Merge "Merge "Add Leanback to the feature exclusion list for Notification" into lollipop-mr1-cts-dev am: 531276e" into marshmallow-cts-dev am: 7bec07f am: 58bfb04 am: 2d49113 am: 2e7a209
am: ba69c27

* commit 'ba69c27e269976dcd4da9224fc6316dfe00d5048':
  Add Leanback to the feature exclusion list for Notification

Change-Id: Ic9b0fc4e4310aaba6b293228608b771b6d07e86e
diff --git a/Android.mk b/Android.mk
index 4251262..c245f57 100644
--- a/Android.mk
+++ b/Android.mk
@@ -14,6 +14,6 @@
 # limitations under the License.
 #
 
-include cts/CtsBuild.mk
+include cts/OldCtsBuild.mk
 include cts/CtsCoverage.mk
 include $(call all-subdir-makefiles)
diff --git a/CtsBuild.mk b/CtsBuild.mk
deleted file mode 100644
index ba158ce..0000000
--- a/CtsBuild.mk
+++ /dev/null
@@ -1,49 +0,0 @@
-# Copyright (C) 2011 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-
-# Functions to get the paths of the build outputs.
-
-define cts-get-lib-paths
-	$(foreach lib,$(1),$(CTS_TESTCASES_OUT)/$(lib).jar)
-endef
-
-define cts-get-ui-lib-paths
-	$(foreach lib,$(1),$(CTS_TESTCASES_OUT)/$(lib).jar)
-endef
-
-define cts-get-native-paths
-	$(foreach exe,$(1),$(CTS_TESTCASES_OUT)/$(exe)$(2))
-endef
-
-define cts-get-package-paths
-	$(foreach pkg,$(1),$(CTS_TESTCASES_OUT)/$(pkg).apk)
-endef
-
-define cts-get-test-xmls
-	$(foreach name,$(1),$(CTS_TESTCASES_OUT)/$(name).xml)
-endef
-
-define cts-get-executable-paths
-	$(foreach executable,$(1),$(CTS_TESTCASES_OUT)/$(executable))
-endef
-
-define cts-get-deqp-api-test-xmls
-	$(foreach file,$(call find-files-in-subdirs, external/deqp/android/cts/master, 'com.drawelements.deqp.$(1).*xml', .),$(CTS_TESTCASES_OUT)/$(file))
-endef
-
-define cts-get-deqp-test-xmls
-	$(foreach api,$(1),$(call cts-get-deqp-api-test-xmls,$(api)))
-endef
diff --git a/CtsCoverage.mk b/CtsCoverage.mk
index 1fb98dc..8cc8a96 100644
--- a/CtsCoverage.mk
+++ b/CtsCoverage.mk
@@ -36,7 +36,7 @@
 
 cts_api_coverage_dependencies := $(cts_api_coverage_exe) $(dexdeps_exe) $(api_xml_description)
 
-android_cts_zip := $(HOST_OUT)/cts/android-cts.zip
+android_cts_zip := $(HOST_OUT)/old-cts/old-android-cts.zip
 cts_verifier_apk := $(call intermediates-dir-for,APPS,CtsVerifier)/package.apk
 
 $(cts-test-coverage-report): PRIVATE_TEST_CASES := $(CTS_TESTCASES_OUT)
diff --git a/CtsTestCaseList.mk b/CtsTestCaseList.mk
deleted file mode 100644
index d8ac03a..0000000
--- a/CtsTestCaseList.mk
+++ /dev/null
@@ -1,302 +0,0 @@
-# Copyright (C) 2010 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-cts_security_apps_list := \
-    CtsAppAccessData \
-    CtsAppWithData \
-    CtsDocumentProvider \
-    CtsDocumentClient \
-    CtsExternalStorageApp \
-    CtsInstrumentationAppDiffCert \
-    CtsNetSecPolicyUsesCleartextTrafficFalse \
-    CtsNetSecPolicyUsesCleartextTrafficTrue \
-    CtsNetSecPolicyUsesCleartextTrafficUnspecified \
-    CtsUsePermissionApp \
-    CtsUsePermissionAppCompat \
-    CtsPermissionDeclareApp \
-    CtsPermissionDeclareAppCompat \
-    CtsReadExternalStorageApp \
-    CtsSharedUidInstall \
-    CtsSharedUidInstallDiffCert \
-    CtsSimpleAppInstall \
-    CtsSimpleAppInstallDiffCert \
-    CtsSplitApp \
-    CtsSplitApp_x86 \
-    CtsSplitApp_x86_64 \
-    CtsSplitApp_armeabi-v7a \
-    CtsSplitApp_armeabi \
-    CtsSplitApp_arm64-v8a \
-    CtsSplitApp_mips64 \
-    CtsSplitApp_mips \
-    CtsSplitAppDiffRevision \
-    CtsSplitAppDiffVersion \
-    CtsSplitAppDiffCert \
-    CtsSplitAppFeature \
-    CtsTargetInstrumentationApp \
-    CtsUsePermissionDiffCert \
-    CtsWriteExternalStorageApp \
-    CtsMultiUserStorageApp
-
-cts_security_keysets_list := \
-    CtsKeySetTestApp \
-    CtsKeySetPermDefSigningA \
-    CtsKeySetPermDefSigningB\
-    CtsKeySetPermUseSigningA \
-    CtsKeySetPermUseSigningB \
-    CtsKeySetSigningAUpgradeA \
-    CtsKeySetSigningBUpgradeA \
-    CtsKeySetSigningAUpgradeAAndB \
-    CtsKeySetSigningAUpgradeAOrB \
-    CtsKeySetSigningAUpgradeB \
-    CtsKeySetSigningBUpgradeB \
-    CtsKeySetSigningAAndBUpgradeA \
-    CtsKeySetSigningAAndCUpgradeB \
-    CtsKeySetSigningAUpgradeNone \
-    CtsKeySetSharedUserSigningAUpgradeB \
-    CtsKeySetSharedUserSigningBUpgradeB \
-    CtsKeySetSigningABadUpgradeB \
-    CtsKeySetSigningCBadAUpgradeAB \
-    CtsKeySetSigningANoDefUpgradeB \
-    CtsKeySetSigningAUpgradeEcA \
-    CtsKeySetSigningEcAUpgradeA
-
-cts_account_support_packages := \
-    CtsUnaffiliatedAccountAuthenticators
-
-cts_support_packages := \
-    CtsAccelerationTestStubs \
-    CtsAlarmClockService \
-    CtsAppTestStubs \
-    CtsAssistService \
-    CtsAssistApp \
-    CtsAtraceTestApp \
-    CtsCertInstallerApp \
-    CtsCppToolsApp \
-    CtsDeviceAdmin \
-    CtsDeviceOpenGl \
-    CtsWifiConfigCreator \
-    CtsDeviceAndProfileOwnerApp \
-    CtsDeviceAppUsageTestApp \
-    CtsDeviceInfo \
-    CtsDeviceOsTestApp \
-    CtsDeviceOwnerApp \
-    CtsDeviceTaskswitchingAppA \
-    CtsDeviceTaskswitchingAppB \
-    CtsDeviceTaskswitchingControl \
-    CtsDeviceUi \
-    CtsHostsideNetworkTestsApp \
-    CtsIntentReceiverApp \
-    CtsIntentSenderApp \
-    CtsLauncherAppsTests \
-    CtsLauncherAppsTestsSupport \
-    CtsLeanbackJank \
-    CtsManagedProfileApp \
-    CtsMonkeyApp \
-    CtsMonkeyApp2 \
-    CtsPackageInstallerApp \
-    CtsPermissionApp \
-    CtsSimpleApp \
-    CtsSimplePreMApp \
-    CtsSomeAccessibilityServices \
-    CtsThemeDeviceApp \
-    TestDeviceSetup \
-    CtsUiAutomatorApp \
-    CtsUsbSerialTestApp \
-    CtsVoiceInteractionService \
-    CtsVoiceInteractionApp \
-    CtsVoiceSettingsService \
-    CtsWidgetProviderApp \
-    CtsTrustedVoiceApp \
-    $(cts_account_support_packages) \
-    $(cts_security_apps_list) \
-    $(cts_security_keysets_list)
-
-cts_external_packages := \
-    com.replica.replicaisland \
-    com.drawelements.deqp
-
-# Any APKs that need to be copied to the CTS distribution's testcases
-# directory but do not require an associated test package XML.
-CTS_TEST_CASE_LIST := \
-    $(cts_support_packages) \
-    $(cts_external_packages)
-
-# Test packages that require an associated test package XML.
-cts_test_packages := \
-    CtsDeviceFilePerf \
-    CtsDeviceUi \
-    CtsDeviceDram \
-    CtsDeviceSimpleCpu \
-    CtsDeviceBrowserBench \
-    CtsDeviceVideoPerf \
-    CtsDeviceOpenGl \
-    CtsDeviceTvProviderPerf \
-    CtsAccelerationTestCases \
-    CtsAccountManagerTestCases \
-    CtsAccessibilityServiceTestCases \
-    CtsAccessibilityTestCases \
-    CtsAdminTestCases \
-    CtsAlarmClockTestCases \
-    CtsAnimationTestCases \
-    CtsAppTestCases \
-    CtsAppWidgetTestCases \
-    CtsAssistTestCases \
-    CtsBluetoothTestCases \
-    CtsCalendarcommon2TestCases \
-    CtsCallLogTestCases \
-    CtsCameraTestCases \
-    CtsContentTestCases \
-    CtsDatabaseTestCases \
-    CtsDisplayTestCases \
-    CtsDpiTestCases \
-    CtsDpiTestCases2 \
-    CtsDreamsTestCases \
-    CtsDrmTestCases \
-    CtsEffectTestCases \
-    CtsGestureTestCases \
-    CtsGraphicsTestCases \
-    CtsGraphics2TestCases \
-    CtsHardwareTestCases \
-    CtsJankTestCases \
-    CtsLeanbackJankTestCases \
-    CtsJobSchedulerDeviceTestCases \
-    CtsJniTestCases \
-    CtsKeystoreTestCases \
-    CtsLibcoreLegacy22TestCases \
-    CtsLocationTestCases \
-    CtsLocation2TestCases \
-    CtsMediaStressTestCases \
-    CtsMediaTestCases \
-    CtsMidiTestCases \
-    CtsNativeOpenGLTestCases \
-    CtsNdefTestCases \
-    CtsNetSecPolicyUsesCleartextTrafficFalseTestCases \
-    CtsNetSecPolicyUsesCleartextTrafficTrueTestCases \
-    CtsNetSecPolicyUsesCleartextTrafficUnspecifiedTestCases \
-    CtsNetTestCases \
-    CtsNetTestCasesLegacyApi22 \
-    CtsNetTestCasesLegacyPermission22 \
-    CtsOpenGLTestCases \
-    CtsOpenGlPerfTestCases \
-    CtsOsTestCases \
-    CtsPermissionTestCases \
-    CtsPermission2TestCases \
-    CtsPreferenceTestCases \
-    CtsPreference2TestCases \
-    CtsPrintTestCases \
-    CtsProviderTestCases \
-    CtsRenderscriptTestCases \
-    CtsRenderscriptLegacyTestCases \
-    CtsRsCppTestCases \
-    CtsSaxTestCases \
-    CtsSecurityTestCases \
-    CtsSignatureTestCases \
-    CtsSpeechTestCases \
-    CtsSystemUiTestCases \
-    CtsTelecomTestCases \
-    CtsTelecomTestCases2 \
-    CtsTelephonyTestCases \
-    CtsTextTestCases \
-    CtsTextureViewTestCases \
-    CtsThemeTestCases \
-    CtsTransitionTestCases \
-    CtsTvTestCases \
-    CtsUiAutomationTestCases \
-    CtsUiRenderingTestCases \
-    CtsUsageStatsTestCases \
-    CtsUtilTestCases \
-    CtsViewTestCases \
-    CtsVoiceInteractionTestCases \
-    CtsVoiceSettingsTestCases \
-    CtsWebkitTestCases \
-    CtsWidgetTestCases
-
-# All APKs that need to be scanned by the coverage utilities.
-CTS_COVERAGE_TEST_CASE_LIST := \
-    $(cts_support_packages) \
-    $(cts_test_packages)
-
-# Host side only tests
-cts_host_libraries := \
-    CtsAdbTests \
-    CtsAppSecurityTests \
-    CtsAtraceHostTestCases \
-    CtsCppToolsTestCases \
-    CtsDevicePolicyManagerTestCases \
-    CtsDumpsysHostTestCases \
-    CtsHostJank \
-    CtsHostsideNetworkTests \
-    CtsHostUi \
-    CtsJdwpSecurityHostTestCases \
-    CtsMonkeyTestCases \
-    CtsOsHostTestCases \
-    CtsThemeHostTestCases \
-    CtsUsageHostTestCases \
-    CtsSecurityHostTestCases \
-    CtsTrustedVoiceHostTestCases \
-    CtsUsbTests
-
-# List of native tests. For 32 bit targets, assumes that there will be
-# one test executable, and it will end in 32. For 64 bit targets, assumes
-# that there will be two executables, one that ends in 32 for the 32
-# bit executable and one that ends in 64 for the 64 bit executable.
-cts_native_tests := \
-    NativeMediaTest_SL \
-    NativeMediaTest_XA \
-
-ifeq ($(HOST_OS)-$(HOST_ARCH),$(filter $(HOST_OS)-$(HOST_ARCH),linux-x86 linux-x86_64))
-cts_native_tests += bionic-unit-tests-cts
-endif
-
-cts_ui_tests := \
-    CtsUiAutomatorTests
-
-cts_device_jars := \
-    CtsDeviceJank \
-    CtsJdwpApp
-
-cts_target_junit_tests := \
-    CtsJdwp
-
-cts_deqp_test_apis := \
-    egl \
-    gles2 \
-    gles3 \
-    gles31
-
-# All the files that will end up under the repository/testcases
-# directory of the final CTS distribution.
-CTS_TEST_CASES := $(call cts-get-lib-paths,$(cts_host_libraries)) \
-    $(call cts-get-package-paths,$(cts_test_packages)) \
-    $(call cts-get-ui-lib-paths,$(cts_ui_tests)) \
-    $(call cts-get-ui-lib-paths,$(cts_device_jars)) \
-    $(call cts-get-ui-lib-paths,$(cts_target_junit_tests)) \
-    $(call cts-get-executable-paths,$(cts_device_executables)) \
-    $(call cts-get-native-paths,$(cts_native_tests),32)
-
-ifeq ($(TARGET_IS_64_BIT),true)
-CTS_TEST_CASES += $(call cts-get-native-paths,$(cts_native_tests),64)
-endif
-
-# All the XMLs that will end up under the repository/testcases
-# and that need to be created before making the final CTS distribution.
-CTS_TEST_XMLS := $(call cts-get-test-xmls,$(cts_host_libraries)) \
-    $(call cts-get-test-xmls,$(cts_test_packages)) \
-    $(call cts-get-test-xmls,$(cts_native_tests)) \
-    $(call cts-get-test-xmls,$(cts_target_junit_tests)) \
-    $(call cts-get-test-xmls,$(cts_ui_tests)) \
-    $(call cts-get-deqp-test-xmls,$(cts_deqp_test_apis))
-
-# The following files will be placed in the tools directory of the CTS distribution
-CTS_TOOLS_LIST :=
diff --git a/OldCtsBuild.mk b/OldCtsBuild.mk
new file mode 100644
index 0000000..c745885
--- /dev/null
+++ b/OldCtsBuild.mk
@@ -0,0 +1,45 @@
+# Copyright (C) 2011 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+
+# Functions to get the paths of the build outputs.
+
+define cts-get-lib-paths
+	$(foreach lib,$(1),$(CTS_TESTCASES_OUT)/$(lib).jar)
+endef
+
+define cts-get-ui-lib-paths
+	$(foreach lib,$(1),$(CTS_TESTCASES_OUT)/$(lib).jar)
+endef
+
+define cts-get-native-paths
+	$(foreach exe,$(1),$(CTS_TESTCASES_OUT)/$(exe)$(2))
+endef
+
+define cts-get-package-paths
+	$(foreach pkg,$(1),$(CTS_TESTCASES_OUT)/$(pkg).apk)
+endef
+
+define cts-get-test-xmls
+	$(foreach name,$(1),$(CTS_TESTCASES_OUT)/$(name).xml)
+endef
+
+define cts-get-executable-paths
+	$(foreach executable,$(1),$(CTS_TESTCASES_OUT)/$(executable))
+endef
+
+define cts-get-deqp-test-xmls
+	$(foreach api,$(1),$(CTS_TESTCASES_OUT)/com.drawelements.deqp.$(api).xml)
+endef
diff --git a/OldCtsTestCaseList.mk b/OldCtsTestCaseList.mk
new file mode 100644
index 0000000..6c89b11
--- /dev/null
+++ b/OldCtsTestCaseList.mk
@@ -0,0 +1,323 @@
+# Copyright (C) 2010 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+cts_security_apps_list := \
+    CtsAppAccessData \
+    CtsAppWithData \
+    CtsDocumentProvider \
+    CtsDocumentClient \
+    CtsEncryptionApp \
+    CtsExternalStorageApp \
+    CtsInstrumentationAppDiffCert \
+    CtsNetSecPolicyUsesCleartextTrafficFalse \
+    CtsNetSecPolicyUsesCleartextTrafficTrue \
+    CtsNetSecPolicyUsesCleartextTrafficUnspecified \
+    CtsUsePermissionApp \
+    CtsUsePermissionAppCompat \
+    CtsPermissionDeclareApp \
+    CtsPermissionDeclareAppCompat \
+    CtsReadExternalStorageApp \
+    CtsSharedUidInstall \
+    CtsSharedUidInstallDiffCert \
+    CtsSimpleAppInstall \
+    CtsSimpleAppInstallDiffCert \
+    CtsSplitApp \
+    CtsSplitApp_x86 \
+    CtsSplitApp_x86_64 \
+    CtsSplitApp_armeabi-v7a \
+    CtsSplitApp_armeabi \
+    CtsSplitApp_arm64-v8a \
+    CtsSplitApp_mips64 \
+    CtsSplitApp_mips \
+    CtsSplitAppDiffRevision \
+    CtsSplitAppDiffVersion \
+    CtsSplitAppDiffCert \
+    CtsSplitAppFeature \
+    CtsTargetInstrumentationApp \
+    CtsUsePermissionDiffCert \
+    CtsWriteExternalStorageApp \
+    CtsMultiUserStorageApp
+
+cts_security_keysets_list := \
+    CtsKeySetTestApp \
+    CtsKeySetPermDefSigningA \
+    CtsKeySetPermDefSigningB\
+    CtsKeySetPermUseSigningA \
+    CtsKeySetPermUseSigningB \
+    CtsKeySetSigningAUpgradeA \
+    CtsKeySetSigningBUpgradeA \
+    CtsKeySetSigningAUpgradeAAndB \
+    CtsKeySetSigningAUpgradeAOrB \
+    CtsKeySetSigningAUpgradeB \
+    CtsKeySetSigningBUpgradeB \
+    CtsKeySetSigningAAndBUpgradeA \
+    CtsKeySetSigningAAndCUpgradeB \
+    CtsKeySetSigningAUpgradeNone \
+    CtsKeySetSharedUserSigningAUpgradeB \
+    CtsKeySetSharedUserSigningBUpgradeB \
+    CtsKeySetSigningABadUpgradeB \
+    CtsKeySetSigningCBadAUpgradeAB \
+    CtsKeySetSigningANoDefUpgradeB \
+    CtsKeySetSigningAUpgradeEcA \
+    CtsKeySetSigningEcAUpgradeA
+
+cts_account_support_packages := \
+    CtsUnaffiliatedAccountAuthenticators
+
+cts_support_packages := \
+    CtsAbiOverrideTestApp \
+    CtsAccountManagementDevicePolicyApp \
+    CtsAdminApp \
+    CtsAlarmClockService \
+    CtsAppRestrictionsManagingApp \
+    CtsAppRestrictionsTargetApp \
+    CtsAppTestStubs \
+    CtsAppUsageTestApp \
+    CtsAssistService \
+    CtsAssistApp \
+    CtsAtraceTestApp \
+    CtsBackupApp \
+    CtsCertInstallerApp \
+    CtsContactDirectoryProvider \
+    CtsCustomizationApp \
+    CtsCppToolsApp \
+    CtsDeviceAdminApp23 \
+    CtsDeviceAdminApp24 \
+    CtsDeviceAndProfileOwnerApp23 \
+    CtsDeviceAndProfileOwnerApp \
+    CtsDeviceInfo \
+    CtsDeviceOsTestApp \
+    CtsDeviceOwnerApp \
+    CtsDeviceServicesTestApp \
+    CtsDeviceTaskSwitchingAppA \
+    CtsDeviceTaskSwitchingAppB \
+    CtsDeviceTaskSwitchingControl \
+    CtsExternalServiceService \
+    CtsHostsideNetworkTestsApp \
+    CtsHostsideNetworkTestsApp2 \
+    CtsIntentReceiverApp \
+    CtsIntentSenderApp \
+    CtsLauncherAppsTests \
+    CtsLauncherAppsTestsSupport \
+    CtsLeanbackJankApp \
+    CtsManagedProfileApp \
+    CtsMonkeyApp \
+    CtsMonkeyApp2 \
+    CtsPackageInstallerApp \
+    CtsPermissionApp \
+    CtsProfileOwnerApp \
+    CtsSimpleApp \
+    CtsSimplePreMApp \
+    CtsSomeAccessibilityServices \
+    CtsSystemUiDeviceApp \
+    CtsThemeDeviceApp \
+    CtsUsbSerialTestApp \
+    CtsVoiceInteractionService \
+    CtsVoiceInteractionApp \
+    CtsVoiceSettingsService \
+    CtsVpnFirewallApp \
+    CtsWidgetProviderApp \
+    CtsWifiConfigCreator \
+    TestDeviceSetup \
+    $(cts_account_support_packages) \
+    $(cts_security_apps_list) \
+    $(cts_security_keysets_list)
+
+cts_external_packages := \
+    com.replica.replicaisland \
+    com.drawelements.deqp
+
+# Any APKs that need to be copied to the CTS distribution's testcases
+# directory but do not require an associated test package XML.
+CTS_TEST_CASE_LIST := \
+    $(cts_support_packages) \
+    $(cts_external_packages)
+
+# Test packages that require an associated test package XML.
+cts_test_packages := \
+    CtsIcuTestCases \
+    CtsAccelerationTestCases \
+    CtsAccountManagerTestCases \
+    CtsAccessibilityServiceTestCases \
+    CtsAccessibilityTestCases \
+    CtsAdminTestCases \
+    CtsAlarmClockTestCases \
+    CtsAnimationTestCases \
+    CtsAppTestCases \
+    CtsAppWidgetTestCases \
+    CtsAssistTestCases \
+    CtsBackupTestCases \
+    CtsBluetoothTestCases \
+    CtsBrowserTestCases \
+    CtsCalendarcommon2TestCases \
+    CtsCallLogTestCases \
+    CtsCameraTestCases \
+    CtsCarTestCases \
+    CtsContentTestCases \
+    CtsDatabaseTestCases \
+    CtsDisplayTestCases \
+    CtsDpiTestCases \
+    CtsDpiTestCases2 \
+    CtsDramTestCases \
+    CtsDreamsTestCases \
+    CtsDrmTestCases \
+    CtsEffectTestCases \
+    CtsExternalServiceTestCases \
+    CtsFileSystemTestCases \
+    CtsGestureTestCases \
+    CtsGraphicsTestCases \
+    CtsGraphics2TestCases \
+    CtsHardwareTestCases \
+    CtsJankDeviceTestCases \
+    CtsLeanbackJankTestCases \
+    CtsJobSchedulerTestCases \
+    CtsJniTestCases \
+    CtsKeystoreTestCases \
+    CtsLibcoreLegacy22TestCases \
+    CtsLocationTestCases \
+    CtsLocation2TestCases \
+    CtsMediaStressTestCases \
+    CtsMediaTestCases \
+    CtsMidiTestCases \
+    CtsMultiUserTestCases \
+    CtsNdefTestCases \
+    CtsNetSecPolicyUsesCleartextTrafficFalseTestCases \
+    CtsNetSecPolicyUsesCleartextTrafficTrueTestCases \
+    CtsNetSecPolicyUsesCleartextTrafficUnspecifiedTestCases \
+    CtsNetTestCases \
+    CtsNetTestCasesLegacyApi22 \
+    CtsNetTestCasesLegacyPermission22 \
+    CtsNetSecConfigAttributeTestCases \
+    CtsNetSecConfigCleartextTrafficTestCases \
+    CtsNetSecConfigBasicDebugDisabledTestCases \
+    CtsNetSecConfigBasicDebugEnabledTestCases \
+    CtsNetSecConfigBasicDomainConfigTestCases \
+    CtsNetSecConfigInvalidPinTestCases \
+    CtsNetSecConfigNestedDomainConfigTestCases \
+    CtsNetSecConfigResourcesSrcTestCases \
+    CtsOpenGLTestCases \
+    CtsOpenGlPerfTestCases \
+    CtsOpenGlPerf2TestCases \
+    CtsOsTestCases \
+    CtsPermissionTestCases \
+    CtsPermission2TestCases \
+    CtsPreferenceTestCases \
+    CtsPreference2TestCases \
+    CtsPrintTestCases \
+    CtsProviderTestCases \
+    CtsRenderscriptTestCases \
+    CtsRenderscriptLegacyTestCases \
+    CtsRsBlasTestCases \
+    CtsRsCppTestCases \
+    CtsSaxTestCases \
+    CtsSecurityTestCases \
+    CtsSignatureTestCases \
+    CtsSimpleCpuTestCases \
+    CtsSpeechTestCases \
+    CtsSystemUiTestCases \
+    CtsTelecomTestCases \
+    CtsTelecomTestCases2 \
+    CtsTelephonyTestCases \
+    CtsTextTestCases \
+    CtsTextureViewTestCases \
+    CtsThemeDeviceTestCases \
+    CtsTransitionTestCases \
+    CtsTvProviderTestCases \
+    CtsTvTestCases \
+    CtsUiAutomationTestCases \
+    CtsUiRenderingTestCases \
+    CtsUiDeviceTestCases \
+    CtsUsageStatsTestCases \
+    CtsUtilTestCases \
+    CtsVideoTestCases \
+    CtsViewTestCases \
+    CtsVoiceInteractionTestCases \
+    CtsVoiceSettingsTestCases \
+    CtsWebkitTestCases \
+    CtsWidgetTestCases
+
+# All APKs that need to be scanned by the coverage utilities.
+CTS_COVERAGE_TEST_CASE_LIST := \
+    $(cts_support_packages) \
+    $(cts_test_packages)
+
+# Host side only tests
+cts_host_libraries := \
+    CtsAadbHostTestCases \
+    CtsAbiOverrideHostTestCases \
+    CtsAppSecurityHostTestCases \
+    CtsAppUsageHostTestCases \
+    CtsAtraceHostTestCases \
+    CtsCppToolsTestCases \
+    CtsDevicePolicyManagerTestCases \
+    CtsDumpsysHostTestCases \
+    CtsHostsideNetworkTests \
+    CtsJdwpSecurityHostTestCases \
+    CtsMonkeyTestCases \
+    CtsOsHostTestCases \
+    CtsSecurityHostTestCases \
+    CtsServicesHostTestCases \
+    CtsThemeHostTestCases \
+    CtsUiHostTestCases \
+    CtsUsbTests \
+    CtsSystemUiHostTestCases
+
+# List of native tests. For 32 bit targets, assumes that there will be
+# one test executable, and it will end in 32. For 64 bit targets, assumes
+# that there will be two executables, one that ends in 32 for the 32
+# bit executable and one that ends in 64 for the 64 bit executable.
+cts_native_tests := \
+    CtsNativeMediaSlTestCases \
+    CtsNativeMediaXaTestCases \
+
+ifeq ($(HOST_OS)-$(HOST_ARCH),$(filter $(HOST_OS)-$(HOST_ARCH),linux-x86 linux-x86_64))
+cts_native_tests += CtsBionicTestCases
+cts_native_tests += CtsSimpleperfTestCases
+endif
+
+cts_device_jars := \
+    CtsJdwpApp
+
+cts_target_junit_tests := \
+    CtsJdwp
+
+cts_deqp_test_apis := \
+    egl \
+    gles2 \
+    gles3 \
+    gles31
+
+# All the files that will end up under the repository/testcases
+# directory of the final CTS distribution.
+CTS_TEST_CASES := $(call cts-get-lib-paths,$(cts_host_libraries)) \
+    $(call cts-get-package-paths,$(cts_test_packages)) \
+    $(call cts-get-ui-lib-paths,$(cts_device_jars)) \
+    $(call cts-get-ui-lib-paths,$(cts_target_junit_tests)) \
+    $(call cts-get-executable-paths,$(cts_device_executables)) \
+    $(call cts-get-native-paths,$(cts_native_tests),32)
+
+ifeq ($(TARGET_IS_64_BIT),true)
+CTS_TEST_CASES += $(call cts-get-native-paths,$(cts_native_tests),64)
+endif
+
+# All the XMLs that will end up under the repository/testcases
+# and that need to be created before making the final CTS distribution.
+CTS_TEST_XMLS := $(call cts-get-test-xmls,$(cts_host_libraries)) \
+    $(call cts-get-test-xmls,$(cts_test_packages)) \
+    $(call cts-get-test-xmls,$(cts_native_tests)) \
+    $(call cts-get-test-xmls,$(cts_target_junit_tests)) \
+    $(call cts-get-deqp-test-xmls,$(cts_deqp_test_apis))
+
+# The following files will be placed in the tools directory of the CTS distribution
+CTS_TOOLS_LIST :=
diff --git a/apps/CameraITS/CameraITS.pdf b/apps/CameraITS/CameraITS.pdf
index 8953af9..80b5e10 100644
--- a/apps/CameraITS/CameraITS.pdf
+++ b/apps/CameraITS/CameraITS.pdf
Binary files differ
diff --git a/apps/CameraITS/build/envsetup.sh b/apps/CameraITS/build/envsetup.sh
index 6069341..bcf294a 100644
--- a/apps/CameraITS/build/envsetup.sh
+++ b/apps/CameraITS/build/envsetup.sh
@@ -17,6 +17,8 @@
 # and that the unit tests for the modules passed (indicating that the setup
 # is correct).
 
+CAMERA_ITS_TOP=$PWD
+
 [[ "${BASH_SOURCE[0]}" != "${0}" ]] || \
     { echo ">> Script must be sourced with 'source $0'" >&2; exit 1; }
 
@@ -43,3 +45,6 @@
         echo ">> Unit test for $M failed" >&2
 done
 
+alias gpylint='gpylint --disable=F0401 --disable=C6304 --rcfile=$CAMERA_ITS_TOP"/build/scripts/gpylint_rcfile"'
+# F0401 ignores import errors since gpylint does not have the python paths
+# C6304 ignore Copyright line errors.
diff --git a/apps/CameraITS/build/scripts/gpylint_rcfile b/apps/CameraITS/build/scripts/gpylint_rcfile
new file mode 100644
index 0000000..43d3dbc
--- /dev/null
+++ b/apps/CameraITS/build/scripts/gpylint_rcfile
@@ -0,0 +1,388 @@
+[MESSAGES CONTROL]
+
+# Only show warnings with the listed confidence levels. Leave empty to show
+# all.
+confidence=
+
+# Disable the message, report, category or checker with the given id(s). You
+# can either give multiple identifiers separated by comma (,) or put this
+# option multiple times (only on the command line, not in the configuration
+# file where it should appear only once).You can also use "--disable=all" to
+# disable everything first and then reenable specific checks. For example, if
+# you want to run only the similarities checker, you can use "--disable=all
+# --enable=similarities". If you want to run only the classes checker, but have
+# no Warning level messages displayed, use"--disable=all --enable=classes
+# --disable=W"
+disable=design,similarities,no-self-use,attribute-defined-outside-init,locally-disabled,star-args,pointless-except,bad-option-value,global-statement,fixme,suppressed-message,useless-suppression
+
+# Enable the message, report, category or checker with the given id(s). You can
+# either give multiple identifier separated by comma (,) or put this option
+# multiple time. See also the "--disable" option for examples.
+#enable=
+
+
+[MODES]
+
+# DEPRECATED.
+disable-docstring=no
+
+# DEPRECATED, use --mode=base
+google=no
+
+# The configuration modes to activate (default: base).
+mode=base
+
+# The mode to use when import path setup fails (default: style).
+safe-mode=base
+
+# DEPRECATED, use --mode=style
+single-file=no
+
+# DEPRECATED, use --mode=test
+test=no
+
+# A pattern for file names that should activate test mode.
+test-filename-pattern=_(unit|reg)?test\.py$
+
+# The configuration mode to use for tests (default: test).
+test-mode=test
+
+
+[PATHS]
+
+# Directories to add to sys.path.
+#import-paths=
+
+# Inject some known modules.
+inject-known-modules=no
+
+# The import path resolver
+resolver=blaze
+
+
+[REPORTS]
+
+# Add a comment according to your evaluation note. This is used by the global
+# evaluation report (RP0004).
+comment=no
+
+# Python expression which should return a note less than 10 (10 is the highest
+# note). You have access to the variables errors warning, statement which
+# respectively contain the number of errors / warnings messages and the total
+# number of statements analyzed. This is used by the global evaluation report
+# (RP0004).
+evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
+
+# Put messages in a separate file for each module / package specified on the
+# command line instead of printing them on stdout. Reports (if any) will be
+# written in a file name "pylint_global.[txt|html]".
+files-output=no
+
+# String to print as the module footer.
+#module-footer-template=
+
+# Template for the module header. %(filename)s will be replaced with the name
+# of the file under analysis.
+#module-header-template=
+
+# Template used to display messages. This is a python new-style format string
+# used to format the message information. See doc for all details
+#msg-template=
+
+# Set the output format. Available formats are text, parseable, colorized, msvs
+# (visual studio) and html. You can also give a reporter class, eg
+# mypackage.mymodule.MyReporterClass.
+output-format=sorted-text
+
+# Tells whether to display a full report or only the messages
+reports=no
+
+
+[BASIC]
+
+# Regular expression which should only match correct argument names
+argument-rgx=^[a-z][a-z0-9_]*$
+
+# Regular expression which should only match correct instance attribute names
+attr-rgx=^_{0,2}[a-z][a-z0-9_]*$
+
+# List of builtins function names that should not be used, separated by a comma
+bad-functions=input,apply,reduce
+
+# Bad variable names which should always be refused, separated by a comma
+bad-names=
+
+# Regular expression which should only match correct attribute names in class
+# bodies
+class-attribute-rgx=^(_?[A-Z][A-Z0-9_]*|__[a-z0-9_]+__|_?[a-z][a-z0-9_]*)$
+
+# Regular expression which should only match correct class names
+class-rgx=^_?[A-Z][a-zA-Z0-9]*$
+
+# Regular expression which should only match correct module level names
+const-rgx=^(_?[A-Z][A-Z0-9_]*|__[a-z0-9_]+__|_?[a-z][a-z0-9_]*)$
+
+# Minimum line length for functions/classes that require docstrings, shorter
+# ones are exempt.
+docstring-min-length=10
+
+# Regular expression which should only match correct function names
+# function-rgx=^(?:(?P<camel_case>_?[A-Z][a-zA-Z0-9]*)|(?P<snake_case>_?[a-z][a-z0-9_]*))$
+function-rgx=^(?:(?P<snake_case>_?[a-z][a-z0-9_]*))$
+
+# Good variable names which should always be accepted, separated by a comma
+good-names=main,_
+
+# Regular expression which should only match correct list comprehension /
+# generator expression variable names
+inlinevar-rgx=^[a-z][a-z0-9_]*$
+
+# Regular expression which should only match correct method names
+# method-rgx=^(?:(?P<exempt>__[a-z0-9_]+__|next)|(?P<camel_case>_{0,2}[A-Z][a-zA-Z0-9]*)|(?P<snake_case>_{0,2}[a-z][a-z0-9_]*))$
+method-rgx=^(?:(?P<exempt>__[a-z0-9_]+__|next)|(?P<snake_case>_{0,2}[a-z][a-z0-9_]*))$
+
+# Regular expression which should only match correct module names
+module-rgx=^(_?[a-z][a-z0-9_]*)|__init__|PRESUBMIT|PRESUBMIT_unittest$
+
+# Colon delimited types of objects which should have the same naming style,
+# separated by a comma
+name-group=function:method
+
+# Regular expression which should only match function or class names that do
+# not require a docstring.
+no-docstring-rgx=(__.*__|main)
+
+# Required attributes for module, separated by a comma
+required-attributes=
+
+# Regular expression which should only match correct variable names
+variable-rgx=^[a-z][a-z0-9_]*$
+
+
+[CLASSES]
+
+# List of method names used to declare (i.e. assign) instance attributes.
+defining-attr-methods=__init__,__new__,setUp
+
+# List of interface methods to ignore, separated by a comma. This is used for
+# instance to not check methods defines in Zope's Interface base class.
+ignore-iface-methods=isImplementedBy,deferred,extends,names,namesAndDescriptions,queryDescriptionFor,getBases,getDescriptionFor,getDoc,getName,getTaggedValue,getTaggedValueTags,isEqualOrExtendedBy,setTaggedValue,isImplementedByInstancesOf,adaptWith,is_implemented_by
+
+# List of valid names for the first argument in a class method.
+valid-classmethod-first-arg=cls,class_
+
+# List of valid names for the first argument in a metaclass class method.
+valid-metaclass-classmethod-first-arg=mcs
+
+
+[DESIGN]
+
+# Argument names that match this expression will be ignored. Default to name
+# with leading underscore
+ignored-argument-names=_.*
+
+# Maximum number of arguments for function / method
+max-args=5
+
+# Maximum number of attributes for a class (see R0902).
+max-attributes=7
+
+# Maximum number of branch for function / method body
+max-branches=12
+
+# Maximum number of locals for function / method body
+max-locals=15
+
+# Maximum number of parents for a class (see R0901).
+max-parents=7
+
+# Maximum number of public methods for a class (see R0904).
+max-public-methods=20
+
+# Maximum number of return / yield for function / method body
+max-returns=6
+
+# Maximum number of statements in function / method body
+max-statements=50
+
+# Minimum number of public methods for a class (see R0903).
+min-public-methods=2
+
+
+[EXCEPTIONS]
+
+# Exceptions that will emit a warning when being caught. Defaults to
+# "Exception"
+overgeneral-exceptions=StandardError,Exception
+
+
+[FORMAT]
+
+# Regexp for a line that is allowed to be longer than the limit.
+ignore-long-lines=(^\s*(import|from)\s|^__version__\s=\s['"]\$Id:|^\s*(# )?<?https?://\S+>?$)
+
+# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1
+# tab).
+indent-string='    '
+
+# Maximum number of characters on a single line.
+max-line-length=80
+
+# Maximum number of lines in a module
+max-module-lines=99999
+
+# List of optional constructs for which whitespace checking is disabled
+no-space-check=
+
+# Allow the body of an if to be on the same line as the test if there is no
+# else.
+single-line-if-stmt=yes
+
+
+[GOOGLE AST]
+
+# List of module members that should be marked as deprecated.
+deprecated-members=string.atof,string.atoi,string.atol,string.capitalize,string.expandtabs,string.find,string.rfind,string.index,string.rindex,string.count,string.lower,string.split,string.rsplit,string.splitfields,string.join,string.joinfields,string.lstrip,string.rstrip,string.strip,string.swapcase,string.translate,string.upper,string.ljust,string.rjust,string.center,string.zfill,string.replace,sys.exitfunc
+
+# Maximum line length for lambdas.
+short-func-length=1
+
+
+[GOOGLE DOCSTRING]
+
+# List of exceptions that do not need to be mentioned in the Raises section of
+# a docstring.
+ignore-exceptions=NotImplementedError,StopIteration
+
+
+[GOOGLE IMPORTS]
+
+# List of modules that should be ignored if unused.
+ignore-unused-imports=google3
+
+
+[GOOGLE LINES]
+
+# Regexp for a proper copyright notice.
+copyright=Copyright \d{4} Google Inc\. +All Rights Reserved\.
+
+
+[GOOGLE TOKENS]
+
+# A regex for finding comments that do not have a space between leading comment
+# separators and textual content.
+comment-starts-without-space=\A#[^\s\w]*\w
+
+# Regexp for a proper TODO comment; the uid group, if any, should match the
+# user ID of the relevant person
+good-todo=# ?TODO\((?P<uid>[a-z][a-z0-9-]*)|b/(?P<bugid>[0-9]+)\):?
+
+# Number of spaces of indent required when the last token on the preceding line
+# is an open (, [, or {.
+indent-after-paren=4
+
+# Minimum number of spaces between the end of a line and an inline comment.
+min-comment-space=2
+
+# Regexp for a TODO comment, which may be incorrect.
+todo=(?i)#\s*todo
+
+
+[IMPORTS]
+
+# Deprecated modules which should not be used, separated by a comma
+deprecated-modules=regsub,TERMIOS,Bastion,rexec
+
+# Create a graph of external dependencies in the given file (report RP0402 must
+# not be disabled)
+ext-import-graph=
+
+# Create a graph of every (i.e. internal and external) dependencies in the
+# given file (report RP0402 must not be disabled)
+import-graph=
+
+# Create a graph of internal dependencies in the given file (report RP0402 must
+# not be disabled)
+int-import-graph=
+
+
+[LOGGING]
+
+# Logging modules to check that the string format arguments are in logging
+# function parameter format
+logging-modules=logging,google3.pyglib.logging
+
+
+[MASTER]
+
+# Add files or directories to the blacklist. They should be base names, not
+# paths.
+ignore=CVS
+
+# Arbitrary Python code to execute before linting.
+#init-hook=
+
+# List of plugins (as comma separated values of python modules names) to load,
+# usually to register additional checkers.
+load-plugins=
+
+# Pickle collected data for later comparisons.
+persistent=no
+
+# Use a custom configuration file for linting.
+#rcfile=
+
+
+[MISCELLANEOUS]
+
+# List of note tags to take in consideration, separated by a comma.
+notes=
+
+
+[SIMILARITIES]
+
+# Ignore comments when computing similarities.
+ignore-comments=yes
+
+# Ignore docstrings when computing similarities.
+ignore-docstrings=yes
+
+# Ignore imports when computing similarities.
+ignore-imports=no
+
+# Minimum lines number of a similarity.
+min-similarity-lines=4
+
+
+[TYPECHECK]
+
+# List of members which are set dynamically and missed by pylint inference
+# system, and so shouldn't trigger E0201 when accessed. Python regular
+# expressions are accepted.
+generated-members=REQUEST,acl_users,aq_parent
+
+# Tells whether missing members accessed in mixin class should be ignored. A
+# mixin class is detected if its name ends with "mixin" (case insensitive).
+ignore-mixin-members=yes
+
+# List of classes names for which member attributes should not be checked
+# (useful for classes with attributes dynamically set).
+ignored-classes=SQLObject
+
+# When zope mode is activated, add a predefined set of Zope acquired attributes
+# to generated-members.
+zope=no
+
+
+[VARIABLES]
+
+# List of additional names supposed to be defined in builtins. Remember that
+# you should avoid to define new builtins when possible.
+additional-builtins=
+
+# A regular expression matching the beginning of the name of dummy variables
+# (i.e. not used).
+dummy-variables-rgx=^\*{0,2}(_$|unused_|dummy_)
+
+# Tells whether we should check for unused import in __init__ files.
+init-import=no
diff --git a/apps/CameraITS/pymodules/its/caps.py b/apps/CameraITS/pymodules/its/caps.py
index 95f19d9..94b12f5 100644
--- a/apps/CameraITS/pymodules/its/caps.py
+++ b/apps/CameraITS/pymodules/its/caps.py
@@ -36,6 +36,30 @@
         print "Test skipped"
         sys.exit(SKIP_RET_CODE)
 
+def full_or_better(props):
+    """Returns whether a device is a FULL or better camera2 device.
+
+    Args:
+        props: Camera properties object.
+
+    Returns:
+        Boolean.
+    """
+    return props.has_key("android.info.supportedHardwareLevel") and \
+            props["android.info.supportedHardwareLevel"] != 2 and \
+            props["android.info.supportedHardwareLevel"] > 1
+
+def level3(props):
+    """Returns whether a device is a LEVEL3 capability camera2 device.
+
+    Args:
+        props: Camera properties object.
+
+    Returns:
+        Boolean.
+    """
+    return props.has_key("android.info.supportedHardwareLevel") and \
+           props["android.info.supportedHardwareLevel"] == 3
 
 def full(props):
     """Returns whether a device is a FULL capability camera2 device.
@@ -73,6 +97,19 @@
     return props.has_key("android.info.supportedHardwareLevel") and \
            props["android.info.supportedHardwareLevel"] == 2
 
+def radial_distortion_correction(props):
+    """Returns whether a device supports RADIAL_DISTORTION_CORRECTION
+    capabilities.
+
+    Args:
+        props: Camera properties object.
+
+    Returns:
+        Boolean.
+    """
+    return props.has_key("android.lens.radialDistortion") and \
+           props["android.lens.radialDistortion"] is not None
+
 def manual_sensor(props):
     """Returns whether a device supports MANUAL_SENSOR capabilities.
 
@@ -83,8 +120,7 @@
         Boolean.
     """
     return    props.has_key("android.request.availableCapabilities") and \
-              1 in props["android.request.availableCapabilities"] \
-           or full(props)
+              1 in props["android.request.availableCapabilities"]
 
 def manual_post_proc(props):
     """Returns whether a device supports MANUAL_POST_PROCESSING capabilities.
@@ -96,8 +132,7 @@
         Boolean.
     """
     return    props.has_key("android.request.availableCapabilities") and \
-              2 in props["android.request.availableCapabilities"] \
-           or full(props)
+              2 in props["android.request.availableCapabilities"]
 
 def raw(props):
     """Returns whether a device supports RAW capabilities.
@@ -144,6 +179,29 @@
     """
     return len(its.objects.get_available_output_sizes("raw12", props)) > 0
 
+def raw_output(props):
+    """Returns whether a device supports any of RAW output format.
+
+    Args:
+        props: Camera properties object.
+
+    Returns:
+        Boolean.
+    """
+    return raw16(props) or raw10(props) or raw12(props)
+
+def post_raw_sensitivity_boost(props):
+    """Returns whether a device supports post RAW sensitivity boost..
+
+    Args:
+        props: Camera properties object.
+
+    Returns:
+        Boolean.
+    """
+    return props.has_key("android.control.postRawSensitivityBoostRange") and \
+            props["android.control.postRawSensitivityBoostRange"] != [100, 100]
+
 def sensor_fusion(props):
     """Returns whether the camera and motion sensor timestamps for the device
     are in the same time domain and can be compared directly.
diff --git a/apps/CameraITS/pymodules/its/device.py b/apps/CameraITS/pymodules/its/device.py
index 835a4a4..8dfcc27 100644
--- a/apps/CameraITS/pymodules/its/device.py
+++ b/apps/CameraITS/pymodules/its/device.py
@@ -84,6 +84,10 @@
     CAP_RAW_YUV_JPEG = [{"format":"raw"}, {"format":"yuv"}, {"format":"jpeg"}]
     CAP_DNG_YUV_JPEG = [{"format":"dng"}, {"format":"yuv"}, {"format":"jpeg"}]
 
+    # Predefine camera props. Save props extracted from the function,
+    # "get_camera_properties".
+    props = None
+
     # Initialize the socket port for the host to forward requests to the device.
     # This method assumes localhost's LOCK_PORT is available and will try to
     # use ports between CLIENT_PORT_START and CLIENT_PORT_START+MAX_NUM_PORTS-1
@@ -170,11 +174,16 @@
                 if len(s) > 7 and s[6] == "=":
                     duration = int(s[7:])
                 print "Rebooting device"
-                _run("%s reboot" % (self.adb));
+                _run("%s reboot" % (self.adb))
                 _run("%s wait-for-device" % (self.adb))
                 time.sleep(duration)
                 print "Reboot complete"
 
+        # Flush logcat so following code won't be misled by previous
+        # 'ItsService ready' log.
+        _run('%s logcat -c' % (self.adb))
+        time.sleep(1)
+
         # TODO: Figure out why "--user 0" is needed, and fix the problem.
         _run('%s shell am force-stop --user 0 %s' % (self.adb, self.PACKAGE))
         _run(('%s shell am startservice --user 0 -t text/plain '
@@ -349,6 +358,7 @@
         data,_ = self.__read_response_from_socket()
         if data['tag'] != 'cameraProperties':
             raise its.error.Error('Invalid command response')
+        self.props = data['objValue']['cameraProperties']
         return data['objValue']['cameraProperties']
 
     def do_3a(self, regions_ae=[[0,0,1,1,1]],
@@ -588,15 +598,44 @@
                 cmd["outputSurfaces"] = [out_surfaces]
             else:
                 cmd["outputSurfaces"] = out_surfaces
-            formats = [c["format"] if c.has_key("format") else "yuv"
+            formats = [c["format"] if "format" in c else "yuv"
                        for c in cmd["outputSurfaces"]]
             formats = [s if s != "jpg" else "jpeg" for s in formats]
         else:
+            max_yuv_size = its.objects.get_available_output_sizes(
+                    "yuv", self.props)[0]
             formats = ['yuv']
+            cmd["outputSurfaces"] = [{"format": "yuv",
+                                      "width" : max_yuv_size[0],
+                                      "height": max_yuv_size[1]}]
         ncap = len(cmd["captureRequests"])
         nsurf = 1 if out_surfaces is None else len(cmd["outputSurfaces"])
+        # Only allow yuv output to multiple targets
+        yuv_surfaces = [s for s in cmd["outputSurfaces"] if s["format"]=="yuv"]
+        n_yuv = len(yuv_surfaces)
+        # Compute the buffer size of YUV targets
+        yuv_maxsize_1d = 0
+        for s in yuv_surfaces:
+            if not ("width" in s and "height" in s):
+                if self.props is None:
+                    raise its.error.Error('Camera props are unavailable')
+                yuv_maxsize_2d = its.objects.get_available_output_sizes(
+                    "yuv", self.props)[0]
+                yuv_maxsize_1d = yuv_maxsize_2d[0] * yuv_maxsize_2d[1] * 3 / 2
+                break
+        yuv_sizes = [c["width"]*c["height"]*3/2
+                     if "width" in c and "height" in c
+                     else yuv_maxsize_1d
+                     for c in yuv_surfaces]
+        # Currently we don't pass enough metadta from ItsService to distinguish
+        # different yuv stream of same buffer size
+        if len(yuv_sizes) != len(set(yuv_sizes)):
+            raise its.error.Error(
+                    'ITS does not support yuv outputs of same buffer size')
         if len(formats) > len(set(formats)):
-            raise its.error.Error('Duplicate format requested')
+            if n_yuv != len(formats) - len(set(formats)) + 1:
+                raise its.error.Error('Duplicate format requested')
+
         raw_formats = 0;
         raw_formats += 1 if "dng" in formats else 0
         raw_formats += 1 if "raw" in formats else 0
@@ -627,19 +666,24 @@
         # the burst, however individual images of different formats can come
         # out in any order for that capture.
         nbufs = 0
-        bufs = {"yuv":[], "raw":[], "raw10":[], "raw12":[],
+        bufs = {"raw":[], "raw10":[], "raw12":[],
                 "rawStats":[], "dng":[], "jpeg":[]}
+        yuv_bufs = {size:[] for size in yuv_sizes}
         mds = []
         widths = None
         heights = None
         while nbufs < ncap*nsurf or len(mds) < ncap:
             jsonObj,buf = self.__read_response_from_socket()
-            if jsonObj['tag'] in ['jpegImage', 'yuvImage', 'rawImage', \
+            if jsonObj['tag'] in ['jpegImage', 'rawImage', \
                     'raw10Image', 'raw12Image', 'rawStatsImage', 'dngImage'] \
                     and buf is not None:
                 fmt = jsonObj['tag'][:-5]
                 bufs[fmt].append(buf)
                 nbufs += 1
+            elif jsonObj['tag'] == 'yuvImage':
+                buf_size = numpy.product(buf.shape)
+                yuv_bufs[buf_size].append(buf)
+                nbufs += 1
             elif jsonObj['tag'] == 'captureResults':
                 mds.append(jsonObj['objValue']['captureResult'])
                 outputs = jsonObj['objValue']['outputs']
@@ -653,11 +697,15 @@
             objs = []
             for i in range(ncap):
                 obj = {}
-                obj["data"] = bufs[fmt][i]
                 obj["width"] = widths[j]
                 obj["height"] = heights[j]
                 obj["format"] = fmt
                 obj["metadata"] = mds[i]
+                if fmt == 'yuv':
+                    buf_size = widths[j] * heights[j] * 3 / 2
+                    obj["data"] = yuv_bufs[buf_size][i]
+                else:
+                    obj["data"] = bufs[fmt][i]
                 objs.append(obj)
             rets.append(objs if ncap>1 else objs[0])
         self.sock.settimeout(self.SOCK_TIMEOUT)
diff --git a/apps/CameraITS/tests/scene0/test_metadata.py b/apps/CameraITS/tests/scene0/test_metadata.py
index 44663bb..2914493 100644
--- a/apps/CameraITS/tests/scene0/test_metadata.py
+++ b/apps/CameraITS/tests/scene0/test_metadata.py
@@ -36,7 +36,7 @@
     print "Hardware level"
     print "  Legacy:", its.caps.legacy(props)
     print "  Limited:", its.caps.limited(props)
-    print "  Full:", its.caps.full(props)
+    print "  Full or better:", its.caps.full_or_better(props)
     print "Capabilities"
     print "  Manual sensor:", its.caps.manual_sensor(props)
     print "  Manual post-proc:", its.caps.manual_post_proc(props)
@@ -46,7 +46,7 @@
     # Test: hardware level should be a valid value.
     check('props.has_key("android.info.supportedHardwareLevel")')
     check('props["android.info.supportedHardwareLevel"] is not None')
-    check('props["android.info.supportedHardwareLevel"] in [0,1,2]')
+    check('props["android.info.supportedHardwareLevel"] in [0,1,2,3]')
     full = getval('props["android.info.supportedHardwareLevel"]') == 1
     manual_sensor = its.caps.manual_sensor(props)
 
diff --git a/apps/CameraITS/tests/scene1/test_ev_compensation_advanced.py b/apps/CameraITS/tests/scene1/test_ev_compensation_advanced.py
index 5fd8f73..1246a11 100644
--- a/apps/CameraITS/tests/scene1/test_ev_compensation_advanced.py
+++ b/apps/CameraITS/tests/scene1/test_ev_compensation_advanced.py
@@ -27,7 +27,7 @@
     """
     NAME = os.path.basename(__file__).split(".")[0]
 
-    MAX_LUMA_DELTA_THRESH = 0.02
+    MAX_LUMA_DELTA_THRESH = 0.05
 
     with its.device.ItsSession() as cam:
         props = cam.get_camera_properties()
@@ -46,11 +46,13 @@
         imid = len(ev_steps) / 2
         ev_shifts = [pow(2, step * ev_per_step) for step in ev_steps]
         lumas = []
+
+        # Converge 3A, and lock AE once converged. skip AF trigger as
+        # dark/bright scene could make AF convergence fail and this test
+        # doesn't care the image sharpness.
+        cam.do_3a(ev_comp=0, lock_ae=True, do_af=False)
+
         for ev in ev_steps:
-            # Re-converge 3A, and lock AE once converged. skip AF trigger as
-            # dark/bright scene could make AF convergence fail and this test
-            # doesn't care the image sharpness.
-            cam.do_3a(ev_comp=ev, lock_ae=True, do_af=False)
 
             # Capture a single shot with the same EV comp and locked AE.
             req = its.objects.auto_capture_request()
@@ -70,7 +72,7 @@
         print "ev_step_size_in_stops", ev_per_step
         shift_mid = ev_shifts[imid]
         luma_normal = lumas[imid] / shift_mid
-        expected_lumas = [luma_normal * ev_shift for ev_shift in ev_shifts]
+        expected_lumas = [min(1.0, luma_normal * ev_shift) for ev_shift in ev_shifts]
 
         pylab.plot(ev_steps, lumas, 'r')
         pylab.plot(ev_steps, expected_lumas, 'b')
diff --git a/apps/CameraITS/tests/scene1/test_ev_compensation_basic.py b/apps/CameraITS/tests/scene1/test_ev_compensation_basic.py
index e3755eb..d67567d 100644
--- a/apps/CameraITS/tests/scene1/test_ev_compensation_basic.py
+++ b/apps/CameraITS/tests/scene1/test_ev_compensation_basic.py
@@ -37,11 +37,13 @@
         steps_per_ev = int(1.0 / ev_per_step)
         evs = range(-2 * steps_per_ev, 2 * steps_per_ev + 1, steps_per_ev)
         lumas = []
+
+        # Converge 3A, and lock AE once converged. skip AF trigger as
+        # dark/bright scene could make AF convergence fail and this test
+        # doesn't care the image sharpness.
+        cam.do_3a(ev_comp=0, lock_ae=True, do_af=False)
+
         for ev in evs:
-            # Re-converge 3A, and lock AE once converged. skip AF trigger as
-            # dark/bright scene could make AF convergence fail and this test
-            # doesn't care the image sharpness.
-            cam.do_3a(ev_comp=ev, lock_ae=True, do_af=False)
 
             # Capture a single shot with the same EV comp and locked AE.
             req = its.objects.auto_capture_request()
diff --git a/apps/CameraITS/tests/scene1/test_latching.py b/apps/CameraITS/tests/scene1/test_latching.py
index 176f01b..a7da421 100644
--- a/apps/CameraITS/tests/scene1/test_latching.py
+++ b/apps/CameraITS/tests/scene1/test_latching.py
@@ -33,8 +33,7 @@
 
     with its.device.ItsSession() as cam:
         props = cam.get_camera_properties()
-        its.caps.skip_unless(its.caps.full(props) and
-                             its.caps.per_frame_control(props))
+        its.caps.skip_unless(its.caps.full_or_better(props))
 
         _,fmt = its.objects.get_fastest_manual_capture_settings(props)
         e, s = its.target.get_target_exposure_combos(cam)["midExposureTime"]
diff --git a/apps/CameraITS/tests/scene1/test_post_raw_sensitivity_boost.py b/apps/CameraITS/tests/scene1/test_post_raw_sensitivity_boost.py
new file mode 100644
index 0000000..682c04a
--- /dev/null
+++ b/apps/CameraITS/tests/scene1/test_post_raw_sensitivity_boost.py
@@ -0,0 +1,143 @@
+# Copyright 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import its.device
+import its.caps
+import its.image
+import its.objects
+import its.target
+import os.path
+import pylab
+import matplotlib
+import matplotlib.pyplot
+
+def main():
+    """Capture a set of raw/yuv images with different
+        sensitivity/post Raw sensitivity boost combination
+        and check if the output pixel mean matches request settings
+    """
+    NAME = os.path.basename(__file__).split(".")[0]
+
+    # Each raw image
+    RATIO_THRESHOLD = 0.03
+
+    with its.device.ItsSession() as cam:
+        props = cam.get_camera_properties()
+        its.caps.skip_unless(its.caps.raw_output(props) and
+                             its.caps.post_raw_sensitivity_boost(props) and
+                             its.caps.compute_target_exposure(props) and
+                             its.caps.per_frame_control(props))
+
+        w,h = its.objects.get_available_output_sizes(
+                "yuv", props, (1920, 1080))[0]
+
+        if its.caps.raw16(props):
+            raw_format = 'raw'
+        elif its.caps.raw10(props):
+            raw_format = 'raw10'
+        elif its.caps.raw12(props):
+            raw_format = 'raw12'
+        else: # should not reach here
+            raise its.error.Error('Cannot find available RAW output format')
+
+        out_surfaces = [{"format": raw_format},
+                        {"format": "yuv", "width": w, "height": h}]
+
+        sens_min, sens_max = props['android.sensor.info.sensitivityRange']
+        sens_boost_min, sens_boost_max = \
+                props['android.control.postRawSensitivityBoostRange']
+
+
+        e_target, s_target = \
+                its.target.get_target_exposure_combos(cam)["midSensitivity"]
+
+        reqs = []
+        settings = []
+        s_boost = sens_boost_min
+        while s_boost <= sens_boost_max:
+            s_raw = int(round(s_target * 100.0 / s_boost))
+            if s_raw < sens_min or s_raw > sens_max:
+                continue
+            req = its.objects.manual_capture_request(s_raw, e_target)
+            req['android.control.postRawSensitivityBoost'] = s_boost
+            reqs.append(req)
+            settings.append((s_raw, s_boost))
+            s_boost *= 2
+
+        caps = cam.do_capture(reqs, out_surfaces)
+
+        raw_rgb_means = []
+        yuv_rgb_means = []
+        raw_caps, yuv_caps = caps
+        if not isinstance(raw_caps, list):
+            raw_caps = [raw_caps]
+        if not isinstance(yuv_caps, list):
+            yuv_caps = [yuv_caps]
+        for i in xrange(len(reqs)):
+            (s, s_boost) = settings[i]
+            raw_cap = raw_caps[i]
+            yuv_cap = yuv_caps[i]
+            raw_rgb = its.image.convert_capture_to_rgb_image(raw_cap, props=props)
+            yuv_rgb = its.image.convert_capture_to_rgb_image(yuv_cap)
+            raw_tile = its.image.get_image_patch(raw_rgb, 0.45,0.45,0.1,0.1)
+            yuv_tile = its.image.get_image_patch(yuv_rgb, 0.45,0.45,0.1,0.1)
+            raw_rgb_means.append(its.image.compute_image_means(raw_tile))
+            yuv_rgb_means.append(its.image.compute_image_means(yuv_tile))
+            its.image.write_image(raw_tile,
+                    "%s_raw_s=%04d_boost=%04d.jpg" % (NAME,s,s_boost))
+            its.image.write_image(yuv_tile,
+                    "%s_yuv_s=%04d_boost=%04d.jpg" % (NAME,s,s_boost))
+            print "s=%d, s_boost=%d: raw_means %s, yuv_means %s"%(
+                    s,s_boost,raw_rgb_means[-1], yuv_rgb_means[-1])
+
+        xs = range(len(reqs))
+        pylab.plot(xs, [rgb[0] for rgb in raw_rgb_means], 'r')
+        pylab.plot(xs, [rgb[1] for rgb in raw_rgb_means], 'g')
+        pylab.plot(xs, [rgb[2] for rgb in raw_rgb_means], 'b')
+        pylab.ylim([0,1])
+        matplotlib.pyplot.savefig("%s_raw_plot_means.png" % (NAME))
+        pylab.clf()
+        pylab.plot(xs, [rgb[0] for rgb in yuv_rgb_means], 'r')
+        pylab.plot(xs, [rgb[1] for rgb in yuv_rgb_means], 'g')
+        pylab.plot(xs, [rgb[2] for rgb in yuv_rgb_means], 'b')
+        pylab.ylim([0,1])
+        matplotlib.pyplot.savefig("%s_yuv_plot_means.png" % (NAME))
+
+        rgb_str = ["R", "G", "B"]
+        # Test that raw means is about 2x brighter than next step
+        raw_thres_min = 2 * (1 - RATIO_THRESHOLD)
+        raw_thres_max = 2 * (1 + RATIO_THRESHOLD)
+        for step in range(1, len(reqs)):
+            for rgb in range(3):
+                ratio = raw_rgb_means[step - 1][rgb] / raw_rgb_means[step][rgb]
+                print "Step (%d,%d) %s channel: %f, %f, ratio %f" % (
+                        step-1, step, rgb_str[rgb],
+                        raw_rgb_means[step - 1][rgb],
+                        raw_rgb_means[step][rgb],
+                        ratio)
+                assert(raw_thres_min < ratio < raw_thres_max)
+
+        # Test that each yuv step is about the same bright as their mean
+        yuv_thres_min = 1 - RATIO_THRESHOLD
+        yuv_thres_max = 1 + RATIO_THRESHOLD
+        for rgb in range(3):
+            vals = [val[rgb] for val in yuv_rgb_means]
+            mean = sum(vals) / len(vals)
+            print "%s channel vals %s mean %f"%(rgb_str[rgb], vals, mean)
+            for step in range(len(reqs)):
+                ratio = vals[step] / mean
+                assert(yuv_thres_min < ratio < yuv_thres_max)
+
+if __name__ == '__main__':
+    main()
diff --git a/apps/CameraITS/tests/scene4/SampleTarget.pdf b/apps/CameraITS/tests/scene4/SampleTarget.pdf
new file mode 100644
index 0000000..e693b34
--- /dev/null
+++ b/apps/CameraITS/tests/scene4/SampleTarget.pdf
Binary files differ
diff --git a/apps/CameraITS/tests/scene4/test_aspect_ratio_and_crop.py b/apps/CameraITS/tests/scene4/test_aspect_ratio_and_crop.py
new file mode 100644
index 0000000..7733c5d
--- /dev/null
+++ b/apps/CameraITS/tests/scene4/test_aspect_ratio_and_crop.py
@@ -0,0 +1,408 @@
+# Copyright 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import its.image
+import its.caps
+import its.device
+import its.objects
+import os.path
+import cv2
+import numpy as np
+
+
+def main():
+    """ Test aspect ratio and check if images are cropped correctly under each
+    output size
+    Aspect ratio test runs on level3, full and limited devices. Crop test only
+    runs on full and level3 devices.
+    The test image is a black circle inside a black square. When raw capture is
+    available, set the height vs. width ratio of the circle in the full-frame
+    raw as ground truth. Then compare with images of request combinations of
+    different formats ("jpeg" and "yuv") and sizes.
+    If raw capture is unavailable, take a picture of the test image right in
+    front to eliminate shooting angle effect. the height vs. width ratio for
+    the circle should be close to 1. Considering shooting position error, aspect
+    ratio greater than 1.05 or smaller than 0.95 will fail the test.
+    """
+    NAME = os.path.basename(__file__).split(".")[0]
+    LARGE_SIZE = 2000   # Define the size of a large image
+    # pass/fail threshold of large size images for aspect ratio test
+    THRES_L_AR_TEST = 0.02
+    # pass/fail threshold of mini size images for aspect ratio test
+    THRES_XS_AR_TEST = 0.05
+    # pass/fail threshold of large size images for crop test
+    THRES_L_CP_TEST = 0.02
+    # pass/fail threshold of mini size images for crop test
+    THRES_XS_CP_TEST = 0.05
+    PREVIEW_SIZE = (1920, 1080) # preview size
+    aspect_ratio_gt = 1  # ground truth
+    failed_ar = []  # streams failed the aspect ration test
+    failed_crop = [] # streams failed the crop test
+    format_list = [] # format list for multiple capture objects.
+    # Do multi-capture of "iter" and "cmpr". Iterate through all the
+    # available sizes of "iter", and only use the size specified for "cmpr"
+    # Do single-capture to cover untouched sizes in multi-capture when needed.
+    format_list.append({"iter": "yuv", "iter_max": None,
+                        "cmpr": "yuv", "cmpr_size": PREVIEW_SIZE})
+    format_list.append({"iter": "yuv", "iter_max": PREVIEW_SIZE,
+                        "cmpr": "jpeg", "cmpr_size": None})
+    format_list.append({"iter": "yuv", "iter_max": PREVIEW_SIZE,
+                        "cmpr": "raw", "cmpr_size": None})
+    format_list.append({"iter": "jpeg", "iter_max": None,
+                        "cmpr": "raw", "cmpr_size": None})
+    format_list.append({"iter": "jpeg", "iter_max": None,
+                        "cmpr": "yuv", "cmpr_size": PREVIEW_SIZE})
+    with its.device.ItsSession() as cam:
+        props = cam.get_camera_properties()
+        # Todo: test for radial distortion enabled devices has not yet been
+        # implemented
+        its.caps.skip_unless(not its.caps.radial_distortion_correction(props))
+        full_device = its.caps.full(props)
+        limited_device = its.caps.limited(props)
+        its.caps.skip_unless(full_device or limited_device)
+        level3_device = its.caps.level3(props)
+        raw_avlb = its.caps.raw16(props)
+        run_crop_test = (level3_device or full_device) and raw_avlb
+        if not run_crop_test:
+            print "Crop test skipped"
+        # Converge 3A and get the estimates.
+        sens, exp, gains, xform, focus = cam.do_3a(get_results=True,
+                                                   lock_ae=True, lock_awb=True)
+        print "AE sensitivity %d, exposure %dms" % (sens, exp / 1000000.0)
+        print "AWB gains", gains
+        print "AWB transform", xform
+        print "AF distance", focus
+        req = its.objects.manual_capture_request(
+                sens, exp, True, props)
+        xform_rat = its.objects.float_to_rational(xform)
+        req["android.colorCorrection.gains"] = gains
+        req["android.colorCorrection.transform"] = xform_rat
+
+        # If raw capture is available, use it as ground truth.
+        if raw_avlb:
+            # Capture full-frame raw. Use its aspect ratio and circle center
+            # location as ground truth for the other jepg or yuv images.
+            out_surface = {"format": "raw"}
+            cap_raw = cam.do_capture(req, out_surface)
+            print "Captured %s %dx%d" % ("raw", cap_raw["width"],
+                                         cap_raw["height"])
+            img_raw = its.image.convert_capture_to_rgb_image(cap_raw,
+                                                             props=props)
+            size_raw = img_raw.shape
+            img_name = "%s_%s_w%d_h%d.png" \
+                       % (NAME, "raw", size_raw[1], size_raw[0])
+            aspect_ratio_gt, cc_ct_gt, circle_size_raw = measure_aspect_ratio(
+                                                         img_raw, 1, img_name)
+            # Normalize the circle size to 1/4 of the image size, so that
+            # circle size won"t affect the crop test result
+            factor_cp_thres = (min(size_raw[0:1])/4.0) / max(circle_size_raw)
+            thres_l_cp_test = THRES_L_CP_TEST * factor_cp_thres
+            thres_xs_cp_test = THRES_XS_CP_TEST * factor_cp_thres
+
+        # Take pictures of each settings with all the image sizes available.
+        for fmt in format_list:
+            fmt_iter = fmt["iter"]
+            fmt_cmpr = fmt["cmpr"]
+            dual_target = fmt_cmpr is not "none"
+            # Get the size of "cmpr"
+            if dual_target:
+                size_cmpr = its.objects.get_available_output_sizes(
+                        fmt_cmpr, props, fmt["cmpr_size"])[0]
+            for size_iter in its.objects.get_available_output_sizes(
+                    fmt_iter, props, fmt["iter_max"]):
+                w_iter = size_iter[0]
+                h_iter = size_iter[1]
+                # Skip testing same format/size combination
+                # ITS does not handle that properly now
+                if dual_target and \
+                        w_iter == size_cmpr[0] and \
+                        h_iter == size_cmpr[1] and \
+                        fmt_iter == fmt_cmpr:
+                    continue
+                out_surface = [{"width": w_iter,
+                                "height": h_iter,
+                                "format": fmt_iter}]
+                if dual_target:
+                    out_surface.append({"width": size_cmpr[0],
+                                        "height": size_cmpr[1],
+                                        "format": fmt_cmpr})
+                cap = cam.do_capture(req, out_surface)
+                if dual_target:
+                    frm_iter = cap[0]
+                else:
+                    frm_iter = cap
+                assert (frm_iter["format"] == fmt_iter)
+                assert (frm_iter["width"] == w_iter)
+                assert (frm_iter["height"] == h_iter)
+                print "Captured %s with %s %dx%d" \
+                        % (fmt_iter, fmt_cmpr, w_iter, h_iter)
+                img = its.image.convert_capture_to_rgb_image(frm_iter)
+                img_name = "%s_%s_with_%s_w%d_h%d.png" \
+                           % (NAME, fmt_iter, fmt_cmpr, w_iter, h_iter)
+                aspect_ratio, cc_ct, _ = measure_aspect_ratio(img, raw_avlb,
+                                                              img_name)
+                # check pass/fail for aspect ratio
+                # image size >= LARGE_SIZE: use THRES_L_AR_TEST
+                # image size == 0 (extreme case): THRES_XS_AR_TEST
+                # 0 < image size < LARGE_SIZE: scale between THRES_XS_AR_TEST
+                # and THRES_L_AR_TEST
+                thres_ar_test = max(THRES_L_AR_TEST,
+                        THRES_XS_AR_TEST + max(w_iter, h_iter) *
+                        (THRES_L_AR_TEST-THRES_XS_AR_TEST)/LARGE_SIZE)
+                thres_range_ar = (aspect_ratio_gt-thres_ar_test,
+                                  aspect_ratio_gt+thres_ar_test)
+                if aspect_ratio < thres_range_ar[0] \
+                        or aspect_ratio > thres_range_ar[1]:
+                    failed_ar.append({"fmt_iter": fmt_iter,
+                                      "fmt_cmpr": fmt_cmpr,
+                                      "w": w_iter, "h": h_iter,
+                                      "ar": aspect_ratio,
+                                      "valid_range": thres_range_ar})
+
+                # check pass/fail for crop
+                if run_crop_test:
+                    # image size >= LARGE_SIZE: use thres_l_cp_test
+                    # image size == 0 (extreme case): thres_xs_cp_test
+                    # 0 < image size < LARGE_SIZE: scale between
+                    # thres_xs_cp_test and thres_l_cp_test
+                    thres_hori_cp_test = max(thres_l_cp_test,
+                            thres_xs_cp_test + w_iter *
+                            (thres_l_cp_test-thres_xs_cp_test)/LARGE_SIZE)
+                    thres_range_h_cp = (cc_ct_gt["hori"]-thres_hori_cp_test,
+                                        cc_ct_gt["hori"]+thres_hori_cp_test)
+                    thres_vert_cp_test = max(thres_l_cp_test,
+                            thres_xs_cp_test + h_iter *
+                            (thres_l_cp_test-thres_xs_cp_test)/LARGE_SIZE)
+                    thres_range_v_cp = (cc_ct_gt["vert"]-thres_vert_cp_test,
+                                        cc_ct_gt["vert"]+thres_vert_cp_test)
+                    if cc_ct["hori"] < thres_range_h_cp[0] \
+                            or cc_ct["hori"] > thres_range_h_cp[1] \
+                            or cc_ct["vert"] < thres_range_v_cp[0] \
+                            or cc_ct["vert"] > thres_range_v_cp[1]:
+                        failed_crop.append({"fmt_iter": fmt_iter,
+                                            "fmt_cmpr": fmt_cmpr,
+                                            "w": w_iter, "h": h_iter,
+                                            "ct_hori": cc_ct["hori"],
+                                            "ct_vert": cc_ct["vert"],
+                                            "valid_range_h": thres_range_h_cp,
+                                            "valid_range_v": thres_range_v_cp})
+
+        # Print aspect ratio test results
+        failed_image_number_for_aspect_ratio_test = len(failed_ar)
+        if failed_image_number_for_aspect_ratio_test > 0:
+            print "\nAspect ratio test summary"
+            print "Images failed in the aspect ratio test:"
+            print "Aspect ratio value: width / height"
+        for fa in failed_ar:
+            print "%s with %s %dx%d: %.3f; valid range: %.3f ~ %.3f" % \
+                  (fa["fmt_iter"], fa["fmt_cmpr"], fa["w"], fa["h"], fa["ar"],
+                   fa["valid_range"][0], fa["valid_range"][1])
+
+        # Print crop test results
+        failed_image_number_for_crop_test = len(failed_crop)
+        if failed_image_number_for_crop_test > 0:
+            print "\nCrop test summary"
+            print "Images failed in the crop test:"
+            print "Circle center position, (horizontal x vertical), listed " \
+                  "below is relative to the image center."
+        for fc in failed_crop:
+            print "%s with %s %dx%d: %.3f x %.3f; " \
+                    "valid horizontal range: %.3f ~ %.3f; " \
+                    "valid vertical range: %.3f ~ %.3f" \
+                    % (fc["fmt_iter"], fc["fmt_cmpr"], fc["w"], fc["h"],
+                    fc["ct_hori"], fc["ct_vert"], fc["valid_range_h"][0],
+                    fc["valid_range_h"][1], fc["valid_range_v"][0],
+                    fc["valid_range_v"][1])
+
+        assert (failed_image_number_for_aspect_ratio_test == 0)
+        if level3_device:
+            assert (failed_image_number_for_crop_test == 0)
+
+
+def measure_aspect_ratio(img, raw_avlb, img_name):
+    """ Measure the aspect ratio of the black circle in the test image.
+
+    Args:
+        img: Numpy float image array in RGB, with pixel values in [0,1].
+        raw_avlb: True: raw capture is available; False: raw capture is not
+             available.
+        img_name: string with image info of format and size.
+    Returns:
+        aspect_ratio: aspect ratio number in float.
+        cc_ct: circle center position relative to the center of image.
+        (circle_w, circle_h): tuple of the circle size
+    """
+    size = img.shape
+    img = img * 255
+    # Gray image
+    img_gray = 0.299 * img[:,:,2] + 0.587 * img[:,:,1] + 0.114 * img[:,:,0]
+
+    # otsu threshold to binarize the image
+    ret3, img_bw = cv2.threshold(np.uint8(img_gray), 0, 255,
+            cv2.THRESH_BINARY + cv2.THRESH_OTSU)
+
+    # connected component
+    contours, hierarchy = cv2.findContours(255-img_bw, cv2.RETR_TREE,
+            cv2.CHAIN_APPROX_SIMPLE)
+
+    # Check each component and find the black circle
+    min_cmpt = size[0] * size[1] * 0.005
+    max_cmpt = size[0] * size[1] * 0.35
+    num_circle = 0
+    aspect_ratio = 0
+    for ct, hrch in zip(contours, hierarchy[0]):
+        # The radius of the circle is 1/3 of the length of the square, meaning
+        # around 1/3 of the area of the square
+        # Parental component should exist and the area is acceptable.
+        # The coutour of a circle should have at least 5 points
+        child_area = cv2.contourArea(ct)
+        if hrch[3] == -1 or child_area < min_cmpt or child_area > max_cmpt or \
+                len(ct) < 15:
+            continue
+        # Check the shapes of current component and its parent
+        child_shape = component_shape(ct)
+        parent = hrch[3]
+        prt_shape = component_shape(contours[parent])
+        prt_area = cv2.contourArea(contours[parent])
+        dist_x = abs(child_shape["ctx"]-prt_shape["ctx"])
+        dist_y = abs(child_shape["cty"]-prt_shape["cty"])
+        # 1. 0.56*Parent"s width < Child"s width < 0.76*Parent"s width.
+        # 2. 0.56*Parent"s height < Child"s height < 0.76*Parent"s height.
+        # 3. Child"s width > 0.1*Image width
+        # 4. Child"s height > 0.1*Image height
+        # 5. 0.25*Parent"s area < Child"s area < 0.45*Parent"s area
+        # 6. Child is a black, and Parent is white
+        # 7. Center of Child and center of parent should overlap
+        if prt_shape["width"] * 0.56 < child_shape["width"] \
+                < prt_shape["width"] * 0.76 \
+                and prt_shape["height"] * 0.56 < child_shape["height"] \
+                < prt_shape["height"] * 0.76 \
+                and child_shape["width"] > 0.1 * size[1] \
+                and child_shape["height"] > 0.1 * size[0] \
+                and 0.30 * prt_area < child_area < 0.50 * prt_area \
+                and img_bw[child_shape["cty"]][child_shape["ctx"]] == 0 \
+                and img_bw[child_shape["top"]][child_shape["left"]] == 255 \
+                and dist_x < 0.1 * child_shape["width"] \
+                and dist_y < 0.1 * child_shape["height"]:
+            # If raw capture is not available, check the camera is placed right
+            # in front of the test page:
+            # 1. Distances between parent and child horizontally on both side,0
+            #    dist_left and dist_right, should be close.
+            # 2. Distances between parent and child vertically on both side,
+            #    dist_top and dist_bottom, should be close.
+            if not raw_avlb:
+                dist_left = child_shape["left"] - prt_shape["left"]
+                dist_right = prt_shape["right"] - child_shape["right"]
+                dist_top = child_shape["top"] - prt_shape["top"]
+                dist_bottom = prt_shape["bottom"] - child_shape["bottom"]
+                if abs(dist_left-dist_right) > 0.05 * child_shape["width"] or \
+                        abs(dist_top-dist_bottom) > \
+                        0.05 * child_shape["height"]:
+                    continue
+            # Calculate aspect ratio
+            aspect_ratio = float(child_shape["width"]) / \
+                           float(child_shape["height"])
+            circle_ctx = child_shape["ctx"]
+            circle_cty = child_shape["cty"]
+            circle_w = float(child_shape["width"])
+            circle_h = float(child_shape["height"])
+            cc_ct = {"hori": float(child_shape["ctx"]-size[1]/2) / circle_w,
+                     "vert": float(child_shape["cty"]-size[0]/2) / circle_h}
+            num_circle += 1
+            # If more than one circle found, break
+            if num_circle == 2:
+                break
+
+    if num_circle == 0:
+        its.image.write_image(img/255, img_name, True)
+        print "No black circle was detected. Please take pictures according " \
+              "to instruction carefully!\n"
+        assert (num_circle == 1)
+
+    if num_circle > 1:
+        its.image.write_image(img/255, img_name, True)
+        print "More than one black circle was detected. Background of scene " \
+              "may be too complex.\n"
+        assert (num_circle == 1)
+
+    # draw circle center and image center, and save the image
+    line_width = max(1, max(size)/500)
+    move_text_dist = line_width * 3
+    cv2.line(img, (circle_ctx, circle_cty), (size[1]/2, size[0]/2),
+             (255, 0, 0), line_width)
+    if circle_cty > size[0]/2:
+        move_text_down_circle = 4
+        move_text_down_image = -1
+    else:
+        move_text_down_circle = -1
+        move_text_down_image = 4
+    if circle_ctx > size[1]/2:
+        move_text_right_circle = 2
+        move_text_right_image = -1
+    else:
+        move_text_right_circle = -1
+        move_text_right_image = 2
+    # circle center
+    text_circle_x = move_text_dist * move_text_right_circle + circle_ctx
+    text_circle_y = move_text_dist * move_text_down_circle + circle_cty
+    cv2.circle(img, (circle_ctx, circle_cty), line_width*2, (255, 0, 0), -1)
+    cv2.putText(img, "circle center", (text_circle_x, text_circle_y),
+                cv2.FONT_HERSHEY_SIMPLEX, line_width/2.0, (255, 0, 0),
+                line_width)
+    # image center
+    text_imgct_x = move_text_dist * move_text_right_image + size[1]/2
+    text_imgct_y = move_text_dist * move_text_down_image + size[0]/2
+    cv2.circle(img, (size[1]/2, size[0]/2), line_width*2, (255, 0, 0), -1)
+    cv2.putText(img, "image center", (text_imgct_x, text_imgct_y),
+                cv2.FONT_HERSHEY_SIMPLEX, line_width/2.0, (255, 0, 0),
+                line_width)
+    its.image.write_image(img/255, img_name, True)
+
+    print "Aspect ratio: %.3f" % aspect_ratio
+    print "Circle center position regarding to image center: %.3fx%.3f" % \
+            (cc_ct["vert"], cc_ct["hori"])
+    return aspect_ratio, cc_ct, (circle_w, circle_h)
+
+
+def component_shape(contour):
+    """ Measure the shape for a connected component in the aspect ratio test
+
+    Args:
+        contour: return from cv2.findContours. A list of pixel coordinates of
+        the contour.
+
+    Returns:
+        The most left, right, top, bottom pixel location, height, width, and
+        the center pixel location of the contour.
+    """
+    shape = {"left": np.inf, "right": 0, "top": np.inf, "bottom": 0,
+             "width": 0, "height": 0, "ctx": 0, "cty": 0}
+    for pt in contour:
+        if pt[0][0] < shape["left"]:
+            shape["left"] = pt[0][0]
+        if pt[0][0] > shape["right"]:
+            shape["right"] = pt[0][0]
+        if pt[0][1] < shape["top"]:
+            shape["top"] = pt[0][1]
+        if pt[0][1] > shape["bottom"]:
+            shape["bottom"] = pt[0][1]
+    shape["width"] = shape["right"] - shape["left"] + 1
+    shape["height"] = shape["bottom"] - shape["top"] + 1
+    shape["ctx"] = (shape["left"]+shape["right"])/2
+    shape["cty"] = (shape["top"]+shape["bottom"])/2
+    return shape
+
+
+if __name__ == "__main__":
+    main()
diff --git a/apps/CameraITS/tests/scene5/test_lens_shading_and_color_uniformity.py b/apps/CameraITS/tests/scene5/test_lens_shading_and_color_uniformity.py
new file mode 100644
index 0000000..c2b46d2
--- /dev/null
+++ b/apps/CameraITS/tests/scene5/test_lens_shading_and_color_uniformity.py
@@ -0,0 +1,248 @@
+# Copyright 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import its.image
+import its.caps
+import its.device
+import its.objects
+import os.path
+import numpy
+import cv2
+import math
+
+
+def main():
+    """ Test that the lens shading correction is applied appropriately, and
+    color of a monochrome uniform scene is evenly distributed, for example,
+    when a diffuser is placed in front of the camera.
+    Perform this test on a yuv frame with auto 3a. Lens shading is evaluated
+    based on the y channel. Measure the average y value for each sample block
+    specified, and then determine pass/fail by comparing with the center y
+    value.
+    The color uniformity test is evaluated in r/g and b/g space. At specified
+    radius of the image, the variance of r/g and b/g value need to be less than
+    a threshold in order to pass the test.
+    """
+    NAME = os.path.basename(__file__).split(".")[0]
+    # Sample block center location and length
+    Num_radius = 8
+    spb_r = 1/2./(Num_radius*2-1)
+    SPB_CT_LIST = numpy.arange(spb_r, 1/2., spb_r*2)
+
+    # Threshold for pass/fail
+    THRES_LS_CT = 0.9   # len shading allowance for center
+    THRES_LS_CN = 0.6   # len shading allowance for corner
+    THRES_UFMT = 0.1   # uniformity allowance
+    # Drawing color
+    RED = (1, 0, 0)   # blocks failed the test
+    GREEN = (0, 0.7, 0.3)   # blocks passed the test
+
+    with its.device.ItsSession() as cam:
+        props = cam.get_camera_properties()
+        # Converge 3A and get the estimates.
+        sens, exp, gains, xform, focus = cam.do_3a(get_results=True,
+                                                   do_af=False,
+                                                   lock_ae=True,
+                                                   lock_awb=True)
+        print "AE sensitivity %d, exposure %dms" % (sens, exp / 1000000.0)
+        print "AWB gains", gains
+        print "AWB transform", xform
+        print "AF distance", focus
+        req = its.objects.auto_capture_request()
+        img_size = its.objects.get_available_output_sizes("yuv", props)
+        w = img_size[0][0]
+        h = img_size[0][1]
+        out_surface = {"format": "yuv"}
+        cap = cam.do_capture(req, out_surface)
+        print "Captured yuv %dx%d" % (w, h)
+        # rgb image
+        img_rgb = its.image.convert_capture_to_rgb_image(cap)
+        img_g_pos = img_rgb[:, :, 1] + 0.001  # in case g channel is zero.
+        r_g = img_rgb[:, :, 0] / img_g_pos
+        b_g = img_rgb[:, :, 2] / img_g_pos
+        # y channel
+        img_y = its.image.convert_capture_to_planes(cap)[0]
+        its.image.write_image(img_y, "%s_y_plane.png" % NAME, True)
+
+        # Evaluation begins
+        # image with legend
+        img_legend_ls = numpy.copy(img_rgb)
+        img_legend_ufmt = numpy.copy(img_rgb)
+        line_width = max(2, int(max(h, w)/500))  # line width of legend
+        font_scale = line_width / 7.0   # font scale of the basic font size
+        text_height = cv2.getTextSize('gf', cv2.FONT_HERSHEY_SIMPLEX,
+                                      font_scale, line_width)[0][1]
+        text_offset = int(text_height*1.5)
+
+        # center block average Y value, r/g, and b/g
+        top = int((0.5-spb_r)*h)
+        bottom = int((0.5+spb_r)*h)
+        left = int((0.5-spb_r)*w)
+        right = int((0.5+spb_r)*w)
+        center_y = numpy.mean(img_y[top:bottom, left:right])
+        center_r_g = numpy.mean(r_g[top:bottom, left:right])
+        center_b_g = numpy.mean(b_g[top:bottom, left:right])
+        # add legend to lens Shading figure
+        cv2.rectangle(img_legend_ls, (left, top), (right, bottom), GREEN,
+                      line_width)
+        draw_legend(img_legend_ls, ["Y: %.2f" % center_y],
+                    [left+text_offset, bottom-text_offset],
+                    font_scale, text_offset, GREEN, int(line_width/2))
+        # add legend to color uniformity figure
+        cv2.rectangle(img_legend_ufmt, (left, top), (right, bottom), GREEN,
+                      line_width)
+        texts = ["r/g: %.2f" % center_r_g,
+                 "b/g: %.2f" % center_b_g]
+        draw_legend(img_legend_ufmt, texts,
+                    [left+text_offset, bottom-text_offset*2],
+                    font_scale, text_offset, GREEN, int(line_width/2))
+
+        # evaluate y and r/g, b/g for each block
+        ls_test_failed = []
+        cu_test_failed = []
+        ls_thres_h = center_y * 1.001
+        dist_max = math.sqrt(pow(w, 2)+pow(h, 2))/2
+        for spb_ct in SPB_CT_LIST:
+            # list sample block center location
+            num_sample = (1-spb_ct*2)/spb_r/2 + 1
+            ct_cord_x = numpy.concatenate(
+                        (numpy.arange(spb_ct, 1-spb_ct+spb_r, spb_r*2),
+                         spb_ct*numpy.ones((num_sample-1)),
+                         (1-spb_ct)*numpy.ones((num_sample-1)),
+                         numpy.arange(spb_ct, 1-spb_ct+spb_r, spb_r*2)))
+            ct_cord_y = numpy.concatenate(
+                        (spb_ct*numpy.ones(num_sample+1),
+                         numpy.arange(spb_ct+spb_r*2, 1-spb_ct, spb_r*2),
+                         numpy.arange(spb_ct+spb_r*2, 1-spb_ct, spb_r*2),
+                         (1-spb_ct)*numpy.ones(num_sample+1)))
+
+            blocks_info = []
+            max_r_g = 0
+            min_r_g = float("inf")
+            max_b_g = 0
+            min_b_g = float("inf")
+            for spb_ctx, spb_cty in zip(ct_cord_x, ct_cord_y):
+                top = int((spb_cty-spb_r)*h)
+                bottom = int((spb_cty+spb_r)*h)
+                left = int((spb_ctx-spb_r)*w)
+                right = int((spb_ctx+spb_r)*w)
+                dist_to_img_center = math.sqrt(pow(abs(spb_ctx-0.5)*w, 2)
+                                     + pow(abs(spb_cty-0.5)*h, 2))
+                ls_thres_l = ((THRES_LS_CT-THRES_LS_CN)*(1-dist_to_img_center
+                              /dist_max)+THRES_LS_CN) * center_y
+
+                # compute block average value
+                block_y = numpy.mean(img_y[top:bottom, left:right])
+                block_r_g = numpy.mean(r_g[top:bottom, left:right])
+                block_b_g = numpy.mean(b_g[top:bottom, left:right])
+                max_r_g = max(max_r_g, block_r_g)
+                min_r_g = min(min_r_g, block_r_g)
+                max_b_g = max(max_b_g, block_b_g)
+                min_b_g = min(min_b_g, block_b_g)
+                blocks_info.append({"pos": [top, bottom, left, right],
+                                    "block_r_g": block_r_g,
+                                    "block_b_g": block_b_g})
+                # check lens shading and draw legend
+                if block_y > ls_thres_h or block_y < ls_thres_l:
+                    ls_test_failed.append({"pos": [top, bottom, left,
+                                                   right],
+                                           "val": block_y,
+                                           "thres_l": ls_thres_l})
+                    legend_color = RED
+                else:
+                    legend_color = GREEN
+                text_bottom = bottom - text_offset
+                cv2.rectangle(img_legend_ls, (left, top), (right, bottom),
+                              legend_color, line_width)
+                draw_legend(img_legend_ls, ["Y: %.2f" % block_y],
+                            [left+text_offset, text_bottom], font_scale,
+                            text_offset, legend_color, int(line_width/2))
+
+            # check color uniformity and draw legend
+            ufmt_r_g = (max_r_g-min_r_g) / center_r_g
+            ufmt_b_g = (max_b_g-min_b_g) / center_b_g
+            if ufmt_r_g > THRES_UFMT or ufmt_b_g > THRES_UFMT:
+                cu_test_failed.append({"pos": spb_ct,
+                                       "ufmt_r_g": ufmt_r_g,
+                                       "ufmt_b_g": ufmt_b_g})
+                legend_color = RED
+            else:
+                legend_color = GREEN
+            for block in blocks_info:
+                top, bottom, left, right = block["pos"]
+                cv2.rectangle(img_legend_ufmt, (left, top), (right, bottom),
+                              legend_color, line_width)
+                texts = ["r/g: %.2f" % block["block_r_g"],
+                         "b/g: %.2f" % block["block_b_g"]]
+                text_bottom = bottom - text_offset * 2
+                draw_legend(img_legend_ufmt, texts,
+                            [left+text_offset, text_bottom], font_scale,
+                            text_offset, legend_color, int(line_width/2))
+
+        # Save images
+        its.image.write_image(img_legend_ufmt,
+                              "%s_color_uniformity_result.png" % NAME, True)
+        its.image.write_image(img_legend_ls,
+                              "%s_lens_shading_result.png" % NAME, True)
+
+        # print results
+        lens_shading_test_passed = True
+        color_uniformity_test_passed = True
+        if len(ls_test_failed) > 0:
+            lens_shading_test_passed = False
+            print "\nLens shading test summary"
+            print "Center block average Y value: %.3f" % center_y
+            print "Blocks failed in the lens shading test:"
+            for block in ls_test_failed:
+                top, bottom, left, right = block["pos"]
+                print "Block position: [top: %d, bottom: %d, left: %d, right: "\
+                      "%d]; average Y value: %.3f; valid value range: %.3f ~ " \
+                      "%.3f" % (top, bottom, left, right, block["val"],
+                      block["thres_l"], ls_thres_h)
+        if len(cu_test_failed) > 0:
+            color_uniformity_test_passed = False
+            print "\nColor uniformity test summary"
+            print "Valid color uniformity value range: 0 ~ ", THRES_UFMT
+            print "Areas that failed the color uniformity test:"
+            for rd in cu_test_failed:
+                print "Radius position: %.3f; r/g uniformity: %.3f; b/g " \
+                      "uniformity: %.3f" % (rd["pos"], rd["ufmt_r_g"],
+                      rd["ufmt_b_g"])
+        assert lens_shading_test_passed
+        assert color_uniformity_test_passed
+
+
+def draw_legend(img, texts, text_org, font_scale, text_offset, legend_color,
+                line_width):
+    """ Draw legend on an image.
+
+    Args:
+        img: Numpy float image array in RGB, with pixel values in [0,1].
+        texts: list of legends. Each element in the list is a line of legend.
+        text_org: tuple of the bottom left corner of the text position in
+            pixels, horizontal and vertical.
+        font_scale: float number. Font scale of the basic font size.
+        text_offset: text line width in pixels.
+        legend_color: text color in rgb value.
+        line_width: strokes width in pixels.
+    """
+    for text in texts:
+        cv2.putText(img, text, (text_org[0], text_org[1]),
+                    cv2.FONT_HERSHEY_SIMPLEX, font_scale,
+                    legend_color, line_width)
+        text_org[1] += text_offset
+
+
+if __name__ == '__main__':
+    main()
diff --git a/apps/CameraITS/tests/sensor_fusion/test_sensor_fusion.py b/apps/CameraITS/tests/sensor_fusion/test_sensor_fusion.py
index 53a7638..e6fe4c2 100644
--- a/apps/CameraITS/tests/sensor_fusion/test_sensor_fusion.py
+++ b/apps/CameraITS/tests/sensor_fusion/test_sensor_fusion.py
@@ -31,11 +31,11 @@
 
 NAME = os.path.basename(__file__).split(".")[0]
 
-# Capture 210 QVGA frames (which is 7s at 30fps)
+# Capture 210 VGA frames (which is 7s at 30fps)
 N = 210
-W,H = 320,240
+W,H = 640,480
 
-FEATURE_PARAMS = dict( maxCorners = 50,
+FEATURE_PARAMS = dict( maxCorners = 80,
                        qualityLevel = 0.3,
                        minDistance = 7,
                        blockSize = 7 )
@@ -273,7 +273,7 @@
             frame = frames[i]
             for x,y in p0[st==1]:
                 cv2.circle(frame, (x,y), 3, (100,100,255), -1)
-            its.image.write_image(frame, "%s_features.jpg"%(NAME))
+            its.image.write_image(frame, "%s_features.png"%(NAME))
     return numpy.array(rots)
 
 def get_cam_times(cam_events):
@@ -307,7 +307,7 @@
     n = len(events["cam"])
     frames = []
     for i in range(n):
-        img = Image.open("%s_frame%03d.jpg"%(NAME,i))
+        img = Image.open("%s_frame%03d.png"%(NAME,i))
         w,h = img.size[0:2]
         frames.append(numpy.array(img).reshape(h,w,3) / 255.0)
     return events, frames
@@ -360,7 +360,7 @@
         for i,c in enumerate(caps):
             img = its.image.convert_capture_to_rgb_image(c)
             frames.append(img)
-            its.image.write_image(img, "%s_frame%03d.jpg"%(NAME,i))
+            its.image.write_image(img, "%s_frame%03d.png"%(NAME,i))
 
         return events, frames
 
diff --git a/apps/CameraITS/tools/run_all_tests.py b/apps/CameraITS/tools/run_all_tests.py
index dd12512..3ed908e 100644
--- a/apps/CameraITS/tools/run_all_tests.py
+++ b/apps/CameraITS/tools/run_all_tests.py
@@ -43,17 +43,24 @@
             "test_yuv_plus_jpeg"
         ],
         "scene2":[],
-        "scene3":[]
+        "scene3":[],
+        "scene4":[],
+        "scene5":[]
     }
 
     # Get all the scene0 and scene1 tests, which can be run using the same
     # physical setup.
-    scenes = ["scene0", "scene1", "scene2", "scene3"]
+    scenes = ["scene0", "scene1", "scene2", "scene3", "scene4", "scene5"]
     scene_req = {
         "scene0" : None,
         "scene1" : "A grey card covering at least the middle 30% of the scene",
         "scene2" : "A picture containing human faces",
-        "scene3" : "A chart containing sharp edges like ISO 12233"
+        "scene3" : "A chart containing sharp edges like ISO 12233",
+        "scene4" : "A specific test page of a circle covering at least the "
+                   "middle 50% of the scene. See CameraITS.pdf section 2.3.4 "
+                   "for more details",
+        "scene5" : "Capture images with a diffuser attached to the camera. See "
+                   "CameraITS.pdf section 2.3.4 for more details"
     }
     tests = []
     for d in scenes:
diff --git a/apps/CtsVerifier/Android.mk b/apps/CtsVerifier/Android.mk
index ad78a59..79e8a36 100644
--- a/apps/CtsVerifier/Android.mk
+++ b/apps/CtsVerifier/Android.mk
@@ -27,17 +27,18 @@
 
 LOCAL_STATIC_JAVA_LIBRARIES := android-ex-camera2 \
                                android-support-v4 \
-                               compatibility-common-util-devicesidelib_v2 \
+                               compatibility-common-util-devicesidelib \
                                cts-sensors-tests \
+                               cts-location-tests \
                                ctstestrunner \
                                apache-commons-math \
                                androidplot \
                                ctsverifier-opencv \
-                               core-tests \
+                               core-tests-support \
                                android-support-v4  \
                                mockito-target \
                                mockwebserver \
-                               compatibility-device-util_v2 \
+                               compatibility-device-util \
 
 LOCAL_PACKAGE_NAME := CtsVerifier
 
@@ -49,6 +50,8 @@
 
 LOCAL_DEX_PREOPT := false
 
+LOCAL_JAVA_LANGUAGE_VERSION := 1.8
+
 include $(BUILD_PACKAGE)
 
 # Build CTS verifier framework as a libary.
@@ -73,8 +76,8 @@
     $(call all-Iaidl-files-under, src)
 
 LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4 \
-                               compatibility-common-util-devicesidelib_v2 \
-                               compatibility-device-util_v2 \
+                               compatibility-common-util-devicesidelib \
+                               compatibility-device-util \
 
 include $(BUILD_STATIC_JAVA_LIBRARY)
 
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index 336eb0a..ba03d60 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -20,9 +20,10 @@
       android:versionCode="5"
       android:versionName="6.0_r2">
 
-    <uses-sdk android:minSdkVersion="19" android:targetSdkVersion="23"/>
+    <uses-sdk android:minSdkVersion="19" android:targetSdkVersion="24"/>
 
     <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
+    <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"/>
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
     <uses-permission android:name="android.permission.BLUETOOTH" />
@@ -55,9 +56,9 @@
     <uses-permission android:name="android.permission.READ_CONTACTS"/>
     <uses-permission android:name="android.permission.WRITE_CONTACTS"/>
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
-    <uses-permission android:name="com.android.providers.tv.permission.READ_EPG_DATA" />
     <uses-permission android:name="com.android.providers.tv.permission.WRITE_EPG_DATA" />
     <uses-permission android:name="android.permission.USE_FINGERPRINT"/>
+    <uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY" />
 
     <!-- Needed by the Audio Quality Verifier to store the sound samples that will be mailed. -->
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
@@ -142,6 +143,15 @@
                     android:value="android.software.backup" />
         </activity>
 
+        <activity android:name=".backup.BackupAccessibilityTestActivity" android:label="@string/backup_accessibility_test">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.cts.intent.category.MANUAL_TEST" />
+            </intent-filter>
+            <meta-data android:name="test_required_features"
+                    android:value="android.software.backup" />
+        </activity>
+
         <activity android:name=".bluetooth.BluetoothTestActivity"
                 android:label="@string/bluetooth_test"
                 android:configChanges="keyboardHidden|orientation|screenSize">
@@ -427,6 +437,59 @@
             <meta-data android:name="test_required_features" android:value="android.hardware.location.gps" />
         </activity>
 
+        <activity android:name=".location.GnssMeasurementRegistrationTestsActivity"
+            android:label="@string/location_gnss_reg_test"
+            android:screenOrientation="locked">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.cts.intent.category.MANUAL_TEST"/>
+            </intent-filter>
+            <meta-data android:name="test_category" android:value="@string/test_category_hardware"/>
+            <meta-data android:name="test_required_features" android:value="android.hardware.location.gps" />
+        </activity>
+
+        <activity android:name=".location.GnssMeasurementValuesTestsActivity"
+            android:label="@string/location_gnss_value_test"
+            android:screenOrientation="locked">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.cts.intent.category.MANUAL_TEST"/>
+            </intent-filter>
+            <meta-data android:name="test_category" android:value="@string/test_category_hardware"/>
+            <meta-data android:name="test_required_features" android:value="android.hardware.location.gps" />
+        </activity>
+
+        <activity android:name=".location.GnssMeasurementWhenNoLocationTestsActivity"
+            android:label="@string/location_gnss_measure_no_location_test"
+            android:screenOrientation="locked">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.cts.intent.category.MANUAL_TEST"/>
+            </intent-filter>
+            <meta-data android:name="test_category" android:value="@string/test_category_hardware"/>
+            <meta-data android:name="test_required_features" android:value="android.hardware.location.gps" />
+        </activity>
+
+        <activity android:name=".location.GnssNavigationMessageTestsActivity"
+            android:label="@string/location_gnss_nav_msg_test"
+            android:screenOrientation="locked">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.cts.intent.category.MANUAL_TEST"/>
+            </intent-filter>
+            <meta-data android:name="test_category" android:value="@string/test_category_hardware"/>
+            <meta-data android:name="test_required_features" android:value="android.hardware.location.gps" />
+        </activity>
+
+        <activity android:name=".location.LocationListenerActivity"
+                android:label="@string/location_listener_activity"
+                android:configChanges="keyboardHidden|orientation|screenSize">
+            <intent-filter>
+                <action android:name="com.android.cts.verifier.location.SET_LOCATION_AND_CHECK" />
+                <category android:name="android.intent.category.DEFAULT"></category>
+                </intent-filter>
+        </activity>
+
         <activity android:name=".net.ConnectivityScreenOffTestActivity"
                 android:label="@string/network_screen_off_test">
             <intent-filter>
@@ -458,6 +521,16 @@
                 android:configChanges="keyboardHidden|orientation|screenSize">
         </activity>
 
+        <activity android:name="com.android.cts.verifier.nfc.hcef.HceFReaderTestActivity"
+                android:label="@string/nfc_hce_f_reader_tests"
+                android:configChanges="keyboardHidden|orientation|screenSize">
+        </activity>
+
+        <activity android:name="com.android.cts.verifier.nfc.hcef.HceFEmulatorTestActivity"
+                android:label="@string/nfc_hce_f_emulator_tests"
+                android:configChanges="keyboardHidden|orientation|screenSize">
+        </activity>
+
         <activity android:name=".nfc.NdefPushSenderActivity"
                 android:label="@string/nfc_ndef_push_sender"
                 android:configChanges="keyboardHidden|orientation|screenSize" />
@@ -562,6 +635,14 @@
                 android:label="@string/nfc_hce_other_conflicting_prefix_aids_emulator"
                 android:configChanges="keyboardHidden|orientation|screenSize" />
 
+        <activity android:name=".nfc.hcef.HceFEmulatorActivity"
+                android:label="@string/nfc_hce_f_emulator"
+                android:configChanges="keyboardHidden|orientation|screenSize" />
+
+        <activity android:name=".nfc.hcef.HceFReaderActivity"
+                android:label="@string/nfc_hce_f_reader"
+                android:configChanges="keyboardHidden|orientation|screenSize" />
+
         <!-- services used for testing NFC host-based card emulation -->
         <service android:name=".nfc.hce.PaymentService1" android:exported="true"
                  android:permission="android.permission.BIND_NFC_SERVICE"
@@ -691,6 +772,15 @@
             <meta-data android:name="android.nfc.cardemulation.host_apdu_service" android:resource="@xml/payment_aid_list_1"/>
         </service>
 
+        <service
+            android:name=".nfc.hcef.MyHostFelicaService"
+            android:enabled="true"
+            android:exported="true" android:permission="android.permission.BIND_NFC_SERVICE">
+            <intent-filter>
+                <action android:name="android.nfc.cardemulation.action.HOST_NFCF_SERVICE"/>
+            </intent-filter>
+            <meta-data android:name="android.nfc.cardemulation.host_nfcf_service" android:resource="@xml/felicaservice"/>
+        </service>
         <!-- Service used for Camera ITS tests -->
         <service android:name=".camera.its.ItsService" >
             <intent-filter>
@@ -1040,6 +1130,17 @@
             <meta-data android:name="test_excluded_features"
                     android:value="android.hardware.type.watch" />
         </activity>
+
+        <activity android:name=".usb.MtpHostTestActivity" android:label="@string/mtp_host_test">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.cts.intent.category.MANUAL_TEST" />
+            </intent-filter>
+            <meta-data android:name="test_category" android:value="@string/test_category_hardware" />
+            <meta-data android:name="test_required_features" android:value="android.hardware.usb.host" />
+            <meta-data android:name="test_excluded_features" android:value="android.hardware.type.automotive" />
+        </activity>
+
 <!-- Turned off Sensor Power Test in initial L release
         <activity android:name=".sensors.SensorPowerTestActivity"
                 android:label="@string/sensor_power_test"
@@ -1073,6 +1174,15 @@
             <meta-data android:name="test_category" android:value="@string/test_category_notifications" />
         </activity>
 
+        <activity android:name=".notifications.ConditionProviderVerifierActivity"
+                  android:label="@string/cp_test">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.cts.intent.category.MANUAL_TEST" />
+            </intent-filter>
+            <meta-data android:name="test_category" android:value="@string/test_category_notifications" />
+        </activity>
+
         <activity android:name=".notifications.AttentionManagementVerifierActivity"
                 android:label="@string/attention_test">
             <intent-filter>
@@ -1104,6 +1214,15 @@
             </intent-filter>
         </service>
 
+        <service android:name=".notifications.MockConditionProvider"
+                 android:exported="true"
+                 android:label="@string/cp_service_name"
+                 android:permission="android.permission.BIND_CONDITION_PROVIDER_SERVICE">
+            <intent-filter>
+                <action android:name="android.service.notification.ConditionProviderService" />
+            </intent-filter>
+        </service>
+
         <service  android:name=".notifications.InteractiveVerifierActivity$DismissService"/>
 
         <activity android:name=".security.CAInstallNotificationVerifierActivity"
@@ -1377,6 +1496,20 @@
                 android:label="@string/positive_device_owner">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
+                <action android:name="com.android.cts.verifier.managedprovisioning.action.CHECK_DEVICE_OWNER" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.cts.intent.category.MANUAL_TEST" />
+            </intent-filter>
+            <meta-data android:name="test_category" android:value="@string/test_category_managed_provisioning" />
+            <meta-data android:name="test_required_features" android:value="android.software.device_admin" />
+        </activity>
+
+        <activity android:name=".managedprovisioning.DeviceOwnerRequestingBugreportTestActivity"
+                android:label="@string/device_owner_requesting_bugreport_tests">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <action android:name="com.android.cts.verifier.managedprovisioning.action.CHECK_DEVICE_OWNER_FOR_REQUESTING_BUGREPORT" />
+                <category android:name="android.intent.category.DEFAULT" />
                 <category android:name="android.cts.intent.category.MANUAL_TEST" />
             </intent-filter>
             <meta-data android:name="test_category" android:value="@string/test_category_managed_provisioning" />
@@ -1435,6 +1568,58 @@
             </intent-filter>
         </activity-alias>
 
+        <activity android:name=".managedprovisioning.OrganizationInfoTestActivity"
+                android:label="@string/provisioning_byod_organization_info">
+        </activity>
+
+        <activity android:name=".managedprovisioning.PolicyTransparencyTestListActivity"
+                android:label="@string/device_profile_owner_policy_transparency_test">
+            <intent-filter>
+                <action android:name="com.android.cts.verifier.managedprovisioning.action.CHECK_POLICY_TRANSPARENCY" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".managedprovisioning.PolicyTransparencyTestActivity">
+            <intent-filter>
+                <action android:name="com.android.cts.verifier.managedprovisioning.action.SHOW_POLICY_TRANSPARENCY_TEST" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".managedprovisioning.CommandReceiverActivity"
+                android:theme="@android:style/Theme.NoDisplay"
+                android:noHistory="true">
+            <intent-filter>
+                <action android:name="com.android.cts.verifier.managedprovisioning.action.EXECUTE_COMMAND" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".managedprovisioning.SetSupportMessageActivity">
+            <intent-filter>
+                <action android:name="com.android.cts.verifier.managedprovisioning.action.SET_SUPPORT_MSG" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+
+        <service android:name=".managedprovisioning.PolicyTransparencyTestActivity$DummyInputMethod"
+                android:label="@string/dummy_input_method_label"
+                android:permission="android.permission.BIND_INPUT_METHOD">
+            <intent-filter>
+                <action android:name="android.view.InputMethod" />
+            </intent-filter>
+            <meta-data android:name="android.view.im" android:resource="@xml/dummy_method" />
+        </service>
+
+        <service android:name=".managedprovisioning.PolicyTransparencyTestActivity$DummyAccessibilityService"
+                android:label="@string/dummy_accessibility_service_label"
+                android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
+            <intent-filter>
+                <action android:name="android.accessibilityservice.AccessibilityService" />
+            </intent-filter>
+        </service>
+
         <activity android:name=".managedprovisioning.AuthenticationBoundKeyTestActivity">
             <intent-filter>
                 <action android:name="com.android.cts.verifier.managedprovisioning.action.AUTH_BOUND_KEY_TEST" />
@@ -1457,6 +1642,18 @@
             <meta-data android:name="test_required_features" android:value="android.software.managed_users:android.software.device_admin" />
         </activity>
 
+        <activity android:name=".managedprovisioning.ByodProvisioningTestActivity"
+                android:label="@string/provisioning_tests_byod">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.cts.intent.category.MANUAL_TEST" />
+            </intent-filter>
+            <meta-data android:name="test_category" android:value="@string/test_category_managed_provisioning" />
+            <meta-data android:name="test_required_features" android:value="android.software.managed_users:android.software.device_admin" />
+        </activity>
+
+        <activity android:name=".managedprovisioning.ByodProvisioningTestActivity$ProvisioningStartingActivity" />
+
         <activity android:name=".managedprovisioning.ByodHelperActivity">
             <intent-filter>
                 <action android:name="com.android.cts.verifier.managedprovisioning.BYOD_QUERY" />
@@ -1478,6 +1675,9 @@
                 <action android:name="com.android.cts.verifier.managedprovisioning.NOTIFICATION" />
                 <action android:name="com.android.cts.verifier.managedprovisioning.LOCKSCREEN_NOTIFICATION" />
                 <action android:name="com.android.cts.verifier.managedprovisioning.CLEAR_NOTIFICATION" />
+                <action android:name="com.android.cts.verifier.managedprovisioning.TEST_SELECT_WORK_CHALLENGE" />
+                <action android:name="com.android.cts.verifier.managedprovisioning.TEST_CONFIRM_WORK_CREDENTIALS" />
+                <action android:name="com.android.cts.verifier.managedprovisioning.TEST_ORGANIZATION_INFO" />
                 <category android:name="android.intent.category.DEFAULT"></category>
             </intent-filter>
         </activity>
@@ -1839,6 +2039,16 @@
             <meta-data android:name="test_required_features" android:value="android.hardware.usb.host" />
         </activity>
 
+        <activity android:name=".audio.AudioFrequencyUnprocessedActivity"
+                  android:label="@string/audio_frequency_unprocessed_test">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.cts.intent.category.MANUAL_TEST" />
+            </intent-filter>
+            <meta-data android:name="test_category" android:value="@string/test_category_audio" />
+            <meta-data android:name="test_required_features" android:value="android.hardware.microphone" />
+        </activity>
+
         <service android:name=".tv.MockTvInputService"
             android:permission="android.permission.BIND_TV_INPUT">
             <intent-filter>
diff --git a/apps/CtsVerifier/jni/audio_loopback/Android.mk b/apps/CtsVerifier/jni/audio_loopback/Android.mk
index 3dfbc34..b302f44 100644
--- a/apps/CtsVerifier/jni/audio_loopback/Android.mk
+++ b/apps/CtsVerifier/jni/audio_loopback/Android.mk
@@ -23,6 +23,7 @@
 LOCAL_PRELINK_MODULE := false
 
 LOCAL_LDFLAGS := -Wl,--hash-style=sysv
-LOCAL_CFLAGS := -DSTDC_HEADERS
+LOCAL_CFLAGS := -DSTDC_HEADERS \
+    -Werror -Wall
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/apps/CtsVerifier/jni/audio_loopback/sles.cpp b/apps/CtsVerifier/jni/audio_loopback/sles.cpp
index 7859d35..b0b683b 100644
--- a/apps/CtsVerifier/jni/audio_loopback/sles.cpp
+++ b/apps/CtsVerifier/jni/audio_loopback/sles.cpp
@@ -40,14 +40,14 @@
     if (ppSles != NULL) {
         sles_data * pSles = (sles_data*) calloc(1, sizeof (sles_data));
 
-        SLES_PRINTF("malloc %d bytes at %p",sizeof(sles_data), pSles);
+        SLES_PRINTF("malloc %zu bytes at %p", sizeof(sles_data), pSles);
         *ppSles = pSles;
         if (pSles != NULL)
         {
             SLES_PRINTF("creating server. Sampling rate =%d, frame count = %d",samplingRate,
                     frameCount);
             status = slesCreateServer(pSles, samplingRate, frameCount, micSource);
-            SLES_PRINTF("slesCreateServer =%d",status);
+            SLES_PRINTF("slesCreateServer =%d", status);
         }
     }
     return status;
@@ -260,6 +260,7 @@
     //        char **freeBuffers;
 
     // Buffer indices
+/*
     pSles->rxFront;    // oldest recording
     pSles->rxRear;     // next to be recorded
     pSles->txFront;    // oldest playing
@@ -268,9 +269,8 @@
     pSles->freeRear;   // next to be freed
 
     pSles->fifo; //(*)
+*/
     pSles->fifo2Buffer = NULL;
-    pSles->recorderBufferQueue;
-    pSles->playerBufferQueue;
 
     // compute total free buffers as -r plus -t
     pSles->freeBufCount = pSles->rxBufCount + pSles->txBufCount;
@@ -325,7 +325,6 @@
     SLresult result;
 
     // create engine
-    pSles->engineObject;
     result = slCreateEngine(&(pSles->engineObject), 0, NULL, 0, NULL, NULL);
     ASSERT_EQ(SL_RESULT_SUCCESS, result);
     result = (*(pSles->engineObject))->Realize(pSles->engineObject, SL_BOOLEAN_FALSE);
@@ -336,7 +335,6 @@
     ASSERT_EQ(SL_RESULT_SUCCESS, result);
 
     // create output mix
-    pSles->outputmixObject;
     result = (*engineEngine)->CreateOutputMix(engineEngine, &(pSles->outputmixObject), 0, NULL,
             NULL);
     ASSERT_EQ(SL_RESULT_SUCCESS, result);
diff --git a/apps/CtsVerifier/proguard.flags b/apps/CtsVerifier/proguard.flags
index 5a2beb5..187e8d2 100644
--- a/apps/CtsVerifier/proguard.flags
+++ b/apps/CtsVerifier/proguard.flags
@@ -14,6 +14,14 @@
     public <methods>;
 }
 
+# ensure we keep public Gnss Measurement test methods, these are needed at runtime
+-keepclassmembers class * extends com.android.cts.verifier.location.BaseGnssTestActivity {
+    public <methods>;
+}
+-keepclassmembers class * extends android.location.cts.GnssTestCase {
+    public <methods>;
+}
+
 -keepclasseswithmembers class * extends com.android.cts.verifier.location.LocationModeTestActivity
 
 # keep mockito methods
@@ -27,3 +35,11 @@
 -dontwarn java.util.concurrent.ConcurrentLinkedDeque
 -dontwarn android.cts.util.**
 -dontwarn junit.**
+
+# Jack seems less rigorous than proguard when it comes to warning about
+# transitive dependencies.
+-dontwarn com.android.org.bouncycastle.**
+-dontwarn com.android.okhttp.**
+-dontwarn org.opencv.**
+-dontwarn android.support.test.internal.runner.hidden.ExposedInstrumentationApi
+
diff --git a/apps/CtsVerifier/res/layout-land/gnss_test.xml b/apps/CtsVerifier/res/layout-land/gnss_test.xml
new file mode 100644
index 0000000..c511d40
--- /dev/null
+++ b/apps/CtsVerifier/res/layout-land/gnss_test.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<com.android.cts.verifier.BoxInsetLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+    <LinearLayout app:ctsv_layout_box="all"
+        android:orientation="vertical"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        >
+
+        <LinearLayout
+            android:orientation="horizontal"
+            android:layout_width="match_parent"
+            android:layout_height="0dp"
+            android:layout_weight="1">
+
+            <TextView android:id="@+id/text"
+                android:textSize="14sp"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"/>
+
+            <ScrollView
+                android:id="@+id/log_scroll_view"
+                android:fillViewport="true"
+                android:layout_height="match_parent"
+                android:layout_width="0dp"
+                android:layout_weight="1">
+
+                <LinearLayout
+                    android:id="@+id/log_layout"
+                    android:orientation="vertical"
+                    android:layout_width="match_parent"
+                    android:layout_height="match_parent"/>
+            </ScrollView>
+
+        </LinearLayout>
+
+        <include layout="@layout/snsr_next_button" />
+
+    </LinearLayout>
+</com.android.cts.verifier.BoxInsetLayout>
diff --git a/apps/CtsVerifier/res/layout-port/gnss_test.xml b/apps/CtsVerifier/res/layout-port/gnss_test.xml
new file mode 100644
index 0000000..560133a
--- /dev/null
+++ b/apps/CtsVerifier/res/layout-port/gnss_test.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<com.android.cts.verifier.BoxInsetLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+    <LinearLayout app:ctsv_layout_box="all"
+        android:orientation="vertical"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        >
+
+        <LinearLayout
+            android:orientation="horizontal"
+            android:layout_width="match_parent"
+            android:layout_height="0dp"
+            android:layout_weight="1">
+
+            <TextView android:id="@+id/text"
+                android:textSize="14sp"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"/>
+
+            <ScrollView
+                android:id="@+id/log_scroll_view"
+                android:fillViewport="true"
+                android:layout_height="match_parent"
+                android:layout_width="0dp"
+                android:layout_weight="1">
+
+                <LinearLayout
+                    android:id="@+id/log_layout"
+                    android:orientation="vertical"
+                    android:layout_width="match_parent"
+                    android:layout_height="match_parent"/>
+
+            </ScrollView>
+
+        </LinearLayout>
+
+        <include layout="@layout/snsr_next_button" />
+
+    </LinearLayout>
+</com.android.cts.verifier.BoxInsetLayout>
diff --git a/apps/CtsVerifier/res/layout-small/gnss_test.xml b/apps/CtsVerifier/res/layout-small/gnss_test.xml
new file mode 100644
index 0000000..5caea07
--- /dev/null
+++ b/apps/CtsVerifier/res/layout-small/gnss_test.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<com.android.cts.verifier.BoxInsetLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+    <ScrollView android:id="@+id/log_scroll_view"
+        app:ctsv_layout_box="all"
+        android:fillViewport="true"
+        android:layout_height="match_parent"
+        android:layout_width="match_parent">
+        <LinearLayout
+            android:orientation="vertical"
+            android:layout_height="wrap_content"
+            android:layout_width="match_parent">
+
+            <TextView android:id="@+id/text"
+                android:textSize="14sp"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"/>
+
+            <LinearLayout android:id="@+id/log_layout"
+                android:orientation="vertical"
+                android:layout_height="wrap_content"
+                android:layout_width="match_parent"/>
+
+            <include layout="@layout/snsr_next_button"/>
+        </LinearLayout>
+
+    </ScrollView>
+</com.android.cts.verifier.BoxInsetLayout>
diff --git a/apps/CtsVerifier/res/layout/audio_frequency_unprocessed_activity.xml b/apps/CtsVerifier/res/layout/audio_frequency_unprocessed_activity.xml
new file mode 100644
index 0000000..abc8033
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/audio_frequency_unprocessed_activity.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:padding="10dip"
+    android:orientation="vertical"
+>
+
+    <ScrollView
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:id="@+id/scrollView"
+    >
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="vertical"
+        >
+
+        <TextView
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:scrollbars="vertical"
+                android:gravity="bottom"
+                android:id="@+id/audio_frequency_unprocessed_defined"/>
+
+                <ProgressBar
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:id="@+id/audio_frequency_unprocessed_progress_bar" />
+
+            <LinearLayout
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:orientation="vertical"
+                android:id="@+id/audio_frequency_unprocessed_layout_test1"
+            >
+
+                <TextView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/audio_frequency_unprocessed_instructions2"
+                    android:id="@+id/audio_frequency_unprocessed_instructions2" />
+
+                <Button
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/audio_frequency_unprocessed_test1_btn"
+                    android:id="@+id/audio_frequency_unprocessed_test1_btn" />
+
+                <TextView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/audio_frequency_unprocessed_results_text"
+                    android:id="@+id/audio_frequency_unprocessed_results1_text" />
+            </LinearLayout>
+
+
+            <include layout="@layout/pass_fail_buttons" />
+        </LinearLayout>
+    </ScrollView>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/apps/CtsVerifier/res/layout/bua_main.xml b/apps/CtsVerifier/res/layout/bua_main.xml
new file mode 100644
index 0000000..e2d5ef1
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/bua_main.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+         android:orientation="vertical"
+         android:layout_width="match_parent"
+         android:layout_height="match_parent"
+         >
+
+    <ListView android:id="@+id/android:list"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            />
+
+    <TextView android:id="@id/android:empty"
+           android:gravity="center"
+           android:layout_width="match_parent"
+           android:layout_height="wrap_content"
+           android:layout_weight="1"
+           android:text="@string/bu_loading"
+           />
+
+    <Button android:id="@+id/generate_button"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/bua_read_settings"
+            />
+
+    <Button android:id="@+id/show_instructions_button"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/bua_show_instructions"
+            />
+
+    <include layout="@layout/pass_fail_buttons" />
+
+</LinearLayout>
diff --git a/apps/CtsVerifier/res/layout/mtp_host_activity.xml b/apps/CtsVerifier/res/layout/mtp_host_activity.xml
new file mode 100644
index 0000000..f260e5d
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/mtp_host_activity.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:orientation="vertical"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+    <ScrollView android:layout_height="0dp"
+            android:layout_width="match_parent"
+            android:layout_weight="1" >
+        <LinearLayout android:id="@+id/mtp_host_list"
+                android:orientation="vertical"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content" />
+    </ScrollView>
+    <TextView android:id="@+id/error_text"
+              android:layout_width="match_parent"
+              android:layout_height="wrap_content" />
+    <include layout="@layout/pass_fail_buttons" />
+</LinearLayout>
diff --git a/apps/CtsVerifier/res/layout/mtp_host_item.xml b/apps/CtsVerifier/res/layout/mtp_host_item.xml
new file mode 100644
index 0000000..5268809
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/mtp_host_item.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:paddingTop="8dp"
+    android:paddingBottom="8dp">
+
+    <ImageView
+        android:id="@+id/status"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentLeft="true"
+        android:layout_alignParentTop="true"
+        android:contentDescription="@string/pass_button_text"
+        android:paddingTop="3dip"
+        android:paddingLeft="10dip"
+        android:paddingRight="10dip"
+        android:src="@drawable/fs_indeterminate" />
+
+    <TextView
+        android:id="@+id/instructions"
+        style="@style/InstructionsSmallFont"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_alignParentTop="true"
+        android:layout_toRightOf="@id/status" />
+
+    <Button
+        android:id="@+id/next_item_button"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_below="@id/instructions"
+        android:layout_toRightOf="@id/status"
+        android:text="@string/next_button_text"
+        android:visibility="gone" />
+
+    <Button
+        android:id="@+id/pass_item_button"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_below="@id/instructions"
+        android:layout_toRightOf="@id/next_item_button"
+        android:text="@string/pass_button_text"
+        android:visibility="gone" />
+
+    <Button
+        android:id="@+id/fail_item_button"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_below="@id/instructions"
+        android:layout_toRightOf="@id/pass_item_button"
+        android:text="@string/fail_button_text"
+        android:visibility="gone" />
+
+</RelativeLayout>
diff --git a/apps/CtsVerifier/res/layout/organization_info.xml b/apps/CtsVerifier/res/layout/organization_info.xml
new file mode 100644
index 0000000..320fb8c
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/organization_info.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:id="@+id/root_view"
+        android:orientation="vertical"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+
+        <TextView android:id="@+id/provisioning_byod_organization_info_instructions"
+                android:layout_width="match_parent"
+                android:layout_height="0dp"
+                android:layout_weight="1"
+                android:text="@string/provisioning_byod_organization_info_instructions"/>
+
+        <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="horizontal">
+            <EditText android:id="@+id/organization_name_edit_text"
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:hint="@string/provisioning_byod_organization_name_hint"
+                    android:gravity="top|start"
+                    android:windowSoftInputMode="adjustPan"
+                    android:padding="16dp"
+                    android:layout_weight="1"/>
+            <EditText android:id="@+id/organization_color_edit_text"
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:hint="@string/provisioning_byod_organization_color_hint"
+                    android:gravity="top|start"
+                    android:digits="#0123456789abcdefABCDEF"
+                    android:inputType="textCapCharacters"
+                    android:windowSoftInputMode="adjustPan"
+                    android:padding="16dp"
+                    android:layout_weight="1" />
+        </LinearLayout>
+
+        <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="horizontal">
+            <Button android:id="@+id/organization_info_set_button"
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:text="@string/provisioning_byod_set_organization_info_button_text"
+                    android:layout_weight="1"/>
+            <Button android:id="@+id/go_button"
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:text="@string/go_button_text"
+                    android:layout_weight="1"/>
+        </LinearLayout>
+
+        <include layout="@layout/pass_fail_buttons" />
+
+</LinearLayout>
diff --git a/apps/CtsVerifier/res/layout/policy_transparency_test.xml b/apps/CtsVerifier/res/layout/policy_transparency_test.xml
new file mode 100644
index 0000000..131ff3e
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/policy_transparency_test.xml
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:id="@+id/root_view"
+        android:orientation="vertical"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:descendantFocusability="beforeDescendants"
+        android:focusableInTouchMode="true">
+    <ScrollView
+            android:layout_width="match_parent"
+            android:layout_height="0dp"
+            android:layout_weight="1"
+            android:paddingTop="4dp">
+        <TextView
+                android:id="@+id/test_instructions"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:textSize="16sp"
+                android:padding="10dp" />
+    </ScrollView>
+
+    <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal"
+            android:paddingTop="8dp"
+            android:gravity="center_vertical">
+        <TextView android:id="@+id/widget_label"
+                android:layout_width="0dp"
+                android:layout_height="wrap_content"
+                android:textSize="18sp"
+                android:layout_weight="1"
+                android:paddingStart="16dp"
+                android:paddingEnd="8dp" />
+        <Switch android:id="@+id/switch_widget"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:paddingStart="8dp"
+                android:paddingEnd="16dp"
+                android:visibility="gone" />
+        <EditText android:id="@+id/edit_text_widget"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:ems="6"
+                android:singleLine="true"
+                android:gravity="center"
+                android:visibility="gone" />
+        <Button android:id="@+id/update_button"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/policy_transparency_update_button_label"
+                android:paddingStart="8dp"
+                android:paddingEnd="16dp"
+                android:visibility="gone" />
+        <Spinner android:id="@+id/spinner_widget"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:visibility="gone" />
+    </LinearLayout>
+
+    <Button android:id="@+id/open_settings_button"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/policy_transparency_open_settings_label" />
+
+    <include layout="@layout/pass_fail_buttons"/>
+</LinearLayout>
\ No newline at end of file
diff --git a/apps/CtsVerifier/res/layout/policy_transparency_test_list.xml b/apps/CtsVerifier/res/layout/policy_transparency_test_list.xml
new file mode 100644
index 0000000..8358e44
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/policy_transparency_test_list.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<com.android.cts.verifier.BoxInsetLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <LinearLayout app:ctsv_layout_box="all"
+            android:orientation="vertical"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            >
+
+        <ListView android:id="@id/android:list"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:layout_weight="1"
+                />
+
+        <TextView android:id="@id/android:empty"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:layout_weight="1"
+                />
+
+        <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content">
+            <Button android:id="@+id/short_msg_button"
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:text="@string/policy_transparency_short_support_msg_label" />
+            <Button android:id="@+id/long_msg_button"
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:text="@string/policy_transparency_long_support_msg_label" />
+        </LinearLayout>
+        <include layout="@layout/pass_fail_buttons" />
+
+    </LinearLayout>
+</com.android.cts.verifier.BoxInsetLayout>
\ No newline at end of file
diff --git a/apps/CtsVerifier/res/layout/requesting_bugreport_device_owner.xml b/apps/CtsVerifier/res/layout/requesting_bugreport_device_owner.xml
new file mode 100644
index 0000000..b2955ec
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/requesting_bugreport_device_owner.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:orientation="vertical"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        >
+
+    <ScrollView
+            android:layout_width="match_parent"
+            android:layout_height="100dp"
+            android:layout_weight="2">
+        <TextView
+                android:id="@+id/requesting_bugreport_device_owner_instructions"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:padding="10dip"
+                android:text="@string/device_owner_requesting_bugreport_tests_info"
+                android:textSize="18dip" />
+    </ScrollView>
+
+    <Button
+        android:id="@+id/set_device_owner_button"
+        android:layout_width="204dp"
+        android:layout_height="wrap_content"
+        android:text="@string/set_device_owner_button_label" />
+
+    <ListView
+        android:id="@+id/android:list"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_weight="3" />
+
+    <include layout="@layout/pass_fail_buttons" />
+
+</LinearLayout>
diff --git a/apps/CtsVerifier/res/layout/set_support_message.xml b/apps/CtsVerifier/res/layout/set_support_message.xml
new file mode 100644
index 0000000..ddf8563
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/set_support_message.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:orientation="vertical">
+    <EditText android:id="@+id/message_view"
+            android:layout_width="match_parent"
+            android:layout_height="0dp"
+            android:layout_weight="1"
+            android:scrollbars="vertical"
+            android:fadeScrollbars="false"
+            android:autoLink="phone|email"
+            android:hint="Enter the support message"
+            android:gravity="top|start"
+            android:windowSoftInputMode="adjustPan"
+            android:padding="16dp"
+            android:textColorLink="?android:attr/colorAccent"
+            android:background="@null" />
+    <Button android:id="@+id/set_default_message"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/policy_transparency_set_default_msg" />
+    <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal">
+        <Button android:id="@+id/clear_message"
+                android:layout_width="0dp"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:text="@string/policy_transparency_clear_msg" />
+        <Button android:id="@+id/set_message"
+                android:layout_width="0dp"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:text="@string/policy_transparency_set_msg" />
+    </LinearLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index e70c98b..94e7bd4 100644
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -13,7 +13,7 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<resources>
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_name">CTS Verifier</string>
 
     <string name="title_version">CTS Verifier %1$s</string>
@@ -52,6 +52,11 @@
     <!-- Strings for ReportViewerActivity -->
     <string name="report_viewer">Report Viewer</string>
 
+    <!-- String shared between BackupTestActivity and BackupAccessibilityTestActivity -->
+    <string name="bu_loading">Loading...</string>
+    <string name="bu_generate_error">Error occurred while generating test data...</string>
+    <string name="bu_settings">Settings</string>
+
     <!-- Strings for BackupTestActivity -->
     <string name="backup_test">Data Backup Test</string>
     <string name="backup_info">This test checks that data backup and automatic restore works
@@ -62,11 +67,9 @@
         \n\nPress the \"Generate Test Data\" to populate these values
         and then follow the on screen instructions to finish the test.
     </string>
+    <string name="bu_generate">Generate Test Data</string>
     <string name="bu_preferences">Preferences</string>
     <string name="bu_files">Files</string>
-    <string name="bu_loading">Loading...</string>
-    <string name="bu_generate">Generate Test Data</string>
-    <string name="bu_generate_error">Error occurred while generating test data...</string>
     <string name="bu_instructions">Random values for the preferences and files have been saved.
         \n\nFollow the instructions below to check that the data backup and restore works:
         \n\n1. Make sure backup and automatic restore are enabled in settings. Depending on the
@@ -79,7 +82,45 @@
         \n\n3. Uninstall the program: adb uninstall com.android.cts.verifier
         \n\n4. Reinstall the CTS Verifier and verify that the values are still the same.
     </string>
-    <string name="bu_settings">Settings</string>
+
+    <!-- Strings for BackupAccessibilityTestActivity -->
+    <string name="backup_accessibility_test">Backup Accessibility Settings Test</string>
+    <string name="backup_accessibility_info">This test checks that data backup and automatic restore
+        of Accessibility-related settings works properly. If backup and restore is working properly,
+        these values should be restored after running the backup manager, removing your Google
+        account, changing the accessibility settings values, and re-adding your Google account.
+        \n\nPress \"Generate Test Data\" to generate test values for accessibility settings and then
+        follow the on screen instructions to finish the test.
+    </string>
+    <string name="bua_settings">General Accessibility Settings</string>
+    <string name="bua_settings_color_correction">Color Correction Settings</string>
+    <string name="bua_settings_accessibility_services">Accessibility Service Settings</string>
+    <string name="bua_settings_captions">Captions Settings</string>
+    <string name="bua_settings_tts">TTS Settings</string>
+    <string name="bua_settings_system">Other System Settings</string>
+    <string name="bua_instructions">You will need two devices for this test.
+        \n\nFollow the instructions below to check that the data backup and restore of
+        accessibility-related settings works properly:
+        \n\n1. Make sure backup and automatic restore are enabled in settings. If you cannot find
+        the corresponding setting options on your device, run \"adb shell bmgr enable true\" to
+        enable the backup manager. You can check its status by executing \"adb shell bmgr enabled\".
+        You will also need to set a Google account as the backup account for the device.
+        \n\n2. Press \"Read Current Values\" and note the default values for the listed settings.
+        Values that are either \"0\" or \"null\" will appear in green. Note: Some default values are
+        neither \"0\", nor \"null\", so you still need to pay attention to the default setting
+        values that are not highlighted.
+        \n\n3. Change the values of the listed settings to something other than their default value.
+        \n\n4. Return to the CtsVerifier and press \"Read Current Values\". Make sure that you have
+        changed all of the settings.
+        \n\n5. Run the backup manager: adb shell bmgr run
+        \n\n6. Factory reset data on the second device. While going through the Setup Wizard,
+        restore all data from the account on your first device. When prompted, choose to restore all
+        settings from your first device.
+        \n\n7. Install CtsVerifier on your new device and make sure that the values read on the
+        second device match the values on your first device.
+    </string>
+    <string name="bua_show_instructions">Show Instructions</string>
+    <string name="bua_read_settings">Read Current Values</string>
 
     <!-- Strings for Device Administration tests -->
     <string name="da_policy_serialization_test">Policy Serialization Test</string>
@@ -374,6 +415,22 @@
         Make sure the device has line of sight to GPS satellites
         (for example, outside, or near a window)
         and then press OK to run the automated tests.</string>
+    <string name="location_listener_activity">Location listener</string>
+
+    <!-- Strings for Location GNSS tests -->
+    <string name="location_gnss_measure_no_location_test">GNSS Measurement WhenNoLocation Test</string>
+    <string name="location_gnss_reg_test">GNSS Measurement Registration Test</string>
+    <string name="location_gnss_value_test">GNSS Measurement Values Test</string>
+    <string name="location_gnss_nav_msg_test">GNSS Navigation Message Test</string>
+    <string name="location_gnss_test_info">This test verifies basic GNSS behavior.
+        Make sure the device has line of sight to GNSS satellites
+        (for example, stationary on a windowsill.  If needed, try again, outside, also with the
+        device stationary, and with at least some view of the sky.) and then press Next to run
+        the automated tests.</string>
+    <string name="location_gnss_test_retry_info">If this test fails, please make sure the device
+        has line of sight to GNSS satellites (for example, stationary on a windowsill. If needed,
+        try again, outside, also with the device stationary, with as much view of the sky as
+        possible.) </string>
 
     <!-- Strings for net.ConnectivityScreenOffTestActivity -->
     <string name="network_screen_off_test">Network Connectivity Screen Off Test</string>
@@ -467,8 +524,13 @@
     <string name="nfc_ndef_content">Id: %1$s\nMime: %2$s\nPayload: %3$s</string>
 
     <string name="nfc_hce">Host-based card emulation</string>
+    <string name="nfc_hce_f">Host-based Felica card emulation</string>
     <string name="nfc_hce_reader_tests">HCE reader tests</string>
+    <string name="nfc_hce_f_reader_tests">HCE Felica reader tests</string>
     <string name="nfc_hce_emulator_tests">HCE emulator tests</string>
+    <string name="nfc_hce_f_emulator_tests">HCE Felica emulator tests</string>
+    <string name="nfc_hce_f_emulator">HCE Felica emulator</string>
+    <string name="nfc_hce_f_reader">HCE Felica reader</string>
     <string name="nfc_hce_emulator_test_info">The host-based card emulation
         tests require two devices to be completed. The HCE emulator tests are used
         to actually test the host-based card emulation feature of the device-under-test. So the
@@ -576,6 +638,7 @@
     <string name="transportService2">TransportService #2</string>
     <string name="accessService">AccessService</string>
     <string name="offhostService">OffhostService</string>
+    <string name="felicaservice">Felica Service</string>
 
     <!-- Strings for Sensor Test Activities -->
     <string name="snsr_device_admin_receiver">Sensor Tests Device Admin Receiver</string>
@@ -891,6 +954,15 @@
     <string name="usb_file_descriptor_error">Could not open file descriptor for USB accessory... try reconnecting and restarting the accessory?</string>
     <string name="usb_test_abort">Test lost focus, aborting test.</string>
 
+    <!-- Strings for MTP host test activity -->
+    <string name="mtp_host_test">MTP Host Test</string>
+    <string name="mtp_host_test_info">The CTS-verifier tests the MTP host feature with another Android device. Please connect another Android device to this Android device by using OTG cable or USB type C cable, then follow the instructions on this screen. Note the test creates/deletes files in the connected Android device.</string>
+    <string name="mtp_host_device_lookup_message">Connect MTP device.\nPlease connect another Android device to this device by using USB OTG cable or USB type C cable.\nOpen \"Use USB for\" dialog from the notification in the other Android device and choose \"File Transfer\" option.\nThen press the next button.</string>
+    <string name="mtp_host_grant_permission_message">Grant permission.\nReply a dialog asking device permission.</string>
+    <string name="mtp_host_test_read_event_message">Test MtpDevice#readEvent.\nTake a picture at the connected device.</string>
+    <string name="mtp_host_test_send_object_message">Test MtpDevice#sendObject.</string>
+    <string name="mtp_host_test_notification_message">Test MTP notification.\nCheck if there is an notification on this device saying the other MTP device is connected to this device. Also check if it opens the UI to browse files in the connected device by tapping the notification.</string>
+
     <!-- Strings for the Camera ITS test activity -->
     <string name="camera_its_test">Camera ITS Test</string>
     <string name="camera_its_test_info">
@@ -1157,6 +1229,23 @@
     <string name="nls_clear_all">Check that service can clear all notifications.</string>
     <string name="nls_service_stopped">Service should stop once disabled.</string>
     <string name="nls_note_missed">Check that notification was not received.</string>
+    <string name="cp_test">Condition Provider test</string>
+    <string name="cp_service_name">Condition Provider for CTS Verifier</string>
+    <string name="cp_info">This test checks that a ConditionProviderService can be enabled
+        and disabled, and that once enabled the service is able to create, query, edit, and delete
+        automatic zen rules.
+    </string>
+    <string name="cp_enable_service">Please enable \"CTS Verifier\" under Do Not Disturb access and return here.</string>
+    <string name="cp_disable_service">Please disable \"CTS Verifier\" under Do Not Disturb access and return here.</string>
+    <string name="cp_start_settings">Launch Settings</string>
+    <string name="cp_create_rule">Creating Automatic Zen Rule</string>
+    <string name="cp_subscribe_rule">Subscribing to Automatic Zen Rule</string>
+    <string name="cp_service_started">Service should start once enabled.</string>
+    <string name="cp_service_stopped">Service should stop once disabled.</string>
+    <string name="cp_unsubscribe_rule">Unsubscribing to Automatic Zen Rule</string>
+    <string name="cp_delete_rule">Deleting Automatic Zen Rule</string>
+    <string name="cp_get_rules">Retrieving Automatic Zen Rules</string>
+    <string name="cp_get_rule">Retrieving Automatic Zen Rule</string>
 
     <string name="location_mode_high_accuracy_test">High Accuracy Mode Test</string>
     <string name="location_mode_high_accuracy_info">
@@ -1233,14 +1322,14 @@
     <string name="keychain_reset">Reset</string>
     <string name="keychain_skip">Skip</string>
     <string name="keychain_setup_desc">The first step sets up an internal KeyStore and generates credentials to use for the remainder of the test.\n\n
- Touch \'Next\' to begin.</string>
-    <string name="keychain_install_desc">Credentials generated. Touch \'Next\' to install them to the system keychain.\n\n
+ Tap \'Next\' to begin.</string>
+    <string name="keychain_install_desc">Credentials generated. Tap \'Next\' to install them to the system keychain.\n\n
 The container for the credentials will not be protected with a password; if prompted for one, leave that field blank.\n\n
 During installation you may be prompted for a name - accept the default suggestion.\n\n
 In the case that these credentials were already installed, you may skip this step.</string>
     <string name="keychain_https_desc">The last test involves setting up an HTTPS connection using credentials from the KeyChain.\n\n
 You should be prompted to select credentials; choose the ones you just installed in the previous step.</string>
-    <string name="keychain_reset_desc">Before marking this test as passed, touch \'Next\' to open security settings and reset the following items:\n
+    <string name="keychain_reset_desc">Before marking this test as passed, tap \'Next\' to open security settings and reset the following items:\n
  1. Clear device credentials.\n
  2. Change the lock screen type to \'None\'.</string>
 
@@ -1320,6 +1409,27 @@
     <string name="provisioning_byod_lockscreen_bound_key">Lockscreen-bound key test</string>
     <string name="provisioning_byod_fingerprint_bound_key">Fingerprint-bound key test</string>
     <string name="provisioning_byod_vpn">Vpn test</string>
+    <string name="provisioning_byod_select_work_challenge">Select work challenge test</string>
+    <string name="provisioning_byod_select_work_challenge_description">
+        This test verifies that a work challenge can be chosen.\n
+
+        1. Verify that you get sent to the page for setting up a new work challenge.\n
+        2. Set a new work challenge.
+    </string>
+    <string name="provisioning_byod_confirm_work_credentials">Confirm work challenge test</string>
+    <string name="provisioning_byod_confirm_work_credentials_description">
+        This test verifies that the work challenge was set correctly and it is customized according
+        to the policies set. You can only do this test after you have done the previous test.\n
+
+        1. Verify that a screen asking you for your work credentials is shown.\n
+        2. Verify that the background image contains an orange suitcase.\n
+        3. Verify that the background color of the remaining image is blue.\n
+        4. Verify that the header text says \"CtsVerifier\".\n
+        5. Confirm your credentials and verify that the credentials you entered previously work.
+    </string>
+    <string name="provisioning_byod_confirm_work_credentials_header">
+        CtsVerifier
+    </string>
     <!-- Strings for DeskClock -->
     <string name="deskclock_tests">Alarms and Timers Tests</string>
     <string name="deskclock_tests_info">
@@ -1472,7 +1582,22 @@
     <!-- Strings common for BYOD and DO managed provisioning tests. -->
     <string name="afw_device_admin">CTS Verifier</string>
 
-    <!-- Strings for BYOD managed provisioning tests (ByodFlowTestActivity) -->
+    <string name="provisioning_tests_byod">BYOD Provisioning tests</string>
+
+    <string name="provisioning_tests_byod_custom_color"> Custom provisioning color </string>
+    <string name="provisioning_tests_byod_custom_color_info">
+        Please press the Go button to start the provisioning.
+        Check that provisioning is colorized in green.
+        Then hit back and stop the provisioning.
+    </string>
+    <string name="provisioning_tests_byod_custom_image"> Custom provisioning image </string>
+    <string name="provisioning_tests_byod_custom_image_info">
+        Please press the Go button to start the provisioning.
+        Check that the CtsVerifier logo is displayed at the top of the page.
+        Then hit back and stop the provisioning.
+    </string>
+
+    <!-- Strings for BYOD managed provisioning (ByodFlowTestActivity) -->
     <string name="test_category_managed_provisioning">Managed Provisioning</string>
     <string name="provisioning_byod">BYOD Managed Provisioning</string>
     <string name="provisioning_byod_info">
@@ -1569,7 +1694,7 @@
     <string name="provisioning_byod_disable_unredacted_notifications_instruction">
         Please press the Go button to lock the screen. Wait a couple of seconds and look out for a
         notification from CtsVerifier.\n
-        Expected result is the notification is shown as \"Contents hidden\", you can not see the contents
+        Expected result is the notification is shown as \"Contents hidden by policy\", you can not see the contents
         (Which would read \"This is a notification\"). You should be seeing a work badge.\n
         After you log back in, please navigate back to CtsVerifier and mark the test as \"Pass\" or \"Fail\".
     </string>
@@ -1593,20 +1718,17 @@
     <string name="provisioning_byod_disallow_apps_control_prepare_button">Prepare test</string>
     <string name="provisioning_byod_disabled_uninstall_button">Disabled uninstall button</string>
     <string name="provisioning_byod_disabled_uninstall_button_instruction">
-        Please press the Go button to go to Settings > Apps. Choose a managed app. Check if the button that says
-        either \"Uninstall\" or \"Disable\" is greyed out and disabled, i.e. nothing happens when you tap on it.
+        Please press the Go button to go to Settings > Apps. Choose a managed app. Check that performing either \"Uninstall\" or \"Disable\" is not possible and triggers a support message when trying to do so.
         Then please press Back and mark the test as \"Pass\" or \"Fail\".
     </string>
     <string name="provisioning_byod_disabled_force_stop_button">Disabled force stop button</string>
     <string name="provisioning_byod_disabled_force_stop_button_instruction">
-        Please press the Go button to go to Settings > Apps. Choose a managed app. Check if the button that says
-        \"Force stop\" is greyed out and disabled, i.e. nothing happens when you tap on it.
+        Please press the Go button to go to Settings > Apps. Choose a managed app. Check that performing \"Force stop\" is not possible and triggers a support message when trying to do so.
         Then please press Back and mark the test as \"Pass\" or \"Fail\".
     </string>
     <string name="provisioning_byod_disabled_app_storage_buttons">Disabled app storage buttons</string>
     <string name="provisioning_byod_disabled_app_storage_buttons_instruction">
-        Please press the Go button to go to Settings > Apps. Choose a managed (badged) app. Select \"Storage\". Check that the buttons
-        \"Clear Data\" and \"Clear Cache\" are disabled, i.e. nothing happens when you tap on them.
+        Please press the Go button to go to Settings > Apps. Choose a managed (badged) app. Select \"Storage\". Check that performing \"Clear Data\" and \"Clear Cache\" is not possible and triggers a support message when trying to do so.
         Note: if an app has no data then tapping the clear data button has no effect anyway. Make sure you have selected
         the badged version of app with non-zero app data. Badged \"Settings\" may be a good candidate.
         Then please press Back and mark the test as \"Pass\" or \"Fail\".
@@ -1685,7 +1807,9 @@
     <string name="provisioning_byod_location_settings_instruction">
         Please press the Go button to open Location page in settings.\n
         \n
-        Verify that work profile entry exists in the page.\n
+        Verify that work profile entry exists in the page and it has a toggleable switch.\n
+        Switch the main location switch at the top of the screen off. You should see the work profile location switch go disabled and into \'off\' state.\n
+        Then switch the main location switch on again. You should see the work profile location switch go enabled and into its previous state.\n
         \n
         Then use the Back button to return to this test and mark accordingly.
     </string>
@@ -1770,7 +1894,7 @@
     <string name="provisioning_byod_location_mode_enable_toast_location_change">Location changed</string>
     <string name="provisioning_byod_location_mode_enable_instruction">
         This test verifies that the location updates can be enabled for the managed profile apps.\n
-        1. Press the go button to go to the location settings page, set the location switch enabled.\n
+        1. Press the go button to go to the location settings page, set both the main location switch and the work profile location switch enabled.\n
         2. Move your position a little bit, verify that location updates toast comes up.\n
         Please wait until the location updates or timeout toast message shows up before going back to the cts-verifier tests.\n
         3. Go back to the cts-verifier tests using the back button, then mark the test accordingly.\n
@@ -1779,13 +1903,72 @@
     <string name="provisioning_byod_location_mode_disable">Disable location</string>
     <string name="provisioning_byod_location_mode_time_out_toast">Timeout waiting for gps location change</string>
     <string name="provisioning_byod_location_mode_disable_instruction">
-        This test verifies that the location updates can be disabled for the managed profile apps.\n
-        1. Press the go button to go to the location settings page, set the location switch disabled.\n
-        2. Move your position a little bit, verify that no location updates toast come up and that the timeout message show up after around 15 seconds. 
+        This test verifies that the location updates can be disabled for the managed profile apps through the main location switch.\n
+        1. Press the go button to go to the location settings page, set the main location switch disabled.\n
+        2. Move your position a little bit, verify that no location updates toast come up and that the timeout message show up after around 15 seconds.
         Please wait until the timeout or location updates toast message shows up before going back to the cts-verifier tests.\n
         3. Go back to the cts-verifier tests using the back button, then mark the test accordingly.\n
     </string>
 
+    <string name="provisioning_byod_work_location_mode_disable">Disable location for work profile</string>
+    <string name="provisioning_byod_work_location_mode_disable_instruction">
+        This test verifies that the location updates can be disabled for the managed profile apps through work profile location switch.\n
+        1. Press the go button to go to the location settings page, set the work location switch disabled while the main location switch is still enabled.\n
+        2. Move your position a little bit, verify that no location updates toast come up and that the timeout message show up after around 15 seconds.
+        Please wait until the timeout or location updates toast message shows up before going back to the cts-verifier tests.\n
+        3. Go back to the cts-verifier tests using the back button, then mark the test accordingly.\n
+    </string>
+    <string name="provisioning_byod_primary_location_when_work_disabled">Primary receives updates while work location is disabled</string>
+    <string name="provisioning_byod_primary_location_when_work_disabled_instruction">
+        This test verifies that location updates are still received by primary profile when location updates are disabled for managed profile apps through work profile location switch.\n
+        1. Press the go button to go to the location settings page, set the work location switch disabled while the main location switch is still enabled.\n
+        2. Move your position a little bit, verify that location updates toast comes up.\n
+        Please wait until the location updates or timeout toast message shows up before going back to the cts-verifier tests.\n
+        3. Go back to the cts-verifier tests using the back button, then mark the test accordingly.\n
+    </string>
+
+    <string name="provisioning_byod_turn_off_work_icon">Icon when work mode is off</string>
+    <string name="provisioning_byod_turn_off_work_icon_instruction">
+        This test verifies that a status bar icon indicates if work mode is off.\n
+        1. Press the go button to go to the settings apps, set work mode to off.\n
+        2. Verify that the status bar shows an icon indicating that work mode is off.\n
+        3. Set work mode to on.\n
+        4. Check that the work icon on the status bar is removed.
+    </string>
+    <string name="provisioning_byod_turn_off_work_launcher">Starting work apps when work mode is off</string>
+    <string name="provisioning_byod_turn_off_work_launcher_instruction">
+        This test verifies that work applications cannot be started if work mode is off.\n
+        1. Press the go button to go to the settings apps, set work mode to off.\n
+        2. Press home to go to the launcher.\n
+        3. Verify that work applications are greyed out.\n
+        4. Tap on a work application.\n
+        5. Verify that the application does not start.\n
+        6. Set work mode to on.\n
+        7. Go to the launcher and verify that you can start a work application.\n
+    </string>
+    <string name="provisioning_byod_turn_off_work_notifications">Notifications when work mode is off</string>
+    <string name="provisioning_byod_turn_off_work_notifications_instruction">
+        This test verifies that work notifications are not shown if work mode is off.\n
+        1. Press the go button to send a work notification.\n
+        2. Set work mode to off.\n
+        3. Check that the work notification has disappeared.\n
+        4. Set work mode to on.\n
+    </string>
+    <string name="provisioning_byod_organization_info">Organization Info</string>
+    <string name="provisioning_byod_organization_name_hint">Name</string>
+    <string name="provisioning_byod_organization_color_hint">#FF00FF</string>
+    <string name="provisioning_byod_set_organization_info_button_text">Set</string>
+    <string name="provisioning_byod_organization_info_instructions">
+    This test verifies that the Organization Info was set correctly.
+    You can only do this test after you have done "select work challenge" test.\n
+        1. Enter your organization name.\n
+        2. Enter a valid color code.\n
+        3. Press the Set button to set organization Info.\n
+        4. Press the Go button to open a dialog to confirm work credentials.\n
+        5. Verify that the background color of the resulting dialog is as set by you.\n
+        6. Verify that the header text has organization name as set by you.\n
+    </string>
+
     <!-- Strings for DeviceOwnerProvisioningTest -->
     <string name="provisioning_device_owner">Device Owner Provisioning</string>
     <string name="device_owner_provisioning_tests">Device Owner provisioning tests</string>
@@ -1896,9 +2079,9 @@
     <string name="device_profile_owner_permission_lockdown_test_instructions">
             Select each of the three grant states for the permission shown below in turn.\n
             Now open application settings, select Permissions, and verify if the following behaviour is observed.\n
-            <b>Allow:</b> Permission is granted to the app and cannot be changed through the settings UI.\n
+            <b>Allow:</b> Permission is granted to the app and cannot be changed through the settings UI. Trying to change it triggers a support message.\n
             <b>Let user decide:</b> Permission state can be changed through the settings UI.\n
-            <b>Deny:</b> Permission is denied to the app and cannot be changed through the settings UI.\n
+            <b>Deny:</b> Permission is denied to the app and cannot be changed through the settings UI. Trying to change it triggers a support message.\n
             Please mark the test accordingly.
     </string>
     <string name="device_owner_permission_lockdown_test_info">
@@ -1906,13 +2089,22 @@
     </string>
     <string name="device_owner_disallow_usb_file_transfer_test">Disallow USB file transfer</string>
     <string name="device_owner_disallow_usb_file_transfer_test_info">
-            Please press below button to set the \"disallow USB file transfer\" restriction.
+            Please press below button to set the \"disallow USB file transfer\" restriction.\n
             Next, connect your device to your desktop computer through USB, open the USB notification from the status bar
-            and check that the \"Transfer files (MTP)\" and \"Transfer photos (PTP)\" options are not present. Also, check
-            that you can download files from your phone to the desktop computer. The test is successful if the files from
-            your phone are not and cannot be downloaded through USB.\n
+            and check that the \"Transfer files (MTP)\" and \"Transfer photos (PTP)\" cannot be selected and triggers a support message when trying to select them.\n
+            Also, check that if you can download files from your phone to the desktop computer. The test is successful if the files from your phone are not and cannot be downloaded through USB.\n
             Please mark the test accordingly.
     </string>
+    <string name="device_owner_set_user_icon">Setting the user icon</string>
+    <string name="device_owner_set_user_icon_instruction">
+        This test verifies that the user icon can be set.\n
+        1. Press the set user icon button.\n
+        2. Press the go button to go to Settings.\n
+        3a. If there is a \"users\" section in Settings, check that the icon of the user \"owner\" is the CtsVerifier one and mark this test accordingly.\n
+        3b. If there is no \"users\" section, mark this test as passed.\n
+    </string>
+    <string name="device_owner_set_user_icon_button">Set user icon</string>
+
     <string name="profile_owner_permission_lockdown_test_info">
         <b>
         Before proceeding, check if com.android.cts.permissionapp (aka CtsPermissionApp) is installed in work profile by going to Settings &gt; Apps. If not, please install the app before proceeding.\n\n
@@ -1945,7 +2137,7 @@
         Confirm that:\n
         \n
         - You cannot view Bluetooth devices in range.\n
-        - You cannot edit, add or remove any already paired devices.\n
+        - Trying to edit, add or remove any already paired devices triggers a support message.\n
         \n
         Use the Back button to return to this page.
     </string>
@@ -1956,7 +2148,18 @@
         Confirm that:\n
         \n
         - You cannot view WiFi networks in range.\n
-        - You cannot edit, add or remove any existing WiFi configs.\n
+        - Trying to edit, add or remove any existing WiFi configs triggers a support message.\n
+        \n
+        Use the Back button to return to this page.
+    </string>
+    <string name="device_owner_disallow_data_roaming">Disallow data roaming</string>
+    <string name="device_owner_disallow_data_roaming_info">
+        Please press the Set restriction button to set the user restriction.
+        Then press Go to open the Cellular network page in Settings.
+        Confirm that:\n
+        \n
+        - Data roaming is disabled.\n
+        - Enabling data roaming is not possible and triggers a support message.\n
         \n
         Use the Back button to return to this page.
     </string>
@@ -1992,13 +2195,222 @@
         1. Press Go to open the Vpn settings page.\n
         Confirm that:\n
         - You cannot add a new VPN network.\n
-        - You cannot edit, add or remove any existing VPNs.\n\n
+        - You cannot edit, add or remove any existing VPNs.\n
+        - Trying to perform any of the above actions will trigger a support message.\n\n
         2. Press Check VPN to check programmatic Vpn test.\n
         - Check Vpn setup\n\n
         Use the Back button to return to this page.
     </string>
     <string name="device_owner_user_vpn_restriction_set">Set VPN restriction</string>
 
+    <!-- Strings for DeviceOwnerBugreportTest -->
+    <string name="device_owner_requesting_bugreport_tests">Device Owner Requesting Bugreport Tests</string>
+    <string name="device_owner_requesting_bugreport_category">Device Owner Requesting Bugreport Tests</string>
+    <string name="device_owner_requesting_bugreport_tests_info">
+            The device owner requesting bugreport tests verify that a bugreport can be requested on a corporate owned device.\n
+            Press below button first, follow steps described in the dialog that pops up,
+            then proceed to the test cases.\n
+            Pressing \'back\', \'pass\' or \'fail\' on this test page will remove the device owner.\n
+            Alternatively, you can run the \'Remove device owner\' test. Ideally, that test should
+            be run last so that it does not interfere with other tests.
+    </string>
+    <string name="device_owner_request_bugreport">Request bugreport</string>
+    <string name="bugreport_sharing_declined">Bugreport sharing declined</string>
+    <string name="bugreport_shared_successfully">Bugreport shared successfully</string>
+    <string name="device_owner_bugreport_sharing_declined_while_being_taken">Sharing of requested bugreport declined while being taken</string>
+    <string name="device_owner_bugreport_sharing_declined_while_being_taken_info">
+        Please press the \"Request bugreport\" button to invoke the bugreport sharing operation.
+        Open the notifications panel and verify that:\n
+        \n
+        - Notification titled \"Taking bugreport...\" with an indefinite progress bar is present.\n
+        - Tapping on the \"Taking bugreport...\" notification opens a dialog titled \"Share bug report?\", that contains a message \"Your IT admin requested a bug report to help troubleshoot this device. Apps and data may be shared, and your device may temporarily slow down.\" and two buttons - \"DECLINE\" and \"SHARE\".\n
+        \n
+        Tap the \"DECLINE\" button and verify that:\n
+        \n
+        - \"Taking bugreport...\" notification with an indefinite progress bar is no longer present.\n
+        - Notification titled \"Device Owner Requesting Bugreport Tests\" with message \"Bugreport sharing declined\" is present.\n
+        \n
+        Dismiss the notifications and mark test as passed or failed.
+    </string>
+    <string name="device_owner_bugreport_sharing_accepted_while_being_taken">Sharing of requested bugreport accepted while being taken</string>
+    <string name="device_owner_bugreport_sharing_accepted_while_being_taken_info">
+        Please press the \"Request bugreport\" button to invoke the bugreport sharing operation.
+        Open the notifications panel and verify that:\n
+        \n
+        - Notification titled \"Taking bugreport...\" with an indefinite progress bar is present.\n
+        - Tapping on the \"Taking bugreport...\" notification opens a dialog titled \"Share bug report?\", that contains a message \"Your IT admin requested a bug report to help troubleshoot this device. Apps and data may be shared, and your device may temporarily slow down.\" and two buttons - \"DECLINE\" and \"SHARE\".\n
+        \n
+        Tap the \"SHARE\" button and verify that:\n
+        \n
+        - \"Taking bugreport...\" notification with an indefinite progress bar is no longer present.\n
+        - Notification titled \"Sharing bugreport...\" with an indefinite progress bar is present.\n
+        - After a few minutes (time necessary to wait for bugreport being collected) notification titled \"Sharing bugreport...\" is automatically dismissed and notification titled \"Device Owner Requesting Bugreport Tests\" with message \"Bugreport shared successfully\" is present.\n
+        \n
+        Dismiss the notifications and mark test as passed or failed.
+    </string>
+    <string name="device_owner_bugreport_sharing_declined_after_having_been_taken">Sharing of requested bugreport declined after having been taken</string>
+    <string name="device_owner_bugreport_sharing_declined_after_having_been_taken_info">
+        Please press the \"Request bugreport\" button to invoke the bugreport sharing operation.
+        Open the notifications panel and verify that:\n
+        \n
+        - Notification titled \"Taking bugreport...\" with an indefinite progress bar is present.\n
+        \n
+        Wait for a few minutes (time necessary for bugreport to be collected) and verify that:\n
+        \n
+        - \"Taking bugreport...\" notification with an indefinite progress bar is dismissed.\n
+        - Notification titled \"Share bug report?\", that contains a message \"Your IT admin requested a bug report to help troubleshoot this device. Apps and data may be shared.\" and two buttons - \"DECLINE\" and \"SHARE\" is shown.\n
+        \n
+        Tap the \"DECLINE\" button and verify that:\n
+        \n
+        - Notification titled \"Share bug report?\" is dismissed.\n
+        - Notification titled \"Device Owner Requesting Bugreport Tests\" with message \"Bugreport sharing declined\" is present.\n
+        \n
+        Dismiss the notifications and mark test as passed or failed.
+    </string>
+    <string name="device_owner_bugreport_sharing_accepted_after_having_been_taken">Sharing of requested bugreport accepted after having been taken</string>
+    <string name="device_owner_bugreport_sharing_accepted_after_having_been_taken_info">
+        Please press the \"Request bugreport\" button to invoke the bugreport sharing operation.
+        Open the notifications panel and verify that:\n
+        \n
+        - Notification titled \"Taking bugreport...\" with an indefinite progress bar is present.\n
+        \n
+        Wait for a few minutes (time necessary for bugreport to be collected) and verify that:\n
+        \n
+        - \"Taking bugreport...\" notification with an indefinite progress bar is dismissed.\n
+        - Notification titled \"Share bug report?\", that contains a message \"Your IT admin requested a bug report to help troubleshoot this device. Apps and data may be shared.\" and two buttons - \"DECLINE\" and \"SHARE\" is shown.\n
+        \n
+        Tap the \"SHARE\" button and verify that:\n
+        \n
+        - Notification titled \"Share bug report?\" is dismissed.\n
+        - Notification titled \"Device Owner Requesting Bugreport Tests\" with message \"Bugreport shared successfully\" is present.\n
+        \n
+        Dismiss the notifications and mark test as passed or failed.
+    </string>
+
+    <!-- Strings used for policy transparency test -->
+    <string name="device_profile_owner_policy_transparency_test">Policy transparency test</string>
+    <string name="device_profile_owner_policy_transparency_test_info">
+        This test checks that if an admin has enforced a policy, we let the user know about this.\nSet the short and long support messages before proceeding with the tests.
+    </string>
+    <string name="policy_transparency_open_settings_label">Open settings</string>
+    <string name="policy_transparency_short_support_msg_label">Set short support message</string>
+    <string name="policy_transparency_long_support_msg_label">Set long support message</string>
+    <string name="policy_transparency_set_msg">Set message</string>
+    <string name="policy_transparency_clear_msg">Clear message</string>
+    <string name="policy_transparency_set_default_msg">Set default message</string>
+    <string name="policy_transparency_default_short_msg">
+        This action is disabled by your administrator. Contact someone@example.com for support.
+    </string>
+    <string name="policy_transparency_default_long_msg">
+        This profile or device is managed by CtsVerifier. You can contact tech
+        support on:\n\n
+        America: +1 555-0100\n\n
+        APAC: +1 555-0100\n\n
+        Europe: +1 555-0100\n\n
+        Email: someone@example.com
+    </string>
+    <string name="policy_transparency_update_button_label">Update</string>
+    <string name="dummy_input_method_label">Dummy input method</string>
+    <string name="dummy_accessibility_service_label">Dummy accessibility service</string>
+    <string name="policy_transparency_test_instructions">
+        1. <xliff:g id="set_step" example="Set policy by turning the switch on">%1$s</xliff:g>\n
+        2. Open Settings app by clicking the "Open settings" button below.\n
+        3. Verify that performing the following action will trigger a support dialog:\n
+           <xliff:g id="user_action" example="Adding an account">%2$s</xliff:g>.\n
+        4. Verify that the support dialog displays the short support message set earlier.\n
+        5. Verify that clicking the "More details" link will redirect to Device administrators
+           page in Settings app which displays the long support message set earlier.\n
+    </string>
+    <string name="user_restriction_set_step">
+        Set \'%s\' user restriction by turning on the switch below.
+    </string>
+    <string name="disallow_add_user">Disallow add user</string>
+    <string name="disallow_add_user_action">Adding a new user</string>
+    <string name="disallow_adjust_volume">Disallow adjust volume</string>
+    <string name="disallow_adjust_volume_action">Adjusting the volume</string>
+    <string name="disallow_apps_control">Disallow controlling apps</string>
+    <string name="disallow_apps_control_action">DISABLE/UNINSTALL/FORCE STOP-ing any app in the managed device/profile other than CtsVerifier</string>
+    <string name="disallow_config_cell_broadcasts">Disallow config cell broadcasts</string>
+    <string name="disallow_config_cell_broadcasts_action">Configuring cell broadcasts</string>
+    <string name="disallow_config_credentials">Disallow config credentials</string>
+    <string name="disallow_config_credentials_action">Configuring user credentials</string>
+    <string name="disallow_config_mobile_networks">Disallow config mobile networks</string>
+    <string name="disallow_config_mobile_networks_action">Configuring mobile networks</string>
+    <string name="disallow_config_tethering">Disallow config tethering</string>
+    <string name="disallow_config_tethering_action">Configuring tethering and portable hotspots</string>
+    <string name="disallow_config_wifi">Disallow config Wi-Fi</string>
+    <string name="disallow_config_wifi_action">Modifying Wi-Fi configuration</string>
+    <string name="disallow_debugging_features">Disallow debugging features</string>
+    <string name="disallow_debugging_features_action">Enabling developer options</string>
+    <string name="disallow_factory_reset">Disallow factory reset</string>
+    <string name="disallow_factory_reset_action">Factory resetting the device</string>
+    <string name="disallow_fun">Disallow fun</string>
+    <string name="disallow_fun_action">Opening android easter egg game by tapping repeatedly on the \'Android version\' option</string>
+    <string name="disallow_install_unknown_sources">Disallow install unknown sources</string>
+    <string name="disallow_install_unknown_sources_action">Enabling \'Unknown sources\' setting</string>
+    <string name="disallow_modify_accounts">Disallow modify accounts</string>
+    <string name="disallow_modify_accounts_action">Adding an account or removing an account (if you have already added one)</string>
+    <string name="disallow_network_reset">Disallow network reset</string>
+    <string name="disallow_network_reset_action">Resetting network settings</string>
+    <string name="disallow_outgoing_beam">Disallow outgoing beam</string>
+    <string name="disallow_outgoing_beam_action">Switching on android beam</string>
+    <string name="disallow_remove_user">Disallow remove user</string>
+    <string name="disallow_remove_user_action">Removing other users</string>
+    <string name="disallow_share_location">Disallow share location</string>
+    <string name="disallow_share_location_action">Turning on location sharing</string>
+    <string name="disallow_uninstall_apps">Disallow uninstall apps</string>
+    <string name="disallow_uninstall_apps_action">Uninstalling applications other CtsVerifier</string>
+    <string name="disallow_keyguard_unredacted_notifications">Disallow lockscreen unredacted notification</string>
+    <string name="disallow_keyguard_unredacted_notifications_set_step">Disallow unredacted notifications when device is locked by turning on the switch below</string>
+    <string name="disallow_keyguard_unredacted_notifications_action">Selecting show all notification content when device is locked</string>
+    <string name="disallow_keyguard_unredacted_notifications_widget_label">@string/disallow_keyguard_unredacted_notifications</string>
+    <string name="set_auto_time_required">Set auto (network) time required</string>
+    <string name="auto_time_required_set_step">Set auto time required policy by turning on the switch below</string>
+    <string name="set_auto_time_required_action">Modifying date and time</string>
+    <string name="set_auto_time_required_widget_label">@string/set_auto_time_required</string>
+    <string name="set_lock_screen_info">Set lock screen info</string>
+    <string name="lock_screen_info_set_step">Select a lock screen info by setting a non-empty message in the edittext below.</string>
+    <string name="set_lock_screen_info_action">Modifying lock screen message</string>
+    <string name="set_lock_screen_info_widget_label">@string/set_lock_screen_info</string>
+    <string name="set_maximum_time_to_lock">Set maximum time to lock</string>
+    <string name="maximum_time_to_lock_set_step">
+        Select a non-zero maximum time to lock value by setting a value in the edittext box below.
+    </string>
+    <string name="set_maximum_time_to_lock_action">Selecting maximum time to lock greater than the set value below</string>
+    <string name="set_maximum_time_to_lock_widget_label">Set maximum time to lock (in Sec):</string>
+    <string name="set_password_quality">Set password quality</string>
+    <string name="password_quality_set_step">Set minimum password quality by selecting an option in the spinner below.</string>
+    <string name="set_password_quality_action">Setting a password which does not meet the requirements of the password quality selected</string>
+    <string name="set_password_quality_widget_label">@string/set_password_quality</string>
+    <string name="password_quality_unspecified">Unspecified</string>
+    <string name="password_quality_something">Something</string>
+    <string name="password_quality_numeric">Numeric</string>
+    <string name="password_quality_numeric_complex">Numeric (Complex)</string>
+    <string name="password_quality_alphabetic">Alphabetic</string>
+    <string name="password_quality_alphanumeric">Alphanumeric</string>
+    <string name="password_quality_complex">Complex</string>
+    <string name="set_permitted_accessibility_services">Set permitted accessibility services</string>
+    <string name="permitted_accessibility_services_set_step">
+        Disallow \'Dummy Accessibility service\' from permitted accessibility services by turning on
+        the switch below.
+    </string>
+    <string name="set_permitted_accessibility_services_action">
+        Enabling \'Dummy Accessibility service\' in the list of accessibility services
+    </string>
+    <string name="set_permitted_accessibility_services_widget_label">
+        Allow only system accessibility services:
+    </string>
+    <string name="set_permitted_input_methods">Set permitted input methods</string>
+    <string name="permitted_input_methods_set_step">
+        Disallow \'Dummy Input method\' from permitted input methods by turning on the switch below.
+    </string>
+    <string name="set_permitted_input_methods_action">
+        Enabling \'Dummy Input Method\' in the list of accessibility services
+    </string>
+    <string name="set_permitted_input_methods_widget_label">
+        Allow only system input methods:
+    </string>
+
     <!-- Strings for JobScheduler Tests -->
     <string name="js_test_description">This test is mostly automated, but requires some user interaction. You can pass this test once the list items below are checked.</string>
 
@@ -2064,6 +2476,13 @@
     Do you see the programs named \"Dummy Program\" and their descriptions
     "Dummy Program Description" in the EPG?
     </string>
+    <string name="tv_input_discover_test_trigger_setup">
+    Select the \"Launch setup\" button and verify if the bundled TV app shows the list of installed
+    TV inputs for setup.
+    </string>
+    <string name="tv_input_discover_test_verify_trigger_setup">
+    Do you see the \"CTS Verifier\" input in the list?
+    </string>
 
     <string name="tv_parental_control_test">TV app parental controls test</string>
     <string name="tv_parental_control_test_info">
@@ -2091,6 +2510,7 @@
 
     <string name="tv_launch_tv_app">Launch TV app</string>
     <string name="tv_launch_epg">Launch EPG</string>
+    <string name="tv_launch_setup">Launch setup</string>
     <string name="tv_channel_not_found">
     CtsVerifier channel is not set up. Please set up before proceeding.
     </string>
@@ -2236,6 +2656,8 @@
     Please consider addressing them for a future release.</string>
     <string name="audio_general_test_passed">Test Successful</string>
     <string name="audio_general_test_failed">Test Failed</string>
+    <string name="audio_general_default_false_string">false</string>
+    <string name="audio_general_default_true_string">true</string>
 
     <!-- Audio Loopback Latency Test -->
     <string name="audio_loopback_test">Audio Loopback Latency Test</string>
@@ -2319,4 +2741,20 @@
     <string name="audio_frequency_mic_test2_btn">Test 2</string>
     <string name="audio_frequency_mic_results_text">Results...</string>
 
+     <!-- Audio Frequency Unprocessed Test -->
+    <string name="audio_frequency_unprocessed_test">Audio Frequency Unprocessed Test</string>
+    <string name="audio_frequency_unprocessed_info">
+   This test requires an external broadband noise source (or click/impulse).
+   Please be prepared to activate the noise source when asked to.
+   The system will measure frequency response of the built in microphone using the UNPROCESSED
+   audio source.
+       </string>
+    <string name="audio_frequency_unprocessed_defined">Audio Frequency Unprocessed feature is defined. Test is mandatory</string>
+    <string name="audio_frequency_unprocessed_not_defined">Audio Frequency Unprocessed feature is NOT defined. Test is optional</string>
+     <string name="audio_frequency_unprocessed_instructions2">
+          Once you press the [TEST] button, you have 5 seconds to play a broadband sound (click or white noise).
+    </string>
+    <string name="audio_frequency_unprocessed_test1_btn">Test 1</string>
+    <string name="audio_frequency_unprocessed_results_text">Results...</string>
+
 </resources>
diff --git a/apps/CtsVerifier/res/xml/device_admin_byod.xml b/apps/CtsVerifier/res/xml/device_admin_byod.xml
index ff1eb95..b1ba372 100644
--- a/apps/CtsVerifier/res/xml/device_admin_byod.xml
+++ b/apps/CtsVerifier/res/xml/device_admin_byod.xml
@@ -24,6 +24,7 @@
         <reset-password />
         <disable-keyguard-features />
         <force-lock />
+        <limit-password />
     </uses-policies>
 </device-admin>
 <!-- END_INCLUDE(meta_data) -->
diff --git a/apps/CtsVerifier/res/xml/dummy_method.xml b/apps/CtsVerifier/res/xml/dummy_method.xml
new file mode 100644
index 0000000..03d555e
--- /dev/null
+++ b/apps/CtsVerifier/res/xml/dummy_method.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Configuration info for the Dummy input method -->
+<input-method xmlns:android="http://schemas.android.com/apk/res/android" />
\ No newline at end of file
diff --git a/apps/CtsVerifier/res/xml/felicaservice.xml b/apps/CtsVerifier/res/xml/felicaservice.xml
new file mode 100644
index 0000000..7d1b164
--- /dev/null
+++ b/apps/CtsVerifier/res/xml/felicaservice.xml
@@ -0,0 +1,5 @@
+<host-nfcf-service xmlns:android="http://schemas.android.com/apk/res/android"
+    android:description="@string/felicaservice">
+    <system-code-filter android:name="4001" />
+    <nfcid2-filter android:name="02FE000000001481" />
+</host-nfcf-service>
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/TestResultsReport.java b/apps/CtsVerifier/src/com/android/cts/verifier/TestResultsReport.java
index dc2502c..76eb8a1 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/TestResultsReport.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/TestResultsReport.java
@@ -16,17 +16,17 @@
 
 package com.android.cts.verifier;
 
+import android.content.Context;
+import android.os.Build;
+import android.text.TextUtils;
+import android.util.Xml;
+
 import com.android.compatibility.common.util.MetricsXmlSerializer;
 import com.android.compatibility.common.util.ReportLog;
 import com.android.cts.verifier.TestListAdapter.TestListItem;
 
 import org.xmlpull.v1.XmlSerializer;
 
-import android.content.Context;
-import android.os.Build;
-import android.text.TextUtils;
-import android.util.Xml;
-
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.text.DateFormat;
@@ -130,6 +130,7 @@
                     xml.endTag(null, TEST_DETAILS_TAG);
                 }
 
+                // TODO(stuartscott): For v2: ReportLog.serialize(xml, mAdapter.getReportLog(i));
                 ReportLog reportLog = mAdapter.getReportLog(i);
                 if (reportLog != null) {
                     MetricsXmlSerializer metricsXmlSerializer = new MetricsXmlSerializer(xml);
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyLineActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyLineActivity.java
index edb3bf0..c0f6750 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyLineActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyLineActivity.java
@@ -78,7 +78,7 @@
 
     private final int mBlockSizeSamples = 1024;
     private final int mSamplingRate = 48000;
-    private final int mSelectedRecordSource = MediaRecorder.AudioSource.VOICE_RECOGNITION;
+    private final int mSelectedRecordSource = MediaRecorder.AudioSource.UNPROCESSED;//VOICE_RECOGNITION;// UNPROCESSED;
     private final int mChannelConfig = AudioFormat.CHANNEL_IN_MONO;
     private final int mAudioFormat = AudioFormat.ENCODING_PCM_16BIT;
     private volatile Thread mRecordThread;
@@ -601,11 +601,13 @@
             mRecorder = new AudioRecord(mSelectedRecordSource, mSamplingRate,
                     mChannelConfig, mAudioFormat, 2 * minRecordBuffSizeInBytes);
         } catch (IllegalArgumentException e) {
+            Log.v(TAG, "Error: " + e.toString());
             return false;
         }
         if (mRecorder.getState() != AudioRecord.STATE_INITIALIZED) {
             mRecorder.release();
             mRecorder = null;
+            Log.v(TAG, "Error: mRecorder not initialized");
             return false;
         }
         mRecorder.setRecordPositionUpdateListener(this);
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyUnprocessedActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyUnprocessedActivity.java
new file mode 100644
index 0000000..13ec1f8
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyUnprocessedActivity.java
@@ -0,0 +1,695 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.verifier.audio;
+
+import com.android.cts.verifier.PassFailButtons;
+import com.android.cts.verifier.R;
+import com.android.cts.verifier.audio.wavelib.*;
+import com.android.compatibility.common.util.ReportLog;
+import com.android.compatibility.common.util.ResultType;
+import com.android.compatibility.common.util.ResultUnit;
+import android.content.Context;
+import android.content.BroadcastReceiver;
+import android.content.Intent;
+import android.content.IntentFilter;
+
+import android.media.AudioDeviceCallback;
+import android.media.AudioDeviceInfo;
+import android.media.AudioFormat;
+import android.media.AudioManager;
+import android.media.AudioTrack;
+import android.media.AudioRecord;
+import android.media.MediaRecorder;
+
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.os.SystemClock;
+
+import android.util.Log;
+
+import android.view.View;
+import android.view.View.OnClickListener;
+
+import android.widget.Button;
+import android.widget.TextView;
+import android.widget.SeekBar;
+import android.widget.LinearLayout;
+import android.widget.ProgressBar;
+
+/**
+ * Tests Audio built in Microphone response for Unprocessed audio source feature.
+ */
+public class AudioFrequencyUnprocessedActivity extends PassFailButtons.Activity implements Runnable,
+    AudioRecord.OnRecordPositionUpdateListener {
+    private static final String TAG = "AudioFrequencyUnprocessedActivity";
+
+    private static final int TEST_STARTED = 900;
+    private static final int TEST_ENDED = 901;
+    private static final int TEST_MESSAGE = 902;
+    private static final int TEST1_MESSAGE = 903;
+    private static final int TEST1_ENDED = 904;
+    private static final double MIN_ENERGY_BAND_1 = -50.0;          //dB Full Scale
+    private static final double MAX_ENERGY_BAND_1_BASE = -60.0;     //dB Full Scale
+    private static final double MIN_FRACTION_POINTS_IN_BAND = 0.3;
+    private static final double MAX_VAL = Math.pow(2, 15);
+    private static final double CLIP_LEVEL = (MAX_VAL-10) / MAX_VAL;
+
+    final OnBtnClickListener mBtnClickListener = new OnBtnClickListener();
+    Context mContext;
+
+    Button mTest1Button;                //execute test 1
+    Button mTest2Button;                 //user to start test
+    String mUsbDevicesInfo;             //usb device info for report
+    LinearLayout mLayoutTest1;
+    TextView mTest1Result;
+    ProgressBar mProgressBar;
+
+    private boolean mIsRecording = false;
+    private final Object mRecordingLock = new Object();
+    private AudioRecord mRecorder;
+    private int mMinRecordBufferSizeInSamples = 0;
+    private short[] mAudioShortArray;
+    private short[] mAudioShortArray2;
+
+    private final int mBlockSizeSamples = 4096;
+    private final int mSamplingRate = 48000;
+    private final int mSelectedRecordSource = MediaRecorder.AudioSource.UNPROCESSED;
+    private final int mChannelConfig = AudioFormat.CHANNEL_IN_MONO;
+    private final int mAudioFormat = AudioFormat.ENCODING_PCM_16BIT;
+    private Thread mRecordThread;
+
+    PipeShort mPipe = new PipeShort(65536);
+
+    private boolean mSupportsUnprocessed = false;
+
+    private DspBufferComplex mC;
+    private DspBufferDouble mData;
+
+    private DspWindow mWindow;
+    private DspFftServer mFftServer;
+    private VectorAverage mFreqAverageMain = new VectorAverage();
+    private VectorAverage mFreqAverageBuiltIn = new VectorAverage();
+
+    int mBands = 4;
+    AudioBandSpecs[] bandSpecsArray = new AudioBandSpecs[mBands];
+    private TextView mTextViewUnprocessedStatus;
+
+    int mMaxLevel;
+    private class OnBtnClickListener implements OnClickListener {
+        @Override
+        public void onClick(View v) {
+            switch (v.getId()) {
+            case R.id.audio_frequency_unprocessed_test1_btn:
+                startTest1();
+                break;
+            }
+        }
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.audio_frequency_unprocessed_activity);
+        mContext = this;
+        mTextViewUnprocessedStatus = (TextView) findViewById(
+                R.id.audio_frequency_unprocessed_defined);
+        //unprocessed test
+        mSupportsUnprocessed = supportsUnprocessed();
+        if (mSupportsUnprocessed) {
+            mTextViewUnprocessedStatus.setText(
+                    getResources().getText(R.string.audio_frequency_unprocessed_defined));
+        } else {
+            mTextViewUnprocessedStatus.setText(
+                    getResources().getText(R.string.audio_frequency_unprocessed_not_defined));
+        }
+
+        mTest1Button = (Button)findViewById(R.id.audio_frequency_unprocessed_test1_btn);
+        mTest1Button.setOnClickListener(mBtnClickListener);
+        mTest1Result = (TextView)findViewById(R.id.audio_frequency_unprocessed_results1_text);
+        mLayoutTest1 = (LinearLayout) findViewById(R.id.audio_frequency_unprocessed_layout_test1);
+        mProgressBar = (ProgressBar)findViewById(R.id.audio_frequency_unprocessed_progress_bar);
+        showWait(false);
+        enableLayout(mLayoutTest1, true);
+
+        //Init FFT stuff
+        mAudioShortArray2 = new short[mBlockSizeSamples*2];
+        mData = new DspBufferDouble(mBlockSizeSamples);
+        mC = new DspBufferComplex(mBlockSizeSamples);
+        mFftServer = new DspFftServer(mBlockSizeSamples);
+
+        int overlap = mBlockSizeSamples / 2;
+
+        mWindow = new DspWindow(DspWindow.WINDOW_HANNING, mBlockSizeSamples, overlap);
+
+        setPassFailButtonClickListeners();
+        getPassButton().setEnabled(false);
+        setInfoResources(R.string.audio_frequency_unprocessed_test,
+                R.string.audio_frequency_unprocessed_info, -1);
+
+        //Init bands for BuiltIn/Reference test
+        bandSpecsArray[0] = new AudioBandSpecs(
+                2, 500,         /* frequency start,stop */
+                30.0, -50,     /* start top,bottom value */
+                30.0, -4.0       /* stop top,bottom value */);
+
+        bandSpecsArray[1] = new AudioBandSpecs(
+                500,4000,       /* frequency start,stop */
+                4.0, -4.0,      /* start top,bottom value */
+                4.0, -4.0        /* stop top,bottom value */);
+
+        bandSpecsArray[2] = new AudioBandSpecs(
+                4000, 12000,    /* frequency start,stop */
+                4.0, -4.0,      /* start top,bottom value */
+                5.0, -5.0       /* stop top,bottom value */);
+
+        bandSpecsArray[3] = new AudioBandSpecs(
+                12000, 20000,   /* frequency start,stop */
+                5.0, -5.0,      /* start top,bottom value */
+                5.0, -30.0      /* stop top,bottom value */);
+
+        mSupportsUnprocessed = supportsUnprocessed();
+        Log.v(TAG, "Supports unprocessed: " + mSupportsUnprocessed);
+    }
+
+    /**
+     * enable test ui elements
+     */
+    private void enableLayout(LinearLayout layout, boolean enable) {
+        for (int i = 0; i < layout.getChildCount(); i++) {
+            View view = layout.getChildAt(i);
+            view.setEnabled(enable);
+        }
+    }
+
+    /**
+     * show active progress bar
+     */
+    private void showWait(boolean show) {
+        if (show) {
+            mProgressBar.setVisibility(View.VISIBLE);
+        } else {
+            mProgressBar.setVisibility(View.INVISIBLE);
+        }
+    }
+
+    private void setMaxLevel() {
+        AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
+        mMaxLevel = am.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
+        am.setStreamVolume(AudioManager.STREAM_MUSIC, (int)(mMaxLevel), 0);
+    }
+
+    private void setMinLevel() {
+        AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
+        am.setStreamVolume(AudioManager.STREAM_MUSIC, 0, 0);
+    }
+
+    private boolean supportsUnprocessed() {
+        boolean unprocessedSupport = false;
+        AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
+        String unprocessedSupportString = am.getProperty(
+                AudioManager.PROPERTY_SUPPORT_AUDIO_SOURCE_UNPROCESSED);
+        Log.v(TAG,"unprocessed support: " + unprocessedSupportString);
+        if (unprocessedSupportString == null ||
+                unprocessedSupportString.equalsIgnoreCase(getResources().getString(
+                        R.string.audio_general_default_false_string))) {
+            unprocessedSupport = false;
+        } else {
+            unprocessedSupport = true;
+        }
+        return unprocessedSupport;
+    }
+
+    /**
+     *  Start the loopback audio test
+     */
+    private void startTest1() {
+        if (mTestThread != null && !mTestThread.isAlive()) {
+            mTestThread = null; //kill it.
+        }
+
+        if (mTestThread == null) {
+            Log.v(TAG,"Executing test Thread");
+            mTestThread = new Thread(mTest1Runnable);
+            mTestThread.start();
+        } else {
+            Log.v(TAG,"test Thread already running.");
+        }
+    }
+
+    Thread mTestThread;
+    Runnable mTest1Runnable = new Runnable() {
+        public void run() {
+            Message msg = Message.obtain();
+            msg.what = TEST_STARTED;
+            mMessageHandler.sendMessage(msg);
+
+            setMaxLevel();
+            sendMessage("Testing Built in Microphone");
+            mFreqAverageBuiltIn.reset();
+            mFreqAverageBuiltIn.setCaptureType(VectorAverage.CAPTURE_TYPE_MAX);
+            play();
+
+            sendMessage("Testing Completed");
+
+            Message msg2 = Message.obtain();
+            msg2.what = TEST1_ENDED;
+            mMessageHandler.sendMessage(msg2);
+        }
+
+        private void play() {
+            startRecording();
+
+            try {
+                Thread.sleep(5000);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+                //restore interrupted status
+                Thread.currentThread().interrupt();
+            }
+            stopRecording();
+        }
+
+        private void sendMessage(String str) {
+            Message msg = Message.obtain();
+            msg.what = TEST1_MESSAGE;
+            msg.obj = str;
+            mMessageHandler.sendMessage(msg);
+        }
+    };
+
+    private Handler mMessageHandler = new Handler() {
+        public void handleMessage(Message msg) {
+            super.handleMessage(msg);
+            switch (msg.what) {
+            case TEST_STARTED:
+                showWait(true);
+                getPassButton().setEnabled(false);
+                break;
+            case TEST_ENDED:
+                showWait(false);
+//                computeTest2Results();
+                break;
+            case TEST1_MESSAGE: {
+                    String str = (String)msg.obj;
+                    if (str != null) {
+                        mTest1Result.setText(str);
+                    }
+                }
+                break;
+            case TEST1_ENDED:
+                showWait(false);
+                computeTest1Results();
+                break;
+            case TEST_MESSAGE: {
+                }
+                break;
+            default:
+                Log.e(TAG, String.format("Unknown message: %d", msg.what));
+            }
+        }
+    };
+
+    private class Results {
+        private String mLabel;
+        public double[] mValuesLog;
+        int[] mPointsPerBand = new int[mBands];
+        double[] mAverageEnergyPerBand = new double[mBands];
+        int[] mInBoundPointsPerBand = new int[mBands];
+        public Results(String label) {
+            mLabel = label;
+        }
+
+        //append results
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            sb.append(String.format("Channel %s\n", mLabel));
+            sb.append("Level in Band 1 : " + (testLevel() ? "OK" :"FAILED") + "\n");
+            for (int b = 0; b < mBands; b++) {
+                double percent = 0;
+                if (mPointsPerBand[b] > 0) {
+                    percent = 100.0 * (double) mInBoundPointsPerBand[b] / mPointsPerBand[b];
+                }
+                sb.append(String.format(
+                        " Band %d: Av. Level: %.1f dB InBand: %d/%d (%.1f%%) %s\n",
+                        b, mAverageEnergyPerBand[b],
+                        mInBoundPointsPerBand[b],
+                        mPointsPerBand[b],
+                        percent,
+                        (testInBand(b) ? "OK" : "FAILED")));
+            }
+            return sb.toString();
+        }
+
+        public boolean testLevel() {
+            if (mAverageEnergyPerBand[1] >= MIN_ENERGY_BAND_1) {
+                return true;
+            }
+            return false;
+        }
+
+        public boolean testInBand(int b) {
+            if (b >= 0 && b < mBands && mPointsPerBand[b] > 0) {
+                if ((double) mInBoundPointsPerBand[b] / mPointsPerBand[b] >
+                    MIN_FRACTION_POINTS_IN_BAND) {
+                        return true;
+                }
+            }
+            return false;
+        }
+
+        public boolean testAll() {
+            if (!testLevel()) {
+                return false;
+            }
+            for (int b = 0; b < mBands; b++) {
+                if (!testInBand(b)) {
+                    return false;
+                }
+            }
+            return true;
+        }
+    }
+
+
+    /**
+     * compute test1 results
+     */
+    private void computeTest1Results() {
+        Results resultsBuiltIn = new Results("BuiltIn");
+        if (computeResultsForVector(mFreqAverageBuiltIn, resultsBuiltIn, bandSpecsArray)) {
+            appendResultsToScreen(resultsBuiltIn.toString(), mTest1Result);
+            recordTestResults(resultsBuiltIn);
+        }
+        if (mSupportsUnprocessed) { //test is mandatory
+            appendResultsToScreen(getResources().getText(
+                    R.string.audio_frequency_unprocessed_defined).toString(), mTest1Result);
+            if (resultsBuiltIn.testAll()) {
+                //tst passed
+                getPassButton().setEnabled(true);
+                String strSuccess = getResources().getString(R.string.audio_general_test_passed);
+                appendResultsToScreen(strSuccess, mTest1Result);
+            } else {
+                getPassButton().setEnabled(false);
+                String strFailed = getResources().getString(R.string.audio_general_test_failed);
+                appendResultsToScreen(strFailed, mTest1Result);
+            }
+        } else {
+            //test optional
+            appendResultsToScreen(getResources().getText(
+                    R.string.audio_frequency_unprocessed_not_defined).toString(), mTest1Result);
+            getPassButton().setEnabled(true);
+        }
+    }
+
+    private boolean computeResultsForVector(VectorAverage freqAverage, Results results,
+            AudioBandSpecs[] bandSpecs) {
+
+        int points = freqAverage.getSize();
+        if (points > 0) {
+            //compute vector in db
+            double[] values = new double[points];
+            freqAverage.getData(values, false);
+            results.mValuesLog = new double[points];
+            for (int i = 0; i < points; i++) {
+                results.mValuesLog[i] = 20 * Math.log10(values[i]);
+            }
+
+            int currentBand = 0;
+            for (int i = 0; i < points; i++) {
+                double freq = (double)mSamplingRate * i / (double)mBlockSizeSamples;
+                if (freq > bandSpecs[currentBand].mFreqStop) {
+                    currentBand++;
+                    if (currentBand >= mBands)
+                        break;
+                }
+
+                if (freq >= bandSpecs[currentBand].mFreqStart) {
+                    results.mAverageEnergyPerBand[currentBand] += results.mValuesLog[i];
+                    results.mPointsPerBand[currentBand]++;
+                }
+            }
+
+            for (int b = 0; b < mBands; b++) {
+                if (results.mPointsPerBand[b] > 0) {
+                    results.mAverageEnergyPerBand[b] =
+                            results.mAverageEnergyPerBand[b] / results.mPointsPerBand[b];
+                }
+            }
+
+            //set offset relative to band 1 level
+            for (int b = 0; b < mBands; b++) {
+                bandSpecs[b].setOffset(results.mAverageEnergyPerBand[1]);
+            }
+
+            //test points in band.
+            currentBand = 0;
+            for (int i = 0; i < points; i++) {
+                double freq = (double)mSamplingRate * i / (double)mBlockSizeSamples;
+                if (freq >  bandSpecs[currentBand].mFreqStop) {
+                    currentBand++;
+                    if (currentBand >= mBands)
+                        break;
+                }
+
+                if (freq >= bandSpecs[currentBand].mFreqStart) {
+                    double value = results.mValuesLog[i];
+                    if (bandSpecs[currentBand].isInBounds(freq, value)) {
+                        results.mInBoundPointsPerBand[currentBand]++;
+                    }
+                }
+            }
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    //append results
+    private void appendResultsToScreen(String str, TextView text) {
+        String currentText = text.getText().toString();
+        text.setText(currentText + "\n" + str);
+    }
+
+    /**
+     * Store test results in log
+     */
+    private void recordTestResults(Results results) {
+        String channelLabel = "channel_" + results.mLabel;
+
+        for (int b = 0; b < mBands; b++) {
+            String bandLabel = String.format(channelLabel + "_%d", b);
+            getReportLog().addValue(
+                    bandLabel + "_Level",
+                    results.mAverageEnergyPerBand[b],
+                    ResultType.HIGHER_BETTER,
+                    ResultUnit.NONE);
+
+            getReportLog().addValue(
+                    bandLabel + "_pointsinbound",
+                    results.mInBoundPointsPerBand[b],
+                    ResultType.HIGHER_BETTER,
+                    ResultUnit.COUNT);
+
+            getReportLog().addValue(
+                    bandLabel + "_pointstotal",
+                    results.mPointsPerBand[b],
+                    ResultType.NEUTRAL,
+                    ResultUnit.COUNT);
+        }
+
+        getReportLog().addValues(channelLabel + "_magnitudeSpectrumLog",
+                results.mValuesLog,
+                ResultType.NEUTRAL,
+                ResultUnit.NONE);
+
+        Log.v(TAG, "Results Recorded");
+    }
+
+    private void recordHeasetPortFound(boolean found) {
+        getReportLog().addValue(
+                "User Reported Headset Port",
+                found ? 1.0 : 0,
+                ResultType.NEUTRAL,
+                ResultUnit.NONE);
+    }
+
+    private void startRecording() {
+        synchronized (mRecordingLock) {
+            mIsRecording = true;
+        }
+
+        boolean successful = initRecord();
+        if (successful) {
+            startRecordingForReal();
+        } else {
+            Log.v(TAG, "Recorder initialization error.");
+            synchronized (mRecordingLock) {
+                mIsRecording = false;
+            }
+        }
+    }
+
+    private void startRecordingForReal() {
+        // start streaming
+        if (mRecordThread == null) {
+            mRecordThread = new Thread(AudioFrequencyUnprocessedActivity.this);
+            mRecordThread.setName("FrequencyAnalyzerThread");
+        }
+        if (!mRecordThread.isAlive()) {
+            mRecordThread.start();
+        }
+
+        mPipe.flush();
+
+        long startTime = SystemClock.uptimeMillis();
+        mRecorder.startRecording();
+        if (mRecorder.getRecordingState() != AudioRecord.RECORDSTATE_RECORDING) {
+            stopRecording();
+            return;
+        }
+        Log.v(TAG, "Start time: " + (long) (SystemClock.uptimeMillis() - startTime) + " ms");
+    }
+
+    private void stopRecording() {
+        synchronized (mRecordingLock) {
+            stopRecordingForReal();
+            mIsRecording = false;
+        }
+    }
+
+    private void stopRecordingForReal() {
+
+        // stop streaming
+        Thread zeThread = mRecordThread;
+        mRecordThread = null;
+        if (zeThread != null) {
+            zeThread.interrupt();
+            try {
+                zeThread.join();
+            } catch(InterruptedException e) {
+                //restore interrupted status of recording thread
+                zeThread.interrupt();
+            }
+        }
+         // release recording resources
+        if (mRecorder != null) {
+            mRecorder.stop();
+            mRecorder.release();
+            mRecorder = null;
+        }
+    }
+
+    private boolean initRecord() {
+        int minRecordBuffSizeInBytes = AudioRecord.getMinBufferSize(mSamplingRate,
+                mChannelConfig, mAudioFormat);
+        Log.v(TAG,"FrequencyAnalyzer: min buff size = " + minRecordBuffSizeInBytes + " bytes");
+        if (minRecordBuffSizeInBytes <= 0) {
+            return false;
+        }
+
+        mMinRecordBufferSizeInSamples = minRecordBuffSizeInBytes / 2;
+        // allocate the byte array to read the audio data
+
+        mAudioShortArray = new short[mMinRecordBufferSizeInSamples];
+
+        Log.v(TAG, "Initiating record:");
+        Log.v(TAG, "      using source " + mSelectedRecordSource);
+        Log.v(TAG, "      at " + mSamplingRate + "Hz");
+
+        try {
+            mRecorder = new AudioRecord(mSelectedRecordSource, mSamplingRate,
+                    mChannelConfig, mAudioFormat, 2 * minRecordBuffSizeInBytes);
+        } catch (IllegalArgumentException e) {
+            return false;
+        }
+        if (mRecorder.getState() != AudioRecord.STATE_INITIALIZED) {
+            mRecorder.release();
+            mRecorder = null;
+            return false;
+        }
+        mRecorder.setRecordPositionUpdateListener(this);
+        mRecorder.setPositionNotificationPeriod(mBlockSizeSamples / 2);
+        return true;
+    }
+
+    // ---------------------------------------------------------
+    // Implementation of AudioRecord.OnPeriodicNotificationListener
+    // --------------------
+    public void onPeriodicNotification(AudioRecord recorder) {
+        int samplesAvailable = mPipe.availableToRead();
+        int samplesNeeded = mBlockSizeSamples;
+        if (samplesAvailable >= samplesNeeded) {
+            mPipe.read(mAudioShortArray2, 0, samplesNeeded);
+
+            //compute stuff.
+            int clipcount = 0;
+            double sum = 0;
+            double maxabs = 0;
+            int i;
+
+            for (i = 0; i < samplesNeeded; i++) {
+                double value = mAudioShortArray2[i] / MAX_VAL;
+                double valueabs = Math.abs(value);
+
+                if (valueabs > maxabs) {
+                    maxabs = valueabs;
+                }
+
+                if (valueabs > CLIP_LEVEL) {
+                    clipcount++;
+                }
+
+                sum += value * value;
+                //fft stuff
+                mData.mData[i] = value;
+            }
+
+            //for the current frame, compute FFT and send to the viewer.
+
+            //apply window and pack as complex for now.
+            DspBufferMath.mult(mData, mData, mWindow.mBuffer);
+            DspBufferMath.set(mC, mData);
+            mFftServer.fft(mC, 1);
+
+            double[] halfMagnitude = new double[mBlockSizeSamples / 2];
+            for (i = 0; i < mBlockSizeSamples / 2; i++) {
+                halfMagnitude[i] = Math.sqrt(mC.mReal[i] * mC.mReal[i] + mC.mImag[i] * mC.mImag[i]);
+            }
+
+            mFreqAverageMain.setData(halfMagnitude, false); //average all of them!
+            mFreqAverageBuiltIn.setData(halfMagnitude, false);
+        }
+    }
+
+    public void onMarkerReached(AudioRecord track) {
+    }
+
+    // ---------------------------------------------------------
+    // Implementation of Runnable for the audio recording + playback
+    // --------------------
+    public void run() {
+        Thread thisThread = Thread.currentThread();
+        while (!thisThread.isInterrupted()) {
+            // read from native recorder
+            int nSamplesRead = mRecorder.read(mAudioShortArray, 0, mMinRecordBufferSizeInSamples);
+            if (nSamplesRead > 0) {
+                mPipe.write(mAudioShortArray, 0, nSamplesRead);
+            }
+        }
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/wavelib/VectorAverage.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/wavelib/VectorAverage.java
index 41f0411..8783cbb 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/wavelib/VectorAverage.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/wavelib/VectorAverage.java
@@ -24,6 +24,12 @@
     private double[] mData;
     private int mValueCount = 0;
 
+    public static final int CAPTURE_TYPE_AVERAGE = 0;
+    public static final int CAPTURE_TYPE_MAX     = 1;
+    public static final int CAPTURE_TYPE_MIN     = 2;
+
+    private int mCaptureType = CAPTURE_TYPE_AVERAGE;
+
     public void setData(double[] data, boolean replace) {
         int size = data.length;
         if (mData == null || mData.length != size) {
@@ -34,10 +40,34 @@
             System.arraycopy(data, 0, mData, 0, size);
             mValueCount = 1;
         } else {
-            for (int i = 0; i < size; i++) {
-                mData[i] += data[i];
+            switch(mCaptureType) {
+                default:
+                case CAPTURE_TYPE_AVERAGE: {
+                    for (int i = 0; i < size; i++) {
+                        mData[i] += data[i];
+                    }
+                    mValueCount++;
+                }
+                break;
+                case CAPTURE_TYPE_MAX: {
+                    for (int i = 0; i < size; i++) {
+                        if (data[i] > mData[i]) {
+                            mData[i] = data[i];
+                        }
+                    }
+                    mValueCount = 1;
+                }
+                break;
+                case CAPTURE_TYPE_MIN: {
+                    for (int i = 0; i < size; i++) {
+                        if (data[i] < mData[i]) {
+                            mData[i] = data[i];
+                        }
+                    }
+                    mValueCount = 1;
+                }
+                break;
             }
-            mValueCount++;
         }
     }
 
@@ -77,6 +107,22 @@
         mValueCount = 0;
     }
 
+    public void setCaptureType(int type) {
+        switch(type) {
+            case CAPTURE_TYPE_AVERAGE:
+            case CAPTURE_TYPE_MAX:
+            case CAPTURE_TYPE_MIN:
+                mCaptureType = type;
+                break;
+            default:
+                mCaptureType = CAPTURE_TYPE_AVERAGE;
+        }
+    }
+
+    public int getCaptureType() {
+        return mCaptureType;
+    }
+
     private final String SERIALIZED_VERSION = "VECTOR_AVERAGE_VERSION";
     private final String SERIALIZED_COUNT = "COUNT";
 
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/backup/BackupAccessibilityTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/backup/BackupAccessibilityTestActivity.java
new file mode 100644
index 0000000..157a71c
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/backup/BackupAccessibilityTestActivity.java
@@ -0,0 +1,342 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.verifier.backup;
+
+import com.android.cts.verifier.PassFailButtons;
+import com.android.cts.verifier.R;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.backup.BackupManager;
+import android.app.backup.FileBackupHelper;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.graphics.Color;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.widget.BaseAdapter;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+import java.util.Scanner;
+
+/**
+ * Test for checking whether Accessibility Settings are being backed up properly. It lists the
+ * values of the accessibility preferences that should get backed up and restored after running the
+ * backup manager and reinstalling the CTS verifier.
+ */
+public class BackupAccessibilityTestActivity extends PassFailButtons.ListActivity {
+
+    private static final String TAG = BackupAccessibilityTestActivity.class.getSimpleName();
+
+    private static final int INSTRUCTIONS_DIALOG_ID = 1;
+
+    private static final List<String> ACCESSIBILITY_SETTINGS = new ArrayList();
+    private static final List<String> COLOR_CORRECTION_SETTINGS = new ArrayList();
+    private static final List<String> ACCESSIBILITY_SERVICE_SETTINGS = new ArrayList();
+    private static final List<String> CAPTIONS_SETTINGS = new ArrayList();
+    private static final List<String> TTS_SETTINGS = new ArrayList();
+    private static final List<String> SYSTEM_SETTINGS = new ArrayList();
+
+    static {
+        ACCESSIBILITY_SETTINGS.add("accessibility_display_magnification_enabled");
+        ACCESSIBILITY_SETTINGS.add("accessibility_autoclick_enabled");
+        ACCESSIBILITY_SETTINGS.add("accessibility_autoclick_delay");
+        ACCESSIBILITY_SETTINGS.add("high_text_contrast_enabled");
+        ACCESSIBILITY_SETTINGS.add("incall_power_button_behavior");
+        ACCESSIBILITY_SETTINGS.add(Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD);
+        ACCESSIBILITY_SETTINGS.add("accessibility_large_pointer_icon");
+        ACCESSIBILITY_SETTINGS.add("long_press_timeout");
+        ACCESSIBILITY_SETTINGS.add(Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED);
+
+        COLOR_CORRECTION_SETTINGS.add("accessibility_display_daltonizer");
+        COLOR_CORRECTION_SETTINGS.add("accessibility_display_daltonizer_enabled");
+
+        CAPTIONS_SETTINGS.add("accessibility_captioning_preset");
+        CAPTIONS_SETTINGS.add("accessibility_captioning_enabled");
+        CAPTIONS_SETTINGS.add("accessibility_captioning_locale");
+        CAPTIONS_SETTINGS.add("accessibility_captioning_background_color");
+        CAPTIONS_SETTINGS.add("accessibility_captioning_foreground_color");
+        CAPTIONS_SETTINGS.add("accessibility_captioning_edge_type");
+        CAPTIONS_SETTINGS.add("accessibility_captioning_edge_color");
+        CAPTIONS_SETTINGS.add("accessibility_captioning_typeface");
+        CAPTIONS_SETTINGS.add("accessibility_captioning_font_scale");
+        CAPTIONS_SETTINGS.add("accessibility_captioning_window_color");
+
+        TTS_SETTINGS.add(Settings.Secure.TTS_DEFAULT_RATE);
+        TTS_SETTINGS.add("tts_default_locale");
+
+        ACCESSIBILITY_SERVICE_SETTINGS.add(Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
+        ACCESSIBILITY_SERVICE_SETTINGS.add("touch_exploration_granted_accessibility_services");
+        ACCESSIBILITY_SERVICE_SETTINGS.add(Settings.Secure.TOUCH_EXPLORATION_ENABLED);
+
+        SYSTEM_SETTINGS.add(Settings.System.FONT_SCALE);
+        SYSTEM_SETTINGS.add(Settings.System.STAY_ON_WHILE_PLUGGED_IN);
+        SYSTEM_SETTINGS.add(Settings.System.SCREEN_OFF_TIMEOUT);
+        SYSTEM_SETTINGS.add(Settings.System.SCREEN_BRIGHTNESS);
+        SYSTEM_SETTINGS.add(Settings.System.SCREEN_BRIGHTNESS_MODE);
+        SYSTEM_SETTINGS.add(Settings.System.TEXT_SHOW_PASSWORD);
+        SYSTEM_SETTINGS.add(Settings.System.HAPTIC_FEEDBACK_ENABLED);
+        SYSTEM_SETTINGS.add("power_sounds_enabled");
+        SYSTEM_SETTINGS.add("lockscreen_sounds_enabled");
+        SYSTEM_SETTINGS.add("pointer_speed");
+        SYSTEM_SETTINGS.add(Settings.System.VIBRATE_WHEN_RINGING);
+        SYSTEM_SETTINGS.add(Settings.System.ACCELEROMETER_ROTATION);
+    }
+
+    private BackupAdapter mAdapter;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
+        setContentView(R.layout.bua_main);
+        setPassFailButtonClickListeners();
+        setInfoResources(R.string.backup_accessibility_test, R.string.backup_accessibility_info, 0);
+
+        mAdapter = new BackupAdapter(this);
+        setListAdapter(mAdapter);
+
+        new ReadCurrentSettingsValuesTask().execute();
+
+        findViewById(R.id.generate_button).setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                new ReadCurrentSettingsValuesTask().execute();
+            }
+        });
+
+        findViewById(R.id.show_instructions_button).setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                showDialog(INSTRUCTIONS_DIALOG_ID);
+            }
+        });
+    }
+
+    class ReadCurrentSettingsValuesTask extends AsyncTask<Void, Void, List<BackupItem>> {
+
+        @Override
+        protected void onPreExecute() {
+            super.onPreExecute();
+            setProgressBarIndeterminateVisibility(true);
+        }
+
+        @Override
+        protected List<BackupItem> doInBackground(Void... params) {
+            List<BackupItem> items = new ArrayList<BackupItem>();
+
+            items.add(new CategoryBackupItem(R.string.bua_settings));
+            addSecureSettings(items, ACCESSIBILITY_SETTINGS);
+
+            items.add(new CategoryBackupItem(R.string.bua_settings_color_correction));
+            addSecureSettings(items, COLOR_CORRECTION_SETTINGS);
+
+            items.add(new CategoryBackupItem(R.string.bua_settings_captions));
+            addSecureSettings(items, CAPTIONS_SETTINGS);
+
+            items.add(new CategoryBackupItem(R.string.bua_settings_tts));
+            addSecureSettings(items, TTS_SETTINGS);
+
+            items.add(new CategoryBackupItem(R.string.bua_settings_accessibility_services));
+            addSecureSettings(items, ACCESSIBILITY_SERVICE_SETTINGS);
+
+            items.add(new CategoryBackupItem(R.string.bua_settings_system));
+            addSystemSettings(items, SYSTEM_SETTINGS);
+
+            return items;
+        }
+
+        private void addSecureSettings(List<BackupItem> items, List<String> settings) {
+            for (String setting : settings) {
+                String value = Settings.Secure.getString(getContentResolver(), setting);
+                items.add(new PreferenceBackupItem(setting, value));
+            }
+        }
+
+        private void addSystemSettings(List<BackupItem> items, List<String> settings) {
+            for (String setting : settings) {
+                String value = Settings.System.getString(getContentResolver(), setting);
+                items.add(new PreferenceBackupItem(setting, value));
+            }
+        }
+
+        @Override
+        protected void onPostExecute(List<BackupItem> result) {
+            super.onPostExecute(result);
+            setProgressBarIndeterminateVisibility(false);
+            mAdapter.clear();
+            mAdapter.addAll(result);
+        }
+    }
+
+    @Override
+    public Dialog onCreateDialog(int id, Bundle args) {
+        switch (id) {
+            case INSTRUCTIONS_DIALOG_ID:
+                return new AlertDialog.Builder(this)
+                    .setIcon(android.R.drawable.ic_dialog_info)
+                    .setTitle(R.string.backup_accessibility_test)
+                    .setMessage(R.string.bua_instructions)
+                    .setPositiveButton(android.R.string.ok, null)
+                    .setNeutralButton(R.string.bu_settings, new DialogInterface.OnClickListener() {
+                        @Override
+                        public void onClick(DialogInterface dialog, int which) {
+                            startActivity(new Intent(Settings.ACTION_PRIVACY_SETTINGS));
+                        }
+                    }).create();
+
+            default:
+                return super.onCreateDialog(id, args);
+        }
+    }
+
+    interface BackupItem {
+        int getViewType();
+        View getView(LayoutInflater inflater, int position, View convertView, ViewGroup parent);
+    }
+
+    static class CategoryBackupItem implements BackupItem {
+
+        private final int mTitleResId;
+
+        CategoryBackupItem(int titleResId) {
+            mTitleResId = titleResId;
+        }
+
+        @Override
+        public int getViewType() {
+            return 0;
+        }
+
+        @Override
+        public View getView(LayoutInflater inflater, int position, View convertView,
+                ViewGroup parent) {
+            TextView view = (TextView) convertView;
+            if (convertView == null) {
+                view = (TextView) inflater.inflate(R.layout.test_category_row, parent, false);
+            }
+            view.setText(mTitleResId);
+            view.setAllCaps(true);
+            view.setTextAppearance(1);  // Bold
+            return view;
+        }
+    }
+
+    static class PreferenceBackupItem implements BackupItem {
+
+        private final String mName;
+        private final String mValue;
+
+        PreferenceBackupItem(String name, String value) {
+            mName = name;
+            mValue = value;
+        }
+
+        @Override
+        public int getViewType() {
+            if (mValue == null || mValue.equals("0")) {
+                return 1;
+            } else {
+                return 2;
+            }
+        }
+
+        @Override
+        public View getView(LayoutInflater inflater, int position, View convertView,
+                ViewGroup parent) {
+            TextView view = (TextView) convertView;
+            if (convertView == null) {
+                view = (TextView) inflater.inflate(R.layout.bu_preference_row, parent, false);
+            }
+            view.setText(mName + " : " + mValue);
+            if (mValue == null || mValue.equals("0")) {
+                view.setTextColor(Color.GREEN);
+            }
+            return view;
+        }
+    }
+
+    class BackupAdapter extends BaseAdapter {
+
+        private final LayoutInflater mLayoutInflater;
+
+        private final List<BackupItem> mItems = new ArrayList<BackupItem>();
+
+        public BackupAdapter(Context context) {
+            mLayoutInflater = (LayoutInflater) context.getSystemService(LAYOUT_INFLATER_SERVICE);
+        }
+
+        public void clear() {
+            mItems.clear();
+        }
+
+        public void addAll(List<BackupItem> items) {
+            mItems.addAll(items);
+            notifyDataSetChanged();
+        }
+
+        @Override
+        public int getCount() {
+            return mItems.size();
+        }
+
+        @Override
+        public BackupItem getItem(int position) {
+            return mItems.get(position);
+        }
+
+        @Override
+        public long getItemId(int position) {
+            return position;
+        }
+
+        @Override
+        public boolean isEnabled(int position) {
+            return false;
+        }
+
+        @Override
+        public int getViewTypeCount() {
+            return 3;
+        }
+
+        @Override
+        public int getItemViewType(int position) {
+            return getItem(position).getViewType();
+        }
+
+        @Override
+        public View getView(int position, View convertView, ViewGroup parent) {
+            return getItem(position).getView(mLayoutInflater, position, convertView, parent);
+        }
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/location/GnssMeasurementRegistrationTestsActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/location/GnssMeasurementRegistrationTestsActivity.java
new file mode 100644
index 0000000..56755cc
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/location/GnssMeasurementRegistrationTestsActivity.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.cts.verifier.location;
+
+import android.location.cts.GnssMeasurementRegistrationTest;
+import com.android.cts.verifier.location.base.GnssCtsTestActivity;
+
+/**
+ * Activity to execute CTS Gnss Measurement tests.
+ * It is a wrapper for {@link GnssMeasurementValuesTest} running with AndroidJUnitRunner.
+ */
+public class GnssMeasurementRegistrationTestsActivity extends GnssCtsTestActivity {
+    public GnssMeasurementRegistrationTestsActivity() {
+        super(GnssMeasurementRegistrationTest.class);
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/location/GnssMeasurementValuesTestsActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/location/GnssMeasurementValuesTestsActivity.java
new file mode 100644
index 0000000..4bdbddf
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/location/GnssMeasurementValuesTestsActivity.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.cts.verifier.location;
+
+import android.location.cts.GnssMeasurementValuesTest;
+import com.android.cts.verifier.location.base.GnssCtsTestActivity;
+
+/**
+ * Activity to execute CTS Gnss Measurement tests.
+ * It is a wrapper for {@link GnssMeasurementValuesTest} running with AndroidJUnitRunner.
+ */
+public class GnssMeasurementValuesTestsActivity extends GnssCtsTestActivity {
+    public GnssMeasurementValuesTestsActivity() {
+        super(GnssMeasurementValuesTest.class);
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/location/GnssMeasurementWhenNoLocationTestsActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/location/GnssMeasurementWhenNoLocationTestsActivity.java
new file mode 100644
index 0000000..1ee74c5
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/location/GnssMeasurementWhenNoLocationTestsActivity.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.cts.verifier.location;
+
+import android.location.cts.GnssMeasurementWhenNoLocationTest;
+import com.android.cts.verifier.location.base.GnssCtsTestActivity;
+
+/**
+ * Activity to execute CTS GnssMeasurementWhenNoLocationTest.
+ * It is a wrapper for {@link GnssMeasurementValuesTest} running with AndroidJUnitRunner.
+ */
+public class GnssMeasurementWhenNoLocationTestsActivity extends GnssCtsTestActivity {
+    public GnssMeasurementWhenNoLocationTestsActivity() {
+        super(GnssMeasurementWhenNoLocationTest.class);
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/location/GnssNavigationMessageTestsActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/location/GnssNavigationMessageTestsActivity.java
new file mode 100644
index 0000000..a4c9c93
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/location/GnssNavigationMessageTestsActivity.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.cts.verifier.location;
+
+import android.location.cts.GnssNavigationMessageTest;
+import com.android.cts.verifier.location.base.GnssCtsTestActivity;
+
+/**
+ * Activity to execute CTS GnssNavigationMessageTest.
+ * It is a wrapper for {@link GnssMeasurementValuesTest} running with AndroidJUnitRunner.
+ */
+public class GnssNavigationMessageTestsActivity extends GnssCtsTestActivity {
+    public GnssNavigationMessageTestsActivity() {
+        super(GnssNavigationMessageTest.class);
+    }
+}
\ No newline at end of file
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/location/LocationListenerActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/location/LocationListenerActivity.java
new file mode 100644
index 0000000..8140b3f
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/location/LocationListenerActivity.java
@@ -0,0 +1,126 @@
+package com.android.cts.verifier.location;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.location.Location;
+import android.location.LocationListener;
+import android.location.LocationManager;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.os.Process;
+import android.provider.Settings;
+import android.util.Log;
+import android.widget.Toast;
+
+import com.android.cts.verifier.R;
+
+public class LocationListenerActivity extends Activity implements Handler.Callback {
+    // Primary -> managed intent: request to goto the location settings page and listen to updates.
+    public static final String ACTION_SET_LOCATION_AND_CHECK_UPDATES =
+            "com.android.cts.verifier.location.SET_LOCATION_AND_CHECK";
+    private static final int REQUEST_LOCATION_UPDATE = 1;
+
+    private static final int MSG_TIMEOUT_ID = 1;
+
+    private static final long MSG_TIMEOUT_MILLISEC = 15000; // 15 seconds.
+
+    private LocationManager mLocationManager;
+    private Handler mHandler;
+    private boolean mIsLocationUpdated;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        mLocationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
+        mHandler = new Handler(this);
+        mIsLocationUpdated = false;
+        Intent intent = getIntent();
+        if (intent != null) {
+            String action = intent.getAction();
+            if (ACTION_SET_LOCATION_AND_CHECK_UPDATES.equals(action)) {
+                Log.d(getLogTag(), "ACTION_SET_LOCATION_AND_CHECK_UPDATES received in uid "
+                        + Process.myUid());
+                handleLocationAction();
+            }
+        }
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        switch (requestCode) {
+            case REQUEST_LOCATION_UPDATE: {
+                Log.d(getLogTag(), "Exit location settings:OK");
+                mLocationManager.removeUpdates(mLocationListener);
+                mHandler.removeMessages(MSG_TIMEOUT_ID);
+                finish();
+                break;
+            }
+            default: {
+                Log.wtf(getLogTag(), "Unknown requestCode " + requestCode + "; data = " + data);
+                break;
+            }
+        }
+    }
+
+    protected void handleLocationAction() {
+        Intent locationSettingsIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
+        if (locationSettingsIntent.resolveActivity(getPackageManager()) != null) {
+            startActivityForResult(locationSettingsIntent, REQUEST_LOCATION_UPDATE);
+            scheduleTimeout();
+        } else {
+            Log.e(getLogTag(), "Settings.ACTION_LOCATION_SOURCE_SETTINGS could not be resolved");
+            finish();
+        }
+        mLocationManager.requestLocationUpdates(
+                LocationManager.GPS_PROVIDER, 0, 0, mLocationListener);
+    }
+
+    private final LocationListener mLocationListener = new LocationListener() {
+        @Override
+        public void onLocationChanged(Location location) {
+            synchronized (LocationListenerActivity.this) {
+                if (mIsLocationUpdated) return;
+                showToast(R.string.provisioning_byod_location_mode_enable_toast_location_change);
+                mIsLocationUpdated = true;
+            }
+        }
+
+        @Override
+        public void onProviderDisabled(String provider) {
+        }
+
+        @Override
+        public void onProviderEnabled(String provider) {
+        }
+
+        @Override
+        public void onStatusChanged(String provider, int status, Bundle extras) {
+        }
+    };
+
+    private void scheduleTimeout() {
+        mHandler.removeMessages(MSG_TIMEOUT_ID);
+        mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_TIMEOUT_ID), MSG_TIMEOUT_MILLISEC);
+    }
+
+    @Override
+    public boolean handleMessage(Message msg) {
+        if (msg.what == MSG_TIMEOUT_ID) {
+            synchronized (this) {
+                if (mIsLocationUpdated) return true;
+                showToast(R.string.provisioning_byod_location_mode_time_out_toast);
+            }
+        }
+        return true;
+    }
+
+    protected String getLogTag() {
+        return "LocationListenerActivity";
+    }
+
+    protected void showToast(int messageId) {
+        String message = getString(messageId);
+        Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/location/base/BaseGnssTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/location/base/BaseGnssTestActivity.java
new file mode 100644
index 0000000..5da985d
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/location/base/BaseGnssTestActivity.java
@@ -0,0 +1,447 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.cts.verifier.location.base;
+
+import com.android.cts.verifier.R;
+import com.android.cts.verifier.TestResult;
+import com.android.cts.verifier.location.reporting.GnssTestDetails;
+
+import junit.framework.Assert;
+
+import com.android.cts.verifier.PassFailButtons;
+
+import android.content.Context;
+import android.content.Intent;
+import android.hardware.cts.helpers.ActivityResultMultiplexedLatch;
+import android.media.MediaPlayer;
+import android.os.Bundle;
+import android.os.SystemClock;
+import android.os.Vibrator;
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.text.format.DateUtils;
+import android.util.Log;
+import android.view.View;
+import android.widget.Button;
+import android.widget.LinearLayout;
+import android.widget.ScrollView;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+import android.test.AndroidTestCase;
+
+/**
+ * A base Activity that is used to build different methods to execute tests inside CtsVerifier.
+ * i.e. CTS tests, and semi-automated CtsVerifier tests.
+ *
+ * This class provides access to the following flow:
+ *      Activity set up
+ *          Execute tests (implemented by sub-classes)
+ *      Activity clean up
+ *
+ * Currently the following class structure is available:
+ * - BaseGnssTestActivity                 : provides the platform to execute Gnss tests inside
+ *      |                                     CtsVerifier.
+ *      |
+ *      -- GnssCtsTestActivity            : an activity that can be inherited from to wrap a CTS
+ *      |                                     Gnss test, and execute it inside CtsVerifier
+ *      |                                     these tests do not require any operator interaction
+ */
+public abstract class BaseGnssTestActivity extends PassFailButtons.Activity
+        implements View.OnClickListener, Runnable, IGnssTestStateContainer {
+    @Deprecated
+    protected static final String LOG_TAG = "GnssTest";
+
+    protected final Class mTestClass;
+
+    private final int mLayoutId;
+
+    private final ExecutorService mExecutorService = Executors.newSingleThreadExecutor();
+    private final ActivityResultMultiplexedLatch mActivityResultMultiplexedLatch =
+            new ActivityResultMultiplexedLatch();
+    private final ArrayList<CountDownLatch> mWaitForUserLatches = new ArrayList<CountDownLatch>();
+
+    private ScrollView mLogScrollView;
+    private LinearLayout mLogLayout;
+    private Button mNextButton;
+    protected TextView mTextView;
+
+    /**
+     * Constructor to be used by subclasses.
+     *
+     * @param testClass The class that contains the tests. It is dependant on test executor
+     *                  implemented by subclasses.
+     */
+    protected BaseGnssTestActivity(Class<? extends AndroidTestCase> testClass) {
+        this(testClass, R.layout.gnss_test);
+    }
+
+    /**
+     * Constructor to be used by subclasses. It allows to provide a custom layout for the test UI.
+     *
+     * @param testClass The class that contains the tests. It is dependant on test executor
+     *                  implemented by subclasses.
+     * @param layoutId The Id of the layout to use for the test UI. The layout must contain all the
+     *                 elements in the base layout {@code R.layout.gnss_test}.
+     */
+    protected BaseGnssTestActivity(Class testClass, int layoutId) {
+        mTestClass = testClass;
+        mLayoutId = layoutId;
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(mLayoutId);
+
+        mLogScrollView = (ScrollView) findViewById(R.id.log_scroll_view);
+        mLogLayout = (LinearLayout) findViewById(R.id.log_layout);
+        mNextButton = (Button) findViewById(R.id.next_button);
+        mNextButton.setOnClickListener(this);
+        mTextView = (TextView) findViewById(R.id.text);
+
+        mTextView.setText(R.string.location_gnss_test_info);
+
+        updateNextButton(false /*not enabled*/);
+        mExecutorService.execute(this);
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+        mExecutorService.shutdownNow();
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+    }
+
+    @Override
+    public void onClick(View target) {
+        synchronized (mWaitForUserLatches) {
+            for (CountDownLatch latch : mWaitForUserLatches) {
+                latch.countDown();
+            }
+            mWaitForUserLatches.clear();
+        }
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        mActivityResultMultiplexedLatch.onActivityResult(requestCode, resultCode);
+    }
+
+    /**
+     * The main execution {@link Thread}.
+     *
+     * This function executes in a background thread, allowing the test run freely behind the
+     * scenes. It provides the following execution hooks:
+     *  - Activity SetUp/CleanUp (not available in JUnit)
+     *  - executeTests: to implement several execution engines
+     */
+    @Override
+    public void run() {
+        long startTimeNs = SystemClock.elapsedRealtimeNanos();
+        String testName = getTestClassName();
+
+        GnssTestDetails testDetails;
+        try {
+            testDetails = new GnssTestDetails(testName, GnssTestDetails.ResultCode.PASS);
+        } catch (Throwable e) {
+            testDetails = new GnssTestDetails(testName, "DeactivateFeatures", e);
+        }
+
+        GnssTestDetails.ResultCode resultCode = testDetails.getResultCode();
+        if (resultCode == GnssTestDetails.ResultCode.SKIPPED) {
+            // this is an invalid state at this point of the test setup
+            throw new IllegalStateException("Deactivation of features cannot skip the test.");
+        }
+        if (resultCode == GnssTestDetails.ResultCode.PASS) {
+            testDetails = executeActivityTests(testName);
+        }
+
+        // This set the test UI so the operator can report the result of the test
+        updateResult(testDetails);
+    }
+
+    /**
+     * A general set up routine. It executes only once before the first test case.
+     *
+     * NOTE: implementers must be aware of the interrupted status of the worker thread, and let
+     * {@link InterruptedException} propagate.
+     *
+     * @throws Throwable An exception that denotes the failure of set up. No tests will be executed.
+     */
+    protected void activitySetUp() throws Throwable {}
+
+    /**
+     * A general clean up routine. It executes upon successful execution of {@link #activitySetUp()}
+     * and after all the test cases.
+     *
+     * NOTE: implementers must be aware of the interrupted status of the worker thread, and handle
+     * it in two cases:
+     * - let {@link InterruptedException} propagate
+     * - if it is invoked with the interrupted status, prevent from showing any UI
+
+     * @throws Throwable An exception that will be logged and ignored, for ease of implementation
+     *                   by subclasses.
+     */
+    protected void activityCleanUp() throws Throwable {}
+
+    /**
+     * Performs the work of executing the tests.
+     * Sub-classes implementing different execution methods implement this method.
+     *
+     * @return A {@link GnssTestDetails} object containing information about the executed tests.
+     */
+    protected abstract GnssTestDetails executeTests() throws InterruptedException;
+
+    @Deprecated
+    protected void appendText(String text) {
+        TextAppender textAppender = new TextAppender(R.layout.snsr_instruction);
+        textAppender.setText(text);
+        textAppender.append();
+    }
+
+    @Deprecated
+    protected void clearText() {
+        this.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mLogLayout.removeAllViews();
+            }
+        });
+    }
+
+    /**
+     * Waits for the operator to acknowledge a requested action.
+     *
+     * @param waitMessageResId The action requested to the operator.
+     */
+    protected void waitForUser(int waitMessageResId) throws InterruptedException {
+        CountDownLatch latch = new CountDownLatch(1);
+        synchronized (mWaitForUserLatches) {
+            mWaitForUserLatches.add(latch);
+        }
+
+        updateNextButton(true);
+        latch.await();
+        updateNextButton(false);
+    }
+
+    /**
+     * Waits for the operator to acknowledge to begin execution.
+     */
+    protected void waitForUserToBegin() throws InterruptedException {
+        waitForUser(R.string.snsr_wait_to_begin);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void waitForUserToContinue() throws InterruptedException {
+        waitForUser(R.string.snsr_wait_for_user);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int executeActivity(String action) throws InterruptedException {
+        return executeActivity(new Intent(action));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int executeActivity(Intent intent) throws InterruptedException {
+        ActivityResultMultiplexedLatch.Latch latch = mActivityResultMultiplexedLatch.bindThread();
+        startActivityForResult(intent, latch.getRequestCode());
+        return latch.await();
+    }
+
+    /**
+     * Plays a (default) sound as a notification for the operator.
+     */
+    protected void playSound() throws InterruptedException {
+        MediaPlayer player = MediaPlayer.create(this, Settings.System.DEFAULT_NOTIFICATION_URI);
+        if (player == null) {
+            Log.e(LOG_TAG, "MediaPlayer unavailable.");
+            return;
+        }
+        player.start();
+        try {
+            Thread.sleep(500);
+        } finally {
+            player.stop();
+        }
+    }
+
+    /**
+     * Makes the device vibrate for the given amount of time.
+     */
+    protected void vibrate(int timeInMs) {
+        Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
+        vibrator.vibrate(timeInMs);
+    }
+
+    /**
+     * Makes the device vibrate following the given pattern.
+     * See {@link Vibrator#vibrate(long[], int)} for more information.
+     */
+    protected void vibrate(long[] pattern) {
+        Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
+        vibrator.vibrate(pattern, -1);
+    }
+
+    protected String getTestClassName() {
+        if (mTestClass == null) {
+            return "<unknown>";
+        }
+        return mTestClass.getName();
+    }
+
+    protected void setLogScrollViewListener(View.OnTouchListener listener) {
+        mLogScrollView.setOnTouchListener(listener);
+    }
+
+    private void setTestResult(GnssTestDetails testDetails) {
+        // the name here, must be the Activity's name because it is what CtsVerifier expects
+        String name = super.getClass().getName();
+        GnssTestDetails.ResultCode resultCode = testDetails.getResultCode();
+        switch(resultCode) {
+            case SKIPPED:
+                TestResult.setPassedResult(this, name, "");
+                break;
+            case PASS:
+                TestResult.setPassedResult(this, name, "");
+                break;
+            case FAIL:
+                TestResult.setFailedResult(this, name, "");
+                break;
+            case INTERRUPTED:
+                // do not set a result, just return so the test can complete
+                break;
+            default:
+                throw new IllegalStateException("Unknown ResultCode: " + resultCode);
+        }
+    }
+
+    private GnssTestDetails executeActivityTests(String testName) {
+        GnssTestDetails testDetails;
+        try {
+            activitySetUp();
+            testDetails = new GnssTestDetails(testName, GnssTestDetails.ResultCode.PASS);
+        } catch (Throwable e) {
+            testDetails = new GnssTestDetails(testName, "ActivitySetUp", e);
+        }
+
+        GnssTestDetails.ResultCode resultCode = testDetails.getResultCode();
+        if (resultCode == GnssTestDetails.ResultCode.PASS) {
+            // TODO: implement execution filters:
+            //      - execute all tests and report results officially
+            //      - execute single test or failed tests only
+            try {
+                testDetails = executeTests();
+            } catch (Throwable e) {
+                // we catch and continue because we have to guarantee a proper clean-up sequence
+                testDetails = new GnssTestDetails(testName, "TestExecution", e);
+            }
+        }
+
+        // clean-up executes for all states, even on SKIPPED and INTERRUPTED there might be some
+        // intermediate state that needs to be taken care of
+        try {
+            activityCleanUp();
+        } catch (Throwable e) {
+            testDetails = new GnssTestDetails(testName, "ActivityCleanUp", e);
+        }
+
+        return testDetails;
+    }
+
+    private void updateResult(final GnssTestDetails testDetails) {
+        runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                setTestResult(testDetails);
+            }
+        });
+    }
+
+    private void updateNextButton(final boolean enabled) {
+        runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mNextButton.setEnabled(enabled);
+            }
+        });
+    }
+
+    private class ViewAppender {
+        protected final View mView;
+
+        public ViewAppender(View view) {
+            mView = view;
+        }
+
+        public void append() {
+            runOnUiThread(new Runnable() {
+                @Override
+                public void run() {
+                    mLogLayout.addView(mView);
+                    mLogScrollView.post(new Runnable() {
+                        @Override
+                        public void run() {
+                            mLogScrollView.fullScroll(View.FOCUS_DOWN);
+                        }
+                    });
+                }
+            });
+        }
+    }
+
+    private class TextAppender extends ViewAppender{
+        private final TextView mTextView;
+
+        public TextAppender(int textViewResId) {
+            super(getLayoutInflater().inflate(textViewResId, null /* viewGroup */));
+            mTextView = (TextView) mView;
+        }
+
+        public void setText(String text) {
+            mTextView.setText(text);
+        }
+
+        public void setText(int textResId) {
+            mTextView.setText(textResId);
+        }
+    }
+}
\ No newline at end of file
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/location/base/GnssCtsTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/location/base/GnssCtsTestActivity.java
new file mode 100644
index 0000000..1039f64
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/location/base/GnssCtsTestActivity.java
@@ -0,0 +1,229 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.cts.verifier.location.base;
+
+import com.android.cts.verifier.R;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.junit.internal.runners.JUnit38ClassRunner;
+import org.junit.internal.runners.SuiteMethod;
+import org.junit.runner.Computer;
+import org.junit.runner.Description;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Request;
+import org.junit.runner.Result;
+import org.junit.runner.Runner;
+import org.junit.runner.notification.Failure;
+import org.junit.runner.notification.RunListener;
+import org.junit.runners.model.InitializationError;
+import org.junit.runners.model.RunnerBuilder;
+
+import android.content.Context;
+import android.os.PowerManager;
+import android.view.WindowManager;
+
+import java.lang.Override;
+import java.lang.Runnable;
+import java.util.concurrent.TimeUnit;
+
+import android.location.cts.GnssTestCase;
+import com.android.cts.verifier.location.reporting.GnssTestDetails;
+
+/**
+ * An Activity that allows Gnss CTS tests to be executed inside CtsVerifier.
+ *
+ * Sub-classes pass the test class as part of construction.
+ * One JUnit test class is executed per Activity, the test class can still be executed outside
+ * CtsVerifier.
+ */
+public class GnssCtsTestActivity extends BaseGnssTestActivity {
+
+    /**
+     * Constructor for a CTS test executor. It will execute a standalone CTS test class.
+     *
+     * @param testClass The test class to execute, it must be a subclass of {@link AndroidTestCase}.
+     */
+    protected GnssCtsTestActivity(Class<? extends GnssTestCase> testClass) {
+        super(testClass);
+    }
+
+    @Override
+    protected void activitySetUp() throws InterruptedException {
+        waitForUserToBegin();
+        runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mTextView.setText("");
+            }
+        });
+    }
+
+    @Override
+    protected void activityCleanUp() {
+        runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
+            }
+        });
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+    }
+
+    /**
+     * For reference on the implementation of this test executor see:
+     *      android.support.test.runner.AndroidJUnitRunner
+     */
+    @Override
+    protected GnssTestDetails executeTests() {
+        JUnitCore testRunner = new JUnitCore();
+        testRunner.addListener(new GnssRunListener());
+
+        Computer computer = new Computer();
+        RunnerBuilder runnerBuilder = new GnssRunnerBuilder();
+
+        Runner runner;
+        try {
+            runner = computer.getSuite(runnerBuilder, new Class[]{ mTestClass });
+        } catch (Exception e) {
+            return new GnssTestDetails(
+                    getTestClassName(),
+                    GnssTestDetails.ResultCode.FAIL,
+                    "[JUnit Initialization]" + e.getMessage());
+        }
+
+        Request request = Request.runner(runner);
+        Result result = testRunner.run(request);
+        return new GnssTestDetails(getApplicationContext(), getClass().getName(), result);
+    }
+
+    /**
+     * A {@link RunnerBuilder} that is used to inject during execution a {@link GnssCtsTestSuite}.
+     */
+    private class GnssRunnerBuilder extends RunnerBuilder {
+        @Override
+        public Runner runnerForClass(Class<?> testClass) throws Throwable {
+            TestSuite testSuite;
+            if (hasSuiteMethod(testClass)) {
+                Test test = SuiteMethod.testFromSuiteMethod(testClass);
+                if (test instanceof TestSuite) {
+                    testSuite = (TestSuite) test;
+                } else {
+                    throw new IllegalArgumentException(
+                            testClass.getName() + "#suite() did not return a TestSuite.");
+                }
+            } else {
+                testSuite = new TestSuite(testClass);
+            }
+            GnssCtsTestSuite gnssTestSuite =
+                    new GnssCtsTestSuite(getApplicationContext(), testSuite);
+            return new JUnit38ClassRunner(gnssTestSuite);
+        }
+
+        private boolean hasSuiteMethod(Class<?> testClass) {
+            try {
+                testClass.getMethod("suite");
+                return true;
+            } catch (NoSuchMethodException e) {
+                return false;
+            }
+        }
+    }
+
+    /**
+     * Dummy {@link RunListener}.
+     * It is only used to handle logging into the UI.
+     */
+    private class GnssRunListener extends RunListener {
+        private volatile boolean mCurrentTestReported;
+        private StringBuilder mTestsResults = new StringBuilder("Test summary:\n");
+        private int mPassTestCase = 0;
+        private int mFailTestCase = 0;
+
+        public void testRunStarted(Description description) throws Exception {
+            // nothing to log
+        }
+
+        public void testRunFinished(Result result) throws Exception {
+            // nothing to log
+            runOnUiThread(new Runnable() {
+                @Override
+                public void run() {
+                    int totalTestCase = mPassTestCase + mFailTestCase;
+                    mTestsResults.append(String.format("\n\n %d/%d verification passed.",
+                            mPassTestCase, totalTestCase));
+                    if (mFailTestCase == 0) {
+                        mTestsResults.append(" All test pass!");
+                    } else {
+                        mTestsResults.append("\n\n" + mTextView.getResources().getString(
+                                R.string.location_gnss_test_retry_info) + "\n");
+                    }
+                    mTextView.setText(mTestsResults);
+                }
+            });
+            vibrate((int)TimeUnit.SECONDS.toMillis(2));
+            playSound();
+        }
+
+        public void testStarted(Description description) throws Exception {
+            mCurrentTestReported = false;
+            runOnUiThread(new Runnable() {
+                @Override
+                public void run() {
+                    mTextView.append("\n Running test: " + description.getMethodName());
+                }
+            });
+        }
+
+        public void testFinished(Description description) throws Exception {
+            if (!mCurrentTestReported) {
+                mPassTestCase++;
+                appendTestDetail("\n Test passed: " + description.getMethodName());
+                mTestsResults.append("\n Test passed: " + description.getMethodName());
+            }
+        }
+
+        public void testFailure(Failure failure) throws Exception {
+            mCurrentTestReported = true;
+            mFailTestCase++;
+            mTestsResults.append("\n Test failed: "
+                    + failure.getDescription().getMethodName()
+                    + "\n\n Error: " + failure.toString() + "\n");
+        }
+
+        public void testAssumptionFailure(Failure failure) {
+            mCurrentTestReported = true;
+        }
+
+        public void testIgnored(Description description) throws Exception {
+            mCurrentTestReported = true;
+        }
+
+        private void appendTestDetail(final String testDetail) {
+            runOnUiThread(new Runnable() {
+                @Override
+                public void run() {
+                    mTextView.append(testDetail);
+                }
+            });
+        }
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/location/base/GnssCtsTestResult.java b/apps/CtsVerifier/src/com/android/cts/verifier/location/base/GnssCtsTestResult.java
new file mode 100644
index 0000000..6bb7ffc
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/location/base/GnssCtsTestResult.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.cts.verifier.location.base;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.Protectable;
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestFailure;
+import junit.framework.TestListener;
+import junit.framework.TestResult;
+
+import android.content.Context;
+import android.test.AndroidTestCase;
+
+import java.util.Enumeration;
+
+/**
+ * A wrapper class for a {@link TestResult}.
+ *
+ * It provides a way to inject augmented data and helper objects during the execution of tests.
+ * i.e. inject a Context object for use by tests.
+ */
+public class GnssCtsTestResult extends TestResult {
+    private final Context mContext;
+    private final TestResult mWrappedTestResult;
+
+    private volatile boolean mInterrupted;
+
+    public GnssCtsTestResult(Context context, TestResult testResult) {
+        mContext = context;
+        mWrappedTestResult = testResult;
+    }
+
+    @Override
+    public void addError(Test test, Throwable throwable) {
+        mWrappedTestResult.addError(test, throwable);
+    }
+
+    @Override
+    public void addFailure(Test test, AssertionFailedError assertionFailedError) {
+        mWrappedTestResult.addFailure(test, assertionFailedError);
+    }
+
+    @Override
+    public void addListener(TestListener testListener) {
+        mWrappedTestResult.addListener(testListener);
+    }
+
+    @Override
+    public void removeListener(TestListener testListener) {
+        mWrappedTestResult.removeListener(testListener);
+    }
+
+    @Override
+    public void endTest(Test test) {
+        mWrappedTestResult.endTest(test);
+    }
+
+    @Override
+    public int errorCount() {
+        return mWrappedTestResult.errorCount();
+    }
+
+    @Override
+    public Enumeration<TestFailure> errors() {
+        return mWrappedTestResult.errors();
+    }
+
+    @Override
+    public int failureCount() {
+        return mWrappedTestResult.failureCount();
+    }
+
+    @Override
+    public Enumeration<TestFailure> failures() {
+        return mWrappedTestResult.failures();
+    }
+
+    @Override
+    public int runCount() {
+        return mWrappedTestResult.runCount();
+    }
+
+    @Override
+    public void runProtected(Test test, Protectable protectable) {
+        try {
+            protectable.protect();
+        } catch (AssertionFailedError e) {
+            addFailure(test, e);
+        } catch (ThreadDeath e) {
+            throw e;
+        } catch (InterruptedException e) {
+            mInterrupted = true;
+            addError(test, e);
+        } catch (Throwable e) {
+            addError(test, e);
+        }
+    }
+
+    @Override
+    public boolean shouldStop() {
+        return mInterrupted || mWrappedTestResult.shouldStop();
+    }
+
+    @Override
+    public void startTest(Test test) {
+        mWrappedTestResult.startTest(test);
+    }
+
+    @Override
+    public void stop() {
+        mWrappedTestResult.stop();
+    }
+
+    @Override
+    public boolean wasSuccessful() {
+        return mWrappedTestResult.wasSuccessful();
+    }
+
+    @Override
+    protected void run(TestCase testCase) {
+        if (testCase instanceof AndroidTestCase) {
+            AndroidTestCase gnssTestCase = (AndroidTestCase) testCase;
+            gnssTestCase.setContext(mContext);
+            //sensorTestCase.setEmulateSensorUnderLoad(false);
+            //sensorTestCase.setCurrentTestNode(new TestNode(testCase));
+            // TODO: set delayed assertion provider
+        } else {
+            throw new IllegalStateException("TestCase invalid.");
+        }
+        super.run(testCase);
+    }
+}
\ No newline at end of file
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/location/base/GnssCtsTestSuite.java b/apps/CtsVerifier/src/com/android/cts/verifier/location/base/GnssCtsTestSuite.java
new file mode 100644
index 0000000..0a724b6
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/location/base/GnssCtsTestSuite.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.cts.verifier.location.base;
+
+import junit.framework.Test;
+import junit.framework.TestResult;
+import junit.framework.TestSuite;
+
+import android.content.Context;
+
+import java.util.Enumeration;
+
+/**
+ * A wrapper class for a {@link TestSuite}.
+ *
+ * It provides a way to inject a {@link GnssCtsTestResult} during execution.
+ */
+public class GnssCtsTestSuite extends TestSuite {
+    private final Context mContext;
+    private final TestSuite mWrappedTestSuite;
+
+    public GnssCtsTestSuite(Context context, TestSuite testSuite) {
+        mContext = context;
+        mWrappedTestSuite = testSuite;
+    }
+
+    @Override
+    public void run(TestResult testResult) {
+        mWrappedTestSuite.run(new GnssCtsTestResult(mContext, testResult));
+    }
+
+    @Override
+    public void addTest(Test test) {
+        mWrappedTestSuite.addTest(test);
+    }
+
+    @Override
+    public int countTestCases() {
+        return mWrappedTestSuite.countTestCases();
+    }
+
+    @Override
+    public String getName() {
+        return mWrappedTestSuite.getName();
+    }
+
+    @Override
+    public void runTest(Test test, TestResult testResult) {
+        mWrappedTestSuite.runTest(test, testResult);
+    }
+
+    @Override
+    public void setName(String name) {
+        mWrappedTestSuite.setName(name);
+    }
+
+    @Override
+    public Test testAt(int index) {
+        return mWrappedTestSuite.testAt(index);
+    }
+
+    @Override
+    public int testCount() {
+        return mWrappedTestSuite.testCount();
+    }
+
+    @Override
+    public Enumeration<Test> tests() {
+        return mWrappedTestSuite.tests();
+    }
+
+    @Override
+    public String toString() {
+        return mWrappedTestSuite.toString();
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/location/base/IGnssTestStateContainer.java b/apps/CtsVerifier/src/com/android/cts/verifier/location/base/IGnssTestStateContainer.java
new file mode 100644
index 0000000..498c599
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/location/base/IGnssTestStateContainer.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.cts.verifier.location.base;
+
+import android.content.ContentResolver;
+import android.content.Intent;
+
+/**
+ * An interface that defines a facade for {@link BaseGnssTestActivity}, so it can be consumed by
+ * other CtsVerifier Sensor Test Framework helper components.
+ */
+public interface IGnssTestStateContainer {
+
+    /**
+     * Waits for the operator to acknowledge to continue execution.
+     */
+    void waitForUserToContinue() throws InterruptedException;
+
+    /**
+     * @param resId The resource Id to extract.
+     * @return The extracted string.
+     */
+    String getString(int resId);
+
+    /**
+     * @param resId  The resource Id to extract.
+     * @param params The parameters to format the string represented by the resource contents.
+     * @return The formatted extracted string.
+     */
+    String getString(int resId, Object... params);
+
+    /**
+     * Starts an Activity and blocks until it completes, then it returns its result back to the
+     * client.
+     *
+     * @param action The action to start the Activity.
+     * @return The Activity's result code.
+     */
+    int executeActivity(String action) throws InterruptedException;
+
+    /**
+     * Starts an Activity and blocks until it completes, then it returns its result back to the
+     * client.
+     *
+     * @param intent The intent to start the Activity.
+     * @return The Activity's result code.
+     */
+    int executeActivity(Intent intent) throws InterruptedException;
+
+    /**
+     * @return The {@link ContentResolver} associated with the test.
+     */
+    ContentResolver getContentResolver();
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/location/reporting/GnssTestDetails.java b/apps/CtsVerifier/src/com/android/cts/verifier/location/reporting/GnssTestDetails.java
new file mode 100644
index 0000000..ea04123
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/location/reporting/GnssTestDetails.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.cts.verifier.location.reporting;
+
+import com.android.cts.verifier.R;
+
+import org.junit.runner.Result;
+
+import android.content.Context;
+
+/**
+ * A class that holds the result of a Gnss test execution.
+ */
+public class GnssTestDetails {
+    private final String mName;
+    private final ResultCode mResultCode;
+    private final String mSummary;
+
+    public enum ResultCode {
+        SKIPPED,
+        PASS,
+        FAIL,
+        INTERRUPTED
+    }
+
+    public GnssTestDetails(String name, ResultCode resultCode) {
+        this(name, resultCode, null /* summary */);
+    }
+
+    public GnssTestDetails(String name, ResultCode resultCode, String summary) {
+        mName = name;
+        mResultCode = resultCode;
+        mSummary = summary;
+    }
+
+    public GnssTestDetails(
+            Context context,
+            String name,
+            int passCount,
+            int skipCount,
+            int failCount) {
+        ResultCode resultCode = ResultCode.PASS;
+        if (failCount > 0) {
+            resultCode = ResultCode.FAIL;
+        } else if (skipCount > 0) {
+            resultCode = ResultCode.SKIPPED;
+        }
+
+        mName = name;
+        mResultCode = resultCode;
+        mSummary = context.getString(R.string.snsr_test_summary, passCount, skipCount, failCount);
+    }
+
+    public GnssTestDetails(Context context, String name, Result result) {
+        this(context,
+                name,
+                result.getRunCount() - result.getFailureCount() - result.getIgnoreCount(),
+                result.getIgnoreCount(),
+                result.getFailureCount());
+    }
+
+    public GnssTestDetails(String name, String tag, Throwable cause) {
+        ResultCode resultCode = ResultCode.FAIL;
+        if (cause instanceof InterruptedException) {
+            resultCode = ResultCode.INTERRUPTED;
+            // the interrupted status must be restored, so other routines can consume it
+            Thread.currentThread().interrupt();
+        }
+        mName = name;
+        mResultCode = resultCode;
+        mSummary = String.format("[%s] %s", tag, cause.getMessage());
+    }
+
+    public String getName() {
+        return mName;
+    }
+
+    public ResultCode getResultCode() {
+        return mResultCode;
+    }
+
+    public String getSummary() {
+        return mSummary;
+    }
+
+    public GnssTestDetails cloneAndChangeResultCode(ResultCode resultCode) {
+        return new GnssTestDetails(mName, resultCode, mSummary);
+    }
+
+    @Override
+    public String toString() {
+        return String.format("%s|%s|%s", mName, mResultCode.name(), mSummary);
+    }
+}
+
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestActivity.java
index 7a51cb9..8cbbb1b 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestActivity.java
@@ -35,6 +35,7 @@
 import com.android.cts.verifier.TestListActivity;
 import com.android.cts.verifier.TestListAdapter.TestListItem;
 import com.android.cts.verifier.TestResult;
+import com.android.cts.verifier.location.LocationListenerActivity;
 
 /**
  * CTS verifier test for BYOD managed provisioning flow.
@@ -76,6 +77,9 @@
     private DialogTestListItem mPrintSettingsVisibleTest;
     private DialogTestListItem mIntentFiltersTest;
     private DialogTestListItem mPermissionLockdownTest;
+    private DialogTestListItem mTurnOffWorkIcon;
+    private DialogTestListItem mTurnOffWorkLauncher;
+    private DialogTestListItem mTurnOffWorkNotifications;
     private DialogTestListItem mCrossProfileImageCaptureSupportTest;
     private DialogTestListItem mCrossProfileVideoCaptureWithExtraOutputSupportTest;
     private DialogTestListItem mCrossProfileVideoCaptureWithoutExtraOutputSupportTest;
@@ -84,9 +88,15 @@
     private DialogTestListItem mDisableNfcBeamTest;
     private TestListItem mAuthenticationBoundKeyTest;
     private DialogTestListItem mEnableLocationModeTest;
-    private DialogTestListItem mDisableLocationModeTest;
+    private DialogTestListItem mDisableLocationModeThroughMainSwitchTest;
+    private DialogTestListItem mDisableLocationModeThroughWorkSwitchTest;
+    private DialogTestListItem mPrimaryLocationWhenWorkDisabledTest;
+    private DialogTestListItem mSelectWorkChallenge;
+    private DialogTestListItem mConfirmWorkCredentials;
     private TestListItem mVpnTest;
     private TestListItem mDisallowAppsControlTest;
+    private TestListItem mOrganizationInfoTest;
+    private TestListItem mPolicyTransparencyTest;
 
     public ByodFlowTestActivity() {
         super(R.layout.provisioning_byod,
@@ -161,7 +171,7 @@
     public void finish() {
         // Pass and fail buttons are known to call finish() when clicked, and this is when we want to
         // clean up the provisioned profile.
-        requestDeleteProfileOwner();
+        Utils.requestDeleteManagedProfile(this);
         enableComponent(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT);
         super.finish();
     }
@@ -336,6 +346,53 @@
                 R.string.profile_owner_permission_lockdown_test_info,
                 permissionCheckIntent);
 
+        mTurnOffWorkIcon = new DialogTestListItem(this,
+                R.string.provisioning_byod_turn_off_work_icon,
+                "BYOD_TurnOffWorkIcon",
+                R.string.provisioning_byod_turn_off_work_icon_instruction,
+                new Intent(Settings.ACTION_SETTINGS));
+
+        mTurnOffWorkLauncher = new DialogTestListItem(this,
+                R.string.provisioning_byod_turn_off_work_launcher,
+                "BYOD_TurnOffWorkStartApps",
+                R.string.provisioning_byod_turn_off_work_launcher_instruction,
+                new Intent(Settings.ACTION_SETTINGS));
+
+        mTurnOffWorkNotifications = new DialogTestListItem(this,
+                R.string.provisioning_byod_turn_off_work_notifications,
+                "BYOD_TurnOffWorkNotifications",
+                R.string.provisioning_byod_turn_off_work_notifications_instruction,
+                new Intent(ByodHelperActivity.ACTION_NOTIFICATION));
+
+        mSelectWorkChallenge = new DialogTestListItem(this,
+                R.string.provisioning_byod_select_work_challenge,
+                "BYOD_SelectWorkChallenge",
+                R.string.provisioning_byod_select_work_challenge_description,
+                new Intent(ByodHelperActivity.ACTION_TEST_SELECT_WORK_CHALLENGE));
+
+        mConfirmWorkCredentials = new DialogTestListItem(this,
+                R.string.provisioning_byod_confirm_work_credentials,
+                "BYOD_ConfirmWorkCredentials",
+                R.string.provisioning_byod_confirm_work_credentials_description,
+                new Intent(ByodHelperActivity.ACTION_TEST_CONFIRM_WORK_CREDENTIALS));
+
+        mOrganizationInfoTest = TestListItem.newTest(this,
+                R.string.provisioning_byod_organization_info,
+                OrganizationInfoTestActivity.class.getName(),
+                new Intent(this, OrganizationInfoTestActivity.class),
+                null);
+
+        final Intent policyTransparencyTestIntent = new Intent(this,
+                PolicyTransparencyTestListActivity.class);
+        policyTransparencyTestIntent.putExtra(
+                PolicyTransparencyTestListActivity.EXTRA_IS_DEVICE_OWNER, false);
+        policyTransparencyTestIntent.putExtra(
+                PolicyTransparencyTestActivity.EXTRA_TEST_ID, "BYOD_PolicyTransparency");
+        mPolicyTransparencyTest = TestListItem.newTest(this,
+                R.string.device_profile_owner_policy_transparency_test,
+                "BYOD_PolicyTransparency",
+                policyTransparencyTestIntent, null);
+
         adapter.add(mProfileOwnerInstalled);
 
         // Badge related tests
@@ -364,6 +421,14 @@
         adapter.add(mKeyguardDisabledFeaturesTest);
         adapter.add(mAuthenticationBoundKeyTest);
         adapter.add(mVpnTest);
+        adapter.add(mTurnOffWorkIcon);
+        adapter.add(mTurnOffWorkLauncher);
+        adapter.add(mTurnOffWorkNotifications);
+        adapter.add(mSelectWorkChallenge);
+        adapter.add(mConfirmWorkCredentials);
+        adapter.add(mOrganizationInfoTest);
+        adapter.add(mPolicyTransparencyTest);
+
         if (canResolveIntent(new Intent(Settings.ACTION_APPLICATION_SETTINGS))) {
             adapter.add(mDisallowAppsControlTest);
         }
@@ -465,15 +530,26 @@
                     R.string.provisioning_byod_location_mode_enable,
                     "BYOD_LocationModeEnableTest",
                     R.string.provisioning_byod_location_mode_enable_instruction,
-                    new Intent(ByodHelperActivity.ACTION_SET_LOCATION_AND_CHECK_UPDATES));
-            mDisableLocationModeTest = new DialogTestListItem(this,
+                    new Intent(ByodHelperActivity.ACTION_BYOD_SET_LOCATION_AND_CHECK_UPDATES));
+            mDisableLocationModeThroughMainSwitchTest = new DialogTestListItem(this,
                     R.string.provisioning_byod_location_mode_disable,
-                    "BYOD_LocationModeDisableTest",
+                    "BYOD_LocationModeDisableMainTest",
                     R.string.provisioning_byod_location_mode_disable_instruction,
-                    new Intent(ByodHelperActivity.ACTION_SET_LOCATION_AND_CHECK_UPDATES));
-
+                    new Intent(ByodHelperActivity.ACTION_BYOD_SET_LOCATION_AND_CHECK_UPDATES));
+            mDisableLocationModeThroughWorkSwitchTest = new DialogTestListItem(this,
+                    R.string.provisioning_byod_work_location_mode_disable,
+                    "BYOD_LocationModeDisableWorkTest",
+                    R.string.provisioning_byod_work_location_mode_disable_instruction,
+                    new Intent(ByodHelperActivity.ACTION_BYOD_SET_LOCATION_AND_CHECK_UPDATES));
+            mPrimaryLocationWhenWorkDisabledTest = new DialogTestListItem(this,
+                    R.string.provisioning_byod_primary_location_when_work_disabled,
+                    "BYOD_PrimaryLocationWhenWorkDisabled",
+                    R.string.provisioning_byod_primary_location_when_work_disabled_instruction,
+                    new Intent(LocationListenerActivity.ACTION_SET_LOCATION_AND_CHECK_UPDATES));
             adapter.add(mEnableLocationModeTest);
-            adapter.add(mDisableLocationModeTest);
+            adapter.add(mDisableLocationModeThroughMainSwitchTest);
+            adapter.add(mDisableLocationModeThroughWorkSwitchTest);
+            adapter.add(mPrimaryLocationWhenWorkDisabledTest);
         } else {
             // The system does not support GPS feature, so skip test.
             Toast.makeText(ByodFlowTestActivity.this,
@@ -507,8 +583,6 @@
                 mAdminReceiverComponent);
 
         if (sending.resolveActivity(getPackageManager()) != null) {
-            // ManagedProvisioning must be started with startActivityForResult, but we don't
-            // care about the result, so passing 0 as a requestCode
             startActivityForResult(sending, REQUEST_MANAGED_PROVISIONING);
         } else {
             showToast(R.string.provisioning_byod_disabled);
@@ -529,17 +603,6 @@
         }
     }
 
-    private void requestDeleteProfileOwner() {
-        try {
-            Intent intent = new Intent(ByodHelperActivity.ACTION_REMOVE_PROFILE_OWNER);
-            startActivity(intent);
-            showToast(R.string.provisioning_byod_delete_profile);
-        }
-        catch (ActivityNotFoundException e) {
-            Log.d(TAG, "requestDeleteProfileOwner: ActivityNotFoundException", e);
-        }
-    }
-
     private void checkIntentFilters() {
         try {
             // Enable component HandleIntentActivity before intent filters are checked.
@@ -587,7 +650,9 @@
             WorkStatusTestActivity.class.getName(),
             PermissionLockdownTestActivity.ACTIVITY_ALIAS,
             AuthenticationBoundKeyTestActivity.class.getName(),
-            VpnTestActivity.class.getName()
+            VpnTestActivity.class.getName(),
+            CommandReceiverActivity.class.getName(),
+            SetSupportMessageActivity.class.getName()
         };
         for (String component : components) {
             getPackageManager().setComponentEnabledSetting(new ComponentName(this, component),
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodHelperActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodHelperActivity.java
index 0cd674ac..e9a2728 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodHelperActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodHelperActivity.java
@@ -19,6 +19,7 @@
 import android.app.Activity;
 import android.app.admin.DevicePolicyManager;
 import android.app.Dialog;
+import android.app.KeyguardManager;
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.content.BroadcastReceiver;
@@ -27,6 +28,7 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.PackageManager;
+import android.graphics.Color;
 import android.location.Location;
 import android.location.LocationListener;
 import android.location.LocationManager;
@@ -47,6 +49,7 @@
 import java.io.File;
 import java.util.ArrayList;
 
+import com.android.cts.verifier.location.LocationListenerActivity;
 import com.android.cts.verifier.R;
 import com.android.cts.verifier.managedprovisioning.ByodPresentMediaDialog.DialogCallback;
 
@@ -59,7 +62,8 @@
  *
  * Note: We have to use a dummy activity because cross-profile intents only work for activities.
  */
-public class ByodHelperActivity extends Activity implements DialogCallback, Handler.Callback {
+public class ByodHelperActivity extends LocationListenerActivity
+        implements DialogCallback {
     static final String TAG = "ByodHelperActivity";
 
     // Primary -> managed intent: query if the profile owner has been set up.
@@ -67,7 +71,7 @@
     // Managed -> primary intent: update profile owner test status in primary's CtsVerifer
     public static final String ACTION_PROFILE_OWNER_STATUS = "com.android.cts.verifier.managedprovisioning.BYOD_STATUS";
     // Primary -> managed intent: request to delete the current profile
-    public static final String ACTION_REMOVE_PROFILE_OWNER = "com.android.cts.verifier.managedprovisioning.BYOD_REMOVE";
+    public static final String ACTION_REMOVE_MANAGED_PROFILE = "com.android.cts.verifier.managedprovisioning.BYOD_REMOVE";
     // Managed -> managed intent: provisioning completed successfully
     public static final String ACTION_PROFILE_PROVISIONED = "com.android.cts.verifier.managedprovisioning.BYOD_PROVISIONED";
     // Primary -> managed intent: request to capture and check an image
@@ -108,7 +112,7 @@
             "com.android.cts.verifier.managedprovisioning.action.TEST_APP_LINKING_DIALOG";
 
     // Primary -> managed intent: request to goto the location settings page and listen to updates.
-    public static final String ACTION_SET_LOCATION_AND_CHECK_UPDATES =
+    public static final String ACTION_BYOD_SET_LOCATION_AND_CHECK_UPDATES =
             "com.android.cts.verifier.managedprovisioning.BYOD_SET_LOCATION_AND_CHECK";
     public static final String ACTION_NOTIFICATION =
             "com.android.cts.verifier.managedprovisioning.NOTIFICATION";
@@ -125,14 +129,25 @@
     public static final String ACTION_CLEAR_USER_RESTRICTION =
             "com.android.cts.verifier.managedprovisioning.BYOD_CLEAR_USER_RESTRICTION";
 
+    // Primary -> managed intent: Start the selection of a work challenge
+    public static final String ACTION_TEST_SELECT_WORK_CHALLENGE =
+            "com.android.cts.verifier.managedprovisioning.TEST_SELECT_WORK_CHALLENGE";
+
+    // Primary -> managed intent: Start the confirm credentials screen for the managed profile
+    public static final String ACTION_TEST_CONFIRM_WORK_CREDENTIALS =
+            "com.android.cts.verifier.managedprovisioning.TEST_CONFIRM_WORK_CREDENTIALS";
+
+    public static final String ACTION_SET_ORGANIZATION_INFO =
+            "com.android.cts.verifier.managedprovisioning.TEST_ORGANIZATION_INFO";
+
     public static final int RESULT_FAILED = RESULT_FIRST_USER;
 
-    private static final int REQUEST_INSTALL_PACKAGE = 1;
-    private static final int REQUEST_IMAGE_CAPTURE = 2;
-    private static final int REQUEST_VIDEO_CAPTURE_WITH_EXTRA_OUTPUT = 3;
-    private static final int REQUEST_VIDEO_CAPTURE_WITHOUT_EXTRA_OUTPUT = 4;
-    private static final int REQUEST_AUDIO_CAPTURE = 5;
-    private static final int REQUEST_LOCATION_UPDATE = 6;
+    private static final int REQUEST_INSTALL_PACKAGE = 2;
+    private static final int REQUEST_IMAGE_CAPTURE = 3;
+    private static final int REQUEST_VIDEO_CAPTURE_WITH_EXTRA_OUTPUT = 4;
+    private static final int REQUEST_VIDEO_CAPTURE_WITHOUT_EXTRA_OUTPUT = 5;
+    private static final int REQUEST_AUDIO_CAPTURE = 6;
+    private static final int REQUEST_LOCATION_UPDATE = 7;
 
     private static final String ORIGINAL_SETTINGS_NAME = "original settings";
 
@@ -141,15 +156,8 @@
     private NotificationManager mNotificationManager;
     private Bundle mOriginalSettings;
 
-    private static final int MSG_TIMEOUT = 1;
-
-    private static final long MSG_TIMEOUT_MILLISEC = 15 * 1000;
-
     private ComponentName mAdminReceiverComponent;
     private DevicePolicyManager mDevicePolicyManager;
-    private LocationManager mLocationManager;
-    private Handler mHandler;
-    private boolean mIsLocationUpdated;
 
     private Uri mImageUri;
     private Uri mVideoUri;
@@ -181,9 +189,6 @@
         mAdminReceiverComponent = new ComponentName(this, DeviceAdminTestReceiver.class.getName());
         mDevicePolicyManager = (DevicePolicyManager) getSystemService(
                 Context.DEVICE_POLICY_SERVICE);
-        mLocationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
-        mHandler = new Handler(this);
-        mIsLocationUpdated = false;
         mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
         Intent intent = getIntent();
         String action = intent.getAction();
@@ -201,7 +206,7 @@
             response.putExtra(EXTRA_PROVISIONED, isProfileOwner());
             setResult(RESULT_OK, response);
             // Request to delete work profile.
-        } else if (action.equals(ACTION_REMOVE_PROFILE_OWNER)) {
+        } else if (action.equals(ACTION_REMOVE_MANAGED_PROFILE)) {
             if (isProfileOwner()) {
                 Log.d(TAG, "Clearing cross profile intents");
                 mDevicePolicyManager.clearCrossProfileIntentFilters(mAdminReceiverComponent);
@@ -281,8 +286,7 @@
         } else if (ACTION_KEYGUARD_DISABLED_FEATURES.equals(action)) {
             final int value = intent.getIntExtra(EXTRA_PARAMETER_1,
                     DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_NONE);
-            ComponentName admin = DeviceAdminTestReceiver.getReceiverComponentName();
-            mDevicePolicyManager.setKeyguardDisabledFeatures(admin, value);
+            mDevicePolicyManager.setKeyguardDisabledFeatures(mAdminReceiverComponent, value);
         } else if (ACTION_LOCKNOW.equals(action)) {
             mDevicePolicyManager.lockNow();
             setResult(RESULT_OK);
@@ -314,31 +318,36 @@
                 mDevicePolicyManager.clearUserRestriction(
                         DeviceAdminTestReceiver.getReceiverComponentName(), restriction);
             }
-        } else if (action.equals(ACTION_SET_LOCATION_AND_CHECK_UPDATES)) {
-            // Grant the locaiton permission to the provile owner on cts-verifier.
-            // The permission state does not have to be reverted at the end since the profile onwer
-            // is going to be deleted when BYOD tests ends.
-            grantLocationPermissionToSelf();
-            Intent locationSettingsIntent = getLocationSettingsIntent();
-            if (locationSettingsIntent.resolveActivity(getPackageManager()) != null) {
-                startActivityForResult(locationSettingsIntent, REQUEST_LOCATION_UPDATE);
-                scheduleTimeout();
-            } else {
-                Log.e(TAG, "BYOD settings could not be resolved in managed profile");
-                finish();
-            }
-            mLocationManager.requestLocationUpdates(
-                    LocationManager.GPS_PROVIDER, 0, 0, mLocationListener);
+        } else if (action.equals(ACTION_BYOD_SET_LOCATION_AND_CHECK_UPDATES)) {
+            handleLocationAction();
             return;
         } else if (action.equals(ACTION_NOTIFICATION)) {
             showNotification(Notification.VISIBILITY_PUBLIC);
         } else if (ACTION_NOTIFICATION_ON_LOCKSCREEN.equals(action)) {
-            DevicePolicyManager dpm = (DevicePolicyManager) getSystemService(
-                    Context.DEVICE_POLICY_SERVICE);
-            dpm.lockNow();
+            mDevicePolicyManager.lockNow();
             showNotification(Notification.VISIBILITY_PRIVATE);
         } else if (ACTION_CLEAR_NOTIFICATION.equals(action)) {
             mNotificationManager.cancel(NOTIFICATION_ID);
+        } else if (ACTION_TEST_SELECT_WORK_CHALLENGE.equals(action)) {
+            mDevicePolicyManager.setOrganizationColor(mAdminReceiverComponent, Color.BLUE);
+            mDevicePolicyManager.setOrganizationName(mAdminReceiverComponent, getResources()
+                    .getString(R.string.provisioning_byod_confirm_work_credentials_header));
+            startActivity(new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD));
+        } else if (ACTION_TEST_CONFIRM_WORK_CREDENTIALS.equals(action)) {
+            KeyguardManager keyguardManager =
+                    (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
+            Intent launchIntent = keyguardManager.createConfirmDeviceCredentialIntent(null, null);
+            startActivity(launchIntent);
+        } else if (ACTION_SET_ORGANIZATION_INFO.equals(action)) {
+            if(intent.hasExtra(OrganizationInfoTestActivity.EXTRA_ORGANIZATION_NAME)) {
+                final String organizationName = intent
+                        .getStringExtra(OrganizationInfoTestActivity.EXTRA_ORGANIZATION_NAME);
+                mDevicePolicyManager.setOrganizationName(mAdminReceiverComponent, organizationName);
+            }
+            final int organizationColor = intent.getIntExtra(
+                    OrganizationInfoTestActivity.EXTRA_ORGANIZATION_COLOR,
+                    mDevicePolicyManager.getOrganizationColor(mAdminReceiverComponent));
+            mDevicePolicyManager.setOrganizationColor(mAdminReceiverComponent, organizationColor);
         }
         // This activity has no UI and is only used to respond to CtsVerifier in the primary side.
         finish();
@@ -404,15 +413,8 @@
                 }
                 break;
             }
-            case REQUEST_LOCATION_UPDATE: {
-                Log.d(TAG, "BYOD exit location settings:OK");
-                mLocationManager.removeUpdates(mLocationListener);
-                mHandler.removeMessages(MSG_TIMEOUT);
-                finish();
-                break;
-            }
             default: {
-                Log.wtf(TAG, "Unknown requestCode " + requestCode + "; data = " + data);
+                super.onActivityResult(requestCode, resultCode, data);
                 break;
             }
         }
@@ -436,10 +438,6 @@
         return new Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION);
     }
 
-    public static Intent getLocationSettingsIntent() {
-        return new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
-    }
-
     public static Intent createLockIntent() {
         return new Intent(ACTION_LOCKNOW);
     }
@@ -484,11 +482,6 @@
         startActivity(intent);
     }
 
-    private void showToast(int messageId) {
-        String message = getString(messageId);
-        Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
-    }
-
     private void grantCameraPermissionToSelf() {
         mDevicePolicyManager.setPermissionGrantState(mAdminReceiverComponent, getPackageName(),
                 android.Manifest.permission.CAMERA,
@@ -502,49 +495,28 @@
         startActivity(chooser);
     }
 
+    @Override
+    protected void handleLocationAction() {
+        // Grant the locaiton permission to the provile owner on cts-verifier.
+        // The permission state does not have to be reverted at the end since the profile onwer
+        // is going to be deleted when BYOD tests ends.
+        grantLocationPermissionToSelf();
+        super.handleLocationAction();
+    }
+
     private void grantLocationPermissionToSelf() {
         mDevicePolicyManager.setPermissionGrantState(mAdminReceiverComponent, getPackageName(),
                 android.Manifest.permission.ACCESS_FINE_LOCATION,
                 DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED);
     }
 
-    private final LocationListener mLocationListener = new LocationListener() {
-        @Override
-        public void onLocationChanged(Location location) {
-            if (mIsLocationUpdated) return;
-            showToast(R.string.provisioning_byod_location_mode_enable_toast_location_change);
-            mIsLocationUpdated = true;
-        }
-
-        @Override
-        public void onProviderDisabled(String provider) {
-        }
-
-        @Override
-        public void onProviderEnabled(String provider) {
-        }
-
-        @Override
-        public void onStatusChanged(String provider, int status, Bundle extras) {
-        }
-    };
-
-    private void scheduleTimeout() {
-        mHandler.removeMessages(MSG_TIMEOUT);
-        mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_TIMEOUT), MSG_TIMEOUT_MILLISEC);
-    }
-
     @Override
     public void onDialogClose() {
         finish();
     }
 
     @Override
-    public boolean handleMessage(Message msg) {
-        if (msg.what == MSG_TIMEOUT) {
-            if (mIsLocationUpdated) return true;
-            showToast(R.string.provisioning_byod_location_mode_time_out_toast);
-        }
-        return true;
+    protected String getLogTag() {
+        return TAG;
     }
 }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodProvisioningTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodProvisioningTestActivity.java
new file mode 100644
index 0000000..dfbbb31
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodProvisioningTestActivity.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.verifier.managedprovisioning;
+
+import android.app.admin.DevicePolicyManager;
+import android.app.Activity;
+import android.content.ComponentName;
+import android.content.ContentResolver;
+import android.content.Intent;
+import android.graphics.Color;
+import android.net.Uri;
+import android.os.Bundle;
+
+import com.android.cts.verifier.ArrayTestListAdapter;
+import com.android.cts.verifier.IntentDrivenTestActivity.ButtonInfo;
+import com.android.cts.verifier.PassFailButtons;
+import com.android.cts.verifier.R;
+
+public class ByodProvisioningTestActivity extends PassFailButtons.TestListActivity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.pass_fail_list);
+        setPassFailButtonClickListeners();
+
+        final ArrayTestListAdapter adapter = new ArrayTestListAdapter(this);
+
+        Intent colorIntent = new Intent(this, ProvisioningStartingActivity.class)
+                .putExtra(DevicePolicyManager.EXTRA_PROVISIONING_MAIN_COLOR, Color.GREEN);
+        adapter.add(Utils.createInteractiveTestItem(this, "BYOD_CustomColor",
+                        R.string.provisioning_tests_byod_custom_color,
+                        R.string.provisioning_tests_byod_custom_color_info,
+                        new ButtonInfo(R.string.go_button_text, colorIntent)));
+        Uri logoUri = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + getPackageName()
+                + "/" + R.drawable.icon);
+        Intent imageIntent = new Intent(this, ProvisioningStartingActivity.class)
+                .putExtra(DevicePolicyManager.EXTRA_PROVISIONING_LOGO_URI, logoUri);
+        adapter.add(Utils.createInteractiveTestItem(this, "BYOD_CustomImage",
+                        R.string.provisioning_tests_byod_custom_image,
+                        R.string.provisioning_tests_byod_custom_image_info,
+                        new ButtonInfo(R.string.go_button_text, imageIntent)));
+
+        setTestListAdapter(adapter);
+    }
+
+    @Override
+    public void finish() {
+        // Pass and fail buttons are known to call finish() when clicked, and this is when we want
+        // to clean up the provisioned profile in case the user has added one.
+        Utils.requestDeleteManagedProfile(this);
+        super.finish();
+    }
+
+    // We need this activity because the provisioning needs to be started with
+    // startActivityForResult
+    public static class ProvisioningStartingActivity extends Activity {
+        @Override
+        protected void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            Intent provisioningIntent = new Intent(
+                    DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE);
+            // forward all the extras we received.
+            provisioningIntent.putExtras(getIntent().getExtras());
+            provisioningIntent.putExtra(
+                    DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME,
+                    new ComponentName(this, DeviceAdminTestReceiver.class.getName()));
+            startActivityForResult(provisioningIntent, 0);
+            finish();
+        }
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/CommandReceiverActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/CommandReceiverActivity.java
new file mode 100644
index 0000000..4e39720
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/CommandReceiverActivity.java
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.verifier.managedprovisioning;
+
+import android.app.Activity;
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.BitmapFactory;
+import android.os.Bundle;
+import android.os.UserManager;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.concurrent.TimeUnit;
+
+public class CommandReceiverActivity extends Activity {
+    private static final String TAG = "CommandReceiverActivity";
+
+    public static final String ACTION_EXECUTE_COMMAND =
+            "com.android.cts.verifier.managedprovisioning.action.EXECUTE_COMMAND";
+    public static final String EXTRA_COMMAND =
+            "com.android.cts.verifier.managedprovisioning.extra.COMMAND";
+
+    public static final String COMMAND_SET_USER_RESTRICTION = "set-user_restriction";
+    public static final String COMMAND_DISALLOW_KEYGUARD_UNREDACTED_NOTIFICATIONS =
+            "disallow-keyguard-unredacted-notifications";
+    public static final String COMMAND_SET_AUTO_TIME_REQUIRED = "set-auto-time-required";
+    public static final String COMMAND_SET_GLOBAL_SETTING =
+            "set-global-setting";
+    public static final String COMMAND_SET_MAXIMUM_TO_LOCK = "set-maximum-time-to-lock";
+    public static final String COMMAND_SET_PASSWORD_QUALITY = "set-password-quality";
+    public static final String COMMAND_SET_KEYGUARD_DISABLED = "set-keyguard-disabled";
+    public static final String COMMAND_SET_LOCK_SCREEN_INFO = "set-lock-screen-info";
+    public static final String COMMAND_SET_STATUSBAR_DISABLED = "set-statusbar-disabled";
+    public static final String COMMAND_ALLOW_ONLY_SYSTEM_INPUT_METHODS =
+            "allow-only-system-input-methods";
+    public static final String COMMAND_ALLOW_ONLY_SYSTEM_ACCESSIBILITY_SERVICES =
+            "allow-only-system-accessibility-services";
+    public static final String COMMAND_DEVICE_OWNER_CLEAR_POLICIES = "do-clear-policies";
+    public static final String COMMAND_PROFILE_OWNER_CLEAR_POLICIES = "po-clear-policies";
+    public static final String COMMAND_REMOVE_DEVICE_OWNER = "remove-device-owner";
+    public static final String COMMAND_REQUEST_BUGREPORT = "request-bugreport";
+    public static final String COMMAND_SET_USER_ICON = "set-user-icon";
+
+    public static final String EXTRA_USER_RESTRICTION =
+            "com.android.cts.verifier.managedprovisioning.extra.USER_RESTRICTION";
+    public static final String EXTRA_SETTING =
+            "com.android.cts.verifier.managedprovisioning.extra.SETTING";
+    // This extra can be used along with a command extra to set policy to
+    // specify if that policy is enforced or not.
+    public static final String EXTRA_ENFORCED =
+            "com.android.cts.verifier.managedprovisioning.extra.ENFORCED";
+    public static final String EXTRA_VALUE =
+            "com.android.cts.verifier.managedprovisioning.extra.VALUE";
+
+    private ComponentName mAdmin;
+    private DevicePolicyManager mDpm;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        final Intent intent = getIntent();
+        try {
+            mDpm = (DevicePolicyManager) getSystemService(
+                    Context.DEVICE_POLICY_SERVICE);
+            mAdmin = DeviceAdminTestReceiver.getReceiverComponentName();
+            Log.i(TAG, "Command: " + intent);
+
+            final String command = getIntent().getStringExtra(EXTRA_COMMAND);
+            switch (command) {
+                case COMMAND_SET_USER_RESTRICTION: {
+                    String restrictionKey = intent.getStringExtra(EXTRA_USER_RESTRICTION);
+                    boolean enforced = intent.getBooleanExtra(EXTRA_ENFORCED, false);
+                    if (enforced) {
+                        mDpm.addUserRestriction(mAdmin, restrictionKey);
+                    } else {
+                        mDpm.clearUserRestriction(mAdmin, restrictionKey);
+                    }
+                } break;
+                case COMMAND_DISALLOW_KEYGUARD_UNREDACTED_NOTIFICATIONS: {
+                    mDpm.setKeyguardDisabledFeatures(mAdmin,
+                            DevicePolicyManager.KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS);
+                } break;
+                case COMMAND_SET_AUTO_TIME_REQUIRED: {
+                    mDpm.setAutoTimeRequired(mAdmin,
+                            intent.getBooleanExtra(EXTRA_ENFORCED, false));
+                }
+                case COMMAND_SET_LOCK_SCREEN_INFO: {
+                    mDpm.setDeviceOwnerLockScreenInfo(mAdmin, intent.getStringExtra(EXTRA_VALUE));
+                }
+                case COMMAND_SET_MAXIMUM_TO_LOCK: {
+                    final long timeInSeconds = Long.parseLong(intent.getStringExtra(EXTRA_VALUE));
+                    mDpm.setMaximumTimeToLock(mAdmin,
+                            TimeUnit.SECONDS.toMillis(timeInSeconds) /* in milliseconds */);
+                } break;
+                case COMMAND_SET_PASSWORD_QUALITY: {
+                    int quality = intent.getIntExtra(EXTRA_VALUE, 0);
+                    mDpm.setPasswordQuality(mAdmin, quality);
+                } break;
+                case COMMAND_SET_KEYGUARD_DISABLED: {
+                    boolean enforced = intent.getBooleanExtra(EXTRA_ENFORCED, false);
+                    if (enforced) {
+                        mDpm.resetPassword(null, 0);
+                    }
+                    mDpm.setKeyguardDisabled(mAdmin, enforced);
+                } break;
+                case COMMAND_SET_STATUSBAR_DISABLED: {
+                    boolean enforced = intent.getBooleanExtra(EXTRA_ENFORCED, false);
+                    mDpm.setStatusBarDisabled(mAdmin, enforced);
+                } break;
+                case COMMAND_ALLOW_ONLY_SYSTEM_INPUT_METHODS: {
+                    boolean enforced = intent.getBooleanExtra(EXTRA_ENFORCED, false);
+                    mDpm.setPermittedInputMethods(mAdmin, enforced ? new ArrayList() : null);
+                } break;
+                case COMMAND_ALLOW_ONLY_SYSTEM_ACCESSIBILITY_SERVICES: {
+                    boolean enforced = intent.getBooleanExtra(EXTRA_ENFORCED, false);
+                    mDpm.setPermittedAccessibilityServices(mAdmin,
+                            enforced ? new ArrayList() : null);
+                } break;
+                case COMMAND_SET_GLOBAL_SETTING: {
+                    final String setting = intent.getStringExtra(EXTRA_SETTING);
+                    final String value = intent.getStringExtra(EXTRA_VALUE);
+                    mDpm.setGlobalSetting(mAdmin, setting, value);
+                } break;
+                case COMMAND_REMOVE_DEVICE_OWNER: {
+                    if (!mDpm.isDeviceOwnerApp(getPackageName())) {
+                        return;
+                    }
+                    clearAllPolicies();
+                    mDpm.clearDeviceOwnerApp(getPackageName());
+                } break;
+                case COMMAND_REQUEST_BUGREPORT: {
+                    if (!mDpm.isDeviceOwnerApp(getPackageName())) {
+                        return;
+                    }
+                    mDpm.requestBugreport(mAdmin);
+                } break;
+                case COMMAND_DEVICE_OWNER_CLEAR_POLICIES: {
+                    if (!mDpm.isDeviceOwnerApp(getPackageName())) {
+                        return;
+                    }
+                    clearAllPolicies();
+                } break;
+                case COMMAND_PROFILE_OWNER_CLEAR_POLICIES: {
+                    if (!mDpm.isProfileOwnerApp(getPackageName())) {
+                        return;
+                    }
+                    clearProfileOwnerRelatedPolicies();
+                } break;
+                case COMMAND_SET_USER_ICON: {
+                    if (!mDpm.isDeviceOwnerApp(getPackageName())) {
+                        return;
+                    }
+                    mDpm.setUserIcon(mAdmin, BitmapFactory.decodeResource(getResources(),
+                            com.android.cts.verifier.R.drawable.icon));
+                } break;
+            }
+        } catch (Exception e) {
+            Log.e(TAG, "Failed to execute command: " + intent, e);
+        } finally {
+            finish();
+        }
+    }
+
+    private void clearAllPolicies() {
+        clearProfileOwnerRelatedPolicies();
+
+        mDpm.clearUserRestriction(mAdmin, UserManager.DISALLOW_ADD_USER);
+        mDpm.clearUserRestriction(mAdmin, UserManager.DISALLOW_ADJUST_VOLUME);
+        mDpm.clearUserRestriction(mAdmin, UserManager.DISALLOW_CONFIG_BLUETOOTH);
+        mDpm.clearUserRestriction(mAdmin, UserManager.DISALLOW_CONFIG_CELL_BROADCASTS);
+        mDpm.clearUserRestriction(mAdmin, UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS);
+        mDpm.clearUserRestriction(mAdmin, UserManager.DISALLOW_CONFIG_TETHERING);
+        mDpm.clearUserRestriction(mAdmin, UserManager.DISALLOW_CONFIG_VPN);
+        mDpm.clearUserRestriction(mAdmin, UserManager.DISALLOW_CONFIG_WIFI);
+        mDpm.clearUserRestriction(mAdmin, UserManager.DISALLOW_DATA_ROAMING);
+        mDpm.clearUserRestriction(mAdmin, UserManager.DISALLOW_DEBUGGING_FEATURES);
+        mDpm.clearUserRestriction(mAdmin, UserManager.DISALLOW_FACTORY_RESET);
+        mDpm.clearUserRestriction(mAdmin, UserManager.DISALLOW_FUN);
+        mDpm.clearUserRestriction(mAdmin, UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES);
+        mDpm.clearUserRestriction(mAdmin, UserManager.DISALLOW_NETWORK_RESET);
+        mDpm.clearUserRestriction(mAdmin, UserManager.DISALLOW_OUTGOING_BEAM);
+        mDpm.clearUserRestriction(mAdmin, UserManager.DISALLOW_REMOVE_USER);
+
+        mDpm.setDeviceOwnerLockScreenInfo(mAdmin, null);
+        mDpm.setKeyguardDisabled(mAdmin, false);
+        mDpm.setAutoTimeRequired(mAdmin, false);
+        mDpm.setStatusBarDisabled(mAdmin, false);
+    }
+
+    private void clearProfileOwnerRelatedPolicies() {
+        mDpm.clearUserRestriction(mAdmin, UserManager.DISALLOW_APPS_CONTROL);
+        mDpm.clearUserRestriction(mAdmin, UserManager.DISALLOW_CONFIG_CREDENTIALS);
+        mDpm.clearUserRestriction(mAdmin, UserManager.DISALLOW_MODIFY_ACCOUNTS);
+        mDpm.clearUserRestriction(mAdmin, UserManager.DISALLOW_SHARE_LOCATION);
+        mDpm.clearUserRestriction(mAdmin, UserManager.DISALLOW_UNINSTALL_APPS);
+
+        mDpm.setKeyguardDisabledFeatures(mAdmin, 0);
+        mDpm.setPasswordQuality(mAdmin, 0);
+        mDpm.setMaximumTimeToLock(mAdmin, 0);
+        mDpm.setPermittedAccessibilityServices(mAdmin, null);
+        mDpm.setPermittedInputMethods(mAdmin, null);
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceAdminTestReceiver.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceAdminTestReceiver.java
index 34166e0..3c3720f 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceAdminTestReceiver.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceAdminTestReceiver.java
@@ -16,6 +16,8 @@
 
 package com.android.cts.verifier.managedprovisioning;
 
+import android.app.Notification;
+import android.app.NotificationManager;
 import android.app.admin.DeviceAdminReceiver;
 import android.app.admin.DevicePolicyManager;
 import android.content.ComponentName;
@@ -25,6 +27,9 @@
 import android.provider.Settings;
 import android.util.Log;
 
+import com.android.cts.verifier.R;
+import com.android.cts.verifier.location.LocationListenerActivity;
+
 /**
  * Profile owner receiver for BYOD flow test.
  * Setup cross-profile intent filter after successful provisioning.
@@ -37,6 +42,7 @@
                 DEVICE_OWNER_PKG + ".managedprovisioning.DeviceAdminTestReceiver";
         private static final ComponentName RECEIVER_COMPONENT_NAME = new ComponentName(
                 DEVICE_OWNER_PKG, ADMIN_RECEIVER_TEST_CLASS);
+        private static final int BUGREPORT_NOTIFICATION_ID = 12345;
 
         public static ComponentName getReceiverComponentName() {
             return RECEIVER_COMPONENT_NAME;
@@ -48,6 +54,20 @@
             setupProfile(context);
         }
 
+        @Override
+        public void onBugreportSharingDeclined(Context context, Intent intent) {
+            Log.i(TAG, "Bugreport sharing declined");
+            showBugreportNotification(context, context.getString(
+                    R.string.bugreport_sharing_declined), BUGREPORT_NOTIFICATION_ID);
+        }
+
+        @Override
+        public void onBugreportShared(Context context, Intent intent, String bugreportFileHash) {
+            Log.i(TAG, "Bugreport shared");
+            showBugreportNotification(context, context.getString(
+                    R.string.bugreport_shared_successfully), BUGREPORT_NOTIFICATION_ID);
+        }
+
         private void setupProfile(Context context) {
             DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);
             dpm.setProfileEnabled(new ComponentName(context.getApplicationContext(), getClass()));
@@ -56,7 +76,7 @@
             // Primary -> work direction
             IntentFilter filter = new IntentFilter();
             filter.addAction(ByodHelperActivity.ACTION_QUERY_PROFILE_OWNER);
-            filter.addAction(ByodHelperActivity.ACTION_REMOVE_PROFILE_OWNER);
+            filter.addAction(ByodHelperActivity.ACTION_REMOVE_MANAGED_PROFILE);
             filter.addAction(ByodHelperActivity.ACTION_INSTALL_APK);
             filter.addAction(ByodHelperActivity.ACTION_CHECK_INTENT_FILTERS);
             filter.addAction(ByodHelperActivity.ACTION_CAPTURE_AND_CHECK_IMAGE);
@@ -79,8 +99,13 @@
             filter.addAction(
                     PermissionLockdownTestActivity.ACTION_MANAGED_PROFILE_CHECK_PERMISSION_LOCKDOWN);
             filter.addAction(AuthenticationBoundKeyTestActivity.ACTION_AUTH_BOUND_KEY_TEST);
-            filter.addAction(ByodHelperActivity.ACTION_SET_LOCATION_AND_CHECK_UPDATES);
+            filter.addAction(ByodHelperActivity.ACTION_BYOD_SET_LOCATION_AND_CHECK_UPDATES);
             filter.addAction(VpnTestActivity.ACTION_VPN);
+            filter.addAction(ByodHelperActivity.ACTION_TEST_SELECT_WORK_CHALLENGE);
+            filter.addAction(ByodHelperActivity.ACTION_TEST_CONFIRM_WORK_CREDENTIALS);
+            filter.addAction(ByodHelperActivity.ACTION_SET_ORGANIZATION_INFO);
+            filter.addAction(SetSupportMessageActivity.ACTION_SET_SUPPORT_MSG);
+            filter.addAction(CommandReceiverActivity.ACTION_EXECUTE_COMMAND);
             dpm.addCrossProfileIntentFilter(getWho(context), filter,
                     DevicePolicyManager.FLAG_MANAGED_CAN_ACCESS_PARENT);
 
@@ -88,6 +113,7 @@
             filter = new IntentFilter();
             filter.addAction(ByodHelperActivity.ACTION_PROFILE_OWNER_STATUS);
             filter.addAction(CrossProfileTestActivity.ACTION_CROSS_PROFILE_TO_PERSONAL);
+            filter.addAction(LocationListenerActivity.ACTION_SET_LOCATION_AND_CHECK_UPDATES);
             dpm.addCrossProfileIntentFilter(getWho(context), filter,
                     DevicePolicyManager.FLAG_PARENT_CAN_ACCESS_MANAGED);
 
@@ -96,4 +122,18 @@
             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
             context.startActivity(intent);
         }
+
+        private void showBugreportNotification(Context context, String msg,
+                int notificationId) {
+            NotificationManager mNotificationManager =
+                    (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
+            Notification notification = new Notification.Builder(context)
+                    .setSmallIcon(R.drawable.icon)
+                    .setContentTitle(context.getString(
+                            R.string.device_owner_requesting_bugreport_tests))
+                    .setContentText(msg)
+                    .setStyle(new Notification.BigTextStyle().bigText(msg))
+                    .build();
+            mNotificationManager.notify(notificationId, notification);
+        }
 }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerNegativeTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerNegativeTestActivity.java
index 3c0955d..5dac13b 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerNegativeTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerNegativeTestActivity.java
@@ -16,6 +16,7 @@
 
 package com.android.cts.verifier.managedprovisioning;
 
+import android.app.admin.DevicePolicyManager;
 import android.content.Intent;
 import android.database.DataSetObserver;
 import android.os.Bundle;
@@ -33,10 +34,8 @@
  */
 public class DeviceOwnerNegativeTestActivity extends PassFailButtons.TestListActivity {
 
-    private static final String ACTION_PROVISION_MANAGED_DEVICE
-        = "com.android.managedprovisioning.ACTION_PROVISION_MANAGED_DEVICE";
     private static final Intent PROVISION_DEVICE_INTENT =
-            new Intent(ACTION_PROVISION_MANAGED_DEVICE);
+            new Intent(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE);
 
     private static final String DEVICE_OWNER_NEGATIVE_TEST = "DEVICE_OWNER_PROVISIONING_NEGATIVE";
     private static final TestInfo DEVICE_OWNER_NEGATIVE_TEST_INFO = new TestInfo(
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerPositiveTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerPositiveTestActivity.java
index b6e3b2c..163f2fe 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerPositiveTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerPositiveTestActivity.java
@@ -16,6 +16,8 @@
 
 package com.android.cts.verifier.managedprovisioning;
 
+import static com.android.cts.verifier.managedprovisioning.Utils.createInteractiveTestItem;
+
 import android.app.Activity;
 import android.app.AlertDialog;
 import android.app.admin.DevicePolicyManager;
@@ -49,22 +51,9 @@
 public class DeviceOwnerPositiveTestActivity extends PassFailButtons.TestListActivity {
     private static final String TAG = "DeviceOwnerPositiveTestActivity";
 
-    static final String EXTRA_COMMAND = "extra-command";
+    private static final String ACTION_CHECK_DEVICE_OWNER =
+            "com.android.cts.verifier.managedprovisioning.action.CHECK_DEVICE_OWNER";
     static final String EXTRA_TEST_ID = "extra-test-id";
-    static final String COMMAND_SET_POLICY = "set-policy";
-    static final String EXTRA_POLICY = "extra-policy";
-    static final String EXTRA_PARAMETER_1 = "extra_parameter_1";
-    static final String EXTRA_PARAMETER_2 = "extra_parameter_2";
-    static final String COMMAND_ADD_USER_RESTRICTION = "add-user-restriction";
-    static final String COMMAND_CLEAR_USER_RESTRICTION = "clear-user-restriction";
-    static final String EXTRA_RESTRICTION = "extra-restriction";
-    static final String COMMAND_TEAR_DOWN = "tear-down";
-    static final String COMMAND_CHECK_DEVICE_OWNER = "check-device-owner";
-    static final String COMMAND_SET_GLOBAL_SETTING = "set-global-setting";
-    static final String COMMAND_SET_STATUSBAR_DISABLED = "set-statusbar-disabled";
-    static final String COMMAND_SET_KEYGUARD_DISABLED = "set-keyguard-disabled";
-    static final String COMMAND_CHECK_PERMISSION_LOCKDOWN = "check-permission-lockdown";
-    static final String EXTRA_SETTING = "extra-setting";
 
     private static final String CHECK_DEVICE_OWNER_TEST_ID = "CHECK_DEVICE_OWNER";
     private static final String DEVICE_ADMIN_SETTINGS_ID = "DEVICE_ADMIN_SETTINGS";
@@ -77,13 +66,28 @@
     private static final String DISALLOW_CONFIG_WIFI_ID = "DISALLOW_CONFIG_WIFI";
     private static final String DISALLOW_CONFIG_VPN_ID = "DISALLOW_CONFIG_VPN";
     private static final String DISALLOW_USB_FILE_TRANSFER_ID = "DISALLOW_USB_FILE_TRANSFER";
-    //TODO(rgl): This symbol should be available in android.provider.settings
-    private static final String ACTION_VPN_SETTINGS = "android.net.vpn.SETTINGS";
+    private static final String SET_USER_ICON_TEST_ID = "SET_USER_ICON";
+    private static final String DISALLOW_DATA_ROAMING_ID = "DISALLOW_DATA_ROAMING";
+    private static final String POLICY_TRANSPARENCY_TEST_ID = "POLICY_TRANSPARENCY";
     private static final String REMOVE_DEVICE_OWNER_TEST_ID = "REMOVE_DEVICE_OWNER";
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
+        if (ACTION_CHECK_DEVICE_OWNER.equals(getIntent().getAction())) {
+            DevicePolicyManager dpm = (DevicePolicyManager) getSystemService(
+                    Context.DEVICE_POLICY_SERVICE);
+            if (dpm.isDeviceOwnerApp(getPackageName())) {
+                TestResult.setPassedResult(this, getIntent().getStringExtra(EXTRA_TEST_ID),
+                        null, null);
+            } else {
+                TestResult.setFailedResult(this, getIntent().getStringExtra(EXTRA_TEST_ID),
+                        getString(R.string.device_owner_incorrect_device_owner), null);
+            }
+            finish();
+            return;
+        }
+
         setContentView(R.layout.positive_device_owner);
         setInfoResources(R.string.device_owner_positive_tests,
                 R.string.device_owner_positive_tests_info, 0);
@@ -121,18 +125,21 @@
 
     @Override
     public void finish() {
-        // Pass and fail buttons are known to call finish() when clicked, and this is when we want
-        // to remove the device owner.
-        startActivity(createTearDownIntent());
+        // If this activity was started for checking device owner status, then no need to do any
+        // tear down.
+        if (!ACTION_CHECK_DEVICE_OWNER.equals(getIntent().getAction())) {
+            // Pass and fail buttons are known to call finish() when clicked,
+            // and this is when we want to remove the device owner.
+            startActivity(createTearDownIntent());
+        }
         super.finish();
     }
 
     private void addTestsToAdapter(final ArrayTestListAdapter adapter) {
         adapter.add(createTestItem(this, CHECK_DEVICE_OWNER_TEST_ID,
                 R.string.device_owner_check_device_owner_test,
-                new Intent(this, CommandReceiver.class)
-                        .putExtra(EXTRA_COMMAND, COMMAND_CHECK_DEVICE_OWNER)
-                        ));
+                new Intent(ACTION_CHECK_DEVICE_OWNER)
+                        .putExtra(EXTRA_TEST_ID, getIntent().getStringExtra(EXTRA_TEST_ID))));
 
         // device admin settings
         adapter.add(createInteractiveTestItem(this, DEVICE_ADMIN_SETTINGS_ID,
@@ -174,11 +181,24 @@
                                         UserManager.DISALLOW_CONFIG_VPN)),
                         new ButtonInfo(
                                 R.string.device_owner_settings_go,
-                                new Intent(ACTION_VPN_SETTINGS)),
+                                new Intent(Settings.ACTION_VPN_SETTINGS)),
                         new ButtonInfo(
                                 R.string.device_owner_vpn_test,
                                 new Intent(this, VpnTestActivity.class))}));
 
+        // DISALLOW_DATA_ROAMING
+        adapter.add(createInteractiveTestItem(this, DISALLOW_DATA_ROAMING_ID,
+                R.string.device_owner_disallow_data_roaming,
+                R.string.device_owner_disallow_data_roaming_info,
+                new ButtonInfo[] {
+                        new ButtonInfo(
+                                R.string.device_owner_user_restriction_set,
+                                createSetUserRestrictionIntent(
+                                        UserManager.DISALLOW_DATA_ROAMING)),
+                        new ButtonInfo(
+                                R.string.device_owner_settings_go,
+                                new Intent(Settings.ACTION_DATA_ROAMING_SETTINGS))}));
+
         // DISALLOW_CONFIG_BLUETOOTH
         if (packageManager.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)) {
             adapter.add(createInteractiveTestItem(this, DISALLOW_CONFIG_BT_ID,
@@ -213,11 +233,13 @@
                         new ButtonInfo(
                                 R.string.device_owner_disable_statusbar_button,
                                 createDeviceOwnerIntentWithBooleanParameter(
-                                        COMMAND_SET_STATUSBAR_DISABLED, true)),
+                                        CommandReceiverActivity.COMMAND_SET_STATUSBAR_DISABLED,
+                                                true)),
                         new ButtonInfo(
                                 R.string.device_owner_reenable_statusbar_button,
                                 createDeviceOwnerIntentWithBooleanParameter(
-                                        COMMAND_SET_STATUSBAR_DISABLED, false))}));
+                                        CommandReceiverActivity.COMMAND_SET_STATUSBAR_DISABLED,
+                                                false))}));
 
         // setKeyguardDisabled
         adapter.add(createInteractiveTestItem(this, DISABLE_KEYGUARD_TEST_ID,
@@ -227,17 +249,41 @@
                         new ButtonInfo(
                                 R.string.device_owner_disable_keyguard_button,
                                 createDeviceOwnerIntentWithBooleanParameter(
-                                        COMMAND_SET_KEYGUARD_DISABLED, true)),
+                                        CommandReceiverActivity.COMMAND_SET_KEYGUARD_DISABLED,
+                                                true)),
                         new ButtonInfo(
                                 R.string.device_owner_reenable_keyguard_button,
                                 createDeviceOwnerIntentWithBooleanParameter(
-                                        COMMAND_SET_KEYGUARD_DISABLED, false))}));
+                                        CommandReceiverActivity.COMMAND_SET_KEYGUARD_DISABLED,
+                                                false))}));
+
+        adapter.add(createInteractiveTestItem(this, SET_USER_ICON_TEST_ID,
+                R.string.device_owner_set_user_icon,
+                R.string.device_owner_set_user_icon_instruction,
+                new ButtonInfo[] {
+                        new ButtonInfo(
+                                R.string.device_owner_set_user_icon_button,
+                                createSetUserIconIntent()),
+                        new ButtonInfo(
+                                R.string.device_owner_settings_go,
+                                new Intent(Settings.ACTION_SETTINGS))}));
 
         // setPermissionGrantState
         adapter.add(createTestItem(this, CHECK_PERMISSION_LOCKDOWN_TEST_ID,
                 R.string.device_profile_owner_permission_lockdown_test,
                 new Intent(PermissionLockdownTestActivity.ACTION_CHECK_PERMISSION_LOCKDOWN)));
 
+        // Policy Transparency
+        final Intent policyTransparencyTestIntent = new Intent(this,
+                PolicyTransparencyTestListActivity.class);
+        policyTransparencyTestIntent.putExtra(
+                PolicyTransparencyTestListActivity.EXTRA_IS_DEVICE_OWNER, true);
+        policyTransparencyTestIntent.putExtra(
+                PolicyTransparencyTestActivity.EXTRA_TEST_ID, POLICY_TRANSPARENCY_TEST_ID);
+        adapter.add(createTestItem(this, POLICY_TRANSPARENCY_TEST_ID,
+                R.string.device_profile_owner_policy_transparency_test,
+                policyTransparencyTestIntent));
+
         // removeDeviceOwner
         adapter.add(createInteractiveTestItem(this, REMOVE_DEVICE_OWNER_TEST_ID,
                 R.string.device_owner_remove_device_owner_test,
@@ -247,112 +293,36 @@
                         createTearDownIntent())));
     }
 
-    static TestListItem createInteractiveTestItem(Activity activity, String id, int titleRes,
-            int infoRes, ButtonInfo buttonInfo) {
-        return createInteractiveTestItem(activity, id, titleRes, infoRes,
-                new ButtonInfo[] { buttonInfo });
-    }
-
-    static TestListItem createInteractiveTestItem(Activity activity, String id, int titleRes,
-            int infoRes, ButtonInfo[] buttonInfos) {
-        return TestListItem.newTest(activity, titleRes,
-                id, new Intent(activity, IntentDrivenTestActivity.class)
-                .putExtra(IntentDrivenTestActivity.EXTRA_ID, id)
-                .putExtra(IntentDrivenTestActivity.EXTRA_TITLE, titleRes)
-                .putExtra(IntentDrivenTestActivity.EXTRA_INFO, infoRes)
-                .putExtra(IntentDrivenTestActivity.EXTRA_BUTTONS, buttonInfos),
-                null);
-    }
 
     static TestListItem createTestItem(Activity activity, String id, int titleRes,
             Intent intent) {
-        return TestListItem.newTest(activity, titleRes, id, intent.putExtra(EXTRA_TEST_ID, id),
-                null);
+        intent.putExtra(EXTRA_TEST_ID, id);
+        return TestListItem.newTest(activity, titleRes, id, intent, null);
     }
 
     private Intent createTearDownIntent() {
-        return new Intent(this, CommandReceiver.class)
-                .putExtra(EXTRA_COMMAND, COMMAND_TEAR_DOWN);
+        return new Intent(this, CommandReceiverActivity.class)
+                .putExtra(CommandReceiverActivity.EXTRA_COMMAND,
+                        CommandReceiverActivity.COMMAND_REMOVE_DEVICE_OWNER);
     }
 
     private Intent createDeviceOwnerIntentWithBooleanParameter(String command, boolean value) {
-        return new Intent(this, CommandReceiver.class)
-                .putExtra(EXTRA_COMMAND, command)
-                .putExtra(EXTRA_PARAMETER_1, value);
+        return new Intent(this, CommandReceiverActivity.class)
+                .putExtra(CommandReceiverActivity.EXTRA_COMMAND, command)
+                .putExtra(CommandReceiverActivity.EXTRA_ENFORCED, value);
     }
 
     private Intent createSetUserRestrictionIntent(String restriction) {
-        return new Intent(this, CommandReceiver.class)
-                .putExtra(EXTRA_COMMAND, COMMAND_ADD_USER_RESTRICTION)
-                .putExtra(EXTRA_RESTRICTION, restriction);
+        return new Intent(this, CommandReceiverActivity.class)
+                .putExtra(CommandReceiverActivity.EXTRA_COMMAND,
+                        CommandReceiverActivity.COMMAND_SET_USER_RESTRICTION)
+                .putExtra(CommandReceiverActivity.EXTRA_USER_RESTRICTION, restriction)
+                .putExtra(CommandReceiverActivity.EXTRA_ENFORCED, true);
     }
 
-    public static class CommandReceiver extends Activity {
-        @Override
-        public void onCreate(Bundle savedInstanceState) {
-            super.onCreate(savedInstanceState);
-            Intent intent = getIntent();
-            String command = intent.getStringExtra(EXTRA_COMMAND);
-            try {
-                DevicePolicyManager dpm = (DevicePolicyManager)
-                        getSystemService(Context.DEVICE_POLICY_SERVICE);
-                ComponentName admin = DeviceAdminTestReceiver.getReceiverComponentName();
-                Log.i(TAG, "Command: " + command);
-
-                if (COMMAND_ADD_USER_RESTRICTION.equals(command)) {
-                    String restrictionKey = intent.getStringExtra(EXTRA_RESTRICTION);
-                    dpm.addUserRestriction(admin, restrictionKey);
-                    Log.i(TAG, "Added user restriction " + restrictionKey);
-                } else if (COMMAND_CLEAR_USER_RESTRICTION.equals(command)) {
-                    String restrictionKey = intent.getStringExtra(EXTRA_RESTRICTION);
-                    dpm.clearUserRestriction(admin, restrictionKey);
-                    Log.i(TAG, "Cleared user restriction " + restrictionKey);
-                } else if (COMMAND_TEAR_DOWN.equals(command)) {
-                    tearDown(dpm, admin);
-                } else if (COMMAND_SET_GLOBAL_SETTING.equals(command)) {
-                    final String setting = intent.getStringExtra(EXTRA_SETTING);
-                    final String value = intent.getStringExtra(EXTRA_PARAMETER_1);
-                    dpm.setGlobalSetting(admin, setting, value);
-                } else if (COMMAND_SET_STATUSBAR_DISABLED.equals(command)) {
-                    final boolean value = intent.getBooleanExtra(EXTRA_PARAMETER_1, false);
-                    dpm.setStatusBarDisabled(admin, value);
-                } else if (COMMAND_SET_KEYGUARD_DISABLED.equals(command)) {
-                    final boolean value = intent.getBooleanExtra(EXTRA_PARAMETER_1, false);
-                    if (value) {
-                        dpm.resetPassword(null, 0);
-                    }
-                    dpm.setKeyguardDisabled(admin, value);
-                } else if (COMMAND_CHECK_DEVICE_OWNER.equals(command)) {
-                    if (dpm.isDeviceOwnerApp(getPackageName())) {
-                        TestResult.setPassedResult(this, intent.getStringExtra(EXTRA_TEST_ID),
-                                null, null);
-                    } else {
-                        TestResult.setFailedResult(this, intent.getStringExtra(EXTRA_TEST_ID),
-                                getString(R.string.device_owner_incorrect_device_owner), null);
-                    }
-                } else {
-                    Log.e(TAG, "Invalid command: " + command);
-                }
-            } catch (Exception e) {
-                Log.e(TAG, "Command " + command + " failed with exception " + e);
-            } finally {
-                // No matter what happened, don't let the activity run
-                finish();
-            }
-        }
-
-        private void tearDown(DevicePolicyManager dpm, ComponentName admin) {
-            if (dpm == null || !dpm.isDeviceOwnerApp(getPackageName())) {
-                return;
-            }
-
-            dpm.setStatusBarDisabled(admin, false);
-            dpm.setKeyguardDisabled(admin, false);
-            dpm.clearUserRestriction(admin, UserManager.DISALLOW_CONFIG_BLUETOOTH);
-            dpm.clearUserRestriction(admin, UserManager.DISALLOW_CONFIG_WIFI);
-            dpm.clearUserRestriction(admin, UserManager.DISALLOW_CONFIG_VPN);
-            dpm.clearDeviceOwnerApp(getPackageName());
-        }
+    private Intent createSetUserIconIntent() {
+        return new Intent(this, CommandReceiverActivity.class)
+                .putExtra(CommandReceiverActivity.EXTRA_COMMAND,
+                        CommandReceiverActivity.COMMAND_SET_USER_ICON);
     }
 }
-
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerRequestingBugreportTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerRequestingBugreportTestActivity.java
new file mode 100644
index 0000000..1d23175
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerRequestingBugreportTestActivity.java
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.verifier.managedprovisioning;
+
+import static com.android.cts.verifier.managedprovisioning.Utils.createInteractiveTestItem;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.database.DataSetObserver;
+import android.os.Bundle;
+import android.view.View;
+import android.view.View.OnClickListener;
+
+import com.android.cts.verifier.ArrayTestListAdapter;
+import com.android.cts.verifier.IntentDrivenTestActivity.ButtonInfo;
+import com.android.cts.verifier.PassFailButtons;
+import com.android.cts.verifier.R;
+import com.android.cts.verifier.TestListAdapter.TestListItem;
+import com.android.cts.verifier.TestResult;
+
+/**
+ * Activity that lists all requesting bugreport device owner tests. Requires the following
+ * adb command be issued by the user prior to starting the tests:
+ *
+ * adb shell dpm set-device-owner
+ *  'com.android.cts.verifier/com.android.cts.verifier.managedprovisioning.DeviceAdminTestReceiver'
+ */
+public class DeviceOwnerRequestingBugreportTestActivity extends PassFailButtons.TestListActivity {
+    private static final String TAG = "DeviceOwnerRequestingBugreportTestActivity";
+
+    private static final String ACTION_CHECK_DEVICE_OWNER_FOR_REQUESTING_BUGREPORT =
+            "com.android.cts.verifier.managedprovisioning.action" +
+            ".CHECK_DEVICE_OWNER_FOR_REQUESTING_BUGREPORT";
+    static final String EXTRA_TEST_ID = "extra-test-id";
+
+    private static final String CHECK_DEVICE_OWNER_TEST_ID = "CHECK_DEVICE_OWNER";
+    private static final String DEVICE_ADMIN_SETTINGS_ID = "DEVICE_ADMIN_SETTINGS";
+    private static final String BUGREPORT_SHARING_DECLINED_WHILE_BEING_TAKEN =
+            "BUGREPORT_SHARING_DECLINED_WHILE_RUNNING";
+    private static final String BUGREPORT_SHARING_ACCEPTED_WHILE_BEING_TAKEN =
+            "BUGREPORT_SHARING_ACCEPTED_WHILE_RUNNING";
+    private static final String BUGREPORT_SHARING_DECLINED_AFTER_HAVING_BEEN_TAKEN =
+            "BUGREPORT_SHARING_DECLINED_AFTER_HAVING_BEEN_TAKEN";
+    private static final String BUGREPORT_SHARING_ACCEPTED_AFTER_HAVING_BEEN_TAKEN =
+            "BUGREPORT_SHARING_ACCEPTED_AFTER_HAVING_BEEN_TAKEN";
+    private static final String REMOVE_DEVICE_OWNER_TEST_ID = "REMOVE_DEVICE_OWNER";
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        if (ACTION_CHECK_DEVICE_OWNER_FOR_REQUESTING_BUGREPORT.equals(getIntent().getAction())) {
+            DevicePolicyManager dpm = (DevicePolicyManager) getSystemService(
+                    Context.DEVICE_POLICY_SERVICE);
+            if (dpm.isDeviceOwnerApp(getPackageName())) {
+                TestResult.setPassedResult(this, getIntent().getStringExtra(EXTRA_TEST_ID),
+                        null, null);
+            } else {
+                TestResult.setFailedResult(this, getIntent().getStringExtra(EXTRA_TEST_ID),
+                        getString(R.string.device_owner_incorrect_device_owner), null);
+            }
+            finish();
+            return;
+        }
+
+        setContentView(R.layout.requesting_bugreport_device_owner);
+        setInfoResources(R.string.device_owner_requesting_bugreport_tests,
+                R.string.device_owner_requesting_bugreport_tests_info, 0);
+        setPassFailButtonClickListeners();
+
+        final ArrayTestListAdapter adapter = new ArrayTestListAdapter(this);
+        adapter.add(TestListItem.newCategory(this,
+                R.string.device_owner_requesting_bugreport_category));
+
+        addTestsToAdapter(adapter);
+
+        adapter.registerDataSetObserver(new DataSetObserver() {
+            @Override
+            public void onChanged() {
+                updatePassButton();
+            }
+        });
+
+        setTestListAdapter(adapter);
+
+        View setDeviceOwnerButton = findViewById(R.id.set_device_owner_button);
+        setDeviceOwnerButton.setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                new AlertDialog.Builder(
+                        DeviceOwnerRequestingBugreportTestActivity.this)
+                        .setIcon(android.R.drawable.ic_dialog_info)
+                        .setTitle(R.string.set_device_owner_dialog_title)
+                        .setMessage(R.string.set_device_owner_dialog_text)
+                        .setPositiveButton(android.R.string.ok, null)
+                        .show();
+            }
+        });
+    }
+
+    @Override
+    public void finish() {
+        // If this activity was started for checking device owner status, then no need to do any
+        // tear down.
+        if (!ACTION_CHECK_DEVICE_OWNER_FOR_REQUESTING_BUGREPORT.equals(getIntent().getAction())) {
+            // Pass and fail buttons are known to call finish() when clicked,
+            // and this is when we want to remove the device owner.
+            startActivity(createTearDownIntent());
+        }
+        super.finish();
+    }
+
+    private void addTestsToAdapter(final ArrayTestListAdapter adapter) {
+        adapter.add(createTestItem(this, CHECK_DEVICE_OWNER_TEST_ID,
+                R.string.device_owner_check_device_owner_test,
+                new Intent(ACTION_CHECK_DEVICE_OWNER_FOR_REQUESTING_BUGREPORT)
+                        .putExtra(EXTRA_TEST_ID, getIntent().getStringExtra(EXTRA_TEST_ID))));
+
+        // bugreport sharing declined while running test
+        adapter.add(createInteractiveTestItem(this, BUGREPORT_SHARING_DECLINED_WHILE_BEING_TAKEN,
+                R.string.device_owner_bugreport_sharing_declined_while_being_taken,
+                R.string.device_owner_bugreport_sharing_declined_while_being_taken_info,
+                new ButtonInfo(
+                        R.string.device_owner_request_bugreport,
+                        createRequestBugreportIntent())));
+
+        // bugreport sharing accepted while running test
+        adapter.add(createInteractiveTestItem(this, BUGREPORT_SHARING_ACCEPTED_WHILE_BEING_TAKEN,
+                R.string.device_owner_bugreport_sharing_accepted_while_being_taken,
+                R.string.device_owner_bugreport_sharing_accepted_while_being_taken_info,
+                new ButtonInfo(
+                        R.string.device_owner_request_bugreport,
+                        createRequestBugreportIntent())));
+
+        // bugreport sharing declined after having been taken test
+        adapter.add(createInteractiveTestItem(this,
+                BUGREPORT_SHARING_DECLINED_AFTER_HAVING_BEEN_TAKEN,
+                R.string.device_owner_bugreport_sharing_declined_after_having_been_taken,
+                R.string.device_owner_bugreport_sharing_declined_after_having_been_taken_info,
+                new ButtonInfo(
+                        R.string.device_owner_request_bugreport,
+                        createRequestBugreportIntent())));
+
+        // bugreport sharing accepted after having been taken test
+        adapter.add(createInteractiveTestItem(this,
+                BUGREPORT_SHARING_ACCEPTED_AFTER_HAVING_BEEN_TAKEN,
+                R.string.device_owner_bugreport_sharing_accepted_after_having_been_taken,
+                R.string.device_owner_bugreport_sharing_accepted_after_having_been_taken_info,
+                new ButtonInfo(
+                        R.string.device_owner_request_bugreport,
+                        createRequestBugreportIntent())));
+
+        // removeDeviceOwner
+        adapter.add(createInteractiveTestItem(this, REMOVE_DEVICE_OWNER_TEST_ID,
+                R.string.device_owner_remove_device_owner_test,
+                R.string.device_owner_remove_device_owner_test_info,
+                new ButtonInfo(
+                        R.string.remove_device_owner_button,
+                        createTearDownIntent())));
+    }
+
+    static TestListItem createTestItem(Activity activity, String id, int titleRes,
+            Intent intent) {
+        intent.putExtra(EXTRA_TEST_ID, id);
+        return TestListItem.newTest(activity, titleRes, id, intent, null);
+    }
+
+    private Intent createTearDownIntent() {
+        return new Intent(this, CommandReceiverActivity.class)
+                .putExtra(CommandReceiverActivity.EXTRA_COMMAND,
+                        CommandReceiverActivity.COMMAND_REMOVE_DEVICE_OWNER);
+    }
+
+    private Intent createRequestBugreportIntent() {
+        return new Intent(this, CommandReceiverActivity.class)
+                .putExtra(CommandReceiverActivity.EXTRA_COMMAND,
+                        CommandReceiverActivity.COMMAND_REQUEST_BUGREPORT);
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/IntentFiltersTestHelper.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/IntentFiltersTestHelper.java
index 21c7331..af71ebe 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/IntentFiltersTestHelper.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/IntentFiltersTestHelper.java
@@ -77,6 +77,7 @@
                 new Intent(Settings.ACTION_WIRELESS_SETTINGS),
                 new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD),
                 new Intent("android.net.vpn.SETTINGS"),
+                new Intent(Settings.ACTION_VPN_SETTINGS),
                 new Intent("android.settings.ACCOUNT_SYNC_SETTINGS"),
                 new Intent(Settings.ACTION_BATTERY_SAVER_SETTINGS),
                 new Intent("android.settings.LICENSE"),
@@ -148,7 +149,6 @@
         if (pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
             forwardedIntentsFromManaged.addAll(Arrays.asList(
                     new Intent(Intent.ACTION_DIAL).setData(Uri.parse("tel:123")),
-                    new Intent(Intent.ACTION_CALL).setData(Uri.parse("tel:123")),
                     new Intent("android.intent.action.CALL_EMERGENCY").setData(
                             Uri.parse("tel:123")),
                     new Intent("android.intent.action.CALL_PRIVILEGED").setData(
@@ -174,6 +174,8 @@
                             Uri.parse("mmsto:07700900100?body=Hello%20world")).addCategory(
                             Intent.CATEGORY_BROWSABLE),
                     new Intent(Settings.ACTION_APN_SETTINGS)));
+            notForwardedIntentsFromManaged
+                    .add(new Intent(Intent.ACTION_CALL).setData(Uri.parse("tel:123")));
         }
 
         if (pm.hasSystemFeature(PackageManager.FEATURE_NFC)) {
@@ -282,15 +284,9 @@
         }
 
         // Check for intents which can be forwarded to the managed profile.
-        Intent intent = checkForIntentsNotHandled(forwardedIntentsFromPrimary,
-                forwarderActivityInfo, true);
-        if (intent != null) {
-            Log.d(TAG, intent + " from primary profile should be forwarded to the " +
-                    "managed profile but is not.");
-            return false;
-        }
-
-        return true;
+        return checkForIntentsNotHandled(forwardedIntentsFromPrimary,
+                forwarderActivityInfo, "from primary profile should be forwarded to the " +
+                "managed profile but is not.", true);
     }
 
     /**
@@ -306,25 +302,17 @@
             return false;
         }
 
+        boolean success = true;
         // Check for intents which can be forwarded to the primary profile.
-        Intent intent = checkForIntentsNotHandled(forwardedIntentsFromManaged,
-                forwarderActivityInfo, true);
-        if (intent != null) {
-            Log.d(TAG, intent + " from managed profile should be forwarded to the " +
-                    "primary profile but is not.");
-            return false;
-        }
+        success &= checkForIntentsNotHandled(forwardedIntentsFromManaged,
+                forwarderActivityInfo, " from managed profile should be forwarded to the " +
+                "primary profile but is not.", true);
 
         // Check for intents which cannot be forwarded to the primary profile.
-        intent = checkForIntentsNotHandled(notForwardedIntentsFromManaged,
-                forwarderActivityInfo, false);
-        if (intent != null) {
-            Log.d(TAG, intent + " from managed profile should not be forwarded to the " +
-                    "primary profile but it is.");
-            return false;
-        }
-
-        return true;
+        success &= checkForIntentsNotHandled(notForwardedIntentsFromManaged,
+                forwarderActivityInfo, "from managed profile should not be forwarded to the " +
+                "primary profile but it is.", false);
+        return success;
     }
 
     /**
@@ -364,17 +352,18 @@
 
     /**
      * Checks if the intents passed are correctly handled.
-     * @return {@code null} if all the intents are correctly handled
-     *         otherwise, the first intent in the list which is not handled correctly.
+     * @return {@code false} if at least one intent is not handled correctly.
      */
-    private Intent checkForIntentsNotHandled(ArrayList<Intent> intentList,
-            ActivityInfo expectedForwarderActivityInfo, boolean canResolve) {
+    private boolean checkForIntentsNotHandled(ArrayList<Intent> intentList,
+            ActivityInfo expectedForwarderActivityInfo, String errorMessage, boolean canResolve) {
+        boolean success = true;
         for (Intent intent : intentList) {
             if (canForwarderActivityHandleIntent(intent,
                     expectedForwarderActivityInfo) != canResolve) {
-                return intent;
+                Log.e(TAG, intent + " " + errorMessage);
+                success = false;
             }
         }
-        return null;
+        return success;
     }
 }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/OrganizationInfoTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/OrganizationInfoTestActivity.java
new file mode 100644
index 0000000..3fb7120
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/OrganizationInfoTestActivity.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.verifier.managedprovisioning;
+
+import android.content.Intent;
+import android.graphics.Color;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.EditText;
+import android.widget.Toast;
+
+import com.android.cts.verifier.PassFailButtons;
+import com.android.cts.verifier.R;
+
+/**
+ * Test class to verify Organization Info.
+ */
+public class OrganizationInfoTestActivity extends PassFailButtons.Activity
+        implements View.OnClickListener {
+
+    public static final String EXTRA_ORGANIZATION_NAME = "extra_organization_name";
+    public static final String EXTRA_ORGANIZATION_COLOR = "extra_organization_color";
+
+    private int mOrganizationColor;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.organization_info);
+        setPassFailButtonClickListeners();
+        setButtonClickListeners();
+    }
+
+    private void setButtonClickListeners() {
+        findViewById(R.id.organization_info_set_button).setOnClickListener(this);
+        findViewById(R.id.go_button).setOnClickListener(this);
+    }
+
+    @Override
+    public void onClick(View view) {
+        if (view.getId() == R.id.organization_info_set_button) {
+            EditText organizationNameEditText = (EditText) findViewById(
+                    R.id.organization_name_edit_text);
+            Intent intent = new Intent(ByodHelperActivity.ACTION_SET_ORGANIZATION_INFO);
+            intent.putExtra(EXTRA_ORGANIZATION_NAME, organizationNameEditText.getText().toString());
+            if (isOrganizationColorSet()) {
+                intent.putExtra(EXTRA_ORGANIZATION_COLOR, mOrganizationColor);
+            }
+            startActivity(intent);
+        } else if (view.getId() == R.id.go_button) {
+            Intent intent = new Intent(ByodHelperActivity.ACTION_TEST_CONFIRM_WORK_CREDENTIALS);
+            startActivity(intent);
+        }
+    }
+
+    private boolean isOrganizationColorSet() {
+        EditText organizationColorEditText = (EditText) findViewById(
+                R.id.organization_color_edit_text);
+        try {
+            mOrganizationColor = Color.parseColor(organizationColorEditText.getText().toString());
+        } catch (Exception e) {
+            Toast.makeText(this, "Not a valid Color value", Toast.LENGTH_SHORT).show();
+            return false;
+        }
+        return true;
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/PolicyTransparencyTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/PolicyTransparencyTestActivity.java
new file mode 100644
index 0000000..9261284
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/PolicyTransparencyTestActivity.java
@@ -0,0 +1,309 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.verifier.managedprovisioning;
+
+import android.accessibilityservice.AccessibilityService;
+import android.app.admin.DevicePolicyManager;
+import android.content.Intent;
+import android.inputmethodservice.InputMethodService;
+import android.os.Bundle;
+import android.os.UserManager;
+import android.util.ArrayMap;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.CompoundButton;
+import android.widget.EditText;
+import android.widget.Spinner;
+import android.widget.Switch;
+import android.widget.TextView;
+
+import com.android.cts.verifier.PassFailButtons;
+import com.android.cts.verifier.R;
+
+import java.util.ArrayList;
+import java.util.Map;
+
+public class PolicyTransparencyTestActivity extends PassFailButtons.Activity implements
+        View.OnClickListener, CompoundButton.OnCheckedChangeListener,
+        AdapterView.OnItemSelectedListener {
+    public static final String ACTION_SHOW_POLICY_TRANSPARENCY_TEST =
+            "com.android.cts.verifier.managedprovisioning.action.SHOW_POLICY_TRANSPARENCY_TEST";
+    public static final String EXTRA_TEST =
+            "com.android.cts.verifier.managedprovisioning.extra.TEST";
+
+    public static final String TEST_CHECK_USER_RESTRICTION = "check-user-restriction";
+    public static final String TEST_CHECK_AUTO_TIME_REQUIRED = "check-auto-time-required";
+    public static final String TEST_CHECK_KEYGURAD_UNREDACTED_NOTIFICATION =
+            "check-keyguard-unredacted-notification";
+    public static final String TEST_CHECK_LOCK_SCREEN_INFO = "check-lock-screen-info";
+    public static final String TEST_CHECK_MAXIMUM_TIME_TO_LOCK = "check-maximum-time-to-lock";
+    public static final String TEST_CHECK_PASSWORD_QUALITY = "check-password-quality";
+    public static final String TEST_CHECK_PERMITTED_ACCESSIBILITY_SERVICE =
+            "check-permitted-accessibility-service";
+    public static final String TEST_CHECK_PERMITTED_INPUT_METHOD = "check-permitted-input-method";
+
+    public static final String EXTRA_SETTINGS_INTENT_ACTION =
+            "com.android.cts.verifier.managedprovisioning.extra.SETTINGS_INTENT_ACTION";
+    public static final String EXTRA_TITLE =
+            "com.android.cts.verifier.managedprovisioning.extra.TITLE";
+    public static final String EXTRA_TEST_ID =
+            "com.android.cts.verifier.managedprovisioning.extra.TEST_ID";
+
+    private static final Map<String, PolicyTestItem> POLICY_TEST_ITEMS = new ArrayMap<>();
+    static {
+        POLICY_TEST_ITEMS.put(TEST_CHECK_AUTO_TIME_REQUIRED, new PolicyTestItem(
+                R.string.auto_time_required_set_step,
+                R.string.set_auto_time_required_action,
+                R.string.set_auto_time_required_widget_label,
+                R.id.switch_widget,
+                CommandReceiverActivity.COMMAND_SET_AUTO_TIME_REQUIRED));
+        POLICY_TEST_ITEMS.put(TEST_CHECK_KEYGURAD_UNREDACTED_NOTIFICATION, new PolicyTestItem(
+                R.string.disallow_keyguard_unredacted_notifications_set_step,
+                R.string.disallow_keyguard_unredacted_notifications_action,
+                R.string.disallow_keyguard_unredacted_notifications_widget_label,
+                R.id.switch_widget,
+                CommandReceiverActivity.COMMAND_DISALLOW_KEYGUARD_UNREDACTED_NOTIFICATIONS));
+        POLICY_TEST_ITEMS.put(TEST_CHECK_LOCK_SCREEN_INFO, new PolicyTestItem(
+                R.string.lock_screen_info_set_step,
+                R.string.set_lock_screen_info_action,
+                R.string.set_lock_screen_info_widget_label,
+                R.id.edit_text_widget,
+                CommandReceiverActivity.COMMAND_SET_LOCK_SCREEN_INFO));
+        POLICY_TEST_ITEMS.put(TEST_CHECK_MAXIMUM_TIME_TO_LOCK, new PolicyTestItem(
+                R.string.maximum_time_to_lock_set_step,
+                R.string.set_maximum_time_to_lock_action,
+                R.string.set_maximum_time_to_lock_widget_label,
+                R.id.edit_text_widget,
+                CommandReceiverActivity.COMMAND_SET_MAXIMUM_TO_LOCK));
+        POLICY_TEST_ITEMS.put(TEST_CHECK_PASSWORD_QUALITY, new PolicyTestItem(
+                R.string.password_quality_set_step,
+                R.string.set_password_quality_action,
+                R.string.set_password_quality_widget_label,
+                R.id.spinner_widget,
+                CommandReceiverActivity.COMMAND_SET_PASSWORD_QUALITY));
+        POLICY_TEST_ITEMS.put(TEST_CHECK_PERMITTED_ACCESSIBILITY_SERVICE, new PolicyTestItem(
+                R.string.permitted_accessibility_services_set_step,
+                R.string.set_permitted_accessibility_services_action,
+                R.string.set_permitted_accessibility_services_widget_label,
+                R.id.switch_widget,
+                CommandReceiverActivity.COMMAND_ALLOW_ONLY_SYSTEM_ACCESSIBILITY_SERVICES));
+        POLICY_TEST_ITEMS.put(TEST_CHECK_PERMITTED_INPUT_METHOD, new PolicyTestItem(
+                R.string.permitted_input_methods_set_step,
+                R.string.set_permitted_input_methods_action,
+                R.string.set_permitted_input_methods_widget_label,
+                R.id.switch_widget,
+                CommandReceiverActivity.COMMAND_ALLOW_ONLY_SYSTEM_INPUT_METHODS));
+    }
+
+    // IDs of settings for {@link DevicePolicyManager#setPasswordQuality(ComponentName, int)}.
+    private final int[] passwordQualityIds = new int[] {
+        DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED,
+        DevicePolicyManager.PASSWORD_QUALITY_SOMETHING,
+        DevicePolicyManager.PASSWORD_QUALITY_NUMERIC,
+        DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX,
+        DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC,
+        DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC,
+        DevicePolicyManager.PASSWORD_QUALITY_COMPLEX
+    };
+    // Strings to show for each password quality setting.
+    private final int[] passwordQualityLabelResIds = new int[] {
+        R.string.password_quality_unspecified,
+        R.string.password_quality_something,
+        R.string.password_quality_numeric,
+        R.string.password_quality_numeric_complex,
+        R.string.password_quality_alphabetic,
+        R.string.password_quality_alphanumeric,
+        R.string.password_quality_complex
+    };
+
+    private String mSettingsIntentAction;
+    private String mTestId;
+    private String mTitle;
+    private String mTest;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.policy_transparency_test);
+        setPassFailButtonClickListeners();
+
+        mTitle = getIntent().getStringExtra(EXTRA_TITLE);
+        mTestId = getIntent().getStringExtra(EXTRA_TEST_ID);
+        mSettingsIntentAction = getIntent().getStringExtra(EXTRA_SETTINGS_INTENT_ACTION);
+        mTest = getIntent().getStringExtra(EXTRA_TEST);
+
+        setTitle(mTitle);
+        findViewById(R.id.open_settings_button).setOnClickListener(this);
+        updateTestInstructions();
+    }
+
+    private void updateTestInstructions() {
+        String setStep = null;
+        String userAction = null;
+        String widgetLabel = null;
+        int widgetId = 0;
+        if (TEST_CHECK_USER_RESTRICTION.equals(mTest)) {
+            setStep = getString(R.string.user_restriction_set_step, mTitle);
+            final String userRestriction = getIntent().getStringExtra(
+                    CommandReceiverActivity.EXTRA_USER_RESTRICTION);
+            userAction = UserRestrictions.getUserAction(this, userRestriction);
+            widgetLabel = mTitle;
+            widgetId = R.id.switch_widget;
+        } else {
+            final PolicyTestItem testItem = POLICY_TEST_ITEMS.get(mTest);
+            setStep = getString(testItem.setStep);
+            userAction = getString(testItem.userAction);
+            widgetLabel = getString(testItem.widgetLabel);
+            widgetId = testItem.widgetId;
+        }
+        ((TextView) findViewById(R.id.widget_label)).setText(widgetLabel);
+        ((TextView) findViewById(R.id.test_instructions)).setText(
+                getString(R.string.policy_transparency_test_instructions, setStep, userAction));
+        updateWidget(widgetId);
+    }
+
+    private void updateWidget(int widgetId) {
+        switch (widgetId) {
+            case R.id.switch_widget: {
+                Switch switchWidget = (Switch) findViewById(R.id.switch_widget);
+                switchWidget.setOnCheckedChangeListener(this);
+                switchWidget.setVisibility(View.VISIBLE);
+            } break;
+            case R.id.edit_text_widget: {
+                findViewById(R.id.edit_text_widget).setVisibility(View.VISIBLE);
+                Button updateButton = (Button) findViewById(R.id.update_button);
+                updateButton.setOnClickListener(this);
+                updateButton.setVisibility(View.VISIBLE);
+            } break;
+            case R.id.spinner_widget: {
+                if (TEST_CHECK_PASSWORD_QUALITY.equals(mTest)) {
+                    Spinner spinner = (Spinner) findViewById(R.id.spinner_widget);
+                    spinner.setVisibility(View.VISIBLE);
+                    spinner.setOnItemSelectedListener(this);
+                    final ArrayList<String> passwordQualityLabels = new ArrayList<String>();
+                    for (int resId : passwordQualityLabelResIds) {
+                        passwordQualityLabels.add(getString(resId));
+                    }
+                    ArrayAdapter<String> adapter = new ArrayAdapter(this,
+                            android.R.layout.simple_spinner_item, passwordQualityLabels);
+                    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+                    spinner.setAdapter(adapter);
+                }
+            } break;
+            default: {
+                throw new IllegalArgumentException("Unknown widgetId: " + widgetId);
+            }
+        }
+    }
+
+    @Override
+    public void onClick(View view) {
+        if (view.getId() == R.id.open_settings_button) {
+            startActivity(new Intent(mSettingsIntentAction));
+        } else if (view.getId() == R.id.update_button) {
+            final PolicyTestItem testItem = POLICY_TEST_ITEMS.get(mTest);
+            final Intent intent = new Intent(CommandReceiverActivity.ACTION_EXECUTE_COMMAND);
+            intent.putExtra(CommandReceiverActivity.EXTRA_COMMAND, testItem.command);
+            final EditText editText = (EditText) findViewById(R.id.edit_text_widget);
+            intent.putExtra(CommandReceiverActivity.EXTRA_VALUE, editText.getText().toString());
+            startActivity(intent);
+        }
+    }
+
+    @Override
+    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+        final Intent intent = new Intent(CommandReceiverActivity.ACTION_EXECUTE_COMMAND);
+        if (TEST_CHECK_USER_RESTRICTION.equals(mTest)) {
+            final String userRestriction = getIntent().getStringExtra(
+                    CommandReceiverActivity.EXTRA_USER_RESTRICTION);
+            intent.putExtra(CommandReceiverActivity.EXTRA_COMMAND,
+                    CommandReceiverActivity.COMMAND_SET_USER_RESTRICTION);
+            intent.putExtra(CommandReceiverActivity.EXTRA_USER_RESTRICTION, userRestriction);
+            intent.putExtra(CommandReceiverActivity.EXTRA_ENFORCED, isChecked);
+        } else {
+            final PolicyTestItem testItem = POLICY_TEST_ITEMS.get(mTest);
+            intent.putExtra(CommandReceiverActivity.EXTRA_COMMAND, testItem.command);
+            intent.putExtra(CommandReceiverActivity.EXTRA_ENFORCED, isChecked);
+        }
+        startActivity(intent);
+    }
+
+    @Override
+    public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
+        final PolicyTestItem testItem = POLICY_TEST_ITEMS.get(mTest);
+        final Intent intent = new Intent(CommandReceiverActivity.ACTION_EXECUTE_COMMAND);
+        intent.putExtra(CommandReceiverActivity.EXTRA_COMMAND, testItem.command);
+        if (TEST_CHECK_PASSWORD_QUALITY.equals(mTest)) {
+            intent.putExtra(CommandReceiverActivity.EXTRA_VALUE, passwordQualityIds[(int) id]);
+        }
+        startActivity(intent);
+    }
+
+    @Override
+    public void onNothingSelected(AdapterView<?> parent) {
+        // Do nothing.
+    }
+
+    @Override
+    public String getTestId() {
+        return mTestId;
+    }
+
+    public class DummyAccessibilityService extends AccessibilityService {
+        @Override
+        public void onAccessibilityEvent(AccessibilityEvent event) {
+            // Do nothing
+        }
+
+        @Override
+        public void onInterrupt() {
+            // Do nothing
+        }
+    }
+
+    public class DummyInputMethod extends InputMethodService {
+        @Override
+        public boolean onEvaluateFullscreenMode() {
+            return false;
+        }
+
+        @Override
+        public boolean onEvaluateInputViewShown() {
+            return false;
+        }
+    }
+
+    private static class PolicyTestItem {
+        public final int setStep;
+        public final int userAction;
+        public final int widgetLabel;
+        public final int widgetId;
+        public final String command;
+
+        public PolicyTestItem(int setStep, int userAction, int widgetLabel, int widgetId,
+                String command) {
+            this.setStep = setStep;
+            this.userAction = userAction;
+            this.widgetLabel = widgetLabel;
+            this.widgetId = widgetId;
+            this.command = command;
+        }
+    }
+}
\ No newline at end of file
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/PolicyTransparencyTestListActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/PolicyTransparencyTestListActivity.java
new file mode 100644
index 0000000..88f4f18
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/PolicyTransparencyTestListActivity.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.verifier.managedprovisioning;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.Intent;
+import android.database.DataSetObserver;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.util.Pair;
+import android.view.View;
+
+import com.android.cts.verifier.ArrayTestListAdapter;
+import com.android.cts.verifier.PassFailButtons;
+import com.android.cts.verifier.R;
+import com.android.cts.verifier.TestListAdapter.TestListItem;
+
+import java.util.ArrayList;
+
+/**
+ * Test class to verify transparency for policies enforced by device/profile owner.
+ */
+public class PolicyTransparencyTestListActivity extends PassFailButtons.TestListActivity
+        implements View.OnClickListener {
+    public static final String ACTION_CHECK_POLICY_TRANSPARENCY =
+            "com.android.cts.verifier.managedprovisioning.action.CHECK_POLICY_TRANSPARENCY";
+    public static final String EXTRA_IS_DEVICE_OWNER =
+            "com.android.cts.verifier.managedprovisioning.extra.IS_DEVICE_OWNER";
+
+    private static final Pair<Intent, Integer>[] POLICIES;
+    static {
+        final String[] policyTests = new String[] {
+            PolicyTransparencyTestActivity.TEST_CHECK_AUTO_TIME_REQUIRED,
+            PolicyTransparencyTestActivity.TEST_CHECK_KEYGURAD_UNREDACTED_NOTIFICATION,
+            PolicyTransparencyTestActivity.TEST_CHECK_LOCK_SCREEN_INFO,
+            PolicyTransparencyTestActivity.TEST_CHECK_MAXIMUM_TIME_TO_LOCK,
+            PolicyTransparencyTestActivity.TEST_CHECK_PASSWORD_QUALITY,
+            PolicyTransparencyTestActivity.TEST_CHECK_PERMITTED_ACCESSIBILITY_SERVICE,
+            PolicyTransparencyTestActivity.TEST_CHECK_PERMITTED_INPUT_METHOD
+        };
+        final String[] settingsIntentActions = new String[] {
+            Settings.ACTION_DATE_SETTINGS,
+            Settings.ACTION_SETTINGS,
+            Settings.ACTION_SECURITY_SETTINGS,
+            Settings.ACTION_DISPLAY_SETTINGS,
+            DevicePolicyManager.ACTION_SET_NEW_PASSWORD,
+            Settings.ACTION_ACCESSIBILITY_SETTINGS,
+            Settings.ACTION_INPUT_METHOD_SETTINGS
+        };
+        final int[] policyLabels = new int[] {
+            R.string.set_auto_time_required,
+            R.string.disallow_keyguard_unredacted_notifications,
+            R.string.set_lock_screen_info,
+            R.string.set_maximum_time_to_lock,
+            R.string.set_password_quality,
+            R.string.set_permitted_accessibility_services,
+            R.string.set_permitted_input_methods
+        };
+        if (policyTests.length != settingsIntentActions.length ||
+                policyTests.length != policyLabels.length) {
+            throw new AssertionError("Number of items in policyTests, "
+                    + " settingsIntentActions and policyLabels do not match");
+        }
+        POLICIES = new Pair[policyTests.length];
+        for (int i = 0; i < policyTests.length; ++i) {
+            final Intent intent =
+                    new Intent(PolicyTransparencyTestActivity.ACTION_SHOW_POLICY_TRANSPARENCY_TEST)
+                            .putExtra(PolicyTransparencyTestActivity.EXTRA_TEST, policyTests[i])
+                            .putExtra(PolicyTransparencyTestActivity.EXTRA_SETTINGS_INTENT_ACTION,
+                                    settingsIntentActions[i]);
+            POLICIES[i] = Pair.create(intent, policyLabels[i]);
+        }
+    }
+
+    private static final ArrayList<String> ALSO_VALID_FOR_PO = new ArrayList<String>();
+    static {
+        ALSO_VALID_FOR_PO.add(
+                PolicyTransparencyTestActivity.TEST_CHECK_PERMITTED_ACCESSIBILITY_SERVICE);
+        ALSO_VALID_FOR_PO.add(PolicyTransparencyTestActivity.TEST_CHECK_PERMITTED_INPUT_METHOD);
+    }
+
+    private boolean mIsDeviceOwner;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.policy_transparency_test_list);
+        setInfoResources(R.string.device_profile_owner_policy_transparency_test,
+                R.string.device_profile_owner_policy_transparency_test_info, 0);
+        setPassFailButtonClickListeners();
+        setSupportMsgButtonClickListeners();
+
+        mIsDeviceOwner = getIntent().getBooleanExtra(EXTRA_IS_DEVICE_OWNER, false);
+
+        final ArrayTestListAdapter adapter = new ArrayTestListAdapter(this);
+        addTestsToAdapter(adapter);
+        adapter.registerDataSetObserver(new DataSetObserver() {
+            @Override
+            public void onChanged() {
+                updatePassButton();
+            }
+        });
+
+        setTestListAdapter(adapter);
+    }
+
+    private void addTestsToAdapter(final ArrayTestListAdapter adapter) {
+        for (String restriction : UserRestrictions.getUserRestrictions()) {
+            final Intent intent = UserRestrictions.getUserRestrictionTestIntent(this, restriction);
+            if (!mIsDeviceOwner && !UserRestrictions.isValidForPO(restriction)) {
+                continue;
+            }
+            final String title = UserRestrictions.getRestrictionLabel(this, restriction);
+            String testId = (mIsDeviceOwner ? "DO_" : "PO_") + title;
+            intent.putExtra(PolicyTransparencyTestActivity.EXTRA_TEST_ID, testId);
+            adapter.add(TestListItem.newTest(title, testId, intent, null));
+        }
+
+        for (Pair<Intent, Integer> policy : POLICIES) {
+            final Intent intent = policy.first;
+            String test = intent.getStringExtra(PolicyTransparencyTestActivity.EXTRA_TEST);
+            if (!mIsDeviceOwner && !ALSO_VALID_FOR_PO.contains(test)) {
+                continue;
+            }
+            final String title = getString(policy.second);
+            String testId = (mIsDeviceOwner ? "DO_" : "PO_") + title;
+            intent.putExtra(PolicyTransparencyTestActivity.EXTRA_TITLE, title);
+            intent.putExtra(PolicyTransparencyTestActivity.EXTRA_TEST_ID, testId);
+            adapter.add(TestListItem.newTest(title, testId, intent, null));
+        }
+    }
+
+    private void setSupportMsgButtonClickListeners() {
+        findViewById(R.id.short_msg_button).setOnClickListener(this);
+        findViewById(R.id.long_msg_button).setOnClickListener(this);
+    }
+
+    @Override
+    public void onClick(View view) {
+        if (view.getId() == R.id.short_msg_button) {
+            final Intent intent = new Intent(SetSupportMessageActivity.ACTION_SET_SUPPORT_MSG);
+            intent.putExtra(SetSupportMessageActivity.EXTRA_SUPPORT_MSG_TYPE,
+                    SetSupportMessageActivity.TYPE_SHORT_MSG);
+            startActivity(intent);
+        } else if (view.getId() == R.id.long_msg_button) {
+            final Intent intent = new Intent(SetSupportMessageActivity.ACTION_SET_SUPPORT_MSG);
+            intent.putExtra(SetSupportMessageActivity.EXTRA_SUPPORT_MSG_TYPE,
+                    SetSupportMessageActivity.TYPE_LONG_MSG);
+            startActivity(intent);
+        }
+    }
+
+    @Override
+    public String getTestId() {
+        return getIntent().getStringExtra(PolicyTransparencyTestActivity.EXTRA_TEST_ID);
+    }
+
+    @Override
+    public void finish() {
+        super.finish();
+        final Intent intent = new Intent(CommandReceiverActivity.ACTION_EXECUTE_COMMAND);
+        intent.putExtra(CommandReceiverActivity.EXTRA_COMMAND, mIsDeviceOwner
+                ? CommandReceiverActivity.COMMAND_DEVICE_OWNER_CLEAR_POLICIES
+                : CommandReceiverActivity.COMMAND_PROFILE_OWNER_CLEAR_POLICIES);
+        startActivity(intent);
+    }
+}
\ No newline at end of file
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/SetSupportMessageActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/SetSupportMessageActivity.java
new file mode 100644
index 0000000..9aa71a8
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/SetSupportMessageActivity.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.verifier.managedprovisioning;
+
+import android.app.Activity;
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.EditText;
+
+import com.android.cts.verifier.R;
+
+public class SetSupportMessageActivity extends Activity implements View.OnClickListener {
+    public static final String ACTION_SET_SUPPORT_MSG =
+            "com.android.cts.verifier.managedprovisioning.action.SET_SUPPORT_MSG";
+    public static final String EXTRA_SUPPORT_MSG_TYPE =
+            "com.android.cts.verifier.managedprovisioning.extra.SUPPORT_MSG_TYPE";
+
+    public static final String TYPE_SHORT_MSG = "short-msg";
+    public static final String TYPE_LONG_MSG = "long-msg";
+
+    private String mType;
+    private EditText mSupportMessage;
+    private DevicePolicyManager mDpm;
+    private ComponentName mAdmin;
+
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.set_support_message);
+        findViewById(R.id.set_default_message).setOnClickListener(this);
+        findViewById(R.id.set_message).setOnClickListener(this);
+        findViewById(R.id.clear_message).setOnClickListener(this);
+        mSupportMessage = (EditText) findViewById(R.id.message_view);
+
+        mType = getIntent().getStringExtra(EXTRA_SUPPORT_MSG_TYPE);
+        setTitle(TYPE_SHORT_MSG.equals(mType)
+                ? R.string.policy_transparency_short_support_msg_label
+                : R.string.policy_transparency_long_support_msg_label);
+        mDpm = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
+        mAdmin = DeviceAdminTestReceiver.getReceiverComponentName();
+
+        mSupportMessage.setText(TYPE_SHORT_MSG.equals(mType)
+                ? mDpm.getShortSupportMessage(mAdmin)
+                : mDpm.getLongSupportMessage(mAdmin));
+    }
+
+    @Override
+    public void onClick(View view) {
+        String message = null;
+        switch (view.getId()) {
+            case R.id.set_default_message: {
+                message = getString(TYPE_SHORT_MSG.equals(mType)
+                        ? R.string.policy_transparency_default_short_msg
+                        : R.string.policy_transparency_default_long_msg);
+            } break;
+            case R.id.set_message: {
+                message = mSupportMessage.getText().toString();
+            } break;
+            case R.id.clear_message: {
+                message = null;
+            } break;
+        }
+        if (TYPE_SHORT_MSG.equals(mType)) {
+            mDpm.setShortSupportMessage(mAdmin, message);
+        } else {
+            mDpm.setLongSupportMessage(mAdmin, message);
+        }
+        mSupportMessage.setText(message);
+    }
+}
\ No newline at end of file
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/UserRestrictions.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/UserRestrictions.java
new file mode 100644
index 0000000..06d0381
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/UserRestrictions.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.verifier.managedprovisioning;
+
+import android.content.Context;
+import android.content.Intent;
+import android.os.UserManager;
+import android.provider.Settings;
+import android.util.ArrayMap;
+
+import java.util.ArrayList;
+
+import com.android.cts.verifier.R;
+
+public class UserRestrictions {
+    private static final String[] RESTRICTION_IDS = new String[] {
+        UserManager.DISALLOW_ADD_USER,
+        UserManager.DISALLOW_ADJUST_VOLUME,
+        UserManager.DISALLOW_APPS_CONTROL,
+        UserManager.DISALLOW_CONFIG_CELL_BROADCASTS,
+        UserManager.DISALLOW_CONFIG_CREDENTIALS,
+        UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS,
+        UserManager.DISALLOW_CONFIG_TETHERING,
+        UserManager.DISALLOW_CONFIG_WIFI,
+        UserManager.DISALLOW_DEBUGGING_FEATURES,
+        UserManager.DISALLOW_FACTORY_RESET,
+        UserManager.DISALLOW_FUN,
+        UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES,
+        UserManager.DISALLOW_MODIFY_ACCOUNTS,
+        UserManager.DISALLOW_NETWORK_RESET,
+        UserManager.DISALLOW_OUTGOING_BEAM,
+        UserManager.DISALLOW_REMOVE_USER,
+        UserManager.DISALLOW_SHARE_LOCATION,
+        UserManager.DISALLOW_UNINSTALL_APPS
+    };
+
+    private static final ArrayMap<String, UserRestrictionItem> USER_RESTRICTION_ITEMS;
+    static {
+        final int[] restrictionLabels = new int[] {
+            R.string.disallow_add_user,
+            R.string.disallow_adjust_volume,
+            R.string.disallow_apps_control,
+            R.string.disallow_config_cell_broadcasts,
+            R.string.disallow_config_credentials,
+            R.string.disallow_config_mobile_networks,
+            R.string.disallow_config_tethering,
+            R.string.disallow_config_wifi,
+            R.string.disallow_debugging_features,
+            R.string.disallow_factory_reset,
+            R.string.disallow_fun,
+            R.string.disallow_install_unknown_sources,
+            R.string.disallow_modify_accounts,
+            R.string.disallow_network_reset,
+            R.string.disallow_outgoing_beam,
+            R.string.disallow_remove_user,
+            R.string.disallow_share_location,
+            R.string.disallow_uninstall_apps
+        };
+
+        final int[] restrictionActions = new int[] {
+            R.string.disallow_add_user_action,
+            R.string.disallow_adjust_volume_action,
+            R.string.disallow_apps_control_action,
+            R.string.disallow_config_cell_broadcasts_action,
+            R.string.disallow_config_credentials_action,
+            R.string.disallow_config_mobile_networks_action,
+            R.string.disallow_config_tethering_action,
+            R.string.disallow_config_wifi_action,
+            R.string.disallow_debugging_features_action,
+            R.string.disallow_factory_reset_action,
+            R.string.disallow_fun_action,
+            R.string.disallow_install_unknown_sources_action,
+            R.string.disallow_modify_accounts_action,
+            R.string.disallow_network_reset_action,
+            R.string.disallow_outgoing_beam_action,
+            R.string.disallow_remove_user_action,
+            R.string.disallow_share_location_action,
+            R.string.disallow_uninstall_apps_action
+        };
+
+        final String[] settingsIntentActions = new String[] {
+            Settings.ACTION_SETTINGS,
+            Settings.ACTION_SOUND_SETTINGS,
+            Settings.ACTION_APPLICATION_SETTINGS,
+            Settings.ACTION_SOUND_SETTINGS,
+            Settings.ACTION_SECURITY_SETTINGS,
+            Settings.ACTION_WIRELESS_SETTINGS,
+            Settings.ACTION_WIRELESS_SETTINGS,
+            Settings.ACTION_WIFI_SETTINGS,
+            Settings.ACTION_DEVICE_INFO_SETTINGS,
+            Settings.ACTION_PRIVACY_SETTINGS,
+            Settings.ACTION_DEVICE_INFO_SETTINGS,
+            Settings.ACTION_SECURITY_SETTINGS,
+            Settings.ACTION_SYNC_SETTINGS,
+            Settings.ACTION_PRIVACY_SETTINGS,
+            Settings.ACTION_WIRELESS_SETTINGS,
+            Settings.ACTION_SETTINGS,
+            Settings.ACTION_LOCATION_SOURCE_SETTINGS,
+            Settings.ACTION_APPLICATION_SETTINGS,
+        };
+
+        if (RESTRICTION_IDS.length != restrictionLabels.length
+                || RESTRICTION_IDS.length != restrictionActions.length
+                || RESTRICTION_IDS.length != settingsIntentActions.length) {
+            throw new AssertionError("Number of items in restrictionIds, restrictionLabels, "
+                    + "restrictionActions, and settingsIntentActions do not match");
+        }
+        USER_RESTRICTION_ITEMS = new ArrayMap<>(RESTRICTION_IDS.length);
+        for (int i = 0; i < RESTRICTION_IDS.length; ++i) {
+            USER_RESTRICTION_ITEMS.put(RESTRICTION_IDS[i], new UserRestrictionItem(
+                    restrictionLabels[i],
+                    restrictionActions[i],
+                    settingsIntentActions[i]));
+        }
+    }
+
+    private static final ArrayList<String> ALSO_VALID_FOR_PO =
+            new ArrayList<String>();
+    static {
+        ALSO_VALID_FOR_PO.add(UserManager.DISALLOW_APPS_CONTROL);
+        ALSO_VALID_FOR_PO.add(UserManager.DISALLOW_UNINSTALL_APPS);
+        ALSO_VALID_FOR_PO.add(UserManager.DISALLOW_MODIFY_ACCOUNTS);
+        ALSO_VALID_FOR_PO.add(UserManager.DISALLOW_SHARE_LOCATION);
+    }
+
+    public static String getRestrictionLabel(Context context, String restriction) {
+        final UserRestrictionItem item = findRestrictionItem(restriction);
+        return context.getString(item.label);
+    }
+
+    public static String getUserAction(Context context, String restriction) {
+        final UserRestrictionItem item = findRestrictionItem(restriction);
+        return context.getString(item.userAction);
+    }
+
+    private static UserRestrictionItem findRestrictionItem(String restriction) {
+        final UserRestrictionItem item = USER_RESTRICTION_ITEMS.get(restriction);
+        if (item == null) {
+            throw new IllegalArgumentException("Unknown restriction: " + restriction);
+        }
+        return item;
+    }
+
+    public static boolean isValidForPO(String restriction) {
+        return ALSO_VALID_FOR_PO.contains(restriction);
+    }
+
+    public static String[] getUserRestrictions() {
+        return RESTRICTION_IDS;
+    }
+
+    public static Intent getUserRestrictionTestIntent(Context context, String restriction) {
+        final UserRestrictionItem item = USER_RESTRICTION_ITEMS.get(restriction);
+        return new Intent(PolicyTransparencyTestActivity.ACTION_SHOW_POLICY_TRANSPARENCY_TEST)
+                .putExtra(PolicyTransparencyTestActivity.EXTRA_TEST,
+                        PolicyTransparencyTestActivity.TEST_CHECK_USER_RESTRICTION)
+                .putExtra(CommandReceiverActivity.EXTRA_USER_RESTRICTION, restriction)
+                .putExtra(PolicyTransparencyTestActivity.EXTRA_TITLE, context.getString(item.label))
+                .putExtra(PolicyTransparencyTestActivity.EXTRA_SETTINGS_INTENT_ACTION,
+                        item.intentAction);
+    }
+
+    private static class UserRestrictionItem {
+        final int label;
+        final int userAction;
+        final String intentAction;
+        public UserRestrictionItem(int label, int userAction, String intentAction) {
+            this.label = label;
+            this.userAction = userAction;
+            this.intentAction = intentAction;
+        }
+    }
+}
\ No newline at end of file
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/Utils.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/Utils.java
new file mode 100644
index 0000000..abccb43
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/Utils.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.verifier.managedprovisioning;
+
+import android.app.Activity;
+import android.widget.Toast;
+import android.content.ActivityNotFoundException;
+import android.content.Context;
+import android.content.Intent;
+import android.util.Log;
+
+import com.android.cts.verifier.IntentDrivenTestActivity;
+import com.android.cts.verifier.IntentDrivenTestActivity.ButtonInfo;
+import com.android.cts.verifier.managedprovisioning.ByodHelperActivity;
+import com.android.cts.verifier.R;
+import com.android.cts.verifier.TestListAdapter.TestListItem;
+
+public class Utils {
+
+    private static final String TAG = "CtsVerifierByodUtils";
+
+    static TestListItem createInteractiveTestItem(Activity activity, String id, int titleRes,
+            int infoRes, ButtonInfo[] buttonInfos) {
+        return TestListItem.newTest(activity, titleRes,
+                id, new Intent(activity, IntentDrivenTestActivity.class)
+                .putExtra(IntentDrivenTestActivity.EXTRA_ID, id)
+                .putExtra(IntentDrivenTestActivity.EXTRA_TITLE, titleRes)
+                .putExtra(IntentDrivenTestActivity.EXTRA_INFO, infoRes)
+                .putExtra(IntentDrivenTestActivity.EXTRA_BUTTONS, buttonInfos),
+                null);
+    }
+
+    static TestListItem createInteractiveTestItem(Activity activity, String id, int titleRes,
+            int infoRes, ButtonInfo buttonInfo) {
+        return createInteractiveTestItem(activity, id, titleRes, infoRes,
+                new ButtonInfo[] { buttonInfo });
+    }
+
+    static void requestDeleteManagedProfile(Context context) {
+        try {
+            Intent intent = new Intent(ByodHelperActivity.ACTION_REMOVE_MANAGED_PROFILE);
+            context.startActivity(intent);
+            String message = context.getString(R.string.provisioning_byod_delete_profile);
+            Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
+        }
+        catch (ActivityNotFoundException e) {
+            Log.d(TAG, "requestDeleteProfileOwner: ActivityNotFoundException", e);
+        }
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/WifiLockdownTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/WifiLockdownTestActivity.java
index 77f36b6..d5e9fd0 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/WifiLockdownTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/WifiLockdownTestActivity.java
@@ -72,21 +72,21 @@
                 new Intent(Settings.ACTION_WIFI_SETTINGS));
         mSwitchLockdownOffButtonInfos = new ButtonInfo[] { new ButtonInfo(
                 R.string.switch_wifi_lockdown_off_button,
-                new Intent(this, DeviceOwnerPositiveTestActivity.CommandReceiver.class)
-                        .putExtra(DeviceOwnerPositiveTestActivity.EXTRA_COMMAND,
-                                DeviceOwnerPositiveTestActivity.COMMAND_SET_GLOBAL_SETTING)
-                        .putExtra(DeviceOwnerPositiveTestActivity.EXTRA_SETTING,
+                new Intent(this, CommandReceiverActivity.class)
+                        .putExtra(CommandReceiverActivity.EXTRA_COMMAND,
+                                CommandReceiverActivity.COMMAND_SET_GLOBAL_SETTING)
+                        .putExtra(CommandReceiverActivity.EXTRA_SETTING,
                                 Settings.Global.WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN)
-                        .putExtra(DeviceOwnerPositiveTestActivity.EXTRA_PARAMETER_1, "0"
+                        .putExtra(CommandReceiverActivity.EXTRA_VALUE, "0"
                 )), goToWifiSettings };
         mSwitchLockdownOnButtonInfos = new ButtonInfo[] { new ButtonInfo(
                 R.string.switch_wifi_lockdown_on_button,
-                new Intent(this, DeviceOwnerPositiveTestActivity.CommandReceiver.class)
-                        .putExtra(DeviceOwnerPositiveTestActivity.EXTRA_COMMAND,
-                                DeviceOwnerPositiveTestActivity.COMMAND_SET_GLOBAL_SETTING)
-                        .putExtra(DeviceOwnerPositiveTestActivity.EXTRA_SETTING,
+                new Intent(this, CommandReceiverActivity.class)
+                        .putExtra(CommandReceiverActivity.EXTRA_COMMAND,
+                                CommandReceiverActivity.COMMAND_SET_GLOBAL_SETTING)
+                        .putExtra(CommandReceiverActivity.EXTRA_SETTING,
                                 Settings.Global.WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN)
-                        .putExtra(DeviceOwnerPositiveTestActivity.EXTRA_PARAMETER_1, "1"
+                        .putExtra(CommandReceiverActivity.EXTRA_VALUE, "1"
                 )), goToWifiSettings };
 
         addTestsToAdapter(adapter);
@@ -132,22 +132,22 @@
     }
 
     private void addTestsToAdapter(final ArrayTestListAdapter adapter) {
-        adapter.add(DeviceOwnerPositiveTestActivity.createInteractiveTestItem(this,
+        adapter.add(Utils.createInteractiveTestItem(this,
                 CONFIG_MODIFIABLE_WHEN_UNLOCKED_TEST_ID,
                 R.string.device_owner_wifi_config_unlocked_modification_test,
                 R.string.device_owner_wifi_config_unlocked_modification_test_info,
                 mSwitchLockdownOffButtonInfos));
-        adapter.add(DeviceOwnerPositiveTestActivity.createInteractiveTestItem(this,
+        adapter.add(Utils.createInteractiveTestItem(this,
                 CONFIG_NOT_MODIFIABLE_WHEN_LOCKED_TEST_ID,
                 R.string.device_owner_wifi_config_locked_modification_test,
                 R.string.device_owner_wifi_config_locked_modification_test_info,
                 mSwitchLockdownOnButtonInfos));
-        adapter.add(DeviceOwnerPositiveTestActivity.createInteractiveTestItem(this,
+        adapter.add(Utils.createInteractiveTestItem(this,
                 CONFIG_CONNECTABLE_WHEN_LOCKED_TEST_ID,
                 R.string.device_owner_wifi_config_locked_connection_test,
                 R.string.device_owner_wifi_config_locked_connection_test_info,
                 mSwitchLockdownOnButtonInfos));
-        adapter.add(DeviceOwnerPositiveTestActivity.createInteractiveTestItem(this,
+        adapter.add(Utils.createInteractiveTestItem(this,
                 CONFIG_REMOVABLE_WHEN_UNLOCKED_TEST_ID,
                 R.string.device_owner_wifi_config_unlocked_removal_test,
                 R.string.device_owner_wifi_config_unlocked_removal_test_info,
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/nfc/NfcTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/NfcTestActivity.java
index 68fc027..eb84d1e 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/nfc/NfcTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/NfcTestActivity.java
@@ -22,6 +22,8 @@
 import com.android.cts.verifier.TestListAdapter.TestListItem;
 import com.android.cts.verifier.nfc.hce.HceEmulatorTestActivity;
 import com.android.cts.verifier.nfc.hce.HceReaderTestActivity;
+import com.android.cts.verifier.nfc.hcef.HceFEmulatorTestActivity;
+import com.android.cts.verifier.nfc.hcef.HceFReaderTestActivity;
 
 import android.content.Intent;
 import android.content.pm.PackageManager;
@@ -82,6 +84,16 @@
                     new Intent(this, HceEmulatorTestActivity.class), null));
         }
 
+        if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION_NFCF)) {
+            adapter.add(TestListItem.newCategory(this, R.string.nfc_hce_f));
+            adapter.add(TestListItem.newTest(this, R.string.nfc_hce_f_reader_tests,
+                    HceFReaderTestActivity.class.getName(),
+                    new Intent(this, HceFReaderTestActivity.class), null));
+            adapter.add(TestListItem.newTest(this, R.string.nfc_hce_f_emulator_tests,
+                    HceFEmulatorTestActivity.class.getName(),
+                    new Intent(this, HceFEmulatorTestActivity.class), null));
+        }
+
         setTestListAdapter(adapter);
     }
 
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/nfc/hcef/HceFEmulatorActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/hcef/HceFEmulatorActivity.java
new file mode 100644
index 0000000..89f040b
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/hcef/HceFEmulatorActivity.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.verifier.nfc.hcef;
+
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.nfc.NfcAdapter;
+import android.nfc.cardemulation.NfcFCardEmulation;
+import android.os.Bundle;
+
+import com.android.cts.verifier.PassFailButtons;
+import com.android.cts.verifier.R;
+
+public class HceFEmulatorActivity extends PassFailButtons.Activity{
+    static String ACTION_TEST_SUCCESS = "success";
+
+    NfcAdapter mAdapter;
+    NfcFCardEmulation mNfcFCardEmulation;
+
+    final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+
+            if (ACTION_TEST_SUCCESS.equals(action)) {
+                getPassButton().setEnabled(true);
+            }
+        }
+    };
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.pass_fail_text);
+        setPassFailButtonClickListeners();
+        getPassButton().setEnabled(false);
+        mAdapter = NfcAdapter.getDefaultAdapter(this);
+        mNfcFCardEmulation = NfcFCardEmulation.getInstance(mAdapter);
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        IntentFilter filter = new IntentFilter(ACTION_TEST_SUCCESS);
+        registerReceiver(mReceiver, filter);
+        ComponentName hceFService = new ComponentName("com.android.cts.verifier",
+                MyHostFelicaService.class.getName());
+        mNfcFCardEmulation.enableNfcFForegroundService(this, hceFService);
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+        unregisterReceiver(mReceiver);
+    }
+
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/nfc/hcef/HceFEmulatorTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/hcef/HceFEmulatorTestActivity.java
new file mode 100644
index 0000000..026bb45
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/hcef/HceFEmulatorTestActivity.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.verifier.nfc.hcef;
+
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.nfc.NfcAdapter;
+import android.nfc.cardemulation.CardEmulation;
+import android.os.Bundle;
+
+import com.android.cts.verifier.ArrayTestListAdapter;
+import com.android.cts.verifier.PassFailButtons;
+import com.android.cts.verifier.R;
+import com.android.cts.verifier.TestListAdapter.TestListItem;
+
+/** Activity that lists all the NFC HCE emulator tests. */
+public class HceFEmulatorTestActivity extends PassFailButtons.TestListActivity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.pass_fail_list);
+        setInfoResources(R.string.nfc_test, R.string.nfc_hce_emulator_test_info, 0);
+        setPassFailButtonClickListeners();
+
+        ArrayTestListAdapter adapter = new ArrayTestListAdapter(this);
+
+        NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
+        CardEmulation cardEmulation = CardEmulation.getInstance(nfcAdapter);
+        if (getPackageManager().hasSystemFeature(
+                PackageManager.FEATURE_NFC_HOST_CARD_EMULATION_NFCF)) {
+            adapter.add(TestListItem.newCategory(this, R.string.nfc_hce_f_emulator_tests));
+
+            adapter.add(TestListItem.newTest(this, R.string.nfc_hce_f_emulator,
+                    HceFEmulatorActivity.class.getName(),
+                    new Intent(this, HceFEmulatorActivity.class), null));
+        }
+
+        setTestListAdapter(adapter);
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/nfc/hcef/HceFReaderActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/hcef/HceFReaderActivity.java
new file mode 100644
index 0000000..ba31ff7
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/hcef/HceFReaderActivity.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.verifier.nfc.hcef;
+
+import android.annotation.TargetApi;
+import android.nfc.NfcAdapter;
+import android.nfc.NfcAdapter.ReaderCallback;
+import android.nfc.Tag;
+import android.nfc.tech.NfcF;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemSelectedListener;
+
+import com.android.cts.verifier.PassFailButtons;
+import com.android.cts.verifier.R;
+
+import java.io.IOException;
+
+@TargetApi(24)
+public class HceFReaderActivity extends PassFailButtons.Activity implements ReaderCallback,
+        OnItemSelectedListener {
+    public static final String TAG = "HceFReaderActivity";
+
+    NfcAdapter mAdapter;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.pass_fail_text);
+        setPassFailButtonClickListeners();
+        getPassButton().setEnabled(false);
+
+        mAdapter = NfcAdapter.getDefaultAdapter(this);
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        mAdapter.enableReaderMode(this, this, NfcAdapter.FLAG_READER_NFC_F |
+                NfcAdapter.FLAG_READER_SKIP_NDEF_CHECK, null);
+    }
+
+    static byte[] createEchoCommand(byte[] nfcid2, byte[] payload) {
+        byte length = (byte) (2 + nfcid2.length + payload.length);
+
+        byte[] echo_cmd = new byte[length];
+        echo_cmd[0] = length;
+        echo_cmd[1] = MyHostFelicaService.CMD_ECHO;
+        System.arraycopy(nfcid2, 0, echo_cmd, 2, nfcid2.length);
+        System.arraycopy(payload, 0, echo_cmd, 2 + nfcid2.length, payload.length);
+        return echo_cmd;
+    }
+
+    static byte[] createSuccessCommand(byte[] nfcid2) {
+        byte[] cmd = new byte[2 + nfcid2.length];
+        cmd[0] = (byte) (2 + nfcid2.length);
+        cmd[1] = MyHostFelicaService.CMD_SUCCESS;
+        System.arraycopy(nfcid2, 0, cmd, 2, nfcid2.length);
+        return cmd;
+    }
+
+    static boolean verifyResponse(byte[] cmd, byte[] resp) {
+        if (resp == null) return false;
+
+        // Verify length
+        if (resp[0] != resp.length) return false;
+        if (resp.length != cmd.length) return false;
+        // Verify cmd
+        if (resp[1] != MyHostFelicaService.RESPONSE_ECHO) return false;
+
+        // Verify rest of data
+        for (int i = 2; i < resp.length; i++) {
+            if (resp[i] != cmd[i]) return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public void onTagDiscovered(Tag tag) {
+        NfcF felica = NfcF.get(tag);
+        if (felica == null) return;
+
+        try {
+            felica.connect();
+            for (int i = 0; i < 32; i++) {
+                byte[] payload = new byte[] {0x14, (byte)i};
+                byte[] echo_cmd = createEchoCommand(MyHostFelicaService.NFCID2, payload);
+                byte[] resp = felica.transceive(echo_cmd);
+                if (!verifyResponse(echo_cmd, resp)) {
+                    Log.e(TAG, "Echo response not correct.");
+                    return;
+                }
+            }
+            // All successful, send success cmd
+            byte[] success_cmd = createSuccessCommand(MyHostFelicaService.NFCID2);
+            felica.transceive(success_cmd);
+
+            runOnUiThread(new Runnable() {
+                @Override
+                public void run() {
+                    getPassButton().setEnabled(true);
+                }
+            });
+        } catch (IOException e) {
+            Log.e(TAG, "IOException, try again.");
+        }
+    }
+
+    @Override
+    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
+
+    }
+
+    @Override
+    public void onNothingSelected(AdapterView<?> parent) {
+
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/nfc/hcef/HceFReaderTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/hcef/HceFReaderTestActivity.java
new file mode 100644
index 0000000..52de01d
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/hcef/HceFReaderTestActivity.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.verifier.nfc.hcef;
+
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+
+import com.android.cts.verifier.ArrayTestListAdapter;
+import com.android.cts.verifier.PassFailButtons;
+import com.android.cts.verifier.R;
+import com.android.cts.verifier.TestListAdapter.TestListItem;
+
+/** Activity that lists all the NFC HCE reader tests. */
+public class HceFReaderTestActivity extends PassFailButtons.TestListActivity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.pass_fail_list);
+        setInfoResources(R.string.nfc_test, R.string.nfc_hce_reader_test_info, 0);
+        setPassFailButtonClickListeners();
+
+        ArrayTestListAdapter adapter = new ArrayTestListAdapter(this);
+
+        if (getPackageManager().hasSystemFeature(
+                PackageManager.FEATURE_NFC_HOST_CARD_EMULATION_NFCF)) {
+            adapter.add(TestListItem.newCategory(this, R.string.nfc_hce_f_reader_tests));
+
+            adapter.add(TestListItem.newTest(this, R.string.nfc_hce_f_reader,
+                    HceFReaderActivity.class.getName(),
+                    new Intent(this, HceFReaderActivity.class), null));
+
+        }
+
+        setTestListAdapter(adapter);
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/nfc/hcef/MyHostFelicaService.java b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/hcef/MyHostFelicaService.java
new file mode 100644
index 0000000..941ea2c
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/hcef/MyHostFelicaService.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.verifier.nfc.hcef;
+
+import android.content.Intent;
+import android.nfc.cardemulation.HostNfcFService;
+import android.os.Bundle;
+import android.util.Log;
+
+import com.android.cts.verifier.nfc.hce.HceUtils;
+
+public class MyHostFelicaService extends HostNfcFService {
+
+    static final String TAG = "MyHostFelicaService";
+    static byte[] NFCID2 = {0x02, (byte) 0xFE, 0x00, 0x00, 0x00, 0x00, 0x14, (byte)0x81};
+
+    static byte CMD_REQUEST_SYSTEM_CODES = 0x0C;
+    static byte RESPONSE_SYSTEM_CODES = 0x0D;
+    static byte CMD_ECHO = (byte) 0xFE;
+    static byte RESPONSE_ECHO = (byte) 0xFF;
+    static byte CMD_SUCCESS = (byte) 0x81;
+
+    static byte[] handleSystemCodeRequest(byte[] sc_request) {
+        // Request system code command
+        byte[] response = new byte[13];
+        response[0] = 0x0D; // length
+        response[1] = RESPONSE_SYSTEM_CODES; // get system codes resp
+        System.arraycopy(sc_request, 2, response, 2, 8);
+        response[10] = 0x01;
+        response[11] = 0x40;
+        response[12] = 0x01;
+        return response;
+    }
+
+    static byte[] handleEchoRequest(byte[] echo_request) {
+        byte[] response = new byte[echo_request.length];
+        response[0] = (byte) echo_request.length;
+        response[1] = RESPONSE_ECHO;
+        for (int i = 2; i < echo_request.length; i++) {
+            // Copy NFCID2 and rest of data
+            response[i] = echo_request[i];
+        }
+        return response;
+
+    }
+
+    @Override
+    public byte[] processNfcFPacket(byte[] bytes, Bundle bundle) {
+        // Verify that NFCID2 matches with this service
+        if (bytes.length < 2 + NFCID2.length) {
+            Log.e(TAG, "Packet not long enough.");
+            return null;
+        }
+        for (int i = 0; i < NFCID2.length; i++) {
+           if (bytes[2 + i] != NFCID2[i]) {
+               Log.e(TAG, "NFCID2 does not match.");
+               return null;
+           }
+        }
+        byte cmd = bytes[1];
+        if (cmd == CMD_REQUEST_SYSTEM_CODES) {
+            return handleSystemCodeRequest(bytes);
+        } else if (cmd == CMD_ECHO) {
+            return handleEchoRequest(bytes);
+        } else if (cmd == CMD_SUCCESS) {
+            // Mark the test a success
+            Intent successIntent = new Intent(HceFEmulatorActivity.ACTION_TEST_SUCCESS);
+            sendBroadcast(successIntent);
+            // And just echo cmd back
+            return bytes;
+        } else {
+            Log.e(TAG, "Invalid command received");
+        }
+
+        return null;
+    }
+
+    @Override
+    public void onDeactivated(int i) {
+
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/notifications/ConditionProviderVerifierActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/notifications/ConditionProviderVerifierActivity.java
new file mode 100644
index 0000000..496414f
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/notifications/ConditionProviderVerifierActivity.java
@@ -0,0 +1,541 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.verifier.notifications;
+
+import com.android.cts.verifier.R;
+
+import android.app.AutomaticZenRule;
+import android.app.NotificationManager;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Parcelable;
+import android.provider.Settings;
+import android.provider.Settings.Secure;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.View;
+import android.view.ViewGroup;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+public class ConditionProviderVerifierActivity extends InteractiveVerifierActivity
+        implements Runnable {
+    protected static final String CP_PACKAGE = "com.android.cts.verifier";
+    protected static final String CP_PATH = CP_PACKAGE +
+            "/com.android.cts.verifier.notifications.MockConditionProvider";
+
+    @Override
+    int getTitleResource() {
+        return R.string.cp_test;
+    }
+
+    @Override
+    int getInstructionsResource() {
+        return R.string.cp_info;
+    }
+
+    // Test Setup
+
+    @Override
+    protected List<InteractiveTestCase> createTestItems() {
+        List<InteractiveTestCase> tests = new ArrayList<>(9);
+        tests.add(new IsEnabledTest());
+        tests.add(new ServiceStartedTest());
+        tests.add(new CreateAutomaticZenRuleTest());
+        tests.add(new GetAutomaticZenRuleTest());
+        tests.add(new GetAutomaticZenRulesTest());
+        tests.add(new SubscribeAutomaticZenRuleTest());
+        tests.add(new DeleteAutomaticZenRuleTest());
+        tests.add(new UnsubscribeAutomaticZenRuleTest());
+        tests.add(new IsDisabledTest());
+        tests.add(new ServiceStoppedTest());
+        return tests;
+    }
+
+    protected class IsEnabledTest extends InteractiveTestCase {
+        @Override
+        View inflate(ViewGroup parent) {
+            return createSettingsItem(parent, R.string.cp_enable_service);
+        }
+
+        @Override
+        boolean autoStart() {
+            return true;
+        }
+
+        @Override
+        void test() {
+            Intent settings = new Intent(Settings.ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS);
+            if (settings.resolveActivity(mPackageManager) == null) {
+                logFail("no settings activity");
+                status = FAIL;
+            } else {
+                String cpPackages = Secure.getString(getContentResolver(),
+                        Settings.Secure.ENABLED_NOTIFICATION_POLICY_ACCESS_PACKAGES);
+                if (cpPackages != null && cpPackages.contains(CP_PACKAGE)) {
+                    status = PASS;
+                } else {
+                    status = WAIT_FOR_USER;
+                }
+                next();
+            }
+        }
+
+        void tearDown() {
+            // wait for the service to start
+            delay();
+        }
+    }
+
+    protected class ServiceStartedTest extends InteractiveTestCase {
+        @Override
+        View inflate(ViewGroup parent) {
+            return createAutoItem(parent, R.string.cp_service_started);
+        }
+
+        @Override
+        void test() {
+            MockConditionProvider.probeConnected(mContext,
+                    new MockConditionProvider.BooleanResultCatcher() {
+                        @Override
+                        public void accept(boolean result) {
+                            if (result) {
+                                status = PASS;
+                            } else {
+                                logFail();
+                                status = RETEST;
+                                delay();
+                            }
+                            next();
+                        }
+                    });
+            delay();  // in case the catcher never returns
+        }
+
+        @Override
+        void tearDown() {
+            MockConditionProvider.resetData(mContext);
+            delay();
+        }
+    }
+
+    private class CreateAutomaticZenRuleTest extends InteractiveTestCase {
+        private String id = null;
+
+        @Override
+        View inflate(ViewGroup parent) {
+            return createAutoItem(parent, R.string.cp_create_rule);
+        }
+
+        @Override
+        void test() {
+            long now = System.currentTimeMillis();
+            AutomaticZenRule ruleToCreate =
+                    createRule("Rule", "value", NotificationManager.INTERRUPTION_FILTER_ALARMS);
+            id = mNm.addAutomaticZenRule(ruleToCreate);
+
+            if (!TextUtils.isEmpty(id)) {
+                status = PASS;
+            } else {
+                logFail();
+                status = FAIL;
+            }
+            next();
+        }
+
+        @Override
+        void tearDown() {
+            if (id != null) {
+                mNm.removeAutomaticZenRule(id);
+            }
+            MockConditionProvider.resetData(mContext);
+            delay();
+        }
+    }
+
+    private class SubscribeAutomaticZenRuleTest extends InteractiveTestCase {
+        private String id = null;
+        private AutomaticZenRule ruleToCreate;
+
+        @Override
+        View inflate(ViewGroup parent) {
+            return createAutoItem(parent, R.string.cp_subscribe_rule);
+        }
+
+        @Override
+        void setUp() {
+            ruleToCreate = createRule("RuleSubscribe", "Subscribevalue",
+                    NotificationManager.INTERRUPTION_FILTER_ALARMS);
+            id = mNm.addAutomaticZenRule(ruleToCreate);
+            status = READY;
+            delay();
+        }
+
+        @Override
+        void test() {
+
+            MockConditionProvider.probeSubscribe(mContext,
+                    new MockConditionProvider.ParcelableListResultCatcher() {
+                        @Override
+                        public void accept(List<Parcelable> result) {
+                            boolean foundMatch = false;
+                            for (Parcelable p : result) {
+                                Uri uri = (Uri) p;
+                                if (ruleToCreate.getConditionId().equals(uri)) {
+                                    foundMatch = true;
+                                    break;
+                                }
+                            }
+                            if (foundMatch) {
+                                status = PASS;
+                            } else {
+                                logFail();
+                                status = RETEST;
+                            }
+                            next();
+                        }
+                    });
+            delay();  // in case the catcher never returns
+        }
+
+        @Override
+        void tearDown() {
+            if (id != null) {
+                mNm.removeAutomaticZenRule(id);
+            }
+            MockConditionProvider.resetData(mContext);
+            // wait for intent to move through the system
+            delay();
+        }
+    }
+
+    private class GetAutomaticZenRuleTest extends InteractiveTestCase {
+        private String id = null;
+        private AutomaticZenRule ruleToCreate;
+
+        @Override
+        View inflate(ViewGroup parent) {
+            return createAutoItem(parent, R.string.cp_get_rule);
+        }
+
+        @Override
+        void setUp() {
+            ruleToCreate = createRule("RuleGet", "valueGet",
+                    NotificationManager.INTERRUPTION_FILTER_ALARMS);
+            id = mNm.addAutomaticZenRule(ruleToCreate);
+            status = READY;
+            delay();
+        }
+
+        @Override
+        void test() {
+            AutomaticZenRule queriedRule = mNm.getAutomaticZenRule(id);
+            if (queriedRule != null
+                    && ruleToCreate.getName().equals(queriedRule.getName())
+                    && ruleToCreate.getOwner().equals(queriedRule.getOwner())
+                    && ruleToCreate.getConditionId().equals(queriedRule.getConditionId())
+                    && ruleToCreate.isEnabled() == queriedRule.isEnabled()) {
+                status = PASS;
+            } else {
+                logFail();
+                status = FAIL;
+            }
+            next();
+        }
+
+        @Override
+        void tearDown() {
+            if (id != null) {
+                mNm.removeAutomaticZenRule(id);
+            }
+            MockConditionProvider.resetData(mContext);
+            delay();
+        }
+    }
+
+    private class GetAutomaticZenRulesTest extends InteractiveTestCase {
+        private List<String> ids = new ArrayList<>();
+        private AutomaticZenRule rule1;
+        private AutomaticZenRule rule2;
+
+        @Override
+        View inflate(ViewGroup parent) {
+            return createAutoItem(parent, R.string.cp_get_rules);
+        }
+
+        @Override
+        void setUp() {
+            rule1 = createRule("Rule1", "value1", NotificationManager.INTERRUPTION_FILTER_ALARMS);
+            rule2 = createRule("Rule2", "value2", NotificationManager.INTERRUPTION_FILTER_NONE);
+            ids.add(mNm.addAutomaticZenRule(rule1));
+            ids.add(mNm.addAutomaticZenRule(rule2));
+            status = READY;
+            delay();
+        }
+
+        @Override
+        void test() {
+            Map<String, AutomaticZenRule> rules = mNm.getAutomaticZenRules();
+
+            if (rules == null || rules.size() != 2) {
+                logFail();
+                status = FAIL;
+                next();
+                return;
+            }
+
+            for (AutomaticZenRule createdRule : rules.values()) {
+                if (!compareRules(createdRule, rule1) && !compareRules(createdRule, rule2)) {
+                    logFail();
+                    status = FAIL;
+                    break;
+                }
+            }
+            status = PASS;
+            next();
+        }
+
+        @Override
+        void tearDown() {
+            for (String id : ids) {
+                mNm.removeAutomaticZenRule(id);
+            }
+            MockConditionProvider.resetData(mContext);
+            delay();
+        }
+    }
+
+    private class DeleteAutomaticZenRuleTest extends InteractiveTestCase {
+        private String id = null;
+
+        @Override
+        View inflate(ViewGroup parent) {
+            return createAutoItem(parent, R.string.cp_delete_rule);
+        }
+
+        @Override
+        void test() {
+            AutomaticZenRule ruleToCreate = createRule("RuleDelete", "Deletevalue",
+                    NotificationManager.INTERRUPTION_FILTER_ALARMS);
+            id = mNm.addAutomaticZenRule(ruleToCreate);
+
+            if (id != null) {
+                if (mNm.removeAutomaticZenRule(id)) {
+                    if (mNm.getAutomaticZenRule(id) == null) {
+                        status = PASS;
+                    } else {
+                        logFail();
+                        status = FAIL;
+                    }
+                } else {
+                    logFail();
+                    status = FAIL;
+                }
+            } else {
+                logFail("Couldn't test rule deletion; creation failed.");
+                status = FAIL;
+            }
+            next();
+        }
+
+        @Override
+        void tearDown() {
+            MockConditionProvider.resetData(mContext);
+            delay();
+        }
+    }
+
+    private class UnsubscribeAutomaticZenRuleTest extends InteractiveTestCase {
+        private String id = null;
+        private AutomaticZenRule ruleToCreate;
+
+        @Override
+        View inflate(ViewGroup parent) {
+            return createAutoItem(parent, R.string.cp_unsubscribe_rule);
+        }
+
+        @Override
+        void setUp() {
+            ruleToCreate = createRule("RuleUnsubscribe", "valueUnsubscribe",
+                    NotificationManager.INTERRUPTION_FILTER_PRIORITY);
+            id = mNm.addAutomaticZenRule(ruleToCreate);
+            status = READY;
+            delay();
+        }
+
+        @Override
+        void test() {
+            MockConditionProvider.probeSubscribe(mContext,
+                    new MockConditionProvider.ParcelableListResultCatcher() {
+                        @Override
+                        public void accept(List<Parcelable> result) {
+                            boolean foundMatch = false;
+                            for (Parcelable p : result) {
+                                Uri uri = (Uri) p;
+                                if (ruleToCreate.getConditionId().equals(uri)) {
+                                    foundMatch = true;
+                                    break;
+                                }
+                            }
+                            if (foundMatch) {
+                                // Now that it's subscribed, remove the rule and verify that it
+                                // unsubscribes.
+                                mNm.removeAutomaticZenRule(id);
+                                MockConditionProvider.probeSubscribe(mContext,
+                                        new MockConditionProvider.ParcelableListResultCatcher() {
+                                            @Override
+                                            public void accept(List<Parcelable> result) {
+                                                boolean foundMatch = false;
+                                                for (Parcelable p : result) {
+                                                    Uri uri = (Uri) p;
+                                                    if (ruleToCreate.getConditionId().equals(uri)) {
+                                                        foundMatch = true;
+                                                        break;
+                                                    }
+                                                }
+                                                if (foundMatch) {
+                                                    logFail();
+                                                    status = RETEST;
+                                                } else {
+                                                    status = PASS;
+                                                }
+                                                next();
+                                            }
+                                        });
+                            } else {
+                                logFail("Couldn't test unsubscribe; subscribe failed.");
+                                status = RETEST;
+                                next();
+                            }
+                        }
+                    });
+            delay();  // in case the catcher never returns
+        }
+
+        @Override
+        void tearDown() {
+            mNm.removeAutomaticZenRule(id);
+            MockConditionProvider.resetData(mContext);
+            // wait for intent to move through the system
+            delay();
+        }
+    }
+
+    private class IsDisabledTest extends InteractiveTestCase {
+        @Override
+        View inflate(ViewGroup parent) {
+            return createSettingsItem(parent, R.string.cp_disable_service);
+        }
+
+        @Override
+        boolean autoStart() {
+            return true;
+        }
+
+        @Override
+        void test() {
+            String cpPackages = Secure.getString(getContentResolver(),
+                    Settings.Secure.ENABLED_NOTIFICATION_POLICY_ACCESS_PACKAGES);
+            if (cpPackages == null || !cpPackages.contains(CP_PACKAGE)) {
+                status = PASS;
+            } else {
+                status = WAIT_FOR_USER;
+            }
+            next();
+        }
+
+        @Override
+        void tearDown() {
+            MockConditionProvider.resetData(mContext);
+            delay();
+        }
+    }
+
+    private class ServiceStoppedTest extends InteractiveTestCase {
+        @Override
+        View inflate(ViewGroup parent) {
+            return createAutoItem(parent, R.string.cp_service_stopped);
+        }
+
+        @Override
+        void test() {
+            MockConditionProvider.probeConnected(mContext,
+                    new MockConditionProvider.BooleanResultCatcher() {
+                        @Override
+                        public void accept(boolean result) {
+                            if (result) {
+                                logFail();
+                                status = RETEST;
+                                delay();
+                            } else {
+                                status = PASS;
+                            }
+                            next();
+                        }
+                    });
+            delay();  // in case the catcher never returns
+        }
+
+        @Override
+        void tearDown() {
+            MockConditionProvider.resetData(mContext);
+            // wait for intent to move through the system
+            delay();
+        }
+    }
+
+    private AutomaticZenRule createRule(String name, String queryValue, int status) {
+        return new AutomaticZenRule(name,
+                ComponentName.unflattenFromString(CP_PATH),
+                MockConditionProvider.toConditionId(queryValue),
+                status,
+                true);
+    }
+
+    private boolean compareRules(AutomaticZenRule rule1, AutomaticZenRule rule2) {
+        return rule1.isEnabled() == rule2.isEnabled()
+                && Objects.equals(rule1.getName(), rule2.getName())
+                && rule1.getInterruptionFilter() == rule2.getInterruptionFilter()
+                && Objects.equals(rule1.getConditionId(), rule2.getConditionId())
+                && Objects.equals(rule1.getOwner(), rule2.getOwner());
+    }
+
+    protected View createSettingsItem(ViewGroup parent, int messageId) {
+        return createUserItem(parent, R.string.cp_start_settings, messageId);
+    }
+
+    public void launchSettings() {
+        startActivity(new Intent(Settings.ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS));
+    }
+
+    public void actionPressed(View v) {
+        Object tag = v.getTag();
+        if (tag instanceof Integer) {
+            int id = ((Integer) tag).intValue();
+            if (id == R.string.cp_start_settings) {
+                launchSettings();
+            } else if (id == R.string.attention_ready) {
+                mCurrentTest.status = READY;
+                next();
+            }
+        }
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/notifications/MockConditionProvider.java b/apps/CtsVerifier/src/com/android/cts/verifier/notifications/MockConditionProvider.java
new file mode 100644
index 0000000..489797b
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/notifications/MockConditionProvider.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.verifier.notifications;
+
+
+import android.app.Activity;
+import android.app.AutomaticZenRule;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Parcelable;
+import android.service.notification.Condition;
+import android.service.notification.ConditionProviderService;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class MockConditionProvider extends ConditionProviderService {
+    static final String TAG = "MockConditionProvider";
+
+    static final String PACKAGE_NAME = "com.android.cts.verifier.notifications";
+    static final String PATH = "mock_cp";
+    static final String QUERY = "query_item";
+
+    static final String SERVICE_BASE = "android.service.notification.cts.MockConditionProvider.";
+    static final String SERVICE_CHECK = SERVICE_BASE + "SERVICE_CHECK";
+    static final String SERVICE_RESET = SERVICE_BASE + "SERVICE_RESET";
+    static final String SERVICE_SUBSCRIBE = SERVICE_BASE + "SERVICE_SUBSCRIBE";
+
+    static final String EXTRA_PAYLOAD = "PAYLOAD";
+    static final String EXTRA_INT = "INT";
+    static final String EXTRA_BOOLEAN = "BOOLEAN";
+    static final String EXTRA_TAG = "TAG";
+    static final String EXTRA_CODE = "CODE";
+
+    static final int RESULT_NO_SERVER = Activity.RESULT_FIRST_USER + 1;
+
+
+    private ArrayList<Uri> mSubscriptions = new ArrayList<>();
+    private boolean mConnected = false;
+    private BroadcastReceiver mReceiver;
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        Log.d(TAG, "created");
+
+        mSubscriptions = new ArrayList<Uri>();
+
+        mReceiver = new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                String action = intent.getAction();
+                if (SERVICE_CHECK.equals(action)) {
+                    Log.d(TAG, "SERVICE_CHECK");
+                    Bundle bundle = new Bundle();
+                    bundle.putBoolean(EXTRA_BOOLEAN, mConnected);
+                    setResultExtras(bundle);
+                    setResultCode(Activity.RESULT_OK);
+                } else if (SERVICE_SUBSCRIBE.equals(action)) {
+                    Log.d(TAG, "SERVICE_SUBSCRIBE");
+                    Bundle bundle = new Bundle();
+                    bundle.putParcelableArrayList(EXTRA_PAYLOAD, mSubscriptions);
+                    setResultExtras(bundle);
+                    setResultCode(Activity.RESULT_OK);
+                } else if (SERVICE_RESET.equals(action)) {
+                    Log.d(TAG, "SERVICE_RESET");
+                    resetData();
+                } else {
+                    Log.w(TAG, "unknown action");
+                    setResultCode(Activity.RESULT_CANCELED);
+                }
+            }
+        };
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(SERVICE_CHECK);
+        filter.addAction(SERVICE_SUBSCRIBE);
+        filter.addAction(SERVICE_RESET);
+        registerReceiver(mReceiver, filter);
+    }
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+        mConnected = false;
+        unregisterReceiver(mReceiver);
+        mReceiver = null;
+        Log.d(TAG, "destroyed");
+    }
+
+    public void resetData() {
+        mSubscriptions.clear();
+    }
+
+    public static void resetData(Context context) {
+        sendCommand(context, SERVICE_RESET, null, 0);
+    }
+
+    public static void probeConnected(Context context, BooleanResultCatcher catcher) {
+        requestConnected(context, SERVICE_CHECK, catcher);
+    }
+
+    public static void probeSubscribe(Context context, ParcelableListResultCatcher catcher) {
+        requestParcelableListResult(context, SERVICE_SUBSCRIBE, catcher);
+    }
+
+    private static void sendCommand(Context context, String action, String tag, int code) {
+        Intent broadcast = new Intent(action);
+        if (tag != null) {
+            broadcast.putExtra(EXTRA_TAG, tag);
+            broadcast.putExtra(EXTRA_CODE, code);
+        }
+        context.sendBroadcast(broadcast);
+    }
+
+    public static Uri toConditionId(String queryValue) {
+        return new Uri.Builder().scheme("scheme")
+                .appendPath(PATH)
+                .appendQueryParameter(QUERY, queryValue)
+                .build();
+    }
+
+    @Override
+    public void onConnected() {
+        Log.d(TAG, "connected");
+        mConnected = true;
+    }
+
+    @Override
+    public void onSubscribe(Uri conditionId) {
+        Log.d(TAG, "subscribed to " + conditionId);
+        mSubscriptions.add(conditionId);
+    }
+
+    @Override
+    public void onUnsubscribe(Uri conditionId) {
+        Log.d(TAG, "unsubscribed from " + conditionId);
+        mSubscriptions.remove(conditionId);
+    }
+
+    public abstract static class BooleanResultCatcher extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            accept(getResultExtras(true).getBoolean(EXTRA_BOOLEAN, false));
+        }
+
+        abstract public void accept(boolean result);
+    }
+
+    private static void requestConnected(Context context, String action,
+            BooleanResultCatcher catcher) {
+        Intent broadcast = new Intent(action);
+        context.sendOrderedBroadcast(broadcast, null, catcher, null, RESULT_NO_SERVER, null, null);
+    }
+
+    public abstract static class ParcelableListResultCatcher extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            accept(getResultExtras(true).getParcelableArrayList(EXTRA_PAYLOAD));
+        }
+
+        abstract public void accept(List<Parcelable> result);
+    }
+
+    private static void requestParcelableListResult(Context context, String action,
+            ParcelableListResultCatcher catcher) {
+        Intent broadcast = new Intent(action);
+        context.sendOrderedBroadcast(broadcast, null, catcher, null, RESULT_NO_SERVER, null, null);
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sample/SampleTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/sample/SampleTestActivity.java
index 41bc303..678aeca 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/sample/SampleTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sample/SampleTestActivity.java
@@ -77,14 +77,15 @@
         double[] metricValues = new double[] {1, 11, 21, 1211, 111221};
 
         // Record metric results
-        getReportLog().setSummary(
-                "Sample Summary", 1.0, ResultType.HIGHER_BETTER, ResultUnit.BYTE);
-        getReportLog().addValues("Sample Values", metricValues, ResultType.NEUTRAL, ResultUnit.FPS);
+        getReportLog().setSummary("Sample Summary", 1.0, ResultType.HIGHER_BETTER,
+                ResultUnit.BYTE);
+        getReportLog().addValues("Sample Values", metricValues, ResultType.NEUTRAL,
+                ResultUnit.FPS);
 
         // Alternatively, activities can invoke TestResult directly to record metrics
         ReportLog reportLog = new PassFailButtons.CtsVerifierReportLog();
         reportLog.setSummary("Sample Summary", 1.0, ResultType.HIGHER_BETTER, ResultUnit.BYTE);
-        getReportLog().addValues("Sample Values", metricValues, ResultType.NEUTRAL, ResultUnit.FPS);
+        reportLog.addValues("Sample Values", metricValues, ResultType.NEUTRAL, ResultUnit.FPS);
         TestResult.setPassedResult(this, "manualSample", "manualDetails", reportLog);
     }
 
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/helpers/SensorTestScreenManipulator.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/helpers/SensorTestScreenManipulator.java
index 2956ed7..b184c4b 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/helpers/SensorTestScreenManipulator.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/helpers/SensorTestScreenManipulator.java
@@ -82,7 +82,7 @@
         mWakeUpScreenWakeLock = powerManager.newWakeLock(levelAndFlags, "SensorTestWakeUpScreen");
         mWakeUpScreenWakeLock.setReferenceCounted(false);
         mKeepScreenOnWakeLock = powerManager.newWakeLock(levelAndFlags, "SensorTestKeepScreenOn");
-        mWakeUpScreenWakeLock.setReferenceCounted(false);
+        mKeepScreenOnWakeLock.setReferenceCounted(false);
     }
 
     /**
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/tv/TvInputDiscoveryTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/tv/TvInputDiscoveryTestActivity.java
index e8e2cee..56c8ac0 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/tv/TvInputDiscoveryTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/tv/TvInputDiscoveryTestActivity.java
@@ -20,6 +20,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.media.tv.TvContract;
+import android.media.tv.TvInputManager;
 import android.os.AsyncTask;
 import android.view.View;
 
@@ -36,6 +37,8 @@
             TvContract.Channels.CONTENT_URI);
     private static final Intent EPG_INTENT = new Intent(Intent.ACTION_VIEW,
             TvContract.Programs.CONTENT_URI);
+    private static final Intent TV_TRIGGER_SETUP_INTENT = new Intent(
+            TvInputManager.ACTION_SETUP_INPUTS);
 
     private static final long TIMEOUT_MS = 5l * 60l * 1000l;  // 5 mins.
 
@@ -47,6 +50,8 @@
     private View mVerifyGlobalSearchItem;
     private View mGoToEpgItem;
     private View mVerifyEpgItem;
+    private View mTriggerSetupItem;
+    private View mVerifyTriggerSetupItem;
     private boolean mTuneVerified;
     private boolean mOverlayViewVerified;
     private boolean mGlobalSearchVerified;
@@ -109,6 +114,13 @@
             setButtonEnabled(mVerifyEpgItem, true);
         } else if (containsButton(mVerifyEpgItem, v)) {
             setPassState(mVerifyEpgItem, true);
+            setButtonEnabled(mTriggerSetupItem, true);
+        } else if (containsButton(mTriggerSetupItem, v)) {
+            startActivity(TV_TRIGGER_SETUP_INTENT);
+            setPassState(mTriggerSetupItem, true);
+            setButtonEnabled(mVerifyTriggerSetupItem, true);
+        } else if (containsButton(mVerifyTriggerSetupItem, v)) {
+            setPassState(mVerifyTriggerSetupItem, true);
             getPassButton().setEnabled(true);
         }
     }
@@ -130,6 +142,10 @@
                 R.string.tv_launch_epg, this);
         mVerifyEpgItem = createUserItem(R.string.tv_input_discover_test_verify_epg,
                 android.R.string.yes, this);
+        mTriggerSetupItem = createUserItem(R.string.tv_input_discover_test_trigger_setup,
+                R.string.tv_launch_setup, this);
+        mVerifyTriggerSetupItem = createUserItem(
+                R.string.tv_input_discover_test_verify_trigger_setup, android.R.string.yes, this);
     }
 
     @Override
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/usb/MtpHostTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/usb/MtpHostTestActivity.java
new file mode 100644
index 0000000..d640e89
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/usb/MtpHostTestActivity.java
@@ -0,0 +1,419 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.verifier.usb;
+
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.hardware.usb.UsbConstants;
+import android.hardware.usb.UsbDevice;
+import android.hardware.usb.UsbDeviceConnection;
+import android.hardware.usb.UsbInterface;
+import android.hardware.usb.UsbManager;
+import android.mtp.MtpConstants;
+import android.mtp.MtpDevice;
+import android.mtp.MtpEvent;
+import android.mtp.MtpObjectInfo;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.os.ParcelFileDescriptor;
+import android.os.SystemClock;
+import android.util.MutableInt;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.android.cts.verifier.PassFailButtons;
+import com.android.cts.verifier.R;
+
+import junit.framework.AssertionFailedError;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import static junit.framework.Assert.*;
+
+public class MtpHostTestActivity extends PassFailButtons.Activity implements Handler.Callback {
+    private static final int MESSAGE_PASS = 0;
+    private static final int MESSAGE_FAIL = 1;
+    private static final int MESSAGE_RUN = 2;
+
+    private static final int ITEM_STATE_PASS = 0;
+    private static final int ITEM_STATE_FAIL = 1;
+    private static final int ITEM_STATE_INDETERMINATE = 2;
+
+    /**
+     * Subclass for PTP.
+     */
+    private static final int SUBCLASS_STILL_IMAGE_CAPTURE = 1;
+
+    /**
+     * Subclass for Android style MTP.
+     */
+    private static final int SUBCLASS_MTP = 0xff;
+
+    /**
+     * Protocol for Picture Transfer Protocol (PIMA 15470).
+     */
+    private static final int PROTOCOL_PICTURE_TRANSFER = 1;
+
+    /**
+     * Protocol for Android style MTP.
+     */
+    private static final int PROTOCOL_MTP = 0;
+
+    private static final int RETRY_DELAY_MS = 1000;
+
+    private static final String ACTION_PERMISSION_GRANTED =
+            "com.android.cts.verifier.usb.ACTION_PERMISSION_GRANTED";
+
+    private static final String TEST_FILE_NAME = "CtsVerifierTest_testfile.txt";
+    private static final byte[] TEST_FILE_CONTENTS =
+            "This is a test file created by CTS verifier test.".getBytes(StandardCharsets.US_ASCII);
+
+    private final Handler mHandler = new Handler(this);
+    private int mStep;
+    private final ArrayList<TestItem> mItems = new ArrayList<>();
+
+    private UsbManager mUsbManager;
+    private BroadcastReceiver mReceiver;
+    private UsbDevice mUsbDevice;
+    private MtpDevice mMtpDevice;
+    private ExecutorService mExecutor;
+    private TextView mErrorText;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.mtp_host_activity);
+        setInfoResources(R.string.mtp_host_test, R.string.mtp_host_test_info, -1);
+        setPassFailButtonClickListeners();
+
+        final LayoutInflater inflater = getLayoutInflater();
+        final LinearLayout itemsView = (LinearLayout) findViewById(R.id.mtp_host_list);
+
+        mErrorText = (TextView) findViewById(R.id.error_text);
+
+        // Don't allow a test pass until all steps are passed.
+        getPassButton().setEnabled(false);
+
+        // Build test items.
+        mItems.add(new TestItem(
+                inflater,
+                R.string.mtp_host_device_lookup_message,
+                new int[] { R.id.next_item_button }));
+        mItems.add(new TestItem(
+                inflater,
+                R.string.mtp_host_grant_permission_message,
+                null));
+        mItems.add(new TestItem(
+                inflater,
+                R.string.mtp_host_test_read_event_message,
+                null));
+        mItems.add(new TestItem(
+                inflater,
+                R.string.mtp_host_test_send_object_message,
+                null));
+        mItems.add(new TestItem(
+                inflater,
+                R.string.mtp_host_test_notification_message,
+                new int[] { R.id.pass_item_button, R.id.fail_item_button }));
+        for (final TestItem item : mItems) {
+            itemsView.addView(item.view);
+        }
+
+        mExecutor = Executors.newSingleThreadExecutor();
+        mUsbManager = getSystemService(UsbManager.class);
+
+        mStep = 0;
+        mHandler.sendEmptyMessage(MESSAGE_RUN);
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+        if (mReceiver != null) {
+            unregisterReceiver(mReceiver);
+            mReceiver = null;
+        }
+    }
+
+    @Override
+    public boolean handleMessage(Message msg) {
+        final TestItem item = mStep < mItems.size() ? mItems.get(mStep) : null;
+
+        switch (msg.what) {
+            case MESSAGE_RUN:
+                if (item == null) {
+                    getPassButton().setEnabled(true);
+                    return true;
+                }
+                item.setEnabled(true);
+                mExecutor.execute(new Runnable() {
+                    private final int mCurrentStep = mStep;
+
+                    @Override
+                    public void run() {
+                        try {
+                            int i = mCurrentStep;
+                            if (i-- == 0) stepFindMtpDevice();
+                            if (i-- == 0) stepGrantPermission();
+                            if (i-- == 0) stepTestReadEvent();
+                            if (i-- == 0) stepTestSendObject();
+                            if (i-- == 0) stepTestNotification();
+                            mHandler.sendEmptyMessage(MESSAGE_PASS);
+                        } catch (Exception | AssertionFailedError exception) {
+                            mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_FAIL, exception));
+                        }
+                    }
+                });
+                break;
+
+            case MESSAGE_PASS:
+                item.setState(ITEM_STATE_PASS);
+                item.setEnabled(false);
+                mStep++;
+                mHandler.sendEmptyMessage(MESSAGE_RUN);
+                break;
+
+            case MESSAGE_FAIL:
+                item.setState(ITEM_STATE_FAIL);
+                item.setEnabled(false);
+                final StringWriter writer = new StringWriter();
+                final Throwable throwable = (Throwable) msg.obj;
+                throwable.printStackTrace(new PrintWriter(writer));
+                mErrorText.setText(writer.toString());
+                break;
+        }
+
+        return true;
+    }
+
+    private void stepFindMtpDevice() throws InterruptedException {
+        assertEquals(R.id.next_item_button, waitForButtonClick());
+
+        UsbDevice device = null;
+        for (final UsbDevice candidate : mUsbManager.getDeviceList().values()) {
+            if (isMtpDevice(candidate)) {
+                device = candidate;
+                break;
+            }
+        }
+        assertNotNull(device);
+        mUsbDevice = device;
+    }
+
+    private void stepGrantPermission() throws InterruptedException {
+        if (!mUsbManager.hasPermission(mUsbDevice)) {
+            final CountDownLatch latch = new CountDownLatch(1);
+            mReceiver = new BroadcastReceiver() {
+                @Override
+                public void onReceive(Context context, Intent intent) {
+                    unregisterReceiver(this);
+                    mReceiver = null;
+                    latch.countDown();
+                }
+            };
+            registerReceiver(mReceiver, new IntentFilter(ACTION_PERMISSION_GRANTED));
+            mUsbManager.requestPermission(
+                    mUsbDevice,
+                    PendingIntent.getBroadcast(
+                            MtpHostTestActivity.this, 0, new Intent(ACTION_PERMISSION_GRANTED), 0));
+
+            latch.await();
+            assertTrue(mUsbManager.hasPermission(mUsbDevice));
+        }
+
+        final UsbDeviceConnection connection = mUsbManager.openDevice(mUsbDevice);
+        assertNotNull(connection);
+
+        // Try to rob device ownership from other applications.
+        for (int i = 0; i < mUsbDevice.getInterfaceCount(); i++) {
+            connection.claimInterface(mUsbDevice.getInterface(i), true);
+            connection.releaseInterface(mUsbDevice.getInterface(i));
+        }
+        mMtpDevice = new MtpDevice(mUsbDevice);
+        assertTrue(mMtpDevice.open(connection));
+        assertTrue(mMtpDevice.getStorageIds().length > 0);
+    }
+
+    private void stepTestReadEvent() {
+        final int[] eventsSupported = mMtpDevice.getDeviceInfo().getEventsSupported();
+        assertTrue(contains(eventsSupported, MtpConstants.EVENT_OBJECT_ADDED));
+
+        while (true) {
+            final MtpEvent event = mMtpDevice.readEvent(null);
+            if (event.getEventCode() == MtpConstants.EVENT_OBJECT_ADDED) {
+                break;
+            }
+            SystemClock.sleep(RETRY_DELAY_MS);
+        }
+    }
+
+    private void stepTestSendObject() throws IOException {
+        final int[] operationsSupported = mMtpDevice.getDeviceInfo().getOperationsSupported();
+        assertTrue(contains(operationsSupported, MtpConstants.OPERATION_SEND_OBJECT_INFO));
+        assertTrue(contains(operationsSupported, MtpConstants.OPERATION_SEND_OBJECT));
+
+        // Delete an existing test file that may be created by the test previously.
+        final int storageId = mMtpDevice.getStorageIds()[0];
+        for (final int objectHandle : mMtpDevice.getObjectHandles(
+                storageId, /* all format */ 0, /* Just under the root */ -1)) {
+            final MtpObjectInfo info = mMtpDevice.getObjectInfo(objectHandle);
+            if (TEST_FILE_NAME.equals(info.getName())) {
+                assertTrue(mMtpDevice.deleteObject(objectHandle));
+            }
+        }
+
+        final MtpObjectInfo info = new MtpObjectInfo.Builder()
+                .setStorageId(storageId)
+                .setName(TEST_FILE_NAME)
+                .setCompressedSize(TEST_FILE_CONTENTS.length)
+                .setFormat(MtpConstants.FORMAT_TEXT)
+                .setParent(-1)
+                .build();
+        final MtpObjectInfo newInfo = mMtpDevice.sendObjectInfo(info);
+        assertNotNull(newInfo);
+        assertTrue(newInfo.getObjectHandle() != -1);
+
+        final ParcelFileDescriptor[] pipes = ParcelFileDescriptor.createPipe();
+        try {
+            try (final ParcelFileDescriptor.AutoCloseOutputStream stream =
+                    new ParcelFileDescriptor.AutoCloseOutputStream(pipes[1])) {
+                stream.write(TEST_FILE_CONTENTS);
+            }
+            assertTrue(mMtpDevice.sendObject(
+                    newInfo.getObjectHandle(),
+                    newInfo.getCompressedSizeLong(),
+                    pipes[0]));
+        } finally {
+            pipes[0].close();
+        }
+    }
+
+    private void stepTestNotification() throws InterruptedException {
+        assertEquals(R.id.pass_item_button, waitForButtonClick());
+    }
+
+    private int waitForButtonClick() throws InterruptedException {
+        final CountDownLatch latch = new CountDownLatch(1);
+        final MutableInt result = new MutableInt(-1);
+        mItems.get(mStep).setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                result.value = v.getId();
+                latch.countDown();
+            }
+        });
+        latch.await();
+        return result.value;
+    }
+
+    private static boolean isMtpDevice(UsbDevice device) {
+        for (int i = 0; i < device.getInterfaceCount(); i++) {
+            final UsbInterface usbInterface = device.getInterface(i);
+            if ((usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_STILL_IMAGE &&
+                    usbInterface.getInterfaceSubclass() == SUBCLASS_STILL_IMAGE_CAPTURE &&
+                    usbInterface.getInterfaceProtocol() == PROTOCOL_PICTURE_TRANSFER)) {
+                return true;
+            }
+            if (usbInterface.getInterfaceClass() == UsbConstants.USB_SUBCLASS_VENDOR_SPEC &&
+                    usbInterface.getInterfaceSubclass() == SUBCLASS_MTP &&
+                    usbInterface.getInterfaceProtocol() == PROTOCOL_MTP &&
+                    "MTP".equals(usbInterface.getName())) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private static boolean contains(int[] set, int value) {
+        for (final int n : set) {
+            if (n == value) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private static class TestItem {
+        private final View view;
+        private final int[] buttons;
+
+        TestItem(LayoutInflater inflater,
+                 int messageText,
+                 int[] buttons) {
+            this.view = inflater.inflate(R.layout.mtp_host_item, null, false);
+
+            final TextView textView = (TextView) view.findViewById(R.id.instructions);
+            textView.setText(messageText);
+
+            this.buttons = buttons != null ? buttons : new int[0];
+            for (final int id : this.buttons) {
+                final Button button = (Button) view.findViewById(id);
+                button.setVisibility(View.VISIBLE);
+                button.setEnabled(false);
+            }
+        }
+
+        void setOnClickListener(OnClickListener listener) {
+            for (final int id : buttons) {
+                final Button button = (Button) view.findViewById(id);
+                button.setOnClickListener(listener);
+            }
+        }
+
+        void setEnabled(boolean value) {
+            for (final int id : buttons) {
+                final Button button = (Button) view.findViewById(id);
+                button.setEnabled(value);
+            }
+        }
+
+        Button getButton(int id) {
+            return (Button) view.findViewById(id);
+        }
+
+        void setState(int state) {
+            final ImageView imageView = (ImageView) view.findViewById(R.id.status);
+            switch (state) {
+                case ITEM_STATE_PASS:
+                    imageView.setImageResource(R.drawable.fs_good);
+                    break;
+                case ITEM_STATE_FAIL:
+                    imageView.setImageResource(R.drawable.fs_error);
+                    break;
+                case ITEM_STATE_INDETERMINATE:
+                    imageView.setImageResource(R.drawable.fs_indeterminate);
+                    break;
+            }
+        }
+    }
+}
diff --git a/apps/PermissionApp/Android.mk b/apps/PermissionApp/Android.mk
index 57950da..50b1759 100644
--- a/apps/PermissionApp/Android.mk
+++ b/apps/PermissionApp/Android.mk
@@ -28,4 +28,7 @@
 
 LOCAL_SDK_VERSION := current
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_CTS_PACKAGE)
diff --git a/build/compatibility_test_suite.mk b/build/compatibility_test_suite.mk
new file mode 100644
index 0000000..f109185
--- /dev/null
+++ b/build/compatibility_test_suite.mk
@@ -0,0 +1,53 @@
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# Builds a compatibility test suite.
+#
+
+# Generate the SuiteInfo.java
+suite_info_java := $(call intermediates-dir-for,JAVA_LIBRARIES,$(LOCAL_MODULE),true,COMMON)/com/android/compatibility/SuiteInfo.java
+$(suite_info_java): PRIVATE_SUITE_BUILD_NUMBER := $(LOCAL_SUITE_BUILD_NUMBER)
+$(suite_info_java): PRIVATE_SUITE_TARGET_ARCH := $(LOCAL_SUITE_TARGET_ARCH)
+$(suite_info_java): PRIVATE_SUITE_NAME := $(LOCAL_SUITE_NAME)
+$(suite_info_java): PRIVATE_SUITE_FULLNAME := $(LOCAL_SUITE_FULLNAME)
+$(suite_info_java): PRIVATE_SUITE_VERSION := $(LOCAL_SUITE_VERSION)
+$(suite_info_java): cts/build/compatibility_test_suite.mk $(LOCAL_MODULE_MAKEFILE)
+	@echo Generating: $@
+	$(hide) mkdir -p $(dir $@)
+	$(hide) echo "/* This file is auto generated by Android.mk.  Do not modify. */" > $@
+	$(hide) echo "package com.android.compatibility;" >> $@
+	$(hide) echo "public class SuiteInfo {" >> $@
+	$(hide) echo "    public static final String BUILD_NUMBER = \"$(PRIVATE_SUITE_BUILD_NUMBER)\";" >> $@
+	$(hide) echo "    public static final String TARGET_ARCH = \"$(PRIVATE_SUITE_TARGET_ARCH)\";" >> $@
+	$(hide) echo "    public static final String NAME = \"$(PRIVATE_SUITE_NAME)\";" >> $@
+	$(hide) echo "    public static final String FULLNAME = \"$(PRIVATE_SUITE_FULLNAME)\";" >> $@
+	$(hide) echo "    public static final String VERSION = \"$(PRIVATE_SUITE_VERSION)\";" >> $@
+	$(hide) echo "}" >> $@
+
+# Reset variables
+LOCAL_SUITE_BUILD_NUMBER :=
+LOCAL_SUITE_NAME :=
+LOCAL_SUITE_FULLNAME :=
+LOCAL_SUITE_VERSION :=
+
+# Include the SuiteInfo.java
+LOCAL_GENERATED_SOURCES := $(suite_info_java)
+
+# Add the base libraries
+LOCAL_JAVA_LIBRARIES += tradefed-prebuilt hosttestlib compatibility-host-util
+
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/build/config.mk b/build/config.mk
index 56d4ae6..306c5fd 100644
--- a/build/config.mk
+++ b/build/config.mk
@@ -14,7 +14,9 @@
 
 # Test XMLs, native executables, and packages will be placed in this
 # directory before creating the final CTS distribution.
-CTS_TESTCASES_OUT := $(HOST_OUT)/cts/android-cts/repository/testcases
+CTS_TESTCASES_OUT := $(HOST_OUT)/old-cts/old-android-cts/repository/testcases
+
+COMPATIBILITY_TESTCASES_OUT_cts := $(HOST_OUT)/cts/android-cts/testcases
 
 # Scanners of source files for tests which are then inputed into
 # the XML generator to produce test XMLs.
@@ -38,12 +40,12 @@
 CTS_MODULE_TEST_CONFIG := AndroidTest.xml
 
 # CTS build rules
+BUILD_COMPATIBILITY_SUITE := cts/build/compatibility_test_suite.mk
 BUILD_CTS_EXECUTABLE := cts/build/test_executable.mk
 BUILD_CTS_PACKAGE := cts/build/test_package.mk
 BUILD_CTS_GTEST_PACKAGE := cts/build/test_gtest_package.mk
 BUILD_CTS_HOST_JAVA_LIBRARY := cts/build/test_host_java_library.mk
 BUILD_CTS_TARGET_JAVA_LIBRARY := cts/build/test_target_java_library.mk
-BUILD_CTS_UI_JAVA_LIBRARY := cts/build/test_uiautomator.mk
 BUILD_CTS_DEQP_PACKAGE := cts/build/test_deqp_package.mk
 BUILD_CTS_SUPPORT_PACKAGE := cts/build/support_package.mk
 BUILD_CTS_MODULE_TEST_CONFIG := cts/build/module_test_config.mk
diff --git a/build/device_info_package.mk b/build/device_info_package.mk
index 5e048b3..b91c264 100644
--- a/build/device_info_package.mk
+++ b/build/device_info_package.mk
@@ -17,15 +17,35 @@
 #
 
 DEVICE_INFO_PACKAGE := com.android.compatibility.common.deviceinfo
-DEVICE_INFO_INSTRUMENT := com.android.compatibility.common.deviceinfo.DeviceInfoInstrument
+DEVICE_INFO_INSTRUMENT := android.support.test.runner.AndroidJUnitRunner
 DEVICE_INFO_PERMISSIONS += android.permission.WRITE_EXTERNAL_STORAGE
 DEVICE_INFO_ACTIVITIES += \
-  $(DEVICE_INFO_PACKAGE).CameraDeviceInfo \
+  $(DEVICE_INFO_PACKAGE).ConfigurationDeviceInfo \
+  $(DEVICE_INFO_PACKAGE).CpuDeviceInfo \
+  $(DEVICE_INFO_PACKAGE).FeatureDeviceInfo \
   $(DEVICE_INFO_PACKAGE).GenericDeviceInfo \
-  $(DEVICE_INFO_PACKAGE).PackageDeviceInfo
+  $(DEVICE_INFO_PACKAGE).GlesStubActivity \
+  $(DEVICE_INFO_PACKAGE).GraphicsDeviceInfo \
+  $(DEVICE_INFO_PACKAGE).LibraryDeviceInfo \
+  $(DEVICE_INFO_PACKAGE).LocaleDeviceInfo \
+  $(DEVICE_INFO_PACKAGE).MediaDeviceInfo \
+  $(DEVICE_INFO_PACKAGE).MemoryDeviceInfo \
+  $(DEVICE_INFO_PACKAGE).PackageDeviceInfo \
+  $(DEVICE_INFO_PACKAGE).PropertyDeviceInfo \
+  $(DEVICE_INFO_PACKAGE).ScreenDeviceInfo \
+  $(DEVICE_INFO_PACKAGE).StorageDeviceInfo \
+  $(DEVICE_INFO_PACKAGE).UserDeviceInfo
+
+ifeq ($(DEVICE_INFO_MIN_SDK),)
+DEVICE_INFO_MIN_SDK := 8
+endif
+
+ifeq ($(DEVICE_INFO_TARGET_SDK),)
+DEVICE_INFO_TARGET_SDK := 8
+endif
 
 # Add the base device info
-LOCAL_STATIC_JAVA_LIBRARIES += compatibility-device-info
+LOCAL_STATIC_JAVA_LIBRARIES += compatibility-device-info compatibility-device-util
 
 # Generator of APK manifests.
 MANIFEST_GENERATOR_JAR := $(HOST_OUT_JAVA_LIBRARIES)/compatibility-manifest-generator.jar
@@ -37,6 +57,8 @@
 $(manifest_xml): PRIVATE_INFO_ACTIVITIES := $(foreach activity,$(DEVICE_INFO_ACTIVITIES),-a $(activity))
 $(manifest_xml): PRIVATE_PACKAGE := $(DEVICE_INFO_PACKAGE)
 $(manifest_xml): PRIVATE_INSTRUMENT := $(DEVICE_INFO_INSTRUMENT)
+$(manifest_xml): PRIVATE_MIN_SDK := $(DEVICE_INFO_MIN_SDK)
+$(manifest_xml): PRIVATE_TARGET_SDK := $(DEVICE_INFO_TARGET_SDK)
 
 # Regenerate manifest.xml if the generator jar, */cts-device-info/Android.mk, or this file is changed.
 $(manifest_xml): $(MANIFEST_GENERATOR_JAR) $(LOCAL_PATH)/Android.mk cts/build/device_info_package.mk
@@ -47,9 +69,13 @@
 						$(PRIVATE_INFO_ACTIVITIES) \
 						-p $(PRIVATE_PACKAGE) \
 						-i $(PRIVATE_INSTRUMENT) \
+						-s $(PRIVATE_MIN_SDK) \
+						-t $(PRIVATE_TARGET_SDK) \
 						-o $@
 
 # Reset variables
+DEVICE_INFO_MIN_SDK :=
+DEVICE_INFO_TARGET_SDK :=
 DEVICE_INFO_PACKAGE :=
 DEVICE_INFO_INSTRUMENT :=
 DEVICE_INFO_PERMISSIONS :=
diff --git a/build/module_test_config.mk b/build/module_test_config.mk
index 6584ef2..fec4893 100644
--- a/build/module_test_config.mk
+++ b/build/module_test_config.mk
@@ -12,10 +12,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-cts_module_test_config := $(if $(wildcard \
-	$(LOCAL_PATH)/$(CTS_MODULE_TEST_CONFIG)), \
-	$(CTS_TESTCASES_OUT)/$(LOCAL_MODULE).config)
-ifneq ($(cts_module_test_config),)
-$(cts_module_test_config): $(LOCAL_PATH)/$(CTS_MODULE_TEST_CONFIG) | $(ACP)
+ifneq ($(LOCAL_CTS_MODULE_CONFIG),)
+cts_module_test_config := $(CTS_TESTCASES_OUT)/$(LOCAL_MODULE).config
+$(cts_module_test_config): $(LOCAL_CTS_MODULE_CONFIG) | $(ACP)
 	$(call copy-file-to-target)
 endif
+# clear var
+LOCAL_CTS_MODULE_CONFIG :=
diff --git a/build/test_deqp_package.mk b/build/test_deqp_package.mk
index 650875c..f98f342 100644
--- a/build/test_deqp_package.mk
+++ b/build/test_deqp_package.mk
@@ -18,24 +18,24 @@
 
 CTS_DEQP_CONFIG_PATH := $(call my-dir)
 
-cts_library_xmls:=$(foreach xml_file, $(call find-files-in-subdirs, external/deqp/android/cts/master, 'com.drawelements.deqp.$(DEQP_API).*xml', .), $(CTS_TESTCASES_OUT)/$(xml_file))
-$(cts_library_xmls) : PRIVATE_API := $(DEQP_API)
-$(cts_library_xmls) : PRIVATE_TEST_NAME := $(DEQP_TEST_NAME)
-$(cts_library_xmls) : PRIVATE_TEST_PACKAGE := com.drawelements.deqp.$(DEQP_API)
-$(cts_library_xmls) : PRIVATE_DUMMY_CASELIST := $(CTS_DEQP_CONFIG_PATH)/deqp_dummy_test_list
-$(cts_library_xmls) : $(CTS_TESTCASES_OUT)/%.xml: external/deqp/android/cts/master/%.xml $(CTS_EXPECTATIONS) $(CTS_UNSUPPORTED_ABIS) $(CTS_XML_GENERATOR)
-	$(hide) echo Generating test description $@
+cts_library_xml := $(CTS_TESTCASES_OUT)/com.drawelements.deqp.$(DEQP_API).xml
+$(cts_library_xml): MUSTPASS_XML_FILE := external/deqp/android/cts/master/com.drawelements.deqp.$(DEQP_API).xml
+$(cts_library_xml): PRIVATE_TEST_NAME := $(DEQP_TEST_NAME)
+$(cts_library_xml): PRIVATE_TEST_PACKAGE := com.drawelements.deqp.$(DEQP_API)
+$(cts_library_xml): PRIVATE_DUMMY_CASELIST := $(CTS_DEQP_CONFIG_PATH)/deqp_dummy_test_list
+$(cts_library_xml): external/deqp/android/cts/master/com.drawelements.deqp.$(DEQP_API).xml external/deqp/android/cts/mnc/$(DEQP_API)-master.txt $(CTS_EXPECTATIONS) $(CTS_UNSUPPORTED_ABIS) $(CTS_XML_GENERATOR)
+	$(hide) echo Generating test description for $(PRIVATE_TEST_NAME)
 	$(hide) mkdir -p $(CTS_TESTCASES_OUT)
-# Query build ABIs by routing a dummy test list through xml generator and parse result
-	$(hide) $(eval supported_abi_attr := $(shell $(CTS_XML_GENERATOR) -t dummyTest \
-										-n dummyName \
-										-p invalid.dummy \
-										-e $(CTS_EXPECTATIONS) \
-										-b $(CTS_UNSUPPORTED_ABIS) \
-										-a $(CTS_TARGET_ARCH) \
-										< $(PRIVATE_DUMMY_CASELIST) \
-										| grep --only-matching -e " abis=\"[^\"]*\""))
-# Patch xml caselist with supported abi
-	$(hide) $(SED_EXTENDED) -e 's:^(\s*)<Test ((.[^/]|[^/])*)(/?)>$$:\1<Test \2 $(supported_abi_attr)\4>:' \
-				< $< \
+
+# Query build ABIs by routing a dummy test list through xml generator and parse result. Use sed to insert the ABI string into the XML files.
+	$(hide) SUPPORTED_ABI_ATTR=`$(CTS_XML_GENERATOR) -t dummyTest \
+									-n dummyName \
+									-p invalid.dummy \
+									-e $(CTS_EXPECTATIONS) \
+									-b $(CTS_UNSUPPORTED_ABIS) \
+									-a $(CTS_TARGET_ARCH) \
+									< $(PRIVATE_DUMMY_CASELIST) \
+									| grep --only-matching -e " abis=\"[^\"]*\""` && \
+			$(SED_EXTENDED) -e "s:^(\s*)<Test ((.[^/]|[^/])*)(/?)>$$:\1<Test \2 $${SUPPORTED_ABI_ATTR}\4>:" \
+				< $(MUSTPASS_XML_FILE) \
 				> $@
diff --git a/build/test_host_java_library.mk b/build/test_host_java_library.mk
index b4c7e63..7fdefb5 100644
--- a/build/test_host_java_library.mk
+++ b/build/test_host_java_library.mk
@@ -29,11 +29,6 @@
 cts_src_dirs := $(addprefix -s , $(cts_src_dirs))
 
 cts_library_xml := $(CTS_TESTCASES_OUT)/$(LOCAL_MODULE).xml
-ifeq ($(cts_runtime_hint),)
-$(cts_library_xml): PRIVATE_CTS_RUNTIME_HINT := "0"
-else
-$(cts_library_xml): PRIVATE_CTS_RUNTIME_HINT := $(cts_runtime_hint)
-endif
 $(cts_library_xml): PRIVATE_SRC_DIRS := $(cts_src_dirs)
 $(cts_library_xml): PRIVATE_TEST_PACKAGE := $(LOCAL_CTS_TEST_PACKAGE)
 $(cts_library_xml): PRIVATE_LIBRARY := $(LOCAL_MODULE)
@@ -49,7 +44,6 @@
 						-j $(PRIVATE_JAR_PATH) \
 						-n $(PRIVATE_LIBRARY) \
 						-p $(PRIVATE_TEST_PACKAGE) \
-						-x "runtimeHint->$(PRIVATE_CTS_RUNTIME_HINT)" \
 						-e $(CTS_EXPECTATIONS) \
 						-b $(CTS_UNSUPPORTED_ABIS) \
 						-a $(CTS_TARGET_ARCH) \
diff --git a/build/test_package.mk b/build/test_package.mk
index 13e582e..c6b0865 100644
--- a/build/test_package.mk
+++ b/build/test_package.mk
@@ -39,11 +39,6 @@
 else
 PRIVATE_CTS_TEST_PACKAGE_NAME_ := android.$(notdir $(LOCAL_PATH))
 endif
-ifeq ($(cts_runtime_hint),)
-$(cts_package_xml): PRIVATE_CTS_RUNTIME_HINT := "0"
-else
-$(cts_package_xml): PRIVATE_CTS_RUNTIME_HINT := $(cts_runtime_hint)
-endif
 $(cts_package_xml): PRIVATE_TEST_PACKAGE := $(PRIVATE_CTS_TEST_PACKAGE_NAME_)
 $(cts_package_xml): PRIVATE_MANIFEST := $(LOCAL_PATH)/AndroidManifest.xml
 $(cts_package_xml): PRIVATE_TEST_TYPE := $(if $(LOCAL_CTS_TEST_RUNNER),$(LOCAL_CTS_TEST_RUNNER),'')
@@ -61,13 +56,9 @@
 						-i "$(PRIVATE_INSTRUMENTATION)" \
 						-n $(PRIVATE_PACKAGE) \
 						-p $(PRIVATE_TEST_PACKAGE) \
-						-x "runtimeHint->$(PRIVATE_CTS_RUNTIME_HINT)" \
 						-e $(CTS_EXPECTATIONS) \
 						-b $(CTS_UNSUPPORTED_ABIS) \
 						-a $(CTS_TARGET_ARCH) \
 						-o $@
 # Have the module name depend on the cts files; so the cts files get generated when you run mm/mmm/mma/mmma.
 $(my_register_name) : $(cts_package_xml) $(cts_module_test_config)
-
-# Make sure we clear cts_runtime_hint, so other parents will use the default if they do not set cts_runtime_hint.
-cts_runtime_hint :=
diff --git a/build/test_target_java_library.mk b/build/test_target_java_library.mk
index fe1000a..525abb5 100644
--- a/build/test_target_java_library.mk
+++ b/build/test_target_java_library.mk
@@ -50,4 +50,4 @@
 						-o $@
 
 # Have the module name depend on the cts files; so the cts files get generated when you run mm/mmm/mma/mmma.
-$(my_register_name) : $(cts_library_jar) $(cts_library_xml $(cts_module_test_config))
+$(my_register_name) : $(cts_library_jar) $(cts_library_xml) $(cts_module_test_config)
diff --git a/build/test_uiautomator.mk b/build/test_uiautomator.mk
deleted file mode 100644
index a191d72..0000000
--- a/build/test_uiautomator.mk
+++ /dev/null
@@ -1,60 +0,0 @@
-# Copyright (C) 2012 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-#
-# Builds a uiautomator library and defines a rule to generate the associated test
-# package XML needed by CTS.
-#
-
-LOCAL_DEX_PREOPT := false
-
-include $(BUILD_JAVA_LIBRARY)
-include $(BUILD_CTS_MODULE_TEST_CONFIG)
-
-cts_library_jar := $(CTS_TESTCASES_OUT)/$(LOCAL_MODULE).jar
-$(cts_library_jar): $(LOCAL_BUILT_MODULE)
-	$(call copy-file-to-target)
-
-cts_src_dirs := $(LOCAL_PATH)/src
-cts_src_dirs += $(sort $(dir $(LOCAL_GENERATED_SOURCES)))
-cts_src_dirs := $(addprefix -s , $(cts_src_dirs))
-
-cts_library_xml := $(CTS_TESTCASES_OUT)/$(LOCAL_MODULE).xml
-$(cts_library_xml): PRIVATE_SRC_DIRS := $(cts_src_dirs)
-$(cts_library_xml): PRIVATE_TEST_APP_PACKAGE := $(LOCAL_CTS_TEST_APP_PACKAGE)
-$(cts_library_xml): PRIVATE_TEST_PACKAGE := $(LOCAL_CTS_TEST_PACKAGE)
-$(cts_library_xml): PRIVATE_TEST_APK := $(LOCAL_CTS_TEST_APK)
-$(cts_library_xml): PRIVATE_LIBRARY := $(LOCAL_MODULE)
-$(cts_library_xml): PRIVATE_JAR_PATH := $(LOCAL_MODULE).jar
-$(cts_library_xml): $(cts_library_jar)
-$(cts_library_xml): $(cts_module_test_config)
-$(cts_library_xml): $(CTS_EXPECTATIONS) $(CTS_UNSUPPORTED_ABIS) $(CTS_JAVA_TEST_SCANNER_DOCLET) $(CTS_JAVA_TEST_SCANNER) $(CTS_XML_GENERATOR)
-	$(hide) echo Generating test description for uiautomator library $(PRIVATE_LIBRARY)
-	$(hide) mkdir -p $(CTS_TESTCASES_OUT)
-	$(hide) $(CTS_JAVA_TEST_SCANNER) $(PRIVATE_SRC_DIRS) \
-						-d $(CTS_JAVA_TEST_SCANNER_DOCLET) | \
-			$(CTS_XML_GENERATOR) -t uiAutomator \
-						-i $(PRIVATE_TEST_APK) \
-						-j $(PRIVATE_JAR_PATH) \
-						-s $(PRIVATE_TEST_PACKAGE) \
-						-n $(PRIVATE_LIBRARY) \
-						-p $(PRIVATE_TEST_PACKAGE) \
-						-r $(PRIVATE_TEST_APP_PACKAGE) \
-						-e $(CTS_EXPECTATIONS) \
-						-b $(CTS_UNSUPPORTED_ABIS) \
-						-a $(CTS_TARGET_ARCH) \
-						-o $@
-
-# Have the module name depend on the cts files; so the cts files get generated when you run mm/mmm/mma/mmma.
-$(my_register_name) : $(cts_library_jar) $(cts_library_xml) $(cts_module_test_config)
diff --git a/common/device-side/device-info/Android.mk b/common/device-side/device-info/Android.mk
index 26b2cb8..1fde079 100644
--- a/common/device-side/device-info/Android.mk
+++ b/common/device-side/device-info/Android.mk
@@ -20,7 +20,7 @@
 
 LOCAL_MODULE_TAGS := optional
 
-LOCAL_STATIC_JAVA_LIBRARIES := compatibility-device-util_v2
+LOCAL_STATIC_JAVA_LIBRARIES := compatibility-device-util android-support-test
 
 LOCAL_MODULE := compatibility-device-info
 
diff --git a/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/CameraDeviceInfo.java b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/CameraDeviceInfo.java
deleted file mode 100644
index 4b65540..0000000
--- a/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/CameraDeviceInfo.java
+++ /dev/null
@@ -1,538 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.compatibility.common.deviceinfo;
-
-import android.content.Context;
-import android.graphics.Rect;
-import android.hardware.Camera;
-import android.hardware.camera2.CameraAccessException;
-import android.hardware.camera2.CameraCharacteristics;
-import android.hardware.camera2.CameraManager;
-import android.hardware.camera2.params.BlackLevelPattern;
-import android.hardware.camera2.params.ColorSpaceTransform;
-import android.hardware.camera2.params.StreamConfigurationMap;
-import android.media.CamcorderProfile;
-import android.os.Build;
-import android.util.Log;
-import android.util.Rational;
-import android.util.Size;
-import android.util.SizeF;
-import android.util.Range;
-
-import com.android.compatibility.common.util.InfoStore;
-
-import java.lang.reflect.Array;
-import java.lang.reflect.Field;
-import java.lang.reflect.GenericArrayType;
-import java.lang.reflect.Modifier;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.util.HashSet;
-import java.util.List;
-
-/**
- * Camera information collector.
- */
-public final class CameraDeviceInfo extends DeviceInfo {
-    private static final String TAG = "CameraDeviceInfo";
-
-    private final static class CameraCharacteristicsStorer {
-        private CameraManager mCameraManager;
-        private InfoStore mStore;
-
-        public CameraCharacteristicsStorer(CameraManager cameraManager, InfoStore store) {
-            if (cameraManager == null || store == null) {
-                throw new IllegalArgumentException("can not create an CameraMetadataGetter object"
-                        + " with null CameraManager or null InfoStore");
-            }
-
-            mCameraManager = cameraManager;
-            mStore = store;
-        }
-
-        public void storeCameraInfo(String cameraId) throws Exception {
-            try {
-                CameraCharacteristics chars = mCameraManager.getCameraCharacteristics(cameraId);
-                mStore.startGroup(); // per camera chars
-                mStore.addResult("cameraId", cameraId);
-                storeCameraChars(chars);
-                mStore.endGroup(); // per camera chars
-            } catch (CameraAccessException e) {
-                Log.e(TAG,
-                        "Unable to get camera camera static info, skip this camera, error: "
-                                + e.getMessage());
-            }
-            return;
-        }
-
-        private void storeRational(
-                Rational rat, String protoName) throws Exception {
-            if (protoName == null) {
-                mStore.startGroup();
-            } else {
-                mStore.startGroup(protoName);
-            }
-            mStore.addResult("numerator", rat.getNumerator());
-            mStore.addResult("denominator", rat.getDenominator());
-            mStore.endGroup();
-        }
-
-        private void storeSize(
-                Size size, String protoName) throws Exception {
-            if (protoName == null) {
-                mStore.startGroup();
-            } else {
-                mStore.startGroup(protoName);
-            }
-            mStore.addResult("width", size.getWidth());
-            mStore.addResult("height", size.getHeight());
-            mStore.endGroup();
-        }
-
-        private void storeSizeF(
-                SizeF size, String protoName) throws Exception {
-            if (protoName == null) {
-                mStore.startGroup();
-            } else {
-                mStore.startGroup(protoName);
-            }
-            mStore.addResult("width", size.getWidth());
-            mStore.addResult("height", size.getHeight());
-            mStore.endGroup();
-        }
-
-        private void storeRect(
-                Rect rect, String protoName) throws Exception {
-            if (protoName == null) {
-                mStore.startGroup();
-            } else {
-                mStore.startGroup(protoName);
-            }
-            mStore.addResult("left", rect.left);
-            mStore.addResult("right", rect.right);
-            mStore.addResult("top", rect.top);
-            mStore.addResult("bottom", rect.bottom);
-            mStore.endGroup();
-        }
-
-        private void storeStreamConfigurationMap(
-                StreamConfigurationMap map, String protoName) throws Exception {
-            if (protoName == null) {
-                mStore.startGroup();
-            } else {
-                mStore.startGroup(protoName);
-            }
-
-            int fmts[] = map.getOutputFormats();
-            if (fmts != null) {
-                mStore.startArray("availableStreamConfigurations");
-                for (int fi = 0; fi < Array.getLength(fmts); fi++) {
-                    Size sizes[] = map.getOutputSizes(fmts[fi]);
-                    if (sizes != null) {
-                        for (int si = 0; si < Array.getLength(sizes); si++) {
-                            mStore.startGroup();
-                            mStore.addResult("format", fmts[fi]);
-                            mStore.addResult("width", sizes[si].getWidth());
-                            mStore.addResult("height", sizes[si].getHeight());
-                            mStore.addResult("input", false);
-                            mStore.addResult("minFrameDuration",
-                                            map.getOutputMinFrameDuration(fmts[fi], sizes[si]));
-                            mStore.endGroup();
-                        }
-                    }
-                }
-                mStore.endArray();
-            }
-            mStore.endGroup();
-        }
-
-        private void storeRangeInt(
-                Range<Integer> range, String protoName) throws Exception {
-            if (protoName == null) {
-                mStore.startGroup();
-            } else {
-                mStore.startGroup(protoName);
-            }
-            mStore.addResult("lower", range.getLower());
-            mStore.addResult("upper", range.getUpper());
-            mStore.endGroup();
-        }
-
-        private void storeRangeLong(
-                Range<Long> range, String protoName) throws Exception {
-            if (protoName == null) {
-                mStore.startGroup();
-            } else {
-                mStore.startGroup(protoName);
-            }
-            mStore.addResult("lower", range.getLower());
-            mStore.addResult("upper", range.getUpper());
-            mStore.endGroup();
-        }
-
-        private void storeColorSpaceTransform(
-                ColorSpaceTransform xform, String protoName) throws Exception {
-            if (protoName == null) {
-                mStore.startGroup();
-            } else {
-                mStore.startGroup(protoName);
-            }
-
-            mStore.startArray("elements");
-            for (int row = 0; row < 3; row++) {
-                for (int col = 0; col < 3; col++) {
-                    storeRational((Rational) xform.getElement(col, row), null);
-                }
-            }
-            mStore.endArray();
-            mStore.endGroup();
-        }
-
-        private void storeBlackLevelPattern(
-                BlackLevelPattern pat, String protoName) throws Exception {
-            if (protoName == null) {
-                mStore.startGroup();
-            } else {
-                mStore.startGroup(protoName);
-            }
-            int patVals[] = new int[4];
-            pat.copyTo(patVals, 0);
-            mStore.addArrayResult("black_level_pattern", patVals);
-            mStore.endGroup();
-        }
-
-        private static String getKeyName(Object keyObj) {
-            return ((CameraCharacteristics.Key) keyObj).getName();
-        }
-
-        private static Object getKeyValue(CameraCharacteristics chars, Object keyObj) {
-            return chars.get((CameraCharacteristics.Key) keyObj);
-        }
-
-        private void storeEntry(Type keyType, Object keyObj,
-                CameraCharacteristics chars) throws Exception {
-            String keyName = getKeyName(keyObj);
-            String protoName = keyName.replace('.', '_');
-            Object keyValue = getKeyValue(chars, keyObj);
-            if (keyValue == null) {
-                return;
-            }
-
-            if (keyType == int.class || keyType == Integer.class) {
-                mStore.addResult(protoName, (int) keyValue);
-                return;
-            } else if (keyType == float.class || keyType == Float.class) {
-                mStore.addResult(protoName, (float) keyValue);
-                return;
-            } else if (keyType == long.class || keyType == Long.class) {
-                mStore.addResult(protoName, (long) keyValue);
-                return;
-            } else if (keyType == double.class || keyType == Double.class) {
-                mStore.addResult(protoName, (double) keyValue);
-                return;
-            } else if (keyType == boolean.class || keyType == Boolean.class) {
-                mStore.addResult(protoName, (boolean) keyValue);
-                return;
-            } else if (keyType == byte.class || keyType == Byte.class) {
-                // Infostore does not support byte, convert to int32 and save
-                int intValue = (int) ((byte) keyValue);
-                mStore.addResult(protoName, intValue);
-                return;
-            } else if (keyType == Rational.class) {
-                storeRational((Rational) keyValue, protoName);
-                return;
-            } else if (keyType == Size.class) {
-                storeSize((Size) keyValue, protoName);
-                return;
-            } else if (keyType == SizeF.class) {
-                storeSizeF((SizeF) keyValue, protoName);
-                return;
-            } else if (keyType == Rect.class) {
-                storeRect((Rect) keyValue, protoName);
-                return;
-            } else if (keyType == StreamConfigurationMap.class) {
-                storeStreamConfigurationMap(
-                        (StreamConfigurationMap) keyValue, protoName);
-                return;
-            } else if (keyType instanceof ParameterizedType &&
-                    ((ParameterizedType) keyType).getRawType() == Range.class &&
-                    ((ParameterizedType) keyType).getActualTypeArguments()[0] == Integer.class) {
-                storeRangeInt((Range<Integer>) keyValue, protoName);
-                return;
-            } else if (keyType instanceof ParameterizedType &&
-                    ((ParameterizedType) keyType).getRawType() == Range.class &&
-                    ((ParameterizedType) keyType).getActualTypeArguments()[0] == Long.class) {
-                storeRangeLong((Range<Long>) keyValue, protoName);
-                return;
-            } else if (keyType == ColorSpaceTransform.class) {
-                storeColorSpaceTransform((ColorSpaceTransform) keyValue, protoName);
-                return;
-            } else if (keyType == BlackLevelPattern.class) {
-                storeBlackLevelPattern((BlackLevelPattern) keyValue, protoName);
-                return;
-            } else {
-                Log.w(TAG, "Storing unsupported key type: " + keyType +
-                        " for keyName: " + keyName);
-                return;
-            }
-        }
-
-        private void storeArrayEntry(Type keyType, Object keyObj,
-                CameraCharacteristics chars) throws Exception {
-            String keyName = getKeyName(keyObj);
-            String protoName = keyName.replace('.', '_');
-            Object keyValue = getKeyValue(chars, keyObj);
-            if (keyValue == null) {
-                return;
-            }
-
-            int arrayLen = Array.getLength(keyValue);
-            if (arrayLen == 0) {
-                return;
-            }
-            Type elmtType = ((GenericArrayType) keyType).getGenericComponentType();
-
-            if (elmtType == int.class) {
-                mStore.addArrayResult(protoName, (int[]) keyValue);
-                return;
-            } else if (elmtType == float.class) {
-                mStore.addArrayResult(protoName, (float[]) keyValue);
-                return;
-            } else if (elmtType == long.class) {
-                mStore.addArrayResult(protoName, (long[]) keyValue);
-                return;
-            } else if (elmtType == double.class) {
-                mStore.addArrayResult(protoName, (double[]) keyValue);
-                return;
-            } else if (elmtType == boolean.class) {
-                mStore.addArrayResult(protoName, (boolean[]) keyValue);
-                return;
-            } else if (elmtType == byte.class) {
-                // Infostore does not support byte, convert to int32 and save
-                int[] intValues = new int[arrayLen];
-                for (int i = 0; i < arrayLen; i++) {
-                    intValues[i] = (int) ((byte) Array.get(keyValue, i));
-                }
-                mStore.addArrayResult(protoName, intValues);
-                return;
-            } else if (elmtType == Rational.class) {
-                mStore.startArray(protoName);
-                for (int i = 0; i < arrayLen; i++) {
-                    storeRational((Rational) Array.get(keyValue, i), null);
-                }
-                mStore.endArray();
-                return;
-            } else if (elmtType == Size.class) {
-                mStore.startArray(protoName);
-                for (int i = 0; i < arrayLen; i++) {
-                    storeSize((Size) Array.get(keyValue, i), null);
-                }
-                mStore.endArray();
-                return;
-            } else if (elmtType == Rect.class) {
-                mStore.startArray(protoName);
-                for (int i = 0; i < arrayLen; i++) {
-                    storeRect((Rect) Array.get(keyValue, i), null);
-                }
-                mStore.endArray();
-                return;
-            } else if (elmtType instanceof ParameterizedType &&
-                    ((ParameterizedType) elmtType).getRawType() == Range.class &&
-                    ((ParameterizedType) elmtType).getActualTypeArguments()[0] == Integer.class) {
-                mStore.startArray(protoName);
-                for (int i = 0; i < arrayLen; i++) {
-                    storeRangeInt((Range<Integer>) Array.get(keyValue, i), null);
-                }
-                mStore.endArray();
-                return;
-            } else if (elmtType == BlackLevelPattern.class) {
-                mStore.startArray(protoName);
-                for (int i = 0; i < arrayLen; i++) {
-                    storeBlackLevelPattern((BlackLevelPattern) Array.get(keyValue, i), null);
-                }
-                mStore.endArray();
-                return;
-            } else {
-                Log.w(TAG, "Storing unsupported array type: " + elmtType +
-                        " for keyName: " + keyName);
-                return;
-            }
-        }
-
-        private void storeCameraChars(
-                CameraCharacteristics chars) throws Exception {
-            HashSet<String> charsKeyNames = getAllCharacteristicsKeyNames();
-            Field[] allFields = chars.getClass().getDeclaredFields();
-            for (Field field : allFields) {
-                if (Modifier.isPublic(field.getModifiers()) &&
-                        Modifier.isStatic(field.getModifiers()) &&
-                        field.getType() == CameraCharacteristics.Key.class &&
-                        field.getGenericType() instanceof ParameterizedType) {
-                    ParameterizedType paramType = (ParameterizedType) field.getGenericType();
-                    Type[] argTypes = paramType.getActualTypeArguments();
-                    if (argTypes.length > 0) {
-                        try {
-                            Type keyType = argTypes[0];
-                            Object keyObj = field.get(chars);
-                            String keyName = getKeyName(keyObj);
-                            if (charsKeyNames.contains(keyName)) {
-                                if (keyType instanceof GenericArrayType) {
-                                    storeArrayEntry(keyType, keyObj, chars);
-                                } else {
-                                    storeEntry(keyType, keyObj, chars);
-                                }
-                            }
-                        } catch (IllegalAccessException e) {
-                            throw new IllegalStateException(
-                                    "Access error for field: " + field + ": ", e);
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-
-    @Override
-    protected void collectDeviceInfo(InfoStore store) throws Exception {
-        store.addResult("profile_480p", CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_480P));
-        store.addResult("profile_720p", CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_720P));
-        store.addResult("profile_1080p", CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_1080P));
-        store.addResult("profile_cif", CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_CIF));
-        store.addResult("profile_qcif", CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_QCIF));
-        store.addResult("profile_qvga", CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_QVGA));
-
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.L) {
-            // query camera devices and store each camera's characteristics
-            CameraManager cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
-            try {
-                String[] cameraIdList = cameraManager.getCameraIdList();
-                store.addResult("num_of_camera", cameraIdList.length);
-                if (cameraIdList.length > 0) {
-                    CameraCharacteristicsStorer charsStorer =
-                            new CameraCharacteristicsStorer(cameraManager, store);
-                    store.startArray("per_camera_info");
-                    for (int i = 0; i < cameraIdList.length; i++) {
-                        charsStorer.storeCameraInfo(cameraIdList[i]);
-                    }
-                    store.endArray(); // per_camera_info
-                }
-            } catch (CameraAccessException e) {
-                Log.e(TAG,
-                        "Unable to get camera camera ID list, error: "
-                                + e.getMessage());
-            }
-        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
-            // Only supports Camera API1
-            int numCameras = Camera.getNumberOfCameras();
-            store.addResult("num_of_camera", numCameras);
-        } else {
-            // No Camera number query support
-            store.addResult("num_of_camera", 0);
-        }
-
-    }
-
-    /*@O~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~
-     * The key entries below this point are generated from metadata
-     * definitions in /system/media/camera/docs. Do not modify by hand or
-     * modify the comment blocks at the start or end.
-     *~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~*/
-
-    private static HashSet<String> getAllCharacteristicsKeyNames() {
-        HashSet<String> charsKeyNames = new HashSet<String>();
-        charsKeyNames.add(CameraCharacteristics.COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES.getName());
-        charsKeyNames.add(CameraCharacteristics.CONTROL_AE_AVAILABLE_ANTIBANDING_MODES.getName());
-        charsKeyNames.add(CameraCharacteristics.CONTROL_AE_AVAILABLE_MODES.getName());
-        charsKeyNames.add(CameraCharacteristics.CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES.getName());
-        charsKeyNames.add(CameraCharacteristics.CONTROL_AE_COMPENSATION_RANGE.getName());
-        charsKeyNames.add(CameraCharacteristics.CONTROL_AE_COMPENSATION_STEP.getName());
-        charsKeyNames.add(CameraCharacteristics.CONTROL_AF_AVAILABLE_MODES.getName());
-        charsKeyNames.add(CameraCharacteristics.CONTROL_AVAILABLE_EFFECTS.getName());
-        charsKeyNames.add(CameraCharacteristics.CONTROL_AVAILABLE_SCENE_MODES.getName());
-        charsKeyNames.add(CameraCharacteristics.CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES.getName());
-        charsKeyNames.add(CameraCharacteristics.CONTROL_AWB_AVAILABLE_MODES.getName());
-        charsKeyNames.add(CameraCharacteristics.CONTROL_MAX_REGIONS_AE.getName());
-        charsKeyNames.add(CameraCharacteristics.CONTROL_MAX_REGIONS_AWB.getName());
-        charsKeyNames.add(CameraCharacteristics.CONTROL_MAX_REGIONS_AF.getName());
-        charsKeyNames.add(CameraCharacteristics.CONTROL_AE_LOCK_AVAILABLE.getName());
-        charsKeyNames.add(CameraCharacteristics.CONTROL_AWB_LOCK_AVAILABLE.getName());
-        charsKeyNames.add(CameraCharacteristics.CONTROL_AVAILABLE_MODES.getName());
-        charsKeyNames.add(CameraCharacteristics.EDGE_AVAILABLE_EDGE_MODES.getName());
-        charsKeyNames.add(CameraCharacteristics.FLASH_INFO_AVAILABLE.getName());
-        charsKeyNames.add(CameraCharacteristics.HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES.getName());
-        charsKeyNames.add(CameraCharacteristics.JPEG_AVAILABLE_THUMBNAIL_SIZES.getName());
-        charsKeyNames.add(CameraCharacteristics.LENS_FACING.getName());
-        charsKeyNames.add(CameraCharacteristics.LENS_INFO_AVAILABLE_APERTURES.getName());
-        charsKeyNames.add(CameraCharacteristics.LENS_INFO_AVAILABLE_FILTER_DENSITIES.getName());
-        charsKeyNames.add(CameraCharacteristics.LENS_INFO_AVAILABLE_FOCAL_LENGTHS.getName());
-        charsKeyNames.add(CameraCharacteristics.LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION.getName());
-        charsKeyNames.add(CameraCharacteristics.LENS_INFO_HYPERFOCAL_DISTANCE.getName());
-        charsKeyNames.add(CameraCharacteristics.LENS_INFO_MINIMUM_FOCUS_DISTANCE.getName());
-        charsKeyNames.add(CameraCharacteristics.LENS_INFO_FOCUS_DISTANCE_CALIBRATION.getName());
-        charsKeyNames.add(CameraCharacteristics.NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES.getName());
-        charsKeyNames.add(CameraCharacteristics.REQUEST_MAX_NUM_OUTPUT_RAW.getName());
-        charsKeyNames.add(CameraCharacteristics.REQUEST_MAX_NUM_OUTPUT_PROC.getName());
-        charsKeyNames.add(CameraCharacteristics.REQUEST_MAX_NUM_OUTPUT_PROC_STALLING.getName());
-        charsKeyNames.add(CameraCharacteristics.REQUEST_MAX_NUM_INPUT_STREAMS.getName());
-        charsKeyNames.add(CameraCharacteristics.REQUEST_PIPELINE_MAX_DEPTH.getName());
-        charsKeyNames.add(CameraCharacteristics.REQUEST_PARTIAL_RESULT_COUNT.getName());
-        charsKeyNames.add(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES.getName());
-        charsKeyNames.add(CameraCharacteristics.SCALER_AVAILABLE_MAX_DIGITAL_ZOOM.getName());
-        charsKeyNames.add(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP.getName());
-        charsKeyNames.add(CameraCharacteristics.SCALER_CROPPING_TYPE.getName());
-        charsKeyNames.add(CameraCharacteristics.SENSOR_REFERENCE_ILLUMINANT1.getName());
-        charsKeyNames.add(CameraCharacteristics.SENSOR_REFERENCE_ILLUMINANT2.getName());
-        charsKeyNames.add(CameraCharacteristics.SENSOR_CALIBRATION_TRANSFORM1.getName());
-        charsKeyNames.add(CameraCharacteristics.SENSOR_CALIBRATION_TRANSFORM2.getName());
-        charsKeyNames.add(CameraCharacteristics.SENSOR_COLOR_TRANSFORM1.getName());
-        charsKeyNames.add(CameraCharacteristics.SENSOR_COLOR_TRANSFORM2.getName());
-        charsKeyNames.add(CameraCharacteristics.SENSOR_FORWARD_MATRIX1.getName());
-        charsKeyNames.add(CameraCharacteristics.SENSOR_FORWARD_MATRIX2.getName());
-        charsKeyNames.add(CameraCharacteristics.SENSOR_BLACK_LEVEL_PATTERN.getName());
-        charsKeyNames.add(CameraCharacteristics.SENSOR_MAX_ANALOG_SENSITIVITY.getName());
-        charsKeyNames.add(CameraCharacteristics.SENSOR_ORIENTATION.getName());
-        charsKeyNames.add(CameraCharacteristics.SENSOR_AVAILABLE_TEST_PATTERN_MODES.getName());
-        charsKeyNames.add(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE.getName());
-        charsKeyNames.add(CameraCharacteristics.SENSOR_INFO_SENSITIVITY_RANGE.getName());
-        charsKeyNames.add(CameraCharacteristics.SENSOR_INFO_COLOR_FILTER_ARRANGEMENT.getName());
-        charsKeyNames.add(CameraCharacteristics.SENSOR_INFO_EXPOSURE_TIME_RANGE.getName());
-        charsKeyNames.add(CameraCharacteristics.SENSOR_INFO_MAX_FRAME_DURATION.getName());
-        charsKeyNames.add(CameraCharacteristics.SENSOR_INFO_PHYSICAL_SIZE.getName());
-        charsKeyNames.add(CameraCharacteristics.SENSOR_INFO_PIXEL_ARRAY_SIZE.getName());
-        charsKeyNames.add(CameraCharacteristics.SENSOR_INFO_WHITE_LEVEL.getName());
-        charsKeyNames.add(CameraCharacteristics.SENSOR_INFO_TIMESTAMP_SOURCE.getName());
-        charsKeyNames.add(CameraCharacteristics.SENSOR_INFO_LENS_SHADING_APPLIED.getName());
-        charsKeyNames.add(CameraCharacteristics.SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE.getName());
-        charsKeyNames.add(CameraCharacteristics.SHADING_AVAILABLE_MODES.getName());
-        charsKeyNames.add(CameraCharacteristics.STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES.getName());
-        charsKeyNames.add(CameraCharacteristics.STATISTICS_INFO_MAX_FACE_COUNT.getName());
-        charsKeyNames.add(CameraCharacteristics.STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES.getName());
-        charsKeyNames.add(CameraCharacteristics.STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES.getName());
-        charsKeyNames.add(CameraCharacteristics.TONEMAP_MAX_CURVE_POINTS.getName());
-        charsKeyNames.add(CameraCharacteristics.TONEMAP_AVAILABLE_TONE_MAP_MODES.getName());
-        charsKeyNames.add(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL.getName());
-        charsKeyNames.add(CameraCharacteristics.SYNC_MAX_LATENCY.getName());
-        charsKeyNames.add(CameraCharacteristics.REPROCESS_MAX_CAPTURE_STALL.getName());
-        charsKeyNames.add(CameraCharacteristics.DEPTH_DEPTH_IS_EXCLUSIVE.getName());
-
-        return charsKeyNames;
-    }
-
-    /*~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~
-     * End generated code
-     *~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~O@*/
-}
diff --git a/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/ConfigurationDeviceInfo.java b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/ConfigurationDeviceInfo.java
new file mode 100644
index 0000000..fb4b7c4
--- /dev/null
+++ b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/ConfigurationDeviceInfo.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.deviceinfo;
+
+import android.content.res.Configuration;
+
+import com.android.compatibility.common.util.DeviceInfoStore;
+
+/**
+ * Configuration device info collector.
+ */
+public final class ConfigurationDeviceInfo extends DeviceInfo {
+
+    @Override
+    protected void collectDeviceInfo(DeviceInfoStore store) throws Exception {
+        Configuration con = getInstrumentation().getContext().getResources().getConfiguration();
+        store.addResult("touchscreen", con.touchscreen);
+        store.addResult("navigation", con.navigation);
+        store.addResult("keyboard", con.keyboard);
+    }
+}
diff --git a/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/CpuDeviceInfo.java b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/CpuDeviceInfo.java
new file mode 100644
index 0000000..ad6a135
--- /dev/null
+++ b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/CpuDeviceInfo.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.deviceinfo;
+
+import com.android.compatibility.common.util.DeviceInfoStore;
+
+/**
+ * CPU device info collector.
+ */
+public final class CpuDeviceInfo extends DeviceInfo {
+
+    @Override
+    protected void collectDeviceInfo(DeviceInfoStore store) throws Exception {
+        store.addResult("available_processors", Runtime.getRuntime().availableProcessors());
+    }
+}
diff --git a/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/DeviceInfo.java b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/DeviceInfo.java
index c74ed3a..8aa3380 100644
--- a/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/DeviceInfo.java
+++ b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/DeviceInfo.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016 The Android Open Source Project
+ * Copyright (C) 2015 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -15,11 +15,130 @@
  */
 package com.android.compatibility.common.deviceinfo;
 
+import android.app.Activity;
+import android.content.Context;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.os.Environment;
+import android.test.InstrumentationTestCase;
+import android.text.TextUtils;
+import android.util.JsonWriter;
+import android.util.Log;
+
+import com.android.compatibility.common.util.DeviceInfoStore;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.OutputStreamWriter;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
 /**
- * DeviceInfoActivity wrapper class. All EDI collectors should extend this
- * class instead of DeviceInfoActivity.
+ * Collect device information on target device and write to a JSON file.
  */
-public abstract class DeviceInfo extends DeviceInfoActivity {
+public abstract class DeviceInfo extends InstrumentationTestCase {
 
+    private enum ResultCode {
+        // Collection started.
+        STARTED,
+        // Collection completed.
+        COMPLETED,
+        // Collection completed with error.
+        ERROR,
+        // Collection failed to complete.
+        FAILED
+    }
+
+    private static final int MAX_STRING_VALUE_LENGTH = 1000;
+    private static final int MAX_ARRAY_LENGTH = 1000;
+
+    private static final String LOG_TAG = "ExtendedDeviceInfo";
+
+    private JsonWriter mJsonWriter = null;
+    private String mResultFilePath = null;
+    private String mErrorMessage = null;
+    private ResultCode mResultCode = ResultCode.STARTED;
+
+    Set<String> mActivityList = new HashSet<String>();
+
+    public void testCollectDeviceInfo() throws Exception {
+        if (!mActivityList.contains(getClass().getName())) {
+            return;
+        }
+
+        final File dir = new File(Environment.getExternalStorageDirectory(), "device-info-files");
+        if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
+            failed("External storage is not mounted");
+        } else if (!dir.mkdirs() && !dir.isDirectory()) {
+            failed("Cannot create directory for device info files");
+        } else {
+            try {
+                File jsonFile = new File(dir, getClass().getSimpleName() + ".deviceinfo.json");
+                jsonFile.createNewFile();
+                mResultFilePath = jsonFile.getAbsolutePath();
+                DeviceInfoStore store = new DeviceInfoStore(jsonFile);
+                store.open();
+                collectDeviceInfo(store);
+                store.close();
+                if (mResultCode == ResultCode.STARTED) {
+                    mResultCode = ResultCode.COMPLETED;
+                }
+            } catch (Exception e) {
+                failed("Could not collect device info: " + e.getMessage());
+            }
+        }
+
+        String message = getClass().getSimpleName() + " collection completed.";
+        assertEquals(message, ResultCode.COMPLETED, mResultCode);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        // Build the list of supported activities that can run collection.
+        ActivityInfo[] activities = null;
+        try {
+            activities = getContext().getPackageManager().getPackageInfo(
+                getContext().getPackageName(), PackageManager.GET_ACTIVITIES).activities;
+        } catch (Exception e) {
+            Log.e(LOG_TAG, "Exception occurred while getting activities.", e);
+            return;
+        }
+
+        for (ActivityInfo activityInfo : activities) {
+            mActivityList.add(activityInfo.name);
+        }
+    }
+
+    /**
+     * Method to collect device information.
+     */
+    protected abstract void collectDeviceInfo(DeviceInfoStore store) throws Exception;
+
+    protected Context getContext() {
+        return getInstrumentation().getContext();
+    }
+
+    /**
+     * Returns the path to the json file if collector completed successfully.
+     */
+    String getResultFilePath() {
+        return mResultFilePath;
+    }
+
+    private void error(String message, Throwable exception) {
+        mResultCode = ResultCode.ERROR;
+        mErrorMessage = message;
+        Log.e(LOG_TAG, message, exception);
+    }
+
+    private void failed(String message) {
+        mResultCode = ResultCode.FAILED;
+        mErrorMessage = message;
+        Log.e(LOG_TAG, message);
+    }
 }
-
diff --git a/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/DeviceInfoActivity.java b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/DeviceInfoActivity.java
deleted file mode 100644
index 1f1e287..0000000
--- a/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/DeviceInfoActivity.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.compatibility.common.deviceinfo;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Environment;
-import android.util.Log;
-
-import java.io.File;
-import java.util.concurrent.CountDownLatch;
-
-import com.android.compatibility.common.util.InfoStore;
-
-/**
- * Collect device information on target device and write to a JSON file.
- */
-public abstract class DeviceInfoActivity extends Activity {
-
-    /** Device info result code: collector failed to complete. */
-    private static final int DEVICE_INFO_RESULT_FAILED = -2;
-    /** Device info result code: collector completed with error. */
-    private static final int DEVICE_INFO_RESULT_ERROR = -1;
-    /** Device info result code: collector has started but not completed. */
-    private static final int DEVICE_INFO_RESULT_STARTED = 0;
-    /** Device info result code: collector completed success. */
-    private static final int DEVICE_INFO_RESULT_OK = 1;
-
-    private static final int MAX_STRING_VALUE_LENGTH = 1000;
-    private static final int MAX_ARRAY_LENGTH = 1000;
-
-    private static final String LOG_TAG = "DeviceInfoActivity";
-
-    private CountDownLatch mDone = new CountDownLatch(1);
-    private String mResultFilePath = null;
-    private String mErrorMessage = "Collector has started.";
-    private int mResultCode = DEVICE_INFO_RESULT_STARTED;
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        final File dir = new File(Environment.getExternalStorageDirectory(), "device-info-files");
-        if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
-            failed("External storage is not mounted");
-        } else if (!dir.mkdirs() && !dir.isDirectory()) {
-            failed("Cannot create directory for device info files");
-        } else {
-            try {
-                File jsonFile = new File(dir, getClass().getSimpleName() + ".deviceinfo.json");
-                jsonFile.createNewFile();
-                mResultFilePath = jsonFile.getAbsolutePath();
-                InfoStore store = new InfoStore(jsonFile);
-                store.open();
-                collectDeviceInfo(store);
-                store.close();
-                if (mResultCode == DEVICE_INFO_RESULT_STARTED) {
-                    mResultCode = DEVICE_INFO_RESULT_OK;
-                }
-            } catch (Exception e) {
-                failed("Could not collect device info: " + e.getMessage());
-            }
-        }
-        Intent data = new Intent();
-        if (mResultCode == DEVICE_INFO_RESULT_OK) {
-            data.setData(Uri.parse(mResultFilePath));
-            setResult(RESULT_OK, data);
-        } else {
-            data.setData(Uri.parse(mErrorMessage));
-            setResult(RESULT_CANCELED, data);
-        }
-
-        mDone.countDown();
-        finish();
-    }
-
-    /**
-     * Method to collect device information.
-     */
-    protected abstract void collectDeviceInfo(InfoStore store) throws Exception;
-
-    void waitForActivityToFinish() {
-        try {
-            mDone.await();
-        } catch (Exception e) {
-            failed("Exception while waiting for activity to finish: " + e.getMessage());
-        }
-    }
-
-    /**
-     * Returns the error message if collector did not complete successfully.
-     */
-    String getErrorMessage() {
-        if (mResultCode == DEVICE_INFO_RESULT_OK) {
-            return null;
-        }
-        return mErrorMessage;
-    }
-
-    /**
-     * Returns the path to the json file if collector completed successfully.
-     */
-    String getResultFilePath() {
-        if (mResultCode == DEVICE_INFO_RESULT_OK) {
-            return mResultFilePath;
-        }
-        return null;
-    }
-
-    private void error(String message) {
-        mResultCode = DEVICE_INFO_RESULT_ERROR;
-        mErrorMessage = message;
-        Log.e(LOG_TAG, message);
-    }
-
-    private void failed(String message) {
-        mResultCode = DEVICE_INFO_RESULT_FAILED;
-        mErrorMessage = message;
-        Log.e(LOG_TAG, message);
-    }
-
-}
-
diff --git a/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/DeviceInfoInstrument.java b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/DeviceInfoInstrument.java
deleted file mode 100644
index 2f80911..0000000
--- a/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/DeviceInfoInstrument.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.compatibility.common.deviceinfo;
-
-import android.app.Activity;
-import android.app.Instrumentation;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.ActivityInfo;
-import android.content.pm.PackageManager;
-import android.os.Bundle;
-import android.text.TextUtils;
-import android.util.Log;
-
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * An instrumentation that runs all activities that extends DeviceInfoActivity.
- */
-public class DeviceInfoInstrument extends Instrumentation {
-
-    private static final String LOG_TAG = "ExtendedDeviceInfo";
-    private static final String COLLECTOR = "collector";
-
-    // List of collectors to run. If null or empty, all collectors will run.
-    private Set<String> mCollectorSet = new HashSet<String>();
-
-    // Results sent to the caller when this istrumentation completes.
-    private Bundle mBundle = new Bundle();
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        if (savedInstanceState != null) {
-            String collectorList = savedInstanceState.getString(COLLECTOR);
-            if (!TextUtils.isEmpty(collectorList)) {
-                for (String collector : TextUtils.split(collectorList, ",")) {
-                  if (!TextUtils.isEmpty(collector)) {
-                    mCollectorSet.add(collector);
-                  }
-                }
-            }
-        }
-        start();
-    }
-
-    @Override
-    public void onStart() {
-        try {
-            Context context = getContext();
-            ActivityInfo[] activities = context.getPackageManager().getPackageInfo(
-                    context.getPackageName(), PackageManager.GET_ACTIVITIES).activities;
-            for (ActivityInfo activityInfo : activities) {
-                runActivity(activityInfo.name);
-            }
-        } catch (Exception e) {
-            Log.e(LOG_TAG, "Exception occurred while running activities.", e);
-            // Returns INSTRUMENTATION_CODE: 0
-            finish(Activity.RESULT_CANCELED, mBundle);
-        }
-        // Returns INSTRUMENTATION_CODE: -1
-        finish(Activity.RESULT_OK, mBundle);
-    }
-
-    /**
-     * Returns true if the activity meets the criteria to run; otherwise, false.
-     */
-    private boolean isActivityRunnable(Class activityClass) {
-        // Don't run the base DeviceInfoActivity class.
-        if (DeviceInfoActivity.class == activityClass) {
-            return false;
-        }
-        // Don't run anything that doesn't extends DeviceInfoActivity.
-        if (!DeviceInfoActivity.class.isAssignableFrom(activityClass)) {
-            return false;
-        }
-        // Only run activity if mCollectorSet is empty or contains it.
-        if (mCollectorSet != null && mCollectorSet.size() > 0) {
-            return mCollectorSet.contains(activityClass.getName());
-        }
-        // Run anything that makes it here.
-        return true;
-    }
-
-    /**
-     * Runs a device info activity and return the file path where the results are written to.
-     */
-    private void runActivity(String activityName) throws Exception {
-        Class activityClass = null;
-        try {
-            activityClass = Class.forName(activityName);
-        } catch (ClassNotFoundException e) {
-            return;
-        }
-
-        if (activityClass == null || !isActivityRunnable(activityClass)) {
-            return;
-        }
-
-        Intent intent = new Intent();
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        intent.setClassName(this.getContext(), activityName);
-
-        DeviceInfoActivity activity = (DeviceInfoActivity) startActivitySync(intent);
-        waitForIdleSync();
-        activity.waitForActivityToFinish();
-
-        String className = activityClass.getSimpleName();
-        String errorMessage = activity.getErrorMessage();
-        if (TextUtils.isEmpty(errorMessage)) {
-            mBundle.putString(className, activity.getResultFilePath());
-        } else {
-            mBundle.putString(className, errorMessage);
-            throw new Exception(errorMessage);
-        }
-    }
-}
-
diff --git a/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/FeatureDeviceInfo.java b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/FeatureDeviceInfo.java
new file mode 100644
index 0000000..414fcab
--- /dev/null
+++ b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/FeatureDeviceInfo.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.deviceinfo;
+
+import android.content.pm.FeatureInfo;
+import android.content.pm.PackageManager;
+
+import com.android.compatibility.common.util.DeviceInfoStore;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Feature device info collector.
+ */
+public final class FeatureDeviceInfo extends DeviceInfo {
+
+    @Override
+    protected void collectDeviceInfo(DeviceInfoStore store) throws Exception {
+        PackageManager packageManager = getInstrumentation().getContext().getPackageManager();
+        store.startArray("feature");
+
+        Set<String> checkedFeatures = new HashSet<String>();
+        for (String featureName : getPackageManagerFeatures()) {
+            checkedFeatures.add(featureName);
+            boolean hasFeature = packageManager.hasSystemFeature(featureName);
+            addFeature(store, featureName, "sdk", hasFeature);
+        }
+
+        FeatureInfo[] featureInfos = packageManager.getSystemAvailableFeatures();
+        if (featureInfos != null) {
+            for (FeatureInfo featureInfo : featureInfos) {
+                if (featureInfo.name != null && !checkedFeatures.contains(featureInfo.name)) {
+                    addFeature(store, featureInfo.name, "other", true);
+                }
+            }
+        }
+
+        store.endArray();
+    }
+
+    /**
+     * Use reflection to get the features defined by the SDK. If there are features that do not fit
+     * the convention of starting with "FEATURE_" then they will still be shown under the
+     * "Other Features" section.
+     *
+     * @return list of feature names from sdk
+     */
+    private List<String> getPackageManagerFeatures() {
+        try {
+            List<String> features = new ArrayList<String>();
+            Field[] fields = PackageManager.class.getFields();
+            for (Field field : fields) {
+                if (field.getName().startsWith("FEATURE_")) {
+                    String feature = (String) field.get(null);
+                    features.add(feature);
+                }
+            }
+            return features;
+        } catch (IllegalAccessException illegalAccess) {
+            throw new RuntimeException(illegalAccess);
+        }
+    }
+
+    private void addFeature(DeviceInfoStore store, String name, String type, boolean available)
+            throws Exception {
+        store.startGroup();
+        store.addResult("name", name);
+        store.addResult("type", type);
+        store.addResult("available", available);
+        store.endGroup();
+    }
+}
diff --git a/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/GenericDeviceInfo.java b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/GenericDeviceInfo.java
index 304b74c..b0486ef 100644
--- a/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/GenericDeviceInfo.java
+++ b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/GenericDeviceInfo.java
@@ -15,13 +15,6 @@
  */
 package com.android.compatibility.common.deviceinfo;
 
-import android.app.Activity;
-import android.app.Instrumentation;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.FeatureInfo;
-import android.content.pm.PackageManager;
-import android.content.res.Configuration;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.Environment;
@@ -29,23 +22,14 @@
 import android.os.UserManager;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
-import android.util.DisplayMetrics;
-import android.util.Log;
-import android.view.Display;
-import android.view.WindowManager;
 
-import java.io.IOException;
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Scanner;
-import java.util.Set;
+import java.lang.Integer;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
 
-import com.android.compatibility.common.util.InfoStore;
+import com.android.compatibility.common.deviceinfo.DeviceInfo;
+import com.android.compatibility.common.util.DeviceInfoStore;
 
 /**
  * Generic device info collector.
@@ -69,16 +53,14 @@
     public static final String BUILD_SERIAL = "build_serial";
     public static final String BUILD_VERSION_RELEASE = "build_version_release";
     public static final String BUILD_VERSION_SDK = "build_version_sdk";
+    public static final String BUILD_VERSION_SDK_INT = "build_version_sdk_int";
     public static final String BUILD_VERSION_BASE_OS = "build_version_base_os";
     public static final String BUILD_VERSION_SECURITY_PATCH = "build_version_security_patch";
 
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-    }
+    private final Map<String, String> mDeviceInfo = new HashMap<>();
 
     @Override
-    protected void collectDeviceInfo(InfoStore store) throws Exception {
+    protected void collectDeviceInfo(DeviceInfoStore store) throws Exception {
         store.addResult(BUILD_ID, Build.ID);
         store.addResult(BUILD_PRODUCT, Build.PRODUCT);
         store.addResult(BUILD_DEVICE, Build.DEVICE);
@@ -94,7 +76,7 @@
         store.addResult(BUILD_VERSION_RELEASE, Build.VERSION.RELEASE);
         store.addResult(BUILD_VERSION_SDK, Build.VERSION.SDK);
 
-         // Collect build fields available in API level 21
+        // Collect build fields available in API level 21
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
             store.addResult(BUILD_ABIS, TextUtils.join(",", Build.SUPPORTED_ABIS));
             store.addResult(BUILD_ABIS_32, TextUtils.join(",", Build.SUPPORTED_32_BIT_ABIS));
diff --git a/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/GlesStubActivity.java b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/GlesStubActivity.java
new file mode 100644
index 0000000..c9d1e9c
--- /dev/null
+++ b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/GlesStubActivity.java
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.deviceinfo;
+
+import android.app.Activity;
+import android.app.ActivityManager;
+import android.app.Instrumentation;
+import android.content.Context;
+import android.content.pm.ConfigurationInfo;
+import android.content.res.Configuration;
+import android.os.Bundle;
+import android.view.Window;
+import android.view.WindowManager;
+import android.opengl.GLES20;
+import android.opengl.GLES30;
+import android.opengl.GLSurfaceView;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+import java.util.HashSet;
+import java.util.Scanner;
+import java.util.Set;
+import java.util.concurrent.CountDownLatch;
+
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.opengles.GL10;
+
+/** Stub activity to collect data from the GlesView */
+public final class GlesStubActivity extends Activity {
+
+    private static final String LOG_TAG = "GlesStubActivity";
+    private int mVersion = -1;
+    private GraphicsDeviceInfo mGraphicsDeviceInfo;
+    private CountDownLatch mDone = new CountDownLatch(1);
+    private HashSet<String> mOpenGlExtensions = new HashSet<String>();
+    private HashSet<String> mFormats = new HashSet<String>();
+    private String mGraphicsVendor;
+    private String mGraphicsRenderer;
+
+    @Override
+    public void onCreate(Bundle bundle) {
+        // Dismiss keyguard and keep screen on while this test is on.
+        Window window = getWindow();
+        window.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD |
+                WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON |
+                WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+
+        super.onCreate(bundle);
+
+        window.setFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED,
+                WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
+
+        ActivityManager activityManager =
+                (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
+        ConfigurationInfo info = activityManager.getDeviceConfigurationInfo();
+
+        mVersion = (info.reqGlEsVersion & 0xffff0000) >> 16;
+
+        new Thread() {
+            @Override
+            public void run() {
+                runIterations(mVersion);
+            }
+        }.start();
+    }
+
+     /**
+     * Wait for this activity to finish gathering information
+     */
+    public void waitForActivityToFinish() {
+        try {
+            mDone.await();
+        } catch (InterruptedException e) {
+            // just move on
+        }
+    }
+
+    private void runIterations(int glVersion) {
+        for (int i = 1; i <= glVersion; i++) {
+            final CountDownLatch done = new CountDownLatch(1);
+            final int version = i;
+            GlesStubActivity.this.runOnUiThread(new Runnable() {
+                @Override
+                public void run() {
+                    setContentView(new GlesSurfaceView(GlesStubActivity.this, version, done));
+                }
+            });
+            try {
+                done.await();
+            } catch (InterruptedException e) {
+                // just move on
+            }
+        }
+        mDone.countDown();
+    }
+
+    int getGlVersion() {
+        return mVersion;
+    }
+
+    List<String> getOpenGlExtensions() {
+        return new ArrayList<>(mOpenGlExtensions);
+    }
+
+    void addOpenGlExtension(String openGlExtension) {
+        mOpenGlExtensions.add(openGlExtension);
+    }
+
+    List<String> getCompressedTextureFormats() {
+        return new ArrayList<>(mFormats);
+    }
+
+    void addCompressedTextureFormat(String format) {
+        mFormats.add(format);
+    }
+
+    String getVendor() {
+        return mGraphicsVendor;
+    }
+
+    void setVendor(String vendor) {
+        mGraphicsVendor = vendor;
+    }
+
+    String getRenderer() {
+        return mGraphicsRenderer;
+    }
+
+    void setRenderer(String renderer) {
+        mGraphicsRenderer = renderer;
+    }
+
+    static class GlesSurfaceView extends GLSurfaceView {
+
+        public GlesSurfaceView(GlesStubActivity parent, int glVersion, CountDownLatch done) {
+            super(parent);
+
+            if (glVersion > 1) {
+                // Default is 1 so only set if bigger than 1
+                setEGLContextClientVersion(glVersion);
+            }
+            setRenderer(new OpenGlesRenderer(parent, glVersion, done));
+        }
+    }
+
+    static class OpenGlesRenderer implements GLSurfaceView.Renderer {
+
+        private final GlesStubActivity mParent;
+        private final int mGlVersion;
+        private final CountDownLatch mDone;
+
+        OpenGlesRenderer(GlesStubActivity parent, int glVersion, CountDownLatch done) {
+            mParent = parent;
+            mGlVersion = glVersion;
+            mDone = done;
+        }
+
+        @Override
+        public void onSurfaceCreated(GL10 gl, EGLConfig config) {
+            String extensions;
+            String vendor;
+            String renderer;
+            if (mGlVersion == 2) {
+                extensions = GLES20.glGetString(GLES20.GL_EXTENSIONS);
+                vendor = GLES20.glGetString(GLES20.GL_VENDOR);
+                renderer = GLES20.glGetString(GLES20.GL_RENDERER);
+            } else if (mGlVersion == 3) {
+                extensions = GLES30.glGetString(GLES30.GL_EXTENSIONS);
+                vendor = GLES30.glGetString(GLES30.GL_VENDOR);
+                renderer = GLES30.glGetString(GLES30.GL_RENDERER);
+            } else {
+                extensions = gl.glGetString(GL10.GL_EXTENSIONS);
+                vendor = gl.glGetString(GL10.GL_VENDOR);
+                renderer = gl.glGetString(GL10.GL_RENDERER);
+            }
+            mParent.setVendor(vendor);
+            mParent.setRenderer(renderer);
+            Scanner scanner = new Scanner(extensions);
+            scanner.useDelimiter(" ");
+            while (scanner.hasNext()) {
+                String ext = scanner.next();
+                mParent.addOpenGlExtension(ext);
+                if (ext.contains("texture")) {
+                    if (ext.contains("compression") || ext.contains("compressed")) {
+                        mParent.addCompressedTextureFormat(ext);
+                    }
+                }
+            }
+            scanner.close();
+            mDone.countDown();
+        }
+
+        @Override
+        public void onSurfaceChanged(GL10 gl, int width, int height) {}
+
+        @Override
+        public void onDrawFrame(GL10 gl) {}
+    }
+}
diff --git a/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/GraphicsDeviceInfo.java b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/GraphicsDeviceInfo.java
new file mode 100644
index 0000000..e8283f8
--- /dev/null
+++ b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/GraphicsDeviceInfo.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.deviceinfo;
+
+import android.os.Bundle;
+
+import com.android.compatibility.common.util.DeviceInfoStore;
+
+/**
+ * Graphics device info collector.
+ */
+public final class GraphicsDeviceInfo extends DeviceInfo {
+
+    private static final String LOG_TAG = "GraphicsDeviceInfo";
+
+    @Override
+    protected void collectDeviceInfo(DeviceInfoStore store) throws Exception {
+        GlesStubActivity stubActivity = GraphicsDeviceInfo.this.launchActivity(
+                "com.android.compatibility.common.deviceinfo",
+                GlesStubActivity.class,
+                new Bundle());
+        stubActivity.waitForActivityToFinish();
+
+        store.addResult("gl_version", stubActivity.getGlVersion());
+        store.addResult("vendor", stubActivity.getVendor());
+        store.addResult("renderer", stubActivity.getRenderer());
+
+        store.addListResult("gl_texture", stubActivity.getCompressedTextureFormats());
+        store.addListResult("gl_extension", stubActivity.getOpenGlExtensions());
+    }
+}
diff --git a/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/LibraryDeviceInfo.java b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/LibraryDeviceInfo.java
new file mode 100644
index 0000000..bc30eefe
--- /dev/null
+++ b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/LibraryDeviceInfo.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.deviceinfo;
+
+import android.util.Log;
+
+import com.android.compatibility.common.util.DeviceInfoStore;
+
+import java.io.Closeable;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Formatter;
+
+/**
+ * Library device info collector.
+ */
+public final class LibraryDeviceInfo extends DeviceInfo {
+
+    private static final String TAG = "LibraryDeviceInfo";
+    private static final int BUFFER_SIZE_BYTES = 4096;
+
+    @Override
+    protected void collectDeviceInfo(DeviceInfoStore store) throws Exception {
+        collectSystemLibs(store);
+        collectVendorLibs(store);
+        collectFrameworkJars(store);
+    }
+
+    private void collectSystemLibs(DeviceInfoStore store) throws Exception {
+        store.startArray("lib");
+        collectFileDetails(store, "/system/lib", ".so");
+        store.endArray();
+    }
+
+    private void collectVendorLibs(DeviceInfoStore store) throws Exception {
+        store.startArray("vendor_lib");
+        collectFileDetails(store, "/system/vendor/lib", ".so");
+        store.endArray();
+    }
+
+    private void collectFrameworkJars(DeviceInfoStore store) throws Exception {
+        store.startArray("framework_jar");
+        collectFileDetails(store, "/system/framework", ".jar");
+        store.endArray();
+    }
+
+    private void collectFileDetails(DeviceInfoStore store, String path, String suffix)
+            throws Exception {
+        File dir = new File(path);
+        for (File file : dir.listFiles()) {
+            String name = file.getName();
+            if (file.isFile() && name.endsWith(suffix)) {
+                String sha1 = "unknown";
+                try {
+                    sha1 = getSha1sum(file);
+                } catch (IOException e) {
+                    Log.e(TAG, "Failed to hash " + file + ": ", e);
+                }
+                store.startGroup();
+                store.addResult("name", name);
+                store.addResult("sha1", sha1);
+                store.endGroup();
+            }
+        }
+    }
+
+    private static String getSha1sum(File file) throws IOException {
+        InputStream in = null;
+        try {
+            in = new FileInputStream(file);
+            return sha1(in);
+        } finally {
+            close(in);
+        }
+    }
+
+    private static void close(Closeable s) throws IOException {
+        if (s == null) {
+            return;
+        }
+        s.close();
+    }
+
+    /**
+     * @return the SHA-1 digest of input as a hex string
+     */
+    public static String sha1(InputStream input) throws IOException {
+        try {
+            return toHexString(digest(input, "sha1"));
+        } catch (NoSuchAlgorithmException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private static byte[] digest(InputStream in, String algorithm)
+        throws NoSuchAlgorithmException, IOException {
+        MessageDigest digest = MessageDigest.getInstance(algorithm);
+        byte[] buffer = new byte[BUFFER_SIZE_BYTES];
+        while (true) {
+            int read = in.read(buffer);
+            if (read < 0) {
+                break;
+            }
+            digest.update(buffer, 0, read);
+        }
+        return digest.digest();
+    }
+
+    private static String toHexString(byte[] buffer) {
+        Formatter formatter = new Formatter();
+        try {
+            for (byte b : buffer) {
+                formatter.format("%02X", b);
+            }
+            return formatter.toString();
+        } finally {
+            formatter.close();
+        }
+    }
+}
diff --git a/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/LocaleDeviceInfo.java b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/LocaleDeviceInfo.java
new file mode 100644
index 0000000..e7cb095
--- /dev/null
+++ b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/LocaleDeviceInfo.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.deviceinfo;
+
+import com.android.compatibility.common.util.DeviceInfoStore;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Locale device info collector.
+ */
+public final class LocaleDeviceInfo extends DeviceInfo {
+
+    @Override
+    protected void collectDeviceInfo(DeviceInfoStore store) throws Exception {
+        List<String> locales = Arrays.asList(
+                getInstrumentation().getContext().getAssets().getLocales());
+        if (locales.isEmpty()) {
+            // default locale
+            locales.add("en_US");
+        }
+        store.addListResult("locale", locales);
+    }
+}
diff --git a/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/MediaDeviceInfo.java b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/MediaDeviceInfo.java
new file mode 100644
index 0000000..8c3ee5a
--- /dev/null
+++ b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/MediaDeviceInfo.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.deviceinfo;
+
+import android.app.ActivityManager;
+import android.app.ActivityManager.MemoryInfo;
+import android.content.Context;
+import android.os.Bundle;
+import android.os.Build;
+
+import android.media.CamcorderProfile;
+import android.media.MediaCodecInfo;
+import android.media.MediaCodecInfo.CodecProfileLevel;
+import android.media.MediaCodecList;
+
+import com.android.compatibility.common.util.DeviceInfoStore;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Media information collector.
+ */
+public final class MediaDeviceInfo extends DeviceInfo {
+
+    @Override
+    protected void collectDeviceInfo(DeviceInfoStore store) throws Exception {
+        store.startArray("media_codec_info");
+        for (int i = 0; i < MediaCodecList.getCodecCount(); i++) {
+            MediaCodecInfo info = MediaCodecList.getCodecInfoAt(i);
+
+            store.startGroup();
+            store.addResult("name", info.getName());
+            store.addResult("encoder", info.isEncoder());
+
+            store.startArray("supported_type");
+            for (String type : info.getSupportedTypes()) {
+
+                store.startGroup();
+                store.addResult("type", type);
+                if (info.getCapabilitiesForType(type).profileLevels.length > 0) {
+                    store.startArray("codec_profile_level");
+                    for (CodecProfileLevel profileLevel :
+                             info.getCapabilitiesForType(type).profileLevels) {
+                        store.startGroup();
+                        store.addResult("level", profileLevel.level);
+                        store.addResult("profile", profileLevel.profile);
+                        store.endGroup();
+                    }
+                    store.endArray(); // codec_profile_level
+                }
+                store.endGroup();
+            }
+            store.endArray();
+            store.endGroup();
+        }
+
+        store.endArray(); // media_codec_profile
+    }
+}
diff --git a/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/MemoryDeviceInfo.java b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/MemoryDeviceInfo.java
new file mode 100644
index 0000000..4cc9de9
--- /dev/null
+++ b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/MemoryDeviceInfo.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.deviceinfo;
+
+import android.app.ActivityManager;
+import android.app.ActivityManager.MemoryInfo;
+import android.content.Context;
+import android.os.Bundle;
+
+import com.android.compatibility.common.deviceinfo.DeviceInfo;
+import com.android.compatibility.common.util.DeviceInfoStore;
+
+/**
+ * MemoryDeviceInfo collector.
+ */
+public final class MemoryDeviceInfo extends DeviceInfo {
+
+    @Override
+    protected void collectDeviceInfo(DeviceInfoStore store) throws Exception {
+        ActivityManager activityManager = (ActivityManager)getInstrumentation()
+                .getTargetContext().getSystemService(Context.ACTIVITY_SERVICE);
+        store.addResult("low_ram_device", activityManager.isLowRamDevice());
+        store.addResult("memory_class", activityManager.getMemoryClass());
+        store.addResult("large_memory_class", activityManager.getLargeMemoryClass());
+
+        MemoryInfo memoryInfo = new MemoryInfo();
+        activityManager.getMemoryInfo(memoryInfo);
+        store.addResult("total_memory", memoryInfo.totalMem);
+    }
+}
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 1452040..e027d34 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
@@ -19,7 +19,8 @@
 import android.content.pm.PackageManager;
 import android.os.Bundle;
 
-import com.android.compatibility.common.util.InfoStore;
+import com.android.compatibility.common.deviceinfo.DeviceInfo;
+import com.android.compatibility.common.util.DeviceInfoStore;
 
 /**
  * PackageDeviceInfo collector.
@@ -33,8 +34,8 @@
     private static final String PRIV_APP_DIR = "/system/priv-app";
 
     @Override
-    protected void collectDeviceInfo(InfoStore store) throws Exception {
-        PackageManager pm = this.getPackageManager();
+    protected void collectDeviceInfo(DeviceInfoStore store) throws Exception {
+        PackageManager pm = getContext().getPackageManager();
         store.startArray(PACKAGE);
         for (PackageInfo pkg : pm.getInstalledPackages(0)) {
             store.startGroup();
diff --git a/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/PropertyDeviceInfo.java b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/PropertyDeviceInfo.java
new file mode 100644
index 0000000..bb7f1eb
--- /dev/null
+++ b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/PropertyDeviceInfo.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.deviceinfo;
+
+import android.util.Log;
+
+import com.android.compatibility.common.util.DeviceInfoStore;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Scanner;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * System property info collector.
+ */
+public final class PropertyDeviceInfo extends DeviceInfo {
+
+    private static final String LOG_TAG = "PropertyDeviceInfo";
+
+    @Override
+    protected void collectDeviceInfo(DeviceInfoStore store) throws Exception {
+        try {
+            collectRoProperties(store);
+        } catch (IOException e) {
+            Log.w(LOG_TAG, "Failed to collect properties", e);
+        }
+    }
+
+    private void collectRoProperties(DeviceInfoStore store) throws IOException {
+        store.startArray("ro_property");
+        Pattern pattern = Pattern.compile("\\[(ro.+)\\]: \\[(.+)\\]");
+        Scanner scanner = null;
+        try {
+            Process getprop = new ProcessBuilder("getprop").start();
+            scanner = new Scanner(getprop.getInputStream());
+            while (scanner.hasNextLine()) {
+                String line = scanner.nextLine();
+                Matcher matcher = pattern.matcher(line);
+                if (matcher.matches()) {
+                    String name = matcher.group(1);
+                    String value = matcher.group(2);
+
+                    store.startGroup();
+                    store.addResult("name", name);
+                    store.addResult("value", value);
+                    store.endGroup();
+                }
+            }
+        } finally {
+            store.endArray();
+            if (scanner != null) {
+                scanner.close();
+            }
+        }
+    }
+}
diff --git a/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/ScreenDeviceInfo.java b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/ScreenDeviceInfo.java
new file mode 100644
index 0000000..dcd6f54
--- /dev/null
+++ b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/ScreenDeviceInfo.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.deviceinfo;
+
+import android.content.Context;
+import android.content.res.Configuration;
+import android.util.DisplayMetrics;
+import android.view.Display;
+import android.view.WindowManager;
+
+import com.android.compatibility.common.util.DeviceInfoStore;
+
+/**
+ * Screen device info collector.
+ */
+public final class ScreenDeviceInfo extends DeviceInfo {
+
+    @Override
+    protected void collectDeviceInfo(DeviceInfoStore store) throws Exception {
+        DisplayMetrics metrics = new DisplayMetrics();
+        WindowManager windowManager =
+                (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
+        Display display = windowManager.getDefaultDisplay();
+        display.getRealMetrics(metrics);
+
+        store.addResult("width_pixels", metrics.widthPixels);
+        store.addResult("height_pixels", metrics.heightPixels);
+        store.addResult("x_dpi", metrics.xdpi);
+        store.addResult("y_dpi", metrics.ydpi);
+        store.addResult("density", metrics.density);
+        store.addResult("density_dpi", metrics.densityDpi);
+
+        Configuration configuration = getContext().getResources().getConfiguration();
+        store.addResult("screen_size", getScreenSize(configuration));
+        store.addResult("smallest_screen_width_dp", configuration.smallestScreenWidthDp);
+    }
+
+    private static String getScreenSize(Configuration configuration) {
+        int screenLayout = configuration.screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK;
+        String screenSize = String.format("0x%x", screenLayout);
+        switch (screenLayout) {
+            case Configuration.SCREENLAYOUT_SIZE_SMALL:
+                screenSize = "small";
+                break;
+
+            case Configuration.SCREENLAYOUT_SIZE_NORMAL:
+                screenSize = "normal";
+                break;
+
+            case Configuration.SCREENLAYOUT_SIZE_LARGE:
+                screenSize = "large";
+                break;
+
+            case Configuration.SCREENLAYOUT_SIZE_XLARGE:
+                screenSize = "xlarge";
+                break;
+
+            case Configuration.SCREENLAYOUT_SIZE_UNDEFINED:
+                screenSize = "undefined";
+                break;
+        }
+        return screenSize;
+    }
+}
diff --git a/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/StorageDeviceInfo.java b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/StorageDeviceInfo.java
new file mode 100644
index 0000000..dafff35
--- /dev/null
+++ b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/StorageDeviceInfo.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.deviceinfo;
+
+import android.os.Environment;
+import android.util.Log;
+
+import com.android.compatibility.common.util.DeviceInfoStore;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Scanner;
+
+/**
+ * Storage device info collector.
+ */
+public class StorageDeviceInfo extends DeviceInfo {
+    private static final String TAG = "StorageDeviceInfo";
+
+    @Override
+    protected void collectDeviceInfo(DeviceInfoStore store) throws Exception {
+        int total = 0;
+        total = Math.max(total, getContext().getExternalCacheDirs().length);
+        total = Math.max(total, getContext().getExternalFilesDirs(null).length);
+        total = Math.max(
+                total, getContext().getExternalFilesDirs(Environment.DIRECTORY_PICTURES).length);
+        total = Math.max(total, getContext().getObbDirs().length);
+
+        int emulated = 0;
+        int physical = 0;
+        if (Environment.isExternalStorageEmulated()) {
+            if (total == 1) {
+                emulated = 1;
+            } else {
+                emulated = 1;
+                physical = total - 1;
+            }
+        } else {
+            physical = total;
+        }
+
+        store.addResult("num_physical", physical);
+        store.addResult("num_emulated", emulated);
+
+        store.addListResult("raw_partition", scanPartitions());
+    }
+
+    private List<String> scanPartitions() {
+        List<String> partitionList = new ArrayList<>();
+        try {
+            Process df = new ProcessBuilder("df").start();
+            Scanner scanner = new Scanner(df.getInputStream());
+            try {
+                while (scanner.hasNextLine()) {
+                    partitionList.add(scanner.nextLine());
+                }
+            } finally {
+                scanner.close();
+            }
+        } catch (Exception e) {
+            Log.w(TAG, Log.getStackTraceString(e));
+        }
+        return partitionList;
+    }
+
+}
diff --git a/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/UserDeviceInfo.java b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/UserDeviceInfo.java
new file mode 100644
index 0000000..c72b02b
--- /dev/null
+++ b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/UserDeviceInfo.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.deviceinfo;
+
+import android.os.UserManager;
+
+import com.android.compatibility.common.util.DeviceInfoStore;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * User device info collector.
+ */
+public final class UserDeviceInfo extends DeviceInfo {
+
+    @Override
+    protected void collectDeviceInfo(DeviceInfoStore store) throws Exception {
+        store.addResult("max_supported_users", getMaxSupportedUsers());
+    }
+
+    private int getMaxSupportedUsers() {
+        try {
+            Method method = UserManager.class.getMethod("getMaxSupportedUsers");
+            return (Integer) method.invoke(null);
+        } catch (ClassCastException |
+                NoSuchMethodException |
+                InvocationTargetException |
+                IllegalAccessException e) {}
+        return -1;
+    }
+}
diff --git a/common/device-side/device-info/tests/Android.mk b/common/device-side/device-info/tests/Android.mk
index e24c5c1..a8d9e038 100644
--- a/common/device-side/device-info/tests/Android.mk
+++ b/common/device-side/device-info/tests/Android.mk
@@ -27,4 +27,3 @@
 LOCAL_MODULE := compatibility-device-info-tests
 
 include $(BUILD_STATIC_JAVA_LIBRARY)
-
diff --git a/common/device-side/device-info/tests/src/com/android/compatibility/common/deviceinfo/DeviceInfoActivityTest.java b/common/device-side/device-info/tests/src/com/android/compatibility/common/deviceinfo/DeviceInfoActivityTest.java
deleted file mode 100644
index d092f4e..0000000
--- a/common/device-side/device-info/tests/src/com/android/compatibility/common/deviceinfo/DeviceInfoActivityTest.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.compatibility.common.deviceinfo;
-
-import android.test.ActivityInstrumentationTestCase2;
-
-import java.io.BufferedReader;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStreamReader;
-
-/**
- * Test for {@link DeviceInfoActivity}.
- */
-public class DeviceInfoActivityTest extends ActivityInstrumentationTestCase2<TestDeviceInfo> {
-
-    private static final String EXPECTED_FILE_PATH =
-            "/storage/emulated/0/device-info-files/TestDeviceInfo.deviceinfo.json";
-
-    private TestDeviceInfo mActivity;
-
-    public DeviceInfoActivityTest() {
-        super(TestDeviceInfo.class);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        // Start the activity and get a reference to it.
-        mActivity = getActivity();
-        // Wait for the activity to finish.
-        mActivity.waitForActivityToFinish();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        mActivity = null;
-        super.tearDown();
-    }
-
-    public void testJsonFile() throws IOException {
-        String resultFilePath = mActivity.getResultFilePath();
-        // Check file path exist
-        assertNotNull("Expected a non-null resultFilePath", resultFilePath);
-        // Check file path location
-        assertEquals("Incorrect file path", EXPECTED_FILE_PATH, resultFilePath);
-        // Check json file content
-        String jsonContent = readFile(resultFilePath);
-        assertEquals("Incorrect json output", ExampleObjects.testDeviceInfoJson(), jsonContent);
-    }
-
-    private String readFile(String filePath) throws IOException {
-        InputStreamReader inputStreamReader = new InputStreamReader(
-                new FileInputStream(filePath), "UTF-8");
-        StringBuilder stringBuilder = new StringBuilder();
-        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
-        String line;
-        while((line = bufferedReader.readLine()) != null) {
-            stringBuilder.append(line);
-            stringBuilder.append('\n');
-        }
-        bufferedReader.close();
-        return stringBuilder.toString();
-    }
-}
-
diff --git a/common/device-side/device-info/tests/src/com/android/compatibility/common/deviceinfo/DeviceInfoTest.java b/common/device-side/device-info/tests/src/com/android/compatibility/common/deviceinfo/DeviceInfoTest.java
new file mode 100644
index 0000000..3459d59
--- /dev/null
+++ b/common/device-side/device-info/tests/src/com/android/compatibility/common/deviceinfo/DeviceInfoTest.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.deviceinfo;
+
+import android.test.AndroidTestCase;
+import android.test.ActivityInstrumentationTestCase2;
+
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+/**
+ * Test for {@link DeviceInfo}.
+ */
+public class DeviceInfoTest extends AndroidTestCase {
+
+    private static final String EXPECTED_FILE_PATH =
+            "/storage/emulated/0/device-info-files/TestDeviceInfo.deviceinfo.json";
+
+    private TestDeviceInfo testDeviceInfo = new TestDeviceInfo();
+
+    public void testJsonFile() throws Exception {
+        testDeviceInfo.setUp();
+        testDeviceInfo.testCollectDeviceInfo();
+        String resultFilePath = testDeviceInfo.getResultFilePath();
+        // Check file path exist
+        assertNotNull("Expected a non-null resultFilePath", resultFilePath);
+        // Check file path location
+        assertEquals("Incorrect file path", EXPECTED_FILE_PATH, resultFilePath);
+        // Check json file content
+        String jsonContent = readFile(resultFilePath);
+        assertEquals("Incorrect json output", ExampleObjects.testDeviceInfoJson(), jsonContent);
+    }
+
+    private String readFile(String filePath) throws IOException {
+        InputStreamReader inputStreamReader = new InputStreamReader(
+                new FileInputStream(filePath), "UTF-8");
+        StringBuilder stringBuilder = new StringBuilder();
+        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
+        String line;
+        while((line = bufferedReader.readLine()) != null) {
+            stringBuilder.append(line);
+            stringBuilder.append('\n');
+        }
+        bufferedReader.close();
+        return stringBuilder.toString();
+    }
+}
\ No newline at end of file
diff --git a/common/device-side/device-info/tests/src/com/android/compatibility/common/deviceinfo/ExampleObjects.java b/common/device-side/device-info/tests/src/com/android/compatibility/common/deviceinfo/ExampleObjects.java
index 570bdd5..9411cd2 100644
--- a/common/device-side/device-info/tests/src/com/android/compatibility/common/deviceinfo/ExampleObjects.java
+++ b/common/device-side/device-info/tests/src/com/android/compatibility/common/deviceinfo/ExampleObjects.java
@@ -16,12 +16,12 @@
 package com.android.compatibility.common.deviceinfo;
 
 /**
- * Example Objects for {@link DeviceInfoActivity} test package.
+ * Example Objects for {@link DeviceInfo} test package.
  */
 public final class ExampleObjects {
 
-    // Must match DeviceInfoActivity.MAX_STRING_VALUE_LENGTH and
-    // DeviceInfoActivity.MAX_ARRAY_LENGTH
+    // Must match DeviceInfo.MAX_STRING_VALUE_LENGTH and
+    // DeviceInfo.MAX_ARRAY_LENGTH
     private static final int MAX_LENGTH = 1000;
 
     private static final String TEST_DEVICE_INFO_JSON = "{\n" +
diff --git a/common/device-side/device-info/tests/src/com/android/compatibility/common/deviceinfo/TestDeviceInfo.java b/common/device-side/device-info/tests/src/com/android/compatibility/common/deviceinfo/TestDeviceInfo.java
index 96814f5..00acb5b 100644
--- a/common/device-side/device-info/tests/src/com/android/compatibility/common/deviceinfo/TestDeviceInfo.java
+++ b/common/device-side/device-info/tests/src/com/android/compatibility/common/deviceinfo/TestDeviceInfo.java
@@ -22,20 +22,21 @@
 import java.util.HashSet;
 import java.util.List;
 
-import com.android.compatibility.common.util.InfoStore;
+import com.android.compatibility.common.util.DeviceInfoStore;
 
 /**
- * Collector for testing DeviceInfoActivity
+ * Collector for testing DeviceInfo
  */
-public class TestDeviceInfo extends DeviceInfoActivity {
+public class TestDeviceInfo extends DeviceInfo {
 
     @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
+    protected void setUp() throws Exception {
+        mActivityList = new HashSet<String>();
+        mActivityList.add(getClass().getName());
     }
 
     @Override
-    protected void collectDeviceInfo(InfoStore store) throws Exception {
+    protected void collectDeviceInfo(DeviceInfoStore store) throws Exception {
 
         // Test primitive results
         store.addResult("test_boolean", true);
diff --git a/common/device-side/device-setup/Android.mk b/common/device-side/device-setup/Android.mk
deleted file mode 100644
index bc7c504..0000000
--- a/common/device-side/device-setup/Android.mk
+++ /dev/null
@@ -1,43 +0,0 @@
-# Copyright (C) 2014 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_MODULE := compatibility-device-setup_v2
-
-LOCAL_SDK_VERSION := current
-
-include $(BUILD_STATIC_JAVA_LIBRARY)
-
-###############################################################################
-# Build the tests
-###############################################################################
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under, tests/src)
-
-LOCAL_JAVA_LIBRARIES := junit
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_MODULE := compatibility-device-setup-tests_v2
-
-include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/common/device-side/device-setup/src/com/android/compatibility/common/devicesetup/DeviceInfoConstants.java b/common/device-side/device-setup/src/com/android/compatibility/common/devicesetup/DeviceInfoConstants.java
deleted file mode 100644
index 7b19b00..0000000
--- a/common/device-side/device-setup/src/com/android/compatibility/common/devicesetup/DeviceInfoConstants.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.compatibility.common.devicesetup;
-
-/**
- * Constants for device info attributes to be sent as instrumentation keys.
- */
-public interface DeviceInfoConstants {
-
-    public static final String BUILD_ABI = "buildAbi";
-    public static final String BUILD_ABI2 = "buildAbi2";
-    public static final String BUILD_BOARD = "buildBoard";
-    public static final String BUILD_BRAND = "buildBrand";
-    public static final String BUILD_DEVICE = "buildDevice";
-    public static final String BUILD_FINGERPRINT = "buildFingerprint";
-    public static final String BUILD_ID = "buildId";
-    public static final String BUILD_MANUFACTURER = "buildManufacturer";
-    public static final String BUILD_MODEL = "buildModel";
-    public static final String BUILD_TAGS = "buildTags";
-    public static final String BUILD_TYPE = "buildType";
-    public static final String BUILD_VERSION = "buildVersion";
-
-    public static final String FEATURES = "features";
-
-    public static final String GRAPHICS_RENDERER = "graphicsRenderer";
-    public static final String GRAPHICS_VENDOR = "graphicsVendor";
-
-    public static final String IMEI = "imei";
-    public static final String IMSI = "imsi";
-
-    public static final String KEYPAD = "keypad";
-
-    public static final String LOCALES = "locales";
-
-    public static final String MULTI_USER = "multiUser";
-
-    public static final String NAVIGATION = "navigation";
-    public static final String NETWORK = "network";
-
-    public static final String OPEN_GL_ES_VERSION = "openGlEsVersion";
-    public static final String OPEN_GL_EXTENSIONS = "openGlExtensions";
-    public static final String OPEN_GL_COMPRESSED_TEXTURE_FORMATS =
-            "openGlCompressedTextureFormats";
-
-    public static final String PARTITIONS = "partitions";
-    public static final String PHONE_NUMBER = "phoneNumber";
-    public static final String PROCESSES = "processes";
-    public static final String PRODUCT_NAME = "productName";
-
-    public static final String RESOLUTION = "resolution";
-
-    public static final String SCREEN_DENSITY = "screenDensity";
-    public static final String SCREEN_DENSITY_BUCKET = "screenDensityBucket";
-    public static final String SCREEN_DENSITY_X = "screenDensityX";
-    public static final String SCREEN_DENSITY_Y = "screenDensityY";
-    public static final String SCREEN_SIZE = "screenSize";
-    public static final String SERIAL_NUMBER = "deviceId";
-    public static final String STORAGE_DEVICES = "storageDevices";
-    public static final String SYS_LIBRARIES = "systemLibraries";
-
-    public static final String TOUCH = "touch";
-
-    public static final String VERSION_RELEASE = "versionRelease";
-    public static final String VERSION_SDK_INT = "versionSdkInt";
-}
diff --git a/common/device-side/device-setup/tests/src/com/android/compatibility/common/devicesetup/DeviceSetupTest.java b/common/device-side/device-setup/tests/src/com/android/compatibility/common/devicesetup/DeviceSetupTest.java
deleted file mode 100644
index ee55a66..0000000
--- a/common/device-side/device-setup/tests/src/com/android/compatibility/common/devicesetup/DeviceSetupTest.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.compatibility.common.devicesetup;
-
-import junit.framework.TestCase;
-
-public class DeviceSetupTest extends TestCase {
-
-    // TODO(stuartscott): Add tests when there is something to test.
-
-}
diff --git a/common/device-side/preconditions/Android.mk b/common/device-side/preconditions/Android.mk
new file mode 100644
index 0000000..75c981b
--- /dev/null
+++ b/common/device-side/preconditions/Android.mk
@@ -0,0 +1,31 @@
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_STATIC_JAVA_LIBRARIES := compatibility-common-util-devicesidelib
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE := compatibility-device-preconditions
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/common/device-side/preconditions/src/com/android/compatibility/common/preconditions/ExternalStorageHelper.java b/common/device-side/preconditions/src/com/android/compatibility/common/preconditions/ExternalStorageHelper.java
new file mode 100644
index 0000000..f398ea8
--- /dev/null
+++ b/common/device-side/preconditions/src/com/android/compatibility/common/preconditions/ExternalStorageHelper.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.compatibility.common.preconditions;
+
+import android.os.Environment;
+
+/**
+ * ExternalStorageHelper is used to check whether the device's external storage is readable
+ * and writeable.
+ */
+public class ExternalStorageHelper {
+
+    /* Checks if external storage is available for read and write */
+    public static boolean isExternalStorageWritable() {
+        String state = Environment.getExternalStorageState();
+        return Environment.MEDIA_MOUNTED.equals(state);
+    }
+
+    /* Checks if external storage is available to at least read */
+    public static boolean isExternalStorageReadable() {
+        String state = Environment.getExternalStorageState();
+        return (Environment.MEDIA_MOUNTED.equals(state) ||
+                Environment.MEDIA_MOUNTED_READ_ONLY.equals(state));
+    }
+
+}
diff --git a/common/device-side/preconditions/src/com/android/compatibility/common/preconditions/ScreenLockHelper.java b/common/device-side/preconditions/src/com/android/compatibility/common/preconditions/ScreenLockHelper.java
new file mode 100644
index 0000000..385f22f
--- /dev/null
+++ b/common/device-side/preconditions/src/com/android/compatibility/common/preconditions/ScreenLockHelper.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.compatibility.common.preconditions;
+
+import android.app.KeyguardManager;
+import android.content.Context;
+import android.os.Build;
+
+/**
+ * ScreenLockHelper is used to check whether the device is protected by a locked screen.
+ */
+public class ScreenLockHelper {
+
+    /*
+     * This helper returns false for the Screen Lock set to 'Swipe' or 'None', as it seems there
+     * is no way to programmatically distinguish between the two.
+     */
+    public static boolean isDeviceSecure(Context context) {
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
+            return true; // KeyguardManager.isDeviceSecure() added in M, skip this check
+        }
+        KeyguardManager km = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
+        return km.isDeviceSecure();
+    }
+
+}
diff --git a/common/device-side/preconditions/src/com/android/compatibility/common/preconditions/WifiHelper.java b/common/device-side/preconditions/src/com/android/compatibility/common/preconditions/WifiHelper.java
new file mode 100644
index 0000000..ef63544
--- /dev/null
+++ b/common/device-side/preconditions/src/com/android/compatibility/common/preconditions/WifiHelper.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.compatibility.common.preconditions;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.os.Build;
+
+/**
+ * WifiHelper is used to check whether the device is connected to WiFi.
+ * This is required for a subset of the CTS test modules.
+ */
+public class WifiHelper {
+
+    public static boolean isWifiConnected(Context context) {
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
+            return true; // ConnectivityManager.getNetworkInfo() added in LOLLIPOP, skip this check
+        }
+        ConnectivityManager cm = (ConnectivityManager)
+                context.getSystemService(Context.CONNECTIVITY_SERVICE);
+        NetworkInfo wifiNetworkInfo = cm.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
+        return wifiNetworkInfo.isConnected();
+    }
+
+}
diff --git a/common/device-side/test-app/Android.mk b/common/device-side/test-app/Android.mk
new file mode 100755
index 0000000..6adce97
--- /dev/null
+++ b/common/device-side/test-app/Android.mk
@@ -0,0 +1,40 @@
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Build an APK which contains the device-side libraries and their tests,
+# this then gets instrumented in order to test the aforementioned libraries.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_DEX_PREOPT := false
+LOCAL_PROGUARD_ENABLED := disabled
+# don't include this package in any target
+LOCAL_MODULE_TAGS := optional
+# and when built explicitly put it in the data partition
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-test\
+    compatibility-common-util-devicesidelib\
+    compatibility-device-info-tests\
+    compatibility-device-info\
+    compatibility-device-util-tests\
+    compatibility-device-util
+
+LOCAL_PACKAGE_NAME := CompatibilityTestApp
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_PACKAGE)
diff --git a/common/device-side/test-app/AndroidManifest.xml b/common/device-side/test-app/AndroidManifest.xml
new file mode 100755
index 0000000..9c857f0
--- /dev/null
+++ b/common/device-side/test-app/AndroidManifest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.compatibility.common">
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+    <application>
+        <uses-library android:name="android.test.runner" />
+        <activity android:name="com.android.compatibility.common.deviceinfo.TestDeviceInfo" />
+    </application>
+
+    <!--  self-instrumenting test package. -->
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="com.android.compatibility.common"
+                     android:label="Tests for device-side Compatibility common code">
+    </instrumentation>
+
+</manifest>
+
diff --git a/common/device-side/test-app/run_tests.sh b/common/device-side/test-app/run_tests.sh
new file mode 100755
index 0000000..5640260
--- /dev/null
+++ b/common/device-side/test-app/run_tests.sh
@@ -0,0 +1,43 @@
+#!/bin/bash
+
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+CTS_DIR=$(dirname ${0})/../../..
+source ${CTS_DIR}/test_defs.sh
+
+if [ `adb devices | wc -l` -lt 3 ]; then
+    echo "NO DEVICES/EMULATORS AVAILABLE. CONNECT ONE."
+    exit 1
+fi
+
+# Take the last serial in the list of devices
+SERIAL=`adb devices | egrep -o "^\w+" | tail -n1`
+if [ -z ${SERIAL} ]; then
+    echo "FAILED TO GET ADB DEVICE SERIAL FOR TEST. EXITING"
+    exit 1
+fi
+
+echo "Running device side tests on device: ${SERIAL}"
+
+APK=${ANDROID_PRODUCT_OUT}/data/app/CompatibilityTestApp/CompatibilityTestApp.apk
+checkFile ${APK}
+
+COMMON_PACKAGE=com.android.compatibility.common
+RUNNER=android.support.test.runner.AndroidJUnitRunner
+# TODO [2015-12-09 kalle] Fail & exit on failing install?
+adb -s ${SERIAL} install -r -g ${APK}
+build_jar_path ${JAR_DIR} "${JARS}"
+java $RDBG_FLAG -cp ${JAR_PATH} ${TF_CONSOLE} run singleCommand instrument --serial ${SERIAL} --package ${COMMON_PACKAGE} --runner ${RUNNER}
+adb -s ${SERIAL} uninstall ${COMMON_PACKAGE}
diff --git a/common/device-side/util/Android.mk b/common/device-side/util/Android.mk
index c8104bf..350c2db 100644
--- a/common/device-side/util/Android.mk
+++ b/common/device-side/util/Android.mk
@@ -12,34 +12,20 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-LOCAL_PATH:= $(call my-dir)
+LOCAL_PATH := $(call my-dir)
 
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
-LOCAL_STATIC_JAVA_LIBRARIES := compatibility-common-util-devicesidelib_v2
+LOCAL_STATIC_JAVA_LIBRARIES := compatibility-common-util-devicesidelib
 
 LOCAL_MODULE_TAGS := optional
 
-LOCAL_MODULE := compatibility-device-util_v2
+LOCAL_MODULE := compatibility-device-util
 
 LOCAL_SDK_VERSION := current
 
 include $(BUILD_STATIC_JAVA_LIBRARY)
 
-################################################################################
-# Build the tests
-###############################################################################
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under, tests/src)
-
-LOCAL_JAVA_LIBRARIES := junit
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_MODULE := compatibility-device-util-tests_v2
-
-include $(BUILD_HOST_JAVA_LIBRARY)
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/DeviceInfoStore.java b/common/device-side/util/src/com/android/compatibility/common/util/DeviceInfoStore.java
new file mode 100644
index 0000000..9f1bda5
--- /dev/null
+++ b/common/device-side/util/src/com/android/compatibility/common/util/DeviceInfoStore.java
@@ -0,0 +1,256 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.util;
+
+import android.util.JsonWriter;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.List;
+
+public class DeviceInfoStore extends InfoStore {
+
+    protected File mJsonFile;
+    protected JsonWriter mJsonWriter = null;
+
+    public DeviceInfoStore() {
+        mJsonFile = null;
+    }
+
+    public DeviceInfoStore(File file) throws Exception {
+        mJsonFile = file;
+    }
+
+    /**
+     * Opens the file for storage and creates the writer.
+     */
+    @Override
+    public void open() throws IOException {
+        FileOutputStream out = new FileOutputStream(mJsonFile);
+        mJsonWriter = new JsonWriter(new OutputStreamWriter(out, StandardCharsets.UTF_8));
+        // TODO(agathaman): remove to make json output less pretty
+        mJsonWriter.setIndent("  ");
+        mJsonWriter.beginObject();
+    }
+
+    /**
+     * Closes the writer.
+     */
+    @Override
+    public void close() throws IOException {
+        mJsonWriter.endObject();
+        mJsonWriter.close();
+    }
+
+    /**
+     * Start a new group of result.
+     */
+    @Override
+    public void startGroup() throws IOException {
+        mJsonWriter.beginObject();
+    }
+
+    /**
+     * Start a new group of result with specified name.
+     */
+    @Override
+    public void startGroup(String name) throws IOException {
+        mJsonWriter.name(name);
+        mJsonWriter.beginObject();
+    }
+
+    /**
+     * Complete adding result to the last started group.
+     */
+    @Override
+    public void endGroup() throws IOException {
+        mJsonWriter.endObject();
+    }
+
+    /**
+     * Start a new array of result.
+     */
+    @Override
+    public void startArray() throws IOException {
+        mJsonWriter.beginArray();
+    }
+
+    /**
+     * Start a new array of result with specified name.
+     */
+    @Override
+    public void startArray(String name) throws IOException {
+        checkName(name);
+        mJsonWriter.name(name);
+        mJsonWriter.beginArray();
+    }
+
+    /**
+     * Complete adding result to the last started array.
+     */
+    @Override
+    public void endArray() throws IOException {
+        mJsonWriter.endArray();
+    }
+
+    /**
+     * Adds a int value to the InfoStore
+     */
+    @Override
+    public void addResult(String name, int value) throws IOException {
+        checkName(name);
+        mJsonWriter.name(name);
+        mJsonWriter.value(value);
+    }
+
+    /**
+     * Adds a long value to the InfoStore
+     */
+    @Override
+    public void addResult(String name, long value) throws IOException {
+        checkName(name);
+        mJsonWriter.name(name);
+        mJsonWriter.value(value);
+    }
+
+    /**
+     * Adds a float value to the InfoStore
+     */
+    @Override
+    public void addResult(String name, float value) throws IOException {
+        checkName(name);
+        mJsonWriter.name(name);
+        mJsonWriter.value(value);
+    }
+
+    /**
+     * Adds a double value to the InfoStore
+     */
+    @Override
+    public void addResult(String name, double value) throws IOException {
+        checkName(name);
+        mJsonWriter.name(name);
+        mJsonWriter.value(value);
+    }
+
+    /**
+     * Adds a boolean value to the InfoStore
+     */
+    @Override
+    public void addResult(String name, boolean value) throws IOException {
+        checkName(name);
+        mJsonWriter.name(name);
+        mJsonWriter.value(value);
+    }
+
+    /**
+     * Adds a String value to the InfoStore
+     */
+    @Override
+    public void addResult(String name, String value) throws IOException {
+        checkName(name);
+        mJsonWriter.name(name);
+        mJsonWriter.value(checkString(value));
+    }
+
+    /**
+     * Adds a int array to the InfoStore
+     */
+    @Override
+    public void addArrayResult(String name, int[] array) throws IOException {
+        checkName(name);
+        mJsonWriter.name(name);
+        mJsonWriter.beginArray();
+        for (int value : checkArray(array)) {
+            mJsonWriter.value(value);
+        }
+        mJsonWriter.endArray();
+    }
+
+    /**
+     * Adds a long array to the InfoStore
+     */
+    @Override
+    public void addArrayResult(String name, long[] array) throws IOException {
+        checkName(name);
+        mJsonWriter.name(name);
+        mJsonWriter.beginArray();
+        for (long value : checkArray(array)) {
+            mJsonWriter.value(value);
+        }
+        mJsonWriter.endArray();
+    }
+
+    /**
+     * Adds a float array to the InfoStore
+     */
+    @Override
+    public void addArrayResult(String name, float[] array) throws IOException {
+        checkName(name);
+        mJsonWriter.name(name);
+        mJsonWriter.beginArray();
+        for (float value : checkArray(array)) {
+            mJsonWriter.value(value);
+        }
+        mJsonWriter.endArray();
+    }
+
+    /**
+     * Adds a double array to the InfoStore
+     */
+    @Override
+    public void addArrayResult(String name, double[] array) throws IOException {
+        checkName(name);
+        mJsonWriter.name(name);
+        mJsonWriter.beginArray();
+        for (double value : checkArray(array)) {
+            mJsonWriter.value(value);
+        }
+        mJsonWriter.endArray();
+    }
+
+    /**
+     * Adds a boolean array to the InfoStore
+     */
+    @Override
+    public void addArrayResult(String name, boolean[] array) throws IOException {
+        checkName(name);
+        mJsonWriter.name(name);
+        mJsonWriter.beginArray();
+        for (boolean value : checkArray(array)) {
+            mJsonWriter.value(value);
+        }
+        mJsonWriter.endArray();
+    }
+
+    /**
+     * Adds a List of String to the InfoStore
+     */
+    @Override
+    public void addListResult(String name, List<String> list) throws IOException {
+        checkName(name);
+        mJsonWriter.name(name);
+        mJsonWriter.beginArray();
+        for (String value : checkStringList(list)) {
+            mJsonWriter.value(checkString(value));
+        }
+        mJsonWriter.endArray();
+    }
+}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/DeviceReportLog.java b/common/device-side/util/src/com/android/compatibility/common/util/DeviceReportLog.java
index 273cdf5..cb81d0b 100644
--- a/common/device-side/util/src/com/android/compatibility/common/util/DeviceReportLog.java
+++ b/common/device-side/util/src/com/android/compatibility/common/util/DeviceReportLog.java
@@ -18,10 +18,16 @@
 
 import android.app.Instrumentation;
 import android.os.Bundle;
+import android.os.Environment;
 import android.util.Log;
 
 import com.android.compatibility.common.util.ReportLog;
 
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.File;
+import java.io.IOException;
+
 /**
  * Handles adding results to the report for device side tests.
  *
@@ -30,13 +36,94 @@
  */
 public class DeviceReportLog extends ReportLog {
     private static final String TAG = DeviceReportLog.class.getSimpleName();
-    private static final String RESULT = "RESULT";
+    private static final String RESULT = "COMPATIBILITY_TEST_RESULT";
+    // TODO(mishragaurav): Remove default names and constructor after fixing b/27950009.
+    private static final String DEFAULT_REPORT_LOG_NAME = "DefaultDeviceTestMetrics";
+    private static final String DEFAULT_STREAM_NAME = "DefaultStream";
+    private static final int INST_STATUS_ERROR = -1;
     private static final int INST_STATUS_IN_PROGRESS = 2;
 
+    private ReportLogDeviceInfoStore store;
+
+    public DeviceReportLog() {
+        this(DEFAULT_REPORT_LOG_NAME, DEFAULT_STREAM_NAME);
+    }
+
+    public DeviceReportLog(String reportLogName) {
+        this(reportLogName, DEFAULT_STREAM_NAME);
+    }
+
+    public DeviceReportLog(String reportLogName, String streamName) {
+        super(reportLogName, streamName);
+        try {
+            final File dir = new File(Environment.getExternalStorageDirectory(), "report-log-files");
+            if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
+                throw new IOException("External storage is not mounted");
+            } else if (!dir.mkdirs() && !dir.isDirectory()) {
+                throw new IOException("Cannot create directory for device info files");
+            } else {
+                File jsonFile = new File(dir, mReportLogName + ".reportlog.json");
+                store = new ReportLogDeviceInfoStore(jsonFile, mStreamName);
+                store.open();
+            }
+        } catch (Exception e) {
+            Log.e(TAG, "Could not create report log file.");
+        }
+    }
+
+    @Override
+    public void addValue(String source, String message, double value, ResultType type,
+            ResultUnit unit) {
+        super.addValue(source, message, value, type, unit);
+        try {
+            store.addResult(message, value);
+        } catch (IOException e) {
+            Log.e(TAG, "Could not log metric.", e);
+        }
+    }
+
+    @Override
+    public void addValue(String message, double value, ResultType type, ResultUnit unit) {
+        super.addValue(message, value, type, unit);
+        try {
+            store.addResult(message, value);
+        } catch (IOException e) {
+            Log.e(TAG, "Could not log metric.", e);
+        }
+    }
+
+    @Override
+    public void addValues(String source, String message, double[] values, ResultType type,
+            ResultUnit unit) {
+        super.addValues(source, message, values, type, unit);
+        try {
+            store.addArrayResult(message, values);
+        } catch (IOException e) {
+            Log.e(TAG, "Could not log metric.", e);
+        }
+    }
+
+    @Override
+    public void addValues(String message, double[] values, ResultType type, ResultUnit unit) {
+        super.addValues(message, values, type, unit);
+        try {
+            store.addArrayResult(message, values);
+        } catch (IOException e) {
+            Log.e(TAG, "Could not log metric.", e);
+        }
+    }
+
     public void submit(Instrumentation instrumentation) {
-        Log.i(TAG, "submit");
-        Bundle output = new Bundle();
-        output.putSerializable(RESULT, this);
-        instrumentation.sendStatus(INST_STATUS_IN_PROGRESS, output);
+        Log.i(TAG, "Submit");
+        try {
+            store.close();
+            Bundle output = new Bundle();
+            output.putString(RESULT, serialize(this));
+            instrumentation.sendStatus(INST_STATUS_IN_PROGRESS, output);
+        } catch (IllegalArgumentException | IllegalStateException | XmlPullParserException
+                | IOException e) {
+            Log.e(TAG, "Submit Failed", e);
+            instrumentation.sendStatus(INST_STATUS_ERROR, null);
+        }
     }
 }
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/DynamicConfigDeviceSide.java b/common/device-side/util/src/com/android/compatibility/common/util/DynamicConfigDeviceSide.java
new file mode 100644
index 0000000..b50b4f7
--- /dev/null
+++ b/common/device-side/util/src/com/android/compatibility/common/util/DynamicConfigDeviceSide.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.compatibility.common.util;
+
+import android.os.Environment;
+import android.util.Log;
+
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * Load dynamic config for device side test cases
+ */
+public class DynamicConfigDeviceSide extends DynamicConfig {
+
+    private static String LOG_TAG = DynamicConfigDeviceSide.class.getSimpleName();
+
+    public DynamicConfigDeviceSide(String moduleName) throws XmlPullParserException, IOException {
+        if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
+            throw new IOException("External storage is not mounted");
+        }
+        File configFile = getConfigFile(new File(CONFIG_FOLDER_ON_DEVICE), moduleName);
+        initializeConfig(configFile);
+    }
+}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/EvaluateJsResultPollingCheck.java b/common/device-side/util/src/com/android/compatibility/common/util/EvaluateJsResultPollingCheck.java
index 521dc40..61f1bb8 100644
--- a/common/device-side/util/src/com/android/compatibility/common/util/EvaluateJsResultPollingCheck.java
+++ b/common/device-side/util/src/com/android/compatibility/common/util/EvaluateJsResultPollingCheck.java
@@ -18,7 +18,7 @@
 
 import android.webkit.ValueCallback;
 
-public class EvaluateJsResultPollingCheck  extends PollingCheck
+public class EvaluateJsResultPollingCheck extends PollingCheck
         implements ValueCallback<String> {
     private String mActualResult;
     private String mExpectedResult;
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/InfoStore.java b/common/device-side/util/src/com/android/compatibility/common/util/InfoStore.java
deleted file mode 100644
index 62decdc..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/InfoStore.java
+++ /dev/null
@@ -1,301 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.compatibility.common.util;
-
-import android.util.JsonWriter;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStreamWriter;
-import java.nio.charset.StandardCharsets;
-import java.io.Serializable;
-import java.util.Arrays;
-import java.util.List;
-
-public class InfoStore {
-
-    private static final int MAX_STRING_LENGTH = 1000;
-    private static final int MAX_ARRAY_LENGTH = 1000;
-    private static final int MAX_LIST_LENGTH = 1000;
-
-    private final File mJsonFile;
-    private JsonWriter mJsonWriter = null;
-
-    public InfoStore(File file) throws Exception {
-        mJsonFile = file;
-    }
-
-    /**
-     * Opens the file for storage and creates the writer.
-     */
-    public void open() throws IOException {
-        FileOutputStream out = new FileOutputStream(mJsonFile);
-        mJsonWriter = new JsonWriter(new OutputStreamWriter(out, StandardCharsets.UTF_8));
-        // TODO(agathaman): remove to make json output less pretty
-        mJsonWriter.setIndent("  ");
-        mJsonWriter.beginObject();
-    }
-
-    /**
-     * Closes the writer.
-     */
-    public void close() throws IOException {
-        mJsonWriter.endObject();
-        mJsonWriter.close();
-    }
-
-    /**
-     * Start a new group of result.
-     */
-    public void startGroup() throws IOException {
-        mJsonWriter.beginObject();
-    }
-
-    /**
-     * Start a new group of result with specified name.
-     */
-    public void startGroup(String name) throws IOException {
-        mJsonWriter.name(name);
-        mJsonWriter.beginObject();
-    }
-
-    /**
-     * Complete adding result to the last started group.
-     */
-    public void endGroup() throws IOException {
-        mJsonWriter.endObject();
-    }
-
-    /**
-     * Start a new array of result.
-     */
-    public void startArray() throws IOException {
-        mJsonWriter.beginArray();
-    }
-
-    /**
-     * Start a new array of result with specified name.
-     */
-    public void startArray(String name) throws IOException {
-        checkName(name);
-        mJsonWriter.name(name);
-        mJsonWriter.beginArray();
-    }
-
-    /**
-     * Complete adding result to the last started array.
-     */
-    public void endArray() throws IOException {
-        mJsonWriter.endArray();
-    }
-
-    /**
-     * Adds a int value to the InfoStore
-     */
-    public void addResult(String name, int value) throws IOException {
-        checkName(name);
-        mJsonWriter.name(name);
-        mJsonWriter.value(value);
-    }
-
-    /**
-     * Adds a long value to the InfoStore
-     */
-    public void addResult(String name, long value) throws IOException {
-        checkName(name);
-        mJsonWriter.name(name);
-        mJsonWriter.value(value);
-    }
-
-    /**
-     * Adds a float value to the InfoStore
-     */
-    public void addResult(String name, float value) throws IOException {
-        checkName(name);
-        mJsonWriter.name(name);
-        mJsonWriter.value(value);
-    }
-
-    /**
-     * Adds a double value to the InfoStore
-     */
-    public void addResult(String name, double value) throws IOException {
-        checkName(name);
-        mJsonWriter.name(name);
-        mJsonWriter.value(value);
-    }
-
-    /**
-     * Adds a boolean value to the InfoStore
-     */
-    public void addResult(String name, boolean value) throws IOException {
-        checkName(name);
-        mJsonWriter.name(name);
-        mJsonWriter.value(value);
-    }
-
-    /**
-     * Adds a String value to the InfoStore
-     */
-    public void addResult(String name, String value) throws IOException {
-        checkName(name);
-        mJsonWriter.name(name);
-        mJsonWriter.value(checkString(value));
-    }
-
-    /**
-     * Adds a int array to the InfoStore
-     */
-    public void addArrayResult(String name, int[] array) throws IOException {
-        checkName(name);
-        mJsonWriter.name(name);
-        mJsonWriter.beginArray();
-        for (int value : checkArray(array)) {
-            mJsonWriter.value(value);
-        }
-        mJsonWriter.endArray();
-    }
-
-    /**
-     * Adds a long array to the InfoStore
-     */
-    public void addArrayResult(String name, long[] array) throws IOException {
-        checkName(name);
-        mJsonWriter.name(name);
-        mJsonWriter.beginArray();
-        for (long value : checkArray(array)) {
-            mJsonWriter.value(value);
-        }
-        mJsonWriter.endArray();
-    }
-
-    /**
-     * Adds a float array to the InfoStore
-     */
-    public void addArrayResult(String name, float[] array) throws IOException {
-        checkName(name);
-        mJsonWriter.name(name);
-        mJsonWriter.beginArray();
-        for (float value : checkArray(array)) {
-            mJsonWriter.value(value);
-        }
-        mJsonWriter.endArray();
-    }
-
-    /**
-     * Adds a double array to the InfoStore
-     */
-    public void addArrayResult(String name, double[] array) throws IOException {
-        checkName(name);
-        mJsonWriter.name(name);
-        mJsonWriter.beginArray();
-        for (double value : checkArray(array)) {
-            mJsonWriter.value(value);
-        }
-        mJsonWriter.endArray();
-    }
-
-    /**
-     * Adds a boolean array to the InfoStore
-     */
-    public void addArrayResult(String name, boolean[] array) throws IOException {
-        checkName(name);
-        mJsonWriter.name(name);
-        mJsonWriter.beginArray();
-        for (boolean value : checkArray(array)) {
-            mJsonWriter.value(value);
-        }
-        mJsonWriter.endArray();
-    }
-
-    /**
-     * Adds a List of String to the InfoStore
-     */
-    public void addListResult(String name, List<String> list) throws IOException {
-        checkName(name);
-        mJsonWriter.name(name);
-        mJsonWriter.beginArray();
-        for (String value : checkStringList(list)) {
-            mJsonWriter.value(checkString(value));
-        }
-        mJsonWriter.endArray();
-    }
-
-    private static int[] checkArray(int[] values) {
-        if (values.length > MAX_ARRAY_LENGTH) {
-            return Arrays.copyOf(values, MAX_ARRAY_LENGTH);
-        } else {
-            return values;
-        }
-    }
-
-    private static long[] checkArray(long[] values) {
-        if (values.length > MAX_ARRAY_LENGTH) {
-            return Arrays.copyOf(values, MAX_ARRAY_LENGTH);
-        } else {
-            return values;
-        }
-    }
-
-    private static float[] checkArray(float[] values) {
-        if (values.length > MAX_ARRAY_LENGTH) {
-            return Arrays.copyOf(values, MAX_ARRAY_LENGTH);
-        } else {
-            return values;
-        }
-    }
-
-    private static double[] checkArray(double[] values) {
-        if (values.length > MAX_ARRAY_LENGTH) {
-            return Arrays.copyOf(values, MAX_ARRAY_LENGTH);
-        } else {
-            return values;
-        }
-    }
-
-    private static boolean[] checkArray(boolean[] values) {
-        if (values.length > MAX_ARRAY_LENGTH) {
-            return Arrays.copyOf(values, MAX_ARRAY_LENGTH);
-        } else {
-            return values;
-        }
-    }
-
-    private static List<String> checkStringList(List<String> list) {
-        if (list.size() > MAX_LIST_LENGTH) {
-            return list.subList(0, MAX_LIST_LENGTH);
-        }
-        return list;
-    }
-
-    private static String checkString(String value) {
-        if (value == null || value.isEmpty()) {
-            return "null";
-        }
-        if (value.length() > MAX_STRING_LENGTH) {
-            return value.substring(0, MAX_STRING_LENGTH);
-        }
-        return value;
-    }
-
-    private static String checkName(String value) {
-        if (value == null || value.isEmpty()) {
-            throw new NullPointerException();
-        }
-        return value;
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/ReportLogDeviceInfoStore.java b/common/device-side/util/src/com/android/compatibility/common/util/ReportLogDeviceInfoStore.java
new file mode 100644
index 0000000..fd61b08
--- /dev/null
+++ b/common/device-side/util/src/com/android/compatibility/common/util/ReportLogDeviceInfoStore.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.util;
+
+import android.util.JsonWriter;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+
+public class ReportLogDeviceInfoStore extends DeviceInfoStore {
+
+    private final String mStreamName;
+
+    public ReportLogDeviceInfoStore(File jsonFile, String streamName) throws Exception {
+        mJsonFile = jsonFile;
+        mStreamName = streamName;
+    }
+
+    /**
+     * Creates the writer and starts the JSON Object for the metric stream.
+     */
+    @Override
+    public void open() throws IOException {
+        BufferedWriter formatWriter;
+        String oldMetrics;
+        if (mJsonFile.exists()) {
+            BufferedReader jsonReader = new BufferedReader(new FileReader(mJsonFile));
+            StringBuilder oldMetricsBuilder = new StringBuilder();
+            String line;
+            while ((line = jsonReader.readLine()) != null) {
+                oldMetricsBuilder.append(line);
+            }
+            oldMetrics = oldMetricsBuilder.toString().trim();
+            if (oldMetrics.charAt(oldMetrics.length() - 1) == '}') {
+                oldMetrics = oldMetrics.substring(0, oldMetrics.length() - 1);
+            }
+            oldMetrics = oldMetrics + ",";
+        } else {
+            oldMetrics = "{";
+        }
+        mJsonFile.createNewFile();
+        formatWriter = new BufferedWriter(new FileWriter(mJsonFile));
+        formatWriter.write(oldMetrics + "\"" + mStreamName + "\":", 0, oldMetrics.length() +
+                mStreamName.length() + 3);
+        formatWriter.flush();
+        formatWriter.close();
+        mJsonWriter = new JsonWriter(new FileWriter(mJsonFile, true));
+        mJsonWriter.beginObject();
+    }
+
+    /**
+     * Closes the writer.
+     */
+    @Override
+    public void close() throws IOException {
+        mJsonWriter.endObject();
+        mJsonWriter.close();
+        // Close the overall JSON object
+        BufferedWriter formatWriter = new BufferedWriter(new FileWriter(mJsonFile, true));
+        formatWriter.write("}", 0, 1);
+        formatWriter.flush();
+        formatWriter.close();
+    }
+}
diff --git a/common/device-side/util/tests/Android.mk b/common/device-side/util/tests/Android.mk
new file mode 100644
index 0000000..fa7424d
--- /dev/null
+++ b/common/device-side/util/tests/Android.mk
@@ -0,0 +1,27 @@
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_STATIC_JAVA_LIBRARIES := compatibility-device-util
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE := compatibility-device-util-tests
+
+include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/common/device-side/util/tests/src/com/android/compatibility/common/util/DeviceReportTest.java b/common/device-side/util/tests/src/com/android/compatibility/common/util/DeviceReportTest.java
new file mode 100644
index 0000000..25fb4d7
--- /dev/null
+++ b/common/device-side/util/tests/src/com/android/compatibility/common/util/DeviceReportTest.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+package com.android.compatibility.common.util;
+
+import android.app.Instrumentation;
+import android.os.Bundle;
+import android.os.Environment;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.lang.StringBuilder;
+
+import junit.framework.TestCase;
+
+import org.json.JSONObject;
+
+/**
+ * Tests for {@line DeviceReportLog}.
+ */
+public class DeviceReportTest extends TestCase {
+
+    /**
+     * A stub of {@link Instrumentation}
+     */
+    public class TestInstrumentation extends Instrumentation {
+
+        private int mResultCode = -1;
+        private Bundle mResults = null;
+
+        @Override
+        public void sendStatus(int resultCode, Bundle results) {
+            mResultCode = resultCode;
+            mResults = results;
+        }
+    }
+
+    private static final int RESULT_CODE = 2;
+    private static final String RESULT_KEY = "COMPATIBILITY_TEST_RESULT";
+    private static final String TEST_MESSAGE_1 = "Foo";
+    private static final double TEST_VALUE_1 = 3;
+    private static final ResultType TEST_TYPE_1 = ResultType.HIGHER_BETTER;
+    private static final ResultUnit TEST_UNIT_1 = ResultUnit.SCORE;
+    private static final String TEST_MESSAGE_2 = "Bar";
+    private static final double TEST_VALUE_2 = 5;
+    private static final ResultType TEST_TYPE_2 = ResultType.LOWER_BETTER;
+    private static final ResultUnit TEST_UNIT_2 = ResultUnit.COUNT;
+    private static final String TEST_MESSAGE_3 = "Sample";
+    private static final double TEST_VALUE_3 = 7;
+    private static final ResultType TEST_TYPE_3 = ResultType.LOWER_BETTER;
+    private static final ResultUnit TEST_UNIT_3 = ResultUnit.COUNT;
+    private static final String TEST_MESSAGE_4 = "Message";
+    private static final double TEST_VALUE_4 = 9;
+    private static final ResultType TEST_TYPE_4 = ResultType.LOWER_BETTER;
+    private static final ResultUnit TEST_UNIT_4 = ResultUnit.COUNT;
+    private static final String REPORT_NAME_1 = "TestReport1";
+    private static final String REPORT_NAME_2 = "TestReport2";
+    private static final String STREAM_NAME_1 = "SampleStream1";
+    private static final String STREAM_NAME_2 = "SampleStream2";
+    private static final String STREAM_NAME_3 = "SampleStream3";
+    private static final String STREAM_NAME_4 = "SampleStream4";
+
+    public void testSubmit() throws Exception {
+        DeviceReportLog log = new DeviceReportLog();
+        log.addValue(TEST_MESSAGE_1, TEST_VALUE_1, TEST_TYPE_1, TEST_UNIT_1);
+        log.setSummary(TEST_MESSAGE_2, TEST_VALUE_2, TEST_TYPE_2, TEST_UNIT_2);
+        TestInstrumentation inst = new TestInstrumentation();
+        log.submit(inst);
+        assertEquals("Incorrect result code", RESULT_CODE, inst.mResultCode);
+        assertNotNull("Bundle missing", inst.mResults);
+        String metrics = inst.mResults.getString(RESULT_KEY);
+        assertNotNull("Metrics missing", metrics);
+        ReportLog result = ReportLog.parse(metrics);
+        assertNotNull("Metrics could not be decoded", result);
+    }
+
+    public void testFile() throws Exception {
+        assertTrue("External storage is not mounted",
+                Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED));
+        final File dir = new File(Environment.getExternalStorageDirectory(), "report-log-files");
+        assertTrue("Report Log directory missing", dir.isDirectory() || dir.mkdirs());
+
+        // Remove files from earlier possible runs.
+        File[] files = dir.listFiles();
+        for (File file : files) {
+            file.delete();
+        }
+
+        TestInstrumentation inst = new TestInstrumentation();
+
+        DeviceReportLog log1 = new DeviceReportLog(REPORT_NAME_1, STREAM_NAME_1);
+        log1.addValue(TEST_MESSAGE_1, TEST_VALUE_1, TEST_TYPE_1, TEST_UNIT_1);
+        log1.setSummary(TEST_MESSAGE_1, TEST_VALUE_1, TEST_TYPE_1, TEST_UNIT_1);
+        log1.submit(inst);
+
+        DeviceReportLog log2 = new DeviceReportLog(REPORT_NAME_1, STREAM_NAME_2);
+        log2.addValue(TEST_MESSAGE_2, TEST_VALUE_2, TEST_TYPE_2, TEST_UNIT_2);
+        log2.setSummary(TEST_MESSAGE_2, TEST_VALUE_2, TEST_TYPE_2, TEST_UNIT_2);
+        log2.submit(inst);
+
+        DeviceReportLog log3 = new DeviceReportLog(REPORT_NAME_2, STREAM_NAME_3);
+        log3.addValue(TEST_MESSAGE_3, TEST_VALUE_3, TEST_TYPE_3, TEST_UNIT_3);
+        log3.setSummary(TEST_MESSAGE_3, TEST_VALUE_3, TEST_TYPE_3, TEST_UNIT_3);
+        log3.submit(inst);
+
+        DeviceReportLog log4 = new DeviceReportLog(REPORT_NAME_2, STREAM_NAME_4);
+        log4.addValue(TEST_MESSAGE_4, TEST_VALUE_4, TEST_TYPE_4, TEST_UNIT_4);
+        log4.setSummary(TEST_MESSAGE_4, TEST_VALUE_4, TEST_TYPE_4, TEST_UNIT_4);
+        log4.submit(inst);
+
+        File jsonFile1 = new File(dir, REPORT_NAME_1 + ".reportlog.json");
+        File jsonFile2 = new File(dir, REPORT_NAME_2 + ".reportlog.json");
+        assertTrue("Report Log missing", jsonFile1.exists());
+        assertTrue("Report Log missing", jsonFile2.exists());
+
+        BufferedReader jsonReader = new BufferedReader(new FileReader(jsonFile1));
+        StringBuilder metricsBuilder = new StringBuilder();
+        String line;
+        while ((line = jsonReader.readLine()) != null) {
+            metricsBuilder.append(line);
+        }
+        String metrics = metricsBuilder.toString().trim();
+        JSONObject jsonObject = new JSONObject(metrics);
+        assertTrue("Incorrect metrics",
+                jsonObject.getJSONObject(STREAM_NAME_1).getDouble(TEST_MESSAGE_1) == TEST_VALUE_1);
+        assertTrue("Incorrect metrics",
+                jsonObject.getJSONObject(STREAM_NAME_2).getDouble(TEST_MESSAGE_2) == TEST_VALUE_2);
+
+        jsonReader = new BufferedReader(new FileReader(jsonFile2));
+        metricsBuilder = new StringBuilder();
+        while ((line = jsonReader.readLine()) != null) {
+            metricsBuilder.append(line);
+        }
+        metrics = metricsBuilder.toString().trim();
+        jsonObject = new JSONObject(metrics);
+        assertTrue("Incorrect metrics",
+                jsonObject.getJSONObject(STREAM_NAME_3).getDouble(TEST_MESSAGE_3) == TEST_VALUE_3);
+        assertTrue("Incorrect metrics",
+                jsonObject.getJSONObject(STREAM_NAME_4).getDouble(TEST_MESSAGE_4) == TEST_VALUE_4);
+    }
+}
diff --git a/common/device-side/util/tests/src/com/android/compatibility/common/util/DeviceUtilTest.java b/common/device-side/util/tests/src/com/android/compatibility/common/util/DeviceUtilTest.java
deleted file mode 100644
index a7e81d7..0000000
--- a/common/device-side/util/tests/src/com/android/compatibility/common/util/DeviceUtilTest.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.compatibility.common.util;
-
-import junit.framework.TestCase;
-
-public class DeviceUtilTest extends TestCase {
-
-}
diff --git a/common/host-side/java-scanner/Android.mk b/common/host-side/java-scanner/Android.mk
deleted file mode 100644
index 7c101ff..0000000
--- a/common/host-side/java-scanner/Android.mk
+++ /dev/null
@@ -1,47 +0,0 @@
-# Copyright (C) 2014 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_JAVA_LIBRARIES := compatibility-common-util-hostsidelib_v2
-
-LOCAL_JAR_MANIFEST := MANIFEST.mf
-
-LOCAL_CLASSPATH := $(HOST_JDK_TOOLS_JAR)
-
-LOCAL_MODULE := compatibility-java-scanner_v2
-
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_HOST_JAVA_LIBRARY)
-
-################################################################################
-# Build the tests
-###############################################################################
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under, tests/src)
-
-LOCAL_JAVA_LIBRARIES := compatibility-tradefed_v2 compatibility-java-scanner_v2 junit
-
-LOCAL_MODULE := compatibility-java-scanner-tests_v2
-
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/common/host-side/java-scanner/MANIFEST.mf b/common/host-side/java-scanner/MANIFEST.mf
deleted file mode 100644
index 975b1ef..0000000
--- a/common/host-side/java-scanner/MANIFEST.mf
+++ /dev/null
@@ -1,3 +0,0 @@
-Manifest-Version: 1.0
-Main-Class: com.android.compatibility.common.scanner.JavaScanner
-Class-Path: compatibility-common-util-hostsidelib_v2.jar
diff --git a/common/host-side/java-scanner/src/com/android/compatibility/common/scanner/JavaScanner.java b/common/host-side/java-scanner/src/com/android/compatibility/common/scanner/JavaScanner.java
deleted file mode 100644
index f3f8a49..0000000
--- a/common/host-side/java-scanner/src/com/android/compatibility/common/scanner/JavaScanner.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.compatibility.common.scanner;
-
-import com.android.compatibility.common.util.KeyValueArgsParser;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileFilter;
-import java.io.InputStreamReader;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-
-/**
- * Scans a source directory for java tests and outputs a list of test classes and methods.
- */
-public class JavaScanner {
-
-    static final String[] SOURCE_PATHS = {
-        "./frameworks/base/core/java",
-        "./frameworks/base/test-runner/src",
-        "./external/junit/src",
-        "./development/tools/hosttestlib/src",
-        "./libcore/dalvik/src/main/java",
-        "./common/device-side/util/src",
-        "./common/host-side/tradefed/src",
-        "./common/util/src"
-    };
-    static final String[] CLASS_PATHS = {
-        "./prebuilts/misc/common/tradefed/tradefed-prebuilt.java",
-        "./prebuilts/misc/common/ub-uiautomator/ub-uiautomator.java"
-    };
-    private final File mSourceDir;
-    private final File mDocletDir;
-
-    /**
-     * @param sourceDir The directory holding the source to scan.
-     * @param docletDir The directory holding the doclet (or its jar).
-     */
-    JavaScanner(File sourceDir, File docletDir) {
-        this.mSourceDir = sourceDir;
-        this.mDocletDir = docletDir;
-    }
-
-    int scan() throws Exception {
-        final ArrayList<String> args = new ArrayList<String>();
-        args.add("javadoc");
-        args.add("-doclet");
-        args.add("com.android.compatibility.common.scanner.JavaScannerDoclet");
-        args.add("-sourcepath");
-        args.add(getSourcePath(mSourceDir));
-        args.add("-classpath");
-        args.add(getClassPath());
-        args.add("-docletpath");
-        args.add(mDocletDir.toString());
-        args.addAll(getSourceFiles(mSourceDir));
-
-        // Dont want p to get blocked due to a full pipe.
-        final Process p = new ProcessBuilder(args).redirectErrorStream(true).start();
-        final BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
-        try {
-            String line = null;
-            while ((line = in.readLine()) != null) {
-                if (line.startsWith("suite:") ||
-                    line.startsWith("case:") ||
-                    line.startsWith("test:")) {
-                    System.out.println(line);
-                }
-            }
-        } finally {
-          if (in != null) {
-              in.close();
-          }
-        }
-
-        return p.waitFor();
-    }
-
-    private static String getSourcePath(File sourceDir) {
-        final ArrayList<String> sourcePath = new ArrayList<String>(Arrays.asList(SOURCE_PATHS));
-        sourcePath.add(sourceDir.toString());
-        return join(sourcePath, ":");
-    }
-
-    private static String getClassPath() {
-        return join(Arrays.asList(CLASS_PATHS), ":");
-    }
-
-    private static ArrayList<String> getSourceFiles(File sourceDir) {
-        final ArrayList<String> sourceFiles = new ArrayList<String>();
-        final File[] files = sourceDir.listFiles(new FileFilter() {
-            public boolean accept(File pathname) {
-                return pathname.isDirectory() || pathname.toString().endsWith(".java");
-            }
-        });
-        for (File f : files) {
-            if (f.isDirectory()) {
-                sourceFiles.addAll(getSourceFiles(f));
-            } else {
-                sourceFiles.add(f.toString());
-            }
-        }
-        return sourceFiles;
-    }
-
-    private static String join(List<String> list, String delimiter) {
-        final StringBuilder builder = new StringBuilder();
-        for (String s : list) {
-            builder.append(s);
-            builder.append(delimiter);
-        }
-        // Adding the delimiter each time and then removing the last one at the end is more
-        // efficient than doing a check in each iteration of the loop.
-        return builder.substring(0, builder.length() - delimiter.length());
-    }
-
-    public static void main(String[] args) throws Exception {
-        final HashMap<String, String> argsMap = KeyValueArgsParser.parse(args);
-        final String sourcePath = argsMap.get("-s");
-        final String docletPath = argsMap.get("-d");
-        if (sourcePath == null || docletPath == null) {
-            usage(args);
-        }
-        System.exit(new JavaScanner(new File(sourcePath), new File(docletPath)).scan());
-    }
-
-    private static void usage(String[] args) {
-        System.err.println("Arguments: " + Arrays.toString(args));
-        System.err.println("Usage: javascanner -s SOURCE_DIR -d DOCLET_PATH");
-        System.exit(1);
-    }
-}
diff --git a/common/host-side/java-scanner/src/com/android/compatibility/common/scanner/JavaScannerDoclet.java b/common/host-side/java-scanner/src/com/android/compatibility/common/scanner/JavaScannerDoclet.java
deleted file mode 100644
index 94eccd0..0000000
--- a/common/host-side/java-scanner/src/com/android/compatibility/common/scanner/JavaScannerDoclet.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.compatibility.common.scanner;
-
-import com.sun.javadoc.ClassDoc;
-import com.sun.javadoc.Doclet;
-import com.sun.javadoc.MethodDoc;
-import com.sun.javadoc.RootDoc;
-
-import java.io.PrintWriter;
-
-/**
- * Doclet that scans java files looking for tests.
- *
- * Sample Ouput;
- * suite:com.android.sample.cts
- * case:SampleDeviceTest
- * test:testSharedPreferences
- */
-public class JavaScannerDoclet extends Doclet {
-
-    private static final String JUNIT_TEST_CASE_CLASS_NAME = "junit.framework.testcase";
-
-    public static boolean start(RootDoc root) {
-        ClassDoc[] classes = root.classes();
-        if (classes == null) {
-            return false;
-        }
-
-        PrintWriter writer = new PrintWriter(System.out);
-
-        for (ClassDoc clazz : classes) {
-            if (clazz.isAbstract() || !isValidJUnitTestCase(clazz)) {
-                continue;
-            }
-            writer.append("suite:").println(clazz.containingPackage().name());
-            writer.append("case:").println(clazz.name());
-            for (; clazz != null; clazz = clazz.superclass()) {
-                for (MethodDoc method : clazz.methods()) {
-                    if (method.name().startsWith("test")) {
-                        writer.append("test:").println(method.name());
-                    }
-                }
-            }
-        }
-
-        writer.close();
-        return true;
-    }
-
-    private static boolean isValidJUnitTestCase(ClassDoc clazz) {
-        while ((clazz = clazz.superclass()) != null) {
-            if (JUNIT_TEST_CASE_CLASS_NAME.equals(clazz.qualifiedName().toLowerCase())) {
-                return true;
-            }
-        }
-        return false;
-    }
-}
diff --git a/common/host-side/java-scanner/tests/src/com/android/compatibility/common/scanner/JavaScannerTest.java b/common/host-side/java-scanner/tests/src/com/android/compatibility/common/scanner/JavaScannerTest.java
deleted file mode 100644
index 4159f0e..0000000
--- a/common/host-side/java-scanner/tests/src/com/android/compatibility/common/scanner/JavaScannerTest.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.compatibility.common.scanner;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.InputStreamReader;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-
-import junit.framework.TestCase;
-
-public class JavaScannerTest extends TestCase {
-
-    private static final String JAR = "out/host/linux-x86/framework/compatibility-java-scanner_v2.jar";
-    private static final String VALID_RESULT =
-        "suite:com.android.test" +
-        "case:ValidTest" +
-        "test:testA";
-
-    private static final String VALID_FILENAME = "ValidTest";
-    private static final String VALID =
-        "package com.android.test;" +
-        "import junit.framework.TestCase;" +
-        "public class ValidTest extends TestCase {" +
-        "  public void testA() throws Exception {" +
-        "    helper();" +
-        "  }" +
-        "  public void helper() {" +
-        "    fail();" +
-        "  }" +
-        "}";
-
-    // TestCases must have TestCase in their hierarchy
-    private static final String INVALID_A_FILENAME = "NotTestCase";
-    private static final String INVALID_A =
-        "package com.android.test;" +
-        "public class NotTestCase {" +
-        "  public void testA() throws Exception {" +
-        "    helper();" +
-        "  }" +
-        "  public void helper() {" +
-        "    fail();" +
-        "  }" +
-        "}";
-
-    // TestCases cant be abstract classes
-    private static final String INVALID_B_FILENAME = "AbstractClass";
-    private static final String INVALID_B =
-        "package com.android.test;" +
-        "import junit.framework.TestCase;" +
-        "public abstract class AbstractClass extends TestCase {" +
-        "  public void testA() throws Exception {" +
-        "    helper();" +
-        "  }" +
-        "  public void helper() {" +
-        "    fail();" +
-        "  }" +
-        "}";
-
-    public void testValidFile() throws Exception {
-        String result = runScanner(VALID_FILENAME, VALID);
-        assertEquals(VALID_RESULT, result);
-    }
-
-    public void testInvalidFileA() throws Exception {
-        assertEquals("", runScanner(INVALID_A_FILENAME, INVALID_A));
-    }
-
-    public void testInvalidFileB() throws Exception {
-        assertEquals("", runScanner(INVALID_B_FILENAME, INVALID_B));
-    }
-
-    private static String runScanner(String filename, String content) throws Exception {
-        final File parent0 = new File(System.getProperty("java.io.tmpdir"));
-        final File parent1 = new File(parent0, "tmp" + System.currentTimeMillis());
-        final File parent2 = new File(parent1, "com");
-        final File parent3 = new File(parent2, "android");
-        final File parent4 = new File(parent3, "test");
-        File f = null;
-        try {
-            parent4.mkdirs();
-            f = new File(parent4, filename + ".java");
-            final PrintWriter out = new PrintWriter(f);
-            out.print(content);
-            out.flush();
-            out.close();
-            ArrayList<String> args = new ArrayList<String>();
-            args.add("java");
-            args.add("-jar");
-            args.add(JAR);
-            args.add("-s");
-            args.add(parent1.toString());
-            args.add("-d");
-            args.add(JAR);
-
-            final Process p = new ProcessBuilder(args).start();
-            final StringBuilder output = new StringBuilder();
-            final BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
-            String line = null;
-            while ((line = in.readLine()) != null) {
-                output.append(line);
-            }
-            int ret = p.waitFor();
-            if (ret == 0) {
-                return output.toString();
-            }
-        } finally {
-            if (f != null) {
-                f.delete();
-            }
-            parent4.delete();
-            parent3.delete();
-            parent2.delete();
-            parent1.delete();
-        }
-        return null;
-    }
-}
diff --git a/common/host-side/manifest-generator/Android.mk b/common/host-side/manifest-generator/Android.mk
index ca08928..b976329 100644
--- a/common/host-side/manifest-generator/Android.mk
+++ b/common/host-side/manifest-generator/Android.mk
@@ -30,4 +30,4 @@
 
 include $(BUILD_HOST_JAVA_LIBRARY)
 
-include $(call all-makefiles-under,$(LOCAL_PATH))
+include $(call all-makefiles-under,$(LOCAL_PATH))
\ No newline at end of file
diff --git a/common/host-side/manifest-generator/src/com/android/compatibility/common/generator/ManifestGenerator.java b/common/host-side/manifest-generator/src/com/android/compatibility/common/generator/ManifestGenerator.java
index e23e254..7241ada 100644
--- a/common/host-side/manifest-generator/src/com/android/compatibility/common/generator/ManifestGenerator.java
+++ b/common/host-side/manifest-generator/src/com/android/compatibility/common/generator/ManifestGenerator.java
@@ -25,9 +25,11 @@
 
 public class ManifestGenerator {
 
+    private static final String DEFAULT_MIN_SDK = "8";
+
     private static final String USAGE = "Usage: "
         + "manifest-generator -n NAME -p PACKAGE_NAME -o OUTPUT_FILE -i INSTRUMENT_NAME "
-        + "[-r PERMISSION]+ [-a ACTIVITY]+";
+        + "[-s MIN_SDK_VERSION] [-t TARGET_SDK_VERSION] [-r PERMISSION]+ [-a ACTIVITY]+";
     private static final String MANIFEST = "manifest";
     private static final String USES_SDK = "uses-sdk";
     private static final String USES_PERMISSION = "uses-permission";
@@ -38,6 +40,8 @@
     public static void main(String[] args) {
         String pkgName = null;
         String instrumentName = null;
+        String minSdk = DEFAULT_MIN_SDK;
+        String targetSdk = null;
         List<String> permissions = new ArrayList<>();
         List<String> activities = new ArrayList<>();
         String output = null;
@@ -53,6 +57,10 @@
                 instrumentName = args[++i];
             } else if (args[i].equals("-r")) {
                 permissions.add(args[++i]);
+            } else if (args[i].equals("-s")) {
+                minSdk = args[++i];
+            } else if (args[i].equals("-t")) {
+                targetSdk = args[++i];
             }
         }
 
@@ -69,7 +77,7 @@
         FileOutputStream out = null;
         try {
           out = new FileOutputStream(output);
-          generate(out, pkgName, instrumentName, permissions, activities);
+          generate(out, pkgName, instrumentName, minSdk, targetSdk, permissions, activities);
         } catch (Exception e) {
           System.err.println("Couldn't create manifest file");
         } finally {
@@ -84,7 +92,8 @@
     }
 
     /*package*/ static void generate(OutputStream out, String pkgName, String instrumentName,
-            List<String> permissions, List<String> activities) throws Exception {
+            String minSdk, String targetSdk, List<String> permissions, List<String> activities)
+            throws Exception {
         final String ns = null;
         KXmlSerializer serializer = new KXmlSerializer();
         serializer.setOutput(out, "UTF-8");
@@ -94,7 +103,10 @@
         serializer.attribute(ns, "xmlns:android", "http://schemas.android.com/apk/res/android");
         serializer.attribute(ns, "package", pkgName);
         serializer.startTag(ns, USES_SDK);
-        serializer.attribute(ns, "android:minSdkVersion", "8");
+        serializer.attribute(ns, "android:minSdkVersion", minSdk);
+        if (targetSdk != null) {
+            serializer.attribute(ns, "android:targetSdkVersion", targetSdk);
+        }
         serializer.endTag(ns, USES_SDK);
         for (String permission : permissions) {
             serializer.startTag(ns, USES_PERMISSION);
@@ -122,5 +134,4 @@
         System.err.println(USAGE);
         System.exit(1);
     }
-
 }
diff --git a/common/host-side/manifest-generator/tests/run_tests.sh b/common/host-side/manifest-generator/tests/run_tests.sh
new file mode 100755
index 0000000..758589c
--- /dev/null
+++ b/common/host-side/manifest-generator/tests/run_tests.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Helper script for running unit tests for compatibility libraries
+
+CTS_DIR=$(dirname ${0})/../../../..
+source ${CTS_DIR}/test_defs.sh
+
+JARS="
+    compatibility-manifest-generator\
+    compatibility-manifest-generator-tests"
+
+run_tests "com.android.compatibility.common.generator.ManifestGeneratorTest" "${JARS}" "${@}"
+
diff --git a/common/host-side/manifest-generator/tests/src/com/android/compatibility/common/generator/ManifestGeneratorTest.java b/common/host-side/manifest-generator/tests/src/com/android/compatibility/common/generator/ManifestGeneratorTest.java
index 457bbb8..a0565e1 100644
--- a/common/host-side/manifest-generator/tests/src/com/android/compatibility/common/generator/ManifestGeneratorTest.java
+++ b/common/host-side/manifest-generator/tests/src/com/android/compatibility/common/generator/ManifestGeneratorTest.java
@@ -29,10 +29,12 @@
 
     private static final String PACKAGE = "test.package";
     private static final String INSTRUMENT = "test.package.TestInstrument";
+    private static final String MIN_SDK = "8";
+    private static final String TARGET_SDK = "9";
     private static final String MANIFEST = "<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>\r\n"
         + "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\" "
         + "package=\"test.package\">\r\n"
-        + "  <uses-sdk android:minSdkVersion=\"8\" />\r\n"
+        + "  <uses-sdk android:minSdkVersion=\"8\" android:targetSdkVersion=\"9\" />\r\n"
         + "%s"
         + "  <application>\r\n"
         + "%s"
@@ -66,7 +68,8 @@
                 return this.string.toString();
             }
         };
-        ManifestGenerator.generate(output, PACKAGE, INSTRUMENT, permissions, activities);
+        ManifestGenerator.generate(output, PACKAGE, INSTRUMENT, MIN_SDK, TARGET_SDK,
+            permissions, activities);
         String permissionXml = String.format(PERMISSION, PERMISSION_A)
                 + String.format(PERMISSION, PERMISSION_B);
         String activityXml = String.format(ACTIVITY, ACTIVITY_A)
diff --git a/common/host-side/native-scanner/Android.mk b/common/host-side/native-scanner/Android.mk
deleted file mode 100644
index 184cdc0..0000000
--- a/common/host-side/native-scanner/Android.mk
+++ /dev/null
@@ -1,47 +0,0 @@
-# Copyright (C) 2014 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_JAR_MANIFEST := MANIFEST.mf
-
-LOCAL_CLASSPATH := $(HOST_JDK_TOOLS_JAR)
-
-LOCAL_JAVA_LIBRARIES := compatibility-common-util-hostsidelib_v2
-
-LOCAL_MODULE := compatibility-native-scanner_v2
-
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_HOST_JAVA_LIBRARY)
-
-################################################################################
-# Build the tests
-###############################################################################
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under, tests/src)
-
-LOCAL_JAVA_LIBRARIES := compatibility-tradefed_v2 compatibility-native-scanner_v2 junit
-
-LOCAL_MODULE := compatibility-native-scanner-tests_v2
-
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/common/host-side/native-scanner/MANIFEST.mf b/common/host-side/native-scanner/MANIFEST.mf
deleted file mode 100644
index c5641ca..0000000
--- a/common/host-side/native-scanner/MANIFEST.mf
+++ /dev/null
@@ -1,3 +0,0 @@
-Manifest-Version: 1.0
-Main-Class: com.android.compatibility.common.scanner.NativeScanner
-Class-Path: compatibility-common-util-hostsidelib_v2.jar
diff --git a/common/host-side/native-scanner/src/com/android/compatibility/common/scanner/NativeScanner.java b/common/host-side/native-scanner/src/com/android/compatibility/common/scanner/NativeScanner.java
deleted file mode 100644
index 7b9e447..0000000
--- a/common/host-side/native-scanner/src/com/android/compatibility/common/scanner/NativeScanner.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.compatibility.common.scanner;
-
-import com.android.compatibility.common.util.KeyValueArgsParser;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.util.ArrayList;
-import java.util.HashMap;
-
-/**
- * Passes the gtest output and outputs a list of test classes and methods.
- */
-public final class NativeScanner {
-
-    private static final String TEST_SUITE_ARG = "t";
-    private static final String USAGE = "Usage: compatibility-native-scanner -t TEST_SUITE"
-        + "  This code reads from stdin the list of tests."
-        + "  The format expected:"
-        + "    TEST_CASE_NAME."
-        + "      TEST_NAME";
-
-    /**
-     * @return An {@link ArrayList} of suites, classes and method names.
-     */
-    static ArrayList<String> getTestNames(BufferedReader reader, String testSuite)
-            throws IOException {
-        ArrayList<String> testNames = new ArrayList<String>();
-        testNames.add("suite:" + testSuite);
-
-        String testCaseName = null;
-        String line;
-        while ((line = reader.readLine()) != null) {
-            if (line.length() == 0) {
-                continue;
-            }
-            if (line.charAt(0) == ' ') {
-                if (testCaseName == null) {
-                    throw new RuntimeException("TEST_CASE_NAME not defined before first test.");
-                }
-                testNames.add("test:" + line.trim());
-            } else {
-                testCaseName = line.trim();
-                if (testCaseName.endsWith(".")) {
-                    testCaseName = testCaseName.substring(0, testCaseName.length()-1);
-                }
-                testNames.add("case:" + testCaseName);
-            }
-        }
-        return testNames;
-    }
-
-    /** Lookup test suite argument and scan {@code System.in} for test cases */
-    public static void main(String[] args) throws IOException {
-        HashMap<String, String> argMap = KeyValueArgsParser.parse(args);
-        if (!argMap.containsKey(TEST_SUITE_ARG)) {
-            System.err.println(USAGE);
-            System.exit(1);
-        }
-
-        String testSuite = argMap.get(TEST_SUITE_ARG);
-
-        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
-        for (String name : getTestNames(reader, testSuite)) {
-            System.out.println(name);
-        }
-    }
-}
diff --git a/common/host-side/native-scanner/tests/src/com/android/compatibility/common/scanner/NativeScannerTest.java b/common/host-side/native-scanner/tests/src/com/android/compatibility/common/scanner/NativeScannerTest.java
deleted file mode 100644
index c5d3157..0000000
--- a/common/host-side/native-scanner/tests/src/com/android/compatibility/common/scanner/NativeScannerTest.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.compatibility.common.scanner;
-
-import com.android.compatibility.common.scanner.NativeScanner;
-
-import junit.framework.TestCase;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.StringReader;
-import java.util.List;
-import java.util.Iterator;
-
-public class NativeScannerTest extends TestCase {
-
-    public void testSingleTestNamesCase() throws Exception {
-        StringReader singleTestString = new StringReader("FakeTestCase.\n  FakeTestName\n");
-        BufferedReader reader = new BufferedReader(singleTestString);
-
-        List<String> names = NativeScanner.getTestNames(reader, "TestSuite");
-        Iterator<String> it = names.iterator();
-        assertEquals("suite:TestSuite", it.next());
-        assertEquals("case:FakeTestCase", it.next());
-        assertEquals("test:FakeTestName", it.next());
-        assertFalse(it.hasNext());
-    }
-
-    public void testMultipleTestNamesCase() throws Exception {
-        StringReader singleTestString = new StringReader(
-          "Case1.\n  Test1\n  Test2\nCase2.\n  Test3\n Test4\n");
-        BufferedReader reader = new BufferedReader(singleTestString);
-
-        List<String> names = NativeScanner.getTestNames(reader, "TestSuite");
-
-        Iterator<String> it = names.iterator();
-        assertEquals("suite:TestSuite", it.next());
-        assertEquals("case:Case1", it.next());
-        assertEquals("test:Test1", it.next());
-        assertEquals("test:Test2", it.next());
-        assertEquals("case:Case2", it.next());
-        assertEquals("test:Test3", it.next());
-        assertEquals("test:Test4", it.next());
-        assertFalse(it.hasNext());
-    }
-
-    public void testMissingTestCaseNameCase() throws IOException {
-        StringReader singleTestString = new StringReader("  Test1\n");
-        BufferedReader reader = new BufferedReader(singleTestString);
-
-        try {
-            NativeScanner.getTestNames(reader, "TestSuite");
-            fail("Expected RuntimeException");
-        } catch (RuntimeException expected) {}
-    }
-}
diff --git a/common/host-side/scripts/compatibility-tests_v2 b/common/host-side/scripts/compatibility-tests_v2
deleted file mode 100755
index 797909e..0000000
--- a/common/host-side/scripts/compatibility-tests_v2
+++ /dev/null
@@ -1,61 +0,0 @@
-#!/bin/bash
-#
-# Copyright (C) 2014 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-checkFile() {
-    if [ ! -f "$1" ]; then
-        echo "Unable to locate $1"
-        exit
-    fi;
-}
-
-HOST_JAR_DIR=${ANDROID_HOST_OUT}/framework
-HOST_JARS="ddmlib-prebuilt tradefed-prebuilt hosttestlib\
-    compatibility-tradefed_v2 compatibility-tradefed-tests_v2\
-    compatibility-java-scanner_v2 compatibility-java-scanner-tests_v2\
-    compatibility-native-scanner_v2 compatibility-native-scanner-tests_v2\
-    compatibility-xml-plan-generator_v2 compatibility-xml-plan-generator-tests_v2\
-    compatibility-device-util-tests_v2 compatibility-device-setup-tests_v2\
-    compatibility-common-util-hostsidelib_v2 compatibility-common-util-tests_v2"
-
-for JAR in ${HOST_JARS}; do
-    checkFile ${HOST_JAR_DIR}/${JAR}.jar
-    JAR_PATH=${JAR_PATH}:${HOST_JAR_DIR}/${JAR}.jar
-done
-
-DEVICE_LIBS_DIR=${ANDROID_PRODUCT_OUT}/obj/JAVA_LIBRARIES
-DEVICE_LIBS="compatibility-common-util-devicesidelib_v2 compatibility-device-util_v2\
-    compatibility-device-setup_v2"
-
-for LIB in ${DEVICE_LIBS}; do
-    checkFile ${DEVICE_LIBS_DIR}/${LIB}_intermediates/javalib.jar
-    JAR_PATH=${JAR_PATH}:${DEVICE_LIBS_DIR}/${LIB}_intermediates/javalib.jar
-done
-
-# TODO(stuartscott): Currently the test classes are explicitly set here, but
-# once our wrappers for tradefed are in place we can make it scan and generate
-# the list of test at runtime.
-TEST_CLASSES="com.android.compatibility.common.devicesetup.DeviceSetupTest\
-    com.android.compatibility.common.scanner.JavaScannerTest\
-    com.android.compatibility.common.scanner.NativeScannerTest\
-    com.android.compatibility.common.tradefed.TradefedTest\
-    com.android.compatibility.common.util.DeviceUtilTest\
-    com.android.compatibility.common.util.CommonUtilTest\
-    com.android.compatibility.common.xmlgenerator.XmlPlanGeneratorTest"
-
-for CLASS in ${TEST_CLASSES}; do
-    java $RDBG_FLAG -cp ${JAR_PATH} com.android.compatibility.common.tradefed.command.CompatibilityConsole run\
-            singleCommand host -n --class ${CLASS} "$@"
-done
diff --git a/common/host-side/scripts/compatibility-tradefed_v2 b/common/host-side/scripts/compatibility-tradefed_v2
deleted file mode 100755
index f64e273..0000000
--- a/common/host-side/scripts/compatibility-tradefed_v2
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/bin/bash
-#
-# Copyright (C) 2014 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-echo "TODO(stuartscott): Add the wrapper to launch the executable. This will be done in the next CL"
diff --git a/common/host-side/tradefed/Android.mk b/common/host-side/tradefed/Android.mk
index 8ff7c8c..3ed225ed 100644
--- a/common/host-side/tradefed/Android.mk
+++ b/common/host-side/tradefed/Android.mk
@@ -1,4 +1,4 @@
-# Copyright (C) 2014 The Android Open Source Project
+# Copyright (C) 2015 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -12,40 +12,4 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-###############################################################################
-# Builds the compatibility tradefed host library
-###############################################################################
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-#LOCAL_JAVA_RESOURCE_DIRS := res
-
-LOCAL_MODULE := compatibility-tradefed_v2
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_JAVA_LIBRARIES := tradefed-prebuilt hosttestlib compatibility-common-util-hostsidelib_v2
-
-include $(BUILD_HOST_JAVA_LIBRARY)
-
-###############################################################################
-# Build the compatibility tradefed tests
-###############################################################################
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under, tests/src)
-
-LOCAL_MODULE := compatibility-tradefed-tests_v2
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_JAVA_LIBRARIES := tradefed-prebuilt compatibility-tradefed_v2 junit
-
-LOCAL_STATIC_JAVA_LIBRARIES := easymock
-
-include $(BUILD_HOST_JAVA_LIBRARY)
+include $(call all-subdir-makefiles)
\ No newline at end of file
diff --git a/common/host-side/tradefed/res/config/common-compatibility-config.xml b/common/host-side/tradefed/res/config/common-compatibility-config.xml
new file mode 100644
index 0000000..1b40f16
--- /dev/null
+++ b/common/host-side/tradefed/res/config/common-compatibility-config.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Common config for Compatibility suites">
+    <device_recovery class="com.android.tradefed.device.WaitDeviceRecovery" />
+    <build_provider class="com.android.compatibility.common.tradefed.build.CompatibilityBuildProvider" />
+    <test class="com.android.compatibility.common.tradefed.testtype.CompatibilityTest" />
+    <logger class="com.android.tradefed.log.FileLogger">
+        <option name="log-level-display" value="WARN" />
+    </logger>
+    <result_reporter class="com.android.compatibility.common.tradefed.result.ResultReporter" />
+</configuration>
diff --git a/common/host-side/tradefed/res/config/everything.xml b/common/host-side/tradefed/res/config/everything.xml
new file mode 100644
index 0000000..d1ac900
--- /dev/null
+++ b/common/host-side/tradefed/res/config/everything.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Common config for Compatibility suites to run all modules">
+
+    <include name="common-compatibility-config" />
+    <option name="compatibility:plan" value="everything" />
+
+</configuration>
diff --git a/common/host-side/tradefed/res/report/compatibility_result.css b/common/host-side/tradefed/res/report/compatibility_result.css
new file mode 100644
index 0000000..699f45a
--- /dev/null
+++ b/common/host-side/tradefed/res/report/compatibility_result.css
@@ -0,0 +1,164 @@
+/* Copyright (C) 2015 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+*/
+
+body {
+    font-family:arial,sans-serif;
+    color:#000;
+    font-size:13px;
+    color:#333;
+    padding:10;
+    margin:10;
+}
+
+/* Report logo and device name */
+table.title {
+    padding:5px;
+    border-width: 0px;
+    margin-left:auto;
+    margin-right:auto;
+    vertical-align:middle;
+}
+
+table.summary {
+    background-color: rgb(212, 233, 169);
+    border-collapse:collapse;
+    border: 0px solid #A5C639;
+    margin-left:auto;
+    margin-right:auto;
+}
+
+table.summary th {
+    background-color: #A5C639;
+    font-size: 1.2em;
+    padding: 0.5em;
+}
+
+table.summary td {
+    border-width: 0px 0px 0px 0px;
+    border-color: gray;
+    border-style: inset;
+    font-size: 1em;
+    padding: 0.5em;
+    vertical-align: top;
+}
+
+table.testsummary {
+    background-color: rgb(212, 233, 169);
+    border-collapse:collapse;
+    margin-left:auto;
+    margin-right:auto;
+}
+
+table.testsummary th {
+    background-color: #A5C639;
+    border: 1px outset gray;
+    padding: 0.5em;
+}
+
+table.testsummary td {
+    border: 1px outset #A5C639;
+    padding: 0.5em;
+    text-align: center;
+}
+
+table.testdetails {
+    background-color: rgb(212, 233, 169);
+    border-collapse:collapse;
+    border-width:1;
+    border-color: #A5C639;
+    margin-left:auto;
+    margin-right:auto;
+    margin-bottom: 2em;
+    vertical-align: top;
+    width: 95%;
+}
+
+table.testdetails th {
+    background-color: #A5C639;
+    border-width: 1px;
+    border-color: gray;
+    border-style: outset;
+    height: 2em;
+    padding: 0.2em;
+}
+
+table.testdetails td {
+    border-width: 1px;
+    border-color: #A5C639;
+    border-style: outset;
+    text-align: left;
+    vertical-align: top;
+    padding: 0.2em;
+}
+
+table.testdetails td.module {
+    background-color: white;
+    border: 0px;
+    font-weight: bold;
+}
+
+/* Test cell details */
+td.failed {
+    background-color: #FA5858;
+    font-weight:bold;
+    vertical-align: top;
+    text-align: center;
+}
+
+td.failuredetails {
+    text-align: left;
+}
+
+td.pass {
+    text-align: center;
+    margin-left:auto;
+    margin-right:auto;
+}
+
+td.not_executed {
+    background-color: #A5C639;
+    vertical-align: top;
+    text-align: center;
+}
+
+td.testname {
+    border-width: 1px;
+    border-color: #A5C639;
+    border-style: outset;
+    text-align: left;
+    vertical-align: top;
+    padding:1;
+    overflow:hidden;
+}
+
+td.testcase {
+    border-width: 1px;
+    border-color: #A5C639;
+    border-style: outset;
+    text-align: left;
+    vertical-align: top;
+    padding:1;
+    overflow:hidden;
+    font-weight:bold;
+}
+
+div.details {
+    white-space: pre-wrap;       /* css-3 */
+    white-space: -moz-pre-wrap;  /* Mozilla, since 1999 */
+    white-space: -pre-wrap;      /* Opera 4-6 */
+    white-space: -o-pre-wrap;    /* Opera 7 */
+    word-wrap: break-word;       /* Internet Explorer 5.5+ */
+    overflow:auto;
+}
diff --git a/common/host-side/tradefed/res/report/compatibility_result.xsd b/common/host-side/tradefed/res/report/compatibility_result.xsd
new file mode 100644
index 0000000..9b2758c
--- /dev/null
+++ b/common/host-side/tradefed/res/report/compatibility_result.xsd
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+           targetNamespace="http://compatibility.android.com/compatibility_result/1.15"
+           xmlns="http://compatibility.android.com/compatibility_result/1.15"
+           elementFormDefault="qualified">
+
+  <xs:element name="Result">
+    <xs:complexType>
+      <xs:sequence>
+        <xs:element name="Summary" type="summaryType"/>
+        <xs:element name="Module" type="moduleType" minOccurs="1" maxOccurs="unbounded"/>
+      </xs:sequence>
+      <xs:attribute name="start" type="xs:string"/>
+      <xs:attribute name="end" type="xs:string"/>
+      <xs:attribute name="plan" type="xs:string"/>
+      <xs:attribute name="suite_name" type="xs:string"/>
+      <xs:attribute name="suite_version" type="xs:string"/>
+    </xs:complexType>
+  </xs:element>
+
+  <xs:complexType name="summaryType">
+    <xs:attribute name="failed" type="xs:integer"/>
+    <xs:attribute name="not_executed" type="xs:integer"/>
+    <xs:attribute name="pass" type="xs:integer"/>
+  </xs:complexType>
+
+  <xs:complexType name="moduleType">
+    <xs:sequence>
+      <xs:element name="Test" type="testType" minOccurs="1" maxOccurs="unbounded" />
+    </xs:sequence>
+    <xs:attribute name="name" type="xs:string" use="required"/>
+    <xs:attribute name="abi" type="xs:string"/>
+  </xs:complexType>
+
+  <xs:simpleType name="unitType">
+    <xs:restriction base="xs:string">
+      <xs:enumeration value="none"/>
+      <xs:enumeration value="ms"/>
+      <xs:enumeration value="fps"/>
+      <xs:enumeration value="ops"/>
+      <xs:enumeration value="kbps"/>
+      <xs:enumeration value="mbps"/>
+      <xs:enumeration value="byte"/>
+      <xs:enumeration value="count"/>
+      <xs:enumeration value="score"/>
+    </xs:restriction>
+  </xs:simpleType>
+
+  <xs:simpleType name="scoreTypeType">
+    <xs:restriction base="xs:string">
+      <xs:enumeration value="higher-better"/>
+      <xs:enumeration value="lower-better"/>
+      <xs:enumeration value="neutral"/>
+      <xs:enumeration value="warning"/>
+    </xs:restriction>
+  </xs:simpleType>
+
+  <xs:complexType name="testType">
+    <xs:sequence>
+      <xs:element name="Failure" minOccurs="0" maxOccurs="1">
+        <xs:complexType>
+          <xs:sequence>
+            <xs:element name="StackTrace" type="xs:string" minOccurs="0" maxOccurs="1"/>
+          </xs:sequence>
+          <xs:attribute name="message" type="xs:string"/>
+        </xs:complexType>
+      </xs:element>
+      <xs:element name="Summary" minOccurs="0" maxOccurs="1">
+        <xs:complexType>
+          <xs:simpleContent>
+            <xs:extension base="xs:decimal">
+              <xs:attribute name="message" type="xs:string" use="required" />
+              <xs:attribute name="scoreType" type="scoreTypeType" use="required" />
+              <xs:attribute name="unit" type="unitType" use="required" />
+              <xs:attribute name="target" type="xs:decimal" />
+            </xs:extension>
+          </xs:simpleContent>
+        </xs:complexType>
+      </xs:element>
+      <xs:element name="Details" minOccurs="0" maxOccurs="1">
+        <xs:complexType>
+          <xs:sequence>
+            <xs:element name="ValueArray" minOccurs="0" maxOccurs="unbounded">
+              <xs:complexType>
+                <xs:sequence>
+                  <xs:element name="Value" type="xs:decimal" minOccurs="0" maxOccurs="unbounded" />
+                </xs:sequence>
+                <xs:attribute name="source" type="xs:string" use="required" />
+                <xs:attribute name="message" type="xs:string" use="required" />
+                <xs:attribute name="scoreType" type="scoreTypeType" use="required" />
+                <xs:attribute name="unit" type="unitType" use="required" />
+              </xs:complexType>
+            </xs:element>
+          </xs:sequence>
+        </xs:complexType>
+      </xs:element>
+    </xs:sequence>
+    <xs:attribute name="name" type="xs:string" use="required"/>
+    <xs:attribute name="result" type="resultType" use="required"/>
+    <xs:attribute name="start" type="xs:string"/>
+    <xs:attribute name="end" type="xs:string"/>
+  </xs:complexType>
+
+  <xs:simpleType name="resultType">
+    <xs:restriction base="xs:string">
+      <xs:enumeration value="pass"/>
+      <xs:enumeration value="fail"/>
+      <xs:enumeration value="not_executed"/>
+    </xs:restriction>
+  </xs:simpleType>
+</xs:schema>
\ No newline at end of file
diff --git a/common/host-side/tradefed/res/report/compatibility_result.xsl b/common/host-side/tradefed/res/report/compatibility_result.xsl
new file mode 100644
index 0000000..ac5c282
--- /dev/null
+++ b/common/host-side/tradefed/res/report/compatibility_result.xsl
@@ -0,0 +1,273 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+
+<!DOCTYPE xsl:stylesheet [ <!ENTITY nbsp "&#160;"> ]>
+<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+    <xsl:output method="html" version="1.0" encoding="UTF-8" indent="yes"/>
+
+    <xsl:template match="/">
+
+        <html>
+            <head>
+                <title>Test Report</title>
+                <style type="text/css">
+                    @import "compatibility_result.css";
+                </style>
+            </head>
+            <body>
+                <div>
+                    <table class="title">
+                        <tr>
+                            <td align="left"><img src="logo.png"/></td>
+                        </tr>
+                    </table>
+                </div>
+
+                <div>
+                    <table class="summary">
+                        <tr>
+                            <th colspan="2">Summary</th>
+                        </tr>
+                        <tr>
+                            <td class="rowtitle">Suite / Plan</td>
+                            <td>
+                                <xsl:value-of select="Result/@suite_name"/> / <xsl:value-of select="Result/@plan"/>
+                            </td>
+                        </tr>
+                        <tr>
+                            <td class="rowtitle">Suite / Build</td>
+                            <td>
+                                <xsl:value-of select="Result/@suite_version"/> / <xsl:value-of select="Result/@suite_build_number"/>
+                            </td>
+                        </tr>
+                        <tr>
+                            <td class="rowtitle">Host Info</td>
+                            <td>
+                                Result/@start
+                                <xsl:value-of select="Result/@host_name"/>
+                                (<xsl:value-of select="Result/@os_name"/> - <xsl:value-of select="Result/@os_version"/>)
+                            </td>
+                        </tr>
+                        <tr>
+                            <td class="rowtitle">Start time / End Time</td>
+                            <td>
+                                <xsl:value-of select="Result/@start_display"/> /
+                                <xsl:value-of select="Result/@end_display"/>
+                            </td>
+                        </tr>
+                        <tr>
+                            <td class="rowtitle">Tests Passed</td>
+                            <td>
+                                <xsl:value-of select="Result/Summary/@pass"/>
+                            </td>
+                        </tr>
+                        <tr>
+                            <td class="rowtitle">Tests Failed</td>
+                            <td>
+                                <xsl:value-of select="Result/Summary/@failed"/>
+                            </td>
+                        </tr>
+                        <tr>
+                            <td class="rowtitle">Tests Not Executed</td>
+                            <td>
+                                <xsl:value-of select="Result/Summary/@not_executed"/>
+                            </td>
+                        </tr>
+                        <tr>
+                            <td class="rowtitle">Fingerprint</td>
+                            <td>
+                                <xsl:value-of select="Result/Build/@build_fingerprint"/>
+                            </td>
+                        </tr>
+                        <tr>
+                            <td class="rowtitle">Security Patch</td>
+                            <td>
+                                <xsl:value-of select="Result/Build/@build_version_security_patch"/>
+                            </td>
+                        </tr>
+                        <tr>
+                            <td class="rowtitle">Release (SDK)</td>
+                            <td>
+                                <xsl:value-of select="Result/Build/@build_version_release"/> (<xsl:value-of select="Result/Build/@build_version_sdk"/>)
+                            </td>
+                        </tr>
+                        <tr>
+                            <td class="rowtitle">ABIs</td>
+                            <td>
+                                <xsl:value-of select="Result/Build/@build_abis"/>
+                            </td>
+                        </tr>
+                    </table>
+                </div>
+
+                <!-- High level summary of test execution -->
+                <br/>
+                <div>
+                    <table class="testsummary">
+                        <tr>
+                            <th>Module</th>
+                            <th>Passed</th>
+                            <th>Failed</th>
+                            <th>Not Executed</th>
+                            <th>Total Tests</th>
+                        </tr>
+                        <xsl:for-each select="Result/Module">
+                            <tr>
+                                <td>
+                                    <xsl:variable name="href"><xsl:value-of select="@name"/> - <xsl:value-of select="@abi"/></xsl:variable>
+                                    <a href="#{$href}"><xsl:value-of select="@name"/> - <xsl:value-of select="@abi"/></a>
+                                </td>
+                                <td>
+                                    <xsl:value-of select="count(TestCase/Test[@result = 'pass'])"/>
+                                </td>
+                                <td>
+                                    <xsl:value-of select="count(TestCase/Test[@result = 'fail'])"/>
+                                </td>
+                                <td>
+                                    <xsl:value-of select="count(TestCase/Test[@result = 'not_executed'])"/>
+                                </td>
+                                <td>
+                                    <xsl:value-of select="count(TestCase/Test)"/>
+                                </td>
+                            </tr>
+                        </xsl:for-each> <!-- end Module -->
+                    </table>
+                </div>
+
+                <xsl:call-template name="filteredResultTestReport">
+                    <xsl:with-param name="header" select="'Failured Tests'" />
+                    <xsl:with-param name="resultFilter" select="'fail'" />
+                </xsl:call-template>
+
+                <xsl:call-template name="filteredResultTestReport">
+                    <xsl:with-param name="header" select="'Not Executed Tests'" />
+                    <xsl:with-param name="resultFilter" select="'not_executed'" />
+                </xsl:call-template>
+
+                <br/>
+                <xsl:call-template name="detailedTestReport" />
+
+            </body>
+        </html>
+    </xsl:template>
+
+    <xsl:template name="filteredResultTestReport">
+        <xsl:param name="header" />
+        <xsl:param name="resultFilter" />
+        <xsl:variable name="numMatching" select="count(Result/Module/Test[@result=$resultFilter])" />
+        <xsl:if test="$numMatching &gt; 0">
+            <h2 align="center"><xsl:value-of select="$header" /> (<xsl:value-of select="$numMatching"/>)</h2>
+            <xsl:call-template name="detailedTestReport">
+                <xsl:with-param name="resultFilter" select="$resultFilter"/>
+            </xsl:call-template>
+        </xsl:if>
+    </xsl:template>
+
+    <xsl:template name="detailedTestReport">
+        <xsl:param name="resultFilter" />
+        <div>
+            <xsl:for-each select="Result/Module">
+                <xsl:if test="$resultFilter=''
+                        or count(Test[@result=$resultFilter]) &gt; 0">
+
+                    <table class="testdetails">
+                        <tr>
+                            <td class="module" colspan="3">
+                                <xsl:variable name="href"><xsl:value-of select="@name"/> - <xsl:value-of select="@abi"/></xsl:variable>
+                                <a name="{$href}"><xsl:value-of select="@name"/> - <xsl:value-of select="@abi"/></a>
+                            </td>
+                        </tr>
+
+                        <tr>
+                            <th width="30%">Test</th>
+                            <th width="5%">Result</th>
+                            <th>Details</th>
+                        </tr>
+
+                        <xsl:for-each select="TestCase">
+                            <xsl:variable name="TestCase" select="."/>
+                            <!-- test -->
+                            <xsl:for-each select="Test">
+                                <xsl:if test="$resultFilter='' or $resultFilter=@result">
+                                    <tr>
+                                        <td class="testname"> <xsl:value-of select="$TestCase/@name"/>#<xsl:value-of select="@name"/></td>
+
+                                        <!-- test results -->
+                                        <xsl:if test="@result='pass'">
+                                            <td class="pass">
+                                                <div style="text-align: center; margin-left:auto; margin-right:auto;">
+                                                    <xsl:value-of select="@result"/>
+                                                </div>
+                                            </td>
+                                            <td class="failuredetails"/>
+                                        </xsl:if>
+
+                                        <xsl:if test="@result='fail'">
+                                            <td class="failed">
+                                                <div style="text-align: center; margin-left:auto; margin-right:auto;">
+                                                    <xsl:value-of select="@result"/>
+                                                </div>
+                                            </td>
+                                            <td class="failuredetails">
+                                                <div class="details">
+                                                    <xsl:value-of select="Failure/@message"/>
+                                                </div>
+                                            </td>
+                                        </xsl:if>
+
+                                        <xsl:if test="@result='not_executed'">
+                                            <td class="not_executed">
+                                                <div style="text-align: center; margin-left:auto; margin-right:auto;">
+                                                    <xsl:value-of select="@result"/>
+                                                </div>
+                                            </td>
+                                            <td class="failuredetails"></td>
+                                        </xsl:if>
+                                    </tr> <!-- finished with a row -->
+                                </xsl:if>
+                            </xsl:for-each> <!-- end test -->
+                        </xsl:for-each>
+                    </table>
+                </xsl:if>
+            </xsl:for-each> <!-- end test Module -->
+        </div>
+    </xsl:template>
+
+    <!-- Take a delimited string and insert line breaks after a some number of elements. -->
+    <xsl:template name="formatDelimitedString">
+        <xsl:param name="string" />
+        <xsl:param name="numTokensPerRow" select="10" />
+        <xsl:param name="tokenIndex" select="1" />
+        <xsl:if test="$string">
+            <!-- Requires the last element to also have a delimiter after it. -->
+            <xsl:variable name="token" select="substring-before($string, ';')" />
+            <xsl:value-of select="$token" />
+            <xsl:text>&#160;</xsl:text>
+
+            <xsl:if test="$tokenIndex mod $numTokensPerRow = 0">
+                <br />
+            </xsl:if>
+
+            <xsl:call-template name="formatDelimitedString">
+                <xsl:with-param name="string" select="substring-after($string, ';')" />
+                <xsl:with-param name="numTokensPerRow" select="$numTokensPerRow" />
+                <xsl:with-param name="tokenIndex" select="$tokenIndex + 1" />
+            </xsl:call-template>
+        </xsl:if>
+    </xsl:template>
+
+</xsl:stylesheet>
diff --git a/common/host-side/tradefed/res/report/logo.png b/common/host-side/tradefed/res/report/logo.png
new file mode 100644
index 0000000..61970b3
--- /dev/null
+++ b/common/host-side/tradefed/res/report/logo.png
Binary files differ
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/build/CompatibilityBuildHelper.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/build/CompatibilityBuildHelper.java
new file mode 100644
index 0000000..e21f98e
--- /dev/null
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/build/CompatibilityBuildHelper.java
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.tradefed.build;
+
+import com.android.compatibility.SuiteInfo;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.build.IFolderBuildInfo;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * A simple helper that stores and retrieves information from a {@link IBuildInfo}.
+ */
+public class CompatibilityBuildHelper {
+
+    private static final String ROOT_DIR = "ROOT_DIR";
+    private static final String ROOT_DIR2 = "ROOT_DIR2";
+    private static final String SUITE_BUILD = "SUITE_BUILD";
+    private static final String SUITE_NAME = "SUITE_NAME";
+    private static final String SUITE_FULL_NAME = "SUITE_FULL_NAME";
+    private static final String SUITE_VERSION = "SUITE_VERSION";
+    private static final String SUITE_PLAN = "SUITE_PLAN";
+    private static final String RESULT_DIR = "RESULT_DIR";
+    private static final String CONFIG_PATH_PREFIX = "DYNAMIC_CONFIG_FILE:";
+    private static final String DYNAMIC_CONFIG_OVERRIDE_URL = "DYNAMIC_CONFIG_OVERRIDE_URL";
+    private final IBuildInfo mBuildInfo;
+    private boolean mInitialized = false;
+
+    /**
+     * Creates a {@link CompatibilityBuildHelper} wrapping the given {@link IBuildInfo}.
+     */
+    public CompatibilityBuildHelper(IBuildInfo buildInfo) {
+        mBuildInfo = buildInfo;
+    }
+
+    /**
+     * Initializes the {@link IBuildInfo} from the manifest.
+     */
+    public void init(String suitePlan, String dynamicConfigUrl) {
+        if (mInitialized) {
+            return;
+        }
+        mInitialized = true;
+        mBuildInfo.addBuildAttribute(SUITE_BUILD, SuiteInfo.BUILD_NUMBER);
+        mBuildInfo.addBuildAttribute(SUITE_NAME, SuiteInfo.NAME);
+        mBuildInfo.addBuildAttribute(SUITE_FULL_NAME, SuiteInfo.FULLNAME);
+        mBuildInfo.addBuildAttribute(SUITE_VERSION, SuiteInfo.VERSION);
+        mBuildInfo.addBuildAttribute(SUITE_PLAN, suitePlan);
+        String rootDirPath = null;
+        if (mBuildInfo instanceof IFolderBuildInfo) {
+            File rootDir = ((IFolderBuildInfo) mBuildInfo).getRootDir();
+            if (rootDir != null) {
+                rootDirPath = rootDir.getAbsolutePath();
+            }
+        }
+        rootDirPath = System.getProperty(String.format("%s_ROOT", SuiteInfo.NAME), rootDirPath);
+        if (rootDirPath == null || rootDirPath.trim().equals("")) {
+            throw new IllegalArgumentException(
+                    String.format("Missing install path property %s_ROOT", SuiteInfo.NAME));
+        }
+        File rootDir = new File(rootDirPath);
+        if (!rootDir.exists()) {
+            throw new IllegalArgumentException(
+                    String.format("Root directory doesn't exist %s", rootDir.getAbsolutePath()));
+        }
+        mBuildInfo.addBuildAttribute(ROOT_DIR, rootDir.getAbsolutePath());
+        if (dynamicConfigUrl != null && !dynamicConfigUrl.isEmpty()) {
+            mBuildInfo.addBuildAttribute(DYNAMIC_CONFIG_OVERRIDE_URL,
+                    dynamicConfigUrl.replace("{suite-name}", getSuiteName()));
+        }
+    }
+
+    public String getSuiteBuild() {
+        return mBuildInfo.getBuildAttributes().get(SUITE_BUILD);
+    }
+
+    public String getSuiteName() {
+        return mBuildInfo.getBuildAttributes().get(SUITE_NAME);
+    }
+
+    public String getSuiteFullName() {
+        return mBuildInfo.getBuildAttributes().get(SUITE_FULL_NAME);
+    }
+
+    public String getSuiteVersion() {
+        return mBuildInfo.getBuildAttributes().get(SUITE_VERSION);
+    }
+
+    public String getSuitePlan() {
+        return mBuildInfo.getBuildAttributes().get(SUITE_PLAN);
+    }
+
+    public String getDynamicConfigUrl() {
+        return mBuildInfo.getBuildAttributes().get(DYNAMIC_CONFIG_OVERRIDE_URL);
+    }
+
+    public void addDynamicConfigFile(String moduleName, File configFile) {
+        mBuildInfo.addBuildAttribute(CONFIG_PATH_PREFIX + moduleName, configFile.getAbsolutePath());
+    }
+
+    public Map<String, File> getDynamicConfigFiles() {
+        Map<String, File> configMap = new HashMap<>();
+        for (String key : mBuildInfo.getBuildAttributes().keySet()) {
+            if (key.startsWith(CONFIG_PATH_PREFIX)) {
+                configMap.put(key.substring(CONFIG_PATH_PREFIX.length()),
+                        new File(mBuildInfo.getBuildAttributes().get(key)));
+            }
+        }
+        return configMap;
+    }
+
+    /**
+     * @return a {@link File} representing the directory holding the Compatibility installation
+     * @throws FileNotFoundException if the directory does not exist
+     */
+    public File getRootDir() throws FileNotFoundException {
+        File dir = null;
+        if (mBuildInfo instanceof IFolderBuildInfo) {
+            dir = ((IFolderBuildInfo) mBuildInfo).getRootDir();
+        }
+        if (dir == null || !dir.exists()) {
+            dir = new File(mBuildInfo.getBuildAttributes().get(ROOT_DIR));
+            if (!dir.exists()) {
+                dir = new File(mBuildInfo.getBuildAttributes().get(ROOT_DIR2));
+            }
+        }
+        if (!dir.exists()) {
+            throw new FileNotFoundException(String.format(
+                    "Compatibility root directory %s does not exist",
+                    dir.getAbsolutePath()));
+        }
+        return dir;
+    }
+
+    /**
+     * @return a {@link File} representing the "android-<suite>" folder of the Compatibility
+     * installation
+     * @throws FileNotFoundException if the directory does not exist
+     */
+    public File getDir() throws FileNotFoundException {
+        File dir = new File(getRootDir(), String.format("android-%s", getSuiteName().toLowerCase()));
+        if (!dir.exists()) {
+            throw new FileNotFoundException(String.format(
+                    "Compatibility install folder %s does not exist",
+                    dir.getAbsolutePath()));
+        }
+        return dir;
+    }
+
+    /**
+     * @return a {@link File} representing the results directory.
+     * @throws FileNotFoundException if the directory structure is not valid.
+     */
+    public File getResultsDir() throws FileNotFoundException {
+        return new File(getDir(), "results");
+    }
+
+    /**
+     * Sets the name of the current invocation's result directory.
+     */
+    public void setResultDir(String resultDir) {
+        mBuildInfo.addBuildAttribute(RESULT_DIR, resultDir);
+    }
+
+    /**
+     * @return a {@link File} representing the result directory of the current invocation.
+     * @throws FileNotFoundException if the directory structure is not valid.
+     */
+    public File getResultDir() throws FileNotFoundException {
+        return new File(getResultsDir(), mBuildInfo.getBuildAttributes().get(RESULT_DIR));
+    }
+
+    /**
+     * @return a {@link File} representing the directory to store result logs.
+     * @throws FileNotFoundException if the directory structure is not valid.
+     */
+    public File getLogsDir() throws FileNotFoundException {
+        return new File(getDir(), "logs");
+    }
+
+    /**
+     * @return a {@link File} representing the test modules directory.
+     * @throws FileNotFoundException if the directory structure is not valid.
+     */
+    public File getTestsDir() throws FileNotFoundException {
+        File testsDir = new File(getDir(), "testcases");
+        if (!testsDir.exists()) {
+            throw new FileNotFoundException(String.format(
+                    "Compatibility tests folder %s does not exist",
+                    testsDir.getAbsolutePath()));
+        }
+        return testsDir;
+    }
+
+}
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/build/CompatibilityBuildProvider.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/build/CompatibilityBuildProvider.java
new file mode 100644
index 0000000..ee6d7db
--- /dev/null
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/build/CompatibilityBuildProvider.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.tradefed.build;
+
+import com.android.compatibility.SuiteInfo;
+import com.android.tradefed.build.BuildInfo;
+import com.android.tradefed.build.BuildRetrievalError;
+import com.android.tradefed.build.DeviceBuildInfo;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.build.IBuildProvider;
+import com.android.tradefed.build.IDeviceBuildProvider;
+import com.android.tradefed.config.Option;
+import com.android.tradefed.config.OptionClass;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+
+import java.util.regex.Pattern;
+/**
+ * A simple {@link IBuildProvider} that uses a pre-existing Compatibility install.
+ */
+@OptionClass(alias="compatibility-build-provider")
+public class CompatibilityBuildProvider implements IDeviceBuildProvider {
+
+    private static final Pattern RELEASE_BUILD = Pattern.compile("^[A-Z]{3}\\d{2}[A-Z]{0,1}$");
+
+    @Option(name="branch", description="build branch name to supply.")
+    private String mBranch = null;
+
+    @Option(name="use-device-build-info", description="Bootstrap build info from device")
+    private boolean mUseDeviceBuildInfo = false;
+
+    @Option(name="test-tag", description="test tag name to supply.")
+    private String mTestTag = "cts";
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public IBuildInfo getBuild() {
+        // Create a blank BuildInfo which will get populated later.
+        String version = SuiteInfo.BUILD_NUMBER;
+        if (version == null) {
+            version = IBuildInfo.UNKNOWN_BUILD_ID;
+        }
+        IBuildInfo ctsBuild = new BuildInfo(version, mTestTag, mTestTag);
+        if (mBranch  != null) {
+            ctsBuild.setBuildBranch(mBranch);
+        }
+
+        return ctsBuild;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public IBuildInfo getBuild(ITestDevice device)
+            throws BuildRetrievalError, DeviceNotAvailableException {
+        if (!mUseDeviceBuildInfo) {
+            // return a regular build info without extracting device attributes into standard
+            // build info fields
+            return getBuild();
+        } else {
+            String buildId = device.getBuildId();
+            String buildFlavor = device.getBuildFlavor();
+            IBuildInfo info = new DeviceBuildInfo(buildId, mTestTag, buildFlavor);
+            if (mBranch == null) {
+                // if branch is not specified via param, make a pseudo branch name based on platform
+                // version and product info from device
+                mBranch = String.format("%s-%s-%s-%s",
+                        device.getProperty("ro.product.brand"),
+                        device.getProperty("ro.product.name"),
+                        device.getProductVariant(),
+                        device.getProperty("ro.build.version.release"));
+            }
+            info.setBuildBranch(mBranch);
+            info.setBuildFlavor(buildFlavor);
+            String buildAlias = device.getBuildAlias();
+            if (RELEASE_BUILD.matcher(buildAlias).matches()) {
+                info.addBuildAttribute("build_alias", buildAlias);
+            }
+            return info;
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void buildNotTested(IBuildInfo info) {
+        // ignore
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void cleanUp(IBuildInfo info) {
+        // ignore
+    }
+}
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/command/CompatibilityConsole.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/command/CompatibilityConsole.java
index dfd1c71..ddbe810 100644
--- a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/command/CompatibilityConsole.java
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/command/CompatibilityConsole.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (C) 2015 The Android Open 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,19 +13,361 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package com.android.compatibility.common.tradefed.command;
 
+import com.android.compatibility.SuiteInfo;
+import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
+import com.android.compatibility.common.tradefed.build.CompatibilityBuildProvider;
+import com.android.compatibility.common.tradefed.result.IInvocationResultRepo;
+import com.android.compatibility.common.tradefed.result.InvocationResultRepo;
+import com.android.compatibility.common.tradefed.testtype.ModuleRepo;
+import com.android.compatibility.common.util.IInvocationResult;
+import com.android.compatibility.common.util.TestStatus;
 import com.android.tradefed.command.Console;
 import com.android.tradefed.config.ConfigurationException;
+import com.android.tradefed.config.ConfigurationFactory;
+import com.android.tradefed.config.IConfiguration;
+import com.android.tradefed.config.IConfigurationFactory;
+import com.android.tradefed.log.LogUtil.CLog;
+import com.android.tradefed.testtype.IRemoteTest;
+import com.android.tradefed.testtype.IRuntimeHintProvider;
+import com.android.tradefed.util.ArrayUtil;
+import com.android.tradefed.util.FileUtil;
+import com.android.tradefed.util.Pair;
+import com.android.tradefed.util.RegexTrie;
+import com.android.tradefed.util.TableFormatter;
+import com.android.tradefed.util.TimeUtil;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 /**
  * An extension of Tradefed's console which adds features specific to compatibility testing.
  */
 public class CompatibilityConsole extends Console {
 
+    /**
+     * Hard coded list of modules to be excluded from manual module sharding
+     * @see #splitModules(int)
+     */
+    private final static Set<String> MODULE_SPLIT_EXCLUSIONS = new HashSet<>();
+    static {
+        MODULE_SPLIT_EXCLUSIONS.add("CtsDeqpTestCases");
+    }
+    private CompatibilityBuildHelper mBuildHelper;
+    private static final int TIMESTAMP_COLUMN = 4;
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void run() {
+        printLine(String.format("Android %s %s (%s)", SuiteInfo.FULLNAME, SuiteInfo.VERSION,
+                SuiteInfo.BUILD_NUMBER));
+        super.run();
+    }
+
+    /**
+     * Adds the 'list plans', 'list modules' and 'list results' commands
+     */
+    @Override
+    protected void setCustomCommands(RegexTrie<Runnable> trie, List<String> genericHelp,
+            Map<String, String> commandHelp) {
+        trie.put(new Runnable() {
+            @Override
+            public void run() {
+                listPlans();
+            }
+        }, LIST_PATTERN, "p(?:lans)?");
+        trie.put(new Runnable() {
+            @Override
+            public void run() {
+                listModules();
+            }
+        }, LIST_PATTERN, "m(?:odules)?");
+        trie.put(new Runnable() {
+            @Override
+            public void run() {
+                listResults();
+            }
+        }, LIST_PATTERN, "r(?:esults)?");
+        trie.put(new ArgRunnable<CaptureList>() {
+            @Override
+            public void run(CaptureList args) {
+                // Skip 2 tokens to get past split and modules pattern
+                String arg = args.get(2).get(0);
+                int shards = Integer.parseInt(arg);
+                if (shards <= 1) {
+                    printLine("number of shards should be more than 1");
+                    return;
+                }
+                splitModules(shards);
+            }
+        }, "split", "m(?:odules)?", "(\\d+)");
+
+        // find existing help for 'LIST_PATTERN' commands, and append these commands help
+        String listHelp = commandHelp.get(LIST_PATTERN);
+        if (listHelp == null) {
+            // no help? Unexpected, but soldier on
+            listHelp = new String();
+        }
+        String combinedHelp = listHelp +
+                "\tp[lans]\tList all plans" + LINE_SEPARATOR +
+                "\tm[odules]\tList all modules" + LINE_SEPARATOR +
+                "\tr[esults]\tList all results" + LINE_SEPARATOR;
+        commandHelp.put(LIST_PATTERN, combinedHelp);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected String getConsolePrompt() {
+        return String.format("%s-tf > ", SuiteInfo.NAME.toLowerCase());
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected String getGenericHelpString(List<String> genericHelp) {
+        StringBuilder helpBuilder = new StringBuilder();
+        helpBuilder.append(SuiteInfo.FULLNAME);
+        helpBuilder.append("\n\n");
+        helpBuilder.append(SuiteInfo.NAME);
+        helpBuilder.append(" is the test harness for running the Android Compatibility Suite, ");
+        helpBuilder.append("built on top of Trade Federation.\n\n");
+        helpBuilder.append("Available commands and options\n");
+        helpBuilder.append("Host:\n");
+        helpBuilder.append("  help: show this message.\n");
+        helpBuilder.append("  help all: show the complete tradefed help.\n");
+        helpBuilder.append("  version: show the version.\n");
+        helpBuilder.append("  exit: gracefully exit the compatibiltiy console, waiting until all ");
+        helpBuilder.append("invocations have completed.\n");
+        helpBuilder.append("Run:\n");
+        final String runPrompt = "  run <plan> ";
+        helpBuilder.append(runPrompt);
+        helpBuilder.append("--module/-m <module>: run a test module.\n");
+        helpBuilder.append(runPrompt);
+        helpBuilder.append("--module/-m <module> --test/-t <test_name>: run a specific test from");
+        helpBuilder.append(" the module. Test name can be <package>.<class>, ");
+        helpBuilder.append("<package>.<class>#<method> or <native_name>.\n");
+        helpBuilder.append(runPrompt);
+        helpBuilder.append("--retry <session_id>: run all failed tests from a previous session.\n");
+        helpBuilder.append(runPrompt);
+        helpBuilder.append("--help/--help-all: get help for ");
+        helpBuilder.append(SuiteInfo.FULLNAME);
+        helpBuilder.append(".\n");
+        helpBuilder.append("Options:\n");
+        helpBuilder.append("  --serial/-s <device_id>: The device to run the test on.\n");
+        helpBuilder.append("  --abi/-a <abi>: The ABI to run the test against.\n");
+        helpBuilder.append("  --shard <shards>: Shards a run into the given number of independant");
+        helpBuilder.append(" chunks, to run on multiple devices in parallel.\n");
+        helpBuilder.append("  --logcat-on-failure: Capture logcat when a test fails.\n");
+        helpBuilder.append("  --bugreport-on-failure: Capture a bugreport when a test fails.\n");
+        helpBuilder.append("  --screenshot-on-failure: Capture a screenshot when a test fails.\n");
+        helpBuilder.append("List:\n");
+        helpBuilder.append("  l/list d/devices: list connected devices and their state\n");
+        helpBuilder.append("  l/list m/modules: list test modules\n");
+        helpBuilder.append("  l/list i/invocations: list invocations aka test runs currently in ");
+        helpBuilder.append("progress\n");
+        helpBuilder.append("  l/list c/commands: list commands aka test run commands currently");
+        helpBuilder.append(" in the queue waiting to be allocated devices\n");
+        helpBuilder.append("  l/list r/results: list results currently in the repository\n");
+        helpBuilder.append("Dump:\n");
+        helpBuilder.append("  d/dump l/logs: dump the tradefed logs for all running invocations\n");
+        return helpBuilder.toString();
+    }
+
+    private void listModules() {
+        File[] files = null;
+        try {
+            files = getBuildHelper().getTestsDir().listFiles(new ModuleRepo.ConfigFilter());
+        } catch (FileNotFoundException e) {
+            printLine(e.getMessage());
+            e.printStackTrace();
+        }
+        if (files != null && files.length > 0) {
+            List<String> modules = new ArrayList<>();
+            for (File moduleFile : files) {
+                modules.add(FileUtil.getBaseName(moduleFile.getName()));
+            }
+            Collections.sort(modules);
+            for (String module : modules) {
+                printLine(module);
+            }
+        } else {
+            printLine("No modules found");
+        }
+    }
+
+    private void listPlans() {
+        printLine("Available plans include:");
+        ConfigurationFactory.getInstance().printHelp(System.out);
+    }
+
+    private void splitModules(int shards) {
+        File[] files = null;
+        try {
+            files = getBuildHelper().getTestsDir().listFiles(new ModuleRepo.ConfigFilter());
+        } catch (FileNotFoundException e) {
+            printLine(e.getMessage());
+            e.printStackTrace();
+        }
+        // parse through all config files to get runtime hints
+        if (files != null && files.length > 0) {
+            IConfigurationFactory configFactory = ConfigurationFactory.getInstance();
+            List<Pair<String, Long>> moduleRuntime = new ArrayList<>();
+            // parse through all config files to calculate module execution time
+            for (File file : files) {
+                IConfiguration config = null;
+                String moduleName = file.getName().split("\\.")[0];
+                if (MODULE_SPLIT_EXCLUSIONS.contains(moduleName)) {
+                    continue;
+                }
+                try {
+                    config = configFactory.createConfigurationFromArgs(new String[]{
+                            file.getAbsolutePath(),
+                    });
+                } catch (ConfigurationException ce) {
+                    printLine("Error loading config file: " + file.getAbsolutePath());
+                    CLog.e(ce);
+                    continue;
+                }
+                long runtime = 0;
+                for (IRemoteTest test : config.getTests()) {
+                    if (test instanceof IRuntimeHintProvider) {
+                        runtime += ((IRuntimeHintProvider) test).getRuntimeHint();
+                    } else {
+                        CLog.w("Using default 1m runtime estimation for test type %s",
+                                test.getClass().getSimpleName());
+                        runtime += 60 * 1000;
+                    }
+                }
+                moduleRuntime.add(new Pair<String, Long>(moduleName, runtime));
+            }
+            // sort list modules in descending order of runtime hint
+            Collections.sort(moduleRuntime, new Comparator<Pair<String, Long>>() {
+                @Override
+                public int compare(Pair<String, Long> o1, Pair<String, Long> o2) {
+                    return o2.second.compareTo(o1.second);
+                }
+            });
+            // partition list of modules based on the runtime hint
+            List<List<Pair<String, Long>>> splittedModules = new ArrayList<>();
+            for (int i = 0; i < shards; i++) {
+                splittedModules.add(new ArrayList<>());
+            }
+            int shardIndex = 0;
+            int increment = 1;
+            long[] shardTimes = new long[shards];
+            // go through the sorted list, distribute modules into shards in zig-zag pattern to get
+            // an even execution time among shards
+            for (Pair<String, Long> module : moduleRuntime) {
+                splittedModules.get(shardIndex).add(module);
+                // also collect total runtime per shard
+                shardTimes[shardIndex] += module.second;
+                shardIndex += increment;
+                // zig-zagging: first distribute modules from shard 0 to N, then N down to 0, repeat
+                if (shardIndex == shards) {
+                    increment = -1;
+                    shardIndex = shards - 1;
+                }
+                if (shardIndex == -1) {
+                    increment = 1;
+                    shardIndex = 0;
+                }
+            }
+            shardIndex = 0;
+            // print the final shared lists
+            for (List<Pair<String, Long>> shardedModules : splittedModules) {
+                printLine(String.format("shard #%d (%s)",
+                        shardIndex, TimeUtil.formatElapsedTime(shardTimes[shardIndex])));
+                for (Pair<String, Long> module : shardedModules) {
+                    printLine(String.format("    %s", module.first));
+                }
+                shardIndex++;
+            }
+        } else {
+            printLine("No modules found");
+        }
+    }
+
+    private void listResults() {
+        TableFormatter tableFormatter = new TableFormatter();
+        List<List<String>> table = new ArrayList<>();
+        IInvocationResultRepo testResultRepo = null;
+        List<IInvocationResult> results = null;
+        try {
+            testResultRepo = new InvocationResultRepo(getBuildHelper().getResultsDir());
+            results = testResultRepo.getResults();
+        } catch (FileNotFoundException e) {
+            printLine(e.getMessage());
+            e.printStackTrace();
+        }
+        if (testResultRepo != null && results.size() > 0) {
+            for (int i = 0; i < results.size(); i++) {
+                IInvocationResult result = results.get(i);
+                Map<String, String> buildInfo = result.getBuildInfo();
+
+                // build attributes are not always present (e.g. in the case of halted test runs)
+                // replace null entries with the string "Unknown"
+                for (Map.Entry<String, String> entry : buildInfo.entrySet()) {
+                    if (entry.getValue() == null) {
+                        buildInfo.put(entry.getKey(), "Unknown");
+                    }
+                }
+
+                table.add(Arrays.asList(
+                        Integer.toString(i),
+                        Integer.toString(result.countResults(TestStatus.PASS)),
+                        Integer.toString(result.countResults(TestStatus.FAIL)),
+                        Integer.toString(result.countResults(TestStatus.NOT_EXECUTED)),
+                        TimeUtil.formatTimeStamp(result.getStartTime()),
+                        result.getTestPlan(),
+                        ArrayUtil.join(", ", result.getDeviceSerials()),
+                        buildInfo.get("build_id"),
+                        buildInfo.get("build_product")
+                        ));
+
+                // sort the table entries on each entry's formatted timestamp
+                Collections.sort(table, new Comparator<List<String>>() {
+                    public int compare(List<String> firstList, List<String> secondList) {
+                        return firstList.get(TIMESTAMP_COLUMN)
+                                .compareTo(secondList.get(TIMESTAMP_COLUMN));
+                    }
+                });
+            }
+
+            // add the table header to the beginning of the list
+            table.add(0, Arrays.asList("Session", "Pass", "Fail", "Not Executed", "Start Time",
+                    "Test Plan", "Device serial(s)", "Build ID", "Product"));
+            tableFormatter.displayTable(table, new PrintWriter(System.out, true));
+        } else {
+            printLine(String.format("No results found"));
+        }
+    }
+
+    private CompatibilityBuildHelper getBuildHelper() {
+        if (mBuildHelper == null) {
+            CompatibilityBuildProvider buildProvider = new CompatibilityBuildProvider();
+            mBuildHelper = new CompatibilityBuildHelper(buildProvider.getBuild());
+            mBuildHelper.init("" /* suite plan */, "" /* dynamic config url */);
+        }
+        return mBuildHelper;
+    }
+
     public static void main(String[] args) throws InterruptedException, ConfigurationException {
-        CompatibilityConsole console = new CompatibilityConsole();
+        Console console = new CompatibilityConsole();
         Console.startConsole(console, args);
     }
 }
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/IInvocationResultRepo.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/IInvocationResultRepo.java
new file mode 100644
index 0000000..c07223b0
--- /dev/null
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/IInvocationResultRepo.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.tradefed.result;
+
+import com.android.compatibility.common.util.IInvocationResult;
+import com.android.compatibility.common.util.InvocationResult;
+
+import java.util.List;
+
+/**
+ * Repository for Compatibility results.
+ */
+public interface IInvocationResultRepo {
+
+    /**
+     * @return the list of {@link IInvocationResult}s. The index is its session id
+     */
+    List<IInvocationResult> getResults();
+
+    /**
+     * Get the {@link IInvocationResult} for given session id.
+     *
+     * @param sessionId the session id
+     * @return the {@link InvocationResult} or <code>null</null> if the result with that session id
+     * cannot be retrieved
+     */
+    IInvocationResult getResult(int sessionId);
+
+}
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/IModuleListener.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/IModuleListener.java
new file mode 100644
index 0000000..213d293
--- /dev/null
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/IModuleListener.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.tradefed.result;
+
+import com.android.tradefed.result.ITestInvocationListener;
+
+/**
+ * Listener for Compatibility tests.
+ * <p>
+ * This listener wraps around the normal listener to convert from module name to module id.
+ */
+public interface IModuleListener extends ITestInvocationListener {
+
+}
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/InvocationResultRepo.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/InvocationResultRepo.java
new file mode 100644
index 0000000..e046e12
--- /dev/null
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/InvocationResultRepo.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.tradefed.result;
+
+import com.android.compatibility.common.util.IInvocationResult;
+import com.android.compatibility.common.util.ResultHandler;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * An implementation of {@link IInvocationResultRepo}.
+ */
+public class InvocationResultRepo implements IInvocationResultRepo {
+
+    /**
+     * Ordered list of result directories. the index of each file is its session id.
+     */
+    private List<IInvocationResult> mResults;
+
+    /**
+     * Create a {@link InvocationResultRepo} from a directory of results
+     *
+     * @param testResultDir the parent directory of results
+     */
+    public InvocationResultRepo(File testResultDir) {
+        mResults = ResultHandler.getResults(testResultDir);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public List<IInvocationResult> getResults() {
+        return new ArrayList<IInvocationResult>(mResults);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public IInvocationResult getResult(int sessionId) {
+        if (sessionId < 0 || sessionId >= mResults.size()) {
+            return null;
+        }
+        return mResults.get(sessionId);
+    }
+
+}
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/ModuleListener.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/ModuleListener.java
new file mode 100644
index 0000000..f3ae7a3
--- /dev/null
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/ModuleListener.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.tradefed.result;
+
+import com.android.compatibility.common.tradefed.testtype.IModuleDef;
+import com.android.ddmlib.testrunner.TestIdentifier;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.log.LogUtil.CLog;
+import com.android.tradefed.result.ITestInvocationListener;
+import com.android.tradefed.result.InputStreamSource;
+import com.android.tradefed.result.LogDataType;
+import com.android.tradefed.result.TestSummary;
+
+import java.util.Map;
+
+/**
+ * Listener for Compatibility test info.
+ * <p>
+ * This listener wraps around the normal listener to convert from module name to module id.
+ */
+public class ModuleListener implements IModuleListener {
+
+    private IModuleDef mModule;
+    private ITestInvocationListener mListener;
+
+    /**
+     * @param module
+     * @param listener
+     */
+    public ModuleListener(IModuleDef module, ITestInvocationListener listener) {
+        mModule = module;
+        mListener = listener;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void invocationStarted(IBuildInfo buildInfo) {
+        CLog.d("ModuleListener.invocationStarted(%s)", buildInfo.toString());
+        mListener.invocationStarted(buildInfo);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void testRunStarted(String name, int numTests) {
+        CLog.d("ModuleListener.testRunStarted(%s, %d)", name, numTests);
+        mListener.testRunStarted(mModule.getId(), numTests);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void testStarted(TestIdentifier test) {
+        CLog.d("ModuleListener.testStarted(%s)", test.toString());
+        mListener.testStarted(test);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void testEnded(TestIdentifier test, Map<String, String> metrics) {
+        CLog.d("ModuleListener.testEnded(%s, %s)", test.toString(), metrics.toString());
+        mListener.testEnded(test, metrics);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void testIgnored(TestIdentifier test) {
+        CLog.d("ModuleListener.testIgnored(%s)", test.toString());
+        mListener.testIgnored(test);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void testFailed(TestIdentifier test, String trace) {
+        CLog.d("ModuleListener.testFailed(%s, %s)", test.toString(), trace);
+        mListener.testFailed(test, trace);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void testAssumptionFailure(TestIdentifier test, String trace) {
+        CLog.d("ModuleListener.testAssumptionFailure(%s, %s)", test.toString(), trace);
+        mListener.testAssumptionFailure(test, trace);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void testRunStopped(long elapsedTime) {
+        CLog.d("ModuleListener.testRunStopped(%d)", elapsedTime);
+        mListener.testRunStopped(elapsedTime);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void testRunEnded(long elapsedTime, Map<String, String> metrics) {
+        CLog.d("ModuleListener.testRunEnded(%d, %s)", elapsedTime, metrics.toString());
+        mListener.testRunEnded(elapsedTime, metrics);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void testRunFailed(String errorMessage) {
+        CLog.d("ModuleListener.testRunFailed(%s)", errorMessage);
+        mListener.testRunFailed(errorMessage);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public TestSummary getSummary() {
+        return mListener.getSummary();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void invocationEnded(long elapsedTime) {
+        CLog.d("ModuleListener.invocationEnded(%d)", elapsedTime);
+        mListener.invocationEnded(elapsedTime);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void invocationFailed(Throwable cause) {
+        CLog.d("ModuleListener.invocationFailed(%s)", cause.toString());
+        mListener.invocationFailed(cause);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void testLog(String name, LogDataType type, InputStreamSource stream) {
+        CLog.d("ModuleListener.testLog(%s, %s, %s)", name, type.toString(), stream.toString());
+        mListener.testLog(name, type, stream);
+    }
+
+}
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/ResultReporter.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/ResultReporter.java
new file mode 100644
index 0000000..9f9728b
--- /dev/null
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/ResultReporter.java
@@ -0,0 +1,491 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.tradefed.result;
+
+import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
+import com.android.compatibility.common.tradefed.testtype.CompatibilityTest;
+import com.android.compatibility.common.util.ICaseResult;
+import com.android.compatibility.common.util.IInvocationResult;
+import com.android.compatibility.common.util.IModuleResult;
+import com.android.compatibility.common.util.ITestResult;
+import com.android.compatibility.common.util.InvocationResult;
+import com.android.compatibility.common.util.MetricsStore;
+import com.android.compatibility.common.util.ReportLog;
+import com.android.compatibility.common.util.ResultHandler;
+import com.android.compatibility.common.util.ResultUploader;
+import com.android.compatibility.common.util.TestStatus;
+import com.android.ddmlib.Log;
+import com.android.ddmlib.Log.LogLevel;
+import com.android.ddmlib.testrunner.TestIdentifier;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.config.Option;
+import com.android.tradefed.config.Option.Importance;
+import com.android.tradefed.config.OptionClass;
+import com.android.tradefed.log.LogUtil.CLog;
+import com.android.tradefed.result.ILogSaver;
+import com.android.tradefed.result.ILogSaverListener;
+import com.android.tradefed.result.ITestInvocationListener;
+import com.android.tradefed.result.ITestSummaryListener;
+import com.android.tradefed.result.InputStreamSource;
+import com.android.tradefed.result.LogDataType;
+import com.android.tradefed.result.LogFile;
+import com.android.tradefed.result.LogFileSaver;
+import com.android.tradefed.result.TestSummary;
+import com.android.tradefed.util.FileUtil;
+import com.android.tradefed.util.StreamUtil;
+import com.android.tradefed.util.TimeUtil;
+
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+/**
+ * Reporter for Compatibility test results.
+ */
+@OptionClass(alias="result-reporter")
+public class ResultReporter implements ILogSaverListener, ITestInvocationListener,
+       ITestSummaryListener {
+
+    private static final String RESULT_KEY = "COMPATIBILITY_TEST_RESULT";
+    private static final String CTS_PREFIX = "cts:";
+    private static final String BUILD_INFO = CTS_PREFIX + "build_";
+    private static final String[] RESULT_RESOURCES = {
+        "compatibility_result.css",
+        "compatibility_result.xsd",
+        "compatibility_result.xsl",
+        "logo.png"};
+
+    @Option(name = CompatibilityTest.RETRY_OPTION,
+            shortName = 'r',
+            description = "retry a previous session.",
+            importance = Importance.IF_UNSET)
+    private Integer mRetrySessionId = null;
+
+    @Option(name = "quiet-output", description = "Mute display of test results.")
+    private boolean mQuietOutput = false;
+
+    @Option(name = "result-server", description = "Server to publish test results.")
+    private String mResultServer;
+
+    @Option(name = "disable-result-posting", description = "Disable result posting into report server.")
+    private boolean mDisableResultPosting = false;
+
+    @Option(name = "include-test-log-tags", description = "Include test log tags in report.")
+    private boolean mIncludeTestLogTags = false;
+
+    @Option(name = "use-log-saver", description = "Also saves generated result with log saver")
+    private boolean mUseLogSaver = false;
+
+    private String mDeviceSerial;
+
+    private IInvocationResult mResult;
+    private File mResultDir = null;
+    private File mLogDir = null;
+    private long mStartTime;
+    private ResultUploader mUploader;
+    private String mReferenceUrl;
+    private IModuleResult mCurrentModuleResult;
+    private ICaseResult mCurrentCaseResult;
+    private ITestResult mCurrentResult;
+    private IBuildInfo mBuild;
+    private CompatibilityBuildHelper mBuildHelper;
+    private ILogSaver mLogSaver;
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void invocationStarted(IBuildInfo buildInfo) {
+        mBuild = buildInfo;
+        mBuildHelper = new CompatibilityBuildHelper(mBuild);
+        mDeviceSerial = buildInfo.getDeviceSerial();
+        if (mDeviceSerial == null) {
+            mDeviceSerial = "unknown_device";
+        }
+        long time = System.currentTimeMillis();
+        String dirSuffix = getDirSuffix(time);
+        if (mRetrySessionId != null) {
+            CLog.d("[%s] Retrying session %d", mDeviceSerial, mRetrySessionId);
+            List<IInvocationResult> results = null;
+            try {
+                results = ResultHandler.getResults(mBuildHelper.getResultsDir());
+            } catch (FileNotFoundException e) {
+                e.printStackTrace();
+            }
+            if (results != null && mRetrySessionId >= 0 && mRetrySessionId < results.size()) {
+                mResult = results.get(mRetrySessionId);
+            } else {
+                throw new IllegalArgumentException(
+                        String.format("Could not find session %d",mRetrySessionId));
+            }
+            mStartTime = mResult.getStartTime();
+            mResultDir = mResult.getResultDir();
+        } else {
+            mStartTime = time;
+            try {
+                mResultDir = new File(mBuildHelper.getResultsDir(), dirSuffix);
+            } catch (FileNotFoundException e) {
+                e.printStackTrace();
+            }
+            if (mResultDir != null && mResultDir.mkdirs()) {
+                logResult("Created result dir %s", mResultDir.getAbsolutePath());
+            } else {
+                throw new IllegalArgumentException(String.format("Could not create result dir %s",
+                        mResultDir.getAbsolutePath()));
+            }
+            mResult = new InvocationResult(mStartTime, mResultDir);
+        }
+        mBuildHelper.setResultDir(mResultDir.getName());
+        mUploader = new ResultUploader(mResultServer, mBuildHelper.getSuiteName());
+        try {
+            mLogDir = new File(mBuildHelper.getLogsDir(), dirSuffix);
+        } catch (FileNotFoundException e) {
+            e.printStackTrace();
+        }
+        if (mLogDir != null && mLogDir.mkdirs()) {
+            logResult("Created log dir %s", mLogDir.getAbsolutePath());
+        } else {
+            throw new IllegalArgumentException(String.format("Could not create log dir %s",
+                    mLogDir.getAbsolutePath()));
+        }
+    }
+
+    /**
+     * @return a {@link String} to use for directory suffixes created from the given time.
+     */
+    private String getDirSuffix(long time) {
+        return new SimpleDateFormat("yyyy.MM.dd_HH.mm.ss").format(new Date(time));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void testRunStarted(String id, int numTests) {
+        logResult("Starting %s with %d test%s", id, numTests, (numTests > 1) ? "s" : "");
+        mCurrentModuleResult = mResult.getOrCreateModule(id);
+        mResult.addDeviceSerial(mDeviceSerial);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void testStarted(TestIdentifier test) {
+        mCurrentCaseResult = mCurrentModuleResult.getOrCreateResult(test.getClassName());
+        mCurrentResult = mCurrentCaseResult.getOrCreateResult(test.getTestName().trim());
+        mCurrentResult.reset();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void testEnded(TestIdentifier test, Map<String, String> metrics) {
+        if (mCurrentResult.getResultStatus() == TestStatus.FAIL) {
+            logResult("%s has previously failed", test);
+            // Test has previously failed.
+            return;
+        }
+        // device test can have performance results in test metrics
+        String perfResult = metrics.get(RESULT_KEY);
+        ReportLog report = null;
+        if (perfResult != null) {
+            try {
+                report = ReportLog.parse(perfResult);
+            } catch (XmlPullParserException | IOException e) {
+                e.printStackTrace();
+            }
+        } else {
+            // host test should be checked into MetricsStore.
+            report = MetricsStore.removeResult(
+                    mDeviceSerial, mCurrentModuleResult.getAbi(), test.toString());
+        }
+        mCurrentResult.passed(report);
+        logResult("%s passed", test);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void testIgnored(TestIdentifier test) {
+        mCurrentResult.notExecuted();
+        logResult("%s ignored", test);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void testFailed(TestIdentifier test, String trace) {
+        mCurrentResult.failed(trace);
+        logResult("%s failed: %s", test, trace);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void testAssumptionFailure(TestIdentifier test, String trace) {
+        mCurrentResult.notExecuted();
+        logResult("%s failed assumption: %s", test, trace);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void testRunStopped(long elapsedTime) {
+        logResult("%s stopped after %s", mCurrentModuleResult.getId(),
+                TimeUtil.formatElapsedTime(elapsedTime));
+        // ignore
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void testRunEnded(long elapsedTime, Map<String, String> metrics) {
+        // Get device info from build attributes
+        for (Entry<String, String> entry : mBuild.getBuildAttributes().entrySet()) {
+            String key = entry.getKey();
+            if (key.startsWith(BUILD_INFO)) {
+                mResult.addBuildInfo(key.substring(CTS_PREFIX.length()), entry.getValue());
+            }
+        }
+        mCurrentModuleResult.addRuntime(elapsedTime);
+        logResult("%s completed in %s. %d passed, %d failed, %d not executed",
+                mCurrentModuleResult.getId(),
+                TimeUtil.formatElapsedTime(elapsedTime),
+                mCurrentModuleResult.countResults(TestStatus.PASS),
+                mCurrentModuleResult.countResults(TestStatus.FAIL),
+                mCurrentModuleResult.countResults(TestStatus.NOT_EXECUTED));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void testRunFailed(String id) {
+        logResult("%s failed to run", id);
+        // ignore
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public TestSummary getSummary() {
+        // ignore
+        return null;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void putSummary(List<TestSummary> summaries) {
+        if (summaries.size() > 0) {
+            mReferenceUrl = summaries.get(0).getSummary().getString();
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void invocationEnded(long elapsedTime) {
+        logResult("Invocation completed in %s. %d passed, %d failed, %d not executed",
+                TimeUtil.formatElapsedTime(elapsedTime),
+                mResult.countResults(TestStatus.PASS),
+                mResult.countResults(TestStatus.FAIL),
+                mResult.countResults(TestStatus.NOT_EXECUTED));
+        try {
+            File resultFile = ResultHandler.writeResults(mBuildHelper.getSuiteName(),
+                    mBuildHelper.getSuiteVersion(), mBuildHelper.getSuitePlan(),
+                    mBuildHelper.getSuiteBuild(), mResult, mResultDir, mStartTime,
+                    elapsedTime + mStartTime, mReferenceUrl);
+            logResult("Result saved at: %s", resultFile.getCanonicalPath());
+            copyDynamicConfigFiles(mBuildHelper.getDynamicConfigFiles(), mResultDir);
+            copyFormattingFiles(mResultDir);
+            zipResults(mResultDir);
+            if (mUseLogSaver) {
+                FileInputStream fis = null;
+                try {
+                    fis = new FileInputStream(resultFile);
+                    mLogSaver.saveLogData("log-result", LogDataType.XML, fis);
+                } catch (IOException ioe) {
+                    CLog.e("[%s] error saving XML with log saver", mDeviceSerial);
+                    CLog.e(ioe);
+                } finally {
+                    StreamUtil.close(fis);
+                }
+            }
+            if (mResultServer != null && !mResultServer.trim().isEmpty() && !mDisableResultPosting) {
+                try {
+                    logResult("Result Server Response: %d",
+                            mUploader.uploadResult(resultFile, mReferenceUrl));
+                } catch (IOException ioe) {
+                    CLog.e("[%s] IOException while uploading result.", mDeviceSerial);
+                    CLog.e(ioe);
+                }
+            }
+        } catch (IOException | XmlPullParserException e) {
+            CLog.e("[%s] Exception while saving result XML.", mDeviceSerial);
+            CLog.e(e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void invocationFailed(Throwable cause) {
+        logResult("Invocation failed: %s", cause);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void testLog(String name, LogDataType type, InputStreamSource stream) {
+        try {
+            LogFileSaver saver = new LogFileSaver(mLogDir);
+            File logFile = saver.saveAndZipLogData(name, type, stream.createInputStream());
+            logResult("Saved logs for %s in %s", name, logFile.getAbsolutePath());
+        } catch (IOException e) {
+            logResult("Failed to write log for %s", name);
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void testLogSaved(String dataName, LogDataType dataType, InputStreamSource dataStream,
+            LogFile logFile) {
+        if (mIncludeTestLogTags && mCurrentResult != null
+                && dataName.startsWith(mCurrentResult.getFullName())) {
+            if (dataType == LogDataType.BUGREPORT) {
+                mCurrentResult.setBugReport(logFile.getUrl());
+            } else if (dataType == LogDataType.LOGCAT) {
+                mCurrentResult.setLog(logFile.getUrl());
+            } else if (dataType == LogDataType.PNG) {
+                mCurrentResult.setScreenshot(logFile.getUrl());
+            }
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setLogSaver(ILogSaver saver) {
+        mLogSaver = saver;
+    }
+
+    /**
+     * Copy the xml formatting files stored in this jar to the results directory
+     *
+     * @param resultsDir
+     */
+    static void copyFormattingFiles(File resultsDir) {
+        for (String resultFileName : RESULT_RESOURCES) {
+            InputStream configStream = ResultHandler.class.getResourceAsStream(
+                    String.format("/report/%s", resultFileName));
+            if (configStream != null) {
+                File resultFile = new File(resultsDir, resultFileName);
+                try {
+                    FileUtil.writeToFile(configStream, resultFile);
+                } catch (IOException e) {
+                    Log.w(ResultReporter.class.getSimpleName(),
+                            String.format("Failed to write %s to file", resultFileName));
+                }
+            } else {
+                Log.w(ResultReporter.class.getSimpleName(),
+                        String.format("Failed to load %s from jar", resultFileName));
+            }
+        }
+    }
+
+    /**
+     * move the dynamic config files to the results directory
+     *
+     * @param configFiles
+     * @param resultsDir
+     */
+    static void copyDynamicConfigFiles(Map<String, File> configFiles, File resultsDir) {
+        if (configFiles.size() == 0) return;
+
+        File folder = new File(resultsDir, "config");
+        folder.mkdir();
+        for (String moduleName : configFiles.keySet()) {
+            File resultFile = new File(folder, moduleName+".dynamic");
+            try {
+                FileUtil.copyFile(configFiles.get(moduleName), resultFile);
+                FileUtil.deleteFile(configFiles.get(moduleName));
+            } catch (IOException e) {
+                Log.w(ResultReporter.class.getSimpleName(),
+                        String.format("Failed to copy config file for %s to file", moduleName));
+            }
+        }
+    }
+
+    /**
+     * Zip the contents of the given results directory.
+     *
+     * @param resultsDir
+     */
+    @SuppressWarnings("deprecation")
+    private static void zipResults(File resultsDir) {
+        try {
+            // create a file in parent directory, with same name as resultsDir
+            File zipResultFile = new File(resultsDir.getParent(), String.format("%s.zip",
+                    resultsDir.getName()));
+            FileUtil.createZip(resultsDir, zipResultFile);
+        } catch (IOException e) {
+            Log.w(ResultReporter.class.getSimpleName(),
+                    String.format("Failed to create zip for %s", resultsDir.getName()));
+        }
+    }
+
+    /**
+     * @return the mResult
+     */
+    public IInvocationResult getResult() {
+        return mResult;
+    }
+
+    private void logResult(String format, Object... args) {
+        format = String.format("[%s] %s", mDeviceSerial, format);
+        if (mQuietOutput) {
+            CLog.i(format, args);
+        } else {
+            CLog.logAndDisplay(LogLevel.INFO, format, args);
+        }
+    }
+}
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/ApkInstaller.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/ApkInstaller.java
new file mode 100644
index 0000000..7773d7d
--- /dev/null
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/ApkInstaller.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.tradefed.targetprep;
+
+import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.config.OptionClass;
+import com.android.tradefed.targetprep.TargetSetupError;
+import com.android.tradefed.targetprep.TestAppInstallSetup;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+
+/**
+ * Installs specified APKs from Compatibility repository.
+ */
+@OptionClass(alias="apk-installer")
+public class ApkInstaller extends TestAppInstallSetup {
+
+    private CompatibilityBuildHelper mBuildHelper = null;
+
+    protected File getTestsDir(IBuildInfo buildInfo) throws FileNotFoundException {
+        if (mBuildHelper == null) {
+            mBuildHelper = new CompatibilityBuildHelper(buildInfo);
+        }
+        return mBuildHelper.getTestsDir();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected File getLocalPathForFilename(IBuildInfo buildInfo, String apkFileName)
+            throws TargetSetupError {
+        File apkFile = null;
+        try {
+            apkFile = new File(getTestsDir(buildInfo), apkFileName);
+            if (!apkFile.isFile()) {
+                throw new FileNotFoundException();
+            }
+        } catch (FileNotFoundException e) {
+            throw new TargetSetupError(String.format("%s not found", apkFileName), e);
+        }
+        return apkFile;
+    }
+}
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/ApkInstrumentationPreparer.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/ApkInstrumentationPreparer.java
new file mode 100644
index 0000000..33ee5d8
--- /dev/null
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/ApkInstrumentationPreparer.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.compatibility.common.tradefed.targetprep;
+
+import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
+import com.android.compatibility.common.tradefed.testtype.CompatibilityTest;
+import com.android.compatibility.common.tradefed.util.NoOpTestInvocationListener;
+import com.android.ddmlib.testrunner.TestIdentifier;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.config.Option;
+import com.android.tradefed.config.Option.Importance;
+import com.android.tradefed.config.OptionClass;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.result.ITestInvocationListener;
+import com.android.tradefed.targetprep.BuildError;
+import com.android.tradefed.targetprep.ITargetCleaner;
+import com.android.tradefed.targetprep.TargetSetupError;
+import com.android.tradefed.testtype.AndroidJUnitTest;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Target preparer that instruments an APK.
+ */
+@OptionClass(alias="apk-instrumentation-preparer")
+public class ApkInstrumentationPreparer extends PreconditionPreparer implements ITargetCleaner {
+
+    @Option(name = "apk", description = "Name of the apk to instrument", mandatory = true)
+    protected String mApkFileName = null;
+
+    @Option(name = "package", description = "Name of the package", mandatory = true)
+    protected String mPackageName = null;
+
+    @Option(name = CompatibilityTest.INCLUDE_FILTER_OPTION,
+            description = "the include module filters to apply.",
+            importance = Importance.ALWAYS)
+    private List<String> mIncludeFilters = new ArrayList<>();
+
+    @Option(name = CompatibilityTest.EXCLUDE_FILTER_OPTION,
+            description = "the exclude module filters to apply.",
+            importance = Importance.ALWAYS)
+    private List<String> mExcludeFilters = new ArrayList<>();
+
+    public enum When {
+        BEFORE, AFTER, BOTH;
+    }
+
+    @Option(name = "when", description = "When to instrument the apk", mandatory = true)
+    protected When mWhen = null;
+
+    protected ConcurrentHashMap<TestIdentifier, Map<String, String>> testMetrics =
+            new ConcurrentHashMap<>();
+    private ConcurrentHashMap<TestIdentifier, String> testFailures = new ConcurrentHashMap<>();
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void run(ITestDevice device, IBuildInfo buildInfo) throws TargetSetupError,
+            BuildError, DeviceNotAvailableException {
+        if (mWhen == When.AFTER) {
+            return;
+        }
+        try {
+            if (instrument(device, buildInfo)) {
+                logInfo("Target preparation successful");
+            } else {
+                throw new TargetSetupError("Not all target preparation steps completed");
+            }
+        } catch (FileNotFoundException e) {
+            throw new TargetSetupError("Couldn't find apk to instrument", e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void tearDown(ITestDevice device, IBuildInfo buildInfo, Throwable e)
+            throws DeviceNotAvailableException {
+        if (e instanceof DeviceNotAvailableException) {
+            return;
+        }
+        if (mWhen == When.BEFORE) {
+            return;
+        }
+        try {
+            instrument(device, buildInfo);
+        } catch (FileNotFoundException e1) {
+            logError("Couldn't find apk to instrument");
+            logError(e1);
+        }
+    }
+
+    private boolean instrument(ITestDevice device, IBuildInfo buildInfo)
+            throws DeviceNotAvailableException, FileNotFoundException {
+        ITestInvocationListener listener = new TargetPreparerListener();
+        CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(buildInfo);
+
+        File testsDir = buildHelper.getTestsDir();
+        File apkFile = new File(testsDir, mApkFileName);
+        if (!apkFile.exists()) {
+            throw new FileNotFoundException(String.format("%s not found", mApkFileName));
+        }
+
+        if (device.getAppPackageInfo(mPackageName) != null) {
+            logInfo("Package %s already present on the device, uninstalling ...", mPackageName);
+            device.uninstallPackage(mPackageName);
+        }
+
+        logInfo("Instrumenting package %s:", mPackageName);
+        AndroidJUnitTest instrTest = new AndroidJUnitTest();
+        instrTest.setDevice(device);
+        instrTest.setInstallFile(apkFile);
+        instrTest.setPackageName(mPackageName);
+        instrTest.addAllIncludeFilters(mIncludeFilters);
+        instrTest.addAllExcludeFilters(mExcludeFilters);
+        instrTest.run(listener);
+        boolean success = true;
+        if (!testFailures.isEmpty()) {
+            for (TestIdentifier test : testFailures.keySet()) {
+                success = false;
+                String trace = testFailures.get(test);
+                logError("Target preparation step %s failed.\n%s", test.getTestName(), trace);
+            }
+        }
+        return success;
+    }
+
+    public class TargetPreparerListener extends NoOpTestInvocationListener {
+
+        @Override
+        public void testEnded(TestIdentifier test, Map<String, String> metrics) {
+            testMetrics.put(test, metrics);
+        }
+
+        @Override
+        public void testFailed(TestIdentifier test, String trace) {
+            testFailures.put(test, trace);
+        }
+
+    }
+
+}
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/ApkPreconditionCheck.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/ApkPreconditionCheck.java
new file mode 100644
index 0000000..0f0b6c2
--- /dev/null
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/ApkPreconditionCheck.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.tradefed.targetprep;
+
+import com.android.tradefed.config.OptionClass;
+
+/**
+ * Runs a precondition test by instrumenting an APK
+ */
+@OptionClass(alias="apk-precondition-check")
+public class ApkPreconditionCheck extends ApkInstrumentationPreparer {
+
+    public ApkPreconditionCheck() {
+        mWhen = When.BEFORE;
+    }
+
+}
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/DeviceInfoCollector.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/DeviceInfoCollector.java
new file mode 100644
index 0000000..651dc7b
--- /dev/null
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/DeviceInfoCollector.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.compatibility.common.tradefed.targetprep;
+
+import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
+import com.android.compatibility.common.tradefed.testtype.CompatibilityTest;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.config.Option;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.log.LogUtil.CLog;
+import com.android.tradefed.targetprep.BuildError;
+import com.android.tradefed.targetprep.TargetSetupError;
+import com.android.tradefed.util.ArrayUtil;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+/**
+ * An {@link ApkInstrumentationPreparer} that collects device info.
+ */
+public class DeviceInfoCollector extends ApkInstrumentationPreparer {
+
+    private static final Map<String, String> BUILD_KEYS = new HashMap<>();
+    static {
+        BUILD_KEYS.put("cts:build_id", "ro.build.id");
+        BUILD_KEYS.put("cts:build_product", "ro.product.name");
+        BUILD_KEYS.put("cts:build_device", "ro.product.device");
+        BUILD_KEYS.put("cts:build_board", "ro.product.board");
+        BUILD_KEYS.put("cts:build_manufacturer", "ro.product.manufacturer");
+        BUILD_KEYS.put("cts:build_brand", "ro.product.brand");
+        BUILD_KEYS.put("cts:build_model", "ro.product.model");
+        BUILD_KEYS.put("cts:build_type", "ro.build.type");
+        BUILD_KEYS.put("cts:build_tags", "ro.build.tags");
+        BUILD_KEYS.put("cts:build_fingerprint", "ro.build.fingerprint");
+        BUILD_KEYS.put("cts:build_abi", "ro.product.cpu.abi");
+        BUILD_KEYS.put("cts:build_abi2", "ro.product.cpu.abi2");
+        BUILD_KEYS.put("cts:build_abis", "ro.product.cpu.abilist");
+        BUILD_KEYS.put("cts:build_abis_32", "ro.product.cpu.abilist32");
+        BUILD_KEYS.put("cts:build_abis_64", "ro.product.cpu.abilist64");
+        BUILD_KEYS.put("cts:build_serial", "ro.serialno");
+        BUILD_KEYS.put("cts:build_version_release", "ro.build.version.release");
+        BUILD_KEYS.put("cts:build_version_sdk", "ro.build.version.sdk");
+        BUILD_KEYS.put("cts:build_version_base_os", "ro.build.version.base_os");
+        BUILD_KEYS.put("cts:build_version_security_patch", "ro.build.version.security_patch");
+    }
+
+    @Option(name = CompatibilityTest.SKIP_DEVICE_INFO_OPTION,
+            shortName = 'd',
+            description = "Whether device info collection should be skipped")
+    private boolean mSkipDeviceInfo = false;
+
+    @Option(name= "src-dir", description = "The directory to copy to the results dir")
+    private String mSrcDir;
+
+    @Option(name = "dest-dir", description = "The directory under the result to store the files")
+    private String mDestDir;
+
+    public DeviceInfoCollector() {
+        mWhen = When.BEFORE;
+    }
+
+    @Override
+    public void setUp(ITestDevice device, IBuildInfo buildInfo) throws TargetSetupError,
+            BuildError, DeviceNotAvailableException {
+        if (mSkipDeviceInfo) {
+            return;
+        }
+        for (Entry<String, String> entry : BUILD_KEYS.entrySet()) {
+            buildInfo.addBuildAttribute(entry.getKey(),
+                    ArrayUtil.join(",", device.getProperty(entry.getValue())));
+        }
+        run(device, buildInfo);
+        getDeviceInfoFiles(device, buildInfo);
+    }
+
+    private void getDeviceInfoFiles(ITestDevice device, IBuildInfo buildInfo) {
+        CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(buildInfo);
+        try {
+            File resultDir = buildHelper.getResultDir();
+            if (mDestDir != null) {
+                resultDir = new File(resultDir, mDestDir);
+            }
+            resultDir.mkdirs();
+            if (!resultDir.isDirectory()) {
+                CLog.e("%s is not a directory", resultDir.getAbsolutePath());
+                return;
+            }
+            String resultPath = resultDir.getAbsolutePath();
+            pull(device, mSrcDir, resultPath);
+        } catch (FileNotFoundException fnfe) {
+            fnfe.printStackTrace();
+        }
+    }
+
+    private void pull(ITestDevice device, String src, String dest) {
+        String command = String.format("adb -s %s pull %s %s", device.getSerialNumber(), src, dest);
+        try {
+            Process p = Runtime.getRuntime().exec(new String[] {"/bin/bash", "-c", command});
+            if (p.waitFor() != 0) {
+                CLog.e("Failed to run %s", command);
+            }
+        } catch (Exception e) {
+            CLog.e("Caught exception during pull.");
+            CLog.e(e);
+        }
+    }
+}
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/DynamicConfigPusher.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/DynamicConfigPusher.java
new file mode 100644
index 0000000..1a4be53
--- /dev/null
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/DynamicConfigPusher.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.tradefed.targetprep;
+
+import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
+import com.android.compatibility.common.util.DynamicConfig;
+import com.android.compatibility.common.util.DynamicConfigHandler;
+import com.android.ddmlib.Log;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.config.Option;
+import com.android.tradefed.config.OptionClass;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.log.LogUtil;
+import com.android.tradefed.targetprep.BuildError;
+import com.android.tradefed.targetprep.ITargetCleaner;
+import com.android.tradefed.targetprep.TargetSetupError;
+import com.android.tradefed.util.FileUtil;
+import com.android.tradefed.util.StreamUtil;
+
+import org.json.JSONException;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.net.URL;
+
+/**
+ * Pushes dynamic config files from config repository
+ */
+@OptionClass(alias="dynamic-config-pusher")
+public class DynamicConfigPusher implements ITargetCleaner {
+    public enum TestTarget {
+        DEVICE,
+        HOST
+    }
+
+    private static final String LOG_TAG = DynamicConfigPusher.class.getSimpleName();
+
+    @Option(name = "cleanup", description = "Whether to remove config files from the test " +
+            "target after test completion.")
+    private boolean mCleanup = true;
+
+    @Option(name="config-filename", description = "The module name for module-level " +
+            "configurations, or the suite name for suite-level configurations")
+    private String mModuleName;
+
+    @Option(name = "target", description = "The test target, \"device\" or \"host\"")
+    private TestTarget mTarget;
+
+    @Option(name = "version", description = "The version of the configuration to retrieve " +
+            "from the server, e.g. \"1\"")
+    private static String mVersion;
+
+
+    private String mFilePushed;
+
+    void setModuleName(String moduleName) {
+        mModuleName = moduleName;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setUp(ITestDevice device, IBuildInfo buildInfo) throws TargetSetupError, BuildError,
+            DeviceNotAvailableException {
+
+        CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(buildInfo);
+
+        File localConfigFile = null;
+        try {
+            localConfigFile = DynamicConfig.getConfigFile(buildHelper.getTestsDir(), mModuleName);
+        } catch (FileNotFoundException e) {
+            throw new TargetSetupError(
+                    "Cannot get local dynamic config file from test directory", e);
+        }
+
+        String apfeConfigInJson = null;
+        String originUrl = buildHelper.getDynamicConfigUrl();
+
+        if (originUrl != null) {
+            try {
+                String requestUrl = originUrl
+                        .replace("{module}", mModuleName).replace("{version}", mVersion);
+                java.net.URL request = new URL(requestUrl);
+                apfeConfigInJson = StreamUtil.getStringFromStream(request.openStream());
+            } catch (IOException e) {
+                LogUtil.printLog(Log.LogLevel.WARN, LOG_TAG,
+                        "Cannot download and parse json config from URL");
+            }
+        } else {
+            LogUtil.printLog(Log.LogLevel.INFO, LOG_TAG,
+                    "Dynamic config override URL is not set, using local configuration values");
+        }
+
+        File src = null;
+        try {
+            src = DynamicConfigHandler.getMergedDynamicConfigFile(
+                    localConfigFile, apfeConfigInJson, mModuleName);
+        } catch (IOException | XmlPullParserException | JSONException e) {
+            throw new TargetSetupError("Cannot get merged dynamic config file", e);
+        }
+
+        switch (mTarget) {
+            case DEVICE:
+                String deviceDest = DynamicConfig.CONFIG_FOLDER_ON_DEVICE + src.getName();
+                if (!device.pushFile(src, deviceDest)) {
+                    throw new TargetSetupError(String.format(
+                            "Failed to push local '%s' to remote '%s'",
+                            src.getAbsolutePath(), deviceDest));
+                } else {
+                    mFilePushed = deviceDest;
+                    buildHelper.addDynamicConfigFile(mModuleName, src);
+                }
+                break;
+
+            case HOST:
+                File storageDir = new File(DynamicConfig.CONFIG_FOLDER_ON_HOST);
+                if (!storageDir.exists()) {
+                    storageDir.mkdir();
+                }
+                File hostDest = new File(DynamicConfig.CONFIG_FOLDER_ON_HOST + src.getName());
+                try {
+                    FileUtil.copyFile(src, hostDest);
+                } catch (IOException e) {
+                    throw new TargetSetupError(String.format("Failed to copy file from %s to %s",
+                            src.getAbsolutePath(), hostDest.getAbsolutePath()), e);
+                }
+                mFilePushed = hostDest.getAbsolutePath();
+                buildHelper.addDynamicConfigFile(mModuleName, src);
+                break;
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void tearDown(ITestDevice device, IBuildInfo buildInfo, Throwable e)
+            throws DeviceNotAvailableException {
+        switch (mTarget) {
+            case DEVICE:
+                if (!(e instanceof DeviceNotAvailableException)
+                        && mCleanup && mFilePushed != null) {
+                    device.executeShellCommand("rm -r " + mFilePushed);
+                }
+                break;
+            case HOST:
+                new File(mFilePushed).delete();
+        }
+    }
+}
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/FilePusher.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/FilePusher.java
new file mode 100644
index 0000000..70dc125
--- /dev/null
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/FilePusher.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.tradefed.targetprep;
+
+import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
+import com.android.ddmlib.Log.LogLevel;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.config.Option;
+import com.android.tradefed.config.OptionClass;
+import com.android.tradefed.log.LogUtil.CLog;
+import com.android.tradefed.targetprep.PushFilePreparer;
+import com.android.tradefed.testtype.IAbi;
+import com.android.tradefed.testtype.IAbiReceiver;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+
+/**
+ * Pushes specified testing artifacts from Compatibility repository.
+ */
+@OptionClass(alias="file-pusher")
+public class FilePusher extends PushFilePreparer implements IAbiReceiver {
+
+    @Option(name = "append-bitness",
+            description = "Append the ABI's bitness to the filename.")
+    private boolean mAppendBitness = false;
+
+    private CompatibilityBuildHelper mBuildHelper = null;
+
+    private IAbi mAbi;
+
+    protected File getTestsDir(IBuildInfo buildInfo) throws FileNotFoundException {
+        if (mBuildHelper == null) {
+            mBuildHelper = new CompatibilityBuildHelper(buildInfo);
+        }
+        return mBuildHelper.getTestsDir();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setAbi(IAbi abi) {
+        mAbi = abi;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public File resolveRelativeFilePath(IBuildInfo buildInfo, String fileName) {
+        try {
+            File f = new File(getTestsDir(buildInfo),
+                    String.format("%s%s", fileName, mAppendBitness ? mAbi.getBitness() : ""));
+            CLog.logAndDisplay(LogLevel.INFO, "Copying from %s", f.getAbsolutePath());
+            return f;
+        } catch (FileNotFoundException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+}
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/LocationCheck.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/LocationCheck.java
new file mode 100644
index 0000000..94bc64f
--- /dev/null
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/LocationCheck.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.tradefed.targetprep;
+
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.config.Option;
+import com.android.tradefed.config.OptionClass;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.targetprep.BuildError;
+import com.android.tradefed.targetprep.TargetSetupError;
+
+/**
+ * Checks that location is enabled for GPS or Network before running a compatibility test
+ */
+@OptionClass(alias="location-check")
+public class LocationCheck extends SettingsPreparer {
+
+    private static final String LOCATION_SETTING = "location_providers_allowed";
+
+    private static final String GPS = "gps";
+    private static final String NETWORK = "network";
+
+    private static final String GPS_FEATURE = "android.hardware.location.gps";
+    private static final String NETWORK_FEATURE = "android.hardware.location.network";
+
+
+    private boolean hasLocationFeature(ITestDevice device) throws DeviceNotAvailableException {
+        String adbFeatures = device.executeShellCommand("pm list features");
+        return (adbFeatures.contains(GPS_FEATURE) || adbFeatures.contains(NETWORK_FEATURE));
+    }
+
+    @Override
+    public void run(ITestDevice device, IBuildInfo buildInfo) throws TargetSetupError,
+            BuildError, DeviceNotAvailableException {
+
+        if (!hasLocationFeature(device)) {
+            return; // skip this precondition if required location feature is not present
+        }
+
+        logInfo("Verifying location setting");
+        mSettingName = LOCATION_SETTING;
+        mSettingType = SettingsPreparer.SettingType.SECURE;
+        mExpectedSettingValues.add(NETWORK);
+        mExpectedSettingValues.add(GPS);
+        mExpectedSettingValues.add(String.format("%s,%s", GPS, NETWORK));
+        mExpectedSettingValues.add(String.format("%s,%s", NETWORK, GPS));
+        mFailureMessage = "Location services must be enabled via GPS or Network in order to " +
+                "successfully run the test suite";
+        super.run(device, buildInfo);
+    }
+}
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/PreconditionPreparer.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/PreconditionPreparer.java
new file mode 100644
index 0000000..fc25e03
--- /dev/null
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/PreconditionPreparer.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.compatibility.common.tradefed.targetprep;
+
+import com.android.compatibility.common.tradefed.testtype.CompatibilityTest;
+import com.android.ddmlib.Log;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.config.Option;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.log.LogUtil;
+import com.android.tradefed.targetprep.BuildError;
+import com.android.tradefed.targetprep.ITargetPreparer;
+import com.android.tradefed.targetprep.TargetSetupError;
+
+/**
+ * An {@link ITargetPreparer} that performs checks and/or tasks to ensure the
+ * the device is ready to run the test suite.
+ */
+public abstract class PreconditionPreparer implements ITargetPreparer {
+
+    @Option(name = CompatibilityTest.SKIP_PRECONDITIONS_OPTION,
+            shortName = 'o',
+            description = "Whether preconditions should be skipped")
+    private boolean mSkipPreconditions = false;
+
+    protected final String LOG_TAG = getClass().getSimpleName();
+
+    @Override
+    public void setUp(ITestDevice device, IBuildInfo buildInfo) throws TargetSetupError,
+            BuildError, DeviceNotAvailableException {
+        if (!mSkipPreconditions) {
+            run(device, buildInfo);
+        }
+    }
+
+    public abstract void run(ITestDevice device, IBuildInfo buildInfo)
+            throws TargetSetupError, BuildError, DeviceNotAvailableException;
+
+    protected void logInfo(String info) {
+        LogUtil.printLog(Log.LogLevel.INFO, LOG_TAG, info);
+    }
+
+    protected void logInfo(String infoFormat, Object... args) {
+        LogUtil.printLog(Log.LogLevel.INFO, LOG_TAG, String.format(infoFormat, args));
+    }
+
+    protected void logWarning(String warning) {
+        LogUtil.printLog(Log.LogLevel.WARN, LOG_TAG, warning);
+    }
+
+    protected void logWarning(String warningFormat, Object... args) {
+        LogUtil.printLog(Log.LogLevel.WARN, LOG_TAG, String.format(warningFormat, args));
+    }
+
+    protected void logError(String error) {
+        LogUtil.printLog(Log.LogLevel.ERROR, LOG_TAG, error);
+    }
+
+    protected void logError(String errorFormat, Object... args) {
+        LogUtil.printLog(Log.LogLevel.ERROR, LOG_TAG, String.format(errorFormat, args));
+    }
+
+    protected void logError(Throwable t) {
+        if (t != null) {
+            Log.e(LOG_TAG, t);
+        }
+    }
+
+}
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/PropertyCheck.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/PropertyCheck.java
new file mode 100644
index 0000000..79f19d0
--- /dev/null
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/PropertyCheck.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.tradefed.targetprep;
+
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.config.Option;
+import com.android.tradefed.config.OptionClass;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.targetprep.BuildError;
+import com.android.tradefed.targetprep.TargetSetupError;
+
+/**
+ * Checks that a device property is as expected
+ */
+@OptionClass(alias="property-check")
+public class PropertyCheck extends PreconditionPreparer {
+
+    @Option(name = "property-name", description = "The name of the property to check",
+            mandatory = true)
+    protected String mPropertyName = null;
+
+    @Option(name = "expected-value", description = "The expected value of the property",
+            mandatory = true)
+    protected String mExpectedPropertyValue = null;
+
+    @Option(name = "throw-error",
+            description = "Whether to throw an error for an unexpected property value")
+    protected boolean mThrowError = false;
+
+    private static final String LOG_TAG = PropertyCheck.class.getSimpleName();
+
+    @Override
+    public void run(ITestDevice device, IBuildInfo buildInfo) throws TargetSetupError,
+            BuildError, DeviceNotAvailableException {
+
+        String propertyValue = device.getProperty(mPropertyName);
+        if (propertyValue == null) {
+            logWarning("Property \"%s\" not found on device, cannot verify value \"%s\" ",
+                    mPropertyName, mExpectedPropertyValue);
+            return;
+        }
+
+        if (!mExpectedPropertyValue.equalsIgnoreCase(propertyValue)) {
+            String msg = String.format("Expected \"%s\" but found \"%s\" for property: %s",
+                    mExpectedPropertyValue, propertyValue, mPropertyName);
+            // Handle unexpected property value with either exception or warning
+            if(mThrowError) {
+                throw new TargetSetupError(msg);
+            } else {
+                logWarning(msg);
+            }
+        }
+    }
+
+}
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/ReportLogCollector.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/ReportLogCollector.java
new file mode 100644
index 0000000..1ee7dd3
--- /dev/null
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/ReportLogCollector.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.compatibility.common.tradefed.targetprep;
+
+import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.config.Option;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.log.LogUtil.CLog;
+import com.android.tradefed.targetprep.BuildError;
+import com.android.tradefed.targetprep.ITargetCleaner;
+import com.android.tradefed.targetprep.TargetSetupError;
+import com.android.tradefed.util.FileUtil;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileWriter;
+import java.io.IOException;
+
+/**
+ * An {@link ITargetCleaner} that prepares and pulls report logs.
+ */
+public class ReportLogCollector implements ITargetCleaner {
+
+    @Option(name= "src-dir", description = "The directory to copy to the results dir")
+    private String mSrcDir;
+
+    @Option(name = "dest-dir", description = "The directory under the result to store the files")
+    private String mDestDir;
+
+    @Option(name = "temp-dir", description = "The temp directory containing host-side report logs")
+    private String mTempReportFolder;
+
+    public ReportLogCollector() {
+    }
+
+    @Override
+    public void setUp(ITestDevice device, IBuildInfo buildInfo) throws TargetSetupError,
+            BuildError, DeviceNotAvailableException {
+        prepareReportLogContainers(device, buildInfo);
+    }
+
+    private void addBuildInfo(ITestDevice device, IBuildInfo buildInfo, String key, String value)
+            throws DeviceNotAvailableException {
+    }
+
+    private void prepareReportLogContainers(ITestDevice device, IBuildInfo buildInfo) {
+        CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(buildInfo);
+        try {
+            File resultDir = buildHelper.getResultDir();
+            if (mDestDir != null) {
+                resultDir = new File(resultDir, mDestDir);
+            }
+            resultDir.mkdirs();
+            if (!resultDir.isDirectory()) {
+                CLog.e("%s is not a directory", resultDir.getAbsolutePath());
+                return;
+            }
+        } catch (FileNotFoundException fnfe) {
+            fnfe.printStackTrace();
+        }
+    }
+
+    @Override
+    public void tearDown(ITestDevice device, IBuildInfo buildInfo, Throwable e) {
+        // Pull report log files from device.
+        CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(buildInfo);
+        try {
+            File resultDir = buildHelper.getResultDir();
+            if (mDestDir != null) {
+                resultDir = new File(resultDir, mDestDir);
+            }
+            resultDir.mkdirs();
+            if (!resultDir.isDirectory()) {
+                CLog.e("%s is not a directory", resultDir.getAbsolutePath());
+                return;
+            }
+            String resultPath = resultDir.getAbsolutePath();
+            final File hostReportDir = FileUtil.createNamedTempDir(mTempReportFolder);
+            if (!hostReportDir.isDirectory()) {
+                CLog.e("%s is not a directory", hostReportDir.getAbsolutePath());
+                return;
+            }
+            String hostReportsPath = hostReportDir.getAbsolutePath();
+            pull(device, mSrcDir, hostReportsPath, resultPath);
+        } catch (Exception exception) {
+            exception.printStackTrace();
+        }
+    }
+
+    private void pull(ITestDevice device, String deviceSrc, String hostSrc, String dest) {
+        String deviceSideCommand = String.format("adb -s %s pull %s %s", device.getSerialNumber(),
+                deviceSrc, dest);
+        String hostSideCommand = String.format("cp -r %s/* %s", hostSrc, dest);
+        String cleanUpCommand = String.format("rm -rf %s", hostSrc);
+        try {
+            Process deviceProcess = Runtime.getRuntime().exec(new String[]{"/bin/bash", "-c",
+                    deviceSideCommand});
+            if (deviceProcess.waitFor() != 0) {
+                CLog.v("No device-side report logs pulled.");
+            }
+            Process hostProcess = Runtime.getRuntime().exec(new String[]{"/bin/bash", "-c",
+                    hostSideCommand});
+            if (hostProcess.waitFor() != 0) {
+                CLog.v("No host-side report logs pulled");
+            }
+            Process cleanUpProcess = Runtime.getRuntime().exec(new String[]{"/bin/bash", "-c",
+                    cleanUpCommand});
+            if (cleanUpProcess.waitFor() != 0) {
+                CLog.e("Failed to run %s", cleanUpCommand);
+            }
+        } catch (Exception e) {
+            CLog.e("Caught exception during pull.");
+            CLog.e(e);
+        }
+    }
+}
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/ResultFilePuller.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/ResultFilePuller.java
new file mode 100644
index 0000000..432f223
--- /dev/null
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/ResultFilePuller.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.tradefed.targetprep;
+
+import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.config.Option;
+import com.android.tradefed.config.OptionClass;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.log.LogUtil.CLog;
+import com.android.tradefed.targetprep.BuildError;
+import com.android.tradefed.targetprep.ITargetCleaner;
+import com.android.tradefed.targetprep.TargetSetupError;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Pulls files from the device after a test run and puts them into the result folder.
+ */
+@OptionClass(alias="result-file-puller")
+public class ResultFilePuller implements ITargetCleaner {
+
+    @Option(name="clear", description = "Whether to clear the src files and dirs before running the test")
+    private boolean mClearSrc = true;
+
+    @Option(name="src-file", description = "The file to copy to the results dir")
+    private List<String> mSrcFiles = new ArrayList<>();
+
+    @Option(name="src-dir", description = "The directory to copy to the results dir")
+    private List<String> mSrcDirs = new ArrayList<>();
+
+    @Option(name = "dest-dir", description = "The directory under the result to store the files")
+    private String mDestDir;
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setUp(ITestDevice device, IBuildInfo buildInfo) throws TargetSetupError, BuildError,
+            DeviceNotAvailableException {
+        if (mClearSrc) {
+            for (String file : mSrcFiles) {
+                delete(device, file);
+            }
+            for (String dir : mSrcDirs) {
+                delete(device, dir);
+            }
+        }
+    }
+
+    private void delete(ITestDevice device, String file) throws DeviceNotAvailableException {
+        device.executeShellCommand(String.format("rm -rf %s", file));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void tearDown(ITestDevice device, IBuildInfo buildInfo, Throwable e)
+            throws DeviceNotAvailableException {
+        CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(buildInfo);
+        try {
+            File resultDir = buildHelper.getResultDir();
+            if (mDestDir != null) {
+                resultDir = new File(resultDir, mDestDir);
+            }
+            resultDir.mkdirs();
+            if (!resultDir.isDirectory()) {
+                CLog.e("%s is not a directory", resultDir.getAbsolutePath());
+                return;
+            }
+            String resultPath = resultDir.getAbsolutePath();
+            for (String file : mSrcFiles) {
+                pull(device, file, resultPath);
+            }
+            for (String dir : mSrcDirs) {
+                pull(device, dir, resultPath);
+            }
+        } catch (FileNotFoundException fnfe) {
+            fnfe.printStackTrace();
+        }
+    }
+
+    private void pull(ITestDevice device, String src, String dest) {
+        String command = String.format("adb -s %s pull %s %s", device.getSerialNumber(), src, dest);
+        try {
+            Process p = Runtime.getRuntime().exec(new String[] {"/bin/bash", "-c", command});
+            if (p.waitFor() != 0) {
+                CLog.e("Failed to run %s", command);
+            }
+        } catch (Exception e) {
+            CLog.e("Caught exception during pull.");
+            CLog.e(e);
+        }
+    }
+}
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/SettingsPreparer.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/SettingsPreparer.java
new file mode 100644
index 0000000..d4c9d54
--- /dev/null
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/SettingsPreparer.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.tradefed.targetprep;
+
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.config.Option;
+import com.android.tradefed.config.OptionClass;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.targetprep.BuildError;
+import com.android.tradefed.targetprep.TargetSetupError;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Checks that a given setting on the device is one of the given values
+ */
+@OptionClass(alias="settings-preparer")
+public class SettingsPreparer extends PreconditionPreparer {
+
+    public enum SettingType {
+        SECURE,
+        GLOBAL,
+        SYSTEM;
+    }
+
+    /* This option must be defined, but is not explicitly marked mandatory, as subclasses of
+     * the SettingsPreparer class can define mSettingName at runtime */
+    @Option(name = "device-setting", description = "The setting on the device to be checked")
+    protected String mSettingName = null;
+
+    /* This option must be defined, but is not explicitly marked mandatory, as subclasses of
+     * the SettingsPreparer class can define mSettingType at runtime */
+    @Option(name = "setting-type",
+            description = "If the setting is 'secure', 'global', or 'system'")
+    protected SettingType mSettingType = null;
+
+    @Option(name = "set-value", description = "The value to be set for the setting")
+    protected String mSetValue = null;
+
+    @Option(name = "expected-values", description = "The set of expected values of the setting")
+    protected List<String> mExpectedSettingValues = new ArrayList<String>();
+
+    @Option(name = "failure-message", description = "The text printed for an unexpected value")
+    protected String mFailureMessage = null;
+
+    @Override
+    public void run(ITestDevice device, IBuildInfo buildInfo) throws TargetSetupError,
+            BuildError, DeviceNotAvailableException {
+
+        if (mSettingName == null) {
+            throw new TargetSetupError("The \"device-setting\" option must be defined for the " +
+                    "SettingsPreparer class");
+        }
+
+        if (mSettingType == null) {
+            throw new TargetSetupError("The \"setting-type\" option must be defined for the " +
+                    "SettingsPreparer class");
+        }
+
+        /* At least one of the options "set-value" and "expected-values" must be set */
+        if (mSetValue == null && mExpectedSettingValues.isEmpty()) {
+            throw new TargetSetupError("At least one of the options \"set-value\" and " +
+                    "\"expected-values\" must be set");
+        }
+
+        String shellCmdGet = (!mExpectedSettingValues.isEmpty()) ?
+                String.format("settings get %s %s", mSettingType, mSettingName) : "";
+        String shellCmdPut = (mSetValue != null) ?
+                String.format("settings put %s %s %s", mSettingType, mSettingName, mSetValue) : "";
+
+
+        /* Case 1: Both expected-values and set-value are given */
+        if (mSetValue != null && !mExpectedSettingValues.isEmpty()) {
+            // first ensure that the set-value given can be found in expected-values
+            if (!mExpectedSettingValues.contains(mSetValue)) {
+                throw new TargetSetupError(String.format(
+                        "set-value for %s is %s, but value not found in expected-values: %s",
+                        mSettingName, mSetValue, mExpectedSettingValues.toString()));
+            }
+            String currentSettingValue = device.executeShellCommand(shellCmdGet).trim();
+            // only change unexpected setting value
+            if (!mExpectedSettingValues.contains(currentSettingValue)) {
+                logInfo("Changing value for %s from %s to %s",
+                        mSettingName, currentSettingValue, mSetValue);
+                device.executeShellCommand(shellCmdPut);
+            }
+            return;
+        }
+
+        /* Case 2: Only set-value given */
+        if (mSetValue != null) {
+            logInfo("Setting %s to value %s", mSettingName, mSetValue);
+            device.executeShellCommand(shellCmdPut);
+            return;
+        }
+
+        /* Case 3: Only expected-values given */
+        String currentSettingValue = device.executeShellCommand(shellCmdGet).trim();
+        if (!mExpectedSettingValues.contains(currentSettingValue)) {
+            if (mFailureMessage == null) {
+                mFailureMessage = String.format(
+                        "Device setting \"%s\" returned \"%s\", not found in %s",
+                        mSettingName, currentSettingValue, mExpectedSettingValues.toString());
+            }
+            throw new TargetSetupError(mFailureMessage);
+        }
+    }
+
+}
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/StayAwakePreparer.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/StayAwakePreparer.java
new file mode 100644
index 0000000..d804146
--- /dev/null
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/StayAwakePreparer.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.tradefed.targetprep;
+
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.config.OptionClass;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.targetprep.BuildError;
+import com.android.tradefed.targetprep.TargetSetupError;
+
+import java.util.Arrays;
+
+/**
+ * Modifies the 'Stay Awake' setting of the device, so that the device's screen stays on
+ * whenever charging via USB
+ */
+@OptionClass(alias="stay-awake-preparer")
+public class StayAwakePreparer extends SettingsPreparer {
+
+    private static final String STAY_AWAKE_SETTING = "stay_on_while_plugged_in";
+
+    /*
+     * Values that are appropriate for the "Stay Awake" setting while running compatibility tests:
+     * (the second bit must be 'on' to allow screen to stay awake while charging via USB)
+     * 2 - Stay awake while charging via USB
+     * 3 - Stay awake while changing via USB or AC
+     * 6 - Stay awake while charging via USB or Wireless
+     * 7 - Stay awake while charging via USB or AC or Wireless
+     */
+    private static final String[] STAY_AWAKE_VALUES = new String[] {"2", "3", "6", "7"};
+    private static final String DEFAULT_VALUE = "7";
+
+    @Override
+    public void run(ITestDevice device, IBuildInfo buildInfo) throws TargetSetupError,
+            BuildError, DeviceNotAvailableException {
+
+        mSettingName = STAY_AWAKE_SETTING;
+        mSettingType = SettingsPreparer.SettingType.GLOBAL;
+        mSetValue = DEFAULT_VALUE;
+        for (String value : STAY_AWAKE_VALUES) {
+            mExpectedSettingValues.add(value);
+        }
+        super.run(device, buildInfo);
+    }
+
+}
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/TokenRequirement.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/TokenRequirement.java
new file mode 100644
index 0000000..54b6bc0
--- /dev/null
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/TokenRequirement.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.compatibility.common.tradefed.targetprep;
+
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.config.Option;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.targetprep.BuildError;
+import com.android.tradefed.targetprep.ITargetPreparer;
+import com.android.tradefed.targetprep.TargetSetupError;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * An {@link ITargetPreparer} that allows a test module to specify tokens that a device must have
+ * to run the tests contained.
+ *
+ * A token is string that is required by a test module and given to a device by the user, they are
+ * used by the scheduler to ensure tests are scheduled on the correct devices. Eg if the user is
+ * sharding the innvocation across 10 devices, they will not want to put a SIM card in every device,
+ * instead they can use a single SIM card and use tokens to tell the scheduler which device should
+ * be used to run the SIM card tests.
+ */
+public class TokenRequirement implements ITargetPreparer {
+
+    @Option(name = "token", description = "The token a device must have to run this module")
+    private Set<String> mTokens = new HashSet<>();
+
+    @Override
+    public void setUp(ITestDevice device, IBuildInfo buildInfo) throws TargetSetupError,
+            BuildError, DeviceNotAvailableException {
+        throw new TargetSetupError("TokenRequirement is not expected to run");
+    }
+
+    /**
+     * @return the {@link Set} of tokens required by this module.
+     */
+    public Set<String> getTokens() {
+        return mTokens;
+    }
+}
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/WifiCheck.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/WifiCheck.java
new file mode 100644
index 0000000..5863bd8
--- /dev/null
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/WifiCheck.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.tradefed.targetprep;
+
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.config.Option;
+import com.android.tradefed.config.OptionClass;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.targetprep.BuildError;
+import com.android.tradefed.targetprep.TargetSetupError;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This preparer ensures that the device is connected to a network.
+ * The options "wifi-ssid" and "wifi-psk" allow users of the preparer to attempt connection
+ * to a network. If the options are provided, the preparer disconnects any existing network
+ * connection, and attempts to connect with the options provided.
+ *
+ * @throws TargetSetupError if device is not connected to a network and no options are given, or
+ * if the device fails to connect to the network specified in the options
+ */
+@OptionClass(alias="wifi-check")
+public class WifiCheck extends PreconditionPreparer {
+
+    private static final String WIFI_FEATURE = "android.hardware.wifi";
+
+    @Option(name = "wifi-ssid", description = "Name of the WiFi network with which to connect")
+    protected String mWifiSsid = null;
+
+    @Option(name = "wifi-psk",
+            description = "The WPA-PSK associated with the wifi-ssid option")
+    protected String mWifiPsk = null;
+
+    private boolean hasWifiFeature(ITestDevice device) throws DeviceNotAvailableException {
+        String pmFeatures = device.executeShellCommand("pm list features");
+        return pmFeatures.contains(WIFI_FEATURE);
+    }
+
+    @Override
+    public void run(ITestDevice device, IBuildInfo buildInfo) throws TargetSetupError,
+            BuildError, DeviceNotAvailableException {
+
+        if(!hasWifiFeature(device)) {
+            return; // skip this precondition check if device doesn't support wifi
+        }
+
+        if (mWifiSsid == null) { // no connection to create, check for existing connectivity
+            if (!device.checkConnectivity()) {
+                throw new TargetSetupError("Device has no network connection, no ssid provided");
+            }
+        } else { // network provided in options, attempt to create new connection
+            logInfo("Attempting connection to \"%s\"", mWifiSsid);
+            if (!device.connectToWifiNetwork(mWifiSsid, mWifiPsk)) { // attempt connection
+                throw new TargetSetupError(String.format(
+                        "Unable to connect to network \"%s\", some modules of CTS" +
+                        "require an active network connection", mWifiSsid));
+            }
+        }
+        logInfo("Wifi is connected");
+    }
+}
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/Abi.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/Abi.java
new file mode 100644
index 0000000..fab990e
--- /dev/null
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/Abi.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.tradefed.testtype;
+
+import com.android.tradefed.testtype.IAbi;
+
+/**
+ * A class representing an ABI.
+ *
+ * TODO(stuartscott): should be in TradeFed.
+ */
+public class Abi implements IAbi {
+
+    private final String mName;
+    private final String mBitness;
+
+    public Abi(String name, String bitness) {
+        mName = name;
+        mBitness = bitness;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String getName() {
+        return mName;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String getBitness() {
+        return mBitness;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String toString() {
+        return mName;
+    }
+
+}
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/CompatibilityTest.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/CompatibilityTest.java
new file mode 100644
index 0000000..a41748e
--- /dev/null
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/CompatibilityTest.java
@@ -0,0 +1,431 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.compatibility.common.tradefed.testtype;
+
+import com.android.compatibility.SuiteInfo;
+import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
+import com.android.compatibility.common.tradefed.result.IInvocationResultRepo;
+import com.android.compatibility.common.tradefed.result.InvocationResultRepo;
+import com.android.compatibility.common.util.AbiUtils;
+import com.android.compatibility.common.util.ICaseResult;
+import com.android.compatibility.common.util.IInvocationResult;
+import com.android.compatibility.common.util.IModuleResult;
+import com.android.compatibility.common.util.ITestResult;
+import com.android.compatibility.common.util.MonitoringUtils;
+import com.android.compatibility.common.util.TestFilter;
+import com.android.compatibility.common.util.TestStatus;
+import com.android.ddmlib.Log.LogLevel;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.config.Option;
+import com.android.tradefed.config.Option.Importance;
+import com.android.tradefed.config.OptionClass;
+import com.android.tradefed.config.OptionCopier;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.log.LogUtil.CLog;
+import com.android.tradefed.result.ITestInvocationListener;
+import com.android.tradefed.testtype.IAbi;
+import com.android.tradefed.testtype.IBuildReceiver;
+import com.android.tradefed.testtype.IDeviceTest;
+import com.android.tradefed.testtype.IRemoteTest;
+import com.android.tradefed.testtype.IShardableTest;
+import com.android.tradefed.util.AbiFormatter;
+import com.android.tradefed.util.ArrayUtil;
+import com.android.tradefed.util.TimeUtil;
+
+import java.io.FileNotFoundException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * A Test for running Compatibility Suites
+ */
+@OptionClass(alias = "compatibility")
+public class CompatibilityTest implements IDeviceTest, IShardableTest, IBuildReceiver {
+
+    public static final String INCLUDE_FILTER_OPTION = "include-filter";
+    public static final String EXCLUDE_FILTER_OPTION = "exclude-filter";
+    private static final String PLAN_OPTION = "plan";
+    private static final String MODULE_OPTION = "module";
+    private static final String TEST_OPTION = "test";
+    private static final String MODULE_ARG_OPTION = "module-arg";
+    private static final String TEST_ARG_OPTION = "test-arg";
+    public static final String RETRY_OPTION = "retry";
+    private static final String ABI_OPTION = "abi";
+    private static final String SHARD_OPTION = "shards";
+    public static final String SKIP_DEVICE_INFO_OPTION = "skip-device-info";
+    public static final String SKIP_PRECONDITIONS_OPTION = "skip-preconditions";
+    public static final String DEVICE_TOKEN_OPTION = "device-token";
+    private static final String URL = "dynamic-config-url";
+
+    @Option(name = PLAN_OPTION,
+            description = "the test suite plan to run, such as \"everything\" or \"cts\"",
+            importance = Importance.ALWAYS)
+    private String mSuitePlan;
+
+    @Option(name = INCLUDE_FILTER_OPTION,
+            description = "the include module filters to apply.",
+            importance = Importance.ALWAYS)
+    private List<String> mIncludeFilters = new ArrayList<>();
+
+    @Option(name = EXCLUDE_FILTER_OPTION,
+            description = "the exclude module filters to apply.",
+            importance = Importance.ALWAYS)
+    private List<String> mExcludeFilters = new ArrayList<>();
+
+    @Option(name = MODULE_OPTION,
+            shortName = 'm',
+            description = "the test module to run.",
+            importance = Importance.IF_UNSET)
+    private String mModuleName = null;
+
+    @Option(name = TEST_OPTION,
+            shortName = 't',
+            description = "the test run.",
+            importance = Importance.IF_UNSET)
+    private String mTestName = null;
+
+    @Option(name = MODULE_ARG_OPTION,
+            description = "the arguments to pass to a module. The expected format is"
+                    + "\"<module-name>:<arg-name>:<arg-value>\"",
+            importance = Importance.ALWAYS)
+    private List<String> mModuleArgs = new ArrayList<>();
+
+    @Option(name = TEST_ARG_OPTION,
+            description = "the arguments to pass to a test. The expected format is"
+                    + "\"<test-class>:<arg-name>:<arg-value>\"",
+            importance = Importance.ALWAYS)
+    private List<String> mTestArgs = new ArrayList<>();
+
+    @Option(name = RETRY_OPTION,
+            shortName = 'r',
+            description = "retry a previous session.",
+            importance = Importance.IF_UNSET)
+    private Integer mRetrySessionId = null;
+
+    @Option(name = ABI_OPTION,
+            shortName = 'a',
+            description = "the abi to test.",
+            importance = Importance.IF_UNSET)
+    private String mAbiName = null;
+
+    @Option(name = SHARD_OPTION,
+            description = "split the modules up to run on multiple devices concurrently.")
+    private int mShards = 1;
+
+    @Option(name = URL,
+            description = "Specify the url for override config")
+    private String mURL;
+
+    @Option(name = SKIP_DEVICE_INFO_OPTION,
+            shortName = 'd',
+            description = "Whether device info collection should be skipped")
+    private boolean mSkipDeviceInfo = false;
+
+    @Option(name = SKIP_PRECONDITIONS_OPTION,
+            shortName = 'o',
+            description = "Whether preconditions should be skipped")
+    private boolean mSkipPreconditions = false;
+
+    @Option(name = DEVICE_TOKEN_OPTION,
+            description = "Holds the devices' tokens, used when scheduling tests that have"
+                    + "prerequisits such as requiring a SIM card. Format is <serial>:<token>",
+            importance = Importance.ALWAYS)
+    private List<String> mDeviceTokens = new ArrayList<>();
+
+    @Option(name = "bugreport-on-failure",
+            description = "Take a bugreport on every test failure. " +
+                    "Warning: can potentially use a lot of disk space.")
+    private boolean mBugReportOnFailure = false;
+
+    @Option(name = "logcat-on-failure",
+            description = "Take a logcat snapshot on every test failure.")
+    private boolean mLogcatOnFailure = false;
+
+    @Option(name = "screenshot-on-failure",
+            description = "Take a screenshot on every test failure.")
+    private boolean mScreenshotOnFailure = false;
+
+    @Option(name = "reboot-on-failure",
+            description = "Reboot the device after every test failure.")
+    private boolean mRebootOnFailure = false;
+
+    @Option(name = "skip-connectivity-check",
+            description = "Don't verify device connectivity between module execution.")
+    private boolean mSkipConnectivityCheck = false;
+
+    @Option(name = "preparer-whitelist",
+            description = "Only run specific preparers."
+            + "Specify zero or more ITargetPreparers as canonical class names. "
+            + "e.g. \"com.android.compatibility.common.tradefed.targetprep.ApkInstaller\" "
+            + "If not specified, all configured preparers are run.")
+    private Set<String> mPreparerWhitelist = new HashSet<>();
+
+    private int mTotalShards;
+    private IModuleRepo mModuleRepo;
+    private ITestDevice mDevice;
+    private IBuildInfo mBuild;
+    private CompatibilityBuildHelper mBuildHelper;
+
+    /**
+     * Create a new {@link CompatibilityTest} that will run the default list of
+     * modules.
+     */
+    public CompatibilityTest() {
+        this(1 /* totalShards */, new ModuleRepo());
+    }
+
+    /**
+     * Create a new {@link CompatibilityTest} that will run a sublist of
+     * modules.
+     */
+    public CompatibilityTest(int totalShards, IModuleRepo moduleRepo) {
+        if (totalShards < 1) {
+            throw new IllegalArgumentException(
+                    "Must be at least 1 shard. Given:" + totalShards);
+        }
+        mTotalShards = totalShards;
+        mModuleRepo = moduleRepo;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public ITestDevice getDevice() {
+        return mDevice;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setDevice(ITestDevice device) {
+        mDevice = device;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setBuild(IBuildInfo buildInfo) {
+        mBuild = buildInfo;
+        mBuildHelper = new CompatibilityBuildHelper(mBuild);
+        mBuildHelper.init(mSuitePlan, mURL);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
+        try {
+            // Synchronized so only one shard enters and sets up the moduleRepo. When the other
+            // shards enter after this, moduleRepo is already initialized so they dont do anything
+            synchronized (mModuleRepo) {
+                if (!mModuleRepo.isInitialized()) {
+                    setupFilters();
+                    // Initialize the repository, {@link CompatibilityBuildHelper#getTestsDir} can
+                    // throw a {@link FileNotFoundException}
+                    mModuleRepo.initialize(mTotalShards, mBuildHelper.getTestsDir(), getAbis(),
+                            mDeviceTokens, mTestArgs, mModuleArgs, mIncludeFilters,
+                            mExcludeFilters, mBuild);
+                }
+            }
+            // Get the tests to run in this shard
+            List<IModuleDef> modules = mModuleRepo.getModules(getDevice().getSerialNumber());
+
+            listener = new FailureListener(listener, getDevice(), mBugReportOnFailure,
+                    mLogcatOnFailure, mScreenshotOnFailure, mRebootOnFailure);
+            int moduleCount = modules.size();
+            CLog.logAndDisplay(LogLevel.INFO, "Starting %d module%s on %s", moduleCount,
+                    (moduleCount > 1) ? "s" : "", mDevice.getSerialNumber());
+            if (!mSkipConnectivityCheck) {
+                MonitoringUtils.checkDeviceConnectivity(getDevice(), listener, "start");
+            }
+
+            // Set values and run preconditions
+            for (int i = 0; i < moduleCount; i++) {
+                IModuleDef module = modules.get(i);
+                module.setBuild(mBuild);
+                module.setDevice(mDevice);
+                module.setPreparerWhitelist(mPreparerWhitelist);
+                module.prepare(mSkipPreconditions);
+            }
+            // Run the tests
+            for (int i = 0; i < moduleCount; i++) {
+                IModuleDef module = modules.get(i);
+                long start = System.currentTimeMillis();
+                module.run(listener);
+                long duration = System.currentTimeMillis() - start;
+                long expected = module.getRuntimeHint();
+                long delta = Math.abs(duration - expected);
+                // Show warning if delta is more than 10% of expected
+                if (expected > 0 && ((float)delta / (float)expected) > 0.1f) {
+                    CLog.logAndDisplay(LogLevel.WARN,
+                            "Inaccurate runtime hint for %s, expected %s was %s",
+                            module.getId(),
+                            TimeUtil.formatElapsedTime(expected),
+                            TimeUtil.formatElapsedTime(duration));
+                }
+                if (!mSkipConnectivityCheck) {
+                    MonitoringUtils.checkDeviceConnectivity(getDevice(), listener,
+                            String.format("%s-%s", module.getName(), module.getAbi().getName()));
+                }
+            }
+        } catch (FileNotFoundException fnfe) {
+            throw new RuntimeException("Failed to initialize modules", fnfe);
+        }
+    }
+
+    /**
+     * Gets the set of ABIs supported by both Compatibility and the device under test
+     *
+     * @return The set of ABIs to run the tests on
+     * @throws DeviceNotAvailableException
+     */
+    Set<IAbi> getAbis() throws DeviceNotAvailableException {
+        Set<IAbi> abis = new HashSet<>();
+        Set<String> archAbis = AbiUtils.getAbisForArch(SuiteInfo.TARGET_ARCH);
+        for (String abi : AbiFormatter.getSupportedAbis(mDevice, "")) {
+            // Only test against ABIs supported by Compatibility, and if the
+            // --abi option was given, it must match.
+            if (AbiUtils.isAbiSupportedByCompatibility(abi) && archAbis.contains(abi)
+                    && (mAbiName == null || mAbiName.equals(abi))) {
+                abis.add(new Abi(abi, AbiUtils.getBitness(abi)));
+            }
+        }
+        if (abis == null || abis.isEmpty()) {
+            if (mAbiName == null) {
+                throw new IllegalArgumentException("Could not get device's ABIs");
+            } else {
+                throw new IllegalArgumentException(String.format(
+                        "Device %s doesn't support %s", mDevice.getSerialNumber(), mAbiName));
+            }
+        }
+        return abis;
+    }
+
+    /**
+     * Sets the include/exclude filters up based on if a module name was given or whether this is a
+     * retry run.
+     */
+    void setupFilters() {
+        if (mRetrySessionId != null) {
+            // We're retrying so clear the filters
+            mIncludeFilters.clear();
+            mExcludeFilters.clear();
+            mModuleName = null;
+            mTestName = null;
+            // Load the invocation result
+            IInvocationResultRepo repo;
+            IInvocationResult result = null;
+            try {
+                repo = new InvocationResultRepo(mBuildHelper.getResultsDir());
+                result = repo.getResult(mRetrySessionId);
+            } catch (FileNotFoundException e) {
+                e.printStackTrace();
+            }
+            if (result == null) {
+                throw new IllegalArgumentException(String.format(
+                        "Could not find session with id %d", mRetrySessionId));
+            }
+            // Append each test that failed or was not executed to the filters
+            for (IModuleResult module : result.getModules()) {
+                for (ICaseResult testResultList : module.getResults()) {
+                    for (ITestResult testResult : testResultList.getResults(TestStatus.PASS)) {
+                        // Create the filter for the test to be run.
+                        TestFilter filter = new TestFilter(
+                                module.getAbi(), module.getName(), testResult.getFullName());
+                        mExcludeFilters.add(filter.toString());
+                    }
+                }
+            }
+        } else if (mModuleName != null) {
+            mIncludeFilters.clear();
+            try {
+                List<String> modules = ModuleRepo.getModuleNamesMatching(
+                        mBuildHelper.getTestsDir(), mModuleName);
+                if (modules.size() == 0) {
+                    throw new IllegalArgumentException(
+                            String.format("No modules found matching %s", mModuleName));
+                } else if (modules.size() > 1) {
+                    throw new IllegalArgumentException(String.format(
+                            "Multiple modules found matching %s:\n%s\nWhich one did you mean?\n",
+                            mModuleName, ArrayUtil.join("\n", modules)));
+                } else {
+                    String module = modules.get(0);
+                    mIncludeFilters.add(new TestFilter(mAbiName, module, mTestName).toString());
+                    if (mTestName != null) {
+                        // We're filtering it down to the lowest level, no need to give excludes
+                        mExcludeFilters.clear();
+                    } else {
+                        // If we dont specify a test name, we only want to run this module with any
+                        // previous exclusions as long as they dont exclude the whole module.
+                        List<String> excludeFilters = new ArrayList<>();
+                        for (String excludeFilter : mExcludeFilters) {
+                            TestFilter filter = TestFilter.createFrom(excludeFilter);
+                            String name = filter.getName();
+                            // Add the filter if it applies to this module, and it has a test name
+                            if (module.equals(name) && filter.getTest() != null) {
+                                excludeFilters.add(excludeFilter);
+                            }
+                        }
+                        mExcludeFilters = excludeFilters;
+                    }
+                }
+            } catch (FileNotFoundException e) {
+                e.printStackTrace();
+            }
+        } else if (mTestName != null) {
+            throw new IllegalArgumentException(
+                    "Test name given without module name. Add --module <module-name>");
+        } else {
+            // If a module has an arg, assume it's included
+            for (String arg : mModuleArgs) {
+                mIncludeFilters.add(arg.split(":")[0]);
+            }
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Collection<IRemoteTest> split() {
+        if (mShards <= 1) {
+            return null;
+        }
+
+        List<IRemoteTest> shardQueue = new LinkedList<>();
+        for (int i = 0; i < mShards; i++) {
+            CompatibilityTest test = new CompatibilityTest(mShards, mModuleRepo);
+            OptionCopier.copyOptionsNoThrow(this, test);
+            // Set the shard count because the copy option on the previous line
+            // copies over the mShard value
+            test.mShards = 0;
+            shardQueue.add(test);
+        }
+
+        return shardQueue;
+    }
+
+}
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/FailureListener.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/FailureListener.java
new file mode 100644
index 0000000..5d2cd38
--- /dev/null
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/FailureListener.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.tradefed.testtype;
+
+import com.android.ddmlib.testrunner.TestIdentifier;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.log.LogUtil.CLog;
+import com.android.tradefed.result.ITestInvocationListener;
+import com.android.tradefed.result.InputStreamSource;
+import com.android.tradefed.result.LogDataType;
+import com.android.tradefed.result.ResultForwarder;
+import com.android.tradefed.util.RunUtil;
+
+public class FailureListener extends ResultForwarder {
+
+    private static final int MAX_LOGCAT_BYTES = 500 * 1024; // 500K
+
+    private ITestDevice mDevice;
+    private boolean mBugReportOnFailure;
+    private boolean mLogcatOnFailure;
+    private boolean mScreenshotOnFailure;
+    private boolean mRebootOnFailure;
+
+    public FailureListener(ITestInvocationListener listener, ITestDevice device,
+            boolean bugReportOnFailure, boolean logcatOnFailure, boolean screenshotOnFailure,
+            boolean rebootOnFailure) {
+        super(listener);
+        mDevice = device;
+        mBugReportOnFailure = bugReportOnFailure;
+        mLogcatOnFailure = logcatOnFailure;
+        mScreenshotOnFailure = screenshotOnFailure;
+        mRebootOnFailure = rebootOnFailure;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void testFailed(TestIdentifier test, String trace) {
+        super.testFailed(test, trace);
+        CLog.i("FailureListener.testFailed %s %b %b %b", test.toString(), mBugReportOnFailure, mLogcatOnFailure, mScreenshotOnFailure);
+        if (mBugReportOnFailure) {
+           InputStreamSource bugSource = mDevice.getBugreport();
+           super.testLog(String.format("%s-bugreport", test.toString()), LogDataType.BUGREPORT,
+                   bugSource);
+           bugSource.cancel();
+        }
+        if (mLogcatOnFailure) {
+            // sleep 2s to ensure test failure stack trace makes it into logcat capture
+            RunUtil.getDefault().sleep(2 * 1000);
+            InputStreamSource logSource = mDevice.getLogcat(MAX_LOGCAT_BYTES);
+            super.testLog(String.format("%s-logcat", test.toString()), LogDataType.LOGCAT,
+                    logSource);
+            logSource.cancel();
+        }
+        if (mScreenshotOnFailure) {
+            try {
+                InputStreamSource screenSource = mDevice.getScreenshot();
+                super.testLog(String.format("%s-screenshot", test.toString()), LogDataType.PNG,
+                        screenSource);
+                screenSource.cancel();
+            } catch (DeviceNotAvailableException e) {
+                CLog.e(e);
+                CLog.e("Device %s became unavailable while capturing screenshot",
+                        mDevice.getSerialNumber());
+            }
+        }
+        if (mRebootOnFailure) {
+            try {
+                // Rebooting on all failures can hide legitimate issues and platform instabilities,
+                // therefore only allowed on "user-debug" and "eng" builds.
+                if ("user".equals(mDevice.getProperty("ro.build.type"))) {
+                    CLog.e("Reboot-on-failure should only be used during development," +
+                            " this is a\" user\" build device");
+                } else {
+                    mDevice.reboot();
+                }
+            } catch (DeviceNotAvailableException e) {
+                CLog.e(e);
+                CLog.e("Device %s became unavailable while rebooting",
+                        mDevice.getSerialNumber());
+            }
+        }
+    }
+
+}
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/IModuleDef.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/IModuleDef.java
new file mode 100644
index 0000000..f18bfc8
--- /dev/null
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/IModuleDef.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.tradefed.testtype;
+
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.testtype.IAbi;
+import com.android.tradefed.testtype.IBuildReceiver;
+import com.android.tradefed.testtype.IDeviceTest;
+import com.android.tradefed.testtype.IRemoteTest;
+import com.android.tradefed.testtype.IRuntimeHintProvider;
+
+import java.util.Set;
+
+/**
+ * Container for Compatibility test info.
+ */
+public interface IModuleDef extends Comparable<IModuleDef>, IBuildReceiver, IDeviceTest,
+        IRemoteTest, IRuntimeHintProvider {
+
+    /**
+     * @return The name of this module.
+     */
+    String getName();
+
+    /**
+     * @return a {@link String} to uniquely identify this module.
+     */
+    String getId();
+
+    /**
+     * @return the abi of this test module.
+     */
+    IAbi getAbi();
+
+    /**
+     * @return the {@link Set} of tokens a device must have in order to run this module.
+     */
+    Set<String> getTokens();
+
+    /**
+     * @return the {@link IRemoteTest} that runs the tests.
+     */
+    IRemoteTest getTest();
+
+    /**
+     * Adds a filter to include a specific test
+     *
+     * @param name the name of the test. Can be <package>, <package>.<class>,
+     * <package>.<class>#<method> or <native_name>
+     */
+    void addIncludeFilter(String name);
+
+    /**
+     * Adds a filter to exclude a specific test
+     *
+     * @param name the name of the test. Can be <package>, <package>.<class>,
+     * <package>.<class>#<method> or <native_name>
+     */
+    void addExcludeFilter(String name);
+
+    /**
+     * Set a list of preparers to allow to run before or after a test.
+     * If this list is empty, then all configured preparers will run.
+     *
+     * @param a list containing the simple name of the preparer to run.
+     */
+    void setPreparerWhitelist(Set<String> preparerWhitelist);
+
+    /**
+     * Runs the module's precondition checks and setup tasks.
+     */
+    void prepare(boolean skipPrep) throws DeviceNotAvailableException;
+
+}
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/IModuleRepo.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/IModuleRepo.java
new file mode 100644
index 0000000..24e1dec
--- /dev/null
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/IModuleRepo.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.tradefed.testtype;
+
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.testtype.IAbi;
+
+import java.io.File;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Interface for accessing tests from the Compatibility repository.
+ */
+public interface IModuleRepo {
+
+    /**
+     * @return true if this repository has been initialized.
+     */
+    boolean isInitialized();
+
+    /**
+     * Initializes the repository.
+     */
+    void initialize(int shards, File testsDir, Set<IAbi> abis, List<String> deviceTokens,
+            List<String> testArgs, List<String> moduleArgs, List<String> mIncludeFilters,
+            List<String> mExcludeFilters, IBuildInfo buildInfo);
+
+    /**
+     * @return a {@link Map} of all modules to run on the device referenced by the given serial.
+     */
+    List<IModuleDef> getModules(String serial);
+
+    /**
+     * @return the number of shards this repo is initialized for.
+     */
+    int getNumberOfShards();
+
+    /**
+     * @return the maximum number of modules a shard will run.
+     */
+    int getModulesPerShard();
+
+    /**
+     * @return the {@link Map} of device serials to tokens.
+     */
+    Map<String, Set<String>> getDeviceTokens();
+
+    /**
+     * @return the {@link Set} of device serials that have taken their workload.
+     */
+    Set<String> getSerials();
+
+    /**
+     * @return the small modules that don't have tokens but have not been assigned to a device.
+     */
+    List<IModuleDef> getSmallModules();
+
+    /**
+     * @return the medium modules that don't have tokens but have not been assigned to a device.
+     */
+    List<IModuleDef> getMediumModules();
+
+    /**
+     * @return the large modules that don't have tokens but have not been assigned to a device.
+     */
+    List<IModuleDef> getLargeModules();
+
+    /**
+     * @return the modules which have token and have not been assigned to a device.
+     */
+    List<IModuleDef> getTokenModules();
+}
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/JarHostTest.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/JarHostTest.java
new file mode 100644
index 0000000..ba4c6c3
--- /dev/null
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/JarHostTest.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.tradefed.testtype;
+
+import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.config.Option;
+import com.android.tradefed.config.Option.Importance;
+import com.android.tradefed.testtype.HostTest;
+import com.android.tradefed.testtype.IAbi;
+import com.android.tradefed.testtype.IAbiReceiver;
+import com.android.tradefed.testtype.IBuildReceiver;
+import com.android.tradefed.testtype.IRemoteTest;
+import com.android.tradefed.testtype.IRuntimeHintProvider;
+import com.android.tradefed.util.TimeVal;
+
+import junit.framework.Test;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Modifier;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
+/**
+ * Test runner for host-side JUnit tests.
+ */
+public class JarHostTest extends HostTest implements IAbiReceiver, IBuildReceiver,
+        IRuntimeHintProvider {
+
+    @Option(name="jar", description="The jars containing the JUnit test class to run.",
+            importance = Importance.IF_UNSET)
+    private Set<String> mJars = new HashSet<>();
+
+    @Option(name = "runtime-hint",
+            isTimeVal = true,
+            description="The hint about the test's runtime.")
+    private long mRuntimeHint = 60000;// 1 minute
+
+    private IAbi mAbi;
+    private IBuildInfo mBuild;
+    private CompatibilityBuildHelper mHelper;
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setAbi(IAbi abi) {
+        mAbi = abi;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setBuild(IBuildInfo build) {
+        mBuild = build;
+        mHelper = new CompatibilityBuildHelper(build);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public long getRuntimeHint() {
+        return mRuntimeHint;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected List<Class<?>> getClasses() throws IllegalArgumentException  {
+        List<Class<?>> classes = super.getClasses();
+        for (String jarName : mJars) {
+            JarFile jarFile = null;
+            try {
+                File file = new File(mHelper.getTestsDir(), jarName);
+                jarFile = new JarFile(file);
+                Enumeration<JarEntry> e = jarFile.entries();
+                URL[] urls = {
+                        new URL(String.format("jar:file:%s!/", file.getAbsolutePath()))
+                };
+                URLClassLoader cl = URLClassLoader.newInstance(urls);
+
+                while (e.hasMoreElements()) {
+                    JarEntry je = e.nextElement();
+                    if (je.isDirectory() || !je.getName().endsWith(".class")
+                            || je.getName().contains("$")) {
+                        continue;
+                    }
+                    String className = getClassName(je.getName());
+                    try {
+                        Class<?> cls = cl.loadClass(className);
+                        int modifiers = cls.getModifiers();
+                        if ((IRemoteTest.class.isAssignableFrom(cls)
+                                || Test.class.isAssignableFrom(cls))
+                                && !Modifier.isStatic(modifiers)
+                                && !Modifier.isPrivate(modifiers)
+                                && !Modifier.isProtected(modifiers)
+                                && !Modifier.isInterface(modifiers)
+                                && !Modifier.isAbstract(modifiers)) {
+                            classes.add(cls);
+                        }
+                    } catch (ClassNotFoundException cnfe) {
+                        throw new IllegalArgumentException(
+                                String.format("Cannot find test class %s", className));
+                    }
+                }
+            } catch (IOException e) {
+                e.printStackTrace();
+            } finally {
+                if (jarFile != null) {
+                    try {
+                        jarFile.close();
+                    } catch (IOException e) {
+                        // Ignored
+                    }
+                }
+            }
+        }
+        return classes;
+    }
+
+    private static String getClassName(String name) {
+        // -6 because of .class
+        return name.substring(0, name.length() - 6).replace('/', '.');
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected Object loadObject(Class<?> classObj) throws IllegalArgumentException {
+        Object object = super.loadObject(classObj);
+        if (object instanceof IAbiReceiver) {
+            ((IAbiReceiver) object).setAbi(mAbi);
+        }
+        if (object instanceof IBuildReceiver) {
+            ((IBuildReceiver) object).setBuild(mBuild);
+        }
+        return object;
+    }
+}
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/ModuleDef.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/ModuleDef.java
new file mode 100644
index 0000000..8d0490b
--- /dev/null
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/ModuleDef.java
@@ -0,0 +1,322 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.tradefed.testtype;
+
+import com.android.compatibility.common.tradefed.result.IModuleListener;
+import com.android.compatibility.common.tradefed.result.ModuleListener;
+import com.android.compatibility.common.tradefed.targetprep.PreconditionPreparer;
+import com.android.compatibility.common.tradefed.targetprep.TokenRequirement;
+import com.android.compatibility.common.util.AbiUtils;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.config.ConfigurationException;
+import com.android.tradefed.config.OptionSetter;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.log.LogUtil.CLog;
+import com.android.tradefed.result.ITestInvocationListener;
+import com.android.tradefed.targetprep.BuildError;
+import com.android.tradefed.targetprep.ITargetCleaner;
+import com.android.tradefed.targetprep.ITargetPreparer;
+import com.android.tradefed.targetprep.TargetSetupError;
+import com.android.tradefed.testtype.IAbi;
+import com.android.tradefed.testtype.IAbiReceiver;
+import com.android.tradefed.testtype.IBuildReceiver;
+import com.android.tradefed.testtype.IDeviceTest;
+import com.android.tradefed.testtype.IRemoteTest;
+import com.android.tradefed.testtype.IRuntimeHintProvider;
+import com.android.tradefed.testtype.ITestCollector;
+import com.android.tradefed.testtype.ITestFilterReceiver;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Container for Compatibility test module info.
+ */
+public class ModuleDef implements IModuleDef {
+
+    private final String mId;
+    private final String mName;
+    private final IAbi mAbi;
+    private final Set<String> mTokens = new HashSet<>();
+    private IRemoteTest mTest = null;
+    private List<ITargetPreparer> mPreconditions = new ArrayList<>();
+    private List<ITargetPreparer> mPreparers = new ArrayList<>();
+    private List<ITargetCleaner> mCleaners = new ArrayList<>();
+    private IBuildInfo mBuild;
+    private ITestDevice mDevice;
+    private List<String> mIncludeFilters = new ArrayList<>();
+    private List<String> mExcludeFilters = new ArrayList<>();
+    private Set<String> mPreparerWhitelist = new HashSet<>();
+
+    public ModuleDef(String name, IAbi abi, IRemoteTest test,
+            List<ITargetPreparer> preparers) {
+        mId = AbiUtils.createId(abi.getName(), name);
+        mName = name;
+        mAbi = abi;
+        mTest = test;
+        boolean hasAbiReceiver = false;
+        for (ITargetPreparer preparer : preparers) {
+            if (preparer instanceof IAbiReceiver) {
+                hasAbiReceiver = true;
+            }
+            // Separate preconditions from target preparers.
+            if (preparer instanceof PreconditionPreparer) {
+                mPreconditions.add(preparer);
+            } else if (preparer instanceof TokenRequirement) {
+                mTokens.addAll(((TokenRequirement) preparer).getTokens());
+            } else {
+                mPreparers.add(preparer);
+            }
+            if (preparer instanceof ITargetCleaner) {
+                mCleaners.add((ITargetCleaner) preparer);
+            }
+        }
+        // Reverse cleaner order
+        Collections.reverse(mCleaners);
+
+        // Required interfaces:
+        if (!hasAbiReceiver && !(test instanceof IAbiReceiver)) {
+            throw new IllegalArgumentException(test
+                    + "does not implement IAbiReceiver"
+                    + " - for multi-abi testing (64bit)");
+        } else if (!(test instanceof IRuntimeHintProvider)) {
+            throw new IllegalArgumentException(test
+                    + " does not implement IRuntimeHintProvider"
+                    + " - to provide estimates of test invocation time");
+        } else if (!(test instanceof ITestCollector)) {
+            throw new IllegalArgumentException(test
+                    + " does not implement ITestCollector"
+                    + " - for test list collection");
+        } else if (!(test instanceof ITestFilterReceiver)) {
+            throw new IllegalArgumentException(test
+                    + " does not implement ITestFilterReceiver"
+                    + " - to allow tests to be filtered");
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String toString() {
+        return mId;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String getId() {
+        return mId;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String getName() {
+        return mName;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public IAbi getAbi() {
+        return mAbi;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Set<String> getTokens() {
+        return mTokens;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public long getRuntimeHint() {
+        if (mTest instanceof IRuntimeHintProvider) {
+            return ((IRuntimeHintProvider) mTest).getRuntimeHint();
+        }
+        return TimeUnit.MINUTES.toMillis(1); // Default 1 minute.
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public IRemoteTest getTest() {
+        return mTest;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void addIncludeFilter(String filter) {
+        mIncludeFilters.add(filter);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void addExcludeFilter(String filter) {
+        mExcludeFilters.add(filter);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setPreparerWhitelist(Set<String> preparerWhitelist) {
+        mPreparerWhitelist.addAll(preparerWhitelist);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int compareTo(IModuleDef moduleDef) {
+        return getName().compareTo(moduleDef.getName());
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setBuild(IBuildInfo build) {
+        mBuild = build;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public ITestDevice getDevice() {
+        return mDevice;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setDevice(ITestDevice device) {
+        mDevice = device;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
+        IModuleListener moduleListener = new ModuleListener(this, listener);
+
+        // Setup
+        for (ITargetPreparer preparer : mPreparers) {
+            String preparerName = preparer.getClass().getCanonicalName();
+            if (!mPreparerWhitelist.isEmpty() && !mPreparerWhitelist.contains(preparerName)) {
+                CLog.w("Skipping Preparer: %s since it is not in the whitelist %s",
+                        preparerName, mPreparerWhitelist);
+                continue;
+            }
+            CLog.d("Preparer: %s", preparer.getClass().getSimpleName());
+            if (preparer instanceof IAbiReceiver) {
+                ((IAbiReceiver) preparer).setAbi(mAbi);
+            }
+            try {
+                preparer.setUp(mDevice, mBuild);
+            } catch (BuildError e) {
+                // This should only happen for flashing new build
+                CLog.e("Unexpected BuildError from precondition: %s",
+                        preparer.getClass().getCanonicalName());
+            } catch (TargetSetupError e) {
+                // log precondition class then rethrow & let caller handle
+                CLog.e("TargetSetupError in precondition: %s",
+                        preparer.getClass().getCanonicalName());
+                throw new RuntimeException(e);
+            }
+        }
+
+
+        CLog.d("Test: %s", mTest.getClass().getSimpleName());
+        if (mTest instanceof IAbiReceiver) {
+            ((IAbiReceiver) mTest).setAbi(mAbi);
+        }
+        if (mTest instanceof IBuildReceiver) {
+            ((IBuildReceiver) mTest).setBuild(mBuild);
+        }
+        if (mTest instanceof IDeviceTest) {
+            ((IDeviceTest) mTest).setDevice(mDevice);
+        }
+        if (mTest instanceof ITestFilterReceiver) {
+            ((ITestFilterReceiver) mTest).addAllIncludeFilters(mIncludeFilters);
+            ((ITestFilterReceiver) mTest).addAllExcludeFilters(mExcludeFilters);
+        }
+        mTest.run(moduleListener);
+
+        // Tear down
+        for (ITargetCleaner cleaner : mCleaners) {
+            CLog.d("Cleaner: %s", cleaner.getClass().getSimpleName());
+            cleaner.tearDown(mDevice, mBuild, null);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void prepare(boolean skipPrep) throws DeviceNotAvailableException {
+        for (ITargetPreparer preparer : mPreconditions) {
+            CLog.d("Preparer: %s", preparer.getClass().getSimpleName());
+            if (preparer instanceof IAbiReceiver) {
+                ((IAbiReceiver) preparer).setAbi(mAbi);
+            }
+            setOption(preparer, CompatibilityTest.SKIP_PRECONDITIONS_OPTION,
+                    Boolean.toString(skipPrep));
+            try {
+                preparer.setUp(mDevice, mBuild);
+            } catch (BuildError e) {
+                // This should only happen for flashing new build
+                CLog.e("Unexpected BuildError from precondition: %s",
+                        preparer.getClass().getCanonicalName());
+            } catch (TargetSetupError e) {
+                // log precondition class then rethrow & let caller handle
+                CLog.e("TargetSetupError in precondition: %s",
+                        preparer.getClass().getCanonicalName());
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    private void setOption(Object target, String option, String value) {
+        try {
+            OptionSetter setter = new OptionSetter(target);
+            setter.setOptionValue(option, value);
+        } catch (ConfigurationException e) {
+            e.printStackTrace();
+        }
+    }
+}
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/ModuleRepo.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/ModuleRepo.java
new file mode 100644
index 0000000..8e984cb
--- /dev/null
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/ModuleRepo.java
@@ -0,0 +1,528 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.tradefed.testtype;
+
+import com.android.compatibility.common.util.AbiUtils;
+import com.android.compatibility.common.util.TestFilter;
+import com.android.ddmlib.Log.LogLevel;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.config.ConfigurationException;
+import com.android.tradefed.config.ConfigurationFactory;
+import com.android.tradefed.config.IConfiguration;
+import com.android.tradefed.config.IConfigurationFactory;
+import com.android.tradefed.log.LogUtil.CLog;
+import com.android.tradefed.testtype.IAbi;
+import com.android.tradefed.testtype.IBuildReceiver;
+import com.android.tradefed.testtype.IRemoteTest;
+import com.android.tradefed.testtype.IShardableTest;
+import com.android.tradefed.util.TimeUtil;
+
+import java.io.File;
+import java.io.FilenameFilter;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Retrieves Compatibility test module definitions from the repository.
+ */
+public class ModuleRepo implements IModuleRepo {
+
+    private static final String CONFIG_EXT = ".config";
+    private static final Map<String, Integer> ENDING_MODULES = new HashMap<>();
+    static {
+        ENDING_MODULES.put("CtsMonkeyTestCases", 1);
+    }
+    private static final long SMALL_TEST = TimeUnit.MINUTES.toMillis(2); // Small tests < 2mins
+    private static final long MEDIUM_TEST = TimeUnit.MINUTES.toMillis(10); // Medium tests < 10mins
+
+    private int mShards;
+    private int mModulesPerShard;
+    private int mSmallModulesPerShard;
+    private int mMediumModulesPerShard;
+    private int mLargeModulesPerShard;
+    private int mModuleCount = 0;
+    private Set<String> mSerials = new HashSet<>();
+    private Map<String, Set<String>> mDeviceTokens = new HashMap<>();
+    private Map<String, Map<String, String>> mTestArgs = new HashMap<>();
+    private Map<String, Map<String, String>> mModuleArgs = new HashMap<>();
+    private boolean mIncludeAll;
+    private Map<String, List<TestFilter>> mIncludeFilters = new HashMap<>();
+    private Map<String, List<TestFilter>> mExcludeFilters = new HashMap<>();
+    private IConfigurationFactory mConfigFactory = ConfigurationFactory.getInstance();
+
+    private volatile boolean mInitialized = false;
+
+    // Holds all the small tests waiting to be run.
+    private List<IModuleDef> mSmallModules = new ArrayList<>();
+    // Holds all the medium tests waiting to be run.
+    private List<IModuleDef> mMediumModules = new ArrayList<>();
+    // Holds all the large tests waiting to be run.
+    private List<IModuleDef> mLargeModules = new ArrayList<>();
+    // Holds all the tests with tokens waiting to be run. Meaning the DUT must have a specific token.
+    private List<IModuleDef> mTokenModules = new ArrayList<>();
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int getNumberOfShards() {
+        return mShards;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int getModulesPerShard() {
+        return mModulesPerShard;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Map<String, Set<String>> getDeviceTokens() {
+        return mDeviceTokens;
+    }
+
+    /**
+     * A {@link FilenameFilter} to find all modules in a directory who match the given pattern.
+     */
+    public static class NameFilter implements FilenameFilter {
+
+        private String mPattern;
+
+        public NameFilter(String pattern) {
+            mPattern = pattern;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public boolean accept(File dir, String name) {
+            return name.contains(mPattern) && name.endsWith(CONFIG_EXT);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Set<String> getSerials() {
+        return mSerials;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public List<IModuleDef> getSmallModules() {
+        return mSmallModules;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public List<IModuleDef> getMediumModules() {
+        return mMediumModules;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public List<IModuleDef> getLargeModules() {
+        return mLargeModules;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public List<IModuleDef> getTokenModules() {
+        return mTokenModules;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean isInitialized() {
+        return mInitialized;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void initialize(int shards, File testsDir, Set<IAbi> abis, List<String> deviceTokens,
+            List<String> testArgs, List<String> moduleArgs, List<String> includeFilters,
+            List<String> excludeFilters, IBuildInfo buildInfo) {
+        CLog.d("Initializing ModuleRepo\nShards:%d\nTests Dir:%s\nABIs:%s\nDevice Tokens:%s\n" +
+                "Test Args:%s\nModule Args:%s\nIncludes:%s\nExcludes:%s",
+                shards, testsDir.getAbsolutePath(), abis, deviceTokens, testArgs, moduleArgs,
+                includeFilters, excludeFilters);
+        mInitialized = true;
+        mShards = shards;
+        for (String line : deviceTokens) {
+            String[] parts = line.split(":");
+            if (parts.length == 2) {
+                String key = parts[0];
+                String value = parts[1];
+                Set<String> list = mDeviceTokens.get(key);
+                if (list == null) {
+                    list = new HashSet<>();
+                    mDeviceTokens.put(key, list);
+                }
+                list.add(value);
+            } else {
+                throw new IllegalArgumentException(
+                        String.format("Could not parse device token: %s", line));
+            }
+        }
+        putArgs(testArgs, mTestArgs);
+        putArgs(moduleArgs, mModuleArgs);
+        mIncludeAll = includeFilters.isEmpty();
+        // Include all the inclusions
+        addFilters(includeFilters, mIncludeFilters, abis);
+        // Exclude all the exclusions
+        addFilters(excludeFilters, mExcludeFilters, abis);
+
+        File[] configFiles = testsDir.listFiles(new ConfigFilter());
+        if (configFiles.length == 0) {
+            throw new IllegalArgumentException(
+                    String.format("No config files found in %s", testsDir.getAbsolutePath()));
+        }
+        for (File configFile : configFiles) {
+            final String name = configFile.getName().replace(CONFIG_EXT, "");
+            final String[] pathArg = new String[] { configFile.getAbsolutePath() };
+            try {
+                // Invokes parser to process the test module config file
+                // Need to generate a different config for each ABI as we cannot guarantee the
+                // configs are idempotent. This however means we parse the same file multiple times
+                for (IAbi abi : abis) {
+                    IConfiguration config = mConfigFactory.createConfigurationFromArgs(pathArg);
+                    String id = AbiUtils.createId(abi.getName(), name);
+                    {
+                        Map<String, String> args = new HashMap<>();
+                        if (mModuleArgs.containsKey(name)) {
+                            args.putAll(mModuleArgs.get(name));
+                        }
+                        if (mModuleArgs.containsKey(id)) {
+                            args.putAll(mModuleArgs.get(id));
+                        }
+                        if (args != null && args.size() > 0) {
+                            for (Entry<String, String> entry : args.entrySet()) {
+                                config.injectOptionValue(entry.getKey(), entry.getValue());
+                            }
+                        }
+                    }
+                    List<IRemoteTest> tests = config.getTests();
+                    for (IRemoteTest test : tests) {
+                        String className = test.getClass().getName();
+                        Map<String, String> args = new HashMap<>();
+                        if (mTestArgs.containsKey(className)) {
+                            args.putAll(mTestArgs.get(className));
+                        }
+                        if (args != null && args.size() > 0) {
+                            for (Entry<String, String> entry : args.entrySet()) {
+                                config.injectOptionValue(entry.getKey(), entry.getValue());
+                            }
+                        }
+                    }
+                    List<IRemoteTest> shardedTests = tests;
+                    if (mShards > 1) {
+                         shardedTests = splitShardableTests(tests, buildInfo);
+                    }
+                    for (IRemoteTest test : shardedTests) {
+                        if (test instanceof IBuildReceiver) {
+                            ((IBuildReceiver)test).setBuild(buildInfo);
+                        }
+                        addModuleDef(name, abi, test, pathArg);
+                    }
+                }
+            } catch (ConfigurationException e) {
+                throw new RuntimeException(String.format("error parsing config file: %s",
+                        configFile.getName()), e);
+            }
+        }
+        mModulesPerShard = mModuleCount / shards;
+        if (mModuleCount % shards != 0) {
+            mModulesPerShard++; // Round up
+        }
+        mSmallModulesPerShard = mSmallModules.size() / shards;
+        mMediumModulesPerShard = mMediumModules.size() / shards;
+        mLargeModulesPerShard = mLargeModules.size() / shards;
+    }
+
+    private static List<IRemoteTest> splitShardableTests(List<IRemoteTest> tests,
+            IBuildInfo buildInfo) {
+        ArrayList<IRemoteTest> shardedList = new ArrayList<>(tests.size());
+        for (IRemoteTest test : tests) {
+            if (test instanceof IShardableTest) {
+                if (test instanceof IBuildReceiver) {
+                    ((IBuildReceiver)test).setBuild(buildInfo);
+                }
+                shardedList.addAll(((IShardableTest)test).split());
+            } else {
+                shardedList.add(test);
+            }
+        }
+        return shardedList;
+    }
+
+    private static void addFilters(List<String> stringFilters,
+            Map<String, List<TestFilter>> filters, Set<IAbi> abis) {
+        for (String filterString : stringFilters) {
+            TestFilter filter = TestFilter.createFrom(filterString);
+            String abi = filter.getAbi();
+            if (abi == null) {
+                for (IAbi a : abis) {
+                    addFilter(a.getName(), filter, filters);
+                }
+            } else {
+                addFilter(abi, filter, filters);
+            }
+        }
+    }
+
+    private static void addFilter(String abi, TestFilter filter,
+            Map<String, List<TestFilter>> filters) {
+        getFilter(filters, AbiUtils.createId(abi, filter.getName())).add(filter);
+    }
+
+    private static List<TestFilter> getFilter(Map<String, List<TestFilter>> filters, String id) {
+        List<TestFilter> fs = filters.get(id);
+        if (fs == null) {
+            fs = new ArrayList<>();
+            filters.put(id, fs);
+        }
+        return fs;
+    }
+
+    private void addModuleDef(String name, IAbi abi, IRemoteTest test,
+            String[] configPaths) throws ConfigurationException {
+        // Invokes parser to process the test module config file
+        IConfiguration config = mConfigFactory.createConfigurationFromArgs(configPaths);
+        addModuleDef(new ModuleDef(name, abi, test, config.getTargetPreparers()));
+    }
+
+    private void addModuleDef(IModuleDef moduleDef) {
+        String id = moduleDef.getId();
+        boolean includeModule = mIncludeAll;
+        for (TestFilter include : getFilter(mIncludeFilters, id)) {
+            String test = include.getTest();
+            if (test != null) {
+                // We're including a subset of tests
+                moduleDef.addIncludeFilter(test);
+            }
+            includeModule = true;
+        }
+        for (TestFilter exclude : getFilter(mExcludeFilters, id)) {
+            String test = exclude.getTest();
+            if (test != null) {
+                // Excluding a subset of tests, so keep module but give filter
+                moduleDef.addExcludeFilter(test);
+            } else {
+                // Excluding all tests in the module so just remove the whole thing
+                includeModule = false;
+            }
+        }
+        if (includeModule) {
+            Set<String> tokens = moduleDef.getTokens();
+            if (tokens != null && !tokens.isEmpty()) {
+                mTokenModules.add(moduleDef);
+            } else if (moduleDef.getRuntimeHint() < SMALL_TEST) {
+                mSmallModules.add(moduleDef);
+            } else if (moduleDef.getRuntimeHint() < MEDIUM_TEST) {
+                mMediumModules.add(moduleDef);
+            } else {
+                mLargeModules.add(moduleDef);
+            }
+            mModuleCount++;
+        }
+    }
+
+    /**
+     * A {@link FilenameFilter} to find all the config files in a directory.
+     */
+    public static class ConfigFilter implements FilenameFilter {
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public boolean accept(File dir, String name) {
+            CLog.d("%s/%s", dir.getAbsolutePath(), name);
+            return name.endsWith(CONFIG_EXT);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized List<IModuleDef> getModules(String serial) {
+        List<IModuleDef> modules = new ArrayList<>(mModulesPerShard);
+        Set<String> tokens = mDeviceTokens.get(serial);
+        getModulesWithTokens(tokens, modules);
+        getModules(modules);
+        mSerials.add(serial);
+        if (mSerials.size() == mShards) {
+            for (IModuleDef def : mTokenModules) {
+                CLog.logAndDisplay(LogLevel.WARN,
+                        String.format("No devices found with %s, running %s on %s",
+                                def.getTokens(), def.getId(), serial));
+                modules.add(def);
+            }
+            // Add left over modules
+            modules.addAll(mLargeModules);
+            modules.addAll(mMediumModules);
+            modules.addAll(mSmallModules);
+        }
+        long estimatedTime = 0;
+        for (IModuleDef def : modules) {
+            estimatedTime += def.getRuntimeHint();
+        }
+        Collections.sort(modules, new ExecutionOrderComparator());
+        CLog.logAndDisplay(LogLevel.INFO, String.format(
+                "%s running %s modules, expected to complete in %s",
+                serial, modules.size(), TimeUtil.formatElapsedTime(estimatedTime)));
+        return modules;
+    }
+
+    /**
+     * Iterates through the remaining tests that require tokens and if the device has all the
+     * required tokens it will queue that module to run on that device, else the module gets put
+     * back into the list.
+     */
+    private void getModulesWithTokens(Set<String> tokens, List<IModuleDef> modules) {
+        if (tokens != null) {
+            List<IModuleDef> copy = mTokenModules;
+            mTokenModules = new ArrayList<>();
+            for (IModuleDef module : copy) {
+                // If a device has all the tokens required by the module then it can run it.
+                if (tokens.containsAll(module.getTokens())) {
+                    modules.add(module);
+                } else {
+                    mTokenModules.add(module);
+                }
+            }
+        }
+    }
+
+    /**
+     * Adds count modules that do not require tokens, to run on a device.
+     */
+    private void getModules(List<IModuleDef> modules) {
+        // Take the normal share of modules unless the device already has token modules.
+        takeModule(mSmallModules, modules, mSmallModulesPerShard - modules.size());
+        takeModule(mMediumModules, modules, mMediumModulesPerShard);
+        takeModule(mLargeModules, modules, mLargeModulesPerShard);
+        // If one bucket runs out, take from any of the others.
+        boolean success = true;
+        while (success && modules.size() < mModulesPerShard) {
+            // Take modules from the buckets until it has enough, or there are no more modules.
+            success = takeModule(mSmallModules, modules, 1)
+                    || takeModule(mMediumModules, modules, 1)
+                    || takeModule(mLargeModules, modules, 1);
+        }
+    }
+
+    /**
+     * Takes count modules from the first list and move it to the second.
+     */
+    private static boolean takeModule(
+            List<IModuleDef> source, List<IModuleDef> destination, int count) {
+        if (source.isEmpty()) {
+            return false;
+        }
+        if (count > source.size()) {
+            count = source.size();
+        }
+        for (int i = 0; i < count; i++) {
+            destination.add(source.remove(source.size() - 1));// Take from the end of the arraylist.
+        }
+        return true;
+    }
+
+    /**
+     * @return the {@link List} of modules whose name contains the given pattern.
+     */
+    public static List<String> getModuleNamesMatching(File directory, String pattern) {
+        String[] names = directory.list(new NameFilter(pattern));
+        List<String> modules = new ArrayList<String>(names.length);
+        for (String name : names) {
+            int index = name.indexOf(CONFIG_EXT);
+            if (index > 0) {
+                String module = name.substring(0, index);
+                if (module.equals(pattern)) {
+                    // Pattern represents a single module, just return a single-item list
+                    modules = new ArrayList<>(1);
+                    modules.add(module);
+                    return modules;
+                }
+                modules.add(module);
+            }
+        }
+        return modules;
+    }
+
+    private static void putArgs(List<String> args, Map<String, Map<String, String>> argsMap) {
+        for (String arg : args) {
+            String[] parts = arg.split(":");
+            String target = parts[0];
+            String key = parts[1];
+            String value = parts[2];
+            Map<String, String> map = argsMap.get(target);
+            if (map == null) {
+                map = new HashMap<>();
+                argsMap.put(target, map);
+            }
+            map.put(key, value);
+        }
+    }
+
+    private static class ExecutionOrderComparator implements Comparator<IModuleDef> {
+
+        @Override
+        public int compare(IModuleDef def1, IModuleDef def2) {
+            int value1 = 0;
+            int value2 = 0;
+            if (ENDING_MODULES.containsKey(def1.getName())) {
+                value1 = ENDING_MODULES.get(def1.getName());
+            }
+            if (ENDING_MODULES.containsKey(def2.getName())) {
+                value2 = ENDING_MODULES.get(def2.getName());
+            }
+            if (value1 == 0 && value2 == 0) {
+                return (int) Math.signum(def2.getRuntimeHint() - def1.getRuntimeHint());
+            }
+            return (int) Math.signum(value1 - value2);
+        }
+    }
+}
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/util/NoOpTestInvocationListener.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/util/NoOpTestInvocationListener.java
new file mode 100644
index 0000000..06f493d
--- /dev/null
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/util/NoOpTestInvocationListener.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.tradefed.util;
+
+import com.android.ddmlib.testrunner.TestIdentifier;
+import com.android.ddmlib.testrunner.ITestRunListener;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.result.InputStreamSource;
+import com.android.tradefed.result.LogDataType;
+import com.android.tradefed.result.ITestInvocationListener;
+import com.android.tradefed.result.TestSummary;
+
+import java.util.Map;
+
+/**
+ * Implementation of ITestInvocationListener that does nothing or returns null for all methods.
+ * Extend this class to implement some, but not all methods of ITestInvocationListener.
+ */
+public class NoOpTestInvocationListener implements ITestInvocationListener {
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void invocationStarted(IBuildInfo buildInfo) {}
+
+     /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void testLog(String dataName, LogDataType dataType, InputStreamSource dataStream) {}
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void invocationEnded(long elapsedTime) {}
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void invocationFailed(Throwable cause) {}
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public TestSummary getSummary() {
+        return null;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void testRunStarted(String runName, int testCount) {}
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void testStarted(TestIdentifier test) {}
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void testFailed(TestIdentifier test, String trace) {}
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void testAssumptionFailure(TestIdentifier test, String trace) {}
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void testIgnored(TestIdentifier test) {}
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void testEnded(TestIdentifier test, Map<String, String> testMetrics) {}
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void testRunFailed(String errorMessage) {}
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void testRunStopped(long elapsedTime) {}
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void testRunEnded(long elapsedTime, Map<String, String> runMetrics) {}
+
+}
diff --git a/common/host-side/tradefed/tests/Android.mk b/common/host-side/tradefed/tests/Android.mk
new file mode 100644
index 0000000..e0b44a3
--- /dev/null
+++ b/common/host-side/tradefed/tests/Android.mk
@@ -0,0 +1,46 @@
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Make a mock compatibility suite to test
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, ../src)
+LOCAL_JAVA_RESOURCE_DIRS := ../res
+
+LOCAL_SUITE_BUILD_NUMBER := 2
+LOCAL_SUITE_TARGET_ARCH := $(TARGET_ARCH)
+LOCAL_SUITE_NAME := TESTS
+LOCAL_SUITE_FULLNAME := "Compatibility Tests"
+LOCAL_SUITE_VERSION := 1
+
+LOCAL_MODULE := compatibility-mock-tradefed
+
+include $(BUILD_COMPATIBILITY_SUITE)
+
+# Make the tests
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_MODULE := compatibility-tradefed-tests
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_STATIC_JAVA_LIBRARIES := easymock
+
+LOCAL_JAVA_LIBRARIES := tradefed-prebuilt compatibility-mock-tradefed junit compatibility-host-util
+
+include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/common/host-side/tradefed/tests/run_tests.sh b/common/host-side/tradefed/tests/run_tests.sh
new file mode 100755
index 0000000..1d1940d
--- /dev/null
+++ b/common/host-side/tradefed/tests/run_tests.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+CTS_DIR=$(dirname ${0})/../../../..
+source ${CTS_DIR}/test_defs.sh
+
+JARS="
+    compatibility-common-util-hostsidelib\
+    compatibility-common-util-tests\
+    compatibility-host-util\
+    compatibility-host-util-tests\
+    compatibility-mock-tradefed\
+    compatibility-tradefed-tests"
+
+run_tests "com.android.compatibility.common.tradefed.UnitTests" "${JARS}" "${@}"
+
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/TradefedTest.java b/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/TradefedTest.java
deleted file mode 100644
index ab19369..0000000
--- a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/TradefedTest.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.compatibility.common.tradefed;
-
-import junit.framework.TestCase;
-
-public class TradefedTest extends TestCase {
-
-    // TODO(stuartscott): Add tests when there is something to test.
-
-}
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/UnitTests.java b/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/UnitTests.java
new file mode 100644
index 0000000..318960c
--- /dev/null
+++ b/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/UnitTests.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.tradefed;
+
+import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelperTest;
+import com.android.compatibility.common.tradefed.command.CompatibilityConsoleTest;
+import com.android.compatibility.common.tradefed.result.ResultReporterTest;
+import com.android.compatibility.common.tradefed.targetprep.PropertyCheckTest;
+import com.android.compatibility.common.tradefed.targetprep.SettingsPreparerTest;
+import com.android.compatibility.common.tradefed.testtype.CompatibilityTestTest;
+import com.android.compatibility.common.tradefed.testtype.ModuleDefTest;
+import com.android.compatibility.common.tradefed.testtype.ModuleRepoTest;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * A test suite for all compatibility tradefed unit tests.
+ * <p/>
+ * All tests listed here should be self-contained, and do not require any external dependencies.
+ */
+public class UnitTests extends TestSuite {
+
+    public UnitTests() {
+        super();
+        addTestSuite(CompatibilityBuildHelperTest.class);
+        addTestSuite(CompatibilityConsoleTest.class);
+        addTestSuite(ResultReporterTest.class);
+        addTestSuite(CompatibilityTestTest.class);
+        addTestSuite(ModuleDefTest.class);
+        addTestSuite(ModuleRepoTest.class);
+        addTestSuite(PropertyCheckTest.class);
+        addTestSuite(SettingsPreparerTest.class);
+    }
+
+    public static Test suite() {
+        return new UnitTests();
+    }
+}
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/build/CompatibilityBuildHelperTest.java b/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/build/CompatibilityBuildHelperTest.java
new file mode 100644
index 0000000..55d15dd
--- /dev/null
+++ b/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/build/CompatibilityBuildHelperTest.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.compatibility.common.tradefed.build;
+
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.util.FileUtil;
+
+import junit.framework.TestCase;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+
+public class CompatibilityBuildHelperTest extends TestCase {
+
+    private static final String ROOT_PROPERTY = "TESTS_ROOT";
+    private static final String BUILD_NUMBER = "2";
+    private static final String SUITE_NAME = "TESTS";
+    private static final String SUITE_FULL_NAME = "Compatibility Tests";
+    private static final String SUITE_VERSION = "1";
+    private static final String SUITE_PLAN = "cts";
+    private static final String DYNAMIC_CONFIG_URL = "";
+    private static final String ROOT_DIR_NAME = "root";
+    private static final String BASE_DIR_NAME = "android-tests";
+    private static final String TESTCASES = "testcases";
+
+    private File mRoot = null;
+    private File mBase = null;
+    private File mTests = null;
+    private IBuildInfo mBuild;
+    private CompatibilityBuildHelper mHelper;
+
+    @Override
+    public void setUp() throws Exception {
+        mRoot = FileUtil.createTempDir(ROOT_DIR_NAME);
+        CompatibilityBuildProvider provider = new CompatibilityBuildProvider();
+        mBuild = provider.getBuild();
+        mHelper = new CompatibilityBuildHelper(mBuild);
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        setProperty(null);
+        FileUtil.recursiveDelete(mRoot);
+        mRoot = null;
+        mBase = null;
+        mTests = null;
+    }
+
+    private void createDirStructure() {
+        mBase = new File(mRoot, BASE_DIR_NAME);
+        mBase.mkdirs();
+        mTests = new File(mBase, TESTCASES);
+        mTests.mkdirs();
+    }
+
+    public void testSuiteInfoLoad() throws Exception {
+        setProperty(mRoot.getAbsolutePath());
+        mHelper.init(SUITE_PLAN, DYNAMIC_CONFIG_URL);
+        assertEquals("Incorrect suite build number", BUILD_NUMBER, mHelper.getSuiteBuild());
+        assertEquals("Incorrect suite name", SUITE_NAME, mHelper.getSuiteName());
+        assertEquals("Incorrect suite full name", SUITE_FULL_NAME, mHelper.getSuiteFullName());
+        assertEquals("Incorrect suite version", SUITE_VERSION, mHelper.getSuiteVersion());
+    }
+
+    public void testProperty() throws Exception {
+        setProperty(null);
+        CompatibilityBuildProvider provider = new CompatibilityBuildProvider();
+        CompatibilityBuildHelper helper = new CompatibilityBuildHelper(provider.getBuild());
+        try {
+            // Should fail with root unset
+            helper.init(SUITE_PLAN, DYNAMIC_CONFIG_URL);
+            fail("Expected fail for unset root property");
+        } catch (IllegalArgumentException e) {
+            /* expected */
+        }
+        setProperty(mRoot.getAbsolutePath());
+        // Shouldn't fail with root set
+        helper.init(SUITE_PLAN, DYNAMIC_CONFIG_URL);
+    }
+
+    public void testValidation() throws Exception {
+        setProperty(mRoot.getAbsolutePath());
+        mHelper.init(SUITE_PLAN, DYNAMIC_CONFIG_URL);
+        try {
+            mHelper.getDir();
+            fail("Build helper validation succeeded on an invalid installation");
+        } catch (FileNotFoundException e) {
+            // Expected
+        }
+        createDirStructure();
+        try {
+            mHelper.getTestsDir();
+        } catch (IllegalArgumentException e) {
+            e.printStackTrace();
+            fail("Build helper validation failed on a valid installation");
+        }
+    }
+
+    public void testDirs() throws Exception {
+        setProperty(mRoot.getAbsolutePath());
+        mHelper.init(SUITE_PLAN, DYNAMIC_CONFIG_URL);
+        createDirStructure();
+        assertNotNull(mRoot);
+        assertNotNull(mBuild);
+        assertNotNull(mHelper.getRootDir());
+        assertEquals("Incorrect root dir", mRoot.getAbsolutePath(),
+                mHelper.getRootDir().getAbsolutePath());
+        assertEquals("Incorrect base dir", mBase.getAbsolutePath(),
+                mHelper.getDir().getAbsolutePath());
+        assertEquals("Incorrect logs dir", new File(mBase, "logs").getAbsolutePath(),
+                mHelper.getLogsDir().getAbsolutePath());
+        assertEquals("Incorrect tests dir", mTests.getAbsolutePath(),
+                mHelper.getTestsDir().getAbsolutePath());
+        assertEquals("Incorrect results dir", new File(mBase, "results").getAbsolutePath(),
+                mHelper.getResultsDir().getAbsolutePath());
+    }
+
+    /**
+     * Sets the *_ROOT property of the build's installation location.
+     *
+     * @param value the value to set, or null to clear the property.
+     */
+    public static void setProperty(String value) {
+        if (value == null) {
+            System.clearProperty(ROOT_PROPERTY);
+        } else {
+            System.setProperty(ROOT_PROPERTY, value);
+        }
+    }
+}
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/command/CompatibilityConsoleTest.java b/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/command/CompatibilityConsoleTest.java
new file mode 100644
index 0000000..55c1651
--- /dev/null
+++ b/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/command/CompatibilityConsoleTest.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.compatibility.common.tradefed.command;
+
+import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelperTest;
+
+import junit.framework.TestCase;
+
+public class CompatibilityConsoleTest extends TestCase {
+
+    @Override
+    public void setUp() throws Exception {
+        CompatibilityBuildHelperTest.setProperty("/tmp/foobar");
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        CompatibilityBuildHelperTest.setProperty(null);
+    }
+
+    public void testHelpExists() throws Exception {
+        CompatibilityConsole console = new CompatibilityConsole() {};
+        assertFalse("No help", console.getGenericHelpString(null).isEmpty());
+    }
+
+    public void testPromptExists() throws Exception {
+        CompatibilityConsole console = new CompatibilityConsole() {};
+        assertFalse("No prompt", console.getConsolePrompt().isEmpty());
+    }
+}
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/result/ResultReporterTest.java b/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/result/ResultReporterTest.java
new file mode 100644
index 0000000..6228cd7
--- /dev/null
+++ b/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/result/ResultReporterTest.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.compatibility.common.tradefed.result;
+
+import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
+import com.android.compatibility.common.util.AbiUtils;
+import com.android.compatibility.common.util.ICaseResult;
+import com.android.compatibility.common.util.IInvocationResult;
+import com.android.compatibility.common.util.IModuleResult;
+import com.android.compatibility.common.util.ITestResult;
+import com.android.compatibility.common.util.TestStatus;
+import com.android.ddmlib.testrunner.TestIdentifier;
+import com.android.tradefed.build.BuildInfo;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.config.OptionSetter;
+import com.android.tradefed.util.FileUtil;
+
+import junit.framework.TestCase;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.util.HashMap;
+import java.util.List;
+
+public class ResultReporterTest extends TestCase {
+
+    private static final String ROOT_PROPERTY = "TESTS_ROOT";
+    private static final String BUILD_NUMBER = "2";
+    private static final String SUITE_PLAN = "cts";
+    private static final String DYNAMIC_CONFIG_URL = "";
+    private static final String ROOT_DIR_NAME = "root";
+    private static final String BASE_DIR_NAME = "android-tests";
+    private static final String TESTCASES = "testcases";
+    private static final String NAME = "ModuleName";
+    private static final String ABI = "mips64";
+    private static final String ID = AbiUtils.createId(ABI, NAME);
+    private static final String CLASS = "android.test.FoorBar";
+    private static final String METHOD_1 = "testBlah1";
+    private static final String METHOD_2 = "testBlah2";
+    private static final String METHOD_3 = "testBlah3";
+    private static final String TEST_1 = String.format("%s#%s", CLASS, METHOD_1);
+    private static final String TEST_2 = String.format("%s#%s", CLASS, METHOD_2);
+    private static final String TEST_3 = String.format("%s#%s", CLASS, METHOD_3);
+    private static final String STACK_TRACE = "Something small is not alright\n " +
+            "at four.big.insects.Marley.sing(Marley.java:10)";
+    private static final String RESULT_DIR = "result123";
+    private static final String[] FORMATTING_FILES = {
+        "compatibility_result.css",
+        "compatibility_result.xsd",
+        "compatibility_result.xsl",
+        "logo.png"};
+
+    private ResultReporter mReporter;
+    private IBuildInfo mBuildInfo;
+    private CompatibilityBuildHelper mBuildHelper;
+
+    private File mRoot = null;
+    private File mBase = null;
+    private File mTests = null;
+
+    @Override
+    public void setUp() throws Exception {
+        mReporter = new ResultReporter();
+        OptionSetter setter = new OptionSetter(mReporter);
+        setter.setOptionValue("quiet-output", "true");
+        mRoot = FileUtil.createTempDir(ROOT_DIR_NAME);
+        mBase = new File(mRoot, BASE_DIR_NAME);
+        mBase.mkdirs();
+        mTests = new File(mBase, TESTCASES);
+        mTests.mkdirs();
+        System.setProperty(ROOT_PROPERTY, mRoot.getAbsolutePath());
+        mBuildInfo = new BuildInfo(BUILD_NUMBER, "", "");
+        mBuildHelper = new CompatibilityBuildHelper(mBuildInfo);
+        mBuildHelper.init(SUITE_PLAN, DYNAMIC_CONFIG_URL);
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        mReporter = null;
+        FileUtil.recursiveDelete(mRoot);
+    }
+
+    public void testSetup() throws Exception {
+        mReporter.invocationStarted(mBuildInfo);
+        // Should have created a directory for the logs
+        File[] children = mBuildHelper.getLogsDir().listFiles();
+        assertTrue("Didn't create logs dir", children.length == 1 && children[0].isDirectory());
+        // Should have created a directory for the results
+        children = mBuildHelper.getResultsDir().listFiles();
+        assertTrue("Didn't create results dir", children.length == 1 && children[0].isDirectory());
+        mReporter.invocationEnded(10);
+        // Should have created a zip file
+        children = mBuildHelper.getResultsDir().listFiles(new FileFilter() {
+            @Override
+            public boolean accept(File pathname) {
+                return pathname.getName().endsWith(".zip");
+            }
+        });
+        assertTrue("Didn't create results zip",
+                children.length == 1 && children[0].isFile() && children[0].length() > 0);
+    }
+
+    public void testResultReporting() throws Exception {
+        mReporter.invocationStarted(mBuildInfo);
+        mReporter.testRunStarted(ID, 2);
+        TestIdentifier test1 = new TestIdentifier(CLASS, METHOD_1);
+        mReporter.testStarted(test1);
+        mReporter.testEnded(test1, new HashMap<String, String>());
+        TestIdentifier test2 = new TestIdentifier(CLASS, METHOD_2);
+        mReporter.testStarted(test2);
+        mReporter.testFailed(test2, STACK_TRACE);
+        TestIdentifier test3 = new TestIdentifier(CLASS, METHOD_3);
+        mReporter.testStarted(test3);
+        mReporter.testFailed(test3, STACK_TRACE);
+        mReporter.testRunEnded(10, new HashMap<String, String>());
+        mReporter.invocationEnded(10);
+        IInvocationResult result = mReporter.getResult();
+        assertEquals("Expected 1 pass", 1, result.countResults(TestStatus.PASS));
+        assertEquals("Expected 2 failures", 2, result.countResults(TestStatus.FAIL));
+        List<IModuleResult> modules = result.getModules();
+        assertEquals("Expected 1 module", 1, modules.size());
+        IModuleResult module = modules.get(0);
+        assertEquals("Incorrect ID", ID, module.getId());
+        List<ICaseResult> caseResults = module.getResults();
+        assertEquals("Expected 1 test case", 1, caseResults.size());
+        ICaseResult caseResult = caseResults.get(0);
+        List<ITestResult> testResults = caseResult.getResults();
+        assertEquals("Expected 3 tests", 3, testResults.size());
+        ITestResult result1 = caseResult.getResult(METHOD_1);
+        assertNotNull(String.format("Expected result for %s", TEST_1), result1);
+        assertEquals(String.format("Expected pass for %s", TEST_1), TestStatus.PASS,
+                result1.getResultStatus());
+        ITestResult result2 = caseResult.getResult(METHOD_2);
+        assertNotNull(String.format("Expected result for %s", TEST_2), result2);
+        assertEquals(String.format("Expected fail for %s", TEST_2), TestStatus.FAIL,
+                result2.getResultStatus());
+        ITestResult result3 = caseResult.getResult(METHOD_3);
+        assertNotNull(String.format("Expected result for %s", TEST_3), result3);
+        assertEquals(String.format("Expected fail for %s", TEST_3), TestStatus.FAIL,
+                result3.getResultStatus());
+    }
+
+    public void testCopyFormattingFiles() throws Exception {
+        File resultDir = new File(mBuildHelper.getResultsDir(), RESULT_DIR);
+        resultDir.mkdirs();
+        ResultReporter.copyFormattingFiles(resultDir);
+        for (String filename : FORMATTING_FILES) {
+            File file = new File(resultDir, filename);
+            assertTrue(String.format("%s (%s) was not created", filename, file.getAbsolutePath()),
+                    file.exists() && file.isFile() && file.length() > 0);
+        }
+    }
+}
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/targetprep/PropertyCheckTest.java b/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/targetprep/PropertyCheckTest.java
new file mode 100644
index 0000000..a309a47
--- /dev/null
+++ b/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/targetprep/PropertyCheckTest.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.compatibility.common.tradefed.targetprep;
+
+import com.android.tradefed.build.DeviceBuildInfo;
+import com.android.tradefed.build.IDeviceBuildInfo;
+import com.android.tradefed.config.OptionSetter;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.targetprep.TargetSetupError;
+
+import junit.framework.TestCase;
+
+import org.easymock.EasyMock;
+
+public class PropertyCheckTest extends TestCase {
+
+    private PropertyCheck mPropertyCheck;
+    private IDeviceBuildInfo mMockBuildInfo;
+    private ITestDevice mMockDevice;
+    private OptionSetter mOptionSetter;
+
+    private static final String PROPERTY = "ro.mock.property";
+    private static final String ACTUAL_VALUE = "mock_actual_value";
+    private static final String BAD_VALUE = "mock_bad_value";
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        mPropertyCheck = new PropertyCheck();
+        mMockDevice = EasyMock.createMock(ITestDevice.class);
+        mMockBuildInfo = new DeviceBuildInfo("0", "", "");
+        mOptionSetter = new OptionSetter(mPropertyCheck);
+        EasyMock.expect(mMockDevice.getProperty(PROPERTY)).andReturn(ACTUAL_VALUE).anyTimes();
+    }
+
+    public void testWarningMatch() throws Exception {
+        mOptionSetter.setOptionValue("property-name", PROPERTY);
+        mOptionSetter.setOptionValue("expected-value", ACTUAL_VALUE);
+        mOptionSetter.setOptionValue("throw-error", "false");
+        EasyMock.replay(mMockDevice);
+        mPropertyCheck.run(mMockDevice, mMockBuildInfo); // no warnings or errors
+    }
+
+    public void testWarningMismatch() throws Exception {
+        mOptionSetter.setOptionValue("property-name", PROPERTY);
+        mOptionSetter.setOptionValue("expected-value", BAD_VALUE);
+        mOptionSetter.setOptionValue("throw-error", "false");
+        EasyMock.replay(mMockDevice);
+        mPropertyCheck.run(mMockDevice, mMockBuildInfo); // should only print a warning
+    }
+
+    public void testErrorMatch() throws Exception {
+        mOptionSetter.setOptionValue("property-name", PROPERTY);
+        mOptionSetter.setOptionValue("expected-value", ACTUAL_VALUE);
+        mOptionSetter.setOptionValue("throw-error", "true");
+        EasyMock.replay(mMockDevice);
+        mPropertyCheck.run(mMockDevice, mMockBuildInfo); // no warnings or errors
+    }
+
+    public void testErrorMismatch() throws Exception {
+        mOptionSetter.setOptionValue("property-name", PROPERTY);
+        mOptionSetter.setOptionValue("expected-value", BAD_VALUE);
+        mOptionSetter.setOptionValue("throw-error", "true");
+        EasyMock.replay(mMockDevice);
+        try {
+            mPropertyCheck.run(mMockDevice, mMockBuildInfo); // expecting TargetSetupError
+            fail("TargetSetupError expected");
+        } catch (TargetSetupError e) {
+            // Expected
+        }
+    }
+
+}
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/targetprep/SettingsPreparerTest.java b/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/targetprep/SettingsPreparerTest.java
new file mode 100644
index 0000000..739662e
--- /dev/null
+++ b/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/targetprep/SettingsPreparerTest.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.compatibility.common.tradefed.targetprep;
+
+import com.android.tradefed.build.DeviceBuildInfo;
+import com.android.tradefed.build.BuildInfo;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.config.OptionSetter;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.targetprep.TargetSetupError;
+
+import junit.framework.TestCase;
+
+import org.easymock.EasyMock;
+
+public class SettingsPreparerTest extends TestCase {
+
+    private SettingsPreparer mSettingsPreparer;
+    private IBuildInfo mMockBuildInfo;
+    private ITestDevice mMockDevice;
+    private OptionSetter mOptionSetter;
+
+    private static final String SHELL_CMD_GET = "settings get GLOBAL stay_on_while_plugged_in";
+    private static final String SHELL_CMD_PUT_7 = "settings put GLOBAL stay_on_while_plugged_in 7";
+    private static final String SHELL_CMD_PUT_8 = "settings put GLOBAL stay_on_while_plugged_in 8";
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        mSettingsPreparer = new SettingsPreparer();
+        mMockDevice = EasyMock.createMock(ITestDevice.class);
+        mMockBuildInfo = new BuildInfo("0", "", "");
+        mOptionSetter = new OptionSetter(mSettingsPreparer);
+        mOptionSetter.setOptionValue("device-setting", "stay_on_while_plugged_in");
+        mOptionSetter.setOptionValue("setting-type", "global");
+    }
+
+    public void testCorrectOneExpected() throws Exception {
+        EasyMock.expect(mMockDevice.executeShellCommand(SHELL_CMD_GET)).andReturn("\n3\n").once();
+        mOptionSetter.setOptionValue("expected-values", "3");
+        EasyMock.replay(mMockDevice);
+        mSettingsPreparer.run(mMockDevice, mMockBuildInfo);
+    }
+
+    public void testCorrectManyExpected() throws Exception {
+        EasyMock.expect(mMockDevice.executeShellCommand(SHELL_CMD_GET)).andReturn("\n3\n").once();
+        mOptionSetter.setOptionValue("expected-values", "2");
+        mOptionSetter.setOptionValue("expected-values", "3");
+        mOptionSetter.setOptionValue("expected-values", "6");
+        mOptionSetter.setOptionValue("expected-values", "7");
+        EasyMock.replay(mMockDevice);
+        mSettingsPreparer.run(mMockDevice, mMockBuildInfo);
+    }
+
+    public void testIncorrectOneExpected() throws Exception {
+        EasyMock.expect(mMockDevice.executeShellCommand(SHELL_CMD_GET)).andReturn("\n0\n").once();
+        mOptionSetter.setOptionValue("expected-values", "3");
+        EasyMock.replay(mMockDevice);
+        try {
+            mSettingsPreparer.run(mMockDevice, mMockBuildInfo);
+            fail("TargetSetupError expected");
+        } catch (TargetSetupError e) {
+            //Expected
+        }
+    }
+
+    public void testIncorrectManyExpected() throws Exception {
+        EasyMock.expect(mMockDevice.executeShellCommand(SHELL_CMD_GET)).andReturn("\n0\n").once();
+        mOptionSetter.setOptionValue("expected-values", "2");
+        mOptionSetter.setOptionValue("expected-values", "3");
+        mOptionSetter.setOptionValue("expected-values", "6");
+        mOptionSetter.setOptionValue("expected-values", "7");
+        EasyMock.replay(mMockDevice);
+        try {
+            mSettingsPreparer.run(mMockDevice, mMockBuildInfo);
+            fail("TargetSetupError expected");
+        } catch (TargetSetupError e) {
+            //Expected
+        }
+    }
+
+    public void testCommandRun() throws Exception {
+        EasyMock.expect(mMockDevice.executeShellCommand(SHELL_CMD_PUT_7)).andReturn("\n");
+        mOptionSetter.setOptionValue("set-value", "7");
+        EasyMock.replay(mMockDevice);
+        mSettingsPreparer.run(mMockDevice, mMockBuildInfo);
+    }
+
+    public void testCommandRunWrongSetValue() throws Exception {
+        EasyMock.expect(mMockDevice.executeShellCommand(SHELL_CMD_PUT_8)).andReturn("\n");
+        mOptionSetter.setOptionValue("set-value", "8");
+        mOptionSetter.setOptionValue("expected-values", "7");
+        EasyMock.replay(mMockDevice);
+        try {
+            mSettingsPreparer.run(mMockDevice, mMockBuildInfo);
+            fail("TargetSetupError expected");
+        } catch (TargetSetupError e) {
+            //Expected
+        }
+    }
+
+    public void testIncorrectOneExpectedCommandRun() throws Exception {
+        EasyMock.expect(mMockDevice.executeShellCommand(SHELL_CMD_GET)).andReturn("\n0\n").once();
+        EasyMock.expect(mMockDevice.executeShellCommand(SHELL_CMD_PUT_7)).andReturn("\n");
+        mOptionSetter.setOptionValue("set-value", "7");
+        mOptionSetter.setOptionValue("expected-values", "7");
+    }
+
+}
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/CompatibilityTestTest.java b/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/CompatibilityTestTest.java
new file mode 100644
index 0000000..ccab426
--- /dev/null
+++ b/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/CompatibilityTestTest.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.compatibility.common.tradefed.testtype;
+
+import junit.framework.TestCase;
+
+public class CompatibilityTestTest extends TestCase {
+
+    @Override
+    public void setUp() throws Exception {
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+    }
+
+}
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/ModuleDefTest.java b/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/ModuleDefTest.java
new file mode 100644
index 0000000..8714c1d
--- /dev/null
+++ b/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/ModuleDefTest.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.compatibility.common.tradefed.testtype;
+
+import com.android.compatibility.common.tradefed.util.NoOpTestInvocationListener;
+import com.android.compatibility.common.util.AbiUtils;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.result.ITestInvocationListener;
+import com.android.tradefed.targetprep.ITargetPreparer;
+import com.android.tradefed.testtype.IAbi;
+import com.android.tradefed.testtype.IRemoteTest;
+import com.android.tradefed.testtype.ITestFilterReceiver;
+
+import junit.framework.TestCase;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ModuleDefTest extends TestCase {
+
+    private static final String NAME = "ModuleName";
+    private static final String ABI = "mips64";
+    private static final String ID = AbiUtils.createId(ABI, NAME);
+    private static final String CLASS = "android.test.FoorBar";
+    private static final String METHOD_1 = "testBlah1";
+    private static final String TEST_1 = String.format("%s#%s", CLASS, METHOD_1);
+
+    public void testAccessors() throws Exception {
+        IAbi abi = new Abi(ABI, "");
+        MockRemoteTest mockTest = new MockRemoteTest();
+        IModuleDef def = new ModuleDef(NAME, abi, mockTest, new ArrayList<ITargetPreparer>());
+        assertEquals("Incorrect ID", ID, def.getId());
+        assertEquals("Incorrect ABI", ABI, def.getAbi().getName());
+        assertEquals("Incorrect Name", NAME, def.getName());
+    }
+
+    public void testAddFilters() throws Exception {
+        IAbi abi = new Abi(ABI, "");
+        MockRemoteTest mockTest = new MockRemoteTest();
+        ModuleDef def = new ModuleDef(NAME, abi, mockTest, new ArrayList<ITargetPreparer>());
+        def.addIncludeFilter(CLASS);
+        def.addExcludeFilter(TEST_1);
+        MockListener mockListener = new MockListener();
+        def.run(mockListener);
+        assertEquals("Expected one include filter", 1, mockTest.mIncludeFilters.size());
+        assertEquals("Expected one exclude filter", 1, mockTest.mExcludeFilters.size());
+        assertEquals("Incorrect include filter", CLASS, mockTest.mIncludeFilters.get(0));
+        assertEquals("Incorrect exclude filter", TEST_1, mockTest.mExcludeFilters.get(0));
+    }
+
+    private class MockRemoteTest implements IRemoteTest, ITestFilterReceiver {
+
+        private final List<String> mIncludeFilters = new ArrayList<>();
+        private final List<String> mExcludeFilters = new ArrayList<>();
+
+        @Override
+        public void addIncludeFilter(String filter) {
+            mIncludeFilters.add(filter);
+        }
+
+        @Override
+        public void addAllIncludeFilters(List<String> filters) {
+            mIncludeFilters.addAll(filters);
+        }
+
+        @Override
+        public void addExcludeFilter(String filter) {
+            mExcludeFilters.add(filter);
+        }
+
+        @Override
+        public void addAllExcludeFilters(List<String> filters) {
+            mExcludeFilters.addAll(filters);
+        }
+
+        @Override
+        public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
+            // Do nothing
+        }
+
+    }
+
+    private class MockListener extends NoOpTestInvocationListener {}
+}
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/ModuleRepoTest.java b/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/ModuleRepoTest.java
new file mode 100644
index 0000000..c691abd
--- /dev/null
+++ b/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/ModuleRepoTest.java
@@ -0,0 +1,246 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.compatibility.common.tradefed.testtype;
+
+import com.android.compatibility.common.tradefed.build.CompatibilityBuildProvider;
+import com.android.compatibility.common.tradefed.testtype.ModuleRepo.ConfigFilter;
+import com.android.compatibility.common.tradefed.testtype.IModuleDef;
+import com.android.compatibility.common.util.AbiUtils;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.testtype.IAbi;
+import com.android.tradefed.testtype.IRemoteTest;
+import com.android.tradefed.testtype.IShardableTest;
+import com.android.tradefed.util.FileUtil;
+
+import junit.framework.TestCase;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+public class ModuleRepoTest extends TestCase {
+
+    private static final String TOKEN =
+            "<target_preparer class=\"com.android.compatibility.common.tradefed.targetprep.TokenRequirement\">\n"
+            + "<option name=\"token\" value=\"%s\" />\n"
+            + "</target_preparer>\n";
+    private static final String CONFIG =
+            "<configuration description=\"Auto Generated File\">\n" +
+            "%s" +
+            "<test class=\"com.android.compatibility.common.tradefed.testtype.%s\">\n" +
+            "<option name=\"module\" value=\"%s\" />" +
+            "</test>\n" +
+            "</configuration>";
+    private static final String FOOBAR_TOKEN = "foobar";
+    private static final String SERIAL1 = "abc";
+    private static final String SERIAL2 = "def";
+    private static final String SERIAL3 = "ghi";
+    private static final Set<String> SERIALS = new HashSet<>();
+    private static final Set<IAbi> ABIS = new HashSet<>();
+    private static final List<String> DEVICE_TOKENS = new ArrayList<>();
+    private static final List<String> TEST_ARGS= new ArrayList<>();
+    private static final List<String> MODULE_ARGS = new ArrayList<>();
+    private static final List<String> INCLUDES = new ArrayList<>();
+    private static final List<String> EXCLUDES = new ArrayList<>();
+    private static final Set<String> FILES = new HashSet<>();
+    private static final String FILENAME = "%s.config";
+    private static final String ABI_32 = "armeabi-v7a";
+    private static final String ABI_64 = "arm64-v8a";
+    private static final String MODULE_NAME_A = "FooModuleA";
+    private static final String MODULE_NAME_B = "FooModuleB";
+    private static final String MODULE_NAME_C = "FooModuleC";
+    private static final String ID_A_32 = AbiUtils.createId(ABI_32, MODULE_NAME_A);
+    private static final String ID_A_64 = AbiUtils.createId(ABI_64, MODULE_NAME_A);
+    private static final String ID_B_32 = AbiUtils.createId(ABI_32, MODULE_NAME_B);
+    private static final String ID_B_64 = AbiUtils.createId(ABI_64, MODULE_NAME_B);
+    private static final String ID_C_32 = AbiUtils.createId(ABI_32, MODULE_NAME_C);
+    private static final String ID_C_64 = AbiUtils.createId(ABI_64, MODULE_NAME_C);
+    private static final String TEST_ARG = TestStub.class.getName() + ":foo:bar";
+    private static final String MODULE_ARG = "%s:blah:foobar";
+    private static final String TEST_STUB = "TestStub"; // Trivial test stub
+    private static final String SHARDABLE_TEST_STUB = "ShardableTestStub"; // Shardable and IBuildReceiver
+    static {
+        SERIALS.add(SERIAL1);
+        SERIALS.add(SERIAL2);
+        SERIALS.add(SERIAL3);
+        ABIS.add(new Abi(ABI_32, "32"));
+        ABIS.add(new Abi(ABI_64, "64"));
+        DEVICE_TOKENS.add(String.format("%s:%s", SERIAL3, FOOBAR_TOKEN));
+        TEST_ARGS.add(TEST_ARG);
+        MODULE_ARGS.add(String.format(MODULE_ARG, MODULE_NAME_A));
+        MODULE_ARGS.add(String.format(MODULE_ARG, MODULE_NAME_B));
+        MODULE_ARGS.add(String.format(MODULE_ARG, MODULE_NAME_C));
+        FILES.add(String.format(FILENAME, MODULE_NAME_A));
+        FILES.add(String.format(FILENAME, MODULE_NAME_B));
+        FILES.add(String.format(FILENAME, MODULE_NAME_C));
+    }
+    private IModuleRepo mRepo;
+    private File mTestsDir;
+    private IBuildInfo mBuild;
+
+    @Override
+    public void setUp() throws Exception {
+        mTestsDir = setUpConfigs();
+        mRepo = new ModuleRepo();
+        mBuild = new CompatibilityBuildProvider().getBuild();
+    }
+
+    private File setUpConfigs() throws IOException {
+        File testsDir = FileUtil.createNamedTempDir("testcases");
+        createConfig(testsDir, MODULE_NAME_A, null);
+        createConfig(testsDir, MODULE_NAME_B, null);
+        createConfig(testsDir, MODULE_NAME_C, FOOBAR_TOKEN);
+        return testsDir;
+    }
+
+    private void createConfig(File testsDir, String name, String token) throws IOException {
+        createConfig(testsDir, name, token, TEST_STUB);
+    }
+
+    private void createConfig(File testsDir, String name, String token, String moduleClass) throws IOException {
+        File config = new File(testsDir, String.format(FILENAME, name));
+        String preparer = "";
+        if (token != null) {
+            preparer = String.format(TOKEN, token);
+        }
+        FileUtil.writeToFile(String.format(CONFIG, preparer, moduleClass, name), config);
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        tearDownConfigs(mTestsDir);
+    }
+
+    private void tearDownConfigs(File testsDir) {
+        FileUtil.recursiveDelete(testsDir);
+    }
+
+    public void testInitialization() throws Exception {
+        mRepo.initialize(3, mTestsDir, ABIS, DEVICE_TOKENS, TEST_ARGS, MODULE_ARGS, INCLUDES,
+                EXCLUDES, mBuild);
+        assertTrue("Should be initialized", mRepo.isInitialized());
+        assertEquals("Wrong number of shards", 3, mRepo.getNumberOfShards());
+        assertEquals("Wrong number of modules per shard", 2, mRepo.getModulesPerShard());
+        Map<String, Set<String>> deviceTokens = mRepo.getDeviceTokens();
+        assertEquals("Wrong number of devices with tokens", 1, deviceTokens.size());
+        Set<String> tokens = deviceTokens.get(SERIAL3);
+        assertEquals("Wrong number of tokens", 1, tokens.size());
+        assertTrue("Unexpected device token", tokens.contains(FOOBAR_TOKEN));
+        assertEquals("Wrong number of modules", 0, mRepo.getLargeModules().size());
+        assertEquals("Wrong number of modules", 0, mRepo.getMediumModules().size());
+        assertEquals("Wrong number of modules", 4, mRepo.getSmallModules().size());
+        List<IModuleDef> tokenModules = mRepo.getTokenModules();
+        assertEquals("Wrong number of modules with tokens", 2, tokenModules.size());
+        List<IModuleDef> serial1Modules = mRepo.getModules(SERIAL1);
+        assertEquals("Wrong number of modules", 2, serial1Modules.size());
+        List<IModuleDef> serial2Modules = mRepo.getModules(SERIAL2);
+        assertEquals("Wrong number of modules", 2, serial2Modules.size());
+        List<IModuleDef> serial3Modules = mRepo.getModules(SERIAL3);
+        assertEquals("Wrong number of modules", 2, serial3Modules.size());
+        // Serial 3 should have the modules with tokens
+        for (IModuleDef module : serial3Modules) {
+            assertEquals("Wrong module", MODULE_NAME_C, module.getName());
+        }
+        Set<String> serials = mRepo.getSerials();
+        assertEquals("Wrong number of serials", 3, serials.size());
+        assertTrue("Unexpected device serial", serials.containsAll(SERIALS));
+    }
+
+    public void testConfigFilter() throws Exception {
+        File[] configFiles = mTestsDir.listFiles(new ConfigFilter());
+        assertEquals("Wrong number of config files found.", 3, configFiles.length);
+        for (File file : configFiles) {
+            assertTrue(String.format("Unrecognised file: %s", file.getAbsolutePath()),
+                    FILES.contains(file.getName()));
+        }
+    }
+
+    public void testFiltering() throws Exception {
+        List<String> includeFilters = new ArrayList<>();
+        includeFilters.add(MODULE_NAME_A);
+        List<String> excludeFilters = new ArrayList<>();
+        excludeFilters.add(ID_A_32);
+        excludeFilters.add(MODULE_NAME_B);
+        mRepo.initialize(1, mTestsDir, ABIS, DEVICE_TOKENS, TEST_ARGS, MODULE_ARGS, includeFilters,
+                excludeFilters, mBuild);
+        List<IModuleDef> modules = mRepo.getModules(SERIAL1);
+        assertEquals("Incorrect number of modules", 1, modules.size());
+        IModuleDef module = modules.get(0);
+        assertEquals("Incorrect ID", ID_A_64, module.getId());
+        checkArgs(module);
+    }
+
+    public void testParsing() throws Exception {
+        mRepo.initialize(1, mTestsDir, ABIS, DEVICE_TOKENS, TEST_ARGS, MODULE_ARGS, INCLUDES,
+                EXCLUDES, mBuild);
+        List<IModuleDef> modules = mRepo.getModules(SERIAL3);
+        Set<String> idSet = new HashSet<>();
+        for (IModuleDef module : modules) {
+            idSet.add(module.getId());
+        }
+        assertEquals("Incorrect number of IDs", 6, idSet.size());
+        assertTrue("Missing ID_A_32", idSet.contains(ID_A_32));
+        assertTrue("Missing ID_A_64", idSet.contains(ID_A_64));
+        assertTrue("Missing ID_B_32", idSet.contains(ID_B_32));
+        assertTrue("Missing ID_B_64", idSet.contains(ID_B_64));
+        assertTrue("Missing ID_C_32", idSet.contains(ID_C_32));
+        assertTrue("Missing ID_C_64", idSet.contains(ID_C_64));
+        for (IModuleDef module : modules) {
+            checkArgs(module);
+        }
+    }
+
+    private void checkArgs(IModuleDef module) {
+        IRemoteTest test = module.getTest();
+        assertTrue("Incorrect test type", test instanceof TestStub);
+        TestStub stub = (TestStub) test;
+        assertEquals("Incorrect test arg", "bar", stub.mFoo);
+        assertEquals("Incorrect module arg", "foobar", stub.mBlah);
+    }
+
+    public void testSplit() throws Exception {
+        createConfig(mTestsDir, "sharder_1", null, SHARDABLE_TEST_STUB);
+        createConfig(mTestsDir, "sharder_2", null, SHARDABLE_TEST_STUB);
+        createConfig(mTestsDir, "sharder_3", null, SHARDABLE_TEST_STUB);
+        Set<IAbi> abis = new HashSet<>();
+        abis.add(new Abi(ABI_64, "64"));
+        ArrayList<String> emptyList = new ArrayList<>();
+
+        mRepo.initialize(3, mTestsDir, abis, DEVICE_TOKENS, emptyList, emptyList, emptyList,
+                         emptyList, mBuild);
+
+        List<IModuleDef> modules = new ArrayList<>();
+        modules.addAll(mRepo.getLargeModules());
+        modules.addAll(mRepo.getMediumModules());
+        modules.addAll(mRepo.getSmallModules());
+        modules.addAll(mRepo.getTokenModules());
+
+        int shardableCount = 0;
+        for (IModuleDef def : modules) {
+            IRemoteTest test = def.getTest();
+            if (test instanceof IShardableTest) {
+                assertNotNull("Build not set", ((ShardableTestStub)test).mBuildInfo);
+                shardableCount++;
+            }
+        }
+        assertEquals("Shards wrong", 3*3, shardableCount);
+    }
+}
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/ShardableTestStub.java b/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/ShardableTestStub.java
new file mode 100644
index 0000000..52a1aad
--- /dev/null
+++ b/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/ShardableTestStub.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.tradefed.testtype;
+
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.config.Option;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.result.ITestInvocationListener;
+import com.android.tradefed.testtype.IBuildReceiver;
+import com.android.tradefed.testtype.IRemoteTest;
+import com.android.tradefed.testtype.IShardableTest;
+
+import junit.framework.Assert;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+public class ShardableTestStub implements IRemoteTest, IShardableTest, IBuildReceiver {
+
+    @Option(name = "module")
+    String mModule;
+    @Option(name = "foo")
+    String mFoo;
+    @Option(name = "blah")
+    String mBlah;
+
+    public IBuildInfo mBuildInfo = null;
+
+    Collection<IRemoteTest> mShards;
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setBuild(IBuildInfo buildInfo) {
+        mBuildInfo = buildInfo;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    @Override
+    public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
+        // Do nothing
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Collection<IRemoteTest> split() {
+        Assert.assertNotNull(mBuildInfo);
+
+        mShards = new ArrayList<>();
+        for (int i = 0; i < 3; i++) {
+            mShards.add(new ShardableTestStub());
+        }
+        return mShards;
+    }
+}
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/TestStub.java b/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/TestStub.java
new file mode 100644
index 0000000..8a6ab69
--- /dev/null
+++ b/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/TestStub.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.tradefed.testtype;
+
+import com.android.tradefed.config.Option;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.result.ITestInvocationListener;
+import com.android.tradefed.testtype.IRemoteTest;
+
+public class TestStub implements IRemoteTest {
+
+    @Option(name = "module")
+    String mModule;
+    @Option(name = "foo")
+    String mFoo;
+    @Option(name = "blah")
+    String mBlah;
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
+        // Do nothing
+    }
+
+}
diff --git a/common/host-side/util/Android.mk b/common/host-side/util/Android.mk
new file mode 100644
index 0000000..5f5fb6f
--- /dev/null
+++ b/common/host-side/util/Android.mk
@@ -0,0 +1,31 @@
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_STATIC_JAVA_LIBRARIES := compatibility-common-util-hostsidelib jsonlib
+
+LOCAL_JAVA_LIBRARIES := json-prebuilt tradefed-prebuilt
+
+LOCAL_MODULE := compatibility-host-util
+
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_HOST_JAVA_LIBRARY)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/common/host-side/util/src/com/android/compatibility/common/util/DynamicConfigHandler.java b/common/host-side/util/src/com/android/compatibility/common/util/DynamicConfigHandler.java
new file mode 100644
index 0000000..bedcecd
--- /dev/null
+++ b/common/host-side/util/src/com/android/compatibility/common/util/DynamicConfigHandler.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.compatibility.common.util;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.json.JSONTokener;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlPullParserFactory;
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class DynamicConfigHandler {
+
+    private static final String LOG_TAG = DynamicConfigHandler.class.getSimpleName();
+
+    private static final String NS = null; //xml constant representing null namespace
+    private static final String ENCODING = "UTF-8";
+
+    public static File getMergedDynamicConfigFile(File localConfigFile, String apbsConfigJson,
+            String moduleName) throws IOException, XmlPullParserException, JSONException {
+
+        Map<String, List<String>> localConfig = DynamicConfig.createConfigMap(localConfigFile);
+        Map<String, List<String>> apbsConfig = parseJsonToConfigMap(apbsConfigJson);
+        localConfig.putAll(apbsConfig);
+        return storeMergedConfigFile(localConfig, moduleName);
+    }
+
+    private static Map<String, List<String>> parseJsonToConfigMap(String apbsConfigJson)
+            throws JSONException {
+
+        Map<String, List<String>> configMap = new HashMap<String, List<String>>();
+        if (apbsConfigJson == null) {
+            return configMap;
+        }
+
+        JSONObject rootObj  = new JSONObject(new JSONTokener(apbsConfigJson));
+        JSONArray configEntries = rootObj.getJSONArray("dynamicConfigEntries");
+        for (int i = 0; i < configEntries.length(); i++) {
+            JSONObject configEntry = configEntries.getJSONObject(i);
+            String key = configEntry.getString("configAttribute");
+            JSONArray configValues = configEntry.getJSONArray("configValues");
+            List<String> values = new ArrayList<>();
+            for (int j = 0; j < configValues.length(); j++) {
+                values.add(configValues.getString(j));
+            }
+            configMap.put(key, values);
+        }
+        return configMap;
+    }
+
+    private static File storeMergedConfigFile(Map<String, List<String>> configMap,
+            String moduleName) throws XmlPullParserException, IOException {
+
+        File folder = new File(DynamicConfig.MERGED_CONFIG_FILE_FOLDER);
+        folder.mkdirs();
+
+        File mergedConfigFile = new File(folder, moduleName + ".dynamic");
+        OutputStream stream = new FileOutputStream(mergedConfigFile);
+        XmlSerializer serializer = XmlPullParserFactory.newInstance().newSerializer();
+        serializer.setOutput(stream, ENCODING);
+        serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
+        serializer.startDocument(ENCODING, false);
+
+        serializer.startTag(NS, DynamicConfig.CONFIG_TAG);
+        for (String key : configMap.keySet()) {
+            serializer.startTag(NS, DynamicConfig.ENTRY_TAG);
+            serializer.attribute(NS, DynamicConfig.KEY_ATTR, key);
+            for (String value : configMap.get(key)) {
+                serializer.startTag(NS, DynamicConfig.VALUE_TAG);
+                serializer.text(value);
+                serializer.endTag(NS, DynamicConfig.VALUE_TAG);
+            }
+            serializer.endTag(NS, DynamicConfig.ENTRY_TAG);
+        }
+        serializer.endTag(NS, DynamicConfig.CONFIG_TAG);
+        serializer.endDocument();
+        return mergedConfigFile;
+    }
+}
diff --git a/common/host-side/util/src/com/android/compatibility/common/util/DynamicConfigHostSide.java b/common/host-side/util/src/com/android/compatibility/common/util/DynamicConfigHostSide.java
new file mode 100644
index 0000000..3e94d36
--- /dev/null
+++ b/common/host-side/util/src/com/android/compatibility/common/util/DynamicConfigHostSide.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.compatibility.common.util;
+
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * Load dynamic config for device side test cases
+ */
+public class DynamicConfigHostSide extends DynamicConfig {
+
+    private static String LOG_TAG = DynamicConfigHostSide.class.getSimpleName();
+
+    public DynamicConfigHostSide(String moduleName) throws IOException, XmlPullParserException {
+        File configFile = getConfigFile(new File(CONFIG_FOLDER_ON_HOST), moduleName);
+        initializeConfig(configFile);
+    }
+}
diff --git a/common/host-side/util/src/com/android/compatibility/common/util/HostInfoStore.java b/common/host-side/util/src/com/android/compatibility/common/util/HostInfoStore.java
new file mode 100644
index 0000000..a17f17a
--- /dev/null
+++ b/common/host-side/util/src/com/android/compatibility/common/util/HostInfoStore.java
@@ -0,0 +1,256 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.util;
+
+import com.android.json.stream.JsonWriter;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.List;
+
+public class HostInfoStore extends InfoStore {
+
+    protected File mJsonFile;
+    protected JsonWriter mJsonWriter = null;
+
+    public HostInfoStore() {
+        mJsonFile = null;
+    }
+
+    public HostInfoStore(File file) throws Exception {
+        mJsonFile = file;
+    }
+
+    /**
+     * Opens the file for storage and creates the writer.
+     */
+    @Override
+    public void open() throws IOException {
+        FileOutputStream out = new FileOutputStream(mJsonFile);
+        mJsonWriter = new JsonWriter(new OutputStreamWriter(out, StandardCharsets.UTF_8));
+        // TODO(agathaman): remove to make json output less pretty
+        mJsonWriter.setIndent("  ");
+        mJsonWriter.beginObject();
+    }
+
+    /**
+     * Closes the writer.
+     */
+    @Override
+    public void close() throws IOException {
+        mJsonWriter.endObject();
+        mJsonWriter.close();
+    }
+
+    /**
+     * Start a new group of result.
+     */
+    @Override
+    public void startGroup() throws IOException {
+        mJsonWriter.beginObject();
+    }
+
+    /**
+     * Start a new group of result with specified name.
+     */
+    @Override
+    public void startGroup(String name) throws IOException {
+        mJsonWriter.name(name);
+        mJsonWriter.beginObject();
+    }
+
+    /**
+     * Complete adding result to the last started group.
+     */
+    @Override
+    public void endGroup() throws IOException {
+        mJsonWriter.endObject();
+    }
+
+    /**
+     * Start a new array of result.
+     */
+    @Override
+    public void startArray() throws IOException {
+        mJsonWriter.beginArray();
+    }
+
+    /**
+     * Start a new array of result with specified name.
+     */
+    @Override
+    public void startArray(String name) throws IOException {
+        checkName(name);
+        mJsonWriter.name(name);
+        mJsonWriter.beginArray();
+    }
+
+    /**
+     * Complete adding result to the last started array.
+     */
+    @Override
+    public void endArray() throws IOException {
+        mJsonWriter.endArray();
+    }
+
+    /**
+     * Adds a int value to the InfoStore
+     */
+    @Override
+    public void addResult(String name, int value) throws IOException {
+        checkName(name);
+        mJsonWriter.name(name);
+        mJsonWriter.value(value);
+    }
+
+    /**
+     * Adds a long value to the InfoStore
+     */
+    @Override
+    public void addResult(String name, long value) throws IOException {
+        checkName(name);
+        mJsonWriter.name(name);
+        mJsonWriter.value(value);
+    }
+
+    /**
+     * Adds a float value to the InfoStore
+     */
+    @Override
+    public void addResult(String name, float value) throws IOException {
+        checkName(name);
+        mJsonWriter.name(name);
+        mJsonWriter.value(value);
+    }
+
+    /**
+     * Adds a double value to the InfoStore
+     */
+    @Override
+    public void addResult(String name, double value) throws IOException {
+        checkName(name);
+        mJsonWriter.name(name);
+        mJsonWriter.value(value);
+    }
+
+    /**
+     * Adds a boolean value to the InfoStore
+     */
+    @Override
+    public void addResult(String name, boolean value) throws IOException {
+        checkName(name);
+        mJsonWriter.name(name);
+        mJsonWriter.value(value);
+    }
+
+    /**
+     * Adds a String value to the InfoStore
+     */
+    @Override
+    public void addResult(String name, String value) throws IOException {
+        checkName(name);
+        mJsonWriter.name(name);
+        mJsonWriter.value(checkString(value));
+    }
+
+    /**
+     * Adds a int array to the InfoStore
+     */
+    @Override
+    public void addArrayResult(String name, int[] array) throws IOException {
+        checkName(name);
+        mJsonWriter.name(name);
+        mJsonWriter.beginArray();
+        for (int value : checkArray(array)) {
+            mJsonWriter.value(value);
+        }
+        mJsonWriter.endArray();
+    }
+
+    /**
+     * Adds a long array to the InfoStore
+     */
+    @Override
+    public void addArrayResult(String name, long[] array) throws IOException {
+        checkName(name);
+        mJsonWriter.name(name);
+        mJsonWriter.beginArray();
+        for (long value : checkArray(array)) {
+            mJsonWriter.value(value);
+        }
+        mJsonWriter.endArray();
+    }
+
+    /**
+     * Adds a float array to the InfoStore
+     */
+    @Override
+    public void addArrayResult(String name, float[] array) throws IOException {
+        checkName(name);
+        mJsonWriter.name(name);
+        mJsonWriter.beginArray();
+        for (float value : checkArray(array)) {
+            mJsonWriter.value(value);
+        }
+        mJsonWriter.endArray();
+    }
+
+    /**
+     * Adds a double array to the InfoStore
+     */
+    @Override
+    public void addArrayResult(String name, double[] array) throws IOException {
+        checkName(name);
+        mJsonWriter.name(name);
+        mJsonWriter.beginArray();
+        for (double value : checkArray(array)) {
+            mJsonWriter.value(value);
+        }
+        mJsonWriter.endArray();
+    }
+
+    /**
+     * Adds a boolean array to the InfoStore
+     */
+    @Override
+    public void addArrayResult(String name, boolean[] array) throws IOException {
+        checkName(name);
+        mJsonWriter.name(name);
+        mJsonWriter.beginArray();
+        for (boolean value : checkArray(array)) {
+            mJsonWriter.value(value);
+        }
+        mJsonWriter.endArray();
+    }
+
+    /**
+     * Adds a List of String to the InfoStore
+     */
+    @Override
+    public void addListResult(String name, List<String> list) throws IOException {
+        checkName(name);
+        mJsonWriter.name(name);
+        mJsonWriter.beginArray();
+        for (String value : checkStringList(list)) {
+            mJsonWriter.value(checkString(value));
+        }
+        mJsonWriter.endArray();
+    }
+}
diff --git a/common/host-side/util/src/com/android/compatibility/common/util/MetricsReportLog.java b/common/host-side/util/src/com/android/compatibility/common/util/MetricsReportLog.java
new file mode 100644
index 0000000..e590b91
--- /dev/null
+++ b/common/host-side/util/src/com/android/compatibility/common/util/MetricsReportLog.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.compatibility.common.util;
+
+import com.android.tradefed.util.FileUtil;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * A {@link ReportLog} that can be used with the in memory metrics store used for host side metrics.
+ */
+public final class MetricsReportLog extends ReportLog {
+    private final String mDeviceSerial;
+    private final String mAbi;
+    private final String mClassMethodName;
+
+    // TODO(mishragaurav): Remove default names and constructor after fixing b/27950009.
+    private static final String DEFAULT_REPORT_LOG_NAME = "DefaultHostTestMetrics";
+    private static final String DEFAULT_STREAM_NAME = "DefaultStream";
+    // Temporary folder must match the temp-dir value configured in ReportLogCollector target
+    // preparer in cts/tools/cts-tradefed/res/config/cts-oreconditions.xml
+    private static final String TEMPORARY_REPORT_FOLDER = "temp-report-logs/";
+    private ReportLogHostInfoStore store;
+
+    /**
+     * @param deviceSerial serial number of the device
+     * @param abi abi the test was run on
+     * @param classMethodName class name and method name of the test in class#method format.
+     *        Note that ReportLog.getClassMethodNames() provide this.
+     */
+    public MetricsReportLog(String deviceSerial, String abi, String classMethodName) {
+        this(deviceSerial, abi, classMethodName, DEFAULT_REPORT_LOG_NAME, DEFAULT_STREAM_NAME);
+    }
+
+    public MetricsReportLog(String deviceSerial, String abi, String classMethodName,
+            String reportLogName) {
+        this(deviceSerial, abi, classMethodName, reportLogName, DEFAULT_STREAM_NAME);
+    }
+
+    public MetricsReportLog(String deviceSerial, String abi, String classMethodName,
+            String reportLogName, String streamName) {
+        super(reportLogName, streamName);
+        mDeviceSerial = deviceSerial;
+        mAbi = abi;
+        mClassMethodName = classMethodName;
+        try {
+            final File dir = FileUtil.createNamedTempDir(TEMPORARY_REPORT_FOLDER);
+            File jsonFile = new File(dir, mReportLogName + ".reportlog.json");
+            store = new ReportLogHostInfoStore(jsonFile, mStreamName);
+            store.open();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    @Override
+    public void addValue(String source, String message, double value, ResultType type,
+            ResultUnit unit) {
+        super.addValue(source, message, value, type, unit);
+        try {
+            store.addResult(message, value);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    @Override
+    public void addValue(String message, double value, ResultType type, ResultUnit unit) {
+        super.addValue(message, value, type, unit);
+        try {
+            store.addResult(message, value);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+
+    }
+
+    public void submit() {
+        try {
+            store.close();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        MetricsStore.storeResult(mDeviceSerial, mAbi, mClassMethodName, this);
+    }
+}
diff --git a/common/host-side/util/src/com/android/compatibility/common/util/MetricsStore.java b/common/host-side/util/src/com/android/compatibility/common/util/MetricsStore.java
new file mode 100644
index 0000000..efe7182
--- /dev/null
+++ b/common/host-side/util/src/com/android/compatibility/common/util/MetricsStore.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.compatibility.common.util;
+
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * A simple in-memory store for metrics results. This should be used for hostside metrics reporting.
+ */
+public class MetricsStore {
+
+    // needs concurrent version as there can be multiple client accessing this.
+    // But there is no additional protection for the same key as that should not happen.
+    private static final ConcurrentHashMap<String, ReportLog> mMap =
+            new ConcurrentHashMap<String, ReportLog>();
+
+    private MetricsStore() {}
+
+    /**
+     * Stores a result. Existing result with the same key will be replaced.
+     * Note that key is generated in the form of device_serial#class#method name.
+     * So there should be no concurrent test for the same (serial, class, method).
+     * @param deviceSerial
+     * @param abi
+     * @param classMethodName
+     * @param reportLog Contains the result to be stored
+     */
+    public static void storeResult(
+            String deviceSerial, String abi, String classMethodName, ReportLog reportLog) {
+        mMap.put(generateTestKey(deviceSerial, abi, classMethodName), reportLog);
+    }
+
+    /**
+     * retrieves a metric result for the given condition and remove it from the internal
+     * storage. If there is no result for the given condition, it will return null.
+     */
+    public static ReportLog removeResult(String deviceSerial, String abi, String classMethodName) {
+        return mMap.remove(generateTestKey(deviceSerial, abi, classMethodName));
+    }
+
+    /**
+     * @return test key in the form of device_serial#abi#class_name#method_name
+     */
+    private static String generateTestKey(String deviceSerial, String abi, String classMethodName) {
+        return String.format("%s#%s#%s", deviceSerial, abi, classMethodName);
+    }
+}
diff --git a/common/host-side/util/src/com/android/compatibility/common/util/MonitoringUtils.java b/common/host-side/util/src/com/android/compatibility/common/util/MonitoringUtils.java
new file mode 100644
index 0000000..e33c7e5a
--- /dev/null
+++ b/common/host-side/util/src/com/android/compatibility/common/util/MonitoringUtils.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.compatibility.common.util;
+
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.log.LogUtil.CLog;
+import com.android.tradefed.result.ITestInvocationListener;
+import com.android.tradefed.result.InputStreamSource;
+import com.android.tradefed.result.LogDataType;
+
+/**
+ * Utility functions related to device state monitoring during compatibility test.
+ */
+public class MonitoringUtils {
+
+    private static final long CONNECTIVITY_CHECK_TIME_MS = 60 * 1000;
+    private static final long CONNECTIVITY_CHECK_INTERVAL_MS = 5 * 1000;
+
+    public static void checkDeviceConnectivity(ITestDevice device, ITestInvocationListener listener,
+            String tag) throws DeviceNotAvailableException {
+            long start = System.currentTimeMillis();
+            while (System.currentTimeMillis() - start < CONNECTIVITY_CHECK_TIME_MS) {
+                if (device.checkConnectivity()) {
+                    CLog.i("Connectivity: passed check.");
+                    return;
+                } else {
+                    try {
+                        Thread.sleep(CONNECTIVITY_CHECK_INTERVAL_MS);
+                    } catch (InterruptedException ie) {
+                        return;
+                    }
+                }
+            }
+            CLog.w("Connectivity: check failed.");
+            InputStreamSource bugSource = device.getBugreport();
+            listener.testLog(String.format("bugreport-connectivity-%s", tag),
+                    LogDataType.TEXT, bugSource);
+            bugSource.cancel();
+        }
+
+}
diff --git a/common/host-side/util/src/com/android/compatibility/common/util/ReportLogHostInfoStore.java b/common/host-side/util/src/com/android/compatibility/common/util/ReportLogHostInfoStore.java
new file mode 100644
index 0000000..65114d9
--- /dev/null
+++ b/common/host-side/util/src/com/android/compatibility/common/util/ReportLogHostInfoStore.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.util;
+
+import com.android.json.stream.JsonWriter;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+
+public class ReportLogHostInfoStore extends HostInfoStore {
+
+    private final String mStreamName;
+
+    public ReportLogHostInfoStore(File jsonFile, String streamName) throws Exception {
+        mJsonFile = jsonFile;
+        mStreamName = streamName;
+    }
+
+    /**
+     * Creates the writer and starts the JSON Object for the metric stream.
+     */
+    @Override
+    public void open() throws IOException {
+        BufferedWriter formatWriter;
+        String oldMetrics;
+        if (mJsonFile.exists()) {
+            BufferedReader jsonReader = new BufferedReader(new FileReader(mJsonFile));
+            StringBuilder oldMetricsBuilder = new StringBuilder();
+            String line;
+            while ((line = jsonReader.readLine()) != null) {
+                oldMetricsBuilder.append(line);
+            }
+            oldMetrics = oldMetricsBuilder.toString().trim();
+            if (oldMetrics.charAt(oldMetrics.length() - 1) == '}') {
+                oldMetrics = oldMetrics.substring(0, oldMetrics.length() - 1);
+            }
+            oldMetrics = oldMetrics + ",";
+        } else {
+            oldMetrics = "{";
+        }
+        mJsonFile.createNewFile();
+        formatWriter = new BufferedWriter(new FileWriter(mJsonFile));
+        formatWriter.write(oldMetrics + "\"" + mStreamName + "\":", 0, oldMetrics.length() +
+                mStreamName.length() + 3);
+        formatWriter.flush();
+        formatWriter.close();
+        mJsonWriter = new JsonWriter(new FileWriter(mJsonFile, true));
+        mJsonWriter.beginObject();
+    }
+
+    /**
+     * Closes the writer.
+     */
+    @Override
+    public void close() throws IOException {
+        mJsonWriter.endObject();
+        mJsonWriter.close();
+        // Close the overall JSON object
+        BufferedWriter formatWriter = new BufferedWriter(new FileWriter(mJsonFile, true));
+        formatWriter.write("}", 0, 1);
+        formatWriter.flush();
+        formatWriter.close();
+    }
+}
diff --git a/common/host-side/util/src/com/android/compatibility/common/util/VersionCodes.java b/common/host-side/util/src/com/android/compatibility/common/util/VersionCodes.java
new file mode 100644
index 0000000..7611b2f
--- /dev/null
+++ b/common/host-side/util/src/com/android/compatibility/common/util/VersionCodes.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.util;
+
+public class VersionCodes {
+    public static final int CUR_DEVELOPMENT = 10000;
+    public static final int BASE = 1;
+    public static final int BASE_1_1 = 2;
+    public static final int CUPCAKE = 3;
+    public static final int DONUT = 4;
+    public static final int ECLAIR = 5;
+    public static final int ECLAIR_0_1 = 6;
+    public static final int ECLAIR_MR1 = 7;
+    public static final int FROYO = 8;
+    public static final int GINGERBREAD = 9;
+    public static final int GINGERBREAD_MR1 = 10;
+    public static final int HONEYCOMB = 11;
+    public static final int HONEYCOMB_MR1 = 12;
+    public static final int HONEYCOMB_MR2 = 13;
+    public static final int ICE_CREAM_SANDWICH = 14;
+    public static final int ICE_CREAM_SANDWICH_MR1 = 15;
+    public static final int JELLY_BEAN = 16;
+    public static final int JELLY_BEAN_MR1 = 17;
+    public static final int JELLY_BEAN_MR2 = 18;
+    public static final int KITKAT = 19;
+    public static final int KITKAT_WATCH = 20;
+    public static final int LOLLIPOP = 21;
+    public static final int LOLLIPOP_MR1 = 22;
+    public static final int M = 23;
+    public static final int N = CUR_DEVELOPMENT;
+}
diff --git a/common/host-side/util/tests/Android.mk b/common/host-side/util/tests/Android.mk
new file mode 100644
index 0000000..a0e9a3b
--- /dev/null
+++ b/common/host-side/util/tests/Android.mk
@@ -0,0 +1,27 @@
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_JAVA_LIBRARIES := compatibility-host-util junit json-prebuilt
+
+LOCAL_MODULE := compatibility-host-util-tests
+
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_HOST_JAVA_LIBRARY)
\ No newline at end of file
diff --git a/common/host-side/util/tests/run_tests.sh b/common/host-side/util/tests/run_tests.sh
new file mode 100755
index 0000000..d4513f9
--- /dev/null
+++ b/common/host-side/util/tests/run_tests.sh
@@ -0,0 +1,31 @@
+#!/bin/bash
+
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Helper script for running unit tests for compatibility libraries
+
+CTS_DIR=$(dirname ${0})/../../../..
+source ${CTS_DIR}/test_defs.sh
+
+JARS="
+    compatibility-common-util-hostsidelib\
+    compatibility-common-util-tests\
+    compatibility-host-util\
+    compatibility-host-util-tests\
+    compatibility-mock-tradefed\
+    compatibility-tradefed-tests"
+
+run_tests "com.android.compatibility.common.util.HostUnitTests" "${JARS}" "${@}"
+
diff --git a/common/host-side/util/tests/src/com/android/compatibility/common/util/DynamicConfigHandlerTest.java b/common/host-side/util/tests/src/com/android/compatibility/common/util/DynamicConfigHandlerTest.java
new file mode 100644
index 0000000..ad0ad9f
--- /dev/null
+++ b/common/host-side/util/tests/src/com/android/compatibility/common/util/DynamicConfigHandlerTest.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.compatibility.common.util;
+
+import junit.framework.TestCase;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Unit tests for {@link DynamicConfigHandler}
+ */
+public class DynamicConfigHandlerTest extends TestCase {
+
+    private static final String localConfig =
+            "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
+            "<dynamicConfig>\n" +
+            "    <entry key=\"test-config-1\">\n" +
+            "        <value>test config 1</value>\n" +
+            "    </entry>\n" +
+            "    <entry key=\"test-config-2\">\n" +
+            "        <value>test config 2</value>\n" +
+            "    </entry>\n" +
+            "    <entry key=\"override-config-2\">\n" +
+            "        <value>test config 3</value>\n" +
+            "    </entry>\n" +
+            "    <entry key=\"config-list\">\n" +
+            "        <value>config0</value>\n" +
+            "        <value>config1</value>\n" +
+            "        <value>config2</value>\n" +
+            "        <value>config3</value>\n" +
+            "        <value>config4</value>\n" +
+            "    </entry>\n" +
+            "    <entry key=\"override-config-list-2\">\n" +
+            "        <value>A</value>\n" +
+            "        <value>B</value>\n" +
+            "        <value>C</value>\n" +
+            "        <value>D</value>\n" +
+            "        <value>E</value>\n" +
+            "    </entry>\n" +
+            "</dynamicConfig>\n";
+
+    private static final String overrideJson =
+            "{\n" +
+            "  \"dynamicConfigEntries\": [\n" +
+            "    {\n" +
+            "      \"configAttribute\": \"version\",\n" +
+            "      \"configValues\": [\n" +
+            "        \"1.0\"\n" +
+            "      ]\n" +
+            "    },\n" +
+            "    {\n" +
+            "      \"configAttribute\": \"suite\",\n" +
+            "      \"configValues\": [\n" +
+            "        \"CTS_V2\"\n" +
+            "      ]\n" +
+            "    },\n" +
+            "    {\n" +
+            "      \"configAttribute\": \"override-config-1\",\n" +
+            "      \"configValues\": [\n" +
+            "        \"override-config-val-1\"\n" +
+            "      ]\n" +
+            "    },\n" +
+            "    {\n" +
+            "      \"configAttribute\": \"override-config-2\",\n" +
+            "      \"configValues\": [\n" +
+            "        \"override-config-val-2\"\n" +
+            "      ]\n" +
+            "    },\n" +
+            "    {\n" +
+            "      \"configAttribute\": \"override-config-list-1\",\n" +
+            "      \"configValues\": [\n" +
+            "        \"override-config-list-val-1-1\",\n" +
+            "        \"override-config-list-val-1-2\"\n" +
+            "      ]\n" +
+            "    },\n" +
+            "    {\n" +
+            "      \"configAttribute\": \"override-config-list-2\",\n" +
+            "      \"configValues\": [\n" +
+            "        \"override-config-list-val-2-1\"\n" +
+            "      ]\n" +
+            "    },\n" +
+            "    {\n" +
+            "      \"configAttribute\": \"override-config-list-3\",\n" +
+            "      \"configValues\": [\n" +
+            "      ]\n" +
+            "    }\n" +
+            "  ]\n" +
+            "}";
+
+    public void testDynamicConfigHandler() throws Exception {
+        String module = "test1";
+        File localConfigFile = createFileFromStr(localConfig, module);
+
+        File mergedFile = DynamicConfigHandler
+                .getMergedDynamicConfigFile(localConfigFile, overrideJson, module);
+
+        Map<String, List<String>> configMap = DynamicConfig.createConfigMap(mergedFile);
+
+        assertEquals("override-config-val-1", configMap.get("override-config-1").get(0));
+        assertTrue(configMap.get("override-config-list-1")
+                .contains("override-config-list-val-1-1"));
+        assertTrue(configMap.get("override-config-list-1")
+                .contains("override-config-list-val-1-2"));
+        assertTrue(configMap.get("override-config-list-3").size() == 0);
+
+        assertEquals("test config 1", configMap.get("test-config-1").get(0));
+        assertTrue(configMap.get("config-list").contains("config2"));
+
+        assertEquals("override-config-val-2", configMap.get("override-config-2").get(0));
+        assertEquals(1, configMap.get("override-config-list-2").size());
+        assertTrue(configMap.get("override-config-list-2")
+                .contains("override-config-list-val-2-1"));
+    }
+
+
+    private File createFileFromStr(String configStr, String module) throws IOException {
+        File file = File.createTempFile(module, "dynamic");
+        FileOutputStream stream = null;
+        try {
+            stream = new FileOutputStream(file);
+            stream.write(configStr.getBytes());
+            stream.flush();
+        } finally {
+            if (stream != null) {
+                stream.close();
+            }
+        }
+        return file;
+    }
+}
diff --git a/common/host-side/util/tests/src/com/android/compatibility/common/util/HostUnitTests.java b/common/host-side/util/tests/src/com/android/compatibility/common/util/HostUnitTests.java
new file mode 100644
index 0000000..8cf1e3f
--- /dev/null
+++ b/common/host-side/util/tests/src/com/android/compatibility/common/util/HostUnitTests.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.util;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * A test suite for all host util unit tests.
+ * <p/>
+ * All tests listed here should be self-contained, and do not require any external dependencies.
+ */
+public class HostUnitTests extends TestSuite {
+
+    public HostUnitTests() {
+        super();
+        addTestSuite(DynamicConfigHandlerTest.class);
+        addTestSuite(MetricsStoreTest.class);
+    }
+
+    public static Test suite() {
+        return new HostUnitTests();
+    }
+}
\ No newline at end of file
diff --git a/common/util/tests/src/com/android/compatibility/common/util/MetricsStoreTest.java b/common/host-side/util/tests/src/com/android/compatibility/common/util/MetricsStoreTest.java
similarity index 100%
rename from common/util/tests/src/com/android/compatibility/common/util/MetricsStoreTest.java
rename to common/host-side/util/tests/src/com/android/compatibility/common/util/MetricsStoreTest.java
diff --git a/common/host-side/xml-plan-generator/Android.mk b/common/host-side/xml-plan-generator/Android.mk
deleted file mode 100644
index 53718e5..0000000
--- a/common/host-side/xml-plan-generator/Android.mk
+++ /dev/null
@@ -1,49 +0,0 @@
-# Copyright (C) 2014 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_JAVA_LIBRARIES := compatibility-common-util-hostsidelib_v2
-
-LOCAL_STATIC_JAVA_LIBRARIES := vogarexpectlib
-
-LOCAL_JAR_MANIFEST := MANIFEST.mf
-
-LOCAL_CLASSPATH := $(HOST_JDK_TOOLS_JAR)
-
-LOCAL_MODULE := compatibility-xml-plan-generator_v2
-
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_HOST_JAVA_LIBRARY)
-
-###############################################################################
-# Build the tests
-###############################################################################
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under, tests/src)
-
-LOCAL_JAVA_LIBRARIES := compatibility-tradefed_v2 compatibility-xml-plan-generator_v2 junit
-
-LOCAL_MODULE := compatibility-xml-plan-generator-tests_v2
-
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/common/host-side/xml-plan-generator/MANIFEST.mf b/common/host-side/xml-plan-generator/MANIFEST.mf
deleted file mode 100644
index 95aee0d..0000000
--- a/common/host-side/xml-plan-generator/MANIFEST.mf
+++ /dev/null
@@ -1,3 +0,0 @@
-Manifest-Version: 1.0
-Main-Class: com.android.compatibility.common.xmlgenerator.XmlPlanGenerator
-Class-Path: compatibility-common-util-hostsidelib_v2.jar
diff --git a/common/host-side/xml-plan-generator/src/com/android/compatibility/common/xmlgenerator/Test.java b/common/host-side/xml-plan-generator/src/com/android/compatibility/common/xmlgenerator/Test.java
deleted file mode 100644
index d3e1d88..0000000
--- a/common/host-side/xml-plan-generator/src/com/android/compatibility/common/xmlgenerator/Test.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.compatibility.common.xmlgenerator;
-
-public class Test {
-
-    private final String mName;
-
-    public Test(String name) {
-        mName = name;
-    }
-
-    public String getName() {
-        return mName;
-    }
-}
diff --git a/common/host-side/xml-plan-generator/src/com/android/compatibility/common/xmlgenerator/TestCase.java b/common/host-side/xml-plan-generator/src/com/android/compatibility/common/xmlgenerator/TestCase.java
deleted file mode 100644
index 65b4aa3..0000000
--- a/common/host-side/xml-plan-generator/src/com/android/compatibility/common/xmlgenerator/TestCase.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.compatibility.common.xmlgenerator;
-
-import java.util.ArrayList;
-
-public class TestCase {
-
-    private final String mName;
-    private final ArrayList<Test> mTests = new ArrayList<Test>();
-
-    public TestCase(String name) {
-        mName = name;
-    }
-
-    public void addTest(Test test) {
-        mTests.add(test);
-    }
-
-    public String getName() {
-        return mName;
-    }
-
-    public ArrayList<Test> getTests() {
-        return mTests;
-    }
-}
diff --git a/common/host-side/xml-plan-generator/src/com/android/compatibility/common/xmlgenerator/TestListParser.java b/common/host-side/xml-plan-generator/src/com/android/compatibility/common/xmlgenerator/TestListParser.java
deleted file mode 100644
index 6880440..0000000
--- a/common/host-side/xml-plan-generator/src/com/android/compatibility/common/xmlgenerator/TestListParser.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.compatibility.common.xmlgenerator;
-
-import java.io.InputStream;
-import java.util.HashMap;
-import java.util.Scanner;
-
-/**
- * Parser of test lists in the form;
- *
- * suite:android.sample
- * case:SampleTest
- * test:testA
- * test:testB
- * suite:android.sample.ui
- * case:SampleUiTest
- * test:testA
- * test:testB
- */
-public class TestListParser {
-
-    private TestListParser() {}
-
-    public static HashMap<String, TestSuite> parse(InputStream input) {
-        final HashMap<String, TestSuite> suites = new HashMap<String, TestSuite>();
-        TestSuite currentSuite = null;
-        TestCase currentCase = null;
-        Scanner in = null;
-        try {
-            in = new Scanner(input);
-            while (in.hasNextLine()) {
-                final String line = in.nextLine();
-                final String[] parts = line.split(":");
-                if (parts.length != 2) {
-                    throw new RuntimeException("Invalid Format: " + line);
-                }
-                final String key = parts[0];
-                final String value = parts[1];
-                if (currentSuite == null) {
-                    if (!"suite".equals(key)) {
-                        throw new RuntimeException("TestSuite Expected");
-                    }
-                    final String[] names = value.split("\\.");
-                    for (int i = 0; i < names.length; i++) {
-                        final String name = names[i];
-                        if (currentSuite != null) {
-                            if (currentSuite.hasTestSuite(name)) {
-                                currentSuite = currentSuite.getTestSuite(name);
-                            } else {
-                                final TestSuite newSuite = new TestSuite(name);
-                                currentSuite.addTestSuite(newSuite);
-                                currentSuite = newSuite;
-                            }
-                        } else if (suites.containsKey(name)) {
-                            currentSuite = suites.get(name);
-                        } else {
-                            currentSuite = new TestSuite(name);
-                            suites.put(name, currentSuite);
-                        }
-                    }
-                } else if (currentCase == null) {
-                    if (!"case".equals(key)) {
-                        throw new RuntimeException("TestCase Expected");
-                    }
-                    currentCase = new TestCase(value);
-                    currentSuite.addTestCase(currentCase);
-                } else {
-                    if (!"test".equals(key)) {
-                        throw new RuntimeException("Test Expected");
-                    }
-                    currentCase.addTest(new Test(value));
-                }
-            }
-        } finally {
-            if (in != null) {
-                in.close();
-            }
-        }
-        return suites;
-    }
-}
diff --git a/common/host-side/xml-plan-generator/src/com/android/compatibility/common/xmlgenerator/TestSuite.java b/common/host-side/xml-plan-generator/src/com/android/compatibility/common/xmlgenerator/TestSuite.java
deleted file mode 100644
index db4fd07c..0000000
--- a/common/host-side/xml-plan-generator/src/com/android/compatibility/common/xmlgenerator/TestSuite.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.compatibility.common.xmlgenerator;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-
-public class TestSuite {
-
-    private final String mName;
-    private final HashMap<String, TestSuite> mTestSuites = new HashMap<String, TestSuite>();
-    private final ArrayList<TestCase> mTestCases = new ArrayList<TestCase>();
-
-    public TestSuite(String name) {
-        mName = name;
-    }
-
-    public boolean hasTestSuite(String name) {
-        return mTestSuites.containsKey(name);
-    }
-
-    public TestSuite getTestSuite(String name) {
-        return mTestSuites.get(name);
-    }
-
-    public void addTestSuite(TestSuite testSuite) {
-        mTestSuites.put(testSuite.getName(), testSuite);
-    }
-
-    public void addTestCase(TestCase testCase) {
-        mTestCases.add(testCase);
-    }
-
-    public String getName() {
-        return mName;
-    }
-
-    public HashMap<String, TestSuite> getTestSuites() {
-        return mTestSuites;
-    }
-
-    public ArrayList<TestCase> getTestCases() {
-        return mTestCases;
-    }
-}
diff --git a/common/host-side/xml-plan-generator/src/com/android/compatibility/common/xmlgenerator/XmlPlanGenerator.java b/common/host-side/xml-plan-generator/src/com/android/compatibility/common/xmlgenerator/XmlPlanGenerator.java
deleted file mode 100644
index efb53d5..0000000
--- a/common/host-side/xml-plan-generator/src/com/android/compatibility/common/xmlgenerator/XmlPlanGenerator.java
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.compatibility.common.xmlgenerator;
-
-import com.android.compatibility.common.util.KeyValueArgsParser;
-
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.NodeList;
-
-import vogar.ExpectationStore;
-import vogar.ModeId;
-import vogar.Result;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-
-import javax.xml.parsers.DocumentBuilderFactory;
-
-/**
- * Passes the scanner output and outputs an xml description of the tests.
- */
-public class XmlPlanGenerator {
-
-    private final ExpectationStore mExpectations;
-    private final String mAppNameSpace;
-    private final String mAppPackageName;
-    private final String mName;
-    private final String mRunner;
-    private final String mTargetBinaryName;
-    private final String mTargetNameSpace;
-    private final String mJarPath;
-    private final String mTestType;
-    private final String mOutput;
-
-    private XmlPlanGenerator(ExpectationStore expectations, String appNameSpace,
-            String appPackageName, String name, String runner, String targetBinaryName,
-            String targetNameSpace, String jarPath, String testType, String output) {
-        mExpectations = expectations;
-        mAppNameSpace = appNameSpace;
-        mAppPackageName = appPackageName;
-        mName = name;
-        mRunner = runner;
-        mTargetBinaryName = targetBinaryName;
-        mTargetNameSpace = targetNameSpace;
-        mJarPath = jarPath;
-        mTestType = testType;
-        mOutput = output;
-    }
-
-    private void writePackageXml() throws IOException {
-        OutputStream out = System.out;
-        if (mOutput != null) {
-            out = new FileOutputStream(mOutput);
-        }
-        PrintWriter writer = null;
-        try {
-            writer = new PrintWriter(out);
-            writer.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
-            writeTestPackage(writer);
-        } finally {
-            if (writer != null) {
-                writer.close();
-            }
-        }
-    }
-
-    private void writeTestPackage(PrintWriter writer) {
-        writer.append("<TestPackage");
-        if (mAppNameSpace != null) {
-            writer.append(" appNameSpace=\"").append(mAppNameSpace).append("\"");
-        }
-
-        writer.append(" appPackageName=\"").append(mAppPackageName).append("\"");
-        writer.append(" name=\"").append(mName).append("\"");
-
-        if (mRunner != null) {
-            writer.append(" runner=\"").append(mRunner).append("\"");
-        }
-
-        if (mAppNameSpace != null && mTargetNameSpace != null
-                && !mAppNameSpace.equals(mTargetNameSpace)) {
-            writer.append(" targetBinaryName=\"").append(mTargetBinaryName).append("\"");
-            writer.append(" targetNameSpace=\"").append(mTargetNameSpace).append("\"");
-        }
-
-        if (mTestType != null && !mTestType.isEmpty()) {
-            writer.append(" testType=\"").append(mTestType).append("\"");
-        }
-
-        if (mJarPath != null) {
-            writer.append(" jarPath=\"").append(mJarPath).append("\"");
-        }
-
-        writer.println(" version=\"1.0\">");
-
-        final HashMap<String, TestSuite> suites = TestListParser.parse(System.in);
-        if (suites.isEmpty()) {
-            throw new RuntimeException("No TestSuites Found");
-        }
-        writeTestSuites(writer, suites, "");
-        writer.println("</TestPackage>");
-    }
-
-    private void writeTestSuites(PrintWriter writer, HashMap<String, TestSuite> suites, String name) {
-        for (String suiteName : suites.keySet()) {
-            final TestSuite suite = suites.get(suiteName);
-            writer.append("<TestSuite name=\"").append(suiteName).println("\">");
-            final String fullname = name + suiteName + ".";
-            writeTestSuites(writer, suite.getTestSuites(), fullname);
-            writeTestCases(writer, suite.getTestCases(), fullname);
-            writer.println("</TestSuite>");
-        }
-    }
-
-    private void writeTestCases(PrintWriter writer, ArrayList<TestCase> cases, String name) {
-        for (TestCase testCase : cases) {
-            final String caseName = testCase.getName();
-            writer.append("<TestCase name=\"").append(caseName).println("\">");
-            final String fullname = name + caseName;
-            writeTests(writer, testCase.getTests(), fullname);
-            writer.println("</TestCase>");
-        }
-    }
-
-    private void writeTests(PrintWriter writer, ArrayList<Test> tests, String name) {
-        if (tests.isEmpty()) {
-            throw new RuntimeException("No Tests Found");
-        }
-        for (Test test : tests) {
-            final String testName = test.getName();
-            writer.append("<Test name=\"").append(testName).append("\"");
-            final String fullname = name + "#" + testName;
-            if (isKnownFailure(mExpectations, fullname)) {
-                writer.append(" expectation=\"failure\"");
-            }
-            writer.println(" />");
-        }
-    }
-
-    public static boolean isKnownFailure(ExpectationStore store, String fullname) {
-        return store != null && store.get(fullname).getResult() != Result.SUCCESS;
-    }
-
-    public static void main(String[] args) throws Exception {
-        final HashMap<String, String> argsMap = KeyValueArgsParser.parse(args);
-        final String packageName = argsMap.get("-p");
-        final String name = argsMap.get("-n");
-        final String testType = argsMap.get("-t");
-        final String jarPath = argsMap.get("-j");
-        final String instrumentation = argsMap.get("-i");
-        final String manifest = argsMap.get("-m");
-        final String expectations = argsMap.get("-e");
-        final String output = argsMap.get("-o");
-        String appNameSpace = argsMap.get("-a");
-        String targetNameSpace = argsMap.get("-r");
-        if (packageName == null || name == null) {
-            usage(args);
-        }
-        String runner = null;
-        if (manifest != null) {
-            Document m = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(manifest);
-            Element elem = m.getDocumentElement();
-            appNameSpace = elem.getAttribute("package");
-            runner = getElementAttribute(elem, "instrumentation", "android:name");
-            targetNameSpace = getElementAttribute(elem, "instrumentation", "android:targetPackage");
-        }
-
-        final HashSet<File> expectationFiles = new HashSet<File>();
-        if (expectations != null) {
-            expectationFiles.add(new File(expectations));
-        }
-        final ExpectationStore store = ExpectationStore.parse(expectationFiles, ModeId.DEVICE);
-        XmlPlanGenerator generator = new XmlPlanGenerator(store, appNameSpace, packageName, name,
-            runner, instrumentation, targetNameSpace, jarPath, testType, output);
-        generator.writePackageXml();
-    }
-
-    private static String getElementAttribute(Element parent, String elem, String name) {
-        NodeList nodeList = parent.getElementsByTagName(elem);
-        if (nodeList.getLength() > 0) {
-             Element element = (Element) nodeList.item(0);
-             return element.getAttribute(name);
-        }
-        return null;
-    }
-
-    private static void usage(String[] args) {
-        System.err.println("Arguments: " + Arrays.toString(args));
-        System.err.println("Usage: compatibility-xml-plan-generator -p PACKAGE_NAME -n NAME" +
-            "[-t TEST_TYPE] [-j JAR_PATH] [-i INSTRUMENTATION] [-m MANIFEST] [-e EXPECTATIONS]" +
-            "[-o OUTPUT]");
-        System.exit(1);
-    }
-}
diff --git a/common/host-side/xml-plan-generator/tests/src/com/android/compatibility/common/xmlgenerator/XmlPlanGeneratorTest.java b/common/host-side/xml-plan-generator/tests/src/com/android/compatibility/common/xmlgenerator/XmlPlanGeneratorTest.java
deleted file mode 100644
index 082af17..0000000
--- a/common/host-side/xml-plan-generator/tests/src/com/android/compatibility/common/xmlgenerator/XmlPlanGeneratorTest.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.compatibility.common.xmlgenerator;
-
-import junit.framework.TestCase;
-
-import java.io.ByteArrayInputStream;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Scanner;
-
-public class XmlPlanGeneratorTest extends TestCase {
-
-    private static final String JAR = "out/host/linux-x86/framework/compatibility-xml-plan-generator_v2.jar";
-    private static final String PACKAGE_NAME = "com.android.test";
-    private static final String NAME = "ValidTest";
-    private static final String VALID_RESULT =
-        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
-        "<TestPackage appPackageName=\"com.android.test\" name=\"ValidTest\" version=\"1.0\">" +
-        "<TestSuite name=\"com\">" +
-        "<TestSuite name=\"android\">" +
-        "<TestSuite name=\"test\">" +
-        "<TestCase name=\"ValidTest\">" +
-        "<Test name=\"testA\" />" +
-        "</TestCase>" +
-        "</TestSuite>" +
-        "</TestSuite>" +
-        "</TestSuite>" +
-        "</TestPackage>";
-
-    private static final String VALID =
-        "suite:com.android.test\n" +
-        "case:ValidTest\n" +
-        "test:testA\n";
-
-    private static final String INVALID_A = "";
-
-    private static final String INVALID_B =
-        "suite:com.android.test\n" +
-        "case:InvalidTest\n";
-
-    private static final String INVALID_C =
-        "uh oh";
-
-    private static final String INVALID_D =
-        "test:testA\n" +
-        "case:InvalidTest\n" +
-        "suite:com.android.test\n";
-
-    private static final String INVALID_E =
-        "suite:com.android.test\n" +
-        "test:testA\n" +
-        "case:InvalidTest\n";
-
-    public void testValid() throws Exception {
-        assertEquals(VALID_RESULT, runGenerator(VALID));
-    }
-
-    public void testInvalidA() throws Exception {
-        assertNull(runGenerator(INVALID_A));
-    }
-
-    public void testInvalidB() throws Exception {
-        assertNull(runGenerator(INVALID_B));
-    }
-
-    public void testTestListParserInvalidFormat() throws Exception {
-        runTestListParser(INVALID_C);
-    }
-
-    public void testTestListParserSuiteExpected() throws Exception {
-        runTestListParser(INVALID_D);
-    }
-
-    public void testTestListParserCaseExpected() throws Exception {
-        runTestListParser(INVALID_E);
-    }
-
-    private static String runGenerator(String input) throws Exception {
-        ArrayList<String> args = new ArrayList<String>();
-        args.add("java");
-        args.add("-jar");
-        args.add(JAR);
-        args.add("-p");
-        args.add(PACKAGE_NAME);
-        args.add("-n");
-        args.add(NAME);
-
-        final Process p = new ProcessBuilder(args).start();
-        final PrintWriter out = new PrintWriter(p.getOutputStream());
-        out.print(input);
-        out.flush();
-        out.close();
-        final StringBuilder output = new StringBuilder();
-        final Scanner in = new Scanner(p.getInputStream());
-        while (in.hasNextLine()) {
-            output.append(in.nextLine());
-        }
-        int ret = p.waitFor();
-        if (ret == 0) {
-            return output.toString();
-        }
-        return null;
-    }
-
-    private static void runTestListParser(String input) throws Exception {
-        try {
-            final ByteArrayInputStream in = new ByteArrayInputStream(input.getBytes());
-            final HashMap<String, TestSuite> suites = TestListParser.parse(in);
-            fail();
-        } catch (RuntimeException e) {}
-    }
-}
diff --git a/common/util/Android.mk b/common/util/Android.mk
index 84ced65..d011636 100644
--- a/common/util/Android.mk
+++ b/common/util/Android.mk
@@ -24,7 +24,7 @@
 
 LOCAL_MODULE_TAGS := optional
 
-LOCAL_MODULE := compatibility-common-util-devicesidelib_v2
+LOCAL_MODULE := compatibility-common-util-devicesidelib
 
 LOCAL_SDK_VERSION := current
 
@@ -40,27 +40,10 @@
 
 LOCAL_MODULE_TAGS := optional
 
-LOCAL_MODULE := compatibility-common-util-hostsidelib_v2
+LOCAL_MODULE := compatibility-common-util-hostsidelib
 
-LOCAL_STATIC_JAVA_LIBRARIES := kxml2-2.3.0
+LOCAL_STATIC_JAVA_LIBRARIES := junit kxml2-2.3.0
 
 include $(BUILD_HOST_JAVA_LIBRARY)
 
-###############################################################################
-# Build the tests
-###############################################################################
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under, tests/src)
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
-                        junit \
-                        kxml2-2.3.0 \
-                        compatibility-common-util-hostsidelib_v2
-
-LOCAL_MODULE := compatibility-common-util-tests_v2
-
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_HOST_JAVA_LIBRARY)
+include $(call all-makefiles-under,$(LOCAL_PATH))
\ No newline at end of file
diff --git a/common/util/run_unit_tests.sh b/common/util/run_unit_tests.sh
deleted file mode 100755
index 04a6745..0000000
--- a/common/util/run_unit_tests.sh
+++ /dev/null
@@ -1,49 +0,0 @@
-#!/bin/bash
-
-# Copyright (C) 2012 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#       http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# helper script for running the cts common unit tests
-
-checkFile() {
-    if [ ! -f "$1" ]; then
-        echo "Unable to locate $1"
-        exit
-    fi;
-}
-
-# check if in Android build env
-if [ ! -z ${ANDROID_BUILD_TOP} ]; then
-    HOST=`uname`
-    if [ "$HOST" == "Linux" ]; then
-        OS="linux-x86"
-    elif [ "$HOST" == "Darwin" ]; then
-        OS="darwin-x86"
-    else
-        echo "Unrecognized OS"
-        exit
-    fi;
-fi;
-
-JAR_DIR=${ANDROID_BUILD_TOP}/out/host/$OS/framework
-JARS="tradefed-prebuilt.jar compatibility-common-util-hostsidelib_v2.jar compatibility-common-util-tests_v2.jar"
-
-for JAR in $JARS; do
-    checkFile ${JAR_DIR}/${JAR}
-    JAR_PATH=${JAR_PATH}:${JAR_DIR}/${JAR}
-done
-
-java $RDBG_FLAG \
-  -cp ${JAR_PATH} com.android.tradefed.command.Console run singleCommand host -n --class com.android.compatibility.common.util.UnitTests "$@"
-
diff --git a/common/util/src/com/android/compatibility/common/util/AbiUtils.java b/common/util/src/com/android/compatibility/common/util/AbiUtils.java
new file mode 100644
index 0000000..ef42a00
--- /dev/null
+++ b/common/util/src/com/android/compatibility/common/util/AbiUtils.java
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.util;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Utility class for handling device ABIs
+ */
+public class AbiUtils {
+
+    /**
+     * The set of 32Bit ABIs.
+     */
+    private static final Set<String> ABIS_32BIT = new HashSet<String>();
+
+    /**
+     * The set of 64Bit ABIs.
+     */
+    private static final Set<String> ABIS_64BIT = new HashSet<String>();
+
+    /**
+     * The set of ARM ABIs.
+     */
+    private static final Set<String> ARM_ABIS = new HashSet<String>();
+
+    /**
+     * The set of Intel ABIs.
+     */
+    private static final Set<String> INTEL_ABIS = new HashSet<String>();
+
+    /**
+     * The set of Mips ABIs.
+     */
+    private static final Set<String> MIPS_ABIS = new HashSet<String>();
+
+    /**
+     * The set of ABI names which Compatibility supports.
+     */
+    private static final Set<String> ABIS_SUPPORTED_BY_COMPATIBILITY = new HashSet<String>();
+
+    /**
+     * The map of architecture to ABI.
+     */
+    private static final Map<String, Set<String>> ARCH_TO_ABIS = new HashMap<String, Set<String>>();
+    static {
+        ABIS_32BIT.add("armeabi-v7a");
+        ABIS_32BIT.add("x86");
+        ABIS_32BIT.add("mips");
+
+        ABIS_64BIT.add("arm64-v8a");
+        ABIS_64BIT.add("x86_64");
+        ABIS_64BIT.add("mips64");
+
+        ARM_ABIS.add("armeabi-v7a");
+        ARM_ABIS.add("arm64-v8a");
+
+        INTEL_ABIS.add("x86");
+        INTEL_ABIS.add("x86_64");
+
+        MIPS_ABIS.add("mips");
+        MIPS_ABIS.add("mips64");
+
+        ARCH_TO_ABIS.put("arm", ARM_ABIS);
+        ARCH_TO_ABIS.put("arm64", ARM_ABIS);
+        ARCH_TO_ABIS.put("x86", INTEL_ABIS);
+        ARCH_TO_ABIS.put("x86_64", INTEL_ABIS);
+        ARCH_TO_ABIS.put("mips", MIPS_ABIS);
+        ARCH_TO_ABIS.put("mips64", MIPS_ABIS);
+
+        ABIS_SUPPORTED_BY_COMPATIBILITY.addAll(ARM_ABIS);
+        ABIS_SUPPORTED_BY_COMPATIBILITY.addAll(INTEL_ABIS);
+        ABIS_SUPPORTED_BY_COMPATIBILITY.addAll(MIPS_ABIS);
+    }
+
+    /**
+     * Private constructor to avoid instantiation.
+     */
+    private AbiUtils() {}
+
+    /**
+     * Returns the set of ABIs associated with the given architecture.
+     * @param arch The architecture to look up.
+     * @return a new Set containing the ABIs.
+     */
+    public static Set<String> getAbisForArch(String arch) {
+        if (arch == null || arch.isEmpty() || !ARCH_TO_ABIS.containsKey(arch)) {
+            return getAbisSupportedByCompatibility();
+        }
+        return new HashSet<String>(ARCH_TO_ABIS.get(arch));
+    }
+
+    /**
+     * Returns the set of ABIs supported by Compatibility.
+     * @return a new Set containing the supported ABIs.
+     */
+    public static Set<String> getAbisSupportedByCompatibility() {
+        return new HashSet<String>(ABIS_SUPPORTED_BY_COMPATIBILITY);
+    }
+
+    /**
+     * @param abi The ABI name to test.
+     * @return true if the given ABI is supported by Compatibility.
+     */
+    public static boolean isAbiSupportedByCompatibility(String abi) {
+        return ABIS_SUPPORTED_BY_COMPATIBILITY.contains(abi);
+    }
+
+    /**
+     * Creates a flag for the given ABI.
+     * @param abi the ABI to create the flag for.
+     * @return a string which can be add to a command sent to ADB.
+     */
+    public static String createAbiFlag(String abi) {
+        if (abi == null || abi.isEmpty() || !isAbiSupportedByCompatibility(abi)) {
+            return "";
+        }
+        return String.format("--abi %s ", abi);
+    }
+
+    /**
+     * Creates a unique id from the given ABI and name.
+     * @param abi The ABI to use.
+     * @param name The name to use.
+     * @return a string which uniquely identifies a run.
+     */
+    public static String createId(String abi, String name) {
+        return String.format("%s %s", abi, name);
+    }
+
+    /**
+     * Parses a unique id into the ABI and name.
+     * @param id The id to parse.
+     * @return a string array containing the ABI and name.
+     */
+    public static String[] parseId(String id) {
+        if (id == null || !id.contains(" ")) {
+            return new String[] {"", ""};
+        }
+        return id.split(" ");
+    }
+
+    /**
+     * @return the test name portion of the test id.
+     *         e.g. armeabi-v7a android.mytest = android.mytest
+     */
+    public static String parseTestName(String id) {
+        return parseId(id)[1];
+    }
+
+    /**
+     * @return the abi portion of the test id.
+     *         e.g. armeabi-v7a android.mytest = armeabi-v7a
+     */
+    public static String parseAbi(String id) {
+        return parseId(id)[0];
+    }
+
+    /**
+     * @param name The name of the ABI.
+     * @return The bitness of the ABI with the given name
+     */
+    public static String getBitness(String name) {
+        return ABIS_32BIT.contains(name) ? "32" : "64";
+    }
+
+    /**
+     * @param unsupportedAbiDescription A comma separated string containing abis.
+     * @return A List of Strings containing valid ABIs.
+     */
+    public static Set<String> parseAbiList(String unsupportedAbiDescription) {
+        Set<String> abiSet = new HashSet<>();
+        String[] descSegments = unsupportedAbiDescription.split(":");
+        if (descSegments.length == 2) {
+            for (String abi : descSegments[1].split(",")) {
+                String trimmedAbi = abi.trim();
+                if (isAbiSupportedByCompatibility(trimmedAbi)) {
+                    abiSet.add(trimmedAbi);
+                }
+            }
+        }
+        return abiSet;
+    }
+}
diff --git a/common/util/src/com/android/compatibility/common/util/CaseResult.java b/common/util/src/com/android/compatibility/common/util/CaseResult.java
new file mode 100644
index 0000000..e16ad1f
--- /dev/null
+++ b/common/util/src/com/android/compatibility/common/util/CaseResult.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.util;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Data structure for a Compatibility test case result.
+ */
+public class CaseResult implements ICaseResult {
+
+    private String mName;
+
+    private Map<String, ITestResult> mResults = new HashMap<>();
+
+    /**
+     * Creates a {@link CaseResult} for the given name, eg &lt;package-name&gt;.&lt;class-name&gt;
+     */
+    public CaseResult(String name) {
+        mName = name;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String getName() {
+        return mName;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public ITestResult getOrCreateResult(String testName) {
+        ITestResult result = mResults.get(testName);
+        if (result == null) {
+            result = new TestResult(this, testName);
+            mResults.put(testName, result);
+        }
+        return result;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public ITestResult getResult(String testName) {
+        return mResults.get(testName);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public List<ITestResult> getResults(TestStatus status) {
+        List<ITestResult> results = new ArrayList<>();
+        for (ITestResult result : mResults.values()) {
+            if (result.getResultStatus() == status) {
+                results.add(result);
+            }
+        }
+        return results;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public List<ITestResult> getResults() {
+        ArrayList<ITestResult> results = new ArrayList<>(mResults.values());
+        Collections.sort(results);
+        return results;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int countResults(TestStatus status) {
+        int total = 0;
+        for (ITestResult result : mResults.values()) {
+            if (result.getResultStatus() == status) {
+                total++;
+            }
+        }
+        return total;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int compareTo(ICaseResult another) {
+        return getName().compareTo(another.getName());
+    }
+
+}
\ No newline at end of file
diff --git a/common/util/src/com/android/compatibility/common/util/DynamicConfig.java b/common/util/src/com/android/compatibility/common/util/DynamicConfig.java
new file mode 100644
index 0000000..8317203
--- /dev/null
+++ b/common/util/src/com/android/compatibility/common/util/DynamicConfig.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.compatibility.common.util;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlPullParserFactory;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Load dynamic config for test cases
+ */
+public class DynamicConfig {
+
+    //XML constant
+    public static final String NS = null;
+    public static final String CONFIG_TAG = "dynamicConfig";
+    public static final String ENTRY_TAG = "entry";
+    public static final String VALUE_TAG = "value";
+    public static final String KEY_ATTR = "key";
+
+    public final static String CONFIG_FOLDER_ON_DEVICE = "/sdcard/dynamic-config-files/";
+    public final static String CONFIG_FOLDER_ON_HOST =
+            System.getProperty("java.io.tmpdir") + "/dynamic-config-files/";
+    public final static String MERGED_CONFIG_FILE_FOLDER =
+            System.getProperty("java.io.tmpdir") + "/dynamic-config-files/merged";
+
+    protected Map<String, List<String>> mDynamicConfigMap = new HashMap<String, List<String>>();
+
+    protected void initializeConfig(File file) throws XmlPullParserException, IOException {
+        mDynamicConfigMap = createConfigMap(file);
+    }
+
+    public String getValue(String key) {
+        List<String> singleValue = mDynamicConfigMap.get(key);
+        if (singleValue == null || singleValue.size() == 0 || singleValue.size() > 1) {
+            // key must exist in the map, and map to a list containing exactly one string
+            return null;
+        }
+        return singleValue.get(0);
+    }
+
+    public List<String> getValues(String key) {
+        return mDynamicConfigMap.get(key);
+    }
+
+    public static File getConfigFile(File configFolder, String moduleName)
+            throws FileNotFoundException {
+        File config =  new File(configFolder, String.format("%s.dynamic", moduleName));
+        if (!config.exists()) {
+            throw new FileNotFoundException(String.format("Cannot find %s.dynamic", moduleName));
+        }
+        return config;
+    }
+
+    public static Map<String, List<String>> createConfigMap(File file)
+            throws XmlPullParserException, IOException {
+
+        Map<String, List<String>> dynamicConfigMap = new HashMap<String, List<String>>();
+        XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser();
+        parser.setInput(new InputStreamReader(new FileInputStream(file)));
+        parser.nextTag();
+        parser.require(XmlPullParser.START_TAG, NS, CONFIG_TAG);
+
+        while (parser.nextTag() == XmlPullParser.START_TAG) {
+            parser.require(XmlPullParser.START_TAG, NS, ENTRY_TAG);
+            String key = parser.getAttributeValue(NS, KEY_ATTR);
+            List<String> valueList = new ArrayList<String>();
+            while (parser.nextTag() == XmlPullParser.START_TAG) {
+                parser.require(XmlPullParser.START_TAG, NS, VALUE_TAG);
+                valueList.add(parser.nextText());
+                parser.require(XmlPullParser.END_TAG, NS, VALUE_TAG);
+            }
+            parser.require(XmlPullParser.END_TAG, NS, ENTRY_TAG);
+            if (key != null && !key.isEmpty()) {
+                dynamicConfigMap.put(key, valueList);
+            }
+        }
+
+        parser.require(XmlPullParser.END_TAG, NS, CONFIG_TAG);
+        return dynamicConfigMap;
+    }
+}
diff --git a/common/util/src/com/android/compatibility/common/util/ICaseResult.java b/common/util/src/com/android/compatibility/common/util/ICaseResult.java
new file mode 100644
index 0000000..99e646a
--- /dev/null
+++ b/common/util/src/com/android/compatibility/common/util/ICaseResult.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.util;
+
+import java.util.List;
+
+/**
+ * Data structure for a Compatibility test case result.
+ */
+public interface ICaseResult extends Comparable<ICaseResult> {
+
+    String getName();
+
+    /**
+     * Gets a {@link ITestResult} for the given test, creating it if it doesn't exist.
+     *
+     * @param testName the name of the test eg &lt;method-name&gt;
+     * @return the {@link ITestResult} or <code>null</code>
+     */
+    ITestResult getOrCreateResult(String testName);
+
+    /**
+     * Gets the {@link ITestResult} for given test.
+     *
+     * @param testName the name of the test eg &lt;method-name&gt;
+     * @return the {@link ITestResult} or <code>null</code>
+     */
+    ITestResult getResult(String testName);
+
+    /**
+     * Gets all results sorted by name.
+     */
+    List<ITestResult> getResults();
+
+    /**
+     * Gets all results which have the given status.
+     */
+    List<ITestResult> getResults(TestStatus status);
+
+    /**
+     * Counts the number of results which have the given status.
+     */
+    int countResults(TestStatus status);
+
+}
diff --git a/common/util/src/com/android/compatibility/common/util/IInvocationResult.java b/common/util/src/com/android/compatibility/common/util/IInvocationResult.java
new file mode 100644
index 0000000..c1e5d28
--- /dev/null
+++ b/common/util/src/com/android/compatibility/common/util/IInvocationResult.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.util;
+
+import java.io.File;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Interface for a the result of a single Compatibility invocation.
+ */
+public interface IInvocationResult {
+
+    /**
+     * @return the starting timestamp.
+     */
+    long getStartTime();
+
+    /**
+     * @param time the starting timestamp
+     */
+    void setStartTime(long time);
+
+    /**
+     * Count the number of results with given status.
+     */
+    int countResults(TestStatus result);
+
+    /**
+     * @param plan the plan associated with this result.
+     */
+    void setTestPlan(String plan);
+
+    /**
+     * @return the test plan associated with this result.
+     */
+    String getTestPlan();
+
+    /**
+     * Adds the given device serial to the result.
+     */
+    void addDeviceSerial(String serial);
+
+    /**
+     * @return the device serials associated with result.
+     */
+    Set<String> getDeviceSerials();
+
+    /**
+     * @return the {@link IModuleResult} for the given id, creating one if it doesn't exist
+     */
+    IModuleResult getOrCreateModule(String id);
+
+    /**
+     * @return the {@link IModuleResult}s sorted by id.
+     */
+    List<IModuleResult> getModules();
+
+    /**
+     * @return the directory containing this result.
+     */
+    File getResultDir();
+
+    /**
+     * Adds the given build info to the result.
+     */
+    void addBuildInfo(String key, String value);
+
+    /**
+     * Gets the {@link Map} of build info collected.
+     */
+    Map<String, String> getBuildInfo();
+}
diff --git a/common/util/src/com/android/compatibility/common/util/IModuleResult.java b/common/util/src/com/android/compatibility/common/util/IModuleResult.java
new file mode 100644
index 0000000..6d4efa1
--- /dev/null
+++ b/common/util/src/com/android/compatibility/common/util/IModuleResult.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.util;
+
+import java.util.List;
+
+/**
+ * Data structure for a Compatibility test module result.
+ */
+public interface IModuleResult extends Comparable<IModuleResult> {
+
+    String getId();
+
+    String getName();
+
+    String getAbi();
+
+    void addRuntime(long elapsedTime);
+
+    long getRuntime();
+
+    /**
+     * Gets a {@link ICaseResult} for the given testcase, creating it if it doesn't exist.
+     *
+     * @param caseName the name of the testcase eg &lt;package-name&gt;&lt;class-name&gt;
+     * @return the {@link ICaseResult} or <code>null</code>
+     */
+    ICaseResult getOrCreateResult(String caseName);
+
+    /**
+     * Gets the {@link ICaseResult} result for given testcase.
+     *
+     * @param caseName the name of the testcase eg &lt;package-name&gt;&lt;class-name&gt;
+     * @return the {@link ITestResult} or <code>null</code>
+     */
+    ICaseResult getResult(String caseName);
+
+    /**
+     * Gets all results sorted by name.
+     */
+    List<ICaseResult> getResults();
+
+    /**
+     * Counts the number of results which have the given status.
+     */
+    int countResults(TestStatus status);
+
+}
diff --git a/common/util/src/com/android/compatibility/common/util/ITestResult.java b/common/util/src/com/android/compatibility/common/util/ITestResult.java
new file mode 100644
index 0000000..701a629
--- /dev/null
+++ b/common/util/src/com/android/compatibility/common/util/ITestResult.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.util;
+
+/**
+ * Represents a single test result.
+ */
+public interface ITestResult extends Comparable<ITestResult> {
+
+    /**
+     * @return The name of this test result.
+     */
+    String getName();
+
+    /**
+     * @return The full name of this test result, ie
+     * &lt;package-name&gt;.&lt;class-name&gt;#&lt;method-name&gt;
+     */
+    String getFullName();
+
+    /**
+     * @return The {@link TestStatus} of this result.
+     */
+    TestStatus getResultStatus();
+
+    /**
+     * Sets the {@link TestStatus} of the result and updates the end time of the test.
+     *
+     * @param status The {@link TestStatus} of this result.
+     */
+    void setResultStatus(TestStatus status);
+
+    /**
+     * @return The failure message to display
+     */
+    String getMessage();
+
+    /**
+     * @param message The message to display which describes the failure
+     */
+    void setMessage(String message);
+
+    /**
+     * @return The stack trace generated by the failure
+     */
+    String getStackTrace();
+
+    /**
+     * @param stackTrace the stack trace generated by the failure.
+     */
+    void setStackTrace(String stackTrace);
+
+    /**
+     * @return the metrics report.
+     */
+    ReportLog getReportLog();
+
+    /**
+     * @param report the metrics report.
+     */
+    void setReportLog(ReportLog report);
+
+    /**
+     * @return the path of the bug report generated of the failure.
+     */
+    String getBugReport();
+
+    /**
+     * @param path the path of the bug report generated of the failure.
+     */
+    void setBugReport(String path);
+
+    /**
+     * @return the path of the log file generated of the failure.
+     */
+    String getLog();
+
+    /**
+     * @param path the path of the log file generated of the failure.
+     */
+    void setLog(String path);
+
+    /**
+     * @return the path of the screenshot file generated of the failure.
+     */
+    String getScreenshot();
+
+    /**
+     * @param path the path of the screenshot file generated of the failure.
+     */
+    void setScreenshot(String path);
+
+    /**
+     * Report the test as a failure.
+     *
+     * @param trace the stacktrace of the failure.
+     */
+    void failed(String trace);
+
+    /**
+     * Report that the test has completed.
+     *
+     * @param report A report generated by the test, or null.
+     */
+    void passed(ReportLog report);
+
+    /**
+     * Report that the test was not executed.
+     */
+    void notExecuted();
+
+    /**
+     * Resets the result.
+     */
+    void reset();
+
+}
diff --git a/common/util/src/com/android/compatibility/common/util/InfoStore.java b/common/util/src/com/android/compatibility/common/util/InfoStore.java
new file mode 100644
index 0000000..6c5cc0d
--- /dev/null
+++ b/common/util/src/com/android/compatibility/common/util/InfoStore.java
@@ -0,0 +1,192 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.util;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+
+public abstract class InfoStore {
+
+    protected static final int MAX_STRING_LENGTH = 1000;
+    protected static final int MAX_ARRAY_LENGTH = 1000;
+    protected static final int MAX_LIST_LENGTH = 1000;
+
+    /**
+     * Opens the file for storage and creates the writer.
+     */
+    abstract void open() throws IOException;
+
+    /**
+     * Closes the writer.
+     */
+    abstract void close() throws IOException;
+
+    /**
+     * Start a new group of result.
+     */
+    abstract void startGroup() throws IOException;
+
+    /**
+     * Start a new group of result with specified name.
+     */
+    abstract void startGroup(String name) throws IOException;
+
+    /**
+     * Complete adding result to the last started group.
+     */
+    abstract void endGroup() throws IOException;
+
+    /**
+     * Start a new array of result.
+     */
+    abstract void startArray() throws IOException;
+
+    /**
+     * Start a new array of result with specified name.
+     */
+    abstract void startArray(String name) throws IOException;
+
+    /**
+     * Complete adding result to the last started array.
+     */
+    abstract void endArray() throws IOException;
+
+    /**
+     * Adds a int value to the InfoStore
+     */
+    abstract void addResult(String name, int value) throws IOException;
+
+    /**
+     * Adds a long value to the InfoStore
+     */
+    abstract void addResult(String name, long value) throws IOException;
+
+    /**
+     * Adds a float value to the InfoStore
+     */
+    abstract void addResult(String name, float value) throws IOException;
+
+    /**
+     * Adds a double value to the InfoStore
+     */
+    abstract void addResult(String name, double value) throws IOException;
+
+    /**
+     * Adds a boolean value to the InfoStore
+     */
+    abstract void addResult(String name, boolean value) throws IOException;
+
+    /**
+     * Adds a String value to the InfoStore
+     */
+    abstract void addResult(String name, String value) throws IOException;
+
+    /**
+     * Adds a int array to the InfoStore
+     */
+    abstract void addArrayResult(String name, int[] array) throws IOException;
+
+    /**
+     * Adds a long array to the InfoStore
+     */
+    abstract void addArrayResult(String name, long[] array) throws IOException;
+
+    /**
+     * Adds a float array to the InfoStore
+     */
+    abstract void addArrayResult(String name, float[] array) throws IOException;
+
+    /**
+     * Adds a double array to the InfoStore
+     */
+    abstract void addArrayResult(String name, double[] array) throws IOException;
+
+    /**
+     * Adds a boolean array to the InfoStore
+     */
+    abstract void addArrayResult(String name, boolean[] array) throws IOException;
+
+    /**
+     * Adds a List of String to the InfoStore
+     */
+    abstract void addListResult(String name, List<String> list) throws IOException;
+
+    protected static int[] checkArray(int[] values) {
+        if (values.length > MAX_ARRAY_LENGTH) {
+            return Arrays.copyOf(values, MAX_ARRAY_LENGTH);
+        } else {
+            return values;
+        }
+    }
+
+    protected static long[] checkArray(long[] values) {
+        if (values.length > MAX_ARRAY_LENGTH) {
+            return Arrays.copyOf(values, MAX_ARRAY_LENGTH);
+        } else {
+            return values;
+        }
+    }
+
+    protected static float[] checkArray(float[] values) {
+        if (values.length > MAX_ARRAY_LENGTH) {
+            return Arrays.copyOf(values, MAX_ARRAY_LENGTH);
+        } else {
+            return values;
+        }
+    }
+
+    protected static double[] checkArray(double[] values) {
+        if (values.length > MAX_ARRAY_LENGTH) {
+            return Arrays.copyOf(values, MAX_ARRAY_LENGTH);
+        } else {
+            return values;
+        }
+    }
+
+    protected static boolean[] checkArray(boolean[] values) {
+        if (values.length > MAX_ARRAY_LENGTH) {
+            return Arrays.copyOf(values, MAX_ARRAY_LENGTH);
+        } else {
+            return values;
+        }
+    }
+
+    protected static List<String> checkStringList(List<String> list) {
+        if (list.size() > MAX_LIST_LENGTH) {
+            return list.subList(0, MAX_LIST_LENGTH);
+        }
+        return list;
+    }
+
+    protected static String checkString(String value) {
+        if (value == null || value.isEmpty()) {
+            return "";
+        }
+        if (value.length() > MAX_STRING_LENGTH) {
+            return value.substring(0, MAX_STRING_LENGTH);
+        }
+        return value;
+    }
+
+    protected static String checkName(String value) {
+        if (value == null || value.isEmpty()) {
+            throw new NullPointerException();
+        }
+        return value;
+    }
+}
diff --git a/common/util/src/com/android/compatibility/common/util/InvocationResult.java b/common/util/src/com/android/compatibility/common/util/InvocationResult.java
new file mode 100644
index 0000000..b499bc1
--- /dev/null
+++ b/common/util/src/com/android/compatibility/common/util/InvocationResult.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.util;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Data structure for the detailed Compatibility test results.
+ */
+public class InvocationResult implements IInvocationResult {
+
+    private long mTimestamp;
+    private Map<String, IModuleResult> mModuleResults = new LinkedHashMap<>();
+    private Map<String, String> mBuildInfo = new HashMap<>();
+    private Set<String> mSerials = new HashSet<>();
+    private String mTestPlan;
+    private File mResultDir;
+
+    /**
+     * @param resultDir
+     */
+    public InvocationResult(File resultDir) {
+        this(System.currentTimeMillis(), resultDir);
+    }
+
+    /**
+     * @param timestamp
+     * @param resultDir
+     */
+    public InvocationResult(long timestamp, File resultDir) {
+        setStartTime(timestamp);
+        mResultDir = resultDir;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public List<IModuleResult> getModules() {
+        ArrayList<IModuleResult> modules = new ArrayList<>(mModuleResults.values());
+        Collections.sort(modules);
+        return modules;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int countResults(TestStatus result) {
+        int total = 0;
+        for (IModuleResult m : mModuleResults.values()) {
+            total += m.countResults(result);
+        }
+        return total;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public IModuleResult getOrCreateModule(String id) {
+        IModuleResult moduleResult = mModuleResults.get(id);
+        if (moduleResult == null) {
+            moduleResult = new ModuleResult(id);
+            mModuleResults.put(id, moduleResult);
+        }
+        return moduleResult;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void addBuildInfo(String key, String value) {
+        mBuildInfo.put(key, value);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Map<String, String> getBuildInfo() {
+        return mBuildInfo;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setStartTime(long time) {
+        mTimestamp = time;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public long getStartTime() {
+        return mTimestamp;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setTestPlan(String plan) {
+        mTestPlan = plan;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String getTestPlan() {
+        return mTestPlan;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void addDeviceSerial(String serial) {
+        mSerials.add(serial);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Set<String> getDeviceSerials() {
+        return mSerials;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public File getResultDir() {
+        return mResultDir;
+    }
+
+}
diff --git a/common/util/src/com/android/compatibility/common/util/MeasureRun.java b/common/util/src/com/android/compatibility/common/util/MeasureRun.java
index d58b8d438..2b8905f 100644
--- a/common/util/src/com/android/compatibility/common/util/MeasureRun.java
+++ b/common/util/src/com/android/compatibility/common/util/MeasureRun.java
@@ -25,7 +25,7 @@
      */
     public void prepare(int i) throws Exception {
         // default empty implementation
-    };
+    }
 
     abstract public void run(int i) throws Exception;
 }
diff --git a/common/util/src/com/android/compatibility/common/util/MetricsReportLog.java b/common/util/src/com/android/compatibility/common/util/MetricsReportLog.java
deleted file mode 100644
index 4675231..0000000
--- a/common/util/src/com/android/compatibility/common/util/MetricsReportLog.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.compatibility.common.util;
-
-/**
- * A {@link ReportLog} that can be used with the in memory metrics store used for host side metrics.
- */
-public final class MetricsReportLog extends ReportLog {
-    private final String mDeviceSerial;
-    private final String mAbi;
-    private final String mClassMethodName;
-
-    /**
-     * @param deviceSerial serial number of the device
-     * @param abi abi the test was run on
-     * @param classMethodName class name and method name of the test in class#method format.
-     *        Note that ReportLog.getClassMethodNames() provide this.
-     */
-    public MetricsReportLog(String deviceSerial, String abi, String classMethodName) {
-        mDeviceSerial = deviceSerial;
-        mAbi = abi;
-        mClassMethodName = classMethodName;
-    }
-
-    public void submit() {
-        MetricsStore.storeResult(mDeviceSerial, mAbi, mClassMethodName, this);
-    }
-}
diff --git a/common/util/src/com/android/compatibility/common/util/MetricsStore.java b/common/util/src/com/android/compatibility/common/util/MetricsStore.java
deleted file mode 100644
index 9eeb94a..0000000
--- a/common/util/src/com/android/compatibility/common/util/MetricsStore.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.compatibility.common.util;
-
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * A simple in-memory store for metrics results. This should be used for hostside metrics reporting.
- */
-public class MetricsStore {
-
-    // needs concurrent version as there can be multiple client accessing this.
-    // But there is no additional protection for the same key as that should not happen.
-    private static final ConcurrentHashMap<String, ReportLog> mMap =
-            new ConcurrentHashMap<String, ReportLog>();
-
-    /**
-     * Stores a result. Existing result with the same key will be replaced.
-     * Note that key is generated in the form of device_serial#class#method name.
-     * So there should be no concurrent test for the same (serial, class, method).
-     * @param deviceSerial
-     * @param abi
-     * @param classMethodName
-     * @param reportLog Contains the result to be stored
-     */
-    public static void storeResult(
-            String deviceSerial, String abi, String classMethodName, ReportLog reportLog) {
-        mMap.put(generateTestKey(deviceSerial, abi, classMethodName), reportLog);
-    }
-
-    /**
-     * retrieves a metric result for the given condition and remove it from the internal
-     * storage. If there is no result for the given condition, it will return null.
-     */
-    public static ReportLog removeResult(String deviceSerial, String abi, String classMethodName) {
-        return mMap.remove(generateTestKey(deviceSerial, abi, classMethodName));
-    }
-
-    /**
-     * @return test key in the form of device_serial#abi#class_name#method_name
-     */
-    private static String generateTestKey(String deviceSerial, String abi, String classMethodName) {
-        return String.format("%s#%s#%s", deviceSerial, abi, classMethodName);
-    }
-}
diff --git a/common/util/src/com/android/compatibility/common/util/MetricsXmlSerializer.java b/common/util/src/com/android/compatibility/common/util/MetricsXmlSerializer.java
index 0e2b004..0f4b597 100644
--- a/common/util/src/com/android/compatibility/common/util/MetricsXmlSerializer.java
+++ b/common/util/src/com/android/compatibility/common/util/MetricsXmlSerializer.java
@@ -21,6 +21,7 @@
 import java.io.IOException;
 import java.util.List;
 
+//TODO(stuartscott): Delete file for v2, ReportLog can serialize itself.
 /**
  * Serialize Metric data from {@link ReportLog} into compatibility report friendly XML
  */
@@ -36,26 +37,26 @@
         if (reportLog == null) {
             return;
         }
-        ReportLog.Result summary = reportLog.getSummary();
-        List<ReportLog.Result> detailedMetrics = reportLog.getDetailedMetrics();
+        ReportLog.Metric summary = reportLog.getSummary();
+        List<ReportLog.Metric> detailedMetrics = reportLog.getDetailedMetrics();
         // <Summary message="Average" scoreType="lower_better" unit="ms">195.2</Summary>
         if (summary != null) {
             mXmlSerializer.startTag(null, "Summary");
             mXmlSerializer.attribute(null, "message", summary.getMessage());
-            mXmlSerializer.attribute(null, "scoreType", summary.getType().getXmlString());
-            mXmlSerializer.attribute(null, "unit", summary.getUnit().getXmlString());
+            mXmlSerializer.attribute(null, "scoreType", summary.getType().toReportString());
+            mXmlSerializer.attribute(null, "unit", summary.getUnit().toReportString());
             mXmlSerializer.text(Double.toString(summary.getValues()[0]));
             mXmlSerializer.endTag(null, "Summary");
         }
 
         if (!detailedMetrics.isEmpty()) {
             mXmlSerializer.startTag(null, "Details");
-            for (ReportLog.Result result : detailedMetrics) {
+            for (ReportLog.Metric result : detailedMetrics) {
                 mXmlSerializer.startTag(null, "ValueArray");
-                mXmlSerializer.attribute(null, "source", result.getLocation());
+                mXmlSerializer.attribute(null, "source", result.getSource());
                 mXmlSerializer.attribute(null, "message", result.getMessage());
-                mXmlSerializer.attribute(null, "scoreType", result.getType().getXmlString());
-                mXmlSerializer.attribute(null, "unit", result.getUnit().getXmlString());
+                mXmlSerializer.attribute(null, "scoreType", result.getType().toReportString());
+                mXmlSerializer.attribute(null, "unit", result.getUnit().toReportString());
 
                 for (double value : result.getValues()) {
                     mXmlSerializer.startTag(null, "Value");
@@ -67,4 +68,4 @@
             mXmlSerializer.endTag(null, "Details");
         }
     }
-}
+}
\ No newline at end of file
diff --git a/common/util/src/com/android/compatibility/common/util/ModuleResult.java b/common/util/src/com/android/compatibility/common/util/ModuleResult.java
new file mode 100644
index 0000000..1f277f7
--- /dev/null
+++ b/common/util/src/com/android/compatibility/common/util/ModuleResult.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.util;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Data structure for a Compatibility test module result.
+ */
+public class ModuleResult implements IModuleResult {
+
+    private String mId;
+    private long mRuntime = 0;
+
+    private Map<String, ICaseResult> mResults = new HashMap<>();
+
+    /**
+     * Creates a {@link ModuleResult} for the given id, created with
+     * {@link AbiUtils#createId(String, String)}
+     */
+    public ModuleResult(String id) {
+        mId = id;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String getId() {
+        return mId;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String getName() {
+        return AbiUtils.parseTestName(mId);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String getAbi() {
+        return AbiUtils.parseAbi(mId);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void addRuntime(long elapsedTime) {
+        mRuntime += elapsedTime;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public long getRuntime() {
+        return mRuntime;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public ICaseResult getOrCreateResult(String caseName) {
+        ICaseResult result = mResults.get(caseName);
+        if (result == null) {
+            result = new CaseResult(caseName);
+            mResults.put(caseName, result);
+        }
+        return result;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public ICaseResult getResult(String caseName) {
+        return mResults.get(caseName);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public List<ICaseResult> getResults() {
+        ArrayList<ICaseResult> results = new ArrayList<>(mResults.values());
+        Collections.sort(results);
+        return results;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int countResults(TestStatus status) {
+        int total = 0;
+        for (ICaseResult result : mResults.values()) {
+            total += result.countResults(status);
+        }
+        return total;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int compareTo(IModuleResult another) {
+        return getId().compareTo(another.getId());
+    }
+
+}
diff --git a/common/util/src/com/android/compatibility/common/util/MultipartForm.java b/common/util/src/com/android/compatibility/common/util/MultipartForm.java
new file mode 100644
index 0000000..c311492
--- /dev/null
+++ b/common/util/src/com/android/compatibility/common/util/MultipartForm.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.compatibility.common.util;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+
+/** Builds a multipart form and submits it. */
+class MultipartForm {
+
+    private static final String FORM_DATA_BOUNDARY = "C75I55u3R3p0r73r";
+
+    /* package */ final String mServerUrl;
+    /* package */ final Map<String, String> mFormValues = new HashMap<String, String>();
+    /* package */ String mName;
+    /* package */ String mFileName;
+    /* package */ byte[] mData;
+
+    /**
+     * Creates a new multi-part form with the given serverUrl.
+     */
+    public MultipartForm(String serverUrl) {
+        mServerUrl = serverUrl;
+    }
+
+    /**
+     * Adds a key value attribute to the form.
+     *
+     * @param name the name of the attribute.
+     * @param value the attribute's value.
+     * @return the {@link MultipartForm} for easy chaining.
+     */
+    public MultipartForm addFormValue(String name, String value) {
+        mFormValues.put(name, value);
+        return this;
+    }
+
+    /**
+     * Adds the file as the payload of the form.
+     *
+     * @param name The name of attribute
+     * @param fileName The file's name
+     * @param data The file's data
+     * @return the {@link MultipartForm} for easy chaining.
+     */
+    public MultipartForm addFormFile(String name, String fileName, byte[] data) {
+        mName = name;
+        mFileName = fileName;
+        mData = data;
+        return this;
+    }
+
+    /**
+     * Submits the form to the server url.
+     *
+     * This will handle a redirection from the server.
+     *
+     * @return response code
+     * @throws IOException
+     */
+    public int submit() throws IOException {
+        return submitForm(mServerUrl);
+    }
+
+    /**
+     * @param serverUrl to post the data to
+     * @return response code
+     * @throws IOException
+     */
+    private int submitForm(String serverUrl) throws IOException {
+        HttpURLConnection connection = null;
+        try {
+            URL url = new URL(serverUrl);
+            connection = (HttpURLConnection) url.openConnection();
+            connection.setInstanceFollowRedirects(false);
+            connection.setRequestMethod("POST");
+            connection.setDoOutput(true);
+            connection.setRequestProperty("Content-Type",
+                    "multipart/form-data; boundary=" + FORM_DATA_BOUNDARY);
+
+            byte[] body = getContentBody();
+            connection.setRequestProperty("Content-Length", Integer.toString(body.length));
+
+            OutputStream output = connection.getOutputStream();
+            try {
+                output.write(body);
+            } finally {
+                output.close();
+            }
+
+            // Open the stream to get a response. Otherwise request will be cancelled.
+            InputStream input = connection.getInputStream();
+            input.close();
+
+            int response = connection.getResponseCode();
+            if (response == 302) {
+                return submitForm(connection.getHeaderField("Location"));
+            }
+            return response;
+        } finally {
+            if (connection != null) {
+                connection.disconnect();
+            }
+        }
+    }
+
+    /* package */ byte[] getContentBody() throws IOException {
+        ByteArrayOutputStream byteOutput = new ByteArrayOutputStream();
+        PrintWriter writer = new PrintWriter(new OutputStreamWriter(byteOutput));
+        writer.println();
+
+        for (Map.Entry<String, String> formValue : mFormValues.entrySet()) {
+            writeFormField(writer, formValue.getKey(), formValue.getValue());
+        }
+
+        if (mData != null) {
+            writeFormFileHeader(writer, mName, mFileName);
+            writer.flush(); // Must flush here before writing to the byte stream!
+            byteOutput.write(mData);
+            writer.println();
+        }
+        writer.append("--").append(FORM_DATA_BOUNDARY).println("--");
+        writer.flush();
+        writer.close();
+        return byteOutput.toByteArray();
+    }
+
+    private void writeFormField(PrintWriter writer, String name, String value) {
+        writer.append("--").println(FORM_DATA_BOUNDARY);
+        writer.append("Content-Disposition: form-data; name=\"").append(name).println("\"");
+        writer.println();
+        writer.println(value);
+    }
+
+    private void writeFormFileHeader(PrintWriter writer, String name, String fileName) {
+        writer.append("--").println(FORM_DATA_BOUNDARY);
+        writer.append("Content-Disposition: form-data; name=\"").append(name);
+        writer.append("\"; filename=\"").append(fileName).println("\"");
+        writer.println("Content-Type: application/x-gzip");
+        writer.println("Content-Transfer-Encoding: binary");
+        writer.println();
+    }
+}
diff --git a/common/util/src/com/android/compatibility/common/util/ReportLog.java b/common/util/src/com/android/compatibility/common/util/ReportLog.java
index 7209ac8..37c39ef 100644
--- a/common/util/src/com/android/compatibility/common/util/ReportLog.java
+++ b/common/util/src/com/android/compatibility/common/util/ReportLog.java
@@ -16,66 +16,96 @@
 
 package com.android.compatibility.common.util;
 
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlPullParserFactory;
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
 import java.io.Serializable;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
-import java.util.StringTokenizer;
-import java.util.regex.Pattern;
 
 /**
  * Utility class to add results to the report.
  */
 public class ReportLog implements Serializable {
 
-    private static final String LOG_SEPARATOR = "+++";
-    private static final String SUMMARY_SEPARATOR = "++++";
-    private static final String LOG_ELEM_SEPARATOR = "|";
-    private static final String EMPTY_CHAR = " ";
-    private Result mSummary;
-    private final List<Result> mDetails = new ArrayList<Result>();
+    private static final String ENCODING = "UTF-8";
+    private static final String TYPE = "org.kxml2.io.KXmlParser,org.kxml2.io.KXmlSerializer";
 
-    static class Result implements Serializable {
-        private String mLocation;
-        private String mMessage;
-        private double[] mValues;
-        private ResultType mType;
-        private ResultUnit mUnit;
-        private Double mTarget;
+    // XML constants
+    private static final String DETAIL_TAG = "Detail";
+    private static final String METRIC_TAG = "Metric";
+    private static final String MESSAGE_ATTR = "message";
+    private static final String SCORETYPE_ATTR = "score_type";
+    private static final String SCOREUNIT_ATTR = "score_unit";
+    private static final String SOURCE_ATTR = "source";
+    private static final String SUMMARY_TAG = "Summary";
+    private static final String VALUE_TAG = "Value";
+    private static final String DEFAULT_NAME = "default";
 
+    protected Metric mSummary;
+    protected String mReportLogName;
+    protected String mStreamName;
+    protected final List<Metric> mDetails = new ArrayList<>();
 
-        private Result(String location, String message, double[] values,
-                ResultType type, ResultUnit unit) {
-            this(location, message, values, null /*target*/, type, unit);
+    public static class Metric implements Serializable {
+        private static final int MAX_SOURCE_LENGTH = 200;
+        private static final int MAX_MESSAGE_LENGTH = 200;
+        private static final int MAX_NUM_VALUES = 1000;
+        String mSource;
+        String mMessage;
+        double[] mValues;
+        ResultType mType;
+        ResultUnit mUnit;
+
+        Metric(String source, String message, double value, ResultType type, ResultUnit unit) {
+            this(source, message, new double[] { value }, type, unit);
         }
 
         /**
-         * Creates a result object to be included in the report. Each object has a message
+         * Creates a metric array to be included in the report. Each object has a message
          * describing its values and enums to interpret them. In addition, each result also includes
          * class, method and line number information about the test which added this result which is
          * collected by looking at the stack trace.
          *
          * @param message A string describing the values
          * @param values An array of the values
-         * @param target Nullable. The target value.
          * @param type Represents how to interpret the values (eg. A lower score is better)
          * @param unit Represents the unit in which the values are (eg. Milliseconds)
          */
-        private Result(String location, String message, double[] values,
-                Double target, ResultType type, ResultUnit unit) {
-            mLocation = location;
-            mMessage = message;
-            mValues = values;
+        Metric(String source, String message, double[] values, ResultType type, ResultUnit unit) {
+            int sourceLength = source.length();
+            if (sourceLength > MAX_SOURCE_LENGTH) {
+                // Substring to the end
+                mSource = source.substring(sourceLength - MAX_SOURCE_LENGTH);
+            } else {
+                mSource = source;
+            }
+            int messageLength = message.length();
+            if (messageLength > MAX_MESSAGE_LENGTH) {
+                // Substring from the start
+                mMessage = message.substring(0, MAX_MESSAGE_LENGTH);
+            } else {
+                mMessage = message;
+            }
+            int valuesLength = values.length;
+            if (valuesLength > MAX_NUM_VALUES) {
+                // Subarray from the start
+                mValues = Arrays.copyOf(values, MAX_NUM_VALUES);
+            } else {
+                mValues = values;
+            }
             mType = type;
             mUnit = unit;
-            mTarget = target;
         }
 
-        public double getTarget() {
-            return mTarget;
-        }
-
-        public String getLocation() {
-            return mLocation;
+        public String getSource() {
+            return mSource;
         }
 
         public String getMessage() {
@@ -94,137 +124,222 @@
             return mUnit;
         }
 
-        /**
-         * Format:
-         * location|message|target|type|unit|value[s], target can be " " if there is no target set.
-         * log for array = classMethodName:line_number|message|unit|type|space separated values
-         */
-        String toEncodedString() {
-            StringBuilder builder = new StringBuilder()
-                    .append(mLocation)
-                    .append(LOG_ELEM_SEPARATOR)
-                    .append(mMessage)
-                    .append(LOG_ELEM_SEPARATOR)
-                    .append(mTarget != null ? mTarget : EMPTY_CHAR)
-                    .append(LOG_ELEM_SEPARATOR)
-                    .append(mType.name())
-                    .append(LOG_ELEM_SEPARATOR)
-                    .append(mUnit.name())
-                    .append(LOG_ELEM_SEPARATOR);
-            for (double value : mValues) {
-                builder.append(value).append(" ");
+        void serialize(XmlSerializer serializer)
+                throws IllegalArgumentException, IllegalStateException, IOException {
+            serializer.startTag(null, METRIC_TAG);
+            serializer.attribute(null, SOURCE_ATTR, getSource());
+            serializer.attribute(null, MESSAGE_ATTR, getMessage());
+            serializer.attribute(null, SCORETYPE_ATTR, getType().toReportString());
+            serializer.attribute(null, SCOREUNIT_ATTR, getUnit().toReportString());
+            for (double d : getValues()) {
+                serializer.startTag(null, VALUE_TAG);
+                serializer.text(Double.toString(d));
+                serializer.endTag(null, VALUE_TAG);
             }
-            return builder.toString();
+            serializer.endTag(null, METRIC_TAG);
         }
 
-        static Result fromEncodedString(String encodedString) {
-            String[] elems = encodedString.split(Pattern.quote(LOG_ELEM_SEPARATOR));
-            if (elems.length < 5) {
-                return null;
+        static Metric parse(XmlPullParser parser)
+                throws XmlPullParserException, IOException {
+            parser.require(XmlPullParser.START_TAG, null, METRIC_TAG);
+            String source = parser.getAttributeValue(null, SOURCE_ATTR);
+            String message = parser.getAttributeValue(null, MESSAGE_ATTR);
+            ResultType type = ResultType.parseReportString(
+                    parser.getAttributeValue(null, SCORETYPE_ATTR));
+            ResultUnit unit = ResultUnit.parseReportString(
+                    parser.getAttributeValue(null, SCOREUNIT_ATTR));
+            List<String> valuesList = new ArrayList<>();
+            while (parser.nextTag() == XmlPullParser.START_TAG) {
+                parser.require(XmlPullParser.START_TAG, null, VALUE_TAG);
+                valuesList.add(parser.nextText());
+                parser.require(XmlPullParser.END_TAG, null, VALUE_TAG);
             }
-
-            String[] valueStrArray = elems[5].split(" ");
-            double[] valueArray = new double[valueStrArray.length];
-            for (int i = 0; i < valueStrArray.length; i++) {
-                valueArray[i] = Double.parseDouble(valueStrArray[i]);
+            int length = valuesList.size();
+            double[] values = new double[length];
+            for (int i = 0; i < length; i++) {
+                values[i] = Double.parseDouble(valuesList.get(i));
             }
-            return new Result(
-                    elems[0], /*location*/
-                    elems[1], /*message*/
-                    valueArray, /*values*/
-                    elems[2].equals(EMPTY_CHAR) ? null : Double.parseDouble(elems[2]), /*target*/
-                    ResultType.valueOf(elems[3]), /*type*/
-                    ResultUnit.valueOf(elems[4])  /*unit*/);
+            parser.require(XmlPullParser.END_TAG, null, METRIC_TAG);
+            return new Metric(source, message, values, type, unit);
         }
     }
 
+    public ReportLog() {
+        mReportLogName = DEFAULT_NAME;
+    }
+
+    public ReportLog(String reportLogName, String streamName) {
+        mReportLogName = reportLogName;
+        mStreamName = streamName;
+    }
+
     /**
-     * Adds an array of values to the report.
+     * @param elem
+     */
+    /* package */ void addMetric(Metric elem) {
+        mDetails.add(elem);
+    }
+
+    /**
+     * Adds an array of metrics to the report.
+     *
+     * NOTE: messages over {@value Metric#MAX_MESSAGE_LENGTH} chars will be trimmed.
+     * NOTE: arrays with length over {@value Metric#MAX_NUM_VALUES} will be truncated.
      */
     public void addValues(String message, double[] values, ResultType type, ResultUnit unit) {
-        mDetails.add(new Result(Stacktrace.getTestCallerClassMethodNameLineNumber(),
+        addMetric(new Metric(Stacktrace.getTestCallerClassMethodNameLineNumber(),
                 message, values, type, unit));
     }
 
     /**
-     * Adds an array of values to the report.
+     * Adds an array of metrics to the report.
+     *
+     * NOTE: sources over {@value Metric#MAX_SOURCE_LENGTH} chars will be trimmed.
+     * NOTE: messages over {@value Metric#MAX_MESSAGE_LENGTH} chars will be trimmed.
+     * NOTE: arrays with length over {@value Metric#MAX_NUM_VALUES} will be truncated.
      */
-    public void addValues(
-            String message, double[] values, ResultType type, ResultUnit unit, String location) {
-        mDetails.add(new Result(location, message, values, type, unit));
+    public void addValues(String source, String message, double[] values, ResultType type,
+            ResultUnit unit) {
+        addMetric(new Metric(source, message, values, type, unit));
     }
 
     /**
-     * Adds a value to the report.
+     * Adds a metric to the report.
+     *
+     * NOTE: messages over {@value Metric#MAX_MESSAGE_LENGTH} chars will be trimmed.
      */
     public void addValue(String message, double value, ResultType type, ResultUnit unit) {
-        mDetails.add(new Result(Stacktrace.getTestCallerClassMethodNameLineNumber(), message,
-                new double[] {value}, type, unit));
+        addMetric(new Metric(Stacktrace.getTestCallerClassMethodNameLineNumber(), message,
+                value, type, unit));
     }
 
     /**
-     * Adds a value to the report.
+     * Adds a metric to the report.
+     *
+     * NOTE: sources over {@value Metric#MAX_SOURCE_LENGTH} chars will be trimmed.
+     * NOTE: messages over {@value Metric#MAX_MESSAGE_LENGTH} chars will be trimmed.
      */
-    public void addValue(String message, double value, ResultType type,
-            ResultUnit unit, String location) {
-        mDetails.add(new Result(location, message, new double[] {value}, type, unit));
+    public void addValue(String source, String message, double value, ResultType type,
+            ResultUnit unit) {
+        addMetric(new Metric(source, message, value, type, unit));
+    }
+
+    /**
+     * @param elem
+     */
+    /* package */ void setSummary(Metric elem) {
+        mSummary = elem;
     }
 
     /**
      * Sets the summary of the report.
+     *
+     * NOTE: messages over {@value Metric#MAX_MESSAGE_LENGTH} chars will be trimmed.
      */
     public void setSummary(String message, double value, ResultType type, ResultUnit unit) {
-        mSummary = new Result(Stacktrace.getTestCallerClassMethodNameLineNumber(),
-                message, new double[] {value}, type, unit);
+        setSummary(new Metric(Stacktrace.getTestCallerClassMethodNameLineNumber(), message, value,
+                type, unit));
     }
 
-    public Result getSummary() {
+    // TODO(mishragaurav): Add support for values of other types.
+
+    public Metric getSummary() {
         return mSummary;
     }
 
-    public List<Result> getDetailedMetrics() {
-        return new ArrayList<Result>(mDetails);
+    public List<Metric> getDetailedMetrics() {
+        return new ArrayList<Metric>(mDetails);
     }
 
     /**
-     * Parse a String encoded {@link com.android.compatibility.common.util.ReportLog}
+     * Serializes a given {@link ReportLog} to a String.
+     * @throws XmlPullParserException
+     * @throws IOException
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
      */
-    public static ReportLog fromEncodedString(String encodedString) {
-        ReportLog reportLog = new ReportLog();
-        StringTokenizer tok = new StringTokenizer(encodedString, SUMMARY_SEPARATOR);
-        if (tok.hasMoreTokens()) {
-            // Extract the summary
-            reportLog.mSummary = Result.fromEncodedString(tok.nextToken());
+    public static String serialize(ReportLog reportlog) throws XmlPullParserException,
+            IllegalArgumentException, IllegalStateException, IOException {
+        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+        XmlSerializer serializer = XmlPullParserFactory.newInstance(TYPE, null).newSerializer();
+        serializer.setOutput(byteArrayOutputStream, ENCODING);
+        serializer.startDocument(ENCODING, true);
+        serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
+        serialize(serializer, reportlog);
+        serializer.endDocument();
+        return byteArrayOutputStream.toString(ENCODING);
+    }
+
+    /**
+     * Serializes a given {@link ReportLog} to XML.
+     * @param serializer
+     * @param reportLog
+     * @throws IOException
+     */
+    public static void serialize(XmlSerializer serializer, ReportLog reportLog)
+            throws IOException {
+        if (reportLog == null) {
+            throw new IllegalArgumentException("Metrics reports was null");
         }
-        if (tok.hasMoreTokens()) {
-            // Extract the detailed results
-            StringTokenizer detailedTok = new StringTokenizer(tok.nextToken(), LOG_SEPARATOR);
-            while (detailedTok.hasMoreTokens()) {
-                reportLog.mDetails.add(Result.fromEncodedString(detailedTok.nextToken()));
+        Metric summary = reportLog.getSummary();
+        List<Metric> detailedMetrics = reportLog.getDetailedMetrics();
+        if (summary == null) {
+            throw new IllegalArgumentException("Metrics reports must have a summary");
+        }
+        serializer.startTag(null, SUMMARY_TAG);
+        summary.serialize(serializer);
+        serializer.endTag(null, SUMMARY_TAG);
+
+        if (!detailedMetrics.isEmpty()) {
+            serializer.startTag(null, DETAIL_TAG);
+            for (Metric elem : detailedMetrics) {
+                elem.serialize(serializer);
             }
+            serializer.endTag(null, DETAIL_TAG);
         }
-        return reportLog;
     }
 
     /**
-     * @return a String representation of this report or null if not collected
+     * Parses a {@link ReportLog} from the given string.
+     * @throws XmlPullParserException
+     * @throws IOException
      */
-    protected String toEncodedString() {
-        if ((mSummary == null) && mDetails.isEmpty()) {
-            // just return empty string
-            return null;
+    public static ReportLog parse(String result) throws XmlPullParserException, IOException {
+        if (result == null || result.trim().isEmpty()) {
+            throw new IllegalArgumentException("Metrics string was empty");
         }
-        StringBuilder builder = new StringBuilder();
-        builder.append(mSummary.toEncodedString());
-        builder.append(SUMMARY_SEPARATOR);
-        for (Result result : mDetails) {
-            builder.append(result.toEncodedString());
-            builder.append(LOG_SEPARATOR);
+        XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
+        XmlPullParser parser = factory.newPullParser();
+        parser.setInput(new ByteArrayInputStream(result.getBytes(ENCODING)), ENCODING);
+        parser.nextTag();
+        return parse(parser);
+    }
+
+    /**
+     * Parses a {@link ReportLog} from the given XML parser.
+     * @param parser
+     * @throws IOException
+     * @throws XmlPullParserException
+     */
+    public static ReportLog parse(XmlPullParser parser) throws XmlPullParserException, IOException {
+        parser.require(XmlPullParser.START_TAG, null, SUMMARY_TAG);
+        parser.nextTag();
+        ReportLog report = new ReportLog();
+        report.setSummary(Metric.parse(parser));
+        parser.nextTag();
+        parser.require(XmlPullParser.END_TAG, null, SUMMARY_TAG);
+        try {
+            parser.nextTag();
+        } catch (XmlPullParserException e) {
+            // Report doesn't have any details, it's ok
+            return report;
         }
-        // delete the last separator
-        if (builder.length() >= LOG_SEPARATOR.length()) {
-            builder.delete(builder.length() - LOG_SEPARATOR.length(), builder.length());
+        if (parser.getName().equals(DETAIL_TAG)) {
+            while (parser.nextTag() == XmlPullParser.START_TAG) {
+                report.addMetric(Metric.parse(parser));
+            }
+            parser.require(XmlPullParser.END_TAG, null, DETAIL_TAG);
         }
-        return builder.toString();
+        return report;
     }
 }
diff --git a/common/util/src/com/android/compatibility/common/util/ResultHandler.java b/common/util/src/com/android/compatibility/common/util/ResultHandler.java
new file mode 100644
index 0000000..8e435d8
--- /dev/null
+++ b/common/util/src/com/android/compatibility/common/util/ResultHandler.java
@@ -0,0 +1,343 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.util;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlPullParserFactory;
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.Set;
+
+/**
+ * Handles conversion of results to/from files.
+ */
+public class ResultHandler {
+
+    private static final String ENCODING = "UTF-8";
+    private static final String TYPE = "org.kxml2.io.KXmlParser,org.kxml2.io.KXmlSerializer";
+    private static final String NS = null;
+    private static final String RESULT_FILE_VERSION = "5.0";
+    /* package */ static final String TEST_RESULT_FILE_NAME = "test_result.xml";
+
+    // XML constants
+    private static final String ABI_ATTR = "abi";
+    private static final String BUGREPORT_TAG = "BugReport";
+    private static final String BUILD_ID = "build_id";
+    private static final String BUILD_PRODUCT = "build_product";
+    private static final String BUILD_TAG = "Build";
+    private static final String CASE_TAG = "TestCase";
+    private static final String DEVICES_ATTR = "devices";
+    private static final String END_DISPLAY_TIME_ATTR = "end_display";
+    private static final String END_TIME_ATTR = "end";
+    private static final String FAILED_ATTR = "failed";
+    private static final String FAILURE_TAG = "Failure";
+    private static final String HOST_NAME_ATTR = "host_name";
+    private static final String JAVA_VENDOR_ATTR = "java_vendor";
+    private static final String JAVA_VERSION_ATTR = "java_version";
+    private static final String LOGCAT_TAG = "Logcat";
+    private static final String MESSAGE_ATTR = "message";
+    private static final String MODULE_TAG = "Module";
+    private static final String NAME_ATTR = "name";
+    private static final String NOT_EXECUTED_ATTR = "not_executed";
+    private static final String OS_ARCH_ATTR = "os_arch";
+    private static final String OS_NAME_ATTR = "os_name";
+    private static final String OS_VERSION_ATTR = "os_version";
+    private static final String PASS_ATTR = "pass";
+    private static final String REPORT_VERSION_ATTR = "report_version";
+    private static final String REFERENCE_URL_ATTR = "reference_url";
+    private static final String RESULT_ATTR = "result";
+    private static final String RESULT_TAG = "Result";
+    private static final String RUNTIME_ATTR = "runtime";
+    private static final String SCREENSHOT_TAG = "Screenshot";
+    private static final String STACK_TAG = "StackTrace";
+    private static final String START_DISPLAY_TIME_ATTR = "start_display";
+    private static final String START_TIME_ATTR = "start";
+    private static final String SUITE_NAME_ATTR = "suite_name";
+    private static final String SUITE_PLAN_ATTR = "suite_plan";
+    private static final String SUITE_VERSION_ATTR = "suite_version";
+    private static final String SUITE_BUILD_ATTR = "suite_build_number";
+    private static final String SUMMARY_TAG = "Summary";
+    private static final String TEST_TAG = "Test";
+
+    /**
+     * @param resultsDir
+     */
+    public static List<IInvocationResult> getResults(File resultsDir) {
+        List<IInvocationResult> results = new ArrayList<>();
+        File[] files = resultsDir.listFiles();
+        if (files == null || files.length == 0) {
+            // No results, just return the empty list
+            return results;
+        }
+        for (File resultDir : files) {
+            if (!resultDir.isDirectory()) {
+                continue;
+            }
+            try {
+                File resultFile = new File(resultDir, TEST_RESULT_FILE_NAME);
+                if (!resultFile.exists()) {
+                    continue;
+                }
+                IInvocationResult invocation = new InvocationResult(resultDir);
+                XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
+                XmlPullParser parser = factory.newPullParser();
+                parser.setInput(new FileReader(resultFile));
+
+                parser.nextTag();
+                parser.require(XmlPullParser.START_TAG, NS, RESULT_TAG);
+                invocation.setStartTime(Long.valueOf(
+                        parser.getAttributeValue(NS, START_TIME_ATTR)));
+                invocation.setTestPlan(parser.getAttributeValue(NS, SUITE_PLAN_ATTR));
+                String deviceList = parser.getAttributeValue(NS, DEVICES_ATTR);
+                for (String device : deviceList.split(",")) {
+                    invocation.addDeviceSerial(device);
+                }
+
+                parser.nextTag();
+                parser.require(XmlPullParser.START_TAG, NS, BUILD_TAG);
+                invocation.addBuildInfo(BUILD_ID, parser.getAttributeValue(NS, BUILD_ID));
+                invocation.addBuildInfo(BUILD_PRODUCT, parser.getAttributeValue(NS, BUILD_PRODUCT));
+
+                // TODO(stuartscott): may want to reload these incase the retry was done with
+                // --skip-device-info flag
+                parser.nextTag();
+                parser.require(XmlPullParser.END_TAG, NS, BUILD_TAG);
+                parser.nextTag();
+                parser.require(XmlPullParser.START_TAG, NS, SUMMARY_TAG);
+                parser.nextTag();
+                parser.require(XmlPullParser.END_TAG, NS, SUMMARY_TAG);
+                while (parser.nextTag() == XmlPullParser.START_TAG) {
+                    parser.require(XmlPullParser.START_TAG, NS, MODULE_TAG);
+                    String name = parser.getAttributeValue(NS, NAME_ATTR);
+                    String abi = parser.getAttributeValue(NS, ABI_ATTR);
+                    String moduleId = AbiUtils.createId(abi, name);
+                    IModuleResult module = invocation.getOrCreateModule(moduleId);
+                    while (parser.nextTag() == XmlPullParser.START_TAG) {
+                        parser.require(XmlPullParser.START_TAG, NS, CASE_TAG);
+                        String caseName = parser.getAttributeValue(NS, NAME_ATTR);
+                        ICaseResult testCase = module.getOrCreateResult(caseName);
+                        while (parser.nextTag() == XmlPullParser.START_TAG) {
+                            parser.require(XmlPullParser.START_TAG, NS, TEST_TAG);
+                            String testName = parser.getAttributeValue(NS, NAME_ATTR);
+                            ITestResult test = testCase.getOrCreateResult(testName);
+                            String result = parser.getAttributeValue(NS, RESULT_ATTR);
+                            test.setResultStatus(TestStatus.getStatus(result));
+                            if (parser.nextTag() == XmlPullParser.START_TAG) {
+                                if (parser.getName().equals(FAILURE_TAG)) {
+                                    test.setMessage(parser.getAttributeValue(NS, MESSAGE_ATTR));
+                                    if (parser.nextTag() == XmlPullParser.START_TAG) {
+                                        parser.require(XmlPullParser.START_TAG, NS, STACK_TAG);
+                                        test.setStackTrace(parser.nextText());
+                                        parser.require(XmlPullParser.END_TAG, NS, STACK_TAG);
+                                        parser.nextTag();
+                                    }
+                                    parser.require(XmlPullParser.END_TAG, NS, FAILURE_TAG);
+                                    parser.nextTag();
+                                } else if (parser.getName().equals(BUGREPORT_TAG)) {
+                                    test.setBugReport(parser.nextText());
+                                    parser.nextTag();
+                                } else if (parser.getName().equals(LOGCAT_TAG)) {
+                                    test.setLog(parser.nextText());
+                                    parser.nextTag();
+                                } else if (parser.getName().equals(SCREENSHOT_TAG)) {
+                                    test.setScreenshot(parser.nextText());
+                                    parser.nextTag();
+                                } else {
+                                    test.setReportLog(ReportLog.parse(parser));
+                                    parser.nextTag();
+                                }
+                            }
+                            parser.require(XmlPullParser.END_TAG, NS, TEST_TAG);
+                        }
+                        parser.require(XmlPullParser.END_TAG, NS, CASE_TAG);
+                    }
+                    parser.require(XmlPullParser.END_TAG, NS, MODULE_TAG);
+                }
+                parser.require(XmlPullParser.END_TAG, NS, RESULT_TAG);
+                results.add(invocation);
+            } catch (XmlPullParserException e) {
+                e.printStackTrace();
+            } catch (FileNotFoundException e) {
+                e.printStackTrace();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+        return results;
+    }
+
+    /**
+     * @param result
+     * @param resultDir
+     * @param startTime
+     * @param referenceUrl A nullable string that can contain a URL to a related data
+     * @return The result file created.
+     * @throws IOException
+     * @throws XmlPullParserException
+     */
+    public static File writeResults(String suiteName, String suiteVersion, String suitePlan,
+            String suiteBuild, IInvocationResult result, File resultDir,
+            long startTime, long endTime, String referenceUrl)
+                    throws IOException, XmlPullParserException {
+        int passed = result.countResults(TestStatus.PASS);
+        int failed = result.countResults(TestStatus.FAIL);
+        int notExecuted = result.countResults(TestStatus.NOT_EXECUTED);
+        File resultFile = new File(resultDir, TEST_RESULT_FILE_NAME);
+        OutputStream stream = new FileOutputStream(resultFile);
+        XmlSerializer serializer = XmlPullParserFactory.newInstance(TYPE, null).newSerializer();
+        serializer.setOutput(stream, ENCODING);
+        serializer.startDocument(ENCODING, false);
+        serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
+        serializer.processingInstruction(
+                "xml-stylesheet type=\"text/xsl\" href=\"compatibility_result.xsl\"");
+        serializer.startTag(NS, RESULT_TAG);
+        serializer.attribute(NS, START_TIME_ATTR, String.valueOf(startTime));
+        serializer.attribute(NS, END_TIME_ATTR, String.valueOf(endTime));
+        serializer.attribute(NS, START_DISPLAY_TIME_ATTR, toReadableDateString(startTime));
+        serializer.attribute(NS, END_DISPLAY_TIME_ATTR, toReadableDateString(endTime));
+
+        serializer.attribute(NS, SUITE_NAME_ATTR, suiteName);
+        serializer.attribute(NS, SUITE_VERSION_ATTR, suiteVersion);
+        serializer.attribute(NS, SUITE_PLAN_ATTR, suitePlan);
+        serializer.attribute(NS, SUITE_BUILD_ATTR, suiteBuild);
+        serializer.attribute(NS, REPORT_VERSION_ATTR, RESULT_FILE_VERSION);
+        if (referenceUrl != null) {
+            serializer.attribute(NS, REFERENCE_URL_ATTR, referenceUrl);
+        }
+
+        // Device Info
+        Set<String> devices = result.getDeviceSerials();
+        StringBuilder deviceList = new StringBuilder();
+        boolean first = true;
+        for (String device : devices) {
+            if (first) {
+                first = false;
+            } else {
+                deviceList.append(",");
+            }
+            deviceList.append(device);
+        }
+        serializer.attribute(NS, DEVICES_ATTR, deviceList.toString());
+
+        // Host Info
+        String hostName = "";
+        try {
+            hostName = InetAddress.getLocalHost().getHostName();
+        } catch (UnknownHostException ignored) {}
+        serializer.attribute(NS, HOST_NAME_ATTR, hostName);
+        serializer.attribute(NS, OS_NAME_ATTR, System.getProperty("os.name"));
+        serializer.attribute(NS, OS_VERSION_ATTR, System.getProperty("os.version"));
+        serializer.attribute(NS, OS_ARCH_ATTR, System.getProperty("os.arch"));
+        serializer.attribute(NS, JAVA_VENDOR_ATTR, System.getProperty("java.vendor"));
+        serializer.attribute(NS, JAVA_VERSION_ATTR, System.getProperty("java.version"));
+
+        // Build Info
+        serializer.startTag(NS, BUILD_TAG);
+        for (Entry<String, String> entry : result.getBuildInfo().entrySet()) {
+            serializer.attribute(NS, entry.getKey(), entry.getValue());
+        }
+        serializer.endTag(NS, BUILD_TAG);
+
+        // Summary
+        serializer.startTag(NS, SUMMARY_TAG);
+        serializer.attribute(NS, PASS_ATTR, Integer.toString(passed));
+        serializer.attribute(NS, FAILED_ATTR, Integer.toString(failed));
+        serializer.attribute(NS, NOT_EXECUTED_ATTR, Integer.toString(notExecuted));
+        serializer.endTag(NS, SUMMARY_TAG);
+
+        // Results
+        for (IModuleResult module : result.getModules()) {
+            serializer.startTag(NS, MODULE_TAG);
+            serializer.attribute(NS, NAME_ATTR, module.getName());
+            serializer.attribute(NS, ABI_ATTR, module.getAbi());
+            serializer.attribute(NS, RUNTIME_ATTR, String.valueOf(module.getRuntime()));
+            for (ICaseResult cr : module.getResults()) {
+                serializer.startTag(NS, CASE_TAG);
+                serializer.attribute(NS, NAME_ATTR, cr.getName());
+                for (ITestResult r : cr.getResults()) {
+                    serializer.startTag(NS, TEST_TAG);
+                    serializer.attribute(NS, RESULT_ATTR, r.getResultStatus().getValue());
+                    serializer.attribute(NS, NAME_ATTR, r.getName());
+                    String message = r.getMessage();
+                    if (message != null) {
+                        serializer.startTag(NS, FAILURE_TAG);
+                        serializer.attribute(NS, MESSAGE_ATTR, message);
+                        String stackTrace = r.getStackTrace();
+                        if (stackTrace != null) {
+                            serializer.startTag(NS, STACK_TAG);
+                            serializer.text(stackTrace);
+                            serializer.endTag(NS, STACK_TAG);
+                        }
+                        serializer.endTag(NS, FAILURE_TAG);
+                    }
+                    String bugreport = r.getBugReport();
+                    if (bugreport != null) {
+                        serializer.startTag(NS, BUGREPORT_TAG);
+                        serializer.text(bugreport);
+                        serializer.endTag(NS, BUGREPORT_TAG);
+                    }
+                    String logcat = r.getLog();
+                    if (logcat != null) {
+                        serializer.startTag(NS, LOGCAT_TAG);
+                        serializer.text(logcat);
+                        serializer.endTag(NS, LOGCAT_TAG);
+                    }
+                    String screenshot = r.getScreenshot();
+                    if (screenshot != null) {
+                        serializer.startTag(NS, SCREENSHOT_TAG);
+                        serializer.text(screenshot);
+                        serializer.endTag(NS, SCREENSHOT_TAG);
+                    }
+                    ReportLog report = r.getReportLog();
+                    if (report != null) {
+                        ReportLog.serialize(serializer, report);
+                    }
+                    serializer.endTag(NS, TEST_TAG);
+                }
+                serializer.endTag(NS, CASE_TAG);
+            }
+            serializer.endTag(NS, MODULE_TAG);
+        }
+        serializer.endDocument();
+        return resultFile;
+    }
+
+    /**
+     * Return the given time as a {@link String} suitable for displaying.
+     * <p/>
+     * Example: Fri Aug 20 15:13:03 PDT 2010
+     *
+     * @param time the epoch time in ms since midnight Jan 1, 1970
+     */
+    static String toReadableDateString(long time) {
+        SimpleDateFormat dateFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy");
+        return dateFormat.format(new Date(time));
+    }
+}
diff --git a/common/util/src/com/android/compatibility/common/util/ResultType.java b/common/util/src/com/android/compatibility/common/util/ResultType.java
index 779c6d0..9d0a5fa 100644
--- a/common/util/src/com/android/compatibility/common/util/ResultType.java
+++ b/common/util/src/com/android/compatibility/common/util/ResultType.java
@@ -30,9 +30,16 @@
     WARNING;
 
     /**
-     * Return string used in the XML report
+     * @return a string to be used in the report.
      */
-    public String getXmlString() {
+    public String toReportString() {
         return name().toLowerCase();
     }
+
+    /**
+     * Returns a {@link ResultType} given a string from the report.
+     */
+    public static ResultType parseReportString(String value) {
+        return ResultType.valueOf(value.toUpperCase());
+    }
 }
diff --git a/common/util/src/com/android/compatibility/common/util/ResultUnit.java b/common/util/src/com/android/compatibility/common/util/ResultUnit.java
index 905c4db..31aecbb 100644
--- a/common/util/src/com/android/compatibility/common/util/ResultUnit.java
+++ b/common/util/src/com/android/compatibility/common/util/ResultUnit.java
@@ -42,10 +42,16 @@
     RADIAN;
 
     /**
-     * Return string used in the XML report
+     * @return a string to be used in the report.
      */
-    public String getXmlString() {
+    public String toReportString() {
         return name().toLowerCase();
     }
-}
 
+    /**
+     * Returns a {@link ResultUnit} given a string from the report.
+     */
+    public static ResultUnit parseReportString(String value) {
+        return ResultUnit.valueOf(value.toUpperCase());
+    }
+}
diff --git a/common/util/src/com/android/compatibility/common/util/ResultUploader.java b/common/util/src/com/android/compatibility/common/util/ResultUploader.java
new file mode 100644
index 0000000..7348284
--- /dev/null
+++ b/common/util/src/com/android/compatibility/common/util/ResultUploader.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.compatibility.common.util;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.zip.GZIPOutputStream;
+
+/**
+ * Uploads a result through a HTTP POST multipart/form-data request containing
+ * the test result XML.
+ */
+public class ResultUploader {
+
+    private static final int RESULT_XML_BYTES = 500 * 1024;
+
+    /* package */ MultipartForm mMultipartForm;
+
+    public ResultUploader(String serverUrl, String suiteName) {
+        mMultipartForm = new MultipartForm(serverUrl).addFormValue("suite", suiteName);
+    }
+
+    /**
+     * Uploads the given file to the server.
+     *
+     * @param reportFile The file to upload.
+     * @param referenceUrl A reference url to use.
+     * @throws IOException
+     */
+    public int uploadResult(File reportFile, String referenceUrl) throws IOException {
+        InputStream input = new FileInputStream(reportFile);
+        try {
+            byte[] data = getBytes(input);
+            mMultipartForm.addFormFile("resultXml", "test-result.xml.gz", data);
+            if (referenceUrl != null && !referenceUrl.trim().isEmpty()) {
+                mMultipartForm.addFormValue("referenceUrl", referenceUrl);
+            }
+            return mMultipartForm.submit();
+        } finally {
+            input.close();
+        }
+    }
+
+    private static byte[] getBytes(InputStream input) throws IOException {
+        ByteArrayOutputStream byteOutput = new ByteArrayOutputStream(RESULT_XML_BYTES);
+        GZIPOutputStream gzipOutput = new GZIPOutputStream(byteOutput);
+        byte[] buffer = new byte[1024];
+        int count;
+        while ((count = input.read(buffer)) > 0) {
+            gzipOutput.write(buffer, 0, count);
+        }
+        gzipOutput.close();
+        return byteOutput.toByteArray();
+    }
+
+}
diff --git a/common/util/src/com/android/compatibility/common/util/Stat.java b/common/util/src/com/android/compatibility/common/util/Stat.java
index 8bf9bf7..9748440 100644
--- a/common/util/src/com/android/compatibility/common/util/Stat.java
+++ b/common/util/src/com/android/compatibility/common/util/Stat.java
@@ -22,6 +22,10 @@
  * Utilities for doing statistics
  */
 public class Stat {
+    /**
+     * Private constructor for static class.
+     */
+    private Stat() {}
 
     /**
      * Collection of statistical propertirs like average, max, min, and stddev
@@ -48,10 +52,8 @@
         double average = data[0];
         double min = data[0];
         double max = data[0];
-        double eX2 = data[0] * data[0]; // will become E[X^2]
         for (int i = 1; i < data.length; i++) {
             average += data[i];
-            eX2 += data[i] * data[i];
             if (data[i] > max) {
                 max = data[i];
             }
@@ -60,9 +62,13 @@
             }
         }
         average /= data.length;
-        eX2 /= data.length;
-        // stddev = sqrt(E[X^2] - (E[X])^2)
-        double stddev = Math.sqrt(eX2 - average * average);
+        double sumOfSquares = 0.0;
+        for (int i = 0; i < data.length; i++) {
+            double diff = average - data[i];
+            sumOfSquares += diff * diff;
+        }
+        double variance = sumOfSquares / (data.length - 1);
+        double stddev = Math.sqrt(variance);
         return new StatResult(average, min, max, stddev, data.length);
     }
 
@@ -84,37 +90,16 @@
         double thresholdMin = median * (1.0 - rejectionThreshold);
         double thresholdMax = median * (1.0 + rejectionThreshold);
 
-        double average = 0.0;
-        double min = median;
-        double max = median;
-        double eX2 = 0.0; // will become E[X^2]
-        int validDataCounter = 0;
+        double[] validData = new double[data.length];
+        int index = 0;
         for (int i = 0; i < data.length; i++) {
             if ((data[i] > thresholdMin) && (data[i] < thresholdMax)) {
-                validDataCounter++;
-                average += data[i];
-                eX2 += data[i] * data[i];
-                if (data[i] > max) {
-                    max = data[i];
-                }
-                if (data[i] < min) {
-                    min = data[i];
-                }
+                validData[index] = data[i];
+                index++;
             }
             // TODO report rejected data
         }
-        double stddev;
-        if (validDataCounter > 0) {
-            average /= validDataCounter;
-            eX2 /= validDataCounter;
-            // stddev = sqrt(E[X^2] - (E[X])^2)
-            stddev = Math.sqrt(eX2 - average * average);
-        } else { // both median is showing too much diff
-            average = median;
-            stddev = 0; // don't care
-        }
-
-        return new StatResult(average, min, max, stddev, validDataCounter);
+        return getStat(Arrays.copyOf(validData, index));
     }
 
     /**
@@ -159,7 +144,6 @@
      * timeInSec with 0 value will be changed to small value to prevent divide by zero.
      * @param change total change of quality for the given duration timeInMSec.
      * @param timeInMSec
-     * @return
      */
     public static double calcRatePerSec(double change, double timeInMSec) {
         if (timeInMSec == 0) {
@@ -185,4 +169,14 @@
         return result;
     }
 
+    /**
+     * Get the value of the 95th percentile using nearest rank algorithm.
+     */
+    public static double get95PercentileValue(double[] values) {
+        Arrays.sort(values);
+        // zero-based array index
+        int index = (int) Math.round(values.length * 0.95 + .5) - 1;
+        return values[index];
+    }
+
 }
diff --git a/common/util/src/com/android/compatibility/common/util/TestFilter.java b/common/util/src/com/android/compatibility/common/util/TestFilter.java
new file mode 100644
index 0000000..47ed9ec
--- /dev/null
+++ b/common/util/src/com/android/compatibility/common/util/TestFilter.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.util;
+
+/**
+ * Represents a filter for including and excluding tests.
+ */
+public class TestFilter {
+
+    private final String mAbi;
+    private final String mName;
+    private final String mTest;
+
+    /**
+     * Builds a new {@link TestFilter} from the given string. Filters can be in one of four forms,
+     * the instance will be initialized as;
+     * -"name"                 -> abi = null, name = "name", test = null
+     * -"name" "test..."       -> abi = null, name = "name", test = "test..."
+     * -"abi" "name"           -> abi = "abi", name = "name", test = null
+     * -"abi" "name" "test..." -> abi = "abi", name = "name", test = "test..."
+     *
+     * Test identifier can contain multiple parts, eg parameterized tests.
+     *
+     * @param filter the filter to parse
+     * @return the {@link TestFilter}
+     */
+    public static TestFilter createFrom(String filter) {
+        if (filter.isEmpty()) {
+            throw new IllegalArgumentException("Filter was empty");
+        }
+        String[] parts = filter.split(" ");
+        String abi = null, name = null, test = null;
+        // Either:
+        // <name>
+        // <name> <test>
+        // <abi> <name>
+        // <abi> <name> <test>
+        if (parts.length == 1) {
+            name = parts[0];
+        } else {
+            int index = 0;
+            if (AbiUtils.isAbiSupportedByCompatibility(parts[0])) {
+                abi = parts[0];
+                index++;
+            }
+            name = parts[index];
+            index++;
+            parts = filter.split(" ", index + 1);
+            if (parts.length > index) {
+                test = parts[index];
+            }
+        }
+        return new TestFilter(abi, name, test);
+    }
+
+    /**
+     * Creates a new {@link TestFilter} from the given parts.
+     *
+     * @param abi The ABI must be supported {@link AbiUtils#isAbiSupportedByCompatibility(String)}
+     * @param name The module's name
+     * @param test The test's identifier eg <package>.<class>#<method>
+     */
+    public TestFilter(String abi, String name, String test) {
+        mAbi = abi;
+        mName = name;
+        mTest = test;
+    }
+
+    /**
+     * Returns a String representation of this filter. This function is the inverse of
+     * {@link TestFilter#createFrom(String)}.
+     *
+     * For a valid filter f;
+     * <pre>
+     * {@code
+     * new TestFilter(f).toString().equals(f)
+     * }
+     * </pre>
+     */
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        if (mAbi != null) {
+            sb.append(mAbi);
+            sb.append(" ");
+        }
+        if (mName != null) {
+            sb.append(mName);
+        }
+        if (mTest != null) {
+            sb.append(" ");
+            sb.append(mTest);
+        }
+        return sb.toString();
+    }
+
+    /**
+     * @return the abi of this filter, or null if not specified.
+     */
+    public String getAbi() {
+        return mAbi;
+    }
+
+    /**
+     * @return the module name of this filter, or null if not specified.
+     */
+    public String getName() {
+        return mName;
+    }
+
+    /**
+     * @return the test identifier of this filter, or null if not specified.
+     */
+    public String getTest() {
+        return mTest;
+    }
+
+}
diff --git a/common/util/src/com/android/compatibility/common/util/TestResult.java b/common/util/src/com/android/compatibility/common/util/TestResult.java
new file mode 100644
index 0000000..1bda3af
--- /dev/null
+++ b/common/util/src/com/android/compatibility/common/util/TestResult.java
@@ -0,0 +1,241 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.util;
+
+/**
+ * Represents a single test result.
+ */
+public class TestResult implements ITestResult {
+
+    private final ICaseResult mParent;
+    private final String mTestName;
+    private TestStatus mResult;
+    private String mMessage;
+    private String mStackTrace;
+    private ReportLog mReport;
+    private String mBugReport;
+    private String mLog;
+    private String mScreenshot;
+
+    /**
+     * Create a {@link TestResult} for the given test name.
+     */
+    public TestResult(ICaseResult parent, String name) {
+        mParent = parent;
+        mTestName = name;
+        reset();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String getName() {
+        return mTestName;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String getFullName() {
+        return String.format("%s#%s", mParent.getName(), getName());
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public TestStatus getResultStatus() {
+        return mResult;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setResultStatus(TestStatus status) {
+        mResult = status;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String getMessage() {
+        return mMessage;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setMessage(String message) {
+        mMessage = message;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String getStackTrace() {
+        return mStackTrace;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setStackTrace(String stackTrace) {
+        mStackTrace = sanitizeStackTrace(stackTrace);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public ReportLog getReportLog() {
+        return mReport;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setReportLog(ReportLog report) {
+        mReport = report;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String getBugReport() {
+        return mBugReport;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setBugReport(String path) {
+        mBugReport = path;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String getLog() {
+        return mLog;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setLog(String path) {
+        mLog = path;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String getScreenshot() {
+        return mScreenshot;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setScreenshot(String path) {
+        mScreenshot = path;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void failed(String trace) {
+        setResultStatus(TestStatus.FAIL);
+        int index = trace.indexOf('\n');
+        if (index < 0) {
+            // Trace is a single line, just set the message to be the same as the stacktrace.
+            setMessage(trace);
+        } else {
+            setMessage(trace.substring(0, index));
+        }
+        setStackTrace(trace);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void passed(ReportLog report) {
+        if (!getResultStatus().equals(TestStatus.FAIL)) {
+            setResultStatus(TestStatus.PASS);
+            if (report != null) {
+                setReportLog(report);
+            }
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void notExecuted() {
+        setResultStatus(TestStatus.NOT_EXECUTED);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void reset() {
+        mResult = TestStatus.NOT_EXECUTED;
+        mMessage = null;
+        mStackTrace = null;
+        mReport = null;
+        mBugReport = null;
+        mLog = null;
+        mScreenshot = null;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int compareTo(ITestResult another) {
+        return getName().compareTo(another.getName());
+    }
+
+    /**
+     * Strip out any invalid XML characters that might cause the report to be unviewable.
+     * http://www.w3.org/TR/REC-xml/#dt-character
+     */
+    static String sanitizeStackTrace(String trace) {
+        if (trace != null) {
+            return trace.replaceAll("[^\\u0009\\u000A\\u000D\\u0020-\\uD7FF\\uE000-\\uFFFD]", "");
+        } else {
+            return null;
+        }
+    }
+
+}
diff --git a/common/util/src/com/android/compatibility/common/util/TestStatus.java b/common/util/src/com/android/compatibility/common/util/TestStatus.java
new file mode 100644
index 0000000..766e4d2
--- /dev/null
+++ b/common/util/src/com/android/compatibility/common/util/TestStatus.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.util;
+
+/**
+ * An enum of possible test statuses.
+ */
+public enum TestStatus {
+    PASS("pass"),
+    FAIL("fail"),
+    NOT_EXECUTED("not_executed");
+
+    private String mValue;
+
+    private TestStatus(String storedValue) {
+        mValue = storedValue;
+    }
+
+    /**
+     * Get the String representation of this test status that should be stored in
+     * xml
+     */
+    public String getValue() {
+       return mValue;
+    }
+
+    /**
+     * Find the {@link TestStatus} corresponding to given string value
+     * <p/>
+     * Performs a case insensitive search
+     *
+     * @param value
+     * @return the {@link TestStatus} or <code>null</code> if it could not be found
+     */
+    static TestStatus getStatus(String  value) {
+        for (TestStatus status : TestStatus.values()) {
+            if (value.compareToIgnoreCase(status.getValue()) == 0) {
+                return status;
+            }
+        }
+        return null;
+    }
+}
diff --git a/common/util/src/com/android/compatibility/common/util/TestSuiteFilter.java b/common/util/src/com/android/compatibility/common/util/TestSuiteFilter.java
new file mode 100644
index 0000000..e498c17
--- /dev/null
+++ b/common/util/src/com/android/compatibility/common/util/TestSuiteFilter.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.util;
+
+import junit.framework.Test;
+import junit.framework.TestResult;
+import junit.framework.TestSuite;
+
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Set;
+
+public class TestSuiteFilter {
+
+    private TestSuiteFilter() {}
+
+    public static TestSuite createSuite(List<Class<?>> classes, Set<String> includes,
+            Set<String> excludes) {
+        return new FilterableTestSuite(classes, includes, excludes);
+    }
+
+    /**
+     * A {@link TestSuite} that can filter which tests run, given the include and exclude filters.
+     *
+     * This had to be private inner class because the test runner would find it and think it was a
+     * suite of tests, but it has no tests in it, causing a crash.
+     */
+    private static class FilterableTestSuite extends TestSuite {
+
+        private Set<String> mIncludes;
+        private Set<String> mExcludes;
+
+        public FilterableTestSuite(List<Class<?>> classes, Set<String> includes,
+                Set<String> excludes) {
+            super(classes.toArray(new Class<?>[classes.size()]));
+            mIncludes = includes;
+            mExcludes = excludes;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public int countTestCases() {
+            return countTests(this);
+        }
+
+        private int countTests(Test test) {
+            if (test instanceof TestSuite) {
+                // If the test is a suite it could contain multiple tests, these need to be split
+                // out into separate tests so they can be filtered
+                TestSuite suite = (TestSuite) test;
+                Enumeration<Test> enumerator = suite.tests();
+                int count = 0;
+                while (enumerator.hasMoreElements()) {
+                    count += countTests(enumerator.nextElement());
+                }
+                return count;
+            } else if (shouldRun(test)) {
+                return 1;
+            }
+            return 0;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public void runTest(Test test, TestResult result) {
+            runTests(test, result);
+        }
+
+        private void runTests(Test test, TestResult result) {
+            if (test instanceof TestSuite) {
+                // If the test is a suite it could contain multiple tests, these need to be split
+                // out into separate tests so they can be filtered
+                TestSuite suite = (TestSuite) test;
+                Enumeration<Test> enumerator = suite.tests();
+                while (enumerator.hasMoreElements()) {
+                    runTests(enumerator.nextElement(), result);
+                }
+            } else if (shouldRun(test)) {
+                test.run(result);
+            }
+        }
+
+        private boolean shouldRun(Test test) {
+            String fullName = test.toString();
+            String[] parts = fullName.split("[\\(\\)]");
+            String className = parts[1];
+            String methodName = String.format("%s#%s", className, parts[0]);
+            int index = className.lastIndexOf('.');
+            String packageName = index < 0 ? "" : className.substring(0, index);
+
+            if (mExcludes.contains(packageName)) {
+                // Skip package because it was excluded
+                return false;
+            }
+            if (mExcludes.contains(className)) {
+                // Skip class because it was excluded
+                return false;
+            }
+            if (mExcludes.contains(methodName)) {
+                // Skip method because it was excluded
+                return false;
+            }
+            return mIncludes.isEmpty()
+                    || mIncludes.contains(methodName)
+                    || mIncludes.contains(className)
+                    || mIncludes.contains(packageName);
+        }
+    }
+}
diff --git a/common/util/tests/Android.mk b/common/util/tests/Android.mk
new file mode 100644
index 0000000..0e0af50
--- /dev/null
+++ b/common/util/tests/Android.mk
@@ -0,0 +1,27 @@
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_JAVA_LIBRARIES := junit kxml2-2.3.0 tradefed-prebuilt compatibility-common-util-hostsidelib
+
+LOCAL_MODULE := compatibility-common-util-tests
+
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/common/util/tests/run_tests.sh b/common/util/tests/run_tests.sh
new file mode 100755
index 0000000..0045014
--- /dev/null
+++ b/common/util/tests/run_tests.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+CTS_DIR=$(dirname ${0})/../../..
+source ${CTS_DIR}/test_defs.sh
+
+JARS="
+    compatibility-common-util-hostsidelib\
+    compatibility-common-util-tests\
+    compatibility-host-util\
+    compatibility-host-util-tests\
+    compatibility-mock-tradefed\
+    compatibility-tradefed-tests"
+
+run_tests "com.android.compatibility.common.util.UnitTests" "${JARS}" "${@}"
+
diff --git a/common/util/tests/src/com/android/compatibility/common/util/AbiUtilsTest.java b/common/util/tests/src/com/android/compatibility/common/util/AbiUtilsTest.java
new file mode 100644
index 0000000..567da54
--- /dev/null
+++ b/common/util/tests/src/com/android/compatibility/common/util/AbiUtilsTest.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.compatibility.common.util;
+
+import junit.framework.TestCase;
+
+/**
+ * Unit tests for {@link AbiUtils}
+ */
+public class AbiUtilsTest extends TestCase {
+
+    private static final String MODULE_NAME = "ModuleName";
+    private static final String ABI_NAME = "mips64";
+    private static final String ABI_FLAG = "--abi mips64 ";
+    private static final String ABI_ID = "mips64 ModuleName";
+
+    public void testCreateAbiFlag() {
+        String flag = AbiUtils.createAbiFlag(ABI_NAME);
+        assertEquals("Incorrect flag created", ABI_FLAG, flag);
+    }
+
+    public void testCreateId() {
+        String id = AbiUtils.createId(ABI_NAME, MODULE_NAME);
+        assertEquals("Incorrect id created", ABI_ID, id);
+    }
+
+    public void testParseId() {
+        String[] parts = AbiUtils.parseId(ABI_ID);
+        assertEquals("Wrong size array", 2, parts.length);
+        assertEquals("Wrong abi name", ABI_NAME, parts[0]);
+        assertEquals("Wrong module name", MODULE_NAME, parts[1]);
+    }
+
+    public void testParseName() {
+        String name = AbiUtils.parseTestName(ABI_ID);
+        assertEquals("Incorrect module name", MODULE_NAME, name);
+    }
+
+    public void testParseAbi() {
+        String abi = AbiUtils.parseAbi(ABI_ID);
+        assertEquals("Incorrect abi name", ABI_NAME, abi);
+    }
+
+}
diff --git a/common/util/tests/src/com/android/compatibility/common/util/CaseResultTest.java b/common/util/tests/src/com/android/compatibility/common/util/CaseResultTest.java
new file mode 100644
index 0000000..ae29597
--- /dev/null
+++ b/common/util/tests/src/com/android/compatibility/common/util/CaseResultTest.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.compatibility.common.util;
+
+import junit.framework.TestCase;
+
+/**
+ * Unit tests for {@link CaseResult}
+ */
+public class CaseResultTest extends TestCase {
+
+    private static final String CLASS = "android.test.FoorBar";
+    private static final String METHOD_1 = "testBlah1";
+    private static final String METHOD_2 = "testBlah2";
+    private static final String METHOD_3 = "testBlah3";
+    private static final String MESSAGE = "Something small is not alright";
+    private static final String STACK_TRACE = "Something small is not alright\n " +
+            "at four.big.insects.Marley.sing(Marley.java:10)";
+    private CaseResult mResult;
+
+    @Override
+    public void setUp() throws Exception {
+        mResult = new CaseResult(CLASS);
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        mResult = null;
+    }
+
+    public void testAccessors() throws Exception {
+        assertEquals("Incorrect case name", CLASS, mResult.getName());
+    }
+
+    public void testResultCreation() throws Exception {
+        ITestResult testResult = mResult.getOrCreateResult(METHOD_1);
+        // Should create one
+        assertEquals("Expected one result", 1, mResult.getResults().size());
+        assertTrue("Expected test result", mResult.getResults().contains(testResult));
+        // Should not create another one
+        ITestResult testResult2 = mResult.getOrCreateResult(METHOD_1);
+        assertEquals("Expected the same result", testResult, testResult2);
+        assertEquals("Expected one result", 1, mResult.getResults().size());
+    }
+
+    public void testResultReporting() throws Exception {
+        ITestResult testResult = mResult.getOrCreateResult(METHOD_1);
+        testResult.failed(STACK_TRACE);
+        assertEquals("Expected status to be set", TestStatus.FAIL, testResult.getResultStatus());
+        assertEquals("Expected message to be set", MESSAGE, testResult.getMessage());
+        assertEquals("Expected stack to be set", STACK_TRACE, testResult.getStackTrace());
+        testResult = mResult.getOrCreateResult(METHOD_2);
+        testResult.passed(null);
+        assertEquals("Expected status to be set", TestStatus.PASS, testResult.getResultStatus());
+        assertEquals("Expected two results", 2, mResult.getResults().size());
+    }
+
+    public void testCountResults() throws Exception {
+        mResult.getOrCreateResult(METHOD_1).failed(STACK_TRACE);
+        mResult.getOrCreateResult(METHOD_2).failed(STACK_TRACE);
+        mResult.getOrCreateResult(METHOD_3).passed(null);
+        assertEquals("Expected two failures", 2, mResult.countResults(TestStatus.FAIL));
+        assertEquals("Expected one pass", 1, mResult.countResults(TestStatus.PASS));
+    }
+}
\ No newline at end of file
diff --git a/common/util/tests/src/com/android/compatibility/common/util/DynamicConfigTest.java b/common/util/tests/src/com/android/compatibility/common/util/DynamicConfigTest.java
new file mode 100644
index 0000000..cf1892a
--- /dev/null
+++ b/common/util/tests/src/com/android/compatibility/common/util/DynamicConfigTest.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.compatibility.common.util;
+
+import junit.framework.TestCase;
+
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+/**
+ * Unit tests for {@link DynamicConfig}
+ */
+public class DynamicConfigTest extends TestCase {
+    private static final String correctConfig =
+            "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
+            "<dynamicConfig>\n" +
+            "    <entry key=\"test-config-1\">\n" +
+            "        <value>test config 1</value>\n" +
+            "    </entry>\n" +
+            "    <entry key=\"test-config-2\">\n" +
+            "        <value>testconfig2</value>\n" +
+            "    </entry>\n" +
+            "    <entry key=\"config-list\">\n" +
+            "        <value>config0</value>\n" +
+            "        <value>config1</value>\n" +
+            "        <value>config2</value>\n" +
+            "        <value>config3</value>\n" +
+            "        <value>config4</value>\n" +
+            "    </entry>\n" +
+            "    <entry key=\"config-list-2\">\n" +
+            "        <value>A</value>\n" +
+            "        <value>B</value>\n" +
+            "        <value>C</value>\n" +
+            "        <value>D</value>\n" +
+            "        <value>E</value>\n" +
+            "    </entry>\n" +
+            "</dynamicConfig>\n";
+
+    private static final String configWrongNodeName =
+            "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
+            "<dynamicCsonfig>\n" +  //The node name dynamicConfig is intentionally mistyped
+            "    <entry key=\"test-config-1\">\n" +
+            "        <value>test config 1</value>\n" +
+            "    </entry>\n" +
+            "    <entry key=\"test-config-2\">\n" +
+            "        <value>testconfig2</value>\n" +
+            "    </entry>\n" +
+            "    <entry key=\"config-list\">\n" +
+            "        <value>Nevermore</value>\n" +
+            "        <value>Puck</value>\n" +
+            "        <value>Zeus</value>\n" +
+            "        <value>Earth Shaker</value>\n" +
+            "        <value>Vengeful Spirit</value>\n" +
+            "    </entry>\n" +
+            "    <entry key=\"config-list-2\">\n" +
+            "        <value>A</value>\n" +
+            "        <value>B</value>\n" +
+            "        <value>C</value>\n" +
+            "        <value>D</value>\n" +
+            "        <value>E</value>\n" +
+            "    </entry>\n" +
+            "</dynamicConfig>\n";
+
+    public void testCorrectConfig() throws Exception {
+        DynamicConfig config = new DynamicConfig();
+        File file = createFileFromStr(correctConfig);
+        config.initializeConfig(file);
+
+        assertEquals("Wrong Config", config.getValue("test-config-1"), "test config 1");
+        assertEquals("Wrong Config", config.getValue("test-config-2"), "testconfig2");
+        assertEquals("Wrong Config List", config.getValues("config-list").get(0), "config0");
+        assertEquals("Wrong Config List", config.getValues("config-list").get(2), "config2");
+        assertEquals("Wrong Config List", config.getValues("config-list-2").get(2), "C");
+    }
+
+    public void testConfigWithWrongNodeName() throws Exception {
+        DynamicConfig config = new DynamicConfig();
+        File file = createFileFromStr(configWrongNodeName);
+
+        try {
+            config.initializeConfig(file);
+            fail("Cannot detect error when config file has wrong node name");
+        } catch (XmlPullParserException e) {
+            //expected
+        }
+    }
+
+    private File createFileFromStr(String configStr) throws IOException {
+        File file = File.createTempFile("test", "dynamic");
+        FileOutputStream stream = new FileOutputStream(file);
+        stream.write(configStr.getBytes());
+        stream.flush();
+        return file;
+    }
+}
diff --git a/common/util/tests/src/com/android/compatibility/common/util/MetricsXmlSerializerTest.java b/common/util/tests/src/com/android/compatibility/common/util/MetricsXmlSerializerTest.java
index 05e69d8..c6f3ec1 100644
--- a/common/util/tests/src/com/android/compatibility/common/util/MetricsXmlSerializerTest.java
+++ b/common/util/tests/src/com/android/compatibility/common/util/MetricsXmlSerializerTest.java
@@ -24,6 +24,7 @@
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 
+//TODO(stuartscott): Delete file for v2, ReportLog can serialize itself.
 /**
  * Unit tests for {@link MetricsXmlSerializer}
  */
@@ -32,8 +33,7 @@
     static class LocalReportLog extends ReportLog {}
     private static final double[] VALUES = new double[] {1, 11, 21, 1211, 111221};
     private static final String HEADER = "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>";
-    private static final String EXPECTED_XML =
-            HEADER
+    private static final String EXPECTED_XML = HEADER
             + "<Summary message=\"Sample\" scoreType=\"higher_better\" unit=\"byte\">1.0</Summary>"
             + "<Details>"
                     + "<ValueArray source=\"com.android.compatibility.common.util."
@@ -89,4 +89,4 @@
 
         assertEquals(EXPECTED_XML, mByteArrayOutputStream.toString("utf-8"));
     }
-}
+}
\ No newline at end of file
diff --git a/common/util/tests/src/com/android/compatibility/common/util/ModuleResultTest.java b/common/util/tests/src/com/android/compatibility/common/util/ModuleResultTest.java
new file mode 100644
index 0000000..2239ac8
--- /dev/null
+++ b/common/util/tests/src/com/android/compatibility/common/util/ModuleResultTest.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.compatibility.common.util;
+
+import junit.framework.TestCase;
+
+/**
+ * Unit tests for {@link ModuleResult}
+ */
+public class ModuleResultTest extends TestCase {
+
+    private static final String NAME = "ModuleName";
+    private static final String ABI = "mips64";
+    private static final String ID = AbiUtils.createId(ABI, NAME);
+    private static final String CLASS = "android.test.FoorBar";
+    private static final String METHOD_1 = "testBlah1";
+    private static final String METHOD_2 = "testBlah2";
+    private static final String METHOD_3 = "testBlah3";
+    private static final String STACK_TRACE = "Something small is not alright\n " +
+            "at four.big.insects.Marley.sing(Marley.java:10)";
+    private ModuleResult mResult;
+
+    @Override
+    public void setUp() throws Exception {
+        mResult = new ModuleResult(ID);
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        mResult = null;
+    }
+
+    public void testAccessors() throws Exception {
+        assertEquals("Incorrect module ID", ID, mResult.getId());
+        assertEquals("Incorrect module ABI", ABI, mResult.getAbi());
+        assertEquals("Incorrect module name", NAME, mResult.getName());
+    }
+
+    public void testResultCreation() throws Exception {
+        ICaseResult caseResult = mResult.getOrCreateResult(CLASS);
+        // Should create one
+        assertEquals("Expected one result", 1, mResult.getResults().size());
+        assertTrue("Expected test result", mResult.getResults().contains(caseResult));
+        // Should not create another one
+        ICaseResult caseResult2 = mResult.getOrCreateResult(CLASS);
+        assertEquals("Expected the same result", caseResult, caseResult2);
+        assertEquals("Expected one result", 1, mResult.getResults().size());
+    }
+
+    public void testCountResults() throws Exception {
+        ICaseResult testCase = mResult.getOrCreateResult(CLASS);
+        testCase.getOrCreateResult(METHOD_1).failed(STACK_TRACE);
+        testCase.getOrCreateResult(METHOD_2).failed(STACK_TRACE);
+        testCase.getOrCreateResult(METHOD_3).passed(null);
+        assertEquals("Expected two failures", 2, mResult.countResults(TestStatus.FAIL));
+        assertEquals("Expected one pass", 1, mResult.countResults(TestStatus.PASS));
+    }
+}
\ No newline at end of file
diff --git a/common/util/tests/src/com/android/compatibility/common/util/MultipartFormTest.java b/common/util/tests/src/com/android/compatibility/common/util/MultipartFormTest.java
new file mode 100644
index 0000000..dd96308
--- /dev/null
+++ b/common/util/tests/src/com/android/compatibility/common/util/MultipartFormTest.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.compatibility.common.util;
+
+import junit.framework.TestCase;
+
+import java.util.Arrays;
+
+/**
+ * Unit tests for {@link MultipartForm}
+ */
+public class MultipartFormTest extends TestCase {
+
+    private static final String SERVER_URL = "http://127.0.0.1:5555";
+    private static final byte[] ZIP_ARRAY = {
+            0xa, 0x2d, 0x2d, 0x43, 0x37, 0x35, 0x49, 0x35, 0x35, 0x75, 0x33, 0x52, 0x33, 0x70, 0x30,
+            0x72, 0x37, 0x33, 0x72, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x44, 0x69,
+            0x73, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x66, 0x6f, 0x72,
+            0x6d, 0x2d, 0x64, 0x61, 0x74, 0x61, 0x3b, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22,
+            0x66, 0x6f, 0x6f, 0x22, 0xa, 0xa, 0x62, 0x61, 0x72, 0xa, 0x2d, 0x2d, 0x43, 0x37, 0x35,
+            0x49, 0x35, 0x35, 0x75, 0x33, 0x52, 0x33, 0x70, 0x30, 0x72, 0x37, 0x33, 0x72, 0xa, 0x43,
+            0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x44, 0x69, 0x73, 0x70, 0x6f, 0x73, 0x69,
+            0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x64, 0x61, 0x74,
+            0x61, 0x3b, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x62, 0x6c, 0x61, 0x68, 0x22,
+            0x3b, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x62, 0x6c,
+            0x61, 0x68, 0x2e, 0x78, 0x6d, 0x6c, 0x2e, 0x67, 0x7a, 0x22, 0xa, 0x43, 0x6f, 0x6e, 0x74,
+            0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x61, 0x70, 0x70, 0x6c,
+            0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x78, 0x2d, 0x67, 0x7a, 0x69, 0x70, 0xa,
+            0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66,
+            0x65, 0x72, 0x2d, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x62,
+            0x69, 0x6e, 0x61, 0x72, 0x79, 0xa, 0xa, 0x62, 0x6c, 0x61, 0x68, 0xa, 0x2d, 0x2d, 0x43,
+            0x37, 0x35, 0x49, 0x35, 0x35, 0x75, 0x33, 0x52, 0x33, 0x70, 0x30, 0x72, 0x37, 0x33,
+            0x72, 0x2d, 0x2d, 0xa,
+    };
+
+    public void testContentBody() throws Exception {
+        MultipartForm form = new MultipartForm(SERVER_URL);
+        form.addFormValue("foo", "bar");
+        form.addFormFile("blah", "blah.xml.gz", "blah".getBytes());
+        byte[] data = form.getContentBody();
+        assertTrue("No data", data.length > 0);
+        assertTrue("Wrong data", Arrays.equals(ZIP_ARRAY, data));
+    }
+}
diff --git a/common/util/tests/src/com/android/compatibility/common/util/ReportLogTest.java b/common/util/tests/src/com/android/compatibility/common/util/ReportLogTest.java
index a5f3306..0b4a639 100644
--- a/common/util/tests/src/com/android/compatibility/common/util/ReportLogTest.java
+++ b/common/util/tests/src/com/android/compatibility/common/util/ReportLogTest.java
@@ -16,8 +16,13 @@
 
 package com.android.compatibility.common.util;
 
+import com.android.compatibility.common.util.ReportLog.Metric;
+
 import junit.framework.TestCase;
 
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.util.List;
 import java.util.Arrays;
 
 /**
@@ -25,44 +30,164 @@
  */
 public class ReportLogTest extends TestCase {
 
-    private static final double[] VALUES = new double[] {1, 11, 21, 1211, 111221};
+    private static final String SOURCE = "Source";
+    private static final String MESSAGE = "Message";
+    private static final double[] VALUES = new double[] {.1, 124, 4736, 835.683, 98, 395};
+    private static final String HEADER_XML =
+            "<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>";
+    private static final String SUMMARY_XML =
+            HEADER_XML + "\r\n" +
+            "<Summary>\r\n" +
+            "  <Metric source=\"com.android.compatibility.common.util.ReportLogTest#%s\" message=\"Sample\" score_type=\"higher_better\" score_unit=\"byte\">\r\n" +
+            "    <Value>1.0</Value>\r\n" +
+            "  </Metric>\r\n" +
+            "</Summary>";
+    private static final String DETAIL_XML =
+            "<Detail>\r\n" +
+            "  <Metric source=\"com.android.compatibility.common.util.ReportLogTest#%s\" message=\"Details\" score_type=\"neutral\" score_unit=\"fps\">\r\n" +
+            "    <Value>0.1</Value>\r\n" +
+            "    <Value>124.0</Value>\r\n" +
+            "    <Value>4736.0</Value>\r\n" +
+            "    <Value>835.683</Value>\r\n" +
+            "    <Value>98.0</Value>\r\n" +
+            "    <Value>395.0</Value>\r\n" +
+            "  </Metric>\r\n" +
+            "</Detail>";
+    private static final String FULL_XML = SUMMARY_XML + "\r\n" + DETAIL_XML;
 
-    private static final String EXPECTED_ENCODED_REPORT_LOG =
-            "com.android.compatibility.common.util.ReportLogTest#testEncodeDecode:44|" +
-            "Sample Summary| |HIGHER_BETTER|BYTE|1.0 ++++" +
-            "com.android.compatibility.common.util.ReportLogTest#testEncodeDecode:45|" +
-            "Details| |NEUTRAL|FPS|1.0 11.0 21.0 1211.0 111221.0 ";
-    private ReportLog reportLog;
+    private ReportLog mReportLog;
 
     @Override
     protected void setUp() throws Exception {
-        this.reportLog = new ReportLog();
+        mReportLog = new ReportLog();
     }
 
-    public void testEncodeDecode() {
-
-        reportLog.setSummary("Sample Summary", 1.0, ResultType.HIGHER_BETTER, ResultUnit.BYTE);
-        reportLog.addValues("Details", VALUES, ResultType.NEUTRAL, ResultUnit.FPS);
-
-        String encodedReportLog = reportLog.toEncodedString();
-        assertEquals(EXPECTED_ENCODED_REPORT_LOG, encodedReportLog);
-
-        ReportLog decodedReportLog = ReportLog.fromEncodedString(encodedReportLog);
-        ReportLog.Result summary = reportLog.getSummary();
-        assertEquals("Sample Summary", summary.getMessage());
-        assertFalse(summary.getLocation().isEmpty());
-        assertEquals(ResultType.HIGHER_BETTER, summary.getType());
-        assertEquals(ResultUnit.BYTE, summary.getUnit());
-        assertTrue(Arrays.equals(new double[] {1.0}, summary.getValues()));
-
-        assertEquals(1, decodedReportLog.getDetailedMetrics().size());
-        ReportLog.Result detail = decodedReportLog.getDetailedMetrics().get(0);
-        assertEquals("Details", detail.getMessage());
-        assertFalse(detail.getLocation().isEmpty());
-        assertEquals(ResultType.NEUTRAL, detail.getType());
-        assertEquals(ResultUnit.FPS, detail.getUnit());
-        assertTrue(Arrays.equals(VALUES, detail.getValues()));
-
-        assertEquals(encodedReportLog, decodedReportLog.toEncodedString());
+    public void testSerialize_null() throws Exception {
+        try {
+            ReportLog.serialize(null);
+            fail("Expected IllegalArgumentException when serializing an empty report");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
     }
+
+    public void testSerialize_noData() throws Exception {
+        try {
+            ReportLog.serialize(mReportLog);
+            fail("Expected IllegalArgumentException when serializing an empty report");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+    }
+
+    public void testSerialize_summaryOnly() throws Exception {
+        mReportLog.setSummary("Sample", 1.0, ResultType.HIGHER_BETTER, ResultUnit.BYTE);
+        assertEquals(String.format(SUMMARY_XML, "testSerialize_summaryOnly:84"),
+                ReportLog.serialize(mReportLog));
+    }
+
+    public void testSerialize_detailOnly() throws Exception {
+        mReportLog.addValues("Details", VALUES, ResultType.NEUTRAL, ResultUnit.FPS);
+        try {
+            ReportLog.serialize(mReportLog);
+            fail("Expected IllegalArgumentException when serializing report without summary");
+        } catch(IllegalArgumentException e) {
+            // Expected
+        }
+    }
+
+    public void testSerialize_full() throws Exception {
+        mReportLog.setSummary("Sample", 1.0, ResultType.HIGHER_BETTER, ResultUnit.BYTE);
+        mReportLog.addValues("Details", VALUES, ResultType.NEUTRAL, ResultUnit.FPS);
+        assertEquals(String.format(FULL_XML, "testSerialize_full:100", "testSerialize_full:101"),
+                ReportLog.serialize(mReportLog));
+    }
+
+    public void testParse_null() throws Exception {
+        try {
+            ReportLog.parse((String) null);
+            fail("Expected IllegalArgumentException when passing a null report");
+        } catch(IllegalArgumentException e) {
+            // Expected
+        }
+    }
+
+    public void testParse_noData() throws Exception {
+        try {
+            ReportLog.parse(HEADER_XML);
+            fail("Expected XmlPullParserException when passing a report with no content");
+        } catch(XmlPullParserException e) {
+            // Expected
+        }
+    }
+
+    public void testParse_summaryOnly() throws Exception {
+        ReportLog report = ReportLog.parse(String.format(SUMMARY_XML, "testParse_summaryOnly:125"));
+        assertNotNull(report);
+        assertEquals("Sample", report.getSummary().getMessage());
+    }
+
+    public void testParse_detailOnly() throws Exception {
+        try {
+            ReportLog.parse(String.format(DETAIL_XML, "testParse_detailOnly:132"));
+            fail("Expected XmlPullParserException when serializing report without summary");
+        } catch (XmlPullParserException e) {
+            // Expected
+        }
+    }
+
+    public void testParse_full() throws Exception {
+        ReportLog report = ReportLog.parse(String.format(FULL_XML, "testParse_full:140",
+                "testParse_full:138"));
+        assertNotNull(report);
+        assertEquals("Sample", report.getSummary().getMessage());
+        List<Metric> details = report.getDetailedMetrics();
+        assertEquals(1, details.size());
+        assertEquals("Details", details.get(0).getMessage());
+    }
+
+    public void testLimits_source() throws Exception {
+        // Should pass with a short source.
+        Metric metric = new Metric(SOURCE, MESSAGE, 1.0, ResultType.HIGHER_BETTER, ResultUnit.BYTE);
+        assertEquals("Expected message to be ok", SOURCE, metric.getSource());
+        // Make a long source.
+        StringBuilder sb = new StringBuilder();
+        // 40 x "Source" = 240 character string
+        for (int i = 0; i < 40; i++) sb.append(SOURCE);
+        String source = sb.toString();
+        // Should be trimmed because source is too long.
+        metric = new Metric(source, MESSAGE, 1.0, ResultType.HIGHER_BETTER, ResultUnit.BYTE);
+        assertEquals("Expected source to be trimmed", source.substring(source.length() - 200),
+                metric.getSource());
+    }
+
+    public void testLimits_message() throws Exception {
+        // Should pass with a short message.
+        Metric metric = new Metric(SOURCE, MESSAGE, 1.0, ResultType.HIGHER_BETTER, ResultUnit.BYTE);
+        assertEquals("Expected message to be ok", MESSAGE, metric.getMessage());
+        // Make a long message.
+        StringBuilder sb = new StringBuilder();
+        // 40 x "Message" = 280 character string
+        for (int i = 0; i < 40; i++) sb.append(MESSAGE);
+        String message = sb.toString();
+        // Should be trimmed because message is too long.
+        metric = new Metric(SOURCE, message, 1.0, ResultType.HIGHER_BETTER, ResultUnit.BYTE);
+        assertEquals("Expected message to be trimmed", message.substring(0, 200),
+                metric.getMessage());
+    }
+
+    public void testLimits_values() throws Exception {
+        // Should pass with a small array.
+        Metric metric = new Metric(SOURCE, MESSAGE, VALUES, ResultType.HIGHER_BETTER,
+                ResultUnit.BYTE);
+        assertTrue("Expected values to be ok", Arrays.equals(VALUES, metric.getValues()));
+        // Make a big array.
+        double[] values = new double[1001];
+        for (int i = 0; i < values.length; i++) values[i] = i;
+        // Should be trimmed because array is too big.
+        metric = new Metric(SOURCE, MESSAGE, values, ResultType.HIGHER_BETTER, ResultUnit.BYTE);
+        assertTrue("Expected values to be trimmed", Arrays.equals(Arrays.copyOf(values, 1000),
+                metric.getValues()));
+    }
+
 }
diff --git a/common/util/tests/src/com/android/compatibility/common/util/ResultHandlerTest.java b/common/util/tests/src/com/android/compatibility/common/util/ResultHandlerTest.java
new file mode 100644
index 0000000..c88fe8e
--- /dev/null
+++ b/common/util/tests/src/com/android/compatibility/common/util/ResultHandlerTest.java
@@ -0,0 +1,345 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+package com.android.compatibility.common.util;
+
+import com.android.tradefed.util.FileUtil;
+
+import junit.framework.TestCase;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Unit tests for {@link ResultHandler}
+ */
+public class ResultHandlerTest extends TestCase {
+
+    private static final String SUITE_NAME = "CTS";
+    private static final String SUITE_VERSION = "5.0";
+    private static final String SUITE_PLAN = "cts";
+    private static final String SUITE_BUILD = "12345";
+    private static final String REPORT_VERSION = "5.0";
+    private static final String OS_NAME = System.getProperty("os.name");
+    private static final String OS_VERSION = System.getProperty("os.version");
+    private static final String OS_ARCH = System.getProperty("os.arch");
+    private static final String JAVA_VENDOR = System.getProperty("java.vendor");
+    private static final String JAVA_VERSION = System.getProperty("java.version");
+    private static final String NAME_A = "ModuleA";
+    private static final String NAME_B = "ModuleB";
+    private static final String ABI = "mips64";
+    private static final String ID_A = AbiUtils.createId(ABI, NAME_A);
+    private static final String ID_B = AbiUtils.createId(ABI, NAME_B);
+
+    private static final String BUILD_ID = "build_id";
+    private static final String BUILD_PRODUCT = "build_product";
+    private static final String EXAMPLE_BUILD_ID = "XYZ";
+    private static final String EXAMPLE_BUILD_PRODUCT = "wolverine";
+
+    private static final String DEVICE_A = "device123";
+    private static final String DEVICE_B = "device456";
+    private static final String DEVICES = "device456,device123";
+    private static final String CLASS_A = "android.test.Foor";
+    private static final String CLASS_B = "android.test.Bar";
+    private static final String METHOD_1 = "testBlah1";
+    private static final String METHOD_2 = "testBlah2";
+    private static final String METHOD_3 = "testBlah3";
+    private static final String METHOD_4 = "testBlah4";
+    private static final String SUMMARY_SOURCE = String.format("%s#%s:20", CLASS_B, METHOD_4);
+    private static final String DETAILS_SOURCE = String.format("%s#%s:18", CLASS_B, METHOD_4);
+    private static final String SUMMARY_MESSAGE = "Headline";
+    private static final double SUMMARY_VALUE = 9001;
+    private static final String DETAILS_MESSAGE = "Deats";
+    private static final double DETAILS_VALUE_1 = 14;
+    private static final double DETAILS_VALUE_2 = 18;
+    private static final double DETAILS_VALUE_3 = 17;
+    private static final String MESSAGE = "Something small is not alright";
+    private static final String STACK_TRACE = "Something small is not alright\n " +
+            "at four.big.insects.Marley.sing(Marley.java:10)";
+    private static final long START_MS = 1431586801000L;
+    private static final long END_MS = 1431673199000L;
+    private static final String START_DISPLAY = "Fri Aug 20 15:13:03 PDT 2010";
+    private static final String END_DISPLAY = "Fri Aug 20 15:13:04 PDT 2010";
+
+    private static final String REFERENCE_URL="http://android.com";
+    private static final String JOIN = "%s%s";
+    private static final String XML_BASE =
+            "<?xml version='1.0' encoding='UTF-8' standalone='no' ?>" +
+            "<?xml-stylesheet type=\"text/xsl\" href=\"compatibility_result.xsl\"?>\n" +
+            "<Result start=\"%d\" end=\"%d\" start_display=\"%s\"" +
+            "end_display=\"%s\" suite_name=\"%s\" suite_version=\"%s\" " +
+            "suite_plan=\"%s\" suite_build_number=\"%s\" report_version=\"%s\" " +
+            "devices=\"%s\" host_name=\"%s\"" +
+            "os_name=\"%s\" os_version=\"%s\" os_arch=\"%s\" java_vendor=\"%s\"" +
+            "java_version=\"%s\" reference_url=\"%s\">\n" +
+            "%s%s%s" +
+            "</Result>";
+    private static final String XML_BUILD_INFO =
+            "  <Build build_fingerprint=\"%s\" " + BUILD_ID + "=\"%s\" " +
+               BUILD_PRODUCT + "=\"%s\" />\n";
+    private static final String XML_SUMMARY =
+            "  <Summary pass=\"%d\" failed=\"%d\" not_executed=\"%d\" />\n";
+    private static final String XML_MODULE =
+            "  <Module name=\"%s\" abi=\"%s\" device=\"%s\">\n" +
+            "%s" +
+            "  </Module>\n";
+    private static final String XML_CASE =
+            "    <TestCase name=\"%s\">\n" +
+            "%s" +
+            "    </TestCase>\n";
+    private static final String XML_TEST_PASS =
+            "      <Test result=\"pass\" name=\"%s\"/>\n";
+    private static final String XML_TEST_NOT_EXECUTED =
+            "      <Test result=\"not_executed\" name=\"%s\"/>\n";
+    private static final String XML_TEST_FAIL =
+            "      <Test result=\"fail\" name=\"%s\">\n" +
+            "        <Failure message=\"%s\">\n" +
+            "          <StackTrace>%s</StackTrace>\n" +
+            "        </Failure>\n" +
+            "      </Test>\n";
+    private static final String XML_TEST_RESULT =
+            "      <Test result=\"pass\" name=\"%s\">\n" +
+            "        <Summary>\n" +
+            "          <Metric source=\"%s\" message=\"%s\" score_type=\"%s\" score_unit=\"%s\">\n" +
+            "             <Value>%s</Value>\n" +
+            "          </Metric>\n" +
+            "        </Summary>\n" +
+            "        <Detail>\n" +
+            "          <Metric source=\"%s\" message=\"%s\" score_type=\"%s\" score_unit=\"%s\">\n" +
+            "            <Value>%s</Value>\n" +
+            "            <Value>%s</Value>\n" +
+            "            <Value>%s</Value>\n" +
+            "          </Metric>\n" +
+            "        </Detail>\n" +
+            "      </Test>\n";
+    private File resultsDir = null;
+    private File resultDir = null;
+
+    @Override
+    public void setUp() throws Exception {
+        resultsDir = FileUtil.createTempDir("results");
+        resultDir = FileUtil.createTempDir("12345", resultsDir);
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        if (resultsDir != null) {
+            FileUtil.recursiveDelete(resultsDir);
+        }
+    }
+
+    public void testSerialization() throws Exception {
+        IInvocationResult result = new InvocationResult(resultDir);
+        result.setStartTime(START_MS);
+        result.setTestPlan(SUITE_PLAN);
+        result.addDeviceSerial(DEVICE_A);
+        result.addDeviceSerial(DEVICE_B);
+        result.addBuildInfo(BUILD_ID, EXAMPLE_BUILD_ID);
+        result.addBuildInfo(BUILD_PRODUCT, EXAMPLE_BUILD_PRODUCT);
+        IModuleResult moduleA = result.getOrCreateModule(ID_A);
+        ICaseResult moduleACase = moduleA.getOrCreateResult(CLASS_A);
+        ITestResult moduleATest1 = moduleACase.getOrCreateResult(METHOD_1);
+        moduleATest1.setResultStatus(TestStatus.PASS);
+        ITestResult moduleATest2 = moduleACase.getOrCreateResult(METHOD_2);
+        moduleATest2.setResultStatus(TestStatus.NOT_EXECUTED);
+
+        IModuleResult moduleB = result.getOrCreateModule(ID_B);
+        ICaseResult moduleBCase = moduleB.getOrCreateResult(CLASS_B);
+        ITestResult moduleBTest3 = moduleBCase.getOrCreateResult(METHOD_3);
+        moduleBTest3.setResultStatus(TestStatus.FAIL);
+        moduleBTest3.setMessage(MESSAGE);
+        moduleBTest3.setStackTrace(STACK_TRACE);
+        ITestResult moduleBTest4 = moduleBCase.getOrCreateResult(METHOD_4);
+        moduleBTest4.setResultStatus(TestStatus.PASS);
+        ReportLog report = new ReportLog();
+        ReportLog.Metric summary = new ReportLog.Metric(SUMMARY_SOURCE, SUMMARY_MESSAGE,
+                SUMMARY_VALUE, ResultType.HIGHER_BETTER, ResultUnit.SCORE);
+        report.setSummary(summary);
+        ReportLog.Metric details = new ReportLog.Metric(DETAILS_SOURCE, DETAILS_MESSAGE,
+                new double[] {DETAILS_VALUE_1, DETAILS_VALUE_2, DETAILS_VALUE_3},
+                ResultType.LOWER_BETTER, ResultUnit.MS);
+        report.addMetric(details);
+        moduleBTest4.setReportLog(report);
+
+        // Serialize to file
+        ResultHandler.writeResults(SUITE_NAME, SUITE_VERSION, SUITE_PLAN, SUITE_BUILD,
+                result, resultDir, START_MS, END_MS, REFERENCE_URL);
+
+        // Parse the results and assert correctness
+        checkResult(ResultHandler.getResults(resultsDir), resultDir);
+    }
+
+    public void testParsing() throws Exception {
+        File resultsDir = null;
+        FileWriter writer = null;
+        try {
+            resultsDir = FileUtil.createTempDir("results");
+            File resultDir = FileUtil.createTempDir("12345", resultsDir);
+            // Create the result file
+            File resultFile = new File(resultDir, ResultHandler.TEST_RESULT_FILE_NAME);
+            writer = new FileWriter(resultFile);
+            String buildInfo = String.format(XML_BUILD_INFO, DEVICE_A,
+                    EXAMPLE_BUILD_ID, EXAMPLE_BUILD_PRODUCT);
+            String summary = String.format(XML_SUMMARY, 2, 1, 1);
+            String moduleATest1 = String.format(XML_TEST_PASS, METHOD_1);
+            String moduleATest2 = String.format(XML_TEST_NOT_EXECUTED, METHOD_2);
+            String moduleATests = String.format(JOIN, moduleATest1, moduleATest2);
+            String moduleACases = String.format(XML_CASE, CLASS_A, moduleATests);
+            String moduleA = String.format(XML_MODULE, NAME_A, ABI, DEVICE_A, moduleACases);
+            String moduleBTest3 = String.format(XML_TEST_FAIL, METHOD_3, MESSAGE, STACK_TRACE);
+            String moduleBTest4 = String.format(XML_TEST_RESULT, METHOD_4,
+                    SUMMARY_SOURCE, SUMMARY_MESSAGE, ResultType.HIGHER_BETTER.toReportString(),
+                    ResultUnit.SCORE.toReportString(), Double.toString(SUMMARY_VALUE),
+                    DETAILS_SOURCE, DETAILS_MESSAGE, ResultType.LOWER_BETTER.toReportString(),
+                    ResultUnit.MS.toReportString(), Double.toString(DETAILS_VALUE_1),
+                    Double.toString(DETAILS_VALUE_2), Double.toString(DETAILS_VALUE_3));
+            String moduleBTests = String.format(JOIN, moduleBTest3, moduleBTest4);
+            String moduleBCases = String.format(XML_CASE, CLASS_B, moduleBTests);
+            String moduleB = String.format(XML_MODULE, NAME_B, ABI, DEVICE_B, moduleBCases);
+            String modules = String.format(JOIN, moduleA, moduleB);
+            String hostName = "";
+            try {
+                hostName = InetAddress.getLocalHost().getHostName();
+            } catch (UnknownHostException ignored) {}
+            String output = String.format(XML_BASE, START_MS, END_MS, START_DISPLAY, END_DISPLAY,
+                    SUITE_NAME, SUITE_VERSION, SUITE_PLAN, SUITE_BUILD, REPORT_VERSION, DEVICES,
+                    hostName, OS_NAME, OS_VERSION, OS_ARCH, JAVA_VENDOR,
+                    JAVA_VERSION, REFERENCE_URL, buildInfo, summary, modules);
+            writer.write(output);
+            writer.flush();
+
+            // Parse the results and assert correctness
+            checkResult(ResultHandler.getResults(resultsDir), resultDir);
+        } finally {
+            if (writer != null) {
+                writer.close();
+            }
+        }
+    }
+
+    private void checkResult(List<IInvocationResult> results, File resultDir) throws Exception {
+        assertEquals("Expected 1 result", 1, results.size());
+        IInvocationResult result = results.get(0);
+        assertEquals("Incorrect result dir", resultDir.getAbsolutePath(),
+                result.getResultDir().getAbsolutePath());
+        assertEquals("Expected 2 passes", 2, result.countResults(TestStatus.PASS));
+        assertEquals("Expected 1 failure", 1, result.countResults(TestStatus.FAIL));
+        assertEquals("Expected 1 not executed", 1, result.countResults(TestStatus.NOT_EXECUTED));
+
+        Map<String, String> buildInfo = result.getBuildInfo();
+        assertEquals("Incorrect Build ID", EXAMPLE_BUILD_ID, buildInfo.get(BUILD_ID));
+        assertEquals("Incorrect Build Product",
+            EXAMPLE_BUILD_PRODUCT, buildInfo.get(BUILD_PRODUCT));
+
+        Set<String> serials = result.getDeviceSerials();
+        assertTrue("Missing device", serials.contains(DEVICE_A));
+        assertTrue("Missing device", serials.contains(DEVICE_B));
+        assertEquals("Expected 2 devices", 2, serials.size());
+        assertTrue("Incorrect devices", serials.contains(DEVICE_A) && serials.contains(DEVICE_B));
+        assertEquals("Incorrect start time", START_MS, result.getStartTime());
+        assertEquals("Incorrect test plan", SUITE_PLAN, result.getTestPlan());
+
+        List<IModuleResult> modules = result.getModules();
+        assertEquals("Expected 2 modules", 2, modules.size());
+
+        IModuleResult moduleA = modules.get(0);
+        assertEquals("Expected 1 pass", 1, moduleA.countResults(TestStatus.PASS));
+        assertEquals("Expected 0 failures", 0, moduleA.countResults(TestStatus.FAIL));
+        assertEquals("Expected 1 not executed", 1, moduleA.countResults(TestStatus.NOT_EXECUTED));
+        assertEquals("Incorrect ABI", ABI, moduleA.getAbi());
+        assertEquals("Incorrect name", NAME_A, moduleA.getName());
+        assertEquals("Incorrect ID", ID_A, moduleA.getId());
+        List<ICaseResult> moduleACases = moduleA.getResults();
+        assertEquals("Expected 1 test case", 1, moduleACases.size());
+        ICaseResult moduleACase = moduleACases.get(0);
+        assertEquals("Incorrect name", CLASS_A, moduleACase.getName());
+        List<ITestResult> moduleAResults = moduleACase.getResults();
+        assertEquals("Expected 2 results", 2, moduleAResults.size());
+        ITestResult moduleATest1 = moduleAResults.get(0);
+        assertEquals("Incorrect name", METHOD_1, moduleATest1.getName());
+        assertEquals("Incorrect result", TestStatus.PASS, moduleATest1.getResultStatus());
+        assertNull("Unexpected bugreport", moduleATest1.getBugReport());
+        assertNull("Unexpected log", moduleATest1.getLog());
+        assertNull("Unexpected screenshot", moduleATest1.getScreenshot());
+        assertNull("Unexpected message", moduleATest1.getMessage());
+        assertNull("Unexpected stack trace", moduleATest1.getStackTrace());
+        assertNull("Unexpected report", moduleATest1.getReportLog());
+        ITestResult moduleATest2 = moduleAResults.get(1);
+        assertEquals("Incorrect name", METHOD_2, moduleATest2.getName());
+        assertEquals("Incorrect result", TestStatus.NOT_EXECUTED, moduleATest2.getResultStatus());
+        assertNull("Unexpected bugreport", moduleATest2.getBugReport());
+        assertNull("Unexpected log", moduleATest2.getLog());
+        assertNull("Unexpected screenshot", moduleATest2.getScreenshot());
+        assertNull("Unexpected message", moduleATest2.getMessage());
+        assertNull("Unexpected stack trace", moduleATest2.getStackTrace());
+        assertNull("Unexpected report", moduleATest2.getReportLog());
+
+        IModuleResult moduleB = modules.get(1);
+        assertEquals("Expected 1 pass", 1, moduleB.countResults(TestStatus.PASS));
+        assertEquals("Expected 1 failure", 1, moduleB.countResults(TestStatus.FAIL));
+        assertEquals("Expected 0 not executed", 0, moduleB.countResults(TestStatus.NOT_EXECUTED));
+        assertEquals("Incorrect ABI", ABI, moduleB.getAbi());
+        assertEquals("Incorrect name", NAME_B, moduleB.getName());
+        assertEquals("Incorrect ID", ID_B, moduleB.getId());
+        List<ICaseResult> moduleBCases = moduleB.getResults();
+        assertEquals("Expected 1 test case", 1, moduleBCases.size());
+        ICaseResult moduleBCase = moduleBCases.get(0);
+        assertEquals("Incorrect name", CLASS_B, moduleBCase.getName());
+        List<ITestResult> moduleBResults = moduleBCase.getResults();
+        assertEquals("Expected 2 results", 2, moduleBResults.size());
+        ITestResult moduleBTest3 = moduleBResults.get(0);
+        assertEquals("Incorrect name", METHOD_3, moduleBTest3.getName());
+        assertEquals("Incorrect result", TestStatus.FAIL, moduleBTest3.getResultStatus());
+        assertNull("Unexpected bugreport", moduleBTest3.getBugReport());
+        assertNull("Unexpected log", moduleBTest3.getLog());
+        assertNull("Unexpected screenshot", moduleBTest3.getScreenshot());
+        assertEquals("Incorrect message", MESSAGE, moduleBTest3.getMessage());
+        assertEquals("Incorrect stack trace", STACK_TRACE, moduleBTest3.getStackTrace());
+        assertNull("Unexpected report", moduleBTest3.getReportLog());
+        ITestResult moduleBTest4 = moduleBResults.get(1);
+        assertEquals("Incorrect name", METHOD_4, moduleBTest4.getName());
+        assertEquals("Incorrect result", TestStatus.PASS, moduleBTest4.getResultStatus());
+        assertNull("Unexpected bugreport", moduleBTest4.getBugReport());
+        assertNull("Unexpected log", moduleBTest4.getLog());
+        assertNull("Unexpected screenshot", moduleBTest4.getScreenshot());
+        assertNull("Unexpected message", moduleBTest4.getMessage());
+        assertNull("Unexpected stack trace", moduleBTest4.getStackTrace());
+        ReportLog report = moduleBTest4.getReportLog();
+        assertNotNull("Expected report", report);
+        ReportLog.Metric summary = report.getSummary();
+        assertNotNull("Expected report summary", summary);
+        assertEquals("Incorrect source", SUMMARY_SOURCE, summary.getSource());
+        assertEquals("Incorrect message", SUMMARY_MESSAGE, summary.getMessage());
+        assertEquals("Incorrect type", ResultType.HIGHER_BETTER, summary.getType());
+        assertEquals("Incorrect unit", ResultUnit.SCORE, summary.getUnit());
+        assertTrue("Incorrect values", Arrays.equals(new double[] { SUMMARY_VALUE },
+                summary.getValues()));
+        List<ReportLog.Metric> details = report.getDetailedMetrics();
+        assertEquals("Expected 1 report detail", 1, details.size());
+        ReportLog.Metric detail = details.get(0);
+        assertEquals("Incorrect source", DETAILS_SOURCE, detail.getSource());
+        assertEquals("Incorrect message", DETAILS_MESSAGE, detail.getMessage());
+        assertEquals("Incorrect type", ResultType.LOWER_BETTER, detail.getType());
+        assertEquals("Incorrect unit", ResultUnit.MS, detail.getUnit());
+        assertTrue("Incorrect values", Arrays.equals(new double[] { DETAILS_VALUE_1,
+                DETAILS_VALUE_2, DETAILS_VALUE_3 }, detail.getValues()));
+    }
+}
diff --git a/common/util/tests/src/com/android/compatibility/common/util/StatTest.java b/common/util/tests/src/com/android/compatibility/common/util/StatTest.java
new file mode 100644
index 0000000..6e53d48
--- /dev/null
+++ b/common/util/tests/src/com/android/compatibility/common/util/StatTest.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.compatibility.common.util;
+
+import com.android.compatibility.common.util.Stat;
+import junit.framework.TestCase;
+
+/**
+ * Unit tests for the {@link Stat} class.
+ */
+public class StatTest extends TestCase {
+
+    /**
+     * Test {@link Stat#get95PercentileValue(double[])}.
+     */
+    public void testGet95PercentileValue() {
+        double[] values = new double[100];
+        for (int i = 0; i < 100; i++) {
+            values[i] = i;
+        }
+        assertEquals(95, (int) Stat.get95PercentileValue(values));
+
+        values = new double[1000];
+        for (int i = 0; i < 1000; i++) {
+            values[i] = i;
+        }
+        assertEquals(950, (int) Stat.get95PercentileValue(values));
+
+        values = new double[100];
+        for (int i = 0; i < 100; i++) {
+            values[i] = i * i;
+        }
+        assertEquals(95 * 95, (int) Stat.get95PercentileValue(values));
+    }
+
+    /**
+     * Test {@link Stat#getAverage(double[])}.
+     */
+    public void testGetAverage() {
+        double[] values = new double[]{0, 1, 2, 3, 4};
+        double average = Stat.getAverage(values);
+        assertEquals(2.0, average, 0.00001);
+
+        values = new double[]{1, 2, 3, 4, 5};
+        average = Stat.getAverage(values);
+        assertEquals(3.0, average, 0.00001);
+
+        values = new double[]{0, 1, 4, 9, 16};
+        average = Stat.getAverage(values);
+        assertEquals(6.0, average, 0.00001);
+    }
+
+    /**
+     * Test standard deviation.
+     */
+    public void testGetStandardDeviation() {
+        double[] values = new double[]{0, 1, 2, 3, 4};
+        double stddev = Stat.getStat(values).mStddev;
+        assertEquals(Math.sqrt(2.5), stddev, 0.00001);
+
+        values = new double[]{1, 2, 3, 4, 5};
+        stddev = Stat.getStat(values).mStddev;
+        assertEquals(Math.sqrt(2.5), stddev, 0.00001);
+
+        values = new double[]{0, 2, 4, 6, 8};
+        stddev = Stat.getStat(values).mStddev;
+        assertEquals(Math.sqrt(10.0), stddev, 0.00001);
+    }
+
+
+}
diff --git a/common/util/tests/src/com/android/compatibility/common/util/TestFilterTest.java b/common/util/tests/src/com/android/compatibility/common/util/TestFilterTest.java
new file mode 100644
index 0000000..bc1091bb
--- /dev/null
+++ b/common/util/tests/src/com/android/compatibility/common/util/TestFilterTest.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.compatibility.common.util;
+
+import junit.framework.TestCase;
+
+/**
+ * Unit tests for {@link TestFilter}
+ */
+public class TestFilterTest extends TestCase {
+
+    private static final String NAME = "ModuleName";
+    private static final String ABI = "mips64";
+    private static final String TEST = "com.android.foobar.Blah#testAllTheThings";
+    private static final String NAME_FILTER = String.format("%s", NAME);
+    private static final String ABI_NAME_FILTER = String.format("%s %s", ABI, NAME);
+    private static final String NAME_TEST_FILTER = String.format("%s %s", NAME, TEST);
+    private static final String FULL_FILTER = String.format("%s %s %s", ABI, NAME, TEST);
+
+    public void testParseNameFilter() {
+        TestFilter filter = TestFilter.createFrom(NAME_FILTER);
+        assertNull("Incorrect abi", filter.getAbi());
+        assertEquals("Incorrect name", NAME, filter.getName());
+        assertNull("Incorrect test", filter.getTest());
+    }
+
+    public void testParseAbiNameFilter() {
+        TestFilter filter = TestFilter.createFrom(ABI_NAME_FILTER);
+        assertEquals("Incorrect abi", ABI, filter.getAbi());
+        assertEquals("Incorrect name", NAME, filter.getName());
+        assertNull("Incorrect test", filter.getTest());
+    }
+
+    public void testParseNameTestFilter() {
+        TestFilter filter = TestFilter.createFrom(NAME_TEST_FILTER);
+        assertNull("Incorrect abi", filter.getAbi());
+        assertEquals("Incorrect name", NAME, filter.getName());
+        assertEquals("Incorrect test", TEST, filter.getTest());
+    }
+
+    public void testParseFullFilter() {
+        TestFilter filter = TestFilter.createFrom(FULL_FILTER);
+        assertEquals("Incorrect abi", ABI, filter.getAbi());
+        assertEquals("Incorrect name", NAME, filter.getName());
+        assertEquals("Incorrect test", TEST, filter.getTest());
+    }
+
+    public void testCreateNameFilter() {
+        TestFilter filter = new TestFilter(null, NAME, null);
+        assertEquals("Incorrect filter", NAME_FILTER, filter.toString());
+    }
+
+    public void testCreateAbiNameFilter() {
+        TestFilter filter = new TestFilter(ABI, NAME, null);
+        assertEquals("Incorrect filter", ABI_NAME_FILTER, filter.toString());
+    }
+
+    public void testCreateNameTestFilter() {
+        TestFilter filter = new TestFilter(null, NAME, TEST);
+        assertEquals("Incorrect filter", NAME_TEST_FILTER, filter.toString());
+    }
+
+    public void testCreateFullFilter() {
+        TestFilter filter = new TestFilter(ABI, NAME, TEST);
+        assertEquals("Incorrect filter", FULL_FILTER, filter.toString());
+    }
+
+}
diff --git a/common/util/tests/src/com/android/compatibility/common/util/TestResultTest.java b/common/util/tests/src/com/android/compatibility/common/util/TestResultTest.java
new file mode 100644
index 0000000..5e4431e
--- /dev/null
+++ b/common/util/tests/src/com/android/compatibility/common/util/TestResultTest.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.compatibility.common.util;
+
+import junit.framework.TestCase;
+
+/**
+ * Unit tests for {@link TestResult}
+ */
+public class TestResultTest extends TestCase {
+
+    private static final String CLASS = "android.test.FoorBar";
+    private static final String METHOD_1 = "testBlah1";
+    private static final String TEST_1 = String.format("%s#%s", CLASS, METHOD_1);
+    private CaseResult mCase;
+    private TestResult mResult;
+
+    @Override
+    public void setUp() throws Exception {
+        mCase = new CaseResult(CLASS);
+        mResult = new TestResult(mCase, METHOD_1);
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        mResult = null;
+    }
+
+    public void testAccessors() throws Exception {
+        assertEquals("Incorrect test name", METHOD_1, mResult.getName());
+        assertEquals("Incorrect full name", TEST_1, mResult.getFullName());
+    }
+
+}
\ No newline at end of file
diff --git a/common/util/tests/src/com/android/compatibility/common/util/UnitTests.java b/common/util/tests/src/com/android/compatibility/common/util/UnitTests.java
index 348c680..967b8a8 100644
--- a/common/util/tests/src/com/android/compatibility/common/util/UnitTests.java
+++ b/common/util/tests/src/com/android/compatibility/common/util/UnitTests.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (C) 2015 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -11,23 +11,36 @@
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
  */
-
 package com.android.compatibility.common.util;
 
+import junit.framework.Test;
 import junit.framework.TestSuite;
 
 /**
- * A {@link TestSuite} for the common.util package.
+ * A test suite for all util unit tests.
+ * <p/>
+ * All tests listed here should be self-contained, and do not require any external dependencies.
  */
 public class UnitTests extends TestSuite {
 
     public UnitTests() {
         super();
-
-        addTestSuite(MetricsStoreTest.class);
+        addTestSuite(AbiUtilsTest.class);
+        addTestSuite(CaseResultTest.class);
+        addTestSuite(DynamicConfigTest.class);
         addTestSuite(MetricsXmlSerializerTest.class);
+        addTestSuite(ModuleResultTest.class);
+        addTestSuite(MultipartFormTest.class);
         addTestSuite(ReportLogTest.class);
+        addTestSuite(StatTest.class);
+        addTestSuite(TestFilterTest.class);
+        addTestSuite(TestResultTest.class);
+        addTestSuite(ResultHandlerTest.class);
     }
-}
+
+    public static Test suite() {
+        return new UnitTests();
+    }
+}
\ No newline at end of file
diff --git a/hostsidetests/aadb/Android.mk b/hostsidetests/aadb/Android.mk
index b9551d1..f20f603 100644
--- a/hostsidetests/aadb/Android.mk
+++ b/hostsidetests/aadb/Android.mk
@@ -19,12 +19,16 @@
 # Only compile source java files in this apk.
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
-LOCAL_MODULE := CtsAdbTests
+# Adb test cases, but name 'aadb' ensures adb tests run before all other modules depending on adb
+LOCAL_MODULE := CtsAadbHostTestCases
 
 LOCAL_JAVA_LIBRARIES := cts-tradefed tradefed-prebuilt
 
 LOCAL_CTS_TEST_PACKAGE := android.aadb
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_CTS_HOST_JAVA_LIBRARY)
 
 # Build the test APKs using their own makefiles
diff --git a/hostsidetests/aadb/AndroidTest.xml b/hostsidetests/aadb/AndroidTest.xml
new file mode 100644
index 0000000..cfba81e
--- /dev/null
+++ b/hostsidetests/aadb/AndroidTest.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for the CTS aadb host tests">
+    <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest">
+        <option name="jar" value="CtsAadbHostTestCases.jar" />
+        <option name="runtime-hint" value="5m30s" />
+    </test>
+</configuration>
diff --git a/hostsidetests/aadb/src/android/aadb/cts/TestDeviceFuncTest.java b/hostsidetests/aadb/src/android/aadb/cts/TestDeviceFuncTest.java
new file mode 100644
index 0000000..6a77674
--- /dev/null
+++ b/hostsidetests/aadb/src/android/aadb/cts/TestDeviceFuncTest.java
@@ -0,0 +1,402 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.aadb.cts;
+
+import com.android.ddmlib.IDevice;
+import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.IFileEntry;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.log.LogUtil.CLog;
+import com.android.tradefed.result.CollectingTestListener;
+import com.android.tradefed.result.InputStreamSource;
+import com.android.tradefed.testtype.DeviceTestCase;
+import com.android.tradefed.util.CommandStatus;
+import com.android.tradefed.util.FileUtil;
+import com.android.tradefed.util.RunUtil;
+import com.android.tradefed.util.StreamUtil;
+
+import java.awt.image.BufferedImage;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.IOException;
+import java.util.TimeZone;
+
+import javax.imageio.ImageIO;
+
+/**
+ * Functional tests for adb connection
+ * <p/>
+ * Requires a physical device to be connected.
+ */
+public class TestDeviceFuncTest extends DeviceTestCase {
+
+    private ITestDevice mTestDevice;
+    /** Expect bugreports to be at least a meg. */
+    private static final int mMinBugreportBytes = 1024 * 1024;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mTestDevice = getDevice();
+    }
+
+    /**
+     * Simple testcase to ensure that the grabbing a bugreport from a real TestDevice works.
+     */
+    public void testBugreport() throws Exception {
+        String data = StreamUtil.getStringFromStream(
+                mTestDevice.getBugreport().createInputStream());
+        assertTrue(String.format("Expected at least %d characters; only saw %d", mMinBugreportBytes,
+                data.length()), data.length() >= mMinBugreportBytes);
+        // TODO: check the captured report more extensively, perhaps using loganalysis
+    }
+
+    /**
+     * Simple normal case test for
+     * {@link TestDevice#executeShellCommand(String)}.
+     * <p/>
+     * Do a 'shell ls' command, and verify /data and /system are listed in result.
+     */
+    public void testExecuteShellCommand() throws IOException, DeviceNotAvailableException {
+        CLog.i("testExecuteShellCommand");
+        assertSimpleShellCommand();
+    }
+
+    /**
+     * Verify that a simple {@link TestDevice#executeShellCommand(String)} command is successful.
+     */
+    private void assertSimpleShellCommand() throws DeviceNotAvailableException {
+    	// Check for expected contents of device's root directory
+        final String output = mTestDevice.executeShellCommand("ls /");
+        assertTrue(output.contains("data"));
+        assertTrue(output.contains("system"));
+    }
+
+
+    /**
+     * Push and then pull a file from device, and verify contents are as expected.
+     */
+    public void testPushPull_normal() throws IOException, DeviceNotAvailableException {
+        CLog.i("testPushPull");
+        File tmpFile = null;
+        File tmpDestFile = null;
+        String deviceFilePath = null;
+
+        try {
+            tmpFile = createTempTestFile(null);
+            String externalStorePath = mTestDevice.getMountPoint(IDevice.MNT_EXTERNAL_STORAGE);
+            assertNotNull(externalStorePath);
+            deviceFilePath = String.format("%s/%s", externalStorePath, "tmp_testPushPull.txt");
+            // ensure file does not already exist
+            mTestDevice.executeShellCommand(String.format("rm %s", deviceFilePath));
+            assertFalse(String.format("%s exists", deviceFilePath),
+                    mTestDevice.doesFileExist(deviceFilePath));
+
+            assertTrue(mTestDevice.pushFile(tmpFile, deviceFilePath));
+            assertTrue(mTestDevice.doesFileExist(deviceFilePath));
+            tmpDestFile = FileUtil.createTempFile("tmp", "txt");
+            assertTrue(mTestDevice.pullFile(deviceFilePath, tmpDestFile));
+            assertTrue(compareFiles(tmpFile, tmpDestFile));
+        } finally {
+            if (tmpDestFile != null) {
+                tmpDestFile.delete();
+            }
+            if (deviceFilePath != null) {
+                mTestDevice.executeShellCommand(String.format("rm %s", deviceFilePath));
+            }
+        }
+    }
+
+    /**
+     * Push and then pull a file from device, and verify contents are as expected.
+     * <p />
+     * This variant of the test uses "${EXTERNAL_STORAGE}" in the pathname.
+     */
+    public void testPushPull_extStorageVariable() throws IOException, DeviceNotAvailableException {
+        CLog.i("testPushPull");
+        File tmpFile = null;
+        File tmpDestFile = null;
+        File tmpDestFile2 = null;
+        String deviceFilePath = null;
+        final String filename = "tmp_testPushPull.txt";
+
+        try {
+            tmpFile = createTempTestFile(null);
+            String externalStorePath = "${EXTERNAL_STORAGE}";
+            assertNotNull(externalStorePath);
+            deviceFilePath = String.format("%s/%s", externalStorePath, filename);
+            // ensure file does not already exist
+            mTestDevice.executeShellCommand(String.format("rm %s", deviceFilePath));
+            assertFalse(String.format("%s exists", deviceFilePath),
+                    mTestDevice.doesFileExist(deviceFilePath));
+
+            assertTrue(mTestDevice.pushFile(tmpFile, deviceFilePath));
+            assertTrue(mTestDevice.doesFileExist(deviceFilePath));
+            tmpDestFile = FileUtil.createTempFile("tmp", "txt");
+            assertTrue(mTestDevice.pullFile(deviceFilePath, tmpDestFile));
+            assertTrue(compareFiles(tmpFile, tmpDestFile));
+
+            tmpDestFile2 = mTestDevice.pullFileFromExternal(filename);
+            assertNotNull(tmpDestFile2);
+            assertTrue(compareFiles(tmpFile, tmpDestFile2));
+        } finally {
+            if (tmpDestFile != null) {
+                tmpDestFile.delete();
+            }
+            if (tmpDestFile2 != null) {
+                tmpDestFile2.delete();
+            }
+            if (deviceFilePath != null) {
+                mTestDevice.executeShellCommand(String.format("rm %s", deviceFilePath));
+            }
+        }
+    }
+
+    /**
+     * Test pulling a file from device that does not exist.
+     * <p/>
+     * Expect {@link TestDevice#pullFile(String)} to return <code>false</code>
+     */
+    public void testPull_noexist() throws IOException, DeviceNotAvailableException {
+        CLog.i("testPull_noexist");
+
+        // make sure the root path is valid
+        String externalStorePath =  mTestDevice.getMountPoint(IDevice.MNT_EXTERNAL_STORAGE);
+        assertNotNull(externalStorePath);
+        String deviceFilePath = String.format("%s/%s", externalStorePath, "thisfiledoesntexist");
+        assertFalse(String.format("%s exists", deviceFilePath),
+                mTestDevice.doesFileExist(deviceFilePath));
+        assertNull(mTestDevice.pullFile(deviceFilePath));
+    }
+
+    private File createTempTestFile(File dir) throws IOException {
+        File tmpFile = null;
+        try {
+            final String fileContents = "this is the test file contents";
+            tmpFile = FileUtil.createTempFile("tmp", ".txt", dir);
+            FileUtil.writeToFile(fileContents, tmpFile);
+            return tmpFile;
+        } catch (IOException e) {
+            if (tmpFile != null) {
+                tmpFile.delete();
+            }
+            throw e;
+        }
+    }
+
+    /**
+     * Utility method to do byte-wise content comparison of two files.
+     */
+    private boolean compareFiles(File file1, File file2) throws IOException {
+        BufferedInputStream stream1 = null;
+        BufferedInputStream stream2 = null;
+
+        try {
+            stream1 = new BufferedInputStream(new FileInputStream(file1));
+            stream2 = new BufferedInputStream(new FileInputStream(file2));
+            boolean eof = false;
+            while (!eof) {
+                int byte1 = stream1.read();
+                int byte2 = stream2.read();
+                if (byte1 != byte2) {
+                    return false;
+                }
+                eof = byte1 == -1;
+            }
+            return true;
+        } finally {
+            if (stream1 != null) {
+                stream1.close();
+            }
+            if (stream2 != null) {
+                stream2.close();
+            }
+        }
+    }
+
+    /**
+     * Test syncing a single file using {@link TestDevice#syncFiles(File, String)}.
+     */
+    public void testSyncFiles_normal() throws Exception {
+        doTestSyncFiles(mTestDevice.getMountPoint(IDevice.MNT_EXTERNAL_STORAGE));
+    }
+
+    /**
+     * Test syncing a single file using {@link TestDevice#syncFiles(File, String)}.
+     * <p />
+     * This variant of the test uses "${EXTERNAL_STORAGE}" in the pathname.
+     */
+    public void testSyncFiles_extStorageVariable() throws Exception {
+        doTestSyncFiles("${EXTERNAL_STORAGE}");
+    }
+
+    /**
+     * Test syncing a single file using {@link TestDevice#syncFiles(File, String)}.
+     */
+    public void doTestSyncFiles(String externalStorePath) throws Exception {
+        String expectedDeviceFilePath = null;
+
+        // create temp dir with one temp file
+        File tmpDir = FileUtil.createTempDir("tmp");
+        try {
+            File tmpFile = createTempTestFile(tmpDir);
+            // set last modified to 10 minutes ago
+            tmpFile.setLastModified(System.currentTimeMillis() - 10*60*1000);
+            assertNotNull(externalStorePath);
+            expectedDeviceFilePath = String.format("%s/%s/%s", externalStorePath,
+                    tmpDir.getName(), tmpFile.getName());
+
+            assertTrue(mTestDevice.syncFiles(tmpDir, externalStorePath));
+            assertTrue(mTestDevice.doesFileExist(expectedDeviceFilePath));
+
+            // get 'ls -l' attributes of file which includes timestamp
+            String origTmpFileStamp = mTestDevice.executeShellCommand(String.format("ls -l %s",
+                    expectedDeviceFilePath));
+            // now create another file and verify that is synced
+            File tmpFile2 = createTempTestFile(tmpDir);
+            tmpFile2.setLastModified(System.currentTimeMillis() - 10*60*1000);
+            assertTrue(mTestDevice.syncFiles(tmpDir, externalStorePath));
+            String expectedDeviceFilePath2 = String.format("%s/%s/%s", externalStorePath,
+                    tmpDir.getName(), tmpFile2.getName());
+            assertTrue(mTestDevice.doesFileExist(expectedDeviceFilePath2));
+
+            // verify 1st file timestamp did not change
+            String unchangedTmpFileStamp = mTestDevice.executeShellCommand(String.format("ls -l %s",
+                    expectedDeviceFilePath));
+            assertEquals(origTmpFileStamp, unchangedTmpFileStamp);
+
+            // now modify 1st file and verify it does change remotely
+            String testString = "blah";
+            FileOutputStream stream = new FileOutputStream(tmpFile);
+            stream.write(testString.getBytes());
+            stream.close();
+
+            // adjust 1st file's last-modified timestamp according to persist.sys.timezone
+            String deviceTimezone = mTestDevice.getProperty("persist.sys.timezone");
+            if (deviceTimezone != null) {
+                TimeZone tz = TimeZone.getTimeZone(deviceTimezone);
+                long timestamp = tmpFile.lastModified() + tz.getRawOffset();
+                if (tz.observesDaylightTime()) {
+                    timestamp += tz.getDSTSavings();
+                }
+                tmpFile.setLastModified(timestamp);
+            }
+
+            assertTrue(mTestDevice.syncFiles(tmpDir, externalStorePath));
+            String tmpFileContents = mTestDevice.executeShellCommand(String.format("cat %s",
+                    expectedDeviceFilePath));
+            assertTrue(tmpFileContents.contains(testString));
+        } finally {
+            if (expectedDeviceFilePath != null && externalStorePath != null) {
+                // note that expectedDeviceFilePath has externalStorePath prepended at definition
+                mTestDevice.executeShellCommand(String.format("rm -r %s", expectedDeviceFilePath));
+            }
+            FileUtil.recursiveDelete(tmpDir);
+        }
+    }
+
+    /**
+     * Test pushing a directory
+     */
+    public void testPushDir() throws IOException, DeviceNotAvailableException {
+        String expectedDeviceFilePath = null;
+        String externalStorePath = null;
+        File rootDir = FileUtil.createTempDir("tmp");
+        // create temp dir with one temp file
+        try {
+            File tmpDir = FileUtil.createTempDir("tmp", rootDir);
+            File tmpFile = createTempTestFile(tmpDir);
+            externalStorePath = mTestDevice.getMountPoint(IDevice.MNT_EXTERNAL_STORAGE);
+            assertNotNull(externalStorePath);
+            expectedDeviceFilePath = String.format("%s/%s/%s", externalStorePath,
+                    tmpDir.getName(), tmpFile.getName());
+
+            assertTrue(mTestDevice.pushDir(rootDir, externalStorePath));
+            assertTrue(mTestDevice.doesFileExist(expectedDeviceFilePath));
+
+        } finally {
+            if (expectedDeviceFilePath != null && externalStorePath != null) {
+                mTestDevice.executeShellCommand(String.format("rm -r %s/%s", externalStorePath,
+                        expectedDeviceFilePath));
+            }
+            FileUtil.recursiveDelete(rootDir);
+        }
+    }
+
+    /**
+     * Basic test for {@link TestDevice#getScreenshot()}.
+     * <p/>
+     * Grab a screenshot and perform a cursory size check to ensure its valid.
+     */
+    public void testGetScreenshot() throws DeviceNotAvailableException, IOException {
+        InputStreamSource source = getDevice().getScreenshot();
+        assertNotNull(source);
+        InputStream inputStream = source.createInputStream();
+        try {
+            BufferedImage screenshotImage = ImageIO.read(inputStream);
+            CLog.i("testGetScreenshot w=%d, h=%d",
+                    screenshotImage.getWidth(), screenshotImage.getHeight());
+            assertTrue(screenshotImage.getWidth() > 0);
+            assertTrue(screenshotImage.getHeight() > 0);
+        } finally {
+            StreamUtil.cancel(source);
+            StreamUtil.close(inputStream);
+        }
+    }
+
+    /**
+     * Basic test for {@link TestDevice#getLogcat(long)}.
+     * <p/>
+     * Dumps a bunch of messages to logcat, calls getLogcat(), and verifies size of capture file is
+     * equal to provided data.
+     */
+    public void testGetLogcat_size() throws DeviceNotAvailableException, IOException {
+        CLog.i("testGetLogcat_size");
+        for (int i = 0; i < 100; i++) {
+            getDevice().executeShellCommand(String.format("log testGetLogcat_size log dump %d", i));
+        }
+        boolean passed = false;
+        int retry = 0;
+        while (!passed) {
+            // sleep a small amount of time to ensure last log message makes it into capture
+            RunUtil.getDefault().sleep(10);
+            InputStreamSource source = getDevice().getLogcat(100 * 1024);
+            assertNotNull(source);
+            File tmpTxtFile = FileUtil.createTempFile("logcat", ".txt");
+            try {
+                FileUtil.writeToFile(source.createInputStream(), tmpTxtFile);
+                CLog.i("Created file at %s", tmpTxtFile.getAbsolutePath());
+                // ensure last log message is present in log
+                String s = FileUtil.readStringFromFile(tmpTxtFile);
+                if (s.contains("testGetLogcat_size log dump 99")) {
+                    passed = true;
+                }
+            } finally {
+                FileUtil.deleteFile(tmpTxtFile);
+                source.cancel();
+            }
+            retry++;
+            if ((retry > 100) && !passed) {
+                fail("last log message is not in captured logcat");
+            }
+        }
+    }
+}
diff --git a/hostsidetests/aadb/src/android/aadb/cts/TestDeviceStressTest.java b/hostsidetests/aadb/src/android/aadb/cts/TestDeviceStressTest.java
new file mode 100644
index 0000000..f5872a7
--- /dev/null
+++ b/hostsidetests/aadb/src/android/aadb/cts/TestDeviceStressTest.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.aadb.cts;
+
+import com.android.ddmlib.IDevice;
+import com.android.ddmlib.Log;
+import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
+import com.android.tradefed.config.Option;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.result.CollectingTestListener;
+import com.android.tradefed.testtype.DeviceTestCase;
+import com.android.tradefed.util.FileUtil;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * Long running functional tests for {@link TestDevice} that verify an operation can be run
+ * many times in sequence
+ * <p/>
+ * Requires a physical device to be connected.
+ */
+public class TestDeviceStressTest extends DeviceTestCase {
+
+    private int mIterations = 25;
+
+    private static final String LOG_TAG = "TestDeviceStressTest";
+    private static final int TEST_FILE_COUNT= 200;
+    private ITestDevice mTestDevice;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mTestDevice = getDevice();
+    }
+
+    private File createTempTestFiles() throws IOException {
+        File tmpDir = null;
+        File tmpFile = null;
+
+        tmpDir = FileUtil.createTempDir("testDir");
+
+        final String fileContents = "this is the test file contents";
+        for (int i = 0; i < TEST_FILE_COUNT; i++) {
+            tmpFile = FileUtil.createTempFile(String.format("tmp_%d", i), ".txt", tmpDir);
+            FileUtil.writeToFile(fileContents, tmpFile);
+        }
+        return tmpDir;
+
+    }
+
+    /**
+     * Stress test to push a folder which contains 200 text file to device
+     * internal storage.
+     */
+    public void testPushFolderWithManyFiles() throws IOException, DeviceNotAvailableException {
+        File tmpDir = null;
+        String deviceFilePath = null;
+        String externalStorePath = mTestDevice.getMountPoint(IDevice.MNT_EXTERNAL_STORAGE);
+        assertNotNull(externalStorePath);
+        deviceFilePath = String.format("%s/%s", externalStorePath, "testDir");
+
+        // start the stress test
+        try {
+            // Create the test folder and make sure the test folder doesn't exist in
+            // device before the test start.
+            tmpDir = createTempTestFiles();
+            for (int i = 0; i < mIterations; i++) {
+                mTestDevice.executeShellCommand(String.format("rm -r %s", deviceFilePath));
+                assertFalse(String.format("%s exists", deviceFilePath),
+                        mTestDevice.doesFileExist(deviceFilePath));
+                assertTrue(mTestDevice.pushDir(tmpDir, deviceFilePath));
+                assertTrue(mTestDevice.doesFileExist(deviceFilePath));
+            }
+        } finally {
+            if (tmpDir != null) {
+                FileUtil.recursiveDelete(tmpDir);
+            }
+            mTestDevice.executeShellCommand(String.format("rm -r %s", deviceFilePath));
+            assertFalse(String.format("%s exists", deviceFilePath),
+                    mTestDevice.doesFileExist(deviceFilePath));
+        }
+    }
+}
diff --git a/hostsidetests/aadb/src/com/android/cts/aadb/TestDeviceFuncTest.java b/hostsidetests/aadb/src/com/android/cts/aadb/TestDeviceFuncTest.java
deleted file mode 100644
index b0fb1fb..0000000
--- a/hostsidetests/aadb/src/com/android/cts/aadb/TestDeviceFuncTest.java
+++ /dev/null
@@ -1,404 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.cts.aadb;
-
-import com.android.ddmlib.IDevice;
-import com.android.ddmlib.Log;
-import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.IFileEntry;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.result.CollectingTestListener;
-import com.android.tradefed.result.InputStreamSource;
-import com.android.tradefed.testtype.DeviceTestCase;
-import com.android.tradefed.util.CommandStatus;
-import com.android.tradefed.util.FileUtil;
-import com.android.tradefed.util.RunUtil;
-import com.android.tradefed.util.StreamUtil;
-
-import java.awt.image.BufferedImage;
-
-import java.io.BufferedInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.InputStream;
-import java.io.IOException;
-import java.util.TimeZone;
-
-import javax.imageio.ImageIO;
-
-/**
- * Functional tests for adb connection
- * <p/>
- * Requires a physical device to be connected.
- */
-public class TestDeviceFuncTest extends DeviceTestCase {
-
-    private static final String LOG_TAG = "TestDeviceFuncTest";
-    private ITestDevice mTestDevice;
-    /** Expect bugreports to be at least a meg. */
-    private static final int mMinBugreportBytes = 1024 * 1024;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mTestDevice = getDevice();
-    }
-
-    /**
-     * Simple testcase to ensure that the grabbing a bugreport from a real TestDevice works.
-     */
-    public void testBugreport() throws Exception {
-        String data = StreamUtil.getStringFromStream(
-                mTestDevice.getBugreport().createInputStream());
-        assertTrue(String.format("Expected at least %d characters; only saw %d", mMinBugreportBytes,
-                data.length()), data.length() >= mMinBugreportBytes);
-        // TODO: check the captured report more extensively, perhaps using loganalysis
-    }
-
-    /**
-     * Simple normal case test for
-     * {@link TestDevice#executeShellCommand(String)}.
-     * <p/>
-     * Do a 'shell ls' command, and verify /data and /system are listed in result.
-     */
-    public void testExecuteShellCommand() throws IOException, DeviceNotAvailableException {
-        Log.i(LOG_TAG, "testExecuteShellCommand");
-        assertSimpleShellCommand();
-    }
-
-    /**
-     * Verify that a simple {@link TestDevice#executeShellCommand(String)} command is successful.
-     */
-    private void assertSimpleShellCommand() throws DeviceNotAvailableException {
-    	// Check for expected contents of device's root directory
-        final String output = mTestDevice.executeShellCommand("ls /");
-        assertTrue(output.contains("data"));
-        assertTrue(output.contains("system"));
-    }
-
-
-    /**
-     * Push and then pull a file from device, and verify contents are as expected.
-     */
-    public void testPushPull_normal() throws IOException, DeviceNotAvailableException {
-        Log.i(LOG_TAG, "testPushPull");
-        File tmpFile = null;
-        File tmpDestFile = null;
-        String deviceFilePath = null;
-
-        try {
-            tmpFile = createTempTestFile(null);
-            String externalStorePath = mTestDevice.getMountPoint(IDevice.MNT_EXTERNAL_STORAGE);
-            assertNotNull(externalStorePath);
-            deviceFilePath = String.format("%s/%s", externalStorePath, "tmp_testPushPull.txt");
-            // ensure file does not already exist
-            mTestDevice.executeShellCommand(String.format("rm %s", deviceFilePath));
-            assertFalse(String.format("%s exists", deviceFilePath),
-                    mTestDevice.doesFileExist(deviceFilePath));
-
-            assertTrue(mTestDevice.pushFile(tmpFile, deviceFilePath));
-            assertTrue(mTestDevice.doesFileExist(deviceFilePath));
-            tmpDestFile = FileUtil.createTempFile("tmp", "txt");
-            assertTrue(mTestDevice.pullFile(deviceFilePath, tmpDestFile));
-            assertTrue(compareFiles(tmpFile, tmpDestFile));
-        } finally {
-            if (tmpDestFile != null) {
-                tmpDestFile.delete();
-            }
-            if (deviceFilePath != null) {
-                mTestDevice.executeShellCommand(String.format("rm %s", deviceFilePath));
-            }
-        }
-    }
-
-    /**
-     * Push and then pull a file from device, and verify contents are as expected.
-     * <p />
-     * This variant of the test uses "${EXTERNAL_STORAGE}" in the pathname.
-     */
-    public void testPushPull_extStorageVariable() throws IOException, DeviceNotAvailableException {
-        Log.i(LOG_TAG, "testPushPull");
-        File tmpFile = null;
-        File tmpDestFile = null;
-        File tmpDestFile2 = null;
-        String deviceFilePath = null;
-        final String filename = "tmp_testPushPull.txt";
-
-        try {
-            tmpFile = createTempTestFile(null);
-            String externalStorePath = "${EXTERNAL_STORAGE}";
-            assertNotNull(externalStorePath);
-            deviceFilePath = String.format("%s/%s", externalStorePath, filename);
-            // ensure file does not already exist
-            mTestDevice.executeShellCommand(String.format("rm %s", deviceFilePath));
-            assertFalse(String.format("%s exists", deviceFilePath),
-                    mTestDevice.doesFileExist(deviceFilePath));
-
-            assertTrue(mTestDevice.pushFile(tmpFile, deviceFilePath));
-            assertTrue(mTestDevice.doesFileExist(deviceFilePath));
-            tmpDestFile = FileUtil.createTempFile("tmp", "txt");
-            assertTrue(mTestDevice.pullFile(deviceFilePath, tmpDestFile));
-            assertTrue(compareFiles(tmpFile, tmpDestFile));
-
-            tmpDestFile2 = mTestDevice.pullFileFromExternal(filename);
-            assertNotNull(tmpDestFile2);
-            assertTrue(compareFiles(tmpFile, tmpDestFile2));
-        } finally {
-            if (tmpDestFile != null) {
-                tmpDestFile.delete();
-            }
-            if (tmpDestFile2 != null) {
-                tmpDestFile2.delete();
-            }
-            if (deviceFilePath != null) {
-                mTestDevice.executeShellCommand(String.format("rm %s", deviceFilePath));
-            }
-        }
-    }
-
-    /**
-     * Test pulling a file from device that does not exist.
-     * <p/>
-     * Expect {@link TestDevice#pullFile(String)} to return <code>false</code>
-     */
-    public void testPull_noexist() throws IOException, DeviceNotAvailableException {
-        Log.i(LOG_TAG, "testPull_noexist");
-
-        // make sure the root path is valid
-        String externalStorePath =  mTestDevice.getMountPoint(IDevice.MNT_EXTERNAL_STORAGE);
-        assertNotNull(externalStorePath);
-        String deviceFilePath = String.format("%s/%s", externalStorePath, "thisfiledoesntexist");
-        assertFalse(String.format("%s exists", deviceFilePath),
-                mTestDevice.doesFileExist(deviceFilePath));
-        assertNull(mTestDevice.pullFile(deviceFilePath));
-    }
-
-    private File createTempTestFile(File dir) throws IOException {
-        File tmpFile = null;
-        try {
-            final String fileContents = "this is the test file contents";
-            tmpFile = FileUtil.createTempFile("tmp", ".txt", dir);
-            FileUtil.writeToFile(fileContents, tmpFile);
-            return tmpFile;
-        } catch (IOException e) {
-            if (tmpFile != null) {
-                tmpFile.delete();
-            }
-            throw e;
-        }
-    }
-
-    /**
-     * Utility method to do byte-wise content comparison of two files.
-     */
-    private boolean compareFiles(File file1, File file2) throws IOException {
-        BufferedInputStream stream1 = null;
-        BufferedInputStream stream2 = null;
-
-        try {
-            stream1 = new BufferedInputStream(new FileInputStream(file1));
-            stream2 = new BufferedInputStream(new FileInputStream(file2));
-            boolean eof = false;
-            while (!eof) {
-                int byte1 = stream1.read();
-                int byte2 = stream2.read();
-                if (byte1 != byte2) {
-                    return false;
-                }
-                eof = byte1 == -1;
-            }
-            return true;
-        } finally {
-            if (stream1 != null) {
-                stream1.close();
-            }
-            if (stream2 != null) {
-                stream2.close();
-            }
-        }
-    }
-
-    /**
-     * Test syncing a single file using {@link TestDevice#syncFiles(File, String)}.
-     */
-    public void testSyncFiles_normal() throws Exception {
-        doTestSyncFiles(mTestDevice.getMountPoint(IDevice.MNT_EXTERNAL_STORAGE));
-    }
-
-    /**
-     * Test syncing a single file using {@link TestDevice#syncFiles(File, String)}.
-     * <p />
-     * This variant of the test uses "${EXTERNAL_STORAGE}" in the pathname.
-     */
-    public void testSyncFiles_extStorageVariable() throws Exception {
-        doTestSyncFiles("${EXTERNAL_STORAGE}");
-    }
-
-    /**
-     * Test syncing a single file using {@link TestDevice#syncFiles(File, String)}.
-     */
-    public void doTestSyncFiles(String externalStorePath) throws Exception {
-        String expectedDeviceFilePath = null;
-
-        // create temp dir with one temp file
-        File tmpDir = FileUtil.createTempDir("tmp");
-        try {
-            File tmpFile = createTempTestFile(tmpDir);
-            // set last modified to 10 minutes ago
-            tmpFile.setLastModified(System.currentTimeMillis() - 10*60*1000);
-            assertNotNull(externalStorePath);
-            expectedDeviceFilePath = String.format("%s/%s/%s", externalStorePath,
-                    tmpDir.getName(), tmpFile.getName());
-
-            assertTrue(mTestDevice.syncFiles(tmpDir, externalStorePath));
-            assertTrue(mTestDevice.doesFileExist(expectedDeviceFilePath));
-
-            // get 'ls -l' attributes of file which includes timestamp
-            String origTmpFileStamp = mTestDevice.executeShellCommand(String.format("ls -l %s",
-                    expectedDeviceFilePath));
-            // now create another file and verify that is synced
-            File tmpFile2 = createTempTestFile(tmpDir);
-            tmpFile2.setLastModified(System.currentTimeMillis() - 10*60*1000);
-            assertTrue(mTestDevice.syncFiles(tmpDir, externalStorePath));
-            String expectedDeviceFilePath2 = String.format("%s/%s/%s", externalStorePath,
-                    tmpDir.getName(), tmpFile2.getName());
-            assertTrue(mTestDevice.doesFileExist(expectedDeviceFilePath2));
-
-            // verify 1st file timestamp did not change
-            String unchangedTmpFileStamp = mTestDevice.executeShellCommand(String.format("ls -l %s",
-                    expectedDeviceFilePath));
-            assertEquals(origTmpFileStamp, unchangedTmpFileStamp);
-
-            // now modify 1st file and verify it does change remotely
-            String testString = "blah";
-            FileOutputStream stream = new FileOutputStream(tmpFile);
-            stream.write(testString.getBytes());
-            stream.close();
-
-            // adjust 1st file's last-modified timestamp according to persist.sys.timezone
-            String deviceTimezone = mTestDevice.getProperty("persist.sys.timezone");
-            if (deviceTimezone != null) {
-                TimeZone tz = TimeZone.getTimeZone(deviceTimezone);
-                long timestamp = tmpFile.lastModified() + tz.getRawOffset();
-                if (tz.observesDaylightTime()) {
-                    timestamp += tz.getDSTSavings();
-                }
-                tmpFile.setLastModified(timestamp);
-            }
-
-            assertTrue(mTestDevice.syncFiles(tmpDir, externalStorePath));
-            String tmpFileContents = mTestDevice.executeShellCommand(String.format("cat %s",
-                    expectedDeviceFilePath));
-            assertTrue(tmpFileContents.contains(testString));
-        } finally {
-            if (expectedDeviceFilePath != null && externalStorePath != null) {
-                // note that expectedDeviceFilePath has externalStorePath prepended at definition
-                mTestDevice.executeShellCommand(String.format("rm -r %s", expectedDeviceFilePath));
-            }
-            FileUtil.recursiveDelete(tmpDir);
-        }
-    }
-
-    /**
-     * Test pushing a directory
-     */
-    public void testPushDir() throws IOException, DeviceNotAvailableException {
-        String expectedDeviceFilePath = null;
-        String externalStorePath = null;
-        File rootDir = FileUtil.createTempDir("tmp");
-        // create temp dir with one temp file
-        try {
-            File tmpDir = FileUtil.createTempDir("tmp", rootDir);
-            File tmpFile = createTempTestFile(tmpDir);
-            externalStorePath = mTestDevice.getMountPoint(IDevice.MNT_EXTERNAL_STORAGE);
-            assertNotNull(externalStorePath);
-            expectedDeviceFilePath = String.format("%s/%s/%s", externalStorePath,
-                    tmpDir.getName(), tmpFile.getName());
-
-            assertTrue(mTestDevice.pushDir(rootDir, externalStorePath));
-            assertTrue(mTestDevice.doesFileExist(expectedDeviceFilePath));
-
-        } finally {
-            if (expectedDeviceFilePath != null && externalStorePath != null) {
-                mTestDevice.executeShellCommand(String.format("rm -r %s/%s", externalStorePath,
-                        expectedDeviceFilePath));
-            }
-            FileUtil.recursiveDelete(rootDir);
-        }
-    }
-
-    /**
-     * Basic test for {@link TestDevice#getScreenshot()}.
-     * <p/>
-     * Grab a screenshot and perform a cursory size check to ensure its valid.
-     */
-    public void testGetScreenshot() throws DeviceNotAvailableException, IOException {
-        InputStreamSource source = getDevice().getScreenshot();
-        assertNotNull(source);
-        InputStream inputStream = source.createInputStream();
-        try {
-            BufferedImage screenshotImage = ImageIO.read(inputStream);
-            CLog.i(LOG_TAG, "testGetScreenshot w=%d, h=%d",
-                    screenshotImage.getWidth(), screenshotImage.getHeight());
-            assertTrue(screenshotImage.getWidth() > 0);
-            assertTrue(screenshotImage.getHeight() > 0);
-        } finally {
-            StreamUtil.cancel(source);
-            StreamUtil.close(inputStream);
-        }
-    }
-
-    /**
-     * Basic test for {@link TestDevice#getLogcat(long)}.
-     * <p/>
-     * Dumps a bunch of messages to logcat, calls getLogcat(), and verifies size of capture file is
-     * equal to provided data.
-     */
-    public void testGetLogcat_size() throws DeviceNotAvailableException, IOException {
-        CLog.i(LOG_TAG, "testGetLogcat_size");
-        for (int i = 0; i < 100; i++) {
-            getDevice().executeShellCommand(String.format("log testGetLogcat_size log dump %d", i));
-        }
-        boolean passed = false;
-        int retry = 0;
-        while (!passed) {
-            // sleep a small amount of time to ensure last log message makes it into capture
-            RunUtil.getDefault().sleep(10);
-            InputStreamSource source = getDevice().getLogcat(100 * 1024);
-            assertNotNull(source);
-            File tmpTxtFile = FileUtil.createTempFile("logcat", ".txt");
-            try {
-                FileUtil.writeToFile(source.createInputStream(), tmpTxtFile);
-                CLog.i("Created file at %s", tmpTxtFile.getAbsolutePath());
-                // ensure last log message is present in log
-                String s = FileUtil.readStringFromFile(tmpTxtFile);
-                if (s.contains("testGetLogcat_size log dump 99")) {
-                    passed = true;
-                }
-            } finally {
-                FileUtil.deleteFile(tmpTxtFile);
-                source.cancel();
-            }
-            retry++;
-            if ((retry > 100) && !passed) {
-                fail("last log message is not in captured logcat");
-            }
-        }
-    }
-}
diff --git a/hostsidetests/aadb/src/com/android/cts/aadb/TestDeviceStressTest.java b/hostsidetests/aadb/src/com/android/cts/aadb/TestDeviceStressTest.java
deleted file mode 100644
index 2c6fcef..0000000
--- a/hostsidetests/aadb/src/com/android/cts/aadb/TestDeviceStressTest.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.cts.aadb;
-
-import com.android.ddmlib.IDevice;
-import com.android.ddmlib.Log;
-import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
-import com.android.tradefed.config.Option;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.result.CollectingTestListener;
-import com.android.tradefed.testtype.DeviceTestCase;
-import com.android.tradefed.util.FileUtil;
-
-import java.io.File;
-import java.io.IOException;
-
-/**
- * Long running functional tests for {@link TestDevice} that verify an operation can be run
- * many times in sequence
- * <p/>
- * Requires a physical device to be connected.
- */
-public class TestDeviceStressTest extends DeviceTestCase {
-
-    private int mIterations = 25;
-
-    private static final String LOG_TAG = "TestDeviceStressTest";
-    private static final int TEST_FILE_COUNT= 200;
-    private ITestDevice mTestDevice;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mTestDevice = getDevice();
-    }
-
-    private File createTempTestFiles() throws IOException {
-        File tmpDir = null;
-        File tmpFile = null;
-
-        tmpDir = FileUtil.createTempDir("testDir");
-
-        final String fileContents = "this is the test file contents";
-        for (int i = 0; i < TEST_FILE_COUNT; i++) {
-            tmpFile = FileUtil.createTempFile(String.format("tmp_%d", i), ".txt", tmpDir);
-            FileUtil.writeToFile(fileContents, tmpFile);
-        }
-        return tmpDir;
-
-    }
-
-    /**
-     * Stress test to push a folder which contains 200 text file to device
-     * internal storage.
-     */
-    public void testPushFolderWithManyFiles() throws IOException, DeviceNotAvailableException {
-        File tmpDir = null;
-        String deviceFilePath = null;
-        String externalStorePath = mTestDevice.getMountPoint(IDevice.MNT_EXTERNAL_STORAGE);
-        assertNotNull(externalStorePath);
-        deviceFilePath = String.format("%s/%s", externalStorePath, "testDir");
-
-        // start the stress test
-        try {
-            // Create the test folder and make sure the test folder doesn't exist in
-            // device before the test start.
-            tmpDir = createTempTestFiles();
-            for (int i = 0; i < mIterations; i++) {
-                mTestDevice.executeShellCommand(String.format("rm -r %s", deviceFilePath));
-                assertFalse(String.format("%s exists", deviceFilePath),
-                        mTestDevice.doesFileExist(deviceFilePath));
-                assertTrue(mTestDevice.pushDir(tmpDir, deviceFilePath));
-                assertTrue(mTestDevice.doesFileExist(deviceFilePath));
-            }
-        } finally {
-            if (tmpDir != null) {
-                FileUtil.recursiveDelete(tmpDir);
-            }
-            mTestDevice.executeShellCommand(String.format("rm -r %s", deviceFilePath));
-            assertFalse(String.format("%s exists", deviceFilePath),
-                    mTestDevice.doesFileExist(deviceFilePath));
-        }
-    }
-}
diff --git a/hostsidetests/abioverride/Android.mk b/hostsidetests/abioverride/Android.mk
new file mode 100644
index 0000000..f77303b
--- /dev/null
+++ b/hostsidetests/abioverride/Android.mk
@@ -0,0 +1,36 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_MODULE := CtsAbiOverrideHostTestCases
+
+LOCAL_MODULE_TAGS := tests
+
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_CTS_TEST_PACKAGE := android.host.abioverride
+
+LOCAL_STATIC_JAVA_LIBRARIES := cts-migration-lib
+
+LOCAL_JAVA_LIBRARIES := compatibility-host-util cts-tradefed tradefed-prebuilt
+
+include $(BUILD_CTS_HOST_JAVA_LIBRARY)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/hostsidetests/abioverride/AndroidTest.xml b/hostsidetests/abioverride/AndroidTest.xml
new file mode 100644
index 0000000..7819f9b
--- /dev/null
+++ b/hostsidetests/abioverride/AndroidTest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS AbiOverride host test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsAbiOverrideTestApp.apk" />
+    </target_preparer>
+    <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
+        <option name="jar" value="CtsAbiOverrideHostTestCases.jar" />
+    </test>
+</configuration>
diff --git a/hostsidetests/abioverride/app/Android.mk b/hostsidetests/abioverride/app/Android.mk
new file mode 100755
index 0000000..56393c5
--- /dev/null
+++ b/hostsidetests/abioverride/app/Android.mk
@@ -0,0 +1,45 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+# Don't include this package in any target
+LOCAL_MODULE_TAGS := tests
+# When built, explicitly put it in the data partition.
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_DEX_PREOPT := false
+
+LOCAL_PROGUARD_ENABLED := disabled
+
+LOCAL_MULTILIB := both
+
+LOCAL_STATIC_JAVA_LIBRARIES := compatibility-device-util ctsdeviceutil ctstestrunner
+
+LOCAL_JNI_SHARED_LIBRARIES := libctsabioverride
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_PACKAGE_NAME := CtsAbiOverrideTestApp
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_PACKAGE)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/hostsidetests/abioverride/app/AndroidManifest.xml b/hostsidetests/abioverride/app/AndroidManifest.xml
new file mode 100755
index 0000000..c42d3a8
--- /dev/null
+++ b/hostsidetests/abioverride/app/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.abioverride.app">
+
+    <application android:use32bitAbi="true" android:multiArch="true">
+        <activity android:name=".AbiOverrideActivity" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
diff --git a/hostsidetests/abioverride/app/jni/Android.mk b/hostsidetests/abioverride/app/jni/Android.mk
new file mode 100644
index 0000000..c500100
--- /dev/null
+++ b/hostsidetests/abioverride/app/jni/Android.mk
@@ -0,0 +1,34 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libctsabioverride
+
+# Don't include this package in any configuration by default.
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := CtsAbiOverrideJniOnLoad.cpp
+
+LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
+
+# Ignore unused parameters.
+LOCAL_CFLAGS += -Wno-unused-parameter
+
+LOCAL_SHARED_LIBRARIES := libnativehelper_compat_libc++ liblog libdl
+LOCAL_CXX_STL := none
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/hostsidetests/abioverride/app/jni/CtsAbiOverrideJniOnLoad.cpp b/hostsidetests/abioverride/app/jni/CtsAbiOverrideJniOnLoad.cpp
new file mode 100644
index 0000000..57c2bb3
--- /dev/null
+++ b/hostsidetests/abioverride/app/jni/CtsAbiOverrideJniOnLoad.cpp
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 <jni.h>
+
+jint JNI_OnLoad(JavaVM *vm, void *reserved) {
+    return JNI_VERSION_1_4;
+}
diff --git a/hostsidetests/abioverride/app/src/android/abioverride/app/AbiOverrideActivity.java b/hostsidetests/abioverride/app/src/android/abioverride/app/AbiOverrideActivity.java
new file mode 100644
index 0000000..814dcf7
--- /dev/null
+++ b/hostsidetests/abioverride/app/src/android/abioverride/app/AbiOverrideActivity.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.abioverride.app;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.os.Process;
+import android.util.Log;
+
+/**
+ * A simple activity for testing abioverride manifest flag.
+ */
+public class AbiOverrideActivity extends Activity {
+
+    public static final String TEST_STRING = "Is64bit ";
+
+    private static final String TAG = AbiOverrideActivity.class.getSimpleName();
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        Log.i(TAG, TEST_STRING + Process.is64Bit());
+    }
+}
diff --git a/hostsidetests/abioverride/src/android/abioverride/cts/AbiOverrideTest.java b/hostsidetests/abioverride/src/android/abioverride/cts/AbiOverrideTest.java
new file mode 100644
index 0000000..26d35a4
--- /dev/null
+++ b/hostsidetests/abioverride/src/android/abioverride/cts/AbiOverrideTest.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.abioverride.cts;
+
+import com.android.cts.migration.MigrationHelper;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceTestCase;
+import com.android.tradefed.testtype.IBuildReceiver;
+
+import java.io.File;
+import java.util.Scanner;
+
+/**
+ * Test to check the APK runs in 32bit ABI.
+ *
+ * When this test builds, it also builds {@link android.abioverride.app.AbiOverrideActivity}
+ * into an APK which it then installed at runtime and started. The activity simply prints
+ * a message to Logcat and then gets uninstalled. The test verifies that logcat has the right
+ * string.
+ */
+public class AbiOverrideTest extends DeviceTestCase implements IBuildReceiver {
+
+    /**
+     * The package name of the APK.
+     */
+    private static final String PACKAGE = "android.abioverride.app";
+
+    /**
+     * The class name of the main activity in the APK.
+     */
+    private static final String CLASS = "AbiOverrideActivity";
+
+    /**
+     * The class name of the main activity in the APK.
+     */
+    private static final String APK_NAME="CtsAbiOverrideTestApp.apk";
+
+    /**
+     * The command to launch the main activity.
+     */
+    private static final String START_COMMAND = String.format(
+            "am start -W -a android.intent.action.MAIN -n %s/%s.%s", PACKAGE, PACKAGE, CLASS);
+
+
+    private static final String TEST_STRING = "Is64bit ";
+            // android.abioverride.app.AbiOverrideActivity.TEST_STRING;
+
+    private IBuildInfo mBuild;
+
+    @Override
+    public void setBuild(IBuildInfo buildInfo) {
+        mBuild = buildInfo;
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        ITestDevice device = getDevice();
+        device.uninstallPackage(PACKAGE);
+        File app = MigrationHelper.getTestFile(mBuild, APK_NAME);
+        String[] options = {};
+        device.installPackage(app, false, options);
+    }
+
+    /**
+     * Tests the abi is correctly set to 32bit when use32BitAbi is set to true.
+     *
+     * @throws Exception
+     */
+    public void testAbiIs32bit() throws Exception {
+        ITestDevice device = getDevice();
+        // Clear logcat.
+        device.executeAdbCommand("logcat", "-c");
+        // Start the APK and wait for it to complete.
+        device.executeShellCommand(START_COMMAND);
+        // Dump logcat
+        String logs = device.executeAdbCommand("logcat", "-v", "brief", "-d", CLASS + ":I", "*:S");
+        // Search for string.
+        String testString = "";
+        Scanner in = new Scanner(logs);
+        while (in.hasNextLine()) {
+            String line = in.nextLine();
+            if(line.startsWith("I/"+CLASS)) {
+                testString = line.split(":")[1].trim();
+            }
+        }
+        in.close();
+        // Verify that TEST_STRING is actually found in logs.
+        assertTrue("No result found in logs", testString.startsWith(TEST_STRING));
+        // Assert that the result is false
+        assertEquals("Incorrect abi", TEST_STRING + "false", testString);
+    }
+}
diff --git a/hostsidetests/appsecurity/Android.mk b/hostsidetests/appsecurity/Android.mk
index 61f9a4d..258192d 100644
--- a/hostsidetests/appsecurity/Android.mk
+++ b/hostsidetests/appsecurity/Android.mk
@@ -19,11 +19,18 @@
 # Only compile source java files in this apk.
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
-LOCAL_MODULE := CtsAppSecurityTests
+LOCAL_MODULE := CtsAppSecurityHostTestCases
 
-LOCAL_JAVA_LIBRARIES := cts-tradefed tradefed-prebuilt
+LOCAL_JAVA_LIBRARIES := cts-tradefed tradefed-prebuilt compatibility-host-util
 
-LOCAL_CTS_TEST_PACKAGE := android.tests.appsecurity
+LOCAL_STATIC_JAVA_LIBRARIES := cts-migration-lib
+
+LOCAL_JAVA_RESOURCE_DIRS := res
+
+LOCAL_CTS_TEST_PACKAGE := android.appsecurity
+
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
 
 include $(BUILD_CTS_HOST_JAVA_LIBRARY)
 
diff --git a/hostsidetests/appsecurity/AndroidTest.xml b/hostsidetests/appsecurity/AndroidTest.xml
new file mode 100644
index 0000000..d1989e6
--- /dev/null
+++ b/hostsidetests/appsecurity/AndroidTest.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for the CTS App Security host tests">
+    <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
+        <option name="jar" value="CtsAppSecurityHostTestCases.jar" />
+        <option name="runtime-hint" value="20m" />
+    </test>
+</configuration>
diff --git a/hostsidetests/appsecurity/certs/pkgsigverify/dsa-1024.pk8 b/hostsidetests/appsecurity/certs/pkgsigverify/dsa-1024.pk8
new file mode 100644
index 0000000..d500d70
--- /dev/null
+++ b/hostsidetests/appsecurity/certs/pkgsigverify/dsa-1024.pk8
Binary files differ
diff --git a/hostsidetests/appsecurity/certs/pkgsigverify/dsa-1024.x509.pem b/hostsidetests/appsecurity/certs/pkgsigverify/dsa-1024.x509.pem
new file mode 100644
index 0000000..e230eb0
--- /dev/null
+++ b/hostsidetests/appsecurity/certs/pkgsigverify/dsa-1024.x509.pem
@@ -0,0 +1,17 @@
+-----BEGIN CERTIFICATE-----
+MIICsTCCAnGgAwIBAgIJAP6EmkoBF8UoMAkGByqGSM44BAMwEzERMA8GA1UEAwwI
+ZHNhLTEwMjQwHhcNMTYwMzMxMTUyNzEwWhcNNDMwODE3MTUyNzEwWjATMREwDwYD
+VQQDDAhkc2EtMTAyNDCCAbYwggErBgcqhkjOOAQBMIIBHgKBgQCTDpv8gS5Y+Ehl
+oln6WT/MYBnywrc3tWDfnlY+9MpVDdB2+kcB7WrhobW1L+6ayKmlkrTaAFjiMPDf
+bdyA6hy3fDu1teLCb89R0uodfZa3MDXXlmqvBk4Fdw8fYijWI/q175e4Y5sNYO9+
+QZg8bBIZnxxCdbKASJ6NAHc50ts3vwIVAIebRw3HnYOZbo6rPoBmcBOxcZTLAoGA
+ch+0D7JrbqmR1w5S3VBtTnONLiBYnaz1Ri3Pfiw5FHKfJcfFcQopIOLJwfdBmY4b
+FLGV5u7DXeJNp16Nvl4MrsmVjkWs9MZVAp5RqzrN9JhVi4ShpdelyFjdWOXHPbc7
+NNqQpTjdkK23r/tCE6XkvkCiWm7Rt22LMpZA4ePALIoDgYQAAoGAc8SkppDzSUPH
+SpKrhrldRyh5m4wSH14ZE96mlSze9tRoSDo8hsA9/vGLgoN7F+3jYSvj8m42tmNt
+jZJWk7vPkJHC/9qoEGbVBY+aTNYwVJyKDJ07vZB9bLxpjD/yyQlsn7/vZTOS657c
+W2S817RgGGyGcCNRoKNig6i0k9fzE8ajUDBOMB0GA1UdDgQWBBSPwzoIjftVH2ke
+EJXtLq+bB50lzDAfBgNVHSMEGDAWgBSPwzoIjftVH2keEJXtLq+bB50lzDAMBgNV
+HRMEBTADAQH/MAkGByqGSM44BAMDLwAwLAIUH1GQcpqx8/9p9QfhCRMvcxrECM4C
+FH8ZULK91BMaHodbRMUtdxB9kIbL
+-----END CERTIFICATE-----
diff --git a/hostsidetests/appsecurity/certs/pkgsigverify/dsa-2048.pk8 b/hostsidetests/appsecurity/certs/pkgsigverify/dsa-2048.pk8
new file mode 100644
index 0000000..cf63594
--- /dev/null
+++ b/hostsidetests/appsecurity/certs/pkgsigverify/dsa-2048.pk8
Binary files differ
diff --git a/hostsidetests/appsecurity/certs/pkgsigverify/dsa-2048.x509.pem b/hostsidetests/appsecurity/certs/pkgsigverify/dsa-2048.x509.pem
new file mode 100644
index 0000000..705db39
--- /dev/null
+++ b/hostsidetests/appsecurity/certs/pkgsigverify/dsa-2048.x509.pem
@@ -0,0 +1,26 @@
+-----BEGIN CERTIFICATE-----
+MIIEWzCCBAKgAwIBAgIJAK4uYtTAat4+MAkGByqGSM44BAMwEzERMA8GA1UEAwwI
+ZHNhLTIwNDgwHhcNMTYwMzMxMTgzMDAxWhcNNDMwODE3MTgzMDAxWjATMREwDwYD
+VQQDDAhkc2EtMjA0ODCCA0cwggI5BgcqhkjOOAQBMIICLAKCAQEAv2/yUkci8fnZ
+ppepy1kcOTIrbPJTW46Z2jKOWjHCTd1aqRFunz3gllpx/YDgjboNIYZf2jKhk2gi
+MgF+8OT0hEHQGXSofnqRoVljexA2nC3tPhVyjN14pQ7ZJXp/raHh1uCT5K7Lfafc
+8y5Cs180CdfisspANfCp10jFu1D2hKOLfggUA9efN05c0f2yOx/Pm9uEiz6ftLUJ
+UWgcJenx1WUk4Nb1qMOWgg9nKQyDiBxZKoVCH5/XJO0K225w6F4scol2hMdTRlA+
+9TGb5tvHKT+Y+lE7fBbcBSKzLT3pwD/T08ErpsIoHqRPamLGHeuamGzvXLHwI1UN
+cJNGg2nnCwIhAJz9K+Qpgg7sbqRMeRvIf2cuWRWbi4XnYR+IAGqgfYUZAoIBADks
+N3taHUnIvkcxTuEUiCSb+d1KMlvbZiH5zLVIyzi5kZNQW8L/gR23z8T6qngXXnFw
+tcTRcb0TDqR7iYPxsX3/x+jBjiApIgebqpnPdpiEAUfORZX7w6CpCNsp9Kqxb98z
+4PtKE9z/20Q3zKhqlwDm8uSjjT7E5xw/YpV8bg7YuQ5eQ8mkonipNXllf3qmDV48
+see/+QwIeBiL7jTjgeBv5ziL8BY2AYmfOwGKwmK9ERxJpIoxgS+5fFuA2oAQ8CwJ
+UDwwv5Wbz7NVkvljHK1Fh5u26ZHdeLT4qp4F0GamJcikq4MqFco6ToCvp8NoDNMZ
+MOno2k1IvsIwrIbrQJgDggEGAAKCAQEAuxbFbx2H4n4BqfbkC9tjn/Mg3zr4LZgG
+7v3FWpzpkbAcEcFCVIqTmJiRlsuf4ml/t9hflOvarfD6TesSc7gyGCJ/2QiqJcI+
+Vif5AKqZskQFlZ5BUMIMjPFMy1WtTVpEotmdbIOaQif4wQrz6SNFUOAXPBKRTY33
+HOLMoo8FRiZ1+uMu9PlUWYqMhSJg+rm2AQPt06D+JToXREaNkYjN0K97T2MTcUNh
+OWiliH/zFuF8N2s6IlNaCv1Yc4FoYEIRoS07dUxcjrV9KRd0TyU0q++rRPluytJP
+yAoyTIrfwa2SM5JR9RtdBZsPdR9Ckpy4ZKSJqDzTbCIU70zsGgHA4aNQME4wHQYD
+VR0OBBYEFL3koBjVHAySf8Xr196yqDT6VhwSMB8GA1UdIwQYMBaAFL3koBjVHAyS
+f8Xr196yqDT6VhwSMAwGA1UdEwQFMAMBAf8wCQYHKoZIzjgEAwNIADBFAiEAjowh
+laeXA/CUrHt6iH4u6edWGeZzyFGlpWsxssKTMBECIG2tZs/xnZVAtXioiIcH1CXT
+LN5AAzZ8wlNUKSvTc12j
+-----END CERTIFICATE-----
diff --git a/hostsidetests/appsecurity/certs/pkgsigverify/dsa-3072.pk8 b/hostsidetests/appsecurity/certs/pkgsigverify/dsa-3072.pk8
new file mode 100644
index 0000000..f0f8983
--- /dev/null
+++ b/hostsidetests/appsecurity/certs/pkgsigverify/dsa-3072.pk8
Binary files differ
diff --git a/hostsidetests/appsecurity/certs/pkgsigverify/dsa-3072.x509.pem b/hostsidetests/appsecurity/certs/pkgsigverify/dsa-3072.x509.pem
new file mode 100644
index 0000000..0284b13
--- /dev/null
+++ b/hostsidetests/appsecurity/certs/pkgsigverify/dsa-3072.x509.pem
@@ -0,0 +1,34 @@
+-----BEGIN CERTIFICATE-----
+MIIF3DCCBYKgAwIBAgIJAKmpH5wXPDbGMAkGByqGSM44BAMwEzERMA8GA1UEAwwI
+ZHNhLTMwNzIwHhcNMTYwMzMxMTgzMjU2WhcNNDMwODE3MTgzMjU2WjATMREwDwYD
+VQQDDAhkc2EtMzA3MjCCBMcwggM5BgcqhkjOOAQBMIIDLAKCAYEAscwotTL9jjwZ
+CpGRqXVezU9P0zY/wHFYMQB09JjgoCJRm0D9FZzmTnySJa4suwlwoduzgv+pkIkk
+nn0w+hL6LsblRTEuFj11o/fLLAZE4KmdIAPkCcH74HOnws4BwazJLWFtVEv+bdyj
+CmrI2urYWT5uRJwWZmkG4iUnoL/5FUv2pvpSOzu6EO+qFcFcWf3/VrQDaaP3jRRh
+iVCThxvX5xOrO24krrOFlHQufY0A6fHYQqII6EYac6tKTI+ltz121DYH914SHMe8
+0JJYpDVOatjTJADyg1AzHAKsyfTKHHpHbqkgU/CRtALEC1DUyLqQhHvBGpodmqPH
+r9Mbd7pXudw2h6O8uapAsmaFt/YdrSbd37UvhLJyyW0fodTjBTA0WiNs0CLTJL9o
+422Nt1cUDQS1JpsghAzmMWaavq7+QIRhpnMHL47p1jCZvcwMboMlcJwOCjyyZS0F
+fmaD+pEi56Lx+9XDblESM78crb8/lbvuohyrwIJciQmL0hQoKIg1AiEApYT1sROj
+BMB4FIQaS86VKdJ4h9OR13AraES3ba9WV1cCggGAI9LskZ7wcUna6nZyGT4f3bH1
+KSeD3602Yd86NKuB8QGr/QT5L+wFwCuvvI4V8P2lM4wb+q1LrR688f53WS4c0Kin
+/MeN4YtkQBzV4l04Bxrce//EcfQzUPDAr41Fwu2tA0BHE67trxGjNS7SzoFZUiDo
+d/aOZCVilFIay5oF2X8yeNcpTynsxTbGxjxhhgG2tS0fvxhbGF6rl4D0Ddskx6L/
+xjstzu0ADE8FNpDehuKqxzOisNLIJgc1INPQ06AmaUF1Pge74T2AJYPYwqfzArG3
+pj+l2iND0PM7lDeQCgivPAqhYrveoIqJe0NAEu/PiCnOW50hQ4F6dl9lzn9sGXTP
+5KxdR5OyG+Ki+nWTN8h3yOy9ZK7Gh8gUeqE3QVow4+1LhcO19C+X+NM588KbKsq9
+KRP5H4v238g6oF2wgbmPrYvqiwoa1qjHvUX7ZjQuIfrN9+lICflsHKtAtchuUIiO
+b1AWPeaJwAynTn2EeDsVd0e8bm+h+g7ZSDAwUOKuA4IBhgACggGBAJfW6T1BxtZo
+EacqR2TwTi9B3O93Zcj0OzDOn9UMahepcfaF1B3wq9UdJ4PPIC1U27CaEXEJNxgJ
+cIURfFPDXA6pLVEqrGgRX2u0FR1pmHVIxjBpvPJvO954+Hawp+ClU6PKLmxuVZpA
+VeJBx7C8/DU/58J//iuG9B6/mwzPuEoPmnGYMsfVCcEX8yQ2PZXyNGp+KnUygyql
+mMxpE8UXtH6mHYontjiw4Afxqwop3v/bG8eT5FHhpXoQDSN/oeGghDaq9DyIjCqr
+GXZDBvEufLYRgOvnpV6T0oMa9U2W2Trz3HYD6eX09FOhGnMWl9euYrSVRihAKBh1
+72ystvPy2R4wdAA5EQf7EsDdgt/QOMf/AvkaKHMP7DNK5BZxwPQ0KwRkLB+0vaDI
+Mnpu29L6TiixMxI1ihnZbR/U0v8H+/SlSjZaPNRQeuoV9d8t81miUqVSMLcpqNui
+ZljSCtoGfktPAbPyFwGenBkGK5oo0I381KTECMynC0R2P9CQUHegeaNQME4wHQYD
+VR0OBBYEFPRqMyQLPdq0guTx3YKiVxtWN+bPMB8GA1UdIwQYMBaAFPRqMyQLPdq0
+guTx3YKiVxtWN+bPMAwGA1UdEwQFMAMBAf8wCQYHKoZIzjgEAwNJADBGAiEAjcit
+8dFR02elWKoeRAounP9TE2aqDqd5cJXqXn0ssMYCIQCIINjXEYRovfVjDotKelRg
+5k0lmzMmx6Xfz8EgZDLovw==
+-----END CERTIFICATE-----
diff --git a/hostsidetests/appsecurity/certs/pkgsigverify/ec-p256.pk8 b/hostsidetests/appsecurity/certs/pkgsigverify/ec-p256.pk8
new file mode 100644
index 0000000..f781c30
--- /dev/null
+++ b/hostsidetests/appsecurity/certs/pkgsigverify/ec-p256.pk8
Binary files differ
diff --git a/hostsidetests/appsecurity/certs/pkgsigverify/ec-p256.x509.pem b/hostsidetests/appsecurity/certs/pkgsigverify/ec-p256.x509.pem
new file mode 100644
index 0000000..06adcfe
--- /dev/null
+++ b/hostsidetests/appsecurity/certs/pkgsigverify/ec-p256.x509.pem
@@ -0,0 +1,10 @@
+-----BEGIN CERTIFICATE-----
+MIIBbDCCARGgAwIBAgIJAMoPtk37ZudyMAoGCCqGSM49BAMCMBIxEDAOBgNVBAMM
+B2VjLXAyNTYwHhcNMTYwMzMxMTQ1ODA2WhcNNDMwODE3MTQ1ODA2WjASMRAwDgYD
+VQQDDAdlYy1wMjU2MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEpl8RPSLLSROQ
+gwesMe4roOkTi3hfrGU20U6izpDStL/hlLUM3I4Wn1SnOpke8Pp2MpglvgeMx4J0
+BwPaRLTX66NQME4wHQYDVR0OBBYEFNQTNWi5WzAVizIgceqMQ/9bBczIMB8GA1Ud
+IwQYMBaAFNQTNWi5WzAVizIgceqMQ/9bBczIMAwGA1UdEwQFMAMBAf8wCgYIKoZI
+zj0EAwIDSQAwRgIhAPUEoIZsrvAp9BcULFy3E1THn/zR1kBhjfyk8Z4W23jWAiEA
++O6kgpeZwGytCMbT0tLsBeBXQVTnR+oP27gELLZVqt0=
+-----END CERTIFICATE-----
diff --git a/hostsidetests/appsecurity/certs/pkgsigverify/ec-p384.pk8 b/hostsidetests/appsecurity/certs/pkgsigverify/ec-p384.pk8
new file mode 100644
index 0000000..f22507d
--- /dev/null
+++ b/hostsidetests/appsecurity/certs/pkgsigverify/ec-p384.pk8
Binary files differ
diff --git a/hostsidetests/appsecurity/certs/pkgsigverify/ec-p384.x509.pem b/hostsidetests/appsecurity/certs/pkgsigverify/ec-p384.x509.pem
new file mode 100644
index 0000000..9d1403b
--- /dev/null
+++ b/hostsidetests/appsecurity/certs/pkgsigverify/ec-p384.x509.pem
@@ -0,0 +1,11 @@
+-----BEGIN CERTIFICATE-----
+MIIBqTCCAS6gAwIBAgIJAMRWS+CLIsxqMAoGCCqGSM49BAMDMBIxEDAOBgNVBAMM
+B2VjLXAzODQwHhcNMTYwMzMxMTUzMDU3WhcNNDMwODE3MTUzMDU3WjASMRAwDgYD
+VQQDDAdlYy1wMzg0MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE18hjdbk/HXGQNIuF
+xKPMAZO3PQnROO6izB/mHM1BKPpih2/51iMTFKn6KCU9NZt/Q4Z+PpZVLuawEWP/
+uoWwWIj+60vk25z47/Sr0icelSDGt9T9ujiNP6aTA5hc9gypo1AwTjAdBgNVHQ4E
+FgQU981MoejFjh0rbaGXODywOYvB32kwHwYDVR0jBBgwFoAU981MoejFjh0rbaGX
+ODywOYvB32kwDAYDVR0TBAUwAwEB/zAKBggqhkjOPQQDAwNpADBmAjEA/58rXa+F
+mB6JwB89/IAucpNlktjSPrH2tD63BSROvpUpXNy+p+OlJu4sCvY7HnwEAjEA0VWw
+QqUBFLQHFJx1JjMYYfT78V8ylY+Ns1lxrdvs29NNg45MA9uw/ZVMMHgTFNph
+-----END CERTIFICATE-----
diff --git a/hostsidetests/appsecurity/certs/pkgsigverify/ec-p521.pk8 b/hostsidetests/appsecurity/certs/pkgsigverify/ec-p521.pk8
new file mode 100644
index 0000000..9c75e4c
--- /dev/null
+++ b/hostsidetests/appsecurity/certs/pkgsigverify/ec-p521.pk8
Binary files differ
diff --git a/hostsidetests/appsecurity/certs/pkgsigverify/ec-p521.x509.pem b/hostsidetests/appsecurity/certs/pkgsigverify/ec-p521.x509.pem
new file mode 100644
index 0000000..a9b8194
--- /dev/null
+++ b/hostsidetests/appsecurity/certs/pkgsigverify/ec-p521.x509.pem
@@ -0,0 +1,13 @@
+-----BEGIN CERTIFICATE-----
+MIIB8zCCAVSgAwIBAgIJAOxXdFsvm3YiMAoGCCqGSM49BAMEMBIxEDAOBgNVBAMM
+B2VjLXA1MjEwHhcNMTYwMzMxMTUzMTIyWhcNNDMwODE3MTUzMTIyWjASMRAwDgYD
+VQQDDAdlYy1wNTIxMIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQAYX95sSjPEQqg
+yLD04tNUyq9y/w8seblOpfqa/Amx6H4GFdrjGXX0YTfXKr9GhAyIyQSnNrIg0zDl
+WQUbBPRW4CYBLFOg1pUn1NBhKFD4NtO1KWvYtNOYDegFjRCPB0p+fEXDbq8QFDYv
+lh+NZUJ16+ih8XNIf1C29xuLEqN6oKOnAvajUDBOMB0GA1UdDgQWBBT/Ra3kz60g
+Q7tYk3byZckcLabt8TAfBgNVHSMEGDAWgBT/Ra3kz60gQ7tYk3byZckcLabt8TAM
+BgNVHRMEBTADAQH/MAoGCCqGSM49BAMEA4GMADCBiAJCAP39hYLsWk2H84oEw+HJ
+qGGjexhqeD3vSO1mWhopripE/81oy3yV10puYoJe11xDSfcDj2VfNCHazuXO3kSx
+GA/1AkIBLUJxp/WYbYzhBGKr6lcxczKI/wuMfkZ6vL+0EMJVA/2uEoeqvnl7Bsdk
+icyaOBNEADijuVdaPPIWzKClt9OaVxE=
+-----END CERTIFICATE-----
diff --git a/hostsidetests/appsecurity/certs/pkgsigverify/rsa-1024.pk8 b/hostsidetests/appsecurity/certs/pkgsigverify/rsa-1024.pk8
new file mode 100644
index 0000000..7b4beee
--- /dev/null
+++ b/hostsidetests/appsecurity/certs/pkgsigverify/rsa-1024.pk8
Binary files differ
diff --git a/hostsidetests/appsecurity/certs/pkgsigverify/rsa-1024.x509.pem b/hostsidetests/appsecurity/certs/pkgsigverify/rsa-1024.x509.pem
new file mode 100644
index 0000000..9498ec5
--- /dev/null
+++ b/hostsidetests/appsecurity/certs/pkgsigverify/rsa-1024.x509.pem
@@ -0,0 +1,13 @@
+-----BEGIN CERTIFICATE-----
+MIIB9DCCAV2gAwIBAgIJAP0KtYjhFu3IMA0GCSqGSIb3DQEBCwUAMBMxETAPBgNV
+BAMMCHJzYS0xMDI0MB4XDTE2MDMzMTE2MTQ0M1oXDTQzMDgxNzE2MTQ0M1owEzER
+MA8GA1UEAwwIcnNhLTEwMjQwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOOP
+r4Y+uCAihcVjey8JmdjyfhZXplVf3HnOQfvWcY97nKnJ7L977QiWajIn7iZRAdVX
+PamVrEbaU6uklgcJFG/qirtscOf6fMBf6GaP2PAhQG89MQnUt9rAjxUAakzWOBTz
+bH0gHRDEGQ30LCA1oSlbLldHz+zBKSC7nsSKYp+9AgMBAAGjUDBOMB0GA1UdDgQW
+BBT1x0TcWRB4i9JnU5pvRtrEv+95OTAfBgNVHSMEGDAWgBT1x0TcWRB4i9JnU5pv
+RtrEv+95OTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4GBAKs024CvDYFv
+rj3GTXM8A9Jslg/86WukzEl/+PXDjbPljNV24RSsFVW5gO0ps6Q/EBkbllJP7xNO
+XmOUDyqUcvcwC1zzySqs8kJcF5GCuRXajy4KiEiA5VRmVUSShhnkYX7g1yXkhWrP
+Ps1fQArqHx84+naFSh9kVqu54QIykS7z
+-----END CERTIFICATE-----
diff --git a/hostsidetests/appsecurity/certs/pkgsigverify/rsa-16384.pk8 b/hostsidetests/appsecurity/certs/pkgsigverify/rsa-16384.pk8
new file mode 100644
index 0000000..c8d2793
--- /dev/null
+++ b/hostsidetests/appsecurity/certs/pkgsigverify/rsa-16384.pk8
Binary files differ
diff --git a/hostsidetests/appsecurity/certs/pkgsigverify/rsa-16384.x509.pem b/hostsidetests/appsecurity/certs/pkgsigverify/rsa-16384.x509.pem
new file mode 100644
index 0000000..22b6148
--- /dev/null
+++ b/hostsidetests/appsecurity/certs/pkgsigverify/rsa-16384.x509.pem
@@ -0,0 +1,93 @@
+-----BEGIN CERTIFICATE-----
+MIIQ+zCCCOOgAwIBAgIJAOd3bpikuRKvMA0GCSqGSIb3DQEBDQUAMBQxEjAQBgNV
+BAMMCXJzYS0xNjM4NDAeFw0xNjA0MDQxOTM0MzFaFw00MzA4MjExOTM0MzFaMBQx
+EjAQBgNVBAMMCXJzYS0xNjM4NDCCCCIwDQYJKoZIhvcNAQEBBQADgggPADCCCAoC
+gggBALDYs7aIK08pNr9fdrpLmUVfSc+3n/RNU2e7o3fzwQf2IMExk/ZmxF/ORgAd
+pXPEkn7uOLYSp+fJHUgqsca+8HsxTN1ypKov0X3OeFbnBLXmsoXgjRzaMEgluupd
+B81xnAKE/Vb+HYaEJ4YP+3UgBLIItnwLtL6vdh+e4qQGF9KEAv+T+PdrNQF0EGWK
+weCaOuMKRKfSnNXMkgIgWgoEefsBXNOR/jRJVFxsnJlwsB2iw0FbKjrxnlmwBL+f
+A8YxdMoCLxjL0TuUEmRyd0jO7Td49kUIkW6ux/b4qOvcUPQiODXeayesJ1lmFepS
+ATjhgCz2+C3pcAJOPvOvC4v0+5OQ3YrU2kKsnj8G2ic3SdPUq4UUvQWqY+rCZVDH
+IqsEs/+XO++wMELkN3uiQcRIEO8aCug+VxMSRiyRSSNtxmcmedUZevbZ6+2leBtn
+AbLP33E5hC80A7WKuddQgOiA1yTUVxatZEaxHFVZlg2nzSYHipvwMVC2+zQ4yrKA
+mbNp5wiVUV5WLsUkYEuSwl+MG9vEjr2gTX+qLrvpIYS2AF/16SOEw5zQBPUcfVIz
+eJU+W//wwXdlNmA6qRCDXqLDBX1MQrChpaI2eRbv64k5C09LtEA5nt/lJt5dm8IF
+XpurOZqHTVG3CCS15SM8PyoApYKN0oM9+6Z+FDUOB+VbTW/hAqKYLNBJmNf8mRkK
++c1peoOAYw5iG8iaSD8f8bcIi3oFPMdt0Gs5vDoLjbWmK2s9P2wknA4hmVe7hvSy
+DMvyxj8j4BLadc3HafcXYPfoNPhfgoiZVLm6ijEj74iKeLSkef8F3x0Agulnitz3
+CWt7X6EXHbqR/0++VTqgnFDe+enf9oFzMsDDbOs59dpyGFSP159dTqJILimF5xUG
+Fw95hsTbdEblZ7Q2MiibB38ifz8WT+Pix72SnHrlcnKonv8Tkeoie0AP+dYkYXpC
+Dy0oIzl7Vhy1e99RjX8kKjZAfCuiQ7wnOGNu6V32UyKMvWD5E6mNLpsvyBRTxDhs
+ePpH5dZWbhg6WxhD68QG/Wi/8FRmc8/TPpPXilOG3HHtX6Q3yfGYHJB6/dJhWQQy
+iZawyEpcyZKjEyWoJayRsKSLb6gW6Idfc1Uf/yb6IHDRlYZEPF7JuznjLCaz2QC9
+8GCBGfUE9OGH+LtdMnsmn2IYEd1FtWrRGduG0HNKubmx8bJmc1HkYDQg3cksPb2o
+jwCND2ALGtTcR30yllmSmEJKpXBYB00iRvxvkBqCkL4THOXhN2V5uEMrS0r8GRZN
+QCvCoFKulPjITmlQ/ciVonN9y9qVeRbFE4ZxiiBxF41K/Mw45ugIqfg4ndJqbub6
+5p15nhYJIC2CbsVL5+1THmd+kompQhUo1ttwof0aHh3KLwe1uq2OEU7Tz71Ct5+G
+b5JjIAlQDuGcfsx3utJY3AE5ailtvaRNAz3FyTsZGkIOeqX4uswWltxGnuSMSbPi
+CPv7ngFXkytkK+3Oqs92XM8mhO1yqPzmm73+qZYDGFdy32C/Rr0enETmgkUFPToH
+28hMcOsEt+7L0GM6A5N708BaF9Csy7XTFz47Hk2CjaKTvP08Tl3bFPULrgJ5KCr6
+4hc/bVIDkU7c1lhDISJ1yuw4KHizmjuf4UeRBBDoB3MpPwZSeEkggGXuX1wkFApu
+RGhjCXQgFU9bNtUHM6Kj0tPQZrgsvx2wwBUFVOfPoej6afrJqpvep+EN1+OJCE4c
+AzuZ1CdE96vEleVbrq3BQaJbsm8JqHs7lAn1aiCK0semqAoXD4cT4L2H4E37IDlm
+PHsxIeTmgD7/TP3InuFB6sYvVM8moG1TLmtUJkpc8kkPBPNbTRHwuRvMGD1pSsP1
+aNbgKkEfGqL1iOrfoTCRGKDeDDxWGsxDOgW1hRs9wGzJuMQjl1Rlb11lnnX7UYyT
+UnD/yw7YaplScWwpsqntQewI59A4ad1wOJlabDUFwkD4i4ERTcjyea1ydE03qaOy
+0ItJbc8kjsEMWFAv1+y7/cxD7kALcytvBHhD8OVJ40qJrtwRsXnv2T74cTPh87qh
+3j2tjdJKVSLxwqg5ZdvIemnWmmFAPuRERResp5j5WLJcOFcXhbp4CAQLViRoktLf
+AKtgKSVa9FQLvombOq8GqWxqeGJEsq+8/X6UOj/RDPu8gUCdodmlxgC5BpJlMTfg
+9ElvHb4oRewPfc5MBV5i++8xagxS1+5NM6z+1qZfT+XJcJ/wFYyeSvGGdEgaDIVd
+XGqOFDmA20bUl0xWSM5j4At2CmymAn32i8FR5lNfB/f8tIGBlXQyrYzpAKoj6FrV
+3u43zKgYBzDTqNs61e+A8MScV5666gvpcOltFiaucc455JGiN2v7N+SAygWaX3nb
+jidmRaIAftup6kXVXxy1ZwpKCtUTqo0M+S/jO9clHy1EYaSX12blCL1B6OFpMRV7
+1foffUHwaPrMqqbPphgN4QRY2Ao2sKSliiP1T8s1T2iteEGiazCdWSOVVi9Acbo5
+DfeBlWwhW6OQpv1nMTznGscc4+ledP5yG5C6boz2aNwK6H6cpDfEc7tWTWhZN5Jm
+Jlra4pseqf9Lsc/Y4QMD1312C3Hu8EtJ/qlxEDhLnCW8PHxdlRsIkmcV8w+as/hu
+6/MlOYcCp9ae6nooFL7ZuDkdDWm84UXdce2ZVVGVoDa+RdpICnp79y/9CLxWue4H
+09VFEFUH//E6lOCBymUjTSO/DQ6z+ceb2W5B3WVV8gqADTDhAgMBAAGjUDBOMB0G
+A1UdDgQWBBQkHp1wX0Sfr0xz7xcip9UwEIFTLDAfBgNVHSMEGDAWgBQkHp1wX0Sf
+r0xz7xcip9UwEIFTLDAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBDQUAA4IIAQAd
+FhlHg4E7Yp8kIOfZRU5Cma6wbOSd2eHkV28WHGdwpKsvNhzgQEj+scYWSS8geozi
+vqSdJCoMmY8hWJh4SY0ED1DjPMoRvE8OotyGoCJovvYQia+gbVneT8JnfV3fkdwi
+hpUmAhokrsHkBj0jp2Ubff/D5yflA+QPCmhZZnkow+5QHXtmpy8CL9Fzfonz5uq7
+yCV5uWRicczFbQw3pDSXKn5OFqXuC8H/8R6Caq2TkJ1LusVtZJevcHBkEQ6e+XEX
+kZ+QCNtHw0a67LQEPtMXSyqZ/zR0roqwT6udUgHhdvZjbbb9GDpTW3u472IY18E+
+bf+npZl9kyuv2kyK1d2IjL45TxjBr7vLbjsP2UsmZvb3Wfb/kiMscvTBcxOL7/WA
+GNJ0XifmJWiDTDC+gUBC7LRN9lG8F7ykrMTtMUNlhow5LpIi0HA8TH58yq3/ulGq
+XWpculy33kcVAFTMGh57r8zq9DwkeW+RWggvHO2422S1bFGmKpizKASTvY6iqo4H
+yKvE9uZ41WaEbpp9WKPIaeup+ynxFpcgwMCKwvs7Yaj+mVexv7CoJ9nrEhMOHDxV
+GRyWDdBoIi08S02JHztZBXp5NZ+hqey5HrO4dhrnV1nVYJmH89KcAlXMfTZ2YHsv
+R2+dm6K8ToaX+Irqbz7Xbv8WG/aAdUqMSWkFEss7OT7VZBUiAdFaWqg0D0wtWSSE
+jZJJs9ISUTClq+97o9BEH2sAebchLFP56nY+Bj/zHBq2qPxTKdKE5BH13KcK1fwO
+eNn8a3SlSEHraa0oV6VjgSoMNdFz7b7b0r/Z8L4PEASJgH+VaGRm2TtuVWFHSqvX
+015UGITk6YgAQ25MTprJc/oAd0dut+aCPtOVElfukYvdrbw1YYQ9tc7kU+AVrzaf
+ytWj2GYR5Slfhle0inKlBvbpLTAHs82bp2Dgy9ZSQzW9/gIvLvCt+Hj0kiSYNcbX
+W7Ai5z2i6XKE7DdQO0Uzt+1bXGK3j2PI+81lCw2ejCFwjdYDWQw9f2nzQ5FgeYwG
+tc6fS4GbJM97n0yH9rj0Jb25AummZGnEL11ytPpC6Nv9cQdCuKDbaWQuQyRMCLEm
+hHaqV6k/fI4Etvuo15pyfJ9w7Xrhc6emgdg2HzJ99lDGkzZAF/3FR7N5pLPk5E0/
+PPlXUSiEx17IeWp3rNt0YSMixkGz+EbKyv9RIZzm/LV4zAzs2ZyUHHavUgZ602eg
+89ppqafaBrCwIWB1jUmnHJop9YlXQ3hE7pAV5qf9GxZLwUdzJcyLte1/vkn1yt94
+nLOZPPWUwUjIaBOZ7e/g8fHBjvAYwyoy3toKVpvkhR48NvcYD8pQ9cB6rIL0JkWV
+nQEYeISlJCUOO3K2eZ3ZH02ftha5gLshcGRXy9NS+4fNxDT3H+102RqSxmKPIxV0
+onV9RyOxUPKLRGjCZBZxs5aSxTYjFJ591azt3yAY4vwCnnHqdNGFbTat/Zc8LUOO
+J26n5cOYFGKPvZVvj8jMNYC1wo+R+A+1FeYXBV4MSVxCB7tjBlbU6OIyZSWLZ8Vw
+LMcPbuZ7ESj1LeTONwS1vspZM8Y/M8+RXv9VA8Z998tnNopdU3izVC2z6Zn9hNNI
+XBDbSe6ZRwsjXrm5TZCBgA4ZE18MwxPVhntSvl87Gc3wF4hz4BOiZXmffrXK4nQJ
+aVA8E2IsriCV+GQBN/ui+w3U9LbtsHrbauhjrru5EfYohpuInwvgPlAnTztdv9u7
+ee8RhwaCa+MInZanD6pRAAcfM6O64CPxHZtfVW6JM42N7wQXijvYzJPVR30F+6o1
+C+KwySuMBOGxOctmzLj938/OMrxuLBOmv3PJvSnHV0pWtbR7r7jH3v0uUm54zH56
+Qo/Rm/Aqf+m4Si3Xtsf9zvc89sqG5v2TT882Joja76zlJfaS31QgbnLTmKtAHtIC
+mqfQPvt1LNEJIiB6FZDHJIW5Ccm7imsixerxCBBoAt/J/dhW6N+cjZ0EWG5NiSoz
+9LmAZv8iWyqK/KvdPXUopQWqkYUvuIyNCYqzTRLKudUMohefNwghvl1gSGp4IMZ/
+4LyrJHi9eCcD9Z65PJsRTua+742N2sdhFfU/C4atOUGSK9x/Dl79Qkgsl6HqAoce
+HXiHAIvoOqC+jzEkjjxow30BzJeGsZoFwNvMUW7HcQ523DiIOx6MX8oQyKEo+W6C
+ayFvvvT3qHu2hL2ZxOXE+rGyUJnmwqctz4ChLvyYXa/eNrycs382x2U5XNXgXzNT
+3bwB9B+LnKSMJEB+UvHdbBcafYyevLptbF5xiiiUA0P3fq61AfmNiCzJWb+kaO11
+oHHQNWyG/fO49u3bZJkhvlsk8GXAp9uTqdW7YAqxjy8NohFewmtpTJPE62XKIqiq
++dqo4nUT761iaUBxgyj1v5jKcXT2JiEMnEe4AN7pZJ01pCNXQrXl+6ru4TVV3tpy
+OsDJ9UfZo8xZXEAJ/gvSyiih0xq6xhwGuUyExC3GldBz2frveWImxVEiqQIdHULH
+WwB6eAm9T1f+2hOGq7AB9Jb8CRyQniJWXtWu9uJBt+XwSt5lN6VUjeLt95SitvjO
+llqs0zhvTf52H8siwaO83Cui78iamqv7jVatB3JYW71S5cOyZ/x5Z5FYqKi8/wjO
+L4OyUs54kfcJllsxAmS014UgcTrJpbMNw7jSzLX6FxT4MEbyARK8wWQfEZQ2tCeo
+IOzfcYvlY05mG0KSzs6ZGBrWRZQDPcbJ0CKNSLTFbQ==
+-----END CERTIFICATE-----
diff --git a/hostsidetests/appsecurity/certs/pkgsigverify/rsa-2048.pk8 b/hostsidetests/appsecurity/certs/pkgsigverify/rsa-2048.pk8
new file mode 100644
index 0000000..105f7e7
--- /dev/null
+++ b/hostsidetests/appsecurity/certs/pkgsigverify/rsa-2048.pk8
Binary files differ
diff --git a/hostsidetests/appsecurity/certs/pkgsigverify/rsa-2048.x509.pem b/hostsidetests/appsecurity/certs/pkgsigverify/rsa-2048.x509.pem
new file mode 100644
index 0000000..0e7b38e
--- /dev/null
+++ b/hostsidetests/appsecurity/certs/pkgsigverify/rsa-2048.x509.pem
@@ -0,0 +1,18 @@
+-----BEGIN CERTIFICATE-----
+MIIC+TCCAeGgAwIBAgIJAI41MGzdARX3MA0GCSqGSIb3DQEBCwUAMBMxETAPBgNV
+BAMMCHJzYS0yMDQ4MB4XDTE2MDMzMTE0NTc0OVoXDTQzMDgxNzE0NTc0OVowEzER
+MA8GA1UEAwwIcnNhLTIwNDgwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
+AQDQ4JI1EJ239V4wss0jpVlZMudh2/kARCVdoBgsRQuvc2RNnO23Eyynlt9UN+Dc
+NRdQIhbCpVTjdEl/bePECHlqg9NE3frAj5GebiUdWL6A/idKsZA1nAKyIgxxjcnu
++38OcrlO6XOm36euxGfd/ULrghZGXzMVFq4uLiIv3DqFkUcIlE0BvUiUoNwpopV4
+MKj1GQgoaEObJG5xkMBKO6vg36VfJ3s3V3r48uJxYGhhBZEB0EpoXLd4i0piAB8S
+MLb0Ek6wA/HZ8A2rdnStk1wl/83OM1jO0uB3hyfJpqIijlvNGnrloYyyOIqS0LGH
+nxSJD7goASH2Ef0h4yxbsOvHAgMBAAGjUDBOMB0GA1UdDgQWBBQXAi1zEH84mzkS
+62ohswGGWSwdbzAfBgNVHSMEGDAWgBQXAi1zEH84mzkS62ohswGGWSwdbzAMBgNV
+HRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAB92T5toLkF6dLl65/boH5Qvub
+5wfIk0AD12T3t3kYWQFOH0YDCHNL3SfmrjYM/CwNJAd1KuCL5AZcn0km/n0SFXt5
+8Ps/MBcb0eK1fYezeEehKUyt5IBgDTKeQOel6So8rGuQRrDf/WV8rt6fugkIODFx
+sB3oj4ESaGXbvmvWD6q4a3koq/nV26kALchnAr7/FTNq3HEIQ1BDr9pldVh1gEV/
+ohHKcQP4M22Es7lredzpIcb5K6Ko/UtwsSRtHnoOjwmb+L/FsgAJsekmcJG5TK1X
+ciIsrrNFDCYzf/d9O1PD/V95kB7460qMzrGWZpc3mLe+OnmVMq6c4omOtIKl
+-----END CERTIFICATE-----
diff --git a/hostsidetests/appsecurity/certs/pkgsigverify/rsa-3072.pk8 b/hostsidetests/appsecurity/certs/pkgsigverify/rsa-3072.pk8
new file mode 100644
index 0000000..163e06c
--- /dev/null
+++ b/hostsidetests/appsecurity/certs/pkgsigverify/rsa-3072.pk8
Binary files differ
diff --git a/hostsidetests/appsecurity/certs/pkgsigverify/rsa-3072.x509.pem b/hostsidetests/appsecurity/certs/pkgsigverify/rsa-3072.x509.pem
new file mode 100644
index 0000000..0f3cd14
--- /dev/null
+++ b/hostsidetests/appsecurity/certs/pkgsigverify/rsa-3072.x509.pem
@@ -0,0 +1,24 @@
+-----BEGIN CERTIFICATE-----
+MIID+TCCAmGgAwIBAgIJAN8aZ+YVywdhMA0GCSqGSIb3DQEBCwUAMBMxETAPBgNV
+BAMMCHJzYS0zMDcyMB4XDTE2MDMzMTE5MTQ1OFoXDTQzMDgxNzE5MTQ1OFowEzER
+MA8GA1UEAwwIcnNhLTMwNzIwggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIB
+gQCcgu3kzCLVWeUzwO5vhwWFD4rCJVavnVJjA4hz3fg9wsh8wpK0D39a8iyKS714
+5fFF/EsPpoKo6b8l9GVHfrSzJSa0rMcQ7+GHLyfG+8Wt6cnGwb8m6FOMKM8YAlUO
+zVL/WDZXBGvHu/gmZXM0ZbCy1cFBy5/kcGF2zF/fa+a8n4fUiQlbGC6y5iXKewMF
+z5/tFN4BeShBSNxGJVNOut/bLOvpGoPQVsteFlUgiSOPuXeiMeXDDEMEHbY7u7lB
+Fmjs5yAdXaLtnsJD689NdfIDZYHsiBRf7sFNWWNg4gE0gEPhN0QkC2Bkak80t2Mw
+XNakB7gqJ7Vsy+ZPBmhzMzeZbrK9cZXgqNNlxmraHycGzPif4sqmpy1/xFxNqOQh
+n2cc0fd2RG0ql1T4qO0U2b2NQzNMcgrtBW2E1UUUVukVJLCa7RKyt7yq7uUqeCYd
+MxNfvWYBSCzpZMvTI7jq6HcCqQOfW8nkE/z2IBdWvBi3yIdgKSsW0uZsW2/1+KlJ
+fhkCAwEAAaNQME4wHQYDVR0OBBYEFLGsv+jET2b4cWyINayy3qf/U7izMB8GA1Ud
+IwQYMBaAFLGsv+jET2b4cWyINayy3qf/U7izMAwGA1UdEwQFMAMBAf8wDQYJKoZI
+hvcNAQELBQADggGBACLyVVZrgLXL0PUAS2WwZruWj9q7lVnzLMla3u9j/fSLnlPK
+/YcuQh/DqovNkPjFrItww4VfLxkQNsdOccAMHWA2rnWivOYnS1q3gM56e9KN/fEq
+yRc3ltZCPvEoFnFEVtVfmgZJGV0xBLZUFHnPjlWtUYXS8pR89x/Klwy5aaJ9OcGW
+SPaI0I3TyFHCb92Dtfdehtdu8YCDrwTyaYLHvYdNQFDrJ20I8WNsG8RwklfAWNwZ
+IJ5fQxwHiCKxvdaTt2NYUSm4R4kEQCgklrgnaEy2kzDVKp4GjQwVrsa1btK+Srrd
+gtIqB+azx3XziuLi129qJGeZsof8ylN5eYmw0r57d6OPB/xj3roBsB77t4d5jEhl
+Y0BZ93t2HWvXJmuolf1JcauDOcGhxxgdiWdcOWeSABH3cNUiilRfs8HRwSzZwB5E
+RyjvKBdGirUAbLgri+8t9165gaz3wVhP4xkcD4e6LoupWHarAMKunMVGVbCOj7mj
+AUPHJ3Z+HhUKiI/q9g==
+-----END CERTIFICATE-----
diff --git a/hostsidetests/appsecurity/certs/pkgsigverify/rsa-4096.pk8 b/hostsidetests/appsecurity/certs/pkgsigverify/rsa-4096.pk8
new file mode 100644
index 0000000..0f498e5
--- /dev/null
+++ b/hostsidetests/appsecurity/certs/pkgsigverify/rsa-4096.pk8
Binary files differ
diff --git a/hostsidetests/appsecurity/certs/pkgsigverify/rsa-4096.x509.pem b/hostsidetests/appsecurity/certs/pkgsigverify/rsa-4096.x509.pem
new file mode 100644
index 0000000..704dcbd
--- /dev/null
+++ b/hostsidetests/appsecurity/certs/pkgsigverify/rsa-4096.x509.pem
@@ -0,0 +1,29 @@
+-----BEGIN CERTIFICATE-----
+MIIE+TCCAuGgAwIBAgIJAIhxrQmG+dcZMA0GCSqGSIb3DQEBCwUAMBMxETAPBgNV
+BAMMCHJzYS00MDk2MB4XDTE2MDMzMTE1Mjg0NloXDTQzMDgxNzE1Mjg0NlowEzER
+MA8GA1UEAwwIcnNhLTQwOTYwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
+AQDTPhE7i4Bv3BQG1ifMPZfTGA1ZvE+mQWOgQ1q/3AQz23I8pIaoj1wFbYDvnTYG
+UCDnlJqKvwL4mrAnxvqTxm+0g/WFOoBKFoNY5OhgcDfomNEFQajY9bgXaNiwEYDU
+0X+q+2KAnr35MF7vdEaHcN8gFh15wObVXmlerMIOWejnwrM4MOXjGjNXtiB+Dg04
+Fb9eHufZ+s1dKNAojD08mUJkxTC1gjmBKPr8hOAPo9ay5NZk6mGaI1E0U5NbIpDe
+0EhYxRXkDjP7f6BzbhFEupCOzZNMC5CxD8fsmku1CaKBayGpsxktYFxsw1RFVTZj
+3pKYnM1fJBHj/hU+7zy60MZNpdU6i5HVa8FPldwAxv6P2dz0wIl9S3rrqDrd2/1p
+r3rKNrMbVo7wzZ8euVhmjttsRvN8NykCniX6oWxuX7EFQxT/ZM0xk055gMMW7xbr
+oLtPAJ1Lk7R6aTCS+ObrhBgS8+38sIT8rF/CCz2KQ68iUpMmMBz+dkYsDwHPq7vG
+wIy8J7fwzTLqUbyO971+4MD9/9HbqfjRAsjfnSz8HqfyHrSDKeAhgqlr8j8DtQ7X
+B2PIZIEmyN//A13xfZQ63c/KR/yf9nPig4KfHulODfWXBD+2T5kzakTSn4My37FF
+mzG0giMMJ3zGs4QpGZAKFGdwhUq6nAAqEKYo+dptlFhbzQIDAQABo1AwTjAdBgNV
+HQ4EFgQU+f3rdfojsysUqNHmjE4c+0I8YGUwHwYDVR0jBBgwFoAU+f3rdfojsysU
+qNHmjE4c+0I8YGUwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAbOd0
+bKbaeGNsinFSck4niiHDhkeD7GhsneReA73LDJVwAsr5SLAYlmZL/R+1Jw2FGa5m
+82q8412xoVxqAbsz/OrBjoW+5RjAUpHSv0vo3Ny9EpFDpRI1yO8EFU2PhpbcC8Av
+101/oBA8tgKDKgb9H9GrnuqKqxLvrOKDle0TEWAb4X+yyuLSneU6UZTn/g6hhKMw
+pRcsCkwwKa2266auq93NA30Xb1UME5med/5fBKzjL7TvA8BTbr8EdHxjbPmnyI1n
+iVQJnkvvk6rDRcWeOt+lP/pmvaCcVFp9FJHlWmxrus7x0PuH8WxecVl6PeV3MLyR
+HXwGLzlqJWFm753FP3sTV3xNqemo1IhtlHR3jgU8Y7Ixq2Ljjs5izucqM+u2Ioo/
+wbzlhjfRmxqGE3RWvq6Vv5C22Th3hEA7PDUKAh1/cvUwZxOh1Wa9Nedhy0SUXAR8
+nY2GHJEN6QmR1ZAoyABHuPqk1IjduDONo0usGk/iYIFMgfwitc5Tv4gdjjBLburF
+NRU3QkoT1twPueb4Xnvmb/yHmTmqm7MM4OlkmTSpYRci8C1JNChdqIjNSF36Flnm
+DEMqP6petbkZcORD7UtgoB+DCPyBWybtm/GDOW2v3CWo94Q5A1yRDpqyQOTIJChe
+sssLUtp3bfmTSFFMfmsovynUlFpsazeFKjQOkYQ=
+-----END CERTIFICATE-----
diff --git a/hostsidetests/appsecurity/certs/pkgsigverify/rsa-8192.pk8 b/hostsidetests/appsecurity/certs/pkgsigverify/rsa-8192.pk8
new file mode 100644
index 0000000..cc7a7ec
--- /dev/null
+++ b/hostsidetests/appsecurity/certs/pkgsigverify/rsa-8192.pk8
Binary files differ
diff --git a/hostsidetests/appsecurity/certs/pkgsigverify/rsa-8192.x509.pem b/hostsidetests/appsecurity/certs/pkgsigverify/rsa-8192.x509.pem
new file mode 100644
index 0000000..42f1428
--- /dev/null
+++ b/hostsidetests/appsecurity/certs/pkgsigverify/rsa-8192.x509.pem
@@ -0,0 +1,50 @@
+-----BEGIN CERTIFICATE-----
+MIII+TCCBOGgAwIBAgIJAMMCN6DTJaAOMA0GCSqGSIb3DQEBDQUAMBMxETAPBgNV
+BAMMCHJzYS04MTkyMB4XDTE2MDQwNDE5MzI0NloXDTQzMDgyMTE5MzI0NlowEzER
+MA8GA1UEAwwIcnNhLTgxOTIwggQiMA0GCSqGSIb3DQEBAQUAA4IEDwAwggQKAoIE
+AQCt2gaOPSTn1A/WkapaytoE2RGF5nBzlfLocagG+0Bgz0RH3QQq0xBEmQivmbj4
+egyKFQQ9dYrefXRnayLQvHpfeT31QXR3iKOfMnvtxK9UnkXo9S/T+czyj91Ox51w
+HFUyMlXjFs8btxi6Lpkrgl3jmL+e4/WI8khvTrdszrO8rBHBYlD8Y7SAvPcVczYq
+nn4m6Jd0/abR5slHiyGtkTREoHmW/u4r4PfTzanLyzcsWH9/td+sYHcu1Y0XTWTR
+x2qrUmpD+7X5cvXP9rsECU82dtnyPZPIHBqzfLJ8oGELsJxgVZ0u9gW0tlmJQdVo
+Q0QPJSWivnNxPl1czJYbXimbY3Zh5hCzdyNqQewVx6iNsNh008JsXJ5/yvJQgLgZ
+UR2gWZMGzLc4V2wiqxuLzELt5RoXPehAdAiOLQu/3Fw+u4J/d7NEwpKgpdDGyG/U
+9nV6mjvomcgOdWKblaRAeiXauYy/MgW68kIu4O4SoKWRRmOF2p+tch3aDKw9M89O
+88QhEzbzDsioAxeOAqL7th3bSPZ2fX05xtM2vFK71QFM41q+FOL+062Ev/VJyU4g
+kxK643V+Cxso9CZEVtFfkNnVIGOI2h8knkOiLtbMnCx/hcxuZLm/XvYQxOO/7ScL
+rkHLUuKu/dK2ksDn8yBgaHfVlHkMmVoSll6fKB+UXpPX7xClrGQAFpVUji5oZN0s
++EcMQdcMtsb6LxnwC9XS1ELQ5FQGuJFatwY9RSV3cbwI6kNKaZiB5sDDAaAHX9GU
+U3EA2fm0u+4UFOSSmYTfx/jl0V1NMQ1oOAY9QMqzckMo2y9cepLQ3temQ/k4bNqj
+rYB3POdqS9OoT74UKU8gg9rv01PaFlLHhPKwVc+MjY36aVefbfk1KZzBpm2twUUm
+F0kz4pU3BYj0aSrTeKWaTLjdn4ndGMSe3QMQQ5GUchWCcygTyID8Wx8+eDzPIs/U
+sc++7fQRuPawcd11oQ7wTjWIjr7VnsV8hiHSyMupEad8HuBt8CNtDf/m/hD1LsEf
+0dY8nDGSPvV/ih2YqTfhcac65D4JKKbV5x65aEwM7frYwi9QsB7CK2xLMHnatp2a
+TRcA24VEsaBP2+UNSLyxkOeeuzSCksHLPBWkVfcRbKUeD9x4Dtwf2WsUtYjGzOQ7
+ApLBB4XHe+GPr/i+PmJP4IDoU1Mifbjla8rz2ZuebZgPnyV7nSvkG/FUqUYpa3Ut
+LY0nF/2dDRF0NirbWuB4Mkk/KlxCQ3w8EZFY5u6L/ee23WxbnVOEQJBtKh7/I/UV
+2dGqoVJx2UqT0MpjUCFjx+KjWvaEt+FfmjfRRqQfHLkJlYly/YdeUrGPdGgJNr0C
+csnZkAZmKDo4OVv+wVduHxHfAgMBAAGjUDBOMB0GA1UdDgQWBBRdiMpGc1L++yQc
+MtftoeGuLwJ+PzAfBgNVHSMEGDAWgBRdiMpGc1L++yQcMtftoeGuLwJ+PzAMBgNV
+HRMEBTADAQH/MA0GCSqGSIb3DQEBDQUAA4IEAQBo9lUFyV8jI0IpcQLC7hC0ILxx
+6DsDw/YpMd9lRyujKa//OVJOEO3Z+SalfoLslMPCD1eeJBxgx9/xTMxZUrunOMJu
+Ddxc5RypVwdt6NOUQ3pNYU+Qkp73aZzakm6/i1LQDOxGf1PaZooPqXaKMfyb9CQ+
+M5wR9XsLDAyQPlylft3cWsp7DaPsrcp7Sn5u33TtvCDgfMwbKZrzzmCdAHS52p0A
+czMpDgYxhxCuHPwN6XSAxlrWnfpkOsdKneiVr4aDm1fp61PQg+sOKNCNJCMmUB50
+XFj14qLmvjLERNl2vUfDqoj6DxC9OceioZljzFM2d8/DEC1/YUT8AGYZQt0ISLlq
+QW4e4iIxXxVNKwXvJZMCd3z4XX8SvAOXL0+WrOffgkQQpSr2jBXKFe0BpCUnzVkN
+jw/bVJ89jrqfupExJ6kKTLzI+H2u/7LgZUn9/QlvhWR3IL1nEvCCOPHXTreuUp2U
+KauH7WQU+mzF/K+obzYiaPc53dz0C3JcvWgv5cBbhDUsGsziZLPkR3r5TvpTNF3t
+c3Ky84q7CfOKI+hGN/S+BNSv+TdA5uOG+h8GJ6SAwVpimzguhx2/iRg7OiHmhoy4
+UfsCF/QdoF3cEoSMMzorOIM+szZ+XggJMbtWzIv4NAL2TCKJcpB6t0Uxci6JN6lM
+tnbq78QxeOoJ3D3g6ZQoGvCdKwHcMQunS2MK75j9hckX5hR+0xnH++bI+D3qXaul
+zCOAcMoGpM7WgyzAc3mh9aAJFk1J9OYzpFY34nX2cDMc0xtI2s9p2/8X14ir5suK
+R0rqm3BZewDaQVNtrZCm/sch1I0cN4GomvxZ+2xD43vsZm8QEB2fyTvazg6kW2O9
+G0coUmszwI63f7fVx+wzZZxS24N17lIO36hjBq12SKDz9C3cIOZpPYdcaNxDyiwq
++RojbgUnosJji+xZtyK5Bf1kNB+jNoNT5OrWCXCR62Z5CQ+fAdlz4NPdibYnwscF
+SD8OA2I7UIT42KAuDBEMKVXe4SlhqLzOdqXwZ7h/ZxyUlY+zpwLO9vfLVpqZiavl
+bx+RO7lkvxPGEtM4mjXt5dNx2rgML/lXSE63qaqspYLJ806A3GE0918/b+ZDfvzG
+HLbeqIVtAlXwOGFLdifLvsgFybQ5yriR/yTlHXN/T8K+Q6wPo3uNkKNgUDq0FmzF
+N9UDQ+VFAdwaGPfBox3okGPoD6/HdiokuwZm4mlioHjZc513qhDapS3fJcXV6tu9
+OhIPBJ5NXVw3IVXwB+eskd2W5y8QlHZKBNTwzc/PBqL93QA2PxOFispDtevAuyTq
+OhRConYsMhoLf/9NqhEsyKVhwtYhYrUh0Q+hCiAg+YpjKuE2YJoUNMVyF3dY
+-----END CERTIFICATE-----
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/README.txt b/hostsidetests/appsecurity/res/pkgsigverify/README.txt
new file mode 100644
index 0000000..fca2b11
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/README.txt
@@ -0,0 +1,3 @@
+APKs in this directory are used by PkgInstallSignatureVerificationTest.
+See that class for information about how these APKs were generated.
+
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/original.apk b/hostsidetests/appsecurity/res/pkgsigverify/original.apk
new file mode 100644
index 0000000..2993c2c
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/original.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/two-signers-second-signer-v2-broken.apk b/hostsidetests/appsecurity/res/pkgsigverify/two-signers-second-signer-v2-broken.apk
new file mode 100644
index 0000000..fcf154e
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/two-signers-second-signer-v2-broken.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/two-signers.apk b/hostsidetests/appsecurity/res/pkgsigverify/two-signers.apk
new file mode 100644
index 0000000..f11760f
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/two-signers.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-two-signers.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-two-signers.apk
new file mode 100644
index 0000000..f096a56
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-two-signers.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-dsa-sha1-1024.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-dsa-sha1-1024.apk
new file mode 100644
index 0000000..0f0f016
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-dsa-sha1-1024.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-dsa-sha1-2048.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-dsa-sha1-2048.apk
new file mode 100644
index 0000000..aa30612
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-dsa-sha1-2048.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-dsa-sha1-3072.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-dsa-sha1-3072.apk
new file mode 100644
index 0000000..68edee9
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-dsa-sha1-3072.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-dsa-sha224-1024.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-dsa-sha224-1024.apk
new file mode 100644
index 0000000..938ea7a
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-dsa-sha224-1024.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-dsa-sha224-2048.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-dsa-sha224-2048.apk
new file mode 100644
index 0000000..2f0002f
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-dsa-sha224-2048.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-dsa-sha224-3072.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-dsa-sha224-3072.apk
new file mode 100644
index 0000000..13b4bcb
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-dsa-sha224-3072.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-dsa-sha256-1024.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-dsa-sha256-1024.apk
new file mode 100644
index 0000000..b1bf280
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-dsa-sha256-1024.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-dsa-sha256-2048.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-dsa-sha256-2048.apk
new file mode 100644
index 0000000..8e7415f
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-dsa-sha256-2048.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-dsa-sha256-3072.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-dsa-sha256-3072.apk
new file mode 100644
index 0000000..65f8238
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-dsa-sha256-3072.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-dsa-sha384-1024.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-dsa-sha384-1024.apk
new file mode 100644
index 0000000..f5db0e4
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-dsa-sha384-1024.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-dsa-sha384-2048.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-dsa-sha384-2048.apk
new file mode 100644
index 0000000..d18a9a9
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-dsa-sha384-2048.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-dsa-sha384-3072.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-dsa-sha384-3072.apk
new file mode 100644
index 0000000..641ba50
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-dsa-sha384-3072.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-dsa-sha512-1024.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-dsa-sha512-1024.apk
new file mode 100644
index 0000000..dd8ab61
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-dsa-sha512-1024.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-dsa-sha512-2048.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-dsa-sha512-2048.apk
new file mode 100644
index 0000000..129a335
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-dsa-sha512-2048.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-dsa-sha512-3072.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-dsa-sha512-3072.apk
new file mode 100644
index 0000000..41287d7
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-dsa-sha512-3072.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-ecdsa-sha1-p256.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-ecdsa-sha1-p256.apk
new file mode 100644
index 0000000..e9a0d90
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-ecdsa-sha1-p256.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-ecdsa-sha1-p384.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-ecdsa-sha1-p384.apk
new file mode 100644
index 0000000..848cda0
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-ecdsa-sha1-p384.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-ecdsa-sha1-p521.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-ecdsa-sha1-p521.apk
new file mode 100644
index 0000000..397e6db
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-ecdsa-sha1-p521.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-ecdsa-sha224-p256.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-ecdsa-sha224-p256.apk
new file mode 100644
index 0000000..5127d60
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-ecdsa-sha224-p256.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-ecdsa-sha224-p384.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-ecdsa-sha224-p384.apk
new file mode 100644
index 0000000..b5d9d46
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-ecdsa-sha224-p384.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-ecdsa-sha224-p521.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-ecdsa-sha224-p521.apk
new file mode 100644
index 0000000..f3aa1d6
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-ecdsa-sha224-p521.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-ecdsa-sha256-p256.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-ecdsa-sha256-p256.apk
new file mode 100644
index 0000000..02b8a31
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-ecdsa-sha256-p256.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-ecdsa-sha256-p384.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-ecdsa-sha256-p384.apk
new file mode 100644
index 0000000..5c4bf7b
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-ecdsa-sha256-p384.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-ecdsa-sha256-p521.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-ecdsa-sha256-p521.apk
new file mode 100644
index 0000000..3a91ee5
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-ecdsa-sha256-p521.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-ecdsa-sha384-p256.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-ecdsa-sha384-p256.apk
new file mode 100644
index 0000000..ec4a42e
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-ecdsa-sha384-p256.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-ecdsa-sha384-p384.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-ecdsa-sha384-p384.apk
new file mode 100644
index 0000000..c3c3e0a
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-ecdsa-sha384-p384.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-ecdsa-sha384-p521.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-ecdsa-sha384-p521.apk
new file mode 100644
index 0000000..5be8ac5
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-ecdsa-sha384-p521.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-ecdsa-sha512-p256.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-ecdsa-sha512-p256.apk
new file mode 100644
index 0000000..60090a5
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-ecdsa-sha512-p256.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-ecdsa-sha512-p384.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-ecdsa-sha512-p384.apk
new file mode 100644
index 0000000..63f6780
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-ecdsa-sha512-p384.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-ecdsa-sha512-p521.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-ecdsa-sha512-p521.apk
new file mode 100644
index 0000000..53ae508
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-ecdsa-sha512-p521.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-md5-1024.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-md5-1024.apk
new file mode 100644
index 0000000..fe50da7
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-md5-1024.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-md5-16384.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-md5-16384.apk
new file mode 100644
index 0000000..3ce1737
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-md5-16384.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-md5-2048.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-md5-2048.apk
new file mode 100644
index 0000000..5eb6dec
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-md5-2048.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-md5-3072.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-md5-3072.apk
new file mode 100644
index 0000000..451f336
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-md5-3072.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-md5-4096.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-md5-4096.apk
new file mode 100644
index 0000000..a99a670
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-md5-4096.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-md5-8192.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-md5-8192.apk
new file mode 100644
index 0000000..10f4654
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-md5-8192.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha1-1024.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha1-1024.apk
new file mode 100644
index 0000000..f31e649
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha1-1024.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha1-16384.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha1-16384.apk
new file mode 100644
index 0000000..784e569
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha1-16384.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha1-2048.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha1-2048.apk
new file mode 100644
index 0000000..a2801e5
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha1-2048.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha1-3072.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha1-3072.apk
new file mode 100644
index 0000000..8d9fccf
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha1-3072.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha1-4096.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha1-4096.apk
new file mode 100644
index 0000000..3e36a40
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha1-4096.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha1-8192.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha1-8192.apk
new file mode 100644
index 0000000..b8f979d
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha1-8192.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha224-1024.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha224-1024.apk
new file mode 100644
index 0000000..d86ac4d
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha224-1024.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha224-16384.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha224-16384.apk
new file mode 100644
index 0000000..7656ece
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha224-16384.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha224-2048.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha224-2048.apk
new file mode 100644
index 0000000..4971db7
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha224-2048.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha224-3072.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha224-3072.apk
new file mode 100644
index 0000000..ed7f3f5
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha224-3072.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha224-4096.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha224-4096.apk
new file mode 100644
index 0000000..7d47560
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha224-4096.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha224-8192.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha224-8192.apk
new file mode 100644
index 0000000..99bcba2
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha224-8192.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha256-1024.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha256-1024.apk
new file mode 100644
index 0000000..46d3e61
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha256-1024.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha256-16384.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha256-16384.apk
new file mode 100644
index 0000000..21bf67f
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha256-16384.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha256-2048.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha256-2048.apk
new file mode 100644
index 0000000..a952f1b
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha256-2048.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha256-3072.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha256-3072.apk
new file mode 100644
index 0000000..db6941d
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha256-3072.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha256-4096.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha256-4096.apk
new file mode 100644
index 0000000..5bd3d0d
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha256-4096.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha256-8192.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha256-8192.apk
new file mode 100644
index 0000000..d8630b6
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha256-8192.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha384-1024.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha384-1024.apk
new file mode 100644
index 0000000..9438016
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha384-1024.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha384-16384.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha384-16384.apk
new file mode 100644
index 0000000..bb0caf0
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha384-16384.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha384-2048.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha384-2048.apk
new file mode 100644
index 0000000..81a0258
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha384-2048.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha384-3072.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha384-3072.apk
new file mode 100644
index 0000000..b76d7cf
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha384-3072.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha384-4096.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha384-4096.apk
new file mode 100644
index 0000000..2583f6f
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha384-4096.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha384-8192.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha384-8192.apk
new file mode 100644
index 0000000..f0b47f6
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha384-8192.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha512-1024.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha512-1024.apk
new file mode 100644
index 0000000..7c6ff19
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha512-1024.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha512-16384.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha512-16384.apk
new file mode 100644
index 0000000..8cf9eba
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha512-16384.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha512-2048.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha512-2048.apk
new file mode 100644
index 0000000..58676e8
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha512-2048.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha512-3072.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha512-3072.apk
new file mode 100644
index 0000000..2f4b23c
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha512-3072.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha512-4096.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha512-4096.apk
new file mode 100644
index 0000000..b823de3
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha512-4096.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha512-8192.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha512-8192.apk
new file mode 100644
index 0000000..ffa6be1
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha512-8192.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-with-apk-sig-block-but-without-apk-sig-scheme-v2-block.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-with-apk-sig-block-but-without-apk-sig-scheme-v2-block.apk
new file mode 100644
index 0000000..a194a2c
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-with-apk-sig-block-but-without-apk-sig-scheme-v2-block.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v2-only-apk-sig-block-size-mismatch.apk b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-apk-sig-block-size-mismatch.apk
new file mode 100644
index 0000000..e657a80
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-apk-sig-block-size-mismatch.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v2-only-cert-and-public-key-mismatch.apk b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-cert-and-public-key-mismatch.apk
new file mode 100644
index 0000000..5fbe97e
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-cert-and-public-key-mismatch.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v2-only-garbage-between-cd-and-eocd.apk b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-garbage-between-cd-and-eocd.apk
new file mode 100644
index 0000000..9360383
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-garbage-between-cd-and-eocd.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v2-only-missing-classes.dex.apk b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-missing-classes.dex.apk
new file mode 100644
index 0000000..0f1350a
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-missing-classes.dex.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v2-only-no-certs-in-sig.apk b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-no-certs-in-sig.apk
new file mode 100644
index 0000000..692c6b3
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-no-certs-in-sig.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v2-only-signatures-and-digests-block-mismatch.apk b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-signatures-and-digests-block-mismatch.apk
new file mode 100644
index 0000000..fb397a4
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-signatures-and-digests-block-mismatch.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v2-only-truncated-cd.apk b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-truncated-cd.apk
new file mode 100644
index 0000000..d2e3e8d
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-truncated-cd.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v2-only-two-signers.apk b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-two-signers.apk
new file mode 100644
index 0000000..697b046
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-two-signers.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v2-only-unknown-pair-in-apk-sig-block.apk b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-unknown-pair-in-apk-sig-block.apk
new file mode 100644
index 0000000..a506bfb
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-unknown-pair-in-apk-sig-block.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-dsa-sha256-1024-sig-does-not-verify.apk b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-dsa-sha256-1024-sig-does-not-verify.apk
new file mode 100644
index 0000000..18a4409
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-dsa-sha256-1024-sig-does-not-verify.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-dsa-sha256-1024.apk b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-dsa-sha256-1024.apk
new file mode 100644
index 0000000..9c8232f
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-dsa-sha256-1024.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-dsa-sha256-2048.apk b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-dsa-sha256-2048.apk
new file mode 100644
index 0000000..1d679b1
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-dsa-sha256-2048.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-dsa-sha256-3072.apk b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-dsa-sha256-3072.apk
new file mode 100644
index 0000000..6921479
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-dsa-sha256-3072.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-ecdsa-sha256-p256-digest-mismatch.apk b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-ecdsa-sha256-p256-digest-mismatch.apk
new file mode 100644
index 0000000..4cfc49c
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-ecdsa-sha256-p256-digest-mismatch.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-ecdsa-sha256-p256-sig-does-not-verify.apk b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-ecdsa-sha256-p256-sig-does-not-verify.apk
new file mode 100644
index 0000000..0339d39
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-ecdsa-sha256-p256-sig-does-not-verify.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-ecdsa-sha256-p256.apk b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-ecdsa-sha256-p256.apk
new file mode 100644
index 0000000..657f1f9
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-ecdsa-sha256-p256.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-ecdsa-sha256-p384.apk b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-ecdsa-sha256-p384.apk
new file mode 100644
index 0000000..326c681
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-ecdsa-sha256-p384.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-ecdsa-sha256-p521.apk b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-ecdsa-sha256-p521.apk
new file mode 100644
index 0000000..7fcb887
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-ecdsa-sha256-p521.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-ecdsa-sha512-p256.apk b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-ecdsa-sha512-p256.apk
new file mode 100644
index 0000000..5942916
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-ecdsa-sha512-p256.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-ecdsa-sha512-p384.apk b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-ecdsa-sha512-p384.apk
new file mode 100644
index 0000000..82aa6ad
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-ecdsa-sha512-p384.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-ecdsa-sha512-p521.apk b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-ecdsa-sha512-p521.apk
new file mode 100644
index 0000000..fde4294
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-ecdsa-sha512-p521.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-ignorable-unsupported-sig-algs.apk b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-ignorable-unsupported-sig-algs.apk
new file mode 100644
index 0000000..165b262
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-ignorable-unsupported-sig-algs.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pkcs1-sha256-1024.apk b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pkcs1-sha256-1024.apk
new file mode 100644
index 0000000..5751fbe
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pkcs1-sha256-1024.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pkcs1-sha256-16384.apk b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pkcs1-sha256-16384.apk
new file mode 100644
index 0000000..a832366
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pkcs1-sha256-16384.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pkcs1-sha256-2048-sig-does-not-verify.apk b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pkcs1-sha256-2048-sig-does-not-verify.apk
new file mode 100644
index 0000000..fe6be6f
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pkcs1-sha256-2048-sig-does-not-verify.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pkcs1-sha256-2048.apk b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pkcs1-sha256-2048.apk
new file mode 100644
index 0000000..90ab764
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pkcs1-sha256-2048.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pkcs1-sha256-3072.apk b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pkcs1-sha256-3072.apk
new file mode 100644
index 0000000..a3569d6
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pkcs1-sha256-3072.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pkcs1-sha256-4096.apk b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pkcs1-sha256-4096.apk
new file mode 100644
index 0000000..101602a
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pkcs1-sha256-4096.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pkcs1-sha256-8192.apk b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pkcs1-sha256-8192.apk
new file mode 100644
index 0000000..1c9f131
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pkcs1-sha256-8192.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pkcs1-sha512-1024.apk b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pkcs1-sha512-1024.apk
new file mode 100644
index 0000000..e95e312
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pkcs1-sha512-1024.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pkcs1-sha512-16384.apk b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pkcs1-sha512-16384.apk
new file mode 100644
index 0000000..2b332b1
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pkcs1-sha512-16384.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pkcs1-sha512-2048.apk b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pkcs1-sha512-2048.apk
new file mode 100644
index 0000000..5e5863e
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pkcs1-sha512-2048.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pkcs1-sha512-3072.apk b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pkcs1-sha512-3072.apk
new file mode 100644
index 0000000..d587865
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pkcs1-sha512-3072.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pkcs1-sha512-4096-digest-mismatch.apk b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pkcs1-sha512-4096-digest-mismatch.apk
new file mode 100644
index 0000000..72f5dba
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pkcs1-sha512-4096-digest-mismatch.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pkcs1-sha512-4096.apk b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pkcs1-sha512-4096.apk
new file mode 100644
index 0000000..1189d8a
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pkcs1-sha512-4096.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pkcs1-sha512-8192.apk b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pkcs1-sha512-8192.apk
new file mode 100644
index 0000000..146534e
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pkcs1-sha512-8192.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pss-sha256-1024.apk b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pss-sha256-1024.apk
new file mode 100644
index 0000000..1331d35
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pss-sha256-1024.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pss-sha256-16384.apk b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pss-sha256-16384.apk
new file mode 100644
index 0000000..a205741
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pss-sha256-16384.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pss-sha256-2048-sig-does-not-verify.apk b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pss-sha256-2048-sig-does-not-verify.apk
new file mode 100644
index 0000000..f90d226
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pss-sha256-2048-sig-does-not-verify.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pss-sha256-2048.apk b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pss-sha256-2048.apk
new file mode 100644
index 0000000..8bdfb45
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pss-sha256-2048.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pss-sha256-3072.apk b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pss-sha256-3072.apk
new file mode 100644
index 0000000..d36731c
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pss-sha256-3072.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pss-sha256-4096.apk b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pss-sha256-4096.apk
new file mode 100644
index 0000000..8e190b4
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pss-sha256-4096.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pss-sha256-8192.apk b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pss-sha256-8192.apk
new file mode 100644
index 0000000..c879ffe
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pss-sha256-8192.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pss-sha512-16384.apk b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pss-sha512-16384.apk
new file mode 100644
index 0000000..d398584
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pss-sha512-16384.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pss-sha512-2048.apk b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pss-sha512-2048.apk
new file mode 100644
index 0000000..bf8150d
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pss-sha512-2048.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pss-sha512-3072.apk b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pss-sha512-3072.apk
new file mode 100644
index 0000000..ca11ebb
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pss-sha512-3072.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pss-sha512-4096.apk b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pss-sha512-4096.apk
new file mode 100644
index 0000000..dfa1206
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pss-sha512-4096.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pss-sha512-8192.apk b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pss-sha512-8192.apk
new file mode 100644
index 0000000..1bdd017
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pss-sha512-8192.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v2-only-wrong-apk-sig-block-magic.apk b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-wrong-apk-sig-block-magic.apk
new file mode 100644
index 0000000..85750d4
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-wrong-apk-sig-block-magic.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v2-stripped-with-ignorable-signing-schemes.apk b/hostsidetests/appsecurity/res/pkgsigverify/v2-stripped-with-ignorable-signing-schemes.apk
new file mode 100644
index 0000000..634255b
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v2-stripped-with-ignorable-signing-schemes.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v2-stripped.apk b/hostsidetests/appsecurity/res/pkgsigverify/v2-stripped.apk
new file mode 100644
index 0000000..0d04d93
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v2-stripped.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/AdoptableHostTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/AdoptableHostTest.java
new file mode 100644
index 0000000..a7c9762
--- /dev/null
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/AdoptableHostTest.java
@@ -0,0 +1,356 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.appsecurity.cts;
+
+import static android.appsecurity.cts.SplitTests.ABI_TO_APK;
+import static android.appsecurity.cts.SplitTests.APK;
+import static android.appsecurity.cts.SplitTests.APK_mdpi;
+import static android.appsecurity.cts.SplitTests.APK_xxhdpi;
+import static android.appsecurity.cts.SplitTests.CLASS;
+import static android.appsecurity.cts.SplitTests.PKG;
+
+import android.appsecurity.cts.SplitTests.BaseInstallMultiple;
+import com.android.cts.migration.MigrationHelper;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.device.CollectingOutputReceiver;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.testtype.DeviceTestCase;
+import com.android.tradefed.testtype.IAbi;
+import com.android.tradefed.testtype.IAbiReceiver;
+import com.android.tradefed.testtype.IBuildReceiver;
+
+import java.util.Arrays;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Set of tests that verify behavior of adopted storage media, if supported.
+ */
+public class AdoptableHostTest extends DeviceTestCase implements IAbiReceiver, IBuildReceiver {
+    private IAbi mAbi;
+    private IBuildInfo mCtsBuild;
+
+    @Override
+    public void setAbi(IAbi abi) {
+        mAbi = abi;
+    }
+
+    @Override
+    public void setBuild(IBuildInfo buildInfo) {
+        mCtsBuild = buildInfo;
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        assertNotNull(mAbi);
+        assertNotNull(mCtsBuild);
+
+        getDevice().uninstallPackage(PKG);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+
+        getDevice().uninstallPackage(PKG);
+    }
+
+    public void testApps() throws Exception {
+        if (!hasAdoptable()) return;
+        final String diskId = getAdoptionDisk();
+        try {
+            final String abi = mAbi.getName();
+            final String apk = ABI_TO_APK.get(abi);
+            assertNotNull("Failed to find APK for ABI " + abi, apk);
+
+            // Install simple app on internal
+            new InstallMultiple().useNaturalAbi().addApk(APK).addApk(apk).run();
+            runDeviceTests(PKG, CLASS, "testDataInternal");
+            runDeviceTests(PKG, CLASS, "testDataWrite");
+            runDeviceTests(PKG, CLASS, "testDataRead");
+            runDeviceTests(PKG, CLASS, "testNative");
+
+            // Adopt that disk!
+            assertEmpty(getDevice().executeShellCommand("sm partition " + diskId + " private"));
+            final LocalVolumeInfo vol = getAdoptionVolume();
+
+            // Move app and verify
+            assertSuccess(getDevice().executeShellCommand(
+                    "pm move-package " + PKG + " " + vol.uuid));
+            runDeviceTests(PKG, CLASS, "testDataNotInternal");
+            runDeviceTests(PKG, CLASS, "testDataRead");
+            runDeviceTests(PKG, CLASS, "testNative");
+
+            // Unmount, remount and verify
+            getDevice().executeShellCommand("sm unmount " + vol.volId);
+            getDevice().executeShellCommand("sm mount " + vol.volId);
+            runDeviceTests(PKG, CLASS, "testDataNotInternal");
+            runDeviceTests(PKG, CLASS, "testDataRead");
+            runDeviceTests(PKG, CLASS, "testNative");
+
+            // Move app back and verify
+            assertSuccess(getDevice().executeShellCommand("pm move-package " + PKG + " internal"));
+            runDeviceTests(PKG, CLASS, "testDataInternal");
+            runDeviceTests(PKG, CLASS, "testDataRead");
+            runDeviceTests(PKG, CLASS, "testNative");
+
+            // Un-adopt volume and app should still be fine
+            getDevice().executeShellCommand("sm partition " + diskId + " public");
+            runDeviceTests(PKG, CLASS, "testDataInternal");
+            runDeviceTests(PKG, CLASS, "testDataRead");
+            runDeviceTests(PKG, CLASS, "testNative");
+
+        } finally {
+            cleanUp(diskId);
+        }
+    }
+
+    public void testPrimaryStorage() throws Exception {
+        if (!hasAdoptable()) return;
+        final String diskId = getAdoptionDisk();
+        try {
+            final String originalVol = getDevice()
+                    .executeShellCommand("sm get-primary-storage-uuid").trim();
+
+            if ("null".equals(originalVol)) {
+                verifyPrimaryInternal(diskId);
+            } else if ("primary_physical".equals(originalVol)) {
+                verifyPrimaryPhysical(diskId);
+            }
+        } finally {
+            cleanUp(diskId);
+        }
+    }
+
+    private void verifyPrimaryInternal(String diskId) throws Exception {
+        // Write some data to shared storage
+        new InstallMultiple().addApk(APK).run();
+        runDeviceTests(PKG, CLASS, "testPrimaryOnSameVolume");
+        runDeviceTests(PKG, CLASS, "testPrimaryInternal");
+        runDeviceTests(PKG, CLASS, "testPrimaryDataWrite");
+        runDeviceTests(PKG, CLASS, "testPrimaryDataRead");
+
+        // Adopt that disk!
+        assertEmpty(getDevice().executeShellCommand("sm partition " + diskId + " private"));
+        final LocalVolumeInfo vol = getAdoptionVolume();
+
+        // Move storage there and verify that data went along for ride
+        final CollectingOutputReceiver out = new CollectingOutputReceiver();
+        getDevice().executeShellCommand("pm move-primary-storage " + vol.uuid, out, 2,
+                TimeUnit.HOURS, 1);
+        assertSuccess(out.getOutput());
+        runDeviceTests(PKG, CLASS, "testPrimaryAdopted");
+        runDeviceTests(PKG, CLASS, "testPrimaryDataRead");
+
+        // Unmount and verify
+        getDevice().executeShellCommand("sm unmount " + vol.volId);
+        runDeviceTests(PKG, CLASS, "testPrimaryUnmounted");
+        getDevice().executeShellCommand("sm mount " + vol.volId);
+        runDeviceTests(PKG, CLASS, "testPrimaryAdopted");
+        runDeviceTests(PKG, CLASS, "testPrimaryDataRead");
+
+        // Move app and verify backing storage volume is same
+        assertSuccess(getDevice().executeShellCommand("pm move-package " + PKG + " " + vol.uuid));
+        runDeviceTests(PKG, CLASS, "testPrimaryOnSameVolume");
+        runDeviceTests(PKG, CLASS, "testPrimaryDataRead");
+
+        // And move back to internal
+        assertSuccess(getDevice().executeShellCommand("pm move-primary-storage internal"));
+        runDeviceTests(PKG, CLASS, "testPrimaryInternal");
+        runDeviceTests(PKG, CLASS, "testPrimaryDataRead");
+
+        assertSuccess(getDevice().executeShellCommand("pm move-package " + PKG + " internal"));
+        runDeviceTests(PKG, CLASS, "testPrimaryOnSameVolume");
+        runDeviceTests(PKG, CLASS, "testPrimaryDataRead");
+    }
+
+    private void verifyPrimaryPhysical(String diskId) throws Exception {
+        // Write some data to shared storage
+        new InstallMultiple().addApk(APK).run();
+        runDeviceTests(PKG, CLASS, "testPrimaryPhysical");
+        runDeviceTests(PKG, CLASS, "testPrimaryDataWrite");
+        runDeviceTests(PKG, CLASS, "testPrimaryDataRead");
+
+        // Adopt that disk!
+        assertEmpty(getDevice().executeShellCommand("sm partition " + diskId + " private"));
+        final LocalVolumeInfo vol = getAdoptionVolume();
+
+        // Move primary storage there, but since we just nuked primary physical
+        // the storage device will be empty
+        assertSuccess(getDevice().executeShellCommand("pm move-primary-storage " + vol.uuid));
+        runDeviceTests(PKG, CLASS, "testPrimaryAdopted");
+        runDeviceTests(PKG, CLASS, "testPrimaryDataWrite");
+        runDeviceTests(PKG, CLASS, "testPrimaryDataRead");
+
+        // Unmount and verify
+        getDevice().executeShellCommand("sm unmount " + vol.volId);
+        runDeviceTests(PKG, CLASS, "testPrimaryUnmounted");
+        getDevice().executeShellCommand("sm mount " + vol.volId);
+        runDeviceTests(PKG, CLASS, "testPrimaryAdopted");
+        runDeviceTests(PKG, CLASS, "testPrimaryDataRead");
+
+        // And move to internal
+        assertSuccess(getDevice().executeShellCommand("pm move-primary-storage internal"));
+        runDeviceTests(PKG, CLASS, "testPrimaryOnSameVolume");
+        runDeviceTests(PKG, CLASS, "testPrimaryInternal");
+        runDeviceTests(PKG, CLASS, "testPrimaryDataRead");
+    }
+
+    /**
+     * Verify that we can install both new and inherited packages directly on
+     * adopted volumes.
+     */
+    public void testPackageInstaller() throws Exception {
+        if (!hasAdoptable()) return;
+        final String diskId = getAdoptionDisk();
+        try {
+            assertEmpty(getDevice().executeShellCommand("sm partition " + diskId + " private"));
+            final LocalVolumeInfo vol = getAdoptionVolume();
+
+            // Install directly onto adopted volume
+            new InstallMultiple().locationAuto().forceUuid(vol.uuid)
+                    .addApk(APK).addApk(APK_mdpi).run();
+            runDeviceTests(PKG, CLASS, "testDataNotInternal");
+            runDeviceTests(PKG, CLASS, "testDensityBest1");
+
+            // Now splice in an additional split which offers better resources
+            new InstallMultiple().locationAuto().inheritFrom(PKG)
+                    .addApk(APK_xxhdpi).run();
+            runDeviceTests(PKG, CLASS, "testDataNotInternal");
+            runDeviceTests(PKG, CLASS, "testDensityBest2");
+
+        } finally {
+            cleanUp(diskId);
+        }
+    }
+
+    /**
+     * Verify behavior when changes occur while adopted device is ejected and
+     * returned at a later time.
+     */
+    public void testEjected() throws Exception {
+        if (!hasAdoptable()) return;
+        final String diskId = getAdoptionDisk();
+        try {
+            assertEmpty(getDevice().executeShellCommand("sm partition " + diskId + " private"));
+            final LocalVolumeInfo vol = getAdoptionVolume();
+
+            // Install directly onto adopted volume, and write data there
+            new InstallMultiple().locationAuto().forceUuid(vol.uuid).addApk(APK).run();
+            runDeviceTests(PKG, CLASS, "testDataNotInternal");
+            runDeviceTests(PKG, CLASS, "testDataWrite");
+            runDeviceTests(PKG, CLASS, "testDataRead");
+
+            // Now unmount and uninstall; leaving stale package on adopted volume
+            getDevice().executeShellCommand("sm unmount " + vol.volId);
+            getDevice().uninstallPackage(PKG);
+
+            // Install second copy on internal, but don't write anything
+            new InstallMultiple().locationInternalOnly().addApk(APK).run();
+            runDeviceTests(PKG, CLASS, "testDataInternal");
+
+            // Kick through a remount cycle, which should purge the adopted app
+            getDevice().executeShellCommand("sm mount " + vol.volId);
+            runDeviceTests(PKG, CLASS, "testDataInternal");
+            try {
+                runDeviceTests(PKG, CLASS, "testDataRead");
+                fail("Unexpected data from adopted volume picked up");
+            } catch (AssertionError expected) {
+            }
+            getDevice().executeShellCommand("sm unmount " + vol.volId);
+
+            // Uninstall the internal copy and remount; we should have no record of app
+            getDevice().uninstallPackage(PKG);
+            getDevice().executeShellCommand("sm mount " + vol.volId);
+
+            assertEmpty(getDevice().executeShellCommand("pm list packages " + PKG));
+        } finally {
+            cleanUp(diskId);
+        }
+    }
+
+    private boolean hasAdoptable() throws Exception {
+        return Boolean.parseBoolean(getDevice().executeShellCommand("sm has-adoptable").trim());
+    }
+
+    private String getAdoptionDisk() throws Exception {
+        final String disks = getDevice().executeShellCommand("sm list-disks adoptable");
+        if (disks == null || disks.length() == 0) {
+            throw new AssertionError("Devices that claim to support adoptable storage must have "
+                    + "adoptable media inserted during CTS to verify correct behavior");
+        }
+        return disks.split("\n")[0].trim();
+    }
+
+    private LocalVolumeInfo getAdoptionVolume() throws Exception {
+        String[] lines = null;
+        int attempt = 0;
+        while (attempt++ < 15) {
+            lines = getDevice().executeShellCommand("sm list-volumes private").split("\n");
+            for (String line : lines) {
+                final LocalVolumeInfo info = new LocalVolumeInfo(line.trim());
+                if (!"private".equals(info.volId) && "mounted".equals(info.state)) {
+                    return info;
+                }
+            }
+            Thread.sleep(1000);
+        }
+        throw new AssertionError("Expected private volume; found " + Arrays.toString(lines));
+    }
+
+    private void cleanUp(String diskId) throws Exception {
+        getDevice().executeShellCommand("sm partition " + diskId + " public");
+        getDevice().executeShellCommand("sm forget all");
+    }
+
+    private void runDeviceTests(String packageName, String testClassName, String testMethodName)
+            throws DeviceNotAvailableException {
+        Utils.runDeviceTests(getDevice(), packageName, testClassName, testMethodName);
+    }
+
+    private static void assertSuccess(String str) {
+        if (str == null || !str.startsWith("Success")) {
+            throw new AssertionError("Expected success string but found " + str);
+        }
+    }
+
+    private static void assertEmpty(String str) {
+        if (str != null && str.trim().length() > 0) {
+            throw new AssertionError("Expected empty string but found " + str);
+        }
+    }
+
+    private static class LocalVolumeInfo {
+        public String volId;
+        public String state;
+        public String uuid;
+
+        public LocalVolumeInfo(String line) {
+            final String[] split = line.split(" ");
+            volId = split[0];
+            state = split[1];
+            uuid = split[2];
+        }
+    }
+
+    private class InstallMultiple extends BaseInstallMultiple<InstallMultiple> {
+        public InstallMultiple() {
+            super(getDevice(), mCtsBuild, mAbi);
+        }
+    }
+}
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/AppSecurityTests.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/AppSecurityTests.java
new file mode 100644
index 0000000..00acdf5
--- /dev/null
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/AppSecurityTests.java
@@ -0,0 +1,300 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.appsecurity.cts;
+
+import com.android.compatibility.common.util.AbiUtils;
+import com.android.cts.migration.MigrationHelper;
+import com.android.ddmlib.Log;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.testtype.DeviceTestCase;
+import com.android.tradefed.testtype.IAbi;
+import com.android.tradefed.testtype.IAbiReceiver;
+import com.android.tradefed.testtype.IBuildReceiver;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+
+/**
+ * Set of tests that verify various security checks involving multiple apps are
+ * properly enforced.
+ */
+public class AppSecurityTests extends DeviceTestCase implements IAbiReceiver, IBuildReceiver {
+
+    // testSharedUidDifferentCerts constants
+    private static final String SHARED_UI_APK = "CtsSharedUidInstall.apk";
+    private static final String SHARED_UI_PKG = "com.android.cts.shareuidinstall";
+    private static final String SHARED_UI_DIFF_CERT_APK = "CtsSharedUidInstallDiffCert.apk";
+    private static final String SHARED_UI_DIFF_CERT_PKG =
+        "com.android.cts.shareuidinstalldiffcert";
+
+    // testAppUpgradeDifferentCerts constants
+    private static final String SIMPLE_APP_APK = "CtsSimpleAppInstall.apk";
+    private static final String SIMPLE_APP_PKG = "com.android.cts.simpleappinstall";
+    private static final String SIMPLE_APP_DIFF_CERT_APK = "CtsSimpleAppInstallDiffCert.apk";
+
+    // testAppFailAccessPrivateData constants
+    private static final String APP_WITH_DATA_APK = "CtsAppWithData.apk";
+    private static final String APP_WITH_DATA_PKG = "com.android.cts.appwithdata";
+    private static final String APP_WITH_DATA_CLASS =
+            "com.android.cts.appwithdata.CreatePrivateDataTest";
+    private static final String APP_WITH_DATA_CREATE_METHOD =
+            "testCreatePrivateData";
+    private static final String APP_WITH_DATA_CHECK_NOEXIST_METHOD =
+            "testEnsurePrivateDataNotExist";
+    private static final String APP_ACCESS_DATA_APK = "CtsAppAccessData.apk";
+    private static final String APP_ACCESS_DATA_PKG = "com.android.cts.appaccessdata";
+
+    // testInstrumentationDiffCert constants
+    private static final String TARGET_INSTRUMENT_APK = "CtsTargetInstrumentationApp.apk";
+    private static final String TARGET_INSTRUMENT_PKG = "com.android.cts.targetinstrumentationapp";
+    private static final String INSTRUMENT_DIFF_CERT_APK = "CtsInstrumentationAppDiffCert.apk";
+    private static final String INSTRUMENT_DIFF_CERT_PKG =
+        "com.android.cts.instrumentationdiffcertapp";
+
+    // testPermissionDiffCert constants
+    private static final String DECLARE_PERMISSION_APK = "CtsPermissionDeclareApp.apk";
+    private static final String DECLARE_PERMISSION_PKG = "com.android.cts.permissiondeclareapp";
+    private static final String DECLARE_PERMISSION_COMPAT_APK = "CtsPermissionDeclareAppCompat.apk";
+    private static final String DECLARE_PERMISSION_COMPAT_PKG = "com.android.cts.permissiondeclareappcompat";
+
+    private static final String PERMISSION_DIFF_CERT_APK = "CtsUsePermissionDiffCert.apk";
+    private static final String PERMISSION_DIFF_CERT_PKG =
+        "com.android.cts.usespermissiondiffcertapp";
+
+    private static final String LOG_TAG = "AppSecurityTests";
+
+    private IAbi mAbi;
+    private IBuildInfo mCtsBuild;
+
+    @Override
+    public void setAbi(IAbi abi) {
+        mAbi = abi;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setBuild(IBuildInfo buildInfo) {
+        mCtsBuild = buildInfo;
+    }
+
+    private File getTestAppFile(String fileName) throws FileNotFoundException {
+        return MigrationHelper.getTestFile(mCtsBuild, fileName);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        // ensure build has been set before test is run
+        assertNotNull(mCtsBuild);
+    }
+
+    /**
+     * Test that an app that declares the same shared uid as an existing app, cannot be installed
+     * if it is signed with a different certificate.
+     */
+    public void testSharedUidDifferentCerts() throws Exception {
+        Log.i(LOG_TAG, "installing apks with shared uid, but different certs");
+        try {
+            // cleanup test apps that might be installed from previous partial test run
+            getDevice().uninstallPackage(SHARED_UI_PKG);
+            getDevice().uninstallPackage(SHARED_UI_DIFF_CERT_PKG);
+
+            String[] options = {AbiUtils.createAbiFlag(mAbi.getName())};
+            String installResult = getDevice().installPackage(getTestAppFile(SHARED_UI_APK),
+                    false, options);
+            assertNull(String.format("failed to install shared uid app, Reason: %s", installResult),
+                    installResult);
+            installResult = getDevice().installPackage(getTestAppFile(SHARED_UI_DIFF_CERT_APK),
+                    false, options);
+            assertNotNull("shared uid app with different cert than existing app installed " +
+                    "successfully", installResult);
+            assertEquals("INSTALL_FAILED_SHARED_USER_INCOMPATIBLE",
+                    installResult.substring(0, installResult.indexOf(':')));
+        } finally {
+            getDevice().uninstallPackage(SHARED_UI_PKG);
+            getDevice().uninstallPackage(SHARED_UI_DIFF_CERT_PKG);
+        }
+    }
+
+    /**
+     * Test that an app update cannot be installed over an existing app if it has a different
+     * certificate.
+     */
+    public void testAppUpgradeDifferentCerts() throws Exception {
+        Log.i(LOG_TAG, "installing app upgrade with different certs");
+        try {
+            // cleanup test app that might be installed from previous partial test run
+            getDevice().uninstallPackage(SIMPLE_APP_PKG);
+
+            String[] options = {AbiUtils.createAbiFlag(mAbi.getName())};
+            String installResult = getDevice().installPackage(getTestAppFile(SIMPLE_APP_APK),
+                    false, options);
+            assertNull(String.format("failed to install simple app. Reason: %s", installResult),
+                    installResult);
+            installResult = getDevice().installPackage(getTestAppFile(SIMPLE_APP_DIFF_CERT_APK),
+                    true /* reinstall */, options);
+            assertNotNull("app upgrade with different cert than existing app installed " +
+                    "successfully", installResult);
+            assertEquals("INSTALL_FAILED_UPDATE_INCOMPATIBLE",
+                    installResult.substring(0, installResult.indexOf(':')));
+        } finally {
+            getDevice().uninstallPackage(SIMPLE_APP_PKG);
+        }
+    }
+
+    /**
+     * Test that an app cannot access another app's private data.
+     */
+    public void testAppFailAccessPrivateData() throws Exception {
+        Log.i(LOG_TAG, "installing app that attempts to access another app's private data");
+        try {
+            // cleanup test app that might be installed from previous partial test run
+            getDevice().uninstallPackage(APP_WITH_DATA_PKG);
+            getDevice().uninstallPackage(APP_ACCESS_DATA_PKG);
+
+            String[] options = {AbiUtils.createAbiFlag(mAbi.getName())};
+            String installResult = getDevice().installPackage(getTestAppFile(APP_WITH_DATA_APK),
+                    false, options);
+            assertNull(String.format("failed to install app with data. Reason: %s", installResult),
+                    installResult);
+            // run appwithdata's tests to create private data
+            runDeviceTests(APP_WITH_DATA_PKG, APP_WITH_DATA_CLASS, APP_WITH_DATA_CREATE_METHOD);
+
+            installResult = getDevice().installPackage(getTestAppFile(APP_ACCESS_DATA_APK),
+                    false, options);
+            assertNull(String.format("failed to install app access data. Reason: %s",
+                    installResult), installResult);
+            // run appaccessdata's tests which attempt to access appwithdata's private data
+            runDeviceTests(APP_ACCESS_DATA_PKG);
+        } finally {
+            getDevice().uninstallPackage(APP_WITH_DATA_PKG);
+            getDevice().uninstallPackage(APP_ACCESS_DATA_PKG);
+        }
+    }
+
+    /**
+     * Test that uninstall of an app removes its private data.
+     */
+    public void testUninstallRemovesData() throws Exception {
+        Log.i(LOG_TAG, "Uninstalling app, verifying data is removed.");
+        try {
+            // cleanup test app that might be installed from previous partial test run
+            getDevice().uninstallPackage(APP_WITH_DATA_PKG);
+
+            String[] options = {AbiUtils.createAbiFlag(mAbi.getName())};
+            String installResult = getDevice().installPackage(getTestAppFile(APP_WITH_DATA_APK),
+                    false, options);
+            assertNull(String.format("failed to install app with data. Reason: %s", installResult),
+                    installResult);
+            // run appwithdata's tests to create private data
+            runDeviceTests(APP_WITH_DATA_PKG, APP_WITH_DATA_CLASS, APP_WITH_DATA_CREATE_METHOD);
+
+            getDevice().uninstallPackage(APP_WITH_DATA_PKG);
+
+            installResult = getDevice().installPackage(getTestAppFile(APP_WITH_DATA_APK),
+                    false, options);
+            assertNull(String.format("failed to install app with data second time. Reason: %s",
+                    installResult), installResult);
+            // run appwithdata's 'check if file exists' test
+            runDeviceTests(APP_WITH_DATA_PKG, APP_WITH_DATA_CLASS,
+                    APP_WITH_DATA_CHECK_NOEXIST_METHOD);
+        } finally {
+            getDevice().uninstallPackage(APP_WITH_DATA_PKG);
+        }
+    }
+
+    /**
+     * Test that an app cannot instrument another app that is signed with different certificate.
+     */
+    public void testInstrumentationDiffCert() throws Exception {
+        Log.i(LOG_TAG, "installing app that attempts to instrument another app");
+        try {
+            // cleanup test app that might be installed from previous partial test run
+            getDevice().uninstallPackage(TARGET_INSTRUMENT_PKG);
+            getDevice().uninstallPackage(INSTRUMENT_DIFF_CERT_PKG);
+
+            String[] options = {AbiUtils.createAbiFlag(mAbi.getName())};
+            String installResult = getDevice().installPackage(
+                    getTestAppFile(TARGET_INSTRUMENT_APK), false, options);
+            assertNull(String.format("failed to install target instrumentation app. Reason: %s",
+                    installResult), installResult);
+
+            // the app will install, but will get error at runtime when starting instrumentation
+            installResult = getDevice().installPackage(getTestAppFile(INSTRUMENT_DIFF_CERT_APK),
+                    false, options);
+            assertNull(String.format(
+                    "failed to install instrumentation app with diff cert. Reason: %s",
+                    installResult), installResult);
+            // run INSTRUMENT_DIFF_CERT_PKG tests
+            // this test will attempt to call startInstrumentation directly and verify
+            // SecurityException is thrown
+            runDeviceTests(INSTRUMENT_DIFF_CERT_PKG);
+        } finally {
+            getDevice().uninstallPackage(TARGET_INSTRUMENT_PKG);
+            getDevice().uninstallPackage(INSTRUMENT_DIFF_CERT_PKG);
+        }
+    }
+
+    /**
+     * Test that an app cannot use a signature-enforced permission if it is signed with a different
+     * certificate than the app that declared the permission.
+     */
+    public void testPermissionDiffCert() throws Exception {
+        Log.i(LOG_TAG, "installing app that attempts to use permission of another app");
+        try {
+            // cleanup test app that might be installed from previous partial test run
+            getDevice().uninstallPackage(DECLARE_PERMISSION_PKG);
+            getDevice().uninstallPackage(DECLARE_PERMISSION_COMPAT_PKG);
+            getDevice().uninstallPackage(PERMISSION_DIFF_CERT_PKG);
+
+            String[] options = {AbiUtils.createAbiFlag(mAbi.getName())};
+            String installResult = getDevice().installPackage(
+                    getTestAppFile(DECLARE_PERMISSION_APK), false, options);
+            assertNull(String.format("failed to install declare permission app. Reason: %s",
+                    installResult), installResult);
+
+            installResult = getDevice().installPackage(
+                    getTestAppFile(DECLARE_PERMISSION_COMPAT_APK), false, options);
+            assertNull(String.format("failed to install declare permission compat app. Reason: %s",
+                    installResult), installResult);
+
+            // the app will install, but will get error at runtime
+            installResult = getDevice().installPackage(getTestAppFile(PERMISSION_DIFF_CERT_APK),
+                    false, options);
+            assertNull(String.format("failed to install permission app with diff cert. Reason: %s",
+                    installResult), installResult);
+            // run PERMISSION_DIFF_CERT_PKG tests which try to access the permission
+            runDeviceTests(PERMISSION_DIFF_CERT_PKG);
+        } finally {
+            getDevice().uninstallPackage(DECLARE_PERMISSION_PKG);
+            getDevice().uninstallPackage(DECLARE_PERMISSION_COMPAT_PKG);
+            getDevice().uninstallPackage(PERMISSION_DIFF_CERT_PKG);
+        }
+    }
+
+    private void runDeviceTests(String packageName) throws DeviceNotAvailableException {
+        Utils.runDeviceTests(getDevice(), packageName);
+    }
+
+    private void runDeviceTests(String packageName, String testClassName, String testMethodName)
+            throws DeviceNotAvailableException {
+        Utils.runDeviceTests(getDevice(), packageName, testClassName, testMethodName);
+    }
+}
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/DirectBootHostTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/DirectBootHostTest.java
new file mode 100644
index 0000000..4983119
--- /dev/null
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/DirectBootHostTest.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.appsecurity.cts;
+
+import android.appsecurity.cts.SplitTests.BaseInstallMultiple;
+
+import com.android.ddmlib.Log;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.testtype.DeviceTestCase;
+import com.android.tradefed.testtype.IAbi;
+import com.android.tradefed.testtype.IAbiReceiver;
+import com.android.tradefed.testtype.IBuildReceiver;
+
+/**
+ * Set of tests that verify behavior of direct boot, if supported.
+ * <p>
+ * Note that these tests drive PIN setup manually instead of relying on device
+ * administrators, which are not supported by all devices.
+ */
+public class DirectBootHostTest extends DeviceTestCase implements IAbiReceiver, IBuildReceiver {
+    private static final String TAG = "DirectBootHostTest";
+
+    private static final String PKG = "com.android.cts.encryptionapp";
+    private static final String CLASS = ".EncryptionAppTest";
+    private static final String APK = "CtsEncryptionApp.apk";
+
+    private static final String OTHER_APK = "CtsSplitApp.apk";
+    private static final String OTHER_PKG = "com.android.cts.splitapp";
+    private static final String OTHER_CLASS = ".SplitAppTest";
+
+    private static final String MODE_NATIVE = "native";
+    private static final String MODE_EMULATED = "emulated";
+    private static final String MODE_NONE = "none";
+
+    private IAbi mAbi;
+    private IBuildInfo mCtsBuild;
+
+    @Override
+    public void setAbi(IAbi abi) {
+        mAbi = abi;
+    }
+
+    @Override
+    public void setBuild(IBuildInfo buildInfo) {
+        mCtsBuild = buildInfo;
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        assertNotNull(mAbi);
+        assertNotNull(mCtsBuild);
+
+        getDevice().uninstallPackage(PKG);
+        getDevice().uninstallPackage(OTHER_PKG);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+
+        getDevice().uninstallPackage(PKG);
+        getDevice().uninstallPackage(OTHER_PKG);
+    }
+
+    /**
+     * If device has native FBE, verify lifecycle.
+     */
+    public void testDirectBootNative() throws Exception {
+        if (!isSupportedDevice()) {
+            Log.v(TAG, "Device not supported; skipping test");
+            return;
+        } else if (!MODE_NATIVE.equals(getFbeMode())) {
+            Log.v(TAG, "Device doesn't have native FBE; skipping test");
+            return;
+        }
+
+        doDirectBootTest(MODE_NATIVE);
+    }
+
+    /**
+     * If device doesn't have native FBE, enable emulation and verify lifecycle.
+     */
+    public void testDirectBootEmulated() throws Exception {
+        if (!isSupportedDevice()) {
+            Log.v(TAG, "Device not supported; skipping test");
+            return;
+        } else if (MODE_NATIVE.equals(getFbeMode())) {
+            Log.v(TAG, "Device has native FBE; skipping test");
+            return;
+        }
+
+        doDirectBootTest(MODE_EMULATED);
+    }
+
+    /**
+     * If device doesn't have native FBE, verify normal lifecycle.
+     */
+    public void testDirectBootNone() throws Exception {
+        if (!isSupportedDevice()) {
+            Log.v(TAG, "Device not supported; skipping test");
+            return;
+        } else if (MODE_NATIVE.equals(getFbeMode())) {
+            Log.v(TAG, "Device has native FBE; skipping test");
+            return;
+        }
+
+        doDirectBootTest(MODE_NONE);
+    }
+
+    public void doDirectBootTest(String mode) throws Exception {
+        int[] users = {};
+        try {
+            users = createUsersForTest();
+
+            // Set up test app and secure lock screens
+            new InstallMultiple().addApk(APK).run();
+            new InstallMultiple().addApk(OTHER_APK).run();
+
+            // To receive boot broadcasts, kick our other app out of stopped state
+            getDevice().executeShellCommand("am start -a android.intent.action.MAIN"
+                    + " -c android.intent.category.LAUNCHER com.android.cts.splitapp/.MyActivity");
+
+            // Give enough time for PackageManager to persist stopped state
+            Thread.sleep(15000);
+
+            runDeviceTests(PKG, CLASS, "testSetUp", users);
+
+            // Give enough time for vold to update keys
+            Thread.sleep(15000);
+
+            // Reboot system into known state with keys ejected
+            if (MODE_EMULATED.equals(mode)) {
+                getDevice().executeShellCommand("sm set-emulate-fbe true");
+                getDevice().waitForDeviceOnline();
+            } else {
+                getDevice().rebootUntilOnline();
+            }
+            waitForBootCompleted();
+
+            if (MODE_NONE.equals(mode)) {
+                runDeviceTests(PKG, CLASS, "testVerifyUnlockedAndDismiss", users);
+            } else {
+                runDeviceTests(PKG, CLASS, "testVerifyLockedAndDismiss", users);
+            }
+
+        } finally {
+            try {
+                // Remove secure lock screens and tear down test app
+                runDeviceTests(PKG, CLASS, "testTearDown", users);
+            } finally {
+                getDevice().uninstallPackage(PKG);
+                removeUsersForTest(users);
+
+                // Get ourselves back into a known-good state
+                if (MODE_EMULATED.equals(mode)) {
+                    getDevice().executeShellCommand("sm set-emulate-fbe false");
+                    getDevice().waitForDeviceOnline();
+                } else {
+                    getDevice().nonBlockingReboot();
+                }
+                waitForBootCompleted();
+            }
+        }
+    }
+
+    private int[] createUsersForTest() throws DeviceNotAvailableException {
+        // TODO: enable test for multiple users
+        return new int[] { 0 };
+//        return Utils.createUsersForTest(getDevice());
+    }
+
+    private void removeUsersForTest(int[] users) throws DeviceNotAvailableException {
+        Utils.removeUsersForTest(getDevice(), users);
+    }
+
+    private void runDeviceTests(String packageName, String testClassName, String testMethodName,
+            int... users) throws DeviceNotAvailableException {
+        for (int user : users) {
+            Log.d(TAG, "runDeviceTests " + testMethodName + " u" + user);
+            Utils.runDeviceTests(getDevice(), packageName, testClassName, testMethodName, user);
+        }
+    }
+
+    private String getFbeMode() throws Exception {
+        return getDevice().executeShellCommand("sm get-fbe-mode").trim();
+    }
+
+    private boolean isBootCompleted() throws Exception {
+        return "1".equals(getDevice().executeShellCommand("getprop sys.boot_completed").trim());
+    }
+
+    private boolean isSupportedDevice() throws Exception {
+        final String featureList = getDevice().executeShellCommand("pm list features");
+        if (featureList.contains("feature:android.hardware.type.watch\n") ||
+                featureList.contains("feature:android.hardware.type.television\n")) {
+            return false;
+        } else {
+            return true;
+        }
+    }
+
+    private void waitForBootCompleted() throws Exception {
+        for (int i = 0; i < 45; i++) {
+            if (isBootCompleted()) {
+                Log.d(TAG, "Yay, system is ready!");
+                return;
+            }
+            Log.d(TAG, "Waiting for system ready...");
+            Thread.sleep(1000);
+        }
+        throw new AssertionError("System failed to become ready!");
+    }
+
+    private class InstallMultiple extends BaseInstallMultiple<InstallMultiple> {
+        public InstallMultiple() {
+            super(getDevice(), mCtsBuild, mAbi);
+        }
+    }
+}
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/DocumentsTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/DocumentsTest.java
new file mode 100644
index 0000000..d81abb6
--- /dev/null
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/DocumentsTest.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.appsecurity.cts;
+
+import com.android.cts.migration.MigrationHelper;
+
+/**
+ * Set of tests that verify behavior of
+ * {@link android.provider.DocumentsContract} and related intents.
+ */
+public class DocumentsTest extends DocumentsTestCase {
+    private static final String PROVIDER_PKG = "com.android.cts.documentprovider";
+    private static final String PROVIDER_APK = "CtsDocumentProvider.apk";
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        getDevice().uninstallPackage(PROVIDER_PKG);
+
+        assertNull(getDevice().installPackage(
+                MigrationHelper.getTestFile(mCtsBuild, PROVIDER_APK), false));
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+
+        getDevice().uninstallPackage(PROVIDER_PKG);
+    }
+
+    public void testOpenSimple() throws Exception {
+        runDeviceTests(CLIENT_PKG, ".DocumentsClientTest", "testOpenSimple");
+    }
+
+    public void testOpenVirtual() throws Exception {
+        runDeviceTests(CLIENT_PKG, ".DocumentsClientTest", "testOpenVirtual");
+    }
+
+    public void testCreateNew() throws Exception {
+        runDeviceTests(CLIENT_PKG, ".DocumentsClientTest", "testCreateNew");
+    }
+
+    public void testCreateExisting() throws Exception {
+        runDeviceTests(CLIENT_PKG, ".DocumentsClientTest", "testCreateExisting");
+    }
+
+    public void testTree() throws Exception {
+        runDeviceTests(CLIENT_PKG, ".DocumentsClientTest", "testTree");
+    }
+
+    public void testGetContent() throws Exception {
+        runDeviceTests(CLIENT_PKG, ".DocumentsClientTest", "testGetContent");
+    }
+
+    public void testTransferDocument() throws Exception {
+        runDeviceTests(CLIENT_PKG, ".DocumentsClientTest", "testTransferDocument");
+    }
+}
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/DocumentsTestCase.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/DocumentsTestCase.java
new file mode 100644
index 0000000..7bd42b5
--- /dev/null
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/DocumentsTestCase.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.appsecurity.cts;
+
+import com.android.cts.migration.MigrationHelper;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.testtype.DeviceTestCase;
+import com.android.tradefed.testtype.IAbi;
+import com.android.tradefed.testtype.IAbiReceiver;
+import com.android.tradefed.testtype.IBuildReceiver;
+
+/**
+ * Base class for {@link android.provider.DocumentsContract} and related test cases.
+ */
+abstract  class DocumentsTestCase extends DeviceTestCase implements IAbiReceiver, IBuildReceiver {
+    protected static final String CLIENT_PKG = "com.android.cts.documentclient";
+    protected static final String CLIENT_APK = "CtsDocumentClient.apk";
+
+    protected IAbi mAbi;
+    protected IBuildInfo mCtsBuild;
+
+    @Override
+    public void setAbi(IAbi abi) {
+        mAbi = abi;
+    }
+
+    @Override
+    public void setBuild(IBuildInfo buildInfo) {
+        mCtsBuild = buildInfo;
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        assertNotNull(mAbi);
+        assertNotNull(mCtsBuild);
+
+        getDevice().uninstallPackage(CLIENT_PKG);
+
+        assertNull(getDevice().installPackage(
+                MigrationHelper.getTestFile(mCtsBuild, CLIENT_APK), false));
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+
+        getDevice().uninstallPackage(CLIENT_PKG);
+    }
+
+    public void runDeviceTests(String packageName, String testClassName, String testMethodName)
+            throws DeviceNotAvailableException {
+        Utils.runDeviceTests(getDevice(), packageName, testClassName, testMethodName);
+    }
+}
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/ExternalStorageHostTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/ExternalStorageHostTest.java
new file mode 100644
index 0000000..c49340e
--- /dev/null
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/ExternalStorageHostTest.java
@@ -0,0 +1,256 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.appsecurity.cts;
+
+import com.android.compatibility.common.util.AbiUtils;
+import com.android.cts.migration.MigrationHelper;
+import com.android.ddmlib.Log;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.testtype.DeviceTestCase;
+import com.android.tradefed.testtype.IAbi;
+import com.android.tradefed.testtype.IAbiReceiver;
+import com.android.tradefed.testtype.IBuildReceiver;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+
+/**
+ * Set of tests that verify behavior of external storage devices.
+ */
+public class ExternalStorageHostTest extends DeviceTestCase
+        implements IAbiReceiver, IBuildReceiver {
+    private static final String TAG = "ExternalStorageHostTest";
+
+    private static final String COMMON_CLASS =
+            "com.android.cts.externalstorageapp.CommonExternalStorageTest";
+
+    private static final String NONE_APK = "CtsExternalStorageApp.apk";
+    private static final String NONE_PKG = "com.android.cts.externalstorageapp";
+    private static final String NONE_CLASS = ".ExternalStorageTest";
+    private static final String READ_APK = "CtsReadExternalStorageApp.apk";
+    private static final String READ_PKG = "com.android.cts.readexternalstorageapp";
+    private static final String READ_CLASS = ".ReadExternalStorageTest";
+    private static final String WRITE_APK = "CtsWriteExternalStorageApp.apk";
+    private static final String WRITE_PKG = "com.android.cts.writeexternalstorageapp";
+    private static final String WRITE_CLASS = ".WriteExternalStorageTest";
+    private static final String MULTIUSER_APK = "CtsMultiUserStorageApp.apk";
+    private static final String MULTIUSER_PKG = "com.android.cts.multiuserstorageapp";
+    private static final String MULTIUSER_CLASS = ".MultiUserStorageTest";
+
+    private IAbi mAbi;
+    private IBuildInfo mCtsBuild;
+
+    @Override
+    public void setAbi(IAbi abi) {
+        mAbi = abi;
+    }
+
+    @Override
+    public void setBuild(IBuildInfo buildInfo) {
+        mCtsBuild = buildInfo;
+    }
+
+    private File getTestAppFile(String fileName) throws FileNotFoundException {
+        return MigrationHelper.getTestFile(mCtsBuild, fileName);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        assertNotNull(mAbi);
+        assertNotNull(mCtsBuild);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    /**
+     * Verify that app with no external storage permissions works correctly.
+     */
+    public void testExternalStorageNone() throws Exception {
+        final int[] users = createUsersForTest();
+        try {
+            wipePrimaryExternalStorage();
+
+            getDevice().uninstallPackage(NONE_PKG);
+            String[] options = {AbiUtils.createAbiFlag(mAbi.getName())};
+            assertNull(getDevice().installPackage(getTestAppFile(NONE_APK), false, options));
+
+            for (int user : users) {
+                runDeviceTests(NONE_PKG, COMMON_CLASS, user);
+                runDeviceTests(NONE_PKG, NONE_CLASS, user);
+            }
+        } finally {
+            getDevice().uninstallPackage(NONE_PKG);
+            removeUsersForTest(users);
+        }
+    }
+
+    /**
+     * Verify that app with
+     * {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} works
+     * correctly.
+     */
+    public void testExternalStorageRead() throws Exception {
+        final int[] users = createUsersForTest();
+        try {
+            wipePrimaryExternalStorage();
+
+            getDevice().uninstallPackage(READ_PKG);
+            String[] options = {AbiUtils.createAbiFlag(mAbi.getName())};
+            assertNull(getDevice().installPackage(getTestAppFile(READ_APK), false, options));
+
+            for (int user : users) {
+                runDeviceTests(READ_PKG, COMMON_CLASS, user);
+                runDeviceTests(READ_PKG, READ_CLASS, user);
+            }
+        } finally {
+            getDevice().uninstallPackage(READ_PKG);
+            removeUsersForTest(users);
+        }
+    }
+
+    /**
+     * Verify that app with
+     * {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} works
+     * correctly.
+     */
+    public void testExternalStorageWrite() throws Exception {
+        final int[] users = createUsersForTest();
+        try {
+            wipePrimaryExternalStorage();
+
+            getDevice().uninstallPackage(WRITE_PKG);
+            String[] options = {AbiUtils.createAbiFlag(mAbi.getName())};
+            assertNull(getDevice().installPackage(getTestAppFile(WRITE_APK), false, options));
+
+            for (int user : users) {
+                runDeviceTests(WRITE_PKG, COMMON_CLASS, user);
+                runDeviceTests(WRITE_PKG, WRITE_CLASS, user);
+            }
+        } finally {
+            getDevice().uninstallPackage(WRITE_PKG);
+            removeUsersForTest(users);
+        }
+    }
+
+    /**
+     * Verify that app with WRITE_EXTERNAL can leave gifts in external storage
+     * directories belonging to other apps, and those apps can read.
+     */
+    public void testExternalStorageGifts() throws Exception {
+        final int[] users = createUsersForTest();
+        try {
+            wipePrimaryExternalStorage();
+
+            getDevice().uninstallPackage(NONE_PKG);
+            getDevice().uninstallPackage(READ_PKG);
+            getDevice().uninstallPackage(WRITE_PKG);
+            final String[] options = {AbiUtils.createAbiFlag(mAbi.getName())};
+
+            // We purposefully delay the installation of the reading apps to
+            // verify that the daemon correctly invalidates any caches.
+            assertNull(getDevice().installPackage(getTestAppFile(WRITE_APK), false, options));
+            for (int user : users) {
+                runDeviceTests(WRITE_PKG, ".WriteGiftTest", user);
+            }
+
+            assertNull(getDevice().installPackage(getTestAppFile(NONE_APK), false, options));
+            assertNull(getDevice().installPackage(getTestAppFile(READ_APK), false, options));
+            for (int user : users) {
+                runDeviceTests(READ_PKG, ".ReadGiftTest", user);
+                runDeviceTests(NONE_PKG, ".GiftTest", user);
+            }
+        } finally {
+            getDevice().uninstallPackage(NONE_PKG);
+            getDevice().uninstallPackage(READ_PKG);
+            getDevice().uninstallPackage(WRITE_PKG);
+            removeUsersForTest(users);
+        }
+    }
+
+    /**
+     * Test multi-user emulated storage environment, ensuring that each user has
+     * isolated storage.
+     */
+    public void testMultiUserStorageIsolated() throws Exception {
+        final int[] users = createUsersForTest();
+        try {
+            if (users.length == 1) {
+                Log.d(TAG, "Single user device; skipping isolated storage tests");
+                return;
+            }
+
+            final int owner = users[0];
+            final int secondary = users[1];
+
+            // Install our test app
+            getDevice().uninstallPackage(MULTIUSER_PKG);
+            String[] options = {AbiUtils.createAbiFlag(mAbi.getName())};
+            final String installResult = getDevice()
+                    .installPackage(getTestAppFile(MULTIUSER_APK), false, options);
+            assertNull("Failed to install: " + installResult, installResult);
+
+            // Clear data from previous tests
+            runDeviceTests(MULTIUSER_PKG, MULTIUSER_CLASS, "testCleanIsolatedStorage", owner);
+            runDeviceTests(MULTIUSER_PKG, MULTIUSER_CLASS, "testCleanIsolatedStorage", secondary);
+
+            // Have both users try writing into isolated storage
+            runDeviceTests(MULTIUSER_PKG, MULTIUSER_CLASS, "testWriteIsolatedStorage", owner);
+            runDeviceTests(MULTIUSER_PKG, MULTIUSER_CLASS, "testWriteIsolatedStorage", secondary);
+
+            // Verify they both have isolated view of storage
+            runDeviceTests(MULTIUSER_PKG, MULTIUSER_CLASS, "testReadIsolatedStorage", owner);
+            runDeviceTests(MULTIUSER_PKG, MULTIUSER_CLASS, "testReadIsolatedStorage", secondary);
+
+            // Verify they can't poke at each other
+            runDeviceTests(MULTIUSER_PKG, MULTIUSER_CLASS, "testUserIsolation", owner);
+            runDeviceTests(MULTIUSER_PKG, MULTIUSER_CLASS, "testUserIsolation", secondary);
+        } finally {
+            getDevice().uninstallPackage(MULTIUSER_PKG);
+            removeUsersForTest(users);
+        }
+    }
+
+    private void wipePrimaryExternalStorage() throws DeviceNotAvailableException {
+        getDevice().executeShellCommand("rm -rf /sdcard/Android");
+        getDevice().executeShellCommand("rm -rf /sdcard/DCIM");
+        getDevice().executeShellCommand("rm -rf /sdcard/MUST_*");
+    }
+
+    private int[] createUsersForTest() throws DeviceNotAvailableException {
+        return Utils.createUsersForTest(getDevice());
+    }
+
+    private void removeUsersForTest(int[] users) throws DeviceNotAvailableException {
+        Utils.removeUsersForTest(getDevice(), users);
+    }
+
+    private void runDeviceTests(String packageName, String testClassName, int userId)
+            throws DeviceNotAvailableException {
+        Utils.runDeviceTests(getDevice(), packageName, testClassName, userId);
+    }
+
+    private void runDeviceTests(String packageName, String testClassName, String testMethodName,
+            int userId) throws DeviceNotAvailableException {
+        Utils.runDeviceTests(getDevice(), packageName, testClassName, testMethodName, userId);
+    }
+}
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/KeySetHostTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/KeySetHostTest.java
new file mode 100644
index 0000000..53a54dd
--- /dev/null
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/KeySetHostTest.java
@@ -0,0 +1,515 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.appsecurity.cts;
+
+import com.android.cts.migration.MigrationHelper;
+import com.android.ddmlib.Log;
+import com.android.ddmlib.Log.LogLevel;
+import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
+import com.android.ddmlib.testrunner.TestIdentifier;
+import com.android.ddmlib.testrunner.TestResult;
+import com.android.ddmlib.testrunner.TestResult.TestStatus;
+import com.android.ddmlib.testrunner.TestRunResult;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.result.CollectingTestListener;
+import com.android.tradefed.testtype.DeviceTestCase;
+import com.android.tradefed.testtype.IBuildReceiver;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.util.Map;
+
+/**
+ * Tests for Keyset based features.
+ */
+public class KeySetHostTest extends DeviceTestCase implements IBuildReceiver {
+
+    private static final String RUNNER = "android.support.test.runner.AndroidJUnitRunner";
+
+    /* package with device-side tests */
+    private static final String KEYSET_TEST_PKG = "com.android.cts.keysets.testapp";
+    private static final String KEYSET_TEST_APP_APK = "CtsKeySetTestApp.apk";
+
+    /* plain test apks with different signing and upgrade keysets */
+    private static final String KEYSET_PKG = "com.android.cts.keysets";
+    private static final String A_SIGNED_NO_UPGRADE =
+            "CtsKeySetSigningAUpgradeNone.apk";
+    private static final String A_SIGNED_A_UPGRADE =
+            "CtsKeySetSigningAUpgradeA.apk";
+    private static final String A_SIGNED_B_UPGRADE =
+            "CtsKeySetSigningAUpgradeB.apk";
+    private static final String A_SIGNED_A_OR_B_UPGRADE =
+            "CtsKeySetSigningAUpgradeAOrB.apk";
+    private static final String B_SIGNED_A_UPGRADE =
+            "CtsKeySetSigningBUpgradeA.apk";
+    private static final String B_SIGNED_B_UPGRADE =
+            "CtsKeySetSigningBUpgradeB.apk";
+    private static final String A_AND_B_SIGNED_A_UPGRADE =
+            "CtsKeySetSigningAAndBUpgradeA.apk";
+    private static final String A_AND_B_SIGNED_B_UPGRADE =
+            "CtsKeySetSigningAAndBUpgradeB.apk";
+    private static final String A_AND_C_SIGNED_B_UPGRADE =
+            "CtsKeySetSigningAAndCUpgradeB.apk";
+    private static final String SHARED_USR_A_SIGNED_B_UPGRADE =
+            "CtsKeySetSharedUserSigningAUpgradeB.apk";
+    private static final String SHARED_USR_B_SIGNED_B_UPGRADE =
+            "CtsKeySetSharedUserSigningBUpgradeB.apk";
+    private static final String A_SIGNED_BAD_B_B_UPGRADE =
+            "CtsKeySetSigningABadUpgradeB.apk";
+    private static final String C_SIGNED_BAD_A_AB_UPGRADE =
+            "CtsKeySetSigningCBadAUpgradeAB.apk";
+    private static final String A_SIGNED_NO_B_B_UPGRADE =
+            "CtsKeySetSigningANoDefUpgradeB.apk";
+    private static final String A_SIGNED_EC_A_UPGRADE =
+            "CtsKeySetSigningAUpgradeEcA.apk";
+    private static final String EC_A_SIGNED_A_UPGRADE =
+            "CtsKeySetSigningEcAUpgradeA.apk";
+
+    /* package which defines the KEYSET_PERM_NAME signature permission */
+    private static final String KEYSET_PERM_DEF_PKG =
+            "com.android.cts.keysets_permdef";
+
+    /* The apks defining and using the permission have both A and B as upgrade keys */
+    private static final String PERM_DEF_A_SIGNED =
+            "CtsKeySetPermDefSigningA.apk";
+    private static final String PERM_DEF_B_SIGNED =
+            "CtsKeySetPermDefSigningB.apk";
+    private static final String PERM_USE_A_SIGNED =
+            "CtsKeySetPermUseSigningA.apk";
+    private static final String PERM_USE_B_SIGNED =
+            "CtsKeySetPermUseSigningB.apk";
+
+    private static final String PERM_TEST_CLASS =
+        "com.android.cts.keysets.KeySetPermissionsTest";
+
+    private static final String LOG_TAG = "AppsecurityHostTests";
+
+    private File getTestAppFile(String fileName) throws FileNotFoundException {
+        return MigrationHelper.getTestFile(mCtsBuild, fileName);
+    }
+
+    /**
+     * Helper method that checks that all tests in given result passed, and attempts to generate
+     * a meaningful error message if they failed.
+     *
+     * @param result
+     */
+    private void assertDeviceTestsPass(TestRunResult result) {
+        assertFalse(String.format("Failed to successfully run device tests for %s. Reason: %s",
+                result.getName(), result.getRunFailureMessage()), result.isRunFailure());
+
+        if (result.hasFailedTests()) {
+
+            /* build a meaningful error message */
+            StringBuilder errorBuilder = new StringBuilder("on-device tests failed:\n");
+            for (Map.Entry<TestIdentifier, TestResult> resultEntry :
+                result.getTestResults().entrySet()) {
+                if (!resultEntry.getValue().getStatus().equals(TestStatus.PASSED)) {
+                    errorBuilder.append(resultEntry.getKey().toString());
+                    errorBuilder.append(":\n");
+                    errorBuilder.append(resultEntry.getValue().getStackTrace());
+                }
+            }
+            fail(errorBuilder.toString());
+        }
+    }
+
+    /**
+     * Helper method that checks that all tests in given result passed, and attempts to generate
+     * a meaningful error message if they failed.
+     *
+     * @param result
+     */
+    private void assertDeviceTestsFail(String msg, TestRunResult result) {
+        assertFalse(String.format("Failed to successfully run device tests for %s. Reason: %s",
+                result.getName(), result.getRunFailureMessage()), result.isRunFailure());
+
+        if (!result.hasFailedTests()) {
+            fail(msg);
+        }
+    }
+
+    /**
+     * Helper method that will run the specified packages tests on device.
+     *
+     * @param pkgName Android application package for tests
+     * @return <code>true</code> if all tests passed.
+     * @throws DeviceNotAvailableException if connection to device was lost.
+     */
+    private boolean runDeviceTests(String pkgName) throws DeviceNotAvailableException {
+        return runDeviceTests(pkgName, null, null);
+    }
+
+    /**
+     * Helper method that will run the specified packages tests on device.
+     *
+     * @param pkgName Android application package for tests
+     * @return <code>true</code> if all tests passed.
+     * @throws DeviceNotAvailableException if connection to device was lost.
+     */
+    private boolean runDeviceTests(String pkgName, String testClassName, String testMethodName)
+            throws DeviceNotAvailableException {
+        TestRunResult runResult = doRunTests(pkgName, testClassName, testMethodName);
+        return !runResult.hasFailedTests();
+    }
+
+    /**
+     * Helper method to run tests and return the listener that collected the results.
+     *
+     * @param pkgName Android application package for tests
+     * @return the {@link TestRunResult}
+     * @throws DeviceNotAvailableException if connection to device was lost.
+     */
+    private TestRunResult doRunTests(String pkgName, String testClassName,
+            String testMethodName) throws DeviceNotAvailableException {
+
+        RemoteAndroidTestRunner testRunner = new RemoteAndroidTestRunner(pkgName,
+                RUNNER, getDevice().getIDevice());
+        if (testClassName != null && testMethodName != null) {
+            testRunner.setMethodName(testClassName, testMethodName);
+        }
+        CollectingTestListener listener = new CollectingTestListener();
+        getDevice().runInstrumentationTests(testRunner, listener);
+        return listener.getCurrentRunResults();
+    }
+
+    /**
+     * Helper method which installs a package and an upgrade to it.
+     *
+     * @param pkgName - package name of apk.
+     * @param firstApk - first apk to install
+     * @param secondApk - apk to which we attempt to upgrade
+     * @param expectedResult - null if successful, otherwise expected error.
+     */
+    private String testPackageUpgrade(String pkgName, String firstApk,
+             String secondApk) throws Exception {
+        String installResult;
+        try {
+
+            /* cleanup test apps that might be installed from previous partial test run */
+            mDevice.uninstallPackage(pkgName);
+
+            installResult = mDevice.installPackage(getTestAppFile(firstApk),
+                    false);
+            /* we should always succeed on first-install */
+            assertNull(String.format("failed to install %s, Reason: %s", pkgName,
+                       installResult), installResult);
+
+            /* attempt to install upgrade */
+            installResult = mDevice.installPackage(getTestAppFile(secondApk),
+                    true);
+        } finally {
+            mDevice.uninstallPackage(pkgName);
+        }
+        return installResult;
+    }
+    /**
+     * A reference to the device under test.
+     */
+    private ITestDevice mDevice;
+
+    private IBuildInfo mCtsBuild;
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setBuild(IBuildInfo buildInfo) {
+        mCtsBuild = buildInfo;
+    }
+
+    @Override
+        protected void setUp() throws Exception {
+        super.setUp();
+        mDevice = getDevice();
+        assertNotNull(mCtsBuild);
+    }
+
+    /**
+     * Tests for KeySet based key rotation
+     */
+
+    /*
+     * Check if an apk which does not specify an upgrade-key-set may be upgraded
+     * to an apk which does.
+     */
+    public void testNoKSToUpgradeKS() throws Exception {
+        String installResult = testPackageUpgrade(KEYSET_PKG, A_SIGNED_NO_UPGRADE, A_SIGNED_A_UPGRADE);
+        assertNull(String.format("failed to upgrade keyset app from no specified upgrade-key-set"
+                + "to version with specified upgrade-key-set, Reason: %s", installResult),
+                installResult);
+    }
+
+    /*
+     * Check if an apk which does specify an upgrade-key-set may be upgraded
+     * to an apk which does not.
+     */
+    public void testUpgradeKSToNoKS() throws Exception {
+        String installResult = testPackageUpgrade(KEYSET_PKG, A_SIGNED_A_UPGRADE, A_SIGNED_NO_UPGRADE);
+        assertNull(String.format("failed to upgrade keyset app from specified upgrade-key-set"
+                + "to version without specified upgrade-key-set, Reason: %s", installResult),
+                installResult);
+    }
+
+    /*
+     * Check if an apk signed by a key other than the upgrade keyset can update
+     * an app
+     */
+    public void testUpgradeKSWithWrongKey() throws Exception {
+        String installResult = testPackageUpgrade(KEYSET_PKG, A_SIGNED_A_UPGRADE, B_SIGNED_A_UPGRADE);
+        assertNotNull("upgrade to improperly signed app succeeded!", installResult);
+    }
+
+    /*
+     * Check if an apk signed by its signing key, which is not an upgrade key,
+     * can upgrade an app.
+     */
+    public void testUpgradeKSWithWrongSigningKey() throws Exception {
+        String installResult = testPackageUpgrade(KEYSET_PKG, A_SIGNED_B_UPGRADE, A_SIGNED_B_UPGRADE);
+         assertNotNull("upgrade to improperly signed app succeeded!",
+                 installResult);
+    }
+
+    /*
+     * Check if an apk signed by its upgrade key, which is not its signing key,
+     * can upgrade an app.
+     */
+    public void testUpgradeKSWithUpgradeKey() throws Exception {
+        String installResult = testPackageUpgrade(KEYSET_PKG, A_SIGNED_B_UPGRADE, B_SIGNED_B_UPGRADE);
+        assertNull(String.format("failed to upgrade keyset app from one signed by key-a"
+                 + "to version signed by upgrade-key-set key-b, Reason: %s", installResult),
+                 installResult);
+    }
+
+    /*
+     * Check if an apk signed by its upgrade key, which is its signing key, can
+     * upgrade an app.
+     */
+    public void testUpgradeKSWithSigningUpgradeKey() throws Exception {
+        String installResult = testPackageUpgrade(KEYSET_PKG, A_SIGNED_A_UPGRADE, A_SIGNED_A_UPGRADE);
+        assertNull(String.format("failed to upgrade keyset app from one signed by key-a"
+                    + "to version signed by upgrade-key-set key-b, Reason: %s", installResult),
+                    installResult);
+    }
+
+    /*
+     * Check if an apk signed by multiple keys, one of which is its upgrade key,
+     * can upgrade an app.
+     */
+    public void testMultipleUpgradeKSWithUpgradeKey() throws Exception {
+        String installResult = testPackageUpgrade(KEYSET_PKG, A_SIGNED_A_UPGRADE,
+                A_AND_B_SIGNED_A_UPGRADE);
+        assertNull(String.format("failed to upgrade keyset app from one signed by key-a"
+                + "to version signed by upgrade-key-set key-b, Reason: %s", installResult),
+                installResult);
+    }
+
+    /*
+     * Check if an apk signed by multiple keys, its signing keys,
+     * but none of which is an upgrade key, can upgrade an app.
+     */
+    public void testMultipleUpgradeKSWithSigningKey() throws Exception {
+        String installResult = testPackageUpgrade(KEYSET_PKG, A_AND_C_SIGNED_B_UPGRADE,
+                A_AND_C_SIGNED_B_UPGRADE);
+        assertNotNull("upgrade to improperly signed app succeeded!", installResult);
+    }
+
+    /*
+     * Check if an apk which defines multiple (two) upgrade keysets is
+     * upgrade-able by either.
+     */
+    public void testUpgradeKSWithMultipleUpgradeKeySetsFirstKey() throws Exception {
+        String installResult = testPackageUpgrade(KEYSET_PKG, A_SIGNED_A_OR_B_UPGRADE,
+                A_SIGNED_A_UPGRADE);
+        assertNull(String.format("failed to upgrade keyset app from one signed by key-a"
+                + "to one signed by first upgrade keyset key-a, Reason: %s", installResult),
+                installResult);
+        installResult = testPackageUpgrade(KEYSET_PKG, A_SIGNED_A_OR_B_UPGRADE,
+                B_SIGNED_B_UPGRADE);
+        assertNull(String.format("failed to upgrade keyset app from one signed by key-a"
+                + "to one signed by second upgrade keyset key-b, Reason: %s", installResult),
+                installResult);
+    }
+
+    /**
+     * Helper method which installs a package defining a permission and a package
+     * using the permission, and then rotates the signing keys for one of them.
+     * A device-side test is then used to ascertain whether or not the permission
+     * was appropriately gained or lost.
+     *
+     * @param permDefApk - apk to install which defines the sig-permissoin
+     * @param permUseApk - apk to install which declares it uses the permission
+     * @param upgradeApk - apk to install which upgrades one of the first two
+     * @param hasPermBeforeUpgrade - whether we expect the consuming app to have
+     *        the permission before the upgrade takes place.
+     * @param hasPermAfterUpgrade - whether we expect the consuming app to have
+     *        the permission after the upgrade takes place.
+     */
+    private void testKeyRotationPerm(String permDefApk, String permUseApk,
+            String upgradeApk, boolean hasPermBeforeUpgrade,
+            boolean hasPermAfterUpgrade) throws Exception {
+        try {
+
+            /* cleanup test apps that might be installed from previous partial test run */
+            mDevice.uninstallPackage(KEYSET_PKG);
+            mDevice.uninstallPackage(KEYSET_PERM_DEF_PKG);
+            mDevice.uninstallPackage(KEYSET_TEST_PKG);
+
+            /* install PERM_DEF, KEYSET_APP and KEYSET_TEST_APP */
+            String installResult = mDevice.installPackage(
+                    getTestAppFile(permDefApk), false);
+            assertNull(String.format("failed to install keyset perm-def app, Reason: %s",
+                       installResult), installResult);
+            installResult = getDevice().installPackage(
+                    getTestAppFile(permUseApk), false);
+            assertNull(String.format("failed to install keyset test app. Reason: %s",
+                    installResult), installResult);
+            installResult = getDevice().installPackage(
+                    getTestAppFile(KEYSET_TEST_APP_APK), false);
+            assertNull(String.format("failed to install keyset test app. Reason: %s",
+                    installResult), installResult);
+
+            /* verify package does have perm */
+            TestRunResult result = doRunTests(KEYSET_TEST_PKG, PERM_TEST_CLASS,
+                    "testHasPerm");
+            if (hasPermBeforeUpgrade) {
+                assertDeviceTestsPass(result);
+            } else {
+                assertDeviceTestsFail(" has permission permission it should not have.", result);
+            }
+
+            /* rotate keys */
+            installResult = mDevice.installPackage(getTestAppFile(upgradeApk),
+                    true);
+            result = doRunTests(KEYSET_TEST_PKG, PERM_TEST_CLASS,
+                    "testHasPerm");
+            if (hasPermAfterUpgrade) {
+                assertDeviceTestsPass(result);
+            } else {
+                assertDeviceTestsFail(KEYSET_PKG + " has permission it should not have.", result);
+            }
+        } finally {
+            mDevice.uninstallPackage(KEYSET_PKG);
+            mDevice.uninstallPackage(KEYSET_PERM_DEF_PKG);
+            mDevice.uninstallPackage(KEYSET_TEST_PKG);
+        }
+    }
+
+    /*
+     * Check if an apk gains signature-level permission after changing to a new
+     * signature, for which a permission should be granted.
+     */
+    public void testUpgradeSigPermGained() throws Exception {
+        testKeyRotationPerm(PERM_DEF_A_SIGNED, PERM_USE_B_SIGNED, PERM_USE_A_SIGNED,
+                false, true);
+    }
+
+    /*
+     * Check if an apk loses signature-level permission after changing to a new
+     * signature, from one for which a permission was previously granted.
+     */
+    public void testUpgradeSigPermLost() throws Exception {
+        testKeyRotationPerm(PERM_DEF_A_SIGNED, PERM_USE_A_SIGNED, PERM_USE_B_SIGNED,
+                true, false);
+    }
+
+    /*
+     * Check if an apk gains signature-level permission after the app defining
+     * it rotates to the same signature.
+     */
+    public void testUpgradeDefinerSigPermGained() throws Exception {
+        testKeyRotationPerm(PERM_DEF_A_SIGNED, PERM_USE_B_SIGNED, PERM_DEF_B_SIGNED,
+                false, true);
+    }
+
+    /*
+     * Check if an apk loses signature-level permission after the app defining
+     * it rotates to a different signature.
+     */
+    public void testUpgradeDefinerSigPermLost() throws Exception {
+        testKeyRotationPerm(PERM_DEF_A_SIGNED, PERM_USE_A_SIGNED, PERM_DEF_B_SIGNED,
+                true, false);
+    }
+
+    /*
+     * Check if an apk which indicates it uses a sharedUserId and defines an
+     * upgrade keyset is allowed to rotate to that keyset.
+     */
+    public void testUpgradeSharedUser() throws Exception {
+        String installResult = testPackageUpgrade(KEYSET_PKG, SHARED_USR_A_SIGNED_B_UPGRADE,
+                SHARED_USR_B_SIGNED_B_UPGRADE);
+        assertNotNull("upgrade allowed for app with shareduserid!", installResult);
+    }
+
+    /*
+     * Check that an apk with an upgrade key represented by a bad public key
+     * fails to install.
+     */
+    public void testBadUpgradeBadPubKey() throws Exception {
+        mDevice.uninstallPackage(KEYSET_PKG);
+        String installResult = mDevice.installPackage(getTestAppFile(A_SIGNED_BAD_B_B_UPGRADE),
+                false);
+        assertNotNull("Installation of apk with upgrade key referring to a bad public key succeeded!",
+                installResult);
+    }
+
+    /*
+     * Check that an apk with an upgrade keyset that includes a bad public key fails to install.
+     */
+    public void testBadUpgradeMissingPubKey() throws Exception {
+        mDevice.uninstallPackage(KEYSET_PKG);
+        String installResult = mDevice.installPackage(getTestAppFile(C_SIGNED_BAD_A_AB_UPGRADE),
+                false);
+        assertNotNull("Installation of apk with upgrade key referring to a bad public key succeeded!",
+                installResult);
+    }
+
+    /*
+     * Check that an apk with an upgrade key that has no corresponding public key fails to install.
+     */
+    public void testBadUpgradeNoPubKey() throws Exception {
+        mDevice.uninstallPackage(KEYSET_PKG);
+        String installResult = mDevice.installPackage(getTestAppFile(A_SIGNED_NO_B_B_UPGRADE),
+                false);
+        assertNotNull("Installation of apk with upgrade key referring to a bad public key succeeded!",
+                installResult);
+    }
+
+    /*
+     * Check if an apk signed by RSA pub key can upgrade to apk signed by EC key.
+     */
+    public void testUpgradeKSRsaToEC() throws Exception {
+        String installResult = testPackageUpgrade(KEYSET_PKG, A_SIGNED_EC_A_UPGRADE,
+                EC_A_SIGNED_A_UPGRADE);
+        assertNull(String.format("failed to upgrade keyset app from one signed by RSA key"
+                 + "to version signed by EC upgrade-key-set, Reason: %s", installResult),
+                 installResult);
+    }
+
+    /*
+     * Check if an apk signed by EC pub key can upgrade to apk signed by RSA key.
+     */
+    public void testUpgradeKSECToRSA() throws Exception {
+        String installResult = testPackageUpgrade(KEYSET_PKG, EC_A_SIGNED_A_UPGRADE,
+                A_SIGNED_EC_A_UPGRADE);
+        assertNull(String.format("failed to upgrade keyset app from one signed by EC key"
+                 + "to version signed by RSA upgrade-key-set, Reason: %s", installResult),
+                 installResult);
+    }
+}
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/PermissionsHostTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/PermissionsHostTest.java
new file mode 100644
index 0000000..6c5e4a5
--- /dev/null
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/PermissionsHostTest.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.appsecurity.cts;
+
+import com.android.cts.migration.MigrationHelper;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.testtype.DeviceTestCase;
+import com.android.tradefed.testtype.IAbi;
+import com.android.tradefed.testtype.IAbiReceiver;
+import com.android.tradefed.testtype.IBuildReceiver;
+
+/**
+ * Set of tests that verify behavior of runtime permissions, including both
+ * dynamic granting and behavior of legacy apps.
+ */
+public class PermissionsHostTest extends DeviceTestCase implements IAbiReceiver, IBuildReceiver {
+    private static final String PKG = "com.android.cts.usepermission";
+
+    private static final String APK = "CtsUsePermissionApp.apk";
+    private static final String APK_COMPAT = "CtsUsePermissionAppCompat.apk";
+
+    private IAbi mAbi;
+    private IBuildInfo mCtsBuild;
+
+    @Override
+    public void setAbi(IAbi abi) {
+        mAbi = abi;
+    }
+
+    @Override
+    public void setBuild(IBuildInfo buildInfo) {
+        mCtsBuild = buildInfo;
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        assertNotNull(mAbi);
+        assertNotNull(mCtsBuild);
+
+        getDevice().uninstallPackage(PKG);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+
+        getDevice().uninstallPackage(PKG);
+    }
+
+    public void testFail() throws Exception {
+        // Sanity check that remote failure is host failure
+        assertNull(getDevice().installPackage(
+                MigrationHelper.getTestFile(mCtsBuild, APK), false, false));
+        try {
+            runDeviceTests(PKG, ".UsePermissionTest", "testFail");
+            fail("Expected remote failure");
+        } catch (AssertionError expected) {
+        }
+    }
+
+    public void testKill() throws Exception {
+        // Sanity check that remote kill is host failure
+        assertNull(getDevice().installPackage(
+                MigrationHelper.getTestFile(mCtsBuild, APK), false, false));
+        try {
+            runDeviceTests(PKG, ".UsePermissionTest", "testKill");
+            fail("Expected remote failure");
+        } catch (AssertionError expected) {
+        }
+    }
+
+    public void testDefault() throws Exception {
+        assertNull(getDevice().installPackage(
+                MigrationHelper.getTestFile(mCtsBuild, APK), false, false));
+        runDeviceTests(PKG, ".UsePermissionTest", "testDefault");
+    }
+
+    public void testGranted() throws Exception {
+        assertNull(getDevice().installPackage(
+                MigrationHelper.getTestFile(mCtsBuild, APK), false, false));
+        grantPermission(PKG, "android.permission.READ_EXTERNAL_STORAGE");
+        grantPermission(PKG, "android.permission.WRITE_EXTERNAL_STORAGE");
+        runDeviceTests(PKG, ".UsePermissionTest", "testGranted");
+    }
+
+    public void testInteractiveGrant() throws Exception {
+        assertNull(getDevice().installPackage(
+                MigrationHelper.getTestFile(mCtsBuild, APK), false, false));
+        runDeviceTests(PKG, ".UsePermissionTest", "testInteractiveGrant");
+    }
+
+    public void testRuntimeGroupGrantSpecificity() throws Exception {
+        assertNull(getDevice().installPackage(
+                MigrationHelper.getTestFile(mCtsBuild, APK), false, false));
+        runDeviceTests(PKG, ".UsePermissionTest", "testRuntimeGroupGrantSpecificity");
+    }
+
+    public void testRuntimeGroupGrantExpansion() throws Exception {
+        assertNull(getDevice().installPackage(
+                MigrationHelper.getTestFile(mCtsBuild, APK), false, false));
+        runDeviceTests(PKG, ".UsePermissionTest", "testRuntimeGroupGrantExpansion");
+    }
+
+    public void testCompatDefault() throws Exception {
+        assertNull(getDevice().installPackage(MigrationHelper.getTestFile(mCtsBuild, APK_COMPAT),
+                false, false));
+        runDeviceTests(PKG, ".UsePermissionCompatTest", "testCompatDefault");
+    }
+
+    public void testCompatRevoked() throws Exception {
+        assertNull(getDevice().installPackage(MigrationHelper.getTestFile(mCtsBuild, APK_COMPAT),
+                false, false));
+        setAppOps(PKG, "android:read_external_storage", "deny");
+        setAppOps(PKG, "android:write_external_storage", "deny");
+        runDeviceTests(PKG, ".UsePermissionCompatTest", "testCompatRevoked");
+    }
+
+    private void runDeviceTests(String packageName, String testClassName, String testMethodName)
+            throws DeviceNotAvailableException {
+        Utils.runDeviceTests(getDevice(), packageName, testClassName, testMethodName);
+    }
+
+    private void grantPermission(String pkg, String permission) throws Exception {
+        assertEmpty(getDevice().executeShellCommand("pm grant " + pkg + " " + permission));
+    }
+
+    private void revokePermission(String pkg, String permission) throws Exception {
+        assertEmpty(getDevice().executeShellCommand("pm revoke " + pkg + " " + permission));
+    }
+
+    private void setAppOps(String pkg, String op, String mode) throws Exception {
+        assertEmpty(getDevice().executeShellCommand("appops set " + pkg + " " + op + " " + mode));
+    }
+
+    private static void assertEmpty(String str) {
+        if (str == null || str.length() == 0) {
+            return;
+        } else {
+            fail("Expected empty string but found " + str);
+        }
+    }
+}
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/PkgInstallSignatureVerificationTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/PkgInstallSignatureVerificationTest.java
new file mode 100644
index 0000000..f6c6f18
--- /dev/null
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/PkgInstallSignatureVerificationTest.java
@@ -0,0 +1,413 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.appsecurity.cts;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Locale;
+
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceTestCase;
+import com.android.tradefed.testtype.IBuildReceiver;
+
+/**
+ * Tests for APK signature verification during installation.
+ */
+public class PkgInstallSignatureVerificationTest extends DeviceTestCase implements IBuildReceiver {
+
+    private static final String TEST_PKG = "android.appsecurity.cts.tinyapp";
+    private static final String TEST_APK_RESOURCE_PREFIX = "/pkgsigverify/";
+
+    private static final String[] DSA_KEY_NAMES = {"1024", "2048", "3072"};
+    private static final String[] EC_KEY_NAMES = {"p256", "p384", "p521"};
+    private static final String[] RSA_KEY_NAMES = {"1024", "2048", "3072", "4096", "8192", "16384"};
+    private static final String[] RSA_KEY_NAMES_2048_AND_LARGER =
+            {"2048", "3072", "4096", "8192", "16384"};
+
+
+    /** Device under test. */
+    private ITestDevice mDevice;
+
+    private IBuildInfo mCtsBuild;
+
+    @Override
+    public void setBuild(IBuildInfo buildInfo) {
+        mCtsBuild = buildInfo;
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mDevice = getDevice();
+        assertNotNull(mCtsBuild);
+        uninstallPackage();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        try {
+            uninstallPackage();
+        } catch (DeviceNotAvailableException ignored) {
+        } finally {
+            super.tearDown();
+        }
+    }
+
+    public void testInstallOriginalSucceeds() throws Exception {
+        // APK signed with v1 and v2 schemes. Obtained by building
+        // cts/hostsidetests/appsecurity/test-apps/tinyapp.
+        assertInstallSucceeds("original.apk");
+    }
+
+    public void testInstallV1OneSignerMD5withRSA() throws Exception {
+        // APK signed with v1 scheme only, one signer.
+        assertInstallSucceedsForEach("v1-only-with-rsa-pkcs1-md5-%s.apk", RSA_KEY_NAMES);
+    }
+
+    public void testInstallV1OneSignerSHA1withRSA() throws Exception {
+        // APK signed with v1 scheme only, one signer.
+        assertInstallSucceedsForEach("v1-only-with-rsa-pkcs1-sha1-%s.apk", RSA_KEY_NAMES);
+    }
+
+    public void testInstallV1OneSignerSHA224withRSA() throws Exception {
+        // APK signed with v1 scheme only, one signer.
+        assertInstallSucceedsForEach("v1-only-with-rsa-pkcs1-sha224-%s.apk", RSA_KEY_NAMES);
+    }
+
+    public void testInstallV1OneSignerSHA256withRSA() throws Exception {
+        // APK signed with v1 scheme only, one signer.
+        assertInstallSucceedsForEach("v1-only-with-rsa-pkcs1-sha256-%s.apk", RSA_KEY_NAMES);
+    }
+
+    public void testInstallV1OneSignerSHA384withRSA() throws Exception {
+        // APK signed with v1 scheme only, one signer.
+        assertInstallSucceedsForEach("v1-only-with-rsa-pkcs1-sha384-%s.apk", RSA_KEY_NAMES);
+    }
+
+    public void testInstallV1OneSignerSHA512withRSA() throws Exception {
+        // APK signed with v1 scheme only, one signer.
+        assertInstallSucceedsForEach("v1-only-with-rsa-pkcs1-sha512-%s.apk", RSA_KEY_NAMES);
+    }
+
+    public void testInstallV1OneSignerSHA1withECDSA() throws Exception {
+        // APK signed with v1 scheme only, one signer.
+        assertInstallSucceedsForEach("v1-only-with-ecdsa-sha1-%s.apk", EC_KEY_NAMES);
+    }
+
+    public void testInstallV1OneSignerSHA224withECDSA() throws Exception {
+        // APK signed with v1 scheme only, one signer.
+        assertInstallSucceedsForEach("v1-only-with-ecdsa-sha224-%s.apk", EC_KEY_NAMES);
+    }
+
+    public void testInstallV1OneSignerSHA256withECDSA() throws Exception {
+        // APK signed with v1 scheme only, one signer.
+        assertInstallSucceedsForEach("v1-only-with-ecdsa-sha256-%s.apk", EC_KEY_NAMES);
+    }
+
+    public void testInstallV1OneSignerSHA384withECDSA() throws Exception {
+        // APK signed with v1 scheme only, one signer.
+        assertInstallSucceedsForEach("v1-only-with-ecdsa-sha384-%s.apk", EC_KEY_NAMES);
+    }
+
+    public void testInstallV1OneSignerSHA512withECDSA() throws Exception {
+        // APK signed with v1 scheme only, one signer.
+        assertInstallSucceedsForEach("v1-only-with-ecdsa-sha512-%s.apk", EC_KEY_NAMES);
+    }
+
+    public void testInstallV1OneSignerSHA1withDSA() throws Exception {
+        // APK signed with v1 scheme only, one signer.
+        assertInstallSucceedsForEach("v1-only-with-dsa-sha1-%s.apk", DSA_KEY_NAMES);
+    }
+
+    public void testInstallV1OneSignerSHA224withDSA() throws Exception {
+        // APK signed with v1 scheme only, one signer.
+        assertInstallSucceedsForEach("v1-only-with-dsa-sha224-%s.apk", DSA_KEY_NAMES);
+    }
+
+    public void testInstallV1OneSignerSHA256withDSA() throws Exception {
+        // APK signed with v1 scheme only, one signer.
+        assertInstallSucceedsForEach("v1-only-with-dsa-sha256-%s.apk", DSA_KEY_NAMES);
+    }
+
+//  Android platform doesn't support DSA with SHA-384 and SHA-512.
+//    public void testInstallV1OneSignerSHA384withDSA() throws Exception {
+//        // APK signed with v1 scheme only, one signer.
+//        assertInstallSucceedsForEach("v1-only-with-dsa-sha384-%s.apk", DSA_KEY_NAMES);
+//    }
+//
+//    public void testInstallV1OneSignerSHA512withDSA() throws Exception {
+//        // APK signed with v1 scheme only, one signer.
+//        assertInstallSucceedsForEach("v1-only-with-dsa-sha512-%s.apk", DSA_KEY_NAMES);
+//    }
+
+    public void testInstallV2StrippedFails() throws Exception {
+        // APK signed with v1 and v2 schemes, but v2 signature was stripped from the file (by using
+        // zipalign).
+        // This should fail because the v1 signature indicates that the APK was supposed to be
+        // signed with v2 scheme as well, making the platform's anti-stripping protections reject
+        // the APK.
+        assertInstallFailsWithError("v2-stripped.apk", "Signature stripped");
+
+        // Similar to above, but the X-Android-APK-Signed anti-stripping header in v1 signature
+        // lists unknown signature schemes in addition to APK Signature Scheme v2. Unknown schemes
+        // should be ignored.
+        assertInstallFailsWithError(
+                "v2-stripped-with-ignorable-signing-schemes.apk", "Signature stripped");
+    }
+
+    public void testInstallV2OneSignerOneSignature() throws Exception {
+        // APK signed with v2 scheme only, one signer, one signature.
+        assertInstallSucceedsForEach("v2-only-with-dsa-sha256-%s.apk", DSA_KEY_NAMES);
+        assertInstallSucceedsForEach("v2-only-with-ecdsa-sha256-%s.apk", EC_KEY_NAMES);
+        assertInstallSucceedsForEach("v2-only-with-rsa-pkcs1-sha256-%s.apk", RSA_KEY_NAMES);
+        assertInstallSucceedsForEach("v2-only-with-rsa-pss-sha256-%s.apk", RSA_KEY_NAMES);
+
+        // DSA with SHA-512 is not supported by Android platform and thus APK Signature Scheme v2
+        // does not support that either
+        // assertInstallSucceedsForEach("v2-only-with-dsa-sha512-%s.apk", DSA_KEY_NAMES);
+        assertInstallSucceedsForEach("v2-only-with-ecdsa-sha512-%s.apk", EC_KEY_NAMES);
+        assertInstallSucceedsForEach("v2-only-with-rsa-pkcs1-sha512-%s.apk", RSA_KEY_NAMES);
+        assertInstallSucceedsForEach(
+                "v2-only-with-rsa-pss-sha512-%s.apk",
+                RSA_KEY_NAMES_2048_AND_LARGER // 1024-bit key is too short for PSS with SHA-512
+                );
+    }
+
+    public void testInstallV2SignatureDoesNotVerify() throws Exception {
+        // APK signed with v2 scheme only, but the signature over signed-data does not verify.
+        String error = "signature did not verify";
+
+        // Bitflip in certificate field inside signed-data. Based on
+        // v2-only-with-dsa-sha256-1024.apk.
+        assertInstallFailsWithError("v2-only-with-dsa-sha256-1024-sig-does-not-verify.apk", error);
+
+        // Signature claims to be RSA PKCS#1 v1.5 with SHA-256, but is actually using SHA-512.
+        // Based on v2-only-with-rsa-pkcs1-sha256-2048.apk.
+        assertInstallFailsWithError(
+                "v2-only-with-rsa-pkcs1-sha256-2048-sig-does-not-verify.apk", error);
+
+        // Signature claims to be RSA PSS with SHA-256 and 32 bytes of salt, but is actually using 0
+        // bytes of salt. Based on v2-only-with-rsa-pkcs1-sha256-2048.apk. Obtained by modifying APK
+        // signer to use the wrong amount of salt.
+        assertInstallFailsWithError(
+                "v2-only-with-rsa-pss-sha256-2048-sig-does-not-verify.apk", error);
+
+        // Bitflip in the ECDSA signature. Based on v2-only-with-ecdsa-sha256-p256.apk.
+        assertInstallFailsWithError(
+                "v2-only-with-ecdsa-sha256-p256-sig-does-not-verify.apk", error);
+    }
+
+    public void testInstallV2ContentDigestMismatch() throws Exception {
+        // APK signed with v2 scheme only, but the digest of contents does not match the digest
+        // stored in signed-data.
+        String error = "digest of contents did not verify";
+
+        // Based on v2-only-with-rsa-pkcs1-sha512-4096.apk. Obtained by modifying APK signer to
+        // flip the leftmost bit in content digest before signing signed-data.
+        assertInstallFailsWithError(
+                "v2-only-with-rsa-pkcs1-sha512-4096-digest-mismatch.apk", error);
+
+        // Based on v2-only-with-ecdsa-sha256-p256.apk. Obtained by modifying APK signer to flip the
+        // leftmost bit in content digest before signing signed-data.
+        assertInstallFailsWithError(
+                "v2-only-with-ecdsa-sha256-p256-digest-mismatch.apk", error);
+    }
+
+    public void testInstallNoApkSignatureSchemeBlock() throws Exception {
+        // APK signed with v2 scheme only, but the rules for verifying APK Signature Scheme v2
+        // signatures say that this APK must not be verified using APK Signature Scheme v2.
+
+        // Obtained from v2-only-with-rsa-pkcs1-sha512-4096.apk by flipping a bit in the magic
+        // field in the footer of APK Signing Block. This makes the APK Signing Block disappear.
+        assertInstallFails("v2-only-wrong-apk-sig-block-magic.apk");
+
+        // Obtained by modifying APK signer to insert "GARBAGE" between ZIP Central Directory and
+        // End of Central Directory. The APK is otherwise fine and is signed with APK Signature
+        // Scheme v2. Based on v2-only-with-rsa-pkcs1-sha256.apk.
+        assertInstallFails("v2-only-garbage-between-cd-and-eocd.apk");
+
+        // Obtained by modifying APK signer to truncate the ZIP Central Directory by one byte. The
+        // APK is otherwise fine and is signed with APK Signature Scheme v2. Based on
+        // v2-only-with-rsa-pkcs1-sha256.apk
+        assertInstallFails("v2-only-truncated-cd.apk");
+
+        // Obtained by modifying the size in APK Signature Block header. Based on
+        // v2-only-with-ecdsa-sha512-p521.apk.
+        assertInstallFails("v2-only-apk-sig-block-size-mismatch.apk");
+
+        // Obtained by modifying the ID under which APK Signature Scheme v2 Block is stored in
+        // APK Signing Block and by modifying the APK signer to not insert anti-stripping
+        // protections into JAR Signature. The APK should appear as having no APK Signature Scheme
+        // v2 Block and should thus successfully verify using JAR Signature Scheme.
+        assertInstallSucceeds("v1-with-apk-sig-block-but-without-apk-sig-scheme-v2-block.apk");
+    }
+
+    public void testInstallV2UnknownPairIgnoredInApkSigningBlock() throws Exception {
+        // Obtained by modifying APK signer to emit an unknown ID-value pair into APK Signing Block
+        // before the ID-value pair containing the APK Signature Scheme v2 Block. The unknown
+        // ID-value should be ignored.
+        assertInstallSucceeds("v2-only-unknown-pair-in-apk-sig-block.apk");
+    }
+
+    public void testInstallV2IgnoresUnknownSignatureAlgorithms() throws Exception {
+        // APK is signed with a known signature algorithm and with a couple of unknown ones.
+        // Obtained by modifying APK signer to use "unknown" signature algorithms in addition to
+        // known ones.
+        assertInstallSucceeds("v2-only-with-ignorable-unsupported-sig-algs.apk");
+    }
+
+    public void testInstallV2RejectsMismatchBetweenSignaturesAndDigestsBlocks() throws Exception {
+        // APK is signed with a single signature algorithm, but the digests block claims that it is
+        // signed with two different signature algorithms. Obtained by modifying APK Signer to
+        // emit an additional digest record with signature algorithm 0x12345678.
+        assertInstallFailsWithError(
+                "v2-only-signatures-and-digests-block-mismatch.apk",
+                "Signature algorithms don't match between digests and signatures records");
+    }
+
+    public void testInstallV2RejectsMismatchBetweenPublicKeyAndCertificate() throws Exception {
+        // APK is signed with v2 only. The public key field does not match the public key in the
+        // leaf certificate. Obtained by modifying APK signer to write out a modified leaf
+        // certificate where the RSA modulus has a bitflip.
+        assertInstallFailsWithError(
+                "v2-only-cert-and-public-key-mismatch.apk",
+                "Public key mismatch between certificate and signature record");
+    }
+
+    public void testInstallV2RejectsSignerBlockWithNoCertificates() throws Exception {
+        // APK is signed with v2 only. There are no certificates listed in the signer block.
+        // Obtained by modifying APK signer to output no certificates.
+        assertInstallFailsWithError("v2-only-no-certs-in-sig.apk", "No certificates listed");
+    }
+
+    public void testInstallTwoSigners() throws Exception {
+        // APK signed by two different signers.
+        assertInstallSucceeds("two-signers.apk");
+        // Because the install attempt below is an update, it also tests that the signing
+        // certificates exposed by v2 signatures above are the same as the one exposed by v1
+        // signatures in this APK.
+        assertInstallSucceeds("v1-only-two-signers.apk");
+        assertInstallSucceeds("v2-only-two-signers.apk");
+    }
+
+    public void testInstallV2TwoSignersRejectsWhenOneBroken() throws Exception {
+        // Bitflip in the ECDSA signature of second signer. Based on two-signers.apk.
+        // This asserts that breakage in any signer leads to rejection of the APK.
+        assertInstallFailsWithError(
+                "two-signers-second-signer-v2-broken.apk", "signature did not verify");
+    }
+
+    public void testInstallV2RejectsWhenMissingCode() throws Exception {
+        // Obtained by removing classes.dex from original.apk and then signing with v2 only.
+        // Although this has nothing to do with v2 signature verification, package manager wants
+        // signature verification / certificate collection to reject APKs with missing code
+        // (classes.dex) unless requested otherwise.
+        assertInstallFailsWithError("v2-only-missing-classes.dex.apk", "code is missing");
+    }
+
+    private void assertInstallSucceeds(String apkFilenameInResources) throws Exception {
+        String installResult = installPackageFromResource(apkFilenameInResources);
+        if (installResult != null) {
+            fail("Failed to install " + apkFilenameInResources + ": " + installResult);
+        }
+    }
+
+    private void assertInstallSucceedsForEach(
+            String apkFilenamePatternInResources, String[] args) throws Exception {
+        for (String arg : args) {
+            String apkFilenameInResources =
+                    String.format(Locale.US, apkFilenamePatternInResources, arg);
+            String installResult = installPackageFromResource(apkFilenameInResources);
+            if (installResult != null) {
+                fail("Failed to install " + apkFilenameInResources + ": " + installResult);
+            }
+            try {
+                uninstallPackage();
+            } catch (Exception e) {
+                throw new RuntimeException(
+                        "Failed to uninstall after installing " + apkFilenameInResources, e);
+            }
+        }
+    }
+
+    private void assertInstallFailsWithError(
+            String apkFilenameInResources, String errorSubstring) throws Exception {
+        String installResult = installPackageFromResource(apkFilenameInResources);
+        if (installResult == null) {
+            fail("Install of " + apkFilenameInResources + " succeeded but was expected to fail"
+                    + " with \"" + errorSubstring + "\"");
+        }
+        assertContains(
+                "Install failure message of " + apkFilenameInResources,
+                errorSubstring,
+                installResult);
+    }
+
+    private void assertInstallFails(String apkFilenameInResources) throws Exception {
+        String installResult = installPackageFromResource(apkFilenameInResources);
+        if (installResult == null) {
+            fail("Install of " + apkFilenameInResources + " succeeded but was expected to fail");
+        }
+    }
+
+    private static void assertContains(String message, String expectedSubstring, String actual) {
+        String errorPrefix = ((message != null) && (message.length() > 0)) ? (message + ": ") : "";
+        if (actual == null) {
+            fail(errorPrefix + "Expected to contain \"" + expectedSubstring + "\", but was null");
+        }
+        if (!actual.contains(expectedSubstring)) {
+            fail(errorPrefix + "Expected to contain \"" + expectedSubstring + "\", but was \""
+                    + actual + "\"");
+        }
+    }
+
+    private String installPackageFromResource(String apkFilenameInResources)
+            throws IOException, DeviceNotAvailableException {
+        // ITestDevice.installPackage API requires the APK to be install to be a File. We thus
+        // copy the requested resource into a temporary file, attempt to install it, and delete the
+        // file during cleanup.
+
+        String fullResourceName = TEST_APK_RESOURCE_PREFIX + apkFilenameInResources;
+        File apkFile = File.createTempFile("pkginstalltest", ".apk");
+        try {
+            try (InputStream in = getClass().getResourceAsStream(fullResourceName);
+                    OutputStream out = new BufferedOutputStream(new FileOutputStream(apkFile))) {
+                if (in == null) {
+                    throw new IllegalArgumentException("Resource not found: " + fullResourceName);
+                }
+                byte[] buf = new byte[65536];
+                int chunkSize;
+                while ((chunkSize = in.read(buf)) != -1) {
+                    out.write(buf, 0, chunkSize);
+                }
+            }
+            return mDevice.installPackage(apkFile, true);
+        } finally {
+            apkFile.delete();
+        }
+    }
+
+    private String uninstallPackage() throws DeviceNotAvailableException {
+        return mDevice.uninstallPackage(TEST_PKG);
+    }
+}
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/ScopedDirectoryAccessTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/ScopedDirectoryAccessTest.java
new file mode 100644
index 0000000..ffc7597
--- /dev/null
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/ScopedDirectoryAccessTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.appsecurity.cts;
+
+/**
+ * Set of tests that verify behavior of the Scoped Directory access API.
+ */
+public class ScopedDirectoryAccessTest extends DocumentsTestCase {
+
+    public void testInvalidPath() throws Exception {
+        runDeviceTests(CLIENT_PKG, ".ScopedDirectoryAccessClientTest", "testInvalidPath");
+    }
+
+    public void testUserRejects() throws Exception {
+        runDeviceTests(CLIENT_PKG, ".ScopedDirectoryAccessClientTest", "testUserRejects");
+    }
+
+    public void testUserAccepts() throws Exception {
+        runDeviceTests(CLIENT_PKG, ".ScopedDirectoryAccessClientTest", "testUserAccepts");
+    }
+
+    public void testUserAcceptsNewDirectory() throws Exception {
+        runDeviceTests(CLIENT_PKG, ".ScopedDirectoryAccessClientTest",
+                "testUserAcceptsNewDirectory");
+    }
+
+    public void testNotAskedAgain() throws Exception {
+        runDeviceTests(CLIENT_PKG, ".ScopedDirectoryAccessClientTest", "testNotAskedAgain");
+    }
+
+    public void testDeniesOnceButAllowsAskingAgain() throws Exception {
+        runDeviceTests(CLIENT_PKG, ".ScopedDirectoryAccessClientTest",
+                "testDeniesOnceButAllowsAskingAgain");
+    }
+
+    public void testDeniesOnceForAll() throws Exception {
+        runDeviceTests(CLIENT_PKG, ".ScopedDirectoryAccessClientTest", "testDeniesOnceForAll");
+    }
+}
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/SplitTests.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/SplitTests.java
new file mode 100644
index 0000000..a2ef1f3
--- /dev/null
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/SplitTests.java
@@ -0,0 +1,429 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.appsecurity.cts;
+
+import com.android.compatibility.common.util.AbiUtils;
+import com.android.cts.migration.MigrationHelper;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceTestCase;
+import com.android.tradefed.testtype.IAbi;
+import com.android.tradefed.testtype.IAbiReceiver;
+import com.android.tradefed.testtype.IBuildReceiver;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * Tests that verify installing of various split APKs from host side.
+ */
+public class SplitTests extends DeviceTestCase implements IAbiReceiver, IBuildReceiver {
+    static final String PKG = "com.android.cts.splitapp";
+    static final String CLASS = ".SplitAppTest";
+
+    static final String APK = "CtsSplitApp.apk";
+
+    static final String APK_mdpi = "CtsSplitApp_mdpi-v4.apk";
+    static final String APK_hdpi = "CtsSplitApp_hdpi-v4.apk";
+    static final String APK_xhdpi = "CtsSplitApp_xhdpi-v4.apk";
+    static final String APK_xxhdpi = "CtsSplitApp_xxhdpi-v4.apk";
+
+    private static final String APK_v7 = "CtsSplitApp_v7.apk";
+    private static final String APK_fr = "CtsSplitApp_fr.apk";
+    private static final String APK_de = "CtsSplitApp_de.apk";
+
+    private static final String APK_x86 = "CtsSplitApp_x86.apk";
+    private static final String APK_x86_64 = "CtsSplitApp_x86_64.apk";
+    private static final String APK_armeabi_v7a = "CtsSplitApp_armeabi-v7a.apk";
+    private static final String APK_armeabi = "CtsSplitApp_armeabi.apk";
+    private static final String APK_arm64_v8a = "CtsSplitApp_arm64-v8a.apk";
+    private static final String APK_mips64 = "CtsSplitApp_mips64.apk";
+    private static final String APK_mips = "CtsSplitApp_mips.apk";
+
+    private static final String APK_DIFF_REVISION = "CtsSplitAppDiffRevision.apk";
+    private static final String APK_DIFF_REVISION_v7 = "CtsSplitAppDiffRevision_v7.apk";
+
+    private static final String APK_DIFF_VERSION = "CtsSplitAppDiffVersion.apk";
+    private static final String APK_DIFF_VERSION_v7 = "CtsSplitAppDiffVersion_v7.apk";
+
+    private static final String APK_DIFF_CERT = "CtsSplitAppDiffCert.apk";
+    private static final String APK_DIFF_CERT_v7 = "CtsSplitAppDiffCert_v7.apk";
+
+    private static final String APK_FEATURE = "CtsSplitAppFeature.apk";
+    private static final String APK_FEATURE_v7 = "CtsSplitAppFeature_v7.apk";
+
+    static final HashMap<String, String> ABI_TO_APK = new HashMap<>();
+
+    static {
+        ABI_TO_APK.put("x86", APK_x86);
+        ABI_TO_APK.put("x86_64", APK_x86_64);
+        ABI_TO_APK.put("armeabi-v7a", APK_armeabi_v7a);
+        ABI_TO_APK.put("armeabi", APK_armeabi);
+        ABI_TO_APK.put("arm64-v8a", APK_arm64_v8a);
+        ABI_TO_APK.put("mips64", APK_mips64);
+        ABI_TO_APK.put("mips", APK_mips);
+    }
+
+    private IAbi mAbi;
+    private IBuildInfo mCtsBuild;
+
+    @Override
+    public void setAbi(IAbi abi) {
+        mAbi = abi;
+    }
+
+    @Override
+    public void setBuild(IBuildInfo buildInfo) {
+        mCtsBuild = buildInfo;
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        assertNotNull(mAbi);
+        assertNotNull(mCtsBuild);
+
+        getDevice().uninstallPackage(PKG);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+
+        getDevice().uninstallPackage(PKG);
+    }
+
+    public void testSingleBase() throws Exception {
+        new InstallMultiple().addApk(APK).run();
+        runDeviceTests(PKG, CLASS, "testSingleBase");
+    }
+
+    public void testDensitySingle() throws Exception {
+        new InstallMultiple().addApk(APK).addApk(APK_mdpi).run();
+        runDeviceTests(PKG, CLASS, "testDensitySingle");
+    }
+
+    public void testDensityAll() throws Exception {
+        new InstallMultiple().addApk(APK).addApk(APK_mdpi).addApk(APK_hdpi).addApk(APK_xhdpi)
+                .addApk(APK_xxhdpi).run();
+        runDeviceTests(PKG, CLASS, "testDensityAll");
+    }
+
+    /**
+     * Install first with low-resolution resources, then add a split that offers
+     * higher-resolution resources.
+     */
+    public void testDensityBest() throws Exception {
+        new InstallMultiple().addApk(APK).addApk(APK_mdpi).run();
+        runDeviceTests(PKG, CLASS, "testDensityBest1");
+
+        // Now splice in an additional split which offers better resources
+        new InstallMultiple().inheritFrom(PKG).addApk(APK_xxhdpi).run();
+        runDeviceTests(PKG, CLASS, "testDensityBest2");
+    }
+
+    /**
+     * Verify that an API-based split can change enabled/disabled state of
+     * manifest elements.
+     */
+    public void testApi() throws Exception {
+        new InstallMultiple().addApk(APK).addApk(APK_v7).run();
+        runDeviceTests(PKG, CLASS, "testApi");
+    }
+
+    public void testLocale() throws Exception {
+        new InstallMultiple().addApk(APK).addApk(APK_de).addApk(APK_fr).run();
+        runDeviceTests(PKG, CLASS, "testLocale");
+    }
+
+    /**
+     * Install test app with <em>single</em> split that exactly matches the
+     * currently active ABI. This also explicitly forces ABI when installing.
+     */
+    public void testNativeSingle() throws Exception {
+        final String abi = mAbi.getName();
+        final String apk = ABI_TO_APK.get(abi);
+        assertNotNull("Failed to find APK for ABI " + abi, apk);
+
+        new InstallMultiple().addApk(APK).addApk(apk).run();
+        runDeviceTests(PKG, CLASS, "testNative");
+    }
+
+    /**
+     * Install test app with <em>single</em> split that exactly matches the
+     * currently active ABI. This variant <em>does not</em> force the ABI when
+     * installing, instead exercising the system's ability to choose the ABI
+     * through inspection of the installed app.
+     */
+    public void testNativeSingleNatural() throws Exception {
+        final String abi = mAbi.getName();
+        final String apk = ABI_TO_APK.get(abi);
+        assertNotNull("Failed to find APK for ABI " + abi, apk);
+
+        new InstallMultiple().useNaturalAbi().addApk(APK).addApk(apk).run();
+        runDeviceTests(PKG, CLASS, "testNative");
+    }
+
+    /**
+     * Install test app with <em>all</em> possible ABI splits. This also
+     * explicitly forces ABI when installing.
+     */
+    public void testNativeAll() throws Exception {
+        final InstallMultiple inst = new InstallMultiple().addApk(APK);
+        for (String apk : ABI_TO_APK.values()) {
+            inst.addApk(apk);
+        }
+        inst.run();
+        runDeviceTests(PKG, CLASS, "testNative");
+    }
+
+    /**
+     * Install test app with <em>all</em> possible ABI splits. This variant
+     * <em>does not</em> force the ABI when installing, instead exercising the
+     * system's ability to choose the ABI through inspection of the installed
+     * app.
+     */
+    public void testNativeAllNatural() throws Exception {
+        final InstallMultiple inst = new InstallMultiple().useNaturalAbi().addApk(APK);
+        for (String apk : ABI_TO_APK.values()) {
+            inst.addApk(apk);
+        }
+        inst.run();
+        runDeviceTests(PKG, CLASS, "testNative");
+    }
+
+    public void testDuplicateBase() throws Exception {
+        new InstallMultiple().addApk(APK).addApk(APK).runExpectingFailure();
+    }
+
+    public void testDuplicateSplit() throws Exception {
+        new InstallMultiple().addApk(APK).addApk(APK_v7).addApk(APK_v7).runExpectingFailure();
+    }
+
+    public void testDiffCert() throws Exception {
+        new InstallMultiple().addApk(APK).addApk(APK_DIFF_CERT_v7).runExpectingFailure();
+    }
+
+    public void testDiffCertInherit() throws Exception {
+        new InstallMultiple().addApk(APK).run();
+        new InstallMultiple().inheritFrom(PKG).addApk(APK_DIFF_CERT_v7).runExpectingFailure();
+    }
+
+    public void testDiffVersion() throws Exception {
+        new InstallMultiple().addApk(APK).addApk(APK_DIFF_VERSION_v7).runExpectingFailure();
+    }
+
+    public void testDiffVersionInherit() throws Exception {
+        new InstallMultiple().addApk(APK).run();
+        new InstallMultiple().inheritFrom(PKG).addApk(APK_DIFF_VERSION_v7).runExpectingFailure();
+    }
+
+    public void testDiffRevision() throws Exception {
+        new InstallMultiple().addApk(APK).addApk(APK_DIFF_REVISION_v7).run();
+        runDeviceTests(PKG, CLASS, "testRevision0_12");
+    }
+
+    public void testDiffRevisionInheritBase() throws Exception {
+        new InstallMultiple().addApk(APK).addApk(APK_v7).run();
+        runDeviceTests(PKG, CLASS, "testRevision0_0");
+        new InstallMultiple().inheritFrom(PKG).addApk(APK_DIFF_REVISION_v7).run();
+        runDeviceTests(PKG, CLASS, "testRevision0_12");
+    }
+
+    public void testDiffRevisionInheritSplit() throws Exception {
+        new InstallMultiple().addApk(APK).addApk(APK_v7).run();
+        runDeviceTests(PKG, CLASS, "testRevision0_0");
+        new InstallMultiple().inheritFrom(PKG).addApk(APK_DIFF_REVISION).run();
+        runDeviceTests(PKG, CLASS, "testRevision12_0");
+    }
+
+    public void testDiffRevisionDowngrade() throws Exception {
+        new InstallMultiple().addApk(APK).addApk(APK_DIFF_REVISION_v7).run();
+        new InstallMultiple().inheritFrom(PKG).addApk(APK_v7).runExpectingFailure();
+    }
+
+    public void testFeatureBase() throws Exception {
+        new InstallMultiple().addApk(APK).addApk(APK_FEATURE).run();
+        runDeviceTests(PKG, CLASS, "testFeatureBase");
+    }
+
+    public void testFeatureApi() throws Exception {
+        new InstallMultiple().addApk(APK).addApk(APK_FEATURE).addApk(APK_FEATURE_v7).run();
+        runDeviceTests(PKG, CLASS, "testFeatureApi");
+    }
+
+    public void testInheritUpdatedBase() throws Exception {
+        // TODO: flesh out this test
+    }
+
+    public void testInheritUpdatedSplit() throws Exception {
+        // TODO: flesh out this test
+    }
+
+    /**
+     * Verify that installing a new version of app wipes code cache.
+     */
+    public void testClearCodeCache() throws Exception {
+        new InstallMultiple().addApk(APK).run();
+        runDeviceTests(PKG, CLASS, "testCodeCacheWrite");
+        new InstallMultiple().addArg("-r").addApk(APK_DIFF_VERSION).run();
+        runDeviceTests(PKG, CLASS, "testCodeCacheRead");
+    }
+
+    private class InstallMultiple extends BaseInstallMultiple<InstallMultiple> {
+        public InstallMultiple() {
+            super(getDevice(), mCtsBuild, mAbi);
+        }
+    }
+
+    public static class BaseInstallMultiple<T extends BaseInstallMultiple<?>> {
+        private final ITestDevice mDevice;
+        private final IBuildInfo mBuild;
+        private final IAbi mAbi;
+
+        private final List<String> mArgs = new ArrayList<>();
+        private final List<File> mApks = new ArrayList<>();
+        private boolean mUseNaturalAbi;
+
+        public BaseInstallMultiple(ITestDevice device, IBuildInfo buildInfo, IAbi abi) {
+            mDevice = device;
+            mBuild = buildInfo;
+            mAbi = abi;
+            addArg("-g");
+        }
+
+        T addArg(String arg) {
+            mArgs.add(arg);
+            return (T) this;
+        }
+
+        T addApk(String apk) throws FileNotFoundException {
+            mApks.add(MigrationHelper.getTestFile(mBuild, apk));
+            return (T) this;
+        }
+
+        T inheritFrom(String packageName) {
+            addArg("-r");
+            addArg("-p " + packageName);
+            return (T) this;
+        }
+
+        T useNaturalAbi() {
+            mUseNaturalAbi = true;
+            return (T) this;
+        }
+
+        T locationAuto() {
+            addArg("--install-location 0");
+            return (T) this;
+        }
+
+        T locationInternalOnly() {
+            addArg("--install-location 1");
+            return (T) this;
+        }
+
+        T locationPreferExternal() {
+            addArg("--install-location 2");
+            return (T) this;
+        }
+
+        T forceUuid(String uuid) {
+            addArg("--force-uuid " + uuid);
+            return (T) this;
+        }
+
+        void run() throws DeviceNotAvailableException {
+            run(true);
+        }
+
+        void runExpectingFailure() throws DeviceNotAvailableException {
+            run(false);
+        }
+
+        private void run(boolean expectingSuccess) throws DeviceNotAvailableException {
+            final ITestDevice device = mDevice;
+
+            // Create an install session
+            final StringBuilder cmd = new StringBuilder();
+            cmd.append("pm install-create");
+            for (String arg : mArgs) {
+                cmd.append(' ').append(arg);
+            }
+            if (!mUseNaturalAbi) {
+                cmd.append(' ').append(AbiUtils.createAbiFlag(mAbi.getName()));
+            }
+
+            String result = device.executeShellCommand(cmd.toString());
+            assertTrue(result, result.startsWith("Success"));
+
+            final int start = result.lastIndexOf("[");
+            final int end = result.lastIndexOf("]");
+            int sessionId = -1;
+            try {
+                if (start != -1 && end != -1 && start < end) {
+                    sessionId = Integer.parseInt(result.substring(start + 1, end));
+                }
+            } catch (NumberFormatException e) {
+            }
+            if (sessionId == -1) {
+                throw new IllegalStateException("Failed to create install session: " + result);
+            }
+
+            // Push our files into session. Ideally we'd use stdin streaming,
+            // but ddmlib doesn't support it yet.
+            for (int i = 0; i < mApks.size(); i++) {
+                final File apk = mApks.get(i);
+                final String remotePath = "/data/local/tmp/" + i + "_" + apk.getName();
+                if (!device.pushFile(apk, remotePath)) {
+                    throw new IllegalStateException("Failed to push " + apk);
+                }
+
+                cmd.setLength(0);
+                cmd.append("pm install-write");
+                cmd.append(' ').append(sessionId);
+                cmd.append(' ').append(i + "_" + apk.getName());
+                cmd.append(' ').append(remotePath);
+
+                result = device.executeShellCommand(cmd.toString());
+                assertTrue(result, result.startsWith("Success"));
+            }
+
+            // Everything staged; let's pull trigger
+            cmd.setLength(0);
+            cmd.append("pm install-commit");
+            cmd.append(' ').append(sessionId);
+
+            result = device.executeShellCommand(cmd.toString());
+            if (expectingSuccess) {
+                assertTrue(result, result.startsWith("Success"));
+            } else {
+                assertFalse(result, result.startsWith("Success"));
+            }
+        }
+    }
+
+    public void runDeviceTests(String packageName, String testClassName, String testMethodName)
+            throws DeviceNotAvailableException {
+        Utils.runDeviceTests(getDevice(), packageName, testClassName, testMethodName);
+    }
+}
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/Utils.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/Utils.java
new file mode 100644
index 0000000..7048074
--- /dev/null
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/Utils.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.appsecurity.cts;
+
+import com.android.ddmlib.Log;
+import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
+import com.android.ddmlib.testrunner.TestIdentifier;
+import com.android.ddmlib.testrunner.TestResult;
+import com.android.ddmlib.testrunner.TestResult.TestStatus;
+import com.android.ddmlib.testrunner.TestRunResult;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.result.CollectingTestListener;
+
+import java.util.Map;
+
+public class Utils {
+    private static final String TAG = "AppSecurity";
+
+    public static final int USER_OWNER = 0;
+
+    public static void runDeviceTests(ITestDevice device, String packageName)
+            throws DeviceNotAvailableException {
+        runDeviceTests(device, packageName, null, null, USER_OWNER);
+    }
+
+    public static void runDeviceTests(ITestDevice device, String packageName, int userId)
+            throws DeviceNotAvailableException {
+        runDeviceTests(device, packageName, null, null, userId);
+    }
+
+    public static void runDeviceTests(ITestDevice device, String packageName, String testClassName)
+            throws DeviceNotAvailableException {
+        runDeviceTests(device, packageName, testClassName, null, USER_OWNER);
+    }
+
+    public static void runDeviceTests(ITestDevice device, String packageName, String testClassName,
+            int userId) throws DeviceNotAvailableException {
+        runDeviceTests(device, packageName, testClassName, null, userId);
+    }
+
+    public static void runDeviceTests(ITestDevice device, String packageName, String testClassName,
+            String testMethodName) throws DeviceNotAvailableException {
+        runDeviceTests(device, packageName, testClassName, testMethodName, USER_OWNER);
+    }
+
+    public static void runDeviceTests(ITestDevice device, String packageName, String testClassName,
+            String testMethodName, int userId) throws DeviceNotAvailableException {
+        if (testClassName != null && testClassName.startsWith(".")) {
+            testClassName = packageName + testClassName;
+        }
+
+        RemoteAndroidTestRunner testRunner = new RemoteAndroidTestRunner(packageName,
+                "android.support.test.runner.AndroidJUnitRunner", device.getIDevice());
+        if (testClassName != null && testMethodName != null) {
+            testRunner.setMethodName(testClassName, testMethodName);
+        } else if (testClassName != null) {
+            testRunner.setClassName(testClassName);
+        }
+
+        if (userId != USER_OWNER) {
+            // TODO: move this to RemoteAndroidTestRunner once it supports users
+            testRunner.addInstrumentationArg("hack_key", "hack_value --user " + userId);
+        }
+
+        final CollectingTestListener listener = new CollectingTestListener();
+        device.runInstrumentationTests(testRunner, listener);
+
+        final TestRunResult result = listener.getCurrentRunResults();
+        if (result.isRunFailure()) {
+            throw new AssertionError("Failed to successfully run device tests for "
+                    + result.getName() + ": " + result.getRunFailureMessage());
+        }
+
+        if (result.hasFailedTests()) {
+            // build a meaningful error message
+            StringBuilder errorBuilder = new StringBuilder("on-device tests failed:\n");
+            for (Map.Entry<TestIdentifier, TestResult> resultEntry :
+                result.getTestResults().entrySet()) {
+                if (!resultEntry.getValue().getStatus().equals(TestStatus.PASSED)) {
+                    errorBuilder.append(resultEntry.getKey().toString());
+                    errorBuilder.append(":\n");
+                    errorBuilder.append(resultEntry.getValue().getStackTrace());
+                }
+            }
+            throw new AssertionError(errorBuilder.toString());
+        }
+    }
+
+    private static boolean isMultiUserSupportedOnDevice(ITestDevice device)
+            throws DeviceNotAvailableException {
+        // TODO: move this to ITestDevice once it supports users
+        final String output = device.executeShellCommand("pm get-max-users");
+        try {
+            return Integer.parseInt(output.substring(output.lastIndexOf(" ")).trim()) > 1;
+        } catch (NumberFormatException e) {
+            throw new AssertionError("Failed to parse result: " + output);
+        }
+    }
+
+    /**
+     * Return set of users that test should be run for, creating a secondary
+     * user if the device supports it. Always call
+     * {@link #removeUsersForTest(ITestDevice, int[])} when finished.
+     */
+    public static int[] createUsersForTest(ITestDevice device) throws DeviceNotAvailableException {
+        if (isMultiUserSupportedOnDevice(device)) {
+            return new int[] { USER_OWNER, createUserOnDevice(device) };
+        } else {
+            Log.d(TAG, "Single user device; skipping isolated storage tests");
+            return new int[] { USER_OWNER };
+        }
+    }
+
+    public static void removeUsersForTest(ITestDevice device, int[] users)
+            throws DeviceNotAvailableException {
+        for (int user : users) {
+            if (user != USER_OWNER) {
+                removeUserOnDevice(device, user);
+            }
+        }
+    }
+
+    private static int createUserOnDevice(ITestDevice device) throws DeviceNotAvailableException {
+        // TODO: move this to ITestDevice once it supports users
+        final String name = "CTS_" + System.currentTimeMillis();
+        final String output = device.executeShellCommand("pm create-user " + name);
+        if (output.startsWith("Success")) {
+            try {
+                final int userId = Integer.parseInt(
+                        output.substring(output.lastIndexOf(" ")).trim());
+                device.executeShellCommand("am start-user " + userId);
+                return userId;
+            } catch (NumberFormatException e) {
+                throw new AssertionError("Failed to parse result: " + output);
+            }
+        } else {
+            throw new AssertionError("Failed to create user: " + output);
+        }
+    }
+
+    private static void removeUserOnDevice(ITestDevice device, int userId)
+            throws DeviceNotAvailableException {
+        // TODO: move this to ITestDevice once it supports users
+        final String output = device.executeShellCommand("pm remove-user " + userId);
+        if (output.startsWith("Error")) {
+            throw new AssertionError("Failed to remove user: " + output);
+        }
+    }
+
+}
diff --git a/hostsidetests/appsecurity/src/com/android/cts/appsecurity/AdoptableHostTest.java b/hostsidetests/appsecurity/src/com/android/cts/appsecurity/AdoptableHostTest.java
deleted file mode 100644
index 2ae2e10..0000000
--- a/hostsidetests/appsecurity/src/com/android/cts/appsecurity/AdoptableHostTest.java
+++ /dev/null
@@ -1,350 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.appsecurity;
-
-import static com.android.cts.appsecurity.SplitTests.ABI_TO_APK;
-import static com.android.cts.appsecurity.SplitTests.APK;
-import static com.android.cts.appsecurity.SplitTests.APK_mdpi;
-import static com.android.cts.appsecurity.SplitTests.APK_xxhdpi;
-import static com.android.cts.appsecurity.SplitTests.CLASS;
-import static com.android.cts.appsecurity.SplitTests.PKG;
-
-import com.android.cts.appsecurity.SplitTests.BaseInstallMultiple;
-import com.android.cts.tradefed.build.CtsBuildHelper;
-import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.testtype.DeviceTestCase;
-import com.android.tradefed.testtype.IAbi;
-import com.android.tradefed.testtype.IAbiReceiver;
-import com.android.tradefed.testtype.IBuildReceiver;
-
-import java.util.Arrays;
-
-/**
- * Set of tests that verify behavior of adopted storage media, if supported.
- */
-public class AdoptableHostTest extends DeviceTestCase implements IAbiReceiver, IBuildReceiver {
-    private IAbi mAbi;
-    private CtsBuildHelper mCtsBuild;
-
-    @Override
-    public void setAbi(IAbi abi) {
-        mAbi = abi;
-    }
-
-    @Override
-    public void setBuild(IBuildInfo buildInfo) {
-        mCtsBuild = CtsBuildHelper.createBuildHelper(buildInfo);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-
-        assertNotNull(mAbi);
-        assertNotNull(mCtsBuild);
-
-        getDevice().uninstallPackage(PKG);
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-
-        getDevice().uninstallPackage(PKG);
-    }
-
-    public void testApps() throws Exception {
-        if (!hasAdoptable()) return;
-        final String diskId = getAdoptionDisk();
-        try {
-            final String abi = mAbi.getName();
-            final String apk = ABI_TO_APK.get(abi);
-            assertNotNull("Failed to find APK for ABI " + abi, apk);
-
-            // Install simple app on internal
-            new InstallMultiple().useNaturalAbi().addApk(APK).addApk(apk).run();
-            runDeviceTests(PKG, CLASS, "testDataInternal");
-            runDeviceTests(PKG, CLASS, "testDataWrite");
-            runDeviceTests(PKG, CLASS, "testDataRead");
-            runDeviceTests(PKG, CLASS, "testNative");
-
-            // Adopt that disk!
-            assertEmpty(getDevice().executeShellCommand("sm partition " + diskId + " private"));
-            final LocalVolumeInfo vol = getAdoptionVolume();
-
-            // Move app and verify
-            assertSuccess(getDevice().executeShellCommand("pm move-package " + PKG + " " + vol.uuid));
-            runDeviceTests(PKG, CLASS, "testDataNotInternal");
-            runDeviceTests(PKG, CLASS, "testDataRead");
-            runDeviceTests(PKG, CLASS, "testNative");
-
-            // Unmount, remount and verify
-            getDevice().executeShellCommand("sm unmount " + vol.volId);
-            getDevice().executeShellCommand("sm mount " + vol.volId);
-            runDeviceTests(PKG, CLASS, "testDataNotInternal");
-            runDeviceTests(PKG, CLASS, "testDataRead");
-            runDeviceTests(PKG, CLASS, "testNative");
-
-            // Move app back and verify
-            assertSuccess(getDevice().executeShellCommand("pm move-package " + PKG + " internal"));
-            runDeviceTests(PKG, CLASS, "testDataInternal");
-            runDeviceTests(PKG, CLASS, "testDataRead");
-            runDeviceTests(PKG, CLASS, "testNative");
-
-            // Un-adopt volume and app should still be fine
-            getDevice().executeShellCommand("sm partition " + diskId + " public");
-            runDeviceTests(PKG, CLASS, "testDataInternal");
-            runDeviceTests(PKG, CLASS, "testDataRead");
-            runDeviceTests(PKG, CLASS, "testNative");
-
-        } finally {
-            cleanUp(diskId);
-        }
-    }
-
-    public void testPrimaryStorage() throws Exception {
-        if (!hasAdoptable()) return;
-        final String diskId = getAdoptionDisk();
-        try {
-            final String originalVol = getDevice()
-                    .executeShellCommand("sm get-primary-storage-uuid").trim();
-
-            if ("null".equals(originalVol)) {
-                verifyPrimaryInternal(diskId);
-            } else if ("primary_physical".equals(originalVol)) {
-                verifyPrimaryPhysical(diskId);
-            }
-        } finally {
-            cleanUp(diskId);
-        }
-    }
-
-    private void verifyPrimaryInternal(String diskId) throws Exception {
-        // Write some data to shared storage
-        new InstallMultiple().addApk(APK).run();
-        runDeviceTests(PKG, CLASS, "testPrimaryOnSameVolume");
-        runDeviceTests(PKG, CLASS, "testPrimaryInternal");
-        runDeviceTests(PKG, CLASS, "testPrimaryDataWrite");
-        runDeviceTests(PKG, CLASS, "testPrimaryDataRead");
-
-        // Adopt that disk!
-        assertEmpty(getDevice().executeShellCommand("sm partition " + diskId + " private"));
-        final LocalVolumeInfo vol = getAdoptionVolume();
-
-        // Move storage there and verify that data went along for ride
-        assertSuccess(getDevice().executeShellCommand("pm move-primary-storage " + vol.uuid));
-        runDeviceTests(PKG, CLASS, "testPrimaryAdopted");
-        runDeviceTests(PKG, CLASS, "testPrimaryDataRead");
-
-        // Unmount and verify
-        getDevice().executeShellCommand("sm unmount " + vol.volId);
-        runDeviceTests(PKG, CLASS, "testPrimaryUnmounted");
-        getDevice().executeShellCommand("sm mount " + vol.volId);
-        runDeviceTests(PKG, CLASS, "testPrimaryAdopted");
-        runDeviceTests(PKG, CLASS, "testPrimaryDataRead");
-
-        // Move app and verify backing storage volume is same
-        assertSuccess(getDevice().executeShellCommand("pm move-package " + PKG + " " + vol.uuid));
-        runDeviceTests(PKG, CLASS, "testPrimaryOnSameVolume");
-        runDeviceTests(PKG, CLASS, "testPrimaryDataRead");
-
-        // And move back to internal
-        assertSuccess(getDevice().executeShellCommand("pm move-primary-storage internal"));
-        runDeviceTests(PKG, CLASS, "testPrimaryInternal");
-        runDeviceTests(PKG, CLASS, "testPrimaryDataRead");
-
-        assertSuccess(getDevice().executeShellCommand("pm move-package " + PKG + " internal"));
-        runDeviceTests(PKG, CLASS, "testPrimaryOnSameVolume");
-        runDeviceTests(PKG, CLASS, "testPrimaryDataRead");
-    }
-
-    private void verifyPrimaryPhysical(String diskId) throws Exception {
-        // Write some data to shared storage
-        new InstallMultiple().addApk(APK).run();
-        runDeviceTests(PKG, CLASS, "testPrimaryPhysical");
-        runDeviceTests(PKG, CLASS, "testPrimaryDataWrite");
-        runDeviceTests(PKG, CLASS, "testPrimaryDataRead");
-
-        // Adopt that disk!
-        assertEmpty(getDevice().executeShellCommand("sm partition " + diskId + " private"));
-        final LocalVolumeInfo vol = getAdoptionVolume();
-
-        // Move primary storage there, but since we just nuked primary physical
-        // the storage device will be empty
-        assertSuccess(getDevice().executeShellCommand("pm move-primary-storage " + vol.uuid));
-        runDeviceTests(PKG, CLASS, "testPrimaryAdopted");
-        runDeviceTests(PKG, CLASS, "testPrimaryDataWrite");
-        runDeviceTests(PKG, CLASS, "testPrimaryDataRead");
-
-        // Unmount and verify
-        getDevice().executeShellCommand("sm unmount " + vol.volId);
-        runDeviceTests(PKG, CLASS, "testPrimaryUnmounted");
-        getDevice().executeShellCommand("sm mount " + vol.volId);
-        runDeviceTests(PKG, CLASS, "testPrimaryAdopted");
-        runDeviceTests(PKG, CLASS, "testPrimaryDataRead");
-
-        // And move to internal
-        assertSuccess(getDevice().executeShellCommand("pm move-primary-storage internal"));
-        runDeviceTests(PKG, CLASS, "testPrimaryOnSameVolume");
-        runDeviceTests(PKG, CLASS, "testPrimaryInternal");
-        runDeviceTests(PKG, CLASS, "testPrimaryDataRead");
-    }
-
-    /**
-     * Verify that we can install both new and inherited packages directly on
-     * adopted volumes.
-     */
-    public void testPackageInstaller() throws Exception {
-        if (!hasAdoptable()) return;
-        final String diskId = getAdoptionDisk();
-        try {
-            assertEmpty(getDevice().executeShellCommand("sm partition " + diskId + " private"));
-            final LocalVolumeInfo vol = getAdoptionVolume();
-
-            // Install directly onto adopted volume
-            new InstallMultiple().locationAuto().forceUuid(vol.uuid)
-                    .addApk(APK).addApk(APK_mdpi).run();
-            runDeviceTests(PKG, CLASS, "testDataNotInternal");
-            runDeviceTests(PKG, CLASS, "testDensityBest1");
-
-            // Now splice in an additional split which offers better resources
-            new InstallMultiple().locationAuto().inheritFrom(PKG)
-                    .addApk(APK_xxhdpi).run();
-            runDeviceTests(PKG, CLASS, "testDataNotInternal");
-            runDeviceTests(PKG, CLASS, "testDensityBest2");
-
-        } finally {
-            cleanUp(diskId);
-        }
-    }
-
-    /**
-     * Verify behavior when changes occur while adopted device is ejected and
-     * returned at a later time.
-     */
-    public void testEjected() throws Exception {
-        if (!hasAdoptable()) return;
-        final String diskId = getAdoptionDisk();
-        try {
-            assertEmpty(getDevice().executeShellCommand("sm partition " + diskId + " private"));
-            final LocalVolumeInfo vol = getAdoptionVolume();
-
-            // Install directly onto adopted volume, and write data there
-            new InstallMultiple().locationAuto().forceUuid(vol.uuid).addApk(APK).run();
-            runDeviceTests(PKG, CLASS, "testDataNotInternal");
-            runDeviceTests(PKG, CLASS, "testDataWrite");
-            runDeviceTests(PKG, CLASS, "testDataRead");
-
-            // Now unmount and uninstall; leaving stale package on adopted volume
-            getDevice().executeShellCommand("sm unmount " + vol.volId);
-            getDevice().uninstallPackage(PKG);
-
-            // Install second copy on internal, but don't write anything
-            new InstallMultiple().locationInternalOnly().addApk(APK).run();
-            runDeviceTests(PKG, CLASS, "testDataInternal");
-
-            // Kick through a remount cycle, which should purge the adopted app
-            getDevice().executeShellCommand("sm mount " + vol.volId);
-            runDeviceTests(PKG, CLASS, "testDataInternal");
-            try {
-                runDeviceTests(PKG, CLASS, "testDataRead");
-                fail("Unexpected data from adopted volume picked up");
-            } catch (AssertionError expected) {
-            }
-            getDevice().executeShellCommand("sm unmount " + vol.volId);
-
-            // Uninstall the internal copy and remount; we should have no record of app
-            getDevice().uninstallPackage(PKG);
-            getDevice().executeShellCommand("sm mount " + vol.volId);
-
-            assertEmpty(getDevice().executeShellCommand("pm list packages " + PKG));
-        } finally {
-            cleanUp(diskId);
-        }
-    }
-
-    private boolean hasAdoptable() throws Exception {
-        return Boolean.parseBoolean(getDevice().executeShellCommand("sm has-adoptable").trim());
-    }
-
-    private String getAdoptionDisk() throws Exception {
-        final String disks = getDevice().executeShellCommand("sm list-disks adoptable");
-        if (disks == null || disks.length() == 0) {
-            throw new AssertionError("Devices that claim to support adoptable storage must have "
-                    + "adoptable media inserted during CTS to verify correct behavior");
-        }
-        return disks.split("\n")[0].trim();
-    }
-
-    private LocalVolumeInfo getAdoptionVolume() throws Exception {
-        String[] lines = null;
-        int attempt = 0;
-        while (attempt++ < 15) {
-            lines = getDevice().executeShellCommand("sm list-volumes private").split("\n");
-            for (String line : lines) {
-                final LocalVolumeInfo info = new LocalVolumeInfo(line.trim());
-                if (!"private".equals(info.volId) && "mounted".equals(info.state)) {
-                    return info;
-                }
-            }
-            Thread.sleep(1000);
-        }
-        throw new AssertionError("Expected private volume; found " + Arrays.toString(lines));
-    }
-
-    private void cleanUp(String diskId) throws Exception {
-        getDevice().executeShellCommand("sm partition " + diskId + " public");
-        getDevice().executeShellCommand("sm forget all");
-    }
-
-    private void runDeviceTests(String packageName, String testClassName, String testMethodName)
-            throws DeviceNotAvailableException {
-        Utils.runDeviceTests(getDevice(), packageName, testClassName, testMethodName);
-    }
-
-    private static void assertSuccess(String str) {
-        if (str == null || !str.startsWith("Success")) {
-            throw new AssertionError("Expected success string but found " + str);
-        }
-    }
-
-    private static void assertEmpty(String str) {
-        if (str != null && str.trim().length() > 0) {
-            throw new AssertionError("Expected empty string but found " + str);
-        }
-    }
-
-    private static class LocalVolumeInfo {
-        public String volId;
-        public String state;
-        public String uuid;
-
-        public LocalVolumeInfo(String line) {
-            final String[] split = line.split(" ");
-            volId = split[0];
-            state = split[1];
-            uuid = split[2];
-        }
-    }
-
-    private class InstallMultiple extends BaseInstallMultiple<InstallMultiple> {
-        public InstallMultiple() {
-            super(getDevice(), mCtsBuild, mAbi);
-        }
-    }
-}
diff --git a/hostsidetests/appsecurity/src/com/android/cts/appsecurity/AppSecurityTests.java b/hostsidetests/appsecurity/src/com/android/cts/appsecurity/AppSecurityTests.java
deleted file mode 100644
index bf9e81c..0000000
--- a/hostsidetests/appsecurity/src/com/android/cts/appsecurity/AppSecurityTests.java
+++ /dev/null
@@ -1,298 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.appsecurity;
-
-import com.android.cts.tradefed.build.CtsBuildHelper;
-import com.android.cts.util.AbiUtils;
-import com.android.ddmlib.Log;
-import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.testtype.DeviceTestCase;
-import com.android.tradefed.testtype.IAbi;
-import com.android.tradefed.testtype.IAbiReceiver;
-import com.android.tradefed.testtype.IBuildReceiver;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-
-/**
- * Set of tests that verify various security checks involving multiple apps are
- * properly enforced.
- */
-public class AppSecurityTests extends DeviceTestCase implements IAbiReceiver, IBuildReceiver {
-
-    // testSharedUidDifferentCerts constants
-    private static final String SHARED_UI_APK = "CtsSharedUidInstall.apk";
-    private static final String SHARED_UI_PKG = "com.android.cts.shareuidinstall";
-    private static final String SHARED_UI_DIFF_CERT_APK = "CtsSharedUidInstallDiffCert.apk";
-    private static final String SHARED_UI_DIFF_CERT_PKG =
-        "com.android.cts.shareuidinstalldiffcert";
-
-    // testAppUpgradeDifferentCerts constants
-    private static final String SIMPLE_APP_APK = "CtsSimpleAppInstall.apk";
-    private static final String SIMPLE_APP_PKG = "com.android.cts.simpleappinstall";
-    private static final String SIMPLE_APP_DIFF_CERT_APK = "CtsSimpleAppInstallDiffCert.apk";
-
-    // testAppFailAccessPrivateData constants
-    private static final String APP_WITH_DATA_APK = "CtsAppWithData.apk";
-    private static final String APP_WITH_DATA_PKG = "com.android.cts.appwithdata";
-    private static final String APP_WITH_DATA_CLASS =
-            "com.android.cts.appwithdata.CreatePrivateDataTest";
-    private static final String APP_WITH_DATA_CREATE_METHOD =
-            "testCreatePrivateData";
-    private static final String APP_WITH_DATA_CHECK_NOEXIST_METHOD =
-            "testEnsurePrivateDataNotExist";
-    private static final String APP_ACCESS_DATA_APK = "CtsAppAccessData.apk";
-    private static final String APP_ACCESS_DATA_PKG = "com.android.cts.appaccessdata";
-
-    // testInstrumentationDiffCert constants
-    private static final String TARGET_INSTRUMENT_APK = "CtsTargetInstrumentationApp.apk";
-    private static final String TARGET_INSTRUMENT_PKG = "com.android.cts.targetinstrumentationapp";
-    private static final String INSTRUMENT_DIFF_CERT_APK = "CtsInstrumentationAppDiffCert.apk";
-    private static final String INSTRUMENT_DIFF_CERT_PKG =
-        "com.android.cts.instrumentationdiffcertapp";
-
-    // testPermissionDiffCert constants
-    private static final String DECLARE_PERMISSION_APK = "CtsPermissionDeclareApp.apk";
-    private static final String DECLARE_PERMISSION_PKG = "com.android.cts.permissiondeclareapp";
-    private static final String DECLARE_PERMISSION_COMPAT_APK = "CtsPermissionDeclareAppCompat.apk";
-    private static final String DECLARE_PERMISSION_COMPAT_PKG = "com.android.cts.permissiondeclareappcompat";
-
-    private static final String PERMISSION_DIFF_CERT_APK = "CtsUsePermissionDiffCert.apk";
-    private static final String PERMISSION_DIFF_CERT_PKG =
-        "com.android.cts.usespermissiondiffcertapp";
-
-    private static final String LOG_TAG = "AppSecurityTests";
-
-    private IAbi mAbi;
-    private CtsBuildHelper mCtsBuild;
-
-    @Override
-    public void setAbi(IAbi abi) {
-        mAbi = abi;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void setBuild(IBuildInfo buildInfo) {
-        mCtsBuild = CtsBuildHelper.createBuildHelper(buildInfo);
-    }
-
-    private File getTestAppFile(String fileName) throws FileNotFoundException {
-        return mCtsBuild.getTestApp(fileName);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        // ensure build has been set before test is run
-        assertNotNull(mCtsBuild);
-    }
-
-    /**
-     * Test that an app that declares the same shared uid as an existing app, cannot be installed
-     * if it is signed with a different certificate.
-     */
-    public void testSharedUidDifferentCerts() throws Exception {
-        Log.i(LOG_TAG, "installing apks with shared uid, but different certs");
-        try {
-            // cleanup test apps that might be installed from previous partial test run
-            getDevice().uninstallPackage(SHARED_UI_PKG);
-            getDevice().uninstallPackage(SHARED_UI_DIFF_CERT_PKG);
-
-            String[] options = {AbiUtils.createAbiFlag(mAbi.getName())};
-            String installResult = getDevice().installPackage(getTestAppFile(SHARED_UI_APK),
-                    false, options);
-            assertNull(String.format("failed to install shared uid app, Reason: %s", installResult),
-                    installResult);
-            installResult = getDevice().installPackage(getTestAppFile(SHARED_UI_DIFF_CERT_APK),
-                    false, options);
-            assertNotNull("shared uid app with different cert than existing app installed " +
-                    "successfully", installResult);
-            assertEquals("INSTALL_FAILED_SHARED_USER_INCOMPATIBLE", installResult);
-        } finally {
-            getDevice().uninstallPackage(SHARED_UI_PKG);
-            getDevice().uninstallPackage(SHARED_UI_DIFF_CERT_PKG);
-        }
-    }
-
-    /**
-     * Test that an app update cannot be installed over an existing app if it has a different
-     * certificate.
-     */
-    public void testAppUpgradeDifferentCerts() throws Exception {
-        Log.i(LOG_TAG, "installing app upgrade with different certs");
-        try {
-            // cleanup test app that might be installed from previous partial test run
-            getDevice().uninstallPackage(SIMPLE_APP_PKG);
-
-            String[] options = {AbiUtils.createAbiFlag(mAbi.getName())};
-            String installResult = getDevice().installPackage(getTestAppFile(SIMPLE_APP_APK),
-                    false, options);
-            assertNull(String.format("failed to install simple app. Reason: %s", installResult),
-                    installResult);
-            installResult = getDevice().installPackage(getTestAppFile(SIMPLE_APP_DIFF_CERT_APK),
-                    true /* reinstall */, options);
-            assertNotNull("app upgrade with different cert than existing app installed " +
-                    "successfully", installResult);
-            assertEquals("INSTALL_FAILED_UPDATE_INCOMPATIBLE", installResult);
-        } finally {
-            getDevice().uninstallPackage(SIMPLE_APP_PKG);
-        }
-    }
-
-    /**
-     * Test that an app cannot access another app's private data.
-     */
-    public void testAppFailAccessPrivateData() throws Exception {
-        Log.i(LOG_TAG, "installing app that attempts to access another app's private data");
-        try {
-            // cleanup test app that might be installed from previous partial test run
-            getDevice().uninstallPackage(APP_WITH_DATA_PKG);
-            getDevice().uninstallPackage(APP_ACCESS_DATA_PKG);
-
-            String[] options = {AbiUtils.createAbiFlag(mAbi.getName())};
-            String installResult = getDevice().installPackage(getTestAppFile(APP_WITH_DATA_APK),
-                    false, options);
-            assertNull(String.format("failed to install app with data. Reason: %s", installResult),
-                    installResult);
-            // run appwithdata's tests to create private data
-            runDeviceTests(APP_WITH_DATA_PKG, APP_WITH_DATA_CLASS, APP_WITH_DATA_CREATE_METHOD);
-
-            installResult = getDevice().installPackage(getTestAppFile(APP_ACCESS_DATA_APK),
-                    false, options);
-            assertNull(String.format("failed to install app access data. Reason: %s",
-                    installResult), installResult);
-            // run appaccessdata's tests which attempt to access appwithdata's private data
-            runDeviceTests(APP_ACCESS_DATA_PKG);
-        } finally {
-            getDevice().uninstallPackage(APP_WITH_DATA_PKG);
-            getDevice().uninstallPackage(APP_ACCESS_DATA_PKG);
-        }
-    }
-
-    /**
-     * Test that uninstall of an app removes its private data.
-     */
-    public void testUninstallRemovesData() throws Exception {
-        Log.i(LOG_TAG, "Uninstalling app, verifying data is removed.");
-        try {
-            // cleanup test app that might be installed from previous partial test run
-            getDevice().uninstallPackage(APP_WITH_DATA_PKG);
-
-            String[] options = {AbiUtils.createAbiFlag(mAbi.getName())};
-            String installResult = getDevice().installPackage(getTestAppFile(APP_WITH_DATA_APK),
-                    false, options);
-            assertNull(String.format("failed to install app with data. Reason: %s", installResult),
-                    installResult);
-            // run appwithdata's tests to create private data
-            runDeviceTests(APP_WITH_DATA_PKG, APP_WITH_DATA_CLASS, APP_WITH_DATA_CREATE_METHOD);
-
-            getDevice().uninstallPackage(APP_WITH_DATA_PKG);
-
-            installResult = getDevice().installPackage(getTestAppFile(APP_WITH_DATA_APK),
-                    false, options);
-            assertNull(String.format("failed to install app with data second time. Reason: %s",
-                    installResult), installResult);
-            // run appwithdata's 'check if file exists' test
-            runDeviceTests(APP_WITH_DATA_PKG, APP_WITH_DATA_CLASS,
-                    APP_WITH_DATA_CHECK_NOEXIST_METHOD);
-        } finally {
-            getDevice().uninstallPackage(APP_WITH_DATA_PKG);
-        }
-    }
-
-    /**
-     * Test that an app cannot instrument another app that is signed with different certificate.
-     */
-    public void testInstrumentationDiffCert() throws Exception {
-        Log.i(LOG_TAG, "installing app that attempts to instrument another app");
-        try {
-            // cleanup test app that might be installed from previous partial test run
-            getDevice().uninstallPackage(TARGET_INSTRUMENT_PKG);
-            getDevice().uninstallPackage(INSTRUMENT_DIFF_CERT_PKG);
-
-            String[] options = {AbiUtils.createAbiFlag(mAbi.getName())};
-            String installResult = getDevice().installPackage(
-                    getTestAppFile(TARGET_INSTRUMENT_APK), false, options);
-            assertNull(String.format("failed to install target instrumentation app. Reason: %s",
-                    installResult), installResult);
-
-            // the app will install, but will get error at runtime when starting instrumentation
-            installResult = getDevice().installPackage(getTestAppFile(INSTRUMENT_DIFF_CERT_APK),
-                    false, options);
-            assertNull(String.format(
-                    "failed to install instrumentation app with diff cert. Reason: %s",
-                    installResult), installResult);
-            // run INSTRUMENT_DIFF_CERT_PKG tests
-            // this test will attempt to call startInstrumentation directly and verify
-            // SecurityException is thrown
-            runDeviceTests(INSTRUMENT_DIFF_CERT_PKG);
-        } finally {
-            getDevice().uninstallPackage(TARGET_INSTRUMENT_PKG);
-            getDevice().uninstallPackage(INSTRUMENT_DIFF_CERT_PKG);
-        }
-    }
-
-    /**
-     * Test that an app cannot use a signature-enforced permission if it is signed with a different
-     * certificate than the app that declared the permission.
-     */
-    public void testPermissionDiffCert() throws Exception {
-        Log.i(LOG_TAG, "installing app that attempts to use permission of another app");
-        try {
-            // cleanup test app that might be installed from previous partial test run
-            getDevice().uninstallPackage(DECLARE_PERMISSION_PKG);
-            getDevice().uninstallPackage(DECLARE_PERMISSION_COMPAT_PKG);
-            getDevice().uninstallPackage(PERMISSION_DIFF_CERT_PKG);
-
-            String[] options = {AbiUtils.createAbiFlag(mAbi.getName())};
-            String installResult = getDevice().installPackage(
-                    getTestAppFile(DECLARE_PERMISSION_APK), false, options);
-            assertNull(String.format("failed to install declare permission app. Reason: %s",
-                    installResult), installResult);
-
-            installResult = getDevice().installPackage(
-                    getTestAppFile(DECLARE_PERMISSION_COMPAT_APK), false, options);
-            assertNull(String.format("failed to install declare permission compat app. Reason: %s",
-                    installResult), installResult);
-
-            // the app will install, but will get error at runtime
-            installResult = getDevice().installPackage(getTestAppFile(PERMISSION_DIFF_CERT_APK),
-                    false, options);
-            assertNull(String.format("failed to install permission app with diff cert. Reason: %s",
-                    installResult), installResult);
-            // run PERMISSION_DIFF_CERT_PKG tests which try to access the permission
-            runDeviceTests(PERMISSION_DIFF_CERT_PKG);
-        } finally {
-            getDevice().uninstallPackage(DECLARE_PERMISSION_PKG);
-            getDevice().uninstallPackage(DECLARE_PERMISSION_COMPAT_PKG);
-            getDevice().uninstallPackage(PERMISSION_DIFF_CERT_PKG);
-        }
-    }
-
-    private void runDeviceTests(String packageName) throws DeviceNotAvailableException {
-        Utils.runDeviceTests(getDevice(), packageName);
-    }
-
-    private void runDeviceTests(String packageName, String testClassName, String testMethodName)
-            throws DeviceNotAvailableException {
-        Utils.runDeviceTests(getDevice(), packageName, testClassName, testMethodName);
-    }
-}
diff --git a/hostsidetests/appsecurity/src/com/android/cts/appsecurity/DocumentsTest.java b/hostsidetests/appsecurity/src/com/android/cts/appsecurity/DocumentsTest.java
deleted file mode 100644
index a4ec65a..0000000
--- a/hostsidetests/appsecurity/src/com/android/cts/appsecurity/DocumentsTest.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.appsecurity;
-
-import com.android.cts.tradefed.build.CtsBuildHelper;
-import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.testtype.DeviceTestCase;
-import com.android.tradefed.testtype.IAbi;
-import com.android.tradefed.testtype.IAbiReceiver;
-import com.android.tradefed.testtype.IBuildReceiver;
-
-/**
- * Set of tests that verify behavior of
- * {@link android.provider.DocumentsContract} and related intents.
- */
-public class DocumentsTest extends DeviceTestCase implements IAbiReceiver, IBuildReceiver {
-    private static final String PROVIDER_PKG = "com.android.cts.documentprovider";
-    private static final String PROVIDER_APK = "CtsDocumentProvider.apk";
-
-    private static final String CLIENT_PKG = "com.android.cts.documentclient";
-    private static final String CLIENT_APK = "CtsDocumentClient.apk";
-
-    private IAbi mAbi;
-    private CtsBuildHelper mCtsBuild;
-
-    @Override
-    public void setAbi(IAbi abi) {
-        mAbi = abi;
-    }
-
-    @Override
-    public void setBuild(IBuildInfo buildInfo) {
-        mCtsBuild = CtsBuildHelper.createBuildHelper(buildInfo);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-
-        assertNotNull(mAbi);
-        assertNotNull(mCtsBuild);
-
-        getDevice().uninstallPackage(PROVIDER_PKG);
-        getDevice().uninstallPackage(CLIENT_PKG);
-
-        assertNull(getDevice().installPackage(mCtsBuild.getTestApp(PROVIDER_APK), false));
-        assertNull(getDevice().installPackage(mCtsBuild.getTestApp(CLIENT_APK), false));
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-
-        getDevice().uninstallPackage(PROVIDER_PKG);
-        getDevice().uninstallPackage(CLIENT_PKG);
-    }
-
-    public void testOpenSimple() throws Exception {
-        runDeviceTests(CLIENT_PKG, ".DocumentsClientTest", "testOpenSimple");
-    }
-
-    public void testCreateNew() throws Exception {
-        runDeviceTests(CLIENT_PKG, ".DocumentsClientTest", "testCreateNew");
-    }
-
-    public void testCreateExisting() throws Exception {
-        runDeviceTests(CLIENT_PKG, ".DocumentsClientTest", "testCreateExisting");
-    }
-
-    public void testTree() throws Exception {
-        runDeviceTests(CLIENT_PKG, ".DocumentsClientTest", "testTree");
-    }
-
-    public void testGetContent() throws Exception {
-        runDeviceTests(CLIENT_PKG, ".DocumentsClientTest", "testGetContent");
-    }
-
-    public void runDeviceTests(String packageName, String testClassName, String testMethodName)
-            throws DeviceNotAvailableException {
-        Utils.runDeviceTests(getDevice(), packageName, testClassName, testMethodName);
-    }
-}
diff --git a/hostsidetests/appsecurity/src/com/android/cts/appsecurity/ExternalStorageHostTest.java b/hostsidetests/appsecurity/src/com/android/cts/appsecurity/ExternalStorageHostTest.java
deleted file mode 100644
index 9c22bdc..0000000
--- a/hostsidetests/appsecurity/src/com/android/cts/appsecurity/ExternalStorageHostTest.java
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.appsecurity;
-
-import com.android.cts.tradefed.build.CtsBuildHelper;
-import com.android.cts.util.AbiUtils;
-import com.android.ddmlib.Log;
-import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.testtype.DeviceTestCase;
-import com.android.tradefed.testtype.IAbi;
-import com.android.tradefed.testtype.IAbiReceiver;
-import com.android.tradefed.testtype.IBuildReceiver;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-
-/**
- * Set of tests that verify behavior of external storage devices.
- */
-public class ExternalStorageHostTest extends DeviceTestCase
-        implements IAbiReceiver, IBuildReceiver {
-    private static final String TAG = "ExternalStorageHostTest";
-
-    private static final String COMMON_CLASS =
-            "com.android.cts.externalstorageapp.CommonExternalStorageTest";
-
-    private static final String NONE_APK = "CtsExternalStorageApp.apk";
-    private static final String NONE_PKG = "com.android.cts.externalstorageapp";
-    private static final String NONE_CLASS = ".ExternalStorageTest";
-    private static final String READ_APK = "CtsReadExternalStorageApp.apk";
-    private static final String READ_PKG = "com.android.cts.readexternalstorageapp";
-    private static final String READ_CLASS = ".ReadExternalStorageTest";
-    private static final String WRITE_APK = "CtsWriteExternalStorageApp.apk";
-    private static final String WRITE_PKG = "com.android.cts.writeexternalstorageapp";
-    private static final String WRITE_CLASS = ".WriteExternalStorageTest";
-    private static final String MULTIUSER_APK = "CtsMultiUserStorageApp.apk";
-    private static final String MULTIUSER_PKG = "com.android.cts.multiuserstorageapp";
-    private static final String MULTIUSER_CLASS = ".MultiUserStorageTest";
-
-    private IAbi mAbi;
-    private CtsBuildHelper mCtsBuild;
-
-    @Override
-    public void setAbi(IAbi abi) {
-        mAbi = abi;
-    }
-
-    @Override
-    public void setBuild(IBuildInfo buildInfo) {
-        mCtsBuild = CtsBuildHelper.createBuildHelper(buildInfo);
-    }
-
-    private File getTestAppFile(String fileName) throws FileNotFoundException {
-        return mCtsBuild.getTestApp(fileName);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-
-        assertNotNull(mAbi);
-        assertNotNull(mCtsBuild);
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-    }
-
-    /**
-     * Verify that app with no external storage permissions works correctly.
-     */
-    public void testExternalStorageNone() throws Exception {
-        final int[] users = createUsersForTest();
-        try {
-            wipePrimaryExternalStorage();
-
-            getDevice().uninstallPackage(NONE_PKG);
-            String[] options = {AbiUtils.createAbiFlag(mAbi.getName())};
-            assertNull(getDevice().installPackage(getTestAppFile(NONE_APK), false, options));
-
-            for (int user : users) {
-                runDeviceTests(NONE_PKG, COMMON_CLASS, user);
-                runDeviceTests(NONE_PKG, NONE_CLASS, user);
-            }
-        } finally {
-            getDevice().uninstallPackage(NONE_PKG);
-            removeUsersForTest(users);
-        }
-    }
-
-    /**
-     * Verify that app with
-     * {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} works
-     * correctly.
-     */
-    public void testExternalStorageRead() throws Exception {
-        final int[] users = createUsersForTest();
-        try {
-            wipePrimaryExternalStorage();
-
-            getDevice().uninstallPackage(READ_PKG);
-            String[] options = {AbiUtils.createAbiFlag(mAbi.getName())};
-            assertNull(getDevice().installPackage(getTestAppFile(READ_APK), false, options));
-
-            for (int user : users) {
-                runDeviceTests(READ_PKG, COMMON_CLASS, user);
-                runDeviceTests(READ_PKG, READ_CLASS, user);
-            }
-        } finally {
-            getDevice().uninstallPackage(READ_PKG);
-            removeUsersForTest(users);
-        }
-    }
-
-    /**
-     * Verify that app with
-     * {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} works
-     * correctly.
-     */
-    public void testExternalStorageWrite() throws Exception {
-        final int[] users = createUsersForTest();
-        try {
-            wipePrimaryExternalStorage();
-
-            getDevice().uninstallPackage(WRITE_PKG);
-            String[] options = {AbiUtils.createAbiFlag(mAbi.getName())};
-            assertNull(getDevice().installPackage(getTestAppFile(WRITE_APK), false, options));
-
-            for (int user : users) {
-                runDeviceTests(WRITE_PKG, COMMON_CLASS, user);
-                runDeviceTests(WRITE_PKG, WRITE_CLASS, user);
-            }
-        } finally {
-            getDevice().uninstallPackage(WRITE_PKG);
-            removeUsersForTest(users);
-        }
-    }
-
-    /**
-     * Verify that app with WRITE_EXTERNAL can leave gifts in external storage
-     * directories belonging to other apps, and those apps can read.
-     */
-    public void testExternalStorageGifts() throws Exception {
-        final int[] users = createUsersForTest();
-        try {
-            wipePrimaryExternalStorage();
-
-            getDevice().uninstallPackage(NONE_PKG);
-            getDevice().uninstallPackage(READ_PKG);
-            getDevice().uninstallPackage(WRITE_PKG);
-            String[] options = {AbiUtils.createAbiFlag(mAbi.getName())};
-            assertNull(getDevice().installPackage(getTestAppFile(NONE_APK), false, options));
-            assertNull(getDevice().installPackage(getTestAppFile(READ_APK), false, options));
-            assertNull(getDevice().installPackage(getTestAppFile(WRITE_APK), false, options));
-
-            for (int user : users) {
-                runDeviceTests(WRITE_PKG, "WriteGiftTest", user);
-                runDeviceTests(READ_PKG, "ReadGiftTest", user);
-                runDeviceTests(NONE_PKG, "GiftTest", user);
-            }
-        } finally {
-            getDevice().uninstallPackage(NONE_PKG);
-            getDevice().uninstallPackage(READ_PKG);
-            getDevice().uninstallPackage(WRITE_PKG);
-            removeUsersForTest(users);
-        }
-    }
-
-    /**
-     * Test multi-user emulated storage environment, ensuring that each user has
-     * isolated storage.
-     */
-    public void testMultiUserStorageIsolated() throws Exception {
-        final int[] users = createUsersForTest();
-        try {
-            if (users.length == 1) {
-                Log.d(TAG, "Single user device; skipping isolated storage tests");
-                return;
-            }
-
-            final int owner = users[0];
-            final int secondary = users[1];
-
-            // Install our test app
-            getDevice().uninstallPackage(MULTIUSER_PKG);
-            String[] options = {AbiUtils.createAbiFlag(mAbi.getName())};
-            final String installResult = getDevice()
-                    .installPackage(getTestAppFile(MULTIUSER_APK), false, options);
-            assertNull("Failed to install: " + installResult, installResult);
-
-            // Clear data from previous tests
-            runDeviceTests(MULTIUSER_PKG, MULTIUSER_CLASS, "testCleanIsolatedStorage", owner);
-            runDeviceTests(MULTIUSER_PKG, MULTIUSER_CLASS, "testCleanIsolatedStorage", secondary);
-
-            // Have both users try writing into isolated storage
-            runDeviceTests(MULTIUSER_PKG, MULTIUSER_CLASS, "testWriteIsolatedStorage", owner);
-            runDeviceTests(MULTIUSER_PKG, MULTIUSER_CLASS, "testWriteIsolatedStorage", secondary);
-
-            // Verify they both have isolated view of storage
-            runDeviceTests(MULTIUSER_PKG, MULTIUSER_CLASS, "testReadIsolatedStorage", owner);
-            runDeviceTests(MULTIUSER_PKG, MULTIUSER_CLASS, "testReadIsolatedStorage", secondary);
-
-            // Verify they can't poke at each other
-            runDeviceTests(MULTIUSER_PKG, MULTIUSER_CLASS, "testUserIsolation", owner);
-            runDeviceTests(MULTIUSER_PKG, MULTIUSER_CLASS, "testUserIsolation", secondary);
-        } finally {
-            getDevice().uninstallPackage(MULTIUSER_PKG);
-            removeUsersForTest(users);
-        }
-    }
-
-    private void wipePrimaryExternalStorage() throws DeviceNotAvailableException {
-        getDevice().executeShellCommand("rm -rf /sdcard/Android");
-        getDevice().executeShellCommand("rm -rf /sdcard/DCIM");
-        getDevice().executeShellCommand("rm -rf /sdcard/MUST_*");
-    }
-
-    private int[] createUsersForTest() throws DeviceNotAvailableException {
-        return Utils.createUsersForTest(getDevice());
-    }
-
-    private void removeUsersForTest(int[] users) throws DeviceNotAvailableException {
-        Utils.removeUsersForTest(getDevice(), users);
-    }
-
-    private void runDeviceTests(String packageName, String testClassName, int userId)
-            throws DeviceNotAvailableException {
-        Utils.runDeviceTests(getDevice(), packageName, testClassName, userId);
-    }
-
-    private void runDeviceTests(String packageName, String testClassName, String testMethodName,
-            int userId) throws DeviceNotAvailableException {
-        Utils.runDeviceTests(getDevice(), packageName, testClassName, testMethodName, userId);
-    }
-}
diff --git a/hostsidetests/appsecurity/src/com/android/cts/appsecurity/KeySetHostTest.java b/hostsidetests/appsecurity/src/com/android/cts/appsecurity/KeySetHostTest.java
deleted file mode 100644
index 9637a6c..0000000
--- a/hostsidetests/appsecurity/src/com/android/cts/appsecurity/KeySetHostTest.java
+++ /dev/null
@@ -1,515 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.cts.appsecurity;
-
-import com.android.cts.tradefed.build.CtsBuildHelper;
-import com.android.ddmlib.Log;
-import com.android.ddmlib.Log.LogLevel;
-import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
-import com.android.ddmlib.testrunner.TestIdentifier;
-import com.android.ddmlib.testrunner.TestResult;
-import com.android.ddmlib.testrunner.TestResult.TestStatus;
-import com.android.ddmlib.testrunner.TestRunResult;
-import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.result.CollectingTestListener;
-import com.android.tradefed.testtype.DeviceTestCase;
-import com.android.tradefed.testtype.IBuildReceiver;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.util.Map;
-
-/**
- * Tests for Keyset based features.
- */
-public class KeySetHostTest extends DeviceTestCase implements IBuildReceiver {
-
-    private static final String RUNNER = "android.support.test.runner.AndroidJUnitRunner";
-
-    /* package with device-side tests */
-    private static final String KEYSET_TEST_PKG = "com.android.cts.keysets.testapp";
-    private static final String KEYSET_TEST_APP_APK = "CtsKeySetTestApp.apk";
-
-    /* plain test apks with different signing and upgrade keysets */
-    private static final String KEYSET_PKG = "com.android.cts.keysets";
-    private static final String A_SIGNED_NO_UPGRADE =
-            "CtsKeySetSigningAUpgradeNone.apk";
-    private static final String A_SIGNED_A_UPGRADE =
-            "CtsKeySetSigningAUpgradeA.apk";
-    private static final String A_SIGNED_B_UPGRADE =
-            "CtsKeySetSigningAUpgradeB.apk";
-    private static final String A_SIGNED_A_OR_B_UPGRADE =
-            "CtsKeySetSigningAUpgradeAOrB.apk";
-    private static final String B_SIGNED_A_UPGRADE =
-            "CtsKeySetSigningBUpgradeA.apk";
-    private static final String B_SIGNED_B_UPGRADE =
-            "CtsKeySetSigningBUpgradeB.apk";
-    private static final String A_AND_B_SIGNED_A_UPGRADE =
-            "CtsKeySetSigningAAndBUpgradeA.apk";
-    private static final String A_AND_B_SIGNED_B_UPGRADE =
-            "CtsKeySetSigningAAndBUpgradeB.apk";
-    private static final String A_AND_C_SIGNED_B_UPGRADE =
-            "CtsKeySetSigningAAndCUpgradeB.apk";
-    private static final String SHARED_USR_A_SIGNED_B_UPGRADE =
-            "CtsKeySetSharedUserSigningAUpgradeB.apk";
-    private static final String SHARED_USR_B_SIGNED_B_UPGRADE =
-            "CtsKeySetSharedUserSigningBUpgradeB.apk";
-    private static final String A_SIGNED_BAD_B_B_UPGRADE =
-            "CtsKeySetSigningABadUpgradeB.apk";
-    private static final String C_SIGNED_BAD_A_AB_UPGRADE =
-            "CtsKeySetSigningCBadAUpgradeAB.apk";
-    private static final String A_SIGNED_NO_B_B_UPGRADE =
-            "CtsKeySetSigningANoDefUpgradeB.apk";
-    private static final String A_SIGNED_EC_A_UPGRADE =
-            "CtsKeySetSigningAUpgradeEcA.apk";
-    private static final String EC_A_SIGNED_A_UPGRADE =
-            "CtsKeySetSigningEcAUpgradeA.apk";
-
-    /* package which defines the KEYSET_PERM_NAME signature permission */
-    private static final String KEYSET_PERM_DEF_PKG =
-            "com.android.cts.keysets_permdef";
-
-    /* The apks defining and using the permission have both A and B as upgrade keys */
-    private static final String PERM_DEF_A_SIGNED =
-            "CtsKeySetPermDefSigningA.apk";
-    private static final String PERM_DEF_B_SIGNED =
-            "CtsKeySetPermDefSigningB.apk";
-    private static final String PERM_USE_A_SIGNED =
-            "CtsKeySetPermUseSigningA.apk";
-    private static final String PERM_USE_B_SIGNED =
-            "CtsKeySetPermUseSigningB.apk";
-
-    private static final String PERM_TEST_CLASS =
-        "com.android.cts.keysets.KeySetPermissionsTest";
-
-    private static final String LOG_TAG = "AppsecurityHostTests";
-
-    private File getTestAppFile(String fileName) throws FileNotFoundException {
-        return mCtsBuild.getTestApp(fileName);
-    }
-
-    /**
-     * Helper method that checks that all tests in given result passed, and attempts to generate
-     * a meaningful error message if they failed.
-     *
-     * @param result
-     */
-    private void assertDeviceTestsPass(TestRunResult result) {
-        assertFalse(String.format("Failed to successfully run device tests for %s. Reason: %s",
-                result.getName(), result.getRunFailureMessage()), result.isRunFailure());
-
-        if (result.hasFailedTests()) {
-
-            /* build a meaningful error message */
-            StringBuilder errorBuilder = new StringBuilder("on-device tests failed:\n");
-            for (Map.Entry<TestIdentifier, TestResult> resultEntry :
-                result.getTestResults().entrySet()) {
-                if (!resultEntry.getValue().getStatus().equals(TestStatus.PASSED)) {
-                    errorBuilder.append(resultEntry.getKey().toString());
-                    errorBuilder.append(":\n");
-                    errorBuilder.append(resultEntry.getValue().getStackTrace());
-                }
-            }
-            fail(errorBuilder.toString());
-        }
-    }
-
-    /**
-     * Helper method that checks that all tests in given result passed, and attempts to generate
-     * a meaningful error message if they failed.
-     *
-     * @param result
-     */
-    private void assertDeviceTestsFail(String msg, TestRunResult result) {
-        assertFalse(String.format("Failed to successfully run device tests for %s. Reason: %s",
-                result.getName(), result.getRunFailureMessage()), result.isRunFailure());
-
-        if (!result.hasFailedTests()) {
-            fail(msg);
-        }
-    }
-
-    /**
-     * Helper method that will run the specified packages tests on device.
-     *
-     * @param pkgName Android application package for tests
-     * @return <code>true</code> if all tests passed.
-     * @throws DeviceNotAvailableException if connection to device was lost.
-     */
-    private boolean runDeviceTests(String pkgName) throws DeviceNotAvailableException {
-        return runDeviceTests(pkgName, null, null);
-    }
-
-    /**
-     * Helper method that will run the specified packages tests on device.
-     *
-     * @param pkgName Android application package for tests
-     * @return <code>true</code> if all tests passed.
-     * @throws DeviceNotAvailableException if connection to device was lost.
-     */
-    private boolean runDeviceTests(String pkgName, String testClassName, String testMethodName)
-            throws DeviceNotAvailableException {
-        TestRunResult runResult = doRunTests(pkgName, testClassName, testMethodName);
-        return !runResult.hasFailedTests();
-    }
-
-    /**
-     * Helper method to run tests and return the listener that collected the results.
-     *
-     * @param pkgName Android application package for tests
-     * @return the {@link TestRunResult}
-     * @throws DeviceNotAvailableException if connection to device was lost.
-     */
-    private TestRunResult doRunTests(String pkgName, String testClassName,
-            String testMethodName) throws DeviceNotAvailableException {
-
-        RemoteAndroidTestRunner testRunner = new RemoteAndroidTestRunner(pkgName,
-                RUNNER, getDevice().getIDevice());
-        if (testClassName != null && testMethodName != null) {
-            testRunner.setMethodName(testClassName, testMethodName);
-        }
-        CollectingTestListener listener = new CollectingTestListener();
-        getDevice().runInstrumentationTests(testRunner, listener);
-        return listener.getCurrentRunResults();
-    }
-
-    /**
-     * Helper method which installs a package and an upgrade to it.
-     *
-     * @param pkgName - package name of apk.
-     * @param firstApk - first apk to install
-     * @param secondApk - apk to which we attempt to upgrade
-     * @param expectedResult - null if successful, otherwise expected error.
-     */
-    private String testPackageUpgrade(String pkgName, String firstApk,
-             String secondApk) throws Exception {
-        String installResult;
-        try {
-
-            /* cleanup test apps that might be installed from previous partial test run */
-            mDevice.uninstallPackage(pkgName);
-
-            installResult = mDevice.installPackage(getTestAppFile(firstApk),
-                    false);
-            /* we should always succeed on first-install */
-            assertNull(String.format("failed to install %s, Reason: %s", pkgName,
-                       installResult), installResult);
-
-            /* attempt to install upgrade */
-            installResult = mDevice.installPackage(getTestAppFile(secondApk),
-                    true);
-        } finally {
-            mDevice.uninstallPackage(pkgName);
-        }
-        return installResult;
-    }
-    /**
-     * A reference to the device under test.
-     */
-    private ITestDevice mDevice;
-
-    private CtsBuildHelper mCtsBuild;
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void setBuild(IBuildInfo buildInfo) {
-        mCtsBuild = CtsBuildHelper.createBuildHelper(buildInfo);
-    }
-
-    @Override
-        protected void setUp() throws Exception {
-        super.setUp();
-        mDevice = getDevice();
-        assertNotNull(mCtsBuild);
-    }
-
-    /**
-     * Tests for KeySet based key rotation
-     */
-
-    /*
-     * Check if an apk which does not specify an upgrade-key-set may be upgraded
-     * to an apk which does.
-     */
-    public void testNoKSToUpgradeKS() throws Exception {
-        String installResult = testPackageUpgrade(KEYSET_PKG, A_SIGNED_NO_UPGRADE, A_SIGNED_A_UPGRADE);
-        assertNull(String.format("failed to upgrade keyset app from no specified upgrade-key-set"
-                + "to version with specified upgrade-key-set, Reason: %s", installResult),
-                installResult);
-    }
-
-    /*
-     * Check if an apk which does specify an upgrade-key-set may be upgraded
-     * to an apk which does not.
-     */
-    public void testUpgradeKSToNoKS() throws Exception {
-        String installResult = testPackageUpgrade(KEYSET_PKG, A_SIGNED_A_UPGRADE, A_SIGNED_NO_UPGRADE);
-        assertNull(String.format("failed to upgrade keyset app from specified upgrade-key-set"
-                + "to version without specified upgrade-key-set, Reason: %s", installResult),
-                installResult);
-    }
-
-    /*
-     * Check if an apk signed by a key other than the upgrade keyset can update
-     * an app
-     */
-    public void testUpgradeKSWithWrongKey() throws Exception {
-        String installResult = testPackageUpgrade(KEYSET_PKG, A_SIGNED_A_UPGRADE, B_SIGNED_A_UPGRADE);
-        assertNotNull("upgrade to improperly signed app succeeded!", installResult);
-    }
-
-    /*
-     * Check if an apk signed by its signing key, which is not an upgrade key,
-     * can upgrade an app.
-     */
-    public void testUpgradeKSWithWrongSigningKey() throws Exception {
-        String installResult = testPackageUpgrade(KEYSET_PKG, A_SIGNED_B_UPGRADE, A_SIGNED_B_UPGRADE);
-         assertNotNull("upgrade to improperly signed app succeeded!",
-                 installResult);
-    }
-
-    /*
-     * Check if an apk signed by its upgrade key, which is not its signing key,
-     * can upgrade an app.
-     */
-    public void testUpgradeKSWithUpgradeKey() throws Exception {
-        String installResult = testPackageUpgrade(KEYSET_PKG, A_SIGNED_B_UPGRADE, B_SIGNED_B_UPGRADE);
-        assertNull(String.format("failed to upgrade keyset app from one signed by key-a"
-                 + "to version signed by upgrade-key-set key-b, Reason: %s", installResult),
-                 installResult);
-    }
-
-    /*
-     * Check if an apk signed by its upgrade key, which is its signing key, can
-     * upgrade an app.
-     */
-    public void testUpgradeKSWithSigningUpgradeKey() throws Exception {
-        String installResult = testPackageUpgrade(KEYSET_PKG, A_SIGNED_A_UPGRADE, A_SIGNED_A_UPGRADE);
-        assertNull(String.format("failed to upgrade keyset app from one signed by key-a"
-                    + "to version signed by upgrade-key-set key-b, Reason: %s", installResult),
-                    installResult);
-    }
-
-    /*
-     * Check if an apk signed by multiple keys, one of which is its upgrade key,
-     * can upgrade an app.
-     */
-    public void testMultipleUpgradeKSWithUpgradeKey() throws Exception {
-        String installResult = testPackageUpgrade(KEYSET_PKG, A_SIGNED_A_UPGRADE,
-                A_AND_B_SIGNED_A_UPGRADE);
-        assertNull(String.format("failed to upgrade keyset app from one signed by key-a"
-                + "to version signed by upgrade-key-set key-b, Reason: %s", installResult),
-                installResult);
-    }
-
-    /*
-     * Check if an apk signed by multiple keys, its signing keys,
-     * but none of which is an upgrade key, can upgrade an app.
-     */
-    public void testMultipleUpgradeKSWithSigningKey() throws Exception {
-        String installResult = testPackageUpgrade(KEYSET_PKG, A_AND_C_SIGNED_B_UPGRADE,
-                A_AND_C_SIGNED_B_UPGRADE);
-        assertNotNull("upgrade to improperly signed app succeeded!", installResult);
-    }
-
-    /*
-     * Check if an apk which defines multiple (two) upgrade keysets is
-     * upgrade-able by either.
-     */
-    public void testUpgradeKSWithMultipleUpgradeKeySetsFirstKey() throws Exception {
-        String installResult = testPackageUpgrade(KEYSET_PKG, A_SIGNED_A_OR_B_UPGRADE,
-                A_SIGNED_A_UPGRADE);
-        assertNull(String.format("failed to upgrade keyset app from one signed by key-a"
-                + "to one signed by first upgrade keyset key-a, Reason: %s", installResult),
-                installResult);
-        installResult = testPackageUpgrade(KEYSET_PKG, A_SIGNED_A_OR_B_UPGRADE,
-                B_SIGNED_B_UPGRADE);
-        assertNull(String.format("failed to upgrade keyset app from one signed by key-a"
-                + "to one signed by second upgrade keyset key-b, Reason: %s", installResult),
-                installResult);
-    }
-
-    /**
-     * Helper method which installs a package defining a permission and a package
-     * using the permission, and then rotates the signing keys for one of them.
-     * A device-side test is then used to ascertain whether or not the permission
-     * was appropriately gained or lost.
-     *
-     * @param permDefApk - apk to install which defines the sig-permissoin
-     * @param permUseApk - apk to install which declares it uses the permission
-     * @param upgradeApk - apk to install which upgrades one of the first two
-     * @param hasPermBeforeUpgrade - whether we expect the consuming app to have
-     *        the permission before the upgrade takes place.
-     * @param hasPermAfterUpgrade - whether we expect the consuming app to have
-     *        the permission after the upgrade takes place.
-     */
-    private void testKeyRotationPerm(String permDefApk, String permUseApk,
-            String upgradeApk, boolean hasPermBeforeUpgrade,
-            boolean hasPermAfterUpgrade) throws Exception {
-        try {
-
-            /* cleanup test apps that might be installed from previous partial test run */
-            mDevice.uninstallPackage(KEYSET_PKG);
-            mDevice.uninstallPackage(KEYSET_PERM_DEF_PKG);
-            mDevice.uninstallPackage(KEYSET_TEST_PKG);
-
-            /* install PERM_DEF, KEYSET_APP and KEYSET_TEST_APP */
-            String installResult = mDevice.installPackage(
-                    getTestAppFile(permDefApk), false);
-            assertNull(String.format("failed to install keyset perm-def app, Reason: %s",
-                       installResult), installResult);
-            installResult = getDevice().installPackage(
-                    getTestAppFile(permUseApk), false);
-            assertNull(String.format("failed to install keyset test app. Reason: %s",
-                    installResult), installResult);
-            installResult = getDevice().installPackage(
-                    getTestAppFile(KEYSET_TEST_APP_APK), false);
-            assertNull(String.format("failed to install keyset test app. Reason: %s",
-                    installResult), installResult);
-
-            /* verify package does have perm */
-            TestRunResult result = doRunTests(KEYSET_TEST_PKG, PERM_TEST_CLASS,
-                    "testHasPerm");
-            if (hasPermBeforeUpgrade) {
-                assertDeviceTestsPass(result);
-            } else {
-                assertDeviceTestsFail(" has permission permission it should not have.", result);
-            }
-
-            /* rotate keys */
-            installResult = mDevice.installPackage(getTestAppFile(upgradeApk),
-                    true);
-            result = doRunTests(KEYSET_TEST_PKG, PERM_TEST_CLASS,
-                    "testHasPerm");
-            if (hasPermAfterUpgrade) {
-                assertDeviceTestsPass(result);
-            } else {
-                assertDeviceTestsFail(KEYSET_PKG + " has permission it should not have.", result);
-            }
-        } finally {
-            mDevice.uninstallPackage(KEYSET_PKG);
-            mDevice.uninstallPackage(KEYSET_PERM_DEF_PKG);
-            mDevice.uninstallPackage(KEYSET_TEST_PKG);
-        }
-    }
-
-    /*
-     * Check if an apk gains signature-level permission after changing to a new
-     * signature, for which a permission should be granted.
-     */
-    public void testUpgradeSigPermGained() throws Exception {
-        testKeyRotationPerm(PERM_DEF_A_SIGNED, PERM_USE_B_SIGNED, PERM_USE_A_SIGNED,
-                false, true);
-    }
-
-    /*
-     * Check if an apk loses signature-level permission after changing to a new
-     * signature, from one for which a permission was previously granted.
-     */
-    public void testUpgradeSigPermLost() throws Exception {
-        testKeyRotationPerm(PERM_DEF_A_SIGNED, PERM_USE_A_SIGNED, PERM_USE_B_SIGNED,
-                true, false);
-    }
-
-    /*
-     * Check if an apk gains signature-level permission after the app defining
-     * it rotates to the same signature.
-     */
-    public void testUpgradeDefinerSigPermGained() throws Exception {
-        testKeyRotationPerm(PERM_DEF_A_SIGNED, PERM_USE_B_SIGNED, PERM_DEF_B_SIGNED,
-                false, true);
-    }
-
-    /*
-     * Check if an apk loses signature-level permission after the app defining
-     * it rotates to a different signature.
-     */
-    public void testUpgradeDefinerSigPermLost() throws Exception {
-        testKeyRotationPerm(PERM_DEF_A_SIGNED, PERM_USE_A_SIGNED, PERM_DEF_B_SIGNED,
-                true, false);
-    }
-
-    /*
-     * Check if an apk which indicates it uses a sharedUserId and defines an
-     * upgrade keyset is allowed to rotate to that keyset.
-     */
-    public void testUpgradeSharedUser() throws Exception {
-        String installResult = testPackageUpgrade(KEYSET_PKG, SHARED_USR_A_SIGNED_B_UPGRADE,
-                SHARED_USR_B_SIGNED_B_UPGRADE);
-        assertNotNull("upgrade allowed for app with shareduserid!", installResult);
-    }
-
-    /*
-     * Check that an apk with an upgrade key represented by a bad public key
-     * fails to install.
-     */
-    public void testBadUpgradeBadPubKey() throws Exception {
-        mDevice.uninstallPackage(KEYSET_PKG);
-        String installResult = mDevice.installPackage(getTestAppFile(A_SIGNED_BAD_B_B_UPGRADE),
-                false);
-        assertNotNull("Installation of apk with upgrade key referring to a bad public key succeeded!",
-                installResult);
-    }
-
-    /*
-     * Check that an apk with an upgrade keyset that includes a bad public key fails to install.
-     */
-    public void testBadUpgradeMissingPubKey() throws Exception {
-        mDevice.uninstallPackage(KEYSET_PKG);
-        String installResult = mDevice.installPackage(getTestAppFile(C_SIGNED_BAD_A_AB_UPGRADE),
-                false);
-        assertNotNull("Installation of apk with upgrade key referring to a bad public key succeeded!",
-                installResult);
-    }
-
-    /*
-     * Check that an apk with an upgrade key that has no corresponding public key fails to install.
-     */
-    public void testBadUpgradeNoPubKey() throws Exception {
-        mDevice.uninstallPackage(KEYSET_PKG);
-        String installResult = mDevice.installPackage(getTestAppFile(A_SIGNED_NO_B_B_UPGRADE),
-                false);
-        assertNotNull("Installation of apk with upgrade key referring to a bad public key succeeded!",
-                installResult);
-    }
-
-    /*
-     * Check if an apk signed by RSA pub key can upgrade to apk signed by EC key.
-     */
-    public void testUpgradeKSRsaToEC() throws Exception {
-        String installResult = testPackageUpgrade(KEYSET_PKG, A_SIGNED_EC_A_UPGRADE,
-                EC_A_SIGNED_A_UPGRADE);
-        assertNull(String.format("failed to upgrade keyset app from one signed by RSA key"
-                 + "to version signed by EC upgrade-key-set, Reason: %s", installResult),
-                 installResult);
-    }
-
-    /*
-     * Check if an apk signed by EC pub key can upgrade to apk signed by RSA key.
-     */
-    public void testUpgradeKSECToRSA() throws Exception {
-        String installResult = testPackageUpgrade(KEYSET_PKG, EC_A_SIGNED_A_UPGRADE,
-                A_SIGNED_EC_A_UPGRADE);
-        assertNull(String.format("failed to upgrade keyset app from one signed by EC key"
-                 + "to version signed by RSA upgrade-key-set, Reason: %s", installResult),
-                 installResult);
-    }
-}
diff --git a/hostsidetests/appsecurity/src/com/android/cts/appsecurity/PermissionsHostTest.java b/hostsidetests/appsecurity/src/com/android/cts/appsecurity/PermissionsHostTest.java
deleted file mode 100644
index 20a92aa..0000000
--- a/hostsidetests/appsecurity/src/com/android/cts/appsecurity/PermissionsHostTest.java
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.appsecurity;
-
-import com.android.cts.tradefed.build.CtsBuildHelper;
-import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.testtype.DeviceTestCase;
-import com.android.tradefed.testtype.IAbi;
-import com.android.tradefed.testtype.IAbiReceiver;
-import com.android.tradefed.testtype.IBuildReceiver;
-
-/**
- * Set of tests that verify behavior of runtime permissions, including both
- * dynamic granting and behavior of legacy apps.
- */
-public class PermissionsHostTest extends DeviceTestCase implements IAbiReceiver, IBuildReceiver {
-    private static final String PKG = "com.android.cts.usepermission";
-
-    private static final String APK = "CtsUsePermissionApp.apk";
-    private static final String APK_COMPAT = "CtsUsePermissionAppCompat.apk";
-
-    private IAbi mAbi;
-    private CtsBuildHelper mCtsBuild;
-
-    @Override
-    public void setAbi(IAbi abi) {
-        mAbi = abi;
-    }
-
-    @Override
-    public void setBuild(IBuildInfo buildInfo) {
-        mCtsBuild = CtsBuildHelper.createBuildHelper(buildInfo);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-
-        assertNotNull(mAbi);
-        assertNotNull(mCtsBuild);
-
-        getDevice().uninstallPackage(PKG);
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-
-        getDevice().uninstallPackage(PKG);
-    }
-
-    public void testFail() throws Exception {
-        // Sanity check that remote failure is host failure
-        assertNull(getDevice().installPackage(mCtsBuild.getTestApp(APK), false, false));
-        try {
-            runDeviceTests(PKG, ".UsePermissionTest", "testFail");
-            fail("Expected remote failure");
-        } catch (AssertionError expected) {
-        }
-    }
-
-    public void testKill() throws Exception {
-        // Sanity check that remote kill is host failure
-        assertNull(getDevice().installPackage(mCtsBuild.getTestApp(APK), false, false));
-        try {
-            runDeviceTests(PKG, ".UsePermissionTest", "testKill");
-            fail("Expected remote failure");
-        } catch (AssertionError expected) {
-        }
-    }
-
-    public void testDefault() throws Exception {
-        assertNull(getDevice().installPackage(mCtsBuild.getTestApp(APK), false, false));
-        runDeviceTests(PKG, ".UsePermissionTest", "testDefault");
-    }
-
-    public void testGranted() throws Exception {
-        assertNull(getDevice().installPackage(mCtsBuild.getTestApp(APK), false, false));
-        grantPermission(PKG, "android.permission.READ_EXTERNAL_STORAGE");
-        grantPermission(PKG, "android.permission.WRITE_EXTERNAL_STORAGE");
-        runDeviceTests(PKG, ".UsePermissionTest", "testGranted");
-    }
-
-    public void testInteractiveGrant() throws Exception {
-        assertNull(getDevice().installPackage(mCtsBuild.getTestApp(APK), false, false));
-        runDeviceTests(PKG, ".UsePermissionTest", "testInteractiveGrant");
-    }
-
-    public void testRuntimeGroupGrantSpecificity() throws Exception {
-        assertNull(getDevice().installPackage(mCtsBuild.getTestApp(APK), false, false));
-        runDeviceTests(PKG, ".UsePermissionTest", "testRuntimeGroupGrantSpecificity");
-    }
-
-    public void testRuntimeGroupGrantExpansion() throws Exception {
-        assertNull(getDevice().installPackage(mCtsBuild.getTestApp(APK), false, false));
-        runDeviceTests(PKG, ".UsePermissionTest", "testRuntimeGroupGrantExpansion");
-    }
-
-    public void testCompatDefault() throws Exception {
-        assertNull(getDevice().installPackage(mCtsBuild.getTestApp(APK_COMPAT), false, false));
-        runDeviceTests(PKG, ".UsePermissionCompatTest", "testCompatDefault");
-    }
-
-    public void testCompatRevoked() throws Exception {
-        assertNull(getDevice().installPackage(mCtsBuild.getTestApp(APK_COMPAT), false, false));
-        setAppOps(PKG, "android:read_external_storage", "deny");
-        setAppOps(PKG, "android:write_external_storage", "deny");
-        runDeviceTests(PKG, ".UsePermissionCompatTest", "testCompatRevoked");
-    }
-
-    private void runDeviceTests(String packageName, String testClassName, String testMethodName)
-            throws DeviceNotAvailableException {
-        Utils.runDeviceTests(getDevice(), packageName, testClassName, testMethodName);
-    }
-
-    private void grantPermission(String pkg, String permission) throws Exception {
-        assertEmpty(getDevice().executeShellCommand("pm grant " + pkg + " " + permission));
-    }
-
-    private void revokePermission(String pkg, String permission) throws Exception {
-        assertEmpty(getDevice().executeShellCommand("pm revoke " + pkg + " " + permission));
-    }
-
-    private void setAppOps(String pkg, String op, String mode) throws Exception {
-        assertEmpty(getDevice().executeShellCommand("appops set " + pkg + " " + op + " " + mode));
-    }
-
-    private static void assertEmpty(String str) {
-        if (str == null || str.length() == 0) {
-            return;
-        } else {
-            fail("Expected empty string but found " + str);
-        }
-    }
-}
diff --git a/hostsidetests/appsecurity/src/com/android/cts/appsecurity/SplitTests.java b/hostsidetests/appsecurity/src/com/android/cts/appsecurity/SplitTests.java
deleted file mode 100644
index ef3af8d..0000000
--- a/hostsidetests/appsecurity/src/com/android/cts/appsecurity/SplitTests.java
+++ /dev/null
@@ -1,429 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.appsecurity;
-
-import com.android.cts.tradefed.build.CtsBuildHelper;
-import com.android.cts.util.AbiUtils;
-import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.testtype.DeviceTestCase;
-import com.android.tradefed.testtype.IAbi;
-import com.android.tradefed.testtype.IAbiReceiver;
-import com.android.tradefed.testtype.IBuildReceiver;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-
-/**
- * Tests that verify installing of various split APKs from host side.
- */
-public class SplitTests extends DeviceTestCase implements IAbiReceiver, IBuildReceiver {
-    static final String PKG = "com.android.cts.splitapp";
-    static final String CLASS = ".SplitAppTest";
-
-    static final String APK = "CtsSplitApp.apk";
-
-    static final String APK_mdpi = "CtsSplitApp_mdpi-v4.apk";
-    static final String APK_hdpi = "CtsSplitApp_hdpi-v4.apk";
-    static final String APK_xhdpi = "CtsSplitApp_xhdpi-v4.apk";
-    static final String APK_xxhdpi = "CtsSplitApp_xxhdpi-v4.apk";
-
-    private static final String APK_v7 = "CtsSplitApp_v7.apk";
-    private static final String APK_fr = "CtsSplitApp_fr.apk";
-    private static final String APK_de = "CtsSplitApp_de.apk";
-
-    private static final String APK_x86 = "CtsSplitApp_x86.apk";
-    private static final String APK_x86_64 = "CtsSplitApp_x86_64.apk";
-    private static final String APK_armeabi_v7a = "CtsSplitApp_armeabi-v7a.apk";
-    private static final String APK_armeabi = "CtsSplitApp_armeabi.apk";
-    private static final String APK_arm64_v8a = "CtsSplitApp_arm64-v8a.apk";
-    private static final String APK_mips64 = "CtsSplitApp_mips64.apk";
-    private static final String APK_mips = "CtsSplitApp_mips.apk";
-
-    private static final String APK_DIFF_REVISION = "CtsSplitAppDiffRevision.apk";
-    private static final String APK_DIFF_REVISION_v7 = "CtsSplitAppDiffRevision_v7.apk";
-
-    private static final String APK_DIFF_VERSION = "CtsSplitAppDiffVersion.apk";
-    private static final String APK_DIFF_VERSION_v7 = "CtsSplitAppDiffVersion_v7.apk";
-
-    private static final String APK_DIFF_CERT = "CtsSplitAppDiffCert.apk";
-    private static final String APK_DIFF_CERT_v7 = "CtsSplitAppDiffCert_v7.apk";
-
-    private static final String APK_FEATURE = "CtsSplitAppFeature.apk";
-    private static final String APK_FEATURE_v7 = "CtsSplitAppFeature_v7.apk";
-
-    static final HashMap<String, String> ABI_TO_APK = new HashMap<>();
-
-    static {
-        ABI_TO_APK.put("x86", APK_x86);
-        ABI_TO_APK.put("x86_64", APK_x86_64);
-        ABI_TO_APK.put("armeabi-v7a", APK_armeabi_v7a);
-        ABI_TO_APK.put("armeabi", APK_armeabi);
-        ABI_TO_APK.put("arm64-v8a", APK_arm64_v8a);
-        ABI_TO_APK.put("mips64", APK_mips64);
-        ABI_TO_APK.put("mips", APK_mips);
-    }
-
-    private IAbi mAbi;
-    private CtsBuildHelper mCtsBuild;
-
-    @Override
-    public void setAbi(IAbi abi) {
-        mAbi = abi;
-    }
-
-    @Override
-    public void setBuild(IBuildInfo buildInfo) {
-        mCtsBuild = CtsBuildHelper.createBuildHelper(buildInfo);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-
-        assertNotNull(mAbi);
-        assertNotNull(mCtsBuild);
-
-        getDevice().uninstallPackage(PKG);
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-
-        getDevice().uninstallPackage(PKG);
-    }
-
-    public void testSingleBase() throws Exception {
-        new InstallMultiple().addApk(APK).run();
-        runDeviceTests(PKG, CLASS, "testSingleBase");
-    }
-
-    public void testDensitySingle() throws Exception {
-        new InstallMultiple().addApk(APK).addApk(APK_mdpi).run();
-        runDeviceTests(PKG, CLASS, "testDensitySingle");
-    }
-
-    public void testDensityAll() throws Exception {
-        new InstallMultiple().addApk(APK).addApk(APK_mdpi).addApk(APK_hdpi).addApk(APK_xhdpi)
-                .addApk(APK_xxhdpi).run();
-        runDeviceTests(PKG, CLASS, "testDensityAll");
-    }
-
-    /**
-     * Install first with low-resolution resources, then add a split that offers
-     * higher-resolution resources.
-     */
-    public void testDensityBest() throws Exception {
-        new InstallMultiple().addApk(APK).addApk(APK_mdpi).run();
-        runDeviceTests(PKG, CLASS, "testDensityBest1");
-
-        // Now splice in an additional split which offers better resources
-        new InstallMultiple().inheritFrom(PKG).addApk(APK_xxhdpi).run();
-        runDeviceTests(PKG, CLASS, "testDensityBest2");
-    }
-
-    /**
-     * Verify that an API-based split can change enabled/disabled state of
-     * manifest elements.
-     */
-    public void testApi() throws Exception {
-        new InstallMultiple().addApk(APK).addApk(APK_v7).run();
-        runDeviceTests(PKG, CLASS, "testApi");
-    }
-
-    public void testLocale() throws Exception {
-        new InstallMultiple().addApk(APK).addApk(APK_de).addApk(APK_fr).run();
-        runDeviceTests(PKG, CLASS, "testLocale");
-    }
-
-    /**
-     * Install test app with <em>single</em> split that exactly matches the
-     * currently active ABI. This also explicitly forces ABI when installing.
-     */
-    public void testNativeSingle() throws Exception {
-        final String abi = mAbi.getName();
-        final String apk = ABI_TO_APK.get(abi);
-        assertNotNull("Failed to find APK for ABI " + abi, apk);
-
-        new InstallMultiple().addApk(APK).addApk(apk).run();
-        runDeviceTests(PKG, CLASS, "testNative");
-    }
-
-    /**
-     * Install test app with <em>single</em> split that exactly matches the
-     * currently active ABI. This variant <em>does not</em> force the ABI when
-     * installing, instead exercising the system's ability to choose the ABI
-     * through inspection of the installed app.
-     */
-    public void testNativeSingleNatural() throws Exception {
-        final String abi = mAbi.getName();
-        final String apk = ABI_TO_APK.get(abi);
-        assertNotNull("Failed to find APK for ABI " + abi, apk);
-
-        new InstallMultiple().useNaturalAbi().addApk(APK).addApk(apk).run();
-        runDeviceTests(PKG, CLASS, "testNative");
-    }
-
-    /**
-     * Install test app with <em>all</em> possible ABI splits. This also
-     * explicitly forces ABI when installing.
-     */
-    public void testNativeAll() throws Exception {
-        final InstallMultiple inst = new InstallMultiple().addApk(APK);
-        for (String apk : ABI_TO_APK.values()) {
-            inst.addApk(apk);
-        }
-        inst.run();
-        runDeviceTests(PKG, CLASS, "testNative");
-    }
-
-    /**
-     * Install test app with <em>all</em> possible ABI splits. This variant
-     * <em>does not</em> force the ABI when installing, instead exercising the
-     * system's ability to choose the ABI through inspection of the installed
-     * app.
-     */
-    public void testNativeAllNatural() throws Exception {
-        final InstallMultiple inst = new InstallMultiple().useNaturalAbi().addApk(APK);
-        for (String apk : ABI_TO_APK.values()) {
-            inst.addApk(apk);
-        }
-        inst.run();
-        runDeviceTests(PKG, CLASS, "testNative");
-    }
-
-    public void testDuplicateBase() throws Exception {
-        new InstallMultiple().addApk(APK).addApk(APK).runExpectingFailure();
-    }
-
-    public void testDuplicateSplit() throws Exception {
-        new InstallMultiple().addApk(APK).addApk(APK_v7).addApk(APK_v7).runExpectingFailure();
-    }
-
-    public void testDiffCert() throws Exception {
-        new InstallMultiple().addApk(APK).addApk(APK_DIFF_CERT_v7).runExpectingFailure();
-    }
-
-    public void testDiffCertInherit() throws Exception {
-        new InstallMultiple().addApk(APK).run();
-        new InstallMultiple().inheritFrom(PKG).addApk(APK_DIFF_CERT_v7).runExpectingFailure();
-    }
-
-    public void testDiffVersion() throws Exception {
-        new InstallMultiple().addApk(APK).addApk(APK_DIFF_VERSION_v7).runExpectingFailure();
-    }
-
-    public void testDiffVersionInherit() throws Exception {
-        new InstallMultiple().addApk(APK).run();
-        new InstallMultiple().inheritFrom(PKG).addApk(APK_DIFF_VERSION_v7).runExpectingFailure();
-    }
-
-    public void testDiffRevision() throws Exception {
-        new InstallMultiple().addApk(APK).addApk(APK_DIFF_REVISION_v7).run();
-        runDeviceTests(PKG, CLASS, "testRevision0_12");
-    }
-
-    public void testDiffRevisionInheritBase() throws Exception {
-        new InstallMultiple().addApk(APK).addApk(APK_v7).run();
-        runDeviceTests(PKG, CLASS, "testRevision0_0");
-        new InstallMultiple().inheritFrom(PKG).addApk(APK_DIFF_REVISION_v7).run();
-        runDeviceTests(PKG, CLASS, "testRevision0_12");
-    }
-
-    public void testDiffRevisionInheritSplit() throws Exception {
-        new InstallMultiple().addApk(APK).addApk(APK_v7).run();
-        runDeviceTests(PKG, CLASS, "testRevision0_0");
-        new InstallMultiple().inheritFrom(PKG).addApk(APK_DIFF_REVISION).run();
-        runDeviceTests(PKG, CLASS, "testRevision12_0");
-    }
-
-    public void testDiffRevisionDowngrade() throws Exception {
-        new InstallMultiple().addApk(APK).addApk(APK_DIFF_REVISION_v7).run();
-        new InstallMultiple().inheritFrom(PKG).addApk(APK_v7).runExpectingFailure();
-    }
-
-    public void testFeatureBase() throws Exception {
-        new InstallMultiple().addApk(APK).addApk(APK_FEATURE).run();
-        runDeviceTests(PKG, CLASS, "testFeatureBase");
-    }
-
-    public void testFeatureApi() throws Exception {
-        new InstallMultiple().addApk(APK).addApk(APK_FEATURE).addApk(APK_FEATURE_v7).run();
-        runDeviceTests(PKG, CLASS, "testFeatureApi");
-    }
-
-    public void testInheritUpdatedBase() throws Exception {
-        // TODO: flesh out this test
-    }
-
-    public void testInheritUpdatedSplit() throws Exception {
-        // TODO: flesh out this test
-    }
-
-    /**
-     * Verify that installing a new version of app wipes code cache.
-     */
-    public void testClearCodeCache() throws Exception {
-        new InstallMultiple().addApk(APK).run();
-        runDeviceTests(PKG, CLASS, "testCodeCacheWrite");
-        new InstallMultiple().addArg("-r").addApk(APK_DIFF_VERSION).run();
-        runDeviceTests(PKG, CLASS, "testCodeCacheRead");
-    }
-
-    private class InstallMultiple extends BaseInstallMultiple<InstallMultiple> {
-        public InstallMultiple() {
-            super(getDevice(), mCtsBuild, mAbi);
-        }
-    }
-
-    public static class BaseInstallMultiple<T extends BaseInstallMultiple<?>> {
-        private final ITestDevice mDevice;
-        private final CtsBuildHelper mBuild;
-        private final IAbi mAbi;
-
-        private final List<String> mArgs = new ArrayList<>();
-        private final List<File> mApks = new ArrayList<>();
-        private boolean mUseNaturalAbi;
-
-        public BaseInstallMultiple(ITestDevice device, CtsBuildHelper build, IAbi abi) {
-            mDevice = device;
-            mBuild = build;
-            mAbi = abi;
-            addArg("-g");
-        }
-
-        T addArg(String arg) {
-            mArgs.add(arg);
-            return (T) this;
-        }
-
-        T addApk(String apk) throws FileNotFoundException {
-            mApks.add(mBuild.getTestApp(apk));
-            return (T) this;
-        }
-
-        T inheritFrom(String packageName) {
-            addArg("-r");
-            addArg("-p " + packageName);
-            return (T) this;
-        }
-
-        T useNaturalAbi() {
-            mUseNaturalAbi = true;
-            return (T) this;
-        }
-
-        T locationAuto() {
-            addArg("--install-location 0");
-            return (T) this;
-        }
-
-        T locationInternalOnly() {
-            addArg("--install-location 1");
-            return (T) this;
-        }
-
-        T locationPreferExternal() {
-            addArg("--install-location 2");
-            return (T) this;
-        }
-
-        T forceUuid(String uuid) {
-            addArg("--force-uuid " + uuid);
-            return (T) this;
-        }
-
-        void run() throws DeviceNotAvailableException {
-            run(true);
-        }
-
-        void runExpectingFailure() throws DeviceNotAvailableException {
-            run(false);
-        }
-
-        private void run(boolean expectingSuccess) throws DeviceNotAvailableException {
-            final ITestDevice device = mDevice;
-
-            // Create an install session
-            final StringBuilder cmd = new StringBuilder();
-            cmd.append("pm install-create");
-            for (String arg : mArgs) {
-                cmd.append(' ').append(arg);
-            }
-            if (!mUseNaturalAbi) {
-                cmd.append(' ').append(AbiUtils.createAbiFlag(mAbi.getName()));
-            }
-
-            String result = device.executeShellCommand(cmd.toString());
-            assertTrue(result, result.startsWith("Success"));
-
-            final int start = result.lastIndexOf("[");
-            final int end = result.lastIndexOf("]");
-            int sessionId = -1;
-            try {
-                if (start != -1 && end != -1 && start < end) {
-                    sessionId = Integer.parseInt(result.substring(start + 1, end));
-                }
-            } catch (NumberFormatException e) {
-            }
-            if (sessionId == -1) {
-                throw new IllegalStateException("Failed to create install session: " + result);
-            }
-
-            // Push our files into session. Ideally we'd use stdin streaming,
-            // but ddmlib doesn't support it yet.
-            for (int i = 0; i < mApks.size(); i++) {
-                final File apk = mApks.get(i);
-                final String remotePath = "/data/local/tmp/" + i + "_" + apk.getName();
-                if (!device.pushFile(apk, remotePath)) {
-                    throw new IllegalStateException("Failed to push " + apk);
-                }
-
-                cmd.setLength(0);
-                cmd.append("pm install-write");
-                cmd.append(' ').append(sessionId);
-                cmd.append(' ').append(i + "_" + apk.getName());
-                cmd.append(' ').append(remotePath);
-
-                result = device.executeShellCommand(cmd.toString());
-                assertTrue(result, result.startsWith("Success"));
-            }
-
-            // Everything staged; let's pull trigger
-            cmd.setLength(0);
-            cmd.append("pm install-commit");
-            cmd.append(' ').append(sessionId);
-
-            result = device.executeShellCommand(cmd.toString());
-            if (expectingSuccess) {
-                assertTrue(result, result.startsWith("Success"));
-            } else {
-                assertFalse(result, result.startsWith("Success"));
-            }
-        }
-    }
-
-    public void runDeviceTests(String packageName, String testClassName, String testMethodName)
-            throws DeviceNotAvailableException {
-        Utils.runDeviceTests(getDevice(), packageName, testClassName, testMethodName);
-    }
-}
diff --git a/hostsidetests/appsecurity/src/com/android/cts/appsecurity/Utils.java b/hostsidetests/appsecurity/src/com/android/cts/appsecurity/Utils.java
deleted file mode 100644
index fdf84d3..0000000
--- a/hostsidetests/appsecurity/src/com/android/cts/appsecurity/Utils.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.appsecurity;
-
-import com.android.ddmlib.Log;
-import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
-import com.android.ddmlib.testrunner.TestIdentifier;
-import com.android.ddmlib.testrunner.TestResult;
-import com.android.ddmlib.testrunner.TestResult.TestStatus;
-import com.android.ddmlib.testrunner.TestRunResult;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.result.CollectingTestListener;
-
-import java.util.Map;
-
-public class Utils {
-    private static final String TAG = "AppSecurity";
-
-    public static final int USER_OWNER = 0;
-
-    public static void runDeviceTests(ITestDevice device, String packageName)
-            throws DeviceNotAvailableException {
-        runDeviceTests(device, packageName, null, null, USER_OWNER);
-    }
-
-    public static void runDeviceTests(ITestDevice device, String packageName, int userId)
-            throws DeviceNotAvailableException {
-        runDeviceTests(device, packageName, null, null, userId);
-    }
-
-    public static void runDeviceTests(ITestDevice device, String packageName, String testClassName)
-            throws DeviceNotAvailableException {
-        runDeviceTests(device, packageName, testClassName, null, USER_OWNER);
-    }
-
-    public static void runDeviceTests(ITestDevice device, String packageName, String testClassName,
-            int userId) throws DeviceNotAvailableException {
-        runDeviceTests(device, packageName, testClassName, null, userId);
-    }
-
-    public static void runDeviceTests(ITestDevice device, String packageName, String testClassName,
-            String testMethodName) throws DeviceNotAvailableException {
-        runDeviceTests(device, packageName, testClassName, testMethodName, USER_OWNER);
-    }
-
-    public static void runDeviceTests(ITestDevice device, String packageName, String testClassName,
-            String testMethodName, int userId) throws DeviceNotAvailableException {
-        if (testClassName != null && testClassName.startsWith(".")) {
-            testClassName = packageName + testClassName;
-        }
-
-        RemoteAndroidTestRunner testRunner = new RemoteAndroidTestRunner(packageName,
-                "android.support.test.runner.AndroidJUnitRunner", device.getIDevice());
-        if (testClassName != null && testMethodName != null) {
-            testRunner.setMethodName(testClassName, testMethodName);
-        } else if (testClassName != null) {
-            testRunner.setClassName(testClassName);
-        }
-
-        if (userId != USER_OWNER) {
-            // TODO: move this to RemoteAndroidTestRunner once it supports users
-            testRunner.addInstrumentationArg("hack_key", "hack_value --user " + userId);
-        }
-
-        final CollectingTestListener listener = new CollectingTestListener();
-        device.runInstrumentationTests(testRunner, listener);
-
-        final TestRunResult result = listener.getCurrentRunResults();
-        if (result.isRunFailure()) {
-            throw new AssertionError("Failed to successfully run device tests for "
-                    + result.getName() + ": " + result.getRunFailureMessage());
-        }
-
-        if (result.hasFailedTests()) {
-            // build a meaningful error message
-            StringBuilder errorBuilder = new StringBuilder("on-device tests failed:\n");
-            for (Map.Entry<TestIdentifier, TestResult> resultEntry :
-                result.getTestResults().entrySet()) {
-                if (!resultEntry.getValue().getStatus().equals(TestStatus.PASSED)) {
-                    errorBuilder.append(resultEntry.getKey().toString());
-                    errorBuilder.append(":\n");
-                    errorBuilder.append(resultEntry.getValue().getStackTrace());
-                }
-            }
-            throw new AssertionError(errorBuilder.toString());
-        }
-    }
-
-    private static boolean isMultiUserSupportedOnDevice(ITestDevice device)
-            throws DeviceNotAvailableException {
-        // TODO: move this to ITestDevice once it supports users
-        final String output = device.executeShellCommand("pm get-max-users");
-        try {
-            return Integer.parseInt(output.substring(output.lastIndexOf(" ")).trim()) > 1;
-        } catch (NumberFormatException e) {
-            throw new AssertionError("Failed to parse result: " + output);
-        }
-    }
-
-    /**
-     * Return set of users that test should be run for, creating a secondary
-     * user if the device supports it. Always call
-     * {@link #removeUsersForTest(ITestDevice, int[])} when finished.
-     */
-    public static int[] createUsersForTest(ITestDevice device) throws DeviceNotAvailableException {
-        if (isMultiUserSupportedOnDevice(device)) {
-            return new int[] { USER_OWNER, createUserOnDevice(device) };
-        } else {
-            Log.d(TAG, "Single user device; skipping isolated storage tests");
-            return new int[] { USER_OWNER };
-        }
-    }
-
-    public static void removeUsersForTest(ITestDevice device, int[] users)
-            throws DeviceNotAvailableException {
-        for (int user : users) {
-            if (user != USER_OWNER) {
-                removeUserOnDevice(device, user);
-            }
-        }
-    }
-
-    private static int createUserOnDevice(ITestDevice device) throws DeviceNotAvailableException {
-        // TODO: move this to ITestDevice once it supports users
-        final String name = "CTS_" + System.currentTimeMillis();
-        final String output = device.executeShellCommand("pm create-user " + name);
-        if (output.startsWith("Success")) {
-            try {
-                final int userId = Integer.parseInt(
-                        output.substring(output.lastIndexOf(" ")).trim());
-                device.executeShellCommand("am start-user " + userId);
-                return userId;
-            } catch (NumberFormatException e) {
-                throw new AssertionError("Failed to parse result: " + output);
-            }
-        } else {
-            throw new AssertionError("Failed to create user: " + output);
-        }
-    }
-
-    private static void removeUserOnDevice(ITestDevice device, int userId)
-            throws DeviceNotAvailableException {
-        // TODO: move this to ITestDevice once it supports users
-        final String output = device.executeShellCommand("pm remove-user " + userId);
-        if (output.startsWith("Error")) {
-            throw new AssertionError("Failed to remove user: " + output);
-        }
-    }
-
-}
diff --git a/hostsidetests/appsecurity/test-apps/Android.mk b/hostsidetests/appsecurity/test-apps/Android.mk
index f6091e4..1d4e58f 100644
--- a/hostsidetests/appsecurity/test-apps/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/Android.mk
@@ -16,6 +16,9 @@
 
 include $(CLEAR_VARS)
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 # Build the test APKs using their own makefiles
 include $(call all-makefiles-under,$(LOCAL_PATH))
 
diff --git a/hostsidetests/appsecurity/test-apps/AppAccessData/Android.mk b/hostsidetests/appsecurity/test-apps/AppAccessData/Android.mk
index 4459e69..606b9ce 100644
--- a/hostsidetests/appsecurity/test-apps/AppAccessData/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/AppAccessData/Android.mk
@@ -25,6 +25,9 @@
 
 LOCAL_PACKAGE_NAME := CtsAppAccessData
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 # although not strictly necessary, sign this app with different cert than CtsAppWithData
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey2
 
diff --git a/hostsidetests/appsecurity/test-apps/AppAccessData/src/com/android/cts/appaccessdata/AccessPrivateDataTest.java b/hostsidetests/appsecurity/test-apps/AppAccessData/src/com/android/cts/appaccessdata/AccessPrivateDataTest.java
index 40d3cff..e7565d4 100644
--- a/hostsidetests/appsecurity/test-apps/AppAccessData/src/com/android/cts/appaccessdata/AccessPrivateDataTest.java
+++ b/hostsidetests/appsecurity/test-apps/AppAccessData/src/com/android/cts/appaccessdata/AccessPrivateDataTest.java
@@ -17,18 +17,21 @@
 package com.android.cts.appaccessdata;
 
 import java.io.BufferedReader;
-import java.io.DataInputStream;
+import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.FileReader;
 import java.io.IOException;
 
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
 import android.test.AndroidTestCase;
 
 /**
  * Test that another app's private data cannot be accessed, while its public data can.
  *
- * Assumes that {@link APP_WITH_DATA_PKG} has already created the private and public data.
+ * Assumes that {@link #APP_WITH_DATA_PKG} has already created the private and public data.
  */
 public class AccessPrivateDataTest extends AndroidTestCase {
 
@@ -39,12 +42,12 @@
 
     /**
      * Name of private file to access. This must match the name of the file created by
-     * {@link APP_WITH_DATA_PKG}.
+     * {@link #APP_WITH_DATA_PKG}.
      */
     private static final String PRIVATE_FILE_NAME = "private_file.txt";
     /**
      * Name of public file to access. This must match the name of the file created by
-     * {@link APP_WITH_DATA_PKG}.
+     * {@link #APP_WITH_DATA_PKG}.
      */
     private static final String PUBLIC_FILE_NAME = "public_file.txt";
 
@@ -56,54 +59,53 @@
     public void testAccessPrivateData() throws IOException {
         try {
             // construct the absolute file path to the app's private file
-            String privateFilePath = String.format("/data/data/%s/%s", APP_WITH_DATA_PKG,
-                    PRIVATE_FILE_NAME);
-            FileInputStream inputStream = new FileInputStream(privateFilePath);
+            ApplicationInfo applicationInfo = getApplicationInfo(APP_WITH_DATA_PKG);
+            File privateFile = new File(applicationInfo.dataDir, "files/" + PRIVATE_FILE_NAME);
+            FileInputStream inputStream = new FileInputStream(privateFile);
             inputStream.read();
             inputStream.close();
             fail("Was able to access another app's private data");
-        } catch (FileNotFoundException e) {
+        } catch (FileNotFoundException | SecurityException e) {
             // expected
-        } catch (SecurityException e) {
-            // also valid
         }
         accessPrivateTrafficStats();
     }
 
+    private ApplicationInfo getApplicationInfo(String packageName) {
+        try {
+            return mContext.getPackageManager().getApplicationInfo(packageName, 0);
+        } catch (PackageManager.NameNotFoundException e) {
+            throw new IllegalStateException("Expected package not found: " + e);
+        }
+    }
+
     /**
      * Tests that another app's public file can be accessed
      * @throws IOException
      */
     public void testAccessPublicData() throws IOException {
         try {
-            getOtherAppUid();
-        } catch (FileNotFoundException e) {
-            fail("Was not able to access another app's public file: " + e);
-        } catch (SecurityException e) {
-            fail("Was not able to access another app's public file: " + e);
+            // construct the absolute file path to the other app's public file
+            ApplicationInfo applicationInfo = getApplicationInfo(APP_WITH_DATA_PKG);
+            File publicFile = new File(applicationInfo.dataDir, "files/" + PUBLIC_FILE_NAME);
+            FileInputStream inputStream = new FileInputStream(publicFile);
+            inputStream.read();
+            inputStream.close();
+            fail("Was able to access another app's public file");
+        } catch (FileNotFoundException | SecurityException e) {
+            // expected
         }
     }
 
-    private int getOtherAppUid() throws IOException, FileNotFoundException, SecurityException {
-        // construct the absolute file path to the other app's public file
-        String publicFilePath = String.format("/data/data/%s/files/%s", APP_WITH_DATA_PKG,
-                PUBLIC_FILE_NAME);
-        DataInputStream inputStream = new DataInputStream(new FileInputStream(publicFilePath));
-        int otherAppUid = (int)inputStream.readInt();
-        inputStream.close();
-        return otherAppUid;
-    }
-
     private void accessPrivateTrafficStats() throws IOException {
         int otherAppUid = -1;
         try {
-            otherAppUid = getOtherAppUid();
-        } catch (FileNotFoundException e) {
-            fail("Was not able to access another app's public file: " + e);
-        } catch (SecurityException e) {
-            fail("Was not able to access another app's public file: " + e);
+            otherAppUid = getContext()
+                    .createPackageContext(APP_WITH_DATA_PKG, 0 /*flags*/)
+                    .getApplicationInfo().uid;
+        } catch (NameNotFoundException e) {
+            fail("Was not able to find other app");
         }
-
         boolean foundOtherStats = false;
         try {
             BufferedReader qtaguidReader = new BufferedReader(new FileReader("/proc/net/xt_qtaguid/stats"));
diff --git a/hostsidetests/appsecurity/test-apps/AppWithData/Android.mk b/hostsidetests/appsecurity/test-apps/AppWithData/Android.mk
index 0916254..1109280 100644
--- a/hostsidetests/appsecurity/test-apps/AppWithData/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/AppWithData/Android.mk
@@ -25,6 +25,9 @@
 
 LOCAL_PACKAGE_NAME := CtsAppWithData
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey1
 
 LOCAL_DEX_PREOPT := false
diff --git a/hostsidetests/appsecurity/test-apps/AppWithData/src/com/android/cts/appwithdata/CreatePrivateDataTest.java b/hostsidetests/appsecurity/test-apps/AppWithData/src/com/android/cts/appwithdata/CreatePrivateDataTest.java
index e11681a..f3787e8 100644
--- a/hostsidetests/appsecurity/test-apps/AppWithData/src/com/android/cts/appwithdata/CreatePrivateDataTest.java
+++ b/hostsidetests/appsecurity/test-apps/AppWithData/src/com/android/cts/appwithdata/CreatePrivateDataTest.java
@@ -24,8 +24,8 @@
 import android.database.sqlite.SQLiteOpenHelper;
 import android.net.TrafficStats;
 import android.test.AndroidTestCase;
-import android.util.Log;
 
+import java.io.File;
 import java.net.ServerSocket;
 import java.net.Socket;
 
@@ -79,8 +79,7 @@
         outputStream.close();
         assertTrue(getContext().getFileStreamPath(PRIVATE_FILE_NAME).exists());
 
-        outputStream = getContext().openFileOutput(PUBLIC_FILE_NAME,
-                Context.MODE_WORLD_READABLE);
+        outputStream = getContext().openFileOutput(PUBLIC_FILE_NAME, 0 /*mode*/);
         DataOutputStream dataOut = new DataOutputStream(outputStream);
         dataOut.writeInt(getContext().getApplicationInfo().uid);
         dataOut.close();
@@ -97,14 +96,11 @@
         try {
             // construct the absolute file path to the app's public's file the same
             // way as the appaccessdata package will.
-            String publicFilePath = String.format("/data/data/%s/files/%s", APP_WITH_DATA_PKG,
-                    PUBLIC_FILE_NAME);
-            DataInputStream inputStream = new DataInputStream(new FileInputStream(publicFilePath));
-            int otherAppUid = (int)inputStream.readInt();
+            File publicFile = new File(mContext.getFilesDir(), PUBLIC_FILE_NAME);
+            DataInputStream inputStream = new DataInputStream(new FileInputStream(publicFile));
+            inputStream.readInt();
             inputStream.close();
-        } catch (FileNotFoundException e) {
-            fail("Was not able to access own public file: " + e);
-        } catch (SecurityException e) {
+        } catch (FileNotFoundException | SecurityException e) {
             fail("Was not able to access own public file: " + e);
         }
     }
diff --git a/hostsidetests/appsecurity/test-apps/DocumentClient/Android.mk b/hostsidetests/appsecurity/test-apps/DocumentClient/Android.mk
index 272ef28..ce47e01 100644
--- a/hostsidetests/appsecurity/test-apps/DocumentClient/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/DocumentClient/Android.mk
@@ -26,6 +26,9 @@
 
 LOCAL_PACKAGE_NAME := CtsDocumentClient
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey2
 
 LOCAL_PROGUARD_ENABLED := disabled
diff --git a/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/DocumentsClientTest.java b/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/DocumentsClientTest.java
index f308211..acba1f4 100644
--- a/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/DocumentsClientTest.java
+++ b/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/DocumentsClientTest.java
@@ -18,63 +18,32 @@
 
 import android.content.ContentResolver;
 import android.content.Intent;
-import android.content.pm.PackageManager;
 import android.database.Cursor;
 import android.net.Uri;
 import android.os.SystemClock;
 import android.provider.DocumentsContract;
 import android.provider.DocumentsContract.Document;
 import android.provider.DocumentsProvider;
-import android.support.test.uiautomator.UiDevice;
 import android.support.test.uiautomator.UiObject;
 import android.support.test.uiautomator.UiObjectNotFoundException;
 import android.support.test.uiautomator.UiScrollable;
 import android.support.test.uiautomator.UiSelector;
-import android.test.InstrumentationTestCase;
 import android.test.MoreAsserts;
-import android.text.format.DateUtils;
 import android.util.Log;
 
 import com.android.cts.documentclient.MyActivity.Result;
 
-import java.io.ByteArrayOutputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
 /**
  * Tests for {@link DocumentsProvider} and interaction with platform intents
  * like {@link Intent#ACTION_OPEN_DOCUMENT}.
  */
-public class DocumentsClientTest extends InstrumentationTestCase {
+public class DocumentsClientTest extends DocumentsClientTestCase {
     private static final String TAG = "DocumentsClientTest";
 
-    private UiDevice mDevice;
-    private MyActivity mActivity;
-
-    private static final long TIMEOUT = 30 * DateUtils.SECOND_IN_MILLIS;
-
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-
-        mDevice = UiDevice.getInstance(getInstrumentation());
-        mActivity = launchActivity(getInstrumentation().getTargetContext().getPackageName(),
-                MyActivity.class, null);
-        mDevice.waitForIdle();
-    }
-
-    @Override
-    public void tearDown() throws Exception {
-        super.tearDown();
-        mActivity.finish();
-    }
-
     private UiObject findRoot(String label) throws UiObjectNotFoundException {
         final UiSelector rootsList = new UiSelector().resourceId(
                 "com.android.documentsui:id/container_roots").childSelector(
-                new UiSelector().resourceId("android:id/list"));
+                new UiSelector().resourceId("com.android.documentsui:id/roots_list"));
 
         // We might need to expand drawer if not visible
         if (!new UiObject(rootsList).waitForExists(TIMEOUT)) {
@@ -97,7 +66,7 @@
     private UiObject findDocument(String label) throws UiObjectNotFoundException {
         final UiSelector docList = new UiSelector().resourceId(
                 "com.android.documentsui:id/container_directory").childSelector(
-                new UiSelector().resourceId("com.android.documentsui:id/list"));
+                new UiSelector().resourceId("com.android.documentsui:id/dir_list"));
 
         // Wait for the first list item to appear
         assertTrue("First list item",
@@ -126,7 +95,7 @@
         final Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
         intent.addCategory(Intent.CATEGORY_OPENABLE);
         intent.setType("*/*");
-        mActivity.startActivityForResult(intent, 42);
+        mActivity.startActivityForResult(intent, REQUEST_CODE);
 
         // Ensure that we see both of our roots
         mDevice.waitForIdle();
@@ -134,15 +103,24 @@
         assertTrue("CtsCreate root", findRoot("CtsCreate").exists());
         assertFalse("CtsGetContent root", findRoot("CtsGetContent").exists());
 
-        // Pick a specific file from our test provider
+        // Choose the local root.
         mDevice.waitForIdle();
         findRoot("CtsLocal").click();
 
+        // Try picking a virtual file. Virtual files must not be returned for CATEGORY_OPENABLE
+        // though, so the click should be ignored.
+        mDevice.waitForIdle();
+        findDocument("VIRTUAL_FILE").click();
+        mDevice.waitForIdle();
+
+        // Pick a regular file.
         mDevice.waitForIdle();
         findDocument("FILE1").click();
 
+        // Confirm that the returned file is a regular file caused by the second click.
         final Result result = mActivity.getResult();
         final Uri uri = result.data.getData();
+        assertEquals("doc:file1", DocumentsContract.getDocumentId(uri));
 
         // We should now have permission to read/write
         MoreAsserts.assertEquals("fileone".getBytes(), readFully(uri));
@@ -152,6 +130,43 @@
         MoreAsserts.assertEquals("replaced!".getBytes(), readFully(uri));
     }
 
+    public void testOpenVirtual() throws Exception {
+        if (!supportedHardware()) return;
+
+        final Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
+        intent.setType("*/*");
+        mActivity.startActivityForResult(intent, REQUEST_CODE);
+
+        // Pick a virtual file from the local root.
+        mDevice.waitForIdle();
+        findRoot("CtsLocal").click();
+
+        mDevice.waitForIdle();
+        findDocument("VIRTUAL_FILE").click();
+
+        // Confirm that the returned file is actually the selected one.
+        final Result result = mActivity.getResult();
+        final Uri uri = result.data.getData();
+        assertEquals("doc:virtual-file", DocumentsContract.getDocumentId(uri));
+
+        final ContentResolver resolver = getInstrumentation().getContext().getContentResolver();
+        final String streamTypes[] = resolver.getStreamTypes(uri, "*/*");
+        assertEquals(1, streamTypes.length);
+        assertEquals("text/plain", streamTypes[0]);
+
+        // Virtual files are not readable unless an alternative MIME type is specified.
+        try {
+            readFully(uri);
+            fail("Unexpected success in reading a virtual file. It should've failed.");
+        } catch (IllegalArgumentException e) {
+            // Expected.
+        }
+
+        // However, they are readable using an alternative MIME type from getStreamTypes().
+        MoreAsserts.assertEquals(
+                "Converted contents.".getBytes(), readTypedFully(uri, streamTypes[0]));
+    }
+
     public void testCreateNew() throws Exception {
         if (!supportedHardware()) return;
 
@@ -162,7 +177,7 @@
         intent.addCategory(Intent.CATEGORY_OPENABLE);
         intent.putExtra(Intent.EXTRA_TITLE, DISPLAY_NAME);
         intent.setType(MIME_TYPE);
-        mActivity.startActivityForResult(intent, 42);
+        mActivity.startActivityForResult(intent, REQUEST_CODE);
 
         mDevice.waitForIdle();
         findRoot("CtsCreate").click();
@@ -186,7 +201,7 @@
         intent.addCategory(Intent.CATEGORY_OPENABLE);
         intent.putExtra(Intent.EXTRA_TITLE, "NEVERUSED");
         intent.setType("mime2/file2");
-        mActivity.startActivityForResult(intent, 42);
+        mActivity.startActivityForResult(intent, REQUEST_CODE);
 
         mDevice.waitForIdle();
         findRoot("CtsCreate").click();
@@ -211,7 +226,7 @@
         if (!supportedHardware()) return;
 
         final Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
-        mActivity.startActivityForResult(intent, 42);
+        mActivity.startActivityForResult(intent, REQUEST_CODE);
 
         mDevice.waitForIdle();
         findRoot("CtsCreate").click();
@@ -237,7 +252,7 @@
         Cursor cursor = resolver.query(children, new String[] {
                 Document.COLUMN_DISPLAY_NAME }, null, null, null);
         try {
-            assertEquals(1, cursor.getCount());
+            assertEquals(2, cursor.getCount());
             assertTrue(cursor.moveToFirst());
             assertEquals("FILE4", cursor.getString(0));
         } finally {
@@ -259,7 +274,7 @@
         try {
             MoreAsserts.assertEquals("filefour".getBytes(), readFully(file4));
             fail("Expected file to be gone");
-        } catch (FileNotFoundException expected) {
+        } catch (SecurityException expected) {
         }
 
         // And rename something
@@ -285,7 +300,7 @@
         final Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
         intent.addCategory(Intent.CATEGORY_OPENABLE);
         intent.setType("*/*");
-        mActivity.startActivityForResult(intent, 42);
+        mActivity.startActivityForResult(intent, REQUEST_CODE);
 
         // Look around, we should be able to see both DocumentsProviders and
         // other GET_CONTENT sources.
@@ -301,49 +316,116 @@
         assertEquals("ReSuLt", result.data.getAction());
     }
 
-    private String getColumn(Uri uri, String column) {
-        final ContentResolver resolver = getInstrumentation().getContext().getContentResolver();
-        final Cursor cursor = resolver.query(uri, new String[] { column }, null, null, null);
+    public void testTransferDocument() throws Exception {
+        if (!supportedHardware()) return;
+
         try {
+            // Opening without permission should fail.
+            readFully(Uri.parse("content://com.android.cts.documentprovider/document/doc:file1"));
+            fail("Able to read data before opened!");
+        } catch (SecurityException expected) {
+        }
+
+        final Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
+        mActivity.startActivityForResult(intent, REQUEST_CODE);
+
+        mDevice.waitForIdle();
+        findRoot("CtsCreate").click();
+
+        findDocument("DIR2").click();
+        mDevice.waitForIdle();
+        findSaveButton().click();
+
+        final Result result = mActivity.getResult();
+        final Uri uri = result.data.getData();
+
+        // We should have selected DIR2.
+        final Uri docUri = DocumentsContract.buildDocumentUriUsingTree(uri,
+                DocumentsContract.getTreeDocumentId(uri));
+
+        assertEquals("DIR2", getColumn(docUri, Document.COLUMN_DISPLAY_NAME));
+
+        final ContentResolver resolver = getInstrumentation().getContext().getContentResolver();
+        final Cursor cursor = resolver.query(
+                DocumentsContract.buildChildDocumentsUriUsingTree(
+                        docUri, DocumentsContract.getDocumentId(docUri)),
+                new String[] { Document.COLUMN_DOCUMENT_ID, Document.COLUMN_DISPLAY_NAME,
+                        Document.COLUMN_FLAGS },
+                null, null, null);
+
+        Uri sourceFileUri = null;
+        Uri targetDirUri = null;
+
+        try {
+            assertEquals(2, cursor.getCount());
             assertTrue(cursor.moveToFirst());
-            return cursor.getString(0);
+            sourceFileUri = DocumentsContract.buildDocumentUriUsingTree(
+                    docUri, cursor.getString(0));
+            assertEquals("FILE4", cursor.getString(1));
+            assertEquals(Document.FLAG_SUPPORTS_WRITE |
+                    Document.FLAG_SUPPORTS_COPY |
+                    Document.FLAG_SUPPORTS_MOVE |
+                    Document.FLAG_SUPPORTS_REMOVE, cursor.getInt(2));
+
+            assertTrue(cursor.moveToNext());
+            targetDirUri = DocumentsContract.buildDocumentUriUsingTree(
+                    docUri, cursor.getString(0));
+            assertEquals("SUB_DIR2", cursor.getString(1));
         } finally {
             cursor.close();
         }
-    }
 
-    private byte[] readFully(Uri uri) throws IOException {
-        InputStream in = getInstrumentation().getContext().getContentResolver()
-                .openInputStream(uri);
+        // Move, copy then remove.
+        final Uri movedFileUri = DocumentsContract.moveDocument(
+                resolver, sourceFileUri, docUri, targetDirUri);
+        assertTrue(movedFileUri != null);
+        final Uri copiedFileUri = DocumentsContract.copyDocument(
+                resolver, movedFileUri, targetDirUri);
+        assertTrue(copiedFileUri != null);
+
+        // Confirm that the files are at the destinations.
+        Cursor cursorDst = resolver.query(
+                DocumentsContract.buildChildDocumentsUriUsingTree(
+                        targetDirUri, DocumentsContract.getDocumentId(targetDirUri)),
+                new String[] { Document.COLUMN_DOCUMENT_ID },
+                null, null, null);
         try {
-            ByteArrayOutputStream bytes = new ByteArrayOutputStream();
-            byte[] buffer = new byte[1024];
-            int count;
-            while ((count = in.read(buffer)) != -1) {
-                bytes.write(buffer, 0, count);
-            }
-            return bytes.toByteArray();
+            assertEquals(2, cursorDst.getCount());
+            assertTrue(cursorDst.moveToFirst());
+            assertEquals("doc:file4", cursorDst.getString(0));
+            assertTrue(cursorDst.moveToNext());
+            assertEquals("doc:file4_copy", cursorDst.getString(0));
         } finally {
-            in.close();
+            cursorDst.close();
         }
-    }
 
-    private void writeFully(Uri uri, byte[] data) throws IOException {
-        OutputStream out = getInstrumentation().getContext().getContentResolver()
-                .openOutputStream(uri);
+        // ... and gone from the source.
+        final Cursor cursorSrc = resolver.query(
+                DocumentsContract.buildChildDocumentsUriUsingTree(
+                        docUri, DocumentsContract.getDocumentId(docUri)),
+                new String[] { Document.COLUMN_DOCUMENT_ID },
+                null, null, null);
         try {
-            out.write(data);
+            assertEquals(1, cursorSrc.getCount());
+            assertTrue(cursorSrc.moveToFirst());
+            assertEquals("doc:sub_dir2", cursorSrc.getString(0));
         } finally {
-            out.close();
+            cursorSrc.close();
         }
-    }
 
-    private boolean supportedHardware() {
-        final PackageManager pm = getInstrumentation().getContext().getPackageManager();
-        if (pm.hasSystemFeature("android.hardware.type.television")
-                || pm.hasSystemFeature("android.hardware.type.watch")) {
-            return false;
+        assertTrue(DocumentsContract.removeDocument(resolver, movedFileUri, targetDirUri));
+        assertTrue(DocumentsContract.removeDocument(resolver, copiedFileUri, targetDirUri));
+
+        // Finally, confirm that removing actually removed the files from the destination.
+        cursorDst = resolver.query(
+                DocumentsContract.buildChildDocumentsUriUsingTree(
+                        targetDirUri, DocumentsContract.getDocumentId(targetDirUri)),
+                new String[] { Document.COLUMN_DOCUMENT_ID },
+                null, null, null);
+        try {
+            assertEquals(0, cursorDst.getCount());
+        } finally {
+            cursorDst.close();
         }
-        return true;
     }
 }
diff --git a/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/DocumentsClientTestCase.java b/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/DocumentsClientTestCase.java
new file mode 100644
index 0000000..e52af73
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/DocumentsClientTestCase.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.documentclient;
+
+import static android.cts.util.SystemUtil.runShellCommand;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import com.android.cts.documentclient.MyActivity.Result;
+
+import android.app.Activity;
+import android.content.ContentResolver;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.res.AssetFileDescriptor;
+import android.content.res.AssetFileDescriptor.AutoCloseInputStream;
+import android.database.Cursor;
+import android.net.Uri;
+import android.support.test.uiautomator.Configurator;
+import android.support.test.uiautomator.UiDevice;
+import android.test.InstrumentationTestCase;
+import android.text.format.DateUtils;
+import android.util.Log;
+import android.view.MotionEvent;
+
+/**
+ * Base class for DocumentsUI test cases.
+ */
+abstract class DocumentsClientTestCase extends InstrumentationTestCase {
+    private static final String TAG = "DocumentsClientTestCase";
+
+    protected UiDevice mDevice;
+    protected MyActivity mActivity;
+
+    protected static final long TIMEOUT = 30 * DateUtils.SECOND_IN_MILLIS;
+    protected static final int REQUEST_CODE = 42;
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+
+        Configurator.getInstance().setToolType(MotionEvent.TOOL_TYPE_FINGER);
+
+        mDevice = UiDevice.getInstance(getInstrumentation());
+        mActivity = launchActivity(getInstrumentation().getTargetContext().getPackageName(),
+                MyActivity.class, null);
+        mDevice.waitForIdle();
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        super.tearDown();
+        mActivity.finish();
+    }
+
+    protected String getColumn(Uri uri, String column) {
+        final ContentResolver resolver = getInstrumentation().getContext().getContentResolver();
+        final Cursor cursor = resolver.query(uri, new String[] { column }, null, null, null);
+        try {
+            assertTrue(cursor.moveToFirst());
+            return cursor.getString(0);
+        } finally {
+            cursor.close();
+        }
+    }
+
+    protected byte[] readFully(Uri uri) throws IOException {
+        final InputStream in = getInstrumentation().getContext().getContentResolver()
+                .openInputStream(uri);
+        return readFully(in);
+    }
+
+    protected byte[] readTypedFully(Uri uri, String mimeType) throws IOException {
+        final AssetFileDescriptor descriptor =
+                getInstrumentation().getContext().getContentResolver()
+                        .openTypedAssetFileDescriptor(uri, mimeType, null, null);
+        try (AutoCloseInputStream in = new AutoCloseInputStream(descriptor)) {
+            return readFully(in);
+        }
+    }
+
+    protected byte[] readFully(InputStream in) throws IOException {
+        try {
+            ByteArrayOutputStream bytes = new ByteArrayOutputStream();
+            byte[] buffer = new byte[1024];
+            int count;
+            while ((count = in.read(buffer)) != -1) {
+                bytes.write(buffer, 0, count);
+            }
+            return bytes.toByteArray();
+        } finally {
+            in.close();
+        }
+    }
+
+    protected void writeFully(Uri uri, byte[] data) throws IOException {
+        OutputStream out = getInstrumentation().getContext().getContentResolver()
+                .openOutputStream(uri);
+        try {
+            out.write(data);
+        } finally {
+            out.close();
+        }
+    }
+
+    protected boolean supportedHardware() {
+        final PackageManager pm = getInstrumentation().getContext().getPackageManager();
+        if (pm.hasSystemFeature("android.hardware.type.television")
+                || pm.hasSystemFeature("android.hardware.type.watch")) {
+            return false;
+        }
+        return true;
+    }
+
+    protected void assertActivityFailed() {
+        final Result result = mActivity.getResult();
+        assertEquals(REQUEST_CODE, result.requestCode);
+        assertEquals(Activity.RESULT_CANCELED, result.resultCode);
+        assertNull(result.data);
+    }
+
+    protected Intent assertActivitySucceeded(String prefix) {
+        final Result result = mActivity.getResult();
+        assertEquals(prefix + ": invalid request code", REQUEST_CODE, result.requestCode);
+        assertEquals(prefix + ": invalid result code", Activity.RESULT_OK, result.resultCode);
+        assertNotNull(prefix + ": null data on result", result.data);
+        return result.data;
+    }
+
+    protected String executeShellCommand(String command) throws Exception {
+        final String result = runShellCommand(getInstrumentation(), command).trim();
+        Log.d(TAG, "Command '" + command + "' returned '" + result + "'");
+        return result;
+    }
+
+    protected void clearDocumentsUi() throws Exception {
+        executeShellCommand("pm clear com.android.documentsui");
+    }
+}
diff --git a/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/MyActivity.java b/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/MyActivity.java
index a6cb28d..7033ae8 100644
--- a/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/MyActivity.java
+++ b/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/MyActivity.java
@@ -28,10 +28,12 @@
     private final SynchronousQueue<Result> mResult = new SynchronousQueue<>();
 
     public static class Result {
+        public final int requestCode;
         public final int resultCode;
         public final Intent data;
 
-        public Result(int resultCode, Intent data) {
+        public Result(int requestCode, int resultCode, Intent data) {
+            this.requestCode = requestCode;
             this.resultCode = resultCode;
             this.data = data;
         }
@@ -49,17 +51,22 @@
     @Override
     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
         try {
-            mResult.offer(new Result(resultCode, data), 5, TimeUnit.SECONDS);
+            mResult.offer(new Result(requestCode, resultCode, data), 5, TimeUnit.SECONDS);
         } catch (InterruptedException e) {
             throw new RuntimeException(e);
         }
     }
 
     public Result getResult() {
+        final Result result;
         try {
-            return mResult.take();
+            result = mResult.poll(30, TimeUnit.SECONDS);
         } catch (InterruptedException e) {
             throw new RuntimeException(e);
         }
+        if (result == null) {
+            throw new IllegalStateException("Activity didn't receive a Result in 30 seconds");
+        }
+        return result;
     }
 }
diff --git a/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/ScopedDirectoryAccessClientTest.java b/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/ScopedDirectoryAccessClientTest.java
new file mode 100644
index 0000000..a4d35fb
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/ScopedDirectoryAccessClientTest.java
@@ -0,0 +1,381 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.documentclient;
+
+import static android.os.Environment.DIRECTORY_ALARMS;
+import static android.os.Environment.DIRECTORY_DCIM;
+import static android.os.Environment.DIRECTORY_DOCUMENTS;
+import static android.os.Environment.DIRECTORY_DOWNLOADS;
+import static android.os.Environment.DIRECTORY_MOVIES;
+import static android.os.Environment.DIRECTORY_MUSIC;
+import static android.os.Environment.DIRECTORY_NOTIFICATIONS;
+import static android.os.Environment.DIRECTORY_PICTURES;
+import static android.os.Environment.DIRECTORY_PODCASTS;
+import static android.os.Environment.DIRECTORY_RINGTONES;
+import static android.test.MoreAsserts.assertContainsRegex;
+import static android.test.MoreAsserts.assertNotContainsRegex;
+import static android.test.MoreAsserts.assertNotEqual;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.storage.StorageManager;
+import android.os.storage.StorageVolume;
+import android.provider.DocumentsContract;
+import android.provider.DocumentsContract.Document;
+import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.UiObject;
+import android.support.test.uiautomator.UiObjectNotFoundException;
+import android.support.test.uiautomator.UiSelector;
+import android.support.test.uiautomator.Until;
+import android.util.Log;
+
+import java.util.List;
+
+/**
+ * Set of tests that verify behavior of the Scoped Directory Access API.
+ */
+public class ScopedDirectoryAccessClientTest extends DocumentsClientTestCase {
+    private static final String TAG = "ScopedDirectoryAccessClientTest";
+
+    private static final String DIRECTORY_ROOT = null;
+
+    private static final String[] STANDARD_DIRECTORIES = {
+        DIRECTORY_MUSIC,
+        DIRECTORY_PODCASTS,
+        DIRECTORY_RINGTONES,
+        DIRECTORY_ALARMS,
+        DIRECTORY_NOTIFICATIONS,
+        DIRECTORY_PICTURES,
+        DIRECTORY_MOVIES,
+        DIRECTORY_DOWNLOADS,
+        DIRECTORY_DCIM,
+        DIRECTORY_DOCUMENTS
+    };
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+
+        // DocumentsUI caches some info like whether a user rejects a request, so we need to clear
+        // its data before each test.
+        clearDocumentsUi();
+    }
+
+    public void testInvalidPath() throws Exception {
+        if (!supportedHardware()) return;
+
+        for (StorageVolume volume : getVolumes()) {
+            openExternalDirectoryInvalidPath(volume, "");
+            openExternalDirectoryInvalidPath(volume, "/dev/null");
+            openExternalDirectoryInvalidPath(volume, "/../");
+            openExternalDirectoryInvalidPath(volume, "/HiddenStuff");
+        }
+        openExternalDirectoryInvalidPath(getPrimaryVolume(), DIRECTORY_ROOT);
+    }
+
+    public void testUserRejects() throws Exception {
+        if (!supportedHardware()) return;
+
+        for (StorageVolume volume : getVolumes()) {
+            // Tests user clicking DENY button, for all valid directories.
+            for (String dir : STANDARD_DIRECTORIES) {
+                userRejectsTest(volume, dir);
+            }
+            if (!volume.isPrimary()) {
+                // Also test root
+                userRejectsTest(volume, DIRECTORY_ROOT);
+            }
+            // Also test user clicking back button - one directory is enough.
+            openExternalDirectoryValidPath(volume, DIRECTORY_PICTURES);
+            mDevice.pressBack();
+            assertActivityFailed();
+        }
+    }
+
+    private void userRejectsTest(StorageVolume volume, String dir) throws Exception {
+        final UiAlertDialog dialog = openExternalDirectoryValidPath(volume, dir);
+        dialog.noButton.click();
+        assertActivityFailed();
+    }
+
+    public void testUserAccepts() throws Exception {
+        if (!supportedHardware()) return;
+
+        for (StorageVolume volume : getVolumes()) {
+            userAcceptsOpenExternalDirectoryTest(volume, DIRECTORY_PICTURES);
+            if (!volume.isPrimary()) {
+                userAcceptsOpenExternalDirectoryTest(volume, DIRECTORY_ROOT);
+            }
+        }
+    }
+
+    public void testUserAcceptsNewDirectory() throws Exception {
+        if (!supportedHardware()) return;
+
+        // TODO: figure out a better way to remove the directory.
+        final String command = "rm -rf /sdcard/" + DIRECTORY_PICTURES;
+        final String output = executeShellCommand(command);
+        if (!output.isEmpty()) {
+            fail("Command '" + command + "' failed: '" + output + "'");
+        }
+        userAcceptsOpenExternalDirectoryTest(getPrimaryVolume(), DIRECTORY_PICTURES);
+    }
+
+    public void testNotAskedAgain() throws Exception {
+        if (!supportedHardware()) return;
+
+        for (StorageVolume volume : getVolumes()) {
+            final String volumeDesc = volume.getDescription(getInstrumentation().getContext());
+            final Uri grantedUri = userAcceptsOpenExternalDirectoryTest(volume, DIRECTORY_PICTURES);
+
+            // Calls it again - since the permission has been granted, it should return right
+            // away, without popping up the permissions dialog.
+            sendOpenExternalDirectoryIntent(volume, DIRECTORY_PICTURES);
+            final Intent newData = assertActivitySucceeded("should have already granted "
+                    + "permission to " + volumeDesc + " and " + DIRECTORY_PICTURES);
+            assertEquals(grantedUri, newData.getData());
+
+            // Make sure other directories still require user permission.
+            final Uri grantedUri2 = userAcceptsOpenExternalDirectoryTest(volume, DIRECTORY_ALARMS);
+            assertNotEqual(grantedUri, grantedUri2);
+        }
+    }
+
+    public void testNotAskedAgainOnRoot() throws Exception {
+        if (!supportedHardware()) return;
+
+        for (StorageVolume volume : getVolumes()) {
+            if (volume.isPrimary()) continue;
+            final String volumeDesc = volume.getDescription(getInstrumentation().getContext());
+            final Uri grantedRootUri = userAcceptsOpenExternalDirectoryTest(volume, DIRECTORY_ROOT);
+
+            // Calls it again - since the permission has been granted, it should return right
+            // away, without popping up the permissions dialog.
+            sendOpenExternalDirectoryIntent(volume, DIRECTORY_ROOT);
+            final Intent rootData = assertActivitySucceeded("should have already granted "
+                    + "permission to " + volumeDesc + " and root dir");
+            assertEquals(grantedRootUri, rootData.getData());
+
+            // Make sure other directories don't permission neither.
+            for (String dir : STANDARD_DIRECTORIES) {
+                sendOpenExternalDirectoryIntent(volume, dir);
+                final Intent childData = assertActivitySucceeded("should have already granted "
+                        + "permission to " + volumeDesc + " and " + dir);
+                assertNotNull(childData);
+                final Uri grantedChildUri = childData.getData();
+                assertFalse("received root URI (" + grantedRootUri + ") for child request",
+                        grantedRootUri.equals(grantedChildUri));
+            }
+        }
+    }
+
+    public void testDeniesOnceButAllowsAskingAgain() throws Exception {
+        if (!supportedHardware())return;
+
+        final String[] dirs = { DIRECTORY_DCIM, DIRECTORY_ROOT };
+        for (StorageVolume volume : getVolumes()) {
+            for (String dir : dirs) {
+                if (volume.isPrimary() && dir == DIRECTORY_ROOT) continue;
+                // Rejects the first attempt...
+                UiAlertDialog dialog = openExternalDirectoryValidPath(volume, dir);
+                dialog.assertDoNotAskAgainVisibility(false);
+                dialog.noButton.click();
+                assertActivityFailed();
+
+                // ...and the second.
+                dialog = openExternalDirectoryValidPath(volume, dir);
+                dialog.assertDoNotAskAgainVisibility(true);
+                dialog.noButton.click();
+                assertActivityFailed();
+
+                // Third time is a charm...
+                userAcceptsOpenExternalDirectoryTest(volume, dir);
+            }
+        }
+    }
+
+    public void testDeniesOnceForAll() throws Exception {
+        if (!supportedHardware()) return;
+
+        final String[] dirs = {DIRECTORY_PICTURES, DIRECTORY_ROOT};
+        for (StorageVolume volume : getVolumes()) {
+            for (String dir : dirs) {
+                if (volume.isPrimary() && dir == DIRECTORY_ROOT) continue;
+                // Rejects the first attempt...
+                UiAlertDialog dialog = openExternalDirectoryValidPath(volume, dir);
+                dialog.assertDoNotAskAgainVisibility(false);
+                dialog.noButton.click();
+                assertActivityFailed();
+
+                // ...and the second, checking the box
+                dialog = openExternalDirectoryValidPath(volume, dir);
+                UiObject checkbox = dialog.assertDoNotAskAgainVisibility(true);
+                assertTrue("checkbox should not be checkable", checkbox.isCheckable());
+                assertFalse("checkbox should not be checked", checkbox.isChecked());
+                checkbox.click();
+                assertTrue("checkbox should be checked", checkbox.isChecked()); // Sanity check
+                assertFalse("allow button should be disabled", dialog.yesButton.isEnabled());
+
+                dialog.noButton.click();
+                assertActivityFailed();
+
+                // Third strike out...
+                sendOpenExternalDirectoryIntent(volume, dir);
+                assertActivityFailed();
+            }
+        }
+    }
+
+    private Uri userAcceptsOpenExternalDirectoryTest(StorageVolume volume, String directoryName)
+            throws Exception {
+        // Asserts dialog contain the proper message.
+        final UiAlertDialog dialog = openExternalDirectoryValidPath(volume, directoryName);
+        final String message = dialog.messageText.getText();
+        Log.v(TAG, "request permission message: " + message);
+        final Context context = getInstrumentation().getContext();
+        final String appLabel = context.getPackageManager().getApplicationLabel(
+                context.getApplicationInfo()).toString();
+        assertContainsRegex("missing app label", appLabel, message);
+        final String volumeLabel = volume.getDescription(context);
+        if (volume.isPrimary()) {
+            assertNotContainsRegex("should not have volume label on primary", volumeLabel, message);
+        } else {
+            assertContainsRegex("missing volume label", volumeLabel, message);
+        }
+        if (directoryName != null) {
+            assertContainsRegex("missing folder", directoryName, message);
+        } else {
+            assertNotContainsRegex("should not have folder for root", "null", message);
+        }
+
+        // Call API...
+        dialog.yesButton.click();
+
+        // ...and get its response.
+        final String volumeDesc = volume.getDescription(context);
+        final Intent data = assertActivitySucceeded("should have already granted "
+                + "permission to " + volumeDesc + " and " + directoryName);
+        final Uri grantedUri = data.getData();
+
+        // Test granted permission directly by persisting it...
+        final ContentResolver resolver = context.getContentResolver();
+        final int modeFlags = data.getFlags()
+                & (Intent.FLAG_GRANT_READ_URI_PERMISSION
+                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
+        resolver.takePersistableUriPermission(grantedUri, modeFlags);
+
+        // ...and indirectly by creating some documents
+        final Uri doc = DocumentsContract.buildDocumentUriUsingTree(grantedUri,
+                DocumentsContract.getTreeDocumentId(grantedUri));
+        assertNotNull("could not get tree URI", doc);
+        final Uri pic = DocumentsContract.createDocument(resolver, doc, "image/png", "pic.png");
+        assertNotNull("could not create file (pic.png) on tree root", pic);
+        final Uri dir = DocumentsContract.createDocument(resolver, doc, Document.MIME_TYPE_DIR,
+                "my dir");
+        assertNotNull("could not create child dir (my dir)", pic);
+        final Uri dirPic = DocumentsContract.createDocument(resolver, dir, "image/png", "pic2.png");
+        assertNotNull("could not create file (pic.png) on child dir (my dir)", dirPic);
+
+        writeFully(pic, "pic".getBytes());
+        writeFully(dirPic, "dirPic".getBytes());
+
+        // Clean up created documents.
+        assertTrue("delete", DocumentsContract.deleteDocument(resolver, pic));
+        assertTrue("delete", DocumentsContract.deleteDocument(resolver, dirPic));
+        assertTrue("delete", DocumentsContract.deleteDocument(resolver, dir));
+
+        return grantedUri;
+    }
+
+    private void openExternalDirectoryInvalidPath(StorageVolume volume, String directoryName) {
+        final Intent intent = volume.createAccessIntent(directoryName);
+        assertNull("should not get intent for volume '" + volume + "' and directory '"
+                + directoryName + "'", intent);
+    }
+
+    private UiAlertDialog openExternalDirectoryValidPath(StorageVolume volume, String path)
+            throws UiObjectNotFoundException {
+        sendOpenExternalDirectoryIntent(volume, path);
+        return new UiAlertDialog(volume, path);
+    }
+
+    private void sendOpenExternalDirectoryIntent(StorageVolume volume, String directoryName) {
+        final Intent intent = volume.createAccessIntent(directoryName);
+        assertNotNull("no intent for '" + volume + "' and directory " + directoryName, intent);
+        mActivity.startActivityForResult(intent, REQUEST_CODE);
+        mDevice.waitForIdle();
+    }
+
+    private List<StorageVolume> getVolumes() {
+        final StorageManager sm = (StorageManager)
+                getInstrumentation().getTargetContext().getSystemService(Context.STORAGE_SERVICE);
+        final List<StorageVolume> volumes = sm.getStorageVolumes();
+        assertTrue("empty volumes", !volumes.isEmpty());
+        return volumes;
+    }
+
+    private StorageVolume getPrimaryVolume() {
+        final StorageManager sm = (StorageManager)
+                getInstrumentation().getTargetContext().getSystemService(Context.STORAGE_SERVICE);
+        return sm.getPrimaryStorageVolume();
+    }
+
+    private final class UiAlertDialog {
+        final UiObject dialog;
+        final UiObject messageText;
+        final UiObject yesButton;
+        final UiObject noButton;
+        final String volumeDesc;
+        final String directory;
+
+        UiAlertDialog(StorageVolume volume, String path) throws UiObjectNotFoundException {
+            volumeDesc = volume.getDescription(getInstrumentation().getContext());
+            directory = path;
+
+            final String id = "android:id/parentPanel";
+            boolean gotIt = mDevice.wait(Until.hasObject(By.res(id)), TIMEOUT);
+            assertTrue("object with id '(" + id + "') not visible yet for "
+                    + volumeDesc + " and " + path, gotIt);
+            dialog = mDevice.findObject(new UiSelector().resourceId(id));
+            assertTrue("object with id '(" + id + "') doesn't exist", dialog.exists());
+            messageText = dialog.getChild(
+                    new UiSelector().resourceId("com.android.documentsui:id/message"));
+            yesButton = dialog.getChild(new UiSelector().resourceId("android:id/button1"));
+            noButton  = dialog.getChild(new UiSelector().resourceId("android:id/button2"));
+        }
+
+        private UiObject getDoNotAskAgainCheckBox() throws UiObjectNotFoundException {
+            return dialog.getChild(
+                    new UiSelector().resourceId("com.android.documentsui:id/do_not_ask_checkbox"));
+        }
+
+        UiObject assertDoNotAskAgainVisibility(boolean expectVisible) {
+            UiObject checkbox = null;
+            try {
+                checkbox = getDoNotAskAgainCheckBox();
+                assertEquals("Wrong value for 'DoNotAskAgain.exists()",
+                        expectVisible, checkbox.exists());
+            } catch (UiObjectNotFoundException e) {
+                if (expectVisible) {
+                    fail("'Do Not Ask Again' not found");
+                }
+            }
+            return checkbox;
+        }
+    }
+}
diff --git a/hostsidetests/appsecurity/test-apps/DocumentProvider/Android.mk b/hostsidetests/appsecurity/test-apps/DocumentProvider/Android.mk
index bbf7734..ef51768 100644
--- a/hostsidetests/appsecurity/test-apps/DocumentProvider/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/DocumentProvider/Android.mk
@@ -26,6 +26,9 @@
 
 LOCAL_PACKAGE_NAME := CtsDocumentProvider
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey1
 
 LOCAL_PROGUARD_ENABLED := disabled
diff --git a/hostsidetests/appsecurity/test-apps/DocumentProvider/src/com/android/cts/documentprovider/MyDocumentsProvider.java b/hostsidetests/appsecurity/test-apps/DocumentProvider/src/com/android/cts/documentprovider/MyDocumentsProvider.java
index 9d38a94..19ba2f7 100644
--- a/hostsidetests/appsecurity/test-apps/DocumentProvider/src/com/android/cts/documentprovider/MyDocumentsProvider.java
+++ b/hostsidetests/appsecurity/test-apps/DocumentProvider/src/com/android/cts/documentprovider/MyDocumentsProvider.java
@@ -16,12 +16,16 @@
 
 package com.android.cts.documentprovider;
 
+import android.content.res.AssetFileDescriptor;
 import android.database.Cursor;
 import android.database.MatrixCursor;
 import android.database.MatrixCursor.RowBuilder;
+import android.net.Uri;
 import android.os.AsyncTask;
+import android.os.Bundle;
 import android.os.CancellationSignal;
 import android.os.ParcelFileDescriptor;
+import android.provider.DocumentsContract;
 import android.provider.DocumentsContract.Document;
 import android.provider.DocumentsContract.Root;
 import android.provider.DocumentsProvider;
@@ -89,11 +93,13 @@
     private Doc mLocalRoot;
     private Doc mCreateRoot;
 
-    private Doc buildDoc(String docId, String displayName, String mimeType) {
+    private Doc buildDoc(String docId, String displayName, String mimeType,
+            String[] streamTypes) {
         final Doc doc = new Doc();
         doc.docId = docId;
         doc.displayName = displayName;
         doc.mimeType = mimeType;
+        doc.streamTypes = streamTypes;
         mDocs.put(doc.docId, doc);
         return doc;
     }
@@ -103,13 +109,13 @@
 
         mDocs.clear();
 
-        mLocalRoot = buildDoc("doc:local", null, Document.MIME_TYPE_DIR);
+        mLocalRoot = buildDoc("doc:local", null, Document.MIME_TYPE_DIR, null);
 
-        mCreateRoot = buildDoc("doc:create", null, Document.MIME_TYPE_DIR);
+        mCreateRoot = buildDoc("doc:create", null, Document.MIME_TYPE_DIR, null);
         mCreateRoot.flags = Document.FLAG_DIR_SUPPORTS_CREATE;
 
         {
-            Doc file1 = buildDoc("doc:file1", "FILE1", "mime1/file1");
+            Doc file1 = buildDoc("doc:file1", "FILE1", "mime1/file1", null);
             file1.contents = "fileone".getBytes();
             file1.flags = Document.FLAG_SUPPORTS_WRITE;
             mLocalRoot.children.add(file1);
@@ -117,31 +123,46 @@
         }
 
         {
-            Doc file2 = buildDoc("doc:file2", "FILE2", "mime2/file2");
+            Doc file2 = buildDoc("doc:file2", "FILE2", "mime2/file2", null);
             file2.contents = "filetwo".getBytes();
             file2.flags = Document.FLAG_SUPPORTS_WRITE;
             mLocalRoot.children.add(file2);
             mCreateRoot.children.add(file2);
         }
 
-        Doc dir1 = buildDoc("doc:dir1", "DIR1", Document.MIME_TYPE_DIR);
+        {
+            Doc virtualFile = buildDoc("doc:virtual-file", "VIRTUAL_FILE", "application/icecream",
+                    new String[] { "text/plain" });
+            virtualFile.flags = Document.FLAG_VIRTUAL_DOCUMENT;
+            virtualFile.contents = "Converted contents.".getBytes();
+            mLocalRoot.children.add(virtualFile);
+            mCreateRoot.children.add(virtualFile);
+        }
+
+        Doc dir1 = buildDoc("doc:dir1", "DIR1", Document.MIME_TYPE_DIR, null);
         mLocalRoot.children.add(dir1);
 
         {
-            Doc file3 = buildDoc("doc:file3", "FILE3", "mime3/file3");
+            Doc file3 = buildDoc("doc:file3", "FILE3", "mime3/file3", null);
             file3.contents = "filethree".getBytes();
             file3.flags = Document.FLAG_SUPPORTS_WRITE;
             dir1.children.add(file3);
         }
 
-        Doc dir2 = buildDoc("doc:dir2", "DIR2", Document.MIME_TYPE_DIR);
+        Doc dir2 = buildDoc("doc:dir2", "DIR2", Document.MIME_TYPE_DIR, null);
         mCreateRoot.children.add(dir2);
 
         {
-            Doc file4 = buildDoc("doc:file4", "FILE4", "mime4/file4");
+            Doc file4 = buildDoc("doc:file4", "FILE4", "mime4/file4", null);
             file4.contents = "filefour".getBytes();
-            file4.flags = Document.FLAG_SUPPORTS_WRITE;
+            file4.flags = Document.FLAG_SUPPORTS_WRITE |
+                    Document.FLAG_SUPPORTS_COPY |
+                    Document.FLAG_SUPPORTS_MOVE |
+                    Document.FLAG_SUPPORTS_REMOVE;
             dir2.children.add(file4);
+
+            Doc subDir2 = buildDoc("doc:sub_dir2", "SUB_DIR2", Document.MIME_TYPE_DIR, null);
+            dir2.children.add(subDir2);
         }
     }
 
@@ -151,6 +172,7 @@
         public String displayName;
         public long size;
         public String mimeType;
+        public String[] streamTypes;
         public long lastModified;
         public byte[] contents;
         public List<Doc> children = new ArrayList<>();
@@ -173,7 +195,9 @@
                 return true;
             }
             if (Document.MIME_TYPE_DIR.equals(doc.mimeType)) {
-                return isChildDocument(doc.docId, documentId);
+                if (isChildDocument(doc.docId, documentId)) {
+                    return true;
+                }
             }
         }
         return false;
@@ -183,7 +207,7 @@
     public String createDocument(String parentDocumentId, String mimeType, String displayName)
             throws FileNotFoundException {
         final String docId = "doc:" + System.currentTimeMillis();
-        final Doc doc = buildDoc(docId, displayName, mimeType);
+        final Doc doc = buildDoc(docId, displayName, mimeType, null);
         doc.flags = Document.FLAG_SUPPORTS_WRITE | Document.FLAG_SUPPORTS_RENAME;
         mDocs.get(parentDocumentId).children.add(doc);
         return docId;
@@ -198,13 +222,48 @@
 
     @Override
     public void deleteDocument(String documentId) throws FileNotFoundException {
-        mDocs.remove(documentId);
-        for (Doc doc : mDocs.values()) {
-            doc.children.remove(documentId);
+        final Doc doc = mDocs.get(documentId);
+        mDocs.remove(doc);
+        for (Doc parentDoc : mDocs.values()) {
+            parentDoc.children.remove(doc);
         }
     }
 
     @Override
+    public void removeDocument(String documentId, String parentDocumentId)
+            throws FileNotFoundException {
+        // There are no multi-parented documents in this provider, so it's safe to remove the
+        // document from mDocs.
+        final Doc doc = mDocs.get(documentId);
+        mDocs.remove(doc);
+        mDocs.get(parentDocumentId).children.remove(doc);
+    }
+
+    @Override
+    public String copyDocument(String sourceDocumentId, String targetParentDocumentId)
+            throws FileNotFoundException {
+        final Doc doc = mDocs.get(sourceDocumentId);
+        if (doc.children.size() > 0) {
+            throw new UnsupportedOperationException("Recursive copy not supported for tests.");
+        }
+
+        final Doc docCopy = buildDoc(doc.docId + "_copy", doc.displayName + "_COPY", doc.mimeType,
+                doc.streamTypes);
+        mDocs.get(targetParentDocumentId).children.add(docCopy);
+        return docCopy.docId;
+    }
+
+    @Override
+    public String moveDocument(String sourceDocumentId, String sourceParentDocumentId,
+            String targetParentDocumentId)
+            throws FileNotFoundException {
+        final Doc doc = mDocs.get(sourceDocumentId);
+        mDocs.get(sourceParentDocumentId).children.remove(doc);
+        mDocs.get(targetParentDocumentId).children.add(doc);
+        return doc.docId;
+    }
+
+    @Override
     public Cursor queryDocument(String documentId, String[] projection)
             throws FileNotFoundException {
         final MatrixCursor result = new MatrixCursor(resolveDocumentProjection(projection));
@@ -229,6 +288,14 @@
         if (doc == null) {
             throw new FileNotFoundException();
         }
+        if ((doc.flags & Document.FLAG_VIRTUAL_DOCUMENT) != 0) {
+            throw new IllegalArgumentException("Tried to open a virtual file.");
+        }
+        return openDocumentUnchecked(doc, mode, signal);
+    }
+
+    private ParcelFileDescriptor openDocumentUnchecked(final Doc doc, String mode,
+            CancellationSignal signal) throws FileNotFoundException {
         final ParcelFileDescriptor[] pipe;
         try {
             pipe = ParcelFileDescriptor.createPipe();
@@ -280,6 +347,48 @@
         }
     }
 
+    @Override
+    public String[] getStreamTypes(Uri documentUri, String mimeTypeFilter) {
+        // TODO: Add enforceTree(uri); b/27156282
+        final String documentId = DocumentsContract.getDocumentId(documentUri);
+
+        if (!"*/*".equals(mimeTypeFilter)) {
+            throw new UnsupportedOperationException(
+                    "Unsupported MIME type filter supported for tests.");
+        }
+
+        final Doc doc = mDocs.get(documentId);
+        if (doc == null) {
+            return null;
+        }
+
+        return doc.streamTypes;
+    }
+
+    @Override
+    public AssetFileDescriptor openTypedDocument(
+            String documentId, String mimeTypeFilter, Bundle opts, CancellationSignal signal)
+            throws FileNotFoundException {
+        final Doc doc = mDocs.get(documentId);
+        if (doc == null) {
+            throw new FileNotFoundException();
+        }
+
+        if (mimeTypeFilter.contains("*")) {
+            throw new UnsupportedOperationException(
+                    "MIME type filters with Wildcards not supported for tests.");
+        }
+
+        for (String streamType : doc.streamTypes) {
+            if (streamType.equals(mimeTypeFilter)) {
+                return new AssetFileDescriptor(openDocumentUnchecked(
+                        doc, "r", signal), 0, doc.contents.length);
+            }
+        }
+
+        throw new UnsupportedOperationException("Unsupported MIME type filter for tests.");
+    }
+
     private static byte[] readFullyNoClose(InputStream in) throws IOException {
         ByteArrayOutputStream bytes = new ByteArrayOutputStream();
         byte[] buffer = new byte[1024];
diff --git a/hostsidetests/appsecurity/test-apps/EncryptionApp/Android.mk b/hostsidetests/appsecurity/test-apps/EncryptionApp/Android.mk
new file mode 100644
index 0000000..d362ed6
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/EncryptionApp/Android.mk
@@ -0,0 +1,37 @@
+#
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+LOCAL_SDK_VERSION := current
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-test ctsdeviceutil ctstestrunner ub-uiautomator
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := CtsEncryptionApp
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey1
+
+LOCAL_PROGUARD_ENABLED := disabled
+LOCAL_DEX_PREOPT := false
+
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/EncryptionApp/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/EncryptionApp/AndroidManifest.xml
new file mode 100644
index 0000000..da3c9e4
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/EncryptionApp/AndroidManifest.xml
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="com.android.cts.encryptionapp">
+    <application android:label="EncryptionApp">
+        <activity android:name=".UnawareActivity"
+                android:exported="true">
+            <intent-filter>
+                <action android:name="com.android.cts.encryptionapp.TEST" />
+            </intent-filter>
+        </activity>
+
+        <receiver android:name=".UnawareReceiver"
+                android:exported="true">
+            <intent-filter>
+                <action android:name="com.android.cts.encryptionapp.TEST" />
+            </intent-filter>
+        </receiver>
+
+        <service android:name=".UnawareService"
+                android:exported="true">
+            <intent-filter>
+                <action android:name="com.android.cts.encryptionapp.TEST" />
+            </intent-filter>
+        </service>
+
+        <provider android:name=".UnawareProvider"
+                android:authorities="com.android.cts.encryptionapp.unaware"
+                android:exported="true">
+            <intent-filter>
+                <action android:name="com.android.cts.encryptionapp.TEST" />
+            </intent-filter>
+        </provider>
+
+        <activity android:name=".AwareActivity"
+                android:directBootAware="true"
+                android:exported="true">
+            <intent-filter>
+                <action android:name="com.android.cts.encryptionapp.TEST" />
+            </intent-filter>
+        </activity>
+
+        <receiver android:name=".AwareReceiver"
+                android:directBootAware="true"
+                android:exported="true">
+            <intent-filter>
+                <action android:name="com.android.cts.encryptionapp.TEST" />
+            </intent-filter>
+        </receiver>
+
+        <service android:name=".AwareService"
+                android:directBootAware="true"
+                android:exported="true">
+            <intent-filter>
+                <action android:name="com.android.cts.encryptionapp.TEST" />
+            </intent-filter>
+        </service>
+
+        <provider android:name=".AwareProvider"
+                android:authorities="com.android.cts.encryptionapp.aware"
+                android:directBootAware="true"
+                android:exported="true">
+            <intent-filter>
+                <action android:name="com.android.cts.encryptionapp.TEST" />
+            </intent-filter>
+        </provider>
+
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+        android:targetPackage="com.android.cts.encryptionapp" />
+
+</manifest>
diff --git a/hostsidetests/appsecurity/test-apps/EncryptionApp/src/com/android/cts/encryptionapp/AwareActivity.java b/hostsidetests/appsecurity/test-apps/EncryptionApp/src/com/android/cts/encryptionapp/AwareActivity.java
new file mode 100644
index 0000000..617fa1f
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/EncryptionApp/src/com/android/cts/encryptionapp/AwareActivity.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.encryptionapp;
+
+import static com.android.cts.encryptionapp.EncryptionApp.AWARE;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.WindowManager;
+
+public class AwareActivity extends Activity {
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        Log.v(AWARE, "Activity.onCreate()");
+
+        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
+                | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
+                | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
+    }
+}
diff --git a/hostsidetests/appsecurity/test-apps/EncryptionApp/src/com/android/cts/encryptionapp/AwareProvider.java b/hostsidetests/appsecurity/test-apps/EncryptionApp/src/com/android/cts/encryptionapp/AwareProvider.java
new file mode 100644
index 0000000..a95fa7d
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/EncryptionApp/src/com/android/cts/encryptionapp/AwareProvider.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.encryptionapp;
+
+import static com.android.cts.encryptionapp.EncryptionApp.AWARE;
+
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.net.Uri;
+import android.util.Log;
+
+public class AwareProvider extends ContentProvider {
+    public static volatile boolean sCreated = false;
+
+    @Override
+    public boolean onCreate() {
+        Log.v(AWARE, "ContentProvider.onCreate()");
+        sCreated = true;
+        return true;
+    }
+
+    @Override
+    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
+            String sortOrder) {
+        return null;
+    }
+
+    @Override
+    public String getType(Uri uri) {
+        return null;
+    }
+
+    @Override
+    public Uri insert(Uri uri, ContentValues values) {
+        return null;
+    }
+
+    @Override
+    public int delete(Uri uri, String selection, String[] selectionArgs) {
+        return 0;
+    }
+
+    @Override
+    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+        return 0;
+    }
+}
diff --git a/hostsidetests/appsecurity/test-apps/EncryptionApp/src/com/android/cts/encryptionapp/AwareReceiver.java b/hostsidetests/appsecurity/test-apps/EncryptionApp/src/com/android/cts/encryptionapp/AwareReceiver.java
new file mode 100644
index 0000000..1ffefa0
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/EncryptionApp/src/com/android/cts/encryptionapp/AwareReceiver.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.encryptionapp;
+
+import static com.android.cts.encryptionapp.EncryptionApp.AWARE;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.util.Log;
+
+public class AwareReceiver extends BroadcastReceiver {
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        Log.v(AWARE, "BroadcastReceiver.onReceive()");
+    }
+}
diff --git a/hostsidetests/appsecurity/test-apps/EncryptionApp/src/com/android/cts/encryptionapp/AwareService.java b/hostsidetests/appsecurity/test-apps/EncryptionApp/src/com/android/cts/encryptionapp/AwareService.java
new file mode 100644
index 0000000..60f1189
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/EncryptionApp/src/com/android/cts/encryptionapp/AwareService.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.encryptionapp;
+
+import static com.android.cts.encryptionapp.EncryptionApp.AWARE;
+
+import android.app.IntentService;
+import android.content.Intent;
+import android.util.Log;
+
+public class AwareService extends IntentService {
+    public AwareService() {
+        super(AWARE);
+    }
+
+    @Override
+    protected void onHandleIntent(Intent intent) {
+        Log.v(AWARE, "IntentService.onHandleIntent()");
+    }
+}
diff --git a/hostsidetests/appsecurity/test-apps/EncryptionApp/src/com/android/cts/encryptionapp/EncryptionApp.java b/hostsidetests/appsecurity/test-apps/EncryptionApp/src/com/android/cts/encryptionapp/EncryptionApp.java
new file mode 100644
index 0000000..238f4e8
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/EncryptionApp/src/com/android/cts/encryptionapp/EncryptionApp.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.encryptionapp;
+
+import android.app.Application;
+import android.util.Log;
+
+public class EncryptionApp extends Application {
+    static final String AWARE = "Aware";
+    static final String UNAWARE = "Unaware";
+
+    @Override
+    public void onCreate() {
+        Log.v(AWARE, "Application.onCreate()");
+    }
+}
diff --git a/hostsidetests/appsecurity/test-apps/EncryptionApp/src/com/android/cts/encryptionapp/EncryptionAppTest.java b/hostsidetests/appsecurity/test-apps/EncryptionApp/src/com/android/cts/encryptionapp/EncryptionAppTest.java
new file mode 100644
index 0000000..fd7dac7
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/EncryptionApp/src/com/android/cts/encryptionapp/EncryptionAppTest.java
@@ -0,0 +1,384 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.encryptionapp;
+
+import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
+import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.ComponentInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.os.SystemClock;
+import android.os.UserManager;
+import android.provider.Settings;
+import android.support.test.uiautomator.UiDevice;
+import android.support.test.uiautomator.UiObject;
+import android.support.test.uiautomator.UiSelector;
+import android.test.InstrumentationTestCase;
+import android.text.format.DateUtils;
+import android.util.Log;
+import android.view.KeyEvent;
+
+import java.io.File;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+public class EncryptionAppTest extends InstrumentationTestCase {
+    private static final String TAG = "EncryptionAppTest";
+
+    private static final long TIMEOUT = 10 * DateUtils.SECOND_IN_MILLIS;
+
+    private static final String KEY_BOOT = "boot";
+
+    private static final String TEST_PKG = "com.android.cts.encryptionapp";
+    private static final String TEST_ACTION = "com.android.cts.encryptionapp.TEST";
+
+    private static final String OTHER_PKG = "com.android.cts.splitapp";
+
+    private Context mCe;
+    private Context mDe;
+    private PackageManager mPm;
+
+    private UiDevice mDevice;
+    private AwareActivity mActivity;
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+
+        mCe = getInstrumentation().getContext();
+        mDe = mCe.createDeviceProtectedStorageContext();
+        mPm = mCe.getPackageManager();
+
+        mDevice = UiDevice.getInstance(getInstrumentation());
+        assertNotNull(mDevice);
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        super.tearDown();
+
+        if (mActivity != null) {
+            mActivity.finish();
+        }
+    }
+
+    public void testSetUp() throws Exception {
+        // Write both CE/DE data for ourselves
+        assertTrue("CE file", getTestFile(mCe).createNewFile());
+        assertTrue("DE file", getTestFile(mDe).createNewFile());
+
+        doBootCountBefore();
+
+        mActivity = launchActivity(getInstrumentation().getTargetContext().getPackageName(),
+                AwareActivity.class, null);
+        mDevice.waitForIdle();
+
+        // Set a PIN for this user
+        final Intent intent = new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD);
+        intent.addCategory(Intent.CATEGORY_DEFAULT);
+        mActivity.startActivity(intent);
+        mDevice.waitForIdle();
+
+        // Pick PIN from the option list
+        UiObject view = new UiObject(new UiSelector()
+                .resourceId("com.android.settings:id/lock_pin"));
+        assertTrue("lock_pin", view.waitForExists(TIMEOUT));
+        view.click();
+        mDevice.waitForIdle();
+
+        // Ignore any interstitial options
+        view = new UiObject(new UiSelector()
+                .resourceId("com.android.settings:id/encrypt_dont_require_password"));
+        if (view.waitForExists(TIMEOUT)) {
+            view.click();
+            mDevice.waitForIdle();
+        }
+
+        // Set our PIN
+        view = new UiObject(new UiSelector()
+                .resourceId("com.android.settings:id/password_entry"));
+        assertTrue("password_entry", view.waitForExists(TIMEOUT));
+
+        // Enter it twice to confirm
+        enterTestPin();
+        enterTestPin();
+
+        mDevice.pressBack();
+    }
+
+    public void testTearDown() throws Exception {
+        // Just in case, always try tearing down keyguard
+        dismissKeyguard();
+
+        mActivity = launchActivity(getInstrumentation().getTargetContext().getPackageName(),
+                AwareActivity.class, null);
+        mDevice.waitForIdle();
+
+        // Clear PIN for this user
+        final Intent intent = new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD);
+        intent.addCategory(Intent.CATEGORY_DEFAULT);
+        mActivity.startActivity(intent);
+        mDevice.waitForIdle();
+
+        // Enter current PIN
+        UiObject view = new UiObject(new UiSelector()
+                .resourceId("com.android.settings:id/password_entry"));
+        assertTrue("password_entry", view.waitForExists(TIMEOUT));
+
+        enterTestPin();
+
+        // Set back to "none"
+        view = new UiObject(new UiSelector()
+                .resourceId("com.android.settings:id/lock_none"));
+        assertTrue("lock_none", view.waitForExists(TIMEOUT));
+        view.click();
+        mDevice.waitForIdle();
+
+        // Yes, we really want to
+        view = new UiObject(new UiSelector()
+                .resourceId("android:id/button1"));
+        if (view.waitForExists(TIMEOUT)) {
+            view.click();
+            mDevice.waitForIdle();
+        }
+
+        mDevice.pressBack();
+    }
+
+    public void doBootCountBefore() throws Exception {
+        final int thisCount = getBootCount();
+        mDe.getSharedPreferences(KEY_BOOT, 0).edit().putInt(KEY_BOOT, thisCount).commit();
+    }
+
+    public void doBootCountAfter() throws Exception {
+        final int lastCount = mDe.getSharedPreferences(KEY_BOOT, 0).getInt(KEY_BOOT, -1);
+        final int thisCount = getBootCount();
+        assertTrue("Current boot count " + thisCount + " not greater than last " + lastCount,
+                thisCount > lastCount);
+    }
+
+    public void testVerifyUnlockedAndDismiss() throws Exception {
+        doBootCountAfter();
+        assertUnlocked();
+        dismissKeyguard();
+        assertUnlocked();
+    }
+
+    public void testVerifyLockedAndDismiss() throws Exception {
+        doBootCountAfter();
+        assertLocked();
+
+        final CountDownLatch latch = new CountDownLatch(1);
+        final BroadcastReceiver receiver = new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                latch.countDown();
+            }
+        };
+        mDe.registerReceiver(receiver, new IntentFilter(Intent.ACTION_USER_UNLOCKED));
+
+        dismissKeyguard();
+
+        // Dismiss keyguard should have kicked off immediate broadcast
+        assertTrue("USER_UNLOCKED", latch.await(1, TimeUnit.MINUTES));
+
+        // And we should now be fully unlocked; we run immediately like this to
+        // avoid missing BOOT_COMPLETED due to instrumentation being torn down.
+        assertUnlocked();
+    }
+
+    private void enterTestPin() throws Exception {
+        // TODO: change the combination on my luggage
+        mDevice.waitForIdle();
+        mDevice.pressKeyCode(KeyEvent.KEYCODE_1);
+        mDevice.pressKeyCode(KeyEvent.KEYCODE_2);
+        mDevice.pressKeyCode(KeyEvent.KEYCODE_3);
+        mDevice.pressKeyCode(KeyEvent.KEYCODE_4);
+        mDevice.pressKeyCode(KeyEvent.KEYCODE_5);
+        mDevice.waitForIdle();
+        mDevice.pressEnter();
+        mDevice.waitForIdle();
+    }
+
+    private void dismissKeyguard() throws Exception {
+        mDevice.wakeUp();
+        mDevice.waitForIdle();
+        mDevice.pressMenu();
+        mDevice.waitForIdle();
+        enterTestPin();
+    }
+
+    public void assertLocked() throws Exception {
+        awaitBroadcast(Intent.ACTION_LOCKED_BOOT_COMPLETED);
+
+        assertFalse("CE exists", getTestFile(mCe).exists());
+        assertTrue("DE exists", getTestFile(mDe).exists());
+
+        assertFalse("isUserUnlocked", mCe.getSystemService(UserManager.class).isUserUnlocked());
+        assertFalse("isUserUnlocked", mDe.getSystemService(UserManager.class).isUserUnlocked());
+
+        assertTrue("AwareProvider", AwareProvider.sCreated);
+        assertFalse("UnawareProvider", UnawareProvider.sCreated);
+
+        assertNotNull("AwareProvider",
+                mPm.resolveContentProvider("com.android.cts.encryptionapp.aware", 0));
+        assertNull("UnawareProvider",
+                mPm.resolveContentProvider("com.android.cts.encryptionapp.unaware", 0));
+
+        assertGetAware(true, 0);
+        assertGetAware(true, MATCH_DIRECT_BOOT_AWARE);
+        assertGetAware(false, MATCH_DIRECT_BOOT_UNAWARE);
+        assertGetAware(true, MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
+
+        assertGetUnaware(false, 0);
+        assertGetUnaware(false, MATCH_DIRECT_BOOT_AWARE);
+        assertGetUnaware(true, MATCH_DIRECT_BOOT_UNAWARE);
+        assertGetUnaware(true, MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
+
+        assertQuery(1, 0);
+        assertQuery(1, MATCH_DIRECT_BOOT_AWARE);
+        assertQuery(1, MATCH_DIRECT_BOOT_UNAWARE);
+        assertQuery(2, MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
+    }
+
+    public void assertUnlocked() throws Exception {
+        awaitBroadcast(Intent.ACTION_LOCKED_BOOT_COMPLETED);
+        awaitBroadcast(Intent.ACTION_BOOT_COMPLETED);
+
+        assertTrue("CE exists", getTestFile(mCe).exists());
+        assertTrue("DE exists", getTestFile(mDe).exists());
+
+        assertTrue("isUserUnlocked", mCe.getSystemService(UserManager.class).isUserUnlocked());
+        assertTrue("isUserUnlocked", mDe.getSystemService(UserManager.class).isUserUnlocked());
+
+        assertTrue("AwareProvider", AwareProvider.sCreated);
+        assertTrue("UnawareProvider", UnawareProvider.sCreated);
+
+        assertNotNull("AwareProvider",
+                mPm.resolveContentProvider("com.android.cts.encryptionapp.aware", 0));
+        assertNotNull("UnawareProvider",
+                mPm.resolveContentProvider("com.android.cts.encryptionapp.unaware", 0));
+
+        assertGetAware(true, 0);
+        assertGetAware(true, MATCH_DIRECT_BOOT_AWARE);
+        assertGetAware(false, MATCH_DIRECT_BOOT_UNAWARE);
+        assertGetAware(true, MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
+
+        assertGetUnaware(true, 0);
+        assertGetUnaware(false, MATCH_DIRECT_BOOT_AWARE);
+        assertGetUnaware(true, MATCH_DIRECT_BOOT_UNAWARE);
+        assertGetUnaware(true, MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
+
+        assertQuery(2, 0);
+        assertQuery(1, MATCH_DIRECT_BOOT_AWARE);
+        assertQuery(1, MATCH_DIRECT_BOOT_UNAWARE);
+        assertQuery(2, MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
+    }
+
+    private void assertQuery(int count, int flags) throws Exception {
+        final Intent intent = new Intent(TEST_ACTION);
+        assertEquals("activity", count, mPm.queryIntentActivities(intent, flags).size());
+        assertEquals("service", count, mPm.queryIntentServices(intent, flags).size());
+        assertEquals("provider", count, mPm.queryIntentContentProviders(intent, flags).size());
+        assertEquals("receiver", count, mPm.queryBroadcastReceivers(intent, flags).size());
+    }
+
+    private void assertGetUnaware(boolean visible, int flags) throws Exception {
+        assertGet(visible, false, flags);
+    }
+
+    private void assertGetAware(boolean visible, int flags) throws Exception {
+        assertGet(visible, true, flags);
+    }
+
+    private ComponentName buildName(String prefix, String type) {
+        return new ComponentName(TEST_PKG, TEST_PKG + "." + prefix + type);
+    }
+
+    private void assertGet(boolean visible, boolean aware, int flags) throws Exception {
+        final String prefix = aware ? "Aware" : "Unaware";
+
+        ComponentName name;
+        ComponentInfo info;
+
+        name = buildName(prefix, "Activity");
+        try {
+            info = mPm.getActivityInfo(name, flags);
+            assertTrue(name + " visible", visible);
+            assertEquals(name + " directBootAware", aware, info.directBootAware);
+        } catch (NameNotFoundException e) {
+            assertFalse(name + " visible", visible);
+        }
+
+        name = buildName(prefix, "Service");
+        try {
+            info = mPm.getServiceInfo(name, flags);
+            assertTrue(name + " visible", visible);
+            assertEquals(name + " directBootAware", aware, info.directBootAware);
+        } catch (NameNotFoundException e) {
+            assertFalse(name + " visible", visible);
+        }
+
+        name = buildName(prefix, "Provider");
+        try {
+            info = mPm.getProviderInfo(name, flags);
+            assertTrue(name + " visible", visible);
+            assertEquals(name + " directBootAware", aware, info.directBootAware);
+        } catch (NameNotFoundException e) {
+            assertFalse(name + " visible", visible);
+        }
+
+        name = buildName(prefix, "Receiver");
+        try {
+            info = mPm.getReceiverInfo(name, flags);
+            assertTrue(name + " visible", visible);
+            assertEquals(name + " directBootAware", aware, info.directBootAware);
+        } catch (NameNotFoundException e) {
+            assertFalse(name + " visible", visible);
+        }
+    }
+
+    private File getTestFile(Context context) {
+        return new File(context.getFilesDir(), "test");
+    }
+
+    private int getBootCount() throws Exception {
+        return Settings.Global.getInt(mDe.getContentResolver(), Settings.Global.BOOT_COUNT);
+    }
+
+    private void awaitBroadcast(String action) throws Exception {
+        final Context otherContext = mDe.createPackageContext(OTHER_PKG, 0)
+                .createDeviceProtectedStorageContext();
+        final File probe = new File(otherContext.getFilesDir(),
+                getBootCount() + "." + action);
+        for (int i = 0; i < 60; i++) {
+            Log.d(TAG, "Waiting for " + probe + "...");
+            if (probe.exists()) {
+                return;
+            }
+            SystemClock.sleep(1000);
+        }
+        throw new AssertionError("Failed to find " + probe);
+    }
+}
diff --git a/hostsidetests/appsecurity/test-apps/EncryptionApp/src/com/android/cts/encryptionapp/UnawareActivity.java b/hostsidetests/appsecurity/test-apps/EncryptionApp/src/com/android/cts/encryptionapp/UnawareActivity.java
new file mode 100644
index 0000000..4978023
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/EncryptionApp/src/com/android/cts/encryptionapp/UnawareActivity.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.encryptionapp;
+
+import static com.android.cts.encryptionapp.EncryptionApp.UNAWARE;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.WindowManager;
+
+public class UnawareActivity extends Activity {
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        Log.v(UNAWARE, "Activity.onCreate()");
+
+        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
+                | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
+                | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
+    }
+}
diff --git a/hostsidetests/appsecurity/test-apps/EncryptionApp/src/com/android/cts/encryptionapp/UnawareProvider.java b/hostsidetests/appsecurity/test-apps/EncryptionApp/src/com/android/cts/encryptionapp/UnawareProvider.java
new file mode 100644
index 0000000..60d57df
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/EncryptionApp/src/com/android/cts/encryptionapp/UnawareProvider.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.encryptionapp;
+
+import static com.android.cts.encryptionapp.EncryptionApp.UNAWARE;
+
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.net.Uri;
+import android.util.Log;
+
+public class UnawareProvider extends ContentProvider {
+    public static volatile boolean sCreated = false;
+
+    @Override
+    public boolean onCreate() {
+        Log.v(UNAWARE, "ContentProvider.onCreate()");
+        sCreated = true;
+        return true;
+    }
+
+    @Override
+    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
+            String sortOrder) {
+        return null;
+    }
+
+    @Override
+    public String getType(Uri uri) {
+        return null;
+    }
+
+    @Override
+    public Uri insert(Uri uri, ContentValues values) {
+        return null;
+    }
+
+    @Override
+    public int delete(Uri uri, String selection, String[] selectionArgs) {
+        return 0;
+    }
+
+    @Override
+    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+        return 0;
+    }
+}
diff --git a/hostsidetests/appsecurity/test-apps/EncryptionApp/src/com/android/cts/encryptionapp/UnawareReceiver.java b/hostsidetests/appsecurity/test-apps/EncryptionApp/src/com/android/cts/encryptionapp/UnawareReceiver.java
new file mode 100644
index 0000000..80a8485
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/EncryptionApp/src/com/android/cts/encryptionapp/UnawareReceiver.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.encryptionapp;
+
+import static com.android.cts.encryptionapp.EncryptionApp.UNAWARE;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.util.Log;
+
+public class UnawareReceiver extends BroadcastReceiver {
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        Log.v(UNAWARE, "BroadcastReceiver.onReceive()");
+    }
+}
diff --git a/hostsidetests/appsecurity/test-apps/EncryptionApp/src/com/android/cts/encryptionapp/UnawareService.java b/hostsidetests/appsecurity/test-apps/EncryptionApp/src/com/android/cts/encryptionapp/UnawareService.java
new file mode 100644
index 0000000..d32654c
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/EncryptionApp/src/com/android/cts/encryptionapp/UnawareService.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.encryptionapp;
+
+import static com.android.cts.encryptionapp.EncryptionApp.UNAWARE;
+
+import android.app.IntentService;
+import android.content.Intent;
+import android.util.Log;
+
+public class UnawareService extends IntentService {
+    public UnawareService() {
+        super(UNAWARE);
+    }
+
+    @Override
+    protected void onHandleIntent(Intent intent) {
+        Log.v(UNAWARE, "IntentService.onHandleIntent()");
+    }
+}
diff --git a/hostsidetests/appsecurity/test-apps/ExternalStorageApp/Android.mk b/hostsidetests/appsecurity/test-apps/ExternalStorageApp/Android.mk
index a7de92a..560607b 100644
--- a/hostsidetests/appsecurity/test-apps/ExternalStorageApp/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/ExternalStorageApp/Android.mk
@@ -23,6 +23,9 @@
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 LOCAL_PACKAGE_NAME := CtsExternalStorageApp
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_DEX_PREOPT := false
 
 include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/ExternalStorageApp/src/com/android/cts/externalstorageapp/CommonExternalStorageTest.java b/hostsidetests/appsecurity/test-apps/ExternalStorageApp/src/com/android/cts/externalstorageapp/CommonExternalStorageTest.java
index 7fe0b80..fcf9f38 100644
--- a/hostsidetests/appsecurity/test-apps/ExternalStorageApp/src/com/android/cts/externalstorageapp/CommonExternalStorageTest.java
+++ b/hostsidetests/appsecurity/test-apps/ExternalStorageApp/src/com/android/cts/externalstorageapp/CommonExternalStorageTest.java
@@ -137,6 +137,16 @@
         Collections.addAll(paths, context.getExternalCacheDirs());
         Collections.addAll(paths, context.getExternalFilesDirs(null));
         Collections.addAll(paths, context.getExternalFilesDirs(Environment.DIRECTORY_PICTURES));
+        Collections.addAll(paths, context.getExternalMediaDirs());
+        Collections.addAll(paths, context.getObbDirs());
+        return paths;
+    }
+
+    public static List<File> getAllPackageSpecificPathsExceptMedia(Context context) {
+        final List<File> paths = new ArrayList<File>();
+        Collections.addAll(paths, context.getExternalCacheDirs());
+        Collections.addAll(paths, context.getExternalFilesDirs(null));
+        Collections.addAll(paths, context.getExternalFilesDirs(Environment.DIRECTORY_PICTURES));
         Collections.addAll(paths, context.getObbDirs());
         return paths;
     }
@@ -146,9 +156,26 @@
         Collections.addAll(paths, context.getExternalCacheDirs());
         Collections.addAll(paths, context.getExternalFilesDirs(null));
         Collections.addAll(paths, context.getExternalFilesDirs(Environment.DIRECTORY_PICTURES));
+        Collections.addAll(paths, context.getExternalMediaDirs());
         return paths;
     }
 
+    /**
+     * Return a set of several package-specific external storage paths pointing
+     * at "gift" files designed to be exchanged with the target package.
+     */
+    public static List<File> getAllPackageSpecificGiftPaths(Context context,
+            String targetPackageName) {
+        final List<File> files = getAllPackageSpecificPaths(context);
+        final List<File> targetFiles = new ArrayList<>();
+        for (File file : files) {
+            final File targetFile = new File(
+                    file.getAbsolutePath().replace(context.getPackageName(), targetPackageName));
+            targetFiles.add(new File(targetFile, targetPackageName + ".gift"));
+        }
+        return targetFiles;
+    }
+
     public static List<File> getPrimaryPackageSpecificPaths(Context context) {
         final List<File> paths = new ArrayList<File>();
         Collections.addAll(paths, context.getExternalCacheDir());
@@ -189,16 +216,25 @@
         return after;
     }
 
-    public static File buildGiftForPackage(Context context, String packageName) {
-        final File myCache = context.getExternalCacheDir();
-        return new File(myCache.getAbsolutePath().replace(context.getPackageName(), packageName),
-                packageName + ".gift");
-    }
-
     public static File buildProbeFile(File dir) {
         return new File(dir, ".probe_" + System.nanoTime());
     }
 
+    public static File[] buildCommonChildDirs(File dir) {
+        return new File[] {
+                new File(dir, Environment.DIRECTORY_MUSIC),
+                new File(dir, Environment.DIRECTORY_PODCASTS),
+                new File(dir, Environment.DIRECTORY_ALARMS),
+                new File(dir, Environment.DIRECTORY_RINGTONES),
+                new File(dir, Environment.DIRECTORY_NOTIFICATIONS),
+                new File(dir, Environment.DIRECTORY_PICTURES),
+                new File(dir, Environment.DIRECTORY_MOVIES),
+                new File(dir, Environment.DIRECTORY_DOWNLOADS),
+                new File(dir, Environment.DIRECTORY_DCIM),
+                new File(dir, Environment.DIRECTORY_DOCUMENTS),
+        };
+    }
+
     public static void assertDirReadOnlyAccess(File path) {
         Log.d(TAG, "Asserting read-only access to " + path);
 
@@ -209,8 +245,9 @@
 
         try {
             final File probe = buildProbeFile(path);
-            probe.createNewFile();
-            probe.delete();
+            assertFalse(probe.createNewFile());
+            assertFalse(probe.exists());
+            assertFalse(probe.delete());
             fail("able to create probe!");
         } catch (IOException e) {
             // expected
@@ -227,8 +264,10 @@
 
         try {
             final File probe = buildProbeFile(path);
-            probe.createNewFile();
-            probe.delete();
+            assertTrue(probe.createNewFile());
+            assertTrue(probe.exists());
+            assertTrue(probe.delete());
+            assertFalse(probe.exists());
         } catch (IOException e) {
             fail("failed to create probe!");
         }
@@ -242,21 +281,29 @@
 
         try {
             final File probe = buildProbeFile(path);
-            probe.createNewFile();
-            probe.delete();
+            assertFalse(probe.createNewFile());
+            assertFalse(probe.exists());
+            assertFalse(probe.delete());
             fail("able to create probe!");
         } catch (IOException e) {
             // expected
         }
     }
 
+    public static void assertDirNoWriteAccess(File[] paths) {
+        for (File path : paths) {
+            assertDirNoWriteAccess(path);
+        }
+    }
+
     public static void assertDirNoWriteAccess(File path) {
         Log.d(TAG, "Asserting no write access to " + path);
 
         try {
             final File probe = buildProbeFile(path);
-            probe.createNewFile();
-            probe.delete();
+            assertFalse(probe.createNewFile());
+            assertFalse(probe.exists());
+            assertFalse(probe.delete());
             fail("able to create probe!");
         } catch (IOException e) {
             // expected
diff --git a/hostsidetests/appsecurity/test-apps/ExternalStorageApp/src/com/android/cts/externalstorageapp/GiftTest.java b/hostsidetests/appsecurity/test-apps/ExternalStorageApp/src/com/android/cts/externalstorageapp/GiftTest.java
index e482b2f..14a0180 100644
--- a/hostsidetests/appsecurity/test-apps/ExternalStorageApp/src/com/android/cts/externalstorageapp/GiftTest.java
+++ b/hostsidetests/appsecurity/test-apps/ExternalStorageApp/src/com/android/cts/externalstorageapp/GiftTest.java
@@ -21,26 +21,33 @@
 import static com.android.cts.externalstorageapp.CommonExternalStorageTest.PACKAGE_WRITE;
 import static com.android.cts.externalstorageapp.CommonExternalStorageTest.assertFileNoAccess;
 import static com.android.cts.externalstorageapp.CommonExternalStorageTest.assertFileReadWriteAccess;
-import static com.android.cts.externalstorageapp.CommonExternalStorageTest.buildGiftForPackage;
+import static com.android.cts.externalstorageapp.CommonExternalStorageTest.getAllPackageSpecificGiftPaths;
 import static com.android.cts.externalstorageapp.CommonExternalStorageTest.readInt;
 
 import android.test.AndroidTestCase;
 
 import java.io.File;
+import java.util.List;
 
 public class GiftTest extends AndroidTestCase {
     /**
      * Verify we can read only our gifts.
      */
     public void testGifts() throws Exception {
-        final File none = buildGiftForPackage(getContext(), PACKAGE_NONE);
-        assertFileReadWriteAccess(none);
-        assertEquals(100, readInt(none));
+        final List<File> noneList = getAllPackageSpecificGiftPaths(getContext(), PACKAGE_NONE);
+        for (File none : noneList) {
+            assertFileReadWriteAccess(none);
+            assertEquals(100, readInt(none));
+        }
 
-        final File read = buildGiftForPackage(getContext(), PACKAGE_READ);
-        assertFileNoAccess(read);
+        final List<File> readList = getAllPackageSpecificGiftPaths(getContext(), PACKAGE_READ);
+        for (File read : readList) {
+            assertFileNoAccess(read);
+        }
 
-        final File write = buildGiftForPackage(getContext(), PACKAGE_WRITE);
-        assertFileNoAccess(write);
+        final List<File> writeList = getAllPackageSpecificGiftPaths(getContext(), PACKAGE_WRITE);
+        for (File write : writeList) {
+            assertFileNoAccess(write);
+        }
     }
 }
diff --git a/hostsidetests/appsecurity/test-apps/InstrumentationAppDiffCert/Android.mk b/hostsidetests/appsecurity/test-apps/InstrumentationAppDiffCert/Android.mk
index 4c64204..31dcd58 100644
--- a/hostsidetests/appsecurity/test-apps/InstrumentationAppDiffCert/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/InstrumentationAppDiffCert/Android.mk
@@ -25,6 +25,9 @@
 
 LOCAL_PACKAGE_NAME := CtsInstrumentationAppDiffCert
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 # sign this app with different cert than CtsTargetInstrumentationApp
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey2
 
diff --git a/hostsidetests/appsecurity/test-apps/MultiUserStorageApp/Android.mk b/hostsidetests/appsecurity/test-apps/MultiUserStorageApp/Android.mk
index c37d052..fd4d927 100644
--- a/hostsidetests/appsecurity/test-apps/MultiUserStorageApp/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/MultiUserStorageApp/Android.mk
@@ -25,6 +25,9 @@
 
 LOCAL_PACKAGE_NAME := CtsMultiUserStorageApp
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_DEX_PREOPT := false
 
 include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/PermissionDeclareApp/Android.mk b/hostsidetests/appsecurity/test-apps/PermissionDeclareApp/Android.mk
index 43d3547..e0e900e 100644
--- a/hostsidetests/appsecurity/test-apps/PermissionDeclareApp/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/PermissionDeclareApp/Android.mk
@@ -25,6 +25,9 @@
 
 LOCAL_PACKAGE_NAME := CtsPermissionDeclareApp
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 # sign this app with a different cert than CtsUsePermissionDiffCert
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey1
 
diff --git a/hostsidetests/appsecurity/test-apps/PermissionDeclareAppCompat/Android.mk b/hostsidetests/appsecurity/test-apps/PermissionDeclareAppCompat/Android.mk
index 5109c99..d4567e3 100644
--- a/hostsidetests/appsecurity/test-apps/PermissionDeclareAppCompat/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/PermissionDeclareAppCompat/Android.mk
@@ -25,6 +25,9 @@
 
 LOCAL_PACKAGE_NAME := CtsPermissionDeclareAppCompat
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 # sign this app with a different cert than CtsUsePermissionDiffCert
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey1
 
diff --git a/hostsidetests/appsecurity/test-apps/ReadExternalStorageApp/Android.mk b/hostsidetests/appsecurity/test-apps/ReadExternalStorageApp/Android.mk
index c662d39..adf6a14 100644
--- a/hostsidetests/appsecurity/test-apps/ReadExternalStorageApp/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/ReadExternalStorageApp/Android.mk
@@ -25,6 +25,9 @@
 
 LOCAL_PACKAGE_NAME := CtsReadExternalStorageApp
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_DEX_PREOPT := false
 
 include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/ReadExternalStorageApp/src/com/android/cts/readexternalstorageapp/ReadExternalStorageTest.java b/hostsidetests/appsecurity/test-apps/ReadExternalStorageApp/src/com/android/cts/readexternalstorageapp/ReadExternalStorageTest.java
index 995da90..14df3cf 100644
--- a/hostsidetests/appsecurity/test-apps/ReadExternalStorageApp/src/com/android/cts/readexternalstorageapp/ReadExternalStorageTest.java
+++ b/hostsidetests/appsecurity/test-apps/ReadExternalStorageApp/src/com/android/cts/readexternalstorageapp/ReadExternalStorageTest.java
@@ -19,6 +19,7 @@
 import static com.android.cts.externalstorageapp.CommonExternalStorageTest.assertDirNoWriteAccess;
 import static com.android.cts.externalstorageapp.CommonExternalStorageTest.assertDirReadOnlyAccess;
 import static com.android.cts.externalstorageapp.CommonExternalStorageTest.assertDirReadWriteAccess;
+import static com.android.cts.externalstorageapp.CommonExternalStorageTest.buildCommonChildDirs;
 import static com.android.cts.externalstorageapp.CommonExternalStorageTest.getAllPackageSpecificPaths;
 import static com.android.cts.externalstorageapp.CommonExternalStorageTest.getMountPaths;
 
@@ -60,8 +61,13 @@
             }
 
             // Keep walking up until we leave device
-            while (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState(path))) {
-                assertDirReadOnlyAccess(path);
+            while (path != null) {
+                if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState(path))) {
+                    assertDirReadOnlyAccess(path);
+                } else {
+                    assertDirNoWriteAccess(path);
+                }
+                assertDirNoWriteAccess(buildCommonChildDirs(path));
                 path = path.getParentFile();
             }
         }
@@ -81,7 +87,9 @@
                 final File userPath = new File(path, userId);
 
                 assertDirNoWriteAccess(path);
+                assertDirNoWriteAccess(buildCommonChildDirs(path));
                 assertDirNoWriteAccess(userPath);
+                assertDirNoWriteAccess(buildCommonChildDirs(userPath));
             }
         }
     }
diff --git a/hostsidetests/appsecurity/test-apps/ReadExternalStorageApp/src/com/android/cts/readexternalstorageapp/ReadGiftTest.java b/hostsidetests/appsecurity/test-apps/ReadExternalStorageApp/src/com/android/cts/readexternalstorageapp/ReadGiftTest.java
index e72be77..78bb738 100644
--- a/hostsidetests/appsecurity/test-apps/ReadExternalStorageApp/src/com/android/cts/readexternalstorageapp/ReadGiftTest.java
+++ b/hostsidetests/appsecurity/test-apps/ReadExternalStorageApp/src/com/android/cts/readexternalstorageapp/ReadGiftTest.java
@@ -21,28 +21,35 @@
 import static com.android.cts.externalstorageapp.CommonExternalStorageTest.PACKAGE_WRITE;
 import static com.android.cts.externalstorageapp.CommonExternalStorageTest.assertFileReadOnlyAccess;
 import static com.android.cts.externalstorageapp.CommonExternalStorageTest.assertFileReadWriteAccess;
-import static com.android.cts.externalstorageapp.CommonExternalStorageTest.buildGiftForPackage;
+import static com.android.cts.externalstorageapp.CommonExternalStorageTest.getAllPackageSpecificGiftPaths;
 import static com.android.cts.externalstorageapp.CommonExternalStorageTest.readInt;
 
 import android.test.AndroidTestCase;
 
 import java.io.File;
+import java.util.List;
 
 public class ReadGiftTest extends AndroidTestCase {
     /**
      * Verify we can read all gifts.
      */
     public void testGifts() throws Exception {
-        final File none = buildGiftForPackage(getContext(), PACKAGE_NONE);
-        assertFileReadOnlyAccess(none);
-        assertEquals(100, readInt(none));
+        final List<File> noneList = getAllPackageSpecificGiftPaths(getContext(), PACKAGE_NONE);
+        for (File none : noneList) {
+            assertFileReadOnlyAccess(none);
+            assertEquals(100, readInt(none));
+        }
 
-        final File read = buildGiftForPackage(getContext(), PACKAGE_READ);
-        assertFileReadWriteAccess(read);
-        assertEquals(101, readInt(read));
+        final List<File> readList = getAllPackageSpecificGiftPaths(getContext(), PACKAGE_READ);
+        for (File read : readList) {
+            assertFileReadWriteAccess(read);
+            assertEquals(101, readInt(read));
+        }
 
-        final File write = buildGiftForPackage(getContext(), PACKAGE_WRITE);
-        assertFileReadOnlyAccess(write);
-        assertEquals(102, readInt(write));
+        final List<File> writeList = getAllPackageSpecificGiftPaths(getContext(), PACKAGE_WRITE);
+        for (File write : writeList) {
+            assertFileReadOnlyAccess(write);
+            assertEquals(102, readInt(write));
+        }
     }
 }
diff --git a/hostsidetests/appsecurity/test-apps/SharedUidInstall/Android.mk b/hostsidetests/appsecurity/test-apps/SharedUidInstall/Android.mk
index 05438ef..548e397 100644
--- a/hostsidetests/appsecurity/test-apps/SharedUidInstall/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/SharedUidInstall/Android.mk
@@ -25,6 +25,9 @@
 
 LOCAL_PACKAGE_NAME := CtsSharedUidInstall
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 # sign this app with a different cert than CtsSharedUidInstallDiffCert
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey1
 
diff --git a/hostsidetests/appsecurity/test-apps/SharedUidInstallDiffCert/Android.mk b/hostsidetests/appsecurity/test-apps/SharedUidInstallDiffCert/Android.mk
index eaed910..0f6cd69 100644
--- a/hostsidetests/appsecurity/test-apps/SharedUidInstallDiffCert/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/SharedUidInstallDiffCert/Android.mk
@@ -25,6 +25,9 @@
 
 LOCAL_PACKAGE_NAME := CtsSharedUidInstallDiffCert
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 # sign this app with a different cert than CtsSharedUidInstall
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey2
 
diff --git a/hostsidetests/appsecurity/test-apps/SimpleAppInstall/Android.mk b/hostsidetests/appsecurity/test-apps/SimpleAppInstall/Android.mk
index 01cffdb..a77a172 100644
--- a/hostsidetests/appsecurity/test-apps/SimpleAppInstall/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/SimpleAppInstall/Android.mk
@@ -25,6 +25,9 @@
 
 LOCAL_PACKAGE_NAME := CtsSimpleAppInstall
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 # sign this app with a different cert than CtsSimpleAppInstallDiffCert
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey1
 
diff --git a/hostsidetests/appsecurity/test-apps/SimpleAppInstallDiffCert/Android.mk b/hostsidetests/appsecurity/test-apps/SimpleAppInstallDiffCert/Android.mk
index 032ef57..e478afb 100644
--- a/hostsidetests/appsecurity/test-apps/SimpleAppInstallDiffCert/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/SimpleAppInstallDiffCert/Android.mk
@@ -25,6 +25,9 @@
 
 LOCAL_PACKAGE_NAME := CtsSimpleAppInstallDiffCert
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 # sign this app with a different cert than CtsSimpleAppInstall
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey2
 
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/Android.mk b/hostsidetests/appsecurity/test-apps/SplitApp/Android.mk
index de46dea..e12feec 100644
--- a/hostsidetests/appsecurity/test-apps/SplitApp/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/Android.mk
@@ -27,6 +27,9 @@
 LOCAL_PACKAGE_NAME := CtsSplitApp
 LOCAL_PACKAGE_SPLITS := mdpi-v4 hdpi-v4 xhdpi-v4 xxhdpi-v4 v7 fr de
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_ASSET_DIR := $(LOCAL_PATH)/assets
 
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey1
@@ -52,6 +55,9 @@
 LOCAL_PACKAGE_NAME := CtsSplitAppDiffRevision
 LOCAL_PACKAGE_SPLITS := v7
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_MANIFEST_FILE := revision/AndroidManifest.xml
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey1
 LOCAL_AAPT_FLAGS := --version-code 100 --version-name OneHundredRevisionTwelve --replace-version
@@ -76,6 +82,9 @@
 LOCAL_PACKAGE_NAME := CtsSplitAppDiffVersion
 LOCAL_PACKAGE_SPLITS := v7
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey1
 LOCAL_AAPT_FLAGS := --version-code 101 --version-name OneHundredOne --replace-version
 
@@ -99,6 +108,9 @@
 LOCAL_PACKAGE_NAME := CtsSplitAppDiffCert
 LOCAL_PACKAGE_SPLITS := v7
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey2
 LOCAL_AAPT_FLAGS := --version-code 100 --version-name OneHundred --replace-version
 
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/SplitApp/AndroidManifest.xml
index dba384c..d9dceb8 100644
--- a/hostsidetests/appsecurity/test-apps/SplitApp/AndroidManifest.xml
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/AndroidManifest.xml
@@ -18,6 +18,7 @@
         package="com.android.cts.splitapp">
 
     <uses-permission android:name="android.permission.CAMERA" />
+    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
 
     <application android:label="SplitApp">
         <activity android:name=".MyActivity">
@@ -33,6 +34,16 @@
                 <action android:name="android.intent.action.DATE_CHANGED" />
             </intent-filter>
         </receiver>
+        <receiver android:name=".LockedBootReceiver" android:exported="true" android:directBootAware="true">
+            <intent-filter>
+                <action android:name="android.intent.action.LOCKED_BOOT_COMPLETED" />
+            </intent-filter>
+        </receiver>
+        <receiver android:name=".BootReceiver" android:exported="true">
+            <intent-filter>
+                <action android:name="android.intent.action.BOOT_COMPLETED" />
+            </intent-filter>
+        </receiver>
 
         <uses-library android:name="android.test.runner" />
     </application>
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/feature/Android.mk b/hostsidetests/appsecurity/test-apps/SplitApp/feature/Android.mk
index fbb7764..aea49c6 100644
--- a/hostsidetests/appsecurity/test-apps/SplitApp/feature/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/feature/Android.mk
@@ -28,6 +28,9 @@
 
 LOCAL_MODULE_TAGS := tests
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 featureOf := CtsSplitApp
 featureOfApk := $(call intermediates-dir-for,APPS,$(featureOf))/package.apk
 localRStamp := $(call intermediates-dir-for,APPS,$(LOCAL_PACKAGE_NAME),,COMMON)/src/R.stamp
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/jni/Android.mk b/hostsidetests/appsecurity/test-apps/SplitApp/jni/Android.mk
index 507b13a..b1e2002 100644
--- a/hostsidetests/appsecurity/test-apps/SplitApp/jni/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/jni/Android.mk
@@ -23,4 +23,7 @@
 
 LOCAL_LDLIBS += -llog
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_SHARED_LIBRARY)
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/libs/Android.mk b/hostsidetests/appsecurity/test-apps/SplitApp/libs/Android.mk
index 5053e7d..ba2da56 100644
--- a/hostsidetests/appsecurity/test-apps/SplitApp/libs/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/libs/Android.mk
@@ -1 +1,15 @@
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT 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 $(call all-subdir-makefiles)
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/libs/arm64-v8a/Android.mk b/hostsidetests/appsecurity/test-apps/SplitApp/libs/arm64-v8a/Android.mk
index 9faaba1..51b91a4 100644
--- a/hostsidetests/appsecurity/test-apps/SplitApp/libs/arm64-v8a/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/libs/arm64-v8a/Android.mk
@@ -22,6 +22,9 @@
 
 LOCAL_JAVA_RESOURCE_DIRS := raw
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey1
 LOCAL_AAPT_FLAGS := --version-code 100 --replace-version
 
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/libs/armeabi-v7a/Android.mk b/hostsidetests/appsecurity/test-apps/SplitApp/libs/armeabi-v7a/Android.mk
index 87b32aa..dc1d703 100644
--- a/hostsidetests/appsecurity/test-apps/SplitApp/libs/armeabi-v7a/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/libs/armeabi-v7a/Android.mk
@@ -22,6 +22,9 @@
 
 LOCAL_JAVA_RESOURCE_DIRS := raw
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey1
 LOCAL_AAPT_FLAGS := --version-code 100 --replace-version
 
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/libs/armeabi/Android.mk b/hostsidetests/appsecurity/test-apps/SplitApp/libs/armeabi/Android.mk
index fe289e0..28c2190 100644
--- a/hostsidetests/appsecurity/test-apps/SplitApp/libs/armeabi/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/libs/armeabi/Android.mk
@@ -22,6 +22,9 @@
 
 LOCAL_JAVA_RESOURCE_DIRS := raw
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey1
 LOCAL_AAPT_FLAGS := --version-code 100 --replace-version
 
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/libs/mips/Android.mk b/hostsidetests/appsecurity/test-apps/SplitApp/libs/mips/Android.mk
index d66d674..d1565e6 100644
--- a/hostsidetests/appsecurity/test-apps/SplitApp/libs/mips/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/libs/mips/Android.mk
@@ -22,6 +22,9 @@
 
 LOCAL_JAVA_RESOURCE_DIRS := raw
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey1
 LOCAL_AAPT_FLAGS := --version-code 100 --replace-version
 
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/libs/mips64/Android.mk b/hostsidetests/appsecurity/test-apps/SplitApp/libs/mips64/Android.mk
index 7232324..383030c 100644
--- a/hostsidetests/appsecurity/test-apps/SplitApp/libs/mips64/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/libs/mips64/Android.mk
@@ -22,6 +22,9 @@
 
 LOCAL_JAVA_RESOURCE_DIRS := raw
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey1
 LOCAL_AAPT_FLAGS := --version-code 100 --replace-version
 
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/libs/x86/Android.mk b/hostsidetests/appsecurity/test-apps/SplitApp/libs/x86/Android.mk
index f1cd994..e9e71ee 100644
--- a/hostsidetests/appsecurity/test-apps/SplitApp/libs/x86/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/libs/x86/Android.mk
@@ -22,6 +22,9 @@
 
 LOCAL_JAVA_RESOURCE_DIRS := raw
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey1
 LOCAL_AAPT_FLAGS := --version-code 100 --replace-version
 
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/libs/x86_64/Android.mk b/hostsidetests/appsecurity/test-apps/SplitApp/libs/x86_64/Android.mk
index 521f6f2..87f0e4a 100644
--- a/hostsidetests/appsecurity/test-apps/SplitApp/libs/x86_64/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/libs/x86_64/Android.mk
@@ -22,6 +22,9 @@
 
 LOCAL_JAVA_RESOURCE_DIRS := raw
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey1
 LOCAL_AAPT_FLAGS := --version-code 100 --replace-version
 
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/src/com/android/cts/splitapp/BaseBootReceiver.java b/hostsidetests/appsecurity/test-apps/SplitApp/src/com/android/cts/splitapp/BaseBootReceiver.java
new file mode 100644
index 0000000..1106a41
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/src/com/android/cts/splitapp/BaseBootReceiver.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.splitapp;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.provider.Settings;
+import android.util.Log;
+
+import java.io.File;
+
+public class BaseBootReceiver extends BroadcastReceiver {
+    private static final String TAG = "SplitApp";
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        try {
+            context = context.createDeviceProtectedStorageContext();
+            final File probe = new File(context.getFilesDir(),
+                    getBootCount(context) + "." + intent.getAction());
+            Log.d(TAG, "Touching probe " + probe);
+            probe.createNewFile();
+            exposeFile(probe);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private static int getBootCount(Context context) throws Exception {
+        return Settings.Global.getInt(context.getContentResolver(), Settings.Global.BOOT_COUNT);
+    }
+
+    private static File exposeFile(File file) throws Exception {
+        file.setReadable(true, false);
+        file.setReadable(true, true);
+
+        File dir = file.getParentFile();
+        do {
+            dir.setExecutable(true, false);
+            dir.setExecutable(true, true);
+            dir = dir.getParentFile();
+        } while (dir != null);
+
+        return file;
+    }
+}
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/src/com/android/cts/splitapp/BootReceiver.java b/hostsidetests/appsecurity/test-apps/SplitApp/src/com/android/cts/splitapp/BootReceiver.java
new file mode 100644
index 0000000..150cf1d
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/src/com/android/cts/splitapp/BootReceiver.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.splitapp;
+
+public class BootReceiver extends BaseBootReceiver {
+}
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/src/com/android/cts/splitapp/LockedBootReceiver.java b/hostsidetests/appsecurity/test-apps/SplitApp/src/com/android/cts/splitapp/LockedBootReceiver.java
new file mode 100644
index 0000000..d00f1de
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/src/com/android/cts/splitapp/LockedBootReceiver.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.splitapp;
+
+public class LockedBootReceiver extends BaseBootReceiver {
+}
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/src/com/android/cts/splitapp/MyActivity.java b/hostsidetests/appsecurity/test-apps/SplitApp/src/com/android/cts/splitapp/MyActivity.java
new file mode 100644
index 0000000..9b9f01c
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/src/com/android/cts/splitapp/MyActivity.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.splitapp;
+
+import android.app.Activity;
+
+public class MyActivity extends Activity {
+}
diff --git a/hostsidetests/appsecurity/test-apps/TargetInstrumentationApp/Android.mk b/hostsidetests/appsecurity/test-apps/TargetInstrumentationApp/Android.mk
index f5ac52f..bfedb36 100644
--- a/hostsidetests/appsecurity/test-apps/TargetInstrumentationApp/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/TargetInstrumentationApp/Android.mk
@@ -25,6 +25,9 @@
 
 LOCAL_PACKAGE_NAME := CtsTargetInstrumentationApp
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 # sign this app with different cert than CtsInstrumentationAppDiffCert
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey1
 
diff --git a/hostsidetests/appsecurity/test-apps/TargetInstrumentationApp/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/TargetInstrumentationApp/AndroidManifest.xml
index c51444d..8b15f1f 100644
--- a/hostsidetests/appsecurity/test-apps/TargetInstrumentationApp/AndroidManifest.xml
+++ b/hostsidetests/appsecurity/test-apps/TargetInstrumentationApp/AndroidManifest.xml
@@ -20,5 +20,6 @@
     A simple app used to test that instrumentation cannot target an app signed with a different
     certificate.
     -->
+    <application />
 
 </manifest>
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionApp/Android.mk b/hostsidetests/appsecurity/test-apps/UsePermissionApp/Android.mk
index f91d0c4..4630f1f 100644
--- a/hostsidetests/appsecurity/test-apps/UsePermissionApp/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionApp/Android.mk
@@ -27,6 +27,9 @@
 
 LOCAL_PACKAGE_NAME := CtsUsePermissionApp
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey2
 
 LOCAL_PROGUARD_ENABLED := disabled
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionAppCompat/Android.mk b/hostsidetests/appsecurity/test-apps/UsePermissionAppCompat/Android.mk
index 70b4b0f..8727c43 100644
--- a/hostsidetests/appsecurity/test-apps/UsePermissionAppCompat/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionAppCompat/Android.mk
@@ -27,6 +27,9 @@
 
 LOCAL_PACKAGE_NAME := CtsUsePermissionAppCompat
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey2
 
 LOCAL_PROGUARD_ENABLED := disabled
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionDiffCert/Android.mk b/hostsidetests/appsecurity/test-apps/UsePermissionDiffCert/Android.mk
index 6e0d090..bda6782 100644
--- a/hostsidetests/appsecurity/test-apps/UsePermissionDiffCert/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionDiffCert/Android.mk
@@ -26,6 +26,9 @@
 
 LOCAL_PACKAGE_NAME := CtsUsePermissionDiffCert
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 # sign this app with a different cert than CtsPermissionDeclareApp
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey2
 
diff --git a/hostsidetests/appsecurity/test-apps/WriteExternalStorageApp/Android.mk b/hostsidetests/appsecurity/test-apps/WriteExternalStorageApp/Android.mk
index cdd77e8..0729b66 100644
--- a/hostsidetests/appsecurity/test-apps/WriteExternalStorageApp/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/WriteExternalStorageApp/Android.mk
@@ -23,6 +23,9 @@
 LOCAL_SRC_FILES := $(call all-java-files-under, src) \
     ../ExternalStorageApp/src/com/android/cts/externalstorageapp/CommonExternalStorageTest.java
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_PACKAGE_NAME := CtsWriteExternalStorageApp
 
 LOCAL_DEX_PREOPT := false
diff --git a/hostsidetests/appsecurity/test-apps/WriteExternalStorageApp/src/com/android/cts/writeexternalstorageapp/WriteExternalStorageTest.java b/hostsidetests/appsecurity/test-apps/WriteExternalStorageApp/src/com/android/cts/writeexternalstorageapp/WriteExternalStorageTest.java
index 3861ddf..81cf7b3 100644
--- a/hostsidetests/appsecurity/test-apps/WriteExternalStorageApp/src/com/android/cts/writeexternalstorageapp/WriteExternalStorageTest.java
+++ b/hostsidetests/appsecurity/test-apps/WriteExternalStorageApp/src/com/android/cts/writeexternalstorageapp/WriteExternalStorageTest.java
@@ -16,14 +16,17 @@
 
 package com.android.cts.writeexternalstorageapp;
 
+import static android.test.MoreAsserts.assertNotEqual;
+
 import static com.android.cts.externalstorageapp.CommonExternalStorageTest.PACKAGE_NONE;
 import static com.android.cts.externalstorageapp.CommonExternalStorageTest.TAG;
 import static com.android.cts.externalstorageapp.CommonExternalStorageTest.assertDirNoWriteAccess;
 import static com.android.cts.externalstorageapp.CommonExternalStorageTest.assertDirReadOnlyAccess;
 import static com.android.cts.externalstorageapp.CommonExternalStorageTest.assertDirReadWriteAccess;
+import static com.android.cts.externalstorageapp.CommonExternalStorageTest.buildCommonChildDirs;
 import static com.android.cts.externalstorageapp.CommonExternalStorageTest.buildProbeFile;
 import static com.android.cts.externalstorageapp.CommonExternalStorageTest.deleteContents;
-import static com.android.cts.externalstorageapp.CommonExternalStorageTest.getAllPackageSpecificPaths;
+import static com.android.cts.externalstorageapp.CommonExternalStorageTest.getAllPackageSpecificPathsExceptMedia;
 import static com.android.cts.externalstorageapp.CommonExternalStorageTest.getMountPaths;
 import static com.android.cts.externalstorageapp.CommonExternalStorageTest.getPrimaryPackageSpecificPaths;
 import static com.android.cts.externalstorageapp.CommonExternalStorageTest.getSecondaryPackageSpecificPaths;
@@ -31,7 +34,10 @@
 import static com.android.cts.externalstorageapp.CommonExternalStorageTest.writeInt;
 
 import android.os.Environment;
+import android.os.SystemClock;
+import android.system.Os;
 import android.test.AndroidTestCase;
+import android.text.format.DateUtils;
 import android.util.Log;
 
 import com.android.cts.externalstorageapp.CommonExternalStorageTest;
@@ -224,9 +230,14 @@
                 path = path.getParentFile();
             }
 
-            // Keep walking up until we leave device
-            while (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState(path))) {
-                assertDirReadOnlyAccess(path);
+            // Walk all the way up to root
+            while (path != null) {
+                if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState(path))) {
+                    assertDirReadOnlyAccess(path);
+                } else {
+                    assertDirNoWriteAccess(path);
+                }
+                assertDirNoWriteAccess(buildCommonChildDirs(path));
                 path = path.getParentFile();
             }
         }
@@ -236,10 +247,10 @@
      * Verify that .nomedia is created correctly.
      */
     public void testVerifyNoMediaCreated() throws Exception {
-        for (File file : getAllPackageSpecificPaths(getContext())) {
+        for (File file : getAllPackageSpecificPathsExceptMedia(getContext())) {
             deleteContents(file);
         }
-        final List<File> paths = getAllPackageSpecificPaths(getContext());
+        final List<File> paths = getAllPackageSpecificPathsExceptMedia(getContext());
 
         // Require that .nomedia was created somewhere above each dir
         for (File path : paths) {
@@ -297,4 +308,29 @@
             }
         }
     }
+
+    /**
+     * Verify that moving around package-specific directories causes permissions
+     * to be updated.
+     */
+    public void testMovePackageSpecificPaths() throws Exception {
+        final File before = getContext().getExternalCacheDir();
+        final File beforeFile = new File(before, "test.probe");
+        assertTrue(beforeFile.createNewFile());
+        assertEquals(Os.getuid(), Os.stat(before.getAbsolutePath()).st_uid);
+        assertEquals(Os.getuid(), Os.stat(beforeFile.getAbsolutePath()).st_uid);
+
+        final File after = new File(before.getAbsolutePath()
+                .replace(getContext().getPackageName(), "com.example.does.not.exist"));
+        after.getParentFile().mkdirs();
+
+        Os.rename(before.getAbsolutePath(), after.getAbsolutePath());
+
+        // Sit around long enough for VFS cache to expire
+        SystemClock.sleep(15 * DateUtils.SECOND_IN_MILLIS);
+
+        final File afterFile = new File(after, "test.probe");
+        assertNotEqual(Os.getuid(), Os.stat(after.getAbsolutePath()).st_uid);
+        assertNotEqual(Os.getuid(), Os.stat(afterFile.getAbsolutePath()).st_uid);
+    }
 }
diff --git a/hostsidetests/appsecurity/test-apps/WriteExternalStorageApp/src/com/android/cts/writeexternalstorageapp/WriteGiftTest.java b/hostsidetests/appsecurity/test-apps/WriteExternalStorageApp/src/com/android/cts/writeexternalstorageapp/WriteGiftTest.java
index 5da42da..db3813f 100644
--- a/hostsidetests/appsecurity/test-apps/WriteExternalStorageApp/src/com/android/cts/writeexternalstorageapp/WriteGiftTest.java
+++ b/hostsidetests/appsecurity/test-apps/WriteExternalStorageApp/src/com/android/cts/writeexternalstorageapp/WriteGiftTest.java
@@ -20,41 +20,48 @@
 import static com.android.cts.externalstorageapp.CommonExternalStorageTest.PACKAGE_READ;
 import static com.android.cts.externalstorageapp.CommonExternalStorageTest.PACKAGE_WRITE;
 import static com.android.cts.externalstorageapp.CommonExternalStorageTest.assertFileReadWriteAccess;
-import static com.android.cts.externalstorageapp.CommonExternalStorageTest.buildGiftForPackage;
+import static com.android.cts.externalstorageapp.CommonExternalStorageTest.getAllPackageSpecificGiftPaths;
 import static com.android.cts.externalstorageapp.CommonExternalStorageTest.readInt;
 import static com.android.cts.externalstorageapp.CommonExternalStorageTest.writeInt;
 
 import android.test.AndroidTestCase;
 
 import java.io.File;
+import java.util.List;
 
 public class WriteGiftTest extends AndroidTestCase {
     /**
      * Leave gifts for other packages in their primary external cache dirs.
      */
     public void testGifts() throws Exception {
-        final File none = buildGiftForPackage(getContext(), PACKAGE_NONE);
-        none.getParentFile().mkdirs();
-        none.createNewFile();
-        assertFileReadWriteAccess(none);
+        final List<File> noneList = getAllPackageSpecificGiftPaths(getContext(), PACKAGE_NONE);
+        for (File none : noneList) {
+            none.getParentFile().mkdirs();
+            none.createNewFile();
+            assertFileReadWriteAccess(none);
 
-        writeInt(none, 100);
-        assertEquals(100, readInt(none));
+            writeInt(none, 100);
+            assertEquals(100, readInt(none));
+        }
 
-        final File read = buildGiftForPackage(getContext(), PACKAGE_READ);
-        read.getParentFile().mkdirs();
-        read.createNewFile();
-        assertFileReadWriteAccess(read);
+        final List<File> readList = getAllPackageSpecificGiftPaths(getContext(), PACKAGE_READ);
+        for (File read : readList) {
+            read.getParentFile().mkdirs();
+            read.createNewFile();
+            assertFileReadWriteAccess(read);
 
-        writeInt(read, 101);
-        assertEquals(101, readInt(read));
+            writeInt(read, 101);
+            assertEquals(101, readInt(read));
+        }
 
-        final File write = buildGiftForPackage(getContext(), PACKAGE_WRITE);
-        write.getParentFile().mkdirs();
-        write.createNewFile();
-        assertFileReadWriteAccess(write);
+        final List<File> writeList = getAllPackageSpecificGiftPaths(getContext(), PACKAGE_WRITE);
+        for (File write : writeList) {
+            write.getParentFile().mkdirs();
+            write.createNewFile();
+            assertFileReadWriteAccess(write);
 
-        writeInt(write, 102);
-        assertEquals(102, readInt(write));
+            writeInt(write, 102);
+            assertEquals(102, readInt(write));
+        }
     }
 }
diff --git a/hostsidetests/appsecurity/test-apps/keysets/Android.mk b/hostsidetests/appsecurity/test-apps/keysets/Android.mk
index 935fa95..7f116be 100644
--- a/hostsidetests/appsecurity/test-apps/keysets/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/keysets/Android.mk
@@ -16,6 +16,9 @@
 
 include $(CLEAR_VARS)
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 # Build the test APKs using their own makefiles
 include $(call all-makefiles-under,$(LOCAL_PATH))
 
diff --git a/hostsidetests/appsecurity/test-apps/keysets/malBadKey/Android.mk b/hostsidetests/appsecurity/test-apps/keysets/malBadKey/Android.mk
index 207160f..30384d0 100644
--- a/hostsidetests/appsecurity/test-apps/keysets/malBadKey/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/keysets/malBadKey/Android.mk
@@ -17,6 +17,9 @@
 #apks signed cts-keyset-test-a
 include $(CLEAR_VARS)
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_MODULE_TAGS := tests
 LOCAL_SDK_VERSION := current
 LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
diff --git a/hostsidetests/appsecurity/test-apps/keysets/malNoDef/Android.mk b/hostsidetests/appsecurity/test-apps/keysets/malNoDef/Android.mk
index 84f3f75..da45804 100644
--- a/hostsidetests/appsecurity/test-apps/keysets/malNoDef/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/keysets/malNoDef/Android.mk
@@ -17,6 +17,9 @@
 #apks signed cts-keyset-test-a
 include $(CLEAR_VARS)
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_MODULE_TAGS := tests
 LOCAL_SDK_VERSION := current
 LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
diff --git a/hostsidetests/appsecurity/test-apps/keysets/malOneDef/Android.mk b/hostsidetests/appsecurity/test-apps/keysets/malOneDef/Android.mk
index 7290f06..eea2e11 100644
--- a/hostsidetests/appsecurity/test-apps/keysets/malOneDef/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/keysets/malOneDef/Android.mk
@@ -17,6 +17,9 @@
 #apks signed cts-keyset-test-a
 include $(CLEAR_VARS)
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_MODULE_TAGS := tests
 LOCAL_SDK_VERSION := current
 LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
diff --git a/hostsidetests/appsecurity/test-apps/keysets/permDef/Android.mk b/hostsidetests/appsecurity/test-apps/keysets/permDef/Android.mk
index f5a7286..cefe00f 100644
--- a/hostsidetests/appsecurity/test-apps/keysets/permDef/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/keysets/permDef/Android.mk
@@ -23,6 +23,8 @@
 LOCAL_PACKAGE_NAME := CtsKeySetPermDefSigningA
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-a
 LOCAL_DEX_PREOPT := false
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
 
 include $(BUILD_CTS_SUPPORT_PACKAGE)
 
@@ -35,5 +37,7 @@
 LOCAL_PACKAGE_NAME := CtsKeySetPermDefSigningB
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-b
 LOCAL_DEX_PREOPT := false
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
 
 include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/keysets/permUse/Android.mk b/hostsidetests/appsecurity/test-apps/keysets/permUse/Android.mk
index 678d89d..f031e4b 100644
--- a/hostsidetests/appsecurity/test-apps/keysets/permUse/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/keysets/permUse/Android.mk
@@ -24,6 +24,9 @@
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-a
 LOCAL_DEX_PREOPT := false
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_CTS_SUPPORT_PACKAGE)
 
 #apks signed cts-keyset-test-b
@@ -36,4 +39,7 @@
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-b
 LOCAL_DEX_PREOPT := false
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/keysets/testApp/Android.mk b/hostsidetests/appsecurity/test-apps/keysets/testApp/Android.mk
index b8acc99..d1eeffa 100644
--- a/hostsidetests/appsecurity/test-apps/keysets/testApp/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/keysets/testApp/Android.mk
@@ -16,6 +16,9 @@
 
 include $(CLEAR_VARS)
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_MODULE_TAGS := tests
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 LOCAL_SDK_VERSION := current
diff --git a/hostsidetests/appsecurity/test-apps/keysets/uA/Android.mk b/hostsidetests/appsecurity/test-apps/keysets/uA/Android.mk
index 79d053b..22c45a7 100644
--- a/hostsidetests/appsecurity/test-apps/keysets/uA/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/keysets/uA/Android.mk
@@ -16,13 +16,14 @@
 
 #apks signed by cts-keyset-test-a
 include $(CLEAR_VARS)
-
 LOCAL_MODULE_TAGS := tests
 LOCAL_SDK_VERSION := current
 LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
 LOCAL_PACKAGE_NAME := CtsKeySetSigningAUpgradeA
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-a
 LOCAL_DEX_PREOPT := false
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
 
 include $(BUILD_CTS_SUPPORT_PACKAGE)
 
@@ -34,24 +35,26 @@
 LOCAL_PACKAGE_NAME := CtsKeySetSigningBUpgradeA
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-b
 LOCAL_DEX_PREOPT := false
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
 
 include $(BUILD_CTS_SUPPORT_PACKAGE)
 
 #apks signed by cts-keyset-test-ec-a
 include $(CLEAR_VARS)
-
 LOCAL_MODULE_TAGS := tests
 LOCAL_SDK_VERSION := current
 LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
 LOCAL_PACKAGE_NAME := CtsKeySetSigningEcAUpgradeA
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-ec-a
 LOCAL_DEX_PREOPT := false
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
 
 include $(BUILD_CTS_SUPPORT_PACKAGE)
 
 #apks signed by cts-keyset-test-a and cts-keyset-test-b
 include $(CLEAR_VARS)
-
 LOCAL_MODULE_TAGS := tests
 LOCAL_SDK_VERSION := current
 LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
@@ -59,4 +62,7 @@
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-a
 LOCAL_ADDITIONAL_CERTIFICATES := cts/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-b
 LOCAL_DEX_PREOPT := false
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/keysets/uAB/Android.mk b/hostsidetests/appsecurity/test-apps/keysets/uAB/Android.mk
index 406529c..340e8c7 100644
--- a/hostsidetests/appsecurity/test-apps/keysets/uAB/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/keysets/uAB/Android.mk
@@ -17,6 +17,9 @@
 #apks signed cts-keyset-test-a
 include $(CLEAR_VARS)
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_MODULE_TAGS := tests
 LOCAL_SDK_VERSION := current
 LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
diff --git a/hostsidetests/appsecurity/test-apps/keysets/uAuB/Android.mk b/hostsidetests/appsecurity/test-apps/keysets/uAuB/Android.mk
index 23d6b17..6389bf6 100644
--- a/hostsidetests/appsecurity/test-apps/keysets/uAuB/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/keysets/uAuB/Android.mk
@@ -17,6 +17,9 @@
 #apks signed cts-keyset-test-a
 include $(CLEAR_VARS)
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_MODULE_TAGS := tests
 LOCAL_SDK_VERSION := current
 LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
diff --git a/hostsidetests/appsecurity/test-apps/keysets/uB/Android.mk b/hostsidetests/appsecurity/test-apps/keysets/uB/Android.mk
index f2cedf9..1e888ae 100644
--- a/hostsidetests/appsecurity/test-apps/keysets/uB/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/keysets/uB/Android.mk
@@ -24,6 +24,9 @@
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-a
 LOCAL_DEX_PREOPT := false
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_CTS_SUPPORT_PACKAGE)
 
 #apks signed cts-keyset-test-b
@@ -36,6 +39,9 @@
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-b
 LOCAL_DEX_PREOPT := false
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_CTS_SUPPORT_PACKAGE)
 
 #apks signed by cts-keyset-test-a and cts-keyset-test-c
@@ -49,4 +55,7 @@
 LOCAL_ADDITIONAL_CERTIFICATES := cts/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-c
 LOCAL_DEX_PREOPT := false
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/keysets/uBsharedUser/Android.mk b/hostsidetests/appsecurity/test-apps/keysets/uBsharedUser/Android.mk
index 1d6d5a5..87a7ff8 100644
--- a/hostsidetests/appsecurity/test-apps/keysets/uBsharedUser/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/keysets/uBsharedUser/Android.mk
@@ -24,6 +24,9 @@
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-a
 LOCAL_DEX_PREOPT := false
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_CTS_SUPPORT_PACKAGE)
 
 #apks signed cts-keyset-test-b
@@ -36,4 +39,7 @@
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-b
 LOCAL_DEX_PREOPT := false
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/keysets/uEcA/Android.mk b/hostsidetests/appsecurity/test-apps/keysets/uEcA/Android.mk
index 3d0109a..42f700e 100644
--- a/hostsidetests/appsecurity/test-apps/keysets/uEcA/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/keysets/uEcA/Android.mk
@@ -17,6 +17,9 @@
 #apks signed by cts-keyset-test-a
 include $(CLEAR_VARS)
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_MODULE_TAGS := tests
 LOCAL_SDK_VERSION := current
 LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
diff --git a/hostsidetests/appsecurity/test-apps/keysets/uNone/Android.mk b/hostsidetests/appsecurity/test-apps/keysets/uNone/Android.mk
index 9b327fe..69d27ed 100644
--- a/hostsidetests/appsecurity/test-apps/keysets/uNone/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/keysets/uNone/Android.mk
@@ -17,6 +17,9 @@
 #apks signed cts-keyset-test-a
 include $(CLEAR_VARS)
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_MODULE_TAGS := tests
 LOCAL_SDK_VERSION := current
 LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
diff --git a/hostsidetests/appsecurity/test-apps/tinyapp/Android.mk b/hostsidetests/appsecurity/test-apps/tinyapp/Android.mk
new file mode 100644
index 0000000..15981f6
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/tinyapp/Android.mk
@@ -0,0 +1,28 @@
+# Copyright (C) 2014 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_MODULE_TAGS := tests
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_SDK_VERSION := 23
+LOCAL_PACKAGE_NAME := CtsPkgInstallTinyApp
+LOCAL_DEX_PREOPT := false
+
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/tinyapp/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/tinyapp/AndroidManifest.xml
new file mode 100644
index 0000000..def2931
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/tinyapp/AndroidManifest.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="android.appsecurity.cts.tinyapp"
+        android:versionCode="10"
+        android:versionName="1.0">
+    <application android:label="@string/app_name">
+        <activity
+                android:name=".MainActivity"
+                android:label="@string/app_name" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
diff --git a/hostsidetests/appsecurity/test-apps/tinyapp/res/values/strings.xml b/hostsidetests/appsecurity/test-apps/tinyapp/res/values/strings.xml
new file mode 100644
index 0000000..70d5a95
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/tinyapp/res/values/strings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <string name="app_name">Tiny App for CTS</string>
+</resources>
diff --git a/hostsidetests/appsecurity/test-apps/tinyapp/src/android/appsecurity/cts/tinyapp/MainActivity.java b/hostsidetests/appsecurity/test-apps/tinyapp/src/android/appsecurity/cts/tinyapp/MainActivity.java
new file mode 100644
index 0000000..67a7abc
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/tinyapp/src/android/appsecurity/cts/tinyapp/MainActivity.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.appsecurity.cts.tinyapp;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class MainActivity extends Activity {
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        finish();
+    }
+}
diff --git a/hostsidetests/atrace/Android.mk b/hostsidetests/atrace/Android.mk
index 1fd7102..d0b7ef5 100644
--- a/hostsidetests/atrace/Android.mk
+++ b/hostsidetests/atrace/Android.mk
@@ -23,8 +23,13 @@
 
 LOCAL_JAVA_LIBRARIES := cts-tradefed tradefed-prebuilt
 
+LOCAL_STATIC_JAVA_LIBRARIES := cts-migration-lib
+
 LOCAL_CTS_TEST_PACKAGE := android.host.atrace
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_CTS_HOST_JAVA_LIBRARY)
 
 include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/hostsidetests/atrace/AndroidTest.xml b/hostsidetests/atrace/AndroidTest.xml
new file mode 100644
index 0000000..b8aeb31
--- /dev/null
+++ b/hostsidetests/atrace/AndroidTest.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS atrace host test cases">
+    <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
+        <option name="jar" value="CtsAtraceHostTestCases.jar" />
+    </test>
+</configuration>
diff --git a/hostsidetests/atrace/AtraceTestApp/Android.mk b/hostsidetests/atrace/AtraceTestApp/Android.mk
index 0eb7cfd..9218e56 100644
--- a/hostsidetests/atrace/AtraceTestApp/Android.mk
+++ b/hostsidetests/atrace/AtraceTestApp/Android.mk
@@ -30,4 +30,7 @@
 
 #LOCAL_DEX_PREOPT := false
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/atrace/src/android/atrace/cts/AtraceHostTest.java b/hostsidetests/atrace/src/android/atrace/cts/AtraceHostTest.java
index 760723e..5f5ebe1 100644
--- a/hostsidetests/atrace/src/android/atrace/cts/AtraceHostTest.java
+++ b/hostsidetests/atrace/src/android/atrace/cts/AtraceHostTest.java
@@ -16,7 +16,7 @@
 
 package android.atrace.cts;
 
-import com.android.cts.tradefed.build.CtsBuildHelper;
+import com.android.cts.migration.MigrationHelper;
 import com.android.ddmlib.Log;
 import com.android.tradefed.build.IBuildInfo;
 import com.android.tradefed.device.ITestDevice;
@@ -118,14 +118,14 @@
         }
     }
 
-    private CtsBuildHelper mCtsBuild;
+    private IBuildInfo mCtsBuild;
 
     /**
      * {@inheritDoc}
      */
     @Override
     public void setBuild(IBuildInfo buildInfo) {
-        mCtsBuild = CtsBuildHelper.createBuildHelper(buildInfo);
+        mCtsBuild = buildInfo;
     }
 
     // Collection of all userspace tags, and 'sched'
@@ -201,7 +201,7 @@
             getDevice().uninstallPackage(TEST_PKG);
 
             // install the test app
-            File testAppFile = mCtsBuild.getTestApp(TEST_APK);
+            File testAppFile = MigrationHelper.getTestFile(mCtsBuild, TEST_APK);
             String installResult = getDevice().installPackage(testAppFile, false);
             assertNull(
                     String.format("failed to install atrace test app. Reason: %s", installResult),
diff --git a/hostsidetests/cpptools/Android.mk b/hostsidetests/cpptools/Android.mk
index a4144a6..824dd97 100644
--- a/hostsidetests/cpptools/Android.mk
+++ b/hostsidetests/cpptools/Android.mk
@@ -23,10 +23,13 @@
 # Must match the package name in CtsTestCaseList.mk
 LOCAL_MODULE := CtsCppToolsTestCases
 
-LOCAL_JAVA_LIBRARIES := cts-tradefed ddmlib-prebuilt tradefed-prebuilt
+LOCAL_JAVA_LIBRARIES := old-cts-tradefed ddmlib-prebuilt tradefed-prebuilt
 
 LOCAL_CTS_TEST_PACKAGE := android.tests.cpptools
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_CTS_HOST_JAVA_LIBRARY)
 
 include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/hostsidetests/cpptools/AndroidTest.xml b/hostsidetests/cpptools/AndroidTest.xml
new file mode 100644
index 0000000..582c772
--- /dev/null
+++ b/hostsidetests/cpptools/AndroidTest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS CPP host test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsCppToolsApp.apk" />
+    </target_preparer>
+    <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
+        <option name="jar" value="CtsCppToolsTestCases.jar" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/hostsidetests/cpptools/app/Android.mk b/hostsidetests/cpptools/app/Android.mk
index 238425a..4e4e51f 100644
--- a/hostsidetests/cpptools/app/Android.mk
+++ b/hostsidetests/cpptools/app/Android.mk
@@ -26,6 +26,9 @@
 
 LOCAL_PACKAGE_NAME := CtsCppToolsApp
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_SDK_VERSION := current
 
-include $(BUILD_CTS_PACKAGE)
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/cpptools/app/AndroidManifest.xml b/hostsidetests/cpptools/app/AndroidManifest.xml
index 1748a38..6d4681e 100755
--- a/hostsidetests/cpptools/app/AndroidManifest.xml
+++ b/hostsidetests/cpptools/app/AndroidManifest.xml
@@ -16,11 +16,11 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.sample.app">
+    package="android.cpptools.app">
 
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <application android:debuggable="true">
-        <activity android:name=".SampleDeviceActivity" >
+        <activity android:name=".CppToolsDeviceActivity" >
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.LAUNCHER" />
diff --git a/hostsidetests/cpptools/app/src/android/cpptools/app/CppToolsDeviceActivity.java b/hostsidetests/cpptools/app/src/android/cpptools/app/CppToolsDeviceActivity.java
new file mode 100644
index 0000000..5d5f384
--- /dev/null
+++ b/hostsidetests/cpptools/app/src/android/cpptools/app/CppToolsDeviceActivity.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.cpptools.app;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.util.Log;
+
+import java.lang.Override;
+
+/**
+ * A simple activity which logs to Logcat.
+ */
+public class CppToolsDeviceActivity extends Activity {
+
+    private static final String TAG = CppToolsDeviceActivity.class.getSimpleName();
+
+    /**
+     * The test string to log.
+     */
+    private static final String TEST_STRING = "SampleTestString";
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        // Log the test string to Logcat.
+        Log.i(TAG, TEST_STRING);
+    }
+
+}
diff --git a/hostsidetests/cpptools/app/src/android/sample/app/SampleDeviceActivity.java b/hostsidetests/cpptools/app/src/android/sample/app/SampleDeviceActivity.java
deleted file mode 100644
index d7efc0c..0000000
--- a/hostsidetests/cpptools/app/src/android/sample/app/SampleDeviceActivity.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.sample.app;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.util.Log;
-
-import java.lang.Override;
-
-/**
- * A simple activity which logs to Logcat.
- */
-public class SampleDeviceActivity extends Activity {
-
-    private static final String TAG = SampleDeviceActivity.class.getSimpleName();
-
-    /**
-     * The test string to log.
-     */
-    private static final String TEST_STRING = "SampleTestString";
-
-    @Override
-    public void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-        // Log the test string to Logcat.
-        Log.i(TAG, TEST_STRING);
-    }
-
-}
diff --git a/hostsidetests/cpptools/src/com/android/cts/cpptools/RunAsHostTest.java b/hostsidetests/cpptools/src/com/android/cts/cpptools/RunAsHostTest.java
index 24a3b0c..ae472de 100644
--- a/hostsidetests/cpptools/src/com/android/cts/cpptools/RunAsHostTest.java
+++ b/hostsidetests/cpptools/src/com/android/cts/cpptools/RunAsHostTest.java
@@ -16,69 +16,15 @@
 
 package com.android.cts.cpptools;
 
-import com.android.cts.tradefed.build.CtsBuildHelper;
-import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.device.ITestDevice;
 import com.android.tradefed.testtype.DeviceTestCase;
-import com.android.tradefed.testtype.IBuildReceiver;
 
-import java.io.File;
-import java.lang.String;
-import java.util.Scanner;
 import java.util.regex.Pattern;
 import java.util.regex.Matcher;
 
 /**
  * Test to check the host can execute commands via "adb shell run-as".
  */
-public class RunAsHostTest extends DeviceTestCase implements IBuildReceiver {
-
-    /**
-     * The package name of the APK.
-     */
-    private static final String PACKAGE = "android.sample.app";
-
-    /**
-     * The file name of the APK.
-     */
-    private static final String APK = "CtsCppToolsApp.apk";
-
-    
-    /**
-     * A reference to the build.
-     */
-    private CtsBuildHelper mBuild;
-
-    /**
-     * A reference to the device under test.
-     */
-    private ITestDevice mDevice;
-
-    @Override
-    public void setBuild(IBuildInfo buildInfo) {
-        // Get the build, this is used to access the APK.
-        mBuild = CtsBuildHelper.createBuildHelper(buildInfo);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        // Get the device, this gives a handle to run commands and install APKs.
-        mDevice = getDevice();
-        // Remove any previously installed versions of this APK.
-        mDevice.uninstallPackage(PACKAGE);
-        // Get the APK from the build.
-        File app = mBuild.getTestApp(APK);
-        // Install the APK on the device.
-        mDevice.installPackage(app, false);
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        // Remove the package once complete.
-        mDevice.uninstallPackage(PACKAGE);
-        super.tearDown();
-    }
+public class RunAsHostTest extends DeviceTestCase {
 
     /**
      * Tests that host can execute shell commands as a debuggable app via adb.
@@ -86,7 +32,7 @@
      * @throws Exception
      */
     public void testRunAs() throws Exception {
-        String runAsResult = mDevice.executeShellCommand("run-as android.sample.app id -u");
+        String runAsResult = getDevice().executeShellCommand("run-as android.cpptools.app id -u");
         assertNotNull("adb shell command failed", runAsResult);
         runAsResult = runAsResult.trim();
         Matcher appIdMatcher = Pattern.compile("^uid=([0-9]+).*$").matcher(runAsResult);
diff --git a/hostsidetests/devicepolicy/Android.mk b/hostsidetests/devicepolicy/Android.mk
index dc5e117..2e585d7 100644
--- a/hostsidetests/devicepolicy/Android.mk
+++ b/hostsidetests/devicepolicy/Android.mk
@@ -22,11 +22,14 @@
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
-LOCAL_JAVA_LIBRARIES := tradefed-prebuilt tools-common-prebuilt cts-tradefed
+LOCAL_JAVA_LIBRARIES := tools-common-prebuilt cts-tradefed tradefed-prebuilt
+
+LOCAL_STATIC_JAVA_LIBRARIES := cts-migration-lib
 
 LOCAL_CTS_TEST_PACKAGE := android.adminhostside
 
-cts_runtime_hint := 70
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
 
 include $(BUILD_CTS_HOST_JAVA_LIBRARY)
 
diff --git a/hostsidetests/devicepolicy/AndroidTest.xml b/hostsidetests/devicepolicy/AndroidTest.xml
new file mode 100644
index 0000000..48b3b5b
--- /dev/null
+++ b/hostsidetests/devicepolicy/AndroidTest.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for the CTS Device Policy host tests">
+    <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
+        <option name="jar" value="CtsDevicePolicyManagerTestCases.jar" />
+        <option name="runtime-hint" value="31m41s" />
+    </test>
+</configuration>
diff --git a/hostsidetests/devicepolicy/app/AccountManagement/Android.mk b/hostsidetests/devicepolicy/app/AccountManagement/Android.mk
new file mode 100644
index 0000000..6e70b01
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/AccountManagement/Android.mk
@@ -0,0 +1,34 @@
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_PACKAGE_NAME := CtsAccountManagementDevicePolicyApp
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4 ctstestrunner ub-uiautomator android-support-test
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/devicepolicy/app/AccountManagement/AndroidManifest.xml b/hostsidetests/devicepolicy/app/AccountManagement/AndroidManifest.xml
new file mode 100644
index 0000000..b1e1b53
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/AccountManagement/AndroidManifest.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.cts.devicepolicy.accountmanagement">
+
+    <uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
+    <uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
+
+    <application>
+        <service android:name=".MockAccountService" android:exported="true">
+            <intent-filter>
+                <action android:name="android.accounts.AccountAuthenticator" />
+            </intent-filter>
+
+            <meta-data android:name="android.accounts.AccountAuthenticator"
+                       android:resource="@xml/authenticator" />
+        </service>
+    </application>
+
+    <instrumentation
+        android:name="android.support.test.runner.AndroidJUnitRunner"
+        android:targetPackage="com.android.cts.devicepolicy.accountmanagement"
+        android:label="Account policy CTS Tests" />
+</manifest>
+
diff --git a/hostsidetests/devicepolicy/app/AccountManagement/res/values/strings.xml b/hostsidetests/devicepolicy/app/AccountManagement/res/values/strings.xml
new file mode 100644
index 0000000..dc8bc5d
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/AccountManagement/res/values/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Label for this package -->
+    <string name="authenticator_label">DevicePolicy mock account</string>
+</resources>
diff --git a/hostsidetests/devicepolicy/app/AccountManagement/res/xml/authenticator.xml b/hostsidetests/devicepolicy/app/AccountManagement/res/xml/authenticator.xml
new file mode 100644
index 0000000..9c82b80
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/AccountManagement/res/xml/authenticator.xml
@@ -0,0 +1,22 @@
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- The attributes in this XML file provide configuration information -->
+<!-- for the Account Manager. -->
+
+<account-authenticator xmlns:android="http://schemas.android.com/apk/res/android"
+    android:accountType="com.android.cts.devicepolicy.accountmanagement.account.type"
+    android:label="@string/authenticator_label"
+/>
diff --git a/hostsidetests/devicepolicy/app/AccountManagement/src/com/android/cts/devicepolicy/accountmanagement/AccountManagementTest.java b/hostsidetests/devicepolicy/app/AccountManagement/src/com/android/cts/devicepolicy/accountmanagement/AccountManagementTest.java
new file mode 100644
index 0000000..f91366a
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/AccountManagement/src/com/android/cts/devicepolicy/accountmanagement/AccountManagementTest.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.devicepolicy.accountmanagement;
+
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.accounts.AccountManagerFuture;
+import android.accounts.AuthenticatorException;
+import android.accounts.OperationCanceledException;
+import android.content.Context;
+import android.os.Bundle;
+import android.test.AndroidTestCase;
+
+import java.io.IOException;
+
+/**
+ * Functionality tests for
+ * {@link android.app.admin.DevicePolicyManager#setAccountManagementDisabled}
+ * and (@link android.os.UserManager#DISALLOW_MODIFY_ACCOUNTS}
+ *
+ * This test depend on {@link MockAccountService}, which provides authenticator of type
+ * {@link MockAccountService#ACCOUNT_TYPE}.
+ */
+public class AccountManagementTest extends AndroidTestCase {
+
+    // Account type for MockAccountAuthenticator
+    private final static Account ACCOUNT = new Account("user0",
+            MockAccountAuthenticator.ACCOUNT_TYPE);
+
+    private AccountManager mAccountManager;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mAccountManager = (AccountManager) mContext.getSystemService(Context.ACCOUNT_SERVICE);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        mAccountManager.removeAccountExplicitly(ACCOUNT);
+        assertEquals(0, mAccountManager.getAccountsByType(MockAccountAuthenticator.ACCOUNT_TYPE)
+                .length);
+        super.tearDown();
+    }
+
+    public void testAddAccount_blocked() throws AuthenticatorException,
+            IOException, OperationCanceledException {
+        assertEquals(0, mAccountManager.getAccountsByType(MockAccountAuthenticator.ACCOUNT_TYPE)
+                .length);
+        // Management is disabled, adding account should fail.
+        try {
+            mAccountManager.addAccount(MockAccountAuthenticator.ACCOUNT_TYPE,
+                null, null, null, null, null, null).getResult();
+            fail("Expected OperationCanceledException is not thrown.");
+        } catch (OperationCanceledException e) {
+            // Expected
+        }
+        assertEquals(0, mAccountManager.getAccountsByType(MockAccountAuthenticator.ACCOUNT_TYPE)
+                .length);
+    }
+
+    public void testAddAccount_allowed() throws Exception {
+        Bundle result = mAccountManager.addAccount(MockAccountAuthenticator.ACCOUNT_TYPE,
+                null, null, null, null, null, null).getResult();
+
+        // Normally the expected result of addAccount() is AccountManager returning
+        // an intent to start the authenticator activity for adding new accounts.
+        // But MockAccountAuthenticator returns a new account straightway.
+        assertEquals(MockAccountAuthenticator.ACCOUNT_TYPE,
+                result.getString(AccountManager.KEY_ACCOUNT_TYPE));
+    }
+
+    public void testRemoveAccount_blocked() throws AuthenticatorException,
+            IOException, OperationCanceledException {
+        assertEquals(0, mAccountManager.getAccountsByType(MockAccountAuthenticator.ACCOUNT_TYPE)
+                .length);
+        // First prepare some accounts by manually adding them,
+        // setAccountManagementDisabled(true) should not stop addAccountExplicitly().
+        assertTrue(mAccountManager.addAccountExplicitly(ACCOUNT, "password", null));
+        assertEquals(1, mAccountManager.getAccountsByType(MockAccountAuthenticator.ACCOUNT_TYPE)
+                .length);
+
+        // Removing account should fail, as we just disabled it.
+        try {
+            mAccountManager.removeAccount(ACCOUNT, null, null).getResult();
+            fail("Expected OperationCanceledException is not thrown.");
+        } catch (OperationCanceledException e) {
+            // Expected
+        }
+        // Make sure the removal actually fails.
+        Account[] accounts = mAccountManager.getAccountsByType(
+                MockAccountAuthenticator.ACCOUNT_TYPE);
+        assertEquals(1, accounts.length);
+        assertEquals(ACCOUNT, accounts[0]);
+    }
+
+    public void testRemoveAccount_allowed() throws Exception {
+        assertEquals(0, mAccountManager.getAccountsByType(MockAccountAuthenticator.ACCOUNT_TYPE)
+                .length);
+        // First prepare some accounts by manually adding them,
+        // setAccountManagementDisabled(true) should not stop addAccountExplicitly().
+        assertTrue(mAccountManager.addAccountExplicitly(ACCOUNT, "password", null));
+        assertEquals(1, mAccountManager.getAccountsByType(MockAccountAuthenticator.ACCOUNT_TYPE)
+                .length);
+        assertTrue(mAccountManager.removeAccount(ACCOUNT, null, null).getResult());
+
+        // Make sure the removal actually succeeded.
+        assertEquals(0, mAccountManager.getAccountsByType(MockAccountAuthenticator.ACCOUNT_TYPE)
+                .length);
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/AccountManagement/src/com/android/cts/devicepolicy/accountmanagement/AccountUtilsTest.java b/hostsidetests/devicepolicy/app/AccountManagement/src/com/android/cts/devicepolicy/accountmanagement/AccountUtilsTest.java
new file mode 100644
index 0000000..69945a6
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/AccountManagement/src/com/android/cts/devicepolicy/accountmanagement/AccountUtilsTest.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.devicepolicy.accountmanagement;
+
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.accounts.AccountManagerFuture;
+import android.accounts.AuthenticatorException;
+import android.accounts.OperationCanceledException;
+import android.content.Context;
+import android.os.Bundle;
+import android.test.AndroidTestCase;
+
+import java.io.IOException;
+
+/**
+ * Functionality tests for
+ * {@link android.app.admin.DevicePolicyManager#setAccountManagementDisabled}
+ * and (@link android.os.UserManager#DISALLOW_MODIFY_ACCOUNTS}
+ *
+ * This test depends on {@link MockAccountService}, which provides authenticator of type
+ * {@link MockAccountService#ACCOUNT_TYPE}.
+ */
+public class AccountUtilsTest extends AndroidTestCase {
+
+    // Account type for MockAccountAuthenticator
+    private final static Account ACCOUNT = new Account("user0",
+            MockAccountAuthenticator.ACCOUNT_TYPE);
+
+    private AccountManager mAccountManager;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mAccountManager = (AccountManager) mContext.getSystemService(Context.ACCOUNT_SERVICE);
+    }
+
+    public void testAddAccountExplicitly() throws Exception {
+        assertEquals(0, mAccountManager.getAccountsByType(MockAccountAuthenticator.ACCOUNT_TYPE)
+                .length);
+        assertTrue(mAccountManager.addAccountExplicitly(ACCOUNT, "password", null));
+        assertEquals(1, mAccountManager.getAccountsByType(MockAccountAuthenticator.ACCOUNT_TYPE)
+                .length);
+    }
+
+    public void testRemoveAccountExplicitly() throws Exception {
+        assertEquals(1, mAccountManager.getAccountsByType(MockAccountAuthenticator.ACCOUNT_TYPE)
+                .length);
+        mAccountManager.removeAccountExplicitly(ACCOUNT);
+        assertEquals(0, mAccountManager.getAccountsByType(MockAccountAuthenticator.ACCOUNT_TYPE)
+                .length);
+    }
+}
+
diff --git a/hostsidetests/devicepolicy/app/AccountManagement/src/com/android/cts/devicepolicy/accountmanagement/MockAccountAuthenticator.java b/hostsidetests/devicepolicy/app/AccountManagement/src/com/android/cts/devicepolicy/accountmanagement/MockAccountAuthenticator.java
new file mode 100644
index 0000000..0ef310b
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/AccountManagement/src/com/android/cts/devicepolicy/accountmanagement/MockAccountAuthenticator.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.devicepolicy.accountmanagement;
+
+import android.accounts.AbstractAccountAuthenticator;
+import android.accounts.Account;
+import android.accounts.AccountAuthenticatorResponse;
+import android.accounts.AccountManager;
+import android.accounts.NetworkErrorException;
+import android.content.Context;
+import android.os.Bundle;
+
+/* package */ class MockAccountAuthenticator extends AbstractAccountAuthenticator {
+    private static MockAccountAuthenticator sMockAuthenticator = null;
+    private static final String ACCOUNT_NAME
+            = "com.android.cts.devicepolicy.accountmanagement.account.name";
+    static final String ACCOUNT_TYPE
+            = "com.android.cts.devicepolicy.accountmanagement.account.type";
+    private static final String AUTH_TOKEN = "mockAuthToken";
+    private static final String AUTH_TOKEN_LABEL = "mockAuthTokenLabel";
+
+    private MockAccountAuthenticator(Context context) {
+        super(context);
+    }
+
+    private Bundle createResultBundle() {
+        Bundle result = new Bundle();
+        result.putString(AccountManager.KEY_ACCOUNT_NAME, ACCOUNT_NAME);
+        result.putString(AccountManager.KEY_ACCOUNT_TYPE, ACCOUNT_TYPE);
+        result.putString(AccountManager.KEY_AUTHTOKEN, AUTH_TOKEN);
+
+        return result;
+    }
+
+    @Override
+    public Bundle addAccount(AccountAuthenticatorResponse response, String accountType,
+            String authTokenType, String[] requiredFeatures, Bundle options)
+            throws NetworkErrorException {
+        return createResultBundle();
+    }
+
+    @Override
+    public Bundle editProperties(AccountAuthenticatorResponse response, String accountType) {
+        return createResultBundle();
+    }
+
+    @Override
+    public Bundle updateCredentials(AccountAuthenticatorResponse response, Account account,
+            String authTokenType, Bundle options) throws NetworkErrorException {
+        return createResultBundle();
+    }
+
+    @Override
+    public Bundle confirmCredentials(AccountAuthenticatorResponse response, Account account,
+            Bundle options) throws NetworkErrorException {
+
+        Bundle result = new Bundle();
+        result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, true);
+        return result;
+    }
+
+    @Override
+    public Bundle getAuthToken(AccountAuthenticatorResponse response, Account account,
+            String authTokenType, Bundle options) throws NetworkErrorException {
+        return createResultBundle();
+    }
+
+    @Override
+    public String getAuthTokenLabel(String authTokenType) {
+        return AUTH_TOKEN_LABEL;
+    }
+
+    @Override
+    public Bundle hasFeatures(AccountAuthenticatorResponse response, Account account,
+            String[] features) throws NetworkErrorException {
+
+        Bundle result = new Bundle();
+        result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, true);
+        return result;
+    }
+
+    public static synchronized MockAccountAuthenticator getMockAuthenticator(Context context) {
+        if (null == sMockAuthenticator) {
+            sMockAuthenticator = new MockAccountAuthenticator(context);
+        }
+        return sMockAuthenticator;
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/AccountManagement/src/com/android/cts/devicepolicy/accountmanagement/MockAccountService.java b/hostsidetests/devicepolicy/app/AccountManagement/src/com/android/cts/devicepolicy/accountmanagement/MockAccountService.java
new file mode 100644
index 0000000..ace585b
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/AccountManagement/src/com/android/cts/devicepolicy/accountmanagement/MockAccountService.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.devicepolicy.accountmanagement;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.IBinder;
+
+/**
+ * Service for wrapping the {@link MockAccountAuthenticator}
+ */
+public class MockAccountService extends Service {
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        return MockAccountAuthenticator.getMockAuthenticator(this).getIBinder();
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/AppRestrictionsManagingApp/Android.mk b/hostsidetests/devicepolicy/app/AppRestrictionsManagingApp/Android.mk
new file mode 100644
index 0000000..192ce46
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/AppRestrictionsManagingApp/Android.mk
@@ -0,0 +1,36 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := CtsAppRestrictionsManagingApp
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_JAVA_LIBRARIES := android.test.runner cts-junit
+
+LOCAL_STATIC_JAVA_LIBRARIES = android-support-v4 ctstestrunner android-support-test
+
+LOCAL_SDK_VERSION := current
+
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/devicepolicy/app/AppRestrictionsManagingApp/AndroidManifest.xml b/hostsidetests/devicepolicy/app/AppRestrictionsManagingApp/AndroidManifest.xml
new file mode 100644
index 0000000..4a6f2a5
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/AppRestrictionsManagingApp/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.cts.apprestrictions.managingapp">
+
+    <uses-sdk android:minSdkVersion="24"/>
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="com.android.cts.apprestrictions.managingapp"
+                     android:label="App restrictions managing package CTS Tests"/>
+</manifest>
diff --git a/hostsidetests/devicepolicy/app/AppRestrictionsManagingApp/src/com/android/cts/apprestrictions/managingapp/ApplicationRestrictionsManagerTest.java b/hostsidetests/devicepolicy/app/AppRestrictionsManagingApp/src/com/android/cts/apprestrictions/managingapp/ApplicationRestrictionsManagerTest.java
new file mode 100644
index 0000000..d9b05b9
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/AppRestrictionsManagingApp/src/com/android/cts/apprestrictions/managingapp/ApplicationRestrictionsManagerTest.java
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.apprestrictions.managingapp;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Bundle;
+import android.os.Parcelable;
+import android.os.UserManager;
+import android.test.InstrumentationTestCase;
+import android.test.MoreAsserts;
+
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Tests that a package other than the DPC can manage app restrictions if allowed by the DPC
+ * via {@link DevicePolicyManager#setApplicationRestrictionsManagingPackage(ComponentName, String)}
+ */
+public class ApplicationRestrictionsManagerTest extends InstrumentationTestCase {
+
+    private static final String APP_RESTRICTIONS_TARGET_PKG =
+            "com.android.cts.apprestrictions.targetapp";
+    private static final String APP_RESTRICTIONS_ACTIVITY_NAME =
+            APP_RESTRICTIONS_TARGET_PKG + ".ApplicationRestrictionsActivity";
+    private static final String ACTION_RESTRICTIONS_VALUE =
+            "com.android.cts.apprestrictions.targetapp.RESTRICTIONS_VALUE";
+
+    private static final ComponentName TEST_COMPONENT_NAME = new ComponentName(
+            APP_RESTRICTIONS_TARGET_PKG, ApplicationRestrictionsManagerTest.class.getName());
+
+    private static final Bundle BUNDLE_0 = createBundle0();
+    private static final Bundle BUNDLE_1 = createBundle1();
+
+    private static final long WAIT_FOR_ACTIVITY_TIMEOUT_SECONDS = 10;
+
+    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (ACTION_RESTRICTIONS_VALUE.equals(action)) {
+                mReceivedRestrictions = intent.getBundleExtra("value");
+                mOnRestrictionsSemaphore.release();
+            }
+        }
+    };
+
+    private Context mContext;
+    private DevicePolicyManager mDevicePolicyManager;
+    private UserManager mUserManager;
+    private final Semaphore mOnRestrictionsSemaphore = new Semaphore(0);
+    private Bundle mReceivedRestrictions;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        mContext = getInstrumentation().getContext();
+        mDevicePolicyManager = (DevicePolicyManager)
+                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
+        mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+
+        mContext.registerReceiver(mReceiver, new IntentFilter(ACTION_RESTRICTIONS_VALUE));
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        mContext.unregisterReceiver(mReceiver);
+
+        super.tearDown();
+    }
+
+    public void testCannotManageAppRestrictions() {
+        assertFalse(mDevicePolicyManager.isCallerApplicationRestrictionsManagingPackage());
+        try {
+            mDevicePolicyManager.setApplicationRestrictions(
+                    null, APP_RESTRICTIONS_TARGET_PKG, null);
+            fail("Expected SecurityException not thrown");
+        } catch (SecurityException expected) {
+            MoreAsserts.assertContainsRegex(
+                    "cannot manage application restrictions", expected.getMessage());
+        }
+        try {
+            mDevicePolicyManager.getApplicationRestrictions(null, APP_RESTRICTIONS_TARGET_PKG);
+            fail("Expected SecurityException not thrown");
+        } catch (SecurityException expected) {
+            MoreAsserts.assertContainsRegex(
+                    "cannot manage application restrictions", expected.getMessage());
+        }
+
+        // Should still be able to retrieve our own restrictions via user manager
+        mUserManager.getApplicationRestrictions(mContext.getPackageName());
+    }
+
+    public void testCanManageAppRestrictions() {
+        assertTrue(mDevicePolicyManager.isCallerApplicationRestrictionsManagingPackage());
+        try {
+            mDevicePolicyManager.setApplicationRestrictions(
+                    null, APP_RESTRICTIONS_TARGET_PKG, BUNDLE_0);
+            assertBundle0(mDevicePolicyManager.getApplicationRestrictions(
+                    null, APP_RESTRICTIONS_TARGET_PKG));
+
+            // Check that the target app can retrieve the same restrictions.
+            assertBundle0(waitForChangedRestriction());
+
+            // Test overwriting
+            mDevicePolicyManager.setApplicationRestrictions(
+                    null, APP_RESTRICTIONS_TARGET_PKG, BUNDLE_1);
+            assertBundle1(mDevicePolicyManager.getApplicationRestrictions(
+                    null, APP_RESTRICTIONS_TARGET_PKG));
+            assertBundle1(waitForChangedRestriction());
+        } finally {
+            mDevicePolicyManager.setApplicationRestrictions(
+                    null, APP_RESTRICTIONS_TARGET_PKG, new Bundle());
+            assertTrue(mDevicePolicyManager.getApplicationRestrictions(
+                    null, APP_RESTRICTIONS_TARGET_PKG).isEmpty());
+        }
+    }
+
+    public void testSettingComponentNameThrowsException() {
+        assertTrue(mDevicePolicyManager.isCallerApplicationRestrictionsManagingPackage());
+        try {
+            mDevicePolicyManager.setApplicationRestrictions(
+                    TEST_COMPONENT_NAME, APP_RESTRICTIONS_TARGET_PKG, null);
+            fail("Expected SecurityException not thrown");
+        } catch (SecurityException expected) {
+            MoreAsserts.assertContainsRegex("No active admin", expected.getMessage());
+        }
+        try {
+            mDevicePolicyManager.getApplicationRestrictions(
+                    TEST_COMPONENT_NAME, APP_RESTRICTIONS_TARGET_PKG);
+            fail("Expected SecurityException not thrown");
+        } catch (SecurityException expected) {
+            MoreAsserts.assertContainsRegex("No active admin", expected.getMessage());
+        }
+    }
+
+    // Should be consistent with assertBundle0
+    private static Bundle createBundle0() {
+        Bundle result = new Bundle();
+        result.putString("dummyString", "value");
+        return result;
+    }
+
+    // Should be consistent with createBundle0
+    private void assertBundle0(Bundle bundle) {
+        assertEquals(1, bundle.size());
+        assertEquals("value", bundle.getString("dummyString"));
+    }
+
+    // Should be consistent with assertBundle1
+    private static Bundle createBundle1() {
+        Bundle result = new Bundle();
+        result.putInt("dummyInt", 1);
+        return result;
+    }
+
+    // Should be consistent with createBundle1
+    private void assertBundle1(Bundle bundle) {
+        assertEquals(1, bundle.size());
+        assertEquals(1, bundle.getInt("dummyInt"));
+    }
+
+    private void startTestActivity() {
+        mContext.startActivity(new Intent()
+                .setComponent(new ComponentName(
+                        APP_RESTRICTIONS_TARGET_PKG, APP_RESTRICTIONS_ACTIVITY_NAME))
+                .addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK));
+    }
+
+    private Bundle waitForChangedRestriction() {
+        startTestActivity();
+
+        try {
+            assertTrue(mOnRestrictionsSemaphore.tryAcquire(
+                    WAIT_FOR_ACTIVITY_TIMEOUT_SECONDS, TimeUnit.SECONDS));
+        } catch (InterruptedException e) {
+            fail("waitForChangedRestriction() interrupted");
+        }
+
+        return mReceivedRestrictions;
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/AppRestrictionsTargetApp/Android.mk b/hostsidetests/devicepolicy/app/AppRestrictionsTargetApp/Android.mk
new file mode 100644
index 0000000..9d785c5
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/AppRestrictionsTargetApp/Android.mk
@@ -0,0 +1,32 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := CtsAppRestrictionsTargetApp
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_SDK_VERSION := current
+
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/devicepolicy/app/AppRestrictionsTargetApp/AndroidManifest.xml b/hostsidetests/devicepolicy/app/AppRestrictionsTargetApp/AndroidManifest.xml
new file mode 100644
index 0000000..40f6993
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/AppRestrictionsTargetApp/AndroidManifest.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.cts.apprestrictions.targetapp">
+
+    <uses-sdk android:minSdkVersion="24"/>
+
+    <application>
+        <activity
+            android:name="com.android.cts.apprestrictions.targetapp.ApplicationRestrictionsActivity"
+            android:exported="true">
+        </activity>
+    </application>
+</manifest>
diff --git a/hostsidetests/devicepolicy/app/AppRestrictionsTargetApp/src/com/android/cts/apprestrictions/targetapp/ApplicationRestrictionsActivity.java b/hostsidetests/devicepolicy/app/AppRestrictionsTargetApp/src/com/android/cts/apprestrictions/targetapp/ApplicationRestrictionsActivity.java
new file mode 100644
index 0000000..c44fecd
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/AppRestrictionsTargetApp/src/com/android/cts/apprestrictions/targetapp/ApplicationRestrictionsActivity.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.apprestrictions.targetapp;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.UserManager;
+
+/**
+ * Test activity for {@link android.app.admin.DevicePolicyManager#setApplicationRestrictions}.
+ *
+ * The actual test will set restrictions for this package, and the purpose of this
+ * activity is to retrieve those restrictions and relay them back to the test for validation.
+ */
+public class ApplicationRestrictionsActivity extends Activity {
+
+    private static final String ACTION_RESTRICTIONS_VALUE =
+            "com.android.cts.apprestrictions.targetapp.RESTRICTIONS_VALUE";
+
+    private UserManager mUserManager;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        mUserManager = (UserManager) getSystemService(Context.USER_SERVICE);
+        handleIntent(getIntent());
+    }
+
+    @Override
+    protected void onNewIntent(Intent intent) {
+        super.onNewIntent(intent);
+        handleIntent(intent);
+    }
+
+    private void handleIntent(Intent intent) {
+        Bundle restrictions = mUserManager.getApplicationRestrictions(getPackageName());
+        sendBroadcast(new Intent(ACTION_RESTRICTIONS_VALUE)
+                .addFlags(Intent.FLAG_RECEIVER_FOREGROUND)
+                .putExtra("value", restrictions));
+
+        finish();
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/CertInstaller/Android.mk b/hostsidetests/devicepolicy/app/CertInstaller/Android.mk
index 22a78e2..90c1657 100644
--- a/hostsidetests/devicepolicy/app/CertInstaller/Android.mk
+++ b/hostsidetests/devicepolicy/app/CertInstaller/Android.mk
@@ -28,4 +28,7 @@
 
 LOCAL_SDK_VERSION := current
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/devicepolicy/app/ContactDirectoryProvider/Android.mk b/hostsidetests/devicepolicy/app/ContactDirectoryProvider/Android.mk
new file mode 100644
index 0000000..ef72d61
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/ContactDirectoryProvider/Android.mk
@@ -0,0 +1,37 @@
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+# Don't include this package in any target.
+LOCAL_MODULE_TAGS := optional
+
+# When built, explicitly put it in the data partition.
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_PACKAGE_NAME := CtsContactDirectoryProvider
+
+LOCAL_SDK_VERSION := current
+
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/devicepolicy/app/ContactDirectoryProvider/AndroidManifest.xml b/hostsidetests/devicepolicy/app/ContactDirectoryProvider/AndroidManifest.xml
new file mode 100644
index 0000000..234cc60
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/ContactDirectoryProvider/AndroidManifest.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.cts.contactdirectoryprovider">
+
+    <uses-permission android:name="android.permission.READ_CONTACTS"/>
+    <uses-permission android:name="android.permission.WRITE_CONTACTS"/>
+
+    <application>
+        <provider
+            android:name=".DirectoryProvider"
+            android:authorities="com.android.cts.contact.directory.provider"
+            android:readPermission="android.permission.READ_CONTACTS"
+            android:multiprocess="false"
+            android:exported="true"
+            >
+          <meta-data
+              android:name="android.content.ContactDirectory"
+              android:value="true"/>
+        </provider>
+    </application>
+
+</manifest>
diff --git a/hostsidetests/devicepolicy/app/ContactDirectoryProvider/res/raw/managed_photo.png b/hostsidetests/devicepolicy/app/ContactDirectoryProvider/res/raw/managed_photo.png
new file mode 100644
index 0000000..ec1b33f
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/ContactDirectoryProvider/res/raw/managed_photo.png
Binary files differ
diff --git a/hostsidetests/devicepolicy/app/ContactDirectoryProvider/res/raw/managed_thumbnail.png b/hostsidetests/devicepolicy/app/ContactDirectoryProvider/res/raw/managed_thumbnail.png
new file mode 100644
index 0000000..c903fd1
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/ContactDirectoryProvider/res/raw/managed_thumbnail.png
Binary files differ
diff --git a/hostsidetests/devicepolicy/app/ContactDirectoryProvider/res/raw/primary_photo.png b/hostsidetests/devicepolicy/app/ContactDirectoryProvider/res/raw/primary_photo.png
new file mode 100644
index 0000000..2272d47
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/ContactDirectoryProvider/res/raw/primary_photo.png
Binary files differ
diff --git a/hostsidetests/devicepolicy/app/ContactDirectoryProvider/res/raw/primary_thumbnail.png b/hostsidetests/devicepolicy/app/ContactDirectoryProvider/res/raw/primary_thumbnail.png
new file mode 100644
index 0000000..e5aa7db
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/ContactDirectoryProvider/res/raw/primary_thumbnail.png
Binary files differ
diff --git a/hostsidetests/devicepolicy/app/ContactDirectoryProvider/res/values/strings.xml b/hostsidetests/devicepolicy/app/ContactDirectoryProvider/res/values/strings.xml
new file mode 100644
index 0000000..fe0ec10
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/ContactDirectoryProvider/res/values/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Label for this package -->
+    <string name="directory_resource_id">Android CTS</string>
+</resources>
\ No newline at end of file
diff --git a/hostsidetests/devicepolicy/app/ContactDirectoryProvider/src/com/android/cts/contactdirectoryprovider/DirectoryProvider.java b/hostsidetests/devicepolicy/app/ContactDirectoryProvider/src/com/android/cts/contactdirectoryprovider/DirectoryProvider.java
new file mode 100644
index 0000000..b57a91a
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/ContactDirectoryProvider/src/com/android/cts/contactdirectoryprovider/DirectoryProvider.java
@@ -0,0 +1,246 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.contactdirectoryprovider;
+
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.UriMatcher;
+import android.content.res.AssetFileDescriptor;
+import android.content.res.Resources;
+import android.database.Cursor;
+import android.database.MatrixCursor;
+import android.net.Uri;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.ParcelFileDescriptor;
+import android.provider.ContactsContract.Contacts;
+import android.provider.ContactsContract.Directory;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.concurrent.Callable;
+import java.util.concurrent.TimeUnit;
+
+public class DirectoryProvider extends ContentProvider {
+    private static final String CONFIG_NAME = "config";
+    private static final String SET_CUSTOM_PREFIX = "set_prefix";
+    private static final String AUTHORITY = "com.android.cts.contact.directory.provider";
+    // Same as com.android.cts.managedprofile.AccountAuthenticator.ACCOUNT_TYPE
+    private static final String TEST_ACCOUNT_TYPE = "com.android.cts.test";
+    private static final String DEFAULT_DISPLAY_NAME = "Directory";
+    private static final String DEFAULT_CONTACT_NAME = "DirectoryContact";
+
+    private static final Uri AUTHORITY_URI = Uri.parse("content://" + AUTHORITY);
+    private static final String PRIMARY_THUMBNAIL = "photo/primary_thumbnail";
+    private static final String PRIMARY_PHOTO = "photo/primary_photo";
+    private static final String MANAGED_THUMBNAIL = "photo/managed_thumbnail";
+    private static final String MANAGED_PHOTO = "photo/managed_photo";
+    private static final Uri PRIMARY_THUMBNAIL_URI = Uri.withAppendedPath(AUTHORITY_URI,
+            PRIMARY_THUMBNAIL);
+    private static final Uri PRIMARY_PHOTO_URI = Uri.withAppendedPath(AUTHORITY_URI,
+            PRIMARY_PHOTO);
+    private static final Uri MANAGED_THUMBNAIL_URI = Uri.withAppendedPath(AUTHORITY_URI,
+            MANAGED_THUMBNAIL);
+    private static final Uri MANAGED_PHOTO_URI = Uri.withAppendedPath(AUTHORITY_URI,
+            MANAGED_PHOTO);
+
+    private static final int GAL_BASE = 0;
+    private static final int GAL_DIRECTORIES = GAL_BASE;
+    private static final int GAL_FILTER = GAL_BASE + 1;
+    private static final int GAL_CONTACT = GAL_BASE + 2;
+    private static final int GAL_CONTACT_WITH_ID = GAL_BASE + 3;
+    private static final int GAL_EMAIL_FILTER = GAL_BASE + 4;
+    private static final int GAL_PHONE_FILTER = GAL_BASE + 5;
+    private static final int GAL_PHONE_LOOKUP = GAL_BASE + 6;
+    private static final int GAL_CALLABLES_FILTER = GAL_BASE + 7;
+    private static final int GAL_EMAIL_LOOKUP = GAL_BASE + 8;
+    private static final int GAL_PRIMARY_THUMBNAIL = GAL_BASE + 9;
+    private static final int GAL_PRIMARY_PHOTO = GAL_BASE + 10;
+    private static final int GAL_MANAGED_THUMBNAIL = GAL_BASE + 11;
+    private static final int GAL_MANAGED_PHOTO = GAL_BASE + 12;
+
+    private final UriMatcher mURIMatcher = new UriMatcher(UriMatcher.NO_MATCH);
+
+    private SharedPreferences mSharedPrefs;
+
+    @Override
+    public boolean onCreate() {
+        mURIMatcher.addURI(AUTHORITY, "directories", GAL_DIRECTORIES);
+        mURIMatcher.addURI(AUTHORITY, "contacts/filter/*", GAL_FILTER);
+        mURIMatcher.addURI(AUTHORITY, "contacts/lookup/*/entities", GAL_CONTACT);
+        mURIMatcher.addURI(AUTHORITY, "contacts/lookup/*/#/entities", GAL_CONTACT_WITH_ID);
+        mURIMatcher.addURI(AUTHORITY, "data/emails/filter/*", GAL_EMAIL_FILTER);
+        mURIMatcher.addURI(AUTHORITY, "data/phones/filter/*", GAL_PHONE_FILTER);
+        mURIMatcher.addURI(AUTHORITY, "phone_lookup/*", GAL_PHONE_LOOKUP);
+        mURIMatcher.addURI(AUTHORITY, "data/callables/filter/*", GAL_CALLABLES_FILTER);
+        mURIMatcher.addURI(AUTHORITY, "data/emails/lookup/*", GAL_EMAIL_LOOKUP);
+        mURIMatcher.addURI(AUTHORITY, PRIMARY_THUMBNAIL, GAL_PRIMARY_THUMBNAIL);
+        mURIMatcher.addURI(AUTHORITY, PRIMARY_PHOTO, GAL_PRIMARY_PHOTO);
+        mURIMatcher.addURI(AUTHORITY, MANAGED_THUMBNAIL, GAL_MANAGED_THUMBNAIL);
+        mURIMatcher.addURI(AUTHORITY, MANAGED_PHOTO, GAL_MANAGED_PHOTO);
+        mSharedPrefs = getContext().getSharedPreferences(CONFIG_NAME, Context.MODE_PRIVATE);
+        return true;
+    }
+
+    @Override
+    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
+            String sortOrder) {
+
+        final String prefix = getPrefix();
+        final int match = mURIMatcher.match(uri);
+        switch (match) {
+            case GAL_DIRECTORIES: {
+                final MatrixCursor cursor = new MatrixCursor(projection);
+                final AccountManager am = getContext().getSystemService(AccountManager.class);
+                Account[] accounts = am.getAccountsByType(TEST_ACCOUNT_TYPE);
+                if (accounts != null) {
+                    for (Account account : accounts) {
+                        final Object[] row = new Object[projection.length];
+                        for (int i = 0; i < projection.length; i++) {
+                            final String column = projection[i];
+                            if (column.equals(Directory.ACCOUNT_NAME)) {
+                                row[i] = account.name;
+                            } else if (column.equals(Directory.ACCOUNT_TYPE)) {
+                                row[i] = TEST_ACCOUNT_TYPE;
+                            } else if (column.equals(Directory.TYPE_RESOURCE_ID)) {
+                                row[i] = R.string.directory_resource_id;
+                            } else if (column.equals(Directory.DISPLAY_NAME)) {
+                                row[i] = prefix + DEFAULT_DISPLAY_NAME;
+                            } else if (column.equals(Directory.EXPORT_SUPPORT)) {
+                                row[i] = Directory.EXPORT_SUPPORT_SAME_ACCOUNT_ONLY;
+                            } else if (column.equals(Directory.SHORTCUT_SUPPORT)) {
+                                row[i] = Directory.SHORTCUT_SUPPORT_NONE;
+                            }
+                        }
+                        cursor.addRow(row);
+                    }
+                }
+                return cursor;
+            }
+            case GAL_FILTER:
+            case GAL_CONTACT:
+            case GAL_CONTACT_WITH_ID:
+            case GAL_EMAIL_FILTER:
+            case GAL_PHONE_FILTER:
+            case GAL_PHONE_LOOKUP:
+            case GAL_CALLABLES_FILTER:
+            case GAL_EMAIL_LOOKUP: {
+                // TODO: Add all CTS tests for these APIs
+                final MatrixCursor cursor = new MatrixCursor(projection);
+                final Object[] row = new Object[projection.length];
+                for (int i = 0; i < projection.length; i++) {
+                    String column = projection[i];
+                    if (column.equals(Contacts._ID)) {
+                        row[i] = -1;
+                    } else if (column.equals(Contacts.DISPLAY_NAME)) {
+                        row[i] = prefix + DEFAULT_CONTACT_NAME;
+
+                    } else if (column.equals(Contacts.PHOTO_THUMBNAIL_URI)) {
+                        row[i] = isManagedProfile() ? MANAGED_THUMBNAIL_URI.toString()
+                                : PRIMARY_THUMBNAIL_URI.toString();
+                    } else if (column.equals(Contacts.PHOTO_URI)) {
+                        row[i] = isManagedProfile() ? MANAGED_PHOTO_URI.toString()
+                                : PRIMARY_PHOTO_URI.toString();
+                    } else {
+                        row[i] = null;
+                    }
+                }
+                cursor.addRow(row);
+                return cursor;
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public String getType(Uri uri) {
+        return null;
+    }
+
+    @Override
+    public int delete(Uri uri, String selection, String[] selectionArgs) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Uri insert(Uri uri, ContentValues values) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Bundle call(String method, String arg, Bundle extras) {
+        // Set custom display name, so primary directory and corp directory will have different
+        // display name
+        if (method.equals(SET_CUSTOM_PREFIX)) {
+            mSharedPrefs.edit().putString(SET_CUSTOM_PREFIX, arg).apply();
+            // Force update the content in CP2
+            final long token = Binder.clearCallingIdentity();
+            getContext().getContentResolver().update(Directory.CONTENT_URI, new ContentValues(),
+                    null, null);
+            Binder.restoreCallingIdentity(token);
+        }
+        return new Bundle();
+    }
+
+    @Override
+    public AssetFileDescriptor openAssetFile(final Uri uri, String mode) {
+        if (!mode.equals("r")) {
+            throw new IllegalArgumentException("mode must be \"r\"");
+        }
+
+        final int match = mURIMatcher.match(uri);
+        final int resId;
+        switch (match) {
+            case GAL_PRIMARY_THUMBNAIL:
+                resId = isManagedProfile() ? 0 : R.raw.primary_thumbnail;
+                break;
+            case GAL_PRIMARY_PHOTO:
+                resId = isManagedProfile() ? 0 : R.raw.primary_photo;
+                break;
+            case GAL_MANAGED_THUMBNAIL:
+                resId = isManagedProfile() ? R.raw.managed_thumbnail : 0;
+                break;
+            case GAL_MANAGED_PHOTO:
+                resId = isManagedProfile() ? R.raw.managed_photo : 0;
+                break;
+            default:
+                resId = 0;
+                break;
+        }
+
+        return resId == 0 ? null : getContext().getResources().openRawResourceFd(resId);
+    }
+
+    private String getPrefix() {
+        return mSharedPrefs.getString(SET_CUSTOM_PREFIX, "");
+    }
+
+    private boolean isManagedProfile() {
+        return "Managed".equals(getPrefix());
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/CustomizationApp/Android.mk b/hostsidetests/devicepolicy/app/CustomizationApp/Android.mk
new file mode 100644
index 0000000..7b29bd4
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/CustomizationApp/Android.mk
@@ -0,0 +1,33 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_PACKAGE_NAME := CtsCustomizationApp
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-test ctsdeviceutil
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_PACKAGE)
\ No newline at end of file
diff --git a/hostsidetests/devicepolicy/app/CustomizationApp/AndroidManifest.xml b/hostsidetests/devicepolicy/app/CustomizationApp/AndroidManifest.xml
new file mode 100644
index 0000000..f638adf
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/CustomizationApp/AndroidManifest.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.cts.customizationapp">
+
+    <uses-sdk android:minSdkVersion="24"/>
+
+    <uses-permission android:name="android.permission.SET_WALLPAPER" />
+
+    <application>
+    </application>
+
+    <instrumentation
+        android:name="android.support.test.runner.AndroidJUnitRunner"
+        android:targetPackage="com.android.cts.customizationapp"
+        android:label="Customization CTS Tests" />
+
+</manifest>
diff --git a/hostsidetests/devicepolicy/app/CustomizationApp/res/raw/wallpaper.png b/hostsidetests/devicepolicy/app/CustomizationApp/res/raw/wallpaper.png
new file mode 100644
index 0000000..6a2f3ba
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/CustomizationApp/res/raw/wallpaper.png
Binary files differ
diff --git a/hostsidetests/devicepolicy/app/CustomizationApp/src/com/android/cts/customizationapp/CustomizationTest.java b/hostsidetests/devicepolicy/app/CustomizationApp/src/com/android/cts/customizationapp/CustomizationTest.java
new file mode 100644
index 0000000..11d8c78
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/CustomizationApp/src/com/android/cts/customizationapp/CustomizationTest.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.customizationapp;
+
+import android.app.WallpaperManager;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.os.UserManager;
+import android.test.AndroidTestCase;
+
+import android.cts.util.BitmapUtils;
+import com.android.cts.customizationapp.R;
+
+/**
+ * Test class to check different restrictions, that are connected to the device customization.
+ * The test verifies that non-admin app can't circumvent restriction. The tested restriction is
+ * {@link UserManager#DISALLOW_SET_WALLPAPER}. There is no non-admin API for setting the user icon,
+ * that would allow to test {@link UserManager#DISALLOW_SET_USER_ICON} restriction in this test.
+ */
+public class CustomizationTest extends AndroidTestCase {
+    private static final int WAITING_TIME_MS = 3 * 1000;
+
+    public void testSetWallpaper_disallowed() throws Exception {
+        final WallpaperManager wallpaperManager = WallpaperManager.getInstance(mContext);
+        final Bitmap originalWallpaper = BitmapUtils.getWallpaperBitmap(mContext);
+        final Bitmap referenceWallpaper = BitmapUtils.generateRandomBitmap(97, 73);
+        final UserManager userManager =
+                (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+        assertTrue(userManager.hasUserRestriction(UserManager.DISALLOW_SET_WALLPAPER));
+
+        // Checking setBitmap() method.
+        wallpaperManager.setBitmap(referenceWallpaper);
+        Thread.sleep(WAITING_TIME_MS);
+        Bitmap newWallpaper = BitmapUtils.getWallpaperBitmap(mContext);
+        assertTrue(BitmapUtils.compareBitmaps(newWallpaper, originalWallpaper));
+
+        // Checking setStream() method.
+        wallpaperManager.setStream(BitmapUtils.bitmapToInputStream(referenceWallpaper));
+        Thread.sleep(WAITING_TIME_MS);
+        newWallpaper = BitmapUtils.getWallpaperBitmap(mContext);
+        assertTrue(BitmapUtils.compareBitmaps(newWallpaper, originalWallpaper));
+
+        // Checking setResource() method.
+        wallpaperManager.setResource(R.raw.wallpaper);
+        Thread.sleep(WAITING_TIME_MS);
+        newWallpaper = BitmapUtils.getWallpaperBitmap(mContext);
+        assertTrue(BitmapUtils.compareBitmaps(newWallpaper, originalWallpaper));
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceAdmin/Android.mk b/hostsidetests/devicepolicy/app/DeviceAdmin/Android.mk
new file mode 100644
index 0000000..31e193d
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAdmin/Android.mk
@@ -0,0 +1,20 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+# Build the test APKs using their own makefiles
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/hostsidetests/devicepolicy/app/DeviceAdmin/api23/Android.mk b/hostsidetests/devicepolicy/app/DeviceAdmin/api23/Android.mk
new file mode 100644
index 0000000..46d9cc0
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAdmin/api23/Android.mk
@@ -0,0 +1,36 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := CtsDeviceAdminApp23
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, ../src)
+
+LOCAL_RESOURCE_DIR += $(LOCAL_PATH)/../res
+
+LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner compatibility-device-util
+
+LOCAL_SDK_VERSION := current
+
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/devicepolicy/app/DeviceAdmin/api23/AndroidManifest.xml b/hostsidetests/devicepolicy/app/DeviceAdmin/api23/AndroidManifest.xml
new file mode 100644
index 0000000..7cd3576
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAdmin/api23/AndroidManifest.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="com.android.cts.deviceadmin23" >
+
+    <uses-sdk android:minSdkVersion="23" android:targetSdkVersion="23"/>
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+        <receiver
+                android:name="com.android.cts.deviceadmin.BaseDeviceAdminTest$AdminReceiver"
+                android:permission="android.permission.BIND_DEVICE_ADMIN"
+                >
+            <meta-data android:name="android.app.device_admin"
+                    android:resource="@xml/device_admin" />
+            <intent-filter>
+                <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
+            </intent-filter>
+        </receiver>
+
+        <receiver
+                android:name="com.android.cts.deviceadmin.DeviceAdminReceiverWithNoProtection"
+                >
+            <meta-data android:name="android.app.device_admin"
+                    android:resource="@xml/device_admin" />
+            <intent-filter>
+                <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
+            </intent-filter>
+        </receiver>
+
+    </application>
+
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+            android:targetPackage="com.android.cts.deviceadmin23"
+            android:label="Device Admin CTS tests"/>
+</manifest>
diff --git a/hostsidetests/devicepolicy/app/DeviceAdmin/api24/Android.mk b/hostsidetests/devicepolicy/app/DeviceAdmin/api24/Android.mk
new file mode 100644
index 0000000..9afaa7a
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAdmin/api24/Android.mk
@@ -0,0 +1,36 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := CtsDeviceAdminApp24
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, ../src)
+
+LOCAL_RESOURCE_DIR += $(LOCAL_PATH)/../res
+
+LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner compatibility-device-util
+
+LOCAL_SDK_VERSION := current
+
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/devicepolicy/app/DeviceAdmin/api24/AndroidManifest.xml b/hostsidetests/devicepolicy/app/DeviceAdmin/api24/AndroidManifest.xml
new file mode 100644
index 0000000..da36c8b
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAdmin/api24/AndroidManifest.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="com.android.cts.deviceadmin24" >
+
+    <uses-sdk android:minSdkVersion="23" android:targetSdkVersion="24"/>
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+        <receiver
+                android:name="com.android.cts.deviceadmin.BaseDeviceAdminTest$AdminReceiver"
+                android:permission="android.permission.BIND_DEVICE_ADMIN"
+                >
+            <meta-data android:name="android.app.device_admin"
+                    android:resource="@xml/device_admin" />
+            <intent-filter>
+                <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
+            </intent-filter>
+        </receiver>
+
+        <receiver
+                android:name="com.android.cts.deviceadmin.DeviceAdminReceiverWithNoProtection"
+                >
+            <meta-data android:name="android.app.device_admin"
+                    android:resource="@xml/device_admin" />
+            <intent-filter>
+                <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
+            </intent-filter>
+        </receiver>
+
+    </application>
+
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+            android:targetPackage="com.android.cts.deviceadmin24"
+            android:label="Device Admin CTS tests"/>
+</manifest>
diff --git a/hostsidetests/devicepolicy/app/DeviceAdmin/res/xml/device_admin.xml b/hostsidetests/devicepolicy/app/DeviceAdmin/res/xml/device_admin.xml
new file mode 100644
index 0000000..8eb7ceb
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAdmin/res/xml/device_admin.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<device-admin xmlns:android="http://schemas.android.com/apk/res/android" android:visible="false">
+    <uses-policies>
+        <reset-password />
+        <limit-password />
+        <wipe-data />
+        <expire-password />
+        <watch-login />
+    </uses-policies>
+</device-admin>
diff --git a/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/BaseDeviceAdminTest.java b/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/BaseDeviceAdminTest.java
new file mode 100644
index 0000000..22eab0b
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/BaseDeviceAdminTest.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.deviceadmin;
+
+import android.app.admin.DeviceAdminReceiver;
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.os.Build;
+import android.test.AndroidTestCase;
+
+public class BaseDeviceAdminTest extends AndroidTestCase {
+
+    public static class AdminReceiver extends DeviceAdminReceiver {
+    }
+
+    protected String mPackageName;
+    protected ComponentName mAdminComponent;
+
+    public DevicePolicyManager dpm;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        dpm = mContext.getSystemService(DevicePolicyManager.class);
+        mPackageName = mContext.getPackageName();
+        mAdminComponent = new ComponentName(mContext, AdminReceiver.class);
+    }
+
+    /**
+     * @return the target API level.  Note we don't get it from the package manager information
+     * but we just parse the last two digits of the package name.  This is to catch a potential
+     * issue where we forget to change the target API level in the manifest.  (Conversely,
+     * if we forget to change the package name, we'll catch that in the caller side.)
+     */
+    protected int getTargetApiLevel() {
+        final String packageName = mContext.getPackageName();
+        return Integer.parseInt(packageName.substring(packageName.length() - 2));
+    }
+
+    protected boolean isDeviceOwner() {
+        return dpm.isDeviceOwnerApp(mAdminComponent.getPackageName());
+    }
+
+    protected void assertDeviceOwner() {
+        assertTrue("Not device owner", isDeviceOwner());
+    }
+
+    protected void assertNotDeviceOwner() {
+        assertFalse("Must not be device owner", isDeviceOwner());
+    }
+
+    protected void assertNotActiveAdmin() throws Exception {
+        for (int i = 0; i < 1000 && dpm.isAdminActive(mAdminComponent); i++) {
+            Thread.sleep(10);
+        }
+        assertFalse("Still active admin", dpm.isAdminActive(mAdminComponent));
+    }
+
+    protected boolean shouldResetPasswordThrow() {
+        return getTargetApiLevel() > Build.VERSION_CODES.M;
+    }
+
+    protected void resetComplexPasswordRestrictions() {
+        dpm.setPasswordMinimumLength(mAdminComponent, 0);
+        dpm.setPasswordMinimumUpperCase(mAdminComponent, 0);
+        dpm.setPasswordMinimumLowerCase(mAdminComponent, 0);
+        dpm.setPasswordMinimumLetters(mAdminComponent, 0);
+        dpm.setPasswordMinimumNumeric(mAdminComponent, 0);
+        dpm.setPasswordMinimumSymbols(mAdminComponent, 0);
+        dpm.setPasswordMinimumNonLetter(mAdminComponent, 0);
+    }
+
+    protected void clearPassword() {
+        assertDeviceOwner();
+
+        resetComplexPasswordRestrictions();
+
+        dpm.setPasswordQuality(mAdminComponent, DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED);
+        assertTrue(dpm.resetPassword("", /* flags =*/ 0));
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/ClearDeviceAdminTest.java b/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/ClearDeviceAdminTest.java
new file mode 100644
index 0000000..3832c4c
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/ClearDeviceAdminTest.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.deviceadmin;
+
+import android.app.admin.DevicePolicyManager;
+import android.test.AndroidTestCase;
+
+/**
+ * Remove myself as active admin.
+ */
+public class ClearDeviceAdminTest extends BaseDeviceAdminTest {
+
+    public void testRemoveActiveAdmin() throws Exception {
+        if (dpm.isAdminActive(mAdminComponent)) {
+            dpm.removeActiveAdmin(mAdminComponent);
+        }
+
+        assertNotActiveAdmin();
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/ClearDeviceAdminWithNoProtectionTest.java b/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/ClearDeviceAdminWithNoProtectionTest.java
new file mode 100644
index 0000000..3bfa905
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/ClearDeviceAdminWithNoProtectionTest.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.deviceadmin;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.test.AndroidTestCase;
+
+/**
+ * Remove {@link DeviceAdminReceiverWithNoProtection} as active admin.
+ */
+public class ClearDeviceAdminWithNoProtectionTest extends AndroidTestCase {
+
+    public void testRemoveActiveAdmin() throws Exception {
+
+        final ComponentName cn = new ComponentName(getContext(),
+                DeviceAdminReceiverWithNoProtection.class);
+
+        final DevicePolicyManager dpm = getContext().getSystemService(DevicePolicyManager.class);
+
+        if (dpm.isAdminActive(cn)) {
+            dpm.removeActiveAdmin(cn);
+            for (int i = 0; i < 1000 && dpm.isAdminActive(cn); i++) {
+                Thread.sleep(10);
+            }
+        }
+        assertFalse("Still active admin", dpm.isAdminActive(cn));
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/ClearDeviceOwnerTest.java b/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/ClearDeviceOwnerTest.java
new file mode 100644
index 0000000..7e20972
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/ClearDeviceOwnerTest.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.deviceadmin;
+
+import android.app.admin.DevicePolicyManager;
+
+/**
+ * Remove myself as DO.
+ */
+public class ClearDeviceOwnerTest extends BaseDeviceAdminTest {
+
+    public void testRemoveDeviceOwner() throws Exception {
+
+        final DevicePolicyManager dpm = getContext().getSystemService(DevicePolicyManager.class);
+
+        dpm.clearDeviceOwnerApp(mPackageName);
+
+        assertNotDeviceOwner();
+
+        assertNotActiveAdmin(); // Wait until DA is deactivated too.
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/ClearPasswordTest.java b/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/ClearPasswordTest.java
new file mode 100644
index 0000000..b65fc1a
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/ClearPasswordTest.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.deviceadmin;
+
+public class ClearPasswordTest extends BaseDeviceAdminTest {
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        assertDeviceOwner();
+    }
+
+    public void testClearPassword() {
+        clearPassword();
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/DeviceAdminPasswordTest.java b/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/DeviceAdminPasswordTest.java
new file mode 100644
index 0000000..2d1197b
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/DeviceAdminPasswordTest.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.deviceadmin;
+
+import android.app.admin.DevicePolicyManager;
+import android.test.MoreAsserts;
+
+/**
+ * Tests that:
+ * - need to be run as device admin (as opposed to device owner) and
+ * - require resetting the password at the end.
+ *
+ * Note: when adding a new method, make sure to add a corresponding method in
+ * BaseDeviceAdminHostSideTest.
+ */
+public class DeviceAdminPasswordTest extends BaseDeviceAdminTest {
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        assertNotDeviceOwner();
+    }
+
+    private void checkSetPassword_nycRestrictions_success() {
+        assertTrue(dpm.resetPassword("1234", /* flags= */ 0));
+    }
+
+    private void checkSetPassword_nycRestrictions_failure() {
+        try {
+            assertFalse(dpm.resetPassword("1234", /* flags= */ 0));
+            if (shouldResetPasswordThrow()) {
+                fail("Didn't throw");
+            }
+        } catch (SecurityException e) {
+            if (!shouldResetPasswordThrow()) {
+                fail("Shouldn't throw");
+            }
+            MoreAsserts.assertContainsRegex("Admin cannot change current password", e.getMessage());
+        }
+    }
+
+    private void checkClearPassword_nycRestrictions_failure() {
+        try {
+            assertFalse(dpm.resetPassword("", /* flags= */ 0));
+            if (shouldResetPasswordThrow()) {
+                fail("Didn't throw");
+            }
+        } catch (SecurityException e) {
+            if (!shouldResetPasswordThrow()) {
+                fail("Shouldn't throw");
+            }
+            MoreAsserts.assertContainsRegex("Cannot call with null password", e.getMessage());
+        }
+    }
+
+    private void assertHasPassword() {
+        dpm.setPasswordMinimumLength(mAdminComponent, 1);
+        try {
+            assertTrue("No password set", dpm.isActivePasswordSufficient());
+        } finally {
+            dpm.setPasswordMinimumLength(mAdminComponent, 0);
+        }
+    }
+
+    private void assertNoPassword() {
+        dpm.setPasswordMinimumLength(mAdminComponent, 1);
+        try {
+            assertFalse("Password is set", dpm.isActivePasswordSufficient());
+        } finally {
+            dpm.setPasswordMinimumLength(mAdminComponent, 0);
+        }
+    }
+
+    /**
+     * Tests for the new restrictions on {@link DevicePolicyManager#resetPassword} introduced
+     * on NYC.
+     */
+    public void testResetPassword_nycRestrictions() throws Exception {
+
+        assertNoPassword();
+
+        // Can't clear the password, even if there's no password set currently.
+        checkClearPassword_nycRestrictions_failure();
+
+        assertNoPassword();
+
+        // No password -> setting one is okay.
+        checkSetPassword_nycRestrictions_success();
+
+        assertHasPassword();
+
+        // But once set, DA can't change the password.
+        checkSetPassword_nycRestrictions_failure();
+
+        assertHasPassword();
+
+        // Still can't clear the password.
+        checkClearPassword_nycRestrictions_failure();
+
+        assertHasPassword();
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/DeviceAdminReceiverWithNoProtection.java b/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/DeviceAdminReceiverWithNoProtection.java
new file mode 100644
index 0000000..ac23656
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/DeviceAdminReceiverWithNoProtection.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.deviceadmin;
+
+import android.app.admin.DeviceAdminReceiver;
+
+/**
+ * Active admin with no android:permission="android.permission.BIND_DEVICE_ADMIN".  It can still
+ * be activated if the target API level <= 23, but not >= 24.
+ */
+public class DeviceAdminReceiverWithNoProtection extends DeviceAdminReceiver {
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/DeviceAdminTest.java b/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/DeviceAdminTest.java
new file mode 100644
index 0000000..7a03902
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/DeviceAdminTest.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.deviceadmin;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+
+/**
+ * Device admin device side tests.
+ */
+public class DeviceAdminTest extends BaseDeviceAdminTest {
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        assertNotDeviceOwner();
+    }
+
+    public void testTargetApiLevel() throws Exception {
+        final PackageManager pm = mContext.getPackageManager();
+
+        final PackageInfo pi = pm.getPackageInfo(mContext.getPackageName(), /* flags =*/ 0);
+
+        assertEquals(getTargetApiLevel(), pi.applicationInfo.targetSdkVersion);
+    }
+
+    public void testGetMaximumFailedPasswordsForWipe() {
+        dpm.setMaximumFailedPasswordsForWipe(mAdminComponent, 3);
+        assertEquals(3, dpm.getMaximumFailedPasswordsForWipe(mAdminComponent));
+
+        dpm.setMaximumFailedPasswordsForWipe(mAdminComponent, 5);
+        assertEquals(5, dpm.getMaximumFailedPasswordsForWipe(mAdminComponent));
+    }
+
+    public void testPasswordHistoryLength() {
+        // Password history length restriction is only imposed if password quality is at least
+        // numeric.
+        dpm.setPasswordQuality(mAdminComponent,
+                DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC);
+        int originalValue = dpm.getPasswordHistoryLength(mAdminComponent);
+        try {
+            dpm.setPasswordHistoryLength(mAdminComponent, 3);
+            assertEquals(3, dpm.getPasswordHistoryLength(mAdminComponent));
+            // Although it would make sense we cannot test if password history restrictions
+            // are enforced as DevicePolicyManagerService.resetPassword fails to do so at the
+            // moment. See b/17707820
+        } finally {
+            dpm.setPasswordHistoryLength(mAdminComponent, originalValue);
+        }
+    }
+
+    public void testPasswordExpirationTimeout() {
+        long originalValue = dpm.getPasswordExpirationTimeout(mAdminComponent);
+        try {
+            for (long testLength : new long[] {
+                    0L, 864000000L /* ten days */, 8640000000L /* 100 days */}) {
+                dpm.setPasswordExpirationTimeout(mAdminComponent, testLength);
+                assertEquals(testLength,
+                        dpm.getPasswordExpirationTimeout(mAdminComponent));
+            }
+        } finally {
+            dpm.setPasswordExpirationTimeout(mAdminComponent, originalValue);
+        }
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/DeviceOwnerPasswordTest.java b/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/DeviceOwnerPasswordTest.java
new file mode 100644
index 0000000..a00b4eb
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/DeviceOwnerPasswordTest.java
@@ -0,0 +1,376 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.deviceadmin;
+
+import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_COMPLEX;
+
+import android.app.admin.DevicePolicyManager;
+
+/**
+ * Tests for {@link DevicePolicyManager#resetPassword} for complex cases.
+ *
+ * This needs to be run as device owner, because in NYC DA can't clear or change the password.
+ */
+public class DeviceOwnerPasswordTest extends BaseDeviceAdminTest {
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        assertDeviceOwner();
+        clearPassword();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        clearPassword();
+
+        super.tearDown();
+    }
+
+    public void testPasswordQuality_something() {
+        dpm.setPasswordQuality(mAdminComponent,
+                DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
+        assertEquals(DevicePolicyManager.PASSWORD_QUALITY_SOMETHING,
+                dpm.getPasswordQuality(mAdminComponent));
+        assertFalse(dpm.isActivePasswordSufficient());
+
+        String caseDescription = "initial";
+        assertPasswordSucceeds("1234", caseDescription);
+        assertPasswordSucceeds("abcd", caseDescription); // can't change.
+        assertPasswordSucceeds("abcd1234", caseDescription);
+
+        dpm.setPasswordMinimumLength(mAdminComponent, 10);
+        caseDescription = "minimum password length = 10";
+        assertEquals(10, dpm.getPasswordMinimumLength(mAdminComponent));
+        assertFalse(dpm.isActivePasswordSufficient());
+
+        assertPasswordFails("1234", caseDescription);
+        assertPasswordFails("abcd", caseDescription);
+        assertPasswordFails("abcd1234", caseDescription);
+
+        dpm.setPasswordMinimumLength(mAdminComponent, 4);
+        caseDescription = "minimum password length = 4";
+        assertEquals(4, dpm.getPasswordMinimumLength(
+                mAdminComponent));
+        assertTrue(dpm.isActivePasswordSufficient());
+
+        assertPasswordSucceeds("1234", caseDescription);
+        assertPasswordSucceeds("abcd", caseDescription);
+        assertPasswordSucceeds("abcd1234", caseDescription);
+    }
+
+    public void testPasswordQuality_numeric() {
+        dpm.setPasswordQuality(mAdminComponent,
+                DevicePolicyManager.PASSWORD_QUALITY_NUMERIC);
+        assertEquals(DevicePolicyManager.PASSWORD_QUALITY_NUMERIC,
+                dpm.getPasswordQuality(mAdminComponent));
+        assertFalse(dpm.isActivePasswordSufficient());            // failure
+
+        String caseDescription = "initial";
+        assertPasswordSucceeds("1234", caseDescription);
+        assertPasswordSucceeds("abcd", caseDescription);
+        assertPasswordSucceeds("abcd1234", caseDescription);
+
+        dpm.setPasswordMinimumLength(mAdminComponent, 10);
+        caseDescription = "minimum password length = 10";
+        assertEquals(10, dpm.getPasswordMinimumLength(mAdminComponent));
+        assertFalse(dpm.isActivePasswordSufficient());
+
+        assertPasswordFails("1234", caseDescription);
+        assertPasswordFails("abcd", caseDescription);
+        assertPasswordFails("abcd1234", caseDescription);
+
+        dpm.setPasswordMinimumLength(mAdminComponent, 4);
+        caseDescription = "minimum password length = 4";
+        assertEquals(4, dpm.getPasswordMinimumLength(
+                mAdminComponent));
+        assertTrue(dpm.isActivePasswordSufficient());
+
+        assertPasswordSucceeds("1234", caseDescription);
+        assertPasswordSucceeds("abcd", caseDescription);
+        assertPasswordSucceeds("abcd1234", caseDescription);
+    }
+
+    public void testPasswordQuality_alphabetic() {
+        dpm.setPasswordQuality(mAdminComponent,
+                DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC);
+        assertEquals(DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC,
+                dpm.getPasswordQuality(mAdminComponent));
+        assertFalse(dpm.isActivePasswordSufficient());
+
+        String caseDescription = "initial";
+        assertPasswordFails("1234", caseDescription);      // can't change
+        assertPasswordSucceeds("abcd", caseDescription);
+        assertPasswordSucceeds("abcd1234", caseDescription);
+
+        dpm.setPasswordMinimumLength(mAdminComponent, 10);
+        caseDescription = "minimum password length = 10";
+        assertEquals(10, dpm.getPasswordMinimumLength(mAdminComponent));
+        assertFalse(dpm.isActivePasswordSufficient());
+
+        assertPasswordFails("1234", caseDescription);
+        assertPasswordFails("abcd", caseDescription);
+        assertPasswordFails("abcd1234", caseDescription);
+
+        dpm.setPasswordMinimumLength(mAdminComponent, 4);
+        caseDescription = "minimum password length = 4";
+        assertEquals(4, dpm.getPasswordMinimumLength(
+                mAdminComponent));
+        assertTrue(dpm.isActivePasswordSufficient());
+
+        assertPasswordFails("1234", caseDescription);
+        assertPasswordSucceeds("abcd", caseDescription);
+        assertPasswordSucceeds("abcd1234", caseDescription);
+    }
+
+    public void testPasswordQuality_alphanumeric() {
+        dpm.setPasswordQuality(mAdminComponent,
+                DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC);
+        assertEquals(DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC,
+                dpm.getPasswordQuality(mAdminComponent));
+        assertFalse(dpm.isActivePasswordSufficient());
+
+        String caseDescription = "initial";
+        assertPasswordFails("1234", caseDescription);
+        assertPasswordFails("abcd", caseDescription);
+        assertPasswordSucceeds("abcd1234", caseDescription);
+
+        dpm.setPasswordMinimumLength(mAdminComponent, 10);
+        caseDescription = "minimum password length = 10";
+        assertEquals(10, dpm.getPasswordMinimumLength(mAdminComponent));
+        assertFalse(dpm.isActivePasswordSufficient());
+
+        assertPasswordFails("1234", caseDescription);
+        assertPasswordFails("abcd", caseDescription);
+        assertPasswordFails("abcd1234", caseDescription);
+
+        dpm.setPasswordMinimumLength(mAdminComponent, 4);
+        caseDescription = "minimum password length = 4";
+        assertEquals(4, dpm.getPasswordMinimumLength(
+                mAdminComponent));
+        assertTrue(dpm.isActivePasswordSufficient());
+
+        assertPasswordFails("1234", caseDescription);
+        assertPasswordFails("abcd", caseDescription);
+        assertPasswordSucceeds("abcd1234", caseDescription);
+    }
+
+    public void testPasswordQuality_complexUpperCase() {
+        dpm.setPasswordQuality(mAdminComponent, PASSWORD_QUALITY_COMPLEX);
+        assertEquals(PASSWORD_QUALITY_COMPLEX, dpm.getPasswordQuality(mAdminComponent));
+        resetComplexPasswordRestrictions();
+
+        String caseDescription = "minimum UpperCase=0";
+        assertPasswordSucceeds("abc1", caseDescription);
+        assertPasswordSucceeds("aBc1", caseDescription);
+        assertPasswordSucceeds("ABC1", caseDescription);
+        assertPasswordSucceeds("ABCD", caseDescription);
+        assertPasswordFails("123", caseDescription); // too short
+
+        dpm.setPasswordMinimumUpperCase(mAdminComponent, 1);
+        assertEquals(1, dpm.getPasswordMinimumUpperCase(mAdminComponent));
+        caseDescription = "minimum UpperCase=1";
+        assertPasswordFails("abc1", caseDescription);
+        assertPasswordSucceeds("aBc1", caseDescription);
+        assertPasswordSucceeds("ABC1", caseDescription);
+        assertPasswordSucceeds("ABCD", caseDescription);
+        assertPasswordFails("123", caseDescription); // too short
+
+        dpm.setPasswordMinimumUpperCase(mAdminComponent, 3);
+        assertEquals(3, dpm.getPasswordMinimumUpperCase(mAdminComponent));
+        caseDescription = "minimum UpperCase=3";
+        assertPasswordFails("abc1", caseDescription);
+        assertPasswordFails("aBC1", caseDescription);
+        assertPasswordSucceeds("ABC1", caseDescription);
+        assertPasswordSucceeds("ABCD", caseDescription);
+        assertPasswordFails("123", caseDescription); // too short
+    }
+
+    public void testPasswordQuality_complexLowerCase() {
+        dpm.setPasswordQuality(mAdminComponent, PASSWORD_QUALITY_COMPLEX);
+        assertEquals(PASSWORD_QUALITY_COMPLEX, dpm.getPasswordQuality(mAdminComponent));
+        resetComplexPasswordRestrictions();
+
+        String caseDescription = "minimum LowerCase=0";
+        assertPasswordSucceeds("ABCD", caseDescription);
+        assertPasswordSucceeds("aBC1", caseDescription);
+        assertPasswordSucceeds("abc1", caseDescription);
+        assertPasswordSucceeds("abcd", caseDescription);
+        assertPasswordFails("123", caseDescription); // too short
+
+        dpm.setPasswordMinimumLowerCase(mAdminComponent, 1);
+        assertEquals(1, dpm.getPasswordMinimumLowerCase(mAdminComponent));
+        caseDescription = "minimum LowerCase=1";
+        assertPasswordFails("ABCD", caseDescription);
+        assertPasswordSucceeds("aBC1", caseDescription);
+        assertPasswordSucceeds("abc1", caseDescription);
+        assertPasswordSucceeds("abcd", caseDescription);
+        assertPasswordFails("123", caseDescription); // too short
+
+        dpm.setPasswordMinimumLowerCase(mAdminComponent, 3);
+        assertEquals(3, dpm.getPasswordMinimumLowerCase(mAdminComponent));
+        caseDescription = "minimum LowerCase=3";
+        assertPasswordFails("ABCD", caseDescription);
+        assertPasswordFails("aBC1", caseDescription);
+        assertPasswordSucceeds("abc1", caseDescription);
+        assertPasswordSucceeds("abcd", caseDescription);
+        assertPasswordFails("123", caseDescription); // too short
+    }
+
+    public void testPasswordQuality_complexLetters() {
+        dpm.setPasswordQuality(mAdminComponent, PASSWORD_QUALITY_COMPLEX);
+        assertEquals(PASSWORD_QUALITY_COMPLEX, dpm.getPasswordQuality(mAdminComponent));
+        resetComplexPasswordRestrictions();
+
+        String caseDescription = "minimum Letters=0";
+        assertPasswordSucceeds("1234", caseDescription);
+        assertPasswordSucceeds("a123", caseDescription);
+        assertPasswordSucceeds("abc1", caseDescription);
+        assertPasswordSucceeds("abcd", caseDescription);
+        assertPasswordFails("123", caseDescription); // too short
+
+        dpm.setPasswordMinimumLetters(mAdminComponent, 1);
+        assertEquals(1, dpm.getPasswordMinimumLetters(mAdminComponent));
+        caseDescription = "minimum Letters=1";
+        assertPasswordFails("1234", caseDescription);
+        assertPasswordSucceeds("a123", caseDescription);
+        assertPasswordSucceeds("abc1", caseDescription);
+        assertPasswordSucceeds("abcd", caseDescription);
+        assertPasswordFails("123", caseDescription); // too short
+
+        dpm.setPasswordMinimumLetters(mAdminComponent, 3);
+        assertEquals(3, dpm.getPasswordMinimumLetters(mAdminComponent));
+        caseDescription = "minimum Letters=3";
+        assertPasswordFails("1234", caseDescription);
+        assertPasswordFails("a123", caseDescription);
+        assertPasswordSucceeds("abc1", caseDescription);
+        assertPasswordSucceeds("abcd", caseDescription);
+        assertPasswordFails("123", caseDescription); // too short
+    }
+
+    public void testPasswordQuality_complexNumeric() {
+        dpm.setPasswordQuality(mAdminComponent, PASSWORD_QUALITY_COMPLEX);
+        assertEquals(PASSWORD_QUALITY_COMPLEX, dpm.getPasswordQuality(mAdminComponent));
+        resetComplexPasswordRestrictions();
+
+        String caseDescription = "minimum Numeric=0";
+        assertPasswordSucceeds("abcd", caseDescription);
+        assertPasswordSucceeds("1abc", caseDescription);
+        assertPasswordSucceeds("123a", caseDescription);
+        assertPasswordSucceeds("1234", caseDescription);
+        assertPasswordFails("123", caseDescription); // too short
+
+        dpm.setPasswordMinimumNumeric(mAdminComponent, 1);
+        assertEquals(1, dpm.getPasswordMinimumNumeric(mAdminComponent));
+        caseDescription = "minimum Numeric=1";
+        assertPasswordFails("abcd", caseDescription);
+        assertPasswordSucceeds("1abc", caseDescription);
+        assertPasswordSucceeds("123a", caseDescription);
+        assertPasswordSucceeds("1234", caseDescription);
+        assertPasswordFails("123", caseDescription); // too short
+
+        dpm.setPasswordMinimumNumeric(mAdminComponent, 3);
+        assertEquals(3, dpm.getPasswordMinimumNumeric(mAdminComponent));
+        caseDescription = "minimum Numeric=3";
+        assertPasswordFails("abcd", caseDescription);
+        assertPasswordFails("1abc", caseDescription);
+        assertPasswordSucceeds("123a", caseDescription);
+        assertPasswordSucceeds("1234", caseDescription);
+        assertPasswordFails("123", caseDescription); // too short
+    }
+
+    public void testPasswordQuality_complexSymbols() {
+        dpm.setPasswordQuality(mAdminComponent, PASSWORD_QUALITY_COMPLEX);
+        assertEquals(PASSWORD_QUALITY_COMPLEX, dpm.getPasswordQuality(mAdminComponent));
+        resetComplexPasswordRestrictions();
+
+        String caseDescription = "minimum Symbols=0";
+        assertPasswordSucceeds("abcd", caseDescription);
+        assertPasswordSucceeds("_bc1", caseDescription);
+        assertPasswordSucceeds("@#!1", caseDescription);
+        assertPasswordSucceeds("_@#!", caseDescription);
+        assertPasswordFails("123", caseDescription); // too short
+
+        dpm.setPasswordMinimumSymbols(mAdminComponent, 1);
+        assertEquals(1, dpm.getPasswordMinimumSymbols(mAdminComponent));
+        caseDescription = "minimum Symbols=1";
+        assertPasswordFails("abcd", caseDescription);
+        assertPasswordSucceeds("_bc1", caseDescription);
+        assertPasswordSucceeds("@#!1", caseDescription);
+        assertPasswordSucceeds("_@#!", caseDescription);
+        assertPasswordFails("123", caseDescription); // too short
+
+        dpm.setPasswordMinimumSymbols(mAdminComponent, 3);
+        assertEquals(3, dpm.getPasswordMinimumSymbols(mAdminComponent));
+        caseDescription = "minimum Symbols=3";
+        assertPasswordFails("abcd", caseDescription);
+        assertPasswordFails("_bc1", caseDescription);
+        assertPasswordSucceeds("@#!1", caseDescription);
+        assertPasswordSucceeds("_@#!", caseDescription);
+        assertPasswordFails("123", caseDescription); // too short
+    }
+
+    public void testPasswordQuality_complexNonLetter() {
+        dpm.setPasswordQuality(mAdminComponent, PASSWORD_QUALITY_COMPLEX);
+        assertEquals(PASSWORD_QUALITY_COMPLEX, dpm.getPasswordQuality(mAdminComponent));
+        resetComplexPasswordRestrictions();
+
+        String caseDescription = "minimum NonLetter=0";
+        assertPasswordSucceeds("Abcd", caseDescription);
+        assertPasswordSucceeds("_bcd", caseDescription);
+        assertPasswordSucceeds("3bcd", caseDescription);
+        assertPasswordSucceeds("_@3c", caseDescription);
+        assertPasswordSucceeds("_25!", caseDescription);
+        assertPasswordFails("123", caseDescription); // too short
+
+        dpm.setPasswordMinimumNonLetter(mAdminComponent, 1);
+        assertEquals(1, dpm.getPasswordMinimumNonLetter(mAdminComponent));
+        caseDescription = "minimum NonLetter=1";
+        assertPasswordFails("Abcd", caseDescription);
+        assertPasswordSucceeds("_bcd", caseDescription);
+        assertPasswordSucceeds("3bcd", caseDescription);
+        assertPasswordSucceeds("_@3c", caseDescription);
+        assertPasswordSucceeds("_25!", caseDescription);
+        assertPasswordFails("123", caseDescription); // too short
+
+        dpm.setPasswordMinimumNonLetter(mAdminComponent, 3);
+        assertEquals(3, dpm.getPasswordMinimumNonLetter(mAdminComponent));
+        caseDescription = "minimum NonLetter=3";
+        assertPasswordFails("Abcd", caseDescription);
+        assertPasswordFails("_bcd", caseDescription);
+        assertPasswordFails("3bcd", caseDescription);
+        assertPasswordSucceeds("_@3c", caseDescription);
+        assertPasswordSucceeds("_25!", caseDescription);
+        assertPasswordFails("123", caseDescription); // too short
+    }
+
+    private void assertPasswordFails(String password, String restriction) {
+        try {
+            boolean passwordResetResult = dpm.resetPassword(password, /* flags= */0);
+            assertFalse("Password '" + password + "' should have failed on " + restriction,
+                    passwordResetResult);
+        } catch (IllegalArgumentException e) {
+            // yesss, we have failed!
+        }
+    }
+
+    private void assertPasswordSucceeds(String password, String restriction) {
+        boolean passwordResetResult = dpm.resetPassword(password, /* flags= */0);
+        assertTrue("Password '" + password + "' failed on " + restriction, passwordResetResult);
+        assertTrue(dpm.isActivePasswordSufficient());
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/Android.mk b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/Android.mk
index 0548af6..af5293a 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/Android.mk
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/Android.mk
@@ -1,4 +1,4 @@
-# Copyright (C) 2015 The Android Open Source Project
+# Copyright (C) 2016 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -12,22 +12,9 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-LOCAL_PATH:= $(call my-dir)
+LOCAL_PATH := $(call my-dir)
 
 include $(CLEAR_VARS)
 
-LOCAL_PACKAGE_NAME := CtsDeviceAndProfileOwnerApp
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_JAVA_LIBRARIES := android.test.runner cts-junit
-
-LOCAL_STATIC_JAVA_LIBRARIES = android-support-v4 ctstestrunner ub-uiautomator
-
-LOCAL_SDK_VERSION := current
-
-include $(BUILD_CTS_PACKAGE)
+# Build the test APKs using their own makefiles
+include $(call all-makefiles-under,$(LOCAL_PATH))
\ No newline at end of file
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/AndroidManifest.xml b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/AndroidManifest.xml
deleted file mode 100644
index fe07bcb..0000000
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/AndroidManifest.xml
+++ /dev/null
@@ -1,86 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.deviceandprofileowner">
-
-    <uses-sdk android:minSdkVersion="23"/>
-    <uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
-    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
-    <uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
-
-    <application>
-        <uses-library android:name="android.test.runner" />
-        <receiver
-            android:name="com.android.cts.deviceandprofileowner.BaseDeviceAdminTest$BasicAdminReceiver"
-            android:permission="android.permission.BIND_DEVICE_ADMIN">
-            <meta-data android:name="android.app.device_admin"
-                       android:resource="@xml/device_admin" />
-            <intent-filter>
-                <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
-            </intent-filter>
-        </receiver>
-        <receiver
-            android:name="com.android.cts.deviceandprofileowner.PrimaryUserDeviceAdmin"
-            android:permission="android.permission.BIND_DEVICE_ADMIN">
-            <meta-data android:name="android.app.device_admin"
-                       android:resource="@xml/primary_device_admin" />
-            <intent-filter>
-                <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
-            </intent-filter>
-        </receiver>
-        <activity
-            android:name="com.android.cts.deviceandprofileowner.ApplicationRestrictionsActivity" />
-        <activity
-            android:name="com.android.cts.deviceandprofileowner.ScreenCaptureDisabledActivity" />
-        <activity
-            android:name="com.android.cts.deviceandprofileowner.ExampleIntentReceivingActivity1">
-            <intent-filter>
-                <action android:name="com.android.cts.deviceandprofileowner.EXAMPLE_ACTION" />
-                <category android:name="android.intent.category.DEFAULT" />
-            </intent-filter>
-        </activity>
-
-        <activity
-            android:name="com.android.cts.deviceandprofileowner.ExampleIntentReceivingActivity2">
-            <intent-filter>
-                <action android:name="com.android.cts.deviceandprofileowner.EXAMPLE_ACTION" />
-                <category android:name="android.intent.category.DEFAULT" />
-            </intent-filter>
-        </activity>
-
-        <service android:name=".MockAccountService" android:exported="true">
-            <intent-filter>
-                <action android:name="android.accounts.AccountAuthenticator" />
-            </intent-filter>
-
-            <meta-data android:name="android.accounts.AccountAuthenticator"
-                       android:resource="@xml/authenticator" />
-        </service>
-
-        <activity android:name=".UserRestrictionActivity" >
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.DEFAULT"/>
-            </intent-filter>
-        </activity>
-
-    </application>
-
-    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.cts.deviceandprofileowner"
-                     android:label="Profile and Device Owner CTS Tests"/>
-</manifest>
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/api23/Android.mk b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/api23/Android.mk
new file mode 100644
index 0000000..b1c35aa
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/api23/Android.mk
@@ -0,0 +1,36 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := CtsDeviceAndProfileOwnerApp23
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, ../src)
+
+LOCAL_STATIC_JAVA_LIBRARIES = android-support-v4 ctsdeviceutil ctstestrunner ub-uiautomator
+
+LOCAL_SDK_VERSION := current
+
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/../res
+
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/api23/AndroidManifest.xml b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/api23/AndroidManifest.xml
new file mode 100644
index 0000000..01f4faa
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/api23/AndroidManifest.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.cts.deviceandprofileowner">
+
+    <uses-sdk android:minSdkVersion="23" android:targetSdkVersion="23"/>
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
+    <uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
+    <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+        <receiver
+            android:name="com.android.cts.deviceandprofileowner.BaseDeviceAdminTest$BasicAdminReceiver"
+            android:permission="android.permission.BIND_DEVICE_ADMIN">
+            <meta-data android:name="android.app.device_admin"
+                       android:resource="@xml/device_admin" />
+            <intent-filter>
+                <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
+            </intent-filter>
+        </receiver>
+    </application>
+
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="com.android.cts.deviceandprofileowner"
+                     android:label="Profile and Device Owner CTS Tests API 23"/>
+</manifest>
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/latest/Android.mk b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/latest/Android.mk
new file mode 100644
index 0000000..7d08bc3
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/latest/Android.mk
@@ -0,0 +1,36 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := CtsDeviceAndProfileOwnerApp
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, ../src)
+
+LOCAL_STATIC_JAVA_LIBRARIES = android-support-v4 ctsdeviceutil ctstestrunner ub-uiautomator
+
+LOCAL_SDK_VERSION := current
+
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/../res
+
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/latest/AndroidManifest.xml b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/latest/AndroidManifest.xml
new file mode 100644
index 0000000..5bd902c
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/latest/AndroidManifest.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.cts.deviceandprofileowner">
+
+    <uses-sdk android:minSdkVersion="23"/>
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
+    <uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
+    <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
+    <uses-permission android:name="android.permission.SET_WALLPAPER" />
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+        <receiver
+            android:name="com.android.cts.deviceandprofileowner.BaseDeviceAdminTest$BasicAdminReceiver"
+            android:permission="android.permission.BIND_DEVICE_ADMIN">
+            <meta-data android:name="android.app.device_admin"
+                       android:resource="@xml/device_admin" />
+            <intent-filter>
+                <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
+            </intent-filter>
+        </receiver>
+        <activity
+            android:name="com.android.cts.deviceandprofileowner.ScreenCaptureDisabledActivity" />
+        <activity
+            android:name="com.android.cts.deviceandprofileowner.ExampleIntentReceivingActivity1">
+            <intent-filter>
+                <action android:name="com.android.cts.deviceandprofileowner.EXAMPLE_ACTION" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+
+        <activity
+            android:name="com.android.cts.deviceandprofileowner.ExampleIntentReceivingActivity2">
+            <intent-filter>
+                <action android:name="com.android.cts.deviceandprofileowner.EXAMPLE_ACTION" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".SetPolicyActivity" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.DEFAULT"/>
+            </intent-filter>
+        </activity>
+
+    </application>
+
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="com.android.cts.deviceandprofileowner"
+                     android:label="Profile and Device Owner CTS Tests"/>
+</manifest>
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/res/raw/wallpaper.png b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/res/raw/wallpaper.png
new file mode 100644
index 0000000..6a2f3ba
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/res/raw/wallpaper.png
Binary files differ
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/res/values/strings.xml b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/res/values/strings.xml
deleted file mode 100644
index 4aca824..0000000
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/res/values/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- Label for this package -->
-    <string name="authenticator_label">Android CTS - Device and Profile Owner</string>
-</resources>
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/res/xml/authenticator.xml b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/res/xml/authenticator.xml
deleted file mode 100644
index 0d8ecd8..0000000
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/res/xml/authenticator.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<!-- Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<!-- The attributes in this XML file provide configuration information -->
-<!-- for the Account Manager. -->
-
-<account-authenticator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:accountType="com.android.cts.deviceandprofileowner.account.type"
-    android:label="@string/authenticator_label"
-/>
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/res/xml/device_admin.xml b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/res/xml/device_admin.xml
index 69a661c..335eadd 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/res/xml/device_admin.xml
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/res/xml/device_admin.xml
@@ -14,5 +14,8 @@
 -->
 <device-admin xmlns:android="http://schemas.android.com/apk/res/android" android:visible="false">
     <uses-policies>
+         <reset-password />
+         <limit-password />
+         <disable-keyguard-features />
     </uses-policies>
 </device-admin>
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/res/xml/primary_device_admin.xml b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/res/xml/primary_device_admin.xml
deleted file mode 100644
index a6aff49..0000000
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/res/xml/primary_device_admin.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<!-- Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<device-admin xmlns:android="http://schemas.android.com/apk/res/android" android:visible="false">
-    <uses-policies>
-         <reset-password />
-         <limit-password />
-    </uses-policies>
-</device-admin>
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/AccountManagementTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/AccountManagementTest.java
deleted file mode 100644
index d93c8f2..0000000
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/AccountManagementTest.java
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.deviceandprofileowner;
-
-import android.accounts.Account;
-import android.accounts.AccountManager;
-import android.accounts.AccountManagerFuture;
-import android.accounts.AuthenticatorException;
-import android.accounts.OperationCanceledException;
-import android.app.admin.DevicePolicyManager;
-import android.content.Context;
-import android.os.Bundle;
-import android.os.UserManager;
-
-import java.io.IOException;
-
-/**
- * Functionality tests for {@link DevicePolicyManager#setAccountManagementDisabled}
- *
- * Fire up a remote unprivileged service and attempt to add/remove/list
- * accounts from it to verify the enforcement is in place.
- *
- * This test depend on {@link MockAccountService}, which provides authenticator of type
- * {@link MockAccountService#ACCOUNT_TYPE}.
- */
-public class AccountManagementTest extends BaseDeviceAdminTest {
-
-    // Account type for MockAccountAuthenticator
-    private final static String ACCOUNT_TYPE_1 = MockAccountAuthenticator.ACCOUNT_TYPE;
-    private final static String ACCOUNT_TYPE_2 = "com.dummy.account";
-    private final static Account ACCOUNT_0 = new Account("user0", ACCOUNT_TYPE_1);
-    private final static Account ACCOUNT_1 = new Account("user1", ACCOUNT_TYPE_1);
-
-    private AccountManager mAccountManager;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mAccountManager = (AccountManager) mContext.getSystemService(Context.ACCOUNT_SERVICE);
-        clearAllAccountManagementDisabled();
-        mDevicePolicyManager.clearUserRestriction(ADMIN_RECEIVER_COMPONENT,
-                UserManager.DISALLOW_MODIFY_ACCOUNTS);
-        AccountUtilsTest.removeAllAccountsForType(mAccountManager, ACCOUNT_TYPE_1);
-        AccountUtilsTest.removeAllAccountsForType(mAccountManager, ACCOUNT_TYPE_2);
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        clearAllAccountManagementDisabled();
-        mDevicePolicyManager.clearUserRestriction(ADMIN_RECEIVER_COMPONENT,
-                UserManager.DISALLOW_MODIFY_ACCOUNTS);
-        AccountUtilsTest.removeAllAccountsForType(mAccountManager, ACCOUNT_TYPE_1);
-        AccountUtilsTest.removeAllAccountsForType(mAccountManager, ACCOUNT_TYPE_2);
-        super.tearDown();
-    }
-
-    public void testAccountManagementDisabled_setterAndGetter() {
-        // Some local tests: adding and removing disabled accounts and make sure
-        // DevicePolicyManager keeps track of the disabled set correctly
-        assertEquals(0, mDevicePolicyManager.getAccountTypesWithManagementDisabled().length);
-
-        mDevicePolicyManager.setAccountManagementDisabled(ADMIN_RECEIVER_COMPONENT, ACCOUNT_TYPE_1,
-                true);
-        assertEquals(1, mDevicePolicyManager.getAccountTypesWithManagementDisabled().length);
-        assertEquals(ACCOUNT_TYPE_1,
-                mDevicePolicyManager.getAccountTypesWithManagementDisabled()[0]);
-
-        mDevicePolicyManager.setAccountManagementDisabled(ADMIN_RECEIVER_COMPONENT, ACCOUNT_TYPE_1,
-                false);
-        assertEquals(0, mDevicePolicyManager.getAccountTypesWithManagementDisabled().length);
-    }
-
-    public void testAccountManagementDisabled_addAccount() throws AuthenticatorException,
-            IOException, OperationCanceledException {
-        // Test for restriction on addAccount()
-        mDevicePolicyManager.setAccountManagementDisabled(ADMIN_RECEIVER_COMPONENT, ACCOUNT_TYPE_1,
-                true);
-        // Test if disabling ACCOUNT_TYPE_2 affects ACCOUNT_TYPE_1
-        mDevicePolicyManager.setAccountManagementDisabled(ADMIN_RECEIVER_COMPONENT, ACCOUNT_TYPE_2,
-                false);
-        assertEquals(1, mDevicePolicyManager.getAccountTypesWithManagementDisabled().length);
-
-        assertEquals(0, mAccountManager.getAccountsByType(ACCOUNT_TYPE_1).length);
-        // Management is disabled, adding account should fail.
-        try {
-            mAccountManager.addAccount(ACCOUNT_TYPE_1, null, null, null, null, null, null)
-                    .getResult();
-            fail("Expected OperationCanceledException is not thrown.");
-        } catch (OperationCanceledException e) {
-            // Expected
-        }
-        assertEquals(0, mAccountManager.getAccountsByType(ACCOUNT_TYPE_1).length);
-
-        // Management is re-enabled, adding account should succeed.
-        mDevicePolicyManager.setAccountManagementDisabled(ADMIN_RECEIVER_COMPONENT, ACCOUNT_TYPE_1,
-                false);
-        assertEquals(0, mDevicePolicyManager.getAccountTypesWithManagementDisabled().length);
-        Bundle result = mAccountManager.addAccount(ACCOUNT_TYPE_1,
-                null, null, null, null, null, null).getResult();
-
-        // Normally the expected result of addAccount() is AccountManager returning
-        // an intent to start the authenticator activity for adding new accounts.
-        // But MockAccountAuthenticator returns a new account straightway.
-        assertEquals(ACCOUNT_TYPE_1, result.getString(AccountManager.KEY_ACCOUNT_TYPE));
-    }
-
-    public void testAccountManagementDisabled_removeAccount() throws AuthenticatorException,
-            IOException, OperationCanceledException {
-        // Test for restriction on removeAccount()
-        mDevicePolicyManager.setAccountManagementDisabled(ADMIN_RECEIVER_COMPONENT, ACCOUNT_TYPE_1,
-                true);
-        mDevicePolicyManager.setAccountManagementDisabled(ADMIN_RECEIVER_COMPONENT, ACCOUNT_TYPE_2,
-                false);
-        assertEquals(1, mDevicePolicyManager.getAccountTypesWithManagementDisabled().length);
-
-        assertEquals(0, mAccountManager.getAccountsByType(ACCOUNT_TYPE_1).length);
-        // First prepare some accounts by manually adding them,
-        // setAccountManagementDisabled(true) should not stop addAccountExplicitly().
-        assertTrue(mAccountManager.addAccountExplicitly(ACCOUNT_0, "password", null));
-        assertTrue(mAccountManager.addAccountExplicitly(ACCOUNT_1, "password", null));
-        assertEquals(2, mAccountManager.getAccountsByType(ACCOUNT_TYPE_1).length);
-
-        // Removing account should fail, as we just disabled it.
-        try {
-            mAccountManager.removeAccount(ACCOUNT_0, null, null).getResult();
-            fail("Expected OperationCanceledException is not thrown.");
-        } catch (OperationCanceledException e) {
-            // Expected
-        }
-        assertEquals(2, mAccountManager.getAccountsByType(ACCOUNT_TYPE_1).length);
-
-        // Re-enable management, so we can successfully remove account this time.
-        mDevicePolicyManager.setAccountManagementDisabled(ADMIN_RECEIVER_COMPONENT, ACCOUNT_TYPE_1,
-                false);
-        assertEquals(0, mDevicePolicyManager.getAccountTypesWithManagementDisabled().length);
-        assertTrue(mAccountManager.removeAccount(ACCOUNT_0, null, null).getResult());
-
-        // Make sure the removal actually succeeds.
-        Account[] accounts = mAccountManager.getAccountsByType(ACCOUNT_TYPE_1);
-        assertEquals(1, accounts.length);
-        assertEquals(ACCOUNT_1, accounts[0]);
-
-        // Disable account type 2, we should still be able to remove from type 1.
-        mDevicePolicyManager.setAccountManagementDisabled(ADMIN_RECEIVER_COMPONENT, ACCOUNT_TYPE_2,
-                true);
-        assertEquals(1, mDevicePolicyManager.getAccountTypesWithManagementDisabled().length);
-        assertTrue(mAccountManager.removeAccount(ACCOUNT_1, null, null).getResult());
-
-        // Make sure the removal actually succeeds.
-        assertEquals(0, mAccountManager.getAccountsByType(ACCOUNT_TYPE_1).length);
-    }
-
-    public void testUserRestriction_addAccount() throws AuthenticatorException, IOException,
-            OperationCanceledException {
-        // Test for restriction on addAccount()
-        mDevicePolicyManager.addUserRestriction(ADMIN_RECEIVER_COMPONENT,
-                UserManager.DISALLOW_MODIFY_ACCOUNTS);
-
-        assertEquals(0, mAccountManager.getAccountsByType(ACCOUNT_TYPE_1).length);
-        // Management is disabled, adding account should fail.
-        try {
-            mAccountManager.addAccount(ACCOUNT_TYPE_1, null, null, null, null, null, null)
-                    .getResult();
-            fail("Expected OperationCanceledException is not thrown.");
-        } catch (OperationCanceledException e) {
-            // Expected
-        }
-        assertEquals(0, mAccountManager.getAccountsByType(ACCOUNT_TYPE_1).length);
-
-        // Management is re-enabled, adding account should succeed.
-        mDevicePolicyManager.clearUserRestriction(ADMIN_RECEIVER_COMPONENT,
-                UserManager.DISALLOW_MODIFY_ACCOUNTS);
-        assertEquals(0, mDevicePolicyManager.getAccountTypesWithManagementDisabled().length);
-        Bundle result = mAccountManager.addAccount(ACCOUNT_TYPE_1,
-                null, null, null, null, null, null).getResult();
-
-        // Normally the expected result of addAccount() is AccountManager returning
-        // an intent to start the authenticator activity for adding new accounts.
-        // But MockAccountAuthenticator returns a new account straightway.
-        assertEquals(ACCOUNT_TYPE_1, result.getString(AccountManager.KEY_ACCOUNT_TYPE));
-    }
-
-    public void testUserRestriction_removeAccount() throws AuthenticatorException,
-            IOException, OperationCanceledException {
-        // Test for restriction on removeAccount()
-        mDevicePolicyManager.addUserRestriction(ADMIN_RECEIVER_COMPONENT,
-                UserManager.DISALLOW_MODIFY_ACCOUNTS);
-
-        assertEquals(0, mAccountManager.getAccountsByType(ACCOUNT_TYPE_1).length);
-        // First prepare some accounts by manually adding them,
-        // setAccountManagementDisabled(true) should not stop addAccountExplicitly().
-        assertTrue(mAccountManager.addAccountExplicitly(ACCOUNT_0, "password", null));
-        assertEquals(1, mAccountManager.getAccountsByType(ACCOUNT_TYPE_1).length);
-
-        // Removing account should fail, as we just disabled it.
-        try {
-            mAccountManager.removeAccount(ACCOUNT_0, null, null).getResult();
-            fail("Expected OperationCanceledException is not thrown.");
-        } catch (OperationCanceledException e) {
-            // Expected
-        }
-        assertEquals(1, mAccountManager.getAccountsByType(ACCOUNT_TYPE_1).length);
-
-        // Re-enable management, so we can successfully remove account this time.
-        mDevicePolicyManager.clearUserRestriction(ADMIN_RECEIVER_COMPONENT,
-                UserManager.DISALLOW_MODIFY_ACCOUNTS);
-        assertTrue(mAccountManager.removeAccount(ACCOUNT_0, null, null).getResult());
-
-        // Make sure the removal actually succeeds.
-        assertEquals(0, mAccountManager.getAccountsByType(ACCOUNT_TYPE_1).length);
-    }
-
-    private void clearAllAccountManagementDisabled() {
-        for (String accountType : mDevicePolicyManager.getAccountTypesWithManagementDisabled()) {
-            mDevicePolicyManager.setAccountManagementDisabled(ADMIN_RECEIVER_COMPONENT, accountType,
-                    false);
-        }
-        assertEquals(0, mDevicePolicyManager.getAccountTypesWithManagementDisabled().length);
-    }
-}
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/AccountUtilsTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/AccountUtilsTest.java
deleted file mode 100644
index 7a9e5ad..0000000
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/AccountUtilsTest.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.deviceandprofileowner;
-
-import android.accounts.Account;
-import android.accounts.AccountManager;
-import android.accounts.AccountManagerFuture;
-import android.content.Context;
-import android.os.Bundle;
-import android.test.AndroidTestCase;
-
-/**
- * Utility class that allows adding and removing accounts.
- *
- * This test depend on {@link MockAccountService}, which provides authenticator of type
- * {@link MockAccountService#ACCOUNT_TYPE}.
- */
-public class AccountUtilsTest extends AndroidTestCase {
-
-    private final static Account ACCOUNT_0 = new Account("user0",
-            MockAccountAuthenticator.ACCOUNT_TYPE);
-    private AccountManager mAccountManager;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mAccountManager = (AccountManager) getContext().getSystemService(Context.ACCOUNT_SERVICE);
-    }
-
-    public void testAddAccount() throws Exception {
-        assertEquals(0, mAccountManager.getAccountsByType(MockAccountAuthenticator.ACCOUNT_TYPE)
-                .length);
-        assertTrue(mAccountManager.addAccountExplicitly(ACCOUNT_0, "password", null));
-        assertEquals(1, mAccountManager.getAccountsByType(MockAccountAuthenticator.ACCOUNT_TYPE)
-                .length);
-    }
-
-    public void testRemoveAccounts() throws Exception {
-        removeAllAccountsForType(mAccountManager, MockAccountAuthenticator.ACCOUNT_TYPE);
-    }
-
-    static void removeAllAccountsForType(AccountManager am, String accountType)
-            throws Exception {
-        Account[] accounts = am.getAccountsByType(accountType);
-        for (Account account : accounts) {
-            AccountManagerFuture<Boolean> result = am.removeAccount(account, null, null);
-            assertTrue(result.getResult());
-        }
-        assertEquals(0, am.getAccountsByType(accountType).length);
-    }
-}
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/AlwaysOnVpnTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/AlwaysOnVpnTest.java
new file mode 100644
index 0000000..edeefd3
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/AlwaysOnVpnTest.java
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.deviceandprofileowner;
+
+import android.net.ConnectivityManager.NetworkCallback;
+import android.net.ConnectivityManager;
+import android.net.Network;
+import android.net.NetworkCapabilities;
+import android.net.NetworkRequest;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.system.StructPollfd;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.util.Arrays;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import static android.system.OsConstants.AF_INET;
+import static android.system.OsConstants.IPPROTO_ICMP;
+import static android.system.OsConstants.POLLIN;
+import static android.system.OsConstants.SOCK_DGRAM;
+
+/**
+ * Validates that a device owner or profile owner can set an always-on VPN without user action.
+ *
+ * A trivial VPN app is installed which reflects ping packets back to the sender. One ping packet is
+ * sent, received after its round-trip, and compared to the original packet to make sure nothing
+ * strange happened on the way through the VPN.
+ *
+ * All of the addresses in this test are fictional and any resemblance to real addresses is the
+ * result of a misconfigured network.
+ */
+public class AlwaysOnVpnTest extends BaseDeviceAdminTest {
+
+    private static final String VPN_PACKAGE = "com.android.cts.vpnfirewall";
+    private static final int NETWORK_TIMEOUT_MS = 5000;
+    private static final int NETWORK_SETTLE_GRACE_MS = 100;
+    private static final int SOCKET_TIMEOUT_MS = 5000;
+
+    private static final int ICMP_ECHO_REQUEST = 0x08;
+    private static final int ICMP_ECHO_REPLY = 0x00;
+
+    @Override
+    public void tearDown() throws Exception {
+        mDevicePolicyManager.setAlwaysOnVpnPackage(ADMIN_RECEIVER_COMPONENT, null);
+        super.tearDown();
+    }
+
+    public void testAlwaysOnVpn() throws Exception {
+        // test always-on is null by default
+        assertNull(mDevicePolicyManager.getAlwaysOnVpnPackage(ADMIN_RECEIVER_COMPONENT));
+
+        final CountDownLatch vpnLatch = new CountDownLatch(1);
+
+        final ConnectivityManager cm =
+                (ConnectivityManager) mContext.getSystemService(mContext.CONNECTIVITY_SERVICE);
+
+        final NetworkRequest request = new NetworkRequest.Builder()
+                .addTransportType(NetworkCapabilities.TRANSPORT_VPN)
+                .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
+                .removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
+                .build();
+        final ConnectivityManager.NetworkCallback callback
+                = new ConnectivityManager.NetworkCallback() {
+            @Override
+            public void onAvailable(Network net) {
+                vpnLatch.countDown();
+            }
+        };
+
+        cm.registerNetworkCallback(request, callback);
+        try {
+            mDevicePolicyManager.setAlwaysOnVpnPackage(ADMIN_RECEIVER_COMPONENT, VPN_PACKAGE);
+            assertEquals(VPN_PACKAGE, mDevicePolicyManager.getAlwaysOnVpnPackage(
+                    ADMIN_RECEIVER_COMPONENT));
+            assertTrue("Took too long waiting to establish a VPN-backed connection",
+                    vpnLatch.await(NETWORK_TIMEOUT_MS, TimeUnit.MILLISECONDS));
+
+            // Give the VPN a moment to start transmitting data.
+            Thread.sleep(NETWORK_SETTLE_GRACE_MS);
+        } catch (InterruptedException e) {
+            fail("Interrupted while waiting to send ping: " + e);
+        } finally {
+            cm.unregisterNetworkCallback(callback);
+        }
+
+        // IP address reserved for documentation by rfc5737
+        checkPing("192.0.2.4");
+    }
+
+    private static void checkPing(String host) throws ErrnoException, IOException {
+        FileDescriptor socket = Os.socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP);
+
+        // Create an ICMP message
+        final int identifier = 0x7E57;
+        final String message = "test packet";
+        byte[] echo = createIcmpMessage(ICMP_ECHO_REQUEST, 0x00, identifier, 0, message.getBytes());
+
+        // Send the echo packet.
+        int port = new InetSocketAddress(0).getPort();
+        Os.connect(socket, InetAddress.getByName(host), port);
+        Os.write(socket, echo, 0, echo.length);
+
+        // Expect a reply.
+        StructPollfd pollfd = new StructPollfd();
+        pollfd.events = (short) POLLIN;
+        pollfd.fd = socket;
+        int ret = Os.poll(new StructPollfd[] { pollfd }, SOCKET_TIMEOUT_MS);
+        assertEquals("Expected reply after sending ping", 1, ret);
+
+        byte[] reply = new byte[echo.length];
+        int read = Os.read(socket, reply, 0, echo.length);
+        assertEquals(echo.length, read);
+
+        // Ignore control type differences since echo=8, reply=0.
+        assertEquals(echo[0], ICMP_ECHO_REQUEST);
+        assertEquals(reply[0], ICMP_ECHO_REPLY);
+        echo[0] = 0;
+        reply[0] = 0;
+
+        // Fix ICMP ID which kernel will have changed on the way out.
+        InetSocketAddress local = (InetSocketAddress) Os.getsockname(socket);
+        port = local.getPort();
+        echo[4] = (byte) ((port >> 8) & 0xFF);
+        echo[5] = (byte) (port & 0xFF);
+
+        // Ignore checksum differences since the types are not supposed to match.
+        echo[2] = echo[3] = 0;
+        reply[2] = reply[3] = 0;
+
+        assertTrue("Packet contents do not match."
+                + "\nEcho packet:  " + Arrays.toString(echo)
+                + "\nReply packet: " + Arrays.toString(reply), Arrays.equals(echo, reply));
+    }
+
+    private static byte[] createIcmpMessage(int type, int code, int extra1, int extra2,
+            byte[] data) throws IOException {
+        ByteArrayOutputStream output = new ByteArrayOutputStream();
+        DataOutputStream stream = new DataOutputStream(output);
+        stream.writeByte(type);
+        stream.writeByte(code);
+        stream.writeShort(/* checksum */ 0);
+        stream.writeShort((short) extra1);
+        stream.writeShort((short) extra2);
+        stream.write(data, 0, data.length);
+        return output.toByteArray();
+    }
+}
+
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ApplicationRestrictionsActivity.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ApplicationRestrictionsActivity.java
deleted file mode 100644
index ccf8222..0000000
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ApplicationRestrictionsActivity.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.cts.deviceandprofileowner;
-
-import android.app.Activity;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.Bundle;
-import android.os.UserManager;
-
-/**
- * Test activity for setApplicationRestrictions().
- *
- * The actual test will set restrictions for this package, and the purpose of this
- * activity is to listen for the ACTION_APPLICATION_RESTRICTIONS_CHANGED broadcast
- * and relay the retrieved restriction bundle back to the test for validation.
- */
-public class ApplicationRestrictionsActivity extends Activity {
-
-    // Incoming intent type
-    public static final String FINISH = "finishActivity";
-
-    // Outgoing broadcast
-    public static final String REGISTERED_ACTION =
-            "com.android.cts.deviceandprofileowner.APP_RESTRICTION_REGISTERED";
-    public static final String RESTRICTION_ACTION =
-            "com.android.cts.deviceandprofileowner.APP_RESTRICTION_VALUE";
-
-    private UserManager mUserManager;
-
-    private final BroadcastReceiver mAppRestrictionReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            broadcastRestriction();
-        }
-    };
-
-    private void broadcastRestriction() {
-        Bundle restrictions = mUserManager.getApplicationRestrictions(getPackageName());
-        Intent intent = new Intent(RESTRICTION_ACTION);
-        intent.putExtra("value", restrictions);
-        sendBroadcast(intent);
-    }
-
-    @Override
-    protected void onNewIntent(Intent intent) {
-        super.onNewIntent(intent);
-        handleIntent(intent);
-    }
-
-    @Override
-    protected void onCreate(android.os.Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        handleIntent(getIntent());
-    }
-
-    @Override
-    protected void onResume() {
-        super.onResume();
-        mUserManager = (UserManager) getSystemService(Context.USER_SERVICE);
-        IntentFilter filter = new IntentFilter(Intent.ACTION_APPLICATION_RESTRICTIONS_CHANGED);
-        registerReceiver(mAppRestrictionReceiver, filter);
-        sendBroadcast(new Intent(REGISTERED_ACTION));
-    }
-
-    @Override
-    protected void onPause() {
-        super.onPause();
-        unregisterReceiver(mAppRestrictionReceiver);
-    }
-
-    private void handleIntent(Intent intent) {
-        if (intent.getBooleanExtra(FINISH, false)) {
-            finish();
-        }
-    }
-
-}
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ApplicationRestrictionsTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ApplicationRestrictionsTest.java
index 98ae202..9ecc339 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ApplicationRestrictionsTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ApplicationRestrictionsTest.java
@@ -16,104 +16,214 @@
 package com.android.cts.deviceandprofileowner;
 
 import android.content.BroadcastReceiver;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.pm.PackageManager.NameNotFoundException;
 import android.os.Bundle;
 import android.os.Parcelable;
+import android.os.UserManager;
+import android.test.MoreAsserts;
 
 import java.util.concurrent.Semaphore;
 import java.util.concurrent.TimeUnit;
 
 /**
- * Functionality tests for setApplicationRestrictions and getApplicationRestrictions
- * in DevicePolicyManager.
+ * Functionality tests for application restrictions APIs.
  *
- * First of all, these two APIs are executed locally to assert that what you set
- * can later be retrieved via the getter. It also fires up an external activity
- * (which runs in com.google.android.xts.gmscore, unlike the test code itself
- * which runs in the test target package com.google.android.gms due to
- * instrumentation) to observe an application's view of its restrictions.
- * The activity listens to ACTION_APPLICATION_RESTRICTIONS_CHANGED broadcast
- * which is fired by the system whenever its restriction is modified,
- * and relays the value back to this test for verification.
+ * <p>APIs are executed locally to assert that what you set can later be retrieved via the getter.
+ * It also fires up an external activity to observe an application's view of its restrictions.
+ *
+ * <p>Finally, it checks that the {@link Intent#ACTION_APPLICATION_RESTRICTIONS_CHANGED} broadcast
+ * is sent whenever app restrictions are modified for a given package.
  */
 public class ApplicationRestrictionsTest extends BaseDeviceAdminTest {
 
-    private static final String[] testStrings = new String[] {
+    private static final String APP_RESTRICTIONS_TARGET_PKG =
+            "com.android.cts.apprestrictions.targetapp";
+    private static final String APP_RESTRICTIONS_ACTIVITY_NAME =
+            APP_RESTRICTIONS_TARGET_PKG + ".ApplicationRestrictionsActivity";
+    private static final String ACTION_RESTRICTIONS_VALUE =
+            "com.android.cts.apprestrictions.targetapp.RESTRICTIONS_VALUE";
+
+    private static final String OTHER_PACKAGE = APP_RESTRICTIONS_TARGET_PKG + "dummy";
+
+    private static final String[] TEST_STRINGS = new String[] {
             "<bad/>",
             ">worse!\"£$%^&*()'<",
             "<JSON>\"{ \\\"One\\\": { \\\"OneOne\\\": \\\"11\\\", \\\""
                     + "OneTwo\\\": \\\"12\\\" }, \\\"Two\\\": \\\"2\\\" } <JSON/>\""
     };
 
-    private final Semaphore mOnRegisteredSemaphore = new Semaphore(0);
-    private final Semaphore mOnRestrictionSemaphore = new Semaphore(0);
+    private static final Bundle BUNDLE_0 = createBundle0();
+    private static final Bundle BUNDLE_1 = createBundle1();
+
+    private static final long RESTRICTIONS_TIMEOUT_SECONDS = 10;
+
+    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (ACTION_RESTRICTIONS_VALUE.equals(action)) {
+                mReceivedRestrictions = intent.getBundleExtra("value");
+                mOnRestrictionsReceivedFromAppSemaphore.release();
+            } else if (Intent.ACTION_APPLICATION_RESTRICTIONS_CHANGED.equals(action)) {
+                mOnAppRestrictionsChangedSemahore.release();
+            }
+        }
+    };
+
+    private final Semaphore mOnAppRestrictionsChangedSemahore = new Semaphore(0);
+    private final Semaphore mOnRestrictionsReceivedFromAppSemaphore = new Semaphore(0);
     private Bundle mReceivedRestrictions;
+    private UserManager mUserManager;
 
     @Override
     protected void setUp() throws Exception {
         super.setUp();
+
+        mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+
         IntentFilter filter = new IntentFilter();
-        filter.addAction(ApplicationRestrictionsActivity.REGISTERED_ACTION);
-        filter.addAction(ApplicationRestrictionsActivity.RESTRICTION_ACTION);
+        filter.addAction(ACTION_RESTRICTIONS_VALUE);
+        filter.addAction(Intent.ACTION_APPLICATION_RESTRICTIONS_CHANGED);
         mContext.registerReceiver(mReceiver, filter);
     }
 
     @Override
     protected void tearDown() throws Exception {
         mContext.unregisterReceiver(mReceiver);
+
+        mDevicePolicyManager.setApplicationRestrictions(
+                ADMIN_RECEIVER_COMPONENT, APP_RESTRICTIONS_TARGET_PKG, new Bundle());
+        mDevicePolicyManager.setApplicationRestrictions(
+                ADMIN_RECEIVER_COMPONENT, OTHER_PACKAGE, new Bundle());
+        mDevicePolicyManager.setApplicationRestrictions(
+                ADMIN_RECEIVER_COMPONENT, mContext.getPackageName(), new Bundle());
+
         super.tearDown();
     }
 
+    public void testNullComponentThrowsException() {
+        try {
+            mDevicePolicyManager.setApplicationRestrictions(
+                    null, APP_RESTRICTIONS_TARGET_PKG, null);
+            fail("Expected SecurityException not thrown");
+        } catch (SecurityException expected) {
+            MoreAsserts.assertContainsRegex(
+                    "cannot manage application restrictions", expected.getMessage());
+        }
+        try {
+            mDevicePolicyManager.getApplicationRestrictions(null, APP_RESTRICTIONS_TARGET_PKG);
+            fail("Expected SecurityException not thrown");
+        } catch (SecurityException expected) {
+            MoreAsserts.assertContainsRegex(
+                    "cannot manage application restrictions", expected.getMessage());
+        }
+    }
+
     public void testSetApplicationRestrictions() {
-        final String CTS_PACKAGE = PACKAGE_NAME;
-        final String OTHER_PACKAGE = CTS_PACKAGE + "dummy";
-
-        startAndWait();
-
-        Bundle bundle0 = createBundle0();
-        Bundle bundle1 = createBundle1();
-
         // Test setting restrictions
-        mDevicePolicyManager.setApplicationRestrictions(ADMIN_RECEIVER_COMPONENT, CTS_PACKAGE,
-                bundle0);
-        mDevicePolicyManager.setApplicationRestrictions(ADMIN_RECEIVER_COMPONENT, OTHER_PACKAGE,
-                bundle1);
+        mDevicePolicyManager.setApplicationRestrictions(
+                ADMIN_RECEIVER_COMPONENT, APP_RESTRICTIONS_TARGET_PKG, BUNDLE_0);
+        mDevicePolicyManager.setApplicationRestrictions(
+                ADMIN_RECEIVER_COMPONENT, OTHER_PACKAGE, BUNDLE_1);
 
         // Retrieve restrictions locally and make sure they are what we put in.
-        assertBundle0(mDevicePolicyManager.getApplicationRestrictions(ADMIN_RECEIVER_COMPONENT,
-                CTS_PACKAGE));
-        assertBundle1(mDevicePolicyManager.getApplicationRestrictions(ADMIN_RECEIVER_COMPONENT,
-                OTHER_PACKAGE));
+        assertBundle0(mDevicePolicyManager.getApplicationRestrictions(
+                ADMIN_RECEIVER_COMPONENT, APP_RESTRICTIONS_TARGET_PKG));
+        assertBundle1(mDevicePolicyManager.getApplicationRestrictions(
+                ADMIN_RECEIVER_COMPONENT, OTHER_PACKAGE));
 
-        // The test activity should have received a change_restriction broadcast
-        // and relay the value back to us.
-        assertBundle0(waitForChangedRestriction());
+        // Check that the target app can retrieve the same restrictions.
+        assertBundle0(waitForRestrictionsValueFromTestActivity());
 
         // Test overwriting
-        mDevicePolicyManager.setApplicationRestrictions(ADMIN_RECEIVER_COMPONENT, CTS_PACKAGE,
-                bundle1);
-        assertBundle1(mDevicePolicyManager.getApplicationRestrictions(ADMIN_RECEIVER_COMPONENT,
-                CTS_PACKAGE));
-        assertBundle1(waitForChangedRestriction());
+        mDevicePolicyManager.setApplicationRestrictions(
+                ADMIN_RECEIVER_COMPONENT, APP_RESTRICTIONS_TARGET_PKG, BUNDLE_1);
+        assertBundle1(mDevicePolicyManager.getApplicationRestrictions(
+                ADMIN_RECEIVER_COMPONENT, APP_RESTRICTIONS_TARGET_PKG));
+        assertBundle1(waitForRestrictionsValueFromTestActivity());
 
-        // Cleanup
-        mDevicePolicyManager.setApplicationRestrictions(ADMIN_RECEIVER_COMPONENT, CTS_PACKAGE,
-                new Bundle());
+        mDevicePolicyManager.setApplicationRestrictions(
+                ADMIN_RECEIVER_COMPONENT, APP_RESTRICTIONS_TARGET_PKG, new Bundle());
         assertTrue(mDevicePolicyManager.getApplicationRestrictions(
-                ADMIN_RECEIVER_COMPONENT, CTS_PACKAGE).isEmpty());
-        assertTrue(waitForChangedRestriction().isEmpty());
-        mDevicePolicyManager.setApplicationRestrictions(ADMIN_RECEIVER_COMPONENT, OTHER_PACKAGE,
-                new Bundle());
+                ADMIN_RECEIVER_COMPONENT, APP_RESTRICTIONS_TARGET_PKG).isEmpty());
+        assertTrue(waitForRestrictionsValueFromTestActivity().isEmpty());
+
+        mDevicePolicyManager.setApplicationRestrictions(
+                ADMIN_RECEIVER_COMPONENT, OTHER_PACKAGE, null);
         assertTrue(mDevicePolicyManager.getApplicationRestrictions(
                 ADMIN_RECEIVER_COMPONENT, OTHER_PACKAGE).isEmpty());
+    }
 
-        finish();
+    public void testCanRetrieveOwnRestrictionsViaUserManager() {
+        final String packageName = mContext.getPackageName();
+
+        mDevicePolicyManager.setApplicationRestrictions(
+                ADMIN_RECEIVER_COMPONENT, packageName, BUNDLE_0);
+        assertBundle0(mDevicePolicyManager.getApplicationRestrictions(
+                ADMIN_RECEIVER_COMPONENT, packageName));
+
+        // Check that we got the restrictions changed callback.
+        assertBundle0(waitForRestrictionsChangedBroadcast());
+
+        mDevicePolicyManager.setApplicationRestrictions(
+                ADMIN_RECEIVER_COMPONENT, packageName, BUNDLE_1);
+        assertBundle1(mDevicePolicyManager.getApplicationRestrictions(
+                ADMIN_RECEIVER_COMPONENT, packageName));
+        assertBundle1(waitForRestrictionsChangedBroadcast());
+    }
+
+    public void testCannotRetrieveOtherPackageRestrictionsViaUserManager() {
+        try {
+            mUserManager.getApplicationRestrictions(OTHER_PACKAGE);
+            fail("Expected SecurityException not thrown");
+        } catch (SecurityException expected) {
+        }
+    }
+
+    public void testSetApplicationRestrictionsManagingPackage() throws NameNotFoundException {
+        final String previousValue = mDevicePolicyManager.getApplicationRestrictionsManagingPackage(
+                ADMIN_RECEIVER_COMPONENT);
+        try {
+            mDevicePolicyManager.setApplicationRestrictionsManagingPackage(
+                    ADMIN_RECEIVER_COMPONENT, APP_RESTRICTIONS_TARGET_PKG);
+            assertEquals(APP_RESTRICTIONS_TARGET_PKG,
+                    mDevicePolicyManager.getApplicationRestrictionsManagingPackage(
+                            ADMIN_RECEIVER_COMPONENT));
+            mDevicePolicyManager.setApplicationRestrictionsManagingPackage(
+                    ADMIN_RECEIVER_COMPONENT, null);
+            assertNull(mDevicePolicyManager.getApplicationRestrictionsManagingPackage(
+                    ADMIN_RECEIVER_COMPONENT));
+        } finally {
+            mDevicePolicyManager.setApplicationRestrictionsManagingPackage(
+                    ADMIN_RECEIVER_COMPONENT, previousValue);
+            assertEquals(previousValue,
+                    mDevicePolicyManager.getApplicationRestrictionsManagingPackage(
+                            ADMIN_RECEIVER_COMPONENT));
+        }
+    }
+
+    public void testSetApplicationRestrictionsManagingPackageForNotInstalledPackage()
+            throws NameNotFoundException {
+        try {
+            mDevicePolicyManager.setApplicationRestrictionsManagingPackage(ADMIN_RECEIVER_COMPONENT,
+                    OTHER_PACKAGE);
+            fail("Not throwing exception for not installed package name");
+        } catch (NameNotFoundException expected) {
+            MoreAsserts.assertContainsRegex(OTHER_PACKAGE, expected.getMessage());
+        } finally {
+            mDevicePolicyManager.setApplicationRestrictionsManagingPackage(ADMIN_RECEIVER_COMPONENT,
+                    null);
+            assertNull(mDevicePolicyManager.getApplicationRestrictionsManagingPackage(
+                    ADMIN_RECEIVER_COMPONENT));
+        }
     }
 
     // Should be consistent with assertBundle0
-    private Bundle createBundle0() {
+    private static Bundle createBundle0() {
         Bundle result = new Bundle();
         // Tests for 6 allowed types: Integer, Boolean, String, String[], Bundle and Parcelable[]
         // Also test for string escaping handling
@@ -123,7 +233,7 @@
         // If a null is stored, "" will be read back
         result.putString("empty", "");
         result.putString("string", "text");
-        result.putStringArray("string[]", testStrings);
+        result.putStringArray("string[]", TEST_STRINGS);
 
         // Adding a bundle, which contain 2 nested restrictions - bundle_string and bundle_int
         Bundle bundle = new Bundle();
@@ -153,9 +263,9 @@
         assertEquals("text", bundle.getString("string"));
 
         String[] strings = bundle.getStringArray("string[]");
-        assertTrue(strings != null && strings.length == testStrings.length);
+        assertTrue(strings != null && strings.length == TEST_STRINGS.length);
         for (int i = 0; i < strings.length; i++) {
-            assertEquals(strings[i], testStrings[i]);
+            assertEquals(strings[i], TEST_STRINGS[i]);
         }
 
         Bundle childBundle = bundle.getBundle("bundle");
@@ -177,7 +287,7 @@
     }
 
     // Should be consistent with assertBundle1
-    private Bundle createBundle1() {
+    private static Bundle createBundle1() {
         Bundle result = new Bundle();
         result.putInt("dummy", 1);
         return result;
@@ -189,53 +299,34 @@
         assertEquals(1, bundle.getInt("dummy"));
     }
 
-    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            String action = intent.getAction();
-            if (ApplicationRestrictionsActivity.REGISTERED_ACTION.equals(action)) {
-                mOnRegisteredSemaphore.release();
-            } else if (ApplicationRestrictionsActivity.RESTRICTION_ACTION.equals(action)) {
-                mReceivedRestrictions = intent.getBundleExtra("value");
-                mOnRestrictionSemaphore.release();
-            }
-        }
-    };
-
-    private void startTestActivity(String command) {
-        Intent intent = new Intent();
-        intent.setClassName(PACKAGE_NAME, ApplicationRestrictionsActivity.class.getName());
-        intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
-
-        if (command != null) {
-            intent.putExtra(command, true);
-        }
-        mContext.startActivity(intent);
+    private void startTestActivity() {
+        mContext.startActivity(new Intent()
+                .setComponent(new ComponentName(
+                        APP_RESTRICTIONS_TARGET_PKG, APP_RESTRICTIONS_ACTIVITY_NAME))
+                .addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK));
     }
 
-    private void startAndWait() {
-        startTestActivity(null);
-        // Wait until the activity has registered its broadcast receiver and ready for incoming
-        // restriction changes.
-        try {
-            assertTrue(mOnRegisteredSemaphore.tryAcquire(5, TimeUnit.SECONDS));
-        } catch (InterruptedException e) {
-            fail("Start ApplicationRestrictionActivity interrupted");
-        }
-    }
+    private Bundle waitForRestrictionsValueFromTestActivity() {
+        startTestActivity();
 
-    private Bundle waitForChangedRestriction() {
         try {
-            assertTrue(mOnRestrictionSemaphore.tryAcquire(5, TimeUnit.SECONDS));
+            assertTrue(mOnRestrictionsReceivedFromAppSemaphore.tryAcquire(
+                    RESTRICTIONS_TIMEOUT_SECONDS, TimeUnit.SECONDS));
         } catch (InterruptedException e) {
-            fail("getRestrictionsAndWait() interrupted");
+            fail("waitForRestrictionsValueFromTestActivity() interrupted");
         }
 
         return mReceivedRestrictions;
     }
 
-    private void finish() {
-        startTestActivity(ApplicationRestrictionsActivity.FINISH);
-    }
+    private Bundle waitForRestrictionsChangedBroadcast() {
+        try {
+            assertTrue(mOnAppRestrictionsChangedSemahore.tryAcquire(
+                    RESTRICTIONS_TIMEOUT_SECONDS, TimeUnit.SECONDS));
+        } catch (InterruptedException e) {
+            fail("waitForRestrictionsChangedBroadcast() interrupted");
+        }
 
+        return mUserManager.getApplicationRestrictions(mContext.getPackageName());
+    }
 }
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/AudioRestrictionTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/AudioRestrictionTest.java
new file mode 100644
index 0000000..0c60fa4
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/AudioRestrictionTest.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.deviceandprofileowner;
+
+import android.content.Context;
+import android.media.AudioManager;
+import android.os.SystemClock;
+import android.os.UserManager;
+
+import java.util.Objects;
+import java.util.concurrent.Callable;
+
+public class AudioRestrictionTest extends BaseDeviceAdminTest {
+
+    private AudioManager mAudioManager;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
+    }
+
+    private void disallowAdjustVolumeTestInternal(boolean setByAddUserRestiction) throws Exception {
+        try {
+            // Set volume of ringtone to be 1.
+            mAudioManager.setStreamVolume(AudioManager.STREAM_RING, 1, /* flag= */ 0);
+
+            // Disallow adjusting volume.
+            mDevicePolicyManager.addUserRestriction(ADMIN_RECEIVER_COMPONENT,
+                    UserManager.DISALLOW_ADJUST_VOLUME);
+            waitUntil(true, new Callable<Boolean>() {
+                @Override
+                public Boolean call() throws Exception {
+                    return mDevicePolicyManager.isMasterVolumeMuted(ADMIN_RECEIVER_COMPONENT);
+                }
+            });
+            // Verify that volume can't be changed.
+            mAudioManager.adjustVolume(AudioManager.ADJUST_RAISE, /* flag= */ 0);
+            assertEquals(1, mAudioManager.getStreamVolume(AudioManager.STREAM_RING));
+
+            // Allowing adjusting volume.
+            mDevicePolicyManager.clearUserRestriction(ADMIN_RECEIVER_COMPONENT,
+                    UserManager.DISALLOW_ADJUST_VOLUME);
+            waitUntil(false, new Callable<Boolean>() {
+                @Override
+                public Boolean call() throws Exception {
+                    return mDevicePolicyManager.isMasterVolumeMuted(ADMIN_RECEIVER_COMPONENT);
+                }
+            });
+            // Verify the volume can be changed now.
+            mAudioManager.adjustVolume(AudioManager.ADJUST_RAISE,  /* flag= */ 0);
+            waitUntil(2, new Callable<Integer>() {
+                @Override
+                public Integer call() throws Exception {
+                    return mAudioManager.getStreamVolume(AudioManager.STREAM_RING);
+                }
+            });
+        } finally {
+            // Clear the restriction.
+            mDevicePolicyManager.clearUserRestriction(ADMIN_RECEIVER_COMPONENT,
+                    UserManager.DISALLOW_ADJUST_VOLUME);
+            waitUntil(false, new Callable<Boolean>() {
+                @Override
+                public Boolean call() throws Exception {
+                    return mDevicePolicyManager.isMasterVolumeMuted(ADMIN_RECEIVER_COMPONENT);
+                }
+            });
+        }
+    }
+
+    public void testDisallowUnmuteMicrophone() throws Exception {
+        try {
+            mAudioManager.setMicrophoneMute(false);
+            assertFalse(mAudioManager.isMicrophoneMute());
+
+            // Disallow the microphone to be unmuted.
+            mDevicePolicyManager.addUserRestriction(
+                    ADMIN_RECEIVER_COMPONENT, UserManager.DISALLOW_UNMUTE_MICROPHONE);
+            waitUntil(true, new Callable<Boolean>() {
+                @Override
+                public Boolean call() throws Exception {
+                    return mAudioManager.isMicrophoneMute();
+                }
+            });
+            // Verify that we can't unmute the microphone.
+            mAudioManager.setMicrophoneMute(false);
+            assertTrue(mAudioManager.isMicrophoneMute());
+        } finally {
+            // Clear the restriction
+            mDevicePolicyManager.clearUserRestriction(
+                    ADMIN_RECEIVER_COMPONENT, UserManager.DISALLOW_UNMUTE_MICROPHONE);
+            waitUntil(false, new Callable<Boolean>() {
+                @Override
+                public Boolean call() throws Exception {
+                    return mAudioManager.isMicrophoneMute();
+                }
+            });
+        }
+    }
+
+    private <T> void waitUntil(T expected, Callable<T> c) throws Exception {
+        final long start = SystemClock.elapsedRealtime();
+        final int TIMEOUT_MS = 5 * 1000;
+
+        T actual;
+        while (!Objects.equals(expected, actual = c.call())) {
+            if ((SystemClock.elapsedRealtime() - start) >= TIMEOUT_MS) {
+                fail(String.format("Timed out waiting the value to change to %s (actual=%s)",
+                        expected, actual));
+            }
+            Thread.sleep(200);
+        }
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/BaseDeviceAdminTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/BaseDeviceAdminTest.java
index 148d8a8..5a8186b 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/BaseDeviceAdminTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/BaseDeviceAdminTest.java
@@ -19,6 +19,9 @@
 import android.app.admin.DevicePolicyManager;
 import android.content.ComponentName;
 import android.content.Context;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.os.UserManager;
 import android.test.InstrumentationTestCase;
 
 /**
@@ -37,6 +40,7 @@
             PACKAGE_NAME, BasicAdminReceiver.class.getName());
 
     protected DevicePolicyManager mDevicePolicyManager;
+    protected UserManager mUserManager;
     protected Context mContext;
 
     @Override
@@ -44,13 +48,21 @@
         super.setUp();
         mContext = getInstrumentation().getContext();
 
-        mDevicePolicyManager = (DevicePolicyManager)
-            mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
+        mDevicePolicyManager = mContext.getSystemService(DevicePolicyManager.class);
         assertNotNull(mDevicePolicyManager);
 
+        mUserManager = mContext.getSystemService(UserManager.class);
+        assertNotNull(mUserManager);
+
         assertTrue(mDevicePolicyManager.isAdminActive(ADMIN_RECEIVER_COMPONENT));
         assertTrue("App is neither device nor profile owner",
                 mDevicePolicyManager.isProfileOwnerApp(PACKAGE_NAME) ||
                 mDevicePolicyManager.isDeviceOwnerApp(PACKAGE_NAME));
     }
+
+    protected int getTargetApiLevel() throws Exception {
+        final PackageManager pm = mContext.getPackageManager();
+        final PackageInfo pi = pm.getPackageInfo(mContext.getPackageName(), /* flags =*/ 0);
+        return pi.applicationInfo.targetSdkVersion;
+    }
 }
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ClearDeviceOwnerTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ClearDeviceOwnerTest.java
index 2fe0569..a7bb762e 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ClearDeviceOwnerTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ClearDeviceOwnerTest.java
@@ -30,13 +30,12 @@
         mDevicePolicyManager = (DevicePolicyManager)
                 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
         if (mDevicePolicyManager != null) {
-            removeActiveAdmin(BaseDeviceAdminTest.ADMIN_RECEIVER_COMPONENT);
             if (mDevicePolicyManager.isDeviceOwnerApp(BaseDeviceAdminTest.PACKAGE_NAME)) {
                 mDevicePolicyManager.clearDeviceOwnerApp(BaseDeviceAdminTest.PACKAGE_NAME);
             }
-            assertFalse(mDevicePolicyManager.isAdminActive(
-                    BaseDeviceAdminTest.ADMIN_RECEIVER_COMPONENT));
             assertFalse(mDevicePolicyManager.isDeviceOwnerApp(BaseDeviceAdminTest.PACKAGE_NAME));
+
+            Utils.assertNotActiveAdmin(getContext(), BaseDeviceAdminTest.ADMIN_RECEIVER_COMPONENT);
         }
 
         super.tearDown();
@@ -46,13 +45,4 @@
     // side test once a test case is finished.
     public void testClearDeviceOwner() {
     }
-
-    private void removeActiveAdmin(ComponentName cn) throws InterruptedException {
-        if (mDevicePolicyManager.isAdminActive(cn)) {
-            mDevicePolicyManager.removeActiveAdmin(cn);
-            for (int i = 0; i < 1000 && mDevicePolicyManager.isAdminActive(cn); i++) {
-                Thread.sleep(100);
-            }
-        }
-    }
 }
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ClearProfileOwnerNegativeTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ClearProfileOwnerNegativeTest.java
new file mode 100644
index 0000000..30ae0cd
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ClearProfileOwnerNegativeTest.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.deviceandprofileowner;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.Context;
+import android.test.AndroidTestCase;
+import android.test.MoreAsserts;
+
+public class ClearProfileOwnerNegativeTest extends AndroidTestCase {
+
+    private DevicePolicyManager mDevicePolicyManager;
+
+    @Override
+    protected void tearDown() throws Exception {
+        mDevicePolicyManager = (DevicePolicyManager)
+                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
+        if (mDevicePolicyManager.isProfileOwnerApp(BaseDeviceAdminTest.PACKAGE_NAME)) {
+            try {
+                mDevicePolicyManager.clearProfileOwner(BaseDeviceAdminTest.ADMIN_RECEIVER_COMPONENT);
+            } catch (SecurityException e) {
+                MoreAsserts.assertContainsRegex("clear profile owner", e.getMessage());
+            }
+        }
+
+        super.tearDown();
+    }
+
+    public void testClearProfileOwnerNegative() {
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ClearProfileOwnerTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ClearProfileOwnerTest.java
new file mode 100644
index 0000000..3e912e1
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ClearProfileOwnerTest.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.deviceandprofileowner;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.test.AndroidTestCase;
+
+public class ClearProfileOwnerTest extends AndroidTestCase {
+
+    private DevicePolicyManager mDevicePolicyManager;
+
+    @Override
+    protected void tearDown() throws Exception {
+        mDevicePolicyManager = (DevicePolicyManager)
+                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
+        if (mDevicePolicyManager != null) {
+            if (mDevicePolicyManager.isProfileOwnerApp(BaseDeviceAdminTest.PACKAGE_NAME)) {
+                mDevicePolicyManager.clearProfileOwner(
+                        BaseDeviceAdminTest.ADMIN_RECEIVER_COMPONENT);
+            }
+            assertFalse(mDevicePolicyManager.isProfileOwnerApp(BaseDeviceAdminTest.PACKAGE_NAME));
+
+            Utils.assertNotActiveAdmin(getContext(), BaseDeviceAdminTest.ADMIN_RECEIVER_COMPONENT);
+        }
+
+        super.tearDown();
+    }
+
+    // This test clears the profile owner and active admin on tearDown(). To be called from the host
+    // side test once a test case is finished.
+    public void testClearProfileOwner() {
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/CustomizationRestrictionsTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/CustomizationRestrictionsTest.java
new file mode 100644
index 0000000..ebc833b
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/CustomizationRestrictionsTest.java
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.deviceandprofileowner;
+
+import android.app.WallpaperManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.os.Process;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.cts.util.BitmapUtils;
+import com.android.cts.deviceandprofileowner.R;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Method;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * These tests verify that the device / profile owner can use appropriate API for customization
+ * (DevicePolicyManager.setUserIcon(), WallpaperManager.setBitmap(), etc.) even in case,
+ * when appropriate restrictions are set. The tested restrictions are
+ * {@link UserManager#DISALLOW_SET_WALLPAPER} and {@link UserManager#DISALLOW_SET_USER_ICON}.
+ */
+public class CustomizationRestrictionsTest extends BaseDeviceAdminTest {
+
+    private static final int BROADCAST_TIMEOUT_SEC = 3;
+
+    // Class sets/resets restriction in try-with-resources statement.
+    private class RestrictionApplicator implements Closeable {
+        private final String mRestriction;
+        RestrictionApplicator(String restriction) {
+            mRestriction = restriction;
+            mDevicePolicyManager.addUserRestriction(ADMIN_RECEIVER_COMPONENT, mRestriction);
+        }
+
+        @Override
+        public void close() throws IOException {
+            mDevicePolicyManager.clearUserRestriction(ADMIN_RECEIVER_COMPONENT, mRestriction);
+        }
+    }
+
+    // Class subscribes/unsubscribe for broadcast notification in try-with-resources statement.
+    private class BroadcastReceiverRegistrator implements Closeable {
+        private final BlockingBroadcastReceiver mReceiver;
+        public BroadcastReceiverRegistrator(String action) {
+            final IntentFilter filter = new IntentFilter();
+            filter.addAction(action);
+            mReceiver = new BlockingBroadcastReceiver();
+            mContext.registerReceiver(mReceiver, filter);
+        }
+
+        @Override
+        public void close() throws IOException {
+            mContext.unregisterReceiver(mReceiver);
+        }
+
+        public void waitForBroadcast() throws Exception {
+            mReceiver.waitForBroadcast();
+        }
+    }
+
+    private class BlockingBroadcastReceiver extends BroadcastReceiver {
+        private BlockingQueue<Integer> mQueue = new ArrayBlockingQueue<Integer> (1);
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            assertTrue(mQueue.add(0));
+        }
+
+        public void waitForBroadcast() throws Exception {
+            Integer result = mQueue.poll(BROADCAST_TIMEOUT_SEC, TimeUnit.SECONDS);
+            assertNotNull(result);
+        }
+    }
+
+    private static int getUserId() throws Exception {
+        UserHandle userHandle = Process.myUserHandle();
+        Class<?>[] noParam = {};
+        Class<?> userHandleClass = userHandle.getClass();
+        Method methodGetIdentifier = userHandleClass.getDeclaredMethod("getIdentifier", noParam);
+        return (Integer) methodGetIdentifier.invoke(userHandle, null);
+    }
+
+    private Bitmap getUserIcon() throws Exception {
+        Class<?>[] paramInt = new Class[1];
+        paramInt[0] = Integer.TYPE;
+        Class<?> umClass = mUserManager.getClass();
+        Method methodGetUserIcon = umClass.getDeclaredMethod("getUserIcon", paramInt);
+        return (Bitmap) methodGetUserIcon.invoke(mUserManager, getUserId());
+    }
+
+    public void testDisallowSetWallpaper_allowed() throws Exception {
+        final WallpaperManager wallpaperManager = WallpaperManager.getInstance(mContext);
+        final Bitmap originalWallpaper = BitmapUtils.getWallpaperBitmap(mContext);
+
+        try (
+            // Set restriction and subscribe for the broadcast.
+            final RestrictionApplicator restr =
+                    new RestrictionApplicator(UserManager.DISALLOW_SET_WALLPAPER);
+            final BroadcastReceiverRegistrator bcast =
+                    new BroadcastReceiverRegistrator(Intent.ACTION_WALLPAPER_CHANGED);
+        ) {
+            assertTrue(mUserManager.hasUserRestriction(UserManager.DISALLOW_SET_WALLPAPER));
+
+            // Checking setBitmap() method.
+            Bitmap referenceWallpaper = BitmapUtils.generateRandomBitmap(97, 73);
+            wallpaperManager.setBitmap(referenceWallpaper);
+            bcast.waitForBroadcast();
+            Bitmap newWallpaper = BitmapUtils.getWallpaperBitmap(mContext);
+            // Violation of encapsulation if refs are equal.
+            assertNotSame(newWallpaper, referenceWallpaper);
+            assertTrue(BitmapUtils.compareBitmaps(newWallpaper, referenceWallpaper));
+
+            // Checking setStream() method.
+            referenceWallpaper = BitmapUtils.generateRandomBitmap(83, 69);
+            wallpaperManager.setStream(BitmapUtils.bitmapToInputStream(referenceWallpaper));
+            bcast.waitForBroadcast();
+            newWallpaper = BitmapUtils.getWallpaperBitmap(mContext);
+            assertTrue(BitmapUtils.compareBitmaps(newWallpaper, referenceWallpaper));
+
+            // Checking setResource() method.
+            final InputStream is = mContext.getResources().openRawResource(R.raw.wallpaper);
+            referenceWallpaper = BitmapFactory.decodeStream(is);
+            wallpaperManager.setResource(R.raw.wallpaper);
+            bcast.waitForBroadcast();
+            newWallpaper = BitmapUtils.getWallpaperBitmap(mContext);
+            assertTrue(BitmapUtils.compareBitmaps(newWallpaper, referenceWallpaper));
+        } finally {
+            wallpaperManager.setBitmap(originalWallpaper);
+        }
+        assertFalse(mUserManager.hasUserRestriction(UserManager.DISALLOW_SET_WALLPAPER));
+    }
+
+    public void testDisallowSetUserIcon_allowed() throws Exception {
+        final Bitmap originalIcon = getUserIcon();
+
+        try (
+            // Apply restriction.
+            final RestrictionApplicator restr =
+                    new RestrictionApplicator(UserManager.DISALLOW_SET_USER_ICON);
+        ) {
+            assertTrue(mUserManager.hasUserRestriction(UserManager.DISALLOW_SET_USER_ICON));
+            final Bitmap randomBmp = BitmapUtils.generateRandomBitmap(17, 31);
+            mDevicePolicyManager.setUserIcon(ADMIN_RECEIVER_COMPONENT, randomBmp);
+            final Bitmap currentIcon = getUserIcon();
+            assertNotSame(randomBmp, currentIcon);
+            assertTrue(BitmapUtils.compareBitmaps(randomBmp, currentIcon));
+        } finally {
+            if (originalIcon == null) {
+                // There is no way to restore absence of an icon. Thus set white
+                // icon for esthetic reasons.
+                mDevicePolicyManager.setUserIcon(ADMIN_RECEIVER_COMPONENT,
+                        BitmapUtils.generateWhiteBitmap(20, 20));
+            } else {
+                mDevicePolicyManager.setUserIcon(ADMIN_RECEIVER_COMPONENT, originalIcon);
+            }
+        }
+        assertFalse(mUserManager.hasUserRestriction(UserManager.DISALLOW_SET_USER_ICON));
+    }
+}
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 3eb8c35..e733189 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
@@ -22,21 +22,10 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.security.KeyChain;
+import android.os.Build;
 import android.security.KeyChainException;
-import android.test.AndroidTestCase;
-import android.util.Base64;
-import android.util.Base64InputStream;
+import android.test.MoreAsserts;
 
-import java.io.ByteArrayInputStream;
-import java.security.KeyFactory;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateException;
-import java.security.cert.CertificateFactory;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.PKCS8EncodedKeySpec;
 import java.util.concurrent.Semaphore;
 import java.util.concurrent.TimeUnit;
 
@@ -48,6 +37,8 @@
 public class DelegatedCertInstallerTest extends BaseDeviceAdminTest {
 
     private static final String CERT_INSTALLER_PACKAGE = "com.android.cts.certinstaller";
+    private static final String NOT_EXIST_CERT_INSTALLER_PACKAGE
+            = "com.android.cts.certinstaller.not_exist";
 
     private static final String ACTION_INSTALL_CERT = "com.android.cts.certinstaller.install_cert";
     private static final String ACTION_REMOVE_CERT = "com.android.cts.certinstaller.remove_cert";
@@ -227,6 +218,27 @@
     }
 
     /**
+     * If DPC is targeting N+, @{link IllegalArgumentException } should be thrown if the package
+     * is missing.
+     */
+    public void testSetNotExistCertInstallerPackage() throws Exception {
+        boolean shouldThrowException = getTargetApiLevel() >= Build.VERSION_CODES.N;
+        try {
+            mDpm.setCertInstallerPackage(
+                    ADMIN_RECEIVER_COMPONENT, NOT_EXIST_CERT_INSTALLER_PACKAGE);
+            if (shouldThrowException) {
+                fail("Did not throw IllegalArgumentException");
+            }
+        } catch (IllegalArgumentException ex) {
+            if (!shouldThrowException) {
+                fail("Should not throw exception");
+            }
+            MoreAsserts.assertContainsRegex("is not installed on the current user",
+                        ex.getMessage());
+        }
+    }
+
+    /**
      * installKeyPair() requires the system to have a lockscreen password, which should have been
      * set by the host side test.
      */
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/DpcAllowedAccountManagementTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/DpcAllowedAccountManagementTest.java
new file mode 100644
index 0000000..291159f
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/DpcAllowedAccountManagementTest.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.deviceandprofileowner;
+
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.accounts.AccountManagerFuture;
+import android.accounts.AuthenticatorException;
+import android.accounts.OperationCanceledException;
+import android.app.admin.DevicePolicyManager;
+import android.content.Context;
+import android.os.Bundle;
+import android.os.UserManager;
+
+import java.io.IOException;
+
+/**
+ * These tests verify that the device / profile owner can use account management APIs to add
+ * accounts even when policies are set. The policies tested are
+ * {@link DevicePolicyManager#setAccountManagementDisabled} and
+ * {@link UserManager#DISALLOW_MODIFY_ACCOUNTS}.
+ *
+ * This test depends on {@link com.android.cts.devicepolicy.accountmanagement.MockAccountService},
+ * which provides authenticator for a mock account type.
+ *
+ * Note that we cannot test account removal, because only the authenticator can remove an account
+ * and the Dpc is not the authenticator for the mock account type.
+ */
+public class DpcAllowedAccountManagementTest extends BaseDeviceAdminTest {
+
+    // Account type for MockAccountAuthenticator
+    private final static String ACCOUNT_TYPE_1
+            = "com.android.cts.devicepolicy.accountmanagement.account.type";
+    private final static String ACCOUNT_TYPE_2 = "com.dummy.account";
+    private final static Account ACCOUNT_0 = new Account("user0", ACCOUNT_TYPE_1);
+    private final static Account ACCOUNT_1 = new Account("user1", ACCOUNT_TYPE_1);
+
+    private AccountManager mAccountManager;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mAccountManager = (AccountManager) mContext.getSystemService(Context.ACCOUNT_SERVICE);
+        clearAllAccountManagementDisabled();
+        mDevicePolicyManager.clearUserRestriction(ADMIN_RECEIVER_COMPONENT,
+                UserManager.DISALLOW_MODIFY_ACCOUNTS);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        clearAllAccountManagementDisabled();
+        mDevicePolicyManager.clearUserRestriction(ADMIN_RECEIVER_COMPONENT,
+                UserManager.DISALLOW_MODIFY_ACCOUNTS);
+        super.tearDown();
+    }
+
+    public void testAccountManagementDisabled_setterAndGetter() {
+        // Some local tests: adding and removing disabled accounts and make sure
+        // DevicePolicyManager keeps track of the disabled set correctly
+        assertEquals(0, mDevicePolicyManager.getAccountTypesWithManagementDisabled().length);
+
+        mDevicePolicyManager.setAccountManagementDisabled(ADMIN_RECEIVER_COMPONENT, ACCOUNT_TYPE_1,
+                true);
+        // Test if disabling ACCOUNT_TYPE_2 affects ACCOUNT_TYPE_1
+        mDevicePolicyManager.setAccountManagementDisabled(ADMIN_RECEIVER_COMPONENT, ACCOUNT_TYPE_2,
+                false);
+        assertEquals(1, mDevicePolicyManager.getAccountTypesWithManagementDisabled().length);
+        assertEquals(ACCOUNT_TYPE_1,
+                mDevicePolicyManager.getAccountTypesWithManagementDisabled()[0]);
+
+        mDevicePolicyManager.setAccountManagementDisabled(ADMIN_RECEIVER_COMPONENT, ACCOUNT_TYPE_1,
+                false);
+        assertEquals(0, mDevicePolicyManager.getAccountTypesWithManagementDisabled().length);
+    }
+
+    public void testAccountManagementDisabled_profileAndDeviceOwnerCanAddAccount()
+            throws AuthenticatorException, IOException, OperationCanceledException {
+        mDevicePolicyManager.setAccountManagementDisabled(ADMIN_RECEIVER_COMPONENT, ACCOUNT_TYPE_1,
+                true);
+
+        assertEquals(0, mAccountManager.getAccountsByType(ACCOUNT_TYPE_1).length);
+        // Management is disabled, but the device / profile owner is still allowed to use the APIs
+        Bundle result = mAccountManager.addAccount(ACCOUNT_TYPE_1,
+                null, null, null, null, null, null).getResult();
+
+        // Normally the expected result of addAccount() is AccountManager returning
+        // an intent to start the authenticator activity for adding new accounts.
+        // But MockAccountAuthenticator returns a new account straightway.
+        assertEquals(ACCOUNT_TYPE_1, result.getString(AccountManager.KEY_ACCOUNT_TYPE));
+    }
+
+    public void testUserRestriction_profileAndDeviceOwnerCanAddAccount()
+            throws AuthenticatorException, IOException, OperationCanceledException {
+        mDevicePolicyManager.addUserRestriction(ADMIN_RECEIVER_COMPONENT,
+                UserManager.DISALLOW_MODIFY_ACCOUNTS);
+
+        assertEquals(0, mAccountManager.getAccountsByType(ACCOUNT_TYPE_1).length);
+        // Management is disabled, but the device / profile owner is still allowed to use the APIs
+        Bundle result = mAccountManager.addAccount(ACCOUNT_TYPE_1,
+                null, null, null, null, null, null).getResult();
+
+        // Normally the expected result of addAccount() is AccountManager returning
+        // an intent to start the authenticator activity for adding new accounts.
+        // But MockAccountAuthenticator returns a new account straightway.
+        assertEquals(ACCOUNT_TYPE_1, result.getString(AccountManager.KEY_ACCOUNT_TYPE));
+    }
+
+    private void clearAllAccountManagementDisabled() {
+        for (String accountType : mDevicePolicyManager.getAccountTypesWithManagementDisabled()) {
+            mDevicePolicyManager.setAccountManagementDisabled(ADMIN_RECEIVER_COMPONENT, accountType,
+                    false);
+        }
+        assertEquals(0, mDevicePolicyManager.getAccountTypesWithManagementDisabled().length);
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/MockAccountAuthenticator.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/MockAccountAuthenticator.java
deleted file mode 100644
index e8e5b45..0000000
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/MockAccountAuthenticator.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.deviceandprofileowner;
-
-import android.accounts.AbstractAccountAuthenticator;
-import android.accounts.Account;
-import android.accounts.AccountAuthenticatorResponse;
-import android.accounts.AccountManager;
-import android.accounts.NetworkErrorException;
-import android.content.Context;
-import android.os.Bundle;
-
-/* package */ class MockAccountAuthenticator extends AbstractAccountAuthenticator {
-    private static MockAccountAuthenticator sMockAuthenticator = null;
-    private static final String ACCOUNT_NAME = "com.android.cts.deviceandprofileowner.account.name";
-    static final String ACCOUNT_TYPE = "com.android.cts.deviceandprofileowner.account.type";
-    private static final String AUTH_TOKEN = "mockAuthToken";
-    private static final String AUTH_TOKEN_LABEL = "mockAuthTokenLabel";
-
-    private MockAccountAuthenticator(Context context) {
-        super(context);
-    }
-
-    private Bundle createResultBundle() {
-        Bundle result = new Bundle();
-        result.putString(AccountManager.KEY_ACCOUNT_NAME, ACCOUNT_NAME);
-        result.putString(AccountManager.KEY_ACCOUNT_TYPE, ACCOUNT_TYPE);
-        result.putString(AccountManager.KEY_AUTHTOKEN, AUTH_TOKEN);
-
-        return result;
-    }
-
-    @Override
-    public Bundle addAccount(AccountAuthenticatorResponse response, String accountType,
-            String authTokenType, String[] requiredFeatures, Bundle options)
-            throws NetworkErrorException {
-        return createResultBundle();
-    }
-
-    @Override
-    public Bundle editProperties(AccountAuthenticatorResponse response, String accountType) {
-        return createResultBundle();
-    }
-
-    @Override
-    public Bundle updateCredentials(AccountAuthenticatorResponse response, Account account,
-            String authTokenType, Bundle options) throws NetworkErrorException {
-        return createResultBundle();
-    }
-
-    @Override
-    public Bundle confirmCredentials(AccountAuthenticatorResponse response, Account account,
-            Bundle options) throws NetworkErrorException {
-
-        Bundle result = new Bundle();
-        result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, true);
-        return result;
-    }
-
-    @Override
-    public Bundle getAuthToken(AccountAuthenticatorResponse response, Account account,
-            String authTokenType, Bundle options) throws NetworkErrorException {
-        return createResultBundle();
-    }
-
-    @Override
-    public String getAuthTokenLabel(String authTokenType) {
-        return AUTH_TOKEN_LABEL;
-    }
-
-    @Override
-    public Bundle hasFeatures(AccountAuthenticatorResponse response, Account account,
-            String[] features) throws NetworkErrorException {
-
-        Bundle result = new Bundle();
-        result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, true);
-        return result;
-    }
-
-    public static synchronized MockAccountAuthenticator getMockAuthenticator(Context context) {
-        if (null == sMockAuthenticator) {
-            sMockAuthenticator = new MockAccountAuthenticator(context);
-        }
-        return sMockAuthenticator;
-    }
-}
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/MockAccountService.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/MockAccountService.java
deleted file mode 100644
index dfedccb..0000000
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/MockAccountService.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.deviceandprofileowner;
-
-import android.app.Service;
-import android.content.Intent;
-import android.os.IBinder;
-
-/**
- * a basic Mock Service for wrapping the MockAccountAuthenticator
- */
-public class MockAccountService extends Service {
-
-    @Override
-    public IBinder onBind(Intent intent) {
-        return MockAccountAuthenticator.getMockAuthenticator(this).getIBinder();
-    }
-}
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/PrimaryUserAdminHelper.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/PrimaryUserAdminHelper.java
deleted file mode 100644
index 7fc0173..0000000
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/PrimaryUserAdminHelper.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.cts.deviceandprofileowner;
-
-import android.app.admin.DevicePolicyManager;
-import android.content.ComponentName;
-import android.content.Context;
-import android.test.AndroidTestCase;
-
-/**
- * This test executes helper tasks as active device admin in the primary user. Current tasks are
- * setting and clearing lockscreen password used by the host side delegated cert installer test.
- */
-public class PrimaryUserAdminHelper extends AndroidTestCase {
-
-    private DevicePolicyManager mDpm;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mDpm = (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
-    }
-
-    /**
-     * Device admin can only be deactivated by itself and this test should be executed before the
-     * device admin package can be uninstalled.
-     */
-    public void testClearDeviceAdmin() throws Exception {
-        ComponentName cn = PrimaryUserDeviceAdmin.ADMIN_RECEIVER_COMPONENT;
-        if (mDpm.isAdminActive(cn)) {
-            mDpm.removeActiveAdmin(cn);
-            // Wait until device admin is not active (with 2 minutes timeout).
-            for (int i = 0; i < 2 * 60 && mDpm.isAdminActive(cn); i++) {
-                Thread.sleep(1000);  // 1 second.
-            }
-        }
-        assertFalse(mDpm.isAdminActive(cn));
-    }
-
-    /**
-     * Set lockscreen password.
-     */
-    public void testSetPassword() {
-        // Enable credential storage by setting a nonempty password.
-        assertTrue(mDpm.resetPassword("test", 0));
-    }
-
-    /**
-     * Clear lockscreen password.
-     */
-    public void testClearPassword() {
-        mDpm.setPasswordQuality(PrimaryUserDeviceAdmin.ADMIN_RECEIVER_COMPONENT,
-                DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED);
-        mDpm.setPasswordMinimumLength(
-                PrimaryUserDeviceAdmin.ADMIN_RECEIVER_COMPONENT, 0);
-        assertTrue(mDpm.resetPassword("", 0));
-    }
-}
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/PrimaryUserDeviceAdmin.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/PrimaryUserDeviceAdmin.java
deleted file mode 100644
index f3c8ff6..0000000
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/PrimaryUserDeviceAdmin.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.cts.deviceandprofileowner;
-
-import android.app.admin.DeviceAdminReceiver;
-import android.content.ComponentName;
-
-/**
- * A device admin class running in the primary user. Currently used by delegated cert installer
- * test to set a lockscreen password which is prerequisite of installKeyPair().
- */
-public class PrimaryUserDeviceAdmin extends DeviceAdminReceiver {
-    public static final ComponentName ADMIN_RECEIVER_COMPONENT = new ComponentName(
-            PrimaryUserDeviceAdmin.class.getPackage().getName(),
-            PrimaryUserDeviceAdmin.class.getName());
-}
\ No newline at end of file
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ResetPasswordHelper.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ResetPasswordHelper.java
new file mode 100644
index 0000000..1303172
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ResetPasswordHelper.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.deviceandprofileowner;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.Context;
+import android.test.AndroidTestCase;
+
+/**
+ * This test is used to set and clear the lockscreen password. This is required to use the keystore
+ * by the host side delegated cert installer test.
+ */
+public class ResetPasswordHelper extends AndroidTestCase {
+
+    private DevicePolicyManager mDpm;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mDpm = (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
+    }
+
+    /**
+     * Set lockscreen password.
+     */
+    public void testSetPassword() {
+        // Enable credential storage by setting a nonempty password.
+        assertTrue(mDpm.resetPassword("test", 0));
+    }
+
+    /**
+     * Clear lockscreen password.
+     */
+    public void testClearPassword() {
+        mDpm.setPasswordQuality(BaseDeviceAdminTest.ADMIN_RECEIVER_COMPONENT,
+                DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED);
+        mDpm.setPasswordMinimumLength(
+                BaseDeviceAdminTest.ADMIN_RECEIVER_COMPONENT, 0);
+        assertTrue(mDpm.resetPassword("", 0));
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ResetPasswordTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ResetPasswordTest.java
new file mode 100644
index 0000000..635ff6d
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ResetPasswordTest.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.deviceandprofileowner;
+
+public class ResetPasswordTest extends BaseDeviceAdminTest {
+    public void testResetPassword() {
+        try {
+            // DO/PO can set a password.
+            mDevicePolicyManager.resetPassword("12345abcdef!!##1", 0);
+
+            // DO/PO can change the password, even if one is set already.
+            mDevicePolicyManager.resetPassword("12345abcdef!!##2", 0);
+        } finally {
+            // DO/PO can clear the password.
+            mDevicePolicyManager.resetPassword("", 0);
+        }
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/SetPolicyActivity.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/SetPolicyActivity.java
new file mode 100644
index 0000000..aaa017b
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/SetPolicyActivity.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.deviceandprofileowner;
+
+import android.app.Activity;
+import android.app.admin.DevicePolicyManager;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.os.Bundle;
+import android.os.Process;
+import android.util.Log;
+
+/**
+ * Simple activity that sets or unsets a policy depending on the value of the extras.
+ */
+public class SetPolicyActivity extends Activity {
+
+    private static final String TAG = SetPolicyActivity.class.getName();
+
+    private static final String EXTRA_RESTRICTION_KEY = "extra-restriction-key";
+    private static final String EXTRA_COMMAND = "extra-command";
+    private static final String EXTRA_ACCOUNT_TYPE = "extra-account-type";
+    private static final String EXTRA_PACKAGE_NAME = "extra-package-name";
+
+    private static final String COMMAND_ADD_USER_RESTRICTION = "add-restriction";
+    private static final String COMMAND_CLEAR_USER_RESTRICTION = "clear-restriction";
+    private static final String COMMAND_BLOCK_ACCOUNT_TYPE = "block-accounttype";
+    private static final String COMMAND_UNBLOCK_ACCOUNT_TYPE = "unblock-accounttype";
+    private static final String COMMAND_SET_APP_RESTRICTIONS_MANAGER =
+            "set-app-restrictions-manager";
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        handleIntent(getIntent());
+    }
+
+    // Overriding this method in case another intent is sent to this activity before finish()
+    @Override
+    public void onNewIntent(Intent intent) {
+        super.onNewIntent(intent);
+        handleIntent(intent);
+    }
+
+    @Override
+    public void onPause() {
+        super.onPause();
+        // Calling finish() here because doing it in onCreate(), onStart() or onResume() makes
+        // "adb shell am start" timeout if using the -W option.
+        finish();
+    }
+
+    private void handleIntent(Intent intent) {
+        DevicePolicyManager dpm = (DevicePolicyManager)
+                getSystemService(Context.DEVICE_POLICY_SERVICE);
+        String command = intent.getStringExtra(EXTRA_COMMAND);
+        Log.i(TAG, "Command: " + command);
+
+        if (COMMAND_ADD_USER_RESTRICTION.equals(command)) {
+            String restrictionKey = intent.getStringExtra(EXTRA_RESTRICTION_KEY);
+            dpm.addUserRestriction(BaseDeviceAdminTest.ADMIN_RECEIVER_COMPONENT, restrictionKey);
+            Log.i(TAG, "Added user restriction " + restrictionKey
+                    + " for user " + Process.myUserHandle());
+        } else if (COMMAND_CLEAR_USER_RESTRICTION.equals(command)) {
+            String restrictionKey = intent.getStringExtra(EXTRA_RESTRICTION_KEY);
+            dpm.clearUserRestriction(
+                    BaseDeviceAdminTest.ADMIN_RECEIVER_COMPONENT, restrictionKey);
+            Log.i(TAG, "Cleared user restriction " + restrictionKey
+                    + " for user " + Process.myUserHandle());
+        } else if (COMMAND_BLOCK_ACCOUNT_TYPE.equals(command)) {
+            String accountType = intent.getStringExtra(EXTRA_ACCOUNT_TYPE);
+            dpm.setAccountManagementDisabled(BaseDeviceAdminTest.ADMIN_RECEIVER_COMPONENT,
+                    accountType, true);
+            Log.i(TAG, "Blocking account management for account type: " + accountType
+                    + " for user " + Process.myUserHandle());
+        } else if (COMMAND_UNBLOCK_ACCOUNT_TYPE.equals(command)) {
+            String accountType = intent.getStringExtra(EXTRA_ACCOUNT_TYPE);
+            dpm.setAccountManagementDisabled(BaseDeviceAdminTest.ADMIN_RECEIVER_COMPONENT,
+                    accountType, false);
+            Log.i(TAG, "Unblocking account management for account type: " + accountType
+                    + " for user " + Process.myUserHandle());
+        } else if (COMMAND_SET_APP_RESTRICTIONS_MANAGER.equals(command)) {
+            String packageName = intent.getStringExtra(EXTRA_PACKAGE_NAME);
+            try {
+                dpm.setApplicationRestrictionsManagingPackage(
+                        BaseDeviceAdminTest.ADMIN_RECEIVER_COMPONENT, packageName);
+            } catch (NameNotFoundException e) {
+                throw new IllegalArgumentException(e);
+            }
+            Log.i(TAG, "Setting the application restrictions managing package to " + packageName);
+        } else {
+            Log.e(TAG, "Invalid command: " + command);
+        }
+    }
+}
+
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/SupportMessageTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/SupportMessageTest.java
new file mode 100644
index 0000000..03ca1a3
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/SupportMessageTest.java
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.deviceandprofileowner;
+
+import java.lang.Character;
+
+public class SupportMessageTest extends BaseDeviceAdminTest {
+
+    /**
+     * Longest allowed length of a short support message before the system may truncate it.
+     *
+     * Taken from documentation for
+     * {@link DevicePolicyManager#setShortSupportMessage(android.content.ComponentName, String)}.
+     */
+    private static final int MAX_SHORT_MSG_LENGTH = 200;
+
+    private static final int REASONABLE_LONG_MSG_LENGTH = 4000;
+
+    // Declare a different string of the same type for both long and short messages, so we can be
+    // sure they aren't mixed up by any API calls.
+    private static class ShortMessage {
+        static final CharSequence EMPTY = "";
+        static final CharSequence SIMPLE = "short-message-short";
+        static final CharSequence MAX_LENGTH =
+                new String(new char[MAX_SHORT_MSG_LENGTH]).replace('\0', 'X');
+        static final CharSequence TOO_LONG =
+                new String(new char[MAX_SHORT_MSG_LENGTH + 10]).replace('\0', 'A');
+        static final CharSequence UNICODE = new String(Character.toChars(0x1F634)) + " zzz";
+        static final CharSequence CONTAINS_NULL = "short\0null";
+    }
+    private static class LongMessage {
+        static final CharSequence EMPTY = "";
+        static final CharSequence SIMPLE = "long-message-long";
+        static final CharSequence LONG =
+                new String(new char[REASONABLE_LONG_MSG_LENGTH]).replace('\0', 'B');
+        static final CharSequence UNICODE = new String(Character.toChars(0x1F609)) + " ;)";
+        static final CharSequence CONTAINS_NULL = "long\0null";
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        clearSupportMessages();
+        super.tearDown();
+    }
+
+    public void testShortSupportMessageSetGetAndClear() {
+        setShortMessage(ShortMessage.SIMPLE);
+        setShortMessage(null);
+    }
+
+    public void testLongSupportMessageSetGetAndClear() {
+        setLongMessage(LongMessage.SIMPLE);
+        setLongMessage(null);
+    }
+
+    public void testLongAndShortMessagesDoNotClobber() {
+        setShortMessage(ShortMessage.SIMPLE);
+        setLongMessage(LongMessage.SIMPLE);
+
+        assertEquals(ShortMessage.SIMPLE, getShortMessage());
+        assertEquals(LongMessage.SIMPLE, getLongMessage());
+    }
+
+    public void testMaximumLengthPrefixIsSaved() {
+        // Save and restore a string of exactly the maximum length
+        setShortMessage(ShortMessage.MAX_LENGTH);
+
+        /*
+         * Save and restore a "short message" string that is too large -- this may only store the
+         * first N characters, not the whole thing, so we need to use {@link String#startsWith}
+         * here.
+         */
+        mDevicePolicyManager.setShortSupportMessage(ADMIN_RECEIVER_COMPONENT,
+                ShortMessage.TOO_LONG);
+        assertStartsWith(ShortMessage.TOO_LONG.subSequence(0, MAX_SHORT_MSG_LENGTH),
+                getShortMessage());
+
+        // Long support messages should not be affected; verify that.
+        mDevicePolicyManager.setLongSupportMessage(ADMIN_RECEIVER_COMPONENT, LongMessage.LONG);
+        assertEquals(LongMessage.LONG, getLongMessage());
+    }
+
+    public void testEmptySupportMessage() {
+        setShortMessage(ShortMessage.EMPTY);
+        setLongMessage(LongMessage.EMPTY);
+    }
+
+    public void testUnicodeCharactersInMessage() {
+        setShortMessage(ShortMessage.UNICODE);
+        setLongMessage(LongMessage.UNICODE);
+    }
+
+    public void testNullCharacterInMessage() {
+        setShortMessage(ShortMessage.CONTAINS_NULL);
+        setLongMessage(LongMessage.CONTAINS_NULL);
+    }
+
+    public void testSetOrGetSupportMessageWithNullAdminFails() {
+        // Short support message
+        try {
+            mDevicePolicyManager.setShortSupportMessage(null, ShortMessage.SIMPLE);
+            fail("Exception should have been thrown for null admin ComponentName");
+        } catch (NullPointerException expected) {
+        }
+        try {
+            CharSequence message = mDevicePolicyManager.getShortSupportMessage(null);
+            fail("Exception should have been thrown for null admin ComponentName");
+        } catch (NullPointerException expected) {
+        }
+
+        // Long support message
+        try {
+            mDevicePolicyManager.setLongSupportMessage(null, LongMessage.SIMPLE);
+            fail("Exception should have been thrown for null admin ComponentName");
+        } catch (NullPointerException expected) {
+        }
+
+        try {
+            CharSequence message = mDevicePolicyManager.getLongSupportMessage(null);
+            fail("Exception should have been thrown for null admin ComponentName");
+        } catch (NullPointerException expected) {
+        }
+    }
+
+    /**
+     * Delete all admin-set support messsages.
+     */
+    private void clearSupportMessages() {
+        setShortMessage(null);
+        setLongMessage(null);
+    }
+
+    /**
+     * Update the short support message.
+     *
+     * @throws AssertionError in the case that the message could not be set.
+     */
+    private void setShortMessage(CharSequence message) {
+        mDevicePolicyManager.setShortSupportMessage(ADMIN_RECEIVER_COMPONENT, message);
+        assertEquals(message, getShortMessage());
+    }
+
+    /**
+     * Update the long support message.
+     *
+     * @throws AssertionError in the case that the message could not be set.
+     */
+    private void setLongMessage(CharSequence message) {
+        mDevicePolicyManager.setLongSupportMessage(ADMIN_RECEIVER_COMPONENT, message);
+        assertEquals(message, getLongMessage());
+    }
+
+    private CharSequence getShortMessage() {
+        return mDevicePolicyManager.getShortSupportMessage(ADMIN_RECEIVER_COMPONENT);
+    }
+
+    private CharSequence getLongMessage() {
+        return mDevicePolicyManager.getLongSupportMessage(ADMIN_RECEIVER_COMPONENT);
+    }
+
+    private static void assertStartsWith(CharSequence expectPrefix, CharSequence actual) {
+        assertNotNull(expectPrefix);
+        assertNotNull(actual);
+        if (!actual.toString().startsWith(expectPrefix.toString())) {
+            fail("Expected prefix: '" + expectPrefix + "'\n" +
+                 "            got: '" + actual + "'");
+        }
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/SuspendPackageTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/SuspendPackageTest.java
new file mode 100644
index 0000000..dca2085
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/SuspendPackageTest.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.deviceandprofileowner;
+
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.ResolveInfo;
+
+import java.util.Arrays;
+import java.util.HashSet;
+
+public class SuspendPackageTest extends BaseDeviceAdminTest {
+    private static final String INTENT_RECEIVER_PKG = "com.android.cts.intent.receiver";
+
+    public void testSetPackagesSuspended() throws NameNotFoundException {
+        String[] notHandledPackages =
+                mDevicePolicyManager.setPackagesSuspended(ADMIN_RECEIVER_COMPONENT, new String[]
+                        {INTENT_RECEIVER_PKG}, true);
+        // all packages should be handled.
+        assertEquals(0, notHandledPackages.length);
+        // test isPackageSuspended
+        boolean isSuspended =
+                mDevicePolicyManager.isPackageSuspended(
+                        ADMIN_RECEIVER_COMPONENT, INTENT_RECEIVER_PKG);
+        assertTrue(isSuspended);
+    }
+
+    public void testSetPackagesNotSuspended() throws NameNotFoundException {
+        String[] notHandledPackages = mDevicePolicyManager.setPackagesSuspended(
+                ADMIN_RECEIVER_COMPONENT,
+                new String[] {INTENT_RECEIVER_PKG},
+                false);
+        // all packages should be handled.
+        assertEquals(0, notHandledPackages.length);
+        // test isPackageSuspended
+        boolean isSuspended =
+                mDevicePolicyManager.isPackageSuspended(
+                        ADMIN_RECEIVER_COMPONENT, INTENT_RECEIVER_PKG);
+        assertFalse(isSuspended);
+    }
+
+    /**
+     * Verify that we cannot suspend launcher and dpc app.
+     */
+    public void testSuspendNotSuspendablePackages() {
+        String launcherPackage = getLauncherPackage();
+        String dpcPackage = ADMIN_RECEIVER_COMPONENT.getPackageName();
+        String[] unsuspendablePackages = new String[] {launcherPackage, dpcPackage};
+        String[] notHandledPackages = mDevicePolicyManager.setPackagesSuspended(
+                ADMIN_RECEIVER_COMPONENT,
+                unsuspendablePackages,
+                true);
+        // no package should be handled.
+        assertArrayEqualIgnoreOrder(unsuspendablePackages, notHandledPackages);
+    }
+
+    /**
+     * @return the package name of launcher.
+     */
+    private String getLauncherPackage() {
+        Intent intent = new Intent(Intent.ACTION_MAIN);
+        intent.addCategory(Intent.CATEGORY_HOME);
+        ResolveInfo resolveInfo = mContext.getPackageManager().resolveActivity(intent,
+                PackageManager.MATCH_DEFAULT_ONLY);
+        return resolveInfo.activityInfo.packageName;
+    }
+
+    private static <T> void assertArrayEqualIgnoreOrder(T[] a, T[] b) {
+        assertEquals(a.length, b.length);
+        assertTrue(new HashSet(Arrays.asList(a)).containsAll(new HashSet(Arrays.asList(b))));
+    }
+
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/TrustAgentInfoTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/TrustAgentInfoTest.java
new file mode 100644
index 0000000..241a830
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/TrustAgentInfoTest.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.deviceandprofileowner;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.os.PersistableBundle;
+
+import java.util.List;
+
+
+public class TrustAgentInfoTest extends BaseDeviceAdminTest {
+    private static final String BUNDLE_KEY = "testing";
+    private static final String BUNDLE_VALUE = "value";
+    private static final PersistableBundle CONFIG = new PersistableBundle();
+    private static final ComponentName TRUST_AGENT_COMPONENT =
+            new ComponentName("com.trustagent", "com.trustagent.xxx");
+    private static final ComponentName NOT_CONFIGURED_TRUST_AGENT_COMPONENT =
+            new ComponentName("com.trustagent.not_configured", "com.trustagent.xxx");
+
+    static {
+        CONFIG.putString(BUNDLE_KEY, BUNDLE_VALUE);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        mDevicePolicyManager.setTrustAgentConfiguration(ADMIN_RECEIVER_COMPONENT,
+                TRUST_AGENT_COMPONENT, null);
+        assertNull(mDevicePolicyManager.getTrustAgentConfiguration(
+                ADMIN_RECEIVER_COMPONENT, TRUST_AGENT_COMPONENT));
+        mDevicePolicyManager.setKeyguardDisabledFeatures(ADMIN_RECEIVER_COMPONENT,
+                DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_NONE);
+        super.tearDown();
+    }
+
+    public void testSetAndGetTrustAgentConfiguration() {
+        // Set the config
+        mDevicePolicyManager.setTrustAgentConfiguration(ADMIN_RECEIVER_COMPONENT,
+                TRUST_AGENT_COMPONENT, CONFIG);
+        // Should able to get the config just set.
+        List<PersistableBundle> configs =
+                mDevicePolicyManager.getTrustAgentConfiguration(
+                        ADMIN_RECEIVER_COMPONENT, TRUST_AGENT_COMPONENT);
+        assertPersistableBundleList(configs);
+        // Try to get the config of an trust agent that is not configured.
+        configs = mDevicePolicyManager
+                .getTrustAgentConfiguration(null, NOT_CONFIGURED_TRUST_AGENT_COMPONENT);
+        assertNull(configs);
+        // Try to get the aggregated list when trust agents is not disabled.
+        configs = mDevicePolicyManager
+                .getTrustAgentConfiguration(null, TRUST_AGENT_COMPONENT);
+        assertNull(configs);
+        // Try to get the aggregated list when trust agents is disabled.
+        mDevicePolicyManager.setKeyguardDisabledFeatures(ADMIN_RECEIVER_COMPONENT,
+                DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS);
+        // Try to get the aggregated list of a trust agent that is not configured.
+        configs = mDevicePolicyManager
+                .getTrustAgentConfiguration(null, NOT_CONFIGURED_TRUST_AGENT_COMPONENT);
+        assertNull(configs);
+        configs = mDevicePolicyManager
+                .getTrustAgentConfiguration(null, TRUST_AGENT_COMPONENT);
+        assertPersistableBundleList(configs);
+    }
+
+    private static void assertPersistableBundleList(List<PersistableBundle> actual) {
+        assertNotNull(actual);
+        assertEquals(1, actual.size());
+        PersistableBundle bundle = actual.get(0);
+        assertEquals(BUNDLE_VALUE, bundle.getString(BUNDLE_KEY));
+    }
+
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/UserRestrictionActivity.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/UserRestrictionActivity.java
deleted file mode 100644
index fed1a79..0000000
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/UserRestrictionActivity.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.cts.deviceandprofileowner;
-
-import android.app.Activity;
-import android.app.admin.DevicePolicyManager;
-import android.content.Context;
-import android.content.Intent;
-import android.os.Bundle;
-import android.os.Process;
-import android.util.Log;
-
-/**
- * Simple activity that adds or clears a user restriction depending on the value of the extras.
- */
-public class UserRestrictionActivity extends Activity {
-
-    private static final String TAG = UserRestrictionActivity.class.getName();
-
-    private static final String EXTRA_RESTRICTION_KEY = "extra-restriction-key";
-    private static final String EXTRA_COMMAND = "extra-command";
-
-    private static final String ADD_COMMAND = "add-restriction";
-    private static final String CLEAR_COMMAND = "clear-restriction";
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        handleIntent(getIntent());
-    }
-
-    // Overriding this method in case another intent is sent to this activity before finish()
-    @Override
-    public void onNewIntent(Intent intent) {
-        super.onNewIntent(intent);
-        handleIntent(intent);
-    }
-
-    @Override
-    public void onPause() {
-        super.onPause();
-        // Calling finish() here because doing it in onCreate(), onStart() or onResume() makes
-        // "adb shell am start" timeout if using the -W option.
-        finish();
-    }
-
-    private void handleIntent(Intent intent) {
-        DevicePolicyManager dpm = (DevicePolicyManager)
-                getSystemService(Context.DEVICE_POLICY_SERVICE);
-        String restrictionKey = intent.getStringExtra(EXTRA_RESTRICTION_KEY);
-        String command = intent.getStringExtra(EXTRA_COMMAND);
-        Log.i(TAG, "Command: \"" + command + "\". Restriction: \"" + restrictionKey + "\"");
-
-        if (ADD_COMMAND.equals(command)) {
-            dpm.addUserRestriction(BaseDeviceAdminTest.ADMIN_RECEIVER_COMPONENT, restrictionKey);
-            Log.i(TAG, "Added user restriction " + restrictionKey
-                    + " for user " + Process.myUserHandle());
-        } else if (CLEAR_COMMAND.equals(command)) {
-            dpm.clearUserRestriction(
-                    BaseDeviceAdminTest.ADMIN_RECEIVER_COMPONENT, restrictionKey);
-            Log.i(TAG, "Cleared user restriction " + restrictionKey
-                    + " for user " + Process.myUserHandle());
-        } else {
-            Log.e(TAG, "Invalid command: " + command);
-        }
-    }
-
-}
\ No newline at end of file
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/Utils.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/Utils.java
new file mode 100644
index 0000000..fefc2ce
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/Utils.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.deviceandprofileowner;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.content.Context;
+
+import junit.framework.Assert;
+
+public class Utils {
+    private Utils() {
+    }
+
+    public static void removeActiveAdmin(Context context, ComponentName cn) throws Exception {
+        final DevicePolicyManager dpm = context.getSystemService(DevicePolicyManager.class);
+        if (dpm.isAdminActive(cn)) {
+            dpm.removeActiveAdmin(cn);
+            assertNotActiveAdmin(context, cn);
+        }
+    }
+
+    public static void assertNotActiveAdmin(Context context, ComponentName cn) throws Exception {
+        final DevicePolicyManager dpm = context.getSystemService(DevicePolicyManager.class);
+
+        for (int i = 0; i < 1000 && dpm.isAdminActive(cn); i++) {
+            Thread.sleep(100);
+        }
+        Assert.assertFalse(dpm.isAdminActive(cn));
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/BaseUserRestrictionsTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/BaseUserRestrictionsTest.java
new file mode 100644
index 0000000..a7d8110
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/BaseUserRestrictionsTest.java
@@ -0,0 +1,219 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.deviceandprofileowner.userrestrictions;
+
+import android.os.UserManager;
+
+import com.android.cts.deviceandprofileowner.BaseDeviceAdminTest;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+public abstract class BaseUserRestrictionsTest extends BaseDeviceAdminTest {
+    protected static final String[] ALL_USER_RESTRICTIONS = new String[]{
+            UserManager.DISALLOW_CONFIG_WIFI,
+            UserManager.DISALLOW_MODIFY_ACCOUNTS,
+            UserManager.DISALLOW_INSTALL_APPS,
+            UserManager.DISALLOW_UNINSTALL_APPS,
+            UserManager.DISALLOW_SHARE_LOCATION,
+            UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES,
+            UserManager.DISALLOW_CONFIG_BLUETOOTH,
+            UserManager.DISALLOW_USB_FILE_TRANSFER,
+            UserManager.DISALLOW_CONFIG_CREDENTIALS,
+            UserManager.DISALLOW_REMOVE_USER,
+            UserManager.DISALLOW_DEBUGGING_FEATURES,
+            UserManager.DISALLOW_CONFIG_VPN,
+            UserManager.DISALLOW_CONFIG_TETHERING,
+            UserManager.DISALLOW_NETWORK_RESET,
+            UserManager.DISALLOW_FACTORY_RESET,
+            UserManager.DISALLOW_ADD_USER,
+            UserManager.ENSURE_VERIFY_APPS,
+            UserManager.DISALLOW_CONFIG_CELL_BROADCASTS,
+            UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS,
+            UserManager.DISALLOW_APPS_CONTROL,
+            UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA,
+            UserManager.DISALLOW_UNMUTE_MICROPHONE,
+            UserManager.DISALLOW_ADJUST_VOLUME,
+            UserManager.DISALLOW_OUTGOING_CALLS,
+            UserManager.DISALLOW_SMS,
+            UserManager.DISALLOW_FUN,
+            UserManager.DISALLOW_CREATE_WINDOWS,
+            UserManager.DISALLOW_CROSS_PROFILE_COPY_PASTE,
+            UserManager.DISALLOW_OUTGOING_BEAM,
+            UserManager.DISALLOW_SAFE_BOOT,
+            UserManager.ALLOW_PARENT_PROFILE_APP_LINKING,
+            UserManager.DISALLOW_DATA_ROAMING,
+            UserManager.DISALLOW_SET_USER_ICON
+    };
+
+    /**
+     * Restrictions that affect all users when DO sets.
+     */
+    protected static final String[] DO_GLOBAL_RESTRICTIONS = new String[] {
+            UserManager.DISALLOW_USB_FILE_TRANSFER,
+            UserManager.DISALLOW_CONFIG_TETHERING,
+            UserManager.DISALLOW_NETWORK_RESET,
+            UserManager.DISALLOW_FACTORY_RESET,
+            UserManager.DISALLOW_ADD_USER,
+            UserManager.DISALLOW_CONFIG_CELL_BROADCASTS,
+            UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS,
+            UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA,
+            UserManager.DISALLOW_SMS,
+            UserManager.DISALLOW_FUN,
+            UserManager.DISALLOW_SAFE_BOOT,
+            UserManager.DISALLOW_CREATE_WINDOWS,
+            // UserManager.DISALLOW_DATA_ROAMING, // Not set during CTS
+
+            // PO can set them too, but when DO sets them, they're global.
+            UserManager.DISALLOW_ADJUST_VOLUME,
+            UserManager.DISALLOW_UNMUTE_MICROPHONE
+    };
+
+    public static final String[] HIDDEN_AND_PROHIBITED = new String[] {
+            "no_record_audio",
+            "no_wallpaper"
+    };
+
+    protected void assertLayeredRestriction(String restriction, boolean expected) {
+        assertEquals("Restriction " + restriction + ": expected=" + expected,
+                expected, mUserManager.hasUserRestriction(restriction));
+    }
+
+    protected void assertOwnerRestriction(String restriction, boolean expected) {
+        assertEquals("Restriction " + restriction + ": expected=" + expected,
+                expected, mDevicePolicyManager.getUserRestrictions(ADMIN_RECEIVER_COMPONENT)
+                        .getBoolean(restriction));
+    }
+
+    protected void assertRestrictions(Set<String> expected) {
+        for (String r : ALL_USER_RESTRICTIONS) {
+            assertLayeredRestriction(r, expected.contains(r));
+        }
+    }
+
+    /**
+     * Test that the given restriction can be set and cleared, then leave it set again.
+     */
+    protected void assertSetClearUserRestriction(String restriction) {
+        final boolean hadRestriction = mUserManager.hasUserRestriction(restriction);
+
+        assertOwnerRestriction(restriction, false);
+
+        // Set.  Shouldn't throw.
+        mDevicePolicyManager.addUserRestriction(ADMIN_RECEIVER_COMPONENT, restriction);
+
+        assertOwnerRestriction(restriction, true);
+        assertLayeredRestriction(restriction, true);
+
+        // Then clear.
+        assertClearUserRestriction(restriction);
+
+        assertLayeredRestriction(restriction, hadRestriction);
+
+        // Then set again.
+        mDevicePolicyManager.addUserRestriction(ADMIN_RECEIVER_COMPONENT, restriction);
+    }
+
+    /**
+     * Test that the given restriction can be cleared.  (and leave it cleared.)
+     */
+    protected void assertClearUserRestriction(String restriction) {
+        mDevicePolicyManager.clearUserRestriction(ADMIN_RECEIVER_COMPONENT, restriction);
+
+        assertOwnerRestriction(restriction, false);
+    }
+
+    /**
+     * Test that the given restriction *cannot* be set (or clear).
+     */
+    protected void assertCannotSetUserRestriction(String restriction) {
+        final boolean hadRestriction = mUserManager.hasUserRestriction(restriction);
+
+        assertOwnerRestriction(restriction, false);
+
+        // Set should fail.
+        try {
+            mDevicePolicyManager.addUserRestriction(ADMIN_RECEIVER_COMPONENT, restriction);
+            fail("Restriction=" + restriction);
+        } catch (SecurityException e) {
+            assertTrue("Restriction=" + restriction + " Message was: " + e.getMessage(),
+                    e.getMessage().contains("cannot set user restriction"));
+        }
+
+        // Shouldn't have changed.
+        assertOwnerRestriction(restriction, false);
+        assertLayeredRestriction(restriction, hadRestriction);
+
+        // Clear should fail too.
+        try {
+            mDevicePolicyManager.clearUserRestriction(ADMIN_RECEIVER_COMPONENT, restriction);
+            fail("Restriction=" + restriction);
+        } catch (SecurityException e) {
+            assertTrue("Restriction=" + restriction + " Message was: " + e.getMessage(),
+                    e.getMessage().contains("cannot set user restriction"));
+        }
+
+        // Shouldn't have changed.
+        assertOwnerRestriction(restriction, false);
+        assertLayeredRestriction(restriction, hadRestriction);
+    }
+
+    /** For {@link #testSetAllRestrictions} */
+    protected abstract String[] getAllowedRestrictions();
+
+    /** For {@link #testSetAllRestrictions} */
+    protected abstract String[] getDisallowedRestrictions();
+
+    /**
+     * Set only one restriction, and make sure only that's set, and then clear it.
+     */
+    public void testSetAllRestrictionsIndividually() {
+        for (String r : getAllowedRestrictions()) {
+            // Set it.
+            assertSetClearUserRestriction(r);
+
+            assertRestrictions(new HashSet<>(Arrays.asList(new String[]{r})));
+
+            // Then clear it.
+            assertClearUserRestriction(r);
+        }
+    }
+
+    /**
+     * Make sure all allowed restrictions can be set, and the others can't.
+     */
+    public void testSetAllRestrictions() {
+        for (String r : getAllowedRestrictions()) {
+            assertSetClearUserRestriction(r);
+        }
+        for (String r : getDisallowedRestrictions()) {
+            assertCannotSetUserRestriction(r);
+        }
+        for (String r : HIDDEN_AND_PROHIBITED) {
+            assertCannotSetUserRestriction(r);
+        }
+    }
+
+    /**
+     * Clear all allowed restrictions.
+     */
+    public void testClearAllRestrictions() {
+        for (String r : getAllowedRestrictions()) {
+            assertClearUserRestriction(r);
+        }
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/CheckNoOwnerRestrictionsTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/CheckNoOwnerRestrictionsTest.java
new file mode 100644
index 0000000..14e5f84
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/CheckNoOwnerRestrictionsTest.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.deviceandprofileowner.userrestrictions;
+
+import android.os.UserManager;
+import android.test.AndroidTestCase;
+
+/**
+ * Used after after DO/PO are removed to make sure user restrictions set by them are no longer
+ * set.
+ */
+public class CheckNoOwnerRestrictionsTest extends AndroidTestCase {
+    public void testNoOwnerRestrictions() {
+        assertFalse(mContext.getSystemService(UserManager.class).hasUserRestriction(
+                UserManager.DISALLOW_UNMUTE_MICROPHONE));
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/DeviceOwnerUserRestrictionsTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/DeviceOwnerUserRestrictionsTest.java
new file mode 100644
index 0000000..1ff9b6c
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/DeviceOwnerUserRestrictionsTest.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.deviceandprofileowner.userrestrictions;
+
+import android.os.UserManager;
+
+public class DeviceOwnerUserRestrictionsTest extends BaseUserRestrictionsTest {
+    public static final String[] ALLOWED = new String[] {
+            // UserManager.DISALLOW_CONFIG_WIFI, // Has unrecoverable side effects.
+            UserManager.DISALLOW_MODIFY_ACCOUNTS,
+            UserManager.DISALLOW_INSTALL_APPS,
+            UserManager.DISALLOW_UNINSTALL_APPS,
+            // UserManager.DISALLOW_SHARE_LOCATION, // Has unrecoverable side effects.
+            // UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, // Has unrecoverable side effects.
+            UserManager.DISALLOW_CONFIG_BLUETOOTH,
+            UserManager.DISALLOW_USB_FILE_TRANSFER,
+            UserManager.DISALLOW_CONFIG_CREDENTIALS,
+            UserManager.DISALLOW_REMOVE_USER,
+            // UserManager.DISALLOW_DEBUGGING_FEATURES, // Need for CTS
+            UserManager.DISALLOW_CONFIG_VPN,
+            UserManager.DISALLOW_CONFIG_TETHERING,
+            UserManager.DISALLOW_NETWORK_RESET,
+            UserManager.DISALLOW_FACTORY_RESET,
+            UserManager.DISALLOW_ADD_USER,
+            // UserManager.ENSURE_VERIFY_APPS, // Has unrecoverable side effects.
+            UserManager.DISALLOW_CONFIG_CELL_BROADCASTS,
+            UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS,
+            UserManager.DISALLOW_APPS_CONTROL,
+            UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA,
+            UserManager.DISALLOW_UNMUTE_MICROPHONE,
+            UserManager.DISALLOW_ADJUST_VOLUME,
+            UserManager.DISALLOW_OUTGOING_CALLS,
+            UserManager.DISALLOW_SMS,
+            UserManager.DISALLOW_FUN,
+            UserManager.DISALLOW_CREATE_WINDOWS,
+            UserManager.DISALLOW_CROSS_PROFILE_COPY_PASTE,
+            UserManager.DISALLOW_OUTGOING_BEAM,
+            UserManager.DISALLOW_SAFE_BOOT,
+            UserManager.ALLOW_PARENT_PROFILE_APP_LINKING,
+            // UserManager.DISALLOW_DATA_ROAMING, // Has unrecoverable side effects.
+            UserManager.DISALLOW_SET_USER_ICON
+    };
+
+    public static final String[] DISALLOWED = new String[] {
+            // DO can set all public restrictions.
+    };
+
+    @Override
+    protected String[] getAllowedRestrictions() {
+        return ALLOWED;
+    }
+
+    @Override
+    protected String[] getDisallowedRestrictions() {
+        return DISALLOWED;
+    }
+}
+
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/PrimaryProfileOwnerUserRestrictionsTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/PrimaryProfileOwnerUserRestrictionsTest.java
new file mode 100644
index 0000000..57c49cf
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/PrimaryProfileOwnerUserRestrictionsTest.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.deviceandprofileowner.userrestrictions;
+
+public class PrimaryProfileOwnerUserRestrictionsTest extends BaseUserRestrictionsTest {
+    @Override
+    protected String[] getAllowedRestrictions() {
+        // PO on user-0 can set DO user restrictions too. (for now?)
+        return DeviceOwnerUserRestrictionsTest.ALLOWED;
+    }
+
+    @Override
+    protected String[] getDisallowedRestrictions() {
+        return DeviceOwnerUserRestrictionsTest.DISALLOWED;
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/SecondaryProfileOwnerUserRestrictionsTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/SecondaryProfileOwnerUserRestrictionsTest.java
new file mode 100644
index 0000000..8cd56bf
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/SecondaryProfileOwnerUserRestrictionsTest.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.deviceandprofileowner.userrestrictions;
+
+import android.os.UserManager;
+
+import java.util.Arrays;
+import java.util.HashSet;
+
+public class SecondaryProfileOwnerUserRestrictionsTest extends BaseUserRestrictionsTest {
+    public static final String[] ALLOWED = new String[] {
+            // UserManager.DISALLOW_CONFIG_WIFI, // Has unrecoverable side effects.
+            UserManager.DISALLOW_MODIFY_ACCOUNTS,
+            UserManager.DISALLOW_INSTALL_APPS,
+            UserManager.DISALLOW_UNINSTALL_APPS,
+            // UserManager.DISALLOW_SHARE_LOCATION, // Has unrecoverable side effects.
+            // UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, // Has unrecoverable side effects.
+            UserManager.DISALLOW_CONFIG_BLUETOOTH,
+            UserManager.DISALLOW_CONFIG_CREDENTIALS,
+            UserManager.DISALLOW_REMOVE_USER,
+            // UserManager.DISALLOW_DEBUGGING_FEATURES, // Need for CTS
+            UserManager.DISALLOW_CONFIG_VPN,
+            // UserManager.ENSURE_VERIFY_APPS, // Has unrecoverable side effects.
+            UserManager.DISALLOW_APPS_CONTROL,
+            UserManager.DISALLOW_UNMUTE_MICROPHONE,
+            UserManager.DISALLOW_ADJUST_VOLUME,
+            UserManager.DISALLOW_OUTGOING_CALLS,
+            UserManager.DISALLOW_CROSS_PROFILE_COPY_PASTE,
+            UserManager.DISALLOW_OUTGOING_BEAM,
+            UserManager.ALLOW_PARENT_PROFILE_APP_LINKING,
+            UserManager.DISALLOW_SET_USER_ICON
+    };
+
+    public static final String[] DISALLOWED = new String[] {
+            UserManager.DISALLOW_USB_FILE_TRANSFER,
+            UserManager.DISALLOW_CONFIG_TETHERING,
+            UserManager.DISALLOW_NETWORK_RESET,
+            UserManager.DISALLOW_FACTORY_RESET,
+            UserManager.DISALLOW_ADD_USER,
+            UserManager.DISALLOW_CONFIG_CELL_BROADCASTS,
+            UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS,
+            UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA,
+            UserManager.DISALLOW_SMS,
+            UserManager.DISALLOW_FUN,
+            UserManager.DISALLOW_SAFE_BOOT,
+            UserManager.DISALLOW_CREATE_WINDOWS,
+            UserManager.DISALLOW_DATA_ROAMING
+    };
+
+    @Override
+    protected String[] getAllowedRestrictions() {
+        return ALLOWED;
+    }
+
+    @Override
+    protected String[] getDisallowedRestrictions() {
+        return DISALLOWED;
+    }
+
+    /**
+     * This is called after DO setting all DO restrictions.  Global restrictions should be
+     * visible on other users.
+     */
+    public void testHasGlobalRestrictions() {
+        assertRestrictions(new HashSet<>(Arrays.asList(DO_GLOBAL_RESTRICTIONS)));
+    }
+
+    /**
+     * This is called after DO setting all DO restrictions, and PO setting all PO restrictions.
+     * All global + local restrictions should be visible.
+     */
+    public void testHasBothGlobalAndLocalRestrictions() {
+        final HashSet<String> expected = new HashSet<>();
+
+        // Should see all global ones from DO.
+        expected.addAll(Arrays.asList(DO_GLOBAL_RESTRICTIONS));
+
+        // Should also see all global ones from itself.
+        expected.addAll(Arrays.asList(ALLOWED));
+
+        assertRestrictions(expected);
+    }
+
+    /**
+     * This is called after DO setting all DO restrictions, and PO setting all PO restrictions,
+     * then DO clearing all restrictions.  Only PO restrictions should be set.
+     */
+    public void testLocalRestrictionsOnly() {
+        // Now should only see the ones that are set by this PO.
+        assertRestrictions(new HashSet<>(Arrays.asList(ALLOWED)));
+    }
+
+    /**
+     * Only the default restrictions should be set.
+     */
+    public void testDefaultRestrictionsOnly() {
+        final HashSet<String> expected = new HashSet<>(
+                // No restrictions.
+        );
+
+        assertRestrictions(expected);
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/Android.mk b/hostsidetests/devicepolicy/app/DeviceOwner/Android.mk
index 314f996..54c0716 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/Android.mk
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/Android.mk
@@ -26,8 +26,11 @@
 
 LOCAL_JAVA_LIBRARIES := android.test.runner cts-junit
 
-LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner compatibility-device-util_v2
+LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner compatibility-device-util ub-uiautomator
 
-LOCAL_SDK_VERSION := current
+LOCAL_SDK_VERSION := test_current
+
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
 
 include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/AndroidManifest.xml b/hostsidetests/devicepolicy/app/DeviceOwner/AndroidManifest.xml
index e424f18..1944444 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/AndroidManifest.xml
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/AndroidManifest.xml
@@ -23,6 +23,7 @@
     <uses-permission android:name="android.permission.WRITE_SETTINGS" />
     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
     <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
+    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
 
     <application>
         <uses-library android:name="android.test.runner" />
@@ -35,6 +36,15 @@
                 <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
             </intent-filter>
         </receiver>
+        <receiver
+            android:name="com.android.cts.deviceowner.CreateAndManageUserTest$TestProfileOwner"
+            android:permission="android.permission.BIND_DEVICE_ADMIN">
+            <meta-data android:name="android.app.device_admin"
+                       android:resource="@xml/device_admin" />
+            <intent-filter>
+                <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
+            </intent-filter>
+        </receiver>
 
         <activity
             android:name="com.android.cts.deviceowner.KeyManagementActivity" />
@@ -52,6 +62,9 @@
             android:name="com.android.cts.deviceowner.LockTaskTest$IntentReceivingActivity"
             android:taskAffinity="com.android.cts.deviceowner.LockTaskTest.IntentReceivingActivity"
             />
+        <!-- Add a network security config that trusts user added CAs for tests -->
+        <meta-data android:name="android.security.net.config"
+                   android:resource="@xml/network_security_config" />
     </application>
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/res/xml/network_security_config.xml b/hostsidetests/devicepolicy/app/DeviceOwner/res/xml/network_security_config.xml
new file mode 100644
index 0000000..1bb298a
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/res/xml/network_security_config.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<network-security-config>
+  <base-config>
+    <trust-anchors>
+      <certificates src="user" />
+    </trust-anchors>
+  </base-config>
+</network-security-config>
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/BaseDeviceOwnerTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/BaseDeviceOwnerTest.java
index b6815fd..b49f923 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/BaseDeviceOwnerTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/BaseDeviceOwnerTest.java
@@ -32,7 +32,7 @@
  * assume these are done. The admin component can be accessed through
  * {@link #getWho()}.
  */
-public class BaseDeviceOwnerTest extends AndroidTestCase {
+public abstract class BaseDeviceOwnerTest extends AndroidTestCase {
 
     public static class BasicAdminReceiver extends DeviceAdminReceiver {
         @Override
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/CaCertManagementTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/CaCertManagementTest.java
index 51c575c..fc9cacb 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/CaCertManagementTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/CaCertManagementTest.java
@@ -15,6 +15,8 @@
  */
 package com.android.cts.deviceowner;
 
+import android.security.NetworkSecurityPolicy;
+
 import java.io.ByteArrayInputStream;
 import java.security.GeneralSecurityException;
 import java.security.KeyStore;
@@ -127,6 +129,8 @@
             }
         }
 
+        NetworkSecurityPolicy.getInstance().handleTrustStorageUpdate();
+
         boolean trusted = false;
         final TrustManagerFactory tmf =
                 TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/ClearDeviceOwnerTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/ClearDeviceOwnerTest.java
index f10124a..70829ed 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/ClearDeviceOwnerTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/ClearDeviceOwnerTest.java
@@ -30,12 +30,12 @@
         mDevicePolicyManager = (DevicePolicyManager)
                 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
         if (mDevicePolicyManager != null) {
-            removeActiveAdmin(BaseDeviceOwnerTest.getWho());
             if (mDevicePolicyManager.isDeviceOwnerApp(BaseDeviceOwnerTest.PACKAGE_NAME)) {
                 mDevicePolicyManager.clearDeviceOwnerApp(BaseDeviceOwnerTest.PACKAGE_NAME);
             }
-            assertFalse(mDevicePolicyManager.isAdminActive(BaseDeviceOwnerTest.getWho()));
             assertFalse(mDevicePolicyManager.isDeviceOwnerApp(BaseDeviceOwnerTest.PACKAGE_NAME));
+
+            waitForActiveAdminRemoved(BaseDeviceOwnerTest.getWho());
         }
 
         super.tearDown();
@@ -46,12 +46,10 @@
     public void testClearDeviceOwner() {
     }
 
-    private void removeActiveAdmin(ComponentName cn) throws InterruptedException {
-        if (mDevicePolicyManager.isAdminActive(cn)) {
-            mDevicePolicyManager.removeActiveAdmin(cn);
-            for (int i = 0; i < 1000 && mDevicePolicyManager.isAdminActive(cn); i++) {
-                Thread.sleep(100);
-            }
+    private void waitForActiveAdminRemoved(ComponentName cn) throws InterruptedException {
+        for (int i = 0; i < 1000 && mDevicePolicyManager.isAdminActive(cn); i++) {
+            Thread.sleep(100);
         }
+        assertFalse(mDevicePolicyManager.isAdminActive(cn));
     }
 }
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
new file mode 100644
index 0000000..391ef15
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/CreateAndManageUserTest.java
@@ -0,0 +1,273 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.deviceowner;
+
+import android.app.ActivityManager;
+import android.app.admin.DeviceAdminReceiver;
+import android.app.admin.DevicePolicyManager;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.os.PersistableBundle;
+import android.os.Process;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.provider.Settings;
+
+import java.lang.reflect.Field;
+
+/**
+ * Test {@link DevicePolicyManager#createAndManageUser}.
+ */
+public class CreateAndManageUserTest extends BaseDeviceOwnerTest {
+
+    private static final String BROADCAST_EXTRA = "broadcastExtra";
+    private static final String ACTION_EXTRA = "actionExtra";
+    private static final String SERIAL_EXTRA = "serialExtra";
+    private static final String PROFILE_OWNER_EXTRA = "profileOwnerExtra";
+    private static final String SETUP_COMPLETE_EXTRA = "setupCompleteExtra";
+    private static final int BROADCAST_TIMEOUT = 15_000;
+    private static final int USER_SWITCH_DELAY = 10_000;
+    private PackageManager mPackageManager;
+    private ActivityManager mActivityManager;
+    private volatile boolean mReceived;
+    private volatile boolean mTestProfileOwnerWasUsed;
+    private volatile boolean mSetupComplete;
+    private UserHandle mUserHandle;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mPackageManager = mContext.getPackageManager();
+        mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        mDevicePolicyManager.clearUserRestriction(getWho(), UserManager.DISALLOW_ADD_USER);
+        mDevicePolicyManager.clearUserRestriction(getWho(), UserManager.DISALLOW_REMOVE_USER);
+        // Remove user in case of failed test.
+        if (mUserHandle != null) {
+            mDevicePolicyManager.removeUser(getWho(), mUserHandle);
+            mUserHandle = null;
+        }
+        super.tearDown();
+    }
+
+    // This class is used by createAndManageUserTest as profile owner for the new user. When
+    // enabled, it sends a broadcast to signal success.
+    public static class TestProfileOwner extends DeviceAdminReceiver {
+        @Override
+        public void onEnabled(Context context, Intent intent) {
+            if (intent.getBooleanExtra(BROADCAST_EXTRA, false)) {
+                Intent i = new Intent(intent.getStringExtra(ACTION_EXTRA));
+                UserManager userManager = (UserManager)
+                        context.getSystemService(Context.USER_SERVICE);
+                long serial = intent.getLongExtra(SERIAL_EXTRA, 0);
+                UserHandle handle = userManager.getUserForSerialNumber(serial);
+                i.putExtra(PROFILE_OWNER_EXTRA, true);
+                // find value of user_setup_complete on new user, and send the result back
+                try {
+                    boolean setupComplete = (Settings.Secure.getInt(context.getContentResolver(),
+                            "user_setup_complete") == 1);
+                    i.putExtra(SETUP_COMPLETE_EXTRA, setupComplete);
+                } catch (Settings.SettingNotFoundException e) {
+                    fail("Did not find settings user_setup_complete");
+                }
+
+                context.sendBroadcastAsUser(i, handle);
+            }
+        }
+
+        public static ComponentName getComponentName() {
+            return new ComponentName(CreateAndManageUserTest.class.getPackage().getName(),
+                    TestProfileOwner.class.getName());
+        }
+    }
+
+    private void waitForBroadcastLocked() {
+        // Wait for broadcast. Time is measured in a while loop because of spurious wakeups.
+        final long initTime = System.currentTimeMillis();
+        while (!mReceived) {
+            try {
+                wait(BROADCAST_TIMEOUT - (System.currentTimeMillis() - initTime));
+            } catch (InterruptedException e) {
+                fail("InterruptedException: " + e.getMessage());
+            }
+            if (!mReceived && System.currentTimeMillis() - initTime > BROADCAST_TIMEOUT) {
+                fail("Timeout while waiting for broadcast after createAndManageUser.");
+            }
+        }
+    }
+
+    // This test will create a user that will get passed a bundle that we specify. The bundle will
+    // contain an action and a serial (for user handle) to broadcast to notify the test that the
+    // configuration was triggered.
+    private void createAndManageUserTest(final int flags) {
+        // This test sets a profile owner on the user, which requires the managed_users feature.
+        if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS)) {
+            return;
+        }
+
+        final boolean expectedSetupComplete = (flags & DevicePolicyManager.SKIP_SETUP_WIZARD) != 0;
+        UserManager userManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+
+        UserHandle firstUser = Process.myUserHandle();
+        final String testUserName = "TestUser_" + System.currentTimeMillis();
+        String action = "com.android.cts.TEST_USER_ACTION";
+        PersistableBundle bundle = new PersistableBundle();
+        bundle.putBoolean(BROADCAST_EXTRA, true);
+        bundle.putLong(SERIAL_EXTRA, userManager.getSerialNumberForUser(firstUser));
+        bundle.putString(ACTION_EXTRA, action);
+
+        mReceived = false;
+        mTestProfileOwnerWasUsed = false;
+        mSetupComplete = !expectedSetupComplete;
+        BroadcastReceiver receiver = new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                mReceived = true;
+                if (intent.getBooleanExtra(PROFILE_OWNER_EXTRA, false)) {
+                    mTestProfileOwnerWasUsed = true;
+                }
+                mSetupComplete = intent.getBooleanExtra(SETUP_COMPLETE_EXTRA,
+                        !expectedSetupComplete);
+                synchronized (CreateAndManageUserTest.this) {
+                    CreateAndManageUserTest.this.notify();
+                }
+            }
+        };
+
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(action);
+        mContext.registerReceiver(receiver, filter);
+
+        synchronized (this) {
+            mUserHandle = mDevicePolicyManager.createAndManageUser(getWho(), testUserName,
+                    TestProfileOwner.getComponentName(), bundle, flags);
+            assertNotNull(mUserHandle);
+
+            mDevicePolicyManager.switchUser(getWho(), mUserHandle);
+            try {
+                wait(USER_SWITCH_DELAY);
+            } catch (InterruptedException e) {
+                fail("InterruptedException: " + e.getMessage());
+            }
+            mDevicePolicyManager.switchUser(getWho(), firstUser);
+
+            waitForBroadcastLocked();
+
+            assertTrue(mReceived);
+            assertTrue(mTestProfileOwnerWasUsed);
+            assertEquals(expectedSetupComplete, mSetupComplete);
+
+            assertTrue(mDevicePolicyManager.removeUser(getWho(), mUserHandle));
+
+            mUserHandle = null;
+        }
+
+        mContext.unregisterReceiver(receiver);
+    }
+
+    /**
+     * Test creating an ephemeral user using the {@link DevicePolicyManager#createAndManageUser}
+     * method.
+     *
+     * <p>The test creates a user by calling to {@link DevicePolicyManager#createAndManageUser}. It
+     * doesn't remove the user afterwards, so its properties can be queried and tested by host-side
+     * tests.
+     * <p>The user's flags will be checked from the corresponding host-side test.
+     */
+    public void testCreateAndManageEphemeralUser() throws Exception {
+        String testUserName = "TestUser_" + System.currentTimeMillis();
+
+        // Use reflection to get the value of the hidden flag to make the new user ephemeral.
+        Field field = DevicePolicyManager.class.getField("MAKE_USER_EPHEMERAL");
+        int makeEphemeralFlag = field.getInt(null);
+
+        // Do not assign return value to mUserHandle, so it is not removed in tearDown.
+        mDevicePolicyManager.createAndManageUser(
+                getWho(),
+                testUserName,
+                getWho(),
+                null,
+                makeEphemeralFlag);
+    }
+
+    /**
+     * Test creating an ephemeral user using the {@link DevicePolicyManager#createAndManageUser}
+     * method fails on systems without the split system user.
+     *
+     * <p>To be used by host-side test on systems without the split system user.
+     */
+    public void testCreateAndManageEphemeralUserFails() throws Exception {
+        String testUserName = "TestUser_" + System.currentTimeMillis();
+
+        // Use reflection to get the value of the hidden flag to make the new user ephemeral.
+        Field field = DevicePolicyManager.class.getField("MAKE_USER_EPHEMERAL");
+        int makeEphemeralFlag = field.getInt(null);
+
+        try {
+            mDevicePolicyManager.createAndManageUser(
+                    getWho(),
+                    testUserName,
+                    getWho(),
+                    null,
+                    makeEphemeralFlag);
+        } catch (IllegalArgumentException e) {
+            // Success, the expected exception was thrown.
+            return;
+        }
+        fail("createAndManageUser should have thrown IllegalArgumentException");
+    }
+
+    public void testCreateAndManageUser_SkipSetupWizard() {
+        createAndManageUserTest(DevicePolicyManager.SKIP_SETUP_WIZARD);
+    }
+
+    public void testCreateAndManageUser_DontSkipSetupWizard() {
+        if (!mActivityManager.isRunningInTestHarness()) {
+            // In test harness, the setup wizard will be disabled by default, so this test is always
+            // failing.
+            createAndManageUserTest(0);
+        }
+    }
+
+    // createAndManageUser should circumvent the DISALLOW_ADD_USER restriction
+    public void testCreateAndManageUser_AddRestrictionSet() {
+        mDevicePolicyManager.addUserRestriction(getWho(), UserManager.DISALLOW_ADD_USER);
+
+        mUserHandle = mDevicePolicyManager.createAndManageUser(getWho(), "Test User", getWho(),
+                null, 0);
+        assertNotNull(mUserHandle);
+    }
+
+    public void testCreateAndManageUser_RemoveRestrictionSet() {
+        mDevicePolicyManager.addUserRestriction(getWho(), UserManager.DISALLOW_REMOVE_USER);
+
+        mUserHandle = mDevicePolicyManager.createAndManageUser(getWho(), "Test User", getWho(),
+                null, 0);
+        assertNotNull(mUserHandle);
+
+        boolean removed = mDevicePolicyManager.removeUser(getWho(), mUserHandle);
+        assertFalse(removed);
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/ForceEphemeralUsersTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/ForceEphemeralUsersTest.java
new file mode 100644
index 0000000..c5fa4b2
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/ForceEphemeralUsersTest.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.deviceowner;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * Test {@link DevicePolicyManager#getForceEphemeralUser} and
+ * {@link DevicePolicyManager#setForceEphemeralUser}.
+ *
+ * <p>The test toggles force-ephemeral-user policy on and leaves it that way which enables
+ * combining it with additional host-side tests.
+ */
+public class ForceEphemeralUsersTest extends BaseDeviceOwnerTest {
+
+    /**
+     * Test setting and subsequently getting the force-ephemeral-user policy.
+     */
+    public void testSetForceEphemeralUsers() throws Exception {
+        Method setForceEphemeralUsersMethod = DevicePolicyManager.class.getDeclaredMethod(
+                "setForceEphemeralUsers", ComponentName.class, boolean.class);
+        setForceEphemeralUsersMethod.invoke(mDevicePolicyManager, getWho(), true);
+
+        Method getForceEphemeralUsersMethod = DevicePolicyManager.class.getDeclaredMethod(
+                "getForceEphemeralUsers", ComponentName.class);
+        assertTrue((boolean) getForceEphemeralUsersMethod.invoke(mDevicePolicyManager, getWho()));
+    }
+
+    /**
+     * Setting force-ephemeral-user policy should fail if not on system with split system user.
+     *
+     * <p>To be run on systems without split system user.
+     */
+    public void testSetForceEphemeralUsersFails() throws Exception {
+        Method setForceEphemeralUsersMethod = DevicePolicyManager.class.getDeclaredMethod(
+                "setForceEphemeralUsers", ComponentName.class, boolean.class);
+        try {
+            setForceEphemeralUsersMethod.invoke(mDevicePolicyManager, getWho(), true);
+        } catch (InvocationTargetException e) {
+            if (e.getCause() instanceof UnsupportedOperationException) {
+                // Test passed, the exception was thrown as expected.
+                return;
+            }
+        }
+        fail("UnsupportedOperationException should have been thrown by setForceEphemeralUsers");
+    }
+
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/HardwarePropertiesManagerTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/HardwarePropertiesManagerTest.java
new file mode 100644
index 0000000..40e5220
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/HardwarePropertiesManagerTest.java
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.deviceowner;
+
+import android.content.Context;
+import android.os.CpuUsageInfo;
+import android.os.HardwarePropertiesManager;
+import android.os.SystemClock;
+
+import java.lang.Math;
+
+/**
+ * Test {@link HardwarePropertiesManager}
+ */
+public class HardwarePropertiesManagerTest extends BaseDeviceOwnerTest {
+    public static final int MAX_FAN_SPEED = 20000;
+    public static final int MAX_DEVICE_TEMPERATURE = 200;
+    public static final int MONITORING_ITERATION_NUMBER = 10;
+
+    // Time between checks in milliseconds.
+    public static final long SLEEP_TIME = 10;
+
+    private void checkFanSpeed(float speed) {
+        assertTrue(speed >= 0 && speed < MAX_FAN_SPEED);
+    }
+
+    private void checkDeviceTemp(float temp, float throttlingTemp, float shutdownTemp) {
+        // Check validity of current temperature.
+        assertTrue(Math.abs(temp) < MAX_DEVICE_TEMPERATURE
+                || temp == HardwarePropertiesManager.UNDEFINED_TEMPERATURE);
+
+        // Compare current temperature and shutdown threshold.
+        assertTrue(temp < shutdownTemp || temp == HardwarePropertiesManager.UNDEFINED_TEMPERATURE
+                || shutdownTemp == HardwarePropertiesManager.UNDEFINED_TEMPERATURE);
+        // Compare throttling and shutdown thresholds.
+        assertTrue(throttlingTemp < shutdownTemp
+                || throttlingTemp == HardwarePropertiesManager.UNDEFINED_TEMPERATURE
+                || shutdownTemp == HardwarePropertiesManager.UNDEFINED_TEMPERATURE);
+    }
+
+    private void checkCpuUsageInfo(CpuUsageInfo info) {
+        assertTrue(info == null || (info.getActive() >= 0 && info.getTotal() >= 0
+                && info.getTotal() >= info.getActive()));
+    }
+
+    private void checkFanSpeeds(float[] fanSpeeds) {
+        for (float speed : fanSpeeds) {
+            checkFanSpeed(speed);
+        }
+    }
+
+    private void checkTemps(float[] temps, float[] throttlingThresholds,
+            float[] shutdownThresholds) {
+        assertEquals(temps.length, throttlingThresholds.length);
+        assertEquals(temps.length, shutdownThresholds.length);
+        for (int i = 0; i < temps.length; ++i) {
+            checkDeviceTemp(temps[i], throttlingThresholds[i], shutdownThresholds[i]);
+        }
+    }
+
+    private void checkCpuUsages(CpuUsageInfo[] cpuUsages) {
+        for (CpuUsageInfo info : cpuUsages) {
+            checkCpuUsageInfo(info);
+        }
+    }
+
+    // Check validity of new array of fan speeds:
+    // the number of fans should be the same.
+    private void checkFanSpeeds(float[] speeds, float[] oldSpeeds) {
+        assertEquals(speeds.length, oldSpeeds.length);
+    }
+
+    // Check validity of new array of cpu usages:
+    // The number of CPUs should be the same and total/active time should not decrease.
+    private void checkCpuUsages(CpuUsageInfo[] infos,
+            CpuUsageInfo[] oldInfos) {
+        assertEquals(infos.length, oldInfos.length);
+        for (int i = 0; i < infos.length; ++i) {
+            assertTrue(oldInfos[i] == null || infos[i] == null
+                    || (oldInfos[i].getActive() <= infos[i].getActive()
+                        && oldInfos[i].getTotal() <= infos[i].getTotal()));
+        }
+    }
+
+    /**
+     * test points:
+     * 1. Get fan speeds, device temperatures and CPU usage information.
+     * 2. Check for validity.
+     * 3. Sleep.
+     * 4. Do it 10 times and compare with old ones.
+     */
+    public void testHardwarePropertiesManager() throws InterruptedException,
+            SecurityException {
+        HardwarePropertiesManager hm = (HardwarePropertiesManager) getContext().getSystemService(
+                Context.HARDWARE_PROPERTIES_SERVICE);
+
+        float[] oldFanSpeeds = hm.getFanSpeeds();
+
+        float[] cpuTemps = hm.getDeviceTemperatures(
+                HardwarePropertiesManager.DEVICE_TEMPERATURE_CPU,
+                HardwarePropertiesManager.TEMPERATURE_CURRENT);
+        float[] cpuThrottlingThresholds = hm.getDeviceTemperatures(
+                HardwarePropertiesManager.DEVICE_TEMPERATURE_CPU,
+                HardwarePropertiesManager.TEMPERATURE_THROTTLING);
+        float[] cpuShutdownThresholds = hm.getDeviceTemperatures(
+                HardwarePropertiesManager.DEVICE_TEMPERATURE_CPU,
+                HardwarePropertiesManager.TEMPERATURE_SHUTDOWN);
+
+        float[] gpuTemps = hm.getDeviceTemperatures(
+                HardwarePropertiesManager.DEVICE_TEMPERATURE_GPU,
+                HardwarePropertiesManager.TEMPERATURE_CURRENT);
+        float[] gpuThrottlingThresholds = hm.getDeviceTemperatures(
+                HardwarePropertiesManager.DEVICE_TEMPERATURE_GPU,
+                HardwarePropertiesManager.TEMPERATURE_THROTTLING);
+        float[] gpuShutdownThresholds = hm.getDeviceTemperatures(
+                HardwarePropertiesManager.DEVICE_TEMPERATURE_GPU,
+                HardwarePropertiesManager.TEMPERATURE_SHUTDOWN);
+
+        float[] batteryTemps = hm.getDeviceTemperatures(
+                HardwarePropertiesManager.DEVICE_TEMPERATURE_BATTERY,
+                HardwarePropertiesManager.TEMPERATURE_CURRENT);
+        float[] batteryThrottlingThresholds = hm.getDeviceTemperatures(
+                HardwarePropertiesManager.DEVICE_TEMPERATURE_BATTERY,
+                HardwarePropertiesManager.TEMPERATURE_THROTTLING);
+        float[] batteryShutdownThresholds = hm.getDeviceTemperatures(
+                HardwarePropertiesManager.DEVICE_TEMPERATURE_BATTERY,
+                HardwarePropertiesManager.TEMPERATURE_SHUTDOWN);
+
+        float[] skinTemps = hm.getDeviceTemperatures(
+                HardwarePropertiesManager.DEVICE_TEMPERATURE_SKIN,
+                HardwarePropertiesManager.TEMPERATURE_CURRENT);
+        float[] skinThrottlingThresholds = hm.getDeviceTemperatures(
+                HardwarePropertiesManager.DEVICE_TEMPERATURE_SKIN,
+                HardwarePropertiesManager.TEMPERATURE_THROTTLING);
+        float[] skinShutdownThresholds = hm.getDeviceTemperatures(
+                HardwarePropertiesManager.DEVICE_TEMPERATURE_SKIN,
+                HardwarePropertiesManager.TEMPERATURE_SHUTDOWN);
+
+        CpuUsageInfo[] oldCpuUsages = hm.getCpuUsages();
+
+        checkFanSpeeds(oldFanSpeeds);
+        checkTemps(cpuTemps, cpuThrottlingThresholds, cpuShutdownThresholds);
+        checkTemps(gpuTemps, gpuThrottlingThresholds, gpuShutdownThresholds);
+        checkTemps(batteryTemps, batteryThrottlingThresholds, batteryShutdownThresholds);
+        checkTemps(skinTemps, skinThrottlingThresholds, skinShutdownThresholds);
+        checkCpuUsages(oldCpuUsages);
+
+        for (int i = 0; i < MONITORING_ITERATION_NUMBER; i++) {
+            Thread.sleep(SLEEP_TIME);
+
+            float[] fanSpeeds = hm.getFanSpeeds();
+            cpuTemps = hm.getDeviceTemperatures(
+                    HardwarePropertiesManager.DEVICE_TEMPERATURE_CPU,
+                    HardwarePropertiesManager.TEMPERATURE_CURRENT);
+            gpuTemps = hm.getDeviceTemperatures(
+                    HardwarePropertiesManager.DEVICE_TEMPERATURE_GPU,
+                    HardwarePropertiesManager.TEMPERATURE_CURRENT);
+            batteryTemps = hm.getDeviceTemperatures(
+                    HardwarePropertiesManager.DEVICE_TEMPERATURE_BATTERY,
+                    HardwarePropertiesManager.TEMPERATURE_CURRENT);
+            skinTemps = hm.getDeviceTemperatures(
+                    HardwarePropertiesManager.DEVICE_TEMPERATURE_SKIN,
+                    HardwarePropertiesManager.TEMPERATURE_CURRENT);
+            CpuUsageInfo[] cpuUsages = hm.getCpuUsages();
+
+            checkFanSpeeds(fanSpeeds);
+            checkTemps(cpuTemps, cpuThrottlingThresholds, cpuShutdownThresholds);
+            checkTemps(gpuTemps, gpuThrottlingThresholds, gpuShutdownThresholds);
+            checkTemps(batteryTemps, batteryThrottlingThresholds, batteryShutdownThresholds);
+            checkTemps(skinTemps, skinThrottlingThresholds, skinShutdownThresholds);
+            checkCpuUsages(cpuUsages);
+
+            // No need to compare length of old and new temperature arrays:
+            // they are compared through throttling and shutdown threshold arrays lengths.
+            checkFanSpeeds(fanSpeeds, oldFanSpeeds);
+            checkCpuUsages(cpuUsages, oldCpuUsages);
+
+            oldFanSpeeds = fanSpeeds;
+            oldCpuUsages = cpuUsages;
+        }
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/KeyManagementTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/KeyManagementTest.java
index 27fd36f..5d6d7fb 100755
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/KeyManagementTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/KeyManagementTest.java
@@ -21,7 +21,6 @@
 import android.app.Activity;
 import android.app.admin.DevicePolicyManager;
 import android.net.Uri;
-import android.os.Handler;
 import android.security.KeyChain;
 import android.security.KeyChainAliasCallback;
 import android.security.KeyChainException;
@@ -44,10 +43,9 @@
 import android.content.ComponentName;
 import android.content.Context;
 
-public class KeyManagementTest extends
-        ActivityInstrumentationTestCase2<KeyManagementActivity> {
+public class KeyManagementTest extends ActivityInstrumentationTestCase2<KeyManagementActivity> {
 
-    private static final int KEYCHAIN_TIMEOUT_MS = 6 * 60 * 1000;
+    private static final long KEYCHAIN_TIMEOUT_MINS = 6;
     private DevicePolicyManager mDevicePolicyManager;
 
     public KeyManagementTest() {
@@ -77,21 +75,85 @@
         super.tearDown();
     }
 
-    public void testCanInstallValidRsaKeypair()
-            throws CertificateException, NoSuchAlgorithmException, InvalidKeySpecException,
-                    KeyChainException, InterruptedException, UnsupportedEncodingException {
+    public void testCanInstallAndRemoveValidRsaKeypair() throws Exception {
         final String alias = "com.android.test.valid-rsa-key-1";
         final PrivateKey privKey = getPrivateKey(FAKE_RSA_1.privateKey , "RSA");
         final Certificate cert = getCertificate(FAKE_RSA_1.caCertificate);
-        assertTrue(mDevicePolicyManager.installKeyPair(getWho(), privKey, cert, alias));
 
-        assertEquals(alias, new KeyChainAliasFuture(alias).get());
-        final PrivateKey retrievedKey = KeyChain.getPrivateKey(getActivity(), alias);
-        assertEquals(retrievedKey.getAlgorithm(), "RSA");
+        // Install keypair.
+        assertTrue(mDevicePolicyManager.installKeyPair(getWho(), privKey, cert, alias));
+        try {
+            // Request and retrieve using the alias.
+            assertGranted(alias, false);
+            assertEquals(alias, new KeyChainAliasFuture(alias).get());
+            assertGranted(alias, true);
+
+            // Verify key is at least something like the one we put in.
+            assertEquals(KeyChain.getPrivateKey(getActivity(), alias).getAlgorithm(), "RSA");
+        } finally {
+            // Delete regardless of whether the test succeeded.
+            assertTrue(mDevicePolicyManager.removeKeyPair(getWho(), alias));
+        }
+        // Verify alias is actually deleted.
+        assertGranted(alias, false);
     }
 
-    public void testNullKeyParamsFailPredictably()
-            throws CertificateException, NoSuchAlgorithmException, InvalidKeySpecException {
+    public void testCanInstallWithAutomaticAccess() throws Exception {
+        final String grant = "com.android.test.autogrant-key-1";
+        final String withhold = "com.android.test.nongrant-key-1";
+        final PrivateKey privKey = getPrivateKey(FAKE_RSA_1.privateKey , "RSA");
+        final Certificate cert = getCertificate(FAKE_RSA_1.caCertificate);
+
+        // Install keypairs.
+        assertTrue(mDevicePolicyManager.installKeyPair(getWho(), privKey, new Certificate[] {cert},
+                grant, true));
+        assertTrue(mDevicePolicyManager.installKeyPair(getWho(), privKey, new Certificate[] {cert},
+                withhold, false));
+        try {
+            // Verify only the requested key was actually granted.
+            assertGranted(grant, true);
+            assertGranted(withhold, false);
+
+            // Verify the granted key is actually obtainable in PrivateKey form.
+            assertEquals(KeyChain.getPrivateKey(getActivity(), grant).getAlgorithm(), "RSA");
+        } finally {
+            // Delete both keypairs.
+            assertTrue(mDevicePolicyManager.removeKeyPair(getWho(), grant));
+            assertTrue(mDevicePolicyManager.removeKeyPair(getWho(), withhold));
+        }
+        // Verify they're actually gone.
+        assertGranted(grant, false);
+        assertGranted(withhold, false);
+    }
+
+    public void testGrantsDoNotPersistBetweenInstallations() throws Exception {
+        final String alias = "com.android.test.persistent-key-1";
+        final PrivateKey privKey = getPrivateKey(FAKE_RSA_1.privateKey , "RSA");
+        final Certificate cert = getCertificate(FAKE_RSA_1.caCertificate);
+
+        // Install keypair.
+        assertTrue(mDevicePolicyManager.installKeyPair(getWho(), privKey, new Certificate[] {cert},
+                alias, true));
+        try {
+            assertGranted(alias, true);
+        } finally {
+            // Delete and verify.
+            assertTrue(mDevicePolicyManager.removeKeyPair(getWho(), alias));
+        }
+        assertGranted(alias, false);
+
+        // Install again.
+        assertTrue(mDevicePolicyManager.installKeyPair(getWho(), privKey, new Certificate[] {cert},
+                alias, false));
+        try {
+            assertGranted(alias, false);
+        } finally {
+            // Delete.
+            assertTrue(mDevicePolicyManager.removeKeyPair(getWho(), alias));
+        }
+    }
+
+    public void testNullKeyParamsFailPredictably() throws Exception {
         final String alias = "com.android.test.null-key-1";
         final PrivateKey privKey = getPrivateKey(FAKE_RSA_1.privateKey, "RSA");
         final Certificate cert = getCertificate(FAKE_RSA_1.caCertificate);
@@ -107,8 +169,7 @@
         }
     }
 
-    public void testNullAdminComponentIsDenied()
-            throws CertificateException, NoSuchAlgorithmException, InvalidKeySpecException {
+    public void testNullAdminComponentIsDenied() throws Exception {
         final String alias = "com.android.test.null-admin-1";
         final PrivateKey privKey = getPrivateKey(FAKE_RSA_1.privateKey, "RSA");
         final Certificate cert = getCertificate(FAKE_RSA_1.caCertificate);
@@ -119,6 +180,15 @@
         }
     }
 
+    private void assertGranted(String alias, boolean expected) throws InterruptedException {
+        boolean granted = false;
+        try {
+            granted = (KeyChain.getPrivateKey(getActivity(), alias) != null);
+        } catch (KeyChainException e) {
+        }
+        assertEquals("Grant for alias: \"" + alias + "\"", expected, granted);
+    }
+
     private static PrivateKey getPrivateKey(final byte[] key, String type)
             throws NoSuchAlgorithmException, InvalidKeySpecException {
         return KeyFactory.getInstance(type).generatePrivate(
@@ -151,7 +221,7 @@
         }
 
         public String get() throws InterruptedException {
-            assertTrue("Chooser timeout", mLatch.await(KEYCHAIN_TIMEOUT_MS, TimeUnit.MILLISECONDS));
+            assertTrue("Chooser timeout", mLatch.await(KEYCHAIN_TIMEOUT_MINS, TimeUnit.MINUTES));
             return mChosenAlias;
         }
     };
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/LockScreenInfoTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/LockScreenInfoTest.java
new file mode 100644
index 0000000..4863192
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/LockScreenInfoTest.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.deviceowner;
+
+import java.lang.Character;
+
+public class LockScreenInfoTest extends BaseDeviceOwnerTest {
+
+    @Override
+    public void tearDown() throws Exception {
+        mDevicePolicyManager.setDeviceOwnerLockScreenInfo(getWho(), null);
+        super.tearDown();
+    }
+
+    public void testSetAndGetLockInfo() {
+        setLockInfo("testSetAndGet");
+    }
+
+    public void testClearLockInfo() {
+        setLockInfo("testClear");
+        setLockInfo(null);
+
+    }
+
+    public void testEmptyStringClearsLockInfo() {
+        final String message = "";
+        mDevicePolicyManager.setDeviceOwnerLockScreenInfo(getWho(), message);
+        assertNull(mDevicePolicyManager.getDeviceOwnerLockScreenInfo());
+    }
+
+    public void testWhitespaceOnly() {
+        setLockInfo("\t");
+    }
+
+    public void testUnicode() {
+        final String smiley = new String(Character.toChars(0x1F601));
+        final String phone = new String(Character.toChars(0x1F4F1));
+        setLockInfo(smiley + phone + "\t" + phone + smiley);
+    }
+
+    public void testNullInString() {
+        setLockInfo("does \0 this \1 work?");
+    }
+
+    public void testReasonablyLongString() {
+        final int messageLength = 128;
+        setLockInfo(new String(new char[messageLength]).replace('\0', 'Z'));
+    }
+
+    public void testSetLockInfoWithNullAdminFails() {
+        final String message = "nulladmin";
+
+        // Set message
+        try {
+            mDevicePolicyManager.setDeviceOwnerLockScreenInfo(null, message);
+            fail("Exception should have been thrown for null admin ComponentName");
+        } catch (NullPointerException expected) {
+        }
+    }
+
+    /**
+     * Sets device owner lock screen info on behalf of the current device owner admin.
+     *
+     * @throws AssertionError if the setting did not take effect.
+     */
+    private void setLockInfo(String message) {
+        mDevicePolicyManager.setDeviceOwnerLockScreenInfo(getWho(), message);
+        assertEquals(message, mDevicePolicyManager.getDeviceOwnerLockScreenInfo());
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/PreDeviceOwnerTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/PreDeviceOwnerTest.java
new file mode 100644
index 0000000..c70ed16
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/PreDeviceOwnerTest.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.deviceowner;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.Context;
+import android.test.AndroidTestCase;
+
+/**
+ * The following test can run in DeviceOwner mode or non-DeviceOwner mode.
+ * Don't inherit {@link BaseDeviceOwnerTest}
+ */
+public class PreDeviceOwnerTest extends AndroidTestCase {
+
+    protected DevicePolicyManager mDevicePolicyManager;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        mDevicePolicyManager = (DevicePolicyManager)
+                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
+    }
+
+    public void testIsProvisioningAllowedFalse() {
+        assertFalse(mDevicePolicyManager.isProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE));
+    }
+
+    public void testIsProvisioningAllowedFalseForManagedProfileAction() {
+        assertFalse(mDevicePolicyManager
+                .isProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE));
+    }
+
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/RemoteBugreportTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/RemoteBugreportTest.java
new file mode 100644
index 0000000..efefde9
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/RemoteBugreportTest.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.deviceowner;
+
+import android.app.Instrumentation;
+import android.app.NotificationManager;
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.UiDevice;
+import android.support.test.uiautomator.UiObject;
+import android.support.test.uiautomator.UiObject2;
+import android.support.test.uiautomator.UiObjectNotFoundException;
+import android.support.test.uiautomator.UiSelector;
+import android.support.test.uiautomator.Until;
+import android.test.InstrumentationTestCase;
+
+/**
+ * Test class for remote bugreports.
+ *
+ * This class also handles making sure that the test is the device owner
+ * and that it has an active admin registered, so that all tests may
+ * assume these are done. The admin component can be accessed through
+ * {@link BaseDeviceOwnerTest#getWho()}.
+ */
+public class RemoteBugreportTest extends InstrumentationTestCase {
+
+    private static final int UI_TIMEOUT_MILLIS = 5000; //5 seconds
+
+    private static final String MESSAGE_ONLY_ONE_MANAGED_USER_ALLOWED =
+            "There should only be one user, managed by Device Owner";
+
+    private static final String TAKING_BUG_REPORT = "Taking bug report";
+    private static final String DECLINE = "DECLINE";
+
+    private DevicePolicyManager mDevicePolicyManager;
+    private Context mContext;
+    private UiDevice mUiDevice;
+    private ComponentName mComponentName;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        Instrumentation instrumentation = getInstrumentation();
+        mContext = instrumentation.getTargetContext();
+        mUiDevice = UiDevice.getInstance(instrumentation);
+        mDevicePolicyManager = (DevicePolicyManager)
+                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
+        BaseDeviceOwnerTest.assertDeviceOwner(mDevicePolicyManager);
+        mComponentName = BaseDeviceOwnerTest.getWho();
+    }
+
+    /**
+     * Test: only one remote bugreport flow can be running on the device at one time.
+     */
+    public void testSubsequentRemoteBugreportThrottled() {
+        boolean startedSuccessfully = mDevicePolicyManager.requestBugreport(mComponentName);
+        assertTrue(startedSuccessfully);
+
+        // subsequent attempts should be throttled
+        assertFalse(mDevicePolicyManager.requestBugreport(mComponentName));
+        assertFalse(mDevicePolicyManager.requestBugreport(mComponentName));
+
+        cancelRemoteBugreportFlowIfStartedSuccessfully(startedSuccessfully);
+    }
+
+    /**
+     * Test: remote bugreport flow can only be started if there's one user on the device.
+     */
+    public void testRequestBugreportNotStartedIfMoreThanOneUserPresent() {
+        boolean startedSuccessfully = false;
+        try {
+            startedSuccessfully = mDevicePolicyManager.requestBugreport(mComponentName);
+            fail("did not throw expected SecurityException");
+        } catch (SecurityException e) {
+            assertEquals(e.getMessage(), MESSAGE_ONLY_ONE_MANAGED_USER_ALLOWED);
+        } finally {
+            cancelRemoteBugreportFlowIfStartedSuccessfully(startedSuccessfully);
+        }
+    }
+
+    /**
+     * Clicks on "Taking bugreport..." notification, and then DECLINE button on the consent dialog
+     * to cancel the whole remote bugreport flow (including stopping the dumpstate service).
+     */
+    private void cancelRemoteBugreportFlowIfStartedSuccessfully(boolean startedSuccessfully) {
+        if (!startedSuccessfully) {
+            return;
+        }
+
+        UiObject2 bugreportNotification = findRemoteBugreportNotification();
+        assertNotNull(bugreportNotification);
+        bugreportNotification.click();
+
+        // give it max 5 seconds to find the DECLINE button on the dialog
+        boolean declineButtonPresent = mUiDevice.wait(
+                Until.hasObject(By.text(DECLINE)), UI_TIMEOUT_MILLIS);
+        assertTrue(declineButtonPresent);
+
+        UiObject declineButton = mUiDevice.findObject(new UiSelector().text(DECLINE));
+        assertNotNull(declineButton);
+        try {
+            declineButton.click();
+        } catch (UiObjectNotFoundException e) {
+            throw new IllegalStateException("Exception when clicking on 'DECLINE' button", e);
+        }
+    }
+
+    /**
+     * Attempts to find the remote bugreport notification scrolling down in the notification panel
+     * in between 10 attempts.
+     */
+    private UiObject2 findRemoteBugreportNotification() {
+        mUiDevice.openNotification();
+        final int displayWidth = mUiDevice.getDisplayWidth();
+        final int displayHeight = mUiDevice.getDisplayHeight();
+        for (int i = 0; i < 10; i++) {
+            UiObject2 notification = mUiDevice.wait(Until.findObject(
+                    By.textStartsWith(TAKING_BUG_REPORT)), UI_TIMEOUT_MILLIS);
+            if (notification != null) {
+                return notification;
+            } else {
+                /* makes a swipe from the middle of the screen upwards to the top of the screen
+                (the motion is upwards, so it scrolls downwards) half a screen, so that the
+                notification is always fully visible - never cut in two pieces) */
+                mUiDevice.swipe(displayWidth / 2, displayHeight / 2, displayWidth / 2,
+                        /* endY= */ 0, /* steps= */ 30);
+            }
+        }
+        return null;
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/SecurityLoggingTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/SecurityLoggingTest.java
new file mode 100644
index 0000000..8e42279
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/SecurityLoggingTest.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.deviceowner;
+
+import android.app.admin.SecurityLog.SecurityEvent;
+import android.os.UserHandle;
+
+import java.util.List;
+
+public class SecurityLoggingTest extends BaseDeviceOwnerTest {
+
+    private static final String MESSAGE_ONLY_ONE_MANAGED_USER_ALLOWED =
+            "There should only be one user, managed by Device Owner";
+
+    /**
+     * Test: setting security logging can only be done if there's one user on the device.
+     */
+    public void testSetSecurityLoggingEnabledNotPossibleIfMoreThanOneUserPresent() {
+        try {
+            mDevicePolicyManager.setSecurityLoggingEnabled(getWho(), true);
+            fail("did not throw expected SecurityException");
+        } catch (SecurityException e) {
+            assertEquals(e.getMessage(), MESSAGE_ONLY_ONE_MANAGED_USER_ALLOWED);
+        }
+    }
+
+    /**
+     * Test: retrieving security logs can only be done if there's one user on the device.
+     */
+    public void testRetrievingSecurityLogsNotPossibleIfMoreThanOneUserPresent() {
+        try {
+            mDevicePolicyManager.retrieveSecurityLogs(getWho());
+            fail("did not throw expected SecurityException");
+        } catch (SecurityException e) {
+            assertEquals(e.getMessage(), MESSAGE_ONLY_ONE_MANAGED_USER_ALLOWED);
+        }
+    }
+
+    /**
+     * Test: retrieving previous security logs can only be done if there's one user on the device.
+     */
+    public void testRetrievingPreviousSecurityLogsNotPossibleIfMoreThanOneUserPresent() {
+        try {
+            mDevicePolicyManager.retrievePreRebootSecurityLogs(getWho());
+            fail("did not throw expected SecurityException");
+        } catch (SecurityException e) {
+            assertEquals(e.getMessage(), MESSAGE_ONLY_ONE_MANAGED_USER_ALLOWED);
+        }
+    }
+
+    /**
+     * Test: Test enabling and disabling of security logging.
+     */
+    public void testEnablingAndDisablingSecurityLogging() {
+        mDevicePolicyManager.setSecurityLoggingEnabled(getWho(), true);
+        assertTrue(mDevicePolicyManager.isSecurityLoggingEnabled(getWho()));
+        mDevicePolicyManager.setSecurityLoggingEnabled(getWho(), false);
+        assertFalse(mDevicePolicyManager.isSecurityLoggingEnabled(getWho()));
+    }
+
+    /**
+     * Test: retrieving security logs should be rate limited - subsequent attempts should return
+     * null.
+     */
+    public void testRetrievingSecurityLogsNotPossibleImmediatelyAfterPreviousSuccessfulRetrieval() {
+        List<SecurityEvent> logs = mDevicePolicyManager.retrieveSecurityLogs(getWho());
+        // if logs is null it means that that attempt was rate limited => test PASS
+        if (logs != null) {
+            assertNull(mDevicePolicyManager.retrieveSecurityLogs(getWho()));
+            assertNull(mDevicePolicyManager.retrieveSecurityLogs(getWho()));
+        }
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/VrTemperatureTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/VrTemperatureTest.java
new file mode 100644
index 0000000..d3f1f2b
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/VrTemperatureTest.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.deviceowner;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.os.HardwarePropertiesManager;
+import android.test.AndroidTestCase;
+import android.util.Log;
+
+import java.lang.Math;
+
+public class VrTemperatureTest extends BaseDeviceOwnerTest {
+    public static final int MIN_DEVICE_TEMPERATURE = -20;
+    public static final int MAX_DEVICE_TEMPERATURE = 200;
+
+    public boolean supportsVrHighPerformance() {
+        PackageManager pm = getContext().getPackageManager();
+        return pm.hasSystemFeature(PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE);
+    }
+
+    private void checkDeviceTemp(float temp, float throttlingTemp, float shutdownTemp,
+        float vrThrottlingTemp) {
+        // Compare current temperature and shutdown threshold.
+        assertTrue(temp <= shutdownTemp ||
+                shutdownTemp == HardwarePropertiesManager.UNDEFINED_TEMPERATURE);
+
+        // Compare throttling and shutdown thresholds.
+        assertTrue(throttlingTemp <= shutdownTemp ||
+                shutdownTemp == HardwarePropertiesManager.UNDEFINED_TEMPERATURE ||
+                throttlingTemp == HardwarePropertiesManager.UNDEFINED_TEMPERATURE);
+
+        // Compare VR throttling and shutdown thresholds.
+        assertTrue(vrThrottlingTemp <= MIN_DEVICE_TEMPERATURE ||
+                vrThrottlingTemp <= shutdownTemp ||
+                shutdownTemp == HardwarePropertiesManager.UNDEFINED_TEMPERATURE);
+    }
+
+    private void checkTemps(float[] temps, float[] throttlingThresholds,
+            float[] shutdownThresholds, float[] vrThrottlingThresholds) {
+        assertEquals(temps.length, throttlingThresholds.length);
+        assertEquals(temps.length, shutdownThresholds.length);
+        boolean hasVrThreshold = vrThrottlingThresholds != null &&
+                vrThrottlingThresholds.length > 0;
+        if (hasVrThreshold) {
+          assertEquals(temps.length, vrThrottlingThresholds.length);
+        }
+        for (int i = 0; i < temps.length; ++i) {
+            checkDeviceTemp(temps[i], throttlingThresholds[i], shutdownThresholds[i],
+                    !hasVrThreshold ? MIN_DEVICE_TEMPERATURE : vrThrottlingThresholds[i]);
+        }
+    }
+
+    /**
+     * Tests that temperature sensors return valid values.
+     */
+    public void testVrTemperatures() throws InterruptedException, SecurityException {
+        if (!supportsVrHighPerformance())
+            return;
+
+        HardwarePropertiesManager hm = (HardwarePropertiesManager) getContext().getSystemService(
+                Context.HARDWARE_PROPERTIES_SERVICE);
+
+        float[] cpuTemps = hm.getDeviceTemperatures(
+                HardwarePropertiesManager.DEVICE_TEMPERATURE_CPU,
+                HardwarePropertiesManager.TEMPERATURE_CURRENT);
+        float[] cpuThrottlingThresholds = hm.getDeviceTemperatures(
+                HardwarePropertiesManager.DEVICE_TEMPERATURE_CPU,
+                HardwarePropertiesManager.TEMPERATURE_THROTTLING);
+        float[] cpuShutdownThresholds = hm.getDeviceTemperatures(
+                HardwarePropertiesManager.DEVICE_TEMPERATURE_CPU,
+                HardwarePropertiesManager.TEMPERATURE_SHUTDOWN);
+
+        float[] gpuTemps = hm.getDeviceTemperatures(
+                HardwarePropertiesManager.DEVICE_TEMPERATURE_GPU,
+                HardwarePropertiesManager.TEMPERATURE_CURRENT);
+        float[] gpuThrottlingThresholds = hm.getDeviceTemperatures(
+                HardwarePropertiesManager.DEVICE_TEMPERATURE_GPU,
+                HardwarePropertiesManager.TEMPERATURE_THROTTLING);
+        float[] gpuShutdownThresholds = hm.getDeviceTemperatures(
+                HardwarePropertiesManager.DEVICE_TEMPERATURE_GPU,
+                HardwarePropertiesManager.TEMPERATURE_SHUTDOWN);
+
+        float[] batteryTemps = hm.getDeviceTemperatures(
+                HardwarePropertiesManager.DEVICE_TEMPERATURE_BATTERY,
+                HardwarePropertiesManager.TEMPERATURE_CURRENT);
+        float[] batteryThrottlingThresholds = hm.getDeviceTemperatures(
+                HardwarePropertiesManager.DEVICE_TEMPERATURE_BATTERY,
+                HardwarePropertiesManager.TEMPERATURE_THROTTLING);
+        float[] batteryShutdownThresholds = hm.getDeviceTemperatures(
+                HardwarePropertiesManager.DEVICE_TEMPERATURE_BATTERY,
+                HardwarePropertiesManager.TEMPERATURE_SHUTDOWN);
+
+        float[] skinTemps = hm.getDeviceTemperatures(
+                HardwarePropertiesManager.DEVICE_TEMPERATURE_SKIN,
+                HardwarePropertiesManager.TEMPERATURE_CURRENT);
+        float[] skinThrottlingThresholds = hm.getDeviceTemperatures(
+                HardwarePropertiesManager.DEVICE_TEMPERATURE_SKIN,
+                HardwarePropertiesManager.TEMPERATURE_THROTTLING);
+        float[] skinShutdownThresholds = hm.getDeviceTemperatures(
+                HardwarePropertiesManager.DEVICE_TEMPERATURE_SKIN,
+                HardwarePropertiesManager.TEMPERATURE_SHUTDOWN);
+        float[] skinVrThrottlingThresholds = hm.getDeviceTemperatures(
+                HardwarePropertiesManager.DEVICE_TEMPERATURE_SKIN,
+                HardwarePropertiesManager.TEMPERATURE_THROTTLING_BELOW_VR_MIN);
+
+        checkTemps(cpuTemps, cpuThrottlingThresholds, cpuShutdownThresholds, null);
+        checkTemps(gpuTemps, gpuThrottlingThresholds, gpuShutdownThresholds, null);
+        checkTemps(batteryTemps, batteryThrottlingThresholds, batteryShutdownThresholds, null);
+        checkTemps(skinTemps, skinThrottlingThresholds, skinShutdownThresholds,
+                skinVrThrottlingThresholds);
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/WifiTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/WifiTest.java
new file mode 100644
index 0000000..e7df649
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/WifiTest.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.deviceowner;
+
+import android.content.pm.PackageManager;
+import android.text.TextUtils;
+
+/**
+ * Tests that require the WiFi feature.
+ */
+public class WifiTest extends BaseDeviceOwnerTest {
+    public void testGetWifiMacAddress() {
+        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI)) {
+            // wifi not supported.
+            return;
+        }
+        final String macAddress = mDevicePolicyManager.getWifiMacAddress(getWho());
+
+        assertFalse("Device owner should be able to get the real MAC address",
+                "02:00:00:00:00:00".equals(macAddress));
+        assertFalse("getWifiMacAddress() returned an empty string.  WiFi not enabled?",
+                TextUtils.isEmpty(macAddress));
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/IntentReceiver/Android.mk b/hostsidetests/devicepolicy/app/IntentReceiver/Android.mk
index 98cdf52..964c389 100644
--- a/hostsidetests/devicepolicy/app/IntentReceiver/Android.mk
+++ b/hostsidetests/devicepolicy/app/IntentReceiver/Android.mk
@@ -30,4 +30,7 @@
 
 LOCAL_SDK_VERSION := current
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/devicepolicy/app/IntentSender/Android.mk b/hostsidetests/devicepolicy/app/IntentSender/Android.mk
index e5246c5..74509d2 100644
--- a/hostsidetests/devicepolicy/app/IntentSender/Android.mk
+++ b/hostsidetests/devicepolicy/app/IntentSender/Android.mk
@@ -30,4 +30,7 @@
 
 LOCAL_SDK_VERSION := current
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/devicepolicy/app/IntentSender/src/com/android/cts/intent/sender/AppLinkTest.java b/hostsidetests/devicepolicy/app/IntentSender/src/com/android/cts/intent/sender/AppLinkTest.java
index 51ff362..fb22ab3 100644
--- a/hostsidetests/devicepolicy/app/IntentSender/src/com/android/cts/intent/sender/AppLinkTest.java
+++ b/hostsidetests/devicepolicy/app/IntentSender/src/com/android/cts/intent/sender/AppLinkTest.java
@@ -78,6 +78,8 @@
         PackageManager pm = mContext.getPackageManager();
 
         Intent result = mActivity.getResult(getHttpIntent());
+        assertNotNull(result);
+
         // If it is received in the other profile, we cannot check the class from the ResolveInfo
         // returned by queryIntentActivities. So we rely on the receiver telling us its class.
         assertEquals(receiverClassName, result.getStringExtra(EXTRA_RECEIVER_CLASS));
diff --git a/hostsidetests/devicepolicy/app/IntentSender/src/com/android/cts/intent/sender/SuspendPackageTest.java b/hostsidetests/devicepolicy/app/IntentSender/src/com/android/cts/intent/sender/SuspendPackageTest.java
new file mode 100644
index 0000000..18cb3ee
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/IntentSender/src/com/android/cts/intent/sender/SuspendPackageTest.java
@@ -0,0 +1,55 @@
+package com.android.cts.intent.sender;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.test.InstrumentationTestCase;
+
+public class SuspendPackageTest extends InstrumentationTestCase {
+    private IntentSenderActivity mActivity;
+    private Context mContext;
+    private PackageManager mPackageManager;
+
+    private static final String INTENT_RECEIVER_PKG = "com.android.cts.intent.receiver";
+    private static final String TARGET_ACTIVTIY_NAME
+            = "com.android.cts.intent.receiver.SimpleIntentReceiverActivity";
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mContext = getInstrumentation().getTargetContext();
+        mActivity = launchActivity(mContext.getPackageName(), IntentSenderActivity.class, null);
+        mPackageManager = mContext.getPackageManager();
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        mActivity.finish();
+        super.tearDown();
+    }
+
+    public void testPackageSuspended() throws Exception {
+        assertPackageSuspended(true);
+    }
+
+    public void testPackageNotSuspended() throws Exception {
+        assertPackageSuspended(false);
+    }
+
+    /**
+     * Verify the package is suspended by trying start the activity inside it. If the package
+     * is not suspended, the target activity will return the result.
+     */
+    private void assertPackageSuspended(boolean suspended) throws Exception {
+        Intent intent = new Intent();
+        intent.setClassName(INTENT_RECEIVER_PKG, TARGET_ACTIVTIY_NAME);
+        Intent result = mActivity.getResult(intent);
+        if (suspended) {
+            assertNull(result);
+        } else {
+            assertNotNull(result);
+        }
+        // No matter it is suspended or not, we should able to resolve the activity.
+        assertNotNull(mPackageManager.resolveActivity(intent, 0));
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/LauncherTests/Android.mk b/hostsidetests/devicepolicy/app/LauncherTests/Android.mk
index 5f645b6..eb4a091 100644
--- a/hostsidetests/devicepolicy/app/LauncherTests/Android.mk
+++ b/hostsidetests/devicepolicy/app/LauncherTests/Android.mk
@@ -30,4 +30,7 @@
 
 LOCAL_SDK_VERSION := current
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/devicepolicy/app/LauncherTestsSupport/Android.mk b/hostsidetests/devicepolicy/app/LauncherTestsSupport/Android.mk
index 2465ef3..9e86d13 100644
--- a/hostsidetests/devicepolicy/app/LauncherTestsSupport/Android.mk
+++ b/hostsidetests/devicepolicy/app/LauncherTestsSupport/Android.mk
@@ -28,4 +28,7 @@
 
 LOCAL_SDK_VERSION := current
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/Android.mk b/hostsidetests/devicepolicy/app/ManagedProfile/Android.mk
index b31e74b..85c74f9 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/Android.mk
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/Android.mk
@@ -26,9 +26,12 @@
 
 LOCAL_JAVA_LIBRARIES := android.test.runner cts-junit
 
-LOCAL_STATIC_JAVA_LIBRARIES = android-support-v4 ctstestrunner compatibility-device-util_v2 \
+LOCAL_STATIC_JAVA_LIBRARIES = android-support-v4 ctstestrunner compatibility-device-util \
 	ub-uiautomator
 
 LOCAL_SDK_VERSION := current
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/AndroidManifest.xml b/hostsidetests/devicepolicy/app/ManagedProfile/AndroidManifest.xml
index a36001c..6d233b7 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/AndroidManifest.xml
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/AndroidManifest.xml
@@ -25,6 +25,9 @@
     <uses-permission android:name="android.permission.READ_CONTACTS" />
     <uses-permission android:name="android.permission.WRITE_CONTACTS" />
     <uses-permission android:name="android.permission.CAMERA" />
+    <uses-permission android:name="android.permission.CALL_PHONE"/>
+    <uses-permission android:name="android.permission.READ_CALL_LOG"/>
+    <uses-permission android:name="android.permission.WRITE_CALL_LOG"/>
 
     <application>
         <uses-library android:name="android.test.runner" />
@@ -80,6 +83,23 @@
             </intent-filter>
         </activity>
         <activity android:name=".TestActivity" />
+
+        <service android:name=".DummyConnectionService"
+                 android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE" >
+            <intent-filter>
+                <action android:name="android.telecom.ConnectionService" />
+            </intent-filter>
+        </service>
+
+        <activity android:name=".DummyDialerActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.DIAL" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.BROWSABLE" />
+                <data android:mimeType="vnd.android.cursor.item/phone" />
+                <data android:mimeType="vnd.android.cursor.item/person" />
+            </intent-filter>
+        </activity>
         <service android:name=".AccountService" android:exported="true">
             <intent-filter>
                 <action android:name="android.accounts.AccountAuthenticator" />
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/res/raw/managed_photo.png b/hostsidetests/devicepolicy/app/ManagedProfile/res/raw/managed_photo.png
new file mode 100644
index 0000000..ec1b33f
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/res/raw/managed_photo.png
Binary files differ
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/res/raw/managed_thumbnail.png b/hostsidetests/devicepolicy/app/ManagedProfile/res/raw/managed_thumbnail.png
new file mode 100644
index 0000000..c903fd1
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/res/raw/managed_thumbnail.png
Binary files differ
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/res/raw/primary_photo.png b/hostsidetests/devicepolicy/app/ManagedProfile/res/raw/primary_photo.png
new file mode 100644
index 0000000..2272d47
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/res/raw/primary_photo.png
Binary files differ
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/res/raw/primary_thumbnail.png b/hostsidetests/devicepolicy/app/ManagedProfile/res/raw/primary_thumbnail.png
new file mode 100644
index 0000000..e5aa7db
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/res/raw/primary_thumbnail.png
Binary files differ
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/res/xml/device_admin.xml b/hostsidetests/devicepolicy/app/ManagedProfile/res/xml/device_admin.xml
index c3d5c98..36c767b 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/res/xml/device_admin.xml
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/res/xml/device_admin.xml
@@ -16,5 +16,7 @@
     <uses-policies>
         <wipe-data />
         <disable-camera />
+        <limit-password />
+        <disable-keyguard-features/>
     </uses-policies>
 </device-admin>
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/AccountAuthenticator.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/AccountAuthenticator.java
index 2d8a2e8..e8cc616 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/AccountAuthenticator.java
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/AccountAuthenticator.java
@@ -25,10 +25,9 @@
 import android.os.Bundle;
 
 /* package */ class AccountAuthenticator extends AbstractAccountAuthenticator {
+    private static AccountAuthenticator sAuthenticator = null;
     public static final String ACCOUNT_NAME = "CTS";
     public static final String ACCOUNT_TYPE = "com.android.cts.test";
-
-    private static AccountAuthenticator sAuthenticator = null;
     private static final String AUTH_TOKEN = "authToken";
     private static final String AUTH_TOKEN_LABEL = "authTokenLabel";
 
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/BaseManagedProfileTest.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/BaseManagedProfileTest.java
index 49754d0..45d540e 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/BaseManagedProfileTest.java
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/BaseManagedProfileTest.java
@@ -37,6 +37,7 @@
             BasicAdminReceiver.class.getPackage().getName(), BasicAdminReceiver.class.getName());
 
     protected DevicePolicyManager mDevicePolicyManager;
+    protected DevicePolicyManager mParentDevicePolicyManager;
     protected Context mContext;
 
     @Override
@@ -46,6 +47,8 @@
 
         mDevicePolicyManager = (DevicePolicyManager)
                 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
+        mParentDevicePolicyManager =
+                mDevicePolicyManager.getParentProfileInstance(ADMIN_RECEIVER_COMPONENT);
         assertNotNull(mDevicePolicyManager);
 
         // TODO: Only check the below if we are running as the profile user. If running under the
@@ -56,4 +59,8 @@
         assertTrue(mDevicePolicyManager.isProfileOwnerApp(
                 ADMIN_RECEIVER_COMPONENT.getPackageName()));
     }
+
+    protected DevicePolicyManager getDevicePolicyManager(boolean isParent) {
+        return isParent ? mParentDevicePolicyManager : mDevicePolicyManager;
+    }
 }
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/ContactsTest.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/ContactsTest.java
index f3fcdfe..5a2b3fa 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/ContactsTest.java
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/ContactsTest.java
@@ -24,16 +24,20 @@
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.OperationApplicationException;
+import android.content.res.Resources;
 import android.content.res.Resources.NotFoundException;
 import android.database.Cursor;
+import android.graphics.Rect;
 import android.net.Uri;
 import android.os.Build;
 import android.os.RemoteException;
 import android.provider.ContactsContract;
+import android.provider.ContactsContract.CommonDataKinds.Callable;
 import android.provider.ContactsContract.CommonDataKinds.Email;
 import android.provider.ContactsContract.CommonDataKinds.Phone;
 import android.provider.ContactsContract.CommonDataKinds.Photo;
-import android.provider.ContactsContract.Data;
+import android.provider.ContactsContract.Contacts;
+import android.provider.ContactsContract.Directory;
 import android.provider.ContactsContract.PhoneLookup;
 import android.provider.ContactsContract.RawContacts;
 import android.test.AndroidTestCase;
@@ -43,6 +47,7 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.ArrayList;
+import java.util.Arrays;
 
 @TargetApi(Build.VERSION_CODES.LOLLIPOP)
 public class ContactsTest extends AndroidTestCase {
@@ -68,6 +73,12 @@
     private static final String SHARED_CONTACT_EMAIL = "shared@shared.com";
     private static final String SHARED_CONTACT_SIP = "baz@sip";
 
+    // Directory display name
+    private static final String PRIMARY_DIRECTORY_NAME = "PrimaryDirectory";
+    private static final String MANAGED_DIRECTORY_NAME = "ManagedDirectory";
+    private static final String PRIMARY_DIRECTORY_CONTACT_NAME = "PrimaryDirectoryContact";
+    private static final String MANAGED_DIRECTORY_CONTACT_NAME = "ManagedDirectoryContact";
+
     private DevicePolicyManager mDevicePolicyManager;
     private ContentResolver mResolver;
 
@@ -93,13 +104,33 @@
             assertNull(photoThumbnailUri);
         }
 
-        private void assertPhotoUrisReadable() throws IOException {
+        private void assertPhotoUrisReadable() {
             assertPhotoUriReadable(photoUri);
             assertPhotoUriReadable(photoThumbnailUri);
         }
 
+        private void assertThumbnailUri(int resId) {
+            Resources resources = mContext.getResources();
+            assertNotNull(this.photoThumbnailUri);
+            byte[] actualPhotoThumbnail = getByteFromStreamForTest(
+                    getInputStreamFromUriForTest(this.photoThumbnailUri));
+            byte[] expectedPhotoThumbnail = getByteFromStreamForTest(
+                    resources.openRawResource(resId));
+            assertTrue(Arrays.equals(expectedPhotoThumbnail, actualPhotoThumbnail));
+        }
+
+        private void assertPhotoUri(int resId) {
+            Resources resources = mContext.getResources();
+            assertNotNull(this.photoUri);
+            byte[] actualPhoto = getByteFromStreamForTest(
+                    getInputStreamFromUriForTest(this.photoUri));
+            byte[] expectedPhoto = getByteFromStreamForTest(
+                    resources.openRawResource(resId));
+            assertTrue(Arrays.equals(expectedPhoto, actualPhoto));
+        }
+
         private boolean hasPhotoId() {
-            return photoId != null;
+            return photoId != null && Long.parseLong(photoId) > 0;
         }
     }
 
@@ -123,14 +154,16 @@
         insertContact(PRIMARY_CONTACT_DISPLAY_NAME, PRIMARY_CONTACT_PHONE,
                 PRIMARY_CONTACT_EMAIL, PRIMARY_CONTACT_SIP, 0);
 
-        ContactInfo contactInfo = getContactInfo(PRIMARY_CONTACT_PHONE);
+        ContactInfo contactInfo = getContactInfoFromPhoneLookupUri(false /*isEnterprise*/,
+                PRIMARY_CONTACT_PHONE);
         assertNotNull(contactInfo);
         assertEquals(PRIMARY_CONTACT_DISPLAY_NAME, contactInfo.displayName);
         contactInfo.assertNoPhotoUri();
         assertFalse(contactInfo.hasPhotoId());
         assertFalse(isEnterpriseContactId(contactInfo.contactId));
 
-        contactInfo = getContactInfoFromEmail(PRIMARY_CONTACT_EMAIL);
+        contactInfo = getContactInfoFromEmailLookupUri(false /*isEnterprise*/,
+                PRIMARY_CONTACT_EMAIL);
         assertNotNull(contactInfo);
         assertEquals(PRIMARY_CONTACT_DISPLAY_NAME, contactInfo.displayName);
         contactInfo.assertNoPhotoUri();
@@ -149,14 +182,16 @@
                 MANAGED_CONTACT_SIP,
                 com.android.cts.managedprofile.R.raw.ic_contact_picture);
 
-        ContactInfo contactInfo = getContactInfo(MANAGED_CONTACT_PHONE);
+        ContactInfo contactInfo = getContactInfoFromPhoneLookupUri(false /*isEnterprise*/,
+                MANAGED_CONTACT_PHONE);
         assertNotNull(contactInfo);
         assertEquals(MANAGED_CONTACT_DISPLAY_NAME, contactInfo.displayName);
         contactInfo.assertPhotoUrisReadable();
         assertTrue(contactInfo.hasPhotoId());
         assertFalse(isEnterpriseContactId(contactInfo.contactId));
 
-        contactInfo = getContactInfoFromEmail(MANAGED_CONTACT_EMAIL);
+        contactInfo = getContactInfoFromEmailLookupUri(false /*isEnterprise*/,
+                MANAGED_CONTACT_EMAIL);
         assertNotNull(contactInfo);
         assertEquals(MANAGED_CONTACT_DISPLAY_NAME, contactInfo.displayName);
         contactInfo.assertPhotoUrisReadable();
@@ -173,14 +208,15 @@
                 SHARED_CONTACT_SIP,
                 com.android.cts.managedprofile.R.raw.ic_contact_picture);
 
-        ContactInfo contactInfo = getContactInfo(SHARED_CONTACT_PHONE);
+        ContactInfo contactInfo = getContactInfoFromPhoneLookupUri(false /*isEnterprise*/,
+                SHARED_CONTACT_PHONE);
         assertNotNull(contactInfo);
         assertEquals(PRIMARY_CONTACT_DISPLAY_NAME_2, contactInfo.displayName);
         contactInfo.assertPhotoUrisReadable();
         assertTrue(contactInfo.hasPhotoId());
         assertFalse(isEnterpriseContactId(contactInfo.contactId));
 
-        contactInfo = getContactInfoFromEmail(SHARED_CONTACT_EMAIL);
+        contactInfo = getContactInfoFromEmailLookupUri(false /*isEnterprise*/, SHARED_CONTACT_EMAIL);
         assertNotNull(contactInfo);
         assertEquals(PRIMARY_CONTACT_DISPLAY_NAME_2, contactInfo.displayName);
         contactInfo.assertPhotoUrisReadable();
@@ -194,14 +230,15 @@
         insertContact(MANAGED_CONTACT_DISPLAY_NAME_2, SHARED_CONTACT_PHONE,
                 SHARED_CONTACT_EMAIL, SHARED_CONTACT_SIP , 0);
 
-        ContactInfo contactInfo = getContactInfo(SHARED_CONTACT_PHONE);
+        ContactInfo contactInfo = getContactInfoFromPhoneLookupUri(false /*isEnterprise*/,
+                SHARED_CONTACT_PHONE);
         assertNotNull(contactInfo);
         assertEquals(MANAGED_CONTACT_DISPLAY_NAME_2, contactInfo.displayName);
         contactInfo.assertNoPhotoUri();
         assertFalse(contactInfo.hasPhotoId());
         assertFalse(isEnterpriseContactId(contactInfo.contactId));
 
-        contactInfo = getContactInfoFromEmail(SHARED_CONTACT_EMAIL);
+        contactInfo = getContactInfoFromEmailLookupUri(false /*isEnterprise*/, SHARED_CONTACT_EMAIL);
         assertNotNull(contactInfo);
         assertEquals(MANAGED_CONTACT_DISPLAY_NAME_2, contactInfo.displayName);
         contactInfo.assertNoPhotoUri();
@@ -212,8 +249,9 @@
     public void testPrimaryProfileEnterprisePhoneLookup_canAccessEnterpriseContact()
             throws IOException {
         assertFalse(isManagedProfile());
-        ContactInfo contactInfo = getEnterpriseContactInfo(MANAGED_CONTACT_PHONE);
-        assertEquals(MANAGED_CONTACT_DISPLAY_NAME, contactInfo.displayName);
+        ContactInfo contactInfo = getContactInfoFromPhoneLookupUri(true /*isEnterprise*/,
+                MANAGED_CONTACT_PHONE);
+        assertManagedLocalContact(contactInfo);
         contactInfo.assertPhotoUrisReadable();
         // Cannot get photo id in ENTERPRISE_CONTENT_FILTER_URI
         assertFalse(contactInfo.hasPhotoId());
@@ -223,20 +261,20 @@
     public void testPrimaryProfileEnterpriseSipLookup_canAccessEnterpriseContact()
             throws IOException {
         assertFalse(isManagedProfile());
-        ContactInfo contactInfo = getEnterpriseContactInfoFromSipAddress(MANAGED_CONTACT_SIP);
-        assertEquals(MANAGED_CONTACT_DISPLAY_NAME, contactInfo.displayName);
+        ContactInfo contactInfo = getContactInfoFromEnterprisePhoneLookupUriWithSipAddress(
+                true /*isEnterprise*/, MANAGED_CONTACT_SIP);
+        assertManagedLocalContact(contactInfo);
         contactInfo.assertPhotoUrisReadable();
         assertFalse(contactInfo.hasPhotoId());
-
-        // Quirk: the _id column from the SIP lookup is actually of the data id, not the contact id.
-        // assertTrue(isEnterpriseContactId(contactInfo.contactId));
+        assertTrue(isEnterpriseContactId(contactInfo.contactId));
     }
 
     public void testPrimaryProfileEnterpriseEmailLookup_canAccessEnterpriseContact()
             throws IOException {
         assertFalse(isManagedProfile());
-        ContactInfo contactInfo = getEnterpriseContactInfoFromEmail(MANAGED_CONTACT_EMAIL);
-        assertEquals(MANAGED_CONTACT_DISPLAY_NAME, contactInfo.displayName);
+        ContactInfo contactInfo = getContactInfoFromEmailLookupUri(true /*isEnterprise*/,
+                MANAGED_CONTACT_EMAIL);
+        assertManagedLocalContact(contactInfo);
         contactInfo.assertPhotoUrisReadable();
         // Cannot get photo id in ENTERPRISE_CONTENT_FILTER_URI
         assertFalse(contactInfo.hasPhotoId());
@@ -246,7 +284,8 @@
     public void testPrimaryProfileEnterprisePhoneLookupDuplicated_canAccessPrimaryContact()
             throws IOException {
         assertFalse(isManagedProfile());
-        ContactInfo contactInfo = getEnterpriseContactInfo(SHARED_CONTACT_PHONE);
+        ContactInfo contactInfo = getContactInfoFromPhoneLookupUri(true /*isEnterprise*/,
+                SHARED_CONTACT_PHONE);
         assertEquals(PRIMARY_CONTACT_DISPLAY_NAME_2, contactInfo.displayName);
         contactInfo.assertPhotoUrisReadable();
         assertTrue(contactInfo.hasPhotoId());
@@ -256,7 +295,8 @@
     public void testPrimaryProfileEnterpriseEmailLookupDuplicated_canAccessPrimaryContact()
             throws IOException {
         assertFalse(isManagedProfile());
-        ContactInfo contactInfo = getEnterpriseContactInfoFromEmail(SHARED_CONTACT_EMAIL);
+        ContactInfo contactInfo = getContactInfoFromEmailLookupUri(true /*isEnterprise*/,
+                SHARED_CONTACT_EMAIL);
         assertEquals(PRIMARY_CONTACT_DISPLAY_NAME_2, contactInfo.displayName);
         contactInfo.assertPhotoUrisReadable();
         assertTrue(contactInfo.hasPhotoId());
@@ -265,7 +305,8 @@
 
     public void testManagedProfileEnterprisePhoneLookupDuplicated_canAccessEnterpriseContact() {
         assertTrue(isManagedProfile());
-        ContactInfo contactInfo = getEnterpriseContactInfo(SHARED_CONTACT_PHONE);
+        ContactInfo contactInfo = getContactInfoFromPhoneLookupUri(true /*isEnterprise*/,
+                SHARED_CONTACT_PHONE);
         assertEquals(MANAGED_CONTACT_DISPLAY_NAME_2, contactInfo.displayName);
         contactInfo.assertNoPhotoUri();
         assertFalse(contactInfo.hasPhotoId());
@@ -274,7 +315,8 @@
 
     public void testManagedProfileEnterpriseEmailLookupDuplicated_canAccessEnterpriseContact() {
         assertTrue(isManagedProfile());
-        ContactInfo contactInfo = getEnterpriseContactInfoFromEmail(SHARED_CONTACT_EMAIL);
+        ContactInfo contactInfo = getContactInfoFromEmailLookupUri(true /*isEnterprise*/,
+                SHARED_CONTACT_EMAIL);
         assertEquals(MANAGED_CONTACT_DISPLAY_NAME_2, contactInfo.displayName);
         contactInfo.assertNoPhotoUri();
         assertFalse(contactInfo.hasPhotoId());
@@ -283,19 +325,22 @@
 
     public void testPrimaryProfilePhoneLookup_canNotAccessEnterpriseContact() {
         assertFalse(isManagedProfile());
-        ContactInfo contactInfo = getContactInfo(MANAGED_CONTACT_PHONE);
+        ContactInfo contactInfo = getContactInfoFromPhoneLookupUri(false /*isEnterprise*/,
+                MANAGED_CONTACT_PHONE);
         assertNull(contactInfo);
     }
 
     public void testPrimaryProfileEmailLookup_canNotAccessEnterpriseContact() {
         assertFalse(isManagedProfile());
-        ContactInfo contactInfo = getContactInfoFromEmail(MANAGED_CONTACT_EMAIL);
+        ContactInfo contactInfo = getContactInfoFromEmailLookupUri(false /*isEnterprise*/,
+                MANAGED_CONTACT_EMAIL);
         assertNull(contactInfo);
     }
 
     public void testPrimaryProfileEnterprisePhoneLookup_canAccessPrimaryContact() {
         assertFalse(isManagedProfile());
-        ContactInfo contactInfo = getEnterpriseContactInfo(PRIMARY_CONTACT_PHONE);
+        ContactInfo contactInfo = getContactInfoFromPhoneLookupUri(true /*isEnterprise*/,
+                PRIMARY_CONTACT_PHONE);
         assertEquals(PRIMARY_CONTACT_DISPLAY_NAME, contactInfo.displayName);
         contactInfo.assertNoPhotoUri();
         assertFalse(contactInfo.hasPhotoId());
@@ -304,28 +349,29 @@
 
     public void testPrimaryProfileEnterpriseEmailLookup_canAccessPrimaryContact() {
         assertFalse(isManagedProfile());
-        ContactInfo contactInfo = getEnterpriseContactInfoFromEmail(PRIMARY_CONTACT_EMAIL);
+        ContactInfo contactInfo = getContactInfoFromEmailLookupUri(true /*isEnterprise*/,
+                PRIMARY_CONTACT_EMAIL);
         assertEquals(PRIMARY_CONTACT_DISPLAY_NAME, contactInfo.displayName);
         contactInfo.assertNoPhotoUri();
         assertFalse(contactInfo.hasPhotoId());
         assertFalse(isEnterpriseContactId(contactInfo.contactId));
     }
 
-    public void testManagedProfileEnterprisePhoneLookup_canAccessEnterpriseContact()
-            throws IOException {
+    public void testManagedProfileEnterprisePhoneLookup_canAccessEnterpriseContact() {
         assertTrue(isManagedProfile());
-        ContactInfo contactInfo = getEnterpriseContactInfo(MANAGED_CONTACT_PHONE);
-        assertEquals(MANAGED_CONTACT_DISPLAY_NAME, contactInfo.displayName);
+        ContactInfo contactInfo = getContactInfoFromPhoneLookupUri(true /*isEnterprise*/,
+                MANAGED_CONTACT_PHONE);
+        assertManagedLocalContact(contactInfo);
         contactInfo.assertPhotoUrisReadable();
         assertTrue(contactInfo.hasPhotoId());
         assertFalse(isEnterpriseContactId(contactInfo.contactId));
     }
 
-    public void testManagedProfileEnterpriseEmailLookup_canAccessEnterpriseContact()
-            throws IOException {
+    public void testManagedProfileEnterpriseEmailLookup_canAccessEnterpriseContact() {
         assertTrue(isManagedProfile());
-        ContactInfo contactInfo = getEnterpriseContactInfoFromEmail(MANAGED_CONTACT_EMAIL);
-        assertEquals(MANAGED_CONTACT_DISPLAY_NAME, contactInfo.displayName);
+        ContactInfo contactInfo = getContactInfoFromEmailLookupUri(true /*isEnterprise*/,
+                MANAGED_CONTACT_EMAIL);
+        assertManagedLocalContact(contactInfo);
         contactInfo.assertPhotoUrisReadable();
         assertTrue(contactInfo.hasPhotoId());
         assertFalse(isEnterpriseContactId(contactInfo.contactId));
@@ -333,40 +379,84 @@
 
     public void testManagedProfileEnterprisePhoneLookup_canNotAccessPrimaryContact() {
         assertTrue(isManagedProfile());
-        ContactInfo contactInfo = getEnterpriseContactInfo(PRIMARY_CONTACT_PHONE);
+        ContactInfo contactInfo = getContactInfoFromPhoneLookupUri(true /*isEnterprise*/,
+                PRIMARY_CONTACT_PHONE);
         assertNull(contactInfo);
     }
 
     public void testManagedProfileEnterpriseEmailLookup_canNotAccessPrimaryContact() {
         assertTrue(isManagedProfile());
-        ContactInfo contactInfo = getEnterpriseContactInfoFromEmail(PRIMARY_CONTACT_EMAIL);
+        ContactInfo contactInfo = getContactInfoFromEmailLookupUri(true /*isEnterprise*/,
+                PRIMARY_CONTACT_EMAIL);
         assertNull(contactInfo);
     }
 
     public void testManagedProfilePhoneLookup_canNotAccessPrimaryContact() {
         assertTrue(isManagedProfile());
-        ContactInfo contactInfo = getContactInfo(PRIMARY_CONTACT_PHONE);
+        ContactInfo contactInfo = getContactInfoFromPhoneLookupUri(false /*isEnterprise*/,
+                PRIMARY_CONTACT_PHONE);
         assertNull(contactInfo);
     }
 
     public void testManagedProfileEmailLookup_canNotAccessPrimaryContact() {
         assertTrue(isManagedProfile());
-        ContactInfo contactInfo = getContactInfoFromEmail(PRIMARY_CONTACT_EMAIL);
+        ContactInfo contactInfo = getContactInfoFromEmailLookupUri(false /*isEnterprise */,
+                PRIMARY_CONTACT_EMAIL);
         assertNull(contactInfo);
     }
 
     public void testPrimaryProfileEnterpriseEmailLookup_canNotAccessEnterpriseContact() {
         assertFalse(isManagedProfile());
-        ContactInfo contactInfo = getEnterpriseContactInfoFromEmail(MANAGED_CONTACT_EMAIL);
+        ContactInfo contactInfo = getContactInfoFromEmailLookupUri(true /*isEnterprise*/,
+                MANAGED_CONTACT_EMAIL);
         assertNull(contactInfo);
     }
 
     public void testPrimaryProfileEnterprisePhoneLookup_canNotAccessEnterpriseContact() {
         assertFalse(isManagedProfile());
-        ContactInfo contactInfo = getEnterpriseContactInfo(MANAGED_CONTACT_PHONE);
+        ContactInfo contactInfo = getContactInfoFromPhoneLookupUri(true /*isEnterprise*/,
+                MANAGED_CONTACT_PHONE);
         assertNull(contactInfo);
     }
 
+    public void testPrimaryProfileEnterprisePhoneLookup_canNotAccessManagedDirectories() {
+        assertFalse(isManagedProfile());
+
+        // local directory
+        final ContactInfo defaultContactInfo =
+                getContactInfoFromEnterprisePhoneLookupUriInDirectory(MANAGED_CONTACT_PHONE,
+                        Directory.ENTERPRISE_DEFAULT);
+        assertNull(defaultContactInfo);
+
+        // remote directory
+        final long directoryId = getEnterpriseRemoteDirectoryIdSliently();
+        if (directoryId != 0) { // if directoryId == 0, it means it can't access managed directory
+            final ContactInfo directoryContactInfo =
+                    getContactInfoFromEnterprisePhoneLookupUriInDirectory(MANAGED_CONTACT_PHONE,
+                            directoryId);
+            assertNull(directoryContactInfo);
+        }
+    }
+
+    public void testPrimaryProfileEnterpriseEmailLookup_canNotAccessManagedDirectories() {
+        assertFalse(isManagedProfile());
+
+        // local directory
+        final ContactInfo defaultContactInfo =
+                getContactInfoFromEnterpriseEmailLookupUriInDirectory(MANAGED_CONTACT_EMAIL,
+                        Directory.ENTERPRISE_DEFAULT);
+        assertNull(defaultContactInfo);
+
+        // remote directory
+        final long directoryId = getEnterpriseRemoteDirectoryIdSliently();
+        if (directoryId != 0) { // if directoryId == 0, it means it can't access managed directory
+            final ContactInfo directoryContactInfo =
+                    getContactInfoFromEnterpriseEmailLookupUriInDirectory(MANAGED_CONTACT_EMAIL,
+                            directoryId);
+            assertNull(directoryContactInfo);
+        }
+    }
+
     public void testSetCrossProfileCallerIdDisabled_true() {
         assertTrue(isManagedProfile());
         mDevicePolicyManager.setCrossProfileCallerIdDisabled(
@@ -379,6 +469,22 @@
                 BaseManagedProfileTest.ADMIN_RECEIVER_COMPONENT, false);
     }
 
+    public void testSetCrossProfileContactsSearchDisabled_true() {
+        assertTrue(isManagedProfile());
+        mDevicePolicyManager.setCrossProfileContactsSearchDisabled(
+                BaseManagedProfileTest.ADMIN_RECEIVER_COMPONENT, true);
+        assertTrue(mDevicePolicyManager.getCrossProfileContactsSearchDisabled(
+                BaseManagedProfileTest.ADMIN_RECEIVER_COMPONENT));
+    }
+
+    public void testSetCrossProfileContactsSearchDisabled_false() {
+        assertTrue(isManagedProfile());
+        mDevicePolicyManager.setCrossProfileContactsSearchDisabled(
+                BaseManagedProfileTest.ADMIN_RECEIVER_COMPONENT, false);
+        assertFalse(mDevicePolicyManager.getCrossProfileContactsSearchDisabled(
+                BaseManagedProfileTest.ADMIN_RECEIVER_COMPONENT));
+    }
+
     public void testCurrentProfileContacts_removeContacts() {
         removeAllTestContactsInProfile();
     }
@@ -394,6 +500,499 @@
                 BaseManagedProfileTest.ADMIN_RECEIVER_COMPONENT));
     }
 
+    public void testGetDirectoryListInPrimaryProfile() {
+        assertFalse(isManagedProfile());
+        final Cursor cursor = mResolver.query(Directory.ENTERPRISE_CONTENT_URI,
+                new String[]{
+                        Directory._ID,
+                        Directory.DISPLAY_NAME
+                }, null, null, null);
+
+        boolean hasPrimaryDefault = false;
+        boolean hasPrimaryInvisible = false;
+        boolean hasManagedDefault = false;
+        boolean hasManagedInvisible = false;
+        boolean hasPrimaryDirectory = false;
+        boolean hasManagedDirectory = false;
+
+        while(cursor.moveToNext()) {
+            final long directoryId = cursor.getLong(0);
+            if (directoryId == Directory.DEFAULT) {
+                hasPrimaryDefault = true;
+            } else if (directoryId == Directory.LOCAL_INVISIBLE) {
+                hasPrimaryInvisible = true;
+            } else if (directoryId == Directory.ENTERPRISE_DEFAULT) {
+                hasManagedDefault = true;
+            } else if (directoryId == Directory.ENTERPRISE_LOCAL_INVISIBLE) {
+                hasManagedInvisible = true;
+            } else {
+                final String displayName = cursor.getString(1);
+                if (Directory.isEnterpriseDirectoryId(directoryId)
+                        && displayName.equals(MANAGED_DIRECTORY_NAME)) {
+                    hasManagedDirectory = true;
+                }
+                if (!Directory.isEnterpriseDirectoryId(directoryId)
+                        && displayName.equals(PRIMARY_DIRECTORY_NAME)) {
+                    hasPrimaryDirectory = true;
+                }
+            }
+        }
+        cursor.close();
+        assertTrue(hasPrimaryDefault);
+        assertTrue(hasPrimaryInvisible);
+        assertTrue(hasManagedDefault);
+        assertTrue(hasManagedInvisible);
+        assertTrue(hasPrimaryDirectory);
+        assertTrue(hasManagedDirectory);
+    }
+
+    public void testPrimaryProfileEnterpriseEmailLookup_canAccessPrimaryDirectories() {
+        assertFalse(isManagedProfile());
+
+        // local directory
+        final ContactInfo defaultContactInfo
+                = getContactInfoFromEnterpriseEmailLookupUriInDirectory(PRIMARY_CONTACT_EMAIL,
+                Directory.DEFAULT);
+        assertPrimaryLocalContact(defaultContactInfo);
+
+        // remote directory
+        final long directoryId = getPrimaryRemoteDirectoryId();
+        final ContactInfo directoryContactInfo
+                = getContactInfoFromEnterpriseEmailLookupUriInDirectory(PRIMARY_CONTACT_EMAIL,
+                directoryId);
+        assertPrimaryDirectoryContact(directoryContactInfo);
+    }
+
+    public void testPrimaryProfileEnterpriseEmailLookup_canAccessManagedDirectories() {
+        assertFalse(isManagedProfile());
+
+        // local directory
+        final ContactInfo defaultContactInfo
+                = getContactInfoFromEnterpriseEmailLookupUriInDirectory(MANAGED_CONTACT_EMAIL,
+                Directory.ENTERPRISE_DEFAULT);
+        assertManagedLocalContact(defaultContactInfo);
+
+        // remote directory
+        final long directoryId = getEnterpriseRemoteDirectoryId();
+        final ContactInfo directoryContactInfo
+                = getContactInfoFromEnterpriseEmailLookupUriInDirectory(MANAGED_CONTACT_EMAIL,
+                directoryId);
+        assertManagedDirectoryContact(directoryContactInfo);
+    }
+
+    public void testPrimaryProfileEnterprisePhoneLookup_canAccessPrimaryDirectories() {
+        assertFalse(isManagedProfile());
+
+        // local directory
+        final ContactInfo defaultContactInfo
+                = getContactInfoFromEnterprisePhoneLookupUriInDirectory(PRIMARY_CONTACT_PHONE,
+                Directory.DEFAULT);
+        assertPrimaryLocalContact(defaultContactInfo);
+
+        // remote directory
+        final long directoryId = getPrimaryRemoteDirectoryId();
+        final ContactInfo directoryContactInfo
+                = getContactInfoFromEnterprisePhoneLookupUriInDirectory(PRIMARY_CONTACT_PHONE,
+                directoryId);
+        assertPrimaryDirectoryContact(directoryContactInfo);
+    }
+
+    public void testPrimaryProfileEnterprisePhoneLookup_canAccessManagedDirectories() {
+        assertFalse(isManagedProfile());
+
+        // local directory
+        final ContactInfo defaultContactInfo
+                = getContactInfoFromEnterprisePhoneLookupUriInDirectory(MANAGED_CONTACT_PHONE,
+                Directory.ENTERPRISE_DEFAULT);
+        assertManagedLocalContact(defaultContactInfo);
+
+        // remote directory
+        final long directoryId = getEnterpriseRemoteDirectoryId();
+        final ContactInfo directoryContactInfo
+                = getContactInfoFromEnterprisePhoneLookupUriInDirectory(MANAGED_CONTACT_PHONE,
+                directoryId);
+        assertManagedDirectoryContact(directoryContactInfo);
+    }
+
+    public void testPrimaryProfileEnterpriseCallableFilter_canAccessPrimaryDirectories() {
+        assertFalse(isManagedProfile());
+        final ContactInfo defaultContactInfo
+                = getContactInfoFromEnterpriseCallableFilterUriInDirectory(
+                        PRIMARY_CONTACT_PHONE, Directory.DEFAULT);
+        assertPrimaryLocalContact(defaultContactInfo);
+
+        final ContactInfo directoryContactInfo
+                = getContactInfoFromEnterpriseCallableFilterUriInDirectory(
+                        PRIMARY_CONTACT_PHONE, getPrimaryRemoteDirectoryId());
+        assertPrimaryDirectoryContact(directoryContactInfo);
+
+    }
+
+    public void testManagedProfileEnterpriseCallableFilter_canAccessManagedDirectories() {
+        assertTrue(isManagedProfile());
+        final ContactInfo defaultContactInfo
+                = getContactInfoFromEnterpriseCallableFilterUriInDirectory(
+                        MANAGED_CONTACT_PHONE, Directory.DEFAULT);
+        assertManagedLocalContact(defaultContactInfo);
+
+        final ContactInfo directoryContactInfo
+                = getContactInfoFromEnterpriseCallableFilterUriInDirectory(
+                        MANAGED_CONTACT_PHONE, getEnterpriseRemoteDirectoryIdInManagedProfile());
+        assertManagedDirectoryContact(directoryContactInfo);
+    }
+
+    public void testPrimaryProfileEnterpriseCallableFilter_canAccessManagedDirectories() {
+        assertFalse(isManagedProfile());
+
+        // local directory
+        final ContactInfo defaultContactInfo
+                = getContactInfoFromEnterpriseCallableFilterUriInDirectory(
+                        MANAGED_CONTACT_PHONE, Directory.ENTERPRISE_DEFAULT);
+        assertManagedLocalContact(defaultContactInfo);
+
+        // remote directory
+        final long directoryId = getEnterpriseRemoteDirectoryId();
+        final ContactInfo directoryContactInfo
+                = getContactInfoFromEnterpriseCallableFilterUriInDirectory(
+                        MANAGED_CONTACT_PHONE, directoryId);
+        assertManagedDirectoryContact(directoryContactInfo);
+    }
+
+    public void testPrimaryProfileEnterpriseCallableFilter_canNotAccessManagedDirectories() {
+        assertFalse(isManagedProfile());
+
+        // local directory
+        final ContactInfo defaultContactInfo
+                = getContactInfoFromEnterpriseCallableFilterUriInDirectory(
+                MANAGED_CONTACT_PHONE, Directory.ENTERPRISE_DEFAULT);
+        assertNull(defaultContactInfo);
+
+        // remote directory
+        final long directoryId = getEnterpriseRemoteDirectoryIdSliently();
+        if (directoryId == 0L) {
+            // if no enterprise directory id is found, the test succeeds.
+            return;
+        } else {
+            final ContactInfo directoryContactInfo =
+                    getContactInfoFromEnterpriseCallableFilterUriInDirectory(MANAGED_CONTACT_PHONE,
+                            directoryId);
+            assertNull(directoryContactInfo);
+        }
+    }
+
+    public void testPrimaryProfileEnterpriseEmailFilter_canAccessPrimaryDirectories() {
+        assertFalse(isManagedProfile());
+        final ContactInfo defaultContactInfo
+                = getContactInfoFromEnterpriseEmailFilterUriInDirectory(
+                        PRIMARY_CONTACT_EMAIL, Directory.DEFAULT);
+        assertPrimaryLocalContact(defaultContactInfo);
+
+        final ContactInfo directoryContactInfo
+                = getContactInfoFromEnterpriseEmailFilterUriInDirectory(
+                        PRIMARY_CONTACT_EMAIL, getPrimaryRemoteDirectoryId());
+        assertPrimaryDirectoryContact(directoryContactInfo);
+    }
+
+    public void testEnterpriseProfileEnterpriseEmailFilter_canAccessManagedDirectories() {
+        assertTrue(isManagedProfile());
+        final ContactInfo defaultContactInfo
+                = getContactInfoFromEnterpriseEmailFilterUriInDirectory(
+                        MANAGED_CONTACT_EMAIL, Directory.DEFAULT);
+        assertManagedLocalContact(defaultContactInfo);
+
+        final ContactInfo directoryContactInfo
+                = getContactInfoFromEnterpriseEmailFilterUriInDirectory(
+                        MANAGED_CONTACT_EMAIL, getEnterpriseRemoteDirectoryIdInManagedProfile());
+        assertManagedDirectoryContact(directoryContactInfo);
+    }
+
+    public void testPrimaryProfileEnterpriseEmailFilter_canAccessManagedDirectories() {
+        assertFalse(isManagedProfile());
+
+        // local directory
+        final ContactInfo defaultContactInfo
+                = getContactInfoFromEnterpriseEmailFilterUriInDirectory(
+                MANAGED_CONTACT_EMAIL, Directory.ENTERPRISE_DEFAULT);
+        assertManagedLocalContact(defaultContactInfo);
+
+        // remote directory
+        final long directoryId = getEnterpriseRemoteDirectoryId();
+        final ContactInfo directoryContactInfo
+                = getContactInfoFromEnterpriseEmailFilterUriInDirectory(
+                MANAGED_CONTACT_EMAIL, directoryId);
+        assertManagedDirectoryContact(directoryContactInfo);
+    }
+
+    public void testPrimaryProfileEnterpriseEmailFilter_canNotAccessManagedDirectories() {
+        assertFalse(isManagedProfile());
+
+        // local directory
+        final ContactInfo defaultContactInfo =
+                getContactInfoFromEnterpriseEmailFilterUriInDirectory(MANAGED_CONTACT_EMAIL,
+                        Directory.ENTERPRISE_DEFAULT);
+        assertNull(defaultContactInfo);
+
+        // remote directory
+        final long directoryId = getEnterpriseRemoteDirectoryIdSliently();
+        if (directoryId == 0L) {
+            // if no enterprise directory id is found, the test succeeds.
+            return;
+        } else {
+            final ContactInfo directoryContactInfo =
+                    getContactInfoFromEnterpriseEmailFilterUriInDirectory(MANAGED_CONTACT_EMAIL,
+                            directoryId);
+            assertNull(directoryContactInfo);
+        }
+    }
+
+    public void testPrimaryProfileEnterpriseContactFilter_canAccessPrimaryDirectories() {
+        assertFalse(isManagedProfile());
+        final ContactInfo defaultContactInfo
+                = getContactInfoFromEnterpriseContactFilterUriInDirectory(
+                        PRIMARY_CONTACT_DISPLAY_NAME, Directory.DEFAULT);
+        assertPrimaryLocalContact(defaultContactInfo);
+
+        final ContactInfo directoryContactInfo
+                = getContactInfoFromEnterpriseContactFilterUriInDirectory(
+                        PRIMARY_DIRECTORY_CONTACT_NAME, getPrimaryRemoteDirectoryId());
+        assertPrimaryDirectoryContact(directoryContactInfo);
+    }
+
+    public void testManagedProfileEnterpriseContactFilter_canAccessManagedDirectories() {
+        assertTrue(isManagedProfile());
+        final ContactInfo defaultContactInfo
+                = getContactInfoFromEnterpriseContactFilterUriInDirectory(
+                        MANAGED_CONTACT_DISPLAY_NAME, Directory.DEFAULT);
+        assertManagedLocalContact(defaultContactInfo);
+
+        final ContactInfo directoryContactInfo
+                = getContactInfoFromEnterpriseContactFilterUriInDirectory(
+                        MANAGED_DIRECTORY_CONTACT_NAME, getEnterpriseRemoteDirectoryIdInManagedProfile());
+        assertManagedDirectoryContact(directoryContactInfo);
+    }
+
+    public void testPrimaryProfileEnterpriseContactFilter_canAccessManagedDirectories() {
+        assertFalse(isManagedProfile());
+
+        // local directory
+        final ContactInfo defaultContactInfo
+                = getContactInfoFromEnterpriseContactFilterUriInDirectory(
+                        MANAGED_CONTACT_DISPLAY_NAME, Directory.ENTERPRISE_DEFAULT);
+        assertManagedLocalContact(defaultContactInfo);
+
+        // remote directory
+        final long directoryId = getEnterpriseRemoteDirectoryId();
+        final ContactInfo directoryContactInfo
+                = getContactInfoFromEnterpriseEmailFilterUriInDirectory(
+                        MANAGED_CONTACT_DISPLAY_NAME, directoryId);
+        assertManagedDirectoryContact(directoryContactInfo);
+    }
+
+    public void testPrimaryProfileEnterpriseContactFilter_canNotAccessManagedDirectories() {
+        assertFalse(isManagedProfile());
+
+        // local directory
+        final ContactInfo defaultContactInfo
+                = getContactInfoFromEnterpriseContactFilterUriInDirectory(
+                        MANAGED_CONTACT_DISPLAY_NAME, Directory.ENTERPRISE_DEFAULT);
+        assertNull(defaultContactInfo);
+
+        // remote directory
+        final long directoryId = getEnterpriseRemoteDirectoryIdSliently();
+        if (directoryId == 0L) {
+            // if no enterprise directory id is found, the test succeeds.
+            return;
+        } else {
+            final ContactInfo directoryContactInfo =
+                    getContactInfoFromEnterpriseEmailFilterUriInDirectory(
+                            MANAGED_CONTACT_DISPLAY_NAME, directoryId);
+            assertNull(directoryContactInfo);
+        }
+    }
+
+    public void testPrimaryProfileEnterprisePhoneFilter_canAccessPrimaryDirectories() {
+        assertFalse(isManagedProfile());
+        final ContactInfo defaultContactInfo
+                = getContactInfoFromEnterprisePhoneFilterUriInDirectory(
+                        PRIMARY_CONTACT_PHONE, Directory.DEFAULT);
+        assertPrimaryLocalContact(defaultContactInfo);
+
+        final ContactInfo directoryContactInfo
+                = getContactInfoFromEnterprisePhoneFilterUriInDirectory(
+                        PRIMARY_CONTACT_PHONE, getPrimaryRemoteDirectoryId());
+        assertPrimaryDirectoryContact(directoryContactInfo);
+    }
+
+    public void testManagedProfileEnterprisePhoneFilter_canAccessManagedDirectories() {
+        assertTrue(isManagedProfile());
+        final ContactInfo defaultContactInfo
+                = getContactInfoFromEnterprisePhoneFilterUriInDirectory(
+                        MANAGED_CONTACT_PHONE, Directory.DEFAULT);
+        assertManagedLocalContact(defaultContactInfo);
+
+        final ContactInfo directoryContactInfo
+                = getContactInfoFromEnterprisePhoneFilterUriInDirectory(
+                        MANAGED_CONTACT_PHONE, getEnterpriseRemoteDirectoryIdInManagedProfile());
+        assertManagedDirectoryContact(directoryContactInfo);
+    }
+
+    public void testPrimaryProfileEnterprisePhoneFilter_canAccessManagedDirectories() {
+        assertFalse(isManagedProfile());
+
+        // local directory
+        final ContactInfo defaultContactInfo
+                = getContactInfoFromEnterprisePhoneFilterUriInDirectory(
+                MANAGED_CONTACT_PHONE, Directory.ENTERPRISE_DEFAULT);
+        assertManagedLocalContact(defaultContactInfo);
+
+        // remote directory
+        final long directoryId = getEnterpriseRemoteDirectoryId();
+        final ContactInfo directoryContactInfo
+                = getContactInfoFromEnterprisePhoneFilterUriInDirectory(
+                MANAGED_CONTACT_PHONE, directoryId);
+        assertManagedDirectoryContact(directoryContactInfo);
+    }
+
+    public void testPrimaryProfileEnterprisePhoneFilter_canNotAccessManagedDirectories() {
+        assertFalse(isManagedProfile());
+
+        // local directory
+        final ContactInfo defaultContactInfo
+                = getContactInfoFromEnterprisePhoneFilterUriInDirectory(
+                MANAGED_CONTACT_PHONE, Directory.ENTERPRISE_DEFAULT);
+        assertNull(defaultContactInfo);
+
+        // remote directory
+        final long directoryId = getEnterpriseRemoteDirectoryIdSliently();
+        if (directoryId == 0L) {
+            // if no enterprise directory id is found, the test succeeds.
+            return;
+        } else {
+            final ContactInfo directoryContactInfo =
+                    getContactInfoFromEnterprisePhoneFilterUriInDirectory(
+                            MANAGED_CONTACT_PHONE, directoryId);
+            assertNull(directoryContactInfo);
+        }
+    }
+
+    public void testPrimaryProfileEnterpriseDirectories_canNotAccessManagedDirectories() {
+        assertFalse(isManagedProfile());
+
+        final Cursor cursor = mResolver.query(Directory.ENTERPRISE_CONTENT_URI,
+                new String[]{Directory._ID}, null, null, null);
+        try {
+            while (cursor.moveToNext()) {
+                final long directoryId = cursor.getLong(0);
+                if (Directory.isEnterpriseDirectoryId(directoryId)) {
+                    fail("found enterprise directories");
+                }
+            }
+        } finally {
+            cursor.close();
+        }
+    }
+
+
+    public void testFilterUriWhenDirectoryParamMissing() {
+        assertFailWhenDirectoryParamMissing(Phone.ENTERPRISE_CONTENT_FILTER_URI);
+        assertFailWhenDirectoryParamMissing(Email.ENTERPRISE_CONTENT_FILTER_URI);
+        assertFailWhenDirectoryParamMissing(Contacts.ENTERPRISE_CONTENT_FILTER_URI);
+        assertFailWhenDirectoryParamMissing(Callable.ENTERPRISE_CONTENT_FILTER_URI);
+    }
+
+    public void testQuickContact() throws Exception {
+        showQuickContactInternal(null);
+        showQuickContactInternal(Directory.ENTERPRISE_DEFAULT);
+        showQuickContactInternal(getEnterpriseRemoteDirectoryId());
+    }
+
+    private void showQuickContactInternal(Long directoryId) throws Exception {
+        final Uri phoneLookupUri =
+                Uri.withAppendedPath(
+                        PhoneLookup.ENTERPRISE_CONTENT_FILTER_URI, MANAGED_CONTACT_PHONE);
+        if (directoryId != null) {
+            phoneLookupUri.buildUpon().appendQueryParameter(ContactsContract.DIRECTORY_PARAM_KEY,
+                    String.valueOf(directoryId)).build();
+        }
+        final Cursor cursor =
+                getContext().getContentResolver().query(phoneLookupUri, null, null, null, null);
+        try {
+            assertTrue(cursor.moveToFirst());
+            final long contactId =
+                    cursor.getLong(cursor.getColumnIndex(ContactsContract.PhoneLookup._ID));
+            final String lookupKey =
+                    cursor.getString(
+                            cursor.getColumnIndex(ContactsContract.PhoneLookup.LOOKUP_KEY));
+            final Uri lookupUri = Contacts.getLookupUri(contactId, lookupKey);
+            // TODO: It is better to verify the uri received by quick contacts, but it is difficult
+            // to verify it as the quick contacts in managed profile is started. We now just make
+            // sure no exception is thrown due to invalid uri (eg: directory id is missing).
+            // Also, consider using UiAutomator to verify the activtiy is started.
+            ContactsContract.QuickContact.showQuickContact(getContext(), (Rect) null, lookupUri,
+                    ContactsContract.QuickContact.MODE_LARGE, null);
+        } finally {
+            if (cursor != null) {
+                cursor.close();
+            }
+        }
+    }
+
+    private long getPrimaryRemoteDirectoryId() {
+        assertFalse(isManagedProfile());
+        return getRemoteDirectoryIdInternal();
+    }
+
+    private long getEnterpriseRemoteDirectoryIdInManagedProfile() {
+        assertTrue(isManagedProfile());
+        return getRemoteDirectoryIdInternal();
+    }
+
+    private long getRemoteDirectoryIdInternal() {
+        final Cursor cursor = mResolver.query(Directory.ENTERPRISE_CONTENT_URI,
+                new String[]{
+                        Directory._ID
+                }, null, null, null);
+        try {
+            while (cursor.moveToNext()) {
+                final long directoryId = cursor.getLong(0);
+                if (!Directory.isEnterpriseDirectoryId(directoryId)
+                        && Directory.isRemoteDirectory(directoryId)) {
+                    return directoryId;
+                }
+            }
+        } finally {
+            cursor.close();
+        }
+        fail("Cannot find primary directory id");
+        return 0;
+    }
+
+    private long getEnterpriseRemoteDirectoryId() {
+        final long enterpriseDirectoryId = getEnterpriseRemoteDirectoryIdSliently();
+        assertNotSame("Cannot find enterprise directory id", 0L, enterpriseDirectoryId);
+        return enterpriseDirectoryId;
+    }
+
+    private long getEnterpriseRemoteDirectoryIdSliently() {
+        assertFalse(isManagedProfile());
+        final Cursor cursor = mResolver.query(Directory.ENTERPRISE_CONTENT_URI,
+                new String[] {
+                    Directory._ID
+                }, null, null, null);
+        try {
+            while (cursor.moveToNext()) {
+                final long directoryId = cursor.getLong(0);
+                if (Directory.isEnterpriseDirectoryId(directoryId)
+                        && Directory.isRemoteDirectory(directoryId)) {
+                    return directoryId;
+                }
+            }
+        } finally {
+            cursor.close();
+        }
+        return 0;
+    }
+
     private boolean isManagedProfile() {
         String adminPackage = BaseManagedProfileTest.ADMIN_RECEIVER_COMPONENT.getPackageName();
         return mDevicePolicyManager.isProfileOwnerApp(adminPackage);
@@ -472,92 +1071,161 @@
         mResolver.applyBatch(ContactsContract.AUTHORITY, ops);
     }
 
-    private ContactInfo getContactInfoFromUri(Uri phoneLookupUri, String phoneNumber) {
-        return getContactInfoFromPhoneLookup(Uri.withAppendedPath(phoneLookupUri,
-                        Uri.encode(phoneNumber)), /* forSip =*/ false);
+    private void assertPrimaryLocalContact(ContactInfo contactInfo) {
+        assertNotNull(contactInfo);
+        assertEquals(PRIMARY_CONTACT_DISPLAY_NAME, contactInfo.displayName);
+        contactInfo.assertNoPhotoUri();
+        assertFalse(contactInfo.hasPhotoId());
     }
 
-    private ContactInfo getContactInfoFromSipUri(Uri phoneLookupUri, String sipAddress) {
-        return getContactInfoFromPhoneLookup(
-                phoneLookupUri.buildUpon().appendEncodedPath(sipAddress).appendQueryParameter(
-                        PhoneLookup.QUERY_PARAMETER_SIP_ADDRESS, "1").build(), /* forSip =*/ true);
+    private void assertManagedLocalContact(ContactInfo contactInfo) {
+        assertNotNull(contactInfo);
+        assertEquals(MANAGED_CONTACT_DISPLAY_NAME, contactInfo.displayName);
+        contactInfo.assertPhotoUrisReadable();
     }
 
-    private ContactInfo getContactInfoFromPhoneLookup(Uri uri, boolean isForSip) {
+    private void assertPrimaryDirectoryContact(ContactInfo contactInfo) {
+        assertNotNull(contactInfo);
+        assertEquals(PRIMARY_DIRECTORY_CONTACT_NAME, contactInfo.displayName);
+        contactInfo.assertThumbnailUri(R.raw.primary_thumbnail);
+        contactInfo.assertPhotoUri(R.raw.primary_photo);
+    }
+
+    private void assertManagedDirectoryContact(ContactInfo contactInfo) {
+        assertNotNull(contactInfo);
+        assertEquals(MANAGED_DIRECTORY_CONTACT_NAME, contactInfo.displayName);
+        contactInfo.assertThumbnailUri(R.raw.managed_thumbnail);
+        contactInfo.assertPhotoUri(R.raw.managed_photo);
+    }
+
+    private void assertContactInfoEquals(ContactInfo lhs, ContactInfo rhs) {
+        if (lhs == null) {
+            assertNull(rhs);
+        } else {
+            assertNotNull(rhs);
+            assertEquals(lhs.contactId, rhs.contactId);
+            assertEquals(lhs.displayName, rhs.displayName);
+            assertEquals(lhs.photoId, rhs.photoId);
+            assertEquals(lhs.photoThumbnailUri, rhs.photoThumbnailUri);
+            assertEquals(lhs.photoUri, rhs.photoUri);
+        }
+    }
+
+    private ContactInfo getContactInfoFromPhoneLookupUri(boolean isEnterprise, String phoneNumber) {
+        Uri baseUri = (isEnterprise) ? PhoneLookup.ENTERPRISE_CONTENT_FILTER_URI
+                : PhoneLookup.CONTENT_FILTER_URI;
+        Uri uri = baseUri.buildUpon().appendPath(phoneNumber).build();
+        ContactInfo contactInfo = getContactInfoFromUri(uri, PhoneLookup._ID,
+                PhoneLookup.DISPLAY_NAME,
+                PhoneLookup.PHOTO_URI, PhoneLookup.PHOTO_THUMBNAIL_URI, PhoneLookup.PHOTO_ID);
+
+        ContactInfo contactInfo2 = getContactInfoFromUri(uri, PhoneLookup.CONTACT_ID,
+                PhoneLookup.DISPLAY_NAME,
+                PhoneLookup.PHOTO_URI, PhoneLookup.PHOTO_THUMBNAIL_URI, PhoneLookup.PHOTO_ID);
+        assertContactInfoEquals(contactInfo, contactInfo2);
+        return contactInfo;
+    }
+
+    private ContactInfo getContactInfoFromEnterprisePhoneLookupUriWithSipAddress(
+            boolean isEnterprise, String sipAddress) {
+        Uri baseUri = (isEnterprise) ? PhoneLookup.ENTERPRISE_CONTENT_FILTER_URI
+                : PhoneLookup.CONTENT_FILTER_URI;
+        Uri uri = baseUri.buildUpon().appendPath(sipAddress)
+                .appendQueryParameter(PhoneLookup.QUERY_PARAMETER_SIP_ADDRESS, "1").build();
+        return getContactInfoFromUri(uri, PhoneLookup.CONTACT_ID, PhoneLookup.DISPLAY_NAME,
+                PhoneLookup.PHOTO_URI, PhoneLookup.PHOTO_THUMBNAIL_URI, PhoneLookup.PHOTO_ID);
+    }
+
+    private ContactInfo getContactInfoFromEnterprisePhoneLookupUriInDirectory(String phoneNumber,
+            long directoryId) {
+        Uri uri = PhoneLookup.ENTERPRISE_CONTENT_FILTER_URI.buildUpon().appendPath(phoneNumber)
+                .appendQueryParameter(ContactsContract.DIRECTORY_PARAM_KEY,
+                        String.valueOf(directoryId)).build();
+        return getContactInfoFromUri(uri, PhoneLookup._ID, PhoneLookup.DISPLAY_NAME,
+                PhoneLookup.PHOTO_URI, PhoneLookup.PHOTO_THUMBNAIL_URI, PhoneLookup.PHOTO_ID);
+    }
+
+    private ContactInfo getContactInfoFromEmailLookupUri(boolean isEnterprise, String email) {
+        Uri baseUri = (isEnterprise) ? Email.ENTERPRISE_CONTENT_LOOKUP_URI
+                : Email.CONTENT_LOOKUP_URI;
+        Uri uri = Uri.withAppendedPath(baseUri, email);
+        return getContactInfoFromUri(uri, Email.CONTACT_ID, Email.DISPLAY_NAME_PRIMARY,
+                Email.PHOTO_URI, Email.PHOTO_THUMBNAIL_URI, Email.PHOTO_ID);
+    }
+
+    private ContactInfo getContactInfoFromEnterpriseEmailLookupUriInDirectory(String email,
+            long directoryId) {
+        Uri uri = Email.ENTERPRISE_CONTENT_LOOKUP_URI.buildUpon().appendPath(email)
+                .appendQueryParameter(ContactsContract.DIRECTORY_PARAM_KEY,
+                        String.valueOf(directoryId)).build();
+        return getContactInfoFromUri(uri, Email.CONTACT_ID, Email.DISPLAY_NAME_PRIMARY,
+                Email.PHOTO_URI, Email.PHOTO_THUMBNAIL_URI, Email.PHOTO_ID);
+    }
+
+    private ContactInfo getContactInfoFromEnterpriseCallableFilterUriInDirectory(String filter,
+            long directoryId) {
+        final Uri uri = Uri.withAppendedPath(Callable.ENTERPRISE_CONTENT_FILTER_URI, filter)
+                .buildUpon().appendQueryParameter(ContactsContract.DIRECTORY_PARAM_KEY,
+                        String.valueOf(directoryId)).build();
+        return getContactInfoFromUri(uri, Callable.CONTACT_ID, Callable.DISPLAY_NAME_PRIMARY,
+                Callable.PHOTO_URI, Callable.PHOTO_THUMBNAIL_URI, Callable.PHOTO_ID);
+    }
+
+    private ContactInfo getContactInfoFromEnterpriseEmailFilterUriInDirectory(String filter,
+            long directoryId) {
+        final Uri uri = Uri.withAppendedPath(Email.ENTERPRISE_CONTENT_FILTER_URI, filter)
+                .buildUpon().appendQueryParameter(ContactsContract.DIRECTORY_PARAM_KEY,
+                        String.valueOf(directoryId)).build();
+        return getContactInfoFromUri(uri, Email.CONTACT_ID, Email.DISPLAY_NAME_PRIMARY,
+                Email.PHOTO_URI, Email.PHOTO_THUMBNAIL_URI, Email.PHOTO_ID);
+    }
+
+    private ContactInfo getContactInfoFromEnterpriseContactFilterUriInDirectory(String filter,
+            long directoryId) {
+        final Uri uri = Uri.withAppendedPath(Contacts.ENTERPRISE_CONTENT_FILTER_URI, filter)
+                .buildUpon().appendQueryParameter(ContactsContract.DIRECTORY_PARAM_KEY,
+                        String.valueOf(directoryId)).build();
+        return getContactInfoFromUri(uri, Contacts._ID, Contacts.DISPLAY_NAME_PRIMARY,
+                Contacts.PHOTO_URI, Contacts.PHOTO_THUMBNAIL_URI, Contacts.PHOTO_ID);
+    }
+
+    private ContactInfo getContactInfoFromEnterprisePhoneFilterUriInDirectory(String filter,
+            long directoryId) {
+        final Uri uri = Uri.withAppendedPath(Phone.ENTERPRISE_CONTENT_FILTER_URI, filter)
+                .buildUpon().appendQueryParameter(ContactsContract.DIRECTORY_PARAM_KEY,
+                        String.valueOf(directoryId)).build();
+        return getContactInfoFromUri(uri, Phone.CONTACT_ID, Phone.DISPLAY_NAME_PRIMARY,
+                Phone.PHOTO_URI, Phone.PHOTO_THUMBNAIL_URI, Phone.PHOTO_ID);
+    }
+
+
+    private ContactInfo getContactInfoFromUri(Uri uri, String idColumn,
+            String displayNameColumn, String photoUriColumn, String photoThumbnailColumn,
+            String photoIdColumn) {
         Cursor cursor = mResolver.query(uri,
                 new String[] {
-                        PhoneLookup._ID, PhoneLookup.DISPLAY_NAME, PhoneLookup.PHOTO_URI,
-                        PhoneLookup.PHOTO_THUMBNAIL_URI, PhoneLookup.PHOTO_ID
+                        idColumn,
+                        displayNameColumn,
+                        photoUriColumn,
+                        photoIdColumn,
+                        photoThumbnailColumn,
                 }, null, null, null);
         if (cursor == null) {
             return null;
         }
-        ContactInfo result = null;
-        if (cursor.moveToFirst()) {
-            result = new ContactInfo(
-                    cursor.getString(cursor.getColumnIndexOrThrow(PhoneLookup._ID)),
-                    cursor.getString(cursor.getColumnIndexOrThrow(PhoneLookup.DISPLAY_NAME)),
-                    cursor.getString(cursor.getColumnIndexOrThrow(PhoneLookup.PHOTO_URI)),
-                    cursor.getString(cursor.getColumnIndexOrThrow(PhoneLookup.PHOTO_THUMBNAIL_URI)),
-                    cursor.getString(cursor.getColumnIndexOrThrow(PhoneLookup.PHOTO_ID)));
+        try {
+            if (cursor.moveToFirst()) {
+                return new ContactInfo(
+                        cursor.getString(cursor.getColumnIndexOrThrow(idColumn)),
+                        cursor.getString(cursor.getColumnIndexOrThrow(displayNameColumn)),
+                        cursor.getString(cursor.getColumnIndexOrThrow(photoUriColumn)),
+                        cursor.getString(cursor.getColumnIndexOrThrow(photoThumbnailColumn)),
+                        cursor.getString(cursor.getColumnIndexOrThrow(photoIdColumn)));
+            }
+        } finally {
+            cursor.close();
         }
-        cursor.close();
-        return result;
-    }
-
-    private ContactInfo getContactInfoFromEmailUri(Uri emailLookupUri, String email) {
-        Uri uri = Uri.withAppendedPath(emailLookupUri, Uri.encode(email));
-        Cursor cursor = mResolver.query(uri,
-                new String[] {
-                        Email.CONTACT_ID,
-                        Email.DISPLAY_NAME_PRIMARY,
-                        Email.PHOTO_URI,
-                        Email.PHOTO_ID,
-                        Email.PHOTO_THUMBNAIL_URI,
-                }, null, null, null);
-        if (cursor == null) {
-            return null;
-        }
-        ContactInfo result = null;
-        if (cursor.moveToFirst()) {
-            result = new ContactInfo(
-                    cursor.getString(cursor.getColumnIndexOrThrow(
-                        Email.CONTACT_ID)),
-                    cursor.getString(cursor.getColumnIndexOrThrow(
-                        Email.DISPLAY_NAME_PRIMARY)),
-                    cursor.getString(cursor.getColumnIndexOrThrow(
-                        Email.PHOTO_URI)),
-                    cursor.getString(cursor.getColumnIndexOrThrow(
-                        Email.PHOTO_THUMBNAIL_URI)),
-                    cursor.getString(cursor.getColumnIndexOrThrow(
-                        Email.PHOTO_ID)));
-        }
-        cursor.close();
-        return result;
-    }
-
-    private ContactInfo getContactInfo(String phoneNumber) {
-        return getContactInfoFromUri(PhoneLookup.CONTENT_FILTER_URI,
-                phoneNumber);
-    }
-
-    private ContactInfo getContactInfoFromEmail(String email) {
-        return getContactInfoFromEmailUri(Email.CONTENT_LOOKUP_URI, email);
-    }
-
-    private ContactInfo getEnterpriseContactInfo(String phoneNumber) {
-        return getContactInfoFromUri(
-                PhoneLookup.ENTERPRISE_CONTENT_FILTER_URI,
-                phoneNumber);
-    }
-
-    private ContactInfo getEnterpriseContactInfoFromSipAddress(String phoneNumber) {
-        return getContactInfoFromSipUri(PhoneLookup.ENTERPRISE_CONTENT_FILTER_URI,
-                phoneNumber);
-    }
-
-    private ContactInfo getEnterpriseContactInfoFromEmail(String email) {
-        return getContactInfoFromEmailUri(Email.ENTERPRISE_CONTENT_LOOKUP_URI, email);
+        return null;
     }
 
     private void removeAllTestContactsInProfile() {
@@ -571,10 +1239,30 @@
             // Catch all exceptions to let tearDown() run smoothly
             e.printStackTrace();
         }
+
         Account account = new Account(TEST_ACCOUNT_NAME, TEST_ACCOUNT_TYPE);
         AccountManager.get(getContext()).removeAccountExplicitly(account);
     }
 
+    private InputStream getInputStreamFromUriForTest(String uriString) {
+        try {
+            return mResolver.openInputStream(Uri.parse(uriString));
+        } catch (FileNotFoundException e) {
+            fail(e.getMessage());
+            throw new RuntimeException(e);
+        }
+    }
+
+    private static byte[] getByteFromStreamForTest(InputStream is) {
+        assertNotNull(is);
+        try (InputStream in = is) {
+            return getByteFromStream(in);
+        } catch (IOException e) {
+            fail(e.getMessage());
+            throw new RuntimeException(e);
+        }
+    }
+
     private static byte[] getByteFromStream(InputStream is) throws IOException {
         ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
         byte[] buf = new byte[1024 * 10];
@@ -589,17 +1277,22 @@
         return ContactsContract.Contacts.isEnterpriseContactId(Long.valueOf(contactId));
     }
 
-    private void assertPhotoUriReadable(String uri) throws IOException {
+    private void assertPhotoUriReadable(String uri) {
         assertNotNull(uri);
-        final InputStream is = mResolver.openInputStream(Uri.parse(uri));
-        try {
+        try (InputStream is = mResolver.openInputStream(Uri.parse(uri))) {
             // Make sure it's readabe.  Don't have to read all content.
             is.read();
-        } finally {
-            try {
-                is.close();
-            } catch (IOException ignore) {
-            }
+        } catch (IOException e) {
+            fail(e.getMessage());
+            throw new RuntimeException(e);
+        }
+    }
+
+    private void assertFailWhenDirectoryParamMissing(Uri uri) {
+        try {
+            mResolver.query(uri, null, null, null, null);
+            fail("IllegalArgumentException is not thrown");
+        } catch (IllegalArgumentException ex) {
         }
     }
 }
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/CrossProfileWidgetTest.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/CrossProfileWidgetTest.java
index 085d56f..c122b07 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/CrossProfileWidgetTest.java
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/CrossProfileWidgetTest.java
@@ -68,9 +68,8 @@
         List<String> providers = mDevicePolicyManager.getCrossProfileWidgetProviders(
                 ADMIN_RECEIVER_COMPONENT);
         assertTrue(providers.isEmpty());
-        // check that widget can still be found inside the profile
-        // This does not currently work correctly: http://b/issues/21180997
-        // assertTrue(containsWidgetProviderPkg(mAppWidgetManager.getInstalledProviders()));
+        // Check that widget can still be found inside the profile
+        assertTrue(containsWidgetProviderPkg(mAppWidgetManager.getInstalledProviders()));
     }
 
     private boolean containsWidgetProviderPkg(List<AppWidgetProviderInfo> widgets) {
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/DummyConnectionService.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/DummyConnectionService.java
new file mode 100644
index 0000000..0b1731d
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/DummyConnectionService.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.managedprofile;
+
+import android.net.Uri;
+import android.telecom.Connection;
+import android.telecom.ConnectionRequest;
+import android.telecom.ConnectionService;
+import android.telecom.DisconnectCause;
+import android.telecom.PhoneAccountHandle;
+import android.telecom.RemoteConference;
+import android.telecom.RemoteConnection;
+import android.telecom.TelecomManager;
+
+/**
+ * A simple connection service that hangs up automatically for incoming and outgoing call.
+ */
+public class DummyConnectionService extends ConnectionService {
+
+    @Override
+    public Connection onCreateOutgoingConnection(PhoneAccountHandle connectionManagerPhoneAccount,
+            ConnectionRequest request) {
+        final DummyConnection connection = new DummyConnection();
+        connection.setAddress(request.getAddress(), TelecomManager.PRESENTATION_ALLOWED);
+        connection.setVideoState(request.getVideoState());
+        hangUpAsync(connection);
+        return connection;
+    }
+
+    @Override
+    public Connection onCreateIncomingConnection(PhoneAccountHandle connectionManagerPhoneAccount,
+            ConnectionRequest request) {
+        final DummyConnection connection = new DummyConnection();
+        connection.setVideoState(request.getVideoState());
+        final Uri address =
+                request.getExtras().getParcelable(TelecomManager.EXTRA_INCOMING_CALL_ADDRESS);
+        connection.setAddress(address, TelecomManager.PRESENTATION_ALLOWED);
+        hangUpAsync(connection);
+        return connection;
+    }
+
+    @Override
+    public void onConference(Connection connection1, Connection connection2) {
+    }
+
+    @Override
+    public void onRemoteExistingConnectionAdded(RemoteConnection connection) {
+    }
+
+    @Override
+    public void onRemoteConferenceAdded(RemoteConference conference) {
+    }
+
+    public static class DummyConnection extends Connection {
+
+        @Override
+        public void onAnswer() {
+            super.onAnswer();
+        }
+
+        @Override
+        public void onAnswer(int videoState) {
+            super.onAnswer(videoState);
+            setActive();
+        }
+
+        @Override
+        public void onReject() {
+            super.onReject();
+            setDisconnected(new DisconnectCause(DisconnectCause.REJECTED));
+            destroy();
+        }
+
+        @Override
+        public void onHold() {
+            super.onHold();
+            setOnHold();
+        }
+
+        @Override
+        public void onUnhold() {
+            super.onUnhold();
+            setActive();
+        }
+
+        @Override
+        public void onDisconnect() {
+            super.onDisconnect();
+            setDisconnected(new DisconnectCause(DisconnectCause.LOCAL));
+            destroy();
+        }
+
+        @Override
+        public void onAbort() {
+            super.onAbort();
+            setDisconnected(new DisconnectCause(DisconnectCause.UNKNOWN));
+            destroy();
+        }
+    }
+
+    /**
+     * Hang up the call after 1 second in a background thread.
+     * TODO: It is better if we could have a callback to know when we can disconnect the call.
+     */
+    private static void hangUpAsync(final Connection connection) {
+        new Thread(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    Thread.sleep(1000);
+                    connection.onDisconnect();
+                } catch (InterruptedException ex) {
+                    // let it be
+                }
+            }
+        }).start();
+    }
+}
\ No newline at end of file
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/DummyDialerActivity.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/DummyDialerActivity.java
new file mode 100644
index 0000000..58fc601
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/DummyDialerActivity.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package com.android.cts.managedprofile;
+
+import android.app.Activity;
+
+/**
+ * To run {@link PhoneAccountTest}, we need to have a dialer in managed profile.
+ */
+public class DummyDialerActivity extends Activity {
+}
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/OrganizationInfoTest.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/OrganizationInfoTest.java
new file mode 100644
index 0000000..ec5ea0f
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/OrganizationInfoTest.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.managedprofile;
+
+import android.graphics.Color;
+
+public class OrganizationInfoTest extends BaseManagedProfileTest {
+
+    public void testDefaultOrganizationColorIsGray() {
+        int defaultColor = mDevicePolicyManager.getOrganizationColor(ADMIN_RECEIVER_COMPONENT);
+        assertEquals(Color.GRAY, defaultColor);
+    }
+
+    public void testSetOrganizationColor() {
+        int previousColor = mDevicePolicyManager.getOrganizationColor(ADMIN_RECEIVER_COMPONENT);
+
+        try {
+            final int[] colors = {
+                Color.TRANSPARENT,
+                Color.WHITE,
+                Color.RED,
+                Color.GREEN,
+                Color.BLUE,
+                0x7FFE5B35 /* HTML name: "Sunset orange". Opacity: 50%. */
+            };
+
+            for (int color : colors) {
+                mDevicePolicyManager.setOrganizationColor(ADMIN_RECEIVER_COMPONENT, color);
+                assertEquals(color,
+                        mDevicePolicyManager.getOrganizationColor(ADMIN_RECEIVER_COMPONENT));
+            }
+        } finally {
+            // Put the organization color back how it was.
+            mDevicePolicyManager.setOrganizationColor(ADMIN_RECEIVER_COMPONENT, previousColor);
+        }
+    }
+
+    public void testSetOrGetOrganizationColorWithNullAdminFails() {
+        try {
+            mDevicePolicyManager.setOrganizationColor(null, Color.GRAY);
+            fail("Exception should have been thrown for null admin ComponentName");
+        } catch (Exception expected) {
+        }
+
+        try {
+            int color = mDevicePolicyManager.getOrganizationColor(null);
+            fail("Exception should have been thrown for null admin ComponentName");
+        } catch (Exception expected) {
+        }
+    }
+
+    public void testDefaultOrganizationNameIsNull() {
+        CharSequence organizationName = mDevicePolicyManager.getOrganizationName(
+                ADMIN_RECEIVER_COMPONENT);
+        assertNull(organizationName);
+    }
+
+    public void testSetOrganizationName() {
+        CharSequence previousOrganizationName = mDevicePolicyManager.getOrganizationName(
+                ADMIN_RECEIVER_COMPONENT);
+
+        try {
+            final CharSequence name = "test-set-name";
+            mDevicePolicyManager.setOrganizationName(ADMIN_RECEIVER_COMPONENT, name);
+            CharSequence organizationName = mDevicePolicyManager.getOrganizationName(
+                    ADMIN_RECEIVER_COMPONENT);
+            assertEquals(name, organizationName);
+        } finally {
+            mDevicePolicyManager.setOrganizationName(ADMIN_RECEIVER_COMPONENT,
+                    previousOrganizationName);
+        }
+    }
+
+    public void testSetOrGetOrganizationNameWithNullAdminFails() {
+        try {
+            mDevicePolicyManager.setOrganizationName(null, "null-admin-fails");
+            fail("Exception should have been thrown for null admin ComponentName");
+        } catch (Exception expected) {
+        }
+
+        try {
+            mDevicePolicyManager.getOrganizationName(null);
+            fail("Exception should have been thrown for null admin ComponentName");
+        } catch (Exception expected) {
+        }
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/PasswordMinimumRestrictionsTest.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/PasswordMinimumRestrictionsTest.java
new file mode 100644
index 0000000..4f94674
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/PasswordMinimumRestrictionsTest.java
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.managedprofile;
+
+import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_COMPLEX;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+
+public class PasswordMinimumRestrictionsTest extends BaseManagedProfileTest {
+
+    private static final int TEST_PASSWORD_LENGTH = 5;
+    private static final int TEST_PASSWORD_LENGTH_LOW = 2;
+    private static final String[] METHOD_LIST = {
+            "PasswordMinimumLength",
+            "PasswordMinimumUpperCase",
+            "PasswordMinimumLowerCase",
+            "PasswordMinimumLetters",
+            "PasswordMinimumNumeric",
+            "PasswordMinimumSymbols",
+            "PasswordMinimumNonLetter",
+            "PasswordHistoryLength"};
+
+    private DevicePolicyManager mParentDpm;
+    private int mCurrentAdminPreviousPasswordQuality;
+    private int mParentPreviousPasswordQuality;
+    private List<Integer> mCurrentAdminPreviousPasswordRestriction = new ArrayList<Integer>();
+    private List<Integer> mParentPreviousPasswordRestriction = new ArrayList<Integer>();
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        mParentDpm = mDevicePolicyManager.getParentProfileInstance(ADMIN_RECEIVER_COMPONENT);
+        mCurrentAdminPreviousPasswordQuality =
+                mDevicePolicyManager.getPasswordQuality(ADMIN_RECEIVER_COMPONENT);
+        mParentPreviousPasswordQuality = mParentDpm.getPasswordQuality(ADMIN_RECEIVER_COMPONENT);
+        mDevicePolicyManager.setPasswordQuality(ADMIN_RECEIVER_COMPONENT, PASSWORD_QUALITY_COMPLEX);
+        mParentDpm.setPasswordQuality(ADMIN_RECEIVER_COMPONENT, PASSWORD_QUALITY_COMPLEX);
+        for (String method : METHOD_LIST) {
+            mCurrentAdminPreviousPasswordRestriction
+                    .add(invokeGetMethod(method, mDevicePolicyManager, ADMIN_RECEIVER_COMPONENT));
+            mParentPreviousPasswordRestriction
+                    .add(invokeGetMethod(method, mParentDpm, ADMIN_RECEIVER_COMPONENT));
+        }
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        for (int i = 0; i < METHOD_LIST.length; i++) {
+            invokeSetMethod(METHOD_LIST[i], mDevicePolicyManager, ADMIN_RECEIVER_COMPONENT,
+                    mCurrentAdminPreviousPasswordRestriction.get(i));
+            invokeSetMethod(METHOD_LIST[i], mParentDpm, ADMIN_RECEIVER_COMPONENT,
+                    mCurrentAdminPreviousPasswordRestriction.get(i));
+        }
+        mDevicePolicyManager.setPasswordQuality(ADMIN_RECEIVER_COMPONENT,
+                mCurrentAdminPreviousPasswordQuality);
+        mParentDpm.setPasswordQuality(ADMIN_RECEIVER_COMPONENT, mParentPreviousPasswordQuality);
+        super.tearDown();
+    }
+
+    public void testPasswordMinimumRestriction() throws Exception {
+        for (int i = 0; i < METHOD_LIST.length; i++) {
+            invokeSetMethod(METHOD_LIST[i], mDevicePolicyManager, ADMIN_RECEIVER_COMPONENT,
+                    TEST_PASSWORD_LENGTH + i);
+            invokeSetMethod(METHOD_LIST[i], mParentDpm, ADMIN_RECEIVER_COMPONENT,
+                    TEST_PASSWORD_LENGTH + 2 * i);
+
+            // Passing the admin component returns the value set for that admin, rather than
+            // aggregated values.
+            assertEquals(
+                    getMethodName(METHOD_LIST[i])
+                            + " failed to get expected value on mDevicePolicyManager.",
+                    TEST_PASSWORD_LENGTH + i, invokeGetMethod(METHOD_LIST[i], mDevicePolicyManager,
+                            ADMIN_RECEIVER_COMPONENT));
+
+            // Passing the admin component returns the value set for that admin, rather than
+            // aggregated values.
+            assertEquals(
+                    getMethodName(METHOD_LIST[i]) + " failed to get expected value on mParentDpm.",
+                    TEST_PASSWORD_LENGTH + 2 * i,
+                    invokeGetMethod(METHOD_LIST[i], mParentDpm, ADMIN_RECEIVER_COMPONENT));
+        }
+    }
+
+    public void testSetPasswordMinimumRestrictionWithNull() {
+        // Test with mDevicePolicyManager.
+        for (String method : METHOD_LIST) {
+            try {
+                invokeSetMethod(method, mDevicePolicyManager, null, TEST_PASSWORD_LENGTH);
+                fail("Exception should have been thrown for null admin ComponentName");
+            } catch (Exception e) {
+                if (!(e.getCause() instanceof NullPointerException)) {
+                    fail("Failed to execute set method: " + setMethodName(method));
+                }
+                // Expected to throw NullPointerException.
+            }
+        }
+
+        // Test with mParentDpm.
+        for (String method : METHOD_LIST) {
+            try {
+                invokeSetMethod(method, mParentDpm, null, TEST_PASSWORD_LENGTH);
+                fail("Exception should have been thrown for null admin ComponentName");
+            } catch (Exception e) {
+                if (!(e.getCause() instanceof NullPointerException)) {
+                    fail("Failed to execute set method: " + setMethodName(method));
+                }
+                // Expected to throw NullPointerException.
+            }
+        }
+    }
+
+    public void testGetPasswordMinimumRestrictionWithNullAdmin() throws Exception {
+        for (int i = 0; i < METHOD_LIST.length; i++) {
+            // Check getMethod with null admin. It should return the aggregated value (which is the
+            // only value set so far).
+            invokeSetMethod(METHOD_LIST[i], mDevicePolicyManager, ADMIN_RECEIVER_COMPONENT,
+                    TEST_PASSWORD_LENGTH_LOW + i);
+            assertEquals(getMethodName(METHOD_LIST[i]) + " failed.", TEST_PASSWORD_LENGTH_LOW + i,
+                    invokeGetMethod(METHOD_LIST[i], mDevicePolicyManager, null));
+
+            // Set strict password minimum restriction using parent instance.
+            invokeSetMethod(METHOD_LIST[i], mParentDpm, ADMIN_RECEIVER_COMPONENT,
+                    TEST_PASSWORD_LENGTH + i);
+            // With null admin, the restriction should be the aggregate of all admins.
+            assertEquals(getMethodName(METHOD_LIST[i]) + " failed.", TEST_PASSWORD_LENGTH + i,
+                    invokeGetMethod(METHOD_LIST[i], mDevicePolicyManager, null));
+            // With null admin, the restriction should be the aggregate of all admins.
+            assertEquals(getMethodName(METHOD_LIST[i]) + " failed.", TEST_PASSWORD_LENGTH + i,
+                    invokeGetMethod(METHOD_LIST[i], mParentDpm, null));
+
+            // Passing the admin component returns the value set for that admin, rather than
+            // aggregated values.
+            assertEquals(getMethodName(METHOD_LIST[i]) + " failed.", TEST_PASSWORD_LENGTH_LOW + i,
+                    invokeGetMethod(METHOD_LIST[i], mDevicePolicyManager,
+                            ADMIN_RECEIVER_COMPONENT));
+            assertEquals(getMethodName(METHOD_LIST[i]) + " failed.", TEST_PASSWORD_LENGTH + i,
+                    invokeGetMethod(METHOD_LIST[i], mParentDpm, ADMIN_RECEIVER_COMPONENT));
+
+            // Set strict password minimum restriction on current admin.
+            invokeSetMethod(METHOD_LIST[i], mDevicePolicyManager, ADMIN_RECEIVER_COMPONENT,
+                    TEST_PASSWORD_LENGTH + i);
+            // Set password minimum restriction using parent instance.
+            invokeSetMethod(METHOD_LIST[i], mParentDpm, ADMIN_RECEIVER_COMPONENT,
+                    TEST_PASSWORD_LENGTH_LOW + i);
+            // With null admin, the restriction should be the aggregate of all admins.
+            assertEquals(getMethodName(METHOD_LIST[i]) + " failed.", TEST_PASSWORD_LENGTH + i,
+                    invokeGetMethod(METHOD_LIST[i], mDevicePolicyManager, null));
+            // With null admin, the restriction should be the aggregate of all admins.
+            assertEquals(getMethodName(METHOD_LIST[i]) + " failed.", TEST_PASSWORD_LENGTH + i,
+                    invokeGetMethod(METHOD_LIST[i], mParentDpm, null));
+
+            // Passing the admin component returns the value set for that admin, rather than
+            // aggregated values.
+            assertEquals(getMethodName(METHOD_LIST[i]) + " failed.", TEST_PASSWORD_LENGTH + i,
+                    invokeGetMethod(METHOD_LIST[i], mDevicePolicyManager,
+                            ADMIN_RECEIVER_COMPONENT));
+            assertEquals(getMethodName(METHOD_LIST[i]) + " failed.", TEST_PASSWORD_LENGTH_LOW + i,
+                    invokeGetMethod(METHOD_LIST[i], mParentDpm, ADMIN_RECEIVER_COMPONENT));
+        }
+    }
+
+    /**
+     * Calls dpm.set{methodName} with given component name and length arguments using reflection.
+     */
+    private void invokeSetMethod(String methodName, DevicePolicyManager dpm,
+            ComponentName componentName, int length) throws Exception {
+        final Method setMethod = DevicePolicyManager.class.getMethod(setMethodName(methodName),
+                ComponentName.class, int.class);
+        setMethod.invoke(dpm, componentName, length);
+    }
+
+    /**
+     * Calls dpm.get{methodName} with given component name using reflection.
+     */
+    private int invokeGetMethod(String methodName, DevicePolicyManager dpm,
+            ComponentName componentName) throws Exception {
+        final Method getMethod =
+                DevicePolicyManager.class.getMethod(getMethodName(methodName), ComponentName.class);
+        return (int) getMethod.invoke(dpm, componentName);
+    }
+
+    private String setMethodName(String methodName) {
+        return "set" + methodName;
+    }
+
+    private String getMethodName(String methodName) {
+        return "get" + methodName;
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/PhoneAccountTest.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/PhoneAccountTest.java
new file mode 100644
index 0000000..63f2309
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/PhoneAccountTest.java
@@ -0,0 +1,310 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package com.android.cts.managedprofile;
+
+import android.app.Instrumentation;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.database.ContentObserver;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.ParcelFileDescriptor;
+import android.os.Process;
+import android.os.UserManager;
+import android.provider.CallLog.Calls;
+import android.telecom.PhoneAccount;
+import android.telecom.PhoneAccountHandle;
+import android.telecom.TelecomManager;
+import android.test.InstrumentationTestCase;
+
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+public class PhoneAccountTest extends InstrumentationTestCase {
+
+    static final String CALL_PROVIDER_ID = "testapps_TestConnectionService_CALL_PROVIDER_ID";
+
+    private static final String COMMAND_ENABLE = "telecom set-phone-account-enabled";
+
+    private static final String PHONE_NUMBER = "886";
+
+    private static final String QUERY_CALL_THROUGH_OUR_CONNECTION_SERVICE = Calls.NUMBER
+            + " = ? AND " + Calls.PHONE_ACCOUNT_COMPONENT_NAME + " = ?";
+
+    private TelecomManager mTelecomManager;
+
+    private Context mContext;
+
+    private Instrumentation mInstrumentation;
+
+    private static final String MANAGED_PROFILE_PKG = "com.android.cts.managedprofile";
+
+    private static final PhoneAccountHandle PHONE_ACCOUNT_HANDLE = new PhoneAccountHandle(
+            new ComponentName(MANAGED_PROFILE_PKG,
+                    DummyConnectionService.class.getName()), CALL_PROVIDER_ID,
+            Process.myUserHandle());
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mInstrumentation = getInstrumentation();
+        mContext = getInstrumentation().getContext();
+        mTelecomManager = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    public void testOutgoingCallUsingTelecomManager() throws Exception {
+        internalTestOutgoingCall(true /* usingTelecomManager */);
+    }
+
+    public void testOutgoingCallUsingActionCall() throws Exception {
+        internalTestOutgoingCall(false /* usingTelecomManager */);
+    }
+
+    /**
+     *  Placing an outgoing call through our phone account and verify the call is inserted
+     *  properly.
+     */
+    private void internalTestOutgoingCall(boolean usingTelecomManager) throws Exception {
+        // Make sure no lingering values from previous runs.
+        cleanupCall(false);
+        final Context context = getInstrumentation().getContext();
+        final HandlerThread handlerThread = new HandlerThread("Observer");
+        // Register the phone account.
+        final PhoneAccountHandle phoneAccountHandle = registerPhoneAccount().getAccountHandle();
+        try {
+            // Register the ContentObserver so that we will be get notified when the call is
+            // inserted.
+            final CountDownLatch countDownLatch = new CountDownLatch(1);
+            handlerThread.start();
+            context.getContentResolver().registerContentObserver(Calls.CONTENT_URI, false,
+                    new CalllogContentObserver(new Handler(handlerThread.getLooper()),
+                            countDownLatch));
+
+            // Place the call.
+            if (usingTelecomManager) {
+                placeCallUsingTelecomManager(phoneAccountHandle);
+            } else {
+                placeCallUsingActionCall(phoneAccountHandle);
+            }
+
+            // Make sure the call inserted is correct.
+            boolean calllogProviderChanged = countDownLatch.await(1, TimeUnit.MINUTES);
+            assertTrue(calllogProviderChanged);
+            assertCalllogInserted(Calls.OUTGOING_TYPE);
+        } finally {
+            handlerThread.quit();
+            cleanupCall(true /* verifyDeletion */ );
+            unregisterPhoneAccount();
+        }
+    }
+
+    private void placeCallUsingTelecomManager(PhoneAccountHandle phoneAccountHandle) {
+        Uri phoneUri = Uri.fromParts(PhoneAccount.SCHEME_TEL, PHONE_NUMBER, null);
+        Bundle extras = new Bundle();
+        extras.putParcelable(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, phoneAccountHandle);
+        mTelecomManager.placeCall(phoneUri, extras);
+    }
+
+    private void placeCallUsingActionCall(PhoneAccountHandle phoneAccountHandle) {
+        Intent intent = new Intent(Intent.ACTION_CALL);
+        intent.setData(Uri.parse("tel:" + PHONE_NUMBER));
+        intent.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, phoneAccountHandle);
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        mContext.startActivity(intent);
+    }
+
+    /**
+     *  Add an incoming call with our phone account and verify the call is inserted properly.
+     */
+    public void testIncomingCall() throws Exception {
+        // Make sure no lingering values from previous runs.
+        cleanupCall(false);
+        final Context context = getInstrumentation().getContext();
+        final HandlerThread handlerThread = new HandlerThread("Observer");
+        // Register the phone account.
+        final PhoneAccountHandle phoneAccountHandle = registerPhoneAccount().getAccountHandle();
+        try {
+            // Register the ContentObserver so that we will be get notified when the call is
+            // inserted.
+            final CountDownLatch countDownLatch = new CountDownLatch(1);
+            handlerThread.start();
+            context.getContentResolver().registerContentObserver(Calls.CONTENT_URI, false,
+                    new CalllogContentObserver(new Handler(handlerThread.getLooper()),
+                            countDownLatch));
+
+            // Add a incoming call.
+            final Bundle bundle = new Bundle();
+            final Uri phoneUri = Uri.fromParts(PhoneAccount.SCHEME_TEL, PHONE_NUMBER, null);
+            bundle.putParcelable(TelecomManager.EXTRA_INCOMING_CALL_ADDRESS, phoneUri);
+            mTelecomManager.addNewIncomingCall(phoneAccountHandle, bundle);
+
+            // Make sure the call inserted is correct.
+            boolean calllogProviderChanged = countDownLatch.await(1, TimeUnit.MINUTES);
+            assertTrue(calllogProviderChanged);
+            assertCalllogInserted(Calls.INCOMING_TYPE);
+        } finally {
+            handlerThread.quit();
+            cleanupCall(true /* verifyDeletion */ );
+            unregisterPhoneAccount();
+        }
+    }
+
+    public void testEnsureCallNotInserted() {
+        Cursor cursor = null;
+        try {
+            cursor = mContext.getContentResolver()
+                    .query(Calls.CONTENT_URI, null, Calls.NUMBER + " = ?",
+                            new String[]{PHONE_NUMBER}, null);
+            assertEquals(0, cursor.getCount());
+        } finally {
+            if (cursor != null) {
+                cursor.close();
+            }
+        }
+    }
+
+    public void testRegisterPhoneAccount() throws Exception {
+        registerPhoneAccount();
+    }
+
+    public void testUnregisterPhoneAccount() {
+        unregisterPhoneAccount();
+    }
+
+    public void testPhoneAccountNotRegistered() {
+        assertNull(mTelecomManager.getPhoneAccount(PHONE_ACCOUNT_HANDLE));
+    }
+
+    private void assertCalllogInserted(int type) {
+        Cursor cursor = null;
+        try {
+            final String connectionServiceComponentName = new ComponentName(mContext,
+                    DummyConnectionService.class).flattenToString();
+            cursor = mContext.getContentResolver()
+                    .query(Calls.CONTENT_URI, null,
+                            QUERY_CALL_THROUGH_OUR_CONNECTION_SERVICE + " AND " +
+                                    Calls.TYPE + " = ?",
+                            new String[]{PHONE_NUMBER, connectionServiceComponentName,
+                                    String.valueOf(type)}, null);
+            assertEquals(1, cursor.getCount());
+        } finally {
+            if (cursor != null) {
+                cursor.close();
+            }
+        }
+    }
+
+    private void cleanupCall(boolean verifyDeletion) {
+        final String connectionServiceComponentName = new ComponentName(mContext,
+                DummyConnectionService.class).flattenToString();
+        int numRowDeleted = mContext.getContentResolver()
+                .delete(Calls.CONTENT_URI, QUERY_CALL_THROUGH_OUR_CONNECTION_SERVICE,
+                        new String[]{PHONE_NUMBER, connectionServiceComponentName});
+        if (verifyDeletion) {
+            assertEquals(1, numRowDeleted);
+        }
+    }
+
+    private PhoneAccount registerPhoneAccount() throws Exception {
+        final PhoneAccount phoneAccount = PhoneAccount.builder(
+                PHONE_ACCOUNT_HANDLE,
+                "TelecomTestApp Call Provider")
+                .setAddress(Uri.parse("tel:555-TEST"))
+                .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
+                .setShortDescription("a short description for the call provider")
+                .setSupportedUriSchemes(Arrays.asList(PhoneAccount.SCHEME_TEL))
+                .build();
+        mTelecomManager.registerPhoneAccount(phoneAccount);
+        enablePhoneAccount(PHONE_ACCOUNT_HANDLE);
+        // make sure the registration is successful.
+        assertNotNull(mTelecomManager.getPhoneAccount(PHONE_ACCOUNT_HANDLE));
+        return phoneAccount;
+    }
+
+    private void unregisterPhoneAccount() {
+        mTelecomManager.unregisterPhoneAccount(PHONE_ACCOUNT_HANDLE);
+        assertNull(mTelecomManager.getPhoneAccount(PHONE_ACCOUNT_HANDLE));
+    }
+
+    /**
+     * Running adb command to enable phone account.
+     */
+    private void enablePhoneAccount(PhoneAccountHandle handle) throws Exception {
+        final ComponentName component = handle.getComponentName();
+        final UserManager userManager = (UserManager) mContext.getSystemService(
+                Context.USER_SERVICE);
+        executeShellCommand(COMMAND_ENABLE + " "
+                + component.getPackageName() + "/" + component.getClassName() + " "
+                + handle.getId() + " " + userManager
+                .getSerialNumberForUser(Process.myUserHandle()));
+    }
+
+    private String executeShellCommand(String command) throws Exception {
+        final ParcelFileDescriptor pfd =
+                mInstrumentation.getUiAutomation().executeShellCommand(command);
+        BufferedReader br = null;
+        try (InputStream in = new FileInputStream(pfd.getFileDescriptor())) {
+            br = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8));
+            String str;
+            StringBuilder out = new StringBuilder();
+            while ((str = br.readLine()) != null) {
+                out.append(str);
+            }
+            return out.toString();
+        } finally {
+            if (br != null) {
+                br.close();
+            }
+            pfd.close();
+        }
+    }
+
+    /**
+     * Observe the change of calllog provider.
+     */
+    private class CalllogContentObserver extends ContentObserver {
+
+        private final CountDownLatch mCountDownLatch;
+
+        public CalllogContentObserver(Handler handler, final CountDownLatch countDownLatch) {
+            super(handler);
+            mCountDownLatch = countDownLatch;
+        }
+
+        @Override
+        public void onChange(boolean selfChange, Uri uri) {
+            super.onChange(selfChange, uri);
+            mCountDownLatch.countDown();
+        }
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/PreManagedProfileTest.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/PreManagedProfileTest.java
new file mode 100644
index 0000000..99fd50d
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/PreManagedProfileTest.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.managedprofile;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.Context;
+import android.test.AndroidTestCase;
+
+public class PreManagedProfileTest extends AndroidTestCase {
+
+    protected DevicePolicyManager mDevicePolicyManager;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        mDevicePolicyManager = (DevicePolicyManager) mContext
+                .getSystemService(Context.DEVICE_POLICY_SERVICE);
+    }
+
+    public void testIsProvisioningAllowedTrue() {
+        assertTrue(mDevicePolicyManager
+                .isProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE));
+    }
+
+    public void testIsProvisioningAllowedFalse() {
+        assertFalse(mDevicePolicyManager
+                .isProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE));
+    }
+
+}
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/TrustAgentInfoTest.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/TrustAgentInfoTest.java
new file mode 100644
index 0000000..2e2a334
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/TrustAgentInfoTest.java
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.managedprofile;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.os.PersistableBundle;
+import android.test.MoreAsserts;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import static com.android.cts.managedprofile.TrustAgentInfoTest.AssertConfigMode.*;
+
+public class TrustAgentInfoTest extends BaseManagedProfileTest {
+    private static final String BUNDLE_KEY = "testing";
+    private static final String BUNDLE_PARENT_VALUE = "parent";
+    private static final String BUNDLE_CHILD_VALUE = "child";
+    private static final PersistableBundle CHILD_CONFIG = new PersistableBundle();
+    private static final PersistableBundle PARENT_CONFIG = new PersistableBundle();
+    private static final ComponentName TRUST_AGENT_COMPONENT =
+            new ComponentName("com.trustagent", "com.trustagent.xxx");
+
+    static {
+        CHILD_CONFIG.putString(BUNDLE_KEY, BUNDLE_CHILD_VALUE);
+        PARENT_CONFIG.putString(BUNDLE_KEY, BUNDLE_PARENT_VALUE);
+    }
+
+    enum AssertConfigMode {
+        ASSERT_PARENT_CONFIG, ASSERT_CHILD_CONFIG, ASSERT_BOTH
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        clearTrustAgentConfiguration(true /* isParent */);
+        clearTrustAgentConfiguration(false /* isParent */);
+        enableTrustAgents(true /* isParent */);
+        enableTrustAgents(false /* isParent */);
+        super.tearDown();
+    }
+
+    public void testSetAndGetTrustAgentConfiguration_child() {
+        setAndGetTrustAgentConfigurationInternal(false /* isParent */);
+    }
+
+    public void testSetAndGetTrustAgentConfiguration_parent() {
+        setAndGetTrustAgentConfigurationInternal(true /* isParent */);
+    }
+
+    public void testSetTrustAgentConfiguration_bothHaveTrustAgentConfigAndUnified() {
+        // Set both trust agents.
+        setTrustAgentConfiguration(false /* isParent */);
+        setTrustAgentConfiguration(true /* isParent */);
+
+        // Case when trust agents is not disabled
+        List<PersistableBundle> parentConfig =
+                mParentDevicePolicyManager.getTrustAgentConfiguration(
+                        null, TRUST_AGENT_COMPONENT);
+        List<PersistableBundle> childConfig = mDevicePolicyManager.getTrustAgentConfiguration(
+                null, TRUST_AGENT_COMPONENT);
+        assertNull(parentConfig);
+        assertNull(childConfig);
+
+        // Case when trust agents is disabled
+        disableTrustAgents(false /* isParent */);
+        disableTrustAgents(true /* isParent */);
+
+        parentConfig = mParentDevicePolicyManager.getTrustAgentConfiguration(
+                null, TRUST_AGENT_COMPONENT);
+        childConfig = mDevicePolicyManager.getTrustAgentConfiguration(
+                null, TRUST_AGENT_COMPONENT);
+        assertPersistableBundleListEquals(ASSERT_BOTH, parentConfig);
+        assertPersistableBundleListEquals(ASSERT_BOTH, childConfig);
+    }
+
+    public void testSetTrustAgentConfiguration_bothHaveTrustAgentConfigAndNonUnified() {
+        // Enable separate challenge for the managed profile.
+        mDevicePolicyManager.resetPassword("1234", 0);
+        // Set both trust agents.
+        setTrustAgentConfiguration(false /* isParent */);
+        setTrustAgentConfiguration(true /* isParent */);
+        disableTrustAgents(false /* isParent */);
+        disableTrustAgents(true /* isParent */);
+
+        List<PersistableBundle> parentConfig =
+                mParentDevicePolicyManager.getTrustAgentConfiguration(
+                        null, TRUST_AGENT_COMPONENT);
+        List<PersistableBundle> childConfig =
+                mDevicePolicyManager.getTrustAgentConfiguration(
+                        null, TRUST_AGENT_COMPONENT);
+        // Separate credential in managed profile, should only get its own config.
+        assertPersistableBundleListEquals(ASSERT_PARENT_CONFIG, parentConfig);
+        assertPersistableBundleListEquals(ASSERT_CHILD_CONFIG, childConfig);
+    }
+
+    private void setAndGetTrustAgentConfigurationInternal(boolean isParent) {
+        // Set the config
+        setTrustAgentConfiguration(isParent);
+        // Case when trust agents is not disabled
+        List<PersistableBundle> configs = getDevicePolicyManager(isParent)
+                .getTrustAgentConfiguration(null, TRUST_AGENT_COMPONENT);
+        assertNull(configs);
+        // Case when trust agents is disabled
+        disableTrustAgents(isParent);
+        configs = getDevicePolicyManager(isParent)
+                .getTrustAgentConfiguration(null, TRUST_AGENT_COMPONENT);
+        assertPersistableBundleListEquals(isParent ?
+                ASSERT_PARENT_CONFIG : ASSERT_CHILD_CONFIG, configs);
+    }
+
+    private void disableTrustAgents(boolean isParent) {
+        getDevicePolicyManager(isParent).setKeyguardDisabledFeatures(ADMIN_RECEIVER_COMPONENT,
+                DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS);
+    }
+
+    private void enableTrustAgents(boolean isParent) {
+        getDevicePolicyManager(isParent).setKeyguardDisabledFeatures(ADMIN_RECEIVER_COMPONENT,
+                DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_NONE);
+    }
+
+    private void clearTrustAgentConfiguration(boolean isParent) {
+        getDevicePolicyManager(isParent).setTrustAgentConfiguration(ADMIN_RECEIVER_COMPONENT,
+                TRUST_AGENT_COMPONENT, null);
+        assertNull(getDevicePolicyManager(isParent).getTrustAgentConfiguration(
+                ADMIN_RECEIVER_COMPONENT, TRUST_AGENT_COMPONENT));
+    }
+
+    private PersistableBundle setTrustAgentConfiguration(boolean isParent) {
+        PersistableBundle expected = isParent ? PARENT_CONFIG : CHILD_CONFIG;
+        getDevicePolicyManager(isParent).setTrustAgentConfiguration(ADMIN_RECEIVER_COMPONENT,
+                TRUST_AGENT_COMPONENT, expected);
+        List<PersistableBundle> configs =
+                getDevicePolicyManager(isParent).getTrustAgentConfiguration(
+                        ADMIN_RECEIVER_COMPONENT, TRUST_AGENT_COMPONENT);
+        assertPersistableBundleListEquals(isParent ?
+                ASSERT_PARENT_CONFIG :
+                ASSERT_CHILD_CONFIG, configs);
+        return expected;
+    }
+
+    private static void assertPersistableBundleListEquals(
+            AssertConfigMode mode, List<PersistableBundle> actual) {
+        Set<String> expectedValues = new HashSet<>();
+        switch (mode) {
+            case ASSERT_CHILD_CONFIG:
+                expectedValues.add(BUNDLE_CHILD_VALUE);
+                break;
+            case ASSERT_PARENT_CONFIG:
+                expectedValues.add(BUNDLE_PARENT_VALUE);
+                break;
+            case ASSERT_BOTH:
+                expectedValues.add(BUNDLE_PARENT_VALUE);
+                expectedValues.add(BUNDLE_CHILD_VALUE);
+                break;
+        }
+        assertNotNull(actual);
+        Set<String> actualValues = new HashSet<>();
+        for (PersistableBundle bundle : actual) {
+            actualValues.add(bundle.getString(BUNDLE_KEY));
+        }
+        MoreAsserts.assertEquals(expectedValues, actualValues);
+    }
+
+}
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/WifiTest.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/WifiTest.java
index c4c02e8..685ad82 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/WifiTest.java
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/WifiTest.java
@@ -44,7 +44,7 @@
     private static final String NETWORK_SSID = "com.android.cts.xwde7ktvh8rmjuhr";
 
     // Time duration to allow before assuming that a WiFi operation failed and ceasing to wait.
-    private static final long UPDATE_TIMEOUT_MS = TimeUnit.SECONDS.toMillis(30);
+    private static final long UPDATE_TIMEOUT_MS = TimeUnit.MINUTES.toMillis(5);
     private static final long UPDATE_INTERVAL_MS = TimeUnit.SECONDS.toMillis(1);
 
     // Shared WifiManager instance.
diff --git a/hostsidetests/devicepolicy/app/PackageInstaller/Android.mk b/hostsidetests/devicepolicy/app/PackageInstaller/Android.mk
index e68c884..5f2a64e 100644
--- a/hostsidetests/devicepolicy/app/PackageInstaller/Android.mk
+++ b/hostsidetests/devicepolicy/app/PackageInstaller/Android.mk
@@ -30,4 +30,7 @@
 
 LOCAL_SDK_VERSION := current
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/devicepolicy/app/PackageInstaller/src/com/android/cts/packageinstaller/ClearDeviceOwnerTest.java b/hostsidetests/devicepolicy/app/PackageInstaller/src/com/android/cts/packageinstaller/ClearDeviceOwnerTest.java
index a06271b..d4718df 100644
--- a/hostsidetests/devicepolicy/app/PackageInstaller/src/com/android/cts/packageinstaller/ClearDeviceOwnerTest.java
+++ b/hostsidetests/devicepolicy/app/PackageInstaller/src/com/android/cts/packageinstaller/ClearDeviceOwnerTest.java
@@ -52,10 +52,9 @@
 
     @Override
     protected void tearDown() throws Exception {
-        removeActiveAdmin(ADMIN_RECEIVER_COMPONENT);
         mDevicePolicyManager.clearDeviceOwnerApp(PACKAGE_NAME);
-        assertFalse(mDevicePolicyManager.isAdminActive(ADMIN_RECEIVER_COMPONENT));
         assertFalse(mDevicePolicyManager.isDeviceOwnerApp(PACKAGE_NAME));
+        waitForActiveAdminRemoved(ADMIN_RECEIVER_COMPONENT);
 
         super.tearDown();
     }
@@ -65,12 +64,10 @@
     public void testClearDeviceOwner() {
     }
 
-    private void removeActiveAdmin(ComponentName cn) throws InterruptedException {
-        if (mDevicePolicyManager.isAdminActive(cn)) {
-            mDevicePolicyManager.removeActiveAdmin(cn);
-            for (int i = 0; i < 1000 && mDevicePolicyManager.isAdminActive(cn); i++) {
-                Thread.sleep(100);
-            }
+    private void waitForActiveAdminRemoved(ComponentName cn) throws InterruptedException {
+        for (int i = 0; i < 1000 && mDevicePolicyManager.isAdminActive(cn); i++) {
+            Thread.sleep(100);
         }
+        assertFalse(mDevicePolicyManager.isAdminActive(cn));
     }
 }
diff --git a/hostsidetests/devicepolicy/app/PackageInstaller/src/com/android/cts/packageinstaller/ManualPackageInstallTest.java b/hostsidetests/devicepolicy/app/PackageInstaller/src/com/android/cts/packageinstaller/ManualPackageInstallTest.java
index 96affae..1bb797f 100644
--- a/hostsidetests/devicepolicy/app/PackageInstaller/src/com/android/cts/packageinstaller/ManualPackageInstallTest.java
+++ b/hostsidetests/devicepolicy/app/PackageInstaller/src/com/android/cts/packageinstaller/ManualPackageInstallTest.java
@@ -33,11 +33,11 @@
     private static final BySelector POPUP_BUTTON_SELECTOR = By
             .clazz(android.widget.Button.class.getName())
             .res("android:id/button1")
-            .pkg("com.google.android.packageinstaller");
-    private static final BySelector POPUP_TEXT_SELECTOR = By
-            .clazz(android.widget.TextView.class.getName())
-            .res("android:id/alertTitle")
-            .pkg("com.google.android.packageinstaller");
+            .pkg("com.android.settings");
+    private static final BySelector POPUP_IMAGE_SELECTOR = By
+            .clazz(android.widget.ImageView.class.getName())
+            .res("com.android.settings:id/admin_support_icon")
+            .pkg("com.android.settings");
     private static final BySelector INSTALL_BUTTON_SELECTOR = By
             .clazz(android.widget.Button.class.getName())
             .res("com.android.packageinstaller:id/ok_button")
@@ -106,9 +106,9 @@
     }
 
     private void automateDismissInstallBlockedDialog() {
-        mDevice.wait(Until.hasObject(POPUP_TEXT_SELECTOR), AUTOMATOR_WAIT_TIMEOUT);
-        UiObject2 text = mDevice.findObject(POPUP_TEXT_SELECTOR);
-        assertNotNull("Alert dialog not found", text);
+        mDevice.wait(Until.hasObject(POPUP_IMAGE_SELECTOR), AUTOMATOR_WAIT_TIMEOUT);
+        UiObject2 icon = mDevice.findObject(POPUP_IMAGE_SELECTOR);
+        assertNotNull("Policy transparency dialog icon not found", icon);
         // "OK" button only present in the dialog if it is blocked by policy.
         UiObject2 button = mDevice.findObject(POPUP_BUTTON_SELECTOR);
         assertNotNull("OK button not found", button);
diff --git a/hostsidetests/devicepolicy/app/ProfileOwner/Android.mk b/hostsidetests/devicepolicy/app/ProfileOwner/Android.mk
new file mode 100644
index 0000000..9d936d0
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/ProfileOwner/Android.mk
@@ -0,0 +1,36 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := CtsProfileOwnerApp
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_JAVA_LIBRARIES := android.test.runner cts-junit
+
+LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner compatibility-device-util ub-uiautomator
+
+LOCAL_SDK_VERSION := current
+
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/devicepolicy/app/ProfileOwner/AndroidManifest.xml b/hostsidetests/devicepolicy/app/ProfileOwner/AndroidManifest.xml
new file mode 100644
index 0000000..7d71942
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/ProfileOwner/AndroidManifest.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.cts.profileowner" >
+
+    <uses-sdk android:minSdkVersion="24"/>
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+        <receiver
+            android:name="com.android.cts.profileowner.BaseProfileOwnerTest$BasicAdminReceiver"
+            android:permission="android.permission.BIND_DEVICE_ADMIN">
+            <meta-data android:name="android.app.device_admin"
+                       android:resource="@xml/device_admin" />
+            <intent-filter>
+                <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
+            </intent-filter>
+        </receiver>
+    </application>
+
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="com.android.cts.profileowner"
+                     android:label="Profile Owner CTS tests"/>
+</manifest>
diff --git a/hostsidetests/devicepolicy/app/ProfileOwner/res/xml/device_admin.xml b/hostsidetests/devicepolicy/app/ProfileOwner/res/xml/device_admin.xml
new file mode 100644
index 0000000..ff086d6
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/ProfileOwner/res/xml/device_admin.xml
@@ -0,0 +1,4 @@
+<device-admin xmlns:android="http://schemas.android.com/apk/res/android" android:visible="false">
+    <uses-policies>
+    </uses-policies>
+</device-admin>
diff --git a/hostsidetests/devicepolicy/app/ProfileOwner/src/com/android/cts/profileowner/BaseProfileOwnerTest.java b/hostsidetests/devicepolicy/app/ProfileOwner/src/com/android/cts/profileowner/BaseProfileOwnerTest.java
new file mode 100644
index 0000000..f47f5a2
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/ProfileOwner/src/com/android/cts/profileowner/BaseProfileOwnerTest.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.profileowner;
+
+import android.app.admin.DeviceAdminReceiver;
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.test.AndroidTestCase;
+
+public abstract class BaseProfileOwnerTest extends AndroidTestCase {
+
+    public static class BasicAdminReceiver extends DeviceAdminReceiver {
+    }
+
+    public static final String PACKAGE_NAME = BaseProfileOwnerTest.class.getPackage().getName();
+
+    protected DevicePolicyManager mDevicePolicyManager;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        mDevicePolicyManager = (DevicePolicyManager)
+                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
+        assertProfileOwner(mDevicePolicyManager);
+    }
+
+    static void assertProfileOwner(DevicePolicyManager dpm) {
+        assertNotNull(dpm);
+        assertTrue(dpm.isAdminActive(getWho()));
+        assertTrue(dpm.isProfileOwnerApp(PACKAGE_NAME));
+    }
+
+    protected static ComponentName getWho() {
+        return new ComponentName(PACKAGE_NAME, BasicAdminReceiver.class.getName());
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/ProfileOwner/src/com/android/cts/profileowner/ClearProfileOwnerTest.java b/hostsidetests/devicepolicy/app/ProfileOwner/src/com/android/cts/profileowner/ClearProfileOwnerTest.java
new file mode 100644
index 0000000..2c7b240
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/ProfileOwner/src/com/android/cts/profileowner/ClearProfileOwnerTest.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.profileowner;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.test.AndroidTestCase;
+
+public class ClearProfileOwnerTest extends AndroidTestCase {
+
+    private DevicePolicyManager mDevicePolicyManager;
+
+    @Override
+    protected void tearDown() throws Exception {
+        mDevicePolicyManager = (DevicePolicyManager)
+                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
+        if (mDevicePolicyManager != null) {
+            if (mDevicePolicyManager.isProfileOwnerApp(BaseProfileOwnerTest.PACKAGE_NAME)) {
+                mDevicePolicyManager.clearProfileOwner(BaseProfileOwnerTest.getWho());
+            }
+            assertFalse(mDevicePolicyManager.isProfileOwnerApp(BaseProfileOwnerTest.PACKAGE_NAME));
+
+            waitForActiveAdminRemoved(BaseProfileOwnerTest.getWho());
+        }
+
+        super.tearDown();
+    }
+
+    // This test clears the profile owner and active admin on tearDown(). To be called from the host
+    // side test once a test case is finished.
+    public void testClearProfileOwner() {
+    }
+
+    private void waitForActiveAdminRemoved(ComponentName cn) throws InterruptedException {
+        for (int i = 0; i < 1000 && mDevicePolicyManager.isAdminActive(cn); i++) {
+            Thread.sleep(100);
+        }
+        assertFalse(mDevicePolicyManager.isAdminActive(cn));
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/ProfileOwner/src/com/android/cts/profileowner/WifiTest.java b/hostsidetests/devicepolicy/app/ProfileOwner/src/com/android/cts/profileowner/WifiTest.java
new file mode 100644
index 0000000..7520ea4
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/ProfileOwner/src/com/android/cts/profileowner/WifiTest.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.profileowner;
+
+public class WifiTest extends BaseProfileOwnerTest {
+    public void testGetWifiMacAddress() {
+        try {
+            mDevicePolicyManager.getWifiMacAddress(getWho());
+            fail("Profile owner shouldn't be able to get the MAC address");
+        } catch (SecurityException e) {
+            if (!e.getMessage().contains("for policy #-2")) {
+                fail("Unexpected exception message: " + e.getMessage());
+            }
+        }
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/SimpleApp/Android.mk b/hostsidetests/devicepolicy/app/SimpleApp/Android.mk
index eae0a4f..f755018 100644
--- a/hostsidetests/devicepolicy/app/SimpleApp/Android.mk
+++ b/hostsidetests/devicepolicy/app/SimpleApp/Android.mk
@@ -24,8 +24,14 @@
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_PACKAGE_NAME := CtsSimpleApp
 
 LOCAL_SDK_VERSION := current
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/devicepolicy/app/SimplePreMApp/Android.mk b/hostsidetests/devicepolicy/app/SimplePreMApp/Android.mk
index 7460552..0b7c625 100644
--- a/hostsidetests/devicepolicy/app/SimplePreMApp/Android.mk
+++ b/hostsidetests/devicepolicy/app/SimplePreMApp/Android.mk
@@ -30,4 +30,7 @@
 
 LOCAL_SDK_VERSION := 21
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/devicepolicy/app/VpnApp/Android.mk b/hostsidetests/devicepolicy/app/VpnApp/Android.mk
new file mode 100644
index 0000000..8963230
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/VpnApp/Android.mk
@@ -0,0 +1,34 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := CtsVpnFirewallApp
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_JAVA_LIBRARIES := android.test.runner
+
+LOCAL_SDK_VERSION := current
+
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/devicepolicy/app/VpnApp/AndroidManifest.xml b/hostsidetests/devicepolicy/app/VpnApp/AndroidManifest.xml
new file mode 100644
index 0000000..ea1a001
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/VpnApp/AndroidManifest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.cts.vpnfirewall">
+
+    <uses-sdk android:minSdkVersion="22"/>
+
+    <application>
+        <service android:name=".ReflectorVpnService"
+                android:permission="android.permission.BIND_VPN_SERVICE">
+            <intent-filter>
+                <action android:name="android.net.VpnService"/>
+            </intent-filter>
+        </service>
+    </application>
+
+</manifest>
diff --git a/hostsidetests/devicepolicy/app/VpnApp/src/com/android/cts/vpnfirewall/IcmpMessage.java b/hostsidetests/devicepolicy/app/VpnApp/src/com/android/cts/vpnfirewall/IcmpMessage.java
new file mode 100644
index 0000000..6304236
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/VpnApp/src/com/android/cts/vpnfirewall/IcmpMessage.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.vpnfirewall;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.Arrays;
+
+public class IcmpMessage {
+    int type;
+    int code;
+    long quench;
+    byte[] data;
+
+    IcmpMessage(DataInputStream stream, int length) throws IOException {
+        type = stream.readUnsignedByte();
+        code = stream.readUnsignedByte();
+        int checksum = stream.readUnsignedShort();
+        quench = stream.readInt() & 0xFFFFFFFFL;
+
+        int dataLength = length - 8;
+        data = new byte[dataLength];
+        int len = stream.read(data, 0, dataLength);
+        if (len != dataLength) {
+            throw new IOException("Expected " + dataLength + " data bytes, received " + len);
+        }
+
+        byte[] original = new byte[length];
+        stream.reset();
+        stream.readFully(original);
+        if (!Arrays.equals(original, getEncoded())) {
+            throw new IOException("Corrupted message. Checksum: " + checksum);
+        }
+    }
+
+    public byte[] getEncoded() throws IOException {
+        ByteArrayOutputStream output = new ByteArrayOutputStream();
+        DataOutputStream stream = new DataOutputStream(output);
+
+        stream.writeByte(type);
+        stream.writeByte(code);
+        int checksumPosition = stream.size();
+        stream.writeShort(/* checksum */ 0);
+        stream.writeInt((int) quench);
+        stream.write(data, 0, data.length);
+
+        byte[] result = output.toByteArray();
+        int checksum = Rfc1071.checksum(result, result.length);
+        result[checksumPosition + 0] = (byte) ((checksum & 0xFF00) >> 8);
+        result[checksumPosition + 1] = (byte) ((checksum & 0x00FF));
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder out = new StringBuilder(64);
+        out.append("ICMP payload {");
+        out.append("\n  Type:     "); out.append(type);
+        out.append("\n  Code:     "); out.append(code);
+        out.append("\n  Quench:   "); out.append(quench);
+        out.append("\n  Data: [");
+        for (int i = 0 ; i < data.length; i++) {
+            if (i % 16 == 0) {
+                out.append(String.format("\n%4s", ""));
+            }
+            if (Character.isLetter((char) data[i])) {
+                out.append(String.format(" %2c", (char) data[i]));
+            } else {
+                out.append(String.format(" %02X", data[i] & 0xFF));
+            }
+        }
+        out.append("\n  ]");
+        out.append("\n}");
+        return out.toString();
+    }
+}
+
diff --git a/hostsidetests/devicepolicy/app/VpnApp/src/com/android/cts/vpnfirewall/Ipv4Packet.java b/hostsidetests/devicepolicy/app/VpnApp/src/com/android/cts/vpnfirewall/Ipv4Packet.java
new file mode 100644
index 0000000..461da1a
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/VpnApp/src/com/android/cts/vpnfirewall/Ipv4Packet.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.vpnfirewall;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.net.Inet4Address;
+import java.util.Arrays;
+
+public class Ipv4Packet {
+    private static final int HEADER_MIN_LENGTH = 20;
+
+    int version;
+    int headerLength;
+    int type;
+    int totalLength;
+    int identification;
+    int flagsAndOffset;
+    int timeToLive;
+    int protocol;
+    Inet4Address sourceAddress;
+    Inet4Address destinationAddress;
+    byte[] options;
+    byte[] data;
+
+    public Ipv4Packet(DataInputStream stream) throws IOException {
+        int versionIhl = stream.readUnsignedByte();
+        version = (versionIhl & 0xF0) >> 4;
+        headerLength = (versionIhl & 0x0F) * 4;
+
+        type = stream.readUnsignedByte();
+        totalLength = stream.readUnsignedShort();
+        identification = stream.readUnsignedShort();
+        flagsAndOffset = stream.readUnsignedShort();
+        timeToLive = stream.readUnsignedByte();
+        protocol = stream.readUnsignedByte();
+        int checksum = stream.readUnsignedShort();
+
+        byte[] address = new byte[4];
+
+        stream.read(address, 0, address.length);
+        sourceAddress = (Inet4Address) Inet4Address.getByAddress(address);
+
+        stream.read(address, 0, address.length);
+        destinationAddress = (Inet4Address) Inet4Address.getByAddress(address);
+
+        if (headerLength < HEADER_MIN_LENGTH) {
+            throw new IllegalArgumentException("Header length = " + headerLength
+                    + " is less than HEADER_MIN_LENGTH = " + HEADER_MIN_LENGTH);
+        }
+        options = new byte[headerLength - HEADER_MIN_LENGTH];
+        stream.read(options, 0, options.length);
+
+        if (totalLength < headerLength) {
+            throw new IllegalArgumentException("Total length = " + totalLength
+                    + " is less than header length = " + headerLength);
+        }
+        data = new byte[totalLength - headerLength];
+        stream.read(data, 0, data.length);
+
+        byte[] original = new byte[totalLength];
+        stream.reset();
+        stream.readFully(original);
+        if (!Arrays.equals(original, getEncoded())) {
+            throw new IOException("Corrupted message. Checksum: " + checksum);
+        }
+    }
+
+    public void setOptions(byte[] newOptions) {
+        options = newOptions;
+        headerLength = HEADER_MIN_LENGTH + options.length;
+    }
+
+    public void setData(byte[] newData) {
+        data = newData;
+        totalLength = headerLength + data.length;
+    }
+
+    public byte[] getEncoded() throws IOException {
+        ByteArrayOutputStream output = new ByteArrayOutputStream();
+        DataOutputStream stream = new DataOutputStream(output);
+
+        stream.writeByte((version << 4) | (headerLength / 4));
+        stream.writeByte(type);
+        stream.writeShort(totalLength);
+        stream.writeShort(identification);
+        stream.writeShort(flagsAndOffset);
+        stream.writeByte(timeToLive);
+        stream.writeByte(protocol);
+
+        int checksumPosition = stream.size();
+        stream.writeShort(/* checksum */ 0);
+        stream.write(sourceAddress.getAddress(), 0, 4);
+        stream.write(destinationAddress.getAddress(), 0, 4);
+        stream.write(options, 0, options.length);
+        stream.write(data, 0, data.length);
+        stream.close();
+
+        byte[] result = output.toByteArray();
+        int checksum = Rfc1071.checksum(result, headerLength);
+        result[checksumPosition + 0] = (byte) ((checksum & 0xFF00) >> 8);
+        result[checksumPosition + 1] = (byte) ((checksum & 0x00FF));
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder out = new StringBuilder(256);
+
+        out.append("IPv4 Packet {");
+        out.append("\n  Version:        ").append(version);
+        out.append("\n  Header length:  ").append(headerLength);
+        out.append("\n  Type:           ").append(type);
+        out.append("\n  Total length:   ").append(totalLength);
+        out.append("\n  Identification: ").append(identification);
+        out.append("\n  Flags + offset: ").append(flagsAndOffset);
+        out.append("\n  Time to live:   ").append(timeToLive);
+        out.append("\n  Protocol:       ").append(protocol);
+        out.append("\n  Source:         ").append(sourceAddress.getHostAddress());
+        out.append("\n  Destination:    ").append(destinationAddress.getHostAddress());
+        out.append("\n  Options: [");
+        for (int i = 0 ; i < options.length; i++) {
+            if (i % 16 == 0) {
+                out.append(String.format("\n%4s", ""));
+            }
+            out.append(String.format(" %02X", options[i] & 0xFF));
+        }
+        out.append("\n  ]");
+        out.append("\n  Data: [");
+        for (int i = 0 ; i < data.length; i++) {
+            if (i % 16 == 0) {
+                out.append(String.format("\n%4s", ""));
+            }
+            out.append(String.format(" %02X", data[i] & 0xFF));
+        }
+        out.append("\n  ]");
+        out.append("\n}");
+        return out.toString();
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/VpnApp/src/com/android/cts/vpnfirewall/PingReflector.java b/hostsidetests/devicepolicy/app/VpnApp/src/com/android/cts/vpnfirewall/PingReflector.java
new file mode 100644
index 0000000..9ee1838
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/VpnApp/src/com/android/cts/vpnfirewall/PingReflector.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.vpnfirewall;
+
+import android.system.ErrnoException;
+import android.system.Os;
+import android.util.Log;
+
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.net.Inet4Address;
+
+public class PingReflector extends Thread {
+    private static final String TAG = "PingReflector";
+
+    private static final int PROTOCOL_ICMP = 0x01;
+
+    private FileDescriptor mFd;
+    private byte[] mBuf;
+
+    public PingReflector(FileDescriptor fd, int mtu) {
+        super("PingReflector");
+        mFd = fd;
+        mBuf = new byte[mtu];
+    }
+
+    public void run() {
+        Log.i(TAG, "PingReflector starting fd=" + mFd + " valid=" + mFd.valid());
+        while (!interrupted() && mFd.valid()) {
+            int len = readPacket(mBuf);
+            if (len > 0) {
+                int version = mBuf[0] >> 4;
+                if (version != 4) {
+                    Log.e(TAG, "Received packet version: " + version + ". Ignoring.");
+                    continue;
+                }
+                try {
+                    processPacket(mBuf, version, len, 0);
+                } catch (IOException e) {
+                    Log.w(TAG, "Failed processing packet", e);
+                }
+            }
+        }
+        Log.i(TAG, "PingReflector exiting fd=" + mFd + " valid=" + mFd.valid());
+    }
+
+    private void processPacket(byte[] buf, int version, int len, int hdrLen) throws IOException {
+        IcmpMessage echo = null;
+        IcmpMessage response = null;
+
+        DataInputStream stream = new DataInputStream(new ByteArrayInputStream(buf));
+        Ipv4Packet packet = new Ipv4Packet(stream);
+        Log.i(TAG, "Packet contents:\n" + packet);
+
+        if (packet.protocol != PROTOCOL_ICMP) {
+            Log.i(TAG, "Protocol is " + packet.protocol + " not ICMP. Ignoring.");
+            return;
+        }
+
+        echo = new IcmpMessage(
+                new DataInputStream(new ByteArrayInputStream(packet.data)), packet.data.length);
+        Log.i(TAG, "Ping packet:\n" + echo);
+
+        // Swap src and dst IP addresses to route the packet back into the device.
+        Inet4Address tmp = packet.sourceAddress;
+        packet.sourceAddress = packet.destinationAddress;
+        packet.destinationAddress = tmp;
+
+        packet.setData(echo.getEncoded());
+        writePacket(packet.getEncoded());
+        Log.i(TAG, "Wrote packet back");
+    }
+
+    private void writePacket(byte[] buf) {
+        try {
+            Os.write(mFd, buf, 0, buf.length);
+        } catch (ErrnoException | IOException e) {
+            Log.e(TAG, "Error writing packet: " + e.getMessage(), e);
+        }
+    }
+
+    private int readPacket(byte[] buf) {
+        try {
+            return Os.read(mFd, buf, 0, buf.length);
+        } catch (ErrnoException | IOException e) {
+            Log.e(TAG, "Error reading packet: " + e.getMessage(), e);
+            return -1;
+        }
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/VpnApp/src/com/android/cts/vpnfirewall/ReflectorVpnService.java b/hostsidetests/devicepolicy/app/VpnApp/src/com/android/cts/vpnfirewall/ReflectorVpnService.java
new file mode 100644
index 0000000..3d2c2ff
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/VpnApp/src/com/android/cts/vpnfirewall/ReflectorVpnService.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.vpnfirewall;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.net.VpnService;
+import android.os.Bundle;
+import android.os.ParcelFileDescriptor;
+import android.os.UserManager;
+import android.text.TextUtils;
+import android.util.Log;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+public class ReflectorVpnService extends VpnService {
+
+    private static String TAG = "ReflectorVpnService";
+    private static int MTU = 1799;
+
+    private ParcelFileDescriptor mFd = null;
+    private PingReflector mPingReflector = null;
+
+    public static final String RESTRICTION_ADDRESSES = "vpn.addresses";
+    public static final String RESTRICTION_ROUTES = "vpn.routes";
+    public static final String RESTRICTION_ALLOWED = "vpn.allowed";
+    public static final String RESTRICTION_DISALLOWED = "vpn.disallowed";
+
+    @Override
+    public int onStartCommand(Intent intent, int flags, int startId) {
+        start();
+        return START_NOT_STICKY;
+    }
+
+    @Override
+    public void onDestroy() {
+        stop();
+        super.onDestroy();
+    }
+
+    private void start() {
+        VpnService.prepare(this);
+        Builder builder = new Builder();
+
+        final UserManager um = (UserManager) getSystemService(Context.USER_SERVICE);
+        final Bundle restrictions = um.getApplicationRestrictions(getPackageName());
+
+        String[] addressArray = restrictions.getStringArray(RESTRICTION_ADDRESSES);
+        if (addressArray == null) {
+            // Addresses for IPv4/IPv6 documentation purposes according to rfc5737/rfc3849.
+            addressArray = new String[] {"192.0.2.3/32", "2001:db8:1:2::/128"};
+        };
+        for (int i = 0; i < addressArray.length; i++) {
+            String[] prefixAndMask = addressArray[i].split("/");
+            try {
+                InetAddress address = InetAddress.getByName(prefixAndMask[0]);
+                int prefixLength = Integer.parseInt(prefixAndMask[1]);
+                builder.addAddress(address, prefixLength);
+            } catch (NumberFormatException | UnknownHostException e) {
+                Log.w(TAG, "Ill-formed address: " + addressArray[i]);
+                continue;
+            }
+        }
+
+        String[] routeArray = restrictions.getStringArray(RESTRICTION_ROUTES);
+        if (routeArray == null) {
+            routeArray = new String[] {"0.0.0.0/0", "::/0"};
+        }
+        for (int i = 0; i < routeArray.length; i++) {
+            String[] prefixAndMask = routeArray[i].split("/");
+            try {
+                InetAddress address = InetAddress.getByName(prefixAndMask[0]);
+                int prefixLength = Integer.parseInt(prefixAndMask[1]);
+                builder.addRoute(address, prefixLength);
+            } catch (NumberFormatException | UnknownHostException e) {
+                Log.w(TAG, "Ill-formed route: " + routeArray[i]);
+                continue;
+            }
+        }
+
+        String[] allowedArray = restrictions.getStringArray(RESTRICTION_ALLOWED);
+        if (allowedArray != null) {
+            for (int i = 0; i < allowedArray.length; i++) {
+                String allowedPackage = allowedArray[i];
+                if (!TextUtils.isEmpty(allowedPackage)) {
+                    try {
+                        builder.addAllowedApplication(allowedPackage);
+                    } catch(NameNotFoundException e) {
+                        Log.w(TAG, "Allowed package not found: " + allowedPackage);
+                        continue;
+                    }
+                }
+            }
+        }
+
+        String[] disallowedArray = restrictions.getStringArray(RESTRICTION_DISALLOWED);
+        if (disallowedArray != null) {
+            for (int i = 0; i < disallowedArray.length; i++) {
+                String disallowedPackage = disallowedArray[i];
+                if (!TextUtils.isEmpty(disallowedPackage)) {
+                    try {
+                        builder.addDisallowedApplication(disallowedPackage);
+                    } catch(NameNotFoundException e) {
+                        Log.w(TAG, "Disallowed package not found: " + disallowedPackage);
+                        continue;
+                    }
+                }
+            }
+        }
+
+        builder.setMtu(MTU);
+        builder.setBlocking(true);
+        builder.setSession(TAG);
+
+        mFd = builder.establish();
+        if (mFd == null) {
+            Log.e(TAG, "Unable to establish file descriptor for VPN connection");
+            return;
+        }
+        Log.i(TAG, "Established, fd=" + mFd.getFd());
+
+        mPingReflector = new PingReflector(mFd.getFileDescriptor(), MTU);
+        mPingReflector.start();
+    }
+
+    private void stop() {
+        if (mPingReflector != null) {
+            mPingReflector.interrupt();
+            mPingReflector = null;
+        }
+        try {
+            if (mFd != null) {
+                Log.i(TAG, "Closing filedescriptor");
+                mFd.close();
+            }
+        } catch(IOException e) {
+            Log.w(TAG, "Closing filedescriptor failed", e);
+        } finally {
+            mFd = null;
+        }
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/VpnApp/src/com/android/cts/vpnfirewall/Rfc1071.java b/hostsidetests/devicepolicy/app/VpnApp/src/com/android/cts/vpnfirewall/Rfc1071.java
new file mode 100644
index 0000000..dbdf9f2
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/VpnApp/src/com/android/cts/vpnfirewall/Rfc1071.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.vpnfirewall;
+
+public final class Rfc1071 {
+    static int checksum(byte[] data, int length) {
+        int sum = 0;
+
+        // High bytes (even indices)
+        for (int i = 0; i < length; i += 2) {
+            sum += (data[i] & 0xFF) << 8;
+            sum = (sum & 0xFFFF) + (sum >> 16);
+        }
+
+        // Low bytes (odd indices)
+        for (int i = 1; i < length; i += 2) {
+            sum += (data[i] & 0xFF);
+            sum = (sum & 0xFFFF) + (sum >> 16);
+        }
+
+        // Fix any one's-complement errors- sometimes it is necessary to rotate twice.
+        sum = (sum & 0xFFFF) + (sum >> 16);
+        return sum ^ 0xFFFF;
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/WidgetProvider/Android.mk b/hostsidetests/devicepolicy/app/WidgetProvider/Android.mk
index c0e35fa..5e5db1e 100644
--- a/hostsidetests/devicepolicy/app/WidgetProvider/Android.mk
+++ b/hostsidetests/devicepolicy/app/WidgetProvider/Android.mk
@@ -26,4 +26,7 @@
 
 LOCAL_SDK_VERSION := current
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/devicepolicy/app/WifiConfigCreator/Android.mk b/hostsidetests/devicepolicy/app/WifiConfigCreator/Android.mk
index 47db44e..699b476 100644
--- a/hostsidetests/devicepolicy/app/WifiConfigCreator/Android.mk
+++ b/hostsidetests/devicepolicy/app/WifiConfigCreator/Android.mk
@@ -26,8 +26,11 @@
 
 LOCAL_PACKAGE_NAME := CtsWifiConfigCreator
 
-LOCAL_STATIC_JAVA_LIBRARIES := compatibility-device-util_v2
+LOCAL_STATIC_JAVA_LIBRARIES := compatibility-device-util
 
 LOCAL_SDK_VERSION := current
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDeviceAdminHostSideTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDeviceAdminHostSideTest.java
new file mode 100644
index 0000000..05f6b72
--- /dev/null
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDeviceAdminHostSideTest.java
@@ -0,0 +1,193 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.devicepolicy;
+
+import com.android.tradefed.device.DeviceNotAvailableException;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+/**
+ * Base class for DeviceAdmin host side tests.
+ *
+ * We have subclasses for device admins for different API levels.
+ */
+public abstract class BaseDeviceAdminHostSideTest extends BaseDevicePolicyTest {
+
+    private static final String ADMIN_RECEIVER_TEST_CLASS = "BaseDeviceAdminTest$AdminReceiver";
+
+    private static final String UNPROTECTED_ADMIN_RECEIVER_TEST_CLASS =
+            "DeviceAdminReceiverWithNoProtection";
+
+    protected int mUserId;
+
+    private boolean mClearDeviceOwnerInTearDown;
+    private boolean mDeactivateInTearDown;
+
+    /** returns "com.android.cts.deviceadmin" */
+    protected final String getDeviceAdminJavaPackage() {
+        return "com.android.cts.deviceadmin";
+    }
+
+    /** e.g. 23, 24, etc. */
+    protected abstract int getTargetApiVersion();
+
+    /** e.g. CtsDeviceAdminApp24.apk */
+    protected final String getDeviceAdminApkFileName() {
+        return "CtsDeviceAdminApp" + getTargetApiVersion() + ".apk";
+    }
+
+    /** e.g. "com.android.cts.deviceadmin24" */
+    protected final String getDeviceAdminApkPackage() {
+        return getDeviceAdminJavaPackage() + getTargetApiVersion();
+    }
+
+    /**
+     * e.g.
+     * "com.android.cts.deviceadmin24/com.android.cts.deviceadmin.BaseDeviceAdminTest$AdminReceiver"
+     */
+    protected final String getAdminReceiverComponent() {
+        return getDeviceAdminApkPackage() + "/" + getDeviceAdminJavaPackage() + "." +
+                ADMIN_RECEIVER_TEST_CLASS;
+    }
+
+    /**
+     * e.g.
+     * "com.android.cts.deviceadmin24/com.android.cts.deviceadmin.DeviceAdminReceiverWithNoProtection"
+     */
+    protected final String getUnprotectedAdminReceiverComponent() {
+        return getDeviceAdminApkPackage() + "/" + getDeviceAdminJavaPackage() + "." +
+                UNPROTECTED_ADMIN_RECEIVER_TEST_CLASS;
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        mUserId = mPrimaryUserId;
+
+        mClearDeviceOwnerInTearDown = false;
+        mDeactivateInTearDown = false;
+
+        if (mHasFeature) {
+            installAppAsUser(getDeviceAdminApkFileName(), mUserId);
+            setDeviceAdmin(getAdminReceiverComponent(), mUserId);
+        }
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        if (mHasFeature) {
+            if (mClearDeviceOwnerInTearDown) {
+                runTests(getDeviceAdminApkPackage(), "ClearDeviceOwnerTest");
+            }
+            if (mDeactivateInTearDown) {
+                runTests(getDeviceAdminApkPackage(), "ClearDeviceAdminTest");
+            }
+            getDevice().uninstallPackage(getDeviceAdminApkPackage());
+        }
+
+        super.tearDown();
+    }
+
+    protected boolean runTests(@Nonnull String apk, @Nonnull String className,
+            @Nullable String method) throws DeviceNotAvailableException {
+        return runDeviceTestsAsUser(apk,
+                getDeviceAdminJavaPackage() + "." + className, method, mUserId);
+    }
+
+    protected boolean runTests(@Nonnull String apk, @Nonnull String className)
+            throws DeviceNotAvailableException {
+        return runTests(apk, className, null);
+    }
+
+    /**
+     * Run all tests in DeviceAdminTest.java (as device admin).
+     */
+    public void testRunDeviceAdminTest() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+
+        mDeactivateInTearDown = true;
+
+        assertTrue("Some of device side tests failed",
+                runTests(getDeviceAdminApkPackage(), "DeviceAdminTest"));
+    }
+
+    private void clearPasswordForDeviceOwner() throws Exception {
+        assertTrue("Failed to clear password",
+                runTests(getDeviceAdminApkPackage(), "ClearPasswordTest"));
+    }
+
+    private void makeDoAndClearPassword() throws Exception {
+        // Clear the password.  We do it by promoting the DA to DO.
+        setDeviceOwner(getAdminReceiverComponent(), mUserId);
+
+        clearPasswordForDeviceOwner();
+
+        assertTrue("Failed to clear device owner",
+                runTests(getDeviceAdminApkPackage(), "ClearDeviceOwnerTest"));
+
+        // Clearing DO removes the DA too, so we need to set it again.
+        setDeviceAdmin(getAdminReceiverComponent(), mUserId);
+    }
+
+    /**
+     * Run the tests in DeviceAdminPasswordTest.java (as device admin).
+     */
+    private void testRunDeviceAdminPasswordTest(String method) throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+
+        mDeactivateInTearDown = true;
+
+        // If there's a password, clear it.
+        makeDoAndClearPassword();
+        try {
+            assertTrue(runTests(getDeviceAdminApkPackage(), "DeviceAdminPasswordTest", method));
+        } finally {
+            makeDoAndClearPassword();
+        }
+    }
+
+    public void testResetPassword_nycRestrictions() throws Exception {
+        testRunDeviceAdminPasswordTest("testResetPassword_nycRestrictions");
+    }
+
+    /**
+     * Run the tests in DeviceOwnerPasswordTest.java (as device owner).
+     */
+    public void testRunDeviceOwnerPasswordTest() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+
+        mClearDeviceOwnerInTearDown = true;
+
+        setDeviceOwner(getAdminReceiverComponent(), mUserId);
+
+        clearPasswordForDeviceOwner();
+
+        try {
+            assertTrue("Some of device side tests failed",
+                    runTests(getDeviceAdminApkPackage(), "DeviceOwnerPasswordTest"));
+        } finally {
+            clearPasswordForDeviceOwner();
+        }
+    }
+}
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
index 4fc14e4..b5e7f5d 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
@@ -16,7 +16,7 @@
 
 package com.android.cts.devicepolicy;
 
-import com.android.cts.tradefed.build.CtsBuildHelper;
+import com.android.cts.migration.MigrationHelper;
 import com.android.ddmlib.Log.LogLevel;
 import com.android.ddmlib.testrunner.InstrumentationResultParser;
 import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
@@ -35,8 +35,12 @@
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
 import java.util.HashSet;
 import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import javax.annotation.Nullable;
 
@@ -48,15 +52,40 @@
 
     private static final String RUNNER = "android.support.test.runner.AndroidJUnitRunner";
 
-    protected CtsBuildHelper mCtsBuild;
+    protected static final int USER_SYSTEM = 0; // From the UserHandle class.
+
+    protected static final int USER_OWNER = 0;
+
+    // From the UserInfo class
+    protected static final int FLAG_PRIMARY = 0x00000001;
+    protected static final int FLAG_GUEST = 0x00000004;
+    protected static final int FLAG_EPHEMERAL = 0x00000100;
+
+    protected static interface Settings {
+        public static final String GLOBAL_NAMESPACE = "global";
+        public static interface Global {
+            public static final String DEVICE_PROVISIONED = "device_provisioned";
+        }
+    }
+
+    protected IBuildInfo mCtsBuild;
 
     private String mPackageVerifier;
     private HashSet<String> mAvailableFeatures;
+
+    /** Whether DPM is supported. */
     protected boolean mHasFeature;
+    protected int mPrimaryUserId;
+
+    /** Whether multi-user is supported. */
+    protected boolean mSupportsMultiUser;
+
+    /** Users we shouldn't delete in the tests */
+    private ArrayList<Integer> mFixedUsers;
 
     @Override
     public void setBuild(IBuildInfo buildInfo) {
-        mCtsBuild = CtsBuildHelper.createBuildHelper(buildInfo);
+        mCtsBuild = buildInfo;
     }
 
     @Override
@@ -65,10 +94,21 @@
         assertNotNull(mCtsBuild);  // ensure build has been set before test is run.
         mHasFeature = getDevice().getApiLevel() >= 21 /* Build.VERSION_CODES.L */
                 && hasDeviceFeature("android.software.device_admin");
+        mSupportsMultiUser = getMaxNumberOfUsersSupported() > 1;
+
         // disable the package verifier to avoid the dialog when installing an app
         mPackageVerifier = getDevice().executeShellCommand(
                 "settings get global package_verifier_enable");
         getDevice().executeShellCommand("settings put global package_verifier_enable 0");
+
+        mFixedUsers = new ArrayList();
+        mPrimaryUserId = getPrimaryUser();
+        mFixedUsers.add(mPrimaryUserId);
+        if (mPrimaryUserId != USER_SYSTEM) {
+            mFixedUsers.add(USER_SYSTEM);
+        }
+        switchUser(mPrimaryUserId);
+        removeTestUsers();
     }
 
     @Override
@@ -76,141 +116,112 @@
         // reset the package verifier setting to its original value
         getDevice().executeShellCommand("settings put global package_verifier_enable "
                 + mPackageVerifier);
+        removeTestUsers();
         super.tearDown();
     }
 
-    protected void installApp(String fileName)
-            throws FileNotFoundException, DeviceNotAvailableException {
-        CLog.logAndDisplay(LogLevel.INFO, "Installing app " + fileName);
-        String installResult = getDevice().installPackage(mCtsBuild.getTestApp(fileName), true);
-        assertNull(String.format("Failed to install %s, Reason: %s", fileName, installResult),
-                installResult);
-    }
-
     protected void installAppAsUser(String appFileName, int userId) throws FileNotFoundException,
             DeviceNotAvailableException {
-        final ITestDevice device = getDevice();
+        installAppAsUser(appFileName, true, userId);
+    }
 
-        final File apk = mCtsBuild.getTestApp(appFileName);
-        final String remotePath = "/data/local/tmp/" + apk.getName();
-        if (!device.pushFile(apk, remotePath)) {
-            throw new IllegalStateException("Failed to push " + apk);
-        }
-
-        final String result = device.executeShellCommand(
-                "pm install -r --user " + userId + " " + remotePath);
-        assertTrue(result, result.contains("\nSuccess"));
+    protected void installAppAsUser(String appFileName, boolean grantPermissions, int userId)
+            throws FileNotFoundException, DeviceNotAvailableException {
+        CLog.logAndDisplay(LogLevel.INFO, "Installing app " + appFileName + " for user " + userId);
+        String result = getDevice().installPackageForUser(
+                MigrationHelper.getTestFile(mCtsBuild, appFileName), true, grantPermissions,
+                userId);
+        assertNull("Failed to install " + appFileName + " for user " + userId + ": " + result,
+                result);
     }
 
     /** Initializes the user with the given id. This is required so that apps can run on it. */
     protected void startUser(int userId) throws Exception {
-        String command = "am start-user " + userId;
+        getDevice().startUser(userId);
+    }
+
+    protected void switchUser(int userId) throws Exception {
+        // TODO Move this logic to ITestDevice
+        String command = "am switch-user " + userId;
         CLog.logAndDisplay(LogLevel.INFO, "Starting command " + command);
         String commandOutput = getDevice().executeShellCommand(command);
         CLog.logAndDisplay(LogLevel.INFO, "Output for command " + command + ": " + commandOutput);
-        assertTrue(commandOutput + " expected to start with \"Success:\"",
-                commandOutput.startsWith("Success:"));
     }
 
     protected int getMaxNumberOfUsersSupported() throws DeviceNotAvailableException {
-        // TODO: move this to ITestDevice once it supports users
-        String command = "pm get-max-users";
-        String commandOutput = getDevice().executeShellCommand(command);
-        CLog.i("Output for command " + command + ": " + commandOutput);
-
-        try {
-            return Integer.parseInt(commandOutput.substring(commandOutput.lastIndexOf(" ")).trim());
-        } catch (NumberFormatException e) {
-            fail("Failed to parse result: " + commandOutput);
-        }
-        return 0;
+        return getDevice().getMaxNumberOfUsersSupported();
     }
 
-    protected ArrayList<Integer> listUsers() throws DeviceNotAvailableException {
+    protected int getUserFlags(int userId) throws DeviceNotAvailableException {
         String command = "pm list users";
         String commandOutput = getDevice().executeShellCommand(command);
         CLog.i("Output for command " + command + ": " + commandOutput);
 
-        // Extract the id of all existing users.
         String[] lines = commandOutput.split("\\r?\\n");
         assertTrue(commandOutput + " should contain at least one line", lines.length >= 1);
-        assertEquals(commandOutput, lines[0], "Users:");
-
-        ArrayList<Integer> users = new ArrayList<Integer>();
         for (int i = 1; i < lines.length; i++) {
             // Individual user is printed out like this:
             // \tUserInfo{$id$:$name$:$Integer.toHexString(flags)$} [running]
             String[] tokens = lines[i].split("\\{|\\}|:");
             assertTrue(lines[i] + " doesn't contain 4 or 5 tokens",
                     tokens.length == 4 || tokens.length == 5);
-            users.add(Integer.parseInt(tokens[1]));
+            // If the user IDs match, return the flags.
+            if (Integer.parseInt(tokens[1]) == userId) {
+                return Integer.parseInt(tokens[3], 16);
+            }
         }
-        return users;
+        fail("User not found");
+        return 0;
     }
 
-    protected void removeUser(int userId) throws Exception  {
-        String stopUserCommand = "am stop-user -w " + userId;
+    protected ArrayList<Integer> listUsers() throws DeviceNotAvailableException {
+        return getDevice().listUsers();
+    }
+
+    protected void stopUser(int userId) throws Exception  {
+        String stopUserCommand = "am stop-user -w -f " + userId;
         CLog.logAndDisplay(LogLevel.INFO, "starting command \"" + stopUserCommand + "\" and waiting.");
         CLog.logAndDisplay(LogLevel.INFO, "Output for command " + stopUserCommand + ": "
                 + getDevice().executeShellCommand(stopUserCommand));
-        String removeUserCommand = "pm remove-user " + userId;
-        CLog.logAndDisplay(LogLevel.INFO, "starting command " + removeUserCommand);
-        CLog.logAndDisplay(LogLevel.INFO, "Output for command " + removeUserCommand + ": "
-                + getDevice().executeShellCommand(removeUserCommand));
+    }
+
+    protected void removeUser(int userId) throws Exception  {
+        if (listUsers().contains(userId) && userId != USER_SYSTEM) {
+            stopUser(userId);
+            assertTrue("Couldn't remove user", getDevice().removeUser(userId));
+        }
     }
 
     protected void removeTestUsers() throws Exception {
         for (int userId : listUsers()) {
-            if (userId != 0) {
+            if (!mFixedUsers.contains(userId)) {
                 removeUser(userId);
             }
         }
     }
 
-    /** Returns true if the specified tests passed. Tests are run as user owner. */
-    protected boolean runDeviceTests(String pkgName, @Nullable String testClassName)
-            throws DeviceNotAvailableException {
-        return runDeviceTests(pkgName, testClassName, null /*testMethodName*/, null /*userId*/);
-    }
-
     /** Returns true if the specified tests passed. Tests are run as given user. */
     protected boolean runDeviceTestsAsUser(
             String pkgName, @Nullable String testClassName, int userId)
             throws DeviceNotAvailableException {
-        return runDeviceTestsAsUser(pkgName, testClassName, null, userId);
+        return runDeviceTestsAsUser(pkgName, testClassName, null /*testMethodName*/, userId);
     }
 
     /** Returns true if the specified tests passed. Tests are run as given user. */
     protected boolean runDeviceTestsAsUser(
             String pkgName, @Nullable String testClassName, String testMethodName, int userId)
             throws DeviceNotAvailableException {
-        return runDeviceTests(pkgName, testClassName, testMethodName, userId);
+        Map<String, String> params = Collections.emptyMap();
+        return runDeviceTestsAsUser(pkgName, testClassName, testMethodName, userId, params);
     }
 
-    protected boolean runDeviceTests(String pkgName, @Nullable String testClassName,
-            @Nullable String testMethodName, @Nullable Integer userId)
-            throws DeviceNotAvailableException {
-        return runDeviceTests(pkgName, testClassName, testMethodName, userId, /*params*/ null);
-    }
-
-    protected boolean runDeviceTests(String pkgName, @Nullable String testClassName,
-            @Nullable String testMethodName, @Nullable Integer userId, @Nullable String params)
-                   throws DeviceNotAvailableException {
+    protected boolean runDeviceTestsAsUser(String pkgName, @Nullable String testClassName,
+            @Nullable String testMethodName, int userId,
+            Map<String, String> params) throws DeviceNotAvailableException {
         if (testClassName != null && testClassName.startsWith(".")) {
             testClassName = pkgName + testClassName;
         }
-        TestRunResult runResult = (userId == null && params == null)
-                ? doRunTests(pkgName, testClassName, testMethodName)
-                : doRunTestsAsUser(pkgName, testClassName, testMethodName,
-                        userId != null ? userId : 0, params != null ? params : "");
-        printTestResult(runResult);
-        return !runResult.hasFailedTests() && runResult.getNumTestsInState(TestStatus.PASSED) > 0;
-    }
 
-    /** Helper method to run tests and return the listener that collected the results. */
-    private TestRunResult doRunTests(
-            String pkgName, String testClassName,
-            String testMethodName) throws DeviceNotAvailableException {
         RemoteAndroidTestRunner testRunner = new RemoteAndroidTestRunner(
                 pkgName, RUNNER, getDevice().getIDevice());
         if (testClassName != null && testMethodName != null) {
@@ -219,32 +230,46 @@
             testRunner.setClassName(testClassName);
         }
 
+        for (Map.Entry<String, String> param : params.entrySet()) {
+            testRunner.addInstrumentationArg(param.getKey(), param.getValue());
+        }
+
         CollectingTestListener listener = new CollectingTestListener();
-        assertTrue(getDevice().runInstrumentationTests(testRunner, listener));
-        return listener.getCurrentRunResults();
+        assertTrue(getDevice().runInstrumentationTestsAsUser(testRunner, userId, listener));
+
+        TestRunResult runResult = listener.getCurrentRunResults();
+        printTestResult(runResult);
+        return !runResult.hasFailedTests() && runResult.getNumTestsInState(TestStatus.PASSED) > 0;
     }
 
-    private TestRunResult doRunTestsAsUser(String pkgName, @Nullable String testClassName,
-            @Nullable String testMethodName, int userId, String params)
-            throws DeviceNotAvailableException {
-        // TODO: move this to RemoteAndroidTestRunner once it supports users. Should be straight
-        // forward to add a RemoteAndroidTestRunner.setUser(userId) method. Then we can merge both
-        // doRunTests* methods.
-        StringBuilder testsToRun = new StringBuilder();
-        if (testClassName != null) {
-            testsToRun.append("-e class " + testClassName);
-            if (testMethodName != null) {
-                testsToRun.append("#" + testMethodName);
-            }
-        }
-        String command = "am instrument --user " + userId + " " + params + " -w -r "
-                + testsToRun + " " + pkgName + "/" + RUNNER;
-        CLog.i("Running " + command);
+    /** Returns true if the system supports the split between system and primary user. */
+    protected boolean hasUserSplit() throws DeviceNotAvailableException {
+        return getBooleanSystemProperty("ro.fw.system_user_split", false);
+    }
 
-        CollectingTestListener listener = new CollectingTestListener();
-        InstrumentationResultParser parser = new InstrumentationResultParser(pkgName, listener);
-        getDevice().executeShellCommand(command, parser);
-        return listener.getCurrentRunResults();
+    /** Returns a boolean value of the system property with the specified key. */
+    protected boolean getBooleanSystemProperty(String key, boolean defaultValue)
+            throws DeviceNotAvailableException {
+        final String[] positiveValues = {"1", "y", "yes", "true", "on"};
+        final String[] negativeValues = {"0", "n", "no", "false", "off"};
+        String propertyValue = getDevice().getProperty(key);
+        if (propertyValue == null || propertyValue.isEmpty()) {
+            return defaultValue;
+        }
+        if (Arrays.asList(positiveValues).contains(propertyValue)) {
+            return true;
+        }
+        if (Arrays.asList(negativeValues).contains(propertyValue)) {
+            return false;
+        }
+        fail("Unexpected value of boolean system property '" + key + "': " + propertyValue);
+        return false;
+    }
+
+    /** Checks whether it is possible to create the desired number of users. */
+    protected boolean canCreateAdditionalUsers(int numberOfUsers)
+            throws DeviceNotAvailableException {
+        return listUsers().size() + numberOfUsers <= getMaxNumberOfUsersSupported();
     }
 
     private void printTestResult(TestRunResult runResult) {
@@ -286,7 +311,15 @@
     }
 
     protected int createUser() throws Exception {
-        String command ="pm create-user TestUser_"+ System.currentTimeMillis();
+        return createUser(0);
+    }
+
+    protected int createUser(int flags) throws Exception {
+        boolean guest = FLAG_GUEST == (flags & FLAG_GUEST);
+        boolean ephemeral = FLAG_EPHEMERAL == (flags & FLAG_EPHEMERAL);
+        // TODO Use ITestDevice.createUser() when guest and ephemeral is available
+        String command ="pm create-user " + (guest ? "--guest " : "")
+                + (ephemeral ? "--ephemeral " : "") + "TestUser_" + System.currentTimeMillis();
         CLog.logAndDisplay(LogLevel.INFO, "Starting command " + command);
         String commandOutput = getDevice().executeShellCommand(command);
         CLog.logAndDisplay(LogLevel.INFO, "Output for command " + command + ": " + commandOutput);
@@ -298,9 +331,9 @@
         return Integer.parseInt(tokens[tokens.length-1]);
     }
 
-    protected int createManagedProfile() throws DeviceNotAvailableException {
-        String command =
-                "pm create-user --profileOf 0 --managed TestProfile_" + System.currentTimeMillis();
+    protected int createManagedProfile(int parentUserId) throws DeviceNotAvailableException {
+        String command = "pm create-user --profileOf " + parentUserId + " --managed "
+                + "TestProfile_" + System.currentTimeMillis();
         CLog.logAndDisplay(LogLevel.INFO, "Starting command " + command);
         String commandOutput = getDevice().executeShellCommand(command);
         CLog.logAndDisplay(LogLevel.INFO, "Output for command " + command + ": " + commandOutput);
@@ -313,7 +346,12 @@
         return Integer.parseInt(tokens[tokens.length-1]);
     }
 
+    protected int getPrimaryUser() throws DeviceNotAvailableException {
+        return getDevice().getPrimaryUserId();
+    }
+
     protected int getUserSerialNumber(int userId) throws DeviceNotAvailableException{
+        // TODO: Move this logic to ITestDevice.
         // dumpsys user return lines like "UserInfo{0:Owner:13} serialNo=0"
         String commandOutput = getDevice().executeShellCommand("dumpsys user");
         String[] tokens = commandOutput.split("\\n");
@@ -348,16 +386,33 @@
         }
     }
 
-    protected void setDeviceAdmin(String componentName) throws DeviceNotAvailableException {
-        String command = "dpm set-active-admin '" + componentName + "'";
+    private String setDeviceAdminInner(String componentName, int userId)
+            throws DeviceNotAvailableException {
+        String command = "dpm set-active-admin --user " + userId + " '" + componentName + "'";
         String commandOutput = getDevice().executeShellCommand(command);
-        CLog.logAndDisplay(LogLevel.INFO, "Output for command " + command + ": " + commandOutput);
+        return commandOutput;
+    }
+
+    protected void setDeviceAdmin(String componentName, int userId)
+            throws DeviceNotAvailableException {
+        String commandOutput = setDeviceAdminInner(componentName, userId);
+        CLog.logAndDisplay(LogLevel.INFO, "Output for command " + commandOutput
+                + ": " + commandOutput);
         assertTrue(commandOutput + " expected to start with \"Success:\"",
                 commandOutput.startsWith("Success:"));
     }
 
-    protected boolean setDeviceOwner(String componentName) throws DeviceNotAvailableException {
-        String command = "dpm set-device-owner '" + componentName + "'";
+    protected void setDeviceAdminExpectingFailure(String componentName, int userId,
+            String errorMessage) throws DeviceNotAvailableException {
+        String commandOutput = setDeviceAdminInner(componentName, userId);
+        if (!commandOutput.contains(errorMessage)) {
+            fail(commandOutput + " expected to contain \"" + errorMessage + "\"");
+        }
+    }
+
+    protected boolean setDeviceOwner(String componentName, int userId)
+            throws DeviceNotAvailableException {
+        String command = "dpm set-device-owner --user " + userId + " '" + componentName + "'";
         String commandOutput = getDevice().executeShellCommand(command);
         CLog.logAndDisplay(LogLevel.INFO, "Output for command " + command + ": " + commandOutput);
         return commandOutput.startsWith("Success:");
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseLauncherAppsTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseLauncherAppsTest.java
index b106ffd..80e73dd 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseLauncherAppsTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseLauncherAppsTest.java
@@ -28,6 +28,8 @@
     protected static final String SIMPLE_APP_APK = "CtsSimpleApp.apk";
     protected static final String LAUNCHER_TESTS_PKG = "com.android.cts.launchertests";
     protected static final String LAUNCHER_TESTS_CLASS = LAUNCHER_TESTS_PKG + ".LauncherAppsTests";
+    protected static final String PARAM_TEST_USER = "testUser";
+
     private static final String LAUNCHER_TESTS_APK = "CtsLauncherAppsTests.apk";
     private static final String LAUNCHER_TESTS_SUPPORT_PKG =
             "com.android.cts.launchertests.support";
@@ -35,8 +37,8 @@
 
     protected void installTestApps() throws Exception {
         uninstallTestApps();
-        installApp(LAUNCHER_TESTS_APK);
-        installApp(LAUNCHER_TESTS_SUPPORT_APK);
+        installAppAsUser(LAUNCHER_TESTS_APK, mPrimaryUserId);
+        installAppAsUser(LAUNCHER_TESTS_SUPPORT_APK, mPrimaryUserId);
     }
 
     protected void uninstallTestApps() throws Exception {
@@ -46,8 +48,8 @@
     }
 
     protected void startCallbackService() throws Exception {
-        String command = "am startservice --user 0 "
-                + "-a " + LAUNCHER_TESTS_SUPPORT_PKG + ".REGISTER_CALLBACK "
+        String command = "am startservice --user " + mPrimaryUserId
+                + " -a " + LAUNCHER_TESTS_SUPPORT_PKG + ".REGISTER_CALLBACK "
                 + LAUNCHER_TESTS_SUPPORT_PKG + "/.LauncherCallbackTestsService";
         CLog.logAndDisplay(LogLevel.INFO, "Output for command " + command + ": "
               + getDevice().executeShellCommand(command));
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/CustomDeviceOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/CustomDeviceOwnerTest.java
index 8d22638..23cdb5a 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/CustomDeviceOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/CustomDeviceOwnerTest.java
@@ -16,6 +16,9 @@
 
 package com.android.cts.devicepolicy;
 
+import com.android.cts.devicepolicy.BaseDevicePolicyTest.Settings;
+import com.android.cts.migration.MigrationHelper;
+
 import java.io.File;
 import java.lang.Exception;
 
@@ -34,16 +37,6 @@
     private static final String DEVICE_OWNER_CLEAR
             = DEVICE_OWNER_PKG + ".ClearDeviceOwnerTest";
 
-    private static final String DEVICE_AND_PROFILE_OWNER_PKG
-            = "com.android.cts.deviceandprofileowner";
-    protected static final String DEVICE_AND_PROFILE_OWNER_APK = "CtsDeviceAndProfileOwnerApp.apk";
-    protected static final String DEVICE_AND_PROFILE_OWNER_ADMIN
-            = ".BaseDeviceAdminTest$BasicAdminReceiver";
-    protected static final String DEVICE_AND_PROFILE_OWNER_ADMIN_COMPONENT
-            = DEVICE_AND_PROFILE_OWNER_PKG + "/" + DEVICE_AND_PROFILE_OWNER_ADMIN;
-    protected static final String DEVICE_AND_PROFILE_OWNER_CLEAR
-            = DEVICE_AND_PROFILE_OWNER_PKG + ".ClearDeviceOwnerTest";
-
     private static final String INTENT_RECEIVER_PKG = "com.android.cts.intent.receiver";
     private static final String INTENT_RECEIVER_APK = "CtsIntentReceiverApp.apk";
 
@@ -58,11 +51,16 @@
     private static final String PACKAGE_INSTALLER_CLEAR_DEVICE_OWNER_TEST_CLASS =
             PACKAGE_INSTALLER_PKG + ".ClearDeviceOwnerTest";
 
+    private static final String ACCOUNT_MANAGEMENT_PKG
+            = "com.android.cts.devicepolicy.accountmanagement";
+    protected static final String ACCOUNT_MANAGEMENT_APK
+            = "CtsAccountManagementDevicePolicyApp.apk";
+
     @Override
     public void tearDown() throws Exception {
         if (mHasFeature) {
             getDevice().uninstallPackage(DEVICE_OWNER_PKG);
-            getDevice().uninstallPackage(DEVICE_AND_PROFILE_OWNER_PKG);
+            getDevice().uninstallPackage(ACCOUNT_MANAGEMENT_PKG);
         }
 
         super.tearDown();
@@ -72,26 +70,26 @@
         if (!mHasFeature) {
             return;
         }
-        installApp(DEVICE_OWNER_APK);
+        installAppAsUser(DEVICE_OWNER_APK, mPrimaryUserId);
         try {
-            installApp(INTENT_RECEIVER_APK);
+            installAppAsUser(INTENT_RECEIVER_APK, mPrimaryUserId);
 
             String testClass = INTENT_RECEIVER_PKG + ".OwnerChangedBroadcastTest";
 
             // Running this test also gets the intent receiver app out of the stopped state, so it
             // can receive broadcast intents.
-            assertTrue(runDeviceTests(INTENT_RECEIVER_PKG, testClass,
-                    "testOwnerChangedBroadcastNotReceived", 0));
+            assertTrue(runDeviceTestsAsUser(INTENT_RECEIVER_PKG, testClass,
+                    "testOwnerChangedBroadcastNotReceived", mPrimaryUserId));
 
             // Setting the device owner should send the owner changed broadcast.
-            assertTrue(setDeviceOwner(DEVICE_OWNER_ADMIN_COMPONENT));
+            assertTrue(setDeviceOwner(DEVICE_OWNER_ADMIN_COMPONENT, mPrimaryUserId));
 
-            assertTrue(runDeviceTests(INTENT_RECEIVER_PKG, testClass,
-                    "testOwnerChangedBroadcastReceived", 0));
+            assertTrue(runDeviceTestsAsUser(INTENT_RECEIVER_PKG, testClass,
+                    "testOwnerChangedBroadcastReceived", mPrimaryUserId));
         } finally {
             getDevice().uninstallPackage(INTENT_RECEIVER_PKG);
             assertTrue("Failed to remove device owner.",
-                    runDeviceTests(DEVICE_OWNER_PKG, DEVICE_OWNER_CLEAR));
+                    runDeviceTestsAsUser(DEVICE_OWNER_PKG, DEVICE_OWNER_CLEAR, mPrimaryUserId));
         }
     }
 
@@ -100,14 +98,14 @@
             return;
         }
         int userId = -1;
-        installApp(DEVICE_OWNER_APK);
+        installAppAsUser(DEVICE_OWNER_APK, mPrimaryUserId);
         try {
             userId = createUser();
-            assertFalse(setDeviceOwner(DEVICE_OWNER_ADMIN_COMPONENT));
+            assertFalse(setDeviceOwner(DEVICE_OWNER_ADMIN_COMPONENT, mPrimaryUserId));
         } finally {
             removeUser(userId);
             // make sure we clean up in case we succeeded in setting the device owner
-            runDeviceTests(DEVICE_OWNER_PKG, DEVICE_OWNER_CLEAR);
+            runDeviceTestsAsUser(DEVICE_OWNER_PKG, DEVICE_OWNER_CLEAR, mPrimaryUserId);
         }
     }
 
@@ -115,16 +113,17 @@
         if (!mHasFeature) {
             return;
         }
-        installApp(DEVICE_AND_PROFILE_OWNER_APK);
+        installAppAsUser(ACCOUNT_MANAGEMENT_APK, mPrimaryUserId);
+        installAppAsUser(DEVICE_OWNER_APK, mPrimaryUserId);
         try {
-            assertTrue(runDeviceTestsAsUser(DEVICE_AND_PROFILE_OWNER_PKG, ".AccountUtilsTest",
-                    "testAddAccount", 0));
-            assertFalse(setDeviceOwner(DEVICE_AND_PROFILE_OWNER_ADMIN_COMPONENT));
+            assertTrue(runDeviceTestsAsUser(ACCOUNT_MANAGEMENT_PKG, ".AccountUtilsTest",
+                    "testAddAccountExplicitly", mPrimaryUserId));
+            assertFalse(setDeviceOwner(DEVICE_OWNER_ADMIN_COMPONENT, mPrimaryUserId));
         } finally {
             // make sure we clean up in case we succeeded in setting the device owner
-            runDeviceTests(DEVICE_AND_PROFILE_OWNER_PKG, DEVICE_AND_PROFILE_OWNER_CLEAR);
-            assertTrue(runDeviceTestsAsUser(DEVICE_AND_PROFILE_OWNER_PKG, ".AccountUtilsTest",
-                    "testRemoveAccounts", 0));
+            runDeviceTestsAsUser(DEVICE_OWNER_PKG, DEVICE_OWNER_CLEAR, mPrimaryUserId);
+            assertTrue(runDeviceTestsAsUser(ACCOUNT_MANAGEMENT_PKG, ".AccountUtilsTest",
+                    "testRemoveAccountExplicitly", mPrimaryUserId));
         }
     }
 
@@ -132,23 +131,37 @@
         if (!mHasFeature) {
             return;
         }
-        final File apk = mCtsBuild.getTestApp(TEST_APP_APK);
+        final File apk = MigrationHelper.getTestFile(mCtsBuild, TEST_APP_APK);
         try {
             // Install the test and prepare the test apk.
-            installApp(PACKAGE_INSTALLER_APK);
-            assertTrue(setDeviceOwner(PACKAGE_INSTALLER_ADMIN_COMPONENT));
+            installAppAsUser(PACKAGE_INSTALLER_APK, mPrimaryUserId);
+            assertTrue(setDeviceOwner(PACKAGE_INSTALLER_ADMIN_COMPONENT, mPrimaryUserId));
 
             getDevice().uninstallPackage(TEST_APP_PKG);
             assertTrue(getDevice().pushFile(apk, TEST_APP_LOCATION + apk.getName()));
-            assertTrue(runDeviceTests(PACKAGE_INSTALLER_PKG,
-                    PACKAGE_INSTALLER_PKG + ".SilentPackageInstallTest"));
+            assertTrue(runDeviceTestsAsUser(PACKAGE_INSTALLER_PKG,
+                    PACKAGE_INSTALLER_PKG + ".SilentPackageInstallTest", mPrimaryUserId));
         } finally {
-            assertTrue("Failed to remove device owner.", runDeviceTests(PACKAGE_INSTALLER_PKG,
-                    PACKAGE_INSTALLER_CLEAR_DEVICE_OWNER_TEST_CLASS));
+            assertTrue("Failed to remove device owner.", runDeviceTestsAsUser(PACKAGE_INSTALLER_PKG,
+                    PACKAGE_INSTALLER_CLEAR_DEVICE_OWNER_TEST_CLASS, mPrimaryUserId));
             String command = "rm " + TEST_APP_LOCATION + apk.getName();
             String commandOutput = getDevice().executeShellCommand(command);
             getDevice().uninstallPackage(TEST_APP_PKG);
             getDevice().uninstallPackage(PACKAGE_INSTALLER_PKG);
         }
     }
+
+    public void testIsProvisioningAllowed() throws Exception {
+        // Must install the apk since the test runs in the DO apk.
+        installAppAsUser(DEVICE_OWNER_APK, mPrimaryUserId);
+        try {
+            // When CTS runs, setupwizard is complete. Expects it has to return false as DO can
+            // only be provisioned before setupwizard is completed.
+
+            assertTrue(runDeviceTestsAsUser(DEVICE_OWNER_PKG, ".PreDeviceOwnerTest",
+                    "testIsProvisioningAllowedFalse", /* deviceOwnerUserId */ 0));
+        } finally {
+            getDevice().uninstallPackage(DEVICE_OWNER_PKG);
+        }
+    }
 }
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/CustomManagedProfileTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/CustomManagedProfileTest.java
new file mode 100644
index 0000000..53e9138
--- /dev/null
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/CustomManagedProfileTest.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.devicepolicy;
+
+import com.android.tradefed.device.DeviceNotAvailableException;
+
+public class CustomManagedProfileTest extends BaseDevicePolicyTest {
+
+    private static final String MANAGED_PROFILE_PKG = "com.android.cts.managedprofile";
+    private static final String MANAGED_PROFILE_APK = "CtsManagedProfileApp.apk";
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        // We need multi user to be supported in order to create a profile of the user owner.
+        mHasFeature = mHasFeature && hasDeviceFeature("android.software.managed_users");
+    }
+
+    public void testIsProvisioningAllowed() throws Exception {
+        final int primaryUserId = getPrimaryUser();
+        // Must install the apk since the test runs in the ManagedProfile apk.
+        installAppAsUser(MANAGED_PROFILE_APK, mPrimaryUserId);
+        try {
+            if (mHasFeature) {
+                // Since we assume, in ManagedProfileTest, provisioning has to be successful,
+                // DevicePolicyManager.isProvisioningAllowed must return true
+                assertIsProvisioningAllowed(true, primaryUserId);
+            } else {
+                // Test the case when feature flag is off
+                assertIsProvisioningAllowed(false, primaryUserId);
+            }
+        } finally {
+            getDevice().uninstallPackage(MANAGED_PROFILE_PKG);
+        }
+    }
+
+    private void assertIsProvisioningAllowed(boolean expected, int userId)
+            throws DeviceNotAvailableException {
+        final String testName = expected ? "testIsProvisioningAllowedTrue"
+                : "testIsProvisioningAllowedFalse";
+        assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".PreManagedProfileTest", testName,
+                userId));
+    }
+}
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAdminHostSideTestApi23.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAdminHostSideTestApi23.java
new file mode 100644
index 0000000..862a933
--- /dev/null
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAdminHostSideTestApi23.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.devicepolicy;
+
+/**
+ * BaseDeviceAdminHostSideTest for device admin targeting API level 23.
+ */
+public class DeviceAdminHostSideTestApi23 extends BaseDeviceAdminHostSideTest {
+    @Override
+    protected int getTargetApiVersion() {
+        return 23;
+    }
+
+    /**
+     * Device admin with no BIND_DEVICE_ADMIN can still be activated, if the target SDK <= 23.
+     */
+    public void testAdminWithNoProtection() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+
+        installAppAsUser(getDeviceAdminApkFileName(), mUserId);
+        try {
+            setDeviceAdmin(getUnprotectedAdminReceiverComponent(), mUserId);
+        } finally {
+            assertTrue("Failed to remove device admin", runTests(
+                    getDeviceAdminApkPackage(), "ClearDeviceAdminWithNoProtectionTest"));
+        }
+    }
+}
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAdminHostSideTestApi24.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAdminHostSideTestApi24.java
new file mode 100644
index 0000000..4682ef6
--- /dev/null
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAdminHostSideTestApi24.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.devicepolicy;
+
+/**
+ * BaseDeviceAdminHostSideTest for device admin targeting API level 24.
+ */
+public class DeviceAdminHostSideTestApi24 extends BaseDeviceAdminHostSideTest {
+    @Override
+    protected int getTargetApiVersion() {
+        return 24;
+    }
+
+    /**
+     * Device admin must be protected with BIND_DEVICE_ADMIN, if the target SDK >= 24.
+     */
+    public void testAdminWithNoProtection() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+
+        installAppAsUser(getDeviceAdminApkFileName(), mUserId);
+        setDeviceAdminExpectingFailure(getUnprotectedAdminReceiverComponent(), mUserId,
+                "must be protected with android.permission.BIND_DEVICE_ADMIN");
+    }
+}
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
index 7e72741..a7e58f3 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
@@ -16,16 +16,21 @@
 
 package com.android.cts.devicepolicy;
 
+import com.android.cts.migration.MigrationHelper;
 import com.android.ddmlib.Log.LogLevel;
 import com.android.tradefed.device.DeviceNotAvailableException;
 import com.android.tradefed.log.LogUtil.CLog;
 
 import java.io.File;
+import java.io.FileNotFoundException;
 
 /**
- * Set of tests for usecases that apply to profile and device owner.
- * This class is the base class of MixedProfileOwnerTest and MixedDeviceOwnerTest and is abstract
- * to avoid running spurious tests.
+ * Set of tests for use cases that apply to profile and device owner.
+ * This class is the base class of MixedProfileOwnerTest, MixedDeviceOwnerTest and
+ * MixedManagedProfileOwnerTest and is abstract to avoid running spurious tests.
+ *
+ * NOTE: Not all tests are executed in the subclasses.  Sometimes, if a test is not applicable to
+ * a subclass, they override it with an empty method.
  */
 public abstract class DeviceAndProfileOwnerTest extends BaseDevicePolicyTest {
 
@@ -34,12 +39,26 @@
     protected static final String ADMIN_RECEIVER_TEST_CLASS
             = ".BaseDeviceAdminTest$BasicAdminReceiver";
 
+    private static final String INTENT_RECEIVER_PKG = "com.android.cts.intent.receiver";
+    private static final String INTENT_RECEIVER_APK = "CtsIntentReceiverApp.apk";
+
+    private static final String INTENT_SENDER_PKG = "com.android.cts.intent.sender";
+    private static final String INTENT_SENDER_APK = "CtsIntentSenderApp.apk";
+
     private static final String PERMISSIONS_APP_PKG = "com.android.cts.permissionapp";
     private static final String PERMISSIONS_APP_APK = "CtsPermissionApp.apk";
 
     private static final String SIMPLE_PRE_M_APP_PKG = "com.android.cts.launcherapps.simplepremapp";
     private static final String SIMPLE_PRE_M_APP_APK = "CtsSimplePreMApp.apk";
 
+    private static final String APP_RESTRICTIONS_MANAGING_APP_PKG
+            = "com.android.cts.apprestrictions.managingapp";
+    private static final String APP_RESTRICTIONS_MANAGING_APP_APK
+            = "CtsAppRestrictionsManagingApp.apk";
+    private static final String APP_RESTRICTIONS_TARGET_APP_PKG
+            = "com.android.cts.apprestrictions.targetapp";
+    private static final String APP_RESTRICTIONS_TARGET_APP_APK = "CtsAppRestrictionsTargetApp.apk";
+
     private static final String CERT_INSTALLER_PKG = "com.android.cts.certinstaller";
     private static final String CERT_INSTALLER_APK = "CtsCertInstallerApp.apk";
 
@@ -50,13 +69,27 @@
     private static final String PACKAGE_INSTALLER_PKG = "com.android.cts.packageinstaller";
     private static final String PACKAGE_INSTALLER_APK = "CtsPackageInstallerApp.apk";
 
-    protected static final int USER_OWNER = 0;
+    private static final String ACCOUNT_MANAGEMENT_PKG
+            = "com.android.cts.devicepolicy.accountmanagement";
+    private static final String ACCOUNT_MANAGEMENT_APK = "CtsAccountManagementDevicePolicyApp.apk";
 
-    private static final String ADD_RESTRICTION_COMMAND = "add-restriction";
-    private static final String CLEAR_RESTRICTION_COMMAND = "clear-restriction";
+    private static final String VPN_APP_PKG = "com.android.cts.vpnfirewall";
+    private static final String VPN_APP_APK = "CtsVpnFirewallApp.apk";
 
-    // ID of the user all tests are run as. For device owner this will be 0, for profile owner it
-    // is the user id of the created profile.
+    private static final String COMMAND_ADD_USER_RESTRICTION = "add-restriction";
+    private static final String COMMAND_CLEAR_USER_RESTRICTION = "clear-restriction";
+    private static final String COMMAND_BLOCK_ACCOUNT_TYPE = "block-accounttype";
+    private static final String COMMAND_UNBLOCK_ACCOUNT_TYPE = "unblock-accounttype";
+
+    private static final String DISALLOW_MODIFY_ACCOUNTS = "no_modify_accounts";
+    private static final String ACCOUNT_TYPE
+            = "com.android.cts.devicepolicy.accountmanagement.account.type";
+
+    private static final String CUSTOMIZATION_APP_PKG = "com.android.cts.customizationapp";
+    private static final String CUSTOMIZATION_APP_APK = "CtsCustomizationApp.apk";
+
+    // ID of the user all tests are run as. For device owner this will be the primary user, for
+    // profile owner it is the user id of the created profile.
     protected int mUserId;
 
     @Override
@@ -65,31 +98,88 @@
             getDevice().uninstallPackage(DEVICE_ADMIN_PKG);
             getDevice().uninstallPackage(PERMISSIONS_APP_PKG);
             getDevice().uninstallPackage(SIMPLE_PRE_M_APP_PKG);
+            getDevice().uninstallPackage(APP_RESTRICTIONS_MANAGING_APP_PKG);
+            getDevice().uninstallPackage(APP_RESTRICTIONS_TARGET_APP_PKG);
             getDevice().uninstallPackage(CERT_INSTALLER_PKG);
+            getDevice().uninstallPackage(ACCOUNT_MANAGEMENT_PKG);
+            getDevice().uninstallPackage(VPN_APP_PKG);
+            getDevice().uninstallPackage(INTENT_RECEIVER_PKG);
+            getDevice().uninstallPackage(INTENT_SENDER_PKG);
+            getDevice().uninstallPackage(CUSTOMIZATION_APP_PKG);
         }
         super.tearDown();
     }
 
+    public void testResetPassword() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+        executeDeviceTestClass(".ResetPasswordTest");
+    }
+
     public void testApplicationRestrictions() throws Exception {
         if (!mHasFeature) {
             return;
         }
-        executeDeviceTestClass(".ApplicationRestrictionsTest");
+
+        installAppAsUser(APP_RESTRICTIONS_MANAGING_APP_APK, mUserId);
+        installAppAsUser(APP_RESTRICTIONS_TARGET_APP_APK, mUserId);
+
+        try {
+            // Only the DPC can manage app restrictions by default.
+            executeDeviceTestClass(".ApplicationRestrictionsTest");
+            executeAppRestrictionsManagingPackageTest("testCannotManageAppRestrictions");
+
+            // Letting the APP_RESTRICTIONS_MANAGING_APP_PKG manage app restrictions too.
+            changeApplicationRestrictionsManagingPackage(APP_RESTRICTIONS_MANAGING_APP_PKG);
+            executeAppRestrictionsManagingPackageTest("testCanManageAppRestrictions");
+            executeAppRestrictionsManagingPackageTest("testSettingComponentNameThrowsException");
+
+            // The DPC should still be able to manage app restrictions normally.
+            executeDeviceTestClass(".ApplicationRestrictionsTest");
+
+            // The app shouldn't be able to manage app restrictions for other users.
+            int parentUserId = getPrimaryUser();
+            if (parentUserId != mUserId) {
+                installAppAsUser(APP_RESTRICTIONS_MANAGING_APP_APK, parentUserId);
+                installAppAsUser(APP_RESTRICTIONS_TARGET_APP_APK, parentUserId);
+                assertTrue(runDeviceTestsAsUser(
+                        APP_RESTRICTIONS_MANAGING_APP_PKG, ".ApplicationRestrictionsManagerTest",
+                        "testCannotManageAppRestrictions", parentUserId));
+            }
+
+            // Revoking the permission for APP_RESTRICTIONS_MANAGING_APP_PKG to manage restrictions.
+            changeApplicationRestrictionsManagingPackage(null);
+            executeAppRestrictionsManagingPackageTest("testCannotManageAppRestrictions");
+
+            // The DPC should still be able to manage app restrictions normally.
+            executeDeviceTestClass(".ApplicationRestrictionsTest");
+        } finally {
+            changeApplicationRestrictionsManagingPackage(null);
+        }
     }
 
     public void testPermissionGrant() throws Exception {
         if (!mHasFeature) {
             return;
         }
-        installAppAsUser(PERMISSIONS_APP_APK, mUserId);
+        installAppPermissionAppAsUser();
         executeDeviceTestMethod(".PermissionsTest", "testPermissionGrantState");
     }
 
+    public void testAlwaysOnVpn() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+        installAppAsUser(VPN_APP_APK, mUserId);
+        executeDeviceTestClass(".AlwaysOnVpnTest");
+    }
+
     public void testPermissionPolicy() throws Exception {
         if (!mHasFeature) {
             return;
         }
-        installAppAsUser(PERMISSIONS_APP_APK, mUserId);
+        installAppPermissionAppAsUser();
         executeDeviceTestMethod(".PermissionsTest", "testPermissionPolicy");
     }
 
@@ -97,7 +187,7 @@
         if (!mHasFeature) {
             return;
         }
-        installAppAsUser(PERMISSIONS_APP_APK, mUserId);
+        installAppPermissionAppAsUser();
         executeDeviceTestMethod(".PermissionsTest", "testPermissionMixedPolicies");
     }
 
@@ -105,7 +195,7 @@
         if (!mHasFeature) {
             return;
         }
-        installAppAsUser(PERMISSIONS_APP_APK, mUserId);
+        installAppPermissionAppAsUser();
         executeDeviceTestMethod(".PermissionsTest", "testPermissionPrompts");
     }
 
@@ -113,31 +203,31 @@
         if (!mHasFeature) {
             return;
         }
-        installAppAsUser(PERMISSIONS_APP_APK, mUserId);
+        installAppPermissionAppAsUser();
         executeDeviceTestMethod(".PermissionsTest", "testPermissionUpdate_setDeniedState");
         executeDeviceTestMethod(".PermissionsTest", "testPermissionUpdate_checkDenied");
-        installAppAsUser(PERMISSIONS_APP_APK, mUserId);
+        installAppPermissionAppAsUser();
         executeDeviceTestMethod(".PermissionsTest", "testPermissionUpdate_checkDenied");
 
         assertNull(getDevice().uninstallPackage(PERMISSIONS_APP_PKG));
-        installAppAsUser(PERMISSIONS_APP_APK, mUserId);
+        installAppPermissionAppAsUser();
         executeDeviceTestMethod(".PermissionsTest", "testPermissionUpdate_setGrantedState");
         executeDeviceTestMethod(".PermissionsTest", "testPermissionUpdate_checkGranted");
-        installAppAsUser(PERMISSIONS_APP_APK, mUserId);
+        installAppPermissionAppAsUser();
         executeDeviceTestMethod(".PermissionsTest", "testPermissionUpdate_checkGranted");
 
         assertNull(getDevice().uninstallPackage(PERMISSIONS_APP_PKG));
-        installAppAsUser(PERMISSIONS_APP_APK, mUserId);
+        installAppPermissionAppAsUser();
         executeDeviceTestMethod(".PermissionsTest", "testPermissionUpdate_setAutoDeniedPolicy");
         executeDeviceTestMethod(".PermissionsTest", "testPermissionUpdate_checkDenied");
-        installAppAsUser(PERMISSIONS_APP_APK, mUserId);
+        installAppPermissionAppAsUser();
         executeDeviceTestMethod(".PermissionsTest", "testPermissionUpdate_checkDenied");
 
         assertNull(getDevice().uninstallPackage(PERMISSIONS_APP_PKG));
-        installAppAsUser(PERMISSIONS_APP_APK, mUserId);
+        installAppPermissionAppAsUser();
         executeDeviceTestMethod(".PermissionsTest", "testPermissionUpdate_setAutoGrantedPolicy");
         executeDeviceTestMethod(".PermissionsTest", "testPermissionUpdate_checkGranted");
-        installAppAsUser(PERMISSIONS_APP_APK, mUserId);
+        installAppPermissionAppAsUser();
         executeDeviceTestMethod(".PermissionsTest", "testPermissionUpdate_checkGranted");
     }
 
@@ -171,52 +261,172 @@
         }
     }
 
+    public void testSupportMessage() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+        installAppAsUser(APP_RESTRICTIONS_MANAGING_APP_APK, mUserId);
+        executeDeviceTestClass(".SupportMessageTest");
+    }
+
     public void testApplicationHidden() throws Exception {
         if (!mHasFeature) {
             return;
         }
-        installAppAsUser(PERMISSIONS_APP_APK, mUserId);
+        installAppPermissionAppAsUser();
         executeDeviceTestClass(".ApplicationHiddenTest");
     }
 
-    public void testAccountManagement() throws Exception {
+    public void testAccountManagement_deviceAndProfileOwnerAlwaysAllowed() throws Exception {
         if (!mHasFeature) {
             return;
         }
 
-        executeDeviceTestClass(".AccountManagementTest");
+        installAppAsUser(ACCOUNT_MANAGEMENT_APK, mUserId);
+        executeDeviceTestClass(".DpcAllowedAccountManagementTest");
+    }
 
-        // Send a home intent to dismiss an error dialog.
-        String command = "am start -a android.intent.action.MAIN -c android.intent.category.HOME";
-        CLog.logAndDisplay(LogLevel.INFO, "Output for command " + command + ": "
-                + getDevice().executeShellCommand(command));
+    public void testAccountManagement_userRestrictionAddAccount() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+
+        installAppAsUser(ACCOUNT_MANAGEMENT_APK, mUserId);
+        try {
+            changeUserRestrictionForUser(DISALLOW_MODIFY_ACCOUNTS, COMMAND_ADD_USER_RESTRICTION,
+                    mUserId);
+            executeAccountTest("testAddAccount_blocked");
+        } finally {
+            // Ensure we clear the user restriction
+            changeUserRestrictionForUser(DISALLOW_MODIFY_ACCOUNTS, COMMAND_CLEAR_USER_RESTRICTION,
+                    mUserId);
+        }
+        executeAccountTest("testAddAccount_allowed");
+    }
+
+    public void testAccountManagement_userRestrictionRemoveAccount() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+
+        installAppAsUser(ACCOUNT_MANAGEMENT_APK, mUserId);
+        try {
+            changeUserRestrictionForUser(DISALLOW_MODIFY_ACCOUNTS, COMMAND_ADD_USER_RESTRICTION,
+                    mUserId);
+            executeAccountTest("testRemoveAccount_blocked");
+        } finally {
+            // Ensure we clear the user restriction
+            changeUserRestrictionForUser(DISALLOW_MODIFY_ACCOUNTS, COMMAND_CLEAR_USER_RESTRICTION,
+                    mUserId);
+        }
+        executeAccountTest("testRemoveAccount_allowed");
+    }
+
+    public void testAccountManagement_disabledAddAccount() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+
+        installAppAsUser(ACCOUNT_MANAGEMENT_APK, mUserId);
+        try {
+            changeAccountManagement(COMMAND_BLOCK_ACCOUNT_TYPE, ACCOUNT_TYPE, mUserId);
+            executeAccountTest("testAddAccount_blocked");
+        } finally {
+            // Ensure we remove account management policies
+            changeAccountManagement(COMMAND_UNBLOCK_ACCOUNT_TYPE, ACCOUNT_TYPE, mUserId);
+        }
+        executeAccountTest("testAddAccount_allowed");
+    }
+
+    public void testAccountManagement_disabledRemoveAccount() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+
+        installAppAsUser(ACCOUNT_MANAGEMENT_APK, mUserId);
+        try {
+            changeAccountManagement(COMMAND_BLOCK_ACCOUNT_TYPE, ACCOUNT_TYPE, mUserId);
+            executeAccountTest("testRemoveAccount_blocked");
+        } finally {
+            // Ensure we remove account management policies
+            changeAccountManagement(COMMAND_UNBLOCK_ACCOUNT_TYPE, ACCOUNT_TYPE, mUserId);
+        }
+        executeAccountTest("testRemoveAccount_allowed");
     }
 
     public void testDelegatedCertInstaller() throws Exception {
         if (!mHasFeature) {
             return;
         }
-        installAppAsUser(CERT_INSTALLER_APK, mUserId);
-        installAppAsUser(DEVICE_ADMIN_APK, USER_OWNER);
-        setDeviceAdmin(DEVICE_ADMIN_PKG + "/.PrimaryUserDeviceAdmin");
 
-        final String adminHelperClass = ".PrimaryUserAdminHelper";
+        installAppAsUser(CERT_INSTALLER_APK, mUserId);
+
+        boolean installProfileOwnerForPassword = (mPrimaryUserId != mUserId);
+        if (installProfileOwnerForPassword) {
+            // This is a managed profile test. We need to set a profile owner on the primary user in
+            // order to be able to set and clear the lockscreen password.
+            installAppAsUser(DEVICE_ADMIN_APK, mPrimaryUserId);
+            setProfileOwnerOrFail(DEVICE_ADMIN_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS,
+                    mPrimaryUserId);
+        }
+
         try {
             // Set a non-empty device lockscreen password, which is a precondition for installing
             // private key pairs.
             assertTrue("Set lockscreen password failed", runDeviceTestsAsUser(DEVICE_ADMIN_PKG,
-                    adminHelperClass, "testSetPassword", 0 /* user 0 */));
+                    ".ResetPasswordHelper", "testSetPassword", mPrimaryUserId));
             assertTrue("DelegatedCertInstaller failed", runDeviceTestsAsUser(DEVICE_ADMIN_PKG,
                     ".DelegatedCertInstallerTest", mUserId));
         } finally {
-            // Reset lockscreen password and remove device admin.
+            // Reset lockscreen password and remove profile owner if required
             assertTrue("Clear lockscreen password failed", runDeviceTestsAsUser(DEVICE_ADMIN_PKG,
-                    adminHelperClass, "testClearPassword", 0 /* user 0 */));
-            assertTrue("Clear device admin failed", runDeviceTestsAsUser(DEVICE_ADMIN_PKG,
-                    adminHelperClass, "testClearDeviceAdmin", 0 /* user 0 */));
+                    ".ResetPasswordHelper", "testClearPassword", mPrimaryUserId));
+            if (installProfileOwnerForPassword) {
+                assertTrue("Failed to remove profile owner.", runDeviceTestsAsUser(DEVICE_ADMIN_PKG,
+                        DEVICE_ADMIN_PKG + ".ClearProfileOwnerTest", mPrimaryUserId));
+            }
         }
     }
 
+    // Sets restrictions and launches non-admin app, that tries to set wallpaper.
+    // Non-admin apps must not violate any user restriction.
+    public void testSetWallpaper_disallowed() throws Exception {
+        // UserManager.DISALLOW_SET_WALLPAPER
+        final String DISALLOW_SET_WALLPAPER = "no_set_wallpaper";
+        if (!mHasFeature) {
+            return;
+        }
+
+        installAppAsUser(CUSTOMIZATION_APP_APK, mUserId);
+        try {
+            changeUserRestrictionForUser(DISALLOW_SET_WALLPAPER, COMMAND_ADD_USER_RESTRICTION,
+                    mUserId);
+            assertTrue(runDeviceTestsAsUser(CUSTOMIZATION_APP_PKG, ".CustomizationTest",
+                "testSetWallpaper_disallowed", mUserId));
+        } finally {
+            changeUserRestrictionForUser(DISALLOW_SET_WALLPAPER, COMMAND_CLEAR_USER_RESTRICTION,
+                    mUserId);
+        }
+    }
+
+    // Runs test with admin privileges. The test methods set all the tested restrictions
+    // inside. But these restrictions must have no effect on the device/profile owner behavior.
+    public void testDisallowSetWallpaper_allowed() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+        executeDeviceTestMethod(".CustomizationRestrictionsTest",
+                "testDisallowSetWallpaper_allowed");
+    }
+
+    public void testDisallowSetUserIcon_allowed() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+        executeDeviceTestMethod(".CustomizationRestrictionsTest",
+                "testDisallowSetUserIcon_allowed");
+    }
+
     public void testPackageInstallUserRestrictions() throws Exception {
         if (!mHasFeature) {
             return;
@@ -225,23 +435,23 @@
         final String DISALLOW_INSTALL_UNKNOWN_SOURCES = "no_install_unknown_sources";
         final String UNKNOWN_SOURCES_SETTING = "install_non_market_apps";
         final String SECURE_SETTING_CATEGORY = "secure";
-        final File apk = mCtsBuild.getTestApp(TEST_APP_APK);
+        final File apk = MigrationHelper.getTestFile(mCtsBuild, TEST_APP_APK);
         String unknownSourceSetting = null;
         try {
             // Install the test and prepare the test apk.
-            installApp(PACKAGE_INSTALLER_APK);
+            installAppAsUser(PACKAGE_INSTALLER_APK, mUserId);
             assertTrue(getDevice().pushFile(apk, TEST_APP_LOCATION + apk.getName()));
 
             // Add restrictions and test if we can install the apk.
             getDevice().uninstallPackage(TEST_APP_PKG);
             changeUserRestrictionForUser(DISALLOW_INSTALL_UNKNOWN_SOURCES,
-                    ADD_RESTRICTION_COMMAND, mUserId);
+                    COMMAND_ADD_USER_RESTRICTION, mUserId);
             assertTrue(runDeviceTestsAsUser(PACKAGE_INSTALLER_PKG, ".ManualPackageInstallTest",
                     "testManualInstallBlocked", mUserId));
 
             // Clear restrictions and test if we can install the apk.
             changeUserRestrictionForUser(DISALLOW_INSTALL_UNKNOWN_SOURCES,
-                    CLEAR_RESTRICTION_COMMAND, mUserId);
+                    COMMAND_CLEAR_USER_RESTRICTION, mUserId);
 
             // Enable Unknown sources in Settings.
             unknownSourceSetting =
@@ -263,6 +473,38 @@
         }
     }
 
+    public void testAudioRestriction() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+        executeDeviceTestClass(".AudioRestrictionTest");
+    }
+
+    public void testSuspendPackage() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+        installAppAsUser(INTENT_SENDER_APK, mUserId);
+        installAppAsUser(INTENT_RECEIVER_APK, mUserId);
+        // Suspend a testing package.
+        executeDeviceTestMethod(".SuspendPackageTest", "testSetPackagesSuspended");
+        // Verify that the package is suspended.
+        executeSuspendPackageTestMethod("testPackageSuspended");
+        // Undo the suspend.
+        executeDeviceTestMethod(".SuspendPackageTest", "testSetPackagesNotSuspended");
+        // Verify that the package is not suspended.
+        executeSuspendPackageTestMethod("testPackageNotSuspended");
+        // Verify we cannot suspend not suspendable packages.
+        executeDeviceTestMethod(".SuspendPackageTest", "testSuspendNotSuspendablePackages");
+    }
+
+    public void testTrustAgentInfo() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+        executeDeviceTestClass(".TrustAgentInfoTest");
+    }
+
     protected void executeDeviceTestClass(String className) throws Exception {
         assertTrue(runDeviceTestsAsUser(DEVICE_ADMIN_PKG, className, mUserId));
     }
@@ -271,13 +513,54 @@
         assertTrue(runDeviceTestsAsUser(DEVICE_ADMIN_PKG, className, testName, mUserId));
     }
 
+    private void installAppPermissionAppAsUser()
+            throws FileNotFoundException, DeviceNotAvailableException {
+        installAppAsUser(PERMISSIONS_APP_APK, false, mUserId);
+    }
+
+    private void executeSuspendPackageTestMethod(String testName) throws Exception {
+        assertTrue(runDeviceTestsAsUser(INTENT_SENDER_PKG, ".SuspendPackageTest",
+                testName, mUserId));
+    }
+
+    private void executeAccountTest(String testName) throws DeviceNotAvailableException {
+        assertTrue(runDeviceTestsAsUser(ACCOUNT_MANAGEMENT_PKG, ".AccountManagementTest",
+                testName, mUserId));
+        // Send a home intent to dismiss an error dialog.
+        String command = "am start -a android.intent.action.MAIN"
+                + " -c android.intent.category.HOME";
+        CLog.i("Output for command " + command + ": " + getDevice().executeShellCommand(command));
+    }
+
+    private void executeAppRestrictionsManagingPackageTest(String testName) throws Exception {
+        assertTrue(runDeviceTestsAsUser(APP_RESTRICTIONS_MANAGING_APP_PKG,
+                ".ApplicationRestrictionsManagerTest", testName, mUserId));
+    }
+
     private void changeUserRestrictionForUser(String key, String command, int userId)
             throws DeviceNotAvailableException {
+        changePolicy(command, "--es extra-restriction-key " + key, userId);
+    }
+
+    private void changeAccountManagement(String command, String accountType, int userId)
+            throws DeviceNotAvailableException {
+        changePolicy(command, "--es extra-account-type " + accountType, userId);
+    }
+
+    private void changeApplicationRestrictionsManagingPackage(String packageName)
+            throws DeviceNotAvailableException {
+        String packageNameExtra = (packageName != null)
+                ? "--es extra-package-name " + packageName : "";
+        changePolicy("set-app-restrictions-manager", packageNameExtra, mUserId);
+    }
+
+    private void changePolicy(String command, String extras, int userId)
+            throws DeviceNotAvailableException {
         String adbCommand = "am start -W --user " + userId
                 + " -c android.intent.category.DEFAULT "
                 + " --es extra-command " + command
-                + " --es extra-restriction-key " + key
-                + " " + DEVICE_ADMIN_PKG + "/.UserRestrictionActivity";
+                + " " + extras
+                + " " + DEVICE_ADMIN_PKG + "/.SetPolicyActivity";
         String commandOutput = getDevice().executeShellCommand(adbCommand);
         CLog.logAndDisplay(LogLevel.INFO,
                 "Output for command " + adbCommand + ": " + commandOutput);
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
index 96ca469..afead29 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
@@ -16,6 +16,8 @@
 
 package com.android.cts.devicepolicy;
 
+import java.util.ArrayList;
+
 /**
  * Set of tests for Device Owner use cases.
  */
@@ -41,22 +43,44 @@
     private static final String CLEAR_DEVICE_OWNER_TEST_CLASS =
             DEVICE_OWNER_PKG + ".ClearDeviceOwnerTest";
 
+    /** The ephemeral users are implemented and supported on the device. */
+    private boolean mHasEphemeralUserFeature;
+
+    /**
+     * Ephemeral users are implemented, but unsupported on the device (because of missing split
+     * system user).
+     */
+    private boolean mHasDisabledEphemeralUserFeature;
+
+    /** CreateAndManageUser is available and an additional user can be created. */
+    private boolean mHasCreateAndManageUserFeature;
+
     @Override
     protected void setUp() throws Exception {
         super.setUp();
         if (mHasFeature) {
-            installApp(DEVICE_OWNER_APK);
-            assertTrue("Failed to set device owner",
-                    setDeviceOwner(DEVICE_OWNER_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS));
+            installAppAsUser(DEVICE_OWNER_APK, mPrimaryUserId);
+            if (!setDeviceOwner(DEVICE_OWNER_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS, mPrimaryUserId))
+            {
+                runDeviceTestsAsUser(
+                        DEVICE_OWNER_PKG, CLEAR_DEVICE_OWNER_TEST_CLASS, mPrimaryUserId);
+                fail("Failed to set device owner");
+            }
         }
+        mHasEphemeralUserFeature = mHasFeature && canCreateAdditionalUsers(1) && hasUserSplit();
+        mHasDisabledEphemeralUserFeature =
+                mHasFeature && canCreateAdditionalUsers(1) && !hasUserSplit();
+        mHasCreateAndManageUserFeature = mHasFeature && canCreateAdditionalUsers(1);
     }
 
     @Override
     protected void tearDown() throws Exception {
         if (mHasFeature) {
-            assertTrue("Failed to remove device owner.",
-                    runDeviceTests(DEVICE_OWNER_PKG, CLEAR_DEVICE_OWNER_TEST_CLASS));
+            assertTrue("Failed to remove device owner.", runDeviceTestsAsUser(
+                    DEVICE_OWNER_PKG, CLEAR_DEVICE_OWNER_TEST_CLASS, mPrimaryUserId));
             getDevice().uninstallPackage(DEVICE_OWNER_PKG);
+            switchUser(USER_SYSTEM);
+            removeTestUsers();
         }
 
         super.tearDown();
@@ -74,9 +98,226 @@
         executeDeviceOwnerTest("KeyManagementTest");
     }
 
+    public void testLockScreenInfo() throws Exception {
+        executeDeviceOwnerTest("LockScreenInfoTest");
+    }
+
+    public void testWifi() throws Exception {
+        if (hasDeviceFeature("android.hardware.wifi")) {
+            return;
+        }
+        executeDeviceOwnerTest("WifiTest");
+    }
+
+    public void testRemoteBugreportWithTwoUsers() throws Exception {
+        if (!mHasFeature || getMaxNumberOfUsersSupported() < 2) {
+            return;
+        }
+        int userId = -1;
+        try {
+            userId = createUser();
+            executeDeviceTestMethod(".RemoteBugreportTest",
+                    "testRequestBugreportNotStartedIfMoreThanOneUserPresent");
+        } finally {
+            removeUser(userId);
+        }
+    }
+
+    public void testRemoteBugreportWithSingleUser() throws Exception {
+        executeDeviceTestMethod(".RemoteBugreportTest", "testSubsequentRemoteBugreportThrottled");
+    }
+
+    /** Tries to toggle the force-ephemeral-users on and checks it was really set. */
+    public void testSetForceEphemeralUsers() throws Exception {
+        if (!mHasEphemeralUserFeature) {
+            return;
+        }
+        // Set force-ephemeral-users policy and verify it was set.
+        executeDeviceTestMethod(".ForceEphemeralUsersTest", "testSetForceEphemeralUsers");
+    }
+
+    /**
+     * Setting force-ephemeral-users policy to true without a split system user should fail.
+     */
+    public void testSetForceEphemeralUsersFailsWithoutSplitSystemUser() throws Exception {
+        if (mHasDisabledEphemeralUserFeature) {
+            executeDeviceTestMethod(".ForceEphemeralUsersTest", "testSetForceEphemeralUsersFails");
+        }
+    }
+
+    /**
+     * All users (except of the system user) must be removed after toggling the
+     * force-ephemeral-users policy to true.
+     *
+     * <p>If the current user is the system user, the other users are removed straight away.
+     */
+    public void testRemoveUsersOnSetForceEphemeralUsers() throws Exception {
+        if (!mHasEphemeralUserFeature) {
+            return;
+        }
+
+        // Create a user.
+        int userId = createUser();
+        assertTrue("User must have been created", listUsers().contains(userId));
+
+        // Set force-ephemeral-users policy and verify it was set.
+        executeDeviceTestMethod(".ForceEphemeralUsersTest", "testSetForceEphemeralUsers");
+
+        // Users have to be removed when force-ephemeral-users is toggled on.
+        assertFalse("User must have been removed", listUsers().contains(userId));
+    }
+
+    /**
+     * All users (except of the system user) must be removed after toggling the
+     * force-ephemeral-users policy to true.
+     *
+     * <p>If the current user is not the system user, switching to the system user should happen
+     * before all other users are removed.
+     */
+    public void testRemoveUsersOnSetForceEphemeralUsersWithUserSwitch() throws Exception {
+        if (!mHasEphemeralUserFeature) {
+            return;
+        }
+
+        // Create a user.
+        int userId = createUser();
+        assertTrue("User must have been created", listUsers().contains(userId));
+
+        // Switch to the new (non-system) user.
+        switchUser(userId);
+
+        // Set force-ephemeral-users policy and verify it was set.
+        executeDeviceTestMethod(".ForceEphemeralUsersTest", "testSetForceEphemeralUsers");
+
+        // Make sure the user has been removed. As it is not a synchronous operation - switching to
+        // the system user must happen first - give the system a little bit of time for finishing
+        // it.
+        final int sleepMs = 500;
+        final int maxSleepMs = 10000;
+        for (int totalSleptMs = 0; totalSleptMs < maxSleepMs; totalSleptMs += sleepMs) {
+            // Wait a little while for the user's removal.
+            Thread.sleep(sleepMs);
+
+            if (!listUsers().contains(userId)) {
+                // Success - the user has been removed.
+                return;
+            }
+        }
+
+        // The user hasn't been removed within the given time.
+        fail("User must have been removed");
+    }
+
+    /** The users created after setting force-ephemeral-users policy to true must be ephemeral. */
+    public void testCreateUserAfterSetForceEphemeralUsers() throws Exception {
+        if (!mHasEphemeralUserFeature) {
+            return;
+        }
+
+        // Set force-ephemeral-users policy and verify it was set.
+        executeDeviceTestMethod(".ForceEphemeralUsersTest", "testSetForceEphemeralUsers");
+
+        int userId = createUser();
+        assertTrue("User must be ephemeral", 0 != (getUserFlags(userId) & FLAG_EPHEMERAL));
+    }
+
+    /**
+     * Test creating an epehemeral user using the DevicePolicyManager's createAndManageUser method.
+     */
+    public void testCreateAndManageEphemeralUser() throws Exception {
+        if (!mHasEphemeralUserFeature) {
+            return;
+        }
+
+        ArrayList<Integer> originalUsers = listUsers();
+        executeDeviceTestMethod(".CreateAndManageUserTest", "testCreateAndManageEphemeralUser");
+
+        ArrayList<Integer> newUsers = listUsers();
+
+        // Check that exactly one new user was created.
+        assertEquals(
+                "One user should have been created", originalUsers.size() + 1, newUsers.size());
+
+        // Get the id of the newly created user.
+        int newUserId = -1;
+        for (int userId : newUsers) {
+            if (!originalUsers.contains(userId)) {
+                newUserId = userId;
+                break;
+            }
+        }
+
+        // Get the flags of the new user and check the user is ephemeral.
+        int flags = getUserFlags(newUserId);
+        assertEquals("Ephemeral flag must be set", FLAG_EPHEMERAL, flags & FLAG_EPHEMERAL);
+    }
+
+    /**
+     * Test that creating an epehemeral user using the DevicePolicyManager's createAndManageUser
+     * method fails on systems without the split system user.
+     */
+    public void testCreateAndManageEphemeralUserFailsWithoutSplitSystemUser() throws Exception {
+        if (mHasDisabledEphemeralUserFeature) {
+            executeDeviceTestMethod(
+                    ".CreateAndManageUserTest", "testCreateAndManageEphemeralUserFails");
+        }
+    }
+
+    public void testCreateAndManageUser_SkipSetupWizard() throws Exception {
+        if (mHasCreateAndManageUserFeature) {
+            executeDeviceTestMethod(".CreateAndManageUserTest",
+                "testCreateAndManageUser_SkipSetupWizard");
+        }
+    }
+
+    public void testCreateAndManageUser_DontSkipSetupWizard() throws Exception {
+        if (mHasCreateAndManageUserFeature) {
+            executeDeviceTestMethod(".CreateAndManageUserTest",
+                "testCreateAndManageUser_DontSkipSetupWizard");
+        }
+    }
+
+    public void testCreateAndManageUser_AddRestrictionSet() throws Exception {
+        if (mHasCreateAndManageUserFeature) {
+            executeDeviceTestMethod(".CreateAndManageUserTest",
+                "testCreateAndManageUser_AddRestrictionSet");
+        }
+    }
+
+    public void testCreateAndManageUser_RemoveRestrictionSet() throws Exception {
+        if (mHasCreateAndManageUserFeature) {
+            executeDeviceTestMethod(".CreateAndManageUserTest",
+                "testCreateAndManageUser_RemoveRestrictionSet");
+        }
+    }
+
+    public void testSecurityLoggingWithTwoUsers() throws Exception {
+        if (!mHasFeature || getMaxNumberOfUsersSupported() < 2) {
+            return;
+        }
+        int userId = -1;
+        try {
+            userId = createUser();
+            executeDeviceTestMethod(".SecurityLoggingTest",
+                    "testSetSecurityLoggingEnabledNotPossibleIfMoreThanOneUserPresent");
+            executeDeviceTestMethod(".SecurityLoggingTest",
+                    "testRetrievingSecurityLogsNotPossibleIfMoreThanOneUserPresent");
+            executeDeviceTestMethod(".SecurityLoggingTest",
+                    "testRetrievingPreviousSecurityLogsNotPossibleIfMoreThanOneUserPresent");
+        } finally {
+            removeUser(userId);
+        }
+    }
+
+    public void testSecurityLoggingWithSingleUser() throws Exception {
+        executeDeviceTestMethod(".SecurityLoggingTest",
+                "testRetrievingSecurityLogsNotPossibleImmediatelyAfterPreviousSuccessfulRetrieval");
+        executeDeviceTestMethod(".SecurityLoggingTest", "testEnablingAndDisablingSecurityLogging");
+    }
+
     public void testLockTask() throws Exception {
         try {
-            installApp(INTENT_RECEIVER_APK);
+            installAppAsUser(INTENT_RECEIVER_APK, mPrimaryUserId);
             executeDeviceOwnerTest("LockTaskTest");
         } finally {
             getDevice().uninstallPackage(INTENT_RECEIVER_PKG);
@@ -91,7 +332,7 @@
         final boolean hasWifi = hasDeviceFeature("android.hardware.wifi");
         if (hasWifi && mHasFeature) {
             try {
-                installApp(WIFI_CONFIG_CREATOR_APK);
+                installAppAsUser(WIFI_CONFIG_CREATOR_APK, mPrimaryUserId);
                 executeDeviceOwnerTest("WifiConfigLockdownTest");
             } finally {
                 getDevice().uninstallPackage(WIFI_CONFIG_CREATOR_PKG);
@@ -104,22 +345,58 @@
             return;
         }
         // verify that we can't set the same admin receiver as device owner again
-        assertFalse(setDeviceOwner(DEVICE_OWNER_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS));
+        assertFalse(setDeviceOwner(
+                DEVICE_OWNER_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS, mPrimaryUserId));
 
         // verify that we can't set a different admin receiver as device owner
         try {
-            installApp(MANAGED_PROFILE_APK);
-            assertFalse(setDeviceOwner(MANAGED_PROFILE_PKG + "/" + MANAGED_PROFILE_ADMIN));
+            installAppAsUser(MANAGED_PROFILE_APK, mPrimaryUserId);
+            assertFalse(setDeviceOwner(
+                    MANAGED_PROFILE_PKG + "/" + MANAGED_PROFILE_ADMIN, mPrimaryUserId));
         } finally {
             getDevice().uninstallPackage(MANAGED_PROFILE_PKG);
         }
     }
 
+    // Execute HardwarePropertiesManagerTest as a device owner.
+    public void testHardwarePropertiesManagerAsDeviceOwner() throws Exception {
+        if (!mHasFeature)
+            return;
+
+        executeDeviceTestMethod(".HardwarePropertiesManagerTest", "testHardwarePropertiesManager");
+    }
+
+    // Execute VrTemperatureTest as a device owner.
+    public void testVrTemperaturesAsDeviceOwner() throws Exception {
+        if (!mHasFeature)
+            return;
+
+        executeDeviceTestMethod(".VrTemperatureTest", "testVrTemperatures");
+    }
+
+    public void testIsManagedDeviceProvisioningAllowed() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+        // This case runs when DO is provisioned
+        // mHasFeature == true and provisioned, can't provision DO again.
+        executeDeviceTestMethod(".PreDeviceOwnerTest", "testIsProvisioningAllowedFalse");
+        // Can't provision Managed Profile when DO is on
+        executeDeviceTestMethod(".PreDeviceOwnerTest",
+                "testIsProvisioningAllowedFalseForManagedProfileAction");
+    }
+
     private void executeDeviceOwnerTest(String testClassName) throws Exception {
         if (!mHasFeature) {
             return;
         }
         String testClass = DEVICE_OWNER_PKG + "." + testClassName;
-        assertTrue(testClass + " failed.", runDeviceTests(DEVICE_OWNER_PKG, testClass));
+        assertTrue(testClass + " failed.",
+                runDeviceTestsAsUser(DEVICE_OWNER_PKG, testClass, mPrimaryUserId));
+    }
+
+    private void executeDeviceTestMethod(String className, String testName) throws Exception {
+        assertTrue(runDeviceTestsAsUser(DEVICE_OWNER_PKG, className, testName,
+                /* deviceOwnerUserId */ mPrimaryUserId));
     }
 }
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/EphemeralUserTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/EphemeralUserTest.java
new file mode 100644
index 0000000..df4a47c
--- /dev/null
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/EphemeralUserTest.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.devicepolicy;
+
+/**
+ * Tests for emphemeral users and profiles.
+ */
+public class EphemeralUserTest extends BaseDevicePolicyTest {
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mHasFeature = canCreateAdditionalUsers(1);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        removeTestUsers();
+        super.tearDown();
+    }
+
+    /** The user should have the ephemeral flag set if it was created as ephemeral. */
+    public void testCreateEphemeralUser() throws Exception {
+        if (!mHasFeature || !hasUserSplit()) {
+            return;
+        }
+        int userId = createUser(FLAG_EPHEMERAL);
+        int flags = getUserFlags(userId);
+        assertTrue("ephemeral flag must be set", FLAG_EPHEMERAL == (flags & FLAG_EPHEMERAL));
+    }
+
+    /** The user should not have the ephemeral flag set if it was not created as ephemeral. */
+    public void testCreateLongLivedUser() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+        int userId = createUser();
+        int flags = getUserFlags(userId);
+        assertTrue("ephemeral flag must not be set", 0 == (flags & FLAG_EPHEMERAL));
+    }
+
+    /**
+     * The profile should have the ephemeral flag set automatically if its parent user is
+     * ephemeral.
+     */
+    public void testProfileInheritsEphemeral() throws Exception {
+        if (!mHasFeature || !hasDeviceFeature("android.software.managed_users")
+                || !hasUserSplit() || !canCreateAdditionalUsers(2)) {
+            return;
+        }
+        int userId = createUser(FLAG_EPHEMERAL);
+        int profileId = createManagedProfile(userId);
+        int flags = getUserFlags(profileId);
+        assertTrue("ephemeral flag must be set", FLAG_EPHEMERAL == (flags & FLAG_EPHEMERAL));
+    }
+
+    /**
+     * Ephemeral user should be automatically removed after it is stopped.
+     */
+    public void testRemoveEphemeralOnStop() throws Exception {
+        if (!mHasFeature || !hasUserSplit()) {
+            return;
+        }
+        int userId = createUser(FLAG_EPHEMERAL);
+        startUser(userId);
+        assertTrue("ephemeral user must exists after start", listUsers().contains(userId));
+        stopUser(userId);
+        assertFalse("ephemeral user must be removed after stop", listUsers().contains(userId));
+    }
+
+    /**
+     * The guest should be automatically created ephemeral when the ephemeral-guest feature is set
+     * and not ephemeral when the feature is not set.
+     */
+    public void testEphemeralGuestFeature() throws Exception {
+        if (!mHasFeature || !hasUserSplit()) {
+            return;
+        }
+        // Create a guest user.
+        int userId = createUser(FLAG_GUEST);
+        int flags = getUserFlags(userId);
+        if (getGuestUsersEphemeral()) {
+            // Check the guest was automatically created ephemeral.
+            assertTrue("ephemeral flag must be set for guest",
+                    FLAG_EPHEMERAL == (flags & FLAG_EPHEMERAL));
+        } else {
+            // The guest should not be ephemeral.
+            assertTrue("ephemeral flag must not be set for guest", 0 == (flags & FLAG_EPHEMERAL));
+        }
+    }
+
+    /**
+     * Test that creating an ephemeral user fails on systems without the split system user.
+     */
+    public void testCreateEphemeralWithoutUserSplitFails() throws Exception {
+        if (!mHasFeature || hasUserSplit()) {
+            return;
+        }
+        String command ="pm create-user --ephemeral " + "TestUser_" + System.currentTimeMillis();
+        String commandOutput = getDevice().executeShellCommand(command);
+
+        assertEquals("Creating the epehemeral user should fail.",
+                "Error: couldn't create User.", commandOutput.trim());
+    }
+
+    private boolean getGuestUsersEphemeral() throws Exception {
+        String commandOutput = getDevice().executeShellCommand("dumpsys user");
+        String[] outputLines = commandOutput.split("\n");
+        for (String line : outputLines) {
+            String[] lineParts = line.split(":");
+            if (lineParts.length == 2 && lineParts[0].trim().equals("All guests ephemeral")) {
+                return Boolean.parseBoolean(lineParts[1].trim());
+            }
+        }
+        return false;
+    }
+}
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/LauncherAppsMultiUserTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/LauncherAppsMultiUserTest.java
index 1d5dd11..2e574d3 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/LauncherAppsMultiUserTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/LauncherAppsMultiUserTest.java
@@ -20,18 +20,18 @@
 import com.android.tradefed.device.DeviceNotAvailableException;
 import com.android.tradefed.log.LogUtil.CLog;
 
+import java.util.Collections;
+
 /**
  * Set of tests for LauncherApps attempting to access a non-profiles
  * apps.
  */
 public class LauncherAppsMultiUserTest extends BaseLauncherAppsTest {
-    private static final String FEATURE_LIVE_TV = "android.software.live_tv";
 
     private int mSecondaryUserId;
-    private int mSecondaryUserSerialNumber;
+    private String mSecondaryUserSerialNumber;
 
     private boolean mMultiUserSupported;
-    private boolean mHasLiveTvFeature;
 
     @Override
     protected void setUp() throws Exception {
@@ -39,14 +39,13 @@
         // We need multi user to be supported in order to create a secondary user
         // and api level 21 to support LauncherApps
         mMultiUserSupported = getMaxNumberOfUsersSupported() > 1 && getDevice().getApiLevel() >= 21;
-        mHasLiveTvFeature = hasDeviceFeature(FEATURE_LIVE_TV);
 
         if (mMultiUserSupported) {
             removeTestUsers();
             installTestApps();
             // Create a secondary user.
             mSecondaryUserId = createUser();
-            mSecondaryUserSerialNumber = getUserSerialNumber(mSecondaryUserId);
+            mSecondaryUserSerialNumber = Integer.toString(getUserSerialNumber(mSecondaryUserId));
             startUser(mSecondaryUserId);
         }
     }
@@ -61,33 +60,27 @@
     }
 
     public void testGetActivitiesForNonProfileFails() throws Exception {
-        if (!mMultiUserSupported || mHasLiveTvFeature) {
+        if (!mMultiUserSupported) {
             return;
         }
-        installApp(SIMPLE_APP_APK);
-        try {
-            assertTrue(runDeviceTests(LAUNCHER_TESTS_PKG,
-                    LAUNCHER_TESTS_CLASS,
-                    "testGetActivitiesForUserFails",
-                            0, "-e testUser " + mSecondaryUserSerialNumber));
-        } finally {
-            getDevice().uninstallPackage(SIMPLE_APP_PKG);
-        }
+        installAppAsUser(SIMPLE_APP_APK, mPrimaryUserId);
+        assertTrue(runDeviceTestsAsUser(LAUNCHER_TESTS_PKG,
+                LAUNCHER_TESTS_CLASS,
+                "testGetActivitiesForUserFails",
+                mPrimaryUserId,
+                Collections.singletonMap(PARAM_TEST_USER, mSecondaryUserSerialNumber)));
     }
 
     public void testNoLauncherCallbackPackageAddedSecondaryUser() throws Exception {
-        if (!mMultiUserSupported || mHasLiveTvFeature) {
+        if (!mMultiUserSupported) {
             return;
         }
         startCallbackService();
-        installApp(SIMPLE_APP_APK);
-        try {
-            assertTrue(runDeviceTests(LAUNCHER_TESTS_PKG,
-                    LAUNCHER_TESTS_CLASS,
-                            "testNoPackageAddedCallbackForUser",
-                            0, "-e testUser " + mSecondaryUserSerialNumber));
-        } finally {
-            getDevice().uninstallPackage(SIMPLE_APP_PKG);
-        }
+        installAppAsUser(SIMPLE_APP_APK, mPrimaryUserId);
+        assertTrue(runDeviceTestsAsUser(LAUNCHER_TESTS_PKG,
+                LAUNCHER_TESTS_CLASS,
+                "testNoPackageAddedCallbackForUser",
+                mPrimaryUserId,
+                Collections.singletonMap(PARAM_TEST_USER, mSecondaryUserSerialNumber)));
     }
 }
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/LauncherAppsProfileTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/LauncherAppsProfileTest.java
index bb26df1..14ce1d9 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/LauncherAppsProfileTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/LauncherAppsProfileTest.java
@@ -20,6 +20,8 @@
 import com.android.tradefed.device.DeviceNotAvailableException;
 import com.android.tradefed.log.LogUtil.CLog;
 
+import java.util.Collections;
+
 /**
  * Set of tests for LauncherApps with managed profiles.
  */
@@ -31,8 +33,9 @@
             MANAGED_PROFILE_PKG + ".BaseManagedProfileTest$BasicAdminReceiver";
 
     private int mProfileUserId;
-    private int mProfileSerialNumber;
-    private int mMainUserSerialNumber;
+    private int mParentUserId;
+    private String mProfileSerialNumber;
+    private String mMainUserSerialNumber;
 
     @Override
     protected void setUp() throws Exception {
@@ -42,12 +45,13 @@
             removeTestUsers();
             installTestApps();
             // Create a managed profile
-            mProfileUserId = createManagedProfile();
-            installApp(MANAGED_PROFILE_APK);
+            mParentUserId = mPrimaryUserId;
+            mProfileUserId = createManagedProfile(mParentUserId);
+            installAppAsUser(MANAGED_PROFILE_APK, mProfileUserId);
             setProfileOwnerOrFail(MANAGED_PROFILE_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS,
                     mProfileUserId);
-            mProfileSerialNumber = getUserSerialNumber(mProfileUserId);
-            mMainUserSerialNumber = getUserSerialNumber(0);
+            mProfileSerialNumber = Integer.toString(getUserSerialNumber(mProfileUserId));
+            mMainUserSerialNumber = Integer.toString(getUserSerialNumber(mParentUserId));
             startUser(mProfileUserId);
         }
     }
@@ -57,7 +61,6 @@
         if (mHasFeature) {
             removeUser(mProfileUserId);
             uninstallTestApps();
-            getDevice().uninstallPackage(MANAGED_PROFILE_PKG);
         }
         super.tearDown();
     }
@@ -67,19 +70,17 @@
             return;
         }
         // Install app for all users.
-        installApp(SIMPLE_APP_APK);
-        try {
-            // Run tests to check SimpleApp exists in both profile and main user.
-            assertTrue(runDeviceTests(LAUNCHER_TESTS_PKG,
-                    LAUNCHER_TESTS_CLASS,
-                    "testSimpleAppInstalledForUser",
-                            0, "-e testUser " + mProfileSerialNumber));
-            assertTrue(runDeviceTests(LAUNCHER_TESTS_PKG,
-                    LAUNCHER_TESTS_PKG + ".LauncherAppsTests", "testSimpleAppInstalledForUser",
-                            0, "-e testUser " + mMainUserSerialNumber));
-        } finally {
-            getDevice().uninstallPackage(SIMPLE_APP_PKG);
-        }
+        installAppAsUser(SIMPLE_APP_APK, mParentUserId);
+        installAppAsUser(SIMPLE_APP_APK, mProfileUserId);
+
+        // Run tests to check SimpleApp exists in both profile and main user.
+        assertTrue(runDeviceTestsAsUser(LAUNCHER_TESTS_PKG,
+                LAUNCHER_TESTS_CLASS,
+                "testSimpleAppInstalledForUser",
+                mParentUserId, Collections.singletonMap(PARAM_TEST_USER, mProfileSerialNumber)));
+        assertTrue(runDeviceTestsAsUser(LAUNCHER_TESTS_PKG,
+                LAUNCHER_TESTS_PKG + ".LauncherAppsTests", "testSimpleAppInstalledForUser",
+                mParentUserId, Collections.singletonMap(PARAM_TEST_USER, mMainUserSerialNumber)));
     }
 
     public void testLauncherCallbackPackageAddedProfile() throws Exception {
@@ -87,48 +88,36 @@
             return;
         }
         startCallbackService();
-        installApp(SIMPLE_APP_APK);
-        try {
-            assertTrue(runDeviceTests(LAUNCHER_TESTS_PKG,
-                    LAUNCHER_TESTS_CLASS,
-                            "testPackageAddedCallbackForUser",
-                            0, "-e testUser " + mProfileSerialNumber));
-        } finally {
-            getDevice().uninstallPackage(SIMPLE_APP_PKG);
-        }
+        installAppAsUser(SIMPLE_APP_APK, mProfileUserId);
+        assertTrue(runDeviceTestsAsUser(LAUNCHER_TESTS_PKG,
+                LAUNCHER_TESTS_CLASS,
+                "testPackageAddedCallbackForUser",
+                mParentUserId, Collections.singletonMap(PARAM_TEST_USER, mProfileSerialNumber)));
     }
 
     public void testLauncherCallbackPackageRemovedProfile() throws Exception {
         if (!mHasFeature) {
             return;
         }
-        installApp(SIMPLE_APP_APK);
-        try {
-            startCallbackService();
-            getDevice().uninstallPackage(SIMPLE_APP_PKG);
-            assertTrue(runDeviceTests(LAUNCHER_TESTS_PKG,
-                    LAUNCHER_TESTS_CLASS,
-                            "testPackageRemovedCallbackForUser",
-                            0, "-e testUser " + mProfileSerialNumber));
-        } finally {
-            getDevice().uninstallPackage(SIMPLE_APP_PKG);
-        }
+        installAppAsUser(SIMPLE_APP_APK, mProfileUserId);
+        startCallbackService();
+        getDevice().uninstallPackage(SIMPLE_APP_PKG);
+        assertTrue(runDeviceTestsAsUser(LAUNCHER_TESTS_PKG,
+                LAUNCHER_TESTS_CLASS,
+                "testPackageRemovedCallbackForUser",
+                mParentUserId, Collections.singletonMap(PARAM_TEST_USER, mProfileSerialNumber)));
     }
 
     public void testLauncherCallbackPackageChangedProfile() throws Exception {
         if (!mHasFeature) {
             return;
         }
-        installApp(SIMPLE_APP_APK);
-        try {
-            startCallbackService();
-            installApp(SIMPLE_APP_APK);
-            assertTrue(runDeviceTests(LAUNCHER_TESTS_PKG,
-                    LAUNCHER_TESTS_CLASS,
-                            "testPackageChangedCallbackForUser",
-                            0, "-e testUser " + mProfileSerialNumber));
-        } finally {
-            getDevice().uninstallPackage(SIMPLE_APP_PKG);
-        }
+        installAppAsUser(SIMPLE_APP_APK, mProfileUserId);
+        startCallbackService();
+        installAppAsUser(SIMPLE_APP_APK, mProfileUserId);
+        assertTrue(runDeviceTestsAsUser(LAUNCHER_TESTS_PKG,
+                LAUNCHER_TESTS_CLASS,
+                "testPackageChangedCallbackForUser",
+                mParentUserId, Collections.singletonMap(PARAM_TEST_USER, mProfileSerialNumber)));
     }
 }
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/LauncherAppsSingleUserTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/LauncherAppsSingleUserTest.java
index 32be962..a2a1986 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/LauncherAppsSingleUserTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/LauncherAppsSingleUserTest.java
@@ -20,12 +20,15 @@
 import com.android.tradefed.device.DeviceNotAvailableException;
 import com.android.tradefed.log.LogUtil.CLog;
 
+import java.util.Collections;
+
 /**
  * Set of tests for LauncherApps with managed profiles.
  */
 public class LauncherAppsSingleUserTest extends BaseLauncherAppsTest {
 
     private boolean mHasLauncherApps;
+    private String mSerialNumber;
 
     @Override
     protected void setUp() throws Exception {
@@ -33,6 +36,7 @@
         mHasLauncherApps = getDevice().getApiLevel() >= 21;
 
         if (mHasLauncherApps) {
+            mSerialNumber = Integer.toString(getUserSerialNumber(USER_SYSTEM));
             installTestApps();
         }
     }
@@ -49,15 +53,10 @@
         if (!mHasLauncherApps) {
             return;
         }
-        installApp(SIMPLE_APP_APK);
-        try {
-            int serialNumber = getUserSerialNumber(0);
-            assertTrue(runDeviceTests(LAUNCHER_TESTS_PKG,
-                    LAUNCHER_TESTS_CLASS, "testSimpleAppInstalledForUser",
-                            0, "-e testUser " + serialNumber));
-        } finally {
-            getDevice().uninstallPackage(SIMPLE_APP_PKG);
-        }
+        installAppAsUser(SIMPLE_APP_APK, mPrimaryUserId);
+        assertTrue(runDeviceTestsAsUser(LAUNCHER_TESTS_PKG,
+                LAUNCHER_TESTS_CLASS, "testSimpleAppInstalledForUser",
+                mPrimaryUserId, Collections.singletonMap(PARAM_TEST_USER, mSerialNumber)));
     }
 
     public void testLauncherCallbackPackageAddedMainUser() throws Exception {
@@ -65,96 +64,67 @@
             return;
         }
         startCallbackService();
-        installApp(SIMPLE_APP_APK);
-        try {
-            int serialNumber = getUserSerialNumber(0);
-            assertTrue(runDeviceTests(LAUNCHER_TESTS_PKG,
-                    LAUNCHER_TESTS_CLASS,
-                            "testPackageAddedCallbackForUser",
-                            0, "-e testUser " + serialNumber));
-        } finally {
-            getDevice().uninstallPackage(SIMPLE_APP_PKG);
-        }
+        installAppAsUser(SIMPLE_APP_APK, mPrimaryUserId);
+
+        assertTrue(runDeviceTestsAsUser(LAUNCHER_TESTS_PKG,
+                LAUNCHER_TESTS_CLASS,
+                "testPackageAddedCallbackForUser",
+                mPrimaryUserId, Collections.singletonMap(PARAM_TEST_USER, mSerialNumber)));
     }
 
     public void testLauncherCallbackPackageRemovedMainUser() throws Exception {
         if (!mHasLauncherApps) {
             return;
         }
-        installApp(SIMPLE_APP_APK);
-        try {
-            startCallbackService();
-            int serialNumber = getUserSerialNumber(0);
-            getDevice().uninstallPackage(SIMPLE_APP_PKG);
-            assertTrue(runDeviceTests(LAUNCHER_TESTS_PKG,
-                    LAUNCHER_TESTS_CLASS,
-                            "testPackageRemovedCallbackForUser",
-                            0, "-e testUser " + serialNumber));
-        } finally {
-            getDevice().uninstallPackage(SIMPLE_APP_PKG);
-        }
+        installAppAsUser(SIMPLE_APP_APK, mPrimaryUserId);
+        startCallbackService();
+        getDevice().uninstallPackage(SIMPLE_APP_PKG);
+        assertTrue(runDeviceTestsAsUser(LAUNCHER_TESTS_PKG,
+                LAUNCHER_TESTS_CLASS,
+                "testPackageRemovedCallbackForUser",
+                mPrimaryUserId, Collections.singletonMap(PARAM_TEST_USER, mSerialNumber)));
     }
 
     public void testLauncherCallbackPackageChangedMainUser() throws Exception {
         if (!mHasLauncherApps) {
             return;
         }
-        installApp(SIMPLE_APP_APK);
-        try {
-            startCallbackService();
-            int serialNumber = getUserSerialNumber(0);
-            installApp(SIMPLE_APP_APK);
-            assertTrue(runDeviceTests(LAUNCHER_TESTS_PKG,
-                    LAUNCHER_TESTS_CLASS,
-                            "testPackageChangedCallbackForUser",
-                            0, "-e testUser " + serialNumber));
-        } finally {
-            getDevice().uninstallPackage(SIMPLE_APP_PKG);
-        }
+        installAppAsUser(SIMPLE_APP_APK, mPrimaryUserId);
+        startCallbackService();
+        installAppAsUser(SIMPLE_APP_APK, mPrimaryUserId);
+        assertTrue(runDeviceTestsAsUser(LAUNCHER_TESTS_PKG,
+                LAUNCHER_TESTS_CLASS,
+                "testPackageChangedCallbackForUser",
+                mPrimaryUserId, Collections.singletonMap(PARAM_TEST_USER, mSerialNumber)));
     }
 
     public void testLauncherNonExportedAppFails() throws Exception {
         if (!mHasLauncherApps) {
             return;
         }
-        installApp(SIMPLE_APP_APK);
-        try {
-            int serialNumber = getUserSerialNumber(0);
-            assertTrue(runDeviceTests(LAUNCHER_TESTS_PKG,
-                    LAUNCHER_TESTS_CLASS, "testLaunchNonExportActivityFails",
-                            0, "-e testUser " + serialNumber));
-        } finally {
-            getDevice().uninstallPackage(SIMPLE_APP_PKG);
-        }
+        installAppAsUser(SIMPLE_APP_APK, mPrimaryUserId);
+        assertTrue(runDeviceTestsAsUser(LAUNCHER_TESTS_PKG,
+                LAUNCHER_TESTS_CLASS, "testLaunchNonExportActivityFails",
+                mPrimaryUserId, Collections.singletonMap(PARAM_TEST_USER, mSerialNumber)));
     }
 
     public void testLaunchNonExportActivityFails() throws Exception {
         if (!mHasLauncherApps) {
             return;
         }
-        installApp(SIMPLE_APP_APK);
-        try {
-            int serialNumber = getUserSerialNumber(0);
-            assertTrue(runDeviceTests(LAUNCHER_TESTS_PKG,
-                    LAUNCHER_TESTS_CLASS, "testLaunchNonExportLauncherFails",
-                            0, "-e testUser " + serialNumber));
-        } finally {
-            getDevice().uninstallPackage(SIMPLE_APP_PKG);
-        }
+        installAppAsUser(SIMPLE_APP_APK, mPrimaryUserId);
+        assertTrue(runDeviceTestsAsUser(LAUNCHER_TESTS_PKG,
+                LAUNCHER_TESTS_CLASS, "testLaunchNonExportLauncherFails",
+                mPrimaryUserId, Collections.singletonMap(PARAM_TEST_USER, mSerialNumber)));
     }
 
     public void testLaunchMainActivity() throws Exception {
         if (!mHasLauncherApps) {
             return;
         }
-        installApp(SIMPLE_APP_APK);
-        try {
-            int serialNumber = getUserSerialNumber(0);
-            assertTrue(runDeviceTests(LAUNCHER_TESTS_PKG,
-                    LAUNCHER_TESTS_CLASS, "testLaunchMainActivity",
-                            0, "-e testUser " + serialNumber));
-        } finally {
-            getDevice().uninstallPackage(SIMPLE_APP_PKG);
-        }
+        installAppAsUser(SIMPLE_APP_APK, mPrimaryUserId);
+        assertTrue(runDeviceTestsAsUser(LAUNCHER_TESTS_PKG,
+                LAUNCHER_TESTS_CLASS, "testLaunchMainActivity",
+                mPrimaryUserId, Collections.singletonMap(PARAM_TEST_USER, mSerialNumber)));
     }
 }
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
index 6cab501..e21a07f 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
@@ -22,6 +22,8 @@
 
 import junit.framework.AssertionFailedError;
 
+import java.util.concurrent.Callable;
+
 /**
  * Set of tests for Managed Profile use cases.
  */
@@ -48,6 +50,15 @@
     private static final String WIDGET_PROVIDER_APK = "CtsWidgetProviderApp.apk";
     private static final String WIDGET_PROVIDER_PKG = "com.android.cts.widgetprovider";
 
+    private static final String DIRECTORY_PROVIDER_APK = "CtsContactDirectoryProvider.apk";
+    private static final String DIRECTORY_PROVIDER_PKG
+            = "com.android.cts.contactdirectoryprovider";
+    private static final String PRIMARY_DIRECTORY_PREFIX = "Primary";
+    private static final String MANAGED_DIRECTORY_PREFIX = "Managed";
+    private static final String DIRECTORY_PRIVOIDER_URI
+            = "content://com.android.cts.contact.directory.provider/";
+    private static final String SET_CUSTOM_DIRECTORY_PREFIX_METHOD = "set_prefix";
+
     private static final String ADMIN_RECEIVER_TEST_CLASS =
             MANAGED_PROFILE_PKG + ".BaseManagedProfileTest$BasicAdminReceiver";
 
@@ -57,10 +68,10 @@
 
     private static final String ADD_RESTRICTION_COMMAND = "add-restriction";
 
-    private static final int USER_OWNER = 0;
+    private int mParentUserId;
 
-    // ID of the profile we'll create. This will always be a profile of USER_OWNER.
-    private int mUserId;
+    // ID of the profile we'll create. This will always be a profile of the parent.
+    private int mProfileUserId;
     private String mPackageVerifier;
 
     private boolean mHasNfcFeature;
@@ -76,18 +87,21 @@
 
         if (mHasFeature) {
             removeTestUsers();
-            mUserId = createManagedProfile();
+            mParentUserId = mPrimaryUserId;
+            mProfileUserId = createManagedProfile(mParentUserId);
 
-            installApp(MANAGED_PROFILE_APK);
-            setProfileOwnerOrFail(MANAGED_PROFILE_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS, mUserId);
-            startUser(mUserId);
+            installAppAsUser(MANAGED_PROFILE_APK, mParentUserId);
+            installAppAsUser(MANAGED_PROFILE_APK, mProfileUserId);
+            setProfileOwnerOrFail(MANAGED_PROFILE_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS,
+                    mProfileUserId);
+            startUser(mProfileUserId);
         }
     }
 
     @Override
     protected void tearDown() throws Exception {
         if (mHasFeature) {
-            removeUser(mUserId);
+            removeUser(mProfileUserId);
             getDevice().uninstallPackage(MANAGED_PROFILE_PKG);
             getDevice().uninstallPackage(INTENT_SENDER_PKG);
             getDevice().uninstallPackage(INTENT_RECEIVER_PKG);
@@ -100,7 +114,8 @@
             return;
         }
         assertTrue(runDeviceTestsAsUser(
-                MANAGED_PROFILE_PKG, MANAGED_PROFILE_PKG + ".ManagedProfileSetupTest", mUserId));
+                MANAGED_PROFILE_PKG, MANAGED_PROFILE_PKG + ".ManagedProfileSetupTest",
+                mProfileUserId));
     }
 
     /**
@@ -110,18 +125,18 @@
         if (!mHasFeature) {
             return;
         }
-        assertTrue(listUsers().contains(mUserId));
+        assertTrue(listUsers().contains(mProfileUserId));
         assertTrue(runDeviceTestsAsUser(
-                MANAGED_PROFILE_PKG, MANAGED_PROFILE_PKG + ".WipeDataTest", mUserId));
+                MANAGED_PROFILE_PKG, MANAGED_PROFILE_PKG + ".WipeDataTest", mProfileUserId));
         // Note: the managed profile is removed by this test, which will make removeUserCommand in
         // tearDown() to complain, but that should be OK since its result is not asserted.
-        assertFalse(listUsers().contains(mUserId));
+        assertFalse(listUsers().contains(mProfileUserId));
     }
 
     public void testMaxOneManagedProfile() throws Exception {
         int newUserId = -1;
         try {
-            newUserId = createManagedProfile();
+            newUserId = createManagedProfile(mParentUserId);
         } catch (AssertionFailedError expected) {
         }
         if (newUserId > 0) {
@@ -139,19 +154,17 @@
             return;
         }
         assertTrue("WiFi config already exists and could not be removed", runDeviceTestsAsUser(
-                MANAGED_PROFILE_PKG, ".WifiTest", "testRemoveWifiNetworkIfExists", USER_OWNER));
-        try {
-            installApp(WIFI_CONFIG_CREATOR_APK);
-            assertTrue("Failed to add WiFi config", runDeviceTestsAsUser(
-                    MANAGED_PROFILE_PKG, ".WifiTest", "testAddWifiNetwork", mUserId));
+                MANAGED_PROFILE_PKG, ".WifiTest", "testRemoveWifiNetworkIfExists", mParentUserId));
 
-            // Now delete the user - should undo the effect of testAddWifiNetwork.
-            removeUser(mUserId);
-            assertTrue("WiFi config not removed after deleting profile", runDeviceTestsAsUser(
-                    MANAGED_PROFILE_PKG, ".WifiTest", "testWifiNetworkDoesNotExist", USER_OWNER));
-        } finally {
-            getDevice().uninstallPackage(WIFI_CONFIG_CREATOR_APK);
-        }
+        installAppAsUser(WIFI_CONFIG_CREATOR_APK, mProfileUserId);
+        assertTrue("Failed to add WiFi config", runDeviceTestsAsUser(
+                MANAGED_PROFILE_PKG, ".WifiTest", "testAddWifiNetwork", mProfileUserId));
+
+        // Now delete the user - should undo the effect of testAddWifiNetwork.
+        removeUser(mProfileUserId);
+        assertTrue("WiFi config not removed after deleting profile", runDeviceTestsAsUser(
+                MANAGED_PROFILE_PKG, ".WifiTest", "testWifiNetworkDoesNotExist",
+                mParentUserId));
     }
 
     public void testCrossProfileIntentFilters() throws Exception {
@@ -160,18 +173,19 @@
         }
         // Set up activities: ManagedProfileActivity will only be enabled in the managed profile and
         // PrimaryUserActivity only in the primary one
-        disableActivityForUser("ManagedProfileActivity", 0);
-        disableActivityForUser("PrimaryUserActivity", mUserId);
+        disableActivityForUser("ManagedProfileActivity", mParentUserId);
+        disableActivityForUser("PrimaryUserActivity", mProfileUserId);
 
         assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG,
-                MANAGED_PROFILE_PKG + ".ManagedProfileTest", mUserId));
+                MANAGED_PROFILE_PKG + ".ManagedProfileTest", mProfileUserId));
 
         // Set up filters from primary to managed profile
-        String command = "am start -W --user " + mUserId  + " " + MANAGED_PROFILE_PKG
+        String command = "am start -W --user " + mProfileUserId  + " " + MANAGED_PROFILE_PKG
                 + "/.PrimaryUserFilterSetterActivity";
         CLog.logAndDisplay(LogLevel.INFO, "Output for command " + command + ": "
               + getDevice().executeShellCommand(command));
-        assertTrue(runDeviceTests(MANAGED_PROFILE_PKG, MANAGED_PROFILE_PKG + ".PrimaryUserTest"));
+        assertTrue(runDeviceTestsAsUser(
+                MANAGED_PROFILE_PKG, MANAGED_PROFILE_PKG + ".PrimaryUserTest", mParentUserId));
         // TODO: Test with startActivity
     }
 
@@ -182,32 +196,33 @@
         // Disable all pre-existing browsers in the managed profile so they don't interfere with
         // intents resolution.
         assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileUtils",
-                "testDisableAllBrowsers", mUserId));
-        installApp(INTENT_RECEIVER_APK);
-        installApp(INTENT_SENDER_APK);
+                "testDisableAllBrowsers", mProfileUserId));
+        installAppAsUser(INTENT_RECEIVER_APK, mParentUserId);
+        installAppAsUser(INTENT_SENDER_APK, mParentUserId);
+        installAppAsUser(INTENT_RECEIVER_APK, mProfileUserId);
+        installAppAsUser(INTENT_SENDER_APK, mProfileUserId);
 
-        changeVerificationStatus(USER_OWNER, INTENT_RECEIVER_PKG, "ask");
-        changeVerificationStatus(mUserId, INTENT_RECEIVER_PKG, "ask");
+        changeVerificationStatus(mParentUserId, INTENT_RECEIVER_PKG, "ask");
+        changeVerificationStatus(mProfileUserId, INTENT_RECEIVER_PKG, "ask");
         // We should have two receivers: IntentReceiverActivity and BrowserActivity in the
         // managed profile
         assertAppLinkResult("testTwoReceivers");
 
         changeUserRestrictionForUser("allow_parent_profile_app_linking", ADD_RESTRICTION_COMMAND,
-                mUserId);
+                mProfileUserId);
         // Now we should also have one receiver in the primary user, so three receivers in total.
         assertAppLinkResult("testThreeReceivers");
 
-        changeVerificationStatus(USER_OWNER, INTENT_RECEIVER_PKG, "never");
+        changeVerificationStatus(mParentUserId, INTENT_RECEIVER_PKG, "never");
         // The primary user one has been set to never: we should only have the managed profile ones.
         assertAppLinkResult("testTwoReceivers");
 
-        changeVerificationStatus(mUserId, INTENT_RECEIVER_PKG, "never");
+        changeVerificationStatus(mProfileUserId, INTENT_RECEIVER_PKG, "never");
         // Now there's only the browser in the managed profile left
         assertAppLinkResult("testReceivedByBrowserActivityInManaged");
 
-
-        changeVerificationStatus(mUserId, INTENT_RECEIVER_PKG, "always");
-        changeVerificationStatus(USER_OWNER, INTENT_RECEIVER_PKG, "always");
+        changeVerificationStatus(mProfileUserId, INTENT_RECEIVER_PKG, "always");
+        changeVerificationStatus(mParentUserId, INTENT_RECEIVER_PKG, "always");
         // We have one always in the primary user and one always in the managed profile: the managed
         // profile one should have precedence.
         assertAppLinkResult("testReceivedByAppLinkActivityInManaged");
@@ -219,29 +234,32 @@
             return;
         }
 
-        assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".SettingsIntentsTest", mUserId));
+        assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".SettingsIntentsTest",
+                mProfileUserId));
     }
 
     public void testCrossProfileContent() throws Exception {
         if (!mHasFeature) {
             return;
         }
-        installApp(INTENT_RECEIVER_APK);
-        installApp(INTENT_SENDER_APK);
+        installAppAsUser(INTENT_RECEIVER_APK, mParentUserId);
+        installAppAsUser(INTENT_SENDER_APK, mParentUserId);
+        installAppAsUser(INTENT_RECEIVER_APK, mProfileUserId);
+        installAppAsUser(INTENT_SENDER_APK, mProfileUserId);
 
         // Test from parent to managed
         assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileUtils",
-                "testRemoveAllFilters", mUserId));
+                "testRemoveAllFilters", mProfileUserId));
         assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileUtils",
-                "testAddManagedCanAccessParentFilters", mUserId));
-        assertTrue(runDeviceTestsAsUser(INTENT_SENDER_PKG, ".ContentTest", 0));
+                "testAddManagedCanAccessParentFilters", mProfileUserId));
+        assertTrue(runDeviceTestsAsUser(INTENT_SENDER_PKG, ".ContentTest", mParentUserId));
 
         // Test from managed to parent
         assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileUtils",
-                "testRemoveAllFilters", mUserId));
+                "testRemoveAllFilters", mProfileUserId));
         assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileUtils",
-                "testAddParentCanAccessManagedFilters", mUserId));
-        assertTrue(runDeviceTestsAsUser(INTENT_SENDER_PKG, ".ContentTest", mUserId));
+                "testAddParentCanAccessManagedFilters", mProfileUserId));
+        assertTrue(runDeviceTestsAsUser(INTENT_SENDER_PKG, ".ContentTest", mProfileUserId));
 
     }
 
@@ -249,33 +267,35 @@
         if (!mHasFeature) {
             return;
         }
-        installApp(INTENT_RECEIVER_APK);
-        installApp(INTENT_SENDER_APK);
+        installAppAsUser(INTENT_RECEIVER_APK, mParentUserId);
+        installAppAsUser(INTENT_SENDER_APK, mParentUserId);
+        installAppAsUser(INTENT_RECEIVER_APK, mProfileUserId);
+        installAppAsUser(INTENT_SENDER_APK, mProfileUserId);
 
         assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileUtils",
-                "testAllowCrossProfileCopyPaste", mUserId));
+                "testAllowCrossProfileCopyPaste", mProfileUserId));
         // Test that managed can see what is copied in the parent.
-        testCrossProfileCopyPasteInternal(mUserId, true);
+        testCrossProfileCopyPasteInternal(mProfileUserId, true);
         // Test that the parent can see what is copied in managed.
-        testCrossProfileCopyPasteInternal(0, true);
+        testCrossProfileCopyPasteInternal(mParentUserId, true);
 
         assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileUtils",
-                "testDisallowCrossProfileCopyPaste", mUserId));
+                "testDisallowCrossProfileCopyPaste", mProfileUserId));
         // Test that managed can still see what is copied in the parent.
-        testCrossProfileCopyPasteInternal(mUserId, true);
+        testCrossProfileCopyPasteInternal(mProfileUserId, true);
         // Test that the parent cannot see what is copied in managed.
-        testCrossProfileCopyPasteInternal(0, false);
+        testCrossProfileCopyPasteInternal(mParentUserId, false);
     }
 
     private void testCrossProfileCopyPasteInternal(int userId, boolean shouldSucceed)
             throws DeviceNotAvailableException {
-        final String direction = (userId == 0)
+        final String direction = (userId == mParentUserId)
                 ? "testAddManagedCanAccessParentFilters"
                 : "testAddParentCanAccessManagedFilters";
         assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileUtils",
-                "testRemoveAllFilters", mUserId));
+                "testRemoveAllFilters", mProfileUserId));
         assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileUtils",
-                direction, mUserId));
+                direction, mProfileUserId));
         if (shouldSucceed) {
             assertTrue(runDeviceTestsAsUser(INTENT_SENDER_PKG, ".CopyPasteTest",
                     "testCanReadAcrossProfiles", userId));
@@ -289,7 +309,7 @@
 
     // TODO: This test is not specific to managed profiles, but applies to multi-user in general.
     // Move it to a MultiUserTest class when there is one. Should probably move
-    // UserRestrictionActivity to a more generic apk too as it might be useful for different kinds
+    // SetPolicyActivity to a more generic apk too as it might be useful for different kinds
     // of tests (same applies to ComponentDisablingActivity).
     public void testNoDebuggingFeaturesRestriction() throws Exception {
         if (!mHasFeature) {
@@ -306,14 +326,14 @@
         String restriction = "no_debugging_features";  // UserManager.DISALLOW_DEBUGGING_FEATURES
 
         String addRestrictionCommandOutput =
-                changeUserRestrictionForUser(restriction, ADD_RESTRICTION_COMMAND, mUserId);
+                changeUserRestrictionForUser(restriction, ADD_RESTRICTION_COMMAND, mProfileUserId);
         assertTrue("Command was expected to succeed " + addRestrictionCommandOutput,
                 addRestrictionCommandOutput.contains("Status: ok"));
 
         // This should now fail, as the shell is not available to start activities under a different
         // user once the restriction is in place.
         addRestrictionCommandOutput =
-                changeUserRestrictionForUser(restriction, ADD_RESTRICTION_COMMAND, mUserId);
+                changeUserRestrictionForUser(restriction, ADD_RESTRICTION_COMMAND, mProfileUserId);
         assertTrue(
                 "Expected SecurityException when starting the activity "
                         + addRestrictionCommandOutput,
@@ -328,13 +348,13 @@
         }
 
         assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".BluetoothTest",
-                "testEnableDisable", mUserId));
+                "testEnableDisable", mProfileUserId));
         assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".BluetoothTest",
-                "testGetAddress", mUserId));
+                "testGetAddress", mProfileUserId));
         assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".BluetoothTest",
-                "testListenUsingRfcommWithServiceRecord", mUserId));
+                "testListenUsingRfcommWithServiceRecord", mProfileUserId));
         assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".BluetoothTest",
-                "testGetRemoteDevice", mUserId));
+                "testGetRemoteDevice", mProfileUserId));
     }
 
     public void testCameraPolicy() throws Exception {
@@ -343,176 +363,126 @@
             return;
         }
         try {
-            setDeviceAdmin(MANAGED_PROFILE_PKG + "/.PrimaryUserDeviceAdmin");
+            setDeviceAdmin(MANAGED_PROFILE_PKG + "/.PrimaryUserDeviceAdmin", mParentUserId);
 
             // Disable managed profile camera.
             assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CameraPolicyTest",
                     "testDisableCameraInManagedProfile",
-                    mUserId));
+                    mProfileUserId));
             assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CameraPolicyTest",
                     "testIsCameraEnabledInPrimaryProfile",
-                    0));
+                    mParentUserId));
 
             // Enable managed profile camera.
             assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CameraPolicyTest",
                     "testEnableCameraInManagedProfile",
-                    mUserId));
+                    mProfileUserId));
             assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CameraPolicyTest",
                     "testIsCameraEnabledInPrimaryProfile",
-                    0));
+                    mParentUserId));
 
             // Disable primary profile camera.
             assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CameraPolicyTest",
                     "testDisableCameraInPrimaryProfile",
-                    0));
+                    mParentUserId));
             assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CameraPolicyTest",
                     "testIsCameraEnabledInManagedProfile",
-                    mUserId));
+                    mProfileUserId));
 
             // Enable primary profile camera.
             assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CameraPolicyTest",
                     "testEnableCameraInPrimaryProfile",
-                    0));
+                    mParentUserId));
             assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CameraPolicyTest",
                     "testIsCameraEnabledInManagedProfile",
-                    mUserId));
+                    mProfileUserId));
         } finally {
             final String adminHelperClass = ".PrimaryUserAdminHelper";
             assertTrue("Clear device admin failed", runDeviceTestsAsUser(MANAGED_PROFILE_PKG,
-                    adminHelperClass, "testClearDeviceAdmin", 0 /* user 0 */));
+                    adminHelperClass, "testClearDeviceAdmin", mParentUserId));
         }
     }
 
-    public void testManagedContacts() throws Exception {
+
+    public void testManagedContactsUris() throws Exception {
+        runManagedContactsTest(new Callable<Void>() {
+            @Override
+            public Void call() throws Exception {
+                ContactsTestSet contactsTestSet = new ContactsTestSet(ManagedProfileTest.this,
+                        MANAGED_PROFILE_PKG, mParentUserId, mProfileUserId);
+
+                contactsTestSet.setCallerIdEnabled(true);
+                contactsTestSet.setContactsSearchEnabled(true);
+                contactsTestSet.checkIfCanLookupEnterpriseContacts(true);
+                contactsTestSet.checkIfCanFilterEnterpriseContacts(true);
+                contactsTestSet.checkIfCanFilterSelfContacts();
+                return null;
+            }
+        });
+    }
+
+    public void testManagedQuickContacts() throws Exception {
+        runManagedContactsTest(new Callable<Void>() {
+            @Override
+            public Void call() throws Exception {
+                assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ContactsTest",
+                        "testQuickContact", mParentUserId));
+                return null;
+            }
+        });
+    }
+
+    public void testManagedContactsPolicies() throws Exception {
+        runManagedContactsTest(new Callable<Void>() {
+            @Override
+            public Void call() throws Exception {
+                ContactsTestSet contactsTestSet = new ContactsTestSet(ManagedProfileTest.this,
+                        MANAGED_PROFILE_PKG, mParentUserId, mProfileUserId);
+                try {
+                    contactsTestSet.setCallerIdEnabled(true);
+                    contactsTestSet.setContactsSearchEnabled(false);
+                    contactsTestSet.checkIfCanLookupEnterpriseContacts(true);
+                    contactsTestSet.checkIfCanFilterEnterpriseContacts(false);
+                    contactsTestSet.checkIfCanFilterSelfContacts();
+                    contactsTestSet.setCallerIdEnabled(false);
+                    contactsTestSet.setContactsSearchEnabled(true);
+                    contactsTestSet.checkIfCanLookupEnterpriseContacts(false);
+                    contactsTestSet.checkIfCanFilterEnterpriseContacts(true);
+                    contactsTestSet.checkIfCanFilterSelfContacts();
+                    contactsTestSet.setCallerIdEnabled(false);
+                    contactsTestSet.setContactsSearchEnabled(false);
+                    contactsTestSet.checkIfCanLookupEnterpriseContacts(false);
+                    contactsTestSet.checkIfCanFilterEnterpriseContacts(false);
+                    contactsTestSet.checkIfCanFilterSelfContacts();
+                    contactsTestSet.checkIfNoEnterpriseDirectoryFound();
+                    return null;
+                } finally {
+                    // reset policies
+                    contactsTestSet.setCallerIdEnabled(true);
+                    contactsTestSet.setContactsSearchEnabled(true);
+                }
+            }
+        });
+    }
+
+    public void testOrganizationInfo() throws Exception {
         if (!mHasFeature) {
             return;
         }
+        assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".OrganizationInfoTest",
+                "testDefaultOrganizationColorIsGray", mProfileUserId));
+        assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".OrganizationInfoTest",
+                "testDefaultOrganizationNameIsNull", mProfileUserId));
+        assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".OrganizationInfoTest",
+                mProfileUserId));
+    }
 
-        try {
-            // Add test account
-            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ContactsTest",
-                    "testAddTestAccount", 0));
-            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ContactsTest",
-                    "testAddTestAccount", mUserId));
-
-            // Insert Primary profile Contacts
-            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ContactsTest",
-                    "testPrimaryProfilePhoneAndEmailLookup_insertedAndfound", 0));
-            // Insert Managed profile Contacts
-            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ContactsTest",
-                    "testManagedProfilePhoneAndEmailLookup_insertedAndfound", mUserId));
-            // Insert a primary contact with same phone & email as other enterprise contacts
-            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ContactsTest",
-                    "testPrimaryProfileDuplicatedPhoneEmailContact_insertedAndfound", 0));
-            // Insert a enterprise contact with same phone & email as other primary contacts
-            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ContactsTest",
-                    "testManagedProfileDuplicatedPhoneEmailContact_insertedAndfound", mUserId));
-
-
-            // Set cross profile caller id to enabled
-            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ContactsTest",
-                    "testSetCrossProfileCallerIdDisabled_false", mUserId));
-
-            // Primary user cannot use ordinary phone/email lookup api to access managed contacts
-            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ContactsTest",
-                    "testPrimaryProfilePhoneLookup_canNotAccessEnterpriseContact", 0));
-            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ContactsTest",
-                    "testPrimaryProfileEmailLookup_canNotAccessEnterpriseContact", 0));
-            // Primary user can use ENTERPRISE_CONTENT_FILTER_URI to access primary contacts
-            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ContactsTest",
-                    "testPrimaryProfileEnterprisePhoneLookup_canAccessPrimaryContact", 0));
-            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ContactsTest",
-                    "testPrimaryProfileEnterpriseEmailLookup_canAccessPrimaryContact", 0));
-            // Primary user can use ENTERPRISE_CONTENT_FILTER_URI to access managed profile contacts
-            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ContactsTest",
-                    "testPrimaryProfileEnterprisePhoneLookup_canAccessEnterpriseContact", 0));
-            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ContactsTest",
-                    "testPrimaryProfileEnterpriseEmailLookup_canAccessEnterpriseContact", 0));
-            // When there exist contacts with the same phone/email in primary & enterprise,
-            // primary user can use ENTERPRISE_CONTENT_FILTER_URI to access the primary contact.
-            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ContactsTest",
-                    "testPrimaryProfileEnterpriseEmailLookupDuplicated_canAccessPrimaryContact",
-                    0));
-            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ContactsTest",
-                    "testPrimaryProfileEnterprisePhoneLookupDuplicated_canAccessPrimaryContact",
-                    0));
-
-            // Make sure SIP enterprise lookup works too.
-            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ContactsTest",
-                    "testPrimaryProfileEnterpriseSipLookup_canAccessEnterpriseContact", 0));
-
-            // Managed user cannot use ordinary phone/email lookup api to access primary contacts
-            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ContactsTest",
-                    "testManagedProfilePhoneLookup_canNotAccessPrimaryContact", mUserId));
-            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ContactsTest",
-                    "testManagedProfileEmailLookup_canNotAccessPrimaryContact", mUserId));
-            // Managed user can use ENTERPRISE_CONTENT_FILTER_URI to access enterprise contacts
-            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ContactsTest",
-                    "testManagedProfileEnterprisePhoneLookup_canAccessEnterpriseContact", mUserId));
-            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ContactsTest",
-                    "testManagedProfileEnterpriseEmailLookup_canAccessEnterpriseContact", mUserId));
-            // Managed user cannot use ENTERPRISE_CONTENT_FILTER_URI to access primary contacts
-            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ContactsTest",
-                    "testManagedProfileEnterprisePhoneLookup_canNotAccessPrimaryContact", mUserId));
-            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ContactsTest",
-                    "testManagedProfileEnterpriseEmailLookup_canNotAccessPrimaryContact", mUserId));
-            // When there exist contacts with the same phone/email in primary & enterprise,
-            // managed user can use ENTERPRISE_CONTENT_FILTER_URI to access the enterprise contact.
-            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ContactsTest",
-                    "testManagedProfileEnterpriseEmailLookupDuplicated_canAccessEnterpriseContact",
-                    mUserId));
-            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ContactsTest",
-                    "testManagedProfileEnterprisePhoneLookupDuplicated_canAccessEnterpriseContact",
-                    mUserId));
-
-            // Set cross profile caller id to disabled
-            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ContactsTest",
-                    "testSetCrossProfileCallerIdDisabled_true", mUserId));
-
-            // Primary user cannot use ordinary phone/email lookup api to access managed contacts
-            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ContactsTest",
-                    "testPrimaryProfilePhoneLookup_canNotAccessEnterpriseContact", 0));
-            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ContactsTest",
-                    "testPrimaryProfileEmailLookup_canNotAccessEnterpriseContact", 0));
-            // Primary user cannot use ENTERPRISE_CONTENT_FILTER_URI to access managed contacts
-            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ContactsTest",
-                    "testPrimaryProfileEnterprisePhoneLookup_canNotAccessEnterpriseContact", 0));
-            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ContactsTest",
-                    "testPrimaryProfileEnterpriseEmailLookup_canNotAccessEnterpriseContact", 0));
-            // When there exist contacts with the same phone/email in primary & enterprise,
-            // primary user can use ENTERPRISE_CONTENT_FILTER_URI to access primary contacts
-            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ContactsTest",
-                    "testPrimaryProfileEnterpriseEmailLookupDuplicated_canAccessPrimaryContact",
-                    0));
-            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ContactsTest",
-                    "testPrimaryProfileEnterprisePhoneLookupDuplicated_canAccessPrimaryContact",
-                    0));
-
-            // Managed user cannot use ordinary phone/email lookup api to access primary contacts
-            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ContactsTest",
-                    "testManagedProfilePhoneLookup_canNotAccessPrimaryContact", mUserId));
-            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ContactsTest",
-                    "testManagedProfileEmailLookup_canNotAccessPrimaryContact", mUserId));
-            // Managed user cannot use ENTERPRISE_CONTENT_FILTER_URI to access primary contacts
-            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ContactsTest",
-                    "testManagedProfileEnterprisePhoneLookup_canNotAccessPrimaryContact", mUserId));
-            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ContactsTest",
-                    "testManagedProfileEnterpriseEmailLookup_canNotAccessPrimaryContact", mUserId));
-            // When there exist contacts with the same phone/email in primary & enterprise,
-            // managed user can use ENTERPRISE_CONTENT_FILTER_URI to access enterprise contacts
-            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ContactsTest",
-                    "testManagedProfileEnterpriseEmailLookupDuplicated_canAccessEnterpriseContact",
-                    mUserId));
-            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ContactsTest",
-                    "testManagedProfileEnterprisePhoneLookupDuplicated_canAccessEnterpriseContact",
-                    mUserId));
-        } finally {
-            // Clean up in managed profile and primary profile
-            runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ContactsTest",
-                    "testCurrentProfileContacts_removeContacts", mUserId);
-            runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ContactsTest",
-                    "testCurrentProfileContacts_removeContacts", 0);
+    public void testPasswordMinimumRestrictions() throws Exception {
+        if (!mHasFeature) {
+            return;
         }
+        assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".PasswordMinimumRestrictionsTest",
+                mProfileUserId));
     }
 
     public void testBluetoothContactSharingDisabled() throws Exception {
@@ -520,7 +490,7 @@
             return;
         }
         assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ContactsTest",
-                "testSetBluetoothContactSharingDisabled_setterAndGetter", mUserId));
+                "testSetBluetoothContactSharingDisabled_setterAndGetter", mProfileUserId));
     }
 
     public void testCannotSetProfileOwnerAgain() throws Exception {
@@ -529,11 +499,11 @@
         }
         // verify that we can't set the same admin receiver as profile owner again
         assertFalse(setProfileOwner(
-                MANAGED_PROFILE_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS, mUserId));
+                MANAGED_PROFILE_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS, mProfileUserId));
 
         // verify that we can't set a different admin receiver as profile owner
-        installAppAsUser(DEVICE_OWNER_APK, mUserId);
-        assertFalse(setProfileOwner(DEVICE_OWNER_PKG + "/" + DEVICE_OWNER_ADMIN, mUserId));
+        installAppAsUser(DEVICE_OWNER_APK, mProfileUserId);
+        assertFalse(setProfileOwner(DEVICE_OWNER_PKG + "/" + DEVICE_OWNER_ADMIN, mProfileUserId));
     }
 
     public void testCannotSetDeviceOwnerWhenProfilePresent() throws Exception {
@@ -542,11 +512,11 @@
         }
 
         try {
-            installApp(DEVICE_OWNER_APK);
-            assertFalse(setDeviceOwner(DEVICE_OWNER_PKG + "/" + DEVICE_OWNER_ADMIN));
+            installAppAsUser(DEVICE_OWNER_APK, mParentUserId);
+            assertFalse(setDeviceOwner(DEVICE_OWNER_PKG + "/" + DEVICE_OWNER_ADMIN, mParentUserId));
         } finally {
             // make sure we clean up in case we succeeded in setting the device owner
-            runDeviceTests(DEVICE_OWNER_PKG, DEVICE_OWNER_CLEAR);
+            runDeviceTestsAsUser(DEVICE_OWNER_PKG, DEVICE_OWNER_CLEAR, mParentUserId);
             getDevice().uninstallPackage(DEVICE_OWNER_PKG);
         }
     }
@@ -557,22 +527,22 @@
         }
 
         assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".NfcTest",
-                "testNfcShareEnabled", mUserId));
+                "testNfcShareEnabled", mProfileUserId));
         assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".NfcTest",
-                "testNfcShareEnabled", 0));
+                "testNfcShareEnabled", mParentUserId));
 
         String restriction = "no_outgoing_beam";  // UserManager.DISALLOW_OUTGOING_BEAM
         String command = "add-restriction";
 
         String addRestrictionCommandOutput =
-                changeUserRestrictionForUser(restriction, command, mUserId);
+                changeUserRestrictionForUser(restriction, command, mProfileUserId);
         assertTrue("Command was expected to succeed " + addRestrictionCommandOutput,
                 addRestrictionCommandOutput.contains("Status: ok"));
 
         assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".NfcTest",
-                "testNfcShareDisabled", mUserId));
+                "testNfcShareDisabled", mProfileUserId));
         assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".NfcTest",
-                "testNfcShareEnabled", 0));
+                "testNfcShareEnabled", mParentUserId));
     }
 
     public void testCrossProfileWidgets() throws Exception {
@@ -581,41 +551,165 @@
         }
 
         try {
-            installApp(WIDGET_PROVIDER_APK);
-            getDevice().executeShellCommand("appwidget grantbind --user 0 --package "
-                    + WIDGET_PROVIDER_PKG);
+            installAppAsUser(WIDGET_PROVIDER_APK, mProfileUserId);
+            installAppAsUser(WIDGET_PROVIDER_APK, mParentUserId);
+            getDevice().executeShellCommand("appwidget grantbind --user " + mParentUserId
+                    + " --package " + WIDGET_PROVIDER_PKG);
             startWidgetHostService();
 
             String commandOutput = changeCrossProfileWidgetForUser(WIDGET_PROVIDER_PKG,
-                    "add-cross-profile-widget", mUserId);
+                    "add-cross-profile-widget", mProfileUserId);
             assertTrue("Command was expected to succeed " + commandOutput,
                     commandOutput.contains("Status: ok"));
 
-            assertTrue(runDeviceTests(MANAGED_PROFILE_PKG, ".CrossProfileWidgetTest",
-                    "testCrossProfileWidgetProviderAdded", mUserId));
-            assertTrue(runDeviceTests(MANAGED_PROFILE_PKG, ".CrossProfileWidgetPrimaryUserTest",
-                    "testHasCrossProfileWidgetProvider_true", 0));
-            assertTrue(runDeviceTests(MANAGED_PROFILE_PKG, ".CrossProfileWidgetPrimaryUserTest",
-                    "testHostReceivesWidgetUpdates_true", 0));
+            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileWidgetTest",
+                    "testCrossProfileWidgetProviderAdded", mProfileUserId));
+            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG,
+                    ".CrossProfileWidgetPrimaryUserTest",
+                    "testHasCrossProfileWidgetProvider_true", mParentUserId));
+            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG,
+                    ".CrossProfileWidgetPrimaryUserTest",
+                    "testHostReceivesWidgetUpdates_true", mParentUserId));
 
             commandOutput = changeCrossProfileWidgetForUser(WIDGET_PROVIDER_PKG,
-                    "remove-cross-profile-widget", mUserId);
+                    "remove-cross-profile-widget", mProfileUserId);
             assertTrue("Command was expected to succeed " + commandOutput,
                     commandOutput.contains("Status: ok"));
 
-            assertTrue(runDeviceTests(MANAGED_PROFILE_PKG, ".CrossProfileWidgetTest",
-                    "testCrossProfileWidgetProviderRemoved", mUserId));
-            assertTrue(runDeviceTests(MANAGED_PROFILE_PKG, ".CrossProfileWidgetPrimaryUserTest",
-                    "testHasCrossProfileWidgetProvider_false", 0));
-            assertTrue(runDeviceTests(MANAGED_PROFILE_PKG, ".CrossProfileWidgetPrimaryUserTest",
-                    "testHostReceivesWidgetUpdates_false", 0));
+            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileWidgetTest",
+                    "testCrossProfileWidgetProviderRemoved", mProfileUserId));
+            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG,
+                    ".CrossProfileWidgetPrimaryUserTest",
+                    "testHasCrossProfileWidgetProvider_false", mParentUserId));
+            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG,
+                    ".CrossProfileWidgetPrimaryUserTest",
+                    "testHostReceivesWidgetUpdates_false", mParentUserId));
         } finally {
             changeCrossProfileWidgetForUser(WIDGET_PROVIDER_PKG, "remove-cross-profile-widget",
-                    mUserId);
+                    mProfileUserId);
             getDevice().uninstallPackage(WIDGET_PROVIDER_PKG);
         }
     }
 
+    public void testIsProvisioningAllowed() throws DeviceNotAvailableException {
+        if (!mHasFeature) {
+            return;
+        }
+        // In Managed profile user when managed profile is provisioned
+        assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".PreManagedProfileTest",
+                "testIsProvisioningAllowedFalse", mProfileUserId));
+
+        // In parent user when managed profile is provisioned
+        // It's allowed to provision again by removing the previous profile
+        assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".PreManagedProfileTest",
+                "testIsProvisioningAllowedTrue", mParentUserId));
+    }
+
+    private void setDirectoryPrefix(String directoryName, int userId)
+            throws DeviceNotAvailableException {
+        String command = "content call --uri " + DIRECTORY_PRIVOIDER_URI
+                + " --user " + userId
+                + " --method " + SET_CUSTOM_DIRECTORY_PREFIX_METHOD
+                + " --arg " + directoryName;
+        CLog.logAndDisplay(LogLevel.INFO, "Output for command " + command + ": "
+                + getDevice().executeShellCommand(command));
+    }
+
+    public void testPhoneAccountVisibility() throws Exception  {
+        if (!mHasFeature) {
+            return;
+        }
+        try {
+            // Register phone account in parent user.
+            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".PhoneAccountTest",
+                    "testRegisterPhoneAccount",
+                    mParentUserId));
+            // The phone account should not be visible in managed user.
+            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".PhoneAccountTest",
+                    "testPhoneAccountNotRegistered",
+                    mProfileUserId));
+        } finally {
+            // Unregister the phone account.
+            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".PhoneAccountTest",
+                    "testUnregisterPhoneAccount",
+                    mParentUserId));
+        }
+
+        try {
+            // Register phone account in profile user.
+            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".PhoneAccountTest",
+                    "testRegisterPhoneAccount",
+                    mProfileUserId));
+            // The phone account should not be visible in parent user.
+            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".PhoneAccountTest",
+                    "testPhoneAccountNotRegistered",
+                    mParentUserId));
+        } finally {
+            // Unregister the phone account.
+            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".PhoneAccountTest",
+                    "testUnregisterPhoneAccount",
+                    mProfileUserId));
+        }
+    }
+
+    public void testManagedCall() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+        // Place a outgoing call through work phone account using TelecomManager and verify the
+        // call is inserted properly.
+        assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".PhoneAccountTest",
+                "testOutgoingCallUsingTelecomManager",
+                mProfileUserId));
+        // Make sure the call is not inserted into parent user.
+        assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".PhoneAccountTest",
+                "testEnsureCallNotInserted",
+                mParentUserId));
+
+        // Place a outgoing call through work phone account using ACTION_CALL and verify the call
+        // is inserted properly.
+        assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".PhoneAccountTest",
+                "testOutgoingCallUsingActionCall",
+                mProfileUserId));
+        // Make sure the call is not inserted into parent user.
+        assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".PhoneAccountTest",
+                "testEnsureCallNotInserted",
+                mParentUserId));
+
+        // Add an incoming call with parent user's phone account and verify the call is inserted
+        // properly.
+        assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".PhoneAccountTest",
+                "testIncomingCall",
+                mProfileUserId));
+        // Make sure the call is not inserted into parent user.
+        assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".PhoneAccountTest",
+                "testEnsureCallNotInserted",
+                mParentUserId));
+    }
+
+    public void testTrustAgentInfo() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+        // Set and get trust agent config using child dpm instance.
+        assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".TrustAgentInfoTest",
+                "testSetAndGetTrustAgentConfiguration_child",
+                mProfileUserId));
+        // Set and get trust agent config using parent dpm instance.
+        assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".TrustAgentInfoTest",
+                "testSetAndGetTrustAgentConfiguration_parent",
+                mProfileUserId));
+        // Unified case
+        assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".TrustAgentInfoTest",
+                "testSetTrustAgentConfiguration_bothHaveTrustAgentConfigAndUnified",
+                mProfileUserId));
+        // Non-unified case, this test must run last because we have no way to clear work side
+        // password.
+        assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".TrustAgentInfoTest",
+                "testSetTrustAgentConfiguration_bothHaveTrustAgentConfigAndNonUnified",
+                mProfileUserId));
+    }
+
     private void disableActivityForUser(String activityName, int userId)
             throws DeviceNotAvailableException {
         String command = "am start -W --user " + userId
@@ -661,15 +755,297 @@
     }
 
     protected void startWidgetHostService() throws Exception {
-        String command = "am startservice --user 0 "
-                + "-a " + WIDGET_PROVIDER_PKG + ".REGISTER_CALLBACK "
-                + "--ei user-extra " + getUserSerialNumber(mUserId)
+        String command = "am startservice --user " + mParentUserId
+                + " -a " + WIDGET_PROVIDER_PKG + ".REGISTER_CALLBACK "
+                + "--ei user-extra " + getUserSerialNumber(mProfileUserId)
                 + " " + WIDGET_PROVIDER_PKG + "/.SimpleAppWidgetHostService";
         CLog.logAndDisplay(LogLevel.INFO, "Output for command " + command + ": "
               + getDevice().executeShellCommand(command));
     }
 
     private void assertAppLinkResult(String methodName) throws DeviceNotAvailableException {
-        assertTrue(runDeviceTestsAsUser(INTENT_SENDER_PKG, ".AppLinkTest", methodName, mUserId));
+        assertTrue(runDeviceTestsAsUser(INTENT_SENDER_PKG, ".AppLinkTest", methodName,
+                mProfileUserId));
+    }
+
+    private void runManagedContactsTest(Callable<Void> callable) throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+
+        try {
+            // Add test account
+            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ContactsTest",
+                    "testAddTestAccount", mParentUserId));
+            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ContactsTest",
+                    "testAddTestAccount", mProfileUserId));
+
+            // Install directory provider to both primary and managed profile
+            installAppAsUser(DIRECTORY_PROVIDER_APK, mProfileUserId);
+            installAppAsUser(DIRECTORY_PROVIDER_APK, mParentUserId);
+            setDirectoryPrefix(PRIMARY_DIRECTORY_PREFIX, mParentUserId);
+            setDirectoryPrefix(MANAGED_DIRECTORY_PREFIX, mProfileUserId);
+
+            // Check enterprise directory API works
+            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ContactsTest",
+                    "testGetDirectoryListInPrimaryProfile", mParentUserId));
+
+            // Insert Primary profile Contacts
+            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ContactsTest",
+                    "testPrimaryProfilePhoneAndEmailLookup_insertedAndfound", mParentUserId));
+            // Insert Managed profile Contacts
+            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ContactsTest",
+                    "testManagedProfilePhoneAndEmailLookup_insertedAndfound", mProfileUserId));
+            // Insert a primary contact with same phone & email as other
+            // enterprise contacts
+            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ContactsTest",
+                    "testPrimaryProfileDuplicatedPhoneEmailContact_insertedAndfound",
+                    mParentUserId));
+            // Insert a enterprise contact with same phone & email as other
+            // primary contacts
+            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ContactsTest",
+                    "testManagedProfileDuplicatedPhoneEmailContact_insertedAndfound",
+                    mProfileUserId));
+
+            callable.call();
+
+        } finally {
+            // Clean up in managed profile and primary profile
+            runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ContactsTest",
+                    "testCurrentProfileContacts_removeContacts", mProfileUserId);
+            runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ContactsTest",
+                    "testCurrentProfileContacts_removeContacts", mParentUserId);
+            getDevice().uninstallPackage(DIRECTORY_PROVIDER_PKG);
+        }
+    }
+
+
+    /*
+     * Container for running ContactsTest under multi-user environment
+     */
+    private static class ContactsTestSet {
+
+        private ManagedProfileTest mManagedProfileTest;
+        private String mManagedProfilePackage;
+        private int mParentUserId;
+        private int mProfileUserId;
+
+        public ContactsTestSet(ManagedProfileTest managedProfileTest, String managedProfilePackage,
+                int parentUserId, int profileUserId) {
+            mManagedProfileTest = managedProfileTest;
+            mManagedProfilePackage = managedProfilePackage;
+            mParentUserId = parentUserId;
+            mProfileUserId = profileUserId;
+        }
+
+        private boolean runDeviceTestsAsUser(String pkgName, String testClassName,
+                String testMethodName, Integer userId) throws DeviceNotAvailableException {
+            return mManagedProfileTest.runDeviceTestsAsUser(pkgName, testClassName, testMethodName,
+                    userId);
+        }
+
+        // Enable / Disable cross profile caller id
+        public void setCallerIdEnabled(boolean enabled) throws DeviceNotAvailableException {
+            if (enabled) {
+                assertTrue(runDeviceTestsAsUser(mManagedProfilePackage, ".ContactsTest",
+                        "testSetCrossProfileCallerIdDisabled_false", mProfileUserId));
+            } else {
+                assertTrue(runDeviceTestsAsUser(mManagedProfilePackage, ".ContactsTest",
+                        "testSetCrossProfileCallerIdDisabled_true", mProfileUserId));
+            }
+        }
+
+        // Enable / Disable cross profile contacts search
+        public void setContactsSearchEnabled(boolean enabled) throws DeviceNotAvailableException {
+            if (enabled) {
+                assertTrue(runDeviceTestsAsUser(mManagedProfilePackage, ".ContactsTest",
+                        "testSetCrossProfileContactsSearchDisabled_false", mProfileUserId));
+            } else {
+                assertTrue(runDeviceTestsAsUser(mManagedProfilePackage, ".ContactsTest",
+                        "testSetCrossProfileContactsSearchDisabled_true", mProfileUserId));
+            }
+        }
+
+        public void checkIfCanLookupEnterpriseContacts(boolean expected)
+                throws DeviceNotAvailableException {
+            // Primary user cannot use ordinary phone/email lookup api to access
+            // managed contacts
+            assertTrue(runDeviceTestsAsUser(mManagedProfilePackage, ".ContactsTest",
+                    "testPrimaryProfilePhoneLookup_canNotAccessEnterpriseContact", mParentUserId));
+            assertTrue(runDeviceTestsAsUser(mManagedProfilePackage, ".ContactsTest",
+                    "testPrimaryProfileEmailLookup_canNotAccessEnterpriseContact", mParentUserId));
+            // Primary user can use ENTERPRISE_CONTENT_FILTER_URI to access
+            // primary contacts
+            assertTrue(runDeviceTestsAsUser(mManagedProfilePackage, ".ContactsTest",
+                    "testPrimaryProfileEnterprisePhoneLookup_canAccessPrimaryContact",
+                    mParentUserId));
+            assertTrue(runDeviceTestsAsUser(mManagedProfilePackage, ".ContactsTest",
+                    "testPrimaryProfileEnterpriseEmailLookup_canAccessPrimaryContact",
+                    mParentUserId));
+            // When there exist contacts with the same phone/email in primary &
+            // enterprise,
+            // primary user can use ENTERPRISE_CONTENT_FILTER_URI to access the
+            // primary contact.
+            assertTrue(runDeviceTestsAsUser(mManagedProfilePackage, ".ContactsTest",
+                    "testPrimaryProfileEnterpriseEmailLookupDuplicated_canAccessPrimaryContact",
+                    mParentUserId));
+            assertTrue(runDeviceTestsAsUser(mManagedProfilePackage, ".ContactsTest",
+                    "testPrimaryProfileEnterprisePhoneLookupDuplicated_canAccessPrimaryContact",
+                    mParentUserId));
+
+            // Managed user cannot use ordinary phone/email lookup api to access
+            // primary contacts
+            assertTrue(runDeviceTestsAsUser(mManagedProfilePackage, ".ContactsTest",
+                    "testManagedProfilePhoneLookup_canNotAccessPrimaryContact", mProfileUserId));
+            assertTrue(runDeviceTestsAsUser(mManagedProfilePackage, ".ContactsTest",
+                    "testManagedProfileEmailLookup_canNotAccessPrimaryContact", mProfileUserId));
+            // Managed user can use ENTERPRISE_CONTENT_FILTER_URI to access
+            // enterprise contacts
+            assertTrue(runDeviceTestsAsUser(mManagedProfilePackage, ".ContactsTest",
+                    "testManagedProfileEnterprisePhoneLookup_canAccessEnterpriseContact",
+                    mProfileUserId));
+            assertTrue(runDeviceTestsAsUser(mManagedProfilePackage, ".ContactsTest",
+                    "testManagedProfileEnterpriseEmailLookup_canAccessEnterpriseContact",
+                    mProfileUserId));
+            // Managed user cannot use ENTERPRISE_CONTENT_FILTER_URI to access
+            // primary contacts
+            assertTrue(runDeviceTestsAsUser(mManagedProfilePackage, ".ContactsTest",
+                    "testManagedProfileEnterprisePhoneLookup_canNotAccessPrimaryContact",
+                    mProfileUserId));
+            assertTrue(runDeviceTestsAsUser(mManagedProfilePackage, ".ContactsTest",
+                    "testManagedProfileEnterpriseEmailLookup_canNotAccessPrimaryContact",
+                    mProfileUserId));
+            // When there exist contacts with the same phone/email in primary &
+            // enterprise,
+            // managed user can use ENTERPRISE_CONTENT_FILTER_URI to access the
+            // enterprise contact.
+            assertTrue(runDeviceTestsAsUser(mManagedProfilePackage, ".ContactsTest",
+                    "testManagedProfileEnterpriseEmailLookupDuplicated_canAccessEnterpriseContact",
+                    mProfileUserId));
+            assertTrue(runDeviceTestsAsUser(mManagedProfilePackage, ".ContactsTest",
+                    "testManagedProfileEnterprisePhoneLookupDuplicated_canAccessEnterpriseContact",
+                    mProfileUserId));
+
+            // Check if phone lookup can access primary directories
+            assertTrue(runDeviceTestsAsUser(mManagedProfilePackage, ".ContactsTest",
+                    "testPrimaryProfileEnterprisePhoneLookup_canAccessPrimaryDirectories",
+                    mParentUserId));
+
+            // Check if email lookup can access primary directories
+            assertTrue(runDeviceTestsAsUser(mManagedProfilePackage, ".ContactsTest",
+                    "testPrimaryProfileEnterpriseEmailLookup_canAccessPrimaryDirectories",
+                    mParentUserId));
+
+            if (expected) {
+                // Primary user can use ENTERPRISE_CONTENT_FILTER_URI to access
+                // managed profile contacts
+                assertTrue(runDeviceTestsAsUser(mManagedProfilePackage, ".ContactsTest",
+                        "testPrimaryProfileEnterprisePhoneLookup_canAccessEnterpriseContact",
+                        mParentUserId));
+                assertTrue(runDeviceTestsAsUser(mManagedProfilePackage, ".ContactsTest",
+                        "testPrimaryProfileEnterpriseEmailLookup_canAccessEnterpriseContact",
+                        mParentUserId));
+
+                // Make sure SIP enterprise lookup works too.
+                assertTrue(runDeviceTestsAsUser(mManagedProfilePackage, ".ContactsTest",
+                        "testPrimaryProfileEnterpriseSipLookup_canAccessEnterpriseContact",
+                        mParentUserId));
+
+                // Check if phone lookup can access enterprise directories
+                assertTrue(runDeviceTestsAsUser(mManagedProfilePackage, ".ContactsTest",
+                        "testPrimaryProfileEnterprisePhoneLookup_canAccessManagedDirectories",
+                        mParentUserId));
+
+                // Check if email lookup can access enterprise directories
+                assertTrue(runDeviceTestsAsUser(mManagedProfilePackage, ".ContactsTest",
+                        "testPrimaryProfileEnterpriseEmailLookup_canAccessManagedDirectories",
+                        mParentUserId));
+            } else {
+                // Primary user cannot use ENTERPRISE_CONTENT_FILTER_URI to
+                // access managed contacts
+                assertTrue(runDeviceTestsAsUser(mManagedProfilePackage, ".ContactsTest",
+                        "testPrimaryProfileEnterprisePhoneLookup_canNotAccessEnterpriseContact",
+                        mParentUserId));
+                assertTrue(runDeviceTestsAsUser(mManagedProfilePackage, ".ContactsTest",
+                        "testPrimaryProfileEnterprisePhoneLookup_canNotAccessManagedDirectories",
+                        mParentUserId));
+
+                assertTrue(runDeviceTestsAsUser(mManagedProfilePackage, ".ContactsTest",
+                        "testPrimaryProfileEnterpriseEmailLookup_canNotAccessManagedDirectories",
+                        mParentUserId));
+                assertTrue(runDeviceTestsAsUser(mManagedProfilePackage, ".ContactsTest",
+                        "testPrimaryProfileEnterprisePhoneLookup_canNotAccessManagedDirectories",
+                        mParentUserId));
+            }
+        }
+
+        public void checkIfCanFilterSelfContacts() throws DeviceNotAvailableException {
+            assertTrue(runDeviceTestsAsUser(mManagedProfilePackage, ".ContactsTest",
+                    "testPrimaryProfileEnterpriseCallableFilter_canAccessPrimaryDirectories",
+                    mParentUserId));
+            assertTrue(runDeviceTestsAsUser(mManagedProfilePackage, ".ContactsTest",
+                    "testManagedProfileEnterpriseCallableFilter_canAccessManagedDirectories",
+                    mProfileUserId));
+
+            assertTrue(runDeviceTestsAsUser(mManagedProfilePackage, ".ContactsTest",
+                    "testPrimaryProfileEnterpriseEmailFilter_canAccessPrimaryDirectories",
+                    mParentUserId));
+            assertTrue(runDeviceTestsAsUser(mManagedProfilePackage, ".ContactsTest",
+                    "testEnterpriseProfileEnterpriseEmailFilter_canAccessManagedDirectories",
+                    mProfileUserId));
+
+            assertTrue(runDeviceTestsAsUser(mManagedProfilePackage, ".ContactsTest",
+                    "testPrimaryProfileEnterpriseContactFilter_canAccessPrimaryDirectories",
+                    mParentUserId));
+            assertTrue(runDeviceTestsAsUser(mManagedProfilePackage, ".ContactsTest",
+                    "testManagedProfileEnterpriseContactFilter_canAccessManagedDirectories",
+                    mProfileUserId));
+
+            assertTrue(runDeviceTestsAsUser(mManagedProfilePackage, ".ContactsTest",
+                    "testPrimaryProfileEnterprisePhoneFilter_canAccessPrimaryDirectories",
+                    mParentUserId));
+            assertTrue(runDeviceTestsAsUser(mManagedProfilePackage, ".ContactsTest",
+                    "testManagedProfileEnterprisePhoneFilter_canAccessManagedDirectories",
+                    mProfileUserId));
+        }
+
+        public void checkIfCanFilterEnterpriseContacts(boolean expected)
+                throws DeviceNotAvailableException {
+            assertTrue(runDeviceTestsAsUser(mManagedProfilePackage, ".ContactsTest",
+                    "testFilterUriWhenDirectoryParamMissing", mParentUserId));
+            if (expected) {
+                assertTrue(runDeviceTestsAsUser(mManagedProfilePackage, ".ContactsTest",
+                        "testPrimaryProfileEnterpriseCallableFilter_canAccessManagedDirectories",
+                        mParentUserId));
+                assertTrue(runDeviceTestsAsUser(mManagedProfilePackage, ".ContactsTest",
+                        "testPrimaryProfileEnterpriseEmailFilter_canAccessManagedDirectories",
+                        mParentUserId));
+                assertTrue(runDeviceTestsAsUser(mManagedProfilePackage, ".ContactsTest",
+                        "testPrimaryProfileEnterpriseContactFilter_canAccessManagedDirectories",
+                        mParentUserId));
+                assertTrue(runDeviceTestsAsUser(mManagedProfilePackage, ".ContactsTest",
+                        "testPrimaryProfileEnterprisePhoneFilter_canAccessManagedDirectories",
+                        mParentUserId));
+            } else {
+                assertTrue(runDeviceTestsAsUser(mManagedProfilePackage, ".ContactsTest",
+                        "testPrimaryProfileEnterpriseCallableFilter_canNotAccessManagedDirectories",
+                        mParentUserId));
+                assertTrue(runDeviceTestsAsUser(mManagedProfilePackage, ".ContactsTest",
+                        "testPrimaryProfileEnterpriseEmailFilter_canNotAccessManagedDirectories",
+                        mParentUserId));
+                assertTrue(runDeviceTestsAsUser(mManagedProfilePackage, ".ContactsTest",
+                        "testPrimaryProfileEnterpriseContactFilter_canNotAccessManagedDirectories",
+                        mParentUserId));
+                assertTrue(runDeviceTestsAsUser(mManagedProfilePackage, ".ContactsTest",
+                        "testPrimaryProfileEnterprisePhoneFilter_canNotAccessManagedDirectories",
+                        mParentUserId));
+            }
+        }
+
+        public void checkIfNoEnterpriseDirectoryFound() throws DeviceNotAvailableException {
+            assertTrue(runDeviceTestsAsUser(mManagedProfilePackage, ".ContactsTest",
+                    "testPrimaryProfileEnterpriseDirectories_canNotAccessManagedDirectories",
+                    mParentUserId));
+        }
     }
 }
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedDeviceOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedDeviceOwnerTest.java
index b996de3..0eed56b 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedDeviceOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedDeviceOwnerTest.java
@@ -36,19 +36,19 @@
         super.setUp();
 
         if (mHasFeature) {
-            mUserId = USER_OWNER;
+            mUserId = mPrimaryUserId;
 
-            installApp(DEVICE_ADMIN_APK);
-            assertTrue("Failed to set device owner",
-                    setDeviceOwner(DEVICE_ADMIN_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS));
+            installAppAsUser(DEVICE_ADMIN_APK, mUserId);
+            assertTrue("Failed to set device owner", setDeviceOwner(
+                    DEVICE_ADMIN_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS, mUserId));
         }
     }
 
     @Override
     protected void tearDown() throws Exception {
         if (mHasFeature) {
-            assertTrue("Failed to remove device owner.",
-                    runDeviceTests(DEVICE_ADMIN_PKG, CLEAR_DEVICE_OWNER_TEST_CLASS));
+            assertTrue("Failed to remove device owner.", runDeviceTestsAsUser(
+                    DEVICE_ADMIN_PKG, CLEAR_DEVICE_OWNER_TEST_CLASS, mUserId));
         }
         super.tearDown();
     }
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedManagedProfileOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedManagedProfileOwnerTest.java
new file mode 100644
index 0000000..32110de
--- /dev/null
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedManagedProfileOwnerTest.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.devicepolicy;
+
+/**
+ * Set of tests for managed profile owner use cases that also apply to device owners.
+ * Tests that should be run identically in both cases are added in DeviceAndProfileOwnerTest.
+ */
+public class MixedManagedProfileOwnerTest extends DeviceAndProfileOwnerTest {
+
+    protected static final String CLEAR_PROFILE_OWNER_NEGATIVE_TEST_CLASS =
+            DEVICE_ADMIN_PKG + ".ClearProfileOwnerNegativeTest";
+
+    private int mParentUserId = -1;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        // We need managed users to be supported in order to create a profile of the user owner.
+        mHasFeature &= hasDeviceFeature("android.software.managed_users");
+
+        if (mHasFeature) {
+            removeTestUsers();
+            mParentUserId = mPrimaryUserId;
+            mUserId = createManagedProfile(mParentUserId);
+            switchUser(mParentUserId);
+            startUser(mUserId);
+
+            installAppAsUser(DEVICE_ADMIN_APK, mUserId);
+            setProfileOwnerOrFail(DEVICE_ADMIN_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS, mUserId);
+            startUser(mUserId);
+        }
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        if (mHasFeature) {
+            removeUser(mUserId);
+        }
+        super.tearDown();
+    }
+
+    // Most tests for this class are defined in DeviceAndProfileOwnerTest
+
+    /**
+     * Verify that screenshots are still possible for activities in the primary user when the policy
+     * is set on the profile owner.
+     */
+    public void testScreenCaptureDisabled_allowedPrimaryUser() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+        executeDeviceTestMethod(".ScreenCaptureDisabledTest", "testSetScreenCaptureDisabled_true");
+        // start the ScreenCaptureDisabledActivity in the parent
+        installAppAsUser(DEVICE_ADMIN_APK, mParentUserId);
+        String command = "am start -W --user " + mParentUserId + " " + DEVICE_ADMIN_PKG + "/"
+                + DEVICE_ADMIN_PKG + ".ScreenCaptureDisabledActivity";
+        getDevice().executeShellCommand(command);
+        executeDeviceTestMethod(".ScreenCaptureDisabledTest", "testScreenCapturePossible");
+    }
+
+    @Override
+    public void testResetPassword() {
+        // Managed profile owner can't call resetPassword().
+    }
+
+    public void testCannotClearProfileOwner() throws Exception {
+        if (mHasFeature) {
+            assertTrue("Managed profile owner shouldn't be removed",
+                    runDeviceTestsAsUser(DEVICE_ADMIN_PKG, CLEAR_PROFILE_OWNER_NEGATIVE_TEST_CLASS,
+                            mPrimaryUserId));
+        }
+    }
+
+    @Override
+    public void testDisallowSetWallpaper_allowed() throws Exception {
+        // Managed profile doesn't have wallpaper.
+    }
+}
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedProfileOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedProfileOwnerTest.java
index bcc5bf9..8b32ac1 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedProfileOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedProfileOwnerTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open 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,59 +16,34 @@
 
 package com.android.cts.devicepolicy;
 
-import com.android.ddmlib.Log.LogLevel;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.log.LogUtil.CLog;
-
-import junit.framework.AssertionFailedError;
-
 /**
- * Set of tests for profile owner use cases that also apply to device owners.
+ * Set of tests for pure (non-managed) profile owner use cases that also apply to device owners.
  * Tests that should be run identically in both cases are added in DeviceAndProfileOwnerTest.
  */
 public class MixedProfileOwnerTest extends DeviceAndProfileOwnerTest {
 
+    protected static final String CLEAR_PROFILE_OWNER_TEST_CLASS =
+            DEVICE_ADMIN_PKG + ".ClearProfileOwnerTest";
+
     @Override
     protected void setUp() throws Exception {
         super.setUp();
 
-        // We need managed users to be supported in order to create a profile of the user owner.
-        mHasFeature &= hasDeviceFeature("android.software.managed_users");
-
         if (mHasFeature) {
-            removeTestUsers();
-            mUserId = createManagedProfile();
+            mUserId = mPrimaryUserId;
 
             installAppAsUser(DEVICE_ADMIN_APK, mUserId);
             setProfileOwnerOrFail(DEVICE_ADMIN_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS, mUserId);
-            startUser(mUserId);
         }
     }
 
     @Override
     protected void tearDown() throws Exception {
         if (mHasFeature) {
-            removeUser(mUserId);
+            assertTrue("Failed to remove profile owner.",
+                    runDeviceTestsAsUser(DEVICE_ADMIN_PKG, CLEAR_PROFILE_OWNER_TEST_CLASS,
+                            mUserId));
         }
         super.tearDown();
     }
-
-    // Most tests for this class are defined in DeviceAndProfileOwnerTest
-
-    /**
-     * Verify that screenshots are still possible for activities in the primary user when the policy
-     * is set on the profile owner.
-     */
-    public void testScreenCaptureDisabled_allowedPrimaryUser() throws Exception {
-        if (!mHasFeature) {
-            return;
-        }
-        executeDeviceTestMethod(".ScreenCaptureDisabledTest", "testSetScreenCaptureDisabled_true");
-        // start the ScreenCaptureDisabledActivity in the primary user
-        installAppAsUser(DEVICE_ADMIN_APK, USER_OWNER);
-        String command = "am start -W --user 0 " + DEVICE_ADMIN_PKG + "/"
-                + DEVICE_ADMIN_PKG + ".ScreenCaptureDisabledActivity";
-        getDevice().executeShellCommand(command);
-        executeDeviceTestMethod(".ScreenCaptureDisabledTest", "testScreenCapturePossible");
-    }
 }
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ProfileOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ProfileOwnerTest.java
new file mode 100644
index 0000000..9deddc2
--- /dev/null
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ProfileOwnerTest.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.devicepolicy;
+
+/**
+ * Host side tests for profile owner.  Run the CtsProfileOwnerApp device side test.
+ */
+public class ProfileOwnerTest extends BaseDevicePolicyTest {
+    private static final String PROFILE_OWNER_PKG = "com.android.cts.profileowner";
+    private static final String PROFILE_OWNER_APK = "CtsProfileOwnerApp.apk";
+
+    private static final String ADMIN_RECEIVER_TEST_CLASS =
+            PROFILE_OWNER_PKG + ".BaseProfileOwnerTest$BasicAdminReceiver";
+    private static final String CLEAR_PROFILE_OWNER_TEST_CLASS =
+            PROFILE_OWNER_PKG + ".ClearProfileOwnerTest";
+
+    private int mUserId = 0;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        mUserId = getPrimaryUser();
+
+
+        if (mHasFeature) {
+            installAppAsUser(PROFILE_OWNER_APK, mUserId);
+            assertTrue("Failed to set profile owner",
+                    setProfileOwner(PROFILE_OWNER_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS, mUserId));
+        }
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        if (mHasFeature) {
+            assertTrue("Failed to remove profile owner.",
+                    runDeviceTestsAsUser(PROFILE_OWNER_PKG, CLEAR_PROFILE_OWNER_TEST_CLASS,
+                            mUserId));
+            getDevice().uninstallPackage(PROFILE_OWNER_PKG);
+        }
+
+        super.tearDown();
+    }
+
+    public void testWifi() throws Exception {
+        if (hasDeviceFeature("android.hardware.wifi")) {
+            return;
+        }
+        executeProfileOwnerTest("WifiTest");
+    }
+
+    private void executeProfileOwnerTest(String testClassName) throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+        String testClass = PROFILE_OWNER_PKG + "." + testClassName;
+        assertTrue(testClass + " failed.", runDeviceTestsAsUser(PROFILE_OWNER_PKG, testClass,
+                mPrimaryUserId));
+    }
+}
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ProfileOwnerTestApi23.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ProfileOwnerTestApi23.java
new file mode 100644
index 0000000..d94748d
--- /dev/null
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ProfileOwnerTestApi23.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.devicepolicy;
+
+/**
+ * To verify PO APIs targeting API level 23.
+ */
+public class ProfileOwnerTestApi23 extends BaseDevicePolicyTest {
+    protected static final String DEVICE_ADMIN_PKG = "com.android.cts.deviceandprofileowner";
+    protected static final String DEVICE_ADMIN_APK = "CtsDeviceAndProfileOwnerApp23.apk";
+    protected static final String ADMIN_RECEIVER_TEST_CLASS
+            = ".BaseDeviceAdminTest$BasicAdminReceiver";
+    protected static final String CLEAR_PROFILE_OWNER_TEST_CLASS =
+            DEVICE_ADMIN_PKG + ".ClearProfileOwnerTest";
+    private int mUserId;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        if (mHasFeature) {
+            mUserId = USER_OWNER;
+
+            installAppAsUser(DEVICE_ADMIN_APK, mUserId);
+            setProfileOwnerOrFail(DEVICE_ADMIN_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS, mUserId);
+        }
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        if (mHasFeature) {
+            assertTrue("Failed to remove profile owner.",
+                    runDeviceTestsAsUser(DEVICE_ADMIN_PKG, CLEAR_PROFILE_OWNER_TEST_CLASS,
+                            mUserId));
+        }
+        super.tearDown();
+    }
+
+    public void testDelegatedCertInstaller() throws Exception {
+        assertTrue("DelegatedCertInstaller failed", runDeviceTestsAsUser(DEVICE_ADMIN_PKG,
+                ".DelegatedCertInstallerTest", "testSetNotExistCertInstallerPackage",  mUserId));
+    }
+}
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/UserRestrictionsTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/UserRestrictionsTest.java
new file mode 100644
index 0000000..84c1a9d
--- /dev/null
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/UserRestrictionsTest.java
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.devicepolicy;
+
+import com.android.tradefed.device.DeviceNotAvailableException;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+public class UserRestrictionsTest extends BaseDevicePolicyTest {
+    private static final String DEVICE_ADMIN_PKG = "com.android.cts.deviceandprofileowner";
+    private static final String DEVICE_ADMIN_APK = "CtsDeviceAndProfileOwnerApp.apk";
+    private static final String ADMIN_RECEIVER_TEST_CLASS
+            = ".BaseDeviceAdminTest$BasicAdminReceiver";
+
+    private boolean mRemoveDeviceOwnerInTearDown;
+    private boolean mRemovePrimaryProfileOwnerInTearDown;
+    private int mDeviceOwnerUserId;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        mRemoveDeviceOwnerInTearDown = false;
+        mRemovePrimaryProfileOwnerInTearDown = false;
+        mDeviceOwnerUserId = mPrimaryUserId;
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        if (mHasFeature) {
+            if (mRemoveDeviceOwnerInTearDown) {
+                assertTrue("Failed to clear device owner",
+                        runTests("ClearDeviceOwnerTest", mDeviceOwnerUserId));
+            }
+            if (mRemovePrimaryProfileOwnerInTearDown) {
+                assertTrue("Failed to clear profile owner",
+                        runTests("ClearProfileOwnerTest", mDeviceOwnerUserId));
+            }
+            assertTrue("Some user restrictions are still set",
+                    runTests("userrestrictions.CheckNoOwnerRestrictionsTest", mDeviceOwnerUserId));
+
+            // DO/PO might have set DISALLOW_REMOVE_USER, so it needs to be done after removing
+            // them.
+            removeTestUsers();
+        }
+        super.tearDown();
+    }
+
+    private boolean runTests(@Nonnull String className,
+            @Nullable String method, int userId) throws DeviceNotAvailableException {
+        return runDeviceTestsAsUser(DEVICE_ADMIN_PKG, "." + className, method, userId);
+    }
+
+    private boolean runTests(@Nonnull String className, int userId)
+            throws DeviceNotAvailableException {
+        return runTests(className, null, userId);
+    }
+
+    public void testUserRestrictions_deviceOwnerOnly() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+        installAppAsUser(DEVICE_ADMIN_APK, mDeviceOwnerUserId);
+        assertTrue("Failed to set device owner",
+                setDeviceOwner(DEVICE_ADMIN_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS,
+                        mDeviceOwnerUserId));
+        mRemoveDeviceOwnerInTearDown = true;
+
+        runTests("userrestrictions.DeviceOwnerUserRestrictionsTest",
+                "testSetAllRestrictions", mDeviceOwnerUserId);
+    }
+
+    public void testUserRestrictions_primaryProfileOwnerOnly() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+        if (hasUserSplit()) {
+            // Can't set PO on user-0 in this mode.
+            return;
+        }
+
+        installAppAsUser(DEVICE_ADMIN_APK, mDeviceOwnerUserId);
+        assertTrue("Failed to set profile owner",
+                setProfileOwner(DEVICE_ADMIN_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS,
+                        mDeviceOwnerUserId));
+        mRemovePrimaryProfileOwnerInTearDown = true;
+
+        runTests("userrestrictions.PrimaryProfileOwnerUserRestrictionsTest",
+                "testSetAllRestrictions", mDeviceOwnerUserId);
+    }
+
+    public void testUserRestrictions_secondaryProfileOwnerOnly() throws Exception {
+        if (!mHasFeature || !mSupportsMultiUser) {
+            return;
+        }
+        final int secondaryUserId = createUser();
+
+        installAppAsUser(DEVICE_ADMIN_APK, secondaryUserId);
+        assertTrue("Failed to set profile owner",
+                setProfileOwner(DEVICE_ADMIN_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS,
+                        secondaryUserId));
+
+        runTests("userrestrictions.SecondaryProfileOwnerUserRestrictionsTest",
+                "testSetAllRestrictions", secondaryUserId);
+    }
+
+    /**
+     * DO + PO combination.  Make sure global DO restrictions are visible on secondary users.
+     */
+    public void testUserRestrictions_layering() throws Exception {
+        if (!mHasFeature || !mSupportsMultiUser) {
+            return;
+        }
+        // Set DO
+        installAppAsUser(DEVICE_ADMIN_APK, mDeviceOwnerUserId);
+        assertTrue("Failed to set device owner",
+                setDeviceOwner(DEVICE_ADMIN_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS,
+                        mDeviceOwnerUserId));
+        mRemoveDeviceOwnerInTearDown = true;
+
+        // Create another user and set PO.
+        final int secondaryUserId = createUser();
+
+        installAppAsUser(DEVICE_ADMIN_APK, secondaryUserId);
+        assertTrue("Failed to set profile owner",
+                setProfileOwner(DEVICE_ADMIN_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS,
+                        secondaryUserId));
+
+        // Let DO set all restrictions.
+        runTests("userrestrictions.DeviceOwnerUserRestrictionsTest",
+                "testSetAllRestrictions", mDeviceOwnerUserId);
+
+        // Make sure the global restrictions are visible to secondary users.
+        runTests("userrestrictions.SecondaryProfileOwnerUserRestrictionsTest",
+                "testHasGlobalRestrictions", secondaryUserId);
+
+        // Then let PO set all restrictions.
+        runTests("userrestrictions.SecondaryProfileOwnerUserRestrictionsTest",
+                "testSetAllRestrictions", secondaryUserId);
+
+        // Make sure both local and global restrictions are visible on secondary users.
+        runTests("userrestrictions.SecondaryProfileOwnerUserRestrictionsTest",
+                "testHasBothGlobalAndLocalRestrictions", secondaryUserId);
+
+        // Let DO clear all restrictions.
+        runTests("userrestrictions.DeviceOwnerUserRestrictionsTest",
+                "testClearAllRestrictions", mDeviceOwnerUserId);
+
+        // Now only PO restrictions should be set on the secondary user.
+        runTests("userrestrictions.SecondaryProfileOwnerUserRestrictionsTest",
+                "testLocalRestrictionsOnly", secondaryUserId);
+    }
+
+    /**
+     * PO on user-0.  It can set DO restrictions too, but they shouldn't leak to other users.
+     */
+    public void testUserRestrictions_layering_profileOwnerNoLeaking() throws Exception {
+        if (!mHasFeature || !mSupportsMultiUser) {
+            return;
+        }
+        if (hasUserSplit()) {
+            // Can't set PO on user-0 in this mode.
+            return;
+        }
+        // Set DO on user 0
+        installAppAsUser(DEVICE_ADMIN_APK, mDeviceOwnerUserId);
+        assertTrue("Failed to set profile owner",
+                setProfileOwner(DEVICE_ADMIN_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS,
+                        mDeviceOwnerUserId));
+        mRemovePrimaryProfileOwnerInTearDown = true;
+
+        // Create another user and set PO.
+        final int secondaryUserId = createUser();
+
+        installAppAsUser(DEVICE_ADMIN_APK, secondaryUserId);
+        assertTrue("Failed to set profile owner",
+                setProfileOwner(DEVICE_ADMIN_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS,
+                        secondaryUserId));
+
+        // Let user-0 PO sets all restrictions.
+        runTests("userrestrictions.PrimaryProfileOwnerUserRestrictionsTest",
+                "testSetAllRestrictions", mDeviceOwnerUserId);
+
+        // Secondary users shouldn't see any of them.
+        runTests("userrestrictions.SecondaryProfileOwnerUserRestrictionsTest",
+                "testDefaultRestrictionsOnly", secondaryUserId);
+    }
+}
\ No newline at end of file
diff --git a/hostsidetests/dumpsys/Android.mk b/hostsidetests/dumpsys/Android.mk
index 5b63199..9de0e9c 100644
--- a/hostsidetests/dumpsys/Android.mk
+++ b/hostsidetests/dumpsys/Android.mk
@@ -23,7 +23,12 @@
 
 LOCAL_JAVA_LIBRARIES := cts-tradefed tradefed-prebuilt
 
-LOCAL_CTS_TEST_PACKAGE := android.host.dumpsys
+LOCAL_STATIC_JAVA_LIBRARIES := cts-migration-lib
+
+LOCAL_CTS_TEST_PACKAGE := android.dumpsys
+
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
 
 include $(BUILD_CTS_HOST_JAVA_LIBRARY)
 
diff --git a/hostsidetests/dumpsys/AndroidTest.xml b/hostsidetests/dumpsys/AndroidTest.xml
new file mode 100644
index 0000000..f1ebc79
--- /dev/null
+++ b/hostsidetests/dumpsys/AndroidTest.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for the CTS dumpsys host tests">
+    <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest">
+        <option name="jar" value="CtsDumpsysHostTestCases.jar" />
+    </test>
+</configuration>
diff --git a/hostsidetests/dumpsys/FramestatsTestApp/Android.mk b/hostsidetests/dumpsys/FramestatsTestApp/Android.mk
index 1104523..b11a57b 100644
--- a/hostsidetests/dumpsys/FramestatsTestApp/Android.mk
+++ b/hostsidetests/dumpsys/FramestatsTestApp/Android.mk
@@ -25,4 +25,7 @@
 
 LOCAL_PACKAGE_NAME := CtsFramestatsTestApp
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/dumpsys/src/android/dumpsys/cts/DumpsysHostTest.java b/hostsidetests/dumpsys/src/android/dumpsys/cts/DumpsysHostTest.java
index 0daae03..e9b08a4 100644
--- a/hostsidetests/dumpsys/src/android/dumpsys/cts/DumpsysHostTest.java
+++ b/hostsidetests/dumpsys/src/android/dumpsys/cts/DumpsysHostTest.java
@@ -16,7 +16,7 @@
 
 package android.dumpsys.cts;
 
-import com.android.cts.tradefed.build.CtsBuildHelper;
+import com.android.cts.migration.MigrationHelper;
 import com.android.tradefed.build.IBuildInfo;
 import com.android.tradefed.device.ITestDevice;
 import com.android.tradefed.testtype.DeviceTestCase;
@@ -30,7 +30,8 @@
 import java.util.Set;
 
 /**
- * Test to check the format of the dumps of various services (currently only procstats is tested).
+ * Test to check the format of the dumps of various services.
+ * Currently procstats and batterystats are tested.
  */
 public class DumpsysHostTest extends DeviceTestCase implements IBuildReceiver {
     private static final String TAG = "DumpsysHostTest";
@@ -486,6 +487,8 @@
                     case "ctr":
                         checkChargeTimeRemain(parts);
                         break;
+                    case "cpu":
+                        checkUidCpuUsage(parts);
                     default:
                         break;
                 }
@@ -515,12 +518,15 @@
 
     private void checkApk(String[] parts) {
         assertEquals(10, parts.length);
-        assertInteger(parts[4]); // wakeups
+        long wakeup_count = assertInteger(parts[4]); // wakeups
         assertNotNull(parts[5]); // apk
         assertNotNull(parts[6]); // service
         assertInteger(parts[7]); // startTime
         assertInteger(parts[8]); // starts
         assertInteger(parts[9]); // launches
+
+        // Sanity check.
+        assertTrue("wakeup count must be >= 0", wakeup_count >= 0);
     }
 
     private void checkProcess(String[] parts) {
@@ -563,13 +569,18 @@
         assertNotNull(parts[4]);      // wakelock
         assertInteger(parts[5]);      // full totalTime
         assertEquals("f", parts[6]);  // full
-        assertInteger(parts[7]);      // full count
+        long full_count = assertInteger(parts[7]);      // full count
         assertInteger(parts[8]);      // partial totalTime
         assertEquals("p", parts[9]);  // partial
-        assertInteger(parts[10]);     // partial count
+        long partial_count = assertInteger(parts[10]);     // partial count
         assertInteger(parts[11]);     // window totalTime
         assertEquals("w", parts[12]); // window
-        assertInteger(parts[13]);     // window count
+        long window_count = assertInteger(parts[13]);     // window count
+
+        // Sanity checks.
+        assertTrue("full wakelock count must be >= 0", full_count >= 0);
+        assertTrue("partial wakelock count must be >= 0", partial_count >= 0);
+        assertTrue("window wakelock count must be >= 0", window_count >= 0);
     }
 
     private void checkSync(String[] parts) {
@@ -604,16 +615,26 @@
 
     private void checkNetwork(String[] parts) {
         assertEquals(14, parts.length);
-        assertInteger(parts[4]);  // mobileBytesRx
-        assertInteger(parts[5]);  // mobileBytesTx
-        assertInteger(parts[6]);  // wifiBytesRx
-        assertInteger(parts[7]);  // wifiBytesTx
-        assertInteger(parts[8]);  // mobilePacketsRx
-        assertInteger(parts[9]);  // mobilePacketsTx
-        assertInteger(parts[10]); // wifiPacketsRx
-        assertInteger(parts[11]); // wifiPacketsTx
+        long mbRx = assertInteger(parts[4]);  // mobileBytesRx
+        long mbTx = assertInteger(parts[5]);  // mobileBytesTx
+        long wbRx = assertInteger(parts[6]);  // wifiBytesRx
+        long wbTx = assertInteger(parts[7]);  // wifiBytesTx
+        long mpRx = assertInteger(parts[8]);  // mobilePacketsRx
+        long mpTx = assertInteger(parts[9]);  // mobilePacketsTx
+        long wpRx = assertInteger(parts[10]); // wifiPacketsRx
+        long wpTx = assertInteger(parts[11]); // wifiPacketsTx
         assertInteger(parts[12]); // mobileActiveTime (usec)
         assertInteger(parts[13]); // mobileActiveCount
+
+        // Assuming each packet contains some bytes, bytes >= packets >= 0.
+        assertTrue("mobileBytesRx must be >= mobilePacketsRx", mbRx >= mpRx);
+        assertTrue("mobilePacketsRx must be >= 0", mpRx >= 0);
+        assertTrue("mobileBytesTx must be >= mobilePacketsTx", mbTx >= mpTx);
+        assertTrue("mobilePacketsTx must be >= 0", mpTx >= 0);
+        assertTrue("wifiBytesRx must be >= wifiPacketsRx", wbRx >= wpRx);
+        assertTrue("wifiPacketsRx must be >= 0", wpRx >= 0);
+        assertTrue("wifiBytesTx must be >= wifiPacketsTx", wbTx >= wpTx);
+        assertTrue("wifiPacketsTx must be >= 0", wpTx >= 0);
     }
 
     private void checkUserActivity(String[] parts) {
@@ -628,13 +649,27 @@
         if (!parts[4].equals("N/A")) {
             assertInteger(parts[4]);  // startCount
         }
-        assertInteger(parts[5]);  // batteryRealtime
-        assertInteger(parts[6]);  // batteryUptime
-        assertInteger(parts[7]);  // totalRealtime
-        assertInteger(parts[8]);  // totalUptime
+        long bReal = assertInteger(parts[5]);  // batteryRealtime
+        long bUp = assertInteger(parts[6]);  // batteryUptime
+        long tReal = assertInteger(parts[7]);  // totalRealtime
+        long tUp = assertInteger(parts[8]);  // totalUptime
         assertInteger(parts[9]);  // startClockTime
-        assertInteger(parts[10]); // batteryScreenOffRealtime
-        assertInteger(parts[11]); // batteryScreenOffUptime
+        long bOffReal = assertInteger(parts[10]); // batteryScreenOffRealtime
+        long bOffUp = assertInteger(parts[11]); // batteryScreenOffUptime
+
+        // The device cannot be up more than there are real-world seconds.
+        assertTrue("batteryRealtime must be >= batteryUptime", bReal >= bUp);
+        assertTrue("totalRealtime must be >= totalUptime", tReal >= tUp);
+        assertTrue("batteryScreenOffRealtime must be >= batteryScreenOffUptime",
+                bOffReal >= bOffUp);
+
+        // total >= battery >= battery screen-off >= 0
+        assertTrue("totalRealtime must be >= batteryRealtime", tReal >= bReal);
+        assertTrue("batteryRealtime must be >= batteryScreenOffRealtime", bReal >= bOffReal);
+        assertTrue("batteryScreenOffRealtime must be >= 0", bOffReal >= 0);
+        assertTrue("totalUptime must be >= batteryUptime", tUp >= bUp);
+        assertTrue("batteryUptime must be >= batteryScreenOffUptime", bUp >= bOffUp);
+        assertTrue("batteryScreenOffUptime must be >= 0", bOffUp >= 0);
     }
 
     private void checkBatteryDischarge(String[] parts) {
@@ -790,7 +825,11 @@
     private void checkPowerUseItem(String[] parts) {
         assertEquals(6, parts.length);
         assertNotNull(parts[4]); // label
-        assertDouble(parts[5]);  // mAh
+        double mAH = assertDouble(parts[5]);  // mAh
+
+        assertTrue("powerUseItem mAH must be >= 0", mAH >= 0);
+        // Largest current Android battery is ~5K. 100K shouldn't get made for a while.
+        assertTrue("powerUseItem mAH is expected to be <= 100000", mAH <= 100000);
     }
 
     private void checkChargeDischargeStep(String[] parts) {
@@ -814,6 +853,12 @@
         assertInteger(parts[4]); // chargeTimeRemaining
     }
 
+    private void checkUidCpuUsage(String[] parts) {
+        assertTrue(parts.length >= 6);
+        assertInteger(parts[4]); // user time
+        assertInteger(parts[5]); // system time
+    }
+
     /**
      * Tests the output of "dumpsys gfxinfo framestats".
      *
@@ -827,7 +872,7 @@
             getDevice().uninstallPackage(TEST_PKG);
 
             // install the test app
-            File testAppFile = mCtsBuild.getTestApp(TEST_APK);
+            File testAppFile = MigrationHelper.getTestFile(mCtsBuild, TEST_APK);
             String installResult = getDevice().installPackage(testAppFile, false);
             assertNull(
                     String.format("failed to install atrace test app. Reason: %s", installResult),
@@ -899,14 +944,14 @@
         assertTrue(foundAtLeastOneRow);
     }
 
-    private CtsBuildHelper mCtsBuild;
+    private IBuildInfo mCtsBuild;
 
     /**
      * {@inheritDoc}
      */
     @Override
     public void setBuild(IBuildInfo buildInfo) {
-        mCtsBuild = CtsBuildHelper.createBuildHelper(buildInfo);
+        mCtsBuild = buildInfo;
     }
 
     private static long assertInteger(String input) {
@@ -919,11 +964,12 @@
         }
     }
 
-    private static void assertDouble(String input) {
+    private static double assertDouble(String input) {
         try {
-            Double.parseDouble(input);
+            return Double.parseDouble(input);
         } catch (NumberFormatException e) {
             fail("Expected a double but found \"" + input + "\"");
+            return -1;
         }
     }
 
diff --git a/hostsidetests/jdwpsecurity/Android.mk b/hostsidetests/jdwpsecurity/Android.mk
index 561d346..338a7ae 100644
--- a/hostsidetests/jdwpsecurity/Android.mk
+++ b/hostsidetests/jdwpsecurity/Android.mk
@@ -25,6 +25,11 @@
 
 LOCAL_JAVA_LIBRARIES := cts-tradefed tradefed-prebuilt
 
+LOCAL_STATIC_JAVA_LIBRARIES := cts-migration-lib
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_CTS_TEST_PACKAGE := android.host.jdwpsecurity
 
 include $(BUILD_CTS_HOST_JAVA_LIBRARY)
diff --git a/hostsidetests/jdwpsecurity/AndroidTest.xml b/hostsidetests/jdwpsecurity/AndroidTest.xml
new file mode 100644
index 0000000..bbb99e9
--- /dev/null
+++ b/hostsidetests/jdwpsecurity/AndroidTest.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for the CTS JDWP host test cases">
+    <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
+        <option name="jar" value="CtsJdwpSecurityHostTestCases.jar" />
+    </test>
+</configuration>
diff --git a/hostsidetests/jdwpsecurity/app/Android.mk b/hostsidetests/jdwpsecurity/app/Android.mk
index 13b5be4..6c7845c 100644
--- a/hostsidetests/jdwpsecurity/app/Android.mk
+++ b/hostsidetests/jdwpsecurity/app/Android.mk
@@ -18,6 +18,8 @@
 LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE := CtsJdwpApp
 LOCAL_SRC_FILES := $(call all-subdir-java-files)
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
 include $(BUILD_JAVA_LIBRARY)
 
 # Copy the built module to the cts dir
diff --git a/hostsidetests/jdwpsecurity/src/android/jdwpsecurity/cts/JdwpSecurityHostTest.java b/hostsidetests/jdwpsecurity/src/android/jdwpsecurity/cts/JdwpSecurityHostTest.java
index 8e276ed..186728c 100644
--- a/hostsidetests/jdwpsecurity/src/android/jdwpsecurity/cts/JdwpSecurityHostTest.java
+++ b/hostsidetests/jdwpsecurity/src/android/jdwpsecurity/cts/JdwpSecurityHostTest.java
@@ -16,7 +16,7 @@
 
 package android.jdwpsecurity.cts;
 
-import com.android.cts.tradefed.build.CtsBuildHelper;
+import com.android.cts.migration.MigrationHelper;
 import com.android.tradefed.build.IBuildInfo;
 import com.android.tradefed.device.DeviceNotAvailableException;
 import com.android.tradefed.log.LogUtil.CLog;
@@ -45,7 +45,7 @@
     private static final String DEVICE_JAR_FILENAME = "CtsJdwpApp.jar";
     private static final String JAR_MAIN_CLASS_NAME = "com.android.cts.jdwpsecurity.JdwpTest";
 
-    private CtsBuildHelper mCtsBuild;
+    private IBuildInfo mBuildInfo;
 
     private static String getDeviceScriptFilepath() {
         return DEVICE_LOCATION + File.separator + DEVICE_SCRIPT_FILENAME;
@@ -57,7 +57,7 @@
 
     @Override
     public void setBuild(IBuildInfo buildInfo) {
-        mCtsBuild = CtsBuildHelper.createBuildHelper(buildInfo);
+        mBuildInfo = buildInfo;
     }
 
     @Override
@@ -85,7 +85,7 @@
         getDevice().executeShellCommand("chmod 755 " + getDeviceScriptFilepath());
 
         // Push jar file.
-        File jarFile = mCtsBuild.getTestApp(DEVICE_JAR_FILENAME);
+        File jarFile = MigrationHelper.getTestFile(mBuildInfo, DEVICE_JAR_FILENAME);
         boolean success = getDevice().pushFile(jarFile, getDeviceJarFilepath());
         assertTrue("Failed to push jar file to " + getDeviceScriptFilepath(), success);
     }
diff --git a/hostsidetests/monkey/Android.mk b/hostsidetests/monkey/Android.mk
index c9f3bb3..14462d0 100644
--- a/hostsidetests/monkey/Android.mk
+++ b/hostsidetests/monkey/Android.mk
@@ -22,11 +22,16 @@
 
 LOCAL_MODULE := CtsMonkeyTestCases
 
-LOCAL_JAVA_LIBRARIES := cts-tradefed tradefed-prebuilt
+LOCAL_JAVA_LIBRARIES := cts-tradefed tradefed-prebuilt compatibility-host-util
+
+LOCAL_STATIC_JAVA_LIBRARIES := cts-migration-lib
 
 # prefix zzz intentional to run this last
 LOCAL_CTS_TEST_PACKAGE := zzz.android.monkey
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_CTS_HOST_JAVA_LIBRARY)
 
 include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/hostsidetests/monkey/AndroidTest.xml b/hostsidetests/monkey/AndroidTest.xml
new file mode 100644
index 0000000..799ee6a
--- /dev/null
+++ b/hostsidetests/monkey/AndroidTest.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for the CTS monkey host tests">
+    <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
+        <option name="jar" value="CtsMonkeyTestCases.jar" />
+        <option name="runtime-hint" value="5m7s" />
+    </test>
+</configuration>
diff --git a/hostsidetests/monkey/src/com/android/cts/monkey/AbstractMonkeyTest.java b/hostsidetests/monkey/src/com/android/cts/monkey/AbstractMonkeyTest.java
index b31a32d..26023be 100755
--- a/hostsidetests/monkey/src/com/android/cts/monkey/AbstractMonkeyTest.java
+++ b/hostsidetests/monkey/src/com/android/cts/monkey/AbstractMonkeyTest.java
@@ -1,7 +1,7 @@
 package com.android.cts.monkey;
 
-import com.android.cts.tradefed.build.CtsBuildHelper;
-import com.android.cts.util.AbiUtils;
+import com.android.compatibility.common.util.AbiUtils;
+import com.android.cts.migration.MigrationHelper;
 import com.android.tradefed.build.IBuildInfo;
 import com.android.tradefed.device.DeviceNotAvailableException;
 import com.android.tradefed.device.ITestDevice;
@@ -23,7 +23,7 @@
     static final String MONKEY_CMD = "monkey --pct-motion 0 --pct-majornav 0 --pct-syskeys 0 --pct-anyevent 0 --pct-rotation 0";
 
     IAbi mAbi;
-    CtsBuildHelper mBuild;
+    IBuildInfo mBuild;
     ITestDevice mDevice;
 
     @Override
@@ -33,7 +33,7 @@
 
     @Override
     public void setBuild(IBuildInfo buildInfo) {
-        mBuild = CtsBuildHelper.createBuildHelper(buildInfo);
+        mBuild = buildInfo;
     }
 
     @Override
@@ -43,7 +43,7 @@
         String[] options = {AbiUtils.createAbiFlag(mAbi.getName())};
         for (int i = 0; i < PKGS.length; i++) {
             mDevice.uninstallPackage(PKGS[i]);
-            File app = mBuild.getTestApp(APKS[i]);
+            File app = MigrationHelper.getTestFile(mBuild, APKS[i]);
             mDevice.installPackage(app, false, options);
         }
         clearLogCat();
diff --git a/hostsidetests/monkey/test-apps/CtsMonkeyApp/Android.mk b/hostsidetests/monkey/test-apps/CtsMonkeyApp/Android.mk
index c04d4b2..573b488 100644
--- a/hostsidetests/monkey/test-apps/CtsMonkeyApp/Android.mk
+++ b/hostsidetests/monkey/test-apps/CtsMonkeyApp/Android.mk
@@ -30,4 +30,7 @@
 
 LOCAL_DEX_PREOPT := false
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/monkey/test-apps/CtsMonkeyApp2/Android.mk b/hostsidetests/monkey/test-apps/CtsMonkeyApp2/Android.mk
index b3cb181..22c8bf3 100644
--- a/hostsidetests/monkey/test-apps/CtsMonkeyApp2/Android.mk
+++ b/hostsidetests/monkey/test-apps/CtsMonkeyApp2/Android.mk
@@ -30,4 +30,7 @@
 
 LOCAL_DEX_PREOPT := false
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/net/Android.mk b/hostsidetests/net/Android.mk
index 6637d61..ad97ecd 100644
--- a/hostsidetests/net/Android.mk
+++ b/hostsidetests/net/Android.mk
@@ -23,8 +23,13 @@
 
 LOCAL_JAVA_LIBRARIES := cts-tradefed tradefed-prebuilt
 
+LOCAL_STATIC_JAVA_LIBRARIES := cts-migration-lib
+
 LOCAL_CTS_TEST_PACKAGE := android.net.hostsidenetwork
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_CTS_HOST_JAVA_LIBRARY)
 
 # Build the test APKs using their own makefiles
diff --git a/hostsidetests/net/AndroidTest.xml b/hostsidetests/net/AndroidTest.xml
new file mode 100644
index 0000000..9945805
--- /dev/null
+++ b/hostsidetests/net/AndroidTest.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS net host test cases">
+    <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
+        <option name="jar" value="CtsHostsideNetworkTests.jar" />
+        <option name="runtime-hint" value="3m56s" />
+    </test>
+</configuration>
diff --git a/hostsidetests/net/app/Android.mk b/hostsidetests/net/app/Android.mk
index 055287a..7f8da07 100644
--- a/hostsidetests/net/app/Android.mk
+++ b/hostsidetests/net/app/Android.mk
@@ -29,4 +29,7 @@
 LOCAL_PROGUARD_ENABLED := disabled
 LOCAL_DEX_PREOPT := false
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/net/app/AndroidManifest.xml b/hostsidetests/net/app/AndroidManifest.xml
index cdde7dc..c7978f8 100644
--- a/hostsidetests/net/app/AndroidManifest.xml
+++ b/hostsidetests/net/app/AndroidManifest.xml
@@ -17,8 +17,10 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
         package="com.android.cts.net.hostside">
 
-    <uses-permission android:name="android.permission.INTERNET"/>
     <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.INTERNET"/>
 
     <application>
         <uses-library android:name="android.test.runner" />
diff --git a/hostsidetests/net/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/hostsidetests/net/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java
new file mode 100644
index 0000000..27d4a2b
--- /dev/null
+++ b/hostsidetests/net/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java
@@ -0,0 +1,497 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.net.hostside;
+
+import static android.cts.util.SystemUtil.runShellCommand;
+import static android.net.ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED;
+import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED;
+import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED;
+import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELISTED;
+
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+import android.app.ActivityManager;
+import android.app.Instrumentation;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.net.wifi.WifiManager;
+import android.test.InstrumentationTestCase;
+import android.util.Log;
+
+/**
+ * Superclass for tests related to background network restrictions.
+ */
+abstract class AbstractRestrictBackgroundNetworkTestCase extends InstrumentationTestCase {
+    protected static final String TAG = "RestrictBackgroundNetworkTests";
+
+    protected static final String TEST_PKG = "com.android.cts.net.hostside";
+    protected static final String TEST_APP2_PKG = "com.android.cts.net.hostside.app2";
+
+    private static final int SLEEP_TIME_SEC = 1;
+    private static final boolean DEBUG = true;
+
+    // Constants below must match values defined on app2's Common.java
+    private static final String MANIFEST_RECEIVER = "ManifestReceiver";
+    private static final String DYNAMIC_RECEIVER = "DynamicReceiver";
+    private static final String ACTION_GET_COUNTERS =
+            "com.android.cts.net.hostside.app2.action.GET_COUNTERS";
+    private static final String ACTION_CHECK_NETWORK =
+            "com.android.cts.net.hostside.app2.action.CHECK_NETWORK";
+    private static final String ACTION_RECEIVER_READY =
+            "com.android.cts.net.hostside.app2.action.RECEIVER_READY";
+    private static final String EXTRA_ACTION = "com.android.cts.net.hostside.app2.extra.ACTION";
+    private static final String EXTRA_RECEIVER_NAME =
+            "com.android.cts.net.hostside.app2.extra.RECEIVER_NAME";
+    private static final String RESULT_SEPARATOR = ";";
+    private static final String STATUS_NETWORK_UNAVAILABLE_PREFIX = "NetworkUnavailable:";
+    private static final String STATUS_NETWORK_AVAILABLE_PREFIX = "NetworkAvailable:";
+    private static final int SECOND_IN_MS = 1000;
+    private static final int NETWORK_TIMEOUT_MS = 15 * SECOND_IN_MS;
+    private static final int PROCESS_STATE_FOREGROUND_SERVICE = 4;
+
+
+    // Must be higher than NETWORK_TIMEOUT_MS
+    private static final int ORDERED_BROADCAST_TIMEOUT_MS = NETWORK_TIMEOUT_MS * 4;
+
+    protected Context mContext;
+    protected Instrumentation mInstrumentation;
+    protected ConnectivityManager mCm;
+    protected WifiManager mWfm;
+    protected int mUid;
+    private String mMeteredWifi;
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+
+        mInstrumentation = getInstrumentation();
+        mContext = mInstrumentation.getContext();
+        mCm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
+        mWfm = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
+        mUid = getUid(TEST_APP2_PKG);
+        final int myUid = getUid(mContext.getPackageName());
+
+        Log.i(TAG, "Apps status on " + getName() + ":\n"
+                + "\ttest app: uid=" + myUid + ", state=" + getProcessStateByUid(myUid) + "\n"
+                + "\tapp2: uid=" + mUid + ", state=" + getProcessStateByUid(mUid));
+   }
+
+    protected int getUid(String packageName) throws Exception {
+        return mContext.getPackageManager().getPackageUid(packageName, 0);
+    }
+
+    protected void assertRestrictBackgroundChangedReceived(int expectedCount) throws Exception {
+        assertRestrictBackgroundChangedReceived(DYNAMIC_RECEIVER, expectedCount);
+        assertRestrictBackgroundChangedReceived(MANIFEST_RECEIVER, 0);
+    }
+
+    protected void assertRestrictBackgroundChangedReceived(String receiverName, int expectedCount)
+            throws Exception {
+        int attempts = 0;
+        int count = 0;
+        final int maxAttempts = 5;
+        do {
+            attempts++;
+            count = getNumberBroadcastsReceived(receiverName, ACTION_RESTRICT_BACKGROUND_CHANGED);
+            if (count == expectedCount) {
+                break;
+            }
+            Log.d(TAG, "Expecting count " + expectedCount + " but actual is " + count + " after "
+                    + attempts + " attempts; sleeping "
+                    + SLEEP_TIME_SEC + " seconds before trying again");
+            Thread.sleep(SLEEP_TIME_SEC * SECOND_IN_MS);
+        } while (attempts <= maxAttempts);
+        assertEquals("Number of expected broadcasts for " + receiverName + " not reached after "
+                + maxAttempts * SLEEP_TIME_SEC + " seconds", expectedCount, count);
+    }
+
+    protected String sendOrderedBroadcast(Intent intent) throws Exception {
+        return sendOrderedBroadcast(intent, ORDERED_BROADCAST_TIMEOUT_MS);
+    }
+
+    protected String sendOrderedBroadcast(Intent intent, int timeoutMs) throws Exception {
+        final LinkedBlockingQueue<String> result = new LinkedBlockingQueue<>(1);
+        Log.d(TAG, "Sending ordered broadcast: " + intent);
+        mContext.sendOrderedBroadcast(intent, null, new BroadcastReceiver() {
+
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                final String resultData = getResultData();
+                if (resultData == null) {
+                    Log.e(TAG, "Received null data from ordered intent");
+                    return;
+                }
+                result.offer(resultData);
+            }
+        }, null, 0, null, null);
+
+        final String resultData = result.poll(timeoutMs, TimeUnit.MILLISECONDS);
+        Log.d(TAG, "Ordered broadcast response: " + resultData);
+        return resultData;
+    }
+
+    protected int getNumberBroadcastsReceived(String receiverName, String action) throws Exception {
+        final Intent intent = new Intent(ACTION_GET_COUNTERS);
+        intent.putExtra(EXTRA_ACTION, ACTION_RESTRICT_BACKGROUND_CHANGED);
+        intent.putExtra(EXTRA_RECEIVER_NAME, receiverName);
+        final String resultData = sendOrderedBroadcast(intent);
+        assertNotNull("timeout waiting for ordered broadcast result", resultData);
+        return Integer.valueOf(resultData);
+    }
+
+    protected void assertRestrictBackgroundStatus(int expectedApiStatus) throws Exception {
+        assertBackgroundState(); // Sanity check.
+        final Intent intent = new Intent(ACTION_CHECK_NETWORK);
+        final String resultData = sendOrderedBroadcast(intent);
+        final String[] resultItems = resultData.split(RESULT_SEPARATOR);
+        final String actualApiStatus = toString(Integer.parseInt(resultItems[0]));
+        // First asserts the API returns the proper value...
+        assertEquals("wrong status", toString(expectedApiStatus), actualApiStatus);
+
+        //...then the actual network status in the background thread.
+        final String networkStatus = getNetworkStatus(resultItems);
+        assertNetworkStatus(expectedApiStatus != RESTRICT_BACKGROUND_STATUS_ENABLED, networkStatus);
+    }
+
+    protected void assertBackgroundNetworkAccess(boolean expectAllowed) throws Exception {
+        assertBackgroundState(); // Sanity check.
+        final Intent intent = new Intent(ACTION_CHECK_NETWORK);
+        final String resultData = sendOrderedBroadcast(intent);
+        final String[] resultItems = resultData.split(RESULT_SEPARATOR);
+        final String networkStatus = getNetworkStatus(resultItems);
+        assertNetworkStatus(expectAllowed, networkStatus);
+    }
+
+    protected final void assertBackgroundState() throws Exception {
+        final ProcessState state = getProcessStateByUid(mUid);
+        Log.v(TAG, "assertBackgroundState(): status for app2 (" + mUid + "): " + state);
+        final boolean isBackground = isBackground(state.state);
+        assertTrue("App2 is not on background state: " + state, isBackground);
+    }
+
+    protected final void assertForegroundServiceState() throws Exception {
+        final ProcessState state = getProcessStateByUid(mUid);
+        Log.v(TAG, "assertForegroundServiceState(): status for app2 (" + mUid + "): " + state);
+        assertEquals("App2 is not on foreground service state: " + state,
+                PROCESS_STATE_FOREGROUND_SERVICE, state.state);
+    }
+
+    /**
+     * Returns whether an app state should be considered "background" for restriction purposes.
+     */
+    protected boolean isBackground(int state) {
+        return state >= PROCESS_STATE_FOREGROUND_SERVICE;
+    }
+
+    private String getNetworkStatus(String[] resultItems) {
+        return resultItems.length < 2 ? null : resultItems[1];
+    }
+
+    private void assertNetworkStatus(boolean expectAvailable, String status) throws Exception {
+        if (status == null) {
+            Log.d(TAG, "timeout waiting for ordered broadcast");
+            if (expectAvailable) {
+                fail("did not get network status when access was allowed");
+            }
+            return;
+        }
+        final String expectedPrefix = expectAvailable ?
+                STATUS_NETWORK_AVAILABLE_PREFIX : STATUS_NETWORK_UNAVAILABLE_PREFIX;
+        assertTrue("Wrong network status (" + status + ") when expectedAvailable is "
+                + expectAvailable, status.startsWith(expectedPrefix));
+    }
+
+    protected String executeShellCommand(String command) throws Exception {
+        final String result = runShellCommand(mInstrumentation, command).trim();
+        if (DEBUG) Log.d(TAG, "Command '" + command + "' returned '" + result + "'");
+        return result;
+    }
+
+    /**
+     * Runs a Shell command which is not expected to generate output.
+     */
+    protected void executeSilentShellCommand(String command) throws Exception {
+        final String result = executeShellCommand(command);
+        assertTrue("Command '" + command + "' failed: " + result, result.trim().isEmpty());
+    }
+
+    /**
+     * Asserts the result of a command, wait and re-running it a couple times if necessary.
+     */
+    protected void assertDelayedShellCommand(String command, final String expectedResult)
+            throws Exception {
+        assertDelayedShellCommand(command, new ExpectResultChecker() {
+
+            @Override
+            public boolean isExpected(String result) {
+                return expectedResult.equals(result);
+            }
+
+            @Override
+            public String getExpected() {
+                return expectedResult;
+            }
+        });
+    }
+
+    protected void assertDelayedShellCommand(String command, ExpectResultChecker checker)
+            throws Exception {
+        final int maxTries = 5;
+        String result = "";
+        for (int i = 1; i <= maxTries; i++) {
+            result = executeShellCommand(command).trim();
+            if (checker.isExpected(result)) return;
+            Log.v(TAG, "Command '" + command + "' returned '" + result + " instead of '"
+                    + checker.getExpected() + "' on attempt #" + i
+                    + "; sleeping 1s before trying again");
+            Thread.sleep(SECOND_IN_MS);
+        }
+        fail("Command '" + command + "' did not return '" + checker.getExpected() + "' after "
+                + maxTries
+                + " attempts. Last result: '" + result + "'");
+    }
+
+    protected void setMeteredNetwork() throws Exception {
+        final NetworkInfo info = mCm.getActiveNetworkInfo();
+        final boolean metered = mCm.isActiveNetworkMetered();
+        if (metered) {
+            Log.d(TAG, "Active network already metered: " + info);
+            return;
+        } else {
+            Log.w(TAG, "Active network not metered: " + info);
+        }
+        final String netId = setWifiMeteredStatus(true);
+
+        // Set flag so status is reverted on resetMeteredNetwork();
+        mMeteredWifi = netId;
+        // Sanity check.
+        assertWifiMeteredStatus(netId, true);
+        assertTrue("Could not set wifi '" + netId + "' as metered ("
+                + mCm.getActiveNetworkInfo() +")", mCm.isActiveNetworkMetered());
+    }
+
+    protected void resetMeteredNetwork() throws Exception {
+        if (mMeteredWifi == null) {
+            Log.d(TAG, "resetMeteredNetwork(): wifi not set as metered");
+            return;
+        }
+        Log.i(TAG, "resetMeteredNetwork(): resetting " + mMeteredWifi);
+        setWifiMeteredStatus(mMeteredWifi, false);
+    }
+
+    private String setWifiMeteredStatus(boolean metered) throws Exception {
+        // We could call setWifiEnabled() here, but it might take sometime to be in a consistent
+        // state (for example, if one of the saved network is not properly authenticated), so it's
+        // better to let the hostside test take care of that.
+        assertTrue("wi-fi is disabled", mWfm.isWifiEnabled());
+        // TODO: if it's not guaranteed the device has wi-fi, we need to change the tests
+        // to make the actual verification of restrictions optional.
+        final String ssid = mWfm.getConnectionInfo().getSSID();
+        return setWifiMeteredStatus(ssid, metered);
+    }
+
+    private String setWifiMeteredStatus(String ssid, boolean metered) throws Exception {
+        assertNotNull("null SSID", ssid);
+        final String netId = ssid.trim().replaceAll("\"", ""); // remove quotes, if any.
+        assertFalse("empty SSID", ssid.isEmpty());
+
+        Log.i(TAG, "Setting wi-fi network " + netId + " metered status to " + metered);
+        final String setCommand = "cmd netpolicy set metered-network " + netId + " " + metered;
+        assertDelayedShellCommand(setCommand, "");
+
+        return netId;
+    }
+
+    private void assertWifiMeteredStatus(String netId, boolean status) throws Exception {
+        final String command = "cmd netpolicy list wifi-networks";
+        final String expectedLine = netId + ";" + status;
+        assertDelayedShellCommand(command, new ExpectResultChecker() {
+
+            @Override
+            public boolean isExpected(String result) {
+                return result.contains(expectedLine);
+            }
+
+            @Override
+            public String getExpected() {
+                return "line containing " + expectedLine;
+            }
+        });
+    }
+
+    protected void setRestrictBackground(boolean enabled) throws Exception {
+        executeShellCommand("cmd netpolicy set restrict-background " + enabled);
+        final String output = executeShellCommand("cmd netpolicy get restrict-background ");
+        final String expectedSuffix = enabled ? "enabled" : "disabled";
+        // TODO: use MoreAsserts?
+        assertTrue("output '" + output + "' should end with '" + expectedSuffix + "'",
+                output.endsWith(expectedSuffix));
+      }
+
+    protected void addRestrictBackgroundWhitelist(int uid) throws Exception {
+        executeShellCommand("cmd netpolicy add restrict-background-whitelist " + uid);
+        assertRestrictBackgroundWhitelist(uid, true);
+    }
+
+    protected void removeRestrictBackgroundWhitelist(int uid) throws Exception {
+        executeShellCommand("cmd netpolicy remove restrict-background-whitelist " + uid);
+        assertRestrictBackgroundWhitelist(uid, false);
+    }
+
+    protected void assertRestrictBackgroundWhitelist(int uid, boolean expected) throws Exception {
+        assertRestrictBackground("restrict-background-whitelist", uid, expected);
+    }
+
+    protected void addRestrictBackgroundBlacklist(int uid) throws Exception {
+        executeShellCommand("cmd netpolicy add restrict-background-blacklist " + uid);
+        assertRestrictBackgroundBlacklist(uid, true);
+    }
+
+    protected void removeRestrictBackgroundBlacklist(int uid) throws Exception {
+        executeShellCommand("cmd netpolicy remove restrict-background-blacklist " + uid);
+        assertRestrictBackgroundBlacklist(uid, false);
+    }
+
+    protected void assertRestrictBackgroundBlacklist(int uid, boolean expected) throws Exception {
+        assertRestrictBackground("restrict-background-blacklist", uid, expected);
+    }
+
+    private void assertRestrictBackground(String list, int uid, boolean expected) throws Exception {
+        final int maxTries = 5;
+        boolean actual = false;
+        for (int i = 1; i <= maxTries; i++) {
+            final String output =
+                    executeShellCommand("cmd netpolicy list " + list);
+            actual = output.contains(Integer.toString(uid));
+            if (expected == actual) {
+                return;
+            }
+            Log.v(TAG, list + " check for uid " + uid + " doesn't match yet (expected "
+                    + expected + ", got " + actual + "); sleeping 1s before polling again");
+            Thread.sleep(SECOND_IN_MS);
+        }
+        fail(list + " check for uid " + uid + " failed: expected " + expected + ", got " + actual);
+    }
+
+    protected void assertPowerSaveModeWhitelist(String packageName, boolean expected)
+            throws Exception {
+        // TODO: currently the power-save mode is behaving like idle, but once it changes, we'll
+        // need to use netpolicy for whitelisting
+        assertDelayedShellCommand("dumpsys deviceidle whitelist =" + packageName,
+                Boolean.toString(expected));
+    }
+
+    protected void addPowerSaveModeWhitelist(String packageName) throws Exception {
+        Log.i(TAG, "Adding package " + packageName + " to power-save-mode whitelist");
+        // TODO: currently the power-save mode is behaving like idle, but once it changes, we'll
+        // need to use netpolicy for whitelisting
+        executeShellCommand("dumpsys deviceidle whitelist +" + packageName);
+        assertPowerSaveModeWhitelist(packageName, true); // Sanity check
+    }
+
+    protected void removePowerSaveModeWhitelist(String packageName) throws Exception {
+        Log.i(TAG, "Removing package " + packageName + " from power-save-mode whitelist");
+        // TODO: currently the power-save mode is behaving like idle, but once it changes, we'll
+        // need to use netpolicy for whitelisting
+        executeShellCommand("dumpsys deviceidle whitelist -" + packageName);
+        assertPowerSaveModeWhitelist(packageName, false); // Sanity check
+    }
+
+    protected void setPowerSaveMode(boolean enabled) throws Exception {
+        Log.i(TAG, "Setting power mode to " + enabled);
+        if (enabled) {
+            executeSilentShellCommand("cmd battery unplug");
+            executeSilentShellCommand("settings put global low_power 1");
+        } else {
+            executeSilentShellCommand("cmd battery reset");
+        }
+    }
+
+    /**
+     * Starts a service that will register a broadcast receiver to receive
+     * {@code RESTRICT_BACKGROUND_CHANGE} intents.
+     * <p>
+     * The service must run in a separate app because otherwise it would be killed every time
+     * {@link #runDeviceTests(String, String)} is executed.
+     */
+    protected void registerBroadcastReceiver() throws Exception {
+        executeShellCommand("am startservice com.android.cts.net.hostside.app2/.MyService");
+        // Wait until receiver is ready.
+        final int maxTries = 5;
+        for (int i = 1; i <= maxTries; i++) {
+            final String message =
+                    sendOrderedBroadcast(new Intent(ACTION_RECEIVER_READY), SECOND_IN_MS);
+            Log.d(TAG, "app2 receiver acked: " + message);
+            if (message != null) {
+                return;
+            }
+            Log.v(TAG, "app2 receiver is not ready yet; sleeping 1s before polling again");
+            Thread.sleep(SECOND_IN_MS);
+        }
+        fail("app2 receiver is not ready");
+    }
+
+    protected void startForegroundService() throws Exception {
+        executeShellCommand(
+                "am startservice com.android.cts.net.hostside.app2/.MyForegroundService");
+    }
+
+    private String toString(int status) {
+        switch (status) {
+            case RESTRICT_BACKGROUND_STATUS_DISABLED:
+                return "DISABLED";
+            case RESTRICT_BACKGROUND_STATUS_WHITELISTED:
+                return "WHITELISTED";
+            case RESTRICT_BACKGROUND_STATUS_ENABLED:
+                return "ENABLED";
+            default:
+                return "UNKNOWN_STATUS_" + status;
+        }
+    }
+
+    private ProcessState getProcessStateByUid(int uid) throws Exception {
+        return new ProcessState(executeShellCommand("cmd activity get-uid-state " + uid));
+    }
+
+    private static class ProcessState {
+        private final String fullState;
+        final int state;
+
+        ProcessState(String fullState) {
+            this.fullState = fullState;
+            try {
+                this.state = Integer.parseInt(fullState.split(" ")[0]);
+            } catch (Exception e) {
+                throw new IllegalArgumentException("Could not parse " + fullState);
+            }
+        }
+
+        @Override
+        public String toString() {
+            return fullState;
+        }
+    }
+
+    protected static interface ExpectResultChecker {
+        boolean isExpected(String result);
+        String getExpected();
+    }
+}
diff --git a/hostsidetests/net/app/src/com/android/cts/net/hostside/BatterySaverModeNonMeteredTest.java b/hostsidetests/net/app/src/com/android/cts/net/hostside/BatterySaverModeNonMeteredTest.java
new file mode 100644
index 0000000..8e83fa2
--- /dev/null
+++ b/hostsidetests/net/app/src/com/android/cts/net/hostside/BatterySaverModeNonMeteredTest.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.net.hostside;
+
+//TODO: move this and BatterySaverModeTest's logic into a common superclass
+public class BatterySaverModeNonMeteredTest extends AbstractRestrictBackgroundNetworkTestCase {
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+
+        setPowerSaveMode(false);
+        assertPowerSaveModeWhitelist(TEST_APP2_PKG, false); // Sanity check
+        registerBroadcastReceiver();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+
+        setPowerSaveMode(false);
+    }
+
+    public void testBackgroundNetworkAccess_enabled() throws Exception {
+        setPowerSaveMode(true);
+        assertBackgroundNetworkAccess(false);
+        // Make sure app is allowed if running a foreground service.
+        startForegroundService();
+        assertForegroundServiceState();
+        assertBackgroundNetworkAccess(true);
+    }
+
+    public void testBackgroundNetworkAccess_whitelisted() throws Exception {
+        setPowerSaveMode(true);
+        assertBackgroundNetworkAccess(false);
+        addPowerSaveModeWhitelist(TEST_APP2_PKG);
+        assertBackgroundNetworkAccess(true);
+        removePowerSaveModeWhitelist(TEST_APP2_PKG);
+        assertBackgroundNetworkAccess(false);
+    }
+
+    public void testBackgroundNetworkAccess_disabled() throws Exception {
+        setPowerSaveMode(false);
+        assertBackgroundNetworkAccess(true);
+    }
+}
diff --git a/hostsidetests/net/app/src/com/android/cts/net/hostside/BatterySaverModeTest.java b/hostsidetests/net/app/src/com/android/cts/net/hostside/BatterySaverModeTest.java
new file mode 100644
index 0000000..d1217b4
--- /dev/null
+++ b/hostsidetests/net/app/src/com/android/cts/net/hostside/BatterySaverModeTest.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.net.hostside;
+
+//TODO: move this and BatterySaverModeNonMeteredTest's logic into a common superclass
+public class BatterySaverModeTest extends AbstractRestrictBackgroundNetworkTestCase {
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+
+        setMeteredNetwork();
+        setPowerSaveMode(false);
+        assertPowerSaveModeWhitelist(TEST_APP2_PKG, false); // Sanity check
+        registerBroadcastReceiver();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+
+        try {
+            resetMeteredNetwork();
+        } finally {
+            setPowerSaveMode(false);
+        }
+    }
+
+    public void testBackgroundNetworkAccess_enabled() throws Exception {
+        setPowerSaveMode(true);
+        assertBackgroundNetworkAccess(false);
+
+        // Make sure app is allowed if running a foreground service.
+        startForegroundService();
+        assertForegroundServiceState();
+        assertBackgroundNetworkAccess(true);
+    }
+
+    public void testBackgroundNetworkAccess_whitelisted() throws Exception {
+        setPowerSaveMode(true);
+        assertBackgroundNetworkAccess(false);
+        addPowerSaveModeWhitelist(TEST_APP2_PKG);
+        assertBackgroundNetworkAccess(true);
+        removePowerSaveModeWhitelist(TEST_APP2_PKG);
+        assertBackgroundNetworkAccess(false);
+    }
+
+    public void testBackgroundNetworkAccess_disabled() throws Exception {
+        setPowerSaveMode(false);
+        assertBackgroundNetworkAccess(true);
+    }
+}
diff --git a/hostsidetests/net/app/src/com/android/cts/net/hostside/DataSaverModeTest.java b/hostsidetests/net/app/src/com/android/cts/net/hostside/DataSaverModeTest.java
new file mode 100644
index 0000000..62f670e
--- /dev/null
+++ b/hostsidetests/net/app/src/com/android/cts/net/hostside/DataSaverModeTest.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.net.hostside;
+
+import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED;
+import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED;
+import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELISTED;
+
+/*
+ * TODO: need to add more scenarios:
+ * - test access on foreground app
+ * - test access on foreground service app
+ * - make sure it works when app is on foreground and state is transitioned:
+ *   - data saver is enabled
+ *   - app is added/removed to blacklist
+ *
+ */
+public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase {
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+
+        setMeteredNetwork();
+        setRestrictBackground(false);
+        registerBroadcastReceiver();
+   }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+
+        try {
+            resetMeteredNetwork();
+        } finally {
+            setRestrictBackground(false);
+        }
+    }
+
+    public void testGetRestrictBackgroundStatus_disabled() throws Exception {
+        removeRestrictBackgroundWhitelist(mUid);
+        assertRestrictBackgroundChangedReceived(0);
+        assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_DISABLED);
+
+        // Sanity check: make sure status is always disabled, never whitelisted
+        addRestrictBackgroundWhitelist(mUid);
+        assertRestrictBackgroundChangedReceived(0);
+        assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_DISABLED);
+    }
+
+    public void testGetRestrictBackgroundStatus_whitelisted() throws Exception {
+        setRestrictBackground(true);
+        assertRestrictBackgroundChangedReceived(1);
+
+        addRestrictBackgroundWhitelist(mUid);
+        assertRestrictBackgroundChangedReceived(2);
+        assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_WHITELISTED);
+    }
+
+    public void testGetRestrictBackgroundStatus_enabled() throws Exception {
+        setRestrictBackground(true);
+        assertRestrictBackgroundChangedReceived(1);
+        assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_ENABLED);
+
+        removeRestrictBackgroundWhitelist(mUid);
+        assertRestrictBackgroundChangedReceived(1);
+        assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_ENABLED);
+
+        // Make sure app is allowed if running a foreground service.
+        assertBackgroundNetworkAccess(false);
+        startForegroundService();
+        assertForegroundServiceState();
+        assertBackgroundNetworkAccess(true);
+    }
+
+    public void testGetRestrictBackgroundStatus_blacklisted() throws Exception {
+        addRestrictBackgroundBlacklist(mUid);
+        assertRestrictBackgroundChangedReceived(1);
+        assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_ENABLED);
+
+        // Make sure blacklist prevails over whitelist.
+        setRestrictBackground(true);
+        assertRestrictBackgroundChangedReceived(2);
+        assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_ENABLED);
+        addRestrictBackgroundWhitelist(mUid);
+        assertRestrictBackgroundChangedReceived(3);
+        assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_ENABLED);
+
+        // Check status after removing blacklist.
+        removeRestrictBackgroundBlacklist(mUid);
+        assertRestrictBackgroundChangedReceived(4);
+        assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_WHITELISTED);
+        setRestrictBackground(false);
+        assertRestrictBackgroundChangedReceived(5);
+        assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_DISABLED);
+    }
+}
diff --git a/hostsidetests/net/app/src/com/android/cts/net/hostside/MyActivity.java b/hostsidetests/net/app/src/com/android/cts/net/hostside/MyActivity.java
index 375c852..0d0bc58 100644
--- a/hostsidetests/net/app/src/com/android/cts/net/hostside/MyActivity.java
+++ b/hostsidetests/net/app/src/com/android/cts/net/hostside/MyActivity.java
@@ -18,13 +18,9 @@
 
 import android.app.Activity;
 import android.content.Intent;
-import android.net.VpnService;
 import android.os.Bundle;
-import android.os.ParcelFileDescriptor;
 import android.view.WindowManager;
 
-import java.util.Arrays;
-import java.util.ArrayList;
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.TimeUnit;
 
diff --git a/hostsidetests/net/app/src/com/android/cts/net/hostside/MyVpnService.java b/hostsidetests/net/app/src/com/android/cts/net/hostside/MyVpnService.java
index a3f400c..90a3ce4 100644
--- a/hostsidetests/net/app/src/com/android/cts/net/hostside/MyVpnService.java
+++ b/hostsidetests/net/app/src/com/android/cts/net/hostside/MyVpnService.java
@@ -26,7 +26,6 @@
 import java.io.IOException;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
-import java.util.ArrayList;
 
 public class MyVpnService extends VpnService {
 
diff --git a/hostsidetests/net/app2/Android.mk b/hostsidetests/net/app2/Android.mk
new file mode 100644
index 0000000..3b59f8f
--- /dev/null
+++ b/hostsidetests/net/app2/Android.mk
@@ -0,0 +1,34 @@
+#
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+LOCAL_SDK_VERSION := current
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := CtsHostsideNetworkTestsApp2
+
+LOCAL_PROGUARD_ENABLED := disabled
+LOCAL_DEX_PREOPT := false
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/net/app2/AndroidManifest.xml b/hostsidetests/net/app2/AndroidManifest.xml
new file mode 100644
index 0000000..9ce5781
--- /dev/null
+++ b/hostsidetests/net/app2/AndroidManifest.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.cts.net.hostside.app2" >
+
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.INTERNET" />
+
+    <!--
+         This application is used to listen to RESTRICT_BACKGROUND_CHANGED intents and store
+         them in a shared preferences which is then read by the test app. These broadcasts are
+         handled by 2 listeners, one defined the manifest and another dynamically registered by
+         a service.
+
+         The manifest-defined listener also handles ordered broadcasts used to share data with the
+         test app.
+    -->
+    <application>
+        <service android:name=".MyService" android:exported="true"/>
+        <service android:name=".MyForegroundService" android:exported="true"/>
+
+        <receiver android:name=".MyBroadcastReceiver" >
+            <intent-filter>
+                <action android:name="android.net.conn.RESTRICT_BACKGROUND_CHANGED" />
+                <action android:name="com.android.cts.net.hostside.app2.action.GET_COUNTERS" />
+                <action android:name="com.android.cts.net.hostside.app2.action.CHECK_NETWORK" />
+            </intent-filter>
+        </receiver>
+    </application>
+
+</manifest>
\ No newline at end of file
diff --git a/hostsidetests/net/app2/src/com/android/cts/net/hostside/app2/Common.java b/hostsidetests/net/app2/src/com/android/cts/net/hostside/app2/Common.java
new file mode 100644
index 0000000..668669b
--- /dev/null
+++ b/hostsidetests/net/app2/src/com/android/cts/net/hostside/app2/Common.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.net.hostside.app2;
+
+import android.content.Context;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.util.Log;
+
+public final class Common {
+
+    static final String TAG = "CtsNetApp2";
+
+    // Constants below must match values defined on app's
+    // AbstractRestrictBackgroundNetworkTestCase.java
+    static final String MANIFEST_RECEIVER = "ManifestReceiver";
+    static final String DYNAMIC_RECEIVER = "DynamicReceiver";
+    static final String ACTION_GET_COUNTERS =
+            "com.android.cts.net.hostside.app2.action.GET_COUNTERS";
+    static final String ACTION_CHECK_NETWORK =
+            "com.android.cts.net.hostside.app2.action.CHECK_NETWORK";
+    static final String ACTION_RECEIVER_READY =
+            "com.android.cts.net.hostside.app2.action.RECEIVER_READY";
+    static final String EXTRA_ACTION = "com.android.cts.net.hostside.app2.extra.ACTION";
+    static final String EXTRA_RECEIVER_NAME =
+            "com.android.cts.net.hostside.app2.extra.RECEIVER_NAME";
+    static final char RESULT_SEPARATOR = ';';
+    static final String STATUS_NETWORK_UNAVAILABLE_PREFIX = "NetworkUnavailable:";
+    static final String STATUS_NETWORK_AVAILABLE_PREFIX = "NetworkAvailable:";
+
+    static int getUid(Context context) {
+        final String packageName = context.getPackageName();
+        try {
+            return context.getPackageManager().getPackageUid(packageName, 0);
+        } catch (NameNotFoundException e) {
+            throw new IllegalStateException("Could not get UID for " + packageName, e);
+        }
+    }
+}
diff --git a/hostsidetests/net/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java b/hostsidetests/net/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java
new file mode 100644
index 0000000..07f717b
--- /dev/null
+++ b/hostsidetests/net/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.net.hostside.app2;
+
+import static android.net.ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED;
+import static com.android.cts.net.hostside.app2.Common.ACTION_CHECK_NETWORK;
+import static com.android.cts.net.hostside.app2.Common.ACTION_GET_COUNTERS;
+import static com.android.cts.net.hostside.app2.Common.ACTION_RECEIVER_READY;
+import static com.android.cts.net.hostside.app2.Common.EXTRA_ACTION;
+import static com.android.cts.net.hostside.app2.Common.EXTRA_RECEIVER_NAME;
+import static com.android.cts.net.hostside.app2.Common.MANIFEST_RECEIVER;
+import static com.android.cts.net.hostside.app2.Common.RESULT_SEPARATOR;
+import static com.android.cts.net.hostside.app2.Common.STATUS_NETWORK_AVAILABLE_PREFIX;
+import static com.android.cts.net.hostside.app2.Common.STATUS_NETWORK_UNAVAILABLE_PREFIX;
+import static com.android.cts.net.hostside.app2.Common.TAG;
+import static com.android.cts.net.hostside.app2.Common.getUid;
+
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.util.Log;
+
+/**
+ * Receiver used to:
+ * <ol>
+ * <li>Stored received RESTRICT_BACKGROUND_CHANGED broadcasts in a shared preference.
+ * <li>Returned the number of RESTRICT_BACKGROUND_CHANGED broadcasts in an ordered broadcast.
+ * </ol>
+ */
+public class MyBroadcastReceiver extends BroadcastReceiver {
+
+    private static final int NETWORK_TIMEOUT_MS = 15 * 1000;
+
+    private final String mName;
+
+    public MyBroadcastReceiver() {
+        this(MANIFEST_RECEIVER);
+    }
+
+    MyBroadcastReceiver(String name) {
+        Log.d(TAG, "Constructing MyBroadcastReceiver named " + name);
+        mName = name;
+    }
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        Log.d(TAG, "onReceive() for " + mName + ": " + intent);
+        final String action = intent.getAction();
+        switch (action) {
+            case ACTION_RESTRICT_BACKGROUND_CHANGED:
+                increaseCounter(context, action);
+                break;
+            case ACTION_GET_COUNTERS:
+                setResultDataFromCounter(context, intent);
+                break;
+            case ACTION_CHECK_NETWORK:
+                checkNetwork(context, intent);
+                break;
+            case ACTION_RECEIVER_READY:
+                final String message = mName + " is ready to rumble";
+                Log.d(TAG, message);
+                setResultData(message);
+                break;
+            default:
+                Log.e(TAG, "received unexpected action: " + action);
+        }
+    }
+
+    private void increaseCounter(Context context, String action) {
+        final SharedPreferences prefs = context.getSharedPreferences(mName, Context.MODE_PRIVATE);
+        final int value = prefs.getInt(action, 0) + 1;
+        Log.d(TAG, "increaseCounter('" + action + "'): setting '" + mName + "' to " + value);
+        prefs.edit().putInt(action, value).apply();
+    }
+
+    private int getCounter(Context context, String action, String receiverName) {
+        final SharedPreferences prefs = context.getSharedPreferences(receiverName,
+                Context.MODE_PRIVATE);
+        final int value = prefs.getInt(action, 0);
+        Log.d(TAG, "getCounter('" + action + "', '" + receiverName + "'): " + value);
+        return value;
+    }
+
+    private void checkNetwork(final Context context, Intent intent) {
+        final ConnectivityManager cm = (ConnectivityManager) context
+                .getSystemService(Context.CONNECTIVITY_SERVICE);
+
+        final StringBuilder data = new StringBuilder();
+        final int apiStatus = cm.getRestrictBackgroundStatus();
+        String netStatus;
+        try {
+            netStatus = checkNetworkStatus(context, cm);
+        } catch (InterruptedException e) {
+            Log.e(TAG, "Timeout checking network status");
+            setResultData(null);
+            return;
+        }
+        data.append(apiStatus).append(RESULT_SEPARATOR);
+        if (netStatus != null) {
+            data.append(netStatus);
+        }
+        Log.d(TAG, "checkNetwork: returning " + data);
+        setResultData(data.toString());
+    }
+
+    private String checkNetworkStatus(final Context context, final ConnectivityManager cm)
+            throws InterruptedException {
+        final LinkedBlockingQueue<String> result = new LinkedBlockingQueue<>(1);
+        new Thread(new Runnable() {
+
+            @Override
+            public void run() {
+                // TODO: connect to a hostside server instead
+                final String address = "http://example.com";
+                final NetworkInfo networkInfo = cm.getActiveNetworkInfo();
+                Log.d(TAG, "Running checkNetworkStatus() on thread "
+                        + Thread.currentThread().getName() + " for UID " + getUid(context)
+                        + "\n\tactiveNetworkInfo: " + networkInfo + "\n\tURL: " + address);
+                String prefix = STATUS_NETWORK_AVAILABLE_PREFIX;
+                try {
+                    final URL url = new URL(address);
+                    final HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+                    conn.setReadTimeout(NETWORK_TIMEOUT_MS);
+                    conn.setConnectTimeout(NETWORK_TIMEOUT_MS);
+                    conn.setRequestMethod("GET");
+                    conn.setDoInput(true);
+                    conn.connect();
+                    final int response = conn.getResponseCode();
+                    Log.d(TAG, "HTTP response for " + address + ": " + response);
+                } catch (Exception e) {
+                    Log.d(TAG, "Exception getting " + address + ": " + e);
+                    prefix = STATUS_NETWORK_UNAVAILABLE_PREFIX + "Exception " + e + ":";
+                }
+                final String netInfo = prefix + networkInfo;
+                Log.d(TAG, "Offering " + netInfo);
+                result.offer(netInfo);
+            }
+        }, mName).start();
+        return result.poll(NETWORK_TIMEOUT_MS * 2, TimeUnit.MILLISECONDS);
+    }
+
+    private void setResultDataFromCounter(Context context, Intent intent) {
+        final String action = intent.getStringExtra(EXTRA_ACTION);
+        if (action == null) {
+            Log.e(TAG, "Missing extra '" + EXTRA_ACTION + "' on " + intent);
+            return;
+        }
+        final String receiverName = intent.getStringExtra(EXTRA_RECEIVER_NAME);
+        if (receiverName == null) {
+            Log.e(TAG, "Missing extra '" + EXTRA_RECEIVER_NAME + "' on " + intent);
+            return;
+        }
+        final int counter = getCounter(context, action, receiverName);
+        setResultData(String.valueOf(counter));
+    }
+}
diff --git a/hostsidetests/net/app2/src/com/android/cts/net/hostside/app2/MyForegroundService.java b/hostsidetests/net/app2/src/com/android/cts/net/hostside/app2/MyForegroundService.java
new file mode 100644
index 0000000..bbafd4c
--- /dev/null
+++ b/hostsidetests/net/app2/src/com/android/cts/net/hostside/app2/MyForegroundService.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.net.hostside.app2;
+
+import static com.android.cts.net.hostside.app2.Common.TAG;
+import android.R;
+import android.app.Notification;
+import android.app.Service;
+import android.content.Intent;
+import android.os.IBinder;
+import android.util.Log;
+
+/**
+ * Service used to change app state to FOREGROUND_SERVICE.
+ */
+public class MyForegroundService extends Service {
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        return null;
+    }
+
+    @Override
+    public int onStartCommand(Intent intent, int flags, int startId) {
+        Log.d(TAG, "MyForegroundService.onStartCommand: " + intent);
+        startForeground(42, new Notification.Builder(this)
+            .setSmallIcon(R.drawable.ic_dialog_alert) // any icon is fine
+            .build());
+        return START_STICKY;
+    }
+}
diff --git a/hostsidetests/net/app2/src/com/android/cts/net/hostside/app2/MyService.java b/hostsidetests/net/app2/src/com/android/cts/net/hostside/app2/MyService.java
new file mode 100644
index 0000000..e6454c7
--- /dev/null
+++ b/hostsidetests/net/app2/src/com/android/cts/net/hostside/app2/MyService.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.net.hostside.app2;
+
+import static android.net.ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED;
+import static com.android.cts.net.hostside.app2.Common.ACTION_RECEIVER_READY;
+import static com.android.cts.net.hostside.app2.Common.DYNAMIC_RECEIVER;
+import static com.android.cts.net.hostside.app2.Common.TAG;
+
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.IBinder;
+import android.util.Log;
+
+/**
+ * Service used to dynamically register a broadcast receiver.
+ */
+public class MyService extends Service {
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        return null;
+    }
+
+    @Override
+    public int onStartCommand(Intent intent, int flags, int startId) {
+        Log.d(TAG, "MyService.onStartCommand: " + intent);
+        final Context context = getApplicationContext();
+        final MyBroadcastReceiver myReceiver = new MyBroadcastReceiver(DYNAMIC_RECEIVER);
+        context.registerReceiver(myReceiver, new IntentFilter(ACTION_RECEIVER_READY));
+        context.registerReceiver(myReceiver, new IntentFilter(ACTION_RESTRICT_BACKGROUND_CHANGED));
+        Log.d(TAG, "receiver registered");
+        return START_STICKY;
+    }
+}
diff --git a/hostsidetests/net/src/com/android/cts/net/HostsideNetworkTestCase.java b/hostsidetests/net/src/com/android/cts/net/HostsideNetworkTestCase.java
new file mode 100644
index 0000000..39b5652
--- /dev/null
+++ b/hostsidetests/net/src/com/android/cts/net/HostsideNetworkTestCase.java
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.net;
+
+import com.android.cts.migration.MigrationHelper;
+import com.android.ddmlib.Log;
+import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
+import com.android.ddmlib.testrunner.TestIdentifier;
+import com.android.ddmlib.testrunner.TestResult;
+import com.android.ddmlib.testrunner.TestResult.TestStatus;
+import com.android.ddmlib.testrunner.TestRunResult;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.result.CollectingTestListener;
+import com.android.tradefed.testtype.DeviceTestCase;
+import com.android.tradefed.testtype.IAbi;
+import com.android.tradefed.testtype.IAbiReceiver;
+import com.android.tradefed.testtype.IBuildReceiver;
+
+import java.io.FileNotFoundException;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+abstract class HostsideNetworkTestCase extends DeviceTestCase implements IAbiReceiver,
+        IBuildReceiver {
+    protected static final boolean DEBUG = false;
+    protected static final String TAG = "HostsideNetworkTests";
+    protected static final String TEST_PKG = "com.android.cts.net.hostside";
+    protected static final String TEST_APK = "CtsHostsideNetworkTestsApp.apk";
+
+    private IAbi mAbi;
+    private IBuildInfo mCtsBuild;
+
+    @Override
+    public void setAbi(IAbi abi) {
+        mAbi = abi;
+    }
+
+    @Override
+    public void setBuild(IBuildInfo buildInfo) {
+        mCtsBuild = buildInfo;
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        assertNotNull(mAbi);
+        assertNotNull(mCtsBuild);
+
+        assertTrue("wi-fi not enabled", getDevice().isWifiEnabled());
+
+        uninstallPackage(TEST_PKG, false);
+        installPackage(TEST_APK);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+
+        uninstallPackage(TEST_PKG, true);
+    }
+
+    protected void installPackage(String apk) throws FileNotFoundException,
+            DeviceNotAvailableException {
+        assertNull(getDevice().installPackage(MigrationHelper.getTestFile(mCtsBuild, apk), false));
+    }
+
+    protected void uninstallPackage(String packageName, boolean shouldSucceed)
+            throws DeviceNotAvailableException {
+        final String result = getDevice().uninstallPackage(packageName);
+        if (shouldSucceed) {
+            assertNull("uninstallPackage(" + packageName + ") failed: " + result, result);
+        }
+    }
+
+    protected void assertPackageUninstalled(String packageName) throws DeviceNotAvailableException,
+            InterruptedException {
+        final String command = "cmd package list packages " + packageName;
+        final int max_tries = 5;
+        for (int i = 1; i <= max_tries; i++) {
+            final String result = runCommand(command);
+            if (result.trim().isEmpty()) {
+                return;
+            }
+            // 'list packages' filters by substring, so we need to iterate with the results
+            // and check one by one, otherwise 'com.android.cts.net.hostside' could return
+            // 'com.android.cts.net.hostside.app2'
+            boolean found = false;
+            for (String line : result.split("[\\r\\n]+")) {
+                if (line.endsWith(packageName)) {
+                    found = true;
+                    break;
+                }
+            }
+            if (!found) {
+                return;
+            }
+            i++;
+            Log.v(TAG, "Package " + packageName + " not uninstalled yet (" + result
+                    + "); sleeping 1s before polling again");
+            Thread.sleep(1000);
+        }
+        fail("Package '" + packageName + "' not uinstalled after " + max_tries + " seconds");
+    }
+
+    protected void runDeviceTests(String packageName, String testClassName)
+            throws DeviceNotAvailableException {
+        runDeviceTests(packageName, testClassName, null);
+    }
+
+    protected void runDeviceTests(String packageName, String testClassName, String methodName)
+            throws DeviceNotAvailableException {
+        RemoteAndroidTestRunner testRunner = new RemoteAndroidTestRunner(packageName,
+                "android.support.test.runner.AndroidJUnitRunner", getDevice().getIDevice());
+
+        if (testClassName != null) {
+            if (methodName != null) {
+                testRunner.setMethodName(testClassName, methodName);
+            } else {
+                testRunner.setClassName(testClassName);
+            }
+        }
+
+        final CollectingTestListener listener = new CollectingTestListener();
+        getDevice().runInstrumentationTests(testRunner, listener);
+
+        final TestRunResult result = listener.getCurrentRunResults();
+        if (result.isRunFailure()) {
+            throw new AssertionError("Failed to successfully run device tests for "
+                    + result.getName() + ": " + result.getRunFailureMessage());
+        }
+
+        if (result.hasFailedTests()) {
+            // build a meaningful error message
+            StringBuilder errorBuilder = new StringBuilder("on-device tests failed:\n");
+            for (Map.Entry<TestIdentifier, TestResult> resultEntry :
+                result.getTestResults().entrySet()) {
+                if (!resultEntry.getValue().getStatus().equals(TestStatus.PASSED)) {
+                    errorBuilder.append(resultEntry.getKey().toString());
+                    errorBuilder.append(":\n");
+                    errorBuilder.append(resultEntry.getValue().getStackTrace());
+                }
+            }
+            throw new AssertionError(errorBuilder.toString());
+        }
+    }
+
+    private static final Pattern UID_PATTERN =
+            Pattern.compile(".*userId=([0-9]+)$", Pattern.MULTILINE);
+
+    protected int getUid(String packageName) throws DeviceNotAvailableException {
+        final String output = runCommand("dumpsys package " + packageName);
+        final Matcher matcher = UID_PATTERN.matcher(output);
+        while (matcher.find()) {
+            final String match = matcher.group(1);
+            return Integer.parseInt(match);
+        }
+        throw new RuntimeException("Did not find regexp '" + UID_PATTERN + "' on adb output\n"
+                + output);
+    }
+
+    protected String runCommand(String command) throws DeviceNotAvailableException {
+        Log.d(TAG, "Command: '" + command + "'");
+        final String output = getDevice().executeShellCommand(command);
+        if (DEBUG) Log.v(TAG, "Output: " + output.trim());
+        return output;
+    }
+}
diff --git a/hostsidetests/net/src/com/android/cts/net/HostsideNetworkTests.java b/hostsidetests/net/src/com/android/cts/net/HostsideNetworkTests.java
deleted file mode 100644
index a7698f3..0000000
--- a/hostsidetests/net/src/com/android/cts/net/HostsideNetworkTests.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.net;
-
-import com.android.cts.tradefed.build.CtsBuildHelper;
-import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
-import com.android.ddmlib.testrunner.TestIdentifier;
-import com.android.ddmlib.testrunner.TestResult;
-import com.android.ddmlib.testrunner.TestResult.TestStatus;
-import com.android.ddmlib.testrunner.TestRunResult;
-import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.testtype.DeviceTestCase;
-import com.android.tradefed.testtype.IAbi;
-import com.android.tradefed.testtype.IAbiReceiver;
-import com.android.tradefed.testtype.IBuildReceiver;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.result.CollectingTestListener;
-
-import java.util.Map;
-
-public class HostsideNetworkTests extends DeviceTestCase implements IAbiReceiver, IBuildReceiver {
-    private static final String TEST_PKG = "com.android.cts.net.hostside";
-    private static final String TEST_APK = "CtsHostsideNetworkTestsApp.apk";
-
-    private IAbi mAbi;
-    private CtsBuildHelper mCtsBuild;
-
-    @Override
-    public void setAbi(IAbi abi) {
-        mAbi = abi;
-    }
-
-    @Override
-    public void setBuild(IBuildInfo buildInfo) {
-        mCtsBuild = CtsBuildHelper.createBuildHelper(buildInfo);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-
-        assertNotNull(mAbi);
-        assertNotNull(mCtsBuild);
-
-        getDevice().uninstallPackage(TEST_PKG);
-
-        assertNull(getDevice().installPackage(mCtsBuild.getTestApp(TEST_APK), false));
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-
-        getDevice().uninstallPackage(TEST_PKG);
-    }
-
-    public void testVpn() throws Exception {
-        runDeviceTests(TEST_PKG, ".VpnTest");
-    }
-
-    public void runDeviceTests(String packageName, String testClassName)
-           throws DeviceNotAvailableException {
-        RemoteAndroidTestRunner testRunner = new RemoteAndroidTestRunner(packageName,
-                "android.support.test.runner.AndroidJUnitRunner", getDevice().getIDevice());
-
-        final CollectingTestListener listener = new CollectingTestListener();
-        getDevice().runInstrumentationTests(testRunner, listener);
-
-        final TestRunResult result = listener.getCurrentRunResults();
-        if (result.isRunFailure()) {
-            throw new AssertionError("Failed to successfully run device tests for "
-                    + result.getName() + ": " + result.getRunFailureMessage());
-        }
-
-        if (result.hasFailedTests()) {
-            // build a meaningful error message
-            StringBuilder errorBuilder = new StringBuilder("on-device tests failed:\n");
-            for (Map.Entry<TestIdentifier, TestResult> resultEntry :
-                result.getTestResults().entrySet()) {
-                if (!resultEntry.getValue().getStatus().equals(TestStatus.PASSED)) {
-                    errorBuilder.append(resultEntry.getKey().toString());
-                    errorBuilder.append(":\n");
-                    errorBuilder.append(resultEntry.getValue().getStackTrace());
-                }
-            }
-            throw new AssertionError(errorBuilder.toString());
-        }
-    }
-}
diff --git a/hostsidetests/net/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java b/hostsidetests/net/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java
new file mode 100644
index 0000000..15a4e0a
--- /dev/null
+++ b/hostsidetests/net/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.net;
+
+import com.android.ddmlib.Log;
+import com.android.tradefed.device.DeviceNotAvailableException;
+
+public class HostsideRestrictBackgroundNetworkTests extends HostsideNetworkTestCase {
+
+    private static final String TEST_APP2_PKG = "com.android.cts.net.hostside.app2";
+    private static final String TEST_APP2_APK = "CtsHostsideNetworkTestsApp2.apk";
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        uninstallPackage(TEST_APP2_PKG, false);
+        installPackage(TEST_APP2_APK);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+
+        uninstallPackage(TEST_APP2_PKG, true);
+    }
+
+    public void testDataSaverMode_disabled() throws Exception {
+        runDeviceTests(TEST_PKG, TEST_PKG + ".DataSaverModeTest",
+                "testGetRestrictBackgroundStatus_disabled");
+    }
+
+    public void testDataSaverMode_whitelisted() throws Exception {
+        runDeviceTests(TEST_PKG, TEST_PKG + ".DataSaverModeTest",
+                "testGetRestrictBackgroundStatus_whitelisted");
+    }
+
+    public void testDataSaverMode_enabled() throws Exception {
+        runDeviceTests(TEST_PKG, TEST_PKG + ".DataSaverModeTest",
+                "testGetRestrictBackgroundStatus_enabled");
+    }
+
+    public void testDataSaverMode_blacklisted() throws Exception {
+        runDeviceTests(TEST_PKG, TEST_PKG + ".DataSaverModeTest",
+                "testGetRestrictBackgroundStatus_blacklisted");
+    }
+
+    public void testDataSaverMode_reinstall() throws Exception {
+        final int oldUid = getUid(TEST_PKG);
+        testDataSaverMode_whitelisted();
+
+        uninstallPackage(TEST_PKG, true);
+        assertPackageUninstalled(TEST_PKG);
+        assertRestrictBackgroundWhitelist(oldUid, false);
+
+        installPackage(TEST_APK);
+        final int newUid = getUid(TEST_PKG);
+        assertRestrictBackgroundWhitelist(oldUid, false);
+        assertRestrictBackgroundWhitelist(newUid, false);
+    }
+
+    public void testBatterySaverMode_disabled() throws Exception {
+        runDeviceTests(TEST_PKG, TEST_PKG + ".BatterySaverModeTest",
+                "testBackgroundNetworkAccess_disabled");
+    }
+
+    public void testBatterySaverMode_whitelisted() throws Exception {
+        runDeviceTests(TEST_PKG, TEST_PKG + ".BatterySaverModeTest",
+                "testBackgroundNetworkAccess_whitelisted");
+    }
+
+    public void testBatterySaverMode_enabled() throws Exception {
+        runDeviceTests(TEST_PKG, TEST_PKG + ".BatterySaverModeTest",
+                "testBackgroundNetworkAccess_enabled");
+    }
+
+    public void testBatterySaverMode_reinstall() throws Exception {
+        testBatterySaverMode_whitelisted();
+
+        uninstallPackage(TEST_PKG, true);
+        assertPackageUninstalled(TEST_PKG);
+        assertPowerSaveModeWhitelist(TEST_PKG, false);
+
+        installPackage(TEST_APK);
+        assertPowerSaveModeWhitelist(TEST_PKG, false);
+    }
+
+    public void testBatteryBatterySaverModeNonMeteredTest_disabled() throws Exception {
+        runDeviceTests(TEST_PKG, TEST_PKG + ".BatterySaverModeNonMeteredTest",
+                "testBackgroundNetworkAccess_disabled");
+    }
+
+    public void testBatteryBatterySaverModeNonMeteredTest_whitelisted() throws Exception {
+        runDeviceTests(TEST_PKG, TEST_PKG + ".BatterySaverModeNonMeteredTest",
+                "testBackgroundNetworkAccess_whitelisted");
+    }
+
+    public void testBatteryBatterySaverModeNonMeteredTest_enabled() throws Exception {
+        runDeviceTests(TEST_PKG, TEST_PKG + ".BatterySaverModeNonMeteredTest",
+                "testBackgroundNetworkAccess_enabled");
+    }
+
+    private void assertRestrictBackgroundWhitelist(int uid, boolean expected) throws Exception {
+        final int max_tries = 5;
+        boolean actual = false;
+        for (int i = 1; i <= max_tries; i++) {
+            final String output = runCommand("cmd netpolicy list restrict-background-whitelist ");
+            actual = output.contains(Integer.toString(uid));
+            if (expected == actual) {
+                return;
+            }
+            Log.v(TAG, "whitelist check for uid " + uid + " doesn't match yet (expected "
+                    + expected + ", got " + actual + "); sleeping 1s before polling again");
+            Thread.sleep(1000);
+        }
+        fail("whitelist check for uid " + uid + " failed: expected "
+                + expected + ", got " + actual);
+    }
+
+    private void assertPowerSaveModeWhitelist(String packageName, boolean expected)
+            throws Exception {
+        // TODO: currently the power-save mode is behaving like idle, but once it changes, we'll
+        // need to use netpolicy for whitelisting
+        assertDelayedCommand("dumpsys deviceidle whitelist =" + packageName,
+                Boolean.toString(expected));
+    }
+
+    /**
+     * Asserts the result of a command, wait and re-running it a couple times if necessary.
+     */
+    private void assertDelayedCommand(String command, String expectedResult)
+            throws InterruptedException, DeviceNotAvailableException {
+        final int maxTries = 5;
+        for (int i = 1; i <= maxTries; i++) {
+            final String result = runCommand(command).trim();
+            if (result.equals(expectedResult)) return;
+            Log.v(TAG, "Command '" + command + "' returned '" + result + " instead of '"
+                    + expectedResult + "' on attempt #; sleeping 1s before polling again");
+            Thread.sleep(1000);
+        }
+        fail("Command '" + command + "' did not return '" + expectedResult + "' after " + maxTries
+                + " attempts");
+    }
+}
diff --git a/hostsidetests/net/src/com/android/cts/net/HostsideVpnTests.java b/hostsidetests/net/src/com/android/cts/net/HostsideVpnTests.java
new file mode 100644
index 0000000..dc965c5
--- /dev/null
+++ b/hostsidetests/net/src/com/android/cts/net/HostsideVpnTests.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.net;
+
+public class HostsideVpnTests extends HostsideNetworkTestCase {
+
+    public void testVpn() throws Exception {
+        runDeviceTests(TEST_PKG, TEST_PKG + ".VpnTest");
+    }
+}
diff --git a/hostsidetests/numberblocking/Android.mk b/hostsidetests/numberblocking/Android.mk
new file mode 100644
index 0000000..bf2d045
--- /dev/null
+++ b/hostsidetests/numberblocking/Android.mk
@@ -0,0 +1,34 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_MODULE_TAGS := tests
+
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_MODULE := CtsHostsideNumberBlockingTestCases
+
+LOCAL_STATIC_JAVA_LIBRARIES := cts-migration-lib
+
+LOCAL_JAVA_LIBRARIES := cts-tradefed tradefed-prebuilt compatibility-host-util
+
+include $(BUILD_HOST_JAVA_LIBRARY)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/hostsidetests/numberblocking/AndroidTest.xml b/hostsidetests/numberblocking/AndroidTest.xml
new file mode 100644
index 0000000..4d06e9d
--- /dev/null
+++ b/hostsidetests/numberblocking/AndroidTest.xml
@@ -0,0 +1,23 @@
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS number blocking test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsHostsideNumberBlockingAppTest.apk" />
+    </target_preparer>
+    <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
+        <option name="jar" value="CtsHostsideNumberBlockingTestCases.jar" />
+    </test>
+</configuration>
diff --git a/hostsidetests/numberblocking/app/Android.mk b/hostsidetests/numberblocking/app/Android.mk
new file mode 100644
index 0000000..492a2ec
--- /dev/null
+++ b/hostsidetests/numberblocking/app/Android.mk
@@ -0,0 +1,39 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+# Don't include this package in any target
+LOCAL_MODULE_TAGS := tests
+# When built, explicitly put it in the data partition.
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_DEX_PREOPT := false
+
+LOCAL_PROGUARD_ENABLED := disabled
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
+
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_PACKAGE_NAME := CtsHostsideNumberBlockingAppTest
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_PACKAGE)
diff --git a/hostsidetests/numberblocking/app/AndroidManifest.xml b/hostsidetests/numberblocking/app/AndroidManifest.xml
new file mode 100755
index 0000000..9c2b3b1
--- /dev/null
+++ b/hostsidetests/numberblocking/app/AndroidManifest.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.cts.numberblocking.hostside">
+
+    <uses-permission android:name="android.permission.CALL_PHONE"/>
+    <uses-permission android:name="android.permission.READ_CALL_LOG"/>
+    <uses-permission android:name="android.permission.WRITE_CALL_LOG"/>
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+
+        <service android:name=".CallBlockingTest$DummyConnectionService"
+            android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE">
+            <intent-filter>
+                <action android:name="android.telecom.ConnectionService" />
+            </intent-filter>
+        </service>
+
+    </application>
+
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="com.android.cts.numberblocking.hostside"
+                     android:label="Number blocking CTS Tests"/>
+
+</manifest>
+
diff --git a/hostsidetests/numberblocking/app/src/com/android/cts/numberblocking/hostside/BaseNumberBlockingClientTest.java b/hostsidetests/numberblocking/app/src/com/android/cts/numberblocking/hostside/BaseNumberBlockingClientTest.java
new file mode 100644
index 0000000..30312da4
--- /dev/null
+++ b/hostsidetests/numberblocking/app/src/com/android/cts/numberblocking/hostside/BaseNumberBlockingClientTest.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.cts.numberblocking.hostside;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.support.test.InstrumentationRegistry;
+import android.telecom.TelecomManager;
+import android.test.InstrumentationTestCase;
+
+/**
+ * Base class for number blocking tests.
+ */
+public class BaseNumberBlockingClientTest extends InstrumentationTestCase {
+    protected TelecomManager mTelecomManager;
+    protected Context mContext;
+    protected String mPhoneAccountId;
+    protected String mBlockedPhoneNumber;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mContext = getInstrumentation().getContext();
+        mTelecomManager = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
+
+        Bundle arguments = InstrumentationRegistry.getArguments();
+        mBlockedPhoneNumber = arguments.getString("blocked_number");
+        assertNotNull(mBlockedPhoneNumber);
+        mPhoneAccountId = arguments.getString("phone_account_id");
+        assertNotNull(mPhoneAccountId);
+    }
+}
diff --git a/hostsidetests/numberblocking/app/src/com/android/cts/numberblocking/hostside/CallBlockingTest.java b/hostsidetests/numberblocking/app/src/com/android/cts/numberblocking/hostside/CallBlockingTest.java
new file mode 100644
index 0000000..674dab2
--- /dev/null
+++ b/hostsidetests/numberblocking/app/src/com/android/cts/numberblocking/hostside/CallBlockingTest.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.cts.numberblocking.hostside;
+
+import android.content.ComponentName;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Process;
+import android.provider.CallLog;
+import android.telecom.Connection;
+import android.telecom.ConnectionRequest;
+import android.telecom.ConnectionService;
+import android.telecom.DisconnectCause;
+import android.telecom.PhoneAccount;
+import android.telecom.PhoneAccountHandle;
+import android.telecom.TelecomManager;
+
+import java.util.Arrays;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Tests call blocking in a multi-user environment.
+ */
+public class CallBlockingTest extends BaseNumberBlockingClientTest {
+    private static final String QUERY_CALL_THROUGH_OUR_CONNECTION_SERVICE = CallLog.Calls.NUMBER
+            + " = ? AND " + CallLog.Calls.PHONE_ACCOUNT_COMPONENT_NAME + " = ?";
+
+    private static CountDownLatch callRejectionCountDownLatch;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        callRejectionCountDownLatch = new CountDownLatch(1);
+    }
+
+    public void testRegisterPhoneAccount() {
+        PhoneAccountHandle phoneAccountHandle = getPhoneAccountHandle();
+        final PhoneAccount phoneAccount = PhoneAccount.builder(
+                phoneAccountHandle, phoneAccountHandle.getId())
+                .setAddress(Uri.parse("tel:333-TEST"))
+                .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
+                .setShortDescription("a short description for the call provider")
+                .setSupportedUriSchemes(Arrays.asList(PhoneAccount.SCHEME_TEL))
+                .build();
+        mTelecomManager.registerPhoneAccount(phoneAccount);
+    }
+
+    public void testUnregisterPhoneAccount() {
+        mTelecomManager.unregisterPhoneAccount(getPhoneAccountHandle());
+        assertNull(mTelecomManager.getPhoneAccount(getPhoneAccountHandle()));
+    }
+
+    public void testIncomingCallFromBlockedNumberIsRejected() throws Exception {
+        // Make sure no lingering values from previous runs.
+        cleanupCall(false /* verifyNoCallLogsWritten */);
+
+        // Register the phone account.
+        // final PhoneAccountHandle phoneAccountHandle = registerPhoneAccount().getAccountHandle();
+        PhoneAccount phoneAccount = mTelecomManager.getPhoneAccount(getPhoneAccountHandle());
+        assertNotNull(phoneAccount);
+        try {
+            // Add a incoming call.
+            final Bundle bundle = new Bundle();
+            final Uri phoneUri = Uri.fromParts(PhoneAccount.SCHEME_TEL, mBlockedPhoneNumber, null);
+            bundle.putParcelable(TelecomManager.EXTRA_INCOMING_CALL_ADDRESS, phoneUri);
+            mTelecomManager.addNewIncomingCall(phoneAccount.getAccountHandle(), bundle);
+
+            // Make sure the call is rejected.
+            assertTrue(callRejectionCountDownLatch.await(10, TimeUnit.SECONDS));
+        } finally {
+            cleanupCall(true /* verifyNoCallLogsWritten */ );
+            unregisterPhoneAccount();
+        }
+    }
+
+    private void cleanupCall(boolean verifyNoCallLogsWritten) {
+        final String connectionServiceComponentName = new ComponentName(mContext,
+                DummyConnectionService.class).flattenToString();
+        int numRowDeleted = mContext.getContentResolver()
+                .delete(CallLog.Calls.CONTENT_URI, QUERY_CALL_THROUGH_OUR_CONNECTION_SERVICE,
+                        new String[]{mBlockedPhoneNumber, connectionServiceComponentName});
+        if (verifyNoCallLogsWritten) {
+            assertEquals(0, numRowDeleted);
+        }
+    }
+
+    private void unregisterPhoneAccount() {
+        mTelecomManager.unregisterPhoneAccount(getPhoneAccountHandle());
+        assertNull(mTelecomManager.getPhoneAccount(getPhoneAccountHandle()));
+    }
+
+    private PhoneAccountHandle getPhoneAccountHandle() {
+        return new PhoneAccountHandle(
+                new ComponentName(
+                        CallBlockingTest.class.getPackage().getName(),
+                        DummyConnectionService.class.getName()),
+                mPhoneAccountId,
+                Process.myUserHandle());
+    }
+
+    public static class DummyConnection extends Connection {
+        @Override
+        public void onReject() {
+            super.onReject();
+            setDisconnected(new DisconnectCause(DisconnectCause.REJECTED));
+            destroy();
+            callRejectionCountDownLatch.countDown();
+        }
+    }
+
+    public static class DummyConnectionService extends ConnectionService {
+        @Override
+        public Connection onCreateIncomingConnection(
+                PhoneAccountHandle connectionManagerAccount, ConnectionRequest request) {
+            final Connection connection = new DummyConnection();
+            connection.setVideoState(request.getVideoState());
+            final Uri address =
+                    request.getExtras().getParcelable(TelecomManager.EXTRA_INCOMING_CALL_ADDRESS);
+            connection.setAddress(address, TelecomManager.PRESENTATION_ALLOWED);
+            return connection;
+        }
+    }
+}
diff --git a/hostsidetests/numberblocking/app/src/com/android/cts/numberblocking/hostside/NumberBlockingAppTest.java b/hostsidetests/numberblocking/app/src/com/android/cts/numberblocking/hostside/NumberBlockingAppTest.java
new file mode 100644
index 0000000..39e70ec
--- /dev/null
+++ b/hostsidetests/numberblocking/app/src/com/android/cts/numberblocking/hostside/NumberBlockingAppTest.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.cts.numberblocking.hostside;
+
+import android.content.ContentValues;
+import android.provider.BlockedNumberContract;
+
+/**
+ * Tests number blocking features as a privileged app that can block numbers.
+ */
+public class NumberBlockingAppTest extends BaseNumberBlockingClientTest {
+    public void testCleanupBlockedNumberAsPrimaryUserSucceeds() throws Exception {
+        assertTrue(BlockedNumberContract.canCurrentUserBlockNumbers(mContext));
+
+        assertTrue(mContext.getContentResolver().delete(
+                BlockedNumberContract.BlockedNumbers.CONTENT_URI,
+                BlockedNumberContract.BlockedNumbers.COLUMN_ORIGINAL_NUMBER + "= ?",
+                new String[]{mBlockedPhoneNumber}) <= 1);
+    }
+
+    public void testBlockNumberAsPrimaryUserSucceeds() throws Exception {
+        assertTrue(BlockedNumberContract.canCurrentUserBlockNumbers(mContext));
+
+        verifyInsertBlockedNumberSucceeds();
+    }
+
+    public void testSecondaryUserCannotBlockNumbers() throws Exception {
+        assertFalse(BlockedNumberContract.canCurrentUserBlockNumbers(mContext));
+
+        try {
+            BlockedNumberContract.isBlocked(mContext, mBlockedPhoneNumber);
+            fail("Expected UnsupportedOperationException.");
+        } catch (UnsupportedOperationException expected) {
+        }
+    }
+
+    public void testUnblockNumberAsPrimaryUserSucceeds() throws Exception {
+        assertTrue(BlockedNumberContract.canCurrentUserBlockNumbers(mContext));
+
+        assertEquals(1, mContext.getContentResolver().delete(
+                BlockedNumberContract.BlockedNumbers.CONTENT_URI,
+                BlockedNumberContract.BlockedNumbers.COLUMN_ORIGINAL_NUMBER + "= ?",
+                new String[]{mBlockedPhoneNumber}));
+    }
+
+    private void verifyInsertBlockedNumberSucceeds() {
+        ContentValues cv = new ContentValues();
+        cv.put(BlockedNumberContract.BlockedNumbers.COLUMN_ORIGINAL_NUMBER, mBlockedPhoneNumber);
+        mContext.getContentResolver().insert(
+                BlockedNumberContract.BlockedNumbers.CONTENT_URI, cv);
+        assertTrue(BlockedNumberContract.isBlocked(mContext, mBlockedPhoneNumber));
+    }
+}
diff --git a/hostsidetests/numberblocking/src/com/android/cts/numberblocking/hostside/NumberBlockingTest.java b/hostsidetests/numberblocking/src/com/android/cts/numberblocking/hostside/NumberBlockingTest.java
new file mode 100644
index 0000000..eae6d86
--- /dev/null
+++ b/hostsidetests/numberblocking/src/com/android/cts/numberblocking/hostside/NumberBlockingTest.java
@@ -0,0 +1,217 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.cts.numberblocking.hostside;
+
+import com.android.cts.migration.MigrationHelper;
+import com.android.ddmlib.Log;
+import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.log.LogUtil;
+import com.android.tradefed.result.CollectingTestListener;
+import com.android.tradefed.testtype.DeviceTestCase;
+import com.android.tradefed.testtype.IBuildReceiver;
+
+import java.io.File;
+
+/**
+ * Multi-user tests for number blocking.
+ */
+// To run the tests in this file w/o running all the cts tests:
+// make cts
+// cts-tradefed
+// run cts -m CtsHostsideNumberBlockingTestCases
+public class NumberBlockingTest extends DeviceTestCase implements IBuildReceiver {
+    private static final String BLOCKED_NUMBER = "556";
+    private static final String PHONE_ACCOUNT_ID = "test_call_provider_id";
+    private static final String TEST_APK = "CtsHostsideNumberBlockingAppTest.apk";
+    private static final String NUMBER_BLOCKING_TESTS_PKG =
+            NumberBlockingTest.class.getPackage().getName();
+    private static final String CALL_BLOCKING_TEST_CLASS_NAME = "CallBlockingTest";
+    private static final String NUMBER_BLOCKING_APP_TEST_CLASS_NAME = "NumberBlockingAppTest";
+    private static final String TEST_APP_CONNECTION_SERVICE_NAME = "DummyConnectionService";
+    private static final String SECONDARY_USER_NAME = "NumberBlockingTest SecondaryUser";
+
+    private int mSecondaryUserId;
+    private int mPrimaryUserSerialNumber;
+    private int mSecondaryUserSerialNumber;
+
+    private IBuildInfo mCtsBuild;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        if (!getDevice().isMultiUserSupported()) {
+            return;
+        }
+
+        installTestAppForUser(getDevice().getPrimaryUserId());
+        createSecondaryUser();
+        installTestAppForUser(mSecondaryUserId);
+
+        mPrimaryUserSerialNumber = getUserSerialNumber(getDevice().getPrimaryUserId());
+        mSecondaryUserSerialNumber = getUserSerialNumber(mSecondaryUserId);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        if (getDevice().isMultiUserSupported()) {
+            getDevice().removeUser(mSecondaryUserId);
+        }
+
+        super.tearDown();
+    }
+
+    @Override
+    public void setBuild(IBuildInfo iBuildInfo) {
+        mCtsBuild = iBuildInfo;
+    }
+
+    public void testNumberBlocking() throws Exception {
+        if (!getDevice().isMultiUserSupported()) {
+            return;
+        }
+
+        try {
+            // First run tests for primary user.
+            // Cleanup state prior to running tests.
+            setTestAppAsDefaultSmsAppForUser(
+                    true /* setToSmsApp */, getDevice().getPrimaryUserId());
+            runTestAsPrimaryUser(NUMBER_BLOCKING_APP_TEST_CLASS_NAME,
+                    "testCleanupBlockedNumberAsPrimaryUserSucceeds");
+
+            // Block a number as a privileged app that can block numbers.
+            runTestAsPrimaryUser(
+                    NUMBER_BLOCKING_APP_TEST_CLASS_NAME, "testBlockNumberAsPrimaryUserSucceeds");
+            setTestAppAsDefaultSmsAppForUser(
+                    false /* setToSmsApp */, getDevice().getPrimaryUserId());
+
+            // Ensure incoming call from blocked number is rejected, and unregister the phone
+            // account.
+            runTestAsPrimaryUser(CALL_BLOCKING_TEST_CLASS_NAME, "testRegisterPhoneAccount");
+            enablePhoneAccountForUser(mPrimaryUserSerialNumber);
+            runTestAsPrimaryUser(CALL_BLOCKING_TEST_CLASS_NAME,
+                    "testIncomingCallFromBlockedNumberIsRejected");
+            runTestAsPrimaryUser(CALL_BLOCKING_TEST_CLASS_NAME, "testUnregisterPhoneAccount");
+
+            // Run tests as secondary user.
+            assertTrue(getDevice().startUser(mSecondaryUserId));
+
+            // Ensure that a privileged app cannot block numbers when the current user is a
+            // secondary user.
+            setTestAppAsDefaultSmsAppForUser(true /* setToSmsApp */, mSecondaryUserId);
+            runTestAsSecondaryUser(NUMBER_BLOCKING_APP_TEST_CLASS_NAME,
+                    "testSecondaryUserCannotBlockNumbers");
+            setTestAppAsDefaultSmsAppForUser(false /* setToSmsApp */, mSecondaryUserId);
+
+            // Calls should be blocked by Telecom for secondary users as well.
+            runTestAsSecondaryUser(CALL_BLOCKING_TEST_CLASS_NAME, "testRegisterPhoneAccount");
+            enablePhoneAccountForUser(mSecondaryUserSerialNumber);
+            runTestAsSecondaryUser(CALL_BLOCKING_TEST_CLASS_NAME,
+                    "testIncomingCallFromBlockedNumberIsRejected");
+        } finally {
+            // Cleanup state by unblocking the blocked number.
+            setTestAppAsDefaultSmsAppForUser(
+                    true /* setToSmsApp */, getDevice().getPrimaryUserId());
+            runTestAsPrimaryUser(
+                    NUMBER_BLOCKING_APP_TEST_CLASS_NAME, "testUnblockNumberAsPrimaryUserSucceeds");
+        }
+    }
+
+    private void createSecondaryUser() throws Exception {
+        mSecondaryUserId = getDevice().createUser(SECONDARY_USER_NAME);
+        getDevice().waitForDeviceAvailable();
+    }
+
+    private void installTestAppForUser(int userId) throws Exception {
+        LogUtil.CLog.logAndDisplay(Log.LogLevel.INFO, "Installing test app for user: " + userId);
+        File testAppFile = MigrationHelper.getTestFile(mCtsBuild, TEST_APK);
+        String installResult = getDevice().installPackageForUser(
+                testAppFile, true /*reinstall*/, userId);
+        assertNull(String.format(
+                "failed to install number blocking test app. Reason: %s", installResult),
+                installResult);
+    }
+
+    private void runTestAsPrimaryUser(String className, String methodName) throws Exception {
+        runTestAsUser(className, methodName, getDevice().getPrimaryUserId());
+    }
+
+    private void runTestAsSecondaryUser(String className, String methodName) throws Exception {
+        runTestAsUser(className, methodName, mSecondaryUserId);
+    }
+
+    private void runTestAsUser(String className, String methodName, int userId) throws Exception {
+        LogUtil.CLog.logAndDisplay(Log.LogLevel.INFO, "Running %s.%s for user: %d",
+                className, methodName, userId);
+        RemoteAndroidTestRunner testRunner = new RemoteAndroidTestRunner(
+                NUMBER_BLOCKING_TESTS_PKG,
+                "android.support.test.runner.AndroidJUnitRunner",
+                getDevice().getIDevice());
+        testRunner.addInstrumentationArg("blocked_number", BLOCKED_NUMBER);
+        testRunner.addInstrumentationArg("phone_account_id", PHONE_ACCOUNT_ID);
+        testRunner.setMethodName(NUMBER_BLOCKING_TESTS_PKG + "." + className, methodName);
+        CollectingTestListener listener = new CollectingTestListener();
+        getDevice().runInstrumentationTestsAsUser(testRunner, userId, listener);
+        assertEquals(1, listener.getNumTotalTests());
+        assertFalse(listener.getCurrentRunResults().getTestResults().keySet().toString(),
+                listener.getCurrentRunResults().hasFailedTests());
+    }
+
+    private void enablePhoneAccountForUser(int userSerialNumber) throws Exception {
+        String command = String.format(
+                "telecom set-phone-account-enabled %s\\/%s.%s\\$%s %s %d",
+                NUMBER_BLOCKING_TESTS_PKG,
+                NUMBER_BLOCKING_TESTS_PKG,
+                CALL_BLOCKING_TEST_CLASS_NAME,
+                TEST_APP_CONNECTION_SERVICE_NAME,
+                PHONE_ACCOUNT_ID,
+                userSerialNumber);
+        String commandResponse = getDevice().executeShellCommand(command);
+        assertTrue(commandResponse, commandResponse.contains("Success"));
+    }
+
+    private void setTestAppAsDefaultSmsAppForUser(boolean setToSmsApp, int userId)
+            throws Exception {
+        String command = String.format("appops set --user %d %s WRITE_SMS %s", userId,
+                NUMBER_BLOCKING_TESTS_PKG,
+                setToSmsApp ? "allow" : "default");
+        assertEquals("", getDevice().executeShellCommand(command));
+    }
+
+    // TODO: Replace this with API in ITestDevice once it is available.
+    private int getUserSerialNumber(int userId) throws DeviceNotAvailableException {
+        // dumpsys user return lines like "UserInfo{0:Owner:13} serialNo=0"
+        String commandOutput = getDevice().executeShellCommand("dumpsys user");
+        String[] tokens = commandOutput.split("\\n");
+        for (String token : tokens) {
+            token = token.trim();
+            if (token.contains("UserInfo{" + userId + ":")) {
+                String[] split = token.split("serialNo=");
+                assertTrue(split.length == 2);
+                int serialNumber = Integer.parseInt(split[1]);
+                LogUtil.CLog.logAndDisplay(
+                        Log.LogLevel.INFO,
+                        String.format("Serial number of user %d : %d", userId, serialNumber));
+                return serialNumber;
+            }
+        }
+        fail("Couldn't find user " + userId);
+        return -1;
+    }
+}
diff --git a/hostsidetests/os/Android.mk b/hostsidetests/os/Android.mk
index 6962e0c..3cc1fad 100644
--- a/hostsidetests/os/Android.mk
+++ b/hostsidetests/os/Android.mk
@@ -27,7 +27,10 @@
 
 LOCAL_CTS_TEST_PACKAGE := android.host.os
 
-LOCAL_CTS_MODULE_CONFIG := $(LOCAL_PATH)/$(CTS_MODULE_TEST_CONFIG)
+LOCAL_CTS_MODULE_CONFIG := $(LOCAL_PATH)/Old$(CTS_MODULE_TEST_CONFIG)
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
 
 include $(BUILD_CTS_HOST_JAVA_LIBRARY)
 
diff --git a/hostsidetests/os/AndroidTest.xml b/hostsidetests/os/AndroidTest.xml
index 6694c30..ff6e6b0 100644
--- a/hostsidetests/os/AndroidTest.xml
+++ b/hostsidetests/os/AndroidTest.xml
@@ -13,7 +13,12 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<configuration description="CTS package preparer for install/uninstall of the apk used as a test operation target">
-    <include name="common-config" />
-    <option name="cts-apk-installer:test-file-name" value="CtsDeviceOsTestApp.apk" />
+<configuration description="Config for the CTS OS host test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsDeviceOsTestApp.apk" />
+    </target_preparer>
+    <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
+        <option name="jar" value="CtsOsHostTestCases.jar" />
+    </test>
 </configuration>
diff --git a/hostsidetests/os/OldAndroidTest.xml b/hostsidetests/os/OldAndroidTest.xml
new file mode 100644
index 0000000..6694c30
--- /dev/null
+++ b/hostsidetests/os/OldAndroidTest.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="CTS package preparer for install/uninstall of the apk used as a test operation target">
+    <include name="common-config" />
+    <option name="cts-apk-installer:test-file-name" value="CtsDeviceOsTestApp.apk" />
+</configuration>
diff --git a/hostsidetests/os/app/Android.mk b/hostsidetests/os/app/Android.mk
index 46861d69..86c109e 100644
--- a/hostsidetests/os/app/Android.mk
+++ b/hostsidetests/os/app/Android.mk
@@ -23,6 +23,9 @@
 
 LOCAL_SDK_VERSION := current
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_PACKAGE_NAME := CtsDeviceOsTestApp
 
 include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/os/app/AndroidManifest.xml b/hostsidetests/os/app/AndroidManifest.xml
index 103cf63..4c4338b 100755
--- a/hostsidetests/os/app/AndroidManifest.xml
+++ b/hostsidetests/os/app/AndroidManifest.xml
@@ -16,7 +16,7 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.app.os.test">
+    package="android.os.app">
 
     <application>
         <activity android:name=".TestNonExported"
diff --git a/hostsidetests/os/app/src/android/os/app/TestNonExported.java b/hostsidetests/os/app/src/android/os/app/TestNonExported.java
new file mode 100644
index 0000000..11c41c9
--- /dev/null
+++ b/hostsidetests/os/app/src/android/os/app/TestNonExported.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.os.app;
+
+import android.app.Activity;
+
+/**
+ * Should never be launched: intentionally not exported
+ */
+public class TestNonExported extends Activity {
+}
diff --git a/hostsidetests/os/app/src/com/android/cts/app/os/test/TestNonExported.java b/hostsidetests/os/app/src/com/android/cts/app/os/test/TestNonExported.java
deleted file mode 100644
index c865c89..0000000
--- a/hostsidetests/os/app/src/com/android/cts/app/os/test/TestNonExported.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.app.os.test;
-
-import android.app.Activity;
-
-/**
- * Should never be launched: intentionally not exported
- */
-public class TestNonExported extends Activity {
-}
diff --git a/hostsidetests/os/src/android/os/cts/OsHostTests.java b/hostsidetests/os/src/android/os/cts/OsHostTests.java
new file mode 100644
index 0000000..73e36c5
--- /dev/null
+++ b/hostsidetests/os/src/android/os/cts/OsHostTests.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.os.cts;
+
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.device.CollectingOutputReceiver;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceTestCase;
+import com.android.tradefed.testtype.IBuildReceiver;
+
+public class OsHostTests extends DeviceTestCase implements IBuildReceiver {
+    private static final String TEST_APP_PACKAGE = "android.os.app";
+    private static final String TEST_NON_EXPORTED_ACTIVITY_CLASS = "TestNonExported";
+
+    private static final String START_NON_EXPORTED_ACTIVITY_COMMAND = String.format(
+            "am start -n %s/%s.%s",
+            TEST_APP_PACKAGE, TEST_APP_PACKAGE, TEST_NON_EXPORTED_ACTIVITY_CLASS);
+
+    /**
+     * A reference to the device under test.
+     */
+    private ITestDevice mDevice;
+
+    @Override
+    public void setBuild(IBuildInfo buildInfo) {
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        // Get the device, this gives a handle to run commands and install APKs.
+        mDevice = getDevice();
+    }
+
+    /**
+     * Test whether non-exported activities are properly not launchable.
+     *
+     * @throws Exception
+     */
+    public void testNonExportedActivities() throws Exception {
+        // Attempt to launch the non-exported activity in the test app
+        CollectingOutputReceiver outputReceiver = new CollectingOutputReceiver();
+        mDevice.executeShellCommand(START_NON_EXPORTED_ACTIVITY_COMMAND, outputReceiver);
+        final String output = outputReceiver.getOutput();
+
+        assertTrue(output.contains("Permission Denial") && output.contains(" not exported"));
+    }
+}
diff --git a/hostsidetests/os/src/com/android/cts/app/os/OsHostTests.java b/hostsidetests/os/src/com/android/cts/app/os/OsHostTests.java
deleted file mode 100644
index d01a521..0000000
--- a/hostsidetests/os/src/com/android/cts/app/os/OsHostTests.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.app.os;
-
-import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.device.CollectingOutputReceiver;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.testtype.DeviceTestCase;
-import com.android.tradefed.testtype.IBuildReceiver;
-
-public class OsHostTests extends DeviceTestCase implements IBuildReceiver {
-    private static final String TEST_APP_PACKAGE = "com.android.cts.app.os.test";
-    private static final String TEST_NON_EXPORTED_ACTIVITY_CLASS = "TestNonExported";
-
-    private static final String START_NON_EXPORTED_ACTIVITY_COMMAND = String.format(
-            "am start -n %s/%s.%s",
-            TEST_APP_PACKAGE, TEST_APP_PACKAGE, TEST_NON_EXPORTED_ACTIVITY_CLASS);
-
-    /**
-     * A reference to the device under test.
-     */
-    private ITestDevice mDevice;
-
-    @Override
-    public void setBuild(IBuildInfo buildInfo) {
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-
-        // Get the device, this gives a handle to run commands and install APKs.
-        mDevice = getDevice();
-    }
-
-    /**
-     * Test whether non-exported activities are properly not launchable.
-     *
-     * @throws Exception
-     */
-    public void testNonExportedActivities() throws Exception {
-        // Attempt to launch the non-exported activity in the test app
-        CollectingOutputReceiver outputReceiver = new CollectingOutputReceiver();
-        mDevice.executeShellCommand(START_NON_EXPORTED_ACTIVITY_COMMAND, outputReceiver);
-        final String output = outputReceiver.getOutput();
-
-        assertTrue(output.contains("Permission Denial") && output.contains(" not exported"));
-    }
-}
diff --git a/hostsidetests/sample/Android.mk b/hostsidetests/sample/Android.mk
index e8cbdda..8d8a076 100644
--- a/hostsidetests/sample/Android.mk
+++ b/hostsidetests/sample/Android.mk
@@ -18,15 +18,15 @@
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
-LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TAGS := tests
 
-# Must match the package name in CtsTestCaseList.mk
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_MODULE := CtsSampleHostTestCases
 
-LOCAL_JAVA_LIBRARIES := cts-tradefed tradefed-prebuilt
+LOCAL_JAVA_LIBRARIES := cts-tradefed tradefed-prebuilt compatibility-host-util
 
-LOCAL_CTS_TEST_PACKAGE := android.host.sample
-
-include $(BUILD_CTS_HOST_JAVA_LIBRARY)
+include $(BUILD_HOST_JAVA_LIBRARY)
 
 include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/hostsidetests/sample/AndroidTest.xml b/hostsidetests/sample/AndroidTest.xml
new file mode 100644
index 0000000..5f5d23d
--- /dev/null
+++ b/hostsidetests/sample/AndroidTest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS Sample host test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsSampleDeviceApp.apk" />
+    </target_preparer>
+    <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
+        <option name="jar" value="CtsSampleHostTestCases.jar" />
+    </test>
+</configuration>
diff --git a/hostsidetests/sample/app/Android.mk b/hostsidetests/sample/app/Android.mk
index 4af45b9..7e7cd91 100644
--- a/hostsidetests/sample/app/Android.mk
+++ b/hostsidetests/sample/app/Android.mk
@@ -16,16 +16,22 @@
 
 include $(CLEAR_VARS)
 
-# Don't include this package in any target.
-LOCAL_MODULE_TAGS := optional
-
+# Don't include this package in any target
+LOCAL_MODULE_TAGS := tests
 # When built, explicitly put it in the data partition.
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
 
+LOCAL_DEX_PREOPT := false
+
+LOCAL_PROGUARD_ENABLED := disabled
+
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_PACKAGE_NAME := CtsSampleDeviceApp
 
 LOCAL_SDK_VERSION := current
 
-include $(BUILD_CTS_PACKAGE)
+include $(BUILD_PACKAGE)
diff --git a/hostsidetests/sample/app/AndroidManifest.xml b/hostsidetests/sample/app/AndroidManifest.xml
index c087435..dfacf25 100755
--- a/hostsidetests/sample/app/AndroidManifest.xml
+++ b/hostsidetests/sample/app/AndroidManifest.xml
@@ -18,7 +18,6 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="android.sample.app">
 
-    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <application>
         <activity android:name=".SampleDeviceActivity" >
             <intent-filter>
diff --git a/hostsidetests/sample/src/android/sample/cts/SampleHostResultTest.java b/hostsidetests/sample/src/android/sample/cts/SampleHostResultTest.java
index bed4c05..808899a 100644
--- a/hostsidetests/sample/src/android/sample/cts/SampleHostResultTest.java
+++ b/hostsidetests/sample/src/android/sample/cts/SampleHostResultTest.java
@@ -16,15 +16,13 @@
 
 package android.sample.cts;
 
-import com.android.cts.tradefed.build.CtsBuildHelper;
-import com.android.cts.tradefed.util.HostReportLog;
-import com.android.cts.util.MeasureRun;
-import com.android.cts.util.MeasureTime;
-import com.android.cts.util.ResultType;
-import com.android.cts.util.ResultUnit;
-import com.android.cts.util.ReportLog;
-import com.android.cts.util.Stat;
-import com.android.ddmlib.IDevice;
+import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
+import com.android.compatibility.common.util.MeasureRun;
+import com.android.compatibility.common.util.MeasureTime;
+import com.android.compatibility.common.util.MetricsReportLog;
+import com.android.compatibility.common.util.ResultType;
+import com.android.compatibility.common.util.ResultUnit;
+import com.android.compatibility.common.util.Stat;
 import com.android.tradefed.build.IBuildInfo;
 import com.android.tradefed.device.ITestDevice;
 import com.android.tradefed.testtype.DeviceTestCase;
@@ -37,7 +35,6 @@
 import com.android.tradefed.util.RunUtil;
 
 import java.io.File;
-import java.lang.Exception;
 
 /**
  * Test to measure the transfer time of a file from the host to the device.
@@ -52,16 +49,21 @@
     private static final int REPEAT = 5;
 
     /**
-     * The name of the plan to transfer.
-     *
-     * In this case we will transfer the CTS.xml file.
+     * The device-side location to write the file to.
      */
-    private static final String PLAN_NAME = "CTS";
+    private static final String FILE_PATH = "/data/local/tmp/%s";
 
     /**
-     * A reference to the build.
+     * The name of the file to transfer.
+     *
+     * In this case we will transfer this test's module config.
      */
-    private CtsBuildHelper mBuild;
+    private static final String FILE_NAME = "CtsSampleHostTestCases.config";
+
+    /**
+     * A helper to access resources in the build.
+     */
+    private CompatibilityBuildHelper mBuildHelper;
 
     /**
      * A reference to the device under test.
@@ -81,7 +83,7 @@
     @Override
     public void setBuild(IBuildInfo buildInfo) {
         // Get the build, this is used to access the APK.
-        mBuild = CtsBuildHelper.createBuildHelper(buildInfo);
+        mBuildHelper = new CompatibilityBuildHelper(buildInfo);
     }
 
     @Override
@@ -100,13 +102,10 @@
      */
     public void testTransferTime() throws Exception {
         final ITestDevice device = mDevice;
-        // Get the external storage location and ensure its not null.
-        final String externalStorePath = mDevice.getMountPoint(IDevice.MNT_EXTERNAL_STORAGE);
-        assertNotNull("External storage location no found", externalStorePath);
         // Create the device side path where the file will be transfered.
-        final String devicePath = String.format("%s/%s", externalStorePath, "tmp_testPushPull.txt");
-        // Get the file from the build.
-        final File testFile = mBuild.getTestPlanFile(PLAN_NAME);
+        final String devicePath = String.format(FILE_PATH, "tmp_testPushPull.txt");
+        // Get this test's module config file from the build.
+        final File testFile = new File(mBuildHelper.getTestsDir(), FILE_NAME);
         double[] result = MeasureTime.measure(REPEAT, new MeasureRun() {
             @Override
             public void prepare(int i) throws Exception {
@@ -133,15 +132,18 @@
         // Compute the stats.
         Stat.StatResult stat = Stat.getStat(result);
         // Get the report for this test and add the results to record.
-        HostReportLog report = new HostReportLog(mDevice.getSerialNumber(), mAbi.getName(),
-                ReportLog.getClassMethodNames());
-        report.printArray("Times", result, ResultType.LOWER_BETTER, ResultUnit.MS);
-        report.printValue("Min", stat.mMin, ResultType.LOWER_BETTER, ResultUnit.MS);
-        report.printValue("Max", stat.mMax, ResultType.LOWER_BETTER, ResultUnit.MS);
+        String reportLogName = "SampleHostTestMetrics";
+        String streamName = "test_transfer_time_metrics";
+        MetricsReportLog report = new MetricsReportLog(mDevice.getSerialNumber(), mAbi.getName(),
+                String.format("%s#testTransferTime", getClass().getCanonicalName()),
+                reportLogName, streamName);
+        report.addValues("times", result, ResultType.LOWER_BETTER, ResultUnit.MS);
+        report.addValue("min", stat.mMin, ResultType.LOWER_BETTER, ResultUnit.MS);
+        report.addValue("max", stat.mMax, ResultType.LOWER_BETTER, ResultUnit.MS);
         // Every report must have a summary,
-        report.printSummary("Average", stat.mAverage, ResultType.LOWER_BETTER, ResultUnit.MS);
+        report.setSummary("average", stat.mAverage, ResultType.LOWER_BETTER, ResultUnit.MS);
         // Send the report to Tradefed.
-        report.deliverReportToHost();
+        report.submit();
     }
 
     /**
diff --git a/hostsidetests/sample/src/android/sample/cts/SampleHostTest.java b/hostsidetests/sample/src/android/sample/cts/SampleHostTest.java
index ab7e0b0..f276712 100644
--- a/hostsidetests/sample/src/android/sample/cts/SampleHostTest.java
+++ b/hostsidetests/sample/src/android/sample/cts/SampleHostTest.java
@@ -16,27 +16,19 @@
 
 package android.sample.cts;
 
-import com.android.cts.tradefed.build.CtsBuildHelper;
-import com.android.cts.util.AbiUtils;
-import com.android.tradefed.build.IBuildInfo;
 import com.android.tradefed.device.ITestDevice;
 import com.android.tradefed.testtype.DeviceTestCase;
-import com.android.tradefed.testtype.IAbi;
-import com.android.tradefed.testtype.IAbiReceiver;
-import com.android.tradefed.testtype.IBuildReceiver;
 
-import java.io.File;
-import java.lang.String;
 import java.util.Scanner;
 
 /**
  * Test to check the APK logs to Logcat.
  *
  * When this test builds, it also builds {@link android.sample.app.SampleDeviceActivity} into an APK
- * which it then installs at runtime and starts. The activity simply prints a message to Logcat and
- * then gets uninstalled.
+ * which it then installed at runtime and started. The activity simply prints a message to Logcat
+ * and then gets uninstalled.
  */
-public class SampleHostTest extends DeviceTestCase implements IAbiReceiver, IBuildReceiver {
+public class SampleHostTest extends DeviceTestCase {
 
     /**
      * The package name of the APK.
@@ -44,11 +36,6 @@
     private static final String PACKAGE = "android.sample.app";
 
     /**
-     * The file name of the APK.
-     */
-    private static final String APK = "CtsSampleDeviceApp.apk";
-
-    /**
      * The class name of the main activity in the APK.
      */
     private static final String CLASS = "SampleDeviceActivity";
@@ -65,65 +52,18 @@
     private static final String TEST_STRING = "SampleTestString";
 
     /**
-     * The ABI to use.
-     */
-    private IAbi mAbi;
-
-    /**
-     * A reference to the build.
-     */
-    private CtsBuildHelper mBuild;
-
-    /**
-     * A reference to the device under test.
-     */
-    private ITestDevice mDevice;
-
-    @Override
-    public void setAbi(IAbi abi) {
-        mAbi = abi;
-    }
-
-    @Override
-    public void setBuild(IBuildInfo buildInfo) {
-        // Get the build, this is used to access the APK.
-        mBuild = CtsBuildHelper.createBuildHelper(buildInfo);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        // Get the device, this gives a handle to run commands and install APKs.
-        mDevice = getDevice();
-        // Remove any previously installed versions of this APK.
-        mDevice.uninstallPackage(PACKAGE);
-        // Get the APK from the build.
-        File app = mBuild.getTestApp(APK);
-        // Get the ABI flag.
-        String[] options = {AbiUtils.createAbiFlag(mAbi.getName())};
-        // Install the APK on the device.
-        mDevice.installPackage(app, false, options);
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        // Remove the package once complete.
-        mDevice.uninstallPackage(PACKAGE);
-        super.tearDown();
-    }
-
-    /**
      * Tests the string was successfully logged to Logcat from the activity.
      *
      * @throws Exception
      */
     public void testLogcat() throws Exception {
+        ITestDevice device = getDevice();
         // Clear logcat.
-        mDevice.executeAdbCommand("logcat", "-c");
+        device.executeAdbCommand("logcat", "-c");
         // Start the APK and wait for it to complete.
-        mDevice.executeShellCommand(START_COMMAND);
+        device.executeShellCommand(START_COMMAND);
         // Dump logcat.
-        String logs = mDevice.executeAdbCommand("logcat", "-v", "brief", "-d", CLASS + ":I", "*:S");
+        String logs = device.executeAdbCommand("logcat", "-v", "brief", "-d", CLASS + ":I", "*:S");
         // Search for string.
         String testString = "";
         Scanner in = new Scanner(logs);
diff --git a/hostsidetests/security/Android.mk b/hostsidetests/security/Android.mk
index d9fbc65..34e0e8a 100644
--- a/hostsidetests/security/Android.mk
+++ b/hostsidetests/security/Android.mk
@@ -20,6 +20,9 @@
 
 LOCAL_MODULE_TAGS := optional
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 # Must match the package name in CtsTestCaseList.mk
 LOCAL_MODULE := CtsSecurityHostTestCases
 
@@ -27,17 +30,28 @@
 
 LOCAL_JAVA_LIBRARIES := cts-tradefed tradefed-prebuilt
 
+LOCAL_STATIC_JAVA_LIBRARIES := cts-migration-lib
+
 LOCAL_CTS_TEST_PACKAGE := android.host.security
 
 selinux_general_seapp_contexts := $(call intermediates-dir-for,ETC,general_seapp_contexts)/general_seapp_contexts
 
-selinux_general_file_contexts := $(call intermediates-dir-for,ETC,general_file_contexts)/general_file_contexts
+selinux_general_seapp_neverallows := $(call intermediates-dir-for,ETC,general_seapp_neverallows)/general_seapp_neverallows
+
+selinux_general_file_contexts := $(call intermediates-dir-for,ETC,general_file_contexts.bin)/general_file_contexts.bin
 
 selinux_general_property_contexts := $(call intermediates-dir-for,ETC,general_property_contexts)/general_property_contexts
 
 selinux_general_service_contexts := $(call intermediates-dir-for,ETC,general_service_contexts)/general_service_contexts
 
-LOCAL_JAVA_RESOURCE_FILES := $(HOST_OUT_EXECUTABLES)/sepolicy-analyze $(HOST_OUT_EXECUTABLES)/checkseapp $(HOST_OUT_EXECUTABLES)/checkfc $(selinux_general_seapp_contexts) $(selinux_general_file_contexts) $(selinux_general_property_contexts) $(selinux_general_service_contexts)
+LOCAL_JAVA_RESOURCE_FILES := \
+    $(HOST_OUT_EXECUTABLES)/checkseapp \
+    $(HOST_OUT_EXECUTABLES)/checkfc \
+    $(selinux_general_seapp_contexts) \
+    $(selinux_general_seapp_neverallows) \
+    $(selinux_general_file_contexts) \
+    $(selinux_general_property_contexts) \
+    $(selinux_general_service_contexts)
 
 selinux_general_policy := $(call intermediates-dir-for,ETC,general_sepolicy.conf)/general_sepolicy.conf
 
@@ -45,6 +59,15 @@
 
 selinux_neverallow_gen_data := cts/tools/selinux/SELinuxNeverallowTestFrame.py
 
+old_cts_sepolicy-analyze := $(CTS_TESTCASES_OUT)/sepolicy-analyze
+
+LOCAL_ADDITIONAL_DEPENDENCIES := $(COMPATIBILITY_TESTCASES_OUT_cts)/sepolicy-analyze \
+    $(old_cts_sepolicy-analyze)
+
+$(old_cts_sepolicy-analyze) : $(HOST_OUT_EXECUTABLES)/sepolicy-analyze
+	mkdir -p $(dir $@)
+	$(copy-file-to-target)
+
 LOCAL_GENERATED_SOURCES := $(call local-generated-sources-dir)/android/cts/security/SELinuxNeverallowRulesTest.java
 
 $(LOCAL_GENERATED_SOURCES) : PRIVATE_SELINUX_GENERAL_POLICY := $(selinux_general_policy)
diff --git a/hostsidetests/security/AndroidTest.xml b/hostsidetests/security/AndroidTest.xml
new file mode 100644
index 0000000..0056e81
--- /dev/null
+++ b/hostsidetests/security/AndroidTest.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for the CTS Security host tests">
+    <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
+        <option name="jar" value="CtsSecurityHostTestCases.jar" />
+        <option name="runtime-hint" value="32s" />
+    </test>
+</configuration>
diff --git a/hostsidetests/security/src/android/cts/security/SELinuxHostTest.java b/hostsidetests/security/src/android/cts/security/SELinuxHostTest.java
deleted file mode 100644
index abb1ac4..0000000
--- a/hostsidetests/security/src/android/cts/security/SELinuxHostTest.java
+++ /dev/null
@@ -1,764 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.cts.security;
-
-import com.android.cts.tradefed.build.CtsBuildHelper;
-import com.android.ddmlib.Log;
-import com.android.ddmlib.Log.LogLevel;
-import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.device.CollectingOutputReceiver;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.testtype.DeviceTestCase;
-import com.android.tradefed.testtype.IBuildReceiver;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileReader;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.lang.String;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import java.util.Scanner;
-import java.util.Set;
-
-/**
- * Host-side SELinux tests.
- *
- * These tests analyze the policy file in use on the subject device directly or
- * run as the shell user to evaluate aspects of the state of SELinux on the test
- * device which otherwise would not be available to a normal apk.
- */
-public class SELinuxHostTest extends DeviceTestCase {
-
-    private File sepolicyAnalyze;
-    private File checkSeapp;
-    private File checkFc;
-    private File aospSeappFile;
-    private File aospFcFile;
-    private File aospPcFile;
-    private File aospSvcFile;
-    private File devicePolicyFile;
-    private File deviceSeappFile;
-    private File deviceFcFile;
-    private File devicePcFile;
-    private File deviceSvcFile;
-
-    /**
-     * A reference to the device under test.
-     */
-    private ITestDevice mDevice;
-
-    private File copyResourceToTempFile(String resName) throws IOException {
-        InputStream is = this.getClass().getResourceAsStream(resName);
-        File tempFile = File.createTempFile("SELinuxHostTest", ".tmp");
-        FileOutputStream os = new FileOutputStream(tempFile);
-        int rByte = 0;
-        while ((rByte = is.read()) != -1) {
-            os.write(rByte);
-        }
-        os.flush();
-        os.close();
-        tempFile.deleteOnExit();
-        return tempFile;
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mDevice = getDevice();
-
-        /* retrieve the sepolicy-analyze executable from jar */
-        sepolicyAnalyze = copyResourceToTempFile("/sepolicy-analyze");
-        sepolicyAnalyze.setExecutable(true);
-
-        /* retrieve the checkseapp executable from jar */
-        checkSeapp = copyResourceToTempFile("/checkseapp");
-        checkSeapp.setExecutable(true);
-
-        /* retrieve the checkfc executable from jar */
-        checkFc = copyResourceToTempFile("/checkfc");
-        checkFc.setExecutable(true);
-
-        /* obtain sepolicy file from running device */
-        devicePolicyFile = File.createTempFile("sepolicy", ".tmp");
-        devicePolicyFile.deleteOnExit();
-        mDevice.pullFile("/sys/fs/selinux/policy", devicePolicyFile);
-
-        /* obtain seapp_contexts file from running device */
-        deviceSeappFile = File.createTempFile("seapp_contexts", ".tmp");
-        deviceSeappFile.deleteOnExit();
-        mDevice.pullFile("/seapp_contexts", deviceSeappFile);
-
-        /* obtain file_contexts file from running device */
-        deviceFcFile = File.createTempFile("file_contexts", ".tmp");
-        deviceFcFile.deleteOnExit();
-        mDevice.pullFile("/file_contexts", deviceFcFile);
-
-        /* obtain property_contexts file from running device */
-        devicePcFile = File.createTempFile("property_contexts", ".tmp");
-        devicePcFile.deleteOnExit();
-        mDevice.pullFile("/property_contexts", devicePcFile);
-
-        /* obtain service_contexts file from running device */
-        deviceSvcFile = File.createTempFile("service_contexts", ".tmp");
-        deviceSvcFile.deleteOnExit();
-        mDevice.pullFile("/service_contexts", deviceSvcFile);
-
-        /* retrieve the AOSP *_contexts files from jar */
-        aospSeappFile = copyResourceToTempFile("/general_seapp_contexts");
-        aospFcFile = copyResourceToTempFile("/general_file_contexts");
-        aospPcFile = copyResourceToTempFile("/general_property_contexts");
-        aospSvcFile = copyResourceToTempFile("/general_service_contexts");
-    }
-
-    /**
-     * Tests that all domains in the running policy file are in enforcing mode
-     *
-     * @throws Exception
-     */
-    public void testAllEnforcing() throws Exception {
-
-        /* run sepolicy-analyze permissive check on policy file */
-        ProcessBuilder pb = new ProcessBuilder(sepolicyAnalyze.getAbsolutePath(),
-                devicePolicyFile.getAbsolutePath(), "permissive");
-        pb.redirectOutput(ProcessBuilder.Redirect.PIPE);
-        pb.redirectErrorStream(true);
-        Process p = pb.start();
-        p.waitFor();
-        BufferedReader result = new BufferedReader(new InputStreamReader(p.getInputStream()));
-        String line;
-        StringBuilder errorString = new StringBuilder();
-        while ((line = result.readLine()) != null) {
-            errorString.append(line);
-            errorString.append("\n");
-        }
-        assertTrue("The following SELinux domains were found to be in permissive mode:\n"
-                   + errorString, errorString.length() == 0);
-    }
-
-    /**
-     * Asserts that specified type is not associated with the specified
-     * attribute.
-     *
-     * @param attribute
-     *  The attribute name.
-     * @param type
-     *  The type name.
-     */
-    private void assertNotInAttribute(String attribute, String badtype) throws Exception {
-        /* run sepolicy-analyze attribute check on policy file */
-        ProcessBuilder pb = new ProcessBuilder(sepolicyAnalyze.getAbsolutePath(),
-                devicePolicyFile.getAbsolutePath(), "attribute", attribute);
-        pb.redirectOutput(ProcessBuilder.Redirect.PIPE);
-        pb.redirectErrorStream(true);
-        Process p = pb.start();
-        p.waitFor();
-        BufferedReader result = new BufferedReader(new InputStreamReader(p.getInputStream()));
-        String type;
-        while ((type = result.readLine()) != null) {
-            assertFalse("Attribute " + attribute + " includes " + type + "\n",
-                        type.equals(badtype));
-        }
-    }
-
-    /**
-     * Tests that mlstrustedsubject does not include untrusted_app
-     * and that mlstrustedobject does not include app_data_file.
-     * This helps prevent circumventing the per-user isolation of
-     * normal apps via levelFrom=user.
-     *
-     * @throws Exception
-     */
-    public void testMLSAttributes() throws Exception {
-        assertNotInAttribute("mlstrustedsubject", "untrusted_app");
-        assertNotInAttribute("mlstrustedobject", "app_data_file");
-    }
-
-    /**
-     * Tests that the seapp_contexts file on the device is valid.
-     *
-     * @throws Exception
-     */
-    public void testValidSeappContexts() throws Exception {
-        File OutputFile = File.createTempFile("seapp_output", ".tmp");
-        OutputFile.deleteOnExit();
-
-        /* run checkseapp on seapp_contexts */
-        ProcessBuilder pb = new ProcessBuilder(checkSeapp.getAbsolutePath(),
-                "-p", devicePolicyFile.getAbsolutePath(),
-                deviceSeappFile.getAbsolutePath(),
-                "-o", OutputFile.getAbsolutePath());
-        pb.redirectOutput(ProcessBuilder.Redirect.PIPE);
-        pb.redirectErrorStream(true);
-        Process p = pb.start();
-        p.waitFor();
-        BufferedReader result = new BufferedReader(new InputStreamReader(p.getInputStream()));
-        String line;
-        StringBuilder errorString = new StringBuilder();
-        while ((line = result.readLine()) != null) {
-            errorString.append(line);
-            errorString.append("\n");
-        }
-        assertTrue("The seapp_contexts file was invalid:\n"
-                   + errorString, errorString.length() == 0);
-    }
-
-    /**
-     * Asserts that the actual file contents starts with the expected file
-     * contents.
-     *
-     * @param expectedFile
-     *  The file with the expected contents.
-     * @param actualFile
-     *  The actual file being checked.
-     */
-    private void assertFileStartsWith(File expectedFile, File actualFile) throws Exception {
-        BufferedReader expectedReader = new BufferedReader(new FileReader(expectedFile.getAbsolutePath()));
-        BufferedReader actualReader = new BufferedReader(new FileReader(actualFile.getAbsolutePath()));
-        String expectedLine, actualLine;
-        while ((expectedLine = expectedReader.readLine()) != null) {
-            actualLine = actualReader.readLine();
-            assertEquals("Lines do not match:", expectedLine, actualLine);
-        }
-    }
-
-    /**
-     * Tests that the seapp_contexts file on the device contains
-     * the standard AOSP entries.
-     *
-     * @throws Exception
-     */
-    public void testAospSeappContexts() throws Exception {
-        assertFileStartsWith(aospSeappFile, deviceSeappFile);
-    }
-
-    /**
-     * Tests that the file_contexts file on the device contains
-     * the standard AOSP entries.
-     *
-     * @throws Exception
-     */
-    public void testAospFileContexts() throws Exception {
-        assertFileStartsWith(aospFcFile, deviceFcFile);
-    }
-
-    /**
-     * Tests that the property_contexts file on the device contains
-     * the standard AOSP entries.
-     *
-     * @throws Exception
-     */
-    public void testAospPropertyContexts() throws Exception {
-        assertFileStartsWith(aospPcFile, devicePcFile);
-    }
-
-    /**
-     * Tests that the service_contexts file on the device contains
-     * the standard AOSP entries.
-     *
-     * @throws Exception
-     */
-    public void testAospServiceContexts() throws Exception {
-        assertFileStartsWith(aospSvcFile, deviceSvcFile);
-    }
-
-    /**
-     * Tests that the file_contexts file on the device is valid.
-     *
-     * @throws Exception
-     */
-    public void testValidFileContexts() throws Exception {
-
-        /* run checkfc on file_contexts */
-        ProcessBuilder pb = new ProcessBuilder(checkFc.getAbsolutePath(),
-                devicePolicyFile.getAbsolutePath(),
-                deviceFcFile.getAbsolutePath());
-        pb.redirectOutput(ProcessBuilder.Redirect.PIPE);
-        pb.redirectErrorStream(true);
-        Process p = pb.start();
-        p.waitFor();
-        BufferedReader result = new BufferedReader(new InputStreamReader(p.getInputStream()));
-        String line;
-        StringBuilder errorString = new StringBuilder();
-        while ((line = result.readLine()) != null) {
-            errorString.append(line);
-            errorString.append("\n");
-        }
-        assertTrue("The file_contexts file was invalid:\n"
-                   + errorString, errorString.length() == 0);
-    }
-
-    /**
-     * Tests that the property_contexts file on the device is valid.
-     *
-     * @throws Exception
-     */
-    public void testValidPropertyContexts() throws Exception {
-
-        /* run checkfc -p on property_contexts */
-        ProcessBuilder pb = new ProcessBuilder(checkFc.getAbsolutePath(),
-                "-p", devicePolicyFile.getAbsolutePath(),
-                devicePcFile.getAbsolutePath());
-        pb.redirectOutput(ProcessBuilder.Redirect.PIPE);
-        pb.redirectErrorStream(true);
-        Process p = pb.start();
-        p.waitFor();
-        BufferedReader result = new BufferedReader(new InputStreamReader(p.getInputStream()));
-        String line;
-        StringBuilder errorString = new StringBuilder();
-        while ((line = result.readLine()) != null) {
-            errorString.append(line);
-            errorString.append("\n");
-        }
-        assertTrue("The property_contexts file was invalid:\n"
-                   + errorString, errorString.length() == 0);
-    }
-
-    /**
-     * Tests that the service_contexts file on the device is valid.
-     *
-     * @throws Exception
-     */
-    public void testValidServiceContexts() throws Exception {
-
-        /* run checkfc -p on service_contexts */
-        ProcessBuilder pb = new ProcessBuilder(checkFc.getAbsolutePath(),
-                "-p", devicePolicyFile.getAbsolutePath(),
-                devicePcFile.getAbsolutePath());
-        pb.redirectOutput(ProcessBuilder.Redirect.PIPE);
-        pb.redirectErrorStream(true);
-        Process p = pb.start();
-        p.waitFor();
-        BufferedReader result = new BufferedReader(new InputStreamReader(p.getInputStream()));
-        String line;
-        StringBuilder errorString = new StringBuilder();
-        while ((line = result.readLine()) != null) {
-            errorString.append(line);
-            errorString.append("\n");
-        }
-        assertTrue("The service_contexts file was invalid:\n"
-                   + errorString, errorString.length() == 0);
-    }
-
-   /**
-     * Tests that the policy defines no booleans (runtime conditional policy).
-     *
-     * @throws Exception
-     */
-    public void testNoBooleans() throws Exception {
-
-        /* run sepolicy-analyze booleans check on policy file */
-        ProcessBuilder pb = new ProcessBuilder(sepolicyAnalyze.getAbsolutePath(),
-                devicePolicyFile.getAbsolutePath(), "booleans");
-        pb.redirectOutput(ProcessBuilder.Redirect.PIPE);
-        pb.redirectErrorStream(true);
-        Process p = pb.start();
-        p.waitFor();
-        BufferedReader result = new BufferedReader(new InputStreamReader(p.getInputStream()));
-        String line;
-        StringBuilder errorString = new StringBuilder();
-        while ((line = result.readLine()) != null) {
-            errorString.append(line);
-            errorString.append("\n");
-        }
-        assertTrue("The policy contained booleans:\n"
-                   + errorString, errorString.length() == 0);
-    }
-
-    /**
-     * Tests that important domain labels are being appropriately applied.
-     */
-
-    /**
-     * Asserts that no processes are running in a domain.
-     *
-     * @param domain
-     *  The domain or SELinux context to check.
-     */
-    private void assertDomainEmpty(String domain) throws DeviceNotAvailableException {
-        List<ProcessDetails> procs = ProcessDetails.getProcMap(mDevice).get(domain);
-        String msg = "Expected no processes in SELinux domain \"" + domain + "\""
-            + " Found: \"" + procs + "\"";
-        assertNull(msg, procs);
-    }
-
-    /**
-     * Asserts that a domain exists and that only one, well defined, process is
-     * running in that domain.
-     *
-     * @param domain
-     *  The domain or SELinux context to check.
-     * @param executable
-     *  The path of the executable or application package name.
-     */
-    private void assertDomainOne(String domain, String executable) throws DeviceNotAvailableException {
-        List<ProcessDetails> procs = ProcessDetails.getProcMap(mDevice).get(domain);
-        List<ProcessDetails> exeProcs = ProcessDetails.getExeMap(mDevice).get(executable);
-        String msg = "Expected 1 process in SELinux domain \"" + domain + "\""
-            + " Found \"" + procs + "\"";
-        assertNotNull(msg, procs);
-        assertEquals(msg, 1, procs.size());
-
-        msg = "Expected executable \"" + executable + "\" in SELinux domain \"" + domain + "\""
-            + "Found: \"" + procs + "\"";
-        assertEquals(msg, executable, procs.get(0).procTitle);
-
-        msg = "Expected 1 process with executable \"" + executable + "\""
-            + " Found \"" + procs + "\"";
-        assertNotNull(msg, exeProcs);
-        assertEquals(msg, 1, exeProcs.size());
-
-        msg = "Expected executable \"" + executable + "\" in SELinux domain \"" + domain + "\""
-            + "Found: \"" + procs + "\"";
-        assertEquals(msg, domain, exeProcs.get(0).label);
-    }
-
-    /**
-     * Asserts that a domain may exist. If a domain exists, the cardinality of
-     * the domain is verified to be 1 and that the correct process is running in
-     * that domain.
-     *
-     * @param domain
-     *  The domain or SELinux context to check.
-     * @param executable
-     *  The path of the executable or application package name.
-     */
-    private void assertDomainZeroOrOne(String domain, String executable)
-        throws DeviceNotAvailableException {
-        List<ProcessDetails> procs = ProcessDetails.getProcMap(mDevice).get(domain);
-        List<ProcessDetails> exeProcs = ProcessDetails.getExeMap(mDevice).get(executable);
-
-        if (procs != null) {
-            String msg = "Expected 1 process in SELinux domain \"" + domain + "\""
-            + " Found: \"" + procs + "\"";
-            assertEquals(msg, 1, procs.size());
-
-            msg = "Expected executable \"" + executable + "\" in SELinux domain \"" + domain + "\""
-                + "Found: \"" + procs.get(0) + "\"";
-            assertEquals(msg, executable, procs.get(0).procTitle);
-        }
-
-        if (exeProcs != null) {
-            String msg = "Expected 1 process with executable \"" + executable + "\""
-            + " Found: \"" + procs + "\"";
-            assertEquals(msg, 1, exeProcs.size());
-
-            msg = "Expected executable \"" + executable + "\" in SELinux domain \"" + domain + "\""
-                + "Found: \"" + procs.get(0) + "\"";
-            assertEquals(msg, domain, exeProcs.get(0).label);
-        }
-    }
-
-    /**
-     * Asserts that a domain must exist, and that the cardinality is greater
-     * than or equal to 1.
-     *
-     * @param domain
-     *  The domain or SELinux context to check.
-     * @param executables
-     *  The path of the allowed executables or application package names.
-     */
-    private void assertDomainN(String domain, String... executables)
-        throws DeviceNotAvailableException {
-        List<ProcessDetails> procs = ProcessDetails.getProcMap(mDevice).get(domain);
-        String msg = "Expected 1 or more processes in SELinux domain but found none.";
-        assertNotNull(msg, procs);
-
-        Set<String> execList = new HashSet<String>(Arrays.asList(executables));
-
-        for (ProcessDetails p : procs) {
-            msg = "Expected one of \"" + execList + "\" in SELinux domain \"" + domain + "\""
-                + " Found: \"" + p + "\"";
-            assertTrue(msg, execList.contains(p.procTitle));
-        }
-
-        for (String exe : executables) {
-            List<ProcessDetails> exeProcs = ProcessDetails.getExeMap(mDevice).get(exe);
-
-            if (exeProcs != null) {
-                for (ProcessDetails p : exeProcs) {
-                    msg = "Expected executable \"" + exe + "\" in SELinux domain \""
-                        + domain + "\"" + " Found: \"" + p + "\"";
-                    assertEquals(msg, domain, p.label);
-                }
-            }
-        }
-    }
-
-    /**
-     * Asserts that a domain, if it exists, is only running the listed executables.
-     *
-     * @param domain
-     *  The domain or SELinux context to check.
-     * @param executables
-     *  The path of the allowed executables or application package names.
-     */
-    private void assertDomainHasExecutable(String domain, String... executables)
-        throws DeviceNotAvailableException {
-        List<ProcessDetails> procs = ProcessDetails.getProcMap(mDevice).get(domain);
-
-        if (procs != null) {
-            Set<String> execList = new HashSet<String>(Arrays.asList(executables));
-
-            for (ProcessDetails p : procs) {
-                String msg = "Expected one of \"" + execList + "\" in SELinux domain \""
-                    + domain + "\"" + " Found: \"" + p + "\"";
-                assertTrue(msg, execList.contains(p.procTitle));
-            }
-        }
-
-        for (String exe : executables) {
-            List<ProcessDetails> exeProcs = ProcessDetails.getExeMap(mDevice).get(exe);
-
-            if (exeProcs != null) {
-                for (ProcessDetails p : exeProcs) {
-                    String msg = "Expected executable \"" + exe + "\" in SELinux domain \""
-                        + domain + "\"" + " Found: \"" + p + "\"";
-                    assertEquals(msg, domain, p.label);
-                }
-            }
-        }
-    }
-
-    /* Init is always there */
-    public void testInitDomain() throws DeviceNotAvailableException {
-        assertDomainOne("u:r:init:s0", "/init");
-    }
-
-    /* Ueventd is always there */
-    public void testUeventdDomain() throws DeviceNotAvailableException {
-        assertDomainOne("u:r:ueventd:s0", "/sbin/ueventd");
-    }
-
-    /* Devices always have healthd */
-    public void testHealthdDomain() throws DeviceNotAvailableException {
-        assertDomainOne("u:r:healthd:s0", "/sbin/healthd");
-    }
-
-    /* Servicemanager is always there */
-    public void testServicemanagerDomain() throws DeviceNotAvailableException {
-        assertDomainOne("u:r:servicemanager:s0", "/system/bin/servicemanager");
-    }
-
-    /* Vold is always there */
-    public void testVoldDomain() throws DeviceNotAvailableException {
-        assertDomainOne("u:r:vold:s0", "/system/bin/vold");
-    }
-
-    /* netd is always there */
-    public void testNetdDomain() throws DeviceNotAvailableException {
-        assertDomainOne("u:r:netd:s0", "/system/bin/netd");
-    }
-
-    /* Debuggerd is always there */
-    public void testDebuggerdDomain() throws DeviceNotAvailableException {
-        assertDomainN("u:r:debuggerd:s0", "/system/bin/debuggerd", "/system/bin/debuggerd64");
-    }
-
-    /* Surface flinger is always there */
-    public void testSurfaceflingerDomain() throws DeviceNotAvailableException {
-        assertDomainOne("u:r:surfaceflinger:s0", "/system/bin/surfaceflinger");
-    }
-
-    /* Zygote is always running */
-    public void testZygoteDomain() throws DeviceNotAvailableException {
-        assertDomainN("u:r:zygote:s0", "zygote", "zygote64");
-    }
-
-    /* Checks drmserver for devices that require it */
-    public void testDrmServerDomain() throws DeviceNotAvailableException {
-        assertDomainZeroOrOne("u:r:drmserver:s0", "/system/bin/drmserver");
-    }
-
-    /* Media server is always running */
-    public void testMediaserverDomain() throws DeviceNotAvailableException {
-        assertDomainN("u:r:mediaserver:s0", "media.log", "/system/bin/mediaserver");
-    }
-
-    /* Installd is always running */
-    public void testInstalldDomain() throws DeviceNotAvailableException {
-        assertDomainOne("u:r:installd:s0", "/system/bin/installd");
-    }
-
-    /* keystore is always running */
-    public void testKeystoreDomain() throws DeviceNotAvailableException {
-        assertDomainOne("u:r:keystore:s0", "/system/bin/keystore");
-    }
-
-    /* System server better be running :-P */
-    public void testSystemServerDomain() throws DeviceNotAvailableException {
-        assertDomainOne("u:r:system_server:s0", "system_server");
-    }
-
-    /*
-     * Some OEMs do not use sdcardd so transient. Other OEMs have multiple sdcards
-     * so they run the daemon multiple times.
-     */
-    public void testSdcarddDomain() throws DeviceNotAvailableException {
-        assertDomainHasExecutable("u:r:sdcardd:s0", "/system/bin/sdcard");
-    }
-
-    /* Watchdogd may or may not be there */
-    public void testWatchdogdDomain() throws DeviceNotAvailableException {
-        assertDomainZeroOrOne("u:r:watchdogd:s0", "/sbin/watchdogd");
-    }
-
-    /* logd may or may not be there */
-    public void testLogdDomain() throws DeviceNotAvailableException {
-        assertDomainZeroOrOne("u:r:logd:s0", "/system/bin/logd");
-    }
-
-    /* lmkd may or may not be there */
-    public void testLmkdDomain() throws DeviceNotAvailableException {
-        assertDomainZeroOrOne("u:r:lmkd:s0", "/system/bin/lmkd");
-    }
-
-    /* Wifi may be off so cardinality of 0 or 1 is ok */
-    public void testWpaDomain() throws DeviceNotAvailableException {
-        assertDomainZeroOrOne("u:r:wpa:s0", "/system/bin/wpa_supplicant");
-    }
-
-    /*
-     * Nothing should be running in this domain, cardinality test is all thats
-     * needed
-     */
-    public void testInitShellDomain() throws DeviceNotAvailableException {
-        assertDomainEmpty("u:r:init_shell:s0");
-    }
-
-    /*
-     * Nothing should be running in this domain, cardinality test is all thats
-     * needed
-     */
-    public void testRecoveryDomain() throws DeviceNotAvailableException {
-        assertDomainEmpty("u:r:recovery:s0");
-    }
-
-    /*
-     * Nothing should be running in this domain, cardinality test is all thats
-     * needed
-     */
-    public void testSuDomain() throws DeviceNotAvailableException {
-        assertDomainEmpty("u:r:su:s0");
-    }
-
-    /*
-     * There will at least be some kernel thread running and all kthreads should
-     * be in kernel context.
-     */
-    public void testKernelDomain() throws DeviceNotAvailableException {
-        String domain = "u:r:kernel:s0";
-        List<ProcessDetails> procs = ProcessDetails.getProcMap(mDevice).get(domain);
-        assertNotNull(procs);
-        for (ProcessDetails p : procs) {
-            assertTrue("Non Kernel thread \"" + p + "\" found!", p.isKernel());
-        }
-    }
-
-    private static class ProcessDetails {
-        public String label;
-        public String user;
-        public int pid;
-        public int ppid;
-        public String procTitle;
-
-        private static HashMap<String, ArrayList<ProcessDetails>> procMap;
-        private static HashMap<String, ArrayList<ProcessDetails>> exeMap;
-        private static int kernelParentThreadpid = -1;
-
-        ProcessDetails(String label, String user, int pid, int ppid, String procTitle) {
-            this.label = label;
-            this.user = user;
-            this.pid = pid;
-            this.ppid = ppid;
-            this.procTitle = procTitle;
-        }
-
-        @Override
-        public String toString() {
-            return "label: " + label
-                    + " user: " + user
-                    + " pid: " + pid
-                    + " ppid: " + ppid
-                    + " cmd: " + procTitle;
-        }
-
-
-        private static void createProcMap(ITestDevice tDevice) throws DeviceNotAvailableException {
-
-            /* take the output of a ps -Z to do our analysis */
-            CollectingOutputReceiver psOut = new CollectingOutputReceiver();
-            tDevice.executeShellCommand("ps -Z", psOut);
-            String psOutString = psOut.getOutput();
-            Pattern p = Pattern.compile(
-                    "^([\\w_:]+)\\s+([\\w_]+)\\s+(\\d+)\\s+(\\d+)\\s+(\\p{Graph}+)$",
-                    Pattern.MULTILINE);
-            Matcher m = p.matcher(psOutString);
-            procMap = new HashMap<String, ArrayList<ProcessDetails>>();
-            exeMap = new HashMap<String, ArrayList<ProcessDetails>>();
-            while(m.find()) {
-                String domainLabel = m.group(1);
-                String user = m.group(2);
-                int pid = Integer.parseInt(m.group(3));
-                int ppid = Integer.parseInt(m.group(4));
-                String procTitle = m.group(5);
-                ProcessDetails proc = new ProcessDetails(domainLabel, user, pid, ppid, procTitle);
-                if (procMap.get(domainLabel) == null) {
-                    procMap.put(domainLabel, new ArrayList<ProcessDetails>());
-                }
-                procMap.get(domainLabel).add(proc);
-                if (procTitle.equals("kthreadd") && ppid == 0) {
-                    kernelParentThreadpid = pid;
-                }
-                if (exeMap.get(procTitle) == null) {
-                    exeMap.put(procTitle, new ArrayList<ProcessDetails>());
-                }
-                exeMap.get(procTitle).add(proc);
-            }
-        }
-
-        public static HashMap<String, ArrayList<ProcessDetails>> getProcMap(ITestDevice tDevice)
-                throws DeviceNotAvailableException{
-            if (procMap == null) {
-                createProcMap(tDevice);
-            }
-            return procMap;
-        }
-
-        public static HashMap<String, ArrayList<ProcessDetails>> getExeMap(ITestDevice tDevice)
-                throws DeviceNotAvailableException{
-            if (exeMap == null) {
-                createProcMap(tDevice);
-            }
-            return exeMap;
-        }
-
-        public boolean isKernel() {
-            return (pid == kernelParentThreadpid || ppid == kernelParentThreadpid);
-        }
-    }
-}
diff --git a/hostsidetests/security/src/android/security/cts/EncryptionHostTest.java b/hostsidetests/security/src/android/security/cts/EncryptionHostTest.java
new file mode 100644
index 0000000..5e12143
--- /dev/null
+++ b/hostsidetests/security/src/android/security/cts/EncryptionHostTest.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.LogLevel;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.log.LogUtil.CLog;
+import com.android.tradefed.testtype.DeviceTestCase;
+
+import java.util.UUID;
+
+/**
+ * Host side encryption tests
+ *
+ * These tests analyze a userdebug device for correct encryption properties
+ */
+public class EncryptionHostTest extends DeviceTestCase {
+    ITestDevice mDevice;
+    boolean mUserDebug;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mDevice = getDevice();
+        mUserDebug = "userdebug".equals(mDevice.executeShellCommand("getprop ro.build.type").trim());
+        if (!mUserDebug) {
+            return;
+        }
+
+        mDevice.executeAdbCommand("root");
+        assertTrue(mDevice.isAdbRoot());
+    }
+
+    public void testEncrypted() throws DeviceNotAvailableException {
+        if (!mUserDebug || !mDevice.isDeviceEncrypted()) {
+            return;
+        }
+        /*
+        // Create file with name and contents a random UUID so we can search for it
+        String uuid = UUID.randomUUID().toString();
+        mDevice.executeShellCommand("echo " + uuid + " > /data/local/tmp/" + uuid);
+        String uuidReturned = mDevice.executeShellCommand("cat /data/local/tmp/" + uuid).trim();
+        assertTrue(uuid.equals(uuidReturned));
+
+        // Get name of /data device
+        String fstabName = mDevice.executeShellCommand("ls /fstab.*");
+        String[] fstab = mDevice.executeShellCommand("cat " + fstabName).split("\n");
+        String path = null;
+        for (String line : fstab) {
+            String[] entries = line.split("[ \t]+");
+            if (entries.length < 2) continue;
+            if ("/data".equals(entries[1])) {
+                path = entries[0];
+                break;
+            }
+        }
+        assertFalse(path == null);
+
+        // grep it for the data
+        String result = mDevice.executeShellCommand("grep " + uuid + " " + path + " ").trim();
+        assertTrue("".equals(result));
+
+        // Clean up
+        mDevice.executeShellCommand("rm /data/local/tmp/" + uuid);
+        */
+    }
+}
diff --git a/hostsidetests/security/src/android/security/cts/SELinuxHostTest.java b/hostsidetests/security/src/android/security/cts/SELinuxHostTest.java
new file mode 100644
index 0000000..f73eb49
--- /dev/null
+++ b/hostsidetests/security/src/android/security/cts/SELinuxHostTest.java
@@ -0,0 +1,842 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.cts.migration.MigrationHelper;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.device.CollectingOutputReceiver;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceTestCase;
+import com.android.tradefed.testtype.IBuildReceiver;
+import com.android.tradefed.testtype.IDeviceTest;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.lang.String;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.Scanner;
+import java.util.Set;
+
+/**
+ * Host-side SELinux tests.
+ *
+ * These tests analyze the policy file in use on the subject device directly or
+ * run as the shell user to evaluate aspects of the state of SELinux on the test
+ * device which otherwise would not be available to a normal apk.
+ */
+public class SELinuxHostTest extends DeviceTestCase implements IBuildReceiver, IDeviceTest {
+
+    private File sepolicyAnalyze;
+    private File checkSeapp;
+    private File checkFc;
+    private File aospSeappFile;
+    private File aospFcFile;
+    private File aospPcFile;
+    private File aospSvcFile;
+    private File devicePolicyFile;
+    private File deviceSeappFile;
+    private File deviceFcFile;
+    private File devicePcFile;
+    private File deviceSvcFile;
+    private File seappNeverAllowFile;
+
+    private IBuildInfo mBuild;
+
+    /**
+     * A reference to the device under test.
+     */
+    private ITestDevice mDevice;
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setBuild(IBuildInfo build) {
+        mBuild = build;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setDevice(ITestDevice device) {
+        super.setDevice(device);
+        mDevice = device;
+    }
+
+    private File copyResourceToTempFile(String resName) throws IOException {
+        InputStream is = this.getClass().getResourceAsStream(resName);
+        File tempFile = File.createTempFile("SELinuxHostTest", ".tmp");
+        FileOutputStream os = new FileOutputStream(tempFile);
+        int rByte = 0;
+        while ((rByte = is.read()) != -1) {
+            os.write(rByte);
+        }
+        os.flush();
+        os.close();
+        tempFile.deleteOnExit();
+        return tempFile;
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        sepolicyAnalyze = MigrationHelper.getTestFile(mBuild, "sepolicy-analyze");
+        sepolicyAnalyze.setExecutable(true);
+
+        /* obtain sepolicy file from running device */
+        devicePolicyFile = File.createTempFile("sepolicy", ".tmp");
+        devicePolicyFile.deleteOnExit();
+        mDevice.pullFile("/sys/fs/selinux/policy", devicePolicyFile);
+    }
+
+    /**
+     * Tests that the kernel is enforcing selinux policy globally.
+     *
+     * @throws Exception
+     */
+    public void testGlobalEnforcing() throws Exception {
+        CollectingOutputReceiver out = new CollectingOutputReceiver();
+        mDevice.executeShellCommand("cat /sys/fs/selinux/enforce", out);
+        assertEquals("SELinux policy is not being enforced!", "1", out.getOutput());
+    }
+
+    /**
+     * Tests that all domains in the running policy file are in enforcing mode
+     *
+     * @throws Exception
+     */
+    public void testAllDomainsEnforcing() throws Exception {
+
+        /* run sepolicy-analyze permissive check on policy file */
+        ProcessBuilder pb = new ProcessBuilder(sepolicyAnalyze.getAbsolutePath(),
+                devicePolicyFile.getAbsolutePath(), "permissive");
+        pb.redirectOutput(ProcessBuilder.Redirect.PIPE);
+        pb.redirectErrorStream(true);
+        Process p = pb.start();
+        p.waitFor();
+        BufferedReader result = new BufferedReader(new InputStreamReader(p.getInputStream()));
+        String line;
+        StringBuilder errorString = new StringBuilder();
+        while ((line = result.readLine()) != null) {
+            errorString.append(line);
+            errorString.append("\n");
+        }
+        assertTrue("The following SELinux domains were found to be in permissive mode:\n"
+                   + errorString, errorString.length() == 0);
+    }
+
+    /**
+     * Asserts that specified type is not associated with the specified
+     * attribute.
+     *
+     * @param attribute
+     *  The attribute name.
+     * @param type
+     *  The type name.
+     */
+    private void assertNotInAttribute(String attribute, String badtype) throws Exception {
+        /* run sepolicy-analyze attribute check on policy file */
+        ProcessBuilder pb = new ProcessBuilder(sepolicyAnalyze.getAbsolutePath(),
+                devicePolicyFile.getAbsolutePath(), "attribute", attribute);
+        pb.redirectOutput(ProcessBuilder.Redirect.PIPE);
+        pb.redirectErrorStream(true);
+        Process p = pb.start();
+        p.waitFor();
+        BufferedReader result = new BufferedReader(new InputStreamReader(p.getInputStream()));
+        String type;
+        while ((type = result.readLine()) != null) {
+            assertFalse("Attribute " + attribute + " includes " + type + "\n",
+                        type.equals(badtype));
+        }
+    }
+
+    /**
+     * Tests that mlstrustedsubject does not include untrusted_app
+     * and that mlstrustedobject does not include app_data_file.
+     * This helps prevent circumventing the per-user isolation of
+     * normal apps via levelFrom=user.
+     *
+     * @throws Exception
+     */
+    public void testMLSAttributes() throws Exception {
+        assertNotInAttribute("mlstrustedsubject", "untrusted_app");
+        assertNotInAttribute("mlstrustedobject", "app_data_file");
+    }
+
+    /**
+     * Tests that the seapp_contexts file on the device is valid.
+     *
+     * @throws Exception
+     */
+    public void testValidSeappContexts() throws Exception {
+
+        /* obtain seapp_contexts file from running device */
+        deviceSeappFile = File.createTempFile("seapp_contexts", ".tmp");
+        deviceSeappFile.deleteOnExit();
+        mDevice.pullFile("/seapp_contexts", deviceSeappFile);
+
+        /* retrieve the checkseapp executable from jar */
+        checkSeapp = copyResourceToTempFile("/checkseapp");
+        checkSeapp.setExecutable(true);
+
+        /* retrieve the AOSP seapp_neverallows file from jar */
+        seappNeverAllowFile = copyResourceToTempFile("/general_seapp_neverallows");
+
+        /* run checkseapp on seapp_contexts */
+        ProcessBuilder pb = new ProcessBuilder(checkSeapp.getAbsolutePath(),
+                "-p", devicePolicyFile.getAbsolutePath(),
+                seappNeverAllowFile.getAbsolutePath(),
+                deviceSeappFile.getAbsolutePath());
+        pb.redirectOutput(ProcessBuilder.Redirect.PIPE);
+        pb.redirectErrorStream(true);
+        Process p = pb.start();
+        p.waitFor();
+        BufferedReader result = new BufferedReader(new InputStreamReader(p.getInputStream()));
+        String line;
+        StringBuilder errorString = new StringBuilder();
+        while ((line = result.readLine()) != null) {
+            errorString.append(line);
+            errorString.append("\n");
+        }
+        assertTrue("The seapp_contexts file was invalid:\n"
+                   + errorString, errorString.length() == 0);
+    }
+
+    /**
+     * Asserts that the actual file contents starts with the expected file
+     * contents.
+     *
+     * @param expectedFile
+     *  The file with the expected contents.
+     * @param actualFile
+     *  The actual file being checked.
+     */
+    private void assertFileStartsWith(File expectedFile, File actualFile) throws Exception {
+        BufferedReader expectedReader = new BufferedReader(new FileReader(expectedFile.getAbsolutePath()));
+        BufferedReader actualReader = new BufferedReader(new FileReader(actualFile.getAbsolutePath()));
+        String expectedLine, actualLine;
+        while ((expectedLine = expectedReader.readLine()) != null) {
+            actualLine = actualReader.readLine();
+            assertEquals("Lines do not match:", expectedLine, actualLine);
+        }
+    }
+
+    /**
+     * Tests that the seapp_contexts file on the device contains
+     * the standard AOSP entries.
+     *
+     * @throws Exception
+     */
+    public void testAospSeappContexts() throws Exception {
+
+        /* obtain seapp_contexts file from running device */
+        deviceSeappFile = File.createTempFile("seapp_contexts", ".tmp");
+        deviceSeappFile.deleteOnExit();
+        mDevice.pullFile("/seapp_contexts", deviceSeappFile);
+
+        /* retrieve the AOSP seapp_contexts file from jar */
+        aospSeappFile = copyResourceToTempFile("/general_seapp_contexts");
+
+        assertFileStartsWith(aospSeappFile, deviceSeappFile);
+    }
+
+    /**
+     * Tests that the file_contexts.bin file on the device contains
+     * the standard AOSP entries.
+     *
+     * @throws Exception
+     */
+    public void testAospFileContexts() throws Exception {
+
+        /* retrieve the checkfc executable from jar */
+        checkFc = copyResourceToTempFile("/checkfc");
+        checkFc.setExecutable(true);
+
+        /* obtain file_contexts.bin file from running device */
+        deviceFcFile = File.createTempFile("file_contexts", ".bin");
+        deviceFcFile.deleteOnExit();
+        mDevice.pullFile("/file_contexts.bin", deviceFcFile);
+
+        /* retrieve the AOSP file_contexts file from jar */
+        aospFcFile = copyResourceToTempFile("/general_file_contexts.bin");
+
+        /* run checkfc -c general_file_contexts.bin file_contexts.bin */
+        ProcessBuilder pb = new ProcessBuilder(checkFc.getAbsolutePath(),
+                "-c", aospFcFile.getAbsolutePath(),
+                deviceFcFile.getAbsolutePath());
+        pb.redirectOutput(ProcessBuilder.Redirect.PIPE);
+        pb.redirectErrorStream(true);
+        Process p = pb.start();
+        p.waitFor();
+        BufferedReader result = new BufferedReader(new InputStreamReader(p.getInputStream()));
+        String line = result.readLine();
+        assertTrue("The file_contexts.bin file did not include the AOSP entries:\n"
+                   + line + "\n",
+                   line.equals("equal") || line.equals("subset"));
+    }
+
+    /**
+     * Tests that the property_contexts file on the device contains
+     * the standard AOSP entries.
+     *
+     * @throws Exception
+     */
+    public void testAospPropertyContexts() throws Exception {
+
+        /* obtain property_contexts file from running device */
+        devicePcFile = File.createTempFile("property_contexts", ".tmp");
+        devicePcFile.deleteOnExit();
+        mDevice.pullFile("/property_contexts", devicePcFile);
+
+        /* retrieve the AOSP property_contexts file from jar */
+        aospPcFile = copyResourceToTempFile("/general_property_contexts");
+
+        assertFileStartsWith(aospPcFile, devicePcFile);
+    }
+
+    /**
+     * Tests that the service_contexts file on the device contains
+     * the standard AOSP entries.
+     *
+     * @throws Exception
+     */
+    public void testAospServiceContexts() throws Exception {
+
+        /* obtain service_contexts file from running device */
+        deviceSvcFile = File.createTempFile("service_contexts", ".tmp");
+        deviceSvcFile.deleteOnExit();
+        mDevice.pullFile("/service_contexts", deviceSvcFile);
+
+        /* retrieve the AOSP service_contexts file from jar */
+        aospSvcFile = copyResourceToTempFile("/general_service_contexts");
+
+        assertFileStartsWith(aospSvcFile, deviceSvcFile);
+    }
+
+    /**
+     * Tests that the file_contexts.bin file on the device is valid.
+     *
+     * @throws Exception
+     */
+    public void testValidFileContexts() throws Exception {
+
+        /* retrieve the checkfc executable from jar */
+        checkFc = copyResourceToTempFile("/checkfc");
+        checkFc.setExecutable(true);
+
+        /* obtain file_contexts.bin file from running device */
+        deviceFcFile = File.createTempFile("file_contexts", ".bin");
+        deviceFcFile.deleteOnExit();
+        mDevice.pullFile("/file_contexts.bin", deviceFcFile);
+
+        /* run checkfc sepolicy file_contexts.bin */
+        ProcessBuilder pb = new ProcessBuilder(checkFc.getAbsolutePath(),
+                devicePolicyFile.getAbsolutePath(),
+                deviceFcFile.getAbsolutePath());
+        pb.redirectOutput(ProcessBuilder.Redirect.PIPE);
+        pb.redirectErrorStream(true);
+        Process p = pb.start();
+        p.waitFor();
+        BufferedReader result = new BufferedReader(new InputStreamReader(p.getInputStream()));
+        String line;
+        StringBuilder errorString = new StringBuilder();
+        while ((line = result.readLine()) != null) {
+            errorString.append(line);
+            errorString.append("\n");
+        }
+        assertTrue("The file_contexts.bin file was invalid:\n"
+                   + errorString, errorString.length() == 0);
+    }
+
+    /**
+     * Tests that the property_contexts file on the device is valid.
+     *
+     * @throws Exception
+     */
+    public void testValidPropertyContexts() throws Exception {
+
+        /* retrieve the checkfc executable from jar */
+        checkFc = copyResourceToTempFile("/checkfc");
+        checkFc.setExecutable(true);
+
+        /* obtain property_contexts file from running device */
+        devicePcFile = File.createTempFile("property_contexts", ".tmp");
+        devicePcFile.deleteOnExit();
+        mDevice.pullFile("/property_contexts", devicePcFile);
+
+        /* run checkfc -p on property_contexts */
+        ProcessBuilder pb = new ProcessBuilder(checkFc.getAbsolutePath(),
+                "-p", devicePolicyFile.getAbsolutePath(),
+                devicePcFile.getAbsolutePath());
+        pb.redirectOutput(ProcessBuilder.Redirect.PIPE);
+        pb.redirectErrorStream(true);
+        Process p = pb.start();
+        p.waitFor();
+        BufferedReader result = new BufferedReader(new InputStreamReader(p.getInputStream()));
+        String line;
+        StringBuilder errorString = new StringBuilder();
+        while ((line = result.readLine()) != null) {
+            errorString.append(line);
+            errorString.append("\n");
+        }
+        assertTrue("The property_contexts file was invalid:\n"
+                   + errorString, errorString.length() == 0);
+    }
+
+    /**
+     * Tests that the service_contexts file on the device is valid.
+     *
+     * @throws Exception
+     */
+    public void testValidServiceContexts() throws Exception {
+
+        /* retrieve the checkfc executable from jar */
+        checkFc = copyResourceToTempFile("/checkfc");
+        checkFc.setExecutable(true);
+
+        /* obtain service_contexts file from running device */
+        deviceSvcFile = File.createTempFile("service_contexts", ".tmp");
+        deviceSvcFile.deleteOnExit();
+        mDevice.pullFile("/service_contexts", deviceSvcFile);
+
+        /* run checkfc -s on service_contexts */
+        ProcessBuilder pb = new ProcessBuilder(checkFc.getAbsolutePath(),
+                "-s", devicePolicyFile.getAbsolutePath(),
+                deviceSvcFile.getAbsolutePath());
+        pb.redirectOutput(ProcessBuilder.Redirect.PIPE);
+        pb.redirectErrorStream(true);
+        Process p = pb.start();
+        p.waitFor();
+        BufferedReader result = new BufferedReader(new InputStreamReader(p.getInputStream()));
+        String line;
+        StringBuilder errorString = new StringBuilder();
+        while ((line = result.readLine()) != null) {
+            errorString.append(line);
+            errorString.append("\n");
+        }
+        assertTrue("The service_contexts file was invalid:\n"
+                   + errorString, errorString.length() == 0);
+    }
+
+   /**
+     * Tests that the policy defines no booleans (runtime conditional policy).
+     *
+     * @throws Exception
+     */
+    public void testNoBooleans() throws Exception {
+
+        /* run sepolicy-analyze booleans check on policy file */
+        ProcessBuilder pb = new ProcessBuilder(sepolicyAnalyze.getAbsolutePath(),
+                devicePolicyFile.getAbsolutePath(), "booleans");
+        pb.redirectOutput(ProcessBuilder.Redirect.PIPE);
+        pb.redirectErrorStream(true);
+        Process p = pb.start();
+        p.waitFor();
+        BufferedReader result = new BufferedReader(new InputStreamReader(p.getInputStream()));
+        String line;
+        StringBuilder errorString = new StringBuilder();
+        while ((line = result.readLine()) != null) {
+            errorString.append(line);
+            errorString.append("\n");
+        }
+        assertTrue("The policy contained booleans:\n"
+                   + errorString, errorString.length() == 0);
+    }
+
+    /**
+     * Tests that important domain labels are being appropriately applied.
+     */
+
+    /**
+     * Asserts that no processes are running in a domain.
+     *
+     * @param domain
+     *  The domain or SELinux context to check.
+     */
+    private void assertDomainEmpty(String domain) throws DeviceNotAvailableException {
+        List<ProcessDetails> procs = ProcessDetails.getProcMap(mDevice).get(domain);
+        String msg = "Expected no processes in SELinux domain \"" + domain + "\""
+            + " Found: \"" + procs + "\"";
+        assertNull(msg, procs);
+    }
+
+    /**
+     * Asserts that a domain exists and that only one, well defined, process is
+     * running in that domain.
+     *
+     * @param domain
+     *  The domain or SELinux context to check.
+     * @param executable
+     *  The path of the executable or application package name.
+     */
+    private void assertDomainOne(String domain, String executable) throws DeviceNotAvailableException {
+        List<ProcessDetails> procs = ProcessDetails.getProcMap(mDevice).get(domain);
+        List<ProcessDetails> exeProcs = ProcessDetails.getExeMap(mDevice).get(executable);
+        String msg = "Expected 1 process in SELinux domain \"" + domain + "\""
+            + " Found \"" + procs + "\"";
+        assertNotNull(msg, procs);
+        assertEquals(msg, 1, procs.size());
+
+        msg = "Expected executable \"" + executable + "\" in SELinux domain \"" + domain + "\""
+            + "Found: \"" + procs + "\"";
+        assertEquals(msg, executable, procs.get(0).procTitle);
+
+        msg = "Expected 1 process with executable \"" + executable + "\""
+            + " Found \"" + procs + "\"";
+        assertNotNull(msg, exeProcs);
+        assertEquals(msg, 1, exeProcs.size());
+
+        msg = "Expected executable \"" + executable + "\" in SELinux domain \"" + domain + "\""
+            + "Found: \"" + procs + "\"";
+        assertEquals(msg, domain, exeProcs.get(0).label);
+    }
+
+    /**
+     * Asserts that a domain may exist. If a domain exists, the cardinality of
+     * the domain is verified to be 1 and that the correct process is running in
+     * that domain.
+     *
+     * @param domain
+     *  The domain or SELinux context to check.
+     * @param executable
+     *  The path of the executable or application package name.
+     */
+    private void assertDomainZeroOrOne(String domain, String executable)
+        throws DeviceNotAvailableException {
+        List<ProcessDetails> procs = ProcessDetails.getProcMap(mDevice).get(domain);
+        List<ProcessDetails> exeProcs = ProcessDetails.getExeMap(mDevice).get(executable);
+
+        if (procs != null) {
+            String msg = "Expected 1 process in SELinux domain \"" + domain + "\""
+            + " Found: \"" + procs + "\"";
+            assertEquals(msg, 1, procs.size());
+
+            msg = "Expected executable \"" + executable + "\" in SELinux domain \"" + domain + "\""
+                + "Found: \"" + procs.get(0) + "\"";
+            assertEquals(msg, executable, procs.get(0).procTitle);
+        }
+
+        if (exeProcs != null) {
+            String msg = "Expected 1 process with executable \"" + executable + "\""
+            + " Found: \"" + procs + "\"";
+            assertEquals(msg, 1, exeProcs.size());
+
+            msg = "Expected executable \"" + executable + "\" in SELinux domain \"" + domain + "\""
+                + "Found: \"" + procs.get(0) + "\"";
+            assertEquals(msg, domain, exeProcs.get(0).label);
+        }
+    }
+
+    /**
+     * Asserts that a domain must exist, and that the cardinality is greater
+     * than or equal to 1.
+     *
+     * @param domain
+     *  The domain or SELinux context to check.
+     * @param executables
+     *  The path of the allowed executables or application package names.
+     */
+    private void assertDomainN(String domain, String... executables)
+        throws DeviceNotAvailableException {
+        List<ProcessDetails> procs = ProcessDetails.getProcMap(mDevice).get(domain);
+        String msg = "Expected 1 or more processes in SELinux domain but found none.";
+        assertNotNull(msg, procs);
+
+        Set<String> execList = new HashSet<String>(Arrays.asList(executables));
+
+        for (ProcessDetails p : procs) {
+            msg = "Expected one of \"" + execList + "\" in SELinux domain \"" + domain + "\""
+                + " Found: \"" + p + "\"";
+            assertTrue(msg, execList.contains(p.procTitle));
+        }
+
+        for (String exe : executables) {
+            List<ProcessDetails> exeProcs = ProcessDetails.getExeMap(mDevice).get(exe);
+
+            if (exeProcs != null) {
+                for (ProcessDetails p : exeProcs) {
+                    msg = "Expected executable \"" + exe + "\" in SELinux domain \""
+                        + domain + "\"" + " Found: \"" + p + "\"";
+                    assertEquals(msg, domain, p.label);
+                }
+            }
+        }
+    }
+
+    /**
+     * Asserts that a domain, if it exists, is only running the listed executables.
+     *
+     * @param domain
+     *  The domain or SELinux context to check.
+     * @param executables
+     *  The path of the allowed executables or application package names.
+     */
+    private void assertDomainHasExecutable(String domain, String... executables)
+        throws DeviceNotAvailableException {
+        List<ProcessDetails> procs = ProcessDetails.getProcMap(mDevice).get(domain);
+
+        if (procs != null) {
+            Set<String> execList = new HashSet<String>(Arrays.asList(executables));
+
+            for (ProcessDetails p : procs) {
+                String msg = "Expected one of \"" + execList + "\" in SELinux domain \""
+                    + domain + "\"" + " Found: \"" + p + "\"";
+                assertTrue(msg, execList.contains(p.procTitle));
+            }
+        }
+
+        for (String exe : executables) {
+            List<ProcessDetails> exeProcs = ProcessDetails.getExeMap(mDevice).get(exe);
+
+            if (exeProcs != null) {
+                for (ProcessDetails p : exeProcs) {
+                    String msg = "Expected executable \"" + exe + "\" in SELinux domain \""
+                        + domain + "\"" + " Found: \"" + p + "\"";
+                    assertEquals(msg, domain, p.label);
+                }
+            }
+        }
+    }
+
+    /* Init is always there */
+    public void testInitDomain() throws DeviceNotAvailableException {
+        assertDomainOne("u:r:init:s0", "/init");
+    }
+
+    /* Ueventd is always there */
+    public void testUeventdDomain() throws DeviceNotAvailableException {
+        assertDomainOne("u:r:ueventd:s0", "/sbin/ueventd");
+    }
+
+    /* Devices always have healthd */
+    public void testHealthdDomain() throws DeviceNotAvailableException {
+        assertDomainOne("u:r:healthd:s0", "/sbin/healthd");
+    }
+
+    /* Servicemanager is always there */
+    public void testServicemanagerDomain() throws DeviceNotAvailableException {
+        assertDomainOne("u:r:servicemanager:s0", "/system/bin/servicemanager");
+    }
+
+    /* Vold is always there */
+    public void testVoldDomain() throws DeviceNotAvailableException {
+        assertDomainOne("u:r:vold:s0", "/system/bin/vold");
+    }
+
+    /* netd is always there */
+    public void testNetdDomain() throws DeviceNotAvailableException {
+        assertDomainOne("u:r:netd:s0", "/system/bin/netd");
+    }
+
+    /* Debuggerd is always there */
+    public void testDebuggerdDomain() throws DeviceNotAvailableException {
+        assertDomainN("u:r:debuggerd:s0", "/system/bin/debuggerd", "/system/bin/debuggerd64",
+                "debuggerd:signaller", "debuggerd64:signaller");
+    }
+
+    /* Surface flinger is always there */
+    public void testSurfaceflingerDomain() throws DeviceNotAvailableException {
+        assertDomainOne("u:r:surfaceflinger:s0", "/system/bin/surfaceflinger");
+    }
+
+    /* Zygote is always running */
+    public void testZygoteDomain() throws DeviceNotAvailableException {
+        assertDomainN("u:r:zygote:s0", "zygote", "zygote64");
+    }
+
+    /* Checks drmserver for devices that require it */
+    public void testDrmServerDomain() throws DeviceNotAvailableException {
+        assertDomainZeroOrOne("u:r:drmserver:s0", "/system/bin/drmserver");
+    }
+
+    /* Installd is always running */
+    public void testInstalldDomain() throws DeviceNotAvailableException {
+        assertDomainOne("u:r:installd:s0", "/system/bin/installd");
+    }
+
+    /* keystore is always running */
+    public void testKeystoreDomain() throws DeviceNotAvailableException {
+        assertDomainOne("u:r:keystore:s0", "/system/bin/keystore");
+    }
+
+    /* System server better be running :-P */
+    public void testSystemServerDomain() throws DeviceNotAvailableException {
+        assertDomainOne("u:r:system_server:s0", "system_server");
+    }
+
+    /*
+     * Some OEMs do not use sdcardd so transient. Other OEMs have multiple sdcards
+     * so they run the daemon multiple times.
+     */
+    public void testSdcarddDomain() throws DeviceNotAvailableException {
+        assertDomainHasExecutable("u:r:sdcardd:s0", "/system/bin/sdcard");
+    }
+
+    /* Watchdogd may or may not be there */
+    public void testWatchdogdDomain() throws DeviceNotAvailableException {
+        assertDomainZeroOrOne("u:r:watchdogd:s0", "/sbin/watchdogd");
+    }
+
+    /* logd may or may not be there */
+    public void testLogdDomain() throws DeviceNotAvailableException {
+        assertDomainZeroOrOne("u:r:logd:s0", "/system/bin/logd");
+    }
+
+    /* lmkd may or may not be there */
+    public void testLmkdDomain() throws DeviceNotAvailableException {
+        assertDomainZeroOrOne("u:r:lmkd:s0", "/system/bin/lmkd");
+    }
+
+    /* Wifi may be off so cardinality of 0 or 1 is ok */
+    public void testWpaDomain() throws DeviceNotAvailableException {
+        assertDomainZeroOrOne("u:r:wpa:s0", "/system/bin/wpa_supplicant");
+    }
+
+    /*
+     * Nothing should be running in this domain, cardinality test is all thats
+     * needed
+     */
+    public void testInitShellDomain() throws DeviceNotAvailableException {
+        assertDomainEmpty("u:r:init_shell:s0");
+    }
+
+    /*
+     * Nothing should be running in this domain, cardinality test is all thats
+     * needed
+     */
+    public void testRecoveryDomain() throws DeviceNotAvailableException {
+        assertDomainEmpty("u:r:recovery:s0");
+    }
+
+    /*
+     * Nothing should be running in this domain, cardinality test is all thats
+     * needed
+     */
+    public void testSuDomain() throws DeviceNotAvailableException {
+        assertDomainEmpty("u:r:su:s0");
+    }
+
+    /*
+     * All kthreads should be in kernel context.
+     */
+    public void testKernelDomain() throws DeviceNotAvailableException {
+        String domain = "u:r:kernel:s0";
+        List<ProcessDetails> procs = ProcessDetails.getProcMap(mDevice).get(domain);
+        if (procs != null) {
+            for (ProcessDetails p : procs) {
+                assertTrue("Non Kernel thread \"" + p + "\" found!", p.isKernel());
+            }
+        }
+    }
+
+    private static class ProcessDetails {
+        public String label;
+        public String user;
+        public int pid;
+        public int ppid;
+        public String procTitle;
+
+        private static HashMap<String, ArrayList<ProcessDetails>> procMap;
+        private static HashMap<String, ArrayList<ProcessDetails>> exeMap;
+        private static int kernelParentThreadpid = -1;
+
+        ProcessDetails(String label, String user, int pid, int ppid, String procTitle) {
+            this.label = label;
+            this.user = user;
+            this.pid = pid;
+            this.ppid = ppid;
+            this.procTitle = procTitle;
+        }
+
+        @Override
+        public String toString() {
+            return "label: " + label
+                    + " user: " + user
+                    + " pid: " + pid
+                    + " ppid: " + ppid
+                    + " cmd: " + procTitle;
+        }
+
+
+        private static void createProcMap(ITestDevice tDevice) throws DeviceNotAvailableException {
+
+            /* take the output of a ps -Z to do our analysis */
+            CollectingOutputReceiver psOut = new CollectingOutputReceiver();
+            // TODO: remove "toybox" below and just run "ps"
+            tDevice.executeShellCommand("toybox ps -A -o label,user,pid,ppid,cmdline", psOut);
+            String psOutString = psOut.getOutput();
+            Pattern p = Pattern.compile(
+                    "^([\\w_:]+)\\s+([\\w_]+)\\s+(\\d+)\\s+(\\d+)\\s+(\\p{Graph}+)(\\s\\p{Graph}+)*\\s*$",
+                    Pattern.MULTILINE);
+            Matcher m = p.matcher(psOutString);
+            procMap = new HashMap<String, ArrayList<ProcessDetails>>();
+            exeMap = new HashMap<String, ArrayList<ProcessDetails>>();
+            while(m.find()) {
+                String domainLabel = m.group(1);
+                String user = m.group(2);
+                int pid = Integer.parseInt(m.group(3));
+                int ppid = Integer.parseInt(m.group(4));
+                String procTitle = m.group(5);
+                ProcessDetails proc = new ProcessDetails(domainLabel, user, pid, ppid, procTitle);
+                if (procMap.get(domainLabel) == null) {
+                    procMap.put(domainLabel, new ArrayList<ProcessDetails>());
+                }
+                procMap.get(domainLabel).add(proc);
+                if (procTitle.equals("[kthreadd]") && ppid == 0) {
+                    kernelParentThreadpid = pid;
+                }
+                if (exeMap.get(procTitle) == null) {
+                    exeMap.put(procTitle, new ArrayList<ProcessDetails>());
+                }
+                exeMap.get(procTitle).add(proc);
+            }
+        }
+
+        public static HashMap<String, ArrayList<ProcessDetails>> getProcMap(ITestDevice tDevice)
+                throws DeviceNotAvailableException{
+            if (procMap == null) {
+                createProcMap(tDevice);
+            }
+            return procMap;
+        }
+
+        public static HashMap<String, ArrayList<ProcessDetails>> getExeMap(ITestDevice tDevice)
+                throws DeviceNotAvailableException{
+            if (exeMap == null) {
+                createProcMap(tDevice);
+            }
+            return exeMap;
+        }
+
+        public boolean isKernel() {
+            return (pid == kernelParentThreadpid || ppid == kernelParentThreadpid);
+        }
+    }
+}
diff --git a/hostsidetests/services/Android.mk b/hostsidetests/services/Android.mk
new file mode 100644
index 0000000..178cb8a
--- /dev/null
+++ b/hostsidetests/services/Android.mk
@@ -0,0 +1,17 @@
+#
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT 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 $(call all-subdir-makefiles)
diff --git a/hostsidetests/services/activitymanager/Android.mk b/hostsidetests/services/activitymanager/Android.mk
new file mode 100644
index 0000000..0cf1f2b
--- /dev/null
+++ b/hostsidetests/services/activitymanager/Android.mk
@@ -0,0 +1,38 @@
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+# Must match the package name in CtsTestCaseList.mk
+LOCAL_MODULE := CtsServicesHostTestCases
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_JAVA_LIBRARIES := cts-tradefed tradefed-prebuilt
+
+LOCAL_CTS_TEST_PACKAGE := android.server
+
+LOCAL_CTS_MODULE_CONFIG := $(LOCAL_PATH)/Old$(CTS_MODULE_TEST_CONFIG)
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+include $(BUILD_CTS_HOST_JAVA_LIBRARY)
+
+# Build the test APKs using their own makefiles
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/hostsidetests/services/activitymanager/AndroidTest.xml b/hostsidetests/services/activitymanager/AndroidTest.xml
new file mode 100644
index 0000000..641fa09
--- /dev/null
+++ b/hostsidetests/services/activitymanager/AndroidTest.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS Sample host test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsDeviceServicesTestApp.apk" />
+    </target_preparer>
+    <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
+        <option name="jar" value="CtsServicesHostTestCases.jar" />
+        <option name="runtime-hint" value="4m7s" />
+    </test>
+</configuration>
diff --git a/hostsidetests/services/activitymanager/OldAndroidTest.xml b/hostsidetests/services/activitymanager/OldAndroidTest.xml
new file mode 100644
index 0000000..37393763
--- /dev/null
+++ b/hostsidetests/services/activitymanager/OldAndroidTest.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="CTS package preparer for install/uninstall of the apk used as a test operation target">
+    <include name="common-config" />
+    <!-- This will tell tradefed to install the test apk. -->
+    <option name="cts-apk-installer:test-file-name" value="CtsDeviceServicesTestApp.apk" />
+</configuration>
diff --git a/hostsidetests/services/activitymanager/app/Android.mk b/hostsidetests/services/activitymanager/app/Android.mk
new file mode 100644
index 0000000..481a4ce
--- /dev/null
+++ b/hostsidetests/services/activitymanager/app/Android.mk
@@ -0,0 +1,31 @@
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+# Don't include this package in any target.
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_SDK_VERSION := current
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_PACKAGE_NAME := CtsDeviceServicesTestApp
+
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/services/activitymanager/app/AndroidManifest.xml b/hostsidetests/services/activitymanager/app/AndroidManifest.xml
new file mode 100755
index 0000000..1e278a0
--- /dev/null
+++ b/hostsidetests/services/activitymanager/app/AndroidManifest.xml
@@ -0,0 +1,142 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
+          package="android.server.app">
+
+    <application>
+        <activity android:name=".TestActivity"
+                android:resizeableActivity="true"
+                android:exported="true"
+        />
+        <activity android:name=".NonResizeableActivity"
+                android:resizeableActivity="false"
+                android:exported="true"
+        />
+        <activity android:name=".DockedActivity"
+                android:resizeableActivity="true"
+                android:exported="true"
+                android:taskAffinity="nobody.but.DockedActivity"
+        />
+        <activity android:name=".NoRelaunchActivity"
+                android:resizeableActivity="true"
+                android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout"
+                android:exported="true"
+                android:taskAffinity="nobody.but.NoRelaunchActivity"
+        />
+        <activity android:name=".SlowCreateActivity"
+                android:resizeableActivity="true"
+                android:exported="true"
+        />
+        <activity android:name=".LaunchToSideActivity"
+                android:resizeableActivity="true"
+                android:exported="true"
+                android:taskAffinity="nobody.but.LaunchToSideActivity"
+        />
+        <activity android:name=".PipActivity"
+                android:resizeableActivity="true"
+                android:supportsPictureInPicture="true"
+                android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout"
+                android:exported="true"
+        />
+        <activity android:name=".AutoEnterPipActivity"
+                  android:resizeableActivity="true"
+                  android:supportsPictureInPicture="true"
+                  android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout"
+                  android:exported="true"
+        />
+        <activity android:name=".AlwaysFocusablePipActivity"
+                  android:theme="@style/Theme.Transparent"
+                  android:resizeableActivity="true"
+                  android:supportsPictureInPicture="true"
+                  androidprv:alwaysFocusable="true"
+                  android:exported="true"
+                  android:taskAffinity="nobody.but.AlwaysFocusablePipActivity"
+        />
+        <activity android:name=".LaunchIntoPinnedStackPipActivity"
+                  android:resizeableActivity="true"
+                  android:supportsPictureInPicture="true"
+                  androidprv:alwaysFocusable="true"
+                  android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout"
+                  android:exported="true"
+        />
+        <activity android:name=".VisibleBehindActivity"
+                  android:resizeableActivity="true"
+                  android:supportsPictureInPicture="true"
+                  android:exported="true"
+                  android:taskAffinity="nobody.but.VisibleBehindActivity"
+        />
+        <activity android:name=".LaunchPipOnPipActivity"
+                  android:resizeableActivity="true"
+                  android:supportsPictureInPicture="true"
+                  android:taskAffinity="nobody.but.LaunchPipOnPipActivity"
+                  android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout"
+                  android:exported="true"
+        />
+        <activity android:name=".FreeformActivity"
+                  android:resizeableActivity="true"
+                  android:taskAffinity="nobody.but.FreeformActivity"
+                  android:exported="true"
+        />
+        <activity android:name=".TopLeftLayoutActivity"
+                  android:resizeableActivity="true"
+                  android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout"
+                  android:exported="true">
+                  <layout android:defaultWidth="240dp"
+                          android:defaultHeight="160dp"
+                          android:gravity="top|left"
+                          android:minimalWidth="100dp"
+                          android:minimalHeight="80dp"
+                  />
+        </activity>
+        <activity android:name=".TopRightLayoutActivity"
+                  android:resizeableActivity="true"
+                  android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout"
+                  android:exported="true">
+                  <layout android:defaultWidth="25%"
+                          android:defaultHeight="35%"
+                          android:gravity="top|right"
+                          android:minimalWidth="100dp"
+                          android:minimalHeight="80dp"
+                  />
+        </activity>
+        <activity android:name=".BottomLeftLayoutActivity"
+                  android:resizeableActivity="true"
+                  android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout"
+                  android:exported="true">
+                  <layout android:defaultWidth="25%"
+                          android:defaultHeight="35%"
+                          android:gravity="bottom|left"
+                          android:minimalWidth="100dp"
+                          android:minimalHeight="80dp"
+                  />
+        </activity>
+        <activity android:name=".BottomRightLayoutActivity"
+                  android:resizeableActivity="true"
+                  android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout"
+                  android:exported="true">
+                  <layout android:defaultWidth="240dp"
+                          android:defaultHeight="160dp"
+                          android:gravity="bottom|right"
+                          android:minimalWidth="100dp"
+                          android:minimalHeight="80dp"
+                  />
+        </activity>
+    </application>
+</manifest>
+
diff --git a/hostsidetests/services/activitymanager/app/res/values/styles.xml b/hostsidetests/services/activitymanager/app/res/values/styles.xml
new file mode 100644
index 0000000..59ebad2
--- /dev/null
+++ b/hostsidetests/services/activitymanager/app/res/values/styles.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2016 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+
+<resources>
+    <style name="Theme.Transparent" parent="android:Theme">
+        <item name="android:windowIsTranslucent">true</item>
+        <item name="android:windowBackground">@android:color/transparent</item>
+        <item name="android:windowNoTitle">true</item>
+    </style>
+</resources>
diff --git a/hostsidetests/services/activitymanager/app/src/android/server/app/AbstractLifecycleLogActivity.java b/hostsidetests/services/activitymanager/app/src/android/server/app/AbstractLifecycleLogActivity.java
new file mode 100644
index 0000000..e3026c9
--- /dev/null
+++ b/hostsidetests/services/activitymanager/app/src/android/server/app/AbstractLifecycleLogActivity.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.server.app;
+
+import android.app.Activity;
+import android.content.res.Configuration;
+import android.os.Bundle;
+import android.util.Log;
+
+public abstract class AbstractLifecycleLogActivity extends Activity {
+    @Override
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        Log.i(getTag(), "onCreate");
+    }
+
+    @Override
+    public void onConfigurationChanged(Configuration newConfig) {
+        super.onConfigurationChanged(newConfig);
+        Log.i(getTag(), "onConfigurationChanged");
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+        Log.i(getTag(), "onDestroy");
+    }
+
+    protected abstract String getTag();
+}
diff --git a/hostsidetests/services/activitymanager/app/src/android/server/app/AlwaysFocusablePipActivity.java b/hostsidetests/services/activitymanager/app/src/android/server/app/AlwaysFocusablePipActivity.java
new file mode 100644
index 0000000..3c6f6a1
--- /dev/null
+++ b/hostsidetests/services/activitymanager/app/src/android/server/app/AlwaysFocusablePipActivity.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.server.app;
+
+import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
+import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
+
+import android.app.Activity;
+import android.app.ActivityOptions;
+import android.content.Intent;
+import android.graphics.Rect;
+
+import java.lang.reflect.Method;
+
+public class AlwaysFocusablePipActivity extends Activity {
+
+    static void launchAlwaysFocusablePipActivity(Activity caller) {
+        final Intent intent = new Intent(caller, AlwaysFocusablePipActivity.class);
+        intent.setFlags(FLAG_ACTIVITY_CLEAR_TASK | FLAG_ACTIVITY_NEW_TASK);
+
+        final ActivityOptions options = ActivityOptions.makeBasic();
+        options.setLaunchBounds(new Rect(0, 0, 500, 500));
+        try {
+            setLaunchStackId(options);
+        } catch (Exception e) {
+            throw new IllegalStateException(e);
+        }
+
+        caller.startActivity(intent, options.toBundle());
+    }
+
+    /** ActivityOptions#setLaunchStackId is a @hidden API so we access it through reflection...*/
+    static void setLaunchStackId(ActivityOptions options) throws Exception {
+        final Method method = options.getClass().getDeclaredMethod(
+                "setLaunchStackId", new Class[] { int.class });
+
+        method.setAccessible(true);
+        method.invoke(options, 4 /* ActivityManager.StackId.PINNED_STACK_ID */);
+    }
+}
diff --git a/hostsidetests/services/activitymanager/app/src/android/server/app/AutoEnterPipActivity.java b/hostsidetests/services/activitymanager/app/src/android/server/app/AutoEnterPipActivity.java
new file mode 100644
index 0000000..97bc041
--- /dev/null
+++ b/hostsidetests/services/activitymanager/app/src/android/server/app/AutoEnterPipActivity.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.server.app;
+
+import android.app.Activity;
+
+public class AutoEnterPipActivity extends Activity {
+    @Override
+    protected void onResume() {
+        super.onResume();
+        enterPictureInPictureMode();
+    }
+}
diff --git a/hostsidetests/services/activitymanager/app/src/android/server/app/BottomLeftLayoutActivity.java b/hostsidetests/services/activitymanager/app/src/android/server/app/BottomLeftLayoutActivity.java
new file mode 100644
index 0000000..27a6fe2
--- /dev/null
+++ b/hostsidetests/services/activitymanager/app/src/android/server/app/BottomLeftLayoutActivity.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.server.app;
+
+import android.app.Activity;
+
+public class BottomLeftLayoutActivity extends Activity {
+}
diff --git a/hostsidetests/services/activitymanager/app/src/android/server/app/BottomRightLayoutActivity.java b/hostsidetests/services/activitymanager/app/src/android/server/app/BottomRightLayoutActivity.java
new file mode 100644
index 0000000..7a91510
--- /dev/null
+++ b/hostsidetests/services/activitymanager/app/src/android/server/app/BottomRightLayoutActivity.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.server.app;
+
+import android.app.Activity;
+
+public class BottomRightLayoutActivity extends Activity {
+}
diff --git a/hostsidetests/services/activitymanager/app/src/android/server/app/DockedActivity.java b/hostsidetests/services/activitymanager/app/src/android/server/app/DockedActivity.java
new file mode 100644
index 0000000..427fd29
--- /dev/null
+++ b/hostsidetests/services/activitymanager/app/src/android/server/app/DockedActivity.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.server.app;
+
+import android.app.Activity;
+
+public class DockedActivity extends Activity {
+}
diff --git a/hostsidetests/services/activitymanager/app/src/android/server/app/FreeformActivity.java b/hostsidetests/services/activitymanager/app/src/android/server/app/FreeformActivity.java
new file mode 100644
index 0000000..a1cb54c
--- /dev/null
+++ b/hostsidetests/services/activitymanager/app/src/android/server/app/FreeformActivity.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.server.app;
+
+import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
+import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
+
+import android.app.Activity;
+import android.app.ActivityOptions;
+import android.content.Intent;
+import android.graphics.Rect;
+
+public class FreeformActivity extends Activity {
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        final Intent intent = new Intent(this, TestActivity.class);
+        intent.setFlags(FLAG_ACTIVITY_CLEAR_TASK | FLAG_ACTIVITY_NEW_TASK);
+
+        final ActivityOptions options = ActivityOptions.makeBasic();
+        options.setLaunchBounds(new Rect(0, 0, 500, 500));
+        this.startActivity(intent, options.toBundle());
+    }
+}
diff --git a/hostsidetests/services/activitymanager/app/src/android/server/app/LaunchIntoPinnedStackPipActivity.java b/hostsidetests/services/activitymanager/app/src/android/server/app/LaunchIntoPinnedStackPipActivity.java
new file mode 100644
index 0000000..45386bf
--- /dev/null
+++ b/hostsidetests/services/activitymanager/app/src/android/server/app/LaunchIntoPinnedStackPipActivity.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.server.app;
+
+import android.app.Activity;
+
+public class LaunchIntoPinnedStackPipActivity extends Activity {
+    @Override
+    protected void onResume() {
+        super.onResume();
+        AlwaysFocusablePipActivity.launchAlwaysFocusablePipActivity(this);
+    }
+}
diff --git a/hostsidetests/services/activitymanager/app/src/android/server/app/LaunchPipOnPipActivity.java b/hostsidetests/services/activitymanager/app/src/android/server/app/LaunchPipOnPipActivity.java
new file mode 100644
index 0000000..d7b4cc1
--- /dev/null
+++ b/hostsidetests/services/activitymanager/app/src/android/server/app/LaunchPipOnPipActivity.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.server.app;
+
+import android.app.Activity;
+
+public class LaunchPipOnPipActivity extends Activity {
+    @Override
+    public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode) {
+        super.onPictureInPictureModeChanged(isInPictureInPictureMode);
+        AlwaysFocusablePipActivity.launchAlwaysFocusablePipActivity(this);
+    }
+}
diff --git a/hostsidetests/services/activitymanager/app/src/android/server/app/LaunchToSideActivity.java b/hostsidetests/services/activitymanager/app/src/android/server/app/LaunchToSideActivity.java
new file mode 100644
index 0000000..9714393
--- /dev/null
+++ b/hostsidetests/services/activitymanager/app/src/android/server/app/LaunchToSideActivity.java
@@ -0,0 +1,21 @@
+package android.server.app;
+
+import static android.content.Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT;
+import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+
+public class LaunchToSideActivity extends Activity {
+    @Override
+    protected void onNewIntent(Intent intent) {
+        super.onNewIntent(intent);
+        final Bundle extras = intent.getExtras();
+         if (extras != null && extras.getBoolean("launch_to_the_side")) {
+            Intent newIntent = new Intent(this, TestActivity.class);
+            newIntent.addFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_LAUNCH_ADJACENT);
+            startActivity(newIntent);
+        }
+    }
+}
diff --git a/hostsidetests/services/activitymanager/app/src/android/server/app/NoRelaunchActivity.java b/hostsidetests/services/activitymanager/app/src/android/server/app/NoRelaunchActivity.java
new file mode 100644
index 0000000..0058c13
--- /dev/null
+++ b/hostsidetests/services/activitymanager/app/src/android/server/app/NoRelaunchActivity.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.server.app;
+
+public class NoRelaunchActivity extends AbstractLifecycleLogActivity {
+
+    private static final String TAG = NoRelaunchActivity.class.getSimpleName();
+
+    @Override
+    protected String getTag() {
+        return TAG;
+    }
+}
diff --git a/hostsidetests/services/activitymanager/app/src/android/server/app/NonResizeableActivity.java b/hostsidetests/services/activitymanager/app/src/android/server/app/NonResizeableActivity.java
new file mode 100644
index 0000000..6312b47
--- /dev/null
+++ b/hostsidetests/services/activitymanager/app/src/android/server/app/NonResizeableActivity.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.server.app;
+
+public class NonResizeableActivity extends AbstractLifecycleLogActivity {
+
+     private static final String TAG = NonResizeableActivity.class.getSimpleName();
+
+    @Override
+    protected String getTag() {
+        return TAG;
+    }
+}
diff --git a/hostsidetests/services/activitymanager/app/src/android/server/app/PipActivity.java b/hostsidetests/services/activitymanager/app/src/android/server/app/PipActivity.java
new file mode 100644
index 0000000..b750389
--- /dev/null
+++ b/hostsidetests/services/activitymanager/app/src/android/server/app/PipActivity.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.server.app;
+
+import android.app.Activity;
+
+public class PipActivity extends Activity {
+}
diff --git a/hostsidetests/services/activitymanager/app/src/android/server/app/SlowCreateActivity.java b/hostsidetests/services/activitymanager/app/src/android/server/app/SlowCreateActivity.java
new file mode 100644
index 0000000..481f5be
--- /dev/null
+++ b/hostsidetests/services/activitymanager/app/src/android/server/app/SlowCreateActivity.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.server.app;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class SlowCreateActivity extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        try {
+            Thread.sleep(2000);
+        } catch(InterruptedException e) {}
+        super.onCreate(savedInstanceState);
+    }
+}
diff --git a/hostsidetests/services/activitymanager/app/src/android/server/app/TestActivity.java b/hostsidetests/services/activitymanager/app/src/android/server/app/TestActivity.java
new file mode 100644
index 0000000..a8e51d5
--- /dev/null
+++ b/hostsidetests/services/activitymanager/app/src/android/server/app/TestActivity.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.server.app;
+
+public class TestActivity extends AbstractLifecycleLogActivity {
+
+    private static final String TAG = TestActivity.class.getSimpleName();
+
+    @Override
+    protected String getTag() {
+        return TAG;
+    }
+}
diff --git a/hostsidetests/services/activitymanager/app/src/android/server/app/TopLeftLayoutActivity.java b/hostsidetests/services/activitymanager/app/src/android/server/app/TopLeftLayoutActivity.java
new file mode 100644
index 0000000..3a0267b
--- /dev/null
+++ b/hostsidetests/services/activitymanager/app/src/android/server/app/TopLeftLayoutActivity.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.server.app;
+
+import android.app.Activity;
+
+public class TopLeftLayoutActivity extends Activity {
+}
diff --git a/hostsidetests/services/activitymanager/app/src/android/server/app/TopRightLayoutActivity.java b/hostsidetests/services/activitymanager/app/src/android/server/app/TopRightLayoutActivity.java
new file mode 100644
index 0000000..eb3b1b0
--- /dev/null
+++ b/hostsidetests/services/activitymanager/app/src/android/server/app/TopRightLayoutActivity.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.server.app;
+
+import android.app.Activity;
+
+public class TopRightLayoutActivity extends Activity {
+}
diff --git a/hostsidetests/services/activitymanager/app/src/android/server/app/VisibleBehindActivity.java b/hostsidetests/services/activitymanager/app/src/android/server/app/VisibleBehindActivity.java
new file mode 100644
index 0000000..cc8f273
--- /dev/null
+++ b/hostsidetests/services/activitymanager/app/src/android/server/app/VisibleBehindActivity.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.server.app;
+
+import android.app.Activity;
+import android.util.Log;
+
+public class VisibleBehindActivity extends Activity {
+    private static final String TAG = "VisibleBehindActivity";
+    @Override
+    protected void onPause() {
+        super.onPause();
+        if (requestVisibleBehind(true)) {
+            Log.e(TAG, "Failed to request visibility behind...");
+        }
+    }
+}
diff --git a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityAndWindowManagersState.java b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityAndWindowManagersState.java
new file mode 100644
index 0000000..5a87b88
--- /dev/null
+++ b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityAndWindowManagersState.java
@@ -0,0 +1,306 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.server.cts;
+
+import com.android.tradefed.device.ITestDevice;
+
+import junit.framework.Assert;
+
+import android.server.cts.ActivityManagerState.ActivityStack;
+import android.server.cts.ActivityManagerState.ActivityTask;
+import android.server.cts.WindowManagerState.WindowStack;
+import android.server.cts.WindowManagerState.WindowTask;
+
+import java.awt.Rectangle;
+import java.util.Objects;
+
+import static android.server.cts.ActivityManagerTestBase.FREEFORM_WORKSPACE_STACK_ID;
+import static android.server.cts.StateLogger.log;
+
+/** Combined state of the activity manager and window manager. */
+class ActivityAndWindowManagersState extends Assert {
+
+    private ActivityManagerState mAmState = new ActivityManagerState();
+    private WindowManagerState mWmState = new WindowManagerState();
+
+    void computeState(ITestDevice device, String[] waitForActivitiesVisible) throws Exception {
+        computeState(device, waitForActivitiesVisible, true);
+    }
+
+    void computeState(ITestDevice device, String[] waitForActivitiesVisible,
+                      boolean compareTaskAndStackBounds) throws Exception {
+        computeState(device, true, waitForActivitiesVisible, compareTaskAndStackBounds);
+    }
+
+    void computeState(ITestDevice device, boolean visibleOnly, String[] waitForActivitiesVisible)
+            throws Exception {
+        computeState(device, visibleOnly, waitForActivitiesVisible, true);
+    }
+
+    void computeState(ITestDevice device, boolean visibleOnly, String[] waitForActivitiesVisible,
+                      boolean compareTaskAndStackBounds) throws Exception {
+        int retriesLeft = 5;
+        boolean retry = waitForActivitiesVisible != null && waitForActivitiesVisible.length > 0;
+        do {
+            mAmState.computeState(device);
+            mWmState.computeState(device, visibleOnly);
+            if (retry && shouldRetry(waitForActivitiesVisible)) {
+                log("***Waiting for Activities to be visible...");
+                try {
+                    Thread.sleep(1000);
+                } catch (InterruptedException e) {
+                    log(e.toString());
+                    // Well I guess we are not waiting...
+                }
+            } else {
+                retry = false;
+            }
+        } while (retry && retriesLeft-- > 0);
+
+        assertSanity();
+        assertValidBounds(compareTaskAndStackBounds);
+    }
+
+    private boolean shouldRetry(String[] waitForActivitiesVisible) {
+        if (!stackInAMAndWMAreEqual()) {
+            // We want to wait a little for the stacks in AM and WM to have equal values as there
+            // might be a transition animation ongoing when we got the states from WM AM separately.
+            log("***stackInAMAndWMAreEqual=false");
+            return true;
+        }
+        // If the caller is interested in us waiting for some particular activity windows to be
+        // visible before compute the state. Check for the visibility of those activity windows.
+        boolean allActivityWindowsVisible = true;
+        for (String activityName : waitForActivitiesVisible) {
+            final String windowName =
+                    ActivityManagerTestBase.getWindowName(activityName);
+            allActivityWindowsVisible &= mWmState.isWindowVisible(windowName);
+        }
+        log("***allActivityWindowsVisible=" + allActivityWindowsVisible);
+        return !allActivityWindowsVisible;
+    }
+
+    ActivityManagerState getAmState() {
+        return mAmState;
+    }
+
+    WindowManagerState getWmState() {
+        return mWmState;
+    }
+
+    void assertSanity() throws Exception {
+        assertTrue("Must have stacks", mAmState.getStackCount() > 0);
+        assertEquals("There should be one and only one resumed activity in the system.",
+                1, mAmState.getResumedActivitiesCount());
+        assertNotNull("Must have focus activity.", mAmState.getFocusedActivity());
+
+        for (ActivityStack aStack : mAmState.getStacks()) {
+            final int stackId = aStack.mStackId;
+            for (ActivityTask aTask : aStack.getTasks()) {
+                assertEquals("Stack can only contain its own tasks", stackId, aTask.mStackId);
+            }
+        }
+
+        assertNotNull("Must have front window.", mWmState.getFrontWindow());
+        assertNotNull("Must have focused window.", mWmState.getFocusedWindow());
+        assertNotNull("Must have app.", mWmState.getFocusedApp());
+    }
+
+    void assertContainsStack(String msg, int stackId) throws Exception {
+        assertTrue(msg, mAmState.containsStack(stackId));
+        assertTrue(msg, mWmState.containsStack(stackId));
+    }
+
+    void assertDoesNotContainStack(String msg, int stackId) throws Exception {
+        assertFalse(msg, mAmState.containsStack(stackId));
+        assertFalse(msg, mWmState.containsStack(stackId));
+    }
+
+    void assertFrontStack(String msg, int stackId) throws Exception {
+        assertEquals(msg, stackId, mAmState.getFrontStackId());
+        assertEquals(msg, stackId, mWmState.getFrontStackId());
+    }
+
+    void assertFocusedStack(String msg, int stackId) throws Exception {
+        assertEquals(msg, stackId, mAmState.getFocusedStackId());
+    }
+
+    void assertNotFocusedStack(String msg, int stackId) throws Exception {
+        if (stackId == mAmState.getFocusedStackId()) {
+            failNotEquals(msg, stackId, mAmState.getFocusedStackId());
+        }
+    }
+
+    void assertFocusedActivity(String msg, String activityName) throws Exception {
+        final String componentName = ActivityManagerTestBase.getActivityComponentName(activityName);
+        assertEquals(msg, componentName, mAmState.getFocusedActivity());
+        assertEquals(msg, componentName, mWmState.getFocusedApp());
+    }
+
+    void assertNotFocusedActivity(String msg, String activityName) throws Exception {
+        final String componentName = ActivityManagerTestBase.getActivityComponentName(activityName);
+        if (mAmState.getFocusedActivity().equals(componentName)) {
+            failNotEquals(msg, mAmState.getFocusedActivity(), componentName);
+        }
+        if (mWmState.getFocusedApp().equals(componentName)) {
+            failNotEquals(msg, mWmState.getFocusedApp(), componentName);
+        }
+    }
+
+    void assertResumedActivity(String msg, String activityName) throws Exception {
+        final String componentName = ActivityManagerTestBase.getActivityComponentName(activityName);
+        assertEquals(msg, componentName, mAmState.getResumedActivity());
+    }
+
+    void assertNotResumedActivity(String msg, String activityName) throws Exception {
+        final String componentName = ActivityManagerTestBase.getActivityComponentName(activityName);
+        if (mAmState.getResumedActivity().equals(componentName)) {
+            failNotEquals(msg, mAmState.getResumedActivity(), componentName);
+        }
+    }
+
+    void assertFocusedWindow(String msg, String windowName) {
+        assertEquals(msg, windowName, mWmState.getFocusedWindow());
+    }
+
+    void assertNotFocusedWindow(String msg, String windowName) {
+        if (mWmState.getFocusedWindow().equals(windowName)) {
+            failNotEquals(msg, mWmState.getFocusedWindow(), windowName);
+        }
+    }
+
+    void assertFrontWindow(String msg, String windowName) {
+        assertEquals(msg, windowName, mWmState.getFrontWindow());
+    }
+
+    void assertVisibility(String activityName, boolean visible) {
+        final String activityComponentName =
+                ActivityManagerTestBase.getActivityComponentName(activityName);
+        final String windowName =
+                ActivityManagerTestBase.getWindowName(activityName);
+
+        final boolean activityVisible = mAmState.isActivityVisible(activityComponentName);
+        final boolean windowVisible = mWmState.isWindowVisible(windowName);
+
+        if (visible) {
+            assertTrue("Activity=" + activityComponentName + " must be visible.", activityVisible);
+            assertTrue("Window=" + windowName + " must be visible.", windowVisible);
+        } else {
+            assertFalse("Activity=" + activityComponentName + " must NOT be visible.",
+                    activityVisible);
+            assertFalse("Window=" + windowName + " must NOT be visible.", windowVisible);
+        }
+    }
+
+    void assertHomeActivityVisible(boolean visible) {
+        final boolean activityVisible = mAmState.isHomeActivityVisible();
+
+        if (visible) {
+            assertTrue("Home activity must be visible.", activityVisible);
+        } else {
+            assertFalse("Home activity must NOT be visible.", activityVisible);
+        }
+    }
+
+    boolean stackInAMAndWMAreEqual() {
+        for (ActivityStack aStack : mAmState.getStacks()) {
+            final int stackId = aStack.mStackId;
+            final WindowStack wStack = mWmState.getStack(stackId);
+            if (wStack == null || aStack.isFullscreen() != wStack.isFullscreen()) {
+                return false;
+            }
+
+            final Rectangle aStackBounds = aStack.getBounds();
+            final Rectangle wStackBounds = wStack.getBounds();
+
+            if ((aStack.isFullscreen() && aStackBounds != null)
+                    || !Objects.equals(aStackBounds, wStackBounds)) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    void assertValidBounds(boolean compareTaskAndStackBounds) {
+        for (ActivityStack aStack : mAmState.getStacks()) {
+            final int stackId = aStack.mStackId;
+            final WindowStack wStack = mWmState.getStack(stackId);
+            assertNotNull("stackId=" + stackId + " in AM but not in WM?", wStack);
+
+            assertEquals("Stack fullscreen state in AM and WM must be equal stackId=" + stackId,
+                    aStack.isFullscreen(), wStack.isFullscreen());
+
+            final Rectangle aStackBounds = aStack.getBounds();
+            final Rectangle wStackBounds = wStack.getBounds();
+
+            if (aStack.isFullscreen()) {
+                assertNull("Stack bounds in AM must be null stackId=" + stackId, aStackBounds);
+            } else {
+                assertEquals("Stack bounds in AM and WM must be equal stackId=" + stackId,
+                        aStackBounds, wStackBounds);
+            }
+
+            for (ActivityTask aTask : aStack.getTasks()) {
+                final int taskId = aTask.mTaskId;
+                final WindowTask wTask = wStack.getTask(taskId);
+                assertNotNull(
+                        "taskId=" + taskId + " in AM but not in WM? stackId=" + stackId, wTask);
+
+                final boolean aTaskIsFullscreen = aTask.isFullscreen();
+                final boolean wTaskIsFullscreen = wTask.isFullscreen();
+                assertEquals("Task fullscreen state in AM and WM must be equal taskId=" + taskId
+                        + ", stackId=" + stackId, aTaskIsFullscreen, wTaskIsFullscreen);
+
+                final Rectangle aTaskBounds = aTask.getBounds();
+                final Rectangle wTaskBounds = wTask.getBounds();
+                final int aTaskMinWidth = aTask.getMinimalWidth();
+                final int aTaskMinHeight = aTask.getMinimalHeight();
+
+                if (aTaskIsFullscreen) {
+                    assertNull("Task bounds in AM must be null for fullscreen taskId=" + taskId,
+                            aTaskBounds);
+                } else {
+                    assertEquals("Task bounds in AM and WM must be equal taskId=" + taskId
+                            + ", stackId=" + stackId, aTaskBounds, wTaskBounds);
+
+                    if (compareTaskAndStackBounds && stackId != FREEFORM_WORKSPACE_STACK_ID) {
+                        if (aTaskMinWidth == -1 && aTaskMinHeight == -1) {
+                            // Minimal size not set for task - checking for equality of bounds with
+                            // stack.
+                            assertEquals("Task bounds must be equal to stack bounds taskId="
+                                    + taskId + ", stackId=" + stackId, aStackBounds, wTaskBounds);
+                        } else {
+                            // Minimal width and/or height set for task - bounds of task and stack
+                            // can be different.
+                            int targetWidth = aTaskMinWidth == -1
+                                    ? (int) aStackBounds.getWidth()
+                                    : (int) Math.max(aTaskMinWidth, aStackBounds.getWidth());
+                            int targetHeight = aTaskMinHeight == -1
+                                    ? (int) aStackBounds.getHeight()
+                                    : (int) Math.max(aTaskMinHeight, aStackBounds.getHeight());
+                            final Rectangle targetBounds = new Rectangle((int) aStackBounds.getX(),
+                                    (int) aStackBounds.getY(), targetWidth, targetHeight);
+                            assertEquals("Task bounds must be set according to minimal size taskId="
+                                    + taskId + ", stackId=" + stackId, targetBounds, wTaskBounds);
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerActivityVisiblityTests.java b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerActivityVisiblityTests.java
new file mode 100644
index 0000000..877e53b
--- /dev/null
+++ b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerActivityVisiblityTests.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.server.cts;
+
+import com.android.tradefed.device.DeviceNotAvailableException;
+
+import java.lang.Exception;
+import java.lang.String;
+
+public class ActivityManagerActivityVisiblityTests extends ActivityManagerTestBase {
+    private static final String TRANSLUCENT_ACTIVITY = "AlwaysFocusablePipActivity";
+    private static final String VISIBLE_BEHIND_ACTIVITY = "VisibleBehindActivity";
+    private static final String PIP_ON_PIP_ACTIVITY = "LaunchPipOnPipActivity";
+    private static final String TEST_ACTIVITY_NAME = "TestActivity";
+
+    public void testVisibleBehindHomeActivity() throws Exception {
+        mDevice.executeShellCommand(getAmStartCmd(VISIBLE_BEHIND_ACTIVITY));
+        mDevice.executeShellCommand(AM_START_HOME_ACTIVITY_COMMAND);
+
+        mAmWmState.computeState(mDevice, new String[] {VISIBLE_BEHIND_ACTIVITY});
+        mAmWmState.assertContainsStack(
+                "Must contain fullscreen stack.", FULLSCREEN_WORKSPACE_STACK_ID);
+        mAmWmState.assertFrontStack("Home stack must be the front stack.", HOME_STACK_ID);
+        mAmWmState.assertVisibility(
+                VISIBLE_BEHIND_ACTIVITY, hasDeviceFeature("android.software.leanback"));
+    }
+
+    public void testVisibleBehindOtherActivity_NotOverHome() throws Exception {
+        mDevice.executeShellCommand(getAmStartCmd(VISIBLE_BEHIND_ACTIVITY));
+        mDevice.executeShellCommand(getAmStartCmd(TRANSLUCENT_ACTIVITY));
+
+        mAmWmState.computeState(mDevice,
+                new String[] {VISIBLE_BEHIND_ACTIVITY, TRANSLUCENT_ACTIVITY});
+        mAmWmState.assertVisibility(VISIBLE_BEHIND_ACTIVITY, true);
+        mAmWmState.assertVisibility(TRANSLUCENT_ACTIVITY, true);
+    }
+
+    public void testVisibleBehindOtherActivity_OverHome() throws Exception {
+        mDevice.executeShellCommand(getAmStartCmdOverHome(VISIBLE_BEHIND_ACTIVITY));
+        mDevice.executeShellCommand(getAmStartCmdOverHome(TRANSLUCENT_ACTIVITY));
+
+        mAmWmState.computeState(mDevice,
+                new String[] {VISIBLE_BEHIND_ACTIVITY, TRANSLUCENT_ACTIVITY});
+        mAmWmState.assertVisibility(VISIBLE_BEHIND_ACTIVITY, true);
+        mAmWmState.assertVisibility(TRANSLUCENT_ACTIVITY, true);
+    }
+
+    public void testTranslucentActivityOnTopOfPinnedStack() throws Exception {
+        if (!supportsPip()) {
+            return;
+        }
+
+        mDevice.executeShellCommand(getAmStartCmdOverHome(PIP_ON_PIP_ACTIVITY));
+        // NOTE: moving to pinned stack will trigger the pip-on-pip activity to launch the
+        // translucent activity.
+        mDevice.executeShellCommand(AM_MOVE_TOP_ACTIVITY_TO_PINNED_STACK_COMMAND);
+
+        mAmWmState.computeState(mDevice, new String[] {PIP_ON_PIP_ACTIVITY, TRANSLUCENT_ACTIVITY});
+        mAmWmState.assertFrontStack("Pinned stack must be the front stack.", PINNED_STACK_ID);
+        mAmWmState.assertVisibility(PIP_ON_PIP_ACTIVITY, true);
+        mAmWmState.assertVisibility(TRANSLUCENT_ACTIVITY, true);
+    }
+
+    /**
+     * Asserts that the home activity is visible when a translucent activity is launched in the
+     * fullscreen stack over the home activity.
+     */
+    public void testTranslucentActivityOnTopOfHome() throws Exception {
+        mDevice.executeShellCommand(AM_START_HOME_ACTIVITY_COMMAND);
+        mDevice.executeShellCommand(getAmStartCmd(TRANSLUCENT_ACTIVITY));
+
+        mAmWmState.computeState(mDevice, new String[]{TRANSLUCENT_ACTIVITY});
+        mAmWmState.assertSanity();
+        mAmWmState.assertFrontStack(
+                "Fullscreen stack must be the front stack.", FULLSCREEN_WORKSPACE_STACK_ID);
+        mAmWmState.assertVisibility(TRANSLUCENT_ACTIVITY, true);
+        mAmWmState.assertHomeActivityVisible(true);
+    }
+
+    /**
+     * Assert that the home activity is visible if a task that was launched from home is pinned
+     * and also assert the next task in the fullscreen stack isn't visible.
+     */
+    public void testHomeVisibleOnActivityTaskPinned() throws Exception {
+        if (!supportsPip()) {
+            return;
+        }
+
+        mDevice.executeShellCommand(AM_START_HOME_ACTIVITY_COMMAND);
+        mDevice.executeShellCommand(getAmStartCmd(TEST_ACTIVITY_NAME));
+        mDevice.executeShellCommand(AM_START_HOME_ACTIVITY_COMMAND);
+        mDevice.executeShellCommand(getAmStartCmd(TRANSLUCENT_ACTIVITY));
+        mDevice.executeShellCommand(AM_MOVE_TOP_ACTIVITY_TO_PINNED_STACK_COMMAND);
+
+        mAmWmState.computeState(mDevice, new String[]{TRANSLUCENT_ACTIVITY});
+        mAmWmState.assertSanity();
+
+        mAmWmState.assertVisibility(TRANSLUCENT_ACTIVITY, true);
+        mAmWmState.assertVisibility(TEST_ACTIVITY_NAME, false);
+        mAmWmState.assertHomeActivityVisible(true);
+    }
+}
diff --git a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerDockedStackTests.java b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerDockedStackTests.java
new file mode 100644
index 0000000..b2163b5
--- /dev/null
+++ b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerDockedStackTests.java
@@ -0,0 +1,266 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.server.cts;
+
+import java.awt.Rectangle;
+import java.util.ArrayList;
+
+import static com.android.ddmlib.Log.LogLevel.*;
+
+public class ActivityManagerDockedStackTests extends ActivityManagerTestBase {
+
+    private static final String TEST_ACTIVITY_NAME = "TestActivity";
+    private static final String NON_RESIZEABLE_ACTIVITY_NAME = "NonResizeableActivity";
+    private static final String DOCKED_ACTIVITY_NAME = "DockedActivity";
+    private static final String LAUNCH_TO_SIDE_ACTIVITY_NAME = "LaunchToSideActivity";
+    private static final String NO_RELAUNCH_ACTIVITY_NAME = "NoRelaunchActivity";
+
+    private static final int TASK_SIZE = 600;
+    private static final int STACK_SIZE = 300;
+
+    public void testStackList() throws Exception {
+        mDevice.executeShellCommand(getAmStartCmd(TEST_ACTIVITY_NAME));
+        mAmWmState.computeState(mDevice, new String[] {TEST_ACTIVITY_NAME});
+        mAmWmState.assertContainsStack("Must contain home stack.", HOME_STACK_ID);
+        mAmWmState.assertContainsStack(
+                "Must contain fullscreen stack.", FULLSCREEN_WORKSPACE_STACK_ID);
+        mAmWmState.assertDoesNotContainStack("Must not contain docked stack.", DOCKED_STACK_ID);
+    }
+
+    public void testDockActivity() throws Exception {
+        launchActivityInDockStack(TEST_ACTIVITY_NAME);
+        mAmWmState.computeState(mDevice, new String[] {TEST_ACTIVITY_NAME});
+        mAmWmState.assertContainsStack("Must contain home stack.", HOME_STACK_ID);
+        mAmWmState.assertContainsStack("Must contain docked stack.", DOCKED_STACK_ID);
+    }
+
+    public void testNonResizeableNotDocked() throws Exception {
+        launchActivityInDockStack(NON_RESIZEABLE_ACTIVITY_NAME);
+        mAmWmState.computeState(mDevice, new String[] {NON_RESIZEABLE_ACTIVITY_NAME});
+
+        mAmWmState.assertContainsStack("Must contain home stack.", HOME_STACK_ID);
+        mAmWmState.assertDoesNotContainStack("Must not contain docked stack.", DOCKED_STACK_ID);
+        mAmWmState.assertFrontStack(
+                "Fullscreen stack must be front stack.", FULLSCREEN_WORKSPACE_STACK_ID);
+    }
+
+    public void testLaunchToSide() throws Exception {
+        launchActivityInDockStack(LAUNCH_TO_SIDE_ACTIVITY_NAME);
+        printStacksAndTasks();
+        launchActivityToSide(LAUNCH_TO_SIDE_ACTIVITY_NAME);
+        mAmWmState.computeState(mDevice, new String[] {LAUNCH_TO_SIDE_ACTIVITY_NAME});
+
+        mAmWmState.assertContainsStack(
+                "Must contain fullscreen stack.", FULLSCREEN_WORKSPACE_STACK_ID);
+        mAmWmState.assertContainsStack("Must contain docked stack.", DOCKED_STACK_ID);
+    }
+
+    public void testLaunchToSideAndBringToFront() throws Exception {
+        launchActivityInDockStack(LAUNCH_TO_SIDE_ACTIVITY_NAME);
+        printStacksAndTasks();
+        final String[] waitForFirstVisible = new String[] {TEST_ACTIVITY_NAME};
+        final String[] waitForSecondVisible = new String[] {NO_RELAUNCH_ACTIVITY_NAME};
+
+        // Launch activity to side.
+        launchActivityToSide(LAUNCH_TO_SIDE_ACTIVITY_NAME);
+        mAmWmState.computeState(mDevice, waitForFirstVisible);
+        int taskNumberInitial = mAmWmState.getAmState().getStackById(FULLSCREEN_WORKSPACE_STACK_ID)
+                .getTasks().size();
+        mAmWmState.assertFocusedActivity("Launched to side activity must be in front.",
+                TEST_ACTIVITY_NAME);
+
+        // Launch another activity to side to cover first one.
+        launchActivityInStack(NO_RELAUNCH_ACTIVITY_NAME, FULLSCREEN_WORKSPACE_STACK_ID);
+        mAmWmState.computeState(mDevice, waitForSecondVisible);
+        int taskNumberCovered = mAmWmState.getAmState().getStackById(FULLSCREEN_WORKSPACE_STACK_ID)
+                .getTasks().size();
+        mAmWmState.assertEquals("Fullscreen stack must have one task added.",
+                taskNumberInitial + 1, taskNumberCovered);
+        mAmWmState.assertFocusedActivity("Launched to side covering activity must be in front.",
+                NO_RELAUNCH_ACTIVITY_NAME);
+
+        // Launch activity that was first launched to side. It should be brought to front.
+        launchActivityToSide(LAUNCH_TO_SIDE_ACTIVITY_NAME);
+        mAmWmState.computeState(mDevice, waitForFirstVisible);
+        int taskNumberFinal = mAmWmState.getAmState().getStackById(FULLSCREEN_WORKSPACE_STACK_ID)
+                .getTasks().size();
+        mAmWmState.assertEquals("Task number in fullscreen stack must remain the same.",
+                taskNumberCovered, taskNumberFinal);
+        mAmWmState.assertFocusedActivity("Launched to side covering activity must be in front.",
+                TEST_ACTIVITY_NAME);
+    }
+
+    public void testLaunchToSideMultiple() throws Exception {
+        launchActivityInDockStack(LAUNCH_TO_SIDE_ACTIVITY_NAME);
+        printStacksAndTasks();
+        final String[] waitForActivitiesVisible = new String[] {TEST_ACTIVITY_NAME};
+
+        // Launch activity to side.
+        launchActivityToSide(LAUNCH_TO_SIDE_ACTIVITY_NAME);
+        mAmWmState.computeState(mDevice, waitForActivitiesVisible);
+        int taskNumberInitial = mAmWmState.getAmState().getStackById(FULLSCREEN_WORKSPACE_STACK_ID)
+                .getTasks().size();
+        mAmWmState.assertNotNull("Launched to side activity must be in fullscreen stack.",
+                mAmWmState.getAmState()
+                        .getTaskByActivityName(TEST_ACTIVITY_NAME, FULLSCREEN_WORKSPACE_STACK_ID));
+
+        // Try to launch to side same activity again.
+        launchActivityToSide(LAUNCH_TO_SIDE_ACTIVITY_NAME);
+        mAmWmState.computeState(mDevice, waitForActivitiesVisible);
+        int taskNumberFinal = mAmWmState.getAmState().getStackById(FULLSCREEN_WORKSPACE_STACK_ID)
+                .getTasks().size();
+        mAmWmState.assertEquals("Task number mustn't change.", taskNumberInitial, taskNumberFinal);
+        mAmWmState.assertFocusedActivity("Launched to side activity must remain in front.",
+                TEST_ACTIVITY_NAME);
+        mAmWmState.assertNotNull("Launched to side activity must remain in fullscreen stack.",
+                mAmWmState.getAmState()
+                        .getTaskByActivityName(TEST_ACTIVITY_NAME, FULLSCREEN_WORKSPACE_STACK_ID));
+    }
+
+    public void testRotationWhenDocked() throws Exception {
+        launchActivityInDockStack(LAUNCH_TO_SIDE_ACTIVITY_NAME);
+        launchActivityToSide(LAUNCH_TO_SIDE_ACTIVITY_NAME);
+        final String[] waitForActivitiesVisible = new String[] {LAUNCH_TO_SIDE_ACTIVITY_NAME};
+        mAmWmState.computeState(mDevice, waitForActivitiesVisible);
+        mAmWmState.assertContainsStack(
+                "Must contain fullscreen stack.", FULLSCREEN_WORKSPACE_STACK_ID);
+        mAmWmState.assertContainsStack("Must contain docked stack.", DOCKED_STACK_ID);
+
+        // Rotate device single steps (90°) 0-1-2-3.
+        // Each time we compute the state we implicitly assert valid bounds.
+        setDeviceRotation(0);
+        mAmWmState.computeState(mDevice, waitForActivitiesVisible);
+        setDeviceRotation(1);
+        mAmWmState.computeState(mDevice, waitForActivitiesVisible);
+        setDeviceRotation(2);
+        mAmWmState.computeState(mDevice, waitForActivitiesVisible);
+        setDeviceRotation(3);
+        mAmWmState.computeState(mDevice, waitForActivitiesVisible);
+        // Double steps (180°) We ended the single step at 3. So, we jump directly to 1 for double
+        // step. So, we are testing 3-1-3 for one side and 0-2-0 for the other side.
+        setDeviceRotation(1);
+        mAmWmState.computeState(mDevice, waitForActivitiesVisible);
+        setDeviceRotation(3);
+        mAmWmState.computeState(mDevice, waitForActivitiesVisible);
+        setDeviceRotation(0);
+        mAmWmState.computeState(mDevice, waitForActivitiesVisible);
+        setDeviceRotation(2);
+        mAmWmState.computeState(mDevice, waitForActivitiesVisible);
+        setDeviceRotation(0);
+        mAmWmState.computeState(mDevice, waitForActivitiesVisible);
+    }
+
+    public void testRotationWhenDockedWhileLocked() throws Exception {
+        launchActivityInDockStack(LAUNCH_TO_SIDE_ACTIVITY_NAME);
+        launchActivityToSide(LAUNCH_TO_SIDE_ACTIVITY_NAME);
+        final String[] waitForActivitiesVisible = new String[] {LAUNCH_TO_SIDE_ACTIVITY_NAME};
+        mAmWmState.computeState(mDevice, waitForActivitiesVisible);
+        mAmWmState.assertSanity();
+        mAmWmState.assertContainsStack(
+                "Must contain fullscreen stack.", FULLSCREEN_WORKSPACE_STACK_ID);
+        mAmWmState.assertContainsStack("Must contain docked stack.", DOCKED_STACK_ID);
+
+        lockDevice();
+        setDeviceRotation(0);
+        unlockDevice();
+        mAmWmState.computeState(mDevice, waitForActivitiesVisible);
+
+        lockDevice();
+        setDeviceRotation(1);
+        unlockDevice();
+        mAmWmState.computeState(mDevice, waitForActivitiesVisible);
+
+        lockDevice();
+        setDeviceRotation(2);
+        unlockDevice();
+        mAmWmState.computeState(mDevice, waitForActivitiesVisible);
+
+        lockDevice();
+        setDeviceRotation(3);
+        unlockDevice();
+        mAmWmState.computeState(mDevice, waitForActivitiesVisible);
+    }
+
+    public void testResizeDockedStack() throws Exception {
+        mDevice.executeShellCommand(getAmStartCmd(TEST_ACTIVITY_NAME));
+        launchActivityInDockStack(DOCKED_ACTIVITY_NAME);
+        resizeDockedStack(STACK_SIZE, STACK_SIZE, TASK_SIZE, TASK_SIZE);
+        mAmWmState.computeState(mDevice, new String[] {TEST_ACTIVITY_NAME, DOCKED_ACTIVITY_NAME},
+                false /* compareTaskAndStackBounds */);
+        mAmWmState.assertContainsStack("Must contain docked stack", DOCKED_STACK_ID);
+        mAmWmState.assertContainsStack("Must contain fullscreen stack",
+                FULLSCREEN_WORKSPACE_STACK_ID);
+        assertEquals(new Rectangle(0, 0, STACK_SIZE, STACK_SIZE),
+                mAmWmState.getAmState().getStackById(DOCKED_STACK_ID).getBounds());
+        assertEquals(new Rectangle(0, 0, TASK_SIZE, TASK_SIZE),
+                mAmWmState.getAmState().getTaskByActivityName(DOCKED_ACTIVITY_NAME).getBounds());
+        mAmWmState.assertVisibility(DOCKED_ACTIVITY_NAME, true);
+        mAmWmState.assertVisibility(TEST_ACTIVITY_NAME, true);
+    }
+
+    public void testActivityLifeCycleOnResizeDockedStack() throws Exception {
+        mDevice.executeShellCommand(getAmStartCmd(NO_RELAUNCH_ACTIVITY_NAME));
+        mAmWmState.computeState(mDevice, new String[]{NO_RELAUNCH_ACTIVITY_NAME});
+        final Rectangle fullScreenBounds =
+                mAmWmState.getWmState().getStack(FULLSCREEN_WORKSPACE_STACK_ID).getBounds();
+
+        launchActivityInDockStack(TEST_ACTIVITY_NAME);
+
+        mAmWmState.computeState(mDevice,
+                new String[]{TEST_ACTIVITY_NAME, NO_RELAUNCH_ACTIVITY_NAME});
+        final Rectangle initialDockBounds =
+                mAmWmState.getWmState().getStack(DOCKED_STACK_ID).getBounds();
+
+        clearLogcat();
+
+        Rectangle newBounds = computeNewDockBounds(fullScreenBounds, initialDockBounds, true);
+        resizeDockedStack(newBounds.width, newBounds.height, newBounds.width, newBounds.height);
+
+        // We resize twice to make sure we cross an orientation change threshold for both
+        // activities.
+        newBounds = computeNewDockBounds(fullScreenBounds, initialDockBounds, false);
+        resizeDockedStack(newBounds.width, newBounds.height, newBounds.width, newBounds.height);
+
+        mAmWmState.computeState(mDevice,
+                new String[]{TEST_ACTIVITY_NAME, NO_RELAUNCH_ACTIVITY_NAME});
+
+        assertActivityLifecycle(TEST_ACTIVITY_NAME, true);
+        assertActivityLifecycle(NO_RELAUNCH_ACTIVITY_NAME, false);
+    }
+
+    private Rectangle computeNewDockBounds(
+            Rectangle fullscreenBounds, Rectangle dockBounds, boolean reduceSize) {
+        final boolean inLandscape = fullscreenBounds.width > dockBounds.width;
+        // We are either increasing size or reducing it.
+        final float sizeChangeFactor = reduceSize ? 0.5f : 1.5f;
+        final Rectangle newBounds = new Rectangle(dockBounds);
+        if (inLandscape) {
+            // In landscape we change the width.
+            newBounds.width *= sizeChangeFactor;
+        } else {
+            // In portrait we change the height
+            newBounds.height *= sizeChangeFactor;
+        }
+
+        return newBounds;
+    }
+
+    private void launchActivityToSide(String activityName) throws Exception {
+        mDevice.executeShellCommand(
+                getAmStartCmd(activityName) + " -f 0x20000000 --ez launch_to_the_side true");
+    }
+}
diff --git a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerFreeformStackTests.java b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerFreeformStackTests.java
new file mode 100644
index 0000000..f86d9ec
--- /dev/null
+++ b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerFreeformStackTests.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.server.cts;
+
+import java.awt.Rectangle;
+import java.util.ArrayList;
+
+public class ActivityManagerFreeformStackTests extends ActivityManagerTestBase {
+
+    private static final String TEST_ACTIVITY = "TestActivity";
+    private static final int TEST_TASK_OFFSET = 20;
+    private static final int TEST_TASK_OFFSET_2 = 100;
+    private static final int TEST_TASK_SIZE_1 = 500;
+    private static final int TEST_TASK_SIZE_2 = TEST_TASK_SIZE_1 * 2;
+    // NOTE: Launching the FreeformActivity will automatically launch the TestActivity
+    // with bounds (0, 0, 500, 500)
+    private static final String FREEFORM_ACTIVITY = "FreeformActivity";
+    private static final String NON_RESIZEABLE_ACTIVITY = "NonResizeableActivity";
+    private static final String NO_RELAUNCH_ACTIVITY = "NoRelaunchActivity";
+
+    public void testFreeformWindowManagementSupport() throws Exception {
+
+        launchActivityInStack(FREEFORM_ACTIVITY, FREEFORM_WORKSPACE_STACK_ID);
+
+        mAmWmState.computeState(mDevice, new String[] {FREEFORM_ACTIVITY});
+
+        if (!supportsFreeform()) {
+            mAmWmState.assertDoesNotContainStack(
+                    "Must not contain freeform stack.", FREEFORM_WORKSPACE_STACK_ID);
+            return;
+        }
+
+        mAmWmState.assertFrontStack(
+                "Freeform stack must be the front stack.", FREEFORM_WORKSPACE_STACK_ID);
+        mAmWmState.assertVisibility(FREEFORM_ACTIVITY, true);
+        mAmWmState.assertVisibility(TEST_ACTIVITY, true);
+        mAmWmState.assertFocusedActivity(
+                TEST_ACTIVITY + " must be focused Activity", TEST_ACTIVITY);
+        assertEquals(new Rectangle(0, 0, TEST_TASK_SIZE_1, TEST_TASK_SIZE_1),
+                mAmWmState.getAmState().getTaskByActivityName(TEST_ACTIVITY).getBounds());
+    }
+
+    public void testNonResizeableActivityNotLaunchedToFreeform() throws Exception {
+        launchActivityInStack(NON_RESIZEABLE_ACTIVITY, FREEFORM_WORKSPACE_STACK_ID);
+
+        mAmWmState.computeState(mDevice, new String[] {NON_RESIZEABLE_ACTIVITY});
+
+        mAmWmState.assertFrontStack(
+                "Fullscreen stack must be the front stack.", FULLSCREEN_WORKSPACE_STACK_ID);
+        mAmWmState.assertDoesNotContainStack(
+                "Must not contain freeform stack.", FREEFORM_WORKSPACE_STACK_ID);
+    }
+
+    public void testActivityLifeCycleOnResizeFreeformTask() throws Exception {
+        launchActivityInStack(TEST_ACTIVITY, FREEFORM_WORKSPACE_STACK_ID);
+        launchActivityInStack(NO_RELAUNCH_ACTIVITY, FREEFORM_WORKSPACE_STACK_ID);
+
+        mAmWmState.computeState(mDevice, new String[]{TEST_ACTIVITY, NO_RELAUNCH_ACTIVITY});
+
+        if (!supportsFreeform()) {
+            mAmWmState.assertDoesNotContainStack(
+                    "Must not contain freeform stack.", FREEFORM_WORKSPACE_STACK_ID);
+            return;
+        }
+
+        resizeActivityTask(TEST_ACTIVITY,
+                TEST_TASK_OFFSET, TEST_TASK_OFFSET, TEST_TASK_SIZE_1, TEST_TASK_SIZE_2);
+        resizeActivityTask(NO_RELAUNCH_ACTIVITY,
+                TEST_TASK_OFFSET_2, TEST_TASK_OFFSET_2, TEST_TASK_SIZE_1, TEST_TASK_SIZE_2);
+
+        mAmWmState.computeState(mDevice, new String[]{TEST_ACTIVITY, NO_RELAUNCH_ACTIVITY});
+
+        clearLogcat();
+        resizeActivityTask(TEST_ACTIVITY,
+                TEST_TASK_OFFSET, TEST_TASK_OFFSET, TEST_TASK_SIZE_2, TEST_TASK_SIZE_1);
+        resizeActivityTask(NO_RELAUNCH_ACTIVITY,
+                TEST_TASK_OFFSET_2, TEST_TASK_OFFSET_2, TEST_TASK_SIZE_2, TEST_TASK_SIZE_1);
+        mAmWmState.computeState(mDevice, new String[]{TEST_ACTIVITY, NO_RELAUNCH_ACTIVITY});
+
+        assertActivityLifecycle(TEST_ACTIVITY, true);
+        assertActivityLifecycle(NO_RELAUNCH_ACTIVITY, false);
+    }
+}
diff --git a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerManifestLayoutTests.java b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerManifestLayoutTests.java
new file mode 100644
index 0000000..cc6dd1e
--- /dev/null
+++ b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerManifestLayoutTests.java
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.server.cts;
+
+import java.lang.Exception;
+import java.lang.String;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import junit.framework.Assert;
+
+import java.awt.Rectangle;
+import android.server.cts.WindowManagerState.WindowState;
+import android.server.cts.WindowManagerState.Display;
+
+import static com.android.ddmlib.Log.LogLevel.INFO;
+
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.log.LogUtil.CLog;
+
+public class ActivityManagerManifestLayoutTests extends ActivityManagerTestBase {
+
+    // Clone of android DisplayMetrics.DENSITY_DEFAULT (DENSITY_MEDIUM)
+    // (Needed in host-side test to convert dp to px.)
+    private static final int DISPLAY_DENSITY_DEFAULT = 160;
+
+    // Test parameters
+    private static final int DEFAULT_WIDTH_DP = 240;
+    private static final int DEFAULT_HEIGHT_DP = 160;
+    private static final float DEFAULT_WIDTH_FRACTION = 0.25f;
+    private static final float DEFAULT_HEIGHT_FRACTION = 0.35f;
+    private static final int MINIMAL_WIDTH_DP = 100;
+    private static final int MINIMAL_HEIGHT_DP = 80;
+
+    private static final int GRAVITY_VER_CENTER = 0x01;
+    private static final int GRAVITY_VER_TOP    = 0x02;
+    private static final int GRAVITY_VER_BOTTOM = 0x04;
+    private static final int GRAVITY_HOR_CENTER = 0x10;
+    private static final int GRAVITY_HOR_LEFT   = 0x20;
+    private static final int GRAVITY_HOR_RIGHT  = 0x40;
+
+    private List<WindowState> mTempWindowList = new ArrayList();
+    private Display mDisplay;
+    private WindowState mWindowState;
+
+    public void testGravityAndDefaultSizeTopLeft() throws Exception {
+        testLayout(GRAVITY_VER_TOP, GRAVITY_HOR_LEFT, false /*fraction*/);
+    }
+
+    public void testGravityAndDefaultSizeTopRight() throws Exception {
+        testLayout(GRAVITY_VER_TOP, GRAVITY_HOR_RIGHT, true /*fraction*/);
+    }
+
+    public void testGravityAndDefaultSizeBottomLeft() throws Exception {
+        testLayout(GRAVITY_VER_BOTTOM, GRAVITY_HOR_LEFT, true /*fraction*/);
+    }
+
+    public void testGravityAndDefaultSizeBottomRight() throws Exception {
+        testLayout(GRAVITY_VER_BOTTOM, GRAVITY_HOR_RIGHT, false /*fraction*/);
+    }
+
+    public void testMinimalSizeFreeform() throws Exception {
+        if (!supportsFreeform()) {
+            CLog.logAndDisplay(INFO, "Skipping test: no freeform support");
+            return;
+        }
+        testMinimalSize(FREEFORM_WORKSPACE_STACK_ID);
+    }
+
+    public void testMinimalSizeDocked() throws Exception {
+        testMinimalSize(DOCKED_STACK_ID);
+    }
+
+    private void testMinimalSize(int stackId) throws Exception {
+        final String activityName = "BottomRightLayoutActivity";
+
+        // Issue command to resize to <0,0,1,1>. We expect the size to be floored at
+        // MINIMAL_WIDTH_DPxMINIMAL_HEIGHT_DP.
+        if (stackId == FREEFORM_WORKSPACE_STACK_ID) {
+            launchActivityInStack(activityName, stackId);
+            resizeActivityTask(activityName, 0, 0, 1, 1);
+        } else { // stackId == DOCKED_STACK_ID
+            launchActivityInDockStack(activityName);
+            resizeDockedStack(1, 1, 1, 1);
+        }
+        getDisplayAndWindowState(activityName);
+
+        final int minimalWidth = dpToPx(MINIMAL_WIDTH_DP, mDisplay.getDpi());
+        final int minimalHeight = dpToPx(MINIMAL_HEIGHT_DP, mDisplay.getDpi());
+        final Rectangle containingRect = mWindowState.getContainingFrame();
+
+        Assert.assertEquals("Minimum width is incorrect", minimalWidth, containingRect.width);
+        Assert.assertEquals("Minimum height is incorrect", minimalHeight, containingRect.height);
+    }
+
+    private void testLayout(
+            int vGravity, int hGravity, boolean fraction) throws Exception {
+        if (!supportsFreeform()) {
+            CLog.logAndDisplay(INFO, "Skipping test: no freeform support");
+            return;
+        }
+
+        final String activityName = (vGravity == GRAVITY_VER_TOP ? "Top" : "Bottom")
+                + (hGravity == GRAVITY_HOR_LEFT ? "Left" : "Right") + "LayoutActivity";
+
+        // Launch in freeform stack
+        launchActivityInStack(activityName, FREEFORM_WORKSPACE_STACK_ID);
+
+        getDisplayAndWindowState(activityName);
+
+        final Rectangle containingRect = mWindowState.getContainingFrame();
+        final Rectangle appRect = mDisplay.getAppRect();
+        final int expectedWidthPx, expectedHeightPx;
+        // Evaluate the expected window size in px. If we're using fraction dimensions,
+        // calculate the size based on the app rect size. Otherwise, convert the expected
+        // size in dp to px.
+        if (fraction) {
+            expectedWidthPx = (int) (appRect.width * DEFAULT_WIDTH_FRACTION);
+            expectedHeightPx = (int) (appRect.height * DEFAULT_HEIGHT_FRACTION);
+        } else {
+            final int densityDpi = mDisplay.getDpi();
+            expectedWidthPx = dpToPx(DEFAULT_WIDTH_DP, densityDpi);
+            expectedHeightPx = dpToPx(DEFAULT_HEIGHT_DP, densityDpi);
+        }
+
+        verifyFrameSizeAndPosition(
+                vGravity, hGravity, expectedWidthPx, expectedHeightPx, containingRect, appRect);
+    }
+
+    private void getDisplayAndWindowState(String activityName) throws Exception {
+        final String windowName = getWindowName(activityName);
+
+        mAmWmState.computeState(mDevice, true /* visibleOnly */, new String[] {activityName});
+
+        mAmWmState.assertFocusedWindow("Test window must be the front window.", windowName);
+
+        mAmWmState.getWmState().getMatchingWindowState(windowName, mTempWindowList);
+
+        Assert.assertEquals("Should have exactly one window state for the activity.",
+                1, mTempWindowList.size());
+
+        mWindowState = mTempWindowList.get(0);
+        Assert.assertNotNull("Should have a valid window", mWindowState);
+
+        mDisplay = mAmWmState.getWmState().getDisplay(mWindowState.getDisplayId());
+        Assert.assertNotNull("Should be on a display", mDisplay);
+    }
+
+    private void verifyFrameSizeAndPosition(
+            int vGravity, int hGravity, int expectedWidthPx, int expectedHeightPx,
+            Rectangle containingFrame, Rectangle parentFrame) {
+        Assert.assertEquals("Width is incorrect", expectedWidthPx, containingFrame.width);
+        Assert.assertEquals("Height is incorrect", expectedHeightPx, containingFrame.height);
+
+        if (vGravity == GRAVITY_VER_TOP) {
+            Assert.assertEquals("Should be on the top", parentFrame.y, containingFrame.y);
+        } else if (vGravity == GRAVITY_VER_BOTTOM) {
+            Assert.assertEquals("Should be on the bottom",
+                    parentFrame.y + parentFrame.height, containingFrame.y + containingFrame.height);
+        }
+
+        if (hGravity == GRAVITY_HOR_LEFT) {
+            Assert.assertEquals("Should be on the left", parentFrame.x, containingFrame.x);
+        } else if (hGravity == GRAVITY_HOR_RIGHT){
+            Assert.assertEquals("Should be on the right",
+                    parentFrame.x + parentFrame.width, containingFrame.x + containingFrame.width);
+        }
+    }
+
+    private static int dpToPx(float dp, int densityDpi){
+        return (int) (dp * densityDpi / DISPLAY_DENSITY_DEFAULT + 0.5f);
+    }
+}
diff --git a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerPinnedStackTests.java b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerPinnedStackTests.java
new file mode 100644
index 0000000..c57b648
--- /dev/null
+++ b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerPinnedStackTests.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.server.cts;
+
+import java.lang.Exception;
+import java.lang.String;
+
+public class ActivityManagerPinnedStackTests extends ActivityManagerTestBase {
+    private static final String PIP_ACTIVITY = "PipActivity";
+    private static final String AUTO_ENTER_PIP_ACTIVITY = "AutoEnterPipActivity";
+    private static final String ALWAYS_FOCUSABLE_PIP_ACTIVITY = "AlwaysFocusablePipActivity";
+    private static final String LAUNCH_INTO_PINNED_STACK_PIP_ACTIVITY =
+            "LaunchIntoPinnedStackPipActivity";
+
+    public void testEnterPictureInPictureMode() throws Exception {
+        pinnedStackTester(AUTO_ENTER_PIP_ACTIVITY, AUTO_ENTER_PIP_ACTIVITY, false, false);
+    }
+
+    public void testMoveTopActivityToPinnedStack() throws Exception {
+        pinnedStackTester(PIP_ACTIVITY, PIP_ACTIVITY, true, false);
+    }
+
+    public void testAlwaysFocusablePipActivity() throws Exception {
+        pinnedStackTester(ALWAYS_FOCUSABLE_PIP_ACTIVITY, ALWAYS_FOCUSABLE_PIP_ACTIVITY, true, true);
+    }
+
+    public void testLaunchIntoPinnedStack() throws Exception {
+        pinnedStackTester(
+                LAUNCH_INTO_PINNED_STACK_PIP_ACTIVITY, ALWAYS_FOCUSABLE_PIP_ACTIVITY, false, true);
+    }
+
+    private void pinnedStackTester(String startActivity, String topActiviyName,
+            boolean moveTopToPinnedStack, boolean isFocusable) throws Exception {
+
+        mDevice.executeShellCommand(getAmStartCmd(startActivity));
+        if (moveTopToPinnedStack) {
+            mDevice.executeShellCommand(AM_MOVE_TOP_ACTIVITY_TO_PINNED_STACK_COMMAND);
+        }
+
+        mAmWmState.computeState(mDevice, new String[] {topActiviyName});
+
+        if (supportsPip()) {
+            final String windowName = getWindowName(topActiviyName);
+            mAmWmState.assertContainsStack("Must contain pinned stack.", PINNED_STACK_ID);
+            mAmWmState.assertFrontStack("Pinned stack must be the front stack.", PINNED_STACK_ID);
+            mAmWmState.assertVisibility(topActiviyName, true);
+
+            if (isFocusable) {
+                mAmWmState.assertFocusedStack(
+                        "Pinned stack must be the focused stack.", PINNED_STACK_ID);
+                mAmWmState.assertFocusedActivity(
+                        "Pinned activity must be focused activity.", topActiviyName);
+                mAmWmState.assertResumedActivity(
+                        "Pinned activity must be the resumed activity.", topActiviyName);
+                mAmWmState.assertFocusedWindow(
+                        "Pinned window must be focused window.", windowName);
+            } else {
+                mAmWmState.assertNotFocusedStack(
+                        "Pinned stack can't be the focused stack.", PINNED_STACK_ID);
+                mAmWmState.assertNotFocusedActivity(
+                        "Pinned stack can't be the focused activity.", topActiviyName);
+                mAmWmState.assertNotResumedActivity(
+                        "Pinned stack can't be the resumed activity.", topActiviyName);
+                mAmWmState.assertNotFocusedWindow(
+                        "Pinned window can't be focused window.", windowName);
+            }
+        } else {
+            mAmWmState.assertDoesNotContainStack(
+                    "Must not contain pinned stack.", PINNED_STACK_ID);
+        }
+    }
+}
diff --git a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerReplaceWindowTests.java b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerReplaceWindowTests.java
new file mode 100644
index 0000000..624128b
--- /dev/null
+++ b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerReplaceWindowTests.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.server.cts;
+
+import java.lang.Exception;
+import java.lang.String;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import junit.framework.Assert;
+
+import static com.android.ddmlib.Log.LogLevel.INFO;
+
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.log.LogUtil.CLog;
+
+public class ActivityManagerReplaceWindowTests extends ActivityManagerTestBase {
+
+    private static final String SLOW_CREATE_ACTIVITY_NAME = "SlowCreateActivity";
+    private static final String NO_RELAUNCH_ACTIVITY_NAME = "NoRelaunchActivity";
+
+    private static final String AM_MOVE_TASK = "am stack movetask ";
+
+    private List<String> mTempWindowTokens = new ArrayList();
+
+    public void testReplaceWindow_Dock_Relaunch() throws Exception {
+        testReplaceWindow_Dock(true);
+    }
+
+    public void testReplaceWindow_Dock_NoRelaunch() throws Exception {
+        testReplaceWindow_Dock(false);
+    }
+
+    private void testReplaceWindow_Dock(boolean relaunch) throws Exception {
+        final String activityName =
+                relaunch ? SLOW_CREATE_ACTIVITY_NAME : NO_RELAUNCH_ACTIVITY_NAME;
+        final String windowName = getWindowName(activityName);
+        final String amStartCmd = getAmStartCmd(activityName);
+
+        mDevice.executeShellCommand(amStartCmd);
+
+        // Sleep 2 seconds, then check if the window is started properly.
+        // SlowCreateActivity will do a sleep inside its onCreate() to simulate a
+        // slow-starting app. So instead of relying on WindowManagerState's
+        // retrying mechanism, we do an explicit sleep to avoid excess spews
+        // from WindowManagerState.
+        if (SLOW_CREATE_ACTIVITY_NAME.equals(activityName)) {
+            Thread.sleep(2000);
+        }
+
+        CLog.logAndDisplay(INFO, "==========Before Docking========");
+        final String oldToken = getFocusedWindowToken(windowName, activityName, true);
+
+        // Move to docked stack
+        final int taskId = getActivityTaskId(activityName);
+        final String cmd = AM_MOVE_TASK + taskId + " " + DOCKED_STACK_ID + " true";
+        mDevice.executeShellCommand(cmd);
+
+        // Sleep 5 seconds, then check if the window is replaced properly.
+        Thread.sleep(5000);
+
+        CLog.logAndDisplay(INFO, "==========After Docking========");
+        final String newToken = getFocusedWindowToken(windowName, activityName, false);
+
+        // For both relaunch and not relaunch case, we'd like the window to be kept.
+        Assert.assertEquals("Window replaced while docking.", oldToken, newToken);
+    }
+
+    private String getFocusedWindowToken(
+            String windowName, String activityName, boolean visibleOnly)
+            throws Exception {
+        mAmWmState.computeState(mDevice, visibleOnly, new String[] {activityName});
+
+        mAmWmState.assertFocusedWindow("Test window must be the front window.",
+                windowName);
+
+        mAmWmState.getWmState().getMatchingWindowTokens(windowName, mTempWindowTokens);
+
+        Assert.assertEquals("Should have exactly one window for the activity.",
+                1, mTempWindowTokens.size());
+
+        return mTempWindowTokens.get(0);
+    }
+}
diff --git a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerState.java b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerState.java
new file mode 100644
index 0000000..fbe119f
--- /dev/null
+++ b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerState.java
@@ -0,0 +1,615 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.server.cts;
+
+import com.android.tradefed.device.CollectingOutputReceiver;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+
+import java.awt.Rectangle;
+import java.lang.Integer;
+import java.lang.String;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+
+import java.util.regex.Pattern;
+import java.util.regex.Matcher;
+
+import static android.server.cts.ActivityManagerTestBase.HOME_STACK_ID;
+import static android.server.cts.StateLogger.log;
+
+class ActivityManagerState {
+    private static final String DUMPSYS_ACTIVITY_ACTIVITIES = "dumpsys activity activities";
+
+    // Copied from ActivityRecord.java
+    private static final int APPLICATION_ACTIVITY_TYPE = 0;
+    private static final int HOME_ACTIVITY_TYPE = 1;
+    private static final int RECENTS_ACTIVITY_TYPE = 2;
+
+    private final Pattern mStackIdPattern = Pattern.compile("Stack #(\\d+)\\:");
+    private final Pattern mFocusedActivityPattern =
+            Pattern.compile("mFocusedActivity\\: ActivityRecord\\{(.+) u(\\d+) (\\S+) (\\S+)\\}");
+    private final Pattern mFocusedStackPattern =
+            Pattern.compile("mFocusedStack=ActivityStack\\{(.+) stackId=(\\d+), (.+)");
+
+    private final Pattern[] mExtractStackExitPatterns =
+            { mStackIdPattern, mFocusedActivityPattern, mFocusedStackPattern};
+
+    // Stacks in z-order with the top most at the front of the list.
+    private final List<ActivityStack> mStacks = new ArrayList();
+    private int mFocusedStackId = -1;
+    private String mFocusedActivityRecord = null;
+    private final List<String> mResumedActivities = new ArrayList();
+    private final LinkedList<String> mSysDump = new LinkedList();
+
+    void computeState(ITestDevice device) throws DeviceNotAvailableException {
+        // It is possible the system is in the middle of transition to the right state when we get
+        // the dump. We try a few times to get the information we need before giving up.
+        int retriesLeft = 3;
+        boolean retry = false;
+        String dump = null;
+
+        log("==============================");
+        log("     ActivityManagerState     ");
+        log("==============================");
+
+        do {
+            if (retry) {
+                log("***Incomplete AM state. Retrying...");
+                // Wait half a second between retries for activity manager to finish transitioning.
+                try {
+                    Thread.sleep(500);
+                } catch (InterruptedException e) {
+                    log(e.toString());
+                    // Well I guess we are not waiting...
+                }
+            }
+
+            final CollectingOutputReceiver outputReceiver = new CollectingOutputReceiver();
+            device.executeShellCommand(DUMPSYS_ACTIVITY_ACTIVITIES, outputReceiver);
+            dump = outputReceiver.getOutput();
+            parseSysDump(dump);
+
+            retry = mStacks.isEmpty() || mFocusedStackId == -1 || mFocusedActivityRecord == null
+                    || mResumedActivities.isEmpty();
+        } while (retry && retriesLeft-- > 0);
+
+        if (retry) {
+            log(dump);
+        }
+
+        if (mStacks.isEmpty()) {
+            log("No stacks found...");
+        }
+        if (mFocusedStackId == -1) {
+            log("No focused stack found...");
+        }
+        if (mFocusedActivityRecord == null) {
+            log("No focused activity found...");
+        }
+        if (mResumedActivities.isEmpty()) {
+            log("No resumed activities found...");
+        }
+    }
+
+    private void parseSysDump(String sysDump) {
+        reset();
+
+        Collections.addAll(mSysDump, sysDump.split("\\n"));
+
+        while (!mSysDump.isEmpty()) {
+            final ActivityStack stack =
+                    ActivityStack.create(mSysDump, mStackIdPattern, mExtractStackExitPatterns);
+
+            if (stack != null) {
+                mStacks.add(stack);
+                if (stack.mResumedActivity != null) {
+                    mResumedActivities.add(stack.mResumedActivity);
+                }
+                continue;
+            }
+
+            final String line = mSysDump.pop().trim();
+
+            Matcher matcher = mFocusedStackPattern.matcher(line);
+            if (matcher.matches()) {
+                log(line);
+                final String stackId = matcher.group(2);
+                log(stackId);
+                mFocusedStackId = Integer.parseInt(stackId);
+                continue;
+            }
+
+            matcher = mFocusedActivityPattern.matcher(line);
+            if (matcher.matches()) {
+                log(line);
+                mFocusedActivityRecord = matcher.group(3);
+                log(mFocusedActivityRecord);
+                continue;
+            }
+        }
+    }
+
+    private void reset() {
+        mStacks.clear();
+        mFocusedStackId = -1;
+        mFocusedActivityRecord = null;
+        mResumedActivities.clear();
+        mSysDump.clear();
+    }
+
+    int getFrontStackId() {
+        return mStacks.get(0).mStackId;
+    }
+
+    int getFocusedStackId() {
+        return mFocusedStackId;
+    }
+
+    String getFocusedActivity() {
+        return mFocusedActivityRecord;
+    }
+
+    String getResumedActivity() {
+        return mResumedActivities.get(0);
+    }
+
+    int getResumedActivitiesCount() {
+        return mResumedActivities.size();
+    }
+
+    boolean containsStack(int stackId) {
+        for (ActivityStack stack : mStacks) {
+            if (stackId == stack.mStackId) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    ActivityStack getStackById(int stackId) {
+        for (ActivityStack stack : mStacks) {
+            if (stackId == stack.mStackId) {
+                return stack;
+            }
+        }
+        return null;
+    }
+
+    List<ActivityStack> getStacks() {
+        return new ArrayList(mStacks);
+    }
+
+    int getStackCount() {
+        return mStacks.size();
+    }
+
+    boolean isActivityVisible(String activityName) {
+        for (ActivityStack stack : mStacks) {
+            for (ActivityTask task : stack.mTasks) {
+               for (Activity activity : task.mActivities) {
+                   if (activity.name.equals(activityName)) {
+                       return activity.visible;
+                   }
+               }
+            }
+        }
+        return false;
+    }
+
+    boolean isHomeActivityVisible() {
+        final Activity homeActivity = getHomeActivity();
+        return homeActivity != null && homeActivity.visible;
+    }
+
+    private Activity getHomeActivity() {
+        for (ActivityStack stack : mStacks) {
+            if (stack.mStackId != HOME_STACK_ID) {
+                continue;
+            }
+
+            for (ActivityTask task : stack.mTasks) {
+                if (task.mTaskType != HOME_ACTIVITY_TYPE) {
+                    continue;
+                }
+                return task.mActivities.get(task.mActivities.size() - 1);
+            }
+
+            return null;
+        }
+        return null;
+    }
+
+    ActivityTask getTaskByActivityName(String activityName) {
+        return getTaskByActivityName(activityName, -1);
+    }
+
+    ActivityTask getTaskByActivityName(String activityName, int stackId) {
+        String fullName = ActivityManagerTestBase.getActivityComponentName(activityName);
+        for (ActivityStack stack : mStacks) {
+            if (stackId == -1 || stackId == stack.mStackId) {
+                for (ActivityTask task : stack.mTasks) {
+                    for (Activity activity : task.mActivities) {
+                        if (activity.name.equals(fullName)) {
+                            return task;
+                        }
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+    static class ActivityStack extends ActivityContainer {
+
+        private static final Pattern TASK_ID_PATTERN = Pattern.compile("Task id #(\\d+)");
+        private static final Pattern RESUMED_ACTIVITY_PATTERN = Pattern.compile(
+                "mResumedActivity\\: ActivityRecord\\{(.+) u(\\d+) (\\S+) (\\S+)\\}");
+
+        int mStackId;
+        String mResumedActivity;
+        ArrayList<ActivityTask> mTasks = new ArrayList();
+
+        private ActivityStack() {
+        }
+
+        static ActivityStack create(
+                LinkedList<String> dump, Pattern stackIdPattern, Pattern[] exitPatterns) {
+            final String line = dump.peek().trim();
+
+            final Matcher matcher = stackIdPattern.matcher(line);
+            if (!matcher.matches()) {
+                // Not a stack.
+                return null;
+            }
+            // For the stack Id line we just read.
+            dump.pop();
+
+            final ActivityStack stack = new ActivityStack();
+            log(line);
+            final String stackId = matcher.group(1);
+            log(stackId);
+            stack.mStackId = Integer.parseInt(stackId);
+            stack.extract(dump, exitPatterns);
+            return stack;
+        }
+
+        private void extract(LinkedList<String> dump, Pattern[] exitPatterns) {
+
+            final List<Pattern> taskExitPatterns = new ArrayList();
+            Collections.addAll(taskExitPatterns, exitPatterns);
+            taskExitPatterns.add(TASK_ID_PATTERN);
+            taskExitPatterns.add(RESUMED_ACTIVITY_PATTERN);
+            final Pattern[] taskExitPatternsArray =
+                    taskExitPatterns.toArray(new Pattern[taskExitPatterns.size()]);
+
+            while (!doneExtracting(dump, exitPatterns)) {
+                final ActivityTask task =
+                        ActivityTask.create(dump, TASK_ID_PATTERN, taskExitPatternsArray);
+
+                if (task != null) {
+                    mTasks.add(task);
+                    continue;
+                }
+
+                final String line = dump.pop().trim();
+
+                if (extractFullscreen(line)) {
+                    continue;
+                }
+
+                if (extractBounds(line)) {
+                    continue;
+                }
+
+                Matcher matcher = RESUMED_ACTIVITY_PATTERN.matcher(line);
+                if (matcher.matches()) {
+                    log(line);
+                    mResumedActivity = matcher.group(3);
+                    log(mResumedActivity);
+                    continue;
+                }
+            }
+        }
+
+        List<ActivityTask> getTasks() {
+            return new ArrayList(mTasks);
+        }
+    }
+
+    static class ActivityTask extends ActivityContainer {
+        private static final Pattern TASK_RECORD_PATTERN = Pattern.compile("\\* TaskRecord\\"
+                + "{(\\S+) #(\\d+) (\\S+)=(\\S+) U=(\\d+) StackId=(\\d+) sz=(\\d+)\\}");
+
+        private static final Pattern LAST_NON_FULLSCREEN_BOUNDS_PATTERN = Pattern.compile(
+                "mLastNonFullscreenBounds=Rect\\((\\d+), (\\d+) - (\\d+), (\\d+)\\)");
+
+        private static final Pattern ORIG_ACTIVITY_PATTERN = Pattern.compile("origActivity=(\\S+)");
+        private static final Pattern REAL_ACTIVITY_PATTERN = Pattern.compile("realActivity=(\\S+)");
+
+        private static final Pattern ACTIVITY_NAME_PATTERN = Pattern.compile(
+                "\\* Hist #(\\d+)\\: ActivityRecord\\{(\\S+) u(\\d+) (\\S+) t(\\d+)\\}");
+
+        private static final Pattern TASK_TYPE_PATTERN = Pattern.compile("autoRemoveRecents=(\\S+) "
+                + "isPersistable=(\\S+) numFullscreen=(\\d+) taskType=(\\d+) "
+                + "mTaskToReturnTo=(\\d+)");
+
+        int mTaskId;
+        int mStackId;
+        Rectangle mLastNonFullscreenBounds;
+        String mRealActivity;
+        String mOrigActivity;
+        ArrayList<Activity> mActivities = new ArrayList();
+        int mTaskType = -1;
+        int mReturnToType = -1;
+
+        private ActivityTask() {
+        }
+
+        static ActivityTask create(
+                LinkedList<String> dump, Pattern taskIdPattern, Pattern[] exitPatterns) {
+            final String line = dump.peek().trim();
+
+            final Matcher matcher = taskIdPattern.matcher(line);
+            if (!matcher.matches()) {
+                // Not a task.
+                return null;
+            }
+            // For the task Id line we just read.
+            dump.pop();
+
+            final ActivityTask task = new ActivityTask();
+            log(line);
+            final String taskId = matcher.group(1);
+            log(taskId);
+            task.mTaskId = Integer.parseInt(taskId);
+            task.extract(dump, exitPatterns);
+            return task;
+        }
+
+        private void extract(LinkedList<String> dump, Pattern[] exitPatterns) {
+            final List<Pattern> activityExitPatterns = new ArrayList();
+            Collections.addAll(activityExitPatterns, exitPatterns);
+            activityExitPatterns.add(ACTIVITY_NAME_PATTERN);
+            final Pattern[] activityExitPatternsArray =
+                    activityExitPatterns.toArray(new Pattern[activityExitPatterns.size()]);
+
+            while (!doneExtracting(dump, exitPatterns)) {
+                final Activity activity =
+                        Activity.create(dump, ACTIVITY_NAME_PATTERN, activityExitPatternsArray);
+
+                if (activity != null) {
+                    mActivities.add(activity);
+                    continue;
+                }
+
+                final String line = dump.pop().trim();
+
+                if (extractFullscreen(line)) {
+                    continue;
+                }
+
+                if (extractBounds(line)) {
+                    continue;
+                }
+
+                if (extractMinimalSize(line)) {
+                    continue;
+                }
+
+                Matcher matcher = TASK_RECORD_PATTERN.matcher(line);
+                if (matcher.matches()) {
+                    log(line);
+                    final String stackId = matcher.group(6);
+                    mStackId = Integer.valueOf(stackId);
+                    log(stackId);
+                    continue;
+                }
+
+                matcher = LAST_NON_FULLSCREEN_BOUNDS_PATTERN.matcher(line);
+                if (matcher.matches()) {
+                    log(line);
+                    mLastNonFullscreenBounds = extractBounds(matcher);
+                }
+
+                matcher = REAL_ACTIVITY_PATTERN.matcher(line);
+                if (matcher.matches()) {
+                    if (mRealActivity == null) {
+                        log(line);
+                        mRealActivity = matcher.group(1);
+                        log(mRealActivity);
+                    }
+                    continue;
+                }
+
+                matcher = ORIG_ACTIVITY_PATTERN.matcher(line);
+                if (matcher.matches()) {
+                    if (mOrigActivity == null) {
+                        log(line);
+                        mOrigActivity = matcher.group(1);
+                        log(mOrigActivity);
+                    }
+                    continue;
+                }
+
+                matcher = TASK_TYPE_PATTERN.matcher(line);
+                if (matcher.matches()) {
+                    log(line);
+                    mTaskType = Integer.valueOf(matcher.group(4));
+                    mReturnToType = Integer.valueOf(matcher.group(5));
+                    continue;
+                }
+            }
+        }
+    }
+
+    static class Activity {
+        private static final Pattern VISIBILITY_PATTERN = Pattern.compile("keysPaused=(\\S+) "
+                + "inHistory=(\\S+) visible=(\\S+) sleeping=(\\S+) idle=(\\S+) "
+                + "mStartingWindowState=(\\S+)");
+        private static final Pattern FRONT_OF_TASK_PATTERN = Pattern.compile("frontOfTask=(\\S+) "
+                + "task=TaskRecord\\{(\\S+) #(\\d+) A=(\\S+) U=(\\d+) StackId=(\\d+) sz=(\\d+)\\}");
+
+        String name;
+        boolean visible;
+        boolean frontOfTask;
+
+        private Activity() {
+        }
+
+        static Activity create(
+                LinkedList<String> dump, Pattern activityNamePattern, Pattern[] exitPatterns) {
+            final String line = dump.peek().trim();
+
+            final Matcher matcher = activityNamePattern.matcher(line);
+            if (!matcher.matches()) {
+                // Not an activity.
+                return null;
+            }
+            // For the activity name line we just read.
+            dump.pop();
+
+            final Activity activity = new Activity();
+            log(line);
+            activity.name = matcher.group(4);
+            log(activity.name);
+            activity.extract(dump, exitPatterns);
+            return activity;
+        }
+
+        private void extract(LinkedList<String> dump, Pattern[] exitPatterns) {
+
+            while (!doneExtracting(dump, exitPatterns)) {
+                final String line = dump.pop().trim();
+
+                Matcher matcher = VISIBILITY_PATTERN.matcher(line);
+                if (matcher.matches()) {
+                    log(line);
+                    final String visibleString = matcher.group(3);
+                    visible = Boolean.valueOf(visibleString);
+                    log(visibleString);
+                    continue;
+                }
+
+                matcher = FRONT_OF_TASK_PATTERN.matcher(line);
+                if (matcher.matches()) {
+                    log(line);
+                    final String frontOfTaskString = matcher.group(1);
+                    frontOfTask = Boolean.valueOf(frontOfTaskString);
+                    log(frontOfTaskString);
+                    continue;
+                }
+            }
+        }
+    }
+
+    static abstract class ActivityContainer {
+        protected static final Pattern FULLSCREEN_PATTERN = Pattern.compile("mFullscreen=(\\S+)");
+        protected static final Pattern BOUNDS_PATTERN =
+                Pattern.compile("mBounds=Rect\\((\\d+), (\\d+) - (\\d+), (\\d+)\\)");
+        protected static final Pattern MINIMAL_WIDTH_PATTERN =
+                Pattern.compile("mMinimalWidth=(\\d+)");
+        protected static final Pattern MINIMAL_HEIGHT_PATTERN =
+                Pattern.compile("mMinimalHeight=(\\d+)");
+
+        protected boolean mFullscreen;
+        protected Rectangle mBounds;
+        protected int mMinimalWidth = -1;
+        protected int mMinimalHeight = -1;
+
+        boolean extractFullscreen(String line) {
+            final Matcher matcher = FULLSCREEN_PATTERN.matcher(line);
+            if (!matcher.matches()) {
+                return false;
+            }
+            log(line);
+            final String fullscreen = matcher.group(1);
+            log(fullscreen);
+            mFullscreen = Boolean.valueOf(fullscreen);
+            return true;
+        }
+
+        boolean extractBounds(String line) {
+            final Matcher matcher = BOUNDS_PATTERN.matcher(line);
+            if (!matcher.matches()) {
+                return false;
+            }
+            log(line);
+            mBounds = extractBounds(matcher);
+            return true;
+        }
+
+        static Rectangle extractBounds(Matcher matcher) {
+            final int left = Integer.valueOf(matcher.group(1));
+            final int top = Integer.valueOf(matcher.group(2));
+            final int right = Integer.valueOf(matcher.group(3));
+            final int bottom = Integer.valueOf(matcher.group(4));
+            final Rectangle rect = new Rectangle(left, top, right - left, bottom - top);
+
+            log(rect.toString());
+            return rect;
+        }
+
+        boolean extractMinimalSize(String line) {
+            final Matcher minWidthMatcher = MINIMAL_WIDTH_PATTERN.matcher(line);
+            final Matcher minHeightMatcher = MINIMAL_HEIGHT_PATTERN.matcher(line);
+
+            if (minWidthMatcher.matches()) {
+                log(line);
+                mMinimalWidth = Integer.valueOf(minWidthMatcher.group(1));
+            } else if (minHeightMatcher.matches()) {
+                log(line);
+                mMinimalHeight = Integer.valueOf(minHeightMatcher.group(1));
+            } else {
+                return false;
+            }
+            return true;
+        }
+
+        Rectangle getBounds() {
+            return mBounds;
+        }
+
+        boolean isFullscreen() {
+            return mFullscreen;
+        }
+
+        int getMinimalWidth() {
+            return mMinimalWidth;
+        }
+
+        int getMinimalHeight() {
+            return mMinimalHeight;
+        }
+    }
+
+    static boolean doneExtracting(LinkedList<String> dump, Pattern[] exitPatterns) {
+        if (dump.isEmpty()) {
+            return true;
+        }
+        final String line = dump.peek().trim();
+
+        for (Pattern pattern : exitPatterns) {
+            if (pattern.matcher(line).matches()) {
+                return true;
+            }
+        }
+        return false;
+    }
+}
diff --git a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerTestBase.java b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerTestBase.java
new file mode 100644
index 0000000..b8f5fff
--- /dev/null
+++ b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerTestBase.java
@@ -0,0 +1,319 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.server.cts;
+
+import com.android.ddmlib.Log.LogLevel;
+import com.android.tradefed.device.CollectingOutputReceiver;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.log.LogUtil.CLog;
+import com.android.tradefed.testtype.DeviceTestCase;
+
+import java.lang.Exception;
+import java.lang.Integer;
+import java.lang.String;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public abstract class ActivityManagerTestBase extends DeviceTestCase {
+    private static final boolean PRETEND_DEVICE_SUPPORTS_PIP = false;
+    private static final boolean PRETEND_DEVICE_SUPPORTS_FREEFORM = false;
+
+    // Constants copied from ActivityManager.StackId. If they are changed there, these must be
+    // updated.
+    /** First static stack ID. */
+    public static final int FIRST_STATIC_STACK_ID = 0;
+
+    /** Home activity stack ID. */
+    public static final int HOME_STACK_ID = FIRST_STATIC_STACK_ID;
+
+    /** ID of stack where fullscreen activities are normally launched into. */
+    public static final int FULLSCREEN_WORKSPACE_STACK_ID = 1;
+
+    /** ID of stack where freeform/resized activities are normally launched into. */
+    public static final int FREEFORM_WORKSPACE_STACK_ID = FULLSCREEN_WORKSPACE_STACK_ID + 1;
+
+    /** ID of stack that occupies a dedicated region of the screen. */
+    public static final int DOCKED_STACK_ID = FREEFORM_WORKSPACE_STACK_ID + 1;
+
+    /** ID of stack that always on top (always visible) when it exist. */
+    public static final int PINNED_STACK_ID = DOCKED_STACK_ID + 1;
+
+    private static final String TASK_ID_PREFIX = "taskId";
+
+    private static final String AM_STACK_LIST = "am stack list";
+
+    private static final String AM_FORCE_STOP_TEST_PACKAGE = "am force-stop android.server.app";
+
+    private static final String AM_REMOVE_STACK = "am stack remove ";
+
+    protected static final String AM_START_HOME_ACTIVITY_COMMAND =
+            "am start -a android.intent.action.MAIN -c android.intent.category.HOME";
+
+    protected static final String AM_MOVE_TOP_ACTIVITY_TO_PINNED_STACK_COMMAND =
+            "am stack move-top-activity-to-pinned-stack 1 0 0 500 500";
+
+    private static final String AM_RESIZE_DOCKED_STACK = "am stack resize-docked-stack ";
+
+    private static final String AM_MOVE_TASK = "am stack movetask ";
+
+    /** A reference to the device under test. */
+    protected ITestDevice mDevice;
+
+    private HashSet<String> mAvailableFeatures;
+
+    protected static String getAmStartCmd(final String activityName) {
+        return "am start -n " + getActivityComponentName(activityName);
+    }
+
+    protected static String getAmStartCmdOverHome(final String activityName) {
+        return "am start --activity-task-on-home -n " + getActivityComponentName(activityName);
+    }
+
+    static String getActivityComponentName(final String activityName) {
+        return "android.server.app/." + activityName;
+    }
+
+    static String getWindowName(final String activityName) {
+        return "android.server.app/android.server.app." + activityName;
+    }
+
+    protected ActivityAndWindowManagersState mAmWmState = new ActivityAndWindowManagersState();
+
+    private int mInitialAccelerometerRotation;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        // Get the device, this gives a handle to run commands and install APKs.
+        mDevice = getDevice();
+        mInitialAccelerometerRotation = getAccelerometerRotation();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+        try {
+            mDevice.executeShellCommand(AM_FORCE_STOP_TEST_PACKAGE);
+            setAccelerometerRotation(mInitialAccelerometerRotation);
+            // Remove special stacks.
+            mDevice.executeShellCommand(AM_REMOVE_STACK + PINNED_STACK_ID);
+            mDevice.executeShellCommand(AM_REMOVE_STACK + DOCKED_STACK_ID);
+            mDevice.executeShellCommand(AM_REMOVE_STACK + FREEFORM_WORKSPACE_STACK_ID);
+        } catch (DeviceNotAvailableException e) {
+        }
+    }
+
+    protected void launchActivityInStack(String activityName, int stackId) throws Exception {
+        mDevice.executeShellCommand(getAmStartCmd(activityName) + " --stack " + stackId);
+    }
+
+    protected void launchActivityInDockStack(String activityName) throws Exception {
+        mDevice.executeShellCommand(getAmStartCmd(activityName));
+        final int taskId = getActivityTaskId(activityName);
+        final String cmd = AM_MOVE_TASK + taskId + " " + DOCKED_STACK_ID + " true";
+        mDevice.executeShellCommand(cmd);
+    }
+
+    protected void resizeActivityTask(String activityName, int left, int top, int right, int bottom)
+            throws Exception {
+        final int taskId = getActivityTaskId(activityName);
+        final String cmd = "am task resize "
+                + taskId + " " + left + " " + top + " " + right + " " + bottom;
+        mDevice.executeShellCommand(cmd);
+    }
+
+    protected void resizeDockedStack(
+            int stackWidth, int stackHeight, int taskWidth, int taskHeight)
+                    throws DeviceNotAvailableException {
+        mDevice.executeShellCommand(AM_RESIZE_DOCKED_STACK
+                + "0 0 " + stackWidth + " " + stackHeight
+                + " 0 0 " + taskWidth + " " + taskHeight);
+    }
+
+    // Utility method for debugging, not used directly here, but useful, so kept around.
+    protected void printStacksAndTasks() throws DeviceNotAvailableException {
+        CollectingOutputReceiver outputReceiver = new CollectingOutputReceiver();
+        mDevice.executeShellCommand(AM_STACK_LIST, outputReceiver);
+        String output = outputReceiver.getOutput();
+        for (String line : output.split("\\n")) {
+            CLog.logAndDisplay(LogLevel.INFO, line);
+        }
+    }
+
+    protected int getActivityTaskId(String name) throws DeviceNotAvailableException {
+        CollectingOutputReceiver outputReceiver = new CollectingOutputReceiver();
+        mDevice.executeShellCommand(AM_STACK_LIST, outputReceiver);
+        final String output = outputReceiver.getOutput();
+        for (String line : output.split("\\n")) {
+            if (line.contains(name)) {
+                for (String word : line.split("\\s+")) {
+                    if (word.startsWith(TASK_ID_PREFIX)) {
+                        final String withColon = word.split("=")[1];
+                        return Integer.parseInt(withColon.substring(0, withColon.length() - 1));
+                    }
+                }
+            }
+        }
+        return -1;
+    }
+
+    protected boolean supportsPip() throws DeviceNotAvailableException {
+        return hasDeviceFeature("android.software.picture_in_picture")
+                || PRETEND_DEVICE_SUPPORTS_PIP;
+    }
+
+    protected boolean supportsFreeform() throws DeviceNotAvailableException {
+        return hasDeviceFeature("android.software.freeform_window_management")
+                || PRETEND_DEVICE_SUPPORTS_FREEFORM;
+    }
+
+    protected boolean hasDeviceFeature(String requiredFeature) throws DeviceNotAvailableException {
+        if (mAvailableFeatures == null) {
+            // TODO: Move this logic to ITestDevice.
+            final String output = runCommandAndPrintOutput("pm list features");
+
+            // Extract the id of the new user.
+            mAvailableFeatures = new HashSet<>();
+            for (String feature: output.split("\\s+")) {
+                // Each line in the output of the command has the format "feature:{FEATURE_VALUE}".
+                String[] tokens = feature.split(":");
+                assertTrue("\"" + feature + "\" expected to have format feature:{FEATURE_VALUE}",
+                        tokens.length > 1);
+                assertEquals(feature, "feature", tokens[0]);
+                mAvailableFeatures.add(tokens[1]);
+            }
+        }
+        boolean result = mAvailableFeatures.contains(requiredFeature);
+        if (!result) {
+            CLog.logAndDisplay(LogLevel.INFO, "Device doesn't support " + requiredFeature);
+        }
+        return result;
+    }
+
+    protected void lockDevice() throws DeviceNotAvailableException {
+        runCommandAndPrintOutput("input keyevent 26");
+    }
+
+    protected void unlockDevice() throws DeviceNotAvailableException {
+        runCommandAndPrintOutput("input keyevent 26");
+        runCommandAndPrintOutput("input keyevent 82");
+    }
+
+    protected void setDeviceRotation(int rotation) throws DeviceNotAvailableException {
+        setAccelerometerRotation(0);
+        runCommandAndPrintOutput("settings put system user_rotation " + rotation);
+    }
+
+    private int getAccelerometerRotation() throws DeviceNotAvailableException {
+        final String rotation =
+                runCommandAndPrintOutput("settings get system accelerometer_rotation");
+        return Integer.valueOf(rotation.trim());
+    }
+
+    private void setAccelerometerRotation(int rotation) throws DeviceNotAvailableException {
+        runCommandAndPrintOutput(
+                "settings put system accelerometer_rotation " + rotation);
+    }
+
+    protected String runCommandAndPrintOutput(String command) throws DeviceNotAvailableException {
+        final String output = mDevice.executeShellCommand(command);
+        CLog.logAndDisplay(LogLevel.INFO, command);
+        CLog.logAndDisplay(LogLevel.INFO, output);
+        return output;
+    }
+
+    protected void clearLogcat() throws DeviceNotAvailableException {
+        mDevice.executeAdbCommand("logcat", "-c");
+    }
+
+    protected void assertActivityLifecycle(String activityName, boolean relaunched)
+            throws DeviceNotAvailableException {
+        final ActivityLifecycleCounts lifecycleCounts = new ActivityLifecycleCounts(activityName);
+
+        if (relaunched) {
+            if (lifecycleCounts.mDestroyCount < 1) {
+                fail(activityName + " must have been destroyed. mDestroyCount="
+                        + lifecycleCounts.mDestroyCount);
+            }
+            if (lifecycleCounts.mCreateCount < 1) {
+                fail(activityName + " must have been (re)created. mCreateCount="
+                        + lifecycleCounts.mCreateCount);
+            }
+        } else {
+            if (lifecycleCounts.mDestroyCount > 0) {
+                fail(activityName + " must *NOT* have been destroyed. mDestroyCount="
+                        + lifecycleCounts.mDestroyCount);
+            }
+            if (lifecycleCounts.mCreateCount > 0) {
+                fail(activityName + " must *NOT* have been (re)created. mCreateCount="
+                        + lifecycleCounts.mCreateCount);
+            }
+            if (lifecycleCounts.mConfigurationChangedCount < 1) {
+                fail(activityName + " must have received configuration changed. "
+                        + "mConfigurationChangedCount="
+                        + lifecycleCounts.mConfigurationChangedCount);
+            }
+        }
+    }
+
+    private class ActivityLifecycleCounts {
+
+        private final Pattern mCreatePattern = Pattern.compile("(.+): onCreate");
+        private final Pattern mConfigurationChangedPattern =
+                Pattern.compile("(.+): onConfigurationChanged");
+        private final Pattern mDestroyPattern = Pattern.compile("(.+): onDestroy");
+
+        private final LinkedList<String> mLogs = new LinkedList();
+        int mCreateCount;
+        int mConfigurationChangedCount;
+        int mDestroyCount;
+
+        public ActivityLifecycleCounts(String activityName) throws DeviceNotAvailableException {
+
+            final String logs = mDevice.executeAdbCommand(
+                    "logcat", "-v", "brief", "-d", activityName + ":I", "*:S");
+            Collections.addAll(mLogs, logs.split("\\n"));
+
+            while (!mLogs.isEmpty()) {
+                final String line = mLogs.pop().trim();
+
+                Matcher matcher = mCreatePattern.matcher(line);
+                if (matcher.matches()) {
+                    mCreateCount++;
+                    continue;
+                }
+
+                matcher = mConfigurationChangedPattern.matcher(line);
+                if (matcher.matches()) {
+                    mConfigurationChangedCount++;
+                    continue;
+                }
+
+                matcher = mDestroyPattern.matcher(line);
+                if (matcher.matches()) {
+                    mDestroyCount++;
+                    continue;
+                }
+            }
+        }
+    }
+}
diff --git a/hostsidetests/services/activitymanager/src/android/server/cts/StateLogger.java b/hostsidetests/services/activitymanager/src/android/server/cts/StateLogger.java
new file mode 100644
index 0000000..1266102
--- /dev/null
+++ b/hostsidetests/services/activitymanager/src/android/server/cts/StateLogger.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.server.cts;
+
+import com.android.tradefed.log.LogUtil.CLog;
+
+import static com.android.ddmlib.Log.LogLevel.INFO;
+
+/**
+ * Util class to perform simple state logging.
+ */
+public class StateLogger {
+    private static final boolean DEBUG = false;
+
+    /** Simple info-level logging gated by {@link #DEBUG} flag */
+    public static void log(String logText) {
+        if (DEBUG) {
+            CLog.logAndDisplay(INFO, logText);
+        }
+    }
+}
diff --git a/hostsidetests/services/activitymanager/src/android/server/cts/WindowManagerState.java b/hostsidetests/services/activitymanager/src/android/server/cts/WindowManagerState.java
new file mode 100644
index 0000000..ffa3b83
--- /dev/null
+++ b/hostsidetests/services/activitymanager/src/android/server/cts/WindowManagerState.java
@@ -0,0 +1,686 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.server.cts;
+
+import com.android.tradefed.device.CollectingOutputReceiver;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.log.LogUtil.CLog;
+
+import java.awt.Rectangle;
+import java.lang.String;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+
+import java.util.regex.Pattern;
+import java.util.regex.Matcher;
+
+import static android.server.cts.StateLogger.log;
+
+class WindowManagerState {
+    private static final String DUMPSYS_WINDOWS_APPS = "dumpsys window apps";
+    private static final String DUMPSYS_WINDOWS_VISIBLE_APPS = "dumpsys window visible-apps";
+
+    private static final Pattern sWindowPattern =
+            Pattern.compile("Window #(\\d+) Window\\{([0-9a-fA-F]+) u(\\d+) (.+)\\}\\:");
+    private static final Pattern sStartingWindowPattern =
+            Pattern.compile("Window #(\\d+) Window\\{([0-9a-fA-F]+) u(\\d+) Starting (.+)\\}\\:");
+    private static final Pattern sExitingWindowPattern =
+            Pattern.compile("Window #(\\d+) Window\\{([0-9a-fA-F]+) u(\\d+) (.+) EXITING\\}\\:");
+
+    private static final Pattern sFocusedWindowPattern = Pattern.compile(
+            "mCurrentFocus=Window\\{([0-9a-fA-F]+) u(\\d+) (\\S+)\\}");
+    private static final Pattern sAppErrorFocusedWindowPattern = Pattern.compile(
+            "mCurrentFocus=Window\\{([0-9a-fA-F]+) u(\\d+) Application Error\\: (\\S+)\\}");
+
+    private static final Pattern sFocusedAppPattern =
+            Pattern.compile("mFocusedApp=AppWindowToken\\{(.+) token=Token\\{(.+) "
+                    + "ActivityRecord\\{(.+) u(\\d+) (\\S+) (\\S+)");
+
+    private static final Pattern sStackIdPattern = Pattern.compile("mStackId=(\\d+)");
+
+    private static final Pattern[] sExtractStackExitPatterns = {
+            sStackIdPattern, sWindowPattern, sStartingWindowPattern, sExitingWindowPattern,
+            sFocusedWindowPattern, sAppErrorFocusedWindowPattern, sFocusedAppPattern };
+
+    // Windows in z-order with the top most at the front of the list.
+    private List<String> mWindows = new ArrayList();
+    private List<WindowState> mWindowStates = new ArrayList();
+    private List<WindowStack> mStacks = new ArrayList();
+    private List<Display> mDisplays = new ArrayList();
+    private String mFocusedWindow = null;
+    private String mFocusedApp = null;
+    private final LinkedList<String> mSysDump = new LinkedList();
+
+    void computeState(ITestDevice device, boolean visibleOnly) throws DeviceNotAvailableException {
+        // It is possible the system is in the middle of transition to the right state when we get
+        // the dump. We try a few times to get the information we need before giving up.
+        int retriesLeft = 3;
+        boolean retry = false;
+        String dump = null;
+
+        log("==============================");
+        log("      WindowManagerState      ");
+        log("==============================");
+        do {
+            if (retry) {
+                log("***Incomplete WM state. Retrying...");
+                // Wait half a second between retries for window manager to finish transitioning...
+                try {
+                    Thread.sleep(500);
+                } catch (InterruptedException e) {
+                    log(e.toString());
+                    // Well I guess we are not waiting...
+                }
+            }
+
+            final CollectingOutputReceiver outputReceiver = new CollectingOutputReceiver();
+            final String dumpsysCmd = visibleOnly ?
+                    DUMPSYS_WINDOWS_VISIBLE_APPS : DUMPSYS_WINDOWS_APPS;
+            device.executeShellCommand(dumpsysCmd, outputReceiver);
+            dump = outputReceiver.getOutput();
+            parseSysDump(dump, visibleOnly);
+
+            retry = mWindows.isEmpty() || mFocusedWindow == null || mFocusedApp == null;
+        } while (retry && retriesLeft-- > 0);
+
+        if (retry) {
+            log(dump);
+        }
+
+        if (mWindows.isEmpty()) {
+            log("No Windows found...");
+        }
+        if (mFocusedWindow == null) {
+            log("No Focused Window...");
+        }
+        if (mFocusedApp == null) {
+            log("No Focused App...");
+        }
+    }
+
+    private void parseSysDump(String sysDump, boolean visibleOnly) {
+        reset();
+
+        Collections.addAll(mSysDump, sysDump.split("\\n"));
+
+        while (!mSysDump.isEmpty()) {
+            final Display display =
+                    Display.create(mSysDump, sExtractStackExitPatterns);
+            if (display != null) {
+                log(display.toString());
+                mDisplays.add(display);
+                continue;
+            }
+
+            final WindowStack stack =
+                    WindowStack.create(mSysDump, sStackIdPattern, sExtractStackExitPatterns);
+
+            if (stack != null) {
+                mStacks.add(stack);
+                continue;
+            }
+
+
+            final WindowState ws = WindowState.create(mSysDump, sExtractStackExitPatterns);
+            if (ws != null) {
+                log(ws.toString());
+
+                if (visibleOnly && mWindows.isEmpty()) {
+                    // This is the front window. Check to see if we are in the middle of
+                    // transitioning. If we are, we want to skip dumping until window manager is
+                    // done transitioning the top window.
+                    if (ws.isStartingWindow()) {
+                        log("Skipping dump due to starting window transition...");
+                        return;
+                    }
+
+                    if (ws.isExitingWindow()) {
+                        log("Skipping dump due to exiting window transition...");
+                        return;
+                    }
+                }
+
+                mWindows.add(ws.getName());
+                mWindowStates.add(ws);
+                continue;
+            }
+
+            final String line = mSysDump.pop().trim();
+
+            Matcher matcher = sFocusedWindowPattern.matcher(line);
+            if (matcher.matches()) {
+                log(line);
+                final String focusedWindow = matcher.group(3);
+                log(focusedWindow);
+                mFocusedWindow = focusedWindow;
+                continue;
+            }
+
+            matcher = sAppErrorFocusedWindowPattern.matcher(line);
+            if (matcher.matches()) {
+                log(line);
+                final String focusedWindow = matcher.group(3);
+                log(focusedWindow);
+                mFocusedWindow = focusedWindow;
+                continue;
+            }
+
+            matcher = sFocusedAppPattern.matcher(line);
+            if (matcher.matches()) {
+                log(line);
+                final String focusedApp = matcher.group(5);
+                log(focusedApp);
+                mFocusedApp = focusedApp;
+                continue;
+            }
+        }
+    }
+
+    void getMatchingWindowTokens(final String windowName, List<String> tokenList) {
+        tokenList.clear();
+
+        for (WindowState ws : mWindowStates) {
+            if (windowName.equals(ws.getName())) {
+                tokenList.add(ws.getToken());
+            }
+        }
+    }
+
+    void getMatchingWindowState(final String windowName, List<WindowState> windowList) {
+        windowList.clear();
+        for (WindowState ws : mWindowStates) {
+            if (windowName.equals(ws.getName())) {
+                windowList.add(ws);
+            }
+        }
+    }
+
+    Display getDisplay(int displayId) {
+        for (Display display : mDisplays) {
+            if (displayId == display.getDisplayId()) {
+                return display;
+            }
+        }
+        return null;
+    }
+
+    String getFrontWindow() {
+        return mWindows.get(0);
+    }
+
+    String getFocusedWindow() {
+        return mFocusedWindow;
+    }
+
+    String getFocusedApp() {
+        return mFocusedApp;
+    }
+
+    int getFrontStackId() {
+        return mStacks.get(0).mStackId;
+    }
+
+    boolean containsStack(int stackId) {
+        for (WindowStack stack : mStacks) {
+            if (stackId == stack.mStackId) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    boolean isWindowVisible(String windowName) {
+        for (String window : mWindows) {
+            if (window.equals(windowName)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    WindowStack getStack(int stackId) {
+        for (WindowStack stack : mStacks) {
+            if (stackId == stack.mStackId) {
+                return stack;
+            }
+        }
+        return null;
+    }
+
+    private void reset() {
+        mSysDump.clear();
+        mStacks.clear();
+        mDisplays.clear();
+        mWindows.clear();
+        mWindowStates.clear();
+        mFocusedWindow = null;
+        mFocusedApp = null;
+    }
+
+    static class WindowStack extends WindowContainer {
+
+        private static final Pattern sTaskIdPattern = Pattern.compile("taskId=(\\d+)");
+
+        int mStackId;
+        ArrayList<WindowTask> mTasks = new ArrayList();
+
+        private WindowStack() {
+
+        }
+
+        static WindowStack create(
+                LinkedList<String> dump, Pattern stackIdPattern, Pattern[] exitPatterns) {
+            final String line = dump.peek().trim();
+
+            final Matcher matcher = stackIdPattern.matcher(line);
+            if (!matcher.matches()) {
+                // Not a stack.
+                return null;
+            }
+            // For the stack Id line we just read.
+            dump.pop();
+
+            final WindowStack stack = new WindowStack();
+            log(line);
+            final String stackId = matcher.group(1);
+            log(stackId);
+            stack.mStackId = Integer.parseInt(stackId);
+            stack.extract(dump, exitPatterns);
+            return stack;
+        }
+
+        void extract(LinkedList<String> dump, Pattern[] exitPatterns) {
+
+            final List<Pattern> taskExitPatterns = new ArrayList();
+            Collections.addAll(taskExitPatterns, exitPatterns);
+            taskExitPatterns.add(sTaskIdPattern);
+            final Pattern[] taskExitPatternsArray =
+                    taskExitPatterns.toArray(new Pattern[taskExitPatterns.size()]);
+
+            while (!doneExtracting(dump, exitPatterns)) {
+                final WindowTask task =
+                        WindowTask.create(dump, sTaskIdPattern, taskExitPatternsArray);
+
+                if (task != null) {
+                    mTasks.add(task);
+                    continue;
+                }
+
+                final String line = dump.pop().trim();
+
+                if (extractFullscreen(line)) {
+                    continue;
+                }
+
+                if (extractBounds(line)) {
+                    continue;
+                }
+            }
+        }
+
+        WindowTask getTask(int taskId) {
+            for (WindowTask task : mTasks) {
+                if (taskId == task.mTaskId) {
+                    return task;
+                }
+            }
+            return null;
+        }
+    }
+
+    static class WindowTask extends WindowContainer {
+        private static final Pattern sTempInsetBoundsPattern =
+                Pattern.compile("mTempInsetBounds=\\[(\\d+),(\\d+)\\]\\[(\\d+),(\\d+)\\]");
+
+        private static final Pattern sAppTokenPattern = Pattern.compile(
+                "Activity #(\\d+) AppWindowToken\\{(\\S+) token=Token\\{(\\S+) "
+                + "ActivityRecord\\{(\\S+) u(\\d+) (\\S+) t(\\d+)\\}\\}\\}");
+
+
+        int mTaskId;
+        Rectangle mTempInsetBounds;
+        List<String> mAppTokens = new ArrayList();
+
+        private WindowTask() {
+        }
+
+        static WindowTask create(
+                LinkedList<String> dump, Pattern taskIdPattern, Pattern[] exitPatterns) {
+            final String line = dump.peek().trim();
+
+            final Matcher matcher = taskIdPattern.matcher(line);
+            if (!matcher.matches()) {
+                // Not a task.
+                return null;
+            }
+            // For the task Id line we just read.
+            dump.pop();
+
+            final WindowTask task = new WindowTask();
+            log(line);
+            final String taskId = matcher.group(1);
+            log(taskId);
+            task.mTaskId = Integer.parseInt(taskId);
+            task.extract(dump, exitPatterns);
+            return task;
+        }
+
+        private void extract(LinkedList<String> dump, Pattern[] exitPatterns) {
+
+            while (!doneExtracting(dump, exitPatterns)) {
+                final String line = dump.pop().trim();
+
+                if (extractFullscreen(line)) {
+                    continue;
+                }
+
+                if (extractBounds(line)) {
+                    continue;
+                }
+
+                Matcher matcher = sTempInsetBoundsPattern.matcher(line);
+                if (matcher.matches()) {
+                    log(line);
+                    mTempInsetBounds = extractBounds(matcher);
+                }
+
+                matcher = sAppTokenPattern.matcher(line);
+                if (matcher.matches()) {
+                    log(line);
+                    final String appToken = matcher.group(6);
+                    log(appToken);
+                    mAppTokens.add(appToken);
+                    continue;
+                }
+            }
+        }
+    }
+
+    static abstract class WindowContainer {
+        protected static final Pattern sFullscreenPattern = Pattern.compile("mFullscreen=(\\S+)");
+        protected static final Pattern sBoundsPattern =
+                Pattern.compile("mBounds=\\[(\\d+),(\\d+)\\]\\[(\\d+),(\\d+)\\]");
+
+        protected boolean mFullscreen;
+        protected Rectangle mBounds;
+
+        static boolean doneExtracting(LinkedList<String> dump, Pattern[] exitPatterns) {
+            if (dump.isEmpty()) {
+                return true;
+            }
+            final String line = dump.peek().trim();
+
+            for (Pattern pattern : exitPatterns) {
+                if (pattern.matcher(line).matches()) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        boolean extractFullscreen(String line) {
+            final Matcher matcher = sFullscreenPattern.matcher(line);
+            if (!matcher.matches()) {
+                return false;
+            }
+            log(line);
+            final String fullscreen = matcher.group(1);
+            log(fullscreen);
+            mFullscreen = Boolean.valueOf(fullscreen);
+            return true;
+        }
+
+        boolean extractBounds(String line) {
+            final Matcher matcher = sBoundsPattern.matcher(line);
+            if (!matcher.matches()) {
+                return false;
+            }
+            log(line);
+            mBounds = extractBounds(matcher);
+            return true;
+        }
+
+        static Rectangle extractBounds(Matcher matcher) {
+            final int left = Integer.valueOf(matcher.group(1));
+            final int top = Integer.valueOf(matcher.group(2));
+            final int right = Integer.valueOf(matcher.group(3));
+            final int bottom = Integer.valueOf(matcher.group(4));
+            final Rectangle rect = new Rectangle(left, top, right - left, bottom - top);
+
+            log(rect.toString());
+            return rect;
+        }
+
+        static void extractMultipleBounds(Matcher matcher, int groupIndex, Rectangle... rectList) {
+            for (Rectangle rect : rectList) {
+                if (rect == null) {
+                    return;
+                }
+                final int left = Integer.valueOf(matcher.group(groupIndex++));
+                final int top = Integer.valueOf(matcher.group(groupIndex++));
+                final int right = Integer.valueOf(matcher.group(groupIndex++));
+                final int bottom = Integer.valueOf(matcher.group(groupIndex++));
+                rect.setBounds(left, top, right - left, bottom - top);
+            }
+        }
+
+        Rectangle getBounds() {
+            return mBounds;
+        }
+
+        boolean isFullscreen() {
+            return mFullscreen;
+        }
+    }
+
+    static class Display extends WindowContainer {
+        private static final String TAG = "[Display] ";
+
+        private static final Pattern sDisplayIdPattern =
+                Pattern.compile("Display: mDisplayId=(\\d+)");
+        private static final Pattern sDisplayInfoPattern =
+                Pattern.compile("(.+) (\\d+)dpi cur=(\\d+)x(\\d+) app=(\\d+)x(\\d+) (.+)");
+
+        private final int mDisplayId;
+        private Rectangle mDisplayRect = new Rectangle();
+        private Rectangle mAppRect = new Rectangle();
+        private int mDpi;
+
+        private Display(int displayId) {
+            mDisplayId = displayId;
+        }
+
+        int getDisplayId() {
+            return mDisplayId;
+        }
+
+        int getDpi() {
+            return mDpi;
+        }
+
+        Rectangle getDisplayRect() {
+            return mDisplayRect;
+        }
+
+        Rectangle getAppRect() {
+            return mAppRect;
+        }
+
+        static Display create(LinkedList<String> dump, Pattern[] exitPatterns) {
+            // TODO: exit pattern for displays?
+            final String line = dump.peek().trim();
+
+            Matcher matcher = sDisplayIdPattern.matcher(line);
+            if (!matcher.matches()) {
+                return null;
+            }
+
+            log(TAG + "DISPLAY_ID: " + line);
+            dump.pop();
+
+            final int displayId = Integer.valueOf(matcher.group(1));
+            final Display display = new Display(displayId);
+            display.extract(dump, exitPatterns);
+            return display;
+        }
+
+        private void extract(LinkedList<String> dump, Pattern[] exitPatterns) {
+            while (!doneExtracting(dump, exitPatterns)) {
+                final String line = dump.pop().trim();
+
+                final Matcher matcher = sDisplayInfoPattern.matcher(line);
+                if (matcher.matches()) {
+                    log(TAG + "DISPLAY_INFO: " + line);
+                    mDpi = Integer.valueOf(matcher.group(2));
+
+                    final int displayWidth = Integer.valueOf(matcher.group(3));
+                    final int displayHeight = Integer.valueOf(matcher.group(4));
+                    mDisplayRect.setBounds(0, 0, displayWidth, displayHeight);
+
+                    final int appWidth = Integer.valueOf(matcher.group(5));
+                    final int appHeight = Integer.valueOf(matcher.group(6));
+                    mAppRect.setBounds(0, 0, appWidth, appHeight);
+
+                    // break as we don't need other info for now
+                    break;
+                }
+                // Extract other info here if needed
+            }
+        }
+
+        @Override
+        public String toString() {
+            return "Display #" + mDisplayId + ": mDisplayRect=" + mDisplayRect
+                    + " mAppRect=" + mAppRect;
+        }
+    }
+
+    static class WindowState extends WindowContainer {
+        private static final String TAG = "[WindowState] ";
+
+        private static final String RECT_STR = "\\[(\\d+),(\\d+)\\]\\[(\\d+),(\\d+)\\]";
+        private static final Pattern sFramePattern =
+                Pattern.compile("Frames: containing=" + RECT_STR + " parent=" + RECT_STR);
+        private static final Pattern sWindowAssociationPattern =
+                Pattern.compile("mDisplayId=(\\d+) stackId=(\\d+) (.+)");
+
+        private final String mName;
+        private final String mAppToken;
+        private final boolean mStarting;
+        private final boolean mExiting;
+        private int mDisplayId = 0;
+        private Rectangle mContainingFrame = new Rectangle();
+        private Rectangle mParentFrame = new Rectangle();
+
+        private WindowState(Matcher matcher, boolean starting, boolean exiting) {
+            mName = matcher.group(4);
+            mAppToken = matcher.group(2);
+            mStarting = starting;
+            mExiting = exiting;
+        }
+
+        String getName() {
+            return mName;
+        }
+
+        String getToken() {
+            return mAppToken;
+        }
+
+        boolean isStartingWindow() {
+            return mStarting;
+        }
+
+        boolean isExitingWindow() {
+            return mExiting;
+        }
+
+        int getDisplayId() {
+            return mDisplayId;
+        }
+
+        Rectangle getContainingFrame() {
+            return mContainingFrame;
+        }
+
+        Rectangle getParentFrame() {
+            return mParentFrame;
+        }
+
+        static WindowState create(LinkedList<String> dump, Pattern[] exitPatterns) {
+            final String line = dump.peek().trim();
+
+            Matcher matcher = sWindowPattern.matcher(line);
+            if (!matcher.matches()) {
+                return null;
+            }
+
+            log(TAG + "WINDOW: " + line);
+            dump.pop();
+
+            final WindowState window;
+            Matcher specialMatcher = sStartingWindowPattern.matcher(line);
+            if (specialMatcher.matches()) {
+                log(TAG + "STARTING: " + line);
+                window = new WindowState(specialMatcher, true, false);
+            } else {
+                specialMatcher = sExitingWindowPattern.matcher(line);
+                if (specialMatcher.matches()) {
+                    log(TAG + "EXITING: " + line);
+                    window = new WindowState(specialMatcher, false, true);
+                } else {
+                    window = new WindowState(matcher, false, false);
+                }
+            }
+
+            window.extract(dump, exitPatterns);
+            return window;
+        }
+
+        private void extract(LinkedList<String> dump, Pattern[] exitPatterns) {
+            while (!doneExtracting(dump, exitPatterns)) {
+                final String line = dump.pop().trim();
+
+                Matcher matcher = sWindowAssociationPattern.matcher(line);
+                if (matcher.matches()) {
+                    log(TAG + "WINDOW_ASSOCIATION: " + line);
+                    mDisplayId = Integer.valueOf(matcher.group(1));
+                    continue;
+                }
+
+                matcher = sFramePattern.matcher(line);
+                if (matcher.matches()) {
+                    log(TAG + "FRAME: " + line);
+                    extractMultipleBounds(matcher, 1, mContainingFrame, mParentFrame);
+                    continue;
+                }
+
+                // Extract other info here if needed
+            }
+        }
+
+        @Override
+        public String toString() {
+            return "WindowState: {" + mAppToken + " " + mName
+                    + (mStarting ? " STARTING" : "") + (mExiting ? " EXITING" : "") + "}"
+                    + " cf=" + mContainingFrame + " pf=" + mParentFrame;
+        }
+    }
+}
diff --git a/hostsidetests/systemui/Android.mk b/hostsidetests/systemui/Android.mk
new file mode 100644
index 0000000..41f05ef
--- /dev/null
+++ b/hostsidetests/systemui/Android.mk
@@ -0,0 +1,40 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_MODULE := CtsSystemUiHostTestCases
+
+LOCAL_JAVA_LIBRARIES := cts-tradefed tradefed-prebuilt compatibility-host-util
+
+LOCAL_STATIC_JAVA_LIBRARIES := cts-migration-lib
+
+LOCAL_CTS_TEST_PACKAGE := android.host.systemui
+
+LOCAL_CTS_MODULE_CONFIG := $(LOCAL_PATH)/Old$(CTS_MODULE_TEST_CONFIG)
+
+LOCAL_SDK_VERSION := current
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+include $(BUILD_CTS_HOST_JAVA_LIBRARY)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/hostsidetests/systemui/AndroidTest.xml b/hostsidetests/systemui/AndroidTest.xml
new file mode 100644
index 0000000..c8b1883
--- /dev/null
+++ b/hostsidetests/systemui/AndroidTest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS System UI host test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsSystemUiDeviceApp.apk" />
+    </target_preparer>
+    <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
+        <option name="jar" value="CtsSystemUiHostTestCases.jar" />
+    </test>
+</configuration>
diff --git a/hostsidetests/systemui/OldAndroidTest.xml b/hostsidetests/systemui/OldAndroidTest.xml
new file mode 100644
index 0000000..2efcb94
--- /dev/null
+++ b/hostsidetests/systemui/OldAndroidTest.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS System UI host test cases">
+
+    <include name="common-config" />
+    <!-- This will tell tradefed to install the test apk. -->
+    <option name="cts-apk-installer:test-file-name" value="CtsSystemUiDeviceApp.apk" />
+</configuration>
diff --git a/hostsidetests/systemui/app/Android.mk b/hostsidetests/systemui/app/Android.mk
new file mode 100644
index 0000000..ca987e7
--- /dev/null
+++ b/hostsidetests/systemui/app/Android.mk
@@ -0,0 +1,37 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+# Don't include this package in any target
+LOCAL_MODULE_TAGS := tests
+# When built, explicitly put it in the data partition.
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_DEX_PREOPT := false
+
+LOCAL_PROGUARD_ENABLED := disabled
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_PACKAGE_NAME := CtsSystemUiDeviceApp
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/systemui/app/AndroidManifest.xml b/hostsidetests/systemui/app/AndroidManifest.xml
new file mode 100755
index 0000000..30be410
--- /dev/null
+++ b/hostsidetests/systemui/app/AndroidManifest.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.systemui.cts">
+
+    <application>
+        <service android:name=".TestTileService"
+            android:icon="@android:drawable/ic_delete"
+            android:permission="android.permission.BIND_QUICK_SETTINGS_TILE">
+            <intent-filter>
+                <action android:name="android.service.quicksettings.action.QS_TILE" />
+            </intent-filter>
+        </service>
+
+        <service android:name=".TestActiveTileService"
+            android:icon="@android:drawable/ic_delete"
+            android:permission="android.permission.BIND_QUICK_SETTINGS_TILE">
+            <intent-filter>
+                <action android:name="android.service.quicksettings.action.QS_TILE" />
+            </intent-filter>
+            <meta-data android:name="android.service.quicksettings.ACTIVE_TILE"
+                android:value="true" />
+        </service>
+
+        <receiver
+            android:name=".TestActiveTileService$Receiver">
+            <intent-filter>
+                <action android:name="android.sysui.testtile.REQUEST_LISTENING" />
+            </intent-filter>
+        </receiver>
+
+    </application>
+
+</manifest>
+
diff --git a/hostsidetests/systemui/app/src/android/systemui/cts/TestActiveTileService.java b/hostsidetests/systemui/app/src/android/systemui/cts/TestActiveTileService.java
new file mode 100644
index 0000000..f8fe6c0
--- /dev/null
+++ b/hostsidetests/systemui/app/src/android/systemui/cts/TestActiveTileService.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 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.systemui.cts;
+
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.util.Log;
+
+public class TestActiveTileService extends TestTileService {
+
+    @Override
+    public void onTileAdded() {
+        Log.i(TAG, TEST_PREFIX + "onTileAdded");
+    }
+
+    public static class Receiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            Log.i(TestActiveTileService.class.getSimpleName(),
+                    TEST_PREFIX + "requestListeningState");
+            requestListeningState(context, new ComponentName(context, TestActiveTileService.class));
+        }
+    }
+}
diff --git a/hostsidetests/systemui/app/src/android/systemui/cts/TestTileService.java b/hostsidetests/systemui/app/src/android/systemui/cts/TestTileService.java
new file mode 100644
index 0000000..e8515d9
--- /dev/null
+++ b/hostsidetests/systemui/app/src/android/systemui/cts/TestTileService.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 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.systemui.cts;
+
+import android.app.Dialog;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.graphics.drawable.Icon;
+import android.provider.Settings;
+import android.service.quicksettings.Tile;
+import android.service.quicksettings.TileService;
+import android.util.Log;
+import android.view.View;
+
+/**
+ * A test tile that logs everything that happens to it.
+ * The tests will manipulate the state of the QS tile through ADB and verify
+ * the correct callbacks actually happened.
+ */
+public class TestTileService extends TileService {
+    protected final String TAG = getClass().getSimpleName();
+
+    public static final String SHOW_DIALOG = "android.sysui.testtile.action.SHOW_DIALOG";
+    public static final String START_ACTIVITY = "android.sysui.testtile.action.START_ACTIVITY";
+
+    public static final String TEST_PREFIX = "TileTest_";
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        Log.i(TAG, TEST_PREFIX + "onCreate");
+    }
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+        Log.i(TAG, TEST_PREFIX + "onDestroy");
+    }
+
+    @Override
+    public void onTileAdded() {
+        Log.i(TAG, TEST_PREFIX + "onTileAdded");
+    }
+
+    @Override
+    public void onTileRemoved() {
+        Log.i(TAG, TEST_PREFIX + "onTileRemoved");
+        super.onTileRemoved();
+    }
+
+    @Override
+    public void onStartListening() {
+        super.onStartListening();
+        Log.i(TAG, TEST_PREFIX + "onStartListening");
+        IntentFilter filter = new IntentFilter(SHOW_DIALOG);
+        filter.addAction(START_ACTIVITY);
+        registerReceiver(mReceiver, filter);
+
+        // Set up some initial good state.
+        getQsTile().setLabel(TAG);
+        getQsTile().setContentDescription("CTS Test Tile");
+        getQsTile().setIcon(Icon.createWithResource(this, android.R.drawable.ic_secure));
+        getQsTile().setState(Tile.STATE_ACTIVE);
+        getQsTile().updateTile();
+    }
+
+    @Override
+    public void onStopListening() {
+        super.onStopListening();
+        Log.i(TAG, TEST_PREFIX + "onStopListening");
+        unregisterReceiver(mReceiver);
+    }
+
+    @Override
+    public void onClick() {
+        super.onClick();
+        Log.i(TAG, TEST_PREFIX + "onClick");
+        Log.i(TAG, TEST_PREFIX + "is_secure_" + isSecure());
+        Log.i(TAG, TEST_PREFIX + "is_locked_" + isLocked());
+        unlockAndRun(new Runnable() {
+            @Override
+            public void run() {
+                Log.i(TAG, TEST_PREFIX + "unlockAndRunRun");
+            }
+        });
+    }
+
+    private void handleStartActivity() {
+        startActivityAndCollapse(new Intent(Settings.ACTION_SETTINGS)
+                .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
+    }
+
+    private void handleShowDialog() {
+        Log.i(TAG, TEST_PREFIX + "handleShowDialog");
+        final Dialog dialog = new Dialog(this);
+        dialog.setContentView(new FocusView(this, dialog));
+        try {
+            showDialog(dialog);
+        } catch (Exception e) {
+            Log.i(TAG, TEST_PREFIX + "onWindowAddFailed", e);
+        }
+    }
+
+    private class FocusView extends View {
+        private final Dialog mDialog;
+
+        public FocusView(Context context, Dialog dialog) {
+            super(context);
+            mDialog = dialog;
+        }
+
+        @Override
+        public void onWindowFocusChanged(boolean hasWindowFocus) {
+            Log.i(TAG, TEST_PREFIX + "onWindowFocusChanged_" + hasWindowFocus);
+            if (hasWindowFocus) {
+                post(new Runnable() {
+                    @Override
+                    public void run() {
+                        mDialog.dismiss();
+                    }
+                });
+            }
+            super.onWindowFocusChanged(hasWindowFocus);
+        }
+    }
+
+    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (intent.getAction().equals(SHOW_DIALOG)) {
+                handleShowDialog();
+            } else {
+                handleStartActivity();
+            }
+        }
+    };
+}
diff --git a/hostsidetests/systemui/src/android/host/systemui/ActiveTileServiceTest.java b/hostsidetests/systemui/src/android/host/systemui/ActiveTileServiceTest.java
new file mode 100644
index 0000000..5325b29
--- /dev/null
+++ b/hostsidetests/systemui/src/android/host/systemui/ActiveTileServiceTest.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 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.host.systemui;
+
+/**
+ * Tests the differences in behavior between tiles in TileService#TILE_MODE_PASSIVE
+ * and TileService#TILE_MODE_ACTIVE.
+ */
+public class ActiveTileServiceTest extends BaseTileServiceTest {
+    // Constants for generating commands below.
+    private static final String SERVICE = "TestActiveTileService";
+
+    private static final String ACTION_REQUEST_LISTENING =
+            "android.sysui.testtile.REQUEST_LISTENING";
+
+    private static final String REQUEST_LISTENING = "am broadcast -a " + ACTION_REQUEST_LISTENING;
+
+    public ActiveTileServiceTest() {
+        super(SERVICE);
+    }
+
+    public void testNotListening() throws Exception {
+        addTile();
+        assertTrue(waitFor("onDestroy"));
+
+        // Open quick settings and verify that this service doesn't get put in
+        // a listening state since its an active tile.
+        openSettings();
+        assertFalse(waitFor("onStartListening"));
+    }
+
+    public void testRequestListening() throws Exception {
+        addTile();
+        assertTrue(waitFor("onDestroy"));
+
+        // Request the listening state and verify that it gets an onStartListening.
+        getDevice().executeShellCommand(REQUEST_LISTENING);
+        assertTrue(waitFor("requestListeningState"));
+        assertTrue(waitFor("onStartListening"));
+    }
+
+    public void testClick() throws Exception {
+        addTile();
+        assertTrue(waitFor("onDestroy"));
+
+        // Open the quick settings.
+        openSettings();
+
+        // Click on the tile and verify it happens.
+        clickTile();
+        assertTrue(waitFor("onStartListening"));
+        assertTrue(waitFor("onClick"));
+    }
+
+}
diff --git a/hostsidetests/systemui/src/android/host/systemui/BaseTileServiceTest.java b/hostsidetests/systemui/src/android/host/systemui/BaseTileServiceTest.java
new file mode 100644
index 0000000..50d25e8
--- /dev/null
+++ b/hostsidetests/systemui/src/android/host/systemui/BaseTileServiceTest.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 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.host.systemui;
+
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.testtype.DeviceTestCase;
+
+public class BaseTileServiceTest extends DeviceTestCase {
+    // Constants for generating commands below.
+    private static final String PACKAGE = "android.systemui.cts";
+    private static final String ACTION_SHOW_DIALOG = "android.sysui.testtile.action.SHOW_DIALOG";
+
+    // Commands used on the device.
+    private static final String ADD_TILE   = "cmd statusbar add-tile ";
+    private static final String REM_TILE   = "cmd statusbar remove-tile ";
+    private static final String CLICK_TILE = "cmd statusbar click-tile ";
+
+    private static final String OPEN_NOTIFICATIONS = "cmd statusbar expand-notifications";
+    private static final String OPEN_SETTINGS      = "cmd statusbar expand-settings";
+    private static final String COLLAPSE           = "cmd statusbar collapse";
+
+    private static final String SHOW_DIALOG = "am broadcast -a " + ACTION_SHOW_DIALOG;
+
+    public static final String TEST_PREFIX = "TileTest_";
+
+    // Time between checks for logs we expect.
+    private static final long CHECK_DELAY = 500;
+    // Number of times to check before failing.
+    private static final long CHECK_RETRIES = 30;
+
+    private final String mService;
+    private final String mComponent;
+
+    public BaseTileServiceTest() {
+        this("");
+    }
+
+    public BaseTileServiceTest(String service) {
+        mService = service;
+        mComponent = PACKAGE + "/." + mService;
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        clearLogcat();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+
+        collapse();
+        remTile();
+        // Try to wait for a onTileRemoved.
+        waitFor("onTileRemoved");
+    }
+
+    protected void showDialog() throws Exception {
+        execute(SHOW_DIALOG);
+    }
+
+    protected void addTile() throws Exception {
+        execute(ADD_TILE + mComponent);
+    }
+
+    protected void remTile() throws Exception {
+        execute(REM_TILE + mComponent);
+    }
+
+    protected void clickTile() throws Exception {
+        execute(CLICK_TILE + mComponent);
+    }
+
+    protected void openNotifications() throws Exception {
+        execute(OPEN_NOTIFICATIONS);
+    }
+
+    protected void openSettings() throws Exception {
+        execute(OPEN_SETTINGS);
+    }
+
+    protected void collapse() throws Exception {
+        execute(COLLAPSE);
+    }
+
+    private void execute(String cmd) throws Exception {
+        getDevice().executeShellCommand(cmd);
+        // All of the status bar commands tend to have animations associated
+        // everything seems to be happier if you give them time to finish.
+        Thread.sleep(100);
+    }
+
+    protected boolean waitFor(String str) throws DeviceNotAvailableException, InterruptedException {
+        final String searchStr = TEST_PREFIX + str;
+        int ct = 0;
+        while (!hasLog(searchStr) && (ct++ < CHECK_RETRIES)) {
+            Thread.sleep(CHECK_DELAY);
+        }
+        return hasLog(searchStr);
+    }
+
+    protected boolean hasLog(String str) throws DeviceNotAvailableException {
+        String logs = getDevice().executeAdbCommand("logcat", "-v", "brief", "-d", mService + ":I",
+                "*:S");
+        return logs.contains(str);
+    }
+
+    private void clearLogcat() throws DeviceNotAvailableException {
+        getDevice().executeAdbCommand("logcat", "-c");
+    }
+}
diff --git a/hostsidetests/systemui/src/android/host/systemui/TileServiceTest.java b/hostsidetests/systemui/src/android/host/systemui/TileServiceTest.java
new file mode 100644
index 0000000..3c92918
--- /dev/null
+++ b/hostsidetests/systemui/src/android/host/systemui/TileServiceTest.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 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.host.systemui;
+
+/**
+ * Tests the lifecycle of a TileService by adding/removing it and opening/closing
+ * the notification/settings shade through adb commands.
+ */
+public class TileServiceTest extends BaseTileServiceTest {
+
+    private static final String SERVICE = "TestTileService";
+
+    public static final String ACTION_START_ACTIVITY =
+            "android.sysui.testtile.action.START_ACTIVITY";
+
+    public static final String START_ACTIVITY_AND_COLLAPSE =
+            "am broadcast -a " + ACTION_START_ACTIVITY;
+
+    public TileServiceTest() {
+        super(SERVICE);
+    }
+
+    public void testAddTile() throws Exception {
+        addTile();
+        // Verify that the service starts up and gets a onTileAdded callback.
+        assertTrue(waitFor("onCreate"));
+        assertTrue(waitFor("onTileAdded"));
+        assertTrue(waitFor("onDestroy"));
+    }
+
+    public void testRemoveTile() throws Exception {
+        addTile();
+        // Verify that the service starts up and gets a onTileAdded callback.
+        assertTrue(waitFor("onCreate"));
+        assertTrue(waitFor("onTileAdded"));
+        assertTrue(waitFor("onDestroy"));
+
+        remTile();
+        assertTrue(waitFor("onTileRemoved"));
+    }
+
+    public void testListeningNotifications() throws Exception {
+        addTile();
+        assertTrue(waitFor("onDestroy"));
+
+        // Open the notification shade and make sure the tile gets a chance to listen.
+        openNotifications();
+        assertTrue(waitFor("onStartListening"));
+        // Collapse the shade and make sure the listening ends.
+        collapse();
+        assertTrue(waitFor("onStopListening"));
+    }
+
+    public void testListeningSettings() throws Exception {
+        addTile();
+        assertTrue(waitFor("onDestroy"));
+
+        // Open the quick settings and make sure the tile gets a chance to listen.
+        openSettings();
+        assertTrue(waitFor("onStartListening"));
+        // Collapse the shade and make sure the listening ends.
+        collapse();
+        assertTrue(waitFor("onStopListening"));
+    }
+
+    public void testCantAddDialog() throws Exception {
+        addTile();
+        assertTrue(waitFor("onDestroy"));
+
+        // Wait for the tile to be added.
+        assertTrue(waitFor("onTileAdded"));
+
+        // Open the quick settings and make sure the tile gets a chance to listen.
+        openSettings();
+        assertTrue(waitFor("onStartListening"));
+
+        // Try to open a dialog, verify it doesn't happen.
+        showDialog();
+        assertTrue(waitFor("handleShowDialog"));
+        assertTrue(waitFor("onWindowAddFailed"));
+    }
+
+    public void testClick() throws Exception {
+        addTile();
+        // Wait for the tile to be added.
+        assertTrue(waitFor("onTileAdded"));
+
+        // Open the quick settings and make sure the tile gets a chance to listen.
+        openSettings();
+        assertTrue(waitFor("onStartListening"));
+
+        // Click on the tile and verify it happens.
+        clickTile();
+        assertTrue(waitFor("onClick"));
+
+        // Verify the state that gets dumped during a click.
+        // Device is expected to be unlocked and unsecure during CTS.
+        // The unlock callback should be triggered immediately.
+        assertTrue(waitFor("is_secure_false"));
+        assertTrue(waitFor("is_locked_false"));
+        assertTrue(waitFor("unlockAndRunRun"));
+    }
+
+    public void testClickAndShowDialog() throws Exception {
+        addTile();
+        assertTrue(waitFor("onDestroy"));
+
+        // Open the quick settings and make sure the tile gets a chance to listen.
+        openSettings();
+        assertTrue(waitFor("onStartListening"));
+
+        // Click on the tile and verify it happens.
+        clickTile();
+        assertTrue(waitFor("onClick"));
+
+        // Try to open a dialog, verify it doesn't happen.
+        showDialog();
+        assertTrue(waitFor("handleShowDialog"));
+        assertTrue(waitFor("onWindowFocusChanged_true"));
+    }
+
+    public void testStartActivity() throws Exception {
+        addTile();
+        // Wait for the tile to be added.
+        assertTrue(waitFor("onTileAdded"));
+
+        // Open the quick settings and make sure the tile gets a chance to listen.
+        openSettings();
+        assertTrue(waitFor("onStartListening"));
+
+        // Trigger the startActivityAndCollapse call and verify we get taken out of listening
+        // because the shade gets collapsed.
+        getDevice().executeShellCommand(START_ACTIVITY_AND_COLLAPSE);
+        assertTrue(waitFor("onStopListening"));
+    }
+
+}
diff --git a/hostsidetests/theme/Android.mk b/hostsidetests/theme/Android.mk
index 188bf7a..d58b85e 100644
--- a/hostsidetests/theme/Android.mk
+++ b/hostsidetests/theme/Android.mk
@@ -25,12 +25,17 @@
 # Must match the package name in CtsTestCaseList.mk
 LOCAL_MODULE := CtsThemeHostTestCases
 
-LOCAL_JAVA_LIBRARIES := cts-tradefed tradefed-prebuilt
+LOCAL_JAVA_LIBRARIES := cts-tradefed tradefed-prebuilt compatibility-host-util
+
+LOCAL_STATIC_JAVA_LIBRARIES := cts-migration-lib
 
 LOCAL_CTS_TEST_PACKAGE := android.host.theme
 
 LOCAL_SDK_VERSION := current
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_CTS_HOST_JAVA_LIBRARY)
 
 include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/hostsidetests/theme/AndroidTest.xml b/hostsidetests/theme/AndroidTest.xml
new file mode 100644
index 0000000..50418ec
--- /dev/null
+++ b/hostsidetests/theme/AndroidTest.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS Theme host test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsThemeDeviceApp.apk" />
+    </target_preparer>
+    <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
+        <option name="jar" value="CtsThemeHostTestCases.jar" />
+        <option name="runtime-hint" value="5h2m34s" />
+    </test>
+</configuration>
diff --git a/hostsidetests/theme/app/Android.mk b/hostsidetests/theme/app/Android.mk
index 1be2983..e55a9b6 100644
--- a/hostsidetests/theme/app/Android.mk
+++ b/hostsidetests/theme/app/Android.mk
@@ -36,6 +36,9 @@
 
 LOCAL_PACKAGE_NAME := CtsThemeDeviceApp
 
-LOCAL_SDK_VERSION := current
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
 
-include $(BUILD_CTS_PACKAGE)
+LOCAL_SDK_VERSION := 23
+
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/theme/app/src/android/theme/app/GenerateImagesActivity.java b/hostsidetests/theme/app/src/android/theme/app/GenerateImagesActivity.java
index e7f5aa2..1bf4da1 100644
--- a/hostsidetests/theme/app/src/android/theme/app/GenerateImagesActivity.java
+++ b/hostsidetests/theme/app/src/android/theme/app/GenerateImagesActivity.java
@@ -30,7 +30,9 @@
 import android.view.WindowManager.LayoutParams;
 
 import java.io.File;
+import java.io.IOException;
 import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 
 /**
  * Generates images by iterating through all themes and launching instances of
@@ -42,9 +44,13 @@
     private static final String OUT_DIR = "cts-theme-assets";
     private static final int REQUEST_CODE = 1;
 
+    public static final String EXTRA_REASON = "reason";
+
     private final CountDownLatch mLatch = new CountDownLatch(1);
 
     private File mOutputDir;
+    private File mOutputZip;
+
     private int mCurrentTheme;
     private String mFinishReason;
     private boolean mFinishSuccess;
@@ -86,14 +92,6 @@
         }.start();
     }
 
-    private void finish(String reason, boolean success) {
-        mFinishSuccess = success;
-        mFinishReason = reason;
-
-        Log.i(TAG, (success ? "OKAY" : "FAIL") + ":" + reason);
-        finish();
-    }
-
     public boolean isFinishSuccess() {
         return mFinishSuccess;
     }
@@ -144,10 +142,6 @@
         public abstract void onFailure();
     }
 
-    public File getOutputDir() {
-        return mOutputDir;
-    }
-
     /**
      * Starts the activity to generate the next image.
      */
@@ -172,8 +166,8 @@
     @Override
     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
         if (resultCode != RESULT_OK) {
-            Log.i(TAG, "FAIL:Failed to generate images for theme " + mCurrentTheme);
-            finish();
+            finish("Failed to generate images for theme " + mCurrentTheme + " ("
+                    + data.getStringExtra(EXTRA_REASON) + ")", false);
             return;
         }
 
@@ -185,16 +179,47 @@
 
         // If we ran out of themes, we're done.
         if (!success) {
+            compressOutput();
+
             finish("Image generation complete!", true);
         }
     }
 
+    private void compressOutput() {
+        mOutputZip = new File(mOutputDir.getParentFile(), mOutputDir.getName() + ".zip");
+
+        if (mOutputZip.exists()) {
+            // Remove any old test results.
+            mOutputZip.delete();
+        }
+
+        try {
+            ThemeTestUtils.compressDirectory(mOutputDir, mOutputZip);
+            ThemeTestUtils.deleteDirectory(mOutputDir);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    private void finish(String reason, boolean success) {
+        mFinishSuccess = success;
+        mFinishReason = reason;
+
+        finish();
+    }
+
+    @Override
     public void finish() {
         mLatch.countDown();
+
         super.finish();
     }
 
-    public void waitForCompletion() throws InterruptedException {
-        mLatch.await();
+    public File getOutputZip() {
+        return mOutputZip;
+    }
+
+    public boolean waitForCompletion(long timeoutMillis) throws InterruptedException {
+        return mLatch.await(timeoutMillis, TimeUnit.MILLISECONDS);
     }
 }
diff --git a/hostsidetests/theme/app/src/android/theme/app/ReferenceImagesTest.java b/hostsidetests/theme/app/src/android/theme/app/ReferenceImagesTest.java
index 7569252..6e0731d 100644
--- a/hostsidetests/theme/app/src/android/theme/app/ReferenceImagesTest.java
+++ b/hostsidetests/theme/app/src/android/theme/app/ReferenceImagesTest.java
@@ -25,6 +25,9 @@
  */
 public class ReferenceImagesTest extends ActivityInstrumentationTestCase2<GenerateImagesActivity> {
 
+    /** Overall test timeout is 30 minutes. Should only take about 5. */
+    private static final int TEST_RESULT_TIMEOUT = 30 * 60 * 1000;
+
     public ReferenceImagesTest() {
         super(GenerateImagesActivity.class);
     }
@@ -33,20 +36,12 @@
         setActivityInitialTouchMode(true);
 
         final GenerateImagesActivity activity = getActivity();
-        activity.waitForCompletion();
-
+        assertTrue("Activity failed to complete within " + TEST_RESULT_TIMEOUT + " ms",
+                activity.waitForCompletion(TEST_RESULT_TIMEOUT));
         assertTrue(activity.getFinishReason(), activity.isFinishSuccess());
 
-        final File outputDir = activity.getOutputDir();
-        final File outputZip = new File(outputDir.getParentFile(), outputDir.getName() + ".zip");
-        if (outputZip.exists()) {
-            // Remove any old test results.
-            outputZip.delete();
-        }
-
-        ThemeTestUtils.compressDirectory(outputDir, outputZip);
-        ThemeTestUtils.deleteDirectory(outputDir);
-
-        assertTrue("Generated reference image ZIP", outputZip.exists());
+        final File outputZip = activity.getOutputZip();
+        assertTrue("Failed to generate reference image ZIP",
+                outputZip != null && outputZip.exists());
     }
 }
diff --git a/hostsidetests/theme/app/src/android/theme/app/ThemeDeviceActivity.java b/hostsidetests/theme/app/src/android/theme/app/ThemeDeviceActivity.java
index d8b1f30..6235fdf 100644
--- a/hostsidetests/theme/app/src/android/theme/app/ThemeDeviceActivity.java
+++ b/hostsidetests/theme/app/src/android/theme/app/ThemeDeviceActivity.java
@@ -44,10 +44,10 @@
     private static final String TAG = "ThemeDeviceActivity";
 
     /**
-     * The duration of the CalendarView adjustment to settle to its final
+     * Delay that allows the Holo-style CalendarView to settle to its final
      * position.
      */
-    private static final long CALENDAR_VIEW_ADJUSTMENT_DURATION = 540;
+    private static final long HOLO_CALENDAR_VIEW_ADJUSTMENT_DURATION = 540;
 
     private Theme mTheme;
     private ReferenceViewGroup mViewGroup;
@@ -111,8 +111,10 @@
     @Override
     protected void onDestroy() {
         if (mLayoutIndex < LAYOUTS.length) {
-            Log.e(TAG, "Not all layouts got rendered: " + mLayoutIndex);
-            setResult(RESULT_CANCELED);
+            final Intent data = new Intent();
+            data.putExtra(GenerateImagesActivity.EXTRA_REASON, "Only rendered "
+                    + mLayoutIndex + "/" + LAYOUTS.length + " layouts");
+            setResult(RESULT_CANCELED, data);
         }
 
         super.onDestroy();
@@ -150,10 +152,10 @@
             }
         };
 
-        if (view instanceof DatePicker) {
+        if (view instanceof DatePicker && mTheme.spec == Theme.HOLO) {
             // The Holo-styled DatePicker uses a CalendarView that has a
             // non-configurable adjustment duration of 540ms.
-            view.postDelayed(generateBitmapRunnable, CALENDAR_VIEW_ADJUSTMENT_DURATION);
+            view.postDelayed(generateBitmapRunnable, HOLO_CALENDAR_VIEW_ADJUSTMENT_DURATION);
         } else {
             view.post(generateBitmapRunnable);
         }
@@ -180,11 +182,16 @@
      * A class to encapsulate information about a theme.
      */
     static class Theme {
+        public static final int HOLO = 0;
+        public static final int MATERIAL = 1;
+
+        public final int spec;
         public final int id;
         public final int apiLevel;
         public final String name;
 
-        private Theme(int id, int apiLevel, String name) {
+        private Theme(int spec, int id, int apiLevel, String name) {
+            this.spec = spec;
             this.id = id;
             this.apiLevel = apiLevel;
             this.name = name;
@@ -194,139 +201,139 @@
     // List of themes to verify.
     static final Theme[] THEMES = {
             // Holo
-            new Theme(android.R.style.Theme_Holo,
+            new Theme(Theme.HOLO, android.R.style.Theme_Holo,
                     Build.VERSION_CODES.HONEYCOMB, "holo"),
-            new Theme(android.R.style.Theme_Holo_Dialog,
+            new Theme(Theme.HOLO, android.R.style.Theme_Holo_Dialog,
                     Build.VERSION_CODES.HONEYCOMB, "holo_dialog"),
-            new Theme(android.R.style.Theme_Holo_Dialog_MinWidth,
+            new Theme(Theme.HOLO, android.R.style.Theme_Holo_Dialog_MinWidth,
                     Build.VERSION_CODES.HONEYCOMB, "holo_dialog_minwidth"),
-            new Theme(android.R.style.Theme_Holo_Dialog_NoActionBar,
+            new Theme(Theme.HOLO, android.R.style.Theme_Holo_Dialog_NoActionBar,
                     Build.VERSION_CODES.HONEYCOMB, "holo_dialog_noactionbar"),
-            new Theme(android.R.style.Theme_Holo_Dialog_NoActionBar_MinWidth,
+            new Theme(Theme.HOLO, android.R.style.Theme_Holo_Dialog_NoActionBar_MinWidth,
                     Build.VERSION_CODES.HONEYCOMB, "holo_dialog_noactionbar_minwidth"),
-            new Theme(android.R.style.Theme_Holo_DialogWhenLarge,
+            new Theme(Theme.HOLO, android.R.style.Theme_Holo_DialogWhenLarge,
                     Build.VERSION_CODES.HONEYCOMB, "holo_dialogwhenlarge"),
-            new Theme(android.R.style.Theme_Holo_DialogWhenLarge_NoActionBar,
+            new Theme(Theme.HOLO, android.R.style.Theme_Holo_DialogWhenLarge_NoActionBar,
                     Build.VERSION_CODES.HONEYCOMB, "holo_dialogwhenlarge_noactionbar"),
-            new Theme(android.R.style.Theme_Holo_InputMethod,
+            new Theme(Theme.HOLO, android.R.style.Theme_Holo_InputMethod,
                     Build.VERSION_CODES.HONEYCOMB, "holo_inputmethod"),
-            new Theme(android.R.style.Theme_Holo_NoActionBar,
+            new Theme(Theme.HOLO, android.R.style.Theme_Holo_NoActionBar,
                     Build.VERSION_CODES.HONEYCOMB, "holo_noactionbar"),
-            new Theme(android.R.style.Theme_Holo_NoActionBar_Fullscreen,
+            new Theme(Theme.HOLO, android.R.style.Theme_Holo_NoActionBar_Fullscreen,
                     Build.VERSION_CODES.HONEYCOMB, "holo_noactionbar_fullscreen"),
-            new Theme(android.R.style.Theme_Holo_NoActionBar_Overscan,
+            new Theme(Theme.HOLO, android.R.style.Theme_Holo_NoActionBar_Overscan,
                     Build.VERSION_CODES.JELLY_BEAN_MR2, "holo_noactionbar_overscan"),
-            new Theme(android.R.style.Theme_Holo_NoActionBar_TranslucentDecor,
+            new Theme(Theme.HOLO, android.R.style.Theme_Holo_NoActionBar_TranslucentDecor,
                     Build.VERSION_CODES.KITKAT, "holo_noactionbar_translucentdecor"),
-            new Theme(android.R.style.Theme_Holo_Panel,
+            new Theme(Theme.HOLO, android.R.style.Theme_Holo_Panel,
                     Build.VERSION_CODES.HONEYCOMB, "holo_panel"),
-            new Theme(android.R.style.Theme_Holo_Wallpaper,
+            new Theme(Theme.HOLO, android.R.style.Theme_Holo_Wallpaper,
                     Build.VERSION_CODES.HONEYCOMB, "holo_wallpaper"),
-            new Theme(android.R.style.Theme_Holo_Wallpaper_NoTitleBar,
+            new Theme(Theme.HOLO, android.R.style.Theme_Holo_Wallpaper_NoTitleBar,
                     Build.VERSION_CODES.HONEYCOMB, "holo_wallpaper_notitlebar"),
 
             // Holo Light
-            new Theme(android.R.style.Theme_Holo_Light,
+            new Theme(Theme.HOLO, android.R.style.Theme_Holo_Light,
                     Build.VERSION_CODES.HONEYCOMB, "holo_light"),
-            new Theme(android.R.style.Theme_Holo_Light_DarkActionBar,
+            new Theme(Theme.HOLO, android.R.style.Theme_Holo_Light_DarkActionBar,
                     Build.VERSION_CODES.ICE_CREAM_SANDWICH, "holo_light_darkactionbar"),
-            new Theme(android.R.style.Theme_Holo_Light_Dialog,
+            new Theme(Theme.HOLO, android.R.style.Theme_Holo_Light_Dialog,
                     Build.VERSION_CODES.HONEYCOMB, "holo_light_dialog"),
-            new Theme(android.R.style.Theme_Holo_Light_Dialog_MinWidth,
+            new Theme(Theme.HOLO, android.R.style.Theme_Holo_Light_Dialog_MinWidth,
                     Build.VERSION_CODES.HONEYCOMB, "holo_light_dialog_minwidth"),
-            new Theme(android.R.style.Theme_Holo_Light_Dialog_NoActionBar,
+            new Theme(Theme.HOLO, android.R.style.Theme_Holo_Light_Dialog_NoActionBar,
                     Build.VERSION_CODES.HONEYCOMB, "holo_light_dialog_noactionbar"),
-            new Theme(android.R.style.Theme_Holo_Light_Dialog_NoActionBar_MinWidth,
+            new Theme(Theme.HOLO, android.R.style.Theme_Holo_Light_Dialog_NoActionBar_MinWidth,
                     Build.VERSION_CODES.HONEYCOMB, "holo_light_dialog_noactionbar_minwidth"),
-            new Theme(android.R.style.Theme_Holo_Light_DialogWhenLarge,
+            new Theme(Theme.HOLO, android.R.style.Theme_Holo_Light_DialogWhenLarge,
                     Build.VERSION_CODES.HONEYCOMB, "holo_light_dialogwhenlarge"),
-            new Theme(android.R.style.Theme_Holo_Light_DialogWhenLarge_NoActionBar,
+            new Theme(Theme.HOLO, android.R.style.Theme_Holo_Light_DialogWhenLarge_NoActionBar,
                     Build.VERSION_CODES.HONEYCOMB, "holo_light_dialogwhenlarge_noactionbar"),
-            new Theme(android.R.style.Theme_Holo_Light_NoActionBar,
+            new Theme(Theme.HOLO, android.R.style.Theme_Holo_Light_NoActionBar,
                     Build.VERSION_CODES.HONEYCOMB_MR2, "holo_light_noactionbar"),
-            new Theme(android.R.style.Theme_Holo_Light_NoActionBar_Fullscreen,
+            new Theme(Theme.HOLO, android.R.style.Theme_Holo_Light_NoActionBar_Fullscreen,
                     Build.VERSION_CODES.HONEYCOMB_MR2, "holo_light_noactionbar_fullscreen"),
-            new Theme(android.R.style.Theme_Holo_Light_NoActionBar_Overscan,
+            new Theme(Theme.HOLO, android.R.style.Theme_Holo_Light_NoActionBar_Overscan,
                     Build.VERSION_CODES.JELLY_BEAN_MR2, "holo_light_noactionbar_overscan"),
-            new Theme(android.R.style.Theme_Holo_Light_NoActionBar_TranslucentDecor,
+            new Theme(Theme.HOLO, android.R.style.Theme_Holo_Light_NoActionBar_TranslucentDecor,
                     Build.VERSION_CODES.KITKAT, "holo_light_noactionbar_translucentdecor"),
-            new Theme(android.R.style.Theme_Holo_Light_Panel,
+            new Theme(Theme.HOLO, android.R.style.Theme_Holo_Light_Panel,
                     Build.VERSION_CODES.HONEYCOMB, "holo_light_panel"),
 
             // Material
-            new Theme(android.R.style.Theme_Material,
+            new Theme(Theme.MATERIAL, android.R.style.Theme_Material,
                     Build.VERSION_CODES.LOLLIPOP, "material"),
-            new Theme(android.R.style.Theme_Material_Dialog,
+            new Theme(Theme.MATERIAL, android.R.style.Theme_Material_Dialog,
                     Build.VERSION_CODES.LOLLIPOP, "material_dialog"),
-            new Theme(android.R.style.Theme_Material_Dialog_Alert,
+            new Theme(Theme.MATERIAL, android.R.style.Theme_Material_Dialog_Alert,
                     Build.VERSION_CODES.LOLLIPOP, "material_dialog_alert"),
-            new Theme(android.R.style.Theme_Material_Dialog_MinWidth,
+            new Theme(Theme.MATERIAL, android.R.style.Theme_Material_Dialog_MinWidth,
                     Build.VERSION_CODES.LOLLIPOP, "material_dialog_minwidth"),
-            new Theme(android.R.style.Theme_Material_Dialog_NoActionBar,
+            new Theme(Theme.MATERIAL, android.R.style.Theme_Material_Dialog_NoActionBar,
                     Build.VERSION_CODES.LOLLIPOP, "material_dialog_noactionbar"),
-            new Theme(android.R.style.Theme_Material_Dialog_NoActionBar_MinWidth,
+            new Theme(Theme.MATERIAL, android.R.style.Theme_Material_Dialog_NoActionBar_MinWidth,
                     Build.VERSION_CODES.LOLLIPOP, "material_dialog_noactionbar_minwidth"),
-            new Theme(android.R.style.Theme_Material_Dialog_Presentation,
+            new Theme(Theme.MATERIAL, android.R.style.Theme_Material_Dialog_Presentation,
                     Build.VERSION_CODES.LOLLIPOP, "material_dialog_presentation"),
-            new Theme(android.R.style.Theme_Material_DialogWhenLarge,
+            new Theme(Theme.MATERIAL, android.R.style.Theme_Material_DialogWhenLarge,
                     Build.VERSION_CODES.LOLLIPOP, "material_dialogwhenlarge"),
-            new Theme(android.R.style.Theme_Material_DialogWhenLarge_NoActionBar,
+            new Theme(Theme.MATERIAL, android.R.style.Theme_Material_DialogWhenLarge_NoActionBar,
                     Build.VERSION_CODES.LOLLIPOP, "material_dialogwhenlarge_noactionbar"),
-            new Theme(android.R.style.Theme_Material_InputMethod,
+            new Theme(Theme.MATERIAL, android.R.style.Theme_Material_InputMethod,
                     Build.VERSION_CODES.LOLLIPOP, "material_inputmethod"),
-            new Theme(android.R.style.Theme_Material_NoActionBar,
+            new Theme(Theme.MATERIAL, android.R.style.Theme_Material_NoActionBar,
                     Build.VERSION_CODES.LOLLIPOP, "material_noactionbar"),
-            new Theme(android.R.style.Theme_Material_NoActionBar_Fullscreen,
+            new Theme(Theme.MATERIAL, android.R.style.Theme_Material_NoActionBar_Fullscreen,
                     Build.VERSION_CODES.LOLLIPOP, "material_noactionbar_fullscreen"),
-            new Theme(android.R.style.Theme_Material_NoActionBar_Overscan,
+            new Theme(Theme.MATERIAL, android.R.style.Theme_Material_NoActionBar_Overscan,
                     Build.VERSION_CODES.LOLLIPOP, "material_noactionbar_overscan"),
-            new Theme(android.R.style.Theme_Material_NoActionBar_TranslucentDecor,
+            new Theme(Theme.MATERIAL, android.R.style.Theme_Material_NoActionBar_TranslucentDecor,
                     Build.VERSION_CODES.LOLLIPOP, "material_noactionbar_translucentdecor"),
-            new Theme(android.R.style.Theme_Material_Panel,
+            new Theme(Theme.MATERIAL, android.R.style.Theme_Material_Panel,
                     Build.VERSION_CODES.LOLLIPOP, "material_panel"),
-            new Theme(android.R.style.Theme_Material_Settings,
+            new Theme(Theme.MATERIAL, android.R.style.Theme_Material_Settings,
                     Build.VERSION_CODES.LOLLIPOP, "material_settings"),
-            new Theme(android.R.style.Theme_Material_Voice,
+            new Theme(Theme.MATERIAL, android.R.style.Theme_Material_Voice,
                     Build.VERSION_CODES.LOLLIPOP, "material_voice"),
-            new Theme(android.R.style.Theme_Material_Wallpaper,
+            new Theme(Theme.MATERIAL, android.R.style.Theme_Material_Wallpaper,
                     Build.VERSION_CODES.LOLLIPOP, "material_wallpaper"),
-            new Theme(android.R.style.Theme_Material_Wallpaper_NoTitleBar,
+            new Theme(Theme.MATERIAL, android.R.style.Theme_Material_Wallpaper_NoTitleBar,
                     Build.VERSION_CODES.LOLLIPOP, "material_wallpaper_notitlebar"),
 
             // Material Light
-            new Theme(android.R.style.Theme_Material_Light,
+            new Theme(Theme.MATERIAL, android.R.style.Theme_Material_Light,
                     Build.VERSION_CODES.LOLLIPOP, "material_light"),
-            new Theme(android.R.style.Theme_Material_Light_DarkActionBar,
+            new Theme(Theme.MATERIAL, android.R.style.Theme_Material_Light_DarkActionBar,
                     Build.VERSION_CODES.LOLLIPOP, "material_light_darkactionbar"),
-            new Theme(android.R.style.Theme_Material_Light_Dialog,
+            new Theme(Theme.MATERIAL, android.R.style.Theme_Material_Light_Dialog,
                     Build.VERSION_CODES.LOLLIPOP, "material_light_dialog"),
-            new Theme(android.R.style.Theme_Material_Light_Dialog_Alert,
+            new Theme(Theme.MATERIAL, android.R.style.Theme_Material_Light_Dialog_Alert,
                     Build.VERSION_CODES.LOLLIPOP, "material_light_dialog_alert"),
-            new Theme(android.R.style.Theme_Material_Light_Dialog_MinWidth,
+            new Theme(Theme.MATERIAL, android.R.style.Theme_Material_Light_Dialog_MinWidth,
                     Build.VERSION_CODES.LOLLIPOP, "material_light_dialog_minwidth"),
-            new Theme(android.R.style.Theme_Material_Light_Dialog_NoActionBar,
+            new Theme(Theme.MATERIAL, android.R.style.Theme_Material_Light_Dialog_NoActionBar,
                     Build.VERSION_CODES.LOLLIPOP, "material_light_dialog_noactionbar"),
-            new Theme(android.R.style.Theme_Material_Light_Dialog_NoActionBar_MinWidth,
+            new Theme(Theme.MATERIAL, android.R.style.Theme_Material_Light_Dialog_NoActionBar_MinWidth,
                     Build.VERSION_CODES.LOLLIPOP, "material_light_dialog_noactionbar_minwidth"),
-            new Theme(android.R.style.Theme_Material_Light_Dialog_Presentation,
+            new Theme(Theme.MATERIAL, android.R.style.Theme_Material_Light_Dialog_Presentation,
                     Build.VERSION_CODES.LOLLIPOP, "material_light_dialog_presentation"),
-            new Theme(android.R.style.Theme_Material_Light_DialogWhenLarge,
+            new Theme(Theme.MATERIAL, android.R.style.Theme_Material_Light_DialogWhenLarge,
                     Build.VERSION_CODES.LOLLIPOP, "material_light_dialogwhenlarge"),
-            new Theme(android.R.style.Theme_Material_Light_DialogWhenLarge_NoActionBar,
+            new Theme(Theme.MATERIAL, android.R.style.Theme_Material_Light_DialogWhenLarge_NoActionBar,
                     Build.VERSION_CODES.LOLLIPOP, "material_light_dialogwhenlarge_noactionbar"),
-            new Theme(android.R.style.Theme_Material_Light_LightStatusBar,
+            new Theme(Theme.MATERIAL, android.R.style.Theme_Material_Light_LightStatusBar,
                     Build.VERSION_CODES.M, "material_light_lightstatusbar"),
-            new Theme(android.R.style.Theme_Material_Light_NoActionBar,
+            new Theme(Theme.MATERIAL, android.R.style.Theme_Material_Light_NoActionBar,
                     Build.VERSION_CODES.LOLLIPOP, "material_light_noactionbar"),
-            new Theme(android.R.style.Theme_Material_Light_NoActionBar_Fullscreen,
+            new Theme(Theme.MATERIAL, android.R.style.Theme_Material_Light_NoActionBar_Fullscreen,
                     Build.VERSION_CODES.LOLLIPOP, "material_light_noactionbar_fullscreen"),
-            new Theme(android.R.style.Theme_Material_Light_NoActionBar_Overscan,
+            new Theme(Theme.MATERIAL, android.R.style.Theme_Material_Light_NoActionBar_Overscan,
                     Build.VERSION_CODES.LOLLIPOP, "material_light_noactionbar_overscan"),
-            new Theme(android.R.style.Theme_Material_Light_NoActionBar_TranslucentDecor,
+            new Theme(Theme.MATERIAL, android.R.style.Theme_Material_Light_NoActionBar_TranslucentDecor,
                     Build.VERSION_CODES.LOLLIPOP, "material_light_noactionbar_translucentdecor"),
-            new Theme(android.R.style.Theme_Material_Light_Panel,
+            new Theme(Theme.MATERIAL, android.R.style.Theme_Material_Light_Panel,
                     Build.VERSION_CODES.LOLLIPOP, "material_light_panel"),
-            new Theme(android.R.style.Theme_Material_Light_Voice,
+            new Theme(Theme.MATERIAL, android.R.style.Theme_Material_Light_Voice,
                     Build.VERSION_CODES.LOLLIPOP, "material_light_voice")
     };
 
diff --git a/hostsidetests/theme/assets/23/420dpi.zip b/hostsidetests/theme/assets/23/420dpi.zip
new file mode 100644
index 0000000..ecf1d54
--- /dev/null
+++ b/hostsidetests/theme/assets/23/420dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/23/560dpi.zip b/hostsidetests/theme/assets/23/560dpi.zip
index cf0a559..231b4f5 100644
--- a/hostsidetests/theme/assets/23/560dpi.zip
+++ b/hostsidetests/theme/assets/23/560dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/generate_images.sh b/hostsidetests/theme/generate_images.sh
index 9bcc3e5..129efc8 100755
--- a/hostsidetests/theme/generate_images.sh
+++ b/hostsidetests/theme/generate_images.sh
@@ -37,7 +37,7 @@
   done
 }
 
-themeApkPath="$ANDROID_HOST_OUT/cts/android-cts/repository/testcases/CtsThemeDeviceApp.apk"
+themeApkPath="$ANDROID_HOST_OUT/cts/android-cts/testcases/CtsThemeDeviceApp.apk"
 outDir="$ANDROID_BUILD_TOP/cts/hostsidetests/theme/assets"
 exe="$ANDROID_BUILD_TOP/cts/hostsidetests/theme/run_theme_capture_device.py"
 
diff --git a/hostsidetests/theme/src/android/theme/cts/ComparisonTask.java b/hostsidetests/theme/src/android/theme/cts/ComparisonTask.java
index 0e11111..c7a5d7c 100755
--- a/hostsidetests/theme/src/android/theme/cts/ComparisonTask.java
+++ b/hostsidetests/theme/src/android/theme/cts/ComparisonTask.java
@@ -18,7 +18,6 @@
 
 import com.android.ddmlib.Log;
 import com.android.ddmlib.Log.LogLevel;
-import com.android.tradefed.device.ITestDevice;
 
 import java.awt.Color;
 import java.awt.image.BufferedImage;
@@ -37,12 +36,10 @@
 
     private static final int IMAGE_THRESHOLD = 2;
 
-    private final ITestDevice mDevice;
     private final File mExpected;
     private final File mActual;
 
-    public ComparisonTask(ITestDevice device, File expected, File actual) {
-        mDevice = device;
+    public ComparisonTask(File expected, File actual) {
         mExpected = expected;
         mActual = actual;
     }
diff --git a/hostsidetests/theme/src/android/theme/cts/ThemeHostTest.java b/hostsidetests/theme/src/android/theme/cts/ThemeHostTest.java
index b4bb748..855f74c 100644
--- a/hostsidetests/theme/src/android/theme/cts/ThemeHostTest.java
+++ b/hostsidetests/theme/src/android/theme/cts/ThemeHostTest.java
@@ -16,12 +16,12 @@
 
 package android.theme.cts;
 
-import com.android.cts.tradefed.build.CtsBuildHelper;
-import com.android.cts.util.AbiUtils;
-import com.android.cts.util.TimeoutReq;
+import com.android.compatibility.common.util.AbiUtils;
+import com.android.cts.migration.MigrationHelper;
 import com.android.ddmlib.Log;
 import com.android.ddmlib.Log.LogLevel;
 import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.device.CollectingOutputReceiver;
 import com.android.tradefed.device.DeviceNotAvailableException;
 import com.android.tradefed.device.ITestDevice;
 import com.android.tradefed.testtype.DeviceTestCase;
@@ -34,12 +34,12 @@
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
-import java.lang.String;
 import java.util.HashMap;
-import java.util.Scanner;
-import java.util.concurrent.Executors;
+import java.util.Map;
 import java.util.concurrent.ExecutorCompletionService;
 import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipInputStream;
 
@@ -47,6 +47,7 @@
  * Test to check non-modifiable themes have not been changed.
  */
 public class ThemeHostTest extends DeviceTestCase implements IAbiReceiver, IBuildReceiver {
+
     private static final String LOG_TAG = "ThemeHostTest";
     private static final String APK_NAME = "CtsThemeDeviceApp";
     private static final String APP_PACKAGE_NAME = "android.theme.app";
@@ -54,12 +55,11 @@
     private static final String GENERATED_ASSETS_ZIP = "/sdcard/cts-theme-assets.zip";
 
     /** The class name of the main activity in the APK. */
-    private static final String CLASS = "GenerateImagesActivity";
+    private static final String TEST_CLASS = "android.support.test.runner.AndroidJUnitRunner";
 
-    /** The command to launch the main activity. */
+    /** The command to launch the main instrumentation test. */
     private static final String START_CMD = String.format(
-            "am start -W -a android.intent.action.MAIN -n %s/%s.%s", APP_PACKAGE_NAME,
-            APP_PACKAGE_NAME, CLASS);
+            "am instrument -w --no-window-animation %s/%s", APP_PACKAGE_NAME, TEST_CLASS);
 
     private static final String CLEAR_GENERATED_CMD = "rm -rf %s/*.png";
     private static final String STOP_CMD = String.format("am force-stop %s", APP_PACKAGE_NAME);
@@ -67,13 +67,17 @@
     private static final String DENSITY_PROP_DEVICE = "ro.sf.lcd_density";
     private static final String DENSITY_PROP_EMULATOR = "qemu.sf.lcd_density";
 
-    private final HashMap<String, File> mReferences = new HashMap<>();
+    /** Overall test timeout is 30 minutes. Should only take about 5. */
+    private static final int TEST_RESULT_TIMEOUT = 30 * 60 * 1000;
+
+    /** Map of reference image names and files. */
+    private Map<String, File> mReferences;
 
     /** The ABI to use. */
     private IAbi mAbi;
 
     /** A reference to the build. */
-    private CtsBuildHelper mBuild;
+    private IBuildInfo mBuildInfo;
 
     /** A reference to the device under test. */
     private ITestDevice mDevice;
@@ -89,8 +93,7 @@
 
     @Override
     public void setBuild(IBuildInfo buildInfo) {
-        // Get the build, this is used to access the APK.
-        mBuild = CtsBuildHelper.createBuildHelper(buildInfo);
+        mBuildInfo = buildInfo;
     }
 
     @Override
@@ -101,19 +104,24 @@
         mDevice.uninstallPackage(APP_PACKAGE_NAME);
 
         // Get the APK from the build.
-        final File app = mBuild.getTestApp(String.format("%s.apk", APK_NAME));
+        final File app = MigrationHelper.getTestFile(mBuildInfo, String.format("%s.apk", APK_NAME));
         final String[] options = {AbiUtils.createAbiFlag(mAbi.getName())};
-
-        mDevice.installPackage(app, false, options);
+        mDevice.installPackage(app, true, true, options);
 
         final String density = getDensityBucketForDevice(mDevice);
         final String zipFile = String.format("/%s.zip", density);
-        Log.logAndDisplay(LogLevel.INFO, LOG_TAG, "Loading resources from " + zipFile);
+        mReferences = extractReferenceImages(zipFile);
 
+        final int numCores = Runtime.getRuntime().availableProcessors();
+        mExecutionService = Executors.newFixedThreadPool(numCores * 2);
+        mCompletionService = new ExecutorCompletionService<>(mExecutionService);
+    }
+
+    private Map<String, File> extractReferenceImages(String zipFile) {
+        final Map<String, File> references = new HashMap<>();
         final InputStream zipStream = ThemeHostTest.class.getResourceAsStream(zipFile);
         if (zipStream != null) {
-            final ZipInputStream in = new ZipInputStream(zipStream);
-            try {
+            try (ZipInputStream in = new ZipInputStream(zipStream)) {
                 ZipEntry ze;
                 final byte[] buffer = new byte[1024];
                 while ((ze = in.getNextEntry()) != null) {
@@ -128,28 +136,22 @@
 
                     out.flush();
                     out.close();
-                    mReferences.put(name, tmp);
+                    references.put(name, tmp);
                 }
             } catch (IOException e) {
-                Log.logAndDisplay(LogLevel.ERROR, LOG_TAG, "Failed to unzip assets: " + zipFile);
-            } finally {
-                in.close();
+                fail("Failed to unzip assets: " + zipFile);
             }
         } else {
-            Log.logAndDisplay(LogLevel.ERROR, LOG_TAG, "Failed to get resource: " + zipFile);
+            fail("Failed to get resource: " + zipFile);
         }
 
-        final int numCores = Runtime.getRuntime().availableProcessors();
-        mExecutionService = Executors.newFixedThreadPool(numCores * 2);
-        mCompletionService = new ExecutorCompletionService<>(mExecutionService);
+        return references;
     }
 
     @Override
     protected void tearDown() throws Exception {
         // Delete the temp files
-        for (File ref : mReferences.values()) {
-            ref.delete();
-        }
+        mReferences.values().forEach(File::delete);
 
         mExecutionService.shutdown();
 
@@ -162,7 +164,6 @@
         super.tearDown();
     }
 
-    @TimeoutReq(minutes = 60)
     public void testThemes() throws Exception {
         if (checkHardwareTypeSkipTest(mDevice.executeShellCommand(HARDWARE_TYPE_CMD).trim())) {
             Log.logAndDisplay(LogLevel.INFO, LOG_TAG, "Skipped themes test for watch");
@@ -170,53 +171,19 @@
         }
 
         if (mReferences.isEmpty()) {
-            Log.logAndDisplay(LogLevel.INFO, LOG_TAG, "Skipped themes test due to no reference images");
+            Log.logAndDisplay(LogLevel.INFO, LOG_TAG,
+                    "Skipped themes test due to missing reference images");
             return;
         }
 
-        Log.logAndDisplay(LogLevel.INFO, LOG_TAG, "Generating device images...");
-
         assertTrue("Aborted image generation", generateDeviceImages());
 
         // Pull ZIP file from remote device.
         final File localZip = File.createTempFile("generated", ".zip");
-        mDevice.pullFile(GENERATED_ASSETS_ZIP, localZip);
+        assertTrue("Failed to pull generated assets from device",
+                mDevice.pullFile(GENERATED_ASSETS_ZIP, localZip));
 
-        int numTasks = 0;
-
-        Log.logAndDisplay(LogLevel.INFO, LOG_TAG, "Extracting generated images...");
-
-        // Extract generated images to temporary files.
-        final byte[] data = new byte[4096];
-        final ZipInputStream zipInput = new ZipInputStream(new FileInputStream(localZip));
-        ZipEntry entry;
-        while ((entry = zipInput.getNextEntry()) != null) {
-            final String name = entry.getName();
-            final File expected = mReferences.get(name);
-            if (expected != null && expected.exists()) {
-                final File actual = File.createTempFile("actual_" + name, ".png");
-                final FileOutputStream pngOutput = new FileOutputStream(actual);
-
-                int count;
-                while ((count = zipInput.read(data, 0, data.length)) != -1) {
-                    pngOutput.write(data, 0, count);
-                }
-
-                pngOutput.flush();
-                pngOutput.close();
-
-                mCompletionService.submit(new ComparisonTask(mDevice, expected, actual));
-                numTasks++;
-            } else {
-                Log.logAndDisplay(LogLevel.INFO, LOG_TAG, "Missing reference image for " + name);
-            }
-
-            zipInput.closeEntry();
-        }
-
-        zipInput.close();
-
-        Log.logAndDisplay(LogLevel.INFO, LOG_TAG, "Waiting for comparison tasks...");
+        final int numTasks = extractGeneratedImages(localZip, mReferences);
 
         int failures = 0;
         for (int i = numTasks; i > 0; i--) {
@@ -224,57 +191,55 @@
         }
 
         assertTrue(failures + " failures in theme test", failures == 0);
+    }
 
-        Log.logAndDisplay(LogLevel.INFO, LOG_TAG, "Finished!");
+    private int extractGeneratedImages(File localZip, Map<String, File> references)
+            throws IOException {
+        int numTasks = 0;
+
+        // Extract generated images to temporary files.
+        final byte[] data = new byte[4096];
+        try (ZipInputStream zipInput = new ZipInputStream(new FileInputStream(localZip))) {
+            ZipEntry entry;
+            while ((entry = zipInput.getNextEntry()) != null) {
+                final String name = entry.getName();
+                final File expected = references.get(name);
+                if (expected != null && expected.exists()) {
+                    final File actual = File.createTempFile("actual_" + name, ".png");
+                    final FileOutputStream pngOutput = new FileOutputStream(actual);
+
+                    int count;
+                    while ((count = zipInput.read(data, 0, data.length)) != -1) {
+                        pngOutput.write(data, 0, count);
+                    }
+
+                    pngOutput.flush();
+                    pngOutput.close();
+
+                    mCompletionService.submit(new ComparisonTask(expected, actual));
+                    numTasks++;
+                } else {
+                    Log.logAndDisplay(LogLevel.INFO, LOG_TAG,
+                            "Missing reference image for " + name);
+                }
+
+                zipInput.closeEntry();
+            }
+        }
+
+        return numTasks;
     }
 
     private boolean generateDeviceImages() throws Exception {
-        // Clear logcat
-        mDevice.executeAdbCommand("logcat", "-c");
-
-        // Stop any existing instances
+        // Stop any existing instances.
         mDevice.executeShellCommand(STOP_CMD);
 
-        // Start activity
-        mDevice.executeShellCommand(START_CMD);
+        // Start instrumentation test.
+        final CollectingOutputReceiver receiver = new CollectingOutputReceiver();
+        mDevice.executeShellCommand(START_CMD, receiver, TEST_RESULT_TIMEOUT,
+                TimeUnit.MILLISECONDS, 0);
 
-        Log.logAndDisplay(LogLevel.VERBOSE, LOG_TAG, "Starting image generation...");
-
-        boolean aborted = false;
-        boolean waiting = true;
-        do {
-            // Dump logcat.
-            final String logs = mDevice.executeAdbCommand(
-                    "logcat", "-v", "brief", "-d", CLASS + ":I", "*:S");
-
-            // Search for string.
-            final Scanner in = new Scanner(logs);
-            while (in.hasNextLine()) {
-                final String line = in.nextLine();
-                if (line.startsWith("I/" + CLASS)) {
-                    final String[] lineSplit = line.split(":");
-                    if (lineSplit.length >= 3) {
-                        final String cmd = lineSplit[1].trim();
-                        final String arg = lineSplit[2].trim();
-                        switch (cmd) {
-                            case "FAIL":
-                                Log.logAndDisplay(LogLevel.WARN, LOG_TAG, line);
-                                Log.logAndDisplay(LogLevel.WARN, LOG_TAG, "Aborting! Check host logs for details.");
-                                aborted = true;
-                                // fall-through
-                            case "OKAY":
-                                waiting = false;
-                                break;
-                        }
-                    }
-                }
-            }
-            in.close();
-        } while (waiting && !aborted);
-
-        Log.logAndDisplay(LogLevel.VERBOSE, LOG_TAG, "Image generation completed!");
-
-        return !aborted;
+        return receiver.getOutput().contains("OK ");
     }
 
     private static String getDensityBucketForDevice(ITestDevice device) {
@@ -303,24 +268,16 @@
                 return "hdpi";
             case 320:
                 return "xhdpi";
-            case 400:
-                return "400dpi";
             case 480:
                 return "xxhdpi";
-            case 560:
-                return "560dpi";
             case 640:
                 return "xxxhdpi";
             default:
-                return "" + density;
+                return density + "dpi";
         }
     }
 
     private static boolean checkHardwareTypeSkipTest(String hardwareTypeString) {
-        if (hardwareTypeString.contains("android.hardware.type.watch")) {
-            return true;
-        }
-
-        return false;
+        return hardwareTypeString.contains("android.hardware.type.watch");
     }
 }
diff --git a/hostsidetests/trustedvoice/Android.mk b/hostsidetests/trustedvoice/Android.mk
index 55e06db..9d6237f 100644
--- a/hostsidetests/trustedvoice/Android.mk
+++ b/hostsidetests/trustedvoice/Android.mk
@@ -27,6 +27,8 @@
 
 LOCAL_CTS_TEST_PACKAGE := android.host.trustedvoice
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
 
 include $(BUILD_CTS_HOST_JAVA_LIBRARY)
 
diff --git a/hostsidetests/trustedvoice/AndroidTest.xml b/hostsidetests/trustedvoice/AndroidTest.xml
new file mode 100644
index 0000000..835db65
--- /dev/null
+++ b/hostsidetests/trustedvoice/AndroidTest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS Trustedvoice host test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsTrustedVoiceApp.apk" />
+    </target_preparer>
+    <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
+        <option name="jar" value="CtsTrustedVoiceHostTestCases.jar" />
+    </test>
+</configuration>
diff --git a/hostsidetests/trustedvoice/app/Android.mk b/hostsidetests/trustedvoice/app/Android.mk
index 598fb27..7a759d8 100644
--- a/hostsidetests/trustedvoice/app/Android.mk
+++ b/hostsidetests/trustedvoice/app/Android.mk
@@ -26,6 +26,9 @@
 
 LOCAL_PACKAGE_NAME := CtsTrustedVoiceApp
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_SDK_VERSION := current
 
-include $(BUILD_CTS_PACKAGE)
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/trustedvoice/src/android/trustedvoice/cts/TrustedVoiceHostTest.java b/hostsidetests/trustedvoice/src/android/trustedvoice/cts/TrustedVoiceHostTest.java
index d075e2c..fd3c827 100644
--- a/hostsidetests/trustedvoice/src/android/trustedvoice/cts/TrustedVoiceHostTest.java
+++ b/hostsidetests/trustedvoice/src/android/trustedvoice/cts/TrustedVoiceHostTest.java
@@ -16,12 +16,7 @@
 
 package android.trustedvoice.cts;
 
-import com.android.cts.tradefed.build.CtsBuildHelper;
-import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.device.ITestDevice;
 import com.android.tradefed.testtype.DeviceTestCase;
-import com.android.tradefed.testtype.IBuildReceiver;
-
 
 import java.io.File;
 import java.lang.String;
@@ -37,7 +32,7 @@
  * into an APK which it then installs at runtime. TrustedVoiceActivity sets the
  * FLAG_DISMISS_KEYGUARD, prints a message to Logcat and then gets uninstalled.
  */
-public class TrustedVoiceHostTest extends DeviceTestCase implements IBuildReceiver {
+public class TrustedVoiceHostTest extends DeviceTestCase {
 
     /**
      * The package name of the APK.
@@ -77,55 +72,19 @@
     private static final String TEST_STRING = "TrustedVoiceTestString";
 
     /**
-     * A reference to the build.
-     */
-    private CtsBuildHelper mBuild;
-
-    /**
-     * A reference to the device under test.
-     */
-    private ITestDevice mDevice;
-
-    @Override
-    public void setBuild(IBuildInfo buildInfo) {
-        // Get the build, this is used to access the APK.
-        mBuild = CtsBuildHelper.createBuildHelper(buildInfo);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        // Get the device, this gives a handle to run commands and install APKs.
-        mDevice = getDevice();
-        // Remove any previously installed versions of this APK.
-        mDevice.uninstallPackage(PACKAGE);
-        // Get the APK from the build.
-        File app = mBuild.getTestApp(APK);
-        // Install the APK on the device.
-        mDevice.installPackage(app, false);
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        // Remove the package once complete.
-        mDevice.uninstallPackage(PACKAGE);
-        super.tearDown();
-    }
-
-    /**
      * Tests the string was successfully logged to Logcat from the activity.
      *
      * @throws Exception
      */
     public void testLogcat() throws Exception {
         // Clear logcat.
-        mDevice.executeAdbCommand("logcat", "-c");
+        getDevice().executeAdbCommand("logcat", "-c");
         // Lock the device
-        mDevice.executeShellCommand(LOCKSCREEN_COMMAND);
+        getDevice().executeShellCommand(LOCKSCREEN_COMMAND);
         // Start the APK and wait for it to complete.
-        mDevice.executeShellCommand(START_COMMAND);
+        getDevice().executeShellCommand(START_COMMAND);
         // Dump logcat.
-        String logs = mDevice.executeAdbCommand("logcat", "-v", "brief", "-d", CLASS + ":I", "*S");
+        String logs = getDevice().executeAdbCommand("logcat", "-v", "brief", "-d", CLASS + ":I", "*S");
         // Search for string.
         Scanner in = new Scanner(logs);
         String testString = "";
diff --git a/hostsidetests/tv/Android.mk b/hostsidetests/tv/Android.mk
new file mode 100644
index 0000000..bb5795b
--- /dev/null
+++ b/hostsidetests/tv/Android.mk
@@ -0,0 +1,36 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+# Only compile source java files in this apk.
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_MODULE := CtsHostsideTvTests
+
+LOCAL_JAVA_LIBRARIES := cts-tradefed tradefed-prebuilt compatibility-host-util
+
+LOCAL_STATIC_JAVA_LIBRARIES := cts-migration-lib
+
+LOCAL_CTS_TEST_PACKAGE := android.tv.hostsidetv
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+include $(BUILD_CTS_HOST_JAVA_LIBRARY)
+
+# Build the test APKs using their own makefiles
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/hostsidetests/tv/AndroidTest.xml b/hostsidetests/tv/AndroidTest.xml
new file mode 100644
index 0000000..c3064eb
--- /dev/null
+++ b/hostsidetests/tv/AndroidTest.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS tv host test cases">
+    <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
+        <option name="jar" value="CtsHostsideTvTests.jar" />
+    </test>
+</configuration>
diff --git a/hostsidetests/tv/app/Android.mk b/hostsidetests/tv/app/Android.mk
new file mode 100644
index 0000000..3235244
--- /dev/null
+++ b/hostsidetests/tv/app/Android.mk
@@ -0,0 +1,35 @@
+#
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+LOCAL_SDK_VERSION := current
+LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctstestrunner
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := CtsHostsideTvInputApp
+
+LOCAL_PROGUARD_ENABLED := disabled
+LOCAL_DEX_PREOPT := false
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/tv/app/AndroidManifest.xml b/hostsidetests/tv/app/AndroidManifest.xml
new file mode 100644
index 0000000..99eeb44
--- /dev/null
+++ b/hostsidetests/tv/app/AndroidManifest.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="com.android.cts.tv.hostside">
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+        <service android:name=".StubTvInputService"
+                 android:permission="android.permission.BIND_TV_INPUT">
+            <intent-filter>
+                <action android:name="android.media.tv.TvInputService"/>
+            </intent-filter>
+            <meta-data android:name="android.media.tv.input"
+                       android:resource="@xml/stub_tv_input_service" />
+        </service>
+    </application>
+
+    <instrumentation
+        android:name="android.support.test.runner.AndroidJUnitRunner"
+        android:targetPackage="com.android.cts.tv.hostside" />
+
+</manifest>
diff --git a/hostsidetests/tv/app/res/xml/stub_tv_input_service.xml b/hostsidetests/tv/app/res/xml/stub_tv_input_service.xml
new file mode 100644
index 0000000..bb9b0b7
--- /dev/null
+++ b/hostsidetests/tv/app/res/xml/stub_tv_input_service.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<tv-input xmlns:android="http://schemas.android.com/apk/res/android"
+    android:setupActivity="com.android.cts.tv.hostside.StubSetupActivity" />
diff --git a/hostsidetests/tv/app/src/com/android/cts/tv/hostside/StubSetupActivity.java b/hostsidetests/tv/app/src/com/android/cts/tv/hostside/StubSetupActivity.java
new file mode 100644
index 0000000..761d56c
--- /dev/null
+++ b/hostsidetests/tv/app/src/com/android/cts/tv/hostside/StubSetupActivity.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.tv.hostside;
+
+import android.preference.PreferenceActivity;
+
+public class StubSetupActivity extends PreferenceActivity {
+
+}
diff --git a/hostsidetests/tv/app/src/com/android/cts/tv/hostside/StubTvInputService.java b/hostsidetests/tv/app/src/com/android/cts/tv/hostside/StubTvInputService.java
new file mode 100644
index 0000000..4292747
--- /dev/null
+++ b/hostsidetests/tv/app/src/com/android/cts/tv/hostside/StubTvInputService.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.tv.hostside;
+
+import android.content.Context;
+import android.media.tv.TvInputService;
+import android.net.Uri;
+import android.view.Surface;
+
+/**
+ * Stub implementation of (@link android.media.tv.TvInputService}.
+ */
+public class StubTvInputService extends TvInputService {
+    @Override
+    public Session onCreateSession(String inputId) {
+        return new StubSessionImpl(this);
+    }
+
+    private static class StubSessionImpl extends Session {
+        StubSessionImpl(Context context) {
+            super(context);
+        }
+
+        @Override
+        public void onRelease() {
+        }
+
+        @Override
+        public boolean onSetSurface(Surface surface) {
+            return false;
+        }
+
+        @Override
+        public void onSetStreamVolume(float volume) {
+        }
+
+        @Override
+        public boolean onTune(Uri channelUri) {
+            return false;
+        }
+
+        @Override
+        public void onSetCaptionEnabled(boolean enabled) {
+        }
+    }
+}
diff --git a/hostsidetests/tv/app2/Android.mk b/hostsidetests/tv/app2/Android.mk
new file mode 100644
index 0000000..a0dcab2
--- /dev/null
+++ b/hostsidetests/tv/app2/Android.mk
@@ -0,0 +1,38 @@
+#
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := CtsHostsideTvInputMonitor
+
+LOCAL_JAVA_LIBRARIES := android.test.runner
+
+LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctstestrunner
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/tv/app2/AndroidManifest.xml b/hostsidetests/tv/app2/AndroidManifest.xml
new file mode 100644
index 0000000..0b20ee5
--- /dev/null
+++ b/hostsidetests/tv/app2/AndroidManifest.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="com.android.cts.tv.hostside.app2">
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+        <activity android:name="com.android.cts.tv.hostside.app2.TvViewMonitorActivity" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+            </intent-filter>
+        </activity>
+    </application>
+
+    <instrumentation
+        android:name="android.support.test.runner.AndroidJUnitRunner"
+        android:targetPackage="com.android.cts.tv.hostside.app2" />
+
+</manifest>
diff --git a/hostsidetests/tv/app2/src/com/android/cts/tv/hostside/app2/TvViewMonitorActivity.java b/hostsidetests/tv/app2/src/com/android/cts/tv/hostside/app2/TvViewMonitorActivity.java
new file mode 100644
index 0000000..33d3a17
--- /dev/null
+++ b/hostsidetests/tv/app2/src/com/android/cts/tv/hostside/app2/TvViewMonitorActivity.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.tv.hostside.app2;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.media.tv.TvInputManager;
+import android.os.Bundle;
+import android.os.Handler;
+import android.util.Log;
+
+public class TvViewMonitorActivity extends Activity {
+    private static final String TAG = TvViewMonitorActivity.class.getSimpleName();
+    private static final String TEST_STRING = "HOST_SIDE_TEST_TV_INTPUT_IS_UPDATED";
+
+    private TvInputManager mManager;
+    private LoggingCallback mCallback = new LoggingCallback();
+
+    private boolean hasTvInputFramework() {
+        return getPackageManager().hasSystemFeature(PackageManager.FEATURE_LIVE_TV);
+    }
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        mManager = (TvInputManager) getSystemService(Context.TV_INPUT_SERVICE);
+        if (hasTvInputFramework()) {
+            mManager.registerCallback(mCallback, new Handler());
+        }
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+        if (hasTvInputFramework()) {
+            mManager.unregisterCallback(mCallback);
+        }
+    }
+
+    private static class LoggingCallback extends TvInputManager.TvInputCallback {
+        @Override
+        public void onInputUpdated(String inputId) {
+            Log.i(TAG, TEST_STRING);
+        }
+    }
+}
diff --git a/hostsidetests/tv/src/com/android/cts/tv/TvInputManagerHostTest.java b/hostsidetests/tv/src/com/android/cts/tv/TvInputManagerHostTest.java
new file mode 100644
index 0000000..65a7928
--- /dev/null
+++ b/hostsidetests/tv/src/com/android/cts/tv/TvInputManagerHostTest.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.tv;
+
+import com.android.ddmlib.Log.LogLevel;
+import com.android.compatibility.common.util.VersionCodes;
+import com.android.cts.migration.MigrationHelper;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.log.LogUtil.CLog;
+import com.android.tradefed.testtype.DeviceTestCase;
+import com.android.tradefed.testtype.IAbi;
+import com.android.tradefed.testtype.IAbiReceiver;
+import com.android.tradefed.testtype.IBuildReceiver;
+
+import java.io.FileNotFoundException;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Scanner;
+
+public class TvInputManagerHostTest extends DeviceTestCase implements IAbiReceiver, IBuildReceiver {
+    private static final String TEST_APK = "CtsHostsideTvInputApp.apk";
+    private static final String TEST_APK2 = "CtsHostsideTvInputMonitor.apk";
+    private static final String TEST_PKG = "com.android.cts.tv.hostside";
+    private static final String TEST_PKG2 = "com.android.cts.tv.hostside.app2";
+    private static final String CLASS = "TvViewMonitorActivity";
+    private static final String INPUT_UPDATED_STRING = "HOST_SIDE_TEST_TV_INTPUT_IS_UPDATED";
+    private static final String START_COMMAND = String.format(
+            "am start -W -a android.intent.action.MAIN -n %s/%s.%s", TEST_PKG2, TEST_PKG2, CLASS);
+    private static final String FEATURE_LIVE_TV = "android.software.live_tv";
+
+    private boolean mHasFeatureLiveTv;
+    private IAbi mAbi;
+    private IBuildInfo mCtsBuildInfo;
+    private HashSet<String> mAvailableFeatures;
+
+    private void installPackage(String apk) throws FileNotFoundException,
+            DeviceNotAvailableException {
+        assertNull(getDevice().installPackage(
+                MigrationHelper.getTestFile(mCtsBuildInfo, apk), true));
+    }
+
+    private void uninstallPackage(String packageName, boolean shouldSucceed)
+            throws DeviceNotAvailableException {
+        final String result = getDevice().uninstallPackage(packageName);
+        if (shouldSucceed) {
+            assertNull("uninstallPackage(" + packageName + ") failed: " + result, result);
+        }
+    }
+
+    @Override
+    public void setAbi(IAbi abi) {
+        mAbi = abi;
+    }
+
+    @Override
+    public void setBuild(IBuildInfo buildInfo) {
+        mCtsBuildInfo = buildInfo;
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        assertNotNull(mAbi);
+        assertNotNull(mCtsBuildInfo);
+        mHasFeatureLiveTv = hasDeviceFeature(FEATURE_LIVE_TV);
+        if (mHasFeatureLiveTv) {
+            uninstallPackage(TEST_PKG, false);
+            uninstallPackage(TEST_PKG2, false);
+            installPackage(TEST_APK);
+            installPackage(TEST_APK2);
+        }
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+        if (mHasFeatureLiveTv) {
+            uninstallPackage(TEST_PKG, true);
+            uninstallPackage(TEST_PKG2, true);
+        }
+    }
+
+    public void testInputUpdated() throws Exception {
+        if (!mHasFeatureLiveTv) {
+            return;
+        }
+        ITestDevice device = getDevice();
+        device.executeAdbCommand("logcat", "-c");
+        device.executeShellCommand(START_COMMAND);
+        // Re-install the input app so the monitoring app can get the onInputUpdated callback.
+        installPackage(TEST_APK);
+        String logs = device.executeAdbCommand("logcat", "-v", "brief", "-d", CLASS + ":I", "*:S");
+        String testString = "";
+        Scanner in = new Scanner(logs);
+        while (in.hasNextLine()) {
+            String line = in.nextLine();
+            if(line.contains(INPUT_UPDATED_STRING)) {
+                testString = line.split(":")[1].trim();
+            }
+        }
+        in.close();
+        assertEquals("Incorrect test string", INPUT_UPDATED_STRING, testString);
+    }
+
+    private boolean hasDeviceFeature(String requiredFeature) throws DeviceNotAvailableException {
+        if (mAvailableFeatures == null) {
+            // TODO: Move this logic to ITestDevice.
+            String command = "pm list features";
+            String commandOutput = getDevice().executeShellCommand(command);
+            CLog.i("Output for command " + command + ": " + commandOutput);
+
+            // Extract the id of the new user.
+            mAvailableFeatures = new HashSet<>();
+            for (String feature: commandOutput.split("\\s+")) {
+                // Each line in the output of the command has the format "feature:{FEATURE_VALUE}".
+                String[] tokens = feature.split(":");
+                assertTrue("\"" + feature + "\" expected to have format feature:{FEATURE_VALUE}",
+                        tokens.length > 1);
+                assertEquals(feature, "feature", tokens[0]);
+                mAvailableFeatures.add(tokens[1]);
+            }
+        }
+        boolean result = mAvailableFeatures.contains(requiredFeature);
+        if (!result) {
+            CLog.logAndDisplay(LogLevel.INFO, "Device doesn't have required feature "
+            + requiredFeature + ". Test won't run.");
+        }
+        return result;
+    }
+}
diff --git a/hostsidetests/ui/Android.mk b/hostsidetests/ui/Android.mk
new file mode 100644
index 0000000..7060bdf
--- /dev/null
+++ b/hostsidetests/ui/Android.mk
@@ -0,0 +1,40 @@
+# Copyright (C) 2012 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE := CtsUiHostTestCases
+
+LOCAL_JAVA_LIBRARIES := cts-tradefed tradefed-prebuilt compatibility-host-util
+
+LOCAL_STATIC_JAVA_LIBRARIES := cts-migration-lib
+
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
+
+$(COMPATIBILITY_TESTCASES_OUT_cts)/CtsUiHostTestCases.jar : $(COMPATIBILITY_TESTCASES_OUT_cts)/com.replica.replicaisland.apk
+
+LOCAL_CTS_TEST_PACKAGE := android.ui.cts
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+include $(BUILD_CTS_HOST_JAVA_LIBRARY)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/hostsidetests/ui/AndroidTest.xml b/hostsidetests/ui/AndroidTest.xml
new file mode 100644
index 0000000..7d17e2b
--- /dev/null
+++ b/hostsidetests/ui/AndroidTest.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS UI host test cases">
+    <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
+        <option name="jar" value="CtsUiHostTestCases.jar" />
+        <option name="runtime-hint" value="2m" />
+    </test>
+</configuration>
diff --git a/hostsidetests/ui/appA/Android.mk b/hostsidetests/ui/appA/Android.mk
new file mode 100644
index 0000000..e3d458b
--- /dev/null
+++ b/hostsidetests/ui/appA/Android.mk
@@ -0,0 +1,34 @@
+# Copyright (C) 2012 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+# don't include this package in any target
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctstestrunner
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := CtsDeviceTaskSwitchingAppA
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/ui/appA/AndroidManifest.xml b/hostsidetests/ui/appA/AndroidManifest.xml
new file mode 100644
index 0000000..f336abd
--- /dev/null
+++ b/hostsidetests/ui/appA/AndroidManifest.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2012 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="android.taskswitching.appa">
+
+    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+
+    <application>
+        <activity
+            android:name=".AppAActivity"
+            android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode"
+            android:screenOrientation="portrait" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+
+</manifest>
\ No newline at end of file
diff --git a/hostsidetests/ui/appA/src/android/taskswitching/appa/AppAActivity.java b/hostsidetests/ui/appA/src/android/taskswitching/appa/AppAActivity.java
new file mode 100644
index 0000000..32ccfc1
--- /dev/null
+++ b/hostsidetests/ui/appA/src/android/taskswitching/appa/AppAActivity.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.taskswitching.appa;
+
+import android.app.ListActivity;
+import android.content.Intent;
+
+import android.os.Bundle;
+import android.os.Handler;
+import android.view.WindowManager;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+
+/**
+ * Simple activity to notify completion via broadcast after onResume.
+ * This is for measuring taskswitching time between two apps.
+ */
+public class AppAActivity extends ListActivity {
+    static final String TAG = "AppAActivity";
+    private static final int NUMBER_ELEMENTS = 1000;
+    private static final String TASKSWITCHING_INTENT = "android.taskswitching.appa";
+    private Handler mHandler;
+
+    private String[] mItems = new String[NUMBER_ELEMENTS];
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
+        for (int i = 0; i < NUMBER_ELEMENTS; i++) {
+            mItems[i] = "A" + Integer.toString(i);
+        }
+        setListAdapter(new ArrayAdapter<String>(this,
+                android.R.layout.simple_list_item_1, mItems));
+        ListView view = getListView();
+        mHandler = new Handler();
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        mHandler.post(new Runnable() {
+
+            @Override
+            public void run() {
+                Intent intent = new Intent(TASKSWITCHING_INTENT);
+                sendBroadcast(intent);
+            }
+        });
+    }
+}
diff --git a/hostsidetests/ui/appB/Android.mk b/hostsidetests/ui/appB/Android.mk
new file mode 100644
index 0000000..c7642fd
--- /dev/null
+++ b/hostsidetests/ui/appB/Android.mk
@@ -0,0 +1,34 @@
+# Copyright (C) 2012 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+# don't include this package in any target
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctstestrunner
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := CtsDeviceTaskSwitchingAppB
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/ui/appB/AndroidManifest.xml b/hostsidetests/ui/appB/AndroidManifest.xml
new file mode 100644
index 0000000..aaf7a2c
--- /dev/null
+++ b/hostsidetests/ui/appB/AndroidManifest.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="android.taskswitching.appb">
+
+    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+
+    <application>
+        <activity
+            android:name=".AppBActivity"
+            android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode"
+            android:screenOrientation="portrait" >
+
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER"/>
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
diff --git a/hostsidetests/ui/appB/src/android/taskswitching/appb/AppBActivity.java b/hostsidetests/ui/appB/src/android/taskswitching/appb/AppBActivity.java
new file mode 100644
index 0000000..ea7f52a
--- /dev/null
+++ b/hostsidetests/ui/appB/src/android/taskswitching/appb/AppBActivity.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.taskswitching.appb;
+
+import android.app.ListActivity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Handler;
+import android.view.WindowManager;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+
+/**
+ * Simple activity to notify completion via broadcast after onResume.
+ * This is for measuring taskswitching time between two apps.
+ */
+public class AppBActivity extends ListActivity {
+    static final String TAG = "AppBActivity";
+    private static final int NUMBER_ELEMENTS = 1000;
+    private static final String TASKSWITCHING_INTENT = "android.taskswitching.appb";
+    private Handler mHandler;
+
+    private String[] mItems = new String[NUMBER_ELEMENTS];
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
+        for (int i = 0; i < NUMBER_ELEMENTS; i++) {
+            mItems[i] = "B" + Integer.toString(i);
+        }
+        setListAdapter(new ArrayAdapter<String>(this,
+                android.R.layout.simple_list_item_1, mItems));
+        ListView view = getListView();
+        mHandler = new Handler();
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        mHandler.post(new Runnable() {
+
+            @Override
+            public void run() {
+                Intent intent = new Intent(TASKSWITCHING_INTENT);
+                sendBroadcast(intent);
+            }
+        });
+    }
+}
diff --git a/hostsidetests/ui/control/Android.mk b/hostsidetests/ui/control/Android.mk
new file mode 100644
index 0000000..5365a6f
--- /dev/null
+++ b/hostsidetests/ui/control/Android.mk
@@ -0,0 +1,34 @@
+# Copyright (C) 2012 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+# don't include this package in any target
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil compatibility-device-util ctstestrunner
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := CtsDeviceTaskSwitchingControl
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/ui/control/AndroidManifest.xml b/hostsidetests/ui/control/AndroidManifest.xml
new file mode 100644
index 0000000..8102620
--- /dev/null
+++ b/hostsidetests/ui/control/AndroidManifest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="android.taskswitching.control.cts">
+
+    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+    <instrumentation
+        android:targetPackage="android.taskswitching.control.cts"
+        android:name="android.support.test.runner.AndroidJUnitRunner" >
+        <meta-data
+            android:name="listener"
+            android:value="com.android.cts.runner.CtsTestRunListener" />
+    </instrumentation>
+</manifest>
diff --git a/hostsidetests/ui/control/src/android/taskswitching/control/cts/TaskSwitchingDeviceTest.java b/hostsidetests/ui/control/src/android/taskswitching/control/cts/TaskSwitchingDeviceTest.java
new file mode 100644
index 0000000..13b60be
--- /dev/null
+++ b/hostsidetests/ui/control/src/android/taskswitching/control/cts/TaskSwitchingDeviceTest.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.taskswitching.control.cts;
+
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+
+import android.cts.util.CtsAndroidTestCase;
+
+import com.android.compatibility.common.util.DeviceReportLog;
+import com.android.compatibility.common.util.MeasureRun;
+import com.android.compatibility.common.util.MeasureTime;
+import com.android.compatibility.common.util.ResultType;
+import com.android.compatibility.common.util.ResultUnit;
+import com.android.compatibility.common.util.Stat;
+
+/**
+ * Device test which actually launches two apps sequentially and
+ * measure time for switching.
+ * Completion of launch is notified via broadcast.
+ */
+public class TaskSwitchingDeviceTest extends CtsAndroidTestCase {
+    private static final String PKG_A = "android.taskswitching.appa";
+    private static final String PKG_B = "android.taskswitching.appb";
+    private static final String ACTIVITY_A = "AppAActivity";
+    private static final String ACTIVITY_B = "AppBActivity";
+    private static final long TASK_SWITCHING_WAIT_TIME = 5;
+    private final AppBroadcastReceiver mReceiverA = new AppBroadcastReceiver();
+    private final AppBroadcastReceiver mReceiverB = new AppBroadcastReceiver();
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        startActivity(PKG_A, ACTIVITY_A);
+        startActivity(PKG_B, ACTIVITY_B);
+        IntentFilter filterA = new IntentFilter();
+        filterA.addAction(PKG_A);
+        IntentFilter filterB = new IntentFilter();
+        filterB.addAction(PKG_B);
+        getContext().registerReceiver(mReceiverA, filterA);
+        getContext().registerReceiver(mReceiverB, filterB);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        getContext().unregisterReceiver(mReceiverA);
+        getContext().unregisterReceiver(mReceiverB);
+        super.tearDown();
+    }
+
+    public void testMeasureTaskSwitching() throws Exception {
+        final int NUMBER_REPEAT = 10;
+        final int SWITCHING_PER_ONE_TRY = 10;
+
+        double[] results = MeasureTime.measure(NUMBER_REPEAT, new MeasureRun() {
+
+            @Override
+            public void run(int i) throws Exception {
+                for (int j = 0; j < SWITCHING_PER_ONE_TRY; j++) {
+                    startActivity(PKG_A, ACTIVITY_A);
+                    assertTrue(mReceiverA.waitForBroadcast(TASK_SWITCHING_WAIT_TIME));
+                    startActivity(PKG_B, ACTIVITY_B);
+                    assertTrue(mReceiverB.waitForBroadcast(TASK_SWITCHING_WAIT_TIME));
+                }
+            }
+        });
+        DeviceReportLog report = new DeviceReportLog();
+        report.addValues("task switching time", results, ResultType.LOWER_BETTER, ResultUnit.MS);
+        Stat.StatResult stat = Stat.getStat(results);
+        report.setSummary("task switching time", stat.mAverage,
+                ResultType.LOWER_BETTER, ResultUnit.MS);
+        report.submit(getInstrumentation());
+    }
+
+    private void startActivity(String packageName, String activityName) {
+        Context context = getContext();
+        Intent intent = new Intent();
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        intent.addCategory(Intent.CATEGORY_LAUNCHER);
+        intent.setComponent(new ComponentName(packageName, packageName + "." + activityName));
+        context.startActivity(intent);
+    }
+
+    class AppBroadcastReceiver extends BroadcastReceiver {
+        private final Semaphore mSemaphore = new Semaphore(0);
+
+        public boolean waitForBroadcast(long timeoutInSec) throws InterruptedException {
+            return mSemaphore.tryAcquire(timeoutInSec, TimeUnit.SECONDS);
+        }
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            mSemaphore.release();
+        }
+    }
+}
diff --git a/hostsidetests/ui/src/android/ui/cts/InstallTimeTest.java b/hostsidetests/ui/src/android/ui/cts/InstallTimeTest.java
new file mode 100644
index 0000000..d91944a
--- /dev/null
+++ b/hostsidetests/ui/src/android/ui/cts/InstallTimeTest.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.ui.cts;
+
+import com.android.compatibility.common.util.AbiUtils;
+import com.android.compatibility.common.util.MeasureRun;
+import com.android.compatibility.common.util.MeasureTime;
+import com.android.compatibility.common.util.MetricsReportLog;
+import com.android.compatibility.common.util.ResultType;
+import com.android.compatibility.common.util.ResultUnit;
+import com.android.compatibility.common.util.Stat;
+import com.android.cts.migration.MigrationHelper;
+import com.android.ddmlib.Log;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceTestCase;
+import com.android.tradefed.testtype.IAbi;
+import com.android.tradefed.testtype.IAbiReceiver;
+import com.android.tradefed.testtype.IBuildReceiver;
+
+import java.io.File;
+
+/**
+ * Test to measure installation time of a APK.
+ */
+public class InstallTimeTest extends DeviceTestCase implements IAbiReceiver, IBuildReceiver {
+    private IBuildInfo mBuild;
+    private ITestDevice mDevice;
+    private IAbi mAbi;
+
+    private static final String TAG = "InstallTimeTest";
+    static final String PACKAGE = "com.replica.replicaisland";
+    static final String APK = "com.replica.replicaisland.apk";
+    private static final double OUTLIER_THRESHOLD = 0.1;
+
+    @Override
+    public void setAbi(IAbi abi) {
+        mAbi = abi;
+    }
+
+    @Override
+    public void setBuild(IBuildInfo buildInfo) {
+        mBuild = buildInfo;
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mDevice = getDevice();
+    }
+
+
+    @Override
+    protected void tearDown() throws Exception {
+        mDevice.uninstallPackage(PACKAGE);
+        super.tearDown();
+    }
+
+    public void testInstallTime() throws Exception {
+        MetricsReportLog report = new MetricsReportLog(mDevice.getSerialNumber(), mAbi.getName(),
+                String.format("%s#%s", getClass().getName(), "testInstallTime"));
+        final int NUMBER_REPEAT = 10;
+        final IBuildInfo build = mBuild;
+        final ITestDevice device = mDevice;
+        double[] result = MeasureTime.measure(NUMBER_REPEAT, new MeasureRun() {
+            @Override
+            public void prepare(int i) throws Exception {
+                device.uninstallPackage(PACKAGE);
+            }
+            @Override
+            public void run(int i) throws Exception {
+                File app = MigrationHelper.getTestFile(build, APK);
+                String[] options = {AbiUtils.createAbiFlag(mAbi.getName())};
+                device.installPackage(app, false, options);
+            }
+        });
+        report.addValues("install time", result, ResultType.LOWER_BETTER, ResultUnit.MS);
+        Stat.StatResult stat = Stat.getStatWithOutlierRejection(result, OUTLIER_THRESHOLD);
+        if (stat.mDataCount != result.length) {
+            Log.w(TAG, "rejecting " + (result.length - stat.mDataCount) + " outliers");
+        }
+        report.setSummary("install time", stat.mAverage, ResultType.LOWER_BETTER, ResultUnit.MS);
+        report.submit();
+    }
+
+}
diff --git a/hostsidetests/ui/src/android/ui/cts/TaskSwitchingTest.java b/hostsidetests/ui/src/android/ui/cts/TaskSwitchingTest.java
new file mode 100644
index 0000000..4af40a2
--- /dev/null
+++ b/hostsidetests/ui/src/android/ui/cts/TaskSwitchingTest.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.ui.cts;
+
+import com.android.compatibility.common.util.AbiUtils;
+import com.android.compatibility.common.util.MetricsStore;
+import com.android.compatibility.common.util.ReportLog;
+import com.android.cts.migration.MigrationHelper;
+import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
+import com.android.ddmlib.testrunner.TestIdentifier;
+import com.android.ddmlib.testrunner.TestRunResult;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.result.CollectingTestListener;
+import com.android.tradefed.testtype.DeviceTestCase;
+import com.android.tradefed.testtype.IAbi;
+import com.android.tradefed.testtype.IAbiReceiver;
+import com.android.tradefed.testtype.IBuildReceiver;
+
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Map;
+
+/**
+ * Measure time to taskswitching between two Apps: A & B
+ * Actual test is done in device, but this host side code installs all necessary APKs
+ * and starts device test which is in CtsDeviceTaskswitchingControl.
+ */
+public class TaskSwitchingTest extends DeviceTestCase implements IAbiReceiver, IBuildReceiver {
+    private static final String TAG = "TaskSwitchingTest";
+    private final static String RUNNER = "android.support.test.runner.AndroidJUnitRunner";
+    private static final String RESULT_KEY = "COMPATIBILITY_TEST_RESULT";
+    private IBuildInfo mBuild;
+    private ITestDevice mDevice;
+    private ReportLog mReport = null;
+    private IAbi mAbi;
+
+    static final String[] PACKAGES = {
+        "android.taskswitching.control.cts",
+        "android.taskswitching.appa",
+        "android.taskswitching.appb"
+    };
+    static final String[] APKS = {
+        "CtsDeviceTaskSwitchingControl.apk",
+        "CtsDeviceTaskSwitchingAppA.apk",
+        "CtsDeviceTaskSwitchingAppB.apk"
+    };
+
+    @Override
+    public void setAbi(IAbi abi) {
+        mAbi = abi;
+    }
+
+    @Override
+    public void setBuild(IBuildInfo buildInfo) {
+        mBuild = buildInfo;
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mDevice = getDevice();
+        String[] options = {AbiUtils.createAbiFlag(mAbi.getName())};
+        for (int i = 0; i < PACKAGES.length; i++) {
+            mDevice.uninstallPackage(PACKAGES[i]);
+            File app = MigrationHelper.getTestFile(mBuild, APKS[i]);
+            mDevice.installPackage(app, false, options);
+        }
+    }
+
+
+    @Override
+    protected void tearDown() throws Exception {
+        for (int i = 0; i < PACKAGES.length; i++) {
+            mDevice.uninstallPackage(PACKAGES[i]);
+        }
+        super.tearDown();
+    }
+
+    public void testTaskSwitching() throws Exception {
+        RemoteAndroidTestRunner testRunner = new RemoteAndroidTestRunner(PACKAGES[0], RUNNER,
+                mDevice.getIDevice());
+        LocalListener listener = new LocalListener();
+        mDevice.runInstrumentationTests(testRunner, listener);
+        TestRunResult result = listener.getCurrentRunResults();
+        if (result.isRunFailure()) {
+            fail(result.getRunFailureMessage());
+        }
+        assertNotNull("no performance data", mReport);
+        MetricsStore.storeResult(mDevice.getSerialNumber(), mAbi.getName(),
+                String.format("%s#%s", getClass().getName(), "testTaskSwitching"), mReport);
+
+    }
+
+    public class LocalListener extends CollectingTestListener {
+        @Override
+        public void testEnded(TestIdentifier test, Map<String, String> testMetrics) {
+            // necessary as testMetrics passed from CollectingTestListerner is empty
+            if (testMetrics.containsKey(RESULT_KEY)) {
+                try {
+                    mReport = ReportLog.parse(testMetrics.get(RESULT_KEY));
+                } catch (XmlPullParserException | IOException e) {
+                    e.printStackTrace();
+                }
+            }
+            super.testEnded(test, testMetrics);
+        }
+    }
+}
diff --git a/hostsidetests/usage/Android.mk b/hostsidetests/usage/Android.mk
index 1d4e36d..72b9473 100644
--- a/hostsidetests/usage/Android.mk
+++ b/hostsidetests/usage/Android.mk
@@ -19,12 +19,15 @@
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
 # Must match the package name in CtsTestCaseList.mk
-LOCAL_MODULE := CtsUsageHostTestCases
+LOCAL_MODULE := CtsAppUsageHostTestCases
 
 LOCAL_JAVA_LIBRARIES := cts-tradefed tradefed-prebuilt
 
 LOCAL_CTS_TEST_PACKAGE := android.host.app.usage
 
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_CTS_HOST_JAVA_LIBRARY)
 
 include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/hostsidetests/usage/AndroidTest.xml b/hostsidetests/usage/AndroidTest.xml
new file mode 100644
index 0000000..bba2748
--- /dev/null
+++ b/hostsidetests/usage/AndroidTest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS App Usage host test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsAppUsageTestApp.apk" />
+    </target_preparer>
+    <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
+        <option name="jar" value="CtsAppUsageHostTestCases.jar" />
+    </test>
+</configuration>
diff --git a/hostsidetests/usage/app/Android.mk b/hostsidetests/usage/app/Android.mk
index b23efbc..7347b9b 100644
--- a/hostsidetests/usage/app/Android.mk
+++ b/hostsidetests/usage/app/Android.mk
@@ -23,6 +23,9 @@
 
 LOCAL_SDK_VERSION := current
 
-LOCAL_PACKAGE_NAME := CtsDeviceAppUsageTestApp
+LOCAL_PACKAGE_NAME := CtsAppUsageTestApp
+
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
 
 include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/usage/app/AndroidManifest.xml b/hostsidetests/usage/app/AndroidManifest.xml
index bad453f..7d5ce48 100755
--- a/hostsidetests/usage/app/AndroidManifest.xml
+++ b/hostsidetests/usage/app/AndroidManifest.xml
@@ -16,7 +16,7 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.app.usage.test">
+    package="android.app.usage.app">
 
     <application>
         <activity android:name=".TestActivity">
diff --git a/hostsidetests/usage/app/src/android/app/usage/app/TestActivity.java b/hostsidetests/usage/app/src/android/app/usage/app/TestActivity.java
new file mode 100644
index 0000000..8cb5842
--- /dev/null
+++ b/hostsidetests/usage/app/src/android/app/usage/app/TestActivity.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.usage.app;
+
+import android.app.Activity;
+
+public class TestActivity extends Activity {
+}
\ No newline at end of file
diff --git a/hostsidetests/usage/app/src/com/android/cts/app/usage/test/TestActivity.java b/hostsidetests/usage/app/src/com/android/cts/app/usage/test/TestActivity.java
deleted file mode 100644
index 9432477..0000000
--- a/hostsidetests/usage/app/src/com/android/cts/app/usage/test/TestActivity.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.app.usage.test;
-
-import android.app.Activity;
-
-public class TestActivity extends Activity {
-}
\ No newline at end of file
diff --git a/hostsidetests/usage/src/android/app/usage/cts/AppIdleHostTest.java b/hostsidetests/usage/src/android/app/usage/cts/AppIdleHostTest.java
new file mode 100644
index 0000000..3cd7bda
--- /dev/null
+++ b/hostsidetests/usage/src/android/app/usage/cts/AppIdleHostTest.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.usage.cts;
+
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceTestCase;
+
+public class AppIdleHostTest extends DeviceTestCase {
+    private static final String SETTINGS_APP_IDLE_CONSTANTS = "app_idle_constants";
+
+    private static final String TEST_APP_PACKAGE = "android.app.usage.app";
+    private static final String TEST_APP_CLASS = "TestActivity";
+
+    private static final long ACTIVITY_LAUNCH_WAIT_MILLIS = 500;
+
+    /**
+     * A reference to the device under test.
+     */
+    private ITestDevice mDevice;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        // Get the device, this gives a handle to run commands and install APKs.
+        mDevice = getDevice();
+    }
+
+    /**
+     * Checks whether an package is idle.
+     * @param appPackage The package to check for idleness.
+     * @return true if the package is idle
+     * @throws DeviceNotAvailableException
+     */
+    private boolean isAppIdle(String appPackage) throws DeviceNotAvailableException {
+        String result = mDevice.executeShellCommand(String.format("am get-inactive %s", appPackage));
+        return result.contains("Idle=true");
+    }
+
+    /**
+     * Set the app idle settings.
+     * @param settingsStr The settings string, a comma separated key=value list.
+     * @throws DeviceNotAvailableException
+     */
+    private void setAppIdleSettings(String settingsStr) throws DeviceNotAvailableException {
+        mDevice.executeShellCommand(String.format("settings put global %s \"%s\"",
+                SETTINGS_APP_IDLE_CONSTANTS, settingsStr));
+    }
+
+    /**
+     * Get the current app idle settings.
+     * @throws DeviceNotAvailableException
+     */
+    private String getAppIdleSettings() throws DeviceNotAvailableException {
+        String result = mDevice.executeShellCommand(String.format("settings get global %s",
+                SETTINGS_APP_IDLE_CONSTANTS));
+        return result.trim();
+    }
+
+    /**
+     * Launch the test app for a few hundred milliseconds then launch home.
+     * @throws DeviceNotAvailableException
+     */
+    private void startAndStopTestApp() throws DeviceNotAvailableException {
+        // Launch the app.
+        mDevice.executeShellCommand(
+                String.format("am start -W -a android.intent.action.MAIN -n %s/%s.%s",
+                        TEST_APP_PACKAGE, TEST_APP_PACKAGE, TEST_APP_CLASS));
+
+        // Wait for some time.
+        sleepUninterrupted(ACTIVITY_LAUNCH_WAIT_MILLIS);
+
+        // Launch home.
+        mDevice.executeShellCommand(
+                "am start -W -a android.intent.action.MAIN -c android.intent.category.HOME");
+    }
+
+    /**
+     * Tests that the app is not idle right after it is launched.
+     */
+    public void testAppIsNotIdleAfterBeingLaunched() throws Exception {
+        final String previousState = getAppIdleSettings();
+        try {
+            // Set the app idle time to something large.
+            setAppIdleSettings("idle_duration=10000,wallclock_threshold=10000");
+            startAndStopTestApp();
+            assertFalse(isAppIdle(TEST_APP_PACKAGE));
+        } finally {
+            setAppIdleSettings(previousState);
+        }
+    }
+
+    private static void sleepUninterrupted(long timeMillis) {
+        boolean interrupted;
+        do {
+            try {
+                Thread.sleep(timeMillis);
+                interrupted = false;
+            } catch (InterruptedException e) {
+                interrupted = true;
+            }
+        } while (interrupted);
+    }
+}
diff --git a/hostsidetests/usage/src/com/android/cts/app/usage/AppIdleHostTest.java b/hostsidetests/usage/src/com/android/cts/app/usage/AppIdleHostTest.java
deleted file mode 100644
index b94d086..0000000
--- a/hostsidetests/usage/src/com/android/cts/app/usage/AppIdleHostTest.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.app.usage;
-
-import com.android.cts.tradefed.build.CtsBuildHelper;
-import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.testtype.DeviceTestCase;
-import com.android.tradefed.testtype.IBuildReceiver;
-
-public class AppIdleHostTest extends DeviceTestCase implements IBuildReceiver {
-    private static final String SETTINGS_APP_IDLE_CONSTANTS = "app_idle_constants";
-
-    private static final String TEST_APP_PACKAGE = "com.android.cts.app.usage.test";
-    private static final String TEST_APP_APK = "CtsDeviceAppUsageTestApp.apk";
-    private static final String TEST_APP_CLASS = "TestActivity";
-
-    private static final long ACTIVITY_LAUNCH_WAIT_MILLIS = 500;
-
-    /**
-     * A reference to the build.
-     */
-    private CtsBuildHelper mBuild;
-
-    /**
-     * A reference to the device under test.
-     */
-    private ITestDevice mDevice;
-
-    @Override
-    public void setBuild(IBuildInfo buildInfo) {
-        // Get the build, this is used to access the APK.
-        mBuild = CtsBuildHelper.createBuildHelper(buildInfo);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        // Get the device, this gives a handle to run commands and install APKs.
-        mDevice = getDevice();
-
-        // Remove any previously installed versions of this APK.
-        mDevice.uninstallPackage(TEST_APP_PACKAGE);
-
-        // Install the APK on the device.
-        mDevice.installPackage(mBuild.getTestApp(TEST_APP_APK), false);
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        // Remove the package once complete.
-        mDevice.uninstallPackage(TEST_APP_PACKAGE);
-        super.tearDown();
-    }
-
-    /**
-     * Checks whether an package is idle.
-     * @param appPackage The package to check for idleness.
-     * @return true if the package is idle
-     * @throws DeviceNotAvailableException
-     */
-    private boolean isAppIdle(String appPackage) throws DeviceNotAvailableException {
-        String result = mDevice.executeShellCommand(String.format("am get-inactive %s", appPackage));
-        return result.contains("Idle=true");
-    }
-
-    /**
-     * Set the app idle settings.
-     * @param settingsStr The settings string, a comma separated key=value list.
-     * @throws DeviceNotAvailableException
-     */
-    private void setAppIdleSettings(String settingsStr) throws DeviceNotAvailableException {
-        mDevice.executeShellCommand(String.format("settings put global %s \"%s\"",
-                SETTINGS_APP_IDLE_CONSTANTS, settingsStr));
-    }
-
-    /**
-     * Get the current app idle settings.
-     * @throws DeviceNotAvailableException
-     */
-    private String getAppIdleSettings() throws DeviceNotAvailableException {
-        String result = mDevice.executeShellCommand(String.format("settings get global %s",
-                SETTINGS_APP_IDLE_CONSTANTS));
-        return result.trim();
-    }
-
-    /**
-     * Launch the test app for a few hundred milliseconds then launch home.
-     * @throws DeviceNotAvailableException
-     */
-    private void startAndStopTestApp() throws DeviceNotAvailableException {
-        // Launch the app.
-        mDevice.executeShellCommand(
-                String.format("am start -W -a android.intent.action.MAIN -n %s/%s.%s",
-                        TEST_APP_PACKAGE, TEST_APP_PACKAGE, TEST_APP_CLASS));
-
-        // Wait for some time.
-        sleepUninterrupted(ACTIVITY_LAUNCH_WAIT_MILLIS);
-
-        // Launch home.
-        mDevice.executeShellCommand(
-                "am start -W -a android.intent.action.MAIN -c android.intent.category.HOME");
-    }
-
-    /**
-     * Tests that the app is not idle right after it is launched.
-     */
-    public void testAppIsNotIdleAfterBeingLaunched() throws Exception {
-        final String previousState = getAppIdleSettings();
-        try {
-            // Set the app idle time to something large.
-            setAppIdleSettings("idle_duration=10000,wallclock_threshold=10000");
-            startAndStopTestApp();
-            assertFalse(isAppIdle(TEST_APP_PACKAGE));
-        } finally {
-            setAppIdleSettings(previousState);
-        }
-    }
-
-    private static void sleepUninterrupted(long timeMillis) {
-        boolean interrupted;
-        do {
-            try {
-                Thread.sleep(timeMillis);
-                interrupted = false;
-            } catch (InterruptedException e) {
-                interrupted = true;
-            }
-        } while (interrupted);
-    }
-}
diff --git a/hostsidetests/usb/Android.mk b/hostsidetests/usb/Android.mk
index f93dfa4..a96c5d8 100644
--- a/hostsidetests/usb/Android.mk
+++ b/hostsidetests/usb/Android.mk
@@ -21,10 +21,15 @@
 
 LOCAL_MODULE := CtsUsbTests
 
-LOCAL_JAVA_LIBRARIES := cts-tradefed tradefed-prebuilt
+LOCAL_JAVA_LIBRARIES := cts-tradefed tradefed-prebuilt compatibility-host-util
+
+LOCAL_STATIC_JAVA_LIBRARIES := cts-migration-lib
 
 LOCAL_CTS_TEST_PACKAGE := android.usb
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_CTS_HOST_JAVA_LIBRARY)
 
 # Build the test APKs using their own makefiles
diff --git a/hostsidetests/usb/AndroidTest.xml b/hostsidetests/usb/AndroidTest.xml
new file mode 100644
index 0000000..013e97f
--- /dev/null
+++ b/hostsidetests/usb/AndroidTest.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS USB host test cases">
+    <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
+        <option name="jar" value="CtsUsbTests.jar" />
+    </test>
+</configuration>
diff --git a/hostsidetests/usb/SerialTestApp/Android.mk b/hostsidetests/usb/SerialTestApp/Android.mk
index a8f51ad..f71c7f4 100644
--- a/hostsidetests/usb/SerialTestApp/Android.mk
+++ b/hostsidetests/usb/SerialTestApp/Android.mk
@@ -28,4 +28,7 @@
 
 LOCAL_SDK_VERSION := current
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/usb/src/com/android/cts/usb/TestUsbTest.java b/hostsidetests/usb/src/com/android/cts/usb/TestUsbTest.java
index 3af52c0..5377711 100644
--- a/hostsidetests/usb/src/com/android/cts/usb/TestUsbTest.java
+++ b/hostsidetests/usb/src/com/android/cts/usb/TestUsbTest.java
@@ -15,8 +15,8 @@
  */
 package com.android.cts.usb;
 
-import com.android.cts.tradefed.build.CtsBuildHelper;
-import com.android.cts.util.AbiUtils;
+import com.android.compatibility.common.util.AbiUtils;
+import com.android.cts.migration.MigrationHelper;
 import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
 import com.android.ddmlib.testrunner.TestRunResult;
 import com.android.tradefed.build.IBuildInfo;
@@ -45,7 +45,7 @@
     private static final String APK_NAME="CtsUsbSerialTestApp.apk";
     private ITestDevice mDevice;
     private IAbi mAbi;
-    private CtsBuildHelper mBuild;
+    private IBuildInfo mBuild;
 
     @Override
     public void setAbi(IAbi abi) {
@@ -54,7 +54,7 @@
 
     @Override
     public void setBuild(IBuildInfo buildInfo) {
-        mBuild = CtsBuildHelper.createBuildHelper(buildInfo);
+        mBuild = buildInfo;
     }
 
     @Override
@@ -62,7 +62,7 @@
         super.setUp();
         mDevice = getDevice();
         mDevice.uninstallPackage(PACKAGE_NAME);
-        File app = mBuild.getTestApp(APK_NAME);
+        File app = MigrationHelper.getTestFile(mBuild, APK_NAME);
         String[] options = {AbiUtils.createAbiFlag(mAbi.getName())};
         mDevice.installPackage(app, false, options);
     }
diff --git a/libs/commonutil/Android.mk b/libs/commonutil/Android.mk
deleted file mode 100644
index 9c131b0..0000000
--- a/libs/commonutil/Android.mk
+++ /dev/null
@@ -1,27 +0,0 @@
-#
-# Copyright (C) 2014 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT 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 $(call all-subdir-makefiles)
-
-# ======================================================
-# Build a static host library for the AbiUtils
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := src/com/android/cts/util/AbiUtils.java
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_MODULE := ctsabiutilslib
-include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/libs/commonutil/src/com/android/cts/util/AbiUtils.java b/libs/commonutil/src/com/android/cts/util/AbiUtils.java
deleted file mode 100644
index 42336f3..0000000
--- a/libs/commonutil/src/com/android/cts/util/AbiUtils.java
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.cts.util;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Utility class for handling device ABIs
- */
-public class AbiUtils {
-
-    /**
-     * The set of 32Bit ABIs.
-     */
-    private static final Set<String> ABIS_32BIT = new HashSet<String>();
-
-    /**
-     * The set of 64Bit ABIs.
-     */
-    private static final Set<String> ABIS_64BIT = new HashSet<String>();
-
-    /**
-     * The set of ARM ABIs.
-     */
-    private static final Set<String> ARM_ABIS = new HashSet<String>();
-
-    /**
-     * The set of Intel ABIs.
-     */
-    private static final Set<String> INTEL_ABIS = new HashSet<String>();
-
-    /**
-     * The set of Mips ABIs.
-     */
-    private static final Set<String> MIPS_ABIS = new HashSet<String>();
-
-    /**
-     * The set of ABI names which CTS supports.
-     */
-    private static final Set<String> ABIS_SUPPORTED_BY_CTS = new HashSet<String>();
-
-    /**
-     * The map of architecture to ABI.
-     */
-    private static final Map<String, Set<String>> ARCH_TO_ABIS = new HashMap<String, Set<String>>();
-    static {
-        ABIS_32BIT.add("armeabi-v7a");
-        ABIS_32BIT.add("x86");
-        ABIS_32BIT.add("mips");
-
-        ABIS_64BIT.add("arm64-v8a");
-        ABIS_64BIT.add("x86_64");
-        ABIS_64BIT.add("mips64");
-
-        ARM_ABIS.add("armeabi-v7a");
-        ARM_ABIS.add("arm64-v8a");
-
-        INTEL_ABIS.add("x86");
-        INTEL_ABIS.add("x86_64");
-
-        MIPS_ABIS.add("mips");
-        MIPS_ABIS.add("mips64");
-
-        ARCH_TO_ABIS.put("arm", ARM_ABIS);
-        ARCH_TO_ABIS.put("arm64", ARM_ABIS);
-        ARCH_TO_ABIS.put("x86", INTEL_ABIS);
-        ARCH_TO_ABIS.put("x86_64", INTEL_ABIS);
-        ARCH_TO_ABIS.put("mips", MIPS_ABIS);
-        ARCH_TO_ABIS.put("mips64", MIPS_ABIS);
-
-        ABIS_SUPPORTED_BY_CTS.addAll(ARM_ABIS);
-        ABIS_SUPPORTED_BY_CTS.addAll(INTEL_ABIS);
-        ABIS_SUPPORTED_BY_CTS.addAll(MIPS_ABIS);
-    }
-
-    /**
-     * Private constructor to avoid instantiation.
-     */
-    private AbiUtils() {}
-
-    /**
-     * Returns the set of ABIs associated with the given architecture.
-     * @param arch The architecture to look up.
-     * @return a new Set containing the ABIs.
-     */
-    public static Set<String> getAbisForArch(String arch) {
-        if (arch == null || arch.isEmpty() || !ARCH_TO_ABIS.containsKey(arch)) {
-            return getAbisSupportedByCts();
-        }
-        return new HashSet<String>(ARCH_TO_ABIS.get(arch));
-    }
-
-    /**
-     * Returns the set of ABIs supported by CTS.
-     * @return a new Set containing the supported ABIs.
-     */
-    public static Set<String> getAbisSupportedByCts() {
-        return new HashSet<String>(ABIS_SUPPORTED_BY_CTS);
-    }
-
-    /**
-     * @param abi The ABI name to test.
-     * @return true if the given ABI is supported by CTS.
-     */
-    public static boolean isAbiSupportedByCts(String abi) {
-        return ABIS_SUPPORTED_BY_CTS.contains(abi);
-    }
-
-    /**
-     * Creates a flag for the given ABI.
-     * @param abi the ABI to create the flag for.
-     * @return a string which can be add to a command sent to ADB.
-     */
-    public static String createAbiFlag(String abi) {
-        if (abi == null || abi.isEmpty() || !isAbiSupportedByCts(abi)) {
-            return "";
-        }
-        return String.format("--abi %s ", abi);
-    }
-
-    /**
-     * Creates a unique id from the given ABI and name.
-     * @param abi The ABI to use.
-     * @param name The name to use.
-     * @return a string which uniquely identifies a run.
-     */
-    public static String createId(String abi, String name) {
-        return String.format("%s %s", abi, name);
-    }
-
-    /**
-     * Parses a unique id into the ABI and name.
-     * @param id The id to parse.
-     * @return a string array containing the ABI and name.
-     */
-    public static String[] parseId(String id) {
-        if (id == null || !id.contains(" ")) {
-            return new String[] {"", ""};
-        }
-        return id.split(" ");
-    }
-
-    /**
-     * @return the test name portion of the test id.
-     *         e.g. armeabi-v7a android.mytest = android.mytest
-     */
-    public static String parseTestName(String id) {
-        return parseId(id)[1];
-    }
-
-    /**
-     * @return the abi portion of the test id.
-     *         e.g. armeabi-v7a android.mytest = armeabi-v7a
-     */
-    public static String parseAbi(String id) {
-        return parseId(id)[0];
-    }
-
-    /**
-     * @param name The name of the ABI.
-     * @return The bitness of the ABI with the given name
-     */
-    public static String getBitness(String name) {
-        return ABIS_32BIT.contains(name) ? "32" : "64";
-    }
-
-    /**
-     * @param abilistString A comma separated string containing abis.
-     * @return A List of Strings containing valid ABIs.
-     */
-    public static Set<String> parseAbiList(String unsupportedAbiDescription) {
-        Set<String> abiSet = new HashSet<>();
-        String[] descSegments = unsupportedAbiDescription.split(":");
-        if (descSegments.length == 2) {
-            for (String abi : descSegments[1].split(",")) {
-                String trimmedAbi = abi.trim();
-                if (isAbiSupportedByCts(trimmedAbi)) {
-                    abiSet.add(trimmedAbi);
-                }
-            }
-        }
-        return abiSet;
-    }
-}
diff --git a/libs/commonutil/src/com/android/cts/util/MeasureRun.java b/libs/commonutil/src/com/android/cts/util/MeasureRun.java
deleted file mode 100644
index 43b5acf..0000000
--- a/libs/commonutil/src/com/android/cts/util/MeasureRun.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.util;
-
-/**
- * interface for measuring time for each run.
- */
-public abstract class MeasureRun {
-    /**
-     *  called before each run. not included to time measurement.
-     */
-    public void prepare(int i) throws Exception {
-        // default empty implementation
-    };
-
-    abstract public void run(int i) throws Exception;
-}
diff --git a/libs/commonutil/src/com/android/cts/util/MeasureTime.java b/libs/commonutil/src/com/android/cts/util/MeasureTime.java
deleted file mode 100644
index fd22ef2..0000000
--- a/libs/commonutil/src/com/android/cts/util/MeasureTime.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.util;
-
-
-public class MeasureTime {
-    /**
-     * measure time taken for each run for given count
-     * @param count
-     * @param run
-     * @return array of time taken in each run in msec.
-     * @throws Exception
-     */
-    public static double[] measure(int count, MeasureRun run) throws Exception {
-        double[] result = new double[count];
-
-        for (int i = 0; i < count; i++) {
-            run.prepare(i);
-            long start = System.currentTimeMillis();
-            run.run(i);
-            long end =  System.currentTimeMillis();
-            result[i] = end - start;
-        }
-        return result;
-    }
-}
diff --git a/libs/commonutil/src/com/android/cts/util/ReportLog.java b/libs/commonutil/src/com/android/cts/util/ReportLog.java
index dd4b414..05dec0f 100644
--- a/libs/commonutil/src/com/android/cts/util/ReportLog.java
+++ b/libs/commonutil/src/com/android/cts/util/ReportLog.java
@@ -16,29 +16,28 @@
 
 package com.android.cts.util;
 
-import java.util.LinkedList;
-import java.util.List;
+import com.android.compatibility.common.util.Stat;
 
-import junit.framework.Assert;
+import org.xmlpull.v1.XmlPullParserException;
 
+import java.io.IOException;
 
 /**
  * Utility class to print performance measurement result back to host.
  * For now, throws know exception with message.
  *
- * Format:
- * Message = summary log SUMMARY_SEPARATOR [LOG_SEPARATOR log]*
- * summary = message|target|unit|type|value, target can be " " if there is no target set.
- * log for array = classMethodName:line_number|message|unit|type|space seSummaryparated values
+ * This class is deprecated, use {@link com.android.compatibility.common.util.ReportLog}
+ * instead.
  */
+@Deprecated
 public class ReportLog {
-    private static final String LOG_SEPARATOR = "+++";
-    private static final String SUMMARY_SEPARATOR = "++++";
-    private static final String LOG_ELEM_SEPARATOR = "|";
 
-    private List<String> mMessages = new LinkedList<String> ();
-    private String mSummary = null;
     protected static int mDepth = 3;
+    protected com.android.compatibility.common.util.ReportLog mReportLog;
+
+    public ReportLog(com.android.compatibility.common.util.ReportLog reportLog) {
+        mReportLog = reportLog;
+    }
 
     /**
      * print array of values to output log
@@ -80,23 +79,11 @@
 
     private void doPrintArray(String testId, String message,
             double[] values, ResultType type, ResultUnit unit) {
-        StringBuilder builder = new StringBuilder();
-        // note mDepth + 1 as this function will be called by printVaue or printArray
-        // and we need caller of printValue / printArray
-        builder.append(testId);
-        builder.append(LOG_ELEM_SEPARATOR);
-        builder.append(message);
-        builder.append(LOG_ELEM_SEPARATOR);
-        builder.append(type.getXmlString());
-        builder.append(LOG_ELEM_SEPARATOR);
-        builder.append(unit.getXmlString());
-        builder.append(LOG_ELEM_SEPARATOR);
-        for (double v : values) {
-            builder.append(v);
-            builder.append(" ");
-        }
-        mMessages.add(builder.toString());
-        printLog(builder.toString());
+        mReportLog.addValues(testId, message, values,
+                com.android.compatibility.common.util.ResultType.parseReportString(
+                        type.getXmlString()),
+                com.android.compatibility.common.util.ResultUnit.parseReportString(
+                        unit.getXmlString()));
     }
 
     /**
@@ -113,18 +100,12 @@
      */
     public void printSummaryWithTarget(String message, double target, double value,
             ResultType type, ResultUnit unit) {
-        mSummary = message + LOG_ELEM_SEPARATOR + target + LOG_ELEM_SEPARATOR + type.getXmlString()
-                + LOG_ELEM_SEPARATOR + unit.getXmlString() + LOG_ELEM_SEPARATOR + value;
-        boolean resultOk = true;
-        if (type == ResultType.HIGHER_BETTER) {
-            resultOk = value >= target;
-        } else if (type == ResultType.LOWER_BETTER) {
-            resultOk = value <= target;
-        }
-        if (!resultOk) {
-            Assert.fail("Measured result " + value + " does not meet perf target " + target +
-                    " with type " + type.getXmlString());
-        }
+        // Ignore target
+        mReportLog.setSummary(message, value,
+                com.android.compatibility.common.util.ResultType.parseReportString(
+                        type.getXmlString()),
+                com.android.compatibility.common.util.ResultUnit.parseReportString(
+                        unit.getXmlString()));
     }
 
     /**
@@ -136,32 +117,24 @@
      * @param unit unit of the data
      */
     public void printSummary(String message, double value, ResultType type, ResultUnit unit) {
-        mSummary = message + LOG_ELEM_SEPARATOR + " " + LOG_ELEM_SEPARATOR + type.getXmlString() +
-                LOG_ELEM_SEPARATOR + unit.getXmlString() + LOG_ELEM_SEPARATOR + value;
+        mReportLog.setSummary(message, value,
+                com.android.compatibility.common.util.ResultType.parseReportString(
+                        type.getXmlString()),
+                com.android.compatibility.common.util.ResultUnit.parseReportString(
+                        unit.getXmlString()));
     }
 
     /**
      * @return a string representation of this report.
      */
     protected String generateReport() {
-        if ((mSummary == null) && mMessages.isEmpty()) {
-            // just return empty string
-            return "";
+        try {
+            return com.android.compatibility.common.util.ReportLog.serialize(mReportLog);
+        } catch (IllegalArgumentException | IllegalStateException | XmlPullParserException
+                | IOException e) {
+            e.printStackTrace();
         }
-        StringBuilder builder = new StringBuilder();
-        builder.append(mSummary);
-        builder.append(SUMMARY_SEPARATOR);
-        for (String entry : mMessages) {
-            builder.append(entry);
-            builder.append(LOG_SEPARATOR);
-        }
-        // delete the last separator
-        if (builder.length() >= LOG_SEPARATOR.length()) {
-            builder.delete(builder.length() - LOG_SEPARATOR.length(), builder.length());
-        }
-        mSummary = null;
-        mMessages.clear();
-        return builder.toString();
+        return null;
     }
 
     /**
@@ -172,27 +145,14 @@
      * @return
      */
     public static double calcRatePerSec(double change, double timeInMSec) {
-        if (timeInMSec == 0) {
-            return change * 1000.0 / 0.001; // do not allow zero
-        } else {
-            return change * 1000.0 / timeInMSec;
-        }
+        return Stat.calcRatePerSec(change, timeInMSec);
     }
 
     /**
      * array version of calcRatePerSecArray
      */
     public static double[] calcRatePerSecArray(double change, double[] timeInMSec) {
-        double[] result = new double[timeInMSec.length];
-        change *= 1000.0;
-        for (int i = 0; i < timeInMSec.length; i++) {
-            if (timeInMSec[i] == 0) {
-                result[i] = change / 0.001;
-            } else {
-                result[i] = change / timeInMSec[i];
-            }
-        }
-        return result;
+        return Stat.calcRatePerSecArray(change, timeInMSec);
     }
 
     /**
@@ -219,10 +179,4 @@
         return names;
     }
 
-    /**
-     * to be overridden by child to print message to be passed
-     */
-    protected void printLog(String msg) {
-
-    }
 }
diff --git a/libs/commonutil/src/com/android/cts/util/ResultType.java b/libs/commonutil/src/com/android/cts/util/ResultType.java
index a5a388c..dbe8602 100644
--- a/libs/commonutil/src/com/android/cts/util/ResultType.java
+++ b/libs/commonutil/src/com/android/cts/util/ResultType.java
@@ -18,7 +18,11 @@
 
 /**
  * Enum for distinguishing performance results.
+ *
+ * This class is deprecated, use {@link com.android.compatibility.common.util.ResultType}
+ * instead.
  */
+@Deprecated
 public enum ResultType {
     /** lower score shows better performance */
     LOWER_BETTER,
diff --git a/libs/commonutil/src/com/android/cts/util/ResultUnit.java b/libs/commonutil/src/com/android/cts/util/ResultUnit.java
index a216a7e..2148821 100644
--- a/libs/commonutil/src/com/android/cts/util/ResultUnit.java
+++ b/libs/commonutil/src/com/android/cts/util/ResultUnit.java
@@ -19,7 +19,10 @@
 /**
  * Enum for representing the unit of performance results.
  *
+ * This class is deprecated, use {@link com.android.compatibility.common.util.ResultUnit}
+ * instead.
  */
+@Deprecated
 public enum ResultUnit {
     /** for value with no unit */
     NONE,
diff --git a/libs/commonutil/src/com/android/cts/util/Stat.java b/libs/commonutil/src/com/android/cts/util/Stat.java
deleted file mode 100644
index ceafa4e..0000000
--- a/libs/commonutil/src/com/android/cts/util/Stat.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.util;
-
-import java.util.Arrays;
-
-/**
- * Utilities for doing statistics
- *
- */
-public class Stat {
-
-    /**
-     * Collection of statistical propertirs like average, max, min, and stddev
-     */
-    public static class StatResult {
-        public double mAverage;
-        public double mMin;
-        public double mMax;
-        public double mStddev;
-        public int mDataCount;
-        public StatResult(double average, double min, double max, double stddev, int dataCount) {
-            mAverage = average;
-            mMin = min;
-            mMax = max;
-            mStddev = stddev;
-            mDataCount = dataCount;
-        }
-    }
-
-    /**
-     * Calculate statistics properties likes average, min, max, and stddev for the given array
-     */
-    public static StatResult getStat(double[] data) {
-        double average = data[0];
-        double min = data[0];
-        double max = data[0];
-        double eX2 = data[0] * data[0]; // will become E[X^2]
-        for (int i = 1; i < data.length; i++) {
-            average += data[i];
-            eX2 += data[i] * data[i];
-            if (data[i] > max) {
-                max = data[i];
-            }
-            if (data[i] < min) {
-                min = data[i];
-            }
-        }
-        average /= data.length;
-        eX2 /= data.length;
-        // stddev = sqrt(E[X^2] - (E[X])^2)
-        double stddev = Math.sqrt(eX2 - average * average);
-        return new StatResult(average, min, max, stddev, data.length);
-    }
-
-    /**
-     * Calculate statistics properties likes average, min, max, and stddev for the given array
-     * while rejecting outlier +/- median * rejectionThreshold.
-     * rejectionThreshold should be bigger than 0.0 and be lowerthan 1.0
-     */
-    public static StatResult getStatWithOutlierRejection(double[] data, double rejectionThreshold) {
-        double[] dataCopied = Arrays.copyOf(data, data.length);
-        Arrays.sort(dataCopied);
-        int medianIndex = dataCopied.length / 2;
-        double median;
-        if (dataCopied.length % 2 == 1) {
-            median = dataCopied[medianIndex];
-        } else {
-            median = (dataCopied[medianIndex - 1] + dataCopied[medianIndex]) / 2.0;
-        }
-        double thresholdMin = median * (1.0 - rejectionThreshold);
-        double thresholdMax = median * (1.0 + rejectionThreshold);
-
-        double average = 0.0;
-        double min = median;
-        double max = median;
-        double eX2 = 0.0; // will become E[X^2]
-        int validDataCounter = 0;
-        for (int i = 0; i < data.length; i++) {
-            if ((data[i] > thresholdMin) && (data[i] < thresholdMax)) {
-                validDataCounter++;
-                average += data[i];
-                eX2 += data[i] * data[i];
-                if (data[i] > max) {
-                    max = data[i];
-                }
-                if (data[i] < min) {
-                    min = data[i];
-                }
-            }
-            //TODO report rejected data
-        }
-        double stddev;
-        if (validDataCounter > 0) {
-            average /= validDataCounter;
-            eX2 /= validDataCounter;
-            // stddev = sqrt(E[X^2] - (E[X])^2)
-            stddev = Math.sqrt(eX2 - average * average);
-        } else { // both median is showing too much diff
-            average = median;
-            stddev = 0; // don't care
-        }
-
-        return new StatResult(average, min, max, stddev, validDataCounter);
-    }
-
-    /**
-     * return the average value of the passed array
-     */
-    public static double getAverage(double[] data) {
-        double sum = data[0];
-        for (int i = 1; i < data.length; i++) {
-            sum += data[i];
-        }
-        return sum / data.length;
-    }
-
-    /**
-     * return the minimum value of the passed array
-     */
-    public static double getMin(double[] data) {
-        double min = data[0];
-        for (int i = 1; i < data.length; i++) {
-            if (data[i] < min) {
-                min = data[i];
-            }
-        }
-        return min;
-    }
-
-    /**
-     * return the maximum value of the passed array
-     */
-    public static double getMax(double[] data) {
-        double max = data[0];
-        for (int i = 1; i < data.length; i++) {
-            if (data[i] > max) {
-                max = data[i];
-            }
-        }
-        return max;
-    }
-}
diff --git a/libs/commonutil/src/com/android/cts/util/StatisticsUtils.java b/libs/commonutil/src/com/android/cts/util/StatisticsUtils.java
deleted file mode 100644
index d6589af..0000000
--- a/libs/commonutil/src/com/android/cts/util/StatisticsUtils.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.cts.util;
-
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Set of static helper methods for CTS tests.
- */
-public class StatisticsUtils {
-
-
-    /**
-     * Private constructor for static class.
-     */
-    private StatisticsUtils() {}
-
-    /**
-     * Get the value of the 95th percentile using nearest rank algorithm.
-     *
-     * @throws IllegalArgumentException if the collection is null or empty
-     */
-    public static <TValue extends Comparable<? super TValue>> TValue get95PercentileValue(
-            Collection<TValue> collection) {
-        validateCollection(collection);
-
-        List<TValue> arrayCopy = new ArrayList<TValue>(collection);
-        Collections.sort(arrayCopy);
-
-        // zero-based array index
-        int arrayIndex = (int) Math.round(arrayCopy.size() * 0.95 + .5) - 1;
-
-        return arrayCopy.get(arrayIndex);
-    }
-
-    /**
-     * Calculate the mean of a collection.
-     *
-     * @throws IllegalArgumentException if the collection is null or empty
-     */
-    public static <TValue extends Number> double getMean(Collection<TValue> collection) {
-        validateCollection(collection);
-
-        double sum = 0.0;
-        for(TValue value : collection) {
-            sum += value.doubleValue();
-        }
-        return sum / collection.size();
-    }
-
-    /**
-     * Calculate the bias-corrected sample variance of a collection.
-     *
-     * @throws IllegalArgumentException if the collection is null or empty
-     */
-    public static <TValue extends Number> double getVariance(Collection<TValue> collection) {
-        validateCollection(collection);
-
-        double mean = getMean(collection);
-        ArrayList<Double> squaredDiffs = new ArrayList<Double>();
-        for(TValue value : collection) {
-            double difference = mean - value.doubleValue();
-            squaredDiffs.add(Math.pow(difference, 2));
-        }
-
-        double sum = 0.0;
-        for (Double value : squaredDiffs) {
-            sum += value;
-        }
-        return sum / (squaredDiffs.size() - 1);
-    }
-
-    /**
-     * Calculate the bias-corrected standard deviation of a collection.
-     *
-     * @throws IllegalArgumentException if the collection is null or empty
-     */
-    public static <TValue extends Number> double getStandardDeviation(
-            Collection<TValue> collection) {
-        return Math.sqrt(getVariance(collection));
-    }
-
-    /**
-     * Validate that a collection is not null or empty.
-     *
-     * @throws IllegalStateException if collection is null or empty.
-     */
-    private static <T> void validateCollection(Collection<T> collection) {
-        if(collection == null || collection.size() == 0) {
-            throw new IllegalStateException("Collection cannot be null or empty");
-        }
-    }
-
-}
diff --git a/libs/commonutil/src/com/android/cts/util/StatisticsUtilsTest.java b/libs/commonutil/src/com/android/cts/util/StatisticsUtilsTest.java
deleted file mode 100644
index d78ba99..0000000
--- a/libs/commonutil/src/com/android/cts/util/StatisticsUtilsTest.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.util;
-
-import junit.framework.TestCase;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Unit tests for the {@link StatisticsUtils} class.
- */
-public class StatisticsUtilsTest extends TestCase {
-
-    /**
-     * Test {@link StatisticsUtils#get95PercentileValue(Collection)}.
-     */
-    public void testGet95PercentileValue() {
-        Collection<Integer> values = new HashSet<Integer>();
-        for (int i = 0; i < 100; i++) {
-            values.add(i);
-        }
-        assertEquals(95, (int) StatisticsUtils.get95PercentileValue(values));
-
-        values = new HashSet<Integer>();
-        for (int i = 0; i < 1000; i++) {
-            values.add(i);
-        }
-        assertEquals(950, (int) StatisticsUtils.get95PercentileValue(values));
-
-        values = new HashSet<Integer>();
-        for (int i = 0; i < 100; i++) {
-            values.add(i * i);
-        }
-        assertEquals(95 * 95, (int) StatisticsUtils.get95PercentileValue(values));
-    }
-
-    /**
-     * Test {@link StatisticsUtils#getMean(Collection)}.
-     */
-    public void testGetMean() {
-        List<Integer> values = Arrays.asList(0, 1, 2, 3, 4);
-        double mean = StatisticsUtils.getMean(values);
-        assertEquals(2.0, mean, 0.00001);
-
-        values = Arrays.asList(1, 2, 3, 4, 5);
-        mean = StatisticsUtils.getMean(values);
-        assertEquals(3.0, mean, 0.00001);
-
-        values = Arrays.asList(0, 1, 4, 9, 16);
-        mean = StatisticsUtils.getMean(values);
-        assertEquals(6.0, mean, 0.00001);
-    }
-
-    /**
-     * Test {@link StatisticsUtils#getVariance(Collection)}.
-     */
-    public void testGetVariance() {
-        List<Integer> values = Arrays.asList(0, 1, 2, 3, 4);
-        double variance = StatisticsUtils.getVariance(values);
-        assertEquals(2.5, variance, 0.00001);
-
-        values = Arrays.asList(1, 2, 3, 4, 5);
-        variance = StatisticsUtils.getVariance(values);
-        assertEquals(2.5, variance, 0.00001);
-
-        values = Arrays.asList(0, 2, 4, 6, 8);
-        variance = StatisticsUtils.getVariance(values);
-        assertEquals(10.0, variance, 0.00001);
-    }
-
-    /**
-     * Test {@link StatisticsUtils#getStandardDeviation(Collection)}.
-     */
-    public void testGetStandardDeviation() {
-        List<Integer> values = Arrays.asList(0, 1, 2, 3, 4);
-        double stddev = StatisticsUtils.getStandardDeviation(values);
-        assertEquals(Math.sqrt(2.5), stddev, 0.00001);
-
-        values = Arrays.asList(1, 2, 3, 4, 5);
-        stddev = StatisticsUtils.getStandardDeviation(values);
-        assertEquals(Math.sqrt(2.5), stddev, 0.00001);
-
-        values = Arrays.asList(0, 2, 4, 6, 8);
-        stddev = StatisticsUtils.getStandardDeviation(values);
-        assertEquals(Math.sqrt(10.0), stddev, 0.00001);
-    }
-
-
-}
diff --git a/libs/deviceutil/Android.mk b/libs/deviceutil/Android.mk
index 8c81ee4..bb039ca 100644
--- a/libs/deviceutil/Android.mk
+++ b/libs/deviceutil/Android.mk
@@ -22,6 +22,8 @@
 
 LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
 
+LOCAL_STATIC_JAVA_LIBRARIES := compatibility-device-util
+
 LOCAL_MODULE_TAGS := optional
 
 LOCAL_MODULE := ctsdeviceutil
diff --git a/libs/deviceutil/jni/Android.mk b/libs/deviceutil/jni/Android.mk
index b801a4d..e413250 100644
--- a/libs/deviceutil/jni/Android.mk
+++ b/libs/deviceutil/jni/Android.mk
@@ -27,6 +27,7 @@
 
 LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
 
-LOCAL_SHARED_LIBRARIES := libnativehelper liblog libdl
+LOCAL_SHARED_LIBRARIES := libnativehelper_compat_libc++ liblog libdl
+LOCAL_SDK_VERSION := 19
 
-include $(BUILD_SHARED_LIBRARY)
\ No newline at end of file
+include $(BUILD_SHARED_LIBRARY)
diff --git a/libs/deviceutil/src/android/cts/util/BitmapUtils.java b/libs/deviceutil/src/android/cts/util/BitmapUtils.java
new file mode 100644
index 0000000..7234425
--- /dev/null
+++ b/libs/deviceutil/src/android/cts/util/BitmapUtils.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.cts.util;
+
+import android.app.WallpaperManager;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Bitmap.CompressFormat;
+import android.graphics.Color;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.lang.reflect.Method;
+import java.util.Random;
+
+public class BitmapUtils {
+    private BitmapUtils() {}
+
+    // Compares two bitmaps by pixels.
+    public static boolean compareBitmaps(Bitmap bmp1, Bitmap bmp2) {
+        if (bmp1 == bmp2) {
+            return true;
+        }
+
+        if ((bmp1.getWidth() != bmp2.getWidth()) || (bmp1.getHeight() != bmp2.getHeight())) {
+            return false;
+        }
+
+        for (int i = 0; i < bmp1.getWidth(); i++) {
+            for (int j = 0; j < bmp1.getHeight(); j++) {
+                if (bmp1.getPixel(i, j) != bmp2.getPixel(i, j)) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    public static Bitmap generateRandomBitmap(int width, int height) {
+        final Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+        final Random generator = new Random();
+        for (int x = 0; x < width; x++) {
+            for (int y = 0; y < height; y++) {
+                bmp.setPixel(x, y, generator.nextInt(Integer.MAX_VALUE));
+            }
+        }
+        return bmp;
+    }
+
+    public static Bitmap generateWhiteBitmap(int width, int height) {
+        final Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+        for (int x = 0; x < width; x++) {
+            for (int y = 0; y < height; y++) {
+                bmp.setPixel(x, y, Color.WHITE);
+            }
+        }
+        return bmp;
+    }
+
+    public static Bitmap getWallpaperBitmap(Context context) throws Exception {
+        WallpaperManager wallpaperManager = WallpaperManager.getInstance(context);
+        Class<?> noparams[] = {};
+        Class<?> wmClass = wallpaperManager.getClass();
+        Method methodGetBitmap = wmClass.getDeclaredMethod("getBitmap", noparams);
+        return (Bitmap) methodGetBitmap.invoke(wallpaperManager, null);
+    }
+
+    public static ByteArrayInputStream bitmapToInputStream(Bitmap bmp) {
+        final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        bmp.compress(CompressFormat.PNG, 0 /*ignored for PNG*/, bos);
+        byte[] bitmapData = bos.toByteArray();
+        return new ByteArrayInputStream(bitmapData);
+    }
+}
diff --git a/libs/deviceutil/src/android/cts/util/CtsActivityInstrumentationTestCase2.java b/libs/deviceutil/src/android/cts/util/CtsActivityInstrumentationTestCase2.java
deleted file mode 100644
index e039407..0000000
--- a/libs/deviceutil/src/android/cts/util/CtsActivityInstrumentationTestCase2.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.cts.util;
-
-import com.android.cts.util.ReportLog;
-
-import android.app.Activity;
-import android.test.ActivityInstrumentationTestCase2;
-
-
-public class CtsActivityInstrumentationTestCase2<T extends Activity> extends
-        ActivityInstrumentationTestCase2<T> {
-
-    private DeviceReportLog mReportLog = new DeviceReportLog();
-
-    public CtsActivityInstrumentationTestCase2(Class<T> activityClass) {
-        super(activityClass);
-    }
-
-    public ReportLog getReportLog() {
-        return mReportLog;
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        mReportLog.deliverReportToHost(getInstrumentation());
-        super.tearDown();
-    }
-
-}
diff --git a/libs/deviceutil/src/android/cts/util/CtsAndroidTestCase.java b/libs/deviceutil/src/android/cts/util/CtsAndroidTestCase.java
index b1164bc..7cf0f7e 100644
--- a/libs/deviceutil/src/android/cts/util/CtsAndroidTestCase.java
+++ b/libs/deviceutil/src/android/cts/util/CtsAndroidTestCase.java
@@ -18,13 +18,14 @@
 package android.cts.util;
 
 import android.content.Context;
+import android.test.ActivityInstrumentationTestCase2;
 
 /**
  *  This class emulates AndroidTestCase, but internally it is ActivityInstrumentationTestCase2
  *  to access Instrumentation.
  *  DummyActivity is not supposed to be accessed.
  */
-public class CtsAndroidTestCase extends CtsActivityInstrumentationTestCase2<DummyActivity> {
+public class CtsAndroidTestCase extends ActivityInstrumentationTestCase2<DummyActivity> {
     public CtsAndroidTestCase() {
         super(DummyActivity.class);
     }
diff --git a/libs/deviceutil/src/android/cts/util/DeviceReportLog.java b/libs/deviceutil/src/android/cts/util/DeviceReportLog.java
index 63b07b7..4dd185e 100644
--- a/libs/deviceutil/src/android/cts/util/DeviceReportLog.java
+++ b/libs/deviceutil/src/android/cts/util/DeviceReportLog.java
@@ -22,6 +22,11 @@
 
 import com.android.cts.util.ReportLog;
 
+/**
+ * This class is deprecated, use {@link com.android.compatibility.common.util.DeviceReportLog}
+ * instead.
+ */
+@Deprecated
 public class DeviceReportLog extends ReportLog {
     private static final String TAG = "DeviceCtsReport";
     private static final String CTS_RESULT_KEY = "CTS_TEST_RESULT";
@@ -33,21 +38,17 @@
     }
 
     public DeviceReportLog(int depth) {
+        super(new com.android.compatibility.common.util.DeviceReportLog());
         mDepth = BASE_DEPTH + depth;
     }
 
-    @Override
-    protected void printLog(String msg) {
-        Log.i(TAG, msg);
-    }
-
     public void deliverReportToHost(Instrumentation instrumentation) {
         Log.i(TAG, "deliverReportToHost");
         String report = generateReport();
-        if (!report.equals("")) {
+        if (report != null && !report.isEmpty()) {
             Bundle output = new Bundle();
             output.putString(CTS_RESULT_KEY, report);
             instrumentation.sendStatus(INST_STATUS_IN_PROGRESS, output);
         }
     }
-}
+}
\ No newline at end of file
diff --git a/libs/deviceutil/src/android/cts/util/PollingCheck.java b/libs/deviceutil/src/android/cts/util/PollingCheck.java
index be6b0b0..3a08c7e 100644
--- a/libs/deviceutil/src/android/cts/util/PollingCheck.java
+++ b/libs/deviceutil/src/android/cts/util/PollingCheck.java
@@ -24,6 +24,10 @@
     private static final long TIME_SLICE = 50;
     private long mTimeout = 3000;
 
+    public static interface PollingCheckCondition {
+        boolean canProceed();
+    }
+
     public PollingCheck() {
     }
 
@@ -69,4 +73,13 @@
 
         Assert.fail(message.toString());
     }
+
+    public static void waitFor(final PollingCheckCondition condition) {
+        new PollingCheck() {
+            @Override
+            protected boolean check() {
+                return condition.canProceed();
+            }
+        }.run();
+    }
 }
diff --git a/libs/json/Android.mk b/libs/json/Android.mk
index 7ec9e79..231f635 100644
--- a/libs/json/Android.mk
+++ b/libs/json/Android.mk
@@ -15,6 +15,9 @@
 #
 
 LOCAL_PATH:= $(call my-dir)
+
+# Build the host library
+# ======================
 include $(CLEAR_VARS)
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
@@ -23,3 +26,13 @@
 
 include $(BUILD_HOST_JAVA_LIBRARY)
 
+# Build the target library
+# =======================
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_MODULE := json
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
diff --git a/libs/migration/Android.mk b/libs/migration/Android.mk
new file mode 100644
index 0000000..11173d6
--- /dev/null
+++ b/libs/migration/Android.mk
@@ -0,0 +1,34 @@
+# Copyright (C) 2012 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_JAVA_LIBRARIES := cts-tradefed tradefed-prebuilt
+
+LOCAL_JAVA_LIBRARIES := tradefed-prebuilt
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE := cts-migration-lib
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_HOST_JAVA_LIBRARY)
\ No newline at end of file
diff --git a/libs/migration/src/com/android/cts/migration/MigrationHelper.java b/libs/migration/src/com/android/cts/migration/MigrationHelper.java
new file mode 100644
index 0000000..0595486
--- /dev/null
+++ b/libs/migration/src/com/android/cts/migration/MigrationHelper.java
@@ -0,0 +1,59 @@
+package com.android.cts.migration;
+
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.log.LogUtil.CLog;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * A temporary helper to enable tests to work with both cts v1 and v2.
+ */
+public class MigrationHelper {
+
+    private static final String COMPATIBILITY_BUILD_HELPER =
+            "com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper";
+    private static final String CTS_BUILD_HELPER =
+            "com.android.cts.tradefed.build.CtsBuildHelper";
+
+    public static File getTestFile(IBuildInfo mBuild, String filename)
+            throws FileNotFoundException {
+        try {
+            Class<?> cls = Class.forName(COMPATIBILITY_BUILD_HELPER);
+            Constructor<?> cons = cls.getConstructor(IBuildInfo.class);
+            Object instance = cons.newInstance(mBuild);
+            Method method = cls.getMethod("getTestsDir");
+            File dir = (File) method.invoke(instance);
+            File file = new File(dir, filename);
+            CLog.i("Looking for test file %s in dir %s", filename, dir.getAbsolutePath());
+            if (file.exists()) {
+                CLog.i("File %s found", filename);
+                return file;
+            }
+        } catch (ClassNotFoundException | NoSuchMethodException | InstantiationException |
+                IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
+            // Ignore and fall back to CtsBuildHelper
+        }
+        try {
+            Class<?> cls = Class.forName(CTS_BUILD_HELPER);
+            Method builder = cls.getMethod("createBuildHelper", IBuildInfo.class);
+            Object helper = builder.invoke(null, mBuild);
+            Method method = cls.getMethod("getTestApp", String.class);
+            File file = (File) method.invoke(helper, filename);
+            CLog.i("Looking for test file %s as %s", filename, file.getAbsolutePath());
+            if (file.exists()) {
+                CLog.i("File %s found", filename);
+                return file;
+            }
+        } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException |
+                IllegalArgumentException | InvocationTargetException e) {
+            // Ignore
+        }
+        throw new FileNotFoundException("Couldn't load file " + filename);
+    }
+
+}
diff --git a/libs/runner/Android.mk b/libs/runner/Android.mk
index 9642f53..15f64a3 100644
--- a/libs/runner/Android.mk
+++ b/libs/runner/Android.mk
@@ -16,9 +16,7 @@
 
 include $(CLEAR_VARS)
 
-LOCAL_SRC_FILES := $(call all-java-files-under, ../../tests/core/runner/src)
-
-LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
+LOCAL_STATIC_JAVA_LIBRARIES := cts-test-runner
 
 LOCAL_MODULE_TAGS := optional
 
diff --git a/libs/testserver/src/android/webkit/cts/CtsTestServer.java b/libs/testserver/src/android/webkit/cts/CtsTestServer.java
index de88f3b..d9256b8 100644
--- a/libs/testserver/src/android/webkit/cts/CtsTestServer.java
+++ b/libs/testserver/src/android/webkit/cts/CtsTestServer.java
@@ -54,34 +54,31 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.UnsupportedEncodingException;
-import java.net.MalformedURLException;
 import java.net.ServerSocket;
 import java.net.Socket;
 import java.net.URI;
 import java.net.URL;
 import java.net.URLEncoder;
-import java.net.URLConnection;
-import java.security.KeyManagementException;
 import java.security.KeyStore;
-import java.security.NoSuchAlgorithmException;
 import java.security.cert.X509Certificate;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.Hashtable;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.Vector;
-import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
+import java.util.concurrent.RejectedExecutionException;
 import java.util.concurrent.TimeUnit;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 import javax.net.ssl.HostnameVerifier;
-import javax.net.ssl.HttpsURLConnection;
 import javax.net.ssl.KeyManager;
 import javax.net.ssl.KeyManagerFactory;
 import javax.net.ssl.SSLContext;
@@ -115,7 +112,6 @@
     private static final String COOKIE_PREFIX = "/cookie";
     private static final String LINKED_SCRIPT_PREFIX = "/linkedscriptprefix";
     private static final String AUTH_PREFIX = "/auth";
-    private static final String SHUTDOWN_PREFIX = "/shutdown";
     public static final String NOLENGTH_POSTFIX = "nolength";
     private static final int DELAY_MILLIS = 2000;
 
@@ -223,74 +219,13 @@
      * Terminate the http server.
      */
     public void shutdown() {
+        mServerThread.shutDownOnClientThread();
+
         try {
-            // Avoid a deadlock between two threads where one is trying to call
-            // close() and the other one is calling accept() by sending a GET
-            // request for shutdown and having the server's one thread
-            // sequentially call accept() and close().
-            URL url = new URL(mServerUri + SHUTDOWN_PREFIX);
-            if (url.getProtocol().equalsIgnoreCase("http")) {
-                // Use Socket instead of HttpURLConnection when the server is in cleartext HTTP mode
-                // to avoid the request being blocked by NetworkSecurityPolicy.
-                Socket socket = null;
-                try {
-                    socket = new Socket(url.getHost(), url.getPort());
-                    socket.getOutputStream().write(
-                        ("GET " + SHUTDOWN_PREFIX + " HTTP/1.0\r\n\r\n").getBytes("US-ASCII"));
-                    socket.getOutputStream().flush();
-                } finally {
-                    if (socket != null) {
-                        try {
-                            socket.close();
-                        } catch (Exception ignored) {}
-                    }
-                }
-            } else {
-                URLConnection connection = openConnection(url);
-                connection.connect();
-
-                // Read the input from the stream to send the request.
-                InputStream is = connection.getInputStream();
-                is.close();
-            }
-
             // Block until the server thread is done shutting down.
             mServerThread.join();
-
-        } catch (MalformedURLException e) {
-            throw new IllegalStateException(e);
         } catch (InterruptedException e) {
             throw new RuntimeException(e);
-        } catch (IOException e) {
-            throw new RuntimeException(e);
-        } catch (NoSuchAlgorithmException e) {
-            throw new IllegalStateException(e);
-        } catch (KeyManagementException e) {
-            throw new IllegalStateException(e);
-        }
-    }
-
-    private URLConnection openConnection(URL url)
-            throws IOException, NoSuchAlgorithmException, KeyManagementException {
-        if (mSsl == SslMode.INSECURE) {
-            return url.openConnection();
-        } else {
-            // Install hostname verifiers and trust managers that don't do
-            // anything in order to get around the client not trusting
-            // the test server due to a lack of certificates.
-
-            HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
-            connection.setHostnameVerifier(new CtsHostnameVerifier());
-
-            SSLContext context = SSLContext.getInstance("TLS");
-            try {
-                context.init(ServerThread.getKeyManagers(), getTrustManagers(), null);
-            } catch (Exception e) {
-                throw new RuntimeException(e);
-            }
-            connection.setSSLSocketFactory(context.getSocketFactory());
-
-            return connection;
         }
     }
 
@@ -775,11 +710,6 @@
             response.setEntity(createPage(agent, agent));
         } else if (path.equals(TEST_DOWNLOAD_PATH)) {
             response = createTestDownloadResponse(Uri.parse(uriString));
-        } else if (path.equals(SHUTDOWN_PREFIX)) {
-            response = createResponse(HttpStatus.SC_OK);
-            // We cannot close the socket here, because we need to respond.
-            // Status must be set to OK, or else the test will fail due to
-            // a RunTimeException.
         } else if (path.equals(APPCACHE_PATH)) {
             response = createResponse(HttpStatus.SC_OK);
             response.setEntity(createEntity("<!DOCTYPE HTML>" +
@@ -924,9 +854,12 @@
         private CtsTestServer mServer;
         private ServerSocket mSocket;
         private SslMode mSsl;
-        private boolean mIsCancelled;
+        private boolean mWillShutDown = false;
         private SSLContext mSslContext;
         private ExecutorService mExecutorService = Executors.newFixedThreadPool(20);
+        private Object mLock = new Object();
+        // All the sockets bound to an open connection.
+        private Set<Socket> mSockets = new HashSet<Socket>();
 
         /**
          * Defines the keystore contents for the server, BKS version. Holds just a
@@ -1012,10 +945,14 @@
         }
 
         public void run() {
-            while (!mIsCancelled) {
+            while (!mWillShutDown) {
                 try {
                     Socket socket = mSocket.accept();
 
+                    synchronized(mLock) {
+                        mSockets.add(socket);
+                    }
+
                     DefaultHttpServerConnection conn = mServer.createHttpServerConnection();
                     HttpParams params = new BasicHttpParams();
                     params.setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_0);
@@ -1025,17 +962,17 @@
                     // parsing the response since conn.close() will crash
                     // for SSL requests due to UnsupportedOperationException.
                     HttpRequest request = conn.receiveRequestHeader();
-                    if (isShutdownRequest(request)) {
-                        mIsCancelled = true;
-                    }
                     if (request instanceof HttpEntityEnclosingRequest) {
                         conn.receiveRequestEntity( (HttpEntityEnclosingRequest) request);
                     }
 
-                    mExecutorService.execute(new HandleResponseTask(conn, request));
+                    mExecutorService.execute(new HandleResponseTask(conn, request, socket));
                 } catch (IOException e) {
                     // normal during shutdown, ignore
                     Log.w(TAG, e);
+                } catch (RejectedExecutionException e) {
+                    // normal during shutdown, ignore
+                    Log.w(TAG, e);
                 } catch (HttpException e) {
                     Log.w(TAG, e);
                 } catch (UnsupportedOperationException e) {
@@ -1044,10 +981,26 @@
                     Log.w(TAG, e);
                 }
             }
+        }
+
+        /**
+         * Shutdown the socket and the executor service.
+         * Note this method is called on the client thread, instead of the server thread.
+         */
+        public void shutDownOnClientThread() {
             try {
+                mWillShutDown = true;
                 mExecutorService.shutdown();
                 mExecutorService.awaitTermination(1L, TimeUnit.MINUTES);
                 mSocket.close();
+                // To prevent the server thread from being blocked on read from socket,
+                // which is called when the server tries to receiveRequestHeader,
+                // close all the sockets here.
+                synchronized(mLock) {
+                    for (Socket socket : mSockets) {
+                        socket.close();
+                    }
+                }
             } catch (IOException ignored) {
                 // safe to ignore
             } catch (InterruptedException e) {
@@ -1055,24 +1008,19 @@
             }
         }
 
-        private static boolean isShutdownRequest(HttpRequest request) {
-            RequestLine requestLine = request.getRequestLine();
-            String uriString = requestLine.getUri();
-            URI uri = URI.create(uriString);
-            String path = uri.getPath();
-            return path.equals(SHUTDOWN_PREFIX);
-        }
-
         private class HandleResponseTask implements Runnable {
 
             private DefaultHttpServerConnection mConnection;
 
             private HttpRequest mRequest;
 
+            private Socket mSocket;
+
             public HandleResponseTask(DefaultHttpServerConnection connection,
-                    HttpRequest request) {
+                    HttpRequest request, Socket socket)  {
                 this.mConnection = connection;
                 this.mRequest = request;
+                this.mSocket = socket;
             }
 
             @Override
@@ -1082,6 +1030,10 @@
                     mConnection.sendResponseHeader(response);
                     mConnection.sendResponseEntity(response);
                     mConnection.close();
+
+                    synchronized(mLock) {
+                        ServerThread.this.mSockets.remove(mSocket);
+                    }
                 } catch (Exception e) {
                     Log.e(TAG, "Error handling request:", e);
                 }
diff --git a/libs/vogar-expect/Android.mk b/libs/vogar-expect/Android.mk
index 075bb43..2b5e074 100644
--- a/libs/vogar-expect/Android.mk
+++ b/libs/vogar-expect/Android.mk
@@ -15,6 +15,9 @@
 #
 
 LOCAL_PATH:= $(call my-dir)
+
+# Build the host library
+# ======================
 include $(CLEAR_VARS)
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 LOCAL_MODULE := vogarexpectlib
@@ -23,3 +26,13 @@
 LOCAL_STATIC_JAVA_LIBRARIES := guavalib jsonlib
 include $(BUILD_HOST_JAVA_LIBRARY)
 
+# Build the target library
+# =======================
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_MODULE := vogarexpect
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_STATIC_JAVA_LIBRARIES := guava json
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
diff --git a/libs/vogar-expect/src/vogar/ExpectationStore.java b/libs/vogar-expect/src/vogar/ExpectationStore.java
index 090322d..bf87b46 100644
--- a/libs/vogar-expect/src/vogar/ExpectationStore.java
+++ b/libs/vogar-expect/src/vogar/ExpectationStore.java
@@ -16,16 +16,17 @@
 
 package vogar;
 
-//import com.google.caliper.internal.gson.stream.JsonReader;
-
 import com.android.json.stream.JsonReader;
 import com.google.common.base.Joiner;
 import com.google.common.base.Splitter;
 import com.google.common.collect.Iterables;
-
 import java.io.File;
 import java.io.FileReader;
 import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.net.URL;
 import java.util.Collections;
 import java.util.LinkedHashMap;
 import java.util.LinkedHashSet;
@@ -127,26 +128,61 @@
         return result;
     }
 
+    /**
+     * Create an {@link ExpectationStore} that is populated from expectation resources.
+     * @param owningClass the class from which the resources are loaded.
+     * @param expectationResources the set of paths to the expectation resources; the paths are
+     * either relative to the owning class, or absolute (starting with a /).
+     * @param mode the mode within which the tests are to be run.
+     * @return the populated {@link ExpectationStore}.
+     * @throws IOException if there was a problem loading
+     */
+    public static ExpectationStore parseResources(
+            Class<?> owningClass, Set<String> expectationResources, ModeId mode)
+            throws IOException {
+        ExpectationStore result = new ExpectationStore();
+        for (String expectationsPath : expectationResources) {
+            URL url = owningClass.getResource(expectationsPath);
+            if (url == null) {
+                Log.warn("Could not find resource '" + expectationsPath
+                        + "' relative to " + owningClass);
+            } else {
+                result.parse(url, mode);
+            }
+        }
+        return result;
+    }
+
+    private void parse(URL url, ModeId mode) throws IOException {
+        Log.verbose("loading expectations from " + url);
+
+        try (InputStream is = url.openStream();
+             Reader reader = new InputStreamReader(is)) {
+            parse(reader, url.toString(), mode);
+        }
+    }
+
     public void parse(File expectationsFile, ModeId mode) throws IOException {
         Log.verbose("loading expectations file " + expectationsFile);
 
+        try (Reader fileReader = new FileReader(expectationsFile)) {
+            String source = expectationsFile.toString();
+            parse(fileReader, source, mode);
+        }
+    }
+
+    private void parse(Reader reader, String source, ModeId mode) throws IOException {
         int count = 0;
-        JsonReader reader = null;
-        try {
-            reader = new JsonReader(new FileReader(expectationsFile));
-            reader.setLenient(true);
-            reader.beginArray();
-            while (reader.hasNext()) {
-                readExpectation(reader, mode);
+        try (JsonReader jsonReader = new JsonReader(reader)) {
+            jsonReader.setLenient(true);
+            jsonReader.beginArray();
+            while (jsonReader.hasNext()) {
+                readExpectation(jsonReader, mode);
                 count++;
             }
-            reader.endArray();
+            jsonReader.endArray();
 
-            Log.verbose("loaded " + count + " expectations from " + expectationsFile);
-        } finally {
-            if (reader != null) {
-                reader.close();
-            }
+            Log.verbose("loaded " + count + " expectations from " + source);
         }
     }
 
@@ -269,4 +305,12 @@
             }
         }
     }
+
+    public Map<String, Expectation> getAllOutComes() {
+        return outcomes;
+    }
+
+    public Map<String, Expectation> getAllFailures() {
+        return failures;
+    }
 }
diff --git a/run_unit_tests.sh b/run_unit_tests.sh
new file mode 100755
index 0000000..64ecf25
--- /dev/null
+++ b/run_unit_tests.sh
@@ -0,0 +1,78 @@
+#!/bin/bash
+
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Helper script for running unit tests for compatibility libraries
+
+CTS_DIR=$(dirname ${0})
+source ${CTS_DIR}/test_defs.sh
+
+echo
+echo "---- BUILD ---- "
+echo
+
+# check if in Android build env
+if [ ! -z ${ANDROID_BUILD_TOP} ]; then
+    HOST=`uname`
+    if [ "$HOST" == "Linux" ]; then
+        OS="linux-x86"
+    elif [ "$HOST" == "Darwin" ]; then
+        OS="darwin-x86"
+    else
+        echo "Unrecognized OS"
+        exit
+    fi;
+fi;
+
+BUILD_TARGETS="
+    compatibility-common-util-tests\
+    compatibility-host-util-tests\
+    compatibility-device-util-tests\
+    compatibility-tradefed-tests\
+    cts-tradefed-tests\
+    compatibility-device-info-tests\
+    compatibility-manifest-generator-tests
+    compatibility-host-media-preconditions-tests\
+    CompatibilityTestApp"
+
+pushd ${CTS_DIR}/..
+make ${BUILD_TARGETS} -j32
+BUILD_STATUS=$?
+popd
+if [ "${BUILD_STATUS}" != "0" ]; then
+    echo "BUILD FAILED - EXIT"
+    exit 1;
+fi;
+
+
+echo
+echo "---- DEVICE-SIDE TESTS ---- "
+echo
+
+${CTS_DIR}/common/device-side/test-app/run_tests.sh
+
+echo
+echo "---- HOST TESTS ---- "
+echo
+
+############### Run the host side tests ###############
+${CTS_DIR}/common/host-side/tradefed/tests/run_tests.sh
+${CTS_DIR}/common/host-side/manifest-generator/tests/run_tests.sh
+${CTS_DIR}/common/host-side/util/tests/run_tests.sh
+${CTS_DIR}/common/util/tests/run_tests.sh
+
+${CTS_DIR}/tools/cts-tradefed/tests/run_tests.sh
+
+${CTS_DIR}/tests/tests/mediastress/preconditions/tests/run_tests.sh
diff --git a/suite/audio_quality/executable/Android.mk b/suite/audio_quality/executable/Android.mk
index a37b987..8049596 100644
--- a/suite/audio_quality/executable/Android.mk
+++ b/suite/audio_quality/executable/Android.mk
@@ -14,23 +14,15 @@
 # limitations under the License.
 #
 
-# build only for linux
-ifeq ($(HOST_OS),linux)
-
 LOCAL_PATH:= $(call my-dir)
 include $(CLEAR_VARS)
-LOCAL_CPP_EXTENSION := .cpp
-LOCAL_MODULE_TAGS := optional
-LOCAL_SRC_FILES := $(patsubst ./%,%, $(shell cd $(LOCAL_PATH); \
-  find . -name "*.cpp" -and -not -name ".*"))
-#$(info $(LOCAL_SRC_FILES))
+LOCAL_SRC_FILES := $(call all-subdir-cpp-files)
 LOCAL_C_INCLUDES += $(LOCAL_PATH)/../lib/include  external/tinyalsa/include/  libcore/include \
 	$(LOCAL_PATH)/../lib/src
 LOCAL_STATIC_LIBRARIES += libutils liblog libcutils libtinyalsa libtinyxml
 LOCAL_WHOLE_STATIC_LIBRARIES := libcts_audio_quality
 LOCAL_CFLAGS:= -g -fno-exceptions
 LOCAL_LDFLAGS:= -g -lrt -ldl -lstdc++ -lm -fno-exceptions -lpthread
+LOCAL_MODULE_HOST_OS := linux
 LOCAL_MODULE:= cts_audio_quality
 include $(BUILD_HOST_EXECUTABLE)
-
-endif # linux
diff --git a/suite/audio_quality/lib/Android.mk b/suite/audio_quality/lib/Android.mk
index 341a4dd..d4aaf84 100644
--- a/suite/audio_quality/lib/Android.mk
+++ b/suite/audio_quality/lib/Android.mk
@@ -14,22 +14,14 @@
 # limitations under the License.
 #
 
-# build only for linux
-ifeq ($(HOST_OS),linux)
-
 LOCAL_PATH:= $(call my-dir)
 include $(CLEAR_VARS)
-LOCAL_CPP_EXTENSION := .cpp
-LOCAL_MODULE_TAGS := optional
-LOCAL_SRC_FILES := $(patsubst ./%,%, $(shell cd $(LOCAL_PATH); \
-  find . -name "*.cpp" -and -not -name ".*"))
-#$(info $(LOCAL_SRC_FILES))
+LOCAL_SRC_FILES := $(call all-subdir-cpp-files)
 LOCAL_C_INCLUDES += $(LOCAL_PATH)/include $(LOCAL_PATH)/src /usr/include/ \
 	external/tinyalsa/include/ external/tinyxml/ libcore/include
 LOCAL_STATIC_LIBRARIES += libutils liblog libtinyalsa libcutils libtinyxml
 LOCAL_CFLAGS:= -g -fno-exceptions
 LOCAL_LDFLAGS:= -g -lrt -ldl -lm -fno-exceptions
+LOCAL_MODULE_HOST_OS := linux
 LOCAL_MODULE:= libcts_audio_quality
 include $(BUILD_HOST_STATIC_LIBRARY)
-
-endif # linux
diff --git a/suite/audio_quality/lib/include/Log.h b/suite/audio_quality/lib/include/Log.h
index d7520f0..b33c21f 100644
--- a/suite/audio_quality/lib/include/Log.h
+++ b/suite/audio_quality/lib/include/Log.h
@@ -64,6 +64,6 @@
 #define ASSERT(cond) if(!(cond)) {  Log::Instance()->printf(Log::ELogE, \
         "assertion failed %s %d", __FILE__, __LINE__); \
     Log::Finalize(); \
-    *(char*)0 = 0; /* this will crash */};
+    abort(); };
 
 #endif // CTSAUDIO_LOG_H
diff --git a/suite/audio_quality/lib/src/FileUtil.cpp b/suite/audio_quality/lib/src/FileUtil.cpp
index dffc394..3b87016 100644
--- a/suite/audio_quality/lib/src/FileUtil.cpp
+++ b/suite/audio_quality/lib/src/FileUtil.cpp
@@ -81,7 +81,7 @@
     mBuffer = new char[DEFAULT_BUFFER_SIZE];
     if (mBuffer == NULL) {
         // cannot use ASSERT here, just crash
-        *(char*)0 = 0;
+        abort();
     }
     mBufferSize = DEFAULT_BUFFER_SIZE;
 }
@@ -130,7 +130,7 @@
             mBuffer = new char[2 * size];
             if (mBuffer == NULL) {
                 // cannot use ASSERT here, just crash
-                *(char*)0 = 0;
+                abort();
             }
             mBufferSize = 2 * size;
             // re-try
diff --git a/suite/audio_quality/lib/src/Log.cpp b/suite/audio_quality/lib/src/Log.cpp
index d4cf353..1d2434a 100644
--- a/suite/audio_quality/lib/src/Log.cpp
+++ b/suite/audio_quality/lib/src/Log.cpp
@@ -23,7 +23,7 @@
 
 #define ASSERT_PLAIN(cond) if(!(cond)) { fprintf(stderr, \
         "assertion failed %s %d", __FILE__, __LINE__); \
-    *(char*)0 = 0; /* this will crash */};
+    abort(); };
 
 Log* Log::Instance(const char* dirName)
 {
diff --git a/suite/audio_quality/lib/src/audio/AudioLocal.cpp b/suite/audio_quality/lib/src/audio/AudioLocal.cpp
index 71b7afb..2a65689 100644
--- a/suite/audio_quality/lib/src/audio/AudioLocal.cpp
+++ b/suite/audio_quality/lib/src/audio/AudioLocal.cpp
@@ -23,7 +23,7 @@
     // gain control not necessary in MobilePre as there is no control.
     // This means audio source itself should be adjusted to control volume
     if (mState == EStNone) {
-        if (run() != android::NO_ERROR) {
+        if (run("AudioLocal") != android::NO_ERROR) {
             LOGE("AudioLocal cannot run");
             // cannot run thread
             return false;
diff --git a/suite/audio_quality/lib/src/audio/RemoteAudio.cpp b/suite/audio_quality/lib/src/audio/RemoteAudio.cpp
index d9b7c51..ead04b91 100644
--- a/suite/audio_quality/lib/src/audio/RemoteAudio.cpp
+++ b/suite/audio_quality/lib/src/audio/RemoteAudio.cpp
@@ -59,7 +59,7 @@
 bool RemoteAudio::init(int port)
 {
     mPort = port;
-    if (run() != android::NO_ERROR) {
+    if (run("RemoteAudio") != android::NO_ERROR) {
         LOGE("RemoteAudio cannot run");
         // cannot run thread
         return false;
diff --git a/suite/audio_quality/test/Android.mk b/suite/audio_quality/test/Android.mk
index bd0033f..21b0250 100644
--- a/suite/audio_quality/test/Android.mk
+++ b/suite/audio_quality/test/Android.mk
@@ -14,16 +14,9 @@
 # limitations under the License.
 #
 
-# build only for linux
-ifeq ($(HOST_OS),linux)
-
 LOCAL_PATH:= $(call my-dir)
 include $(CLEAR_VARS)
-LOCAL_CPP_EXTENSION := .cpp
-LOCAL_MODULE_TAGS := optional
-LOCAL_SRC_FILES := $(patsubst ./%,%, $(shell cd $(LOCAL_PATH); \
-  find . -name "*.cpp" -and -not -name ".*"))
-#LOCAL_SRC_FILES := 	AudioRecordPlayTest.cpp
+LOCAL_SRC_FILES := $(call all-subdir-cpp-files)
 
 #$(info $(LOCAL_SRC_FILES))
 LOCAL_C_INCLUDES += $(LOCAL_PATH)/../lib/include $(LOCAL_PATH)/../lib/src external/gtest/include \
@@ -35,7 +28,6 @@
 LOCAL_WHOLE_STATIC_LIBRARIES := libcts_audio_quality
 LOCAL_CFLAGS:= -g -fno-exceptions
 LOCAL_LDFLAGS:= -g -lrt -ldl -lm -fno-exceptions -lpthread
+LOCAL_MODULE_HOST_OS := linux
 LOCAL_MODULE:= cts_audio_quality_test
 include $(BUILD_HOST_EXECUTABLE)
-
-endif # linux
diff --git a/suite/cts/deviceTests/browserbench/Android.mk b/suite/cts/deviceTests/browserbench/Android.mk
deleted file mode 100644
index 3696bcd..0000000
--- a/suite/cts/deviceTests/browserbench/Android.mk
+++ /dev/null
@@ -1,31 +0,0 @@
-# Copyright (C) 2012 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-# don't include this package in any target
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctstestrunner ctstestserver
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_PACKAGE_NAME := CtsDeviceBrowserBench
-
-LOCAL_SDK_VERSION := 16
-
-include $(BUILD_CTS_PACKAGE)
-
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/suite/cts/deviceTests/browserbench/AndroidManifest.xml b/suite/cts/deviceTests/browserbench/AndroidManifest.xml
deleted file mode 100644
index 4bf5b5e..0000000
--- a/suite/cts/deviceTests/browserbench/AndroidManifest.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-        package="com.android.cts.browser">
-
-    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
-    <uses-permission android:name="android.permission.INTERNET" />
-    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
-
-    <application>
-        <uses-library android:name="android.test.runner" />
-    </application>
-    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-            android:targetPackage="com.android.cts.browser" />
-</manifest>
diff --git a/suite/cts/deviceTests/browserbench/src/com/android/cts/browser/BrowserBenchTest.java b/suite/cts/deviceTests/browserbench/src/com/android/cts/browser/BrowserBenchTest.java
deleted file mode 100644
index d74ddb2..0000000
--- a/suite/cts/deviceTests/browserbench/src/com/android/cts/browser/BrowserBenchTest.java
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.browser;
-
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.cts.util.WatchDog;
-import android.net.Uri;
-import android.provider.Browser;
-import android.util.Log;
-import android.webkit.cts.CtsTestServer;
-
-import android.cts.util.CtsAndroidTestCase;
-import com.android.cts.util.ResultType;
-import com.android.cts.util.ResultUnit;
-import com.android.cts.util.Stat;
-import com.android.cts.util.TimeoutReq;
-
-import java.net.URLDecoder;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.http.HttpRequest;
-import org.apache.http.HttpResponse;
-import org.apache.http.RequestLine;
-/**
- * Browser benchmarking.
- * It launches an activity with URL and wait for POST from the client.
- */
-public class BrowserBenchTest extends CtsAndroidTestCase {
-    private static final String TAG = BrowserBenchTest.class.getSimpleName();
-    private static final boolean DEBUG = false;
-    private static final String OCTANE_START_FILE = "octane/index.html";
-    private static final String ROBOHORNET_START_FILE = "robohornet/robohornet.html";
-    private static final String HOST_COMPLETION_BROADCAST = "com.android.cts.browser.completion";
-    // time-out for watch-dog. POST should happen within this time.
-    private static long BROWSER_POST_TIMEOUT_IN_MS = 10 * 60 * 1000L;
-    // watch-dog will time-out first. So make it long enough.
-    private static long BROWSER_COMPLETION_TIMEOUT_IN_MS = 60 * 60 * 1000L;
-    private static final String HTTP_USER_AGENT = "User-Agent";
-    private CtsTestServer mWebServer;
-    // used for final score
-    private ResultType mTypeNonFinal = ResultType.NEUTRAL;
-    private ResultUnit mUnitNonFinal = ResultUnit.NONE;
-    // used for all other scores
-    private ResultType mTypeFinal = ResultType.NEUTRAL;
-    private ResultUnit mUnitFinal = ResultUnit.SCORE;
-    private WatchDog mWatchDog;
-    private CountDownLatch mLatch;
-    // can be changed by each test before starting
-    private volatile int mNumberRepeat;
-    /** tells how many tests have run up to now */
-    private volatile int mRunIndex;
-    /** stores results for each runs. last entry will be the final score. */
-    private LinkedHashMap<String, double[]> mResultsMap;
-    private PackageManager mPackageManager;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mPackageManager = getInstrumentation().getContext().getPackageManager();
-        mWebServer = new CtsTestServer(getContext()) {
-            @Override
-            protected HttpResponse onPost(HttpRequest request) throws Exception {
-                // post uri will look like "cts_report.html?final=1&score=10.1&message=hello"
-                RequestLine requestLine = request.getRequestLine();
-                String uriString = URLDecoder.decode(requestLine.getUri(), "UTF-8");
-                if (DEBUG) {
-                    Log.i(TAG, "uri:" + uriString);
-                }
-                String resultRe =
-                        ".*cts_report.html\\?final=([\\d])&score=([\\d]+\\.?[\\d]*)&message=([\\w][\\w ]*)";
-                Pattern resultPattern = Pattern.compile(resultRe);
-                Matcher matchResult = resultPattern.matcher(uriString);
-                if (matchResult.find()) {
-                    int isFinal = Integer.parseInt(matchResult.group(1));
-                    double score = Double.parseDouble(matchResult.group(2));
-                    String message = matchResult.group(3);
-                    Log.i(TAG, message + ":" + score);
-                    if (!mResultsMap.containsKey(message)) {
-                        mResultsMap.put(message, new double[mNumberRepeat]);
-                    }
-                    double[] scores = mResultsMap.get(message);
-                    scores[mRunIndex] = score;
-                    if (isFinal == 1) {
-                        String userAgent = request.getFirstHeader(HTTP_USER_AGENT).getValue();
-                        getReportLog().printValue(HTTP_USER_AGENT + "=" + userAgent, 0,
-                                ResultType.NEUTRAL, ResultUnit.NONE);
-                        mLatch.countDown();
-                    }
-                    mWatchDog.reset();
-                }
-                return null; // default response is OK as it will be ignored by client anyway.
-            }
-        };
-        mResultsMap = new LinkedHashMap<String, double[]>();
-        mWatchDog = new WatchDog(BROWSER_POST_TIMEOUT_IN_MS);
-        mWatchDog.start();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        mWatchDog.stop();
-        mWebServer.shutdown();
-        mWebServer = null;
-        mResultsMap = null;
-        super.tearDown();
-    }
-
-    @TimeoutReq(minutes = 60)
-    public void testOctane() throws InterruptedException {
-        if (!isBrowserSupported()) {
-            Log.i(TAG, "Skipping test for device with no supported browser");
-            return;
-        }
-        String url = mWebServer.getAssetUrl(OCTANE_START_FILE) + "?auto=1";
-        final int kRepeat = 5;
-        doTest(url, ResultType.LOWER_BETTER, ResultUnit.MS,
-                ResultType.HIGHER_BETTER, ResultUnit.SCORE, kRepeat);
-    }
-
-    private void doTest(String url, ResultType typeNonFinal, ResultUnit unitNonFinal,
-            ResultType typeFinal, ResultUnit unitFinal, int numberRepeat)
-                    throws InterruptedException {
-        mTypeNonFinal = typeNonFinal;
-        mUnitNonFinal = unitNonFinal;
-        mTypeFinal = typeFinal;
-        mUnitFinal = unitFinal;
-        mNumberRepeat = numberRepeat;
-        Uri uri = Uri.parse(url);
-        for (mRunIndex = 0; mRunIndex < numberRepeat; mRunIndex++) {
-            Log.i(TAG, mRunIndex + "-th round");
-            mLatch = new CountDownLatch(1);
-            Intent intent = new Intent(Intent.ACTION_VIEW, uri);
-            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-            // force using only one window or tab
-            intent.putExtra(Browser.EXTRA_APPLICATION_ID, getContext().getPackageName());
-            getContext().startActivity(intent);
-            boolean ok = mLatch.await(BROWSER_COMPLETION_TIMEOUT_IN_MS, TimeUnit.MILLISECONDS);
-            assertTrue("timed-out", ok);
-        }
-        // it is somewhat awkward to handle the last one specially with Map
-        int numberEntries = mResultsMap.size();
-        int numberToProcess = 1;
-        for (Map.Entry<String, double[]> entry : mResultsMap.entrySet()) {
-            String message = entry.getKey();
-            double[] scores = entry.getValue();
-            if (numberToProcess == numberEntries) { // final score
-                // store the whole results first
-                getReportLog().printArray(message, scores, mTypeFinal, mUnitFinal);
-                getReportLog().printSummary(message, Stat.getAverage(scores), mTypeFinal,
-                        mUnitFinal);
-            } else { // interim results
-                getReportLog().printArray(message, scores, mTypeNonFinal, mUnitNonFinal);
-            }
-            numberToProcess++;
-        }
-    }
-
-    /**
-     * @return true iff this device is has a working browser.
-     */
-    private boolean isBrowserSupported() {
-        return !(mPackageManager.hasSystemFeature("android.hardware.type.television")
-                 || mPackageManager.hasSystemFeature("android.software.leanback")
-                 || mPackageManager.hasSystemFeature("android.hardware.type.watch"));
-    }
-}
diff --git a/suite/cts/deviceTests/dram/Android.mk b/suite/cts/deviceTests/dram/Android.mk
deleted file mode 100644
index 879d151..0000000
--- a/suite/cts/deviceTests/dram/Android.mk
+++ /dev/null
@@ -1,36 +0,0 @@
-# Copyright (C) 2012 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-# don't include this package in any target
-LOCAL_MODULE_TAGS := tests
-
-# Include both the 32 and 64 bit versions
-LOCAL_MULTILIB := both
-
-LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctstestrunner
-
-LOCAL_JNI_SHARED_LIBRARIES := libctsdram_jni
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_PACKAGE_NAME := CtsDeviceDram
-
-LOCAL_SDK_VERSION := 16
-
-include $(BUILD_CTS_PACKAGE)
-
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/suite/cts/deviceTests/dram/AndroidManifest.xml b/suite/cts/deviceTests/dram/AndroidManifest.xml
deleted file mode 100644
index c9aaf3d..0000000
--- a/suite/cts/deviceTests/dram/AndroidManifest.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-        package="com.android.cts.dram">
-
-    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
-    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
-
-    <application>
-        <uses-library android:name="android.test.runner" />
-    </application>
-    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-            android:targetPackage="com.android.cts.dram"
-            android:label="DRAM bandwidth measurement" />
-</manifest>
diff --git a/suite/cts/deviceTests/dram/jni/MemoryNativeJni.cpp b/suite/cts/deviceTests/dram/jni/MemoryNativeJni.cpp
deleted file mode 100644
index 7d9a5fc..0000000
--- a/suite/cts/deviceTests/dram/jni/MemoryNativeJni.cpp
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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 <jni.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/time.h>
-
-double currentTimeMillis()
-{
-    struct timeval tv;
-    gettimeofday(&tv, (struct timezone *) NULL);
-    return tv.tv_sec * 1000.0 + tv.tv_usec / 1000.0;
-}
-
-extern "C" JNIEXPORT jdouble JNICALL Java_com_android_cts_dram_MemoryNative_runMemcpy(JNIEnv* env,
-        jclass clazz, jint bufferSize, jint repetition)
-{
-    char* src = new char[bufferSize];
-    char* dst = new char[bufferSize];
-    if ((src == NULL) || (dst == NULL)) {
-        delete[] src;
-        delete[] dst;
-        env->ThrowNew(env->FindClass("java/lang/OutOfMemoryError"), "No memory");
-        return -1;
-    }
-    memset(src, 0, bufferSize);
-    memset(dst, 0, bufferSize);
-    double start = currentTimeMillis();
-    for (int i = 0; i < repetition; i++) {
-        memcpy(dst, src, bufferSize);
-        src[bufferSize - 1] = i & 0xff;
-    }
-    double end = currentTimeMillis();
-    delete[] src;
-    delete[] dst;
-    return end - start;
-}
-
-extern "C" JNIEXPORT jdouble JNICALL Java_com_android_cts_dram_MemoryNative_runMemset(JNIEnv* env,
-        jclass clazz, jint bufferSize, jint repetition, jint c)
-{
-    char* dst = new char[bufferSize];
-    if (dst == NULL) {
-        delete[] dst;
-        env->ThrowNew(env->FindClass("java/lang/OutOfMemoryError"), "No memory");
-        return -1;
-    }
-    memset(dst, 0, bufferSize);
-    double start = currentTimeMillis();
-    for (int i = 0; i < repetition; i++) {
-        memset(dst, (c + i) & 0xff, bufferSize);
-    }
-    double end = currentTimeMillis();
-    delete[] dst;
-    return end - start;
-}
-
diff --git a/suite/cts/deviceTests/dram/src/com/android/cts/dram/BandwidthTest.java b/suite/cts/deviceTests/dram/src/com/android/cts/dram/BandwidthTest.java
deleted file mode 100644
index eeb7f9b..0000000
--- a/suite/cts/deviceTests/dram/src/com/android/cts/dram/BandwidthTest.java
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.dram;
-
-import android.content.Context;
-import android.graphics.Point;
-import android.util.Log;
-import android.view.WindowManager;
-
-import com.android.cts.util.ResultType;
-import com.android.cts.util.ResultUnit;
-import android.cts.util.CtsAndroidTestCase;
-import com.android.cts.util.ReportLog;
-import com.android.cts.util.Stat;
-
-/**
- * check how many screens the memcpy function can copy in a sec.
- * Note that this does not represent the total memory bandwidth available in the system
- * as typically CPU cannot use the whole bandwidth.
- * Smaller buffers can fit into L1 or L2 cache, which can show big boost.
- */
-public class BandwidthTest extends CtsAndroidTestCase {
-    private static final String TAG = BandwidthTest.class.getSimpleName();
-    private static final int MEMCPY_REPETITION = 10;
-    private static final int MEMSET_REPETITION = 30;
-    private static final int REPEAT_IN_EACH_CALL = 100;
-    private static final int KB = 1024;
-    private static final int MB = 1024 * 1024;
-    private static final int MEMSET_CHAR = 0xa5;
-    // reject data outside +/- this value * median
-    private static final double OUTLIER_THRESHOLD = 0.1;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        // warm-up
-        MemoryNative.runMemcpy(2 * MB, 100);
-    }
-
-    public void testMemcpyK004() {
-        doRunMemcpy(4 * KB);
-    }
-
-    public void testMemcpyK008() {
-        doRunMemcpy(8 * KB);
-    }
-
-    public void testMemcpyK016() {
-        doRunMemcpy(16 * KB);
-    }
-
-    public void testMemcpyK032() {
-        doRunMemcpy(32 * KB);
-    }
-
-    public void testMemcpyK064() {
-        doRunMemcpy(64 * KB);
-    }
-
-    public void testMemcpyK128() {
-        doRunMemcpy(128 * KB);
-    }
-
-    public void testMemcpyK256() {
-        doRunMemcpy(256 * KB);
-    }
-
-    public void testMemcpyK512() {
-        doRunMemcpy(512 * KB);
-    }
-
-    public void testMemcpyM001() {
-        doRunMemcpy(1 * MB);
-    }
-
-    public void testMemcpyM002() {
-        doRunMemcpy(2 * MB);
-    }
-
-    public void testMemcpyM004() {
-        doRunMemcpy(4 * MB);
-    }
-
-    public void testMemcpyM008() {
-        doRunMemcpy(8 * MB);
-    }
-
-    public void testMemcpyM016() {
-        doRunMemcpy(16 * MB);
-    }
-
-    public void testMemsetK004() {
-        doRunMemset(4 * KB);
-    }
-
-    public void testMemsetK008() {
-        doRunMemset(8 * KB);
-    }
-
-    public void testMemsetK016() {
-        doRunMemset(16 * KB);
-    }
-
-    public void testMemsetK032() {
-        doRunMemset(32 * KB);
-    }
-
-    public void testMemsetK064() {
-        doRunMemset(64 * KB);
-    }
-
-    public void testMemsetK128() {
-        doRunMemset(128 * KB);
-    }
-
-    public void testMemsetK256() {
-        doRunMemset(256 * KB);
-    }
-
-    public void testMemsetK512() {
-        doRunMemset(512 * KB);
-    }
-
-    public void testMemsetM001() {
-        doRunMemset(1 * MB);
-    }
-
-    public void testMemsetM002() {
-        doRunMemset(2 * MB);
-    }
-
-    public void testMemsetM004() {
-        doRunMemset(4 * MB);
-    }
-
-    public void testMemsetM008() {
-        doRunMemset(8 * MB);
-    }
-
-    public void testMemsetM016() {
-        doRunMemset(16 * MB);
-    }
-
-    private void doRunMemcpy(int bufferSize) {
-        double[] result = new double[MEMCPY_REPETITION];
-        int repeatInEachCall = REPEAT_IN_EACH_CALL;
-        if (bufferSize < (1 * MB)) {
-            // too small buffer size finishes too early to give accurate result.
-            repeatInEachCall *= (1 * MB / bufferSize);
-        }
-        for (int i = 0; i < MEMCPY_REPETITION; i++) {
-            result[i] = MemoryNative.runMemcpy(bufferSize, repeatInEachCall);
-        }
-        getReportLog().printArray("memcpy time", result, ResultType.LOWER_BETTER,
-                ResultUnit.MS);
-        double[] mbps = ReportLog.calcRatePerSecArray(
-                (double)bufferSize * repeatInEachCall / 1024.0 / 1024.0, result);
-        getReportLog().printArray("memcpy throughput", mbps, ResultType.HIGHER_BETTER,
-                ResultUnit.MBPS);
-        Stat.StatResult stat = Stat.getStatWithOutlierRejection(mbps, OUTLIER_THRESHOLD);
-        if (stat.mDataCount != result.length) {
-            Log.w(TAG, "rejecting " + (result.length - stat.mDataCount) + " outliers");
-        }
-        WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
-        Point size = new Point();
-        wm.getDefaultDisplay().getSize(size);
-        Log.i(TAG, " x " + size.x + " y " + size.y);
-        double pixels = size.x * size.y;
-        // now this represents how many times the whole screen can be copied in a sec.
-        double screensPerSecAverage = stat.mAverage / pixels * 1024.0 * 1024.0 / 4.0;
-        getReportLog().printValue("memcpy in fps", screensPerSecAverage,
-                ResultType.HIGHER_BETTER, ResultUnit.FPS);
-        getReportLog().printSummary("memcpy throughput", stat.mAverage, ResultType.HIGHER_BETTER,
-                ResultUnit.MBPS);
-    }
-
-    private void doRunMemset(int bufferSize) {
-        double[] result = new double[MEMSET_REPETITION];
-        int repeatInEachCall = REPEAT_IN_EACH_CALL;
-        if (bufferSize < (1 * MB)) {
-            // too small buffer size finishes too early to give accurate result.
-            repeatInEachCall *= (1 * MB / bufferSize);
-        }
-        for (int i = 0; i < MEMSET_REPETITION; i++) {
-            result[i] = MemoryNative.runMemset(bufferSize, repeatInEachCall, MEMSET_CHAR);
-        }
-        getReportLog().printArray("memset time", result, ResultType.LOWER_BETTER,
-                ResultUnit.MS);
-        double[] mbps = ReportLog.calcRatePerSecArray(
-                (double)bufferSize * repeatInEachCall / 1024.0 / 1024.0, result);
-        getReportLog().printArray("memset throughput", mbps, ResultType.HIGHER_BETTER,
-                ResultUnit.MBPS);
-        Stat.StatResult stat = Stat.getStatWithOutlierRejection(mbps, OUTLIER_THRESHOLD);
-        if (stat.mDataCount != result.length) {
-            Log.w(TAG, "rejecting " + (result.length - stat.mDataCount) + " outliers");
-        }
-        WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
-        Point size = new Point();
-        wm.getDefaultDisplay().getSize(size);
-        Log.i(TAG, " x " + size.x + " y " + size.y);
-        double pixels = size.x * size.y;
-        // now this represents how many times the whole screen can be copied in a sec.
-        double screensPerSecAverage = stat.mAverage / pixels * 1024.0 * 1024.0 / 4.0;
-        getReportLog().printValue("memset in fps", screensPerSecAverage,
-                ResultType.HIGHER_BETTER, ResultUnit.FPS);
-        getReportLog().printSummary("memset throughput", stat.mAverage, ResultType.HIGHER_BETTER,
-                ResultUnit.MBPS);
-    }
-}
diff --git a/suite/cts/deviceTests/dram/src/com/android/cts/dram/MemoryNative.java b/suite/cts/deviceTests/dram/src/com/android/cts/dram/MemoryNative.java
deleted file mode 100644
index e55127d..0000000
--- a/suite/cts/deviceTests/dram/src/com/android/cts/dram/MemoryNative.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.dram;
-
-public class MemoryNative {
-    static {
-        System.loadLibrary("ctsdram_jni");
-    }
-    /**
-     * run memcpy for given number of repetition from a source to a destination buffers
-     * with each having the size of bufferSize.
-     * @param bufferSize
-     * @param repeatition
-     * @return time spent in copying in ms.
-     */
-    public static native double runMemcpy(int bufferSize, int repetition);
-
-    /**
-     * run memset for given number of repetition from a source to a destination buffers
-     * with each having the size of bufferSize.
-     * @param bufferSize
-     * @param repetition
-     * @param c char to set. Only LSBs will be used to get char value.
-     * @return time spent in memset in ms.
-     */
-    public static native double runMemset(int bufferSize, int repetition, int c);
-}
diff --git a/suite/cts/deviceTests/filesystemperf/Android.mk b/suite/cts/deviceTests/filesystemperf/Android.mk
deleted file mode 100644
index 7ee93de..0000000
--- a/suite/cts/deviceTests/filesystemperf/Android.mk
+++ /dev/null
@@ -1,32 +0,0 @@
-# Copyright (C) 2012 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-# don't include this package in any target
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctstestrunner
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_PACKAGE_NAME := CtsDeviceFilePerf
-
-LOCAL_SDK_VERSION := 16
-
-cts_runtime_hint := 28
-
-include $(BUILD_CTS_PACKAGE)
-
diff --git a/suite/cts/deviceTests/filesystemperf/AndroidManifest.xml b/suite/cts/deviceTests/filesystemperf/AndroidManifest.xml
deleted file mode 100644
index 329bf19..0000000
--- a/suite/cts/deviceTests/filesystemperf/AndroidManifest.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-        package="com.android.cts.filesystemperf">
-
-    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
-    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
-
-    <application>
-        <uses-library android:name="android.test.runner" />
-    </application>
-    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-            android:targetPackage="com.android.cts.filesystemperf"
-            android:label="UI Latency measurement" />
-</manifest>
diff --git a/suite/cts/deviceTests/filesystemperf/src/com/android/cts/filesystemperf/AlmostFullTest.java b/suite/cts/deviceTests/filesystemperf/src/com/android/cts/filesystemperf/AlmostFullTest.java
deleted file mode 100644
index ab81f16..0000000
--- a/suite/cts/deviceTests/filesystemperf/src/com/android/cts/filesystemperf/AlmostFullTest.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.filesystemperf;
-
-import android.util.Log;
-
-import android.cts.util.CtsAndroidTestCase;
-import android.cts.util.SystemUtil;
-
-import com.android.cts.util.TimeoutReq;
-
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicInteger;
-
-public class AlmostFullTest extends CtsAndroidTestCase {
-
-    private static final String DIR_INITIAL_FILL = "INITIAL_FILL";
-    private static final String DIR_SEQ_UPDATE = "SEQ_UPDATE";
-    private static final String DIR_RANDOM_WR = "RANDOM_WR";
-    private static final String DIR_RANDOM_RD = "RANDOM_RD";
-    private static final String TAG = "AlmostFullTest";
-
-    private static final long FREE_SPACE_FINAL = 1000L * 1024 * 1024L;
-
-    // test runner creates multiple instances at the begging.
-    // use that to fill disk only once.
-    // set as final to initialize it only once
-    private static final AtomicInteger mRefCounter = new AtomicInteger(0);
-    private static final AtomicBoolean mDiskFilled = new AtomicBoolean(false);
-
-    public AlmostFullTest() {
-        int currentCounter = mRefCounter.incrementAndGet();
-        Log.i(TAG, "++currentCounter: " + currentCounter);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        if (mDiskFilled.compareAndSet(false, true)) {
-            Log.i(TAG, "Filling disk");
-            // initial fill done in two stage as disk can be filled by other
-            // components
-            long freeDisk = SystemUtil.getFreeDiskSize(getContext());
-            long diskToFill = freeDisk - FREE_SPACE_FINAL;
-            if (diskToFill >= 0) {
-                Log.i(TAG, "free disk " + freeDisk + ", to fill " + diskToFill);
-            } else {
-                Log.i(TAG, "free disk " + freeDisk + " too small, needs " + FREE_SPACE_FINAL);
-                return;
-            }
-            final long MAX_FILE_SIZE_TO_FILL = 1024L * 1024L * 1024L;
-            long filled = 0;
-            while (filled < diskToFill) {
-                long toFill = diskToFill - filled;
-                if (toFill > MAX_FILE_SIZE_TO_FILL) {
-                    toFill = MAX_FILE_SIZE_TO_FILL;
-                }
-                Log.i(TAG, "Generating file " + toFill);
-                FileUtil.createNewFilledFile(getContext(),
-                        DIR_INITIAL_FILL, toFill);
-                filled += toFill;
-            }
-        }
-        Log.i(TAG, "free disk " + SystemUtil.getFreeDiskSize(getContext()));
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        Log.i(TAG, "tearDown free disk " + SystemUtil.getFreeDiskSize(getContext()));
-        int currentCounter = mRefCounter.decrementAndGet();
-        Log.i(TAG, "--currentCounter: " + currentCounter);
-        if (currentCounter == 0) {
-            FileUtil.removeFileOrDir(getContext(), DIR_INITIAL_FILL);
-        }
-        FileUtil.removeFileOrDir(getContext(), DIR_SEQ_UPDATE);
-        FileUtil.removeFileOrDir(getContext(), DIR_RANDOM_WR);
-        FileUtil.removeFileOrDir(getContext(), DIR_RANDOM_RD);
-        Log.i(TAG, "tearDown free disk " + SystemUtil.getFreeDiskSize(getContext()));
-        super.tearDown();
-    }
-
-    @TimeoutReq(minutes = 30)
-    public void testSequentialUpdate() throws Exception {
-        // now about freeSpaceToLeave should be left
-        // and try updating exceeding the free space size
-        final long FILE_SIZE = 400L * 1024L * 1024L;
-        long freeDisk = SystemUtil.getFreeDiskSize(getContext());
-        Log.i(TAG, "Now free space is " + freeDisk);
-        if (freeDisk < FILE_SIZE) {
-            Log.w(TAG, "too little space: " + freeDisk);
-            return;
-        }
-        final int BUFFER_SIZE = 10 * 1024 * 1024;
-        final int NUMBER_REPETITION = 10;
-        FileUtil.doSequentialUpdateTest(getContext(), DIR_SEQ_UPDATE, getReportLog(), FILE_SIZE,
-                BUFFER_SIZE, NUMBER_REPETITION);
-    }
-
-    // TODO: file size too small and caching will give wrong better result.
-    // needs to flush cache by reading big files per each read.
-    @TimeoutReq(minutes = 60)
-    public void testRandomRead() throws Exception {
-        final int BUFFER_SIZE = 4 * 1024;
-        final long fileSize = 400L * 1024L * 1024L;
-        long freeDisk = SystemUtil.getFreeDiskSize(getContext());
-        if (freeDisk < fileSize) {
-            Log.w(TAG, "too little space: " + freeDisk);
-            return;
-        }
-        FileUtil.doRandomReadTest(getContext(), DIR_RANDOM_RD, getReportLog(), fileSize,
-                BUFFER_SIZE);
-    }
-
-    @TimeoutReq(minutes = 60)
-    public void testRandomUpdate() throws Exception {
-        final int BUFFER_SIZE = 4 * 1024;
-        final long fileSize = 256L * 1024L * 1024L;
-        long freeDisk = SystemUtil.getFreeDiskSize(getContext());
-        if (freeDisk < fileSize) {
-            Log.w(TAG, "too little space: " + freeDisk);
-            return;
-        }
-        FileUtil.doRandomWriteTest(getContext(), DIR_RANDOM_WR, getReportLog(), fileSize,
-                BUFFER_SIZE);
-    }
-}
diff --git a/suite/cts/deviceTests/filesystemperf/src/com/android/cts/filesystemperf/FileUtil.java b/suite/cts/deviceTests/filesystemperf/src/com/android/cts/filesystemperf/FileUtil.java
deleted file mode 100755
index 6231774..0000000
--- a/suite/cts/deviceTests/filesystemperf/src/com/android/cts/filesystemperf/FileUtil.java
+++ /dev/null
@@ -1,408 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.filesystemperf;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.RandomAccessFile;
-import java.util.Random;
-
-import com.android.cts.util.MeasureRun;
-import com.android.cts.util.MeasureTime;
-import com.android.cts.util.ResultType;
-import com.android.cts.util.ResultUnit;
-import com.android.cts.util.ReportLog;
-import com.android.cts.util.Stat;
-import android.cts.util.SystemUtil;
-
-import android.content.Context;
-import android.util.Log;
-
-public class FileUtil {
-    private static final String TAG = "FileUtil";
-    private static final Random mRandom = new Random(0);
-    private static long mFileId = 0;
-    /**
-     * create array with different data per each call
-     *
-     * @param length
-     * @param randomSeed
-     * @return
-     */
-    public static byte[] generateRandomData(int length) {
-        byte[] buffer = new byte[length];
-        int val = mRandom.nextInt();
-        for (int i = 0; i < length / 4; i++) {
-            // in little-endian
-            buffer[i * 4] = (byte)(val & 0x000000ff);
-            buffer[i * 4 + 1] = (byte)((val & 0x0000ff00) >> 8);
-            buffer[i * 4 + 2] = (byte)((val & 0x00ff0000) >> 16);
-            buffer[i * 4 + 3] = (byte)((val & 0xff000000) >> 24);
-            val++;
-        }
-        for (int i = (length / 4) * 4; i < length; i++) {
-            buffer[i] = 0;
-        }
-        return buffer;
-    }
-
-    /**
-     * create a new file under the given dirName.
-     * Existing files will not be affected.
-     * @param context
-     * @param dirName
-     * @return
-     */
-    public static File createNewFile(Context context, String dirName) {
-        File topDir = new File(context.getFilesDir(), dirName);
-        topDir.mkdir();
-        String[] list = topDir.list();
-
-        String newFileName;
-        while (true) {
-            newFileName = Long.toString(mFileId);
-            boolean fileExist = false;
-            for (String child : list) {
-                if (child.equals(newFileName)) {
-                    fileExist = true;
-                    break;
-                }
-            }
-            if (!fileExist) {
-                break;
-            }
-            mFileId++;
-        }
-        mFileId++;
-        //Log.i(TAG, "filename" + Long.toString(mFileId));
-        return new File(topDir, newFileName);
-    }
-
-    /**
-     * create multiple new files
-     * @param context
-     * @param dirName
-     * @param count number of files to create
-     * @return
-     */
-    public static File[] createNewFiles(Context context, String dirName, int count) {
-        File[] files = new File[count];
-        for (int i = 0; i < count; i++) {
-            files[i] = createNewFile(context, dirName);
-        }
-        return files;
-    }
-
-    /**
-     * write file with given byte array
-     * @param file
-     * @param data
-     * @param append will append if set true. Otherwise, write from beginning
-     * @throws IOException
-     */
-    public static void writeFile(File file, byte[] data, boolean append) throws IOException {
-        final RandomAccessFile randomFile = new RandomAccessFile(file, "rwd"); // force O_SYNC
-        if (append) {
-            randomFile.seek(randomFile.length());
-        } else {
-            randomFile.seek(0L);
-        }
-        randomFile.write(data);
-        randomFile.close();
-    }
-
-    /**
-     * create a new file with given length.
-     * @param context
-     * @param dirName
-     * @param length
-     * @return
-     * @throws IOException
-     */
-    public static File createNewFilledFile(Context context, String dirName, long length)
-            throws IOException {
-        final int BUFFER_SIZE = 10 * 1024 * 1024;
-        File file = createNewFile(context, dirName);
-        FileOutputStream out = new FileOutputStream(file);
-        byte[] data = generateRandomData(BUFFER_SIZE);
-        long written = 0;
-        while (written < length) {
-            out.write(data);
-            written += BUFFER_SIZE;
-        }
-        out.flush();
-        out.close();
-        return file;
-    }
-
-    /**
-     * remove given file or directory under the current app's files dir.
-     * @param context
-     * @param name
-     */
-    public static void removeFileOrDir(Context context, String name) {
-        File entry = new File(context.getFilesDir(), name);
-        if (entry.exists()) {
-            removeEntry(entry);
-        }
-    }
-
-    private static void removeEntry(File entry) {
-        if (entry.isDirectory()) {
-            String[] children = entry.list();
-            for (String child : children) {
-                removeEntry(new File(entry, child));
-            }
-        }
-        Log.i(TAG, "delete file " + entry.getAbsolutePath());
-        entry.delete();
-    }
-
-    /**
-     * measure time taken for each IO run with amount R/W
-     * @param count
-     * @param run
-     * @param readAmount returns amount of read in bytes for each interval.
-     *        Value will not be written if /proc/self/io does not exist.
-     * @param writeAmount returns amount of write in bytes for each interval.
-     * @return time per each interval
-     * @throws IOException
-     */
-    public static double[] measureIO(int count, double[] readAmount, double[] writeAmount,
-            MeasureRun run)  throws Exception {
-        double[] result = new double[count];
-        File procIo = new File("/proc/self/io");
-        boolean measureIo = procIo.exists() && procIo.canRead();
-        long prev = System.currentTimeMillis();
-        RWAmount prevAmount = new RWAmount();
-        if (measureIo) {
-            prevAmount = getRWAmount(procIo);
-        }
-        for (int i = 0; i < count; i++) {
-            run.run(i);
-            long current =  System.currentTimeMillis();
-            result[i] = current - prev;
-            prev = current;
-            if (measureIo) {
-                RWAmount currentAmount = getRWAmount(procIo);
-                readAmount[i] = currentAmount.mRd - prevAmount.mRd;
-                writeAmount[i] = currentAmount.mWr - prevAmount.mWr;
-                prevAmount = currentAmount;
-            }
-        }
-        return result;
-    }
-
-    private static class RWAmount {
-        public double mRd = 0.0;
-        public double mWr = 0.0;
-    };
-
-    private static RWAmount getRWAmount(File file) throws IOException {
-        RWAmount amount = new RWAmount();
-
-        BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
-        String line;
-        while((line = br.readLine())!= null) {
-            if (line.startsWith("read_bytes")) {
-                amount.mRd = Double.parseDouble(line.split(" ")[1]);
-            } else if (line.startsWith("write_bytes")) {
-                amount.mWr = Double.parseDouble(line.split(" ")[1]);
-            }
-        }
-        br.close();
-        return amount;
-    }
-
-    /**
-     * get file size exceeding total memory size ( 2x total memory).
-     * The size is rounded in bufferSize. And the size will be bigger than 400MB.
-     * @param context
-     * @param bufferSize
-     * @return file size or 0 if there is not enough space.
-     */
-    public static long getFileSizeExceedingMemory(Context context, int bufferSize) {
-        long freeDisk = SystemUtil.getFreeDiskSize(context);
-        long memSize = SystemUtil.getTotalMemory(context);
-        long diskSizeTarget = (2 * memSize / bufferSize) * bufferSize;
-        final long minimumDiskSize = (512L * 1024L * 1024L / bufferSize) * bufferSize;
-        final long reservedDiskSize = (50L * 1024L * 1024L / bufferSize) * bufferSize;
-        if ( diskSizeTarget < minimumDiskSize ) {
-            diskSizeTarget = minimumDiskSize;
-        }
-        if (diskSizeTarget > freeDisk) {
-            Log.i(TAG, "Free disk size " + freeDisk + " too small");
-            return 0;
-        }
-        if ((freeDisk - diskSizeTarget) < reservedDiskSize) {
-            diskSizeTarget -= reservedDiskSize;
-        }
-        return diskSizeTarget;
-    }
-
-    /**
-     *
-     * @param context
-     * @param dirName
-     * @param report
-     * @param fileSize
-     * @param bufferSize should be power of two
-     * @throws IOException
-     */
-    public static void doRandomReadTest(Context context, String dirName, ReportLog report,
-            long fileSize, int bufferSize) throws Exception {
-        File file = FileUtil.createNewFilledFile(context,
-                dirName, fileSize);
-
-        final byte[] data = FileUtil.generateRandomData(bufferSize);
-        Random random = new Random(0);
-        final int totalReadCount = (int)(fileSize / bufferSize);
-        final int[] readOffsets = new int[totalReadCount];
-        for (int i = 0; i < totalReadCount; i++) {
-            // align in buffer size
-            readOffsets[i] = (int)(random.nextFloat() * (fileSize - bufferSize)) &
-                    ~(bufferSize - 1);
-        }
-        final int runsInOneGo = 16;
-        final int readsInOneMeasure = totalReadCount / runsInOneGo;
-
-        final RandomAccessFile randomFile = new RandomAccessFile(file, "rw"); // do not need O_SYNC
-        double[] rdAmount = new double[runsInOneGo];
-        double[] wrAmount = new double[runsInOneGo];
-        double[] times = FileUtil.measureIO(runsInOneGo, rdAmount, wrAmount, new MeasureRun() {
-
-            @Override
-            public void run(int i) throws IOException {
-                Log.i(TAG, "starting " + i + " -th round");
-                int start = i * readsInOneMeasure;
-                int end = (i + 1) * readsInOneMeasure;
-                for (int j = start; j < end; j++) {
-                    randomFile.seek(readOffsets[j]);
-                    randomFile.read(data);
-                }
-            }
-        });
-        randomFile.close();
-        double[] mbps = ReportLog.calcRatePerSecArray((double)fileSize / runsInOneGo / 1024 / 1024,
-                times);
-        report.printArray("read throughput",
-                mbps, ResultType.HIGHER_BETTER, ResultUnit.MBPS);
-        // This is just the amount of IO returned from kernel. So this is performance neutral.
-        report.printArray("read amount", rdAmount, ResultType.NEUTRAL, ResultUnit.BYTE);
-        Stat.StatResult stat = Stat.getStat(mbps);
-
-        report.printSummary("read throughput", stat.mAverage, ResultType.HIGHER_BETTER,
-                ResultUnit.MBPS);
-    }
-
-    /**
-     *
-     * @param context
-     * @param dirName
-     * @param report
-     * @param fileSize
-     * @param bufferSize should be power of two
-     * @throws IOException
-     */
-    public static void doRandomWriteTest(Context context, String dirName, ReportLog report,
-            long fileSize, int bufferSize) throws Exception {
-        File file = FileUtil.createNewFilledFile(context,
-                dirName, fileSize);
-        final byte[] data = FileUtil.generateRandomData(bufferSize);
-        Random random = new Random(0);
-        final int totalWriteCount = (int)(fileSize / bufferSize);
-        final int[] writeOffsets = new int[totalWriteCount];
-        for (int i = 0; i < totalWriteCount; i++) {
-            writeOffsets[i] = (int)(random.nextFloat() * (fileSize - bufferSize)) &
-                    ~(bufferSize - 1);
-        }
-        final int runsInOneGo = 16;
-        final int writesInOneMeasure = totalWriteCount / runsInOneGo;
-
-        final RandomAccessFile randomFile = new RandomAccessFile(file, "rwd"); // force O_SYNC
-        double[] rdAmount = new double[runsInOneGo];
-        double[] wrAmount = new double[runsInOneGo];
-        double[] times = FileUtil.measureIO(runsInOneGo, rdAmount, wrAmount, new MeasureRun() {
-
-            @Override
-            public void run(int i) throws IOException {
-                Log.i(TAG, "starting " + i + " -th round");
-                int start = i * writesInOneMeasure;
-                int end = (i + 1) * writesInOneMeasure;
-                for (int j = start; j < end; j++) {
-                    randomFile.seek(writeOffsets[j]);
-                    randomFile.write(data);
-                }
-            }
-        });
-        randomFile.close();
-        double[] mbps = ReportLog.calcRatePerSecArray((double)fileSize / runsInOneGo / 1024 / 1024,
-                times);
-        report.printArray("write throughput",
-                mbps, ResultType.HIGHER_BETTER, ResultUnit.MBPS);
-        report.printArray("write amount", wrAmount, ResultType.NEUTRAL,
-                ResultUnit.BYTE);
-        Stat.StatResult stat = Stat.getStat(mbps);
-
-        report.printSummary("write throughput", stat.mAverage, ResultType.HIGHER_BETTER,
-                ResultUnit.MBPS);
-    }
-
-    /**
-     *
-     * @param context
-     * @param dirName
-     * @param report
-     * @param fileSize fileSize should be multiple of bufferSize.
-     * @param bufferSize
-     * @param numberRepetition
-     * @throws IOException
-     */
-    public static void doSequentialUpdateTest(Context context, String dirName, ReportLog report,
-            long fileSize, int bufferSize, int numberRepetition) throws Exception {
-        File file = FileUtil.createNewFilledFile(context,
-                dirName, fileSize);
-        final byte[] data = FileUtil.generateRandomData(bufferSize);
-        int numberRepeatInOneRun = (int)(fileSize / bufferSize);
-        double[] mbpsAll = new double[numberRepetition * numberRepeatInOneRun];
-        for (int i = 0; i < numberRepetition; i++) {
-            Log.i(TAG, "starting " + i + " -th round");
-            final RandomAccessFile randomFile = new RandomAccessFile(file, "rwd");  // force O_SYNC
-            randomFile.seek(0L);
-            double[] times = MeasureTime.measure(numberRepeatInOneRun, new MeasureRun() {
-
-                @Override
-                public void run(int i) throws IOException {
-                    randomFile.write(data);
-                }
-            });
-            randomFile.close();
-            double[] mbps = ReportLog.calcRatePerSecArray((double)bufferSize / 1024 / 1024,
-                    times);
-            report.printArray(i + "-th round throughput",
-                    mbps, ResultType.HIGHER_BETTER, ResultUnit.MBPS);
-            ReportLog.copyArray(mbps, mbpsAll, i * numberRepeatInOneRun);
-        }
-        Stat.StatResult stat = Stat.getStat(mbpsAll);
-        report.printSummary("update throughput", stat.mAverage, ResultType.HIGHER_BETTER,
-                ResultUnit.MBPS);
-    }
-}
diff --git a/suite/cts/deviceTests/filesystemperf/src/com/android/cts/filesystemperf/RandomRWTest.java b/suite/cts/deviceTests/filesystemperf/src/com/android/cts/filesystemperf/RandomRWTest.java
deleted file mode 100644
index 6ad927b..0000000
--- a/suite/cts/deviceTests/filesystemperf/src/com/android/cts/filesystemperf/RandomRWTest.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.filesystemperf;
-
-import android.cts.util.CtsAndroidTestCase;
-import com.android.cts.util.TimeoutReq;
-
-public class RandomRWTest extends CtsAndroidTestCase {
-    private static final String DIR_RANDOM_WR = "RANDOM_WR";
-    private static final String DIR_RANDOM_RD = "RANDOM_RD";
-
-    @Override
-    protected void tearDown() throws Exception {
-        FileUtil.removeFileOrDir(getContext(), DIR_RANDOM_WR);
-        FileUtil.removeFileOrDir(getContext(), DIR_RANDOM_RD);
-        super.tearDown();
-    }
-
-    @TimeoutReq(minutes = 60)
-    public void testRandomRead() throws Exception {
-        final int READ_BUFFER_SIZE = 4 * 1024;
-        final long fileSize = FileUtil.getFileSizeExceedingMemory(getContext(), READ_BUFFER_SIZE);
-        if (fileSize == 0) { // not enough space, give up
-            return;
-        }
-        FileUtil.doRandomReadTest(getContext(), DIR_RANDOM_RD, getReportLog(), fileSize,
-                READ_BUFFER_SIZE);
-    }
-
-    // It is taking too long in some device, and thus cannot run multiple times
-    @TimeoutReq(minutes = 60)
-    public void testRandomUpdate() throws Exception {
-        final int WRITE_BUFFER_SIZE = 4 * 1024;
-        final long fileSize = 256 * 1024 * 1024;
-        FileUtil.doRandomWriteTest(getContext(), DIR_RANDOM_WR, getReportLog(), fileSize,
-                WRITE_BUFFER_SIZE);
-    }
-}
diff --git a/suite/cts/deviceTests/filesystemperf/src/com/android/cts/filesystemperf/SequentialRWTest.java b/suite/cts/deviceTests/filesystemperf/src/com/android/cts/filesystemperf/SequentialRWTest.java
deleted file mode 100644
index d369ce8..0000000
--- a/suite/cts/deviceTests/filesystemperf/src/com/android/cts/filesystemperf/SequentialRWTest.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.filesystemperf;
-
-import android.cts.util.CtsAndroidTestCase;
-import com.android.cts.util.MeasureRun;
-import com.android.cts.util.MeasureTime;
-import com.android.cts.util.ResultType;
-import com.android.cts.util.ResultUnit;
-import com.android.cts.util.ReportLog;
-import com.android.cts.util.Stat;
-import com.android.cts.util.TimeoutReq;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-
-public class SequentialRWTest extends CtsAndroidTestCase {
-    private static final String DIR_SEQ_WR = "SEQ_WR";
-    private static final String DIR_SEQ_UPDATE = "SEQ_UPDATE";
-    private static final String DIR_SEQ_RD = "SEQ_RD";
-    private static final int BUFFER_SIZE = 10 * 1024 * 1024;
-
-    @Override
-    protected void tearDown() throws Exception {
-        FileUtil.removeFileOrDir(getContext(), DIR_SEQ_WR);
-        FileUtil.removeFileOrDir(getContext(), DIR_SEQ_UPDATE);
-        FileUtil.removeFileOrDir(getContext(), DIR_SEQ_RD);
-        super.tearDown();
-    }
-
-    @TimeoutReq(minutes = 30)
-    public void testSingleSequentialWrite() throws Exception {
-        final long fileSize = FileUtil.getFileSizeExceedingMemory(getContext(), BUFFER_SIZE);
-        if (fileSize == 0) { // not enough space, give up
-            return;
-        }
-        final int numberOfFiles =(int)(fileSize / BUFFER_SIZE);
-        getReportLog().printValue("files", numberOfFiles, ResultType.NEUTRAL,
-                ResultUnit.COUNT);
-        final byte[] data = FileUtil.generateRandomData(BUFFER_SIZE);
-        final File[] files = FileUtil.createNewFiles(getContext(), DIR_SEQ_WR,
-                numberOfFiles);
-        double[] rdAmount = new double[numberOfFiles];
-        double[] wrAmount = new double[numberOfFiles];
-        double[] times = FileUtil.measureIO(numberOfFiles, rdAmount, wrAmount, new MeasureRun() {
-
-            @Override
-            public void run(int i) throws IOException {
-                FileUtil.writeFile(files[i], data, false);
-            }
-        });
-        double[] mbps = ReportLog.calcRatePerSecArray((double)BUFFER_SIZE / 1024 / 1024, times);
-        getReportLog().printArray("write throughput",
-                mbps, ResultType.HIGHER_BETTER, ResultUnit.MBPS);
-        getReportLog().printArray("write amount", wrAmount, ResultType.NEUTRAL,
-                ResultUnit.BYTE);
-        Stat.StatResult stat = Stat.getStat(mbps);
-        getReportLog().printSummary("write throughput", stat.mAverage, ResultType.HIGHER_BETTER,
-                ResultUnit.MBPS);
-    }
-
-    @TimeoutReq(minutes = 60)
-    public void testSingleSequentialUpdate() throws Exception {
-        final long fileSize = FileUtil.getFileSizeExceedingMemory(getContext(), BUFFER_SIZE);
-        if (fileSize == 0) { // not enough space, give up
-            return;
-        }
-        final int NUMBER_REPETITION = 6;
-        FileUtil.doSequentialUpdateTest(getContext(), DIR_SEQ_UPDATE, getReportLog(), fileSize,
-                BUFFER_SIZE, NUMBER_REPETITION);
-    }
-
-    @TimeoutReq(minutes = 30)
-    public void testSingleSequentialRead() throws Exception {
-        final long fileSize = FileUtil.getFileSizeExceedingMemory(getContext(), BUFFER_SIZE);
-        if (fileSize == 0) { // not enough space, give up
-            return;
-        }
-        long start = System.currentTimeMillis();
-        final File file = FileUtil.createNewFilledFile(getContext(),
-                DIR_SEQ_RD, fileSize);
-        long finish = System.currentTimeMillis();
-        getReportLog().printValue("write throughput for test file of length " + fileSize,
-                ReportLog.calcRatePerSec((double)fileSize / 1024 / 1024, finish - start),
-                ResultType.HIGHER_BETTER, ResultUnit.MBPS);
-
-        final int NUMBER_READ = 10;
-
-        final byte[] data = new byte[BUFFER_SIZE];
-        double[] times = MeasureTime.measure(NUMBER_READ, new MeasureRun() {
-
-            @Override
-            public void run(int i) throws IOException {
-                final FileInputStream in = new FileInputStream(file);
-                long read = 0;
-                while (read < fileSize) {
-                    in.read(data);
-                    read += BUFFER_SIZE;
-                }
-                in.close();
-            }
-        });
-        double[] mbps = ReportLog.calcRatePerSecArray((double)fileSize / 1024 / 1024, times);
-        getReportLog().printArray("read throughput",
-                mbps, ResultType.HIGHER_BETTER, ResultUnit.MBPS);
-        Stat.StatResult stat = Stat.getStat(mbps);
-        getReportLog().printSummary("read throughput", stat.mAverage, ResultType.HIGHER_BETTER,
-                ResultUnit.MBPS);
-    }
-}
diff --git a/suite/cts/deviceTests/filesystemperf/src/com/android/cts/filesystemperf/TestTest.java b/suite/cts/deviceTests/filesystemperf/src/com/android/cts/filesystemperf/TestTest.java
deleted file mode 100644
index 052c054..0000000
--- a/suite/cts/deviceTests/filesystemperf/src/com/android/cts/filesystemperf/TestTest.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-// code for testing, will be removed / moved before release
-
-package com.android.cts.filesystemperf;
-
-import android.cts.util.CtsAndroidTestCase;
-
-/**
- * This class is for testing CTS logging. Will be disabled in release.
- *
- */
-public class TestTest extends CtsAndroidTestCase {
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-    }
-/* code for testing CTS logging. Disabled.
-    @TimeoutReq(minutes = 15)
-    public void testPass() {
-        double[] array = new double[] {1.0, 2.0, 3.0};
-        getReportLog().printArray(" ", array, true);
-        getReportLog().printArray(" ", array, false);
-        getReportLog().printValue(" ", 1.0);
-        getReportLog().printValue(" ", 2.0);
-        getReportLog().printSummary("This should be shown", 0, 0);
-    }
-
-    @TimeoutReq(minutes = 10)
-    public void testFail() throws Exception {
-        getReportLog().printValue(" ", 1.0);
-        getReportLog().printValue(" ", 2.0);
-        getReportLog().printSummary("This should not be shown", 0, 0);
-        throw new Exception("failed");
-    }
-*/
-}
diff --git a/suite/cts/deviceTests/jank2/Android.mk b/suite/cts/deviceTests/jank2/Android.mk
deleted file mode 100644
index 346297e..0000000
--- a/suite/cts/deviceTests/jank2/Android.mk
+++ /dev/null
@@ -1,29 +0,0 @@
-# Copyright (C) 2015 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_PACKAGE_NAME := CtsJankTestCases
-
-LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctstestrunner ub-uiautomator ub-janktesthelper
-
-include $(BUILD_CTS_PACKAGE)
diff --git a/suite/cts/deviceTests/jank2/AndroidManifest.xml b/suite/cts/deviceTests/jank2/AndroidManifest.xml
deleted file mode 100644
index a4c8337..0000000
--- a/suite/cts/deviceTests/jank2/AndroidManifest.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-        package="android.cts.jank">
-
-  <application>
-      <uses-library android:name="android.test.runner"/>
-  </application>
-
-  <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                   android:targetPackage="android.cts.jank"
-                   android:label="Jank tests">
-        <meta-data android:name="listener"
-            android:value="com.android.cts.runner.CtsTestRunListener" />
-    </instrumentation>
-
-</manifest>
diff --git a/suite/cts/deviceTests/jank2/AndroidTest.xml b/suite/cts/deviceTests/jank2/AndroidTest.xml
deleted file mode 100644
index 2fbbac7..0000000
--- a/suite/cts/deviceTests/jank2/AndroidTest.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<configuration description="CTS Jank test config">
-    <include name="common-config" />
-    <option name="cts-apk-installer:test-file-name" value="CtsDeviceUi.apk" />
-</configuration>
diff --git a/suite/cts/deviceTests/jank2/src/android/cts/jank/CtsJankTestBase.java b/suite/cts/deviceTests/jank2/src/android/cts/jank/CtsJankTestBase.java
deleted file mode 100644
index cb5c122..0000000
--- a/suite/cts/deviceTests/jank2/src/android/cts/jank/CtsJankTestBase.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.cts.jank;
-
-import android.cts.util.DeviceReportLog;
-import android.os.Bundle;
-import android.support.test.jank.JankTestBase;
-import android.support.test.jank.WindowContentFrameStatsMonitor;
-import android.support.test.uiautomator.UiDevice;
-
-import com.android.cts.util.ResultType;
-import com.android.cts.util.ResultUnit;
-
-public abstract class CtsJankTestBase extends JankTestBase {
-
-    private UiDevice mDevice;
-    private DeviceReportLog mLog;
-
-    @Override
-    public void afterTest(Bundle metrics) {
-        String source = String.format("%s#%s", getClass().getCanonicalName(), getName());
-        mLog.printValue(source, WindowContentFrameStatsMonitor.KEY_AVG_FPS,
-                metrics.getDouble(WindowContentFrameStatsMonitor.KEY_AVG_FPS),
-                ResultType.HIGHER_BETTER, ResultUnit.FPS);
-        mLog.printValue(source, WindowContentFrameStatsMonitor.KEY_AVG_LONGEST_FRAME,
-                metrics.getDouble(WindowContentFrameStatsMonitor.KEY_AVG_LONGEST_FRAME),
-                ResultType.LOWER_BETTER, ResultUnit.MS);
-        mLog.printValue(source, WindowContentFrameStatsMonitor.KEY_MAX_NUM_JANKY,
-                metrics.getInt(WindowContentFrameStatsMonitor.KEY_MAX_NUM_JANKY),
-                ResultType.LOWER_BETTER, ResultUnit.COUNT);
-        mLog.printSummary(WindowContentFrameStatsMonitor.KEY_AVG_NUM_JANKY,
-                metrics.getDouble(WindowContentFrameStatsMonitor.KEY_AVG_NUM_JANKY),
-                ResultType.LOWER_BETTER, ResultUnit.COUNT);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mLog = new DeviceReportLog();
-        // fix device orientation
-        mDevice = UiDevice.getInstance(getInstrumentation());
-        mDevice.setOrientationNatural();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        mLog.deliverReportToHost(getInstrumentation());
-        // restore device orientation
-        mDevice.unfreezeRotation();
-        super.tearDown();
-    }
-
-    protected UiDevice getUiDevice() {
-        return mDevice;
-    }
-}
diff --git a/suite/cts/deviceTests/jank2/src/android/cts/jank/ui/CtsDeviceJankUi.java b/suite/cts/deviceTests/jank2/src/android/cts/jank/ui/CtsDeviceJankUi.java
deleted file mode 100644
index 884f83c..0000000
--- a/suite/cts/deviceTests/jank2/src/android/cts/jank/ui/CtsDeviceJankUi.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 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.cts.jank.ui;
-
-import android.content.ComponentName;
-import android.content.Intent;
-import android.cts.jank.CtsJankTestBase;
-import android.os.SystemClock;
-import android.support.test.jank.JankTest;
-import android.support.test.jank.WindowContentFrameStatsMonitor;
-import android.support.test.uiautomator.By;
-import android.support.test.uiautomator.Direction;
-import android.support.test.uiautomator.Until;
-import android.widget.ListView;
-
-import java.io.IOException;
-
-public class CtsDeviceJankUi extends CtsJankTestBase {
-    private final static int NUM_ELEMENTS = 1000;
-    private static final long DEFAULT_ANIMATION_TIME = 2 * 1000;
-    private static final long POST_SCROLL_IDLE_TIME = 2 *1000;
-    private final static String PACKAGE = "com.android.cts.ui";
-    private final static String CLASS = PACKAGE + ".ScrollingActivity";
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        // launch the activity as part of the set up
-        Intent intent = new Intent(Intent.ACTION_MAIN);
-        intent.setComponent(new ComponentName(PACKAGE, CLASS));
-        intent.putExtra("num_elements", NUM_ELEMENTS);
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        getInstrumentation().getTargetContext().startActivity(intent);
-        getUiDevice().wait(Until.hasObject(By.pkg(PACKAGE)), DEFAULT_ANIMATION_TIME);
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        getUiDevice().pressHome();
-        super.tearDown();
-    }
-
-    @JankTest(expectedFrames=50, defaultIterationCount=5)
-    @WindowContentFrameStatsMonitor
-    public void testScrolling() throws IOException {
-        getUiDevice().findObject(By.clazz(ListView.class)).fling(Direction.DOWN);
-        SystemClock.sleep(POST_SCROLL_IDLE_TIME);
-    }
-}
diff --git a/suite/cts/deviceTests/opengl/Android.mk b/suite/cts/deviceTests/opengl/Android.mk
deleted file mode 100644
index 0708efb..0000000
--- a/suite/cts/deviceTests/opengl/Android.mk
+++ /dev/null
@@ -1,36 +0,0 @@
-# Copyright (C) 2013 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-# don't include this package in any target
-LOCAL_MODULE_TAGS := tests
-
-# Include both the 32 and 64 bit versions
-LOCAL_MULTILIB := both
-
-LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctstestrunner
-
-LOCAL_JNI_SHARED_LIBRARIES := libctsopengl_jni
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_PACKAGE_NAME := CtsDeviceOpenGl
-
-LOCAL_SDK_VERSION := 16
-
-include $(BUILD_CTS_PACKAGE)
-
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/suite/cts/deviceTests/opengl/AndroidManifest.xml b/suite/cts/deviceTests/opengl/AndroidManifest.xml
deleted file mode 100644
index 05fb5be..0000000
--- a/suite/cts/deviceTests/opengl/AndroidManifest.xml
+++ /dev/null
@@ -1,53 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.opengl"
-    android:versionCode="1"
-    android:versionName="1.0" >
-
-    <uses-sdk
-        android:minSdkVersion="16"
-        android:targetSdkVersion="17" />
-
-    <uses-feature
-        android:glEsVersion="0x00020000"
-        android:required="true" />
-
-    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
-    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
-
-    <application android:allowBackup="false" >
-        <uses-library android:name="android.test.runner" />
-
-        <activity
-            android:name=".primitive.GLPrimitiveActivity"
-            android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode"
-            android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-        <activity
-            android:name=".reference.GLReferenceActivity"
-            android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode"
-            android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-        <activity
-            android:name=".reference.GLGameActivity"
-            android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode"
-            android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >
-        </activity>
-    </application>
-
-    <instrumentation
-        android:name="android.support.test.runner.AndroidJUnitRunner"
-        android:label="OpenGL ES 2.0 Benchmark"
-        android:targetPackage="com.android.cts.opengl" />
-
-</manifest>
\ No newline at end of file
diff --git a/suite/cts/deviceTests/opengl/jni/Android.mk b/suite/cts/deviceTests/opengl/jni/Android.mk
deleted file mode 100644
index 7b58170..0000000
--- a/suite/cts/deviceTests/opengl/jni/Android.mk
+++ /dev/null
@@ -1,34 +0,0 @@
-# Copyright (C) 2013 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libctsopengl_jni
-
-LOCAL_MODULE_TAGS := optional
-
-# Needed in order to use fences for synchronization
-LOCAL_CFLAGS += -DEGL_EGLEXT_PROTOTYPES -funsigned-char
-
-# Get all cpp files but not hidden files
-LOCAL_SRC_FILES := $(patsubst ./%,%, $(shell cd $(LOCAL_PATH); \
-		  find . -name "*.cpp" -and -not -name ".*"))
-
-LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
-
-LOCAL_SHARED_LIBRARIES := libEGL libGLESv2 libandroid libutils libcutils liblog
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/suite/cts/deviceTests/opengl/jni/graphics/GLUtils.cpp b/suite/cts/deviceTests/opengl/jni/graphics/GLUtils.cpp
deleted file mode 100644
index ea166a1..0000000
--- a/suite/cts/deviceTests/opengl/jni/graphics/GLUtils.cpp
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-
-#include "GLUtils.h"
-#include <stdlib.h>
-#include <sys/time.h>
-
-#include <android/asset_manager_jni.h>
-
-#define LOG_TAG "CTS_OPENGL"
-#define LOG_NDEBUG 0
-#include <utils/Log.h>
-
-static JNIEnv* sEnv = NULL;
-static jobject sAssetManager = NULL;
-
-void GLUtils::setEnvAndAssetManager(JNIEnv* env, jobject assetManager) {
-    sEnv = env;
-    sAssetManager = assetManager;
-}
-
-static AAsset* loadAsset(const char* path) {
-    AAssetManager* nativeManager = AAssetManager_fromJava(sEnv, sAssetManager);
-    if (nativeManager == NULL) {
-        return NULL;
-    }
-    return AAssetManager_open(nativeManager, path, AASSET_MODE_UNKNOWN);;
-}
-
-char* GLUtils::openTextFile(const char* path) {
-    AAsset* asset = loadAsset(path);
-    if (asset == NULL) {
-        ALOGE("Couldn't load %s", path);
-        return NULL;
-    }
-    off_t length = AAsset_getLength(asset);
-    char* buffer = new char[length + 1];
-    int num = AAsset_read(asset, buffer, length);
-    AAsset_close(asset);
-    if (num != length) {
-        ALOGE("Couldn't read %s", path);
-        delete[] buffer;
-        return NULL;
-    }
-    buffer[length] = '\0';
-    return buffer;
-}
-
-GLuint GLUtils::loadTexture(const char* path) {
-    GLuint textureId = 0;
-    jclass activityClass = sEnv->FindClass("com/android/cts/opengl/reference/GLGameActivity");
-    if (activityClass == NULL) {
-        ALOGE("Couldn't find activity class");
-        return -1;
-    }
-    jmethodID loadTexture = sEnv->GetStaticMethodID(activityClass, "loadTexture",
-            "(Landroid/content/res/AssetManager;Ljava/lang/String;)I");
-    if (loadTexture == NULL) {
-        ALOGE("Couldn't find loadTexture method");
-        return -1;
-    }
-    jstring pathStr = sEnv->NewStringUTF(path);
-    textureId = sEnv->CallStaticIntMethod(activityClass, loadTexture, sAssetManager, pathStr);
-    sEnv->DeleteLocalRef(pathStr);
-    return textureId;
-}
-
-static int readInt(char* b) {
-    unsigned char* ub = (unsigned char*) b;
-    return (((int) ub[0]) << 24) | (((int) ub[1]) << 16) | (((int) ub[2]) << 8) | ((int) ub[3]);
-}
-
-static float readFloat(char* b) {
-    union {
-        int input;
-        float output;
-    } data;
-    data.input = readInt(b);
-    return data.output;
-}
-
-Mesh* GLUtils::loadMesh(const char* path) {
-    char* buffer = openTextFile(path);
-    if (buffer == NULL) {
-        return NULL;
-    }
-    int index = 0;
-    int numVertices = readInt(buffer + index);
-    index += 4;
-    float* vertices = new float[numVertices * 3];
-    float* normals = new float[numVertices * 3];
-    float* texCoords = new float[numVertices * 2];
-    for (int i = 0; i < numVertices; i++) {
-        // Vertices
-        int vIndex = i * 3;
-        vertices[vIndex + 0] = readFloat(buffer + index);
-        index += 4;
-        vertices[vIndex + 1] = readFloat(buffer + index);
-        index += 4;
-        vertices[vIndex + 2] = readFloat(buffer + index);
-        index += 4;
-        // Normals
-        normals[vIndex + 0] = readFloat(buffer + index);
-        index += 4;
-        normals[vIndex + 1] = readFloat(buffer + index);
-        index += 4;
-        normals[vIndex + 2] = readFloat(buffer + index);
-        index += 4;
-        // Texture Coordinates
-        int tIndex = i * 2;
-        texCoords[tIndex + 0] = readFloat(buffer + index);
-        index += 4;
-        texCoords[tIndex + 1] = readFloat(buffer + index);
-        index += 4;
-    }
-    return new Mesh(vertices, normals, texCoords, numVertices);
-}
-
-// Loads the given source code as a shader of the given type.
-static GLuint loadShader(GLenum shaderType, const char** source) {
-    GLuint shader = glCreateShader(shaderType);
-    if (shader) {
-        glShaderSource(shader, 1, source, NULL);
-        glCompileShader(shader);
-        GLint compiled = 0;
-        glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
-        if (!compiled) {
-            GLint infoLen = 0;
-            glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
-            if (infoLen > 0) {
-                char* infoLog = (char*) malloc(sizeof(char) * infoLen);
-                glGetShaderInfoLog(shader, infoLen, NULL, infoLog);
-                ALOGE("Error compiling shader:\n%s\n", infoLog);
-                free(infoLog);
-            }
-            glDeleteShader(shader);
-            shader = 0;
-        }
-    }
-    return shader;
-}
-
-GLuint GLUtils::createProgram(const char** vertexSource, const char** fragmentSource) {
-    GLuint vertexShader = loadShader(GL_VERTEX_SHADER, vertexSource);
-    if (!vertexShader) {
-        return 0;
-    }
-
-    GLuint fragmentShader = loadShader(GL_FRAGMENT_SHADER, fragmentSource);
-    if (!fragmentShader) {
-        return 0;
-    }
-
-    GLuint program = glCreateProgram();
-    if (program) {
-        glAttachShader(program, vertexShader);
-        glAttachShader(program, fragmentShader);
-
-        GLint linkStatus;
-        glLinkProgram(program);
-        glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
-
-        if (!linkStatus) {
-            GLint infoLen = 0;
-            glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLen);
-            if (infoLen > 0) {
-                char* infoLog = (char*) malloc(sizeof(char) * infoLen);
-                glGetProgramInfoLog(program, infoLen, NULL, infoLog);
-                ALOGE("Error linking program:\n%s\n", infoLog);
-                free(infoLog);
-            }
-            glDeleteProgram(program);
-            program = 0;
-        }
-    }
-    return program;
-}
-
-double GLUtils::currentTimeMillis() {
-    struct timeval tv;
-    gettimeofday(&tv, (struct timezone *) NULL);
-    return tv.tv_sec * 1000.0 + tv.tv_usec / 1000.0;
-}
-
-// Rounds a number up to the smallest power of 2 that is greater than or equal to x.
-int GLUtils::roundUpToSmallestPowerOf2(int x) {
-    if (x < 0) {
-        return 0;
-    }
-    --x;
-    x |= x >> 1;
-    x |= x >> 2;
-    x |= x >> 4;
-    x |= x >> 8;
-    x |= x >> 16;
-    return x + 1;
-}
-
-GLuint GLUtils::genTexture(int texWidth, int texHeight, int fill) {
-    GLuint textureId = 0;
-    int w = roundUpToSmallestPowerOf2(texWidth);
-    int h = roundUpToSmallestPowerOf2(texHeight);
-    uint32_t* m = new uint32_t[w * h];
-    if (m != NULL) {
-        uint32_t* d = m;
-        for (int y = 0; y < h; y++) {
-            for (int x = 0; x < w; x++) {
-                if (fill == RANDOM_FILL) {
-                    *d = 0xff000000 | ((y & 0xff) << 16) | ((x & 0xff) << 8) | ((x + y) & 0xff);
-                } else {
-                    *d = 0xff000000 | fill;
-                }
-                d++;
-            }
-        }
-        glGenTextures(1, &textureId);
-        glBindTexture(GL_TEXTURE_2D, textureId);
-        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, m);
-        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
-        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
-    }
-    delete[] m;
-    return textureId;
-}
diff --git a/suite/cts/deviceTests/opengl/jni/graphics/Matrix.cpp b/suite/cts/deviceTests/opengl/jni/graphics/Matrix.cpp
deleted file mode 100644
index 0097a5d..0000000
--- a/suite/cts/deviceTests/opengl/jni/graphics/Matrix.cpp
+++ /dev/null
@@ -1,328 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-
-#include "Matrix.h"
-#include <string.h>
-#include <cmath>
-
-#define LOG_TAG "CTS_OPENGL"
-#define LOG_NDEBUG 0
-#include "utils/Log.h"
-
-Matrix::Matrix() {
-    identity();
-}
-
-Matrix::Matrix(const Matrix& src) {
-    loadWith(src);
-}
-
-void Matrix::print(const char* label) {
-    ALOGI("%c", *label);
-    for (int i = 0; i < 4; i++) {
-        const float* d = &(mData[i * 4]);
-        ALOGI("%f %f %f %f\n", d[0], d[1], d[2], d[3]);
-    }
-}
-
-bool Matrix::equals(const Matrix& src) {
-    bool equals = true;
-    const float* d = src.mData;
-    for (int i = 0; i < MATRIX_SIZE && equals; i++) {
-        if (mData[i] != d[i]) {
-            equals = false;
-        }
-    }
-    return equals;
-}
-
-void Matrix::loadWith(const Matrix& src) {
-    memcpy(mData, src.mData, MATRIX_SIZE * sizeof(float));
-}
-
-void Matrix::identity() {
-    mData[0] = 1.0f;
-    mData[1] = 0.0f;
-    mData[2] = 0.0f;
-    mData[3] = 0.0f;
-
-    mData[4] = 0.0f;
-    mData[5] = 1.0f;
-    mData[6] = 0.0f;
-    mData[7] = 0.0f;
-
-    mData[8] = 0.0f;
-    mData[9] = 0.0f;
-    mData[10] = 1.0f;
-    mData[11] = 0.0f;
-
-    mData[12] = 0.0f;
-    mData[13] = 0.0f;
-    mData[14] = 0.0f;
-    mData[15] = 1.0f;
-}
-
-void Matrix::translate(float x, float y, float z) {
-    Matrix* m = newTranslate(x, y, z);
-    Matrix* temp = new Matrix(*this);
-    if (m != NULL && temp != NULL) {
-        multiply(*temp, *m);
-    }
-    delete m;
-    delete temp;
-}
-
-void Matrix::scale(float x, float y, float z) {
-    Matrix* m = newScale(x, y, z);
-    Matrix* temp = new Matrix(*this);
-    if (m != NULL && temp != NULL) {
-        multiply(*temp, *m);
-    }
-    delete m;
-    delete temp;
-}
-
-void Matrix::rotate(float radians, float x, float y, float z) {
-    Matrix* m = newRotate(radians, x, y, z);
-    Matrix* temp = new Matrix(*this);
-    if (m != NULL && temp != NULL) {
-        multiply(*temp, *m);
-    }
-    delete m;
-    delete temp;
-}
-
-void Matrix::multiply(const Matrix& l, const Matrix& r) {
-    float const* const lhs = l.mData;
-    float const* const rhs = r.mData;
-    for (int i = 0; i < 4; i++) {
-        const int i4 = i * 4;
-        float x = 0;
-        float y = 0;
-        float z = 0;
-        float w = 0;
-
-        for (int j = 0; j < 4; j++) {
-            const int j4 = j * 4;
-            const float e = rhs[i4 + j];
-            x += lhs[j4 + 0] * e;
-            y += lhs[j4 + 1] * e;
-            z += lhs[j4 + 2] * e;
-            w += lhs[j4 + 3] * e;
-        }
-
-        mData[i4 + 0] = x;
-        mData[i4 + 1] = y;
-        mData[i4 + 2] = z;
-        mData[i4 + 3] = w;
-    }
-}
-
-Matrix* Matrix::newLookAt(float eyeX, float eyeY, float eyeZ, float centerX,
-        float centerY, float centerZ, float upX, float upY, float upZ) {
-    Matrix* m = new Matrix();
-    if (m != NULL) {
-        // See the OpenGL GLUT documentation for gluLookAt for a description
-        // of the algorithm. We implement it in a straightforward way:
-
-        float fx = centerX - eyeX;
-        float fy = centerY - eyeY;
-        float fz = centerZ - eyeZ;
-
-        // Normalize f
-        float rlf = 1.0f / (float) sqrt(fx * fx + fy * fy + fz * fz);
-        fx *= rlf;
-        fy *= rlf;
-        fz *= rlf;
-
-        // compute s = f x up (x means "cross product")
-        float sx = fy * upZ - fz * upY;
-        float sy = fz * upX - fx * upZ;
-        float sz = fx * upY - fy * upX;
-
-        // and normalize s
-        float rls = 1.0f / (float) sqrt(sx * sx + sy * sy + sz * sz);
-        sx *= rls;
-        sy *= rls;
-        sz *= rls;
-
-        // compute u = s x f
-        float ux = sy * fz - sz * fy;
-        float uy = sz * fx - sx * fz;
-        float uz = sx * fy - sy * fx;
-
-        float* d = m->mData;
-        d[0] = sx;
-        d[1] = ux;
-        d[2] = -fx;
-        d[3] = 0.0f;
-
-        d[4] = sy;
-        d[5] = uy;
-        d[6] = -fy;
-        d[7] = 0.0f;
-
-        d[8] = sz;
-        d[9] = uz;
-        d[10] = -fz;
-        d[11] = 0.0f;
-
-        d[12] = 0.0f;
-        d[13] = 0.0f;
-        d[14] = 0.0f;
-        d[15] = 1.0f;
-
-        m->translate(-eyeX, -eyeY, -eyeZ);
-    }
-    return m;
-}
-
-Matrix* Matrix::newFrustum(float left, float right, float bottom, float top,
-        float near, float far) {
-    const float r_width = 1.0f / (right - left);
-    const float r_height = 1.0f / (top - bottom);
-    const float r_depth = 1.0f / (near - far);
-    const float x = 2.0f * (near * r_width);
-    const float y = 2.0f * (near * r_height);
-    const float A = (right + left) * r_width;
-    const float B = (top + bottom) * r_height;
-    const float C = (far + near) * r_depth;
-    const float D = 2.0f * (far * near * r_depth);
-    Matrix* m = new Matrix();
-    if (m != NULL) {
-        float* d = m->mData;
-        d[0] = x;
-        d[5] = y;
-        d[8] = A;
-        d[9] = B;
-        d[10] = C;
-        d[14] = D;
-        d[11] = -1.0f;
-        d[1] = 0.0f;
-        d[2] = 0.0f;
-        d[3] = 0.0f;
-        d[4] = 0.0f;
-        d[6] = 0.0f;
-        d[7] = 0.0f;
-        d[12] = 0.0f;
-        d[13] = 0.0f;
-        d[15] = 0.0f;
-    }
-    return m;
-}
-
-Matrix* Matrix::newTranslate(float x, float y, float z) {
-    Matrix* m = new Matrix();
-    if (m != NULL) {
-        float* d = m->mData;
-        d[12] = x;
-        d[13] = y;
-        d[14] = z;
-    }
-    return m;
-}
-Matrix* Matrix::newScale(float x, float y, float z) {
-    Matrix* m = new Matrix();
-    if (m != NULL) {
-        float* d = m->mData;
-        d[0] = x;
-        d[5] = y;
-        d[10] = z;
-    }
-    return m;
-}
-Matrix* Matrix::newRotate(float radians, float x, float y, float z) {
-    Matrix* m = new Matrix();
-    if (m != NULL) {
-        float* d = m->mData;
-        d[3] = 0;
-        d[7] = 0;
-        d[11] = 0;
-        d[12] = 0;
-        d[13] = 0;
-        d[14] = 0;
-        d[15] = 1;
-        float s = (float) sinf(radians);
-        float c = (float) cosf(radians);
-        if (1.0f == x && 0.0f == y && 0.0f == z) {
-            d[5] = c;
-            d[10] = c;
-            d[6] = s;
-            d[9] = -s;
-            d[1] = 0;
-            d[2] = 0;
-            d[4] = 0;
-            d[8] = 0;
-            d[0] = 1;
-        } else if (0.0f == x && 1.0f == y && 0.0f == z) {
-            d[0] = c;
-            d[10] = c;
-            d[8] = s;
-            d[2] = -s;
-            d[1] = 0;
-            d[4] = 0;
-            d[6] = 0;
-            d[9] = 0;
-            d[5] = 1;
-        } else if (0.0f == x && 0.0f == y && 1.0f == z) {
-            d[0] = c;
-            d[5] = c;
-            d[1] = s;
-            d[4] = -s;
-            d[2] = 0;
-            d[6] = 0;
-            d[8] = 0;
-            d[9] = 0;
-            d[10] = 1;
-        } else {
-            float len = sqrt((x * x) + (y * y) + (z * z));
-            if (1.0f != len) {
-                float recipLen = 1.0f / len;
-                x *= recipLen;
-                y *= recipLen;
-                z *= recipLen;
-            }
-            float nc = 1.0f - c;
-            float xy = x * y;
-            float yz = y * z;
-            float zx = z * x;
-            float xs = x * s;
-            float ys = y * s;
-            float zs = z * s;
-            d[0] = x * x * nc + c;
-            d[4] = xy * nc - zs;
-            d[8] = zx * nc + ys;
-            d[1] = xy * nc + zs;
-            d[5] = y * y * nc + c;
-            d[9] = yz * nc - xs;
-            d[2] = zx * nc - ys;
-            d[6] = yz * nc + xs;
-            d[10] = z * z * nc + c;
-        }
-    }
-    return m;
-}
-
-void Matrix::multiplyVector(float* result, const Matrix& lhs,
-        const float* rhs) {
-    const float* d = lhs.mData;
-    const float x = rhs[0];
-    const float y = rhs[1];
-    const float z = rhs[2];
-    const float w = rhs[3];
-    for (int i = 0; i < 4; i++) {
-        const int j = i * 4;
-        result[i] = d[j + 0] * x + d[j + 1] * y + d[j + 2] * z + d[j + 3] * w;
-    }
-}
diff --git a/suite/cts/deviceTests/opengl/jni/graphics/Renderer.cpp b/suite/cts/deviceTests/opengl/jni/graphics/Renderer.cpp
deleted file mode 100644
index 16504fd..0000000
--- a/suite/cts/deviceTests/opengl/jni/graphics/Renderer.cpp
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-#include "Renderer.h"
-#include <graphics/GLUtils.h>
-
-#define LOG_TAG "CTS_OPENGL"
-#define LOG_NDEBUG 0
-#include <utils/Log.h>
-
-#include <Trace.h>
-
-// Used to center the grid on the screen.
-#define CENTER_GRID(x) ((((x) * 2.0 + 1) - OFFSCREEN_GRID_SIZE) / OFFSCREEN_GRID_SIZE)
-// Leave a good error message if something fails.
-#define EGL_RESULT_CHECK(X) do { \
-                                   EGLint error = eglGetError(); \
-                                   if (!(X) || error != EGL_SUCCESS) { \
-                                       ALOGE("EGL error '%d' at %s:%d", error, __FILE__, __LINE__);\
-                                       return false; \
-                                    } \
-                            } while (0)
-
-static const int FBO_NUM_VERTICES = 6;
-
-static const float FBO_VERTICES[FBO_NUM_VERTICES * 3] = {
-        0.1f, 0.1f, -0.1f,
-        -0.1f, 0.1f, -0.1f,
-        -0.1f, -0.1f, -0.1f,
-        -0.1f, -0.1f, -0.1f,
-        0.1f, -0.1f, -0.1f,
-        0.1f, 0.1f, -0.1f };
-static const float FBO_TEX_COORDS[FBO_NUM_VERTICES * 2] = {
-        1.0f, 1.0f,
-        0.0f, 1.0f,
-        0.0f, 0.0f,
-        0.0f, 0.0f,
-        1.0f, 0.0f,
-        1.0f, 1.0f };
-
-static const char* FBO_VERTEX =
-        "attribute vec4 a_Position;"
-        "attribute vec2 a_TexCoord;"
-        "uniform float u_XOffset;"
-        "uniform float u_YOffset;"
-        "varying vec2 v_TexCoord;"
-        "void main() {"
-        "  v_TexCoord = a_TexCoord;"
-        "  gl_Position.x = a_Position.x + u_XOffset;"
-        "  gl_Position.y = a_Position.y + u_YOffset;"
-        "  gl_Position.zw = a_Position.zw;"
-        "}";
-
-static const char* FBO_FRAGMENT =
-        "precision mediump float;"
-        "uniform sampler2D u_Texture;"
-        "varying vec2 v_TexCoord;"
-        "void main() {"
-        "  gl_FragColor = texture2D(u_Texture, v_TexCoord);"
-        "}";
-
-static const EGLint contextAttribs[] = {
-        EGL_CONTEXT_CLIENT_VERSION, 2,
-        EGL_NONE };
-
-static const EGLint configAttribs[] = {
-        EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
-        EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
-        EGL_RED_SIZE, 8,
-        EGL_GREEN_SIZE, 8,
-        EGL_BLUE_SIZE, 8,
-        EGL_ALPHA_SIZE, 8,
-        EGL_DEPTH_SIZE, 16,
-        EGL_STENCIL_SIZE, 8,
-        EGL_NONE };
-
-static const int FBO_SIZE = 128;
-
-Renderer::Renderer(EGLNativeWindowType window, bool offscreen) :
-        mOffscreen(offscreen), mEglDisplay(EGL_NO_DISPLAY), mEglSurface(EGL_NO_SURFACE),
-        mEglContext(EGL_NO_CONTEXT), mWindow(window)  {
-}
-
-bool Renderer::eglSetUp() {
-    SCOPED_TRACE();
-    mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
-    EGL_RESULT_CHECK(mEglDisplay != EGL_NO_DISPLAY);
-
-    EGLint major;
-    EGLint minor;
-    EGL_RESULT_CHECK(eglInitialize(mEglDisplay, &major, &minor));
-
-    EGLint numConfigs = 0;
-    EGL_RESULT_CHECK(eglChooseConfig(mEglDisplay, configAttribs, &mGlConfig, 1, &numConfigs)
-                     && (numConfigs > 0));
-
-    mEglSurface = eglCreateWindowSurface(mEglDisplay, mGlConfig, mWindow, NULL);
-    EGL_RESULT_CHECK(mEglSurface != EGL_NO_SURFACE);
-
-    mEglContext = eglCreateContext(mEglDisplay, mGlConfig, EGL_NO_CONTEXT, contextAttribs);
-    EGL_RESULT_CHECK(mEglContext != EGL_NO_CONTEXT);
-
-    EGL_RESULT_CHECK(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext));
-    EGL_RESULT_CHECK(eglQuerySurface(mEglDisplay, mEglSurface, EGL_WIDTH, &mWidth));
-    EGL_RESULT_CHECK(eglQuerySurface(mEglDisplay, mEglSurface, EGL_HEIGHT, &mHeight));
-
-    return true;
-}
-
-void Renderer::eglTearDown() {
-    SCOPED_TRACE();
-    eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
-
-    if (mEglContext != EGL_NO_CONTEXT) {
-        eglDestroyContext(mEglDisplay, mEglContext);
-        mEglContext = EGL_NO_CONTEXT;
-    }
-
-    if (mEglSurface != EGL_NO_SURFACE) {
-        mEglSurface = EGL_NO_SURFACE;
-    }
-
-    if (mEglDisplay != EGL_NO_DISPLAY) {
-        eglTerminate(mEglDisplay);
-        mEglDisplay = EGL_NO_DISPLAY;
-    }
-}
-
-bool Renderer::setUp(int /*workload*/) {
-    SCOPED_TRACE();
-
-    EGL_RESULT_CHECK(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext));
-
-    if (mOffscreen) {
-        mFboWidth = FBO_SIZE;
-        mFboHeight = FBO_SIZE;
-
-        glGenFramebuffers(1, &mFboId);
-        glBindFramebuffer(GL_FRAMEBUFFER, mFboId);
-
-        glGenRenderbuffers(1, &mFboDepthId);
-        glBindRenderbuffer(GL_RENDERBUFFER, mFboDepthId);
-        glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, mFboWidth, mFboHeight);
-        glBindRenderbuffer(GL_RENDERBUFFER, 0);
-        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
-                                  GL_RENDERBUFFER, mFboDepthId);
-
-        mFboTexId = GLUtils::genTexture(mFboWidth, mFboHeight, 0);
-        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mFboTexId, 0);
-
-        GLuint err = glGetError();
-        if (err != GL_NO_ERROR) {
-            ALOGE("GLError %d", err);
-            return false;
-        }
-
-        GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
-        if (status != GL_FRAMEBUFFER_COMPLETE) {
-            ALOGE("Framebuffer not complete: %d", status);
-            return false;
-        }
-        // Create fbo program.
-        mFboProgId = GLUtils::createProgram(&FBO_VERTEX, &FBO_FRAGMENT);
-        if (mFboProgId == 0) {
-            return false;
-        }
-        // Bind attributes.
-        mFboTexUniformHandle = glGetUniformLocation(mFboProgId, "u_Texture");
-        mFboXOffsetUniformHandle = glGetUniformLocation(mFboProgId, "u_XOffset");
-        mFboYOffsetUniformHandle = glGetUniformLocation(mFboProgId, "u_YOffset");
-        mFboPositionHandle = glGetAttribLocation(mFboProgId, "a_Position");
-        mFboTexCoordHandle = glGetAttribLocation(mFboProgId, "a_TexCoord");
-    } else {
-        mFboWidth = 0;
-        mFboHeight = 0;
-        mFboId = 0;
-        mFboDepthId = 0;
-        mFboTexId = 0;
-    }
-
-    GLuint err = glGetError();
-    if (err != GL_NO_ERROR) {
-        ALOGE("GLError %d in setUp", err);
-        return false;
-    }
-
-    return true;
-}
-
-bool Renderer::tearDown() {
-    SCOPED_TRACE();
-    if (mOffscreen) {
-        if (mFboId != 0) {
-            glDeleteFramebuffers(1, &mFboId);
-            mFboId = 0;
-        }
-        if (mFboDepthId != 0) {
-            glDeleteRenderbuffers(1, &mFboDepthId);
-            mFboDepthId = 0;
-        }
-        if (mFboTexId != 0) {
-            glDeleteTextures(1, &mFboTexId);
-            mFboTexId = 0;
-        }
-    }
-    GLuint err = glGetError();
-    if (err != GL_NO_ERROR) {
-        ALOGE("GLError %d in tearDown", err);
-        return false;
-    }
-
-    return true;
-}
-
-bool Renderer::draw() {
-    SCOPED_TRACE();
-
-    EGL_RESULT_CHECK(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext));
-
-    glBindFramebuffer(GL_FRAMEBUFFER, 0);
-    glViewport(0, 0, mWidth, mHeight);
-
-    if (mOffscreen) {
-        // Set the background clear color to black.
-        glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
-        glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
-        for (int i = 0; i < OFFSCREEN_INNER_FRAMES; i++) {
-            // Switch to FBO and re-attach.
-            glBindFramebuffer(GL_FRAMEBUFFER, mFboId);
-            glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
-                                    GL_RENDERBUFFER, mFboDepthId);
-            glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
-                                 GL_TEXTURE_2D, mFboTexId, 0);
-            glViewport(0, 0, mFboWidth, mFboHeight);
-
-            // Render workload.
-            drawWorkload();
-            glFlush();
-
-            // Switch back to display.
-            glBindFramebuffer(GL_FRAMEBUFFER, 0);
-            glViewport(0, 0, mWidth, mHeight);
-
-            // No culling of back faces
-            glDisable (GL_CULL_FACE);
-            // No depth testing
-            glDisable (GL_DEPTH_TEST);
-            // No blending
-            glDisable (GL_BLEND);
-
-            glUseProgram(mFboProgId);
-
-            // Set the texture.
-            glActiveTexture (GL_TEXTURE0);
-            glBindTexture(GL_TEXTURE_2D, mFboTexId);
-            glUniform1i(mFboTexUniformHandle, 0);
-
-            // Set the offsets
-            glUniform1f(mFboXOffsetUniformHandle, CENTER_GRID(i / OFFSCREEN_GRID_SIZE));
-            glUniform1f(mFboYOffsetUniformHandle, CENTER_GRID(i % OFFSCREEN_GRID_SIZE));
-
-            glEnableVertexAttribArray(mFboPositionHandle);
-            glEnableVertexAttribArray(mFboTexCoordHandle);
-            glVertexAttribPointer(mFboPositionHandle, 3, GL_FLOAT, false, 0, FBO_VERTICES);
-            glVertexAttribPointer(mFboTexCoordHandle, 2, GL_FLOAT, false, 0, FBO_TEX_COORDS);
-
-            // Render FBO to display.
-            glDrawArrays(GL_TRIANGLES, 0, FBO_NUM_VERTICES);
-        }
-    } else {
-        // Render workload.
-        drawWorkload();
-    }
-
-    GLuint err = glGetError();
-    if (err != GL_NO_ERROR) {
-        ALOGE("GLError %d in draw", err);
-        return false;
-    }
-
-    EGL_RESULT_CHECK(eglSwapBuffers(mEglDisplay, mEglSurface)); 
-    return true;
-}
diff --git a/suite/cts/deviceTests/opengl/jni/graphics/SceneGraphNode.cpp b/suite/cts/deviceTests/opengl/jni/graphics/SceneGraphNode.cpp
deleted file mode 100644
index 455ccd6..0000000
--- a/suite/cts/deviceTests/opengl/jni/graphics/SceneGraphNode.cpp
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-#include "SceneGraphNode.h"
-
-SceneGraphNode::~SceneGraphNode() {
-    for (size_t i = 0; i < mChildren.size(); i++) {
-        delete mChildren[i];
-    }
-}
-
-void SceneGraphNode::addChild(SceneGraphNode* child) {
-    mChildren.add(child);
-}
-
-void SceneGraphNode::draw(Program& program, Matrix& model, Matrix& view, Matrix& projection) {
-    before(program, model, view, projection);
-    for (size_t i = 0; i < mChildren.size(); i++) {
-        mChildren[i]->draw(program, model, view, projection);
-    }
-    after(program, model, view, projection);
-}
diff --git a/suite/cts/deviceTests/opengl/jni/graphics/SceneGraphNode.h b/suite/cts/deviceTests/opengl/jni/graphics/SceneGraphNode.h
deleted file mode 100644
index dce8fde..0000000
--- a/suite/cts/deviceTests/opengl/jni/graphics/SceneGraphNode.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-#ifndef SCENEGRAPHNODE_H
-#define SCENEGRAPHNODE_H
-
-#include <utils/Vector.h>
-#include "Matrix.h"
-#include "Program.h"
-
-class SceneGraphNode {
-public:
-    SceneGraphNode() {};
-    virtual ~SceneGraphNode();
-    void addChild(SceneGraphNode* child);
-protected:
-    virtual void before(Program& program, Matrix& model, Matrix& view, Matrix& projection) = 0;
-    virtual void after(Program& program, Matrix& model, Matrix& view, Matrix& projection) = 0;
-    void draw(Program& program, Matrix& model, Matrix& view, Matrix& projection);
-private:
-    android::Vector<SceneGraphNode*> mChildren;
-};
-
-#endif
diff --git a/suite/cts/deviceTests/opengl/jni/primitive/GLPrimitive.cpp b/suite/cts/deviceTests/opengl/jni/primitive/GLPrimitive.cpp
deleted file mode 100644
index 856da1e..0000000
--- a/suite/cts/deviceTests/opengl/jni/primitive/GLPrimitive.cpp
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-#include <jni.h>
-
-#include <stdlib.h>
-
-#include <android/native_window.h>
-#include <android/native_window_jni.h>
-
-#include <graphics/GLUtils.h>
-#include <graphics/Renderer.h>
-
-#include "fullpipeline/FullPipelineRenderer.h"
-#include "pixeloutput/PixelOutputRenderer.h"
-#include "shaderperf/ShaderPerfRenderer.h"
-#include "contextswitch/ContextSwitchRenderer.h"
-
-// Holds the current benchmark's renderer.
-Renderer* gRenderer = NULL;
-ANativeWindow* gNativeWindow = NULL;
-
-enum {
-    FULL_PIPELINE_BENCHMARK = 0,
-    PIXEL_OUTPUT_BENCHMARK = 1,
-    SHADER_PERF_BENCHMARK = 2,
-    CONTEXT_SWITCH_BENCHMARK = 3
-};
-
-extern "C" JNIEXPORT jboolean JNICALL
-Java_com_android_cts_opengl_primitive_GLPrimitiveActivity_startBenchmark(
-        JNIEnv* env, jclass /*clazz*/, jint workload, jint numFrames, jdoubleArray frameTimes) {
-    if (gRenderer == NULL) {
-        return false;
-    }
-
-    // Sets up the renderer.
-    bool success = gRenderer->setUp(workload);
-
-    // Records the start time.
-    double start = GLUtils::currentTimeMillis();
-
-    // Offscreen renders 100 tiles per frame so reduce the number of frames to render.
-    if (gRenderer->mOffscreen) {
-        numFrames /= Renderer::OFFSCREEN_INNER_FRAMES;
-    }
-
-    // Draw off the screen.
-    for (int i = 0; i < numFrames && success; i++) {
-        // Draw a frame.
-        success = gRenderer->draw();
-    }
-
-    // Records the end time.
-    double end = GLUtils::currentTimeMillis();
-
-    // Sets the times in the Java array.
-    double times[] = {start, end};
-    env->SetDoubleArrayRegion(frameTimes, 0, 2, times);
-
-    success = gRenderer->tearDown() && success;
-    return success;
-}
-
-// The following functions create the renderers for the various benchmarks.
-extern "C" JNIEXPORT void JNICALL
-Java_com_android_cts_opengl_primitive_GLPrimitiveActivity_setupBenchmark(
-        JNIEnv* env, jclass /*clazz*/, jobject surface, jint benchmark,
-        jboolean offscreen) {
-    gNativeWindow = ANativeWindow_fromSurface(env, surface);
-    switch (benchmark) {
-        case FULL_PIPELINE_BENCHMARK:
-            gRenderer = new FullPipelineRenderer(gNativeWindow, offscreen);
-            break;
-        case PIXEL_OUTPUT_BENCHMARK:
-            gRenderer = new PixelOutputRenderer(gNativeWindow, offscreen);
-            break;
-        case SHADER_PERF_BENCHMARK:
-            gRenderer = new ShaderPerfRenderer(gNativeWindow, offscreen);
-            break;
-        case CONTEXT_SWITCH_BENCHMARK:
-            gRenderer = new ContextSwitchRenderer(gNativeWindow, offscreen);
-            break;
-        default:
-            ALOGE("Unknown benchmark '%d'", benchmark);
-            ANativeWindow_release(gNativeWindow);
-            gNativeWindow = NULL;
-            return;
-    }
-
-    // Set up call will log error conditions
-    if (!gRenderer->eglSetUp()) {
-        delete gRenderer;
-        gRenderer = NULL;
-
-        ANativeWindow_release(gNativeWindow);
-        gNativeWindow = NULL;
-    }
-}
-
-extern "C" JNIEXPORT void JNICALL
-Java_com_android_cts_opengl_primitive_GLPrimitiveActivity_tearDownBenchmark(
-        JNIEnv* /*env*/, jclass /*clazz*/) {
-    if (gRenderer == NULL) {
-        return;
-    }
-    gRenderer->eglTearDown();
-    delete gRenderer;
-    gRenderer = NULL;
-
-    ANativeWindow_release(gNativeWindow);
-    gNativeWindow = NULL;
-}
diff --git a/suite/cts/deviceTests/opengl/jni/primitive/contextswitch/ContextSwitchRenderer.cpp b/suite/cts/deviceTests/opengl/jni/primitive/contextswitch/ContextSwitchRenderer.cpp
deleted file mode 100644
index 1127d88..0000000
--- a/suite/cts/deviceTests/opengl/jni/primitive/contextswitch/ContextSwitchRenderer.cpp
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-
-#include <android/native_window.h>
-
-#include <stdlib.h>
-
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-
-#include "ContextSwitchRenderer.h"
-#include <graphics/GLUtils.h>
-
-#define LOG_TAG "CTS_OPENGL"
-#define LOG_NDEBUG 0
-#include <utils/Log.h>
-#include <Trace.h>
-
-static const EGLint contextAttribs[] = {
-        EGL_CONTEXT_CLIENT_VERSION, 2,
-        EGL_NONE };
-
-static const int NUM_WORKER_CONTEXTS = 7;
-
-static const int CS_TEXTURE_SIZE = 64;
-
-static const int CS_NUM_VERTICES = 6;
-
-static const float CS_VERTICES[CS_NUM_VERTICES * 3] = {
-        0.1f, 0.1f, -0.1f,
-        -0.1f, 0.1f, -0.1f,
-        -0.1f, -0.1f, -0.1f,
-        -0.1f, -0.1f, -0.1f,
-        0.1f, -0.1f, -0.1f,
-        0.1f, 0.1f, -0.1f };
-
-static const float CS_TEX_COORDS[CS_NUM_VERTICES * 2] = {
-        1.0f, 1.0f,
-        0.0f, 1.0f,
-        0.0f, 0.0f,
-        0.0f, 0.0f,
-        1.0f, 0.0f,
-        1.0f, 1.0f };
-
-static const char* CS_VERTEX =
-        "attribute vec4 a_Position;"
-        "attribute vec2 a_TexCoord;"
-        "uniform float u_Translate;"
-        "varying vec2 v_TexCoord;"
-        "void main() {"
-        "  v_TexCoord = a_TexCoord;"
-        "  gl_Position.x = a_Position.x + u_Translate;"
-        "  gl_Position.yzw = a_Position.yzw;"
-        "}";
-
-static const char* CS_FRAGMENT =
-        "precision mediump float;"
-        "uniform sampler2D u_Texture;"
-        "varying vec2 v_TexCoord;"
-        "void main() {"
-        "  gl_FragColor = texture2D(u_Texture, v_TexCoord);"
-        "}";
-
-ContextSwitchRenderer::ContextSwitchRenderer(ANativeWindow* window, bool offscreen) :
-        Renderer(window, offscreen), mContexts(NULL), mWorkload(0) {
-}
-
-bool ContextSwitchRenderer::setUp(int workload) {
-    SCOPED_TRACE();
-    mWorkload = workload;
-    if (!Renderer::setUp(workload)) {
-        return false;
-    }
-
-    // Setup texture.
-    mTextureId = GLUtils::genTexture(CS_TEXTURE_SIZE, CS_TEXTURE_SIZE, GLUtils::RANDOM_FILL);
-    if (mTextureId == 0) {
-        return false;
-    }
-
-    // Create program.
-    mProgramId = GLUtils::createProgram(&CS_VERTEX, &CS_FRAGMENT);
-    if (mProgramId == 0) {
-        return false;
-    }
-    // Bind attributes.
-    mTextureUniformHandle = glGetUniformLocation(mProgramId, "u_Texture");
-    mTranslateUniformHandle = glGetUniformLocation(mProgramId, "u_Translate");
-    mPositionHandle = glGetAttribLocation(mProgramId, "a_Position");
-    mTexCoordHandle = glGetAttribLocation(mProgramId, "a_TexCoord");
-
-    mContexts = new EGLContext[NUM_WORKER_CONTEXTS];
-    mFboIds = new GLuint[NUM_WORKER_CONTEXTS];
-    for (int i = 0; i < NUM_WORKER_CONTEXTS; i++) {
-        // Create the contexts, they share data with the main one.
-        mContexts[i] = eglCreateContext(mEglDisplay, mGlConfig, mEglContext, contextAttribs);
-        if (EGL_NO_CONTEXT == mContexts[i] || EGL_SUCCESS != eglGetError()) {
-            return false;
-        }
-
-        if (!eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mContexts[i])
-                || EGL_SUCCESS != eglGetError()) {
-            return false;
-        }
-        if (mOffscreen) {
-            // FBOs are not shared across contexts, textures and renderbuffers are though.
-            glGenFramebuffers(1, &mFboIds[i]);
-            glBindFramebuffer(GL_FRAMEBUFFER, mFboIds[i]);
-
-            glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
-                                      GL_RENDERBUFFER, mFboDepthId);
-
-            glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
-                                   GL_TEXTURE_2D, mFboTexId, 0);
-            GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
-            if (status != GL_FRAMEBUFFER_COMPLETE) {
-                ALOGE("Framebuffer not complete: %d", status);
-                return false;
-            }
-        }
-    }
-    return true;
-}
-
-bool ContextSwitchRenderer::tearDown() {
-    SCOPED_TRACE();
-    if (mContexts) {
-        // Destroy the contexts, the main one will be handled by Renderer::eglTearDown().
-        for (int i = 0; i < NUM_WORKER_CONTEXTS; i++) {
-            if (mOffscreen) {
-                if (mFboIds[i] != 0) {
-                    eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mContexts[i]);
-                    glDeleteFramebuffers(1, &mFboIds[i]);
-                    mFboIds[i] = 0;
-                }
-            }
-            eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
-            eglDestroyContext(mEglDisplay, mContexts[i]);
-        }
-        delete[] mContexts;
-    }
-    eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext);
-    if (mTextureId != 0) {
-        glDeleteTextures(1, &mTextureId);
-        mTextureId = 0;
-    }
-    if (!Renderer::tearDown()) {
-        return false;
-    }
-    return true;
-}
-
-void ContextSwitchRenderer::drawWorkload() {
-    SCOPED_TRACE();
-
-    if (mWorkload > 8) {
-        return; // This test does not support higher workloads.
-    }
-
-    // Set the background clear color to black.
-    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
-    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
-    // No culling of back faces
-    glDisable(GL_CULL_FACE);
-    // No depth testing
-    glDisable(GL_DEPTH_TEST);
-
-    EGLSyncKHR fence = eglCreateSyncKHR(mEglDisplay, EGL_SYNC_FENCE_KHR, NULL);
-
-    const int TOTAL_NUM_CONTEXTS = NUM_WORKER_CONTEXTS + 1;
-    const float TRANSLATION = 0.9f - (TOTAL_NUM_CONTEXTS * 0.2f);
-    for (int i = 0; i < TOTAL_NUM_CONTEXTS; i++) {
-        eglWaitSyncKHR(mEglDisplay, fence, 0);
-        eglDestroySyncKHR(mEglDisplay, fence);
-        glUseProgram(mProgramId);
-
-        // Set the texture.
-        glActiveTexture (GL_TEXTURE0);
-        glBindTexture(GL_TEXTURE_2D, mTextureId);
-        glUniform1i(mTextureUniformHandle, 0);
-
-        // Set the x translate.
-        glUniform1f(mTranslateUniformHandle, (i * 0.2f) + TRANSLATION);
-
-        glEnableVertexAttribArray(mPositionHandle);
-        glEnableVertexAttribArray(mTexCoordHandle);
-        glVertexAttribPointer(mPositionHandle, 3, GL_FLOAT, false, 0, CS_VERTICES);
-        glVertexAttribPointer(mTexCoordHandle, 2, GL_FLOAT, false, 0, CS_TEX_COORDS);
-
-        glDrawArrays(GL_TRIANGLES, 0, CS_NUM_VERTICES);
-        fence = eglCreateSyncKHR(mEglDisplay, EGL_SYNC_FENCE_KHR, NULL);
-
-        // Switch to next context.
-        if (i < (mWorkload - 1)) {
-            eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mContexts[i]);
-            // Switch to FBO and re-attach.
-            if (mOffscreen) {
-                glBindFramebuffer(GL_FRAMEBUFFER, mFboIds[i]);
-                glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
-                                        GL_RENDERBUFFER, mFboDepthId);
-                glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
-                                     GL_TEXTURE_2D, mFboTexId, 0);
-                glViewport(0, 0, mFboWidth, mFboHeight);
-            }
-        }
-        GLuint err = glGetError();
-        if (err != GL_NO_ERROR) {
-            ALOGE("GLError %d in drawWorkload", err);
-            break;
-        }
-    }
-
-    eglWaitSyncKHR(mEglDisplay, fence, 0);
-    eglDestroySyncKHR(mEglDisplay, fence);
-
-    // Switch back to the main context.
-    eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext);
-    if (mOffscreen) {
-        glBindFramebuffer(GL_FRAMEBUFFER, mFboId);
-        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
-                                GL_RENDERBUFFER, mFboDepthId);
-        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
-                             GL_TEXTURE_2D, mFboTexId, 0);
-        glViewport(0, 0, mFboWidth, mFboHeight);
-    }
-}
diff --git a/suite/cts/deviceTests/opengl/jni/reference/GLReference.cpp b/suite/cts/deviceTests/opengl/jni/reference/GLReference.cpp
deleted file mode 100644
index dc0b4e2..0000000
--- a/suite/cts/deviceTests/opengl/jni/reference/GLReference.cpp
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-#include <jni.h>
-
-#include <android/native_window.h>
-#include <android/native_window_jni.h>
-
-#include <graphics/GLUtils.h>
-#include <graphics/Renderer.h>
-
-#include "ReferenceRenderer.h"
-
-extern "C" JNIEXPORT jboolean JNICALL
-Java_com_android_cts_opengl_reference_GLGameActivity_startBenchmark(
-    JNIEnv* env, jclass /*clazz*/, jobject assetManager, jobject surface, jint numFrames,
-        jdoubleArray setUpTimes, jdoubleArray updateTimes, jdoubleArray renderTimes) {
-
-    GLUtils::setEnvAndAssetManager(env, assetManager);
-
-    if (numFrames > (ReferenceRenderer::FRAMES_PER_SCENE * ReferenceRenderer::NUM_SCENES)) {
-        return false;
-    }
-
-    ANativeWindow* nativeWindow = ANativeWindow_fromSurface(env, surface);
-    ReferenceRenderer* renderer = new ReferenceRenderer(nativeWindow);
-    bool success = renderer->eglSetUp();
-    success = renderer->setUp(0) && success;
-    env->SetDoubleArrayRegion(
-            setUpTimes, 0, ReferenceRenderer::NUM_SETUP_TIMES, renderer->mSetUpTimes);
-
-    double updates[numFrames];
-    double renders[numFrames];
-    for (int i = 0; i < numFrames && success; i++) {
-        double t0 = GLUtils::currentTimeMillis();
-        success = renderer->update(i);
-        double t1 = GLUtils::currentTimeMillis();
-        success = success && renderer->draw();
-        double t2 = GLUtils::currentTimeMillis();
-        updates[i] = t1 - t0;
-        renders[i] = t2 - t1;
-    }
-
-    env->SetDoubleArrayRegion(updateTimes, 0, numFrames, updates);
-    env->SetDoubleArrayRegion(renderTimes, 0, numFrames, renders);
-
-    success = renderer->tearDown() && success;
-    renderer->eglTearDown();
-    delete renderer;
-    renderer = NULL;
-
-    ANativeWindow_release(nativeWindow);
-
-    return success;
-}
diff --git a/suite/cts/deviceTests/opengl/jni/reference/ReferenceRenderer.cpp b/suite/cts/deviceTests/opengl/jni/reference/ReferenceRenderer.cpp
deleted file mode 100644
index 3b12ee1..0000000
--- a/suite/cts/deviceTests/opengl/jni/reference/ReferenceRenderer.cpp
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-#include "ReferenceRenderer.h"
-
-#include "scene/flocking/FlockingScene.h"
-#include "scene/glowing/GlowingScene.h"
-
-#include <graphics/GLUtils.h>
-#include <graphics/ProgramNode.h>
-
-#include <Trace.h>
-
-ReferenceRenderer::ReferenceRenderer(ANativeWindow* window) :
-        Renderer(window, false) {
-}
-
-bool ReferenceRenderer::setUp(int workload) {
-    SCOPED_TRACE();
-    // Reset the times.
-    for (int i = 0; i < NUM_SETUP_TIMES; i++) {
-        mSetUpTimes[i] = 0;
-    }
-    // Set up OpenGLES.
-    double start = GLUtils::currentTimeMillis();
-    if (!Renderer::setUp(workload)) {
-        return false;
-    }
-    mSetUpTimes[0] = GLUtils::currentTimeMillis() - start;
-
-    // Create the scenes.
-    mScenes[0] = new FlockingScene(mWidth, mHeight);
-    mScenes[1] = new GlowingScene(mWidth, mHeight);
-    // TODO add more scenes to do a comprehensive test.
-
-    // Set up the scenes.
-    double times[NUM_SETUP_TIMES];
-    for (int i = 0; i < NUM_SCENES; i++) {
-        times[0] = GLUtils::currentTimeMillis();
-        mScenes[i]->setUpContext();
-        times[1] = GLUtils::currentTimeMillis();
-        mScenes[i]->setUpTextures();
-        times[2] = GLUtils::currentTimeMillis();
-        mScenes[i]->setUpMeshes();
-        times[3] = GLUtils::currentTimeMillis();
-
-        for (int i = 1; i < NUM_SETUP_TIMES; i++) {
-            // Add on the set up times.
-            mSetUpTimes[i] += times[i] - times[i - 1];
-        }
-    }
-    return true;
-}
-
-bool ReferenceRenderer::tearDown() {
-    SCOPED_TRACE();
-    for (int i = 0; i < NUM_SCENES; i++) {
-        mScenes[i]->tearDown();
-        delete mScenes[i];
-    }
-    mCurrentScene = NULL;
-    if (!Renderer::tearDown()) {
-        return false;
-    }
-    return true;
-}
-
-bool ReferenceRenderer::update(int frame) {
-    SCOPED_TRACE();
-    int sceneId = frame / ReferenceRenderer::FRAMES_PER_SCENE;
-    int localFrame = frame % ReferenceRenderer::FRAMES_PER_SCENE;
-    mCurrentScene = mScenes[sceneId];
-    mCurrentScene->update(localFrame);
-    return true;
-}
-
-void ReferenceRenderer::drawWorkload() {
-    SCOPED_TRACE();
-    // Set the background clear color to black.
-    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
-    // Use culling to remove back faces.
-    glEnable (GL_CULL_FACE);
-    // Use depth testing.
-    glEnable (GL_DEPTH_TEST);
-
-    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
-    if (!mCurrentScene->draw()) {
-        ALOGE("Error when rendering scene");
-    }
-}
diff --git a/suite/cts/deviceTests/opengl/jni/reference/scene/Scene.h b/suite/cts/deviceTests/opengl/jni/reference/scene/Scene.h
deleted file mode 100644
index 06178b9..0000000
--- a/suite/cts/deviceTests/opengl/jni/reference/scene/Scene.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-#ifndef SCENE_H
-#define SCENE_H
-
-#include <graphics/Matrix.h>
-#include <graphics/Mesh.h>
-#include <graphics/Program.h>
-#include <graphics/ProgramNode.h>
-
-#include <utils/Vector.h>
-
-class Scene {
-public:
-    Scene(int width, int height);
-    virtual ~Scene() {};
-    virtual bool setUpContext();
-    virtual bool setUpTextures() = 0;
-    virtual bool setUpMeshes() = 0;
-    virtual bool tearDown();
-    virtual bool update(int frame);
-    virtual bool draw() = 0;
-    void drawSceneGraph(int index);
-protected:
-    virtual bool setUpPrograms() = 0;
-    virtual Matrix* setUpModelMatrix() = 0;
-    virtual Matrix* setUpViewMatrix() = 0;
-    virtual Matrix* setUpProjectionMatrix(float width, float height) = 0;
-    virtual bool updateSceneGraphs(int frame) = 0;
-    int mWidth;
-    int mHeight;
-    android::Vector<Mesh*> mMeshes;
-    android::Vector<GLuint> mTextureIds;
-    android::Vector<ProgramNode*> mSceneGraphs;
-private:
-    Matrix* mModelMatrix;
-    Matrix* mViewMatrix;
-    Matrix* mProjectionMatrix;
-};
-#endif
diff --git a/suite/cts/deviceTests/opengl/jni/reference/scene/flocking/Boid.h b/suite/cts/deviceTests/opengl/jni/reference/scene/flocking/Boid.h
deleted file mode 100644
index 3e4367a..0000000
--- a/suite/cts/deviceTests/opengl/jni/reference/scene/flocking/Boid.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-// An implementation of Craig Reynold's Boid Simulation.
-#ifndef BOID_H
-#define BOID_H
-
-#include <graphics/Vector2D.h>
-#include <utils/Compat.h>
-
-class Boid {
-public:
-    Boid(float x, float y);
-    void resetAcceleration();
-    void flock(const Boid* boids[], int numBoids, int index, float limitX, float limitY);
-    // The following floats are the parameters for the flocking algorithm, changing these
-    // modifies the boid's behaviour.
-    static const CONSTEXPR float MAX_SPEED = 2.0f;// Upper limit of boid velocity.
-    static const CONSTEXPR float MAX_FORCE = 0.05f;// Upper limit of the force used to push a boid.
-    static const CONSTEXPR float NEIGHBOUR_RADIUS = 70.0f;// Radius used to find neighbours, was 50.
-    static const CONSTEXPR float DESIRED_BOID_DIST = 35.0f;// Distance boids want to be from others, was 25.
-    // The weightings of the components.
-    static const CONSTEXPR float SEPARATION_WEIGHT = 2.0f;
-    static const CONSTEXPR float ALIGNMENT_WEIGHT = 1.0f;
-    static const CONSTEXPR float COHESION_WEIGHT = 1.0f;
-    Vector2D mPosition;
-    Vector2D mVelocity;
-    Vector2D mAcceleration;
-};
-#endif
diff --git a/suite/cts/deviceTests/opengl/jni/reference/scene/flocking/FlockingScene.cpp b/suite/cts/deviceTests/opengl/jni/reference/scene/flocking/FlockingScene.cpp
deleted file mode 100644
index 71e5dac..0000000
--- a/suite/cts/deviceTests/opengl/jni/reference/scene/flocking/FlockingScene.cpp
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-#include "FlockingScene.h"
-
-#include "WaterMeshNode.h"
-
-#include <cstdlib>
-#include <cmath>
-
-#include <Trace.h>
-
-#include <graphics/PerspectiveMeshNode.h>
-#include <graphics/PerspectiveProgram.h>
-#include <graphics/GLUtils.h>
-#include <graphics/Matrix.h>
-#include <graphics/Mesh.h>
-#include <graphics/ProgramNode.h>
-#include <graphics/TransformationNode.h>
-
-FlockingScene::FlockingScene(int width, int height) :
-        Scene(width, height), mMainProgram(NULL), mWaterProgram(NULL) {
-    for (int i = 0; i < NUM_BOIDS; i++) {
-        // Generate a boid with a random position. (-50, 50)
-        float x = (rand() % 101) - 50.0f;
-        float y = (rand() % 101) - 50.0f;
-        mBoids[i] = new Boid(x, y);
-    }
-}
-
-bool FlockingScene::setUpPrograms() {
-    // Main Program
-    const char* vertex = GLUtils::openTextFile("vertex/perspective");
-    const char* fragment = GLUtils::openTextFile("fragment/perspective");
-    if (vertex == NULL || fragment == NULL) {
-        return false;
-    }
-    GLuint programId = GLUtils::createProgram(&vertex, &fragment);
-    delete[] vertex;
-    delete[] fragment;
-    if (programId == 0) {
-        return false;
-    }
-    mMainProgram = new PerspectiveProgram(programId);
-    // Water Program
-    vertex = GLUtils::openTextFile("vertex/water");
-    fragment = GLUtils::openTextFile("fragment/water");
-    if (vertex == NULL || fragment == NULL) {
-        return false;
-    }
-    programId = GLUtils::createProgram(&vertex, &fragment);
-    delete[] vertex;
-    delete[] fragment;
-    if (programId == 0) {
-        return false;
-    }
-    mWaterProgram = new PerspectiveProgram(programId);
-    return true;
-}
-
-Matrix* FlockingScene::setUpModelMatrix() {
-    return new Matrix();
-}
-
-Matrix* FlockingScene::setUpViewMatrix() {
-    // Position the eye in front of the origin.
-    float eyeX = 0.0f;
-    float eyeY = 0.0f;
-    float eyeZ = 10.0f;
-
-    // We are looking at the origin
-    float centerX = 0.0f;
-    float centerY = 0.0f;
-    float centerZ = 0.0f;
-
-    // Set our up vector.
-    float upX = 0.0f;
-    float upY = 1.0f;
-    float upZ = 0.0f;
-
-    // Set the view matrix.
-    return Matrix::newLookAt(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ);
-}
-
-Matrix* FlockingScene::setUpProjectionMatrix(float width, float height) {
-    // Create a new perspective projection matrix. The height will stay the same
-    // while the width will vary as per aspect ratio.
-    mDisplayRatio = width / height;
-    // Set board dimensions
-    mBoardHeight = 1000.0f;
-    mBoardWidth = mDisplayRatio * mBoardHeight;
-    float left = -mDisplayRatio;
-    float right = mDisplayRatio;
-    float bottom = -1.0f;
-    float top = 1.0f;
-    float near = 8.0f;
-    float far = 12.0f;
-
-    return Matrix::newFrustum(left, right, bottom, top, near, far);
-}
-
-bool FlockingScene::setUpTextures() {
-    SCOPED_TRACE();
-    mTextureIds.add(GLUtils::loadTexture("texture/fish_dark.png"));
-    mTextureIds.add(GLUtils::loadTexture("texture/background.png"));
-    mTextureIds.add(GLUtils::loadTexture("texture/water1.png"));
-    mTextureIds.add(GLUtils::loadTexture("texture/water2.png"));
-    return true;
-}
-
-bool FlockingScene::setUpMeshes() {
-    SCOPED_TRACE();
-    mMeshes.add(GLUtils::loadMesh("mesh/fish.cob"));
-    mMeshes.add(GLUtils::loadMesh("mesh/plane.cob"));
-    return true;
-}
-
-bool FlockingScene::tearDown() {
-    SCOPED_TRACE();
-    for (int i = 0; i < NUM_BOIDS; i++) {
-        delete mBoids[i];
-    }
-    delete mMainProgram;
-    delete mWaterProgram;
-    return Scene::tearDown();
-}
-
-bool FlockingScene::updateSceneGraphs(int frame) {
-    const float MAIN_SCALE = 1.25f; // Scale up as the camera is far away.
-    const float LIMIT_X = mBoardWidth / 2.0f;
-    const float LIMIT_Y = mBoardHeight / 2.0f;
-
-    ProgramNode* mainSceneGraph = new ProgramNode(*mMainProgram);
-    mSceneGraphs.add(mainSceneGraph);
-    // Bottom
-    Matrix* transformMatrix = Matrix::newScale(MAIN_SCALE * mDisplayRatio, MAIN_SCALE, 0.0f);
-    TransformationNode* transformNode = new TransformationNode(transformMatrix);
-    mainSceneGraph->addChild(transformNode);
-    MeshNode* meshNode = new PerspectiveMeshNode(mMeshes[1], mTextureIds[1]);
-    transformNode->addChild(meshNode);
-    // Boids
-    const float MARGIN = 30.0f; // So the fish dont disappear and appear at the edges.
-    for (int i = 0; i < NUM_BOIDS; i++) {
-        Boid* b = mBoids[i];
-        b->flock((const Boid**) &mBoids, NUM_BOIDS, i, LIMIT_X + MARGIN, LIMIT_Y + MARGIN);
-        Vector2D* pos = &(b->mPosition);
-        Vector2D* vel = &(b->mVelocity);
-
-        // Normalize to (-1,1)
-        float x = pos->mX / (LIMIT_X * BOID_SCALE) * mDisplayRatio;
-        float y = pos->mY / (LIMIT_Y * BOID_SCALE);
-
-        const float SCALE = BOID_SCALE * MAIN_SCALE;
-        transformMatrix = Matrix::newScale(SCALE, SCALE, SCALE);
-        transformMatrix->translate(x, y, 1.0f);
-        transformMatrix->rotate(atan2(vel->mY, vel->mX) + M_PI, 0, 0, 1);
-        transformNode = new TransformationNode(transformMatrix);
-        mainSceneGraph->addChild(transformNode);
-        meshNode = new PerspectiveMeshNode(mMeshes[0], mTextureIds[0]);
-        transformNode->addChild(meshNode);
-    }
-    ProgramNode* waterSceneGraph = new ProgramNode(*mWaterProgram);
-    mSceneGraphs.add(waterSceneGraph);
-    // Top
-    transformMatrix = Matrix::newScale(MAIN_SCALE * mDisplayRatio, MAIN_SCALE, 1.0f);
-    transformMatrix->translate(0, 0, 0.1f);
-    transformNode = new TransformationNode(transformMatrix);
-    waterSceneGraph->addChild(transformNode);
-    meshNode = new WaterMeshNode(mMeshes[1], frame, mTextureIds[2], mTextureIds[3]);
-    transformNode->addChild(meshNode);
-    return true;
-}
-
-bool FlockingScene::draw() {
-    SCOPED_TRACE();
-    drawSceneGraph(0); // Draw fish and pond bottom
-    // Use blending.
-    glEnable (GL_BLEND);
-    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-    drawSceneGraph(1); // Draw water
-    glDisable(GL_BLEND);
-    return true;
-}
diff --git a/suite/cts/deviceTests/opengl/jni/reference/scene/flocking/FlockingScene.h b/suite/cts/deviceTests/opengl/jni/reference/scene/flocking/FlockingScene.h
deleted file mode 100644
index 7cdcffe..0000000
--- a/suite/cts/deviceTests/opengl/jni/reference/scene/flocking/FlockingScene.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-#ifndef FLOCKINGSCENE_H
-#define FLOCKINGSCENE_H
-
-#include <graphics/Program.h>
-#include <utils/Compat.h>
-
-#include "../Scene.h"
-#include "Boid.h"
-
-class FlockingScene : public Scene {
-public:
-    FlockingScene(int width, int height);
-    virtual ~FlockingScene() {};
-    bool setUpTextures();
-    bool setUpMeshes();
-    bool tearDown();
-    bool draw();
-    static const int NUM_BOIDS = 100;
-protected:
-    bool setUpPrograms();
-    Matrix* setUpModelMatrix();
-    Matrix* setUpViewMatrix();
-    Matrix* setUpProjectionMatrix(float width, float height);
-    bool updateSceneGraphs(int frame);
-private:
-    Boid* mBoids[NUM_BOIDS];
-    float mDisplayRatio;
-    float mBoardWidth;
-    float mBoardHeight;
-    Program* mMainProgram;
-    Program* mWaterProgram;
-    static const CONSTEXPR float BOID_SCALE = 1.0f / 50.0f;
-};
-#endif
diff --git a/suite/cts/deviceTests/opengl/jni/reference/scene/glowing/GlowingScene.cpp b/suite/cts/deviceTests/opengl/jni/reference/scene/glowing/GlowingScene.cpp
deleted file mode 100644
index 0d22b96..0000000
--- a/suite/cts/deviceTests/opengl/jni/reference/scene/glowing/GlowingScene.cpp
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-#include "GlowingScene.h"
-#include "BlurMeshNode.h"
-
-#include <Trace.h>
-
-#include <graphics/PerspectiveMeshNode.h>
-#include <graphics/PerspectiveProgram.h>
-#include <graphics/Program.h>
-#include <graphics/GLUtils.h>
-#include <graphics/Mesh.h>
-#include <graphics/ProgramNode.h>
-#include <graphics/TransformationNode.h>
-
-GlowingScene::GlowingScene(int width, int height) :
-        Scene(width, height), mFboId(0), mMainProgram(NULL), mBlurProgram(NULL) {
-    mFboWidth = GLUtils::roundUpToSmallestPowerOf2(width);
-    mFboHeight = GLUtils::roundUpToSmallestPowerOf2(height);
-    mFboRatio = mFboWidth / mFboHeight;
-    mFboModelMatrix = setUpModelMatrix();
-    mFboViewMatrix = setUpViewMatrix();
-    mFboProjectionMatrix = setUpProjectionMatrix(mFboWidth, mFboHeight);
-}
-
-bool GlowingScene::setUpContext() {
-    if (!Scene::setUpContext()) {
-        return false;
-    }
-    // Create a fbo
-    glGenFramebuffers(1, &mFboId);
-    return true;
-}
-
-bool GlowingScene::setUpPrograms() {
-    // Main Program
-    const char* vertex = GLUtils::openTextFile("vertex/perspective");
-    const char* fragment = GLUtils::openTextFile("fragment/perspective");
-    if (vertex == NULL || fragment == NULL) {
-        return false;
-    }
-    GLuint programId = GLUtils::createProgram(&vertex, &fragment);
-    delete[] vertex;
-    delete[] fragment;
-    if (programId == 0) {
-        return false;
-    }
-    mMainProgram = new PerspectiveProgram(programId);
-    // Blur Program
-    vertex = GLUtils::openTextFile("vertex/blur");
-    fragment = GLUtils::openTextFile("fragment/blur");
-    if (vertex == NULL || fragment == NULL) {
-        return false;
-    }
-    programId = GLUtils::createProgram(&vertex, &fragment);
-    delete[] vertex;
-    delete[] fragment;
-    if (programId == 0) {
-        return false;
-    }
-    mBlurProgram = new Program(programId);
-    return true;
-}
-
-Matrix* GlowingScene::setUpModelMatrix() {
-    return new Matrix();
-}
-
-Matrix* GlowingScene::setUpViewMatrix() {
-    // Position the eye in front of the origin.
-    float eyeX = 0.0f;
-    float eyeY = 0.0f;
-    float eyeZ = 10.0f;
-
-    // Look at the origin
-    float centerX = 0.0f;
-    float centerY = 0.0f;
-    float centerZ = 0.0f;
-
-    // Set up vector.
-    float upX = 0.0f;
-    float upY = 1.0f;
-    float upZ = 0.0f;
-
-    // Set the view matrix.
-    return Matrix::newLookAt(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ);
-}
-
-Matrix* GlowingScene::setUpProjectionMatrix(float width, float height) {
-    // Create a new perspective projection matrix. The height will stay the same
-    // while the width will vary as per aspect ratio.
-    float ratio = width / height;
-    float left = -ratio;
-    float right = ratio;
-    float bottom = -1.0f;
-    float top = 1.0f;
-    float near = 8.0f;
-    float far = 12.0f;
-
-    return Matrix::newFrustum(left, right, bottom, top, near, far);
-}
-
-bool GlowingScene::setUpTextures() {
-    SCOPED_TRACE();
-    mTextureIds.add(GLUtils::genTexture(mWidth, mHeight, 0)); // fbo
-    mTextureIds.add(GLUtils::genTexture(mWidth, mHeight, 0)); // tmp1
-    mTextureIds.add(GLUtils::genTexture(mWidth, mHeight, 0)); // tmp2
-    mTextureIds.add(GLUtils::loadTexture("texture/arc.png"));
-    return true;
-}
-
-bool GlowingScene::setUpMeshes() {
-    SCOPED_TRACE();
-    mMeshes.add(GLUtils::loadMesh("mesh/plane.cob"));
-    mMeshes.add(GLUtils::loadMesh("mesh/arc.cob"));
-    return true;
-}
-
-bool GlowingScene::tearDown() {
-    SCOPED_TRACE();
-    if (mMainProgram != NULL) {
-        delete mMainProgram;
-        mMainProgram = NULL;
-    }
-    if (mBlurProgram != NULL) {
-        delete mBlurProgram;
-        mBlurProgram = NULL;
-    }
-    if (mFboId != 0) {
-        glDeleteFramebuffers(1, &mFboId);
-        mFboId = 0;
-    }
-    delete mFboModelMatrix;
-    mFboModelMatrix = NULL;
-    delete mFboViewMatrix;
-    mFboViewMatrix = NULL;
-    delete mFboProjectionMatrix;
-    mFboProjectionMatrix = NULL;
-    return Scene::tearDown();
-}
-
-bool GlowingScene::updateSceneGraphs(int frame) {
-    // To render the mesh to the FBO
-    ProgramNode* lightSceneGraph = new ProgramNode(*mMainProgram);
-    mSceneGraphs.add(lightSceneGraph);
-    MeshNode* meshNode = new PerspectiveMeshNode(mMeshes[1], mTextureIds[3]);
-    lightSceneGraph->addChild(meshNode);
-
-    // To blur the image
-    ProgramNode* blurSceneGraph = new ProgramNode(*mBlurProgram);
-    mSceneGraphs.add(blurSceneGraph);
-    meshNode = new BlurMeshNode(mMeshes[0], mTextureIds[0], mTextureIds[1], mTextureIds[2],
-            mFboWidth, mFboHeight);
-    blurSceneGraph->addChild(meshNode);
-
-    // Blur To screen
-    ProgramNode* glowSceneGraph = new ProgramNode(*mMainProgram);
-    mSceneGraphs.add(glowSceneGraph);
-    Matrix* transformMatrix = Matrix::newScale(mFboRatio, 1.0f, 1.0f);
-    TransformationNode* transformNode = new TransformationNode(transformMatrix);
-    glowSceneGraph->addChild(transformNode);
-    meshNode = new PerspectiveMeshNode(mMeshes[0], mTextureIds[2]);
-    transformNode->addChild(meshNode);
-    return true;
-}
-
-bool GlowingScene::draw() {
-    SCOPED_TRACE();
-    glBindFramebuffer(GL_FRAMEBUFFER, mFboId); // Use FBO
-    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextureIds[0], 0);
-    if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
-        return false;
-    }
-    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
-    glClear (GL_COLOR_BUFFER_BIT);
-    glViewport(0, 0, mFboWidth, mFboHeight);
-    mFboModelMatrix->identity();
-    mSceneGraphs[0]->drawProgram(*mFboModelMatrix, *mFboViewMatrix, *mFboProjectionMatrix); // Mesh
-    mFboModelMatrix->identity();
-    mSceneGraphs[1]->drawProgram(*mFboModelMatrix, *mFboViewMatrix, *mFboProjectionMatrix); // Blur
-
-    glBindFramebuffer(GL_FRAMEBUFFER, 0); // Use Screen
-    glViewport(0, 0, mWidth, mHeight);
-    Scene::drawSceneGraph(2); // Blur to Screen
-    return true;
-}
diff --git a/suite/cts/deviceTests/opengl/src/com/android/cts/opengl/GLActivityIntentKeys.java b/suite/cts/deviceTests/opengl/src/com/android/cts/opengl/GLActivityIntentKeys.java
deleted file mode 100644
index 9a29caf..0000000
--- a/suite/cts/deviceTests/opengl/src/com/android/cts/opengl/GLActivityIntentKeys.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.android.cts.opengl;
-
-public class GLActivityIntentKeys {
-    /**
-     * Holds the name of the benchmark to run.
-     */
-    public final static String INTENT_EXTRA_BENCHMARK_NAME = "benchmark_name";
-    /**
-     * Holds whether or not the benchmark is to be run offscreen.
-     */
-    public final static String INTENT_EXTRA_OFFSCREEN = "offscreen";
-    /**
-     * The number of frames to render for each workload.
-     */
-    public final static String INTENT_EXTRA_NUM_FRAMES = "num_frames";
-    /**
-     * The number of iterations to run, the workload increases with each iteration.
-     */
-    public final static String INTENT_EXTRA_NUM_ITERATIONS = "num_iterations";
-    /**
-     * The number of milliseconds to wait before timing out.
-     */
-    public final static String INTENT_EXTRA_TIMEOUT = "timeout";
-}
diff --git a/suite/cts/deviceTests/opengl/src/com/android/cts/opengl/primitive/BenchmarkName.java b/suite/cts/deviceTests/opengl/src/com/android/cts/opengl/primitive/BenchmarkName.java
deleted file mode 100644
index a6bd6db..0000000
--- a/suite/cts/deviceTests/opengl/src/com/android/cts/opengl/primitive/BenchmarkName.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.android.cts.opengl.primitive;
-
-/**
- * Represents the different primitive benchmarks.
- */
-public enum BenchmarkName {
-    FullPipeline,
-    PixelOutput,
-    ShaderPerf,
-    ContextSwitch;
-}
diff --git a/suite/cts/deviceTests/opengl/src/com/android/cts/opengl/primitive/GLPrimitiveActivity.java b/suite/cts/deviceTests/opengl/src/com/android/cts/opengl/primitive/GLPrimitiveActivity.java
deleted file mode 100644
index 6defdb7..0000000
--- a/suite/cts/deviceTests/opengl/src/com/android/cts/opengl/primitive/GLPrimitiveActivity.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.android.cts.opengl.primitive;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.cts.util.WatchDog;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.SurfaceHolder;
-import android.view.SurfaceView;
-import android.view.Surface;
-
-import com.android.cts.opengl.GLActivityIntentKeys;
-
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.Semaphore;
-
-public class GLPrimitiveActivity extends Activity {
-
-    public final static String TAG = "GLPrimitiveActivity";
-
-    private volatile Exception mException;
-    private volatile Surface mSurface = null;
-    private CountDownLatch mStartSignal = new CountDownLatch(1);
-    private Semaphore mSemaphore = new Semaphore(0);
-
-    private BenchmarkName mBenchmark;
-    private boolean mOffscreen;
-    private int mNumFrames;
-    private int mNumIterations;
-    private int mTimeout;
-    public double[] mFpsValues;
-
-    @Override
-    public void onCreate(Bundle data) {
-        super.onCreate(data);
-        System.loadLibrary("ctsopengl_jni");
-        Intent intent = getIntent();
-        mBenchmark = BenchmarkName.valueOf(
-                intent.getStringExtra(GLActivityIntentKeys.INTENT_EXTRA_BENCHMARK_NAME));
-        mOffscreen = intent.getBooleanExtra(GLActivityIntentKeys.INTENT_EXTRA_OFFSCREEN, false);
-        mNumFrames = intent.getIntExtra(GLActivityIntentKeys.INTENT_EXTRA_NUM_FRAMES, 0);
-        mNumIterations = intent.getIntExtra(GLActivityIntentKeys.INTENT_EXTRA_NUM_ITERATIONS, 0);
-        mTimeout = intent.getIntExtra(GLActivityIntentKeys.INTENT_EXTRA_TIMEOUT, 0);
-        mFpsValues = new double[mNumIterations];
-
-        Log.i(TAG, "Benchmark: " + mBenchmark);
-        Log.i(TAG, "Offscreen: " + mOffscreen);
-        Log.i(TAG, "Num Frames: " + mNumFrames);
-        Log.i(TAG, "Num Iterations: " + mNumIterations);
-        Log.i(TAG, "Time Out: " + mTimeout);
-
-        SurfaceView surfaceView = new SurfaceView(this);
-        surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
-            @Override
-            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
-                mSurface = holder.getSurface();
-                mStartSignal.countDown();
-            }
-
-            @Override
-            public void surfaceCreated(SurfaceHolder holder) {}
-
-            @Override
-            public void surfaceDestroyed(SurfaceHolder holder) {}
-        });
-        setContentView(surfaceView);
-        // Spawns a worker to run the benchmark.
-        Worker worker = new Worker();
-        worker.start();
-    }
-
-    public void waitForCompletion() throws Exception {
-        // Wait for semiphore.
-        mSemaphore.acquire();
-        if (mException != null) {
-            throw mException;
-        }
-    }
-
-    private void complete() {
-        // Release semiphore.
-        mSemaphore.release();
-        finish();
-    }
-
-    private synchronized void setException(Exception e) {
-        if (mException == null) {
-            mException = e;
-        }
-    }
-
-    private static native boolean setupBenchmark(
-            Surface surface, int benchmark, boolean offscreen);
-
-    private static native boolean startBenchmark(int workload, int numFrames, double[] frameTimes);
-
-    private static native void tearDownBenchmark();
-
-    /**
-     * This thread runs the benchmarks, freeing the UI thread.
-     */
-    private class Worker extends Thread implements WatchDog.TimeoutCallback {
-
-        private WatchDog watchDog;
-        private volatile boolean success = true;
-
-        @Override
-        public void run() {
-            try {
-                mStartSignal.await();
-            } catch (InterruptedException e) {
-                setException(e);
-                complete();
-                return;
-            }
-            Log.i(TAG, mBenchmark + " Benchmark Started");
-            // Creates a watchdog to ensure a iteration doesn't exceed the timeout.
-            watchDog = new WatchDog(mTimeout, this);
-            // Used to record the start and end time of the iteration.
-            double[] times = new double[2];
-            try {
-                // Setup the benchmark.
-                setupBenchmark(mSurface, mBenchmark.ordinal(), mOffscreen);
-                for (int i = 0; i < mNumIterations && success; i++) {
-                    // The workload to use for this iteration.
-                    int workload = i + 1;
-                    watchDog.start();
-                    // Start benchmark.
-                    success = startBenchmark(workload, mNumFrames, times);
-                    watchDog.stop();
-                    if (!success) {
-                        setException(new Exception("Benchmark failed to run"));
-                    } else {
-                        // Calculate FPS.
-                        mFpsValues[i] = mNumFrames * 1000.0f / (times[1] - times[0]);
-                    }
-                }
-            }
-            finally
-            {
-                tearDownBenchmark();
-            }
-
-            complete();
-            Log.i(TAG, mBenchmark + " Benchmark Completed");
-        }
-
-        public void onTimeout() {
-            setException(new Exception("Benchmark timed out"));
-            complete();
-        }
-
-    }
-}
diff --git a/suite/cts/deviceTests/opengl/src/com/android/cts/opengl/primitive/GLPrimitiveBenchmark.java b/suite/cts/deviceTests/opengl/src/com/android/cts/opengl/primitive/GLPrimitiveBenchmark.java
deleted file mode 100644
index c177129..0000000
--- a/suite/cts/deviceTests/opengl/src/com/android/cts/opengl/primitive/GLPrimitiveBenchmark.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.android.cts.opengl.primitive;
-
-import com.android.cts.opengl.GLActivityIntentKeys;
-import android.cts.util.CtsActivityInstrumentationTestCase2;
-import com.android.cts.util.ResultType;
-import com.android.cts.util.ResultUnit;
-
-import android.content.Intent;
-import com.android.cts.util.TimeoutReq;
-
-/**
- * Runs the Primitive OpenGL ES 2.0 Benchmarks.
- */
-public class GLPrimitiveBenchmark extends CtsActivityInstrumentationTestCase2<GLPrimitiveActivity> {
-
-    private static final int NUM_FRAMES = 100;
-    private static final int NUM_ITERATIONS = 8;
-    private static final int TIMEOUT = 1000000;
-
-    public GLPrimitiveBenchmark() {
-        super(GLPrimitiveActivity.class);
-    }
-
-    /**
-     * Runs the full OpenGL ES 2.0 pipeline test offscreen.
-     */
-    @TimeoutReq(minutes = 100)
-    public void testFullPipelineOffscreen() throws Exception {
-        runBenchmark(BenchmarkName.FullPipeline, true, NUM_FRAMES, NUM_ITERATIONS, TIMEOUT);
-    }
-
-    /**
-     * Runs the full OpenGL ES 2.0 pipeline test onscreen.
-     */
-    @TimeoutReq(minutes = 100)
-    public void testFullPipelineOnscreen() throws Exception {
-        runBenchmark(BenchmarkName.FullPipeline, false, NUM_FRAMES, NUM_ITERATIONS, TIMEOUT);
-    }
-
-    /**
-     * Runs the pixel output test offscreen.
-     */
-    @TimeoutReq(minutes = 100)
-    public void testPixelOutputOffscreen() throws Exception {
-        runBenchmark(BenchmarkName.PixelOutput, true, NUM_FRAMES, NUM_ITERATIONS, TIMEOUT);
-    }
-
-    /**
-     * Runs the pixel output test onscreen.
-     */
-    @TimeoutReq(minutes = 100)
-    public void testPixelOutputOnscreen() throws Exception {
-        runBenchmark(BenchmarkName.PixelOutput, false, NUM_FRAMES, NUM_ITERATIONS, TIMEOUT);
-    }
-
-    /**
-     * Runs the shader performance test offscreen.
-     */
-    @TimeoutReq(minutes = 100)
-    public void testShaderPerfOffscreen() throws Exception {
-        runBenchmark(BenchmarkName.ShaderPerf, true, NUM_FRAMES, NUM_ITERATIONS, TIMEOUT);
-    }
-
-    /**
-     * Runs the shader performance test onscreen.
-     */
-    @TimeoutReq(minutes = 100)
-    public void testShaderPerfOnscreen() throws Exception {
-        runBenchmark(BenchmarkName.ShaderPerf, false, NUM_FRAMES, NUM_ITERATIONS, TIMEOUT);
-    }
-
-    /**
-     * Runs the context switch overhead test offscreen.
-     */
-    @TimeoutReq(minutes = 100)
-    public void testContextSwitchOffscreen() throws Exception {
-        runBenchmark(BenchmarkName.ContextSwitch, true, NUM_FRAMES, NUM_ITERATIONS, TIMEOUT);
-    }
-
-    /**
-     * Runs the context switch overhead test onscreen.
-     */
-    @TimeoutReq(minutes = 100)
-    public void testContextSwitchOnscreen() throws Exception {
-        runBenchmark(BenchmarkName.ContextSwitch, false, NUM_FRAMES, NUM_ITERATIONS, TIMEOUT);
-    }
-
-    /**
-     * Runs the specified test.
-     *
-     * @param benchmark An enum representing the benchmark to run.
-     * @param offscreen Whether to render to an offscreen framebuffer rather than the screen.
-     * @param numFrames The number of frames to render.
-     * @param numIterations The number of iterations to run, each iteration has a bigger workload.
-     * @param timeout The milliseconds to wait for an iteration of the benchmark before timing out.
-     * @throws Exception If the benchmark could not be run.
-     */
-    private void runBenchmark(BenchmarkName benchmark, boolean offscreen, int numFrames,
-            int numIterations, int timeout) throws Exception {
-        String benchmarkName = benchmark.toString();
-        Intent intent = new Intent();
-        intent.putExtra(GLActivityIntentKeys.INTENT_EXTRA_BENCHMARK_NAME, benchmarkName);
-        intent.putExtra(GLActivityIntentKeys.INTENT_EXTRA_OFFSCREEN, offscreen);
-        intent.putExtra(GLActivityIntentKeys.INTENT_EXTRA_NUM_FRAMES, numFrames);
-        intent.putExtra(GLActivityIntentKeys.INTENT_EXTRA_NUM_ITERATIONS, numIterations);
-        intent.putExtra(GLActivityIntentKeys.INTENT_EXTRA_TIMEOUT, timeout);
-
-        setActivityIntent(intent);
-        GLPrimitiveActivity activity = getActivity();
-        if (activity != null) {
-            activity.waitForCompletion();
-            double[] fpsValues = activity.mFpsValues;
-            double score = 0;
-            for (double d : fpsValues) {
-                score += d;
-            }
-            score /= numIterations;// Average.
-
-            // TODO: maybe standard deviation / RMSE will be useful?
-
-            getReportLog().printArray(
-                    "Fps Values", fpsValues, ResultType.HIGHER_BETTER, ResultUnit.FPS);
-            getReportLog().printSummary(
-                    "Average Frames Per Second", score, ResultType.HIGHER_BETTER,
-                    ResultUnit.SCORE);
-        }
-    }
-}
diff --git a/suite/cts/deviceTests/opengl/src/com/android/cts/opengl/reference/GLGameActivity.java b/suite/cts/deviceTests/opengl/src/com/android/cts/opengl/reference/GLGameActivity.java
deleted file mode 100644
index 3b310f9..0000000
--- a/suite/cts/deviceTests/opengl/src/com/android/cts/opengl/reference/GLGameActivity.java
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.android.cts.opengl.reference;
-
-import com.android.cts.opengl.GLActivityIntentKeys;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.content.res.AssetManager;
-import android.cts.util.WatchDog;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.opengl.GLES20;
-import android.opengl.GLUtils;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.view.Surface;
-import android.view.SurfaceHolder;
-import android.view.SurfaceView;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.concurrent.CountDownLatch;
-
-public class GLGameActivity extends Activity {
-
-    public final static String SET_UP_TIME = "set_up_time";
-    public final static String UPDATE_TIMES = "update_times";
-    public final static String RENDER_TIMES = "render_times";
-
-    private int mNumFrames;
-    private int mTimeout;
-    private double[] mSetUpTimes;
-    private double[] mUpdateTimes;
-    private double[] mRenderTimes;
-    private volatile Surface mSurface = null;
-    private CountDownLatch mStartSignal = new CountDownLatch(1);
-
-    @Override
-    public void onCreate(Bundle data) {
-        super.onCreate(data);
-        System.loadLibrary("ctsopengl_jni");
-
-        Intent intent = getIntent();
-        mNumFrames = intent.getIntExtra(GLActivityIntentKeys.INTENT_EXTRA_NUM_FRAMES, 1000);
-        mTimeout = intent.getIntExtra(GLActivityIntentKeys.INTENT_EXTRA_TIMEOUT, 1000000);
-
-        SurfaceView surfaceView = new SurfaceView(this);
-        surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
-            @Override
-            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
-                mSurface = holder.getSurface();
-                mStartSignal.countDown();
-            }
-
-            @Override
-            public void surfaceCreated(SurfaceHolder holder) {}
-
-            @Override
-            public void surfaceDestroyed(SurfaceHolder holder) {}
-        });
-        setContentView(surfaceView);
-
-        // Spawns a worker.
-        Worker worker = new Worker(new Handler() {
-            public void handleMessage(Message msg) {
-                Intent intent = new Intent();
-                intent.putExtra(SET_UP_TIME, mSetUpTimes);
-                intent.putExtra(UPDATE_TIMES, mUpdateTimes);
-                intent.putExtra(RENDER_TIMES, mRenderTimes);
-                setResult((msg.what == 1) ? RESULT_OK : RESULT_CANCELED, intent);
-                finish();
-            }
-        });
-        worker.start();
-    }
-
-    private static native boolean startBenchmark(AssetManager manager,
-            Surface surface,
-            int numFrames,
-            double[] setUpTimes,
-            double[] updateTimes,
-            double[] renderTimes);
-
-    /**
-     * This thread renderers the benchmarks, freeing the UI thread.
-     */
-    private class Worker extends Thread implements WatchDog.TimeoutCallback {
-
-        private WatchDog watchDog;
-        private Handler mHandler;
-
-        public Worker(Handler handler) {
-            mHandler = handler;
-        }
-
-        @Override
-        public void run() {
-            try {
-                mStartSignal.await();
-            } catch (InterruptedException e) {
-                mHandler.sendEmptyMessage(0);
-                return;
-            }
-            // Creates a watchdog to ensure a iteration doesn't exceed the timeout.
-            watchDog = new WatchDog(mTimeout, this);
-            watchDog.start();
-
-            // Used to record the time taken to setup (GL, context, textures, meshes).
-            mSetUpTimes = new double[4];
-            // Used to record the times taken to update.
-            mUpdateTimes = new double[mNumFrames];
-            // Used to record the times taken to render.
-            mRenderTimes = new double[mNumFrames];
-            boolean success = startBenchmark(getAssets(),
-                    mSurface,
-                    mNumFrames,
-                    mSetUpTimes,
-                    mUpdateTimes,
-                    mRenderTimes);
-
-            watchDog.stop();
-            mHandler.sendEmptyMessage((success) ? 1 : 0);
-        }
-
-        public void onTimeout() {
-            mHandler.sendEmptyMessage(0);
-        }
-
-    }
-
-    public static int loadTexture(AssetManager manager, String path) {
-        InputStream in = null;
-        try {
-            in = manager.open(path);
-        } catch (IOException e) {
-            e.printStackTrace();
-            return -1;
-        }
-        BitmapFactory.Options op = new BitmapFactory.Options();
-        op.inPreferredConfig = Bitmap.Config.ARGB_8888;
-        Bitmap bmp = BitmapFactory.decodeStream(in, null, op);
-        // generate textureID
-        int[] textures = new int[1];
-        GLES20.glGenTextures(1, textures, 0);
-        int textureID = textures[0];
-
-        // create texture
-        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureID);
-        GLES20.glTexParameteri(
-                GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
-        GLES20.glTexParameteri(
-                GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
-        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_REPEAT);
-        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_REPEAT);
-        GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bmp, 0);
-
-        // clean up
-        try {
-            in.close();
-        } catch (IOException e) {
-            e.printStackTrace();
-        } finally {
-            bmp.recycle();
-        }
-        return textureID;
-    }
-}
diff --git a/suite/cts/deviceTests/opengl/src/com/android/cts/opengl/reference/GLReferenceActivity.java b/suite/cts/deviceTests/opengl/src/com/android/cts/opengl/reference/GLReferenceActivity.java
deleted file mode 100644
index 8d34535..0000000
--- a/suite/cts/deviceTests/opengl/src/com/android/cts/opengl/reference/GLReferenceActivity.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.android.cts.opengl.reference;
-
-import com.android.cts.opengl.GLActivityIntentKeys;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.os.Bundle;
-
-import java.util.concurrent.Semaphore;
-
-public class GLReferenceActivity extends Activity {
-
-    private final static int GAME_ACTIVITY_CODE = 1;
-
-    private volatile Exception mException;
-    private int mNumFrames;
-    private int mTimeout;
-
-    public double[] mSetUpTimes;
-    public double[] mUpdateTimes;
-    public double[] mRenderTimes;
-
-    private Semaphore mSemaphore = new Semaphore(0);
-
-    @Override
-    public void onCreate(Bundle data) {
-        super.onCreate(data);
-        Intent intent = getIntent();
-        mNumFrames = intent.getIntExtra(GLActivityIntentKeys.INTENT_EXTRA_NUM_FRAMES, 0);
-        mTimeout = intent.getIntExtra(GLActivityIntentKeys.INTENT_EXTRA_TIMEOUT, 0);
-
-        // Start benchmark
-        intent = new Intent(this, GLGameActivity.class);
-        intent.putExtra(GLActivityIntentKeys.INTENT_EXTRA_NUM_FRAMES, mNumFrames);
-        intent.putExtra(GLActivityIntentKeys.INTENT_EXTRA_TIMEOUT, mTimeout);
-        startActivityForResult(intent, GAME_ACTIVITY_CODE);
-    }
-
-    public void waitForCompletion() throws Exception {
-        // Wait for semiphore.
-        mSemaphore.acquire();
-        if (mException != null) {
-            throw mException;
-        }
-    }
-
-    private synchronized void setException(Exception e) {
-        if (mException == null) {
-            mException = e;
-        }
-    }
-
-    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
-        if (requestCode == GAME_ACTIVITY_CODE) {
-            if (resultCode == RESULT_OK) {
-                // Benchmark passed
-                mSetUpTimes = data.getDoubleArrayExtra(GLGameActivity.SET_UP_TIME);
-                mUpdateTimes = data.getDoubleArrayExtra(GLGameActivity.UPDATE_TIMES);
-                mRenderTimes = data.getDoubleArrayExtra(GLGameActivity.RENDER_TIMES);
-            } else {
-                setException(new Exception("Benchmark failed to run"));
-            }
-            // Release semiphore.
-            mSemaphore.release();
-            finish();
-        }
-    }
-
-}
diff --git a/suite/cts/deviceTests/opengl/src/com/android/cts/opengl/reference/GLReferenceBenchmark.java b/suite/cts/deviceTests/opengl/src/com/android/cts/opengl/reference/GLReferenceBenchmark.java
deleted file mode 100644
index fdea916..0000000
--- a/suite/cts/deviceTests/opengl/src/com/android/cts/opengl/reference/GLReferenceBenchmark.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.android.cts.opengl.reference;
-
-import com.android.cts.opengl.GLActivityIntentKeys;
-
-import android.cts.util.CtsActivityInstrumentationTestCase2;
-import com.android.cts.util.ResultType;
-import com.android.cts.util.ResultUnit;
-import com.android.cts.util.TimeoutReq;
-
-import android.content.Intent;
-
-/**
- * Runs the Reference OpenGL ES 2.0 Benchmark.
- */
-public class GLReferenceBenchmark extends CtsActivityInstrumentationTestCase2<GLReferenceActivity> {
-
-    private static final int NUM_FRAMES_PER_SCENE = 500;
-    private static final int NUM_SCENES = 2;
-    private static final int NUM_FRAMES = NUM_FRAMES_PER_SCENE * NUM_SCENES;
-    private static final int TIMEOUT = 1000000;
-
-    public GLReferenceBenchmark() {
-        super(GLReferenceActivity.class);
-    }
-
-    /**
-     * Runs the reference benchmark.
-     */
-    @TimeoutReq(minutes = 30)
-    public void testReferenceBenchmark() throws Exception {
-        Intent intent = new Intent();
-        intent.putExtra(GLActivityIntentKeys.INTENT_EXTRA_NUM_FRAMES, NUM_FRAMES);
-        intent.putExtra(GLActivityIntentKeys.INTENT_EXTRA_TIMEOUT, TIMEOUT);
-
-        GLReferenceActivity activity = null;
-        setActivityIntent(intent);
-        activity = getActivity();
-        if (activity != null) {
-            activity.waitForCompletion();
-            double totalTime = 0;
-            double[] setUpTimes = activity.mSetUpTimes;
-            double[] updateTimes = activity.mUpdateTimes;
-            double[] renderTimes = activity.mRenderTimes;
-
-            // Calculate update and render average.
-            double updateSum = updateTimes[0];
-            double renderSum = renderTimes[0];
-            for (int i = 0; i < NUM_FRAMES - 1; i++) {
-                updateSum += updateTimes[i + 1];
-                renderSum += renderTimes[i + 1];
-            }
-            double updateAverage = updateSum / NUM_FRAMES;
-            double renderAverage = renderSum / NUM_FRAMES;
-
-            getReportLog().printArray(
-                    "Set Up Times", setUpTimes, ResultType.LOWER_BETTER, ResultUnit.MS);
-            getReportLog().printArray(
-                    "Update Times", updateTimes, ResultType.LOWER_BETTER, ResultUnit.MS);
-            getReportLog().printValue(
-                    "Update Time Average", updateAverage, ResultType.LOWER_BETTER,
-                    ResultUnit.MS);
-            getReportLog().printArray(
-                    "Render Times", renderTimes, ResultType.LOWER_BETTER, ResultUnit.MS);
-            getReportLog().printValue(
-                    "Render Time Average", renderAverage, ResultType.LOWER_BETTER,
-                    ResultUnit.MS);
-            totalTime = setUpTimes[0] + setUpTimes[1] + setUpTimes[2] +
-                    setUpTimes[3] + updateAverage + renderAverage;
-            getReportLog().printSummary(
-                    "Total Time", totalTime, ResultType.LOWER_BETTER, ResultUnit.MS);
-        }
-    }
-}
diff --git a/suite/cts/deviceTests/opengl/test/Android.mk b/suite/cts/deviceTests/opengl/test/Android.mk
deleted file mode 100644
index 5270bac..0000000
--- a/suite/cts/deviceTests/opengl/test/Android.mk
+++ /dev/null
@@ -1,35 +0,0 @@
-#
-# Copyright (C) 2013 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# build only for linux
-ifeq ($(HOST_OS),linux)
-
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
-
-LOCAL_MODULE_TAGS := optional
-LOCAL_SRC_FILES := $(patsubst ./%,%, $(shell cd $(LOCAL_PATH); \
-  find . -name "*.cpp" -and -not -name ".*"))
-LOCAL_SRC_FILES += ../jni/graphics/Matrix.cpp
-
-#$(info $(LOCAL_SRC_FILES))
-LOCAL_C_INCLUDES += external/gtest/include $(LOCAL_PATH)/../jni/graphics/
-LOCAL_STATIC_LIBRARIES := libgtest_host libgtest_main_host liblog
-LOCAL_LDFLAGS:= -g -lpthread
-LOCAL_MODULE:= cts_device_opengl_test
-include $(BUILD_HOST_EXECUTABLE)
-
-endif # linux
diff --git a/suite/cts/deviceTests/simplecpu/Android.mk b/suite/cts/deviceTests/simplecpu/Android.mk
deleted file mode 100644
index 17e7506..0000000
--- a/suite/cts/deviceTests/simplecpu/Android.mk
+++ /dev/null
@@ -1,36 +0,0 @@
-# Copyright (C) 2012 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-# don't include this package in any target
-LOCAL_MODULE_TAGS := tests
-
-# Include both the 32 and 64 bit versions
-LOCAL_MULTILIB := both
-
-LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctstestrunner
-
-LOCAL_JNI_SHARED_LIBRARIES := libctscpu_jni
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_PACKAGE_NAME := CtsDeviceSimpleCpu
-
-LOCAL_SDK_VERSION := 16
-
-include $(BUILD_CTS_PACKAGE)
-
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/suite/cts/deviceTests/simplecpu/AndroidManifest.xml b/suite/cts/deviceTests/simplecpu/AndroidManifest.xml
deleted file mode 100644
index e5c1c2b..0000000
--- a/suite/cts/deviceTests/simplecpu/AndroidManifest.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-        package="com.android.cts.simplecpu">
-
-    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
-    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
-
-    <application>
-        <uses-library android:name="android.test.runner" />
-    </application>
-    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-            android:targetPackage="com.android.cts.simplecpu"
-            android:label="Very simple CPU benchmarking" />
-</manifest>
diff --git a/suite/cts/deviceTests/simplecpu/jni/CpuNativeJni.cpp b/suite/cts/deviceTests/simplecpu/jni/CpuNativeJni.cpp
deleted file mode 100644
index e0be7f3..0000000
--- a/suite/cts/deviceTests/simplecpu/jni/CpuNativeJni.cpp
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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 <jni.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/time.h>
-
-/* Code from now to qsort_local all copied from bionic source.
- * The code is duplicated here to remove dependency on optimized bionic
- */
-static __inline char    *med3(char *, char *, char *, int (*)(const void *, const void *));
-static __inline void     swapfunc(char *, char *, int, int);
-
-#define min(a, b)   (a) < (b) ? a : b
-
-/*
- * Qsort routine from Bentley & McIlroy's "Engineering a Sort Function".
- */
-#define swapcode(TYPE, parmi, parmj, n) {       \
-    long i = (n) / sizeof (TYPE);           \
-    TYPE *pi = (TYPE *) (parmi);            \
-    TYPE *pj = (TYPE *) (parmj);            \
-    do {                        \
-        TYPE    t = *pi;            \
-        *pi++ = *pj;                \
-        *pj++ = t;              \
-        } while (--i > 0);              \
-}
-
-#define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \
-    es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1;
-
-static __inline void
-swapfunc(char *a, char *b, int n, int swaptype)
-{
-    if (swaptype <= 1)
-        swapcode(long, a, b, n)
-    else
-        swapcode(char, a, b, n)
-}
-
-#define swap(a, b)                  \
-    if (swaptype == 0) {                \
-        long t = *(long *)(a);          \
-        *(long *)(a) = *(long *)(b);        \
-        *(long *)(b) = t;           \
-    } else                      \
-        swapfunc(a, b, es, swaptype)
-
-#define vecswap(a, b, n)    if ((n) > 0) swapfunc(a, b, n, swaptype)
-
-static __inline char *
-med3(char *a, char *b, char *c, int (*cmp)(const void *, const void *))
-{
-    return cmp(a, b) < 0 ?
-           (cmp(b, c) < 0 ? b : (cmp(a, c) < 0 ? c : a ))
-              :(cmp(b, c) > 0 ? b : (cmp(a, c) < 0 ? a : c ));
-}
-
-void
-qsort_local(void *aa, size_t n, size_t es, int (*cmp)(const void *, const void *))
-{
-    char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
-    int d, r, swaptype, swap_cnt;
-    char *a = (char*)aa;
-
-loop:   SWAPINIT(a, es);
-    swap_cnt = 0;
-    if (n < 7) {
-        for (pm = (char *)a + es; pm < (char *) a + n * es; pm += es)
-            for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0;
-                 pl -= es)
-                swap(pl, pl - es);
-        return;
-    }
-    pm = (char *)a + (n / 2) * es;
-    if (n > 7) {
-        pl = (char *)a;
-        pn = (char *)a + (n - 1) * es;
-        if (n > 40) {
-            d = (n / 8) * es;
-            pl = med3(pl, pl + d, pl + 2 * d, cmp);
-            pm = med3(pm - d, pm, pm + d, cmp);
-            pn = med3(pn - 2 * d, pn - d, pn, cmp);
-        }
-        pm = med3(pl, pm, pn, cmp);
-    }
-    swap(a, pm);
-    pa = pb = (char *)a + es;
-
-    pc = pd = (char *)a + (n - 1) * es;
-    for (;;) {
-        while (pb <= pc && (r = cmp(pb, a)) <= 0) {
-            if (r == 0) {
-                swap_cnt = 1;
-                swap(pa, pb);
-                pa += es;
-            }
-            pb += es;
-        }
-        while (pb <= pc && (r = cmp(pc, a)) >= 0) {
-            if (r == 0) {
-                swap_cnt = 1;
-                swap(pc, pd);
-                pd -= es;
-            }
-            pc -= es;
-        }
-        if (pb > pc)
-            break;
-        swap(pb, pc);
-        swap_cnt = 1;
-        pb += es;
-        pc -= es;
-    }
-    if (swap_cnt == 0) {  /* Switch to insertion sort */
-        for (pm = (char *) a + es; pm < (char *) a + n * es; pm += es)
-            for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0;
-                 pl -= es)
-                swap(pl, pl - es);
-        return;
-    }
-
-    pn = (char *)a + n * es;
-    r = min(pa - (char *)a, pb - pa);
-    vecswap(a, pb - r, r);
-    r = min(pd - pc, pn - pd - (int)es);
-    vecswap(pb, pn - r, r);
-    if ((r = pb - pa) > (int)es)
-        qsort_local(a, r / es, es, cmp);
-    if ((r = pd - pc) > (int)es) {
-        /* Iterate rather than recurse to save stack space */
-        a = pn - r;
-        n = r / es;
-        goto loop;
-    }
-    /* qsort(pn - r, r / es, es, cmp); */
-}
-
-/* code duplication ends here */
-
-/**
- * Util for getting time stamp
- */
-double currentTimeMillis()
-{
-    struct timeval tv;
-    gettimeofday(&tv, (struct timezone *) NULL);
-    return tv.tv_sec * 1000.0 + tv.tv_usec / 1000.0;
-}
-
-/**
- * Initialize given array randomly for the given seed
- */
-template <typename T> void randomInitArray(T* array, int len, unsigned int seed)
-{
-    srand(seed);
-    for (int i = 0; i < len; i++) {
-        array[i] = (T) rand();
-    }
-}
-
-/**
- * comparison function for int, for qsort
- */
-int cmpint(const void* p1, const void* p2)
-{
-    return *(int*)p1 - *(int*)p2;
-}
-
-extern "C" JNIEXPORT jdouble JNICALL Java_com_android_cts_simplecpu_CpuNative_runSort(JNIEnv* env,
-        jclass clazz, jint numberElements, jint repetition)
-{
-    int* data = new int[numberElements];
-    if (data == NULL) {
-        env->ThrowNew(env->FindClass("java/lang/OutOfMemoryError"), "No memory");
-        return -1;
-    }
-    double totalTime = 0;
-    for (int i = 0; i < repetition; i++) {
-        randomInitArray<int>(data, numberElements, 0);
-        double start = currentTimeMillis();
-        qsort_local(data, numberElements, sizeof(int), cmpint);
-        double end = currentTimeMillis();
-        totalTime += (end - start);
-    }
-    delete[] data;
-    return totalTime;
-}
-
-
-/**
- * Do matrix multiplication, C = A x B with all matrices having dimension of n x n
- * The implementation is not in the most efficient, but it is good enough for benchmarking purpose.
- * @param n should be multiple of 8
- */
-void doMatrixMultiplication(float* A, float* B, float* C, int n)
-{
-    // batch size
-    const int M = 8;
-    for (int i = 0; i < n; i++) {
-        for (int j = 0; j < n; j += M) {
-            float sum[M];
-            for (int k = 0; k < M; k++) {
-                sum[k] = 0;
-            }
-            // re-use the whole cache line for accessing B.
-            // otherwise, the whole line will be read and only one value will be used.
-
-            for (int k = 0; k < n; k++) {
-                float a = A[i * n + k];
-                sum[0] += a * B[k * n + j];
-                sum[1] += a * B[k * n + j + 1];
-                sum[2] += a * B[k * n + j + 2];
-                sum[3] += a * B[k * n + j + 3];
-                sum[4] += a * B[k * n + j + 4];
-                sum[5] += a * B[k * n + j + 5];
-                sum[6] += a * B[k * n + j + 6];
-                sum[7] += a * B[k * n + j + 7];
-            }
-            for (int k = 0; k < M; k++) {
-                C[i * n + j + k] = sum[k];
-            }
-        }
-    }
-}
-
-extern "C" JNIEXPORT jdouble JNICALL Java_com_android_cts_simplecpu_CpuNative_runMatrixMultiplication(
-        JNIEnv* env, jclass clazz, jint n, jint repetition)
-{
-    // C = A x B
-    float* A = new float[n * n];
-    float* B = new float[n * n];
-    float* C = new float[n * n];
-    if ((A == NULL) || (B == NULL) || (C == NULL)) {
-        delete[] A;
-        delete[] B;
-        delete[] C;
-        env->ThrowNew(env->FindClass("java/lang/OutOfMemoryError"), "No memory");
-        return -1;
-    }
-    double totalTime = 0;
-    for (int i = 0; i < repetition; i++) {
-        randomInitArray<float>(A, n * n, 0);
-        randomInitArray<float>(B, n * n, 1);
-        double start = currentTimeMillis();
-        doMatrixMultiplication(A, B, C, n);
-        double end = currentTimeMillis();
-        totalTime += (end - start);
-    }
-    delete[] A;
-    delete[] B;
-    delete[] C;
-    return totalTime;
-}
-
diff --git a/suite/cts/deviceTests/simplecpu/src/com/android/cts/simplecpu/CpuNative.java b/suite/cts/deviceTests/simplecpu/src/com/android/cts/simplecpu/CpuNative.java
deleted file mode 100644
index 8b48623..0000000
--- a/suite/cts/deviceTests/simplecpu/src/com/android/cts/simplecpu/CpuNative.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.simplecpu;
-
-public class CpuNative {
-    static {
-        System.loadLibrary("ctscpu_jni");
-    }
-    /**
-     * run qsort for given number of repetition
-     * with each having the size of bufferSize.
-     * @param numberElements
-     * @param repeatition
-     * @return time taken for computation, added for all repetition in ms
-     */
-    public static native double runSort(int numberElements, int repetition);
-
-    /**
-     * run matrix multiplication of (n x n) x (n x n)
-     *
-     * @param n dimension, should be multiple of 8
-     * @param repetition
-     * @return time taken for computation, added for all repetition in ms
-     */
-    public static native double runMatrixMultiplication(int n, int repetition);
-}
diff --git a/suite/cts/deviceTests/simplecpu/src/com/android/cts/simplecpu/SimpleCpuTest.java b/suite/cts/deviceTests/simplecpu/src/com/android/cts/simplecpu/SimpleCpuTest.java
deleted file mode 100644
index ce0feac..0000000
--- a/suite/cts/deviceTests/simplecpu/src/com/android/cts/simplecpu/SimpleCpuTest.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.simplecpu;
-
-import android.util.Log;
-
-import com.android.cts.util.ResultType;
-import com.android.cts.util.ResultUnit;
-import android.cts.util.CtsAndroidTestCase;
-import com.android.cts.util.Stat;
-import com.android.cts.util.TimeoutReq;
-
-/**
- * Very simple CPU benchmarking to check the basic capability of CPU.
- * Cases include
- *   qsort
- *   matrix multiplication (for floating point performance)
- */
-public class SimpleCpuTest extends CtsAndroidTestCase {
-    private static final String TAG = "BandwidthTest";
-    private static final int KB = 1024;
-    private static final int MB = 1024 * 1024;
-    private static final int NUMBER_REPEAT = 20;
-    // reject data outside +/- this value * median
-    private static final double OUTLIER_THRESHOLD = 0.1;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        warmUpCpu();
-    }
-
-    public void testSort004KB() {
-        doTestSort(NUMBER_REPEAT, 4 * KB);
-    }
-
-    public void testSort128KB() {
-        doTestSort(NUMBER_REPEAT, 128 * KB);
-    }
-
-    public void testSort001MB() {
-        doTestSort(NUMBER_REPEAT, 1 * MB);
-    }
-
-    // will fit into L1
-    public void testMatrixMultiplication032() {
-        doMatrixMultiplication(NUMBER_REPEAT, 32);
-    }
-
-    // mostly fit into L2
-    public void testMatrixMultiplication128() {
-        doMatrixMultiplication(NUMBER_REPEAT, 128);
-    }
-
-    // may fit into L2
-    public void testMatrixMultiplication200() {
-        doMatrixMultiplication(NUMBER_REPEAT, 200);
-    }
-
-    public void testMatrixMultiplication400() {
-        doMatrixMultiplication(NUMBER_REPEAT, 400);
-    }
-
-    // will exceed L2
-    @TimeoutReq(minutes = 30)
-    public void testMatrixMultiplication600() {
-        doMatrixMultiplication(NUMBER_REPEAT, 600);
-    }
-
-    /**
-     * run some code to force full CPU freq.
-     */
-    private void warmUpCpu() {
-        CpuNative.runSort(1 * MB, 10);
-    }
-
-    /**
-     * qsort test
-     * @param numberRepeat
-     * @param arrayLength
-     */
-    private void doTestSort(int numberRepeat, int arrayLength) {
-        final int numberRepeatInEachCall = 10;
-        double[] result = new double[numberRepeat];
-        for (int i = 0; i < numberRepeat; i++) {
-            result[i] = CpuNative.runSort(arrayLength, numberRepeatInEachCall);
-        }
-        getReportLog().printArray("sorting time", result, ResultType.LOWER_BETTER,
-                ResultUnit.MS);
-        Stat.StatResult stat = Stat.getStatWithOutlierRejection(result, OUTLIER_THRESHOLD);
-        if (stat.mDataCount != result.length) {
-            Log.w(TAG, "rejecting " + (result.length - stat.mDataCount) + " outliers");
-        }
-        getReportLog().printSummary("sorting time", stat.mAverage, ResultType.LOWER_BETTER,
-                ResultUnit.MS);
-    }
-
-    /**
-     * Matrix multiplication test, nxn matrix multiplication
-     * @param numberRepeat
-     * @param n should be multiple of 8
-     */
-    private void doMatrixMultiplication(int numberRepeat, int n) {
-        assertTrue(n % 8 == 0);
-        final int numberRepeatInEachCall = 10;
-        double[] result = new double[numberRepeat];
-        for (int i = 0; i < numberRepeat; i++) {
-            result[i] = CpuNative.runMatrixMultiplication(n, numberRepeatInEachCall);
-        }
-        getReportLog().printArray("matrix mutiplication time", result, ResultType.LOWER_BETTER,
-                ResultUnit.MS);
-        Stat.StatResult stat = Stat.getStatWithOutlierRejection(result, OUTLIER_THRESHOLD);
-        if (stat.mDataCount != result.length) {
-            Log.w(TAG, "rejecting " + (result.length - stat.mDataCount) + " outliers");
-        }
-        getReportLog().printSummary("matrix mutiplication time", stat.mAverage,
-                ResultType.LOWER_BETTER, ResultUnit.MS);
-    }
-
-}
diff --git a/suite/cts/deviceTests/tvproviderperf/Android.mk b/suite/cts/deviceTests/tvproviderperf/Android.mk
deleted file mode 100644
index e268955..0000000
--- a/suite/cts/deviceTests/tvproviderperf/Android.mk
+++ /dev/null
@@ -1,30 +0,0 @@
-# Copyright (C) 2014 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-# don't include this package in any target
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctstestrunner
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_PACKAGE_NAME := CtsDeviceTvProviderPerf
-
-LOCAL_SDK_VERSION := current
-
-include $(BUILD_CTS_PACKAGE)
-
diff --git a/suite/cts/deviceTests/tvproviderperf/AndroidManifest.xml b/suite/cts/deviceTests/tvproviderperf/AndroidManifest.xml
deleted file mode 100644
index d345ab2..0000000
--- a/suite/cts/deviceTests/tvproviderperf/AndroidManifest.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-        package="com.android.cts.tvproviderperf">
-
-    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
-    <uses-permission android:name="com.android.providers.tv.permission.READ_EPG_DATA" />
-    <uses-permission android:name="com.android.providers.tv.permission.WRITE_EPG_DATA" />
-
-    <application>
-        <uses-library android:name="android.test.runner" />
-    </application>
-
-    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-            android:targetPackage="com.android.cts.tvproviderperf"
-            android:label="TvProvider performance measurement" />
-</manifest>
diff --git a/suite/cts/deviceTests/tvproviderperf/src/com/android/cts/tvproviderperf/TvProviderPerfTest.java b/suite/cts/deviceTests/tvproviderperf/src/com/android/cts/tvproviderperf/TvProviderPerfTest.java
deleted file mode 100644
index 8eef86d..0000000
--- a/suite/cts/deviceTests/tvproviderperf/src/com/android/cts/tvproviderperf/TvProviderPerfTest.java
+++ /dev/null
@@ -1,375 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.tvproviderperf;
-
-import android.content.ComponentName;
-import android.content.ContentProviderOperation;
-import android.content.ContentProviderResult;
-import android.content.ContentResolver;
-import android.content.ContentUris;
-import android.content.ContentValues;
-import android.content.OperationApplicationException;
-import android.content.pm.PackageManager;
-import android.database.Cursor;
-import android.cts.util.CtsAndroidTestCase;
-import android.media.tv.TvContract;
-import android.media.tv.TvContract.Channels;
-import android.media.tv.TvContract.Programs;
-import android.net.Uri;
-import android.os.RemoteException;
-
-import com.android.cts.util.MeasureRun;
-import com.android.cts.util.MeasureTime;
-import com.android.cts.util.ResultType;
-import com.android.cts.util.ResultUnit;
-import com.android.cts.util.ReportLog;
-import com.android.cts.util.TimeoutReq;
-import com.android.cts.util.Stat;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Test performance of TvProvider on a device. TvProvider typically handles hundreds of
- * thousands of records periodically, so it is desirable to have performance under a reasonable
- * bar.
- */
-public class TvProviderPerfTest extends CtsAndroidTestCase {
-    private static final int TRANSACTION_RUNS = 100;
-    private static final int QUERY_RUNS = 10;
-
-    private ContentResolver mContentResolver;
-    private String mInputId;
-    private boolean mHasTvInputFramework;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mHasTvInputFramework = getContext().getPackageManager().hasSystemFeature(
-                PackageManager.FEATURE_LIVE_TV);
-        if (!mHasTvInputFramework) return;
-        mContentResolver = getContext().getContentResolver();
-        mInputId = TvContract.buildInputId(new ComponentName(getContext(), getClass()));
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        try {
-            if (!mHasTvInputFramework) return;
-            mContentResolver.delete(Programs.CONTENT_URI, null, null);
-            mContentResolver.delete(Channels.CONTENT_URI, null, null);
-        } finally {
-            super.tearDown();
-        }
-    }
-
-    @TimeoutReq(minutes = 8)
-    public void testChannels() throws Exception {
-        if (!mHasTvInputFramework) return;
-        double[] averages = new double[5];
-
-        // Insert
-        final ArrayList<ContentProviderOperation> operations = new ArrayList<>();
-        final int TRANSACTION_SIZE = 1000;
-        double[] applyBatchTimes = MeasureTime.measure(TRANSACTION_RUNS, new MeasureRun() {
-            @Override
-            public void run(int i) {
-                operations.clear();
-                for (int j = 0; j < TRANSACTION_SIZE; ++j) {
-                    ContentValues values = new ContentValues();
-                    values.put(Channels.COLUMN_INPUT_ID, mInputId);
-                    values.put(Channels.COLUMN_SERVICE_TYPE,
-                            Channels.SERVICE_TYPE_AUDIO_VIDEO);
-                    values.put(Channels.COLUMN_TYPE, Channels.TYPE_OTHER);
-                    operations.add(
-                            ContentProviderOperation.newInsert(Channels.CONTENT_URI)
-                            .withValues(values).build());
-                }
-                try {
-                    mContentResolver.applyBatch(TvContract.AUTHORITY, operations);
-                } catch (OperationApplicationException | RemoteException e) {
-                    throw new RuntimeException(e);
-                }
-            }
-        });
-        getReportLog().printArray("Elapsed time for insert: ",
-                applyBatchTimes, ResultType.LOWER_BETTER, ResultUnit.MS);
-        averages[0] = Stat.getAverage(applyBatchTimes);
-
-        // Update
-        final String[] projection = { Channels._ID };
-        try (final Cursor cursor = mContentResolver.query(Channels.CONTENT_URI,
-                projection, null, null, null)) {
-            applyBatchTimes = MeasureTime.measure(TRANSACTION_RUNS, new MeasureRun() {
-                @Override
-                public void run(int i) {
-                    operations.clear();
-                    for (int j = 0; j < TRANSACTION_SIZE && cursor.moveToNext(); ++j) {
-                        Uri channelUri = TvContract.buildChannelUri(cursor.getLong(0));
-                        String number = Integer.toString(i * TRANSACTION_SIZE + j);
-                        operations.add(
-                                ContentProviderOperation.newUpdate(channelUri)
-                                .withValue(Channels.COLUMN_DISPLAY_NUMBER, number)
-                                .build());
-                    }
-                    try {
-                        mContentResolver.applyBatch(TvContract.AUTHORITY, operations);
-                    } catch (OperationApplicationException | RemoteException e) {
-                        throw new RuntimeException(e);
-                    }
-                }
-            });
-        }
-        getReportLog().printArray("Elapsed time for update: ",
-                applyBatchTimes, ResultType.LOWER_BETTER, ResultUnit.MS);
-        averages[1] = Stat.getAverage(applyBatchTimes);
-
-        // Query channels
-        applyBatchTimes = MeasureTime.measure(QUERY_RUNS, new MeasureRun() {
-            @Override
-            public void run(int i) {
-                try (Cursor cursor = mContentResolver.query(Channels.CONTENT_URI, null, null,
-                        null, null)) {
-                    while (cursor.moveToNext()) {
-                        // Do nothing. Just iterate all the items.
-                    }
-                }
-            }
-        });
-        getReportLog().printArray("Elapsed time for query (channels): ",
-                applyBatchTimes, ResultType.LOWER_BETTER, ResultUnit.MS);
-        averages[2] = Stat.getAverage(applyBatchTimes);
-
-        // Query a channel
-        try (final Cursor cursor = mContentResolver.query(Channels.CONTENT_URI,
-                projection, null, null, null)) {
-            applyBatchTimes = MeasureTime.measure(QUERY_RUNS, new MeasureRun() {
-                @Override
-                public void run(int i) {
-                    assertTrue(cursor.moveToNext());
-                    try (Cursor c = mContentResolver.query(TvContract.buildChannelUri(
-                            cursor.getLong(0)), null, null, null, null)) {
-                        while (c.moveToNext()) {
-                            // Do nothing. Just iterate all the items.
-                        }
-                    }
-                }
-            });
-        }
-        getReportLog().printArray("Elapsed time for query (a channel): ",
-                applyBatchTimes, ResultType.LOWER_BETTER, ResultUnit.MS);
-        averages[3] = Stat.getAverage(applyBatchTimes);
-
-        // Delete
-        applyBatchTimes = MeasureTime.measure(1, new MeasureRun() {
-            @Override
-            public void run(int i) {
-                mContentResolver.delete(TvContract.buildChannelsUriForInput(mInputId), null, null);
-            }
-        });
-        getReportLog().printArray("Elapsed time for delete: ",
-                applyBatchTimes, ResultType.LOWER_BETTER, ResultUnit.MS);
-        averages[4] = Stat.getAverage(applyBatchTimes);
-
-        getReportLog().printArray("Average elapsed time for insert, update, query (channels), "
-                + "query (a channel), delete: ",
-                averages, ResultType.LOWER_BETTER, ResultUnit.MS);
-    }
-
-    @TimeoutReq(minutes = 12)
-    public void testPrograms() throws Exception {
-        if (!mHasTvInputFramework) return;
-        double[] averages = new double[7];
-
-        // Prepare (insert channels)
-        final ArrayList<ContentProviderOperation> operations = new ArrayList<>();
-        final int TRANSACTION_SIZE = 1000;
-        final int NUM_CHANNELS = 100;
-        final List<Uri> channelUris = new ArrayList<>();
-
-        operations.clear();
-        for (int i = 0; i < NUM_CHANNELS; ++i) {
-            ContentValues values = new ContentValues();
-            values.put(Channels.COLUMN_INPUT_ID, mInputId);
-            values.put(Channels.COLUMN_SERVICE_TYPE,
-                    Channels.SERVICE_TYPE_AUDIO_VIDEO);
-            values.put(Channels.COLUMN_TYPE, Channels.TYPE_OTHER);
-            operations.add(
-                    ContentProviderOperation.newInsert(Channels.CONTENT_URI)
-                    .withValues(values).build());
-        }
-        try {
-            ContentProviderResult[] results =
-                    mContentResolver.applyBatch(TvContract.AUTHORITY, operations);
-            for (ContentProviderResult result : results) {
-                channelUris.add(result.uri);
-            }
-        } catch (OperationApplicationException | RemoteException e) {
-            throw new RuntimeException(e);
-        }
-
-        // Insert
-        double[] applyBatchTimes = MeasureTime.measure(NUM_CHANNELS, new MeasureRun() {
-            @Override
-            public void run(int i) {
-                operations.clear();
-                Uri channelUri = channelUris.get(i);
-                long channelId = ContentUris.parseId(channelUri);
-                for (int j = 0; j < TRANSACTION_SIZE; ++j) {
-                    ContentValues values = new ContentValues();
-                    values.put(Programs.COLUMN_CHANNEL_ID, channelId);
-                    operations.add(
-                            ContentProviderOperation.newInsert(Programs.CONTENT_URI)
-                            .withValues(values).build());
-                }
-                try {
-                    mContentResolver.applyBatch(TvContract.AUTHORITY, operations);
-                } catch (OperationApplicationException | RemoteException e) {
-                    throw new RuntimeException(e);
-                }
-            }
-        });
-        getReportLog().printArray("Elapsed time for insert: ",
-                applyBatchTimes, ResultType.LOWER_BETTER, ResultUnit.MS);
-        averages[0] = Stat.getAverage(applyBatchTimes);
-
-        // Update
-        final long PROGRAM_DURATION_MS = 60 * 1000;
-        final String[] projection = { Programs._ID };
-        applyBatchTimes = MeasureTime.measure(NUM_CHANNELS, new MeasureRun() {
-            @Override
-            public void run(int i) {
-                Uri channelUri = channelUris.get(i);
-                operations.clear();
-                try (Cursor cursor = mContentResolver.query(
-                        TvContract.buildProgramsUriForChannel(channelUri),
-                        projection, null, null, null)) {
-                    long startTimeMs = 0;
-                    long endTimeMs = 0;
-                    while (cursor.moveToNext()) {
-                        Uri programUri = TvContract.buildProgramUri(cursor.getLong(0));
-                        endTimeMs += PROGRAM_DURATION_MS;
-                        operations.add(
-                                ContentProviderOperation.newUpdate(programUri)
-                                .withValue(Programs.COLUMN_START_TIME_UTC_MILLIS, startTimeMs)
-                                .withValue(Programs.COLUMN_END_TIME_UTC_MILLIS, endTimeMs)
-                                .build());
-                        startTimeMs = endTimeMs;
-                    }
-                }
-                try {
-                    mContentResolver.applyBatch(TvContract.AUTHORITY, operations);
-                } catch (OperationApplicationException | RemoteException e) {
-                    throw new RuntimeException(e);
-                }
-            }
-        });
-        getReportLog().printArray("Elapsed time for update: ",
-                applyBatchTimes, ResultType.LOWER_BETTER, ResultUnit.MS);
-        averages[1] = Stat.getAverage(applyBatchTimes);
-
-        // Query programs
-        applyBatchTimes = MeasureTime.measure(QUERY_RUNS, new MeasureRun() {
-            @Override
-            public void run(int i) {
-                try (Cursor cursor = mContentResolver.query(Programs.CONTENT_URI, null, null,
-                        null, null)) {
-                    while (cursor.moveToNext()) {
-                        // Do nothing. Just iterate all the items.
-                    }
-                }
-            }
-        });
-        getReportLog().printArray("Elapsed time for query (programs): ",
-                applyBatchTimes, ResultType.LOWER_BETTER, ResultUnit.MS);
-        averages[2] = Stat.getAverage(applyBatchTimes);
-
-        // Query programs with selection
-        applyBatchTimes = MeasureTime.measure(QUERY_RUNS, new MeasureRun() {
-            @Override
-            public void run(int i) {
-                Uri channelUri = channelUris.get(i);
-                try (Cursor cursor = mContentResolver.query(
-                        TvContract.buildProgramsUriForChannel(
-                                channelUri, 0,
-                                PROGRAM_DURATION_MS * TRANSACTION_SIZE / 2),
-                        null, null, null, null)) {
-                    while (cursor.moveToNext()) {
-                        // Do nothing. Just iterate all the items.
-                    }
-                }
-            }
-        });
-        getReportLog().printArray("Elapsed time for query (programs with selection): ",
-                applyBatchTimes, ResultType.LOWER_BETTER, ResultUnit.MS);
-        averages[3] = Stat.getAverage(applyBatchTimes);
-
-        // Query a program
-        try (final Cursor cursor = mContentResolver.query(Programs.CONTENT_URI,
-                projection, null, null, null)) {
-            applyBatchTimes = MeasureTime.measure(QUERY_RUNS, new MeasureRun() {
-                @Override
-                public void run(int i) {
-                    assertTrue(cursor.moveToNext());
-                    try (Cursor c = mContentResolver.query(TvContract.buildProgramUri(
-                            cursor.getLong(0)), null, null, null, null)) {
-                        while (c.moveToNext()) {
-                            // Do nothing. Just iterate all the items.
-                        }
-                    }
-                }
-            });
-        }
-        getReportLog().printArray("Elapsed time for query (a program): ",
-                applyBatchTimes, ResultType.LOWER_BETTER, ResultUnit.MS);
-        averages[4] = Stat.getAverage(applyBatchTimes);
-
-        // Delete programs
-        applyBatchTimes = MeasureTime.measure(NUM_CHANNELS, new MeasureRun() {
-            @Override
-            public void run(int i) {
-                Uri channelUri = channelUris.get(i);
-                mContentResolver.delete(
-                        TvContract.buildProgramsUriForChannel(
-                                channelUri,
-                                PROGRAM_DURATION_MS * TRANSACTION_SIZE / 2,
-                                PROGRAM_DURATION_MS * TRANSACTION_SIZE),
-                        null, null);
-            }
-        });
-        getReportLog().printArray("Elapsed time for delete programs: ",
-                applyBatchTimes, ResultType.LOWER_BETTER, ResultUnit.MS);
-        averages[5] = Stat.getAverage(applyBatchTimes);
-
-        // Delete channels
-        applyBatchTimes = MeasureTime.measure(NUM_CHANNELS, new MeasureRun() {
-            @Override
-            public void run(int i) {
-                Uri channelUri = channelUris.get(i);
-                mContentResolver.delete(channelUri, null, null);
-            }
-        });
-        getReportLog().printArray("Elapsed time for delete channels: ",
-                applyBatchTimes, ResultType.LOWER_BETTER, ResultUnit.MS);
-        averages[6] = Stat.getAverage(applyBatchTimes);
-
-        getReportLog().printArray("Average elapsed time for insert, update, query (programs), "
-                + "query (programs with selection), query (a channel), delete (channels), "
-                + "delete (programs): ",
-                averages, ResultType.LOWER_BETTER, ResultUnit.MS);
-    }
-}
diff --git a/suite/cts/deviceTests/ui/Android.mk b/suite/cts/deviceTests/ui/Android.mk
deleted file mode 100644
index ee52172..0000000
--- a/suite/cts/deviceTests/ui/Android.mk
+++ /dev/null
@@ -1,33 +0,0 @@
-# Copyright (C) 2012 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-# don't include this package in any target
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-
-LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctstestrunner
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_PACKAGE_NAME := CtsDeviceUi
-
-LOCAL_SDK_VERSION := 16
-
-include $(BUILD_CTS_PACKAGE)
-
-
diff --git a/suite/cts/deviceTests/ui/AndroidManifest.xml b/suite/cts/deviceTests/ui/AndroidManifest.xml
deleted file mode 100644
index b41008e7..0000000
--- a/suite/cts/deviceTests/ui/AndroidManifest.xml
+++ /dev/null
@@ -1,47 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2012 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.ui" >
-
-    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
-    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
-
-    <application>
-        <uses-library android:name="android.test.runner" />
-
-        <activity
-            android:name=".ScrollingActivity"
-            android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode" >
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-    </application>
-
-    <instrumentation
-        android:name="android.support.test.runner.AndroidJUnitRunner"
-        android:label="UI Latency measurement"
-        android:targetPackage="com.android.cts.ui" >
-        <meta-data
-            android:name="listener"
-            android:value="com.android.cts.runner.CtsTestRunListener" />
-    </instrumentation>
-
-</manifest>
diff --git a/suite/cts/deviceTests/ui/src/com/android/cts/ui/ScrollingActivity.java b/suite/cts/deviceTests/ui/src/com/android/cts/ui/ScrollingActivity.java
deleted file mode 100644
index 2229e97..0000000
--- a/suite/cts/deviceTests/ui/src/com/android/cts/ui/ScrollingActivity.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.ui;
-
-import android.app.ListActivity;
-import android.os.Bundle;
-import android.widget.AbsListView;
-import android.widget.AbsListView.OnScrollListener;
-import android.widget.ArrayAdapter;
-import android.widget.ListView;
-
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Activity for measuring scrolling time of long list.
- */
-public class ScrollingActivity extends ListActivity implements OnScrollListener {
-    static final String TAG = "ScrollingActivity";
-    private static final String NUM_ELEMENTS_EXTRA = "num_elements";
-    private static final int NUM_ELEMENTS_DEFAULT = 10000;
-    private static final int SCROLL_TIME_IN_MS = 1;
-    private static final int WAIT_TIMEOUT_IN_SECS = 5 * 60;
-    private String[] mItems;
-    private CountDownLatch mLatchStop = null;
-    private int mTargetLoc;
-    private int mNumElements;
-
-    public void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-        mNumElements = getIntent().getIntExtra(NUM_ELEMENTS_EXTRA, NUM_ELEMENTS_DEFAULT);
-        mItems = new String[mNumElements];
-        for (int i = 0; i < mNumElements; i++) {
-            mItems[i] = Integer.toString(i);
-        }
-        setListAdapter(new ArrayAdapter<String>(this,
-                android.R.layout.simple_list_item_1, mItems));
-        ListView view = getListView();
-        view.setOnScrollListener(this);
-    }
-
-    public boolean scrollToTop() {
-        return doScroll(0);
-    }
-    public boolean scrollToBottom() {
-        return doScroll(mNumElements - 1);
-    }
-
-    private boolean doScroll(final int loc) {
-        mLatchStop = new CountDownLatch(1);
-        mTargetLoc = loc;
-        final ListView view = getListView();
-        runOnUiThread( new Runnable() {
-            @Override
-            public void run() {
-                view.smoothScrollToPositionFromTop(loc, 0, SCROLL_TIME_IN_MS);
-            }
-        });
-        boolean result = false;
-        try {
-            result = mLatchStop.await(WAIT_TIMEOUT_IN_SECS, TimeUnit.SECONDS);
-        } catch (InterruptedException e) {
-            // ignore
-        }
-        mLatchStop = null;
-        return result;
-    }
-
-    @Override
-    public void onScrollStateChanged(AbsListView view, int scrollState) {
-
-    }
-
-    @Override
-    public void onScroll(AbsListView view, int firstVisibleItem,
-            int visibleItemCount, int totalItemCount) {
-        //Log.i(TAG, "onScroll " + firstVisibleItem + " " + visibleItemCount);
-        if ((mTargetLoc >= firstVisibleItem) &&
-                (mTargetLoc <= (firstVisibleItem + visibleItemCount))) {
-            if (mLatchStop != null) {
-                mLatchStop.countDown();
-            }
-        }
-    }
-}
diff --git a/suite/cts/deviceTests/ui/src/com/android/cts/ui/ScrollingTest.java b/suite/cts/deviceTests/ui/src/com/android/cts/ui/ScrollingTest.java
deleted file mode 100644
index b5b40e4..0000000
--- a/suite/cts/deviceTests/ui/src/com/android/cts/ui/ScrollingTest.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.cts.ui;
-
-import com.android.cts.util.MeasureRun;
-import com.android.cts.util.MeasureTime;
-import com.android.cts.util.ResultType;
-import com.android.cts.util.ResultUnit;
-import android.cts.util.CtsActivityInstrumentationTestCase2;
-import com.android.cts.util.Stat;
-import com.android.cts.util.TimeoutReq;
-
-import java.io.IOException;
-
-public class ScrollingTest extends CtsActivityInstrumentationTestCase2<ScrollingActivity> {
-    private ScrollingActivity mActivity;
-
-    public ScrollingTest() {
-        super(ScrollingActivity.class);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mActivity = getActivity();
-        getInstrumentation().waitForIdleSync();
-        try {
-            runTestOnUiThread(new Runnable() {
-                public void run() {
-                }
-            });
-        } catch (Throwable e) {
-            e.printStackTrace();
-            fail();
-        }
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        mActivity = null;
-        super.tearDown();
-    }
-
-    @TimeoutReq(minutes = 30)
-    public void testFullScrolling() throws Exception {
-        final int NUMBER_REPEAT = 10;
-        final ScrollingActivity activity = mActivity;
-        double[] results = MeasureTime.measure(NUMBER_REPEAT, new MeasureRun() {
-
-            @Override
-            public void run(int i) throws IOException {
-                assertTrue(activity.scrollToBottom());
-                assertTrue(activity.scrollToTop());
-            }
-        });
-        getReportLog().printArray("scrolling time", results, ResultType.LOWER_BETTER,
-                ResultUnit.MS);
-        Stat.StatResult stat = Stat.getStat(results);
-        getReportLog().printSummary("scrolling time", stat.mAverage, ResultType.LOWER_BETTER,
-                ResultUnit.MS);
-    }
-}
diff --git a/suite/cts/deviceTests/videoperf/Android.mk b/suite/cts/deviceTests/videoperf/Android.mk
deleted file mode 100644
index b589475..0000000
--- a/suite/cts/deviceTests/videoperf/Android.mk
+++ /dev/null
@@ -1,39 +0,0 @@
-# Copyright (C) 2013 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-# don't include this package in any target
-LOCAL_MODULE_TAGS := optional
-# and when built explicitly put it in the data partition
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-
-# include both the 32 and 64 bit versions
-LOCAL_MULTILIB := both
-
-LOCAL_STATIC_JAVA_LIBRARIES := ctsmediautil ctsdeviceutil ctstestrunner
-
-LOCAL_JNI_SHARED_LIBRARIES := libctsmediacodec_jni
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_PACKAGE_NAME := CtsDeviceVideoPerf
-
-LOCAL_SDK_VERSION := current
-
-cts_runtime_hint := 50
-
-include $(BUILD_CTS_PACKAGE)
-
diff --git a/suite/cts/deviceTests/videoperf/AndroidManifest.xml b/suite/cts/deviceTests/videoperf/AndroidManifest.xml
deleted file mode 100644
index ca01298b..0000000
--- a/suite/cts/deviceTests/videoperf/AndroidManifest.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-        package="com.android.cts.videoperf">
-
-    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
-    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
-
-    <application>
-        <uses-library android:name="android.test.runner" />
-    </application>
-    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-            android:targetPackage="com.android.cts.videoperf"
-            android:label="UI Latency measurement" >
-        <meta-data
-            android:name="listener"
-            android:value="com.android.cts.runner.CtsTestRunListener" />
-    </instrumentation>
-</manifest>
diff --git a/suite/cts/deviceTests/videoperf/src/com/android/cts/videoperf/CodecInfo.java b/suite/cts/deviceTests/videoperf/src/com/android/cts/videoperf/CodecInfo.java
deleted file mode 100644
index ccb3126..0000000
--- a/suite/cts/deviceTests/videoperf/src/com/android/cts/videoperf/CodecInfo.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.videoperf;
-
-import android.media.MediaCodec;
-import android.media.MediaCodecInfo;
-import android.media.MediaCodecInfo.CodecCapabilities;
-import android.media.MediaCodecInfo.CodecProfileLevel;
-import android.media.MediaCodecInfo.VideoCapabilities;
-import android.media.MediaCodecList;
-import android.media.MediaFormat;
-import android.util.Log;
-import android.util.Range;
-
-import java.io.IOException;
-
-/**
- * Utility class for getting codec information like bit rate, fps, and etc.
- * Uses public member variables instead of methods as this code is only for video benchmarking.
- */
-public class CodecInfo {
-    /** bit rate in bps */
-    public int mBitRate = 0;
-    /** Frame rate */
-    public int mFps = 0;
-    /** if codec is supporting YUV semiplanar format */
-    public boolean mSupportSemiPlanar = false;
-    /** if codec is supporting YUV planar format */
-    public boolean mSupportPlanar = false;
-
-    private static final String TAG = "CodecInfo";
-    private static final String VIDEO_AVC = MediaFormat.MIMETYPE_VIDEO_AVC;
-    /**
-     * Check if given codec with given (w,h) is supported.
-     * @param codecName codec name
-     * @param mimeType codec type in mime format like MediaFormat.MIMETYPE_VIDEO_AVC
-     * @param w video width
-     * @param h video height
-     * @return null if the configuration is not supported.
-     */
-    public static CodecInfo getSupportedFormatInfo(
-            String codecName, String mimeType, int w, int h) {
-        MediaCodec codec;
-        try {
-            codec = MediaCodec.createByCodecName(codecName);
-        } catch (IOException e) {
-            return null;
-        }
-
-        CodecCapabilities cap = codec.getCodecInfo().getCapabilitiesForType(mimeType);
-        if (cap.colorFormats.length == 0) {
-            Log.w(TAG, "no supported color format");
-            codec.release();
-            return null;
-        }
-
-        CodecInfo info = new CodecInfo();
-        for (int color : cap.colorFormats) {
-            if (color == CodecCapabilities.COLOR_FormatYUV420SemiPlanar) {
-                info.mSupportSemiPlanar = true;
-            }
-            if (color == CodecCapabilities.COLOR_FormatYUV420Planar) {
-                info.mSupportPlanar = true;
-            }
-        }
-        printIntArray("supported colors", cap.colorFormats);
-
-        VideoCapabilities vidCap = cap.getVideoCapabilities();
-        try {
-            info.mFps = vidCap.getSupportedFrameRatesFor(w, h).getUpper().intValue();
-        } catch (IllegalArgumentException e) {
-            Log.w(TAG, "unsupported size");
-            codec.release();
-            return null;
-        }
-        info.mBitRate = vidCap.getBitrateRange().getUpper();
-        Log.i(TAG, "test bit rate " + info.mBitRate + " fps " + info.mFps);
-        codec.release();
-        return info;
-    }
-
-    // for debugging
-    private static void printIntArray(String msg, int[] data) {
-        StringBuilder builder = new StringBuilder();
-        builder.append(msg);
-        builder.append(":");
-        for (int e : data) {
-            builder.append(Integer.toHexString(e));
-            builder.append(",");
-        }
-        builder.deleteCharAt(builder.length() - 1);
-        Log.i(TAG, builder.toString());
-    }
-}
diff --git a/suite/cts/deviceTests/videoperf/src/com/android/cts/videoperf/VideoEncoderDecoderTest.java b/suite/cts/deviceTests/videoperf/src/com/android/cts/videoperf/VideoEncoderDecoderTest.java
deleted file mode 100644
index 62f37c5..0000000
--- a/suite/cts/deviceTests/videoperf/src/com/android/cts/videoperf/VideoEncoderDecoderTest.java
+++ /dev/null
@@ -1,1260 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.videoperf;
-
-import android.cts.util.MediaUtils;
-import android.cts.util.DeviceReportLog;
-import android.graphics.ImageFormat;
-import android.graphics.Point;
-import android.media.cts.CodecImage;
-import android.media.cts.CodecUtils;
-import android.media.Image;
-import android.media.Image.Plane;
-import android.media.MediaCodec;
-import android.media.MediaCodec.BufferInfo;
-import android.media.MediaCodecInfo;
-import android.media.MediaCodecInfo.CodecCapabilities;
-import android.media.MediaCodecList;
-import android.media.MediaFormat;
-import android.util.Log;
-import android.util.Pair;
-import android.util.Range;
-import android.util.Size;
-
-import android.cts.util.CtsAndroidTestCase;
-import com.android.cts.util.ResultType;
-import com.android.cts.util.ResultUnit;
-import com.android.cts.util.Stat;
-import com.android.cts.util.TimeoutReq;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.lang.System;
-import java.util.Arrays;
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.Random;
-import java.util.Vector;
-
-/**
- * This tries to test video encoder / decoder performance by running encoding / decoding
- * without displaying the raw data. To make things simpler, encoder is used to encode synthetic
- * data and decoder is used to decode the encoded video. This approach does not work where
- * there is only decoder. Performance index is total time taken for encoding and decoding
- * the whole frames.
- * To prevent sacrificing quality for faster encoding / decoding, randomly selected pixels are
- * compared with the original image. As the pixel comparison can slow down the decoding process,
- * only some randomly selected pixels are compared. As there can be only one performance index,
- * error above certain threshold in pixel value will be treated as an error.
- */
-public class VideoEncoderDecoderTest extends CtsAndroidTestCase {
-    private static final String TAG = "VideoEncoderDecoderTest";
-    // this wait time affects fps as too big value will work as a blocker if device fps
-    // is not very high.
-    private static final long VIDEO_CODEC_WAIT_TIME_US = 5000;
-    private static final boolean VERBOSE = false;
-    private static final String VIDEO_AVC = MediaFormat.MIMETYPE_VIDEO_AVC;
-    private static final String VIDEO_VP8 = MediaFormat.MIMETYPE_VIDEO_VP8;
-    private static final String VIDEO_H263 = MediaFormat.MIMETYPE_VIDEO_H263;
-    private static final String VIDEO_MPEG4 = MediaFormat.MIMETYPE_VIDEO_MPEG4;
-    private int mCurrentTestRound = 0;
-    private double[][] mEncoderFrameTimeDiff = null;
-    private double[][] mDecoderFrameTimeDiff = null;
-    // i frame interval for encoder
-    private static final int KEY_I_FRAME_INTERVAL = 5;
-    private static final int MOVING_AVERAGE_NUM = 10;
-
-    private static final int Y_CLAMP_MIN = 16;
-    private static final int Y_CLAMP_MAX = 235;
-    private static final int YUV_PLANE_ADDITIONAL_LENGTH = 200;
-    private ByteBuffer mYBuffer, mYDirectBuffer;
-    private ByteBuffer mUVBuffer, mUVDirectBuffer;
-    private int mSrcColorFormat;
-    private int mDstColorFormat;
-    private int mBufferWidth;
-    private int mBufferHeight;
-    private int mVideoWidth;
-    private int mVideoHeight;
-    private int mFrameRate;
-
-    private MediaFormat mEncInputFormat;
-    private MediaFormat mEncOutputFormat;
-    private MediaFormat mDecOutputFormat;
-
-    private LinkedList<Pair<ByteBuffer, BufferInfo>> mEncodedOutputBuffer;
-    // check this many pixels per each decoded frame
-    // checking too many points decreases decoder frame rates a lot.
-    private static final int PIXEL_CHECK_PER_FRAME = 1000;
-    // RMS error in pixel values above this will be treated as error.
-    private static final double PIXEL_RMS_ERROR_MARGAIN = 20.0;
-    private double mRmsErrorMargain = PIXEL_RMS_ERROR_MARGAIN;
-    private Random mRandom;
-
-    private class TestConfig {
-        public boolean mTestPixels = true;
-        public boolean mTestResult = false;
-        public boolean mReportFrameTime = false;
-        public int mTotalFrames = 300;
-        public int mMaxTimeMs = 120000;  // 2 minutes
-        public int mNumberOfRepeat = 10;
-    }
-
-    private TestConfig mTestConfig;
-
-    private DeviceReportLog mReportLog;
-
-    @Override
-    protected void setUp() throws Exception {
-        mEncodedOutputBuffer = new LinkedList<Pair<ByteBuffer, BufferInfo>>();
-        // Use time as a seed, hoping to prevent checking pixels in the same pattern
-        long now = System.currentTimeMillis();
-        mRandom = new Random(now);
-        mTestConfig = new TestConfig();
-        mReportLog = new DeviceReportLog();
-        super.setUp();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        mEncodedOutputBuffer.clear();
-        mEncodedOutputBuffer = null;
-        mYBuffer = null;
-        mUVBuffer = null;
-        mYDirectBuffer = null;
-        mUVDirectBuffer = null;
-        mRandom = null;
-        mTestConfig = null;
-        mReportLog.deliverReportToHost(getInstrumentation());
-        super.tearDown();
-    }
-
-    private String getEncoderName(String mime) {
-        return getCodecName(mime, true /* isEncoder */);
-    }
-
-    private String getDecoderName(String mime) {
-        return getCodecName(mime, false /* isEncoder */);
-    }
-
-    private String getCodecName(String mime, boolean isEncoder) {
-        MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
-        for (MediaCodecInfo info : mcl.getCodecInfos()) {
-            if (info.isEncoder() != isEncoder) {
-                continue;
-            }
-            CodecCapabilities caps = null;
-            try {
-                caps = info.getCapabilitiesForType(mime);
-            } catch (IllegalArgumentException e) {  // mime is not supported
-                continue;
-            }
-            return info.getName();
-        }
-        return null;
-    }
-
-    private String[] getEncoderName(String mime, boolean isGoog) {
-        return getCodecName(mime, isGoog, true /* isEncoder */);
-    }
-
-    private String[] getDecoderName(String mime, boolean isGoog) {
-        return getCodecName(mime, isGoog, false /* isEncoder */);
-    }
-
-    private String[] getCodecName(String mime, boolean isGoog, boolean isEncoder) {
-        MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
-        ArrayList<String> result = new ArrayList<String>();
-        for (MediaCodecInfo info : mcl.getCodecInfos()) {
-            if (info.isEncoder() != isEncoder
-                    || info.getName().toLowerCase().startsWith("omx.google.") != isGoog) {
-                continue;
-            }
-            CodecCapabilities caps = null;
-            try {
-                caps = info.getCapabilitiesForType(mime);
-            } catch (IllegalArgumentException e) {  // mime is not supported
-                continue;
-            }
-            result.add(info.getName());
-        }
-        return result.toArray(new String[result.size()]);
-    }
-
-    public void testAvc0176x0144() throws Exception {
-        doTestDefault(VIDEO_AVC, 176, 144);
-    }
-
-    public void testAvc0352x0288() throws Exception {
-        doTestDefault(VIDEO_AVC, 352, 288);
-    }
-
-    public void testAvc0720x0480() throws Exception {
-        doTestDefault(VIDEO_AVC, 720, 480);
-    }
-
-    public void testAvc1280x0720() throws Exception {
-        doTestDefault(VIDEO_AVC, 1280, 720);
-    }
-
-    /**
-     * resolution intentionally set to 1072 not 1080
-     * as 1080 is not multiple of 16, and it requires additional setting like stride
-     * which is not specified in API documentation.
-     */
-    public void testAvc1920x1072() throws Exception {
-        doTestDefault(VIDEO_AVC, 1920, 1072);
-    }
-
-    // Avc tests
-    public void testAvc0320x0240Other() throws Exception {
-        doTestOther(VIDEO_AVC, 320, 240);
-    }
-
-    public void testAvc0320x0240Goog() throws Exception {
-        doTestGoog(VIDEO_AVC, 320, 240);
-    }
-
-    public void testAvc0720x0480Other() throws Exception {
-        doTestOther(VIDEO_AVC, 720, 480);
-    }
-
-    public void testAvc0720x0480Goog() throws Exception {
-        doTestGoog(VIDEO_AVC, 720, 480);
-    }
-
-    @TimeoutReq(minutes = 10)
-    public void testAvc1280x0720Other() throws Exception {
-        doTestOther(VIDEO_AVC, 1280, 720);
-    }
-
-    @TimeoutReq(minutes = 10)
-    public void testAvc1280x0720Goog() throws Exception {
-        doTestGoog(VIDEO_AVC, 1280, 720);
-    }
-
-    @TimeoutReq(minutes = 10)
-    public void testAvc1920x1080Other() throws Exception {
-        doTestOther(VIDEO_AVC, 1920, 1080);
-    }
-
-    @TimeoutReq(minutes = 10)
-    public void testAvc1920x1080Goog() throws Exception {
-        doTestGoog(VIDEO_AVC, 1920, 1080);
-    }
-
-    // Vp8 tests
-    public void testVp80320x0180Other() throws Exception {
-        doTestOther(VIDEO_VP8, 320, 180);
-    }
-
-    public void testVp80320x0180Goog() throws Exception {
-        doTestGoog(VIDEO_VP8, 320, 180);
-    }
-
-    public void testVp80640x0360Other() throws Exception {
-        doTestOther(VIDEO_VP8, 640, 360);
-    }
-
-    public void testVp80640x0360Goog() throws Exception {
-        doTestGoog(VIDEO_VP8, 640, 360);
-    }
-
-    @TimeoutReq(minutes = 10)
-    public void testVp81280x0720Other() throws Exception {
-        doTestOther(VIDEO_VP8, 1280, 720);
-    }
-
-    @TimeoutReq(minutes = 10)
-    public void testVp81280x0720Goog() throws Exception {
-        doTestGoog(VIDEO_VP8, 1280, 720);
-    }
-
-    @TimeoutReq(minutes = 10)
-    public void testVp81920x1080Other() throws Exception {
-        doTestOther(VIDEO_VP8, 1920, 1080);
-    }
-
-    @TimeoutReq(minutes = 10)
-    public void testVp81920x1080Goog() throws Exception {
-        doTestGoog(VIDEO_VP8, 1920, 1080);
-    }
-
-    // H263 tests
-    public void testH2630176x0144Other() throws Exception {
-        doTestOther(VIDEO_H263, 176, 144);
-    }
-
-    public void testH2630176x0144Goog() throws Exception {
-        doTestGoog(VIDEO_H263, 176, 144);
-    }
-
-    public void testH2630352x0288Other() throws Exception {
-        doTestOther(VIDEO_H263, 352, 288);
-    }
-
-    public void testH2630352x0288Goog() throws Exception {
-        doTestGoog(VIDEO_H263, 352, 288);
-    }
-
-    // Mpeg4 tests
-    public void testMpeg40176x0144Other() throws Exception {
-        doTestOther(VIDEO_MPEG4, 176, 144);
-    }
-
-    public void testMpeg40176x0144Goog() throws Exception {
-        doTestGoog(VIDEO_MPEG4, 176, 144);
-    }
-
-    public void testMpeg40352x0288Other() throws Exception {
-        doTestOther(VIDEO_MPEG4, 352, 288);
-    }
-
-    public void testMpeg40352x0288Goog() throws Exception {
-        doTestGoog(VIDEO_MPEG4, 352, 288);
-    }
-
-    public void testMpeg40640x0480Other() throws Exception {
-        doTestOther(VIDEO_MPEG4, 640, 480);
-    }
-
-    public void testMpeg40640x0480Goog() throws Exception {
-        doTestGoog(VIDEO_MPEG4, 640, 480);
-    }
-
-    @TimeoutReq(minutes = 10)
-    public void testMpeg41280x0720Other() throws Exception {
-        doTestOther(VIDEO_MPEG4, 1280, 720);
-    }
-
-    @TimeoutReq(minutes = 10)
-    public void testMpeg41280x0720Goog() throws Exception {
-        doTestGoog(VIDEO_MPEG4, 1280, 720);
-    }
-
-    private boolean isSrcSemiPlanar() {
-        return mSrcColorFormat == CodecCapabilities.COLOR_FormatYUV420SemiPlanar;
-    }
-
-    private boolean isSrcFlexYUV() {
-        return mSrcColorFormat == CodecCapabilities.COLOR_FormatYUV420Flexible;
-    }
-
-    private boolean isDstSemiPlanar() {
-        return mDstColorFormat == CodecCapabilities.COLOR_FormatYUV420SemiPlanar;
-    }
-
-    private boolean isDstFlexYUV() {
-        return mDstColorFormat == CodecCapabilities.COLOR_FormatYUV420Flexible;
-    }
-
-    private static int getColorFormat(CodecInfo info) {
-        if (info.mSupportSemiPlanar) {
-            return CodecCapabilities.COLOR_FormatYUV420SemiPlanar;
-        } else if (info.mSupportPlanar) {
-            return CodecCapabilities.COLOR_FormatYUV420Planar;
-        } else {
-            // FlexYUV must be supported
-            return CodecCapabilities.COLOR_FormatYUV420Flexible;
-        }
-    }
-
-    private void doTestGoog(String mimeType, int w, int h) throws Exception {
-        mTestConfig.mTestPixels = false;
-        mTestConfig.mTestResult = true;
-        mTestConfig.mTotalFrames = 3000;
-        mTestConfig.mNumberOfRepeat = 2;
-        doTest(true /* isGoog */, mimeType, w, h);
-    }
-
-    private void doTestOther(String mimeType, int w, int h) throws Exception {
-        mTestConfig.mTestPixels = false;
-        mTestConfig.mTestResult = true;
-        mTestConfig.mTotalFrames = 3000;
-        mTestConfig.mNumberOfRepeat = 2;
-        doTest(false /* isGoog */, mimeType, w, h);
-    }
-
-    private void doTestDefault(String mimeType, int w, int h) throws Exception {
-        String encoderName = getEncoderName(mimeType);
-        if (encoderName == null) {
-            Log.i(TAG, "Encoder for " + mimeType + " not found");
-            return;
-        }
-
-        String decoderName = getDecoderName(mimeType);
-        if (decoderName == null) {
-            Log.i(TAG, "Encoder for " + mimeType + " not found");
-            return;
-        }
-
-        doTestByName(encoderName, decoderName, mimeType, w, h);
-    }
-
-    /**
-     * Run encoding / decoding test for given mimeType of codec
-     * @param isGoog test google or non-google codec.
-     * @param mimeType like video/avc
-     * @param w video width
-     * @param h video height
-     */
-    private void doTest(boolean isGoog, String mimeType, int w, int h)
-            throws Exception {
-        String[] encoderNames = getEncoderName(mimeType, isGoog);
-        if (encoderNames.length == 0) {
-            Log.i(TAG, isGoog ? "Google " : "Non-google "
-                    + "encoder for " + mimeType + " not found");
-            return;
-        }
-
-        String[] decoderNames = getDecoderName(mimeType, isGoog);
-        if (decoderNames.length == 0) {
-            Log.i(TAG, isGoog ? "Google " : "Non-google "
-                    + "decoder for " + mimeType + " not found");
-            return;
-        }
-
-        for (String encoderName: encoderNames) {
-            for (String decoderName: decoderNames) {
-                doTestByName(encoderName, decoderName, mimeType, w, h);
-            }
-        }
-    }
-
-    private void doTestByName(
-            String encoderName, String decoderName, String mimeType, int w, int h)
-            throws Exception {
-        CodecInfo infoEnc = CodecInfo.getSupportedFormatInfo(encoderName, mimeType, w, h);
-        if (infoEnc == null) {
-            Log.i(TAG, "Encoder " + mimeType + " with " + w + "," + h + " not supported");
-            return;
-        }
-        CodecInfo infoDec = CodecInfo.getSupportedFormatInfo(decoderName, mimeType, w, h);
-        assertNotNull(infoDec);
-        mVideoWidth = w;
-        mVideoHeight = h;
-
-        mSrcColorFormat = getColorFormat(infoEnc);
-        mDstColorFormat = getColorFormat(infoDec);
-        Log.i(TAG, "Testing video resolution " + w + "x" + h +
-                   ": enc format " + mSrcColorFormat +
-                   ", dec format " + mDstColorFormat);
-
-        initYUVPlane(w + YUV_PLANE_ADDITIONAL_LENGTH, h + YUV_PLANE_ADDITIONAL_LENGTH);
-        mEncoderFrameTimeDiff =
-                new double[mTestConfig.mNumberOfRepeat][mTestConfig.mTotalFrames - 1];
-        mDecoderFrameTimeDiff =
-                new double[mTestConfig.mNumberOfRepeat][mTestConfig.mTotalFrames - 1];
-        double[] encoderFpsResults = new double[mTestConfig.mNumberOfRepeat];
-        double[] decoderFpsResults = new double[mTestConfig.mNumberOfRepeat];
-        double[] totalFpsResults = new double[mTestConfig.mNumberOfRepeat];
-        double[] decoderRmsErrorResults = new double[mTestConfig.mNumberOfRepeat];
-        boolean success = true;
-        for (int i = 0; i < mTestConfig.mNumberOfRepeat && success; i++) {
-            mCurrentTestRound = i;
-            MediaFormat format = new MediaFormat();
-            format.setString(MediaFormat.KEY_MIME, mimeType);
-            format.setInteger(MediaFormat.KEY_BIT_RATE, infoEnc.mBitRate);
-            format.setInteger(MediaFormat.KEY_WIDTH, w);
-            format.setInteger(MediaFormat.KEY_HEIGHT, h);
-            format.setInteger(MediaFormat.KEY_COLOR_FORMAT, mSrcColorFormat);
-            format.setInteger(MediaFormat.KEY_FRAME_RATE, infoEnc.mFps);
-            mFrameRate = infoEnc.mFps;
-            format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, KEY_I_FRAME_INTERVAL);
-
-            double encodingTime = runEncoder(encoderName, format, mTestConfig.mTotalFrames);
-            // re-initialize format for decoder
-            format = new MediaFormat();
-            format.setString(MediaFormat.KEY_MIME, mimeType);
-            format.setInteger(MediaFormat.KEY_WIDTH, w);
-            format.setInteger(MediaFormat.KEY_HEIGHT, h);
-            format.setInteger(MediaFormat.KEY_COLOR_FORMAT, mDstColorFormat);
-            double[] decoderResult = runDecoder(decoderName, format);
-            if (decoderResult == null) {
-                success = false;
-            } else {
-                double decodingTime = decoderResult[0];
-                decoderRmsErrorResults[i] = decoderResult[1];
-                encoderFpsResults[i] = (double)mTestConfig.mTotalFrames / encodingTime * 1000.0;
-                decoderFpsResults[i] = (double)mTestConfig.mTotalFrames / decodingTime * 1000.0;
-                totalFpsResults[i] =
-                        (double)mTestConfig.mTotalFrames / (encodingTime + decodingTime) * 1000.0;
-            }
-
-            // clear things for re-start
-            mEncodedOutputBuffer.clear();
-            // it will be good to clean everything to make every run the same.
-            System.gc();
-        }
-        mReportLog.printArray("encoder", encoderFpsResults, ResultType.HIGHER_BETTER,
-                ResultUnit.FPS);
-        mReportLog.printArray("rms error", decoderRmsErrorResults, ResultType.LOWER_BETTER,
-                ResultUnit.NONE);
-        mReportLog.printArray("decoder", decoderFpsResults, ResultType.HIGHER_BETTER,
-                ResultUnit.FPS);
-        mReportLog.printArray("encoder decoder", totalFpsResults, ResultType.HIGHER_BETTER,
-                ResultUnit.FPS);
-        mReportLog.printValue(mimeType + " encoder average fps for " + w + "x" + h,
-                Stat.getAverage(encoderFpsResults), ResultType.HIGHER_BETTER, ResultUnit.FPS);
-        mReportLog.printValue(mimeType + " decoder average fps for " + w + "x" + h,
-                Stat.getAverage(decoderFpsResults), ResultType.HIGHER_BETTER, ResultUnit.FPS);
-        mReportLog.printSummary("encoder decoder", Stat.getAverage(totalFpsResults),
-                ResultType.HIGHER_BETTER, ResultUnit.FPS);
-
-        boolean encTestPassed = false;
-        boolean decTestPassed = false;
-        double[] measuredFps = new double[mTestConfig.mNumberOfRepeat];
-        String[] resultRawData = new String[mTestConfig.mNumberOfRepeat];
-        for (int i = 0; i < mTestConfig.mNumberOfRepeat; i++) {
-            // make sure that rms error is not too big.
-            if (decoderRmsErrorResults[i] >= mRmsErrorMargain) {
-                fail("rms error is bigger than the limit "
-                        + decoderRmsErrorResults[i] + " vs " + mRmsErrorMargain);
-            }
-
-            if (mTestConfig.mReportFrameTime) {
-                mReportLog.printValue(
-                        "encodertest#" + i + ": " + Arrays.toString(mEncoderFrameTimeDiff[i]),
-                        0, ResultType.NEUTRAL, ResultUnit.NONE);
-                mReportLog.printValue(
-                        "decodertest#" + i + ": " + Arrays.toString(mDecoderFrameTimeDiff[i]),
-                        0, ResultType.NEUTRAL, ResultUnit.NONE);
-            }
-
-            if (mTestConfig.mTestResult) {
-                double[] avgs = MediaUtils.calculateMovingAverage(
-                        mEncoderFrameTimeDiff[i], MOVING_AVERAGE_NUM);
-                double encMin = Stat.getMin(avgs);
-                double encMax = Stat.getMax(avgs);
-                double encAvg = MediaUtils.getAverage(mEncoderFrameTimeDiff[i]);
-                double encStdev = MediaUtils.getStdev(avgs);
-                String prefix = "codec=" + encoderName + " round=" + i +
-                        " EncInputFormat=" + mEncInputFormat +
-                        " EncOutputFormat=" + mEncOutputFormat;
-                String result =
-                        MediaUtils.logResults(mReportLog, prefix, encMin, encMax, encAvg, encStdev);
-                double measuredEncFps = 1000000000 / encMin;
-                resultRawData[i] = result;
-                measuredFps[i] = measuredEncFps;
-                if (!encTestPassed) {
-                    encTestPassed = MediaUtils.verifyResults(
-                            encoderName, mimeType, w, h, measuredEncFps);
-                }
-
-                avgs = MediaUtils.calculateMovingAverage(
-                        mDecoderFrameTimeDiff[i], MOVING_AVERAGE_NUM);
-                double decMin = Stat.getMin(avgs);
-                double decMax = Stat.getMax(avgs);
-                double decAvg = MediaUtils.getAverage(mDecoderFrameTimeDiff[i]);
-                double decStdev = MediaUtils.getStdev(avgs);
-                prefix = "codec=" + decoderName + " size=" + w + "x" + h + " round=" + i +
-                        " DecOutputFormat=" + mDecOutputFormat;
-                MediaUtils.logResults(mReportLog, prefix, decMin, decMax, decAvg, decStdev);
-                double measuredDecFps = 1000000000 / decMin;
-                if (!decTestPassed) {
-                    decTestPassed = MediaUtils.verifyResults(
-                            decoderName, mimeType, w, h, measuredDecFps);
-                }
-            }
-        }
-
-        if (mTestConfig.mTestResult) {
-            if (!encTestPassed) {
-                Range<Double> reportedRange =
-                    MediaUtils.getAchievableFrameRatesFor(encoderName, mimeType, w, h);
-                String failMessage =
-                    MediaUtils.getErrorMessage(reportedRange, measuredFps, resultRawData);
-                fail(failMessage);
-            }
-            // Decoder result will be verified in VideoDecoderPerfTest
-            // if (!decTestPassed) {
-            //     fail("Measured fps for " + decoderName +
-            //             " doesn't match with reported achievable frame rates.");
-            // }
-        }
-        measuredFps = null;
-        resultRawData = null;
-    }
-
-    /**
-     * run encoder benchmarking
-     * @param encoderName encoder name
-     * @param format format of media to encode
-     * @param totalFrames total number of frames to encode
-     * @return time taken in ms to encode the frames. This does not include initialization time.
-     */
-    private double runEncoder(String encoderName, MediaFormat format, int totalFrames) {
-        MediaCodec codec = null;
-        try {
-            codec = MediaCodec.createByCodecName(encoderName);
-            codec.configure(
-                    format,
-                    null /* surface */,
-                    null /* crypto */,
-                    MediaCodec.CONFIGURE_FLAG_ENCODE);
-        } catch (IllegalStateException e) {
-            Log.e(TAG, "codec '" + encoderName + "' failed configuration.");
-            codec.release();
-            assertTrue("codec '" + encoderName + "' failed configuration.", false);
-        } catch (IOException | NullPointerException e) {
-            Log.i(TAG, "could not find codec for " + format);
-            return Double.NaN;
-        }
-        codec.start();
-        mEncInputFormat = codec.getInputFormat();
-        ByteBuffer[] codecOutputBuffers = codec.getOutputBuffers();
-
-        int numBytesSubmitted = 0;
-        int numBytesDequeued = 0;
-        int inFramesCount = 0;
-        long lastOutputTimeNs = 0;
-        long start = System.currentTimeMillis();
-        while (true) {
-            int index;
-
-            if (inFramesCount < totalFrames) {
-                index = codec.dequeueInputBuffer(VIDEO_CODEC_WAIT_TIME_US /* timeoutUs */);
-                if (index != MediaCodec.INFO_TRY_AGAIN_LATER) {
-                    int size;
-                    boolean eos = (inFramesCount == (totalFrames - 1));
-                    if (!eos && ((System.currentTimeMillis() - start) > mTestConfig.mMaxTimeMs)) {
-                        eos = true;
-                    }
-                    // when encoder only supports flexYUV, use Image only; otherwise,
-                    // use ByteBuffer & Image each on half of the frames to test both
-                    if (isSrcFlexYUV() || inFramesCount % 2 == 0) {
-                        Image image = codec.getInputImage(index);
-                        // image should always be available
-                        assertTrue(image != null);
-                        size = queueInputImageEncoder(
-                                codec, image, index, inFramesCount,
-                                eos ? MediaCodec.BUFFER_FLAG_END_OF_STREAM : 0);
-                    } else {
-                        ByteBuffer buffer = codec.getInputBuffer(index);
-                        size = queueInputBufferEncoder(
-                                codec, buffer, index, inFramesCount,
-                                eos ? MediaCodec.BUFFER_FLAG_END_OF_STREAM : 0);
-                    }
-                    inFramesCount++;
-                    numBytesSubmitted += size;
-                    if (VERBOSE) {
-                        Log.d(TAG, "queued " + size + " bytes of input data, frame " +
-                                (inFramesCount - 1));
-                    }
-
-                }
-            }
-            MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
-            index = codec.dequeueOutputBuffer(info, VIDEO_CODEC_WAIT_TIME_US /* timeoutUs */);
-            if (index == MediaCodec.INFO_TRY_AGAIN_LATER) {
-            } else if (index == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
-                mEncOutputFormat = codec.getOutputFormat();
-            } else if (index == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
-                codecOutputBuffers = codec.getOutputBuffers();
-            } else if (index >= 0) {
-                if (lastOutputTimeNs > 0) {
-                    int pos = mEncodedOutputBuffer.size() - 1;
-                    if (pos < mEncoderFrameTimeDiff[mCurrentTestRound].length) {
-                        long diff = System.nanoTime() - lastOutputTimeNs;
-                        mEncoderFrameTimeDiff[mCurrentTestRound][pos] = diff;
-                    }
-                }
-                lastOutputTimeNs = System.nanoTime();
-
-                dequeueOutputBufferEncoder(codec, codecOutputBuffers, index, info);
-                numBytesDequeued += info.size;
-                if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
-                    if (VERBOSE) {
-                        Log.d(TAG, "dequeued output EOS.");
-                    }
-                    break;
-                }
-                if (VERBOSE) {
-                    Log.d(TAG, "dequeued " + info.size + " bytes of output data.");
-                }
-            }
-        }
-        long finish = System.currentTimeMillis();
-        int validDataNum = Math.min(mEncodedOutputBuffer.size() - 1,
-                mEncoderFrameTimeDiff[mCurrentTestRound].length);
-        mEncoderFrameTimeDiff[mCurrentTestRound] =
-                Arrays.copyOf(mEncoderFrameTimeDiff[mCurrentTestRound], validDataNum);
-        if (VERBOSE) {
-            Log.d(TAG, "queued a total of " + numBytesSubmitted + "bytes, "
-                    + "dequeued " + numBytesDequeued + " bytes.");
-        }
-        codec.stop();
-        codec.release();
-        codec = null;
-        return (double)(finish - start);
-    }
-
-    /**
-     * Fills input buffer for encoder from YUV buffers.
-     * @return size of enqueued data.
-     */
-    private int queueInputBufferEncoder(
-            MediaCodec codec, ByteBuffer buffer, int index, int frameCount, int flags) {
-        buffer.clear();
-
-        Point origin = getOrigin(frameCount);
-        // Y color first
-        int srcOffsetY = origin.x + origin.y * mBufferWidth;
-        final byte[] yBuffer = mYBuffer.array();
-        for (int i = 0; i < mVideoHeight; i++) {
-            buffer.put(yBuffer, srcOffsetY, mVideoWidth);
-            srcOffsetY += mBufferWidth;
-        }
-        if (isSrcSemiPlanar()) {
-            int srcOffsetU = origin.y / 2 * mBufferWidth + origin.x / 2 * 2;
-            final byte[] uvBuffer = mUVBuffer.array();
-            for (int i = 0; i < mVideoHeight / 2; i++) {
-                buffer.put(uvBuffer, srcOffsetU, mVideoWidth);
-                srcOffsetU += mBufferWidth;
-            }
-        } else {
-            int srcOffsetU = origin.y / 2 * mBufferWidth / 2 + origin.x / 2;
-            int srcOffsetV = srcOffsetU + mBufferWidth / 2 * mBufferHeight / 2;
-            final byte[] uvBuffer = mUVBuffer.array();
-            for (int i = 0; i < mVideoHeight / 2; i++) { //U only
-                buffer.put(uvBuffer, srcOffsetU, mVideoWidth / 2);
-                srcOffsetU += mBufferWidth / 2;
-            }
-            for (int i = 0; i < mVideoHeight / 2; i++) { //V only
-                buffer.put(uvBuffer, srcOffsetV, mVideoWidth / 2);
-                srcOffsetV += mBufferWidth / 2;
-            }
-        }
-        int size = mVideoHeight * mVideoWidth * 3 / 2;
-        long ptsUsec = computePresentationTime(frameCount);
-
-        codec.queueInputBuffer(index, 0 /* offset */, size, ptsUsec /* timeUs */, flags);
-        if (VERBOSE && (frameCount == 0)) {
-            printByteArray("Y ", mYBuffer.array(), 0, 20);
-            printByteArray("UV ", mUVBuffer.array(), 0, 20);
-            printByteArray("UV ", mUVBuffer.array(), mBufferWidth * 60, 20);
-        }
-        return size;
-    }
-
-    class YUVImage extends CodecImage {
-        private final int mImageWidth;
-        private final int mImageHeight;
-        private final Plane[] mPlanes;
-
-        YUVImage(
-                Point origin,
-                int imageWidth, int imageHeight,
-                int arrayWidth, int arrayHeight,
-                boolean semiPlanar,
-                ByteBuffer bufferY, ByteBuffer bufferUV) {
-            mImageWidth = imageWidth;
-            mImageHeight = imageHeight;
-            ByteBuffer dupY = bufferY.duplicate();
-            ByteBuffer dupUV = bufferUV.duplicate();
-            mPlanes = new Plane[3];
-
-            int srcOffsetY = origin.x + origin.y * arrayWidth;
-
-            mPlanes[0] = new YUVPlane(
-                        mImageWidth, mImageHeight, arrayWidth, 1,
-                        dupY, srcOffsetY);
-
-            if (semiPlanar) {
-                int srcOffsetUV = origin.y / 2 * arrayWidth + origin.x / 2 * 2;
-
-                mPlanes[1] = new YUVPlane(
-                        mImageWidth / 2, mImageHeight / 2, arrayWidth, 2,
-                        dupUV, srcOffsetUV);
-                mPlanes[2] = new YUVPlane(
-                        mImageWidth / 2, mImageHeight / 2, arrayWidth, 2,
-                        dupUV, srcOffsetUV + 1);
-            } else {
-                int srcOffsetU = origin.y / 2 * arrayWidth / 2 + origin.x / 2;
-                int srcOffsetV = srcOffsetU + arrayWidth / 2 * arrayHeight / 2;
-
-                mPlanes[1] = new YUVPlane(
-                        mImageWidth / 2, mImageHeight / 2, arrayWidth / 2, 1,
-                        dupUV, srcOffsetU);
-                mPlanes[2] = new YUVPlane(
-                        mImageWidth / 2, mImageHeight / 2, arrayWidth / 2, 1,
-                        dupUV, srcOffsetV);
-            }
-        }
-
-        @Override
-        public int getFormat() {
-            return ImageFormat.YUV_420_888;
-        }
-
-        @Override
-        public int getWidth() {
-            return mImageWidth;
-        }
-
-        @Override
-        public int getHeight() {
-            return mImageHeight;
-        }
-
-        @Override
-        public long getTimestamp() {
-            return 0;
-        }
-
-        @Override
-        public Plane[] getPlanes() {
-            return mPlanes;
-        }
-
-        @Override
-        public void close() {
-            mPlanes[0] = null;
-            mPlanes[1] = null;
-            mPlanes[2] = null;
-        }
-
-        class YUVPlane extends CodecImage.Plane {
-            private final int mRowStride;
-            private final int mPixelStride;
-            private final ByteBuffer mByteBuffer;
-
-            YUVPlane(int w, int h, int rowStride, int pixelStride,
-                    ByteBuffer buffer, int offset) {
-                mRowStride = rowStride;
-                mPixelStride = pixelStride;
-
-                // only safe to access length bytes starting from buffer[offset]
-                int length = (h - 1) * rowStride + (w - 1) * pixelStride + 1;
-
-                buffer.position(offset);
-                mByteBuffer = buffer.slice();
-                mByteBuffer.limit(length);
-            }
-
-            @Override
-            public int getRowStride() {
-                return mRowStride;
-            }
-
-            @Override
-            public int getPixelStride() {
-                return mPixelStride;
-            }
-
-            @Override
-            public ByteBuffer getBuffer() {
-                return mByteBuffer;
-            }
-        }
-    }
-
-    /**
-     * Fills input image for encoder from YUV buffers.
-     * @return size of enqueued data.
-     */
-    private int queueInputImageEncoder(
-            MediaCodec codec, Image image, int index, int frameCount, int flags) {
-        assertTrue(image.getFormat() == ImageFormat.YUV_420_888);
-
-
-        Point origin = getOrigin(frameCount);
-
-        // Y color first
-        CodecImage srcImage = new YUVImage(
-                origin,
-                mVideoWidth, mVideoHeight,
-                mBufferWidth, mBufferHeight,
-                isSrcSemiPlanar(),
-                mYDirectBuffer, mUVDirectBuffer);
-
-        CodecUtils.copyFlexYUVImage(image, srcImage);
-
-        int size = mVideoHeight * mVideoWidth * 3 / 2;
-        long ptsUsec = computePresentationTime(frameCount);
-
-        codec.queueInputBuffer(index, 0 /* offset */, size, ptsUsec /* timeUs */, flags);
-        if (VERBOSE && (frameCount == 0)) {
-            printByteArray("Y ", mYBuffer.array(), 0, 20);
-            printByteArray("UV ", mUVBuffer.array(), 0, 20);
-            printByteArray("UV ", mUVBuffer.array(), mBufferWidth * 60, 20);
-        }
-        return size;
-    }
-
-    /**
-     * Dequeue encoded data from output buffer and store for later usage.
-     */
-    private void dequeueOutputBufferEncoder(
-            MediaCodec codec, ByteBuffer[] outputBuffers,
-            int index, MediaCodec.BufferInfo info) {
-        ByteBuffer output = outputBuffers[index];
-        int l = info.size;
-        ByteBuffer copied = ByteBuffer.allocate(l);
-        output.get(copied.array(), 0, l);
-        BufferInfo savedInfo = new BufferInfo();
-        savedInfo.set(0, l, info.presentationTimeUs, info.flags);
-        mEncodedOutputBuffer.addLast(Pair.create(copied, savedInfo));
-        codec.releaseOutputBuffer(index, false /* render */);
-    }
-
-    /**
-     * run encoder benchmarking with encoded stream stored from encoding phase
-     * @param decoderName decoder name
-     * @param format format of media to decode
-     * @return returns length-2 array with 0: time for decoding, 1 : rms error of pixels
-     */
-    private double[] runDecoder(String decoderName, MediaFormat format) {
-        MediaCodec codec = null;
-        try {
-            codec = MediaCodec.createByCodecName(decoderName);
-        } catch (IOException | NullPointerException e) {
-            Log.i(TAG, "could not find decoder for " + format);
-            return null;
-        }
-        codec.configure(format, null /* surface */, null /* crypto */, 0 /* flags */);
-        codec.start();
-        ByteBuffer[] codecInputBuffers = codec.getInputBuffers();
-
-        double totalErrorSquared = 0;
-
-        MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
-        boolean sawOutputEOS = false;
-        int inputLeft = mEncodedOutputBuffer.size();
-        int inputBufferCount = 0;
-        int outFrameCount = 0;
-        YUVValue expected = new YUVValue();
-        YUVValue decoded = new YUVValue();
-        long lastOutputTimeNs = 0;
-        long start = System.currentTimeMillis();
-        while (!sawOutputEOS) {
-            if (inputLeft > 0) {
-                int inputBufIndex = codec.dequeueInputBuffer(VIDEO_CODEC_WAIT_TIME_US);
-
-                if (inputBufIndex >= 0) {
-                    ByteBuffer dstBuf = codecInputBuffers[inputBufIndex];
-                    dstBuf.clear();
-                    ByteBuffer src = mEncodedOutputBuffer.get(inputBufferCount).first;
-                    BufferInfo srcInfo = mEncodedOutputBuffer.get(inputBufferCount).second;
-                    int writeSize = src.capacity();
-                    dstBuf.put(src.array(), 0, writeSize);
-
-                    int flags = srcInfo.flags;
-                    if ((System.currentTimeMillis() - start) > mTestConfig.mMaxTimeMs) {
-                        flags |= MediaCodec.BUFFER_FLAG_END_OF_STREAM;
-                    }
-
-                    codec.queueInputBuffer(
-                            inputBufIndex,
-                            0 /* offset */,
-                            writeSize,
-                            srcInfo.presentationTimeUs,
-                            flags);
-                    inputLeft --;
-                    inputBufferCount ++;
-                }
-            }
-
-            int res = codec.dequeueOutputBuffer(info, VIDEO_CODEC_WAIT_TIME_US);
-            if (res >= 0) {
-                int outputBufIndex = res;
-
-                // only do YUV compare on EOS frame if the buffer size is none-zero
-                if (info.size > 0) {
-                    if (lastOutputTimeNs > 0) {
-                        int pos = outFrameCount - 1;
-                        if (pos < mDecoderFrameTimeDiff[mCurrentTestRound].length) {
-                            long diff = System.nanoTime() - lastOutputTimeNs;
-                            mDecoderFrameTimeDiff[mCurrentTestRound][pos] = diff;
-                        }
-                    }
-                    lastOutputTimeNs = System.nanoTime();
-
-                    if (mTestConfig.mTestPixels) {
-                        Point origin = getOrigin(outFrameCount);
-                        int i;
-
-                        // if decoder supports planar or semiplanar, check output with
-                        // ByteBuffer & Image each on half of the points
-                        int pixelCheckPerFrame = PIXEL_CHECK_PER_FRAME;
-                        if (!isDstFlexYUV()) {
-                            pixelCheckPerFrame /= 2;
-                            ByteBuffer buf = codec.getOutputBuffer(outputBufIndex);
-                            if (VERBOSE && (outFrameCount == 0)) {
-                                printByteBuffer("Y ", buf, 0, 20);
-                                printByteBuffer("UV ", buf, mVideoWidth * mVideoHeight, 20);
-                                printByteBuffer("UV ", buf,
-                                        mVideoWidth * mVideoHeight + mVideoWidth * 60, 20);
-                            }
-                            for (i = 0; i < pixelCheckPerFrame; i++) {
-                                int w = mRandom.nextInt(mVideoWidth);
-                                int h = mRandom.nextInt(mVideoHeight);
-                                getPixelValuesFromYUVBuffers(origin.x, origin.y, w, h, expected);
-                                getPixelValuesFromOutputBuffer(buf, w, h, decoded);
-                                if (VERBOSE) {
-                                    Log.i(TAG, outFrameCount + "-" + i + "- th round: ByteBuffer:"
-                                            + " expected "
-                                            + expected.mY + "," + expected.mU + "," + expected.mV
-                                            + " decoded "
-                                            + decoded.mY + "," + decoded.mU + "," + decoded.mV);
-                                }
-                                totalErrorSquared += expected.calcErrorSquared(decoded);
-                            }
-                        }
-
-                        Image image = codec.getOutputImage(outputBufIndex);
-                        assertTrue(image != null);
-                        for (i = 0; i < pixelCheckPerFrame; i++) {
-                            int w = mRandom.nextInt(mVideoWidth);
-                            int h = mRandom.nextInt(mVideoHeight);
-                            getPixelValuesFromYUVBuffers(origin.x, origin.y, w, h, expected);
-                            getPixelValuesFromImage(image, w, h, decoded);
-                            if (VERBOSE) {
-                                Log.i(TAG, outFrameCount + "-" + i + "- th round: FlexYUV:"
-                                        + " expcted "
-                                        + expected.mY + "," + expected.mU + "," + expected.mV
-                                        + " decoded "
-                                        + decoded.mY + "," + decoded.mU + "," + decoded.mV);
-                            }
-                            totalErrorSquared += expected.calcErrorSquared(decoded);
-                        }
-                    }
-                    outFrameCount++;
-                }
-                codec.releaseOutputBuffer(outputBufIndex, false /* render */);
-                if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
-                    Log.d(TAG, "saw output EOS.");
-                    sawOutputEOS = true;
-                }
-            } else if (res == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
-                mDecOutputFormat = codec.getOutputFormat();
-                Log.d(TAG, "output format has changed to " + mDecOutputFormat);
-                int colorFormat = mDecOutputFormat.getInteger(MediaFormat.KEY_COLOR_FORMAT);
-                if (colorFormat == CodecCapabilities.COLOR_FormatYUV420SemiPlanar
-                        || colorFormat == CodecCapabilities.COLOR_FormatYUV420Planar) {
-                    mDstColorFormat = colorFormat;
-                } else {
-                    mDstColorFormat = CodecCapabilities.COLOR_FormatYUV420Flexible;
-                    Log.w(TAG, "output format changed to unsupported one " +
-                            Integer.toHexString(colorFormat) + ", using FlexYUV");
-                }
-            }
-        }
-        long finish = System.currentTimeMillis();
-        int validDataNum = Math.min(outFrameCount - 1,
-                mDecoderFrameTimeDiff[mCurrentTestRound].length);
-        mDecoderFrameTimeDiff[mCurrentTestRound] =
-                Arrays.copyOf(mDecoderFrameTimeDiff[mCurrentTestRound], validDataNum);
-        codec.stop();
-        codec.release();
-        codec = null;
-
-        // divide by 3 as sum is done for Y, U, V.
-        double errorRms = Math.sqrt(totalErrorSquared / PIXEL_CHECK_PER_FRAME / outFrameCount / 3);
-        double[] result = { (double) finish - start, errorRms };
-        return result;
-    }
-
-    /**
-     *  returns origin in the absolute frame for given frame count.
-     *  The video scene is moving by moving origin per each frame.
-     */
-    private Point getOrigin(int frameCount) {
-        if (frameCount < 100) {
-            return new Point(2 * frameCount, 0);
-        } else if (frameCount < 200) {
-            return new Point(200, (frameCount - 100) * 2);
-        } else {
-            if (frameCount > 300) { // for safety
-                frameCount = 300;
-            }
-            return new Point(600 - frameCount * 2, 600 - frameCount * 2);
-        }
-    }
-
-    /**
-     * initialize reference YUV plane
-     * @param w This should be YUV_PLANE_ADDITIONAL_LENGTH pixels bigger than video resolution
-     *          to allow movements
-     * @param h This should be YUV_PLANE_ADDITIONAL_LENGTH pixels bigger than video resolution
-     *          to allow movements
-     * @param semiPlanarEnc
-     * @param semiPlanarDec
-     */
-    private void initYUVPlane(int w, int h) {
-        int bufferSizeY = w * h;
-        mYBuffer = ByteBuffer.allocate(bufferSizeY);
-        mUVBuffer = ByteBuffer.allocate(bufferSizeY / 2);
-        mYDirectBuffer = ByteBuffer.allocateDirect(bufferSizeY);
-        mUVDirectBuffer = ByteBuffer.allocateDirect(bufferSizeY / 2);
-        mBufferWidth = w;
-        mBufferHeight = h;
-        final byte[] yArray = mYBuffer.array();
-        final byte[] uvArray = mUVBuffer.array();
-        for (int i = 0; i < h; i++) {
-            for (int j = 0; j < w; j++) {
-                yArray[i * w + j]  = clampY((i + j) & 0xff);
-            }
-        }
-        if (isSrcSemiPlanar()) {
-            for (int i = 0; i < h/2; i++) {
-                for (int j = 0; j < w/2; j++) {
-                    uvArray[i * w + 2 * j]  = (byte) (i & 0xff);
-                    uvArray[i * w + 2 * j + 1]  = (byte) (j & 0xff);
-                }
-            }
-        } else { // planar, U first, then V
-            int vOffset = bufferSizeY / 4;
-            for (int i = 0; i < h/2; i++) {
-                for (int j = 0; j < w/2; j++) {
-                    uvArray[i * w/2 + j]  = (byte) (i & 0xff);
-                    uvArray[i * w/2 + vOffset + j]  = (byte) (j & 0xff);
-                }
-            }
-        }
-        mYDirectBuffer.put(yArray);
-        mUVDirectBuffer.put(uvArray);
-        mYDirectBuffer.rewind();
-        mUVDirectBuffer.rewind();
-    }
-
-    /**
-     * class to store pixel values in YUV
-     *
-     */
-    public class YUVValue {
-        public byte mY;
-        public byte mU;
-        public byte mV;
-        public YUVValue() {
-        }
-
-        public boolean equalTo(YUVValue other) {
-            return (mY == other.mY) && (mU == other.mU) && (mV == other.mV);
-        }
-
-        public double calcErrorSquared(YUVValue other) {
-            double yDelta = mY - other.mY;
-            double uDelta = mU - other.mU;
-            double vDelta = mV - other.mV;
-            return yDelta * yDelta + uDelta * uDelta + vDelta * vDelta;
-        }
-    }
-
-    /**
-     * Read YUV values from given position (x,y) for given origin (originX, originY)
-     * The whole data is already available from YBuffer and UVBuffer.
-     * @param result pass the result via this. This is for avoiding creating / destroying too many
-     *               instances
-     */
-    private void getPixelValuesFromYUVBuffers(int originX, int originY, int x, int y,
-            YUVValue result) {
-        result.mY = mYBuffer.get((originY + y) * mBufferWidth + (originX + x));
-        if (isSrcSemiPlanar()) {
-            int index = (originY + y) / 2 * mBufferWidth + (originX + x) / 2 * 2;
-            //Log.d(TAG, "YUV " + originX + "," + originY + "," + x + "," + y + "," + index);
-            result.mU = mUVBuffer.get(index);
-            result.mV = mUVBuffer.get(index + 1);
-        } else {
-            int vOffset = mBufferWidth * mBufferHeight / 4;
-            int index = (originY + y) / 2 * mBufferWidth / 2 + (originX + x) / 2;
-            result.mU = mUVBuffer.get(index);
-            result.mV = mUVBuffer.get(vOffset + index);
-        }
-    }
-
-    /**
-     * Read YUV pixels from decoded output buffer for give (x, y) position
-     * Output buffer is composed of Y parts followed by U/V
-     * @param result pass the result via this. This is for avoiding creating / destroying too many
-     *               instances
-     */
-    private void getPixelValuesFromOutputBuffer(ByteBuffer buffer, int x, int y, YUVValue result) {
-        result.mY = buffer.get(y * mVideoWidth + x);
-        if (isDstSemiPlanar()) {
-            int index = mVideoWidth * mVideoHeight + y / 2 * mVideoWidth + x / 2 * 2;
-            //Log.d(TAG, "Decoded " + x + "," + y + "," + index);
-            result.mU = buffer.get(index);
-            result.mV = buffer.get(index + 1);
-        } else {
-            int vOffset = mVideoWidth * mVideoHeight / 4;
-            int index = mVideoWidth * mVideoHeight + y / 2 * mVideoWidth / 2 + x / 2;
-            result.mU = buffer.get(index);
-            result.mV = buffer.get(index + vOffset);
-        }
-    }
-
-    private void getPixelValuesFromImage(Image image, int x, int y, YUVValue result) {
-        assertTrue(image.getFormat() == ImageFormat.YUV_420_888);
-
-        Plane[] planes = image.getPlanes();
-        assertTrue(planes.length == 3);
-
-        result.mY = getPixelFromPlane(planes[0], x, y);
-        result.mU = getPixelFromPlane(planes[1], x / 2, y / 2);
-        result.mV = getPixelFromPlane(planes[2], x / 2, y / 2);
-    }
-
-    private byte getPixelFromPlane(Plane plane, int x, int y) {
-        ByteBuffer buf = plane.getBuffer();
-        return buf.get(y * plane.getRowStride() + x * plane.getPixelStride());
-    }
-
-    /**
-     * Y cannot have full range. clamp it to prevent invalid value.
-     */
-    private byte clampY(int y) {
-        if (y < Y_CLAMP_MIN) {
-            y = Y_CLAMP_MIN;
-        } else if (y > Y_CLAMP_MAX) {
-            y = Y_CLAMP_MAX;
-        }
-        return (byte) (y & 0xff);
-    }
-
-    // for debugging
-    private void printByteArray(String msg, byte[] data, int offset, int len) {
-        StringBuilder builder = new StringBuilder();
-        builder.append(msg);
-        builder.append(":");
-        for (int i = offset; i < offset + len; i++) {
-            builder.append(Integer.toHexString(data[i]));
-            builder.append(",");
-        }
-        builder.deleteCharAt(builder.length() - 1);
-        Log.i(TAG, builder.toString());
-    }
-
-    // for debugging
-    private void printByteBuffer(String msg, ByteBuffer data, int offset, int len) {
-        StringBuilder builder = new StringBuilder();
-        builder.append(msg);
-        builder.append(":");
-        for (int i = offset; i < offset + len; i++) {
-            builder.append(Integer.toHexString(data.get(i)));
-            builder.append(",");
-        }
-        builder.deleteCharAt(builder.length() - 1);
-        Log.i(TAG, builder.toString());
-    }
-
-    /**
-     * Generates the presentation time for frame N, in microseconds.
-     */
-    private long computePresentationTime(int frameIndex) {
-        return 132 + frameIndex * 1000000L / mFrameRate;
-    }
-}
diff --git a/suite/cts/hostTests/Android.mk b/suite/cts/hostTests/Android.mk
deleted file mode 100644
index c141484..0000000
--- a/suite/cts/hostTests/Android.mk
+++ /dev/null
@@ -1,17 +0,0 @@
-#
-# Copyright (C) 2012 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT 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 $(call all-subdir-makefiles)
diff --git a/suite/cts/hostTests/jank/Android.mk b/suite/cts/hostTests/jank/Android.mk
deleted file mode 100644
index a1f4d90..0000000
--- a/suite/cts/hostTests/jank/Android.mk
+++ /dev/null
@@ -1,43 +0,0 @@
-# Copyright (C) 2013 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_MODULE := CtsHostJank
-
-LOCAL_JAVA_LIBRARIES := cts-tradefed tradefed-prebuilt
-
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
-
-LOCAL_CTS_TEST_PACKAGE := com.android.cts.jank
-
-LOCAL_DEVICE_JAR_ := CtsDeviceJank
-cts_library_jar_ := $(CTS_TESTCASES_OUT)/$(LOCAL_DEVICE_JAR_).jar
-
-$(cts_library_jar_): $(call intermediates-dir-for,JAVA_LIBRARIES,$(LOCAL_DEVICE_JAR_))/javalib.jar | $(ACP)
-	$(hide) mkdir -p $(CTS_TESTCASES_OUT)
-	$(hide) $(ACP) -fp $(call intermediates-dir-for,JAVA_LIBRARIES,$(LOCAL_DEVICE_JAR_))/javalib.jar $@
-
-$(CTS_TESTCASES_OUT)/CtsHostJank.xml: $(cts_library_jar_)
-
-include $(BUILD_CTS_HOST_JAVA_LIBRARY)
-
-# Build the library using its own makefile
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/suite/cts/hostTests/jank/app/Android.mk b/suite/cts/hostTests/jank/app/Android.mk
deleted file mode 100644
index 8f4fce6..0000000
--- a/suite/cts/hostTests/jank/app/Android.mk
+++ /dev/null
@@ -1,28 +0,0 @@
-# Copyright (C) 2013 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE := CtsDeviceJank
-LOCAL_DEX_PREOPT := false
-
-LOCAL_JAVA_LIBRARIES := uiautomator.core
-
-LOCAL_STATIC_JAVA_LIBRARIES := com.android.uiautomator.platform.common
-
-include $(BUILD_JAVA_LIBRARY)
\ No newline at end of file
diff --git a/suite/cts/hostTests/jank/app/src/com/android/cts/jank/CtsJankTestBase.java b/suite/cts/hostTests/jank/app/src/com/android/cts/jank/CtsJankTestBase.java
deleted file mode 100644
index 6d5162b..0000000
--- a/suite/cts/hostTests/jank/app/src/com/android/cts/jank/CtsJankTestBase.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package com.android.cts.jank;
-
-import android.os.Bundle;
-import android.util.Log;
-
-import com.android.uiautomator.platform.JankTestBase;
-
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.util.Scanner;
-
-public class CtsJankTestBase extends JankTestBase {
-    private final static String TAG = CtsJankTestBase.class.getName();
-    protected final static String START_CMD = "am start -W -a android.intent.action.MAIN -n %s";
-    protected final static String STOP_CMD = "am force-stop %s";
-    protected final static String INTENT_STRING_EXTRA = " --es %s %s";
-    protected final static String INTENT_BOOLEAN_EXTRA = " --ez %s %b";
-    protected final static String INTENT_INTEGER_EXTRA = " --ei %s %d";
-    protected static long SLEEP_TIME = 2000; // 2 seconds
-    protected static int NUM_ITERATIONS = 5;
-    protected static int TRACE_TIME = 5;
-
-    @Override
-    protected String getPropertyString(Bundle params, String key)
-            throws FileNotFoundException, IOException {
-        if (key.equals("iteration")) {
-            return NUM_ITERATIONS + "";
-        }
-        if (key.equals("tracetime")) {
-            return TRACE_TIME + "";
-        }
-        return super.getPropertyString(params, key);
-    }
-
-    protected void runShellCommand(String command) throws Exception {
-        Process p = null;
-        Scanner out = null;
-        Scanner err = null;
-        try {
-            p = Runtime.getRuntime().exec(command);
-
-            StringBuilder outStr = new StringBuilder();
-            StringBuilder errStr = new StringBuilder();
-            out = new Scanner(p.getInputStream());
-            err = new Scanner(p.getErrorStream());
-            boolean read = true;
-            while (read) {
-                if (out.hasNextLine()) {
-                    outStr.append(out.nextLine());
-                    outStr.append("\n");
-                } else if (err.hasNextLine()) {
-                    errStr.append(err.nextLine());
-                    errStr.append("\n");
-                } else {
-                    read = false;
-                }
-            }
-            Log.i(TAG, command);
-            if (outStr.length() > 0) {
-                Log.i(TAG, outStr.toString());
-            }
-            if (errStr.length() > 0) {
-                Log.e(TAG, errStr.toString());
-            }
-        } finally {
-            if (p != null) {
-                int status = p.waitFor();
-                if (status != 0) {
-                    throw new RuntimeException(
-                            String.format("Run shell command: %s, status: %s", command, status));
-                }
-                p.destroy();
-                p = null;
-            }
-            if (out != null) {
-                out.close();
-            }
-            if (err != null) {
-                err.close();
-            }
-        }
-    }
-}
diff --git a/suite/cts/hostTests/jank/app/src/com/android/cts/jank/opengl/CtsDeviceJankOpenGl.java b/suite/cts/hostTests/jank/app/src/com/android/cts/jank/opengl/CtsDeviceJankOpenGl.java
deleted file mode 100755
index 5ba0613..0000000
--- a/suite/cts/hostTests/jank/app/src/com/android/cts/jank/opengl/CtsDeviceJankOpenGl.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package com.android.cts.jank.opengl;
-
-import android.util.Log;
-
-import com.android.cts.jank.CtsJankTestBase;
-import com.android.uiautomator.platform.SurfaceFlingerHelper;
-
-public class CtsDeviceJankOpenGl extends CtsJankTestBase {
-    private final static String TAG = CtsDeviceJankOpenGl.class.getName();
-    private final static String PACKAGE = "com.android.cts.opengl";
-    private final static String COMPONENT =
-            PACKAGE + "/" + PACKAGE + ".primitive.GLPrimitiveActivity";
-    private static String APP_WINDOW_NAME = "SurfaceView";
-
-    /**
-     * Runs the full OpenGL ES 2.0 pipeline test.
-     */
-    public void testFullPipeline() throws Exception {
-        runBenchmark("FullPipeline");
-    }
-
-    /**
-     * Runs the pixel output test.
-     */
-    public void testPixelOutput() throws Exception {
-        runBenchmark("PixelOutput");
-    }
-
-    /**
-     * Runs the shader performance test.
-     */
-    public void testShaderPerf() throws Exception {
-        runBenchmark("ShaderPerf");
-    }
-
-    /**
-     * Runs the context switch overhead test.
-     */
-    public void testContextSwitch() throws Exception {
-        runBenchmark("ContextSwitch");
-    }
-
-    /**
-     * Runs the benchhmark for jank test.
-     */
-    public void runBenchmark(String benchmark) throws Exception {
-        // Start activity command
-        final StringBuilder sb = new StringBuilder();
-        sb.append(String.format(START_CMD, COMPONENT));
-        sb.append(String.format(INTENT_STRING_EXTRA, "benchmark_name", benchmark));
-        sb.append(String.format(INTENT_BOOLEAN_EXTRA, "offscreen", false));
-        sb.append(String.format(INTENT_INTEGER_EXTRA, "num_frames", 1000));
-        sb.append(String.format(INTENT_INTEGER_EXTRA, "num_iterations", 1));
-        sb.append(String.format(INTENT_INTEGER_EXTRA, "timeout", 10000));
-        final String startCommand = sb.toString();
-        final String stopCommand = String.format(STOP_CMD, PACKAGE);
-
-        Log.i(TAG, "Start command: " + startCommand);
-        Log.i(TAG, "Stop command: " + stopCommand);
-
-        setIteration(NUM_ITERATIONS);
-        for (int i = 0; i < NUM_ITERATIONS; i++) {
-            // Stop any existing instances
-            runShellCommand(stopCommand);
-            // Start activity
-            runShellCommand(startCommand);
-
-            // Wait for the activity to start
-            sleep(SLEEP_TIME / 2);
-
-            // Start systrace
-            startTrace(mTestCaseName, i);
-
-            // Clear SurfaceFlinger buffer
-            Log.i(TAG, "Clearing SurfaceFlinger buffer");
-            SurfaceFlingerHelper.clearBuffer(APP_WINDOW_NAME);
-
-            // This is where user interactions would go, in this case just sleep
-            sleep(SLEEP_TIME);
-
-            // Dump SurfaceFlinger buffer
-            Log.i(TAG, "Dumping SurfaceFlinger buffer");
-            boolean result = SurfaceFlingerHelper.dumpFrameLatency(APP_WINDOW_NAME, true);
-            assertTrue("SurfaceFlingerHelper could not get timestamps", result);
-
-            // Stop systrace
-            endTrace();
-
-            // Record results
-            recordResults(mTestCaseName, i);
-        }
-        // Save aggregated results
-        saveResults(mTestCaseName);
-        // Stop any remaining instances
-        runShellCommand(stopCommand);
-    }
-}
diff --git a/suite/cts/hostTests/jank/src/com/android/cts/jank/CtsHostJankTest.java b/suite/cts/hostTests/jank/src/com/android/cts/jank/CtsHostJankTest.java
deleted file mode 100644
index e196bfb..0000000
--- a/suite/cts/hostTests/jank/src/com/android/cts/jank/CtsHostJankTest.java
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.android.cts.jank;
-
-import com.android.cts.tradefed.build.CtsBuildHelper;
-import com.android.cts.tradefed.util.HostReportLog;
-import com.android.cts.util.ResultType;
-import com.android.cts.util.ResultUnit;
-import com.android.ddmlib.IShellOutputReceiver;
-import com.android.ddmlib.Log;
-import com.android.ddmlib.Log.LogLevel;
-import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.testtype.DeviceTestCase;
-import com.android.tradefed.testtype.IAbi;
-import com.android.tradefed.testtype.IAbiReceiver;
-import com.android.tradefed.testtype.IBuildReceiver;
-
-import java.io.File;
-import java.util.HashMap;
-import java.util.Scanner;
-
-public class CtsHostJankTest extends DeviceTestCase implements IAbiReceiver, IBuildReceiver {
-
-    private static final String TAG = CtsHostJankTest.class.getSimpleName();
-    private static final String DEVICE_LOCATION = "/data/local/tmp/";
-    // FIXME uiautomator is deprecated and does not support --abi flag
-    private static final String RUN_UI_AUTOMATOR_CMD = "uiautomator runtest %s -c %s";
-    private final String mHostTestClass;
-    private final String mDeviceTestClass;
-    private final String mJarName;
-    private final String mJarPath;
-    protected ITestDevice mDevice;
-    protected CtsBuildHelper mBuild;
-    protected IAbi mAbi;
-
-    public CtsHostJankTest(String jarName, String deviceTestClass, String hostTestClass) {
-        this.mHostTestClass = hostTestClass;
-        this.mDeviceTestClass = deviceTestClass;
-        this.mJarName = jarName;
-        this.mJarPath = DEVICE_LOCATION + jarName;
-    }
-
-    @Override
-    public void setAbi(IAbi abi) {
-        mAbi = abi;
-    }
-
-    @Override
-    public void setBuild(IBuildInfo buildInfo) {
-        mBuild = CtsBuildHelper.createBuildHelper(buildInfo);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mDevice = getDevice();
-        // Push jar to device.
-        File jarFile = mBuild.getTestApp(mJarName);
-        boolean result = mDevice.pushFile(jarFile, mJarPath);
-        assertTrue("Failed to push file to " + mJarPath, result);
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        // Delete jar from device.
-        mDevice.executeShellCommand("rm " + mJarPath);
-        super.tearDown();
-    }
-
-    public void runUiAutomatorTest(String testName) throws Exception {
-        // Delete any existing result files
-        mDevice.executeShellCommand("rm -r " + DEVICE_LOCATION + "*.txt");
-
-        // Run ui automator test.
-        mDevice.executeShellCommand(
-                String.format(RUN_UI_AUTOMATOR_CMD, mJarName, mDeviceTestClass + "#" + testName),
-                new IShellOutputReceiver() {
-                    private StringBuilder sb = new StringBuilder();
-
-                    @Override
-                    public void addOutput(byte[] data, int offset, int length) {
-                        byte[] raw = new byte[length];
-                        for (int i = 0; i < length; i++) {
-                            raw[i] = data[i + offset];
-                        }
-                        sb.append(new String(raw));
-                    }
-
-                    @Override
-                    public void flush() {
-                        Log.logAndDisplay(LogLevel.INFO, TAG, sb.toString());
-                    }
-
-                    @Override
-                    public boolean isCancelled() {
-                        return false;
-                    }
-                });
-
-        // Pull result file across
-        File result = mDevice.pullFile(DEVICE_LOCATION + "UiJankinessTestsOutput.txt");
-        assertNotNull("Couldn't get result file", result);
-        // Parse result file
-        Scanner in = new Scanner(result);
-        HashMap<String, Double> results = new HashMap<String, Double>(4);
-        while (in.hasNextLine()) {
-            String[] parts = in.nextLine().split(":");
-            if (parts.length == 2) {
-                results.put(parts[0], Double.parseDouble(parts[1]));
-            }
-        }
-        in.close();
-        Log.logAndDisplay(LogLevel.INFO, TAG, "Results: " + results);
-        assertEquals("Could not parse the results file: ", 4, results.size());
-
-        double avgNumJanks = results.get("average number of jankiness");
-        double maxNumJanks = results.get("max number of jankiness");
-        double avgFrameRate = results.get("average frame rate");
-        double avgMaxAccFrames = results.get("average of max accumulated frames");
-
-        // Create and deliver the report.
-        HostReportLog report = new HostReportLog(mDevice.getSerialNumber(), mAbi.getName(),
-                mHostTestClass + "#" + testName);
-        report.printValue(
-                "Average Frame Rate", avgFrameRate, ResultType.HIGHER_BETTER, ResultUnit.COUNT);
-        report.printValue("Average of Maximum Accumulated Frames", avgMaxAccFrames,
-                ResultType.LOWER_BETTER, ResultUnit.COUNT);
-        report.printValue(
-                "Maximum Number of Janks", maxNumJanks, ResultType.LOWER_BETTER, ResultUnit.COUNT);
-        report.printSummary(
-                "Average Number of Janks", avgNumJanks, ResultType.LOWER_BETTER, ResultUnit.SCORE);
-        report.deliverReportToHost();
-    }
-
-}
diff --git a/suite/cts/hostTests/jank/src/com/android/cts/jank/opengl/CtsHostJankOpenGl.java b/suite/cts/hostTests/jank/src/com/android/cts/jank/opengl/CtsHostJankOpenGl.java
deleted file mode 100644
index 2942ecf..0000000
--- a/suite/cts/hostTests/jank/src/com/android/cts/jank/opengl/CtsHostJankOpenGl.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.android.cts.jank.opengl;
-
-import com.android.cts.jank.CtsHostJankTest;
-import com.android.cts.util.AbiUtils;
-import java.io.File;
-
-public class CtsHostJankOpenGl extends CtsHostJankTest {
-
-    private static final String APK_PACKAGE = "com.android.cts";
-    private static final String APK = "CtsDeviceOpenGl.apk";
-    private static final String PACKAGE = "com.android.cts.jank.opengl";
-    private static final String HOST_CLASS = CtsHostJankOpenGl.class.getName();
-    private static final String DEVICE_CLASS = PACKAGE + ".CtsDeviceJankOpenGl";
-    private static final String JAR_NAME = "CtsDeviceJank.jar";
-
-    public CtsHostJankOpenGl() {
-        super(JAR_NAME, DEVICE_CLASS, HOST_CLASS);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        // Install the app.
-        mDevice.uninstallPackage(APK_PACKAGE);
-        File app = mBuild.getTestApp(APK);
-        String[] options = {AbiUtils.createAbiFlag(mAbi.getName())};
-        mDevice.installPackage(app, false, options);
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        // Uninstall the app.
-        mDevice.uninstallPackage(APK_PACKAGE);
-        super.tearDown();
-    }
-
-    public void testFullPipeline() throws Exception {
-        runUiAutomatorTest("testFullPipeline");
-    }
-
-    public void testPixelOutput() throws Exception {
-        runUiAutomatorTest("testPixelOutput");
-    }
-
-    public void testShaderPerf() throws Exception {
-        runUiAutomatorTest("testShaderPerf");
-    }
-
-    public void testContextSwitch() throws Exception {
-        runUiAutomatorTest("testContextSwitch");
-    }
-}
diff --git a/suite/cts/hostTests/uihost/.gitignore b/suite/cts/hostTests/uihost/.gitignore
deleted file mode 100644
index 5e56e04..0000000
--- a/suite/cts/hostTests/uihost/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-/bin
diff --git a/suite/cts/hostTests/uihost/Android.mk b/suite/cts/hostTests/uihost/Android.mk
deleted file mode 100644
index 67ebcbb..0000000
--- a/suite/cts/hostTests/uihost/Android.mk
+++ /dev/null
@@ -1,33 +0,0 @@
-# Copyright (C) 2012 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_MODULE := CtsHostUi
-
-LOCAL_JAVA_LIBRARIES := cts-tradefed tradefed-prebuilt
-
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
-
-LOCAL_CTS_TEST_PACKAGE := com.android.cts.uihost
-
-include $(BUILD_CTS_HOST_JAVA_LIBRARY)
-
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/suite/cts/hostTests/uihost/appA/Android.mk b/suite/cts/hostTests/uihost/appA/Android.mk
deleted file mode 100644
index 17f076f..0000000
--- a/suite/cts/hostTests/uihost/appA/Android.mk
+++ /dev/null
@@ -1,31 +0,0 @@
-# Copyright (C) 2012 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-# don't include this package in any target
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-
-LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctstestrunner
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_PACKAGE_NAME := CtsDeviceTaskswitchingAppA
-
-LOCAL_SDK_VERSION := current
-
-include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/suite/cts/hostTests/uihost/appA/AndroidManifest.xml b/suite/cts/hostTests/uihost/appA/AndroidManifest.xml
deleted file mode 100644
index b97325c..0000000
--- a/suite/cts/hostTests/uihost/appA/AndroidManifest.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2012 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.taskswitching.appa" >
-
-    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
-
-    <application>
-        <activity
-            android:name=".AppAActivity"
-            android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode"
-            android:screenOrientation="portrait" >
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-    </application>
-
-</manifest>
\ No newline at end of file
diff --git a/suite/cts/hostTests/uihost/appA/src/com/android/cts/taskswitching/appa/AppAActivity.java b/suite/cts/hostTests/uihost/appA/src/com/android/cts/taskswitching/appa/AppAActivity.java
deleted file mode 100644
index a4207a0..0000000
--- a/suite/cts/hostTests/uihost/appA/src/com/android/cts/taskswitching/appa/AppAActivity.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.taskswitching.appa;
-
-
-import android.app.ListActivity;
-import android.content.Intent;
-
-import android.os.Bundle;
-import android.os.Handler;
-import android.view.WindowManager;
-import android.widget.ArrayAdapter;
-import android.widget.ListView;
-
-/**
- * Simple activity to notify completion via broadcast after onResume.
- * This is for measuring taskswitching time between two apps.
- */
-public class AppAActivity extends ListActivity {
-    static final String TAG = "AppAActivity";
-    private static final int NUMBER_ELEMENTS = 1000;
-    private static final String TASKSWITCHING_INTENT = "com.android.cts.taskswitching.appa";
-    private Handler mHandler;
-
-    private String[] mItems = new String[NUMBER_ELEMENTS];
-
-    public void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-        getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
-        for (int i = 0; i < NUMBER_ELEMENTS; i++) {
-            mItems[i] = "A" + Integer.toString(i);
-        }
-        setListAdapter(new ArrayAdapter<String>(this,
-                android.R.layout.simple_list_item_1, mItems));
-        ListView view = getListView();
-        mHandler = new Handler();
-    }
-
-    public void onResume() {
-        super.onResume();
-        mHandler.post(new Runnable() {
-
-            @Override
-            public void run() {
-                Intent intent = new Intent(TASKSWITCHING_INTENT);
-                sendBroadcast(intent);
-            }
-        });
-    }
-}
diff --git a/suite/cts/hostTests/uihost/appB/Android.mk b/suite/cts/hostTests/uihost/appB/Android.mk
deleted file mode 100644
index ebb36d2..0000000
--- a/suite/cts/hostTests/uihost/appB/Android.mk
+++ /dev/null
@@ -1,31 +0,0 @@
-# Copyright (C) 2012 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-# don't include this package in any target
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-
-LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctstestrunner
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_PACKAGE_NAME := CtsDeviceTaskswitchingAppB
-
-LOCAL_SDK_VERSION := current
-
-include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/suite/cts/hostTests/uihost/appB/AndroidManifest.xml b/suite/cts/hostTests/uihost/appB/AndroidManifest.xml
deleted file mode 100644
index b96afe5..0000000
--- a/suite/cts/hostTests/uihost/appB/AndroidManifest.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-        package="com.android.cts.taskswitching.appb">
-
-    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
-
-    <application>
-        <activity
-            android:name=".AppBActivity"
-            android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode"
-            android:screenOrientation="portrait" >
-
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER"/>
-            </intent-filter>
-        </activity>
-    </application>
-</manifest>
diff --git a/suite/cts/hostTests/uihost/appB/src/com/android/cts/taskswitching/appb/AppBActivity.java b/suite/cts/hostTests/uihost/appB/src/com/android/cts/taskswitching/appb/AppBActivity.java
deleted file mode 100644
index 4df5e98..0000000
--- a/suite/cts/hostTests/uihost/appB/src/com/android/cts/taskswitching/appb/AppBActivity.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.taskswitching.appb;
-
-import android.app.ListActivity;
-import android.content.Intent;
-import android.os.Bundle;
-import android.os.Handler;
-import android.view.WindowManager;
-import android.widget.ArrayAdapter;
-import android.widget.ListView;
-
-/**
- * Simple activity to notify completion via broadcast after onResume.
- * This is for measuring taskswitching time between two apps.
- */
-public class AppBActivity extends ListActivity {
-    static final String TAG = "AppBActivity";
-    private static final int NUMBER_ELEMENTS = 1000;
-    private static final String TASKSWITCHING_INTENT = "com.android.cts.taskswitching.appb";
-    private Handler mHandler;
-
-    private String[] mItems = new String[NUMBER_ELEMENTS];
-
-    public void onCreate(Bundle icicle)
-    {
-        super.onCreate(icicle);
-        getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
-        for (int i = 0; i < NUMBER_ELEMENTS; i++) {
-            mItems[i] = "B" + Integer.toString(i);
-        }
-        setListAdapter(new ArrayAdapter<String>(this,
-                android.R.layout.simple_list_item_1, mItems));
-        ListView view = getListView();
-        mHandler = new Handler();
-    }
-
-    public void onResume()
-    {
-        super.onResume();
-        mHandler.post(new Runnable() {
-
-            @Override
-            public void run() {
-                Intent intent = new Intent(TASKSWITCHING_INTENT);
-                sendBroadcast(intent);
-            }
-        });
-    }
-}
diff --git a/suite/cts/hostTests/uihost/control/Android.mk b/suite/cts/hostTests/uihost/control/Android.mk
deleted file mode 100644
index 4de9ae8..0000000
--- a/suite/cts/hostTests/uihost/control/Android.mk
+++ /dev/null
@@ -1,31 +0,0 @@
-# Copyright (C) 2012 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-# don't include this package in any target
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-
-LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctstestrunner
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_PACKAGE_NAME := CtsDeviceTaskswitchingControl
-
-LOCAL_SDK_VERSION := current
-
-include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/suite/cts/hostTests/uihost/control/AndroidManifest.xml b/suite/cts/hostTests/uihost/control/AndroidManifest.xml
deleted file mode 100644
index e4b10f2..0000000
--- a/suite/cts/hostTests/uihost/control/AndroidManifest.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-        package="com.android.cts.taskswitching.control">
-
-    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
-
-    <application>
-        <uses-library android:name="android.test.runner" />
-    </application>
-    <instrumentation
-        android:targetPackage="com.android.cts.taskswitching.control"
-        android:name="android.support.test.runner.AndroidJUnitRunner" >
-        <meta-data
-            android:name="listener"
-            android:value="com.android.cts.runner.CtsTestRunListener" />
-    </instrumentation>
-</manifest>
diff --git a/suite/cts/hostTests/uihost/control/src/com/android/cts/taskswitching/control/TaskswitchingDeviceTest.java b/suite/cts/hostTests/uihost/control/src/com/android/cts/taskswitching/control/TaskswitchingDeviceTest.java
deleted file mode 100644
index bdb3132..0000000
--- a/suite/cts/hostTests/uihost/control/src/com/android/cts/taskswitching/control/TaskswitchingDeviceTest.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.taskswitching.control;
-
-import java.util.concurrent.Semaphore;
-import java.util.concurrent.TimeUnit;
-
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-
-import com.android.cts.util.MeasureRun;
-import com.android.cts.util.MeasureTime;
-import com.android.cts.util.ResultType;
-import com.android.cts.util.ResultUnit;
-import android.cts.util.CtsAndroidTestCase;
-import com.android.cts.util.Stat;
-
-
-/**
- * Device test which actually launches two apps sequentially and
- * measure time for switching.
- * Completion of launch is notified via broadcast.
- */
-public class TaskswitchingDeviceTest extends CtsAndroidTestCase {
-    private static final String PKG_A = "com.android.cts.taskswitching.appa";
-    private static final String PKG_B = "com.android.cts.taskswitching.appb";
-    private static final String ACTIVITY_A = "AppAActivity";
-    private static final String ACTIVITY_B = "AppBActivity";
-    private static final long TASK_SWITCHING_WAIT_TIME = 5;
-    private final AppBroadcastReceiver mReceiverA = new AppBroadcastReceiver();
-    private final AppBroadcastReceiver mReceiverB = new AppBroadcastReceiver();
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        startActivity(PKG_A, ACTIVITY_A);
-        startActivity(PKG_B, ACTIVITY_B);
-        IntentFilter filterA = new IntentFilter();
-        filterA.addAction(PKG_A);
-        IntentFilter filterB = new IntentFilter();
-        filterB.addAction(PKG_B);
-        getContext().registerReceiver(mReceiverA, filterA);
-        getContext().registerReceiver(mReceiverB, filterB);
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        getContext().unregisterReceiver(mReceiverA);
-        getContext().unregisterReceiver(mReceiverB);
-        super.tearDown();
-    }
-
-    public void testMeasureTaskSwitching() throws Exception {
-        final int NUMBER_REPEAT = 10;
-        final int SWITCHING_PER_ONE_TRY = 10;
-
-        double[] results = MeasureTime.measure(NUMBER_REPEAT, new MeasureRun() {
-
-            @Override
-            public void run(int i) throws Exception {
-                for (int j = 0; j < SWITCHING_PER_ONE_TRY; j++) {
-                    startActivity(PKG_A, ACTIVITY_A);
-                    assertTrue(mReceiverA.waitForBroadcast(TASK_SWITCHING_WAIT_TIME));
-                    startActivity(PKG_B, ACTIVITY_B);
-                    assertTrue(mReceiverB.waitForBroadcast(TASK_SWITCHING_WAIT_TIME));
-                }
-            }
-        });
-        getReportLog().printArray("taskswitching time", results, ResultType.LOWER_BETTER,
-                ResultUnit.MS);
-        Stat.StatResult stat = Stat.getStat(results);
-        getReportLog().printSummary("taskswitching time", stat.mAverage,
-                ResultType.LOWER_BETTER, ResultUnit.MS);
-    }
-
-    private void startActivity(String packageName, String activityName) {
-        Context context = getContext();
-        Intent intent = new Intent();
-        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        intent.addCategory(Intent.CATEGORY_LAUNCHER);
-        intent.setComponent(new ComponentName(packageName, packageName + "." + activityName));
-        context.startActivity(intent);
-    }
-
-    class AppBroadcastReceiver extends BroadcastReceiver {
-        private final Semaphore mSemaphore = new Semaphore(0);
-
-        public boolean waitForBroadcast(long timeoutInSec) throws InterruptedException {
-            return mSemaphore.tryAcquire(timeoutInSec, TimeUnit.SECONDS);
-        }
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            mSemaphore.release();
-        }
-    }
-}
diff --git a/suite/cts/hostTests/uihost/src/com/android/cts/uihost/InstallTimeTest.java b/suite/cts/hostTests/uihost/src/com/android/cts/uihost/InstallTimeTest.java
deleted file mode 100644
index 75a2e92..0000000
--- a/suite/cts/hostTests/uihost/src/com/android/cts/uihost/InstallTimeTest.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.uihost;
-
-import com.android.cts.tradefed.build.CtsBuildHelper;
-import com.android.cts.tradefed.util.HostReportLog;
-import com.android.cts.util.AbiUtils;
-import com.android.cts.util.MeasureRun;
-import com.android.cts.util.MeasureTime;
-import com.android.cts.util.ResultType;
-import com.android.cts.util.ResultUnit;
-import com.android.cts.util.ReportLog;
-import com.android.cts.util.Stat;
-import com.android.ddmlib.Log;
-import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.testtype.DeviceTestCase;
-import com.android.tradefed.testtype.IAbi;
-import com.android.tradefed.testtype.IAbiReceiver;
-import com.android.tradefed.testtype.IBuildReceiver;
-
-import java.io.File;
-
-
-/**
- * Test to measure installation time of a APK.
- */
-public class InstallTimeTest extends DeviceTestCase implements IAbiReceiver, IBuildReceiver {
-    private CtsBuildHelper mBuild;
-    private ITestDevice mDevice;
-    private IAbi mAbi;
-
-    private static final String TAG = "InstallTimeTest";
-    static final String PACKAGE = "com.replica.replicaisland";
-    static final String APK = "com.replica.replicaisland.apk";
-    private static final double OUTLIER_THRESHOLD = 0.1;
-
-    @Override
-    public void setAbi(IAbi abi) {
-        mAbi = abi;
-    }
-
-    @Override
-    public void setBuild(IBuildInfo buildInfo) {
-        mBuild = CtsBuildHelper.createBuildHelper(buildInfo);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mDevice = getDevice();
-    }
-
-
-    @Override
-    protected void tearDown() throws Exception {
-        mDevice.uninstallPackage(PACKAGE);
-        super.tearDown();
-    }
-
-    public void testInstallTime() throws Exception {
-        HostReportLog report = new HostReportLog(mDevice.getSerialNumber(), mAbi.getName(),
-                ReportLog.getClassMethodNames());
-        final int NUMBER_REPEAT = 10;
-        final CtsBuildHelper build = mBuild;
-        final ITestDevice device = mDevice;
-        double[] result = MeasureTime.measure(NUMBER_REPEAT, new MeasureRun() {
-            @Override
-            public void prepare(int i) throws Exception {
-                device.uninstallPackage(PACKAGE);
-            }
-            @Override
-            public void run(int i) throws Exception {
-                File app = build.getTestApp(APK);
-                String[] options = {AbiUtils.createAbiFlag(mAbi.getName())};
-                device.installPackage(app, false, options);
-            }
-        });
-        report.printArray("install time", result, ResultType.LOWER_BETTER,
-                ResultUnit.MS);
-        Stat.StatResult stat = Stat.getStatWithOutlierRejection(result, OUTLIER_THRESHOLD);
-        if (stat.mDataCount != result.length) {
-            Log.w(TAG, "rejecting " + (result.length - stat.mDataCount) + " outliers");
-        }
-        report.printSummary("install time", stat.mAverage, ResultType.LOWER_BETTER,
-                ResultUnit.MS);
-        report.deliverReportToHost();
-    }
-
-}
diff --git a/suite/cts/hostTests/uihost/src/com/android/cts/uihost/TaskSwitchingTest.java b/suite/cts/hostTests/uihost/src/com/android/cts/uihost/TaskSwitchingTest.java
deleted file mode 100644
index 2d33436..0000000
--- a/suite/cts/hostTests/uihost/src/com/android/cts/uihost/TaskSwitchingTest.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.uihost;
-
-import com.android.cts.tradefed.build.CtsBuildHelper;
-import com.android.cts.tradefed.util.CtsHostStore;
-import com.android.cts.tradefed.util.HostReportLog;
-import com.android.cts.util.AbiUtils;
-import com.android.cts.util.ReportLog;
-import com.android.cts.util.TimeoutReq;
-import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
-import com.android.ddmlib.testrunner.TestIdentifier;
-import com.android.ddmlib.testrunner.TestRunResult;
-import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.result.CollectingTestListener;
-import com.android.tradefed.testtype.DeviceTestCase;
-import com.android.tradefed.testtype.IAbi;
-import com.android.tradefed.testtype.IAbiReceiver;
-import com.android.tradefed.testtype.IBuildReceiver;
-
-import java.io.File;
-import java.util.Map;
-
-
-/**
- * Measure time to taskswitching between two Apps: A & B
- * Actual test is done in device, but this host side code installs all necessary APKs
- * and starts device test which is in CtsDeviceTaskswitchingControl.
- */
-public class TaskSwitchingTest extends DeviceTestCase implements IAbiReceiver, IBuildReceiver {
-    private static final String TAG = "TaskSwitchingTest";
-    private final static String RUNNER = "android.support.test.runner.AndroidJUnitRunner";
-    private CtsBuildHelper mBuild;
-    private ITestDevice mDevice;
-    private String mCtsReport = null;
-    private IAbi mAbi;
-
-    static final String[] PACKAGES = {
-        "com.android.cts.taskswitching.control",
-        "com.android.cts.taskswitching.appa",
-        "com.android.cts.taskswitching.appb"
-    };
-    static final String[] APKS = {
-        "CtsDeviceTaskswitchingControl.apk",
-        "CtsDeviceTaskswitchingAppA.apk",
-        "CtsDeviceTaskswitchingAppB.apk"
-    };
-
-    @Override
-    public void setAbi(IAbi abi) {
-        mAbi = abi;
-    }
-
-    @Override
-    public void setBuild(IBuildInfo buildInfo) {
-        mBuild = CtsBuildHelper.createBuildHelper(buildInfo);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mDevice = getDevice();
-        String[] options = {AbiUtils.createAbiFlag(mAbi.getName())};
-        for (int i = 0; i < PACKAGES.length; i++) {
-            mDevice.uninstallPackage(PACKAGES[i]);
-            File app = mBuild.getTestApp(APKS[i]);
-            mDevice.installPackage(app, false, options);
-        }
-    }
-
-
-    @Override
-    protected void tearDown() throws Exception {
-        for (int i = 0; i < PACKAGES.length; i++) {
-            mDevice.uninstallPackage(PACKAGES[i]);
-        }
-        super.tearDown();
-    }
-
-    @TimeoutReq(minutes = 30)
-    public void testTaskswitching() throws Exception {
-        // TODO is this used?
-        HostReportLog report = new HostReportLog(mDevice.getSerialNumber(), mAbi.getName(),
-                ReportLog.getClassMethodNames());
-        RemoteAndroidTestRunner testRunner = new RemoteAndroidTestRunner(PACKAGES[0], RUNNER,
-                mDevice.getIDevice());
-        LocalListener listener = new LocalListener();
-        mDevice.runInstrumentationTests(testRunner, listener);
-        TestRunResult result = listener.getCurrentRunResults();
-        if (result.isRunFailure()) {
-            fail(result.getRunFailureMessage());
-        }
-        assertNotNull("no performance data", mCtsReport);
-        CtsHostStore.storeCtsResult(mDevice.getSerialNumber(), mAbi.getName(),
-                ReportLog.getClassMethodNames(), mCtsReport);
-
-    }
-
-    public class LocalListener extends CollectingTestListener {
-        @Override
-        public void testEnded(TestIdentifier test, Map<String, String> testMetrics) {
-            // necessary as testMetrics passed from CollectingTestListerner is empty
-            if (testMetrics.containsKey("CTS_TEST_RESULT")) {
-                mCtsReport = testMetrics.get("CTS_TEST_RESULT");
-            }
-            super.testEnded(test, testMetrics);
-        }
-    }
-}
diff --git a/test_defs.sh b/test_defs.sh
new file mode 100644
index 0000000..5d5090d
--- /dev/null
+++ b/test_defs.sh
@@ -0,0 +1,47 @@
+#!/bin/bash
+
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Common tools for running unit tests of the compatibility libs
+
+JAR_DIR=${ANDROID_HOST_OUT}/framework
+TF_CONSOLE=com.android.tradefed.command.Console
+
+COMMON_JARS="
+    ddmlib-prebuilt\
+    hosttestlib\
+    tradefed-prebuilt"
+
+checkFile() {
+    if [ ! -f "$1" ]; then
+        echo "Unable to locate $1"
+        exit
+    fi;
+}
+
+build_jar_path() {
+    JAR_PATH=
+    for JAR in ${2} ${COMMON_JARS}; do
+        checkFile ${1}/${JAR}.jar
+        JAR_PATH=${JAR_PATH}:${1}/${JAR}.jar
+    done
+}
+
+run_tests() {
+    build_jar_path "${JAR_DIR}" "${2}"
+    for CLASS in ${1}; do
+        java $RDBG_FLAG -cp ${JAR_PATH} ${TF_CONSOLE} run singleCommand host -n --class ${CLASS} ${3}
+    done
+}
diff --git a/tests/JobScheduler/Android.mk b/tests/JobScheduler/Android.mk
index 499abded..153a4fd 100755
--- a/tests/JobScheduler/Android.mk
+++ b/tests/JobScheduler/Android.mk
@@ -26,8 +26,11 @@
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 # Must match the package name in CtsTestCaseList.mk
-LOCAL_PACKAGE_NAME := CtsJobSchedulerDeviceTestCases
+LOCAL_PACKAGE_NAME := CtsJobSchedulerTestCases
 
 LOCAL_SDK_VERSION := current
 
diff --git a/tests/JobScheduler/AndroidManifest.xml b/tests/JobScheduler/AndroidManifest.xml
index 17cf399..2078978 100755
--- a/tests/JobScheduler/AndroidManifest.xml
+++ b/tests/JobScheduler/AndroidManifest.xml
@@ -16,7 +16,7 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.jobscheduler.cts.deviceside">
+    package="android.jobscheduler.cts">
 
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
@@ -35,7 +35,7 @@
     <instrumentation
         android:name="android.support.test.runner.AndroidJUnitRunner"
         android:label="JobScheduler device-side tests"
-        android:targetPackage="android.jobscheduler.cts.deviceside" >
+        android:targetPackage="android.jobscheduler.cts" >
         <meta-data
             android:name="listener"
             android:value="com.android.cts.runner.CtsTestRunListener" />
diff --git a/tests/JobScheduler/AndroidTest.xml b/tests/JobScheduler/AndroidTest.xml
new file mode 100644
index 0000000..57a2f30
--- /dev/null
+++ b/tests/JobScheduler/AndroidTest.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS Job Scheduler test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsJobSchedulerTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.jobscheduler.cts" />
+        <option name="runtime-hint" value="2m" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/JobScheduler/src/android/jobscheduler/cts/TimingConstraintsTest.java b/tests/JobScheduler/src/android/jobscheduler/cts/TimingConstraintsTest.java
index 40b67c8..62c7124 100644
--- a/tests/JobScheduler/src/android/jobscheduler/cts/TimingConstraintsTest.java
+++ b/tests/JobScheduler/src/android/jobscheduler/cts/TimingConstraintsTest.java
@@ -41,18 +41,6 @@
         assertTrue("Timed out waiting for override deadline.", executed);
     }
 
-    public void testSchedulePeriodic() throws Exception {
-        JobInfo periodicJob =
-                new JobInfo.Builder(TIMING_JOB_ID, kJobServiceComponent)
-                        .setPeriodic(5000L)  // 5 second period.
-                        .build();
-
-        kTestEnvironment.setExpectedExecutions(3);
-        mJobScheduler.schedule(periodicJob);
-        final boolean countedDown = kTestEnvironment.awaitExecution();
-        assertTrue("Timed out waiting for periodic jobs to execute", countedDown);
-    }
-
     public void testCancel() throws Exception {
         JobInfo cancelJob = new JobInfo.Builder(CANCEL_JOB_ID, kJobServiceComponent)
                 .setMinimumLatency(5000L) // make sure it doesn't actually run immediately
@@ -106,4 +94,4 @@
                         " JobParameters#isOverrideDeadlineExpired=false",
                 kTestEnvironment.getLastJobParameters().isOverrideDeadlineExpired());
     }
-}
\ No newline at end of file
+}
diff --git a/tests/acceleration/Android.mk b/tests/acceleration/Android.mk
index f36b64b..c70047017 100644
--- a/tests/acceleration/Android.mk
+++ b/tests/acceleration/Android.mk
@@ -24,10 +24,15 @@
 
 LOCAL_PROGUARD_ENABLED := disabled
 
+LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
+
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
-LOCAL_PACKAGE_NAME := CtsAccelerationTestStubs
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_PACKAGE_NAME := CtsAccelerationTestCases
 
 LOCAL_SDK_VERSION := current
 
-include $(BUILD_CTS_SUPPORT_PACKAGE)
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/acceleration/AndroidManifest.xml b/tests/acceleration/AndroidManifest.xml
index f92b736..1a21554 100644
--- a/tests/acceleration/AndroidManifest.xml
+++ b/tests/acceleration/AndroidManifest.xml
@@ -15,15 +15,25 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-        package="com.android.cts.acceleration.stub">
+        package="android.acceleration.cts">
+
+    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
 
     <application android:hardwareAccelerated="true">
-        <activity android:name="android.acceleration.cts.HardwareAcceleratedActivity" />
-        <activity android:name="android.acceleration.cts.SoftwareAcceleratedActivity"
+        <uses-library android:name="android.test.runner" />
+        <activity android:name="android.acceleration.HardwareAcceleratedActivity" />
+        <activity android:name="android.acceleration.SoftwareAcceleratedActivity"
                 android:hardwareAccelerated="false" />
-        <activity android:name="android.acceleration.cts.WindowFlagHardwareAcceleratedActivity"
+        <activity android:name="android.acceleration.WindowFlagHardwareAcceleratedActivity"
                 android:hardwareAccelerated="false" />
     </application>
 
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+            android:targetPackage="android.acceleration.cts"
+            android:label="Tests for the Hardware Acceleration APIs." >
+        <meta-data android:name="listener"
+                android:value="com.android.cts.runner.CtsTestRunListener" />
+    </instrumentation>
+
 </manifest>
 
diff --git a/tests/acceleration/AndroidTest.xml b/tests/acceleration/AndroidTest.xml
new file mode 100644
index 0000000..1786c8e
--- /dev/null
+++ b/tests/acceleration/AndroidTest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS Acceleration test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsAccelerationTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.acceleration.cts" />
+    </test>
+</configuration>
diff --git a/tests/acceleration/res/layout/acceleration.xml b/tests/acceleration/res/layout/acceleration.xml
index 8dc027a..5127507 100644
--- a/tests/acceleration/res/layout/acceleration.xml
+++ b/tests/acceleration/res/layout/acceleration.xml
@@ -18,25 +18,25 @@
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         >
-    <android.acceleration.cts.AcceleratedView android:id="@+id/hardware_accelerated_view"
+    <android.acceleration.AcceleratedView android:id="@+id/hardware_accelerated_view"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_weight="1"
             android:layerType="hardware"
             />
-    <android.acceleration.cts.AcceleratedView android:id="@+id/software_accelerated_view"
+    <android.acceleration.AcceleratedView android:id="@+id/software_accelerated_view"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_weight="1"
             android:layerType="software"
             />
     <!-- Acceleration will be set via manual setLayerType calls from the activity. -->
-    <android.acceleration.cts.AcceleratedView android:id="@+id/manual_hardware_accelerated_view"
+    <android.acceleration.AcceleratedView android:id="@+id/manual_hardware_accelerated_view"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_weight="1"
             />
-    <android.acceleration.cts.AcceleratedView android:id="@+id/manual_software_accelerated_view"
+    <android.acceleration.AcceleratedView android:id="@+id/manual_software_accelerated_view"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_weight="1"
diff --git a/tests/acceleration/src/android/acceleration/AcceleratedView.java b/tests/acceleration/src/android/acceleration/AcceleratedView.java
new file mode 100644
index 0000000..7134a76
--- /dev/null
+++ b/tests/acceleration/src/android/acceleration/AcceleratedView.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.acceleration;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.util.AttributeSet;
+import android.view.View;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+public class AcceleratedView extends View {
+
+    private final CountDownLatch mDrawLatch = new CountDownLatch(1);
+
+    private boolean mIsHardwareAccelerated;
+
+    public AcceleratedView(Context context) {
+        super(context);
+    }
+
+    public AcceleratedView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public AcceleratedView(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+    }
+
+    @Override
+    protected void onDraw(Canvas canvas) {
+        super.onDraw(canvas);
+        synchronized (this) {
+            mIsHardwareAccelerated = canvas.isHardwareAccelerated();
+        }
+        mDrawLatch.countDown();
+    }
+
+    public boolean isCanvasHardwareAccelerated() {
+        try {
+            if (mDrawLatch.await(1, TimeUnit.SECONDS)) {
+                synchronized (this) {
+                    return mIsHardwareAccelerated;
+                }
+            } else {
+                throw new IllegalStateException("View was not drawn...");
+            }
+        } catch (InterruptedException e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
diff --git a/tests/acceleration/src/android/acceleration/BaseAcceleratedActivity.java b/tests/acceleration/src/android/acceleration/BaseAcceleratedActivity.java
new file mode 100644
index 0000000..262b43e
--- /dev/null
+++ b/tests/acceleration/src/android/acceleration/BaseAcceleratedActivity.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.acceleration;
+
+import android.acceleration.cts.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+
+public abstract class BaseAcceleratedActivity extends Activity {
+
+    private AcceleratedView mHardwareAcceleratedView;
+    private AcceleratedView mSoftwareAcceleratedView;
+
+    private AcceleratedView mManualHardwareAcceleratedView;
+    private AcceleratedView mManualSoftwareAcceleratedView;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.acceleration);
+
+        mHardwareAcceleratedView = (AcceleratedView) findViewById(R.id.hardware_accelerated_view);
+        mSoftwareAcceleratedView = (AcceleratedView) findViewById(R.id.software_accelerated_view);
+
+        mManualHardwareAcceleratedView =
+            (AcceleratedView) findViewById(R.id.manual_hardware_accelerated_view);
+        mManualSoftwareAcceleratedView =
+            (AcceleratedView) findViewById(R.id.manual_software_accelerated_view);
+
+        mManualHardwareAcceleratedView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+        mManualSoftwareAcceleratedView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
+    }
+
+    public AcceleratedView getHardwareAcceleratedView() {
+        return mHardwareAcceleratedView;
+    }
+
+    public AcceleratedView getSoftwareAcceleratedView() {
+        return mSoftwareAcceleratedView;
+    }
+
+    public AcceleratedView getManualHardwareAcceleratedView() {
+        return mManualHardwareAcceleratedView;
+    }
+
+    public AcceleratedView getManualSoftwareAcceleratedView() {
+        return mManualSoftwareAcceleratedView;
+    }
+}
diff --git a/tests/acceleration/src/android/acceleration/HardwareAcceleratedActivity.java b/tests/acceleration/src/android/acceleration/HardwareAcceleratedActivity.java
new file mode 100644
index 0000000..9122565
--- /dev/null
+++ b/tests/acceleration/src/android/acceleration/HardwareAcceleratedActivity.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.acceleration;
+
+public class HardwareAcceleratedActivity extends BaseAcceleratedActivity {
+}
diff --git a/tests/acceleration/src/android/acceleration/SoftwareAcceleratedActivity.java b/tests/acceleration/src/android/acceleration/SoftwareAcceleratedActivity.java
new file mode 100644
index 0000000..7555862
--- /dev/null
+++ b/tests/acceleration/src/android/acceleration/SoftwareAcceleratedActivity.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.acceleration;
+
+public class SoftwareAcceleratedActivity extends BaseAcceleratedActivity {
+}
diff --git a/tests/acceleration/src/android/acceleration/WindowFlagHardwareAcceleratedActivity.java b/tests/acceleration/src/android/acceleration/WindowFlagHardwareAcceleratedActivity.java
new file mode 100644
index 0000000..d448334
--- /dev/null
+++ b/tests/acceleration/src/android/acceleration/WindowFlagHardwareAcceleratedActivity.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.acceleration;
+
+import android.os.Bundle;
+import android.view.WindowManager;
+
+public class WindowFlagHardwareAcceleratedActivity extends BaseAcceleratedActivity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        getWindow().setFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
+                WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
+    }
+}
diff --git a/tests/acceleration/src/android/acceleration/cts/AcceleratedView.java b/tests/acceleration/src/android/acceleration/cts/AcceleratedView.java
deleted file mode 100644
index 7d749a1..0000000
--- a/tests/acceleration/src/android/acceleration/cts/AcceleratedView.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.acceleration.cts;
-
-import android.content.Context;
-import android.graphics.Canvas;
-import android.util.AttributeSet;
-import android.view.View;
-
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-public class AcceleratedView extends View {
-
-    private final CountDownLatch mDrawLatch = new CountDownLatch(1);
-
-    private boolean mIsHardwareAccelerated;
-
-    public AcceleratedView(Context context) {
-        super(context);
-    }
-
-    public AcceleratedView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public AcceleratedView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-    }
-
-    @Override
-    protected void onDraw(Canvas canvas) {
-        super.onDraw(canvas);
-        synchronized (this) {
-            mIsHardwareAccelerated = canvas.isHardwareAccelerated();
-        }
-        mDrawLatch.countDown();
-    }
-
-    public boolean isCanvasHardwareAccelerated() {
-        try {
-            if (mDrawLatch.await(1, TimeUnit.SECONDS)) {
-                synchronized (this) {
-                    return mIsHardwareAccelerated;
-                }
-            } else {
-                throw new IllegalStateException("View was not drawn...");
-            }
-        } catch (InterruptedException e) {
-            throw new RuntimeException(e);
-        }
-    }
-}
diff --git a/tests/acceleration/src/android/acceleration/cts/BaseAcceleratedActivity.java b/tests/acceleration/src/android/acceleration/cts/BaseAcceleratedActivity.java
deleted file mode 100644
index 8ef6a8e..0000000
--- a/tests/acceleration/src/android/acceleration/cts/BaseAcceleratedActivity.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.acceleration.cts;
-
-import com.android.cts.acceleration.stub.R;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.view.View;
-
-abstract class BaseAcceleratedActivity extends Activity {
-
-    private AcceleratedView mHardwareAcceleratedView;
-    private AcceleratedView mSoftwareAcceleratedView;
-
-    private AcceleratedView mManualHardwareAcceleratedView;
-    private AcceleratedView mManualSoftwareAcceleratedView;
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.acceleration);
-
-        mHardwareAcceleratedView = (AcceleratedView) findViewById(R.id.hardware_accelerated_view);
-        mSoftwareAcceleratedView = (AcceleratedView) findViewById(R.id.software_accelerated_view);
-
-        mManualHardwareAcceleratedView =
-            (AcceleratedView) findViewById(R.id.manual_hardware_accelerated_view);
-        mManualSoftwareAcceleratedView =
-            (AcceleratedView) findViewById(R.id.manual_software_accelerated_view);
-
-        mManualHardwareAcceleratedView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
-        mManualSoftwareAcceleratedView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
-    }
-
-    public AcceleratedView getHardwareAcceleratedView() {
-        return mHardwareAcceleratedView;
-    }
-
-    public AcceleratedView getSoftwareAcceleratedView() {
-        return mSoftwareAcceleratedView;
-    }
-
-    public AcceleratedView getManualHardwareAcceleratedView() {
-        return mManualHardwareAcceleratedView;
-    }
-
-    public AcceleratedView getManualSoftwareAcceleratedView() {
-        return mManualSoftwareAcceleratedView;
-    }
-}
diff --git a/tests/acceleration/src/android/acceleration/cts/BaseAccelerationTest.java b/tests/acceleration/src/android/acceleration/cts/BaseAccelerationTest.java
new file mode 100644
index 0000000..c6e94ec
--- /dev/null
+++ b/tests/acceleration/src/android/acceleration/cts/BaseAccelerationTest.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.acceleration.cts;
+
+import android.acceleration.AcceleratedView;
+import android.acceleration.BaseAcceleratedActivity;
+import android.app.ActivityManager;
+import android.content.Context;
+import android.content.pm.ConfigurationInfo;
+import android.content.pm.FeatureInfo;
+import android.test.ActivityInstrumentationTestCase2;
+import android.view.View;
+
+abstract class BaseAccelerationTest<B extends BaseAcceleratedActivity>
+        extends ActivityInstrumentationTestCase2<B> {
+
+    protected B mActivity;
+
+    /** View with android:layerType="hardware" set */
+    protected AcceleratedView mHardwareView;
+
+    /** View with android:layerType="software" set */
+    protected AcceleratedView mSoftwareView;
+
+    /** View with setLayerType(HARDWARE) called */
+    protected AcceleratedView mManualHardwareView;
+
+    /** View with setLayerType(SOFTWARE) called */
+    protected AcceleratedView mManualSoftwareView;
+
+    BaseAccelerationTest(Class<B> clazz) {
+        super(clazz);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mActivity = getActivity();
+        mHardwareView = mActivity.getHardwareAcceleratedView();
+        mSoftwareView = mActivity.getSoftwareAcceleratedView();
+        mManualHardwareView = mActivity.getManualHardwareAcceleratedView();
+        mManualSoftwareView = mActivity.getManualSoftwareAcceleratedView();
+    }
+
+    public void testNotAttachedView() {
+        // Views that are not attached can't be attached to an accelerated window.
+        View view = new View(mActivity);
+        assertFalse(view.isHardwareAccelerated());
+    }
+
+    protected static int getGlEsVersion(Context context) {
+        ActivityManager activityManager =
+                (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
+        ConfigurationInfo configInfo = activityManager.getDeviceConfigurationInfo();
+        if (configInfo.reqGlEsVersion != ConfigurationInfo.GL_ES_VERSION_UNDEFINED) {
+            return getMajorVersion(configInfo.reqGlEsVersion);
+        } else {
+            return 1; // Lack of property means OpenGL ES version 1
+        }
+    }
+
+    /** @see FeatureInfo#getGlEsVersion() */
+    private static int getMajorVersion(int glEsVersion) {
+        return ((glEsVersion & 0xffff0000) >> 16);
+    }
+}
diff --git a/tests/acceleration/src/android/acceleration/cts/HardwareAcceleratedActivity.java b/tests/acceleration/src/android/acceleration/cts/HardwareAcceleratedActivity.java
deleted file mode 100644
index bb26202..0000000
--- a/tests/acceleration/src/android/acceleration/cts/HardwareAcceleratedActivity.java
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.acceleration.cts;
-
-public class HardwareAcceleratedActivity extends BaseAcceleratedActivity {
-}
diff --git a/tests/acceleration/src/android/acceleration/cts/HardwareAccelerationTest.java b/tests/acceleration/src/android/acceleration/cts/HardwareAccelerationTest.java
new file mode 100644
index 0000000..94089cc
--- /dev/null
+++ b/tests/acceleration/src/android/acceleration/cts/HardwareAccelerationTest.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.acceleration.cts;
+
+import android.acceleration.HardwareAcceleratedActivity;
+
+/**
+ * Test that uses an Activity with hardware acceleration enabled.
+ */
+public class HardwareAccelerationTest
+        extends BaseAccelerationTest<HardwareAcceleratedActivity> {
+
+    public HardwareAccelerationTest() {
+        super(HardwareAcceleratedActivity.class);
+    }
+
+    public void testIsHardwareAccelerated() {
+        // Hardware acceleration should be available on devices with GL ES 2 or higher...
+        if (getGlEsVersion(mActivity) >= 2) {
+            // Both of the views are attached to a hardware accelerated window
+            assertTrue(mHardwareView.isHardwareAccelerated());
+            assertTrue(mSoftwareView.isHardwareAccelerated());
+            assertTrue(mManualHardwareView.isHardwareAccelerated());
+            assertTrue(mManualSoftwareView.isHardwareAccelerated());
+
+            assertTrue(mHardwareView.isCanvasHardwareAccelerated());
+            assertFalse(mSoftwareView.isCanvasHardwareAccelerated());
+            assertTrue(mManualHardwareView.isCanvasHardwareAccelerated());
+            assertFalse(mManualSoftwareView.isCanvasHardwareAccelerated());
+        } else {
+            assertFalse(mHardwareView.isHardwareAccelerated());
+            assertFalse(mSoftwareView.isHardwareAccelerated());
+            assertFalse(mManualHardwareView.isHardwareAccelerated());
+            assertFalse(mManualSoftwareView.isHardwareAccelerated());
+
+            assertFalse(mHardwareView.isCanvasHardwareAccelerated());
+            assertFalse(mSoftwareView.isCanvasHardwareAccelerated());
+            assertFalse(mManualHardwareView.isCanvasHardwareAccelerated());
+            assertFalse(mManualSoftwareView.isCanvasHardwareAccelerated());
+        }
+    }
+}
diff --git a/tests/acceleration/src/android/acceleration/cts/SoftwareAcceleratedActivity.java b/tests/acceleration/src/android/acceleration/cts/SoftwareAcceleratedActivity.java
deleted file mode 100644
index 0a6a3df..0000000
--- a/tests/acceleration/src/android/acceleration/cts/SoftwareAcceleratedActivity.java
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.acceleration.cts;
-
-public class SoftwareAcceleratedActivity extends BaseAcceleratedActivity {
-}
diff --git a/tests/acceleration/src/android/acceleration/cts/SoftwareAccelerationTest.java b/tests/acceleration/src/android/acceleration/cts/SoftwareAccelerationTest.java
new file mode 100644
index 0000000..4e12c1e
--- /dev/null
+++ b/tests/acceleration/src/android/acceleration/cts/SoftwareAccelerationTest.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.acceleration.cts;
+
+import android.acceleration.SoftwareAcceleratedActivity;
+
+/**
+ * Test that uses an Activity with hardware acceleration explicitly disabled
+ * and makes sure that all views are rendered using software acceleration.
+ */
+public class SoftwareAccelerationTest
+        extends BaseAccelerationTest<SoftwareAcceleratedActivity> {
+
+    public SoftwareAccelerationTest() {
+        super(SoftwareAcceleratedActivity.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mActivity = getActivity();
+    }
+
+    public void testIsHardwareAccelerated() {
+        // Both of the views are not attached to a hardware accelerated window
+        assertFalse(mHardwareView.isHardwareAccelerated());
+        assertFalse(mSoftwareView.isHardwareAccelerated());
+        assertFalse(mManualHardwareView.isHardwareAccelerated());
+        assertFalse(mManualSoftwareView.isHardwareAccelerated());
+
+        assertFalse(mHardwareView.isCanvasHardwareAccelerated());
+        assertFalse(mSoftwareView.isCanvasHardwareAccelerated());
+        assertFalse(mManualHardwareView.isCanvasHardwareAccelerated());
+        assertFalse(mManualSoftwareView.isCanvasHardwareAccelerated());
+    }
+}
diff --git a/tests/acceleration/src/android/acceleration/cts/WindowFlagHardwareAcceleratedActivity.java b/tests/acceleration/src/android/acceleration/cts/WindowFlagHardwareAcceleratedActivity.java
deleted file mode 100644
index 9def8b7..0000000
--- a/tests/acceleration/src/android/acceleration/cts/WindowFlagHardwareAcceleratedActivity.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.acceleration.cts;
-
-import android.os.Bundle;
-import android.view.WindowManager;
-
-public class WindowFlagHardwareAcceleratedActivity extends BaseAcceleratedActivity {
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        getWindow().setFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
-                WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
-    }
-}
diff --git a/tests/acceleration/src/android/acceleration/cts/WindowFlagHardwareAccelerationTest.java b/tests/acceleration/src/android/acceleration/cts/WindowFlagHardwareAccelerationTest.java
new file mode 100644
index 0000000..2070666
--- /dev/null
+++ b/tests/acceleration/src/android/acceleration/cts/WindowFlagHardwareAccelerationTest.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.acceleration.cts;
+
+import android.acceleration.WindowFlagHardwareAcceleratedActivity;
+
+/**
+ * Test that uses an Activity with hardware acceleration enabled.
+ */
+public class WindowFlagHardwareAccelerationTest
+        extends BaseAccelerationTest<WindowFlagHardwareAcceleratedActivity> {
+
+    public WindowFlagHardwareAccelerationTest() {
+        super(WindowFlagHardwareAcceleratedActivity.class);
+    }
+
+    public void testIsHardwareAccelerated() {
+        // Hardware acceleration should be available on devices with GL ES 2 or higher...
+        if (getGlEsVersion(mActivity) >= 2) {
+            // Both of the views are attached to a hardware accelerated window
+            assertTrue(mHardwareView.isHardwareAccelerated());
+            assertTrue(mSoftwareView.isHardwareAccelerated());
+            assertTrue(mManualHardwareView.isHardwareAccelerated());
+            assertTrue(mManualSoftwareView.isHardwareAccelerated());
+
+            assertTrue(mHardwareView.isCanvasHardwareAccelerated());
+            assertFalse(mSoftwareView.isCanvasHardwareAccelerated());
+            assertTrue(mManualHardwareView.isCanvasHardwareAccelerated());
+            assertFalse(mManualSoftwareView.isCanvasHardwareAccelerated());
+        } else {
+            assertFalse(mHardwareView.isHardwareAccelerated());
+            assertFalse(mSoftwareView.isHardwareAccelerated());
+            assertFalse(mManualHardwareView.isHardwareAccelerated());
+            assertFalse(mManualSoftwareView.isHardwareAccelerated());
+
+            assertFalse(mHardwareView.isCanvasHardwareAccelerated());
+            assertFalse(mSoftwareView.isCanvasHardwareAccelerated());
+            assertFalse(mManualHardwareView.isCanvasHardwareAccelerated());
+            assertFalse(mManualSoftwareView.isCanvasHardwareAccelerated());
+        }
+    }
+}
diff --git a/tests/accessibility/Android.mk b/tests/accessibility/Android.mk
index bddbb58..42245f25 100644
--- a/tests/accessibility/Android.mk
+++ b/tests/accessibility/Android.mk
@@ -1,4 +1,4 @@
-# Copyright (C) 2010 The Android Open Source Project
+# Copyright (C) 2012 The Android Open 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,14 +18,19 @@
 
 LOCAL_MODULE_TAGS := optional
 
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
-LOCAL_PACKAGE_NAME := CtsSomeAccessibilityServices
+LOCAL_PACKAGE_NAME := CtsAccessibilityTestCases
+
+LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctstestrunner
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
 
 LOCAL_SDK_VERSION := current
 
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+include $(BUILD_CTS_PACKAGE)
 
-LOCAL_DEX_PREOPT := false
-
-include $(BUILD_CTS_SUPPORT_PACKAGE)
+include $(call all-makefiles-under,$(LOCAL_PATH))
\ No newline at end of file
diff --git a/tests/accessibility/AndroidManifest.xml b/tests/accessibility/AndroidManifest.xml
index dde1de8..26ac267 100644
--- a/tests/accessibility/AndroidManifest.xml
+++ b/tests/accessibility/AndroidManifest.xml
@@ -17,30 +17,39 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="android.view.accessibility.services">
+          package="android.view.accessibility.cts">
 
-  <application>
+    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+    <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
 
-    <service android:name=".SpeakingAccessibilityService"
-             android:label="@string/title_speaking_accessibility_service"
-             android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
-      <intent-filter>
-        <action android:name="android.accessibilityservice.AccessibilityService"/>
-      </intent-filter>
-      <meta-data android:name="android.accessibilityservice"
-                android:resource="@xml/speaking_accessibilityservice" />
-    </service>
+    <application android:theme="@android:style/Theme.Holo.NoActionBar" >
+        <uses-library android:name="android.test.runner"/>
+        <service android:name=".SpeakingAccessibilityService"
+                 android:label="@string/title_speaking_accessibility_service"
+                 android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
+            <intent-filter>
+                <action android:name="android.accessibilityservice.AccessibilityService"/>
+            </intent-filter>
+            <meta-data android:name="android.accessibilityservice"
+                       android:resource="@xml/speaking_accessibilityservice" />
+        </service>
 
-    <service android:name=".VibratingAccessibilityService"
-             android:label="@string/title_vibrating_accessibility_service"
-             android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
-      <intent-filter>
-        <action android:name="android.accessibilityservice.AccessibilityService"/>
-      </intent-filter>
-      <meta-data android:name="android.accessibilityservice"
-                android:resource="@xml/vibrating_accessibilityservice" />
-    </service>
+        <service android:name=".VibratingAccessibilityService"
+                 android:label="@string/title_vibrating_accessibility_service"
+                 android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
+            <intent-filter>
+                <action android:name="android.accessibilityservice.AccessibilityService"/>
+            </intent-filter>
+            <meta-data android:name="android.accessibilityservice"
+                       android:resource="@xml/vibrating_accessibilityservice" />
+        </service>
+    </application>
 
-  </application>
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="android.view.accessibility.cts"
+                     android:label="Tests for the accessibility APIs.">
+        <meta-data android:name="listener"
+                   android:value="com.android.cts.runner.CtsTestRunListener" />
+    </instrumentation>
 
 </manifest>
diff --git a/tests/accessibility/AndroidTest.xml b/tests/accessibility/AndroidTest.xml
new file mode 100644
index 0000000..b6c8ab5
--- /dev/null
+++ b/tests/accessibility/AndroidTest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS Accessibility test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsAccessibilityTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.view.accessibility.cts" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/tests/accessibility/res/values/ids.xml b/tests/accessibility/res/values/ids.xml
similarity index 100%
rename from tests/tests/accessibility/res/values/ids.xml
rename to tests/accessibility/res/values/ids.xml
diff --git a/tests/tests/accessibility/src/android/view/accessibility/cts/AccessibilityEventTest.java b/tests/accessibility/src/android/view/accessibility/cts/AccessibilityEventTest.java
similarity index 100%
rename from tests/tests/accessibility/src/android/view/accessibility/cts/AccessibilityEventTest.java
rename to tests/accessibility/src/android/view/accessibility/cts/AccessibilityEventTest.java
diff --git a/tests/accessibility/src/android/view/accessibility/cts/AccessibilityManagerTest.java b/tests/accessibility/src/android/view/accessibility/cts/AccessibilityManagerTest.java
new file mode 100644
index 0000000..1256546
--- /dev/null
+++ b/tests/accessibility/src/android/view/accessibility/cts/AccessibilityManagerTest.java
@@ -0,0 +1,240 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.view.accessibility.cts;
+
+import android.accessibilityservice.AccessibilityServiceInfo;
+import android.app.Service;
+import android.content.pm.ServiceInfo;
+import android.cts.util.PollingCheck;
+import android.test.InstrumentationTestCase;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityManager;
+import android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener;
+import android.view.accessibility.AccessibilityManager.TouchExplorationStateChangeListener;
+
+import java.util.List;
+
+/**
+ * Class for testing {@link AccessibilityManager}.
+ */
+public class AccessibilityManagerTest extends InstrumentationTestCase {
+
+    private static final String SPEAKING_ACCESSIBLITY_SERVICE_NAME =
+        "android.view.accessibility.cts.SpeakingAccessibilityService";
+
+    private static final String VIBRATING_ACCESSIBLITY_SERVICE_NAME =
+        "android.view.accessibility.cts.VibratingAccessibilityService";
+
+    private static final long WAIT_FOR_ACCESSIBILITY_ENABLED_TIMEOUT = 3000; // 3s
+
+    private AccessibilityManager mAccessibilityManager;
+
+    @Override
+    public void setUp() throws Exception {
+        mAccessibilityManager = (AccessibilityManager)
+                getInstrumentation().getContext().getSystemService(Service.ACCESSIBILITY_SERVICE);
+        ServiceControlUtils.enableSpeakingAndVibratingServices(getInstrumentation());
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        ServiceControlUtils.turnAccessibilityOff(getInstrumentation());
+    }
+
+    public void testAddAndRemoveAccessibilityStateChangeListener() throws Exception {
+        AccessibilityStateChangeListener listener = new AccessibilityStateChangeListener() {
+            @Override
+            public void onAccessibilityStateChanged(boolean enabled) {
+                /* do nothing */
+            }
+        };
+        assertTrue(mAccessibilityManager.addAccessibilityStateChangeListener(listener));
+        assertTrue(mAccessibilityManager.removeAccessibilityStateChangeListener(listener));
+        assertFalse(mAccessibilityManager.removeAccessibilityStateChangeListener(listener));
+    }
+
+    public void testAddAndRemoveTouchExplorationStateChangeListener() throws Exception {
+        TouchExplorationStateChangeListener listener = new TouchExplorationStateChangeListener() {
+            @Override
+            public void onTouchExplorationStateChanged(boolean enabled) {
+                // Do nothing.
+            }
+        };
+        assertTrue(mAccessibilityManager.addTouchExplorationStateChangeListener(listener));
+        assertTrue(mAccessibilityManager.removeTouchExplorationStateChangeListener(listener));
+        assertFalse(mAccessibilityManager.removeTouchExplorationStateChangeListener(listener));
+    }
+
+    public void testIsTouchExplorationEnabled() throws Exception {
+        new PollingCheck() {
+            @Override
+            protected boolean check() {
+                return mAccessibilityManager.isTouchExplorationEnabled();
+            }
+        }.run();
+    }
+
+    public void testGetInstalledAccessibilityServicesList() throws Exception {
+        List<AccessibilityServiceInfo> installedServices =
+            mAccessibilityManager.getInstalledAccessibilityServiceList();
+        assertFalse("There must be at least one installed service.", installedServices.isEmpty());
+        boolean speakingServiceInstalled = false;
+        boolean vibratingServiceInstalled = false;
+        final int serviceCount = installedServices.size();
+        for (int i = 0; i < serviceCount; i++) {
+            AccessibilityServiceInfo installedService = installedServices.get(i);
+            ServiceInfo serviceInfo = installedService.getResolveInfo().serviceInfo;
+            if (getClass().getPackage().getName().equals(serviceInfo.packageName)
+                    && SPEAKING_ACCESSIBLITY_SERVICE_NAME.equals(serviceInfo.name)) {
+                speakingServiceInstalled = true;
+            }
+            if (getClass().getPackage().getName().equals(serviceInfo.packageName)
+                    && VIBRATING_ACCESSIBLITY_SERVICE_NAME.equals(serviceInfo.name)) {
+                vibratingServiceInstalled = true;
+            }
+        }
+        assertTrue("The speaking service should be installed.", speakingServiceInstalled);
+        assertTrue("The vibrating service should be installed.", vibratingServiceInstalled);
+    }
+
+    public void testGetEnabledAccessibilityServiceList() throws Exception {
+        List<AccessibilityServiceInfo> enabledServices =
+            mAccessibilityManager.getEnabledAccessibilityServiceList(
+                    AccessibilityServiceInfo.FEEDBACK_ALL_MASK);
+        boolean speakingServiceEnabled = false;
+        boolean vibratingServiceEnabled = false;
+        final int serviceCount = enabledServices.size();
+        for (int i = 0; i < serviceCount; i++) {
+            AccessibilityServiceInfo enabledService = enabledServices.get(i);
+            ServiceInfo serviceInfo = enabledService.getResolveInfo().serviceInfo;
+            if (getClass().getPackage().getName().equals(serviceInfo.packageName)
+                    && SPEAKING_ACCESSIBLITY_SERVICE_NAME.equals(serviceInfo.name)) {
+                speakingServiceEnabled = true;
+            }
+            if (getClass().getPackage().getName().equals(serviceInfo.packageName)
+                    && VIBRATING_ACCESSIBLITY_SERVICE_NAME.equals(serviceInfo.name)) {
+                vibratingServiceEnabled = true;
+            }
+        }
+        assertTrue("The speaking service should be enabled.", speakingServiceEnabled);
+        assertTrue("The vibrating service should be enabled.", vibratingServiceEnabled);
+    }
+
+    public void testGetEnabledAccessibilityServiceListForType() throws Exception {
+        List<AccessibilityServiceInfo> enabledServices =
+            mAccessibilityManager.getEnabledAccessibilityServiceList(
+                    AccessibilityServiceInfo.FEEDBACK_SPOKEN);
+        assertSame("There should be only one enabled speaking service.", 1, enabledServices.size());
+        final int serviceCount = enabledServices.size();
+        for (int i = 0; i < serviceCount; i++) {
+            AccessibilityServiceInfo enabledService = enabledServices.get(i);
+            ServiceInfo serviceInfo = enabledService.getResolveInfo().serviceInfo;
+            if (getClass().getPackage().getName().equals(serviceInfo.packageName)
+                    && SPEAKING_ACCESSIBLITY_SERVICE_NAME.equals(serviceInfo.name)) {
+                return;
+            }
+        }
+        fail("The speaking service is not enabled.");
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testGetAccessibilityServiceList() throws Exception {
+        List<ServiceInfo> services = mAccessibilityManager.getAccessibilityServiceList();
+        boolean speakingServiceInstalled = false;
+        boolean vibratingServiceInstalled = false;
+        final int serviceCount = services.size();
+        for (int i = 0; i < serviceCount; i++) {
+            ServiceInfo serviceInfo = services.get(i);
+            if (getClass().getPackage().getName().equals(serviceInfo.packageName)
+                    && SPEAKING_ACCESSIBLITY_SERVICE_NAME.equals(serviceInfo.name)) {
+                speakingServiceInstalled = true;
+            }
+            if (getClass().getPackage().getName().equals(serviceInfo.packageName)
+                    && VIBRATING_ACCESSIBLITY_SERVICE_NAME.equals(serviceInfo.name)) {
+                vibratingServiceInstalled = true;
+            }
+        }
+        assertTrue("The speaking service should be installed.", speakingServiceInstalled);
+        assertTrue("The vibrating service should be installed.", vibratingServiceInstalled);
+    }
+
+    public void testInterrupt() throws Exception {
+        // The APIs are heavily tested in the android.accessibiliyservice package.
+        // This just makes sure the call does not throw an exception.
+        waitForAccessibilityEnabled();
+        mAccessibilityManager.interrupt();
+    }
+
+    public void testSendAccessibilityEvent() throws Exception {
+        // The APIs are heavily tested in the android.accessibiliyservice package.
+        // This just makes sure the call does not throw an exception.
+        waitForAccessibilityEnabled();
+        mAccessibilityManager.sendAccessibilityEvent(AccessibilityEvent.obtain(
+                AccessibilityEvent.TYPE_VIEW_CLICKED));
+    }
+
+    public void testTouchExplorationStateChanged() throws Exception {
+        waitForTouchExplorationEnabled();
+    }
+
+    private void waitForAccessibilityEnabled() throws InterruptedException {
+        final Object waitObject = new Object();
+
+        AccessibilityStateChangeListener listener = new AccessibilityStateChangeListener() {
+            @Override
+            public void onAccessibilityStateChanged(boolean b) {
+                synchronized (waitObject) {
+                    waitObject.notifyAll();
+                }
+            }
+        };
+        mAccessibilityManager.addAccessibilityStateChangeListener(listener);
+        long timeoutTime = System.currentTimeMillis() + WAIT_FOR_ACCESSIBILITY_ENABLED_TIMEOUT;
+        synchronized (waitObject) {
+            while (!mAccessibilityManager.isEnabled()
+                    && (System.currentTimeMillis() < timeoutTime)) {
+                waitObject.wait(timeoutTime - System.currentTimeMillis());
+            }
+        }
+        mAccessibilityManager.removeAccessibilityStateChangeListener(listener);
+        assertTrue("Timed out enabling accessibility", mAccessibilityManager.isEnabled());
+    }
+
+    private void waitForTouchExplorationEnabled() throws InterruptedException {
+        final Object waitObject = new Object();
+
+        TouchExplorationStateChangeListener listener = new TouchExplorationStateChangeListener() {
+            @Override
+            public void onTouchExplorationStateChanged(boolean b) {
+                synchronized (waitObject) {
+                    waitObject.notifyAll();
+                }
+            }
+        };
+        mAccessibilityManager.addTouchExplorationStateChangeListener(listener);
+        long timeoutTime = System.currentTimeMillis() + WAIT_FOR_ACCESSIBILITY_ENABLED_TIMEOUT;
+        synchronized (waitObject) {
+            while (!mAccessibilityManager.isTouchExplorationEnabled()
+                    && (System.currentTimeMillis() < timeoutTime)) {
+                waitObject.wait(timeoutTime - System.currentTimeMillis());
+            }
+        }
+        mAccessibilityManager.removeTouchExplorationStateChangeListener(listener);
+        assertTrue("Timed out enabling touch exploration",
+                mAccessibilityManager.isTouchExplorationEnabled());
+    }
+}
diff --git a/tests/accessibility/src/android/view/accessibility/cts/AccessibilityNodeInfoTest.java b/tests/accessibility/src/android/view/accessibility/cts/AccessibilityNodeInfoTest.java
new file mode 100644
index 0000000..9c9b0db
--- /dev/null
+++ b/tests/accessibility/src/android/view/accessibility/cts/AccessibilityNodeInfoTest.java
@@ -0,0 +1,307 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.view.accessibility.cts;
+
+import android.graphics.Rect;
+import android.os.Parcel;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.view.View;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
+import android.view.accessibility.cts.R;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Class for testing {@link AccessibilityNodeInfo}.
+ */
+public class AccessibilityNodeInfoTest extends AndroidTestCase {
+
+    /** The number of properties of the {@link AccessibilityNodeInfo} class. */
+    private static final int NON_STATIC_FIELD_COUNT = 31;
+
+    @SmallTest
+    public void testMarshaling() throws Exception {
+        // no new fields, so we are testing marshaling of all such
+        AccessibilityRecordTest.assertNoNewNonStaticFieldsAdded(AccessibilityNodeInfo.class,
+                NON_STATIC_FIELD_COUNT);
+
+        // fully populate the node info to marshal
+        AccessibilityNodeInfo sentInfo = AccessibilityNodeInfo.obtain(new View(getContext()));
+        fullyPopulateAccessibilityNodeInfo(sentInfo);
+
+        // marshal and unmarshal the node info
+        Parcel parcel = Parcel.obtain();
+        sentInfo.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        AccessibilityNodeInfo receivedInfo = AccessibilityNodeInfo.CREATOR.createFromParcel(parcel);
+
+        // make sure all fields properly marshaled
+        assertEqualsAccessibilityNodeInfo(sentInfo, receivedInfo);
+    }
+
+    /**
+     * Tests if {@link AccessibilityNodeInfo}s are properly reused.
+     */
+    @SmallTest
+    public void testReuse() {
+        AccessibilityEvent firstInfo = AccessibilityEvent.obtain();
+        firstInfo.recycle();
+        AccessibilityEvent secondInfo = AccessibilityEvent.obtain();
+        assertSame("AccessibilityNodeInfo not properly reused", firstInfo, secondInfo);
+    }
+
+    /**
+     * Tests if {@link AccessibilityNodeInfo} are properly recycled.
+     */
+    @SmallTest
+    public void testRecycle() {
+        // obtain and populate an node info
+        AccessibilityNodeInfo populatedInfo = AccessibilityNodeInfo.obtain();
+        fullyPopulateAccessibilityNodeInfo(populatedInfo);
+
+        // recycle and obtain the same recycled instance
+        populatedInfo.recycle();
+        AccessibilityNodeInfo recycledInfo = AccessibilityNodeInfo.obtain();
+
+        // check expectations
+        assertAccessibilityNodeInfoCleared(recycledInfo);
+    }
+
+    /**
+     * Tests whether the event describes its contents consistently.
+     */
+    @SmallTest
+    public void testDescribeContents() {
+        AccessibilityNodeInfo info = AccessibilityNodeInfo.obtain();
+        assertSame("Accessibility node infos always return 0 for this method.", 0,
+                info.describeContents());
+        fullyPopulateAccessibilityNodeInfo(info);
+        assertSame("Accessibility node infos always return 0 for this method.", 0,
+                info.describeContents());
+    }
+
+    /**
+     * Tests whether accessibility actions are properly added.
+     */
+    @SmallTest
+    public void testAddActions() {
+        List<AccessibilityAction> customActions = new ArrayList<AccessibilityAction>();
+        customActions.add(new AccessibilityAction(AccessibilityNodeInfo.ACTION_FOCUS, "Foo"));
+        customActions.add(new AccessibilityAction(R.id.foo_custom_action, "Foo"));
+
+        AccessibilityNodeInfo info = AccessibilityNodeInfo.obtain();
+        info.addAction(AccessibilityNodeInfo.ACTION_FOCUS);
+        info.addAction(AccessibilityNodeInfo.ACTION_CLEAR_FOCUS);
+        for (AccessibilityAction customAction : customActions) {
+            info.addAction(customAction);
+        }
+
+        assertSame(info.getActions(), (AccessibilityNodeInfo.ACTION_FOCUS
+                | AccessibilityNodeInfo.ACTION_CLEAR_FOCUS));
+
+        List<AccessibilityAction> allActions = new ArrayList<AccessibilityAction>();
+        allActions.add(AccessibilityAction.ACTION_CLEAR_FOCUS);
+        allActions.addAll(customActions);
+        assertEquals(info.getActionList(), allActions);
+    }
+
+    /**
+     * Tests whether we catch addition of an action with invalid id.
+     */
+    @SmallTest
+    public void testCreateInvalidActionId() {
+        try {
+            new AccessibilityAction(3, null);
+        } catch (IllegalArgumentException iae) {
+            /* expected */
+        }
+    }
+
+    /**
+     * Tests whether accessibility actions are properly removed.
+     */
+    @SmallTest
+    public void testRemoveActions() {
+        AccessibilityNodeInfo info = AccessibilityNodeInfo.obtain();
+
+        info.addAction(AccessibilityNodeInfo.ACTION_FOCUS);
+        assertSame(info.getActions(), AccessibilityNodeInfo.ACTION_FOCUS);
+
+        info.removeAction(AccessibilityNodeInfo.ACTION_FOCUS);
+        assertSame(info.getActions(), 0);
+        assertTrue(info.getActionList().isEmpty());
+
+        AccessibilityAction customFocus = new AccessibilityAction(
+                AccessibilityNodeInfo.ACTION_FOCUS, "Foo");
+        info.addAction(AccessibilityNodeInfo.ACTION_FOCUS);
+        info.addAction(customFocus);
+        assertSame(info.getActionList().size(), 1);
+        assertEquals(info.getActionList().get(0), customFocus);
+        assertSame(info.getActions(), AccessibilityNodeInfo.ACTION_FOCUS);
+
+        info.removeAction(customFocus);
+        assertSame(info.getActions(), 0);
+        assertTrue(info.getActionList().isEmpty());
+    }
+
+    /**
+     * Fully populates the {@link AccessibilityNodeInfo} to marshal.
+     *
+     * @param info The node info to populate.
+     */
+    private void fullyPopulateAccessibilityNodeInfo(AccessibilityNodeInfo info) {
+        info.setParent(new View(getContext()));
+        info.setSource(new View(getContext()));
+        info.addChild(new View(getContext()));
+        info.addChild(new View(getContext()), 1);
+        info.setBoundsInParent(new Rect(1,1,1,1));
+        info.setBoundsInScreen(new Rect(2,2,2,2));
+        info.setClassName("foo.bar.baz.Class");
+        info.setContentDescription("content description");
+        info.setPackageName("foo.bar.baz");
+        info.setText("text");
+        info.setCheckable(true);
+        info.setChecked(true);
+        info.setClickable(true);
+        info.setEnabled(true);
+        info.setFocusable(true);
+        info.setFocused(true);
+        info.setImportantForAccessibility(true);
+        info.setLongClickable(true);
+        info.setContextClickable(true);
+        info.setPassword(true);
+        info.setScrollable(true);
+        info.setSelected(true);
+        info.addAction(AccessibilityNodeInfo.ACTION_FOCUS);
+        info.addAction(AccessibilityNodeInfo.ACTION_CLEAR_FOCUS);
+        info.addAction(new AccessibilityAction(AccessibilityNodeInfo.ACTION_FOCUS, "Foo"));
+        info.addAction(new AccessibilityAction(R.id.foo_custom_action, "Foo"));
+        info.setAccessibilityFocused(true);
+        info.setMovementGranularities(AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE);
+        info.setLabeledBy(new View(getContext()));
+        info.setLabelFor(new View(getContext()));
+        info.setViewIdResourceName("foo.bar:id/baz");
+        info.setDrawingOrder(5);
+    }
+
+    /**
+     * Compares all properties of the <code>expectedInfo</code> and the
+     * <code>receviedInfo</code> to verify that the received node info is
+     * the one that is expected.
+     */
+    public static void assertEqualsAccessibilityNodeInfo(AccessibilityNodeInfo expectedInfo,
+            AccessibilityNodeInfo receivedInfo) {
+        Rect expectedBounds = new Rect();
+        Rect receivedBounds = new Rect();
+        expectedInfo.getBoundsInParent(expectedBounds);
+        receivedInfo.getBoundsInParent(receivedBounds);
+        assertEquals("boundsInParent has incorrect value", expectedBounds, receivedBounds);
+        expectedInfo.getBoundsInScreen(expectedBounds);
+        receivedInfo.getBoundsInScreen(receivedBounds);
+        assertEquals("boundsInScreen has incorrect value", expectedBounds, receivedBounds);
+        assertEquals("className has incorrect value", expectedInfo.getClassName(),
+                receivedInfo.getClassName());
+        assertEquals("contentDescription has incorrect value", expectedInfo.getContentDescription(),
+                receivedInfo.getContentDescription());
+        assertEquals("packageName has incorrect value", expectedInfo.getPackageName(),
+                receivedInfo.getPackageName());
+        assertEquals("text has incorrect value", expectedInfo.getText(), receivedInfo.getText());
+        assertSame("checkable has incorrect value", expectedInfo.isCheckable(),
+                receivedInfo.isCheckable());
+        assertSame("checked has incorrect value", expectedInfo.isChecked(),
+                receivedInfo.isChecked());
+        assertSame("clickable has incorrect value", expectedInfo.isClickable(),
+                receivedInfo.isClickable());
+        assertSame("enabled has incorrect value", expectedInfo.isEnabled(),
+                receivedInfo.isEnabled());
+        assertSame("focusable has incorrect value", expectedInfo.isFocusable(),
+                receivedInfo.isFocusable());
+        assertSame("focused has incorrect value", expectedInfo.isFocused(),
+                receivedInfo.isFocused());
+        assertSame("importantForAccessibility has incorrect value",
+                expectedInfo.isImportantForAccessibility(),
+                receivedInfo.isImportantForAccessibility());
+        assertSame("longClickable has incorrect value", expectedInfo.isLongClickable(),
+                receivedInfo.isLongClickable());
+        assertSame("contextClickable has incorrect value", expectedInfo.isContextClickable(),
+                receivedInfo.isContextClickable());
+        assertSame("password has incorrect value", expectedInfo.isPassword(),
+                receivedInfo.isPassword());
+        assertSame("scrollable has incorrect value", expectedInfo.isScrollable(),
+                receivedInfo.isScrollable());
+        assertSame("selected has incorrect value", expectedInfo.isSelected(),
+                receivedInfo.isSelected());
+        assertSame("actions has incorrect value", expectedInfo.getActions(),
+                receivedInfo.getActions());
+        assertEquals("actionsSet has incorrect value", expectedInfo.getActionList(),
+                receivedInfo.getActionList());
+        assertSame("childCount has incorrect value", expectedInfo.getChildCount(),
+                receivedInfo.getChildCount());
+        assertSame("childCount has incorrect value", expectedInfo.getChildCount(),
+                receivedInfo.getChildCount());
+        assertSame("accessibilityFocused has incorrect value",
+                expectedInfo.isAccessibilityFocused(),
+                receivedInfo.isAccessibilityFocused());
+        assertSame("movementGranularities has incorrect value",
+                expectedInfo.getMovementGranularities(),
+                receivedInfo.getMovementGranularities());
+        assertEquals("viewId has incorrect value", expectedInfo.getViewIdResourceName(),
+                receivedInfo.getViewIdResourceName());
+        assertEquals("drawing order has incorrect value", expectedInfo.getDrawingOrder(),
+                receivedInfo.getDrawingOrder());
+    }
+
+    /**
+     * Asserts that an {@link AccessibilityNodeInfo} is cleared.
+     *
+     * @param info The node info to check.
+     */
+    public static void assertAccessibilityNodeInfoCleared(AccessibilityNodeInfo info) {
+        Rect bounds = new Rect();
+        info.getBoundsInParent(bounds);
+        assertTrue("boundsInParent not properly recycled", bounds.isEmpty());
+        info.getBoundsInScreen(bounds);
+        assertTrue("boundsInScreen not properly recycled", bounds.isEmpty());
+        assertNull("className not properly recycled", info.getClassName());
+        assertNull("contentDescription not properly recycled", info.getContentDescription());
+        assertNull("packageName not properly recycled", info.getPackageName());
+        assertNull("text not properly recycled", info.getText());
+        assertFalse("checkable not properly recycled", info.isCheckable());
+        assertFalse("checked not properly recycled", info.isChecked());
+        assertFalse("clickable not properly recycled", info.isClickable());
+        assertFalse("enabled not properly recycled", info.isEnabled());
+        assertFalse("focusable not properly recycled", info.isFocusable());
+        assertFalse("focused not properly recycled", info.isFocused());
+        assertFalse("importantForAccessibility not properly recycled",
+                info.isImportantForAccessibility());
+        assertFalse("longClickable not properly recycled", info.isLongClickable());
+        assertFalse("contextClickable not properly recycled", info.isContextClickable());
+        assertFalse("password not properly recycled", info.isPassword());
+        assertFalse("scrollable not properly recycled", info.isScrollable());
+        assertFalse("selected not properly recycled", info.isSelected());
+        assertSame("actions not properly recycled", 0, info.getActions());
+        assertFalse("accessibilityFocused not properly recycled", info.isAccessibilityFocused());
+        assertSame("movementGranularities not properly recycled", 0,
+                info.getMovementGranularities());
+        assertNull("viewId not properly recycled", info.getViewIdResourceName());
+        assertEquals(0, info.getDrawingOrder());
+    }
+}
diff --git a/tests/accessibility/src/android/view/accessibility/cts/AccessibilityNodeInfo_CollectionInfoTest.java b/tests/accessibility/src/android/view/accessibility/cts/AccessibilityNodeInfo_CollectionInfoTest.java
new file mode 100644
index 0000000..d64bd94
--- /dev/null
+++ b/tests/accessibility/src/android/view/accessibility/cts/AccessibilityNodeInfo_CollectionInfoTest.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.view.accessibility.cts;
+
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.view.accessibility.AccessibilityNodeInfo.CollectionInfo;
+
+/**
+ * Class for testing {@link CollectionInfo}.
+ */
+public class AccessibilityNodeInfo_CollectionInfoTest extends AndroidTestCase {
+
+    @SmallTest
+    public void testObtain() {
+        CollectionInfo c;
+
+        c = CollectionInfo.obtain(0, 1, true);
+        assertNotNull(c);
+        assertEquals(0, c.getRowCount());
+        assertEquals(1, c.getColumnCount());
+        assertTrue(c.isHierarchical());
+        assertEquals(CollectionInfo.SELECTION_MODE_NONE, c.getSelectionMode());
+
+        c = CollectionInfo.obtain(1, 2, true, CollectionInfo.SELECTION_MODE_MULTIPLE);
+        assertNotNull(c);
+        assertEquals(1, c.getRowCount());
+        assertEquals(2, c.getColumnCount());
+        assertTrue(c.isHierarchical());
+        assertEquals(CollectionInfo.SELECTION_MODE_MULTIPLE, c.getSelectionMode());
+    }
+}
diff --git a/tests/accessibility/src/android/view/accessibility/cts/AccessibilityNodeInfo_RangeInfoTest.java b/tests/accessibility/src/android/view/accessibility/cts/AccessibilityNodeInfo_RangeInfoTest.java
new file mode 100644
index 0000000..954d762
--- /dev/null
+++ b/tests/accessibility/src/android/view/accessibility/cts/AccessibilityNodeInfo_RangeInfoTest.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.view.accessibility.cts;
+
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityNodeInfo.RangeInfo;
+
+/**
+ * Class for testing {@link AccessibilityNodeInfo.RangeInfo}.
+ */
+public class AccessibilityNodeInfo_RangeInfoTest extends AndroidTestCase {
+
+    /** Allowed tolerance for floating point equality comparisons. */
+    public static final float FLOAT_TOLERANCE = 0.001f;
+
+    @SmallTest
+    public void testObtain() {
+        RangeInfo r;
+
+        r = RangeInfo.obtain(RangeInfo.RANGE_TYPE_INT, -100, 0, -50);
+        assertEquals(RangeInfo.RANGE_TYPE_INT, r.getType());
+        assertEquals(-100, r.getMin(), FLOAT_TOLERANCE);
+        assertEquals(0, r.getMax(), FLOAT_TOLERANCE);
+        assertEquals(-50, r.getCurrent(), FLOAT_TOLERANCE);
+
+        r = RangeInfo.obtain(RangeInfo.RANGE_TYPE_FLOAT, -1.5f, 1.5f, 0.0f);
+        assertEquals(RangeInfo.RANGE_TYPE_FLOAT, r.getType());
+        assertEquals(-1.5f, r.getMin(), FLOAT_TOLERANCE);
+        assertEquals(1.5f, r.getMax(), FLOAT_TOLERANCE);
+        assertEquals(0.0f, r.getCurrent(), FLOAT_TOLERANCE);
+
+        r = RangeInfo.obtain(RangeInfo.RANGE_TYPE_PERCENT, 0.0f, 100.0f, 50.0f);
+        assertEquals(RangeInfo.RANGE_TYPE_PERCENT, r.getType());
+        assertEquals(0.0f, r.getMin(), FLOAT_TOLERANCE);
+        assertEquals(100.0f, r.getMax(), FLOAT_TOLERANCE);
+        assertEquals(50.0f, r.getCurrent(), FLOAT_TOLERANCE);
+    }
+}
diff --git a/tests/accessibility/src/android/view/accessibility/cts/AccessibilityNodeProviderTest.java b/tests/accessibility/src/android/view/accessibility/cts/AccessibilityNodeProviderTest.java
new file mode 100644
index 0000000..eeee235
--- /dev/null
+++ b/tests/accessibility/src/android/view/accessibility/cts/AccessibilityNodeProviderTest.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.view.accessibility.cts;
+
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.view.accessibility.AccessibilityNodeProvider;
+
+/**
+ * Class for testing {@link AccessibilityNodeProvider}.
+ */
+public class AccessibilityNodeProviderTest extends AndroidTestCase {
+    @SmallTest
+    public void testDefaultBehavior() {
+        AccessibilityNodeProvider p = new AccessibilityNodeProvider() {
+            // Class is abstract, but has no abstract methods.
+        };
+
+        assertNull(p.createAccessibilityNodeInfo(0));
+        assertNull(p.findAccessibilityNodeInfosByText(null, 0));
+        assertNull(p.findFocus(0));
+        assertFalse(p.performAction(0, 0, null));
+    }
+}
diff --git a/tests/tests/accessibility/src/android/view/accessibility/cts/AccessibilityRecordTest.java b/tests/accessibility/src/android/view/accessibility/cts/AccessibilityRecordTest.java
similarity index 100%
rename from tests/tests/accessibility/src/android/view/accessibility/cts/AccessibilityRecordTest.java
rename to tests/accessibility/src/android/view/accessibility/cts/AccessibilityRecordTest.java
diff --git a/tests/accessibility/src/android/view/accessibility/cts/AccessibilityServiceInfoTest.java b/tests/accessibility/src/android/view/accessibility/cts/AccessibilityServiceInfoTest.java
new file mode 100644
index 0000000..bd14ee6
--- /dev/null
+++ b/tests/accessibility/src/android/view/accessibility/cts/AccessibilityServiceInfoTest.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view.accessibility.cts;
+
+import android.accessibilityservice.AccessibilityServiceInfo;
+import android.app.Service;
+import android.test.InstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityManager;
+
+import java.util.List;
+
+/**
+ * Tests whether accessibility service infos are properly reported. Logically,
+ * this test belongs to cts/test/test/accessibilityservice but the tests there
+ * are using the new UiAutomation API which disables all currently active
+ * accessibility service and the fake service used for implementing the UI
+ * automation is not reported through the APIs.
+ */
+public class AccessibilityServiceInfoTest  extends InstrumentationTestCase {
+
+    @Override
+    public void setUp() throws Exception {
+        ServiceControlUtils.enableSpeakingAndVibratingServices(getInstrumentation());
+    }
+
+    @Override
+    public void tearDown() {
+        ServiceControlUtils.turnAccessibilityOff(getInstrumentation());
+    }
+
+    /**
+     * Tests whether a service can that requested it can retrieve
+     * window content.
+     */
+    @MediumTest
+    @SuppressWarnings("deprecation")
+    public void testAccessibilityServiceInfoForEnabledService() {
+        AccessibilityManager accessibilityManager = (AccessibilityManager)
+                getInstrumentation().getContext().getSystemService(Service.ACCESSIBILITY_SERVICE);
+        List<AccessibilityServiceInfo> enabledServices =
+            accessibilityManager.getEnabledAccessibilityServiceList(
+                    AccessibilityServiceInfo.FEEDBACK_SPOKEN);
+        assertSame("There should be one speaking service.", 1, enabledServices.size());
+        AccessibilityServiceInfo speakingService = enabledServices.get(0);
+        assertSame(AccessibilityEvent.TYPES_ALL_MASK, speakingService.eventTypes);
+        assertSame(AccessibilityServiceInfo.FEEDBACK_SPOKEN, speakingService.feedbackType);
+        assertSame(AccessibilityServiceInfo.DEFAULT
+                | AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS
+                | AccessibilityServiceInfo.FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY
+                | AccessibilityServiceInfo.FLAG_REQUEST_TOUCH_EXPLORATION_MODE
+                | AccessibilityServiceInfo.FLAG_REQUEST_FILTER_KEY_EVENTS
+                | AccessibilityServiceInfo.FLAG_REPORT_VIEW_IDS,
+                speakingService.flags);
+        assertSame(0l, speakingService.notificationTimeout);
+        assertEquals("Some description", speakingService.getDescription());
+        assertNull(speakingService.packageNames /*all packages*/);
+        assertNotNull(speakingService.getId());
+        assertSame(speakingService.getCapabilities(),
+                AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY
+                | AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS
+                | AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION
+                | AccessibilityServiceInfo.CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT);
+        assertEquals("foo.bar.Activity", speakingService.getSettingsActivityName());
+        assertEquals("Some description", speakingService.loadDescription(
+                getInstrumentation().getContext().getPackageManager()));
+        assertNotNull(speakingService.getResolveInfo());
+    }
+}
diff --git a/tests/accessibility/src/android/view/accessibility/cts/AccessibilityWindowInfoTest.java b/tests/accessibility/src/android/view/accessibility/cts/AccessibilityWindowInfoTest.java
new file mode 100644
index 0000000..ffbe833
--- /dev/null
+++ b/tests/accessibility/src/android/view/accessibility/cts/AccessibilityWindowInfoTest.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.view.accessibility.cts;
+
+import android.graphics.Rect;
+import android.os.Parcel;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.text.TextUtils;
+import android.view.accessibility.AccessibilityWindowInfo;
+
+/**
+ * Class for testing {@link AccessibilityWindowInfo}.
+ */
+public class AccessibilityWindowInfoTest extends AndroidTestCase {
+
+    @SmallTest
+    public void testObtain() {
+        AccessibilityWindowInfo w1 = AccessibilityWindowInfo.obtain();
+        assertNotNull(w1);
+
+        AccessibilityWindowInfo w2 = AccessibilityWindowInfo.obtain(w1);
+        assertNotSame(w1, w2);
+        assertTrue(areWindowsEqual(w1, w2));
+    }
+
+    @SmallTest
+    public void testParceling() {
+        Parcel parcel = Parcel.obtain();
+        AccessibilityWindowInfo w1 = AccessibilityWindowInfo.obtain();
+        w1.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        AccessibilityWindowInfo w2 = AccessibilityWindowInfo.CREATOR.createFromParcel(parcel);
+        assertNotSame(w1, w2);
+        assertTrue(areWindowsEqual(w1, w2));
+    }
+
+    @SmallTest
+    public void testDefaultValues() {
+        AccessibilityWindowInfo w = AccessibilityWindowInfo.obtain();
+        assertEquals(0, w.getChildCount());
+        assertEquals(-1, w.getType());
+        assertEquals(-1, w.getLayer());
+        assertEquals(-1, w.getId());
+        assertEquals(0, w.describeContents());
+        assertNull(w.getParent());
+        assertNull(w.getRoot());
+        assertFalse(w.isAccessibilityFocused());
+        assertFalse(w.isActive());
+        assertFalse(w.isFocused());
+        assertNull(w.getTitle());
+
+        Rect rect = new Rect();
+        w.getBoundsInScreen(rect);
+        assertTrue(rect.isEmpty());
+
+        try {
+            w.getChild(0);
+            fail("Expected IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // Expected.
+        }
+    }
+
+    @SmallTest
+    public void testRecycle() {
+        AccessibilityWindowInfo w = AccessibilityWindowInfo.obtain();
+        w.recycle();
+
+        try {
+            w.recycle();
+            fail("Expected IllegalStateException");
+        } catch (IllegalStateException e) {
+            // Expected.
+        }
+    }
+
+    private boolean areWindowsEqual(AccessibilityWindowInfo w1, AccessibilityWindowInfo w2) {
+        boolean equality = w1.equals(w2);
+        equality &= TextUtils.equals(w1.getTitle(), w2.getTitle());
+        equality &= w1.isAccessibilityFocused() == w2.isAccessibilityFocused();
+        equality &= w1.isActive() == w2.isActive();
+        equality &= w1.getType() == w2.getType();
+        equality &= w1.getLayer() == w2.getLayer();
+        Rect bounds1 = new Rect();
+        Rect bounds2 = new Rect();
+        w1.getBoundsInScreen(bounds1);
+        w2.getBoundsInScreen(bounds2);
+        equality &= bounds1.equals(bounds2);
+        return equality;
+    }
+}
diff --git a/tests/accessibility/src/android/view/accessibility/cts/CaptioningManagerTest.java b/tests/accessibility/src/android/view/accessibility/cts/CaptioningManagerTest.java
new file mode 100644
index 0000000..cf82666
--- /dev/null
+++ b/tests/accessibility/src/android/view/accessibility/cts/CaptioningManagerTest.java
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.view.accessibility.cts;
+
+import android.app.UiAutomation;
+import android.os.ParcelFileDescriptor;
+import android.test.InstrumentationTestCase;
+import android.view.accessibility.CaptioningManager;
+import android.view.accessibility.CaptioningManager.CaptionStyle;
+import android.view.accessibility.CaptioningManager.CaptioningChangeListener;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Locale;
+
+/**
+ * Tests whether the CaptioningManager APIs are functional.
+ */
+public class CaptioningManagerTest extends InstrumentationTestCase {
+    private CaptioningManager mManager;
+    private UiAutomation mUiAutomation;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        mManager = getInstrumentation().getTargetContext().getSystemService(
+                CaptioningManager.class);
+
+        assertNotNull("Obtained captioning manager", mManager);
+
+        mUiAutomation = getInstrumentation().getUiAutomation();
+    }
+
+    /**
+     * Tests whether a client can observe changes in caption properties.
+     */
+    public void testChangeListener() {
+        putSecureSetting("accessibility_captioning_enabled","0");
+        putSecureSetting("accessibility_captioning_preset", "1");
+        putSecureSetting("accessibility_captioning_locale", "en_US");
+        putSecureSetting("accessibility_captioning_font_scale", "1.0");
+
+        MockCaptioningChangeListener listener = new MockCaptioningChangeListener();
+        mManager.addCaptioningChangeListener(listener);
+
+        putSecureSetting("accessibility_captioning_enabled", "1");
+        assertTrue("Observed enabled change", listener.wasEnabledChangedCalled);
+
+        // Style change gets posted in a Runnable, so we need to wait for idle.
+        putSecureSetting("accessibility_captioning_preset", "-1");
+        getInstrumentation().waitForIdleSync();
+        assertTrue("Observed user style change", listener.wasUserStyleChangedCalled);
+
+        putSecureSetting("accessibility_captioning_locale", "ja_JP");
+        assertTrue("Observed locale change", listener.wasLocaleChangedCalled);
+
+        putSecureSetting("accessibility_captioning_font_scale", "2.0");
+        assertTrue("Observed font scale change", listener.wasFontScaleChangedCalled);
+
+        mManager.removeCaptioningChangeListener(listener);
+
+        listener.reset();
+
+        putSecureSetting("accessibility_captioning_enabled","0");
+        assertFalse("Did not observe enabled change", listener.wasEnabledChangedCalled);
+
+        try {
+            mManager.removeCaptioningChangeListener(listener);
+        } catch (Exception e) {
+            throw new AssertionError("Fails silently when removing listener twice", e);
+        }
+    }
+
+    public void testProperties() {
+        putSecureSetting("accessibility_captioning_font_scale", "2.0");
+        putSecureSetting("accessibility_captioning_locale", "ja_JP");
+        putSecureSetting("accessibility_captioning_enabled", "1");
+
+        assertEquals("Test runner set font scale to 2.0", 2.0f, mManager.getFontScale());
+        assertEquals("Test runner set locale to Japanese", Locale.JAPAN, mManager.getLocale());
+        assertEquals("Test runner set enabled to true", true, mManager.isEnabled());
+    }
+
+    public void testUserStyle() {
+        putSecureSetting("accessibility_captioning_preset", "-1");
+        putSecureSetting("accessibility_captioning_foreground_color", "511");
+        putSecureSetting("accessibility_captioning_background_color", "511");
+        putSecureSetting("accessibility_captioning_window_color", "511");
+        putSecureSetting("accessibility_captioning_edge_color", "511");
+        putSecureSetting("accessibility_captioning_edge_type", "-1");
+        deleteSecureSetting("accessibility_captioning_typeface");
+
+        CaptionStyle userStyle = mManager.getUserStyle();
+        assertNotNull("Default user style is not null", userStyle);
+        assertFalse("Default user style has no edge type", userStyle.hasEdgeType());
+        assertFalse("Default user style has no edge color", userStyle.hasEdgeColor());
+        assertFalse("Default user style has no foreground color", userStyle.hasForegroundColor());
+        assertFalse("Default user style has no background color", userStyle.hasBackgroundColor());
+        assertFalse("Default user style has no window color", userStyle.hasWindowColor());
+        assertNull("Default user style has no typeface", userStyle.getTypeface());
+    }
+
+    private void deleteSecureSetting(String name) {
+        execShellCommand("settings delete secure " + name);
+    }
+
+    private void putSecureSetting(String name, String value) {
+        execShellCommand("settings put secure " + name + " " + value);
+    }
+
+    private void execShellCommand(String cmd) {
+        ParcelFileDescriptor pfd = mUiAutomation.executeShellCommand(cmd);
+        InputStream is = new FileInputStream(pfd.getFileDescriptor());
+        try {
+            final byte[] buffer = new byte[8192];
+            while ((is.read(buffer)) != -1);
+        } catch (IOException e) {
+            throw new RuntimeException("Failed to exec: " + cmd);
+        }
+    }
+
+    private static class MockCaptioningChangeListener extends CaptioningChangeListener {
+        boolean wasEnabledChangedCalled = false;
+        boolean wasUserStyleChangedCalled = false;
+        boolean wasLocaleChangedCalled = false;
+        boolean wasFontScaleChangedCalled = false;
+
+        @Override
+        public void onEnabledChanged(boolean enabled) {
+            super.onEnabledChanged(enabled);
+            wasEnabledChangedCalled = true;
+        }
+
+        @Override
+        public void onUserStyleChanged(CaptionStyle userStyle) {
+            super.onUserStyleChanged(userStyle);
+            wasUserStyleChangedCalled = true;
+        }
+
+        @Override
+        public void onLocaleChanged(Locale locale) {
+            super.onLocaleChanged(locale);
+            wasLocaleChangedCalled = true;
+        }
+
+        @Override
+        public void onFontScaleChanged(float fontScale) {
+            super.onFontScaleChanged(fontScale);
+            wasFontScaleChangedCalled = true;
+        }
+
+        public void reset() {
+            wasEnabledChangedCalled = false;
+            wasUserStyleChangedCalled = false;
+            wasLocaleChangedCalled = false;
+            wasFontScaleChangedCalled = false;
+        }
+    }
+}
diff --git a/tests/accessibility/src/android/view/accessibility/cts/ServiceControlUtils.java b/tests/accessibility/src/android/view/accessibility/cts/ServiceControlUtils.java
new file mode 100644
index 0000000..c2e0050
--- /dev/null
+++ b/tests/accessibility/src/android/view/accessibility/cts/ServiceControlUtils.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.view.accessibility.cts;
+
+import android.app.Instrumentation;
+import android.app.UiAutomation;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.os.ParcelFileDescriptor;
+import android.os.SystemClock;
+import android.provider.Settings;
+import android.view.accessibility.AccessibilityManager;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Utility methods for enabling and disabling the services used in this package
+ */
+public class ServiceControlUtils {
+    private static final int TIMEOUT_FOR_SERVICE_ENABLE = 10000; // millis; 10s
+
+    private static final String SETTING_ENABLE_SPEAKING_AND_VIBRATING_SERVICES =
+            "android.view.accessibility.cts/.SpeakingAccessibilityService:"
+            + "android.view.accessibility.cts/.VibratingAccessibilityService";
+
+    /**
+     * Enable {@code SpeakingAccessibilityService} and {@code SpeakingAccessibilityService}
+     *
+     * @param instrumentation A valid instrumentation
+     */
+    public static void enableSpeakingAndVibratingServices(Instrumentation instrumentation)
+            throws IOException {
+        Context context = instrumentation.getContext();
+
+        // Get permission to enable accessibility
+        UiAutomation uiAutomation = instrumentation.getUiAutomation();
+
+        // Change the settings to enable the two services
+        ContentResolver cr = context.getContentResolver();
+        String alreadyEnabledServices = Settings.Secure.getString(
+                cr, Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
+        ParcelFileDescriptor fd = uiAutomation.executeShellCommand("settings --user cur put secure "
+                + Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES + " "
+                + alreadyEnabledServices + ":"
+                + SETTING_ENABLE_SPEAKING_AND_VIBRATING_SERVICES);
+        InputStream in = new FileInputStream(fd.getFileDescriptor());
+        byte[] buffer = new byte[4096];
+        while (in.read(buffer) > 0);
+        uiAutomation.destroy();
+
+        // Wait for speaking service to be connected
+        long timeoutTimeMillis = SystemClock.uptimeMillis() + TIMEOUT_FOR_SERVICE_ENABLE;
+        boolean speakingServiceStarted = false;
+        while (!speakingServiceStarted && (SystemClock.uptimeMillis() < timeoutTimeMillis)) {
+            synchronized (SpeakingAccessibilityService.sWaitObjectForConnecting) {
+                if (SpeakingAccessibilityService.sConnectedInstance != null) {
+                    speakingServiceStarted = true;
+                    break;
+                }
+                if (!speakingServiceStarted) {
+                    try {
+                        SpeakingAccessibilityService.sWaitObjectForConnecting.wait(
+                                timeoutTimeMillis - SystemClock.uptimeMillis());
+                    } catch (InterruptedException e) {
+                    }
+                }
+            }
+        }
+        if (!speakingServiceStarted) {
+            throw new RuntimeException("Speaking accessibility service not starting");
+        }
+
+        // Wait for vibrating service to be connected
+        while (SystemClock.uptimeMillis() < timeoutTimeMillis) {
+            synchronized (VibratingAccessibilityService.sWaitObjectForConnecting) {
+                if (VibratingAccessibilityService.sConnectedInstance != null) {
+                    return;
+                }
+
+                try {
+                    VibratingAccessibilityService.sWaitObjectForConnecting.wait(
+                            timeoutTimeMillis - SystemClock.uptimeMillis());
+                } catch (InterruptedException e) {
+                }
+            }
+        }
+        throw new RuntimeException("Vibrating accessibility service not starting");
+    }
+
+    /**
+     * Turn off all accessibility services. Assumes permissions to write settings are already
+     * set, which they are in
+     * {@link ServiceControlUtils#enableSpeakingAndVibratingServices(Instrumentation)}.
+     *
+     * @param instrumentation A valid instrumentation
+     */
+    public static void turnAccessibilityOff(Instrumentation instrumentation) {
+        SpeakingAccessibilityService.sConnectedInstance.disableSelf();
+        SpeakingAccessibilityService.sConnectedInstance = null;
+        VibratingAccessibilityService.sConnectedInstance.disableSelf();
+        VibratingAccessibilityService.sConnectedInstance = null;
+
+        final Object waitLockForA11yOff = new Object();
+        AccessibilityManager manager = (AccessibilityManager) instrumentation
+                .getContext().getSystemService(Context.ACCESSIBILITY_SERVICE);
+        manager.addAccessibilityStateChangeListener(
+                new AccessibilityManager.AccessibilityStateChangeListener() {
+                    @Override
+                    public void onAccessibilityStateChanged(boolean b) {
+                        synchronized (waitLockForA11yOff) {
+                            waitLockForA11yOff.notifyAll();
+                        }
+                    }
+                });
+        long timeoutTimeMillis = SystemClock.uptimeMillis() + TIMEOUT_FOR_SERVICE_ENABLE;
+        while (SystemClock.uptimeMillis() < timeoutTimeMillis) {
+            synchronized (waitLockForA11yOff) {
+                if (!manager.isEnabled()) {
+                    return;
+                }
+                try {
+                    waitLockForA11yOff.wait(timeoutTimeMillis - SystemClock.uptimeMillis());
+                } catch (InterruptedException e) {
+                    // Ignored; loop again
+                }
+            }
+        }
+        throw new RuntimeException("Unable to turn accessibility off");
+    }
+}
diff --git a/tests/accessibility/src/android/view/accessibility/cts/SpeakingAccessibilityService.java b/tests/accessibility/src/android/view/accessibility/cts/SpeakingAccessibilityService.java
new file mode 100644
index 0000000..219a2ff
--- /dev/null
+++ b/tests/accessibility/src/android/view/accessibility/cts/SpeakingAccessibilityService.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.view.accessibility.cts;
+
+import android.accessibilityservice.AccessibilityService;
+import android.accessibilityservice.AccessibilityServiceInfo;
+import android.view.accessibility.AccessibilityEvent;
+
+/**
+ * Stub accessibility service that reports itself as providing spoken feedback.
+ */
+public class SpeakingAccessibilityService extends AccessibilityService {
+    public static Object sWaitObjectForConnecting = new Object();
+
+    public static SpeakingAccessibilityService sConnectedInstance;
+
+    @Override
+    public void onDestroy() {
+        sConnectedInstance = null;
+    }
+
+    @Override
+    protected void onServiceConnected() {
+        final AccessibilityServiceInfo info = getServiceInfo();
+        info.flags |= AccessibilityServiceInfo.FLAG_REQUEST_TOUCH_EXPLORATION_MODE;
+        setServiceInfo(info);
+
+        synchronized (sWaitObjectForConnecting) {
+            sConnectedInstance = this;
+            sWaitObjectForConnecting.notifyAll();
+        }
+    }
+
+    @Override
+    public void onAccessibilityEvent(AccessibilityEvent event) {
+        /* do nothing */
+    }
+
+    @Override
+    public void onInterrupt() {
+        /* do nothing */
+    }
+}
diff --git a/tests/accessibility/src/android/view/accessibility/cts/VibratingAccessibilityService.java b/tests/accessibility/src/android/view/accessibility/cts/VibratingAccessibilityService.java
new file mode 100644
index 0000000..41edf9f
--- /dev/null
+++ b/tests/accessibility/src/android/view/accessibility/cts/VibratingAccessibilityService.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.view.accessibility.cts;
+
+import android.accessibilityservice.AccessibilityService;
+import android.accessibilityservice.AccessibilityServiceInfo;
+import android.view.accessibility.AccessibilityEvent;
+
+/**
+ * Stub accessibility service that reports itself as providing haptic feedback.
+ */
+public class VibratingAccessibilityService extends AccessibilityService {
+    public static Object sWaitObjectForConnecting = new Object();
+
+    public static VibratingAccessibilityService sConnectedInstance;
+
+    @Override
+    public void onDestroy() {
+        sConnectedInstance = null;
+    }
+
+    @Override
+    protected void onServiceConnected() {
+        final AccessibilityServiceInfo info = getServiceInfo();
+        info.flags |= AccessibilityServiceInfo.FLAG_REQUEST_TOUCH_EXPLORATION_MODE;
+        setServiceInfo(info);
+
+        synchronized (sWaitObjectForConnecting) {
+            sConnectedInstance = this;
+            sWaitObjectForConnecting.notifyAll();
+        }
+    }
+
+    @Override
+    public void onAccessibilityEvent(AccessibilityEvent event) {
+        /* do nothing */
+    }
+
+    @Override
+    public void onInterrupt() {
+        /* do nothing */
+    }
+}
diff --git a/tests/accessibility/src/android/view/accessibility/services/SpeakingAccessibilityService.java b/tests/accessibility/src/android/view/accessibility/services/SpeakingAccessibilityService.java
deleted file mode 100644
index c54c8eb..0000000
--- a/tests/accessibility/src/android/view/accessibility/services/SpeakingAccessibilityService.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.view.accessibility.services;
-
-import android.accessibilityservice.AccessibilityService;
-import android.view.accessibility.AccessibilityEvent;
-
-/**
- * Stub accessibility service that reports itself as providing spoken feedback.
- */
-public class SpeakingAccessibilityService extends AccessibilityService {
-
-    @Override
-    public void onAccessibilityEvent(AccessibilityEvent event) {
-        /* do nothing */
-    }
-
-    @Override
-    public void onInterrupt() {
-        /* do nothing */
-    }
-}
diff --git a/tests/accessibility/src/android/view/accessibility/services/VibratingAccessibilityService.java b/tests/accessibility/src/android/view/accessibility/services/VibratingAccessibilityService.java
deleted file mode 100644
index 22df63d..0000000
--- a/tests/accessibility/src/android/view/accessibility/services/VibratingAccessibilityService.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.view.accessibility.services;
-
-import android.accessibilityservice.AccessibilityService;
-import android.view.accessibility.AccessibilityEvent;
-
-/**
- * Stub accessibility service that reports itself as providing haptic feedback.
- */
-public class VibratingAccessibilityService extends AccessibilityService {
-
-    @Override
-    public void onAccessibilityEvent(AccessibilityEvent event) {
-        /* do nothing */
-    }
-
-    @Override
-    public void onInterrupt() {
-        /* do nothing */
-    }
-}
diff --git a/tests/accessibilityservice/Android.mk b/tests/accessibilityservice/Android.mk
new file mode 100644
index 0000000..8ce6e99
--- /dev/null
+++ b/tests/accessibilityservice/Android.mk
@@ -0,0 +1,32 @@
+# Copyright (C) 2010 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner mockito-target
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_PACKAGE_NAME := CtsAccessibilityServiceTestCases
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/accessibilityservice/AndroidManifest.xml b/tests/accessibilityservice/AndroidManifest.xml
new file mode 100644
index 0000000..3381f48
--- /dev/null
+++ b/tests/accessibilityservice/AndroidManifest.xml
@@ -0,0 +1,111 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="android.accessibilityservice.cts">
+
+    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+    <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
+
+    <application android:theme="@android:style/Theme.Holo.NoActionBar">
+
+        <uses-library android:name="android.test.runner" />
+
+        <activity
+            android:label="@string/accessibility_end_to_end_test_activity"
+            android:name=".AccessibilityEndToEndActivity" />
+
+        <activity
+            android:label="@string/accessibility_query_window_test_activity"
+            android:name=".AccessibilityWindowQueryActivity" />
+
+        <activity
+            android:label="@string/accessibility_view_tree_reporting_test_activity"
+            android:name=".AccessibilityViewTreeReportingActivity" />
+
+        <activity
+            android:label="@string/accessibility_focus_and_input_focus_sync_test_activity"
+            android:name=".AccessibilityFocusAndInputFocusSyncActivity" />
+
+        <activity
+            android:label="@string/accessibility_text_traversal_test_activity"
+            android:name=".AccessibilityTextTraversalActivity"/>
+
+        <activity android:label="Activity for testing window accessibility reporting"
+             android:name=".AccessibilityWindowReportingActivity"/>
+
+        <activity
+            android:label="Full screen activity for gesture dispatch testing"
+            android:name=".AccessibilityGestureDispatchTest$GestureDispatchActivity" />
+
+        <service
+            android:name=".StubGestureAccessibilityService"
+            android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
+            <intent-filter>
+                <action android:name="android.accessibilityservice.AccessibilityService" />
+                <category android:name="android.accessibilityservice.category.FEEDBACK_GENERIC" />
+            </intent-filter>
+
+            <meta-data
+                android:name="android.accessibilityservice"
+                android:resource="@xml/stub_gesture_a11y_service" />
+        </service>
+
+        <activity
+            android:label="@string/accessibility_soft_keyboard_modes_activity"
+            android:name=".AccessibilitySoftKeyboardModesTest$SoftKeyboardModesActivity"
+            android:windowSoftInputMode="stateAlwaysVisible" />
+
+        <service
+            android:name=".InstrumentedAccessibilityService"
+            android:label="@string/title_soft_keyboard_modes_accessibility_service"
+            android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
+            <intent-filter>
+                <action android:name="android.accessibilityservice.AccessibilityService" />
+                <category android:name="android.accessibilityservice.category.FEEDBACK_GENERIC" />
+            </intent-filter>
+            <meta-data
+                android:name="android.accessibilityservice"
+                android:resource="@xml/stub_soft_keyboard_modes_accessibility_service" />
+        </service>
+
+        <service
+            android:name=".StubMagnificationAccessibilityService"
+            android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
+            <intent-filter>
+                <action android:name="android.accessibilityservice.AccessibilityService" />
+                <category android:name="android.accessibilityservice.category.FEEDBACK_GENERIC" />
+            </intent-filter>
+
+            <meta-data
+                android:name="android.accessibilityservice"
+                android:resource="@xml/stub_magnification_a11y_service" />
+        </service>
+
+    </application>
+
+    <instrumentation
+        android:name="android.support.test.runner.AndroidJUnitRunner"
+        android:targetPackage="android.accessibilityservice.cts"
+        android:label="Tests for the accessibility APIs.">
+        <meta-data
+            android:name="listener"
+            android:value="com.android.cts.runner.CtsTestRunListener" />
+
+    </instrumentation>
+
+</manifest>
diff --git a/tests/accessibilityservice/AndroidTest.xml b/tests/accessibilityservice/AndroidTest.xml
new file mode 100644
index 0000000..b2cb477
--- /dev/null
+++ b/tests/accessibilityservice/AndroidTest.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS accessibility service test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsAccessibilityServiceTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.accessibilityservice.cts" />
+        <option name="runtime-hint" value="2m12s" />
+    </test>
+</configuration>
diff --git a/tests/tests/accessibilityservice/res/layout/accessibility_focus_and_input_focus_sync_test.xml b/tests/accessibilityservice/res/layout/accessibility_focus_and_input_focus_sync_test.xml
similarity index 100%
rename from tests/tests/accessibilityservice/res/layout/accessibility_focus_and_input_focus_sync_test.xml
rename to tests/accessibilityservice/res/layout/accessibility_focus_and_input_focus_sync_test.xml
diff --git a/tests/accessibilityservice/res/layout/accessibility_soft_keyboard_modes_test.xml b/tests/accessibilityservice/res/layout/accessibility_soft_keyboard_modes_test.xml
new file mode 100644
index 0000000..577a204
--- /dev/null
+++ b/tests/accessibilityservice/res/layout/accessibility_soft_keyboard_modes_test.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<EditText xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/edit_text"
+    android:orientation="vertical"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent" />
diff --git a/tests/accessibilityservice/res/layout/accessibility_text_traversal_test.xml b/tests/accessibilityservice/res/layout/accessibility_text_traversal_test.xml
new file mode 100644
index 0000000..852a003
--- /dev/null
+++ b/tests/accessibilityservice/res/layout/accessibility_text_traversal_test.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="fill_parent"
+    android:layout_height="wrap_content"
+    >
+
+   <View
+       android:id="@+id/view"
+       android:layout_width="50dip"
+       android:layout_height="50dip"
+       android:visibility="gone"
+       />
+
+   <TextView
+       android:id="@+id/text"
+       android:layout_width="80dip"
+       android:layout_height="80dip"
+       android:includeFontPadding="false"
+       android:textSize="10dip"
+       android:textStyle="normal"
+       android:fontFamily="sans-serif"
+       android:visibility="gone"
+       />
+
+   <EditText
+       android:id="@+id/edit"
+       android:layout_width="80dip"
+       android:layout_height="80dip"
+       android:maxLines="1000"
+       android:scrollbars="vertical"
+       android:focusable="false"
+       android:includeFontPadding="false"
+       android:textSize="10dip"
+       android:textStyle="normal"
+       android:lineSpacingExtra="20dp"
+       android:lineSpacingMultiplier="0.0"
+       android:fontFamily="sans-serif"
+       android:background="@null"
+       android:visibility="gone"
+       />
+
+</LinearLayout>
diff --git a/tests/tests/accessibilityservice/res/layout/accessibility_view_tree_reporting_test.xml b/tests/accessibilityservice/res/layout/accessibility_view_tree_reporting_test.xml
similarity index 100%
rename from tests/tests/accessibilityservice/res/layout/accessibility_view_tree_reporting_test.xml
rename to tests/accessibilityservice/res/layout/accessibility_view_tree_reporting_test.xml
diff --git a/tests/accessibilityservice/res/layout/accessibility_window_reporting_test.xml b/tests/accessibilityservice/res/layout/accessibility_window_reporting_test.xml
new file mode 100644
index 0000000..074343e
--- /dev/null
+++ b/tests/accessibilityservice/res/layout/accessibility_window_reporting_test.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:orientation="vertical"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent">
+    <AutoCompleteTextView
+              android:id="@+id/autoCompleteLayout"
+              android:layout_width="match_parent"
+              android:layout_height="wrap_content"/>
+</LinearLayout>
\ No newline at end of file
diff --git a/tests/tests/accessibilityservice/res/layout/end_to_end_test.xml b/tests/accessibilityservice/res/layout/end_to_end_test.xml
similarity index 100%
rename from tests/tests/accessibilityservice/res/layout/end_to_end_test.xml
rename to tests/accessibilityservice/res/layout/end_to_end_test.xml
diff --git a/tests/accessibilityservice/res/layout/full_screen_frame_layout.xml b/tests/accessibilityservice/res/layout/full_screen_frame_layout.xml
new file mode 100644
index 0000000..3585bbd
--- /dev/null
+++ b/tests/accessibilityservice/res/layout/full_screen_frame_layout.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+        android:id="@+id/full_screen_text_view"
+        android:text="@string/full_screen_text_view"
+        android:layout_width="fill_parent"
+        android:layout_height="fill_parent" />
diff --git a/tests/tests/accessibilityservice/res/layout/list_view_row.xml b/tests/accessibilityservice/res/layout/list_view_row.xml
similarity index 100%
rename from tests/tests/accessibilityservice/res/layout/list_view_row.xml
rename to tests/accessibilityservice/res/layout/list_view_row.xml
diff --git a/tests/tests/accessibilityservice/res/layout/query_window_test.xml b/tests/accessibilityservice/res/layout/query_window_test.xml
similarity index 100%
rename from tests/tests/accessibilityservice/res/layout/query_window_test.xml
rename to tests/accessibilityservice/res/layout/query_window_test.xml
diff --git a/tests/tests/accessibilityservice/res/values/ids.xml b/tests/accessibilityservice/res/values/ids.xml
similarity index 100%
rename from tests/tests/accessibilityservice/res/values/ids.xml
rename to tests/accessibilityservice/res/values/ids.xml
diff --git a/tests/accessibilityservice/res/values/strings.xml b/tests/accessibilityservice/res/values/strings.xml
new file mode 100644
index 0000000..7c9547c
--- /dev/null
+++ b/tests/accessibilityservice/res/values/strings.xml
@@ -0,0 +1,161 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+
+    <!-- AccessibilityEndToEndTest -->
+
+    <!-- String title of the accessibility end-to-end test activity -->
+    <string name="accessibility_end_to_end_test_activity">End-to-end test</string>
+
+    <!-- String title of the accessibility test activity -->
+    <string name="accessibility_test_activity">Test</string>
+
+    <!-- String value of used as text input -->
+    <string name="text_input_blah">Blah</string>
+
+    <!-- String value of used as text input -->
+    <string name="text_input_blah_blah">Blah blah</string>
+
+    <!-- String title of the button -->
+    <string name="button_title">Click me</string>
+
+    <!-- String value of the first list item -->
+    <string name="first_list_item">First list item</string>
+
+    <!-- String value of the second list item -->
+    <string name="second_list_item">Second list item</string>
+
+    <!-- String alert title -->
+    <string name="alert_title">Alert title</string>
+
+    <!-- String alert message -->
+    <string name="alert_message">Alert message</string>
+
+    <!-- String notification message -->
+    <string name="notification_message">Notification message</string>
+
+    <!-- AccessibilityWindowQueryTest -->
+
+    <!-- String title of the accessibility query window test activity -->
+    <string name="accessibility_query_window_test_activity">Query window test</string>
+
+    <!-- String Button1 text -->
+    <string name="button1">B1</string>
+
+    <!-- String Button2 text -->
+    <string name="button2">B2</string>
+
+    <!-- String Button3 text -->
+    <string name="button3">B3</string>
+
+    <!-- String Button4 text -->
+    <string name="button4">B4</string>
+
+    <!-- String Button5 text -->
+    <string name="button5">B5</string>
+
+    <!-- String Button6 text -->
+    <string name="button6">B6</string>
+
+    <!-- String with content description for Button6 -->
+    <string name="contentDescription">contentDescription</string>
+
+    <!-- String Button7 text -->
+    <string name="button7">B7</string>
+
+    <!-- String Button8 text -->
+    <string name="button8">B8</string>
+
+    <!-- String Button9 text -->
+    <string name="button9">B9</string>
+
+    <!-- AccessibilityFocusTest -->
+
+    <!-- String title of the accessibility hierarchical focus test activity -->
+    <string name="accessibility_view_tree_reporting_test_activity">Accessibility view three reporting test</string>
+
+    <!-- String root LinearLayout text -->
+    <string name="rootLinearLayout">rLL</string>
+
+    <!-- String first FrameLayout text -->
+    <string name="firstFrameLayout">fFL</string>
+
+    <!-- String first LinearLayout text -->
+    <string name="firstLinearLayout">fLL</string>
+
+    <!-- String first TextView text -->
+    <string name="firstTextView">fTV</string>
+
+    <!-- String first EditText text -->
+    <string name="firstEditText">fET</string>
+
+    <!-- String first Button text -->
+    <string name="firstButton">fB</string>
+
+    <!-- String second FrameLayout text -->
+    <string name="secondFrameLayout">sFL</string>
+
+    <!-- String second LinearLayout text -->
+    <string name="secondLinearLayout">sLL</string>
+
+    <!-- String second TextView text -->
+    <string name="secondTextView">sTV</string>
+
+    <!-- String second EditText text -->
+    <string name="secondEditText">sET</string>
+
+    <!-- String second Button text -->
+    <string name="secondButton">sB</string>
+
+    <!-- String title of the accessibility focus and input focus sync test activity -->
+    <string name="accessibility_focus_and_input_focus_sync_test_activity">Accessibility focus and input focus sync test</string>
+
+    <!-- String title of the accessibility text traversal test activity. -->
+    <string name="accessibility_text_traversal_test_activity">Accessibility text traversal test</string>
+
+    <string name="android_wiki_short">
+        Android is a\nLinux-based\noperating</string>
+
+    <string name="android_wiki">Android is a Linux-based operating system for mobile devices such as smartphones and tablet computers. It is developed by the Open Handset Alliance, and here is some text padding</string>
+
+    <string name="a_b">A B</string>
+
+    <string name="android_wiki_search">Android is a Linux-based</string>
+
+    <string name="foo_bar_baz">Foo bar baz.</string>
+
+    <string name="stub_gesture_a11y_service_description">com.android.accessibilityservice.cts.StubGestureAccessibilityService</string>
+
+    <string name="android_wiki_paragraphs">
+        \n\nAndroid is a\n\n It is developed\n The
+        unveiling\n\n</string>
+
+    <string name="full_screen_text_view">Full Screen Text View</string>
+    <!-- Soft Keyboard Modes tests -->
+
+    <!-- String title for the accessibility service -->
+    <string name="accessibility_soft_keyboard_modes_activity">
+        Soft Keyboard Modes Activity</string>
+
+    <string name="title_soft_keyboard_modes_accessibility_service">
+        Stub Soft Keyboard Modes Accessibility Service</string>
+
+    <!-- Description of the accessibility service -->
+    <string name="soft_keyboard_modes_accessibility_service_description">This Accessibility Service was installed for testing purposes. It can be uninstalled by going to Settings > Apps > android.view.accessibilityservice.services and selecting \"Uninstall\".</string>
+
+</resources>
diff --git a/tests/accessibilityservice/res/xml/stub_gesture_a11y_service.xml b/tests/accessibilityservice/res/xml/stub_gesture_a11y_service.xml
new file mode 100644
index 0000000..25a55fc
--- /dev/null
+++ b/tests/accessibilityservice/res/xml/stub_gesture_a11y_service.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
+                       android:description="@string/stub_gesture_a11y_service_description"
+                       android:accessibilityEventTypes="typeAllMask"
+                       android:accessibilityFeedbackType="feedbackGeneric"
+                       android:accessibilityFlags="flagDefault"
+                       android:canPerformGestures="true"
+                       android:notificationTimeout="0" />
diff --git a/tests/accessibilityservice/res/xml/stub_magnification_a11y_service.xml b/tests/accessibilityservice/res/xml/stub_magnification_a11y_service.xml
new file mode 100644
index 0000000..110f741
--- /dev/null
+++ b/tests/accessibilityservice/res/xml/stub_magnification_a11y_service.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
+    android:accessibilityEventTypes="typeAllMask"
+    android:accessibilityFeedbackType="feedbackGeneric"
+    android:canRetrieveWindowContent="true"
+    android:canRequestTouchExplorationMode="true"
+    android:canRequestEnhancedWebAccessibility="true"
+    android:canRequestFilterKeyEvents="true"
+    android:canControlMagnification="true" />
diff --git a/tests/accessibilityservice/res/xml/stub_soft_keyboard_modes_accessibility_service.xml b/tests/accessibilityservice/res/xml/stub_soft_keyboard_modes_accessibility_service.xml
new file mode 100644
index 0000000..b5f9ede
--- /dev/null
+++ b/tests/accessibilityservice/res/xml/stub_soft_keyboard_modes_accessibility_service.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
+    android:accessibilityEventTypes="typeAllMask"
+    android:accessibilityFeedbackType="feedbackGeneric"
+    android:accessibilityFlags="flagDefault|flagRetrieveInteractiveWindows"
+    android:canRetrieveWindowContent="true"
+    android:description="@string/soft_keyboard_modes_accessibility_service_description" />
diff --git a/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityActivityTestCase.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityActivityTestCase.java
similarity index 100%
rename from tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityActivityTestCase.java
rename to tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityActivityTestCase.java
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEndToEndActivity.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEndToEndActivity.java
new file mode 100644
index 0000000..9a26ac7
--- /dev/null
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEndToEndActivity.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.accessibilityservice.cts;
+
+import android.accessibilityservice.cts.R;
+
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.ListAdapter;
+import android.widget.ListView;
+import android.widget.TextView;
+
+/**
+ * This class is an {@link android.app.Activity} used to perform end-to-end
+ * testing of the accessibility feature by interaction with the
+ * UI widgets.
+ */
+public class AccessibilityEndToEndActivity extends AccessibilityTestActivity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.end_to_end_test);
+
+        ListAdapter listAdapter = new BaseAdapter() {
+            public View getView(int position, View convertView, ViewGroup parent) {
+                TextView textView = (TextView) View
+                        .inflate(AccessibilityEndToEndActivity.this, R.layout.list_view_row, null);
+                textView.setText((String) getItem(position));
+                return textView;
+            }
+
+            public long getItemId(int position) {
+                return position;
+            }
+
+            public Object getItem(int position) {
+                if (position == 0) {
+                    return AccessibilityEndToEndActivity.this.getString(R.string.first_list_item);
+                } else {
+                    return AccessibilityEndToEndActivity.this.getString(R.string.second_list_item);
+                }
+            }
+
+            public int getCount() {
+                return 2;
+            }
+        };
+
+        ListView listView = (ListView) findViewById(R.id.listview);
+        listView.setAdapter(listAdapter);
+    }
+}
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEndToEndTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEndToEndTest.java
new file mode 100644
index 0000000..d8a1be1
--- /dev/null
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEndToEndTest.java
@@ -0,0 +1,438 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.accessibilityservice.cts;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.app.Service;
+import android.app.UiAutomation;
+import android.content.Intent;
+import android.content.res.Configuration;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.accessibility.AccessibilityEvent;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.ListView;
+
+import android.accessibilityservice.cts.R;
+
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * This class performs end-to-end testing of the accessibility feature by
+ * creating an {@link Activity} and poking around so {@link AccessibilityEvent}s
+ * are generated and their correct dispatch verified.
+ */
+public class AccessibilityEndToEndTest extends
+        AccessibilityActivityTestCase<AccessibilityEndToEndActivity> {
+
+    private static final String LOG_TAG = "AccessibilityEndToEndTest";
+
+    /**
+     * Creates a new instance for testing {@link AccessibilityEndToEndActivity}.
+     */
+    public AccessibilityEndToEndTest() {
+        super(AccessibilityEndToEndActivity.class);
+    }
+
+    @MediumTest
+    public void testTypeViewSelectedAccessibilityEvent() throws Throwable {
+        // create and populate the expected event
+        final AccessibilityEvent expected = AccessibilityEvent.obtain();
+        expected.setEventType(AccessibilityEvent.TYPE_VIEW_SELECTED);
+        expected.setClassName(ListView.class.getName());
+        expected.setPackageName(getActivity().getPackageName());
+        expected.getText().add(getActivity().getString(R.string.second_list_item));
+        expected.setItemCount(2);
+        expected.setCurrentItemIndex(1);
+        expected.setEnabled(true);
+        expected.setScrollable(false);
+        expected.setFromIndex(0);
+        expected.setToIndex(1);
+
+        final ListView listView = (ListView) getActivity().findViewById(R.id.listview);
+
+        AccessibilityEvent awaitedEvent =
+            getInstrumentation().getUiAutomation().executeAndWaitForEvent(
+                new Runnable() {
+            @Override
+            public void run() {
+                // trigger the event
+                getActivity().runOnUiThread(new Runnable() {
+                    @Override
+                    public void run() {
+                        listView.setSelection(1);
+                    }
+                });
+            }},
+            new UiAutomation.AccessibilityEventFilter() {
+                // check the received event
+                @Override
+                public boolean accept(AccessibilityEvent event) {
+                    return equalsAccessiblityEvent(event, expected);
+                }
+            },
+            TIMEOUT_ASYNC_PROCESSING);
+        assertNotNull("Did not receive expected event: " + expected, awaitedEvent);
+    }
+
+    @MediumTest
+    public void testTypeViewClickedAccessibilityEvent() throws Throwable {
+        // create and populate the expected event
+        final AccessibilityEvent expected = AccessibilityEvent.obtain();
+        expected.setEventType(AccessibilityEvent.TYPE_VIEW_CLICKED);
+        expected.setClassName(Button.class.getName());
+        expected.setPackageName(getActivity().getPackageName());
+        expected.getText().add(getActivity().getString(R.string.button_title));
+        expected.setEnabled(true);
+
+        final Button button = (Button) getActivity().findViewById(R.id.button);
+
+        AccessibilityEvent awaitedEvent =
+            getInstrumentation().getUiAutomation().executeAndWaitForEvent(
+                new Runnable() {
+            @Override
+            public void run() {
+                // trigger the event
+                getActivity().runOnUiThread(new Runnable() {
+                    @Override
+                    public void run() {
+                        button.performClick();
+                    }
+                });
+            }},
+            new UiAutomation.AccessibilityEventFilter() {
+                // check the received event
+                @Override
+                public boolean accept(AccessibilityEvent event) {
+                    return equalsAccessiblityEvent(event, expected);
+                }
+            },
+            TIMEOUT_ASYNC_PROCESSING);
+        assertNotNull("Did not receive expected event: " + expected, awaitedEvent);
+    }
+
+    @MediumTest
+    public void testTypeViewLongClickedAccessibilityEvent() throws Throwable {
+        // create and populate the expected event
+        final AccessibilityEvent expected = AccessibilityEvent.obtain();
+        expected.setEventType(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED);
+        expected.setClassName(Button.class.getName());
+        expected.setPackageName(getActivity().getPackageName());
+        expected.getText().add(getActivity().getString(R.string.button_title));
+        expected.setEnabled(true);
+
+        final Button button = (Button) getActivity().findViewById(R.id.button);
+
+        AccessibilityEvent awaitedEvent =
+            getInstrumentation().getUiAutomation().executeAndWaitForEvent(
+                new Runnable() {
+            @Override
+            public void run() {
+                // trigger the event
+                getActivity().runOnUiThread(new Runnable() {
+                    @Override
+                    public void run() {
+                        button.performLongClick();
+                    }
+                });
+            }},
+            new UiAutomation.AccessibilityEventFilter() {
+                // check the received event
+                @Override
+                public boolean accept(AccessibilityEvent event) {
+                    return equalsAccessiblityEvent(event, expected);
+                }
+            },
+            TIMEOUT_ASYNC_PROCESSING);
+        assertNotNull("Did not receive expected event: " + expected, awaitedEvent);
+    }
+
+    @MediumTest
+    public void testTypeViewFocusedAccessibilityEvent() throws Throwable {
+        // create and populate the expected event
+        final AccessibilityEvent expected = AccessibilityEvent.obtain();
+        expected.setEventType(AccessibilityEvent.TYPE_VIEW_FOCUSED);
+        expected.setClassName(Button.class.getName());
+        expected.setPackageName(getActivity().getPackageName());
+        expected.getText().add(getActivity().getString(R.string.button_title));
+        expected.setItemCount(3);
+        expected.setCurrentItemIndex(2);
+        expected.setEnabled(true);
+
+        final Button button = (Button) getActivity().findViewById(R.id.button);
+
+        AccessibilityEvent awaitedEvent =
+            getInstrumentation().getUiAutomation().executeAndWaitForEvent(
+                new Runnable() {
+            @Override
+            public void run() {
+                // trigger the event
+                getActivity().runOnUiThread(new Runnable() {
+                    @Override
+                    public void run() {
+                        button.requestFocus();
+                    }
+                });
+            }},
+            new UiAutomation.AccessibilityEventFilter() {
+                // check the received event
+                @Override
+                public boolean accept(AccessibilityEvent event) {
+                    return equalsAccessiblityEvent(event, expected);
+                }
+            },
+            TIMEOUT_ASYNC_PROCESSING);
+        assertNotNull("Did not receive expected event: " + expected, awaitedEvent);
+    }
+
+    @MediumTest
+    public void testTypeViewTextChangedAccessibilityEvent() throws Throwable {
+        // focus the edit text
+        final EditText editText = (EditText) getActivity().findViewById(R.id.edittext);
+
+        AccessibilityEvent awaitedFocusEvent =
+            getInstrumentation().getUiAutomation().executeAndWaitForEvent(
+                new Runnable() {
+            @Override
+            public void run() {
+                // trigger the event
+                getActivity().runOnUiThread(new Runnable() {
+                    @Override
+                    public void run() {
+                        editText.requestFocus();
+                    }
+                });
+            }},
+            new UiAutomation.AccessibilityEventFilter() {
+                // check the received event
+                @Override
+                public boolean accept(AccessibilityEvent event) {
+                    return event.getEventType() == AccessibilityEvent.TYPE_VIEW_FOCUSED;
+                }
+            },
+            TIMEOUT_ASYNC_PROCESSING);
+        assertNotNull("Did not receive expected focuss event.", awaitedFocusEvent);
+
+        final String beforeText = getActivity().getString(R.string.text_input_blah);
+        final String newText = getActivity().getString(R.string.text_input_blah_blah);
+        final String afterText = beforeText.substring(0, 3) + newText;
+
+        // create and populate the expected event
+        final AccessibilityEvent expected = AccessibilityEvent.obtain();
+        expected.setEventType(AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED);
+        expected.setClassName(EditText.class.getName());
+        expected.setPackageName(getActivity().getPackageName());
+        expected.getText().add(afterText);
+        expected.setBeforeText(beforeText);
+        expected.setFromIndex(3);
+        expected.setAddedCount(9);
+        expected.setRemovedCount(1);
+        expected.setEnabled(true);
+
+        AccessibilityEvent awaitedTextChangeEvent =
+            getInstrumentation().getUiAutomation().executeAndWaitForEvent(
+                new Runnable() {
+            @Override
+            public void run() {
+                // trigger the event
+                getActivity().runOnUiThread(new Runnable() {
+                    @Override
+                    public void run() {
+                        editText.getEditableText().replace(3, 4, newText);
+                    }
+                });
+            }},
+            new UiAutomation.AccessibilityEventFilter() {
+                // check the received event
+                @Override
+                public boolean accept(AccessibilityEvent event) {
+                    return equalsAccessiblityEvent(event, expected);
+                }
+            },
+            TIMEOUT_ASYNC_PROCESSING);
+        assertNotNull("Did not receive expected event: " + expected, awaitedTextChangeEvent);
+    }
+
+    @MediumTest
+    public void testTypeWindowStateChangedAccessibilityEvent() throws Throwable {
+        // create and populate the expected event
+        final AccessibilityEvent expected = AccessibilityEvent.obtain();
+        expected.setEventType(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
+        expected.setClassName(AlertDialog.class.getName());
+        expected.setPackageName(getActivity().getPackageName());
+        expected.getText().add(getActivity().getString(R.string.alert_title));
+        expected.getText().add(getActivity().getString(R.string.alert_message));
+        expected.setEnabled(true);
+
+        AccessibilityEvent awaitedEvent =
+            getInstrumentation().getUiAutomation().executeAndWaitForEvent(
+                new Runnable() {
+            @Override
+            public void run() {
+                // trigger the event
+                getActivity().runOnUiThread(new Runnable() {
+                    @Override
+                    public void run() {
+                        (new AlertDialog.Builder(getActivity()).setTitle(R.string.alert_title)
+                                .setMessage(R.string.alert_message)).create().show();
+                    }
+                });
+            }},
+            new UiAutomation.AccessibilityEventFilter() {
+                // check the received event
+                @Override
+                public boolean accept(AccessibilityEvent event) {
+                    return equalsAccessiblityEvent(event, expected);
+                }
+            },
+            TIMEOUT_ASYNC_PROCESSING);
+        assertNotNull("Did not receive expected event: " + expected, awaitedEvent);
+    }
+
+    @MediumTest
+    @SuppressWarnings("deprecation")
+    public void testTypeNotificationStateChangedAccessibilityEvent() throws Throwable {
+        // No notification UI on televisions.
+        if((getActivity().getResources().getConfiguration().uiMode
+                & Configuration.UI_MODE_TYPE_MASK) == Configuration.UI_MODE_TYPE_TELEVISION) {
+            Log.i(LOG_TAG, "Skipping: testTypeNotificationStateChangedAccessibilityEvent" +
+                    " - No notification UI on televisions.");
+            return;
+        }
+
+        String message = getActivity().getString(R.string.notification_message);
+
+        // create the notification to send
+        final int notificationId = 1;
+        final Notification notification = new Notification.Builder(getActivity())
+                .setSmallIcon(android.R.drawable.stat_notify_call_mute)
+                .setContentIntent(PendingIntent.getActivity(getActivity(), 0, new Intent(),
+                        PendingIntent.FLAG_CANCEL_CURRENT))
+                .setTicker(message)
+                .setContentTitle("")
+                .setContentText("")
+                .setPriority(Notification.PRIORITY_MAX)
+                // Mark the notification as "interruptive" by specifying a vibration pattern. This
+                // ensures it's announced properly on watch-type devices.
+                .setVibrate(new long[] {})
+                .build();
+
+        // create and populate the expected event
+        final AccessibilityEvent expected = AccessibilityEvent.obtain();
+        expected.setEventType(AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED);
+        expected.setClassName(Notification.class.getName());
+        expected.setPackageName(getActivity().getPackageName());
+        expected.getText().add(message);
+        expected.setParcelableData(notification);
+
+        AccessibilityEvent awaitedEvent =
+            getInstrumentation().getUiAutomation().executeAndWaitForEvent(
+                new Runnable() {
+            @Override
+            public void run() {
+                // trigger the event
+                getActivity().runOnUiThread(new Runnable() {
+                    @Override
+                    public void run() {
+                        // trigger the event
+                        NotificationManager notificationManager =
+                            (NotificationManager) getActivity().getSystemService(
+                                    Service.NOTIFICATION_SERVICE);
+                        notificationManager.notify(notificationId, notification);
+                        getActivity().finish();
+                    }
+                });
+            }},
+            new UiAutomation.AccessibilityEventFilter() {
+                // check the received event
+                @Override
+                public boolean accept(AccessibilityEvent event) {
+                    return equalsAccessiblityEvent(event, expected);
+                }
+            },
+            TIMEOUT_ASYNC_PROCESSING);
+        assertNotNull("Did not receive expected event: " + expected, awaitedEvent);
+    }
+
+    /**
+     * Compares all properties of the <code>first</code> and the
+     * <code>second</code>.
+     */
+    private boolean equalsAccessiblityEvent(AccessibilityEvent first, AccessibilityEvent second) {
+         return first.getEventType() == second.getEventType()
+            && first.isChecked() == second.isChecked()
+            && first.getCurrentItemIndex() == second.getCurrentItemIndex()
+            && first.isEnabled() == second.isEnabled()
+            && first.getFromIndex() == second.getFromIndex()
+            && first.getItemCount() == second.getItemCount()
+            && first.isPassword() == second.isPassword()
+            && first.getRemovedCount() == second.getRemovedCount()
+            && first.isScrollable()== second.isScrollable()
+            && first.getToIndex() == second.getToIndex()
+            && first.getRecordCount() == second.getRecordCount()
+            && first.getScrollX() == second.getScrollX()
+            && first.getScrollY() == second.getScrollY()
+            && first.getAddedCount() == second.getAddedCount()
+            && TextUtils.equals(first.getBeforeText(), second.getBeforeText())
+            && TextUtils.equals(first.getClassName(), second.getClassName())
+            && TextUtils.equals(first.getContentDescription(), second.getContentDescription())
+            && equalsNotificationAsParcelableData(first, second)
+            && equalsText(first, second);
+    }
+
+    /**
+     * Compares the {@link android.os.Parcelable} data of the
+     * <code>first</code> and <code>second</code>.
+     */
+    private boolean equalsNotificationAsParcelableData(AccessibilityEvent first,
+            AccessibilityEvent second) {
+        Notification firstNotification = (Notification) first.getParcelableData();
+        Notification secondNotification = (Notification) second.getParcelableData();
+        if (firstNotification == null) {
+            return (secondNotification == null);
+        } else if (secondNotification == null) {
+            return false;
+        }
+        return TextUtils.equals(firstNotification.tickerText, secondNotification.tickerText);
+    }
+
+    /**
+     * Compares the text of the <code>first</code> and <code>second</code> text.
+     */
+    private boolean equalsText(AccessibilityEvent first, AccessibilityEvent second) {
+        List<CharSequence> firstText = first.getText();
+        List<CharSequence> secondText = second.getText();
+        if (firstText.size() != secondText.size()) {
+            return false;
+        }
+        Iterator<CharSequence> firstIterator = firstText.iterator();
+        Iterator<CharSequence> secondIterator = secondText.iterator();
+        for (int i = 0; i < firstText.size(); i++) {
+            if (!firstIterator.next().toString().equals(secondIterator.next().toString())) {
+                return false;
+            }
+        }
+        return true;
+    }
+}
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityFocusAndInputFocusSyncActivity.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityFocusAndInputFocusSyncActivity.java
new file mode 100644
index 0000000..62831a4
--- /dev/null
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityFocusAndInputFocusSyncActivity.java
@@ -0,0 +1,35 @@
+/**
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 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.accessibilityservice.cts;
+
+import android.os.Bundle;
+
+import android.accessibilityservice.cts.R;
+
+/**
+ * Activity for testing the accessibility focus APIs exposed to
+ * accessibility services. These APIs allow moving accessibility
+ * focus in the view tree from an AccessiiblityService. Specifically,
+ * this activity is for verifying the the sync between accessibility
+ * and input focus.
+ */
+public class AccessibilityFocusAndInputFocusSyncActivity extends AccessibilityTestActivity {
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.accessibility_focus_and_input_focus_sync_test);
+    }
+}
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityFocusAndInputFocusSyncTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityFocusAndInputFocusSyncTest.java
new file mode 100644
index 0000000..ec420de
--- /dev/null
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityFocusAndInputFocusSyncTest.java
@@ -0,0 +1,229 @@
+/**
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 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.accessibilityservice.cts;
+
+import static android.view.accessibility.AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS;
+import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS;
+
+import android.app.UiAutomation;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityNodeInfo;
+
+import android.accessibilityservice.cts.R;
+
+import java.util.LinkedList;
+import java.util.Queue;
+
+/**
+ * Test cases for testing the accessibility focus APIs exposed to accessibility
+ * services. These APIs allow moving accessibility focus in the view tree from
+ * an AccessiiblityService. Specifically, this activity is for verifying the the
+ * sync between accessibility and input focus.
+ */
+public class AccessibilityFocusAndInputFocusSyncTest
+        extends AccessibilityActivityTestCase<AccessibilityFocusAndInputFocusSyncActivity>{
+
+    public AccessibilityFocusAndInputFocusSyncTest() {
+        super(AccessibilityFocusAndInputFocusSyncActivity.class);
+    }
+
+    @MediumTest
+    public void testFindAccessibilityFocus() throws Exception {
+        // Get the view that has input and accessibility focus.
+        final AccessibilityNodeInfo expected = getInstrumentation().getUiAutomation()
+                .getRootInActiveWindow().findAccessibilityNodeInfosByText(
+                        getString(R.string.firstEditText)).get(0);
+        assertNotNull(expected);
+        assertFalse(expected.isAccessibilityFocused());
+        assertTrue(expected.isFocused());
+
+        getInstrumentation().getUiAutomation().executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                // Perform a focus action and check for success.
+                assertTrue(expected.performAction(ACTION_ACCESSIBILITY_FOCUS));
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return event.getEventType() == AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED;
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Get the second expected node info.
+        AccessibilityNodeInfo received = getInstrumentation().getUiAutomation()
+                .getRootInActiveWindow().findFocus(AccessibilityNodeInfo.FOCUS_ACCESSIBILITY);
+        assertNotNull(received);
+        assertTrue(received.isAccessibilityFocused());
+
+        // Make sure we got the expected focusable.
+        assertEquals(expected, received);
+    }
+
+    @MediumTest
+    public void testInitialStateNoAccessibilityFocus() throws Exception {
+        // Get the root which is only accessibility focused.
+        AccessibilityNodeInfo focused = getInstrumentation().getUiAutomation()
+                .getRootInActiveWindow().findFocus(AccessibilityNodeInfo.FOCUS_ACCESSIBILITY);
+        assertNull(focused);
+    }
+
+    @MediumTest
+    public void testActionAccessibilityFocus() throws Exception {
+        // Get the root linear layout info.
+        final AccessibilityNodeInfo rootLinearLayout = getInstrumentation().getUiAutomation()
+                .getRootInActiveWindow().findAccessibilityNodeInfosByText(
+                        getString(R.string.rootLinearLayout)).get(0);
+        assertNotNull(rootLinearLayout);
+        assertFalse(rootLinearLayout.isAccessibilityFocused());
+
+        getInstrumentation().getUiAutomation().executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                // Perform a focus action and check for success.
+                assertTrue(rootLinearLayout.performAction(ACTION_ACCESSIBILITY_FOCUS));
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return event.getEventType() == AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED;
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Get the node info again.
+        rootLinearLayout.refresh();
+
+        // Check if the node info is focused.
+        assertTrue(rootLinearLayout.isAccessibilityFocused());
+    }
+
+    @MediumTest
+    public void testActionClearAccessibilityFocus() throws Exception {
+        // Get the root linear layout info.
+        final AccessibilityNodeInfo rootLinearLayout = getInstrumentation().getUiAutomation()
+                .getRootInActiveWindow().findAccessibilityNodeInfosByText(
+                        getString(R.string.rootLinearLayout)).get(0);
+        assertNotNull(rootLinearLayout);
+
+        getInstrumentation().getUiAutomation().executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                // Perform a focus action and check for success.
+                assertTrue(rootLinearLayout.performAction(ACTION_ACCESSIBILITY_FOCUS));
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return event.getEventType() == AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED;
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Refresh the node info.
+        rootLinearLayout.refresh();
+
+        // Check if the node info is focused.
+        assertTrue(rootLinearLayout.isAccessibilityFocused());
+
+        getInstrumentation().getUiAutomation().executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                // Perform a clear focus action and check for success.
+                assertTrue(rootLinearLayout.performAction(ACTION_CLEAR_ACCESSIBILITY_FOCUS));
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return event.getEventType()
+                        == AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED;
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Refresh the node info.
+        rootLinearLayout.refresh();
+
+        // Check if the node info is not focused.
+        assertFalse(rootLinearLayout.isAccessibilityFocused());
+    }
+
+    @MediumTest
+    public void testOnlyOneNodeHasAccessibilityFocus() throws Exception {
+        // Get the first not focused edit text.
+        final AccessibilityNodeInfo firstEditText = getInstrumentation().getUiAutomation()
+                .getRootInActiveWindow().findAccessibilityNodeInfosByText(
+                        getString(R.string.firstEditText)).get(0);
+        assertNotNull(firstEditText);
+        assertTrue(firstEditText.isFocusable());
+        assertTrue(firstEditText.isFocused());
+        assertFalse(firstEditText.isAccessibilityFocused());
+
+        getInstrumentation().getUiAutomation().executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                // Perform a set focus action and check for success.
+                assertTrue(firstEditText.performAction(ACTION_ACCESSIBILITY_FOCUS));
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return event.getEventType() == AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED;
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Get the second not focused edit text.
+        final AccessibilityNodeInfo secondEditText = getInstrumentation().getUiAutomation()
+                .getRootInActiveWindow().findAccessibilityNodeInfosByText(
+                        getString(R.string.secondEditText)).get(0);
+        assertNotNull(secondEditText);
+        assertTrue(secondEditText.isFocusable());
+        assertFalse(secondEditText.isFocused());
+        assertFalse(secondEditText.isAccessibilityFocused());
+
+        getInstrumentation().getUiAutomation().executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                // Perform a set focus action and check for success.
+                assertTrue(secondEditText.performAction(ACTION_ACCESSIBILITY_FOCUS));
+                
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return event.getEventType() == AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED;
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Get the node info again.
+        secondEditText.refresh();
+
+        // Make sure no other node has accessibility focus.
+        AccessibilityNodeInfo root = getInstrumentation().getUiAutomation().getRootInActiveWindow();
+        Queue<AccessibilityNodeInfo> workQueue = new LinkedList<AccessibilityNodeInfo>();
+        workQueue.add(root);
+        while (!workQueue.isEmpty()) {
+            AccessibilityNodeInfo current = workQueue.poll();
+            if (current.isAccessibilityFocused() && !current.equals(secondEditText)) {
+                fail();
+            }
+            final int childCount = current.getChildCount();
+            for (int i = 0; i < childCount; i++) {
+                AccessibilityNodeInfo child = current.getChild(i);
+                if (child != null) {
+                    workQueue.offer(child);
+                }
+            }
+        }
+    }
+}
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGestureDispatchTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGestureDispatchTest.java
new file mode 100644
index 0000000..7da7d37
--- /dev/null
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGestureDispatchTest.java
@@ -0,0 +1,529 @@
+/**
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 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.accessibilityservice.cts;
+
+import android.accessibilityservice.AccessibilityService;
+import android.accessibilityservice.GestureDescription;
+import android.graphics.Matrix;
+import android.graphics.Path;
+import android.graphics.Rect;
+import android.os.Bundle;
+import android.os.SystemClock;
+import android.test.ActivityInstrumentationTestCase2;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewConfiguration;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * Verify that gestures dispatched from an accessibility service show up in the current UI
+ */
+public class AccessibilityGestureDispatchTest extends
+        ActivityInstrumentationTestCase2<AccessibilityGestureDispatchTest.GestureDispatchActivity> {
+    private static final int GESTURE_COMPLETION_TIMEOUT = 5000; // millis
+    private static final int MOTION_EVENT_TIMEOUT = 1000; // millis
+
+    final List<MotionEvent> mMotionEvents = new ArrayList<>();
+    StubGestureAccessibilityService mService;
+    MyTouchListener mMyTouchListener = new MyTouchListener();
+    MyGestureCallback mCallback;
+    TextView mFullScreenTextView;
+    Rect mViewBounds = new Rect();
+    boolean mGotUpEvent;
+
+    public AccessibilityGestureDispatchTest() {
+        super(GestureDispatchActivity.class);
+    }
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+
+        mFullScreenTextView =
+                (TextView) getActivity().findViewById(R.id.full_screen_text_view);
+        getInstrumentation().runOnMainSync(() -> {
+            mFullScreenTextView.getGlobalVisibleRect(mViewBounds);
+            mFullScreenTextView.setOnTouchListener(mMyTouchListener);
+        });
+
+        mService = StubGestureAccessibilityService.enableSelf(this);
+
+        mMotionEvents.clear();
+        mCallback = new MyGestureCallback();
+        mGotUpEvent = false;
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        mService.runOnServiceSync(() -> mService.disableSelf());
+
+        super.tearDown();
+    }
+
+    public void testClickAt_producesDownThenUp() throws InterruptedException {
+        final int clickXInsideView = 10;
+        final int clickYInsideView = 20;
+        int clickX = clickXInsideView + mViewBounds.left;
+        int clickY = clickYInsideView + mViewBounds.top;
+        GestureDescription click = createClick(clickX, clickY);
+        mService.runOnServiceSync(() -> mService.doDispatchGesture(click, mCallback, null));
+        mCallback.assertGestureCompletes(GESTURE_COMPLETION_TIMEOUT);
+        waitForMotionEvents(3);
+
+        assertEquals(3, mMotionEvents.size());
+        MotionEvent clickDown = mMotionEvents.get(0);
+        MotionEvent clickMove = mMotionEvents.get(1);
+        MotionEvent clickUp = mMotionEvents.get(2);
+
+        assertEquals(MotionEvent.ACTION_DOWN, clickDown.getActionMasked());
+        assertEquals(0, clickDown.getActionIndex());
+        assertEquals(0, clickDown.getDeviceId());
+        assertEquals(0, clickDown.getEdgeFlags());
+        assertEquals(1F, clickDown.getXPrecision());
+        assertEquals(1F, clickDown.getYPrecision());
+        assertEquals(1, clickDown.getPointerCount());
+        assertEquals(1F, clickDown.getPressure());
+        assertEquals((float) clickXInsideView, clickDown.getX());
+        assertEquals((float) clickYInsideView, clickDown.getY());
+        assertEquals(clickDown.getDownTime(), clickDown.getEventTime());
+
+        assertEquals(MotionEvent.ACTION_MOVE, clickMove.getActionMasked());
+        assertEquals(clickDown.getDownTime(), clickMove.getDownTime());
+        assertEquals(ViewConfiguration.getTapTimeout(),
+                clickMove.getEventTime() - clickMove.getDownTime());
+        assertEquals(0, clickMove.getActionIndex());
+        assertEquals(1, clickMove.getPointerCount());
+        assertEquals((float) clickXInsideView + 1, clickMove.getX());
+        assertEquals((float) clickYInsideView, clickMove.getY());
+        assertEquals(clickDown.getPointerId(0),
+                clickMove.getPointerId(0));
+
+        assertEquals(MotionEvent.ACTION_UP, clickUp.getActionMasked());
+        assertEquals(clickDown.getDownTime(), clickUp.getDownTime());
+        assertEquals(clickMove.getEventTime(), clickUp.getEventTime());
+        assertTrue(clickDown.getEventTime() + ViewConfiguration.getLongPressTimeout()
+                > clickUp.getEventTime());
+        assertEquals((float) clickXInsideView + 1, clickUp.getX());
+        assertEquals((float) clickYInsideView, clickUp.getY());
+    }
+
+    public void testLongClickAt_producesEventsWithLongClickTiming() throws InterruptedException {
+        final int clickXInsideView = 10;
+        final int clickYInsideView = 20;
+        int clickX = clickXInsideView + mViewBounds.left;
+        int clickY = clickYInsideView + mViewBounds.top;
+        GestureDescription longClick = createLongClick(clickX, clickY);
+        mService.runOnServiceSync(() -> mService.doDispatchGesture(longClick, mCallback, null));
+        mCallback.assertGestureCompletes(
+                ViewConfiguration.getLongPressTimeout() + GESTURE_COMPLETION_TIMEOUT);
+
+        waitForMotionEvents(3);
+        MotionEvent clickDown = mMotionEvents.get(0);
+        MotionEvent clickMove = mMotionEvents.get(1);
+        MotionEvent clickUp = mMotionEvents.get(2);
+
+        assertEquals(MotionEvent.ACTION_DOWN, clickDown.getActionMasked());
+
+        assertEquals((float) clickXInsideView, clickDown.getX());
+        assertEquals((float) clickYInsideView, clickDown.getY());
+
+        assertEquals(MotionEvent.ACTION_MOVE, clickMove.getActionMasked());
+        assertEquals(clickDown.getDownTime(), clickMove.getDownTime());
+        assertEquals((float) clickXInsideView + 1, clickMove.getX());
+        assertEquals((float) clickYInsideView, clickMove.getY());
+        assertEquals(clickDown.getPointerId(0), clickMove.getPointerId(0));
+
+        assertEquals(MotionEvent.ACTION_UP, clickUp.getActionMasked());
+        assertTrue(clickDown.getEventTime() + ViewConfiguration.getLongPressTimeout()
+                <= clickUp.getEventTime());
+        assertEquals(clickDown.getDownTime(), clickUp.getDownTime());
+        assertEquals((float) clickXInsideView + 1, clickUp.getX());
+        assertEquals((float) clickYInsideView, clickUp.getY());
+    }
+
+    public void testSwipe_shouldContainPointsInALine() throws InterruptedException {
+        int startXInsideView = 10;
+        int startYInsideView = 20;
+        int endXInsideView = 20;
+        int endYInsideView = 40;
+        int startX = startXInsideView + mViewBounds.left;
+        int startY = startYInsideView + mViewBounds.top;
+        int endX = endXInsideView + mViewBounds.left;
+        int endY = endYInsideView + mViewBounds.top;
+        int gestureTime = 500;
+        float swipeTolerance = 2.0f;
+
+        GestureDescription swipe = createSwipe(startX, startY, endX, endY, gestureTime);
+        mService.runOnServiceSync(() -> mService.doDispatchGesture(swipe, mCallback, null));
+        mCallback.assertGestureCompletes(gestureTime + GESTURE_COMPLETION_TIMEOUT);
+        waitForUpEvent();
+        int numEvents = mMotionEvents.size();
+
+        MotionEvent downEvent = mMotionEvents.get(0);
+        assertEquals(MotionEvent.ACTION_DOWN, downEvent.getActionMasked());
+        assertEquals(startXInsideView, (int) downEvent.getX());
+        assertEquals(startYInsideView, (int) downEvent.getY());
+
+        MotionEvent upEvent = mMotionEvents.get(numEvents - 1);
+        assertEquals(MotionEvent.ACTION_UP, upEvent.getActionMasked());
+        assertEquals(endXInsideView, (int) upEvent.getX());
+        assertEquals(endYInsideView, (int) upEvent.getY());
+        assertEquals(gestureTime, upEvent.getEventTime() - downEvent.getEventTime());
+
+        long lastEventTime = downEvent.getEventTime();
+        for (int i = 1; i < numEvents - 1; i++) {
+            MotionEvent moveEvent = mMotionEvents.get(i);
+            assertEquals(MotionEvent.ACTION_MOVE, moveEvent.getActionMasked());
+            assertTrue(moveEvent.getEventTime() >= lastEventTime);
+            float fractionOfSwipe =
+                    ((float) (moveEvent.getEventTime() - downEvent.getEventTime())) / gestureTime;
+            float fractionX = ((float) (endXInsideView - startXInsideView)) * fractionOfSwipe;
+            float fractionY = ((float) (endYInsideView - startYInsideView)) * fractionOfSwipe;
+            assertEquals(startXInsideView + fractionX, moveEvent.getX(), swipeTolerance);
+            assertEquals(startYInsideView + fractionY, moveEvent.getY(), swipeTolerance);
+            lastEventTime = moveEvent.getEventTime();
+        }
+    }
+
+    public void testSlowSwipe_shouldNotContainMovesForTinyMovement() throws InterruptedException {
+        int startXInsideView = 10;
+        int startYInsideView = 20;
+        int endXInsideView = 11;
+        int endYInsideView = 22;
+        int startX = startXInsideView + mViewBounds.left;
+        int startY = startYInsideView + mViewBounds.top;
+        int endX = endXInsideView + mViewBounds.left;
+        int endY = endYInsideView + mViewBounds.top;
+        int gestureTime = 1000;
+
+        GestureDescription swipe = createSwipe(startX, startY, endX, endY, gestureTime);
+        mService.runOnServiceSync(() -> mService.doDispatchGesture(swipe, mCallback, null));
+        mCallback.assertGestureCompletes(gestureTime + GESTURE_COMPLETION_TIMEOUT);
+        waitForUpEvent();
+
+        assertEquals(5, mMotionEvents.size());
+
+        assertEquals(MotionEvent.ACTION_DOWN, mMotionEvents.get(0).getActionMasked());
+        assertEquals(MotionEvent.ACTION_MOVE, mMotionEvents.get(1).getActionMasked());
+        assertEquals(MotionEvent.ACTION_MOVE, mMotionEvents.get(2).getActionMasked());
+        assertEquals(MotionEvent.ACTION_MOVE, mMotionEvents.get(3).getActionMasked());
+        assertEquals(MotionEvent.ACTION_UP, mMotionEvents.get(4).getActionMasked());
+
+        assertEquals(startXInsideView, (int) mMotionEvents.get(0).getX());
+        assertEquals(startXInsideView, (int) mMotionEvents.get(1).getX());
+        assertEquals(startXInsideView + 1, (int) mMotionEvents.get(2).getX());
+        assertEquals(startXInsideView + 1, (int) mMotionEvents.get(3).getX());
+        assertEquals(startXInsideView + 1, (int) mMotionEvents.get(4).getX());
+
+        assertEquals(startYInsideView, (int) mMotionEvents.get(0).getY());
+        assertEquals(startYInsideView + 1, (int) mMotionEvents.get(1).getY());
+        assertEquals(startYInsideView + 1, (int) mMotionEvents.get(2).getY());
+        assertEquals(startYInsideView + 2, (int) mMotionEvents.get(3).getY());
+        assertEquals(startYInsideView + 2, (int) mMotionEvents.get(4).getY());
+    }
+
+    public void testAngledPinch_looksReasonable() throws InterruptedException {
+        int centerXInsideView = 50;
+        int centerYInsideView = 60;
+        int centerX = centerXInsideView + mViewBounds.left;
+        int centerY = centerYInsideView + mViewBounds.top;
+        int startSpacing = 100;
+        int endSpacing = 50;
+        int gestureTime = 500;
+        float pinchTolerance = 2.0f;
+
+        GestureDescription pinch = createPinch(centerX, centerY, startSpacing,
+                endSpacing, 45.0F, gestureTime);
+        mService.runOnServiceSync(() -> mService.doDispatchGesture(pinch, mCallback, null));
+        mCallback.assertGestureCompletes(gestureTime + GESTURE_COMPLETION_TIMEOUT);
+        waitForUpEvent();
+        int numEvents = mMotionEvents.size();
+
+        // First two events are the initial down and the pointer down
+        assertEquals(MotionEvent.ACTION_DOWN, mMotionEvents.get(0).getActionMasked());
+        assertEquals(MotionEvent.ACTION_POINTER_DOWN, mMotionEvents.get(1).getActionMasked());
+
+        // The second event must have two pointers at the initial spacing along a 45 degree angle
+        MotionEvent firstEventWithTwoPointers = mMotionEvents.get(1);
+        assertEquals(2, firstEventWithTwoPointers.getPointerCount());
+        MotionEvent.PointerCoords coords0 = new MotionEvent.PointerCoords();
+        MotionEvent.PointerCoords coords1 = new MotionEvent.PointerCoords();
+        firstEventWithTwoPointers.getPointerCoords(0, coords0);
+        firstEventWithTwoPointers.getPointerCoords(1, coords1);
+        // Verify center point
+        assertEquals((float) centerXInsideView, (coords0.x + coords1.x) / 2, pinchTolerance);
+        assertEquals((float) centerYInsideView, (coords0.y + coords1.y) / 2, pinchTolerance);
+        // Verify angle
+        assertEquals(coords0.x - centerXInsideView, coords0.y - centerYInsideView, pinchTolerance);
+        assertEquals(coords1.x - centerXInsideView, coords1.y - centerYInsideView, pinchTolerance);
+        // Verify spacing
+        assertEquals(startSpacing, distance(coords0, coords1), pinchTolerance);
+
+        // The last two events are the pointer up and the final up
+        assertEquals(MotionEvent.ACTION_UP, mMotionEvents.get(numEvents - 1).getActionMasked());
+
+        MotionEvent lastEventWithTwoPointers = mMotionEvents.get(numEvents - 2);
+        assertEquals(MotionEvent.ACTION_POINTER_UP, lastEventWithTwoPointers.getActionMasked());
+        lastEventWithTwoPointers.getPointerCoords(0, coords0);
+        lastEventWithTwoPointers.getPointerCoords(1, coords1);
+        // Verify center point
+        assertEquals((float) centerXInsideView, (coords0.x + coords1.x) / 2, pinchTolerance);
+        assertEquals((float) centerYInsideView, (coords0.y + coords1.y) / 2, pinchTolerance);
+        // Verify angle
+        assertEquals(coords0.x - centerXInsideView, coords0.y - centerYInsideView, pinchTolerance);
+        assertEquals(coords1.x - centerXInsideView, coords1.y - centerYInsideView, pinchTolerance);
+        // Verify spacing
+        assertEquals(endSpacing, distance(coords0, coords1), pinchTolerance);
+
+        float lastSpacing = startSpacing;
+        for (int i = 2; i < numEvents - 2; i++) {
+            MotionEvent eventInMiddle = mMotionEvents.get(i);
+            assertEquals(MotionEvent.ACTION_MOVE, eventInMiddle.getActionMasked());
+            eventInMiddle.getPointerCoords(0, coords0);
+            eventInMiddle.getPointerCoords(1, coords1);
+            // Verify center point
+            assertEquals((float) centerXInsideView, (coords0.x + coords1.x) / 2, pinchTolerance);
+            assertEquals((float) centerYInsideView, (coords0.y + coords1.y) / 2, pinchTolerance);
+            // Verify angle
+            assertEquals(coords0.x - centerXInsideView, coords0.y - centerYInsideView,
+                    pinchTolerance);
+            assertEquals(coords1.x - centerXInsideView, coords1.y - centerYInsideView,
+                    pinchTolerance);
+            float spacing = distance(coords0, coords1);
+            assertTrue(spacing <= lastSpacing + pinchTolerance);
+            assertTrue(spacing >= endSpacing - pinchTolerance);
+            lastSpacing = spacing;
+        }
+    }
+
+    public void testClickWhenMagnified_matchesActualTouch() throws InterruptedException {
+        final int clickXInsideView = 10;
+        final int clickYInsideView = 20;
+        int clickX = clickXInsideView + mViewBounds.left;
+        int clickY = clickYInsideView + mViewBounds.top;
+        final float TOUCH_TOLERANCE = 2.0f;
+
+        StubMagnificationAccessibilityService magnificationService =
+                StubMagnificationAccessibilityService.enableSelf(this);
+        android.accessibilityservice.AccessibilityService.MagnificationController
+                magnificationController = magnificationService.getMagnificationController();
+        try {
+            // Magnify screen by 2x from upper left corner
+            final AtomicBoolean setScale = new AtomicBoolean();
+            final AtomicBoolean setCenter = new AtomicBoolean();
+            final float magnificationFactor = 2.0f;
+            magnificationService.runOnServiceSync(() -> {
+                        setScale.set(magnificationController.setScale(magnificationFactor, false));
+                        setCenter.set(magnificationController.setCenter(0, 0, false));
+                    });
+            assertTrue("Failed to set scale", setScale.get());
+            assertTrue("Failed to set center", setCenter.get());
+
+            GestureDescription click = createClick((int) (clickX * magnificationFactor),
+                    (int) (clickY * magnificationFactor));
+            mService.runOnServiceSync(() -> mService.doDispatchGesture(click, mCallback, null));
+            mCallback.assertGestureCompletes(GESTURE_COMPLETION_TIMEOUT);
+            waitForMotionEvents(3);
+        } finally {
+            // Reset magnification
+            final AtomicBoolean result = new AtomicBoolean();
+            magnificationService.runOnServiceSync(() ->
+                    result.set(magnificationController.reset(false)));
+            magnificationService.runOnServiceSync(() -> magnificationService.disableSelf());
+            assertTrue("Failed to reset", result.get());
+        }
+
+        assertEquals(3, mMotionEvents.size());
+        MotionEvent clickDown = mMotionEvents.get(0);
+        MotionEvent clickMove = mMotionEvents.get(1);
+        MotionEvent clickUp = mMotionEvents.get(2);
+
+        assertEquals(MotionEvent.ACTION_DOWN, clickDown.getActionMasked());
+        assertEquals((float) clickXInsideView, clickDown.getX(), TOUCH_TOLERANCE);
+        assertEquals((float) clickYInsideView, clickDown.getY(), TOUCH_TOLERANCE);
+        assertEquals(clickDown.getDownTime(), clickDown.getEventTime());
+
+        assertEquals(MotionEvent.ACTION_MOVE, clickMove.getActionMasked());
+        assertEquals((float) clickXInsideView + 1, clickMove.getX(), TOUCH_TOLERANCE);
+        assertEquals((float) clickYInsideView, clickMove.getY(), TOUCH_TOLERANCE);
+
+        assertEquals(MotionEvent.ACTION_UP, clickUp.getActionMasked());
+        assertEquals((float) clickXInsideView + 1, clickUp.getX(), TOUCH_TOLERANCE);
+        assertEquals((float) clickYInsideView, clickUp.getY(), TOUCH_TOLERANCE);
+    }
+
+
+    public static class GestureDispatchActivity extends AccessibilityTestActivity {
+        public GestureDispatchActivity() {
+            super();
+        }
+
+        @Override
+        public void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            setContentView(R.layout.full_screen_frame_layout);
+        }
+    }
+
+    public static class MyGestureCallback extends AccessibilityService.GestureResultCallback {
+        private boolean mCompleted;
+        private boolean mCancelled;
+
+        @Override
+        public synchronized void onCompleted(GestureDescription gestureDescription) {
+            mCompleted = true;
+            notifyAll();
+        }
+
+        @Override
+        public synchronized void onCancelled(GestureDescription gestureDescription) {
+            mCancelled = true;
+            notifyAll();
+        }
+
+        public synchronized void assertGestureCompletes(long timeout) {
+            if (mCompleted) {
+                return;
+            }
+            try {
+                wait(timeout);
+            } catch (InterruptedException e) {
+                throw new RuntimeException(e);
+            }
+            assertTrue("Gesture did not complete.", mCompleted);
+        }
+    }
+
+    private void waitForMotionEvents(int numEventsExpected) throws InterruptedException {
+        synchronized (mMotionEvents) {
+            long endMillis = SystemClock.uptimeMillis() + MOTION_EVENT_TIMEOUT;
+            while ((mMotionEvents.size() < numEventsExpected)
+                    && (SystemClock.uptimeMillis() < endMillis)) {
+                mMotionEvents.wait(endMillis - SystemClock.uptimeMillis());
+            }
+        }
+    }
+
+    private void waitForUpEvent() throws InterruptedException {
+        synchronized (mMotionEvents) {
+            long endMillis = SystemClock.uptimeMillis() + MOTION_EVENT_TIMEOUT;
+            while (!mGotUpEvent && (SystemClock.uptimeMillis() < endMillis)) {
+                mMotionEvents.wait(endMillis - SystemClock.uptimeMillis());
+            }
+        }
+    }
+
+    private float distance(MotionEvent.PointerCoords point1, MotionEvent.PointerCoords point2) {
+        return (float) Math.hypot((double) (point1.x - point2.x), (double) (point1.y - point2.y));
+    }
+
+    private class MyTouchListener implements View.OnTouchListener {
+        @Override
+        public boolean onTouch(View view, MotionEvent motionEvent) {
+            synchronized (mMotionEvents) {
+                if (motionEvent.getActionMasked() == MotionEvent.ACTION_UP) {
+                    mGotUpEvent = true;
+                }
+                mMotionEvents.add(MotionEvent.obtain(motionEvent));
+                mMotionEvents.notifyAll();
+                return true;
+            }
+        }
+    }
+
+    private GestureDescription createClick(int x, int y) {
+        Path clickPath = new Path();
+        clickPath.moveTo(x, y);
+        clickPath.lineTo(x + 1, y);
+        GestureDescription.StrokeDescription clickStroke =
+                new GestureDescription.StrokeDescription(clickPath, 0, ViewConfiguration.getTapTimeout());
+        GestureDescription.Builder clickBuilder = new GestureDescription.Builder();
+        clickBuilder.addStroke(clickStroke);
+        return clickBuilder.build();
+    }
+
+    private GestureDescription createLongClick(int x, int y) {
+        Path clickPath = new Path();
+        clickPath.moveTo(x, y);
+        clickPath.lineTo(x + 1, y);
+        int longPressTime = ViewConfiguration.getLongPressTimeout();
+
+        GestureDescription.StrokeDescription longClickStroke =
+                new GestureDescription.StrokeDescription(clickPath, 0, longPressTime + (longPressTime / 2));
+        GestureDescription.Builder longClickBuilder = new GestureDescription.Builder();
+        longClickBuilder.addStroke(longClickStroke);
+        return longClickBuilder.build();
+    }
+
+    private GestureDescription createSwipe(
+            int startX, int startY, int endX, int endY, long duration) {
+        Path swipePath = new Path();
+        swipePath.moveTo(startX, startY);
+        swipePath.lineTo(endX, endY);
+
+        GestureDescription.StrokeDescription swipeStroke = new GestureDescription.StrokeDescription(swipePath, 0, duration);
+        GestureDescription.Builder swipeBuilder = new GestureDescription.Builder();
+        swipeBuilder.addStroke(swipeStroke);
+        return swipeBuilder.build();
+    }
+
+    private GestureDescription createPinch(int centerX, int centerY, int startSpacing,
+            int endSpacing, float orientation, long duration) {
+        if ((startSpacing < 0) || (endSpacing < 0)) {
+            throw new IllegalArgumentException("Pinch spacing cannot be negative");
+        }
+        float[] startPoint1 = new float[2];
+        float[] endPoint1 = new float[2];
+        float[] startPoint2 = new float[2];
+        float[] endPoint2 = new float[2];
+
+        /* Build points for a horizontal gesture centered at the origin */
+        startPoint1[0] = startSpacing / 2;
+        startPoint1[1] = 0;
+        endPoint1[0] = endSpacing / 2;
+        endPoint1[1] = 0;
+        startPoint2[0] = -startSpacing / 2;
+        startPoint2[1] = 0;
+        endPoint2[0] = -endSpacing / 2;
+        endPoint2[1] = 0;
+
+        /* Rotate and translate the points */
+        Matrix matrix = new Matrix();
+        matrix.setRotate(orientation);
+        matrix.postTranslate(centerX, centerY);
+        matrix.mapPoints(startPoint1);
+        matrix.mapPoints(endPoint1);
+        matrix.mapPoints(startPoint2);
+        matrix.mapPoints(endPoint2);
+
+        Path path1 = new Path();
+        path1.moveTo(startPoint1[0], startPoint1[1]);
+        path1.lineTo(endPoint1[0], endPoint1[1]);
+        Path path2 = new Path();
+        path2.moveTo(startPoint2[0], startPoint2[1]);
+        path2.lineTo(endPoint2[0], endPoint2[1]);
+
+        GestureDescription.StrokeDescription path1Stroke = new GestureDescription.StrokeDescription(path1, 0, duration);
+        GestureDescription.StrokeDescription path2Stroke = new GestureDescription.StrokeDescription(path2, 0, duration);
+        GestureDescription.Builder swipeBuilder = new GestureDescription.Builder();
+        swipeBuilder.addStroke(path1Stroke);
+        swipeBuilder.addStroke(path2Stroke);
+        return swipeBuilder.build();
+    }
+}
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityMagnificationTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityMagnificationTest.java
new file mode 100644
index 0000000..c021922
--- /dev/null
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityMagnificationTest.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.accessibilityservice.cts;
+
+import android.accessibilityservice.AccessibilityService.MagnificationController;
+import android.accessibilityservice.AccessibilityService.MagnificationController.OnMagnificationChangedListener;
+import android.accessibilityservice.AccessibilityServiceInfo;
+import android.content.res.Resources;
+import android.graphics.Region;
+import android.test.InstrumentationTestCase;
+import android.util.DisplayMetrics;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import static org.mockito.Mockito.*;
+
+/**
+ * Class for testing {@link AccessibilityServiceInfo}.
+ */
+public class AccessibilityMagnificationTest extends InstrumentationTestCase {
+
+    /** Maximum timeout when waiting for a magnification callback. */
+    public static final int LISTENER_TIMEOUT_MILLIS = 500;
+
+    private StubMagnificationAccessibilityService mService;
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+
+        mService = StubMagnificationAccessibilityService.enableSelf(this);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        mService.runOnServiceSync(() -> mService.disableSelf());
+        mService = null;
+
+        super.tearDown();
+    }
+
+    public void testSetScale() {
+        final MagnificationController controller = mService.getMagnificationController();
+        final float scale = 2.0f;
+        final AtomicBoolean result = new AtomicBoolean();
+
+        mService.runOnServiceSync(() -> result.set(controller.setScale(scale, false)));
+
+        assertTrue("Failed to set scale", result.get());
+        assertEquals("Failed to apply scale", scale, controller.getScale());
+
+        mService.runOnServiceSync(() -> result.set(controller.reset(false)));
+
+        assertTrue("Failed to reset", result.get());
+        assertEquals("Failed to apply reset", 1.0f, controller.getScale());
+    }
+
+    public void testSetScaleAndCenter() {
+        final MagnificationController controller = mService.getMagnificationController();
+        final Resources res = getInstrumentation().getTargetContext().getResources();
+        final DisplayMetrics metrics = res.getDisplayMetrics();
+        final float scale = 2.0f;
+        final float x = metrics.widthPixels / 2.0f;
+        final float y = metrics.heightPixels / 2.0f;
+        final AtomicBoolean setScale = new AtomicBoolean();
+        final AtomicBoolean setCenter = new AtomicBoolean();
+        final AtomicBoolean result = new AtomicBoolean();
+
+        mService.runOnServiceSync(() -> {
+            setScale.set(controller.setScale(scale, false));
+            setCenter.set(controller.setCenter(x, y, false));
+        });
+
+        assertTrue("Failed to set scale", setScale.get());
+        assertEquals("Failed to apply scale", scale, controller.getScale());
+
+        assertTrue("Failed to set center", setCenter.get());
+        assertEquals("Failed to apply center X", x, controller.getCenterX());
+        assertEquals("Failed to apply center Y", y, controller.getCenterY());
+
+        mService.runOnServiceSync(() -> result.set(controller.reset(false)));
+
+        assertTrue("Failed to reset", result.get());
+        assertEquals("Failed to apply reset", 1.0f, controller.getScale());
+    }
+
+    public void testListener() {
+        final MagnificationController controller = mService.getMagnificationController();
+        final OnMagnificationChangedListener listener = mock(OnMagnificationChangedListener.class);
+        controller.addListener(listener);
+
+        try {
+            final float scale = 2.0f;
+            final AtomicBoolean result = new AtomicBoolean();
+
+            mService.runOnServiceSync(() -> result.set(controller.setScale(scale, false)));
+
+            assertTrue("Failed to set scale", result.get());
+            verify(listener, timeout(LISTENER_TIMEOUT_MILLIS).atLeastOnce()).onMagnificationChanged(
+                    eq(controller), any(Region.class), eq(scale), anyFloat(), anyFloat());
+
+            mService.runOnServiceSync(() -> result.set(controller.reset(false)));
+
+            assertTrue("Failed to reset", result.get());
+            verify(listener, timeout(LISTENER_TIMEOUT_MILLIS).atLeastOnce()).onMagnificationChanged(
+                    eq(controller), any(Region.class), eq(1.0f), anyFloat(), anyFloat());
+        } finally {
+            controller.removeListener(listener);
+        }
+    }
+}
diff --git a/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityServiceInfoTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityServiceInfoTest.java
similarity index 100%
rename from tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityServiceInfoTest.java
rename to tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityServiceInfoTest.java
diff --git a/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilitySettingsTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilitySettingsTest.java
similarity index 100%
rename from tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilitySettingsTest.java
rename to tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilitySettingsTest.java
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilitySoftKeyboardModesTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilitySoftKeyboardModesTest.java
new file mode 100644
index 0000000..b782216e
--- /dev/null
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilitySoftKeyboardModesTest.java
@@ -0,0 +1,242 @@
+/**
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 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.accessibilityservice.cts;
+
+import android.accessibilityservice.AccessibilityServiceInfo;
+import android.accessibilityservice.AccessibilityService.SoftKeyboardController;
+import android.app.UiAutomation;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.os.Bundle;
+import android.os.ParcelFileDescriptor;
+import android.os.SystemClock;
+import android.provider.Settings;
+import android.test.ActivityInstrumentationTestCase2;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityManager;
+
+import android.accessibilityservice.cts.R;
+
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+import java.util.List;
+import java.util.concurrent.TimeoutException;
+
+/**
+ * Test cases for testing the accessibility APIs for interacting with the soft keyboard show mode.
+ */
+public class AccessibilitySoftKeyboardModesTest extends ActivityInstrumentationTestCase2
+        <AccessibilitySoftKeyboardModesTest.SoftKeyboardModesActivity> {
+
+    private static final long TIMEOUT_PROPAGATE_SETTING = 5000;
+
+    /**
+     * Timeout required for pending Binder calls or event processing to
+     * complete.
+     */
+    private static final long TIMEOUT_ASYNC_PROCESSING = 5000;
+
+    /**
+     * The timeout since the last accessibility event to consider the device idle.
+     */
+    private static final long TIMEOUT_ACCESSIBILITY_STATE_IDLE = 500;
+
+    private static final int SHOW_MODE_AUTO = 0;
+    private static final int SHOW_MODE_HIDDEN = 1;
+
+    private int mLastCallbackValue;
+
+    private InstrumentedAccessibilityService mService;
+    private SoftKeyboardController mKeyboardController;
+    private UiAutomation mUiAutomation;
+
+    private Object mLock = new Object();
+
+    public AccessibilitySoftKeyboardModesTest() {
+        super(SoftKeyboardModesActivity.class);
+    }
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+
+        // If we don't call getActivity(), we get an empty list when requesting the number of
+        // windows on screen.
+        getActivity();
+
+        mService = InstrumentedAccessibilityService.enableService(
+                this, InstrumentedAccessibilityService.class);
+        mKeyboardController = mService.getSoftKeyboardController();
+        mUiAutomation = getInstrumentation()
+                .getUiAutomation(UiAutomation.FLAG_DONT_SUPPRESS_ACCESSIBILITY_SERVICES);
+        AccessibilityServiceInfo info = mUiAutomation.getServiceInfo();
+        info.flags |= AccessibilityServiceInfo.FLAG_RETRIEVE_INTERACTIVE_WINDOWS;
+        mUiAutomation.setServiceInfo(info);
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        mService.runOnServiceSync(() -> mService.disableSelf());
+    }
+
+    public void testApiReturnValues_shouldChangeValueOnRequestAndSendCallback() throws Exception {
+        mLastCallbackValue = -1;
+
+        final SoftKeyboardController.OnShowModeChangedListener listener =
+                new SoftKeyboardController.OnShowModeChangedListener() {
+                    @Override
+                    public void onShowModeChanged(SoftKeyboardController controller, int showMode) {
+                        synchronized (mLock) {
+                            mLastCallbackValue = showMode;
+                            mLock.notifyAll();
+                        }
+                    }
+                };
+        mKeyboardController.addOnShowModeChangedListener(listener);
+
+        // The soft keyboard should be in its' default mode.
+        assertEquals(SHOW_MODE_AUTO, mKeyboardController.getShowMode());
+
+        // Set the show mode to SHOW_MODE_HIDDEN.
+        assertTrue(mKeyboardController.setShowMode(SHOW_MODE_HIDDEN));
+
+        // Make sure the mode was changed.
+        assertEquals(SHOW_MODE_HIDDEN, mKeyboardController.getShowMode());
+
+        // Make sure we're getting the callback with the proper value.
+        waitForCallbackValueWithLock(SHOW_MODE_HIDDEN);
+
+        // Make sure we can set the value back to the default.
+        assertTrue(mKeyboardController.setShowMode(SHOW_MODE_AUTO));
+        assertEquals(SHOW_MODE_AUTO, mKeyboardController.getShowMode());
+        waitForCallbackValueWithLock(SHOW_MODE_AUTO);
+
+        // Make sure we can remove our listener.
+        assertTrue(mKeyboardController.removeOnShowModeChangedListener(listener));
+    }
+
+    public void testHideSoftKeyboard_shouldHideAndShowKeyboardOnRequest() throws Exception {
+        // The soft keyboard should be in its' default mode.
+        assertEquals(SHOW_MODE_AUTO, mKeyboardController.getShowMode());
+
+        // Note: This Activity always has a visible keyboard (due to windowSoftInputMode being set
+        // to stateAlwaysVisible).
+        int numWindowsWithIme = mUiAutomation.getWindows().size();
+
+        // Request the keyboard be hidden.
+        assertTrue(mKeyboardController.setShowMode(SHOW_MODE_HIDDEN));
+        waitForWindowStateChanged();
+        waitForIdle();
+
+        // Make sure the keyboard is hidden.
+        assertEquals(numWindowsWithIme - 1, mUiAutomation.getWindows().size());
+
+        // Request the default keyboard mode.
+        assertTrue(mKeyboardController.setShowMode(SHOW_MODE_AUTO));
+        waitForWindowStateChanged();
+        waitForIdle();
+
+        // Make sure the keyboard is visible.
+        assertEquals(numWindowsWithIme, mUiAutomation.getWindows().size());
+    }
+
+    public void testHideSoftKeyboard_shouldHideKeyboardUntilServiceIsDisabled() throws Exception {
+        // The soft keyboard should be in its' default mode.
+        assertEquals(SHOW_MODE_AUTO, mKeyboardController.getShowMode());
+
+        // Note: This Activity always has a visible keyboard (due to windowSoftInputMode being set
+        // to stateAlwaysVisible).
+        int numWindowsWithIme = mUiAutomation.getWindows().size();
+
+        // Set the show mode to SHOW_MODE_HIDDEN.
+        assertTrue(mKeyboardController.setShowMode(SHOW_MODE_HIDDEN));
+        waitForWindowStateChanged();
+        waitForIdle();
+
+        // Make sure the keyboard is hidden.
+        assertEquals(numWindowsWithIme - 1, mUiAutomation.getWindows().size());
+
+        // Make sure we can see the soft keyboard once all Accessibility Services are disabled.
+        mService.disableSelf();
+        waitForWindowStateChanged();
+        waitForIdle();
+
+        // See how many windows are present.
+        assertEquals(numWindowsWithIme, mUiAutomation.getWindows().size());
+    }
+
+    private void waitForCallbackValueWithLock(int expectedValue) throws Exception {
+        long timeoutTimeMillis = SystemClock.uptimeMillis() + TIMEOUT_PROPAGATE_SETTING;
+
+        while (SystemClock.uptimeMillis() < timeoutTimeMillis) {
+            synchronized(mLock) {
+                if (mLastCallbackValue == expectedValue) {
+                    return;
+                }
+                try {
+                    mLock.wait(timeoutTimeMillis - SystemClock.uptimeMillis());
+                } catch (InterruptedException e) {
+                    // Wait until timeout.
+                }
+            }
+        }
+
+        throw new IllegalStateException("last callback value <" + mLastCallbackValue
+                + "> does not match expected value < " + expectedValue + ">");
+    }
+
+    private void waitForWindowStateChanged() throws Exception {
+        try {
+            mUiAutomation.executeAndWaitForEvent(new Runnable() {
+                @Override
+                public void run() {
+                    // Do nothing.
+                }
+            },
+            new UiAutomation.AccessibilityEventFilter() {
+                @Override
+                public boolean accept (AccessibilityEvent event) {
+                    return event.getEventType() == AccessibilityEvent.TYPE_WINDOWS_CHANGED;
+                }
+            },
+            TIMEOUT_PROPAGATE_SETTING);
+        } catch (TimeoutException ignored) {
+            // Ignore since the event could have occurred before this method was called. There
+            // should be a check after this method returns to catch incorrect values.
+        }
+    }
+
+    private void waitForIdle() throws TimeoutException {
+        mUiAutomation.waitForIdle(TIMEOUT_ACCESSIBILITY_STATE_IDLE, TIMEOUT_ASYNC_PROCESSING);
+    }
+
+    /**
+     * Activity for testing the AccessibilityService API for hiding and showring the soft keyboard.
+     */
+    public static class SoftKeyboardModesActivity extends AccessibilityTestActivity {
+        public SoftKeyboardModesActivity() {
+            super();
+        }
+
+        @Override
+        public void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            setContentView(R.layout.accessibility_soft_keyboard_modes_test);
+        }
+    }
+}
diff --git a/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTestActivity.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTestActivity.java
similarity index 100%
rename from tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTestActivity.java
rename to tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTestActivity.java
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTextActionTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTextActionTest.java
new file mode 100644
index 0000000..e94cb11
--- /dev/null
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTextActionTest.java
@@ -0,0 +1,139 @@
+/**
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 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.accessibilityservice.cts;
+
+import android.app.UiAutomation;
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.view.View;
+import android.view.accessibility.AccessibilityNodeInfo;
+import android.widget.EditText;
+import android.widget.TextView;
+
+import android.accessibilityservice.cts.R;
+
+/**
+ * Test cases for actions taken on text views.
+ */
+public class AccessibilityTextActionTest extends
+        AccessibilityActivityTestCase<AccessibilityTextTraversalActivity> {
+    UiAutomation mUiAutomation;
+
+    public AccessibilityTextActionTest() {
+        super(AccessibilityTextTraversalActivity.class);
+    }
+
+    public void setUp() throws Exception {
+        super.setUp();
+        mUiAutomation = getInstrumentation().getUiAutomation();
+    }
+
+    public void tearDown() throws Exception {
+        mUiAutomation.destroy();
+        super.tearDown();
+    }
+
+    public void testNotEditableTextView_shouldNotExposeOrRespondToSetTextAction() {
+        final TextView textView = (TextView) getActivity().findViewById(R.id.text);
+
+        getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                textView.setVisibility(View.VISIBLE);
+                textView.setText(getString(R.string.a_b));
+            }
+        });
+
+        final AccessibilityNodeInfo text = mUiAutomation.getRootInActiveWindow()
+                .findAccessibilityNodeInfosByText(getString(R.string.a_b)).get(0);
+
+        assertFalse("Standard text view should not support SET_TEXT", text.getActionList()
+                .contains(AccessibilityNodeInfo.AccessibilityAction.ACTION_SET_TEXT));
+        assertEquals("Standard text view should not support SET_TEXT", 0,
+                text.getActions() & AccessibilityNodeInfo.ACTION_SET_TEXT);
+        Bundle args = new Bundle();
+        args.putCharSequence(AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE,
+                getString(R.string.text_input_blah));
+        assertFalse(text.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, args));
+
+        getInstrumentation().waitForIdleSync();
+        assertTrue("Text view should not update on failed set text",
+                TextUtils.equals(getString(R.string.a_b), textView.getText()));
+    }
+
+    public void testEditableTextView_shouldExposeAndRespondToSetTextAction() {
+        final TextView textView = (TextView) getActivity().findViewById(R.id.text);
+
+        getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                textView.setVisibility(View.VISIBLE);
+                textView.setText(getString(R.string.a_b), TextView.BufferType.EDITABLE);
+            }
+        });
+
+        final AccessibilityNodeInfo text = mUiAutomation.getRootInActiveWindow()
+                .findAccessibilityNodeInfosByText(getString(R.string.a_b)).get(0);
+
+        assertTrue("Editable text view should support SET_TEXT", text.getActionList()
+                .contains(AccessibilityNodeInfo.AccessibilityAction.ACTION_SET_TEXT));
+        assertEquals("Editable text view should support SET_TEXT",
+                AccessibilityNodeInfo.ACTION_SET_TEXT,
+                text.getActions() & AccessibilityNodeInfo.ACTION_SET_TEXT);
+
+        Bundle args = new Bundle();
+        String textToSet = getString(R.string.text_input_blah);
+        args.putCharSequence(
+                AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, textToSet);
+
+        assertTrue(text.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, args));
+
+        getInstrumentation().waitForIdleSync();
+        assertTrue("Editable text should update on set text",
+                TextUtils.equals(textToSet, textView.getText()));
+    }
+
+    public void testEditText_shouldExposeAndRespondToSetTextAction() {
+        final EditText editText = (EditText) getActivity().findViewById(R.id.edit);
+
+        getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                editText.setVisibility(View.VISIBLE);
+                editText.setText(getString(R.string.a_b));
+            }
+        });
+
+        final AccessibilityNodeInfo text = mUiAutomation.getRootInActiveWindow()
+                .findAccessibilityNodeInfosByText(getString(R.string.a_b)).get(0);
+
+        assertTrue("EditText should support SET_TEXT", text.getActionList()
+                .contains(AccessibilityNodeInfo.AccessibilityAction.ACTION_SET_TEXT));
+        assertEquals("EditText view should support SET_TEXT",
+                AccessibilityNodeInfo.ACTION_SET_TEXT,
+                text.getActions() & AccessibilityNodeInfo.ACTION_SET_TEXT);
+
+        Bundle args = new Bundle();
+        String textToSet = getString(R.string.text_input_blah);
+        args.putCharSequence(
+                AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, textToSet);
+
+        assertTrue(text.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, args));
+
+        getInstrumentation().waitForIdleSync();
+        assertTrue("EditText should update on set text",
+                TextUtils.equals(textToSet, editText.getText()));
+    }
+}
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTextTraversalActivity.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTextTraversalActivity.java
new file mode 100644
index 0000000..2b93a08
--- /dev/null
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTextTraversalActivity.java
@@ -0,0 +1,32 @@
+/**
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 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.accessibilityservice.cts;
+
+import android.os.Bundle;
+
+import android.accessibilityservice.cts.R;
+
+/**
+ * Activity for testing the accessibility APIs for traversing the
+ * text content of a View at several granularities.
+ */
+public class AccessibilityTextTraversalActivity extends AccessibilityTestActivity {
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.accessibility_text_traversal_test);
+    }
+}
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTextTraversalTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTextTraversalTest.java
new file mode 100644
index 0000000..53eec5f
--- /dev/null
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTextTraversalTest.java
@@ -0,0 +1,4083 @@
+/**
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 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.accessibilityservice.cts;
+
+import android.app.UiAutomation;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.text.Selection;
+import android.text.TextUtils;
+import android.view.View;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityNodeInfo;
+import android.widget.EditText;
+import android.widget.TextView;
+
+import android.accessibilityservice.cts.R;
+
+/**
+ * Test cases for testing the accessibility APIs for traversing the text content of
+ * a View at several granularities.
+ */
+public class AccessibilityTextTraversalTest
+        extends AccessibilityActivityTestCase<AccessibilityTextTraversalActivity> {
+    // The number of characters per page may vary with font, so this number is slightly uncertain.
+    // We need some threshold, however, to make sure moving by a page isn't just moving by a line.
+    private static final int[] CHARACTER_INDICES_OF_PAGE_START = {0, 53, 122, 178};
+
+    public AccessibilityTextTraversalTest() {
+        super(AccessibilityTextTraversalActivity.class);
+    }
+
+    @MediumTest
+    public void testActionNextAndPreviousAtGranularityCharacterOverContentDescription()
+            throws Exception {
+        final View view = getActivity().findViewById(R.id.view);
+
+        getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                view.setVisibility(View.VISIBLE);
+                view.setContentDescription(getString(R.string.a_b));
+            }
+        });
+
+        final AccessibilityNodeInfo text = getInstrumentation().getUiAutomation()
+                .getRootInActiveWindow().findAccessibilityNodeInfosByText(
+                        getString(R.string.a_b)).get(0);
+
+        final int granularities = text.getMovementGranularities();
+        assertEquals(granularities, AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER
+                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD
+                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH);
+
+        final Bundle arguments = new Bundle();
+        arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT,
+                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER);
+
+        // Move to the next character and wait for an event.
+        AccessibilityEvent firstExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY,
+                        arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(View.class.getName())
+                        && event.getContentDescription().toString().equals(
+                                getString(R.string.a_b))
+                        && event.getFromIndex() == 0
+                        && event.getToIndex() == 1
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(firstExpected);
+
+        // Move to the next character and wait for an event.
+        AccessibilityEvent secondExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY,
+                        arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(View.class.getName())
+                        && event.getContentDescription().toString().equals(
+                                getString(R.string.a_b))
+                        && event.getFromIndex() == 1
+                        && event.getToIndex() == 2
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(secondExpected);
+
+        // Move to the next character and wait for an event.
+        AccessibilityEvent thirdExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY,
+                        arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(View.class.getName())
+                        && event.getContentDescription().toString().equals(
+                                getString(R.string.a_b))
+                        && event.getFromIndex() == 2
+                        && event.getToIndex() == 3
+                        && event.getMovementGranularity() ==
+                                 AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(thirdExpected);
+
+        // Make sure there is no next.
+        assertFalse(text.performAction(AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY,
+                arguments));
+
+        // Move to the previous character and wait for an event.
+        AccessibilityEvent fourthExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY,
+                        arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(View.class.getName())
+                        && event.getContentDescription().toString().equals(
+                                getString(R.string.a_b))
+                        && event.getFromIndex() == 2
+                        && event.getToIndex() == 3
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(fourthExpected);
+
+        // Move to the previous character and wait for an event.
+        AccessibilityEvent fifthExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY,
+                        arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(View.class.getName())
+                        && event.getContentDescription().toString().equals(
+                                getString(R.string.a_b))
+                        && event.getFromIndex() == 1
+                        && event.getToIndex() == 2
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(fifthExpected);
+
+        // Move to the next character and wait for an event.
+        AccessibilityEvent sixthExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY,
+                        arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(View.class.getName())
+                        && event.getContentDescription().toString().equals(
+                                getString(R.string.a_b))
+                        && event.getFromIndex() == 0
+                        && event.getToIndex() == 1
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(sixthExpected);
+
+        // Make sure there is no previous.
+        assertFalse(text.performAction(
+                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments));
+    }
+
+    @MediumTest
+    public void testActionNextAndPreviousAtGranularityWordOverContentDescription()
+            throws Exception {
+        final View view = getActivity().findViewById(R.id.view);
+
+        getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                view.setVisibility(View.VISIBLE);
+                view.setContentDescription(getString(R.string.foo_bar_baz));
+            }
+        });
+
+        final AccessibilityNodeInfo text = getInstrumentation().getUiAutomation()
+                .getRootInActiveWindow().findAccessibilityNodeInfosByText(
+                        getString(R.string.foo_bar_baz)).get(0);
+
+        final int granularities = text.getMovementGranularities();
+        assertEquals(granularities, AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER
+                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD
+                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH);
+
+        final Bundle arguments = new Bundle();
+        arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT,
+                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
+
+        // Move to the next character and wait for an event.
+        AccessibilityEvent firstExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(View.class.getName())
+                        && event.getContentDescription().toString().equals(
+                                getString(R.string.foo_bar_baz))
+                        && event.getFromIndex() == 0
+                        && event.getToIndex() == 3
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(firstExpected);
+
+        // Move to the next character and wait for an event.
+        AccessibilityEvent secondExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(View.class.getName())
+                        && event.getContentDescription().toString().equals(
+                                getString(R.string.foo_bar_baz))
+                        && event.getFromIndex() == 4
+                        && event.getToIndex() == 7
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(secondExpected);
+
+        // Move to the next character and wait for an event.
+        AccessibilityEvent thirdExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(View.class.getName())
+                        && event.getContentDescription().toString().equals(
+                                getString(R.string.foo_bar_baz))
+                        && event.getFromIndex() == 8
+                        && event.getToIndex() == 11
+                        && event.getMovementGranularity() ==
+                               AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(thirdExpected);
+
+        // Make sure there is no next.
+        assertFalse(text.performAction(
+                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments));
+
+        // Move to the next character and wait for an event.
+        AccessibilityEvent fourthExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(View.class.getName())
+                        && event.getContentDescription().toString().equals(
+                                getString(R.string.foo_bar_baz))
+                        && event.getFromIndex() == 8
+                        && event.getToIndex() == 11
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(fourthExpected);
+
+        // Move to the next character and wait for an event.
+        AccessibilityEvent fifthExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(View.class.getName())
+                        && event.getContentDescription().toString().equals(
+                                getString(R.string.foo_bar_baz))
+                        && event.getFromIndex() == 4
+                        && event.getToIndex() == 7
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(fifthExpected);
+
+        // Move to the next character and wait for an event.
+        AccessibilityEvent sixthExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(View.class.getName())
+                        && event.getContentDescription().toString().equals(
+                                getString(R.string.foo_bar_baz))
+                        && event.getFromIndex() == 0
+                        && event.getToIndex() == 3
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(sixthExpected);
+
+        // Make sure there is no previous.
+        assertFalse(text.performAction(
+                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments));
+    }
+
+    @MediumTest
+    public void testActionNextAndPreviousAtGranularityCharacterOverText()
+            throws Exception {
+        final TextView textView = (TextView) getActivity().findViewById(R.id.text);
+
+        getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                textView.setVisibility(View.VISIBLE);
+                textView.setText(getString(R.string.a_b));
+            }
+        });
+
+        final AccessibilityNodeInfo text = getInstrumentation().getUiAutomation()
+               .getRootInActiveWindow().findAccessibilityNodeInfosByText(
+                       getString(R.string.a_b)).get(0);
+
+        final int granularities = text.getMovementGranularities();
+        assertEquals(granularities, AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER
+                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD
+                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE
+                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH
+                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
+
+        final Bundle arguments = new Bundle();
+        arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT,
+                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER);
+
+        // Move to the next character and wait for an event.
+        AccessibilityEvent firstExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(TextView.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(R.string.a_b))
+                        && event.getFromIndex() == 0
+                        && event.getToIndex() == 1
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(firstExpected);
+
+        // Verify the selection position.
+        assertEquals(1, Selection.getSelectionStart(textView.getText()));
+        assertEquals(1, Selection.getSelectionEnd(textView.getText()));
+
+        // Move to the next character and wait for an event.
+        AccessibilityEvent secondExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(TextView.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(R.string.a_b))
+                        && event.getFromIndex() == 1
+                        && event.getToIndex() == 2
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(secondExpected);
+
+        // Verify the selection position.
+        assertEquals(2, Selection.getSelectionStart(textView.getText()));
+        assertEquals(2, Selection.getSelectionEnd(textView.getText()));
+
+        // Move to the next character and wait for an event.
+        AccessibilityEvent thirdExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(TextView.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(R.string.a_b))
+                        && event.getFromIndex() == 2
+                        && event.getToIndex() == 3
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(thirdExpected);
+
+        // Verify the selection position.
+        assertEquals(3, Selection.getSelectionStart(textView.getText()));
+        assertEquals(3, Selection.getSelectionEnd(textView.getText()));
+
+        // Make sure there is no next.
+        assertFalse(text.performAction(
+                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments));
+
+        // Verify the selection position.
+        assertEquals(3, Selection.getSelectionStart(textView.getText()));
+        assertEquals(3, Selection.getSelectionEnd(textView.getText()));
+
+        // Move to the previous character and wait for an event.
+        AccessibilityEvent fifthExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(TextView.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(R.string.a_b))
+                        && event.getFromIndex() == 2
+                        && event.getToIndex() == 3
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(fifthExpected);
+
+        // Verify the selection position.
+        assertEquals(2, Selection.getSelectionStart(textView.getText()));
+        assertEquals(2, Selection.getSelectionEnd(textView.getText()));
+
+        // Move to the previous character and wait for an event.
+        AccessibilityEvent sixthExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(TextView.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(R.string.a_b))
+                        && event.getFromIndex() == 1
+                        && event.getToIndex() == 2
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(sixthExpected);
+
+        // Verify the selection position.
+        assertEquals(1, Selection.getSelectionStart(textView.getText()));
+        assertEquals(1, Selection.getSelectionEnd(textView.getText()));
+
+        // Move to the previous character and wait for an event.
+        AccessibilityEvent seventhExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(TextView.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(R.string.a_b))
+                        && event.getFromIndex() == 0
+                        && event.getToIndex() == 1
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(seventhExpected);
+
+        // Verify the selection position.
+        assertEquals(0, Selection.getSelectionStart(textView.getText()));
+        assertEquals(0, Selection.getSelectionEnd(textView.getText()));
+
+        // Make sure there is no previous.
+        assertFalse(text.performAction(
+                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments));
+
+        // Verify the selection position.
+        assertEquals(0, Selection.getSelectionStart(textView.getText()));
+        assertEquals(0, Selection.getSelectionEnd(textView.getText()));
+    }
+
+    @MediumTest
+    public void testActionNextAndPreviousAtGranularityCharacterOverTextExtend()
+            throws Exception {
+        final EditText editText = (EditText) getActivity().findViewById(R.id.edit);
+
+        getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                editText.setVisibility(View.VISIBLE);
+                editText.setText(getString(R.string.a_b));
+                Selection.removeSelection(editText.getText());
+            }
+        });
+
+        final AccessibilityNodeInfo text = getInstrumentation().getUiAutomation()
+               .getRootInActiveWindow().findAccessibilityNodeInfosByText(
+                       getString(R.string.a_b)).get(0);
+
+        final int granularities = text.getMovementGranularities();
+        assertEquals(granularities, AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER
+                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD
+                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE
+                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH
+                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
+
+        final Bundle arguments = new Bundle();
+        arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT,
+                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER);
+        arguments.putBoolean(AccessibilityNodeInfo.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN, true);
+
+        // Move to the next character and wait for an event.
+        AccessibilityEvent firstExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(EditText.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(R.string.a_b))
+                        && event.getFromIndex() == 0
+                        && event.getToIndex() == 1
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(firstExpected);
+
+        // Verify the selection position.
+        assertEquals(0, Selection.getSelectionStart(editText.getText()));
+        assertEquals(1, Selection.getSelectionEnd(editText.getText()));
+
+        // Move to the next character and wait for an event.
+        AccessibilityEvent secondExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(EditText.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(R.string.a_b))
+                        && event.getFromIndex() == 1
+                        && event.getToIndex() == 2
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(secondExpected);
+
+        // Verify the selection position.
+        assertEquals(0, Selection.getSelectionStart(editText.getText()));
+        assertEquals(2, Selection.getSelectionEnd(editText.getText()));
+
+        // Move to the next character and wait for an event.
+        AccessibilityEvent thirdExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(EditText.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(R.string.a_b))
+                        && event.getFromIndex() == 2
+                        && event.getToIndex() == 3
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(thirdExpected);
+
+        // Verify the selection position.
+        assertEquals(0, Selection.getSelectionStart(editText.getText()));
+        assertEquals(3, Selection.getSelectionEnd(editText.getText()));
+
+        // Make sure there is no next.
+        assertFalse(text.performAction(
+                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments));
+
+        // Verify the selection position.
+        assertEquals(0, Selection.getSelectionStart(editText.getText()));
+        assertEquals(3, Selection.getSelectionEnd(editText.getText()));
+
+        // Move to the previous character and wait for an event.
+        AccessibilityEvent fourthExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(EditText.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(R.string.a_b))
+                        && event.getFromIndex() == 2
+                        && event.getToIndex() == 3
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(fourthExpected);
+
+        // Verify the selection position.
+        assertEquals(0, Selection.getSelectionStart(editText.getText()));
+        assertEquals(2, Selection.getSelectionEnd(editText.getText()));
+
+        // Move to the previous character and wait for an event.
+        AccessibilityEvent fifthExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(EditText.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(R.string.a_b))
+                        && event.getFromIndex() == 1
+                        && event.getToIndex() == 2
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(fifthExpected);
+
+        // Verify the selection position.
+        assertEquals(0, Selection.getSelectionStart(editText.getText()));
+        assertEquals(1, Selection.getSelectionEnd(editText.getText()));
+
+        // Move to the previous character and wait for an event.
+        AccessibilityEvent sixthExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(EditText.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(R.string.a_b))
+                        && event.getFromIndex() == 0
+                        && event.getToIndex() == 1
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(sixthExpected);
+
+        // Verify the selection position.
+        assertEquals(0, Selection.getSelectionStart(editText.getText()));
+        assertEquals(0, Selection.getSelectionEnd(editText.getText()));
+
+        // Make sure there is no previous.
+        assertFalse(text.performAction(
+                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments));
+
+        // Verify the selection position.
+        assertEquals(0, Selection.getSelectionStart(editText.getText()));
+        assertEquals(0, Selection.getSelectionEnd(editText.getText()));
+
+        // Focus the view so we can change selection.
+        getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                editText.setFocusable(true);
+                editText.requestFocus();
+            }
+        });
+
+        // Put selection at the end of the text.
+        Bundle setSelectionArgs = new Bundle();
+        setSelectionArgs.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT, 3);
+        setSelectionArgs.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT, 3);
+        assertTrue(text.performAction(
+                AccessibilityNodeInfo.ACTION_SET_SELECTION, setSelectionArgs));
+
+        // Verify the selection position.
+        assertEquals(3, Selection.getSelectionStart(editText.getText()));
+        assertEquals(3, Selection.getSelectionEnd(editText.getText()));
+
+        // Unfocus the view so we can get rid of the soft-keyboard.
+        getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                editText.clearFocus();
+                editText.setFocusable(false);
+            }
+        });
+
+        // Move to the previous character and wait for an event.
+        AccessibilityEvent seventhExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(EditText.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(R.string.a_b))
+                        && event.getFromIndex() == 2
+                        && event.getToIndex() == 3
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(seventhExpected);
+
+        // Verify the selection position.
+        assertEquals(3, Selection.getSelectionStart(editText.getText()));
+        assertEquals(2, Selection.getSelectionEnd(editText.getText()));
+
+        // Move to the previous character and wait for an event.
+        AccessibilityEvent eightExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(EditText.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(R.string.a_b))
+                        && event.getFromIndex() == 1
+                        && event.getToIndex() == 2
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(eightExpected);
+
+        // Verify the selection position.
+        assertEquals(3, Selection.getSelectionStart(editText.getText()));
+        assertEquals(1, Selection.getSelectionEnd(editText.getText()));
+
+        // Move to the previous character and wait for an event.
+        AccessibilityEvent ninethExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(EditText.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(R.string.a_b))
+                        && event.getFromIndex() == 0
+                        && event.getToIndex() == 1
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(ninethExpected);
+
+        // Verify the selection position.
+        assertEquals(3, Selection.getSelectionStart(editText.getText()));
+        assertEquals(0, Selection.getSelectionEnd(editText.getText()));
+
+        // Make sure there is no previous.
+        assertFalse(text.performAction(
+                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments));
+
+        // Verify the selection position.
+        assertEquals(3, Selection.getSelectionStart(editText.getText()));
+        assertEquals(0, Selection.getSelectionEnd(editText.getText()));
+
+        // Move to the next character and wait for an event.
+        AccessibilityEvent tenthExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(EditText.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(R.string.a_b))
+                        && event.getFromIndex() == 0
+                        && event.getToIndex() == 1
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(tenthExpected);
+
+        // Verify the selection position.
+        assertEquals(3, Selection.getSelectionStart(editText.getText()));
+        assertEquals(1, Selection.getSelectionEnd(editText.getText()));
+
+        // Move to the next character and wait for an event.
+        AccessibilityEvent eleventhExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(EditText.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(R.string.a_b))
+                        && event.getFromIndex() == 1
+                        && event.getToIndex() == 2
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(eleventhExpected);
+
+        // Verify the selection position.
+        assertEquals(3, Selection.getSelectionStart(editText.getText()));
+        assertEquals(2, Selection.getSelectionEnd(editText.getText()));
+
+        // Move to the next character and wait for an event.
+        AccessibilityEvent twelvethExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(EditText.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(R.string.a_b))
+                        && event.getFromIndex() == 2
+                        && event.getToIndex() == 3
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(twelvethExpected);
+
+        // Verify the selection position.
+        assertEquals(3, Selection.getSelectionStart(editText.getText()));
+        assertEquals(3, Selection.getSelectionEnd(editText.getText()));
+
+        // Make sure there is no next.
+        assertFalse(text.performAction(
+                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments));
+
+        // Verify the selection position.
+        assertEquals(3, Selection.getSelectionStart(editText.getText()));
+        assertEquals(3, Selection.getSelectionEnd(editText.getText()));
+    }
+
+    @MediumTest
+    public void testActionNextAndPreviousAtGranularityWordOverText() throws Exception {
+        final TextView textView = (TextView) getActivity().findViewById(R.id.text);
+
+        getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                textView.setVisibility(View.VISIBLE);
+                textView.setText(getString(R.string.foo_bar_baz));
+            }
+        });
+
+        final AccessibilityNodeInfo text = getInstrumentation().getUiAutomation()
+               .getRootInActiveWindow().findAccessibilityNodeInfosByText(getString(
+                       R.string.foo_bar_baz)).get(0);
+
+        final int granularities = text.getMovementGranularities();
+        assertEquals(granularities, AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER
+                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD
+                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE
+                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH
+                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
+
+        final Bundle arguments = new Bundle();
+        arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT,
+                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
+
+        // Move to the next word and wait for an event.
+        AccessibilityEvent firstExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(TextView.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(R.string.foo_bar_baz))
+                        && event.getFromIndex() == 0
+                        && event.getToIndex() == 3
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(firstExpected);
+
+        // Verify the selection position.
+        assertEquals(3, Selection.getSelectionStart(textView.getText()));
+        assertEquals(3, Selection.getSelectionEnd(textView.getText()));
+
+        // Move to the next word and wait for an event.
+        AccessibilityEvent secondExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(TextView.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(R.string.foo_bar_baz))
+                        && event.getFromIndex() == 4
+                        && event.getToIndex() == 7
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(secondExpected);
+
+        // Verify the selection position.
+        assertEquals(7, Selection.getSelectionStart(textView.getText()));
+        assertEquals(7, Selection.getSelectionEnd(textView.getText()));
+
+        // Move to the next word and wait for an event.
+        AccessibilityEvent thirdExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(TextView.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(R.string.foo_bar_baz))
+                        && event.getFromIndex() == 8
+                        && event.getToIndex() == 11
+                        && event.getMovementGranularity() ==
+                                 AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(thirdExpected);
+
+        // Verify the selection position.
+        assertEquals(11, Selection.getSelectionStart(textView.getText()));
+        assertEquals(11, Selection.getSelectionEnd(textView.getText()));
+
+        // Make sure there is no next.
+        assertFalse(text.performAction(
+                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments));
+
+        // Verify the selection position.
+        assertEquals(11, Selection.getSelectionStart(textView.getText()));
+        assertEquals(11, Selection.getSelectionEnd(textView.getText()));
+
+        // Move to the next word and wait for an event.
+        AccessibilityEvent fourthExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(TextView.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(R.string.foo_bar_baz))
+                        && event.getFromIndex() == 8
+                        && event.getToIndex() == 11
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(fourthExpected);
+
+        // Verify the selection position.
+        assertEquals(8, Selection.getSelectionStart(textView.getText()));
+        assertEquals(8, Selection.getSelectionEnd(textView.getText()));
+
+        // Move to the next word and wait for an event.
+        AccessibilityEvent fifthExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(TextView.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(R.string.foo_bar_baz))
+                        && event.getFromIndex() == 4
+                        && event.getToIndex() == 7
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(fifthExpected);
+
+        // Verify the selection position.
+        assertEquals(4, Selection.getSelectionStart(textView.getText()));
+        assertEquals(4, Selection.getSelectionEnd(textView.getText()));
+
+        // Move to the next character and wait for an event.
+        AccessibilityEvent sixthExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(TextView.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(R.string.foo_bar_baz))
+                        && event.getFromIndex() == 0
+                        && event.getToIndex() == 3
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(sixthExpected);
+
+        // Verify the selection position.
+        assertEquals(0, Selection.getSelectionStart(textView.getText()));
+        assertEquals(0, Selection.getSelectionEnd(textView.getText()));
+
+        // Make sure there is no previous.
+        assertFalse(text.performAction(
+                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments));
+
+        // Verify the selection position.
+        assertEquals(0, Selection.getSelectionStart(textView.getText()));
+        assertEquals(0, Selection.getSelectionEnd(textView.getText()));
+    }
+
+    @MediumTest
+    public void testActionNextAndPreviousAtGranularityWordOverEditTextWithContentDescription()
+            throws Exception {
+        final EditText editText = (EditText) getActivity().findViewById(R.id.edit);
+
+        getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                editText.setVisibility(View.VISIBLE);
+                editText.setText(getString(R.string.foo_bar_baz));
+                editText.setContentDescription(getString(R.string.android_wiki));
+            }
+        });
+
+        final AccessibilityNodeInfo text = getInstrumentation().getUiAutomation()
+               .getRootInActiveWindow().findAccessibilityNodeInfosByText(getString(
+                       R.string.foo_bar_baz)).get(0);
+
+        final int granularities = text.getMovementGranularities();
+        assertEquals(granularities, AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER
+                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD
+                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE
+                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH
+                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
+
+        final Bundle arguments = new Bundle();
+        arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT,
+                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
+
+        // Move to the next word and wait for an event.
+        AccessibilityEvent firstExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(EditText.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(R.string.foo_bar_baz))
+                        && event.getContentDescription().equals(getString(R.string.android_wiki))
+                        && event.getFromIndex() == 0
+                        && event.getToIndex() == 3
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(firstExpected);
+
+        // Verify the selection position.
+        assertEquals(3, editText.getSelectionStart());
+        assertEquals(3, editText.getSelectionEnd());
+
+        // Move to the next word and wait for an event.
+        AccessibilityEvent secondExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(EditText.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(R.string.foo_bar_baz))
+                        && event.getContentDescription().equals(getString(R.string.android_wiki))
+                        && event.getFromIndex() == 4
+                        && event.getToIndex() == 7
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(secondExpected);
+
+        // Verify the selection position.
+        assertEquals(7, editText.getSelectionStart());
+        assertEquals(7, editText.getSelectionEnd());
+
+        // Move to the next word and wait for an event.
+        AccessibilityEvent thirdExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(EditText.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(R.string.foo_bar_baz))
+                        && event.getContentDescription().equals(getString(R.string.android_wiki))
+                        && event.getFromIndex() == 8
+                        && event.getToIndex() == 11
+                        && event.getMovementGranularity() ==
+                                 AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(thirdExpected);
+
+        // Verify the selection position.
+        assertEquals(11, editText.getSelectionStart());
+        assertEquals(11, editText.getSelectionEnd());
+
+        // Make sure there is no next.
+        assertFalse(text.performAction(
+                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments));
+
+        // Verify the selection position.
+        assertEquals(11, editText.getSelectionStart());
+        assertEquals(11, editText.getSelectionEnd());
+
+        // Move to the next word and wait for an event.
+        AccessibilityEvent fourthExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(EditText.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(R.string.foo_bar_baz))
+                        && event.getContentDescription().equals(getString(R.string.android_wiki))
+                        && event.getFromIndex() == 8
+                        && event.getToIndex() == 11
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(fourthExpected);
+
+        // Verify the selection position.
+        assertEquals(8, editText.getSelectionStart());
+        assertEquals(8, editText.getSelectionEnd());
+
+        // Move to the next word and wait for an event.
+        AccessibilityEvent fifthExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(EditText.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(R.string.foo_bar_baz))
+                        && event.getContentDescription().equals(getString(R.string.android_wiki))
+                        && event.getFromIndex() == 4
+                        && event.getToIndex() == 7
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(fifthExpected);
+
+        // Verify the selection position.
+        assertEquals(4, editText.getSelectionStart());
+        assertEquals(4, editText.getSelectionEnd());
+
+        // Move to the next character and wait for an event.
+        AccessibilityEvent sixthExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(EditText.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(R.string.foo_bar_baz))
+                        && event.getContentDescription().equals(getString(R.string.android_wiki))
+                        && event.getFromIndex() == 0
+                        && event.getToIndex() == 3
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(sixthExpected);
+
+        // Verify the selection position.
+        assertEquals(0, editText.getSelectionStart());
+        assertEquals(0, editText.getSelectionEnd());
+
+        // Make sure there is no previous.
+        assertFalse(text.performAction(
+                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments));
+
+        // Verify the selection position.
+        assertEquals(0, editText.getSelectionStart());
+        assertEquals(0, editText.getSelectionEnd());
+    }
+
+    @MediumTest
+    public void testActionNextAndPreviousAtGranularityWordOverTextExtend() throws Exception {
+        final EditText editText = (EditText) getActivity().findViewById(R.id.edit);
+
+        getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                editText.setVisibility(View.VISIBLE);
+                editText.setText(getString(R.string.foo_bar_baz));
+                Selection.removeSelection(editText.getText());
+            }
+        });
+
+        final AccessibilityNodeInfo text = getInstrumentation().getUiAutomation()
+               .getRootInActiveWindow().findAccessibilityNodeInfosByText(getString(
+                       R.string.foo_bar_baz)).get(0);
+
+        final int granularities = text.getMovementGranularities();
+        assertEquals(granularities, AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER
+                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD
+                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE
+                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH
+                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
+
+        final Bundle arguments = new Bundle();
+        arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT,
+                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
+        arguments.putBoolean(AccessibilityNodeInfo.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN, true);
+
+        // Move to the next word and wait for an event.
+        AccessibilityEvent firstExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(EditText.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(R.string.foo_bar_baz))
+                        && event.getFromIndex() == 0
+                        && event.getToIndex() == 3
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(firstExpected);
+
+        // Verify the selection position.
+        assertEquals(0, Selection.getSelectionStart(editText.getText()));
+        assertEquals(3, Selection.getSelectionEnd(editText.getText()));
+
+        // Move to the next word and wait for an event.
+        AccessibilityEvent secondExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(EditText.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(R.string.foo_bar_baz))
+                        && event.getFromIndex() == 4
+                        && event.getToIndex() == 7
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(secondExpected);
+
+        // Verify the selection position.
+        assertEquals(0, Selection.getSelectionStart(editText.getText()));
+        assertEquals(7, Selection.getSelectionEnd(editText.getText()));
+
+        // Move to the next word and wait for an event.
+        AccessibilityEvent thirdExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(EditText.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(R.string.foo_bar_baz))
+                        && event.getFromIndex() == 8
+                        && event.getToIndex() == 11
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(thirdExpected);
+
+        // Verify the selection position.
+        assertEquals(0, Selection.getSelectionStart(editText.getText()));
+        assertEquals(11, Selection.getSelectionEnd(editText.getText()));
+
+        // Make sure there is no next.
+        assertFalse(text.performAction(
+                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments));
+
+        // Move to the previous word and wait for an event.
+        AccessibilityEvent fourthExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(EditText.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(R.string.foo_bar_baz))
+                        && event.getFromIndex() == 8
+                        && event.getToIndex() == 11
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(fourthExpected);
+
+        // Verify the selection position.
+        assertEquals(0, Selection.getSelectionStart(editText.getText()));
+        assertEquals(8, Selection.getSelectionEnd(editText.getText()));
+
+        // Move to the previous word and wait for an event.
+        AccessibilityEvent fifthExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(EditText.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(R.string.foo_bar_baz))
+                        && event.getFromIndex() == 4
+                        && event.getToIndex() == 7
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(fifthExpected);
+
+        // Verify the selection position.
+        assertEquals(0, Selection.getSelectionStart(editText.getText()));
+        assertEquals(4, Selection.getSelectionEnd(editText.getText()));
+
+        // Move to the previous character and wait for an event.
+        AccessibilityEvent sixthExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(EditText.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(R.string.foo_bar_baz))
+                        && event.getFromIndex() == 0
+                        && event.getToIndex() == 3
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(sixthExpected);
+
+        // Verify the selection position.
+        assertEquals(0, Selection.getSelectionStart(editText.getText()));
+        assertEquals(0, Selection.getSelectionEnd(editText.getText()));
+
+        // Make sure there is no previous.
+        assertFalse(text.performAction(
+                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments));
+
+        // Verify the selection position.
+        assertEquals(0, Selection.getSelectionStart(editText.getText()));
+        assertEquals(0, Selection.getSelectionEnd(editText.getText()));
+
+        // Focus the view so we can change selection.
+        getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                editText.setFocusable(true);
+                editText.requestFocus();
+            }
+        });
+
+        // Put selection at the end of the text.
+        Bundle setSelectionArgs = new Bundle();
+        setSelectionArgs.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT, 11);
+        setSelectionArgs.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT, 11);
+        assertTrue(text.performAction(
+                AccessibilityNodeInfo.ACTION_SET_SELECTION, setSelectionArgs));
+
+        // Verify the selection position.
+        assertEquals(11, Selection.getSelectionStart(editText.getText()));
+        assertEquals(11, Selection.getSelectionEnd(editText.getText()));
+
+        // Unfocus the view so we can get rid of the soft-keyboard.
+        getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                editText.clearFocus();
+                editText.setFocusable(false);
+            }
+        });
+
+        // Move to the previous word and wait for an event.
+        AccessibilityEvent seventhExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(EditText.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(R.string.foo_bar_baz))
+                        && event.getFromIndex() == 8
+                        && event.getToIndex() == 11
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(seventhExpected);
+
+        // Verify the selection position.
+        assertEquals(11, Selection.getSelectionStart(editText.getText()));
+        assertEquals(8, Selection.getSelectionEnd(editText.getText()));
+
+        // Move to the previous word and wait for an event.
+        AccessibilityEvent eightExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(EditText.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(R.string.foo_bar_baz))
+                        && event.getFromIndex() == 4
+                        && event.getToIndex() == 7
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(eightExpected);
+
+        // Verify the selection position.
+        assertEquals(11, Selection.getSelectionStart(editText.getText()));
+        assertEquals(4, Selection.getSelectionEnd(editText.getText()));
+
+        // Move to the previous character and wait for an event.
+        AccessibilityEvent ninethExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(EditText.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(R.string.foo_bar_baz))
+                        && event.getFromIndex() == 0
+                        && event.getToIndex() == 3
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(ninethExpected);
+
+        // Verify the selection position.
+        assertEquals(11, Selection.getSelectionStart(editText.getText()));
+        assertEquals(0, Selection.getSelectionEnd(editText.getText()));
+
+        // Make sure there is no previous.
+        assertFalse(text.performAction(
+                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments));
+
+        // Verify the selection position.
+        assertEquals(11, Selection.getSelectionStart(editText.getText()));
+        assertEquals(0, Selection.getSelectionEnd(editText.getText()));
+
+        // Move to the next word and wait for an event.
+        AccessibilityEvent tenthExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(EditText.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(R.string.foo_bar_baz))
+                        && event.getFromIndex() == 0
+                        && event.getToIndex() == 3
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(tenthExpected);
+
+        // Verify the selection position.
+        assertEquals(11, Selection.getSelectionStart(editText.getText()));
+        assertEquals(3, Selection.getSelectionEnd(editText.getText()));
+
+        // Move to the next word and wait for an event.
+        AccessibilityEvent eleventhExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(EditText.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(R.string.foo_bar_baz))
+                        && event.getFromIndex() == 4
+                        && event.getToIndex() == 7
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(eleventhExpected);
+
+        // Verify the selection position.
+        assertEquals(11, Selection.getSelectionStart(editText.getText()));
+        assertEquals(7, Selection.getSelectionEnd(editText.getText()));
+
+        // Move to the next word and wait for an event.
+        AccessibilityEvent twelvthExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(EditText.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(R.string.foo_bar_baz))
+                        && event.getFromIndex() == 8
+                        && event.getToIndex() == 11
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(twelvthExpected);
+
+        // Verify the selection position.
+        assertEquals(11, Selection.getSelectionStart(editText.getText()));
+        assertEquals(11, Selection.getSelectionEnd(editText.getText()));
+
+        // Make sure there is no next.
+        assertFalse(text.performAction(
+                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments));
+
+        // Verify the selection position.
+        assertEquals(11, Selection.getSelectionStart(editText.getText()));
+        assertEquals(11, Selection.getSelectionEnd(editText.getText()));
+    }
+
+    @MediumTest
+    public void testActionNextAndPreviousAtGranularityLineOverText() throws Exception {
+        final TextView textView = (TextView) getActivity().findViewById(R.id.text);
+
+        getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                textView.setVisibility(View.VISIBLE);
+                textView.setText(getString(R.string.android_wiki_short));
+            }
+        });
+
+        final AccessibilityNodeInfo text = getInstrumentation().getUiAutomation()
+               .getRootInActiveWindow().findAccessibilityNodeInfosByText(getString(
+                       R.string.android_wiki_short)).get(0);
+
+        final int granularities = text.getMovementGranularities();
+        assertEquals(granularities, AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER
+                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD
+                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE
+                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH
+                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
+
+        final Bundle arguments = new Bundle();
+        arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT,
+                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE);
+
+        // Move to the next line and wait for an event.
+        AccessibilityEvent firstExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(TextView.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(
+                                R.string.android_wiki_short))
+                        && event.getFromIndex() == 0
+                        && event.getToIndex() == 13
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(firstExpected);
+
+        // Verify the selection position.
+        assertEquals(13, Selection.getSelectionStart(textView.getText()));
+        assertEquals(13, Selection.getSelectionEnd(textView.getText()));
+
+        // Move to the next line and wait for an event.
+        AccessibilityEvent secondExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(TextView.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(
+                                R.string.android_wiki_short))
+                        && event.getFromIndex() == 13
+                        && event.getToIndex() == 25
+                        && event.getMovementGranularity() ==
+                                 AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(secondExpected);
+
+        // Verify the selection position.
+        assertEquals(25, Selection.getSelectionStart(textView.getText()));
+        assertEquals(25, Selection.getSelectionEnd(textView.getText()));
+
+        // Move to the next line and wait for an event.
+        AccessibilityEvent thirdExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(TextView.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(
+                                R.string.android_wiki_short))
+                        && event.getFromIndex() == 25
+                        && event.getToIndex() == 34
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(thirdExpected);
+
+        // Verify the selection position.
+        assertEquals(34, Selection.getSelectionStart(textView.getText()));
+        assertEquals(34, Selection.getSelectionEnd(textView.getText()));
+
+        // Make sure there is no next.
+        assertFalse(text.performAction(
+                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments));
+
+        // Verify the selection position.
+        assertEquals(34, Selection.getSelectionStart(textView.getText()));
+        assertEquals(34, Selection.getSelectionEnd(textView.getText()));
+
+        // Move to the previous line and wait for an event.
+        AccessibilityEvent fourthExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(TextView.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(
+                                R.string.android_wiki_short))
+                        && event.getFromIndex() == 25
+                        && event.getToIndex() == 34
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(fourthExpected);
+
+        // Verify the selection position.
+        assertEquals(25, Selection.getSelectionStart(textView.getText()));
+        assertEquals(25, Selection.getSelectionEnd(textView.getText()));
+
+        // Move to the previous line and wait for an event.
+        AccessibilityEvent fifthExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(TextView.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(
+                                R.string.android_wiki_short))
+                        && event.getFromIndex() == 13
+                        && event.getToIndex() == 25
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(fifthExpected);
+
+        // Verify the selection position.
+        assertEquals(13, Selection.getSelectionStart(textView.getText()));
+        assertEquals(13, Selection.getSelectionEnd(textView.getText()));
+
+        // Move to the previous line and wait for an event.
+        AccessibilityEvent sixthExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(TextView.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(
+                                R.string.android_wiki_short))
+                        && event.getFromIndex() == 0
+                        && event.getToIndex() == 13
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(sixthExpected);
+
+        // Verify the selection position.
+        assertEquals(0, Selection.getSelectionStart(textView.getText()));
+        assertEquals(0, Selection.getSelectionEnd(textView.getText()));
+
+        // Make sure there is no previous.
+        assertFalse(text.performAction(
+                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments));
+
+        // Verify the selection position.
+        assertEquals(0, Selection.getSelectionStart(textView.getText()));
+        assertEquals(0, Selection.getSelectionEnd(textView.getText()));
+    }
+
+    @MediumTest
+    public void testActionNextAndPreviousAtGranularityLineOverTextExtend() throws Exception {
+        final EditText editText = (EditText) getActivity().findViewById(R.id.edit);
+
+        getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                editText.setVisibility(View.VISIBLE);
+                editText.setText(getString(R.string.android_wiki_short));
+                Selection.removeSelection(editText.getText());
+            }
+        });
+
+        final AccessibilityNodeInfo text = getInstrumentation().getUiAutomation()
+               .getRootInActiveWindow().findAccessibilityNodeInfosByText(getString(
+                       R.string.android_wiki_short)).get(0);
+
+        final int granularities = text.getMovementGranularities();
+        assertEquals(granularities, AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER
+                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD
+                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE
+                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH
+                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
+
+        final Bundle arguments = new Bundle();
+        arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT,
+                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE);
+        arguments.putBoolean(AccessibilityNodeInfo.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN, true);
+
+        // Move to the next line and wait for an event.
+        AccessibilityEvent firstExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(EditText.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(
+                                R.string.android_wiki_short))
+                        && event.getFromIndex() == 0
+                        && event.getToIndex() == 13
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(firstExpected);
+
+        // Verify the selection position.
+        assertEquals(0, Selection.getSelectionStart(editText.getText()));
+        assertEquals(13, Selection.getSelectionEnd(editText.getText()));
+
+        // Move to the next line and wait for an event.
+        AccessibilityEvent secondExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(EditText.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(
+                                R.string.android_wiki_short))
+                        && event.getFromIndex() == 13
+                        && event.getToIndex() == 25
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(secondExpected);
+
+        // Verify the selection position.
+        assertEquals(0, Selection.getSelectionStart(editText.getText()));
+        assertEquals(25, Selection.getSelectionEnd(editText.getText()));
+
+        // Move to the next line and wait for an event.
+        AccessibilityEvent thirdExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(EditText.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(
+                                R.string.android_wiki_short))
+                        && event.getFromIndex() == 25
+                        && event.getToIndex() == 34
+                        && event.getMovementGranularity() ==
+                                 AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(thirdExpected);
+
+        // Verify the selection position.
+        assertEquals(0, Selection.getSelectionStart(editText.getText()));
+        assertEquals(34, Selection.getSelectionEnd(editText.getText()));
+
+        // Move to the previous line and wait for an event.
+        AccessibilityEvent fourthExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(EditText.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(
+                                R.string.android_wiki_short))
+                        && event.getFromIndex() == 25
+                        && event.getToIndex() == 34
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(fourthExpected);
+
+        // Verify the selection position.
+        assertEquals(0, Selection.getSelectionStart(editText.getText()));
+        assertEquals(25, Selection.getSelectionEnd(editText.getText()));
+
+        // Move to the previous line and wait for an event.
+        AccessibilityEvent fifthExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(EditText.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(
+                                R.string.android_wiki_short))
+                        && event.getFromIndex() == 13
+                        && event.getToIndex() == 25
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(fifthExpected);
+
+        // Verify the selection position.
+        assertEquals(0, Selection.getSelectionStart(editText.getText()));
+        assertEquals(13, Selection.getSelectionEnd(editText.getText()));
+
+        // Move to the previous line and wait for an event.
+        AccessibilityEvent sixthExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                               AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(EditText.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(
+                                R.string.android_wiki_short))
+                        && event.getFromIndex() == 0
+                        && event.getToIndex() == 13
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(sixthExpected);
+
+        // Verify the selection position.
+        assertEquals(0, Selection.getSelectionStart(editText.getText()));
+        assertEquals(0, Selection.getSelectionEnd(editText.getText()));
+
+        // Make sure there is no previous.
+        assertFalse(text.performAction(
+                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments));
+
+        // Verify the selection position.
+        assertEquals(0, Selection.getSelectionStart(editText.getText()));
+        assertEquals(0, Selection.getSelectionEnd(editText.getText()));
+
+        // Focus the view so we can change selection.
+        getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                editText.setFocusable(true);
+                editText.requestFocus();
+            }
+        });
+
+        // Put selection at the end of the text.
+        Bundle setSelectionArgs = new Bundle();
+        setSelectionArgs.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT, 34);
+        setSelectionArgs.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT, 34);
+        assertTrue(text.performAction(
+                AccessibilityNodeInfo.ACTION_SET_SELECTION, setSelectionArgs));
+
+        // Verify the selection position.
+        assertEquals(34, Selection.getSelectionStart(editText.getText()));
+        assertEquals(34, Selection.getSelectionEnd(editText.getText()));
+
+        // Unocus the view so we can hide the keyboard.
+        getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                editText.clearFocus();
+                editText.setFocusable(false);
+            }
+        });
+
+        // Move to the previous line and wait for an event.
+        AccessibilityEvent seventhExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(EditText.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(
+                                R.string.android_wiki_short))
+                        && event.getFromIndex() == 25
+                        && event.getToIndex() == 34
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(seventhExpected);
+
+        // Verify the selection position.
+        assertEquals(34, Selection.getSelectionStart(editText.getText()));
+        assertEquals(25, Selection.getSelectionEnd(editText.getText()));
+
+        // Move to the previous line and wait for an event.
+        AccessibilityEvent eightExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(EditText.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(
+                                R.string.android_wiki_short))
+                        && event.getFromIndex() == 13
+                        && event.getToIndex() == 25
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(eightExpected);
+
+        // Verify the selection position.
+        assertEquals(34, Selection.getSelectionStart(editText.getText()));
+        assertEquals(13, Selection.getSelectionEnd(editText.getText()));
+
+        // Move to the previous line and wait for an event.
+        AccessibilityEvent ninethExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                               AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(EditText.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(
+                                R.string.android_wiki_short))
+                        && event.getFromIndex() == 0
+                        && event.getToIndex() == 13
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(ninethExpected);
+
+        // Verify the selection position.
+        assertEquals(34, Selection.getSelectionStart(editText.getText()));
+        assertEquals(0, Selection.getSelectionEnd(editText.getText()));
+
+        // Make sure there is no previous.
+        assertFalse(text.performAction(
+                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments));
+
+        // Verify the selection position.
+        assertEquals(34, Selection.getSelectionStart(editText.getText()));
+        assertEquals(0, Selection.getSelectionEnd(editText.getText()));
+
+        // Move to the next line and wait for an event.
+        AccessibilityEvent tenthExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(EditText.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(
+                                R.string.android_wiki_short))
+                        && event.getFromIndex() == 0
+                        && event.getToIndex() == 13
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(tenthExpected);
+
+        // Verify the selection position.
+        assertEquals(34, Selection.getSelectionStart(editText.getText()));
+        assertEquals(13, Selection.getSelectionEnd(editText.getText()));
+
+        // Move to the next line and wait for an event.
+        AccessibilityEvent eleventhExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(EditText.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(
+                                R.string.android_wiki_short))
+                        && event.getFromIndex() == 13
+                        && event.getToIndex() == 25
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(eleventhExpected);
+
+        // Verify the selection position.
+        assertEquals(34, Selection.getSelectionStart(editText.getText()));
+        assertEquals(25, Selection.getSelectionEnd(editText.getText()));
+
+        // Move to the next line and wait for an event.
+        AccessibilityEvent twelvethExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(EditText.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(
+                                R.string.android_wiki_short))
+                        && event.getFromIndex() == 25
+                        && event.getToIndex() == 34
+                        && event.getMovementGranularity() ==
+                                 AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(twelvethExpected);
+
+        // Verify the selection position.
+        assertEquals(34, Selection.getSelectionStart(editText.getText()));
+        assertEquals(34, Selection.getSelectionEnd(editText.getText()));
+    }
+
+    @MediumTest
+    public void testActionNextAndPreviousAtGranularityPageOverText() throws Exception {
+        final EditText editText = (EditText) getActivity().findViewById(R.id.edit);
+
+        getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                editText.setVisibility(View.VISIBLE);
+                editText.setText(getString(R.string.android_wiki));
+                Selection.removeSelection(editText.getText());
+            }
+        });
+
+        final AccessibilityNodeInfo text = getInstrumentation().getUiAutomation()
+               .getRootInActiveWindow().findAccessibilityNodeInfosByText(getString(
+                       R.string.android_wiki)).get(0);
+
+        final int granularities = text.getMovementGranularities();
+        assertEquals(granularities, AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER
+                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD
+                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE
+                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH
+                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
+
+        final Bundle arguments = new Bundle();
+        arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT,
+                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
+
+        // Move forward a few pages
+        for (int i = 0; i < CHARACTER_INDICES_OF_PAGE_START.length - 1; i++) {
+            AccessibilityEvent event = performMovementActionAndGetEvent(
+                    text,
+                    AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY,
+                    AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE,
+                    false);
+            assertEquals(event.getClassName(), EditText.class.getName());
+            assertTrue("Event should contain text", event.getText().size() > 0);
+            assertTrue("Event text doesn't match. Expected: " + getString(R.string.android_wiki)
+                    + ". Received:" + event.getText().get(0),
+                    TextUtils.equals(event.getText().get(0), getString(R.string.android_wiki)));
+            assertEquals("Event from should be start of text skipped.",
+                    CHARACTER_INDICES_OF_PAGE_START[i], event.getFromIndex());
+            assertEquals("Event to should be end of text skipped.",
+                    CHARACTER_INDICES_OF_PAGE_START[i + 1], event.getToIndex());
+            // Verify the selection position has changed.
+            assertEquals("Event selection start should match position it moved to.",
+                    CHARACTER_INDICES_OF_PAGE_START[i + 1],
+                    Selection.getSelectionStart(editText.getText()));
+            assertEquals("Event selection end should match position it moved to.",
+                    CHARACTER_INDICES_OF_PAGE_START[i + 1],
+                    Selection.getSelectionEnd(editText.getText()));
+        }
+
+        // Move back to the beginning
+        for (int i = CHARACTER_INDICES_OF_PAGE_START.length - 2; i >= 0; i--) {
+            AccessibilityEvent event = performMovementActionAndGetEvent(
+                    text,
+                    AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY,
+                    AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE,
+                    false);
+            assertEquals(event.getClassName(), EditText.class.getName());
+            assertTrue("Event should contain text", event.getText().size() > 0);
+            assertTrue("Event text doesn't match. Expected: " + getString(R.string.android_wiki)
+                            + ". Received:" + event.getText().get(0),
+                    TextUtils.equals(event.getText().get(0), getString(R.string.android_wiki)));
+            assertEquals("Event from should be start of text skipped.",
+                    CHARACTER_INDICES_OF_PAGE_START[i], event.getFromIndex());
+            assertEquals("Event to should be end of text skipped.",
+                    CHARACTER_INDICES_OF_PAGE_START[i + 1], event.getToIndex());
+            // Verify the selection position has changed.
+            assertEquals("Event selection start should match position it moved to.",
+                    CHARACTER_INDICES_OF_PAGE_START[i],
+                    Selection.getSelectionStart(editText.getText()));
+            assertEquals("Event selection end should match position it moved to.",
+                    CHARACTER_INDICES_OF_PAGE_START[i],
+                    Selection.getSelectionEnd(editText.getText()));
+        }
+    }
+
+    @MediumTest
+    public void testActionNextAndPreviousAtGranularityPageOverTextExtend() throws Exception {
+        final EditText editText = (EditText) getActivity().findViewById(R.id.edit);
+
+        getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                editText.setVisibility(View.VISIBLE);
+                editText.setText(getString(R.string.android_wiki));
+                Selection.removeSelection(editText.getText());
+            }
+        });
+
+        final AccessibilityNodeInfo text = getInstrumentation().getUiAutomation()
+               .getRootInActiveWindow().findAccessibilityNodeInfosByText(getString(
+                       R.string.android_wiki)).get(0);
+
+        final int granularities = text.getMovementGranularities();
+        assertEquals(granularities, AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER
+                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD
+                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE
+                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH
+                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
+
+        final Bundle arguments = new Bundle();
+        arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT,
+                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
+
+        // Move forward a few pages
+        for (int i = 0; i < CHARACTER_INDICES_OF_PAGE_START.length - 1; i++) {
+            AccessibilityEvent event = performMovementActionAndGetEvent(
+                    text,
+                    AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY,
+                    AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE,
+                    true);
+            assertEquals(event.getClassName(), EditText.class.getName());
+            assertTrue("Event should contain text", event.getText().size() > 0);
+            assertTrue("Event text doesn't match. Expected: " + getString(R.string.android_wiki)
+                            + ". Received:" + event.getText().get(0),
+                    TextUtils.equals(event.getText().get(0), getString(R.string.android_wiki)));
+            assertEquals("Event from should be start of text skipped",
+                    CHARACTER_INDICES_OF_PAGE_START[i], event.getFromIndex());
+            assertEquals("Event to should be end of text skipped",
+                    CHARACTER_INDICES_OF_PAGE_START[i + 1], event.getToIndex());
+            // Verify the selection position has changed.
+            assertEquals("Event selection start should stay at beginning",
+                    0, Selection.getSelectionStart(editText.getText()));
+            assertEquals("Event selection end should match current position",
+                    CHARACTER_INDICES_OF_PAGE_START[i + 1],
+                    Selection.getSelectionEnd(editText.getText()));
+        }
+
+        // Move back to the beginning
+        for (int i = CHARACTER_INDICES_OF_PAGE_START.length - 2; i >= 0; i--) {
+            AccessibilityEvent event = performMovementActionAndGetEvent(
+                    text,
+                    AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY,
+                    AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE,
+                    true);
+            assertEquals(event.getClassName(), EditText.class.getName());
+            assertTrue("Event should contain text", event.getText().size() > 0);
+            assertTrue("Event text doesn't match. Expected: " + getString(R.string.android_wiki)
+                            + ". Received:" + event.getText().get(0),
+                    TextUtils.equals(event.getText().get(0), getString(R.string.android_wiki)));
+            assertEquals("Event from should be start of text skipped",
+                    CHARACTER_INDICES_OF_PAGE_START[i], event.getFromIndex());
+            assertEquals("Event to should be end of text skipped",
+                    CHARACTER_INDICES_OF_PAGE_START[i + 1], event.getToIndex());
+            // Verify the selection position has changed.
+            assertEquals("Event selection start should stay at beginning",
+                    0, Selection.getSelectionStart(editText.getText()));
+            assertEquals("Event selection end should match current position",
+                    CHARACTER_INDICES_OF_PAGE_START[i],
+                    Selection.getSelectionEnd(editText.getText()));
+        }
+    }
+
+    @MediumTest
+    public void testActionNextAndPreviousAtGranularityParagraphOverText() throws Exception {
+        final TextView textView = (TextView) getActivity().findViewById(R.id.edit);
+
+        getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                textView.setVisibility(View.VISIBLE);
+                textView.setText(getString(R.string.android_wiki_paragraphs));
+            }
+        });
+
+        final AccessibilityNodeInfo text = getInstrumentation().getUiAutomation()
+               .getRootInActiveWindow().findAccessibilityNodeInfosByText(getString(
+                       R.string.android_wiki_paragraphs)).get(0);
+
+        final int granularities = text.getMovementGranularities();
+        assertEquals(granularities, AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER
+                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD
+                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE
+                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH
+                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
+
+        final Bundle arguments = new Bundle();
+        arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT,
+                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH);
+
+        // Move to the next paragraph and wait for an event.
+        AccessibilityEvent firstExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(EditText.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(
+                                R.string.android_wiki_paragraphs))
+                        && event.getFromIndex() == 2
+                        && event.getToIndex() == 14
+                        && event.getMovementGranularity() ==
+                                 AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(firstExpected);
+
+        // Verify the selection position.
+        assertEquals(14, Selection.getSelectionStart(textView.getText()));
+        assertEquals(14, Selection.getSelectionEnd(textView.getText()));
+
+        // Move to the next paragraph and wait for an event.
+        AccessibilityEvent secondExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                 AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(EditText.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(
+                                R.string.android_wiki_paragraphs))
+                        && event.getFromIndex() == 16
+                        && event.getToIndex() == 32
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(secondExpected);
+
+        // Verify the selection position.
+        assertEquals(32, Selection.getSelectionStart(textView.getText()));
+        assertEquals(32, Selection.getSelectionEnd(textView.getText()));
+
+        // Move to the next paragraph and wait for an event.
+        AccessibilityEvent thirdExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(EditText.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(
+                                R.string.android_wiki_paragraphs))
+                        && event.getFromIndex() == 33
+                        && event.getToIndex() == 47
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(thirdExpected);
+
+        // Verify the selection position.
+        assertEquals(47, Selection.getSelectionStart(textView.getText()));
+        assertEquals(47, Selection.getSelectionEnd(textView.getText()));
+
+        // Make sure there is no next.
+        assertFalse(text.performAction(
+                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments));
+
+        // Verify the selection position.
+        assertEquals(47, Selection.getSelectionStart(textView.getText()));
+        assertEquals(47, Selection.getSelectionEnd(textView.getText()));
+
+        // Move to the previous paragraph and wait for an event.
+        AccessibilityEvent fourthExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(EditText.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(
+                                R.string.android_wiki_paragraphs))
+                        && event.getFromIndex() == 33
+                        && event.getToIndex() == 47
+                        && event.getMovementGranularity() ==
+                                 AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(fourthExpected);
+
+        // Verify the selection position.
+        assertEquals(33, Selection.getSelectionStart(textView.getText()));
+        assertEquals(33, Selection.getSelectionEnd(textView.getText()));
+
+        // Move to the previous paragraph and wait for an event.
+        AccessibilityEvent fifthExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(EditText.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(
+                                R.string.android_wiki_paragraphs))
+                        && event.getFromIndex() == 16
+                        && event.getToIndex() == 32
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(fifthExpected);
+
+        // Verify the selection position.
+        assertEquals(16, Selection.getSelectionStart(textView.getText()));
+        assertEquals(16, Selection.getSelectionEnd(textView.getText()));
+
+        // Move to the previous paragraph and wait for an event.
+        AccessibilityEvent sixthExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(EditText.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(
+                                R.string.android_wiki_paragraphs))
+                        && event.getFromIndex() == 2
+                        && event.getToIndex() == 14
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(sixthExpected);
+
+        // Verify the selection position.
+        assertEquals(2, Selection.getSelectionStart(textView.getText()));
+        assertEquals(2, Selection.getSelectionEnd(textView.getText()));
+
+        // Make sure there is no previous.
+        assertFalse(text.performAction(
+                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments));
+
+        // Verify the selection position.
+        assertEquals(2, Selection.getSelectionStart(textView.getText()));
+        assertEquals(2, Selection.getSelectionEnd(textView.getText()));
+    }
+
+    @MediumTest
+    public void testActionNextAndPreviousAtGranularityParagraphOverTextExtend() throws Exception {
+        final EditText editText = (EditText) getActivity().findViewById(R.id.edit);
+
+        getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                editText.setVisibility(View.VISIBLE);
+                editText.setText(getString(R.string.android_wiki_paragraphs));
+                Selection.removeSelection(editText.getText());
+            }
+        });
+
+        final AccessibilityNodeInfo text = getInstrumentation().getUiAutomation()
+               .getRootInActiveWindow().findAccessibilityNodeInfosByText(getString(
+                       R.string.android_wiki_paragraphs)).get(0);
+
+        final int granularities = text.getMovementGranularities();
+        assertEquals(granularities, AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER
+                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD
+                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE
+                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH
+                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
+
+        final Bundle arguments = new Bundle();
+        arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT,
+                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH);
+        arguments.putBoolean(AccessibilityNodeInfo.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN, true);
+
+        // Move to the next paragraph and wait for an event.
+        AccessibilityEvent firstExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(EditText.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(
+                                R.string.android_wiki_paragraphs))
+                        && event.getFromIndex() == 2
+                        && event.getToIndex() == 14
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(firstExpected);
+
+        // Verify the selection position.
+        assertEquals(2, Selection.getSelectionStart(editText.getText()));
+        assertEquals(14, Selection.getSelectionEnd(editText.getText()));
+
+        // Move to the next paragraph and wait for an event.
+        AccessibilityEvent secondExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(EditText.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(
+                                R.string.android_wiki_paragraphs))
+                        && event.getFromIndex() == 16
+                        && event.getToIndex() == 32
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(secondExpected);
+
+        // Verify the selection position.
+        assertEquals(2, Selection.getSelectionStart(editText.getText()));
+        assertEquals(32, Selection.getSelectionEnd(editText.getText()));
+
+        // Move to the next paragraph and wait for an event.
+        AccessibilityEvent thirdExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(EditText.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(
+                                R.string.android_wiki_paragraphs))
+                        && event.getFromIndex() == 33
+                        && event.getToIndex() == 47
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(thirdExpected);
+
+        // Verify the selection position.
+        assertEquals(2, Selection.getSelectionStart(editText.getText()));
+        assertEquals(47, Selection.getSelectionEnd(editText.getText()));
+
+        // Make sure there is no next.
+        assertFalse(text.performAction(
+                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments));
+
+        // Verify the selection position.
+        assertEquals(2, Selection.getSelectionStart(editText.getText()));
+        assertEquals(47, Selection.getSelectionEnd(editText.getText()));
+
+        // Move to the previous paragraph and wait for an event.
+        AccessibilityEvent fourthExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(EditText.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(
+                                R.string.android_wiki_paragraphs))
+                        && event.getFromIndex() == 33
+                        && event.getToIndex() == 47
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(fourthExpected);
+
+        // Verify the selection position.
+        assertEquals(2, Selection.getSelectionStart(editText.getText()));
+        assertEquals(33, Selection.getSelectionEnd(editText.getText()));
+
+        // Move to the previous paragraph and wait for an event.
+        AccessibilityEvent fifthExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(EditText.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(
+                                R.string.android_wiki_paragraphs))
+                        && event.getFromIndex() == 16
+                        && event.getToIndex() == 32
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(fifthExpected);
+
+        // Verify the selection position.
+        assertEquals(2, Selection.getSelectionStart(editText.getText()));
+        assertEquals(16, Selection.getSelectionEnd(editText.getText()));
+
+        // Move to the previous paragraph and wait for an event.
+        AccessibilityEvent sixthExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(EditText.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(
+                                R.string.android_wiki_paragraphs))
+                        && event.getFromIndex() == 2
+                        && event.getToIndex() == 14
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(sixthExpected);
+
+        // Verify the selection position.
+        assertEquals(2, Selection.getSelectionStart(editText.getText()));
+        assertEquals(2, Selection.getSelectionEnd(editText.getText()));
+
+        // Make sure there is no previous.
+        assertFalse(text.performAction(
+                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments));
+
+        // Verify the selection position.
+        assertEquals(2, Selection.getSelectionStart(editText.getText()));
+        assertEquals(2, Selection.getSelectionEnd(editText.getText()));
+
+        // Focus the view so we can change selection.
+        getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                editText.setFocusable(true);
+                editText.requestFocus();
+            }
+        });
+
+        // Put selection at the end of the text.
+        Bundle setSelectionArgs = new Bundle();
+        setSelectionArgs.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT, 47);
+        setSelectionArgs.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT, 47);
+        assertTrue(text.performAction(
+                AccessibilityNodeInfo.ACTION_SET_SELECTION, setSelectionArgs));
+
+        // Verify the selection position.
+        assertEquals(47, Selection.getSelectionStart(editText.getText()));
+        assertEquals(47, Selection.getSelectionEnd(editText.getText()));
+
+        // Unfocus the view so we can get rid of the soft-keyboard.
+        getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                editText.clearFocus();
+                editText.setFocusable(false);
+            }
+        });
+
+        // Move to the previous paragraph and wait for an event.
+        AccessibilityEvent seventhExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(EditText.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(
+                                R.string.android_wiki_paragraphs))
+                        && event.getFromIndex() == 33
+                        && event.getToIndex() == 47
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(seventhExpected);
+
+        // Verify the selection position.
+        assertEquals(47, Selection.getSelectionStart(editText.getText()));
+        assertEquals(33, Selection.getSelectionEnd(editText.getText()));
+
+        // Move to the previous paragraph and wait for an event.
+        AccessibilityEvent eightExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(EditText.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(
+                                R.string.android_wiki_paragraphs))
+                        && event.getFromIndex() == 16
+                        && event.getToIndex() == 32
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(eightExpected);
+
+        // Verify the selection position.
+        assertEquals(47, Selection.getSelectionStart(editText.getText()));
+        assertEquals(16, Selection.getSelectionEnd(editText.getText()));
+
+        // Move to the previous paragraph and wait for an event.
+        AccessibilityEvent ninethExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(EditText.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(
+                                R.string.android_wiki_paragraphs))
+                        && event.getFromIndex() == 2
+                        && event.getToIndex() == 14
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(ninethExpected);
+
+        // Verify the selection position.
+        assertEquals(47, Selection.getSelectionStart(editText.getText()));
+        assertEquals(2, Selection.getSelectionEnd(editText.getText()));
+
+        // Make sure there is no previous.
+        assertFalse(text.performAction(
+                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments));
+
+        // Verify the selection position.
+        assertEquals(47, Selection.getSelectionStart(editText.getText()));
+        assertEquals(2, Selection.getSelectionEnd(editText.getText()));
+
+        // Move to the next paragraph and wait for an event.
+        AccessibilityEvent tenthExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(EditText.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(
+                                R.string.android_wiki_paragraphs))
+                        && event.getFromIndex() == 2
+                        && event.getToIndex() == 14
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(tenthExpected);
+
+        // Verify the selection position.
+        assertEquals(47, Selection.getSelectionStart(editText.getText()));
+        assertEquals(14, Selection.getSelectionEnd(editText.getText()));
+
+        // Move to the next paragraph and wait for an event.
+        AccessibilityEvent eleventhExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(EditText.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(
+                                R.string.android_wiki_paragraphs))
+                        && event.getFromIndex() == 16
+                        && event.getToIndex() == 32
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(eleventhExpected);
+
+        // Verify the selection position.
+        assertEquals(47, Selection.getSelectionStart(editText.getText()));
+        assertEquals(32, Selection.getSelectionEnd(editText.getText()));
+
+        // Move to the next paragraph and wait for an event.
+        AccessibilityEvent twlevethExpected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                text.performAction(
+                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return
+                (event.getEventType() ==
+                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+                        && event.getAction() ==
+                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
+                        && event.getPackageName().equals(getActivity().getPackageName())
+                        && event.getClassName().equals(EditText.class.getName())
+                        && event.getText().size() > 0
+                        && event.getText().get(0).toString().equals(getString(
+                                R.string.android_wiki_paragraphs))
+                        && event.getFromIndex() == 33
+                        && event.getToIndex() == 47
+                        && event.getMovementGranularity() ==
+                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure we got the expected event.
+        assertNotNull(twlevethExpected);
+
+        // Verify the selection position.
+        assertEquals(47, Selection.getSelectionStart(editText.getText()));
+        assertEquals(47, Selection.getSelectionEnd(editText.getText()));
+
+        // Make sure there is no next.
+        assertFalse(text.performAction(
+                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments));
+
+        // Verify the selection position.
+        assertEquals(47, Selection.getSelectionStart(editText.getText()));
+        assertEquals(47, Selection.getSelectionEnd(editText.getText()));
+    }
+
+    @MediumTest
+    public void testTextEditingActions() throws Exception {
+        if (!getActivity().getPackageManager().hasSystemFeature(
+                PackageManager.FEATURE_INPUT_METHODS)) {
+            return;
+        }
+
+        final EditText editText = (EditText) getActivity().findViewById(R.id.edit);
+        final String textContent = getString(R.string.foo_bar_baz);
+
+        getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                editText.setVisibility(View.VISIBLE);
+                editText.setFocusable(true);
+                editText.requestFocus();
+                editText.setText(getString(R.string.foo_bar_baz));
+                Selection.removeSelection(editText.getText());
+            }
+        });
+
+        final AccessibilityNodeInfo text = getInstrumentation().getUiAutomation()
+               .getRootInActiveWindow().findAccessibilityNodeInfosByText(
+                       getString(R.string.foo_bar_baz)).get(0);
+
+        // Select all text.
+        Bundle arguments = new Bundle();
+        arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT, 0);
+        arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT,
+                editText.getText().length());
+        assertTrue(text.performAction(
+                AccessibilityNodeInfo.ACTION_SET_SELECTION, arguments));
+
+        // Copy the selected text.
+        text.performAction(AccessibilityNodeInfo.ACTION_COPY);
+
+        // Set selection at the end.
+        final int textLength = editText.getText().length();
+        // Verify the selection position.
+        assertEquals(textLength, Selection.getSelectionStart(editText.getText()));
+        assertEquals(textLength, Selection.getSelectionEnd(editText.getText()));
+
+        // Paste the selected text.
+        assertTrue(text.performAction(
+                AccessibilityNodeInfo.ACTION_PASTE));
+
+        // Verify the content.
+        assertEquals(editText.getText().toString(), textContent + textContent);
+
+        // Select all text.
+        arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT, 0);
+        arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT,
+                editText.getText().length());
+        assertTrue(text.performAction(
+                AccessibilityNodeInfo.ACTION_SET_SELECTION, arguments));
+
+        // Cut the selected text.
+        assertTrue(text.performAction(
+                AccessibilityNodeInfo.ACTION_CUT));
+
+        // Verify the content.
+        assertTrue(TextUtils.isEmpty(editText.getText()));
+    }
+
+    public void testSetSelectionInContentDescription() throws Exception {
+        final View view = getActivity().findViewById(R.id.view);
+
+        getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                view.setVisibility(View.VISIBLE);
+                view.setContentDescription(getString(R.string.foo_bar_baz));
+            }
+        });
+
+        AccessibilityNodeInfo text = getInstrumentation().getUiAutomation()
+               .getRootInActiveWindow().findAccessibilityNodeInfosByText(
+                       getString(R.string.foo_bar_baz)).get(0);
+
+        // Set the cursor position.
+        Bundle arguments = new Bundle();
+        arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT, 4);
+        arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT, 4);
+        assertTrue(text.performAction(
+                AccessibilityNodeInfo.ACTION_SET_SELECTION, arguments));
+
+        // Try and fail to set the selection longer than zero.
+        arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT, 4);
+        arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT, 5);
+        assertFalse(text.performAction(
+                AccessibilityNodeInfo.ACTION_SET_SELECTION, arguments));
+    }
+
+    public void testSelectionPositionForNonEditableView() throws Exception {
+        final View view = getActivity().findViewById(R.id.view);
+
+        getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                view.setVisibility(View.VISIBLE);
+                view.setContentDescription(getString(R.string.foo_bar_baz));
+            }
+        });
+
+        final AccessibilityNodeInfo text = getInstrumentation().getUiAutomation()
+               .getRootInActiveWindow().findAccessibilityNodeInfosByText(
+                       getString(R.string.foo_bar_baz)).get(0);
+
+        // Check the initial node properties.
+        assertFalse(text.isEditable());
+        assertSame(text.getTextSelectionStart(), -1);
+        assertSame(text.getTextSelectionEnd(), -1);
+
+        // Set the cursor position.
+        getInstrumentation().getUiAutomation().executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                Bundle arguments = new Bundle();
+                arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT, 4);
+                arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT, 4);
+                assertTrue(text.performAction(
+                        AccessibilityNodeInfo.ACTION_SET_SELECTION, arguments));
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return (event.getEventType()
+                        == AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED);
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Refresh the node.
+        AccessibilityNodeInfo refreshedText = getInstrumentation().getUiAutomation()
+                .getRootInActiveWindow().findAccessibilityNodeInfosByText(
+                        getString(R.string.foo_bar_baz)).get(0);
+
+        // Check the related node properties.
+        assertFalse(refreshedText.isEditable());
+        assertSame(refreshedText.getTextSelectionStart(), 4);
+        assertSame(refreshedText.getTextSelectionEnd(), 4);
+
+        // Try to set to an invalid cursor position.
+        Bundle arguments = new Bundle();
+        arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT, 4);
+        arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT, 5);
+        assertFalse(text.performAction(
+                AccessibilityNodeInfo.ACTION_SET_SELECTION, arguments));
+
+        // Refresh the node.
+        refreshedText = getInstrumentation().getUiAutomation()
+                .getRootInActiveWindow().findAccessibilityNodeInfosByText(
+                        getString(R.string.foo_bar_baz)).get(0);
+
+        // Check the related node properties.
+        assertFalse(refreshedText.isEditable());
+        assertSame(refreshedText.getTextSelectionStart(), 4);
+        assertSame(refreshedText.getTextSelectionEnd(), 4);
+    }
+
+    private AccessibilityEvent performMovementActionAndGetEvent(final AccessibilityNodeInfo target,
+            final int action, final int granularity, final boolean extendSelection)
+            throws Exception {
+        final Bundle arguments = new Bundle();
+        arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT,
+                granularity);
+        if (extendSelection) {
+            arguments.putBoolean(
+                    AccessibilityNodeInfo.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN, true);
+        }
+        Runnable performActionRunnable = new Runnable() {
+            @Override
+            public void run() {
+                target.performAction(action, arguments);
+            }
+        };
+        UiAutomation.AccessibilityEventFilter filter = new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                boolean isMovementEvent = event.getEventType()
+                        == AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY;
+                boolean actionMatches = event.getAction() == action;
+                boolean packageMatches =
+                        event.getPackageName().equals(getActivity().getPackageName());
+                boolean granularityMatches = event.getMovementGranularity() == granularity;
+                return isMovementEvent && actionMatches && packageMatches && granularityMatches;
+            }
+        };
+        return getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(performActionRunnable, filter, TIMEOUT_ASYNC_PROCESSING);
+    }
+}
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityViewTreeReportingActivity.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityViewTreeReportingActivity.java
new file mode 100644
index 0000000..c28e7e8
--- /dev/null
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityViewTreeReportingActivity.java
@@ -0,0 +1,35 @@
+/**
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 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.accessibilityservice.cts;
+
+import android.os.Bundle;
+
+import android.accessibilityservice.cts.R;
+
+/**
+ * Activity for testing the accessibility focus APIs exposed to
+ * accessibility services. These APIs allow moving accessibility
+ * focus in the view tree from an AccessiiblityService. Specifically,
+ * this activity is for verifying the hierarchical movement of the
+ * accessibility focus.
+ */
+public class AccessibilityViewTreeReportingActivity extends AccessibilityTestActivity {
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.accessibility_view_tree_reporting_test);
+    }
+}
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityViewTreeReportingTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityViewTreeReportingTest.java
new file mode 100644
index 0000000..a292e4e
--- /dev/null
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityViewTreeReportingTest.java
@@ -0,0 +1,304 @@
+/**
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 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.accessibilityservice.cts;
+
+import android.accessibilityservice.AccessibilityServiceInfo;
+import android.app.UiAutomation;
+import android.content.Context;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.View;
+import android.view.accessibility.AccessibilityNodeInfo;
+
+import android.accessibilityservice.cts.R;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+
+/**
+ * Test cases for testing the accessibility focus APIs exposed to accessibility
+ * services. This test checks how the view hierarchy is reported to accessibility
+ * services.
+ */
+public class AccessibilityViewTreeReportingTest
+        extends AccessibilityActivityTestCase<AccessibilityViewTreeReportingActivity>{
+
+    public AccessibilityViewTreeReportingTest() {
+        super(AccessibilityViewTreeReportingActivity.class);
+    }
+
+    @MediumTest
+    public void testDescendantsOfNotImportantViewReportedInOrder1() throws Exception {
+        UiAutomation uiAutomation = getUiAutomation(false);
+        AccessibilityNodeInfo firstFrameLayout =
+                getNodeByText(uiAutomation, R.string.firstFrameLayout);
+        assertNotNull(firstFrameLayout);
+        assertSame(3, firstFrameLayout.getChildCount());
+
+        // Check if the first child is the right one.
+        AccessibilityNodeInfo firstTextView = getNodeByText(uiAutomation, R.string.firstTextView);
+        assertEquals(firstTextView, firstFrameLayout.getChild(0));
+
+        // Check if the second child is the right one.
+        AccessibilityNodeInfo firstEditText = getNodeByText(uiAutomation, R.string.firstEditText);
+        assertEquals(firstEditText, firstFrameLayout.getChild(1));
+
+        // Check if the third child is the right one.
+        AccessibilityNodeInfo firstButton = getNodeByText(uiAutomation, R.string.firstButton);
+        assertEquals(firstButton, firstFrameLayout.getChild(2));
+    }
+
+    @MediumTest
+    public void testDescendantsOfNotImportantViewReportedInOrder2() throws Exception {
+        UiAutomation uiAutomation = getUiAutomation(false);
+        AccessibilityNodeInfo secondFrameLayout =
+                getNodeByText(uiAutomation, R.string.secondFrameLayout);
+        assertNotNull(secondFrameLayout);
+        assertSame(3, secondFrameLayout.getChildCount());
+
+        // Check if the first child is the right one.
+        AccessibilityNodeInfo secondTextView = getNodeByText(uiAutomation, R.string.secondTextView);
+        assertEquals(secondTextView, secondFrameLayout.getChild(0));
+
+        // Check if the second child is the right one.
+        AccessibilityNodeInfo secondEditText = getNodeByText(uiAutomation, R.string.secondEditText);
+        assertEquals(secondEditText, secondFrameLayout.getChild(1));
+
+        // Check if the third child is the right one.
+        AccessibilityNodeInfo secondButton = getNodeByText(uiAutomation, R.string.secondButton);
+        assertEquals(secondButton, secondFrameLayout.getChild(2));
+    }
+
+    @MediumTest
+    public void testDescendantsOfNotImportantViewReportedInOrder3() throws Exception {
+        UiAutomation uiAutomation = getUiAutomation(false);
+        AccessibilityNodeInfo rootLinearLayout =
+                getNodeByText(uiAutomation, R.string.rootLinearLayout);
+        assertNotNull(rootLinearLayout);
+        assertSame(4, rootLinearLayout.getChildCount());
+
+        // Check if the first child is the right one.
+        AccessibilityNodeInfo firstFrameLayout =
+                getNodeByText(uiAutomation, R.string.firstFrameLayout);
+        assertEquals(firstFrameLayout, rootLinearLayout.getChild(0));
+
+        // Check if the second child is the right one.
+        AccessibilityNodeInfo secondTextView = getNodeByText(uiAutomation, R.string.secondTextView);
+        assertEquals(secondTextView, rootLinearLayout.getChild(1));
+
+        // Check if the third child is the right one.
+        AccessibilityNodeInfo secondEditText = getNodeByText(uiAutomation, R.string.secondEditText);
+        assertEquals(secondEditText, rootLinearLayout.getChild(2));
+
+        // Check if the fourth child is the right one.
+        AccessibilityNodeInfo secondButton = getNodeByText(uiAutomation, R.string.secondButton);
+        assertEquals(secondButton, rootLinearLayout.getChild(3));
+    }
+
+    @MediumTest
+    public void testDrawingOrderInImportantParentFollowsXmlOrder() throws Exception {
+        getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                getActivity().findViewById(R.id.firstLinearLayout)
+                        .setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
+            }
+        });
+
+        UiAutomation uiAutomation = getUiAutomation(false);
+        AccessibilityNodeInfo firstTextView = getNodeByText(uiAutomation, R.string.firstTextView);
+        AccessibilityNodeInfo firstEditText = getNodeByText(uiAutomation, R.string.firstEditText);
+        AccessibilityNodeInfo firstButton = getNodeByText(uiAutomation, R.string.firstButton);
+
+        // Drawing order is: firstTextView, firstEditText, firstButton
+        assertTrue(firstTextView.getDrawingOrder() < firstEditText.getDrawingOrder());
+        assertTrue(firstEditText.getDrawingOrder() < firstButton.getDrawingOrder());
+
+        // Confirm that obtaining copies doesn't change our results
+        AccessibilityNodeInfo copyOfFirstEditText = AccessibilityNodeInfo.obtain(firstEditText);
+        assertTrue(firstTextView.getDrawingOrder() < copyOfFirstEditText.getDrawingOrder());
+        assertTrue(copyOfFirstEditText.getDrawingOrder() < firstButton.getDrawingOrder());
+    }
+
+    @MediumTest
+    public void testDrawingOrderGettingAllViewsFollowsXmlOrder() throws Exception {
+        UiAutomation uiAutomation = getUiAutomation(true);
+        AccessibilityNodeInfo firstTextView = getNodeByText(uiAutomation, R.string.firstTextView);
+        AccessibilityNodeInfo firstEditText = getNodeByText(uiAutomation, R.string.firstEditText);
+        AccessibilityNodeInfo firstButton = getNodeByText(uiAutomation, R.string.firstButton);
+
+        // Drawing order is: firstTextView, firstEditText, firstButton
+        assertTrue(firstTextView.getDrawingOrder() < firstEditText.getDrawingOrder());
+        assertTrue(firstEditText.getDrawingOrder() < firstButton.getDrawingOrder());
+    }
+
+    @MediumTest
+    public void testDrawingOrderWithZCoordsDrawsHighestZLast() throws Exception {
+        getInstrumentation().runOnMainSync(new Runnable() {
+           @Override
+           public void run() {
+               AccessibilityViewTreeReportingActivity activity = getActivity();
+               activity.findViewById(R.id.firstTextView).setZ(50);
+               activity.findViewById(R.id.firstEditText).setZ(100);
+           }
+        });
+
+        UiAutomation uiAutomation = getUiAutomation(true);
+        AccessibilityNodeInfo firstTextView = getNodeByText(uiAutomation, R.string.firstTextView);
+        AccessibilityNodeInfo firstEditText = getNodeByText(uiAutomation, R.string.firstEditText);
+        AccessibilityNodeInfo firstButton = getNodeByText(uiAutomation, R.string.firstButton);
+
+        // Drawing order is firstButton (no z), firstTextView (z=50), firstEditText (z=100)
+        assertTrue(firstButton.getDrawingOrder() < firstTextView.getDrawingOrder());
+        assertTrue(firstTextView.getDrawingOrder() < firstEditText.getDrawingOrder());
+    }
+
+    @MediumTest
+    public void testDrawingOrderWithCustomDrawingOrder() throws Exception {
+        getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                // Reorganize the hiearchy to replace firstLinearLayout with one that allows us to
+                // control the draw order
+                AccessibilityViewTreeReportingActivity activity = getActivity();
+                LinearLayout rootLinearLayout =
+                        (LinearLayout) activity.findViewById(R.id.rootLinearLayout);
+                LinearLayout firstLinearLayout =
+                        (LinearLayout) activity.findViewById(R.id.firstLinearLayout);
+                View firstTextView = activity.findViewById(R.id.firstTextView);
+                View firstEditText = activity.findViewById(R.id.firstEditText);
+                View firstButton = activity.findViewById(R.id.firstButton);
+                firstLinearLayout.removeAllViews();
+                LinearLayoutWithDrawingOrder layoutWithDrawingOrder =
+                        new LinearLayoutWithDrawingOrder(activity);
+                rootLinearLayout.addView(layoutWithDrawingOrder);
+                layoutWithDrawingOrder.addView(firstTextView);
+                layoutWithDrawingOrder.addView(firstEditText);
+                layoutWithDrawingOrder.addView(firstButton);
+                layoutWithDrawingOrder.childDrawingOrder = new int[] {2, 0, 1};
+            }
+        });
+
+        UiAutomation uiAutomation = getUiAutomation(true);
+        AccessibilityNodeInfo firstTextView = getNodeByText(uiAutomation, R.string.firstTextView);
+        AccessibilityNodeInfo firstEditText = getNodeByText(uiAutomation, R.string.firstEditText);
+        AccessibilityNodeInfo firstButton = getNodeByText(uiAutomation, R.string.firstButton);
+
+        // Drawing order is firstEditText, firstButton, firstTextView
+        assertTrue(firstEditText.getDrawingOrder() < firstButton.getDrawingOrder());
+        assertTrue(firstButton.getDrawingOrder() < firstTextView.getDrawingOrder());
+    }
+
+    @MediumTest
+    public void testDrawingOrderWithNotImportantSiblingConsidersItsChildren() throws Exception {
+        getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                // Make the first frame layout a higher Z so it's drawn last
+                getActivity().findViewById(R.id.firstFrameLayout).setZ(100);
+            }
+        });
+        UiAutomation uiAutomation = getUiAutomation(false);
+        AccessibilityNodeInfo secondTextView = getNodeByText(uiAutomation, R.string.secondTextView);
+        AccessibilityNodeInfo secondEditText = getNodeByText(uiAutomation, R.string.secondEditText);
+        AccessibilityNodeInfo secondButton = getNodeByText(uiAutomation, R.string.secondButton);
+        AccessibilityNodeInfo firstFrameLayout =
+                getNodeByText(uiAutomation, R.string.firstFrameLayout);
+        assertTrue(secondTextView.getDrawingOrder() < firstFrameLayout.getDrawingOrder());
+        assertTrue(secondEditText.getDrawingOrder() < firstFrameLayout.getDrawingOrder());
+        assertTrue(secondButton.getDrawingOrder() < firstFrameLayout.getDrawingOrder());
+    }
+
+    @MediumTest
+    public void testDrawingOrderWithNotImportantParentConsidersParentSibling() throws Exception {
+        UiAutomation uiAutomation = getUiAutomation(false);
+        AccessibilityNodeInfo firstFrameLayout =
+                getNodeByText(uiAutomation, R.string.firstFrameLayout);
+        AccessibilityNodeInfo secondTextView = getNodeByText(uiAutomation, R.string.secondTextView);
+        AccessibilityNodeInfo secondEditText = getNodeByText(uiAutomation, R.string.secondEditText);
+        AccessibilityNodeInfo secondButton = getNodeByText(uiAutomation, R.string.secondButton);
+
+        assertTrue(secondTextView.getDrawingOrder() > firstFrameLayout.getDrawingOrder());
+        assertTrue(secondEditText.getDrawingOrder() > firstFrameLayout.getDrawingOrder());
+        assertTrue(secondButton.getDrawingOrder() > firstFrameLayout.getDrawingOrder());
+    }
+
+    @MediumTest
+    public void testDrawingOrderRootNodeHasIndex0() throws Exception {
+        assertEquals(0, getUiAutomation(false).getRootInActiveWindow().getDrawingOrder());
+    }
+
+    @MediumTest
+    public void testAccessibilityImportanceReportingForImportantView() throws Exception {
+        getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                // Manually control importance for firstButton
+                AccessibilityViewTreeReportingActivity activity = getActivity();
+                View firstButton = activity.findViewById(R.id.firstButton);
+                firstButton.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
+            }
+        });
+
+        UiAutomation uiAutomation = getUiAutomation(true);
+        AccessibilityNodeInfo firstButtonNode = getNodeByText(uiAutomation, R.string.firstButton);
+        assertTrue(firstButtonNode.isImportantForAccessibility());
+    }
+
+    @MediumTest
+    public void testAccessibilityImportanceReportingForUnimportantView() throws Exception {
+        getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                // Manually control importance for firstButton
+                AccessibilityViewTreeReportingActivity activity = getActivity();
+                View firstButton = activity.findViewById(R.id.firstButton);
+                firstButton.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
+            }
+        });
+
+        UiAutomation uiAutomation = getUiAutomation(true);
+        AccessibilityNodeInfo firstButtonNode = getNodeByText(uiAutomation, R.string.firstButton);
+        assertFalse(firstButtonNode.isImportantForAccessibility());
+    }
+
+    private UiAutomation getUiAutomation(boolean getNonImportantViews) {
+        UiAutomation uiAutomation = getInstrumentation().getUiAutomation();
+        AccessibilityServiceInfo serviceInfo = uiAutomation.getServiceInfo();
+        serviceInfo.flags &= ~AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS;
+        serviceInfo.flags |= getNonImportantViews ?
+                AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS : 0;
+        uiAutomation.setServiceInfo(serviceInfo);
+        return uiAutomation;
+    }
+
+    private AccessibilityNodeInfo getNodeByText(UiAutomation uiAutomation, int stringId) {
+        return uiAutomation.getRootInActiveWindow()
+                .findAccessibilityNodeInfosByText(getString(stringId)).get(0);
+    }
+
+    class LinearLayoutWithDrawingOrder extends LinearLayout {
+        public int[] childDrawingOrder;
+        LinearLayoutWithDrawingOrder(Context context) {
+            super(context);
+            setChildrenDrawingOrderEnabled(true);
+        }
+
+        @Override
+        protected int getChildDrawingOrder(int childCount, int i) {
+            return childDrawingOrder[i];
+        }
+    }
+}
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowQueryActivity.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowQueryActivity.java
new file mode 100644
index 0000000..9070a81
--- /dev/null
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowQueryActivity.java
@@ -0,0 +1,64 @@
+/**
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 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.accessibilityservice.cts;
+
+import android.os.Bundle;
+import android.view.View;
+
+import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
+import android.accessibilityservice.cts.R;
+
+/**
+ * Activity for testing the accessibility APIs for querying of
+ * the screen content. These APIs allow exploring the screen and
+ * requesting an action to be performed on a given view from an
+ * AccessibilityService.
+ */
+public class AccessibilityWindowQueryActivity extends AccessibilityTestActivity {
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.query_window_test);
+
+        findViewById(R.id.button5).setOnClickListener(new View.OnClickListener() {
+            public void onClick(View v) {
+                /* do nothing */
+            }
+        });
+        findViewById(R.id.button5).setOnLongClickListener(new View.OnLongClickListener() {
+            public boolean onLongClick(View v) {
+                return true;
+            }
+        });
+
+        findViewById(R.id.button5).setAccessibilityDelegate(new View.AccessibilityDelegate() {
+            @Override
+            public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
+                super.onInitializeAccessibilityNodeInfo(host, info);
+                info.addAction(new AccessibilityAction(R.id.foo_custom_action, "Foo"));
+            }
+
+            @Override
+            public boolean performAccessibilityAction(View host, int action, Bundle args) {
+                if (action == R.id.foo_custom_action) {
+                    return true;
+                }
+                return super.performAccessibilityAction(host, action, args);
+            }
+        });
+    }
+}
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowQueryTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowQueryTest.java
new file mode 100755
index 0000000..d328916
--- /dev/null
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowQueryTest.java
@@ -0,0 +1,947 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.accessibilityservice.cts;
+
+import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLEAR_FOCUS;
+import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLEAR_SELECTION;
+import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLICK;
+import static android.view.accessibility.AccessibilityNodeInfo.ACTION_FOCUS;
+import static android.view.accessibility.AccessibilityNodeInfo.ACTION_LONG_CLICK;
+import static android.view.accessibility.AccessibilityNodeInfo.ACTION_SELECT;
+
+import android.accessibilityservice.AccessibilityService;
+import android.accessibilityservice.AccessibilityServiceInfo;
+import android.app.UiAutomation;
+import android.graphics.Rect;
+import android.os.SystemClock;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.Gravity;
+import android.view.Window;
+import android.view.WindowManager;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
+import android.view.accessibility.AccessibilityWindowInfo;
+
+import android.widget.Button;
+import android.accessibilityservice.cts.R;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Queue;
+import java.util.concurrent.TimeoutException;
+
+/**
+ * Test cases for testing the accessibility APIs for querying of the screen content.
+ * These APIs allow exploring the screen and requesting an action to be performed
+ * on a given view from an AccessibilityService.
+ */
+public class AccessibilityWindowQueryTest
+        extends AccessibilityActivityTestCase<AccessibilityWindowQueryActivity> {
+
+    private static final long TIMEOUT_WINDOW_STATE_IDLE = 500;
+
+    public AccessibilityWindowQueryTest() {
+        super(AccessibilityWindowQueryActivity.class);
+    }
+
+    @MediumTest
+    public void testFindByText() throws Exception {
+        // find a view by text
+        List<AccessibilityNodeInfo> buttons = getInstrumentation().getUiAutomation()
+                .getRootInActiveWindow().findAccessibilityNodeInfosByText("b");
+        assertEquals(9, buttons.size());
+    }
+
+    @MediumTest
+    public void testFindByContentDescription() throws Exception {
+        // find a view by text
+        AccessibilityNodeInfo button = getInstrumentation().getUiAutomation()
+                .getRootInActiveWindow().findAccessibilityNodeInfosByText(
+                        getString(R.string.contentDescription)).get(0);
+        assertNotNull(button);
+    }
+
+    @MediumTest
+    public void testTraverseWindow() throws Exception {
+        verifyNodesInAppWindow(getInstrumentation().getUiAutomation().getRootInActiveWindow());
+    }
+
+    @MediumTest
+    public void testNoWindowsAccessIfFlagNotSet() throws Exception {
+        // Make sure the windows cannot be accessed.
+        UiAutomation uiAutomation = getInstrumentation().getUiAutomation();
+        assertTrue(uiAutomation.getWindows().isEmpty());
+
+        // Find a button to click on.
+        final AccessibilityNodeInfo button1 = uiAutomation.getRootInActiveWindow()
+                .findAccessibilityNodeInfosByViewId(
+                        "android.accessibilityservice.cts:id/button1").get(0);
+
+        // Argh...
+        final List<AccessibilityEvent> events = new ArrayList<AccessibilityEvent>();
+
+        // Click the button.
+        uiAutomation.executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                button1.performAction(AccessibilityNodeInfo.ACTION_CLICK);
+            }
+        },
+        new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_CLICKED) {
+                    events.add(event);
+                    return true;
+                }
+                return false;
+            }
+        },
+        TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure the source window cannot be accessed.
+        AccessibilityEvent event = events.get(0);
+        assertNull(event.getSource().getWindow());
+    }
+
+    @MediumTest
+    public void testTraverseAllWindows() throws Exception {
+        setAccessInteractiveWindowsFlag();
+        try {
+            UiAutomation uiAutomation = getInstrumentation().getUiAutomation();
+
+            List<AccessibilityWindowInfo> windows = uiAutomation.getWindows();
+            Rect boundsInScreen = new Rect();
+
+            final int windowCount = windows.size();
+            for (int i = 0; i < windowCount; i++) {
+                AccessibilityWindowInfo window = windows.get(i);
+
+                window.getBoundsInScreen(boundsInScreen);
+                assertFalse(boundsInScreen.isEmpty()); // Varies on screen size, emptiness check.
+                assertNull(window.getParent());
+                assertSame(0, window.getChildCount());
+                assertNull(window.getParent());
+                assertNotNull(window.getRoot());
+
+                if (window.getType() == AccessibilityWindowInfo.TYPE_APPLICATION) {
+                    assertTrue(window.isFocused());
+                    assertTrue(window.isActive());
+                    verifyNodesInAppWindow(window.getRoot());
+                } else if (window.getType() == AccessibilityWindowInfo.TYPE_SYSTEM) {
+                    assertFalse(window.isFocused());
+                    assertFalse(window.isActive());
+                }
+            }
+        } finally {
+            clearAccessInteractiveWindowsFlag();
+        }
+    }
+
+    @MediumTest
+    public void testTraverseWindowFromEvent() throws Exception {
+        setAccessInteractiveWindowsFlag();
+        try {
+            UiAutomation uiAutomation = getInstrumentation().getUiAutomation();
+
+            // Find a button to click on.
+            final AccessibilityNodeInfo button1 = uiAutomation.getRootInActiveWindow()
+                    .findAccessibilityNodeInfosByViewId(
+                            "android.accessibilityservice.cts:id/button1").get(0);
+
+            // Argh...
+            final List<AccessibilityEvent> events = new ArrayList<AccessibilityEvent>();
+
+            // Click the button.
+            uiAutomation.executeAndWaitForEvent(new Runnable() {
+                @Override
+                public void run() {
+                    button1.performAction(AccessibilityNodeInfo.ACTION_CLICK);
+                }
+            },
+            new UiAutomation.AccessibilityEventFilter() {
+                @Override
+                public boolean accept(AccessibilityEvent event) {
+                    if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_CLICKED) {
+                        events.add(event);
+                        return true;
+                    }
+                    return false;
+                }
+            },
+            TIMEOUT_ASYNC_PROCESSING);
+
+            // Get the source window.
+            AccessibilityEvent event = events.get(0);
+            AccessibilityWindowInfo window = event.getSource().getWindow();
+
+            // Verify the application window.
+            Rect boundsInScreen = new Rect();
+            window.getBoundsInScreen(boundsInScreen);
+            assertFalse(boundsInScreen.isEmpty()); // Varies on screen size, so just emptiness check.
+            assertSame(window.getType(), AccessibilityWindowInfo.TYPE_APPLICATION);
+            assertTrue(window.isFocused());
+            assertTrue(window.isActive());
+            assertNull(window.getParent());
+            assertSame(0, window.getChildCount());
+            assertNotNull(window.getRoot());
+
+            // Verify the window content.
+            verifyNodesInAppWindow(window.getRoot());
+        } finally {
+            clearAccessInteractiveWindowsFlag();
+        }
+    }
+
+    @MediumTest
+    public void testInteractWithAppWindow() throws Exception {
+        setAccessInteractiveWindowsFlag();
+        try {
+            UiAutomation uiAutomation = getInstrumentation().getUiAutomation();
+
+            // Find a button to click on.
+            final AccessibilityNodeInfo button1 = uiAutomation.getRootInActiveWindow()
+                    .findAccessibilityNodeInfosByViewId(
+                            "android.accessibilityservice.cts:id/button1").get(0);
+
+            // Argh...
+            final List<AccessibilityEvent> events = new ArrayList<AccessibilityEvent>();
+
+            // Click the button.
+            uiAutomation.executeAndWaitForEvent(new Runnable() {
+                @Override
+                public void run() {
+                    button1.performAction(AccessibilityNodeInfo.ACTION_CLICK);
+                }
+            },
+            new UiAutomation.AccessibilityEventFilter() {
+                @Override
+                public boolean accept(AccessibilityEvent event) {
+                    if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_CLICKED) {
+                        events.add(event);
+                        return true;
+                    }
+                    return false;
+                }
+            },
+            TIMEOUT_ASYNC_PROCESSING);
+
+            // Get the source window.
+            AccessibilityEvent event = events.get(0);
+            AccessibilityWindowInfo window = event.getSource().getWindow();
+
+            // Find a another button from the event's window.
+            final AccessibilityNodeInfo button2 = window.getRoot()
+                    .findAccessibilityNodeInfosByViewId(
+                            "android.accessibilityservice.cts:id/button2").get(0);
+
+            // Click the second button.
+            uiAutomation.executeAndWaitForEvent(new Runnable() {
+                @Override
+                public void run() {
+                    button2.performAction(AccessibilityNodeInfo.ACTION_CLICK);
+                }
+            },
+            new UiAutomation.AccessibilityEventFilter() {
+                @Override
+                public boolean accept(AccessibilityEvent event) {
+                    return event.getEventType() == AccessibilityEvent.TYPE_VIEW_CLICKED;
+                }
+            },
+            TIMEOUT_ASYNC_PROCESSING);
+        } finally {
+            clearAccessInteractiveWindowsFlag();
+        }
+    }
+
+    @MediumTest
+    public void testSingleAccessibilityFocusAcrossWindows() throws Exception {
+        setAccessInteractiveWindowsFlag();
+        try {
+            // Add two more windows.
+            addTwoAppPanelWindows();
+
+            // Put accessibility focus in the first app window.
+            ensureAppWindowFocusedOrFail(0);
+            // Make sure there only one accessibility focus.
+            assertSingleAccessibilityFocus();
+
+            // Put accessibility focus in the second app window.
+            ensureAppWindowFocusedOrFail(1);
+            // Make sure there only one accessibility focus.
+            assertSingleAccessibilityFocus();
+
+            // Put accessibility focus in the third app window.
+            ensureAppWindowFocusedOrFail(2);
+            // Make sure there only one accessibility focus.
+            assertSingleAccessibilityFocus();
+        } finally {
+            ensureAccessibilityFocusCleared();
+            clearAccessInteractiveWindowsFlag();
+        }
+    }
+
+    @MediumTest
+    public void testPerformActionFocus() throws Exception {
+        // find a view and make sure it is not focused
+        AccessibilityNodeInfo button = getInstrumentation().getUiAutomation()
+                .getRootInActiveWindow().findAccessibilityNodeInfosByText(
+                        getString(R.string.button5)).get(0);
+        assertFalse(button.isFocused());
+
+        // focus the view
+        assertTrue(button.performAction(ACTION_FOCUS));
+
+        // find the view again and make sure it is focused
+        button = getInstrumentation().getUiAutomation().getRootInActiveWindow()
+                .findAccessibilityNodeInfosByText(getString(R.string.button5)).get(0);
+        assertTrue(button.isFocused());
+    }
+
+    @MediumTest
+    public void testPerformActionClearFocus() throws Exception {
+        // find a view and make sure it is not focused
+        AccessibilityNodeInfo button = getInstrumentation().getUiAutomation()
+                .getRootInActiveWindow().findAccessibilityNodeInfosByText(
+                        getString(R.string.button5)).get(0);
+        assertFalse(button.isFocused());
+
+        // focus the view
+        assertTrue(button.performAction(ACTION_FOCUS));
+
+        // find the view again and make sure it is focused
+        button = getInstrumentation().getUiAutomation().getRootInActiveWindow()
+                .findAccessibilityNodeInfosByText(getString(R.string.button5)).get(0);
+        assertTrue(button.isFocused());
+
+        // unfocus the view
+        assertTrue(button.performAction(ACTION_CLEAR_FOCUS));
+
+        // find the view again and make sure it is not focused
+        button = getInstrumentation().getUiAutomation().getRootInActiveWindow()
+                .findAccessibilityNodeInfosByText(getString(R.string.button5)).get(0);
+        assertFalse(button.isFocused());
+    }
+
+    @MediumTest
+    public void testPerformActionSelect() throws Exception {
+        // find a view and make sure it is not selected
+        AccessibilityNodeInfo button = getInstrumentation().getUiAutomation()
+                .getRootInActiveWindow().findAccessibilityNodeInfosByText(
+                        getString(R.string.button5)).get(0);
+        assertFalse(button.isSelected());
+
+        // select the view
+        assertTrue(button.performAction(ACTION_SELECT));
+
+        // find the view again and make sure it is selected
+        button = getInstrumentation().getUiAutomation().getRootInActiveWindow()
+                .findAccessibilityNodeInfosByText(getString(R.string.button5)).get(0);
+        assertTrue(button.isSelected());
+    }
+
+    @MediumTest
+    public void testPerformActionClearSelection() throws Exception {
+        // find a view and make sure it is not selected
+        AccessibilityNodeInfo button = getInstrumentation().getUiAutomation()
+                .getRootInActiveWindow().findAccessibilityNodeInfosByText(
+                        getString(R.string.button5)).get(0);
+        assertFalse(button.isSelected());
+
+        // select the view
+        assertTrue(button.performAction(ACTION_SELECT));
+
+        // find the view again and make sure it is selected
+        button = getInstrumentation().getUiAutomation().getRootInActiveWindow()
+                .findAccessibilityNodeInfosByText(getString(R.string.button5)).get(0);
+
+        assertTrue(button.isSelected());
+
+        // unselect the view
+        assertTrue(button.performAction(ACTION_CLEAR_SELECTION));
+
+        // find the view again and make sure it is not selected
+        button = getInstrumentation().getUiAutomation().getRootInActiveWindow()
+                .findAccessibilityNodeInfosByText(getString(R.string.button5)).get(0);
+        assertFalse(button.isSelected());
+    }
+
+    @MediumTest
+    public void testPerformActionClick() throws Exception {
+        // find a view and make sure it is not selected
+        final AccessibilityNodeInfo button = getInstrumentation().getUiAutomation()
+                .getRootInActiveWindow().findAccessibilityNodeInfosByText(
+                        getString(R.string.button5)).get(0);
+        assertFalse(button.isSelected());
+
+        // Make an action and wait for an event.
+        AccessibilityEvent expected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                button.performAction(ACTION_CLICK);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return (event.getEventType() == AccessibilityEvent.TYPE_VIEW_CLICKED);
+            }
+        },
+        TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure the expected event was received.
+        assertNotNull(expected);
+    }
+
+    @MediumTest
+    public void testPerformActionLongClick() throws Exception {
+        // find a view and make sure it is not selected
+        final AccessibilityNodeInfo button = getInstrumentation().getUiAutomation()
+                .getRootInActiveWindow().findAccessibilityNodeInfosByText(
+                        getString(R.string.button5)).get(0);
+        assertFalse(button.isSelected());
+
+        // Make an action and wait for an event.
+        AccessibilityEvent expected = getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                button.performAction(ACTION_LONG_CLICK);
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return (event.getEventType() == AccessibilityEvent.TYPE_VIEW_LONG_CLICKED);
+            }
+        },
+        TIMEOUT_ASYNC_PROCESSING);
+
+        // Make sure the expected event was received.
+        assertNotNull(expected);
+    }
+
+
+    @MediumTest
+    public void testPerformCustomAction() throws Exception {
+        // find a view and make sure it is not selected
+        AccessibilityNodeInfo button = getInstrumentation().getUiAutomation()
+                .getRootInActiveWindow().findAccessibilityNodeInfosByText(
+                        getString(R.string.button5)).get(0);
+
+        // find the custom action and perform it
+        List<AccessibilityAction> actions = button.getActionList();
+        final int actionCount = actions.size();
+        for (int i = 0; i < actionCount; i++) {
+            AccessibilityAction action = actions.get(i);
+            if (action.getId() == R.id.foo_custom_action) {
+                assertSame(action.getLabel(), "Foo");
+                // perform the action
+                assertTrue(button.performAction(action.getId()));
+                return;
+            }
+        }
+    }
+
+    @MediumTest
+    public void testGetEventSource() throws Exception {
+        // find a view and make sure it is not focused
+        final AccessibilityNodeInfo button = getInstrumentation().getUiAutomation()
+                .getRootInActiveWindow().findAccessibilityNodeInfosByText(
+                        getString(R.string.button5)).get(0);
+        assertFalse(button.isSelected());
+
+        // focus and wait for the event
+        AccessibilityEvent awaitedEvent = getInstrumentation().getUiAutomation()
+            .executeAndWaitForEvent(
+                new Runnable() {
+            @Override
+            public void run() {
+                assertTrue(button.performAction(ACTION_FOCUS));
+            }
+        },
+                new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return (event.getEventType() == AccessibilityEvent.TYPE_VIEW_FOCUSED);
+            }
+        },
+        TIMEOUT_ASYNC_PROCESSING);
+
+        assertNotNull(awaitedEvent);
+
+        // check that last event source
+        AccessibilityNodeInfo source = awaitedEvent.getSource();
+        assertNotNull(source);
+
+        // bounds
+        Rect buttonBounds = new Rect();
+        button.getBoundsInParent(buttonBounds);
+        Rect sourceBounds = new Rect();
+        source.getBoundsInParent(sourceBounds);
+
+        assertEquals(buttonBounds.left, sourceBounds.left);
+        assertEquals(buttonBounds.right, sourceBounds.right);
+        assertEquals(buttonBounds.top, sourceBounds.top);
+        assertEquals(buttonBounds.bottom, sourceBounds.bottom);
+
+        // char sequence attributes
+        assertEquals(button.getPackageName(), source.getPackageName());
+        assertEquals(button.getClassName(), source.getClassName());
+        assertEquals(button.getText().toString(), source.getText().toString());
+        assertSame(button.getContentDescription(), source.getContentDescription());
+
+        // boolean attributes
+        assertSame(button.isFocusable(), source.isFocusable());
+        assertSame(button.isClickable(), source.isClickable());
+        assertSame(button.isEnabled(), source.isEnabled());
+        assertNotSame(button.isFocused(), source.isFocused());
+        assertSame(button.isLongClickable(), source.isLongClickable());
+        assertSame(button.isPassword(), source.isPassword());
+        assertSame(button.isSelected(), source.isSelected());
+        assertSame(button.isCheckable(), source.isCheckable());
+        assertSame(button.isChecked(), source.isChecked());
+    }
+
+    @MediumTest
+    public void testPerformGlobalActionBack() throws Exception {
+        assertTrue(getInstrumentation().getUiAutomation().performGlobalAction(
+                AccessibilityService.GLOBAL_ACTION_BACK));
+
+        // Sleep a bit so the UI is settles.
+        waitForIdle();
+    }
+
+    @MediumTest
+    public void testPerformGlobalActionHome() throws Exception {
+        assertTrue(getInstrumentation().getUiAutomation().performGlobalAction(
+                AccessibilityService.GLOBAL_ACTION_HOME));
+
+        // Sleep a bit so the UI is settles.
+        waitForIdle();
+    }
+
+    @MediumTest
+    public void testPerformGlobalActionRecents() throws Exception {
+        // Check whether the action succeeded.
+        assertTrue(getInstrumentation().getUiAutomation().performGlobalAction(
+                AccessibilityService.GLOBAL_ACTION_RECENTS));
+
+        // Sleep a bit so the UI is settles.
+        waitForIdle();
+
+        // This is a necessary since the back action does not
+        // dismiss recents until they stop animating. Sigh...
+        SystemClock.sleep(5000);
+
+        // Clean up.
+        getInstrumentation().getUiAutomation().performGlobalAction(
+                AccessibilityService.GLOBAL_ACTION_BACK);
+
+        // Sleep a bit so the UI is settles.
+        waitForIdle();
+    }
+
+    @MediumTest
+    public void testPerformGlobalActionNotifications() throws Exception {
+        // Perform the action under test
+        assertTrue(getInstrumentation().getUiAutomation().performGlobalAction(
+                AccessibilityService.GLOBAL_ACTION_NOTIFICATIONS));
+
+        // Sleep a bit so the UI is settles.
+        waitForIdle();
+
+        // Clean up.
+        assertTrue(getInstrumentation().getUiAutomation().performGlobalAction(
+                AccessibilityService.GLOBAL_ACTION_BACK));
+
+        // Sleep a bit so the UI is settles.
+        waitForIdle();
+    }
+
+    @MediumTest
+    public void testPerformGlobalActionQuickSettings() throws Exception {
+        // Check whether the action succeeded.
+        assertTrue(getInstrumentation().getUiAutomation().performGlobalAction(
+                AccessibilityService.GLOBAL_ACTION_QUICK_SETTINGS));
+
+        // Sleep a bit so the UI is settles.
+        waitForIdle();
+
+        // Clean up.
+        getInstrumentation().getUiAutomation().performGlobalAction(
+                AccessibilityService.GLOBAL_ACTION_BACK);
+
+        // Sleep a bit so the UI is settles.
+        waitForIdle();
+    }
+
+    @MediumTest
+    public void testPerformGlobalActionPowerDialog() throws Exception {
+        // Check whether the action succeeded.
+        assertTrue(getInstrumentation().getUiAutomation().performGlobalAction(
+                AccessibilityService.GLOBAL_ACTION_POWER_DIALOG));
+
+        // Sleep a bit so the UI is settles.
+        waitForIdle();
+
+        // Clean up.
+        getInstrumentation().getUiAutomation().performGlobalAction(
+                AccessibilityService.GLOBAL_ACTION_BACK);
+
+        // Sleep a bit so the UI is settles.
+        waitForIdle();
+    }
+
+    @MediumTest
+    public void testObjectContract() throws Exception {
+        try {
+            AccessibilityServiceInfo info = getInstrumentation().getUiAutomation().getServiceInfo();
+            info.flags |= AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS;
+            getInstrumentation().getUiAutomation().setServiceInfo(info);
+
+            // find a view and make sure it is not focused
+            AccessibilityNodeInfo button = getInstrumentation().getUiAutomation()
+                    .getRootInActiveWindow().findAccessibilityNodeInfosByText(
+                            getString(R.string.button5)).get(0);
+            AccessibilityNodeInfo parent = button.getParent();
+            final int childCount = parent.getChildCount();
+            for (int i = 0; i < childCount; i++) {
+                AccessibilityNodeInfo child = parent.getChild(i);
+                assertNotNull(child);
+                if (child.equals(button)) {
+                    assertEquals("Equal objects must have same hasCode.", button.hashCode(),
+                            child.hashCode());
+                    return;
+                }
+            }
+            fail("Parent's children do not have the info whose parent is the parent.");
+        } finally {
+            AccessibilityServiceInfo info = getInstrumentation().getUiAutomation().getServiceInfo();
+            info.flags &= ~AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS;
+            getInstrumentation().getUiAutomation().setServiceInfo(info);
+        }
+    }
+
+    @MediumTest
+    public void testWindowDockAndUndock_dividerWindowAppearsAndDisappears() throws Exception {
+        setAccessInteractiveWindowsFlag();
+        final UiAutomation uiAutomation = getInstrumentation().getUiAutomation();
+        assertFalse(isDividerWindowPresent(uiAutomation));
+        Runnable toggleSplitScreenRunnable = new Runnable() {
+            @Override
+            public void run() {
+                assertTrue(uiAutomation.performGlobalAction(
+                        AccessibilityService.GLOBAL_ACTION_TOGGLE_SPLIT_SCREEN));
+            }
+        };
+        UiAutomation.AccessibilityEventFilter windowsChangedFilter =
+                new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return (event.getEventType() == AccessibilityEvent.TYPE_WINDOWS_CHANGED);
+            }
+        };
+
+        uiAutomation.executeAndWaitForEvent(toggleSplitScreenRunnable, windowsChangedFilter,
+                TIMEOUT_ASYNC_PROCESSING);
+        waitForIdle();
+        assertTrue(isDividerWindowPresent(uiAutomation));
+        uiAutomation.executeAndWaitForEvent(toggleSplitScreenRunnable, windowsChangedFilter,
+                TIMEOUT_ASYNC_PROCESSING);
+        waitForIdle();
+        assertFalse(isDividerWindowPresent(uiAutomation));
+    }
+
+    private boolean isDividerWindowPresent(UiAutomation uiAutomation) {
+        List<AccessibilityWindowInfo> windows = uiAutomation.getWindows();
+        final int windowCount = windows.size();
+        for (int i = 0; i < windowCount; i++) {
+            AccessibilityWindowInfo window = windows.get(i);
+            Rect bounds = new Rect();
+            window.getBoundsInScreen(bounds);
+            if (window.getType() == AccessibilityWindowInfo.TYPE_SPLIT_SCREEN_DIVIDER) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private void assertSingleAccessibilityFocus() {
+        UiAutomation uiAutomation = getInstrumentation().getUiAutomation();
+        List<AccessibilityWindowInfo> windows = uiAutomation.getWindows();
+        AccessibilityWindowInfo focused = null;
+
+        final int windowCount = windows.size();
+        for (int i = 0; i < windowCount; i++) {
+            AccessibilityWindowInfo window = windows.get(i);
+
+            if (window.isAccessibilityFocused()) {
+                if (focused == null) {
+                    focused = window;
+
+                    AccessibilityNodeInfo root = window.getRoot();
+                    assertEquals(uiAutomation.findFocus(
+                            AccessibilityNodeInfo.FOCUS_ACCESSIBILITY), root);
+                    assertEquals(root.findFocus(
+                            AccessibilityNodeInfo.FOCUS_ACCESSIBILITY), root);
+                } else {
+                    throw new AssertionError("Duplicate accessibility focus");
+                }
+            } else {
+                assertNull(window.getRoot().findFocus(
+                        AccessibilityNodeInfo.FOCUS_ACCESSIBILITY));
+            }
+        }
+    }
+
+    private void ensureAppWindowFocusedOrFail(int appWindowIndex) throws TimeoutException {
+        UiAutomation uiAutomation = getInstrumentation().getUiAutomation();
+        List<AccessibilityWindowInfo> windows = uiAutomation.getWindows();
+        AccessibilityWindowInfo focusTareget = null;
+
+        int visitedAppWindows = -1;
+        final int windowCount = windows.size();
+        for (int i = 0; i < windowCount; i++) {
+            AccessibilityWindowInfo window = windows.get(i);
+            if (window.getType() == AccessibilityWindowInfo.TYPE_APPLICATION) {
+                visitedAppWindows++;
+                if (appWindowIndex <= visitedAppWindows) {
+                    focusTareget = window;
+                    break;
+                }
+            }
+        }
+
+        if (focusTareget == null) {
+            throw new IllegalStateException("Couldn't find app window: " + appWindowIndex);
+        }
+
+        if (focusTareget.isAccessibilityFocused()) {
+            return;
+        }
+
+        final AccessibilityWindowInfo finalFocusTarget = focusTareget;
+        uiAutomation.executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                assertTrue(finalFocusTarget.getRoot().performAction(
+                        AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS));
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return event.getEventType() == AccessibilityEvent.TYPE_WINDOWS_CHANGED;
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        windows = uiAutomation.getWindows();
+        for (int i = 0; i < windowCount; i++) {
+            AccessibilityWindowInfo window = windows.get(i);
+            if (window.getId() == focusTareget.getId()) {
+                assertTrue(window.isAccessibilityFocused());
+                break;
+            }
+        }
+    }
+
+    private void addTwoAppPanelWindows() throws TimeoutException {
+        final UiAutomation uiAutomation = getInstrumentation().getUiAutomation();
+
+        uiAutomation.waitForIdle(TIMEOUT_WINDOW_STATE_IDLE, TIMEOUT_ASYNC_PROCESSING);
+
+        // Add the first window.
+        uiAutomation.executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                getInstrumentation().runOnMainSync(new Runnable() {
+                    @Override
+                    public void run() {
+                        WindowManager.LayoutParams params = new WindowManager.LayoutParams();
+                        params.gravity = Gravity.TOP;
+                        params.y = getStatusBarHeight();
+                        params.width = WindowManager.LayoutParams.MATCH_PARENT;
+                        params.height = WindowManager.LayoutParams.WRAP_CONTENT;
+                        params.flags = WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
+                                | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR
+                                | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+                                | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
+                        params.type = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
+                        params.token = getActivity().getWindow().getDecorView().getWindowToken();
+
+                        Button button = new Button(getActivity());
+                        button.setText(R.string.button1);
+                        getActivity().getWindowManager().addView(button, params);
+                    }
+                });
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return event.getEventType() == AccessibilityEvent.TYPE_WINDOWS_CHANGED;
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+
+        // Add the second window.
+        uiAutomation.executeAndWaitForEvent(new Runnable() {
+            @Override
+            public void run() {
+                getInstrumentation().runOnMainSync(new Runnable() {
+                    @Override
+                    public void run() {
+                        WindowManager.LayoutParams params = new WindowManager.LayoutParams();
+                        params.gravity = Gravity.BOTTOM;
+                        params.width = WindowManager.LayoutParams.MATCH_PARENT;
+                        params.height = WindowManager.LayoutParams.WRAP_CONTENT;
+                        params.flags = WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
+                                | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR
+                                | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+                                | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
+                        params.type = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
+                        params.token = getActivity().getWindow().getDecorView().getWindowToken();
+
+                        Button button = new Button(getActivity());
+                        button.setText(R.string.button2);
+                        getActivity().getWindowManager().addView(button, params);
+                    }
+                });
+            }
+        }, new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                return event.getEventType() == AccessibilityEvent.TYPE_WINDOWS_CHANGED;
+            }
+        }, TIMEOUT_ASYNC_PROCESSING);
+    }
+
+    private int getStatusBarHeight() {
+        final Rect rect = new Rect();
+        Window window = getActivity().getWindow();
+        window.getDecorView().getWindowVisibleDisplayFrame(rect);
+        return rect.top;
+    }
+
+    private void setAccessInteractiveWindowsFlag () {
+        UiAutomation uiAutomation = getInstrumentation().getUiAutomation();
+        AccessibilityServiceInfo info = uiAutomation.getServiceInfo();
+        info.flags |= AccessibilityServiceInfo.FLAG_RETRIEVE_INTERACTIVE_WINDOWS;
+        uiAutomation.setServiceInfo(info);
+    }
+
+    private void clearAccessInteractiveWindowsFlag () {
+        UiAutomation uiAutomation = getInstrumentation().getUiAutomation();
+        AccessibilityServiceInfo info = uiAutomation.getServiceInfo();
+        info.flags &= ~AccessibilityServiceInfo.FLAG_RETRIEVE_INTERACTIVE_WINDOWS;
+        uiAutomation.setServiceInfo(info);
+    }
+
+    private void ensureAccessibilityFocusCleared() {
+        try {
+            final UiAutomation uiAutomation = getInstrumentation().getUiAutomation();
+            uiAutomation.executeAndWaitForEvent(new Runnable() {
+                @Override
+                public void run() {
+                    List<AccessibilityWindowInfo> windows = uiAutomation.getWindows();
+                    final int windowCount = windows.size();
+                    for (int i = 0; i < windowCount; i++) {
+                        AccessibilityWindowInfo window = windows.get(i);
+                        if (window.isAccessibilityFocused()) {
+                            window.getRoot().performAction(
+                                    AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS);
+                        }
+                    }
+                }
+            }, new UiAutomation.AccessibilityEventFilter() {
+                @Override
+                public boolean accept(AccessibilityEvent event) {
+                    return event.getEventType() ==
+                            AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED;
+                }
+            }, TIMEOUT_ASYNC_PROCESSING);
+        } catch (TimeoutException te) {
+            /* ignore */
+        }
+    }
+
+    private void verifyNodesInAppWindow(AccessibilityNodeInfo root) throws Exception {
+        try {
+            AccessibilityServiceInfo info = getInstrumentation().getUiAutomation().getServiceInfo();
+            info.flags |= AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS;
+            getInstrumentation().getUiAutomation().setServiceInfo(info);
+
+            root.refresh();
+
+            // make list of expected nodes
+            List<String> classNameAndTextList = new ArrayList<String>();
+            classNameAndTextList.add("android.widget.LinearLayout");
+            classNameAndTextList.add("android.widget.LinearLayout");
+            classNameAndTextList.add("android.widget.LinearLayout");
+            classNameAndTextList.add("android.widget.LinearLayout");
+            classNameAndTextList.add("android.widget.ButtonB1");
+            classNameAndTextList.add("android.widget.ButtonB2");
+            classNameAndTextList.add("android.widget.ButtonB3");
+            classNameAndTextList.add("android.widget.ButtonB4");
+            classNameAndTextList.add("android.widget.ButtonB5");
+            classNameAndTextList.add("android.widget.ButtonB6");
+            classNameAndTextList.add("android.widget.ButtonB7");
+            classNameAndTextList.add("android.widget.ButtonB8");
+            classNameAndTextList.add("android.widget.ButtonB9");
+
+            String contentViewIdResName = "android.accessibilityservice.cts:id/added_content";
+            boolean verifyContent = false;
+
+            Queue<AccessibilityNodeInfo> fringe = new LinkedList<AccessibilityNodeInfo>();
+            fringe.add(root);
+
+            // do a BFS traversal and check nodes
+            while (!fringe.isEmpty()) {
+                AccessibilityNodeInfo current = fringe.poll();
+
+                if (!verifyContent
+                        && contentViewIdResName.equals(current.getViewIdResourceName())) {
+                    verifyContent = true;
+                }
+
+                if (verifyContent) {
+                    CharSequence text = current.getText();
+                    String receivedClassNameAndText = current.getClassName().toString()
+                            + ((text != null) ? text.toString() : "");
+                    String expectedClassNameAndText = classNameAndTextList.remove(0);
+
+                    assertEquals("Did not get the expected node info",
+                            expectedClassNameAndText, receivedClassNameAndText);
+                }
+
+                final int childCount = current.getChildCount();
+                for (int i = 0; i < childCount; i++) {
+                    AccessibilityNodeInfo child = current.getChild(i);
+                    fringe.add(child);
+                }
+            }
+        } finally {
+            AccessibilityServiceInfo info = getInstrumentation().getUiAutomation().getServiceInfo();
+            info.flags &= ~AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS;
+            getInstrumentation().getUiAutomation().setServiceInfo(info);
+        }
+    }
+
+    @Override
+    protected void scrubClass(Class<?> testCaseClass) {
+        /* intentionally do not scrub */
+    }
+}
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowReportingActivity.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowReportingActivity.java
new file mode 100644
index 0000000..d17a285
--- /dev/null
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowReportingActivity.java
@@ -0,0 +1,28 @@
+/**
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 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.accessibilityservice.cts;
+
+import android.os.Bundle;
+
+/**
+ * Activity used by ActivityWindowReportingTest
+ */
+public class AccessibilityWindowReportingActivity extends AccessibilityTestActivity {
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.accessibility_window_reporting_test);
+    }
+}
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowReportingTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowReportingTest.java
new file mode 100644
index 0000000..3fee77c
--- /dev/null
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowReportingTest.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.accessibilityservice.cts;
+
+import android.accessibilityservice.AccessibilityServiceInfo;
+import android.app.UiAutomation;
+import android.text.TextUtils;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityWindowInfo;
+import android.widget.ArrayAdapter;
+import android.widget.AutoCompleteTextView;
+
+import java.util.List;
+import java.util.concurrent.TimeoutException;
+
+/**
+ * Tests that AccessibilityWindowInfos are properly populated
+ */
+public class AccessibilityWindowReportingTest
+        extends AccessibilityActivityTestCase<AccessibilityWindowReportingActivity> {
+    UiAutomation mUiAutomation;
+
+    public AccessibilityWindowReportingTest() {
+        super(AccessibilityWindowReportingActivity.class);
+    }
+
+    public void setUp() throws Exception {
+        super.setUp();
+        mUiAutomation = getInstrumentation().getUiAutomation();
+        AccessibilityServiceInfo info = mUiAutomation.getServiceInfo();
+        info.flags |= AccessibilityServiceInfo.FLAG_RETRIEVE_INTERACTIVE_WINDOWS;
+        mUiAutomation.setServiceInfo(info);
+    }
+
+    public void tearDown() throws Exception {
+        mUiAutomation.destroy();
+        super.tearDown();
+    }
+
+    public void testWindowTitle_getTitleReturnsTitle() {
+        AccessibilityWindowInfo window = findWindowByTitle(getActivity().getTitle());
+        assertNotNull("Window title not reported to accessibility", window);
+        window.recycle();
+    }
+
+    public void testGetAnchorForDropDownForAutoCompleteTextView_returnsTextViewNode() {
+        final AutoCompleteTextView autoCompleteTextView =
+                (AutoCompleteTextView) getActivity().findViewById(R.id.autoCompleteLayout);
+        AccessibilityNodeInfo autoCompleteTextInfo = mUiAutomation.getRootInActiveWindow()
+                .findAccessibilityNodeInfosByViewId(
+                        "android.accessibilityservice.cts:id/autoCompleteLayout")
+                .get(0);
+
+        // For the drop-down
+        final String[] COUNTRIES = new String[] {"Belgium", "France", "Italy", "Germany", "Spain"};
+
+        try {
+            mUiAutomation.executeAndWaitForEvent(new Runnable() {
+                @Override
+                public void run() {
+                    getInstrumentation().runOnMainSync(new Runnable() {
+                        @Override
+                        public void run() {
+                            ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(),
+                                    android.R.layout.simple_dropdown_item_1line, COUNTRIES);
+                            autoCompleteTextView.setAdapter(adapter);
+                            autoCompleteTextView.showDropDown();
+                        }
+                    });
+                }
+            }, new UiAutomation.AccessibilityEventFilter() {
+                @Override
+                public boolean accept(AccessibilityEvent event) {
+                    return event.getEventType() == AccessibilityEvent.TYPE_WINDOWS_CHANGED;
+                }
+            }, TIMEOUT_ASYNC_PROCESSING);
+        } catch (TimeoutException exception) {
+            throw new RuntimeException(
+                    "Failed to get window changed event when showing dropdown", exception);
+        }
+
+        // Find the pop-up window
+        boolean foundPopup = false;
+        List<AccessibilityWindowInfo> windows = mUiAutomation.getWindows();
+        for (int i = 0; i < windows.size(); i++) {
+            AccessibilityWindowInfo window = windows.get(i);
+            if (window.getAnchor() == null) {
+                continue;
+            }
+            assertEquals(autoCompleteTextInfo, window.getAnchor());
+            assertFalse("Found multiple pop-ups anchored to one text view", foundPopup);
+            foundPopup = true;
+        }
+        assertTrue("Failed to find accessibility window for auto-complete pop-up", foundPopup);
+    }
+
+    private AccessibilityWindowInfo findWindowByTitle(CharSequence title) {
+        List<AccessibilityWindowInfo> windows = mUiAutomation.getWindows();
+        AccessibilityWindowInfo returnValue = null;
+        for (int i = 0; i < windows.size(); i++) {
+            AccessibilityWindowInfo window = windows.get(i);
+            if (TextUtils.equals(title, window.getTitle())) {
+                returnValue = window;
+            } else {
+                window.recycle();
+            }
+        }
+        return returnValue;
+    }
+}
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/GestureDescriptionTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/GestureDescriptionTest.java
new file mode 100644
index 0000000..b3fa9d2
--- /dev/null
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/GestureDescriptionTest.java
@@ -0,0 +1,185 @@
+/**
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 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.accessibilityservice.cts;
+
+import android.accessibilityservice.GestureDescription;
+import android.graphics.Path;
+import android.graphics.PathMeasure;
+import android.test.InstrumentationTestCase;
+
+/**
+ * Tests for creating gesture descriptions.
+ */
+public class GestureDescriptionTest extends InstrumentationTestCase {
+    static final int NOMINAL_PATH_DURATION = 100;
+    private Path mNominalPath;
+
+    @Override
+    public void setUp() {
+        mNominalPath = new Path();
+        mNominalPath.moveTo(0, 0);
+        mNominalPath.lineTo(10, 10);
+    }
+
+    public void testCreateStroke_noDuration_shouldThrow() {
+        try {
+            new GestureDescription.StrokeDescription(mNominalPath, 0, 0);
+            fail("Missing exception for stroke with no duration.");
+        } catch (IllegalArgumentException e) {
+        }
+    }
+
+    public void testCreateStroke_negativeStartTime_shouldThrow() {
+        try {
+            new GestureDescription.StrokeDescription(mNominalPath, -1, NOMINAL_PATH_DURATION);
+            fail("Missing exception for stroke with negative start time.");
+        } catch (IllegalArgumentException e) {
+        }
+    }
+
+    public void testCreateStroke_negativeStartX_shouldThrow() {
+        Path negativeStartXPath = new Path();
+        negativeStartXPath.moveTo(-1, 0);
+        negativeStartXPath.lineTo(10, 10);
+        try {
+            new GestureDescription.StrokeDescription(negativeStartXPath, 0, NOMINAL_PATH_DURATION);
+            fail("Missing exception for stroke with negative start x coord.");
+        } catch (IllegalArgumentException e) {
+        }
+    }
+
+    public void testCreateStroke_negativeStartY_shouldThrow() {
+        Path negativeStartYPath = new Path();
+        negativeStartYPath.moveTo(0, -1);
+        negativeStartYPath.lineTo(10, 10);
+        try {
+            new GestureDescription.StrokeDescription(negativeStartYPath, 0, NOMINAL_PATH_DURATION);
+            fail("Missing exception for stroke with negative start y coord.");
+        } catch (IllegalArgumentException e) {
+        }
+    }
+
+    public void testCreateStroke_negativeEndX_shouldThrow() {
+        Path negativeEndXPath = new Path();
+        negativeEndXPath.moveTo(0, 0);
+        negativeEndXPath.lineTo(-10, 10);
+        try {
+            new GestureDescription.StrokeDescription(negativeEndXPath, 0, NOMINAL_PATH_DURATION);
+            fail("Missing exception for stroke with negative end x coord.");
+        } catch (IllegalArgumentException e) {
+        }
+    }
+
+    public void testCreateStroke_negativeEndY_shouldThrow() {
+        Path negativeEndYPath = new Path();
+        negativeEndYPath.moveTo(0, 0);
+        negativeEndYPath.lineTo(10, -10);
+        try {
+            new GestureDescription.StrokeDescription(negativeEndYPath, 0, NOMINAL_PATH_DURATION);
+            fail("Missing exception for stroke with negative end y coord.");
+        } catch (IllegalArgumentException e) {
+        }
+    }
+
+    public void testCreateStroke_pathWithZeroLength_shouldThrow() {
+        Path zeroLengthPath = new Path();
+        zeroLengthPath.moveTo(0, 0);
+        zeroLengthPath.lineTo(0, 0);
+        try {
+            new GestureDescription.StrokeDescription(zeroLengthPath, 0, NOMINAL_PATH_DURATION);
+            fail("Missing exception for stroke with path of zero length.");
+        } catch (IllegalArgumentException e) {
+        }
+    }
+
+    public void testCreateStroke_pathWithMultipleContours_shouldThrow() {
+        Path multiContourPath = new Path();
+        multiContourPath.moveTo(0, 0);
+        multiContourPath.lineTo(10, 10);
+        multiContourPath.moveTo(20, 0);
+        multiContourPath.lineTo(20, 10);
+        try {
+            new GestureDescription.StrokeDescription(multiContourPath, 0, NOMINAL_PATH_DURATION);
+            fail("Missing exception for stroke with multi-contour path.");
+        } catch (IllegalArgumentException e) {
+        }
+    }
+
+    public void testAddStroke_allowUpToMaxPaths() {
+        GestureDescription.Builder gestureBuilder = new GestureDescription.Builder();
+        for (int i = 0; i < GestureDescription.getMaxStrokeCount(); i++) {
+            Path path = new Path();
+            path.moveTo(i, i);
+            path.lineTo(10 + i, 10 + i);
+            gestureBuilder.addStroke(
+                    new GestureDescription.StrokeDescription(path, 0, NOMINAL_PATH_DURATION));
+        }
+        Path path = new Path();
+        path.moveTo(10, 10);
+        path.lineTo(20, 20);
+        try {
+            gestureBuilder.addStroke(
+                    new GestureDescription.StrokeDescription(path, 0, NOMINAL_PATH_DURATION));
+            fail("Missing exception for adding too many strokes.");
+        } catch (RuntimeException e) {
+        }
+    }
+
+    public void testAddStroke_withDurationTooLong_shouldThrow() {
+        Path path = new Path();
+        path.moveTo(10, 10);
+        path.lineTo(20, 20);
+        GestureDescription.Builder gestureBuilder = new GestureDescription.Builder();
+        try {
+            gestureBuilder.addStroke(new GestureDescription.StrokeDescription(
+                    path, 0, GestureDescription.getMaxGestureDuration() + 1));
+            fail("Missing exception for adding stroke with duration too long.");
+        } catch (RuntimeException e) {
+        }
+    }
+
+    public void testEmptyDescription_shouldThrow() {
+        GestureDescription.Builder gestureBuilder = new GestureDescription.Builder();
+        try {
+            gestureBuilder.build();
+            fail("Missing exception for building an empty gesture.");
+        } catch (RuntimeException e) {
+        }
+    }
+
+    public void testStrokeDescriptionGetters_workAsExpected() {
+        int x = 100;
+        int startY = 100;
+        int endY = 150;
+        int start = 50;
+        int duration = 100;
+        Path path = new Path();
+        path.moveTo(x, startY);
+        path.lineTo(x, endY);
+        GestureDescription.StrokeDescription strokeDescription = new GestureDescription.StrokeDescription(path, start, duration);
+        GestureDescription.Builder builder = new GestureDescription.Builder();
+        builder.addStroke(strokeDescription);
+
+        GestureDescription gesture = builder.build();
+
+        assertEquals(1, gesture.getStrokeCount());
+        strokeDescription = gesture.getStroke(0);
+        assertEquals(start, strokeDescription.getStartTime());
+        assertEquals(duration, strokeDescription.getDuration());
+        Path returnedPath = strokeDescription.getPath();
+        PathMeasure measure = new PathMeasure(returnedPath, false);
+        assertEquals(50, (int) measure.getLength());
+    }
+}
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/InstrumentedAccessibilityService.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/InstrumentedAccessibilityService.java
new file mode 100644
index 0000000..99efb2c
--- /dev/null
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/InstrumentedAccessibilityService.java
@@ -0,0 +1,181 @@
+package android.accessibilityservice.cts;
+
+import android.accessibilityservice.AccessibilityService;
+import android.accessibilityservice.AccessibilityServiceInfo;
+import android.content.Context;
+import android.os.Handler;
+import android.os.SystemClock;
+import android.provider.Settings;
+import android.test.InstrumentationTestCase;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityManager;
+
+import java.lang.ref.WeakReference;
+import java.util.HashMap;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
+public class InstrumentedAccessibilityService extends AccessibilityService {
+    // Match com.android.server.accessibility.AccessibilityManagerService#COMPONENT_NAME_SEPARATOR
+    private static final String COMPONENT_NAME_SEPARATOR = ":";
+
+    private static final int TIMEOUT_SERVICE_ENABLE = 10000;
+    private static final int TIMEOUT_SERVICE_PERFORM_SYNC = 5000;
+
+    private static final HashMap<Class, WeakReference<InstrumentedAccessibilityService>>
+            sInstances = new HashMap<>();
+
+    private final Handler mHandler = new Handler();
+
+    @Override
+    protected void onServiceConnected() {
+        synchronized (sInstances) {
+            sInstances.put(getClass(), new WeakReference<>(this));
+            sInstances.notifyAll();
+        }
+    }
+
+    @Override
+    public void onDestroy() {
+        synchronized (sInstances) {
+            sInstances.remove(getClass());
+        }
+    }
+
+    @Override
+    public void onAccessibilityEvent(AccessibilityEvent event) {
+        // Stub method.
+    }
+
+    @Override
+    public void onInterrupt() {
+        // Stub method.
+    }
+
+    public void runOnServiceSync(Runnable runner) {
+        final SyncRunnable sr = new SyncRunnable(runner, TIMEOUT_SERVICE_PERFORM_SYNC);
+        mHandler.post(sr);
+        assertTrue("Timed out waiting for runOnServiceSync()", sr.waitForComplete());
+    }
+
+    private static final class SyncRunnable implements Runnable {
+        private final CountDownLatch mLatch = new CountDownLatch(1);
+        private final Runnable mTarget;
+        private final long mTimeout;
+
+        public SyncRunnable(Runnable target, long timeout) {
+            mTarget = target;
+            mTimeout = timeout;
+        }
+
+        public void run() {
+            mTarget.run();
+            mLatch.countDown();
+        }
+
+        public boolean waitForComplete() {
+            try {
+                return mLatch.await(mTimeout, TimeUnit.MILLISECONDS);
+            } catch (InterruptedException e) {
+                return false;
+            }
+        }
+    }
+
+    protected static <T extends InstrumentedAccessibilityService> T enableService(
+            InstrumentationTestCase testCase, Class<T> clazz) {
+        final String serviceName = clazz.getSimpleName();
+        final Context context = testCase.getInstrumentation().getContext();
+        final String enabledServices = Settings.Secure.getString(
+                context.getContentResolver(),
+                Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
+        if (enabledServices != null) {
+            assertFalse("Service is already enabled", enabledServices.contains(serviceName));
+        }
+
+        final AccessibilityManager manager = (AccessibilityManager) context.getSystemService(
+                Context.ACCESSIBILITY_SERVICE);
+        final List<AccessibilityServiceInfo> serviceInfos =
+                manager.getInstalledAccessibilityServiceList();
+        for (AccessibilityServiceInfo serviceInfo : serviceInfos) {
+            final String serviceId = serviceInfo.getId();
+            if (serviceId.endsWith(serviceName)) {
+                ShellCommandBuilder.create(testCase)
+                        .putSecureSetting(Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
+                                enabledServices + COMPONENT_NAME_SEPARATOR + serviceId)
+                        .putSecureSetting(Settings.Secure.ACCESSIBILITY_ENABLED, "1")
+                        .run();
+
+                final T instance = getInstanceForClass(clazz, TIMEOUT_SERVICE_ENABLE);
+                if (instance == null) {
+                    throw new RuntimeException("Starting accessibility service " + serviceName
+                            + " took longer than " + TIMEOUT_SERVICE_ENABLE + "ms");
+                }
+                return instance;
+            }
+        }
+        throw new RuntimeException("Accessibility service " + serviceName + " not found");
+    }
+
+    private static <T extends InstrumentedAccessibilityService> T getInstanceForClass(Class clazz,
+            long timeoutMillis) {
+        final long timeoutTimeMillis = SystemClock.uptimeMillis() + timeoutMillis;
+        while (SystemClock.uptimeMillis() < timeoutTimeMillis) {
+            synchronized (sInstances) {
+                final WeakReference<InstrumentedAccessibilityService> ref = sInstances.get(clazz);
+                if (ref != null) {
+                    final T instance = (T) ref.get();
+                    if (instance == null) {
+                        sInstances.remove(clazz);
+                    } else {
+                        return instance;
+                    }
+                }
+                try {
+                    sInstances.wait(timeoutTimeMillis - SystemClock.uptimeMillis());
+                } catch (InterruptedException e) {
+                    return null;
+                }
+            }
+        }
+        return null;
+    }
+
+    public static void disableAllServices(InstrumentationTestCase testCase) {
+        final Object waitLockForA11yOff = new Object();
+        final Context context = testCase.getInstrumentation().getContext();
+        final AccessibilityManager manager =
+                (AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE);
+        manager.addAccessibilityStateChangeListener(b -> {
+            synchronized (waitLockForA11yOff) {
+                waitLockForA11yOff.notifyAll();
+            }
+        });
+
+        ShellCommandBuilder.create(testCase)
+                .deleteSecureSetting(Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES)
+                .deleteSecureSetting(Settings.Secure.ACCESSIBILITY_ENABLED)
+                .run();
+
+        final long timeoutTimeMillis = SystemClock.uptimeMillis() + TIMEOUT_SERVICE_ENABLE;
+        while (SystemClock.uptimeMillis() < timeoutTimeMillis) {
+            synchronized (waitLockForA11yOff) {
+                if (manager.getEnabledAccessibilityServiceList(
+                        AccessibilityServiceInfo.FEEDBACK_ALL_MASK).isEmpty()) {
+                    return;
+                }
+                try {
+                    waitLockForA11yOff.wait(timeoutTimeMillis - SystemClock.uptimeMillis());
+                } catch (InterruptedException e) {
+                    // Ignored; loop again
+                }
+            }
+        }
+        throw new RuntimeException("Disabling all accessibility services took longer than "
+                + TIMEOUT_SERVICE_ENABLE + "ms");
+    }
+}
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/ShellCommandBuilder.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/ShellCommandBuilder.java
new file mode 100644
index 0000000..1ad55fc
--- /dev/null
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/ShellCommandBuilder.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.accessibilityservice.cts;
+
+import android.app.UiAutomation;
+import android.os.ParcelFileDescriptor;
+import android.test.InstrumentationTestCase;
+
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+import java.util.LinkedList;
+
+public class ShellCommandBuilder {
+    private final LinkedList<String> mCommands = new LinkedList<>();
+
+    private final InstrumentationTestCase mTestCase;
+
+    public static ShellCommandBuilder create(InstrumentationTestCase testCase) {
+        return new ShellCommandBuilder(testCase);
+    }
+
+    private ShellCommandBuilder(InstrumentationTestCase testCase) {
+        mTestCase = testCase;
+    }
+
+    public void run() {
+        final UiAutomation automation = mTestCase.getInstrumentation().getUiAutomation(
+                UiAutomation.FLAG_DONT_SUPPRESS_ACCESSIBILITY_SERVICES);
+        for (String command : mCommands) {
+            execShellCommand(automation, command);
+        }
+    }
+
+    public ShellCommandBuilder deleteSecureSetting(String name) {
+        mCommands.add("settings delete secure " + name);
+        return this;
+    }
+
+    public ShellCommandBuilder putSecureSetting(String name, String value) {
+        mCommands.add("settings put secure " + name + " " + value);
+        return this;
+    }
+
+    public ShellCommandBuilder grantPermission(String packageName, String permission) {
+        mCommands.add("pm grant " + packageName + " " + permission);
+        return this;
+    }
+
+    public ShellCommandBuilder addCommand(String command) {
+        mCommands.add(command);
+        return this;
+    }
+
+    private static void execShellCommand(UiAutomation automation, String command) {
+        try (ParcelFileDescriptor fd = automation.executeShellCommand(command)) {
+            try (InputStream inputStream = new FileInputStream(fd.getFileDescriptor())) {
+                try (BufferedReader reader = new BufferedReader(
+                        new InputStreamReader(inputStream, StandardCharsets.UTF_8))) {
+                    while (reader.readLine() != null) {
+                        // Keep reading.
+                    }
+                }
+            }
+        } catch (IOException e) {
+            throw new RuntimeException("Failed to exec shell command", e);
+        }
+    }
+}
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/StubGestureAccessibilityService.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/StubGestureAccessibilityService.java
new file mode 100644
index 0000000..caf5ab3
--- /dev/null
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/StubGestureAccessibilityService.java
@@ -0,0 +1,38 @@
+/**
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 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.accessibilityservice.cts;
+
+import android.accessibilityservice.GestureDescription;
+import android.os.Handler;
+import android.test.InstrumentationTestCase;
+import android.view.accessibility.AccessibilityEvent;
+
+import java.io.IOException;
+
+/**
+ * A stub accessibility service to install for testing gesture dispatch
+ */
+public class StubGestureAccessibilityService extends InstrumentedAccessibilityService {
+
+    public boolean doDispatchGesture(GestureDescription description, GestureResultCallback callback,
+            Handler handler) {
+        return dispatchGesture(description, callback, handler);
+    }
+
+    public static StubGestureAccessibilityService enableSelf(InstrumentationTestCase test) {
+        return InstrumentedAccessibilityService.enableService(
+                test, StubGestureAccessibilityService.class);
+    }
+}
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/StubMagnificationAccessibilityService.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/StubMagnificationAccessibilityService.java
new file mode 100644
index 0000000..e5e1949
--- /dev/null
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/StubMagnificationAccessibilityService.java
@@ -0,0 +1,33 @@
+/**
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 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.accessibilityservice.cts;
+
+import android.accessibilityservice.GestureDescription;
+import android.os.Handler;
+import android.test.InstrumentationTestCase;
+import android.view.accessibility.AccessibilityEvent;
+
+import java.io.IOException;
+
+/**
+ * A stub accessibility service to install for testing gesture dispatch
+ */
+public class StubMagnificationAccessibilityService extends InstrumentedAccessibilityService {
+
+    public static StubMagnificationAccessibilityService enableSelf(InstrumentationTestCase test) {
+        return InstrumentedAccessibilityService.enableService(
+                test, StubMagnificationAccessibilityService.class);
+    }
+}
diff --git a/tests/admin/Android.mk b/tests/admin/Android.mk
new file mode 100644
index 0000000..e12cc94
--- /dev/null
+++ b/tests/admin/Android.mk
@@ -0,0 +1,41 @@
+# Copyright (C) 2011 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
+    ctstestrunner mockito-target platform-test-annotations
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := CtsAdminTestCases
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_INSTRUMENTATION_FOR := CtsAdminApp
+
+LOCAL_CTS_MODULE_CONFIG := $(LOCAL_PATH)/Old$(CTS_MODULE_TEST_CONFIG)
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_PACKAGE)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/admin/AndroidManifest.xml b/tests/admin/AndroidManifest.xml
new file mode 100644
index 0000000..d3467af
--- /dev/null
+++ b/tests/admin/AndroidManifest.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="android.admin.cts">
+
+  <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+  <application>
+      <uses-library android:name="android.test.runner"/>
+  </application>
+
+  <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                   android:targetPackage="android.admin.app"
+                   android:label="Tests for the admin APIs.">
+        <meta-data android:name="listener"
+            android:value="com.android.cts.runner.CtsTestRunListener" />
+    </instrumentation>
+
+</manifest>
diff --git a/tests/admin/AndroidTest.xml b/tests/admin/AndroidTest.xml
new file mode 100644
index 0000000..5d7d99e
--- /dev/null
+++ b/tests/admin/AndroidTest.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for the CTS device admin tests">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsAdminApp.apk" />
+        <option name="test-file-name" value="CtsAdminTestCases.apk" />
+    </target_preparer>
+
+    <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+        <option name="run-command" value="dpm set-active-admin --user cur android.admin.app/.CtsDeviceAdminReceiver" />
+        <option name="run-command" value="dpm set-active-admin --user cur android.admin.app/.CtsDeviceAdminReceiver2" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.admin.cts" />
+        <option name="exclude-filter" value="android.admin.app.DeactivationTest" />
+    </test>
+
+    <!-- Instrument the app to clear the device admins so the apk can be uninstalled -->
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstrumentationPreparer">
+        <option name="apk" value="CtsAdminApp.apk" />
+        <option name="package" value="android.admin.app" />
+        <option name="include-filter" value="android.admin.app.DeactivationTest" />
+        <option name="when" value="after" />
+    </target_preparer>
+</configuration>
\ No newline at end of file
diff --git a/tests/admin/OldAndroidTest.xml b/tests/admin/OldAndroidTest.xml
new file mode 100644
index 0000000..0cfada8
--- /dev/null
+++ b/tests/admin/OldAndroidTest.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="CTS device admin test config">
+    <include name="common-config" />
+    <option name="run-command:run-command" value="dpm set-active-admin --user cur android.admin.app/.CtsDeviceAdminReceiver" />
+    <option name="run-command:run-command" value="dpm set-active-admin --user cur android.admin.app/.CtsDeviceAdminReceiver2" />
+</configuration>
diff --git a/tests/admin/app/Android.mk b/tests/admin/app/Android.mk
new file mode 100644
index 0000000..aac8a89
--- /dev/null
+++ b/tests/admin/app/Android.mk
@@ -0,0 +1,38 @@
+# Copyright (C) 2011 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_JAVA_LIBRARIES := guava
+
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := CtsAdminApp
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_SDK_VERSION := current
+
+LOCAL_DEX_PREOPT := false
+
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/tests/admin/app/AndroidManifest.xml b/tests/admin/app/AndroidManifest.xml
new file mode 100644
index 0000000..0834579
--- /dev/null
+++ b/tests/admin/app/AndroidManifest.xml
@@ -0,0 +1,126 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="android.admin.app">
+    <application>
+
+        <uses-library android:name="android.test.runner"/>
+
+        <receiver android:name="android.admin.app.CtsDeviceAdminDeviceOwner"
+            android:permission="android.permission.BIND_DEVICE_ADMIN">
+            <meta-data android:name="android.app.device_admin"
+                android:resource="@xml/device_admin" />
+            <intent-filter>
+                <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
+            </intent-filter>
+        </receiver>
+
+        <receiver android:name="android.admin.app.CtsDeviceAdminReceiver"
+                android:permission="android.permission.BIND_DEVICE_ADMIN">
+            <meta-data android:name="android.app.device_admin"
+                    android:resource="@xml/device_admin" />
+            <intent-filter>
+                <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
+            </intent-filter>
+        </receiver>
+
+        <receiver android:name="android.admin.app.CtsDeviceAdminReceiver2"
+                android:permission="android.permission.BIND_DEVICE_ADMIN">
+            <meta-data android:name="android.app.device_admin"
+                    android:resource="@xml/device_admin_2" />
+            <intent-filter>
+                <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
+            </intent-filter>
+        </receiver>
+
+        <!-- Device Admin that needs to be in the deactivated state in order
+             for tests to pass. -->
+        <receiver android:name="android.admin.app.CtsDeviceAdminDeactivatedReceiver"
+                android:permission="android.permission.BIND_DEVICE_ADMIN">
+            <meta-data android:name="android.app.device_admin"
+                    android:resource="@xml/device_admin" />
+            <intent-filter>
+                <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
+            </intent-filter>
+        </receiver>
+
+        <!-- Helper Activity used by Device Admin activation tests -->
+        <activity android:name="android.admin.app.CtsDeviceAdminActivationTestActivity"
+                android:label="Device Admin activation test" />
+
+        <!-- Broken device admin: meta-data missing -->
+        <receiver android:name="android.admin.app.CtsDeviceAdminBrokenReceiver"
+                android:permission="android.permission.BIND_DEVICE_ADMIN">
+            <intent-filter>
+                <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
+            </intent-filter>
+        </receiver>
+
+        <!-- Broken device admin: filter doesn't match an Intent with action
+             android.app.action.DEVICE_ADMIN_ENABLED and nothing else (e.g.,
+             data) set -->
+        <receiver android:name="android.admin.app.CtsDeviceAdminBrokenReceiver2"
+                android:permission="android.permission.BIND_DEVICE_ADMIN">
+            <meta-data android:name="android.app.device_admin"
+                    android:resource="@xml/device_admin" />
+            <intent-filter>
+                <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
+                <data android:scheme="https" />
+            </intent-filter>
+        </receiver>
+
+        <!-- Broken device admin: meta-data element doesn't point to valid
+             Device Admin configuration/description -->
+        <receiver android:name="android.admin.app.CtsDeviceAdminBrokenReceiver3"
+                android:permission="android.permission.BIND_DEVICE_ADMIN">
+            <meta-data android:name="android.app.device_admin"
+                    android:resource="@xml/broken_device_admin" />
+            <intent-filter>
+                <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
+            </intent-filter>
+        </receiver>
+
+        <!-- Broken device admin: filter doesn't match Intents with action
+             android.app.action.DEVICE_ADMIN_ENABLED -->
+        <receiver android:name="android.admin.app.CtsDeviceAdminBrokenReceiver4"
+                android:permission="android.permission.BIND_DEVICE_ADMIN">
+            <meta-data android:name="android.app.device_admin"
+                    android:resource="@xml/device_admin" />
+            <intent-filter>
+                <action android:name="android.app.action.DEVICE_ADMIN_DISABLED" />
+            </intent-filter>
+        </receiver>
+
+        <!-- Broken device admin: no intent-filter -->
+        <receiver android:name="android.admin.app.CtsDeviceAdminBrokenReceiver5"
+                android:permission="android.permission.BIND_DEVICE_ADMIN">
+            <meta-data android:name="android.app.device_admin"
+                    android:resource="@xml/device_admin" />
+        </receiver>
+
+    </application>
+
+    <!--  self-instrumenting test package. -->
+    <instrumentation
+        android:name="android.support.test.runner.AndroidJUnitRunner"
+        android:label="Deactivate Admins"
+        android:targetPackage="android.admin.app" >
+    </instrumentation>
+
+</manifest>
diff --git a/tests/deviceadmin/res/xml/broken_device_admin.xml b/tests/admin/app/res/xml/broken_device_admin.xml
similarity index 100%
rename from tests/deviceadmin/res/xml/broken_device_admin.xml
rename to tests/admin/app/res/xml/broken_device_admin.xml
diff --git a/tests/deviceadmin/res/xml/device_admin.xml b/tests/admin/app/res/xml/device_admin.xml
similarity index 100%
rename from tests/deviceadmin/res/xml/device_admin.xml
rename to tests/admin/app/res/xml/device_admin.xml
diff --git a/tests/deviceadmin/res/xml/device_admin_2.xml b/tests/admin/app/res/xml/device_admin_2.xml
similarity index 100%
rename from tests/deviceadmin/res/xml/device_admin_2.xml
rename to tests/admin/app/res/xml/device_admin_2.xml
diff --git a/tests/admin/app/src/android/admin/app/CtsDeviceAdminActivationTestActivity.java b/tests/admin/app/src/android/admin/app/CtsDeviceAdminActivationTestActivity.java
new file mode 100644
index 0000000..9f46949
--- /dev/null
+++ b/tests/admin/app/src/android/admin/app/CtsDeviceAdminActivationTestActivity.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.admin.app;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.WindowManager;
+
+import com.google.common.annotations.VisibleForTesting;
+
+/**
+ * Helper {@link Activity} for CTS tests of Device Admin activation. The {@code Activity}
+ * enables tests to capture the invocations of its {@link #onActivityResult(int, int, Intent)} by
+ * providing a {@link OnActivityResultListener}.
+ */
+public class CtsDeviceAdminActivationTestActivity extends Activity {
+    public interface OnActivityResultListener {
+        void onActivityResult(int requestCode, int resultCode, Intent data);
+    }
+
+    private OnActivityResultListener mOnActivityResultListener;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // Dismiss keyguard and keep screen on while this Activity is displayed.
+        // This is needed because on older platforms, when the keyguard is on, onActivityResult is
+        // not invoked when a Device Admin activation is rejected without user interaction.
+        getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
+                | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
+                | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+    }
+
+    @VisibleForTesting
+    public void setOnActivityResultListener(OnActivityResultListener listener) {
+        mOnActivityResultListener = listener;
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        if (mOnActivityResultListener != null) {
+            mOnActivityResultListener.onActivityResult(requestCode, resultCode, data);
+            return;
+        }
+
+        super.onActivityResult(requestCode, resultCode, data);
+    }
+}
diff --git a/tests/admin/app/src/android/admin/app/CtsDeviceAdminBrokenReceiver.java b/tests/admin/app/src/android/admin/app/CtsDeviceAdminBrokenReceiver.java
new file mode 100644
index 0000000..8aec34a
--- /dev/null
+++ b/tests/admin/app/src/android/admin/app/CtsDeviceAdminBrokenReceiver.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.admin.app;
+
+import android.app.admin.DeviceAdminReceiver;
+
+public class CtsDeviceAdminBrokenReceiver extends DeviceAdminReceiver {
+}
diff --git a/tests/admin/app/src/android/admin/app/CtsDeviceAdminBrokenReceiver2.java b/tests/admin/app/src/android/admin/app/CtsDeviceAdminBrokenReceiver2.java
new file mode 100644
index 0000000..9895716
--- /dev/null
+++ b/tests/admin/app/src/android/admin/app/CtsDeviceAdminBrokenReceiver2.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.admin.app;
+
+import android.app.admin.DeviceAdminReceiver;
+
+public class CtsDeviceAdminBrokenReceiver2 extends DeviceAdminReceiver {
+}
diff --git a/tests/admin/app/src/android/admin/app/CtsDeviceAdminBrokenReceiver3.java b/tests/admin/app/src/android/admin/app/CtsDeviceAdminBrokenReceiver3.java
new file mode 100644
index 0000000..0c6d2cc
--- /dev/null
+++ b/tests/admin/app/src/android/admin/app/CtsDeviceAdminBrokenReceiver3.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.admin.app;
+
+import android.app.admin.DeviceAdminReceiver;
+
+public class CtsDeviceAdminBrokenReceiver3 extends DeviceAdminReceiver {
+}
diff --git a/tests/admin/app/src/android/admin/app/CtsDeviceAdminBrokenReceiver4.java b/tests/admin/app/src/android/admin/app/CtsDeviceAdminBrokenReceiver4.java
new file mode 100644
index 0000000..20229c6
--- /dev/null
+++ b/tests/admin/app/src/android/admin/app/CtsDeviceAdminBrokenReceiver4.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.admin.app;
+
+import android.app.admin.DeviceAdminReceiver;
+
+public class CtsDeviceAdminBrokenReceiver4 extends DeviceAdminReceiver {
+}
diff --git a/tests/admin/app/src/android/admin/app/CtsDeviceAdminBrokenReceiver5.java b/tests/admin/app/src/android/admin/app/CtsDeviceAdminBrokenReceiver5.java
new file mode 100644
index 0000000..709dd86
--- /dev/null
+++ b/tests/admin/app/src/android/admin/app/CtsDeviceAdminBrokenReceiver5.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.admin.app;
+
+import android.app.admin.DeviceAdminReceiver;
+
+public class CtsDeviceAdminBrokenReceiver5 extends DeviceAdminReceiver {
+}
diff --git a/tests/admin/app/src/android/admin/app/CtsDeviceAdminDeactivatedReceiver.java b/tests/admin/app/src/android/admin/app/CtsDeviceAdminDeactivatedReceiver.java
new file mode 100644
index 0000000..fbafe0e
--- /dev/null
+++ b/tests/admin/app/src/android/admin/app/CtsDeviceAdminDeactivatedReceiver.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.admin.app;
+
+import android.app.admin.DeviceAdminReceiver;
+
+public class CtsDeviceAdminDeactivatedReceiver extends DeviceAdminReceiver {
+}
diff --git a/tests/admin/app/src/android/admin/app/CtsDeviceAdminDeviceOwner.java b/tests/admin/app/src/android/admin/app/CtsDeviceAdminDeviceOwner.java
new file mode 100644
index 0000000..619f700
--- /dev/null
+++ b/tests/admin/app/src/android/admin/app/CtsDeviceAdminDeviceOwner.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.admin.app;
+
+import android.app.admin.DeviceAdminReceiver;
+
+public class CtsDeviceAdminDeviceOwner extends DeviceAdminReceiver {
+
+}
diff --git a/tests/admin/app/src/android/admin/app/CtsDeviceAdminReceiver.java b/tests/admin/app/src/android/admin/app/CtsDeviceAdminReceiver.java
new file mode 100644
index 0000000..737111f
--- /dev/null
+++ b/tests/admin/app/src/android/admin/app/CtsDeviceAdminReceiver.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.admin.app;
+
+import android.app.admin.DeviceAdminReceiver;
+
+public class CtsDeviceAdminReceiver extends DeviceAdminReceiver {
+}
diff --git a/tests/admin/app/src/android/admin/app/CtsDeviceAdminReceiver2.java b/tests/admin/app/src/android/admin/app/CtsDeviceAdminReceiver2.java
new file mode 100644
index 0000000..9baf8b0
--- /dev/null
+++ b/tests/admin/app/src/android/admin/app/CtsDeviceAdminReceiver2.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.admin.app;
+
+import android.app.admin.DeviceAdminReceiver;
+
+public class CtsDeviceAdminReceiver2 extends DeviceAdminReceiver {
+}
diff --git a/tests/admin/app/src/android/admin/app/DeactivationTest.java b/tests/admin/app/src/android/admin/app/DeactivationTest.java
new file mode 100644
index 0000000..20bba5c
--- /dev/null
+++ b/tests/admin/app/src/android/admin/app/DeactivationTest.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.admin.app;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.test.AndroidTestCase;
+
+/**
+ * Helper to deactivate Device Admins.
+ */
+public class DeactivationTest extends AndroidTestCase {
+    private static final String PACKAGE = CtsDeviceAdminReceiver.class.getPackage().getName();
+    private static final ComponentName RECEIVER1 = new ComponentName(PACKAGE,
+            CtsDeviceAdminReceiver.class.getName());
+    private static final ComponentName RECEIVER2 = new ComponentName(PACKAGE,
+            CtsDeviceAdminReceiver2.class.getName());
+
+    public void testDeactivateAdmins() throws Exception {
+        DevicePolicyManager manager = (DevicePolicyManager)
+                getContext().getSystemService(Context.DEVICE_POLICY_SERVICE);
+        assertNotNull(manager);
+
+        manager.removeActiveAdmin(RECEIVER1);
+        manager.removeActiveAdmin(RECEIVER2);
+
+        for (int i = 0; i < 1000 && isActive(manager); i++) {
+            try {
+                Thread.sleep(100);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+        }
+        assertFalse(isActive(manager));
+    }
+
+    private boolean isActive(DevicePolicyManager manager) {
+        return manager.isAdminActive(RECEIVER1) ||
+                manager.isAdminActive(RECEIVER2);
+    }
+}
\ No newline at end of file
diff --git a/tests/admin/src/android/admin/cts/DeviceAdminActivationTest.java b/tests/admin/src/android/admin/cts/DeviceAdminActivationTest.java
new file mode 100644
index 0000000..e3b7c4b
--- /dev/null
+++ b/tests/admin/src/android/admin/cts/DeviceAdminActivationTest.java
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.admin.cts;
+
+import android.app.Activity;
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.admin.app.CtsDeviceAdminBrokenReceiver;
+import android.admin.app.CtsDeviceAdminBrokenReceiver2;
+import android.admin.app.CtsDeviceAdminBrokenReceiver3;
+import android.admin.app.CtsDeviceAdminBrokenReceiver4;
+import android.admin.app.CtsDeviceAdminBrokenReceiver5;
+import android.admin.app.CtsDeviceAdminDeactivatedReceiver;
+import android.admin.app.CtsDeviceAdminActivationTestActivity;
+import android.admin.app.CtsDeviceAdminActivationTestActivity.OnActivityResultListener;
+import android.os.SystemClock;
+import android.test.ActivityInstrumentationTestCase2;
+import android.util.Log;
+
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * Tests for the standard way of activating a Device Admin: by starting system UI via an
+ * {@link Intent} with {@link DevicePolicyManager#ACTION_ADD_DEVICE_ADMIN}. The test requires that
+ * the {@code CtsDeviceAdmin.apk} be installed.
+ */
+public class DeviceAdminActivationTest
+    extends ActivityInstrumentationTestCase2<CtsDeviceAdminActivationTestActivity> {
+
+    private static final String TAG = DeviceAdminActivationTest.class.getSimpleName();
+
+    // IMPLEMENTATION NOTE: Because Device Admin activation requires the use of
+    // Activity.startActivityForResult, this test creates an empty Activity which then invokes
+    // startActivityForResult.
+
+    private static final int REQUEST_CODE_ACTIVATE_ADMIN = 1;
+
+    /**
+     * Maximum duration of time (milliseconds) after which the effects of programmatic actions in
+     * this test should have affected the UI.
+     */
+    private static final int UI_EFFECT_TIMEOUT_MILLIS = 5000;
+
+    private boolean mDeviceAdmin;
+    @Mock private OnActivityResultListener mMockOnActivityResultListener;
+
+    public DeviceAdminActivationTest() {
+        super(CtsDeviceAdminActivationTestActivity.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        MockitoAnnotations.initMocks(this);
+        getActivity().setOnActivityResultListener(mMockOnActivityResultListener);
+        mDeviceAdmin = getInstrumentation().getContext().getPackageManager().hasSystemFeature(
+                PackageManager.FEATURE_DEVICE_ADMIN);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        try {
+            finishActivateDeviceAdminActivity();
+        } finally {
+            super.tearDown();
+        }
+    }
+
+    public void testActivateGoodReceiverDisplaysActivationUi() throws Exception {
+        if (!mDeviceAdmin) {
+            Log.w(TAG, "Skipping testActivateGoodReceiverDisplaysActivationUi");
+            return;
+        }
+        assertDeviceAdminDeactivated(CtsDeviceAdminDeactivatedReceiver.class);
+        startAddDeviceAdminActivityForResult(CtsDeviceAdminDeactivatedReceiver.class);
+        assertWithTimeoutOnActivityResultNotInvoked();
+        // The UI is up and running. Assert that dismissing the UI returns the corresponding result
+        // to the test activity.
+        finishActivateDeviceAdminActivity();
+        assertWithTimeoutOnActivityResultInvokedWithResultCode(Activity.RESULT_CANCELED);
+        assertDeviceAdminDeactivated(CtsDeviceAdminDeactivatedReceiver.class);
+    }
+
+    public void testActivateBrokenReceiverFails() throws Exception {
+        if (!mDeviceAdmin) {
+            Log.w(TAG, "Skipping testActivateBrokenReceiverFails");
+            return;
+        }
+        assertDeviceAdminDeactivated(CtsDeviceAdminBrokenReceiver.class);
+        startAddDeviceAdminActivityForResult(CtsDeviceAdminBrokenReceiver.class);
+        assertWithTimeoutOnActivityResultInvokedWithResultCode(Activity.RESULT_CANCELED);
+        assertDeviceAdminDeactivated(CtsDeviceAdminBrokenReceiver.class);
+    }
+
+    public void testActivateBrokenReceiver2Fails() throws Exception {
+        if (!mDeviceAdmin) {
+            Log.w(TAG, "Skipping testActivateBrokenReceiver2Fails");
+            return;
+        }
+        assertDeviceAdminDeactivated(CtsDeviceAdminBrokenReceiver2.class);
+        startAddDeviceAdminActivityForResult(CtsDeviceAdminBrokenReceiver2.class);
+        assertWithTimeoutOnActivityResultInvokedWithResultCode(Activity.RESULT_CANCELED);
+        assertDeviceAdminDeactivated(CtsDeviceAdminBrokenReceiver2.class);
+    }
+
+    public void testActivateBrokenReceiver3Fails() throws Exception {
+        if (!mDeviceAdmin) {
+            Log.w(TAG, "Skipping testActivateBrokenReceiver3Fails");
+            return;
+        }
+        assertDeviceAdminDeactivated(CtsDeviceAdminBrokenReceiver3.class);
+        startAddDeviceAdminActivityForResult(CtsDeviceAdminBrokenReceiver3.class);
+        assertWithTimeoutOnActivityResultInvokedWithResultCode(Activity.RESULT_CANCELED);
+        assertDeviceAdminDeactivated(CtsDeviceAdminBrokenReceiver3.class);
+    }
+
+    public void testActivateBrokenReceiver4Fails() throws Exception {
+        if (!mDeviceAdmin) {
+            Log.w(TAG, "Skipping testActivateBrokenReceiver4Fails");
+            return;
+        }
+        assertDeviceAdminDeactivated(CtsDeviceAdminBrokenReceiver4.class);
+        startAddDeviceAdminActivityForResult(CtsDeviceAdminBrokenReceiver4.class);
+        assertWithTimeoutOnActivityResultInvokedWithResultCode(Activity.RESULT_CANCELED);
+        assertDeviceAdminDeactivated(CtsDeviceAdminBrokenReceiver4.class);
+    }
+
+    public void testActivateBrokenReceiver5Fails() throws Exception {
+        if (!mDeviceAdmin) {
+            Log.w(TAG, "Skipping testActivateBrokenReceiver5Fails");
+            return;
+        }
+        assertDeviceAdminDeactivated(CtsDeviceAdminBrokenReceiver5.class);
+        startAddDeviceAdminActivityForResult(CtsDeviceAdminBrokenReceiver5.class);
+        assertWithTimeoutOnActivityResultInvokedWithResultCode(Activity.RESULT_CANCELED);
+        assertDeviceAdminDeactivated(CtsDeviceAdminBrokenReceiver5.class);
+    }
+
+    private void startAddDeviceAdminActivityForResult(Class<?> receiverClass) {
+        getActivity().startActivityForResult(
+                getAddDeviceAdminIntent(receiverClass),
+                REQUEST_CODE_ACTIVATE_ADMIN);
+    }
+
+    private Intent getAddDeviceAdminIntent(Class<?> receiverClass) {
+        return new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN)
+            .putExtra(
+                    DevicePolicyManager.EXTRA_DEVICE_ADMIN,
+                    new ComponentName(
+                            getInstrumentation().getTargetContext(),
+                            receiverClass));
+    }
+
+    private void assertWithTimeoutOnActivityResultNotInvoked() {
+        SystemClock.sleep(UI_EFFECT_TIMEOUT_MILLIS);
+        Mockito.verify(mMockOnActivityResultListener, Mockito.never())
+                .onActivityResult(
+                        Mockito.eq(REQUEST_CODE_ACTIVATE_ADMIN),
+                        Mockito.anyInt(),
+                        Mockito.any(Intent.class));
+    }
+
+    private void assertWithTimeoutOnActivityResultInvokedWithResultCode(int expectedResultCode) {
+        ArgumentCaptor<Integer> resultCodeCaptor = ArgumentCaptor.forClass(int.class);
+        Mockito.verify(mMockOnActivityResultListener, Mockito.timeout(UI_EFFECT_TIMEOUT_MILLIS))
+                .onActivityResult(
+                        Mockito.eq(REQUEST_CODE_ACTIVATE_ADMIN),
+                        resultCodeCaptor.capture(),
+                        Mockito.any(Intent.class));
+        assertEquals(expectedResultCode, (int) resultCodeCaptor.getValue());
+    }
+
+    private void finishActivateDeviceAdminActivity() {
+        getActivity().finishActivity(REQUEST_CODE_ACTIVATE_ADMIN);
+    }
+
+    private void assertDeviceAdminDeactivated(Class<?> receiverClass) {
+        DevicePolicyManager devicePolicyManager =
+                (DevicePolicyManager) getActivity().getSystemService(
+                        Context.DEVICE_POLICY_SERVICE);
+        assertFalse(devicePolicyManager.isAdminActive(
+                new ComponentName(getInstrumentation().getTargetContext(), receiverClass)));
+    }
+}
diff --git a/tests/admin/src/android/admin/cts/DeviceAdminInfoTest.java b/tests/admin/src/android/admin/cts/DeviceAdminInfoTest.java
new file mode 100644
index 0000000..ca1b340
--- /dev/null
+++ b/tests/admin/src/android/admin/cts/DeviceAdminInfoTest.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.admin.cts;
+
+import android.app.admin.DeviceAdminInfo;
+import android.content.ComponentName;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.test.AndroidTestCase;
+import android.util.Log;
+
+public class DeviceAdminInfoTest extends AndroidTestCase {
+
+    private static final String TAG = DeviceAdminInfoTest.class.getSimpleName();
+
+    private PackageManager mPackageManager;
+    private ComponentName mComponent;
+    private ComponentName mSecondComponent;
+    private boolean mDeviceAdmin;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mPackageManager = mContext.getPackageManager();
+        mComponent = getReceiverComponent();
+        mSecondComponent = getSecondReceiverComponent();
+        mDeviceAdmin =
+                mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN);
+    }
+
+    static ComponentName getReceiverComponent() {
+        return new ComponentName("android.admin.app", "android.admin.app.CtsDeviceAdminReceiver");
+    }
+
+    static ComponentName getSecondReceiverComponent() {
+        return new ComponentName("android.admin.app", "android.admin.app.CtsDeviceAdminReceiver2");
+    }
+
+    public void testDeviceAdminInfo() throws Exception {
+        if (!mDeviceAdmin) {
+            Log.w(TAG, "Skipping testDeviceAdminInfo");
+            return;
+        }
+        ResolveInfo resolveInfo = new ResolveInfo();
+        resolveInfo.activityInfo = mPackageManager.getReceiverInfo(mComponent,
+                PackageManager.GET_META_DATA);
+
+        DeviceAdminInfo info = new DeviceAdminInfo(mContext, resolveInfo);
+        assertEquals(mComponent, info.getComponent());
+        assertEquals(mComponent.getPackageName(), info.getPackageName());
+        assertEquals(mComponent.getClassName(), info.getReceiverName());
+
+        assertTrue(info.usesPolicy(DeviceAdminInfo.USES_POLICY_FORCE_LOCK));
+        assertTrue(info.usesPolicy(DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD));
+        assertTrue(info.usesPolicy(DeviceAdminInfo.USES_POLICY_RESET_PASSWORD));
+        assertTrue(info.usesPolicy(DeviceAdminInfo.USES_POLICY_WATCH_LOGIN));
+        assertTrue(info.usesPolicy(DeviceAdminInfo.USES_POLICY_WIPE_DATA));
+
+        assertEquals("force-lock",
+                info.getTagForPolicy(DeviceAdminInfo.USES_POLICY_FORCE_LOCK));
+        assertEquals("limit-password",
+                info.getTagForPolicy(DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD));
+        assertEquals("reset-password",
+                info.getTagForPolicy(DeviceAdminInfo.USES_POLICY_RESET_PASSWORD));
+        assertEquals("watch-login",
+                info.getTagForPolicy(DeviceAdminInfo.USES_POLICY_WATCH_LOGIN));
+        assertEquals("wipe-data",
+                info.getTagForPolicy(DeviceAdminInfo.USES_POLICY_WIPE_DATA));
+    }
+
+    public void testDeviceAdminInfo2() throws Exception {
+        if (!mDeviceAdmin) {
+            Log.w(TAG, "Skipping testDeviceAdminInfo2");
+            return;
+        }
+        ResolveInfo resolveInfo = new ResolveInfo();
+        resolveInfo.activityInfo = mPackageManager.getReceiverInfo(mSecondComponent,
+                PackageManager.GET_META_DATA);
+
+        DeviceAdminInfo info = new DeviceAdminInfo(mContext, resolveInfo);
+        assertEquals(mSecondComponent, info.getComponent());
+        assertEquals(mSecondComponent.getPackageName(), info.getPackageName());
+        assertEquals(mSecondComponent.getClassName(), info.getReceiverName());
+
+        assertFalse(info.usesPolicy(DeviceAdminInfo.USES_POLICY_FORCE_LOCK));
+        assertTrue(info.usesPolicy(DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD));
+        assertTrue(info.usesPolicy(DeviceAdminInfo.USES_POLICY_RESET_PASSWORD));
+        assertFalse(info.usesPolicy(DeviceAdminInfo.USES_POLICY_WATCH_LOGIN));
+        assertTrue(info.usesPolicy(DeviceAdminInfo.USES_POLICY_WIPE_DATA));
+
+        assertEquals("force-lock",
+                info.getTagForPolicy(DeviceAdminInfo.USES_POLICY_FORCE_LOCK));
+        assertEquals("limit-password",
+                info.getTagForPolicy(DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD));
+        assertEquals("reset-password",
+                info.getTagForPolicy(DeviceAdminInfo.USES_POLICY_RESET_PASSWORD));
+        assertEquals("watch-login",
+                info.getTagForPolicy(DeviceAdminInfo.USES_POLICY_WATCH_LOGIN));
+        assertEquals("wipe-data",
+                info.getTagForPolicy(DeviceAdminInfo.USES_POLICY_WIPE_DATA));
+    }
+}
diff --git a/tests/admin/src/android/admin/cts/DeviceAdminReceiverTest.java b/tests/admin/src/android/admin/cts/DeviceAdminReceiverTest.java
new file mode 100644
index 0000000..81ea503
--- /dev/null
+++ b/tests/admin/src/android/admin/cts/DeviceAdminReceiverTest.java
@@ -0,0 +1,203 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.admin.cts;
+
+import android.app.admin.DeviceAdminReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.platform.test.annotations.Presubmit;
+import android.test.AndroidTestCase;
+import android.util.Log;
+
+public class DeviceAdminReceiverTest extends AndroidTestCase {
+
+    private static final String TAG = DeviceAdminReceiverTest.class.getSimpleName();
+    private static final String DISABLE_WARNING = "Disable Warning";
+    private static final String BUGREPORT_HASH = "f4k3h45h";
+
+    private static final String ACTION_BUGREPORT_SHARING_DECLINED =
+            "android.app.action.BUGREPORT_SHARING_DECLINED";
+    private static final String ACTION_BUGREPORT_FAILED = "android.app.action.BUGREPORT_FAILED";
+    private static final String ACTION_BUGREPORT_SHARE =
+            "android.app.action.BUGREPORT_SHARE";
+    private static final String ACTION_SECURITY_LOGS_AVAILABLE
+            = "android.app.action.SECURITY_LOGS_AVAILABLE";
+    private static final String EXTRA_BUGREPORT_FAILURE_REASON =
+            "android.app.extra.BUGREPORT_FAILURE_REASON";
+    private static final String EXTRA_BUGREPORT_HASH = "android.app.extra.BUGREPORT_HASH";
+
+    private static final int PASSWORD_CHANGED = 0x1;
+    private static final int PASSWORD_FAILED = 0x2;
+    private static final int PASSWORD_SUCCEEDED = 0x4;
+    private static final int DEVICE_ADMIN_ENABLED = 0x8;
+    private static final int DEVICE_ADMIN_DISABLE_REQUESTED = 0x10;
+    private static final int DEVICE_ADMIN_DISABLED = 0x20;
+    private static final int BUGREPORT_SHARING_DECLINED = 0x40;
+    private static final int BUGREPORT_FAILED = 0x80;
+    private static final int BUGREPORT_SHARED = 0x100;
+    private static final int SECURITY_LOGS_AVAILABLE = 0x200;
+
+    private TestReceiver mReceiver;
+    private boolean mDeviceAdmin;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mReceiver = new TestReceiver();
+        mDeviceAdmin =
+                mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN);
+    }
+
+    @Presubmit
+    public void testOnReceive() {
+        if (!mDeviceAdmin) {
+            Log.w(TAG, "Skipping testOnReceive");
+            return;
+        }
+        mReceiver.reset();
+        mReceiver.onReceive(mContext, new Intent(DeviceAdminReceiver.ACTION_PASSWORD_CHANGED));
+        assertTrue(mReceiver.hasFlags(PASSWORD_CHANGED));
+
+        mReceiver.reset();
+        mReceiver.onReceive(mContext, new Intent(DeviceAdminReceiver.ACTION_PASSWORD_FAILED));
+        assertTrue(mReceiver.hasFlags(PASSWORD_FAILED));
+
+        mReceiver.reset();
+        mReceiver.onReceive(mContext, new Intent(DeviceAdminReceiver.ACTION_PASSWORD_SUCCEEDED));
+        assertTrue(mReceiver.hasFlags(PASSWORD_SUCCEEDED));
+
+        mReceiver.reset();
+        mReceiver.onReceive(mContext, new Intent(DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED));
+        assertTrue(mReceiver.hasFlags(DEVICE_ADMIN_ENABLED));
+
+        mReceiver.reset();
+        mReceiver.onReceive(mContext, new Intent(DeviceAdminReceiver.ACTION_DEVICE_ADMIN_DISABLED));
+        assertTrue(mReceiver.hasFlags(DEVICE_ADMIN_DISABLED));
+
+        mReceiver.reset();
+        mReceiver.onReceive(mContext, new Intent(ACTION_BUGREPORT_SHARING_DECLINED));
+        assertTrue(mReceiver.hasFlags(BUGREPORT_SHARING_DECLINED));
+
+        mReceiver.reset();
+        Intent bugreportFailedIntent = new Intent(ACTION_BUGREPORT_FAILED);
+        bugreportFailedIntent.putExtra(EXTRA_BUGREPORT_FAILURE_REASON,
+                DeviceAdminReceiver.BUGREPORT_FAILURE_FAILED_COMPLETING);
+        mReceiver.onReceive(mContext, bugreportFailedIntent);
+        assertTrue(mReceiver.hasFlags(BUGREPORT_FAILED));
+        assertEquals(DeviceAdminReceiver.BUGREPORT_FAILURE_FAILED_COMPLETING,
+                mReceiver.getBugreportFailureCode());
+
+        mReceiver.reset();
+        Intent bugreportSharedIntent = new Intent(ACTION_BUGREPORT_SHARE);
+        bugreportSharedIntent.putExtra(EXTRA_BUGREPORT_HASH, BUGREPORT_HASH);
+        mReceiver.onReceive(mContext, bugreportSharedIntent);
+        assertTrue(mReceiver.hasFlags(BUGREPORT_SHARED));
+        assertEquals(BUGREPORT_HASH, mReceiver.getBugreportHash());
+
+        mReceiver.reset();
+        mReceiver.onReceive(mContext, new Intent(ACTION_SECURITY_LOGS_AVAILABLE));
+        assertTrue(mReceiver.hasFlags(SECURITY_LOGS_AVAILABLE));
+    }
+
+    private class TestReceiver extends DeviceAdminReceiver {
+
+        private int mFlags = 0;
+        private int bugreportFailureCode = -1;
+        private String bugreportHash;
+
+        void reset() {
+            mFlags = 0;
+            bugreportFailureCode = -1;
+            bugreportHash = null;
+        }
+
+        boolean hasFlags(int flags) {
+            return mFlags == flags;
+        }
+
+        int getBugreportFailureCode() {
+            return bugreportFailureCode;
+        }
+
+        String getBugreportHash() {
+            return bugreportHash;
+        }
+
+        @Override
+        public void onPasswordChanged(Context context, Intent intent) {
+            super.onPasswordChanged(context, intent);
+            mFlags |= PASSWORD_CHANGED;
+        }
+
+        @Override
+        public void onPasswordFailed(Context context, Intent intent) {
+            super.onPasswordFailed(context, intent);
+            mFlags |= PASSWORD_FAILED;
+        }
+
+        @Override
+        public void onPasswordSucceeded(Context context, Intent intent) {
+            super.onPasswordSucceeded(context, intent);
+            mFlags |= PASSWORD_SUCCEEDED;
+        }
+
+        @Override
+        public void onEnabled(Context context, Intent intent) {
+            super.onEnabled(context, intent);
+            mFlags |= DEVICE_ADMIN_ENABLED;
+        }
+
+        @Override
+        public CharSequence onDisableRequested(Context context, Intent intent) {
+            mFlags |= DEVICE_ADMIN_DISABLE_REQUESTED;
+            return DISABLE_WARNING;
+        }
+
+        @Override
+        public void onDisabled(Context context, Intent intent) {
+            super.onDisabled(context, intent);
+            mFlags |= DEVICE_ADMIN_DISABLED;
+        }
+
+        @Override
+        public void onBugreportSharingDeclined(Context context, Intent intent) {
+            super.onBugreportSharingDeclined(context, intent);
+            mFlags |= BUGREPORT_SHARING_DECLINED;
+        }
+
+        @Override
+        public void onBugreportFailed(Context context, Intent intent, int failureCode) {
+            super.onBugreportFailed(context, intent, failureCode);
+            mFlags |= BUGREPORT_FAILED;
+            bugreportFailureCode = failureCode;
+        }
+
+        @Override
+        public void onBugreportShared(Context context, Intent intent, String bugreportHash) {
+            super.onBugreportShared(context, intent, bugreportHash);
+            mFlags |= BUGREPORT_SHARED;
+            this.bugreportHash = bugreportHash;
+        }
+
+        @Override
+        public void onSecurityLogsAvailable(Context context, Intent intent) {
+            super.onSecurityLogsAvailable(context, intent);
+            mFlags |= SECURITY_LOGS_AVAILABLE;
+        }
+    }
+}
diff --git a/tests/admin/src/android/admin/cts/DevicePolicyManagerTest.java b/tests/admin/src/android/admin/cts/DevicePolicyManagerTest.java
new file mode 100644
index 0000000..543a385
--- /dev/null
+++ b/tests/admin/src/android/admin/cts/DevicePolicyManagerTest.java
@@ -0,0 +1,753 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.admin.cts;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.ResolveInfo;
+import android.os.Build;
+import android.os.UserManager;
+import android.provider.Settings;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.Suppress;
+import android.util.Log;
+
+import java.util.List;
+
+/**
+ * TODO: Make sure DO APIs are not called by PO.
+ * Test that exercises {@link DevicePolicyManager}. The test requires that the
+ * CtsDeviceAdminReceiver be installed via the CtsDeviceAdmin.apk and be
+ * activated via "Settings > Location & security > Select device administrators".
+ */
+public class DevicePolicyManagerTest extends AndroidTestCase {
+
+    private static final String TAG = DevicePolicyManagerTest.class.getSimpleName();
+
+    private DevicePolicyManager mDevicePolicyManager;
+    private ComponentName mComponent;
+    private boolean mDeviceAdmin;
+    private boolean mManagedProfiles;
+    private PackageManager mPackageManager;
+
+    private static final String TEST_CA_STRING1 =
+            "-----BEGIN CERTIFICATE-----\n" +
+            "MIICVzCCAgGgAwIBAgIJAMvnLHnnfO/IMA0GCSqGSIb3DQEBBQUAMIGGMQswCQYD\n" +
+            "VQQGEwJJTjELMAkGA1UECAwCQVAxDDAKBgNVBAcMA0hZRDEVMBMGA1UECgwMSU1G\n" +
+            "TCBQVlQgTFREMRAwDgYDVQQLDAdJTUZMIE9VMRIwEAYDVQQDDAlJTUZMLklORk8x\n" +
+            "HzAdBgkqhkiG9w0BCQEWEHJhbWVzaEBpbWZsLmluZm8wHhcNMTMwODI4MDk0NDA5\n" +
+            "WhcNMjMwODI2MDk0NDA5WjCBhjELMAkGA1UEBhMCSU4xCzAJBgNVBAgMAkFQMQww\n" +
+            "CgYDVQQHDANIWUQxFTATBgNVBAoMDElNRkwgUFZUIExURDEQMA4GA1UECwwHSU1G\n" +
+            "TCBPVTESMBAGA1UEAwwJSU1GTC5JTkZPMR8wHQYJKoZIhvcNAQkBFhByYW1lc2hA\n" +
+            "aW1mbC5pbmZvMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJ738cbTQlNIO7O6nV/f\n" +
+            "DJTMvWbPkyHYX8CQ7yXiAzEiZ5bzKJjDJmpRAkUrVinljKns2l6C4++l/5A7pFOO\n" +
+            "33kCAwEAAaNQME4wHQYDVR0OBBYEFOdbZP7LaMbgeZYPuds2CeSonmYxMB8GA1Ud\n" +
+            "IwQYMBaAFOdbZP7LaMbgeZYPuds2CeSonmYxMAwGA1UdEwQFMAMBAf8wDQYJKoZI\n" +
+            "hvcNAQEFBQADQQBdrk6J9koyylMtl/zRfiMAc2zgeC825fgP6421NTxs1rjLs1HG\n" +
+            "VcUyQ1/e7WQgOaBHi9TefUJi+4PSVSluOXon\n" +
+            "-----END CERTIFICATE-----";
+
+    private static final String MANAGED_PROVISIONING_PKG = "com.android.managedprovisioning";
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mDevicePolicyManager = (DevicePolicyManager)
+                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
+        mComponent = DeviceAdminInfoTest.getReceiverComponent();
+        mPackageManager = mContext.getPackageManager();
+        mDeviceAdmin = mPackageManager.hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN);
+        mManagedProfiles = mDeviceAdmin
+                && mPackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS);
+    }
+
+    public void testGetActiveAdmins() {
+        if (!mDeviceAdmin) {
+            Log.w(TAG, "Skipping testGetActiveAdmins");
+            return;
+        }
+        List<ComponentName> activeAdmins = mDevicePolicyManager.getActiveAdmins();
+        assertFalse(activeAdmins.isEmpty());
+        assertTrue(activeAdmins.contains(mComponent));
+        assertTrue(mDevicePolicyManager.isAdminActive(mComponent));
+    }
+
+    public void testKeyguardDisabledFeatures() {
+        if (!mDeviceAdmin) {
+            Log.w(TAG, "Skipping testKeyguardDisabledFeatures");
+            return;
+        }
+        int originalValue = mDevicePolicyManager.getKeyguardDisabledFeatures(mComponent);
+        try {
+            for (int which = DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_NONE;
+                    which < 2 * DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT; ++which) {
+                mDevicePolicyManager.setKeyguardDisabledFeatures(mComponent, which);
+                assertEquals(which, mDevicePolicyManager.getKeyguardDisabledFeatures(mComponent));
+            }
+        } finally {
+            mDevicePolicyManager.setKeyguardDisabledFeatures(mComponent, originalValue);
+        }
+    }
+
+    public void testRequestRemoteBugreport_failIfNotDeviceOwner() {
+        if (!mDeviceAdmin) {
+            Log.w(TAG, "Skipping testRequestRemoteBugreport_failIfNotDeviceOwner");
+            return;
+        }
+        try {
+            mDevicePolicyManager.requestBugreport(mComponent);
+            fail("did not throw expected SecurityException");
+        } catch (SecurityException e) {
+            assertDeviceOwnerMessage(e.getMessage());
+        }
+    }
+
+    public void testSetSecurityLoggingEnabled_failIfNotDeviceOwner() {
+        if (!mDeviceAdmin) {
+            Log.w(TAG, "Skipping testSetSecurityLoggingEnabled_failIfNotDeviceOwner");
+            return;
+        }
+        try {
+            mDevicePolicyManager.setSecurityLoggingEnabled(mComponent, true);
+            fail("did not throw expected SecurityException");
+        } catch (SecurityException e) {
+            assertDeviceOwnerMessage(e.getMessage());
+        }
+    }
+
+    public void testIsSecurityLoggingEnabled_failIfNotDeviceOwner() {
+        if (!mDeviceAdmin) {
+            Log.w(TAG, "Skipping testIsSecurityLoggingEnabled_failIfNotDeviceOwner");
+            return;
+        }
+        try {
+            mDevicePolicyManager.isSecurityLoggingEnabled(mComponent);
+            fail("did not throw expected SecurityException");
+        } catch (SecurityException e) {
+            assertDeviceOwnerMessage(e.getMessage());
+        }
+    }
+
+    public void testRetrieveSecurityLogs_failIfNotDeviceOwner() {
+        if (!mDeviceAdmin) {
+            Log.w(TAG, "Skipping testRetrieveSecurityLogs_failIfNotDeviceOwner");
+            return;
+        }
+        try {
+            mDevicePolicyManager.retrieveSecurityLogs(mComponent);
+            fail("did not throw expected SecurityException");
+        } catch (SecurityException e) {
+            assertDeviceOwnerMessage(e.getMessage());
+        }
+    }
+
+    public void testRetrievePreRebootSecurityLogs_failIfNotDeviceOwner() {
+        if (!mDeviceAdmin) {
+            Log.w(TAG, "Skipping testRetrievePreRebootSecurityLogs_failIfNotDeviceOwner");
+            return;
+        }
+        try {
+            mDevicePolicyManager.retrievePreRebootSecurityLogs(mComponent);
+            fail("did not throw expected SecurityException");
+        } catch (SecurityException e) {
+            assertDeviceOwnerMessage(e.getMessage());
+        }
+    }
+
+    public void testRemoveUser_failIfNotDeviceOwner() {
+        if (!mDeviceAdmin) {
+            Log.w(TAG, "Skipping testRemoveUser_failIfNotDeviceOwner");
+            return;
+        }
+        try {
+            mDevicePolicyManager.removeUser(mComponent, null);
+            fail("did not throw expected SecurityException");
+        } catch (SecurityException e) {
+            assertDeviceOwnerMessage(e.getMessage());
+        }
+    }
+
+    public void testSetApplicationHidden_failIfNotDeviceOrProfileOwner() {
+        if (!mDeviceAdmin) {
+            Log.w(TAG, "Skipping testSetApplicationHidden_failIfNotDeviceOrProfileOwner");
+            return;
+        }
+        try {
+            mDevicePolicyManager.setApplicationHidden(mComponent, "com.google.anything", true);
+            fail("did not throw expected SecurityException");
+        } catch (SecurityException e) {
+            assertProfileOwnerMessage(e.getMessage());
+        }
+    }
+
+    public void testIsApplicationHidden_failIfNotDeviceOrProfileOwner() {
+        if (!mDeviceAdmin) {
+            Log.w(TAG, "Skipping testIsApplicationHidden_failIfNotDeviceOrProfileOwner");
+            return;
+        }
+        try {
+            mDevicePolicyManager.isApplicationHidden(mComponent, "com.google.anything");
+            fail("did not throw expected SecurityException");
+        } catch (SecurityException e) {
+            assertProfileOwnerMessage(e.getMessage());
+        }
+    }
+
+    public void testSetGlobalSetting_failIfNotDeviceOwner() {
+        if (!mDeviceAdmin) {
+            Log.w(TAG, "Skipping testSetGlobalSetting_failIfNotDeviceOwner");
+            return;
+        }
+        try {
+            mDevicePolicyManager.setGlobalSetting(mComponent,
+                    Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, "1");
+            fail("did not throw expected SecurityException");
+        } catch (SecurityException e) {
+            assertDeviceOwnerMessage(e.getMessage());
+        }
+    }
+
+    public void testSetSecureSetting_failIfNotDeviceOrProfileOwner() {
+        if (!mDeviceAdmin) {
+            Log.w(TAG, "Skipping testSetSecureSetting_failIfNotDeviceOrProfileOwner");
+            return;
+        }
+        try {
+            mDevicePolicyManager.setSecureSetting(mComponent,
+                    Settings.Secure.INSTALL_NON_MARKET_APPS, "1");
+            fail("did not throw expected SecurityException");
+        } catch (SecurityException e) {
+            assertProfileOwnerMessage(e.getMessage());
+        }
+    }
+
+    public void testSetMasterVolumeMuted_failIfNotDeviceOrProfileOwner() {
+        if (!mDeviceAdmin) {
+            Log.w(TAG, "Skipping testSetMasterVolumeMuted_failIfNotDeviceOrProfileOwner");
+            return;
+        }
+        try {
+            mDevicePolicyManager.setMasterVolumeMuted(mComponent, true);
+            fail("did not throw expected SecurityException");
+        } catch (SecurityException e) {
+            assertProfileOwnerMessage(e.getMessage());
+        }
+    }
+
+    public void testIsMasterVolumeMuted_failIfNotDeviceOrProfileOwner() {
+        if (!mDeviceAdmin) {
+            Log.w(TAG, "Skipping testSetMasterVolumeMuted_failIfNotDeviceOrProfileOwner");
+            return;
+        }
+        try {
+            mDevicePolicyManager.isMasterVolumeMuted(mComponent);
+            fail("did not throw expected SecurityException");
+        } catch (SecurityException e) {
+            assertProfileOwnerMessage(e.getMessage());
+        }
+    }
+
+    public void testSetRecommendedGlobalProxy_failIfNotDeviceOwner() {
+        if (!mDeviceAdmin) {
+            Log.w(TAG, "Skipping testSetRecommendedGlobalProxy_failIfNotDeviceOwner");
+            return;
+        }
+        try {
+            mDevicePolicyManager.setRecommendedGlobalProxy(mComponent, null);
+            fail("did not throw expected SecurityException");
+        } catch (SecurityException e) {
+            assertDeviceOwnerMessage(e.getMessage());
+        }
+    }
+
+    public void testSetLockTaskPackages_failIfNotDeviceOwner() {
+        if (!mDeviceAdmin) {
+            Log.w(TAG, "Skipping testSetLockTaskPackages_failIfNotDeviceOwner");
+            return;
+        }
+        try {
+            mDevicePolicyManager.setLockTaskPackages(mComponent, new String[] {"package"});
+            fail("did not throw expected SecurityException");
+        } catch (SecurityException e) {
+        }
+    }
+
+    // This test registers itself as DO, so this is no longer testable.  We do a positive test
+    // for clearDeviceOwnerApp()
+    @Suppress
+    public void testClearDeviceOwnerApp_failIfNotDeviceOwner() {
+        if (!mDeviceAdmin) {
+            Log.w(TAG, "Skipping testClearDeviceOwnerApp_failIfNotDeviceOwner");
+            return;
+        }
+        try {
+            mDevicePolicyManager.clearDeviceOwnerApp("android.admin.app");
+            fail("did not throw expected SecurityException");
+        } catch (SecurityException e) {
+            assertDeviceOwnerMessage(e.getMessage());
+        }
+    }
+
+    public void testSwitchUser_failIfNotDeviceOwner() {
+        if (!mDeviceAdmin) {
+            Log.w(TAG, "Skipping testSwitchUser_failIfNotDeviceOwner");
+            return;
+        }
+        try {
+            mDevicePolicyManager.switchUser(mComponent, null);
+            fail("did not throw expected SecurityException");
+        } catch (SecurityException e) {
+            assertDeviceOwnerMessage(e.getMessage());
+        }
+    }
+
+    public void testCreateAndManageUser_failIfNotDeviceOwner() {
+        if (!mDeviceAdmin) {
+            Log.w(TAG, "Skipping testCreateAndManageUser_failIfNotDeviceOwner");
+            return;
+        }
+        try {
+            mDevicePolicyManager.createAndManageUser(mComponent, "name", mComponent, null, 0);
+            fail("did not throw expected SecurityException");
+        } catch (SecurityException e) {
+            assertDeviceOwnerMessage(e.getMessage());
+        }
+    }
+
+    public void testInstallCaCert_failIfNotProfileOwner() {
+        if (!mDeviceAdmin) {
+            Log.w(TAG, "Skipping testInstallCaCert_failIfNotProfileOwner");
+            return;
+        }
+        try {
+            mDevicePolicyManager.installCaCert(mComponent,
+                    TEST_CA_STRING1.getBytes());
+            fail("did not throw expected SecurityException");
+        } catch (SecurityException e) {
+            assertProfileOwnerMessage(e.getMessage());
+        }
+    }
+
+    public void testInstallCaCert_failIfNotCertInstaller() {
+        if (!mDeviceAdmin) {
+            Log.w(TAG, "Skipping testInstallCaCert_failIfNotCertInstaller");
+            return;
+        }
+        try {
+            // Delegated cert installer is identified by using null as the first argument.
+            mDevicePolicyManager.installCaCert(null, TEST_CA_STRING1.getBytes());
+            fail("did not throw expected SecurityException");
+        } catch (SecurityException expected) {
+        }
+    }
+
+    public void testUninstallCaCert_failIfNotProfileOwner() {
+        if (!mDeviceAdmin) {
+            Log.w(TAG, "Skipping testUninstallCaCert_failIfNotProfileOwner");
+            return;
+        }
+        try {
+            mDevicePolicyManager.uninstallCaCert(mComponent,
+                    TEST_CA_STRING1.getBytes());
+            fail("did not throw expected SecurityException");
+        } catch (SecurityException e) {
+            assertProfileOwnerMessage(e.getMessage());
+        }
+    }
+
+    public void testUninstallCaCert_failIfNotCertInstaller() {
+        if (!mDeviceAdmin) {
+            Log.w(TAG, "Skipping testUninstallCaCert_failIfNotCertInstaller");
+            return;
+        }
+        try {
+            // Delegated cert installer is identified by using null as the first argument.
+            mDevicePolicyManager.uninstallCaCert(null, TEST_CA_STRING1.getBytes());
+            fail("did not throw expected SecurityException");
+        } catch (SecurityException expected) {
+        }
+    }
+
+    public void testGetInstalledCaCerts_failIfNotProfileOwner() {
+        if (!mDeviceAdmin) {
+            Log.w(TAG, "Skipping testGetInstalledCaCerts_failIfNotProfileOwner");
+            return;
+        }
+        try {
+            mDevicePolicyManager.getInstalledCaCerts(mComponent);
+            fail("did not throw expected SecurityException");
+        } catch (SecurityException e) {
+            assertProfileOwnerMessage(e.getMessage());
+        }
+    }
+
+    public void testGetInstalledCaCerts_failIfNotCertInstaller() {
+        if (!mDeviceAdmin) {
+            Log.w(TAG, "Skipping testGetInstalledCaCerts_failIfNotCertInstaller");
+            return;
+        }
+        try {
+            // Delegated cert installer is identified by using null as the first argument.
+            mDevicePolicyManager.getInstalledCaCerts(null);
+            fail("did not throw expected SecurityException");
+        } catch (SecurityException expected) {
+        }
+    }
+
+    public void testHasCaCertInstalled_failIfNotProfileOwner() {
+        if (!mDeviceAdmin) {
+            Log.w(TAG, "Skipping testHasCaCertInstalled_failIfNotProfileOwner");
+            return;
+        }
+        try {
+            mDevicePolicyManager.hasCaCertInstalled(mComponent,
+                    TEST_CA_STRING1.getBytes());
+            fail("did not throw expected SecurityException");
+        } catch (SecurityException e) {
+            assertProfileOwnerMessage(e.getMessage());
+        }
+    }
+
+    public void testHasCaCertInstalled_failIfNotCertInstaller() {
+        if (!mDeviceAdmin) {
+            Log.w(TAG, "Skipping testHasCaCertInstalled_failIfNotCertInstaller");
+            return;
+        }
+        try {
+            // Delegated cert installer is identified by using null as the first argument.
+            mDevicePolicyManager.hasCaCertInstalled(null, TEST_CA_STRING1.getBytes());
+            fail("did not throw expected SecurityException");
+        } catch (SecurityException expected) {
+        }
+    }
+
+    public void testUninstallAllUserCaCerts_failIfNotProfileOwner() {
+        if (!mDeviceAdmin) {
+            Log.w(TAG, "Skipping testUninstallAllUserCaCerts_failIfNotProfileOwner");
+            return;
+        }
+        try {
+            mDevicePolicyManager.uninstallAllUserCaCerts(mComponent);
+            fail("did not throw expected SecurityException");
+        } catch (SecurityException e) {
+            assertProfileOwnerMessage(e.getMessage());
+        }
+    }
+
+    public void testUninstallAllUserCaCerts_failIfNotCertInstaller() {
+        if (!mDeviceAdmin) {
+            Log.w(TAG, "Skipping testUninstallAllUserCaCerts_failIfNotCertInstaller");
+            return;
+        }
+        try {
+            // Delegated cert installer is identified by using null as the first argument.
+            mDevicePolicyManager.uninstallAllUserCaCerts(null);
+            fail("did not throw expected SecurityException");
+        } catch (SecurityException expected) {
+        }
+    }
+
+    public void testSetScreenCaptureDisabled_failIfNotProfileOwner() {
+        if (!mDeviceAdmin) {
+            Log.w(TAG, "Skipping testSetScreenCaptureDisabled_failIfNotProfileOwner");
+            return;
+        }
+        try {
+            mDevicePolicyManager.setScreenCaptureDisabled(mComponent, true);
+            fail("did not throw expected SecurityException");
+        } catch (SecurityException e) {
+            assertProfileOwnerMessage(e.getMessage());
+        }
+    }
+
+    public void testSetAutoTimeRequired_failIfNotDeviceOwner() {
+        if (!mDeviceAdmin) {
+            Log.w(TAG, "Skipping testSetAutoTimeRequired_failIfNotDeviceOwner");
+            return;
+        }
+        try {
+            mDevicePolicyManager.setAutoTimeRequired(mComponent, true);
+            fail("did not throw expected SecurityException");
+        } catch (SecurityException e) {
+            assertDeviceOwnerMessage(e.getMessage());
+        }
+    }
+
+    public void testAddPersistentPreferredActivity_failIfNotProfileOwner() {
+        if (!mDeviceAdmin) {
+            Log.w(TAG, "Skipping testAddPersistentPreferredActivity_failIfNotProfileOwner");
+            return;
+        }
+        try {
+            mDevicePolicyManager.addPersistentPreferredActivity(mComponent,
+                    new IntentFilter(Intent.ACTION_MAIN),
+                    new ComponentName("android.admin.cts", "dummy"));
+            fail("did not throw expected SecurityException");
+        } catch (SecurityException e) {
+            assertProfileOwnerMessage(e.getMessage());
+        }
+    }
+
+    public void testClearPackagePersistentPreferredActivities_failIfNotProfileOwner() {
+        if (!mDeviceAdmin) {
+            Log.w(TAG, "Skipping testClearPackagePersistentPreferredActivities_failIfNotProfileOwner");
+            return;
+        }
+        try {
+            mDevicePolicyManager.clearPackagePersistentPreferredActivities(mComponent,
+                    "android.admin.cts");
+            fail("did not throw expected SecurityException");
+        } catch (SecurityException e) {
+            assertProfileOwnerMessage(e.getMessage());
+        }
+    }
+
+    public void testSetApplicationRestrictions_failIfNotProfileOwner() {
+        if (!mDeviceAdmin) {
+            Log.w(TAG, "Skipping testSetApplicationRestrictions_failIfNotProfileOwner");
+            return;
+        }
+        try {
+            mDevicePolicyManager.setApplicationRestrictions(mComponent,
+                    "android.admin.cts", null);
+            fail("did not throw expected SecurityException");
+        } catch (SecurityException e) {
+            assertProfileOwnerMessage(e.getMessage());
+        }
+    }
+
+    public void testAddUserRestriction_failIfNotProfileOwner() {
+        if (!mDeviceAdmin) {
+            Log.w(TAG, "Skipping testAddUserRestriction_failIfNotProfileOwner");
+            return;
+        }
+        try {
+            mDevicePolicyManager.addUserRestriction(mComponent,
+                    UserManager.DISALLOW_SMS);
+            fail("did not throw expected SecurityException");
+        } catch (SecurityException e) {
+            assertProfileOwnerMessage(e.getMessage());
+        }
+    }
+
+    public void testSetAccountManagementDisabled_failIfNotProfileOwner() {
+        if (!mDeviceAdmin) {
+            Log.w(TAG, "Skipping testSetAccountManagementDisabled_failIfNotProfileOwner");
+            return;
+        }
+        try {
+            mDevicePolicyManager.setAccountManagementDisabled(mComponent,
+                    "dummy", true);
+            fail("did not throw expected SecurityException");
+        } catch (SecurityException e) {
+            assertProfileOwnerMessage(e.getMessage());
+        }
+    }
+
+    public void testSetRestrictionsProvider_failIfNotProfileOwner() {
+        if (!mDeviceAdmin) {
+            Log.w(TAG, "Skipping testSetRestrictionsProvider_failIfNotProfileOwner");
+            return;
+        }
+        try {
+            mDevicePolicyManager.setRestrictionsProvider(mComponent,
+                    new ComponentName("android.admin.cts", "dummy"));
+            fail("did not throw expected SecurityException");
+        } catch (SecurityException e) {
+            assertProfileOwnerMessage(e.getMessage());
+        }
+    }
+
+    public void testSetUninstallBlocked_failIfNotProfileOwner() {
+        if (!mDeviceAdmin) {
+            Log.w(TAG, "Skipping testSetUninstallBlocked_failIfNotProfileOwner");
+            return;
+        }
+        try {
+            mDevicePolicyManager.setUninstallBlocked(mComponent,
+                    "android.admin.cts", true);
+            fail("did not throw expected SecurityException");
+        } catch (SecurityException e) {
+            assertProfileOwnerMessage(e.getMessage());
+        }
+    }
+
+    public void testSetPermittedAccessibilityServices_failIfNotProfileOwner() {
+        if (!mDeviceAdmin) {
+            Log.w(TAG, "Skipping testSetPermittedAccessibilityServices_failIfNotProfileOwner");
+            return;
+        }
+        try {
+            mDevicePolicyManager.setPermittedAccessibilityServices(mComponent, null);
+            fail("did not throw expected SecurityException");
+        } catch (SecurityException e) {
+            assertProfileOwnerMessage(e.getMessage());
+        }
+    }
+
+    public void testSetCrossProfileContactsSearchDisabled_failIfNotProfileOwner() {
+        if (!mDeviceAdmin) {
+            Log.w(TAG, "Skipping testSetCrossProfileContactsSearchDisabled_failIfNotProfileOwner");
+            return;
+        }
+        try {
+            mDevicePolicyManager.setCrossProfileContactsSearchDisabled(mComponent, true);
+            fail("did not throw expected SecurityException");
+        } catch (SecurityException e) {
+            assertProfileOwnerMessage(e.getMessage());
+        }
+    }
+
+    public void testSetBluetoothContactSharingDisabled_failIfNotProfileOwner() {
+        if (!mDeviceAdmin) {
+            Log.w(TAG, "Skipping testSetBluetoothContactSharingDisabled_failIfNotProfileOwner");
+            return;
+        }
+        try {
+            mDevicePolicyManager.setBluetoothContactSharingDisabled(mComponent, true);
+            fail("did not throw expected SecurityException");
+        } catch (SecurityException e) {
+            assertProfileOwnerMessage(e.getMessage());
+        }
+    }
+
+    public void testSetPermittedInputMethods_failIfNotProfileOwner() {
+        if (!mDeviceAdmin) {
+            Log.w(TAG, "Skipping testSetPermittedInputMethods_failIfNotProfileOwner");
+            return;
+        }
+        try {
+            mDevicePolicyManager.setPermittedInputMethods(mComponent, null);
+            fail("did not throw expected SecurityException");
+        } catch (SecurityException e) {
+            assertProfileOwnerMessage(e.getMessage());
+        }
+    }
+
+    /**
+     * Test whether the version of the pre-installed launcher is at least L. This is needed for
+     * managed profile support.
+     */
+    public void testLauncherVersionAtLeastL() throws Exception {
+        if (!mManagedProfiles) {
+            return;
+        }
+
+        Intent intent = new Intent(Intent.ACTION_MAIN);
+        intent.addCategory(Intent.CATEGORY_HOME);
+        List<ResolveInfo> resolveInfos = mPackageManager.queryIntentActivities(intent,
+                0 /* default flags */);
+        assertFalse("No launcher present", resolveInfos.isEmpty());
+
+        for (ResolveInfo resolveInfo : resolveInfos) {
+            ApplicationInfo launcherAppInfo = mPackageManager.getApplicationInfo(
+                    resolveInfo.activityInfo.packageName, 0 /* default flags */);
+            if ((launcherAppInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0 &&
+                    launcherAppInfo.targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP) {
+                return;
+            }
+        }
+        fail("No system launcher with version L+ present present on device.");
+    }
+
+    /**
+     * Test that managed provisioning is pre-installed if and only if the device declares the
+     * device admin feature.
+     */
+    public void testManagedProvisioningPreInstalled() throws Exception {
+        assertEquals(mDeviceAdmin, isPackageInstalledOnSystemImage(MANAGED_PROVISIONING_PKG));
+    }
+
+    private void assertDeviceOwnerMessage(String message) {
+        assertTrue("message is: "+ message, message.contains("does not own the device")
+                || message.contains("can only be called by the device owner"));
+    }
+
+    private void assertProfileOwnerMessage(String message) {
+        assertTrue("message is: "+ message,
+                message.contains("does not own the profile"));
+    }
+
+    public void testSetDelegatedCertInstaller_failIfNotProfileOwner() {
+        if (!mDeviceAdmin) {
+            Log.w(TAG, "Skipping testSetDelegatedCertInstaller_failIfNotProfileOwner");
+            return;
+        }
+        try {
+            mDevicePolicyManager.setCertInstallerPackage(mComponent, "com.test.package");
+            fail("did not throw expected SecurityException");
+        } catch (SecurityException e) {
+            assertProfileOwnerMessage(e.getMessage());
+        }
+    }
+
+    public void testGetDelegatedCertInstaller_failIfNotProfileOwner() {
+        if (!mDeviceAdmin) {
+            Log.w(TAG, "Skipping testGetDelegatedCertInstaller_failIfNotProfileOwner");
+            return;
+        }
+        try {
+            mDevicePolicyManager.getCertInstallerPackage(mComponent);
+            fail("did not throw expected SecurityException");
+        } catch (SecurityException e) {
+            assertProfileOwnerMessage(e.getMessage());
+        }
+    }
+
+    public void testSetSystemUpdatePolicy_failIfNotDeviceOwner() {
+        if (!mDeviceAdmin) {
+            Log.w(TAG, "Skipping testSetSystemUpdatePolicy_failIfNotDeviceOwner");
+            return;
+        }
+        try {
+            mDevicePolicyManager.setSystemUpdatePolicy(mComponent, null);
+            fail("did not throw expected SecurityException");
+        } catch (SecurityException e) {
+            assertDeviceOwnerMessage(e.getMessage());
+        }
+    }
+
+    private boolean isPackageInstalledOnSystemImage(String packagename) {
+        try {
+            ApplicationInfo info = mPackageManager.getApplicationInfo(packagename,
+                    0 /* default flags */);
+            return (info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
+        } catch (NameNotFoundException e) {
+            return false;
+        }
+    }
+
+    public void testReboot_failIfNotDeviceOwner() {
+        if (!mDeviceAdmin) {
+            Log.w(TAG, "Skipping testReboot_failIfNotDeviceOwner");
+            return;
+        }
+        try {
+            mDevicePolicyManager.reboot(mComponent);
+            fail("did not throw expected SecurityException");
+        } catch (SecurityException e) {
+            assertDeviceOwnerMessage(e.getMessage());
+        }
+    }
+
+}
diff --git a/tests/app/Android.mk b/tests/app/Android.mk
index f4f0a13..775e679 100644
--- a/tests/app/Android.mk
+++ b/tests/app/Android.mk
@@ -21,15 +21,23 @@
 # and when built explicitly put it in the data partition
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
 
-LOCAL_PROGUARD_ENABLED := disabled
-
 LOCAL_JAVA_LIBRARIES := android.test.runner telephony-common voip-common org.apache.http.legacy
 
-LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctstestrunner ctstestserver
+LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctstestrunner ctstestserver mockito-target
 
-LOCAL_SRC_FILES := $(call all-java-files-under, src) \
-              src/android/app/cts/ISecondary.aidl
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
-LOCAL_PACKAGE_NAME := CtsAppTestStubs
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
 
-include $(BUILD_CTS_SUPPORT_PACKAGE)
+LOCAL_PACKAGE_NAME := CtsAppTestCases
+
+LOCAL_INSTRUMENTATION_FOR := CtsAppTestStubs
+
+LOCAL_CTS_MODULE_CONFIG := $(LOCAL_PATH)/Old$(CTS_MODULE_TEST_CONFIG)
+
+LOCAL_SDK_VERSION := test_current
+
+include $(BUILD_CTS_PACKAGE)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/app/AndroidManifest.xml b/tests/app/AndroidManifest.xml
index 8d7729e..0a7216d 100644
--- a/tests/app/AndroidManifest.xml
+++ b/tests/app/AndroidManifest.xml
@@ -16,270 +16,22 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.app.stub">
+    package="android.app.cts">
 
-    <permission android:name="android.app.cts.permission.TEST_GRANTED"
-        android:protectionLevel="normal"
-            android:label="@string/permlab_testGranted"
-            android:description="@string/permdesc_testGranted">
-        <meta-data android:name="android.app.cts.string" android:value="foo" />
-        <meta-data android:name="android.app.cts.boolean" android:value="true" />
-        <meta-data android:name="android.app.cts.integer" android:value="100" />
-        <meta-data android:name="android.app.cts.color" android:value="#ff000000" />
-        <meta-data android:name="android.app.cts.float" android:value="100.1" />
-        <meta-data android:name="android.app.cts.reference" android:resource="@xml/metadata" />
-    </permission>
-
-    <uses-permission android:name="android.app.cts.permission.TEST_GRANTED" />
-    <uses-permission android:name="android.permission.READ_CONTACTS" />
-    <uses-permission android:name="android.permission.WRITE_CONTACTS" />
-    <uses-permission android:name="android.permission.INTERNET" />
-    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
-    <uses-permission android:name="android.permission.CAMERA" />
-    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
-    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
-    <uses-permission android:name="android.permission.SET_WALLPAPER_HINTS" />
-    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+    <uses-sdk android:minSdkVersion="11" />
+    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <uses-permission android:name="android.permission.BODY_SENSORS" />
-
-    <application android:label="Android TestCase"
-                android:icon="@drawable/size_48x48"
-                android:maxRecents="1"
-                android:multiArch="true"
-                android:name="android.app.cts.MockApplication"
-                android:supportsRtl="true">
+    <application>
         <uses-library android:name="android.test.runner" />
         <uses-library android:name="org.apache.http.legacy" android:required="false" />
-
-        <activity android:name="android.app.cts.ActionBarActivity" />
-
-        <activity android:name="android.app.cts.DialogStubActivity"
-            android:label="DialogStubActivity"
-            android:configChanges="keyboardHidden|orientation|screenSize">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
-            </intent-filter>
-        </activity>
-
-        <activity android:name="android.app.cts.MockActivity" android:label="MockActivity">
-            <meta-data android:name="android.app.alias"
-                android:resource="@xml/alias" />
-            <meta-data android:name="android.app.intent.filter"
-                android:resource="@xml/intentfilter" />
-        </activity>
-
-        <activity android:name="android.app.cts.MockApplicationActivity"
-            android:label="MockApplicationActivity">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN"/>
-                <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
-            </intent-filter>
-        </activity>
-
-        <activity android:name="android.app.cts.InstrumentationTestActivity"
-                  android:theme="@style/Theme_NoSwipeDismiss"
-                  android:label="InstrumentationTestActivity">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.DEFAULT" />
-                <data android:mimeType="vnd.android.cursor.dir/person" />
-            </intent-filter>
-        </activity>
-
-        <activity android:name="android.app.cts.AliasActivityStub">
-            <meta-data android:name="android.app.alias"
-                android:resource="@xml/alias" />
-        </activity>
-
-        <activity android:name="android.app.cts.ChildActivity"
-                        android:label="ChildActivity" />
-
-        <receiver android:name="android.app.cts.MockReceiver">
-            <intent-filter>
-                <action android:name="android.app.cts.PendingIntentTest.TEST_RECEIVER" />
-            </intent-filter>
-        </receiver>
-
-        <service android:name="android.app.cts.MockService" />
-
-        <activity android:name="android.app.cts.SearchManagerStubActivity"
-                android:label="SearchManagerStubActivity">
-            <intent-filter>
-                <action android:name="android.intent.action.SEARCH" />
-                <category android:name="android.intent.category.DEFAULT" />
-            </intent-filter>
-            <meta-data android:name="android.app.searchable" android:resource="@xml/searchable" />
-        </activity>
-
-        <service android:name="android.app.cts.LocalService">
-            <intent-filter>
-                <action android:name="android.app.cts.activity.SERVICE_LOCAL" />
-            </intent-filter>
-            <meta-data android:name="android.app.cts.string" android:value="foo" />
-            <meta-data android:name="android.app.cts.boolean" android:value="true" />
-            <meta-data android:name="android.app.cts.integer" android:value="100" />
-            <meta-data android:name="android.app.cts.color" android:value="#ff000000" />
-            <meta-data android:name="android.app.cts.float" android:value="100.1" />
-            <meta-data android:name="android.app.cts.reference" android:resource="@xml/metadata" />
-        </service>
-
-        <service android:name="android.app.cts.LocalGrantedService"
-             android:permission="android.app.cts.permission.TEST_GRANTED">
-            <intent-filter>
-                <action android:name="android.app.cts.activity.SERVICE_LOCAL_GRANTED" />
-            </intent-filter>
-        </service>
-
-        <service android:name="android.app.cts.LocalDeniedService"
-               android:permission="android.app.cts.permission.TEST_DENIED">
-            <intent-filter>
-                <action android:name="android.app.cts.activity.SERVICE_LOCAL_DENIED" />
-            </intent-filter>
-        </service>
-
-        <activity android:name="android.app.cts.TestedScreen"
-                android:process=":remoteScreen">
-        </activity>
-        <activity android:name="android.app.cts.LocalScreen" android:multiprocess="true">
-        </activity>
-        <activity android:name="android.app.cts.ClearTop" android:multiprocess="true"
-               android:launchMode="singleTop">
-        </activity>
-        <activity android:name="android.app.cts.LocalDialog" android:multiprocess="true"
-               android:theme="@android:style/Theme.Dialog">
-        </activity>
-
-        <activity android:name="android.app.cts.PendingIntentStubActivity"
-             android:label="PendingIntentStubActivity"/>
-
-        <activity android:name="android.app.cts.LocalActivityManagerStubActivity"
-                        android:label="LocalActivityManagerStubActivity" />
-
-        <activity android:name="android.app.cts.LocalActivityManagerTestHelper"
-            android:label="LocalActivityManagerTestHelper" />
-
-        <activity android:name="android.app.cts.LaunchpadTabActivity" android:multiprocess="true">
-        </activity>
-
-        <activity android:name="android.app.cts.LocalActivity" android:multiprocess="true">
-            <meta-data android:name="android.app.cts.string" android:value="foo" />
-            <meta-data android:name="android.app.cts.boolean" android:value="true" />
-            <meta-data android:name="android.app.cts.integer" android:value="100" />
-            <meta-data android:name="android.app.cts.color" android:value="#ff000000" />
-            <meta-data android:name="android.app.cts.float" android:value="100.1" />
-            <meta-data android:name="android.app.cts.reference" android:resource="@xml/metadata" />
-        </activity>
-
-        <activity android:name="android.app.cts.TestedActivity"
-                android:process=":remoteActivity">
-        </activity>
-
-        <activity android:name="android.app.cts.ExpandableListTestActivity"
-            android:label="ExpandableListTestActivity">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
-            </intent-filter>
-        </activity>
-
-        <activity android:name="android.app.cts.ChildTabActivity" android:label="ChildTabActivity" />
-
-        <activity android:name="android.app.cts.LauncherActivityStub"
-                  android:label="LauncherActivityStub" >
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN"/>
-                <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
-            </intent-filter>
-        </activity>
-
-        <activity android:name="android.app.cts.MockTabActivity" android:label="MockTabActivity" />
-
-        <activity android:name="android.app.cts.AppStubActivity" android:label="AppStubActivity">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
-            </intent-filter>
-        </activity>
-
-        <activity android:name="android.app.cts.DialogStubActivity"
-                  android:theme="@style/Theme_NoSwipeDismiss"
-                  android:label="DialogStubActivity">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
-            </intent-filter>
-        </activity>
-
-        <activity android:name="android.app.cts.ActivityManagerStubFooActivity"
-            android:label="ActivityManagerStubFooActivity">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
-            </intent-filter>
-        </activity>
-
-        <activity android:name="android.app.cts.ActivityManagerRecentOneActivity"
-            android:label="ActivityManagerRecentOneActivity"
-            android:allowTaskReparenting="true"
-            android:taskAffinity="android.app.cts.recentOne">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-            </intent-filter>
-        </activity>
-
-        <activity android:name="android.app.cts.ActivityManagerRecentTwoActivity"
-            android:label="ActivityManagerRecentTwoActivity"
-            android:allowTaskReparenting="true"
-            android:taskAffinity="android.app.cts.recentTwo">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-            </intent-filter>
-        </activity>
-
-        <activity android:name="android.app.cts.ActivityManagerStubCrashActivity"
-            android:label="ActivityManagerStubCrashActivity"
-            android:multiprocess="true"
-            android:process=":ActivityManagerStubCrashActivity">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-            </intent-filter>
-        </activity>
-
-        <service android:name="android.app.cts.StubRemoteService"
-            android:process=":remote">
-            <intent-filter>
-                <action
-                    android:name="android.app.cts.ISecondary" />
-                <action
-                    android:name="android.app.REMOTESERVICE" />
-            </intent-filter>
-        </service>
-
-        <activity android:name="android.app.ActivityGroup"
-            android:label="ActivityGroup" />
-
-        <activity android:name="android.app.cts.KeyguardManagerActivity"
-            android:label="KeyguardManagerActivity">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
-            </intent-filter>
-        </activity>
-
-        <service android:name="android.app.cts.IntentServiceStub"/>
-
-        <activity android:name="android.app.cts.LaunchpadActivity"
-                  android:configChanges="keyboardHidden|orientation|screenSize"
-                  android:multiprocess="true">
-        </activity>
-
-        <activity android:name="android.app.cts.ActivityManagerMemoryClassLaunchActivity" />
-
-        <activity android:name="android.app.cts.ActivityManagerMemoryClassTestActivity"
-                android:process=":memoryclass" />
-
     </application>
 
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="android.app.stubs"
+                     android:label="CTS tests of android.app">
+        <meta-data android:name="listener"
+            android:value="com.android.cts.runner.CtsTestRunListener" />
+    </instrumentation>
+
 </manifest>
 
diff --git a/tests/app/AndroidTest.xml b/tests/app/AndroidTest.xml
new file mode 100644
index 0000000..6487bd7
--- /dev/null
+++ b/tests/app/AndroidTest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS App test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.LocationCheck" />
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsSimpleApp.apk" />
+        <option name="test-file-name" value="CtsAppTestStubs.apk" />
+        <option name="test-file-name" value="CtsAppTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.app.cts" />
+        <option name="runtime-hint" value="6m38s" />
+    </test>
+
+</configuration>
diff --git a/tests/app/OldAndroidTest.xml b/tests/app/OldAndroidTest.xml
new file mode 100644
index 0000000..01ebbcb
--- /dev/null
+++ b/tests/app/OldAndroidTest.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Base config for CTS package preparer">
+    <include name="common-config" />
+    <option name="cts-apk-installer:test-file-name" value="CtsSimpleApp.apk" />
+</configuration>
diff --git a/tests/app/app/Android.mk b/tests/app/app/Android.mk
new file mode 100644
index 0000000..24b5c5c
--- /dev/null
+++ b/tests/app/app/Android.mk
@@ -0,0 +1,38 @@
+# Copyright (C) 2008 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+# don't include this package in any target
+LOCAL_MODULE_TAGS := optional
+# and when built explicitly put it in the data partition
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_PROGUARD_ENABLED := disabled
+
+LOCAL_JAVA_LIBRARIES := android.test.runner telephony-common voip-common org.apache.http.legacy
+
+LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctstestrunner ctstestserver mockito-target
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src) \
+              src/android/app/stubs/ISecondary.aidl
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_PACKAGE_NAME := CtsAppTestStubs
+
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/tests/app/app/AndroidManifest.xml b/tests/app/app/AndroidManifest.xml
new file mode 100644
index 0000000..ea094ab
--- /dev/null
+++ b/tests/app/app/AndroidManifest.xml
@@ -0,0 +1,330 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.app.stubs">
+
+    <permission android:name="android.app.stubs.permission.TEST_GRANTED"
+        android:protectionLevel="normal"
+            android:label="@string/permlab_testGranted"
+            android:description="@string/permdesc_testGranted">
+        <meta-data android:name="android.app.stubs.string" android:value="foo" />
+        <meta-data android:name="android.app.stubs.boolean" android:value="true" />
+        <meta-data android:name="android.app.stubs.integer" android:value="100" />
+        <meta-data android:name="android.app.stubs.color" android:value="#ff000000" />
+        <meta-data android:name="android.app.stubs.float" android:value="100.1" />
+        <meta-data android:name="android.app.stubs.reference" android:resource="@xml/metadata" />
+    </permission>
+
+    <uses-permission android:name="android.app.stubs.permission.TEST_GRANTED" />
+    <uses-permission android:name="android.permission.READ_CONTACTS" />
+    <uses-permission android:name="android.permission.WRITE_CONTACTS" />
+    <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
+    <uses-permission android:name="android.permission.CAMERA" />
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
+    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
+    <uses-permission android:name="android.permission.SET_WALLPAPER_HINTS" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.BODY_SENSORS" />
+
+    <application android:label="Android TestCase"
+                android:icon="@drawable/size_48x48"
+                android:maxRecents="1"
+                android:multiArch="true"
+                android:name="android.app.stubs.MockApplication"
+                android:supportsRtl="true">
+        <uses-library android:name="android.test.runner" />
+        <uses-library android:name="org.apache.http.legacy" android:required="false" />
+
+        <activity android:name="android.app.stubs.ActionBarActivity" />
+
+        <activity android:name="android.app.stubs.DialogStubActivity"
+            android:label="DialogStubActivity"
+            android:configChanges="keyboardHidden|orientation|screenSize">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name="android.app.stubs.MockActivity" android:label="MockActivity">
+            <meta-data android:name="android.app.alias"
+                android:resource="@xml/alias" />
+            <meta-data android:name="android.app.intent.filter"
+                android:resource="@xml/intentfilter" />
+        </activity>
+
+        <activity android:name="android.app.stubs.MockApplicationActivity"
+            android:label="MockApplicationActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name="android.app.stubs.InstrumentationTestActivity"
+                  android:theme="@style/Theme_NoSwipeDismiss"
+                  android:label="InstrumentationTestActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <data android:mimeType="vnd.android.cursor.dir/person" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name="android.app.stubs.AliasActivityStub">
+            <meta-data android:name="android.app.alias"
+                android:resource="@xml/alias" />
+        </activity>
+
+        <activity android:name="android.app.stubs.ChildActivity"
+                        android:label="ChildActivity" />
+
+        <receiver android:name="android.app.stubs.MockReceiver">
+            <intent-filter>
+                <action android:name="android.app.stubs.PendingIntentTest.TEST_RECEIVER" />
+            </intent-filter>
+        </receiver>
+
+        <service android:name="android.app.stubs.MockService" />
+
+        <activity android:name="android.app.stubs.SearchManagerStubActivity"
+                android:label="SearchManagerStubActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.SEARCH" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+            <meta-data android:name="android.app.searchable" android:resource="@xml/searchable" />
+        </activity>
+
+        <service android:name="android.app.stubs.LocalService">
+            <intent-filter>
+                <action android:name="android.app.stubs.activity.SERVICE_LOCAL" />
+            </intent-filter>
+            <meta-data android:name="android.app.stubs.string" android:value="foo" />
+            <meta-data android:name="android.app.stubs.boolean" android:value="true" />
+            <meta-data android:name="android.app.stubs.integer" android:value="100" />
+            <meta-data android:name="android.app.stubs.color" android:value="#ff000000" />
+            <meta-data android:name="android.app.stubs.float" android:value="100.1" />
+            <meta-data android:name="android.app.stubs.reference" android:resource="@xml/metadata" />
+        </service>
+
+        <service android:name="android.app.stubs.LocalGrantedService"
+             android:permission="android.app.stubs.permission.TEST_GRANTED">
+            <intent-filter>
+                <action android:name="android.app.stubs.activity.SERVICE_LOCAL_GRANTED" />
+            </intent-filter>
+        </service>
+
+        <service android:name="android.app.stubs.LocalDeniedService"
+               android:permission="android.app.stubs.permission.TEST_DENIED">
+            <intent-filter>
+                <action android:name="android.app.stubs.activity.SERVICE_LOCAL_DENIED" />
+            </intent-filter>
+        </service>
+
+        <activity android:name="android.app.stubs.TestedScreen"
+                android:process=":remoteScreen">
+        </activity>
+        <activity android:name="android.app.stubs.LocalScreen" android:multiprocess="true">
+        </activity>
+        <activity android:name="android.app.stubs.ClearTop" android:multiprocess="true"
+               android:launchMode="singleTop">
+        </activity>
+        <activity android:name="android.app.stubs.LocalDialog" android:multiprocess="true"
+               android:theme="@android:style/Theme.Dialog">
+        </activity>
+
+        <activity android:name="android.app.stubs.PendingIntentStubActivity"
+             android:label="PendingIntentStubActivity"/>
+
+        <activity android:name="android.app.stubs.LocalActivityManagerStubActivity"
+                        android:label="LocalActivityManagerStubActivity" />
+
+        <activity android:name="android.app.stubs.LocalActivityManagerTestHelper"
+            android:label="LocalActivityManagerTestHelper" />
+
+        <activity android:name="android.app.stubs.LaunchpadTabActivity" android:multiprocess="true">
+        </activity>
+
+        <activity android:name="android.app.stubs.LocalActivity" android:multiprocess="true">
+            <meta-data android:name="android.app.stubs.string" android:value="foo" />
+            <meta-data android:name="android.app.stubs.boolean" android:value="true" />
+            <meta-data android:name="android.app.stubs.integer" android:value="100" />
+            <meta-data android:name="android.app.stubs.color" android:value="#ff000000" />
+            <meta-data android:name="android.app.stubs.float" android:value="100.1" />
+            <meta-data android:name="android.app.stubs.reference" android:resource="@xml/metadata" />
+        </activity>
+
+        <activity android:name="android.app.stubs.TestedActivity"
+                android:process=":remoteActivity">
+        </activity>
+
+        <activity android:name="android.app.stubs.ExpandableListTestActivity"
+            android:label="ExpandableListTestActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name="android.app.stubs.FragmentTestActivity"
+            android:label="FragmentTestActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name="android.app.stubs.ChildTabActivity" android:label="ChildTabActivity" />
+
+        <activity android:name="android.app.stubs.LauncherActivityStub"
+                  android:label="LauncherActivityStub" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name="android.app.stubs.MockTabActivity" android:label="MockTabActivity" />
+
+        <activity android:name="android.app.stubs.MockListActivity" android:label="MockListActivity" />
+
+        <activity android:name="android.app.stubs.AppStubActivity" android:label="AppStubActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name="android.app.stubs.DialogStubActivity"
+                  android:theme="@style/Theme_NoSwipeDismiss"
+                  android:label="DialogStubActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name="android.app.stubs.ActivityManagerStubFooActivity"
+            android:label="ActivityManagerStubFooActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name="android.app.stubs.ActivityManagerRecentOneActivity"
+            android:label="ActivityManagerRecentOneActivity"
+            android:allowTaskReparenting="true"
+            android:taskAffinity="android.app.stubs.recentOne">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name="android.app.stubs.ActivityManagerRecentTwoActivity"
+            android:label="ActivityManagerRecentTwoActivity"
+            android:allowTaskReparenting="true"
+            android:taskAffinity="android.app.stubs.recentTwo">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name="android.app.stubs.ActivityManagerStubCrashActivity"
+            android:label="ActivityManagerStubCrashActivity"
+            android:multiprocess="true"
+            android:process=":ActivityManagerStubCrashActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+            </intent-filter>
+        </activity>
+
+        <service android:name="android.app.stubs.StubRemoteService"
+            android:process=":remote">
+            <intent-filter>
+                <action
+                    android:name="android.app.stubs.ISecondary" />
+                <action
+                    android:name="android.app.REMOTESERVICE" />
+            </intent-filter>
+        </service>
+
+        <activity android:name="android.app.ActivityGroup"
+            android:label="ActivityGroup" />
+
+        <activity android:name="android.app.stubs.KeyguardManagerActivity"
+            android:label="KeyguardManagerActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+            </intent-filter>
+        </activity>
+
+        <service android:name="android.app.stubs.IntentServiceStub"/>
+
+        <activity android:name="android.app.stubs.LaunchpadActivity"
+                  android:configChanges="keyboardHidden|orientation|screenSize"
+                  android:multiprocess="true">
+        </activity>
+
+        <activity android:name="android.app.stubs.ActivityManagerMemoryClassLaunchActivity" />
+
+        <activity android:name="android.app.stubs.ActivityManagerMemoryClassTestActivity"
+                android:process=":memoryclass" />
+
+        <activity android:name="android.app.stubs.PipActivity"
+                  android:label="PipActivity"
+                  android:resizeableActivity="true"
+                  android:supportsPictureInPicture="true"
+                  android:configChanges="smallestScreenSize|orientation|screenSize|screenLayout">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name="android.app.stubs.PipNotResizeableActivity"
+                  android:label="PipNotResizeableActivity"
+                  android:resizeableActivity="false"
+                  android:supportsPictureInPicture="true"
+                  android:configChanges="smallestScreenSize|orientation|screenSize|screenLayout">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name="android.app.stubs.PipNotSupportedActivity"
+                  android:label="PipNotSupportedActivity"
+                  android:resizeableActivity="true"
+                  android:supportsPictureInPicture="false"
+                  android:configChanges="smallestScreenSize|orientation|screenSize|screenLayout">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name="android.app.stubs.KeyboardShortcutsActivity" />
+
+    </application>
+
+</manifest>
+
diff --git a/tests/app/assets/noiseandchirps b/tests/app/app/assets/noiseandchirps
similarity index 100%
rename from tests/app/assets/noiseandchirps
rename to tests/app/app/assets/noiseandchirps
Binary files differ
diff --git a/tests/app/assets/noiseandchirps.mp3 b/tests/app/app/assets/noiseandchirps.mp3
similarity index 100%
rename from tests/app/assets/noiseandchirps.mp3
rename to tests/app/app/assets/noiseandchirps.mp3
Binary files differ
diff --git a/tests/app/assets/noiseandchirps.ogg b/tests/app/app/assets/noiseandchirps.ogg
similarity index 100%
rename from tests/app/assets/noiseandchirps.ogg
rename to tests/app/app/assets/noiseandchirps.ogg
Binary files differ
diff --git a/tests/app/assets/noiseandchirps.wrong b/tests/app/app/assets/noiseandchirps.wrong
similarity index 100%
rename from tests/app/assets/noiseandchirps.wrong
rename to tests/app/app/assets/noiseandchirps.wrong
Binary files differ
diff --git a/tests/app/res/drawable/icon_black.jpg b/tests/app/app/res/drawable/icon_black.jpg
similarity index 100%
rename from tests/app/res/drawable/icon_black.jpg
rename to tests/app/app/res/drawable/icon_black.jpg
Binary files differ
diff --git a/tests/app/res/drawable/icon_blue.jpg b/tests/app/app/res/drawable/icon_blue.jpg
similarity index 100%
rename from tests/app/res/drawable/icon_blue.jpg
rename to tests/app/app/res/drawable/icon_blue.jpg
Binary files differ
diff --git a/tests/app/res/drawable/icon_green.jpg b/tests/app/app/res/drawable/icon_green.jpg
similarity index 100%
rename from tests/app/res/drawable/icon_green.jpg
rename to tests/app/app/res/drawable/icon_green.jpg
Binary files differ
diff --git a/tests/app/res/drawable/icon_red.jpg b/tests/app/app/res/drawable/icon_red.jpg
similarity index 100%
rename from tests/app/res/drawable/icon_red.jpg
rename to tests/app/app/res/drawable/icon_red.jpg
Binary files differ
diff --git a/tests/app/res/drawable/icon_yellow.jpg b/tests/app/app/res/drawable/icon_yellow.jpg
similarity index 100%
rename from tests/app/res/drawable/icon_yellow.jpg
rename to tests/app/app/res/drawable/icon_yellow.jpg
Binary files differ
diff --git a/tests/app/res/drawable/ninepatch_0.9.png b/tests/app/app/res/drawable/ninepatch_0.9.png
similarity index 100%
rename from tests/app/res/drawable/ninepatch_0.9.png
rename to tests/app/app/res/drawable/ninepatch_0.9.png
Binary files differ
diff --git a/tests/app/res/drawable/ninepatch_1.9.png b/tests/app/app/res/drawable/ninepatch_1.9.png
similarity index 100%
rename from tests/app/res/drawable/ninepatch_1.9.png
rename to tests/app/app/res/drawable/ninepatch_1.9.png
Binary files differ
diff --git a/tests/app/res/drawable/pass.jpg b/tests/app/app/res/drawable/pass.jpg
similarity index 100%
rename from tests/app/res/drawable/pass.jpg
rename to tests/app/app/res/drawable/pass.jpg
Binary files differ
diff --git a/tests/app/res/drawable/robot.png b/tests/app/app/res/drawable/robot.png
similarity index 100%
rename from tests/app/res/drawable/robot.png
rename to tests/app/app/res/drawable/robot.png
Binary files differ
diff --git a/tests/app/res/drawable/size_48x48.jpg b/tests/app/app/res/drawable/size_48x48.jpg
similarity index 100%
rename from tests/app/res/drawable/size_48x48.jpg
rename to tests/app/app/res/drawable/size_48x48.jpg
Binary files differ
diff --git a/tests/app/app/res/layout/activity_content.xml b/tests/app/app/res/layout/activity_content.xml
new file mode 100644
index 0000000..8870e60
--- /dev/null
+++ b/tests/app/app/res/layout/activity_content.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+             android:id="@+id/content"
+             android:layout_width="match_parent"
+             android:layout_height="match_parent"/>
diff --git a/tests/app/res/layout/alert_dialog_text_entry.xml b/tests/app/app/res/layout/alert_dialog_text_entry.xml
similarity index 100%
rename from tests/app/res/layout/alert_dialog_text_entry.xml
rename to tests/app/app/res/layout/alert_dialog_text_entry.xml
diff --git a/tests/app/app/res/layout/alert_dialog_text_entry_2.xml b/tests/app/app/res/layout/alert_dialog_text_entry_2.xml
new file mode 100644
index 0000000..5dc8b1b
--- /dev/null
+++ b/tests/app/app/res/layout/alert_dialog_text_entry_2.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/username_form"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical">
+
+    <TextView
+        android:id="@+id/username_view"
+        android:layout_height="wrap_content"
+        android:layout_width="wrap_content"
+        android:layout_marginLeft="20dip"
+        android:layout_marginRight="20dip"
+        android:text="@string/alert_dialog_username"
+        android:gravity="left" />
+
+    <EditText
+        android:id="@+id/username_edit"
+        android:layout_height="wrap_content"
+        android:layout_width="match_parent"
+        android:layout_marginLeft="20dip"
+        android:layout_marginRight="20dip"
+        android:scrollHorizontally="true"
+        android:autoText="false"
+        android:capitalize="none"
+        android:gravity="fill_horizontal" />
+
+</LinearLayout>
diff --git a/tests/app/res/layout/alertdialog_custom_title.xml b/tests/app/app/res/layout/alertdialog_custom_title.xml
similarity index 100%
rename from tests/app/res/layout/alertdialog_custom_title.xml
rename to tests/app/app/res/layout/alertdialog_custom_title.xml
diff --git a/tests/app/res/layout/app_activity.xml b/tests/app/app/res/layout/app_activity.xml
similarity index 100%
rename from tests/app/res/layout/app_activity.xml
rename to tests/app/app/res/layout/app_activity.xml
diff --git a/tests/app/res/layout/checkbox_layout.xml b/tests/app/app/res/layout/checkbox_layout.xml
similarity index 100%
rename from tests/app/res/layout/checkbox_layout.xml
rename to tests/app/app/res/layout/checkbox_layout.xml
diff --git a/tests/app/res/layout/dialog_stub_layout.xml b/tests/app/app/res/layout/dialog_stub_layout.xml
similarity index 100%
rename from tests/app/res/layout/dialog_stub_layout.xml
rename to tests/app/app/res/layout/dialog_stub_layout.xml
diff --git a/tests/app/app/res/layout/fragment_a.xml b/tests/app/app/res/layout/fragment_a.xml
new file mode 100644
index 0000000..38e0423
--- /dev/null
+++ b/tests/app/app/res/layout/fragment_a.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent"
+              android:orientation="vertical">
+    <TextView android:layout_width="wrap_content"
+              android:layout_height="wrap_content"
+              android:id="@+id/textA"
+              android:text="@string/hello"/>
+</LinearLayout>
diff --git a/tests/app/app/res/layout/fragment_b.xml b/tests/app/app/res/layout/fragment_b.xml
new file mode 100644
index 0000000..d8ed961
--- /dev/null
+++ b/tests/app/app/res/layout/fragment_b.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent"
+              android:orientation="vertical">
+    <TextView android:layout_width="wrap_content"
+              android:layout_height="wrap_content"
+              android:id="@+id/textB"
+              android:text="@string/hello"/>
+</LinearLayout>
diff --git a/tests/app/app/res/layout/fragment_c.xml b/tests/app/app/res/layout/fragment_c.xml
new file mode 100644
index 0000000..ed3c753
--- /dev/null
+++ b/tests/app/app/res/layout/fragment_c.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent"
+              android:orientation="vertical">
+    <TextView android:layout_width="wrap_content"
+              android:layout_height="wrap_content"
+              android:id="@+id/textC"
+              android:text="@string/hello"/>
+</LinearLayout>
diff --git a/tests/app/app/res/layout/fragment_end.xml b/tests/app/app/res/layout/fragment_end.xml
new file mode 100644
index 0000000..aa3d9e8
--- /dev/null
+++ b/tests/app/app/res/layout/fragment_end.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent"
+              android:orientation="vertical">
+    <TextView android:layout_width="wrap_content"
+              android:layout_height="wrap_content"
+              android:transitionName="destination"
+              android:id="@+id/hello"
+              android:text="@string/hello"/>
+    <View android:layout_width="10dp"
+          android:layout_height="10dp"
+          android:background="#0F0"
+          android:id="@+id/greenSquare"/>
+    <View android:layout_width="10dp"
+          android:layout_height="10dp"
+          android:background="#F00"
+          android:id="@+id/redSquare"/>
+</LinearLayout>
diff --git a/tests/app/app/res/layout/fragment_start.xml b/tests/app/app/res/layout/fragment_start.xml
new file mode 100644
index 0000000..793e9b5
--- /dev/null
+++ b/tests/app/app/res/layout/fragment_start.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent"
+              android:orientation="vertical">
+    <View android:layout_width="10dp"
+          android:layout_height="10dp"
+          android:background="#0F0"
+          android:id="@+id/greenSquare"/>
+    <View android:layout_width="10dp"
+          android:layout_height="10dp"
+          android:background="#F00"
+          android:id="@+id/redSquare"/>
+    <TextView android:layout_width="wrap_content"
+              android:layout_height="wrap_content"
+              android:transitionName="source"
+              android:id="@+id/hello"
+              android:text="@string/hello"/>
+</LinearLayout>
diff --git a/tests/app/res/menu/browser.xml b/tests/app/app/res/menu/browser.xml
similarity index 100%
rename from tests/app/res/menu/browser.xml
rename to tests/app/app/res/menu/browser.xml
diff --git a/tests/app/res/values/arrays.xml b/tests/app/app/res/values/arrays.xml
similarity index 100%
rename from tests/app/res/values/arrays.xml
rename to tests/app/app/res/values/arrays.xml
diff --git a/tests/app/res/values/attrs.xml b/tests/app/app/res/values/attrs.xml
similarity index 100%
rename from tests/app/res/values/attrs.xml
rename to tests/app/app/res/values/attrs.xml
diff --git a/tests/app/res/values/colors.xml b/tests/app/app/res/values/colors.xml
similarity index 100%
rename from tests/app/res/values/colors.xml
rename to tests/app/app/res/values/colors.xml
diff --git a/tests/app/app/res/values/strings.xml b/tests/app/app/res/values/strings.xml
new file mode 100644
index 0000000..5e9e6d7
--- /dev/null
+++ b/tests/app/app/res/values/strings.xml
@@ -0,0 +1,180 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="permlab_testGranted">Test Granted</string>
+    <string name="permdesc_testGranted">Used for running CTS tests, for testing operations
+        where we have the permission.</string>
+    <string name="permlab_testDynamic">Test Dynamic</string>
+    <string name="permdesc_testDynamic">Used for running CTS tests, for testing adding
+        dynamic permissions.</string>
+    <string name="permlab_testDenied">Test Denied</string>
+    <string name="permdesc_testDenied">Used for running CTS tests, for testing operations
+        where we do not have the permission.</string>
+    <string name="explain">1. click start. \n2. if above image shaked, then press pass button,
+         else press failed button.</string>
+    <string name="text_view_hello">Hello! Text view!</string>
+    <string name="text_view_hello_two_lines">Hello! \nText view!</string>
+    <string name="text_view_simple_hint">This is a hint.</string>
+    <string name="text_view_hint">This is a string for testing hint of textview.</string>
+    <string name="activity_forwarding">App/Forwarding</string>
+    <string name="forwarding">$$$</string>
+    <string name="go">Go</string>
+    <string name="back">Back</string>
+    <string name="forward_target">
+        Press back button and notice we don\'t see the previous activity.
+    </string>
+    <string name="edit_text">testing</string>
+    <string name="text">DialogTest</string>
+    <string name="text_country">Country</string>
+    <string name="text_name">Name</string>
+    <string name="hello_world">Hello, World!</string>
+    <string name="hello_android">Hello, Android!</string>
+    <string name="alert_dialog_username">Name:</string>
+    <string name="alert_dialog_password">Password:</string>
+    <string name="alert_dialog_positive">Positive</string>
+    <string name="alert_dialog_negative">Negative</string>
+    <string name="alert_dialog_neutral">Neutral</string>
+    <string name="notify">Notify </string>
+    <string name="tabs_1">testing</string>
+    <string name="table_layout_first">first</string>
+    <string name="table_layout_second">second</string>
+    <string name="table_layout_third">third</string>
+    <string name="table_layout_long">Very long to make the string out of the screen</string>
+    <string name="chronometer_text">Test Chronometer</string>
+    <string name="am">AM</string>
+    <string name="pm">PM</string>
+    <string name="viewgroup_test">ViewGroup test</string>
+    <string name="viewanimator_test">ViewAnimator test</string>
+    <string name="id_ok">OK</string>
+    <string name="id_cancel">Cancel</string>
+    <string name="context_test_string1">This is %s string.</string>
+    <string name="context_test_string2">This is test string.</string>
+    <string name="animationutils_test_instructions">Choose different animations</string>
+    <string name="animationutils_test_alpha">Alpha animation</string>
+    <string name="animationutils_test_scale">Scale animation</string>
+    <string name="animationutils_test_rotate">Rotate animation</string>
+    <string name="animationutils_test_translate">Translate animation</string>
+    <string name="animationutils_test_set">Animation set</string>
+    <string name="animationutils_test_layout">Layout animation</string>
+    <string name="animationutils_test_gridlayout">Grid layout animation</string>
+    <string name="twolinelistitem_test_text1">text1</string>
+    <string name="twolinelistitem_test_text2">text2</string>
+    <string name="metadata_text">metadata text</string>
+    <string name="horizontal_text_1">horizontal 1</string>
+    <string name="horizontal_text_2">horizontal 2</string>
+    <string name="horizontal_text_3">horizontal 3</string>
+    <string name="vertical_text_1">vertical 1</string>
+    <string name="vertical_text_2">vertical 2</string>
+    <string name="vertical_text_3">vertical 3</string>
+    <string name="reference">here</string>
+    <string name="coerceIntegerToString">100</string>
+    <string name="coerceBooleanToString">true</string>
+    <string name="coerceColorToString">#fff</string>
+    <string name="coerceFloatToString">100.0</string>
+    <string name="coerceDimensionToString">100px</string>
+    <string name="coerceFractionToString">100<xliff:g id="percent">%</xliff:g></string>
+    <string name="formattedStringNone">Format[]</string>
+    <string name="formattedStringOne">Format[<xliff:g id="format">%d</xliff:g>]</string>
+    <string name="formattedStringTwo">Format[<xliff:g id="format">%3$d,%2$s</xliff:g>]</string>
+    <string name="checkboxpref_key">checkboxpref_key</string>
+   <string name="checkboxpref_title">title of preference</string>
+   <string name="checkboxpref_summary">summary of preference</string>
+   <string name="checkboxpref_summary_on">summary on of preference</string>
+   <string name="checkboxpref_summary_off">summary off of preference</string>
+   <string name="checkboxpref_depend">checkboxpref_depend</string>
+   <string name="checkboxpref_depend_title"> depend title of preference</string>
+   <string name="checkboxpref_depend_summary"> depend summary of preference</string>
+   <string name="edittextpref_key">edittextpref_key</string>
+   <string name="edittextpref_default_value">default value of preference</string>
+   <string name="edittextpref_title">title of edit text preference</string>
+   <string name="edittextpref_summary">summary of edit text preference</string>
+   <string name="edittextpref_dialog_title">dialog title of edit text preference</string>
+   <string name="edittextpref_text">text of  edit text preference</string>
+   <string name="listpref_key">listpref_key</string>
+   <string name="listpref_title">title of list preference</string>
+   <string name="listpref_summary">summary of list preference</string>
+   <string name="listpref_dialogtitle">dialog title of list preference</string>
+   <string name="easy">Easy</string>
+   <string name="medium">Medium</string>
+   <string name="hard">Hard</string>
+   <string name="footer_view">Footer view</string>
+   <string name="header_view">Header view</string>
+   <string name="dialogpref_title">title of dialog preference </string>
+   <string name="dialogpref_dialog_title">dialog title of dialog preference </string>
+   <string name="dialogpref_key">dialogpref_key</string>
+   <string name="dialogpref_default_value">default value of dialog preference</string>
+   <string name="dialogpref_summary">summary of dialog preference</string>
+   <string name="dialogpref_message">message of dialog preference</string>
+   <string name="dialogpref_sure">Sure</string>
+   <string name="dialogpref_cancel">Cancel</string>
+   <string name="pref_key">pref_key</string>
+   <string name="pref_title">title of preference</string>
+   <string name="pref_summary">summary of preference</string>
+   <string name="pref_depend_key">pref_depend_key</string>
+   <string name="pref_depend_title"> depend title of preference</string>
+   <string name="pref_depend_summary"> depend summary of preference</string>
+   <string name="android_intent_action_preference">android.intent.action.PREFERENCE</string>
+   <string name="def_pref_key">def_pref_key</string>
+   <string name="def_pref_title">default preference</string>
+   <string name="def_pref_summary">This is default preference of cts</string>
+   <string name="relative_view1">view 1</string>
+   <string name="relative_view2">view 2</string>
+   <string name="relative_view3">view 3</string>
+   <string name="relative_view4">view 4</string>
+   <string name="relative_view5">view 5</string>
+   <string name="relative_view6">view 6</string>
+   <string name="relative_view7">view 7</string>
+   <string name="relative_view8">view 8</string>
+   <string name="relative_view9">view 9</string>
+   <string name="relative_view10">view 10</string>
+   <string name="relative_view11">view 11</string>
+   <string name="relative_view12">view 12</string>
+   <string name="relative_view13">view 13</string>
+   <string name="country">Country:</string>
+   <string name="symbol">Symbol:</string>
+   <string name="country_warning">No such country registered</string>
+   <string name="version_cur">base</string>
+   <string name="version_old">base</string>
+   <string name="version_v3">base</string>
+   <string name="authenticator_label">Android CTS</string>
+   <string name="search_label">Android CTS</string>
+   <string name="tag1">tag 1</string>
+   <string name="tag2">tag 2</string>
+
+   <string name="button">Button</string>
+   <string name="holo_test">Holo Test</string>
+   <string name="holo_generator">Holo Generator</string>
+   <string name="holo_light_test">Holo Light Test</string>
+   <string name="holo_light_generator">Holo Light Generator</string>
+   <string name="reference_image">Reference Image: </string>
+   <string name="generated_image">Generated Image: </string>
+   <string name="themes_prompt">Select a Theme:</string>
+   <string name="sample_text">Sample text goes here. I wanted something creative and whimsical
+but then I just got bored...</string>
+    <string name="long_text">This is a really long string which exceeds the width of the view.
+New devices have a much larger screen which actually enables long strings to be displayed
+with no fading. I have made this string longer to fix this case. If you are correcting this
+text, I would love to see the kind of devices you guys now use! Guys, maybe some devices need longer string!
+I think so, so how about double this string, like copy and paste!
+This is a really long string which exceeds the width of the view.
+New devices have a much larger screen which actually enables long strings to be displayed
+with no fading. I have made this string longer to fix this case. If you are correcting this
+text, I would love to see the kind of devices you guys now use! Guys, maybe some devices need longer string!
+I think so, so how about double this string, like copy and paste! </string>
+    <string name="rectangle200">"M 0,0 l 200,0 l 0, 200 l -200, 0 z"</string>
+    <string name="hello">Hello World</string>
+</resources>
diff --git a/tests/app/app/res/values/styles.xml b/tests/app/app/res/values/styles.xml
new file mode 100644
index 0000000..9f62d79
--- /dev/null
+++ b/tests/app/app/res/values/styles.xml
@@ -0,0 +1,176 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <style name="Whatever">
+        <item name="type1">true</item>
+        <item name="type2">false</item>
+        <item name="type3">#ff0000ff</item>
+        <item name="type4">#ff00ff00</item>
+        <item name="type5">0.75px</item>
+        <item name="type6">10px</item>
+        <item name="type7">18px</item>
+        <item name="type8">@drawable/pass</item>
+        <item name="type9">3.14</item>
+        <item name="type10">100%</item>
+        <item name="type11">365</item>
+        <item name="type12">86400</item>
+        <item name="type13">@string/hello_android</item>
+        <item name="type14">TypedArray Test!</item>
+        <item name="type15">@array/difficultyLevel</item>
+        <item name="type16">Typed Value!</item>
+    </style>
+
+    <style name="TextViewWithoutColorAndAppearance">
+        <item name="android:textSize">18sp</item>
+    </style>
+
+    <style name="TextViewWithColorButWithOutAppearance">
+        <item name="android:textColor">#ff0000ff</item>
+    </style>
+
+    <style name="TextViewWithColorAndAppearance">
+        <item name="android:textColor">#ff0000ff</item>
+        <item name="android:textAppearance">@style/TextAppearance.WithColor</item>
+    </style>
+
+    <style name="TextViewWithoutColorButWithAppearance">
+        <item name="android:textAppearance">@style/TextAppearance.WithColor</item>
+    </style>
+
+    <style name="TextAppearance" parent="android:TextAppearance">
+    </style>
+
+    <style name="TextAppearance.WithColor">
+        <item name="android:textColor">#ffff0000</item>
+    </style>
+
+    <style name="TextAppearance.All">
+        <item name="android:textColor">@drawable/black</item>
+        <item name="android:textSize">20px</item>
+        <item name="android:textStyle">bold</item>
+        <item name="android:textColorHint">@drawable/red</item>
+        <item name="android:textColorLink">@drawable/blue</item>
+        <item name="android:textColorHighlight">@drawable/yellow</item>
+    </style>
+
+    <style name="TextAppearance.Colors">
+        <item name="android:textColor">@drawable/black</item>
+        <item name="android:textColorHint">@drawable/blue</item>
+        <item name="android:textColorLink">@drawable/yellow</item>
+        <item name="android:textColorHighlight">@drawable/red</item>
+    </style>
+
+    <style name="TextAppearance.NotColors">
+        <item name="android:textSize">17px</item>
+        <item name="android:typeface">sans</item>
+        <item name="android:textStyle">normal</item>
+    </style>
+
+    <style name="TextAppearance.Style">
+        <item name="android:textStyle">normal</item>
+    </style>
+
+    <style name="TestEnum1">
+        <item name="testEnum">val1</item>
+    </style>
+
+    <style name="TestEnum2">
+        <item name="testEnum">val2</item>
+    </style>
+
+    <style name="TestEnum10">
+        <item name="testEnum">val10</item>
+    </style>
+
+    <style name="TestFlag1">
+        <item name="testFlags">bit1</item>
+    </style>
+
+    <style name="TestFlag2">
+        <item name="testFlags">bit2</item>
+    </style>
+
+    <style name="TestFlag31">
+        <item name="testFlags">bit31</item>
+    </style>
+
+    <style name="TestFlag1And2">
+        <item name="testFlags">bit1|bit2</item>
+    </style>
+
+    <style name="TestFlag1And2And31">
+        <item name="testFlags">bit1|bit2|bit31</item>
+    </style>
+
+    <style name="TestEnum1.EmptyInherit" />
+
+    <style name="Theme_AlertDialog">
+        <item name="android:textSize">18sp</item>
+    </style>
+
+    <style name="TestProgressBar">
+        <item name="android:indeterminateOnly">false</item>
+        <item name="android:progressDrawable">?android:drawable/progress_horizontal</item>
+        <item name="android:indeterminateDrawable">?android:drawable/progress_horizontal</item>
+        <item name="android:minHeight">20dip</item>
+        <item name="android:maxHeight">20dip</item>
+        <item name="android:focusable">true</item>
+    </style>
+
+    <style name="Test_Theme">
+        <item name="android:windowNoTitle">true</item>
+        <item name="android:panelColorForeground">#ff000000</item>
+        <item name="android:panelColorBackground">#ffffffff</item>
+    </style>
+
+    <style name="Theme_OverrideOuter">
+        <item name="themeType">1</item>
+    </style>
+
+    <style name="Theme_OverrideInner">
+        <item name="themeType">2</item>
+        <item name="themeOverrideAttr">@style/Theme_OverrideAttr</item>
+    </style>
+
+    <style name="Theme_OverrideAttr">
+        <item name="themeType">3</item>
+    </style>
+
+    <style name="Theme_ThemedDrawableTest">
+        <item name="themeBoolean">true</item>
+        <item name="themeColor">@android:color/black</item>
+        <item name="themeFloat">1.0</item>
+        <item name="themeAngle">45.0</item>
+        <item name="themeInteger">1</item>
+        <item name="themeDimension">1px</item>
+        <item name="themeDrawable">@drawable/icon_black</item>
+        <item name="themeBitmap">@drawable/icon_black</item>
+        <item name="themeNinePatch">@drawable/ninepatch_0</item>
+        <item name="themeGravity">48</item>
+        <item name="themeTileMode">2</item>
+    </style>
+
+    <style name="Theme_NoSwipeDismiss">
+        <item name="android:windowSwipeToDismiss">false</item>
+    </style>
+
+    <style name="DialogTheme_Test" parent="@android:style/Theme.Material.Dialog">
+        <item name="themeInteger">20</item>
+    </style>
+
+</resources>
diff --git a/tests/app/app/res/xml/alias.xml b/tests/app/app/res/xml/alias.xml
new file mode 100644
index 0000000..de3f557
--- /dev/null
+++ b/tests/app/app/res/xml/alias.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+-->
+
+<alias xmlns:android="http://schemas.android.com/apk/res/android">
+    <intent android:action="android.intent.action.MAIN"
+        android:targetPackage="android.app.stubs"
+        android:targetClass="android.app.stubs.ChildActivity"
+        android:data="http://www.google.com/">
+    </intent>
+</alias>
+
diff --git a/tests/app/res/xml/intentfilter.xml b/tests/app/app/res/xml/intentfilter.xml
similarity index 100%
rename from tests/app/res/xml/intentfilter.xml
rename to tests/app/app/res/xml/intentfilter.xml
diff --git a/tests/app/res/xml/metadata.xml b/tests/app/app/res/xml/metadata.xml
similarity index 100%
rename from tests/app/res/xml/metadata.xml
rename to tests/app/app/res/xml/metadata.xml
diff --git a/tests/app/res/xml/searchable.xml b/tests/app/app/res/xml/searchable.xml
similarity index 100%
rename from tests/app/res/xml/searchable.xml
rename to tests/app/app/res/xml/searchable.xml
diff --git a/tests/app/app/src/android/app/stubs/ActionBarActivity.java b/tests/app/app/src/android/app/stubs/ActionBarActivity.java
new file mode 100644
index 0000000..ec27b1b
--- /dev/null
+++ b/tests/app/app/src/android/app/stubs/ActionBarActivity.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.stubs;
+
+import android.app.ActionBar;
+import android.app.Activity;
+import android.os.Bundle;
+
+public class ActionBarActivity extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        ActionBar bar = getActionBar();
+        if (bar != null) {
+            bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
+        }
+    }
+}
diff --git a/tests/app/app/src/android/app/stubs/ActivityManagerMemoryClassLaunchActivity.java b/tests/app/app/src/android/app/stubs/ActivityManagerMemoryClassLaunchActivity.java
new file mode 100644
index 0000000..d79467c
--- /dev/null
+++ b/tests/app/app/src/android/app/stubs/ActivityManagerMemoryClassLaunchActivity.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.stubs;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * {@link Activity} that just launches {@link ActivityManagerMemoryClassTestActivity} and
+ * returns the result of that activity.
+ */
+public class ActivityManagerMemoryClassLaunchActivity extends Activity {
+
+    public static final String MEMORY_CLASS_EXTRA = "activityMemoryClass";
+
+    private static final int TEST_ACTIVITY_REQUEST_CODE = 1337;
+
+    private final CountDownLatch mLatch = new CountDownLatch(1);
+
+    private int mChildResult = RESULT_CANCELED;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // Start the activity that runs in a separate process to do the actual testing,
+        // since the test itself cannot start an activity in a separate process. A separate
+        // process is used to avoid including the overhead of the test instrumentation process.
+
+        Intent intent = getIntent();
+        int memoryClass = intent.getIntExtra(MEMORY_CLASS_EXTRA, -1);
+
+        Intent testIntent = new Intent(this, ActivityManagerMemoryClassTestActivity.class);
+        testIntent.putExtra(MEMORY_CLASS_EXTRA, memoryClass);
+        startActivityForResult(testIntent, TEST_ACTIVITY_REQUEST_CODE);
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        super.onActivityResult(requestCode, resultCode, data);
+        if (requestCode == 1337) {
+            synchronized (this) {
+                mChildResult = resultCode;
+            }
+        } else {
+            throw new IllegalStateException("Request code: " + requestCode);
+        }
+    }
+
+    public int getResult() throws InterruptedException {
+        mLatch.await(5, TimeUnit.SECONDS);
+        synchronized (this) {
+            return mChildResult;
+        }
+    }
+}
diff --git a/tests/app/app/src/android/app/stubs/ActivityManagerMemoryClassTestActivity.java b/tests/app/app/src/android/app/stubs/ActivityManagerMemoryClassTestActivity.java
new file mode 100644
index 0000000..09566aa
--- /dev/null
+++ b/tests/app/app/src/android/app/stubs/ActivityManagerMemoryClassTestActivity.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.stubs;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.util.Log;
+
+/**
+ * {@link Activity} that allocates arrays of 256k until reaching 75% of the specified memory class.
+ */
+public class ActivityManagerMemoryClassTestActivity extends Activity {
+
+    private static final String TAG = "ActivityManagerMemoryClassTest";
+
+    private static final double FREE_MEMORY_PERCENTAGE = 0.75;
+
+    private static final int ARRAY_BYTES_SIZE = 256 * 1024;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        Intent intent = getIntent();
+        int memoryClass =
+                intent.getIntExtra(ActivityManagerMemoryClassLaunchActivity.MEMORY_CLASS_EXTRA, -1);
+        new AllocateMemoryTask(memoryClass).execute();
+    }
+
+    private class AllocateMemoryTask extends AsyncTask<Void, Void, Void> {
+
+        private final int mMemoryClass;
+
+        AllocateMemoryTask(int memoryClass) {
+            this.mMemoryClass = memoryClass;
+        }
+
+        @Override
+        protected Void doInBackground(Void... params) {
+            int targetMbs = (int) (mMemoryClass * FREE_MEMORY_PERCENTAGE);
+            int numArrays = targetMbs * 1024 * 1024 / ARRAY_BYTES_SIZE;
+            Log.i(TAG, "Memory class: " + mMemoryClass + "mb Target memory: "
+                    + targetMbs + "mb Number of arrays: " + numArrays);
+
+            byte[][] arrays = new byte[numArrays][];
+            for (int i = 0; i < arrays.length; i++) {
+                Log.i(TAG, "Allocating array " + i + " of " + arrays.length
+                        + " (" + (i * ARRAY_BYTES_SIZE / 1024 / 1024) + "mb)");
+                arrays[i] = new byte[ARRAY_BYTES_SIZE];
+            }
+            return null;
+        }
+
+        @Override
+        protected void onPostExecute(Void result) {
+            super.onPostExecute(result);
+            setResult(RESULT_OK);
+            finish();
+        }
+    }
+}
diff --git a/tests/app/app/src/android/app/stubs/ActivityManagerRecentOneActivity.java b/tests/app/app/src/android/app/stubs/ActivityManagerRecentOneActivity.java
new file mode 100644
index 0000000..41944bd
--- /dev/null
+++ b/tests/app/app/src/android/app/stubs/ActivityManagerRecentOneActivity.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.stubs;
+
+import android.app.Activity;
+
+public class ActivityManagerRecentOneActivity extends Activity {
+}
diff --git a/tests/app/app/src/android/app/stubs/ActivityManagerRecentTwoActivity.java b/tests/app/app/src/android/app/stubs/ActivityManagerRecentTwoActivity.java
new file mode 100644
index 0000000..136e565
--- /dev/null
+++ b/tests/app/app/src/android/app/stubs/ActivityManagerRecentTwoActivity.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.stubs;
+
+import android.app.Activity;
+
+public class ActivityManagerRecentTwoActivity extends Activity {
+}
diff --git a/tests/app/app/src/android/app/stubs/ActivityManagerStubCrashActivity.java b/tests/app/app/src/android/app/stubs/ActivityManagerStubCrashActivity.java
new file mode 100644
index 0000000..f6bef49
--- /dev/null
+++ b/tests/app/app/src/android/app/stubs/ActivityManagerStubCrashActivity.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.stubs;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.TextView;
+
+public class ActivityManagerStubCrashActivity extends Activity {
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        final TextView tv = new TextView(this);
+        tv.setText("Hello, Android but crash");
+        setContentView(tv);
+        die();
+    }
+
+    public void die() {
+        throw new NullPointerException("Expected NPE.");
+    }
+}
+
diff --git a/tests/app/app/src/android/app/stubs/ActivityManagerStubFooActivity.java b/tests/app/app/src/android/app/stubs/ActivityManagerStubFooActivity.java
new file mode 100644
index 0000000..5892e6b
--- /dev/null
+++ b/tests/app/app/src/android/app/stubs/ActivityManagerStubFooActivity.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.stubs;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.TextView;
+
+public class ActivityManagerStubFooActivity extends Activity {
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        final TextView tv = new TextView(this);
+        tv.setText("Hello, Android");
+        setContentView(tv);
+    }
+}
diff --git a/tests/app/app/src/android/app/stubs/ActivityTestsBase.java b/tests/app/app/src/android/app/stubs/ActivityTestsBase.java
new file mode 100644
index 0000000..12463b4
--- /dev/null
+++ b/tests/app/app/src/android/app/stubs/ActivityTestsBase.java
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.stubs;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.test.AndroidTestCase;
+import android.test.PerformanceTestCase;
+
+public class ActivityTestsBase extends AndroidTestCase implements PerformanceTestCase,
+        LaunchpadActivity.CallingTest {
+    public static final String PERMISSION_GRANTED = "android.app.cts.permission.TEST_GRANTED";
+    public static final String PERMISSION_DENIED = "android.app.cts.permission.TEST_DENIED";
+
+    private static final int TIMEOUT_MS = 60 * 1000;
+
+    protected Intent mIntent;
+
+    private PerformanceTestCase.Intermediates mIntermediates;
+    private String mExpecting;
+
+    // Synchronization of activity result.
+    private boolean mFinished;
+    private int mResultCode = 0;
+    private Intent mData;
+    private RuntimeException mResultStack = null;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mIntent = new Intent(mContext, LaunchpadActivity.class);
+        mIntermediates = null;
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        mIntermediates = null;
+        super.tearDown();
+    }
+
+    public boolean isPerformanceOnly() {
+        return false;
+    }
+
+    public void setInternalIterations(int count) {
+    }
+
+    public void startTiming(boolean realTime) {
+        if (mIntermediates != null) {
+            mIntermediates.startTiming(realTime);
+        }
+    }
+
+    public void addIntermediate(String name) {
+        if (mIntermediates != null) {
+            mIntermediates.addIntermediate(name);
+        }
+    }
+
+    public void addIntermediate(String name, long timeInNS) {
+        if (mIntermediates != null) {
+            mIntermediates.addIntermediate(name, timeInNS);
+        }
+    }
+
+    public void finishTiming(boolean realTime) {
+        if (mIntermediates != null) {
+            mIntermediates.finishTiming(realTime);
+        }
+    }
+
+    public void activityFinished(int resultCode, Intent data, RuntimeException where) {
+        finishWithResult(resultCode, data, where);
+    }
+
+    public Intent editIntent() {
+        return mIntent;
+    }
+
+    @Override
+    public Context getContext() {
+        return mContext;
+    }
+
+    public int startPerformance(Intermediates intermediates) {
+        mIntermediates = intermediates;
+        return 1;
+    }
+
+    public void finishGood() {
+        finishWithResult(Activity.RESULT_OK, null);
+    }
+
+    public void finishBad(String error) {
+        finishWithResult(Activity.RESULT_CANCELED, new Intent().setAction(error));
+    }
+
+    public void finishWithResult(int resultCode, Intent data) {
+        final RuntimeException where = new RuntimeException("Original error was here");
+        where.fillInStackTrace();
+        finishWithResult(resultCode, data, where);
+    }
+
+    public void finishWithResult(int resultCode, Intent data, RuntimeException where) {
+        synchronized (this) {
+            mResultCode = resultCode;
+            mData = data;
+            mResultStack = where;
+            mFinished = true;
+            notifyAll();
+        }
+    }
+
+    public int runLaunchpad(String action) {
+        startLaunchpadActivity(action);
+        return waitForResultOrThrow(TIMEOUT_MS);
+    }
+
+    private void startLaunchpadActivity(String action) {
+        LaunchpadActivity.setCallingTest(this);
+
+        synchronized (this) {
+            mIntent.setAction(action);
+            mFinished = false;
+            mIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            mContext.startActivity(mIntent);
+        }
+    }
+
+    public int waitForResultOrThrow(int timeoutMs) {
+        return waitForResultOrThrow(timeoutMs, null);
+    }
+
+    public int waitForResultOrThrow(int timeoutMs, String expected) {
+        final int res = waitForResult(timeoutMs, expected);
+
+        if (res == Activity.RESULT_CANCELED) {
+            if (mResultStack != null) {
+                throw new RuntimeException(mData != null ? mData.toString() : "Unable to launch",
+                        mResultStack);
+            } else {
+                throw new RuntimeException(mData != null ? mData.toString() : "Unable to launch");
+            }
+        }
+        return res;
+    }
+
+    public int waitForResult(int timeoutMs, String expected) {
+        mExpecting = expected;
+
+        final long endTime = System.currentTimeMillis() + timeoutMs;
+
+        boolean timeout = false;
+        synchronized (this) {
+            while (!mFinished) {
+                final long delay = endTime - System.currentTimeMillis();
+                if (delay < 0) {
+                    timeout = true;
+                    break;
+                }
+
+                try {
+                    wait(delay);
+                } catch (final java.lang.InterruptedException e) {
+                    // do nothing
+                }
+            }
+        }
+
+        mFinished = false;
+
+        if (timeout) {
+            mResultCode = Activity.RESULT_CANCELED;
+            onTimeout();
+        }
+        return mResultCode;
+    }
+
+
+    public int getResultCode() {
+        return mResultCode;
+    }
+
+    public Intent getResultData() {
+        return mData;
+    }
+
+    public RuntimeException getResultStack() {
+        return mResultStack;
+    }
+
+    public void onTimeout() {
+        final String msg = mExpecting == null ? "Timeout" : "Timeout while expecting " + mExpecting;
+        finishWithResult(Activity.RESULT_CANCELED, new Intent().setAction(msg));
+    }
+}
diff --git a/tests/app/app/src/android/app/stubs/AliasActivityStub.java b/tests/app/app/src/android/app/stubs/AliasActivityStub.java
new file mode 100644
index 0000000..7d2d469
--- /dev/null
+++ b/tests/app/app/src/android/app/stubs/AliasActivityStub.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.stubs;
+
+import android.app.AliasActivity;
+import android.os.Bundle;
+
+public class AliasActivityStub extends AliasActivity {
+
+    public static boolean isOnCreateCalled = false;
+    public static boolean isFinished = false;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        isOnCreateCalled = true;
+    }
+
+    @Override
+    public void finish() {
+        super.finish();
+        isFinished = true;
+    }
+}
diff --git a/tests/app/app/src/android/app/stubs/AppStubActivity.java b/tests/app/app/src/android/app/stubs/AppStubActivity.java
new file mode 100644
index 0000000..1da2421
--- /dev/null
+++ b/tests/app/app/src/android/app/stubs/AppStubActivity.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.stubs;
+
+import android.app.Activity;
+import android.app.Dialog;
+import android.content.res.Resources;
+import android.os.Bundle;
+import android.view.ContextMenu;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ContextMenu.ContextMenuInfo;
+
+/**
+ * A minimal "Hello, World!" application.
+ */
+public class AppStubActivity extends Activity {
+    private Dialog mDialog;
+    public boolean mOnPrepareDialog;
+    public boolean mOnOptionsMenuClosedCalled;
+    public boolean mOnPrepareOptionsMenuCalled;
+    public boolean mOnOptionsItemSelectedCalled;
+    public boolean mOnCreateOptionsMenu;
+    public boolean mIndterminate = false;
+    public boolean mIndterminatevisibility = false;
+    public boolean mSecPro = false;
+    public boolean mOnContextItemSelectedCalled;
+    public boolean mOnCreateContextMenu;
+    public boolean mApplyResourceCalled;
+    public boolean mCreateContextMenuCalled;
+    public boolean mRequestWinFeatureRet = false;
+
+    public AppStubActivity() {
+
+    }
+
+    public void finalize() {
+        try {
+            super.finalize();
+        } catch (Throwable exception) {
+            System.err.print("exception!");
+        }
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState){
+        super.onCreate(savedInstanceState);
+        mRequestWinFeatureRet = requestWindowFeature(1);
+        setContentView(R.layout.app_activity);
+    }
+
+    public Dialog getDialogById(int id) {
+        return mDialog;
+    }
+
+    @Override
+    public Dialog onCreateDialog(int id) {
+        super.onCreateDialog(id);
+        mDialog = new Dialog(this);
+        return mDialog;
+    }
+
+    @Override
+    protected void onPrepareDialog(int id, Dialog dialog) {
+        super.onPrepareDialog(id, dialog);
+        mOnPrepareDialog = true;
+    }
+
+    @Override
+    public void onOptionsMenuClosed(Menu menu) {
+        super.onOptionsMenuClosed(menu);
+        mOnOptionsMenuClosedCalled = true;
+    }
+
+    @Override
+    public boolean onPrepareOptionsMenu(Menu menu) {
+        mOnPrepareOptionsMenuCalled = true;
+        return super.onPrepareOptionsMenu(menu);
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        mOnCreateOptionsMenu = true;
+        if(menu != null)
+            menu.add(0, 0, 0, "Fake Item");
+        return super.onCreateOptionsMenu(menu);
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        mOnOptionsItemSelectedCalled = true;
+        return super.onOptionsItemSelected(item);
+    }
+
+    public boolean setProBarIndeterminate(boolean indeterminate){
+        mIndterminate = indeterminate;
+        super.setProgressBarIndeterminate(indeterminate);
+        return mIndterminate;
+    }
+
+    public boolean setProBarIndeterminateVisibility(boolean visible){
+        mIndterminatevisibility = visible;
+        super.setProgressBarIndeterminateVisibility(visible);
+        return mIndterminatevisibility;
+    }
+
+    public boolean setSecPro(int secPro){
+        mSecPro = true;
+        super.setSecondaryProgress(secPro);
+        return mSecPro;
+    }
+
+    @Override
+    public boolean onContextItemSelected(MenuItem item){
+        mOnContextItemSelectedCalled = true;
+        return super.onContextItemSelected(item);
+    }
+
+    @Override
+    public void onApplyThemeResource( Resources.Theme theme,
+                                      int resid,
+                                      boolean first){
+        super.onApplyThemeResource(theme,resid,first);
+        mApplyResourceCalled = true;
+    }
+
+    @Override
+    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
+        super.onCreateContextMenu(menu,v,menuInfo);
+        mCreateContextMenuCalled = true;
+    }
+}
+
diff --git a/tests/app/app/src/android/app/stubs/CTSActivityTestCaseBase.java b/tests/app/app/src/android/app/stubs/CTSActivityTestCaseBase.java
new file mode 100644
index 0000000..44ff6b2
--- /dev/null
+++ b/tests/app/app/src/android/app/stubs/CTSActivityTestCaseBase.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.stubs;
+
+import android.cts.util.CTSResult;
+import android.test.InstrumentationTestCase;
+
+public class CTSActivityTestCaseBase extends InstrumentationTestCase implements CTSResult {
+
+    private Sync mSync;
+    static class Sync {
+        public boolean mHasNotify;
+        public int mResult;
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mSync = new Sync();
+    }
+
+    public void setResult(int resultCode) {
+        synchronized (mSync) {
+            mSync.mHasNotify = true;
+            mSync.mResult = resultCode;
+            mSync.notify();
+        }
+    }
+
+    protected void waitForResult() throws InterruptedException {
+        synchronized (mSync) {
+            while (!mSync.mHasNotify) {
+                mSync.wait();
+            }
+            assertEquals(CTSResult.RESULT_OK, mSync.mResult);
+        }
+    }
+}
diff --git a/tests/app/app/src/android/app/stubs/ChildActivity.java b/tests/app/app/src/android/app/stubs/ChildActivity.java
new file mode 100644
index 0000000..559b101
--- /dev/null
+++ b/tests/app/app/src/android/app/stubs/ChildActivity.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.stubs;
+
+import android.app.Activity;
+
+public class ChildActivity extends Activity {
+
+    public static boolean isStarted = false;
+
+    @Override
+    protected void onStart() {
+        super.onStart();
+        isStarted = true;
+    }
+}
diff --git a/tests/app/app/src/android/app/stubs/ChildTabActivity.java b/tests/app/app/src/android/app/stubs/ChildTabActivity.java
new file mode 100644
index 0000000..1f0fb37
--- /dev/null
+++ b/tests/app/app/src/android/app/stubs/ChildTabActivity.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.stubs;
+
+import android.app.Activity;
+
+/**
+ * An empty activity for the TabActivity test
+ */
+public class ChildTabActivity extends Activity {
+}
diff --git a/tests/app/app/src/android/app/stubs/ClearTop.java b/tests/app/app/src/android/app/stubs/ClearTop.java
new file mode 100644
index 0000000..94fcc57
--- /dev/null
+++ b/tests/app/app/src/android/app/stubs/ClearTop.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.stubs;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.util.Log;
+
+public class ClearTop extends Activity {
+    public static final String WAIT_CLEAR_TASK = "waitClearTask";
+    private static final String TAG = "ClearTop";
+    public ClearTop() {
+    }
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        final Intent intent = new Intent(getIntent()).setAction(LocalScreen.CLEAR_TASK).setClass(
+                this, LocalScreen.class);
+        startActivity(intent);
+    }
+
+    @Override
+    public void onNewIntent(Intent intent) {
+        Log.i(TAG, "onNewIntent");
+        if (LocalScreen.CLEAR_TASK.equals(intent.getAction())) {
+            setResult(RESULT_OK);
+        } else {
+            setResult(RESULT_CANCELED, new Intent().setAction("New intent received " + intent
+                    + ", expecting action " + TestedScreen.CLEAR_TASK));
+        }
+        finish();
+    }
+}
diff --git a/tests/app/app/src/android/app/stubs/DialogStubActivity.java b/tests/app/app/src/android/app/stubs/DialogStubActivity.java
new file mode 100644
index 0000000..03e6010
--- /dev/null
+++ b/tests/app/app/src/android/app/stubs/DialogStubActivity.java
@@ -0,0 +1,449 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.stubs;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.DatePickerDialog;
+import android.app.Dialog;
+import android.app.TimePickerDialog;
+import android.app.DatePickerDialog.OnDateSetListener;
+import android.app.TimePickerDialog.OnTimeSetListener;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.DialogInterface.OnCancelListener;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.test.ActivityInstrumentationTestCase2;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.DatePicker;
+import android.widget.TimePicker;
+
+/*
+ * Stub class for  Dialog, AlertDialog, DatePickerDialog, TimePickerDialog etc.
+ */
+public class DialogStubActivity extends Activity {
+    public static final int TEST_DIALOG_WITHOUT_THEME = 0;
+    public static final int TEST_DIALOG_WITH_THEME = 1;
+    public static final int TEST_ALERTDIALOG = 2;
+    public static final int TEST_CUSTOM_ALERTDIALOG = 3;
+    public static final int TEST_DATEPICKERDIALOG = 4;
+    public static final int TEST_DATEPICKERDIALOG_WITH_THEME = 5;
+    public static final int TEST_TIMEPICKERDIALOG = 6;
+    public static final int TEST_TIMEPICKERDIALOG_WITH_THEME = 7;
+    public static final int TEST_ONSTART_AND_ONSTOP = 8;
+    public static final int TEST_ALERTDIALOG_DEPRECATED = 9;
+    public static final int TEST_ALERTDIALOG_CALLBACK = 10;
+    public static final int TEST_CUSTOM_ALERTDIALOG_VIEW = 11;
+    public static final int TEST_ALERTDIALOG_DEPRECATED_WITH_MESSAGE = 12;
+    public static final int TEST_ALERTDIALOG_THEME = 13;
+    public static final int TEST_ALERTDIALOG_CANCELABLE = 14;
+    public static final int TEST_ALERTDIALOG_NOT_CANCELABLE = 15;
+    public static final int TEST_PROTECTED_CANCELABLE = 16;
+    public static final int TEST_PROTECTED_NOT_CANCELABLE = 17;
+    public static final int TEST_ALERT_DIALOG_ICON_DRAWABLE = 18;
+    public static final int TEST_ALERT_DIALOG_ICON_ATTRIBUTE = 19;
+    public static final int TEST_ALERTDIALOG_WITH_MESSAGE = 20;
+
+    public static final int SPACING_LEFT = 10;
+    public static final int SPACING_TOP = 20;
+    public static final int SPACING_RIGHT = 30;
+    public static final int SPACING_BOTTOM = 40;
+    public static int buttonIndex;
+
+    public static final String DEFAULT_ALERTDIALOG_TITLE = "AlertDialog";
+    public static final String DEFAULT_ALERTDIALOG_MESSAGE = "AlertDialog message";
+    private static final String LOG_TAG = "DialogStubActivity";
+
+    public boolean isPositiveButtonClicked = false;
+    public boolean isNegativeButtonClicked = false;
+    public boolean isNeutralButtonClicked = false;
+    public boolean isCallBackCalled;
+    public boolean onCancelCalled;
+    public boolean onKeyDownCalled;
+    public boolean onKeyUpCalled;
+    public boolean onCreateCalled;
+    public boolean onCancelListenerCalled;
+    public boolean onClickCalled;
+    public static boolean onDateChangedCalled;
+    public static boolean onRestoreInstanceStateCalled;
+    public boolean onSaveInstanceStateCalled;
+    public int updatedYear;
+    public int updatedMonth;
+    public int updatedDay;
+
+    public final int INITIAL_YEAR = 2008;
+    public final int INITIAL_MONTH = 7;
+    public final int INITIAL_DAY_OF_MONTH = 27;
+    private final int INITIAL_HOUR = 10;
+    private final int INITIAL_MINUTE = 35;
+    private Dialog mDialog;
+    private AlertDialog mAlertDialog;
+    private OnDateSetListener mOnDateSetListener = new OnDateSetListener() {
+        public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
+            updatedYear = year;
+            updatedMonth = monthOfYear;
+            updatedDay = dayOfMonth;
+        }
+    };
+
+    @SuppressWarnings("deprecation")
+    @Override
+    protected Dialog onCreateDialog(int id) {
+        switch (id) {
+            case TEST_DIALOG_WITHOUT_THEME:
+                mDialog = new Dialog(this);
+                mDialog.setTitle("Hello, Dialog");
+                break;
+
+            case TEST_DIALOG_WITH_THEME:
+                mDialog = new Dialog(this, 1);
+                break;
+
+            case TEST_ALERTDIALOG:
+                mDialog = getAlertDialogInstance(false);
+                break;
+
+            case TEST_CUSTOM_ALERTDIALOG:
+                mDialog = getCustomAlertDialogInstance(false);
+                break;
+
+            case TEST_CUSTOM_ALERTDIALOG_VIEW:
+                mDialog = getCustomAlertDialogInstance(true);
+                break;
+
+            case TEST_DATEPICKERDIALOG:
+                mDialog = new MockDatePickerDialog(this, mOnDateSetListener, INITIAL_YEAR,
+                        INITIAL_MONTH, INITIAL_DAY_OF_MONTH);
+                break;
+
+            case TEST_DATEPICKERDIALOG_WITH_THEME:
+                mDialog = new MockDatePickerDialog(this,
+                        com.android.internal.R.style.Theme_Translucent, mOnDateSetListener,
+                        INITIAL_YEAR, INITIAL_MONTH, INITIAL_DAY_OF_MONTH);
+                break;
+
+            case TEST_TIMEPICKERDIALOG:
+                mDialog = new TimePickerDialog(this, new OnTimeSetListener() {
+                    public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
+                        isCallBackCalled = true;
+                    }
+                }, INITIAL_HOUR, INITIAL_MINUTE, true);
+                break;
+
+            case TEST_TIMEPICKERDIALOG_WITH_THEME:
+                mDialog = new TimePickerDialog(this,
+                        com.android.internal.R.style.Theme_Translucent, null, INITIAL_HOUR,
+                        INITIAL_MINUTE, true);
+                break;
+
+            case TEST_ONSTART_AND_ONSTOP:
+                mDialog = new TestDialog(this);
+                Log.i(LOG_TAG, "mTestDialog:" + mDialog);
+                return mDialog;
+
+            case TEST_ALERTDIALOG_DEPRECATED:
+                mDialog = getAlertDialogInstance(true);
+                break;
+
+            case TEST_ALERTDIALOG_DEPRECATED_WITH_MESSAGE:
+            case TEST_ALERTDIALOG_WITH_MESSAGE:
+                final Handler handler = new Handler() {
+                    @Override
+                    public void handleMessage(Message msg) {
+                        buttonIndex = msg.what;
+                        super.handleMessage(msg);
+                    }
+                };
+                final Message positiveMessage = Message.obtain();
+                positiveMessage.setTarget(handler);
+                positiveMessage.what = DialogInterface.BUTTON_POSITIVE;
+
+                final Message negativeMessage = Message.obtain();
+                negativeMessage.setTarget(handler);
+                negativeMessage.what = DialogInterface.BUTTON_NEGATIVE;
+
+                final Message neutralMessage = Message.obtain();
+                neutralMessage.setTarget(handler);
+                neutralMessage.what = DialogInterface.BUTTON_NEUTRAL;
+                mAlertDialog = getAlertDialogInstance(false);
+                if (id == TEST_ALERTDIALOG_DEPRECATED_WITH_MESSAGE) {
+                    mAlertDialog.setButton(getString(R.string.alert_dialog_positive),
+                            positiveMessage);
+                    mAlertDialog.setButton2(getString(R.string.alert_dialog_negative),
+                            negativeMessage);
+                    mAlertDialog.setButton3(getString(R.string.alert_dialog_neutral),
+                            neutralMessage);
+                } else {
+                    mAlertDialog.setButton(AlertDialog.BUTTON_POSITIVE,
+                            getString(R.string.alert_dialog_positive), positiveMessage);
+                    mAlertDialog.setButton(AlertDialog.BUTTON_NEUTRAL,
+                            getString(R.string.alert_dialog_neutral), neutralMessage);
+                    mAlertDialog.setButton(AlertDialog.BUTTON_NEGATIVE,
+                            getString(R.string.alert_dialog_negative), negativeMessage);
+                }
+                mDialog = mAlertDialog;
+                break;
+
+            case TEST_ALERTDIALOG_CALLBACK:
+                mDialog = new MockAlertDialog(this);
+                break;
+            case TEST_ALERTDIALOG_THEME:
+                mDialog = new MockAlertDialog(this, R.style.Theme_AlertDialog);
+                break;
+            case TEST_ALERTDIALOG_CANCELABLE:
+                mDialog = getAlertDialogCancelableInstance(true);
+                break;
+            case TEST_ALERTDIALOG_NOT_CANCELABLE:
+                mDialog = getAlertDialogCancelableInstance(false);
+                break;
+            case TEST_PROTECTED_CANCELABLE:
+                mDialog = new TestDialog(this, true, new OnCancelListener() {
+                    public void onCancel(DialogInterface dialog) {
+                        onCancelListenerCalled = true;
+                    }
+                });
+                break;
+            case TEST_PROTECTED_NOT_CANCELABLE:
+                mDialog = new TestDialog(this, false, new OnCancelListener() {
+                    public void onCancel(DialogInterface dialog) {
+                        onCancelListenerCalled = true;
+                    }
+                });
+                break;
+            case TEST_ALERT_DIALOG_ICON_DRAWABLE:
+                mAlertDialog = getAlertDialogInstance(false);
+                mAlertDialog.setIcon(mAlertDialog.getContext().getDrawable(R.drawable.robot));
+                mDialog = mAlertDialog;
+                break;
+            case TEST_ALERT_DIALOG_ICON_ATTRIBUTE:
+                mAlertDialog = getAlertDialogInstance(false);
+                mAlertDialog.setIconAttribute(android.R.attr.alertDialogIcon);
+                mDialog = mAlertDialog;
+                break;
+
+            default:
+                break;
+        }
+
+        Log.i(LOG_TAG, "mDialog:" + mDialog);
+        return mDialog;
+    }
+
+    private AlertDialog getAlertDialogCancelableInstance(boolean cancelable) {
+        OnCancelListener cancelListener = new OnCancelListener() {
+            public void onCancel(DialogInterface dialog) {
+                onCancelCalled = true;
+            }
+        };
+        return new MockAlertDialog(this, cancelable, cancelListener);
+    }
+
+    @SuppressWarnings("deprecation")
+    private AlertDialog getAlertDialogInstance(boolean deprecated) {
+        mAlertDialog = new AlertDialog.Builder(DialogStubActivity.this).create();
+        mAlertDialog.setIcon(R.drawable.pass);
+        mAlertDialog.setTitle(DEFAULT_ALERTDIALOG_TITLE);
+        mAlertDialog.setMessage(DEFAULT_ALERTDIALOG_MESSAGE);
+        mAlertDialog.setInverseBackgroundForced(true);
+        final DialogInterface.OnClickListener positiveListener = new MockOnClickListener(
+                DialogInterface.BUTTON_POSITIVE);
+        final DialogInterface.OnClickListener netativeListener = new MockOnClickListener(
+                DialogInterface.BUTTON_NEGATIVE);
+        final DialogInterface.OnClickListener neutralListener = new MockOnClickListener(
+                DialogInterface.BUTTON_NEUTRAL);
+
+        if (deprecated) {
+            mAlertDialog.setButton(getString(R.string.alert_dialog_positive), positiveListener);
+            mAlertDialog.setButton2(getString(R.string.alert_dialog_negative), netativeListener);
+            mAlertDialog.setButton3(getString(R.string.alert_dialog_neutral), neutralListener);
+        } else {
+            mAlertDialog.setButton(DialogInterface.BUTTON_POSITIVE,
+                    getString(R.string.alert_dialog_positive), positiveListener);
+            mAlertDialog.setButton(DialogInterface.BUTTON_NEGATIVE,
+                    getString(R.string.alert_dialog_negative), netativeListener);
+            mAlertDialog.setButton(DialogInterface.BUTTON_NEUTRAL,
+                    getString(R.string.alert_dialog_neutral), neutralListener);
+        }
+        return mAlertDialog;
+
+    }
+
+    private AlertDialog getCustomAlertDialogInstance(boolean withSpacing) {
+        final LayoutInflater inflate = getLayoutInflater();
+        final View customTitleViewCustom = inflate.inflate(R.layout.alertdialog_custom_title, null);
+        final View textEntryView = inflate.inflate(R.layout.alert_dialog_text_entry_2, null);
+        mAlertDialog = new AlertDialog.Builder(DialogStubActivity.this).create();
+        mAlertDialog.setCustomTitle(customTitleViewCustom);
+        mAlertDialog.setMessage(DEFAULT_ALERTDIALOG_MESSAGE);
+        if (withSpacing) {
+            mAlertDialog.setView(textEntryView, SPACING_LEFT, SPACING_TOP, SPACING_RIGHT,
+                    SPACING_BOTTOM);
+        } else {
+            mAlertDialog.setView(textEntryView);
+        }
+
+        return mAlertDialog;
+
+    }
+
+    public Dialog getDialog() {
+        return mDialog;
+    }
+
+    public String getDialogTitle() {
+        return (String) mDialog.getWindow().getAttributes().getTitle();
+    }
+
+    private static final String TEST_DIALOG_NUMBER_EXTRA = "testDialogNumber";
+
+    public static <T extends Activity> T startDialogActivity(
+            ActivityInstrumentationTestCase2<T> testCase, int dialogNumber) {
+        Intent intent = new Intent(Intent.ACTION_MAIN);
+        intent.putExtra(TEST_DIALOG_NUMBER_EXTRA, dialogNumber);
+        testCase.setActivityIntent(intent);
+        return testCase.getActivity();
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.dialog_stub_layout);
+
+        Intent intent = getIntent();
+        int dialogNum = intent.getIntExtra(TEST_DIALOG_NUMBER_EXTRA, -1);
+        if (dialogNum != -1) {
+            showDialog(dialogNum);
+        }
+    }
+
+    public void setUpTitle(final String title) {
+        runOnUiThread(new Runnable() {
+            public void run() {
+                getDialog().setTitle(title);
+            }
+        });
+    }
+
+    public void setUpTitle(final int id) {
+        runOnUiThread(new Runnable() {
+            public void run() {
+                getDialog().setTitle(id);
+            }
+        });
+    }
+
+    class MockAlertDialog extends AlertDialog {
+        public MockAlertDialog(Context context) {
+            super(context);
+        }
+
+        public MockAlertDialog(Context context, int theme) {
+            super(context, theme);
+        }
+
+        public MockAlertDialog(Context context, boolean cancelable, OnCancelListener cancelListener) {
+            super(context, cancelable, cancelListener);
+        }
+
+        @Override
+        public boolean onKeyDown(int keyCode, KeyEvent event) {
+            onKeyDownCalled = true;
+            return super.onKeyDown(keyCode, event);
+        }
+
+        @Override
+        public boolean onKeyUp(int keyCode, KeyEvent event) {
+            onKeyUpCalled = true;
+            return super.onKeyUp(keyCode, event);
+        }
+
+        @Override
+        protected void onCreate(Bundle savedInstanceState) {
+            onCreateCalled = true;
+            super.onCreate(savedInstanceState);
+        }
+
+    }
+
+    class MockOnClickListener implements DialogInterface.OnClickListener {
+        private final int mId;
+
+        public MockOnClickListener(final int buttonId) {
+            mId = buttonId;
+        }
+
+        public void onClick(DialogInterface dialog, int which) {
+            switch (mId) {
+                case DialogInterface.BUTTON_POSITIVE:
+                    isPositiveButtonClicked = true;
+                    break;
+                case DialogInterface.BUTTON_NEGATIVE:
+                    isNegativeButtonClicked = true;
+                    break;
+                case DialogInterface.BUTTON_NEUTRAL:
+                    isNeutralButtonClicked = true;
+                    break;
+                default:
+                    break;
+            }
+        }
+    }
+
+    class MockDatePickerDialog extends DatePickerDialog {
+        public MockDatePickerDialog(Context context, OnDateSetListener callBack, int year,
+                int monthOfYear, int dayOfMonth) {
+            super(context, callBack, year, monthOfYear, dayOfMonth);
+        }
+
+        public MockDatePickerDialog(Context context, int theme, OnDateSetListener callBack,
+                int year, int monthOfYear, int dayOfMonth) {
+            super(context, theme, callBack, year, monthOfYear, dayOfMonth);
+        }
+
+        @Override
+        public void onClick(DialogInterface dialog, int which) {
+            onClickCalled = true;
+            super.onClick(dialog, which);
+        }
+
+        @Override
+        public void onDateChanged(DatePicker view, int year, int month, int day) {
+            onDateChangedCalled = true;
+            super.onDateChanged(view, year, month, day);
+        }
+
+        @Override
+        public void onRestoreInstanceState(Bundle savedInstanceState) {
+            onRestoreInstanceStateCalled = true;
+            super.onRestoreInstanceState(savedInstanceState);
+        }
+
+        @Override
+        public Bundle onSaveInstanceState() {
+            onSaveInstanceStateCalled = true;
+            return super.onSaveInstanceState();
+        }
+
+    }
+}
diff --git a/tests/app/app/src/android/app/stubs/ExpandableListTestActivity.java b/tests/app/app/src/android/app/stubs/ExpandableListTestActivity.java
new file mode 100644
index 0000000..ab377d9
--- /dev/null
+++ b/tests/app/app/src/android/app/stubs/ExpandableListTestActivity.java
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.stubs;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import android.app.ExpandableListActivity;
+import android.os.Bundle;
+import android.os.Looper;
+import android.os.MessageQueue;
+import android.view.ContextMenu;
+import android.view.View;
+import android.view.ContextMenu.ContextMenuInfo;
+import android.widget.ExpandableListAdapter;
+import android.widget.ExpandableListView;
+import android.widget.SimpleExpandableListAdapter;
+
+import com.android.internal.R;
+import com.android.internal.view.menu.ContextMenuBuilder;
+import com.google.android.collect.Lists;
+
+public class ExpandableListTestActivity extends ExpandableListActivity {
+    private static final String NAME = "NAME";
+    private static final String IS_EVEN = "IS_EVEN";
+    private boolean mOnContentChangedCalled = false;
+    private boolean mOnCreateContextMenuCalled = false;
+    private boolean mOnGroupCollapseCalled = false;
+    private boolean mOnGroupExpandCalled = false;
+    private ExpandableListAdapter mAdapter;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        final List<Map<String, String>> groupData = Lists.newArrayList();
+        final List<List<Map<String, String>>> childData = Lists.newArrayList();
+        for (int i = 0; i < 20; i++) {
+            final Map<String, String> curGroupMap = new HashMap<String, String>();
+            groupData.add(curGroupMap);
+            curGroupMap.put(NAME, "Group " + i);
+            curGroupMap.put(IS_EVEN, (i % 2 == 0) ? "This group is even" : "This group is odd");
+
+            final List<Map<String, String>> children = Lists.newArrayList();
+            for (int j = 0; j < 15; j++) {
+                Map<String, String> curChildMap = new HashMap<String, String>();
+                children.add(curChildMap);
+                curChildMap.put(NAME, "Child " + j);
+                curChildMap.put(IS_EVEN, (j % 2 == 0) ? "This child is even" : "This child is odd");
+            }
+            childData.add(children);
+        }
+
+        // Set up our adapter
+        mAdapter = new SimpleExpandableListAdapter(this, groupData,
+                R.layout.simple_expandable_list_item_1,
+                new String[] { NAME, IS_EVEN }, new int[] { R.id.text1, R.id.text2 }, childData,
+                R.layout.simple_expandable_list_item_2,
+                new String[] { NAME, IS_EVEN }, new int[] { R.id.text1, R.id.text2 });
+        setListAdapter(mAdapter);
+
+    }
+
+    private int testCallback() {
+        final ExpandableListView v = getExpandableListView();
+        final ExpandableListAdapter a = getExpandableListAdapter();
+        final View convertView = new View(this);
+        final View gv = a.getGroupView(0, true, convertView, v);
+        v.setOnCreateContextMenuListener(this);
+        v.createContextMenu(new ContextMenuBuilder(this));
+        for (int i = 0; i < 20; i++) {
+            v.expandGroup(i);
+            v.performClick();
+            v.performLongClick();
+            for (int k = 0; k < 15; k++) {
+                v.performItemClick(gv, i, k);
+            }
+            v.collapseGroup(i);
+        }
+        if (mOnContentChangedCalled && mOnCreateContextMenuCalled
+                && mOnGroupCollapseCalled && mOnGroupExpandCalled)
+            return RESULT_OK;
+
+        return RESULT_CANCELED;
+    }
+
+    private int testView() {
+        final ExpandableListView currentView = getExpandableListView();
+        for (int i = 0; i < 20; i++) {
+            if (!currentView.expandGroup(i))
+                return RESULT_CANCELED;
+            if (!currentView.collapseGroup(i))
+                return RESULT_CANCELED;
+        }
+        final View otherView = findViewById(android.R.id.list);
+        setContentView(otherView);
+        if (!otherView.equals(getExpandableListView()))
+            return RESULT_CANCELED;
+        setContentView(currentView);
+        return RESULT_OK;
+    }
+
+    private int testSelecte() {
+        final ExpandableListView v = getExpandableListView();
+        for (int i = 0; i < 20; i++) {
+            v.expandGroup(i);
+            setSelectedGroup(i);
+            for (int k = 0; k < 15; k++) {
+                setSelectedChild(i, k, false);
+                if (ExpandableListView.getPackedPositionForChild(i, k) != getSelectedPosition())
+                    return RESULT_CANCELED;
+            }
+
+            for (int k = 0; k < 15; k++) {
+                setSelectedChild(i, k, true);
+                if (ExpandableListView.getPackedPositionForChild(i, k) != getSelectedPosition())
+                    return RESULT_CANCELED;
+            }
+            v.collapseGroup(i);
+        }
+        return RESULT_OK;
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        final String action = getIntent().getAction();
+        if (LaunchpadActivity.EXPANDLIST_SELECT.equals(action)) {
+            setResult(testSelecte());
+        } else if (LaunchpadActivity.EXPANDLIST_VIEW.equals(action)) {
+            setResult(testView());
+        } else if (LaunchpadActivity.EXPANDLIST_CALLBACK.equals(action)) {
+            setResult(testCallback());
+        }
+        Looper.myQueue().addIdleHandler(new Idler());
+    }
+
+    protected void onRestoreInstanceState(Bundle state) {
+        super.onRestoreInstanceState(state);
+    }
+
+    @Override
+    public void onContentChanged() {
+        mOnContentChangedCalled = true;
+        super.onContentChanged();
+    }
+
+    @Override
+    public void onCreateContextMenu(ContextMenu menu, View v,
+            ContextMenuInfo menuInfo) {
+        mOnCreateContextMenuCalled = true;
+        super.onCreateContextMenu(menu, v, menuInfo);
+    }
+
+    @Override
+    public void onGroupCollapse(int groupPosition) {
+        mOnGroupCollapseCalled = true;
+        super.onGroupCollapse(groupPosition);
+    }
+
+    @Override
+    public void onGroupExpand(int groupPosition) {
+        mOnGroupExpandCalled = true;
+        super.onGroupExpand(groupPosition);
+    }
+
+    protected void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+    }
+
+    protected void onStop() {
+        super.onStop();
+    }
+
+    private class Idler implements MessageQueue.IdleHandler {
+        public final boolean queueIdle() {
+            finish();
+            return false;
+        }
+    }
+
+}
diff --git a/tests/app/app/src/android/app/stubs/FragmentTestActivity.java b/tests/app/app/src/android/app/stubs/FragmentTestActivity.java
new file mode 100644
index 0000000..65ba911
--- /dev/null
+++ b/tests/app/app/src/android/app/stubs/FragmentTestActivity.java
@@ -0,0 +1,192 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.stubs;
+
+import android.app.Activity;
+import android.app.Fragment;
+import android.content.Context;
+import android.os.Bundle;
+import android.transition.Transition;
+import android.transition.Transition.TransitionListener;
+import android.transition.TransitionInflater;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+/**
+ * A simple activity used for Fragment Transitions
+ */
+public class FragmentTestActivity extends Activity {
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        setContentView(R.layout.activity_content);
+    }
+
+    public static class TestFragment extends Fragment {
+        public static final int ENTER = 0;
+        public static final int RETURN = 1;
+        public static final int EXIT = 2;
+        public static final int REENTER = 3;
+        public static final int SHARED_ELEMENT_ENTER = 4;
+        public static final int SHARED_ELEMENT_RETURN = 5;
+        private static final int TRANSITION_COUNT = 6;
+
+        private static final String LAYOUT_ID = "layoutId";
+        private static final String TRANSITION_KEY = "transition_";
+        private int mLayoutId = R.layout.fragment_start;
+        private final int[] mTransitionIds = new int[] {
+                android.R.transition.explode,
+                android.R.transition.explode,
+                android.R.transition.fade,
+                android.R.transition.fade,
+                android.R.transition.move,
+                android.R.transition.move,
+        };
+        private final TransitionCalledListener[] mListeners =
+                new TransitionCalledListener[TRANSITION_COUNT];
+        private OnTransitionListener mOnTransitionListener;
+
+        public TestFragment() {
+            for (int i = 0; i < TRANSITION_COUNT; i++) {
+                mListeners[i] = new TransitionCalledListener();
+            }
+        }
+
+        public TestFragment(int layoutId) {
+            this();
+            mLayoutId = layoutId;
+        }
+
+        public void clearTransitions() {
+            for (int i = 0; i < TRANSITION_COUNT; i++) {
+                mTransitionIds[i] = 0;
+            }
+        }
+
+        public void clearNotifications() {
+            for (int i = 0; i < TRANSITION_COUNT; i++) {
+                mListeners[i].transitionStarted = false;
+                mListeners[i].transitionEnded = false;
+            }
+        }
+
+        @Override
+        public void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            if (savedInstanceState != null) {
+                mLayoutId = savedInstanceState.getInt(LAYOUT_ID, mLayoutId);
+                for (int i = 0; i < TRANSITION_COUNT; i++) {
+                    String key = TRANSITION_KEY + i;
+                    mTransitionIds[i] = savedInstanceState.getInt(key, mTransitionIds[i]);
+                }
+            }
+        }
+
+        @Override
+        public void onSaveInstanceState(Bundle outState) {
+            super.onSaveInstanceState(outState);
+            outState.putInt(LAYOUT_ID, mLayoutId);
+            for (int i = 0; i < TRANSITION_COUNT; i++) {
+                String key = TRANSITION_KEY + i;
+                outState.putInt(key, mTransitionIds[i]);
+            }
+        }
+
+        @Override
+        public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                Bundle savedInstanceState) {
+            return inflater.inflate(mLayoutId, container, false);
+        }
+
+        @Override
+        public void onAttach(Context context) {
+            super.onAttach(context);
+            setEnterTransition(loadTransition(ENTER));
+            setReenterTransition(loadTransition(REENTER));
+            setExitTransition(loadTransition(EXIT));
+            setReturnTransition(loadTransition(RETURN));
+            setSharedElementEnterTransition(loadTransition(SHARED_ELEMENT_ENTER));
+            setSharedElementReturnTransition(loadTransition(SHARED_ELEMENT_RETURN));
+        }
+
+        public void setOnTransitionListener(OnTransitionListener listener) {
+            mOnTransitionListener = listener;
+        }
+
+        public boolean wasStartCalled(int transitionKey) {
+            return mListeners[transitionKey].transitionStarted;
+        }
+
+        public boolean wasEndCalled(int transitionKey) {
+            return mListeners[transitionKey].transitionEnded;
+        }
+
+        private Transition loadTransition(int key) {
+            final int id = mTransitionIds[key];
+            if (id == 0) {
+                return null;
+            }
+            Transition transition = TransitionInflater.from(getActivity()).inflateTransition(id);
+            transition.addListener(mListeners[key]);
+            return transition;
+        }
+
+        private void notifyTransition() {
+            if (mOnTransitionListener != null) {
+                mOnTransitionListener.onTransition(this);
+            }
+        }
+
+        private class TransitionCalledListener implements TransitionListener {
+            public boolean transitionStarted;
+            public boolean transitionEnded;
+
+            public TransitionCalledListener() {
+            }
+
+            @Override
+            public void onTransitionStart(Transition transition) {
+                transitionStarted = true;
+                notifyTransition();
+            }
+
+            @Override
+            public void onTransitionEnd(Transition transition) {
+                transitionEnded = true;
+                notifyTransition();
+            }
+
+            @Override
+            public void onTransitionCancel(Transition transition) {
+            }
+
+            @Override
+            public void onTransitionPause(Transition transition) {
+            }
+
+            @Override
+            public void onTransitionResume(Transition transition) {
+            }
+        }
+    }
+
+    public interface OnTransitionListener {
+        void onTransition(TestFragment fragment);
+    }
+
+}
diff --git a/tests/app/app/src/android/app/stubs/ISecondary.aidl b/tests/app/app/src/android/app/stubs/ISecondary.aidl
new file mode 100644
index 0000000..2f3ec25
--- /dev/null
+++ b/tests/app/app/src/android/app/stubs/ISecondary.aidl
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.stubs;
+
+interface ISecondary {
+
+    int getPid();
+
+    long getElapsedCpuTime();
+
+    String getTimeZoneID();
+}
diff --git a/tests/app/app/src/android/app/stubs/InstrumentationTestActivity.java b/tests/app/app/src/android/app/stubs/InstrumentationTestActivity.java
new file mode 100644
index 0000000..8e36beb
--- /dev/null
+++ b/tests/app/app/src/android/app/stubs/InstrumentationTestActivity.java
@@ -0,0 +1,365 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.stubs;
+
+import java.util.ArrayList;
+import java.util.List;
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.KeyEvent;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.MotionEvent;
+import android.view.View;
+import android.widget.TextView;
+
+public class InstrumentationTestActivity extends Activity {
+
+    private boolean mOnCreateCalled;
+    private boolean mOnDestroyCalled ;
+    private boolean mOnNewIntentCalled;
+    private boolean mOnPauseCalled;
+    private boolean mOnPostCreate;
+    private boolean mOnRestart;
+    private boolean mOnRestoreInstanceState;
+    private boolean mOnResume;
+    private boolean mOnSaveInstanceState;
+    private boolean mOnStart;
+    private boolean mOnStop;
+    private boolean mOnMenuOpened;
+    private boolean mOnLeave;
+    private int mMenuID;
+    private boolean mOnTouchEventCalled;
+    private int mKeyDownCode;
+    private int mKeyUpCode;
+    private MotionEvent mMotionEvent;
+    private Bundle mBundle;
+    private MockTextView mTextView;
+    private List<KeyEvent> mKeyDownList = new ArrayList<KeyEvent>();
+    private List<KeyEvent> mKeyUpList = new ArrayList<KeyEvent>();
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        mTextView = new MockTextView(this);
+        setContentView(mTextView);
+        mOnCreateCalled = true;
+    }
+
+    class MockTextView extends TextView {
+
+        public MockTextView(Context context) {
+            super(context);
+        }
+
+        @Override
+        public boolean onTouchEvent(MotionEvent event) {
+            return super.onTouchEvent(event);
+        }
+
+        @Override
+        public boolean onTrackballEvent(MotionEvent event) {
+            return super.onTrackballEvent(event);
+        }
+
+        @Override
+        public void getLocationOnScreen(int[] location) {
+            super.getLocationOnScreen(location);
+            location[0] = location[1] = 10;
+        }
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+        mOnDestroyCalled = true;
+    }
+
+    @Override
+    protected void onNewIntent(Intent intent) {
+        super.onNewIntent(intent);
+        mOnNewIntentCalled = true;
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+        mOnPauseCalled = true;
+    }
+
+    @Override
+    protected void onPostCreate(Bundle savedInstanceState) {
+        super.onPostCreate(savedInstanceState);
+        mOnPostCreate = true;
+    }
+
+    @Override
+    protected void onRestart() {
+        super.onRestart();
+        mOnRestart = true;
+    }
+
+    @Override
+    protected void onRestoreInstanceState(Bundle savedInstanceState) {
+        super.onRestoreInstanceState(savedInstanceState);
+        mOnRestoreInstanceState = true;
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent event) {
+        mOnTouchEventCalled = true;
+        mMotionEvent = event;
+        return super.onTouchEvent(event);
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        mOnResume = true;
+    }
+
+    @Override
+    protected void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+        mOnSaveInstanceState = true;
+        mBundle = outState;
+    }
+
+    @Override
+    protected void onStart() {
+        super.onStart();
+        mOnStart = true;
+    }
+
+    @Override
+    protected void onStop() {
+        super.onStop();
+        mOnStop = true;
+    }
+
+    @Override
+    protected void onUserLeaveHint() {
+        super.onUserLeaveHint();
+        mOnLeave = true;
+    }
+
+    @Override
+    public boolean onMenuOpened(int featureId, Menu menu) {
+        mOnMenuOpened = true;
+        return super.onMenuOpened(featureId, menu);
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        super.onCreateOptionsMenu(menu);
+        MenuInflater inflater = getMenuInflater();
+        inflater.inflate(R.menu.browser, menu);
+
+        menu.add("title");
+        mOnMenuOpened = true;
+        return true;
+    }
+
+    @Override
+    public boolean onCreatePanelMenu(int featureId, Menu menu) {
+        return super.onCreatePanelMenu(featureId, menu);
+    }
+
+    @Override
+    public boolean onMenuItemSelected(int featureId, MenuItem item) {
+        mMenuID = item.getItemId();
+        return super.onMenuItemSelected(featureId, item);
+    }
+
+    @Override
+    public void openContextMenu(View view) {
+        super.openContextMenu(view);
+    }
+
+    @Override
+    public void openOptionsMenu() {
+        super.openOptionsMenu();
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        return super.onOptionsItemSelected(item);
+    }
+
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        mKeyDownList.add(event);
+        mKeyDownCode = keyCode;
+        return super.onKeyDown(keyCode, event);
+    }
+
+    @Override
+    public boolean onTrackballEvent(MotionEvent event) {
+        mMotionEvent = event;
+        return super.onTrackballEvent(event);
+    }
+
+    @Override
+    public boolean onKeyUp(int keyCode, KeyEvent event) {
+        mKeyUpList.add(event);
+        mKeyUpCode = keyCode;
+        return super.onKeyUp(keyCode, event);
+    }
+
+    public boolean isOnCreateCalled() {
+        return mOnCreateCalled;
+    }
+
+    public void setOnCreateCalled(boolean onCreateCalled) {
+        mOnCreateCalled = onCreateCalled;
+    }
+
+    public boolean isOnDestroyCalled() {
+        return mOnDestroyCalled;
+    }
+
+    public void setOnDestroyCalled(boolean onDestroyCalled) {
+        mOnDestroyCalled = onDestroyCalled;
+    }
+
+    public boolean isOnNewIntentCalled() {
+        return mOnNewIntentCalled;
+    }
+
+    public void setOnNewIntentCalled(boolean onNewIntentCalled) {
+        mOnNewIntentCalled = onNewIntentCalled;
+    }
+
+    public boolean isOnPauseCalled() {
+        return mOnPauseCalled;
+    }
+
+    public void setOnPauseCalled(boolean onPauseCalled) {
+        mOnPauseCalled = onPauseCalled;
+    }
+
+    public boolean isOnPostCreate() {
+        return mOnPostCreate;
+    }
+
+    public void setOnPostCreate(boolean onPostCreate) {
+        mOnPostCreate = onPostCreate;
+    }
+
+    public boolean isOnRestart() {
+        return mOnRestart;
+    }
+
+    public void setOnRestart(boolean onRestart) {
+        mOnRestart = onRestart;
+    }
+
+    public boolean isOnRestoreInstanceState() {
+        return mOnRestoreInstanceState;
+    }
+
+    public void setOnRestoreInstanceState(boolean onRestoreInstanceState) {
+        mOnRestoreInstanceState = onRestoreInstanceState;
+    }
+
+    public boolean isOnResume() {
+        return mOnResume;
+    }
+
+    public void setOnResume(boolean onResume) {
+        mOnResume = onResume;
+    }
+
+    public boolean isOnSaveInstanceState() {
+        return mOnSaveInstanceState;
+    }
+
+    public void setOnSaveInstanceState(boolean onSaveInstanceState) {
+        mOnSaveInstanceState = onSaveInstanceState;
+    }
+
+    public boolean isOnStart() {
+        return mOnStart;
+    }
+
+    public void setOnStart(boolean onStart) {
+        mOnStart = onStart;
+    }
+
+    public boolean isOnStop() {
+        return mOnStop;
+    }
+
+    public boolean isOnLeave() {
+        return mOnLeave;
+    }
+
+    public void setOnStop(boolean onStop) {
+        mOnStop = onStop;
+    }
+
+    public boolean isMOnMenuOpened() {
+        return mOnMenuOpened;
+    }
+
+    public void setOnMenuOpened(boolean onMenuOpened) {
+        mOnMenuOpened = onMenuOpened;
+    }
+
+    public int getMenuID() {
+        return mMenuID;
+    }
+
+    public void setMenuID(int menuID) {
+        mMenuID = menuID;
+    }
+
+    public MotionEvent getMotionEvent() {
+        return mMotionEvent;
+    }
+
+    public Bundle getBundle() {
+        return mBundle;
+    }
+
+    public boolean isOnTouchEventCalled() {
+        return mOnTouchEventCalled;
+    }
+
+    public void setOnTouchEventCalled(boolean onTouchEventCalled) {
+        mOnTouchEventCalled = onTouchEventCalled;
+    }
+
+    public int getKeyUpCode() {
+        return mKeyUpCode;
+    }
+
+    public int getKeyDownCode() {
+        return mKeyDownCode;
+    }
+
+    public List<KeyEvent> getKeyUpList() {
+        return mKeyUpList;
+    }
+
+    public List<KeyEvent> getKeyDownList() {
+        return mKeyDownList;
+    }
+}
diff --git a/tests/app/app/src/android/app/stubs/IntentServiceStub.java b/tests/app/app/src/android/app/stubs/IntentServiceStub.java
new file mode 100644
index 0000000..626e464
--- /dev/null
+++ b/tests/app/app/src/android/app/stubs/IntentServiceStub.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.stubs;
+
+import android.app.IntentService;
+import android.content.Intent;
+import android.cts.util.PollingCheck;
+import android.os.Binder;
+import android.os.IBinder;
+
+public class IntentServiceStub extends IntentService {
+    public IntentServiceStub() {
+        super("IntentServiceStub");
+    }
+
+    public static final String ISS_ADD = "add";
+    public static final String ISS_VALUE = "value";
+
+    private static int onHandleIntentCalled;
+    private static boolean onBindCalled;
+    private static boolean onCreateCalled;
+    private static boolean onDestroyCalled;
+    private static boolean onStartCalled;
+    private static int accumulator;
+
+    private static Throwable throwable;
+
+    public synchronized static void reset() {
+        onHandleIntentCalled = 0;
+        onBindCalled = false;
+        onCreateCalled = false;
+        onDestroyCalled = false;
+        onStartCalled = false;
+        accumulator = 0;
+        throwable = null;
+    }
+
+    public static void waitToFinish(long timeout) throws Throwable {
+        new PollingCheck(timeout) {
+            @Override
+            protected boolean check() {
+                synchronized (IntentServiceStub.class) {
+                    return IntentServiceStub.onDestroyCalled;
+                }
+            }
+        }.run();
+        if (throwable != null) {
+            throw throwable;
+        }
+    }
+
+    @Override
+    protected void onHandleIntent(Intent intent) {
+        synchronized (IntentServiceStub.class) {
+            onHandleIntentCalled += 1;
+            try {
+                String action = intent.getAction();
+                if (action != null && action.equals(ISS_ADD)) {
+                    accumulator += intent.getIntExtra(ISS_VALUE, 0);
+                }
+            } catch (Throwable t) {
+                throwable = t;
+            }
+        }
+    }
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        synchronized (IntentServiceStub.class) {
+            onBindCalled = true;
+        }
+        return new Binder();
+    }
+
+    @Override
+    public void onCreate() {
+        synchronized (IntentServiceStub.class) {
+            onCreateCalled = true;
+        }
+        super.onCreate();
+    }
+
+    @Override
+    public void onDestroy() {
+        synchronized (IntentServiceStub.class) {
+            onDestroyCalled = true;
+        }
+        super.onDestroy();
+    }
+
+    @Override
+    public void onStart(Intent intent, int startId) {
+        synchronized (IntentService.class) {
+            onStartCalled = true;
+        }
+        super.onStart(intent, startId);
+    }
+
+    public synchronized static int getOnHandleIntentCalledCount() {
+        return onHandleIntentCalled;
+    }
+
+    public synchronized static boolean isOnBindCalled() {
+        return onBindCalled;
+    }
+
+    public synchronized static boolean isOnCreateCalled() {
+        return onCreateCalled;
+    }
+
+    public synchronized static boolean isOnDestroyCalled() {
+        return onDestroyCalled;
+    }
+
+    public synchronized static boolean isOnStartCalled() {
+        return onStartCalled;
+    }
+
+    public synchronized static int getAccumulator() {
+        return accumulator;
+    }
+}
diff --git a/tests/app/app/src/android/app/stubs/KeyboardShortcutsActivity.java b/tests/app/app/src/android/app/stubs/KeyboardShortcutsActivity.java
new file mode 100644
index 0000000..dd9d1dc
--- /dev/null
+++ b/tests/app/app/src/android/app/stubs/KeyboardShortcutsActivity.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.stubs;
+
+import android.app.Activity;
+import android.view.Menu;
+
+public class KeyboardShortcutsActivity extends Activity {
+
+    public static final String ITEM_1_NAME = "item 1";
+    public static final char ITEM_1_SHORTCUT = 'i';
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        menu.add(ITEM_1_NAME).setAlphabeticShortcut(ITEM_1_SHORTCUT);
+        return true;
+    }
+}
diff --git a/tests/app/app/src/android/app/stubs/KeyguardManagerActivity.java b/tests/app/app/src/android/app/stubs/KeyguardManagerActivity.java
new file mode 100644
index 0000000..e85938d
--- /dev/null
+++ b/tests/app/app/src/android/app/stubs/KeyguardManagerActivity.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.stubs;
+
+import android.app.Activity;
+import android.app.KeyguardManager;
+import android.content.Context;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.KeyEvent;
+
+public class KeyguardManagerActivity extends Activity {
+    private static final String TAG = "KeyguardManagerActivity";
+    public static final boolean DEBUG = false;
+    private KeyguardManager mKeyguardManager;
+    private KeyguardManager.KeyguardLock mKeyLock;
+    public int keyCode;
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        mKeyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
+        mKeyLock = null;
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        if (DEBUG) {
+            Log.d(TAG, "onResume");
+        }
+        if (mKeyLock == null) {
+            mKeyLock = mKeyguardManager.newKeyguardLock(TAG);
+            mKeyLock.disableKeyguard();
+            if (DEBUG) {
+                Log.d(TAG, "disableKeyguard");
+            }
+        }
+    }
+
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        this.keyCode = keyCode;
+        if (keyCode == KeyEvent.KEYCODE_0 && mKeyLock != null) {
+            mKeyLock.reenableKeyguard();
+            mKeyLock = null;
+            if (DEBUG) {
+                Log.d(TAG, "reenableKeyguard");
+            }
+        }
+        if (DEBUG) {
+            Log.d(TAG, "onKeyDown");
+        }
+        return super.onKeyDown(keyCode, event);
+    }
+}
diff --git a/tests/app/app/src/android/app/stubs/LauncherActivityStub.java b/tests/app/app/src/android/app/stubs/LauncherActivityStub.java
new file mode 100644
index 0000000..f309b04
--- /dev/null
+++ b/tests/app/app/src/android/app/stubs/LauncherActivityStub.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.stubs;
+
+import android.app.LauncherActivity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.ListView;
+
+public class LauncherActivityStub extends LauncherActivity {
+    public boolean isOnCreateCalled = false;
+    public boolean isOnListItemClick = false;
+    // For testing LauncherActivity#getTargetIntent()
+    private Intent mSuperIntent;
+
+    public Intent getSuperIntent() {
+        return mSuperIntent;
+    }
+
+    @Override
+    protected Intent getTargetIntent() {
+        mSuperIntent = super.getTargetIntent();
+        Intent targetIntent = new Intent(Intent.ACTION_MAIN, null);
+        targetIntent.addCategory(Intent.CATEGORY_FRAMEWORK_INSTRUMENTATION_TEST);
+        targetIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        return targetIntent;
+    }
+
+    @Override
+    public Intent intentForPosition(int position) {
+        return super.intentForPosition(position);
+    }
+
+    public LauncherActivityStub() {
+        super();
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        isOnCreateCalled = true;
+    }
+
+    @Override
+    public void onListItemClick(ListView l, View v, int position, long id) {
+        super.onListItemClick(l, v, position, id);
+        isOnListItemClick = true;
+    }
+}
diff --git a/tests/app/app/src/android/app/stubs/LaunchpadActivity.java b/tests/app/app/src/android/app/stubs/LaunchpadActivity.java
new file mode 100644
index 0000000..16b1363
--- /dev/null
+++ b/tests/app/app/src/android/app/stubs/LaunchpadActivity.java
@@ -0,0 +1,648 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.stubs;
+
+import android.app.Activity;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.test.PerformanceTestCase;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+class MyBadParcelable implements Parcelable {
+    public MyBadParcelable() {
+    }
+
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeString("I am bad");
+    }
+
+    public int describeContents() {
+        return 0;
+    }
+
+    public static final Parcelable.Creator<MyBadParcelable> CREATOR =
+        new Parcelable.Creator<MyBadParcelable>() {
+        public MyBadParcelable createFromParcel(Parcel in) {
+            return new MyBadParcelable(in);
+        }
+
+        public MyBadParcelable[] newArray(int size) {
+            return new MyBadParcelable[size];
+        }
+    };
+
+    public MyBadParcelable(Parcel in) {
+        in.readString();
+    }
+}
+
+public class LaunchpadActivity extends Activity {
+    public interface CallingTest extends PerformanceTestCase.Intermediates {
+        public void startTiming(boolean realTime);
+
+        public void addIntermediate(String name);
+
+        public void addIntermediate(String name, long timeInNS);
+
+        public void finishTiming(boolean realTime);
+
+        public void activityFinished(int resultCode, Intent data, RuntimeException where);
+    }
+
+    // Also used as the Binder interface descriptor string in these tests
+    public static final String LAUNCH = "android.app.cts.activity.LAUNCH";
+
+    public static final String FORWARD_RESULT = "android.app.cts.activity.FORWARD_RESULT";
+    public static final String RETURNED_RESULT = "android.app.cts.activity.RETURNED_RESULT";
+
+    public static final String BAD_PARCELABLE = "android.app.cts.activity.BAD_PARCELABLE";
+
+    public static final int LAUNCHED_RESULT = 1;
+    public static final int FORWARDED_RESULT = 2;
+
+    public static final String LIFECYCLE_BASIC = "android.app.cts.activity.LIFECYCLE_BASIC";
+    public static final String LIFECYCLE_SCREEN = "android.app.cts.activity.LIFECYCLE_SCREEN";
+    public static final String LIFECYCLE_DIALOG = "android.app.cts.activity.LIFECYCLE_DIALOG";
+
+    public static final String BROADCAST_REGISTERED = "android.app.cts.activity.BROADCAST_REGISTERED";
+    public static final String BROADCAST_LOCAL = "android.app.cts.activity.BROADCAST_LOCAL";
+    public static final String BROADCAST_REMOTE = "android.app.cts.activity.BROADCAST_REMOTE";
+    public static final String BROADCAST_ALL = "android.app.cts.activity.BROADCAST_ALL";
+    public static final String BROADCAST_REPEAT = "android.app.cts.activity.BROADCAST_REPEAT";
+    public static final String BROADCAST_MULTI = "android.app.cts.activity.BROADCAST_MULTI";
+    public static final String BROADCAST_ABORT = "android.app.cts.activity.BROADCAST_ABORT";
+
+    public static final String EXPANDLIST_SELECT = "EXPANDLIST_SELECT";
+    public static final String EXPANDLIST_VIEW = "EXPANDLIST_VIEW";
+    public static final String EXPANDLIST_CALLBACK = "EXPANDLIST_CALLBACK";
+
+    public static final String BROADCAST_STICKY1 = "android.app.cts.activity.BROADCAST_STICKY1";
+    public static final String BROADCAST_STICKY2 = "android.app.cts.activity.BROADCAST_STICKY2";
+
+    public static final String ALIAS_ACTIVITY = "android.app.cts.activity.ALIAS_ACTIVITY";
+
+    public static final String RECEIVER_REG = "receiver-reg";
+    public static final String RECEIVER_LOCAL = "receiver-local";
+    public static final String RECEIVER_REMOTE = "receiver-remote";
+    public static final String RECEIVER_ABORT = "receiver-abort";
+
+    public static final String DATA_1 = "one";
+    public static final String DATA_2 = "two";
+
+    public static final String ON_START = "onStart";
+    public static final String ON_RESTART = "onRestart";
+    public static final String ON_RESUME = "onResume";
+    public static final String ON_FREEZE = "onSaveInstanceState";
+    public static final String ON_PAUSE = "onPause";
+
+    // ON_STOP and ON_DESTROY are not tested because they may not be called.
+
+    public static final String DO_FINISH = "finish";
+    public static final String DO_LOCAL_SCREEN = "local-screen";
+    public static final String DO_LOCAL_DIALOG = "local-dialog";
+
+    private static final String TAG = "LaunchpadActivity";
+
+    private boolean mBadParcelable = false;
+
+    private boolean mStarted = false;
+
+    private int mResultCode = RESULT_CANCELED;
+    private Intent mData = new Intent().setAction("No result received");
+    private RuntimeException mResultStack = null;
+
+    /** Index into the {@link #mNextLifecycle} array. */
+    private int mNextLifecycle;
+
+    /** Current lifecycle expected to be followed. */
+    private String[] mExpectedLifecycle;
+
+    /** Other possible lifecycles. Never includes the current {@link #mExpectedLifecycle}. */
+    private List<String[]> mOtherPossibleLifecycles = new ArrayList<String[]>(2);
+
+    /** Map from lifecycle arrays to debugging log names. */
+    private Map<String[], String> mLifecycleNames = new HashMap<String[], String>(2);
+
+    private String[] mExpectedReceivers = null;
+    private int mNextReceiver;
+
+    private String[] mExpectedData = null;
+    private boolean[] mReceivedData = null;
+
+    boolean mReceiverRegistered = false;
+
+    private static CallingTest sCallingTest = null;
+
+    public static void setCallingTest(CallingTest ct) {
+        sCallingTest = ct;
+    }
+
+    public LaunchpadActivity() {
+    }
+
+    @Override
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        resetLifecycles();
+
+        // ON_STOP and ON_DESTROY are not tested because they may not be called.
+
+        final String action = getIntent().getAction();
+        if (LIFECYCLE_BASIC.equals(action)) {
+            addPossibleLifecycle(LIFECYCLE_BASIC, new String[] {
+                    ON_START, ON_RESUME, DO_FINISH, ON_PAUSE
+            });
+        } else if (LIFECYCLE_SCREEN.equals(action)) {
+            addPossibleLifecycle(LIFECYCLE_SCREEN + "_RESTART", new String[] {
+                    ON_START, ON_RESUME, DO_LOCAL_SCREEN, ON_PAUSE,
+                    ON_RESTART, ON_START, ON_RESUME, DO_FINISH, ON_PAUSE
+            });
+            addPossibleLifecycle(LIFECYCLE_SCREEN + "_RESUME", new String[] {
+                    ON_START, ON_RESUME, DO_LOCAL_SCREEN, ON_PAUSE,
+                    ON_RESUME, DO_FINISH, ON_PAUSE
+            });
+        } else if (LIFECYCLE_DIALOG.equals(action)) {
+            addPossibleLifecycle(LIFECYCLE_DIALOG + "_RESTART", new String[] {
+                    ON_START, ON_RESUME, DO_LOCAL_DIALOG, ON_PAUSE,
+                    ON_RESTART, ON_START, ON_RESUME, DO_FINISH, ON_PAUSE
+            });
+            addPossibleLifecycle(LIFECYCLE_DIALOG + "_RESUME", new String[] {
+                    ON_START, ON_RESUME, DO_LOCAL_DIALOG, ON_PAUSE,
+                    ON_RESUME, DO_FINISH, ON_PAUSE
+            });
+        }
+    }
+
+    private void resetLifecycles() {
+        mNextLifecycle = 0;
+        mExpectedLifecycle = null;
+        mOtherPossibleLifecycles.clear();
+        mLifecycleNames.clear();
+    }
+
+    /**
+     * Add a potential lifecycle that this activity may follow, since there
+     * are usually multiple valid lifecycles. For instance, sometimes onPause
+     * will lead to onResume rather than onStop when another activity is
+     * raised over the current one.
+     *
+     * @param debugName for the lifecycle shown in the logs
+     * @param lifecycle array containing tokens indicating the expected lifecycle
+     */
+    private void addPossibleLifecycle(String debugName, String[] lifecycle) {
+        mLifecycleNames.put(lifecycle, debugName);
+        if (mExpectedLifecycle == null) {
+            mExpectedLifecycle = lifecycle;
+        } else {
+            mOtherPossibleLifecycles.add(lifecycle);
+        }
+    }
+
+    /**
+     * Switch to the next possible lifecycle and return if switching was
+     * successful. Call this method when mExpectedLifecycle doesn't match
+     * the current lifecycle and you need to check another possible lifecycle.
+     *
+     * @return whether on not there was a lifecycle to switch to
+     */
+    private boolean switchToNextPossibleLifecycle() {
+        if (!mOtherPossibleLifecycles.isEmpty()) {
+            String[] newLifecycle = mOtherPossibleLifecycles.remove(0);
+            Log.w(TAG, "Switching expected lifecycles from "
+                    + mLifecycleNames.get(mExpectedLifecycle) + " to "
+                    + mLifecycleNames.get(newLifecycle));
+            mExpectedLifecycle = newLifecycle;
+            return true;
+        } else {
+            Log.w(TAG, "No more lifecycles after "
+                    + mLifecycleNames.get(mExpectedLifecycle));
+            mExpectedLifecycle = null;
+            return false;
+        }
+    }
+
+    @Override
+    protected void onStart() {
+        super.onStart();
+        checkLifecycle(ON_START);
+    }
+
+    @Override
+    protected void onRestart() {
+        super.onStart();
+        checkLifecycle(ON_RESTART);
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+
+        checkLifecycle(ON_RESUME);
+
+        if (!mStarted) {
+            mStarted = true;
+
+            mHandler.postDelayed(mTimeout, 10 * 1000);
+
+            final String action = getIntent().getAction();
+
+            sCallingTest.startTiming(true);
+
+            if (LAUNCH.equals(action)) {
+                final Intent intent = getIntent();
+                intent.setFlags(0);
+                intent.setComponent((ComponentName) intent.getParcelableExtra("component"));
+                startActivityForResult(intent, LAUNCHED_RESULT);
+
+            } else if (FORWARD_RESULT.equals(action)) {
+                final Intent intent = getIntent();
+                intent.setFlags(0);
+                intent.setClass(this, LocalScreen.class);
+                startActivityForResult(intent, FORWARDED_RESULT);
+            } else if (BAD_PARCELABLE.equals(action)) {
+                mBadParcelable = true;
+                final Intent intent = getIntent();
+                intent.setFlags(0);
+                intent.setClass(this, LocalScreen.class);
+                startActivityForResult(intent, LAUNCHED_RESULT);
+            } else if (BROADCAST_REGISTERED.equals(action)) {
+                setExpectedReceivers(new String[] {
+                    RECEIVER_REG
+                });
+                registerMyReceiver(new IntentFilter(BROADCAST_REGISTERED));
+                sCallingTest.addIntermediate("after-register");
+                sendBroadcast(makeBroadcastIntent(BROADCAST_REGISTERED));
+            } else if (BROADCAST_LOCAL.equals(action)) {
+                setExpectedReceivers(new String[] {
+                    RECEIVER_LOCAL
+                });
+                sendBroadcast(makeBroadcastIntent(BROADCAST_LOCAL));
+            } else if (BROADCAST_REMOTE.equals(action)) {
+                setExpectedReceivers(new String[] {
+                    RECEIVER_REMOTE
+                });
+                sendBroadcast(makeBroadcastIntent(BROADCAST_REMOTE));
+            } else if (BROADCAST_ALL.equals(action)) {
+                setExpectedReceivers(new String[] {
+                        RECEIVER_REMOTE, RECEIVER_REG, RECEIVER_LOCAL
+                });
+                registerMyReceiver(new IntentFilter(BROADCAST_ALL));
+                sCallingTest.addIntermediate("after-register");
+                sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_ALL), null);
+            } else if (BROADCAST_MULTI.equals(action)) {
+                setExpectedReceivers(new String[] {
+                        RECEIVER_REMOTE, RECEIVER_REG, RECEIVER_LOCAL, RECEIVER_REMOTE,
+                        RECEIVER_REG, RECEIVER_LOCAL, RECEIVER_REMOTE, RECEIVER_REG,
+                        RECEIVER_LOCAL, RECEIVER_LOCAL, RECEIVER_REMOTE, RECEIVER_LOCAL,
+                        RECEIVER_REMOTE, RECEIVER_REMOTE, RECEIVER_REG, RECEIVER_LOCAL,
+                        RECEIVER_REMOTE, RECEIVER_REG, RECEIVER_LOCAL, RECEIVER_REMOTE,
+                        RECEIVER_REG, RECEIVER_LOCAL, RECEIVER_REMOTE, RECEIVER_LOCAL,
+                        RECEIVER_REMOTE, RECEIVER_LOCAL
+                });
+                registerMyReceiver(new IntentFilter(BROADCAST_ALL));
+                sCallingTest.addIntermediate("after-register");
+                sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_ALL), null);
+                sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_ALL), null);
+                sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_ALL), null);
+                sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_LOCAL), null);
+                sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_REMOTE), null);
+                sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_LOCAL), null);
+                sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_REMOTE), null);
+                sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_ALL), null);
+                sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_ALL), null);
+                sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_ALL), null);
+                sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_REPEAT), null);
+            } else if (BROADCAST_ABORT.equals(action)) {
+                setExpectedReceivers(new String[] {
+                        RECEIVER_REMOTE, RECEIVER_ABORT
+                });
+                registerMyReceiver(new IntentFilter(BROADCAST_ABORT));
+                sCallingTest.addIntermediate("after-register");
+                sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_ABORT), null);
+            } else if (BROADCAST_STICKY1.equals(action)) {
+                setExpectedReceivers(new String[] {
+                    RECEIVER_REG
+                });
+                setExpectedData(new String[] {
+                    DATA_1
+                });
+                registerMyReceiver(new IntentFilter(BROADCAST_STICKY1));
+                sCallingTest.addIntermediate("after-register");
+            } else if (BROADCAST_STICKY2.equals(action)) {
+                setExpectedReceivers(new String[] {
+                        RECEIVER_REG, RECEIVER_REG
+                });
+                setExpectedData(new String[] {
+                        DATA_1, DATA_2
+                });
+                final IntentFilter filter = new IntentFilter(BROADCAST_STICKY1);
+                filter.addAction(BROADCAST_STICKY2);
+                registerMyReceiver(filter);
+                sCallingTest.addIntermediate("after-register");
+            } else if (ALIAS_ACTIVITY.equals(action)) {
+                final Intent intent = getIntent();
+                intent.setFlags(0);
+                intent.setClass(this, AliasActivityStub.class);
+                startActivityForResult(intent, LAUNCHED_RESULT);
+            } else if (EXPANDLIST_SELECT.equals(action)) {
+                final Intent intent = getIntent();
+                intent.setFlags(0);
+                intent.setAction(action);
+                intent.setComponent((ComponentName) intent.getParcelableExtra("component"));
+                startActivityForResult(intent, LAUNCHED_RESULT);
+            } else if (EXPANDLIST_VIEW.equals(action)) {
+                final Intent intent = getIntent();
+                intent.setFlags(0);
+                intent.setAction(action);
+                intent.setComponent((ComponentName) intent.getParcelableExtra("component"));
+                startActivityForResult(intent, LAUNCHED_RESULT);
+            } else if (EXPANDLIST_CALLBACK.equals(action)) {
+                final Intent intent = getIntent();
+                intent.setFlags(0);
+                intent.setAction(action);
+                intent.setComponent((ComponentName) intent.getParcelableExtra("component"));
+                startActivityForResult(intent, LAUNCHED_RESULT);
+            }
+        }
+    }
+
+    @Override
+    protected void onSaveInstanceState(Bundle icicle) {
+        super.onSaveInstanceState(icicle);
+        if (mBadParcelable) {
+            icicle.putParcelable("baddy", new MyBadParcelable());
+        }
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+        checkLifecycle(ON_PAUSE);
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        switch (requestCode) {
+            case LAUNCHED_RESULT:
+                sCallingTest.finishTiming(true);
+                finishWithResult(resultCode, data);
+                break;
+            case FORWARDED_RESULT:
+                sCallingTest.finishTiming(true);
+                if (RETURNED_RESULT.equals(data.getAction())) {
+                    finishWithResult(resultCode, data);
+                } else {
+                    finishWithResult(RESULT_CANCELED, new Intent().setAction("Bad data returned: "
+                            + data));
+                }
+                break;
+            default:
+                sCallingTest.finishTiming(true);
+                finishWithResult(RESULT_CANCELED, new Intent()
+                        .setAction("Unexpected request code: " + requestCode));
+                break;
+        }
+    }
+
+    private void checkLifecycle(String where) {
+        String action = getIntent().getAction();
+
+        if (mExpectedLifecycle == null) {
+            return;
+        }
+
+        if (mNextLifecycle >= mExpectedLifecycle.length) {
+            finishBad("Activity lifecycle for " + action + " incorrect: received " + where
+                    + " but don't expect any more calls");
+            mExpectedLifecycle = null;
+            return;
+        }
+
+        do {
+            if (mExpectedLifecycle[mNextLifecycle].equals(where)) {
+                Log.w(TAG, "Matched: " + where);
+                break;
+            } else {
+                Log.w(TAG, "Expected " + mExpectedLifecycle[mNextLifecycle] + " but got " + where);
+            }
+        } while (switchToNextPossibleLifecycle());
+
+        if (mExpectedLifecycle == null) {
+            finishBad("Activity lifecycle for " + action + " incorrect: received " + where
+                    + " at " + mNextLifecycle);
+            return;
+        }
+
+        mNextLifecycle++;
+
+        if (mNextLifecycle >= mExpectedLifecycle.length) {
+            finishGood();
+            return;
+        }
+
+        final String next = mExpectedLifecycle[mNextLifecycle];
+        if (next.equals(DO_FINISH)) {
+            mNextLifecycle++;
+            if (mNextLifecycle >= mExpectedLifecycle.length) {
+                setTestResult(RESULT_OK, null);
+            }
+            if (!isFinishing()) {
+                finish();
+            }
+        } else if (next.equals(DO_LOCAL_SCREEN)) {
+            mNextLifecycle++;
+            final Intent intent = new Intent(TestedScreen.WAIT_BEFORE_FINISH);
+            intent.setClass(this, LocalScreen.class);
+            startActivity(intent);
+        } else if (next.equals(DO_LOCAL_DIALOG)) {
+            mNextLifecycle++;
+            final Intent intent = new Intent(TestedScreen.WAIT_BEFORE_FINISH);
+            intent.setClass(this, LocalDialog.class);
+            startActivity(intent);
+        }
+    }
+
+    private void setExpectedReceivers(String[] receivers) {
+        mExpectedReceivers = receivers;
+        mNextReceiver = 0;
+    }
+
+    private void setExpectedData(String[] data) {
+        mExpectedData = data;
+        mReceivedData = new boolean[data.length];
+    }
+
+    @SuppressWarnings("deprecation")
+    private Intent makeBroadcastIntent(String action) {
+        final Intent intent = new Intent(action, null);
+        intent.putExtra("caller", mCallTarget);
+        return intent;
+    }
+
+    private void finishGood() {
+        finishWithResult(RESULT_OK, null);
+    }
+
+    private void finishBad(String error) {
+        finishWithResult(RESULT_CANCELED, new Intent().setAction(error));
+    }
+
+    private void finishWithResult(int resultCode, Intent data) {
+        setTestResult(resultCode, data);
+        finish();
+
+        // Member fields set by calling setTestResult above...
+        sCallingTest.activityFinished(mResultCode, mData, mResultStack);
+    }
+
+    private void setTestResult(int resultCode, Intent data) {
+        mHandler.removeCallbacks(mTimeout);
+        unregisterMyReceiver();
+        mResultCode = resultCode;
+        mData = data;
+        mResultStack = new RuntimeException("Original error was here");
+        mResultStack.fillInStackTrace();
+    }
+
+    private void registerMyReceiver(IntentFilter filter) {
+        mReceiverRegistered = true;
+        registerReceiver(mReceiver, filter);
+    }
+
+    private void unregisterMyReceiver() {
+        if (mReceiverRegistered) {
+            mReceiverRegistered = false;
+            unregisterReceiver(mReceiver);
+        }
+    }
+
+    private final Handler mHandler = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+        }
+    };
+
+    static final int GOT_RECEIVE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION;
+    static final int ERROR_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 1;
+
+    private final Binder mCallTarget = new Binder() {
+        @Override
+        public boolean onTransact(int code, Parcel data, Parcel reply, int flags) {
+            data.setDataPosition(0);
+            data.enforceInterface(LaunchpadActivity.LAUNCH);
+            if (code == GOT_RECEIVE_TRANSACTION) {
+                final String name = data.readString();
+                gotReceive(name, null);
+                return true;
+            } else if (code == ERROR_TRANSACTION) {
+                finishBad(data.readString());
+                return true;
+            }
+            return false;
+        }
+    };
+
+    private final void gotReceive(String name, Intent intent) {
+        synchronized (this) {
+
+            sCallingTest.addIntermediate(mNextReceiver + "-" + name);
+
+            if (mExpectedData != null) {
+                final int n = mExpectedData.length;
+                int i;
+                boolean prev = false;
+                for (i = 0; i < n; i++) {
+                    if (mExpectedData[i].equals(intent.getStringExtra("test"))) {
+                        if (mReceivedData[i]) {
+                            prev = true;
+                            continue;
+                        }
+                        mReceivedData[i] = true;
+                        break;
+                    }
+                }
+                if (i >= n) {
+                    if (prev) {
+                        finishBad("Receive got data too many times: "
+                                + intent.getStringExtra("test"));
+                    } else {
+                        finishBad("Receive got unexpected data: " + intent.getStringExtra("test"));
+                    }
+                    return;
+                }
+            }
+
+            if (mNextReceiver >= mExpectedReceivers.length) {
+                finishBad("Got too many onReceiveIntent() calls!");
+            } else if (!mExpectedReceivers[mNextReceiver].equals(name)) {
+                finishBad("Receive out of order: got " + name + " but expected "
+                        + mExpectedReceivers[mNextReceiver] + " at " + mNextReceiver);
+            } else {
+                mNextReceiver++;
+                if (mNextReceiver == mExpectedReceivers.length) {
+                    mHandler.post(mUnregister);
+                }
+            }
+
+        }
+    }
+
+    private final Runnable mUnregister = new Runnable() {
+        public void run() {
+            if (mReceiverRegistered) {
+                sCallingTest.addIntermediate("before-unregister");
+                unregisterMyReceiver();
+            }
+            sCallingTest.finishTiming(true);
+            finishGood();
+        }
+    };
+
+    private final Runnable mTimeout = new Runnable() {
+        public void run() {
+            Log.i(TAG, "timeout");
+            String msg = "Timeout";
+            if (mExpectedReceivers != null && mNextReceiver < mExpectedReceivers.length) {
+                msg = msg + " waiting for " + mExpectedReceivers[mNextReceiver];
+            }
+            finishBad(msg);
+        }
+    };
+
+    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            gotReceive(RECEIVER_REG, intent);
+        }
+    };
+}
diff --git a/tests/app/app/src/android/app/stubs/LaunchpadTabActivity.java b/tests/app/app/src/android/app/stubs/LaunchpadTabActivity.java
new file mode 100644
index 0000000..a63b384
--- /dev/null
+++ b/tests/app/app/src/android/app/stubs/LaunchpadTabActivity.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.stubs;
+
+import android.app.TabActivity;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.os.Bundle;
+import android.widget.TabHost;
+
+public class LaunchpadTabActivity extends TabActivity {
+    public LaunchpadTabActivity() {
+    }
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        final Intent tabIntent = new Intent(getIntent());
+        tabIntent.setComponent((ComponentName) tabIntent.getParcelableExtra("tab"));
+
+        final TabHost th = getTabHost();
+        final TabHost.TabSpec ts = th.newTabSpec("1");
+        ts.setIndicator("One");
+        ts.setContent(tabIntent);
+        th.addTab(ts);
+    }
+}
diff --git a/tests/app/app/src/android/app/stubs/LocalActivity.java b/tests/app/app/src/android/app/stubs/LocalActivity.java
new file mode 100644
index 0000000..b279d3b
--- /dev/null
+++ b/tests/app/app/src/android/app/stubs/LocalActivity.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.stubs;
+
+public class LocalActivity extends TestedActivity {
+    public LocalActivity() {
+    }
+}
diff --git a/tests/app/app/src/android/app/stubs/LocalActivityManagerStubActivity.java b/tests/app/app/src/android/app/stubs/LocalActivityManagerStubActivity.java
new file mode 100644
index 0000000..f7df9a3
--- /dev/null
+++ b/tests/app/app/src/android/app/stubs/LocalActivityManagerStubActivity.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.stubs;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class LocalActivityManagerStubActivity extends Activity{
+
+    public static boolean sIsOnResumeCalled;
+    public static boolean sIsOnStopCalled;
+    public static boolean sIsOnPauseCalled;
+    public static boolean sIsOnDestroyCalled;
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        sIsOnResumeCalled = true;
+    }
+
+    @Override
+    protected void onStop() {
+        super.onStop();
+        sIsOnStopCalled = true;
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+        sIsOnPauseCalled = true;
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+        sIsOnDestroyCalled = true;
+    }
+}
diff --git a/tests/app/app/src/android/app/stubs/LocalActivityManagerTestHelper.java b/tests/app/app/src/android/app/stubs/LocalActivityManagerTestHelper.java
new file mode 100644
index 0000000..8e28ee4
--- /dev/null
+++ b/tests/app/app/src/android/app/stubs/LocalActivityManagerTestHelper.java
@@ -0,0 +1,340 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES 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.app.stubs;
+
+
+import android.app.Activity;
+import android.app.ActivityGroup;
+import android.app.LocalActivityManager;
+import android.content.Intent;
+import android.cts.util.CTSResult;
+import android.os.Bundle;
+import android.view.Window;
+
+public class LocalActivityManagerTestHelper extends ActivityGroup {
+
+    public static final String ACTION_DISPATCH_RESUME = "dispatchResume";
+    public static final String ACTION_START_ACTIVITY = "startActivity";
+    public static final String ACTION_DISPATCH_CREATE = "dispatchCreate";
+    public static final String ACTION_DISPATCH_STOP = "dispatchStop";
+    public static final String ACTION_DISPATCH_PAUSE_TRUE = "dispatchPauseTrue";
+    public static final String ACTION_DISPATCH_PAUSE_FALSE = "dispatchPauseFalse";
+    public static final String ACTION_SAVE_INSTANCE_STATE = "saveInstanceState";
+    public static final String ACTION_DISPATCH_DESTROY = "dispatchDestroy";
+    public static final String ACTION_REMOVE_ALL_ACTIVITY = "removeAllActivities";
+
+    private String mCurrentAction;
+    private LocalActivityManager mLocalActivityManager;
+
+    private static CTSResult sResult;
+
+    public static void setResult(CTSResult cr) {
+        sResult = cr;
+    }
+
+    public LocalActivityManagerTestHelper() {
+        super();
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        mCurrentAction = getIntent().getAction();
+        mLocalActivityManager = getLocalActivityManager();
+    }
+
+    @Override
+    protected void onStart() {
+        super.onStart();
+    }
+
+    protected void onResume() {
+        super.onResume();
+        if (mCurrentAction.equals(ACTION_DISPATCH_RESUME)) {
+            testDispatchResume();
+        } else if (mCurrentAction.equals(ACTION_START_ACTIVITY)) {
+            testStartActivity();
+        } else if (mCurrentAction.equals(ACTION_DISPATCH_CREATE)) {
+            testDispatchCreate();
+        } else if (mCurrentAction.equals(ACTION_DISPATCH_STOP)) {
+            testDispatchStop();
+        } else if (mCurrentAction.equals(ACTION_DISPATCH_PAUSE_TRUE)) {
+            testDispatchPauseTrue();
+        } else if (mCurrentAction.equals(ACTION_DISPATCH_PAUSE_FALSE)) {
+            testDispatchPauseFalse();
+        } else if (mCurrentAction.equals(ACTION_SAVE_INSTANCE_STATE)) {
+            testSaveInstanceState();
+        } else if (mCurrentAction.equals(ACTION_DISPATCH_DESTROY)) {
+            testDispatchDestroy();
+        } else if (mCurrentAction.equals(ACTION_REMOVE_ALL_ACTIVITY)) {
+            testRemoveAllActivity();
+        }
+    }
+
+    private void testRemoveAllActivity() {
+        final String id = "id_remove_activity";
+        final Intent intent = new Intent(this, LocalActivityManagerStubActivity.class);
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        mLocalActivityManager.startActivity(id, intent);
+
+        Activity activity = mLocalActivityManager.getActivity(id);
+        if (activity == null) {
+            fail();
+            return;
+        }
+
+        if (!activity.getClass().getName().equals("android.app.stubs."
+                    + "LocalActivityManagerStubActivity")) {
+            fail();
+            return;
+        }
+
+        mLocalActivityManager.removeAllActivities();
+        activity = mLocalActivityManager.getActivity(id);
+        if (activity != null) {
+            fail();
+            return;
+        }
+        pass();
+    }
+
+    private void testDispatchDestroy() {
+        final String id1 = "id_dispatch_destroy1";
+        final String id2 = "id_dispatch_destroy2";
+        final Intent intent = new Intent(this, LocalActivityManagerStubActivity.class);
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        mLocalActivityManager.startActivity(id1, intent);
+
+        LocalActivityManagerStubActivity.sIsOnDestroyCalled = false;
+        mLocalActivityManager.dispatchDestroy(false);
+        if (mLocalActivityManager.getCurrentActivity().isFinishing()){
+            fail();
+            return;
+        }
+
+        if (!LocalActivityManagerStubActivity.sIsOnDestroyCalled) {
+            fail();
+            return;
+        }
+
+        mLocalActivityManager.startActivity(id2, intent);
+        LocalActivityManagerStubActivity.sIsOnDestroyCalled = false;
+        mLocalActivityManager.dispatchDestroy(true);
+
+        if (!LocalActivityManagerStubActivity.sIsOnDestroyCalled) {
+            fail();
+            return;
+        }
+
+        if (!mLocalActivityManager.getCurrentActivity().isFinishing()){
+            fail();
+            return;
+        }
+        pass();
+    }
+
+    private void testSaveInstanceState() {
+        final String key = "_id1";
+        mLocalActivityManager.dispatchCreate(null);
+        final Bundle bundle = mLocalActivityManager.saveInstanceState();
+        if (bundle != null) {
+            fail();
+            return;
+        }
+
+        final String id = "id_dispatch_pause";
+        final Intent intent = new Intent(this, LocalActivityManagerStubActivity.class);
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        mLocalActivityManager.startActivity(id, intent);
+
+        final Bundle savedBundle = new Bundle();
+        final Bundle bb = new Bundle();
+        savedBundle.putBundle(key, bb);
+
+        mLocalActivityManager.dispatchCreate(savedBundle);
+        final Bundle returnedBundle = mLocalActivityManager.saveInstanceState();
+        if (returnedBundle.getBundle(key) == null ) {
+            fail();
+            return;
+        }
+        pass();
+    }
+
+    private void testDispatchPauseFalse() {
+        final String id = "id_dispatch_pause";
+        final Intent intent = new Intent(this, LocalActivityManagerStubActivity.class);
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        mLocalActivityManager.startActivity(id, intent);
+        LocalActivityManagerStubActivity.sIsOnPauseCalled = false;
+        mLocalActivityManager.dispatchPause(false);
+        if (!LocalActivityManagerStubActivity.sIsOnPauseCalled) {
+            fail();
+            return;
+        }
+        pass();
+    }
+
+    private void testDispatchPauseTrue() {
+        final String id = "id_dispatch_pause";
+        final Intent intent = new Intent(this, LocalActivityManagerStubActivity.class);
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        mLocalActivityManager.startActivity(id, intent);
+        LocalActivityManagerStubActivity.sIsOnPauseCalled = false;
+        mLocalActivityManager.dispatchPause(true);
+        if (!LocalActivityManagerStubActivity.sIsOnPauseCalled) {
+            fail();
+            return;
+        }
+        pass();
+    }
+
+    private void testDispatchStop() {
+        final String id = "id_dispatch_stop";
+        final Intent intent = new Intent(this, LocalActivityManagerStubActivity.class);
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        mLocalActivityManager.startActivity(id, intent);
+        if (mLocalActivityManager.getCurrentActivity() == null) {
+            fail();
+            return;
+        }
+
+        LocalActivityManagerStubActivity.sIsOnStopCalled = false;
+        mLocalActivityManager.dispatchStop();
+
+        if (!LocalActivityManagerStubActivity.sIsOnStopCalled) {
+            fail();
+            return;
+        }
+        pass();
+    }
+
+    private void testDispatchCreate() {
+        final Bundle EXPECTED = new Bundle();
+        final String id = "id";
+
+        final Intent intent = new Intent(this, LocalActivityManagerStubActivity.class);
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        mLocalActivityManager.startActivity("_id" + System.currentTimeMillis(), intent);
+        final Bundle bundle = mLocalActivityManager.saveInstanceState();
+        if (bundle == null) {
+            fail();
+            return;
+        }
+
+        if (bundle.keySet().size() != 1) {
+            fail();
+            return;
+        }
+
+        bundle.putBundle(id, EXPECTED);
+        // test null parameter
+        mLocalActivityManager.dispatchCreate(null);
+
+        if (mLocalActivityManager.saveInstanceState().keySet().size() != 1) {
+            fail();
+            return;
+        }
+
+        mLocalActivityManager.dispatchCreate(bundle);
+
+        final Bundle b = mLocalActivityManager.saveInstanceState();
+        final Bundle bb = b.getBundle(id);
+        if (bb != EXPECTED) {
+            fail();
+            return;
+        }
+        pass();
+    }
+
+    private void testStartActivity() {
+        final Intent intent = new Intent(this, LocalActivityManagerStubActivity.class);
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        final String id = "_id_resume_test";
+        final Window w = mLocalActivityManager.startActivity(id, intent);
+        if (w == null) {
+            fail();
+            return;
+        }
+
+        Activity activity = mLocalActivityManager.getActivity(id);
+        if (activity == null) {
+            fail();
+            return;
+        }
+
+        // testing null id
+        activity = mLocalActivityManager.getActivity("null id");
+        if (activity != null) {
+            fail();
+            return;
+        }
+
+        if (!mLocalActivityManager.getCurrentId().equals(id)) {
+            fail();
+            return;
+        }
+
+        if (mLocalActivityManager.getActivity(id) != mLocalActivityManager
+                .getCurrentActivity()) {
+            fail();
+            return;
+        }
+
+        if (mLocalActivityManager.destroyActivity(id, true) == null) {
+            fail();
+            return;
+        }
+
+        if (mLocalActivityManager.startActivity(null, intent) == null) {
+            fail();
+            return;
+        }
+
+        try {
+            // test when calling startActivity with both null parameter.
+            mLocalActivityManager.startActivity(null, null);
+            fail();
+            return;
+        } catch (NullPointerException e) {
+        }
+        pass();
+    }
+
+    private void testDispatchResume() {
+        final Intent intent = new Intent(this, LocalActivityManagerStubActivity.class);
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        mLocalActivityManager.startActivity("_id_resume_test", intent);
+        mLocalActivityManager.dispatchStop();
+        LocalActivityManagerStubActivity.sIsOnResumeCalled = false;
+        mLocalActivityManager.dispatchResume();
+        if (LocalActivityManagerStubActivity.sIsOnResumeCalled) {
+            pass();
+        } else {
+            fail();
+        }
+    }
+
+    private void fail() {
+        sResult.setResult(CTSResult.RESULT_FAIL);
+        finish();
+    }
+
+    private void pass() {
+        sResult.setResult(CTSResult.RESULT_OK);
+        finish();
+    }
+}
diff --git a/tests/app/app/src/android/app/stubs/LocalDeniedService.java b/tests/app/app/src/android/app/stubs/LocalDeniedService.java
new file mode 100644
index 0000000..aaf4670
--- /dev/null
+++ b/tests/app/app/src/android/app/stubs/LocalDeniedService.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.stubs;
+
+public class LocalDeniedService extends LocalService
+{
+}
+
diff --git a/tests/app/app/src/android/app/stubs/LocalDialog.java b/tests/app/app/src/android/app/stubs/LocalDialog.java
new file mode 100644
index 0000000..62c4824
--- /dev/null
+++ b/tests/app/app/src/android/app/stubs/LocalDialog.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.stubs;
+
+public class LocalDialog extends TestedScreen {
+    public LocalDialog() {
+    }
+}
diff --git a/tests/app/app/src/android/app/stubs/LocalGrantedService.java b/tests/app/app/src/android/app/stubs/LocalGrantedService.java
new file mode 100644
index 0000000..c82d3fd
--- /dev/null
+++ b/tests/app/app/src/android/app/stubs/LocalGrantedService.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.stubs;
+
+public class LocalGrantedService extends LocalService
+{
+}
+
diff --git a/tests/app/app/src/android/app/stubs/LocalScreen.java b/tests/app/app/src/android/app/stubs/LocalScreen.java
new file mode 100644
index 0000000..21026a1
--- /dev/null
+++ b/tests/app/app/src/android/app/stubs/LocalScreen.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.stubs;
+
+public class LocalScreen extends TestedScreen {
+    public LocalScreen() {
+    }
+}
diff --git a/tests/app/app/src/android/app/stubs/LocalService.java b/tests/app/app/src/android/app/stubs/LocalService.java
new file mode 100644
index 0000000..01e098b
--- /dev/null
+++ b/tests/app/app/src/android/app/stubs/LocalService.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.stubs;
+
+import android.app.Service;
+import android.content.Intent;
+import android.cts.util.IBinderParcelable;
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.RemoteException;
+
+public class LocalService extends Service {
+    public static final String SERVICE_LOCAL =
+            "android.app.cts.activity.SERVICE_LOCAL";
+    public static final String SERVICE_LOCAL_GRANTED =
+            "android.app.cts.activity.SERVICE_LOCAL_GRANTED";
+    public static final String SERVICE_LOCAL_DENIED =
+            "android.app.cts.activity.SERVICE_LOCAL_DENIED";
+
+    public static final String REPORT_OBJ_NAME = "report";
+
+    public static final int STARTED_CODE = 1;
+    public static final int DESTROYED_CODE = 2;
+    public static final int SET_REPORTER_CODE = 3;
+    public static final int UNBIND_CODE = 4;
+    public static final int REBIND_CODE = 5;
+
+    private IBinder mReportObject;
+    private int mStartCount = 1;
+
+    private final IBinder mBinder = new Binder() {
+        @Override
+        protected boolean onTransact(int code, Parcel data, Parcel reply,
+                int flags) throws RemoteException {
+            if (code == SET_REPORTER_CODE) {
+                data.enforceInterface(SERVICE_LOCAL);
+                mReportObject = data.readStrongBinder();
+                return true;
+            } else {
+                return super.onTransact(code, data, reply, flags);
+            }
+        }
+    };
+
+
+    public LocalService() {
+    }
+
+    @Override
+    public void onStart(Intent intent, int startId) {
+        if (intent.getExtras() != null) {
+            IBinderParcelable parcelable
+                    = (IBinderParcelable) intent.getExtras().getParcelable(REPORT_OBJ_NAME);
+            mReportObject = parcelable.binder;
+            if (mReportObject != null) {
+                bindAction(STARTED_CODE);
+            }
+        }
+    }
+
+    @Override
+    public void onDestroy() {
+        if (mReportObject != null) {
+            bindAction(DESTROYED_CODE);
+        }
+    }
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        return mBinder;
+    }
+
+    @Override
+    public boolean onUnbind(Intent intent) {
+        if (mReportObject != null) {
+            bindAction(UNBIND_CODE);
+        }
+        return true;
+    }
+
+    @Override
+    public void onRebind(Intent intent) {
+        if (mReportObject != null) {
+            bindAction(REBIND_CODE);
+        }
+    }
+
+    private void bindAction(final int bindCode) {
+        try {
+            Parcel data = Parcel.obtain();
+            data.writeInterfaceToken(SERVICE_LOCAL);
+            if (bindCode == STARTED_CODE) {
+                data.writeInt(mStartCount);
+                mStartCount++;
+            }
+            mReportObject.transact(
+                    bindCode, data, null, 0);
+            data.recycle();
+        } catch (RemoteException e) {
+            // fail
+        }
+    }
+}
diff --git a/tests/app/app/src/android/app/stubs/MockActivity.java b/tests/app/app/src/android/app/stubs/MockActivity.java
new file mode 100644
index 0000000..625263a
--- /dev/null
+++ b/tests/app/app/src/android/app/stubs/MockActivity.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.stubs;
+
+import android.app.Activity;
+
+public class MockActivity extends Activity {
+
+}
diff --git a/tests/app/app/src/android/app/stubs/MockAlarmReceiver.java b/tests/app/app/src/android/app/stubs/MockAlarmReceiver.java
new file mode 100644
index 0000000..57374ef
--- /dev/null
+++ b/tests/app/app/src/android/app/stubs/MockAlarmReceiver.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.stubs;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.os.SystemClock;
+
+/**
+ * this class  receive alarm from AlarmManagerTest
+ */
+public class MockAlarmReceiver extends BroadcastReceiver {
+    private final Object mSync = new Object();
+    public final String mTargetAction;
+
+    public volatile boolean alarmed = false;
+    public volatile long elapsedTime;
+    public volatile long rtcTime;
+
+    public MockAlarmReceiver(String targetAction) {
+        mTargetAction = targetAction;
+    }
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        final String action = intent.getAction();
+        if (action.equals(mTargetAction)) {
+            synchronized (mSync) {
+                alarmed = true;
+                elapsedTime = SystemClock.elapsedRealtime();
+                rtcTime = System.currentTimeMillis();
+            }
+        }
+    }
+
+    public void setAlarmedFalse() {
+        synchronized (mSync) {
+            alarmed = false;
+        }
+    }
+}
diff --git a/tests/app/app/src/android/app/stubs/MockApplication.java b/tests/app/app/src/android/app/stubs/MockApplication.java
new file mode 100644
index 0000000..4de2a95
--- /dev/null
+++ b/tests/app/app/src/android/app/stubs/MockApplication.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.stubs;
+
+import android.app.Application;
+import android.content.res.Configuration;
+
+
+public class MockApplication extends Application {
+
+    public boolean isOnCreateCalled;
+    public boolean isConstructorCalled;
+    public boolean isOnConfigurationChangedCalled;
+    public boolean isOnLowMemoryCalled;
+
+    public MockApplication() {
+        super();
+        isConstructorCalled = true;
+    }
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        isOnCreateCalled = true;
+    }
+
+    @Override
+    public void onTerminate() {
+        super.onTerminate();
+        // The documentation states that one cannot rely on this method being called. No need to
+        // test it here.
+    }
+
+    @Override
+    public void onConfigurationChanged(Configuration newConfig) {
+        super.onConfigurationChanged(newConfig);
+        isOnConfigurationChangedCalled = true;
+    }
+
+    @Override
+    public void onLowMemory() {
+        super.onLowMemory();
+        isOnLowMemoryCalled = true;
+    }
+}
diff --git a/tests/app/app/src/android/app/stubs/MockApplicationActivity.java b/tests/app/app/src/android/app/stubs/MockApplicationActivity.java
new file mode 100644
index 0000000..6df70d7
--- /dev/null
+++ b/tests/app/app/src/android/app/stubs/MockApplicationActivity.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.stubs;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.TextView;
+
+public class MockApplicationActivity extends Activity {
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        TextView textView = new TextView(this);
+        textView.setText("Test");
+        setContentView(textView);
+    }
+
+}
diff --git a/tests/app/app/src/android/app/stubs/MockListActivity.java b/tests/app/app/src/android/app/stubs/MockListActivity.java
new file mode 100644
index 0000000..1d32192
--- /dev/null
+++ b/tests/app/app/src/android/app/stubs/MockListActivity.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.stubs;
+
+import android.app.ListActivity;
+import android.view.View;
+import android.widget.ListView;
+
+public class MockListActivity extends ListActivity {
+    public boolean isOnListItemClickCalled;
+    public int itemClickCallCount;
+    public int clickedItemPosition;
+
+    @Override
+    protected void onListItemClick(ListView l, View v, int position, long id) {
+        isOnListItemClickCalled = true;
+        itemClickCallCount++;
+        clickedItemPosition = position;
+    }
+}
diff --git a/tests/app/app/src/android/app/stubs/MockReceiver.java b/tests/app/app/src/android/app/stubs/MockReceiver.java
new file mode 100644
index 0000000..7704340
--- /dev/null
+++ b/tests/app/app/src/android/app/stubs/MockReceiver.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.stubs;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+public class MockReceiver extends BroadcastReceiver {
+
+    // PendingIntent may return same instance or new instance, so static variable is needed.
+    public static int sResultCode = 0;
+    public static final String MOCKACTION = "android.app.PendingIntentTest.TEST_RECEIVER";
+    public static String sAction;
+
+    /**
+     * set the result as true when received alarm
+     */
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        sAction = intent.getAction();
+        if (sAction.equals(MOCKACTION)) {
+            sResultCode = getResultCode();
+        }
+    }
+}
+
diff --git a/tests/app/app/src/android/app/stubs/MockService.java b/tests/app/app/src/android/app/stubs/MockService.java
new file mode 100644
index 0000000..7a8c001
--- /dev/null
+++ b/tests/app/app/src/android/app/stubs/MockService.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.stubs;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.Binder;
+import android.os.IBinder;
+
+public class MockService extends Service {
+    public static boolean result = false;
+    private final IBinder mBinder = new MockBinder();
+
+    public class MockBinder extends Binder {
+        MockService getService() {
+            return MockService.this;
+        }
+    }
+
+    /**
+     * set the result as true when service bind
+     */
+    @Override
+    public IBinder onBind(Intent intent) {
+        result = true;
+        return mBinder;
+    }
+
+    /**
+     * set the result as true when service start
+     */
+    @Override
+    public void onStart(Intent intent, int startId) {
+        super.onStart(intent, startId);
+        result = true;
+    }
+}
+
diff --git a/tests/app/app/src/android/app/stubs/MockTabActivity.java b/tests/app/app/src/android/app/stubs/MockTabActivity.java
new file mode 100644
index 0000000..247cfe0
--- /dev/null
+++ b/tests/app/app/src/android/app/stubs/MockTabActivity.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.stubs;
+
+import android.app.Activity;
+import android.app.TabActivity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.widget.TabHost;
+
+public class MockTabActivity extends TabActivity {
+
+    private static final String TAB1 = "tab1";
+    private static final String TAB2 = "tab2";
+    private static final String TAB3 = "tab3";
+
+    public boolean isOnChildTitleChangedCalled;
+    public boolean isOnPostCreateCalled;
+    public boolean isOnSaveInstanceStateCalled;
+    public boolean isOnContentChangedCalled;
+    public static boolean isOnRestoreInstanceStateCalled;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        final TabHost tabHost = getTabHost();
+
+        tabHost.addTab(tabHost.newTabSpec(TAB1).setIndicator(TAB1)
+                .setContent(new Intent(this, ChildTabActivity.class)));
+
+        tabHost.addTab(tabHost.newTabSpec(TAB2).setIndicator(TAB2)
+                .setContent(new Intent(this, MockActivity.class)));
+
+        tabHost.addTab(tabHost.newTabSpec(TAB3).setIndicator(TAB3).setContent(
+                new Intent(this, AppStubActivity.class).addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)));
+
+    }
+
+    @Override
+    protected void onChildTitleChanged(Activity childActivity, CharSequence title) {
+        super.onChildTitleChanged(childActivity, title);
+        isOnChildTitleChangedCalled = true;
+    }
+
+    @Override
+    protected void onPostCreate(Bundle icicle) {
+        super.onPostCreate(icicle);
+        isOnPostCreateCalled = true;
+    }
+
+    @Override
+    protected void onRestoreInstanceState(Bundle state) {
+        super.onRestoreInstanceState(state);
+        isOnRestoreInstanceStateCalled = true;
+    }
+
+    @Override
+    protected void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+        isOnSaveInstanceStateCalled = true;
+    }
+
+    @Override
+    public void onContentChanged() {
+        super.onContentChanged();
+        isOnContentChangedCalled = true;
+    }
+}
diff --git a/tests/app/app/src/android/app/stubs/OrientationTestUtils.java b/tests/app/app/src/android/app/stubs/OrientationTestUtils.java
new file mode 100644
index 0000000..4ff3fcb
--- /dev/null
+++ b/tests/app/app/src/android/app/stubs/OrientationTestUtils.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.stubs;
+
+import android.app.Activity;
+import android.app.Instrumentation;
+import android.content.pm.ActivityInfo;
+
+public class OrientationTestUtils {
+
+    /**
+     * Change the activity's orientation to something different and then switch back. This is used
+     * to trigger {@link Activity#onConfigurationChanged(android.content.res.Configuration)}.
+     *
+     * @param activity whose orientation will be changed and restored
+     */
+    public static void toggleOrientation(Activity activity) {
+        toggleOrientationSync(activity, null);
+    }
+
+    /**
+     * Same as {@link #toggleOrientation(Activity)} except {@link Instrumentation#waitForIdleSync()}
+     * is called after each orientation change.
+     *
+     * @param activity whose orientation will be changed and restored
+     * @param instrumentation use for idle syncing
+     */
+    public static void toggleOrientationSync(final Activity activity,
+            final Instrumentation instrumentation) {
+        final int originalOrientation = activity.getResources().getConfiguration().orientation;
+        final int newOrientation = originalOrientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
+                ? ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
+                : ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
+        changeOrientation(activity, instrumentation, newOrientation);
+        changeOrientation(activity, instrumentation, originalOrientation);
+    }
+
+    private static void changeOrientation(final Activity activity,
+            Instrumentation instrumentation, final int orientation) {
+        activity.setRequestedOrientation(orientation);
+        if (instrumentation != null) {
+            instrumentation.waitForIdleSync();
+        }
+    }
+}
diff --git a/tests/app/app/src/android/app/stubs/PendingIntentStubActivity.java b/tests/app/app/src/android/app/stubs/PendingIntentStubActivity.java
new file mode 100644
index 0000000..00b59d1
--- /dev/null
+++ b/tests/app/app/src/android/app/stubs/PendingIntentStubActivity.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.stubs;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class PendingIntentStubActivity extends Activity {
+
+    public static final int INVALIDATE = -1;
+    public static final int ON_CREATE = 0;
+    public static int status = INVALIDATE;
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        status = ON_CREATE;
+    }
+
+}
diff --git a/tests/app/app/src/android/app/stubs/PipActivity.java b/tests/app/app/src/android/app/stubs/PipActivity.java
new file mode 100644
index 0000000..533f054
--- /dev/null
+++ b/tests/app/app/src/android/app/stubs/PipActivity.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.stubs;
+
+import android.app.Activity;
+
+public class PipActivity extends Activity {
+
+}
diff --git a/tests/app/app/src/android/app/stubs/PipNotResizeableActivity.java b/tests/app/app/src/android/app/stubs/PipNotResizeableActivity.java
new file mode 100644
index 0000000..7ed1acc
--- /dev/null
+++ b/tests/app/app/src/android/app/stubs/PipNotResizeableActivity.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.stubs;
+
+import android.app.Activity;
+
+public class PipNotResizeableActivity extends Activity {
+
+}
diff --git a/tests/app/app/src/android/app/stubs/PipNotSupportedActivity.java b/tests/app/app/src/android/app/stubs/PipNotSupportedActivity.java
new file mode 100644
index 0000000..e6656a0
--- /dev/null
+++ b/tests/app/app/src/android/app/stubs/PipNotSupportedActivity.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.stubs;
+
+import android.app.Activity;
+
+public class PipNotSupportedActivity extends Activity {
+
+}
diff --git a/tests/app/app/src/android/app/stubs/SearchManagerStubActivity.java b/tests/app/app/src/android/app/stubs/SearchManagerStubActivity.java
new file mode 100644
index 0000000..d6eb968
--- /dev/null
+++ b/tests/app/app/src/android/app/stubs/SearchManagerStubActivity.java
@@ -0,0 +1,239 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.stubs;
+
+import android.app.Activity;
+import android.app.SearchManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.cts.util.CTSResult;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.util.Log;
+
+public class SearchManagerStubActivity extends Activity {
+
+    private static final String TAG = "SearchManagerStubActivity";
+
+    public static final String TEST_STOP_SEARCH = "stopSearch";
+    public static final String TEST_ON_DISMISSLISTENER = "setOnDismissListener";
+    public static final String TEST_ON_CANCELLISTENER = "setOnCancelListener";
+
+    private SearchManager mSearchManager;
+    private ComponentName mComponentName;
+
+    private static CTSResult sCTSResult;
+    private boolean mDismissCalled;
+    private boolean mCancelCalled;
+
+    public static void setCTSResult(CTSResult result) {
+        sCTSResult = result;
+    }
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        mSearchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
+        mComponentName = getComponentName();
+        String action = getIntent().getAction();
+        if (action.equals(TEST_STOP_SEARCH)) {
+            testStopSearch();
+        } else if (action.equals(TEST_ON_DISMISSLISTENER)) {
+            testOnDismissListener();
+        } else if (action.equals(TEST_ON_CANCELLISTENER)) {
+            testOnCancelListener();
+        }
+    }
+
+    private void testOnCancelListener() {
+        mCancelCalled = false;
+        mSearchManager.setOnCancelListener(new SearchManager.OnCancelListener() {
+            @Override
+            public void onCancel() {
+               mCancelCalled = true;
+            }
+        });
+
+        new TestStepHandler() {
+            @Override
+            public boolean doStep(int step) throws FailException {
+                switch (step) {
+                    case 1:
+                        startSearch("test", false, mComponentName, null, false);
+                        return false;
+                    case 2:
+                        assertFalse("cancel called", mCancelCalled);
+                        stopSearch();
+                        return false;
+                    case 3:
+                        assertTrue("cancel not called", mCancelCalled);
+                        pass();
+                        return true;
+                    default:
+                        throw new IllegalArgumentException("Bad step " + step);
+                }
+            }
+        }.start();
+    }
+
+    private void testOnDismissListener() {
+        mDismissCalled = false;
+
+        mSearchManager.setOnDismissListener(new SearchManager.OnDismissListener() {
+            public void onDismiss() {
+                mDismissCalled = true;
+            }
+        });
+
+        new TestStepHandler() {
+            @Override
+            public boolean doStep(int step) throws FailException {
+                switch (step) {
+                    case 1:
+                        startSearch("test", false, mComponentName, null, false);
+                        return false;
+                    case 2:
+                        if (mDismissCalled) {
+                            throw new FailException("dismiss called");
+                        } else {
+                            stopSearch();
+                        }
+                        return false;
+                    case 3:
+                        if (mDismissCalled) {
+                            pass();
+                        } else {
+                            throw new FailException("dismiss not called");
+                        }
+                        return true;
+                    default:
+                        throw new IllegalArgumentException("Bad step " + step);
+                }
+            }
+        }.start();
+    }
+
+    private void testStopSearch() {
+        new TestStepHandler() {
+            @Override
+            public boolean doStep(int step) throws FailException {
+                switch (step) {
+                    case 1:
+                        startSearch("test", false, mComponentName, null, false);
+                        return false;
+                    case 2:
+                        assertVisible();
+                        stopSearch();
+                        return false;
+                    case 3:
+                        assertInVisible();
+                        pass();
+                        return true;
+                    default:
+                        throw new IllegalArgumentException("Bad step " + step);
+                }
+            }
+        }.start();
+    }
+
+    private void fail(Exception ex) {
+        Log.e(TAG, "test failed", ex);
+        sCTSResult.setResult(CTSResult.RESULT_FAIL);
+        finish();
+    }
+
+    private void pass() {
+        sCTSResult.setResult(CTSResult.RESULT_OK);
+        finish();
+    }
+
+    private void assertInVisible() throws FailException {
+        if (isVisible()) {
+            throw new FailException();
+        }
+    }
+
+    private void assertVisible() throws FailException {
+        if (!isVisible()) {
+            throw new FailException();
+        }
+    }
+
+    private void assertFalse(String message, boolean value) throws FailException {
+        assertTrue(message, !value);
+    }
+
+    private void assertTrue(String message, boolean value) throws FailException {
+        if (!value) {
+            throw new FailException(message);
+        }
+    }
+
+    private void startSearch(String initialQuery, boolean selectInitialQuery,
+            ComponentName launchActivity, Bundle appSearchData, boolean globalSearch) {
+        mSearchManager.startSearch(initialQuery, selectInitialQuery, launchActivity, appSearchData,
+                globalSearch);
+    }
+
+    private void stopSearch() {
+       mSearchManager.stopSearch();
+    }
+
+    private boolean isVisible() {
+        return mSearchManager.isVisible();
+    }
+
+    private abstract class TestStepHandler extends Handler {
+
+        public void start() {
+            sendEmptyMessage(1);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            try {
+                if (!doStep(msg.what)) {
+                    sendEmptyMessage(msg.what + 1);
+                }
+            } catch (FailException ex) {
+                fail(ex);
+            }
+        }
+
+        /**
+         * Performs one step of the test.
+         *
+         * @param step The 1-based number of the step to perform.
+         * @return {@code true} if this was the last step.
+         * @throws FailException If the test failed.
+         */
+        protected abstract boolean doStep(int step) throws FailException;
+    }
+
+    private static class FailException extends Exception {
+        private static final long serialVersionUID = 1L;
+
+        public FailException() {
+            super();
+        }
+
+        public FailException(String detailMessage) {
+            super(detailMessage);
+        }
+    }
+}
diff --git a/tests/app/app/src/android/app/stubs/StubRemoteService.java b/tests/app/app/src/android/app/stubs/StubRemoteService.java
new file mode 100644
index 0000000..4fde60b
--- /dev/null
+++ b/tests/app/app/src/android/app/stubs/StubRemoteService.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.stubs;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.IBinder;
+import android.os.Process;
+
+public class StubRemoteService extends Service{
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        android.util.Log.d("Process test stub", "StubRemoteServiceProcessPid:" + Process.myPid());
+    }
+
+    private final ISecondary.Stub mSecondaryBinder = new ISecondary.Stub() {
+        public int getPid() {
+            return Process.myPid();
+        }
+
+        public long getElapsedCpuTime() {
+            return Process.getElapsedCpuTime();
+        }
+
+        public String getTimeZoneID() {
+            return java.util.TimeZone.getDefault().getID();
+        }
+    };
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        if (ISecondary.class.getName().equals(intent.getAction())) {
+            return mSecondaryBinder;
+        }
+        return null;
+    }
+
+}
diff --git a/tests/app/app/src/android/app/stubs/TestDialog.java b/tests/app/app/src/android/app/stubs/TestDialog.java
new file mode 100644
index 0000000..e404e65
--- /dev/null
+++ b/tests/app/app/src/android/app/stubs/TestDialog.java
@@ -0,0 +1,320 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.stubs;
+
+import android.app.Dialog;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.ContextMenu;
+import android.view.KeyEvent;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.Window;
+import android.view.ContextMenu.ContextMenuInfo;
+import android.view.WindowManager.LayoutParams;
+
+public class TestDialog extends Dialog {
+    private static final int OPTIONS_MENU_ITEM_0 = Menu.FIRST;
+    private static final int OPTIONS_MENU_ITEM_1 = Menu.FIRST + 1;
+    private static final int OPTIONS_MENU_ITEM_2 = Menu.FIRST + 2;
+    private static final int OPTIONS_MENU_ITEM_3 = Menu.FIRST + 3;
+    private static final int OPTIONS_MENU_ITEM_4 = Menu.FIRST + 4;
+    private static final int OPTIONS_MENU_ITEM_5 = Menu.FIRST + 5;
+    private static final int OPTIONS_MENU_ITEM_6 = Menu.FIRST + 6;
+    private static final int CONTEXT_MENU_ITEM_0 = Menu.FIRST + 7;
+    private static final int CONTEXT_MENU_ITEM_1 = Menu.FIRST + 8;
+    private static final int CONTEXT_MENU_ITEM_2 = Menu.FIRST + 9;
+    public boolean isOnStartCalled;
+    public boolean isOnStopCalled;
+    public boolean isOnCreateCalled;
+    public boolean isRequestWindowFeature;
+    public boolean isOnContentChangedCalled;
+    public boolean isOnWindowFocusChangedCalled;
+    public boolean isOnTouchEventCalled;
+    public boolean isOnTrackballEventCalled;
+    public boolean isOnKeyDownCalled;
+    public boolean isOnKeyUpCalled;
+    public boolean isOnKeyMultipleCalled;
+    public boolean isOnSaveInstanceStateCalled;
+    public static boolean isOnRestoreInstanceStateCalled;
+    public boolean isOnWindowAttributesChangedCalled;
+    public boolean isOnCreatePanelMenuCalled;
+    public boolean isOnCreatePanelViewCalled;
+    public boolean isOnPreparePanelCalled;
+    public boolean isOnMenuOpenedCalled;
+    public boolean isOnMenuItemSelectedCalled;
+    public boolean isOnPanelClosedCalled;
+    public boolean isOnCreateOptionsMenuCalled;
+    public boolean isOnPrepareOptionsMenuCalled;
+    public boolean isOnOptionsItemSelectedCalled;
+    public boolean isOnOptionsMenuClosedCalled;
+    public boolean isOnContextItemSelectedCalled;
+    public boolean isOnContextMenuClosedCalled;
+    public boolean isOnCreateContextMenuCalled;
+    public boolean isOnSearchRequestedCalled;
+    public boolean onKeyDownReturn;
+    public boolean onKeyMultipleReturn;
+    public boolean dispatchTouchEventResult;
+    public boolean dispatchKeyEventResult;
+    public int keyDownCode = -1;
+    public Window window;
+    public Bundle saveInstanceState;
+    public Bundle savedInstanceState;
+    public KeyEvent keyEvent;
+    public MotionEvent touchEvent;
+    public MotionEvent trackballEvent;
+    public MotionEvent onTrackballEvent;
+    public MotionEvent onTouchEvent;
+    public KeyEvent keyMultipleEvent;
+
+    public TestDialog(Context context) {
+        super(context);
+    }
+
+    public TestDialog(Context context, int theme) {
+        super(context, theme);
+    }
+
+    public TestDialog(Context context, boolean cancelable, OnCancelListener cancelListener) {
+        super(context, cancelable, cancelListener);
+    }
+
+    @Override
+    protected void onStart() {
+        super.onStart();
+        isOnStartCalled = true;
+    }
+
+    @Override
+    protected void onStop() {
+        super.onStop();
+        isOnStopCalled = true;
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        isRequestWindowFeature = requestWindowFeature(Window.FEATURE_LEFT_ICON);
+        super.onCreate(savedInstanceState);
+        isOnCreateCalled = true;
+    }
+
+    @Override
+    public void onContentChanged() {
+        super.onContentChanged();
+
+        isOnContentChangedCalled = true;
+    }
+
+    @Override
+    public void onWindowFocusChanged(boolean hasFocus) {
+        super.onWindowFocusChanged(hasFocus);
+
+        isOnWindowFocusChangedCalled = true;
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent event) {
+        isOnTouchEventCalled = true;
+        onTouchEvent = event;
+        return super.onTouchEvent(event);
+    }
+
+    @Override
+    public boolean onTrackballEvent(MotionEvent event) {
+        isOnTrackballEventCalled = true;
+        onTrackballEvent = event;
+        return super.onTrackballEvent(event);
+    }
+
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        isOnKeyDownCalled = true;
+        keyDownCode = keyCode;
+        onKeyDownReturn = super.onKeyDown(keyCode, event);
+
+        return onKeyDownReturn;
+    }
+
+    @Override
+    public boolean onKeyUp(int keyCode, KeyEvent event) {
+        isOnKeyUpCalled = true;
+
+        return super.onKeyUp(keyCode, event);
+    }
+
+    @Override
+    public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) {
+        isOnKeyMultipleCalled = true;
+        onKeyMultipleReturn = super.onKeyMultiple(keyCode, repeatCount, event);
+        keyMultipleEvent = event;
+        return onKeyMultipleReturn;
+    }
+
+    @Override
+    public Bundle onSaveInstanceState() {
+        isOnSaveInstanceStateCalled = true;
+        saveInstanceState = super.onSaveInstanceState();
+        return saveInstanceState;
+    }
+
+    @Override
+    public void onRestoreInstanceState(Bundle savedInstanceState) {
+        isOnRestoreInstanceStateCalled = true;
+        this.savedInstanceState = savedInstanceState;
+
+        super.onRestoreInstanceState(savedInstanceState);
+    }
+
+    @Override
+    public void onWindowAttributesChanged(LayoutParams params) {
+        isOnWindowAttributesChangedCalled = true;
+        super.onWindowAttributesChanged(params);
+    }
+
+    @Override
+    public boolean onCreatePanelMenu(int featureId, Menu menu) {
+        isOnCreatePanelMenuCalled = true;
+        return super.onCreatePanelMenu(featureId, menu);
+    }
+
+    @Override
+    public View onCreatePanelView(int featureId) {
+        isOnCreatePanelViewCalled = true;
+        return super.onCreatePanelView(featureId);
+    }
+
+    @Override
+    public boolean onPreparePanel(int featureId, View view, Menu menu) {
+        isOnPreparePanelCalled = true;
+        return super.onPreparePanel(featureId, view, menu);
+    }
+
+    @Override
+    public boolean onMenuItemSelected(int featureId, MenuItem item) {
+        isOnMenuItemSelectedCalled = true;
+        return super.onMenuItemSelected(featureId, item);
+    }
+
+    @Override
+    public boolean onMenuOpened(int featureId, Menu menu) {
+        isOnMenuOpenedCalled = true;
+        return super.onMenuOpened(featureId, menu);
+    }
+
+    @Override
+    public void onPanelClosed(int featureId, Menu menu) {
+        isOnPanelClosedCalled = true;
+        super.onPanelClosed(featureId, menu);
+    }
+
+    @Override
+    public boolean onPrepareOptionsMenu(Menu menu) {
+        isOnPrepareOptionsMenuCalled = true;
+        return super.onPrepareOptionsMenu(menu);
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        super.onCreateOptionsMenu(menu);
+        menu.add(0, OPTIONS_MENU_ITEM_0, 0, "OptionsMenuItem0");
+        menu.add(0, OPTIONS_MENU_ITEM_1, 0, "OptionsMenuItem1");
+        menu.add(0, OPTIONS_MENU_ITEM_2, 0, "OptionsMenuItem2");
+        menu.add(0, OPTIONS_MENU_ITEM_3, 0, "OptionsMenuItem3");
+        menu.add(0, OPTIONS_MENU_ITEM_4, 0, "OptionsMenuItem4");
+        menu.add(0, OPTIONS_MENU_ITEM_5, 0, "OptionsMenuItem5");
+        menu.add(0, OPTIONS_MENU_ITEM_6, 0, "OptionsMenuItem6");
+        isOnCreateOptionsMenuCalled = true;
+        return true;
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        isOnOptionsItemSelectedCalled = true;
+        switch (item.getItemId()) {
+            case OPTIONS_MENU_ITEM_0:
+            case OPTIONS_MENU_ITEM_1:
+            case OPTIONS_MENU_ITEM_2:
+            case OPTIONS_MENU_ITEM_3:
+            case OPTIONS_MENU_ITEM_4:
+            case OPTIONS_MENU_ITEM_5:
+            case OPTIONS_MENU_ITEM_6:
+                return true;
+            default:
+                return super.onOptionsItemSelected(item);
+        }
+    }
+
+    @Override
+    public void onOptionsMenuClosed(Menu menu) {
+        isOnOptionsMenuClosedCalled = true;
+        super.onOptionsMenuClosed(menu);
+    }
+
+    @Override
+    public boolean onContextItemSelected(MenuItem item) {
+        isOnContextItemSelectedCalled = true;
+        switch (item.getItemId()) {
+            case CONTEXT_MENU_ITEM_0:
+            case CONTEXT_MENU_ITEM_1:
+            case CONTEXT_MENU_ITEM_2:
+                return true;
+            default:
+                return super.onContextItemSelected(item);
+        }
+    }
+
+    @Override
+    public void onContextMenuClosed(Menu menu) {
+        isOnContextMenuClosedCalled = true;
+        super.onContextMenuClosed(menu);
+    }
+
+    @Override
+    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
+        menu.add(0, CONTEXT_MENU_ITEM_0, 0, "ContextMenuItem0");
+        menu.add(0, CONTEXT_MENU_ITEM_1, 0, "ContextMenuItem1");
+        menu.add(0, CONTEXT_MENU_ITEM_2, 0, "ContextMenuItem2");
+        isOnCreateContextMenuCalled = true;
+    }
+
+    @Override
+    public boolean onSearchRequested() {
+        isOnSearchRequestedCalled = true;
+        return super.onSearchRequested();
+    }
+
+    @Override
+    public boolean dispatchKeyEvent(KeyEvent event) {
+        keyEvent = event;
+        dispatchKeyEventResult = super.dispatchKeyEvent(event);
+        return dispatchKeyEventResult;
+    }
+
+    @Override
+    public boolean dispatchTrackballEvent(MotionEvent ev) {
+        trackballEvent = ev;
+        return super.dispatchTrackballEvent(ev);
+    }
+
+    @Override
+    public boolean dispatchTouchEvent(MotionEvent ev) {
+        touchEvent = ev;
+        dispatchTouchEventResult = super.dispatchTouchEvent(ev);
+        return dispatchTouchEventResult;
+    }
+}
diff --git a/tests/app/app/src/android/app/stubs/TestedActivity.java b/tests/app/app/src/android/app/stubs/TestedActivity.java
new file mode 100644
index 0000000..fb90055
--- /dev/null
+++ b/tests/app/app/src/android/app/stubs/TestedActivity.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.stubs;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.os.Looper;
+import android.os.MessageQueue;
+import android.util.Log;
+
+public class TestedActivity extends Activity {
+    private static final String TAG = "TestedActivity" ;
+    public TestedActivity() {
+    }
+
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+    }
+
+    protected void onRestoreInstanceState(Bundle state) {
+        super.onRestoreInstanceState(state);
+    }
+
+    protected void onResume() {
+        super.onResume();
+        Looper.myLooper();
+        Looper.myQueue().addIdleHandler(new Idler());
+    }
+
+    protected void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+    }
+
+    protected void onStop() {
+        super.onStop();
+    }
+
+    private class Idler implements MessageQueue.IdleHandler {
+        public final boolean queueIdle() {
+            Log.i(TAG, "idle");
+            setResult(RESULT_OK);
+            finish();
+            return false;
+        }
+    }
+}
diff --git a/tests/app/app/src/android/app/stubs/TestedScreen.java b/tests/app/app/src/android/app/stubs/TestedScreen.java
new file mode 100644
index 0000000..1b707e7
--- /dev/null
+++ b/tests/app/app/src/android/app/stubs/TestedScreen.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.stubs;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.MessageQueue;
+import android.os.SystemClock;
+import android.util.Log;
+
+public class TestedScreen extends Activity {
+    public static final String WAIT_BEFORE_FINISH = "TestedScreen.WAIT_BEFORE_FINISH";
+    public static final String DELIVER_RESULT = "TestedScreen.DELIVER_RESULT";
+    public static final String CLEAR_TASK = "TestedScreen.CLEAR_TASK";
+    private static final String TAG = "TestedScreen" ;
+    public TestedScreen() {
+    }
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        if (LaunchpadActivity.FORWARD_RESULT.equals(getIntent().getAction())) {
+            final Intent intent = new Intent(getIntent());
+            intent.setAction(DELIVER_RESULT);
+            intent.setFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
+            startActivity(intent);
+            finish();
+        } else if (DELIVER_RESULT.equals(getIntent().getAction())) {
+            setResult(RESULT_OK, new Intent().setAction(LaunchpadActivity.RETURNED_RESULT));
+            finish();
+        } else if (CLEAR_TASK.equals(getIntent().getAction())) {
+            if (!getIntent().getBooleanExtra(ClearTop.WAIT_CLEAR_TASK, false)) {
+                launchClearTask();
+            }
+        }
+    }
+
+    @Override
+    protected void onRestoreInstanceState(Bundle state) {
+        super.onRestoreInstanceState(state);
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        if (CLEAR_TASK.equals(getIntent().getAction())) {
+            if (getIntent().getBooleanExtra(ClearTop.WAIT_CLEAR_TASK, false)) {
+                Looper.myLooper();
+                Looper.myQueue().addIdleHandler(new Idler());
+            }
+        } else {
+            Looper.myLooper();
+            Looper.myQueue().addIdleHandler(new Idler());
+        }
+    }
+
+    @Override
+    protected void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+    }
+
+    @Override
+    protected void onStop() {
+        super.onStop();
+    }
+
+    private void launchClearTask() {
+        final Intent intent = new Intent(getIntent()).addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
+                .setClass(this, ClearTop.class);
+        startActivity(intent);
+    }
+
+    private final Handler mHandler = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            if (CLEAR_TASK.equals(getIntent().getAction())) {
+                launchClearTask();
+            } else {
+                setResult(RESULT_OK);
+                finish();
+            }
+        }
+    };
+
+    private class Idler implements MessageQueue.IdleHandler {
+        public final boolean queueIdle() {
+            Log.i(TAG, "idle");
+            if (WAIT_BEFORE_FINISH.equals(getIntent().getAction())) {
+                final Message m = Message.obtain();
+                mHandler.sendMessageAtTime(m, SystemClock.uptimeMillis() + 1000);
+            } else if (CLEAR_TASK.equals(getIntent().getAction())) {
+                final Message m = Message.obtain();
+                mHandler.sendMessageAtTime(m, SystemClock.uptimeMillis() + 1000);
+            } else {
+                setResult(RESULT_OK);
+                finish();
+            }
+            return false;
+        }
+    }
+}
diff --git a/tests/app/res/layout/alert_dialog_text_entry_2.xml b/tests/app/res/layout/alert_dialog_text_entry_2.xml
deleted file mode 100644
index 848b342..0000000
--- a/tests/app/res/layout/alert_dialog_text_entry_2.xml
+++ /dev/null
@@ -1,42 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:orientation="vertical">
-
-    <TextView
-        android:id="@+id/username_view"
-        android:layout_height="wrap_content"
-        android:layout_width="wrap_content"
-        android:layout_marginLeft="20dip"
-        android:layout_marginRight="20dip"
-        android:text="@string/alert_dialog_username"
-        android:gravity="left" />
-
-    <EditText
-        android:id="@+id/username_edit"
-        android:layout_height="wrap_content"
-        android:layout_width="match_parent"
-        android:layout_marginLeft="20dip"
-        android:layout_marginRight="20dip"
-        android:scrollHorizontally="true"
-        android:autoText="false"
-        android:capitalize="none"
-        android:gravity="fill_horizontal" />
-
-</LinearLayout>
diff --git a/tests/app/res/values/strings.xml b/tests/app/res/values/strings.xml
deleted file mode 100644
index c167278..0000000
--- a/tests/app/res/values/strings.xml
+++ /dev/null
@@ -1,179 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="permlab_testGranted">Test Granted</string>
-    <string name="permdesc_testGranted">Used for running CTS tests, for testing operations
-        where we have the permission.</string>
-    <string name="permlab_testDynamic">Test Dynamic</string>
-    <string name="permdesc_testDynamic">Used for running CTS tests, for testing adding
-        dynamic permissions.</string>
-    <string name="permlab_testDenied">Test Denied</string>
-    <string name="permdesc_testDenied">Used for running CTS tests, for testing operations
-        where we do not have the permission.</string>
-    <string name="explain">1. click start. \n2. if above image shaked, then press pass button,
-         else press failed button.</string>
-    <string name="text_view_hello">Hello! Text view!</string>
-    <string name="text_view_hello_two_lines">Hello! \nText view!</string>
-    <string name="text_view_simple_hint">This is a hint.</string>
-    <string name="text_view_hint">This is a string for testing hint of textview.</string>
-    <string name="activity_forwarding">App/Forwarding</string>
-    <string name="forwarding">$$$</string>
-    <string name="go">Go</string>
-    <string name="back">Back</string>
-    <string name="forward_target">
-        Press back button and notice we don\'t see the previous activity.
-    </string>
-    <string name="edit_text">testing</string>
-    <string name="text">DialogTest</string>
-    <string name="text_country">Country</string>
-    <string name="text_name">Name</string>
-    <string name="hello_world">Hello, World!</string>
-    <string name="hello_android">Hello, Android!</string>
-    <string name="alert_dialog_username">Name:</string>
-    <string name="alert_dialog_password">Password:</string>
-    <string name="alert_dialog_positive">Positive</string>
-    <string name="alert_dialog_negative">Negative</string>
-    <string name="alert_dialog_neutral">Neutral</string>
-    <string name="notify">Notify </string>
-    <string name="tabs_1">testing</string>
-    <string name="table_layout_first">first</string>
-    <string name="table_layout_second">second</string>
-    <string name="table_layout_third">third</string>
-    <string name="table_layout_long">Very long to make the string out of the screen</string>
-    <string name="chronometer_text">Test Chronometer</string>
-    <string name="am">AM</string>
-    <string name="pm">PM</string>
-    <string name="viewgroup_test">ViewGroup test</string>
-    <string name="viewanimator_test">ViewAnimator test</string>
-    <string name="id_ok">OK</string>
-    <string name="id_cancel">Cancel</string>
-    <string name="context_test_string1">This is %s string.</string>
-    <string name="context_test_string2">This is test string.</string>
-    <string name="animationutils_test_instructions">Choose different animations</string>
-    <string name="animationutils_test_alpha">Alpha animation</string>
-    <string name="animationutils_test_scale">Scale animation</string>
-    <string name="animationutils_test_rotate">Rotate animation</string>
-    <string name="animationutils_test_translate">Translate animation</string>
-    <string name="animationutils_test_set">Animation set</string>
-    <string name="animationutils_test_layout">Layout animation</string>
-    <string name="animationutils_test_gridlayout">Grid layout animation</string>
-    <string name="twolinelistitem_test_text1">text1</string>
-    <string name="twolinelistitem_test_text2">text2</string>
-    <string name="metadata_text">metadata text</string>
-    <string name="horizontal_text_1">horizontal 1</string>
-    <string name="horizontal_text_2">horizontal 2</string>
-    <string name="horizontal_text_3">horizontal 3</string>
-    <string name="vertical_text_1">vertical 1</string>
-    <string name="vertical_text_2">vertical 2</string>
-    <string name="vertical_text_3">vertical 3</string>
-    <string name="reference">here</string>
-    <string name="coerceIntegerToString">100</string>
-    <string name="coerceBooleanToString">true</string>
-    <string name="coerceColorToString">#fff</string>
-    <string name="coerceFloatToString">100.0</string>
-    <string name="coerceDimensionToString">100px</string>
-    <string name="coerceFractionToString">100<xliff:g id="percent">%</xliff:g></string>
-    <string name="formattedStringNone">Format[]</string>
-    <string name="formattedStringOne">Format[<xliff:g id="format">%d</xliff:g>]</string>
-    <string name="formattedStringTwo">Format[<xliff:g id="format">%3$d,%2$s</xliff:g>]</string>
-    <string name="checkboxpref_key">checkboxpref_key</string>
-   <string name="checkboxpref_title">title of preference</string>
-   <string name="checkboxpref_summary">summary of preference</string>
-   <string name="checkboxpref_summary_on">summary on of preference</string>
-   <string name="checkboxpref_summary_off">summary off of preference</string>
-   <string name="checkboxpref_depend">checkboxpref_depend</string>
-   <string name="checkboxpref_depend_title"> depend title of preference</string>
-   <string name="checkboxpref_depend_summary"> depend summary of preference</string>
-   <string name="edittextpref_key">edittextpref_key</string>
-   <string name="edittextpref_default_value">default value of preference</string>
-   <string name="edittextpref_title">title of edit text preference</string>
-   <string name="edittextpref_summary">summary of edit text preference</string>
-   <string name="edittextpref_dialog_title">dialog title of edit text preference</string>
-   <string name="edittextpref_text">text of  edit text preference</string>
-   <string name="listpref_key">listpref_key</string>
-   <string name="listpref_title">title of list preference</string>
-   <string name="listpref_summary">summary of list preference</string>
-   <string name="listpref_dialogtitle">dialog title of list preference</string>
-   <string name="easy">Easy</string>
-   <string name="medium">Medium</string>
-   <string name="hard">Hard</string>
-   <string name="footer_view">Footer view</string>
-   <string name="header_view">Header view</string>
-   <string name="dialogpref_title">title of dialog preference </string>
-   <string name="dialogpref_dialog_title">dialog title of dialog preference </string>
-   <string name="dialogpref_key">dialogpref_key</string>
-   <string name="dialogpref_default_value">default value of dialog preference</string>
-   <string name="dialogpref_summary">summary of dialog preference</string>
-   <string name="dialogpref_message">message of dialog preference</string>
-   <string name="dialogpref_sure">Sure</string>
-   <string name="dialogpref_cancel">Cancel</string>
-   <string name="pref_key">pref_key</string>
-   <string name="pref_title">title of preference</string>
-   <string name="pref_summary">summary of preference</string>
-   <string name="pref_depend_key">pref_depend_key</string>
-   <string name="pref_depend_title"> depend title of preference</string>
-   <string name="pref_depend_summary"> depend summary of preference</string>
-   <string name="android_intent_action_preference">android.intent.action.PREFERENCE</string>
-   <string name="def_pref_key">def_pref_key</string>
-   <string name="def_pref_title">default preference</string>
-   <string name="def_pref_summary">This is default preference of cts</string>
-   <string name="relative_view1">view 1</string>
-   <string name="relative_view2">view 2</string>
-   <string name="relative_view3">view 3</string>
-   <string name="relative_view4">view 4</string>
-   <string name="relative_view5">view 5</string>
-   <string name="relative_view6">view 6</string>
-   <string name="relative_view7">view 7</string>
-   <string name="relative_view8">view 8</string>
-   <string name="relative_view9">view 9</string>
-   <string name="relative_view10">view 10</string>
-   <string name="relative_view11">view 11</string>
-   <string name="relative_view12">view 12</string>
-   <string name="relative_view13">view 13</string>
-   <string name="country">Country:</string>
-   <string name="symbol">Symbol:</string>
-   <string name="country_warning">No such country registered</string>
-   <string name="version_cur">base</string>
-   <string name="version_old">base</string>
-   <string name="version_v3">base</string>
-   <string name="authenticator_label">Android CTS</string>
-   <string name="search_label">Android CTS</string>
-   <string name="tag1">tag 1</string>
-   <string name="tag2">tag 2</string>
-
-   <string name="button">Button</string>
-   <string name="holo_test">Holo Test</string>
-   <string name="holo_generator">Holo Generator</string>
-   <string name="holo_light_test">Holo Light Test</string>
-   <string name="holo_light_generator">Holo Light Generator</string>
-   <string name="reference_image">Reference Image: </string>
-   <string name="generated_image">Generated Image: </string>
-   <string name="themes_prompt">Select a Theme:</string>
-   <string name="sample_text">Sample text goes here. I wanted something creative and whimsical
-but then I just got bored...</string>
-    <string name="long_text">This is a really long string which exceeds the width of the view.
-New devices have a much larger screen which actually enables long strings to be displayed
-with no fading. I have made this string longer to fix this case. If you are correcting this
-text, I would love to see the kind of devices you guys now use! Guys, maybe some devices need longer string!
-I think so, so how about double this string, like copy and paste!
-This is a really long string which exceeds the width of the view.
-New devices have a much larger screen which actually enables long strings to be displayed
-with no fading. I have made this string longer to fix this case. If you are correcting this
-text, I would love to see the kind of devices you guys now use! Guys, maybe some devices need longer string!
-I think so, so how about double this string, like copy and paste! </string>
-    <string name="rectangle200">"M 0,0 l 200,0 l 0, 200 l -200, 0 z"</string>
-</resources>
diff --git a/tests/app/res/values/styles.xml b/tests/app/res/values/styles.xml
deleted file mode 100644
index 81925cc..0000000
--- a/tests/app/res/values/styles.xml
+++ /dev/null
@@ -1,172 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android">
-
-    <style name="Whatever">
-        <item name="type1">true</item>
-        <item name="type2">false</item>
-        <item name="type3">#ff0000ff</item>
-        <item name="type4">#ff00ff00</item>
-        <item name="type5">0.75px</item>
-        <item name="type6">10px</item>
-        <item name="type7">18px</item>
-        <item name="type8">@drawable/pass</item>
-        <item name="type9">3.14</item>
-        <item name="type10">100%</item>
-        <item name="type11">365</item>
-        <item name="type12">86400</item>
-        <item name="type13">@string/hello_android</item>
-        <item name="type14">TypedArray Test!</item>
-        <item name="type15">@array/difficultyLevel</item>
-        <item name="type16">Typed Value!</item>
-    </style>
-
-    <style name="TextViewWithoutColorAndAppearance">
-        <item name="android:textSize">18sp</item>
-    </style>
-
-    <style name="TextViewWithColorButWithOutAppearance">
-        <item name="android:textColor">#ff0000ff</item>
-    </style>
-
-    <style name="TextViewWithColorAndAppearance">
-        <item name="android:textColor">#ff0000ff</item>
-        <item name="android:textAppearance">@style/TextAppearance.WithColor</item>
-    </style>
-
-    <style name="TextViewWithoutColorButWithAppearance">
-        <item name="android:textAppearance">@style/TextAppearance.WithColor</item>
-    </style>
-
-    <style name="TextAppearance" parent="android:TextAppearance">
-    </style>
-
-    <style name="TextAppearance.WithColor">
-        <item name="android:textColor">#ffff0000</item>
-    </style>
-
-    <style name="TextAppearance.All">
-        <item name="android:textColor">@drawable/black</item>
-        <item name="android:textSize">20px</item>
-        <item name="android:textStyle">bold</item>
-        <item name="android:textColorHint">@drawable/red</item>
-        <item name="android:textColorLink">@drawable/blue</item>
-        <item name="android:textColorHighlight">@drawable/yellow</item>
-    </style>
-
-    <style name="TextAppearance.Colors">
-        <item name="android:textColor">@drawable/black</item>
-        <item name="android:textColorHint">@drawable/blue</item>
-        <item name="android:textColorLink">@drawable/yellow</item>
-        <item name="android:textColorHighlight">@drawable/red</item>
-    </style>
-
-    <style name="TextAppearance.NotColors">
-        <item name="android:textSize">17px</item>
-        <item name="android:typeface">sans</item>
-        <item name="android:textStyle">normal</item>
-    </style>
-
-    <style name="TextAppearance.Style">
-        <item name="android:textStyle">normal</item>
-    </style>
-
-    <style name="TestEnum1">
-        <item name="testEnum">val1</item>
-    </style>
-
-    <style name="TestEnum2">
-        <item name="testEnum">val2</item>
-    </style>
-
-    <style name="TestEnum10">
-        <item name="testEnum">val10</item>
-    </style>
-
-    <style name="TestFlag1">
-        <item name="testFlags">bit1</item>
-    </style>
-
-    <style name="TestFlag2">
-        <item name="testFlags">bit2</item>
-    </style>
-
-    <style name="TestFlag31">
-        <item name="testFlags">bit31</item>
-    </style>
-
-    <style name="TestFlag1And2">
-        <item name="testFlags">bit1|bit2</item>
-    </style>
-
-    <style name="TestFlag1And2And31">
-        <item name="testFlags">bit1|bit2|bit31</item>
-    </style>
-
-    <style name="TestEnum1.EmptyInherit" />
-
-    <style name="Theme_AlertDialog">
-        <item name="android:textSize">18sp</item>
-    </style>
-
-    <style name="TestProgressBar">
-        <item name="android:indeterminateOnly">false</item>
-        <item name="android:progressDrawable">?android:drawable/progress_horizontal</item>
-        <item name="android:indeterminateDrawable">?android:drawable/progress_horizontal</item>
-        <item name="android:minHeight">20dip</item>
-        <item name="android:maxHeight">20dip</item>
-        <item name="android:focusable">true</item>
-    </style>
-
-    <style name="Test_Theme">
-        <item name="android:windowNoTitle">true</item>
-        <item name="android:panelColorForeground">#ff000000</item>
-        <item name="android:panelColorBackground">#ffffffff</item>
-    </style>
-
-    <style name="Theme_OverrideOuter">
-        <item name="themeType">1</item>
-    </style>
-
-    <style name="Theme_OverrideInner">
-        <item name="themeType">2</item>
-        <item name="themeOverrideAttr">@style/Theme_OverrideAttr</item>
-    </style>
-
-    <style name="Theme_OverrideAttr">
-        <item name="themeType">3</item>
-    </style>
-
-    <style name="Theme_ThemedDrawableTest">
-        <item name="themeBoolean">true</item>
-        <item name="themeColor">@android:color/black</item>
-        <item name="themeFloat">1.0</item>
-        <item name="themeAngle">45.0</item>
-        <item name="themeInteger">1</item>
-        <item name="themeDimension">1px</item>
-        <item name="themeDrawable">@drawable/icon_black</item>
-        <item name="themeBitmap">@drawable/icon_black</item>
-        <item name="themeNinePatch">@drawable/ninepatch_0</item>
-        <item name="themeGravity">48</item>
-        <item name="themeTileMode">2</item>
-    </style>
-
-    <style name="Theme_NoSwipeDismiss">
-        <item name="android:windowSwipeToDismiss">false</item>
-    </style>
-
-</resources>
diff --git a/tests/app/res/xml/alias.xml b/tests/app/res/xml/alias.xml
deleted file mode 100644
index 321e536..0000000
--- a/tests/app/res/xml/alias.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
--->
-
-<alias xmlns:android="http://schemas.android.com/apk/res/android">
-    <intent android:action="android.intent.action.MAIN"
-        android:targetPackage="com.android.cts.app.stub"
-        android:targetClass="android.app.cts.ChildActivity"
-        android:data="http://www.google.com/">
-    </intent>
-</alias>
-
diff --git a/tests/tests/app/src/android/app/backup/cts/BackupAgentHelperTest.java b/tests/app/src/android/app/backup/cts/BackupAgentHelperTest.java
similarity index 100%
rename from tests/tests/app/src/android/app/backup/cts/BackupAgentHelperTest.java
rename to tests/app/src/android/app/backup/cts/BackupAgentHelperTest.java
diff --git a/tests/tests/app/src/android/app/backup/cts/BackupAgentTest.java b/tests/app/src/android/app/backup/cts/BackupAgentTest.java
similarity index 100%
rename from tests/tests/app/src/android/app/backup/cts/BackupAgentTest.java
rename to tests/app/src/android/app/backup/cts/BackupAgentTest.java
diff --git a/tests/app/src/android/app/backup/cts/BackupManagerTest.java b/tests/app/src/android/app/backup/cts/BackupManagerTest.java
new file mode 100644
index 0000000..510e8d1
--- /dev/null
+++ b/tests/app/src/android/app/backup/cts/BackupManagerTest.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.backup.cts;
+
+import android.app.backup.BackupManager;
+import android.app.backup.RestoreObserver;
+import android.test.AndroidTestCase;
+
+public class BackupManagerTest extends AndroidTestCase {
+
+    public void testBackupManager() throws Exception {
+        // Check that these don't crash as if they were called in an app...
+        BackupManager backupManager = new BackupManager(mContext);
+        backupManager.dataChanged();
+        BackupManager.dataChanged("android.app.stubs");
+
+        // Backup isn't expected to work in this test but check for obvious bugs...
+        int result = backupManager.requestRestore(new RestoreObserver() {});
+        assertTrue(result != 0);
+    }
+}
diff --git a/tests/tests/app/src/android/app/backup/cts/FileBackupHelperTest.java b/tests/app/src/android/app/backup/cts/FileBackupHelperTest.java
similarity index 100%
rename from tests/tests/app/src/android/app/backup/cts/FileBackupHelperTest.java
rename to tests/app/src/android/app/backup/cts/FileBackupHelperTest.java
diff --git a/tests/tests/app/src/android/app/backup/cts/SharedPreferencesBackupHelperTest.java b/tests/app/src/android/app/backup/cts/SharedPreferencesBackupHelperTest.java
similarity index 100%
rename from tests/tests/app/src/android/app/backup/cts/SharedPreferencesBackupHelperTest.java
rename to tests/app/src/android/app/backup/cts/SharedPreferencesBackupHelperTest.java
diff --git a/tests/app/src/android/app/cts/ActionBarActivity.java b/tests/app/src/android/app/cts/ActionBarActivity.java
deleted file mode 100644
index dc65cb2..0000000
--- a/tests/app/src/android/app/cts/ActionBarActivity.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-import android.app.ActionBar;
-import android.app.Activity;
-import android.os.Bundle;
-
-public class ActionBarActivity extends Activity {
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        ActionBar bar = getActionBar();
-        if (bar != null) {
-            bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
-        }
-    }
-}
diff --git a/tests/app/src/android/app/cts/ActionBarTest.java b/tests/app/src/android/app/cts/ActionBarTest.java
new file mode 100644
index 0000000..3404b57
--- /dev/null
+++ b/tests/app/src/android/app/cts/ActionBarTest.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.cts;
+
+import android.app.ActionBar;
+import android.app.ActionBar.Tab;
+import android.app.ActionBar.TabListener;
+import android.app.FragmentTransaction;
+import android.app.stubs.ActionBarActivity;
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.UiThreadTest;
+
+public class ActionBarTest extends ActivityInstrumentationTestCase2<ActionBarActivity> {
+
+    private ActionBarActivity mActivity;
+    private ActionBar mBar;
+
+    public ActionBarTest() {
+        super(ActionBarActivity.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mActivity = getActivity();
+        mBar = mActivity.getActionBar();
+    }
+
+    @UiThreadTest
+    public void testAddTab() {
+        if (mBar == null) {
+            return;
+        }
+        assertEquals(0, mBar.getTabCount());
+
+        Tab t1 = createTab("Tab 1");
+        mBar.addTab(t1);
+        assertEquals(1, mBar.getTabCount());
+        assertEquals(t1, mBar.getSelectedTab());
+        assertEquals(t1, mBar.getTabAt(0));
+
+        Tab t2 = createTab("Tab 2");
+        mBar.addTab(t2);
+        assertEquals(2, mBar.getTabCount());
+        assertEquals(t1, mBar.getSelectedTab());
+        assertEquals(t2, mBar.getTabAt(1));
+
+        Tab t3 = createTab("Tab 3");
+        mBar.addTab(t3, true);
+        assertEquals(3, mBar.getTabCount());
+        assertEquals(t3, mBar.getSelectedTab());
+        assertEquals(t3, mBar.getTabAt(2));
+
+        Tab t4 = createTab("Tab 2.5");
+        mBar.addTab(t4, 2);
+        assertEquals(4, mBar.getTabCount());
+        assertEquals(t4, mBar.getTabAt(2));
+        assertEquals(t3, mBar.getTabAt(3));
+
+        Tab t5 = createTab("Tab 0.5");
+        mBar.addTab(t5, 0, true);
+        assertEquals(5, mBar.getTabCount());
+        assertEquals(t5, mBar.getSelectedTab());
+        assertEquals(t5, mBar.getTabAt(0));
+        assertEquals(t1, mBar.getTabAt(1));
+        assertEquals(t2, mBar.getTabAt(2));
+        assertEquals(t4, mBar.getTabAt(3));
+        assertEquals(t3, mBar.getTabAt(4));
+    }
+
+    private Tab createTab(String name) {
+        return mBar.newTab().setText("Tab 1").setTabListener(new TestTabListener());
+    }
+
+    static class TestTabListener implements TabListener {
+        @Override
+        public void onTabSelected(Tab tab, FragmentTransaction ft) {
+        }
+
+        @Override
+        public void onTabUnselected(Tab tab, FragmentTransaction ft) {
+        }
+
+        @Override
+        public void onTabReselected(Tab tab, FragmentTransaction ft) {
+        }
+    }
+}
diff --git a/tests/app/src/android/app/cts/ActivityGroupTest.java b/tests/app/src/android/app/cts/ActivityGroupTest.java
new file mode 100644
index 0000000..8b76cb6
--- /dev/null
+++ b/tests/app/src/android/app/cts/ActivityGroupTest.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.cts;
+
+import android.app.stubs.ActivityTestsBase;
+import android.app.stubs.LaunchpadActivity;
+import android.app.stubs.LaunchpadTabActivity;
+import android.content.ComponentName;
+import android.content.Intent;
+
+public class ActivityGroupTest extends ActivityTestsBase {
+    private Intent mTabIntent;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mTabIntent = new Intent(mContext, LaunchpadTabActivity.class);
+        mTabIntent.putExtra("tab", new ComponentName(mContext, LaunchpadActivity.class));
+    }
+
+    public void testTabBasic() throws Exception {
+        mIntent = mTabIntent;
+        runLaunchpad(LaunchpadActivity.LIFECYCLE_BASIC);
+    }
+
+    public void testTabScreen() throws Exception {
+        mIntent = mTabIntent;
+        runLaunchpad(LaunchpadActivity.LIFECYCLE_SCREEN);
+    }
+
+    public void testTabDialog() throws Exception {
+        mIntent = mTabIntent;
+        runLaunchpad(LaunchpadActivity.LIFECYCLE_DIALOG);
+    }
+}
diff --git a/tests/app/src/android/app/cts/ActivityKeyboardShortcutsTest.java b/tests/app/src/android/app/cts/ActivityKeyboardShortcutsTest.java
new file mode 100644
index 0000000..678f12c
--- /dev/null
+++ b/tests/app/src/android/app/cts/ActivityKeyboardShortcutsTest.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.cts;
+
+import android.app.Activity;
+import android.app.stubs.KeyboardShortcutsActivity;
+import android.test.ActivityInstrumentationTestCase2;
+import android.view.KeyEvent;
+import android.view.KeyboardShortcutGroup;
+import android.view.Menu;
+import android.widget.PopupMenu;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Tests functionality in Activity related to Keyboard Shortcuts.
+ */
+public class ActivityKeyboardShortcutsTest
+        extends ActivityInstrumentationTestCase2<KeyboardShortcutsActivity> {
+
+    private Activity mActivity;
+    private Menu mMenu;
+
+    public ActivityKeyboardShortcutsTest() {
+        super(KeyboardShortcutsActivity.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mActivity = getActivity();
+        mMenu = new PopupMenu(mActivity, null).getMenu();
+    }
+
+    public void testOnProvideKeyboardShortcuts() {
+        List<KeyboardShortcutGroup> data = new ArrayList<>();
+        mActivity.onCreateOptionsMenu(mMenu);
+        mActivity.onProvideKeyboardShortcuts(data, mMenu, -1);
+
+        assertEquals(1, data.size());
+        assertEquals(1, data.get(0).getItems().size());
+        assertEquals(KeyboardShortcutsActivity.ITEM_1_NAME,
+            data.get(0).getItems().get(0).getLabel());
+        assertEquals(KeyboardShortcutsActivity.ITEM_1_SHORTCUT,
+            data.get(0).getItems().get(0).getBaseCharacter());
+        assertEquals(KeyEvent.META_CTRL_ON, data.get(0).getItems().get(0).getModifiers());
+    }
+}
diff --git a/tests/app/src/android/app/cts/ActivityManagerMemoryClassLaunchActivity.java b/tests/app/src/android/app/cts/ActivityManagerMemoryClassLaunchActivity.java
deleted file mode 100644
index f1f95b8..0000000
--- a/tests/app/src/android/app/cts/ActivityManagerMemoryClassLaunchActivity.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.os.Bundle;
-
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-/**
- * {@link Activity} that just launches {@link ActivityManagerMemoryClassTestActivity} and
- * returns the result of that activity.
- */
-public class ActivityManagerMemoryClassLaunchActivity extends Activity {
-
-    public static final String MEMORY_CLASS_EXTRA = "activityMemoryClass";
-
-    private static final int TEST_ACTIVITY_REQUEST_CODE = 1337;
-
-    private final CountDownLatch mLatch = new CountDownLatch(1);
-
-    private int mChildResult = RESULT_CANCELED;
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        // Start the activity that runs in a separate process to do the actual testing,
-        // since the test itself cannot start an activity in a separate process. A separate
-        // process is used to avoid including the overhead of the test instrumentation process.
-
-        Intent intent = getIntent();
-        int memoryClass = intent.getIntExtra(MEMORY_CLASS_EXTRA, -1);
-
-        Intent testIntent = new Intent(this, ActivityManagerMemoryClassTestActivity.class);
-        testIntent.putExtra(MEMORY_CLASS_EXTRA, memoryClass);
-        startActivityForResult(testIntent, TEST_ACTIVITY_REQUEST_CODE);
-    }
-
-    @Override
-    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
-        super.onActivityResult(requestCode, resultCode, data);
-        if (requestCode == 1337) {
-            synchronized (this) {
-                mChildResult = resultCode;
-            }
-        } else {
-            throw new IllegalStateException("Request code: " + requestCode);
-        }
-    }
-
-    public int getResult() throws InterruptedException {
-        mLatch.await(5, TimeUnit.SECONDS);
-        synchronized (this) {
-            return mChildResult;
-        }
-    }
-}
diff --git a/tests/app/src/android/app/cts/ActivityManagerMemoryClassTest.java b/tests/app/src/android/app/cts/ActivityManagerMemoryClassTest.java
new file mode 100644
index 0000000..cb331d1
--- /dev/null
+++ b/tests/app/src/android/app/cts/ActivityManagerMemoryClassTest.java
@@ -0,0 +1,192 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.cts;
+
+import android.app.Activity;
+import android.app.ActivityManager;
+import android.app.stubs.ActivityManagerMemoryClassLaunchActivity;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.res.Configuration;
+import android.test.ActivityInstrumentationTestCase2;
+import android.util.DisplayMetrics;
+import android.view.Display;
+import android.view.WindowManager;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * {@link ActivityInstrumentationTestCase2} that tests {@link ActivityManager#getMemoryClass()}
+ * by checking that the memory class matches the proper screen density and by launching an
+ * application that attempts to allocate memory on the heap.
+ */
+public class ActivityManagerMemoryClassTest
+        extends ActivityInstrumentationTestCase2<ActivityManagerMemoryClassLaunchActivity> {
+
+    public ActivityManagerMemoryClassTest() {
+        super(ActivityManagerMemoryClassLaunchActivity.class);
+    }
+
+    public static class ExpectedMemorySizesClass {
+        private static final Map<Integer, Integer> expectedMemorySizeForWatch
+            =  new HashMap<Integer, Integer>();
+        private static final Map<Integer, Integer> expectedMemorySizeForSmallNormalScreen
+            =  new HashMap<Integer, Integer>();
+        private static final Map<Integer, Integer> expectedMemorySizeForLargeScreen
+            =  new HashMap<Integer, Integer>();
+        private static final Map<Integer, Integer> expectedMemorySizeForXLargeScreen
+            =  new HashMap<Integer, Integer>();
+
+        static {
+            expectedMemorySizeForWatch.put(DisplayMetrics.DENSITY_LOW, 32);
+            expectedMemorySizeForWatch.put(DisplayMetrics.DENSITY_MEDIUM, 32);
+            expectedMemorySizeForWatch.put(DisplayMetrics.DENSITY_TV, 32);
+            expectedMemorySizeForWatch.put(DisplayMetrics.DENSITY_HIGH, 36);
+            expectedMemorySizeForWatch.put(DisplayMetrics.DENSITY_280, 36);
+            expectedMemorySizeForWatch.put(DisplayMetrics.DENSITY_XHIGH, 48);
+            expectedMemorySizeForWatch.put(DisplayMetrics.DENSITY_360, 48);
+            expectedMemorySizeForWatch.put(DisplayMetrics.DENSITY_400, 56);
+            expectedMemorySizeForWatch.put(DisplayMetrics.DENSITY_420, 64);
+            expectedMemorySizeForWatch.put(DisplayMetrics.DENSITY_XXHIGH, 88);
+            expectedMemorySizeForWatch.put(DisplayMetrics.DENSITY_560, 112);
+            expectedMemorySizeForWatch.put(DisplayMetrics.DENSITY_XXXHIGH, 154);
+        }
+
+        static {
+            expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_LOW, 32);
+            expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_MEDIUM, 32);
+            expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_TV, 48);
+            expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_HIGH, 48);
+            expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_280, 48);
+            expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_XHIGH, 80);
+            expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_360, 80);
+            expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_400, 96);
+            expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_420, 112);
+            expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_XXHIGH, 128);
+            expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_560, 192);
+            expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_XXXHIGH, 256);
+        }
+
+        static {
+            expectedMemorySizeForLargeScreen.put(DisplayMetrics.DENSITY_LOW, 32);
+            expectedMemorySizeForLargeScreen.put(DisplayMetrics.DENSITY_MEDIUM, 64);
+            expectedMemorySizeForLargeScreen.put(DisplayMetrics.DENSITY_TV, 80);
+            expectedMemorySizeForLargeScreen.put(DisplayMetrics.DENSITY_HIGH, 80);
+            expectedMemorySizeForLargeScreen.put(DisplayMetrics.DENSITY_280, 96);
+            expectedMemorySizeForLargeScreen.put(DisplayMetrics.DENSITY_XHIGH, 128);
+            expectedMemorySizeForLargeScreen.put(DisplayMetrics.DENSITY_360, 160);
+            expectedMemorySizeForLargeScreen.put(DisplayMetrics.DENSITY_400, 192);
+            expectedMemorySizeForLargeScreen.put(DisplayMetrics.DENSITY_420, 228);
+            expectedMemorySizeForLargeScreen.put(DisplayMetrics.DENSITY_XXHIGH, 256);
+            expectedMemorySizeForLargeScreen.put(DisplayMetrics.DENSITY_560, 384);
+            expectedMemorySizeForLargeScreen.put(DisplayMetrics.DENSITY_XXXHIGH, 512);
+        }
+
+        static {
+            expectedMemorySizeForXLargeScreen.put(DisplayMetrics.DENSITY_LOW, 48);
+            expectedMemorySizeForXLargeScreen.put(DisplayMetrics.DENSITY_MEDIUM, 80);
+            expectedMemorySizeForXLargeScreen.put(DisplayMetrics.DENSITY_TV, 96);
+            expectedMemorySizeForXLargeScreen.put(DisplayMetrics.DENSITY_HIGH, 96);
+            expectedMemorySizeForXLargeScreen.put(DisplayMetrics.DENSITY_280, 144);
+            expectedMemorySizeForXLargeScreen.put(DisplayMetrics.DENSITY_XHIGH, 192);
+            expectedMemorySizeForXLargeScreen.put(DisplayMetrics.DENSITY_360, 240);
+            expectedMemorySizeForXLargeScreen.put(DisplayMetrics.DENSITY_400, 288);
+            expectedMemorySizeForXLargeScreen.put(DisplayMetrics.DENSITY_420, 336);
+            expectedMemorySizeForXLargeScreen.put(DisplayMetrics.DENSITY_XXHIGH, 384);
+            expectedMemorySizeForXLargeScreen.put(DisplayMetrics.DENSITY_560, 576);
+            expectedMemorySizeForXLargeScreen.put(DisplayMetrics.DENSITY_XXXHIGH, 768);
+        }
+
+        public static Integer getExpectedMemorySize(
+                int screenSize,
+                int screenDensity,
+                boolean isWatch) {
+
+           if (isWatch) {
+              return expectedMemorySizeForWatch.get(screenDensity);
+           }
+
+           switch (screenSize) {
+                case Configuration.SCREENLAYOUT_SIZE_SMALL:
+                case Configuration.SCREENLAYOUT_SIZE_NORMAL:
+                    return expectedMemorySizeForSmallNormalScreen.get(screenDensity);
+                case Configuration.SCREENLAYOUT_SIZE_LARGE:
+                    return expectedMemorySizeForLargeScreen.get(screenDensity);
+                case Configuration.SCREENLAYOUT_SIZE_XLARGE:
+                    return expectedMemorySizeForXLargeScreen.get(screenDensity);
+                default:
+                    throw new IllegalArgumentException("No memory requirement specified "
+                        + " for screen layout size " + screenSize);
+           }
+        }
+    }
+
+    public void testGetMemoryClass() throws Exception {
+        int memoryClass = getMemoryClass();
+        int screenDensity = getScreenDensity();
+        int screenSize = getScreenSize();
+        assertMemoryForScreenDensity(memoryClass, screenDensity, screenSize);
+
+        runHeapTestApp(memoryClass);
+    }
+
+    private int getMemoryClass() {
+        Context context = getInstrumentation().getTargetContext();
+        ActivityManager activityManager =
+                (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
+        return activityManager.getMemoryClass();
+    }
+
+    private int getScreenDensity() {
+        Context context = getInstrumentation().getTargetContext();
+        WindowManager windowManager =
+                (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
+        Display display = windowManager.getDefaultDisplay();
+        DisplayMetrics metrics = new DisplayMetrics();
+        display.getMetrics(metrics);
+        return metrics.densityDpi;
+    }
+
+    private int getScreenSize() {
+        Context context = getInstrumentation().getTargetContext();
+        Configuration config = context.getResources().getConfiguration();
+        return config.screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK;
+    }
+
+    private void assertMemoryForScreenDensity(int memoryClass, int screenDensity, int screenSize) {
+        Context context = getInstrumentation().getTargetContext();
+        boolean isWatch =
+            context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH);
+        int expectedMinimumMemory =
+            ExpectedMemorySizesClass.getExpectedMemorySize(screenSize, screenDensity, isWatch);
+
+        assertTrue("Expected to have at least " + expectedMinimumMemory
+                + "mb of memory for screen density " + screenDensity,
+                        memoryClass >= expectedMinimumMemory);
+    }
+
+    private void runHeapTestApp(int memoryClass) throws InterruptedException {
+        Intent intent = new Intent();
+        intent.putExtra(ActivityManagerMemoryClassLaunchActivity.MEMORY_CLASS_EXTRA,
+                memoryClass);
+        setActivityIntent(intent);
+        ActivityManagerMemoryClassLaunchActivity activity = getActivity();
+        assertEquals("The test application couldn't allocate memory close to the amount "
+                + " specified by the memory class.", Activity.RESULT_OK, activity.getResult());
+    }
+}
diff --git a/tests/app/src/android/app/cts/ActivityManagerMemoryClassTestActivity.java b/tests/app/src/android/app/cts/ActivityManagerMemoryClassTestActivity.java
deleted file mode 100644
index e717b03..0000000
--- a/tests/app/src/android/app/cts/ActivityManagerMemoryClassTestActivity.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.util.Log;
-
-/**
- * {@link Activity} that allocates arrays of 256k until reaching 75% of the specified memory class.
- */
-public class ActivityManagerMemoryClassTestActivity extends Activity {
-
-    private static final String TAG = "ActivityManagerMemoryClassTest";
-
-    private static final double FREE_MEMORY_PERCENTAGE = 0.75;
-
-    private static final int ARRAY_BYTES_SIZE = 256 * 1024;
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        Intent intent = getIntent();
-        int memoryClass =
-                intent.getIntExtra(ActivityManagerMemoryClassLaunchActivity.MEMORY_CLASS_EXTRA, -1);
-        new AllocateMemoryTask(memoryClass).execute();
-    }
-
-    private class AllocateMemoryTask extends AsyncTask<Void, Void, Void> {
-
-        private final int mMemoryClass;
-
-        AllocateMemoryTask(int memoryClass) {
-            this.mMemoryClass = memoryClass;
-        }
-
-        @Override
-        protected Void doInBackground(Void... params) {
-            int targetMbs = (int) (mMemoryClass * FREE_MEMORY_PERCENTAGE);
-            int numArrays = targetMbs * 1024 * 1024 / ARRAY_BYTES_SIZE;
-            Log.i(TAG, "Memory class: " + mMemoryClass + "mb Target memory: "
-                    + targetMbs + "mb Number of arrays: " + numArrays);
-
-            byte[][] arrays = new byte[numArrays][];
-            for (int i = 0; i < arrays.length; i++) {
-                Log.i(TAG, "Allocating array " + i + " of " + arrays.length
-                        + " (" + (i * ARRAY_BYTES_SIZE / 1024 / 1024) + "mb)");
-                arrays[i] = new byte[ARRAY_BYTES_SIZE];
-            }
-            return null;
-        }
-
-        @Override
-        protected void onPostExecute(Void result) {
-            super.onPostExecute(result);
-            setResult(RESULT_OK);
-            finish();
-        }
-    }
-}
diff --git a/tests/tests/app/src/android/app/cts/ActivityManagerMemoryInfoTest.java b/tests/app/src/android/app/cts/ActivityManagerMemoryInfoTest.java
similarity index 100%
rename from tests/tests/app/src/android/app/cts/ActivityManagerMemoryInfoTest.java
rename to tests/app/src/android/app/cts/ActivityManagerMemoryInfoTest.java
diff --git a/tests/tests/app/src/android/app/cts/ActivityManagerProcessErrorStateInfoTest.java b/tests/app/src/android/app/cts/ActivityManagerProcessErrorStateInfoTest.java
similarity index 100%
rename from tests/tests/app/src/android/app/cts/ActivityManagerProcessErrorStateInfoTest.java
rename to tests/app/src/android/app/cts/ActivityManagerProcessErrorStateInfoTest.java
diff --git a/tests/app/src/android/app/cts/ActivityManagerRecentOneActivity.java b/tests/app/src/android/app/cts/ActivityManagerRecentOneActivity.java
deleted file mode 100644
index b3edece..0000000
--- a/tests/app/src/android/app/cts/ActivityManagerRecentOneActivity.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-import android.app.Activity;
-
-public class ActivityManagerRecentOneActivity extends Activity {
-}
diff --git a/tests/tests/app/src/android/app/cts/ActivityManagerRecentTaskInfoTest.java b/tests/app/src/android/app/cts/ActivityManagerRecentTaskInfoTest.java
similarity index 100%
rename from tests/tests/app/src/android/app/cts/ActivityManagerRecentTaskInfoTest.java
rename to tests/app/src/android/app/cts/ActivityManagerRecentTaskInfoTest.java
diff --git a/tests/app/src/android/app/cts/ActivityManagerRecentTwoActivity.java b/tests/app/src/android/app/cts/ActivityManagerRecentTwoActivity.java
deleted file mode 100644
index 97a91cc..0000000
--- a/tests/app/src/android/app/cts/ActivityManagerRecentTwoActivity.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-import android.app.Activity;
-
-public class ActivityManagerRecentTwoActivity extends Activity {
-}
diff --git a/tests/tests/app/src/android/app/cts/ActivityManagerRunningTaskInfoTest.java b/tests/app/src/android/app/cts/ActivityManagerRunningTaskInfoTest.java
similarity index 100%
rename from tests/tests/app/src/android/app/cts/ActivityManagerRunningTaskInfoTest.java
rename to tests/app/src/android/app/cts/ActivityManagerRunningTaskInfoTest.java
diff --git a/tests/app/src/android/app/cts/ActivityManagerStubCrashActivity.java b/tests/app/src/android/app/cts/ActivityManagerStubCrashActivity.java
deleted file mode 100644
index b1c30a8..0000000
--- a/tests/app/src/android/app/cts/ActivityManagerStubCrashActivity.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.widget.TextView;
-
-public class ActivityManagerStubCrashActivity extends Activity {
-
-    @Override
-    public void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-        final TextView tv = new TextView(this);
-        tv.setText("Hello, Android but crash");
-        setContentView(tv);
-        die();
-    }
-
-    public void die() {
-        throw new NullPointerException("Expected NPE.");
-    }
-}
-
diff --git a/tests/app/src/android/app/cts/ActivityManagerStubFooActivity.java b/tests/app/src/android/app/cts/ActivityManagerStubFooActivity.java
deleted file mode 100644
index c002ec8..0000000
--- a/tests/app/src/android/app/cts/ActivityManagerStubFooActivity.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.widget.TextView;
-
-public class ActivityManagerStubFooActivity extends Activity {
-
-    @Override
-    public void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-        final TextView tv = new TextView(this);
-        tv.setText("Hello, Android");
-        setContentView(tv);
-    }
-}
diff --git a/tests/app/src/android/app/cts/ActivityManagerTest.java b/tests/app/src/android/app/cts/ActivityManagerTest.java
new file mode 100644
index 0000000..c03ad6d
--- /dev/null
+++ b/tests/app/src/android/app/cts/ActivityManagerTest.java
@@ -0,0 +1,530 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.cts;
+
+import android.app.Activity;
+import android.app.ActivityManager;
+import android.app.ActivityManager.RecentTaskInfo;
+import android.app.ActivityManager.RunningAppProcessInfo;
+import android.app.ActivityManager.RunningServiceInfo;
+import android.app.ActivityManager.RunningTaskInfo;
+import android.app.ActivityOptions;
+import android.app.Instrumentation;
+import android.app.Instrumentation.ActivityMonitor;
+import android.app.Instrumentation.ActivityResult;
+import android.app.PendingIntent;
+import android.app.stubs.ActivityManagerRecentOneActivity;
+import android.app.stubs.ActivityManagerRecentTwoActivity;
+import android.app.stubs.MockApplicationActivity;
+import android.app.stubs.MockService;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.ConfigurationInfo;
+import android.test.InstrumentationTestCase;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ActivityManagerTest extends InstrumentationTestCase {
+    private static final String STUB_PACKAGE_NAME = "android.app.stubs";
+    private static final int WAITFOR_MSEC = 5000;
+    private static final String SERVICE_NAME = "android.app.stubs.MockService";
+    private static final int WAIT_TIME = 2000;
+    // A secondary test activity from another APK.
+    private static final String SIMPLE_PACKAGE_NAME = "com.android.cts.launcherapps.simpleapp";
+    private static final String SIMPLE_ACTIVITY = ".SimpleActivity";
+    private static final String SIMPLE_ACTIVITY_IMMEDIATE_EXIT = ".SimpleActivityImmediateExit";
+    private static final String SIMPLE_ACTIVITY_CHAIN_EXIT = ".SimpleActivityChainExit";
+    // The action sent back by the SIMPLE_APP after a restart.
+    private static final String ACTIVITY_LAUNCHED_ACTION =
+            "com.android.cts.launchertests.LauncherAppsTests.LAUNCHED_ACTION";
+    // The action sent back by the SIMPLE_APP_IMMEDIATE_EXIT when it terminates.
+    private static final String ACTIVITY_EXIT_ACTION =
+            "com.android.cts.launchertests.LauncherAppsTests.EXIT_ACTION";
+    // The action sent back by the SIMPLE_APP_CHAIN_EXIT when the task chain ends. 
+    private static final String ACTIVITY_CHAIN_EXIT_ACTION =
+            "com.android.cts.launchertests.LauncherAppsTests.CHAIN_EXIT_ACTION";
+    // The action sent to identify the time track info.
+    private static final String ACTIVITY_TIME_TRACK_INFO = "com.android.cts.TIME_TRACK_INFO";
+    // Return states of the ActivityReceiverFilter.
+    public static final int RESULT_PASS = 1;
+    public static final int RESULT_FAIL = 2;
+    public static final int RESULT_TIMEOUT = 3;
+
+    private Context mContext;
+    private ActivityManager mActivityManager;
+    private Intent mIntent;
+    private List<Activity> mStartedActivityList;
+    private int mErrorProcessID;
+    private Instrumentation mInstrumentation;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mInstrumentation = getInstrumentation();
+        mContext = mInstrumentation.getContext();
+        mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
+        mStartedActivityList = new ArrayList<Activity>();
+        mErrorProcessID = -1;
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+        if (mIntent != null) {
+            mInstrumentation.getContext().stopService(mIntent);
+        }
+        for (int i = 0; i < mStartedActivityList.size(); i++) {
+            mStartedActivityList.get(i).finish();
+        }
+        if (mErrorProcessID != -1) {
+            android.os.Process.killProcess(mErrorProcessID);
+        }
+    }
+
+    public void testGetRecentTasks() throws Exception {
+        int maxNum = 0;
+        int flags = 0;
+
+        List<RecentTaskInfo> recentTaskList;
+        // Test parameter: maxNum is set to 0
+        recentTaskList = mActivityManager.getRecentTasks(maxNum, flags);
+        assertNotNull(recentTaskList);
+        assertTrue(recentTaskList.size() == 0);
+        // Test parameter: maxNum is set to 50
+        maxNum = 50;
+        recentTaskList = mActivityManager.getRecentTasks(maxNum, flags);
+        assertNotNull(recentTaskList);
+        // start recent1_activity.
+        startSubActivity(ActivityManagerRecentOneActivity.class);
+        Thread.sleep(WAIT_TIME);
+        // start recent2_activity
+        startSubActivity(ActivityManagerRecentTwoActivity.class);
+        Thread.sleep(WAIT_TIME);
+        /*
+         * assert both recent1_activity and recent2_activity exist in the recent
+         * tasks list. Moreover,the index of the recent2_activity is smaller
+         * than the index of recent1_activity
+         */
+        recentTaskList = mActivityManager.getRecentTasks(maxNum, flags);
+        int indexRecentOne = -1;
+        int indexRecentTwo = -1;
+        int i = 0;
+        for (RecentTaskInfo rti : recentTaskList) {
+            if (rti.baseIntent.getComponent().getClassName().equals(
+                    ActivityManagerRecentOneActivity.class.getName())) {
+                indexRecentOne = i;
+            } else if (rti.baseIntent.getComponent().getClassName().equals(
+                    ActivityManagerRecentTwoActivity.class.getName())) {
+                indexRecentTwo = i;
+            }
+            i++;
+        }
+        assertTrue(indexRecentOne != -1 && indexRecentTwo != -1);
+        assertTrue(indexRecentTwo < indexRecentOne);
+
+        try {
+            mActivityManager.getRecentTasks(-1, 0);
+            fail("Should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected exception
+        }
+    }
+
+    public void testGetRecentTasksLimitedToCurrentAPK() throws Exception {
+        int maxNum = 0;
+        int flags = 0;
+
+        // Check the number of tasks at this time.
+        List<RecentTaskInfo>  recentTaskList;
+        recentTaskList = mActivityManager.getRecentTasks(maxNum, flags);
+        int numberOfEntriesFirstRun = recentTaskList.size();
+
+        // Start another activity from another APK.
+        Intent intent = new Intent(Intent.ACTION_MAIN);
+        intent.setClassName(SIMPLE_PACKAGE_NAME, SIMPLE_PACKAGE_NAME + SIMPLE_ACTIVITY);
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        ActivityReceiverFilter receiver = new ActivityReceiverFilter(ACTIVITY_LAUNCHED_ACTION);
+        mContext.startActivity(intent);
+
+        // Make sure the activity has really started.
+        assertEquals(RESULT_PASS, receiver.waitForActivity());
+        receiver.close();
+
+        // There shouldn't be any more tasks in this list at this time.
+        recentTaskList = mActivityManager.getRecentTasks(maxNum, flags);
+        int numberOfEntriesSecondRun = recentTaskList.size();
+        assertTrue(numberOfEntriesSecondRun == numberOfEntriesFirstRun);
+    }
+
+    // The receiver filter needs to be instantiated with the command to filter for before calling
+    // startActivity.
+    private class ActivityReceiverFilter extends BroadcastReceiver {
+        // The activity we want to filter for.
+        private String mActivityToFilter;
+        private int result = RESULT_TIMEOUT;
+        public long mTimeUsed = 0;
+        private static final int TIMEOUT_IN_MS = 1000;
+
+        // Create the filter with the intent to look for.
+        public ActivityReceiverFilter(String activityToFilter) {
+            mActivityToFilter = activityToFilter;
+            IntentFilter filter = new IntentFilter();
+            filter.addAction(mActivityToFilter);
+            mInstrumentation.getTargetContext().registerReceiver(this, filter);
+        }
+
+        // Turn off the filter.
+        public void close() {
+            mInstrumentation.getTargetContext().unregisterReceiver(this);
+        }
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (intent.getAction().equals(mActivityToFilter)) {
+                synchronized(this) {
+                   result = RESULT_PASS;
+                   if (mActivityToFilter.equals(ACTIVITY_TIME_TRACK_INFO)) {
+                       mTimeUsed = intent.getExtras().getLong(
+                               ActivityOptions.EXTRA_USAGE_TIME_REPORT);
+                   }
+                   notifyAll();
+                }
+            }
+        }
+
+        public int waitForActivity() {
+            synchronized(this) {
+                try {
+                    wait(TIMEOUT_IN_MS);
+                } catch (InterruptedException e) {
+                }
+            }
+            return result;
+        }
+    }
+
+    private final <T extends Activity> void startSubActivity(Class<T> activityClass) {
+        final Instrumentation.ActivityResult result = new ActivityResult(0, new Intent());
+        final ActivityMonitor monitor = new ActivityMonitor(activityClass.getName(), result, false);
+        mInstrumentation.addMonitor(monitor);
+        launchActivity(STUB_PACKAGE_NAME, activityClass, null);
+        mStartedActivityList.add(monitor.waitForActivity());
+    }
+
+    public void testGetRunningTasks() {
+        // Test illegal parameter
+        List<RunningTaskInfo> runningTaskList;
+        runningTaskList = mActivityManager.getRunningTasks(-1);
+        assertTrue(runningTaskList.size() == 0);
+
+        runningTaskList = mActivityManager.getRunningTasks(0);
+        assertTrue(runningTaskList.size() == 0);
+
+        runningTaskList = mActivityManager.getRunningTasks(20);
+        int taskSize = runningTaskList.size();
+        assertTrue(taskSize >= 0 && taskSize <= 20);
+
+        // start recent1_activity.
+        startSubActivity(ActivityManagerRecentOneActivity.class);
+        // start recent2_activity
+        startSubActivity(ActivityManagerRecentTwoActivity.class);
+
+        /*
+         * assert both recent1_activity and recent2_activity exist in the
+         * running tasks list. Moreover,the index of the recent2_activity is
+         * smaller than the index of recent1_activity
+         */
+        runningTaskList = mActivityManager.getRunningTasks(20);
+        int indexRecentOne = -1;
+        int indexRecentTwo = -1;
+        int i = 0;
+        for (RunningTaskInfo rti : runningTaskList) {
+            if (rti.baseActivity.getClassName().equals(
+                    ActivityManagerRecentOneActivity.class.getName())) {
+                indexRecentOne = i;
+            } else if (rti.baseActivity.getClassName().equals(
+                    ActivityManagerRecentTwoActivity.class.getName())) {
+                indexRecentTwo = i;
+            }
+            i++;
+        }
+        assertTrue(indexRecentOne != -1 && indexRecentTwo != -1);
+        assertTrue(indexRecentTwo < indexRecentOne);
+    }
+
+    public void testGetRunningServices() throws Exception {
+        // Test illegal parameter
+        List<RunningServiceInfo> runningServiceInfo;
+        runningServiceInfo = mActivityManager.getRunningServices(-1);
+        assertTrue(runningServiceInfo.size() == 0);
+
+        runningServiceInfo = mActivityManager.getRunningServices(0);
+        assertTrue(runningServiceInfo.size() == 0);
+
+        runningServiceInfo = mActivityManager.getRunningServices(5);
+        assertTrue(runningServiceInfo.size() >= 0 && runningServiceInfo.size() <= 5);
+
+        Intent intent = new Intent();
+        intent.setClass(mInstrumentation.getTargetContext(), MockService.class);
+        mInstrumentation.getTargetContext().startService(intent);
+        Thread.sleep(WAIT_TIME);
+
+        runningServiceInfo = mActivityManager.getRunningServices(Integer.MAX_VALUE);
+        boolean foundService = false;
+        for (RunningServiceInfo rs : runningServiceInfo) {
+            if (rs.service.getClassName().equals(SERVICE_NAME)) {
+                foundService = true;
+                break;
+            }
+        }
+        assertTrue(foundService);
+        mContext.stopService(intent);
+        Thread.sleep(WAIT_TIME);
+    }
+
+    public void testGetMemoryInfo() {
+        ActivityManager.MemoryInfo outInfo = new ActivityManager.MemoryInfo();
+        mActivityManager.getMemoryInfo(outInfo);
+        assertTrue(outInfo.lowMemory == (outInfo.availMem <= outInfo.threshold));
+    }
+
+    public void testGetRunningAppProcesses() throws Exception {
+        List<RunningAppProcessInfo> list = mActivityManager.getRunningAppProcesses();
+        assertNotNull(list);
+        final String SYSTEM_PROCESS = "system";
+        boolean hasSystemProcess = false;
+        // The package name is also the default name for the application process
+        final String TEST_PROCESS = STUB_PACKAGE_NAME;
+        boolean hasTestProcess = false;
+        for (RunningAppProcessInfo ra : list) {
+            if (ra.processName.equals(SYSTEM_PROCESS)) {
+                hasSystemProcess = true;
+            } else if (ra.processName.equals(TEST_PROCESS)) {
+                hasTestProcess = true;
+            }
+        }
+        // For security reasons the system process is not exposed.
+        assertTrue(!hasSystemProcess && hasTestProcess);
+
+        for (RunningAppProcessInfo ra : list) {
+            if (ra.processName.equals("android.app.stubs:remote")) {
+                fail("should be no process named android.app.stubs:remote");
+            }
+        }
+        // start a new process
+        mIntent = new Intent("android.app.REMOTESERVICE");
+        mIntent.setPackage("android.app.stubs");
+        mInstrumentation.getTargetContext().startService(mIntent);
+        Thread.sleep(WAITFOR_MSEC);
+
+        List<RunningAppProcessInfo> listNew = mActivityManager.getRunningAppProcesses();
+        assertTrue(list.size() <= listNew.size());
+
+        for (RunningAppProcessInfo ra : listNew) {
+            if (ra.processName.equals("android.app.stubs:remote")) {
+                return;
+            }
+        }
+        fail("android.app.stubs:remote process should be available");
+    }
+
+    public void testGetProcessInErrorState() throws Exception {
+        List<ActivityManager.ProcessErrorStateInfo> errList = null;
+        errList = mActivityManager.getProcessesInErrorState();
+    }
+
+    public void testRestartPackage() {
+    }
+
+    public void testGetDeviceConfigurationInfo() {
+        ConfigurationInfo conInf = mActivityManager.getDeviceConfigurationInfo();
+        assertNotNull(conInf);
+    }
+
+    /**
+     * Simple test for {@link ActivityManager.isUserAMonkey()} - verifies its false.
+     *
+     * TODO: test positive case
+     */
+    public void testIsUserAMonkey() {
+        assertFalse(ActivityManager.isUserAMonkey());
+    }
+
+    /**
+     * Verify that {@link ActivityManager.isRunningInTestHarness()} is false.
+     */
+    public void testIsRunningInTestHarness() {
+        assertFalse("isRunningInTestHarness must be false in production builds",
+                ActivityManager.isRunningInTestHarness());
+    }
+
+    /**
+     * Go back to the home screen since running applications can interfere with application
+     * lifetime tests.
+     */
+    private void launchHome() throws Exception {
+        Intent intent = new Intent(Intent.ACTION_MAIN);
+        intent.addCategory(Intent.CATEGORY_HOME);
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        mContext.startActivity(intent);
+        Thread.sleep(WAIT_TIME);
+    }
+
+    /**
+     * Verify that the TimeTrackingAPI works properly when starting and ending an activity.
+     */
+    public void testTimeTrackingAPI_SimpleStartExit() throws Exception {
+        launchHome();
+        // Prepare to start an activity from another APK.
+        Intent intent = new Intent(Intent.ACTION_MAIN);
+        intent.setClassName(SIMPLE_PACKAGE_NAME,
+                SIMPLE_PACKAGE_NAME + SIMPLE_ACTIVITY_IMMEDIATE_EXIT);
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
+        // Prepare the time receiver action.
+        Context context = mInstrumentation.getTargetContext();
+        ActivityOptions options = ActivityOptions.makeBasic();
+        Intent receiveIntent = new Intent(ACTIVITY_TIME_TRACK_INFO);
+        options.requestUsageTimeReport(PendingIntent.getBroadcast(context,
+                0, receiveIntent, PendingIntent.FLAG_CANCEL_CURRENT));
+
+        // The application finished tracker.
+        ActivityReceiverFilter appEndReceiver = new ActivityReceiverFilter(ACTIVITY_EXIT_ACTION);
+
+        // The filter for the time event.
+        ActivityReceiverFilter timeReceiver = new ActivityReceiverFilter(ACTIVITY_TIME_TRACK_INFO);
+
+        // Run the activity.
+        mContext.startActivity(intent, options.toBundle());
+
+        // Wait until it finishes and end the reciever then.
+        assertEquals(RESULT_PASS, appEndReceiver.waitForActivity());
+        appEndReceiver.close();
+
+        // At this time the timerReceiver should not fire, even though the activity has shut down,
+        // because we are back to the home screen.
+        assertEquals(RESULT_TIMEOUT, timeReceiver.waitForActivity());
+        assertTrue(timeReceiver.mTimeUsed == 0);
+
+        // Issuing now another activity will trigger the timing information release.
+        final Intent dummyIntent = new Intent(context, MockApplicationActivity.class);
+        dummyIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        final Activity activity = mInstrumentation.startActivitySync(dummyIntent);
+
+        // Wait until it finishes and end the reciever then.
+        assertEquals(RESULT_PASS, timeReceiver.waitForActivity());
+        timeReceiver.close();
+        assertTrue(timeReceiver.mTimeUsed != 0);
+    }
+
+    /**
+     * Verify that the TimeTrackingAPI works properly when switching away from the monitored task.
+     */
+    public void testTimeTrackingAPI_SwitchAwayTriggers() throws Exception {
+        launchHome();
+
+        // Prepare to start an activity from another APK.
+        Intent intent = new Intent(Intent.ACTION_MAIN);
+        intent.setClassName(SIMPLE_PACKAGE_NAME, SIMPLE_PACKAGE_NAME + SIMPLE_ACTIVITY);
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
+        // Prepare the time receiver action.
+        Context context = mInstrumentation.getTargetContext();
+        ActivityOptions options = ActivityOptions.makeBasic();
+        Intent receiveIntent = new Intent(ACTIVITY_TIME_TRACK_INFO);
+        options.requestUsageTimeReport(PendingIntent.getBroadcast(context,
+                0, receiveIntent, PendingIntent.FLAG_CANCEL_CURRENT));
+
+        // The application started tracker.
+        ActivityReceiverFilter appStartedReceiver = new ActivityReceiverFilter(
+                ACTIVITY_LAUNCHED_ACTION);
+
+        // The filter for the time event.
+        ActivityReceiverFilter timeReceiver = new ActivityReceiverFilter(ACTIVITY_TIME_TRACK_INFO);
+
+        // Run the activity.
+        mContext.startActivity(intent, options.toBundle());
+
+        // Wait until it finishes and end the reciever then.
+        assertEquals(RESULT_PASS, appStartedReceiver.waitForActivity());
+        appStartedReceiver.close();
+
+        // At this time the timerReceiver should not fire since our app is running.
+        assertEquals(RESULT_TIMEOUT, timeReceiver.waitForActivity());
+        assertTrue(timeReceiver.mTimeUsed == 0);
+
+        // Starting now another activity will put ours into the back hence releasing the timing.
+        final Intent dummyIntent = new Intent(context, MockApplicationActivity.class);
+        dummyIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        final Activity activity = mInstrumentation.startActivitySync(dummyIntent);
+
+        // Wait until it finishes and end the reciever then.
+        assertEquals(RESULT_PASS, timeReceiver.waitForActivity());
+        timeReceiver.close();
+        assertTrue(timeReceiver.mTimeUsed != 0);
+    }
+
+    /**
+     * Verify that the TimeTrackingAPI works properly when handling an activity chain gets started
+     * and ended.
+     */
+    public void testTimeTrackingAPI_ChainedActivityExit() throws Exception {
+        launchHome();
+        // Prepare to start an activity from another APK.
+        Intent intent = new Intent(Intent.ACTION_MAIN);
+        intent.setClassName(SIMPLE_PACKAGE_NAME,
+                SIMPLE_PACKAGE_NAME + SIMPLE_ACTIVITY_CHAIN_EXIT);
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
+        // Prepare the time receiver action.
+        Context context = mInstrumentation.getTargetContext();
+        ActivityOptions options = ActivityOptions.makeBasic();
+        Intent receiveIntent = new Intent(ACTIVITY_TIME_TRACK_INFO);
+        options.requestUsageTimeReport(PendingIntent.getBroadcast(context,
+                0, receiveIntent, PendingIntent.FLAG_CANCEL_CURRENT));
+
+        // The application finished tracker.
+        ActivityReceiverFilter appEndReceiver = new ActivityReceiverFilter(
+                ACTIVITY_CHAIN_EXIT_ACTION);
+
+        // The filter for the time event.
+        ActivityReceiverFilter timeReceiver = new ActivityReceiverFilter(ACTIVITY_TIME_TRACK_INFO);
+
+        // Run the activity.
+        mContext.startActivity(intent, options.toBundle());
+
+        // Wait until it finishes and end the reciever then.
+        assertEquals(RESULT_PASS, appEndReceiver.waitForActivity());
+        appEndReceiver.close();
+
+        // At this time the timerReceiver should not fire, even though the activity has shut down.
+        assertEquals(RESULT_TIMEOUT, timeReceiver.waitForActivity());
+        assertTrue(timeReceiver.mTimeUsed == 0);
+
+        // Issue another activity so that the timing information gets released.
+        final Intent dummyIntent = new Intent(context, MockApplicationActivity.class);
+        dummyIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        final Activity activity = mInstrumentation.startActivitySync(dummyIntent);
+
+        // Wait until it finishes and end the reciever then.
+        assertEquals(RESULT_PASS, timeReceiver.waitForActivity());
+        timeReceiver.close();
+        assertTrue(timeReceiver.mTimeUsed != 0);
+    }
+}
diff --git a/tests/tests/app/src/android/app/cts/ActivityManager_RunningAppProcessInfoTest.java b/tests/app/src/android/app/cts/ActivityManager_RunningAppProcessInfoTest.java
similarity index 100%
rename from tests/tests/app/src/android/app/cts/ActivityManager_RunningAppProcessInfoTest.java
rename to tests/app/src/android/app/cts/ActivityManager_RunningAppProcessInfoTest.java
diff --git a/tests/app/src/android/app/cts/ActivityManager_RunningServiceInfoTest.java b/tests/app/src/android/app/cts/ActivityManager_RunningServiceInfoTest.java
new file mode 100644
index 0000000..fa34130
--- /dev/null
+++ b/tests/app/src/android/app/cts/ActivityManager_RunningServiceInfoTest.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.cts;
+
+import android.app.ActivityManager;
+import android.app.stubs.MockActivity;
+import android.content.ComponentName;
+import android.os.Parcel;
+import android.test.AndroidTestCase;
+
+public class ActivityManager_RunningServiceInfoTest extends AndroidTestCase {
+    private ActivityManager.RunningServiceInfo mRunningServiceInfo;
+    private ComponentName mService;
+    private static final String PROCESS = "process";
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mRunningServiceInfo = new ActivityManager.RunningServiceInfo();
+        mService = new ComponentName(getContext(), MockActivity.class);
+
+        mRunningServiceInfo.service = mService;
+        mRunningServiceInfo.pid = 1;
+        mRunningServiceInfo.process = PROCESS;
+        mRunningServiceInfo.foreground = true;
+        mRunningServiceInfo.activeSince = 1l;
+        mRunningServiceInfo.started = true;
+        mRunningServiceInfo.clientCount = 2;
+        mRunningServiceInfo.crashCount = 1;
+        mRunningServiceInfo.lastActivityTime = 1l;
+        mRunningServiceInfo.restarting = 1l;
+    }
+
+    public void testConstructor() {
+        new ActivityManager.RunningServiceInfo();
+    }
+
+    public void testDescribeContents() {
+        assertEquals(0, mRunningServiceInfo.describeContents());
+    }
+
+    public void testWriteToParcel() throws Exception {
+
+        Parcel parcel = Parcel.obtain();
+        mRunningServiceInfo.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        ActivityManager.RunningServiceInfo values =
+            ActivityManager.RunningServiceInfo.CREATOR.createFromParcel(parcel);
+        assertEquals(mService, values.service);
+        assertEquals(1, values.pid);
+        assertEquals(PROCESS, values.process);
+        assertTrue(values.foreground);
+        assertEquals(1l, values.activeSince);
+        assertTrue(values.started);
+        assertEquals(2, values.clientCount);
+        assertEquals(1, values.crashCount);
+        assertEquals(1l, values.lastActivityTime);
+        assertEquals(1l, values.restarting);
+    }
+
+    public void testReadFromParcel() throws Exception {
+
+        Parcel parcel = Parcel.obtain();
+        mRunningServiceInfo.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        ActivityManager.RunningServiceInfo values =
+            new ActivityManager.RunningServiceInfo();
+        values.readFromParcel(parcel);
+        assertEquals(mService, values.service);
+        assertEquals(1, values.pid);
+        assertEquals(PROCESS, values.process);
+        assertTrue(values.foreground);
+        assertEquals(1l, values.activeSince);
+        assertTrue(values.started);
+        assertEquals(2, values.clientCount);
+        assertEquals(1, values.crashCount);
+        assertEquals(1l, values.lastActivityTime);
+        assertEquals(1l, values.restarting);
+    }
+
+}
diff --git a/tests/app/src/android/app/cts/ActivityTestsBase.java b/tests/app/src/android/app/cts/ActivityTestsBase.java
deleted file mode 100644
index 426a8b8..0000000
--- a/tests/app/src/android/app/cts/ActivityTestsBase.java
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-import android.app.Activity;
-import android.content.Context;
-import android.content.Intent;
-import android.test.AndroidTestCase;
-import android.test.PerformanceTestCase;
-
-public class ActivityTestsBase extends AndroidTestCase implements PerformanceTestCase,
-        LaunchpadActivity.CallingTest {
-    public static final String PERMISSION_GRANTED = "android.app.cts.permission.TEST_GRANTED";
-    public static final String PERMISSION_DENIED = "android.app.cts.permission.TEST_DENIED";
-
-    private static final int TIMEOUT_MS = 60 * 1000;
-
-    protected Intent mIntent;
-
-    private PerformanceTestCase.Intermediates mIntermediates;
-    private String mExpecting;
-
-    // Synchronization of activity result.
-    private boolean mFinished;
-    private int mResultCode = 0;
-    private Intent mData;
-    private RuntimeException mResultStack = null;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mIntent = new Intent(mContext, LaunchpadActivity.class);
-        mIntermediates = null;
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        mIntermediates = null;
-        super.tearDown();
-    }
-
-    public boolean isPerformanceOnly() {
-        return false;
-    }
-
-    public void setInternalIterations(int count) {
-    }
-
-    public void startTiming(boolean realTime) {
-        if (mIntermediates != null) {
-            mIntermediates.startTiming(realTime);
-        }
-    }
-
-    public void addIntermediate(String name) {
-        if (mIntermediates != null) {
-            mIntermediates.addIntermediate(name);
-        }
-    }
-
-    public void addIntermediate(String name, long timeInNS) {
-        if (mIntermediates != null) {
-            mIntermediates.addIntermediate(name, timeInNS);
-        }
-    }
-
-    public void finishTiming(boolean realTime) {
-        if (mIntermediates != null) {
-            mIntermediates.finishTiming(realTime);
-        }
-    }
-
-    public void activityFinished(int resultCode, Intent data, RuntimeException where) {
-        finishWithResult(resultCode, data, where);
-    }
-
-    public Intent editIntent() {
-        return mIntent;
-    }
-
-    @Override
-    public Context getContext() {
-        return mContext;
-    }
-
-    public int startPerformance(Intermediates intermediates) {
-        mIntermediates = intermediates;
-        return 1;
-    }
-
-    public void finishGood() {
-        finishWithResult(Activity.RESULT_OK, null);
-    }
-
-    public void finishBad(String error) {
-        finishWithResult(Activity.RESULT_CANCELED, new Intent().setAction(error));
-    }
-
-    public void finishWithResult(int resultCode, Intent data) {
-        final RuntimeException where = new RuntimeException("Original error was here");
-        where.fillInStackTrace();
-        finishWithResult(resultCode, data, where);
-    }
-
-    public void finishWithResult(int resultCode, Intent data, RuntimeException where) {
-        synchronized (this) {
-            mResultCode = resultCode;
-            mData = data;
-            mResultStack = where;
-            mFinished = true;
-            notifyAll();
-        }
-    }
-
-    public int runLaunchpad(String action) {
-        startLaunchpadActivity(action);
-        return waitForResultOrThrow(TIMEOUT_MS);
-    }
-
-    private void startLaunchpadActivity(String action) {
-        LaunchpadActivity.setCallingTest(this);
-
-        synchronized (this) {
-            mIntent.setAction(action);
-            mFinished = false;
-            mIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-            mContext.startActivity(mIntent);
-        }
-    }
-
-    public int waitForResultOrThrow(int timeoutMs) {
-        return waitForResultOrThrow(timeoutMs, null);
-    }
-
-    public int waitForResultOrThrow(int timeoutMs, String expected) {
-        final int res = waitForResult(timeoutMs, expected);
-
-        if (res == Activity.RESULT_CANCELED) {
-            if (mResultStack != null) {
-                throw new RuntimeException(mData != null ? mData.toString() : "Unable to launch",
-                        mResultStack);
-            } else {
-                throw new RuntimeException(mData != null ? mData.toString() : "Unable to launch");
-            }
-        }
-        return res;
-    }
-
-    public int waitForResult(int timeoutMs, String expected) {
-        mExpecting = expected;
-
-        final long endTime = System.currentTimeMillis() + timeoutMs;
-
-        boolean timeout = false;
-        synchronized (this) {
-            while (!mFinished) {
-                final long delay = endTime - System.currentTimeMillis();
-                if (delay < 0) {
-                    timeout = true;
-                    break;
-                }
-
-                try {
-                    wait(delay);
-                } catch (final java.lang.InterruptedException e) {
-                    // do nothing
-                }
-            }
-        }
-
-        mFinished = false;
-
-        if (timeout) {
-            mResultCode = Activity.RESULT_CANCELED;
-            onTimeout();
-        }
-        return mResultCode;
-    }
-
-
-    public int getResultCode() {
-        return mResultCode;
-    }
-
-    public Intent getResultData() {
-        return mData;
-    }
-
-    public RuntimeException getResultStack() {
-        return mResultStack;
-    }
-
-    public void onTimeout() {
-        final String msg = mExpecting == null ? "Timeout" : "Timeout while expecting " + mExpecting;
-        finishWithResult(Activity.RESULT_CANCELED, new Intent().setAction(msg));
-    }
-}
diff --git a/tests/app/src/android/app/cts/AlarmManagerTest.java b/tests/app/src/android/app/cts/AlarmManagerTest.java
new file mode 100644
index 0000000..fabedd9
--- /dev/null
+++ b/tests/app/src/android/app/cts/AlarmManagerTest.java
@@ -0,0 +1,351 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.cts;
+
+
+import android.app.AlarmManager;
+import android.app.AlarmManager.AlarmClockInfo;
+import android.app.PendingIntent;
+import android.app.stubs.MockAlarmReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.cts.util.PollingCheck;
+import android.os.Build;
+import android.os.SystemClock;
+import android.test.AndroidTestCase;
+import android.test.MoreAsserts;
+import android.util.Log;
+
+public class AlarmManagerTest extends AndroidTestCase {
+    public static final String MOCKACTION = "android.app.AlarmManagerTest.TEST_ALARMRECEIVER";
+    public static final String MOCKACTION2 = "android.app.AlarmManagerTest.TEST_ALARMRECEIVER2";
+
+    private AlarmManager mAm;
+    private Intent mIntent;
+    private PendingIntent mSender;
+    private Intent mIntent2;
+    private PendingIntent mSender2;
+
+    /*
+     *  The default snooze delay: 5 seconds
+     */
+    private static final long SNOOZE_DELAY = 5 * 1000L;
+    private long mWakeupTime;
+    private MockAlarmReceiver mMockAlarmReceiver;
+    private MockAlarmReceiver mMockAlarmReceiver2;
+
+    private static final int TIME_DELTA = 1000;
+    private static final int TIME_DELAY = 10000;
+    private static final int REPEAT_PERIOD = 60000;
+
+    // Receiver registration/unregistration between tests races with the system process, so
+    // we add a little buffer time here to allow the system to process before we proceed.
+    // This value is in milliseconds.
+    private static final long REGISTER_PAUSE = 250;
+
+    // Constants used for validating exact vs inexact alarm batching immunity.  We run a few
+    // trials of an exact alarm that is placed within an inexact alarm's window of opportunity,
+    // and mandate that the average observed delivery skew between the two be statistically
+    // significant -- i.e. that the two alarms are not being coalesced.  We also place an
+    // additional exact alarm only a short time after the inexact alarm's nominal trigger time.
+    // If exact alarms are allowed to batch with inexact ones this will tend to have no effect,
+    // but in the correct behavior -- inexact alarms not permitted to batch with exact ones --
+    // this additional exact alarm will have the effect of guaranteeing that the inexact alarm
+    // must fire no later than it -- i.e. a considerable time before the significant, later
+    // exact alarm.
+    //
+    // The test essentially amounts to requiring that the inexact MOCKACTION alarm and
+    // the much later exact MOCKACTION2 alarm fire far apart, always; with an implicit
+    // insistence that alarm batches are delivered at the head of their window.
+    private static final long TEST_WINDOW_LENGTH = 5 * 1000L;
+    private static final long TEST_ALARM_FUTURITY = 6 * 1000L;
+    private static final long FAIL_DELTA = 50;
+    private static final long NUM_TRIALS = 5;
+    private static final long MAX_NEAR_DELIVERIES = 2;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        mAm = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
+
+        mIntent = new Intent(MOCKACTION)
+                .addFlags(Intent.FLAG_RECEIVER_FOREGROUND | Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+        mSender = PendingIntent.getBroadcast(mContext, 0, mIntent, 0);
+        mMockAlarmReceiver = new MockAlarmReceiver(mIntent.getAction());
+
+        mIntent2 = new Intent(MOCKACTION2)
+                .addFlags(Intent.FLAG_RECEIVER_FOREGROUND | Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+        mSender2 = PendingIntent.getBroadcast(mContext, 0, mIntent2, 0);
+        mMockAlarmReceiver2 = new MockAlarmReceiver(mIntent2.getAction());
+
+        IntentFilter filter = new IntentFilter(mIntent.getAction());
+        mContext.registerReceiver(mMockAlarmReceiver, filter);
+
+        IntentFilter filter2 = new IntentFilter(mIntent2.getAction());
+        mContext.registerReceiver(mMockAlarmReceiver2, filter2);
+
+        Thread.sleep(REGISTER_PAUSE);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+        mContext.unregisterReceiver(mMockAlarmReceiver);
+        mContext.unregisterReceiver(mMockAlarmReceiver2);
+
+        Thread.sleep(REGISTER_PAUSE);
+    }
+
+    public void testSetTypes() throws Exception {
+        // TODO: try to find a way to make device sleep then test whether
+        // AlarmManager perform the expected way
+
+        // test parameter type is RTC_WAKEUP
+        mMockAlarmReceiver.setAlarmedFalse();
+        mWakeupTime = System.currentTimeMillis() + SNOOZE_DELAY;
+        mAm.setExact(AlarmManager.RTC_WAKEUP, mWakeupTime, mSender);
+        new PollingCheck(SNOOZE_DELAY + TIME_DELAY) {
+            @Override
+            protected boolean check() {
+                return mMockAlarmReceiver.alarmed;
+            }
+        }.run();
+        assertEquals(mMockAlarmReceiver.rtcTime, mWakeupTime, TIME_DELTA);
+
+        // test parameter type is RTC
+        mMockAlarmReceiver.setAlarmedFalse();
+        mWakeupTime = System.currentTimeMillis() + SNOOZE_DELAY;
+        mAm.setExact(AlarmManager.RTC, mWakeupTime, mSender);
+        new PollingCheck(SNOOZE_DELAY + TIME_DELAY) {
+            @Override
+            protected boolean check() {
+                return mMockAlarmReceiver.alarmed;
+            }
+        }.run();
+        assertEquals(mMockAlarmReceiver.rtcTime, mWakeupTime, TIME_DELTA);
+
+        // test parameter type is ELAPSED_REALTIME
+        mMockAlarmReceiver.setAlarmedFalse();
+        mWakeupTime = SystemClock.elapsedRealtime() + SNOOZE_DELAY;
+        mAm.setExact(AlarmManager.ELAPSED_REALTIME, mWakeupTime, mSender);
+        new PollingCheck(SNOOZE_DELAY + TIME_DELAY) {
+            @Override
+            protected boolean check() {
+                return mMockAlarmReceiver.alarmed;
+            }
+        }.run();
+        assertEquals(mMockAlarmReceiver.elapsedTime, mWakeupTime, TIME_DELTA);
+
+        // test parameter type is ELAPSED_REALTIME_WAKEUP
+        mMockAlarmReceiver.setAlarmedFalse();
+        mWakeupTime = SystemClock.elapsedRealtime() + SNOOZE_DELAY;
+        mAm.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, mWakeupTime, mSender);
+        new PollingCheck(SNOOZE_DELAY + TIME_DELAY) {
+            @Override
+            protected boolean check() {
+                return mMockAlarmReceiver.alarmed;
+            }
+        }.run();
+        assertEquals(mMockAlarmReceiver.elapsedTime, mWakeupTime, TIME_DELTA);
+    }
+
+    public void testAlarmTriggersImmediatelyIfSetTimeIsNegative() throws Exception {
+        // An alarm with a negative wakeup time should be triggered immediately.
+        // This exercises a workaround for a limitation of the /dev/alarm driver
+        // that would instead cause such alarms to never be triggered.
+        mMockAlarmReceiver.setAlarmedFalse();
+        mWakeupTime = -1000;
+        mAm.set(AlarmManager.RTC, mWakeupTime, mSender);
+        new PollingCheck(TIME_DELAY) {
+            @Override
+            protected boolean check() {
+                return mMockAlarmReceiver.alarmed;
+            }
+        }.run();
+    }
+
+    public void testExactAlarmBatching() throws Exception {
+        int deliveriesTogether = 0;
+        for (int i = 0; i < NUM_TRIALS; i++) {
+            final long now = System.currentTimeMillis();
+            final long windowStart = now + TEST_ALARM_FUTURITY;
+            final long exactStart = windowStart + TEST_WINDOW_LENGTH - 1;
+
+            mMockAlarmReceiver.setAlarmedFalse();
+            mMockAlarmReceiver2.setAlarmedFalse();
+            mAm.setWindow(AlarmManager.RTC_WAKEUP, windowStart, TEST_WINDOW_LENGTH, mSender);
+            mAm.setExact(AlarmManager.RTC_WAKEUP, exactStart, mSender2);
+
+            // Wait until a half-second beyond its target window, just to provide a
+            // little safety slop.
+            new PollingCheck(TEST_WINDOW_LENGTH + (windowStart - now) + 500) {
+                @Override
+                protected boolean check() {
+                    return mMockAlarmReceiver.alarmed;
+                }
+            }.run();
+
+            // Now wait until 1 sec beyond the expected exact alarm fire time, or for at
+            // least one second if we're already past the nominal exact alarm fire time
+            long timeToExact = Math.max(exactStart - System.currentTimeMillis() + 1000, 1000);
+            new PollingCheck(timeToExact) {
+                @Override
+                protected boolean check() {
+                    return mMockAlarmReceiver2.alarmed;
+                }
+            }.run();
+
+            // Success when we observe that the exact and windowed alarm are not being often
+            // delivered close together -- that is, when we can be confident that they are not
+            // being coalesced.
+            final long delta = Math.abs(mMockAlarmReceiver2.rtcTime - mMockAlarmReceiver.rtcTime);
+            Log.i("TEST", "[" + i + "]  delta = " + delta);
+            if (delta < FAIL_DELTA) {
+                deliveriesTogether++;
+                assertTrue("Exact alarms appear to be coalescing with inexact alarms",
+                        deliveriesTogether <= MAX_NEAR_DELIVERIES);
+            }
+        }
+    }
+
+    public void testSetRepeating() throws Exception {
+        mMockAlarmReceiver.setAlarmedFalse();
+        mWakeupTime = System.currentTimeMillis() + TEST_ALARM_FUTURITY;
+        mAm.setRepeating(AlarmManager.RTC_WAKEUP, mWakeupTime, REPEAT_PERIOD, mSender);
+
+        // wait beyond the initial alarm's possible delivery window to verify that it fires the first time
+        new PollingCheck(TEST_ALARM_FUTURITY + REPEAT_PERIOD) {
+            @Override
+            protected boolean check() {
+                return mMockAlarmReceiver.alarmed;
+            }
+        }.run();
+        assertTrue(mMockAlarmReceiver.alarmed);
+
+        // Now reset the receiver and wait for the intended repeat alarm to fire as expected
+        mMockAlarmReceiver.setAlarmedFalse();
+        new PollingCheck(REPEAT_PERIOD*2) {
+            @Override
+            protected boolean check() {
+                return mMockAlarmReceiver.alarmed;
+            }
+        }.run();
+        assertTrue(mMockAlarmReceiver.alarmed);
+
+        mAm.cancel(mSender);
+    }
+
+    public void testCancel() throws Exception {
+        mMockAlarmReceiver.setAlarmedFalse();
+        mMockAlarmReceiver2.setAlarmedFalse();
+
+        // set two alarms
+        final long when1 = System.currentTimeMillis() + TEST_ALARM_FUTURITY;
+        mAm.setExact(AlarmManager.RTC_WAKEUP, when1, mSender);
+        final long when2 = when1 + TIME_DELTA; // will fire after when1's target time
+        mAm.setExact(AlarmManager.RTC_WAKEUP, when2, mSender2);
+
+        // cancel the earlier one
+        mAm.cancel(mSender);
+
+        // and verify that only the later one fired
+        new PollingCheck(TIME_DELAY) {
+            @Override
+            protected boolean check() {
+                return mMockAlarmReceiver2.alarmed;
+            }
+        }.run();
+
+        assertFalse(mMockAlarmReceiver.alarmed);
+        assertTrue(mMockAlarmReceiver2.alarmed);
+    }
+
+    public void testSetInexactRepeating() throws Exception {
+        mAm.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(),
+                AlarmManager.INTERVAL_FIFTEEN_MINUTES, mSender);
+        SystemClock.setCurrentTimeMillis(System.currentTimeMillis()
+                + AlarmManager.INTERVAL_FIFTEEN_MINUTES);
+        // currently there is no way to write Android system clock. When try to
+        // write the system time, there will be log as
+        // " Unable to open alarm driver: Permission denied". But still fail
+        // after tried many permission.
+    }
+
+    public void testSetAlarmClock() throws Exception {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+            mMockAlarmReceiver.setAlarmedFalse();
+            mMockAlarmReceiver2.setAlarmedFalse();
+
+            // Set first alarm clock.
+            final long wakeupTimeFirst = System.currentTimeMillis()
+                    + 2 * TEST_ALARM_FUTURITY;
+            mAm.setAlarmClock(new AlarmClockInfo(wakeupTimeFirst, null), mSender);
+
+            // Verify getNextAlarmClock returns first alarm clock.
+            AlarmClockInfo nextAlarmClock = mAm.getNextAlarmClock();
+            assertEquals(wakeupTimeFirst, nextAlarmClock.getTriggerTime());
+            assertNull(nextAlarmClock.getShowIntent());
+
+            // Set second alarm clock, earlier than first.
+            final long wakeupTimeSecond = System.currentTimeMillis()
+                    + TEST_ALARM_FUTURITY;
+            PendingIntent showIntentSecond = PendingIntent.getBroadcast(getContext(), 0,
+                    new Intent(getContext(), AlarmManagerTest.class).setAction("SHOW_INTENT"), 0);
+            mAm.setAlarmClock(new AlarmClockInfo(wakeupTimeSecond, showIntentSecond),
+                    mSender2);
+
+            // Verify getNextAlarmClock returns second alarm clock now.
+            nextAlarmClock = mAm.getNextAlarmClock();
+            assertEquals(wakeupTimeSecond, nextAlarmClock.getTriggerTime());
+            assertEquals(showIntentSecond, nextAlarmClock.getShowIntent());
+
+            // Cancel second alarm.
+            mAm.cancel(mSender2);
+
+            // Verify getNextAlarmClock returns first alarm clock again.
+            nextAlarmClock = mAm.getNextAlarmClock();
+            assertEquals(wakeupTimeFirst, nextAlarmClock.getTriggerTime());
+            assertNull(nextAlarmClock.getShowIntent());
+
+            // Wait for first alarm to trigger.
+            assertFalse(mMockAlarmReceiver.alarmed);
+            new PollingCheck(2 * TEST_ALARM_FUTURITY + TIME_DELAY) {
+                @Override
+                protected boolean check() {
+                    return mMockAlarmReceiver.alarmed;
+                }
+            }.run();
+
+            // Verify first alarm fired at the right time.
+            assertEquals(mMockAlarmReceiver.rtcTime, wakeupTimeFirst, TIME_DELTA);
+
+            // Verify second alarm didn't fire.
+            assertFalse(mMockAlarmReceiver2.alarmed);
+
+            // Verify the next alarm is not returning neither the first nor the second alarm.
+            nextAlarmClock = mAm.getNextAlarmClock();
+            MoreAsserts.assertNotEqual(wakeupTimeFirst, nextAlarmClock != null
+                    ? nextAlarmClock.getTriggerTime()
+                    : null);
+            MoreAsserts.assertNotEqual(wakeupTimeSecond, nextAlarmClock != null
+                    ? nextAlarmClock.getTriggerTime()
+                    : null);
+        }
+    }
+}
diff --git a/tests/app/src/android/app/cts/AlertDialogTest.java b/tests/app/src/android/app/cts/AlertDialogTest.java
new file mode 100644
index 0000000..e9628a6
--- /dev/null
+++ b/tests/app/src/android/app/cts/AlertDialogTest.java
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.cts;
+
+import android.app.AlertDialog;
+import android.app.Instrumentation;
+import android.app.stubs.DialogStubActivity;
+import android.content.DialogInterface;
+import android.cts.util.PollingCheck;
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.view.KeyEvent;
+import android.widget.Button;
+
+import android.app.stubs.R;
+/*
+ * Test AlertDialog
+ */
+@SmallTest
+public class AlertDialogTest extends ActivityInstrumentationTestCase2<DialogStubActivity> {
+    private Instrumentation mInstrumentation;
+    private DialogStubActivity mActivity;
+    private Button mPositiveButton;
+    private Button mNegativeButton;
+    private Button mNeutralButton;
+
+    public AlertDialogTest() {
+        super("android.app.stubs", DialogStubActivity.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mInstrumentation = getInstrumentation();
+    }
+
+    protected void startDialogActivity(int dialogNumber) {
+        mActivity = DialogStubActivity.startDialogActivity(this, dialogNumber);
+
+        PollingCheck.waitFor(() -> mActivity.getDialog().isShowing());
+    }
+
+    public void testAlertDialog() throws Throwable {
+        doTestAlertDialog(DialogStubActivity.TEST_ALERTDIALOG);
+    }
+
+    private void doTestAlertDialog(int index) throws Throwable {
+        startDialogActivity(index);
+        assertTrue(mActivity.getDialog().isShowing());
+
+        mPositiveButton = ((AlertDialog) (mActivity.getDialog())).getButton(
+                DialogInterface.BUTTON_POSITIVE);
+        assertNotNull(mPositiveButton);
+        assertEquals(mActivity.getString(R.string.alert_dialog_positive),
+                mPositiveButton.getText());
+        mNeutralButton = ((AlertDialog) (mActivity.getDialog())).getButton(
+                DialogInterface.BUTTON_NEUTRAL);
+        assertNotNull(mNeutralButton);
+        assertEquals(mActivity.getString(R.string.alert_dialog_neutral),
+                mNeutralButton.getText());
+        mNegativeButton = ((AlertDialog) (mActivity.getDialog())).getButton(
+                DialogInterface.BUTTON_NEGATIVE);
+        assertNotNull(mNegativeButton);
+        assertEquals(mActivity.getString(R.string.alert_dialog_negative),
+                mNegativeButton.getText());
+
+        assertFalse(mActivity.isPositiveButtonClicked);
+        performClick(mPositiveButton);
+        assertTrue(mActivity.isPositiveButtonClicked);
+
+        assertFalse(mActivity.isNegativeButtonClicked);
+        performClick(mNegativeButton);
+        assertTrue(mActivity.isNegativeButtonClicked);
+
+        assertFalse(mActivity.isNeutralButtonClicked);
+        performClick(mNeutralButton);
+        assertTrue(mActivity.isNeutralButtonClicked);
+    }
+
+    public void testAlertDialogDeprecatedAPI() throws Throwable {
+        doTestAlertDialog(DialogStubActivity.TEST_ALERTDIALOG_DEPRECATED);
+    }
+
+    private void testAlertDialogAPIWithMessage(final boolean useDeprecatedAPIs) throws Throwable {
+        startDialogActivity(useDeprecatedAPIs
+                ? DialogStubActivity.TEST_ALERTDIALOG_DEPRECATED_WITH_MESSAGE
+                : DialogStubActivity.TEST_ALERTDIALOG_WITH_MESSAGE);
+
+        assertTrue(mActivity.getDialog().isShowing());
+
+        mPositiveButton = ((AlertDialog) (mActivity.getDialog())).getButton(
+                DialogInterface.BUTTON_POSITIVE);
+        assertNotNull(mPositiveButton);
+        assertEquals(mActivity.getString(R.string.alert_dialog_positive),
+                mPositiveButton.getText());
+        mNegativeButton = ((AlertDialog) (mActivity.getDialog())).getButton(
+                DialogInterface.BUTTON_NEGATIVE);
+        assertNotNull(mNegativeButton);
+        assertEquals(mActivity.getString(R.string.alert_dialog_negative),
+                mNegativeButton.getText());
+        mNeutralButton = ((AlertDialog) (mActivity.getDialog())).getButton(
+                DialogInterface.BUTTON_NEUTRAL);
+        assertNotNull(mNeutralButton);
+        assertEquals(mActivity.getString(R.string.alert_dialog_neutral),
+                mNeutralButton.getText());
+
+        DialogStubActivity.buttonIndex = 0;
+        performClick(mPositiveButton);
+        assertEquals(DialogInterface.BUTTON_POSITIVE, DialogStubActivity.buttonIndex);
+
+        DialogStubActivity.buttonIndex = 0;
+        performClick(mNeutralButton);
+        assertEquals(DialogInterface.BUTTON_NEUTRAL, DialogStubActivity.buttonIndex);
+
+        DialogStubActivity.buttonIndex = 0;
+        performClick(mNegativeButton);
+        assertEquals(DialogInterface.BUTTON_NEGATIVE, DialogStubActivity.buttonIndex);
+    }
+
+    public void testAlertDialogAPIWithMessageDeprecated() throws Throwable {
+        testAlertDialogAPIWithMessage(true);
+    }
+
+    public void testAlertDialogAPIWithMessageNotDeprecated() throws Throwable {
+        testAlertDialogAPIWithMessage(false);
+    }
+
+    private void performClick(final Button button) throws Throwable {
+        runTestOnUiThread(() -> button.performClick());
+        mInstrumentation.waitForIdleSync();
+    }
+
+    public void testCustomAlertDialog() {
+        startDialogActivity(DialogStubActivity.TEST_CUSTOM_ALERTDIALOG);
+        assertTrue(mActivity.getDialog().isShowing());
+    }
+
+    public void testCustomAlertDialogView() {
+        startDialogActivity(DialogStubActivity.TEST_CUSTOM_ALERTDIALOG_VIEW);
+        assertTrue(mActivity.getDialog().isShowing());
+    }
+
+    public void testCallback() {
+        startDialogActivity(DialogStubActivity.TEST_ALERTDIALOG_CALLBACK);
+        assertTrue(mActivity.onCreateCalled);
+
+        mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_0);
+        assertTrue(mActivity.onKeyDownCalled);
+        mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_0);
+        assertTrue(mActivity.onKeyUpCalled);
+    }
+
+    public void testAlertDialogTheme() throws Exception {
+        startDialogActivity(DialogStubActivity.TEST_ALERTDIALOG_THEME);
+        assertTrue(mActivity.getDialog().isShowing());
+    }
+
+    public void testAlertDialogCancelable() throws Exception {
+        startDialogActivity(DialogStubActivity.TEST_ALERTDIALOG_CANCELABLE);
+        assertTrue(mActivity.getDialog().isShowing());
+        assertFalse(mActivity.onCancelCalled);
+        mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_BACK);
+        mInstrumentation.waitForIdleSync();
+        assertTrue(mActivity.onCancelCalled);
+    }
+
+    public void testAlertDialogNotCancelable() throws Exception {
+        startDialogActivity(DialogStubActivity.TEST_ALERTDIALOG_NOT_CANCELABLE);
+        assertTrue(mActivity.getDialog().isShowing());
+        assertFalse(mActivity.onCancelCalled);
+        mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_BACK);
+        assertFalse(mActivity.onCancelCalled);
+    }
+
+    public void testAlertDialogIconDrawable() {
+        startDialogActivity(DialogStubActivity.TEST_ALERT_DIALOG_ICON_DRAWABLE);
+        assertTrue(mActivity.getDialog().isShowing());
+    }
+
+    public void testAlertDialogIconAttribute() {
+        startDialogActivity(DialogStubActivity.TEST_ALERT_DIALOG_ICON_ATTRIBUTE);
+        assertTrue(mActivity.getDialog().isShowing());
+    }
+}
diff --git a/tests/app/src/android/app/cts/AlertDialog_BuilderCursorTest.java b/tests/app/src/android/app/cts/AlertDialog_BuilderCursorTest.java
new file mode 100644
index 0000000..972afe6
--- /dev/null
+++ b/tests/app/src/android/app/cts/AlertDialog_BuilderCursorTest.java
@@ -0,0 +1,247 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.cts;
+
+import android.app.AlertDialog;
+import android.app.AlertDialog.Builder;
+import android.app.Instrumentation;
+import android.app.stubs.DialogStubActivity;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnClickListener;
+import android.content.DialogInterface.OnMultiChoiceClickListener;
+import android.cts.util.PollingCheck;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteCursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.support.test.InstrumentationRegistry;
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.widget.ListView;
+
+import java.io.File;
+
+import static org.mockito.Mockito.*;
+
+@MediumTest
+public class AlertDialog_BuilderCursorTest
+        extends ActivityInstrumentationTestCase2<DialogStubActivity> {
+    private Builder mBuilder;
+    private Context mContext;
+    private Instrumentation mInstrumentation;
+    private AlertDialog mDialog;
+    private ListView mListView;
+
+    private static final String TEXT_COLUMN_NAME = "text";
+    private static final String CHECKED_COLUMN_NAME = "checked";
+
+    private String[] mTextContent;
+    private boolean[] mCheckedContent;
+
+    private String[] mProjectionWithChecked;
+    private String[] mProjectionWithoutChecked;
+
+    private SQLiteDatabase mDatabase;
+    private File mDatabaseFile;
+    private Cursor mCursor;
+
+    private OnClickListener mOnClickListener = mock(OnClickListener.class);
+
+    /**
+     * Multi-choice click listener that is registered on our {@link AlertDialog} when it's in
+     * multi-choide mode. Note that this needs to be a separate class that is also protected (not
+     * private) so that Mockito can "spy" on it.
+     */
+    protected class MultiChoiceClickListener implements OnMultiChoiceClickListener {
+        private boolean[] mCheckedTracker;
+
+        public MultiChoiceClickListener(boolean[] checkedTracker) {
+            mCheckedTracker = checkedTracker;
+        }
+
+        @Override
+        public void onClick(DialogInterface dialog, int which,
+                boolean isChecked) {
+            // Update the underlying database with the new checked
+            // state for the specific row
+            mCursor.moveToPosition(which);
+            ContentValues valuesToUpdate = new ContentValues();
+            valuesToUpdate.put(CHECKED_COLUMN_NAME, isChecked ? 1 : 0);
+            mDatabase.update("test", valuesToUpdate,
+                    TEXT_COLUMN_NAME + " = ?",
+                    new String[] { mCursor.getString(1) } );
+            mCursor.requery();
+            mCheckedTracker[which] = isChecked;
+        }
+    }
+
+    public AlertDialog_BuilderCursorTest() {
+        super("android.app.stubs", DialogStubActivity.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mBuilder = null;
+        mInstrumentation = getInstrumentation();
+        mContext = getActivity();
+
+        PollingCheck.waitFor(() -> getActivity().hasWindowFocus());
+
+        mListView = null;
+        mDialog = null;
+
+        // Local test data for the tests
+        mTextContent = new String[] { "Adele", "Beyonce", "Ciara", "Dido" };
+        mCheckedContent = new boolean[] { false, false, true, false };
+
+        // Two projections - one with "checked" column and one without
+        mProjectionWithChecked = new String[] {
+                "_id",                       // 0
+                TEXT_COLUMN_NAME,            // 1
+                CHECKED_COLUMN_NAME          // 2
+        };
+        mProjectionWithoutChecked = new String[] {
+                "_id",                       // 0
+                TEXT_COLUMN_NAME             // 1
+        };
+
+        File dbDir = mContext.getDir("tests", Context.MODE_PRIVATE);
+        mDatabaseFile = new File(dbDir, "database_alert_dialog_test.db");
+        if (mDatabaseFile.exists()) {
+            mDatabaseFile.delete();
+        }
+        mDatabase = SQLiteDatabase.openOrCreateDatabase(mDatabaseFile.getPath(), null);
+        assertNotNull(mDatabase);
+        // Create and populate a test table
+        mDatabase.execSQL(
+                "CREATE TABLE test (_id INTEGER PRIMARY KEY, " + TEXT_COLUMN_NAME +
+                        " TEXT, " + CHECKED_COLUMN_NAME + " INTEGER);");
+        for (int i = 0; i < mTextContent.length; i++) {
+            mDatabase.execSQL("INSERT INTO test (" + TEXT_COLUMN_NAME + ", " +
+                    CHECKED_COLUMN_NAME + ") VALUES ('" + mTextContent[i] + "', " +
+                    (mCheckedContent[i] ? "1" : "0") + ");");
+        }
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        if (mCursor != null) {
+            // Close the cursor on the UI thread as the list view in the alert dialog
+            // will get notified of any change to the underlying cursor.
+            InstrumentationRegistry.getInstrumentation().runOnMainSync(
+                    () -> {
+                        mCursor.close();
+                        mCursor = null;
+                    });
+        }
+        if (mDatabase != null) {
+            mDatabase.close();
+        }
+        if (mDatabaseFile != null) {
+            mDatabaseFile.delete();
+        }
+
+        super.tearDown();
+    }
+
+    public void testSetCursor() throws Throwable {
+        // Use a projection without "checked" column
+        mCursor = mDatabase.query("test", mProjectionWithoutChecked,
+                null, null, null, null, null);
+        assertNotNull(mCursor);
+
+        runTestOnUiThread(
+                () -> {
+                    mBuilder = new Builder(mContext);
+                    mBuilder.setCursor(mCursor, mOnClickListener, TEXT_COLUMN_NAME);
+                    mDialog = mBuilder.show();
+                    mListView = mDialog.getListView();
+                    mListView.performItemClick(null, 0, 0);
+                });
+        mInstrumentation.waitForIdleSync();
+        final SQLiteCursor selected = (SQLiteCursor) mListView.getSelectedItem();
+        assertEquals(mCursor.getString(1), selected.getString(1));
+        verify(mOnClickListener, times(1)).onClick(mDialog, 0);
+        verifyNoMoreInteractions(mOnClickListener);
+    }
+
+    public void testSetSingleChoiceItemsWithParamCursor() throws Throwable {
+        // Use a projection without "checked" column
+        mCursor = mDatabase.query("test", mProjectionWithoutChecked,
+                null, null, null, null, null);
+        assertNotNull(mCursor);
+
+        runTestOnUiThread(
+                () -> {
+                    mBuilder = new Builder(mContext);
+                    mBuilder.setSingleChoiceItems(mCursor, 0, TEXT_COLUMN_NAME, mOnClickListener);
+                    mDialog = mBuilder.show();
+                    mListView = mDialog.getListView();
+                    mListView.performItemClick(null, 0, 0);
+                });
+        mInstrumentation.waitForIdleSync();
+        final SQLiteCursor selected = (SQLiteCursor) mListView.getSelectedItem();
+        assertEquals(mCursor.getString(1), selected.getString(1));
+        verify(mOnClickListener, times(1)).onClick(mDialog, 0);
+        verifyNoMoreInteractions(mOnClickListener);
+    }
+
+    public void testSetMultiChoiceItemsWithParamCursor() throws Throwable {
+        mCursor = mDatabase.query("test", mProjectionWithChecked,
+                null, null, null, null, null);
+        assertNotNull(mCursor);
+
+        final boolean[] checkedTracker = mCheckedContent.clone();
+        final OnMultiChoiceClickListener mockMultiChoiceClickListener =
+                spy(new MultiChoiceClickListener(checkedTracker));
+        runTestOnUiThread(
+                () -> {
+                    mBuilder = new Builder(mContext);
+                    mBuilder.setMultiChoiceItems(mCursor, CHECKED_COLUMN_NAME, TEXT_COLUMN_NAME,
+                            mockMultiChoiceClickListener);
+                    mDialog = mBuilder.show();
+                    mListView = mDialog.getListView();
+                    mListView.performItemClick(null, 0, 0);
+                });
+        mInstrumentation.waitForIdleSync();
+
+        SQLiteCursor selected = (SQLiteCursor) mListView.getSelectedItem();
+        assertEquals(mCursor.getString(0), selected.getString(0));
+        verify(mockMultiChoiceClickListener, times(1)).onClick(mDialog, 0, true);
+        // Verify that our multi-choice listener was invoked to update our tracker array
+        assertTrue(checkedTracker[0]);
+        assertFalse(checkedTracker[1]);
+        assertTrue(checkedTracker[2]);
+        assertFalse(checkedTracker[3]);
+
+        runTestOnUiThread(() -> mListView.performItemClick(null, 1, 1));
+        mInstrumentation.waitForIdleSync();
+
+        selected = (SQLiteCursor) mListView.getSelectedItem();
+        assertEquals(mCursor.getString(1), selected.getString(1));
+        verify(mockMultiChoiceClickListener, times(1)).onClick(mDialog, 1, true);
+        // Verify that our multi-choice listener was invoked to update our tracker array
+        assertTrue(checkedTracker[0]);
+        assertTrue(checkedTracker[1]);
+        assertTrue(checkedTracker[2]);
+        assertFalse(checkedTracker[3]);
+
+        verifyNoMoreInteractions(mockMultiChoiceClickListener);
+    }
+}
diff --git a/tests/app/src/android/app/cts/AlertDialog_BuilderTest.java b/tests/app/src/android/app/cts/AlertDialog_BuilderTest.java
new file mode 100644
index 0000000..710c8d6
--- /dev/null
+++ b/tests/app/src/android/app/cts/AlertDialog_BuilderTest.java
@@ -0,0 +1,685 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.cts;
+
+import android.app.AlertDialog;
+import android.app.AlertDialog.Builder;
+import android.app.Instrumentation;
+import android.app.stubs.DialogStubActivity;
+import android.app.stubs.R;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnCancelListener;
+import android.content.DialogInterface.OnClickListener;
+import android.content.DialogInterface.OnDismissListener;
+import android.content.DialogInterface.OnKeyListener;
+import android.content.DialogInterface.OnMultiChoiceClickListener;
+import android.content.res.TypedArray;
+import android.cts.util.PollingCheck;
+import android.graphics.drawable.Drawable;
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.AdapterView.OnItemSelectedListener;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.ListAdapter;
+import android.widget.ListView;
+import org.mockito.ArgumentCaptor;
+
+import static org.mockito.Mockito.*;
+
+@SmallTest
+public class AlertDialog_BuilderTest extends ActivityInstrumentationTestCase2<DialogStubActivity> {
+    private Builder mBuilder;
+    private Context mContext;
+    private Instrumentation mInstrumentation;
+    private final CharSequence mTitle = "title";
+    private Drawable mDrawable;
+    private AlertDialog mDialog;
+    private Button mButton;
+    private CharSequence mSelectedItem;
+
+    private View mView;
+    private ListView mListView;
+
+    private OnClickListener mOnClickListener = mock(OnClickListener.class);
+
+    private OnCancelListener mOnCancelListener = mock(OnCancelListener.class);
+
+    private OnDismissListener mOnDismissListener = mock(OnDismissListener.class);
+
+    private OnKeyListener mOnKeyListener = mock(OnKeyListener.class);
+
+    private OnItemSelectedListener mOnItemSelectedListener = mock(OnItemSelectedListener.class);
+
+    private OnMultiChoiceClickListener mOnMultiChoiceClickListener =
+            mock(OnMultiChoiceClickListener.class);
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mBuilder = null;
+        mInstrumentation = getInstrumentation();
+        mContext = getActivity();
+
+        PollingCheck.waitFor(() -> getActivity().hasWindowFocus());
+
+        mButton = null;
+        mView = null;
+        mListView = null;
+        mDialog = null;
+        mSelectedItem = null;
+    }
+
+    public AlertDialog_BuilderTest() {
+        super("android.app.stubs", DialogStubActivity.class);
+    }
+
+    public void testConstructor() {
+        new AlertDialog.Builder(mContext);
+    }
+
+    public void testConstructorWithThemeId() {
+        mBuilder = new AlertDialog.Builder(mContext, R.style.DialogTheme_Test);
+
+        // Get the context from the builder and attempt to resolve a custom attribute
+        // set on our theme. This way we verify that our theme has been applied to the
+        // builder.
+        final Context themedContext = mBuilder.getContext();
+        int[] attrs = new int[] { R.attr.themeInteger };
+        TypedArray ta = themedContext.obtainStyledAttributes(attrs);
+        assertEquals(20, ta.getInt(0, 0));
+    }
+
+    public void testSetIconWithParamInt() throws Throwable {
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                mDrawable = mContext.getResources().getDrawable(android.R.drawable.btn_default);
+                mBuilder = new AlertDialog.Builder(mContext);
+                mBuilder.setIcon(android.R.drawable.btn_default);
+                mDialog = mBuilder.show();
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+    }
+
+    public void testSetIconWithParamDrawable() throws Throwable {
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                mDrawable = mContext.getResources().getDrawable(android.R.drawable.btn_default);
+                mBuilder = new AlertDialog.Builder(mContext);
+                mBuilder.setIcon(mDrawable);
+                mDialog = mBuilder.show();
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+    }
+
+    public void testSetIconAttribute() throws Throwable {
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                mDrawable = mContext.getResources().getDrawable(android.R.drawable.btn_default);
+                mBuilder = new AlertDialog.Builder(mContext);
+                mBuilder.setIconAttribute(android.R.attr.alertDialogIcon);
+                mDialog = mBuilder.show();
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+    }
+
+    public void testSetPositiveButtonWithParamInt() throws Throwable {
+       runTestOnUiThread(new Runnable() {
+            public void run() {
+                mBuilder = new AlertDialog.Builder(mContext);
+                mBuilder.setPositiveButton(android.R.string.yes, mOnClickListener);
+                mBuilder.setOnDismissListener(mOnDismissListener);
+                mDialog = mBuilder.show();
+                mButton = mDialog.getButton(DialogInterface.BUTTON_POSITIVE);
+                mButton.performClick();
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+
+        assertEquals(mContext.getText(android.R.string.yes), mButton.getText());
+        verify(mOnClickListener, times(1)).onClick(mDialog, DialogInterface.BUTTON_POSITIVE);
+        verifyNoMoreInteractions(mOnClickListener);
+        // Button click should also dismiss the dialog and notify the listener
+        verify(mOnDismissListener, times(1)).onDismiss(mDialog);
+        verifyNoMoreInteractions(mOnDismissListener);
+    }
+
+    public void testSetPositiveButtonWithParamCharSequence() throws Throwable {
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                mBuilder = new AlertDialog.Builder(mContext);
+                mBuilder.setPositiveButton(android.R.string.yes, mOnClickListener);
+                mBuilder.setOnDismissListener(mOnDismissListener);
+                mDialog = mBuilder.show();
+                mButton = mDialog.getButton(DialogInterface.BUTTON_POSITIVE);
+                mButton.performClick();
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+        assertEquals(mContext.getText(android.R.string.yes), mButton.getText());
+        verify(mOnClickListener, times(1)).onClick(mDialog, DialogInterface.BUTTON_POSITIVE);
+        verifyNoMoreInteractions(mOnClickListener);
+        // Button click should also dismiss the dialog and notify the listener
+        verify(mOnDismissListener, times(1)).onDismiss(mDialog);
+        verifyNoMoreInteractions(mOnDismissListener);
+    }
+
+    public void testSetNegativeButtonWithParamCharSequence() throws Throwable {
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                mBuilder = new AlertDialog.Builder(mContext);
+                mBuilder.setNegativeButton(mTitle, mOnClickListener);
+                mBuilder.setOnDismissListener(mOnDismissListener);
+                mDialog = mBuilder.show();
+                mButton = mDialog.getButton(DialogInterface.BUTTON_NEGATIVE);
+                mButton.performClick();
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+        assertEquals(mTitle, mButton.getText());
+        verify(mOnClickListener, times(1)).onClick(mDialog, DialogInterface.BUTTON_NEGATIVE);
+        verifyNoMoreInteractions(mOnClickListener);
+        // Button click should also dismiss the dialog and notify the listener
+        verify(mOnDismissListener, times(1)).onDismiss(mDialog);
+        verifyNoMoreInteractions(mOnDismissListener);
+    }
+
+    public void testSetNegativeButtonWithParamInt() throws Throwable {
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                mBuilder = new AlertDialog.Builder(mContext);
+                mBuilder.setNegativeButton(R.string.notify, mOnClickListener);
+                mBuilder.setOnDismissListener(mOnDismissListener);
+                mDialog = mBuilder.show();
+                mButton = mDialog.getButton(DialogInterface.BUTTON_NEGATIVE);
+                mButton.performClick();
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+        assertEquals(mContext.getText(R.string.notify), mButton.getText());
+        verify(mOnClickListener, times(1)).onClick(mDialog, DialogInterface.BUTTON_NEGATIVE);
+        verifyNoMoreInteractions(mOnClickListener);
+        // Button click should also dismiss the dialog and notify the listener
+        verify(mOnDismissListener, times(1)).onDismiss(mDialog);
+        verifyNoMoreInteractions(mOnDismissListener);
+    }
+
+    public void testSetNeutralButtonWithParamInt() throws Throwable {
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                mBuilder = new AlertDialog.Builder(mContext);
+                mBuilder.setNeutralButton(R.string.notify, mOnClickListener);
+                mBuilder.setOnDismissListener(mOnDismissListener);
+                mDialog = mBuilder.show();
+                mButton = mDialog.getButton(DialogInterface.BUTTON_NEUTRAL);
+                mButton.performClick();
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+        assertEquals(mContext.getText(R.string.notify), mButton.getText());
+        verify(mOnClickListener, times(1)).onClick(mDialog, DialogInterface.BUTTON_NEUTRAL);
+        verifyNoMoreInteractions(mOnClickListener);
+        // Button click should also dismiss the dialog and notify the listener
+        verify(mOnDismissListener, times(1)).onDismiss(mDialog);
+        verifyNoMoreInteractions(mOnDismissListener);
+    }
+
+    public void testSetNeutralButtonWithParamCharSequence() throws Throwable {
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                mBuilder = new AlertDialog.Builder(mContext);
+                mBuilder.setNeutralButton(mTitle, mOnClickListener);
+                mBuilder.setOnDismissListener(mOnDismissListener);
+                mDialog = mBuilder.show();
+                mButton = mDialog.getButton(DialogInterface.BUTTON_NEUTRAL);
+                mButton.performClick();
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+        assertEquals(mTitle, mButton.getText());
+        verify(mOnClickListener, times(1)).onClick(mDialog, DialogInterface.BUTTON_NEUTRAL);
+        verifyNoMoreInteractions(mOnClickListener);
+        // Button click should also dismiss the dialog and notify the listener
+        verify(mOnDismissListener, times(1)).onDismiss(mDialog);
+        verifyNoMoreInteractions(mOnDismissListener);
+    }
+
+    private void testCancelable(final boolean cancelable) throws Throwable {
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                mBuilder = new AlertDialog.Builder(mContext);
+                mBuilder.setCancelable(cancelable);
+                mDialog = mBuilder.show();
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+        new PollingCheck() {
+            @Override
+            protected boolean check() {
+                return mDialog.isShowing();
+            }
+        }.run();
+        mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_BACK);
+        mInstrumentation.waitForIdleSync();
+        new PollingCheck() {
+            @Override
+            protected boolean check() {
+                boolean showing = mDialog.isShowing();
+                if (cancelable) {
+                    // if the dialog is cancelable, then pressing back
+                    // should cancel it. Thus it should not be showing
+                    return !showing;
+                } else {
+                    // if the dialog is not cancelable, pressing back
+                    // should so nothing and it should still be showing
+                    return showing;
+                }
+            }
+        }.run();
+    }
+
+    public void testSetCancelable() throws Throwable {
+        testCancelable(true);
+    }
+
+    public void testDisableCancelable() throws Throwable {
+        testCancelable(false);
+    }
+
+    public void testSetOnCancelListener() throws Throwable {
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                mBuilder = new AlertDialog.Builder(mContext);
+                mBuilder.setOnCancelListener(mOnCancelListener);
+                mDialog = mBuilder.show();
+                mDialog.cancel();
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+        verify(mOnCancelListener, times(1)).onCancel(mDialog);
+        verifyNoMoreInteractions(mOnCancelListener);
+    }
+
+    public void testSetOnDismissListener() throws Throwable {
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                mBuilder = new AlertDialog.Builder(mContext);
+                mBuilder.setOnDismissListener(mOnDismissListener);
+                mDialog = mBuilder.show();
+                mDialog.dismiss();
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+        verify(mOnDismissListener, times(1)).onDismiss(mDialog);
+        verifyNoMoreInteractions(mOnDismissListener);
+    }
+
+    public void testSetOnKeyListener() throws Throwable {
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                mBuilder = new AlertDialog.Builder(mContext);
+                mBuilder.setOnKeyListener(mOnKeyListener);
+                mDialog = mBuilder.show();
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+        sendKeys(KeyEvent.KEYCODE_0, KeyEvent.KEYCODE_1);
+        // Use Mockito captures so that we can verify that each "sent" key code resulted
+        // in one DOWN event and one UP event.
+        ArgumentCaptor<KeyEvent> keyEvent0Captor = ArgumentCaptor.forClass(KeyEvent.class);
+        ArgumentCaptor<KeyEvent> keyEvent1Captor = ArgumentCaptor.forClass(KeyEvent.class);
+        verify(mOnKeyListener, times(2)).onKey(eq(mDialog), eq(KeyEvent.KEYCODE_0),
+                keyEvent0Captor.capture());
+        verify(mOnKeyListener, times(2)).onKey(eq(mDialog), eq(KeyEvent.KEYCODE_1),
+                keyEvent1Captor.capture());
+        verifyNoMoreInteractions(mOnKeyListener);
+        assertEquals(KeyEvent.ACTION_DOWN, keyEvent0Captor.getAllValues().get(0).getAction());
+        assertEquals(KeyEvent.ACTION_UP, keyEvent0Captor.getAllValues().get(1).getAction());
+        assertEquals(KeyEvent.ACTION_DOWN, keyEvent1Captor.getAllValues().get(0).getAction());
+        assertEquals(KeyEvent.ACTION_UP, keyEvent1Captor.getAllValues().get(1).getAction());
+    }
+
+    public void testSetItemsWithParamInt() throws Throwable {
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                mBuilder = new AlertDialog.Builder(mContext);
+                mBuilder.setItems(R.array.difficultyLevel, mOnClickListener);
+                mDialog = mBuilder.show();
+                mListView = mDialog.getListView();
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+
+        final CharSequence[] levels = mContext.getResources().getTextArray(
+                R.array.difficultyLevel);
+        assertEquals(levels[0], mListView.getItemAtPosition(0));
+    }
+
+    public void testSetItemsWithParamCharSequence() throws Throwable {
+        final CharSequence[] expect = mContext.getResources().getTextArray(
+                R.array.difficultyLevel);
+
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                mBuilder = new AlertDialog.Builder(mContext);
+                mBuilder.setItems(expect, mOnClickListener);
+                mDialog = mBuilder.show();
+                mListView = mDialog.getListView();
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+        assertEquals(expect[0], mListView.getItemAtPosition(0));
+    }
+
+    public void testSetAdapter() throws Throwable {
+        final ListAdapter adapter = new AdapterTest();
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                mBuilder = new AlertDialog.Builder(mContext);
+                mBuilder.setAdapter(adapter, mOnClickListener);
+                mDialog = mBuilder.show();
+                mListView = mDialog.getListView();
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+        assertEquals(adapter, mListView.getAdapter());
+    }
+
+    public void testSetMultiChoiceItemsWithParamInt() throws Throwable {
+
+        final CharSequence[] items = mContext.getResources().getTextArray(
+                R.array.difficultyLevel);
+
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                mBuilder = new AlertDialog.Builder(mContext);
+                mBuilder.setMultiChoiceItems(R.array.difficultyLevel, null,
+                        mOnMultiChoiceClickListener);
+                mDialog = mBuilder.show();
+                mListView = mDialog.getListView();
+                mSelectedItem = (CharSequence)mListView.getSelectedItem();
+                mListView.performItemClick(null, 0, 0);
+                mListView.performItemClick(null, 1, 0);
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+        assertEquals(items[0], mSelectedItem);
+        verify(mOnMultiChoiceClickListener, times(1)).onClick(mDialog, 0, true);
+        verify(mOnMultiChoiceClickListener, times(1)).onClick(mDialog, 1, true);
+        verifyNoMoreInteractions(mOnMultiChoiceClickListener);
+        assertEquals(items[0], mListView.getItemAtPosition(0));
+    }
+
+    public void testSetMultiChoiceItemsWithParamCharSequence() throws Throwable {
+        final CharSequence[] items = mContext.getResources().getTextArray(
+                R.array.difficultyLevel);
+
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                mBuilder = new AlertDialog.Builder(mContext);
+                mBuilder.setMultiChoiceItems(items, null, mOnMultiChoiceClickListener);
+                mDialog = mBuilder.show();
+                mListView = mDialog.getListView();
+                mSelectedItem = (CharSequence)mListView.getSelectedItem();
+                mListView.performItemClick(null, 0, 0);
+                mListView.performItemClick(null, 1, 0);
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+        assertEquals(items[0], mSelectedItem);
+        verify(mOnMultiChoiceClickListener, times(1)).onClick(mDialog, 0, true);
+        verify(mOnMultiChoiceClickListener, times(1)).onClick(mDialog, 1, true);
+        verifyNoMoreInteractions(mOnMultiChoiceClickListener);
+        assertEquals(items[0], mListView.getItemAtPosition(0));
+    }
+
+    public void testSetSingleChoiceItemsWithParamInt() throws Throwable {
+        final CharSequence[] items = mContext.getResources().getTextArray(
+                R.array.difficultyLevel);
+
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                mBuilder = new AlertDialog.Builder(mContext);
+                mBuilder.setSingleChoiceItems(R.array.difficultyLevel, 0,
+                        mOnClickListener);
+                mDialog = mBuilder.show();
+                mListView = mDialog.getListView();
+                mSelectedItem = (CharSequence)mListView.getSelectedItem();
+                mListView.performItemClick(null, 0, 0);
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+        assertEquals(items[0], mSelectedItem);
+        assertEquals(items[0], mListView.getItemAtPosition(0));
+        verify(mOnClickListener, times(1)).onClick(mDialog, 0);
+        verifyNoMoreInteractions(mOnClickListener);
+    }
+
+    public void testSetSingleChoiceItemsWithParamCharSequence() throws Throwable {
+        final CharSequence[] items = mContext.getResources().getTextArray(
+                R.array.difficultyLevel);
+
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                mBuilder = new AlertDialog.Builder(mContext);
+                mBuilder.setSingleChoiceItems(items, 0, mOnClickListener);
+                mDialog = mBuilder.show();
+                mListView = mDialog.getListView();
+                mSelectedItem = (CharSequence)mListView.getSelectedItem();
+                mListView.performItemClick(null, 0, 0);
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+        assertEquals(items[0], mSelectedItem);
+        assertEquals(items[0], mListView.getItemAtPosition(0));
+        verify(mOnClickListener, times(1)).onClick(mDialog, 0);
+        verifyNoMoreInteractions(mOnClickListener);
+    }
+
+    public void testSetSingleChoiceItems() throws Throwable {
+        final CharSequence[] items = mContext.getResources().getTextArray(
+                R.array.difficultyLevel);
+
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                mBuilder = new AlertDialog.Builder(mContext);
+                mBuilder.setSingleChoiceItems(new ArrayAdapter<CharSequence>(mContext,
+                        android.R.layout.select_dialog_singlechoice, android.R.id.text1, items), 0,
+                        mOnClickListener);
+                mDialog = mBuilder.show();
+                mListView = mDialog.getListView();
+                mSelectedItem = (CharSequence)mListView.getSelectedItem();
+                mListView.performItemClick(null, 0, 0);
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+        assertEquals(items[0], mSelectedItem);
+        assertEquals(items[0], mListView.getItemAtPosition(0));
+        verify(mOnClickListener, times(1)).onClick(mDialog, 0);
+        verifyNoMoreInteractions(mOnClickListener);
+    }
+
+    public void testSetOnItemSelectedListener() throws Throwable {
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                mBuilder = new AlertDialog.Builder(mContext);
+                mBuilder.setOnItemSelectedListener(mOnItemSelectedListener);
+                mBuilder.setItems(R.array.difficultyLevel, mOnClickListener);
+                mDialog = mBuilder.show();
+                mListView = mDialog.getListView();
+                mListView.pointToPosition(0, 0);
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+        verify(mOnItemSelectedListener, times(1)).onItemSelected(eq(mListView), any(View.class),
+                eq(0), any(Long.class));
+        verifyNoMoreInteractions(mOnItemSelectedListener);
+    }
+
+    public void testSetView() throws Throwable {
+        final View view = new View(mContext);
+        view.setId(100);
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                mBuilder = new AlertDialog.Builder(mContext);
+                mBuilder.setView(view);
+                mDialog = mBuilder.show();
+                mView = mDialog.getWindow().findViewById(100);
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+        assertEquals(view, mView);
+    }
+
+    public void testSetViewFromInflater() throws Throwable {
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                mBuilder = new AlertDialog.Builder(mContext);
+                mBuilder.setView(LayoutInflater.from(mBuilder.getContext()).inflate(
+                        R.layout.alert_dialog_text_entry_2, null, false));
+                mDialog = mBuilder.show();
+                mView = mDialog.getWindow().findViewById(R.id.username_form);
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+        assertNotNull(mView);
+        assertNotNull(mView.findViewById(R.id.username_view));
+        assertNotNull(mView.findViewById(R.id.username_edit));
+    }
+
+    public void testSetViewById() throws Throwable {
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                mBuilder = new AlertDialog.Builder(mContext);
+                mBuilder.setView(R.layout.alert_dialog_text_entry_2);
+                mDialog = mBuilder.show();
+                mView = mDialog.getWindow().findViewById(R.id.username_form);
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+        assertNotNull(mView);
+        assertNotNull(mView.findViewById(R.id.username_view));
+        assertNotNull(mView.findViewById(R.id.username_edit));
+    }
+
+    public void testSetCustomTitle() throws Throwable {
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                mBuilder = new AlertDialog.Builder(mContext);
+                mBuilder.setCustomTitle(LayoutInflater.from(mBuilder.getContext()).inflate(
+                        R.layout.alertdialog_custom_title, null, false));
+                mDialog = mBuilder.show();
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+    }
+
+    public void testSetInverseBackgroundForced() throws Throwable {
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                mBuilder = new AlertDialog.Builder(mContext);
+                mBuilder.setInverseBackgroundForced(true);
+                mDialog = mBuilder.create();
+                mDialog.show();
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+    }
+
+    public void testCreate() throws Throwable {
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                mBuilder = new AlertDialog.Builder(mContext);
+                mDialog = mBuilder.create();
+                mDialog.show();
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+        assertNotNull(mDialog);
+        assertTrue(mDialog.isShowing());
+    }
+
+    public void testShow() throws Throwable {
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                mBuilder = new AlertDialog.Builder(mContext);
+                mDialog = mBuilder.show();
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+        assertTrue(mDialog.isShowing());
+    }
+
+    private static class AdapterTest implements android.widget.ListAdapter {
+        public boolean areAllItemsEnabled() {
+            return true;
+        }
+
+        public boolean isEnabled(int position) {
+            return false;
+        }
+
+        public int getCount() {
+            return 0;
+        }
+
+        public Object getItem(int position) {
+            return null;
+        }
+
+        public long getItemId(int position) {
+            return 0;
+        }
+
+        public int getItemViewType(int position) {
+            return 0;
+        }
+
+        public android.view.View getView( int position,
+                                          android.view.View convertView,
+                                          android.view.ViewGroup parent){
+            return null;
+        }
+
+        public int getViewTypeCount() {
+            return 1;
+        }
+
+        public boolean hasStableIds() {
+            return false;
+        }
+
+        public boolean isEmpty() {
+            return true;
+        }
+
+        public void registerDataSetObserver(
+            android.database.DataSetObserver observer) {
+        }
+
+        public void unregisterDataSetObserver(
+            android.database.DataSetObserver observer) {
+        }
+    }
+}
diff --git a/tests/app/src/android/app/cts/AliasActivityStub.java b/tests/app/src/android/app/cts/AliasActivityStub.java
deleted file mode 100644
index 977bdc3..0000000
--- a/tests/app/src/android/app/cts/AliasActivityStub.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-import android.app.AliasActivity;
-import android.os.Bundle;
-
-public class AliasActivityStub extends AliasActivity {
-
-    public static boolean isOnCreateCalled = false;
-    public static boolean isFinished = false;
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        isOnCreateCalled = true;
-    }
-
-    @Override
-    public void finish() {
-        super.finish();
-        isFinished = true;
-    }
-}
diff --git a/tests/app/src/android/app/cts/AliasActivityTest.java b/tests/app/src/android/app/cts/AliasActivityTest.java
new file mode 100644
index 0000000..d3fe06c
--- /dev/null
+++ b/tests/app/src/android/app/cts/AliasActivityTest.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.cts;
+
+import android.app.AliasActivity;
+import android.app.stubs.AliasActivityStub;
+import android.app.stubs.ChildActivity;
+import android.content.Context;
+import android.content.Intent;
+import android.test.InstrumentationTestCase;
+
+public class AliasActivityTest extends InstrumentationTestCase {
+
+    private static final long SLEEP_TIME = 1000;
+
+    public void testAliasActivity() throws Throwable {
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                new AliasActivity();
+            }
+        });
+        getInstrumentation().waitForIdleSync();
+        Context context = getInstrumentation().getTargetContext();
+
+        Intent intent = new Intent();
+        intent.setClass(context, AliasActivityStub.class);
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
+        assertFalse(ChildActivity.isStarted);
+        assertFalse(AliasActivityStub.isOnCreateCalled);
+        context.startActivity(intent);
+        Thread.sleep(SLEEP_TIME);
+        assertTrue(AliasActivityStub.isOnCreateCalled);
+        assertTrue(ChildActivity.isStarted);
+        assertTrue(AliasActivityStub.isFinished);
+    }
+
+}
diff --git a/tests/app/src/android/app/cts/AppStubActivity.java b/tests/app/src/android/app/cts/AppStubActivity.java
deleted file mode 100644
index da5e55a..0000000
--- a/tests/app/src/android/app/cts/AppStubActivity.java
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-import android.app.Activity;
-import android.app.Dialog;
-import android.content.res.Resources;
-import android.os.Bundle;
-import android.view.ContextMenu;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.ContextMenu.ContextMenuInfo;
-
-import com.android.cts.app.stub.R;
-
-/**
- * A minimal "Hello, World!" application.
- */
-public class AppStubActivity extends Activity {
-    private Dialog mDialog;
-    public boolean mOnPrepareDialog;
-    public boolean mOnOptionsMenuClosedCalled;
-    public boolean mOnPrepareOptionsMenuCalled;
-    public boolean mOnOptionsItemSelectedCalled;
-    public boolean mOnCreateOptionsMenu;
-    public boolean mIndterminate = false;
-    public boolean mIndterminatevisibility = false;
-    public boolean mSecPro = false;
-    public boolean mOnContextItemSelectedCalled;
-    public boolean mOnCreateContextMenu;
-    public boolean mApplyResourceCalled;
-    public boolean mCreateContextMenuCalled;
-    public boolean mRequestWinFeatureRet = false;
-
-    public AppStubActivity() {
-
-    }
-
-    public void finalize() {
-        try {
-            super.finalize();
-        } catch (Throwable exception) {
-            System.err.print("exception!");
-        }
-    }
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState){
-        super.onCreate(savedInstanceState);
-        mRequestWinFeatureRet = requestWindowFeature(1);
-        setContentView(R.layout.app_activity);
-    }
-
-    public Dialog getDialogById(int id) {
-        return mDialog;
-    }
-
-    @Override
-    public Dialog onCreateDialog(int id) {
-        super.onCreateDialog(id);
-        mDialog = new Dialog(this);
-        return mDialog;
-    }
-
-    @Override
-    protected void onPrepareDialog(int id, Dialog dialog) {
-        super.onPrepareDialog(id, dialog);
-        mOnPrepareDialog = true;
-    }
-
-    @Override
-    public void onOptionsMenuClosed(Menu menu) {
-        super.onOptionsMenuClosed(menu);
-        mOnOptionsMenuClosedCalled = true;
-    }
-
-    @Override
-    public boolean onPrepareOptionsMenu(Menu menu) {
-        mOnPrepareOptionsMenuCalled = true;
-        return super.onPrepareOptionsMenu(menu);
-    }
-
-    @Override
-    public boolean onCreateOptionsMenu(Menu menu) {
-        mOnCreateOptionsMenu = true;
-        if(menu != null)
-            menu.add(0, 0, 0, "Fake Item");
-        return super.onCreateOptionsMenu(menu);
-    }
-
-    @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
-        mOnOptionsItemSelectedCalled = true;
-        return super.onOptionsItemSelected(item);
-    }
-
-    public boolean setProBarIndeterminate(boolean indeterminate){
-        mIndterminate = indeterminate;
-        super.setProgressBarIndeterminate(indeterminate);
-        return mIndterminate;
-    }
-
-    public boolean setProBarIndeterminateVisibility(boolean visible){
-        mIndterminatevisibility = visible;
-        super.setProgressBarIndeterminateVisibility(visible);
-        return mIndterminatevisibility;
-    }
-
-    public boolean setSecPro(int secPro){
-        mSecPro = true;
-        super.setSecondaryProgress(secPro);
-        return mSecPro;
-    }
-
-    @Override
-    public boolean onContextItemSelected(MenuItem item){
-        mOnContextItemSelectedCalled = true;
-        return super.onContextItemSelected(item);
-    }
-
-    @Override
-    public void onApplyThemeResource( Resources.Theme theme,
-                                      int resid,
-                                      boolean first){
-        super.onApplyThemeResource(theme,resid,first);
-        mApplyResourceCalled = true;
-    }
-
-    @Override
-    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
-        super.onCreateContextMenu(menu,v,menuInfo);
-        mCreateContextMenuCalled = true;
-    }
-}
-
diff --git a/tests/app/src/android/app/cts/ApplicationTest.java b/tests/app/src/android/app/cts/ApplicationTest.java
new file mode 100644
index 0000000..aaed064
--- /dev/null
+++ b/tests/app/src/android/app/cts/ApplicationTest.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.cts;
+
+import android.app.Activity;
+import android.app.Application;
+import android.app.Instrumentation;
+import android.app.stubs.MockApplication;
+import android.app.stubs.MockApplicationActivity;
+import android.app.stubs.OrientationTestUtils;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.test.InstrumentationTestCase;
+
+/**
+ * Test {@link Application}.
+ */
+public class ApplicationTest extends InstrumentationTestCase {
+
+    public void testApplication() throws Throwable {
+        final Instrumentation instrumentation = getInstrumentation();
+        final Context targetContext = instrumentation.getTargetContext();
+
+        final Intent intent = new Intent(targetContext, MockApplicationActivity.class);
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
+        final Activity activity = instrumentation.startActivitySync(intent);
+        final MockApplication mockApp = (MockApplication) activity.getApplication();
+        assertTrue(mockApp.isConstructorCalled);
+        assertTrue(mockApp.isOnCreateCalled);
+
+        //skip if the device doesn't support both of portrait and landscape orientation screens.
+        final PackageManager pm = targetContext.getPackageManager();
+        if(!(pm.hasSystemFeature(PackageManager.FEATURE_SCREEN_LANDSCAPE)
+                && pm.hasSystemFeature(PackageManager.FEATURE_SCREEN_PORTRAIT))){
+            return;
+        }
+
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+               OrientationTestUtils.toggleOrientation(activity);
+            }
+        });
+        instrumentation.waitForIdleSync();
+        assertTrue(mockApp.isOnConfigurationChangedCalled);
+    }
+
+}
diff --git a/tests/app/src/android/app/cts/AutomaticZenRuleTest.java b/tests/app/src/android/app/cts/AutomaticZenRuleTest.java
new file mode 100644
index 0000000..37972b6
--- /dev/null
+++ b/tests/app/src/android/app/cts/AutomaticZenRuleTest.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.cts;
+
+import android.app.AutomaticZenRule;
+import android.app.NotificationManager;
+import android.content.ComponentName;
+import android.net.Uri;
+import android.os.Parcel;
+import android.test.AndroidTestCase;
+
+public class AutomaticZenRuleTest extends AndroidTestCase {
+
+    private final String mName = "name";
+    private final ComponentName mOwner = new ComponentName("pkg", "cls");
+    private final Uri mConditionId = new Uri.Builder().scheme("scheme")
+            .authority("authority")
+            .appendPath("path")
+            .appendPath("test")
+            .build();
+    private final int mInterruptionFilter = NotificationManager.INTERRUPTION_FILTER_NONE;
+    private final boolean mEnabled = true;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+    }
+
+    public void testDescribeContents() {
+        final int expected = 0;
+        AutomaticZenRule rule = new AutomaticZenRule(mName, mOwner, mConditionId,
+                mInterruptionFilter, mEnabled);
+        assertEquals(expected, rule.describeContents());
+    }
+
+    public void testWriteToParcel() {
+        AutomaticZenRule rule = new AutomaticZenRule(mName, mOwner, mConditionId,
+                mInterruptionFilter, mEnabled);
+        Parcel parcel = Parcel.obtain();
+        rule.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        AutomaticZenRule rule1 = new AutomaticZenRule(parcel);
+        assertEquals(mName, rule1.getName());
+        assertEquals(mOwner, rule1.getOwner());
+        assertEquals(mConditionId, rule1.getConditionId());
+        assertEquals(mInterruptionFilter, rule1.getInterruptionFilter());
+        assertEquals(mEnabled, rule1.isEnabled());
+
+        rule.setName(null);
+        parcel = Parcel.obtain();
+        rule.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        rule1 = new AutomaticZenRule(parcel);
+        assertNull(rule1.getName());
+    }
+
+    public void testSetConditionId() {
+        final Uri newConditionId = new Uri.Builder().scheme("scheme")
+                .authority("authority2")
+                .appendPath("3path")
+                .appendPath("test4")
+                .build();
+        AutomaticZenRule rule = new AutomaticZenRule(mName, mOwner, mConditionId,
+                mInterruptionFilter, mEnabled);
+        rule.setConditionId(newConditionId);
+        assertEquals(newConditionId, rule.getConditionId());
+    }
+
+    public void testSetEnabled() {
+        AutomaticZenRule rule = new AutomaticZenRule(mName, mOwner, mConditionId,
+                mInterruptionFilter, mEnabled);
+        rule.setEnabled(!mEnabled);
+        assertEquals(!mEnabled, rule.isEnabled());
+    }
+
+    public void testSetInterruptionFilter() {
+        AutomaticZenRule rule = new AutomaticZenRule(mName, mOwner, mConditionId,
+                mInterruptionFilter, mEnabled);
+        for (int i = NotificationManager.INTERRUPTION_FILTER_UNKNOWN;
+             i <= NotificationManager.INTERRUPTION_FILTER_ALARMS; i++) {
+            rule.setInterruptionFilter(i);
+            assertEquals(i, rule.getInterruptionFilter());
+        }
+    }
+
+    public void testSetName() {
+        AutomaticZenRule rule = new AutomaticZenRule(mName, mOwner, mConditionId,
+                mInterruptionFilter, mEnabled);
+        rule.setName(mName + "new");
+        assertEquals(mName + "new", rule.getName());
+    }
+}
diff --git a/tests/app/src/android/app/cts/CTSActivityTestCaseBase.java b/tests/app/src/android/app/cts/CTSActivityTestCaseBase.java
deleted file mode 100644
index efe693a..0000000
--- a/tests/app/src/android/app/cts/CTSActivityTestCaseBase.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-import android.cts.util.CTSResult;
-import android.test.InstrumentationTestCase;
-
-public class CTSActivityTestCaseBase extends InstrumentationTestCase implements CTSResult {
-
-    private Sync mSync;
-    static class Sync {
-        public boolean mHasNotify;
-        public int mResult;
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mSync = new Sync();
-    }
-
-    public void setResult(int resultCode) {
-        synchronized (mSync) {
-            mSync.mHasNotify = true;
-            mSync.mResult = resultCode;
-            mSync.notify();
-        }
-    }
-
-    protected void waitForResult() throws InterruptedException {
-        synchronized (mSync) {
-            while (!mSync.mHasNotify) {
-                mSync.wait();
-            }
-            assertEquals(CTSResult.RESULT_OK, mSync.mResult);
-        }
-    }
-}
diff --git a/tests/app/src/android/app/cts/ChildActivity.java b/tests/app/src/android/app/cts/ChildActivity.java
deleted file mode 100644
index 5f77655..0000000
--- a/tests/app/src/android/app/cts/ChildActivity.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-import android.app.Activity;
-
-public class ChildActivity extends Activity {
-
-    public static boolean isStarted = false;
-
-    @Override
-    protected void onStart() {
-        super.onStart();
-        isStarted = true;
-    }
-}
diff --git a/tests/app/src/android/app/cts/ChildTabActivity.java b/tests/app/src/android/app/cts/ChildTabActivity.java
deleted file mode 100644
index e3b2369..0000000
--- a/tests/app/src/android/app/cts/ChildTabActivity.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-import android.app.Activity;
-
-/**
- * An empty activity for the TabActivity test
- */
-public class ChildTabActivity extends Activity {
-}
diff --git a/tests/app/src/android/app/cts/ClearTop.java b/tests/app/src/android/app/cts/ClearTop.java
deleted file mode 100644
index 5f608702..0000000
--- a/tests/app/src/android/app/cts/ClearTop.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.os.Bundle;
-import android.util.Log;
-
-public class ClearTop extends Activity {
-    public static final String WAIT_CLEAR_TASK = "waitClearTask";
-    private static final String TAG = "ClearTop";
-    public ClearTop() {
-    }
-
-    @Override
-    public void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-        final Intent intent = new Intent(getIntent()).setAction(LocalScreen.CLEAR_TASK).setClass(
-                this, LocalScreen.class);
-        startActivity(intent);
-    }
-
-    @Override
-    public void onNewIntent(Intent intent) {
-        Log.i(TAG, "onNewIntent");
-        if (LocalScreen.CLEAR_TASK.equals(intent.getAction())) {
-            setResult(RESULT_OK);
-        } else {
-            setResult(RESULT_CANCELED, new Intent().setAction("New intent received " + intent
-                    + ", expecting action " + TestedScreen.CLEAR_TASK));
-        }
-        finish();
-    }
-}
diff --git a/tests/app/src/android/app/cts/ConditionTest.java b/tests/app/src/android/app/cts/ConditionTest.java
new file mode 100644
index 0000000..b1985d1
--- /dev/null
+++ b/tests/app/src/android/app/cts/ConditionTest.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.cts;
+
+import android.net.Uri;
+import android.os.Parcel;
+import android.service.notification.Condition;
+import android.test.AndroidTestCase;
+
+public class ConditionTest extends AndroidTestCase {
+
+    private final Uri mConditionId = new Uri.Builder().scheme("scheme")
+            .authority("authority")
+            .appendPath("path")
+            .appendPath("test")
+            .build();
+    private final String mSummary = "summary";
+    private final int mState = Condition.STATE_FALSE;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+    }
+
+    public void testDescribeContents() {
+        final int expected = 0;
+        Condition condition = new Condition(mConditionId, mSummary, mState);
+        assertEquals(expected, condition.describeContents());
+    }
+
+    public void testConstructor() {
+        Condition condition = new Condition(mConditionId, mSummary, mState);
+        assertEquals(mConditionId, condition.id);
+        assertEquals(mSummary, condition.summary);
+        assertEquals("", condition.line1);
+        assertEquals("", condition.line2);
+        assertEquals(mState, condition.state);
+        assertEquals(-1, condition.icon);
+        assertEquals(Condition.FLAG_RELEVANT_ALWAYS, condition.flags);
+    }
+
+    public void testWriteToParcel() {
+        Condition condition = new Condition(mConditionId, mSummary, mState);
+        Parcel parcel = Parcel.obtain();
+        condition.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        Condition condition1 = new Condition(parcel);
+        assertEquals(mConditionId, condition1.id);
+        assertEquals(mSummary, condition1.summary);
+        assertEquals("", condition1.line1);
+        assertEquals("", condition1.line2);
+        assertEquals(mState, condition1.state);
+        assertEquals(-1, condition1.icon);
+        assertEquals(Condition.FLAG_RELEVANT_ALWAYS, condition1.flags);
+    }
+}
diff --git a/tests/app/src/android/app/cts/DialogStubActivity.java b/tests/app/src/android/app/cts/DialogStubActivity.java
deleted file mode 100644
index a773ae2..0000000
--- a/tests/app/src/android/app/cts/DialogStubActivity.java
+++ /dev/null
@@ -1,424 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-import com.android.cts.app.stub.R;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.app.DatePickerDialog;
-import android.app.Dialog;
-import android.app.TimePickerDialog;
-import android.app.DatePickerDialog.OnDateSetListener;
-import android.app.TimePickerDialog.OnTimeSetListener;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.DialogInterface.OnCancelListener;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.test.ActivityInstrumentationTestCase2;
-import android.util.Log;
-import android.view.KeyEvent;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.DatePicker;
-import android.widget.TimePicker;
-
-/*
- * Stub class for  Dialog, AlertDialog, DatePickerDialog, TimePickerDialog etc.
- */
-public class DialogStubActivity extends Activity {
-    public static final int TEST_DIALOG_WITHOUT_THEME = 0;
-    public static final int TEST_DIALOG_WITH_THEME = 1;
-    public static final int TEST_ALERTDIALOG = 2;
-    public static final int TEST_CUSTOM_ALERTDIALOG = 3;
-    public static final int TEST_DATEPICKERDIALOG = 4;
-    public static final int TEST_DATEPICKERDIALOG_WITH_THEME = 5;
-    public static final int TEST_TIMEPICKERDIALOG = 6;
-    public static final int TEST_TIMEPICKERDIALOG_WITH_THEME = 7;
-    public static final int TEST_ONSTART_AND_ONSTOP = 8;
-    public static final int TEST_ALERTDIALOG_DEPRECATED = 9;
-    public static final int TEST_ALERTDIALOG_CALLBACK = 10;
-    public static final int TEST_CUSTOM_ALERTDIALOG_VIEW = 11;
-    public static final int TEST_ALERTDIALOG_DEPRECATED_WITH_MESSAGE = 12;
-    public static final int TEST_ALERTDIALOG_THEME = 13;
-    public static final int TEST_ALERTDIALOG_CANCELABLE = 14;
-    public static final int TEST_ALERTDIALOG_NOT_CANCELABLE = 15;
-    public static final int TEST_PROTECTED_CANCELABLE = 16;
-    public static final int TEST_PROTECTED_NOT_CANCELABLE = 17;
-
-    public static final int SPACING_LEFT = 10;
-    public static final int SPACING_TOP = 20;
-    public static final int SPACING_RIGHT = 30;
-    public static final int SPACING_BOTTOM = 40;
-    public static int buttonIndex;
-
-    public static final String DEFAULT_ALERTDIALOG_TITLE = "AlertDialog";
-    public static final String DEFAULT_ALERTDIALOG_MESSAGE = "AlertDialog message";
-    private static final String LOG_TAG = "DialogStubActivity";
-
-    public boolean isPositiveButtonClicked = false;
-    public boolean isNegativeButtonClicked = false;
-    public boolean isNeutralButtonClicked = false;
-    public boolean isCallBackCalled;
-    public boolean onCancelCalled;
-    public boolean onKeyDownCalled;
-    public boolean onKeyUpCalled;
-    public boolean onCreateCalled;
-    public boolean onCancelListenerCalled;
-    public boolean onClickCalled;
-    public static boolean onDateChangedCalled;
-    public static boolean onRestoreInstanceStateCalled;
-    public boolean onSaveInstanceStateCalled;
-    public int updatedYear;
-    public int updatedMonth;
-    public int updatedDay;
-
-    public final int INITIAL_YEAR = 2008;
-    public final int INITIAL_MONTH = 7;
-    public final int INITIAL_DAY_OF_MONTH = 27;
-    private final int INITIAL_HOUR = 10;
-    private final int INITIAL_MINUTE = 35;
-    private Dialog mDialog;
-    private AlertDialog mAlertDialog;
-    private OnDateSetListener mOnDateSetListener = new OnDateSetListener() {
-        public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
-            updatedYear = year;
-            updatedMonth = monthOfYear;
-            updatedDay = dayOfMonth;
-        }
-    };
-
-    @SuppressWarnings("deprecation")
-    @Override
-    protected Dialog onCreateDialog(int id) {
-        switch (id) {
-            case TEST_DIALOG_WITHOUT_THEME:
-                mDialog = new Dialog(this);
-                mDialog.setTitle("Hello, Dialog");
-                break;
-
-            case TEST_DIALOG_WITH_THEME:
-                mDialog = new Dialog(this, 1);
-                break;
-
-            case TEST_ALERTDIALOG:
-                mDialog = getAlertDialogInstance(false);
-                break;
-
-            case TEST_CUSTOM_ALERTDIALOG:
-                mDialog = getCustomAlertDialogInstance(false);
-                break;
-
-            case TEST_CUSTOM_ALERTDIALOG_VIEW:
-                mDialog = getCustomAlertDialogInstance(true);
-                break;
-
-            case TEST_DATEPICKERDIALOG:
-                mDialog = new MockDatePickerDialog(this, mOnDateSetListener, INITIAL_YEAR,
-                        INITIAL_MONTH, INITIAL_DAY_OF_MONTH);
-                break;
-
-            case TEST_DATEPICKERDIALOG_WITH_THEME:
-                mDialog = new MockDatePickerDialog(this,
-                        com.android.internal.R.style.Theme_Translucent, mOnDateSetListener,
-                        INITIAL_YEAR, INITIAL_MONTH, INITIAL_DAY_OF_MONTH);
-                break;
-
-            case TEST_TIMEPICKERDIALOG:
-                mDialog = new TimePickerDialog(this, new OnTimeSetListener() {
-                    public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
-                        isCallBackCalled = true;
-                    }
-                }, INITIAL_HOUR, INITIAL_MINUTE, true);
-                break;
-
-            case TEST_TIMEPICKERDIALOG_WITH_THEME:
-                mDialog = new TimePickerDialog(this,
-                        com.android.internal.R.style.Theme_Translucent, null, INITIAL_HOUR,
-                        INITIAL_MINUTE, true);
-                break;
-
-            case TEST_ONSTART_AND_ONSTOP:
-                mDialog = new TestDialog(this);
-                Log.i(LOG_TAG, "mTestDialog:" + mDialog);
-                return mDialog;
-
-            case TEST_ALERTDIALOG_DEPRECATED:
-                mDialog = getAlertDialogInstance(true);
-                break;
-
-            case TEST_ALERTDIALOG_DEPRECATED_WITH_MESSAGE:
-                final Handler handler = new Handler() {
-                    @Override
-                    public void handleMessage(Message msg) {
-                        buttonIndex = msg.what;
-                        super.handleMessage(msg);
-                    }
-                };
-                final Message positiveMessage = Message.obtain();
-                positiveMessage.setTarget(handler);
-                positiveMessage.what = DialogInterface.BUTTON_POSITIVE;
-
-                final Message negativeMessage = Message.obtain();
-                negativeMessage.setTarget(handler);
-                negativeMessage.what = DialogInterface.BUTTON_NEGATIVE;
-
-                final Message neutralMessage = Message.obtain();
-                neutralMessage.setTarget(handler);
-                neutralMessage.what = DialogInterface.BUTTON_NEUTRAL;
-                mAlertDialog = getAlertDialogInstance(false);
-                mAlertDialog.setButton(getString(R.string.alert_dialog_positive), positiveMessage);
-                mAlertDialog.setButton2(getString(R.string.alert_dialog_negative), negativeMessage);
-                mAlertDialog.setButton3(getString(R.string.alert_dialog_neutral), neutralMessage);
-                mDialog = mAlertDialog;
-                break;
-
-            case TEST_ALERTDIALOG_CALLBACK:
-                mDialog = new MockAlertDialog(this);
-                break;
-            case TEST_ALERTDIALOG_THEME:
-                mDialog = new MockAlertDialog(this, R.style.Theme_AlertDialog);
-                break;
-            case TEST_ALERTDIALOG_CANCELABLE:
-                mDialog = getAlertDialogCancelablInstance(true);
-                break;
-            case TEST_ALERTDIALOG_NOT_CANCELABLE:
-                mDialog = getAlertDialogCancelablInstance(false);
-                break;
-            case TEST_PROTECTED_CANCELABLE:
-                mDialog = new TestDialog(this, true, new OnCancelListener() {
-                    public void onCancel(DialogInterface dialog) {
-                        onCancelListenerCalled = true;
-                    }
-                });
-                break;
-            case TEST_PROTECTED_NOT_CANCELABLE:
-                mDialog = new TestDialog(this, false, new OnCancelListener() {
-                    public void onCancel(DialogInterface dialog) {
-                        onCancelListenerCalled = true;
-                    }
-                });
-                break;
-            default:
-                break;
-        }
-
-        Log.i(LOG_TAG, "mDialog:" + mDialog);
-        return mDialog;
-    }
-
-    private AlertDialog getAlertDialogCancelablInstance(boolean cancelable) {
-        OnCancelListener cancelListener = new OnCancelListener() {
-            public void onCancel(DialogInterface dialog) {
-                onCancelCalled = true;
-            }
-        };
-        return new MockAlertDialog(this, cancelable, cancelListener);
-    }
-
-    @SuppressWarnings("deprecation")
-    private AlertDialog getAlertDialogInstance(boolean deprecated) {
-        mAlertDialog = new AlertDialog.Builder(DialogStubActivity.this).create();
-        mAlertDialog.setIcon(com.android.cts.app.stub.R.drawable.pass);
-        mAlertDialog.setTitle(DEFAULT_ALERTDIALOG_TITLE);
-        mAlertDialog.setMessage(DEFAULT_ALERTDIALOG_MESSAGE);
-        mAlertDialog.setInverseBackgroundForced(true);
-        final DialogInterface.OnClickListener positiveListener = new MockOnClickListener(
-                DialogInterface.BUTTON_POSITIVE);
-        final DialogInterface.OnClickListener netativeListener = new MockOnClickListener(
-                DialogInterface.BUTTON_NEGATIVE);
-        final DialogInterface.OnClickListener neutralListener = new MockOnClickListener(
-                DialogInterface.BUTTON_NEUTRAL);
-
-        if (deprecated) {
-            mAlertDialog.setButton(getString(R.string.alert_dialog_positive), positiveListener);
-            mAlertDialog.setButton2(getString(R.string.alert_dialog_negative), netativeListener);
-            mAlertDialog.setButton3(getString(R.string.alert_dialog_neutral), neutralListener);
-        } else {
-            mAlertDialog.setButton(DialogInterface.BUTTON_POSITIVE,
-                    getString(R.string.alert_dialog_positive), positiveListener);
-            mAlertDialog.setButton(DialogInterface.BUTTON_NEGATIVE,
-                    getString(R.string.alert_dialog_negative), netativeListener);
-            mAlertDialog.setButton(DialogInterface.BUTTON_NEUTRAL,
-                    getString(R.string.alert_dialog_neutral), neutralListener);
-        }
-        return mAlertDialog;
-
-    }
-
-    private AlertDialog getCustomAlertDialogInstance(boolean withSpacing) {
-        final LayoutInflater inflate = getLayoutInflater();
-        final View customTitleViewCustom = inflate.inflate(R.layout.alertdialog_custom_title, null);
-        final View textEntryView = inflate.inflate(R.layout.alert_dialog_text_entry_2, null);
-        mAlertDialog = new AlertDialog.Builder(DialogStubActivity.this).create();
-        mAlertDialog.setCustomTitle(customTitleViewCustom);
-        mAlertDialog.setMessage(DEFAULT_ALERTDIALOG_MESSAGE);
-        if (withSpacing) {
-            mAlertDialog.setView(textEntryView, SPACING_LEFT, SPACING_TOP, SPACING_RIGHT,
-                    SPACING_BOTTOM);
-        } else {
-            mAlertDialog.setView(textEntryView);
-        }
-
-        return mAlertDialog;
-
-    }
-
-    public Dialog getDialog() {
-        return mDialog;
-    }
-
-    public String getDialogTitle() {
-        return (String) mDialog.getWindow().getAttributes().getTitle();
-    }
-
-    private static final String TEST_DIALOG_NUMBER_EXTRA = "testDialogNumber";
-
-    public static <T extends Activity> T startDialogActivity(
-            ActivityInstrumentationTestCase2<T> testCase, int dialogNumber) {
-        Intent intent = new Intent(Intent.ACTION_MAIN);
-        intent.putExtra(TEST_DIALOG_NUMBER_EXTRA, dialogNumber);
-        testCase.setActivityIntent(intent);
-        return testCase.getActivity();
-    }
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        setContentView(R.layout.dialog_stub_layout);
-
-        Intent intent = getIntent();
-        int dialogNum = intent.getIntExtra(TEST_DIALOG_NUMBER_EXTRA, -1);
-        if (dialogNum != -1) {
-            showDialog(dialogNum);
-        }
-    }
-
-    public void setUpTitle(final String title) {
-        runOnUiThread(new Runnable() {
-            public void run() {
-                getDialog().setTitle(title);
-            }
-        });
-    }
-
-    public void setUpTitle(final int id) {
-        runOnUiThread(new Runnable() {
-            public void run() {
-                getDialog().setTitle(id);
-            }
-        });
-    }
-
-    class MockAlertDialog extends AlertDialog {
-        public MockAlertDialog(Context context) {
-            super(context);
-        }
-
-        public MockAlertDialog(Context context, int theme) {
-            super(context, theme);
-        }
-
-        public MockAlertDialog(Context context, boolean cancelable, OnCancelListener cancelListener) {
-            super(context, cancelable, cancelListener);
-        }
-
-        @Override
-        public boolean onKeyDown(int keyCode, KeyEvent event) {
-            onKeyDownCalled = true;
-            return super.onKeyDown(keyCode, event);
-        }
-
-        @Override
-        public boolean onKeyUp(int keyCode, KeyEvent event) {
-            onKeyUpCalled = true;
-            return super.onKeyUp(keyCode, event);
-        }
-
-        @Override
-        protected void onCreate(Bundle savedInstanceState) {
-            onCreateCalled = true;
-            super.onCreate(savedInstanceState);
-        }
-
-    }
-
-    class MockOnClickListener implements DialogInterface.OnClickListener {
-        private final int mId;
-
-        public MockOnClickListener(final int buttonId) {
-            mId = buttonId;
-        }
-
-        public void onClick(DialogInterface dialog, int which) {
-            switch (mId) {
-                case DialogInterface.BUTTON_POSITIVE:
-                    isPositiveButtonClicked = true;
-                    break;
-                case DialogInterface.BUTTON_NEGATIVE:
-                    isNegativeButtonClicked = true;
-                    break;
-                case DialogInterface.BUTTON_NEUTRAL:
-                    isNeutralButtonClicked = true;
-                    break;
-                default:
-                    break;
-            }
-        }
-    }
-
-    class MockDatePickerDialog extends DatePickerDialog {
-        public MockDatePickerDialog(Context context, OnDateSetListener callBack, int year,
-                int monthOfYear, int dayOfMonth) {
-            super(context, callBack, year, monthOfYear, dayOfMonth);
-        }
-
-        public MockDatePickerDialog(Context context, int theme, OnDateSetListener callBack,
-                int year, int monthOfYear, int dayOfMonth) {
-            super(context, theme, callBack, year, monthOfYear, dayOfMonth);
-        }
-
-        @Override
-        public void onClick(DialogInterface dialog, int which) {
-            onClickCalled = true;
-            super.onClick(dialog, which);
-        }
-
-        @Override
-        public void onDateChanged(DatePicker view, int year, int month, int day) {
-            onDateChangedCalled = true;
-            super.onDateChanged(view, year, month, day);
-        }
-
-        @Override
-        public void onRestoreInstanceState(Bundle savedInstanceState) {
-            onRestoreInstanceStateCalled = true;
-            super.onRestoreInstanceState(savedInstanceState);
-        }
-
-        @Override
-        public Bundle onSaveInstanceState() {
-            onSaveInstanceStateCalled = true;
-            return super.onSaveInstanceState();
-        }
-
-    }
-}
diff --git a/tests/app/src/android/app/cts/DialogTest.java b/tests/app/src/android/app/cts/DialogTest.java
new file mode 100755
index 0000000..8ae4c66
--- /dev/null
+++ b/tests/app/src/android/app/cts/DialogTest.java
@@ -0,0 +1,940 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.cts;
+
+import android.app.Dialog;
+import android.app.Instrumentation;
+import android.app.stubs.DialogStubActivity;
+import android.app.stubs.OrientationTestUtils;
+import android.app.stubs.TestDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnCancelListener;
+import android.content.DialogInterface.OnDismissListener;
+import android.content.DialogInterface.OnKeyListener;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.cts.util.PollingCheck;
+import android.graphics.Canvas;
+import android.graphics.ColorFilter;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.Message;
+import android.os.SystemClock;
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.UiThreadTest;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.view.WindowManager;
+import android.widget.LinearLayout;
+
+import android.app.stubs.R;
+
+import java.lang.ref.WeakReference;
+
+public class DialogTest extends ActivityInstrumentationTestCase2<DialogStubActivity> {
+
+    protected static final long SLEEP_TIME = 200;
+    private static final String STUB_ACTIVITY_PACKAGE = "android.app.stubs";
+    private static final long TEST_TIMEOUT = 1000L;
+
+    /**
+     *  please refer to Dialog
+     */
+    private static final int DISMISS = 0x43;
+    private static final int CANCEL = 0x44;
+
+    private boolean mCalledCallback;
+    private boolean mIsKey0Listened;
+    private boolean mIsKey1Listened;
+    private boolean mOnCancelListenerCalled;
+
+    private Instrumentation mInstrumentation;
+    private Context mContext;
+    private DialogStubActivity mActivity;
+
+
+    public DialogTest() {
+        super(STUB_ACTIVITY_PACKAGE, DialogStubActivity.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mInstrumentation = getInstrumentation();
+        mContext = mInstrumentation.getContext();
+    }
+
+    private void startDialogActivity(int dialogNumber) {
+        mActivity = DialogStubActivity.startDialogActivity(this, dialogNumber);
+    }
+
+    @UiThreadTest
+    public void testConstructor() {
+        new Dialog(mContext);
+        Dialog d = new Dialog(mContext, 0);
+        // According to javadoc of constructors, it will set theme to system default theme,
+        // when we set no theme id or set it theme id to 0.
+        // But CTS can no assert dialog theme equals system internal theme.
+
+        d = new Dialog(mContext, R.style.TextAppearance);
+        TypedArray ta =
+            d.getContext().getTheme().obtainStyledAttributes(R.styleable.TextAppearance);
+        assertTextAppearanceStyle(ta);
+
+        final Window w = d.getWindow();
+        ta = w.getContext().getTheme().obtainStyledAttributes(R.styleable.TextAppearance);
+        assertTextAppearanceStyle(ta);
+    }
+
+    public void testConstructor_protectedCancellable() {
+        startDialogActivity(DialogStubActivity.TEST_PROTECTED_CANCELABLE);
+        mActivity.onCancelListenerCalled = false;
+        sendKeys(KeyEvent.KEYCODE_BACK);
+        assertTrue(mActivity.onCancelListenerCalled);
+    }
+
+    public void testConstructor_protectedNotCancellable() {
+        startDialogActivity(DialogStubActivity.TEST_PROTECTED_NOT_CANCELABLE);
+        mActivity.onCancelListenerCalled = false;
+        sendKeys(KeyEvent.KEYCODE_BACK);
+        assertFalse(mActivity.onCancelListenerCalled);
+    }
+
+    private void assertTextAppearanceStyle(TypedArray ta) {
+        final int defValue = -1;
+        // get Theme and assert
+        final Resources.Theme expected = mContext.getResources().newTheme();
+        expected.setTo(mContext.getTheme());
+        expected.applyStyle(R.style.TextAppearance, true);
+        TypedArray expectedTa = expected.obtainStyledAttributes(R.styleable.TextAppearance);
+        assertEquals(expectedTa.getIndexCount(), ta.getIndexCount());
+        assertEquals(expectedTa.getColor(R.styleable.TextAppearance_textColor, defValue),
+                ta.getColor(R.styleable.TextAppearance_textColor, defValue));
+        assertEquals(expectedTa.getColor(R.styleable.TextAppearance_textColorHint, defValue),
+                ta.getColor(R.styleable.TextAppearance_textColorHint, defValue));
+        assertEquals(expectedTa.getColor(R.styleable.TextAppearance_textColorLink, defValue),
+                ta.getColor(R.styleable.TextAppearance_textColorLink, defValue));
+        assertEquals(expectedTa.getColor(R.styleable.TextAppearance_textColorHighlight, defValue),
+                ta.getColor(R.styleable.TextAppearance_textColorHighlight, defValue));
+        assertEquals(expectedTa.getDimension(R.styleable.TextAppearance_textSize, defValue),
+                ta.getDimension(R.styleable.TextAppearance_textSize, defValue));
+        assertEquals(expectedTa.getInt(R.styleable.TextAppearance_textStyle, defValue),
+                ta.getInt(R.styleable.TextAppearance_textStyle, defValue));
+    }
+
+    public void testOnStartCreateStop(){
+        startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
+        final TestDialog d = (TestDialog) mActivity.getDialog();
+
+        assertTrue(d.isOnStartCalled);
+        assertTrue(d.isOnCreateCalled);
+
+        assertFalse(d.isOnStopCalled);
+        sendKeys(KeyEvent.KEYCODE_BACK);
+        assertTrue(d.isOnStopCalled);
+    }
+
+    public void testAccessOwnerActivity() throws Throwable {
+        startDialogActivity(DialogStubActivity.TEST_DIALOG_WITHOUT_THEME);
+        Dialog d = mActivity.getDialog();
+        assertNotNull(d);
+        assertSame(mActivity, d.getOwnerActivity());
+        d.setVolumeControlStream(d.getVolumeControlStream() + 1);
+        assertEquals(d.getOwnerActivity().getVolumeControlStream() + 1, d.getVolumeControlStream());
+
+        try {
+            d.setOwnerActivity(null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                Dialog dialog = new Dialog(mContext);
+                assertNull(dialog.getOwnerActivity());
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+    }
+
+    public void testShow() throws Throwable {
+        startDialogActivity(DialogStubActivity.TEST_DIALOG_WITHOUT_THEME);
+        final Dialog d = mActivity.getDialog();
+        final View decor = d.getWindow().getDecorView();
+
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                d.hide();
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+
+        assertEquals(View.GONE, decor.getVisibility());
+        assertTrue(d.isShowing());
+
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                d.show();
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+
+        assertEquals(View.VISIBLE, decor.getVisibility());
+        assertTrue(d.isShowing());
+        dialogDismiss(d);
+        assertFalse(d.isShowing());
+    }
+
+    public void testOnSaveInstanceState() {
+        startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
+        final TestDialog d = (TestDialog) mActivity.getDialog();
+
+        assertFalse(d.isOnSaveInstanceStateCalled);
+        assertFalse(TestDialog.isOnRestoreInstanceStateCalled);
+
+        //skip if the device doesn't support both of portrait and landscape orientation screens.
+        final PackageManager pm = mContext.getPackageManager();
+        if(!(pm.hasSystemFeature(PackageManager.FEATURE_SCREEN_LANDSCAPE)
+                && pm.hasSystemFeature(PackageManager.FEATURE_SCREEN_PORTRAIT))){
+            return;
+        }
+
+        OrientationTestUtils.toggleOrientationSync(mActivity, mInstrumentation);
+
+        assertTrue(d.isOnSaveInstanceStateCalled);
+        assertTrue(TestDialog.isOnRestoreInstanceStateCalled);
+    }
+
+    public void testGetCurrentFocus() throws Throwable {
+        startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
+        final TestDialog d = (TestDialog) mActivity.getDialog();
+        assertNull(d.getCurrentFocus());
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                d.takeKeyEvents(true);
+                d.setContentView(R.layout.alert_dialog_text_entry);
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+
+        sendKeys(KeyEvent.KEYCODE_0);
+        // When mWindow is not null getCUrrentFocus is the view in dialog
+        assertEquals(d.getWindow().getCurrentFocus(), d.getCurrentFocus());
+    }
+
+    public void testSetContentView() throws Throwable {
+        startDialogActivity(DialogStubActivity.TEST_DIALOG_WITHOUT_THEME);
+        final Dialog d = mActivity.getDialog();
+        assertNotNull(d);
+
+        // set content view to a four elements layout
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                d.setContentView(R.layout.alert_dialog_text_entry);
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+
+        // check if four elements are right there
+        assertNotNull(d.findViewById(R.id.username_view));
+        assertNotNull(d.findViewById(R.id.username_edit));
+        assertNotNull(d.findViewById(R.id.password_view));
+        assertNotNull(d.findViewById(R.id.password_edit));
+
+        final LayoutInflater inflate1 = d.getLayoutInflater();
+
+        // set content view to a two elements layout
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                d.setContentView(inflate1.inflate(R.layout.alert_dialog_text_entry_2, null));
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+
+        // check if only two elements are right there
+        assertNotNull(d.findViewById(R.id.username_view));
+        assertNotNull(d.findViewById(R.id.username_edit));
+        assertNull(d.findViewById(R.id.password_view));
+        assertNull(d.findViewById(R.id.password_edit));
+
+        final WindowManager.LayoutParams lp = d.getWindow().getAttributes();
+        final LayoutInflater inflate2 = mActivity.getLayoutInflater();
+
+        // set content view to a four elements layout
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                d.setContentView(inflate2.inflate(R.layout.alert_dialog_text_entry, null), lp);
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+
+        // check if four elements are right there
+        assertNotNull(d.findViewById(R.id.username_view));
+        assertNotNull(d.findViewById(R.id.username_edit));
+        assertNotNull(d.findViewById(R.id.password_view));
+        assertNotNull(d.findViewById(R.id.password_edit));
+
+        final WindowManager.LayoutParams lp2 = d.getWindow().getAttributes();
+        final LayoutInflater inflate3 = mActivity.getLayoutInflater();
+        lp2.height = ViewGroup.LayoutParams.WRAP_CONTENT;
+        lp2.width = ViewGroup.LayoutParams.WRAP_CONTENT;
+
+        // add a check box view
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                d.addContentView(inflate3.inflate(R.layout.checkbox_layout, null), lp2);
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+
+        // check if four elements are right there, and new add view there.
+        assertNotNull(d.findViewById(R.id.check_box));
+        assertNotNull(d.findViewById(R.id.username_view));
+        assertNotNull(d.findViewById(R.id.username_edit));
+        assertNotNull(d.findViewById(R.id.password_view));
+        assertNotNull(d.findViewById(R.id.password_edit));
+    }
+
+    public void testSetTitle() {
+        final String expectedTitle = "Test Dialog Without theme";
+        startDialogActivity(DialogStubActivity.TEST_DIALOG_WITHOUT_THEME);
+
+        assertNotNull(mActivity.getDialog());
+        mActivity.setUpTitle(expectedTitle);
+        mInstrumentation.waitForIdleSync();
+
+        final Dialog d = mActivity.getDialog();
+        assertEquals(expectedTitle, (String) d.getWindow().getAttributes().getTitle());
+
+        mActivity.setUpTitle(R.string.hello_android);
+        mInstrumentation.waitForIdleSync();
+        assertEquals(mActivity.getResources().getString(R.string.hello_android),
+                (String) d.getWindow().getAttributes().getTitle());
+    }
+
+    public void testOnKeyDownKeyUp() {
+        startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
+        final TestDialog d = (TestDialog) mActivity.getDialog();
+        assertFalse(d.isOnKeyDownCalled);
+        assertFalse(d.isOnKeyUpCalled);
+
+        // send key 0 down and up events, onKeyDown return false
+        mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_0);
+        assertTrue(d.isOnKeyDownCalled);
+        assertTrue(d.isOnKeyUpCalled);
+        assertEquals(KeyEvent.KEYCODE_0, d.keyDownCode);
+        assertFalse(d.onKeyDownReturn);
+
+        // send key back down and up events, onKeyDown return true
+        mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_BACK);
+        assertEquals(KeyEvent.KEYCODE_BACK, d.keyDownCode);
+        assertTrue(d.onKeyDownReturn);
+    }
+
+     public void testOnKeyMultiple() {
+         startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
+         final TestDialog d = (TestDialog) mActivity.getDialog();
+
+         assertNull(d.keyMultipleEvent);
+         d.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_MULTIPLE, KeyEvent.KEYCODE_UNKNOWN));
+         assertTrue(d.isOnKeyMultipleCalled);
+         assertFalse(d.onKeyMultipleReturn);
+         assertEquals(KeyEvent.KEYCODE_UNKNOWN, d.keyMultipleEvent.getKeyCode());
+         assertEquals(KeyEvent.ACTION_MULTIPLE, d.keyMultipleEvent.getAction());
+     }
+
+    public void testTouchEvent() {
+        startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
+        final TestDialog d = (TestDialog) mActivity.getDialog();
+
+        assertNull(d.onTouchEvent);
+        assertNull(d.touchEvent);
+        assertFalse(d.isOnTouchEventCalled);
+
+        // Send a touch event outside the activity.  The event will be ignored
+        // because closeOnTouchOutside is false.
+        d.setCanceledOnTouchOutside(false);
+
+        long now = SystemClock.uptimeMillis();
+        MotionEvent touchMotionEvent = MotionEvent.obtain(now, now, MotionEvent.ACTION_DOWN,
+                1, getStatusBarHeight(), 0);
+        mInstrumentation.sendPointerSync(touchMotionEvent);
+
+        new PollingCheck(TEST_TIMEOUT) {
+            protected boolean check() {
+                return !d.dispatchTouchEventResult;
+            }
+        }.run();
+
+        assertMotionEventEquals(touchMotionEvent, d.touchEvent);
+
+        assertTrue(d.isOnTouchEventCalled);
+        assertMotionEventEquals(touchMotionEvent, d.onTouchEvent);
+        d.isOnTouchEventCalled = false;
+        assertTrue(d.isShowing());
+
+        // Watch activities cover the entire screen, so there is no way to touch outside.
+        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH)) {
+            // Send a touch event outside the activity.  This time the dialog will be dismissed
+            // because closeOnTouchOutside is true.
+            d.setCanceledOnTouchOutside(true);
+
+            touchMotionEvent = MotionEvent.obtain(now, now + 1, MotionEvent.ACTION_DOWN,
+                    1, getStatusBarHeight(), 0);
+            mInstrumentation.sendPointerSync(touchMotionEvent);
+
+            new PollingCheck(TEST_TIMEOUT) {
+                protected boolean check() {
+                    return d.dispatchTouchEventResult;
+                }
+            }.run();
+
+            assertMotionEventEquals(touchMotionEvent, d.touchEvent);
+
+            assertTrue(d.isOnTouchEventCalled);
+            assertMotionEventEquals(touchMotionEvent, d.onTouchEvent);
+            assertFalse(d.isShowing());
+        }
+    }
+
+    private int getStatusBarHeight() {
+        final Rect rect = new Rect();
+        Window window = mActivity.getWindow();
+        window.getDecorView().getWindowVisibleDisplayFrame(rect);
+        return rect.top;
+    }
+
+    public void testTrackballEvent() {
+        startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
+        final TestDialog d = (TestDialog) mActivity.getDialog();
+        long eventTime = SystemClock.uptimeMillis();
+        final MotionEvent trackBallEvent = MotionEvent.obtain(eventTime, eventTime,
+                MotionEvent.ACTION_DOWN, 0.0f, 0.0f, 0);
+
+        assertNull(d.trackballEvent);
+        assertNull(d.onTrackballEvent);
+
+        assertFalse(d.isOnTrackballEventCalled);
+        mInstrumentation.sendTrackballEventSync(trackBallEvent);
+        assertTrue(d.isOnTrackballEventCalled);
+        assertMotionEventEquals(trackBallEvent, d.trackballEvent);
+        assertMotionEventEquals(trackBallEvent, d.onTrackballEvent);
+
+    }
+
+    private void assertMotionEventEquals(final MotionEvent expected, final MotionEvent actual) {
+        assertEquals(expected.getDownTime(), actual.getDownTime());
+        assertEquals(expected.getEventTime(), actual.getEventTime());
+        assertEquals(expected.getAction(), actual.getAction());
+        assertEquals(expected.getMetaState(), actual.getMetaState());
+        assertEquals(expected.getSize(), actual.getSize());
+        // As MotionEvent doc says the value of X and Y coordinate may have
+        // a fraction for input devices that are sub-pixel precise,
+        // so we won't assert them here.
+    }
+
+    public void testOnWindowAttributesChanged() throws Throwable {
+        startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
+        final TestDialog d = (TestDialog) mActivity.getDialog();
+
+        assertTrue(d.isOnWindowAttributesChangedCalled);
+        d.isOnWindowAttributesChangedCalled = false;
+
+        final WindowManager.LayoutParams lp = d.getWindow().getAttributes();
+        lp.setTitle("test OnWindowAttributesChanged");
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                d.getWindow().setAttributes(lp);
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+
+        assertTrue(d.isOnWindowAttributesChangedCalled);
+        assertSame(lp, d.getWindow().getAttributes());
+    }
+
+    public void testOnContentChanged() throws Throwable {
+        startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
+        final TestDialog d = (TestDialog) mActivity.getDialog();
+        assertNotNull(d);
+
+        assertFalse(d.isOnContentChangedCalled);
+
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                d.setContentView(R.layout.alert_dialog_text_entry);
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+
+        assertTrue(d.isOnContentChangedCalled);
+    }
+
+    public void testOnWindowFocusChanged() throws Throwable {
+        startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
+        final TestDialog d = (TestDialog) mActivity.getDialog();
+        assertTrue(d.isOnWindowFocusChangedCalled);
+        d.isOnWindowFocusChangedCalled = false;
+
+        // show a new dialog, the new dialog get focus
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                mActivity.showDialog(DialogStubActivity.TEST_DIALOG_WITHOUT_THEME);
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+
+        // Wait until TestDialog#OnWindowFocusChanged() is called
+        new PollingCheck(TEST_TIMEOUT) {
+            protected boolean check() {
+                return d.isOnWindowFocusChangedCalled;
+            }
+        }.run();
+    }
+
+    public void testDispatchKeyEvent() {
+        startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
+        final TestDialog d = (TestDialog) mActivity.getDialog();
+
+        sendKeys(KeyEvent.KEYCODE_0);
+        assertFalse(d.dispatchKeyEventResult);
+        assertEquals(KeyEvent.KEYCODE_0, d.keyEvent.getKeyCode());
+
+        d.setOnKeyListener(new OnKeyListener() {
+            public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
+                if (KeyEvent.ACTION_DOWN == event.getAction()) {
+                    if (KeyEvent.KEYCODE_0 == keyCode) {
+                        mIsKey0Listened = true;
+                        return true;
+                    }
+
+                    if (KeyEvent.KEYCODE_1 == keyCode) {
+                        mIsKey1Listened = true;
+                        return true;
+                    }
+                }
+
+                return false;
+            }
+        });
+
+        mIsKey1Listened = false;
+        sendKeys(KeyEvent.KEYCODE_1);
+        assertTrue(mIsKey1Listened);
+
+        mIsKey0Listened = false;
+        sendKeys(KeyEvent.KEYCODE_0);
+        assertTrue(mIsKey0Listened);
+    }
+
+    /*
+     * Test point
+     * 1. registerForContextMenu() will OnCreateContextMenuListener on the view to this activity,
+     * so onCreateContextMenu() will be called when it is time to show the context menu.
+     * 2. Close context menu will make onPanelClosed to be called,
+     * and onPanelClosed will calls through to the new onPanelClosed method.
+     * 3. unregisterForContextMenu() will remove the OnCreateContextMenuListener on the view,
+     * so onCreateContextMenu() will not be called when try to open context menu.
+     * 4. Selected a item of context menu will make onMenuItemSelected() to be called,
+     * and onMenuItemSelected will calls through to the new onContextItemSelected method.
+     * 5. onContextMenuClosed is called whenever the context menu is being closed (either by
+     * the user canceling the menu with the back/menu button, or when an item is selected).
+     */
+    public void testContextMenu() throws Throwable {
+        startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
+        final TestDialog d = (TestDialog) mActivity.getDialog();
+        final LinearLayout parent = new LinearLayout(mContext);
+        final MockView v = new MockView(mContext);
+        parent.addView(v);
+        assertFalse(v.isShowContextMenuCalled);
+        // Register for context menu and open it
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                d.addContentView(parent, new LinearLayout.LayoutParams(
+                        ViewGroup.LayoutParams.MATCH_PARENT,
+                        ViewGroup.LayoutParams.WRAP_CONTENT));
+                d.registerForContextMenu(v);
+                d.openContextMenu(v);
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+
+        assertTrue(v.isShowContextMenuCalled);
+        assertTrue(d.isOnCreateContextMenuCalled);
+
+        assertFalse(d.isOnPanelClosedCalled);
+        assertFalse(d.isOnContextMenuClosedCalled);
+        // Closed context menu
+        sendKeys(KeyEvent.KEYCODE_BACK);
+        assertTrue(d.isOnPanelClosedCalled);
+        // Here isOnContextMenuClosedCalled should be true, see bug 1716918.
+        assertFalse(d.isOnContextMenuClosedCalled);
+
+        v.isShowContextMenuCalled = false;
+        d.isOnCreateContextMenuCalled = false;
+        // Unregister for context menu, and try to open it
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                d.unregisterForContextMenu(v);
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                d.openContextMenu(v);
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+
+        assertTrue(v.isShowContextMenuCalled);
+        assertFalse(d.isOnCreateContextMenuCalled);
+
+        // Register for context menu and open it again
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                d.registerForContextMenu(v);
+                d.openContextMenu(v);
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+
+        assertFalse(d.isOnContextItemSelectedCalled);
+        assertFalse(d.isOnMenuItemSelectedCalled);
+        d.isOnPanelClosedCalled = false;
+        assertFalse(d.isOnContextMenuClosedCalled);
+        // select a context menu item
+        sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
+        assertTrue(d.isOnMenuItemSelectedCalled);
+        // Here isOnContextItemSelectedCalled should be true, see bug 1716918.
+        assertFalse(d.isOnContextItemSelectedCalled);
+        assertTrue(d.isOnPanelClosedCalled);
+        // Here isOnContextMenuClosedCalled should be true, see bug 1716918.
+        assertFalse(d.isOnContextMenuClosedCalled);
+    }
+
+    public void testOnSearchRequested() {
+    }
+
+    public void testTakeKeyEvents() throws Throwable {
+        startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
+        final TestDialog d = (TestDialog) mActivity.getDialog();
+        final View v = d.getWindow().getDecorView();
+        assertNull(d.getCurrentFocus());
+        takeKeyEvents(d, true);
+        assertTrue(v.isFocusable());
+        sendKeys(KeyEvent.KEYCODE_0);
+        assertEquals(KeyEvent.KEYCODE_0, d.keyEvent.getKeyCode());
+        d.keyEvent = null;
+
+        takeKeyEvents(d, false);
+        assertNull(d.getCurrentFocus());
+        assertFalse(v.isFocusable());
+        sendKeys(KeyEvent.KEYCODE_0);
+        // d.keyEvent should be null
+    }
+
+    private void takeKeyEvents(final Dialog d, final boolean get) throws Throwable {
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                d.takeKeyEvents(get);
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+    }
+
+    public void testRequestWindowFeature() {
+        startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
+        // called requestWindowFeature at TestDialog onCreate method
+        assertTrue(((TestDialog) mActivity.getDialog()).isRequestWindowFeature);
+    }
+
+    public void testSetFeatureDrawableResource() throws Throwable {
+        startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                mActivity.getDialog().setFeatureDrawableResource(Window.FEATURE_LEFT_ICON,
+                        R.drawable.robot);
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+    }
+
+    public void testSetFeatureDrawableUri() throws Throwable {
+        startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                mActivity.getDialog().setFeatureDrawableUri(Window.FEATURE_LEFT_ICON,
+                        Uri.parse("http://www.google.com"));
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+    }
+
+    public void testSetFeatureDrawable() throws Throwable {
+        startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                mActivity.getDialog().setFeatureDrawable(Window.FEATURE_LEFT_ICON, 
+                        new MockDrawable());
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+    }
+
+    public void testSetFeatureDrawableAlpha() throws Throwable {
+        startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                mActivity.getDialog().setFeatureDrawableAlpha(Window.FEATURE_LEFT_ICON, 0);
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+    }
+
+    public void testGetLayoutInflater() {
+        startDialogActivity(DialogStubActivity.TEST_DIALOG_WITHOUT_THEME);
+        final Dialog d = mActivity.getDialog();
+        assertEquals(d.getWindow().getLayoutInflater(), d.getLayoutInflater());
+    }
+
+    public void testSetCancelable_true() {
+        startDialogActivity(DialogStubActivity.TEST_DIALOG_WITHOUT_THEME);
+        final Dialog d = mActivity.getDialog();
+
+        d.setCancelable(true);
+        assertTrue(d.isShowing());
+        sendKeys(KeyEvent.KEYCODE_BACK);
+        assertFalse(d.isShowing());
+    }
+
+    public void testSetCancellable_false() {
+        startDialogActivity(DialogStubActivity.TEST_DIALOG_WITHOUT_THEME);
+        final Dialog d = mActivity.getDialog();
+
+        d.setCancelable(false);
+        assertTrue(d.isShowing());
+        sendKeys(KeyEvent.KEYCODE_BACK);
+        assertTrue(d.isShowing());
+    }
+
+    /*
+     * Test point
+     * 1. Cancel the dialog.
+     * 2. Set a listener to be invoked when the dialog is canceled.
+     */
+    public void testCancel_listener() throws Throwable {
+        startDialogActivity(DialogStubActivity.TEST_DIALOG_WITHOUT_THEME);
+        final Dialog d = mActivity.getDialog();
+
+        assertTrue(d.isShowing());
+        mOnCancelListenerCalled = false;
+        d.setOnCancelListener(new OnCancelListener() {
+            public void onCancel(DialogInterface dialog) {
+                mOnCancelListenerCalled = true;
+            }
+        });
+        dialogCancel(d);
+
+        assertFalse(d.isShowing());
+        assertTrue(mOnCancelListenerCalled);
+    }
+
+    public void testCancel_noListener() throws Throwable {
+        startDialogActivity(DialogStubActivity.TEST_DIALOG_WITHOUT_THEME);
+        final Dialog d = mActivity.getDialog();
+
+        assertTrue(d.isShowing());
+        mOnCancelListenerCalled = false;
+        d.setOnCancelListener(null);
+        dialogCancel(d);
+
+        assertFalse(d.isShowing());
+        assertFalse(mOnCancelListenerCalled);
+    }
+
+    public void testSetCancelMessage() throws Exception {
+        mCalledCallback = false;
+        startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
+        final TestDialog d = (TestDialog) mActivity.getDialog();
+        final HandlerThread ht = new HandlerThread("DialogTest");
+        ht.start();
+
+        d.setCancelMessage(new MockDismissCancelHandler(d, ht.getLooper()).obtainMessage(CANCEL,
+                new OnCancelListener() {
+                    public void onCancel(DialogInterface dialog) {
+                        mCalledCallback = true;
+                    }
+                }));
+        assertTrue(d.isShowing());
+        assertFalse(mCalledCallback);
+        sendKeys(KeyEvent.KEYCODE_BACK);
+        assertTrue(mCalledCallback);
+        assertFalse(d.isShowing());
+
+        ht.join(100);
+    }
+
+    /*
+     * Test point
+     * 1. Set a listener to be invoked when the dialog is dismissed.
+     * 2. set onDismissListener to null, it will not changed flag after dialog dismissed.
+     */
+    public void testSetOnDismissListener_listener() throws Throwable {
+        mCalledCallback = false;
+        startDialogActivity(DialogStubActivity.TEST_DIALOG_WITHOUT_THEME);
+        final Dialog d = mActivity.getDialog();
+
+        d.setOnDismissListener(new OnDismissListener() {
+            public void onDismiss(DialogInterface dialog) {
+                mCalledCallback = true;
+            }
+        });
+
+        assertTrue(d.isShowing());
+        assertFalse(mCalledCallback);
+        dialogDismiss(d);
+        assertTrue(mCalledCallback);
+        assertFalse(d.isShowing());
+    }
+
+    public void testSetOnDismissListener_noListener() throws Throwable {
+        startDialogActivity(DialogStubActivity.TEST_DIALOG_WITHOUT_THEME);
+        final Dialog d = mActivity.getDialog();
+        assertTrue(d.isShowing());
+        mCalledCallback = false;
+        d.setOnDismissListener(null);
+        dialogDismiss(d);
+        assertFalse(mCalledCallback);
+        assertFalse(d.isShowing());
+    }
+
+    public void testSetDismissMessage() throws Throwable {
+        mCalledCallback = false;
+        startDialogActivity(DialogStubActivity.TEST_DIALOG_WITHOUT_THEME);
+        final Dialog d = mActivity.getDialog();
+
+        final HandlerThread ht = new HandlerThread("DialogTest");
+        ht.start();
+
+        d.setDismissMessage(new MockDismissCancelHandler(d, ht.getLooper()).obtainMessage(DISMISS,
+                new OnDismissListener() {
+                    public void onDismiss(DialogInterface dialog) {
+                        mCalledCallback = true;
+                    }
+                }));
+        assertTrue(d.isShowing());
+        assertFalse(mCalledCallback);
+        dialogDismiss(d);
+        ht.join(100);
+        assertTrue(mCalledCallback);
+        assertFalse(d.isShowing());
+    }
+
+    private void dialogDismiss(final Dialog d) throws Throwable {
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                d.dismiss();
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+    }
+
+    private void dialogCancel(final Dialog d) throws Throwable {
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                d.cancel();
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+    }
+
+    private static class MockDismissCancelHandler extends Handler {
+        private WeakReference<DialogInterface> mDialog;
+
+        public MockDismissCancelHandler(Dialog dialog, Looper looper) {
+            super(looper);
+
+            mDialog = new WeakReference<DialogInterface>(dialog);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+            case DISMISS:
+                ((OnDismissListener) msg.obj).onDismiss(mDialog.get());
+                break;
+            case CANCEL:
+                ((OnCancelListener) msg.obj).onCancel(mDialog.get());
+                break;
+            }
+        }
+    }
+
+    private static class MockDrawable extends Drawable {
+        @Override
+        public void draw(Canvas canvas) {
+        }
+
+        @Override
+        public int getOpacity() {
+            return 0;
+        }
+
+        @Override
+        public void setAlpha(int alpha) {
+        }
+
+        @Override
+        public void setColorFilter(ColorFilter cf) {
+        }
+    }
+
+    private static class MockView extends View {
+        public boolean isShowContextMenuCalled;
+        protected OnCreateContextMenuListener mOnCreateContextMenuListener;
+
+        public MockView(Context context) {
+            super(context);
+        }
+
+        public void setOnCreateContextMenuListener(OnCreateContextMenuListener l) {
+            super.setOnCreateContextMenuListener(l);
+            mOnCreateContextMenuListener = l;
+        }
+
+        public OnCreateContextMenuListener getOnCreateContextMenuListener() {
+            return mOnCreateContextMenuListener;
+        }
+
+        @Override
+        public boolean showContextMenu() {
+            isShowContextMenuCalled = true;
+            return super.showContextMenu();
+        }
+    }
+}
diff --git a/tests/app/src/android/app/cts/DownloadManagerTest.java b/tests/app/src/android/app/cts/DownloadManagerTest.java
new file mode 100644
index 0000000..50eb96b
--- /dev/null
+++ b/tests/app/src/android/app/cts/DownloadManagerTest.java
@@ -0,0 +1,482 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.cts;
+
+import android.app.DownloadManager;
+import android.app.DownloadManager.Query;
+import android.app.DownloadManager.Request;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.cts.util.PollingCheck;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Environment;
+import android.os.ParcelFileDescriptor;
+import android.os.SystemClock;
+import android.test.AndroidTestCase;
+import android.text.format.DateUtils;
+import android.util.Log;
+import android.webkit.cts.CtsTestServer;
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.HashSet;
+
+public class DownloadManagerTest extends AndroidTestCase {
+    private static final String TAG = "DownloadManagerTest";
+
+    /**
+     * According to the CDD Section 7.6.1, the DownloadManager implementation must be able to
+     * download individual files of 100 MB.
+     */
+    private static final int MINIMUM_DOWNLOAD_BYTES = 100 * 1024 * 1024;
+
+    private static final long SHORT_TIMEOUT = 5 * DateUtils.SECOND_IN_MILLIS;
+    private static final long LONG_TIMEOUT = 3 * DateUtils.MINUTE_IN_MILLIS;
+
+    private DownloadManager mDownloadManager;
+
+    private CtsTestServer mWebServer;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mDownloadManager = (DownloadManager) mContext.getSystemService(Context.DOWNLOAD_SERVICE);
+        mWebServer = new CtsTestServer(mContext);
+        clearDownloads();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+        mWebServer.shutdown();
+    }
+
+    public void testDownloadManager() throws Exception {
+        final DownloadCompleteReceiver receiver = new DownloadCompleteReceiver();
+        try {
+            IntentFilter intentFilter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
+            mContext.registerReceiver(receiver, intentFilter);
+
+            long goodId = mDownloadManager.enqueue(new Request(getGoodUrl()));
+            long badId = mDownloadManager.enqueue(new Request(getBadUrl()));
+
+            int allDownloads = getTotalNumberDownloads();
+            assertEquals(2, allDownloads);
+
+            assertDownloadQueryableById(goodId);
+            assertDownloadQueryableById(badId);
+
+            receiver.waitForDownloadComplete(SHORT_TIMEOUT, goodId, badId);
+
+            assertDownloadQueryableByStatus(DownloadManager.STATUS_SUCCESSFUL);
+            assertDownloadQueryableByStatus(DownloadManager.STATUS_FAILED);
+
+            assertRemoveDownload(goodId, allDownloads - 1);
+            assertRemoveDownload(badId, allDownloads - 2);
+        } finally {
+            mContext.unregisterReceiver(receiver);
+        }
+    }
+
+    public void testDownloadManagerSupportsHttp() throws Exception {
+        final DownloadCompleteReceiver receiver = new DownloadCompleteReceiver();
+        try {
+            IntentFilter intentFilter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
+            mContext.registerReceiver(receiver, intentFilter);
+
+            long id = mDownloadManager.enqueue(new Request(getGoodUrl()));
+
+            assertEquals(1, getTotalNumberDownloads());
+
+            assertDownloadQueryableById(id);
+
+            receiver.waitForDownloadComplete(SHORT_TIMEOUT, id);
+
+            assertDownloadQueryableByStatus(DownloadManager.STATUS_SUCCESSFUL);
+
+            assertRemoveDownload(id, 0);
+        } finally {
+            mContext.unregisterReceiver(receiver);
+        }
+    }
+
+    public void testDownloadManagerSupportsHttpWithExternalWebServer() throws Exception {
+        if (!hasInternetConnection()) {
+            Log.i(TAG, "testDownloadManagerSupportsHttpWithExternalWebServer() ignored on device without Internet");
+            return;
+        }
+
+        // As a result of testDownloadManagerSupportsHttpsWithExternalWebServer relying on an
+        // external resource https://www.example.com this test uses http://www.example.com to help
+        // disambiguate errors from testDownloadManagerSupportsHttpsWithExternalWebServer.
+
+        final DownloadCompleteReceiver receiver = new DownloadCompleteReceiver();
+        try {
+            IntentFilter intentFilter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
+            mContext.registerReceiver(receiver, intentFilter);
+
+            long id = mDownloadManager.enqueue(new Request(Uri.parse("http://www.example.com")));
+
+            assertEquals(1, getTotalNumberDownloads());
+
+            assertDownloadQueryableById(id);
+
+            receiver.waitForDownloadComplete(LONG_TIMEOUT, id);
+
+            assertDownloadQueryableByStatus(DownloadManager.STATUS_SUCCESSFUL);
+
+            assertRemoveDownload(id, 0);
+        } finally {
+            mContext.unregisterReceiver(receiver);
+        }
+    }
+
+    public void testDownloadManagerSupportsHttpsWithExternalWebServer() throws Exception {
+        if (!hasInternetConnection()) {
+            Log.i(TAG, "testDownloadManagerSupportsHttpsWithExternalWebServer() ignored on device without Internet");
+            return;
+        }
+
+        // For HTTPS, DownloadManager trusts only SSL server certs issued by CAs trusted by the
+        // system. Unfortunately, this means that it cannot trust the mock web server's SSL cert.
+        // Until this is resolved (e.g., by making it possible to specify additional CA certs to
+        // trust for a particular download), this test relies on https://www.example.com being
+        // operational and reachable from the Android under test.
+
+        final DownloadCompleteReceiver receiver = new DownloadCompleteReceiver();
+        try {
+            IntentFilter intentFilter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
+            mContext.registerReceiver(receiver, intentFilter);
+
+            long id = mDownloadManager.enqueue(new Request(Uri.parse("https://www.example.com")));
+
+            assertEquals(1, getTotalNumberDownloads());
+
+            assertDownloadQueryableById(id);
+
+            receiver.waitForDownloadComplete(LONG_TIMEOUT, id);
+
+            assertDownloadQueryableByStatus(DownloadManager.STATUS_SUCCESSFUL);
+
+            assertRemoveDownload(id, 0);
+        } finally {
+            mContext.unregisterReceiver(receiver);
+        }
+    }
+
+    public void testMinimumDownload() throws Exception {
+        final DownloadCompleteReceiver receiver = new DownloadCompleteReceiver();
+        try {
+            IntentFilter intentFilter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
+            mContext.registerReceiver(receiver, intentFilter);
+
+            long id = mDownloadManager.enqueue(new Request(getMinimumDownloadUrl()));
+            receiver.waitForDownloadComplete(LONG_TIMEOUT, id);
+
+            ParcelFileDescriptor fileDescriptor = mDownloadManager.openDownloadedFile(id);
+            assertEquals(MINIMUM_DOWNLOAD_BYTES, fileDescriptor.getStatSize());
+
+            Cursor cursor = null;
+            try {
+                cursor = mDownloadManager.query(new Query().setFilterById(id));
+                assertTrue(cursor.moveToNext());
+                assertEquals(DownloadManager.STATUS_SUCCESSFUL, cursor.getInt(
+                        cursor.getColumnIndex(DownloadManager.COLUMN_STATUS)));
+                assertEquals(MINIMUM_DOWNLOAD_BYTES, cursor.getInt(
+                        cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES)));
+                assertFalse(cursor.moveToNext());
+            } finally {
+                if (cursor != null) {
+                    cursor.close();
+                }
+            }
+
+            assertRemoveDownload(id, 0);
+        } finally {
+            mContext.unregisterReceiver(receiver);
+        }
+    }
+
+    /**
+     * Set download locations and verify that file is downloaded to correct location.
+     *
+     * Checks three different methods of setting location: directly via setDestinationUri, and
+     * indirectly through setDestinationInExternalFilesDir and setDestinationinExternalPublicDir.
+     */
+    public void testDownloadManagerDestination() throws Exception {
+        File uriLocation = new File(mContext.getExternalFilesDir(null), "uriFile.bin");
+        if (uriLocation.exists()) {
+            assertTrue(uriLocation.delete());
+        }
+
+        File extFileLocation = new File(mContext.getExternalFilesDir(null), "extFile.bin");
+        if (extFileLocation.exists()) {
+            assertTrue(extFileLocation.delete());
+        }
+
+        File publicLocation = new File(
+                Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS),
+                "publicFile.bin");
+        if (publicLocation.exists()) {
+            assertTrue(publicLocation.delete());
+        }
+
+        final DownloadCompleteReceiver receiver = new DownloadCompleteReceiver();
+        try {
+            IntentFilter intentFilter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
+            mContext.registerReceiver(receiver, intentFilter);
+
+            Request requestUri = new Request(getGoodUrl());
+            requestUri.setDestinationUri(Uri.fromFile(uriLocation));
+            long uriId = mDownloadManager.enqueue(requestUri);
+
+            Request requestExtFile = new Request(getGoodUrl());
+            requestExtFile.setDestinationInExternalFilesDir(mContext, null, "extFile.bin");
+            long extFileId = mDownloadManager.enqueue(requestExtFile);
+
+            Request requestPublic = new Request(getGoodUrl());
+            requestPublic.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS,
+                    "publicFile.bin");
+            long publicId = mDownloadManager.enqueue(requestPublic);
+
+            int allDownloads = getTotalNumberDownloads();
+            assertEquals(3, allDownloads);
+
+            receiver.waitForDownloadComplete(SHORT_TIMEOUT, uriId, extFileId, publicId);
+
+            assertSuccessfulDownload(uriId, uriLocation);
+            assertSuccessfulDownload(extFileId, extFileLocation);
+            assertSuccessfulDownload(publicId, publicLocation);
+
+            assertRemoveDownload(uriId, allDownloads - 1);
+            assertRemoveDownload(extFileId, allDownloads - 2);
+            assertRemoveDownload(publicId, allDownloads - 3);
+        } finally {
+            mContext.unregisterReceiver(receiver);
+        }
+    }
+
+    /**
+     * Set the download location and verify that the extension of the file name is left unchanged.
+     */
+    public void testDownloadManagerDestinationExtension() throws Exception {
+        String noExt = "noiseandchirps";
+        File noExtLocation = new File(mContext.getExternalFilesDir(null), noExt);
+        if (noExtLocation.exists()) {
+            assertTrue(noExtLocation.delete());
+        }
+
+        String wrongExt = "noiseandchirps.wrong";
+        File wrongExtLocation = new File(mContext.getExternalFilesDir(null), wrongExt);
+        if (wrongExtLocation.exists()) {
+            assertTrue(wrongExtLocation.delete());
+        }
+
+        final DownloadCompleteReceiver receiver = new DownloadCompleteReceiver();
+        try {
+            IntentFilter intentFilter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
+            mContext.registerReceiver(receiver, intentFilter);
+
+            Request requestNoExt = new Request(getAssetUrl(noExt));
+            requestNoExt.setDestinationUri(Uri.fromFile(noExtLocation));
+            long noExtId = mDownloadManager.enqueue(requestNoExt);
+
+            Request requestWrongExt = new Request(getAssetUrl(wrongExt));
+            requestWrongExt.setDestinationUri(Uri.fromFile(wrongExtLocation));
+            long wrongExtId = mDownloadManager.enqueue(requestWrongExt);
+
+            int allDownloads = getTotalNumberDownloads();
+            assertEquals(2, allDownloads);
+
+            receiver.waitForDownloadComplete(SHORT_TIMEOUT, noExtId, wrongExtId);
+
+            assertSuccessfulDownload(noExtId, noExtLocation);
+            assertSuccessfulDownload(wrongExtId, wrongExtLocation);
+
+            assertRemoveDownload(noExtId, allDownloads - 1);
+            assertRemoveDownload(wrongExtId, allDownloads - 2);
+        } finally {
+            mContext.unregisterReceiver(receiver);
+        }
+    }
+
+    private class DownloadCompleteReceiver extends BroadcastReceiver {
+        private HashSet<Long> mCompleteIds = new HashSet<>();
+
+        public DownloadCompleteReceiver() {
+        }
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            synchronized (mCompleteIds) {
+                mCompleteIds.add(intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1));
+                mCompleteIds.notifyAll();
+            }
+        }
+
+        private boolean isCompleteLocked(long... ids) {
+            for (long id : ids) {
+                if (!mCompleteIds.contains(id)) {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        public void waitForDownloadComplete(long timeoutMillis, long... waitForIds)
+                throws InterruptedException {
+            if (waitForIds.length == 0) {
+                throw new IllegalArgumentException("Missing IDs to wait for");
+            }
+
+            final long startTime = SystemClock.elapsedRealtime();
+            do {
+                synchronized (mCompleteIds) {
+                    mCompleteIds.wait(timeoutMillis);
+                    if (isCompleteLocked(waitForIds)) return;
+                }
+            } while ((SystemClock.elapsedRealtime() - startTime) < timeoutMillis);
+
+            throw new InterruptedException("Timeout waiting for IDs " + Arrays.toString(waitForIds)
+                    + "; received " + mCompleteIds.toString()
+                    + ".  Make sure you have WiFi or some other connectivity for this test.");
+        }
+    }
+
+    private void clearDownloads() {
+        if (getTotalNumberDownloads() > 0) {
+            Cursor cursor = null;
+            try {
+                Query query = new Query();
+                cursor = mDownloadManager.query(query);
+                int columnIndex = cursor.getColumnIndex(DownloadManager.COLUMN_ID);
+                long[] removeIds = new long[cursor.getCount()];
+                for (int i = 0; cursor.moveToNext(); i++) {
+                    removeIds[i] = cursor.getLong(columnIndex);
+                }
+                assertEquals(removeIds.length, mDownloadManager.remove(removeIds));
+                assertEquals(0, getTotalNumberDownloads());
+            } finally {
+                if (cursor != null) {
+                    cursor.close();
+                }
+            }
+        }
+    }
+
+    private Uri getGoodUrl() {
+        return Uri.parse(mWebServer.getTestDownloadUrl("cts-good-download", 0));
+    }
+
+    private Uri getBadUrl() {
+        return Uri.parse(mWebServer.getBaseUri() + "/nosuchurl");
+    }
+
+    private Uri getMinimumDownloadUrl() {
+        return Uri.parse(mWebServer.getTestDownloadUrl("cts-minimum-download",
+                MINIMUM_DOWNLOAD_BYTES));
+    }
+
+    private Uri getAssetUrl(String asset) {
+        return Uri.parse(mWebServer.getAssetUrl(asset));
+    }
+
+    private int getTotalNumberDownloads() {
+        Cursor cursor = null;
+        try {
+            Query query = new Query();
+            cursor = mDownloadManager.query(query);
+            return cursor.getCount();
+        } finally {
+            if (cursor != null) {
+                cursor.close();
+            }
+        }
+    }
+
+    private void assertDownloadQueryableById(long downloadId) {
+        Cursor cursor = null;
+        try {
+            Query query = new Query().setFilterById(downloadId);
+            cursor = mDownloadManager.query(query);
+            assertEquals(1, cursor.getCount());
+        } finally {
+            if (cursor != null) {
+                cursor.close();
+            }
+        }
+    }
+
+    private void assertDownloadQueryableByStatus(final int status) {
+        new PollingCheck() {
+            @Override
+            protected boolean check() {
+                Cursor cursor= null;
+                try {
+                    Query query = new Query().setFilterByStatus(status);
+                    cursor = mDownloadManager.query(query);
+                    return 1 == cursor.getCount();
+                } finally {
+                    if (cursor != null) {
+                        cursor.close();
+                    }
+                }
+            }
+        }.run();
+    }
+
+    private void assertSuccessfulDownload(long id, File location) {
+        Cursor cursor = null;
+        try {
+            cursor = mDownloadManager.query(new Query().setFilterById(id));
+            assertTrue(cursor.moveToNext());
+            assertEquals(DownloadManager.STATUS_SUCCESSFUL, cursor.getInt(
+                    cursor.getColumnIndex(DownloadManager.COLUMN_STATUS)));
+            assertEquals(Uri.fromFile(location).toString(),
+                    cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI)));
+            assertTrue(location.exists());
+        } finally {
+            if (cursor != null) {
+                cursor.close();
+            }
+        }
+    }
+
+    private void assertRemoveDownload(long removeId, int expectedNumDownloads) {
+        Cursor cursor = null;
+        try {
+            assertEquals(1, mDownloadManager.remove(removeId));
+            Query query = new Query();
+            cursor = mDownloadManager.query(query);
+            assertEquals(expectedNumDownloads, cursor.getCount());
+        } finally {
+            if (cursor != null) {
+                cursor.close();
+            }
+        }
+    }
+
+    private boolean hasInternetConnection() {
+        final PackageManager pm = getContext().getPackageManager();
+        return pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)
+                || pm.hasSystemFeature(PackageManager.FEATURE_WIFI)
+                || pm.hasSystemFeature(PackageManager.FEATURE_ETHERNET);
+    }
+}
diff --git a/tests/app/src/android/app/cts/ExpandableListActivityTest.java b/tests/app/src/android/app/cts/ExpandableListActivityTest.java
new file mode 100644
index 0000000..a457cf7
--- /dev/null
+++ b/tests/app/src/android/app/cts/ExpandableListActivityTest.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.cts;
+
+import android.app.stubs.ActivityTestsBase;
+import android.app.stubs.ExpandableListTestActivity;
+import android.app.stubs.LaunchpadActivity;
+import android.content.ComponentName;
+
+public class ExpandableListActivityTest extends ActivityTestsBase {
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mIntent.putExtra("component", new ComponentName(getContext(),
+                ExpandableListTestActivity.class));
+    }
+
+    public void testSelect() {
+        runLaunchpad(LaunchpadActivity.EXPANDLIST_SELECT);
+    }
+
+    public void testView() {
+        runLaunchpad(LaunchpadActivity.EXPANDLIST_VIEW);
+    }
+
+    public void testCallback() {
+        runLaunchpad(LaunchpadActivity.EXPANDLIST_CALLBACK);
+    }
+}
\ No newline at end of file
diff --git a/tests/app/src/android/app/cts/ExpandableListTestActivity.java b/tests/app/src/android/app/cts/ExpandableListTestActivity.java
deleted file mode 100644
index 8c8b65b..0000000
--- a/tests/app/src/android/app/cts/ExpandableListTestActivity.java
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import android.app.ExpandableListActivity;
-import android.os.Bundle;
-import android.os.Looper;
-import android.os.MessageQueue;
-import android.view.ContextMenu;
-import android.view.View;
-import android.view.ContextMenu.ContextMenuInfo;
-import android.widget.ExpandableListAdapter;
-import android.widget.ExpandableListView;
-import android.widget.SimpleExpandableListAdapter;
-
-import com.android.internal.R;
-import com.android.internal.view.menu.ContextMenuBuilder;
-import com.google.android.collect.Lists;
-
-public class ExpandableListTestActivity extends ExpandableListActivity {
-    private static final String NAME = "NAME";
-    private static final String IS_EVEN = "IS_EVEN";
-    private boolean mOnContentChangedCalled = false;
-    private boolean mOnCreateContextMenuCalled = false;
-    private boolean mOnGroupCollapseCalled = false;
-    private boolean mOnGroupExpandCalled = false;
-    private ExpandableListAdapter mAdapter;
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        final List<Map<String, String>> groupData = Lists.newArrayList();
-        final List<List<Map<String, String>>> childData = Lists.newArrayList();
-        for (int i = 0; i < 20; i++) {
-            final Map<String, String> curGroupMap = new HashMap<String, String>();
-            groupData.add(curGroupMap);
-            curGroupMap.put(NAME, "Group " + i);
-            curGroupMap.put(IS_EVEN, (i % 2 == 0) ? "This group is even" : "This group is odd");
-
-            final List<Map<String, String>> children = Lists.newArrayList();
-            for (int j = 0; j < 15; j++) {
-                Map<String, String> curChildMap = new HashMap<String, String>();
-                children.add(curChildMap);
-                curChildMap.put(NAME, "Child " + j);
-                curChildMap.put(IS_EVEN, (j % 2 == 0) ? "This child is even" : "This child is odd");
-            }
-            childData.add(children);
-        }
-
-        // Set up our adapter
-        mAdapter = new SimpleExpandableListAdapter(this, groupData,
-                R.layout.simple_expandable_list_item_1,
-                new String[] { NAME, IS_EVEN }, new int[] { R.id.text1, R.id.text2 }, childData,
-                R.layout.simple_expandable_list_item_2,
-                new String[] { NAME, IS_EVEN }, new int[] { R.id.text1, R.id.text2 });
-        setListAdapter(mAdapter);
-
-    }
-
-    private int testCallback() {
-        final ExpandableListView v = getExpandableListView();
-        final ExpandableListAdapter a = getExpandableListAdapter();
-        final View convertView = new View(this);
-        final View gv = a.getGroupView(0, true, convertView, v);
-        v.setOnCreateContextMenuListener(this);
-        v.createContextMenu(new ContextMenuBuilder(this));
-        for (int i = 0; i < 20; i++) {
-            v.expandGroup(i);
-            v.performClick();
-            v.performLongClick();
-            for (int k = 0; k < 15; k++) {
-                v.performItemClick(gv, i, k);
-            }
-            v.collapseGroup(i);
-        }
-        if (mOnContentChangedCalled && mOnCreateContextMenuCalled
-                && mOnGroupCollapseCalled && mOnGroupExpandCalled)
-            return RESULT_OK;
-
-        return RESULT_CANCELED;
-    }
-
-    private int testView() {
-        final ExpandableListView currentView = getExpandableListView();
-        for (int i = 0; i < 20; i++) {
-            if (!currentView.expandGroup(i))
-                return RESULT_CANCELED;
-            if (!currentView.collapseGroup(i))
-                return RESULT_CANCELED;
-        }
-        final View otherView = findViewById(android.R.id.list);
-        setContentView(otherView);
-        if (!otherView.equals(getExpandableListView()))
-            return RESULT_CANCELED;
-        setContentView(currentView);
-        return RESULT_OK;
-    }
-
-    private int testSelecte() {
-        final ExpandableListView v = getExpandableListView();
-        for (int i = 0; i < 20; i++) {
-            v.expandGroup(i);
-            setSelectedGroup(i);
-            for (int k = 0; k < 15; k++) {
-                setSelectedChild(i, k, false);
-                if (ExpandableListView.getPackedPositionForChild(i, k) != getSelectedPosition())
-                    return RESULT_CANCELED;
-            }
-
-            for (int k = 0; k < 15; k++) {
-                setSelectedChild(i, k, true);
-                if (ExpandableListView.getPackedPositionForChild(i, k) != getSelectedPosition())
-                    return RESULT_CANCELED;
-            }
-            v.collapseGroup(i);
-        }
-        return RESULT_OK;
-    }
-
-    @Override
-    protected void onResume() {
-        super.onResume();
-        final String action = getIntent().getAction();
-        if (LaunchpadActivity.EXPANDLIST_SELECT.equals(action)) {
-            setResult(testSelecte());
-        } else if (LaunchpadActivity.EXPANDLIST_VIEW.equals(action)) {
-            setResult(testView());
-        } else if (LaunchpadActivity.EXPANDLIST_CALLBACK.equals(action)) {
-            setResult(testCallback());
-        }
-        Looper.myQueue().addIdleHandler(new Idler());
-    }
-
-    protected void onRestoreInstanceState(Bundle state) {
-        super.onRestoreInstanceState(state);
-    }
-
-    @Override
-    public void onContentChanged() {
-        mOnContentChangedCalled = true;
-        super.onContentChanged();
-    }
-
-    @Override
-    public void onCreateContextMenu(ContextMenu menu, View v,
-            ContextMenuInfo menuInfo) {
-        mOnCreateContextMenuCalled = true;
-        super.onCreateContextMenu(menu, v, menuInfo);
-    }
-
-    @Override
-    public void onGroupCollapse(int groupPosition) {
-        mOnGroupCollapseCalled = true;
-        super.onGroupCollapse(groupPosition);
-    }
-
-    @Override
-    public void onGroupExpand(int groupPosition) {
-        mOnGroupExpandCalled = true;
-        super.onGroupExpand(groupPosition);
-    }
-
-    protected void onSaveInstanceState(Bundle outState) {
-        super.onSaveInstanceState(outState);
-    }
-
-    protected void onStop() {
-        super.onStop();
-    }
-
-    private class Idler implements MessageQueue.IdleHandler {
-        public final boolean queueIdle() {
-            finish();
-            return false;
-        }
-    }
-
-}
diff --git a/tests/app/src/android/app/cts/FragmentReplaceTest.java b/tests/app/src/android/app/cts/FragmentReplaceTest.java
new file mode 100644
index 0000000..ad9e3af
--- /dev/null
+++ b/tests/app/src/android/app/cts/FragmentReplaceTest.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.cts;
+
+import android.app.stubs.FragmentTestActivity;
+import android.app.stubs.FragmentTestActivity.TestFragment;
+import android.app.stubs.R;
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.UiThreadTest;
+
+/**
+ * Test to prevent regressions in FragmentManager fragment replace method. See b/24693644
+ */
+public class FragmentReplaceTest extends
+        ActivityInstrumentationTestCase2<FragmentTestActivity> {
+    private FragmentTestActivity mActivity;
+
+
+    public FragmentReplaceTest() {
+        super(FragmentTestActivity.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mActivity = getActivity();
+    }
+
+    @UiThreadTest
+    public void testReplaceFragment() throws Throwable {
+        mActivity.getFragmentManager().beginTransaction()
+                .add(R.id.content, new TestFragment(R.layout.fragment_a))
+                .addToBackStack(null)
+                .commit();
+        mActivity.getFragmentManager().executePendingTransactions();
+        assertNotNull(mActivity.findViewById(R.id.textA));
+        assertNull(mActivity.findViewById(R.id.textB));
+        assertNull(mActivity.findViewById(R.id.textC));
+
+        mActivity.getFragmentManager().beginTransaction()
+                .add(R.id.content, new TestFragment(R.layout.fragment_b))
+                .addToBackStack(null)
+                .commit();
+        mActivity.getFragmentManager().executePendingTransactions();
+        assertNotNull(mActivity.findViewById(R.id.textA));
+        assertNotNull(mActivity.findViewById(R.id.textB));
+        assertNull(mActivity.findViewById(R.id.textC));
+
+        mActivity.getFragmentManager().beginTransaction()
+                .replace(R.id.content, new TestFragment(R.layout.fragment_c))
+                .addToBackStack(null)
+                .commit();
+        mActivity.getFragmentManager().executePendingTransactions();
+        assertNull(mActivity.findViewById(R.id.textA));
+        assertNull(mActivity.findViewById(R.id.textB));
+        assertNotNull(mActivity.findViewById(R.id.textC));
+    }
+}
diff --git a/tests/tests/app/src/android/app/cts/FragmentTest.java b/tests/app/src/android/app/cts/FragmentTest.java
similarity index 100%
rename from tests/tests/app/src/android/app/cts/FragmentTest.java
rename to tests/app/src/android/app/cts/FragmentTest.java
diff --git a/tests/app/src/android/app/cts/FragmentTransitionTest.java b/tests/app/src/android/app/cts/FragmentTransitionTest.java
new file mode 100644
index 0000000..7270672
--- /dev/null
+++ b/tests/app/src/android/app/cts/FragmentTransitionTest.java
@@ -0,0 +1,466 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.cts;
+
+import android.app.FragmentManager;
+import android.app.stubs.FragmentTestActivity;
+import android.app.stubs.FragmentTestActivity.OnTransitionListener;
+import android.app.stubs.FragmentTestActivity.TestFragment;
+import android.app.stubs.R;
+import android.os.Debug;
+import android.os.SystemClock;
+import android.test.ActivityInstrumentationTestCase2;
+import android.view.View;
+
+public class FragmentTransitionTest extends
+        ActivityInstrumentationTestCase2<FragmentTestActivity> {
+    private TestFragment mStartFragment;
+    private TestFragment mMidFragment;
+    private TestFragment mEndFragment;
+    private FragmentTestActivity mActivity;
+
+    public FragmentTransitionTest() {
+        super(FragmentTestActivity.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mStartFragment = null;
+        mMidFragment = null;
+        mEndFragment = null;
+        mActivity = getActivity();
+    }
+
+    public void testFragmentTransition() throws Throwable {
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mStartFragment = new TestFragment(R.layout.fragment_start);
+                mActivity.getFragmentManager().beginTransaction()
+                        .replace(R.id.content, mStartFragment)
+                        .commit();
+                mActivity.getFragmentManager().executePendingTransactions();
+            }
+        });
+        waitForEnd(mStartFragment, TestFragment.ENTER);
+        assertTrue(mStartFragment.wasEndCalled(TestFragment.ENTER));
+        mStartFragment.clearNotifications();
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                final View sharedElement = mActivity.findViewById(R.id.hello);
+                assertEquals("source", sharedElement.getTransitionName());
+
+                mEndFragment = new TestFragment(R.layout.fragment_end);
+                mActivity.getFragmentManager().beginTransaction()
+                        .replace(R.id.content, mEndFragment)
+                        .addSharedElement(sharedElement, "destination")
+                        .addToBackStack(null)
+                        .commit();
+                mActivity.getFragmentManager().executePendingTransactions();
+            }
+        });
+        waitForEnd(mEndFragment, TestFragment.ENTER);
+        assertTrue(mEndFragment.wasEndCalled(TestFragment.ENTER));
+        assertTrue(mStartFragment.wasEndCalled(TestFragment.EXIT));
+        assertTrue(mEndFragment.wasEndCalled(TestFragment.SHARED_ELEMENT_ENTER));
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                final View textView = mActivity.findViewById(R.id.hello);
+                assertEquals("destination", textView.getTransitionName());
+                mActivity.getFragmentManager().popBackStack();
+                mActivity.getFragmentManager().executePendingTransactions();
+            }
+        });
+        waitForEnd(mStartFragment, TestFragment.REENTER);
+        assertTrue(mStartFragment.wasEndCalled(TestFragment.REENTER));
+        assertTrue(mEndFragment.wasEndCalled(TestFragment.RETURN));
+    }
+
+    public void testFirstOutLastInTransition() throws Throwable {
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mStartFragment = new TestFragment(R.layout.fragment_start);
+                mActivity.getFragmentManager().beginTransaction()
+                        .replace(R.id.content, mStartFragment)
+                        .commit();
+                mActivity.getFragmentManager().executePendingTransactions();
+            }
+        });
+        waitForEnd(mStartFragment, TestFragment.ENTER);
+        assertTrue(mStartFragment.wasEndCalled(TestFragment.ENTER));
+        mStartFragment.clearNotifications();
+
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mMidFragment = new TestFragment(R.layout.checkbox_layout);
+                mEndFragment = new TestFragment(R.layout.fragment_end);
+                mActivity.getFragmentManager().beginTransaction()
+                        .replace(R.id.content, mMidFragment)
+                        .replace(R.id.content, mEndFragment)
+                        .addToBackStack(null)
+                        .commit();
+                mActivity.getFragmentManager().executePendingTransactions();
+            }
+        });
+        waitForEnd(mEndFragment, TestFragment.ENTER);
+        assertTrue(mEndFragment.wasEndCalled(TestFragment.ENTER));
+        assertFalse(mEndFragment.wasEndCalled(TestFragment.EXIT));
+        assertFalse(mEndFragment.wasEndCalled(TestFragment.RETURN));
+        assertFalse(mEndFragment.wasEndCalled(TestFragment.REENTER));
+
+        assertTrue(mStartFragment.wasEndCalled(TestFragment.EXIT));
+        assertFalse(mStartFragment.wasEndCalled(TestFragment.ENTER));
+        assertFalse(mStartFragment.wasEndCalled(TestFragment.RETURN));
+        assertFalse(mStartFragment.wasEndCalled(TestFragment.REENTER));
+
+        assertFalse(mMidFragment.wasStartCalled(TestFragment.ENTER));
+        assertFalse(mMidFragment.wasStartCalled(TestFragment.EXIT));
+        assertFalse(mMidFragment.wasStartCalled(TestFragment.REENTER));
+        assertFalse(mMidFragment.wasStartCalled(TestFragment.RETURN));
+
+        mStartFragment.clearNotifications();
+        mEndFragment.clearNotifications();
+
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mActivity.getFragmentManager().popBackStack();
+                mActivity.getFragmentManager().executePendingTransactions();
+            }
+        });
+        waitForEnd(mEndFragment, TestFragment.RETURN);
+        assertTrue(mEndFragment.wasEndCalled(TestFragment.RETURN));
+        assertFalse(mMidFragment.wasStartCalled(TestFragment.ENTER));
+        assertFalse(mMidFragment.wasStartCalled(TestFragment.EXIT));
+        assertFalse(mMidFragment.wasStartCalled(TestFragment.REENTER));
+        assertFalse(mMidFragment.wasStartCalled(TestFragment.RETURN));
+
+        assertTrue(mStartFragment.wasStartCalled(TestFragment.REENTER));
+        assertFalse(mStartFragment.wasStartCalled(TestFragment.ENTER));
+        assertFalse(mStartFragment.wasStartCalled(TestFragment.EXIT));
+        assertFalse(mStartFragment.wasStartCalled(TestFragment.RETURN));
+    }
+
+    public void testPopTwo() throws Throwable {
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mStartFragment = new TestFragment(R.layout.fragment_start);
+                mActivity.getFragmentManager().beginTransaction()
+                        .replace(R.id.content, mStartFragment)
+                        .commit();
+                mActivity.getFragmentManager().executePendingTransactions();
+            }
+        });
+        waitForEnd(mStartFragment, TestFragment.ENTER);
+        assertTrue(mStartFragment.wasEndCalled(TestFragment.ENTER));
+        mStartFragment.clearNotifications();
+
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mMidFragment = new TestFragment(R.layout.checkbox_layout);
+                mActivity.getFragmentManager().beginTransaction()
+                        .replace(R.id.content, mMidFragment)
+                        .addToBackStack(null)
+                        .commit();
+                mActivity.getFragmentManager().executePendingTransactions();
+            }
+        });
+        waitForEnd(mMidFragment, TestFragment.ENTER);
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mEndFragment = new TestFragment(R.layout.fragment_end);
+                mActivity.getFragmentManager().beginTransaction()
+                        .replace(R.id.content, mEndFragment)
+                        .addToBackStack(null)
+                        .commit();
+                mActivity.getFragmentManager().executePendingTransactions();
+            }
+        });
+        waitForEnd(mEndFragment, TestFragment.ENTER);
+        assertTrue(mEndFragment.wasEndCalled(TestFragment.ENTER));
+        assertFalse(mEndFragment.wasEndCalled(TestFragment.EXIT));
+        assertFalse(mEndFragment.wasEndCalled(TestFragment.RETURN));
+        assertFalse(mEndFragment.wasEndCalled(TestFragment.REENTER));
+
+        assertTrue(mStartFragment.wasEndCalled(TestFragment.EXIT));
+        assertFalse(mStartFragment.wasEndCalled(TestFragment.ENTER));
+        assertFalse(mStartFragment.wasEndCalled(TestFragment.RETURN));
+        assertFalse(mStartFragment.wasEndCalled(TestFragment.REENTER));
+
+        assertTrue(mMidFragment.wasStartCalled(TestFragment.ENTER));
+        assertTrue(mMidFragment.wasStartCalled(TestFragment.EXIT));
+        assertFalse(mMidFragment.wasStartCalled(TestFragment.REENTER));
+        assertFalse(mMidFragment.wasStartCalled(TestFragment.RETURN));
+
+        mStartFragment.clearNotifications();
+        mMidFragment.clearNotifications();
+        mEndFragment.clearNotifications();
+
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                FragmentManager fm = mActivity.getFragmentManager();
+                int id = fm.getBackStackEntryAt(0).getId();
+                fm.popBackStack(id, FragmentManager.POP_BACK_STACK_INCLUSIVE);
+                fm.executePendingTransactions();
+            }
+        });
+        waitForEnd(mEndFragment, TestFragment.RETURN);
+        assertTrue(mEndFragment.wasEndCalled(TestFragment.RETURN));
+
+        assertFalse(mMidFragment.wasStartCalled(TestFragment.ENTER));
+        assertFalse(mMidFragment.wasStartCalled(TestFragment.EXIT));
+        assertFalse(mMidFragment.wasStartCalled(TestFragment.REENTER));
+        assertFalse(mMidFragment.wasStartCalled(TestFragment.RETURN));
+
+        assertTrue(mStartFragment.wasStartCalled(TestFragment.REENTER));
+        assertFalse(mStartFragment.wasStartCalled(TestFragment.ENTER));
+        assertFalse(mStartFragment.wasStartCalled(TestFragment.EXIT));
+        assertFalse(mStartFragment.wasStartCalled(TestFragment.RETURN));
+    }
+
+    public void testNullTransition() throws Throwable {
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mStartFragment = new TestFragment(R.layout.fragment_start);
+                mStartFragment.clearTransitions();
+                mActivity.getFragmentManager().beginTransaction()
+                        .replace(R.id.content, mStartFragment)
+                        .commit();
+                mActivity.getFragmentManager().executePendingTransactions();
+            }
+        });
+        waitForStart(mStartFragment, TestFragment.ENTER);
+        // No transitions
+        assertFalse(mStartFragment.wasStartCalled(TestFragment.ENTER));
+
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mMidFragment = new TestFragment(R.layout.checkbox_layout);
+                mEndFragment = new TestFragment(R.layout.fragment_end);
+                mEndFragment.clearTransitions();
+                mActivity.getFragmentManager().beginTransaction()
+                        .replace(R.id.content, mMidFragment)
+                        .replace(R.id.content, mEndFragment)
+                        .addToBackStack(null)
+                        .commit();
+                mActivity.getFragmentManager().executePendingTransactions();
+            }
+        });
+        waitForStart(mEndFragment, TestFragment.ENTER);
+        assertFalse(mEndFragment.wasEndCalled(TestFragment.ENTER));
+        assertFalse(mEndFragment.wasEndCalled(TestFragment.EXIT));
+        assertFalse(mEndFragment.wasEndCalled(TestFragment.RETURN));
+        assertFalse(mEndFragment.wasEndCalled(TestFragment.REENTER));
+
+        assertFalse(mStartFragment.wasEndCalled(TestFragment.EXIT));
+        assertFalse(mStartFragment.wasEndCalled(TestFragment.ENTER));
+        assertFalse(mStartFragment.wasEndCalled(TestFragment.RETURN));
+        assertFalse(mStartFragment.wasEndCalled(TestFragment.REENTER));
+
+        assertFalse(mMidFragment.wasStartCalled(TestFragment.ENTER));
+        assertFalse(mMidFragment.wasStartCalled(TestFragment.EXIT));
+        assertFalse(mMidFragment.wasStartCalled(TestFragment.REENTER));
+        assertFalse(mMidFragment.wasStartCalled(TestFragment.RETURN));
+
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mActivity.getFragmentManager().popBackStack();
+                mActivity.getFragmentManager().executePendingTransactions();
+            }
+        });
+        waitForStart(mEndFragment, TestFragment.RETURN);
+        assertFalse(mEndFragment.wasEndCalled(TestFragment.RETURN));
+        assertFalse(mMidFragment.wasStartCalled(TestFragment.ENTER));
+        assertFalse(mMidFragment.wasStartCalled(TestFragment.EXIT));
+        assertFalse(mMidFragment.wasStartCalled(TestFragment.REENTER));
+        assertFalse(mMidFragment.wasStartCalled(TestFragment.RETURN));
+
+        assertFalse(mStartFragment.wasStartCalled(TestFragment.REENTER));
+        assertFalse(mStartFragment.wasStartCalled(TestFragment.ENTER));
+        assertFalse(mStartFragment.wasStartCalled(TestFragment.EXIT));
+        assertFalse(mStartFragment.wasStartCalled(TestFragment.RETURN));
+    }
+
+    public void testRemoveAdded() throws Throwable {
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mStartFragment = new TestFragment(R.layout.fragment_start);
+                mActivity.getFragmentManager().beginTransaction()
+                        .replace(R.id.content, mStartFragment)
+                        .commit();
+                mActivity.getFragmentManager().executePendingTransactions();
+            }
+        });
+        waitForEnd(mStartFragment, TestFragment.ENTER);
+        assertTrue(mStartFragment.wasEndCalled(TestFragment.ENTER));
+        mStartFragment.clearNotifications();
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mEndFragment = new TestFragment(R.layout.fragment_end);
+                mActivity.getFragmentManager().beginTransaction()
+                        .replace(R.id.content, mEndFragment)
+                        .replace(R.id.content, mStartFragment)
+                        .replace(R.id.content, mEndFragment)
+                        .addToBackStack(null)
+                        .commit();
+                mActivity.getFragmentManager().executePendingTransactions();
+            }
+        });
+        waitForEnd(mEndFragment, TestFragment.ENTER);
+        assertTrue(mEndFragment.wasEndCalled(TestFragment.ENTER));
+        assertTrue(mStartFragment.wasEndCalled(TestFragment.EXIT));
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mActivity.getFragmentManager().popBackStack();
+                mActivity.getFragmentManager().executePendingTransactions();
+            }
+        });
+        waitForEnd(mStartFragment, TestFragment.REENTER);
+        assertTrue(mStartFragment.wasEndCalled(TestFragment.REENTER));
+        assertTrue(mEndFragment.wasEndCalled(TestFragment.RETURN));
+    }
+
+    public void testAddRemoved() throws Throwable {
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mStartFragment = new TestFragment(R.layout.fragment_start);
+                mActivity.getFragmentManager().beginTransaction()
+                        .replace(R.id.content, mStartFragment)
+                        .commit();
+                mActivity.getFragmentManager().executePendingTransactions();
+            }
+        });
+        waitForEnd(mStartFragment, TestFragment.ENTER);
+        assertTrue(mStartFragment.wasEndCalled(TestFragment.ENTER));
+        mStartFragment.clearNotifications();
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mEndFragment = new TestFragment(R.layout.fragment_end);
+                mActivity.getFragmentManager().beginTransaction()
+                        .replace(R.id.content, mEndFragment)
+                        .replace(R.id.content, mStartFragment)
+                        .addToBackStack(null)
+                        .commit();
+                mActivity.getFragmentManager().executePendingTransactions();
+            }
+        });
+        waitForStart(mStartFragment, TestFragment.ENTER);
+        assertFalse(mStartFragment.wasStartCalled(TestFragment.ENTER));
+        assertFalse(mStartFragment.wasStartCalled(TestFragment.EXIT));
+        assertFalse(mEndFragment.wasStartCalled(TestFragment.ENTER));
+        assertFalse(mEndFragment.wasStartCalled(TestFragment.EXIT));
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mActivity.getFragmentManager().popBackStack();
+                mActivity.getFragmentManager().executePendingTransactions();
+            }
+        });
+        waitForStart(mStartFragment, TestFragment.REENTER);
+        assertFalse(mStartFragment.wasStartCalled(TestFragment.REENTER));
+        assertFalse(mStartFragment.wasStartCalled(TestFragment.RETURN));
+        assertFalse(mEndFragment.wasStartCalled(TestFragment.REENTER));
+        assertFalse(mEndFragment.wasStartCalled(TestFragment.RETURN));
+    }
+
+    private boolean waitForStart(TestFragment fragment, int key) throws InterruptedException {
+        final boolean started;
+        WaitForTransition listener = new WaitForTransition(key, true);
+        fragment.setOnTransitionListener(listener);
+        final long endTime = SystemClock.uptimeMillis() + 100;
+        synchronized (listener) {
+            long waitTime;
+            while ((waitTime = endTime - SystemClock.uptimeMillis()) > 0 &&
+                    !listener.isDone()) {
+                listener.wait(waitTime);
+            }
+            started = listener.isDone();
+        }
+        fragment.setOnTransitionListener(null);
+        getInstrumentation().waitForIdleSync();
+        return started;
+    }
+
+    private boolean waitForEnd(TestFragment fragment, int key) throws InterruptedException {
+        if (!waitForStart(fragment, key)) {
+            return false;
+        }
+        final boolean ended;
+        WaitForTransition listener = new WaitForTransition(key, false);
+        fragment.setOnTransitionListener(listener);
+        final long endTime = SystemClock.uptimeMillis() + 400;
+        synchronized (listener) {
+            long waitTime;
+            while ((waitTime = endTime - SystemClock.uptimeMillis()) > 0 &&
+                    !listener.isDone()) {
+                listener.wait(waitTime);
+            }
+            ended = listener.isDone();
+        }
+        fragment.setOnTransitionListener(null);
+        getInstrumentation().waitForIdleSync();
+        return ended;
+    }
+
+    private static class WaitForTransition implements OnTransitionListener {
+        final int key;
+        final boolean isStart;
+        boolean isDone;
+
+        public WaitForTransition(int key, boolean isStart) {
+            this.key = key;
+            this.isStart = isStart;
+        }
+
+        protected boolean isComplete(TestFragment fragment) {
+            if (isStart) {
+                return fragment.wasStartCalled(key);
+            } else {
+                return fragment.wasEndCalled(key);
+            }
+        }
+
+        public synchronized boolean isDone() {
+            return isDone;
+        }
+
+        @Override
+        public synchronized void onTransition(TestFragment fragment) {
+            isDone = isComplete(fragment);
+            if (isDone) {
+                notifyAll();
+            }
+        }
+    }
+
+}
diff --git a/tests/app/src/android/app/cts/ISecondary.aidl b/tests/app/src/android/app/cts/ISecondary.aidl
deleted file mode 100644
index c3280d3..0000000
--- a/tests/app/src/android/app/cts/ISecondary.aidl
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-interface ISecondary {
-
-    int getPid();
-
-    long getElapsedCpuTime();
-
-    String getTimeZoneID();
-}
diff --git a/tests/app/src/android/app/cts/InstrumentationTest.java b/tests/app/src/android/app/cts/InstrumentationTest.java
new file mode 100644
index 0000000..5019586
--- /dev/null
+++ b/tests/app/src/android/app/cts/InstrumentationTest.java
@@ -0,0 +1,717 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.cts;
+
+import android.app.Activity;
+import android.app.Application;
+import android.app.Instrumentation;
+import android.app.Instrumentation.ActivityMonitor;
+import android.app.Instrumentation.ActivityResult;
+import android.app.stubs.InstrumentationTestActivity;
+import android.app.stubs.MockApplication;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.ActivityInfo;
+import android.content.res.Configuration;
+import android.graphics.Point;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Debug;
+import android.os.SystemClock;
+import android.test.InstrumentationTestCase;
+import android.test.UiThreadTest;
+import android.view.InputQueue;
+import android.view.KeyCharacterMap;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.SurfaceHolder;
+import android.view.View;
+import android.view.ViewGroup.LayoutParams;
+import android.view.Window;
+
+import java.util.List;
+
+import android.app.stubs.R;
+
+public class InstrumentationTest extends InstrumentationTestCase {
+
+    private static final int WAIT_TIME = 1000;
+    private Instrumentation mInstrumentation;
+    private InstrumentationTestActivity mActivity;
+    private Intent mIntent;
+    private boolean mRunOnMainSyncResult;
+    private Context mContext;
+    private MockActivity mMockActivity;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mInstrumentation = getInstrumentation();
+        mContext = mInstrumentation.getTargetContext();
+        mIntent = new Intent(mContext, InstrumentationTestActivity.class);
+        mIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        mActivity = (InstrumentationTestActivity) mInstrumentation.startActivitySync(mIntent);
+    }
+
+    protected void tearDown() throws Exception {
+        mInstrumentation = null;
+        mIntent = null;
+        if (mActivity != null) {
+            mActivity.finish();
+            mActivity = null;
+        }
+        super.tearDown();
+    }
+
+    public void testConstructor() throws Exception {
+        new Instrumentation();
+    }
+
+    public void testMonitor() throws Exception {
+        if (mActivity != null)
+            mActivity.finish();
+        ActivityResult result = new ActivityResult(Activity.RESULT_OK, new Intent());
+        ActivityMonitor monitor = new ActivityMonitor(
+                InstrumentationTestActivity.class.getName(), result, false);
+        mInstrumentation.addMonitor(monitor);
+        Intent intent = new Intent(mContext, InstrumentationTestActivity.class);
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        mContext.startActivity(intent);
+        Activity activity = mInstrumentation.waitForMonitorWithTimeout(monitor, WAIT_TIME);
+        assertTrue(activity instanceof InstrumentationTestActivity);
+        assertTrue(mInstrumentation.checkMonitorHit(monitor, 1));
+        activity.finish();
+
+        mInstrumentation.addMonitor(monitor);
+        mInstrumentation.removeMonitor(monitor);
+        Activity a = mInstrumentation.startActivitySync(intent);
+        assertTrue(a instanceof InstrumentationTestActivity);
+        activity = mInstrumentation.waitForMonitorWithTimeout(monitor, WAIT_TIME);
+        assertNull(activity);
+        a.finish();
+
+        IntentFilter filter = new IntentFilter();
+        ActivityMonitor am = mInstrumentation.addMonitor(filter, result, false);
+        mContext.startActivity(intent);
+        mInstrumentation.waitForIdleSync();
+        activity = am.waitForActivity();
+        assertTrue(activity instanceof InstrumentationTestActivity);
+        activity.finish();
+        mInstrumentation.removeMonitor(am);
+        am = mInstrumentation
+                .addMonitor(InstrumentationTestActivity.class.getName(), result, false);
+        mContext.startActivity(intent);
+        activity = am.waitForActivity();
+        assertTrue(activity instanceof InstrumentationTestActivity);
+        activity.finish();
+        mInstrumentation.removeMonitor(am);
+    }
+
+    public void testCallActivityOnCreate() throws Throwable {
+        mActivity.setOnCreateCalled(false);
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                mInstrumentation.callActivityOnCreate(mActivity, new Bundle());
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+        assertTrue(mActivity.isOnCreateCalled());
+    }
+
+    public void testAllocCounting() throws Exception {
+        mInstrumentation.startAllocCounting();
+
+        Bundle b = mInstrumentation.getAllocCounts();
+        assertTrue(b.size() > 0);
+        b = mInstrumentation.getBinderCounts();
+        assertTrue(b.size() > 0);
+
+        int globeAllocCount = Debug.getGlobalAllocCount();
+        int globeAllocSize = Debug.getGlobalAllocSize();
+        int globeExternalAllCount = Debug.getGlobalExternalAllocCount();
+        int globeExternalAllSize = Debug.getGlobalExternalAllocSize();
+        int threadAllocCount = Debug.getThreadAllocCount();
+
+        assertTrue(Debug.getGlobalAllocCount() >= globeAllocCount);
+        assertTrue(Debug.getGlobalAllocSize() >= globeAllocSize);
+        assertTrue(Debug.getGlobalExternalAllocCount() >= globeExternalAllCount);
+        assertTrue(Debug.getGlobalExternalAllocSize() >= globeExternalAllSize);
+        assertTrue(Debug.getThreadAllocCount() >= threadAllocCount);
+
+        mInstrumentation.stopAllocCounting();
+
+        globeAllocCount = Debug.getGlobalAllocCount();
+        globeAllocSize = Debug.getGlobalAllocSize();
+        globeExternalAllCount = Debug.getGlobalExternalAllocCount();
+        globeExternalAllSize = Debug.getGlobalExternalAllocSize();
+        threadAllocCount = Debug.getThreadAllocCount();
+        assertEquals(globeAllocCount, Debug.getGlobalAllocCount());
+        assertEquals(globeAllocSize, Debug.getGlobalAllocSize());
+        assertEquals(globeExternalAllCount, Debug.getGlobalExternalAllocCount());
+        assertEquals(globeExternalAllSize, Debug.getGlobalExternalAllocSize());
+        assertEquals(threadAllocCount, Debug.getThreadAllocCount());
+    }
+
+    public void testSendTrackballEventSync() throws Exception {
+        long now = SystemClock.uptimeMillis();
+        MotionEvent orig = MotionEvent.obtain(now, now, MotionEvent.ACTION_DOWN,
+                100, 100, 0);
+        mInstrumentation.sendTrackballEventSync(orig);
+        mInstrumentation.waitForIdleSync();
+
+        MotionEvent motionEvent = mActivity.getMotionEvent();
+        assertEquals(orig.getMetaState(), motionEvent.getMetaState());
+        assertEquals(orig.getEventTime(), motionEvent.getEventTime());
+        assertEquals(orig.getDownTime(), motionEvent.getDownTime());
+    }
+
+    public void testCallApplicationOnCreate() throws Exception {
+        InstrumentationTestStub ca = new InstrumentationTestStub();
+        mInstrumentation.callApplicationOnCreate(ca);
+        assertTrue(ca.mIsOnCreateCalled);
+    }
+
+    public void testContext() throws Exception {
+        Context c1 = mInstrumentation.getContext();
+        Context c2 = mInstrumentation.getTargetContext();
+        assertNotSame(c1.getPackageName(), c2.getPackageName());
+    }
+
+    public void testInvokeMenuActionSync() throws Exception {
+        final int resId = R.id.goto_menu_id;
+        if (mActivity.getWindow().hasFeature(Window.FEATURE_OPTIONS_PANEL)) {
+            mInstrumentation.invokeMenuActionSync(mActivity, resId, 0);
+            mInstrumentation.waitForIdleSync();
+
+            assertEquals(resId, mActivity.getMenuID());
+        }
+    }
+
+    public void testCallActivityOnPostCreate() throws Throwable {
+        mActivity.setOnPostCreate(false);
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                mInstrumentation.callActivityOnPostCreate(mActivity, new Bundle());
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+        assertTrue(mActivity.isOnPostCreate());
+    }
+
+    public void testCallActivityOnNewIntent() throws Throwable {
+        mActivity.setOnNewIntentCalled(false);
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                mInstrumentation.callActivityOnNewIntent(mActivity, null);
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+
+        assertTrue(mActivity.isOnNewIntentCalled());
+    }
+
+    public void testCallActivityOnResume() throws Throwable {
+        mActivity.setOnResume(false);
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                mInstrumentation.callActivityOnResume(mActivity);
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+        assertTrue(mActivity.isOnResume());
+    }
+
+    public void testMisc() throws Exception {
+    }
+
+    public void testPerformanceSnapshot() throws Exception {
+        mInstrumentation.setAutomaticPerformanceSnapshots();
+        mInstrumentation.startPerformanceSnapshot();
+        mInstrumentation.endPerformanceSnapshot();
+    }
+
+    public void testProfiling() throws Exception {
+        // by default, profiling was disabled. but after set the handleProfiling attribute in the
+        // manifest file for this Instrumentation to true, the profiling was also disabled.
+        assertFalse(mInstrumentation.isProfiling());
+
+        mInstrumentation.startProfiling();
+        mInstrumentation.stopProfiling();
+    }
+
+    public void testInvokeContextMenuAction() throws Exception {
+        mActivity.runOnUiThread(new Runnable() {
+            public void run() {
+                mMockActivity = new MockActivity();
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+        final int id = 1;
+        final int flag = 2;
+        mInstrumentation.invokeContextMenuAction(mMockActivity, id, flag);
+        mInstrumentation.waitForIdleSync();
+
+        assertEquals(id, mMockActivity.mWindow.mId);
+        assertEquals(flag, mMockActivity.mWindow.mFlags);
+    }
+
+    public void testSendStringSync() {
+        final String text = "abcd";
+        mInstrumentation.sendStringSync(text);
+        mInstrumentation.waitForIdleSync();
+
+        List<KeyEvent> keyUpList = mActivity.getKeyUpList();
+        List<KeyEvent> keyDownList = mActivity.getKeyDownList();
+        assertEquals(text.length(), keyDownList.size());
+        assertEquals(text.length(), keyUpList.size());
+
+        KeyCharacterMap kcm = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD);
+        KeyEvent[] keyEvents = kcm.getEvents(text.toCharArray());
+
+        int i = 0;
+        for (int j = 0; j < keyDownList.size(); j++) {
+            assertEquals(keyEvents[i++].getKeyCode(), keyDownList.get(j).getKeyCode());
+            assertEquals(keyEvents[i++].getKeyCode(), keyUpList.get(j).getKeyCode());
+        }
+    }
+
+    public void testCallActivityOnSaveInstanceState() throws Throwable {
+        final Bundle bundle = new Bundle();
+        mActivity.setOnSaveInstanceState(false);
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                mInstrumentation.callActivityOnSaveInstanceState(mActivity, bundle);
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+
+        assertTrue(mActivity.isOnSaveInstanceState());
+        assertSame(bundle, mActivity.getBundle());
+    }
+
+    public void testSendPointerSync() throws Exception {
+        mInstrumentation.waitForIdleSync();
+        mInstrumentation.setInTouchMode(true);
+
+        // Send a touch event to the middle of the activity.
+        // We assume that the Activity is empty so there won't be anything in the middle
+        // to handle the touch.  Consequently the Activity should receive onTouchEvent
+        // because nothing else handled it.
+        Point size = new Point();
+        mActivity.getWindowManager().getDefaultDisplay().getSize(size);
+        final int x = size.x / 2;
+        final int y = size.y / 2;
+        long now = SystemClock.uptimeMillis();
+        MotionEvent orig = MotionEvent.obtain(now, now, MotionEvent.ACTION_DOWN,
+                x, y, 0);
+        mInstrumentation.sendPointerSync(orig);
+
+        mInstrumentation.waitForIdleSync();
+        assertTrue(mActivity.isOnTouchEventCalled());
+        mActivity.setOnTouchEventCalled(false);
+    }
+
+    public void testGetComponentName() throws Exception {
+        ComponentName com = getInstrumentation().getComponentName();
+        assertNotNull(com.getPackageName());
+        assertNotNull(com.getClassName());
+        assertNotNull(com.getShortClassName());
+    }
+
+    public void testNewApplication() throws Exception {
+        final String className = "android.app.stubs.MockApplication";
+        ClassLoader cl = getClass().getClassLoader();
+
+        Application app = mInstrumentation.newApplication(cl, className, mContext);
+        assertEquals(className, app.getClass().getName());
+
+        app = Instrumentation.newApplication(MockApplication.class, mContext);
+        assertEquals(className, app.getClass().getName());
+    }
+
+    public void testRunOnMainSync() throws Exception {
+        mRunOnMainSyncResult = false;
+        mInstrumentation.runOnMainSync(new Runnable() {
+            public void run() {
+                mRunOnMainSyncResult = true;
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+        assertTrue(mRunOnMainSyncResult);
+    }
+
+    public void testCallActivityOnPause() throws Exception {
+        mActivity.setOnPauseCalled(false);
+        mInstrumentation.callActivityOnPause(mActivity);
+        mInstrumentation.waitForIdleSync();
+        assertTrue(mActivity.isOnPauseCalled());
+    }
+
+    public void testSendKeyDownUpSync() throws Exception {
+        mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_0);
+        mInstrumentation.waitForIdleSync();
+        assertEquals(1, mActivity.getKeyUpList().size());
+        assertEquals(1, mActivity.getKeyDownList().size());
+        assertEquals(KeyEvent.KEYCODE_0, mActivity.getKeyUpList().get(0).getKeyCode());
+        assertEquals(KeyEvent.KEYCODE_0, mActivity.getKeyDownList().get(0).getKeyCode());
+    }
+
+    @UiThreadTest
+    public void testNewActivity() throws Exception {
+        Intent intent = new Intent();
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
+        ClassLoader cl = getClass().getClassLoader();
+        Activity activity = mInstrumentation.newActivity(cl, InstrumentationTestActivity.class
+                .getName(), intent);
+        assertEquals(InstrumentationTestActivity.class.getName(), activity.getClass().getName());
+        activity.finish();
+        activity = null;
+
+        intent = new Intent(mContext, InstrumentationTestActivity.class);
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
+        Activity father = new Activity();
+        ActivityInfo info = new ActivityInfo();
+
+        activity = mInstrumentation
+                .newActivity(InstrumentationTestActivity.class, mContext, null, null, intent, info,
+                        InstrumentationTestActivity.class.getName(), father, null, null);
+
+        assertEquals(father, activity.getParent());
+        assertEquals(InstrumentationTestActivity.class.getName(), activity.getClass().getName());
+        activity.finish();
+    }
+
+    public void testCallActivityOnStart() throws Exception {
+        mActivity.setOnStart(false);
+        mInstrumentation.callActivityOnStart(mActivity);
+        mInstrumentation.waitForIdleSync();
+        assertTrue(mActivity.isOnStart());
+    }
+
+    public void testWaitForIdle() throws Exception {
+        MockRunnable mr = new MockRunnable();
+        assertFalse(mr.isRunCalled());
+        mInstrumentation.waitForIdle(mr);
+        Thread.sleep(WAIT_TIME);
+        assertTrue(mr.isRunCalled());
+    }
+
+    public void testSendCharacterSync() throws Exception {
+        mInstrumentation.sendCharacterSync(KeyEvent.KEYCODE_0);
+        mInstrumentation.waitForIdleSync();
+        assertEquals(KeyEvent.KEYCODE_0, mActivity.getKeyDownCode());
+        assertEquals(KeyEvent.KEYCODE_0, mActivity.getKeyUpCode());
+    }
+
+    public void testCallActivityOnRestart() throws Exception {
+        mActivity.setOnRestart(false);
+        mInstrumentation.callActivityOnRestart(mActivity);
+        mInstrumentation.waitForIdleSync();
+        assertTrue(mActivity.isOnRestart());
+    }
+
+    public void testCallActivityOnStop() throws Exception {
+        mActivity.setOnStop(false);
+        mInstrumentation.callActivityOnStop(mActivity);
+        mInstrumentation.waitForIdleSync();
+        assertTrue(mActivity.isOnStop());
+    }
+
+    public void testCallActivityOnUserLeaving() throws Exception {
+        assertFalse(mActivity.isOnLeave());
+        mInstrumentation.callActivityOnUserLeaving(mActivity);
+        mInstrumentation.waitForIdleSync();
+        assertTrue(mActivity.isOnLeave());
+    }
+
+    public void testCallActivityOnRestoreInstanceState() throws Exception {
+        mActivity.setOnRestoreInstanceState(false);
+        mInstrumentation.callActivityOnRestoreInstanceState(mActivity, new Bundle());
+        mInstrumentation.waitForIdleSync();
+        assertTrue(mActivity.isOnRestoreInstanceState());
+    }
+
+    public void testSendKeySync() throws Exception {
+        KeyEvent key = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_0);
+        mInstrumentation.sendKeySync(key);
+        mInstrumentation.waitForIdleSync();
+        assertEquals(KeyEvent.KEYCODE_0, mActivity.getKeyDownCode());
+    }
+
+    private static class MockRunnable implements Runnable {
+        private boolean mIsRunCalled ;
+
+        public void run() {
+            mIsRunCalled = true;
+        }
+
+        public boolean isRunCalled() {
+            return mIsRunCalled;
+        }
+    }
+
+    private class MockActivity extends Activity {
+        MockWindow mWindow = new MockWindow(mContext);
+
+        @Override
+        public Window getWindow() {
+            return mWindow;
+        }
+
+        private class MockWindow extends Window {
+
+            public int mId;
+            public int mFlags;
+
+            public MockWindow(Context context) {
+                super(context);
+            }
+
+            @Override
+            public void addContentView(View view, LayoutParams params) {
+            }
+
+            @Override
+            public void closeAllPanels() {
+            }
+
+            @Override
+            public void closePanel(int featureId) {
+            }
+
+            @Override
+            public View getCurrentFocus() {
+                return null;
+            }
+
+            @Override
+            public View getDecorView() {
+                return null;
+            }
+
+            @Override
+            public LayoutInflater getLayoutInflater() {
+                return null;
+            }
+
+            @Override
+            public int getVolumeControlStream() {
+                return 0;
+            }
+
+            @Override
+            public boolean isFloating() {
+                return false;
+            }
+
+            @Override
+            public boolean isShortcutKey(int keyCode, KeyEvent event) {
+                return false;
+            }
+
+            @Override
+            protected void onActive() {
+            }
+
+            @Override
+            public void onConfigurationChanged(Configuration newConfig) {
+            }
+
+            @Override
+            public void openPanel(int featureId, KeyEvent event) {
+            }
+
+            public void alwaysReadCloseOnTouchAttr() {
+            }
+
+            @Override
+            public View peekDecorView() {
+                return null;
+            }
+
+            @Override
+            public boolean performContextMenuIdentifierAction(int id, int flags) {
+                mId = id;
+                mFlags = flags;
+                return false;
+            }
+
+            @Override
+            public boolean performPanelIdentifierAction(int featureId, int id, int flags) {
+                return false;
+            }
+
+            @Override
+            public boolean performPanelShortcut(int featureId, int keyCode,
+                    KeyEvent event, int flags) {
+                return false;
+            }
+
+            @Override
+            public void restoreHierarchyState(Bundle savedInstanceState) {
+            }
+
+            @Override
+            public Bundle saveHierarchyState() {
+                return null;
+            }
+
+            @Override
+            public void setBackgroundDrawable(Drawable drawable) {
+            }
+
+            @Override
+            public void setChildDrawable(int featureId, Drawable drawable) {
+            }
+
+            @Override
+            public void setChildInt(int featureId, int value) {
+            }
+
+            @Override
+            public void setContentView(int layoutResID) {
+            }
+
+            @Override
+            public void setContentView(View view) {
+            }
+
+            @Override
+            public void setContentView(View view, LayoutParams params) {
+            }
+
+            @Override
+            public void setFeatureDrawable(int featureId, Drawable drawable) {
+            }
+
+            @Override
+            public void setFeatureDrawableAlpha(int featureId, int alpha) {
+            }
+
+            @Override
+            public void setFeatureDrawableResource(int featureId, int resId) {
+            }
+
+            @Override
+            public void setFeatureDrawableUri(int featureId, Uri uri) {
+            }
+
+            @Override
+            public void setFeatureInt(int featureId, int value) {
+            }
+
+            @Override
+            public void setTitle(CharSequence title) {
+            }
+
+            @Override
+            public void setTitleColor(int textColor) {
+            }
+
+            @Override
+            public void setVolumeControlStream(int streamType) {
+            }
+
+            @Override
+            public boolean superDispatchKeyEvent(KeyEvent event) {
+                return false;
+            }
+
+            @Override
+            public boolean superDispatchKeyShortcutEvent(KeyEvent event) {
+                return false;
+            }
+
+            @Override
+            public boolean superDispatchTouchEvent(MotionEvent event) {
+                return false;
+            }
+
+            @Override
+            public boolean superDispatchTrackballEvent(MotionEvent event) {
+                return false;
+            }
+
+            @Override
+            public boolean superDispatchGenericMotionEvent(MotionEvent event) {
+                return false;
+            }
+
+            @Override
+            public void takeKeyEvents(boolean get) {
+            }
+
+            @Override
+            public void togglePanel(int featureId, KeyEvent event) {
+            }
+
+            @Override
+            public void invalidatePanelMenu(int featureId) {
+            }
+
+            @Override
+            public void takeSurface(SurfaceHolder.Callback2 callback) {
+            }
+
+            @Override
+            public void takeInputQueue(InputQueue.Callback queue) {
+            }
+
+            @Override
+            public void setStatusBarColor(int color) {
+            }
+
+            @Override
+            public int getStatusBarColor() {
+                return 0;
+            }
+
+            @Override
+            public void setNavigationBarColor(int color) {
+            }
+
+            @Override
+            public void setDecorCaptionShade(int decorCaptionShade) {
+            }
+
+            @Override
+            public void setResizingCaptionDrawable(Drawable drawable) {
+            }
+
+            @Override
+            public int getNavigationBarColor() {
+                return 0;
+            }
+        }
+    }
+
+    private static class InstrumentationTestStub extends Application {
+        boolean mIsOnCreateCalled = false;
+
+        @Override
+        public void onCreate() {
+            super.onCreate();
+            mIsOnCreateCalled = true;
+        }
+    }
+}
diff --git a/tests/app/src/android/app/cts/InstrumentationTestActivity.java b/tests/app/src/android/app/cts/InstrumentationTestActivity.java
deleted file mode 100644
index bec721e..0000000
--- a/tests/app/src/android/app/cts/InstrumentationTestActivity.java
+++ /dev/null
@@ -1,366 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-import java.util.ArrayList;
-import java.util.List;
-import android.app.Activity;
-import android.content.Context;
-import android.content.Intent;
-import android.os.Bundle;
-import android.view.KeyEvent;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.MotionEvent;
-import android.view.View;
-import android.widget.TextView;
-import com.android.cts.app.stub.R;
-
-public class InstrumentationTestActivity extends Activity {
-
-    private boolean mOnCreateCalled;
-    private boolean mOnDestroyCalled ;
-    private boolean mOnNewIntentCalled;
-    private boolean mOnPauseCalled;
-    private boolean mOnPostCreate;
-    private boolean mOnRestart;
-    private boolean mOnRestoreInstanceState;
-    private boolean mOnResume;
-    private boolean mOnSaveInstanceState;
-    private boolean mOnStart;
-    private boolean mOnStop;
-    private boolean mOnMenuOpened;
-    private boolean mOnLeave;
-    private int mMenuID;
-    private boolean mOnTouchEventCalled;
-    private int mKeyDownCode;
-    private int mKeyUpCode;
-    private MotionEvent mMotionEvent;
-    private Bundle mBundle;
-    private MockTextView mTextView;
-    private List<KeyEvent> mKeyDownList = new ArrayList<KeyEvent>();
-    private List<KeyEvent> mKeyUpList = new ArrayList<KeyEvent>();
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        mTextView = new MockTextView(this);
-        setContentView(mTextView);
-        mOnCreateCalled = true;
-    }
-
-    class MockTextView extends TextView {
-
-        public MockTextView(Context context) {
-            super(context);
-        }
-
-        @Override
-        public boolean onTouchEvent(MotionEvent event) {
-            return super.onTouchEvent(event);
-        }
-
-        @Override
-        public boolean onTrackballEvent(MotionEvent event) {
-            return super.onTrackballEvent(event);
-        }
-
-        @Override
-        public void getLocationOnScreen(int[] location) {
-            super.getLocationOnScreen(location);
-            location[0] = location[1] = 10;
-        }
-    }
-
-    @Override
-    protected void onDestroy() {
-        super.onDestroy();
-        mOnDestroyCalled = true;
-    }
-
-    @Override
-    protected void onNewIntent(Intent intent) {
-        super.onNewIntent(intent);
-        mOnNewIntentCalled = true;
-    }
-
-    @Override
-    protected void onPause() {
-        super.onPause();
-        mOnPauseCalled = true;
-    }
-
-    @Override
-    protected void onPostCreate(Bundle savedInstanceState) {
-        super.onPostCreate(savedInstanceState);
-        mOnPostCreate = true;
-    }
-
-    @Override
-    protected void onRestart() {
-        super.onRestart();
-        mOnRestart = true;
-    }
-
-    @Override
-    protected void onRestoreInstanceState(Bundle savedInstanceState) {
-        super.onRestoreInstanceState(savedInstanceState);
-        mOnRestoreInstanceState = true;
-    }
-
-    @Override
-    public boolean onTouchEvent(MotionEvent event) {
-        mOnTouchEventCalled = true;
-        mMotionEvent = event;
-        return super.onTouchEvent(event);
-    }
-
-    @Override
-    protected void onResume() {
-        super.onResume();
-        mOnResume = true;
-    }
-
-    @Override
-    protected void onSaveInstanceState(Bundle outState) {
-        super.onSaveInstanceState(outState);
-        mOnSaveInstanceState = true;
-        mBundle = outState;
-    }
-
-    @Override
-    protected void onStart() {
-        super.onStart();
-        mOnStart = true;
-    }
-
-    @Override
-    protected void onStop() {
-        super.onStop();
-        mOnStop = true;
-    }
-
-    @Override
-    protected void onUserLeaveHint() {
-        super.onUserLeaveHint();
-        mOnLeave = true;
-    }
-
-    @Override
-    public boolean onMenuOpened(int featureId, Menu menu) {
-        mOnMenuOpened = true;
-        return super.onMenuOpened(featureId, menu);
-    }
-
-    @Override
-    public boolean onCreateOptionsMenu(Menu menu) {
-        super.onCreateOptionsMenu(menu);
-        MenuInflater inflater = getMenuInflater();
-        inflater.inflate(R.menu.browser, menu);
-
-        menu.add("title");
-        mOnMenuOpened = true;
-        return true;
-    }
-
-    @Override
-    public boolean onCreatePanelMenu(int featureId, Menu menu) {
-        return super.onCreatePanelMenu(featureId, menu);
-    }
-
-    @Override
-    public boolean onMenuItemSelected(int featureId, MenuItem item) {
-        mMenuID = item.getItemId();
-        return super.onMenuItemSelected(featureId, item);
-    }
-
-    @Override
-    public void openContextMenu(View view) {
-        super.openContextMenu(view);
-    }
-
-    @Override
-    public void openOptionsMenu() {
-        super.openOptionsMenu();
-    }
-
-    @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
-        return super.onOptionsItemSelected(item);
-    }
-
-    @Override
-    public boolean onKeyDown(int keyCode, KeyEvent event) {
-        mKeyDownList.add(event);
-        mKeyDownCode = keyCode;
-        return super.onKeyDown(keyCode, event);
-    }
-
-    @Override
-    public boolean onTrackballEvent(MotionEvent event) {
-        mMotionEvent = event;
-        return super.onTrackballEvent(event);
-    }
-
-    @Override
-    public boolean onKeyUp(int keyCode, KeyEvent event) {
-        mKeyUpList.add(event);
-        mKeyUpCode = keyCode;
-        return super.onKeyUp(keyCode, event);
-    }
-
-    public boolean isOnCreateCalled() {
-        return mOnCreateCalled;
-    }
-
-    public void setOnCreateCalled(boolean onCreateCalled) {
-        mOnCreateCalled = onCreateCalled;
-    }
-
-    public boolean isOnDestroyCalled() {
-        return mOnDestroyCalled;
-    }
-
-    public void setOnDestroyCalled(boolean onDestroyCalled) {
-        mOnDestroyCalled = onDestroyCalled;
-    }
-
-    public boolean isOnNewIntentCalled() {
-        return mOnNewIntentCalled;
-    }
-
-    public void setOnNewIntentCalled(boolean onNewIntentCalled) {
-        mOnNewIntentCalled = onNewIntentCalled;
-    }
-
-    public boolean isOnPauseCalled() {
-        return mOnPauseCalled;
-    }
-
-    public void setOnPauseCalled(boolean onPauseCalled) {
-        mOnPauseCalled = onPauseCalled;
-    }
-
-    public boolean isOnPostCreate() {
-        return mOnPostCreate;
-    }
-
-    public void setOnPostCreate(boolean onPostCreate) {
-        mOnPostCreate = onPostCreate;
-    }
-
-    public boolean isOnRestart() {
-        return mOnRestart;
-    }
-
-    public void setOnRestart(boolean onRestart) {
-        mOnRestart = onRestart;
-    }
-
-    public boolean isOnRestoreInstanceState() {
-        return mOnRestoreInstanceState;
-    }
-
-    public void setOnRestoreInstanceState(boolean onRestoreInstanceState) {
-        mOnRestoreInstanceState = onRestoreInstanceState;
-    }
-
-    public boolean isOnResume() {
-        return mOnResume;
-    }
-
-    public void setOnResume(boolean onResume) {
-        mOnResume = onResume;
-    }
-
-    public boolean isOnSaveInstanceState() {
-        return mOnSaveInstanceState;
-    }
-
-    public void setOnSaveInstanceState(boolean onSaveInstanceState) {
-        mOnSaveInstanceState = onSaveInstanceState;
-    }
-
-    public boolean isOnStart() {
-        return mOnStart;
-    }
-
-    public void setOnStart(boolean onStart) {
-        mOnStart = onStart;
-    }
-
-    public boolean isOnStop() {
-        return mOnStop;
-    }
-
-    public boolean isOnLeave() {
-        return mOnLeave;
-    }
-
-    public void setOnStop(boolean onStop) {
-        mOnStop = onStop;
-    }
-
-    public boolean isMOnMenuOpened() {
-        return mOnMenuOpened;
-    }
-
-    public void setOnMenuOpened(boolean onMenuOpened) {
-        mOnMenuOpened = onMenuOpened;
-    }
-
-    public int getMenuID() {
-        return mMenuID;
-    }
-
-    public void setMenuID(int menuID) {
-        mMenuID = menuID;
-    }
-
-    public MotionEvent getMotionEvent() {
-        return mMotionEvent;
-    }
-
-    public Bundle getBundle() {
-        return mBundle;
-    }
-
-    public boolean isOnTouchEventCalled() {
-        return mOnTouchEventCalled;
-    }
-
-    public void setOnTouchEventCalled(boolean onTouchEventCalled) {
-        mOnTouchEventCalled = onTouchEventCalled;
-    }
-
-    public int getKeyUpCode() {
-        return mKeyUpCode;
-    }
-
-    public int getKeyDownCode() {
-        return mKeyDownCode;
-    }
-
-    public List<KeyEvent> getKeyUpList() {
-        return mKeyUpList;
-    }
-
-    public List<KeyEvent> getKeyDownList() {
-        return mKeyDownList;
-    }
-}
diff --git a/tests/app/src/android/app/cts/Instrumentation_ActivityMonitorTest.java b/tests/app/src/android/app/cts/Instrumentation_ActivityMonitorTest.java
new file mode 100644
index 0000000..719f74b
--- /dev/null
+++ b/tests/app/src/android/app/cts/Instrumentation_ActivityMonitorTest.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.cts;
+
+import android.app.Activity;
+import android.app.Instrumentation;
+import android.app.Instrumentation.ActivityMonitor;
+import android.app.Instrumentation.ActivityResult;
+import android.app.stubs.InstrumentationTestActivity;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.test.InstrumentationTestCase;
+
+public class Instrumentation_ActivityMonitorTest extends InstrumentationTestCase {
+
+    private static final long WAIT_TIMEOUT = 100;
+
+    /**
+     * check points:
+     * 1 Constructor with blocking true and false
+     * 2 waitForActivity with timeout and no timeout
+     * 3 get info about ActivityMonitor
+     */
+    public void testActivityMonitor() throws Exception {
+        ActivityResult result = new ActivityResult(Activity.RESULT_OK, new Intent());
+        Instrumentation instrumentation = getInstrumentation();
+        ActivityMonitor am = instrumentation.addMonitor(
+                InstrumentationTestActivity.class.getName(), result, false);
+        Context context = instrumentation.getTargetContext();
+        Intent intent = new Intent(context, InstrumentationTestActivity.class);
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        context.startActivity(intent);
+        Activity lastActivity = am.getLastActivity();
+        final long TIMEOUT_MSEC = 5000;
+        long timeout = System.currentTimeMillis() + TIMEOUT_MSEC;
+        while (lastActivity == null && System.currentTimeMillis() < timeout) {
+            Thread.sleep(WAIT_TIMEOUT);
+            lastActivity = am.getLastActivity();
+        }
+        Activity activity = am.waitForActivity();
+        assertSame(activity, lastActivity);
+        assertEquals(1, am.getHits());
+        assertTrue(activity instanceof InstrumentationTestActivity);
+        activity.finish();
+        instrumentation.waitForIdleSync();
+        context.startActivity(intent);
+        timeout = System.currentTimeMillis() + TIMEOUT_MSEC;
+        activity = null;
+        while (activity == null && System.currentTimeMillis() < timeout) {
+            Thread.sleep(WAIT_TIMEOUT);
+            activity = am.waitForActivityWithTimeout(WAIT_TIMEOUT);
+        }
+        assertNotNull(activity);
+        activity.finish();
+        instrumentation.removeMonitor(am);
+
+        am = new ActivityMonitor(InstrumentationTestActivity.class.getName(), result, true);
+        assertSame(result, am.getResult());
+        assertTrue(am.isBlocking());
+        IntentFilter which = new IntentFilter();
+        am = new ActivityMonitor(which, result, false);
+        assertSame(which, am.getFilter());
+        assertFalse(am.isBlocking());
+    }
+}
diff --git a/tests/tests/app/src/android/app/cts/Instrumentation_ActivityResultTest.java b/tests/app/src/android/app/cts/Instrumentation_ActivityResultTest.java
similarity index 100%
rename from tests/tests/app/src/android/app/cts/Instrumentation_ActivityResultTest.java
rename to tests/app/src/android/app/cts/Instrumentation_ActivityResultTest.java
diff --git a/tests/app/src/android/app/cts/IntentServiceStub.java b/tests/app/src/android/app/cts/IntentServiceStub.java
deleted file mode 100644
index 8f23a4f..0000000
--- a/tests/app/src/android/app/cts/IntentServiceStub.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-import android.app.IntentService;
-import android.content.Intent;
-import android.cts.util.PollingCheck;
-import android.os.Binder;
-import android.os.IBinder;
-
-public class IntentServiceStub extends IntentService {
-    public IntentServiceStub() {
-        super("IntentServiceStub");
-    }
-
-    public static final String ISS_ADD = "add";
-    public static final String ISS_VALUE = "value";
-
-    private static int onHandleIntentCalled;
-    private static boolean onBindCalled;
-    private static boolean onCreateCalled;
-    private static boolean onDestroyCalled;
-    private static boolean onStartCalled;
-    private static int accumulator;
-
-    private static Throwable throwable;
-
-    public synchronized static void reset() {
-        onHandleIntentCalled = 0;
-        onBindCalled = false;
-        onCreateCalled = false;
-        onDestroyCalled = false;
-        onStartCalled = false;
-        accumulator = 0;
-        throwable = null;
-    }
-
-    public static void waitToFinish(long timeout) throws Throwable {
-        new PollingCheck(timeout) {
-            @Override
-            protected boolean check() {
-                synchronized (IntentServiceStub.class) {
-                    return IntentServiceStub.onDestroyCalled;
-                }
-            }
-        }.run();
-        if (throwable != null) {
-            throw throwable;
-        }
-    }
-
-    @Override
-    protected void onHandleIntent(Intent intent) {
-        synchronized (IntentServiceStub.class) {
-            onHandleIntentCalled += 1;
-            try {
-                String action = intent.getAction();
-                if (action != null && action.equals(ISS_ADD)) {
-                    accumulator += intent.getIntExtra(ISS_VALUE, 0);
-                }
-            } catch (Throwable t) {
-                throwable = t;
-            }
-        }
-    }
-
-    @Override
-    public IBinder onBind(Intent intent) {
-        synchronized (IntentServiceStub.class) {
-            onBindCalled = true;
-        }
-        return new Binder();
-    }
-
-    @Override
-    public void onCreate() {
-        synchronized (IntentServiceStub.class) {
-            onCreateCalled = true;
-        }
-        super.onCreate();
-    }
-
-    @Override
-    public void onDestroy() {
-        synchronized (IntentServiceStub.class) {
-            onDestroyCalled = true;
-        }
-        super.onDestroy();
-    }
-
-    @Override
-    public void onStart(Intent intent, int startId) {
-        synchronized (IntentService.class) {
-            onStartCalled = true;
-        }
-        super.onStart(intent, startId);
-    }
-
-    public synchronized static int getOnHandleIntentCalledCount() {
-        return onHandleIntentCalled;
-    }
-
-    public synchronized static boolean isOnBindCalled() {
-        return onBindCalled;
-    }
-
-    public synchronized static boolean isOnCreateCalled() {
-        return onCreateCalled;
-    }
-
-    public synchronized static boolean isOnDestroyCalled() {
-        return onDestroyCalled;
-    }
-
-    public synchronized static boolean isOnStartCalled() {
-        return onStartCalled;
-    }
-
-    public synchronized static int getAccumulator() {
-        return accumulator;
-    }
-}
diff --git a/tests/app/src/android/app/cts/IntentServiceTest.java b/tests/app/src/android/app/cts/IntentServiceTest.java
new file mode 100644
index 0000000..9d721fe
--- /dev/null
+++ b/tests/app/src/android/app/cts/IntentServiceTest.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.cts;
+
+import android.app.stubs.ActivityTestsBase;
+import android.app.stubs.IntentServiceStub;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.cts.util.PollingCheck;
+import android.os.IBinder;
+
+import java.util.concurrent.Callable;
+
+public class IntentServiceTest extends ActivityTestsBase {
+
+    private Intent mIntent;
+    private static final int TIMEOUT_MSEC = 30000;
+    private boolean mConnected;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        IntentServiceStub.reset();
+        mIntent = new Intent(mContext, IntentServiceStub.class);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+        mContext.stopService(mIntent);
+    }
+
+    public void testIntents() throws Throwable {
+        final int value = 42;
+        final int adds = 3;
+
+        Intent addIntent = new Intent(mContext, IntentServiceStub.class);
+
+        addIntent.setAction(IntentServiceStub.ISS_ADD);
+        addIntent.putExtra(IntentServiceStub.ISS_VALUE, 42);
+
+        for (int i = 0; i < adds; i++) {
+            mContext.startService(addIntent);
+        }
+
+        PollingCheck.check("onHandleIntentCalled not called enough", TIMEOUT_MSEC,
+                new Callable<Boolean>() {
+            @Override
+            public Boolean call() throws Exception {
+                return IntentServiceStub.getOnHandleIntentCalledCount() == adds;
+            }
+        });
+
+        PollingCheck.check("accumulator not correct", TIMEOUT_MSEC, new Callable<Boolean>() {
+            @Override
+            public Boolean call() throws Exception {
+                return IntentServiceStub.getAccumulator() == adds * value;
+            }
+        });
+
+        PollingCheck.check("onDestroyCalled not called", TIMEOUT_MSEC, new Callable<Boolean>() {
+            @Override
+            public Boolean call() throws Exception {
+                return IntentServiceStub.isOnDestroyCalled();
+            }
+        });
+    }
+
+    public void testIntentServiceLifeCycle() throws Throwable {
+        // start service
+        mContext.startService(mIntent);
+        new PollingCheck(TIMEOUT_MSEC) {
+            protected boolean check() {
+                return IntentServiceStub.getOnHandleIntentCalledCount() > 0;
+            }
+        }.run();
+        assertTrue(IntentServiceStub.isOnCreateCalled());
+        assertTrue(IntentServiceStub.isOnStartCalled());
+
+        // bind service
+        ServiceConnection conn = new TestConnection();
+        mContext.bindService(mIntent, conn, Context.BIND_AUTO_CREATE);
+        new PollingCheck(TIMEOUT_MSEC) {
+            protected boolean check() {
+                return mConnected;
+            }
+        }.run();
+        assertTrue(IntentServiceStub.isOnBindCalled());
+
+        // unbind service
+        mContext.unbindService(conn);
+        // stop service
+        mContext.stopService(mIntent);
+        IntentServiceStub.waitToFinish(TIMEOUT_MSEC);
+    }
+
+    private class TestConnection implements ServiceConnection {
+
+        public void onServiceConnected(ComponentName name, IBinder service) {
+            mConnected = true;
+        }
+
+        public void onServiceDisconnected(ComponentName name) {
+        }
+    }
+}
diff --git a/tests/app/src/android/app/cts/KeyguardManagerActivity.java b/tests/app/src/android/app/cts/KeyguardManagerActivity.java
deleted file mode 100644
index a1f5289..0000000
--- a/tests/app/src/android/app/cts/KeyguardManagerActivity.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-import android.app.Activity;
-import android.app.KeyguardManager;
-import android.content.Context;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.KeyEvent;
-
-public class KeyguardManagerActivity extends Activity {
-    private static final String TAG = "KeyguardManagerActivity";
-    public static final boolean DEBUG = false;
-    private KeyguardManager mKeyguardManager;
-    private KeyguardManager.KeyguardLock mKeyLock;
-    public int keyCode;
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        mKeyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
-        mKeyLock = null;
-    }
-
-    @Override
-    protected void onResume() {
-        super.onResume();
-        if (DEBUG) {
-            Log.d(TAG, "onResume");
-        }
-        if (mKeyLock == null) {
-            mKeyLock = mKeyguardManager.newKeyguardLock(TAG);
-            mKeyLock.disableKeyguard();
-            if (DEBUG) {
-                Log.d(TAG, "disableKeyguard");
-            }
-        }
-    }
-
-    @Override
-    public boolean onKeyDown(int keyCode, KeyEvent event) {
-        this.keyCode = keyCode;
-        if (keyCode == KeyEvent.KEYCODE_0 && mKeyLock != null) {
-            mKeyLock.reenableKeyguard();
-            mKeyLock = null;
-            if (DEBUG) {
-                Log.d(TAG, "reenableKeyguard");
-            }
-        }
-        if (DEBUG) {
-            Log.d(TAG, "onKeyDown");
-        }
-        return super.onKeyDown(keyCode, event);
-    }
-}
diff --git a/tests/app/src/android/app/cts/KeyguardManagerKeyguardLockTest.java b/tests/app/src/android/app/cts/KeyguardManagerKeyguardLockTest.java
new file mode 100644
index 0000000..33d42ce
--- /dev/null
+++ b/tests/app/src/android/app/cts/KeyguardManagerKeyguardLockTest.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.cts;
+
+import android.test.InstrumentationTestCase;
+
+public class KeyguardManagerKeyguardLockTest extends InstrumentationTestCase {
+
+    public void testDisableKeyguard() {
+    }
+
+    public void testReenableKeyguard() {
+    }
+}
diff --git a/tests/app/src/android/app/cts/KeyguardManagerTest.java b/tests/app/src/android/app/cts/KeyguardManagerTest.java
new file mode 100644
index 0000000..23410ed5
--- /dev/null
+++ b/tests/app/src/android/app/cts/KeyguardManagerTest.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.cts;
+
+import android.app.KeyguardManager;
+import android.app.stubs.KeyguardManagerActivity;
+import android.content.Context;
+import android.test.ActivityInstrumentationTestCase2;
+
+public class KeyguardManagerTest
+        extends ActivityInstrumentationTestCase2<KeyguardManagerActivity> {
+
+    private static final String TAG = "KeyguardManagerTest";
+
+    public KeyguardManagerTest() {
+        super("android.app.stubs", KeyguardManagerActivity.class);
+    }
+
+    public void testNewKeyguardLock() {
+        final Context c = getInstrumentation().getContext();
+        final KeyguardManager keyguardManager = (KeyguardManager) c.getSystemService(
+                Context.KEYGUARD_SERVICE);
+        final KeyguardManager.KeyguardLock keyLock = keyguardManager.newKeyguardLock(TAG);
+        assertNotNull(keyLock);
+    }
+
+    public void testInKeyguardRestrictedInputMode() {
+    }
+
+    public void testExitKeyguardSecurely() {
+    }
+}
diff --git a/tests/app/src/android/app/cts/LaunchTest.java b/tests/app/src/android/app/cts/LaunchTest.java
new file mode 100644
index 0000000..eaa4b2f
--- /dev/null
+++ b/tests/app/src/android/app/cts/LaunchTest.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.cts;
+
+import android.app.stubs.ActivityTestsBase;
+import android.app.stubs.ClearTop;
+import android.app.stubs.LaunchpadActivity;
+import android.app.stubs.LocalActivity;
+import android.app.stubs.LocalScreen;
+import android.app.stubs.TestedActivity;
+import android.app.stubs.TestedScreen;
+import android.content.ComponentName;
+
+public class LaunchTest extends ActivityTestsBase {
+
+    public void testClearTopWhilResumed() {
+        mIntent.putExtra("component", new ComponentName(getContext(), ClearTop.class));
+        mIntent.putExtra(ClearTop.WAIT_CLEAR_TASK, true);
+        runLaunchpad(LaunchpadActivity.LAUNCH);
+    }
+
+    public void testClearTopInCreate() throws Exception {
+        mIntent.putExtra("component", new ComponentName(getContext(), ClearTop.class));
+        runLaunchpad(LaunchpadActivity.LAUNCH);
+    }
+
+    public void testForwardResult() {
+        runLaunchpad(LaunchpadActivity.FORWARD_RESULT);
+    }
+
+    public void testLocalScreen() {
+        mIntent.putExtra("component", new ComponentName(getContext(), LocalScreen.class));
+        runLaunchpad(LaunchpadActivity.LAUNCH);
+    }
+
+    public void testColdScreen() {
+        mIntent.putExtra("component", new ComponentName(getContext(), TestedScreen.class));
+        runLaunchpad(LaunchpadActivity.LAUNCH);
+    }
+
+    public void testLocalActivity() {
+        mIntent.putExtra("component", new ComponentName(getContext(), LocalActivity.class));
+        runLaunchpad(LaunchpadActivity.LAUNCH);
+    }
+
+    public void testColdActivity() {
+        mIntent.putExtra("component", new ComponentName(getContext(), TestedActivity.class));
+        runLaunchpad(LaunchpadActivity.LAUNCH);
+    }
+}
diff --git a/tests/app/src/android/app/cts/LauncherActivityStub.java b/tests/app/src/android/app/cts/LauncherActivityStub.java
deleted file mode 100644
index 4be63d6..0000000
--- a/tests/app/src/android/app/cts/LauncherActivityStub.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-import android.app.LauncherActivity;
-import android.content.Intent;
-import android.os.Bundle;
-import android.view.View;
-import android.widget.ListView;
-
-public class LauncherActivityStub extends LauncherActivity {
-    public boolean isOnCreateCalled = false;
-    public boolean isOnListItemClick = false;
-    // For testing LauncherActivity#getTargetIntent()
-    private Intent mSuperIntent;
-
-    public Intent getSuperIntent() {
-        return mSuperIntent;
-    }
-
-    @Override
-    protected Intent getTargetIntent() {
-        mSuperIntent = super.getTargetIntent();
-        Intent targetIntent = new Intent(Intent.ACTION_MAIN, null);
-        targetIntent.addCategory(Intent.CATEGORY_FRAMEWORK_INSTRUMENTATION_TEST);
-        targetIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        return targetIntent;
-    }
-
-    @Override
-    protected Intent intentForPosition(int position) {
-        return super.intentForPosition(position);
-    }
-
-    public LauncherActivityStub() {
-        super();
-    }
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        isOnCreateCalled = true;
-    }
-
-    @Override
-    public void onListItemClick(ListView l, View v, int position, long id) {
-        super.onListItemClick(l, v, position, id);
-        isOnListItemClick = true;
-    }
-}
diff --git a/tests/app/src/android/app/cts/LauncherActivityTest.java b/tests/app/src/android/app/cts/LauncherActivityTest.java
new file mode 100644
index 0000000..6ab4608
--- /dev/null
+++ b/tests/app/src/android/app/cts/LauncherActivityTest.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.cts;
+
+import android.app.Instrumentation;
+import android.app.LauncherActivity.ListItem;
+import android.app.stubs.LauncherActivityStub;
+import android.test.ActivityInstrumentationTestCase2;
+import android.view.KeyEvent;
+
+import java.util.List;
+
+public class LauncherActivityTest
+        extends ActivityInstrumentationTestCase2<LauncherActivityStub> {
+
+    private Instrumentation mInstrumentation;
+    private LauncherActivityStub mActivity;
+
+    public LauncherActivityTest() {
+        super("android.app.stubs", LauncherActivityStub.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mInstrumentation = getInstrumentation();
+        mActivity = getActivity();
+    }
+
+    public void testLaunchActivity() throws Throwable {
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                // Test getTargetIntent. LaunchActivity#getTargetIntent() just returns a Intent() instance
+                // with no content, so we use LaunchActivityStub#getSuperIntent() to get the default Intent,
+                // and create a new intent for other tests.
+                assertNotNull(mActivity.getSuperIntent());
+
+                // Test makeListItems. Make sure the size > 0. The sorted order is related to the sort
+                // way, so it's mutable.
+                final List<ListItem> list = mActivity.makeListItems();
+                assertTrue(list.size() > 0);
+
+                // There should be an activity(but with uncertain content) in position 0.
+                assertNotNull(mActivity.intentForPosition(0));
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+        // Test onListItemClick
+        sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+        sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+        sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+        sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
+        assertTrue(mActivity.isOnListItemClick);
+    }
+}
diff --git a/tests/app/src/android/app/cts/LauncherActivity_IconResizerTest.java b/tests/app/src/android/app/cts/LauncherActivity_IconResizerTest.java
new file mode 100644
index 0000000..b6ba9c6
--- /dev/null
+++ b/tests/app/src/android/app/cts/LauncherActivity_IconResizerTest.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.cts;
+
+import android.app.LauncherActivity.IconResizer;
+import android.app.stubs.LauncherActivityStub;
+import android.graphics.drawable.Drawable;
+import android.test.ActivityInstrumentationTestCase2;
+
+import android.app.stubs.R;
+
+public class LauncherActivity_IconResizerTest extends
+        ActivityInstrumentationTestCase2<LauncherActivityStub> {
+
+    private static final String PACKAGE = "android.app.stubs";
+    private LauncherActivityStub mActivity;
+
+    public LauncherActivity_IconResizerTest() {
+        super(PACKAGE, LauncherActivityStub.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mActivity = getActivity();
+    }
+
+    public void testIconResizer() throws Throwable {
+        final IconResizer ir = mActivity.new IconResizer();
+        final Drawable d = mActivity.getResources().getDrawable(R.drawable.pass);
+        assertNotNull(d);
+
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                Drawable thumbNail = ir.createIconThumbnail(d);
+                assertNotNull(thumbNail);
+                // The size of the thumbnail is defined by inner R resource file
+                // whose details are not open.
+                assertTrue(thumbNail.getIntrinsicHeight() > 0);
+                assertTrue(thumbNail.getIntrinsicWidth() > 0);
+            }
+        });
+        getInstrumentation().waitForIdleSync();
+    }
+}
diff --git a/tests/app/src/android/app/cts/LauncherActivity_ListItemTest.java b/tests/app/src/android/app/cts/LauncherActivity_ListItemTest.java
new file mode 100644
index 0000000..6c22905
--- /dev/null
+++ b/tests/app/src/android/app/cts/LauncherActivity_ListItemTest.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.cts;
+
+import android.app.LauncherActivity;
+import android.test.AndroidTestCase;
+
+public class LauncherActivity_ListItemTest extends AndroidTestCase {
+    public void testConstructor() {
+        // Test public constructor
+        new LauncherActivity.ListItem();
+    }
+}
diff --git a/tests/app/src/android/app/cts/LaunchpadActivity.java b/tests/app/src/android/app/cts/LaunchpadActivity.java
deleted file mode 100644
index 2a90055..0000000
--- a/tests/app/src/android/app/cts/LaunchpadActivity.java
+++ /dev/null
@@ -1,648 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-import android.app.Activity;
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.Binder;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Message;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.test.PerformanceTestCase;
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-class MyBadParcelable implements Parcelable {
-    public MyBadParcelable() {
-    }
-
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeString("I am bad");
-    }
-
-    public int describeContents() {
-        return 0;
-    }
-
-    public static final Parcelable.Creator<MyBadParcelable> CREATOR =
-        new Parcelable.Creator<MyBadParcelable>() {
-        public MyBadParcelable createFromParcel(Parcel in) {
-            return new MyBadParcelable(in);
-        }
-
-        public MyBadParcelable[] newArray(int size) {
-            return new MyBadParcelable[size];
-        }
-    };
-
-    public MyBadParcelable(Parcel in) {
-        in.readString();
-    }
-}
-
-public class LaunchpadActivity extends Activity {
-    public interface CallingTest extends PerformanceTestCase.Intermediates {
-        public void startTiming(boolean realTime);
-
-        public void addIntermediate(String name);
-
-        public void addIntermediate(String name, long timeInNS);
-
-        public void finishTiming(boolean realTime);
-
-        public void activityFinished(int resultCode, Intent data, RuntimeException where);
-    }
-
-    // Also used as the Binder interface descriptor string in these tests
-    public static final String LAUNCH = "android.app.cts.activity.LAUNCH";
-
-    public static final String FORWARD_RESULT = "android.app.cts.activity.FORWARD_RESULT";
-    public static final String RETURNED_RESULT = "android.app.cts.activity.RETURNED_RESULT";
-
-    public static final String BAD_PARCELABLE = "android.app.cts.activity.BAD_PARCELABLE";
-
-    public static final int LAUNCHED_RESULT = 1;
-    public static final int FORWARDED_RESULT = 2;
-
-    public static final String LIFECYCLE_BASIC = "android.app.cts.activity.LIFECYCLE_BASIC";
-    public static final String LIFECYCLE_SCREEN = "android.app.cts.activity.LIFECYCLE_SCREEN";
-    public static final String LIFECYCLE_DIALOG = "android.app.cts.activity.LIFECYCLE_DIALOG";
-
-    public static final String BROADCAST_REGISTERED = "android.app.cts.activity.BROADCAST_REGISTERED";
-    public static final String BROADCAST_LOCAL = "android.app.cts.activity.BROADCAST_LOCAL";
-    public static final String BROADCAST_REMOTE = "android.app.cts.activity.BROADCAST_REMOTE";
-    public static final String BROADCAST_ALL = "android.app.cts.activity.BROADCAST_ALL";
-    public static final String BROADCAST_REPEAT = "android.app.cts.activity.BROADCAST_REPEAT";
-    public static final String BROADCAST_MULTI = "android.app.cts.activity.BROADCAST_MULTI";
-    public static final String BROADCAST_ABORT = "android.app.cts.activity.BROADCAST_ABORT";
-
-    public static final String EXPANDLIST_SELECT = "EXPANDLIST_SELECT";
-    public static final String EXPANDLIST_VIEW = "EXPANDLIST_VIEW";
-    public static final String EXPANDLIST_CALLBACK = "EXPANDLIST_CALLBACK";
-
-    public static final String BROADCAST_STICKY1 = "android.app.cts.activity.BROADCAST_STICKY1";
-    public static final String BROADCAST_STICKY2 = "android.app.cts.activity.BROADCAST_STICKY2";
-
-    public static final String ALIAS_ACTIVITY = "android.app.cts.activity.ALIAS_ACTIVITY";
-
-    public static final String RECEIVER_REG = "receiver-reg";
-    public static final String RECEIVER_LOCAL = "receiver-local";
-    public static final String RECEIVER_REMOTE = "receiver-remote";
-    public static final String RECEIVER_ABORT = "receiver-abort";
-
-    public static final String DATA_1 = "one";
-    public static final String DATA_2 = "two";
-
-    public static final String ON_START = "onStart";
-    public static final String ON_RESTART = "onRestart";
-    public static final String ON_RESUME = "onResume";
-    public static final String ON_FREEZE = "onSaveInstanceState";
-    public static final String ON_PAUSE = "onPause";
-
-    // ON_STOP and ON_DESTROY are not tested because they may not be called.
-
-    public static final String DO_FINISH = "finish";
-    public static final String DO_LOCAL_SCREEN = "local-screen";
-    public static final String DO_LOCAL_DIALOG = "local-dialog";
-
-    private static final String TAG = "LaunchpadActivity";
-
-    private boolean mBadParcelable = false;
-
-    private boolean mStarted = false;
-
-    private int mResultCode = RESULT_CANCELED;
-    private Intent mData = new Intent().setAction("No result received");
-    private RuntimeException mResultStack = null;
-
-    /** Index into the {@link #mNextLifecycle} array. */
-    private int mNextLifecycle;
-
-    /** Current lifecycle expected to be followed. */
-    private String[] mExpectedLifecycle;
-
-    /** Other possible lifecycles. Never includes the current {@link #mExpectedLifecycle}. */
-    private List<String[]> mOtherPossibleLifecycles = new ArrayList<String[]>(2);
-
-    /** Map from lifecycle arrays to debugging log names. */
-    private Map<String[], String> mLifecycleNames = new HashMap<String[], String>(2);
-
-    private String[] mExpectedReceivers = null;
-    private int mNextReceiver;
-
-    private String[] mExpectedData = null;
-    private boolean[] mReceivedData = null;
-
-    boolean mReceiverRegistered = false;
-
-    private static CallingTest sCallingTest = null;
-
-    public static void setCallingTest(CallingTest ct) {
-        sCallingTest = ct;
-    }
-
-    public LaunchpadActivity() {
-    }
-
-    @Override
-    protected void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-
-        resetLifecycles();
-
-        // ON_STOP and ON_DESTROY are not tested because they may not be called.
-
-        final String action = getIntent().getAction();
-        if (LIFECYCLE_BASIC.equals(action)) {
-            addPossibleLifecycle(LIFECYCLE_BASIC, new String[] {
-                    ON_START, ON_RESUME, DO_FINISH, ON_PAUSE
-            });
-        } else if (LIFECYCLE_SCREEN.equals(action)) {
-            addPossibleLifecycle(LIFECYCLE_SCREEN + "_RESTART", new String[] {
-                    ON_START, ON_RESUME, DO_LOCAL_SCREEN, ON_PAUSE,
-                    ON_RESTART, ON_START, ON_RESUME, DO_FINISH, ON_PAUSE
-            });
-            addPossibleLifecycle(LIFECYCLE_SCREEN + "_RESUME", new String[] {
-                    ON_START, ON_RESUME, DO_LOCAL_SCREEN, ON_PAUSE,
-                    ON_RESUME, DO_FINISH, ON_PAUSE
-            });
-        } else if (LIFECYCLE_DIALOG.equals(action)) {
-            addPossibleLifecycle(LIFECYCLE_DIALOG + "_RESTART", new String[] {
-                    ON_START, ON_RESUME, DO_LOCAL_DIALOG, ON_PAUSE,
-                    ON_RESTART, ON_START, ON_RESUME, DO_FINISH, ON_PAUSE
-            });
-            addPossibleLifecycle(LIFECYCLE_DIALOG + "_RESUME", new String[] {
-                    ON_START, ON_RESUME, DO_LOCAL_DIALOG, ON_PAUSE,
-                    ON_RESUME, DO_FINISH, ON_PAUSE
-            });
-        }
-    }
-
-    private void resetLifecycles() {
-        mNextLifecycle = 0;
-        mExpectedLifecycle = null;
-        mOtherPossibleLifecycles.clear();
-        mLifecycleNames.clear();
-    }
-
-    /**
-     * Add a potential lifecycle that this activity may follow, since there
-     * are usually multiple valid lifecycles. For instance, sometimes onPause
-     * will lead to onResume rather than onStop when another activity is
-     * raised over the current one.
-     *
-     * @param debugName for the lifecycle shown in the logs
-     * @param lifecycle array containing tokens indicating the expected lifecycle
-     */
-    private void addPossibleLifecycle(String debugName, String[] lifecycle) {
-        mLifecycleNames.put(lifecycle, debugName);
-        if (mExpectedLifecycle == null) {
-            mExpectedLifecycle = lifecycle;
-        } else {
-            mOtherPossibleLifecycles.add(lifecycle);
-        }
-    }
-
-    /**
-     * Switch to the next possible lifecycle and return if switching was
-     * successful. Call this method when mExpectedLifecycle doesn't match
-     * the current lifecycle and you need to check another possible lifecycle.
-     *
-     * @return whether on not there was a lifecycle to switch to
-     */
-    private boolean switchToNextPossibleLifecycle() {
-        if (!mOtherPossibleLifecycles.isEmpty()) {
-            String[] newLifecycle = mOtherPossibleLifecycles.remove(0);
-            Log.w(TAG, "Switching expected lifecycles from "
-                    + mLifecycleNames.get(mExpectedLifecycle) + " to "
-                    + mLifecycleNames.get(newLifecycle));
-            mExpectedLifecycle = newLifecycle;
-            return true;
-        } else {
-            Log.w(TAG, "No more lifecycles after "
-                    + mLifecycleNames.get(mExpectedLifecycle));
-            mExpectedLifecycle = null;
-            return false;
-        }
-    }
-
-    @Override
-    protected void onStart() {
-        super.onStart();
-        checkLifecycle(ON_START);
-    }
-
-    @Override
-    protected void onRestart() {
-        super.onStart();
-        checkLifecycle(ON_RESTART);
-    }
-
-    @Override
-    protected void onResume() {
-        super.onResume();
-
-        checkLifecycle(ON_RESUME);
-
-        if (!mStarted) {
-            mStarted = true;
-
-            mHandler.postDelayed(mTimeout, 10 * 1000);
-
-            final String action = getIntent().getAction();
-
-            sCallingTest.startTiming(true);
-
-            if (LAUNCH.equals(action)) {
-                final Intent intent = getIntent();
-                intent.setFlags(0);
-                intent.setComponent((ComponentName) intent.getParcelableExtra("component"));
-                startActivityForResult(intent, LAUNCHED_RESULT);
-
-            } else if (FORWARD_RESULT.equals(action)) {
-                final Intent intent = getIntent();
-                intent.setFlags(0);
-                intent.setClass(this, LocalScreen.class);
-                startActivityForResult(intent, FORWARDED_RESULT);
-            } else if (BAD_PARCELABLE.equals(action)) {
-                mBadParcelable = true;
-                final Intent intent = getIntent();
-                intent.setFlags(0);
-                intent.setClass(this, LocalScreen.class);
-                startActivityForResult(intent, LAUNCHED_RESULT);
-            } else if (BROADCAST_REGISTERED.equals(action)) {
-                setExpectedReceivers(new String[] {
-                    RECEIVER_REG
-                });
-                registerMyReceiver(new IntentFilter(BROADCAST_REGISTERED));
-                sCallingTest.addIntermediate("after-register");
-                sendBroadcast(makeBroadcastIntent(BROADCAST_REGISTERED));
-            } else if (BROADCAST_LOCAL.equals(action)) {
-                setExpectedReceivers(new String[] {
-                    RECEIVER_LOCAL
-                });
-                sendBroadcast(makeBroadcastIntent(BROADCAST_LOCAL));
-            } else if (BROADCAST_REMOTE.equals(action)) {
-                setExpectedReceivers(new String[] {
-                    RECEIVER_REMOTE
-                });
-                sendBroadcast(makeBroadcastIntent(BROADCAST_REMOTE));
-            } else if (BROADCAST_ALL.equals(action)) {
-                setExpectedReceivers(new String[] {
-                        RECEIVER_REMOTE, RECEIVER_REG, RECEIVER_LOCAL
-                });
-                registerMyReceiver(new IntentFilter(BROADCAST_ALL));
-                sCallingTest.addIntermediate("after-register");
-                sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_ALL), null);
-            } else if (BROADCAST_MULTI.equals(action)) {
-                setExpectedReceivers(new String[] {
-                        RECEIVER_REMOTE, RECEIVER_REG, RECEIVER_LOCAL, RECEIVER_REMOTE,
-                        RECEIVER_REG, RECEIVER_LOCAL, RECEIVER_REMOTE, RECEIVER_REG,
-                        RECEIVER_LOCAL, RECEIVER_LOCAL, RECEIVER_REMOTE, RECEIVER_LOCAL,
-                        RECEIVER_REMOTE, RECEIVER_REMOTE, RECEIVER_REG, RECEIVER_LOCAL,
-                        RECEIVER_REMOTE, RECEIVER_REG, RECEIVER_LOCAL, RECEIVER_REMOTE,
-                        RECEIVER_REG, RECEIVER_LOCAL, RECEIVER_REMOTE, RECEIVER_LOCAL,
-                        RECEIVER_REMOTE, RECEIVER_LOCAL
-                });
-                registerMyReceiver(new IntentFilter(BROADCAST_ALL));
-                sCallingTest.addIntermediate("after-register");
-                sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_ALL), null);
-                sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_ALL), null);
-                sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_ALL), null);
-                sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_LOCAL), null);
-                sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_REMOTE), null);
-                sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_LOCAL), null);
-                sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_REMOTE), null);
-                sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_ALL), null);
-                sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_ALL), null);
-                sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_ALL), null);
-                sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_REPEAT), null);
-            } else if (BROADCAST_ABORT.equals(action)) {
-                setExpectedReceivers(new String[] {
-                        RECEIVER_REMOTE, RECEIVER_ABORT
-                });
-                registerMyReceiver(new IntentFilter(BROADCAST_ABORT));
-                sCallingTest.addIntermediate("after-register");
-                sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_ABORT), null);
-            } else if (BROADCAST_STICKY1.equals(action)) {
-                setExpectedReceivers(new String[] {
-                    RECEIVER_REG
-                });
-                setExpectedData(new String[] {
-                    DATA_1
-                });
-                registerMyReceiver(new IntentFilter(BROADCAST_STICKY1));
-                sCallingTest.addIntermediate("after-register");
-            } else if (BROADCAST_STICKY2.equals(action)) {
-                setExpectedReceivers(new String[] {
-                        RECEIVER_REG, RECEIVER_REG
-                });
-                setExpectedData(new String[] {
-                        DATA_1, DATA_2
-                });
-                final IntentFilter filter = new IntentFilter(BROADCAST_STICKY1);
-                filter.addAction(BROADCAST_STICKY2);
-                registerMyReceiver(filter);
-                sCallingTest.addIntermediate("after-register");
-            } else if (ALIAS_ACTIVITY.equals(action)) {
-                final Intent intent = getIntent();
-                intent.setFlags(0);
-                intent.setClass(this, AliasActivityStub.class);
-                startActivityForResult(intent, LAUNCHED_RESULT);
-            } else if (EXPANDLIST_SELECT.equals(action)) {
-                final Intent intent = getIntent();
-                intent.setFlags(0);
-                intent.setAction(action);
-                intent.setComponent((ComponentName) intent.getParcelableExtra("component"));
-                startActivityForResult(intent, LAUNCHED_RESULT);
-            } else if (EXPANDLIST_VIEW.equals(action)) {
-                final Intent intent = getIntent();
-                intent.setFlags(0);
-                intent.setAction(action);
-                intent.setComponent((ComponentName) intent.getParcelableExtra("component"));
-                startActivityForResult(intent, LAUNCHED_RESULT);
-            } else if (EXPANDLIST_CALLBACK.equals(action)) {
-                final Intent intent = getIntent();
-                intent.setFlags(0);
-                intent.setAction(action);
-                intent.setComponent((ComponentName) intent.getParcelableExtra("component"));
-                startActivityForResult(intent, LAUNCHED_RESULT);
-            }
-        }
-    }
-
-    @Override
-    protected void onSaveInstanceState(Bundle icicle) {
-        super.onSaveInstanceState(icicle);
-        if (mBadParcelable) {
-            icicle.putParcelable("baddy", new MyBadParcelable());
-        }
-    }
-
-    @Override
-    protected void onPause() {
-        super.onPause();
-        checkLifecycle(ON_PAUSE);
-    }
-
-    @Override
-    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
-        switch (requestCode) {
-            case LAUNCHED_RESULT:
-                sCallingTest.finishTiming(true);
-                finishWithResult(resultCode, data);
-                break;
-            case FORWARDED_RESULT:
-                sCallingTest.finishTiming(true);
-                if (RETURNED_RESULT.equals(data.getAction())) {
-                    finishWithResult(resultCode, data);
-                } else {
-                    finishWithResult(RESULT_CANCELED, new Intent().setAction("Bad data returned: "
-                            + data));
-                }
-                break;
-            default:
-                sCallingTest.finishTiming(true);
-                finishWithResult(RESULT_CANCELED, new Intent()
-                        .setAction("Unexpected request code: " + requestCode));
-                break;
-        }
-    }
-
-    private void checkLifecycle(String where) {
-        String action = getIntent().getAction();
-
-        if (mExpectedLifecycle == null) {
-            return;
-        }
-
-        if (mNextLifecycle >= mExpectedLifecycle.length) {
-            finishBad("Activity lifecycle for " + action + " incorrect: received " + where
-                    + " but don't expect any more calls");
-            mExpectedLifecycle = null;
-            return;
-        }
-
-        do {
-            if (mExpectedLifecycle[mNextLifecycle].equals(where)) {
-                Log.w(TAG, "Matched: " + where);
-                break;
-            } else {
-                Log.w(TAG, "Expected " + mExpectedLifecycle[mNextLifecycle] + " but got " + where);
-            }
-        } while (switchToNextPossibleLifecycle());
-
-        if (mExpectedLifecycle == null) {
-            finishBad("Activity lifecycle for " + action + " incorrect: received " + where
-                    + " at " + mNextLifecycle);
-            return;
-        }
-
-        mNextLifecycle++;
-
-        if (mNextLifecycle >= mExpectedLifecycle.length) {
-            finishGood();
-            return;
-        }
-
-        final String next = mExpectedLifecycle[mNextLifecycle];
-        if (next.equals(DO_FINISH)) {
-            mNextLifecycle++;
-            if (mNextLifecycle >= mExpectedLifecycle.length) {
-                setTestResult(RESULT_OK, null);
-            }
-            if (!isFinishing()) {
-                finish();
-            }
-        } else if (next.equals(DO_LOCAL_SCREEN)) {
-            mNextLifecycle++;
-            final Intent intent = new Intent(TestedScreen.WAIT_BEFORE_FINISH);
-            intent.setClass(this, LocalScreen.class);
-            startActivity(intent);
-        } else if (next.equals(DO_LOCAL_DIALOG)) {
-            mNextLifecycle++;
-            final Intent intent = new Intent(TestedScreen.WAIT_BEFORE_FINISH);
-            intent.setClass(this, LocalDialog.class);
-            startActivity(intent);
-        }
-    }
-
-    private void setExpectedReceivers(String[] receivers) {
-        mExpectedReceivers = receivers;
-        mNextReceiver = 0;
-    }
-
-    private void setExpectedData(String[] data) {
-        mExpectedData = data;
-        mReceivedData = new boolean[data.length];
-    }
-
-    @SuppressWarnings("deprecation")
-    private Intent makeBroadcastIntent(String action) {
-        final Intent intent = new Intent(action, null);
-        intent.putExtra("caller", mCallTarget);
-        return intent;
-    }
-
-    private void finishGood() {
-        finishWithResult(RESULT_OK, null);
-    }
-
-    private void finishBad(String error) {
-        finishWithResult(RESULT_CANCELED, new Intent().setAction(error));
-    }
-
-    private void finishWithResult(int resultCode, Intent data) {
-        setTestResult(resultCode, data);
-        finish();
-
-        // Member fields set by calling setTestResult above...
-        sCallingTest.activityFinished(mResultCode, mData, mResultStack);
-    }
-
-    private void setTestResult(int resultCode, Intent data) {
-        mHandler.removeCallbacks(mTimeout);
-        unregisterMyReceiver();
-        mResultCode = resultCode;
-        mData = data;
-        mResultStack = new RuntimeException("Original error was here");
-        mResultStack.fillInStackTrace();
-    }
-
-    private void registerMyReceiver(IntentFilter filter) {
-        mReceiverRegistered = true;
-        registerReceiver(mReceiver, filter);
-    }
-
-    private void unregisterMyReceiver() {
-        if (mReceiverRegistered) {
-            mReceiverRegistered = false;
-            unregisterReceiver(mReceiver);
-        }
-    }
-
-    private final Handler mHandler = new Handler() {
-        @Override
-        public void handleMessage(Message msg) {
-        }
-    };
-
-    static final int GOT_RECEIVE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION;
-    static final int ERROR_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 1;
-
-    private final Binder mCallTarget = new Binder() {
-        @Override
-        public boolean onTransact(int code, Parcel data, Parcel reply, int flags) {
-            data.setDataPosition(0);
-            data.enforceInterface(LaunchpadActivity.LAUNCH);
-            if (code == GOT_RECEIVE_TRANSACTION) {
-                final String name = data.readString();
-                gotReceive(name, null);
-                return true;
-            } else if (code == ERROR_TRANSACTION) {
-                finishBad(data.readString());
-                return true;
-            }
-            return false;
-        }
-    };
-
-    private final void gotReceive(String name, Intent intent) {
-        synchronized (this) {
-
-            sCallingTest.addIntermediate(mNextReceiver + "-" + name);
-
-            if (mExpectedData != null) {
-                final int n = mExpectedData.length;
-                int i;
-                boolean prev = false;
-                for (i = 0; i < n; i++) {
-                    if (mExpectedData[i].equals(intent.getStringExtra("test"))) {
-                        if (mReceivedData[i]) {
-                            prev = true;
-                            continue;
-                        }
-                        mReceivedData[i] = true;
-                        break;
-                    }
-                }
-                if (i >= n) {
-                    if (prev) {
-                        finishBad("Receive got data too many times: "
-                                + intent.getStringExtra("test"));
-                    } else {
-                        finishBad("Receive got unexpected data: " + intent.getStringExtra("test"));
-                    }
-                    return;
-                }
-            }
-
-            if (mNextReceiver >= mExpectedReceivers.length) {
-                finishBad("Got too many onReceiveIntent() calls!");
-            } else if (!mExpectedReceivers[mNextReceiver].equals(name)) {
-                finishBad("Receive out of order: got " + name + " but expected "
-                        + mExpectedReceivers[mNextReceiver] + " at " + mNextReceiver);
-            } else {
-                mNextReceiver++;
-                if (mNextReceiver == mExpectedReceivers.length) {
-                    mHandler.post(mUnregister);
-                }
-            }
-
-        }
-    }
-
-    private final Runnable mUnregister = new Runnable() {
-        public void run() {
-            if (mReceiverRegistered) {
-                sCallingTest.addIntermediate("before-unregister");
-                unregisterMyReceiver();
-            }
-            sCallingTest.finishTiming(true);
-            finishGood();
-        }
-    };
-
-    private final Runnable mTimeout = new Runnable() {
-        public void run() {
-            Log.i(TAG, "timeout");
-            String msg = "Timeout";
-            if (mExpectedReceivers != null && mNextReceiver < mExpectedReceivers.length) {
-                msg = msg + " waiting for " + mExpectedReceivers[mNextReceiver];
-            }
-            finishBad(msg);
-        }
-    };
-
-    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            gotReceive(RECEIVER_REG, intent);
-        }
-    };
-}
diff --git a/tests/app/src/android/app/cts/LaunchpadTabActivity.java b/tests/app/src/android/app/cts/LaunchpadTabActivity.java
deleted file mode 100644
index 3dfd2c3..0000000
--- a/tests/app/src/android/app/cts/LaunchpadTabActivity.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-import android.app.TabActivity;
-import android.content.ComponentName;
-import android.content.Intent;
-import android.os.Bundle;
-import android.widget.TabHost;
-
-public class LaunchpadTabActivity extends TabActivity {
-    public LaunchpadTabActivity() {
-    }
-
-    @Override
-    public void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-
-        final Intent tabIntent = new Intent(getIntent());
-        tabIntent.setComponent((ComponentName) tabIntent.getParcelableExtra("tab"));
-
-        final TabHost th = getTabHost();
-        final TabHost.TabSpec ts = th.newTabSpec("1");
-        ts.setIndicator("One");
-        ts.setContent(tabIntent);
-        th.addTab(ts);
-    }
-}
diff --git a/tests/app/src/android/app/cts/LifecycleTest.java b/tests/app/src/android/app/cts/LifecycleTest.java
new file mode 100644
index 0000000..8b08dcb
--- /dev/null
+++ b/tests/app/src/android/app/cts/LifecycleTest.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.cts;
+
+import android.app.stubs.ActivityTestsBase;
+import android.app.stubs.LaunchpadActivity;
+import android.app.stubs.LaunchpadTabActivity;
+import android.content.ComponentName;
+import android.content.Intent;
+
+public class LifecycleTest extends ActivityTestsBase {
+    private Intent mTopIntent;
+    private Intent mTabIntent;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mTopIntent = mIntent;
+        mTabIntent = new Intent(mContext, LaunchpadTabActivity.class);
+        mTabIntent.putExtra("tab", new ComponentName(mContext, LaunchpadActivity.class));
+    }
+
+    public void testTabDialog() {
+        mIntent = mTabIntent;
+        runLaunchpad(LaunchpadActivity.LIFECYCLE_DIALOG);
+    }
+
+    public void testDialog() {
+        mIntent = mTopIntent;
+        runLaunchpad(LaunchpadActivity.LIFECYCLE_DIALOG);
+    }
+
+    public void testTabScreen() {
+        mIntent = mTabIntent;
+        runLaunchpad(LaunchpadActivity.LIFECYCLE_SCREEN);
+    }
+
+    public void testScreen() {
+        mIntent = mTopIntent;
+        runLaunchpad(LaunchpadActivity.LIFECYCLE_SCREEN);
+    }
+
+    public void testTabBasic() {
+        mIntent = mTabIntent;
+        runLaunchpad(LaunchpadActivity.LIFECYCLE_BASIC);
+    }
+
+    public void testBasic() {
+        mIntent = mTopIntent;
+        runLaunchpad(LaunchpadActivity.LIFECYCLE_BASIC);
+    }
+}
diff --git a/tests/app/src/android/app/cts/ListActivityTest.java b/tests/app/src/android/app/cts/ListActivityTest.java
new file mode 100644
index 0000000..1947595
--- /dev/null
+++ b/tests/app/src/android/app/cts/ListActivityTest.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.cts;
+
+import android.app.Instrumentation;
+import android.app.ListActivity;
+import android.app.stubs.MockListActivity;
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.view.View;
+import android.view.ViewTreeObserver;
+import android.widget.ArrayAdapter;
+import android.widget.ListAdapter;
+import junit.framework.Assert;
+
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+@SmallTest
+public class ListActivityTest extends ActivityInstrumentationTestCase2<MockListActivity> {
+    private ListActivity mActivity;
+
+    public ListActivityTest() {
+        super(MockListActivity.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mActivity = getActivity();
+    }
+
+    public void testAdapter() throws Throwable {
+        final ListAdapter listAdapter = new ArrayAdapter<String>(mActivity,
+                android.R.layout.simple_list_item_1,
+                new String[] { "Mercury", "Mars", "Earth", "Venus"});
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mActivity.setListAdapter(listAdapter);
+            }
+        });
+        assertEquals(listAdapter, mActivity.getListAdapter());
+        assertEquals(listAdapter, mActivity.getListView().getAdapter());
+    }
+
+    public void testSelection() throws Throwable {
+        final ListAdapter listAdapter = new ArrayAdapter<String>(mActivity,
+                android.R.layout.simple_list_item_1,
+                new String[] { "Alpha", "Bravo", "Charlie", "Delta", "Echo"});
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mActivity.setListAdapter(listAdapter);
+            }
+        });
+        assertEquals(0, mActivity.getSelectedItemPosition());
+        assertEquals(0, mActivity.getSelectedItemId());
+
+        runOnMainAndDrawSync(getInstrumentation(), mActivity.getListView(), new Runnable() {
+            @Override
+            public void run() {
+                mActivity.setSelection(2);
+            }
+        });
+        assertEquals(2, mActivity.getSelectedItemPosition());
+        assertEquals(2, mActivity.getSelectedItemId());
+    }
+
+    public void testItemClick() throws Throwable {
+        final ListAdapter listAdapter = new ArrayAdapter<String>(mActivity,
+                android.R.layout.simple_list_item_1,
+                new String[] { "Froyo", "Gingerbread", "Ice Cream Sandwich" });
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mActivity.setListAdapter(listAdapter);
+            }
+        });
+
+        final MockListActivity mockListActivity = (MockListActivity) mActivity;
+        assertFalse(mockListActivity.isOnListItemClickCalled);
+
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mActivity.getListView().performItemClick(null, 1, 1);
+            }
+        });
+
+        assertTrue(mockListActivity.isOnListItemClickCalled);
+        assertEquals(1, mockListActivity.itemClickCallCount);
+        assertEquals(1, mockListActivity.clickedItemPosition);
+    }
+
+    private static void runOnMainAndDrawSync(Instrumentation instrumentation,
+            final View view, final Runnable runner) {
+        final Semaphore token = new Semaphore(0);
+        final Runnable releaseToken = new Runnable() {
+            @Override
+            public void run() {
+                token.release();
+            }
+        };
+
+        instrumentation.runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                final ViewTreeObserver observer = view.getViewTreeObserver();
+                final ViewTreeObserver.OnDrawListener listener = new ViewTreeObserver.OnDrawListener() {
+                    @Override
+                    public void onDraw() {
+                        observer.removeOnDrawListener(this);
+                        view.post(releaseToken);
+                    }
+                };
+
+                observer.addOnDrawListener(listener);
+                runner.run();
+            }
+        });
+
+        try {
+            Assert.assertTrue("Expected draw pass occurred within 5 seconds",
+                    token.tryAcquire(5, TimeUnit.SECONDS));
+        } catch (InterruptedException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+}
diff --git a/tests/app/src/android/app/cts/LocalActivity.java b/tests/app/src/android/app/cts/LocalActivity.java
deleted file mode 100644
index 67fad8c..0000000
--- a/tests/app/src/android/app/cts/LocalActivity.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-public class LocalActivity extends TestedActivity {
-    public LocalActivity() {
-    }
-}
diff --git a/tests/app/src/android/app/cts/LocalActivityManagerStubActivity.java b/tests/app/src/android/app/cts/LocalActivityManagerStubActivity.java
deleted file mode 100644
index e64c75a..0000000
--- a/tests/app/src/android/app/cts/LocalActivityManagerStubActivity.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-import android.app.Activity;
-import android.os.Bundle;
-
-public class LocalActivityManagerStubActivity extends Activity{
-
-    public static boolean sIsOnResumeCalled;
-    public static boolean sIsOnStopCalled;
-    public static boolean sIsOnPauseCalled;
-    public static boolean sIsOnDestroyCalled;
-
-    @Override
-    public void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-    }
-
-    @Override
-    public void onResume() {
-        super.onResume();
-        sIsOnResumeCalled = true;
-    }
-
-    @Override
-    protected void onStop() {
-        super.onStop();
-        sIsOnStopCalled = true;
-    }
-
-    @Override
-    protected void onPause() {
-        super.onPause();
-        sIsOnPauseCalled = true;
-    }
-
-    @Override
-    protected void onDestroy() {
-        super.onDestroy();
-        sIsOnDestroyCalled = true;
-    }
-}
diff --git a/tests/app/src/android/app/cts/LocalActivityManagerTest.java b/tests/app/src/android/app/cts/LocalActivityManagerTest.java
new file mode 100644
index 0000000..7f6fd2f
--- /dev/null
+++ b/tests/app/src/android/app/cts/LocalActivityManagerTest.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.cts;
+
+import android.app.Activity;
+import android.app.Instrumentation;
+import android.app.LocalActivityManager;
+import android.app.stubs.LocalActivityManagerTestHelper;
+import android.content.Intent;
+import android.cts.util.CTSResult;
+import android.test.InstrumentationTestCase;
+import android.test.UiThreadTest;
+
+public class LocalActivityManagerTest extends InstrumentationTestCase implements CTSResult {
+
+    private Instrumentation mInstrumentation;
+
+    private Sync mSync = new Sync();
+    private static class Sync {
+        public boolean mHasNotify;
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mInstrumentation = getInstrumentation();
+        mSync = new Sync();
+    }
+
+    private void setupActivity(final String action) {
+        final Intent intent = new Intent(mInstrumentation.getTargetContext(),
+                LocalActivityManagerTestHelper.class);
+        intent.setAction(action);
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        mInstrumentation.getTargetContext().startActivity(intent);
+    }
+
+    @UiThreadTest
+    public void testConstructor() {
+        new LocalActivityManager(new Activity(), true);
+        new LocalActivityManager(new Activity(), false);
+        new LocalActivityManager(null, false);
+        new LocalActivityManager(null, true);
+    }
+
+    public void testDispatchResume() throws InterruptedException {
+        LocalActivityManagerTestHelper.setResult(this);
+        setupActivity(LocalActivityManagerTestHelper.ACTION_DISPATCH_RESUME);
+        waitForResult();
+    }
+
+    private void waitForResult() throws InterruptedException {
+        synchronized (mSync) {
+            if (!mSync.mHasNotify) {
+                mSync.wait();
+            }
+        }
+    }
+
+    public void testStartActivity() throws InterruptedException {
+        LocalActivityManagerTestHelper.setResult(this);
+        setupActivity(LocalActivityManagerTestHelper.ACTION_START_ACTIVITY);
+        waitForResult();
+    }
+
+    public void testDispatchCreate() throws InterruptedException {
+        LocalActivityManagerTestHelper.setResult(this);
+        setupActivity(LocalActivityManagerTestHelper.ACTION_DISPATCH_CREATE);
+        waitForResult();
+    }
+
+    public void testDispatchStop() throws InterruptedException {
+        LocalActivityManagerTestHelper.setResult(this);
+        setupActivity(LocalActivityManagerTestHelper.ACTION_DISPATCH_STOP);
+        waitForResult();
+    }
+
+    public void testDispatchPauseTrue() throws InterruptedException {
+        LocalActivityManagerTestHelper.setResult(this);
+        setupActivity(LocalActivityManagerTestHelper.ACTION_DISPATCH_PAUSE_TRUE);
+        waitForResult();
+    }
+
+    public void testDispatchPauseFalse() throws InterruptedException {
+        LocalActivityManagerTestHelper.setResult(this);
+        setupActivity(LocalActivityManagerTestHelper.ACTION_DISPATCH_PAUSE_FALSE);
+        waitForResult();
+    }
+
+    public void testSaveInstanceState() throws InterruptedException {
+        LocalActivityManagerTestHelper.setResult(this);
+        setupActivity(LocalActivityManagerTestHelper.ACTION_SAVE_INSTANCE_STATE);
+        waitForResult();
+    }
+
+    public void testDispatchDestroy() throws InterruptedException {
+        LocalActivityManagerTestHelper.setResult(this);
+        setupActivity(LocalActivityManagerTestHelper.ACTION_DISPATCH_DESTROY);
+        waitForResult();
+    }
+
+    public void testRemoveAllActivities() throws InterruptedException {
+        LocalActivityManagerTestHelper.setResult(this);
+        setupActivity(LocalActivityManagerTestHelper.ACTION_REMOVE_ALL_ACTIVITY);
+        waitForResult();
+    }
+
+    public void setResult(final int resultCode) {
+        synchronized (mSync) {
+            mSync.mHasNotify = true;
+            mSync.notify();
+            assertEquals(CTSResult.RESULT_OK, resultCode);
+        }
+    }
+
+    public void setResult(Exception e) {
+        setResult(CTSResult.RESULT_FAIL);
+    }
+
+}
diff --git a/tests/app/src/android/app/cts/LocalActivityManagerTestHelper.java b/tests/app/src/android/app/cts/LocalActivityManagerTestHelper.java
deleted file mode 100644
index 70764e4..0000000
--- a/tests/app/src/android/app/cts/LocalActivityManagerTestHelper.java
+++ /dev/null
@@ -1,340 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES 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.app.cts;
-
-
-import android.app.Activity;
-import android.app.ActivityGroup;
-import android.app.LocalActivityManager;
-import android.content.Intent;
-import android.cts.util.CTSResult;
-import android.os.Bundle;
-import android.view.Window;
-
-public class LocalActivityManagerTestHelper extends ActivityGroup {
-
-    public static final String ACTION_DISPATCH_RESUME = "dispatchResume";
-    public static final String ACTION_START_ACTIVITY = "startActivity";
-    public static final String ACTION_DISPATCH_CREATE = "dispatchCreate";
-    public static final String ACTION_DISPATCH_STOP = "dispatchStop";
-    public static final String ACTION_DISPATCH_PAUSE_TRUE = "dispatchPauseTrue";
-    public static final String ACTION_DISPATCH_PAUSE_FALSE = "dispatchPauseFalse";
-    public static final String ACTION_SAVE_INSTANCE_STATE = "saveInstanceState";
-    public static final String ACTION_DISPATCH_DESTROY = "dispatchDestroy";
-    public static final String ACTION_REMOVE_ALL_ACTIVITY = "removeAllActivities";
-
-    private String mCurrentAction;
-    private LocalActivityManager mLocalActivityManager;
-
-    private static CTSResult sResult;
-
-    public static void setResult(CTSResult cr) {
-        sResult = cr;
-    }
-
-    public LocalActivityManagerTestHelper() {
-        super();
-    }
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        mCurrentAction = getIntent().getAction();
-        mLocalActivityManager = getLocalActivityManager();
-    }
-
-    @Override
-    protected void onStart() {
-        super.onStart();
-    }
-
-    protected void onResume() {
-        super.onResume();
-        if (mCurrentAction.equals(ACTION_DISPATCH_RESUME)) {
-            testDispatchResume();
-        } else if (mCurrentAction.equals(ACTION_START_ACTIVITY)) {
-            testStartActivity();
-        } else if (mCurrentAction.equals(ACTION_DISPATCH_CREATE)) {
-            testDispatchCreate();
-        } else if (mCurrentAction.equals(ACTION_DISPATCH_STOP)) {
-            testDispatchStop();
-        } else if (mCurrentAction.equals(ACTION_DISPATCH_PAUSE_TRUE)) {
-            testDispatchPauseTrue();
-        } else if (mCurrentAction.equals(ACTION_DISPATCH_PAUSE_FALSE)) {
-            testDispatchPauseFalse();
-        } else if (mCurrentAction.equals(ACTION_SAVE_INSTANCE_STATE)) {
-            testSaveInstanceState();
-        } else if (mCurrentAction.equals(ACTION_DISPATCH_DESTROY)) {
-            testDispatchDestroy();
-        } else if (mCurrentAction.equals(ACTION_REMOVE_ALL_ACTIVITY)) {
-            testRemoveAllActivity();
-        }
-    }
-
-    private void testRemoveAllActivity() {
-        final String id = "id_remove_activity";
-        final Intent intent = new Intent(this, LocalActivityManagerStubActivity.class);
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        mLocalActivityManager.startActivity(id, intent);
-
-        Activity activity = mLocalActivityManager.getActivity(id);
-        if (activity == null) {
-            fail();
-            return;
-        }
-
-        if (!activity.getClass().getName().equals("android.app.cts."
-                    + "LocalActivityManagerStubActivity")) {
-            fail();
-            return;
-        }
-
-        mLocalActivityManager.removeAllActivities();
-        activity = mLocalActivityManager.getActivity(id);
-        if (activity != null) {
-            fail();
-            return;
-        }
-        pass();
-    }
-
-    private void testDispatchDestroy() {
-        final String id1 = "id_dispatch_destroy1";
-        final String id2 = "id_dispatch_destroy2";
-        final Intent intent = new Intent(this, LocalActivityManagerStubActivity.class);
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        mLocalActivityManager.startActivity(id1, intent);
-
-        LocalActivityManagerStubActivity.sIsOnDestroyCalled = false;
-        mLocalActivityManager.dispatchDestroy(false);
-        if (mLocalActivityManager.getCurrentActivity().isFinishing()){
-            fail();
-            return;
-        }
-
-        if (!LocalActivityManagerStubActivity.sIsOnDestroyCalled) {
-            fail();
-            return;
-        }
-
-        mLocalActivityManager.startActivity(id2, intent);
-        LocalActivityManagerStubActivity.sIsOnDestroyCalled = false;
-        mLocalActivityManager.dispatchDestroy(true);
-
-        if (!LocalActivityManagerStubActivity.sIsOnDestroyCalled) {
-            fail();
-            return;
-        }
-
-        if (!mLocalActivityManager.getCurrentActivity().isFinishing()){
-            fail();
-            return;
-        }
-        pass();
-    }
-
-    private void testSaveInstanceState() {
-        final String key = "_id1";
-        mLocalActivityManager.dispatchCreate(null);
-        final Bundle bundle = mLocalActivityManager.saveInstanceState();
-        if (bundle != null) {
-            fail();
-            return;
-        }
-
-        final String id = "id_dispatch_pause";
-        final Intent intent = new Intent(this, LocalActivityManagerStubActivity.class);
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        mLocalActivityManager.startActivity(id, intent);
-
-        final Bundle savedBundle = new Bundle();
-        final Bundle bb = new Bundle();
-        savedBundle.putBundle(key, bb);
-
-        mLocalActivityManager.dispatchCreate(savedBundle);
-        final Bundle returnedBundle = mLocalActivityManager.saveInstanceState();
-        if (returnedBundle.getBundle(key) == null ) {
-            fail();
-            return;
-        }
-        pass();
-    }
-
-    private void testDispatchPauseFalse() {
-        final String id = "id_dispatch_pause";
-        final Intent intent = new Intent(this, LocalActivityManagerStubActivity.class);
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        mLocalActivityManager.startActivity(id, intent);
-        LocalActivityManagerStubActivity.sIsOnPauseCalled = false;
-        mLocalActivityManager.dispatchPause(false);
-        if (!LocalActivityManagerStubActivity.sIsOnPauseCalled) {
-            fail();
-            return;
-        }
-        pass();
-    }
-
-    private void testDispatchPauseTrue() {
-        final String id = "id_dispatch_pause";
-        final Intent intent = new Intent(this, LocalActivityManagerStubActivity.class);
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        mLocalActivityManager.startActivity(id, intent);
-        LocalActivityManagerStubActivity.sIsOnPauseCalled = false;
-        mLocalActivityManager.dispatchPause(true);
-        if (!LocalActivityManagerStubActivity.sIsOnPauseCalled) {
-            fail();
-            return;
-        }
-        pass();
-    }
-
-    private void testDispatchStop() {
-        final String id = "id_dispatch_stop";
-        final Intent intent = new Intent(this, LocalActivityManagerStubActivity.class);
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        mLocalActivityManager.startActivity(id, intent);
-        if (mLocalActivityManager.getCurrentActivity() == null) {
-            fail();
-            return;
-        }
-
-        LocalActivityManagerStubActivity.sIsOnStopCalled = false;
-        mLocalActivityManager.dispatchStop();
-
-        if (!LocalActivityManagerStubActivity.sIsOnStopCalled) {
-            fail();
-            return;
-        }
-        pass();
-    }
-
-    private void testDispatchCreate() {
-        final Bundle EXPECTED = new Bundle();
-        final String id = "id";
-
-        final Intent intent = new Intent(this, LocalActivityManagerStubActivity.class);
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        mLocalActivityManager.startActivity("_id" + System.currentTimeMillis(), intent);
-        final Bundle bundle = mLocalActivityManager.saveInstanceState();
-        if (bundle == null) {
-            fail();
-            return;
-        }
-
-        if (bundle.keySet().size() != 1) {
-            fail();
-            return;
-        }
-
-        bundle.putBundle(id, EXPECTED);
-        // test null parameter
-        mLocalActivityManager.dispatchCreate(null);
-
-        if (mLocalActivityManager.saveInstanceState().keySet().size() != 1) {
-            fail();
-            return;
-        }
-
-        mLocalActivityManager.dispatchCreate(bundle);
-
-        final Bundle b = mLocalActivityManager.saveInstanceState();
-        final Bundle bb = b.getBundle(id);
-        if (bb != EXPECTED) {
-            fail();
-            return;
-        }
-        pass();
-    }
-
-    private void testStartActivity() {
-        final Intent intent = new Intent(this, LocalActivityManagerStubActivity.class);
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        final String id = "_id_resume_test";
-        final Window w = mLocalActivityManager.startActivity(id, intent);
-        if (w == null) {
-            fail();
-            return;
-        }
-
-        Activity activity = mLocalActivityManager.getActivity(id);
-        if (activity == null) {
-            fail();
-            return;
-        }
-
-        // testing null id
-        activity = mLocalActivityManager.getActivity("null id");
-        if (activity != null) {
-            fail();
-            return;
-        }
-
-        if (!mLocalActivityManager.getCurrentId().equals(id)) {
-            fail();
-            return;
-        }
-
-        if (mLocalActivityManager.getActivity(id) != mLocalActivityManager
-                .getCurrentActivity()) {
-            fail();
-            return;
-        }
-
-        if (mLocalActivityManager.destroyActivity(id, true) == null) {
-            fail();
-            return;
-        }
-
-        if (mLocalActivityManager.startActivity(null, intent) == null) {
-            fail();
-            return;
-        }
-
-        try {
-            // test when calling startActivity with both null parameter.
-            mLocalActivityManager.startActivity(null, null);
-            fail();
-            return;
-        } catch (NullPointerException e) {
-        }
-        pass();
-    }
-
-    private void testDispatchResume() {
-        final Intent intent = new Intent(this, LocalActivityManagerStubActivity.class);
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        mLocalActivityManager.startActivity("_id_resume_test", intent);
-        mLocalActivityManager.dispatchStop();
-        LocalActivityManagerStubActivity.sIsOnResumeCalled = false;
-        mLocalActivityManager.dispatchResume();
-        if (LocalActivityManagerStubActivity.sIsOnResumeCalled) {
-            pass();
-        } else {
-            fail();
-        }
-    }
-
-    private void fail() {
-        sResult.setResult(CTSResult.RESULT_FAIL);
-        finish();
-    }
-
-    private void pass() {
-        sResult.setResult(CTSResult.RESULT_OK);
-        finish();
-    }
-}
diff --git a/tests/app/src/android/app/cts/LocalDeniedService.java b/tests/app/src/android/app/cts/LocalDeniedService.java
deleted file mode 100644
index d3c9153..0000000
--- a/tests/app/src/android/app/cts/LocalDeniedService.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-public class LocalDeniedService extends LocalService
-{
-}
-
diff --git a/tests/app/src/android/app/cts/LocalDialog.java b/tests/app/src/android/app/cts/LocalDialog.java
deleted file mode 100644
index ec670fc..0000000
--- a/tests/app/src/android/app/cts/LocalDialog.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-public class LocalDialog extends TestedScreen {
-    public LocalDialog() {
-    }
-}
diff --git a/tests/app/src/android/app/cts/LocalGrantedService.java b/tests/app/src/android/app/cts/LocalGrantedService.java
deleted file mode 100644
index c073f12..0000000
--- a/tests/app/src/android/app/cts/LocalGrantedService.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-public class LocalGrantedService extends LocalService
-{
-}
-
diff --git a/tests/app/src/android/app/cts/LocalScreen.java b/tests/app/src/android/app/cts/LocalScreen.java
deleted file mode 100644
index 87f5530..0000000
--- a/tests/app/src/android/app/cts/LocalScreen.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-public class LocalScreen extends TestedScreen {
-    public LocalScreen() {
-    }
-}
diff --git a/tests/app/src/android/app/cts/LocalService.java b/tests/app/src/android/app/cts/LocalService.java
deleted file mode 100644
index 6c4ae99..0000000
--- a/tests/app/src/android/app/cts/LocalService.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-import android.app.Service;
-import android.content.Intent;
-import android.cts.util.IBinderParcelable;
-import android.os.Binder;
-import android.os.IBinder;
-import android.os.Parcel;
-import android.os.RemoteException;
-
-public class LocalService extends Service {
-    public static final String SERVICE_LOCAL =
-            "android.app.cts.activity.SERVICE_LOCAL";
-    public static final String SERVICE_LOCAL_GRANTED =
-            "android.app.cts.activity.SERVICE_LOCAL_GRANTED";
-    public static final String SERVICE_LOCAL_DENIED =
-            "android.app.cts.activity.SERVICE_LOCAL_DENIED";
-
-    public static final String REPORT_OBJ_NAME = "report";
-
-    public static final int STARTED_CODE = 1;
-    public static final int DESTROYED_CODE = 2;
-    public static final int SET_REPORTER_CODE = 3;
-    public static final int UNBIND_CODE = 4;
-    public static final int REBIND_CODE = 5;
-
-    private IBinder mReportObject;
-    private int mStartCount = 1;
-
-    private final IBinder mBinder = new Binder() {
-        @Override
-        protected boolean onTransact(int code, Parcel data, Parcel reply,
-                int flags) throws RemoteException {
-            if (code == SET_REPORTER_CODE) {
-                data.enforceInterface(SERVICE_LOCAL);
-                mReportObject = data.readStrongBinder();
-                return true;
-            } else {
-                return super.onTransact(code, data, reply, flags);
-            }
-        }
-    };
-
-
-    public LocalService() {
-    }
-
-    @Override
-    public void onStart(Intent intent, int startId) {
-        if (intent.getExtras() != null) {
-            IBinderParcelable parcelable
-                    = (IBinderParcelable) intent.getExtras().getParcelable(REPORT_OBJ_NAME);
-            mReportObject = parcelable.binder;
-            if (mReportObject != null) {
-                bindAction(STARTED_CODE);
-            }
-        }
-    }
-
-    @Override
-    public void onDestroy() {
-        if (mReportObject != null) {
-            bindAction(DESTROYED_CODE);
-        }
-    }
-
-    @Override
-    public IBinder onBind(Intent intent) {
-        return mBinder;
-    }
-
-    @Override
-    public boolean onUnbind(Intent intent) {
-        if (mReportObject != null) {
-            bindAction(UNBIND_CODE);
-        }
-        return true;
-    }
-
-    @Override
-    public void onRebind(Intent intent) {
-        if (mReportObject != null) {
-            bindAction(REBIND_CODE);
-        }
-    }
-
-    private void bindAction(final int bindCode) {
-        try {
-            Parcel data = Parcel.obtain();
-            data.writeInterfaceToken(SERVICE_LOCAL);
-            if (bindCode == STARTED_CODE) {
-                data.writeInt(mStartCount);
-                mStartCount++;
-            }
-            mReportObject.transact(
-                    bindCode, data, null, 0);
-            data.recycle();
-        } catch (RemoteException e) {
-            // fail
-        }
-    }
-}
diff --git a/tests/app/src/android/app/cts/MockActivity.java b/tests/app/src/android/app/cts/MockActivity.java
deleted file mode 100644
index 8d10c71..0000000
--- a/tests/app/src/android/app/cts/MockActivity.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-import android.app.Activity;
-
-public class MockActivity extends Activity {
-
-}
diff --git a/tests/app/src/android/app/cts/MockAlarmReceiver.java b/tests/app/src/android/app/cts/MockAlarmReceiver.java
deleted file mode 100644
index 8745db6..0000000
--- a/tests/app/src/android/app/cts/MockAlarmReceiver.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.os.SystemClock;
-
-/**
- * this class  receive alarm from AlarmManagerTest
- */
-public class MockAlarmReceiver extends BroadcastReceiver {
-    private final Object mSync = new Object();
-    public final String mTargetAction;
-
-    public volatile boolean alarmed = false;
-    public volatile long elapsedTime;
-    public volatile long rtcTime;
-
-    public MockAlarmReceiver(String targetAction) {
-        mTargetAction = targetAction;
-    }
-
-    @Override
-    public void onReceive(Context context, Intent intent) {
-        final String action = intent.getAction();
-        if (action.equals(mTargetAction)) {
-            synchronized (mSync) {
-                alarmed = true;
-                elapsedTime = SystemClock.elapsedRealtime();
-                rtcTime = System.currentTimeMillis();
-            }
-        }
-    }
-
-    public void setAlarmedFalse() {
-        synchronized (mSync) {
-            alarmed = false;
-        }
-    }
-}
diff --git a/tests/app/src/android/app/cts/MockApplication.java b/tests/app/src/android/app/cts/MockApplication.java
deleted file mode 100644
index 0d0cb43..0000000
--- a/tests/app/src/android/app/cts/MockApplication.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-import android.app.Application;
-import android.content.res.Configuration;
-
-
-public class MockApplication extends Application {
-
-    public boolean isOnCreateCalled;
-    public boolean isConstructorCalled;
-    public boolean isOnConfigurationChangedCalled;
-    public boolean isOnLowMemoryCalled;
-
-    public MockApplication() {
-        super();
-        isConstructorCalled = true;
-    }
-
-    @Override
-    public void onCreate() {
-        super.onCreate();
-        isOnCreateCalled = true;
-    }
-
-    @Override
-    public void onTerminate() {
-        super.onTerminate();
-        // The documentation states that one cannot rely on this method being called. No need to
-        // test it here.
-    }
-
-    @Override
-    public void onConfigurationChanged(Configuration newConfig) {
-        super.onConfigurationChanged(newConfig);
-        isOnConfigurationChangedCalled = true;
-    }
-
-    @Override
-    public void onLowMemory() {
-        super.onLowMemory();
-        isOnLowMemoryCalled = true;
-    }
-}
diff --git a/tests/app/src/android/app/cts/MockApplicationActivity.java b/tests/app/src/android/app/cts/MockApplicationActivity.java
deleted file mode 100644
index 40299ee..0000000
--- a/tests/app/src/android/app/cts/MockApplicationActivity.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.widget.TextView;
-
-public class MockApplicationActivity extends Activity {
-
-    @Override
-    public void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-        TextView textView = new TextView(this);
-        textView.setText("Test");
-        setContentView(textView);
-    }
-
-}
diff --git a/tests/app/src/android/app/cts/MockReceiver.java b/tests/app/src/android/app/cts/MockReceiver.java
deleted file mode 100644
index d102cbe..0000000
--- a/tests/app/src/android/app/cts/MockReceiver.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-
-public class MockReceiver extends BroadcastReceiver {
-
-    // PendingIntent may return same instance or new instance, so static variable is needed.
-    public static int sResultCode = 0;
-    public static final String MOCKACTION = "android.app.PendingIntentTest.TEST_RECEIVER";
-    public static String sAction;
-
-    /**
-     * set the result as true when received alarm
-     */
-    @Override
-    public void onReceive(Context context, Intent intent) {
-        sAction = intent.getAction();
-        if (sAction.equals(MOCKACTION)) {
-            sResultCode = getResultCode();
-        }
-    }
-}
-
diff --git a/tests/app/src/android/app/cts/MockService.java b/tests/app/src/android/app/cts/MockService.java
deleted file mode 100644
index 510e731..0000000
--- a/tests/app/src/android/app/cts/MockService.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-import android.app.Service;
-import android.content.Intent;
-import android.os.Binder;
-import android.os.IBinder;
-
-public class MockService extends Service {
-    public static boolean result = false;
-    private final IBinder mBinder = new MockBinder();
-
-    public class MockBinder extends Binder {
-        MockService getService() {
-            return MockService.this;
-        }
-    }
-
-    /**
-     * set the result as true when service bind
-     */
-    @Override
-    public IBinder onBind(Intent intent) {
-        result = true;
-        return mBinder;
-    }
-
-    /**
-     * set the result as true when service start
-     */
-    @Override
-    public void onStart(Intent intent, int startId) {
-        super.onStart(intent, startId);
-        result = true;
-    }
-}
-
diff --git a/tests/app/src/android/app/cts/MockTabActivity.java b/tests/app/src/android/app/cts/MockTabActivity.java
deleted file mode 100644
index aca19f5..0000000
--- a/tests/app/src/android/app/cts/MockTabActivity.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-import android.app.Activity;
-import android.app.TabActivity;
-import android.content.Intent;
-import android.os.Bundle;
-import android.widget.TabHost;
-
-public class MockTabActivity extends TabActivity {
-
-    private static final String TAB1 = "tab1";
-    private static final String TAB2 = "tab2";
-    private static final String TAB3 = "tab3";
-
-    public boolean isOnChildTitleChangedCalled;
-    public boolean isOnPostCreateCalled;
-    public boolean isOnSaveInstanceStateCalled;
-    public boolean isOnContentChangedCalled;
-    public static boolean isOnRestoreInstanceStateCalled;
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        final TabHost tabHost = getTabHost();
-
-        tabHost.addTab(tabHost.newTabSpec(TAB1).setIndicator(TAB1)
-                .setContent(new Intent(this, ChildTabActivity.class)));
-
-        tabHost.addTab(tabHost.newTabSpec(TAB2).setIndicator(TAB2)
-                .setContent(new Intent(this, MockActivity.class)));
-
-        tabHost.addTab(tabHost.newTabSpec(TAB3).setIndicator(TAB3).setContent(
-                new Intent(this, AppStubActivity.class).addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)));
-
-    }
-
-    @Override
-    protected void onChildTitleChanged(Activity childActivity, CharSequence title) {
-        super.onChildTitleChanged(childActivity, title);
-        isOnChildTitleChangedCalled = true;
-    }
-
-    @Override
-    protected void onPostCreate(Bundle icicle) {
-        super.onPostCreate(icicle);
-        isOnPostCreateCalled = true;
-    }
-
-    @Override
-    protected void onRestoreInstanceState(Bundle state) {
-        super.onRestoreInstanceState(state);
-        isOnRestoreInstanceStateCalled = true;
-    }
-
-    @Override
-    protected void onSaveInstanceState(Bundle outState) {
-        super.onSaveInstanceState(outState);
-        isOnSaveInstanceStateCalled = true;
-    }
-
-    @Override
-    public void onContentChanged() {
-        super.onContentChanged();
-        isOnContentChangedCalled = true;
-    }
-}
diff --git a/tests/app/src/android/app/cts/NotificationManagerTest.java b/tests/app/src/android/app/cts/NotificationManagerTest.java
new file mode 100644
index 0000000..c4cbaee
--- /dev/null
+++ b/tests/app/src/android/app/cts/NotificationManagerTest.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.cts;
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+import android.provider.Telephony.Threads;
+import android.service.notification.StatusBarNotification;
+import android.test.AndroidTestCase;
+import android.util.Log;
+
+import android.app.stubs.R;
+
+public class NotificationManagerTest extends AndroidTestCase {
+    final String TAG = NotificationManagerTest.class.getSimpleName();
+    final boolean DEBUG = false;
+
+    private NotificationManager mNotificationManager;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mNotificationManager = (NotificationManager) mContext.getSystemService(
+                Context.NOTIFICATION_SERVICE);
+        // clear the deck so that our getActiveNotifications results are predictable
+        mNotificationManager.cancelAll();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+        mNotificationManager.cancelAll();
+    }
+
+    public void testNotify() {
+        mNotificationManager.cancelAll();
+
+        final int id = 1;
+        sendNotification(id, R.drawable.black);
+        // test updating the same notification
+        sendNotification(id, R.drawable.blue);
+        sendNotification(id, R.drawable.yellow);
+
+        // assume that sendNotification tested to make sure individual notifications were present
+        StatusBarNotification[] sbns = mNotificationManager.getActiveNotifications();
+        for (StatusBarNotification sbn : sbns) {
+            if (sbn.getId() != id) {
+                fail("we got back other notifications besides the one we posted: "
+                        + sbn.getKey());
+            }
+        }
+    }
+
+    public void testCancel() {
+        final int id = 9;
+        sendNotification(id, R.drawable.black);
+        mNotificationManager.cancel(id);
+
+        if (!checkNotificationExistence(id, /*shouldExist=*/ false)) {
+            fail("canceled notification was still alive, id=" + id);
+        }
+    }
+
+    public void testCancelAll() {
+        sendNotification(1, R.drawable.black);
+        sendNotification(2, R.drawable.blue);
+        sendNotification(3, R.drawable.yellow);
+
+        if (DEBUG) {
+            Log.d(TAG, "posted 3 notifications, here they are: ");
+            StatusBarNotification[] sbns = mNotificationManager.getActiveNotifications();
+            for (StatusBarNotification sbn : sbns) {
+                Log.d(TAG, "  " + sbn);
+            }
+            Log.d(TAG, "about to cancel...");
+        }
+        mNotificationManager.cancelAll();
+
+        StatusBarNotification[] sbns = mNotificationManager.getActiveNotifications();
+        assertTrue("notification list was not empty after cancelAll", sbns.length == 0);
+    }
+
+    private void sendNotification(final int id, final int icon) {
+        final Intent intent = new Intent(Intent.ACTION_MAIN, Threads.CONTENT_URI);
+
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP
+                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+        intent.setAction(Intent.ACTION_MAIN);
+
+        final PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, intent, 0);
+        final Notification notification = new Notification.Builder(mContext)
+                .setSmallIcon(icon)
+                .setWhen(System.currentTimeMillis())
+                .setContentTitle("notify#" + id)
+                .setContentText("This is #" + id + "notification  ")
+                .setContentIntent(pendingIntent)
+                .build();
+        mNotificationManager.notify(id, notification);
+
+
+        if (!checkNotificationExistence(id, /*shouldExist=*/ true)) {
+            fail("couldn't find posted notification id=" + id);
+        }
+    }
+
+    private boolean checkNotificationExistence(int id, boolean shouldExist) {
+        // notification is a bit asynchronous so it may take a few ms to appear in getActiveNotifications()
+        // we will check for it for up to 200ms before giving up
+        boolean found = false;
+        for (int tries=3; tries-->0;) {
+            // Need reset flag.
+            found = false;
+            final StatusBarNotification[] sbns = mNotificationManager.getActiveNotifications();
+            for (StatusBarNotification sbn : sbns) {
+                if (sbn.getId() == id) {
+                    found = true;
+                    break;
+                }
+            }
+            if (found == shouldExist) break;
+            try {
+                Thread.sleep(100);
+            } catch (InterruptedException ex) {
+                // pass
+            }
+        }
+        return found == shouldExist;
+    }
+}
diff --git a/tests/app/src/android/app/cts/NotificationTest.java b/tests/app/src/android/app/cts/NotificationTest.java
new file mode 100644
index 0000000..42a158e
--- /dev/null
+++ b/tests/app/src/android/app/cts/NotificationTest.java
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.cts;
+
+import android.app.Notification;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Parcel;
+import android.test.AndroidTestCase;
+import android.widget.RemoteViews;
+
+public class NotificationTest extends AndroidTestCase {
+
+    private Notification mNotification;
+    private Context mContext;
+
+    private static final String TICKER_TEXT = "tickerText";
+    private static final String CONTENT_TITLE = "contentTitle";
+    private static final String CONTENT_TEXT = "contentText";
+    private static final String URI_STRING = "uriString";
+    private static final int TOLERANCE = 200;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mContext = getContext();
+        mNotification = new Notification();
+    }
+
+    public void testConstructor() {
+        mNotification = null;
+        mNotification = new Notification();
+        assertNotNull(mNotification);
+        assertTrue(System.currentTimeMillis() - mNotification.when < TOLERANCE);
+
+        mNotification = null;
+        final int notificationTime = 200;
+        mNotification = new Notification(0, TICKER_TEXT, notificationTime);
+        assertEquals(notificationTime, mNotification.when);
+        assertEquals(0, mNotification.icon);
+        assertEquals(TICKER_TEXT, mNotification.tickerText);
+    }
+
+    public void testDescribeContents() {
+        final int expected = 0;
+        mNotification = new Notification();
+        assertEquals(expected, mNotification.describeContents());
+    }
+
+    public void testWriteToParcel() {
+        mNotification = new Notification();
+        mNotification.icon = 0;
+        mNotification.number = 1;
+        final Intent intent = new Intent();
+        final PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0);
+        mNotification.contentIntent = pendingIntent;
+        final Intent deleteIntent = new Intent();
+        final PendingIntent delPendingIntent = PendingIntent.getBroadcast(
+                mContext, 0, deleteIntent, 0);
+        mNotification.deleteIntent = delPendingIntent;
+        mNotification.tickerText = TICKER_TEXT;
+
+        final RemoteViews contentView = new RemoteViews(mContext.getPackageName(),
+                android.R.layout.simple_list_item_1);
+        mNotification.contentView = contentView;
+        mNotification.defaults = 0;
+        mNotification.flags = 0;
+        final Uri uri = Uri.parse(URI_STRING);
+        mNotification.sound = uri;
+        mNotification.audioStreamType = 0;
+        final long[] longArray = { 1l, 2l, 3l };
+        mNotification.vibrate = longArray;
+        mNotification.ledARGB = 0;
+        mNotification.ledOnMS = 0;
+        mNotification.ledOffMS = 0;
+        mNotification.iconLevel = 0;
+        Parcel parcel = Parcel.obtain();
+        mNotification.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        // Test Notification(Parcel)
+        Notification result = new Notification(parcel);
+        assertEquals(mNotification.icon, result.icon);
+        assertEquals(mNotification.when, result.when);
+        assertEquals(mNotification.number, result.number);
+        assertNotNull(result.contentIntent);
+        assertNotNull(result.deleteIntent);
+        assertEquals(mNotification.tickerText, result.tickerText);
+        assertNotNull(result.contentView);
+        assertEquals(mNotification.defaults, result.defaults);
+        assertEquals(mNotification.flags, result.flags);
+        assertNotNull(result.sound);
+        assertEquals(mNotification.audioStreamType, result.audioStreamType);
+        assertEquals(mNotification.vibrate[0], result.vibrate[0]);
+        assertEquals(mNotification.vibrate[1], result.vibrate[1]);
+        assertEquals(mNotification.vibrate[2], result.vibrate[2]);
+        assertEquals(mNotification.ledARGB, result.ledARGB);
+        assertEquals(mNotification.ledOnMS, result.ledOnMS);
+        assertEquals(mNotification.ledOffMS, result.ledOffMS);
+        assertEquals(mNotification.iconLevel, result.iconLevel);
+
+        mNotification.contentIntent = null;
+        parcel = Parcel.obtain();
+        mNotification.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        result = new Notification(parcel);
+        assertNull(result.contentIntent);
+
+        mNotification.deleteIntent = null;
+        parcel = Parcel.obtain();
+        mNotification.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        result = new Notification(parcel);
+        assertNull(result.deleteIntent);
+
+        mNotification.tickerText = null;
+        parcel = Parcel.obtain();
+        mNotification.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        result = new Notification(parcel);
+        assertNull(result.tickerText);
+
+        mNotification.contentView = null;
+        parcel = Parcel.obtain();
+        mNotification.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        result = new Notification(parcel);
+        assertNull(result.contentView);
+
+        mNotification.sound = null;
+        parcel = Parcel.obtain();
+        mNotification.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        result = new Notification(parcel);
+        assertNull(result.sound);
+    }
+
+    public void testBuilder() {
+        final Intent intent = new Intent();
+        final PendingIntent contentIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0);
+        mNotification = new Notification.Builder(mContext)
+                .setSmallIcon(1)
+                .setContentTitle(CONTENT_TITLE)
+                .setContentText(CONTENT_TEXT)
+                .setContentIntent(contentIntent)
+                .build();
+        assertEquals(CONTENT_TEXT, mNotification.extras.getString(Notification.EXTRA_TEXT));
+        assertEquals(CONTENT_TITLE, mNotification.extras.getString(Notification.EXTRA_TITLE));
+        assertEquals(1, mNotification.icon);
+        assertEquals(contentIntent, mNotification.contentIntent);
+    }
+
+    public void testToString() {
+        mNotification = new Notification();
+        assertNotNull(mNotification.toString());
+    }
+}
diff --git a/tests/app/src/android/app/cts/OrientationTestUtils.java b/tests/app/src/android/app/cts/OrientationTestUtils.java
deleted file mode 100644
index 7b2b568..0000000
--- a/tests/app/src/android/app/cts/OrientationTestUtils.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-import android.app.Activity;
-import android.app.Instrumentation;
-import android.content.pm.ActivityInfo;
-
-public class OrientationTestUtils {
-
-    /**
-     * Change the activity's orientation to something different and then switch back. This is used
-     * to trigger {@link Activity#onConfigurationChanged(android.content.res.Configuration)}.
-     *
-     * @param activity whose orientation will be changed and restored
-     */
-    public static void toggleOrientation(Activity activity) {
-        toggleOrientationSync(activity, null);
-    }
-
-    /**
-     * Same as {@link #toggleOrientation(Activity)} except {@link Instrumentation#waitForIdleSync()}
-     * is called after each orientation change.
-     *
-     * @param activity whose orientation will be changed and restored
-     * @param instrumentation use for idle syncing
-     */
-    public static void toggleOrientationSync(final Activity activity,
-            final Instrumentation instrumentation) {
-        final int originalOrientation = activity.getResources().getConfiguration().orientation;
-        final int newOrientation = originalOrientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
-                ? ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
-                : ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
-        changeOrientation(activity, instrumentation, newOrientation);
-        changeOrientation(activity, instrumentation, originalOrientation);
-    }
-
-    private static void changeOrientation(final Activity activity,
-            Instrumentation instrumentation, final int orientation) {
-        activity.setRequestedOrientation(orientation);
-        if (instrumentation != null) {
-            instrumentation.waitForIdleSync();
-        }
-    }
-}
diff --git a/tests/app/src/android/app/cts/PendingIntentStubActivity.java b/tests/app/src/android/app/cts/PendingIntentStubActivity.java
deleted file mode 100644
index a2a3bd8..0000000
--- a/tests/app/src/android/app/cts/PendingIntentStubActivity.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-import android.app.Activity;
-import android.os.Bundle;
-
-public class PendingIntentStubActivity extends Activity {
-
-    public static final int INVALIDATE = -1;
-    public static final int ON_CREATE = 0;
-    public static int status = INVALIDATE;
-
-    @Override
-    public void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-        status = ON_CREATE;
-    }
-
-}
diff --git a/tests/app/src/android/app/cts/PendingIntentTest.java b/tests/app/src/android/app/cts/PendingIntentTest.java
new file mode 100644
index 0000000..697de72
--- /dev/null
+++ b/tests/app/src/android/app/cts/PendingIntentTest.java
@@ -0,0 +1,456 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.cts;
+
+import android.app.PendingIntent;
+import android.app.PendingIntent.CanceledException;
+import android.app.stubs.MockReceiver;
+import android.app.stubs.MockService;
+import android.app.stubs.PendingIntentStubActivity;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.Parcel;
+import android.test.AndroidTestCase;
+
+public class PendingIntentTest extends AndroidTestCase {
+
+    private static final int WAIT_TIME = 5000;
+    private PendingIntent mPendingIntent;
+    private Intent mIntent;
+    private Context mContext;
+    private boolean mFinishResult;
+    private boolean mHandleResult;
+    private String mResultAction;
+    private PendingIntent.OnFinished mFinish;
+    private boolean mLooperStart;
+    private Looper mLooper;
+    private Handler mHandler;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mContext = getContext();
+        mFinish = new PendingIntent.OnFinished() {
+            public void onSendFinished(PendingIntent pi, Intent intent, int resultCode,
+                    String resultData, Bundle resultExtras) {
+                mFinishResult = true;
+                if (intent != null) {
+                    mResultAction = intent.getAction();
+                }
+            }
+        };
+
+        new Thread() {
+            @Override
+            public void run() {
+                Looper.prepare();
+                mLooper = Looper.myLooper();
+                mLooperStart = true;
+                Looper.loop();
+            }
+        }.start();
+        while (!mLooperStart) {
+            Thread.sleep(50);
+        }
+        mHandler = new Handler(mLooper) {
+            @Override
+            public void dispatchMessage(Message msg) {
+                mHandleResult = true;
+                super.dispatchMessage(msg);
+            }
+
+            @Override
+            public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
+                mHandleResult = true;
+                return super.sendMessageAtTime(msg, uptimeMillis);
+            }
+
+            @Override
+            public void handleMessage(Message msg) {
+                super.handleMessage(msg);
+                mHandleResult = true;
+            }
+        };
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+        mLooper.quit();
+    }
+
+    public void testGetActivity() throws InterruptedException, CanceledException {
+        PendingIntentStubActivity.status = PendingIntentStubActivity.INVALIDATE;
+        mPendingIntent = null;
+        mIntent = new Intent();
+
+        mIntent.setClass(mContext, PendingIntentStubActivity.class);
+        mIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        mPendingIntent = PendingIntent.getActivity(mContext, 1, mIntent,
+                PendingIntent.FLAG_CANCEL_CURRENT);
+        assertEquals(mContext.getPackageName(), mPendingIntent.getTargetPackage());
+
+        mPendingIntent.send();
+
+        Thread.sleep(WAIT_TIME);
+        assertNotNull(mPendingIntent);
+        assertEquals(PendingIntentStubActivity.status, PendingIntentStubActivity.ON_CREATE);
+
+        // test getActivity return null
+        mPendingIntent.cancel();
+        mPendingIntent = PendingIntent.getActivity(mContext, 1, mIntent,
+                PendingIntent.FLAG_NO_CREATE);
+        assertNull(mPendingIntent);
+
+        mPendingIntent = PendingIntent.getActivity(mContext, 1, mIntent,
+                PendingIntent.FLAG_ONE_SHOT);
+
+        pendingIntentSendError(mPendingIntent);
+    }
+
+    private void pendingIntentSendError(PendingIntent pendingIntent) {
+        try {
+            // From the doc send function will throw CanceledException if the PendingIntent
+            // is no longer allowing more intents to be sent through it. So here call it twice then
+            // a CanceledException should be caught.
+            mPendingIntent.send();
+            mPendingIntent.send();
+            fail("CanceledException expected, but not thrown");
+        } catch (PendingIntent.CanceledException e) {
+            // expected
+        }
+    }
+
+    public void testGetBroadcast() throws InterruptedException, CanceledException {
+        MockReceiver.sAction = null;
+        mIntent = new Intent(MockReceiver.MOCKACTION);
+        mIntent.setClass(mContext, MockReceiver.class);
+        mPendingIntent = PendingIntent.getBroadcast(mContext, 1, mIntent,
+                PendingIntent.FLAG_CANCEL_CURRENT);
+
+        mPendingIntent.send();
+
+        Thread.sleep(WAIT_TIME);
+        assertEquals(MockReceiver.MOCKACTION, MockReceiver.sAction);
+
+        // test getBroadcast return null
+        mPendingIntent.cancel();
+        mPendingIntent = PendingIntent.getBroadcast(mContext, 1, mIntent,
+                PendingIntent.FLAG_NO_CREATE);
+        assertNull(mPendingIntent);
+
+        mPendingIntent = PendingIntent.getBroadcast(mContext, 1, mIntent,
+                PendingIntent.FLAG_ONE_SHOT);
+
+        pendingIntentSendError(mPendingIntent);
+    }
+
+    public void testGetService() throws InterruptedException, CanceledException {
+        MockService.result = false;
+        mIntent = new Intent();
+        mIntent.setClass(mContext, MockService.class);
+        mPendingIntent = PendingIntent.getService(mContext, 1, mIntent,
+                PendingIntent.FLAG_CANCEL_CURRENT);
+
+        mPendingIntent.send();
+
+        Thread.sleep(WAIT_TIME);
+        assertTrue(MockService.result);
+
+        // test getService return null
+        mPendingIntent.cancel();
+        mPendingIntent = PendingIntent.getService(mContext, 1, mIntent,
+                PendingIntent.FLAG_NO_CREATE);
+        assertNull(mPendingIntent);
+
+        mPendingIntent = PendingIntent.getService(mContext, 1, mIntent,
+                PendingIntent.FLAG_ONE_SHOT);
+
+        pendingIntentSendError(mPendingIntent);
+    }
+
+    public void testCancel() throws CanceledException {
+        mIntent = new Intent();
+        mIntent.setClass(mContext, MockService.class);
+        mPendingIntent = PendingIntent.getBroadcast(mContext, 1, mIntent,
+                PendingIntent.FLAG_CANCEL_CURRENT);
+
+        mPendingIntent.send();
+
+        mPendingIntent.cancel();
+        pendingIntentSendShouldFail(mPendingIntent);
+    }
+
+    private void pendingIntentSendShouldFail(PendingIntent pendingIntent) {
+        try {
+            pendingIntent.send();
+            fail("CanceledException expected, but not thrown");
+        } catch (CanceledException e) {
+            // expected
+        }
+    }
+
+    public void testSend() throws InterruptedException, CanceledException {
+        MockReceiver.sAction = null;
+        MockReceiver.sResultCode = -1;
+        mIntent = new Intent();
+        mIntent.setAction(MockReceiver.MOCKACTION);
+        mIntent.setClass(mContext, MockReceiver.class);
+        mPendingIntent = PendingIntent.getBroadcast(mContext, 1, mIntent,
+                PendingIntent.FLAG_CANCEL_CURRENT);
+
+        mPendingIntent.send();
+
+        Thread.sleep(WAIT_TIME);
+
+        // send function to send default code 0
+        assertEquals(0, MockReceiver.sResultCode);
+        assertEquals(MockReceiver.MOCKACTION, MockReceiver.sAction);
+        mPendingIntent.cancel();
+
+        pendingIntentSendShouldFail(mPendingIntent);
+    }
+
+    public void testSendWithParamInt() throws InterruptedException, CanceledException {
+        mIntent = new Intent(MockReceiver.MOCKACTION);
+        mIntent.setClass(mContext, MockReceiver.class);
+        mPendingIntent = PendingIntent.getBroadcast(mContext, 1, mIntent,
+                PendingIntent.FLAG_CANCEL_CURRENT);
+        MockReceiver.sResultCode = 0;
+        MockReceiver.sAction = null;
+        // send result code 1.
+        mPendingIntent.send(1);
+        Thread.sleep(WAIT_TIME);
+        assertEquals(MockReceiver.MOCKACTION, MockReceiver.sAction);
+
+        // assert the result code
+        assertEquals(1, MockReceiver.sResultCode);
+        assertEquals(mResultAction, null);
+
+        mResultAction = null;
+        MockReceiver.sResultCode = 0;
+        // send result code 2
+        mPendingIntent.send(2);
+        Thread.sleep(WAIT_TIME);
+
+        assertEquals(MockReceiver.MOCKACTION, MockReceiver.sAction);
+
+        // assert the result code
+        assertEquals(2, MockReceiver.sResultCode);
+        assertEquals(MockReceiver.sAction, MockReceiver.MOCKACTION);
+        assertNull(mResultAction);
+        mPendingIntent.cancel();
+        pendingIntentSendShouldFail(mPendingIntent);
+    }
+
+    public void testSendWithParamContextIntIntent() throws InterruptedException, CanceledException {
+        mIntent = new Intent(MockReceiver.MOCKACTION);
+        mIntent.setClass(mContext, MockReceiver.class);
+
+        MockReceiver.sAction = null;
+        MockReceiver.sResultCode = 0;
+
+        mPendingIntent = PendingIntent.getBroadcast(mContext, 1, mIntent, 1);
+
+        mPendingIntent.send(mContext, 1, null);
+        Thread.sleep(WAIT_TIME);
+
+        assertEquals(MockReceiver.MOCKACTION, MockReceiver.sAction);
+        assertEquals(1, MockReceiver.sResultCode);
+        mPendingIntent.cancel();
+
+        mPendingIntent = PendingIntent.getBroadcast(mContext, 1, mIntent, 1);
+        MockReceiver.sAction = null;
+        MockReceiver.sResultCode = 0;
+
+        mPendingIntent.send(mContext, 2, mIntent);
+        Thread.sleep(WAIT_TIME);
+        assertEquals(MockReceiver.MOCKACTION, MockReceiver.sAction);
+        assertEquals(2, MockReceiver.sResultCode);
+        mPendingIntent.cancel();
+    }
+
+    public void testSendWithParamIntOnFinishedHandler() throws InterruptedException,
+            CanceledException {
+        mIntent = new Intent(MockReceiver.MOCKACTION);
+        mIntent.setClass(mContext, MockReceiver.class);
+
+        mPendingIntent = PendingIntent.getBroadcast(mContext, 1, mIntent, 1);
+        mFinishResult = false;
+        mHandleResult = false;
+        MockReceiver.sAction = null;
+        MockReceiver.sResultCode = 0;
+
+        mPendingIntent.send(1, null, null);
+        Thread.sleep(WAIT_TIME);
+        assertFalse(mFinishResult);
+        assertFalse(mHandleResult);
+        assertEquals(MockReceiver.MOCKACTION, MockReceiver.sAction);
+
+        // assert result code
+        assertEquals(1, MockReceiver.sResultCode);
+        mPendingIntent.cancel();
+
+        mPendingIntent = PendingIntent.getBroadcast(mContext, 1, mIntent, 1);
+        mFinishResult = false;
+        MockReceiver.sAction = null;
+        MockReceiver.sResultCode = 0;
+        mHandleResult = false;
+
+        mPendingIntent.send(2, mFinish, null);
+        Thread.sleep(WAIT_TIME);
+        assertTrue(mFinishResult);
+        assertFalse(mHandleResult);
+        assertEquals(MockReceiver.MOCKACTION, MockReceiver.sAction);
+
+        // assert result code
+        assertEquals(2, MockReceiver.sResultCode);
+        mPendingIntent.cancel();
+
+        mHandleResult = false;
+        mFinishResult = false;
+        mPendingIntent = PendingIntent.getBroadcast(mContext, 1, mIntent, 1);
+        MockReceiver.sAction = null;
+        mPendingIntent.send(3, mFinish, mHandler);
+        Thread.sleep(WAIT_TIME);
+        assertTrue(mHandleResult);
+        assertTrue(mFinishResult);
+        assertEquals(MockReceiver.MOCKACTION, MockReceiver.sAction);
+
+        // assert result code
+        assertEquals(3, MockReceiver.sResultCode);
+        mPendingIntent.cancel();
+    }
+
+    public void testSendWithParamContextIntIntentOnFinishedHandler() throws InterruptedException,
+            CanceledException {
+        mIntent = new Intent(MockReceiver.MOCKACTION);
+        mIntent.setAction(MockReceiver.MOCKACTION);
+
+        mPendingIntent = PendingIntent.getBroadcast(mContext, 1, mIntent, 1);
+        mFinishResult = false;
+        mResultAction = null;
+        mHandleResult = false;
+        mPendingIntent.send(mContext, 1, mIntent, null, null);
+        Thread.sleep(WAIT_TIME);
+        assertFalse(mFinishResult);
+        assertFalse(mHandleResult);
+        assertNull(mResultAction);
+        mPendingIntent.cancel();
+
+        mPendingIntent = PendingIntent.getBroadcast(mContext, 1, mIntent, 1);
+        mFinishResult = false;
+        mResultAction = null;
+        mHandleResult = false;
+        mPendingIntent.send(mContext, 1, mIntent, mFinish, null);
+        Thread.sleep(WAIT_TIME);
+        assertTrue(mFinishResult);
+        assertEquals(mResultAction, MockReceiver.MOCKACTION);
+        assertFalse(mHandleResult);
+        mPendingIntent.cancel();
+
+        mPendingIntent = PendingIntent.getBroadcast(mContext, 1, mIntent, 1);
+        mFinishResult = false;
+        mResultAction = null;
+        mHandleResult = false;
+        mPendingIntent.send(mContext, 1, mIntent, mFinish, mHandler);
+        Thread.sleep(WAIT_TIME);
+        assertTrue(mHandleResult);
+        assertEquals(mResultAction, MockReceiver.MOCKACTION);
+        assertTrue(mFinishResult);
+        mPendingIntent.cancel();
+    }
+
+    public void testGetTargetPackage() {
+        mIntent = new Intent();
+        mPendingIntent = PendingIntent.getActivity(mContext, 1, mIntent,
+                PendingIntent.FLAG_CANCEL_CURRENT);
+        assertEquals(mContext.getPackageName(), mPendingIntent.getTargetPackage());
+    }
+
+    public void testEquals() {
+        mIntent = new Intent();
+        mPendingIntent = PendingIntent.getActivity(mContext, 1, mIntent,
+                PendingIntent.FLAG_CANCEL_CURRENT);
+
+        PendingIntent target = PendingIntent.getActivity(mContext, 1, mIntent,
+                PendingIntent.FLAG_CANCEL_CURRENT);
+
+        assertFalse(mPendingIntent.equals(target));
+        assertFalse(mPendingIntent.hashCode() == target.hashCode());
+        mPendingIntent = PendingIntent.getActivity(mContext, 1, mIntent, 1);
+
+        target = PendingIntent.getActivity(mContext, 1, mIntent, 1);
+        assertTrue(mPendingIntent.equals(target));
+
+        mIntent = new Intent(MockReceiver.MOCKACTION);
+        target = PendingIntent.getBroadcast(mContext, 1, mIntent, 1);
+        assertFalse(mPendingIntent.equals(target));
+        assertFalse(mPendingIntent.hashCode() == target.hashCode());
+
+        mPendingIntent = PendingIntent.getActivity(mContext, 1, mIntent, 1);
+        target = PendingIntent.getActivity(mContext, 1, mIntent, 1);
+
+        assertTrue(mPendingIntent.equals(target));
+        assertEquals(mPendingIntent.hashCode(), target.hashCode());
+    }
+
+    public void testDescribeContents() {
+        mIntent = new Intent();
+        mPendingIntent = PendingIntent.getActivity(mContext, 1, mIntent,
+                PendingIntent.FLAG_CANCEL_CURRENT);
+        final int expected = 0;
+        assertEquals(expected, mPendingIntent.describeContents());
+    }
+
+    public void testWriteToParcel() {
+        mIntent = new Intent();
+        mPendingIntent = PendingIntent.getActivity(mContext, 1, mIntent,
+                PendingIntent.FLAG_CANCEL_CURRENT);
+        Parcel parcel = Parcel.obtain();
+
+        mPendingIntent.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        PendingIntent pendingIntent = PendingIntent.CREATOR.createFromParcel(parcel);
+        assertTrue(mPendingIntent.equals(pendingIntent));
+    }
+
+    public void testReadAndWritePendingIntentOrNullToParcel() {
+        mIntent = new Intent();
+        mPendingIntent = PendingIntent.getActivity(mContext, 1, mIntent,
+                PendingIntent.FLAG_CANCEL_CURRENT);
+        assertNotNull(mPendingIntent.toString());
+
+        Parcel parcel = Parcel.obtain();
+        PendingIntent.writePendingIntentOrNullToParcel(mPendingIntent, parcel);
+        parcel.setDataPosition(0);
+        PendingIntent target = PendingIntent.readPendingIntentOrNullFromParcel(parcel);
+        assertEquals(mPendingIntent, target);
+        assertEquals(mPendingIntent.getTargetPackage(), target.getTargetPackage());
+
+        mPendingIntent = null;
+        parcel = Parcel.obtain();
+        PendingIntent.writePendingIntentOrNullToParcel(mPendingIntent, parcel);
+        target = PendingIntent.readPendingIntentOrNullFromParcel(parcel);
+        assertNull(target);
+    }
+
+}
diff --git a/tests/tests/app/src/android/app/cts/PendingIntent_CanceledExceptionTest.java b/tests/app/src/android/app/cts/PendingIntent_CanceledExceptionTest.java
similarity index 100%
rename from tests/tests/app/src/android/app/cts/PendingIntent_CanceledExceptionTest.java
rename to tests/app/src/android/app/cts/PendingIntent_CanceledExceptionTest.java
diff --git a/tests/app/src/android/app/cts/PipActivityTest.java b/tests/app/src/android/app/cts/PipActivityTest.java
new file mode 100644
index 0000000..a8cfc90
--- /dev/null
+++ b/tests/app/src/android/app/cts/PipActivityTest.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.cts;
+
+import android.app.Instrumentation;
+import android.app.stubs.PipActivity;
+import android.test.ActivityInstrumentationTestCase2;
+
+import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
+
+public class PipActivityTest extends ActivityInstrumentationTestCase2<PipActivity> {
+
+    private Instrumentation mInstrumentation;
+    private PipActivity mActivity;
+
+    public PipActivityTest() {
+        super("android.app.stubs", PipActivity.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mInstrumentation = getInstrumentation();
+        mActivity = getActivity();
+    }
+
+    public void testLaunchPipActivity() throws Throwable {
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                final boolean supportsPip =
+                        mActivity.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
+                if (supportsPip) {
+                    mActivity.enterPictureInPictureMode();
+
+                    // Entering PIP mode is not synchronous, so waiting for completion of all work
+                    // on UI thread.
+                    mInstrumentation.waitForIdle(new Runnable() {
+                        @Override
+                        public void run() {
+                            assertTrue(mActivity.isInMultiWindowMode());
+                            assertTrue(mActivity.isInPictureInPictureMode());
+                        }
+                    });
+                } else {
+                    boolean pipSupportDisabled = false;
+                    try {
+                        mActivity.enterPictureInPictureMode();
+                    } catch (IllegalStateException e) {
+                        // Pip not supported
+                        pipSupportDisabled = true;
+                    }
+                    assertTrue(pipSupportDisabled);
+
+                    // Entering PIP mode is not synchronous, so waiting for completion of all work
+                    // on UI thread.
+                    mInstrumentation.waitForIdle(new Runnable() {
+                        @Override
+                        public void run() {
+                            assertFalse(mActivity.isInMultiWindowMode());
+                            assertFalse(mActivity.isInPictureInPictureMode());
+                        }
+                    });
+                }
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+    }
+}
diff --git a/tests/app/src/android/app/cts/PipNotResizeableActivityTest.java b/tests/app/src/android/app/cts/PipNotResizeableActivityTest.java
new file mode 100644
index 0000000..7189dc1
--- /dev/null
+++ b/tests/app/src/android/app/cts/PipNotResizeableActivityTest.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.cts;
+
+import android.app.Instrumentation;
+import android.app.stubs.PipNotResizeableActivity;
+import android.test.ActivityInstrumentationTestCase2;
+
+public class PipNotResizeableActivityTest
+        extends ActivityInstrumentationTestCase2<PipNotResizeableActivity> {
+
+        private Instrumentation mInstrumentation;
+        private PipNotResizeableActivity mActivity;
+
+        public PipNotResizeableActivityTest() {
+            super("android.app.stubs", PipNotResizeableActivity.class);
+        }
+
+        @Override
+        protected void setUp() throws Exception {
+            super.setUp();
+            mInstrumentation = getInstrumentation();
+            mActivity = getActivity();
+        }
+
+        public void testLaunchPipNotResizeableActivity() throws Throwable {
+            runTestOnUiThread(new Runnable() {
+                public void run() {
+                    boolean pipSupportDisabled = false;
+                    try {
+                        mActivity.enterPictureInPictureMode();
+                    } catch (IllegalStateException e) {
+                        // Pip not supported
+                        pipSupportDisabled = true;
+                    } catch (IllegalArgumentException e) {
+                        // Pip not supported
+                        pipSupportDisabled = true;
+                    }
+                    assertTrue(pipSupportDisabled);
+                    assertFalse(mActivity.isInMultiWindowMode());
+                    assertFalse(mActivity.isInPictureInPictureMode());
+                }
+            });
+            mInstrumentation.waitForIdleSync();
+        }
+    }
diff --git a/tests/app/src/android/app/cts/PipNotSupportedActivityTest.java b/tests/app/src/android/app/cts/PipNotSupportedActivityTest.java
new file mode 100644
index 0000000..e8d13dc
--- /dev/null
+++ b/tests/app/src/android/app/cts/PipNotSupportedActivityTest.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.cts;
+
+import android.app.Instrumentation;
+import android.app.stubs.PipNotSupportedActivity;
+import android.test.ActivityInstrumentationTestCase2;
+
+public class PipNotSupportedActivityTest
+        extends ActivityInstrumentationTestCase2<PipNotSupportedActivity> {
+
+    private Instrumentation mInstrumentation;
+    private PipNotSupportedActivity mActivity;
+
+    public PipNotSupportedActivityTest() {
+        super("android.app.stubs", PipNotSupportedActivity.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mInstrumentation = getInstrumentation();
+        mActivity = getActivity();
+    }
+
+    public void testLaunchPipNotSupportedActivity() throws Throwable {
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                boolean pipSupportDisabled = false;
+                try {
+                    mActivity.enterPictureInPictureMode();
+                } catch (IllegalStateException e) {
+                    // Pip not supported
+                    pipSupportDisabled = true;
+                } catch (IllegalArgumentException e) {
+                    // Pip not supported
+                    pipSupportDisabled = true;
+                }
+                assertTrue(pipSupportDisabled);
+                assertFalse(mActivity.isInMultiWindowMode());
+                assertFalse(mActivity.isInPictureInPictureMode());
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+    }
+}
diff --git a/tests/app/src/android/app/cts/ProgressDialogTest.java b/tests/app/src/android/app/cts/ProgressDialogTest.java
new file mode 100644
index 0000000..4f4007e
--- /dev/null
+++ b/tests/app/src/android/app/cts/ProgressDialogTest.java
@@ -0,0 +1,365 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.cts;
+
+import android.app.Instrumentation;
+import android.app.ProgressDialog;
+import android.app.stubs.MockActivity;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnCancelListener;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.UiThreadTest;
+import android.view.Window;
+import android.widget.ProgressBar;
+
+import android.app.stubs.R;
+
+/**
+ * Test {@link ProgressDialog}.
+ */
+public class ProgressDialogTest extends ActivityInstrumentationTestCase2<MockActivity> {
+    private final CharSequence TITLE = "title";
+    private final CharSequence MESSAGE = "message";
+
+    private boolean mCanceled;
+    private Drawable mDrawable;
+    private Drawable mActualDrawableNull;
+    private Drawable mActualDrawable;
+    private ProgressBar mProgressBar;
+    private int mProgress1;
+    private int mProgress2;
+
+    private Context mContext;
+    private Instrumentation mInstrumentation;
+    private MockActivity mActivity;
+
+    public ProgressDialogTest() {
+        super("android.app.stubs", MockActivity.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        mCanceled = false;
+        mInstrumentation = getInstrumentation();
+        mActivity = getActivity();
+        mContext = mActivity;
+        mDrawable = getActivity().getResources().getDrawable(
+                R.drawable.yellow);
+    }
+
+    @UiThreadTest
+    public void testProgressDialog1(){
+        new ProgressDialog(mContext);
+    }
+
+    @UiThreadTest
+    public void testProgressDialog2(){
+        new ProgressDialog(mContext, R.style.Theme_AlertDialog);
+    }
+
+    @UiThreadTest
+    public void testOnStartCreateStop() {
+        MockProgressDialog pd = new MockProgressDialog(mContext);
+
+        assertFalse(pd.mIsOnCreateCalled);
+        assertFalse(pd.mIsOnStartCalled);
+        pd.show();
+        assertTrue(pd.mIsOnCreateCalled);
+        assertTrue(pd.mIsOnStartCalled);
+
+        assertFalse(pd.mIsOnStopCalled);
+        pd.dismiss();
+        assertTrue(pd.mIsOnStopCalled);
+    }
+
+    @UiThreadTest
+    public void testShow1() {
+        ProgressDialog.show(mContext, TITLE, MESSAGE);
+    }
+
+    @UiThreadTest
+    public void testShow2() {
+        ProgressDialog dialog = ProgressDialog.show(mContext, TITLE, MESSAGE, false);
+
+        /*
+         * note: the progress bar's style only supports indeterminate mode,
+         * so can't change indeterminate
+         */
+        assertTrue(dialog.isIndeterminate());
+
+        dialog = ProgressDialog.show(mContext, TITLE, MESSAGE, true);
+        assertTrue(dialog.isIndeterminate());
+    }
+
+    public void testShow3() throws Throwable {
+        final OnCancelListener cL = new OnCancelListener(){
+            public void onCancel(DialogInterface dialog) {
+                mCanceled = true;
+            }
+        };
+
+        // cancelable is false
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                ProgressDialog dialog = ProgressDialog.show(mContext, TITLE, MESSAGE, true, false);
+
+                dialog.setOnCancelListener(cL);
+                dialog.onBackPressed();
+                dialog.dismiss();
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+
+        assertFalse(mCanceled);
+
+        // cancelable is true
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                ProgressDialog dialog = ProgressDialog.show(mContext, TITLE, MESSAGE, true, true);
+                assertFalse(mCanceled);
+                dialog.setOnCancelListener(cL);
+                dialog.onBackPressed();
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+
+        assertTrue(mCanceled);
+    }
+
+    public void testShow4() throws Throwable {
+        final OnCancelListener cL = new OnCancelListener(){
+            public void onCancel(DialogInterface dialog) {
+                mCanceled = true;
+            }
+        };
+
+        // cancelable is false
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                ProgressDialog dialog = ProgressDialog.show(
+                        mContext, TITLE, MESSAGE, true, false, cL);
+
+                dialog.onBackPressed();
+                dialog.dismiss();;
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+
+        assertFalse(mCanceled);
+
+        // cancelable is true
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                ProgressDialog dialog = ProgressDialog.show(
+                        mContext, TITLE, MESSAGE, true, true, cL);
+
+                assertFalse(mCanceled);
+                dialog.onBackPressed();
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+
+        assertTrue(mCanceled);
+    }
+
+    @UiThreadTest
+    public void testAccessMax() {
+        // progressDialog is null
+        ProgressDialog progressDialog = buildDialog();
+        progressDialog.setMax(2008);
+        assertEquals(2008, progressDialog.getMax());
+
+        // progressDialog is not null
+        progressDialog = ProgressDialog.show(mContext, TITLE, MESSAGE);
+        progressDialog.setMax(2009);
+        assertEquals(2009, progressDialog.getMax());
+    }
+
+    @UiThreadTest
+    public void testAccessProgress() {
+        // progressDialog is null
+        ProgressDialog progressDialog = buildDialog();
+        progressDialog.setProgress(11);
+        assertEquals(11, progressDialog.getProgress());
+
+        /* progressDialog is not null
+         * note: the progress bar's style only supports indeterminate mode,
+         * so can't change progress
+         */
+        progressDialog = ProgressDialog.show(mContext, TITLE, MESSAGE);
+        progressDialog.setProgress(12);
+        assertEquals(0, progressDialog.getProgress());
+    }
+
+    @UiThreadTest
+    public void testAccessSecondaryProgress() {
+        // dialog is null
+        ProgressDialog dialog = buildDialog();
+        dialog.setSecondaryProgress(17);
+        assertEquals(17, dialog.getSecondaryProgress());
+
+        /* mProgress is not null
+         * note: the progress bar's style only supports indeterminate mode,
+         * so can't change secondary progress
+         */
+        dialog = ProgressDialog.show(mContext, TITLE, MESSAGE);
+        dialog.setSecondaryProgress(18);
+        assertEquals(0, dialog.getSecondaryProgress());
+    }
+
+    @UiThreadTest
+    public void testSetIndeterminate() {
+        // progress is null
+        ProgressDialog dialog = buildDialog();
+        dialog.setIndeterminate(true);
+        assertTrue(dialog.isIndeterminate());
+        dialog.setIndeterminate(false);
+        assertFalse(dialog.isIndeterminate());
+
+        /* mProgress is not null
+         * note: the progress bar's style only supports indeterminate mode,
+         * so can't change indeterminate
+         */
+        dialog = ProgressDialog.show(mContext, TITLE, MESSAGE);
+        dialog.setIndeterminate(true);
+        assertTrue(dialog.isIndeterminate());
+        dialog.setIndeterminate(false);
+        assertTrue(dialog.isIndeterminate());
+    }
+
+    @UiThreadTest
+    public void testIncrementProgressBy() throws Throwable {
+        ProgressDialog dialog = new ProgressDialog(mContext);
+        dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
+        dialog.show();
+        dialog.setProgress(10);
+        mProgress1 = dialog.getProgress();
+        dialog.incrementProgressBy(60);
+        mProgress2 = dialog.getProgress();
+        dialog.cancel();
+
+        assertEquals(10, mProgress1);
+        assertEquals(70, mProgress2);
+    }
+
+    @UiThreadTest
+    public void testIncrementSecondaryProgressBy() throws Throwable {
+        ProgressDialog dialog = new ProgressDialog(mContext);
+        dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
+        dialog.show();
+        dialog.setSecondaryProgress(10);
+        mProgress1 = dialog.getSecondaryProgress();
+        dialog.incrementSecondaryProgressBy(60);
+        mProgress2 = dialog.getSecondaryProgress();
+
+        assertEquals(10, mProgress1);
+        assertEquals(70, mProgress2);
+    }
+
+    @UiThreadTest
+    public void testSetProgressDrawable() throws Throwable {
+        ProgressDialog dialog = ProgressDialog.show(mContext, TITLE, MESSAGE);
+        Window w = dialog.getWindow();
+        ProgressBar progressBar = (ProgressBar) w.findViewById(android.R.id.progress);
+
+        dialog.setProgressDrawable(mDrawable);
+        mActualDrawable = progressBar.getProgressDrawable();
+
+        dialog.setProgressDrawable(null);
+        mActualDrawableNull = progressBar.getProgressDrawable();
+        assertEquals(mDrawable, mActualDrawable);
+        assertEquals(null, mActualDrawableNull);
+    }
+
+    @UiThreadTest
+    public void testSetIndeterminateDrawable() throws Throwable {
+        ProgressDialog dialog = ProgressDialog.show(mContext, TITLE, MESSAGE);
+        Window w = dialog.getWindow();
+        mProgressBar = (ProgressBar) w.findViewById(android.R.id.progress);
+
+        dialog.setIndeterminateDrawable(mDrawable);
+        mActualDrawable = mProgressBar.getIndeterminateDrawable();
+        assertEquals(mDrawable, mActualDrawable);
+
+        dialog.setIndeterminateDrawable(null);
+        mActualDrawableNull = mProgressBar.getIndeterminateDrawable();
+        assertEquals(null, mActualDrawableNull);
+    }
+
+    @UiThreadTest
+    public void testSetMessage() throws Throwable {
+        ProgressDialog dialog = new ProgressDialog(mContext);
+        dialog = new ProgressDialog(mContext);
+        dialog.setMessage(MESSAGE);
+        dialog.show();
+        // dialog is not null
+        dialog = ProgressDialog.show(mContext, TITLE, MESSAGE);
+        dialog.setMessage("Chuck Norris");
+    }
+
+    @UiThreadTest
+    public void testSetProgressStyle() throws Throwable {
+        ProgressDialog dialog = new ProgressDialog(mContext);
+        setProgressStyle(dialog, ProgressDialog.STYLE_HORIZONTAL);
+        setProgressStyle(dialog, ProgressDialog.STYLE_SPINNER);
+        setProgressStyle(dialog, 100);
+    }
+
+    private void setProgressStyle(ProgressDialog dialog, int style) {
+        dialog.setProgressStyle(style);
+        dialog.show();
+        dialog.setProgress(10);
+        dialog.setMax(100);
+    }
+
+    private static class MockProgressDialog extends ProgressDialog {
+        public boolean mIsOnStopCalled;
+        public boolean mIsOnStartCalled;
+        public boolean mIsOnCreateCalled;
+
+        public MockProgressDialog(Context context) {
+            super(context);
+        }
+
+        @Override
+        protected void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            mIsOnCreateCalled = true;
+        }
+
+        @Override
+        public void onStart(){
+            super.onStart();
+            mIsOnStartCalled = true;
+        }
+
+        @Override
+        public void onStop() {
+            super.onStop();
+            mIsOnStopCalled = true;
+        }
+    }
+
+    private ProgressDialog buildDialog() {
+        return new ProgressDialog(mContext);
+    }
+}
diff --git a/tests/app/src/android/app/cts/SearchManagerStubActivity.java b/tests/app/src/android/app/cts/SearchManagerStubActivity.java
deleted file mode 100644
index 0dbd832..0000000
--- a/tests/app/src/android/app/cts/SearchManagerStubActivity.java
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-import android.app.Activity;
-import android.app.SearchManager;
-import android.content.ComponentName;
-import android.content.Context;
-import android.cts.util.CTSResult;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.util.Log;
-
-public class SearchManagerStubActivity extends Activity {
-
-    private static final String TAG = "SearchManagerStubActivity";
-
-    public static final String TEST_STOP_SEARCH = "stopSearch";
-    public static final String TEST_ON_DISMISSLISTENER = "setOnDismissListener";
-    public static final String TEST_ON_CANCELLISTENER = "setOnCancelListener";
-
-    private SearchManager mSearchManager;
-    private ComponentName mComponentName;
-
-    private static CTSResult sCTSResult;
-    private boolean mDismissCalled;
-    private boolean mCancelCalled;
-
-    public static void setCTSResult(CTSResult result) {
-        sCTSResult = result;
-    }
-
-    @Override
-    public void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-        mSearchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
-        mComponentName = getComponentName();
-        String action = getIntent().getAction();
-        if (action.equals(TEST_STOP_SEARCH)) {
-            testStopSearch();
-        } else if (action.equals(TEST_ON_DISMISSLISTENER)) {
-            testOnDismissListener();
-        } else if (action.equals(TEST_ON_CANCELLISTENER)) {
-            testOnCancelListener();
-        }
-    }
-
-    private void testOnCancelListener() {
-        mCancelCalled = false;
-        mSearchManager.setOnCancelListener(new SearchManager.OnCancelListener() {
-            @Override
-            public void onCancel() {
-               mCancelCalled = true;
-            }
-        });
-
-        new TestStepHandler() {
-            @Override
-            public boolean doStep(int step) throws FailException {
-                switch (step) {
-                    case 1:
-                        startSearch("test", false, mComponentName, null, false);
-                        return false;
-                    case 2:
-                        assertFalse("cancel called", mCancelCalled);
-                        stopSearch();
-                        return false;
-                    case 3:
-                        assertTrue("cancel not called", mCancelCalled);
-                        pass();
-                        return true;
-                    default:
-                        throw new IllegalArgumentException("Bad step " + step);
-                }
-            }
-        }.start();
-    }
-
-    private void testOnDismissListener() {
-        mDismissCalled = false;
-
-        mSearchManager.setOnDismissListener(new SearchManager.OnDismissListener() {
-            public void onDismiss() {
-                mDismissCalled = true;
-            }
-        });
-
-        new TestStepHandler() {
-            @Override
-            public boolean doStep(int step) throws FailException {
-                switch (step) {
-                    case 1:
-                        startSearch("test", false, mComponentName, null, false);
-                        return false;
-                    case 2:
-                        if (mDismissCalled) {
-                            throw new FailException("dismiss called");
-                        } else {
-                            stopSearch();
-                        }
-                        return false;
-                    case 3:
-                        if (mDismissCalled) {
-                            pass();
-                        } else {
-                            throw new FailException("dismiss not called");
-                        }
-                        return true;
-                    default:
-                        throw new IllegalArgumentException("Bad step " + step);
-                }
-            }
-        }.start();
-    }
-
-    private void testStopSearch() {
-        new TestStepHandler() {
-            @Override
-            public boolean doStep(int step) throws FailException {
-                switch (step) {
-                    case 1:
-                        startSearch("test", false, mComponentName, null, false);
-                        return false;
-                    case 2:
-                        assertVisible();
-                        stopSearch();
-                        return false;
-                    case 3:
-                        assertInVisible();
-                        pass();
-                        return true;
-                    default:
-                        throw new IllegalArgumentException("Bad step " + step);
-                }
-            }
-        }.start();
-    }
-
-    private void fail(Exception ex) {
-        Log.e(TAG, "test failed", ex);
-        sCTSResult.setResult(CTSResult.RESULT_FAIL);
-        finish();
-    }
-
-    private void pass() {
-        sCTSResult.setResult(CTSResult.RESULT_OK);
-        finish();
-    }
-
-    private void assertInVisible() throws FailException {
-        if (isVisible()) {
-            throw new FailException();
-        }
-    }
-
-    private void assertVisible() throws FailException {
-        if (!isVisible()) {
-            throw new FailException();
-        }
-    }
-
-    private void assertFalse(String message, boolean value) throws FailException {
-        assertTrue(message, !value);
-    }
-
-    private void assertTrue(String message, boolean value) throws FailException {
-        if (!value) {
-            throw new FailException(message);
-        }
-    }
-
-    private void startSearch(String initialQuery, boolean selectInitialQuery,
-            ComponentName launchActivity, Bundle appSearchData, boolean globalSearch) {
-        mSearchManager.startSearch(initialQuery, selectInitialQuery, launchActivity, appSearchData,
-                globalSearch);
-    }
-
-    private void stopSearch() {
-       mSearchManager.stopSearch();
-    }
-
-    private boolean isVisible() {
-        return mSearchManager.isVisible();
-    }
-
-    private abstract class TestStepHandler extends Handler {
-
-        public void start() {
-            sendEmptyMessage(1);
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            try {
-                if (!doStep(msg.what)) {
-                    sendEmptyMessage(msg.what + 1);
-                }
-            } catch (FailException ex) {
-                fail(ex);
-            }
-        }
-
-        /**
-         * Performs one step of the test.
-         *
-         * @param step The 1-based number of the step to perform.
-         * @return {@code true} if this was the last step.
-         * @throws FailException If the test failed.
-         */
-        protected abstract boolean doStep(int step) throws FailException;
-    }
-
-    private static class FailException extends Exception {
-        private static final long serialVersionUID = 1L;
-
-        public FailException() {
-            super();
-        }
-
-        public FailException(String detailMessage) {
-            super(detailMessage);
-        }
-    }
-}
diff --git a/tests/app/src/android/app/cts/SearchManagerTest.java b/tests/app/src/android/app/cts/SearchManagerTest.java
new file mode 100644
index 0000000..13a8073
--- /dev/null
+++ b/tests/app/src/android/app/cts/SearchManagerTest.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.cts;
+
+import android.app.stubs.CTSActivityTestCaseBase;
+import android.app.stubs.SearchManagerStubActivity;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+
+public class SearchManagerTest extends CTSActivityTestCaseBase {
+
+    private void setupActivity(String action) {
+        Intent intent = new Intent();
+        intent.setAction(action);
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        intent.setClass(getInstrumentation().getTargetContext(), SearchManagerStubActivity.class);
+        getInstrumentation().getTargetContext().startActivity(intent);
+    }
+
+    public void testStopSearch() throws InterruptedException {
+        if (isTelevision()) {
+            return;
+        }
+        SearchManagerStubActivity.setCTSResult(this);
+        setupActivity(SearchManagerStubActivity.TEST_STOP_SEARCH);
+        waitForResult();
+    }
+
+    public void testSetOnDismissListener() throws InterruptedException {
+        if (isTelevision()) {
+            return;
+        }
+        SearchManagerStubActivity.setCTSResult(this);
+        setupActivity(SearchManagerStubActivity.TEST_ON_DISMISSLISTENER);
+        waitForResult();
+    }
+
+    public void testSetOnCancelListener() throws InterruptedException {
+        if (isTelevision()) {
+            return;
+        }
+        SearchManagerStubActivity.setCTSResult(this);
+        setupActivity(SearchManagerStubActivity.TEST_ON_CANCELLISTENER);
+        waitForResult();
+    }
+
+    private boolean isTelevision() {
+        Context context = getInstrumentation().getTargetContext();
+        PackageManager pm = context.getPackageManager();
+        return pm.hasSystemFeature(PackageManager.FEATURE_TELEVISION)
+                || pm.hasSystemFeature(PackageManager.FEATURE_LEANBACK);
+    }
+}
diff --git a/tests/app/src/android/app/cts/ServiceTest.java b/tests/app/src/android/app/cts/ServiceTest.java
new file mode 100644
index 0000000..4842bb1
--- /dev/null
+++ b/tests/app/src/android/app/cts/ServiceTest.java
@@ -0,0 +1,468 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.cts;
+
+import android.app.stubs.ActivityTestsBase;
+import android.app.stubs.LocalDeniedService;
+import android.app.stubs.LocalGrantedService;
+import android.app.stubs.LocalService;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.cts.util.IBinderParcelable;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.RemoteException;
+import android.test.suitebuilder.annotation.MediumTest;
+
+public class ServiceTest extends ActivityTestsBase {
+    private static final int STATE_START_1 = 0;
+    private static final int STATE_START_2 = 1;
+    private static final int STATE_UNBIND = 2;
+    private static final int STATE_DESTROY = 3;
+    private static final int STATE_REBIND = 4;
+    private static final int STATE_UNBIND_ONLY = 5;
+    private static final int DELAY = 5000;
+    private static final
+        String EXIST_CONN_TO_RECEIVE_SERVICE = "existing connection to receive service";
+    private static final String EXIST_CONN_TO_LOSE_SERVICE = "existing connection to lose service";
+    private int mExpectedServiceState;
+    private Context mContext;
+    private Intent mLocalService;
+    private Intent mLocalDeniedService;
+    private Intent mLocalGrantedService;
+    private Intent mLocalService_ApplicationHasPermission;
+    private Intent mLocalService_ApplicationDoesNotHavePermission;
+
+    private IBinder mStateReceiver;
+
+    private static class EmptyConnection implements ServiceConnection {
+        @Override
+        public void onServiceConnected(ComponentName name, IBinder service) {
+        }
+
+        @Override
+        public void onServiceDisconnected(ComponentName name) {
+        }
+    }
+
+    private class TestConnection implements ServiceConnection {
+        private final boolean mExpectDisconnect;
+        private final boolean mSetReporter;
+        private boolean mMonitor;
+        private int mCount;
+
+        public TestConnection(boolean expectDisconnect, boolean setReporter) {
+            mExpectDisconnect = expectDisconnect;
+            mSetReporter = setReporter;
+            mMonitor = !setReporter;
+        }
+
+        void setMonitor(boolean v) {
+            mMonitor = v;
+        }
+
+        @Override
+        public void onServiceConnected(ComponentName name, IBinder service) {
+            if (mSetReporter) {
+                Parcel data = Parcel.obtain();
+                data.writeInterfaceToken(LocalService.SERVICE_LOCAL);
+                data.writeStrongBinder(mStateReceiver);
+                try {
+                    service.transact(LocalService.SET_REPORTER_CODE, data, null, 0);
+                } catch (RemoteException e) {
+                    finishBad("DeadObjectException when sending reporting object");
+                }
+                data.recycle();
+            }
+
+            if (mMonitor) {
+                mCount++;
+                if (mExpectedServiceState == STATE_START_1) {
+                    if (mCount == 1) {
+                        finishGood();
+                    } else {
+                        finishBad("onServiceConnected() again on an object when it "
+                                + "should have been the first time");
+                    }
+                } else if (mExpectedServiceState == STATE_START_2) {
+                    if (mCount == 2) {
+                        finishGood();
+                    } else {
+                        finishBad("onServiceConnected() the first time on an object "
+                                + "when it should have been the second time");
+                    }
+                } else {
+                    finishBad("onServiceConnected() called unexpectedly");
+                }
+            }
+        }
+
+        @Override
+        public void onServiceDisconnected(ComponentName name) {
+            if (mMonitor) {
+                if (mExpectedServiceState == STATE_DESTROY) {
+                    if (mExpectDisconnect) {
+                        finishGood();
+                    } else {
+                        finishBad("onServiceDisconnected() when it shouldn't have been");
+                    }
+                } else {
+                    finishBad("onServiceDisconnected() called unexpectedly");
+                }
+            }
+        }
+    }
+
+    private void startExpectResult(Intent service) {
+        startExpectResult(service, new Bundle());
+    }
+
+    private void startExpectResult(Intent service, Bundle bundle) {
+        bundle.putParcelable(LocalService.REPORT_OBJ_NAME, new IBinderParcelable(mStateReceiver));
+
+        boolean success = false;
+        try {
+            mExpectedServiceState = STATE_START_1;
+            mContext.startService(new Intent(service).putExtras(bundle));
+            waitForResultOrThrow(DELAY, "service to start first time");
+            mExpectedServiceState = STATE_START_2;
+            mContext.startService(new Intent(service).putExtras(bundle));
+            waitForResultOrThrow(DELAY, "service to start second time");
+            success = true;
+        } finally {
+            if (!success) {
+                mContext.stopService(service);
+            }
+        }
+        mExpectedServiceState = STATE_DESTROY;
+        mContext.stopService(service);
+        waitForResultOrThrow(DELAY, "service to be destroyed");
+    }
+
+    /**
+     * test the service lifecycle, a service can be used in two ways:
+     * 1  It can be started and allowed to run until someone stops it or it stops itself.
+     *    In this mode, it's started by calling Context.startService()
+     *    and stopped by calling Context.stopService().
+     *    It can stop itself by calling Service.stopSelf() or Service.stopSelfResult().
+     *    Only one stopService() call is needed to stop the service,
+     *    no matter how many times startService() was called.
+     * 2  It can be operated programmatically using an interface that it defines and exports.
+     *    Clients establish a connection to the Service object
+     *    and use that connection to call into the service.
+     *    The connection is established by calling Context.bindService(),
+     *    and is closed by calling Context.unbindService().
+     *    Multiple clients can bind to the same service.
+     *    If the service has not already been launched, bindService() can optionally launch it.
+     */
+    private void bindExpectResult(Intent service) {
+        TestConnection conn = new TestConnection(true, false);
+        TestConnection conn2 = new TestConnection(false, false);
+        boolean success = false;
+        try {
+            // Expect to see the TestConnection connected.
+            mExpectedServiceState = STATE_START_1;
+            mContext.bindService(service, conn, 0);
+            mContext.startService(service);
+            waitForResultOrThrow(DELAY, EXIST_CONN_TO_RECEIVE_SERVICE);
+
+            // Expect to see the second TestConnection connected.
+            mContext.bindService(service, conn2, 0);
+            waitForResultOrThrow(DELAY, "new connection to receive service");
+
+            mContext.unbindService(conn2);
+            success = true;
+        } finally {
+            if (!success) {
+                mContext.unbindService(conn);
+                mContext.unbindService(conn2);
+                mContext.stopService(service);
+            }
+        }
+
+        // Expect to see the TestConnection disconnected.
+        mExpectedServiceState = STATE_DESTROY;
+        mContext.stopService(service);
+        waitForResultOrThrow(DELAY, EXIST_CONN_TO_LOSE_SERVICE);
+
+        mContext.unbindService(conn);
+
+        conn = new TestConnection(true, true);
+        success = false;
+        try {
+            // Expect to see the TestConnection connected.
+            conn.setMonitor(true);
+            mExpectedServiceState = STATE_START_1;
+            mContext.bindService(service, conn, 0);
+            mContext.startService(service);
+            waitForResultOrThrow(DELAY, EXIST_CONN_TO_RECEIVE_SERVICE);
+
+            success = true;
+        } finally {
+            if (!success) {
+                mContext.unbindService(conn);
+                mContext.stopService(service);
+            }
+        }
+
+        // Expect to see the service unbind and then destroyed.
+        conn.setMonitor(false);
+        mExpectedServiceState = STATE_UNBIND;
+        mContext.stopService(service);
+        waitForResultOrThrow(DELAY, EXIST_CONN_TO_LOSE_SERVICE);
+
+        mContext.unbindService(conn);
+
+        conn = new TestConnection(true, true);
+        success = false;
+        try {
+            // Expect to see the TestConnection connected.
+            conn.setMonitor(true);
+            mExpectedServiceState = STATE_START_1;
+            mContext.bindService(service, conn, 0);
+            mContext.startService(service);
+            waitForResultOrThrow(DELAY, EXIST_CONN_TO_RECEIVE_SERVICE);
+
+            success = true;
+        } finally {
+            if (!success) {
+                mContext.unbindService(conn);
+                mContext.stopService(service);
+            }
+        }
+
+        // Expect to see the service unbind but not destroyed.
+        conn.setMonitor(false);
+        mExpectedServiceState = STATE_UNBIND_ONLY;
+        mContext.unbindService(conn);
+        waitForResultOrThrow(DELAY, "existing connection to unbind service");
+
+        // Expect to see the service rebound.
+        mExpectedServiceState = STATE_REBIND;
+        mContext.bindService(service, conn, 0);
+        waitForResultOrThrow(DELAY, "existing connection to rebind service");
+
+        // Expect to see the service unbind and then destroyed.
+        mExpectedServiceState = STATE_UNBIND;
+        mContext.stopService(service);
+        waitForResultOrThrow(DELAY, EXIST_CONN_TO_LOSE_SERVICE);
+
+        mContext.unbindService(conn);
+    }
+
+    /**
+     * test automatically create the service as long as the binding exists
+     * and disconnect from an application service
+     */
+    private void bindAutoExpectResult(Intent service) {
+        TestConnection conn = new TestConnection(false, true);
+        boolean success = false;
+        try {
+            conn.setMonitor(true);
+            mExpectedServiceState = STATE_START_1;
+            mContext.bindService(
+                    service, conn, Context.BIND_AUTO_CREATE);
+            waitForResultOrThrow(DELAY, "connection to start and receive service");
+            success = true;
+        } finally {
+            if (!success) {
+                mContext.unbindService(conn);
+            }
+        }
+        mExpectedServiceState = STATE_UNBIND;
+        mContext.unbindService(conn);
+        waitForResultOrThrow(DELAY, "disconnecting from service");
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mContext = getContext();
+        mLocalService = new Intent(mContext, LocalService.class);
+        mLocalDeniedService = new Intent(mContext, LocalDeniedService.class);
+        mLocalGrantedService = new Intent(mContext, LocalGrantedService.class);
+        mLocalService_ApplicationHasPermission = new Intent(
+                LocalService.SERVICE_LOCAL_GRANTED, null /*uri*/, mContext, LocalService.class);
+        mLocalService_ApplicationDoesNotHavePermission = new Intent(
+                LocalService.SERVICE_LOCAL_DENIED, null /*uri*/, mContext, LocalService.class);
+        mStateReceiver = new MockBinder();
+    }
+
+    private class MockBinder extends Binder {
+        @Override
+        protected boolean onTransact(int code, Parcel data, Parcel reply,
+                int flags) throws RemoteException {
+            if (code == LocalService.STARTED_CODE) {
+                data.enforceInterface(LocalService.SERVICE_LOCAL);
+                int count = data.readInt();
+                if (mExpectedServiceState == STATE_START_1) {
+                    if (count == 1) {
+                        finishGood();
+                    } else {
+                        finishBad("onStart() again on an object when it "
+                                + "should have been the first time");
+                    }
+                } else if (mExpectedServiceState == STATE_START_2) {
+                    if (count == 2) {
+                        finishGood();
+                    } else {
+                        finishBad("onStart() the first time on an object when it "
+                                + "should have been the second time");
+                    }
+                } else {
+                    finishBad("onStart() was called when not expected (state="
+                            + mExpectedServiceState + ")");
+                }
+                return true;
+            } else if (code == LocalService.DESTROYED_CODE) {
+                data.enforceInterface(LocalService.SERVICE_LOCAL);
+                if (mExpectedServiceState == STATE_DESTROY) {
+                    finishGood();
+                } else {
+                    finishBad("onDestroy() was called when not expected (state="
+                            + mExpectedServiceState + ")");
+                }
+                return true;
+            } else if (code == LocalService.UNBIND_CODE) {
+                data.enforceInterface(LocalService.SERVICE_LOCAL);
+                if (mExpectedServiceState == STATE_UNBIND) {
+                    mExpectedServiceState = STATE_DESTROY;
+                } else if (mExpectedServiceState == STATE_UNBIND_ONLY) {
+                    finishGood();
+                } else {
+                    finishBad("onUnbind() was called when not expected (state="
+                            + mExpectedServiceState + ")");
+                }
+                return true;
+            } else if (code == LocalService.REBIND_CODE) {
+                data.enforceInterface(LocalService.SERVICE_LOCAL);
+                if (mExpectedServiceState == STATE_REBIND) {
+                    finishGood();
+                } else {
+                    finishBad("onRebind() was called when not expected (state="
+                            + mExpectedServiceState + ")");
+                }
+                return true;
+            } else {
+                return super.onTransact(code, data, reply, flags);
+            }
+        }
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+        mContext.stopService(mLocalService);
+        mContext.stopService(mLocalGrantedService);
+        mContext.stopService(mLocalService_ApplicationHasPermission);
+    }
+
+    public void testLocalStartClass() throws Exception {
+        startExpectResult(mLocalService);
+    }
+
+    public void testLocalStartAction() throws Exception {
+        startExpectResult(new Intent(
+                LocalService.SERVICE_LOCAL, null /*uri*/, mContext, LocalService.class));
+    }
+
+    public void testLocalBindClass() throws Exception {
+        bindExpectResult(mLocalService);
+    }
+
+    @MediumTest
+    public void testLocalBindAction() throws Exception {
+        bindExpectResult(new Intent(
+                LocalService.SERVICE_LOCAL, null /*uri*/, mContext, LocalService.class));
+    }
+
+    @MediumTest
+    public void testLocalBindAutoClass() throws Exception {
+        bindAutoExpectResult(mLocalService);
+    }
+
+    @MediumTest
+    public void testLocalBindAutoAction() throws Exception {
+        bindAutoExpectResult(new Intent(
+                LocalService.SERVICE_LOCAL, null /*uri*/, mContext, LocalService.class));
+    }
+
+    @MediumTest
+    public void testLocalStartClassPermissions() throws Exception {
+        startExpectResult(mLocalGrantedService);
+        startExpectResult(mLocalDeniedService);
+    }
+
+    @MediumTest
+    public void testLocalStartActionPermissions() throws Exception {
+        startExpectResult(mLocalService_ApplicationHasPermission);
+        startExpectResult(mLocalService_ApplicationDoesNotHavePermission);
+    }
+
+    @MediumTest
+    public void testLocalBindClassPermissions() throws Exception {
+        bindExpectResult(mLocalGrantedService);
+        bindExpectResult(mLocalDeniedService);
+    }
+
+    @MediumTest
+    public void testLocalBindActionPermissions() throws Exception {
+        bindExpectResult(mLocalService_ApplicationHasPermission);
+        bindExpectResult(mLocalService_ApplicationDoesNotHavePermission);
+    }
+
+    @MediumTest
+    public void testLocalBindAutoClassPermissionGranted() throws Exception {
+        bindAutoExpectResult(mLocalGrantedService);
+    }
+
+    @MediumTest
+    public void testLocalBindAutoActionPermissionGranted() throws Exception {
+        bindAutoExpectResult(mLocalService_ApplicationHasPermission);
+    }
+
+    @MediumTest
+    public void testLocalUnbindTwice() throws Exception {
+        EmptyConnection conn = new EmptyConnection();
+        mContext.bindService(
+                mLocalService_ApplicationHasPermission, conn, 0);
+        mContext.unbindService(conn);
+        try {
+            mContext.unbindService(conn);
+            fail("No exception thrown on the second unbind");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+    }
+
+    @MediumTest
+    public void testImplicitIntentFailsOnApiLevel21() throws Exception {
+        Intent intent = new Intent(LocalService.SERVICE_LOCAL);
+        EmptyConnection conn = new EmptyConnection();
+        try {
+            mContext.bindService(intent, conn, 0);
+            mContext.unbindService(conn);
+            fail("Implicit intents should be disallowed for apps targeting API 21+");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+    }
+}
diff --git a/tests/app/src/android/app/cts/StubRemoteService.java b/tests/app/src/android/app/cts/StubRemoteService.java
deleted file mode 100644
index 1239734..0000000
--- a/tests/app/src/android/app/cts/StubRemoteService.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-import android.app.Service;
-import android.content.Intent;
-import android.os.IBinder;
-import android.os.Process;
-
-public class StubRemoteService extends Service{
-
-    @Override
-    public void onCreate() {
-        super.onCreate();
-        android.util.Log.d("Process test stub", "StubRemoteServiceProcessPid:" + Process.myPid());
-    }
-
-    private final ISecondary.Stub mSecondaryBinder = new ISecondary.Stub() {
-        public int getPid() {
-            return Process.myPid();
-        }
-
-        public long getElapsedCpuTime() {
-            return Process.getElapsedCpuTime();
-        }
-
-        public String getTimeZoneID() {
-            return java.util.TimeZone.getDefault().getID();
-        }
-    };
-
-    @Override
-    public IBinder onBind(Intent intent) {
-        if (ISecondary.class.getName().equals(intent.getAction())) {
-            return mSecondaryBinder;
-        }
-        return null;
-    }
-
-}
diff --git a/tests/app/src/android/app/cts/SystemFeaturesTest.java b/tests/app/src/android/app/cts/SystemFeaturesTest.java
new file mode 100644
index 0000000..864f1be
--- /dev/null
+++ b/tests/app/src/android/app/cts/SystemFeaturesTest.java
@@ -0,0 +1,504 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.cts;
+
+import android.app.ActivityManager;
+import android.app.Instrumentation;
+import android.app.WallpaperManager;
+import android.bluetooth.BluetoothAdapter;
+import android.content.ActivityNotFoundException;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ConfigurationInfo;
+import android.content.pm.FeatureInfo;
+import android.content.pm.PackageManager;
+import android.content.res.Configuration;
+import android.hardware.Camera;
+import android.hardware.Camera.CameraInfo;
+import android.hardware.Camera.Parameters;
+import android.hardware.Sensor;
+import android.hardware.SensorManager;
+import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CameraManager;
+import android.hardware.camera2.CameraMetadata;
+import android.location.LocationManager;
+import android.net.sip.SipManager;
+import android.net.wifi.WifiManager;
+import android.nfc.NfcAdapter;
+import android.telephony.TelephonyManager;
+import android.test.InstrumentationTestCase;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Test for checking that the {@link PackageManager} is reporting the correct features.
+ */
+public class SystemFeaturesTest extends InstrumentationTestCase {
+
+    private Context mContext;
+    private PackageManager mPackageManager;
+    private HashSet<String> mAvailableFeatures;
+
+    private ActivityManager mActivityManager;
+    private LocationManager mLocationManager;
+    private SensorManager mSensorManager;
+    private TelephonyManager mTelephonyManager;
+    private WifiManager mWifiManager;
+    private CameraManager mCameraManager;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        Instrumentation instrumentation = getInstrumentation();
+        mContext = instrumentation.getTargetContext();
+        mPackageManager = mContext.getPackageManager();
+        mAvailableFeatures = new HashSet<String>();
+        if (mPackageManager.getSystemAvailableFeatures() != null) {
+            for (FeatureInfo feature : mPackageManager.getSystemAvailableFeatures()) {
+                mAvailableFeatures.add(feature.name);
+            }
+        }
+        mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
+        mLocationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
+        mSensorManager = (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE);
+        mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
+        mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
+        mCameraManager = (CameraManager) mContext.getSystemService(Context.CAMERA_SERVICE);
+    }
+
+    /**
+     * Check for features improperly prefixed with "android." that are not defined in
+     * {@link PackageManager}.
+     */
+    public void testFeatureNamespaces() throws IllegalArgumentException, IllegalAccessException {
+        Set<String> officialFeatures = getFeatureConstantsNames("FEATURE_");
+        assertFalse(officialFeatures.isEmpty());
+
+        Set<String> notOfficialFeatures = new HashSet<String>(mAvailableFeatures);
+        notOfficialFeatures.removeAll(officialFeatures);
+
+        for (String featureName : notOfficialFeatures) {
+            if (featureName != null) {
+                assertFalse("Use a different namespace than 'android' for " + featureName,
+                        featureName.startsWith("android"));
+            }
+        }
+    }
+
+    public void testBluetoothFeature() {
+        if (BluetoothAdapter.getDefaultAdapter() != null) {
+            assertAvailable(PackageManager.FEATURE_BLUETOOTH);
+        } else {
+            assertNotAvailable(PackageManager.FEATURE_BLUETOOTH);
+        }
+    }
+
+    public void testCameraFeatures() throws Exception {
+        int numCameras = Camera.getNumberOfCameras();
+        if (numCameras == 0) {
+            assertNotAvailable(PackageManager.FEATURE_CAMERA);
+            assertNotAvailable(PackageManager.FEATURE_CAMERA_AUTOFOCUS);
+            assertNotAvailable(PackageManager.FEATURE_CAMERA_FLASH);
+            assertNotAvailable(PackageManager.FEATURE_CAMERA_FRONT);
+            assertNotAvailable(PackageManager.FEATURE_CAMERA_ANY);
+            assertNotAvailable(PackageManager.FEATURE_CAMERA_LEVEL_FULL);
+            assertNotAvailable(PackageManager.FEATURE_CAMERA_CAPABILITY_MANUAL_SENSOR);
+            assertNotAvailable(PackageManager.FEATURE_CAMERA_CAPABILITY_MANUAL_POST_PROCESSING);
+            assertNotAvailable(PackageManager.FEATURE_CAMERA_CAPABILITY_RAW);
+
+            assertFalse("Devices supporting external cameras must have a representative camera " +
+                    "connected for testing",
+                    mPackageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_EXTERNAL));
+        } else {
+            assertAvailable(PackageManager.FEATURE_CAMERA_ANY);
+            checkFrontCamera();
+            checkRearCamera();
+            checkCamera2Features();
+        }
+    }
+
+    private void checkCamera2Features() throws Exception {
+        String[] cameraIds = mCameraManager.getCameraIdList();
+        boolean fullCamera = false;
+        boolean manualSensor = false;
+        boolean manualPostProcessing = false;
+        boolean raw = false;
+        CameraCharacteristics[] cameraChars = new CameraCharacteristics[cameraIds.length];
+        for (String cameraId : cameraIds) {
+            CameraCharacteristics chars = mCameraManager.getCameraCharacteristics(cameraId);
+            Integer hwLevel = chars.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);
+            int[] capabilities = chars.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES);
+            if (hwLevel == CameraMetadata.INFO_SUPPORTED_HARDWARE_LEVEL_FULL ||
+                    hwLevel >= CameraMetadata.INFO_SUPPORTED_HARDWARE_LEVEL_3) {
+                fullCamera = true;
+            }
+            for (int capability : capabilities) {
+                switch (capability) {
+                    case CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR:
+                        manualSensor = true;
+                        break;
+                    case CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING:
+                        manualPostProcessing = true;
+                        break;
+                    case CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_RAW:
+                        raw = true;
+                        break;
+                    default:
+                        // Capabilities don't have a matching system feature
+                        break;
+                }
+            }
+        }
+        assertFeature(fullCamera, PackageManager.FEATURE_CAMERA_LEVEL_FULL);
+        assertFeature(manualSensor, PackageManager.FEATURE_CAMERA_CAPABILITY_MANUAL_SENSOR);
+        assertFeature(manualPostProcessing,
+                PackageManager.FEATURE_CAMERA_CAPABILITY_MANUAL_POST_PROCESSING);
+        assertFeature(raw, PackageManager.FEATURE_CAMERA_CAPABILITY_RAW);
+    }
+
+    private void checkFrontCamera() {
+        CameraInfo info = new CameraInfo();
+        int numCameras = Camera.getNumberOfCameras();
+        int frontCameraId = -1;
+        for (int i = 0; i < numCameras; i++) {
+            Camera.getCameraInfo(i, info);
+            if (info.facing == CameraInfo.CAMERA_FACING_FRONT) {
+                frontCameraId = i;
+            }
+        }
+
+        if (frontCameraId > -1) {
+            assertTrue("Device has front-facing camera but does not report either " +
+                    "the FEATURE_CAMERA_FRONT or FEATURE_CAMERA_EXTERNAL feature",
+                    mPackageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_FRONT) ||
+                    mPackageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_EXTERNAL));
+        } else {
+            assertFalse("Device does not have front-facing camera but reports either " +
+                    "the FEATURE_CAMERA_FRONT or FEATURE_CAMERA_EXTERNAL feature",
+                    mPackageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_FRONT) ||
+                    mPackageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_EXTERNAL));
+        }
+    }
+
+    private void checkRearCamera() {
+        Camera camera = null;
+        try {
+            camera = Camera.open();
+            if (camera != null) {
+                assertAvailable(PackageManager.FEATURE_CAMERA);
+
+                Camera.Parameters params = camera.getParameters();
+                if (params.getSupportedFocusModes().contains(Parameters.FOCUS_MODE_AUTO)) {
+                    assertAvailable(PackageManager.FEATURE_CAMERA_AUTOFOCUS);
+                } else {
+                    assertNotAvailable(PackageManager.FEATURE_CAMERA_AUTOFOCUS);
+                }
+
+                if (params.getFlashMode() != null) {
+                    assertAvailable(PackageManager.FEATURE_CAMERA_FLASH);
+                } else {
+                    assertNotAvailable(PackageManager.FEATURE_CAMERA_FLASH);
+                }
+            } else {
+                assertNotAvailable(PackageManager.FEATURE_CAMERA);
+                assertNotAvailable(PackageManager.FEATURE_CAMERA_AUTOFOCUS);
+                assertNotAvailable(PackageManager.FEATURE_CAMERA_FLASH);
+            }
+        } finally {
+            if (camera != null) {
+                camera.release();
+            }
+        }
+    }
+
+    public void testLiveWallpaperFeature() {
+        try {
+            Intent intent = new Intent(WallpaperManager.ACTION_LIVE_WALLPAPER_CHOOSER);
+            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            mContext.startActivity(intent);
+            assertAvailable(PackageManager.FEATURE_LIVE_WALLPAPER);
+        } catch (ActivityNotFoundException e) {
+            assertNotAvailable(PackageManager.FEATURE_LIVE_WALLPAPER);
+        }
+    }
+
+    public void testLocationFeatures() {
+        if (mLocationManager.getProvider(LocationManager.GPS_PROVIDER) != null) {
+            assertAvailable(PackageManager.FEATURE_LOCATION);
+            assertAvailable(PackageManager.FEATURE_LOCATION_GPS);
+        } else {
+            assertNotAvailable(PackageManager.FEATURE_LOCATION_GPS);
+        }
+
+        if (mLocationManager.getProvider(LocationManager.NETWORK_PROVIDER) != null) {
+            assertAvailable(PackageManager.FEATURE_LOCATION);
+            assertAvailable(PackageManager.FEATURE_LOCATION_NETWORK);
+        } else {
+            assertNotAvailable(PackageManager.FEATURE_LOCATION_NETWORK);
+        }
+    }
+
+    public void testNfcFeatures() {
+        if (NfcAdapter.getDefaultAdapter(mContext) != null) {
+            assertAvailable(PackageManager.FEATURE_NFC);
+            assertAvailable(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION);
+        } else {
+            assertNotAvailable(PackageManager.FEATURE_NFC);
+        }
+    }
+
+    public void testScreenFeatures() {
+        assertTrue(mPackageManager.hasSystemFeature(PackageManager.FEATURE_SCREEN_LANDSCAPE)
+                || mPackageManager.hasSystemFeature(PackageManager.FEATURE_SCREEN_PORTRAIT));
+    }
+
+    /**
+     * Check that the sensor features reported by the PackageManager correspond to the sensors
+     * returned by {@link SensorManager#getSensorList(int)}.
+     */
+    public void testSensorFeatures() throws Exception {
+        Set<String> featuresLeft = getFeatureConstantsNames("FEATURE_SENSOR_");
+
+        assertFeatureForSensor(featuresLeft, PackageManager.FEATURE_SENSOR_ACCELEROMETER,
+                Sensor.TYPE_ACCELEROMETER);
+        assertFeatureForSensor(featuresLeft, PackageManager.FEATURE_SENSOR_BAROMETER,
+                Sensor.TYPE_PRESSURE);
+        assertFeatureForSensor(featuresLeft, PackageManager.FEATURE_SENSOR_COMPASS,
+                Sensor.TYPE_MAGNETIC_FIELD);
+        assertFeatureForSensor(featuresLeft, PackageManager.FEATURE_SENSOR_GYROSCOPE,
+                Sensor.TYPE_GYROSCOPE);
+        assertFeatureForSensor(featuresLeft, PackageManager.FEATURE_SENSOR_LIGHT,
+                Sensor.TYPE_LIGHT);
+        assertFeatureForSensor(featuresLeft, PackageManager.FEATURE_SENSOR_PROXIMITY,
+                Sensor.TYPE_PROXIMITY);
+        assertFeatureForSensor(featuresLeft, PackageManager.FEATURE_SENSOR_STEP_COUNTER,
+                Sensor.TYPE_STEP_COUNTER);
+        assertFeatureForSensor(featuresLeft, PackageManager.FEATURE_SENSOR_STEP_DETECTOR,
+                Sensor.TYPE_STEP_DETECTOR);
+        assertFeatureForSensor(featuresLeft, PackageManager.FEATURE_SENSOR_AMBIENT_TEMPERATURE,
+                Sensor.TYPE_AMBIENT_TEMPERATURE);
+        assertFeatureForSensor(featuresLeft, PackageManager.FEATURE_SENSOR_RELATIVE_HUMIDITY,
+                Sensor.TYPE_RELATIVE_HUMIDITY);
+
+
+        /*
+         * We have three cases to test for :
+         * Case 1:  Device does not have an HRM
+         * FEATURE_SENSOR_HEART_RATE               false
+         * FEATURE_SENSOR_HEART_RATE_ECG           false
+         * assertFeatureForSensor(TYPE_HEART_RATE) false
+         *
+         * Case 2:  Device has a PPG HRM
+         * FEATURE_SENSOR_HEART_RATE               true
+         * FEATURE_SENSOR_HEART_RATE_ECG           false
+         * assertFeatureForSensor(TYPE_HEART_RATE) true
+         *
+         * Case 3:  Device has an ECG HRM
+         * FEATURE_SENSOR_HEART_RATE               false
+         * FEATURE_SENSOR_HEART_RATE_ECG           true
+         * assertFeatureForSensor(TYPE_HEART_RATE) true
+         */
+
+        if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_SENSOR_HEART_RATE_ECG)) {
+                /* Case 3 for FEATURE_SENSOR_HEART_RATE_ECG true case */
+                assertFeatureForSensor(featuresLeft, PackageManager.FEATURE_SENSOR_HEART_RATE_ECG,
+                        Sensor.TYPE_HEART_RATE);
+
+                /* Remove HEART_RATE from featuresLeft, no way to test that one */
+                assertTrue("Features left " + featuresLeft + " to check did not include "
+                        + PackageManager.FEATURE_SENSOR_HEART_RATE,
+                        featuresLeft.remove(PackageManager.FEATURE_SENSOR_HEART_RATE));
+        } else if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_SENSOR_HEART_RATE)) {
+                /* Case 1 & 2 for FEATURE_SENSOR_HEART_RATE_ECG false case */
+                assertFeatureForSensor(featuresLeft, PackageManager.FEATURE_SENSOR_HEART_RATE_ECG,
+                        Sensor.TYPE_HEART_RATE);
+
+                /* Case 1 & 3 for FEATURE_SENSOR_HEART_RATE false case */
+                assertFeatureForSensor(featuresLeft, PackageManager.FEATURE_SENSOR_HEART_RATE,
+                        Sensor.TYPE_HEART_RATE);
+        } else {
+                /* Case 2 for FEATURE_SENSOR_HEART_RATE true case */
+                assertFeatureForSensor(featuresLeft, PackageManager.FEATURE_SENSOR_HEART_RATE,
+                        Sensor.TYPE_HEART_RATE);
+
+                /* Remove HEART_RATE_ECG from featuresLeft, no way to test that one */
+                assertTrue("Features left " + featuresLeft + " to check did not include "
+                        + PackageManager.FEATURE_SENSOR_HEART_RATE_ECG,
+                        featuresLeft.remove(PackageManager.FEATURE_SENSOR_HEART_RATE_ECG));
+        }
+
+        assertTrue("Assertions need to be added to this test for " + featuresLeft,
+                featuresLeft.isEmpty());
+    }
+
+    /** Get a list of feature constants in PackageManager matching a prefix. */
+    private static Set<String> getFeatureConstantsNames(String prefix)
+            throws IllegalArgumentException, IllegalAccessException {
+        Set<String> features = new HashSet<String>();
+        Field[] fields = PackageManager.class.getFields();
+        for (Field field : fields) {
+            if (field.getName().startsWith(prefix)) {
+                String feature = (String) field.get(null);
+                features.add(feature);
+            }
+        }
+        return features;
+    }
+
+    public void testSipFeatures() {
+        if (SipManager.newInstance(mContext) != null) {
+            assertAvailable(PackageManager.FEATURE_SIP);
+        } else {
+            assertNotAvailable(PackageManager.FEATURE_SIP);
+            assertNotAvailable(PackageManager.FEATURE_SIP_VOIP);
+        }
+
+        if (SipManager.isApiSupported(mContext)) {
+            assertAvailable(PackageManager.FEATURE_SIP);
+        } else {
+            assertNotAvailable(PackageManager.FEATURE_SIP);
+            assertNotAvailable(PackageManager.FEATURE_SIP_VOIP);
+        }
+
+        if (SipManager.isVoipSupported(mContext)) {
+            assertAvailable(PackageManager.FEATURE_SIP);
+            assertAvailable(PackageManager.FEATURE_SIP_VOIP);
+        } else {
+            assertNotAvailable(PackageManager.FEATURE_SIP_VOIP);
+        }
+    }
+
+    /**
+     * Check that if the PackageManager declares a sensor feature that the device has at least
+     * one sensor that matches that feature. Also check that if a PackageManager does not declare
+     * a sensor that the device also does not have such a sensor.
+     *
+     * @param featuresLeft to check in order to make sure the test covers all sensor features
+     * @param expectedFeature that the PackageManager may report
+     * @param expectedSensorType that that {@link SensorManager#getSensorList(int)} may have
+     */
+    private void assertFeatureForSensor(Set<String> featuresLeft, String expectedFeature,
+            int expectedSensorType) {
+        assertTrue("Features left " + featuresLeft + " to check did not include "
+                + expectedFeature, featuresLeft.remove(expectedFeature));
+
+        boolean hasSensorFeature = mPackageManager.hasSystemFeature(expectedFeature);
+
+        List<Sensor> sensors = mSensorManager.getSensorList(expectedSensorType);
+        List<String> sensorNames = new ArrayList<String>(sensors.size());
+        for (Sensor sensor : sensors) {
+            sensorNames.add(sensor.getName());
+        }
+        boolean hasSensorType = !sensors.isEmpty();
+
+        String message = "PackageManager#hasSystemFeature(" + expectedFeature + ") returns "
+                + hasSensorFeature
+                + " but SensorManager#getSensorList(" + expectedSensorType + ") shows sensors "
+                + sensorNames;
+
+        assertEquals(message, hasSensorFeature, hasSensorType);
+    }
+
+    /**
+     * Check that the {@link TelephonyManager#getPhoneType()} matches the reported features.
+     */
+    public void testTelephonyFeatures() {
+        if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
+            return;
+        }
+
+        int phoneType = mTelephonyManager.getPhoneType();
+        switch (phoneType) {
+            case TelephonyManager.PHONE_TYPE_GSM:
+                assertAvailable(PackageManager.FEATURE_TELEPHONY_GSM);
+                break;
+
+            case TelephonyManager.PHONE_TYPE_CDMA:
+                assertAvailable(PackageManager.FEATURE_TELEPHONY_CDMA);
+                break;
+
+            case TelephonyManager.PHONE_TYPE_NONE:
+                fail("FEATURE_TELEPHONY is present; phone type should not be PHONE_TYPE_NONE");
+                break;
+
+            default:
+                throw new IllegalArgumentException("Did you add a new phone type? " + phoneType);
+        }
+    }
+
+    public void testTouchScreenFeatures() {
+        ConfigurationInfo configInfo = mActivityManager.getDeviceConfigurationInfo();
+        if (configInfo.reqTouchScreen != Configuration.TOUCHSCREEN_NOTOUCH) {
+            assertAvailable(PackageManager.FEATURE_TOUCHSCREEN);
+            assertAvailable(PackageManager.FEATURE_FAKETOUCH);
+        } else {
+            assertNotAvailable(PackageManager.FEATURE_TOUCHSCREEN);
+        }
+
+        // TODO: Add tests for the other touchscreen features.
+    }
+
+    public void testUsbAccessory() {
+        assertAvailable(PackageManager.FEATURE_USB_ACCESSORY);
+    }
+
+    public void testWifiFeature() throws Exception {
+        if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI)) {
+            // no WiFi, skip the test
+            return;
+        }
+        boolean enabled = mWifiManager.isWifiEnabled();
+        try {
+            // WifiManager is hard-coded to return true,
+            // the case without WiFi is already handled,
+            // so this case MUST have WiFi.
+            if (mWifiManager.setWifiEnabled(true)) {
+                assertAvailable(PackageManager.FEATURE_WIFI);
+            }
+        } finally {
+            if (!enabled) {
+                mWifiManager.setWifiEnabled(false);
+            }
+        }
+    }
+
+    private void assertAvailable(String feature) {
+        assertTrue("PackageManager#hasSystemFeature should return true for " + feature,
+                mPackageManager.hasSystemFeature(feature));
+        assertTrue("PackageManager#getSystemAvailableFeatures should have " + feature,
+                mAvailableFeatures.contains(feature));
+    }
+
+    private void assertNotAvailable(String feature) {
+        assertFalse("PackageManager#hasSystemFeature should NOT return true for " + feature,
+                mPackageManager.hasSystemFeature(feature));
+        assertFalse("PackageManager#getSystemAvailableFeatures should NOT have " + feature,
+                mAvailableFeatures.contains(feature));
+    }
+
+    private void assertFeature(boolean exist, String feature) {
+        if (exist) {
+            assertAvailable(feature);
+        } else {
+            assertNotAvailable(feature);
+        }
+    }
+}
diff --git a/tests/app/src/android/app/cts/TabActivityTest.java b/tests/app/src/android/app/cts/TabActivityTest.java
new file mode 100644
index 0000000..77a17e8
--- /dev/null
+++ b/tests/app/src/android/app/cts/TabActivityTest.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.cts;
+
+import android.app.Activity;
+import android.app.Instrumentation;
+import android.app.TabActivity;
+import android.app.stubs.MockTabActivity;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.test.InstrumentationTestCase;
+import android.test.UiThreadTest;
+import android.widget.TabHost;
+
+public class TabActivityTest extends InstrumentationTestCase {
+    private Instrumentation mInstrumentation;
+    private MockTabActivity mActivity;
+    private Activity mChildActivity;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mInstrumentation = super.getInstrumentation();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        if (mActivity != null) {
+            if (!mActivity.isFinishing()) {
+                mActivity.finish();
+            } else if (mChildActivity != null) {
+                if (!mChildActivity.isFinishing()) {
+                    mChildActivity.finish();
+                }
+            }
+        }
+        super.tearDown();
+    }
+
+    public void testTabActivity() throws Throwable {
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                // Test constructor
+                new TabActivity();
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+        final String packageName = "android.app.stubs";
+        final Intent intent = new Intent(Intent.ACTION_MAIN);
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        intent.setClassName(packageName, MockTabActivity.class.getName());
+        mActivity = (MockTabActivity) mInstrumentation.startActivitySync(intent);
+        // Test onPostCreate, onContentChanged. These two methods are invoked in starting
+        // activity. Default values of isOnContentChangedCalled, isOnPostCreateCalled are false.
+        assertTrue(mActivity.isOnContentChangedCalled);
+        assertTrue(mActivity.isOnPostCreateCalled);
+
+        // Can't get default value.
+        final int defaultIndex = 1;
+        mActivity.setDefaultTab(defaultIndex);
+        final String defaultTab = "DefaultTab";
+        mActivity.setDefaultTab(defaultTab);
+        // Test getTabHost, getTabWidget
+        final TabHost tabHost = mActivity.getTabHost();
+        assertNotNull(tabHost);
+        assertNotNull(tabHost.getTabWidget());
+    }
+
+    @UiThreadTest
+    public void testChildTitleCallback() throws Exception {
+        final Context context = mInstrumentation.getTargetContext();
+        final Intent intent = new Intent(context, MockTabActivity.class);
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
+        final MockTabActivity father = new MockTabActivity();
+        final ComponentName componentName = new ComponentName(context, MockTabActivity.class);
+        final ActivityInfo info = context.getPackageManager().getActivityInfo(componentName, 0);
+        mChildActivity = mInstrumentation.newActivity(MockTabActivity.class, mInstrumentation
+                .getTargetContext(), null, null, intent, info, MockTabActivity.class.getName(),
+                father, null, null);
+
+        assertNotNull(mChildActivity);
+        final String newTitle = "New Title";
+        mChildActivity.setTitle(newTitle);
+        assertTrue(father.isOnChildTitleChangedCalled);
+    }
+}
diff --git a/tests/app/src/android/app/cts/TestDialog.java b/tests/app/src/android/app/cts/TestDialog.java
deleted file mode 100644
index 7effc79..0000000
--- a/tests/app/src/android/app/cts/TestDialog.java
+++ /dev/null
@@ -1,320 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-import android.app.Dialog;
-import android.content.Context;
-import android.os.Bundle;
-import android.view.ContextMenu;
-import android.view.KeyEvent;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.Window;
-import android.view.ContextMenu.ContextMenuInfo;
-import android.view.WindowManager.LayoutParams;
-
-public class TestDialog extends Dialog {
-    private static final int OPTIONS_MENU_ITEM_0 = Menu.FIRST;
-    private static final int OPTIONS_MENU_ITEM_1 = Menu.FIRST + 1;
-    private static final int OPTIONS_MENU_ITEM_2 = Menu.FIRST + 2;
-    private static final int OPTIONS_MENU_ITEM_3 = Menu.FIRST + 3;
-    private static final int OPTIONS_MENU_ITEM_4 = Menu.FIRST + 4;
-    private static final int OPTIONS_MENU_ITEM_5 = Menu.FIRST + 5;
-    private static final int OPTIONS_MENU_ITEM_6 = Menu.FIRST + 6;
-    private static final int CONTEXT_MENU_ITEM_0 = Menu.FIRST + 7;
-    private static final int CONTEXT_MENU_ITEM_1 = Menu.FIRST + 8;
-    private static final int CONTEXT_MENU_ITEM_2 = Menu.FIRST + 9;
-    public boolean isOnStartCalled;
-    public boolean isOnStopCalled;
-    public boolean isOnCreateCalled;
-    public boolean isRequestWindowFeature;
-    public boolean isOnContentChangedCalled;
-    public boolean isOnWindowFocusChangedCalled;
-    public boolean isOnTouchEventCalled;
-    public boolean isOnTrackballEventCalled;
-    public boolean isOnKeyDownCalled;
-    public boolean isOnKeyUpCalled;
-    public boolean isOnKeyMultipleCalled;
-    public boolean isOnSaveInstanceStateCalled;
-    public static boolean isOnRestoreInstanceStateCalled;
-    public boolean isOnWindowAttributesChangedCalled;
-    public boolean isOnCreatePanelMenuCalled;
-    public boolean isOnCreatePanelViewCalled;
-    public boolean isOnPreparePanelCalled;
-    public boolean isOnMenuOpenedCalled;
-    public boolean isOnMenuItemSelectedCalled;
-    public boolean isOnPanelClosedCalled;
-    public boolean isOnCreateOptionsMenuCalled;
-    public boolean isOnPrepareOptionsMenuCalled;
-    public boolean isOnOptionsItemSelectedCalled;
-    public boolean isOnOptionsMenuClosedCalled;
-    public boolean isOnContextItemSelectedCalled;
-    public boolean isOnContextMenuClosedCalled;
-    public boolean isOnCreateContextMenuCalled;
-    public boolean isOnSearchRequestedCalled;
-    public boolean onKeyDownReturn;
-    public boolean onKeyMultipleReturn;
-    public boolean dispatchTouchEventResult;
-    public boolean dispatchKeyEventResult;
-    public int keyDownCode = -1;
-    public Window window;
-    public Bundle saveInstanceState;
-    public Bundle savedInstanceState;
-    public KeyEvent keyEvent;
-    public MotionEvent touchEvent;
-    public MotionEvent trackballEvent;
-    public MotionEvent onTrackballEvent;
-    public MotionEvent onTouchEvent;
-    public KeyEvent keyMultipleEvent;
-
-    public TestDialog(Context context) {
-        super(context);
-    }
-
-    public TestDialog(Context context, int theme) {
-        super(context, theme);
-    }
-
-    public TestDialog(Context context, boolean cancelable, OnCancelListener cancelListener) {
-        super(context, cancelable, cancelListener);
-    }
-
-    @Override
-    protected void onStart() {
-        super.onStart();
-        isOnStartCalled = true;
-    }
-
-    @Override
-    protected void onStop() {
-        super.onStop();
-        isOnStopCalled = true;
-    }
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        isRequestWindowFeature = requestWindowFeature(Window.FEATURE_LEFT_ICON);
-        super.onCreate(savedInstanceState);
-        isOnCreateCalled = true;
-    }
-
-    @Override
-    public void onContentChanged() {
-        super.onContentChanged();
-
-        isOnContentChangedCalled = true;
-    }
-
-    @Override
-    public void onWindowFocusChanged(boolean hasFocus) {
-        super.onWindowFocusChanged(hasFocus);
-
-        isOnWindowFocusChangedCalled = true;
-    }
-
-    @Override
-    public boolean onTouchEvent(MotionEvent event) {
-        isOnTouchEventCalled = true;
-        onTouchEvent = event;
-        return super.onTouchEvent(event);
-    }
-
-    @Override
-    public boolean onTrackballEvent(MotionEvent event) {
-        isOnTrackballEventCalled = true;
-        onTrackballEvent = event;
-        return super.onTrackballEvent(event);
-    }
-
-    @Override
-    public boolean onKeyDown(int keyCode, KeyEvent event) {
-        isOnKeyDownCalled = true;
-        keyDownCode = keyCode;
-        onKeyDownReturn = super.onKeyDown(keyCode, event);
-
-        return onKeyDownReturn;
-    }
-
-    @Override
-    public boolean onKeyUp(int keyCode, KeyEvent event) {
-        isOnKeyUpCalled = true;
-
-        return super.onKeyUp(keyCode, event);
-    }
-
-    @Override
-    public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) {
-        isOnKeyMultipleCalled = true;
-        onKeyMultipleReturn = super.onKeyMultiple(keyCode, repeatCount, event);
-        keyMultipleEvent = event;
-        return onKeyMultipleReturn;
-    }
-
-    @Override
-    public Bundle onSaveInstanceState() {
-        isOnSaveInstanceStateCalled = true;
-        saveInstanceState = super.onSaveInstanceState();
-        return saveInstanceState;
-    }
-
-    @Override
-    public void onRestoreInstanceState(Bundle savedInstanceState) {
-        isOnRestoreInstanceStateCalled = true;
-        this.savedInstanceState = savedInstanceState;
-
-        super.onRestoreInstanceState(savedInstanceState);
-    }
-
-    @Override
-    public void onWindowAttributesChanged(LayoutParams params) {
-        isOnWindowAttributesChangedCalled = true;
-        super.onWindowAttributesChanged(params);
-    }
-
-    @Override
-    public boolean onCreatePanelMenu(int featureId, Menu menu) {
-        isOnCreatePanelMenuCalled = true;
-        return super.onCreatePanelMenu(featureId, menu);
-    }
-
-    @Override
-    public View onCreatePanelView(int featureId) {
-        isOnCreatePanelViewCalled = true;
-        return super.onCreatePanelView(featureId);
-    }
-
-    @Override
-    public boolean onPreparePanel(int featureId, View view, Menu menu) {
-        isOnPreparePanelCalled = true;
-        return super.onPreparePanel(featureId, view, menu);
-    }
-
-    @Override
-    public boolean onMenuItemSelected(int featureId, MenuItem item) {
-        isOnMenuItemSelectedCalled = true;
-        return super.onMenuItemSelected(featureId, item);
-    }
-
-    @Override
-    public boolean onMenuOpened(int featureId, Menu menu) {
-        isOnMenuOpenedCalled = true;
-        return super.onMenuOpened(featureId, menu);
-    }
-
-    @Override
-    public void onPanelClosed(int featureId, Menu menu) {
-        isOnPanelClosedCalled = true;
-        super.onPanelClosed(featureId, menu);
-    }
-
-    @Override
-    public boolean onPrepareOptionsMenu(Menu menu) {
-        isOnPrepareOptionsMenuCalled = true;
-        return super.onPrepareOptionsMenu(menu);
-    }
-
-    @Override
-    public boolean onCreateOptionsMenu(Menu menu) {
-        super.onCreateOptionsMenu(menu);
-        menu.add(0, OPTIONS_MENU_ITEM_0, 0, "OptionsMenuItem0");
-        menu.add(0, OPTIONS_MENU_ITEM_1, 0, "OptionsMenuItem1");
-        menu.add(0, OPTIONS_MENU_ITEM_2, 0, "OptionsMenuItem2");
-        menu.add(0, OPTIONS_MENU_ITEM_3, 0, "OptionsMenuItem3");
-        menu.add(0, OPTIONS_MENU_ITEM_4, 0, "OptionsMenuItem4");
-        menu.add(0, OPTIONS_MENU_ITEM_5, 0, "OptionsMenuItem5");
-        menu.add(0, OPTIONS_MENU_ITEM_6, 0, "OptionsMenuItem6");
-        isOnCreateOptionsMenuCalled = true;
-        return true;
-    }
-
-    @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
-        isOnOptionsItemSelectedCalled = true;
-        switch (item.getItemId()) {
-            case OPTIONS_MENU_ITEM_0:
-            case OPTIONS_MENU_ITEM_1:
-            case OPTIONS_MENU_ITEM_2:
-            case OPTIONS_MENU_ITEM_3:
-            case OPTIONS_MENU_ITEM_4:
-            case OPTIONS_MENU_ITEM_5:
-            case OPTIONS_MENU_ITEM_6:
-                return true;
-            default:
-                return super.onOptionsItemSelected(item);
-        }
-    }
-
-    @Override
-    public void onOptionsMenuClosed(Menu menu) {
-        isOnOptionsMenuClosedCalled = true;
-        super.onOptionsMenuClosed(menu);
-    }
-
-    @Override
-    public boolean onContextItemSelected(MenuItem item) {
-        isOnContextItemSelectedCalled = true;
-        switch (item.getItemId()) {
-            case CONTEXT_MENU_ITEM_0:
-            case CONTEXT_MENU_ITEM_1:
-            case CONTEXT_MENU_ITEM_2:
-                return true;
-            default:
-                return super.onContextItemSelected(item);
-        }
-    }
-
-    @Override
-    public void onContextMenuClosed(Menu menu) {
-        isOnContextMenuClosedCalled = true;
-        super.onContextMenuClosed(menu);
-    }
-
-    @Override
-    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
-        menu.add(0, CONTEXT_MENU_ITEM_0, 0, "ContextMenuItem0");
-        menu.add(0, CONTEXT_MENU_ITEM_1, 0, "ContextMenuItem1");
-        menu.add(0, CONTEXT_MENU_ITEM_2, 0, "ContextMenuItem2");
-        isOnCreateContextMenuCalled = true;
-    }
-
-    @Override
-    public boolean onSearchRequested() {
-        isOnSearchRequestedCalled = true;
-        return super.onSearchRequested();
-    }
-
-    @Override
-    public boolean dispatchKeyEvent(KeyEvent event) {
-        keyEvent = event;
-        dispatchKeyEventResult = super.dispatchKeyEvent(event);
-        return dispatchKeyEventResult;
-    }
-
-    @Override
-    public boolean dispatchTrackballEvent(MotionEvent ev) {
-        trackballEvent = ev;
-        return super.dispatchTrackballEvent(ev);
-    }
-
-    @Override
-    public boolean dispatchTouchEvent(MotionEvent ev) {
-        touchEvent = ev;
-        dispatchTouchEventResult = super.dispatchTouchEvent(ev);
-        return dispatchTouchEventResult;
-    }
-}
diff --git a/tests/app/src/android/app/cts/TestedActivity.java b/tests/app/src/android/app/cts/TestedActivity.java
deleted file mode 100644
index b6565bf..0000000
--- a/tests/app/src/android/app/cts/TestedActivity.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.os.Looper;
-import android.os.MessageQueue;
-import android.util.Log;
-
-public class TestedActivity extends Activity {
-    private static final String TAG = "TestedActivity" ;
-    public TestedActivity() {
-    }
-
-    public void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-    }
-
-    protected void onRestoreInstanceState(Bundle state) {
-        super.onRestoreInstanceState(state);
-    }
-
-    protected void onResume() {
-        super.onResume();
-        Looper.myLooper();
-        Looper.myQueue().addIdleHandler(new Idler());
-    }
-
-    protected void onSaveInstanceState(Bundle outState) {
-        super.onSaveInstanceState(outState);
-    }
-
-    protected void onStop() {
-        super.onStop();
-    }
-
-    private class Idler implements MessageQueue.IdleHandler {
-        public final boolean queueIdle() {
-            Log.i(TAG, "idle");
-            setResult(RESULT_OK);
-            finish();
-            return false;
-        }
-    }
-}
diff --git a/tests/app/src/android/app/cts/TestedScreen.java b/tests/app/src/android/app/cts/TestedScreen.java
deleted file mode 100644
index 052fb34..0000000
--- a/tests/app/src/android/app/cts/TestedScreen.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.os.MessageQueue;
-import android.os.SystemClock;
-import android.util.Log;
-
-public class TestedScreen extends Activity {
-    public static final String WAIT_BEFORE_FINISH = "TestedScreen.WAIT_BEFORE_FINISH";
-    public static final String DELIVER_RESULT = "TestedScreen.DELIVER_RESULT";
-    public static final String CLEAR_TASK = "TestedScreen.CLEAR_TASK";
-    private static final String TAG = "TestedScreen" ;
-    public TestedScreen() {
-    }
-
-    @Override
-    public void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-        if (LaunchpadActivity.FORWARD_RESULT.equals(getIntent().getAction())) {
-            final Intent intent = new Intent(getIntent());
-            intent.setAction(DELIVER_RESULT);
-            intent.setFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
-            startActivity(intent);
-            finish();
-        } else if (DELIVER_RESULT.equals(getIntent().getAction())) {
-            setResult(RESULT_OK, new Intent().setAction(LaunchpadActivity.RETURNED_RESULT));
-            finish();
-        } else if (CLEAR_TASK.equals(getIntent().getAction())) {
-            if (!getIntent().getBooleanExtra(ClearTop.WAIT_CLEAR_TASK, false)) {
-                launchClearTask();
-            }
-        }
-    }
-
-    @Override
-    protected void onRestoreInstanceState(Bundle state) {
-        super.onRestoreInstanceState(state);
-    }
-
-    @Override
-    protected void onResume() {
-        super.onResume();
-        if (CLEAR_TASK.equals(getIntent().getAction())) {
-            if (getIntent().getBooleanExtra(ClearTop.WAIT_CLEAR_TASK, false)) {
-                Looper.myLooper();
-                Looper.myQueue().addIdleHandler(new Idler());
-            }
-        } else {
-            Looper.myLooper();
-            Looper.myQueue().addIdleHandler(new Idler());
-        }
-    }
-
-    @Override
-    protected void onSaveInstanceState(Bundle outState) {
-        super.onSaveInstanceState(outState);
-    }
-
-    @Override
-    protected void onStop() {
-        super.onStop();
-    }
-
-    private void launchClearTask() {
-        final Intent intent = new Intent(getIntent()).addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
-                .setClass(this, ClearTop.class);
-        startActivity(intent);
-    }
-
-    private final Handler mHandler = new Handler() {
-        @Override
-        public void handleMessage(Message msg) {
-            if (CLEAR_TASK.equals(getIntent().getAction())) {
-                launchClearTask();
-            } else {
-                setResult(RESULT_OK);
-                finish();
-            }
-        }
-    };
-
-    private class Idler implements MessageQueue.IdleHandler {
-        public final boolean queueIdle() {
-            Log.i(TAG, "idle");
-            if (WAIT_BEFORE_FINISH.equals(getIntent().getAction())) {
-                final Message m = Message.obtain();
-                mHandler.sendMessageAtTime(m, SystemClock.uptimeMillis() + 1000);
-            } else if (CLEAR_TASK.equals(getIntent().getAction())) {
-                final Message m = Message.obtain();
-                mHandler.sendMessageAtTime(m, SystemClock.uptimeMillis() + 1000);
-            } else {
-                setResult(RESULT_OK);
-                finish();
-            }
-            return false;
-        }
-    }
-}
diff --git a/tests/app/src/android/app/cts/TimePickerDialogTest.java b/tests/app/src/android/app/cts/TimePickerDialogTest.java
new file mode 100644
index 0000000..3da25ab
--- /dev/null
+++ b/tests/app/src/android/app/cts/TimePickerDialogTest.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.cts;
+
+import android.app.TimePickerDialog;
+import android.app.TimePickerDialog.OnTimeSetListener;
+import android.app.stubs.DialogStubActivity;
+import android.content.Context;
+import android.os.Bundle;
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.UiThreadTest;
+import android.widget.TimePicker;
+
+import android.app.stubs.R;
+
+/**
+ * Test {@link TimePickerDialog}.
+ */
+public class TimePickerDialogTest extends ActivityInstrumentationTestCase2<DialogStubActivity> {
+    private static final String HOUR = "hour";
+    private static final String MINUTE = "minute";
+    private static final String IS_24_HOUR = "is24hour";
+
+    private static final int TARGET_HOUR = 15;
+    private static final int TARGET_MINUTE = 9;
+
+    private int mCallbackHour;
+    private int mCallbackMinute;
+
+    private OnTimeSetListener mOnTimeSetListener;
+
+    private Context mContext;
+    private DialogStubActivity mActivity;
+
+    public TimePickerDialogTest() {
+        super("android.app.stubs", DialogStubActivity.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        mContext = getInstrumentation().getContext();
+        mOnTimeSetListener = new OnTimeSetListener(){
+            public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
+                mCallbackHour = hourOfDay;
+                mCallbackMinute = minute;
+            }
+        };
+    }
+
+    @UiThreadTest
+    public void testSaveInstanceState() {
+        TimePickerDialog tD = new TimePickerDialog(
+            mContext, mOnTimeSetListener, TARGET_HOUR, TARGET_MINUTE, true);
+
+        Bundle b = tD.onSaveInstanceState();
+
+        assertEquals(TARGET_HOUR, b.getInt(HOUR));
+        assertEquals(TARGET_MINUTE, b.getInt(MINUTE));
+        assertTrue(b.getBoolean(IS_24_HOUR));
+
+        int minute = 13;
+        tD = new TimePickerDialog(
+                mContext, R.style.Theme_AlertDialog,
+                    mOnTimeSetListener, TARGET_HOUR, minute, false);
+
+        b = tD.onSaveInstanceState();
+
+        assertEquals(TARGET_HOUR, b.getInt(HOUR));
+        assertEquals(minute, b.getInt(MINUTE));
+        assertFalse(b.getBoolean(IS_24_HOUR));
+    }
+
+    @UiThreadTest
+    public void testOnClick() {
+        TimePickerDialog timePickerDialog = buildDialog();
+        timePickerDialog.onClick(null, TimePickerDialog.BUTTON_POSITIVE);
+
+        assertEquals(TARGET_HOUR, mCallbackHour);
+        assertEquals(TARGET_MINUTE, mCallbackMinute);
+    }
+
+    public void testOnTimeChanged() throws Throwable {
+        final int minute = 34;
+        startDialogActivity(DialogStubActivity.TEST_TIMEPICKERDIALOG);
+        final TimePickerDialog d = (TimePickerDialog) mActivity.getDialog();
+
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                d.onTimeChanged(null, TARGET_HOUR, minute);
+            }
+        });
+        getInstrumentation().waitForIdleSync();
+
+    }
+
+    @UiThreadTest
+    public void testUpdateTime() {
+        TimePickerDialog timePickerDialog = buildDialog();
+        int minute = 18;
+        timePickerDialog.updateTime(TARGET_HOUR, minute);
+
+        // here call onSaveInstanceState is to check the data put by updateTime
+        Bundle b = timePickerDialog.onSaveInstanceState();
+
+        assertEquals(TARGET_HOUR, b.getInt(HOUR));
+        assertEquals(minute, b.getInt(MINUTE));
+    }
+
+    @UiThreadTest
+    public void testOnRestoreInstanceState() {
+        int minute = 27;
+        Bundle b1 = new Bundle();
+        b1.putInt(HOUR, TARGET_HOUR);
+        b1.putInt(MINUTE, minute);
+        b1.putBoolean(IS_24_HOUR, false);
+
+        TimePickerDialog timePickerDialog = buildDialog();
+        timePickerDialog.onRestoreInstanceState(b1);
+
+        //here call onSaveInstanceState is to check the data put by onRestoreInstanceState
+        Bundle b2 = timePickerDialog.onSaveInstanceState();
+
+        assertEquals(TARGET_HOUR, b2.getInt(HOUR));
+        assertEquals(minute, b2.getInt(MINUTE));
+        assertFalse(b2.getBoolean(IS_24_HOUR));
+    }
+
+    private void startDialogActivity(int dialogNumber) {
+        mActivity = DialogStubActivity.startDialogActivity(this, dialogNumber);
+    }
+
+    private TimePickerDialog buildDialog() {
+        return new TimePickerDialog(
+                mContext, mOnTimeSetListener, TARGET_HOUR, TARGET_MINUTE, true);
+    }
+}
diff --git a/tests/app/src/android/app/cts/UiModeManagerTest.java b/tests/app/src/android/app/cts/UiModeManagerTest.java
new file mode 100644
index 0000000..40fe0f5
--- /dev/null
+++ b/tests/app/src/android/app/cts/UiModeManagerTest.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.cts;
+
+import android.app.UiModeManager;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.res.Configuration;
+import android.test.AndroidTestCase;
+import android.util.Log;
+
+public class UiModeManagerTest extends AndroidTestCase {
+    private static final String TAG = "UiModeManagerTest";
+
+    private UiModeManager mUiModeManager;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mUiModeManager = (UiModeManager) getContext().getSystemService(Context.UI_MODE_SERVICE);
+        assertNotNull(mUiModeManager);
+    }
+
+    public void testUiMode() throws Exception {
+        if (isAutomotive()) {
+            Log.i(TAG, "testUiMode automotive");
+            doTestUiModeForAutomotive();
+        } else if (isTelevision()) {
+            assertEquals(Configuration.UI_MODE_TYPE_TELEVISION,
+                    mUiModeManager.getCurrentModeType());
+            doTestLockedUiMode();
+        } else if (isWatch()) {
+            assertEquals(Configuration.UI_MODE_TYPE_WATCH,
+                    mUiModeManager.getCurrentModeType());
+            doTestLockedUiMode();
+        } else {
+            Log.i(TAG, "testUiMode generic");
+            doTestUiModeGeneric();
+        }
+    }
+
+    public void testNightMode() throws Exception {
+        if (isAutomotive()) {
+            assertTrue(mUiModeManager.isNightModeLocked());
+            doTestLockedNightMode();
+        } else {
+            if (mUiModeManager.isNightModeLocked()) {
+                doTestLockedNightMode();
+            } else {
+                doTestUnlockedNightMode();
+            }
+        }
+    }
+
+    private boolean isAutomotive() {
+        return getContext().getPackageManager().hasSystemFeature(
+                PackageManager.FEATURE_AUTOMOTIVE);
+    }
+
+    private boolean isTelevision() {
+        PackageManager pm = getContext().getPackageManager();
+        return pm.hasSystemFeature(PackageManager.FEATURE_TELEVISION)
+                || pm.hasSystemFeature(PackageManager.FEATURE_LEANBACK);
+    }
+
+    private boolean isWatch() {
+        return getContext().getPackageManager().hasSystemFeature(
+                PackageManager.FEATURE_WATCH);
+    }
+
+    private void doTestUiModeForAutomotive() throws Exception {
+        assertEquals(Configuration.UI_MODE_TYPE_CAR, mUiModeManager.getCurrentModeType());
+        assertTrue(mUiModeManager.isUiModeLocked());
+        doTestLockedUiMode();
+    }
+
+    private void doTestUiModeGeneric() throws Exception {
+        if (mUiModeManager.isUiModeLocked()) {
+            doTestLockedUiMode();
+        } else {
+            doTestUnlockedUiMode();
+        }
+    }
+
+    private void doTestLockedUiMode() throws Exception {
+        int originalMode = mUiModeManager.getCurrentModeType();
+        mUiModeManager.enableCarMode(0);
+        assertEquals(originalMode, mUiModeManager.getCurrentModeType());
+        mUiModeManager.disableCarMode(0);
+        assertEquals(originalMode, mUiModeManager.getCurrentModeType());
+    }
+
+    private void doTestUnlockedUiMode() throws Exception {
+        mUiModeManager.enableCarMode(0);
+        assertEquals(Configuration.UI_MODE_TYPE_CAR, mUiModeManager.getCurrentModeType());
+        mUiModeManager.disableCarMode(0);
+        assertNotSame(Configuration.UI_MODE_TYPE_CAR, mUiModeManager.getCurrentModeType());
+    }
+
+    private void doTestLockedNightMode() throws Exception {
+        int currentMode = mUiModeManager.getNightMode();
+        if (currentMode == UiModeManager.MODE_NIGHT_YES) {
+            mUiModeManager.setNightMode(UiModeManager.MODE_NIGHT_NO);
+            assertEquals(currentMode, mUiModeManager.getNightMode());
+        } else {
+            mUiModeManager.setNightMode(UiModeManager.MODE_NIGHT_YES);
+            assertEquals(currentMode, mUiModeManager.getNightMode());
+        }
+    }
+
+    private void doTestUnlockedNightMode() throws Exception {
+        // day night mode should be settable regardless of car mode.
+        mUiModeManager.enableCarMode(0);
+        doTestAllNightModes();
+        mUiModeManager.disableCarMode(0);
+        doTestAllNightModes();
+    }
+
+    private void doTestAllNightModes() {
+        assertNightModeChange(UiModeManager.MODE_NIGHT_AUTO);
+        assertNightModeChange(UiModeManager.MODE_NIGHT_YES);
+        assertNightModeChange(UiModeManager.MODE_NIGHT_NO);
+    }
+
+    private void assertNightModeChange(int mode) {
+        mUiModeManager.setNightMode(mode);
+        assertEquals(mode, mUiModeManager.getNightMode());
+    }
+}
diff --git a/tests/app/src/android/app/cts/WallpaperManagerTest.java b/tests/app/src/android/app/cts/WallpaperManagerTest.java
new file mode 100644
index 0000000..9f66e15
--- /dev/null
+++ b/tests/app/src/android/app/cts/WallpaperManagerTest.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.cts;
+
+import android.app.WallpaperManager;
+import android.content.Context;
+import android.graphics.Point;
+import android.test.AndroidTestCase;
+import android.view.Display;
+import android.view.WindowManager;
+
+public class WallpaperManagerTest extends AndroidTestCase {
+
+    private WallpaperManager mWallpaperManager;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mWallpaperManager = WallpaperManager.getInstance(mContext);
+    }
+
+    /**
+     * Suggesting desired dimensions is only a hint to the system that can be ignored.
+     *
+     * Test if the desired minimum width or height the WallpaperManager returns
+     * is greater than 0. If so, then we check whether that the size is at least the
+     * as big as the screen.
+     */
+    public void testSuggestDesiredDimensions() {
+        final Point min = getScreenSize();
+        final int w = min.x * 3;
+        final int h = min.y * 2;
+        assertDesiredMinimum(new Point(min.x / 2, min.y / 2), min);
+
+        assertDesiredMinimum(new Point(w, h), min);
+
+        assertDesiredMinimum(new Point(min.x / 2, h), min);
+
+        assertDesiredMinimum(new Point(w, min.y / 2), min);
+    }
+
+    private void assertDesiredMinimum(Point suggestedSize, Point minSize) {
+        mWallpaperManager.suggestDesiredDimensions(suggestedSize.x, suggestedSize.y);
+        Point actualSize = new Point(mWallpaperManager.getDesiredMinimumWidth(),
+                mWallpaperManager.getDesiredMinimumHeight());
+        if (actualSize.x > 0 || actualSize.y > 0) {
+            if((actualSize.x < minSize.x || actualSize.y < minSize.y)){
+                throw new AssertionError("Expected at least x: " + minSize.x + " y: "
+                                         + minSize.y + ", got x: " + actualSize.x +
+                                         " y: " + actualSize.y );
+            }
+        }
+    }
+
+    private Point getScreenSize() {
+        WindowManager wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
+        Display d = wm.getDefaultDisplay();
+        Point p = new Point();
+        d.getRealSize(p);
+        return p;
+    }
+}
diff --git a/tests/aslr/Android.mk b/tests/aslr/Android.mk
new file mode 100644
index 0000000..ebee2a8
--- /dev/null
+++ b/tests/aslr/Android.mk
@@ -0,0 +1,62 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+test_executable := CtsAslrMallocTestCases
+list_executable := $(test_executable)_list
+
+include $(CLEAR_VARS)
+LOCAL_MODULE:= $(test_executable)
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA)/nativetest
+LOCAL_MULTILIB := both
+LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
+LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
+
+LOCAL_C_INCLUDES := \
+    external/gtest/include
+
+LOCAL_SRC_FILES := \
+    src/AslrMallocTest.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+    libbase \
+    libutils \
+    liblog \
+
+LOCAL_STATIC_LIBRARIES := \
+    libgtest
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+include $(BUILD_CTS_EXECUTABLE)
+
+include $(CLEAR_VARS)
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
+
+LOCAL_MODULE := $(list_executable)
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := \
+    src/AslrMallocTest.cpp
+
+LOCAL_CFLAGS := \
+    -DBUILD_ONLY \
+
+LOCAL_SHARED_LIBRARIES := \
+    liblog
+
+include $(BUILD_HOST_NATIVE_TEST)
diff --git a/tests/aslr/AndroidTest.xml b/tests/aslr/AndroidTest.xml
new file mode 100644
index 0000000..c04e1ab
--- /dev/null
+++ b/tests/aslr/AndroidTest.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS Aslr Malloc test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
+        <option name="cleanup" value="true" />
+        <option name="push" value="CtsAslrMallocTestCases->/data/local/tmp/CtsAslrMallocTestCases" />
+        <option name="append-bitness" value="true" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="CtsAslrMallocTestCases" />
+        <option name="runtime-hint" value="3m30s" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/aslr/src/AslrMallocTest.cpp b/tests/aslr/src/AslrMallocTest.cpp
new file mode 100644
index 0000000..6e773cb
--- /dev/null
+++ b/tests/aslr/src/AslrMallocTest.cpp
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 LOG_NDEBUG 0
+#define LOG_TAG "AslrMallocTest"
+
+#if !defined(BUILD_ONLY)
+#include <android-base/file.h>
+#include <android-base/parseint.h>
+#include <android-base/stringprintf.h>
+#include <android-base/strings.h>
+#include <linux/limits.h>
+#include <math.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <unordered_set>
+#endif
+
+#include <gtest/gtest.h>
+#include <string>
+#include <utils/Log.h>
+
+/* minimum entropy for malloc return addresses */
+const size_t minEntropyBits = 8;
+
+/* test using the following allocation sizes */
+const size_t allocSizes[] = {
+    1 << 8,     // small
+    1 << 16,    // large
+    1 << 23     // huge
+};
+
+/* when started using this argument followed by the allocation size,
+ * performs malloc(size) and prints out the address */
+static const std::string argPrint = "--print-malloc-address";
+
+#if !defined(BUILD_ONLY)
+class AslrMallocTest : public ::testing::Test
+{
+protected:
+    std::string self_;
+
+    AslrMallocTest() {}
+    virtual ~AslrMallocTest() {}
+
+    virtual void SetUp()
+    {
+        /* path to self for exec */
+        char path[PATH_MAX];
+        auto size = readlink("/proc/self/exe", path, sizeof(path));
+        ASSERT_TRUE(size > 0 && size < PATH_MAX);
+        path[size] = '\0';
+        self_ = path;
+    }
+
+    void GetAddress(size_t allocSize, uintptr_t& address)
+    {
+        int fds[2];
+        ASSERT_TRUE(pipe(fds) != -1);
+
+        auto pid = fork();
+        ASSERT_TRUE(pid != -1);
+
+        if (pid == 0) {
+            /* child process */
+            ASSERT_TRUE(TEMP_FAILURE_RETRY(dup2(fds[1], STDOUT_FILENO)) != -1);
+
+            for (auto fd : fds) {
+                TEMP_FAILURE_RETRY(close(fd));
+            }
+
+            /* exec self to print malloc output */
+            ASSERT_TRUE(execl(self_.c_str(), self_.c_str(), argPrint.c_str(),
+                android::base::StringPrintf("%zu", allocSize).c_str(),
+                nullptr) != -1);
+        }
+
+        /* parent process */
+        TEMP_FAILURE_RETRY(close(fds[1]));
+
+        std::string output;
+        ASSERT_TRUE(android::base::ReadFdToString(fds[0], &output));
+        TEMP_FAILURE_RETRY(close(fds[0]));
+
+        int status;
+        ASSERT_TRUE(waitpid(pid, &status, 0) != -1);
+        ASSERT_TRUE(WEXITSTATUS(status) == EXIT_SUCCESS);
+
+        ASSERT_TRUE(android::base::ParseUint(output.c_str(), &address));
+    }
+
+    void TestRandomization()
+    {
+        /* should be sufficient to see minEntropyBits when rounded up */
+        size_t iterations = 2 * (1 << minEntropyBits);
+
+        for (auto size : allocSizes) {
+            ALOGV("running %zu iterations for allocation size %zu",
+                iterations, size);
+
+            /* collect unique return addresses */
+            std::unordered_set<uintptr_t> addresses;
+
+            for (size_t i = 0; i < iterations; ++i) {
+                uintptr_t address;
+                GetAddress(size, address);
+
+                addresses.emplace(address);
+            }
+
+            size_t entropy = static_cast<size_t>(0.5 +
+                                log2(static_cast<double>(addresses.size())));
+
+            ALOGV("%zu bits of entropy for allocation size %zu (minimum %zu)",
+                entropy, size, minEntropyBits);
+            ALOGE_IF(entropy < minEntropyBits,
+                "insufficient entropy for malloc(%zu)", size);
+            ASSERT_TRUE(entropy >= minEntropyBits);
+        }
+    }
+};
+#else /* defined(BUILD_ONLY) */
+class AslrMallocTest : public ::testing::Test
+{
+protected:
+    void TestRandomization() {}
+};
+#endif
+
+TEST_F(AslrMallocTest, testMallocRandomization) {
+    TestRandomization();
+}
+
+int main(int argc, char **argv)
+{
+#if !defined(BUILD_ONLY)
+    if (argc == 3 && argPrint == argv[1]) {
+        size_t size;
+
+        if (!android::base::ParseUint(argv[2], &size)) {
+            return EXIT_FAILURE;
+        }
+
+        printf("%p", malloc(size));
+        return EXIT_SUCCESS;
+    }
+#endif
+
+    testing::InitGoogleTest(&argc, argv);
+    return RUN_ALL_TESTS();
+}
diff --git a/tests/backup/Android.mk b/tests/backup/Android.mk
new file mode 100644
index 0000000..a2de68b
--- /dev/null
+++ b/tests/backup/Android.mk
@@ -0,0 +1,39 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+# don't include this package in any target
+LOCAL_MODULE_TAGS := optional
+# and when built explicitly put it in the data partition
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_JAVA_LIBRARIES := android.test.runner telephony-common voip-common org.apache.http.legacy
+
+LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctstestrunner ctstestserver mockito-target
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_PACKAGE_NAME := CtsBackupTestCases
+
+LOCAL_SDK_VERSION := test_current
+
+include $(BUILD_CTS_PACKAGE)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/backup/AndroidManifest.xml b/tests/backup/AndroidManifest.xml
new file mode 100644
index 0000000..333045a
--- /dev/null
+++ b/tests/backup/AndroidManifest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2016 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.backup.cts">
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="android.backup.cts"
+                     android:label="CTS tests of Android Backup/Restore">
+        <meta-data android:name="listener"
+            android:value="com.android.cts.runner.CtsTestRunListener" />
+    </instrumentation>
+
+</manifest>
+
diff --git a/tests/backup/AndroidTest.xml b/tests/backup/AndroidTest.xml
new file mode 100644
index 0000000..ce5d261
--- /dev/null
+++ b/tests/backup/AndroidTest.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2016 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<configuration description="Config for CTS Backup test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsBackupApp.apk" />
+        <option name="test-file-name" value="CtsBackupTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.backup.cts" />
+    </test>
+</configuration>
diff --git a/tests/backup/app/Android.mk b/tests/backup/app/Android.mk
new file mode 100644
index 0000000..cffb1d2
--- /dev/null
+++ b/tests/backup/app/Android.mk
@@ -0,0 +1,34 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := CtsBackupApp
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
+    ctsdeviceutil \
+    ctstestrunner
+
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/tests/backup/app/AndroidManifest.xml b/tests/backup/app/AndroidManifest.xml
new file mode 100644
index 0000000..1507bc2
--- /dev/null
+++ b/tests/backup/app/AndroidManifest.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2016 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.backup.app" >
+
+    <application
+        android:allowBackup="true"
+        android:backupAgent="BackupCtsBackupAgent"
+        android:label="Android Backup CTS App"
+        android:fullBackupOnly="true">
+        <activity
+            android:name=".MainActivity"
+            android:label="Android Backup CTS App" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
diff --git a/tests/backup/app/src/android/backup/app/BackupCtsBackupAgent.java b/tests/backup/app/src/android/backup/app/BackupCtsBackupAgent.java
new file mode 100644
index 0000000..f6fb8c1
--- /dev/null
+++ b/tests/backup/app/src/android/backup/app/BackupCtsBackupAgent.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.backup.app;
+
+import android.app.backup.BackupAgent;
+import android.app.backup.BackupDataInput;
+import android.app.backup.BackupDataOutput;
+import android.app.backup.FullBackupDataOutput;
+import android.os.ParcelFileDescriptor;
+import android.util.Log;
+
+import java.io.IOException;
+
+/*
+ * Backup agent for Backup CTS App.
+ *
+ * Logs callbacks into logcat.
+ */
+public class BackupCtsBackupAgent extends BackupAgent {
+
+    @Override
+    public void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
+                         ParcelFileDescriptor newState) throws IOException {
+        Log.d(MainActivity.TAG, "Backup requested");
+    }
+
+    @Override
+    public void onRestore(BackupDataInput data, int appVersionCode,
+                          ParcelFileDescriptor newState) throws IOException {
+        Log.d(MainActivity.TAG, "Restore requested");
+    }
+
+    @Override
+    public void onFullBackup(FullBackupDataOutput data) throws IOException {
+        Log.d(MainActivity.TAG, "Full backup requested");
+        super.onFullBackup(data);
+    }
+
+    @Override
+    public void onQuotaExceeded(long backupDataBytes, long quotaBytes) {
+        Log.d(MainActivity.TAG, "Quota exceeded!");
+    }
+}
diff --git a/tests/backup/app/src/android/backup/app/MainActivity.java b/tests/backup/app/src/android/backup/app/MainActivity.java
new file mode 100644
index 0000000..93c6dd6
--- /dev/null
+++ b/tests/backup/app/src/android/backup/app/MainActivity.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.backup.app;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.util.Log;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Random;
+
+/**
+ * The activity could be invoked to create a test file.
+ *
+ * Here is an example of a call:
+ *
+ * am start -a android.intent.action.MAIN \
+ * -c android.intent.category.LAUNCHER \
+ * -n android.backup.app/android.backup.app.MainActivity \
+ * -e file_size 10000000
+ *
+ * "File created!" string is printed in logcat when file is created.
+ */
+public class MainActivity extends Activity {
+    public static final String TAG = "BackupCTSApp";
+
+    private static final String FILE_NAME = "file_name";
+    private static final String FILE_SIZE_EXTRA = "file_size";
+    private static final int DATA_CHUNK_SIZE = 1024 * 1024;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceActivity) {
+        super.onCreate(savedInstanceActivity);
+        if (getIntent().hasExtra(FILE_SIZE_EXTRA)) {
+            int fileSize = Integer.parseInt(getIntent().getStringExtra(FILE_SIZE_EXTRA));
+            Log.i(TAG, "Creating file of size: " + fileSize);
+            try {
+                createFile(fileSize);
+                Log.d(TAG, "File created!");
+            } catch (IOException e) {
+                Log.e(TAG, "IOException: " + e);
+            }
+        } else {
+            Log.d(TAG, "No file size was provided");
+        }
+    }
+
+    private void createFile(int size) throws IOException {
+        byte[] bytes = new byte[DATA_CHUNK_SIZE];
+        new Random().nextBytes(bytes);
+        File f = new File(getFilesDir().getAbsolutePath(), FILE_NAME);
+        f.getParentFile().mkdirs();
+        try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(f))) {
+            while (size > 0) {
+                int bytesToWrite = Math.min(size, DATA_CHUNK_SIZE);
+                bos.write(bytes, 0, bytesToWrite);
+                size -= bytesToWrite;
+            }
+        }
+    }
+}
diff --git a/tests/backup/src/android/backup/cts/BackupQuotaTest.java b/tests/backup/src/android/backup/cts/BackupQuotaTest.java
new file mode 100644
index 0000000..6122ad0
--- /dev/null
+++ b/tests/backup/src/android/backup/cts/BackupQuotaTest.java
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.backup.cts;
+
+import android.app.Instrumentation;
+import android.os.ParcelFileDescriptor;
+import android.test.InstrumentationTestCase;
+import android.util.Log;
+
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+import java.util.concurrent.TimeUnit;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Verifies receiving quotaExceeded() callback on full backup.
+ *
+ * Uses test app that creates large file and receives the callback.
+ * {@link com.android.internal.backup.LocalTransport} is used, it has size quota 25MB.
+ */
+public class BackupQuotaTest extends InstrumentationTestCase {
+    private static final String APP_LOG_TAG = "BackupCTSApp";
+
+    private static final String LOCAL_TRANSPORT =
+            "android/com.android.internal.backup.LocalTransport";
+    private static final int LOCAL_TRANSPORT_EXCEEDING_FILE_SIZE = 30 * 1024 * 1024;
+    private static final String BACKUP_APP_NAME = "android.backup.app";
+
+    private static final int SMALL_LOGCAT_DELAY = 1000;
+
+    private boolean wasBackupEnabled;
+    private String oldTransport;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        // Enable backup and select local backup transport
+        assertTrue("LocalTransport should be available.", hasBackupTransport(LOCAL_TRANSPORT));
+        wasBackupEnabled = enableBackup(true);
+        oldTransport = setBackupTransport(LOCAL_TRANSPORT);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        // Return old transport
+        setBackupTransport(oldTransport);
+        enableBackup(wasBackupEnabled);
+        super.tearDown();
+    }
+
+    public void testQuotaExceeded() throws Exception {
+        exec("logcat --clear");
+        exec("setprop log.tag." + APP_LOG_TAG +" VERBOSE");
+        // Launch test app and create file exceeding limit for local transport
+        exec("am start -W -a android.intent.action.MAIN " +
+                "-c android.intent.category.LAUNCHER " +
+                "-n " + BACKUP_APP_NAME + "/" + BACKUP_APP_NAME +".MainActivity " +
+                "-e file_size " + LOCAL_TRANSPORT_EXCEEDING_FILE_SIZE);
+        assertTrue("File was not created", waitForLogcat("File created!", 30));
+
+        // Request backup and wait for quota exceeded event in logcat
+        exec("bmgr backupnow " + BACKUP_APP_NAME);
+        assertTrue("Quota exceeded event is not received", waitForLogcat("Quota exceeded!", 10));
+    }
+
+    private boolean enableBackup(boolean enable) throws Exception {
+        boolean previouslyEnabled;
+        String output = exec("bmgr enabled");
+        Pattern pattern = Pattern.compile("^Backup Manager currently (enabled|disabled)$");
+        Matcher matcher = pattern.matcher(output.trim());
+        if (matcher.find()) {
+            previouslyEnabled = "enabled".equals(matcher.group(1));
+        } else {
+            throw new RuntimeException("non-parsable output setting bmgr enabled: " + output);
+        }
+
+        exec("bmgr enable " + enable);
+        return previouslyEnabled;
+    }
+
+    private String setBackupTransport(String transport) throws Exception {
+        String output = exec("bmgr transport " + transport);
+        Pattern pattern = Pattern.compile("\\(formerly (.*)\\)$");
+        Matcher matcher = pattern.matcher(output);
+        if (matcher.find()) {
+            return matcher.group(1);
+        } else {
+            throw new RuntimeException("non-parsable output setting bmgr transport: " + output);
+        }
+    }
+
+    private boolean hasBackupTransport(String transport) throws Exception {
+        String output = exec("bmgr list transports");
+        for (String t : output.split(" ")) {
+            if (transport.equals(t)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean waitForLogcat(String logcatString, int maxTimeoutInSeconds) throws Exception {
+        long timeout = System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(maxTimeoutInSeconds);
+        while (timeout >= System.currentTimeMillis()) {
+            FileInputStream fis = executeStreamedShellCommand(getInstrumentation(),
+                    "logcat -v brief -d " + APP_LOG_TAG + ":* *:S");
+            BufferedReader log = new BufferedReader(new InputStreamReader(fis));
+            String line;
+            while ((line = log.readLine()) != null) {
+                if (line.contains(logcatString)) {
+                    return true;
+                }
+            }
+            closeQuietly(log);
+            // In case the key has not been found, wait for the log to update before
+            // performing the next search.
+            Thread.sleep(SMALL_LOGCAT_DELAY);
+        }
+        return false;
+    }
+
+    private String exec(String command) throws Exception {
+        BufferedReader br = null;
+        try (InputStream in = executeStreamedShellCommand(getInstrumentation(), command)) {
+            br = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8));
+            String str = null;
+            StringBuilder out = new StringBuilder();
+            while ((str = br.readLine()) != null) {
+                out.append(str);
+            }
+            return out.toString();
+        } finally {
+            if (br != null) {
+                closeQuietly(br);
+            }
+        }
+    }
+
+    private static FileInputStream executeStreamedShellCommand(Instrumentation instrumentation,
+                                                               String command) throws Exception {
+        final ParcelFileDescriptor pfd =
+                instrumentation.getUiAutomation().executeShellCommand(command);
+        return new FileInputStream(pfd.getFileDescriptor());
+    }
+
+    private static void closeQuietly(AutoCloseable closeable) {
+        if (closeable != null) {
+            try {
+                closeable.close();
+            } catch (RuntimeException rethrown) {
+                throw rethrown;
+            } catch (Exception ignored) {
+            }
+        }
+    }
+}
diff --git a/tests/browser/Android.mk b/tests/browser/Android.mk
new file mode 100644
index 0000000..efa68b9
--- /dev/null
+++ b/tests/browser/Android.mk
@@ -0,0 +1,34 @@
+# Copyright (C) 2012 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+# don't include this package in any target
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil compatibility-device-util ctstestrunner ctstestserver
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_PACKAGE_NAME := CtsBrowserTestCases
+
+LOCAL_SDK_VERSION := 16
+
+include $(BUILD_CTS_PACKAGE)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/browser/AndroidManifest.xml b/tests/browser/AndroidManifest.xml
new file mode 100644
index 0000000..f850e28
--- /dev/null
+++ b/tests/browser/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="android.browser.cts">
+
+    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+    <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+            android:targetPackage="android.browser.cts" />
+</manifest>
diff --git a/tests/browser/AndroidTest.xml b/tests/browser/AndroidTest.xml
new file mode 100644
index 0000000..49c93fc
--- /dev/null
+++ b/tests/browser/AndroidTest.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS Browser test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsBrowserTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.browser.cts" />
+        <option name="runtime-hint" value="4m14s" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/suite/cts/deviceTests/browserbench/assets/octane/base.js b/tests/browser/assets/octane/base.js
similarity index 100%
rename from suite/cts/deviceTests/browserbench/assets/octane/base.js
rename to tests/browser/assets/octane/base.js
diff --git a/suite/cts/deviceTests/browserbench/assets/octane/box2d.js b/tests/browser/assets/octane/box2d.js
similarity index 100%
rename from suite/cts/deviceTests/browserbench/assets/octane/box2d.js
rename to tests/browser/assets/octane/box2d.js
diff --git a/suite/cts/deviceTests/browserbench/assets/octane/code-load.js b/tests/browser/assets/octane/code-load.js
similarity index 100%
rename from suite/cts/deviceTests/browserbench/assets/octane/code-load.js
rename to tests/browser/assets/octane/code-load.js
diff --git a/suite/cts/deviceTests/browserbench/assets/octane/crypto.js b/tests/browser/assets/octane/crypto.js
similarity index 100%
rename from suite/cts/deviceTests/browserbench/assets/octane/crypto.js
rename to tests/browser/assets/octane/crypto.js
diff --git a/suite/cts/deviceTests/browserbench/assets/octane/css/bootstrap-responsive.css b/tests/browser/assets/octane/css/bootstrap-responsive.css
similarity index 100%
rename from suite/cts/deviceTests/browserbench/assets/octane/css/bootstrap-responsive.css
rename to tests/browser/assets/octane/css/bootstrap-responsive.css
diff --git a/suite/cts/deviceTests/browserbench/assets/octane/css/bootstrap.css b/tests/browser/assets/octane/css/bootstrap.css
similarity index 100%
rename from suite/cts/deviceTests/browserbench/assets/octane/css/bootstrap.css
rename to tests/browser/assets/octane/css/bootstrap.css
diff --git a/suite/cts/deviceTests/browserbench/assets/octane/css/docs.css b/tests/browser/assets/octane/css/docs.css
similarity index 100%
rename from suite/cts/deviceTests/browserbench/assets/octane/css/docs.css
rename to tests/browser/assets/octane/css/docs.css
diff --git a/suite/cts/deviceTests/browserbench/assets/octane/cts_report.html b/tests/browser/assets/octane/cts_report.html
similarity index 100%
rename from suite/cts/deviceTests/browserbench/assets/octane/cts_report.html
rename to tests/browser/assets/octane/cts_report.html
diff --git a/suite/cts/deviceTests/browserbench/assets/octane/cts_report.js b/tests/browser/assets/octane/cts_report.js
similarity index 100%
rename from suite/cts/deviceTests/browserbench/assets/octane/cts_report.js
rename to tests/browser/assets/octane/cts_report.js
diff --git a/suite/cts/deviceTests/browserbench/assets/octane/deltablue.js b/tests/browser/assets/octane/deltablue.js
similarity index 100%
rename from suite/cts/deviceTests/browserbench/assets/octane/deltablue.js
rename to tests/browser/assets/octane/deltablue.js
diff --git a/suite/cts/deviceTests/browserbench/assets/octane/earley-boyer.js b/tests/browser/assets/octane/earley-boyer.js
similarity index 100%
rename from suite/cts/deviceTests/browserbench/assets/octane/earley-boyer.js
rename to tests/browser/assets/octane/earley-boyer.js
diff --git a/suite/cts/deviceTests/browserbench/assets/octane/gbemu.js b/tests/browser/assets/octane/gbemu.js
similarity index 100%
rename from suite/cts/deviceTests/browserbench/assets/octane/gbemu.js
rename to tests/browser/assets/octane/gbemu.js
diff --git a/suite/cts/deviceTests/browserbench/assets/octane/ico/apple-touch-icon-114-precomposed.png b/tests/browser/assets/octane/ico/apple-touch-icon-114-precomposed.png
similarity index 100%
rename from suite/cts/deviceTests/browserbench/assets/octane/ico/apple-touch-icon-114-precomposed.png
rename to tests/browser/assets/octane/ico/apple-touch-icon-114-precomposed.png
Binary files differ
diff --git a/suite/cts/deviceTests/browserbench/assets/octane/ico/apple-touch-icon-144-precomposed.png b/tests/browser/assets/octane/ico/apple-touch-icon-144-precomposed.png
similarity index 100%
rename from suite/cts/deviceTests/browserbench/assets/octane/ico/apple-touch-icon-144-precomposed.png
rename to tests/browser/assets/octane/ico/apple-touch-icon-144-precomposed.png
Binary files differ
diff --git a/suite/cts/deviceTests/browserbench/assets/octane/ico/apple-touch-icon-57-precomposed.png b/tests/browser/assets/octane/ico/apple-touch-icon-57-precomposed.png
similarity index 100%
rename from suite/cts/deviceTests/browserbench/assets/octane/ico/apple-touch-icon-57-precomposed.png
rename to tests/browser/assets/octane/ico/apple-touch-icon-57-precomposed.png
Binary files differ
diff --git a/suite/cts/deviceTests/browserbench/assets/octane/ico/apple-touch-icon-72-precomposed.png b/tests/browser/assets/octane/ico/apple-touch-icon-72-precomposed.png
similarity index 100%
rename from suite/cts/deviceTests/browserbench/assets/octane/ico/apple-touch-icon-72-precomposed.png
rename to tests/browser/assets/octane/ico/apple-touch-icon-72-precomposed.png
Binary files differ
diff --git a/suite/cts/deviceTests/browserbench/assets/octane/ico/favicon.ico b/tests/browser/assets/octane/ico/favicon.ico
similarity index 100%
rename from suite/cts/deviceTests/browserbench/assets/octane/ico/favicon.ico
rename to tests/browser/assets/octane/ico/favicon.ico
Binary files differ
diff --git a/suite/cts/deviceTests/browserbench/assets/octane/index.html b/tests/browser/assets/octane/index.html
similarity index 100%
rename from suite/cts/deviceTests/browserbench/assets/octane/index.html
rename to tests/browser/assets/octane/index.html
diff --git a/suite/cts/deviceTests/browserbench/assets/octane/js/bootstrap-collapse.js b/tests/browser/assets/octane/js/bootstrap-collapse.js
similarity index 100%
rename from suite/cts/deviceTests/browserbench/assets/octane/js/bootstrap-collapse.js
rename to tests/browser/assets/octane/js/bootstrap-collapse.js
diff --git a/suite/cts/deviceTests/browserbench/assets/octane/js/bootstrap-transition.js b/tests/browser/assets/octane/js/bootstrap-transition.js
similarity index 100%
rename from suite/cts/deviceTests/browserbench/assets/octane/js/bootstrap-transition.js
rename to tests/browser/assets/octane/js/bootstrap-transition.js
diff --git a/suite/cts/deviceTests/browserbench/assets/octane/js/jquery.js b/tests/browser/assets/octane/js/jquery.js
similarity index 100%
rename from suite/cts/deviceTests/browserbench/assets/octane/js/jquery.js
rename to tests/browser/assets/octane/js/jquery.js
diff --git a/suite/cts/deviceTests/browserbench/assets/octane/mandreel.js b/tests/browser/assets/octane/mandreel.js
similarity index 100%
rename from suite/cts/deviceTests/browserbench/assets/octane/mandreel.js
rename to tests/browser/assets/octane/mandreel.js
diff --git a/suite/cts/deviceTests/browserbench/assets/octane/navier-stokes.js b/tests/browser/assets/octane/navier-stokes.js
similarity index 100%
rename from suite/cts/deviceTests/browserbench/assets/octane/navier-stokes.js
rename to tests/browser/assets/octane/navier-stokes.js
diff --git a/suite/cts/deviceTests/browserbench/assets/octane/pdfjs.js b/tests/browser/assets/octane/pdfjs.js
similarity index 100%
rename from suite/cts/deviceTests/browserbench/assets/octane/pdfjs.js
rename to tests/browser/assets/octane/pdfjs.js
diff --git a/suite/cts/deviceTests/browserbench/assets/octane/raytrace.js b/tests/browser/assets/octane/raytrace.js
similarity index 100%
rename from suite/cts/deviceTests/browserbench/assets/octane/raytrace.js
rename to tests/browser/assets/octane/raytrace.js
diff --git a/suite/cts/deviceTests/browserbench/assets/octane/regexp.js b/tests/browser/assets/octane/regexp.js
similarity index 100%
rename from suite/cts/deviceTests/browserbench/assets/octane/regexp.js
rename to tests/browser/assets/octane/regexp.js
diff --git a/suite/cts/deviceTests/browserbench/assets/octane/richards.js b/tests/browser/assets/octane/richards.js
similarity index 100%
rename from suite/cts/deviceTests/browserbench/assets/octane/richards.js
rename to tests/browser/assets/octane/richards.js
diff --git a/suite/cts/deviceTests/browserbench/assets/octane/run.js b/tests/browser/assets/octane/run.js
similarity index 100%
rename from suite/cts/deviceTests/browserbench/assets/octane/run.js
rename to tests/browser/assets/octane/run.js
diff --git a/suite/cts/deviceTests/browserbench/assets/octane/splay.js b/tests/browser/assets/octane/splay.js
similarity index 100%
rename from suite/cts/deviceTests/browserbench/assets/octane/splay.js
rename to tests/browser/assets/octane/splay.js
diff --git a/tests/browser/src/android/browser/cts/BrowserBenchTest.java b/tests/browser/src/android/browser/cts/BrowserBenchTest.java
new file mode 100644
index 0000000..ff1a2ab
--- /dev/null
+++ b/tests/browser/src/android/browser/cts/BrowserBenchTest.java
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.browser.cts;
+
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.cts.util.CtsAndroidTestCase;
+import android.cts.util.WatchDog;
+import android.net.Uri;
+import android.provider.Browser;
+import android.util.Log;
+import android.webkit.cts.CtsTestServer;
+
+import com.android.compatibility.common.util.DeviceReportLog;
+import com.android.compatibility.common.util.ResultType;
+import com.android.compatibility.common.util.ResultUnit;
+import com.android.compatibility.common.util.Stat;
+import com.android.cts.util.TimeoutReq;
+
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpResponse;
+import org.apache.http.RequestLine;
+
+import java.net.URLDecoder;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+/**
+ * Browser benchmarking.
+ * It launches an activity with URL and wait for POST from the client.
+ */
+public class BrowserBenchTest extends CtsAndroidTestCase {
+    private static final String TAG = BrowserBenchTest.class.getSimpleName();
+    private static final boolean DEBUG = false;
+    private static final String OCTANE_START_FILE = "octane/index.html";
+    private static final String ROBOHORNET_START_FILE = "robohornet/robohornet.html";
+    private static final String HOST_COMPLETION_BROADCAST = "android.browser.cts.completion";
+    // time-out for watch-dog. POST should happen within this time.
+    private static long BROWSER_POST_TIMEOUT_IN_MS = 10 * 60 * 1000L;
+    // watch-dog will time-out first. So make it long enough.
+    private static long BROWSER_COMPLETION_TIMEOUT_IN_MS = 60 * 60 * 1000L;
+    private static final String HTTP_USER_AGENT = "User-Agent";
+    private CtsTestServer mWebServer;
+    // used for final score
+    private ResultType mTypeNonFinal = ResultType.NEUTRAL;
+    private ResultUnit mUnitNonFinal = ResultUnit.NONE;
+    // used for all other scores
+    private ResultType mTypeFinal = ResultType.NEUTRAL;
+    private ResultUnit mUnitFinal = ResultUnit.SCORE;
+    private WatchDog mWatchDog;
+    private CountDownLatch mLatch;
+    // can be changed by each test before starting
+    private volatile int mNumberRepeat;
+    /** tells how many tests have run up to now */
+    private volatile int mRunIndex;
+    /** stores results for each runs. last entry will be the final score. */
+    private LinkedHashMap<String, double[]> mResultsMap;
+    private PackageManager mPackageManager;
+    private DeviceReportLog mReport;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mReport = new DeviceReportLog();
+        mPackageManager = getInstrumentation().getContext().getPackageManager();
+        mWebServer = new CtsTestServer(getContext()) {
+            @Override
+            protected HttpResponse onPost(HttpRequest request) throws Exception {
+                // post uri will look like "cts_report.html?final=1&score=10.1&message=hello"
+                RequestLine requestLine = request.getRequestLine();
+                String uriString = URLDecoder.decode(requestLine.getUri(), "UTF-8");
+                if (DEBUG) {
+                    Log.i(TAG, "uri:" + uriString);
+                }
+                String resultRe =
+                        ".*cts_report.html\\?final=([\\d])&score=([\\d]+\\.?[\\d]*)&message=([\\w][\\w ]*)";
+                Pattern resultPattern = Pattern.compile(resultRe);
+                Matcher matchResult = resultPattern.matcher(uriString);
+                if (matchResult.find()) {
+                    int isFinal = Integer.parseInt(matchResult.group(1));
+                    double score = Double.parseDouble(matchResult.group(2));
+                    String message = matchResult.group(3);
+                    Log.i(TAG, message + ":" + score);
+                    if (!mResultsMap.containsKey(message)) {
+                        mResultsMap.put(message, new double[mNumberRepeat]);
+                    }
+                    double[] scores = mResultsMap.get(message);
+                    scores[mRunIndex] = score;
+                    if (isFinal == 1) {
+                        String userAgent = request.getFirstHeader(HTTP_USER_AGENT).getValue();
+                        mReport.addValue(HTTP_USER_AGENT + "=" + userAgent, 0,
+                                ResultType.NEUTRAL, ResultUnit.NONE);
+                        mLatch.countDown();
+                    }
+                    mWatchDog.reset();
+                }
+                return null; // default response is OK as it will be ignored by client anyway.
+            }
+        };
+        mResultsMap = new LinkedHashMap<String, double[]>();
+        mWatchDog = new WatchDog(BROWSER_POST_TIMEOUT_IN_MS);
+        mWatchDog.start();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        mWatchDog.stop();
+        mWebServer.shutdown();
+        mWebServer = null;
+        mResultsMap = null;
+        mReport.submit(getInstrumentation());
+        super.tearDown();
+    }
+
+    @TimeoutReq(minutes = 60)
+    public void testOctane() throws InterruptedException {
+        if (!isBrowserSupported()) {
+            Log.i(TAG, "Skipping test for device with no supported browser");
+            return;
+        }
+        String url = mWebServer.getAssetUrl(OCTANE_START_FILE) + "?auto=1";
+        final int kRepeat = 5;
+        doTest(url, ResultType.LOWER_BETTER, ResultUnit.MS,
+                ResultType.HIGHER_BETTER, ResultUnit.SCORE, kRepeat);
+    }
+
+    private void doTest(String url, ResultType typeNonFinal, ResultUnit unitNonFinal,
+            ResultType typeFinal, ResultUnit unitFinal, int numberRepeat)
+                    throws InterruptedException {
+        mTypeNonFinal = typeNonFinal;
+        mUnitNonFinal = unitNonFinal;
+        mTypeFinal = typeFinal;
+        mUnitFinal = unitFinal;
+        mNumberRepeat = numberRepeat;
+        Uri uri = Uri.parse(url);
+        for (mRunIndex = 0; mRunIndex < numberRepeat; mRunIndex++) {
+            Log.i(TAG, mRunIndex + "-th round");
+            mLatch = new CountDownLatch(1);
+            Intent intent = new Intent(Intent.ACTION_VIEW, uri);
+            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            // force using only one window or tab
+            intent.putExtra(Browser.EXTRA_APPLICATION_ID, getContext().getPackageName());
+            getContext().startActivity(intent);
+            boolean ok = mLatch.await(BROWSER_COMPLETION_TIMEOUT_IN_MS, TimeUnit.MILLISECONDS);
+            assertTrue("timed-out", ok);
+        }
+        // it is somewhat awkward to handle the last one specially with Map
+        int numberEntries = mResultsMap.size();
+        int numberToProcess = 1; 
+        for (Map.Entry<String, double[]> entry : mResultsMap.entrySet()) {
+            String message = entry.getKey();
+            double[] scores = entry.getValue();
+            if (numberToProcess == numberEntries) { // final score
+                // store the whole results first
+                mReport.addValues(message, scores, mTypeFinal, mUnitFinal);
+                mReport.setSummary(message, Stat.getAverage(scores), mTypeFinal, mUnitFinal);
+            } else { // interim results
+                mReport.addValues(message, scores, mTypeNonFinal, mUnitNonFinal);
+            }
+            numberToProcess++;
+        }
+    }
+
+    /**
+     * @return true iff this device is has a working browser.
+     */
+    private boolean isBrowserSupported() {
+        return !(mPackageManager.hasSystemFeature("android.hardware.type.television")
+                 || mPackageManager.hasSystemFeature("android.software.leanback")
+                 || mPackageManager.hasSystemFeature("android.hardware.type.watch"));
+    }
+}
diff --git a/tests/camera/Android.mk b/tests/camera/Android.mk
index 4cae7c4..4065bfb 100644
--- a/tests/camera/Android.mk
+++ b/tests/camera/Android.mk
@@ -20,13 +20,23 @@
 
 LOCAL_MODULE_TAGS := tests
 
+# Include both the 32 and 64 bit versions
+LOCAL_MULTILIB := both
+
 LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil \
 	ctstestrunner \
 	mockito-target \
 	android-ex-camera2
 
+LOCAL_JNI_SHARED_LIBRARIES := \
+	libctscamera2_jni \
+	libnativehelper_compat_libc++
+
 LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-renderscript-files-under, src)
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_PACKAGE_NAME := CtsCameraTestCases
 
 LOCAL_SDK_VERSION := current
@@ -36,3 +46,5 @@
 cts_runtime_hint := 120
 
 include $(BUILD_CTS_PACKAGE)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/camera/AndroidManifest.xml b/tests/camera/AndroidManifest.xml
index 2b39fca..cddeaeb 100644
--- a/tests/camera/AndroidManifest.xml
+++ b/tests/camera/AndroidManifest.xml
@@ -24,7 +24,7 @@
     <uses-permission android:name="android.permission.REORDER_TASKS" />
     <uses-permission android:name="android.permission.WAKE_LOCK" />
 
-    <application>
+    <application android:largeHeap="true">
         <uses-library android:name="android.test.runner" />
 
         <activity android:name="android.hardware.cts.CameraCtsActivity"
@@ -68,6 +68,13 @@
             android:process=":camera2ActivityProcess">
         </activity>
 
+        <activity android:name="android.hardware.multiprocess.camera.cts.MediaRecorderCameraActivity"
+            android:label="RemoteMediaRecorderCameraActivity"
+            android:screenOrientation="landscape"
+            android:configChanges="keyboardHidden|orientation|screenSize"
+            android:process=":mediaRecorderCameraActivityProcess">
+        </activity>
+
     </application>
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
diff --git a/tests/camera/AndroidTest.xml b/tests/camera/AndroidTest.xml
new file mode 100644
index 0000000..b54e1a22
--- /dev/null
+++ b/tests/camera/AndroidTest.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS Camera test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsCameraTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.camera.cts" />
+        <option name="runtime-hint" value="12m7s" />
+        <!-- test-timeout unit is ms, value = 30 min -->
+        <option name="test-timeout" value="1800000" />
+    </test>
+</configuration>
diff --git a/tests/camera/libctscamera2jni/Android.mk b/tests/camera/libctscamera2jni/Android.mk
new file mode 100644
index 0000000..eac42f5
--- /dev/null
+++ b/tests/camera/libctscamera2jni/Android.mk
@@ -0,0 +1,53 @@
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE    := libctscamera2_jni
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := \
+	native-camera-jni.cpp \
+	dng-validate-jni.cpp
+
+LOCAL_C_INCLUDES := \
+	$(JNI_H_INCLUDE) \
+	system/core/include \
+	frameworks/av/include/camera/ndk \
+	frameworks/av/include/ndk \
+
+# Flags needed by DNG SDK
+LOCAL_CFLAGS := -DUNIX_ENV=1 -DqDNGBigEndian=0 -DqDNGThreadSafe=1 -DqDNGUseLibJPEG=1 -DqDNGUseXMP=0 -DqDNGValidate=1 -DqDNGValidateTarget=1 -DqAndroid=1 -fexceptions -Wsign-compare -Wno-reorder -Wframe-larger-than=20000
+
+# Flags to avoid warnings from DNG SDK
+LOCAL_CFLAGS += -Wno-unused-parameter
+
+LOCAL_STATIC_LIBRARIES := libdng_sdk_validate libjpeg_static libz
+LOCAL_SHARED_LIBRARIES := libandroid \
+    libnativehelper_compat_libc++ \
+    liblog \
+    libcamera2ndk \
+    libmediandk
+
+# NDK build, shared C++ runtime
+#LOCAL_SDK_VERSION := current
+#LOCAL_NDK_STL_VARIANT := c++_shared
+
+# Temporary workaround until camera2 NDK is active. See b/27102995.
+LOCAL_CXX_STL := libc++_static
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/tests/camera/libctscamera2jni/dng-validate-jni.cpp b/tests/camera/libctscamera2jni/dng-validate-jni.cpp
new file mode 100644
index 0000000..186cf3f
--- /dev/null
+++ b/tests/camera/libctscamera2jni/dng-validate-jni.cpp
@@ -0,0 +1,469 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 LOG_NDEBUG 0
+#define LOG_TAG "DngValidateCamera"
+#include <log/log.h>
+#include <jni.h>
+
+#include <string>
+#include <sstream>
+#include <iostream>
+
+/**
+ * Use DNG SDK to validate captured DNG file.
+ *
+ * This code is largely based on the dng_validate.cpp implementation included
+ * with the DNG SDK. The portions of this file that are from the DNG SDK are
+ * covered by the the DNG SDK license in /external/dng_sdk/LICENSE
+ */
+
+#include "dng_color_space.h"
+#include "dng_date_time.h"
+#include "dng_exceptions.h"
+#include "dng_file_stream.h"
+#include "dng_globals.h"
+#include "dng_host.h"
+#include "dng_ifd.h"
+#include "dng_image_writer.h"
+#include "dng_info.h"
+#include "dng_linearization_info.h"
+#include "dng_mosaic_info.h"
+#include "dng_negative.h"
+#include "dng_preview.h"
+#include "dng_render.h"
+#include "dng_simple_image.h"
+#include "dng_tag_codes.h"
+#include "dng_tag_types.h"
+#include "dng_tag_values.h"
+
+// Version of DNG validate referenced for this implementation
+#define kDNGValidateVersion "1.4"
+
+static bool gFourColorBayer = false;
+
+static int32 gMosaicPlane = -1;
+
+static uint32 gPreferredSize = 0;
+static uint32 gMinimumSize   = 0;
+static uint32 gMaximumSize   = 0;
+
+static uint32 gProxyDNGSize = 0;
+
+static const dng_color_space *gFinalSpace = &dng_space_sRGB::Get();
+
+static uint32 gFinalPixelType = ttByte;
+
+static dng_string gDumpStage1;
+static dng_string gDumpStage2;
+static dng_string gDumpStage3;
+static dng_string gDumpTIF;
+static dng_string gDumpDNG;
+
+/**
+ * Validate DNG file in provided buffer.
+ *
+ * Returns dng_error_none (0) on success, otherwise one of the
+ * dng_error_code enum values is returned.
+ *
+ * Warnings and errors found during validation are printed to stderr
+ */
+static dng_error_code dng_validate(const void* data, uint32_t count) {
+
+    ALOGI("Validating DNG buffer");
+
+    try {
+        dng_stream stream(data, count);
+
+        dng_host host;
+
+        host.SetPreferredSize(gPreferredSize);
+        host.SetMinimumSize(gMinimumSize);
+        host.SetMaximumSize(gMaximumSize);
+
+        host.ValidateSizes();
+
+        if (host.MinimumSize()) {
+            host.SetForPreview(true);
+            gDumpDNG.Clear();
+        }
+
+        if (gDumpDNG.NotEmpty()) {
+            host.SetSaveDNGVersion(dngVersion_SaveDefault);
+            host.SetSaveLinearDNG(false);
+            host.SetKeepOriginalFile(false);
+        }
+
+        // Read into the negative.
+
+        AutoPtr<dng_negative> negative;
+        {
+            dng_info info;
+            info.Parse(host, stream);
+            info.PostParse(host);
+            if (!info.IsValidDNG()) {
+                return dng_error_bad_format;
+            }
+
+            negative.Reset(host.Make_dng_negative());
+            negative->Parse(host, stream, info);
+            negative->PostParse(host, stream, info);
+
+            {
+                dng_timer timer("Raw image read time");
+                negative->ReadStage1Image(host, stream, info);
+            }
+
+            if (info.fMaskIndex != -1) {
+                dng_timer timer("Transparency mask read time");
+                negative->ReadTransparencyMask(host, stream, info);
+            }
+
+            negative->ValidateRawImageDigest(host);
+        }
+
+        // Option to write stage 1 image.
+
+        if (gDumpStage1.NotEmpty()) {
+            dng_file_stream stream2 (gDumpStage1.Get(), true);
+            const dng_image &stage1 = *negative->Stage1Image();
+            dng_image_writer writer;
+
+            writer.WriteTIFF(host,
+                    stream2,
+                    stage1,
+                    stage1.Planes() >= 3 ? piRGB
+                    : piBlackIsZero);
+
+            gDumpStage1.Clear();
+        }
+
+        // Metadata.
+
+        negative->SynchronizeMetadata();
+
+        // Four color Bayer option.
+
+        if (gFourColorBayer) {
+            negative->SetFourColorBayer();
+        }
+
+        // Build stage 2 image.
+
+        {
+            dng_timer timer("Linearization time");
+            negative->BuildStage2Image(host);
+        }
+
+        if (gDumpStage2.NotEmpty()) {
+            dng_file_stream stream2(gDumpStage2.Get(), true);
+            const dng_image &stage2 = *negative->Stage2Image();
+            dng_image_writer writer;
+
+            writer.WriteTIFF (host,
+                    stream2,
+                    stage2,
+                    stage2.Planes() >= 3 ? piRGB
+                    : piBlackIsZero);
+
+            gDumpStage2.Clear();
+        }
+
+        // Build stage 3 image.
+
+        {
+            dng_timer timer("Interpolate time");
+            negative->BuildStage3Image(host,
+                    gMosaicPlane);
+        }
+
+        // Convert to proxy, if requested.
+
+        if (gProxyDNGSize) {
+            dng_timer timer("ConvertToProxy time");
+            dng_image_writer writer;
+
+            negative->ConvertToProxy(host,
+                    writer,
+                    gProxyDNGSize);
+        }
+
+        // Flatten transparency, if required.
+
+        if (negative->NeedFlattenTransparency(host)) {
+            dng_timer timer("FlattenTransparency time");
+            negative->FlattenTransparency(host);
+        }
+
+        if (gDumpStage3.NotEmpty()) {
+            dng_file_stream stream2(gDumpStage3.Get(), true);
+            const dng_image &stage3 = *negative->Stage3Image();
+            dng_image_writer writer;
+
+            writer.WriteTIFF (host,
+                    stream2,
+                    stage3,
+                    stage3.Planes () >= 3 ? piRGB
+                    : piBlackIsZero);
+
+            gDumpStage3.Clear();
+        }
+
+        // Output DNG file if requested.
+
+        if (gDumpDNG.NotEmpty()) {
+            // Build the preview list.
+            dng_preview_list previewList;
+            dng_date_time_info dateTimeInfo;
+            CurrentDateTimeAndZone(dateTimeInfo);
+
+            for (uint32 previewIndex = 0; previewIndex < 2; previewIndex++) {
+
+                // Skip preview if writing a compresssed main image to save space
+                // in this example code.
+                if (negative->RawJPEGImage() != NULL && previewIndex > 0) {
+                    break;
+                }
+
+                // Report timing.
+                dng_timer timer(previewIndex == 0 ? "Build thumbnail time"
+                        : "Build preview time");
+
+                // Render a preview sized image.
+                AutoPtr<dng_image> previewImage;
+
+                {
+                    dng_render render (host, *negative);
+                    render.SetFinalSpace (negative->IsMonochrome() ?
+                            dng_space_GrayGamma22::Get() : dng_space_sRGB::Get());
+                    render.SetFinalPixelType (ttByte);
+                    render.SetMaximumSize (previewIndex == 0 ? 256 : 1024);
+
+                    previewImage.Reset (render.Render());
+                }
+
+                // Don't write the preview if it is same size as thumbnail.
+
+                if (previewIndex > 0 &&
+                        Max_uint32(previewImage->Bounds().W(),
+                                previewImage->Bounds().H()) <= 256) {
+                    break;
+                }
+
+                // If we have compressed JPEG data, create a compressed thumbnail.  Otherwise
+                // save a uncompressed thumbnail.
+                bool useCompressedPreview = (negative->RawJPEGImage() != NULL) ||
+                        (previewIndex > 0);
+
+                AutoPtr<dng_preview> preview (useCompressedPreview ?
+                        (dng_preview *) new dng_jpeg_preview :
+                        (dng_preview *) new dng_image_preview);
+
+                // Setup up preview info.
+
+                preview->fInfo.fApplicationName.Set("dng_validate");
+                preview->fInfo.fApplicationVersion.Set(kDNGValidateVersion);
+
+                preview->fInfo.fSettingsName.Set("Default");
+
+                preview->fInfo.fColorSpace = previewImage->Planes() == 1 ?
+                        previewColorSpace_GrayGamma22 :
+                        previewColorSpace_sRGB;
+
+                preview->fInfo.fDateTime = dateTimeInfo.Encode_ISO_8601();
+
+                if (!useCompressedPreview) {
+                    dng_image_preview *imagePreview = static_cast<dng_image_preview *>(preview.Get());
+                    imagePreview->fImage.Reset(previewImage.Release());
+                } else {
+                    dng_jpeg_preview *jpegPreview = static_cast<dng_jpeg_preview *>(preview.Get());
+                    int32 quality = (previewIndex == 0 ? 8 : 5);
+                    dng_image_writer writer;
+                    writer.EncodeJPEGPreview (host,
+                            *previewImage,
+                            *jpegPreview,
+                            quality);
+                }
+                previewList.Append (preview);
+            }
+
+            // Write DNG file.
+
+            dng_file_stream stream2(gDumpDNG.Get(), true);
+
+            {
+                dng_timer timer("Write DNG time");
+                dng_image_writer writer;
+
+                writer.WriteDNG(host,
+                        stream2,
+                        *negative.Get(),
+                        &previewList,
+                        dngVersion_Current,
+                        false);
+            }
+
+            gDumpDNG.Clear();
+        }
+
+        // Output TIF file if requested.
+        if (gDumpTIF.NotEmpty()) {
+
+            // Render final image.
+
+            dng_render render(host, *negative);
+
+            render.SetFinalSpace(*gFinalSpace   );
+            render.SetFinalPixelType(gFinalPixelType);
+
+            if (host.MinimumSize()) {
+                dng_point stage3Size = negative->Stage3Image()->Size();
+                render.SetMaximumSize (Max_uint32(stage3Size.v,
+                                stage3Size.h));
+            }
+
+            AutoPtr<dng_image> finalImage;
+
+            {
+                dng_timer timer("Render time");
+                finalImage.Reset(render.Render());
+            }
+
+            finalImage->Rotate(negative->Orientation());
+
+            // Now that Camera Raw supports non-raw formats, we should
+            // not keep any Camera Raw settings in the XMP around when
+            // writing rendered files.
+#if qDNGUseXMP
+            if (negative->GetXMP()) {
+                negative->GetXMP()->RemoveProperties(XMP_NS_CRS);
+                negative->GetXMP()->RemoveProperties(XMP_NS_CRSS);
+            }
+#endif
+
+            // Write TIF file.
+            dng_file_stream stream2(gDumpTIF.Get(), true);
+
+            {
+                dng_timer timer("Write TIFF time");
+                dng_image_writer writer;
+
+                writer.WriteTIFF(host,
+                        stream2,
+                        *finalImage.Get(),
+                        finalImage->Planes() >= 3 ? piRGB
+                        : piBlackIsZero,
+                        ccUncompressed,
+                        negative.Get(),
+                        &render.FinalSpace());
+            }
+            gDumpTIF.Clear();
+        }
+    } catch (const dng_exception &except) {
+        return except.ErrorCode();
+    } catch (...) {
+        return dng_error_unknown;
+    }
+
+    ALOGI("DNG validation complete");
+
+    return dng_error_none;
+}
+
+extern "C" jboolean
+Java_android_hardware_camera2_cts_DngCreatorTest_validateDngNative(
+    JNIEnv* env, jclass /*clazz*/, jbyteArray dngBuffer) {
+
+    jbyte* buffer = env->GetByteArrayElements(dngBuffer, NULL);
+    jsize bufferCount = env->GetArrayLength(dngBuffer);
+    if (buffer == nullptr) {
+        ALOGE("Unable to map DNG buffer to native");
+        return JNI_FALSE;
+    }
+
+    // DNG parsing warnings/errors fprintfs are spread throughout the DNG SDK,
+    // guarded by the qDNGValidate define flag. To avoid modifying the SDK,
+    // redirect stderr to a pipe to capture output locally.
+
+    int pipeFds[2];
+    int err;
+
+    err = pipe(pipeFds);
+    if (err != 0) {
+        ALOGE("Error redirecting dng_validate output: %d", errno);
+        env->ReleaseByteArrayElements(dngBuffer, buffer, 0);
+        return JNI_FALSE;
+    }
+
+    int stderrFd = dup(fileno(stderr));
+    dup2(pipeFds[1], fileno(stderr));
+    close(pipeFds[1]);
+
+    // Actually run the validation
+    dng_error_code dng_err = dng_validate(buffer, bufferCount);
+
+    env->ReleaseByteArrayElements(dngBuffer, buffer, 0);
+
+    // Restore stderr and read out pipe
+    dup2(stderrFd, fileno(stderr));
+
+    std::stringstream errorStream;
+    const size_t BUF_SIZE = 256;
+    char readBuf[BUF_SIZE];
+
+    ssize_t count = 0;
+    while((count = read(pipeFds[0], readBuf, BUF_SIZE)) > 0) {
+        errorStream.write(readBuf, count);
+    }
+    if (count < 0) {
+        ALOGE("Error reading from dng_validate output pipe: %d", errno);
+        return JNI_FALSE;
+    }
+    close(pipeFds[1]);
+
+    std::string line;
+    int lineCount = 0;
+    ALOGI("Output from DNG validation:");
+    // dng_validate doesn't actually propagate all errors/warnings to the
+    // return error code, so look for an error pattern in output to detect
+    // problems. Also make sure the output is long enough since some non-error
+    // content should always be printed.
+    while(std::getline(errorStream, line, '\n')) {
+        lineCount++;
+        if ( (line.size() > 3) &&
+                (line[0] == line[1]) &&
+                (line[1] == line[2]) &&
+                (line[2] == '*') ) {
+            // Found a warning or error, so need to fail the test
+            if (dng_err == dng_error_none) {
+                dng_err = dng_error_bad_format;
+            }
+            ALOGE("**|%s", line.c_str());
+        } else {
+            ALOGI("  |%s", line.c_str());
+        }
+    }
+    // If no output is produced, assume something went wrong
+    if (lineCount < 3) {
+        ALOGE("Validation output less than expected!");
+        dng_err = dng_error_unknown;
+    }
+    if (dng_err != dng_error_none) {
+        ALOGE("DNG validation failed!");
+    }
+
+    return (dng_err == dng_error_none) ? JNI_TRUE : JNI_FALSE;
+}
diff --git a/tests/camera/libctscamera2jni/native-camera-jni.cpp b/tests/camera/libctscamera2jni/native-camera-jni.cpp
new file mode 100644
index 0000000..90c34db
--- /dev/null
+++ b/tests/camera/libctscamera2jni/native-camera-jni.cpp
@@ -0,0 +1,1844 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 LOG_NDEBUG 0
+#define LOG_TAG "NativeCamera"
+#include <log/log.h>
+
+#include <string>
+#include <map>
+#include <mutex>
+#include <unistd.h>
+#include <assert.h>
+#include <jni.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <android/native_window_jni.h>
+
+#include "NdkCameraError.h"
+#include "NdkCameraManager.h"
+#include "NdkCameraDevice.h"
+#include "NdkCameraCaptureSession.h"
+#include "NdkImage.h"
+#include "NdkImageReader.h"
+
+#define LOG_ERROR(buf, ...) sprintf(buf, __VA_ARGS__); \
+                            ALOGE("%s", buf);
+
+namespace {
+    const int MAX_ERROR_STRING_LEN = 512;
+    char errorString[MAX_ERROR_STRING_LEN];
+}
+
+class CameraServiceListener {
+  public:
+    static void onAvailable(void* obj, const char* cameraId) {
+        ALOGV("Camera %s onAvailable", cameraId);
+        if (obj == nullptr) {
+            return;
+        }
+        CameraServiceListener* thiz = reinterpret_cast<CameraServiceListener*>(obj);
+        std::lock_guard<std::mutex> lock(thiz->mMutex);
+        thiz->mOnAvailableCount++;
+        thiz->mAvailableMap[cameraId] = true;
+        return;
+    }
+
+    static void onUnavailable(void* obj, const char* cameraId) {
+        ALOGV("Camera %s onUnavailable", cameraId);
+        if (obj == nullptr) {
+            return;
+        }
+        CameraServiceListener* thiz = reinterpret_cast<CameraServiceListener*>(obj);
+        std::lock_guard<std::mutex> lock(thiz->mMutex);
+        thiz->mOnUnavailableCount++;
+        thiz->mAvailableMap[cameraId] = false;
+        return;
+    }
+
+    void resetCount() {
+        std::lock_guard<std::mutex> lock(mMutex);
+        mOnAvailableCount = 0;
+        mOnUnavailableCount = 0;
+        return;
+    }
+
+    int getAvailableCount() {
+        std::lock_guard<std::mutex> lock(mMutex);
+        return mOnAvailableCount;
+    }
+
+    int getUnavailableCount() {
+        std::lock_guard<std::mutex> lock(mMutex);
+        return mOnUnavailableCount;
+    }
+
+    bool isAvailable(const char* cameraId) {
+        std::lock_guard<std::mutex> lock(mMutex);
+        if (mAvailableMap.count(cameraId) == 0) {
+            return false;
+        }
+        return mAvailableMap[cameraId];
+    }
+
+  private:
+    std::mutex mMutex;
+    int mOnAvailableCount = 0;
+    int mOnUnavailableCount = 0;
+    std::map<std::string, bool> mAvailableMap;
+};
+
+class CameraDeviceListener {
+  public:
+    static void onDisconnected(void* obj, ACameraDevice* device) {
+        ALOGV("Camera %s is disconnected!", ACameraDevice_getId(device));
+        if (obj == nullptr) {
+            return;
+        }
+        CameraDeviceListener* thiz = reinterpret_cast<CameraDeviceListener*>(obj);
+        std::lock_guard<std::mutex> lock(thiz->mMutex);
+        thiz->mOnDisconnect++;
+        return;
+    }
+
+    static void onError(void* obj, ACameraDevice* device, int errorCode) {
+        ALOGV("Camera %s receive error %d!", ACameraDevice_getId(device), errorCode);
+        if (obj == nullptr) {
+            return;
+        }
+        CameraDeviceListener* thiz = reinterpret_cast<CameraDeviceListener*>(obj);
+        std::lock_guard<std::mutex> lock(thiz->mMutex);
+        thiz->mOnError++;
+        thiz->mLatestError = errorCode;
+        return;
+    }
+
+  private:
+    std::mutex mMutex;
+    int mOnDisconnect = 0;
+    int mOnError = 0;
+    int mLatestError = 0;
+};
+
+class CaptureSessionListener {
+
+  public:
+    static void onClosed(void* obj, ACameraCaptureSession *session) {
+        // TODO: might want an API to query cameraId even session is closed?
+        ALOGV("Session %p is closed!", session);
+        if (obj == nullptr) {
+            return;
+        }
+        CaptureSessionListener* thiz = reinterpret_cast<CaptureSessionListener*>(obj);
+        std::lock_guard<std::mutex> lock(thiz->mMutex);
+        thiz->mIsClosed = true;
+        thiz->mOnClosed++; // Should never > 1
+    }
+
+    static void onReady(void* obj, ACameraCaptureSession *session) {
+        ALOGV("%s", __FUNCTION__);
+        if (obj == nullptr) {
+            return;
+        }
+        CaptureSessionListener* thiz = reinterpret_cast<CaptureSessionListener*>(obj);
+        std::lock_guard<std::mutex> lock(thiz->mMutex);
+        ACameraDevice* device = nullptr;
+        camera_status_t ret = ACameraCaptureSession_getDevice(session, &device);
+        // There will be one onReady fired after session closed
+        if (ret != ACAMERA_OK && !thiz->mIsClosed) {
+            ALOGE("%s Getting camera device from session callback failed!",
+                    __FUNCTION__);
+            thiz->mInError = true;
+        }
+        ALOGV("Session for camera %s is ready!", ACameraDevice_getId(device));
+        thiz->mIsIdle = true;
+        thiz->mOnReady++;
+    }
+
+    static void onActive(void* obj, ACameraCaptureSession *session) {
+        ALOGV("%s", __FUNCTION__);
+        if (obj == nullptr) {
+            return;
+        }
+        CaptureSessionListener* thiz = reinterpret_cast<CaptureSessionListener*>(obj);
+        std::lock_guard<std::mutex> lock(thiz->mMutex);
+        ACameraDevice* device = nullptr;
+        camera_status_t ret = ACameraCaptureSession_getDevice(session, &device);
+        if (ret != ACAMERA_OK) {
+            ALOGE("%s Getting camera device from session callback failed!",
+                    __FUNCTION__);
+            thiz->mInError = true;
+        }
+        ALOGV("Session for camera %s is busy!", ACameraDevice_getId(device));
+        thiz->mIsIdle = false;
+        thiz->mOnActive;
+    }
+
+    bool isClosed() {
+        std::lock_guard<std::mutex> lock(mMutex);
+        return mIsClosed;
+    }
+
+    bool isIdle() {
+        std::lock_guard<std::mutex> lock(mMutex);
+        return mIsIdle;
+    }
+
+    bool isInError() {
+        std::lock_guard<std::mutex> lock(mMutex);
+        return mInError;
+    }
+
+    int onClosedCount()  {
+        std::lock_guard<std::mutex> lock(mMutex);
+        return mOnClosed;
+    }
+
+    int onReadyCount()  {
+        std::lock_guard<std::mutex> lock(mMutex);
+        return mOnReady;
+    }
+
+    int onActiveCount()  {
+        std::lock_guard<std::mutex> lock(mMutex);
+        return mOnActive;
+    }
+
+    void reset() {
+        std::lock_guard<std::mutex> lock(mMutex);
+        mIsClosed = false;
+        mIsIdle = true;
+        mInError = false;
+        mOnClosed = 0;
+        mOnReady = 0;
+        mOnActive = 0;
+    }
+
+  private:
+    std::mutex mMutex;
+    bool mIsClosed = false;
+    bool mIsIdle = true;
+    bool mInError = false; // should always stay false
+    int mOnClosed = 0;
+    int mOnReady = 0;
+    int mOnActive = 0;
+};
+
+class ImageReaderListener {
+  public:
+    static void onImageAvailable(void* obj, AImageReader* reader) {
+        ALOGV("%s", __FUNCTION__);
+        if (obj == nullptr) {
+            return;
+        }
+        ImageReaderListener* thiz = reinterpret_cast<ImageReaderListener*>(obj);
+        std::lock_guard<std::mutex> lock(thiz->mMutex);
+        thiz->mOnImageAvailableCount++;
+
+        AImage* img = nullptr;
+        media_status_t ret = AImageReader_acquireNextImage(reader, &img);
+        if (ret != AMEDIA_OK || img == nullptr) {
+            ALOGE("%s: acquire image from reader %p failed! ret: %d, img %p",
+                    __FUNCTION__, reader, ret, img);
+            return;
+        }
+
+        // TODO: validate image content
+        int32_t format = -1;
+        ret = AImage_getFormat(img, &format);
+        if (ret != AMEDIA_OK || format == -1) {
+            ALOGE("%s: get format for image %p failed! ret: %d, format %d",
+                    __FUNCTION__, img, ret, format);
+        }
+
+        // Save jpeg to SD card
+        if (thiz->mDumpFilePathBase && format == AIMAGE_FORMAT_JPEG) {
+            int32_t numPlanes = 0;
+            ret = AImage_getNumberOfPlanes(img, &numPlanes);
+            if (ret != AMEDIA_OK || numPlanes != 1) {
+                ALOGE("%s: get numPlanes for image %p failed! ret: %d, numPlanes %d",
+                        __FUNCTION__, img, ret, numPlanes);
+                AImage_delete(img);
+                return;
+            }
+
+            int32_t width = -1, height = -1;
+            ret = AImage_getWidth(img, &width);
+            if (ret != AMEDIA_OK || width <= 0) {
+                ALOGE("%s: get width for image %p failed! ret: %d, width %d",
+                        __FUNCTION__, img, ret, width);
+                AImage_delete(img);
+                return;
+            }
+
+            ret = AImage_getHeight(img, &height);
+            if (ret != AMEDIA_OK || height <= 0) {
+                ALOGE("%s: get height for image %p failed! ret: %d, height %d",
+                        __FUNCTION__, img, ret, height);
+                AImage_delete(img);
+                return;
+            }
+
+            uint8_t* data = nullptr;
+            int dataLength = 0;
+            ret =  AImage_getPlaneData(img, /*planeIdx*/0, &data, &dataLength);
+            if (ret != AMEDIA_OK || data == nullptr || dataLength <= 0) {
+                ALOGE("%s: get jpeg data for image %p failed! ret: %d, data %p, len %d",
+                        __FUNCTION__, img, ret, data, dataLength);
+                AImage_delete(img);
+                return;
+            }
+
+#if 0
+            char dumpFilePath[512];
+            sprintf(dumpFilePath, "%s/%dx%d.jpg", thiz->mDumpFilePathBase, width, height);
+            ALOGI("Writing jpeg file to %s", dumpFilePath);
+            FILE* file = fopen(dumpFilePath,"w+");
+
+            if (file != nullptr) {
+                fwrite(data, 1, dataLength, file);
+                fflush(file);
+                fclose(file);
+            }
+#endif
+        }
+
+        AImage_delete(img);
+    }
+
+    int onImageAvailableCount() {
+        std::lock_guard<std::mutex> lock(mMutex);
+        return mOnImageAvailableCount;
+    }
+
+    void setDumpFilePathBase(const char* path) {
+        std::lock_guard<std::mutex> lock(mMutex);
+        mDumpFilePathBase = path;
+    }
+
+    void reset() {
+        std::lock_guard<std::mutex> lock(mMutex);
+        mOnImageAvailableCount = 0;
+        mDumpFilePathBase = nullptr;
+    }
+
+  private:
+    // TODO: add mReader to make sure each listener is associated to one reader?
+    std::mutex mMutex;
+    int mOnImageAvailableCount = 0;
+    const char* mDumpFilePathBase = nullptr;
+};
+
+class StaticInfo {
+  public:
+    StaticInfo(ACameraMetadata* chars) : mChars(chars) {}
+
+    bool isColorOutputSupported() {
+        return isCapabilitySupported(ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE);
+    }
+
+    bool isCapabilitySupported(acamera_metadata_enum_android_request_available_capabilities_t cap) {
+        ACameraMetadata_const_entry entry;
+        ACameraMetadata_getConstEntry(mChars, ACAMERA_REQUEST_AVAILABLE_CAPABILITIES, &entry);
+        for (uint32_t i = 0; i < entry.count; i++) {
+            if (entry.data.u8[i] == cap) {
+                return true;
+            }
+        }
+        return false;
+    }
+  private:
+    const ACameraMetadata* mChars;
+};
+
+class PreviewTestCase {
+  public:
+    ~PreviewTestCase() {
+        resetCamera();
+        deInit();
+        if (mCameraManager) {
+            ACameraManager_delete(mCameraManager);
+            mCameraManager = nullptr;
+        }
+    }
+
+    PreviewTestCase() {
+        // create is guaranteed to succeed;
+        createManager();
+    }
+
+    // Free all resources except camera manager
+    void resetCamera() {
+        mReaderListener.reset();
+        mSessionListener.reset();
+        if (mSession) {
+            ACameraCaptureSession_close(mSession);
+            mSession = nullptr;
+        }
+        if (mDevice) {
+            ACameraDevice_close(mDevice);
+            mDevice = nullptr;
+        }
+        if (mImgReader) {
+            AImageReader_delete(mImgReader);
+            // No need to call ANativeWindow_release on imageReaderAnw
+            mImgReaderAnw = nullptr;
+            mImgReader = nullptr;
+        }
+        if (mPreviewAnw) {
+            ANativeWindow_release(mPreviewAnw);
+            mPreviewAnw = nullptr;
+        }
+        if (mOutputs) {
+            ACaptureSessionOutputContainer_free(mOutputs);
+            mOutputs = nullptr;
+        }
+        if (mPreviewOutput) {
+            ACaptureSessionOutput_free(mPreviewOutput);
+            mPreviewOutput = nullptr;
+        }
+        if (mImgReaderOutput) {
+            ACaptureSessionOutput_free(mImgReaderOutput);
+            mImgReaderOutput = nullptr;
+        }
+        if (mPreviewRequest) {
+            ACaptureRequest_free(mPreviewRequest);
+            mPreviewRequest = nullptr;
+        }
+        if (mStillRequest) {
+            ACaptureRequest_free(mStillRequest);
+            mStillRequest = nullptr;
+        }
+        if (mReqPreviewOutput) {
+            ACameraOutputTarget_free(mReqPreviewOutput);
+            mReqPreviewOutput = nullptr;
+        }
+        if (mReqImgReaderOutput) {
+            ACameraOutputTarget_free(mReqImgReaderOutput);
+            mReqImgReaderOutput = nullptr;
+        }
+
+        mImgReaderInited = false;
+        mPreviewInited = false;
+    }
+
+    camera_status_t initWithErrorLog() {
+        camera_status_t ret = ACameraManager_getCameraIdList(
+                mCameraManager, &mCameraIdList);
+        if (ret != ACAMERA_OK) {
+            LOG_ERROR(errorString, "Get camera id list failed: ret %d", ret);
+            return ret;
+        }
+        ret = ACameraManager_registerAvailabilityCallback(mCameraManager, &mServiceCb);
+        if (ret != ACAMERA_OK) {
+            LOG_ERROR(errorString, "Register availability callback failed: ret %d", ret);
+            return ret;
+        }
+        mMgrInited = true;
+        return ACAMERA_OK;
+    }
+
+    camera_status_t deInit () {
+        if (!mMgrInited) {
+            return ACAMERA_OK;
+        }
+
+        camera_status_t ret = ACameraManager_unregisterAvailabilityCallback(
+                mCameraManager, &mServiceCb);
+        if (ret != ACAMERA_OK) {
+            ALOGE("Unregister availability callback failed: ret %d", ret);
+            return ret;
+        }
+
+        if (mCameraIdList) {
+            ACameraManager_deleteCameraIdList(mCameraIdList);
+            mCameraIdList = nullptr;
+        }
+        mMgrInited = false;
+        return ACAMERA_OK;
+    }
+
+    int getNumCameras() {
+        if (!mMgrInited || !mCameraIdList) {
+            return -1;
+        }
+        return mCameraIdList->numCameras;
+    }
+
+    const char* getCameraId(int idx) {
+        if (!mMgrInited || !mCameraIdList || idx < 0 || idx >= mCameraIdList->numCameras) {
+            return nullptr;
+        }
+        return mCameraIdList->cameraIds[idx];
+    }
+
+    camera_status_t openCamera(const char* cameraId) {
+        if (mDevice) {
+            ALOGE("Cannot open camera before closing previously open one");
+            return ACAMERA_ERROR_INVALID_PARAMETER;
+        }
+        mCameraId = cameraId;
+        return ACameraManager_openCamera(mCameraManager, cameraId, &mDeviceCb, &mDevice);
+    }
+
+    camera_status_t closeCamera() {
+        camera_status_t ret = ACameraDevice_close(mDevice);
+        mDevice = nullptr;
+        return ret;
+    }
+
+    bool isCameraAvailable(const char* cameraId) {
+        if (!mMgrInited) {
+            ALOGE("Camera service listener has not been registered!");
+        }
+        return mServiceListener.isAvailable(cameraId);
+    }
+
+    media_status_t initImageReaderWithErrorLog(
+            int32_t width, int32_t height, int32_t format, int32_t maxImages) {
+        if (mImgReader || mImgReaderAnw) {
+            LOG_ERROR(errorString, "Cannot init image reader before closing existing one");
+            return AMEDIA_ERROR_UNKNOWN;
+        }
+
+        media_status_t ret = AImageReader_new(
+                width, height, format,
+                maxImages, &mImgReader);
+        if (ret != AMEDIA_OK) {
+            LOG_ERROR(errorString, "Create image reader. ret %d", ret);
+            return ret;
+        }
+        if (mImgReader == nullptr) {
+            LOG_ERROR(errorString, "null image reader created");
+            return AMEDIA_ERROR_UNKNOWN;
+        }
+
+        ret = AImageReader_setImageListener(
+                mImgReader, &mReaderCb);
+        if (ret != AMEDIA_OK) {
+            LOG_ERROR(errorString, "Set AImageReader listener failed. ret %d", ret);
+            return ret;
+        }
+
+        ret = AImageReader_getWindow(mImgReader, &mImgReaderAnw);
+        if (ret != AMEDIA_OK) {
+            LOG_ERROR(errorString, "AImageReader_getWindow failed. ret %d", ret);
+            return ret;
+        }
+        if (mImgReaderAnw == nullptr) {
+            LOG_ERROR(errorString, "Null ANW from AImageReader!");
+            return AMEDIA_ERROR_UNKNOWN;
+        }
+        mImgReaderInited = true;
+        return AMEDIA_OK;
+    }
+
+    ANativeWindow* initPreviewAnw(JNIEnv* env, jobject jSurface) {
+        if (mPreviewAnw) {
+            ALOGE("Cannot init preview twice!");
+            return nullptr;
+        }
+        mPreviewAnw =  ANativeWindow_fromSurface(env, jSurface);
+        mPreviewInited = true;
+        return mPreviewAnw;
+    }
+
+    camera_status_t createCaptureSessionWithLog() {
+        if (mSession) {
+            LOG_ERROR(errorString, "Cannot create session before closing existing one");
+            return ACAMERA_ERROR_UNKNOWN;
+        }
+
+        if (!mMgrInited || (!mImgReaderInited && !mPreviewInited)) {
+            LOG_ERROR(errorString, "Cannot create session. mgrInit %d readerInit %d previewInit %d",
+                    mMgrInited, mImgReaderInited, mPreviewInited);
+            return ACAMERA_ERROR_UNKNOWN;
+        }
+
+        camera_status_t ret = ACaptureSessionOutputContainer_create(&mOutputs);
+        if (ret != ACAMERA_OK) {
+            LOG_ERROR(errorString, "Create capture session output container failed. ret %d", ret);
+            return ret;
+        }
+
+        if (mImgReaderInited) {
+            ret = ACaptureSessionOutput_create(mImgReaderAnw, &mImgReaderOutput);
+            if (ret != ACAMERA_OK || mImgReaderOutput == nullptr) {
+                LOG_ERROR(errorString,
+                        "Sesssion image reader output create fail! ret %d output %p",
+                        ret, mImgReaderOutput);
+                if (ret == ACAMERA_OK) {
+                    ret = ACAMERA_ERROR_UNKNOWN; // ret OK but output is null
+                }
+                return ret;
+            }
+
+            ret = ACaptureSessionOutputContainer_add(mOutputs, mImgReaderOutput);
+            if (ret != ACAMERA_OK) {
+                LOG_ERROR(errorString, "Sesssion image reader output add failed! ret %d", ret);
+                return ret;
+            }
+        }
+
+        if (mPreviewInited) {
+            ret = ACaptureSessionOutput_create(mPreviewAnw, &mPreviewOutput);
+            if (ret != ACAMERA_OK || mPreviewOutput == nullptr) {
+                LOG_ERROR(errorString,
+                        "Sesssion preview output create fail! ret %d output %p",
+                        ret, mPreviewOutput);
+                if (ret == ACAMERA_OK) {
+                    ret = ACAMERA_ERROR_UNKNOWN; // ret OK but output is null
+                }
+                return ret;
+            }
+
+            ret = ACaptureSessionOutputContainer_add(mOutputs, mPreviewOutput);
+            if (ret != ACAMERA_OK) {
+                LOG_ERROR(errorString, "Sesssion preview output add failed! ret %d", ret);
+                return ret;
+            }
+        }
+
+        ret = ACameraDevice_createCaptureSession(
+                mDevice, mOutputs, &mSessionCb, &mSession);
+        if (ret != ACAMERA_OK || mSession == nullptr) {
+            LOG_ERROR(errorString, "Create session for camera %s failed. ret %d session %p",
+                    mCameraId, ret, mSession);
+            if (ret == ACAMERA_OK) {
+                ret = ACAMERA_ERROR_UNKNOWN; // ret OK but session is null
+            }
+            return ret;
+        }
+
+        return ACAMERA_OK;
+    }
+
+    void closeSession() {
+        if (mSession != nullptr) {
+            ACameraCaptureSession_close(mSession);
+        }
+        if (mOutputs) {
+            ACaptureSessionOutputContainer_free(mOutputs);
+            mOutputs = nullptr;
+        }
+        if (mPreviewOutput) {
+            ACaptureSessionOutput_free(mPreviewOutput);
+            mPreviewOutput = nullptr;
+        }
+        if (mImgReaderOutput) {
+            ACaptureSessionOutput_free(mImgReaderOutput);
+            mImgReaderOutput = nullptr;
+        }
+        mSession = nullptr;
+    }
+
+    camera_status_t createRequestsWithErrorLog() {
+        if (mPreviewRequest || mStillRequest) {
+            LOG_ERROR(errorString, "Cannot create requests before deleteing existing one");
+            return ACAMERA_ERROR_UNKNOWN;
+        }
+
+        if (mDevice == nullptr || (!mPreviewInited && !mImgReaderInited)) {
+            LOG_ERROR(errorString,
+                    "Cannot create request. device %p previewInit %d readeInit %d",
+                    mDevice, mPreviewInited, mImgReaderInited);
+            return ACAMERA_ERROR_UNKNOWN;
+        }
+
+        camera_status_t ret;
+        if (mPreviewInited) {
+            ret = ACameraDevice_createCaptureRequest(
+                    mDevice, TEMPLATE_PREVIEW, &mPreviewRequest);
+            if (ret != ACAMERA_OK) {
+                LOG_ERROR(errorString, "Camera %s create preview request failed. ret %d",
+                        mCameraId, ret);
+                return ret;
+            }
+
+            ret = ACameraOutputTarget_create(mPreviewAnw, &mReqPreviewOutput);
+            if (ret != ACAMERA_OK) {
+                LOG_ERROR(errorString,
+                        "Camera %s create request preview output target failed. ret %d",
+                        mCameraId, ret);
+                return ret;
+            }
+
+            ret = ACaptureRequest_addTarget(mPreviewRequest, mReqPreviewOutput);
+            if (ret != ACAMERA_OK) {
+                LOG_ERROR(errorString, "Camera %s add preview request output failed. ret %d",
+                        mCameraId, ret);
+                return ret;
+            }
+        } else {
+            ALOGI("Preview not inited. Will not create preview request!");
+        }
+
+        if (mImgReaderInited) {
+            ret = ACameraDevice_createCaptureRequest(
+                    mDevice, TEMPLATE_STILL_CAPTURE, &mStillRequest);
+            if (ret != ACAMERA_OK) {
+                LOG_ERROR(errorString, "Camera %s create still request failed. ret %d",
+                        mCameraId, ret);
+                return ret;
+            }
+
+            ret = ACameraOutputTarget_create(mImgReaderAnw, &mReqImgReaderOutput);
+            if (ret != ACAMERA_OK) {
+                LOG_ERROR(errorString,
+                        "Camera %s create request reader output target failed. ret %d",
+                        mCameraId, ret);
+                return ret;
+            }
+
+            ret = ACaptureRequest_addTarget(mStillRequest, mReqImgReaderOutput);
+            if (ret != ACAMERA_OK) {
+                LOG_ERROR(errorString, "Camera %s add still request output failed. ret %d",
+                        mCameraId, ret);
+                return ret;
+            }
+
+            if (mPreviewInited) {
+                ret = ACaptureRequest_addTarget(mStillRequest, mReqPreviewOutput);
+                if (ret != ACAMERA_OK) {
+                    LOG_ERROR(errorString,
+                            "Camera %s add still request preview output failed. ret %d",
+                            mCameraId, ret);
+                    return ret;
+                }
+            }
+        } else {
+            ALOGI("AImageReader not inited. Will not create still request!");
+        }
+
+        return ACAMERA_OK;
+    }
+
+    camera_status_t startPreview() {
+        if (mSession == nullptr || mPreviewRequest == nullptr) {
+            ALOGE("Testcase cannot start preview: session %p, preview request %p",
+                    mSession, mPreviewRequest);
+            return ACAMERA_ERROR_UNKNOWN;
+        }
+        int previewSeqId;
+        return ACameraCaptureSession_setRepeatingRequest(
+                mSession, nullptr, 1, &mPreviewRequest, &previewSeqId);
+    }
+
+    camera_status_t takePicture() {
+        if (mSession == nullptr || mStillRequest == nullptr) {
+            ALOGE("Testcase cannot take picture: session %p, still request %p",
+                    mSession, mStillRequest);
+            return ACAMERA_ERROR_UNKNOWN;
+        }
+        int seqId;
+        return ACameraCaptureSession_capture(
+                mSession, nullptr, 1, &mStillRequest, &seqId);
+    }
+
+    int getReaderImageCount() {
+        return mReaderListener.onImageAvailableCount();
+    }
+
+    camera_status_t resetWithErrorLog() {
+        camera_status_t ret;
+
+        mReaderListener.reset();
+        closeSession();
+
+        for (int i = 0; i < 50; i++) {
+            usleep(100000); // sleep 100ms
+            if (mSessionListener.isClosed()) {
+                ALOGI("Session take ~%d ms to close", i*100);
+                break;
+            }
+        }
+
+        if (!mSessionListener.isClosed() || mSessionListener.onClosedCount() != 1) {
+            LOG_ERROR(errorString,
+                    "Session for camera %s close error. isClosde %d close count %d",
+                    mCameraId, mSessionListener.isClosed(), mSessionListener.onClosedCount());
+            return ACAMERA_ERROR_UNKNOWN;
+        }
+        mSessionListener.reset();
+
+        ret = closeCamera();
+        if (ret != ACAMERA_OK) {
+            LOG_ERROR(errorString, "Close camera device %s failure. ret %d", mCameraId, ret);
+            return ret;
+        }
+
+        resetCamera();
+        return ACAMERA_OK;
+    }
+
+    void setDumpFilePathBase(const char* path) {
+        mReaderListener.setDumpFilePathBase(path);
+    }
+
+    CaptureSessionListener* getSessionListener() {
+        return &mSessionListener;
+    }
+
+  private:
+    ACameraManager* createManager() {
+        if (!mCameraManager) {
+            mCameraManager = ACameraManager_create();
+        }
+        return mCameraManager;
+    }
+
+    CameraServiceListener mServiceListener;
+    ACameraManager_AvailabilityCallbacks mServiceCb {
+        &mServiceListener,
+        CameraServiceListener::onAvailable,
+        CameraServiceListener::onUnavailable
+    };
+    CameraDeviceListener mDeviceListener;
+    ACameraDevice_StateCallbacks mDeviceCb {
+        &mDeviceListener,
+        CameraDeviceListener::onDisconnected,
+        CameraDeviceListener::onError
+    };
+    CaptureSessionListener mSessionListener;
+    ACameraCaptureSession_stateCallbacks mSessionCb {
+        &mSessionListener,
+        CaptureSessionListener::onClosed,
+        CaptureSessionListener::onReady,
+        CaptureSessionListener::onActive
+    };
+
+    // TODO: capture listeners
+    ImageReaderListener mReaderListener;
+    AImageReader_ImageListener mReaderCb {
+        &mReaderListener,
+        ImageReaderListener::onImageAvailable
+    };
+
+    ACameraIdList* mCameraIdList = nullptr;
+    ACameraDevice* mDevice = nullptr;
+    AImageReader* mImgReader = nullptr;
+    ANativeWindow* mImgReaderAnw = nullptr;
+    ANativeWindow* mPreviewAnw = nullptr;
+    ACameraManager* mCameraManager = nullptr;
+    ACaptureSessionOutputContainer* mOutputs = nullptr;
+    ACaptureSessionOutput* mPreviewOutput = nullptr;
+    ACaptureSessionOutput* mImgReaderOutput = nullptr;
+    ACameraCaptureSession* mSession = nullptr;
+    ACaptureRequest* mPreviewRequest = nullptr;
+    ACaptureRequest* mStillRequest = nullptr;
+    ACameraOutputTarget* mReqPreviewOutput = nullptr;
+    ACameraOutputTarget* mReqImgReaderOutput = nullptr;
+    const char* mCameraId;
+
+    bool mMgrInited = false; // cameraId, serviceListener
+    bool mImgReaderInited = false;
+    bool mPreviewInited = false;
+};
+
+jint throwAssertionError(JNIEnv* env, const char* message)
+{
+    jclass assertionClass;
+    const char* className = "junit/framework/AssertionFailedError";
+
+    assertionClass = env->FindClass(className);
+    if (assertionClass == nullptr) {
+        ALOGE("Native throw error: cannot find class %s", className);
+        return -1;
+    }
+    return env->ThrowNew(assertionClass, message);
+}
+
+extern "C" jboolean
+Java_android_hardware_camera2_cts_NativeCameraManagerTest_\
+testCameraManagerGetAndCloseNative(
+        JNIEnv* env, jclass /*clazz*/) {
+    bool pass = false;
+    ALOGV("%s", __FUNCTION__);
+    ACameraManager* cameraManager2 = nullptr;
+    ACameraManager* cameraManager3 = nullptr;
+    ACameraManager* cameraManager4 = nullptr;
+    camera_status_t ret = ACAMERA_OK;
+    ACameraManager* cameraManager = ACameraManager_create();
+    if (cameraManager == nullptr) {
+        LOG_ERROR(errorString, "ACameraManager_create returns nullptr");
+        goto cleanup;
+    }
+    ACameraManager_delete(cameraManager);
+    cameraManager = nullptr;
+
+    // Test get/close multiple instances
+    cameraManager = ACameraManager_create();
+    cameraManager2 = ACameraManager_create();
+    if (cameraManager2 == nullptr) {
+        LOG_ERROR(errorString, "ACameraManager_create 2 returns nullptr");
+        goto cleanup;
+    }
+    ACameraManager_delete(cameraManager);
+    cameraManager = nullptr;
+    cameraManager3 = ACameraManager_create();
+    if (cameraManager3 == nullptr) {
+        LOG_ERROR(errorString, "ACameraManager_create 3 returns nullptr");
+        goto cleanup;
+    }
+    cameraManager4 = ACameraManager_create();
+        if (cameraManager4 == nullptr) {
+        LOG_ERROR(errorString, "ACameraManager_create 4 returns nullptr");
+        goto cleanup;
+    }
+    ACameraManager_delete(cameraManager3);
+    ACameraManager_delete(cameraManager2);
+    ACameraManager_delete(cameraManager4);
+
+    pass = true;
+cleanup:
+    if (cameraManager) {
+        ACameraManager_delete(cameraManager);
+    }
+    ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "fail");
+    if (!pass) {
+        throwAssertionError(env, errorString);
+    }
+    return pass;
+}
+
+extern "C" jboolean
+Java_android_hardware_camera2_cts_NativeCameraManagerTest_\
+testCameraManagerGetCameraIdsNative(
+        JNIEnv* env, jclass /*clazz*/) {
+    ALOGV("%s", __FUNCTION__);
+    bool pass = false;
+    ACameraManager* mgr = ACameraManager_create();
+    ACameraIdList *cameraIdList = nullptr;
+    camera_status_t ret = ACameraManager_getCameraIdList(mgr, &cameraIdList);
+    if (ret != ACAMERA_OK || cameraIdList == nullptr) {
+        LOG_ERROR(errorString, "Get camera id list failed: ret %d, cameraIdList %p",
+                ret, cameraIdList);
+        goto cleanup;
+    }
+    ALOGI("Number of cameras: %d", cameraIdList->numCameras);
+    for (int i = 0; i < cameraIdList->numCameras; i++) {
+        ALOGI("Camera ID: %s", cameraIdList->cameraIds[i]);
+    }
+    ACameraManager_deleteCameraIdList(cameraIdList);
+    cameraIdList = nullptr;
+
+    pass = true;
+cleanup:
+    if (mgr) {
+        ACameraManager_delete(mgr);
+    }
+    if (cameraIdList) {
+        ACameraManager_deleteCameraIdList(cameraIdList);
+    }
+    ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "fail");
+    if (!pass) {
+        throwAssertionError(env, errorString);
+    }
+    return pass;
+}
+
+extern "C" jboolean
+Java_android_hardware_camera2_cts_NativeCameraManagerTest_\
+testCameraManagerAvailabilityCallbackNative(
+        JNIEnv* env, jclass /*clazz*/) {
+    ALOGV("%s", __FUNCTION__);
+    bool pass = false;
+    ACameraManager* mgr = ACameraManager_create();
+    ACameraIdList *cameraIdList = nullptr;
+    camera_status_t ret = ACameraManager_getCameraIdList(mgr, &cameraIdList);
+    int numCameras = cameraIdList->numCameras;
+    CameraServiceListener listener;
+    ACameraManager_AvailabilityCallbacks cbs {
+            &listener,
+            CameraServiceListener::onAvailable,
+            CameraServiceListener::onUnavailable};
+    ret = ACameraManager_registerAvailabilityCallback(mgr, &cbs);
+    if (ret != ACAMERA_OK) {
+        LOG_ERROR(errorString, "Register availability callback failed: ret %d", ret);
+        goto cleanup;
+    }
+    sleep(1); // sleep a second to give some time for callbacks to happen
+
+    // Should at least get onAvailable for each camera once
+    if (listener.getAvailableCount() < numCameras) {
+        LOG_ERROR(errorString, "Expect at least %d available callback but only got %d",
+                numCameras, listener.getAvailableCount());
+        goto cleanup;
+    }
+
+    ret = ACameraManager_unregisterAvailabilityCallback(mgr, &cbs);
+    if (ret != ACAMERA_OK) {
+        LOG_ERROR(errorString, "Unregister availability callback failed: ret %d", ret);
+        goto cleanup;
+    }
+    pass = true;
+cleanup:
+    if (cameraIdList) {
+        ACameraManager_deleteCameraIdList(cameraIdList);
+    }
+    if (mgr) {
+        ACameraManager_delete(mgr);
+    }
+    ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
+    if (!pass) {
+        throwAssertionError(env, errorString);
+    }
+    return pass;
+}
+
+extern "C" jboolean
+Java_android_hardware_camera2_cts_NativeCameraManagerTest_\
+testCameraManagerCharacteristicsNative(
+        JNIEnv* env, jclass /*clazz*/) {
+    ALOGV("%s", __FUNCTION__);
+    bool pass = false;
+    ACameraManager* mgr = ACameraManager_create();
+    ACameraIdList *cameraIdList = nullptr;
+    ACameraMetadata* chars = nullptr;
+    int numCameras = 0;
+    camera_status_t ret = ACameraManager_getCameraIdList(mgr, &cameraIdList);
+    if (ret != ACAMERA_OK || cameraIdList == nullptr) {
+        LOG_ERROR(errorString, "Get camera id list failed: ret %d, cameraIdList %p",
+                ret, cameraIdList);
+        goto cleanup;
+    }
+    numCameras = cameraIdList->numCameras;
+
+    for (int i = 0; i < numCameras; i++) {
+        ret = ACameraManager_getCameraCharacteristics(
+                mgr, cameraIdList->cameraIds[i], &chars);
+        if (ret != ACAMERA_OK) {
+            LOG_ERROR(errorString, "Get camera characteristics failed: ret %d", ret);
+            goto cleanup;
+        }
+
+        int32_t numTags = 0;
+        const uint32_t* tags = nullptr;
+        ret = ACameraMetadata_getAllTags(chars, &numTags, &tags);
+        if (ret != ACAMERA_OK) {
+            LOG_ERROR(errorString, "Get camera characteristics tags failed: ret %d", ret);
+            goto cleanup;
+        }
+
+        for (int tid = 0; tid < numTags; tid++) {
+            uint32_t tagId = tags[tid];
+            ALOGV("%s capture request contains key %u", __FUNCTION__, tagId);
+            uint32_t sectionId = tagId >> 16;
+            if (sectionId >= ACAMERA_SECTION_COUNT && sectionId < ACAMERA_VENDOR) {
+                LOG_ERROR(errorString, "Unknown tagId %u, sectionId %u", tagId, sectionId);
+                goto cleanup;
+            }
+        }
+
+        ACameraMetadata_const_entry entry;
+        ret = ACameraMetadata_getConstEntry(chars, ACAMERA_REQUEST_AVAILABLE_CAPABILITIES, &entry);
+        if (ret != ACAMERA_OK) {
+            LOG_ERROR(errorString, "Get const available capabilities key failed. ret %d", ret);
+            goto cleanup;
+        }
+
+        // Check the entry is actually legit
+        if (entry.tag != ACAMERA_REQUEST_AVAILABLE_CAPABILITIES ||
+                entry.count == 0 || entry.type != ACAMERA_TYPE_BYTE || entry.data.i32 == nullptr) {
+            LOG_ERROR(errorString,
+                    "Bad available capabilities key: tag: %d (expected %d), count %u (expect > 0), "
+                    "type %d (expected %d), data %p (expected not null)",
+                    entry.tag, ACAMERA_REQUEST_AVAILABLE_CAPABILITIES, entry.count,
+                    entry.type, ACAMERA_TYPE_BYTE, entry.data.i32);
+            goto cleanup;
+        }
+        // All camera supports BC except depth only cameras
+        bool supportBC = false, supportDepth = false;
+        for (uint32_t i = 0; i < entry.count; i++) {
+            if (entry.data.u8[i] == ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE) {
+                supportBC = true;
+            }
+            if (entry.data.u8[i] == ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT) {
+                supportDepth = true;
+            }
+        }
+        if (!(supportBC || supportDepth)) {
+            LOG_ERROR(errorString, "Error: camera device %s does not support either BC or DEPTH",
+                    cameraIdList->cameraIds[i]);
+            goto cleanup;
+        }
+
+        // Check get unknown value fails
+        uint32_t badTag = (uint32_t) ACAMERA_VENDOR_START - 1;
+        ret = ACameraMetadata_getConstEntry(chars, ACAMERA_VENDOR_START, &entry);
+        if (ret == ACAMERA_OK) {
+            LOG_ERROR(errorString, "Error: get unknown tag should fail!");
+            goto cleanup;
+        }
+
+        ACameraMetadata_free(chars);
+        chars = nullptr;
+    }
+
+    pass = true;
+cleanup:
+    if (chars) {
+        ACameraMetadata_free(chars);
+    }
+    ACameraManager_deleteCameraIdList(cameraIdList);
+    ACameraManager_delete(mgr);
+    ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
+    if (!pass) {
+        throwAssertionError(env, errorString);
+    }
+    return pass;
+}
+
+extern "C" jboolean
+Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
+testCameraDeviceOpenAndCloseNative(
+        JNIEnv* env, jclass /*clazz*/) {
+    ALOGV("%s", __FUNCTION__);
+    int numCameras = 0;
+    bool pass = false;
+    PreviewTestCase testCase;
+
+    camera_status_t ret = testCase.initWithErrorLog();
+    if (ret != ACAMERA_OK) {
+        // Don't log error here. testcase did it
+        goto cleanup;
+    }
+
+    numCameras = testCase.getNumCameras();
+    if (numCameras < 0) {
+        LOG_ERROR(errorString, "Testcase returned negavtive number of cameras: %d", numCameras);
+        goto cleanup;
+    }
+
+    for (int i = 0; i < numCameras; i++) {
+        const char* cameraId = testCase.getCameraId(i);
+        if (cameraId == nullptr) {
+            LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
+            goto cleanup;
+        }
+
+        ret = testCase.openCamera(cameraId);
+        if (ret != ACAMERA_OK) {
+            LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
+            goto cleanup;
+        }
+
+        usleep(100000); // sleep to give some time for callbacks to happen
+
+        if (testCase.isCameraAvailable(cameraId)) {
+            LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
+            goto cleanup;
+        }
+
+        ret = testCase.closeCamera();
+        if (ret != ACAMERA_OK) {
+            LOG_ERROR(errorString, "Close camera device %s failure. ret %d", cameraId, ret);
+            goto cleanup;
+        }
+
+        usleep(100000); // sleep to give some time for callbacks to happen
+
+        if (!testCase.isCameraAvailable(cameraId)) {
+            LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
+            goto cleanup;
+        }
+    }
+
+    ret = testCase.deInit();
+    if (ret != ACAMERA_OK) {
+        LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
+        goto cleanup;
+    }
+
+    pass = true;
+cleanup:
+    ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
+    if (!pass) {
+        throwAssertionError(env, errorString);
+    }
+    return pass;
+}
+
+extern "C" jboolean
+Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
+testCameraDeviceCreateCaptureRequestNative(
+        JNIEnv* env, jclass /*clazz*/) {
+    ALOGV("%s", __FUNCTION__);
+    bool pass = false;
+    ACameraManager* mgr = ACameraManager_create();
+    ACameraIdList* cameraIdList = nullptr;
+    ACameraDevice* device = nullptr;
+    ACaptureRequest* request = nullptr;
+    ACameraMetadata* chars = nullptr;
+    camera_status_t ret = ACameraManager_getCameraIdList(mgr, &cameraIdList);
+
+    int numCameras = cameraIdList->numCameras;
+    for (int i = 0; i < numCameras; i++) {
+        CameraDeviceListener deviceListener;
+        const char* cameraId = cameraIdList->cameraIds[i];
+        ACameraDevice_StateCallbacks deviceCb {
+            &deviceListener,
+            CameraDeviceListener::onDisconnected,
+            CameraDeviceListener::onError
+        };
+        ret = ACameraManager_openCamera(mgr, cameraId, &deviceCb, &device);
+        if (ret != ACAMERA_OK) {
+            LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
+            goto cleanup;
+        }
+
+        ret = ACameraManager_getCameraCharacteristics(mgr, cameraId, &chars);
+        if (ret != ACAMERA_OK || chars == nullptr) {
+            LOG_ERROR(errorString, "Get camera %s characteristics failure. ret %d, chars %p",
+                    cameraId, ret, chars);
+            goto cleanup;
+        }
+        StaticInfo staticInfo(chars);
+
+        for (int t = TEMPLATE_PREVIEW; t <= TEMPLATE_MANUAL; t++) {
+            ACameraDevice_request_template templateId =
+                    static_cast<ACameraDevice_request_template>(t);
+            ret = ACameraDevice_createCaptureRequest(device, templateId, &request);
+            if (ret == ACAMERA_ERROR_UNSUPPORTED) {
+                // template not supported. skip
+                continue;
+            }
+
+            if (ret != ACAMERA_OK) {
+                LOG_ERROR(errorString, "Create capture request failed!: ret %d", ret);
+                goto cleanup;
+            }
+
+            int32_t numTags = 0;
+            const uint32_t* tags = nullptr;
+            ret = ACaptureRequest_getAllTags(request, &numTags, &tags);
+            if (ret != ACAMERA_OK) {
+                LOG_ERROR(errorString, "Get capture request tags failed: ret %d", ret);
+                goto cleanup;
+            }
+
+            for (int tid = 0; tid < numTags; tid++) {
+                uint32_t tagId = tags[tid];
+                ALOGV("%s capture request contains key %u", __FUNCTION__, tagId);
+                uint32_t sectionId = tagId >> 16;
+                if (sectionId >= ACAMERA_SECTION_COUNT && sectionId < ACAMERA_VENDOR) {
+                    LOG_ERROR(errorString, "Unknown tagId %u, sectionId %u", tagId, sectionId);
+                    goto cleanup;
+                }
+            }
+
+            // try get/set capture request fields
+            ACameraMetadata_const_entry entry;
+            ret = ACaptureRequest_getConstEntry(request, ACAMERA_CONTROL_AE_MODE, &entry);
+            if (ret != ACAMERA_OK) {
+                LOG_ERROR(errorString, "Get AE mode key failed. ret %d", ret);
+                goto cleanup;
+            }
+
+            if (entry.tag != ACAMERA_CONTROL_AE_MODE || entry.type != ACAMERA_TYPE_BYTE ||\
+                    entry.count != 1) {
+                LOG_ERROR(errorString,
+                        "Bad AE mode key. tag 0x%x (expect 0x%x), type %d (expect %d), "
+                        "count %d (expect %d)",
+                        entry.tag, ACAMERA_CONTROL_AE_MODE, entry.type, ACAMERA_TYPE_BYTE,
+                        entry.count, 1);
+                goto cleanup;
+            }
+            if (t == TEMPLATE_MANUAL) {
+                if (entry.data.u8[0] != ACAMERA_CONTROL_AE_MODE_OFF) {
+                    LOG_ERROR(errorString, "Error: MANUAL template AE mode %d (expect %d)",
+                            entry.data.u8[0], ACAMERA_CONTROL_AE_MODE_OFF);
+                    goto cleanup;
+                }
+                // try set AE_MODE_ON
+                uint8_t aeMode = ACAMERA_CONTROL_AE_MODE_ON;
+                ret = ACaptureRequest_setEntry_u8(
+                        request, ACAMERA_CONTROL_AE_MODE, /*count*/ 1, &aeMode);
+                if (ret != ACAMERA_OK) {
+                    LOG_ERROR(errorString,
+                            "Error: Camera %s template %d: update AE mode key fail. ret %d",
+                            cameraId, t, ret);
+                    goto cleanup;
+                }
+                ret = ACaptureRequest_getConstEntry(
+                        request, ACAMERA_CONTROL_AE_MODE, &entry);
+                if (ret != ACAMERA_OK) {
+                    LOG_ERROR(errorString, "Get AE mode key failed. ret %d", ret);
+                    goto cleanup;
+                }
+                if (entry.data.u8[0] != aeMode) {
+                    LOG_ERROR(errorString,
+                            "Error: AE mode key is not updated. expect %d but get %d",
+                            aeMode, entry.data.u8[0]);
+                    goto cleanup;
+                }
+            } else {
+                if (staticInfo.isColorOutputSupported()) {
+                    if (entry.data.u8[0] != ACAMERA_CONTROL_AE_MODE_ON) {
+                        LOG_ERROR(errorString,
+                                "Error: Template %d has wrong AE mode %d (expect %d)",
+                                t, entry.data.u8[0], ACAMERA_CONTROL_AE_MODE_ON);
+                        goto cleanup;
+                    }
+                    // try set AE_MODE_OFF
+                    if (staticInfo.isCapabilitySupported(
+                            ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR)) {
+                        uint8_t aeMode = ACAMERA_CONTROL_AE_MODE_OFF;
+                        ret = ACaptureRequest_setEntry_u8(
+                                request, ACAMERA_CONTROL_AE_MODE, /*count*/ 1, &aeMode);
+                        if (ret != ACAMERA_OK) {
+                            LOG_ERROR(errorString,
+                                    "Error: Camera %s template %d: update AE mode key fail. ret %d",
+                                    cameraId, t, ret);
+                            goto cleanup;
+                        }
+                        ret = ACaptureRequest_getConstEntry(
+                                request, ACAMERA_CONTROL_AE_MODE, &entry);
+                        if (ret != ACAMERA_OK) {
+                            LOG_ERROR(errorString, "Get AE mode key failed. ret %d", ret);
+                            goto cleanup;
+                        }
+                        if (entry.data.u8[0] != aeMode) {
+                            LOG_ERROR(errorString,
+                                    "Error: AE mode key is not updated. expect %d but get %d",
+                                    aeMode, entry.data.u8[0]);
+                            goto cleanup;
+                        }
+                    }
+                }
+            }
+            ACaptureRequest_free(request);
+            request = nullptr;
+        }
+
+        ACameraMetadata_free(chars);
+        chars = nullptr;
+        ACameraDevice_close(device);
+        device = nullptr;
+    }
+
+    pass = true;
+cleanup:
+    if (cameraIdList) {
+        ACameraManager_deleteCameraIdList(cameraIdList);
+    }
+    if (request) {
+        ACaptureRequest_free(request);
+    }
+    if (chars) {
+        ACameraMetadata_free(chars);
+    }
+    if (device) {
+        ACameraDevice_close(device);
+    }
+    if (mgr) {
+        ACameraManager_delete(mgr);
+    }
+    ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
+    if (!pass) {
+        throwAssertionError(env, errorString);
+    }
+    return pass;
+}
+
+extern "C" jboolean
+Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
+testCameraDeviceSessionOpenAndCloseNative(
+        JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface) {
+    ALOGV("%s", __FUNCTION__);
+    int numCameras = 0;
+    bool pass = false;
+    PreviewTestCase testCase;
+
+    camera_status_t ret = testCase.initWithErrorLog();
+    if (ret != ACAMERA_OK) {
+        // Don't log error here. testcase did it
+        goto cleanup;
+    }
+
+    numCameras = testCase.getNumCameras();
+    if (numCameras < 0) {
+        LOG_ERROR(errorString, "Testcase returned negavtive number of cameras: %d", numCameras);
+        goto cleanup;
+    }
+
+    for (int i = 0; i < numCameras; i++) {
+        const char* cameraId = testCase.getCameraId(i);
+        if (cameraId == nullptr) {
+            LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
+            goto cleanup;
+        }
+
+        ret = testCase.openCamera(cameraId);
+        if (ret != ACAMERA_OK) {
+            LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
+            goto cleanup;
+        }
+
+        usleep(100000); // sleep to give some time for callbacks to happen
+
+        if (testCase.isCameraAvailable(cameraId)) {
+            LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
+            goto cleanup;
+        }
+
+        ANativeWindow* previewAnw = testCase.initPreviewAnw(env, jPreviewSurface);
+        if (previewAnw == nullptr) {
+            LOG_ERROR(errorString, "Null ANW from preview surface!");
+            goto cleanup;
+        }
+
+        CaptureSessionListener* sessionListener = testCase.getSessionListener();
+        if (sessionListener == nullptr) {
+            LOG_ERROR(errorString, "Session listener camera %s is null", cameraId);
+            goto cleanup;
+        }
+
+        // Try open/close session multiple times
+        for (int j = 0; j < 5; j++) {
+            ret = testCase.createCaptureSessionWithLog();
+            if (ret != ACAMERA_OK) {
+                // Don't log error here. testcase did it
+                goto cleanup;
+            }
+
+            usleep(100000); // sleep to give some time for callbacks to happen
+
+            if (!sessionListener->isIdle()) {
+                LOG_ERROR(errorString, "Session for camera %s should be idle right after creation",
+                        cameraId);
+                goto cleanup;
+            }
+
+            testCase.closeSession();
+
+            usleep(100000); // sleep to give some time for callbacks to happen
+            if (!sessionListener->isClosed() || sessionListener->onClosedCount() != 1) {
+                LOG_ERROR(errorString,
+                        "Session for camera %s close error. isClosde %d close count %d",
+                        cameraId, sessionListener->isClosed(), sessionListener->onClosedCount());
+                goto cleanup;
+            }
+            sessionListener->reset();
+        }
+
+        // Try open/close really fast
+        ret = testCase.createCaptureSessionWithLog();
+        if (ret != ACAMERA_OK) {
+            LOG_ERROR(errorString, "Create session for camera %s failed. ret %d",
+                    cameraId, ret);
+            goto cleanup;
+        }
+        testCase.closeSession();
+        usleep(100000); // sleep to give some time for callbacks to happen
+        if (!sessionListener->isClosed() || sessionListener->onClosedCount() != 1) {
+            LOG_ERROR(errorString,
+                    "Session for camera %s close error. isClosde %d close count %d",
+                    cameraId, sessionListener->isClosed(), sessionListener->onClosedCount());
+            goto cleanup;
+        }
+
+        ret = testCase.resetWithErrorLog();
+        if (ret != ACAMERA_OK) {
+            // Don't log error here. testcase did it
+            goto cleanup;
+        }
+
+        usleep(100000); // sleep to give some time for callbacks to happen
+
+        if (!testCase.isCameraAvailable(cameraId)) {
+            LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
+            goto cleanup;
+        }
+    }
+
+    ret = testCase.deInit();
+    if (ret != ACAMERA_OK) {
+        LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
+        goto cleanup;
+    }
+
+    pass = true;
+cleanup:
+    ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
+    if (!pass) {
+        throwAssertionError(env, errorString);
+    }
+    return pass;
+}
+
+extern "C" jboolean
+Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
+testCameraDeviceSimplePreviewNative(
+        JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface) {
+    ALOGV("%s", __FUNCTION__);
+    int numCameras = 0;
+    bool pass = false;
+    PreviewTestCase testCase;
+
+    camera_status_t ret = testCase.initWithErrorLog();
+    if (ret != ACAMERA_OK) {
+        // Don't log error here. testcase did it
+        goto cleanup;
+    }
+
+    numCameras = testCase.getNumCameras();
+    if (numCameras < 0) {
+        LOG_ERROR(errorString, "Testcase returned negavtive number of cameras: %d", numCameras);
+        goto cleanup;
+    }
+
+    for (int i = 0; i < numCameras; i++) {
+        const char* cameraId = testCase.getCameraId(i);
+        if (cameraId == nullptr) {
+            LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
+            goto cleanup;
+        }
+
+        ret = testCase.openCamera(cameraId);
+        if (ret != ACAMERA_OK) {
+            LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
+            goto cleanup;
+        }
+
+        usleep(100000); // sleep to give some time for callbacks to happen
+
+        if (testCase.isCameraAvailable(cameraId)) {
+            LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
+            goto cleanup;
+        }
+
+        ANativeWindow* previewAnw = testCase.initPreviewAnw(env, jPreviewSurface);
+        if (previewAnw == nullptr) {
+            LOG_ERROR(errorString, "Null ANW from preview surface!");
+            goto cleanup;
+        }
+
+        ret = testCase.createCaptureSessionWithLog();
+        if (ret != ACAMERA_OK) {
+            // Don't log error here. testcase did it
+            goto cleanup;
+        }
+
+        ret = testCase.createRequestsWithErrorLog();
+        if (ret != ACAMERA_OK) {
+            // Don't log error here. testcase did it
+            goto cleanup;
+        }
+
+        ret = testCase.startPreview();
+        if (ret != ACAMERA_OK) {
+            LOG_ERROR(errorString, "Start preview failed!");
+            goto cleanup;
+        }
+
+        sleep(3);
+
+        ret = testCase.resetWithErrorLog();
+        if (ret != ACAMERA_OK) {
+            // Don't log error here. testcase did it
+            goto cleanup;
+        }
+
+        usleep(100000); // sleep to give some time for callbacks to happen
+
+        if (!testCase.isCameraAvailable(cameraId)) {
+            LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
+            goto cleanup;
+        }
+    }
+
+    ret = testCase.deInit();
+    if (ret != ACAMERA_OK) {
+        LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
+        goto cleanup;
+    }
+
+    pass = true;
+cleanup:
+    ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
+    if (!pass) {
+        throwAssertionError(env, errorString);
+    }
+    return pass;
+}
+
+extern "C" jboolean
+Java_android_hardware_camera2_cts_NativeImageReaderTest_\
+testJpegNative(
+        JNIEnv* env, jclass /*clazz*/, jstring jOutPath) {
+    ALOGV("%s", __FUNCTION__);
+    const int NUM_TEST_IMAGES = 10;
+    const int TEST_WIDTH  = 640;
+    const int TEST_HEIGHT = 480;
+    media_status_t mediaRet = AMEDIA_ERROR_UNKNOWN;
+    int numCameras = 0;
+    bool pass = false;
+    PreviewTestCase testCase;
+
+    const char* outPath = env->GetStringUTFChars(jOutPath, nullptr);
+    testCase.setDumpFilePathBase(outPath);
+    ALOGI("%s: out path is %s", __FUNCTION__, outPath);
+
+    camera_status_t ret = testCase.initWithErrorLog();
+    if (ret != ACAMERA_OK) {
+        // Don't log error here. testcase did it
+        goto cleanup;
+    }
+
+    numCameras = testCase.getNumCameras();
+    if (numCameras < 0) {
+        LOG_ERROR(errorString, "Testcase returned negavtive number of cameras: %d", numCameras);
+        goto cleanup;
+    }
+
+    for (int i = 0; i < numCameras; i++) {
+        const char* cameraId = testCase.getCameraId(i);
+        if (cameraId == nullptr) {
+            LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
+            goto cleanup;
+        }
+
+        ret = testCase.openCamera(cameraId);
+        if (ret != ACAMERA_OK) {
+            LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
+            goto cleanup;
+        }
+
+        usleep(100000); // sleep to give some time for callbacks to happen
+
+        if (testCase.isCameraAvailable(cameraId)) {
+            LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
+            goto cleanup;
+        }
+
+        mediaRet = testCase.initImageReaderWithErrorLog(
+                TEST_WIDTH, TEST_HEIGHT, AIMAGE_FORMAT_JPEG, NUM_TEST_IMAGES);
+        if (mediaRet != AMEDIA_OK) {
+            // Don't log error here. testcase did it
+            goto cleanup;
+        }
+
+        ret = testCase.createCaptureSessionWithLog();
+        if (ret != ACAMERA_OK) {
+            // Don't log error here. testcase did it
+            goto cleanup;
+        }
+
+        ret = testCase.createRequestsWithErrorLog();
+        if (ret != ACAMERA_OK) {
+            // Don't log error here. testcase did it
+            goto cleanup;
+        }
+
+        // Do some still capture
+        for (int capture = 0; capture < NUM_TEST_IMAGES; capture++) {
+            ret = testCase.takePicture();
+            if (ret != ACAMERA_OK) {
+                LOG_ERROR(errorString, "Camera %s capture(%d) failed. ret %d",
+                        cameraId, capture, ret);
+                goto cleanup;
+            }
+        }
+
+        // wait until all capture finished
+        for (int i = 0; i < 50; i++) {
+            usleep(100000); // sleep 100ms
+            if (testCase.getReaderImageCount() == NUM_TEST_IMAGES) {
+                ALOGI("Session take ~%d ms to capture %d images",
+                        i*100, NUM_TEST_IMAGES);
+                break;
+            }
+        }
+
+        if (testCase.getReaderImageCount() != NUM_TEST_IMAGES) {
+            LOG_ERROR(errorString, "Camera %s timeout capturing %d images. Got %d",
+                    cameraId, NUM_TEST_IMAGES, testCase.getReaderImageCount());
+            goto cleanup;
+        }
+
+        ret = testCase.resetWithErrorLog();
+        if (ret != ACAMERA_OK) {
+            // Don't log error here. testcase did it
+            goto cleanup;
+        }
+
+        usleep(100000); // sleep to give some time for callbacks to happen
+
+        if (!testCase.isCameraAvailable(cameraId)) {
+            LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
+            goto cleanup;
+        }
+    }
+
+    ret = testCase.deInit();
+    if (ret != ACAMERA_OK) {
+        LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
+        goto cleanup;
+    }
+
+    pass = true;
+
+cleanup:
+    env->ReleaseStringUTFChars(jOutPath, outPath);
+    ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
+    if (!pass) {
+        throwAssertionError(env, errorString);
+    }
+    return pass;
+}
+
+
+extern "C" jboolean
+Java_android_hardware_camera2_cts_NativeStillCaptureTest_\
+testStillCaptureNative(
+        JNIEnv* env, jclass /*clazz*/, jstring jOutPath, jobject jPreviewSurface) {
+    ALOGV("%s", __FUNCTION__);
+    const int NUM_TEST_IMAGES = 10;
+    const int TEST_WIDTH  = 640;
+    const int TEST_HEIGHT = 480;
+    media_status_t mediaRet = AMEDIA_ERROR_UNKNOWN;
+    int numCameras = 0;
+    bool pass = false;
+    PreviewTestCase testCase;
+
+    const char* outPath = env->GetStringUTFChars(jOutPath, nullptr);
+    testCase.setDumpFilePathBase(outPath);
+    ALOGI("%s: out path is %s", __FUNCTION__, outPath);
+
+    camera_status_t ret = testCase.initWithErrorLog();
+    if (ret != ACAMERA_OK) {
+        // Don't log error here. testcase did it
+        goto cleanup;
+    }
+
+    numCameras = testCase.getNumCameras();
+    if (numCameras < 0) {
+        LOG_ERROR(errorString, "Testcase returned negavtive number of cameras: %d", numCameras);
+        goto cleanup;
+    }
+
+    for (int i = 0; i < numCameras; i++) {
+        const char* cameraId = testCase.getCameraId(i);
+        if (cameraId == nullptr) {
+            LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
+            goto cleanup;
+        }
+
+        ret = testCase.openCamera(cameraId);
+        if (ret != ACAMERA_OK) {
+            LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
+            goto cleanup;
+        }
+
+        usleep(100000); // sleep to give some time for callbacks to happen
+
+        if (testCase.isCameraAvailable(cameraId)) {
+            LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
+            goto cleanup;
+        }
+
+        mediaRet = testCase.initImageReaderWithErrorLog(
+                TEST_WIDTH, TEST_HEIGHT, AIMAGE_FORMAT_JPEG, NUM_TEST_IMAGES);
+        if (mediaRet != AMEDIA_OK) {
+            // Don't log error here. testcase did it
+            goto cleanup;
+        }
+
+        ANativeWindow* previewAnw = testCase.initPreviewAnw(env, jPreviewSurface);
+        if (previewAnw == nullptr) {
+            LOG_ERROR(errorString, "Null ANW from preview surface!");
+            goto cleanup;
+        }
+
+        ret = testCase.createCaptureSessionWithLog();
+        if (ret != ACAMERA_OK) {
+            // Don't log error here. testcase did it
+            goto cleanup;
+        }
+
+        ret = testCase.createRequestsWithErrorLog();
+        if (ret != ACAMERA_OK) {
+            // Don't log error here. testcase did it
+            goto cleanup;
+        }
+
+        ret = testCase.startPreview();
+        if (ret != ACAMERA_OK) {
+            LOG_ERROR(errorString, "Start preview failed!");
+            goto cleanup;
+        }
+
+        // Let preview run some time
+        sleep(3);
+
+        // Do some still capture
+        for (int capture = 0; capture < NUM_TEST_IMAGES; capture++) {
+            ret = testCase.takePicture();
+            if (ret != ACAMERA_OK) {
+                LOG_ERROR(errorString, "Camera %s capture(%d) failed. ret %d",
+                        cameraId, capture, ret);
+                goto cleanup;
+            }
+        }
+
+        // wait until all capture finished
+        for (int i = 0; i < 50; i++) {
+            usleep(100000); // sleep 100ms
+            if (testCase.getReaderImageCount() == NUM_TEST_IMAGES) {
+                ALOGI("Session take ~%d ms to capture %d images",
+                        i*100, NUM_TEST_IMAGES);
+                break;
+            }
+        }
+
+        if (testCase.getReaderImageCount() != NUM_TEST_IMAGES) {
+            LOG_ERROR(errorString, "Camera %s timeout capturing %d images. Got %d",
+                    cameraId, NUM_TEST_IMAGES, testCase.getReaderImageCount());
+            goto cleanup;
+        }
+
+        ret = testCase.resetWithErrorLog();
+        if (ret != ACAMERA_OK) {
+            // Don't log error here. testcase did it
+            goto cleanup;
+        }
+
+        usleep(100000); // sleep to give some time for callbacks to happen
+
+        if (!testCase.isCameraAvailable(cameraId)) {
+            LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
+            goto cleanup;
+        }
+    }
+
+    ret = testCase.deInit();
+    if (ret != ACAMERA_OK) {
+        LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
+        goto cleanup;
+    }
+
+    pass = true;
+cleanup:
+    env->ReleaseStringUTFChars(jOutPath, outPath);
+    ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
+    if (!pass) {
+        throwAssertionError(env, errorString);
+    }
+    return pass;
+}
+
diff --git a/tests/camera/src/android/hardware/camera2/cts/AllocationTest.java b/tests/camera/src/android/hardware/camera2/cts/AllocationTest.java
index 0476477..2969753 100644
--- a/tests/camera/src/android/hardware/camera2/cts/AllocationTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/AllocationTest.java
@@ -95,8 +95,6 @@
         super.setContext(context);
         mCameraManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
         assertNotNull("Can't connect to camera manager!", mCameraManager);
-
-        RenderScriptSingleton.setContext(context);
     }
 
     @Override
@@ -111,6 +109,8 @@
         mCameraIterable = new CameraIterable();
         mSizeIterable = new SizeIterable();
         mResultIterable = new ResultIterable();
+
+        RenderScriptSingleton.setContext(getContext());
     }
 
     @Override
@@ -470,15 +470,14 @@
                     @Override
                     public void run(final Size size) throws CameraAccessException {
                         // Create a script graph that converts YUV to RGB
-                        final ScriptGraph scriptGraph = ScriptGraph.create()
+                        try (ScriptGraph scriptGraph = ScriptGraph.create()
                                 .configureInputWithSurface(size, YUV_420_888)
                                 .chainScript(ScriptYuvToRgb.class)
-                                .buildGraph();
+                                .buildGraph()) {
 
-                        if (VERBOSE) Log.v(TAG, "Prepared ScriptYuvToRgb for size " + size);
+                            if (VERBOSE) Log.v(TAG, "Prepared ScriptYuvToRgb for size " + size);
 
-                        // Run the graph against camera input and validate we get some input
-                        try {
+                            // Run the graph against camera input and validate we get some input
                             CaptureRequest request =
                                     configureAndCreateRequestForSurface(scriptGraph.getInputSurface()).build();
 
@@ -495,8 +494,6 @@
                             });
 
                             stopCapture();
-                        } finally {
-                            scriptGraph.close();
                         }
                     }
                 });
@@ -536,36 +533,37 @@
                 final Size maxSize = getMaxSize(
                         getSupportedSizeForFormat(YUV_420_888, camera.getId(), mCameraManager));
 
-                ScriptGraph scriptGraph = createGraphForYuvCroppedMeans(maxSize);
+                try (ScriptGraph scriptGraph = createGraphForYuvCroppedMeans(maxSize)) {
 
-                CaptureRequest.Builder req =
-                        configureAndCreateRequestForSurface(scriptGraph.getInputSurface());
+                    CaptureRequest.Builder req =
+                            configureAndCreateRequestForSurface(scriptGraph.getInputSurface());
 
-                // Take a shot with very low ISO and exposure time. Expect it to be black.
-                int minimumSensitivity = staticInfo.getSensitivityMinimumOrDefault();
-                long minimumExposure = staticInfo.getExposureMinimumOrDefault();
-                setManualCaptureRequest(req, minimumSensitivity, minimumExposure);
+                    // Take a shot with very low ISO and exposure time. Expect it to be black.
+                    int minimumSensitivity = staticInfo.getSensitivityMinimumOrDefault();
+                    long minimumExposure = staticInfo.getExposureMinimumOrDefault();
+                    setManualCaptureRequest(req, minimumSensitivity, minimumExposure);
 
-                CaptureRequest lowIsoExposureShot = req.build();
-                captureSingleShotAndExecute(lowIsoExposureShot, scriptGraph);
+                    CaptureRequest lowIsoExposureShot = req.build();
+                    captureSingleShotAndExecute(lowIsoExposureShot, scriptGraph);
 
-                float[] blackMeans = convertPixelYuvToRgb(scriptGraph.getOutputData());
+                    float[] blackMeans = convertPixelYuvToRgb(scriptGraph.getOutputData());
 
-                // Take a shot with very high ISO and exposure time. Expect it to be white.
-                int maximumSensitivity = staticInfo.getSensitivityMaximumOrDefault();
-                long maximumExposure = staticInfo.getExposureMaximumOrDefault();
-                setManualCaptureRequest(req, maximumSensitivity, maximumExposure);
+                    // Take a shot with very high ISO and exposure time. Expect it to be white.
+                    int maximumSensitivity = staticInfo.getSensitivityMaximumOrDefault();
+                    long maximumExposure = staticInfo.getExposureMaximumOrDefault();
+                    setManualCaptureRequest(req, maximumSensitivity, maximumExposure);
 
-                CaptureRequest highIsoExposureShot = req.build();
-                captureSingleShotAndExecute(highIsoExposureShot, scriptGraph);
+                    CaptureRequest highIsoExposureShot = req.build();
+                    captureSingleShotAndExecute(highIsoExposureShot, scriptGraph);
 
-                float[] whiteMeans = convertPixelYuvToRgb(scriptGraph.getOutputData());
+                    float[] whiteMeans = convertPixelYuvToRgb(scriptGraph.getOutputData());
 
-                // low iso + low exposure (first shot)
-                assertArrayWithinUpperBound("Black means too high", blackMeans, THRESHOLD_LOW);
+                    // low iso + low exposure (first shot)
+                    assertArrayWithinUpperBound("Black means too high", blackMeans, THRESHOLD_LOW);
 
-                // high iso + high exposure (second shot)
-                assertArrayWithinLowerBound("White means too low", whiteMeans, THRESHOLD_HIGH);
+                    // high iso + high exposure (second shot)
+                    assertArrayWithinLowerBound("White means too low", whiteMeans, THRESHOLD_HIGH);
+                }
             }
         });
     }
@@ -608,48 +606,49 @@
                     sensitivities[i] = sensitivityMin + delta * i;
                 }
 
-                ScriptGraph scriptGraph = createGraphForYuvCroppedMeans(maxSize);
+                try (ScriptGraph scriptGraph = createGraphForYuvCroppedMeans(maxSize)) {
 
-                CaptureRequest.Builder req =
-                        configureAndCreateRequestForSurface(scriptGraph.getInputSurface());
+                    CaptureRequest.Builder req =
+                            configureAndCreateRequestForSurface(scriptGraph.getInputSurface());
 
-                // Take burst shots with increasing sensitivity one after other.
-                for (int i = 0; i < NUM_STEPS; ++i) {
-                    setManualCaptureRequest(req, sensitivities[i], EXPOSURE_TIME_NS);
-                    captureSingleShotAndExecute(req.build(), scriptGraph);
-                    float[] means = convertPixelYuvToRgb(scriptGraph.getOutputData());
-                    rgbMeans.add(means);
+                    // Take burst shots with increasing sensitivity one after other.
+                    for (int i = 0; i < NUM_STEPS; ++i) {
+                        setManualCaptureRequest(req, sensitivities[i], EXPOSURE_TIME_NS);
+                        captureSingleShotAndExecute(req.build(), scriptGraph);
+                        float[] means = convertPixelYuvToRgb(scriptGraph.getOutputData());
+                        rgbMeans.add(means);
 
-                    if (VERBOSE) {
-                        Log.v(TAG, "testParamSensitivity - captured image " + i +
-                                " with RGB means: " + Arrays.toString(means));
+                        if (VERBOSE) {
+                            Log.v(TAG, "testParamSensitivity - captured image " + i +
+                                    " with RGB means: " + Arrays.toString(means));
+                        }
                     }
-                }
 
-                // Test that every consecutive image gets brighter.
-                for (int i = 0; i < rgbMeans.size() - 1; ++i) {
-                    float[] curMeans = rgbMeans.get(i);
-                    float[] nextMeans = rgbMeans.get(i+1);
+                    // Test that every consecutive image gets brighter.
+                    for (int i = 0; i < rgbMeans.size() - 1; ++i) {
+                        float[] curMeans = rgbMeans.get(i);
+                        float[] nextMeans = rgbMeans.get(i+1);
 
-                    assertArrayNotGreater(
-                            String.format("Shot with sensitivity %d should not have higher " +
-                                    "average means than shot with sensitivity %d",
-                                    sensitivities[i], sensitivities[i+1]),
-                            curMeans, nextMeans);
-                }
+                        assertArrayNotGreater(
+                                String.format("Shot with sensitivity %d should not have higher " +
+                                        "average means than shot with sensitivity %d",
+                                        sensitivities[i], sensitivities[i+1]),
+                                curMeans, nextMeans);
+                    }
 
-                // Test the min-max diff and ratios are within expected thresholds
-                float[] lastMeans = rgbMeans.get(NUM_STEPS - 1);
-                float[] firstMeans = rgbMeans.get(/*location*/0);
-                for (int i = 0; i < RGB_CHANNELS; ++i) {
-                    assertTrue(
-                            String.format("Sensitivity max-min diff too small (max=%f, min=%f)",
-                                    lastMeans[i], firstMeans[i]),
-                            lastMeans[i] - firstMeans[i] > THRESHOLD_MAX_MIN_DIFF);
-                    assertTrue(
-                            String.format("Sensitivity max-min ratio too small (max=%f, min=%f)",
-                                    lastMeans[i], firstMeans[i]),
-                            lastMeans[i] / firstMeans[i] > THRESHOLD_MAX_MIN_RATIO);
+                    // Test the min-max diff and ratios are within expected thresholds
+                    float[] lastMeans = rgbMeans.get(NUM_STEPS - 1);
+                    float[] firstMeans = rgbMeans.get(/*location*/0);
+                    for (int i = 0; i < RGB_CHANNELS; ++i) {
+                        assertTrue(
+                                String.format("Sensitivity max-min diff too small (max=%f, min=%f)",
+                                        lastMeans[i], firstMeans[i]),
+                                lastMeans[i] - firstMeans[i] > THRESHOLD_MAX_MIN_DIFF);
+                        assertTrue(
+                                String.format("Sensitivity max-min ratio too small (max=%f, min=%f)",
+                                        lastMeans[i], firstMeans[i]),
+                                lastMeans[i] / firstMeans[i] > THRESHOLD_MAX_MIN_RATIO);
+                    }
                 }
             }
         });
@@ -717,7 +716,7 @@
                 CameraCharacteristics properties =
                         mCameraManager.getCameraCharacteristics(mCameraIds[i]);
                 StaticMetadata staticInfo = new StaticMetadata(properties);
-                if (fullHwLevel && !staticInfo.isHardwareLevelFull()) {
+                if (fullHwLevel && !staticInfo.isHardwareLevelAtLeastFull()) {
                     Log.i(TAG, String.format(
                             "Skipping this test for camera %s, needs FULL hw level",
                             mCameraIds[i]));
diff --git a/tests/camera/src/android/hardware/camera2/cts/BurstCaptureRawTest.java b/tests/camera/src/android/hardware/camera2/cts/BurstCaptureRawTest.java
index 41e2045..72a5f99 100644
--- a/tests/camera/src/android/hardware/camera2/cts/BurstCaptureRawTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/BurstCaptureRawTest.java
@@ -437,8 +437,7 @@
      */
     private boolean checkCapability(ArrayList<Integer> supportedRawList, int[] testedFormats) {
         // make sure the sensor has manual support
-        if (!mStaticInfo.isCapabilitySupported(
-                CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL)) {
+        if (!mStaticInfo.isHardwareLevelAtLeastFull()) {
             Log.w(TAG, "Full hardware level is not supported");
             return false;
         }
diff --git a/tests/camera/src/android/hardware/camera2/cts/Camera2SurfaceViewCtsActivity.java b/tests/camera/src/android/hardware/camera2/cts/Camera2SurfaceViewCtsActivity.java
index 6773a9b..e1dfbc1 100644
--- a/tests/camera/src/android/hardware/camera2/cts/Camera2SurfaceViewCtsActivity.java
+++ b/tests/camera/src/android/hardware/camera2/cts/Camera2SurfaceViewCtsActivity.java
@@ -28,11 +28,15 @@
 public class Camera2SurfaceViewCtsActivity extends Activity implements SurfaceHolder.Callback {
     private final static String TAG = "Camera2SurfaceViewCtsActivity";
     private final ConditionVariable surfaceChangedDone = new ConditionVariable();
+    private final ConditionVariable surfaceStateDone = new ConditionVariable();
 
     private SurfaceView mSurfaceView;
     private int currentWidth = 0;
     private int currentHeight = 0;
-    private final Object sizeLock = new Object();
+    private boolean surfaceValid = false;
+
+    private final Object surfaceLock = new Object();
+
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -56,7 +60,7 @@
                             timeOutMs, expectWidth, expectHeight));
         }
 
-        synchronized(sizeLock) {
+        synchronized(surfaceLock) {
             if (expectWidth == currentWidth && expectHeight == currentHeight) {
                 return true;
             }
@@ -85,16 +89,60 @@
 
         // Couldn't get expected surface size change.
         return false;
-     }
+    }
+
+    /**
+     * Wait for surface state to become valid (surfaceCreated) / invalid (surfaceDestroyed)
+     */
+    public boolean waitForSurfaceState(int timeOutMs, boolean valid) {
+        if (timeOutMs <= 0) {
+            throw new IllegalArgumentException(
+                    String.format("timeout(%d) should be a positive number", timeOutMs));
+        }
+
+        synchronized(surfaceLock) {
+            if (valid == surfaceValid) {
+                return true;
+            }
+        }
+
+        int waitTimeMs = timeOutMs;
+        boolean stateReached = false;
+        while (!stateReached && waitTimeMs > 0) {
+            long startTimeMs = SystemClock.elapsedRealtime();
+            stateReached = surfaceStateDone.block(waitTimeMs);
+            if (!stateReached) {
+                Log.e(TAG, "Wait for surface state " + valid + " timed out after " + timeOutMs + " ms");
+                return false;
+            } else {
+                surfaceStateDone.close();
+                synchronized(surfaceLock) {
+                    if (valid == surfaceValid) return true;
+                }
+                // Do a further iteration as surfaceDestroyed could be called
+                // again.
+                stateReached = false;
+            }
+            waitTimeMs -= (SystemClock.elapsedRealtime() - startTimeMs);
+        }
+
+        // Couldn't get expected surface size change.
+        return false;
+    }
 
     @Override
     public void surfaceCreated(SurfaceHolder holder) {
+        Log.i(TAG, "Surface created");
+        synchronized (surfaceLock) {
+            surfaceValid = true;
+        }
+        surfaceStateDone.open();
     }
 
     @Override
     public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
         Log.i(TAG, "Surface Changed to: " + width + "x" + height);
-        synchronized (sizeLock) {
+        synchronized (surfaceLock) {
             currentWidth = width;
             currentHeight = height;
         }
@@ -103,5 +151,10 @@
 
     @Override
     public void surfaceDestroyed(SurfaceHolder holder) {
+        Log.i(TAG, "Surface destroyed");
+        synchronized (surfaceLock) {
+            surfaceValid = false;
+        }
+        surfaceStateDone.open();
     }
 }
diff --git a/tests/camera/src/android/hardware/camera2/cts/CameraDeviceTest.java b/tests/camera/src/android/hardware/camera2/cts/CameraDeviceTest.java
index 44fda14..6861989 100644
--- a/tests/camera/src/android/hardware/camera2/cts/CameraDeviceTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/CameraDeviceTest.java
@@ -74,6 +74,7 @@
     private static final int REPEATING_CAPTURE_EXPECTED_RESULT_COUNT = 5;
     private static final int MAX_NUM_IMAGES = 5;
     private static final int MIN_FPS_REQUIRED_FOR_STREAMING = 20;
+    private static final int DEFAULT_POST_RAW_SENSITIVITY_BOOST = 100;
 
     private CameraCaptureSession mSession;
 
@@ -90,6 +91,11 @@
             CameraDevice.TEMPLATE_VIDEO_SNAPSHOT
     };
 
+    private static int[] sInvalidTemplates = new int[] {
+            CameraDevice.TEMPLATE_PREVIEW - 1,
+            CameraDevice.TEMPLATE_MANUAL + 1,
+    };
+
     // Request templates that are unsupported by LEGACY mode.
     private static Set<Integer> sLegacySkipTemplates = new HashSet<>();
     static {
@@ -299,6 +305,20 @@
                                 capReq.get(CaptureRequest.SENSOR_SENSITIVITY));
                     }
                 }
+
+                /**
+                 * Test: creating capture requests with an invalid template ID should throw
+                 * IllegalArgumentException.
+                 */
+                for (int j = 0; j < sInvalidTemplates.length; j++) {
+                    try {
+                        CaptureRequest.Builder capReq =
+                                mCamera.createCaptureRequest(sInvalidTemplates[j]);
+                        fail("Should get IllegalArgumentException due to an invalid template ID.");
+                    } catch (IllegalArgumentException e) {
+                        // Expected exception.
+                    }
+                }
             }
             finally {
                 try {
@@ -425,6 +445,7 @@
         // method on the camera device or session.
 
         class ChainedCaptureCallback extends CameraCaptureSession.CaptureCallback {
+            @Override
             public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request,
                     TotalCaptureResult result) {
                 try {
@@ -450,6 +471,7 @@
                 }
             }
 
+            @Override
             public void onCaptureFailed(CameraCaptureSession session, CaptureRequest request,
                     CaptureFailure failure) {
                 try {
@@ -466,6 +488,7 @@
         class ChainedSessionListener extends CameraCaptureSession.StateCallback {
             private final ChainedCaptureCallback mCaptureCallback = new ChainedCaptureCallback();
 
+            @Override
             public void onConfigured(CameraCaptureSession session) {
                 try {
                     CaptureRequest.Builder request =
@@ -486,6 +509,7 @@
                 }
             }
 
+            @Override
             public void onConfigureFailed(CameraCaptureSession session) {
                 try {
                     CameraDevice camera = session.getDevice();
@@ -503,6 +527,7 @@
 
             public CameraDevice cameraDevice;
 
+            @Override
             public void onOpened(CameraDevice camera) {
 
                 cameraDevice = camera;
@@ -525,6 +550,7 @@
                 }
             }
 
+            @Override
             public void onDisconnected(CameraDevice camera) {
                 try {
                     camera.close();
@@ -534,6 +560,7 @@
                 }
             }
 
+            @Override
             public void onError(CameraDevice camera, int error) {
                 try {
                     camera.close();
@@ -751,7 +778,7 @@
         try {
             mSession.prepare(output3Surface);
             // Legacy camera prepare always succeed
-            if (mStaticInfo.isHardwareLevelLimitedOrBetter()) {
+            if (mStaticInfo.isHardwareLevelAtLeastLimited()) {
                 fail("Preparing surface not part of session must throw IllegalArgumentException");
             }
         } catch (IllegalArgumentException e) {
@@ -775,7 +802,7 @@
         try {
             mSession.prepare(output1Surface);
             // Legacy camera prepare always succeed
-            if (mStaticInfo.isHardwareLevelLimitedOrBetter()) {
+            if (mStaticInfo.isHardwareLevelAtLeastLimited()) {
                 fail("Preparing already-used surface must throw IllegalArgumentException");
             }
         } catch (IllegalArgumentException e) {
@@ -796,7 +823,7 @@
         try {
             mSession.prepare(output1Surface);
             // Legacy camera prepare always succeed
-            if (mStaticInfo.isHardwareLevelLimitedOrBetter()) {
+            if (mStaticInfo.isHardwareLevelAtLeastLimited()) {
                 fail("Preparing surface used in previous session must throw " +
                         "IllegalArgumentException");
             }
@@ -817,7 +844,7 @@
         try {
             mSession.prepare(output3Surface);
             // Legacy camera prepare always succeed
-            if (mStaticInfo.isHardwareLevelLimitedOrBetter()) {
+            if (mStaticInfo.isHardwareLevelAtLeastLimited()) {
                 fail("Preparing already-used surface must throw IllegalArgumentException");
             }
         } catch (IllegalArgumentException e) {
@@ -842,7 +869,7 @@
         try {
             mSession.prepare(output1Surface);
             // Legacy camera prepare always succeed
-            if (mStaticInfo.isHardwareLevelLimitedOrBetter()) {
+            if (mStaticInfo.isHardwareLevelAtLeastLimited()) {
                 fail("Preparing surface used in previous session must throw " +
                         "IllegalArgumentException");
             }
@@ -1077,9 +1104,22 @@
         if (repeating) {
             if (abort) {
                 mSession.abortCaptures();
-            } else {
-                mSession.stopRepeating();
+                // Have to make sure abort and new requests aren't interleave together.
+                waitForSessionState(SESSION_READY, SESSION_READY_TIMEOUT_MS);
+
+                // Capture a single capture, and verify the result.
+                SimpleCaptureCallback resultCallback = new SimpleCaptureCallback();
+                CaptureRequest singleRequest = requestBuilder.build();
+                mSession.capture(singleRequest, resultCallback, mHandler);
+                resultCallback.getCaptureResultForRequest(singleRequest, CAPTURE_RESULT_TIMEOUT_MS);
+
+                // Resume the repeating, and verify that results are returned.
+                mSession.setRepeatingRequest(singleRequest, resultCallback, mHandler);
+                for (int i = 0; i < REPEATING_CAPTURE_EXPECTED_RESULT_COUNT; i++) {
+                    resultCallback.getCaptureResult(CAPTURE_RESULT_TIMEOUT_MS);
+                }
             }
+            mSession.stopRepeating();
         }
         waitForSessionState(SESSION_READY, SESSION_READY_TIMEOUT_MS);
     }
@@ -1096,6 +1136,7 @@
 
         assertTrue("Invalid args to capture function", len <= templates.length);
         List<CaptureRequest> requests = new ArrayList<CaptureRequest>();
+        List<CaptureRequest> postAbortRequests = new ArrayList<CaptureRequest>();
         for (int i = 0; i < len; i++) {
             // Skip video snapshots for LEGACY mode
             if (mStaticInfo.isHardwareLevelLegacy() &&
@@ -1111,6 +1152,9 @@
             assertNotNull("Failed to create capture request", requestBuilder);
             requestBuilder.addTarget(mReaderSurface);
             requests.add(requestBuilder.build());
+            if (abort) {
+                postAbortRequests.add(requestBuilder.build());
+            }
         }
         CameraCaptureSession.CaptureCallback mockCaptureCallback =
                 mock(CameraCaptureSession.CaptureCallback.class);
@@ -1137,9 +1181,25 @@
         if (repeating) {
             if (abort) {
                 mSession.abortCaptures();
-            } else {
-                mSession.stopRepeating();
+                // Have to make sure abort and new requests aren't interleave together.
+                waitForSessionState(SESSION_READY, SESSION_READY_TIMEOUT_MS);
+
+                // Capture a burst of captures, and verify the results.
+                SimpleCaptureCallback resultCallback = new SimpleCaptureCallback();
+                mSession.captureBurst(postAbortRequests, resultCallback, mHandler);
+                // Verify that the results are returned.
+                for (int i = 0; i < postAbortRequests.size(); i++) {
+                    resultCallback.getCaptureResultForRequest(
+                            postAbortRequests.get(i), CAPTURE_RESULT_TIMEOUT_MS);
+                }
+
+                // Resume the repeating, and verify that results are returned.
+                mSession.setRepeatingBurst(requests, resultCallback, mHandler);
+                for (int i = 0; i < REPEATING_CAPTURE_EXPECTED_RESULT_COUNT; i++) {
+                    resultCallback.getCaptureResult(CAPTURE_RESULT_TIMEOUT_MS);
+                }
             }
+            mSession.stopRepeating();
         }
         waitForSessionState(SESSION_READY, SESSION_READY_TIMEOUT_MS);
     }
@@ -1253,7 +1313,7 @@
             }
 
             // Relax framerate constraints on legacy mode
-            if (mStaticInfo.isHardwareLevelLimitedOrBetter()) {
+            if (mStaticInfo.isHardwareLevelAtLeastLimited()) {
                 // Need give fixed frame rate for video recording template.
                 if (template == CameraDevice.TEMPLATE_RECORD) {
                     if (maxFps != minFps) {
@@ -1508,7 +1568,6 @@
             }
         }
 
-        // Edge enhancement and noise reduction modes
         boolean supportReprocessing =
                 availableCaps.contains(REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING) ||
                 availableCaps.contains(REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING);
@@ -1522,6 +1581,7 @@
                         CaptureRequest.COLOR_CORRECTION_MODE_TRANSFORM_MATRIX);
             }
 
+            // Edge enhancement, noise reduction and aberration correction modes.
             mCollector.expectEquals("Edge mode must be present in request if " +
                             "available edge modes are present in metadata, and vice-versa.",
                     mStaticInfo.areKeysAvailable(CameraCharacteristics.
@@ -1530,12 +1590,10 @@
             if (mStaticInfo.areKeysAvailable(EDGE_MODE)) {
                 List<Integer> availableEdgeModes =
                         Arrays.asList(toObject(mStaticInfo.getAvailableEdgeModesChecked()));
+                // Don't need check fast as fast or high quality must be both present or both not.
                 if (availableEdgeModes.contains(CaptureRequest.EDGE_MODE_HIGH_QUALITY)) {
                     mCollector.expectKeyValueEquals(request, EDGE_MODE,
                             CaptureRequest.EDGE_MODE_HIGH_QUALITY);
-                } else if (availableEdgeModes.contains(CaptureRequest.EDGE_MODE_FAST)) {
-                    mCollector.expectKeyValueEquals(request, EDGE_MODE,
-                            CaptureRequest.EDGE_MODE_FAST);
                 } else {
                     mCollector.expectKeyValueEquals(request, EDGE_MODE,
                             CaptureRequest.EDGE_MODE_OFF);
@@ -1551,25 +1609,88 @@
                     CameraCharacteristics.NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES)) {
                 List<Integer> availableNoiseReductionModes =
                         Arrays.asList(toObject(mStaticInfo.getAvailableNoiseReductionModesChecked()));
+                // Don't need check fast as fast or high quality must be both present or both not.
                 if (availableNoiseReductionModes
                         .contains(CaptureRequest.NOISE_REDUCTION_MODE_HIGH_QUALITY)) {
                     mCollector.expectKeyValueEquals(
                             request, NOISE_REDUCTION_MODE,
                             CaptureRequest.NOISE_REDUCTION_MODE_HIGH_QUALITY);
-                } else if (availableNoiseReductionModes
-                        .contains(CaptureRequest.NOISE_REDUCTION_MODE_FAST)) {
-                    mCollector.expectKeyValueEquals(
-                            request, NOISE_REDUCTION_MODE, CaptureRequest.NOISE_REDUCTION_MODE_FAST);
                 } else {
                     mCollector.expectKeyValueEquals(
                             request, NOISE_REDUCTION_MODE, CaptureRequest.NOISE_REDUCTION_MODE_OFF);
                 }
             }
+
+            boolean supportAvailableAberrationModes = mStaticInfo.areKeysAvailable(
+                    CameraCharacteristics.COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES);
+            boolean supportAberrationRequestKey = mStaticInfo.areKeysAvailable(
+                    CaptureRequest.COLOR_CORRECTION_ABERRATION_MODE);
+            mCollector.expectEquals("Aberration correction mode must be present in request if " +
+                    "available aberration correction reductions are present in metadata, and "
+                    + "vice-versa.", supportAvailableAberrationModes, supportAberrationRequestKey);
+            if (supportAberrationRequestKey) {
+                List<Integer> availableAberrationModes = Arrays.asList(
+                        toObject(mStaticInfo.getAvailableColorAberrationModesChecked()));
+                // Don't need check fast as fast or high quality must be both present or both not.
+                if (availableAberrationModes
+                        .contains(CaptureRequest.COLOR_CORRECTION_ABERRATION_MODE_HIGH_QUALITY)) {
+                    mCollector.expectKeyValueEquals(
+                            request, COLOR_CORRECTION_ABERRATION_MODE,
+                            CaptureRequest.COLOR_CORRECTION_ABERRATION_MODE_HIGH_QUALITY);
+                } else {
+                    mCollector.expectKeyValueEquals(
+                            request, COLOR_CORRECTION_ABERRATION_MODE,
+                            CaptureRequest.COLOR_CORRECTION_ABERRATION_MODE_OFF);
+                }
+            }
         } else if (template == CameraDevice.TEMPLATE_ZERO_SHUTTER_LAG && supportReprocessing) {
             mCollector.expectKeyValueEquals(request, EDGE_MODE,
                     CaptureRequest.EDGE_MODE_ZERO_SHUTTER_LAG);
             mCollector.expectKeyValueEquals(request, NOISE_REDUCTION_MODE,
                     CaptureRequest.NOISE_REDUCTION_MODE_ZERO_SHUTTER_LAG);
+        } else if (template == CameraDevice.TEMPLATE_PREVIEW ||
+                template == CameraDevice.TEMPLATE_RECORD){
+            if (mStaticInfo.areKeysAvailable(EDGE_MODE)) {
+                List<Integer> availableEdgeModes =
+                        Arrays.asList(toObject(mStaticInfo.getAvailableEdgeModesChecked()));
+                if (availableEdgeModes.contains(CaptureRequest.EDGE_MODE_FAST)) {
+                    mCollector.expectKeyValueEquals(request, EDGE_MODE,
+                            CaptureRequest.EDGE_MODE_FAST);
+                } else {
+                    mCollector.expectKeyValueEquals(request, EDGE_MODE,
+                            CaptureRequest.EDGE_MODE_OFF);
+                }
+            }
+
+            if (mStaticInfo.areKeysAvailable(NOISE_REDUCTION_MODE)) {
+                List<Integer> availableNoiseReductionModes =
+                        Arrays.asList(toObject(
+                                mStaticInfo.getAvailableNoiseReductionModesChecked()));
+                if (availableNoiseReductionModes
+                        .contains(CaptureRequest.NOISE_REDUCTION_MODE_FAST)) {
+                    mCollector.expectKeyValueEquals(
+                            request, NOISE_REDUCTION_MODE,
+                            CaptureRequest.NOISE_REDUCTION_MODE_FAST);
+                } else {
+                    mCollector.expectKeyValueEquals(
+                            request, NOISE_REDUCTION_MODE, CaptureRequest.NOISE_REDUCTION_MODE_OFF);
+                }
+            }
+
+            if (mStaticInfo.areKeysAvailable(COLOR_CORRECTION_ABERRATION_MODE)) {
+                List<Integer> availableAberrationModes = Arrays.asList(
+                        toObject(mStaticInfo.getAvailableColorAberrationModesChecked()));
+                if (availableAberrationModes
+                        .contains(CaptureRequest.COLOR_CORRECTION_ABERRATION_MODE_FAST)) {
+                    mCollector.expectKeyValueEquals(
+                            request, COLOR_CORRECTION_ABERRATION_MODE,
+                            CaptureRequest.COLOR_CORRECTION_ABERRATION_MODE_FAST);
+                } else {
+                    mCollector.expectKeyValueEquals(
+                            request, COLOR_CORRECTION_ABERRATION_MODE,
+                            CaptureRequest.COLOR_CORRECTION_ABERRATION_MODE_OFF);
+                }
+            }
         } else {
             if (mStaticInfo.areKeysAvailable(EDGE_MODE)) {
                 mCollector.expectKeyValueNotNull(request, EDGE_MODE);
@@ -1578,6 +1699,10 @@
             if (mStaticInfo.areKeysAvailable(NOISE_REDUCTION_MODE)) {
                 mCollector.expectKeyValueNotNull(request, NOISE_REDUCTION_MODE);
             }
+
+            if (mStaticInfo.areKeysAvailable(COLOR_CORRECTION_ABERRATION_MODE)) {
+                mCollector.expectKeyValueNotNull(request, COLOR_CORRECTION_ABERRATION_MODE);
+            }
         }
 
         // Tone map and lens shading modes.
@@ -1621,6 +1746,22 @@
             }
         }
 
+        int[] outputFormats = mStaticInfo.getAvailableFormats(
+                StaticMetadata.StreamDirection.Output);
+        boolean supportRaw = false;
+        for (int format : outputFormats) {
+            if (format == ImageFormat.RAW_SENSOR || format == ImageFormat.RAW10 ||
+                    format == ImageFormat.RAW12 || format == ImageFormat.RAW_PRIVATE) {
+                supportRaw = true;
+                break;
+            }
+        }
+        if (supportRaw) {
+            mCollector.expectKeyValueEquals(request,
+                    CONTROL_POST_RAW_SENSITIVITY_BOOST,
+                    DEFAULT_POST_RAW_SENSITIVITY_BOOST);
+        }
+
         mCollector.expectKeyValueEquals(request, CONTROL_CAPTURE_INTENT, template);
 
         // TODO: use the list of keys from CameraCharacteristics to avoid expecting
@@ -1681,6 +1822,7 @@
      * @param listener The {@link #CaptureCallback} camera device used to notify callbacks.
      * @param handler The handler camera device used to post callbacks.
      */
+    @Override
     protected void startCapture(CaptureRequest request, boolean repeating,
             CameraCaptureSession.CaptureCallback listener, Handler handler)
                     throws CameraAccessException {
diff --git a/tests/camera/src/android/hardware/camera2/cts/CameraTestUtils.java b/tests/camera/src/android/hardware/camera2/cts/CameraTestUtils.java
index c29f866..cdca29b 100644
--- a/tests/camera/src/android/hardware/camera2/cts/CameraTestUtils.java
+++ b/tests/camera/src/android/hardware/camera2/cts/CameraTestUtils.java
@@ -36,6 +36,7 @@
 import android.hardware.camera2.TotalCaptureResult;
 import android.hardware.cts.helpers.CameraUtils;
 import android.hardware.camera2.params.MeteringRectangle;
+import android.hardware.camera2.params.OutputConfiguration;
 import android.hardware.camera2.params.StreamConfigurationMap;
 import android.location.Location;
 import android.location.LocationManager;
@@ -313,7 +314,11 @@
         @Override
         public void onImageAvailable(ImageReader reader) {
             try {
-                mQueue.put(reader.acquireNextImage());
+                Image imge = reader.acquireNextImage();
+                if (imge == null) {
+                    return;
+                }
+                mQueue.put(imge);
                 if (mAsyncMode && mQueue.size() >= mMaxImages) {
                     Image img = mQueue.poll();
                     img.close();
@@ -386,6 +391,9 @@
         // Pair<CaptureRequest, Long> is a pair of capture request and timestamp.
         private final LinkedBlockingQueue<Pair<CaptureRequest, Long>> mCaptureStartQueue =
                 new LinkedBlockingQueue<>();
+        // Pair<Int, Long> is a pair of sequence id and frame number
+        private final LinkedBlockingQueue<Pair<Integer, Long>> mCaptureSequenceCompletedQueue =
+                new LinkedBlockingQueue<>();
 
         private AtomicLong mNumFramesArrived = new AtomicLong(0);
 
@@ -426,6 +434,12 @@
         @Override
         public void onCaptureSequenceCompleted(CameraCaptureSession session, int sequenceId,
                 long frameNumber) {
+            try {
+                mCaptureSequenceCompletedQueue.put(new Pair(sequenceId, frameNumber));
+            } catch (InterruptedException e) {
+                throw new UnsupportedOperationException(
+                        "Can't handle InterruptedException in onCaptureSequenceCompleted");
+            }
         }
 
         public long getTotalNumFrames() {
@@ -626,9 +640,38 @@
                     "event after waiting for " + numCaptureStartsWait + " capture starts");
         }
 
+        /**
+         * Wait until it receives capture sequence completed callback for a given squence ID.
+         *
+         * @param sequenceId The sequence ID of the capture sequence completed callback to wait for.
+         * @param timeoutMs Time to wait for each capture sequence complete callback before
+         *                  timing out.
+         */
+        public long getCaptureSequenceLastFrameNumber(int sequenceId, long timeoutMs) {
+            try {
+                while (true) {
+                    Pair<Integer, Long> completedSequence =
+                            mCaptureSequenceCompletedQueue.poll(timeoutMs, TimeUnit.MILLISECONDS);
+                    assertNotNull("Wait for a capture sequence completed timed out in " +
+                            timeoutMs + "ms", completedSequence);
+
+                    if (completedSequence.first.equals(sequenceId)) {
+                        return completedSequence.second.longValue();
+                    }
+                }
+            } catch (InterruptedException e) {
+                throw new UnsupportedOperationException("Unhandled interrupted exception", e);
+            }
+        }
+
         public boolean hasMoreResults()
         {
-            return mQueue.isEmpty();
+            return !mQueue.isEmpty();
+        }
+
+        public boolean hasMoreFailures()
+        {
+            return !mFailureQueue.isEmpty();
         }
 
         public void drain() {
@@ -725,6 +768,26 @@
     }
 
     /**
+     * Configure a new camera session with output configurations.
+     *
+     * @param camera The CameraDevice to be configured.
+     * @param outputs The OutputConfiguration list that is used for camera output.
+     * @param listener The callback CameraDevice will notify when capture results are available.
+     */
+    public static CameraCaptureSession configureCameraSessionWithConfig(CameraDevice camera,
+            List<OutputConfiguration> outputs,
+            CameraCaptureSession.StateCallback listener, Handler handler)
+            throws CameraAccessException {
+        BlockingSessionCallback sessionListener = new BlockingSessionCallback(listener);
+        camera.createCaptureSessionByOutputConfigurations(outputs, sessionListener, handler);
+        CameraCaptureSession session =
+                sessionListener.waitAndGetSession(SESSION_CONFIGURE_TIMEOUT_MS);
+        assertFalse("Camera session should not be a reprocessable session",
+                session.isReprocessable());
+        return session;
+    }
+
+    /**
      * Configure a new camera session with output surfaces.
      *
      * @param camera The CameraDevice to be configured.
@@ -763,6 +826,40 @@
         return session;
     }
 
+    /**
+     * Create a reprocessable camera session with input and output configurations.
+     *
+     * @param camera The CameraDevice to be configured.
+     * @param inputConfiguration The input configuration used to create this session.
+     * @param outputs The output configurations used to create this session.
+     * @param listener The callback CameraDevice will notify when capture results are available.
+     * @param handler The handler used to notify callbacks.
+     * @return The session ready to use.
+     * @throws CameraAccessException
+     */
+    public static CameraCaptureSession configureReprocCameraSessionWithConfig(CameraDevice camera,
+            InputConfiguration inputConfiguration, List<OutputConfiguration> outputs,
+            CameraCaptureSession.StateCallback listener, Handler handler)
+            throws CameraAccessException {
+        BlockingSessionCallback sessionListener = new BlockingSessionCallback(listener);
+        camera.createReprocessableCaptureSessionByConfigurations(inputConfiguration, outputs,
+                sessionListener, handler);
+
+        Integer[] sessionStates = {BlockingSessionCallback.SESSION_READY,
+                                   BlockingSessionCallback.SESSION_CONFIGURE_FAILED};
+        int state = sessionListener.getStateWaiter().waitForAnyOfStates(
+                Arrays.asList(sessionStates), SESSION_CONFIGURE_TIMEOUT_MS);
+
+        assertTrue("Creating a reprocessable session failed.",
+                state == BlockingSessionCallback.SESSION_READY);
+
+        CameraCaptureSession session =
+                sessionListener.waitAndGetSession(SESSION_CONFIGURE_TIMEOUT_MS);
+        assertTrue("Camera session should be a reprocessable session", session.isReprocessable());
+
+        return session;
+    }
+
     public static <T> void assertArrayNotEmpty(T arr, String message) {
         assertTrue(message, arr != null && Array.getLength(arr) > 0);
     }
@@ -822,7 +919,8 @@
         ByteBuffer buffer = null;
         // JPEG doesn't have pixelstride and rowstride, treat it as 1D buffer.
         // Same goes for DEPTH_POINT_CLOUD
-        if (format == ImageFormat.JPEG || format == ImageFormat.DEPTH_POINT_CLOUD) {
+        if (format == ImageFormat.JPEG || format == ImageFormat.DEPTH_POINT_CLOUD ||
+                format == ImageFormat.RAW_PRIVATE) {
             buffer = planes[0].getBuffer();
             assertNotNull("Fail to get jpeg or depth ByteBuffer", buffer);
             data = new byte[buffer.remaining()];
@@ -902,6 +1000,7 @@
                 break;
             case ImageFormat.JPEG:
             case ImageFormat.RAW_SENSOR:
+            case ImageFormat.RAW_PRIVATE:
             case ImageFormat.DEPTH16:
             case ImageFormat.DEPTH_POINT_CLOUD:
                 assertEquals("JPEG/RAW/depth Images should have one plane", 1, planes.length);
@@ -1324,6 +1423,9 @@
             case ImageFormat.DEPTH_POINT_CLOUD:
                 validateDepthPointCloudData(data, width, height, format, image.getTimestamp(), filePath);
                 break;
+            case ImageFormat.RAW_PRIVATE:
+                validateRawPrivateData(data, width, height, image.getTimestamp(), filePath);
+                break;
             default:
                 throw new UnsupportedOperationException("Unsupported format for validation: "
                         + format);
@@ -1420,6 +1522,26 @@
         return;
     }
 
+    private static void validateRawPrivateData(byte[] rawData, int width, int height,
+            long ts, String filePath) {
+        if (VERBOSE) Log.v(TAG, "Validating private raw data");
+        // Expect each RAW pixel should occupy at least one byte and no more than 2.5 bytes
+        int expectedSizeMin = width * height;
+        int expectedSizeMax = width * height * 5 / 2;
+
+        assertTrue("Opaque RAW size " + rawData.length + "out of normal bound [" +
+                expectedSizeMin + "," + expectedSizeMax + "]",
+                expectedSizeMin <= rawData.length && rawData.length <= expectedSizeMax);
+
+        if (DEBUG && filePath != null) {
+            String fileName =
+                    filePath + "/" + width + "x" + height + "_" + ts / 1e6 + ".rawPriv";
+            dumpFile(fileName, rawData);
+        }
+
+        return;
+    }
+
     private static void validateDepth16Data(byte[] depthData, int width, int height, int format,
             long ts, String filePath) {
 
@@ -1776,7 +1898,7 @@
         int orientationTested = expectedExifData.jpegOrientation;
         // Legacy shim always doesn't rotate thumbnail size
         if ((orientationTested == 90 || orientationTested == 270) &&
-                staticInfo.isHardwareLevelLimitedOrBetter()) {
+                staticInfo.isHardwareLevelAtLeastLimited()) {
             int exifOrientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,
                     /*defaultValue*/-1);
             if (exifOrientation == ExifInterface.ORIENTATION_UNDEFINED) {
@@ -1995,7 +2117,8 @@
                 exifFocalLength, EXIF_FOCAL_LENGTH_ERROR_MARGIN);
         // More checks for focal length.
         collector.expectEquals("Exif focal length should match capture result",
-                validateFocalLength(result, staticInfo, collector), exifFocalLength);
+                validateFocalLength(result, staticInfo, collector),
+                exifFocalLength, EXIF_FOCAL_LENGTH_ERROR_MARGIN);
 
         // TAG_EXPOSURE_TIME
         // ExifInterface API gives exposure time value in the form of float instead of rational
@@ -2026,7 +2149,8 @@
                         apertureValue, EXIF_APERTURE_ERROR_MARGIN);
                 // More checks for aperture.
                 collector.expectEquals("Exif aperture length should match capture result",
-                        validateAperture(result, staticInfo, collector), apertureValue);
+                        validateAperture(result, staticInfo, collector),
+                        apertureValue, EXIF_APERTURE_ERROR_MARGIN);
             }
         }
 
@@ -2131,4 +2255,20 @@
         else
             return new Size(width, height);
     }
+
+    /**
+     * Check if a particular stream configuration is supported by configuring it
+     * to the device.
+     */
+    public static boolean isStreamConfigurationSupported(CameraDevice camera,
+            List<Surface> outputSurfaces,
+            CameraCaptureSession.StateCallback listener, Handler handler) {
+        try {
+            configureCameraSession(camera, outputSurfaces, listener, handler);
+            return true;
+        } catch (Exception e) {
+            Log.i(TAG, "This stream configuration is not supported due to " + e.getMessage());
+            return false;
+        }
+    }
 }
diff --git a/tests/camera/src/android/hardware/camera2/cts/CaptureRequestTest.java b/tests/camera/src/android/hardware/camera2/cts/CaptureRequestTest.java
index ffbe432..4272f59 100644
--- a/tests/camera/src/android/hardware/camera2/cts/CaptureRequestTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/CaptureRequestTest.java
@@ -29,20 +29,20 @@
 import android.hardware.camera2.CaptureResult;
 import android.hardware.camera2.cts.CameraTestUtils.SimpleCaptureCallback;
 import android.hardware.camera2.cts.testcases.Camera2SurfaceViewTestCase;
+import android.hardware.camera2.params.BlackLevelPattern;
 import android.hardware.camera2.params.ColorSpaceTransform;
 import android.hardware.camera2.params.Face;
 import android.hardware.camera2.params.LensShadingMap;
 import android.hardware.camera2.params.MeteringRectangle;
 import android.hardware.camera2.params.RggbChannelVector;
 import android.hardware.camera2.params.TonemapCurve;
-
+import android.media.Image;
 import android.util.Log;
 import android.util.Range;
 import android.util.Rational;
 import android.util.Size;
 
-import com.android.cts.util.TimeoutReq;
-
+import java.nio.ByteBuffer;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
@@ -79,6 +79,7 @@
     private static final int NUM_RESULTS_WAIT_TIMEOUT = 100;
     private static final int NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY = 8;
     private static final int NUM_TEST_FOCUS_DISTANCES = 10;
+    private static final int NUM_FOCUS_DISTANCES_REPEAT = 3;
     // 5 percent error margin for calibrated device
     private static final float FOCUS_DISTANCE_ERROR_PERCENT_CALIBRATED = 0.05f;
     // 25 percent error margin for uncalibrated device
@@ -87,11 +88,12 @@
     private static final float FOCUS_DISTANCE_ERROR_PERCENT_APPROXIMATE = 0.10f;
     private static final int ANTI_FLICKERING_50HZ = 1;
     private static final int ANTI_FLICKERING_60HZ = 2;
-
     // 5 percent error margin for resulting crop regions
     private static final float CROP_REGION_ERROR_PERCENT_DELTA = 0.05f;
     // 1 percent error margin for centering the crop region
     private static final float CROP_REGION_ERROR_PERCENT_CENTERED = 0.01f;
+    private static final float DYNAMIC_VS_FIXED_BLK_WH_LVL_ERROR_MARGIN = 0.25f;
+    private static final float DYNAMIC_VS_OPTICAL_BLK_LVL_ERROR_MARGIN = 0.1f;
 
     // Linear tone mapping curve example.
     private static final float[] TONEMAP_CURVE_LINEAR = {0, 0, 1.0f, 1.0f};
@@ -180,6 +182,32 @@
     }
 
     /**
+     * Test dynamic black/white levels if they are supported.
+     *
+     * <p>
+     * If the dynamic black and white levels are reported, test below:
+     *   1. the dynamic black and white levels shouldn't deviate from the global value too much
+     *   for different sensitivities.
+     *   2. If the RAW_SENSOR and optical black regions are supported, capture RAW images and
+     *   calculate the optical black level values. The reported dynamic black level should be
+     *   close enough to the optical black level values.
+     * </p>
+     */
+    public void testDynamicBlackWhiteLevel() throws Exception {
+        for (String id : mCameraIds) {
+            try {
+                openDevice(id);
+                if (!mStaticInfo.isDynamicBlackLevelSupported()) {
+                    continue;
+                }
+                dynamicBlackWhiteLevelTestByCamera();
+            } finally {
+                closeDevice();
+            }
+        }
+    }
+
+    /**
      * Basic lens shading map request test.
      * <p>
      * When {@link CaptureRequest#SHADING_MODE} is set to OFF, no lens shading correction will
@@ -305,7 +333,6 @@
      * API specifications.
      * </p>
      */
-    @TimeoutReq(minutes = 40)
     public void testAeModeAndLock() throws Exception {
         for (int i = 0; i < mCameraIds.length; i++) {
             try {
@@ -633,6 +660,170 @@
 
     // TODO: add 3A state machine test.
 
+    /**
+     * Per camera dynamic black and white level test.
+     */
+    private void dynamicBlackWhiteLevelTestByCamera() throws Exception {
+        SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
+        SimpleImageReaderListener imageListener = null;
+        CaptureRequest.Builder previewBuilder =
+                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+        CaptureRequest.Builder rawBuilder = null;
+        Size previewSize =
+                getMaxPreviewSize(mCamera.getId(), mCameraManager,
+                getPreviewSizeBound(mWindowManager, PREVIEW_SIZE_BOUND));
+        Size rawSize = null;
+        boolean canCaptureBlackRaw =
+                mStaticInfo.isCapabilitySupported(
+                        CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_RAW) &&
+                mStaticInfo.isOpticalBlackRegionSupported();
+        if (canCaptureBlackRaw) {
+            // Capture Raw16, then calculate the optical black, and use it to check with the dynamic
+            // black level.
+            rawBuilder =
+                    mCamera.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
+            rawSize = mStaticInfo.getRawDimensChecked();
+            imageListener = new SimpleImageReaderListener();
+            prepareRawCaptureAndStartPreview(previewBuilder, rawBuilder, previewSize, rawSize,
+                    resultListener, imageListener);
+        } else {
+            startPreview(previewBuilder, previewSize, resultListener);
+        }
+
+        // Capture a sequence of frames with different sensitivities and validate the black/white
+        // level values
+        int[] sensitivities = getSensitivityTestValues();
+        float[][] dynamicBlackLevels = new float[sensitivities.length][];
+        int[] dynamicWhiteLevels = new int[sensitivities.length];
+        float[][] opticalBlackLevels = new float[sensitivities.length][];
+        for (int i = 0; i < sensitivities.length; i++) {
+            CaptureResult result = null;
+            if (canCaptureBlackRaw) {
+                changeExposure(rawBuilder, DEFAULT_EXP_TIME_NS, sensitivities[i]);
+                CaptureRequest rawRequest = rawBuilder.build();
+                mSession.capture(rawRequest, resultListener, mHandler);
+                result = resultListener.getCaptureResultForRequest(rawRequest,
+                        NUM_RESULTS_WAIT_TIMEOUT);
+                Image rawImage = imageListener.getImage(CAPTURE_IMAGE_TIMEOUT_MS);
+
+                // Get max (area-wise) optical black region
+                Rect[] opticalBlackRegions = mStaticInfo.getCharacteristics().get(
+                        CameraCharacteristics.SENSOR_OPTICAL_BLACK_REGIONS);
+                Rect maxRegion = opticalBlackRegions[0];
+                for (Rect region : opticalBlackRegions) {
+                    if (region.width() * region.height() > maxRegion.width() * maxRegion.height()) {
+                        maxRegion = region;
+                    }
+                }
+
+                // Get average black pixel values in the region (region is multiple of 2x2)
+                Image.Plane rawPlane = rawImage.getPlanes()[0];
+                ByteBuffer rawBuffer = rawPlane.getBuffer();
+                float[] avgBlackLevels = {0, 0, 0, 0};
+                int rowSize = rawPlane.getRowStride() * rawPlane.getPixelStride();
+                int bytePerPixel = rawPlane.getPixelStride();
+                if (VERBOSE) {
+                    Log.v(TAG, "maxRegion: " + maxRegion + ", Row stride: " +
+                            rawPlane.getRowStride());
+                }
+                for (int row = maxRegion.left; row < maxRegion.right; row += 2) {
+                    for (int col = maxRegion.top; col < maxRegion.bottom; col += 2) {
+                        int startOffset = col * rawPlane.getRowStride() + row * bytePerPixel;
+                        avgBlackLevels[0] += rawBuffer.getShort(startOffset);
+                        avgBlackLevels[1] += rawBuffer.getShort(startOffset + bytePerPixel);
+                        startOffset += rowSize;
+                        avgBlackLevels[2] += rawBuffer.getShort(startOffset);
+                        avgBlackLevels[3] += rawBuffer.getShort(startOffset + bytePerPixel);
+                    }
+                }
+                int numBlackBlocks = maxRegion.width() * maxRegion.height() / (2 * 2);
+                for (int m = 0; m < avgBlackLevels.length; m++) {
+                    avgBlackLevels[m] /= numBlackBlocks;
+                }
+                opticalBlackLevels[i] = avgBlackLevels;
+
+                if (VERBOSE) {
+                    Log.v(TAG, String.format("Optical black level results for sensitivity (%d): %s",
+                            sensitivities[i], Arrays.toString(avgBlackLevels)));
+                }
+
+                rawImage.close();
+            } else {
+                changeExposure(previewBuilder, DEFAULT_EXP_TIME_NS, sensitivities[i]);
+                CaptureRequest previewRequest = previewBuilder.build();
+                mSession.capture(previewRequest, resultListener, mHandler);
+                result = resultListener.getCaptureResultForRequest(previewRequest,
+                        NUM_RESULTS_WAIT_TIMEOUT);
+            }
+
+            dynamicBlackLevels[i] = getValueNotNull(result,
+                    CaptureResult.SENSOR_DYNAMIC_BLACK_LEVEL);
+            dynamicWhiteLevels[i] = getValueNotNull(result,
+                    CaptureResult.SENSOR_DYNAMIC_WHITE_LEVEL);
+        }
+
+        if (VERBOSE) {
+            Log.v(TAG, "Different sensitivities tested: " + Arrays.toString(sensitivities));
+            Log.v(TAG, "Dynamic black level results: " + Arrays.deepToString(dynamicBlackLevels));
+            Log.v(TAG, "Dynamic white level results: " + Arrays.toString(dynamicWhiteLevels));
+            if (canCaptureBlackRaw) {
+                Log.v(TAG, "Optical black level results " +
+                        Arrays.deepToString(opticalBlackLevels));
+            }
+        }
+
+        // check the dynamic black level against global black level.
+        // Implicit guarantee: if the dynamic black level is supported, fixed black level must be
+        // supported as well (tested in ExtendedCameraCharacteristicsTest#testOpticalBlackRegions).
+        BlackLevelPattern blackPattern = mStaticInfo.getCharacteristics().get(
+                CameraCharacteristics.SENSOR_BLACK_LEVEL_PATTERN);
+        int[] fixedBlackLevels = new int[4];
+        int fixedWhiteLevel = mStaticInfo.getCharacteristics().get(
+                CameraCharacteristics.SENSOR_INFO_WHITE_LEVEL);
+        blackPattern.copyTo(fixedBlackLevels, 0);
+        float maxBlackDeviation = 0;
+        int maxWhiteDeviation = 0;
+        for (int i = 0; i < dynamicBlackLevels.length; i++) {
+            for (int j = 0; j < dynamicBlackLevels[i].length; j++) {
+                if (maxBlackDeviation < Math.abs(fixedBlackLevels[j] - dynamicBlackLevels[i][j])) {
+                    maxBlackDeviation = Math.abs(fixedBlackLevels[j] - dynamicBlackLevels[i][j]);
+                }
+            }
+            if (maxWhiteDeviation < Math.abs(dynamicWhiteLevels[i] - fixedWhiteLevel)) {
+                maxWhiteDeviation = Math.abs(dynamicWhiteLevels[i] - fixedWhiteLevel);
+            }
+        }
+        mCollector.expectLessOrEqual("Max deviation of the dynamic black level vs fixed black level"
+                + " exceed threshold."
+                + " Dynamic black level results: " + Arrays.deepToString(dynamicBlackLevels),
+                fixedBlackLevels[0] * DYNAMIC_VS_FIXED_BLK_WH_LVL_ERROR_MARGIN, maxBlackDeviation);
+        mCollector.expectLessOrEqual("Max deviation of the dynamic white level exceed threshold."
+                + " Dynamic white level results: " + Arrays.toString(dynamicWhiteLevels),
+                fixedWhiteLevel * DYNAMIC_VS_FIXED_BLK_WH_LVL_ERROR_MARGIN,
+                (float)maxWhiteDeviation);
+
+        // Validate against optical black levels if it is available
+        if (canCaptureBlackRaw) {
+            maxBlackDeviation = 0;
+            for (int i = 0; i < dynamicBlackLevels.length; i++) {
+                for (int j = 0; j < dynamicBlackLevels[i].length; j++) {
+                    if (maxBlackDeviation <
+                            Math.abs(opticalBlackLevels[i][j] - dynamicBlackLevels[i][j])) {
+                        maxBlackDeviation =
+                                Math.abs(opticalBlackLevels[i][j] - dynamicBlackLevels[i][j]);
+                    }
+                }
+            }
+
+            mCollector.expectLessOrEqual("Max deviation of the dynamic black level vs optical black"
+                    + " exceed threshold."
+                    + " Dynamic black level results: " + Arrays.deepToString(dynamicBlackLevels)
+                    + " Optical black level results: " + Arrays.deepToString(opticalBlackLevels),
+                    fixedBlackLevels[0] * DYNAMIC_VS_OPTICAL_BLK_LVL_ERROR_MARGIN,
+                    maxBlackDeviation);
+        }
+    }
+
     private void noiseReductionModeTestByCamera() throws Exception {
         Size maxPrevSize = mOrderedPreviewSizes.get(0);
         CaptureRequest.Builder requestBuilder =
@@ -661,36 +852,66 @@
     }
 
     private void focusDistanceTestByCamera() throws Exception {
-        Size maxPrevSize = mOrderedPreviewSizes.get(0);
-        float[] testDistances = getFocusDistanceTestValuesInOrder();
         CaptureRequest.Builder requestBuilder =
                 mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
         requestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_OFF);
+        int calibrationStatus = mStaticInfo.getFocusDistanceCalibrationChecked();
+        float errorMargin = FOCUS_DISTANCE_ERROR_PERCENT_UNCALIBRATED;
+        if (calibrationStatus ==
+                CameraMetadata.LENS_INFO_FOCUS_DISTANCE_CALIBRATION_CALIBRATED) {
+            errorMargin = FOCUS_DISTANCE_ERROR_PERCENT_CALIBRATED;
+        } else if (calibrationStatus ==
+                CameraMetadata.LENS_INFO_FOCUS_DISTANCE_CALIBRATION_APPROXIMATE) {
+            errorMargin = FOCUS_DISTANCE_ERROR_PERCENT_APPROXIMATE;
+        }
+
+        // Test changing focus distance with repeating request
+        focusDistanceTestRepeating(requestBuilder, errorMargin);
+
+        if (calibrationStatus ==
+                CameraMetadata.LENS_INFO_FOCUS_DISTANCE_CALIBRATION_CALIBRATED)  {
+            // Test changing focus distance with burst request
+            focusDistanceTestBurst(requestBuilder, errorMargin);
+        }
+    }
+
+    private void focusDistanceTestRepeating(CaptureRequest.Builder requestBuilder,
+            float errorMargin) throws Exception {
+        CaptureRequest request;
+        float[] testDistances = getFocusDistanceTestValuesInOrder(0, 0);
+        Size maxPrevSize = mOrderedPreviewSizes.get(0);
         SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
         startPreview(requestBuilder, maxPrevSize, resultListener);
 
-        CaptureRequest request;
         float[] resultDistances = new float[testDistances.length];
+        int[] resultLensStates = new int[testDistances.length];
+
+        // Collect results
         for (int i = 0; i < testDistances.length; i++) {
             requestBuilder.set(CaptureRequest.LENS_FOCUS_DISTANCE, testDistances[i]);
             request = requestBuilder.build();
             resultListener = new SimpleCaptureCallback();
             mSession.setRepeatingRequest(request, resultListener, mHandler);
             waitForSettingsApplied(resultListener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
-            resultDistances[i] = verifyFocusDistanceControl(testDistances[i], request,
-                    resultListener);
+            waitForResultValue(resultListener, CaptureResult.LENS_STATE,
+                    CaptureResult.LENS_STATE_STATIONARY, NUM_RESULTS_WAIT_TIMEOUT);
+            CaptureResult result = resultListener.getCaptureResultForRequest(request,
+                    NUM_RESULTS_WAIT_TIMEOUT);
+
+            resultDistances[i] = getValueNotNull(result, CaptureResult.LENS_FOCUS_DISTANCE);
+            resultLensStates[i] = getValueNotNull(result, CaptureResult.LENS_STATE);
+
             if (VERBOSE) {
-                Log.v(TAG, "Capture request focus distance: " + testDistances[i] + " result: "
-                        + resultDistances[i]);
+                Log.v(TAG, "Capture repeating request focus distance: " + testDistances[i]
+                        + " result: " + resultDistances[i] + " lens state " + resultLensStates[i]);
             }
         }
 
-        // Verify the monotonicity
-        mCollector.checkArrayMonotonicityAndNotAllEqual(CameraTestUtils.toObject(resultDistances),
-                /*ascendingOrder*/true);
+        verifyFocusDistance(testDistances, resultDistances, resultLensStates,
+                /*ascendingOrder*/true, /*noOvershoot*/false, /*repeatStart*/0, /*repeatEnd*/0,
+                errorMargin);
 
-        if (mStaticInfo.getCharacteristics().getKeys().
-                contains(CameraCharacteristics.LENS_INFO_HYPERFOCAL_DISTANCE)) {
+        if (mStaticInfo.areKeysAvailable(CameraCharacteristics.LENS_INFO_HYPERFOCAL_DISTANCE)) {
 
             // Test hyperfocal distance optionally
             float hyperFocalDistance = mStaticInfo.getHyperfocalDistanceChecked();
@@ -704,57 +925,157 @@
                 // Then wait for the lens.state to be stationary.
                 waitForResultValue(resultListener, CaptureResult.LENS_STATE,
                         CaptureResult.LENS_STATE_STATIONARY, NUM_RESULTS_WAIT_TIMEOUT);
-                // Need get reasonably accurate value.
                 CaptureResult result = resultListener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
                 Float focusDistance = getValueNotNull(result, CaptureResult.LENS_FOCUS_DISTANCE);
-                float errorMargin = FOCUS_DISTANCE_ERROR_PERCENT_UNCALIBRATED;
-                int calibrationStatus = mStaticInfo.getFocusDistanceCalibrationChecked();
-                if (calibrationStatus ==
-                        CameraMetadata.LENS_INFO_FOCUS_DISTANCE_CALIBRATION_CALIBRATED) {
-                    errorMargin = FOCUS_DISTANCE_ERROR_PERCENT_CALIBRATED;
-                } else if (calibrationStatus ==
-                        CameraMetadata.LENS_INFO_FOCUS_DISTANCE_CALIBRATION_APPROXIMATE) {
-                    errorMargin = FOCUS_DISTANCE_ERROR_PERCENT_APPROXIMATE;
-                }
                 mCollector.expectInRange("Focus distance for hyper focal should be close enough to" +
-                                "requested value", focusDistance,
+                        " requested value", focusDistance,
                         hyperFocalDistance * (1.0f - errorMargin),
-                        hyperFocalDistance * (1.0f + errorMargin)
-                );
+                        hyperFocalDistance * (1.0f + errorMargin));
             }
         }
     }
 
+    private void focusDistanceTestBurst(CaptureRequest.Builder requestBuilder,
+            float errorMargin) throws Exception {
+
+        Size maxPrevSize = mOrderedPreviewSizes.get(0);
+        float[] testDistances = getFocusDistanceTestValuesInOrder(NUM_FOCUS_DISTANCES_REPEAT,
+                NUM_FOCUS_DISTANCES_REPEAT);
+        SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
+        startPreview(requestBuilder, maxPrevSize, resultListener);
+
+        float[] resultDistances = new float[testDistances.length];
+        int[] resultLensStates = new int[testDistances.length];
+
+        final int maxPipelineDepth = mStaticInfo.getCharacteristics().get(
+            CameraCharacteristics.REQUEST_PIPELINE_MAX_DEPTH);
+
+        // Move lens to starting position, and wait for the lens.state to be stationary.
+        CaptureRequest request;
+        requestBuilder.set(CaptureRequest.LENS_FOCUS_DISTANCE, testDistances[0]);
+        request = requestBuilder.build();
+        mSession.setRepeatingRequest(request, resultListener, mHandler);
+        waitForResultValue(resultListener, CaptureResult.LENS_STATE,
+                CaptureResult.LENS_STATE_STATIONARY, NUM_RESULTS_WAIT_TIMEOUT);
+
+        // Submit burst of requests with different focus distances
+        List<CaptureRequest> burst = new ArrayList<>();
+        for (int i = 0; i < testDistances.length; i ++) {
+            requestBuilder.set(CaptureRequest.LENS_FOCUS_DISTANCE, testDistances[i]);
+            burst.add(requestBuilder.build());
+        }
+        mSession.captureBurst(burst, resultListener, mHandler);
+
+        for (int i = 0; i < testDistances.length; i++) {
+            CaptureResult result = resultListener.getCaptureResultForRequest(
+                    burst.get(i), maxPipelineDepth+1);
+
+            resultDistances[i] = getValueNotNull(result, CaptureResult.LENS_FOCUS_DISTANCE);
+            resultLensStates[i] = getValueNotNull(result, CaptureResult.LENS_STATE);
+
+            if (VERBOSE) {
+                Log.v(TAG, "Capture burst request focus distance: " + testDistances[i]
+                        + " result: " + resultDistances[i] + " lens state " + resultLensStates[i]);
+            }
+        }
+
+        verifyFocusDistance(testDistances, resultDistances, resultLensStates,
+                /*ascendingOrder*/true, /*noOvershoot*/true,
+                /*repeatStart*/NUM_FOCUS_DISTANCES_REPEAT, /*repeatEnd*/NUM_FOCUS_DISTANCES_REPEAT,
+                errorMargin);
+
+    }
+
     /**
      * Verify focus distance control.
      *
-     * @param distance The focus distance requested
-     * @param request The capture request to control the manual focus distance
-     * @param resultListener The capture listener to recieve capture result callbacks
-     * @return the result focus distance
+     * Assumption:
+     * - First repeatStart+1 elements of requestedDistances share the same value
+     * - Last repeatEnd+1 elements of requestedDistances share the same value
+     * - All elements in between are monotonically increasing/decreasing depending on ascendingOrder.
+     * - Focuser is at requestedDistances[0] at the beginning of the test.
+     *
+     * @param requestedDistances The requested focus distances
+     * @param resultDistances The result focus distances
+     * @param lensStates The result lens states
+     * @param ascendingOrder The order of the expected focus distance request/output
+     * @param noOvershoot Assert that focus control doesn't overshoot the requested value
+     * @param repeatStart The number of times the starting focus distance is repeated
+     * @param repeatEnd The number of times the ending focus distance is repeated
+     * @param errorMargin The error margin between request and result
      */
-    private float verifyFocusDistanceControl(float distance, CaptureRequest request,
-            SimpleCaptureCallback resultListener) {
-        // Need make sure the result corresponding to the request is back, then check.
-        CaptureResult result =
-                resultListener.getCaptureResultForRequest(request, NUM_RESULTS_WAIT_TIMEOUT);
-        // Then wait for the lens.state to be stationary.
-        waitForResultValue(resultListener, CaptureResult.LENS_STATE,
-                CaptureResult.LENS_STATE_STATIONARY, NUM_RESULTS_WAIT_TIMEOUT);
-        // Then check the focus distance.
-        result = resultListener.getCaptureResultForRequest(request, NUM_RESULTS_WAIT_TIMEOUT);
-        Float resultDistance = getValueNotNull(result, CaptureResult.LENS_FOCUS_DISTANCE);
-        if (mStaticInfo.getFocusDistanceCalibrationChecked() ==
-                CameraCharacteristics.LENS_INFO_FOCUS_DISTANCE_CALIBRATION_CALIBRATED) {
-            // TODO: what's more to test for CALIBRATED devices?
-        }
+    private void verifyFocusDistance(float[] requestedDistances, float[] resultDistances,
+            int[] lensStates, boolean ascendingOrder, boolean noOvershoot, int repeatStart,
+            int repeatEnd, float errorMargin) {
 
         float minValue = 0;
         float maxValue = mStaticInfo.getMinimumFocusDistanceChecked();
-        mCollector.expectInRange("Result focus distance is out of range",
-                resultDistance, minValue, maxValue);
+        float hyperfocalDistance = 0;
+        if (mStaticInfo.areKeysAvailable(CameraCharacteristics.LENS_INFO_HYPERFOCAL_DISTANCE)) {
+            hyperfocalDistance = mStaticInfo.getHyperfocalDistanceChecked();
+        }
 
-        return resultDistance;
+        // Verify lens and focus distance do not change for first repeatStart
+        // results.
+        for (int i = 0; i < repeatStart; i ++) {
+            float marginMin = requestedDistances[i] * (1.0f - errorMargin);
+            // HAL may choose to use hyperfocal distance for all distances between [0, hyperfocal].
+            float marginMax =
+                    Math.max(requestedDistances[i], hyperfocalDistance) * (1.0f + errorMargin);
+
+            mCollector.expectEquals("Lens moves even though focus_distance didn't change",
+                    lensStates[i], CaptureResult.LENS_STATE_STATIONARY);
+            if (noOvershoot) {
+                mCollector.expectInRange("Focus distance in result should be close enough to " +
+                        "requested value", resultDistances[i], marginMin, marginMax);
+            }
+            mCollector.expectInRange("Result focus distance is out of range",
+                    resultDistances[i], minValue, maxValue);
+        }
+
+        for (int i = repeatStart; i < resultDistances.length-1; i ++) {
+            float marginMin = requestedDistances[i] * (1.0f - errorMargin);
+            // HAL may choose to use hyperfocal distance for all distances between [0, hyperfocal].
+            float marginMax =
+                    Math.max(requestedDistances[i], hyperfocalDistance) * (1.0f + errorMargin);
+            if (noOvershoot) {
+                // Result focus distance shouldn't overshoot the request
+                boolean condition;
+                if (ascendingOrder) {
+                    condition = resultDistances[i] <= marginMax;
+               } else {
+                    condition = resultDistances[i] >= marginMin;
+                }
+                mCollector.expectTrue(String.format(
+                      "Lens shouldn't move past request focus distance. result " +
+                      resultDistances[i] + " vs target of " +
+                      (ascendingOrder ? marginMax : marginMin)), condition);
+            }
+
+            // Verify monotonically increased focus distance setting
+            boolean condition;
+            float compareDistance = resultDistances[i+1] - resultDistances[i];
+            if (i < resultDistances.length-1-repeatEnd) {
+                condition = (ascendingOrder ? compareDistance > 0 : compareDistance < 0);
+            } else {
+                condition = (ascendingOrder ? compareDistance >= 0 : compareDistance <= 0);
+            }
+            mCollector.expectTrue(String.format("Adjacent [resultDistances, lens_state] results ["
+                  + resultDistances[i] + "," + lensStates[i] + "], [" + resultDistances[i+1] + ","
+                  + lensStates[i+1] + "] monotonicity is broken"), condition);
+        }
+
+        mCollector.expectTrue(String.format("All values of this array are equal: " +
+                resultDistances[0] + " " + resultDistances[resultDistances.length-1]),
+                resultDistances[0] != resultDistances[resultDistances.length-1]);
+
+        // Verify lens moved to destination location.
+        mCollector.expectInRange("Focus distance " + resultDistances[resultDistances.length-1] +
+                " for minFocusDistance should be closed enough to requested value " +
+                requestedDistances[requestedDistances.length-1],
+                resultDistances[resultDistances.length-1],
+                requestedDistances[requestedDistances.length-1] * (1.0f - errorMargin),
+                requestedDistances[requestedDistances.length-1] * (1.0f + errorMargin));
     }
 
     /**
@@ -946,7 +1267,7 @@
         }
 
         // Test flash SINGLE mode control. Wait for flash state to be READY first.
-        if (mStaticInfo.isHardwareLevelLimitedOrBetter()) {
+        if (mStaticInfo.isHardwareLevelAtLeastLimited()) {
             waitForResultValue(listener, CaptureResult.FLASH_STATE, CaptureResult.FLASH_STATE_READY,
                     NUM_RESULTS_WAIT_TIMEOUT);
         } // else the settings were already waited on earlier
@@ -1696,7 +2017,7 @@
             // In LEGACY mode, a transition to one of the continuous AF modes does not necessarily
             // result in a passive AF call if the camera has already been focused, and the scene has
             // not changed enough to trigger an AF pass.  Skip this constraint for LEGACY.
-            if (mStaticInfo.isHardwareLevelLimitedOrBetter() &&
+            if (mStaticInfo.isHardwareLevelAtLeastLimited() &&
                     (mode == CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE ||
                     mode == CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_VIDEO)) {
                 List<Integer> afStateList = new ArrayList<Integer>();
@@ -1864,7 +2185,7 @@
                                  previousCrop.height() > currentCrop.height()));
                 }
 
-                if (mStaticInfo.isHardwareLevelLimitedOrBetter()) {
+                if (mStaticInfo.isHardwareLevelAtLeastLimited()) {
                     mCollector.expectRectsAreSimilar(
                             "Request and result crop region should be similar",
                             cropRegions[i], cropRegion, CROP_REGION_ERROR_PERCENT_DELTA);
@@ -2042,16 +2363,28 @@
 
     /**
      * Generate test focus distances in range of [0, minFocusDistance] in increasing order.
+     *
+     * @param repeatMin number of times minValue will be repeated.
+     * @param repeatMax number of times maxValue will be repeated.
      */
-    private float[] getFocusDistanceTestValuesInOrder() {
-        float[] testValues = new float[NUM_TEST_FOCUS_DISTANCES + 1];
+    private float[] getFocusDistanceTestValuesInOrder(int repeatMin, int repeatMax) {
+        int totalCount = NUM_TEST_FOCUS_DISTANCES + 1 + repeatMin + repeatMax;
+        float[] testValues = new float[totalCount];
         float minValue = 0;
         float maxValue = mStaticInfo.getMinimumFocusDistanceChecked();
 
         float range = maxValue - minValue;
         float stepSize = range / NUM_TEST_FOCUS_DISTANCES;
-        for (int i = 0; i < testValues.length; i++) {
-            testValues[i] = minValue + stepSize * i;
+
+        for (int i = 0; i < repeatMin; i++) {
+            testValues[i] = minValue;
+        }
+        for (int i = 0; i <= NUM_TEST_FOCUS_DISTANCES; i++) {
+            testValues[repeatMin+i] = minValue + stepSize * i;
+        }
+        for (int i = 0; i < repeatMax; i++) {
+            testValues[repeatMin+NUM_TEST_FOCUS_DISTANCES+1+i] =
+                    maxValue;
         }
 
         return testValues;
@@ -2114,7 +2447,7 @@
      * @param result Result sensitivity
      */
     private void validateSensitivity(int request, int result) {
-        float sensitivityDelta = (float)(request - result);
+        float sensitivityDelta = request - result;
         float sensitivityErrorMargin = request * SENSITIVITY_ERROR_MARGIN_RATE;
         // First, round down not up, second, need close enough.
         mCollector.expectTrue("Sensitivity is invalid for AE manaul control test, request: "
diff --git a/tests/camera/src/android/hardware/camera2/cts/CaptureResultTest.java b/tests/camera/src/android/hardware/camera2/cts/CaptureResultTest.java
index 2ae29c3..802c500 100644
--- a/tests/camera/src/android/hardware/camera2/cts/CaptureResultTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/CaptureResultTest.java
@@ -29,6 +29,7 @@
 import android.os.SystemClock;
 import android.util.Pair;
 import android.util.Size;
+import android.hardware.camera2.cts.helpers.StaticMetadata;
 import android.hardware.camera2.cts.testcases.Camera2AndroidTestCase;
 
 import static android.hardware.camera2.cts.CameraTestUtils.*;
@@ -499,6 +500,21 @@
             waiverKeys.add(CaptureResult.LENS_RADIAL_DISTORTION);
         }
 
+        // Waived if RAW output is not supported
+        int[] outputFormats = mStaticInfo.getAvailableFormats(
+                StaticMetadata.StreamDirection.Output);
+        boolean supportRaw = false;
+        for (int format : outputFormats) {
+            if (format == ImageFormat.RAW_SENSOR || format == ImageFormat.RAW10 ||
+                    format == ImageFormat.RAW12 || format == ImageFormat.RAW_PRIVATE) {
+                supportRaw = true;
+                break;
+            }
+        }
+        if (!supportRaw) {
+            waiverKeys.add(CaptureResult.CONTROL_POST_RAW_SENSITIVITY_BOOST);
+        }
+
         if (mStaticInfo.getAeMaxRegionsChecked() == 0) {
             waiverKeys.add(CaptureResult.CONTROL_AE_REGIONS);
         }
@@ -509,7 +525,13 @@
             waiverKeys.add(CaptureResult.CONTROL_AF_REGIONS);
         }
 
-        if (mStaticInfo.isHardwareLevelFull()) {
+        // Keys for dynamic black/white levels
+        if (!mStaticInfo.isOpticalBlackRegionSupported()) {
+            waiverKeys.add(CaptureResult.SENSOR_DYNAMIC_BLACK_LEVEL);
+            waiverKeys.add(CaptureResult.SENSOR_DYNAMIC_WHITE_LEVEL);
+        }
+
+        if (mStaticInfo.isHardwareLevelAtLeastFull()) {
             return waiverKeys;
         }
 
@@ -742,6 +764,7 @@
         resultKeys.add(CaptureResult.CONTROL_AE_STATE);
         resultKeys.add(CaptureResult.CONTROL_AF_STATE);
         resultKeys.add(CaptureResult.CONTROL_AWB_STATE);
+        resultKeys.add(CaptureResult.CONTROL_POST_RAW_SENSITIVITY_BOOST);
         resultKeys.add(CaptureResult.EDGE_MODE);
         resultKeys.add(CaptureResult.FLASH_MODE);
         resultKeys.add(CaptureResult.FLASH_STATE);
@@ -775,6 +798,8 @@
         resultKeys.add(CaptureResult.SENSOR_TEST_PATTERN_DATA);
         resultKeys.add(CaptureResult.SENSOR_TEST_PATTERN_MODE);
         resultKeys.add(CaptureResult.SENSOR_ROLLING_SHUTTER_SKEW);
+        resultKeys.add(CaptureResult.SENSOR_DYNAMIC_BLACK_LEVEL);
+        resultKeys.add(CaptureResult.SENSOR_DYNAMIC_WHITE_LEVEL);
         resultKeys.add(CaptureResult.SHADING_MODE);
         resultKeys.add(CaptureResult.STATISTICS_FACE_DETECT_MODE);
         resultKeys.add(CaptureResult.STATISTICS_HOT_PIXEL_MAP_MODE);
diff --git a/tests/camera/src/android/hardware/camera2/cts/DngCreatorTest.java b/tests/camera/src/android/hardware/camera2/cts/DngCreatorTest.java
index bddbd52..02bb348 100644
--- a/tests/camera/src/android/hardware/camera2/cts/DngCreatorTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/DngCreatorTest.java
@@ -46,13 +46,16 @@
 import android.view.Surface;
 
 import java.io.ByteArrayOutputStream;
+import java.io.File;
 import java.io.FileOutputStream;
 import java.nio.ByteBuffer;
 import java.nio.channels.FileChannel;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Calendar;
 import java.util.Collections;
 import java.util.List;
+import java.util.TimeZone;
 
 import static android.hardware.camera2.cts.helpers.AssertHelpers.*;
 
@@ -63,13 +66,39 @@
     private static final String TAG = "DngCreatorTest";
     private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
     private static final String DEBUG_DNG_FILE = "raw16.dng";
+    private static final String TEST_DNG_FILE = "test.dng";
 
     private static final double IMAGE_DIFFERENCE_TOLERANCE = 65;
     private static final int DEFAULT_PATCH_DIMEN = 512;
     private static final int AE_TIMEOUT_MS = 2000;
 
+    // Constants used for GPS testing.
+    private static final double GPS_DIFFERENCE_TOLERANCE = 0.0001;
+    private static final double GPS_LATITUDE = 37.420016;
+    private static final double GPS_LONGITUDE = -122.081987;
+    private static final String GPS_DATESTAMP = "2015:01:27";
+    private static final String GPS_TIMESTAMP = "02:12:01";
+    private static final Calendar GPS_CALENDAR =
+            Calendar.getInstance(TimeZone.getTimeZone("GMT+0"));
+
+    /** Load DNG validation jni on initialization */
+    static {
+        System.loadLibrary("ctscamera2_jni");
+    }
+
+    static {
+        GPS_CALENDAR.set(2015, 0, 27, 2, 12, 01);
+    }
+
+    class CapturedData {
+        public Pair<List<Image>, CaptureResult> imagePair;
+        public CameraCharacteristics characteristics;
+    }
+
     @Override
     protected void setUp() throws Exception {
+        RenderScriptSingleton.setContext(getContext());
+
         super.setUp();
     }
 
@@ -83,8 +112,6 @@
     @Override
     public synchronized void setContext(Context context) {
         super.setContext(context);
-
-        RenderScriptSingleton.setContext(context);
     }
 
     /**
@@ -144,6 +171,8 @@
                     fileStream.close();
                     Log.v(TAG, "Test DNG file for camera " + deviceId + " saved to " + dngFilePath);
                 }
+                assertTrue("Generated DNG file does not pass validation",
+                        validateDngNative(outputStream.toByteArray()));
             } finally {
                 closeDevice(deviceId);
                 closeImageReader(captureReader);
@@ -165,8 +194,8 @@
      *
      * <p>
      * For each camera, capture a single RAW16 image at the first capture size reported for
-     * the raw format on that device, and save that image as a DNG file.  No further validation
-     * is done.
+     * the raw format on that device, and save that image as a DNG file. GPS information validation
+     * is done via ExifInterface.
      * </p>
      *
      * <p>
@@ -222,9 +251,9 @@
                 DngCreator dngCreator = new DngCreator(characteristics, resultPair.second);
                 Location l = new Location("test");
                 l.reset();
-                l.setLatitude(37.420016);
-                l.setLongitude(-122.081987);
-                l.setTime(System.currentTimeMillis());
+                l.setLatitude(GPS_LATITUDE);
+                l.setLongitude(GPS_LONGITUDE);
+                l.setTime(GPS_CALENDAR.getTimeInMillis());
                 dngCreator.setLocation(l);
 
                 dngCreator.setDescription("helloworld");
@@ -233,16 +262,41 @@
                 outputStream = new ByteArrayOutputStream();
                 dngCreator.writeImage(outputStream, resultPair.first.get(0));
 
+                String filePath = DEBUG_FILE_NAME_BASE + "/camera_thumb_" + deviceId + "_" +
+                        DEBUG_DNG_FILE;
+                // Write out captured DNG file for the first camera device if setprop is enabled
+                fileStream = new FileOutputStream(filePath);
+                fileStream.write(outputStream.toByteArray());
+                fileStream.flush();
+                fileStream.close();
                 if (VERBOSE) {
-                    String filePath = DEBUG_FILE_NAME_BASE + "/camera_thumb_" + deviceId + "_" +
-                            DEBUG_DNG_FILE;
-                    // Write out captured DNG file for the first camera device if setprop is enabled
-                    fileStream = new FileOutputStream(filePath);
-                    fileStream.write(outputStream.toByteArray());
-                    fileStream.flush();
-                    fileStream.close();
                     Log.v(TAG, "Test DNG file for camera " + deviceId + " saved to " + filePath);
                 }
+
+                assertTrue("Generated DNG file does not pass validation",
+                        validateDngNative(outputStream.toByteArray()));
+
+                ExifInterface exifInterface = new ExifInterface(filePath);
+                // Verify GPS data.
+                float[] latLong = new float[2];
+                assertTrue(exifInterface.getLatLong(latLong));
+                assertEquals(GPS_LATITUDE, latLong[0], GPS_DIFFERENCE_TOLERANCE);
+                assertEquals(GPS_LONGITUDE, latLong[1], GPS_DIFFERENCE_TOLERANCE);
+                assertEquals(GPS_DATESTAMP,
+                        exifInterface.getAttribute(ExifInterface.TAG_GPS_DATESTAMP));
+                assertEquals(GPS_TIMESTAMP,
+                        exifInterface.getAttribute(ExifInterface.TAG_GPS_TIMESTAMP));
+
+                // Verify the orientation.
+                assertEquals(ExifInterface.ORIENTATION_FLIP_VERTICAL,
+                        exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION,
+                                ExifInterface.ORIENTATION_UNDEFINED));
+
+                if (!VERBOSE) {
+                    // Delete the captured DNG file.
+                    File dngFile = new File(filePath);
+                    assertTrue(dngFile.delete());
+                }
             } finally {
                 closeDevice(deviceId);
                 for (ImageReader r : captureReaders) {
@@ -282,62 +336,22 @@
      * </p>
      */
     public void testRaw16JpegConsistency() throws Exception {
-        for (int i = 0; i < mCameraIds.length; i++) {
-            String deviceId = mCameraIds[i];
-            List<ImageReader> captureReaders = new ArrayList<ImageReader>();
-            List<CameraTestUtils.SimpleImageReaderListener> captureListeners =
-                    new ArrayList<CameraTestUtils.SimpleImageReaderListener>();
+        for (String deviceId : mCameraIds) {
+            List<ImageReader> captureReaders = new ArrayList<>();
             FileOutputStream fileStream = null;
             ByteArrayOutputStream outputStream = null;
             FileChannel fileChannel = null;
             try {
-                openDevice(deviceId);
-
-                if (!mStaticInfo.isCapabilitySupported(
-                        CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_RAW)) {
-                    Log.i(TAG, "RAW capability is not supported in camera " + mCameraIds[i] +
-                            ". Skip the test.");
+                CapturedData data = captureRawJpegImagePair(deviceId, captureReaders);
+                if (data == null) {
                     continue;
                 }
-
-                Size activeArraySize = mStaticInfo.getRawDimensChecked();
-
-                // Get largest jpeg size
-                Size[] targetJpegSizes =
-                        mStaticInfo.getAvailableSizesForFormatChecked(ImageFormat.JPEG,
-                                StaticMetadata.StreamDirection.Output);
-
-                Size largestJpegSize = Collections.max(Arrays.asList(targetJpegSizes),
-                        new CameraTestUtils.SizeComparator());
-
-                // Create raw image reader and capture listener
-                CameraTestUtils.SimpleImageReaderListener rawListener
-                        = new CameraTestUtils.SimpleImageReaderListener();
-                captureReaders.add(createImageReader(activeArraySize, ImageFormat.RAW_SENSOR, 2,
-                        rawListener));
-                captureListeners.add(rawListener);
-
-
-                // Create jpeg image reader and capture listener
-                CameraTestUtils.SimpleImageReaderListener jpegListener
-                        = new CameraTestUtils.SimpleImageReaderListener();
-                captureReaders.add(createImageReader(largestJpegSize, ImageFormat.JPEG, 2,
-                        jpegListener));
-                captureListeners.add(jpegListener);
-
-                Pair<List<Image>, CaptureResult> resultPair = captureSingleRawShot(activeArraySize,
-                        captureReaders, /*waitForAe*/true, captureListeners);
-                CameraCharacteristics characteristics = mStaticInfo.getCharacteristics();
-                Image raw = resultPair.first.get(0);
-                Image jpeg = resultPair.first.get(1);
+                Image raw = data.imagePair.first.get(0);
+                Image jpeg = data.imagePair.first.get(1);
 
                 Bitmap rawBitmap = Bitmap.createBitmap(raw.getWidth(), raw.getHeight(),
                         Bitmap.Config.ARGB_8888);
 
-                Size rawBitmapSize = new Size(rawBitmap.getWidth(), rawBitmap.getHeight());
-                assertTrue("Raw bitmap size must be equal to either pre-correction active array" +
-                        " size or pixel array size.", rawBitmapSize.equals(activeArraySize));
-
                 byte[] rawPlane = new byte[raw.getPlanes()[0].getRowStride() * raw.getHeight()];
 
                 // Render RAW image to a bitmap
@@ -346,15 +360,16 @@
 
                 RawConverter.convertToSRGB(RenderScriptSingleton.getRS(), raw.getWidth(),
                         raw.getHeight(), raw.getPlanes()[0].getRowStride(), rawPlane,
-                        characteristics, resultPair.second, /*offsetX*/0, /*offsetY*/0,
-                        /*out*/rawBitmap);
+                        data.characteristics, data.imagePair.second, /*offsetX*/ 0, /*offsetY*/ 0,
+                        /*out*/ rawBitmap);
 
                 rawPlane = null;
                 System.gc(); // Hint to VM
 
                 if (VERBOSE) {
                     // Generate DNG file
-                    DngCreator dngCreator = new DngCreator(characteristics, resultPair.second);
+                    DngCreator dngCreator =
+                            new DngCreator(data.characteristics, data.imagePair.second);
 
                     // Write DNG to file
                     String dngFilePath = DEBUG_FILE_NAME_BASE + "/camera_" + deviceId + "_" +
@@ -388,82 +403,8 @@
                             rawFilePath);
                 }
 
-                raw.close();
-
-                // Decompress JPEG image to a bitmap
-                byte[] compressedJpegData = CameraTestUtils.getDataFromImage(jpeg);
-
-                jpeg.close();
-
-                // Get JPEG dimensions without decoding
-                BitmapFactory.Options opt0 = new BitmapFactory.Options();
-                opt0.inJustDecodeBounds = true;
-                BitmapFactory.decodeByteArray(compressedJpegData, /*offset*/0,
-                        compressedJpegData.length, /*inout*/opt0);
-                Rect jpegDimens = new Rect(0, 0, opt0.outWidth, opt0.outHeight);
-
-                // Find square center patch from JPEG and RAW bitmaps
-                RectF jpegRect = new RectF(jpegDimens);
-                RectF rawRect = new RectF(0, 0, rawBitmap.getWidth(), rawBitmap.getHeight());
-                int sideDimen = Math.min(Math.min(Math.min(Math.min(DEFAULT_PATCH_DIMEN,
-                        jpegDimens.width()), jpegDimens.height()), rawBitmap.getWidth()),
-                        rawBitmap.getHeight());
-
-                RectF jpegIntermediate = new RectF(0, 0, sideDimen, sideDimen);
-                jpegIntermediate.offset(jpegRect.centerX() - jpegIntermediate.centerX(),
-                        jpegRect.centerY() - jpegIntermediate.centerY());
-
-                RectF rawIntermediate = new RectF(0, 0, sideDimen, sideDimen);
-                rawIntermediate.offset(rawRect.centerX() - rawIntermediate.centerX(),
-                        rawRect.centerY() - rawIntermediate.centerY());
-                Rect jpegFinal = new Rect();
-                jpegIntermediate.roundOut(jpegFinal);
-                Rect rawFinal = new Rect();
-                rawIntermediate.roundOut(rawFinal);
-
-                // Get RAW center patch, and free up rest of RAW image
-                Bitmap rawPatch = Bitmap.createBitmap(rawBitmap, rawFinal.left, rawFinal.top,
-                        rawFinal.width(), rawFinal.height());
-                rawBitmap.recycle();
-                rawBitmap = null;
-                System.gc(); // Hint to VM
-
-                BitmapFactory.Options opt = new BitmapFactory.Options();
-                opt.inPreferredConfig = Bitmap.Config.ARGB_8888;
-                Bitmap jpegPatch = BitmapRegionDecoder.newInstance(compressedJpegData,
-                        /*offset*/0, compressedJpegData.length, /*isShareable*/true).
-                        decodeRegion(jpegFinal, opt);
-
-                // Compare center patch from JPEG and rendered RAW bitmap
-                double difference = BitmapUtils.calcDifferenceMetric(jpegPatch, rawPatch);
-                if (difference > IMAGE_DIFFERENCE_TOLERANCE) {
-                    // Write JPEG patch to file
-                    String jpegFilePath = DEBUG_FILE_NAME_BASE + "/camera_" + deviceId +
-                            "_jpeg_patch.jpg";
-                    fileStream = new FileOutputStream(jpegFilePath);
-                    jpegPatch.compress(Bitmap.CompressFormat.JPEG, 90, fileStream);
-                    fileStream.flush();
-                    fileStream.close();
-                    Log.e(TAG, "Failed JPEG patch file for camera " + deviceId + " saved to " +
-                            jpegFilePath);
-
-                    // Write RAW patch to file
-                    String rawFilePath = DEBUG_FILE_NAME_BASE + "/camera_" + deviceId +
-                            "_raw_patch.jpg";
-                    fileStream = new FileOutputStream(rawFilePath);
-                    rawPatch.compress(Bitmap.CompressFormat.JPEG, 90, fileStream);
-                    fileStream.flush();
-                    fileStream.close();
-                    Log.e(TAG, "Failed RAW patch file for camera " + deviceId + " saved to " +
-                            rawFilePath);
-
-                    fail("Camera " + mCamera.getId() + ": RAW and JPEG image at  for the same " +
-                            "frame are not similar, center patches have difference metric of " +
-                            difference);
-                }
-
+                validateRawJpegImagePair(rawBitmap, jpeg, deviceId);
             } finally {
-                closeDevice(deviceId);
                 for (ImageReader r : captureReaders) {
                     closeImageReader(r);
                 }
@@ -483,6 +424,184 @@
         }
     }
 
+    /**
+     * Test basic DNG creation, ensure that the DNG image can be rendered by BitmapFactory.
+     */
+    public void testDngRenderingByBitmapFactor() throws Exception {
+        for (String deviceId : mCameraIds) {
+            List<ImageReader> captureReaders = new ArrayList<>();
+
+            CapturedData data = captureRawJpegImagePair(deviceId, captureReaders);
+            if (data == null) {
+                continue;
+            }
+            Image raw = data.imagePair.first.get(0);
+            Image jpeg = data.imagePair.first.get(1);
+
+            // Generate DNG file
+            DngCreator dngCreator = new DngCreator(data.characteristics, data.imagePair.second);
+
+            // Write DNG to file
+            String dngFilePath = DEBUG_FILE_NAME_BASE + "/camera_" + deviceId + "_"
+                    + TEST_DNG_FILE;
+            // Write out captured DNG file for the first camera device if setprop is enabled
+            try (FileOutputStream fileStream = new FileOutputStream(dngFilePath)) {
+                dngCreator.writeImage(fileStream, raw);
+
+                // Render the DNG file using BitmapFactory.
+                Bitmap rawBitmap = BitmapFactory.decodeFile(dngFilePath);
+                assertNotNull(rawBitmap);
+
+                validateRawJpegImagePair(rawBitmap, jpeg, deviceId);
+            } finally {
+                for (ImageReader r : captureReaders) {
+                    closeImageReader(r);
+                }
+
+                System.gc(); // Hint to VM
+            }
+        }
+    }
+
+    /*
+     * Create RAW + JPEG image pair with characteristics info.
+     */
+    private CapturedData captureRawJpegImagePair(String deviceId, List<ImageReader> captureReaders)
+            throws Exception {
+        CapturedData data = new CapturedData();
+        List<CameraTestUtils.SimpleImageReaderListener> captureListeners = new ArrayList<>();
+        try {
+            openDevice(deviceId);
+
+            if (!mStaticInfo.isCapabilitySupported(
+                    CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_RAW)) {
+                Log.i(TAG, "RAW capability is not supported in camera " + deviceId
+                        + ". Skip the test.");
+                return null;
+            }
+
+            Size activeArraySize = mStaticInfo.getRawDimensChecked();
+
+            // Get largest jpeg size
+            Size[] targetJpegSizes = mStaticInfo.getAvailableSizesForFormatChecked(
+                    ImageFormat.JPEG, StaticMetadata.StreamDirection.Output);
+
+            Size largestJpegSize = Collections.max(Arrays.asList(targetJpegSizes),
+                    new CameraTestUtils.SizeComparator());
+
+            // Create raw image reader and capture listener
+            CameraTestUtils.SimpleImageReaderListener rawListener =
+                    new CameraTestUtils.SimpleImageReaderListener();
+            captureReaders.add(createImageReader(activeArraySize, ImageFormat.RAW_SENSOR, 2,
+                    rawListener));
+            captureListeners.add(rawListener);
+
+
+            // Create jpeg image reader and capture listener
+            CameraTestUtils.SimpleImageReaderListener jpegListener =
+                    new CameraTestUtils.SimpleImageReaderListener();
+            captureReaders.add(createImageReader(largestJpegSize, ImageFormat.JPEG, 2,
+                    jpegListener));
+            captureListeners.add(jpegListener);
+
+            data.imagePair = captureSingleRawShot(activeArraySize,
+                    captureReaders, /*waitForAe*/ true, captureListeners);
+            data.characteristics = mStaticInfo.getCharacteristics();
+
+            Image raw = data.imagePair.first.get(0);
+            Size rawBitmapSize = new Size(raw.getWidth(), raw.getHeight());
+            assertTrue("Raw bitmap size must be equal to either pre-correction active array" +
+                    " size or pixel array size.", rawBitmapSize.equals(activeArraySize));
+
+            return data;
+        } finally {
+            closeDevice(deviceId);
+        }
+    }
+
+    /*
+     * Verify the image pair by comparing the center patch.
+     */
+    private void validateRawJpegImagePair(Bitmap rawBitmap, Image jpeg, String deviceId)
+            throws Exception {
+        // Decompress JPEG image to a bitmap
+        byte[] compressedJpegData = CameraTestUtils.getDataFromImage(jpeg);
+
+        // Get JPEG dimensions without decoding
+        BitmapFactory.Options opt0 = new BitmapFactory.Options();
+        opt0.inJustDecodeBounds = true;
+        BitmapFactory.decodeByteArray(compressedJpegData, /*offset*/0,
+                compressedJpegData.length, /*inout*/opt0);
+        Rect jpegDimens = new Rect(0, 0, opt0.outWidth, opt0.outHeight);
+
+        // Find square center patch from JPEG and RAW bitmaps
+        RectF jpegRect = new RectF(jpegDimens);
+        RectF rawRect = new RectF(0, 0, rawBitmap.getWidth(), rawBitmap.getHeight());
+        int sideDimen = Math.min(Math.min(Math.min(Math.min(DEFAULT_PATCH_DIMEN,
+                jpegDimens.width()), jpegDimens.height()), rawBitmap.getWidth()),
+                rawBitmap.getHeight());
+
+        RectF jpegIntermediate = new RectF(0, 0, sideDimen, sideDimen);
+        jpegIntermediate.offset(jpegRect.centerX() - jpegIntermediate.centerX(),
+                jpegRect.centerY() - jpegIntermediate.centerY());
+
+        RectF rawIntermediate = new RectF(0, 0, sideDimen, sideDimen);
+        rawIntermediate.offset(rawRect.centerX() - rawIntermediate.centerX(),
+                rawRect.centerY() - rawIntermediate.centerY());
+        Rect jpegFinal = new Rect();
+        jpegIntermediate.roundOut(jpegFinal);
+        Rect rawFinal = new Rect();
+        rawIntermediate.roundOut(rawFinal);
+
+        // Get RAW center patch, and free up rest of RAW image
+        Bitmap rawPatch = Bitmap.createBitmap(rawBitmap, rawFinal.left, rawFinal.top,
+                rawFinal.width(), rawFinal.height());
+        rawBitmap.recycle();
+        rawBitmap = null;
+        System.gc(); // Hint to VM
+
+        BitmapFactory.Options opt = new BitmapFactory.Options();
+        opt.inPreferredConfig = Bitmap.Config.ARGB_8888;
+        Bitmap jpegPatch = BitmapRegionDecoder.newInstance(compressedJpegData,
+                /*offset*/0, compressedJpegData.length, /*isShareable*/true).
+                decodeRegion(jpegFinal, opt);
+
+        // Compare center patch from JPEG and rendered RAW bitmap
+        double difference = BitmapUtils.calcDifferenceMetric(jpegPatch, rawPatch);
+        if (difference > IMAGE_DIFFERENCE_TOLERANCE) {
+            FileOutputStream fileStream = null;
+            try {
+                // Write JPEG patch to file
+                String jpegFilePath = DEBUG_FILE_NAME_BASE + "/camera_" + deviceId +
+                        "_jpeg_patch.jpg";
+                fileStream = new FileOutputStream(jpegFilePath);
+                jpegPatch.compress(Bitmap.CompressFormat.JPEG, 90, fileStream);
+                fileStream.flush();
+                fileStream.close();
+                Log.e(TAG, "Failed JPEG patch file for camera " + deviceId + " saved to " +
+                        jpegFilePath);
+
+                // Write RAW patch to file
+                String rawFilePath = DEBUG_FILE_NAME_BASE + "/camera_" + deviceId +
+                        "_raw_patch.jpg";
+                fileStream = new FileOutputStream(rawFilePath);
+                rawPatch.compress(Bitmap.CompressFormat.JPEG, 90, fileStream);
+                fileStream.flush();
+                fileStream.close();
+                Log.e(TAG, "Failed RAW patch file for camera " + deviceId + " saved to " +
+                        rawFilePath);
+
+                fail("Camera " + mCamera.getId() + ": RAW and JPEG image at  for the same " +
+                        "frame are not similar, center patches have difference metric of " +
+                        difference);
+            } finally {
+                if (fileStream != null) {
+                    fileStream.close();
+                }
+            }
+        }
+    }
+
     private Pair<Image, CaptureResult> captureSingleRawShot(Size s, boolean waitForAe,
             ImageReader captureReader,
             CameraTestUtils.SimpleImageReaderListener captureListener) throws Exception {
@@ -578,8 +697,9 @@
                 @Override
                 public void onCaptureProgressed(CameraCaptureSession session,
                         CaptureRequest request, CaptureResult partialResult) {
-                    if (partialResult.get(CaptureResult.CONTROL_AE_STATE) ==
-                            CaptureRequest.CONTROL_AE_STATE_CONVERGED) {
+                    int aeState = partialResult.get(CaptureResult.CONTROL_AE_STATE);
+                    if (aeState == CaptureRequest.CONTROL_AE_STATE_CONVERGED ||
+                            aeState == CaptureRequest.CONTROL_AE_STATE_FLASH_REQUIRED) {
                         waitForAeCondition.open();
                     }
                 }
@@ -587,8 +707,9 @@
                 @Override
                 public void onCaptureCompleted(CameraCaptureSession session,
                         CaptureRequest request, TotalCaptureResult result) {
-                    if (result.get(CaptureResult.CONTROL_AE_STATE) ==
-                            CaptureRequest.CONTROL_AE_STATE_CONVERGED) {
+                    int aeState = result.get(CaptureResult.CONTROL_AE_STATE);
+                    if (aeState == CaptureRequest.CONTROL_AE_STATE_CONVERGED ||
+                            aeState == CaptureRequest.CONTROL_AE_STATE_FLASH_REQUIRED) {
                         waitForAeCondition.open();
                     }
                 }
@@ -631,4 +752,12 @@
 
         return ret;
     }
+
+    /**
+     * Use the DNG SDK to validate a DNG file stored in the buffer.
+     *
+     * Returns false if the DNG has validation errors. Validation warnings/errors
+     * will be printed to logcat.
+     */
+    private static native boolean validateDngNative(byte[] dngBuffer);
 }
diff --git a/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java b/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
index 49bbff1..4d9a145 100644
--- a/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
@@ -24,6 +24,7 @@
 import android.hardware.camera2.CameraCharacteristics.Key;
 import android.hardware.camera2.CameraManager;
 import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.CaptureResult;
 import android.hardware.camera2.cts.helpers.CameraErrorCollector;
 import android.hardware.camera2.params.BlackLevelPattern;
 import android.hardware.camera2.params.ColorSpaceTransform;
@@ -76,6 +77,7 @@
     private static final int LEGACY = CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY;
     private static final int LIMITED = CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED;
     private static final int FULL = CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL;
+    private static final int LEVEL_3 = CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_3;
     private static final int OPT = Integer.MAX_VALUE;  // For keys that are optional on all hardware levels.
 
     /*
@@ -217,7 +219,7 @@
 
             // Handle FullHD special case first
             if (jpegSizesList.contains(FULLHD)) {
-                if (hwLevel == FULL || (hwLevel == LIMITED &&
+                if (hwLevel >= LEVEL_3 || hwLevel == FULL || (hwLevel == LIMITED &&
                         maxVideoSize.getWidth() >= FULLHD.getWidth() &&
                         maxVideoSize.getHeight() >= FULLHD.getHeight())) {
                     boolean yuvSupportFullHD = yuvSizesList.contains(FULLHD) ||
@@ -245,7 +247,7 @@
                 jpegSizesList.removeAll(toBeRemoved);
             }
 
-            if (hwLevel == FULL || hwLevel == LIMITED) {
+            if (hwLevel >= LEVEL_3 || hwLevel == FULL || hwLevel == LIMITED) {
                 if (!yuvSizesList.containsAll(jpegSizesList)) {
                     for (Size s : jpegSizesList) {
                         if (!yuvSizesList.contains(s)) {
@@ -390,6 +392,18 @@
                 expectKeyAvailable(c, CameraCharacteristics.SENSOR_FORWARD_MATRIX2                          , OPT      ,   RAW                  );
             }
 
+            // Required key if any of RAW format output is supported
+            StreamConfigurationMap config =
+                    c.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
+            assertNotNull(String.format("No stream configuration map found for: ID %s",
+                    mIds[counter]), config);
+            if (config.isOutputSupportedFor(ImageFormat.RAW_SENSOR) ||
+                    config.isOutputSupportedFor(ImageFormat.RAW10)  ||
+                    config.isOutputSupportedFor(ImageFormat.RAW12)  ||
+                    config.isOutputSupportedFor(ImageFormat.RAW_PRIVATE)) {
+                expectKeyAvailable(c,
+                        CameraCharacteristics.CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE, OPT, BC);
+            }
             counter++;
         }
     }
@@ -679,16 +693,23 @@
 
             boolean supportZslEdgeMode = false;
             boolean supportZslNoiseReductionMode = false;
+            boolean supportHiQNoiseReductionMode = false;
+            boolean supportHiQEdgeMode = false;
 
             if (availableEdgeModes != null) {
                 supportZslEdgeMode = Arrays.asList(CameraTestUtils.toObject(availableEdgeModes)).
                         contains(CaptureRequest.EDGE_MODE_ZERO_SHUTTER_LAG);
+                supportHiQEdgeMode = Arrays.asList(CameraTestUtils.toObject(availableEdgeModes)).
+                        contains(CaptureRequest.EDGE_MODE_HIGH_QUALITY);
             }
 
             if (availableNoiseReductionModes != null) {
                 supportZslNoiseReductionMode = Arrays.asList(
                         CameraTestUtils.toObject(availableNoiseReductionModes)).contains(
                         CaptureRequest.NOISE_REDUCTION_MODE_ZERO_SHUTTER_LAG);
+                supportHiQNoiseReductionMode = Arrays.asList(
+                        CameraTestUtils.toObject(availableNoiseReductionModes)).contains(
+                        CaptureRequest.NOISE_REDUCTION_MODE_HIGH_QUALITY);
             }
 
             if (supportYUV || supportOpaque) {
@@ -700,6 +721,15 @@
                         "NOISE_REDUCTION_MODE_ZERO_SHUTTER_LAG is not supported",
                         supportZslNoiseReductionMode);
 
+                // For reprocessing, if we only require OFF and ZSL mode, it will be just like jpeg
+                // encoding. We implicitly require FAST to make reprocessing meaningful, which means
+                // that we also require HIGH_QUALITY.
+                mCollector.expectTrue("Support reprocessing but EDGE_MODE_HIGH_QUALITY is " +
+                        "not supported", supportHiQEdgeMode);
+                mCollector.expectTrue("Support reprocessing but " +
+                        "NOISE_REDUCTION_MODE_HIGH_QUALITY is not supported",
+                        supportHiQNoiseReductionMode);
+
                 // Verify mandatory input formats are supported
                 mCollector.expectTrue("YUV_420_888 input must be supported for YUV reprocessing",
                         !supportYUV || arrayContains(inputFormats, ImageFormat.YUV_420_888));
@@ -1195,6 +1225,82 @@
     }
 
     /**
+     * Sanity check of optical black regions.
+     */
+    public void testOpticalBlackRegions() {
+        int counter = 0;
+        for (CameraCharacteristics c : mCharacteristics) {
+            List<CaptureResult.Key<?>> resultKeys = c.getAvailableCaptureResultKeys();
+            boolean hasDynamicBlackLevel =
+                    resultKeys.contains(CaptureResult.SENSOR_DYNAMIC_BLACK_LEVEL);
+            boolean hasDynamicWhiteLevel =
+                    resultKeys.contains(CaptureResult.SENSOR_DYNAMIC_WHITE_LEVEL);
+            boolean hasFixedBlackLevel =
+                    c.getKeys().contains(CameraCharacteristics.SENSOR_BLACK_LEVEL_PATTERN);
+            boolean hasFixedWhiteLevel =
+                    c.getKeys().contains(CameraCharacteristics.SENSOR_INFO_WHITE_LEVEL);
+            // The black and white levels should be either all supported or none of them is
+            // supported.
+            mCollector.expectTrue("Dynamic black and white level should be all or none of them"
+                    + " be supported", hasDynamicWhiteLevel == hasDynamicBlackLevel);
+            mCollector.expectTrue("Fixed black and white level should be all or none of them"
+                    + " be supported", hasFixedBlackLevel == hasFixedWhiteLevel);
+            mCollector.expectTrue("Fixed black level should be supported if dynamic black"
+                    + " level is supported", !hasDynamicBlackLevel || hasFixedBlackLevel);
+
+            if (c.getKeys().contains(CameraCharacteristics.SENSOR_OPTICAL_BLACK_REGIONS)) {
+                // Regions shouldn't be null or empty.
+                Rect[] regions = CameraTestUtils.getValueNotNull(c,
+                        CameraCharacteristics.SENSOR_OPTICAL_BLACK_REGIONS);
+                CameraTestUtils.assertArrayNotEmpty(regions, "Optical back region arrays must not"
+                        + " be empty");
+
+                // Dynamic black level should be supported if the optical black region is
+                // advertised.
+                mCollector.expectTrue("Dynamic black and white level keys should be advertised in "
+                        + "available capture result key list", hasDynamicWhiteLevel);
+
+                // Range check.
+                for (Rect region : regions) {
+                    mCollector.expectTrue("Camera " + mIds[counter] + ": optical black region" +
+                            " shouldn't be empty!", !region.isEmpty());
+                    mCollector.expectGreaterOrEqual("Optical black region left", 0/*expected*/,
+                            region.left/*actual*/);
+                    mCollector.expectGreaterOrEqual("Optical black region top", 0/*expected*/,
+                            region.top/*actual*/);
+                    mCollector.expectTrue("Optical black region left/right/width/height must be"
+                            + " even number, otherwise, the bayer CFA pattern in this region will"
+                            + " be messed up",
+                            region.left % 2 == 0 && region.top % 2 == 0 &&
+                            region.width() % 2 == 0 && region.height() % 2 == 0);
+                    mCollector.expectGreaterOrEqual("Optical black region top", 0/*expected*/,
+                            region.top/*actual*/);
+                    Size size = CameraTestUtils.getValueNotNull(c,
+                            CameraCharacteristics.SENSOR_INFO_PIXEL_ARRAY_SIZE);
+                    mCollector.expectLessOrEqual("Optical black region width",
+                            size.getWidth()/*expected*/, region.width());
+                    mCollector.expectLessOrEqual("Optical black region height",
+                            size.getHeight()/*expected*/, region.height());
+                    Rect activeArray = CameraTestUtils.getValueNotNull(c,
+                            CameraCharacteristics.SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE);
+                    mCollector.expectTrue("Optical black region" + region + " should be outside of"
+                            + " active array " + activeArray,
+                            !region.intersect(activeArray));
+                    // Region need to be disjoint:
+                    for (Rect region2 : regions) {
+                        mCollector.expectTrue("Optical black region" + region + " should have no "
+                                + "overlap with " + region2,
+                                region == region2 || !region.intersect(region2));
+                    }
+                }
+            } else {
+                Log.i(TAG, "Camera " + mIds[counter] + " doesn't support optical black regions,"
+                        + " skip the region test");
+            }
+            counter++;
+        }
+    }
+    /**
      * Create an invalid size that's close to one of the good sizes in the list, but not one of them
      */
     private Size findInvalidSize(Size[] goodSizes) {
@@ -1356,7 +1462,7 @@
         return remapHardwareLevel(left) - remapHardwareLevel(right);
     }
 
-    /** Remap HW levels worst<->best, 0 = worst, 2 = best */
+    /** Remap HW levels worst<->best, 0 = LEGACY, 1 = LIMITED, 2 = FULL, ..., N = LEVEL_N */
     private static int remapHardwareLevel(int level) {
         switch (level) {
             case OPT:
@@ -1366,7 +1472,11 @@
             case LIMITED:
                 return 1; // second lowest
             case FULL:
-                return 2; // best
+                return 2; // good
+            default:
+                if (level >= LEVEL_3) {
+                    return level; // higher levels map directly
+                }
         }
 
         fail("Unknown HW level: " + level);
@@ -1381,6 +1491,10 @@
                 return "LIMITED";
             case FULL:
                 return "FULL";
+            default:
+                if (level >= LEVEL_3) {
+                    return String.format("LEVEL_%d", level);
+                }
         }
 
         // unknown
diff --git a/tests/camera/src/android/hardware/camera2/cts/ImageReaderTest.java b/tests/camera/src/android/hardware/camera2/cts/ImageReaderTest.java
index 9c783e0..3f68d19 100644
--- a/tests/camera/src/android/hardware/camera2/cts/ImageReaderTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/ImageReaderTest.java
@@ -29,6 +29,7 @@
 import android.hardware.camera2.CameraDevice;
 import android.hardware.camera2.CaptureRequest;
 import android.hardware.camera2.CaptureResult;
+import android.hardware.camera2.cts.CameraTestUtils.ImageDropperListener;
 import android.hardware.camera2.cts.helpers.StaticMetadata;
 import android.hardware.camera2.cts.rs.BitmapUtils;
 import android.hardware.camera2.cts.testcases.Camera2AndroidTestCase;
@@ -160,6 +161,20 @@
         }
     }
 
+    public void testRawPrivate() throws Exception {
+        for (String id : mCameraIds) {
+            try {
+                Log.v(TAG, "Testing raw capture for camera " + id);
+                openDevice(id);
+
+                bufferFormatTestByCamera(ImageFormat.RAW_PRIVATE, /*repeating*/false);
+            } finally {
+                closeDevice(id);
+            }
+        }
+    }
+
+
     public void testRepeatingJpeg() throws Exception {
         for (String id : mCameraIds) {
             try {
@@ -185,11 +200,30 @@
         }
     }
 
+    public void testRepeatingRawPrivate() throws Exception {
+        for (String id : mCameraIds) {
+            try {
+                Log.v(TAG, "Testing repeating raw capture for camera " + id);
+                openDevice(id);
+
+                bufferFormatTestByCamera(ImageFormat.RAW_PRIVATE, /*repeating*/true);
+            } finally {
+                closeDevice(id);
+            }
+        }
+    }
+
     public void testLongProcessingRepeatingRaw() throws Exception {
         for (String id : mCameraIds) {
             try {
                 Log.v(TAG, "Testing long processing on repeating raw for camera " + id);
                 openDevice(id);
+
+                if (!mStaticInfo.isCapabilitySupported(
+                        CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR)) {
+                    continue;
+                }
+
                 bufferFormatLongProcessingTimeTestByCamera(ImageFormat.RAW_SENSOR);
             } finally {
                 closeDevice(id);
@@ -202,6 +236,12 @@
             try {
                 Log.v(TAG, "Testing long processing on repeating YUV for camera " + id);
                 openDevice(id);
+
+                if (!mStaticInfo.isCapabilitySupported(
+                        CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR)) {
+                    continue;
+                }
+
                 bufferFormatLongProcessingTimeTestByCamera(ImageFormat.YUV_420_888);
             } finally {
                 closeDevice(id);
@@ -828,14 +868,22 @@
                                     "sensitivity was %d expecting %d.", i, format, sz.toString(),
                                     getValueNotNull(result, CaptureResult.SENSOR_SENSITIVITY),
                                     TEST_SENSITIVITY_VALUE),
-                            sensitivityDiff == 0);
+                            sensitivityDiff >= 0);
 
 
                     // Sleep to Simulate long porcessing before closing the image.
                     Thread.sleep(LONG_PROCESS_TIME_MS);
                     img.close();
                 }
-                // stop capture.
+                // Stop capture.
+                // Drain the reader queue in case the full queue blocks
+                // HAL from delivering new results
+                ImageDropperListener imageDropperListener = new ImageDropperListener();
+                mReader.setOnImageAvailableListener(imageDropperListener, mHandler);
+                Image img = mReader.acquireLatestImage();
+                if (img != null) {
+                    img.close();
+                }
                 stopCapture(/*fast*/false);
             } finally {
                 closeDefaultImageReader();
diff --git a/tests/camera/src/android/hardware/camera2/cts/NativeCameraDeviceTest.java b/tests/camera/src/android/hardware/camera2/cts/NativeCameraDeviceTest.java
new file mode 100644
index 0000000..e2a61a6
--- /dev/null
+++ b/tests/camera/src/android/hardware/camera2/cts/NativeCameraDeviceTest.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.hardware.camera2.cts;
+
+import android.hardware.camera2.cts.testcases.Camera2SurfaceViewTestCase;
+import android.util.Log;
+import android.util.Size;
+import android.view.Surface;
+
+/**
+ * <p>Basic test for CameraManager class.</p>
+ */
+public class NativeCameraDeviceTest extends Camera2SurfaceViewTestCase {
+    private static final String TAG = "NativeCameraDeviceTest";
+    private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
+
+    /** Load jni on initialization */
+    static {
+        Log.i("NativeCameraDeviceTest", "before loadlibrary");
+        System.loadLibrary("ctscamera2_jni");
+        Log.i("NativeCameraDeviceTest", "after loadlibrary");
+    }
+
+    public void testCameraDeviceOpenAndClose() {
+        assertTrue("testCameraDeviceOpenAndClose fail, see log for details",
+                testCameraDeviceOpenAndCloseNative());
+    }
+
+    public void testCameraDeviceCreateCaptureRequest() {
+        assertTrue("testCameraDeviceCreateCaptureRequest fail, see log for details",
+                testCameraDeviceCreateCaptureRequestNative());
+    }
+
+    public void testCameraDeviceSessionOpenAndClose() {
+        // Init preview surface to a guaranteed working size
+        updatePreviewSurface(new Size(640, 480));
+        assertTrue("testCameraDeviceSessionOpenAndClose fail, see log for details",
+                testCameraDeviceSessionOpenAndCloseNative(mPreviewSurface));
+    }
+
+    public void testCameraDeviceSimplePreview() {
+        // Init preview surface to a guaranteed working size
+        updatePreviewSurface(new Size(640, 480));
+        assertTrue("testCameraDeviceSimplePreview fail, see log for details",
+                testCameraDeviceSimplePreviewNative(mPreviewSurface));
+    }
+
+    private static native boolean testCameraDeviceOpenAndCloseNative();
+    private static native boolean testCameraDeviceCreateCaptureRequestNative();
+    private static native boolean testCameraDeviceSessionOpenAndCloseNative(Surface preview);
+    private static native boolean testCameraDeviceSimplePreviewNative(Surface preview);
+}
diff --git a/tests/camera/src/android/hardware/camera2/cts/NativeCameraManagerTest.java b/tests/camera/src/android/hardware/camera2/cts/NativeCameraManagerTest.java
new file mode 100644
index 0000000..08e0363
--- /dev/null
+++ b/tests/camera/src/android/hardware/camera2/cts/NativeCameraManagerTest.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.hardware.camera2.cts;
+
+import android.test.AndroidTestCase;
+import android.util.Log;
+
+/**
+ * <p>Basic test for CameraManager class.</p>
+ */
+public class NativeCameraManagerTest extends AndroidTestCase {
+    private static final String TAG = "NativeCameraManagerTest";
+    private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
+
+    /** Load jni on initialization */
+    static {
+        Log.i("NativeCameraManagerTest", "before loadlibrary");
+        System.loadLibrary("ctscamera2_jni");
+        Log.i("NativeCameraManagerTest", "after loadlibrary");
+    }
+
+    public void testCameraManagerGetAndClose() {
+        assertTrue("testCameraManagerGetAndClose fail, see log for details",
+                testCameraManagerGetAndCloseNative());
+    }
+
+    public void testCameraManagerGetCameraIds() {
+        assertTrue("testCameraManagerGetCameraIds fail, see log for details",
+                testCameraManagerGetCameraIdsNative());
+    }
+
+    public void testCameraManagerAvailabilityCallback() {
+        assertTrue("testCameraManagerAvailabilityCallback fail, see log for details",
+                testCameraManagerAvailabilityCallbackNative());
+    }
+
+    public void testCameraManagerCameraCharacteristics() {
+        assertTrue("testCameraManagerCameraCharacteristics fail, see log for details",
+                testCameraManagerCharacteristicsNative());
+    }
+
+    private static native boolean testCameraManagerGetAndCloseNative();
+    private static native boolean testCameraManagerGetCameraIdsNative();
+    private static native boolean testCameraManagerAvailabilityCallbackNative();
+    private static native boolean testCameraManagerCharacteristicsNative();
+}
diff --git a/tests/camera/src/android/hardware/camera2/cts/NativeImageReaderTest.java b/tests/camera/src/android/hardware/camera2/cts/NativeImageReaderTest.java
new file mode 100644
index 0000000..7e4508a
--- /dev/null
+++ b/tests/camera/src/android/hardware/camera2/cts/NativeImageReaderTest.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.hardware.camera2.cts;
+
+import android.hardware.camera2.cts.testcases.Camera2AndroidTestCase;
+import android.util.Log;
+
+/**
+ * <p>Basic test for CameraManager class.</p>
+ */
+public class NativeImageReaderTest extends Camera2AndroidTestCase {
+    private static final String TAG = "NativeImageReaderTest";
+    private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
+
+    /** Load jni on initialization */
+    static {
+        Log.i("NativeImageReaderTest", "before loadlibrary");
+        System.loadLibrary("ctscamera2_jni");
+        Log.i("NativeImageReaderTest", "after loadlibrary");
+    }
+
+    public void testJpeg() {
+        assertTrue("testJpeg fail, see log for details",
+                testJpegNative(DEBUG_FILE_NAME_BASE));
+    }
+
+    private static native boolean testJpegNative(String filePath);
+}
diff --git a/tests/camera/src/android/hardware/camera2/cts/NativeStillCaptureTest.java b/tests/camera/src/android/hardware/camera2/cts/NativeStillCaptureTest.java
new file mode 100644
index 0000000..14b5a22
--- /dev/null
+++ b/tests/camera/src/android/hardware/camera2/cts/NativeStillCaptureTest.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.hardware.camera2.cts;
+
+import android.hardware.camera2.cts.testcases.Camera2SurfaceViewTestCase;
+import android.util.Log;
+import android.util.Size;
+import android.view.Surface;
+
+/**
+ * <p>Basic test for CameraManager class.</p>
+ */
+public class NativeStillCaptureTest extends Camera2SurfaceViewTestCase {
+    private static final String TAG = "NativeStillCaptureTest";
+    private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
+
+    /** Load jni on initialization */
+    static {
+        Log.i("NativeStillCaptureTest", "before loadlibrary");
+        System.loadLibrary("ctscamera2_jni");
+        Log.i("NativeStillCaptureTest", "after loadlibrary");
+    }
+
+    public void testStillCapture() {
+        // Init preview surface to a guaranteed working size
+        updatePreviewSurface(new Size(640, 480));
+        assertTrue("testStillCapture fail, see log for details",
+                testStillCaptureNative(DEBUG_FILE_NAME_BASE, mPreviewSurface));
+    }
+
+    private static native boolean testStillCaptureNative(
+            String filePath, Surface previewSurface);
+}
diff --git a/tests/camera/src/android/hardware/camera2/cts/PerformanceTest.java b/tests/camera/src/android/hardware/camera2/cts/PerformanceTest.java
index cfac535..5c97d5c 100644
--- a/tests/camera/src/android/hardware/camera2/cts/PerformanceTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/PerformanceTest.java
@@ -16,7 +16,7 @@
 
 package android.hardware.camera2.cts;
 
-import static com.android.ex.camera2.blocking.BlockingSessionCallback.*;
+import static com.android.ex.camera2.blocking.BlockingSessionCallback.SESSION_CLOSED;
 
 import android.graphics.ImageFormat;
 import android.hardware.camera2.CameraAccessException;
@@ -32,20 +32,20 @@
 import android.hardware.camera2.cts.helpers.StaticMetadata.CheckLevel;
 import android.hardware.camera2.cts.testcases.Camera2SurfaceViewTestCase;
 import android.hardware.camera2.params.InputConfiguration;
-import android.util.Log;
-import android.util.Pair;
-import android.util.Size;
-import android.view.Surface;
-import android.cts.util.DeviceReportLog;
 import android.media.Image;
 import android.media.ImageReader;
 import android.media.ImageWriter;
 import android.os.ConditionVariable;
 import android.os.SystemClock;
+import android.util.Log;
+import android.util.Pair;
+import android.util.Size;
+import android.view.Surface;
 
-import com.android.cts.util.ResultType;
-import com.android.cts.util.ResultUnit;
-import com.android.cts.util.Stat;
+import com.android.compatibility.common.util.DeviceReportLog;
+import com.android.compatibility.common.util.ResultType;
+import com.android.compatibility.common.util.ResultUnit;
+import com.android.compatibility.common.util.Stat;
 import com.android.ex.camera2.blocking.BlockingSessionCallback;
 import com.android.ex.camera2.exceptions.TimeoutRuntimeException;
 
@@ -95,7 +95,7 @@
     @Override
     protected void tearDown() throws Exception {
         // Deliver the report to host will automatically clear the report log.
-        mReportLog.deliverReportToHost(getInstrumentation());
+        mReportLog.submit(getInstrumentation());
         super.tearDown();
     }
 
@@ -114,16 +114,18 @@
      * </p>
      */
     public void testCameraLaunch() throws Exception {
-        double[] cameraOpenTimes = new double[NUM_TEST_LOOPS];
-        double[] configureStreamTimes = new double[NUM_TEST_LOOPS];
-        double[] startPreviewTimes = new double[NUM_TEST_LOOPS];
-        double[] stopPreviewTimes = new double[NUM_TEST_LOOPS];
-        double[] cameraCloseTimes = new double[NUM_TEST_LOOPS];
-        double[] cameraLaunchTimes = new double[NUM_TEST_LOOPS];
         double[] avgCameraLaunchTimes = new double[mCameraIds.length];
 
         int counter = 0;
         for (String id : mCameraIds) {
+            // Do NOT move these variables to outer scope
+            // They will be passed to DeviceReportLog and their references will be stored
+            double[] cameraOpenTimes = new double[NUM_TEST_LOOPS];
+            double[] configureStreamTimes = new double[NUM_TEST_LOOPS];
+            double[] startPreviewTimes = new double[NUM_TEST_LOOPS];
+            double[] stopPreviewTimes = new double[NUM_TEST_LOOPS];
+            double[] cameraCloseTimes = new double[NUM_TEST_LOOPS];
+            double[] cameraLaunchTimes = new double[NUM_TEST_LOOPS];
             try {
                 mStaticInfo = new StaticMetadata(mCameraManager.getCameraCharacteristics(id));
                 if (mStaticInfo.isColorOutputSupported()) {
@@ -180,22 +182,22 @@
 
                 avgCameraLaunchTimes[counter] = Stat.getAverage(cameraLaunchTimes);
                 // Finish the data collection, report the KPIs.
-                mReportLog.printArray("Camera " + id
+                mReportLog.addValues("Camera " + id
                         + ": Camera open time", cameraOpenTimes,
                         ResultType.LOWER_BETTER, ResultUnit.MS);
-                mReportLog.printArray("Camera " + id
+                mReportLog.addValues("Camera " + id
                         + ": Camera configure stream time", configureStreamTimes,
                         ResultType.LOWER_BETTER, ResultUnit.MS);
-                mReportLog.printArray("Camera " + id
+                mReportLog.addValues("Camera " + id
                         + ": Camera start preview time", startPreviewTimes,
                         ResultType.LOWER_BETTER, ResultUnit.MS);
-                mReportLog.printArray("Camera " + id
+                mReportLog.addValues("Camera " + id
                         + ": Camera stop preview", stopPreviewTimes,
                         ResultType.LOWER_BETTER, ResultUnit.MS);
-                mReportLog.printArray("Camera " + id
+                mReportLog.addValues("Camera " + id
                         + ": Camera close time", cameraCloseTimes,
                         ResultType.LOWER_BETTER, ResultUnit.MS);
-                mReportLog.printArray("Camera " + id
+                mReportLog.addValues("Camera " + id
                         + ": Camera launch time", cameraLaunchTimes,
                         ResultType.LOWER_BETTER, ResultUnit.MS);
             }
@@ -205,7 +207,7 @@
             counter++;
         }
         if (mCameraIds.length != 0) {
-            mReportLog.printSummary("Camera launch average time for all cameras ",
+            mReportLog.setSummary("Camera launch average time for all cameras ",
                     Stat.getAverage(avgCameraLaunchTimes), ResultType.LOWER_BETTER, ResultUnit.MS);
         }
     }
@@ -224,13 +226,15 @@
      * </p>
      */
     public void testSingleCapture() throws Exception {
-        double[] captureTimes = new double[NUM_TEST_LOOPS];
-        double[] getPartialTimes = new double[NUM_TEST_LOOPS];
-        double[] getResultTimes = new double[NUM_TEST_LOOPS];
         double[] avgResultTimes = new double[mCameraIds.length];
 
         int counter = 0;
         for (String id : mCameraIds) {
+            // Do NOT move these variables to outer scope
+            // They will be passed to DeviceReportLog and their references will be stored
+            double[] captureTimes = new double[NUM_TEST_LOOPS];
+            double[] getPartialTimes = new double[NUM_TEST_LOOPS];
+            double[] getResultTimes = new double[NUM_TEST_LOOPS];
             try {
                 openDevice(id);
 
@@ -297,19 +301,19 @@
                     // simulate real scenario (preview runs a bit)
                     waitForNumResults(previewResultListener, NUM_RESULTS_WAIT);
 
-                    blockingStopPreview();
+                    stopPreviewAndDrain();
 
                 }
-                mReportLog.printArray("Camera " + id
+                mReportLog.addValues("Camera " + id
                         + ": Camera capture latency", captureTimes,
                         ResultType.LOWER_BETTER, ResultUnit.MS);
                 // If any of the partial results do not contain AE and AF state, then no report
                 if (isPartialTimingValid) {
-                    mReportLog.printArray("Camera " + id
+                    mReportLog.addValues("Camera " + id
                             + ": Camera partial result latency", getPartialTimes,
                             ResultType.LOWER_BETTER, ResultUnit.MS);
                 }
-                mReportLog.printArray("Camera " + id
+                mReportLog.addValues("Camera " + id
                         + ": Camera capture result latency", getResultTimes,
                         ResultType.LOWER_BETTER, ResultUnit.MS);
 
@@ -324,15 +328,14 @@
 
         // Result will not be reported in CTS report if no summary is printed.
         if (mCameraIds.length != 0) {
-            mReportLog.printSummary("Camera capture result average latency for all cameras ",
+            mReportLog.setSummary("Camera capture result average latency for all cameras ",
                     Stat.getAverage(avgResultTimes), ResultType.LOWER_BETTER, ResultUnit.MS);
         }
     }
 
     /**
-     * Test reprocessing shot-to-shot latency, i.e., from the time a reprocess
-     * request is issued to the time the reprocess image is returned.
-     *
+     * Test reprocessing shot-to-shot latency with default NR and edge options, i.e., from the time
+     * a reprocess request is issued to the time the reprocess image is returned.
      */
     public void testReprocessingLatency() throws Exception {
         for (String id : mCameraIds) {
@@ -344,7 +347,8 @@
                 try {
                     openDevice(id);
 
-                    reprocessingPerformanceTestByCamera(format, /*asyncMode*/false);
+                    reprocessingPerformanceTestByCamera(format, /*asyncMode*/false,
+                            /*highQuality*/false);
                 } finally {
                     closeReaderWriters();
                     closeDevice();
@@ -354,7 +358,7 @@
     }
 
     /**
-     * Test reprocessing throughput, i.e., how many frames can be reprocessed
+     * Test reprocessing throughput with default NR and edge options, i.e., how many frames can be reprocessed
      * during a given amount of time.
      *
      */
@@ -368,7 +372,57 @@
                 try {
                     openDevice(id);
 
-                    reprocessingPerformanceTestByCamera(format, /*asyncMode*/true);
+                    reprocessingPerformanceTestByCamera(format, /*asyncMode*/true,
+                            /*highQuality*/false);
+                } finally {
+                    closeReaderWriters();
+                    closeDevice();
+                }
+            }
+        }
+    }
+
+    /**
+     * Test reprocessing shot-to-shot latency with High Quality NR and edge options, i.e., from the
+     * time a reprocess request is issued to the time the reprocess image is returned.
+     */
+    public void testHighQualityReprocessingLatency() throws Exception {
+        for (String id : mCameraIds) {
+            for (int format : REPROCESS_FORMATS) {
+                if (!isReprocessSupported(id, format)) {
+                    continue;
+                }
+
+                try {
+                    openDevice(id);
+
+                    reprocessingPerformanceTestByCamera(format, /*asyncMode*/false,
+                            /*requireHighQuality*/true);
+                } finally {
+                    closeReaderWriters();
+                    closeDevice();
+                }
+            }
+        }
+    }
+
+    /**
+     * Test reprocessing throughput with high quality NR and edge options, i.e., how many frames can
+     * be reprocessed during a given amount of time.
+     *
+     */
+    public void testHighQualityReprocessingThroughput() throws Exception {
+        for (String id : mCameraIds) {
+            for (int format : REPROCESS_FORMATS) {
+                if (!isReprocessSupported(id, format)) {
+                    continue;
+                }
+
+                try {
+                    openDevice(id);
+
+                    reprocessingPerformanceTestByCamera(format, /*asyncMode*/true,
+                            /*requireHighQuality*/true);
                 } finally {
                     closeReaderWriters();
                     closeDevice();
@@ -418,6 +472,10 @@
                             WAIT_FOR_RESULT_TIMEOUT_MS, inputImages[i].getTimestamp());
             reprocessReqs[i] = mCamera.createReprocessCaptureRequest(zslResult);
             reprocessReqs[i].addTarget(mJpegReader.getSurface());
+            reprocessReqs[i].set(CaptureRequest.NOISE_REDUCTION_MODE,
+                    CaptureRequest.NOISE_REDUCTION_MODE_HIGH_QUALITY);
+            reprocessReqs[i].set(CaptureRequest.EDGE_MODE,
+                    CaptureRequest.EDGE_MODE_HIGH_QUALITY);
             mWriter.queueInputImage(inputImages[i]);
         }
 
@@ -481,13 +539,13 @@
             reprocessType = " opaque reprocessing ";
         }
 
-        mReportLog.printArray("Camera " + mCamera.getId()
+        mReportLog.addValues("Camera " + mCamera.getId()
                 + ":" + reprocessType + " max capture timestamp gaps", maxCaptureGapsMs,
                 ResultType.LOWER_BETTER, ResultUnit.MS);
-        mReportLog.printArray("Camera " + mCamera.getId()
+        mReportLog.addValues("Camera " + mCamera.getId()
                 + ":" + reprocessType + "capture average frame duration", averageFrameDurationMs,
                 ResultType.LOWER_BETTER, ResultUnit.MS);
-        mReportLog.printSummary("Camera reprocessing average max capture timestamp gaps for Camera "
+        mReportLog.setSummary("Camera reprocessing average max capture timestamp gaps for Camera "
                 + mCamera.getId(), Stat.getAverage(maxCaptureGapsMs), ResultType.LOWER_BETTER,
                 ResultUnit.MS);
 
@@ -502,7 +560,8 @@
         }
     }
 
-    private void reprocessingPerformanceTestByCamera(int reprocessInputFormat, boolean asyncMode)
+    private void reprocessingPerformanceTestByCamera(int reprocessInputFormat, boolean asyncMode,
+            boolean requireHighQuality)
             throws Exception {
         // Prepare the reprocessing capture
         prepareReprocessCapture(reprocessInputFormat);
@@ -522,6 +581,13 @@
                     mZslResultListener.getCaptureResult(
                             WAIT_FOR_RESULT_TIMEOUT_MS, inputImages[i].getTimestamp());
             reprocessReqs[i] = mCamera.createReprocessCaptureRequest(zslResult);
+            if (requireHighQuality) {
+                // Reprocessing should support high quality for NR and edge modes.
+                reprocessReqs[i].set(CaptureRequest.NOISE_REDUCTION_MODE,
+                        CaptureRequest.NOISE_REDUCTION_MODE_HIGH_QUALITY);
+                reprocessReqs[i].set(CaptureRequest.EDGE_MODE,
+                        CaptureRequest.EDGE_MODE_HIGH_QUALITY);
+            }
             reprocessReqs[i].addTarget(mJpegReader.getSurface());
         }
 
@@ -574,18 +640,27 @@
         }
 
         // Report the performance data
+        String captureMsg;
         if (asyncMode) {
-            mReportLog.printArray("Camera " + mCamera.getId()
-                    + ":" + reprocessType + "capture latency", getImageLatenciesMs,
+            captureMsg = "capture latency";
+            if (requireHighQuality) {
+                captureMsg += " for High Quality noise reduction and edge modes";
+            }
+            mReportLog.addValues("Camera " + mCamera.getId()
+                    + ":" + reprocessType + captureMsg, getImageLatenciesMs,
                     ResultType.LOWER_BETTER, ResultUnit.MS);
-            mReportLog.printSummary("Camera reprocessing average latency for Camera " +
+            mReportLog.setSummary("Camera reprocessing average latency for Camera " +
                     mCamera.getId(), Stat.getAverage(getImageLatenciesMs), ResultType.LOWER_BETTER,
                     ResultUnit.MS);
         } else {
-            mReportLog.printArray("Camera " + mCamera.getId()
-                    + ":" + reprocessType + "shot to shot latency", getImageLatenciesMs,
+            captureMsg = "shot to shot latency";
+            if (requireHighQuality) {
+                captureMsg += " for High Quality noise reduction and edge modes";
+            }
+            mReportLog.addValues("Camera " + mCamera.getId()
+                    + ":" + reprocessType + captureMsg, getImageLatenciesMs,
                     ResultType.LOWER_BETTER, ResultUnit.MS);
-            mReportLog.printSummary("Camera reprocessing shot to shot average latency for Camera " +
+            mReportLog.setSummary("Camera reprocessing shot to shot average latency for Camera " +
                     mCamera.getId(), Stat.getAverage(getImageLatenciesMs), ResultType.LOWER_BETTER,
                     ResultUnit.MS);
         }
diff --git a/tests/camera/src/android/hardware/camera2/cts/RecordingTest.java b/tests/camera/src/android/hardware/camera2/cts/RecordingTest.java
index ca9ccec..1a09a43 100644
--- a/tests/camera/src/android/hardware/camera2/cts/RecordingTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/RecordingTest.java
@@ -104,7 +104,7 @@
         super.tearDown();
     }
 
-    private void doBasicRecording() throws Exception {
+    private void doBasicRecording(boolean useVideoStab) throws Exception {
         for (int i = 0; i < mCameraIds.length; i++) {
             try {
                 Log.i(TAG, "Testing basic recording for camera " + mCameraIds[i]);
@@ -116,9 +116,17 @@
                             " does not support color outputs, skipping");
                     continue;
                 }
+
+                if (!mStaticInfo.isVideoStabilizationSupported() && useVideoStab) {
+                    Log.i(TAG, "Camera " + mCameraIds[i] +
+                            " does not support video stabilization, skipping the stabilization"
+                            + " test");
+                    continue;
+                }
+
                 initSupportedVideoSize(mCameraIds[i]);
 
-                basicRecordingTestByCamera(mCamcorderProfileList);
+                basicRecordingTestByCamera(mCamcorderProfileList, useVideoStab);
             } finally {
                 closeDevice();
                 releaseRecorder();
@@ -128,6 +136,23 @@
 
     /**
      * <p>
+     * Test basic video stabilitzation camera recording.
+     * </p>
+     * <p>
+     * This test covers the typical basic use case of camera recording with video
+     * stabilization is enabled, if video stabilization is supported.
+     * MediaRecorder is used to record the audio and video, CamcorderProfile is
+     * used to configure the MediaRecorder. It goes through the pre-defined
+     * CamcorderProfile list, test each profile configuration and validate the
+     * recorded video. Preview is set to the video size.
+     * </p>
+     */
+    public void testBasicVideoStabilizationRecording() throws Exception {
+        doBasicRecording(/*useVideoStab*/true);
+    }
+
+    /**
+     * <p>
      * Test basic camera recording.
      * </p>
      * <p>
@@ -139,7 +164,7 @@
      * </p>
      */
     public void testBasicRecording() throws Exception {
-        doBasicRecording();
+        doBasicRecording(/*useVideoStab*/false);
     }
 
     /**
@@ -159,7 +184,7 @@
         assertNotNull("Failed to create persistent input surface!", mPersistentSurface);
 
         try {
-            doBasicRecording();
+            doBasicRecording(/*useVideoStab*/false);
         } finally {
             mPersistentSurface.release();
             mPersistentSurface = null;
@@ -311,7 +336,7 @@
                 }
 
                 int camcorderProfileList[] = new int[] {minFpsProfileId, maxFpsProfileId};
-                basicRecordingTestByCamera(camcorderProfileList);
+                basicRecordingTestByCamera(camcorderProfileList, /*useVideoStab*/false);
             } finally {
                 closeDevice();
                 releaseRecorder();
@@ -595,15 +620,15 @@
      * Test camera recording by using each available CamcorderProfile for a
      * given camera. preview size is set to the video size.
      */
-    private void basicRecordingTestByCamera(int[] camcorderProfileList) throws Exception {
+    private void basicRecordingTestByCamera(int[] camcorderProfileList, boolean useVideoStab)
+            throws Exception {
         Size maxPreviewSize = mOrderedPreviewSizes.get(0);
         List<Range<Integer> > fpsRanges = Arrays.asList(
                 mStaticInfo.getAeAvailableTargetFpsRangesChecked());
         int cameraId = Integer.valueOf(mCamera.getId());
         int maxVideoFrameRate = -1;
         for (int profileId : camcorderProfileList) {
-            if (!CamcorderProfile.hasProfile(cameraId, profileId) ||
-                    allowedUnsupported(cameraId, profileId)) {
+            if (!CamcorderProfile.hasProfile(cameraId, profileId)) {
                 continue;
             }
 
@@ -613,6 +638,11 @@
             if (maxVideoFrameRate < profile.videoFrameRate) {
                 maxVideoFrameRate = profile.videoFrameRate;
             }
+
+            if (allowedUnsupported(cameraId, profileId)) {
+                continue;
+            }
+
             if (mStaticInfo.isHardwareLevelLegacy() &&
                     (videoSz.getWidth() > maxPreviewSize.getWidth() ||
                      videoSz.getHeight() > maxPreviewSize.getHeight())) {
@@ -644,7 +674,7 @@
 
             // Start recording
             SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
-            startRecording(/* useMediaRecorder */true, resultListener);
+            startRecording(/* useMediaRecorder */true, resultListener, useVideoStab);
 
             // Record certain duration.
             SystemClock.sleep(RECORDING_DURATION_MS);
@@ -699,7 +729,7 @@
 
             // Start recording
             SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
-            startRecording(/* useMediaRecorder */true, resultListener);
+            startRecording(/* useMediaRecorder */true, resultListener, /*useVideoStab*/false);
 
             // Record certain duration.
             SystemClock.sleep(RECORDING_DURATION_MS);
@@ -852,16 +882,17 @@
                     }
                 }
             }
+            Size defaultvideoSnapshotSz = videoSnapshotSz;
 
             /**
              * Only test full res snapshot when below conditions are all true.
-             * 1. Camera is a FULL device
+             * 1. Camera is at least a LIMITED device.
              * 2. video size is up to max preview size, which will be bounded by 1080p.
              * 3. Full resolution jpeg stream can keep up to video stream speed.
              *    When full res jpeg stream cannot keep up to video stream speed, search
              *    the largest jpeg size that can susptain video speed instead.
              */
-            if (mStaticInfo.isHardwareLevelFull() &&
+            if (mStaticInfo.isHardwareLevelAtLeastLimited() &&
                     videoSz.getWidth() <= maxPreviewSize.getWidth() &&
                     videoSz.getHeight() <= maxPreviewSize.getHeight()) {
                 for (Size jpegSize : mOrderedStillSizes) {
@@ -889,6 +920,23 @@
                     videoSnapshotSz, ImageFormat.JPEG,
                     MAX_VIDEO_SNAPSHOT_IMAGES, /*listener*/null);
 
+            // Full or better devices should support whatever video snapshot size calculated above.
+            // Limited devices may only be able to support the default one.
+            if (mStaticInfo.isHardwareLevelLimited()) {
+                List<Surface> outputs = new ArrayList<Surface>();
+                outputs.add(mPreviewSurface);
+                outputs.add(mRecordingSurface);
+                outputs.add(mReaderSurface);
+                boolean isSupported = isStreamConfigurationSupported(
+                        mCamera, outputs, mSessionListener, mHandler);
+                if (!isSupported) {
+                    videoSnapshotSz = defaultvideoSnapshotSz;
+                    createImageReader(
+                            videoSnapshotSz, ImageFormat.JPEG,
+                            MAX_VIDEO_SNAPSHOT_IMAGES, /*listener*/null);
+                }
+            }
+
             if (VERBOSE) {
                 Log.v(TAG, "Testing camera recording with video size " + videoSz.toString());
             }
@@ -921,7 +969,8 @@
                 CaptureRequest request = videoSnapshotRequestBuilder.build();
 
                 // Start recording
-                startRecording(/* useMediaRecorder */true, resultListener);
+                startRecording(/* useMediaRecorder */true, resultListener,
+                        /*useVideoStab*/mStaticInfo.isVideoStabilizationSupported());
                 long startTime = SystemClock.elapsedRealtime();
 
                 // Record certain duration.
@@ -1112,7 +1161,11 @@
     }
 
     private void startRecording(boolean useMediaRecorder,
-            CameraCaptureSession.CaptureCallback listener) throws Exception {
+            CameraCaptureSession.CaptureCallback listener, boolean useVideoStab) throws Exception {
+        if (!mStaticInfo.isVideoStabilizationSupported() && useVideoStab) {
+            throw new IllegalArgumentException("Video stabilization is not supported");
+        }
+
         List<Surface> outputSurfaces = new ArrayList<Surface>(2);
         assertTrue("Both preview and recording surfaces should be valid",
                 mPreviewSurface.isValid() && mRecordingSurface.isValid());
@@ -1130,6 +1183,10 @@
         // Make sure camera output frame rate is set to correct value.
         Range<Integer> fpsRange = Range.create(mVideoFrameRate, mVideoFrameRate);
         recordingRequestBuilder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, fpsRange);
+        if (useVideoStab) {
+            recordingRequestBuilder.set(CaptureRequest.CONTROL_VIDEO_STABILIZATION_MODE,
+                    CaptureRequest.CONTROL_VIDEO_STABILIZATION_MODE_ON);
+        }
         recordingRequestBuilder.addTarget(mRecordingSurface);
         recordingRequestBuilder.addTarget(mPreviewSurface);
         mSession.setRepeatingRequest(recordingRequestBuilder.build(), listener, mHandler);
@@ -1142,10 +1199,6 @@
         mRecordingStartTime = SystemClock.elapsedRealtime();
     }
 
-    private void startRecording(boolean useMediaRecorder)  throws Exception {
-        startRecording(useMediaRecorder, null);
-    }
-
     private void stopCameraStreaming() throws Exception {
         if (VERBOSE) {
             Log.v(TAG, "Stopping camera streaming and waiting for idle");
@@ -1252,7 +1305,7 @@
         double expectedDurationMs = 1000.0 / mVideoFrameRate;
         CaptureResult prevResult = resultListener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
         long prevTS = getValueNotNull(prevResult, CaptureResult.SENSOR_TIMESTAMP);
-        while (!resultListener.hasMoreResults()) {
+        while (resultListener.hasMoreResults()) {
             CaptureResult currentResult =
                     resultListener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
             long currentTS = getValueNotNull(currentResult, CaptureResult.SENSOR_TIMESTAMP);
@@ -1330,7 +1383,7 @@
         double expectedDurationMs = 1000.0 / mVideoFrameRate;
         CaptureResult prevResult = resultListener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
         long prevTS = getValueNotNull(prevResult, CaptureResult.SENSOR_TIMESTAMP);
-        while (!resultListener.hasMoreResults()) {
+        while (resultListener.hasMoreResults()) {
             CaptureResult currentResult =
                     resultListener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
             long currentTS = getValueNotNull(currentResult, CaptureResult.SENSOR_TIMESTAMP);
diff --git a/tests/camera/src/android/hardware/camera2/cts/RobustnessTest.java b/tests/camera/src/android/hardware/camera2/cts/RobustnessTest.java
index ddae8eb..e8995ae 100644
--- a/tests/camera/src/android/hardware/camera2/cts/RobustnessTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/RobustnessTest.java
@@ -168,50 +168,86 @@
 
         // Enum values are defined in MaxStreamSizes
         final int[][] LEGACY_COMBINATIONS = {
-            {PRIV, MAXIMUM}, // Simple preview, GPU video processing, or no-preview video recording
-            {JPEG, MAXIMUM}, // No-viewfinder still image capture
-            {YUV,  MAXIMUM}, // In-application video/image processing
-            {PRIV, PREVIEW,  JPEG, MAXIMUM}, // Standard still imaging.
-            {YUV,  PREVIEW,  JPEG, MAXIMUM}, // In-app processing plus still capture.
-            {PRIV, PREVIEW,  PRIV, PREVIEW}, // Standard recording.
-            {PRIV, PREVIEW,  YUV,  PREVIEW}, // Preview plus in-app processing.
-            {PRIV, PREVIEW,  YUV,  PREVIEW,  JPEG, MAXIMUM} // Still capture plus in-app processing.
+            // Simple preview, GPU video processing, or no-preview video recording
+            {PRIV, MAXIMUM},
+            // No-viewfinder still image capture
+            {JPEG, MAXIMUM},
+            // In-application video/image processing
+            {YUV,  MAXIMUM},
+            // Standard still imaging.
+            {PRIV, PREVIEW,  JPEG, MAXIMUM},
+            // In-app processing plus still capture.
+            {YUV,  PREVIEW,  JPEG, MAXIMUM},
+            // Standard recording.
+            {PRIV, PREVIEW,  PRIV, PREVIEW},
+            // Preview plus in-app processing.
+            {PRIV, PREVIEW,  YUV,  PREVIEW},
+            // Still capture plus in-app processing.
+            {PRIV, PREVIEW,  YUV,  PREVIEW,  JPEG, MAXIMUM}
         };
 
         final int[][] LIMITED_COMBINATIONS = {
-            {PRIV, PREVIEW,  PRIV, RECORD }, // High-resolution video recording with preview.
-            {PRIV, PREVIEW,  YUV , RECORD }, // High-resolution in-app video processing with preview.
-            {YUV , PREVIEW,  YUV , RECORD }, // Two-input in-app video processing.
-            {PRIV, PREVIEW,  PRIV, RECORD,   JPEG, RECORD  }, // High-resolution recording with video snapshot.
-            {PRIV, PREVIEW,  YUV,  RECORD,   JPEG, RECORD  }, // High-resolution in-app processing with video snapshot.
-            {YUV , PREVIEW,  YUV,  PREVIEW,  JPEG, MAXIMUM }  // Two-input in-app processing with still capture.
+            // High-resolution video recording with preview.
+            {PRIV, PREVIEW,  PRIV, RECORD },
+            // High-resolution in-app video processing with preview.
+            {PRIV, PREVIEW,  YUV , RECORD },
+            // Two-input in-app video processing.
+            {YUV , PREVIEW,  YUV , RECORD },
+            // High-resolution recording with video snapshot.
+            {PRIV, PREVIEW,  PRIV, RECORD,   JPEG, RECORD  },
+            // High-resolution in-app processing with video snapshot.
+            {PRIV, PREVIEW,  YUV,  RECORD,   JPEG, RECORD  },
+            // Two-input in-app processing with still capture.
+            {YUV , PREVIEW,  YUV,  PREVIEW,  JPEG, MAXIMUM }
         };
 
         final int[][] BURST_COMBINATIONS = {
-            {PRIV, PREVIEW,  PRIV, MAXIMUM }, // Maximum-resolution GPU processing with preview.
-            {PRIV, PREVIEW,  YUV,  MAXIMUM }, // Maximum-resolution in-app processing with preview.
-            {YUV,  PREVIEW,  YUV,  MAXIMUM }, // Maximum-resolution two-input in-app processsing.
+            // Maximum-resolution GPU processing with preview.
+            {PRIV, PREVIEW,  PRIV, MAXIMUM },
+            // Maximum-resolution in-app processing with preview.
+            {PRIV, PREVIEW,  YUV,  MAXIMUM },
+            // Maximum-resolution two-input in-app processsing.
+            {YUV,  PREVIEW,  YUV,  MAXIMUM },
         };
 
         final int[][] FULL_COMBINATIONS = {
-            {PRIV, PREVIEW,  PRIV, PREVIEW,  JPEG, MAXIMUM }, //Video recording with maximum-size video snapshot.
-            {YUV,  VGA,      PRIV, PREVIEW,  YUV,  MAXIMUM }, // Standard video recording plus maximum-resolution in-app processing.
-            {YUV,  VGA,      YUV,  PREVIEW,  YUV,  MAXIMUM } // Preview plus two-input maximum-resolution in-app processing.
+            // Video recording with maximum-size video snapshot.
+            {PRIV, PREVIEW,  PRIV, PREVIEW,  JPEG, MAXIMUM },
+            // Standard video recording plus maximum-resolution in-app processing.
+            {YUV,  VGA,      PRIV, PREVIEW,  YUV,  MAXIMUM },
+            // Preview plus two-input maximum-resolution in-app processing.
+            {YUV,  VGA,      YUV,  PREVIEW,  YUV,  MAXIMUM }
         };
 
         final int[][] RAW_COMBINATIONS = {
-            {RAW,  MAXIMUM }, // No-preview DNG capture.
-            {PRIV, PREVIEW,  RAW,  MAXIMUM }, // Standard DNG capture.
-            {YUV,  PREVIEW,  RAW,  MAXIMUM }, // In-app processing plus DNG capture.
-            {PRIV, PREVIEW,  PRIV, PREVIEW,  RAW, MAXIMUM}, // Video recording with DNG capture.
-            {PRIV, PREVIEW,  YUV,  PREVIEW,  RAW, MAXIMUM}, // Preview with in-app processing and DNG capture.
-            {YUV,  PREVIEW,  YUV,  PREVIEW,  RAW, MAXIMUM}, // Two-input in-app processing plus DNG capture.
-            {PRIV, PREVIEW,  JPEG, MAXIMUM,  RAW, MAXIMUM}, // Still capture with simultaneous JPEG and DNG.
-            {YUV,  PREVIEW,  JPEG, MAXIMUM,  RAW, MAXIMUM}  // In-app processing with simultaneous JPEG and DNG.
+            // No-preview DNG capture.
+            {RAW,  MAXIMUM },
+            // Standard DNG capture.
+            {PRIV, PREVIEW,  RAW,  MAXIMUM },
+            // In-app processing plus DNG capture.
+            {YUV,  PREVIEW,  RAW,  MAXIMUM },
+            // Video recording with DNG capture.
+            {PRIV, PREVIEW,  PRIV, PREVIEW,  RAW, MAXIMUM},
+            // Preview with in-app processing and DNG capture.
+            {PRIV, PREVIEW,  YUV,  PREVIEW,  RAW, MAXIMUM},
+            // Two-input in-app processing plus DNG capture.
+            {YUV,  PREVIEW,  YUV,  PREVIEW,  RAW, MAXIMUM},
+            // Still capture with simultaneous JPEG and DNG.
+            {PRIV, PREVIEW,  JPEG, MAXIMUM,  RAW, MAXIMUM},
+            // In-app processing with simultaneous JPEG and DNG.
+            {YUV,  PREVIEW,  JPEG, MAXIMUM,  RAW, MAXIMUM}
+        };
+
+        final int[][] LEVEL_3_COMBINATIONS = {
+            // In-app viewfinder analysis with dynamic selection of output format
+            {PRIV, PREVIEW, PRIV, VGA, YUV, MAXIMUM, RAW, MAXIMUM},
+            // In-app viewfinder analysis with dynamic selection of output format
+            {PRIV, PREVIEW, PRIV, VGA, JPEG, MAXIMUM, RAW, MAXIMUM}
         };
 
         final int[][][] TABLES =
-            { LEGACY_COMBINATIONS, LIMITED_COMBINATIONS, BURST_COMBINATIONS, FULL_COMBINATIONS, RAW_COMBINATIONS };
+                { LEGACY_COMBINATIONS, LIMITED_COMBINATIONS, BURST_COMBINATIONS, FULL_COMBINATIONS,
+                  RAW_COMBINATIONS, LEVEL_3_COMBINATIONS };
 
         sanityCheckConfigurationTables(TABLES);
 
@@ -257,7 +293,7 @@
                     }
                 }
 
-                if (mStaticInfo.isHardwareLevelFull()) {
+                if (mStaticInfo.isHardwareLevelAtLeastFull()) {
                     for (int[] config : FULL_COMBINATIONS) {
                         testOutputCombination(id, config, maxSizes);
                     }
@@ -269,6 +305,13 @@
                         testOutputCombination(id, config, maxSizes);
                     }
                 }
+
+                if (mStaticInfo.isHardwareLevelAtLeast(
+                        CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_3)) {
+                    for (int[] config: LEVEL_3_COMBINATIONS) {
+                        testOutputCombination(id, config, maxSizes);
+                    }
+                }
             }
 
             closeDevice(id);
@@ -287,45 +330,55 @@
          *    2. Reprocess capture requests targeting YUV and JPEG outputs are successful.
          */
         final int[][] LIMITED_COMBINATIONS = {
-            // Input        Outputs
-            {PRIV, MAXIMUM, JPEG, MAXIMUM},
-            {YUV , MAXIMUM, JPEG, MAXIMUM},
-            {PRIV, MAXIMUM, PRIV, PREVIEW, JPEG, MAXIMUM},
-            {YUV , MAXIMUM, PRIV, PREVIEW, JPEG, MAXIMUM},
-            {PRIV, MAXIMUM, YUV , PREVIEW, JPEG, MAXIMUM},
-            {YUV , MAXIMUM, YUV , PREVIEW, JPEG, MAXIMUM},
-            {PRIV, MAXIMUM, YUV , PREVIEW, YUV , PREVIEW, JPEG, MAXIMUM},
-            {YUV,  MAXIMUM, YUV , PREVIEW, YUV , PREVIEW, JPEG, MAXIMUM},
+            // Input           Outputs
+            {PRIV, MAXIMUM,    JPEG, MAXIMUM},
+            {YUV , MAXIMUM,    JPEG, MAXIMUM},
+            {PRIV, MAXIMUM,    PRIV, PREVIEW, JPEG, MAXIMUM},
+            {YUV , MAXIMUM,    PRIV, PREVIEW, JPEG, MAXIMUM},
+            {PRIV, MAXIMUM,    YUV , PREVIEW, JPEG, MAXIMUM},
+            {YUV , MAXIMUM,    YUV , PREVIEW, JPEG, MAXIMUM},
+            {PRIV, MAXIMUM,    YUV , PREVIEW, YUV , PREVIEW, JPEG, MAXIMUM},
+            {YUV,  MAXIMUM,    YUV , PREVIEW, YUV , PREVIEW, JPEG, MAXIMUM},
         };
 
         final int[][] FULL_COMBINATIONS = {
-            // Input        Outputs
-            {YUV , MAXIMUM, PRIV, PREVIEW},
-            {YUV , MAXIMUM, YUV , PREVIEW},
-            {PRIV, MAXIMUM, PRIV, PREVIEW, YUV , RECORD},
-            {YUV , MAXIMUM, PRIV, PREVIEW, YUV , RECORD},
-            {PRIV, MAXIMUM, PRIV, PREVIEW, YUV , MAXIMUM},
-            {PRIV, MAXIMUM, YUV , PREVIEW, YUV , MAXIMUM},
-            {PRIV, MAXIMUM, PRIV, PREVIEW, YUV , PREVIEW, JPEG, MAXIMUM},
-            {YUV , MAXIMUM, PRIV, PREVIEW, YUV , PREVIEW, JPEG, MAXIMUM},
+            // Input           Outputs
+            {YUV , MAXIMUM,    PRIV, PREVIEW},
+            {YUV , MAXIMUM,    YUV , PREVIEW},
+            {PRIV, MAXIMUM,    PRIV, PREVIEW, YUV , RECORD},
+            {YUV , MAXIMUM,    PRIV, PREVIEW, YUV , RECORD},
+            {PRIV, MAXIMUM,    PRIV, PREVIEW, YUV , MAXIMUM},
+            {PRIV, MAXIMUM,    YUV , PREVIEW, YUV , MAXIMUM},
+            {PRIV, MAXIMUM,    PRIV, PREVIEW, YUV , PREVIEW, JPEG, MAXIMUM},
+            {YUV , MAXIMUM,    PRIV, PREVIEW, YUV , PREVIEW, JPEG, MAXIMUM},
         };
 
         final int[][] RAW_COMBINATIONS = {
-            // Input        Outputs
-            {PRIV, MAXIMUM, YUV , PREVIEW, RAW , MAXIMUM},
-            {YUV , MAXIMUM, YUV , PREVIEW, RAW , MAXIMUM},
-            {PRIV, MAXIMUM, PRIV, PREVIEW, YUV , PREVIEW, RAW , MAXIMUM},
-            {YUV , MAXIMUM, PRIV, PREVIEW, YUV , PREVIEW, RAW , MAXIMUM},
-            {PRIV, MAXIMUM, YUV , PREVIEW, YUV , PREVIEW, RAW , MAXIMUM},
-            {YUV , MAXIMUM, YUV , PREVIEW, YUV , PREVIEW, RAW , MAXIMUM},
-            {PRIV, MAXIMUM, PRIV, PREVIEW, JPEG, MAXIMUM, RAW , MAXIMUM},
-            {YUV , MAXIMUM, PRIV, PREVIEW, JPEG, MAXIMUM, RAW , MAXIMUM},
-            {PRIV, MAXIMUM, YUV , PREVIEW, JPEG, MAXIMUM, RAW , MAXIMUM},
-            {YUV , MAXIMUM, YUV , PREVIEW, JPEG, MAXIMUM, RAW , MAXIMUM},
+            // Input           Outputs
+            {PRIV, MAXIMUM,    YUV , PREVIEW, RAW , MAXIMUM},
+            {YUV , MAXIMUM,    YUV , PREVIEW, RAW , MAXIMUM},
+            {PRIV, MAXIMUM,    PRIV, PREVIEW, YUV , PREVIEW, RAW , MAXIMUM},
+            {YUV , MAXIMUM,    PRIV, PREVIEW, YUV , PREVIEW, RAW , MAXIMUM},
+            {PRIV, MAXIMUM,    YUV , PREVIEW, YUV , PREVIEW, RAW , MAXIMUM},
+            {YUV , MAXIMUM,    YUV , PREVIEW, YUV , PREVIEW, RAW , MAXIMUM},
+            {PRIV, MAXIMUM,    PRIV, PREVIEW, JPEG, MAXIMUM, RAW , MAXIMUM},
+            {YUV , MAXIMUM,    PRIV, PREVIEW, JPEG, MAXIMUM, RAW , MAXIMUM},
+            {PRIV, MAXIMUM,    YUV , PREVIEW, JPEG, MAXIMUM, RAW , MAXIMUM},
+            {YUV , MAXIMUM,    YUV , PREVIEW, JPEG, MAXIMUM, RAW , MAXIMUM},
+        };
+
+        final int[][] LEVEL_3_COMBINATIONS = {
+            // Input          Outputs
+            // In-app viewfinder analysis with YUV->YUV ZSL and RAW
+            {YUV , MAXIMUM,   PRIV, PREVIEW, PRIV, VGA, RAW, MAXIMUM},
+            // In-app viewfinder analysis with PRIV->JPEG ZSL and RAW
+            {PRIV, MAXIMUM,   PRIV, PREVIEW, PRIV, VGA, RAW, MAXIMUM, JPEG, MAXIMUM},
+            // In-app viewfinder analysis with YUV->JPEG ZSL and RAW
+            {YUV , MAXIMUM,   PRIV, PREVIEW, PRIV, VGA, RAW, MAXIMUM, JPEG, MAXIMUM},
         };
 
         final int[][][] TABLES =
-                { LIMITED_COMBINATIONS, FULL_COMBINATIONS, RAW_COMBINATIONS };
+                { LIMITED_COMBINATIONS, FULL_COMBINATIONS, RAW_COMBINATIONS, LEVEL_3_COMBINATIONS };
 
         sanityCheckConfigurationTables(TABLES);
 
@@ -347,7 +400,7 @@
                 }
 
                 // Check FULL devices
-                if (staticInfo.isHardwareLevelFull()) {
+                if (staticInfo.isHardwareLevelAtLeastFull()) {
                     for (int[] config : FULL_COMBINATIONS) {
                         testReprocessStreamCombination(id, config, maxSizes, staticInfo);
                     }
@@ -360,6 +413,13 @@
                         testReprocessStreamCombination(id, config, maxSizes, staticInfo);
                     }
                 }
+
+                if (mStaticInfo.isHardwareLevelAtLeast(
+                        CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_3)) {
+                    for (int[] config: LEVEL_3_COMBINATIONS) {
+                        testReprocessStreamCombination(id, config, maxSizes, staticInfo);
+                    }
+                }
             } finally {
                 closeDevice(id);
             }
@@ -848,13 +908,69 @@
         }
     }
 
-    private CaptureRequest.Builder prepareTriggerTestSession(
-            SurfaceTexture preview, int aeMode, int afMode) throws Exception {
-        Log.i(TAG, String.format("Testing AE mode %s, AF mode %s",
-                        StaticMetadata.AE_MODE_NAMES[aeMode],
-                        StaticMetadata.AF_MODE_NAMES[afMode]));
+    public void testAbandonRepeatingRequestSurface() throws Exception {
+        for (String id : mCameraIds) {
+            Log.i(TAG, String.format(
+                    "Testing Camera %s for abandoning surface of a repeating request", id));
 
+            openDevice(id);
+            try {
+                SurfaceTexture preview = new SurfaceTexture(/*random int*/ 1);
+                Surface previewSurface = new Surface(preview);
 
+                CaptureRequest.Builder previewRequest = preparePreviewTestSession(preview);
+                SimpleCaptureCallback captureListener = new CameraTestUtils.SimpleCaptureCallback();
+
+                int sequenceId = mCameraSession.setRepeatingRequest(previewRequest.build(),
+                        captureListener, mHandler);
+
+                for (int i = 0; i < PREVIEW_WARMUP_FRAMES; i++) {
+                    captureListener.getTotalCaptureResult(CAPTURE_TIMEOUT);
+                }
+
+                // Abandon preview surface.
+                preview.release();
+
+                // Check onCaptureSequenceCompleted is received.
+                long sequenceLastFrameNumber = captureListener.getCaptureSequenceLastFrameNumber(
+                        sequenceId, CAPTURE_TIMEOUT);
+
+                mCameraSession.stopRepeating();
+
+                // Find the last frame number received in results and failures.
+                long lastFrameNumber = -1;
+                while (captureListener.hasMoreResults()) {
+                    TotalCaptureResult result = captureListener.getTotalCaptureResult(
+                            CAPTURE_TIMEOUT);
+                    if (lastFrameNumber < result.getFrameNumber()) {
+                        lastFrameNumber = result.getFrameNumber();
+                    }
+                }
+
+                while (captureListener.hasMoreFailures()) {
+                    ArrayList<CaptureFailure> failures = captureListener.getCaptureFailures(
+                            /*maxNumFailures*/ 1);
+                    for (CaptureFailure failure : failures) {
+                        if (lastFrameNumber < failure.getFrameNumber()) {
+                            lastFrameNumber = failure.getFrameNumber();
+                        }
+                    }
+                }
+
+                // Verify the last frame number received from capture sequence completed matches the
+                // the last frame number of the results and failures.
+                assertEquals(String.format("Last frame number from onCaptureSequenceCompleted " +
+                        "(%d) doesn't match the last frame number received from " +
+                        "results/failures (%d)", sequenceLastFrameNumber, lastFrameNumber),
+                        sequenceLastFrameNumber, lastFrameNumber);
+            } finally {
+                closeDevice(id);
+            }
+        }
+    }
+
+    private CaptureRequest.Builder preparePreviewTestSession(SurfaceTexture preview)
+            throws Exception {
         Surface previewSurface = new Surface(preview);
 
         preview.setDefaultBufferSize(640, 480);
@@ -869,6 +985,16 @@
 
         previewRequest.addTarget(previewSurface);
 
+        return previewRequest;
+    }
+
+    private CaptureRequest.Builder prepareTriggerTestSession(
+            SurfaceTexture preview, int aeMode, int afMode) throws Exception {
+        Log.i(TAG, String.format("Testing AE mode %s, AF mode %s",
+                        StaticMetadata.AE_MODE_NAMES[aeMode],
+                        StaticMetadata.AF_MODE_NAMES[afMode]));
+
+        CaptureRequest.Builder previewRequest = preparePreviewTestSession(preview);
         previewRequest.set(CaptureRequest.CONTROL_AE_MODE, aeMode);
         previewRequest.set(CaptureRequest.CONTROL_AF_MODE, afMode);
 
diff --git a/tests/camera/src/android/hardware/camera2/cts/StaticMetadataTest.java b/tests/camera/src/android/hardware/camera2/cts/StaticMetadataTest.java
index 5e029edb..8ee0a41 100644
--- a/tests/camera/src/android/hardware/camera2/cts/StaticMetadataTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/StaticMetadataTest.java
@@ -78,7 +78,15 @@
                     availableCaps.contains(REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE) ||
                     availableCaps.contains(REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT) );
 
-            if (mStaticInfo.isHardwareLevelFull()) {
+            if (mStaticInfo.isHardwareLevelAtLeast(
+                    CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_3)) {
+                mCollector.expectTrue("Level 3 device must contain YUV_REPROCESSING capability",
+                        availableCaps.contains(REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING));
+                mCollector.expectTrue("Level 3 device must contain RAW capability",
+                        availableCaps.contains(REQUEST_AVAILABLE_CAPABILITIES_RAW));
+            }
+
+            if (mStaticInfo.isHardwareLevelAtLeastFull()) {
                 // Capability advertisement must be right.
                 mCollector.expectTrue("Full device must contain MANUAL_SENSOR capability",
                         availableCaps.contains(REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR));
@@ -142,7 +150,7 @@
             mCollector.expectTrue("max number of processed (stalling) output streams must be >= 1",
                     maxNumStreamsProcStall >= 1);
 
-            if (mStaticInfo.isHardwareLevelFull()) {
+            if (mStaticInfo.isHardwareLevelAtLeastFull()) {
                 mCollector.expectTrue("max number of processed (non-stalling) output streams" +
                         "must be >= 3 for FULL device",
                         maxNumStreamsProc >= 3);
@@ -338,7 +346,7 @@
                 Boolean contrastCurveModeSupported = false;
                 Boolean gammaAndPresetModeSupported = false;
                 Boolean offColorAberrationModeSupported = false;
-                if (mStaticInfo.isHardwareLevelLimitedOrBetter() && mStaticInfo.isColorOutputSupported()) {
+                if (mStaticInfo.isHardwareLevelAtLeastLimited() && mStaticInfo.isColorOutputSupported()) {
                     int[] tonemapModes = mStaticInfo.getAvailableToneMapModesChecked();
                     List<Integer> modeList = (tonemapModes.length == 0) ?
                             new ArrayList<Integer>() :
diff --git a/tests/camera/src/android/hardware/camera2/cts/StillCaptureTest.java b/tests/camera/src/android/hardware/camera2/cts/StillCaptureTest.java
index e7978c6..a9b4ad2 100644
--- a/tests/camera/src/android/hardware/camera2/cts/StillCaptureTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/StillCaptureTest.java
@@ -19,6 +19,8 @@
 import static android.hardware.camera2.cts.CameraTestUtils.*;
 import static android.hardware.camera2.cts.helpers.AssertHelpers.assertArrayContains;
 
+import android.graphics.Bitmap;
+import android.graphics.Bitmap.Config;
 import android.graphics.ImageFormat;
 import android.graphics.Point;
 import android.graphics.Rect;
@@ -64,6 +66,8 @@
     private static final int NUM_FRAMES_WAITED = 30;
     // 5 percent error margin for resulting metering regions
     private static final float METERING_REGION_ERROR_PERCENT_DELTA = 0.05f;
+    // Android CDD (5.0 and newer) required number of simultenous bitmap allocations for camera
+    private static final int MAX_ALLOCATED_BITMAPS = 3;
 
     @Override
     protected void setUp() throws Exception {
@@ -372,7 +376,7 @@
                     continue;
                 }
                 takePictureTestByCamera(/*aeRegions*/null, /*awbRegions*/null, /*afRegions*/null,
-                        /*addAeTriggerCancel*/true);
+                        /*addAeTriggerCancel*/true, /*allocateBitmap*/false);
             } finally {
                 closeDevice();
                 closeImageReader();
@@ -381,6 +385,33 @@
     }
 
     /**
+     * Test allocate some bitmaps while taking picture.
+     * <p>
+     * Per android CDD (5.0 and newer), android devices should support allocation of at least 3
+     * bitmaps equal to the size of the images produced by the largest resolution camera sensor on
+     * the devices.
+     * </p>
+     */
+    public void testAllocateBitmap() throws Exception {
+        for (String id : mCameraIds) {
+            try {
+                Log.i(TAG, "Testing bitmap allocations for Camera " + id);
+                openDevice(id);
+                if (!mStaticInfo.isColorOutputSupported()) {
+                    Log.i(TAG, "Camera " + id + " does not support color outputs, skipping");
+                    continue;
+                }
+                takePictureTestByCamera(/*aeRegions*/null, /*awbRegions*/null, /*afRegions*/null,
+                        /*addAeTriggerCancel*/false, /*allocateBitmap*/true);
+            } finally {
+                closeDevice();
+                closeImageReader();
+            }
+        }
+
+    }
+
+    /**
      * Start preview,take a picture and test preview is still running after snapshot
      */
     private void previewPersistenceTestByCamera() throws Exception {
@@ -438,7 +469,7 @@
             MeteringRectangle[] aeRegions, MeteringRectangle[] awbRegions,
             MeteringRectangle[] afRegions) throws Exception {
         takePictureTestByCamera(aeRegions, awbRegions, afRegions,
-                /*addAeTriggerCancel*/false);
+                /*addAeTriggerCancel*/false, /*allocateBitmap*/false);
     }
 
     /**
@@ -456,10 +487,12 @@
      * @param awbRegions AWB regions for this capture
      * @param afRegions AF regions for this capture
      * @param addAeTriggerCancel If a AE precapture trigger cancel is sent after the trigger.
+     * @param allocateBitmap If a set of bitmaps are allocated during the test for memory test.
      */
     private void takePictureTestByCamera(
             MeteringRectangle[] aeRegions, MeteringRectangle[] awbRegions,
-            MeteringRectangle[] afRegions, boolean addAeTriggerCancel) throws Exception {
+            MeteringRectangle[] afRegions, boolean addAeTriggerCancel, boolean allocateBitmap)
+                    throws Exception {
 
         boolean hasFocuser = mStaticInfo.hasFocuser();
 
@@ -527,7 +560,7 @@
             stillRequest.set(CaptureRequest.CONTROL_AWB_REGIONS, awbRegions);
         }
         mSession.setRepeatingRequest(previewRequest.build(), resultListener, mHandler);
-        if (mStaticInfo.isHardwareLevelLimitedOrBetter()) {
+        if (mStaticInfo.isHardwareLevelAtLeastLimited()) {
             waitForResultValue(resultListener, CaptureResult.CONTROL_AWB_STATE,
                     CaptureResult.CONTROL_AWB_STATE_CONVERGED, NUM_RESULTS_WAIT_TIMEOUT);
         } else {
@@ -628,6 +661,16 @@
         // validate image
         Image image = imageListener.getImage(CAPTURE_IMAGE_TIMEOUT_MS);
         validateJpegCapture(image, maxStillSz);
+        // Test if the system can allocate 3 bitmap successfully, per android CDD camera memory
+        // requirements added by CDD 5.0
+        if (allocateBitmap) {
+            Bitmap bm[] = new Bitmap[MAX_ALLOCATED_BITMAPS];
+            for (int i = 0; i < MAX_ALLOCATED_BITMAPS; i++) {
+                bm[i] = Bitmap.createBitmap(
+                        maxStillSz.getWidth(), maxStillSz.getHeight(), Config.ARGB_8888);
+                assertNotNull("Created bitmap #" + i + " shouldn't be null", bm[i]);
+            }
+        }
 
         // Free image resources
         image.close();
diff --git a/tests/camera/src/android/hardware/camera2/cts/SurfaceViewPreviewTest.java b/tests/camera/src/android/hardware/camera2/cts/SurfaceViewPreviewTest.java
index 06daa51..a367d37 100644
--- a/tests/camera/src/android/hardware/camera2/cts/SurfaceViewPreviewTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/SurfaceViewPreviewTest.java
@@ -20,6 +20,10 @@
 
 import android.graphics.ImageFormat;
 import android.view.Surface;
+
+import com.android.ex.camera2.blocking.BlockingSessionCallback;
+
+import android.graphics.SurfaceTexture;
 import android.hardware.camera2.CameraCaptureSession;
 import android.hardware.camera2.CameraCaptureSession.CaptureCallback;
 import android.hardware.camera2.CameraDevice;
@@ -30,6 +34,7 @@
 import android.util.Size;
 import android.hardware.camera2.cts.CameraTestUtils.SimpleCaptureCallback;
 import android.hardware.camera2.cts.testcases.Camera2SurfaceViewTestCase;
+import android.hardware.camera2.params.OutputConfiguration;
 import android.util.Log;
 import android.util.Pair;
 import android.util.Range;
@@ -53,6 +58,7 @@
     private static final int NUM_FRAMES_VERIFIED = 30;
     private static final int NUM_TEST_PATTERN_FRAMES_VERIFIED = 60;
     private static final float FRAME_DURATION_ERROR_MARGIN = 0.005f; // 0.5 percent error margin.
+    private static final int PREPARE_TIMEOUT_MS = 10000; // 10 s
 
     @Override
     protected void setUp() throws Exception {
@@ -133,6 +139,31 @@
     }
 
     /**
+     * Test surface set streaming use cases.
+     *
+     * <p>
+     * The test sets output configuration with increasing surface set IDs for preview and YUV
+     * streams. The max supported preview size is selected for preview stream, and the max
+     * supported YUV size (depending on hw supported level) is selected for YUV stream. This test
+     * also exercises the prepare API.
+     * </p>
+     */
+    public void testSurfaceSet() throws Exception {
+        for (String id : mCameraIds) {
+            try {
+                openDevice(id);
+                if (!mStaticInfo.isColorOutputSupported()) {
+                    Log.i(TAG, "Camera " + id + " does not support color outputs, skipping");
+                    continue;
+                }
+                surfaceSetTestByCamera(id);
+            } finally {
+                closeDevice();
+            }
+        }
+    }
+
+    /**
      * Test to verify the {@link CameraCaptureSession#prepare} method works correctly, and has the
      * expected effects on performance.
      *
@@ -163,7 +194,6 @@
         final int UNKNOWN_LATENCY_RESULT_WAIT = 5;
         final int MAX_RESULTS_TO_WAIT = 10;
         final int FRAMES_FOR_AVERAGING = 100;
-        final int PREPARE_TIMEOUT_MS = 10000; // 10 s
         final float PREPARE_FRAME_RATE_BOUNDS = 0.05f; // fraction allowed difference
         final float PREPARE_PEAK_RATE_BOUNDS = 0.5f; // fraction allowed difference
 
@@ -206,7 +236,7 @@
             // Lock AE if possible to improve stability
             previewRequest.set(CaptureRequest.CONTROL_AE_LOCK, true);
             mSession.setRepeatingRequest(previewRequest.build(), resultListener, mHandler);
-            if (mStaticInfo.isHardwareLevelLimitedOrBetter()) {
+            if (mStaticInfo.isHardwareLevelAtLeastLimited()) {
                 // Legacy mode doesn't output AE state
                 waitForResultValue(resultListener, CaptureResult.CONTROL_AE_STATE,
                         CaptureResult.CONTROL_AE_STATE_LOCKED, MAX_RESULTS_TO_WAIT);
@@ -241,7 +271,7 @@
                             whilePreparingFrameDurationStats.first / 1e6,
                             whilePreparingFrameDurationStats.second / 1e6));
 
-            if (mStaticInfo.isHardwareLevelLimitedOrBetter()) {
+            if (mStaticInfo.isHardwareLevelAtLeastLimited()) {
                 mCollector.expectTrue(
                     String.format("Camera %s: Preview peak frame interval affected by prepare " +
                             "call: preview avg frame duration: %f ms, peak during prepare: %f ms",
@@ -279,7 +309,7 @@
                         preparedFrameDurationStats.first / 1e6,
                         preparedFrameDurationStats.second / 1e6));
 
-        if (mStaticInfo.isHardwareLevelLimitedOrBetter()) {
+        if (mStaticInfo.isHardwareLevelAtLeastLimited()) {
             mCollector.expectTrue(
                 String.format("Camera %s: Preview peak frame interval affected by use of new " +
                         " stream: preview avg frame duration: %f ms, peak with new stream: %f ms",
@@ -298,6 +328,97 @@
     }
 
     /**
+     * Test to verify correct behavior with the same Surface object being used repeatedly with
+     * different native internals, and multiple Surfaces pointing to the same actual consumer object
+     */
+    public void testSurfaceEquality() throws Exception {
+        for (int i = 0; i < mCameraIds.length; i++) {
+            try {
+                openDevice(mCameraIds[i]);
+                if (!mStaticInfo.isColorOutputSupported()) {
+                    Log.i(TAG, "Camera " + mCameraIds[i] +
+                            " does not support color outputs, skipping");
+                    continue;
+                }
+                surfaceEqualityTestByCamera(mCameraIds[i]);
+            }
+            finally {
+                closeDevice();
+            }
+        }
+    }
+
+    private void surfaceEqualityTestByCamera(String cameraId) throws Exception {
+        final int SOME_FRAMES = 10;
+
+        Size maxPreviewSize = mOrderedPreviewSizes.get(0);
+
+        SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
+
+        // Create a SurfaceTexture for a second output
+        SurfaceTexture sharedOutputTexture = new SurfaceTexture(/*random texture ID*/ 5);
+        sharedOutputTexture.setDefaultBufferSize(maxPreviewSize.getWidth(),
+                maxPreviewSize.getHeight());
+        Surface sharedOutputSurface1 = new Surface(sharedOutputTexture);
+
+        updatePreviewSurface(maxPreviewSize);
+
+        List<Surface> outputSurfaces = new ArrayList<Surface>();
+        outputSurfaces.add(mPreviewSurface);
+        outputSurfaces.add(sharedOutputSurface1);
+
+        BlockingSessionCallback sessionListener =
+                new BlockingSessionCallback();
+
+        mSession = configureCameraSession(mCamera, outputSurfaces, sessionListener, mHandler);
+        sessionListener.getStateWaiter().waitForState(BlockingSessionCallback.SESSION_READY,
+                SESSION_CONFIGURE_TIMEOUT_MS);
+
+        CaptureRequest.Builder previewRequest =
+                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+        previewRequest.addTarget(mPreviewSurface);
+        previewRequest.addTarget(sharedOutputSurface1);
+
+        mSession.setRepeatingRequest(previewRequest.build(), resultListener, mHandler);
+
+        // Wait to get some frames out
+        waitForNumResults(resultListener, SOME_FRAMES);
+
+        // Drain
+        mSession.abortCaptures();
+        sessionListener.getStateWaiter().waitForState(BlockingSessionCallback.SESSION_READY,
+                SESSION_CONFIGURE_TIMEOUT_MS);
+
+        // Hide / unhide the SurfaceView to get a new target Surface
+        recreatePreviewSurface();
+
+        // And resize it again
+        updatePreviewSurface(maxPreviewSize);
+
+        // Create a second surface that targets the shared SurfaceTexture
+        Surface sharedOutputSurface2 = new Surface(sharedOutputTexture);
+
+        // Use the new Surfaces for a new session
+        outputSurfaces.clear();
+        outputSurfaces.add(mPreviewSurface);
+        outputSurfaces.add(sharedOutputSurface2);
+
+        sessionListener = new BlockingSessionCallback();
+
+        mSession = configureCameraSession(mCamera, outputSurfaces, sessionListener, mHandler);
+
+        previewRequest =
+                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+        previewRequest.addTarget(mPreviewSurface);
+        previewRequest.addTarget(sharedOutputSurface2);
+
+        mSession.setRepeatingRequest(previewRequest.build(), resultListener, mHandler);
+
+        // Wait to get some frames out
+        waitForNumResults(resultListener, SOME_FRAMES);
+    }
+
+    /**
      * Measure the inter-frame interval based on SENSOR_TIMESTAMP for frameCount frames from the
      * provided capture listener.  If prevTimestamp is positive, it is used for the first interval
      * calculation; otherwise, the first result is used to establish the starting time.
@@ -330,7 +451,6 @@
      * validated.
      */
     private void previewFpsRangeTestByCamera() throws Exception {
-        final int FPS_RANGE_SIZE = 2;
         Size maxPreviewSz = mOrderedPreviewSizes.get(0);
         Range<Integer>[] fpsRanges = mStaticInfo.getAeAvailableTargetFpsRangesChecked();
         boolean antiBandingOffIsSupported = mStaticInfo.isAntiBandingOffModeSupported();
@@ -450,6 +570,78 @@
         stopPreview();
     }
 
+    private void surfaceSetTestByCamera(String cameraId) throws Exception {
+        final int MAX_SURFACE_GROUP_ID = 10;
+        Size maxPreviewSz = mOrderedPreviewSizes.get(0);
+        Size yuvSizeBound = maxPreviewSz; // Default case: legacy device
+        if (mStaticInfo.isHardwareLevelLimited()) {
+            yuvSizeBound = mOrderedVideoSizes.get(0);
+        } else if (mStaticInfo.isHardwareLevelAtLeastFull()) {
+            yuvSizeBound = null;
+        }
+        Size maxYuvSize = getSupportedPreviewSizes(cameraId, mCameraManager, yuvSizeBound).get(0);
+
+        CaptureRequest.Builder requestBuilder =
+                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+        ImageDropperListener imageListener = new ImageDropperListener();
+
+        updatePreviewSurface(maxPreviewSz);
+        createImageReader(maxYuvSize, ImageFormat.YUV_420_888, MAX_READER_IMAGES, imageListener);
+        List<OutputConfiguration> outputConfigs = new ArrayList<OutputConfiguration>();
+        OutputConfiguration previewConfig = new OutputConfiguration(mPreviewSurface);
+        OutputConfiguration yuvConfig = new OutputConfiguration(mReaderSurface);
+        assertEquals(OutputConfiguration.SURFACE_GROUP_ID_NONE, previewConfig.getSurfaceGroupId());
+        assertEquals(OutputConfiguration.SURFACE_GROUP_ID_NONE, yuvConfig.getSurfaceGroupId());
+        assertEquals(mPreviewSurface, previewConfig.getSurface());
+        assertEquals(mReaderSurface, yuvConfig.getSurface());
+        outputConfigs.add(previewConfig);
+        outputConfigs.add(yuvConfig);
+        requestBuilder.addTarget(mPreviewSurface);
+        requestBuilder.addTarget(mReaderSurface);
+
+        // Test different stream set ID.
+        for (int surfaceGroupId = OutputConfiguration.SURFACE_GROUP_ID_NONE;
+                surfaceGroupId < MAX_SURFACE_GROUP_ID; surfaceGroupId++) {
+            if (VERBOSE) {
+                Log.v(TAG, "test preview with surface group id: ");
+            }
+
+            previewConfig = new OutputConfiguration(surfaceGroupId, mPreviewSurface);
+            yuvConfig = new OutputConfiguration(surfaceGroupId, mReaderSurface);
+            outputConfigs.clear();
+            outputConfigs.add(previewConfig);
+            outputConfigs.add(yuvConfig);
+
+            for (OutputConfiguration config : outputConfigs) {
+                assertEquals(surfaceGroupId, config.getSurfaceGroupId());
+            }
+
+            CameraCaptureSession.StateCallback mockSessionListener =
+                    mock(CameraCaptureSession.StateCallback.class);
+
+            mSession = configureCameraSessionWithConfig(mCamera, outputConfigs,
+                    mockSessionListener, mHandler);
+
+
+            mSession.prepare(mPreviewSurface);
+            verify(mockSessionListener,
+                    timeout(PREPARE_TIMEOUT_MS).times(1)).
+                    onSurfacePrepared(eq(mSession), eq(mPreviewSurface));
+
+            mSession.prepare(mReaderSurface);
+            verify(mockSessionListener,
+                    timeout(PREPARE_TIMEOUT_MS).times(1)).
+                    onSurfacePrepared(eq(mSession), eq(mReaderSurface));
+
+            CaptureRequest request = requestBuilder.build();
+            CaptureCallback mockCaptureCallback =
+                    mock(CameraCaptureSession.CaptureCallback.class);
+            mSession.setRepeatingRequest(request, mockCaptureCallback, mHandler);
+            verifyCaptureResults(mSession, mockCaptureCallback, NUM_FRAMES_VERIFIED,
+                    NUM_FRAMES_VERIFIED * FRAME_TIMEOUT_MS);
+        }
+    }
+
     private class IsCaptureResultValid extends ArgumentMatcher<TotalCaptureResult> {
         @Override
         public boolean matches(Object obj) {
diff --git a/tests/camera/src/android/hardware/camera2/cts/helpers/StaticMetadata.java b/tests/camera/src/android/hardware/camera2/cts/helpers/StaticMetadata.java
index e892e42..5736ebd 100644
--- a/tests/camera/src/android/hardware/camera2/cts/helpers/StaticMetadata.java
+++ b/tests/camera/src/android/hardware/camera2/cts/helpers/StaticMetadata.java
@@ -191,15 +191,28 @@
 
     /**
      * Whether or not the hardware level reported by android.info.supportedHardwareLevel
-     * is {@value CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_FULL}.
+     * is at least {@value CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_FULL}.
      *
      * <p>If the camera device is not reporting the hardwareLevel, this
      * will cause the test to fail.</p>
      *
      * @return {@code true} if the device is {@code FULL}, {@code false} otherwise.
      */
-    public boolean isHardwareLevelFull() {
-        return getHardwareLevelChecked() == CameraMetadata.INFO_SUPPORTED_HARDWARE_LEVEL_FULL;
+    public boolean isHardwareLevelAtLeastFull() {
+        return isHardwareLevelAtLeast(CameraMetadata.INFO_SUPPORTED_HARDWARE_LEVEL_FULL);
+    }
+
+    /**
+     * Whether or not the hardware level reported by android.info.supportedHardwareLevel is
+     * at least the desired one (but could be higher)
+     */
+    public boolean isHardwareLevelAtLeast(int level) {
+        int deviceLevel = getHardwareLevelChecked();
+        if (deviceLevel == CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY) {
+            return level == deviceLevel;
+        }
+        // deviceLevel is not LEGACY, can use numerical sort
+        return level <= deviceLevel;
     }
 
     /**
@@ -279,18 +292,8 @@
      *          {@code true} if the device is {@code LIMITED} or {@code FULL},
      *          {@code false} otherwise (i.e. LEGACY).
      */
-    public boolean isHardwareLevelLimitedOrBetter() {
-        Integer hwLevel = getValueFromKeyNonNull(
-                CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);
-
-        if (hwLevel == null) {
-            return false;
-        }
-
-        // Normal. Device could be limited.
-        int hwLevelInt = hwLevel;
-        return hwLevelInt == CameraMetadata.INFO_SUPPORTED_HARDWARE_LEVEL_FULL ||
-                hwLevelInt == CameraMetadata.INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED;
+    public boolean isHardwareLevelAtLeastLimited() {
+        return isHardwareLevelAtLeast(CameraMetadata.INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED);
     }
 
     /**
@@ -391,7 +394,7 @@
          * android.lens.info.minimumFocusDistance - required for FULL and MANUAL_SENSOR-capable
          *   devices; optional for all other devices.
          */
-        if (isHardwareLevelFull() || isCapabilitySupported(
+        if (isHardwareLevelAtLeastFull() || isCapabilitySupported(
                 CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR)) {
             minFocusDistance = getValueFromKeyNonNull(key);
         } else {
@@ -625,12 +628,12 @@
         }
 
         List<Integer> modeList = Arrays.asList(CameraTestUtils.toObject(modes));
-        if (isHardwareLevelFull()) {
+        if (isHardwareLevelAtLeastFull()) {
             checkTrueForKey(key, "Full-capability camera devices must support FAST mode",
                     modeList.contains(CameraMetadata.HOT_PIXEL_MODE_FAST));
         }
 
-        if (isHardwareLevelLimitedOrBetter()) {
+        if (isHardwareLevelAtLeastLimited()) {
             // FAST and HIGH_QUALITY mode must be both present or both not present
             List<Integer> coupledModes = Arrays.asList(new Integer[] {
                     CameraMetadata.HOT_PIXEL_MODE_FAST,
@@ -723,7 +726,7 @@
         // Qualification check for MANUAL_POSTPROCESSING capability is in
         // StaticMetadataTest#testCapabilities
 
-        if (isHardwareLevelLimitedOrBetter()) {
+        if (isHardwareLevelAtLeastLimited()) {
             // FAST and HIGH_QUALITY mode must be both present or both not present
             List<Integer> coupledModes = Arrays.asList(new Integer[] {
                     CameraMetadata.TONEMAP_MODE_FAST,
@@ -887,7 +890,7 @@
         Key<Integer> key = CameraCharacteristics.SENSOR_MAX_ANALOG_SENSITIVITY;
         Integer maxAnalogsensitivity = mCharacteristics.get(key);
         if (maxAnalogsensitivity == null) {
-            if (isHardwareLevelFull()) {
+            if (isHardwareLevelAtLeastFull()) {
                 Assert.fail("Full device should report max analog sensitivity");
             }
             return 0;
@@ -1170,7 +1173,7 @@
 
         // FULL mode camera devices always support OFF mode.
         boolean condition =
-                !isHardwareLevelFull() || modeList.contains(CameraMetadata.CONTROL_AE_MODE_OFF);
+                !isHardwareLevelAtLeastFull() || modeList.contains(CameraMetadata.CONTROL_AE_MODE_OFF);
         checkTrueForKey(modesKey, "Full capability device must have OFF mode", condition);
 
         // Boundary check.
@@ -1201,7 +1204,7 @@
         List<Integer> modesList = Arrays.asList(CameraTestUtils.toObject(awbModes));
         checkTrueForKey(key, " All camera devices must support AUTO mode",
                 modesList.contains(CameraMetadata.CONTROL_AWB_MODE_AUTO));
-        if (isHardwareLevelFull()) {
+        if (isHardwareLevelAtLeastFull()) {
             checkTrueForKey(key, " Full capability camera devices must support OFF mode",
                     modesList.contains(CameraMetadata.CONTROL_AWB_MODE_OFF));
         }
@@ -1225,7 +1228,7 @@
         }
 
         List<Integer> modesList = Arrays.asList(CameraTestUtils.toObject(afModes));
-        if (isHardwareLevelLimitedOrBetter()) {
+        if (isHardwareLevelAtLeastLimited()) {
             // Some LEGACY mode devices do not support AF OFF
             checkTrueForKey(key, " All camera devices must support OFF mode",
                     modesList.contains(CameraMetadata.CONTROL_AF_MODE_OFF));
@@ -1496,13 +1499,13 @@
 
         List<Integer> modeList = Arrays.asList(CameraTestUtils.toObject(edgeModes));
         // Full device should always include OFF and FAST
-        if (isHardwareLevelFull()) {
+        if (isHardwareLevelAtLeastFull()) {
             checkTrueForKey(key, "Full device must contain OFF and FAST edge modes",
                     modeList.contains(CameraMetadata.EDGE_MODE_OFF) &&
                     modeList.contains(CameraMetadata.EDGE_MODE_FAST));
         }
 
-        if (isHardwareLevelLimitedOrBetter()) {
+        if (isHardwareLevelAtLeastLimited()) {
             // FAST and HIGH_QUALITY mode must be both present or both not present
             List<Integer> coupledModes = Arrays.asList(new Integer[] {
                     CameraMetadata.EDGE_MODE_FAST,
@@ -1527,14 +1530,14 @@
 
         List<Integer> modeList = Arrays.asList(CameraTestUtils.toObject(noiseReductionModes));
         // Full device should always include OFF and FAST
-        if (isHardwareLevelFull()) {
+        if (isHardwareLevelAtLeastFull()) {
 
             checkTrueForKey(key, "Full device must contain OFF and FAST noise reduction modes",
                     modeList.contains(CameraMetadata.NOISE_REDUCTION_MODE_OFF) &&
                     modeList.contains(CameraMetadata.NOISE_REDUCTION_MODE_FAST));
         }
 
-        if (isHardwareLevelLimitedOrBetter()) {
+        if (isHardwareLevelAtLeastLimited()) {
             // FAST and HIGH_QUALITY mode must be both present or both not present
             List<Integer> coupledModes = Arrays.asList(new Integer[] {
                     CameraMetadata.NOISE_REDUCTION_MODE_FAST,
@@ -1563,7 +1566,7 @@
         }
 
         // Legacy devices don't have a minimum step requirement
-        if (isHardwareLevelLimitedOrBetter()) {
+        if (isHardwareLevelAtLeastLimited()) {
             float compensationStepF =
                     (float) compensationStep.getNumerator() / compensationStep.getDenominator();
             checkTrueForKey(key, " value must be no more than 1/2", compensationStepF <= 0.5f);
@@ -1592,7 +1595,7 @@
         }
 
         // Legacy devices don't have a minimum range requirement
-        if (isHardwareLevelLimitedOrBetter() && !compensationRange.equals(ZERO_RANGE)) {
+        if (isHardwareLevelAtLeastLimited() && !compensationRange.equals(ZERO_RANGE)) {
             checkTrueForKey(key, " range value must be at least " + DEFAULT_RANGE
                     + ", actual " + compensationRange + ", compensation step " + compensationStep,
                    compensationRange.getLower() <= DEFAULT_RANGE.getLower() &&
@@ -1626,6 +1629,13 @@
         return modes;
     }
 
+    public boolean isVideoStabilizationSupported() {
+        Integer[] videoStabModes =
+                CameraTestUtils.toObject(getAvailableVideoStabilizationModesChecked());
+        return Arrays.asList(videoStabModes).contains(
+                CameraMetadata.CONTROL_VIDEO_STABILIZATION_MODE_ON);
+    }
+
     /**
      * Get availableOpticalStabilization and do the sanity check.
      *
@@ -1722,7 +1732,7 @@
                 modeList.contains(CameraMetadata.COLOR_CORRECTION_ABERRATION_MODE_OFF) ||
                 modeList.contains(CameraMetadata.COLOR_CORRECTION_ABERRATION_MODE_FAST));
 
-        if (isHardwareLevelLimitedOrBetter()) {
+        if (isHardwareLevelAtLeastLimited()) {
             // FAST and HIGH_QUALITY mode must be both present or both not present
             List<Integer> coupledModes = Arrays.asList(new Integer[] {
                     CameraMetadata.COLOR_CORRECTION_ABERRATION_MODE_FAST,
@@ -2195,6 +2205,25 @@
     }
 
     /**
+     * Check if optical black regions key is supported.
+     */
+    public boolean isOpticalBlackRegionSupported() {
+        return areKeysAvailable(CameraCharacteristics.SENSOR_OPTICAL_BLACK_REGIONS);
+    }
+
+    /**
+     * Check if the dynamic black level is supported.
+     *
+     * <p>
+     * Note that: This also indicates if the white level is supported, as dynamic black and white
+     * level must be all supported or none of them is supported.
+     * </p>
+     */
+    public boolean isDynamicBlackLevelSupported() {
+        return areKeysAvailable(CaptureResult.SENSOR_DYNAMIC_BLACK_LEVEL);
+    }
+
+    /**
      * Get the value in index for a fixed-size array from a given key.
      *
      * <p>If the camera device is incorrectly reporting values, log a warning and return
diff --git a/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2SurfaceViewTestCase.java b/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2SurfaceViewTestCase.java
index b7287ae..9ffe095 100644
--- a/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2SurfaceViewTestCase.java
+++ b/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2SurfaceViewTestCase.java
@@ -29,6 +29,7 @@
 import android.util.Log;
 import android.view.Surface;
 import android.view.SurfaceHolder;
+import android.view.View;
 import android.view.WindowManager;
 import android.content.Context;
 import android.graphics.ImageFormat;
@@ -216,12 +217,25 @@
     }
 
     /**
-     * Stop preview for current camera device.
+     * Stop preview for current camera device by closing the session.
+     * Does _not_ wait for the device to go idle
      */
     protected void stopPreview() throws Exception {
+        if (VERBOSE) Log.v(TAG, "Stopping preview");
+        // Stop repeat, wait for captures to complete, and disconnect from surfaces
+        mSession.close();
+    }
+
+    /**
+     * Stop preview for current camera device by closing the session and waiting for it to close,
+     * resulting in an idle device.
+     */
+    protected void stopPreviewAndDrain() throws Exception {
         if (VERBOSE) Log.v(TAG, "Stopping preview and waiting for idle");
         // Stop repeat, wait for captures to complete, and disconnect from surfaces
         mSession.close();
+        mSessionListener.getStateWaiter().waitForState(BlockingSessionCallback.SESSION_CLOSED,
+                /*timeoutMs*/WAIT_FOR_RESULT_TIMEOUT_MS);
     }
 
     /**
@@ -485,7 +499,7 @@
             int numResultWaitForUnknownLatency) {
         waitForSettingsApplied(resultListener, numResultWaitForUnknownLatency);
 
-        if (!mStaticInfo.isHardwareLevelLimitedOrBetter()) {
+        if (!mStaticInfo.isHardwareLevelAtLeastLimited()) {
             // No-op for metadata
             return;
         }
@@ -515,7 +529,7 @@
 
         waitForSettingsApplied(resultListener, numResultWaitForUnknownLatency);
 
-        if (!mStaticInfo.isHardwareLevelLimitedOrBetter()) {
+        if (!mStaticInfo.isHardwareLevelAtLeastLimited()) {
             // No-op for legacy devices
             return;
         }
@@ -625,6 +639,41 @@
     }
 
     /**
+     * Recreate the SurfaceView's Surface
+     *
+     * Hide and unhide the activity's preview SurfaceView, so that its backing Surface is
+     * recreated
+     */
+    protected void recreatePreviewSurface() {
+        Camera2SurfaceViewCtsActivity ctsActivity = getActivity();
+        setPreviewVisibility(View.GONE);
+        boolean res = ctsActivity.waitForSurfaceState(
+            WAIT_FOR_SURFACE_CHANGE_TIMEOUT_MS, /*valid*/ false);
+        assertTrue("wait for surface destroyed timed out", res);
+        setPreviewVisibility(View.VISIBLE);
+        res = ctsActivity.waitForSurfaceState(
+            WAIT_FOR_SURFACE_CHANGE_TIMEOUT_MS, /*valid*/ true);
+        assertTrue("wait for surface created timed out", res);
+    }
+
+    /**
+     * Show/hide the preview SurfaceView.
+     *
+     * If set to View.GONE, the surfaceDestroyed callback will fire
+     * @param visibility the new new visibility to set, one of View.VISIBLE / INVISIBLE / GONE
+     */
+    protected void setPreviewVisibility(int visibility) {
+        final Camera2SurfaceViewCtsActivity ctsActivity = getActivity();
+        Handler handler = new Handler(Looper.getMainLooper());
+        handler.post(new Runnable() {
+            @Override
+            public void run() {
+                ctsActivity.getSurfaceView().setVisibility(visibility);
+            }
+        });
+    }
+
+    /**
      * Setup single capture configuration and start preview.
      *
      * @param previewRequest The capture request to be used for preview
diff --git a/tests/camera/src/android/hardware/cts/CameraGLTest.java b/tests/camera/src/android/hardware/cts/CameraGLTest.java
index 5ea7517..1f86936 100644
--- a/tests/camera/src/android/hardware/cts/CameraGLTest.java
+++ b/tests/camera/src/android/hardware/cts/CameraGLTest.java
@@ -62,7 +62,7 @@
 @LargeTest
 public class CameraGLTest extends ActivityInstrumentationTestCase2<GLSurfaceViewCtsActivity> {
     private static final String TAG = "CameraGLTest";
-    private static final String PACKAGE = "com.android.cts.hardware";
+    private static final String PACKAGE = "android.hardware.cts";
     private static final boolean LOGV = false;
     private static final boolean LOGVV = false;
     private static final int EGL_OPENGL_ES2_BIT = 0x0004;
diff --git a/tests/camera/src/android/hardware/cts/CameraTest.java b/tests/camera/src/android/hardware/cts/CameraTest.java
index 6869ed1..1ea4b0d 100644
--- a/tests/camera/src/android/hardware/cts/CameraTest.java
+++ b/tests/camera/src/android/hardware/cts/CameraTest.java
@@ -67,7 +67,7 @@
 @LargeTest
 public class CameraTest extends ActivityInstrumentationTestCase2<CameraCtsActivity> {
     private static final String TAG = "CameraTest";
-    private static final String PACKAGE = "com.android.cts.hardware";
+    private static final String PACKAGE = "android.hardware.cts";
     private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
     private final String JPEG_PATH = Environment.getExternalStorageDirectory().getPath() +
             "/test.jpg";
diff --git a/tests/camera/src/android/hardware/multiprocess/camera/cts/CameraEvictionTest.java b/tests/camera/src/android/hardware/multiprocess/camera/cts/CameraEvictionTest.java
index 9f1ae03..834d37cf 100644
--- a/tests/camera/src/android/hardware/multiprocess/camera/cts/CameraEvictionTest.java
+++ b/tests/camera/src/android/hardware/multiprocess/camera/cts/CameraEvictionTest.java
@@ -147,93 +147,7 @@
      * Test basic eviction scenarios for the Camera1 API.
      */
     public void testCamera1ActivityEviction() throws Throwable {
-
-        // Open a camera1 client in the main CTS process's activity
-        final Camera.ErrorCallback mockErrorCb1 = mock(Camera.ErrorCallback.class);
-        final boolean[] skip = {false};
-        runTestOnUiThread(new Runnable() {
-            @Override
-            public void run() {
-                // Open camera
-                mCamera = Camera.open();
-                if (mCamera == null) {
-                    skip[0] = true;
-                } else {
-                    mCamera.setErrorCallback(mockErrorCb1);
-                }
-                notifyFromUI();
-            }
-        });
-        waitForUI();
-
-        if (skip[0]) {
-            Log.i(TAG, "Skipping testCamera1ActivityEviction, device has no cameras.");
-            return;
-        }
-
-        verifyZeroInteractions(mockErrorCb1);
-
-        startRemoteProcess(Camera1Activity.class, "camera1ActivityProcess");
-
-        // Make sure camera was setup correctly in remote activity
-        List<ErrorLoggingService.LogEvent> events = null;
-        try {
-            events = mErrorServiceConnection.getLog(SETUP_TIMEOUT,
-                    TestConstants.EVENT_CAMERA_CONNECT);
-        } finally {
-            if (events != null) assertOnly(TestConstants.EVENT_CAMERA_CONNECT, events);
-        }
-
-        Thread.sleep(WAIT_TIME);
-
-        // Ensure UI thread has a chance to process callbacks.
-        runTestOnUiThread(new Runnable() {
-            @Override
-            public void run() {
-                Log.i("CTS", "Did something on UI thread.");
-                notifyFromUI();
-            }
-        });
-        waitForUI();
-
-        // Make sure we received correct callback in error listener, and nothing else
-        verify(mockErrorCb1, only()).onError(eq(Camera.CAMERA_ERROR_EVICTED), isA(Camera.class));
-        mCamera = null;
-
-        // Try to open the camera again (even though other TOP process holds the camera).
-        final boolean[] pass = {false};
-        runTestOnUiThread(new Runnable() {
-            @Override
-            public void run() {
-                // Open camera
-                try {
-                    mCamera = Camera.open();
-                } catch (RuntimeException e) {
-                    pass[0] = true;
-                }
-                notifyFromUI();
-            }
-        });
-        waitForUI();
-
-        assertTrue("Did not receive exception when opening camera while camera is held by a" +
-                " higher priority client process.", pass[0]);
-
-        // Verify that attempting to open the camera didn't cause anything weird to happen in the
-        // other process.
-        List<ErrorLoggingService.LogEvent> eventList2 = null;
-        boolean timeoutExceptionHit = false;
-        try {
-            eventList2 = mErrorServiceConnection.getLog(EVICTION_TIMEOUT);
-        } catch (TimeoutException e) {
-            timeoutExceptionHit = true;
-        }
-
-        assertNone("Remote camera service received invalid events: ", eventList2);
-        assertTrue("Remote camera service exited early", timeoutExceptionHit);
-        android.os.Process.killProcess(mProcessPid);
-        mProcessPid = -1;
-        forceCtsActivityToTop();
+        testAPI1ActivityEviction(Camera1Activity.class, "camera1ActivityProcess");
     }
 
     /**
@@ -342,6 +256,114 @@
         forceCtsActivityToTop();
     }
 
+
+    /**
+     * Test basic eviction scenarios for camera used in MediaRecoder
+     */
+    public void testMediaRecorderCameraActivityEviction() throws Throwable {
+        testAPI1ActivityEviction(MediaRecorderCameraActivity.class,
+                "mediaRecorderCameraActivityProcess");
+    }
+
+    /**
+     * Test basic eviction scenarios for Camera1 API.
+     *
+     * This test will open camera, create a higher priority process to run the specified activity,
+     * open camera again, and verify the right clients are evicted.
+     *
+     * @param activityKlass An activity to run in a higher priority process.
+     * @param processName The process name.
+     */
+    private void testAPI1ActivityEviction (java.lang.Class<?> activityKlass, String processName)
+            throws Throwable {
+        // Open a camera1 client in the main CTS process's activity
+        final Camera.ErrorCallback mockErrorCb1 = mock(Camera.ErrorCallback.class);
+        final boolean[] skip = {false};
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                // Open camera
+                mCamera = Camera.open();
+                if (mCamera == null) {
+                    skip[0] = true;
+                } else {
+                    mCamera.setErrorCallback(mockErrorCb1);
+                }
+                notifyFromUI();
+            }
+        });
+        waitForUI();
+
+        if (skip[0]) {
+            Log.i(TAG, "Skipping testCamera1ActivityEviction, device has no cameras.");
+            return;
+        }
+
+        verifyZeroInteractions(mockErrorCb1);
+
+        startRemoteProcess(activityKlass, processName);
+
+        // Make sure camera was setup correctly in remote activity
+        List<ErrorLoggingService.LogEvent> events = null;
+        try {
+            events = mErrorServiceConnection.getLog(SETUP_TIMEOUT,
+                    TestConstants.EVENT_CAMERA_CONNECT);
+        } finally {
+            if (events != null) assertOnly(TestConstants.EVENT_CAMERA_CONNECT, events);
+        }
+
+        Thread.sleep(WAIT_TIME);
+
+        // Ensure UI thread has a chance to process callbacks.
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                Log.i("CTS", "Did something on UI thread.");
+                notifyFromUI();
+            }
+        });
+        waitForUI();
+
+        // Make sure we received correct callback in error listener, and nothing else
+        verify(mockErrorCb1, only()).onError(eq(Camera.CAMERA_ERROR_EVICTED), isA(Camera.class));
+        mCamera = null;
+
+        // Try to open the camera again (even though other TOP process holds the camera).
+        final boolean[] pass = {false};
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                // Open camera
+                try {
+                    mCamera = Camera.open();
+                } catch (RuntimeException e) {
+                    pass[0] = true;
+                }
+                notifyFromUI();
+            }
+        });
+        waitForUI();
+
+        assertTrue("Did not receive exception when opening camera while camera is held by a" +
+                " higher priority client process.", pass[0]);
+
+        // Verify that attempting to open the camera didn't cause anything weird to happen in the
+        // other process.
+        List<ErrorLoggingService.LogEvent> eventList2 = null;
+        boolean timeoutExceptionHit = false;
+        try {
+            eventList2 = mErrorServiceConnection.getLog(EVICTION_TIMEOUT);
+        } catch (TimeoutException e) {
+            timeoutExceptionHit = true;
+        }
+
+        assertNone("Remote camera service received invalid events: ", eventList2);
+        assertTrue("Remote camera service exited early", timeoutExceptionHit);
+        android.os.Process.killProcess(mProcessPid);
+        mProcessPid = -1;
+        forceCtsActivityToTop();
+    }
+
     /**
      * Ensure the CTS activity becomes foreground again instead of launcher.
      */
diff --git a/tests/camera/src/android/hardware/multiprocess/camera/cts/MediaRecorderCameraActivity.java b/tests/camera/src/android/hardware/multiprocess/camera/cts/MediaRecorderCameraActivity.java
new file mode 100644
index 0000000..0558800
--- /dev/null
+++ b/tests/camera/src/android/hardware/multiprocess/camera/cts/MediaRecorderCameraActivity.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.hardware.multiprocess.camera.cts;
+
+import android.app.Activity;
+import android.camera.cts.R;
+import android.media.MediaRecorder;
+import android.os.Bundle;
+import android.os.Environment;
+import android.util.Log;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+import android.view.ViewGroup;
+
+import java.io.File;
+
+/**
+ * Activity implementing basic access of camera using MediaRecorder API.
+ *
+ * <p />
+ * This will log all errors to {@link android.hardware.multiprocess.camera.cts.ErrorLoggingService}.
+ */
+public class MediaRecorderCameraActivity extends Activity implements SurfaceHolder.Callback {
+    private static final String TAG = "MediaRecorderCameraActivity";
+
+    private static final int VIDEO_WIDTH = 640;
+    private static final int VIDEO_HEIGHT = 480;
+    private static final int LAYOUT_WIDTH = VIDEO_WIDTH;
+    private static final int LAYOUT_HEIGHT = VIDEO_HEIGHT;
+
+    private final String OUTPUT_PATH = new File(Environment.getExternalStorageDirectory(),
+                "record.out").getAbsolutePath();
+
+    private File mOutFile;
+    private SurfaceView mSurfaceView;
+    private ErrorLoggingService.ErrorServiceConnection mErrorServiceConnection;
+    private MediaRecorder mMediaRecorder;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        Log.i(TAG, "onCreate called.");
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.surface_view);
+
+        mErrorServiceConnection = new ErrorLoggingService.ErrorServiceConnection(this);
+        mErrorServiceConnection.start();
+
+        mMediaRecorder = new MediaRecorder();
+    }
+
+    @Override
+    protected void onResume() {
+        Log.i(TAG, "onResume called.");
+        super.onResume();
+        try {
+
+            mSurfaceView = (SurfaceView)this.findViewById(R.id.surface_view);
+            ViewGroup.LayoutParams lp = mSurfaceView.getLayoutParams();
+            lp.width = LAYOUT_WIDTH;
+            lp.height = LAYOUT_HEIGHT;
+            mSurfaceView.setLayoutParams(lp);
+
+            SurfaceHolder holder = mSurfaceView.getHolder();
+            holder.setFixedSize(LAYOUT_WIDTH, LAYOUT_HEIGHT);
+            holder.addCallback(this);
+
+        } catch (Throwable e) {
+            mErrorServiceConnection.logAsync(TestConstants.EVENT_CAMERA_ERROR, TAG +
+                    " camera exception during connection: " + e);
+            Log.e(TAG, "Runtime error: " + e);
+        }
+    }
+
+    @Override
+    protected void onPause() {
+        Log.i(TAG, "onPause called.");
+        super.onPause();
+    }
+
+    @Override
+    protected void onDestroy() {
+        Log.i(TAG, "onDestroy called.");
+        super.onDestroy();
+        if (mErrorServiceConnection != null) {
+            mErrorServiceConnection.stop();
+            mErrorServiceConnection = null;
+        }
+
+        if (mOutFile != null && mOutFile.exists()) {
+            mOutFile.delete();
+        }
+
+        if (mMediaRecorder != null) {
+            mMediaRecorder.stop();
+            mMediaRecorder.release();
+        }
+    }
+
+    @Override
+    public void surfaceCreated(SurfaceHolder holder) {
+    }
+
+    @Override
+    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
+        try {
+            mOutFile = new File(OUTPUT_PATH);
+            mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
+            mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
+            mMediaRecorder.setPreviewDisplay(mSurfaceView.getHolder().getSurface());
+            mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);
+            mMediaRecorder.setVideoSize(VIDEO_WIDTH, VIDEO_HEIGHT);
+            mMediaRecorder.setOutputFile(OUTPUT_PATH);
+            mMediaRecorder.prepare();
+            mMediaRecorder.start();
+
+            mErrorServiceConnection.logAsync(TestConstants.EVENT_CAMERA_CONNECT,
+                    TAG + " camera connected");
+        } catch (Throwable e) {
+            mErrorServiceConnection.logAsync(TestConstants.EVENT_CAMERA_ERROR, TAG +
+                    " camera exception during connection: " + e);
+            Log.e(TAG, "Runtime error: " + e);
+        }
+    }
+
+    @Override
+    public void surfaceDestroyed(SurfaceHolder holder) {
+    }
+}
diff --git a/tests/core/ctscore.mk b/tests/core/ctscore.mk
index fea0b07..10a91f1 100644
--- a/tests/core/ctscore.mk
+++ b/tests/core/ctscore.mk
@@ -23,7 +23,10 @@
 # Don't delete META-INF from the core-tests jar
 LOCAL_DONT_DELETE_JAR_META_INF := true
 
-LOCAL_JNI_SHARED_LIBRARIES := libjavacoretests
+# TODO: Clean up this mess. (b/26483949). libnativehelper_compat_libc++ pulls in its own
+# static copy of libc++ and the libc++ we're bundling here is the platform libc++. This is
+# bround to break but is being submitted as a workaround for failing CTS tests.
+LOCAL_JNI_SHARED_LIBRARIES := libjavacoretests libsqlite_jni libnativehelper_compat_libc++ libc++
 
 # Include both the 32 and 64 bit versions of libjavacoretests,
 # where applicable.
diff --git a/tests/core/libcore/com/Android.mk b/tests/core/libcore/com/Android.mk
index db08dbd..c1df39a 100644
--- a/tests/core/libcore/com/Android.mk
+++ b/tests/core/libcore/com/Android.mk
@@ -17,4 +17,5 @@
 include $(CLEAR_VARS)
 LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.com
 LOCAL_STATIC_JAVA_LIBRARIES := core-tests
+LOCAL_JAVA_LANGUAGE_VERSION := 1.8
 include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/conscrypt/Android.mk b/tests/core/libcore/conscrypt/Android.mk
index bcfd3a4..cd8559c 100644
--- a/tests/core/libcore/conscrypt/Android.mk
+++ b/tests/core/libcore/conscrypt/Android.mk
@@ -21,4 +21,5 @@
 include $(CLEAR_VARS)
 LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.conscrypt
 LOCAL_STATIC_JAVA_LIBRARIES := core-tests conscrypt-tests
+LOCAL_JAVA_LANGUAGE_VERSION := 1.8
 include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/dalvik/Android.mk b/tests/core/libcore/dalvik/Android.mk
index 42d14f3..501c674 100644
--- a/tests/core/libcore/dalvik/Android.mk
+++ b/tests/core/libcore/dalvik/Android.mk
@@ -17,4 +17,5 @@
 include $(CLEAR_VARS)
 LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.dalvik
 LOCAL_STATIC_JAVA_LIBRARIES := core-tests
+LOCAL_JAVA_LANGUAGE_VERSION := 1.8
 include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/harmony_annotation/Android.mk b/tests/core/libcore/harmony_annotation/Android.mk
index e9f716e..6746cf3 100644
--- a/tests/core/libcore/harmony_annotation/Android.mk
+++ b/tests/core/libcore/harmony_annotation/Android.mk
@@ -21,4 +21,5 @@
 include $(CLEAR_VARS)
 LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.harmony_annotation
 LOCAL_STATIC_JAVA_LIBRARIES := core-tests
+LOCAL_JAVA_LANGUAGE_VERSION := 1.8
 include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/harmony_java_io/Android.mk b/tests/core/libcore/harmony_java_io/Android.mk
index a8d4fa0..3108f30 100644
--- a/tests/core/libcore/harmony_java_io/Android.mk
+++ b/tests/core/libcore/harmony_java_io/Android.mk
@@ -21,4 +21,5 @@
 include $(CLEAR_VARS)
 LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.harmony_java_io
 LOCAL_STATIC_JAVA_LIBRARIES := core-tests
+LOCAL_JAVA_LANGUAGE_VERSION := 1.8
 include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/harmony_java_lang/Android.mk b/tests/core/libcore/harmony_java_lang/Android.mk
index 8b1bdff..e333708 100644
--- a/tests/core/libcore/harmony_java_lang/Android.mk
+++ b/tests/core/libcore/harmony_java_lang/Android.mk
@@ -21,4 +21,5 @@
 include $(CLEAR_VARS)
 LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.harmony_java_lang
 LOCAL_STATIC_JAVA_LIBRARIES := core-tests
+LOCAL_JAVA_LANGUAGE_VERSION := 1.8
 include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/harmony_java_math/Android.mk b/tests/core/libcore/harmony_java_math/Android.mk
index 8310743..5889f85 100644
--- a/tests/core/libcore/harmony_java_math/Android.mk
+++ b/tests/core/libcore/harmony_java_math/Android.mk
@@ -21,4 +21,5 @@
 include $(CLEAR_VARS)
 LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.harmony_java_math
 LOCAL_STATIC_JAVA_LIBRARIES := core-tests
+LOCAL_JAVA_LANGUAGE_VERSION := 1.8
 include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/harmony_java_net/Android.mk b/tests/core/libcore/harmony_java_net/Android.mk
index 7917bcc..95218c4 100644
--- a/tests/core/libcore/harmony_java_net/Android.mk
+++ b/tests/core/libcore/harmony_java_net/Android.mk
@@ -21,4 +21,5 @@
 include $(CLEAR_VARS)
 LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.harmony_java_net
 LOCAL_STATIC_JAVA_LIBRARIES := core-tests
+LOCAL_JAVA_LANGUAGE_VERSION := 1.8
 include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/harmony_java_nio/Android.mk b/tests/core/libcore/harmony_java_nio/Android.mk
index 2c6f673..5bdfd17 100644
--- a/tests/core/libcore/harmony_java_nio/Android.mk
+++ b/tests/core/libcore/harmony_java_nio/Android.mk
@@ -21,4 +21,5 @@
 include $(CLEAR_VARS)
 LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.harmony_java_nio
 LOCAL_STATIC_JAVA_LIBRARIES := core-tests
+LOCAL_JAVA_LANGUAGE_VERSION := 1.8
 include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/harmony_java_text/Android.mk b/tests/core/libcore/harmony_java_text/Android.mk
index ecd1574..21113e5 100644
--- a/tests/core/libcore/harmony_java_text/Android.mk
+++ b/tests/core/libcore/harmony_java_text/Android.mk
@@ -21,4 +21,5 @@
 include $(CLEAR_VARS)
 LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.harmony_java_text
 LOCAL_STATIC_JAVA_LIBRARIES := core-tests
+LOCAL_JAVA_LANGUAGE_VERSION := 1.8
 include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/harmony_java_util/Android.mk b/tests/core/libcore/harmony_java_util/Android.mk
index 6d7bded..f34295e 100644
--- a/tests/core/libcore/harmony_java_util/Android.mk
+++ b/tests/core/libcore/harmony_java_util/Android.mk
@@ -21,4 +21,5 @@
 include $(CLEAR_VARS)
 LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.harmony_java_util
 LOCAL_STATIC_JAVA_LIBRARIES := core-tests
+LOCAL_JAVA_LANGUAGE_VERSION := 1.8
 include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/harmony_javax_security/Android.mk b/tests/core/libcore/harmony_javax_security/Android.mk
index 011940d..fce594b 100644
--- a/tests/core/libcore/harmony_javax_security/Android.mk
+++ b/tests/core/libcore/harmony_javax_security/Android.mk
@@ -21,4 +21,5 @@
 include $(CLEAR_VARS)
 LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.harmony_javax_security
 LOCAL_STATIC_JAVA_LIBRARIES := core-tests
+LOCAL_JAVA_LANGUAGE_VERSION := 1.8
 include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/harmony_logging/Android.mk b/tests/core/libcore/harmony_logging/Android.mk
index 2ec10f1..69a8e3a 100644
--- a/tests/core/libcore/harmony_logging/Android.mk
+++ b/tests/core/libcore/harmony_logging/Android.mk
@@ -21,4 +21,5 @@
 include $(CLEAR_VARS)
 LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.harmony_logging
 LOCAL_STATIC_JAVA_LIBRARIES := apache-harmony-tests
+LOCAL_JAVA_LANGUAGE_VERSION := 1.8
 include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/libcore/Android.mk b/tests/core/libcore/libcore/Android.mk
index a86d2c0..c9aea5e 100644
--- a/tests/core/libcore/libcore/Android.mk
+++ b/tests/core/libcore/libcore/Android.mk
@@ -16,5 +16,9 @@
 
 include $(CLEAR_VARS)
 LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.libcore
-LOCAL_STATIC_JAVA_LIBRARIES := core-tests
+# Note that we're not pulling in junit4 here because it's provided by
+# android.test.runner (which might pull in a different version from the
+# one that would be pulled in here).
+LOCAL_STATIC_JAVA_LIBRARIES := core-tests mockito-target-minus-junit4
+LOCAL_JAVA_LANGUAGE_VERSION := 1.8
 include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/okhttp/Android.mk b/tests/core/libcore/okhttp/Android.mk
index 4fe50ff..c2b71c0 100644
--- a/tests/core/libcore/okhttp/Android.mk
+++ b/tests/core/libcore/okhttp/Android.mk
@@ -20,5 +20,5 @@
 
 include $(CLEAR_VARS)
 LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.okhttp
-LOCAL_STATIC_JAVA_LIBRARIES := okhttp-nojarjar junit4-target bouncycastle-nojarjar okhttp-tests-nojarjar
+LOCAL_STATIC_JAVA_LIBRARIES := okhttp-nojarjar bouncycastle-nojarjar okhttp-tests-nojarjar
 include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/org/Android.mk b/tests/core/libcore/org/Android.mk
index 0f3f0ca..d174f98 100644
--- a/tests/core/libcore/org/Android.mk
+++ b/tests/core/libcore/org/Android.mk
@@ -17,4 +17,5 @@
 include $(CLEAR_VARS)
 LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.org
 LOCAL_STATIC_JAVA_LIBRARIES := core-tests
+LOCAL_JAVA_LANGUAGE_VERSION := 1.8
 include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/sun/Android.mk b/tests/core/libcore/sun/Android.mk
index ed6d2c7..2fa1520 100644
--- a/tests/core/libcore/sun/Android.mk
+++ b/tests/core/libcore/sun/Android.mk
@@ -17,4 +17,5 @@
 include $(CLEAR_VARS)
 LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.sun
 LOCAL_STATIC_JAVA_LIBRARIES := core-tests
+LOCAL_JAVA_LANGUAGE_VERSION := 1.8
 include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/tests/Android.mk b/tests/core/libcore/tests/Android.mk
index 54ffd31..6429558 100644
--- a/tests/core/libcore/tests/Android.mk
+++ b/tests/core/libcore/tests/Android.mk
@@ -16,5 +16,6 @@
 
 include $(CLEAR_VARS)
 LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.tests
-LOCAL_STATIC_JAVA_LIBRARIES := core-tests
+LOCAL_STATIC_JAVA_LIBRARIES := core-tests mockito-target-minus-junit4
+LOCAL_JAVA_LANGUAGE_VERSION := 1.8
 include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/runner/Android.mk b/tests/core/runner/Android.mk
index 649b3b4..1355512 100644
--- a/tests/core/runner/Android.mk
+++ b/tests/core/runner/Android.mk
@@ -23,10 +23,44 @@
 # include this package in the tests target for continuous testing
 LOCAL_MODULE_TAGS := tests
 
-LOCAL_SRC_FILES := $(call all-java-files-under,src)
-
 LOCAL_PACKAGE_NAME := android.core.tests.runner
 
-LOCAL_STATIC_JAVA_LIBRARIES := core-tests android-support-test
+LOCAL_STATIC_JAVA_LIBRARIES := cts-test-runner
+
+LOCAL_JAVA_LANGUAGE_VERSION := 1.8
 
 include $(BUILD_CTSCORE_PACKAGE)
+
+#==========================================================
+# Build the core runner.
+#==========================================================
+
+# Build library
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+LOCAL_SRC_FILES := $(call all-java-files-under,src)
+LOCAL_MODULE := cts-core-test-runner
+LOCAL_STATIC_JAVA_LIBRARIES := \
+    compatibility-device-util \
+    android-support-test \
+    android.test.runner \
+    vogarexpect
+
+LOCAL_JAVA_LANGUAGE_VERSION := 1.8
+
+include $(BUILD_JAVA_LIBRARY)
+
+#==========================================================
+# Build the run listener
+#==========================================================
+
+# Build library
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+LOCAL_SRC_FILES := $(call all-java-files-under,src/com/android/cts/runner)
+LOCAL_MODULE := cts-test-runner
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
+
+include $(BUILD_JAVA_LIBRARY)
diff --git a/tests/core/runner/src/com/android/cts/core/runner/AndroidJUnitRunnerConstants.java b/tests/core/runner/src/com/android/cts/core/runner/AndroidJUnitRunnerConstants.java
new file mode 100644
index 0000000..c6c8504
--- /dev/null
+++ b/tests/core/runner/src/com/android/cts/core/runner/AndroidJUnitRunnerConstants.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.core.runner;
+
+import android.support.test.runner.AndroidJUnitRunner;
+
+/**
+ * Constants used to communicate to and from {@link AndroidJUnitRunner}.
+ */
+public interface AndroidJUnitRunnerConstants {
+
+    /**
+     * The names of the file containing the names of the tests to run.
+     *
+     * <p>This is an internal constant used within
+     * {@code android.support.test.internal.runner.RunnerArgs}, which is used on both the server
+     * and
+     * client side. The constant is used when there are too many test names to pass on the command
+     * line, in which case they are stored in a file that is pushed to the device and then the
+     * location of that file is passed in this argument. The {@code RunnerArgs} on the client will
+     * read the contents of that file in order to retrieve the list of names and then return that
+     * to
+     * its client without the client being aware of how that was done.
+     */
+    String ARGUMENT_TEST_FILE = "testFile";
+
+    /**
+     * A comma separated list of the names of test classes to run.
+     *
+     * <p>The equivalent constant in {@code InstrumentationTestRunner} is hidden and so not
+     * available
+     * through the public API.
+     */
+    String ARGUMENT_TEST_CLASS = "class";
+
+    /**
+     * Log the results as if the tests were executed but don't actually run the tests.
+     *
+     * <p>The equivalent constant in {@code InstrumentationTestRunner} is private.
+     */
+    String ARGUMENT_LOG_ONLY = "log";
+
+    /**
+     * Wait for the debugger before starting.
+     *
+     * <p>There is no equivalent constant in {@code InstrumentationTestRunner} but the string is
+     * used
+     * within that class.
+     */
+    String ARGUMENT_DEBUG = "debug";
+
+    /**
+     * Only count the number of tests to run.
+     *
+     * <p>There is no equivalent constant in {@code InstrumentationTestRunner} but the string is
+     * used
+     * within that class.
+     */
+    String ARGUMENT_COUNT = "count";
+
+    /**
+     * Token representing how long (in seconds) the current test took to execute.
+     *
+     * <p>The equivalent constant in {@code InstrumentationTestRunner} is private.
+     */
+    String REPORT_KEY_RUNTIME = "runtime";
+
+    /**
+     * An identifier for tests run using this class.
+     */
+    String REPORT_VALUE_ID = "CoreTestRunner";
+}
diff --git a/tests/core/runner/src/com/android/cts/core/runner/CoreTestRunner.java b/tests/core/runner/src/com/android/cts/core/runner/CoreTestRunner.java
new file mode 100644
index 0000000..13af39a
--- /dev/null
+++ b/tests/core/runner/src/com/android/cts/core/runner/CoreTestRunner.java
@@ -0,0 +1,294 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.core.runner;
+
+import android.app.Activity;
+import android.app.Instrumentation;
+import android.os.Bundle;
+import android.os.Debug;
+import android.support.test.internal.runner.listener.InstrumentationResultPrinter;
+import android.support.test.internal.runner.listener.InstrumentationRunListener;
+import android.support.test.internal.util.AndroidRunnerParams;
+import android.util.Log;
+import com.android.cts.core.runner.support.ExtendedAndroidRunnerBuilder;
+import com.google.common.base.Splitter;
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+import javax.annotation.Nullable;
+import org.junit.runner.Computer;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Request;
+import org.junit.runner.Runner;
+import org.junit.runner.manipulation.Filter;
+import org.junit.runner.manipulation.Filterable;
+import org.junit.runner.manipulation.NoTestsRemainException;
+import org.junit.runner.notification.RunListener;
+import org.junit.runners.model.InitializationError;
+import org.junit.runners.model.RunnerBuilder;
+import vogar.ExpectationStore;
+import vogar.ModeId;
+
+import static com.android.cts.core.runner.AndroidJUnitRunnerConstants.ARGUMENT_COUNT;
+import static com.android.cts.core.runner.AndroidJUnitRunnerConstants.ARGUMENT_DEBUG;
+import static com.android.cts.core.runner.AndroidJUnitRunnerConstants.ARGUMENT_LOG_ONLY;
+import static com.android.cts.core.runner.AndroidJUnitRunnerConstants.ARGUMENT_TEST_CLASS;
+import static com.android.cts.core.runner.AndroidJUnitRunnerConstants.ARGUMENT_TEST_FILE;
+
+/**
+ * A drop-in replacement for AndroidJUnitTestRunner, which understands the same arguments, and has
+ * similar functionality, but can filter by expectations and allows a custom runner-builder to be
+ * provided.
+ */
+public class CoreTestRunner extends Instrumentation {
+
+    public static final String TAG = "LibcoreTestRunner";
+
+    private static final java.lang.String ARGUMENT_ROOT_CLASSES = "core-root-classes";
+
+    private static final String ARGUMENT_EXPECTATIONS = "core-expectations";
+
+    private static final String ARGUMENT_CORE_LISTENER = "core-listener";
+
+    private static final Splitter CLASS_LIST_SPLITTER = Splitter.on(',').trimResults();
+
+    /** The args for the runner. */
+    private Bundle args;
+
+    /** Only count the number of tests, and not run them. */
+    private boolean testCountOnly;
+
+    /** Only log the number of tests, and not run them. */
+    private boolean logOnly;
+
+    /**
+     * The container for any test expectations.
+     */
+    @Nullable
+    private ExpectationStore expectationStore;
+
+    /**
+     * The list of tests to run.
+     */
+    private TestList testList;
+
+    /**
+     * The list of {@link RunListener} classes to create.
+     */
+    private List<Class<? extends RunListener>> listenerClasses;
+
+    @Override
+    public void onCreate(final Bundle args) {
+        super.onCreate(args);
+        this.args = args;
+
+        boolean debug = "true".equalsIgnoreCase(args.getString(ARGUMENT_DEBUG));
+        if (debug) {
+            Log.i(TAG, "Waiting for debugger to connect...");
+            Debug.waitForDebugger();
+            Log.i(TAG, "Debugger connected.");
+        }
+
+        // Log the message only after getting a value from the args so that the args are
+        // unparceled.
+        Log.d(TAG, "In OnCreate: " + args);
+
+        this.logOnly = "true".equalsIgnoreCase(args.getString(ARGUMENT_LOG_ONLY));
+        this.testCountOnly = args.getBoolean(ARGUMENT_COUNT);
+
+        try {
+            // Get the set of resource names containing the expectations.
+            Set<String> expectationResources = new LinkedHashSet<>(
+                    getExpectationResourcePaths(args));
+            expectationStore = ExpectationStore.parseResources(
+                    getClass(), expectationResources, ModeId.DEVICE);
+        } catch (IOException e) {
+            Log.e(TAG, "Could not initialize ExpectationStore: ", e);
+        }
+
+        // The test can be run specifying a list of tests to run, or as cts-tradefed does it,
+        // by passing a fileName with a test to run on each line.
+        List<String> testNameList;
+        String arg;
+        if ((arg = args.getString(ARGUMENT_TEST_FILE)) != null) {
+            // The tests are specified in a file.
+            try {
+                testNameList = readTestsFromFile(arg);
+            } catch (IOException err) {
+                finish(Activity.RESULT_CANCELED, new Bundle());
+                return;
+            }
+        } else if ((arg = args.getString(ARGUMENT_TEST_CLASS)) != null) {
+            // The tests are specified in a String passed in the bundle.
+            String[] tests = arg.split(",");
+            testNameList = Arrays.asList(tests);
+        } else {
+            // null means the runner should run all tests.
+            testNameList = null;
+        }
+
+        if (testNameList == null) {
+            List<String> roots = getRootClassNames(args);
+            if (roots == null) {
+                // Find all test classes
+                testList = getAllTestClasses();
+            } else {
+                testList = TestList.rootList(roots);
+            }
+
+        } else {
+            testList = TestList.exclusiveList(testNameList);
+        }
+
+        listenerClasses = new ArrayList<>();
+        String listenerArg = args.getString(ARGUMENT_CORE_LISTENER);
+        if (listenerArg != null) {
+            List<String> listenerClassNames = CLASS_LIST_SPLITTER.splitToList(listenerArg);
+            for (String listenerClassName : listenerClassNames) {
+                try {
+                    Class<? extends RunListener> listenerClass = Class.forName(listenerClassName)
+                            .asSubclass(RunListener.class);
+                    listenerClasses.add(listenerClass);
+                } catch (ClassNotFoundException e) {
+                    Log.e(TAG, "Could not load listener class: " + listenerClassName, e);
+                }
+            }
+        }
+
+        start();
+    }
+
+    protected List<String> getExpectationResourcePaths(Bundle args) {
+        return CLASS_LIST_SPLITTER.splitToList(args.getString(ARGUMENT_EXPECTATIONS));
+    }
+
+    protected List<String> getRootClassNames(Bundle args) {
+        String rootClasses = args.getString(ARGUMENT_ROOT_CLASSES);
+        List<String> roots;
+        if (rootClasses == null) {
+            roots = null;
+        } else {
+            roots = CLASS_LIST_SPLITTER.splitToList(rootClasses);
+        }
+        return roots;
+    }
+
+    @Override
+    public void onStart() {
+        if (logOnly || testCountOnly) {
+            Log.d(TAG, "Counting/logging tests only");
+        } else {
+            Log.d(TAG, "Running tests");
+        }
+
+        AndroidRunnerParams runnerParams = new AndroidRunnerParams(this, args,
+                logOnly || testCountOnly, -1, false);
+
+        JUnitCore core = new JUnitCore();
+
+        Request request;
+        try {
+            RunnerBuilder runnerBuilder = new ExtendedAndroidRunnerBuilder(runnerParams);
+            Class[] classes = testList.getClassesToRun();
+            Runner suite = new Computer().getSuite(runnerBuilder, classes);
+
+            if (suite instanceof Filterable) {
+                Filterable filterable = (Filterable) suite;
+
+                // Filter out all the tests that are expected to fail.
+                Filter filter = new TestFilter(testList, expectationStore);
+
+                try {
+                    filterable.filter(filter);
+                } catch (NoTestsRemainException e) {
+                    // Sometimes filtering will remove all tests but we do not care about that.
+                }
+            }
+
+            request = Request.runner(suite);
+
+        } catch (InitializationError e) {
+            throw new RuntimeException("Could not create a suite", e);
+        }
+
+        InstrumentationResultPrinter instrumentationResultPrinter =
+                new InstrumentationResultPrinter();
+        instrumentationResultPrinter.setInstrumentation(this);
+        core.addListener(instrumentationResultPrinter);
+
+        for (Class<? extends RunListener> listenerClass : listenerClasses) {
+            try {
+                RunListener runListener = listenerClass.newInstance();
+                if (runListener instanceof InstrumentationRunListener) {
+                    ((InstrumentationRunListener) runListener).setInstrumentation(this);
+                }
+                core.addListener(runListener);
+            } catch (InstantiationException | IllegalAccessException e) {
+                Log.e(TAG, "Could not create instance of listener: " + listenerClass, e);
+            }
+        }
+
+        Bundle results = new Bundle();
+        try {
+            core.run(request);
+        } catch (RuntimeException e) {
+            final String msg = "Fatal exception when running tests";
+            Log.e(TAG, msg, e);
+            // report the exception to instrumentation out
+            results.putString(Instrumentation.REPORT_KEY_STREAMRESULT,
+                    msg + "\n" + Log.getStackTraceString(e));
+        }
+
+        Log.d(TAG, "Finished");
+        finish(Activity.RESULT_OK, results);
+    }
+
+    /**
+     * Read tests from a specified file.
+     *
+     * @return class names of tests. If there was an error reading the file, null is returned.
+     */
+    private static List<String> readTestsFromFile(String fileName) throws IOException {
+        try (BufferedReader br = new BufferedReader(new FileReader(fileName))) {
+            List<String> tests = new ArrayList<>();
+            String line;
+            while ((line = br.readLine()) != null) {
+                tests.add(line);
+            }
+            return tests;
+        } catch (IOException err) {
+            Log.e(TAG, "There was an error reading the test class list: " + err.getMessage());
+            throw err;
+        }
+    }
+
+    private TestList getAllTestClasses() {
+        Collection<Class<?>> classes = TestClassFinder.getClasses(
+                Collections.singletonList(getContext().getPackageCodePath()),
+                getClass().getClassLoader());
+
+        return TestList.classList(classes);
+    }
+
+}
diff --git a/tests/core/runner/src/com/android/cts/core/runner/TestClassFinder.java b/tests/core/runner/src/com/android/cts/core/runner/TestClassFinder.java
new file mode 100644
index 0000000..1b15aec
--- /dev/null
+++ b/tests/core/runner/src/com/android/cts/core/runner/TestClassFinder.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.core.runner;
+
+import android.support.test.internal.runner.ClassPathScanner;
+import android.support.test.internal.runner.ClassPathScanner.ClassNameFilter;
+import android.support.test.internal.runner.TestLoader;
+import android.util.Log;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Find tests in the current APK.
+ */
+public class TestClassFinder {
+
+    // Excluded test packages
+    private static final String[] DEFAULT_EXCLUDED_PACKAGES = {
+            "junit",
+            "org.junit",
+            "org.hamcrest",
+            "org.mockito",// exclude Mockito for performance and to prevent JVM related errors
+            "android.support.test.internal.runner.junit3",// always skip AndroidTestSuite
+    };
+
+    static Collection<Class<?>> getClasses(List<String> apks, ClassLoader loader) {
+        List<Class<?>> classes = new ArrayList<>();
+        ClassPathScanner scanner = new ClassPathScanner(apks);
+
+        ClassPathScanner.ChainedClassNameFilter filter =
+                new ClassPathScanner.ChainedClassNameFilter();
+        // exclude inner classes
+        filter.add(new ClassPathScanner.ExternalClassNameFilter());
+
+        // exclude default classes
+        for (String defaultExcludedPackage : DEFAULT_EXCLUDED_PACKAGES) {
+            filter.add(new ExcludePackageNameFilter(defaultExcludedPackage));
+        }
+
+        TestLoader testLoader = new TestLoader();
+        testLoader.setClassLoader(loader);
+
+        try {
+            Set<String> classNames = scanner.getClassPathEntries(filter);
+            for (String className : classNames) {
+                Class<?> cls = testLoader.loadIfTest(className);
+                if (cls != null) {
+                    classes.add(cls);
+                }
+            }
+            return classes;
+        } catch (IOException e) {
+            Log.e(CoreTestRunner.TAG, "Failed to scan classes", e);
+        }
+
+        return testLoader.getLoadedClasses();
+    }
+
+    /**
+     * A {@link ClassNameFilter} that only rejects a given package names within the given namespace.
+     */
+    public static class ExcludePackageNameFilter implements ClassNameFilter {
+
+        private final String mPkgName;
+
+        ExcludePackageNameFilter(String pkgName) {
+            if (!pkgName.endsWith(".")) {
+                mPkgName = String.format("%s.", pkgName);
+            } else {
+                mPkgName = pkgName;
+            }
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public boolean accept(String pathName) {
+            return !pathName.startsWith(mPkgName);
+        }
+    }
+}
diff --git a/tests/core/runner/src/com/android/cts/core/runner/TestFilter.java b/tests/core/runner/src/com/android/cts/core/runner/TestFilter.java
new file mode 100644
index 0000000..8cadbcf
--- /dev/null
+++ b/tests/core/runner/src/com/android/cts/core/runner/TestFilter.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.core.runner;
+
+import android.util.Log;
+import java.util.List;
+import javax.annotation.Nullable;
+import org.junit.runner.Description;
+import org.junit.runner.manipulation.Filter;
+import org.junit.runners.ParentRunner;
+import org.junit.runners.Suite;
+import vogar.Expectation;
+import vogar.ExpectationStore;
+import vogar.Result;
+
+/**
+ * Filter out tests/classes that are not requested or which are expected to fail.
+ *
+ * <p>This filter has to handle both a hierarchy of {@code Description descriptions} that looks
+ * something like this:
+ * <pre>
+ * Suite
+ *     Suite
+ *         Suite
+ *             ParentRunner
+ *                 Test
+ *                 ...
+ *             ...
+ *         ParentRunner
+ *             Test
+ *             ...
+ *         ...
+ *     Suite
+ *         ParentRunner
+ *             Test
+ *             ...
+ *         ...
+ *     ...
+ * </pre>
+ *
+ * <p>And also a flatter hierarchy that looks like this (in CTSv1):
+ * Runner
+ * Test
+ * ...
+ * ...
+ *
+ * <p>It cannot filter out the non-leaf nodes in the hierarchy, i.e. {@link Suite} and
+ * {@link ParentRunner}, as that would prevent it from traversing the hierarchy and finding
+ * the leaf nodes.
+ */
+class TestFilter extends Filter {
+
+    private final ExpectationStore expectationStore;
+
+    private final TestList testList;
+
+    public TestFilter(TestList testList, @Nullable ExpectationStore expectationStore) {
+        this.expectationStore = expectationStore;
+        this.testList = testList;
+    }
+
+    @Override
+    public boolean shouldRun(Description description) {
+        // Only filter leaf nodes. The description is for a test if and only if it is a leaf node.
+        // Non-leaf nodes must not be filtered out as that would prevent leaf nodes from being
+        // visited in the case when we are traversing the hierarchy of classes.
+        Description testDescription = getTestDescription(description);
+        if (testDescription != null) {
+            String className = testDescription.getClassName();
+            String methodName = testDescription.getMethodName();
+            String testName = className + "#" + methodName;
+
+            // If the test isn't in the list of tests to run then do not run it.
+            if (!testList.shouldRunTest(testName)) {
+                return false;
+            }
+
+            if (expectationStore != null) {
+                Expectation expectation = expectationStore.get(testName);
+                if (expectation.getResult() != Result.SUCCESS) {
+                    Log.d(CoreTestRunner.TAG, "Excluding test " + testDescription
+                            + " as it matches expectation: " + expectation);
+                    return false;
+                }
+            }
+        }
+
+        return true;
+    }
+
+    private Description getTestDescription(Description description) {
+        List<Description> children = description.getChildren();
+        // An empty description is by definition a test.
+        if (children.isEmpty()) {
+            return description;
+        }
+
+        // Handle initialization errors that were wrapped in an ErrorReportingRunner as a special
+        // case. This is needed because ErrorReportingRunner is treated as a suite of Throwables,
+        // (where each Throwable corresponds to a test called initializationError) and so its
+        // description contains children, one for each Throwable, and so is not treated as a test
+        // to filter. Unfortunately, it does not support Filterable so this filter is never applied
+        // to its children.
+        // See https://github.com/junit-team/junit/issues/1253
+        Description child = children.get(0);
+        String methodName = child.getMethodName();
+        if ("initializationError".equals(methodName)) {
+            return child;
+        }
+
+        return null;
+    }
+
+    @Override
+    public String describe() {
+        return "TestFilter";
+    }
+}
diff --git a/tests/core/runner/src/com/android/cts/core/runner/TestList.java b/tests/core/runner/src/com/android/cts/core/runner/TestList.java
new file mode 100644
index 0000000..4008d69
--- /dev/null
+++ b/tests/core/runner/src/com/android/cts/core/runner/TestList.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.core.runner;
+
+import android.util.Log;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+import javax.annotation.Nullable;
+
+/**
+ * A list of the tests to run.
+ */
+class TestList {
+
+    /**
+     * The names of the set of tests to run, if null then all tests should be run.
+     */
+    @Nullable
+    private final Set<String> testsToRun;
+
+    private final Collection<Class<?>> classesToRun;
+
+    public static TestList exclusiveList(List<String> testNameList) {
+        Set<String> classNamesToRun = new LinkedHashSet<>();
+        Set<String> testsToRun = new LinkedHashSet<>(testNameList);
+
+        for (String testName : testNameList) {
+            int index = testName.indexOf('#');
+            String className;
+            if (index == -1) {
+                className = testName;
+            } else {
+                className = testName.substring(0, index);
+            }
+            classNamesToRun.add(className);
+        }
+
+        Log.d(CoreTestRunner.TAG, "Running only the following tests: " + testsToRun);
+        return new TestList(getClasses(classNamesToRun), testsToRun);
+    }
+
+    public static TestList rootList(List<String> rootList) {
+
+        // Run from the root test class.
+        Set<String> classNamesToRun = new LinkedHashSet<>(rootList);
+        Log.d(CoreTestRunner.TAG, "Running all tests rooted at " + classNamesToRun);
+
+        List<Class<?>> classesToRun1 = getClasses(classNamesToRun);
+
+        return new TestList(classesToRun1, null);
+    }
+
+    private static List<Class<?>> getClasses(Set<String> classNames) {
+        // Populate the list of classes to run.
+        List<Class<?>> classesToRun = new ArrayList<>();
+        for (String className : classNames) {
+            try {
+                classesToRun.add(Class.forName(className));
+            } catch (ClassNotFoundException e) {
+                throw new IllegalStateException("Could not load class '" + className, e);
+            }
+        }
+        return classesToRun;
+    }
+
+    public static TestList classList(Collection<Class<?>> classes) {
+        return new TestList(classes, null);
+    }
+
+    /**
+     * @param classes The list of classes to run.
+     * @param testsToRun The exclusive set of tests to run or null if all tests reachable from the
+     */
+    private TestList(Collection<Class<?>> classes, Set<String> testsToRun) {
+        this.testsToRun = testsToRun;
+        this.classesToRun = classes;
+    }
+
+    /**
+     * Return all the classes to run.
+     */
+    public Class[] getClassesToRun() {
+        return classesToRun.toArray(new Class[classesToRun.size()]);
+    }
+
+    /**
+     * Return true if the test with the specified name should be run, false otherwise.
+     */
+    public boolean shouldRunTest(String testName) {
+        // If the tests aren't explicitly provided then run all tests by
+        // default, otherwise run only those tests explicitly listed by name.
+        return testsToRun == null || testsToRun.contains(testName);
+    }
+}
diff --git a/tests/core/runner/src/com/android/cts/core/runner/support/AndroidRunnerBuilder.java b/tests/core/runner/src/com/android/cts/core/runner/support/AndroidRunnerBuilder.java
new file mode 100644
index 0000000..91df2b9
--- /dev/null
+++ b/tests/core/runner/src/com/android/cts/core/runner/support/AndroidRunnerBuilder.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.core.runner.support;
+
+import android.support.test.internal.runner.junit3.AndroidJUnit3Builder;
+import android.support.test.internal.runner.junit3.AndroidSuiteBuilder;
+import android.support.test.internal.runner.junit4.AndroidAnnotatedBuilder;
+import android.support.test.internal.runner.junit4.AndroidJUnit4Builder;
+import android.support.test.internal.util.AndroidRunnerParams;
+
+import org.junit.internal.builders.AllDefaultPossibilitiesBuilder;
+import org.junit.internal.builders.AnnotatedBuilder;
+import org.junit.internal.builders.IgnoredBuilder;
+import org.junit.internal.builders.JUnit3Builder;
+import org.junit.internal.builders.JUnit4Builder;
+import org.junit.runners.model.RunnerBuilder;
+
+/**
+ * A {@link RunnerBuilder} that can handle all types of tests.
+ */
+// A copy of package private class android.support.test.internal.runner.AndroidRunnerBuilder.
+// Copied here so that it can be extended.
+class AndroidRunnerBuilder extends AllDefaultPossibilitiesBuilder {
+
+    private final AndroidJUnit3Builder mAndroidJUnit3Builder;
+    private final AndroidJUnit4Builder mAndroidJUnit4Builder;
+    private final AndroidSuiteBuilder mAndroidSuiteBuilder;
+    private final AndroidAnnotatedBuilder mAndroidAnnotatedBuilder;
+    // TODO: customize for Android ?
+    private final IgnoredBuilder mIgnoredBuilder;
+
+    /**
+     * @param runnerParams {@link AndroidRunnerParams} that stores common runner parameters
+     */
+    // Added canUseSuiteMethod parameter.
+    AndroidRunnerBuilder(AndroidRunnerParams runnerParams, boolean canUseSuiteMethod) {
+        super(canUseSuiteMethod);
+        mAndroidJUnit3Builder = new AndroidJUnit3Builder(runnerParams);
+        mAndroidJUnit4Builder = new AndroidJUnit4Builder(runnerParams);
+        mAndroidSuiteBuilder = new AndroidSuiteBuilder(runnerParams);
+        mAndroidAnnotatedBuilder = new AndroidAnnotatedBuilder(this, runnerParams);
+        mIgnoredBuilder = new IgnoredBuilder();
+    }
+
+    @Override
+    protected JUnit4Builder junit4Builder() {
+        return mAndroidJUnit4Builder;
+    }
+
+    @Override
+    protected JUnit3Builder junit3Builder() {
+        return mAndroidJUnit3Builder;
+    }
+
+    @Override
+    protected AnnotatedBuilder annotatedBuilder() {
+        return mAndroidAnnotatedBuilder;
+    }
+
+    @Override
+    protected IgnoredBuilder ignoredBuilder() {
+        return mIgnoredBuilder;
+    }
+
+    @Override
+    protected RunnerBuilder suiteMethodBuilder() {
+        return mAndroidSuiteBuilder;
+    }
+}
diff --git a/tests/core/runner/src/com/android/cts/core/runner/support/ExtendedAndroidAnnotatedBuilder.java b/tests/core/runner/src/com/android/cts/core/runner/support/ExtendedAndroidAnnotatedBuilder.java
new file mode 100644
index 0000000..05c6623
--- /dev/null
+++ b/tests/core/runner/src/com/android/cts/core/runner/support/ExtendedAndroidAnnotatedBuilder.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.core.runner.support;
+
+import android.support.test.internal.runner.junit4.AndroidAnnotatedBuilder;
+import android.support.test.internal.util.AndroidRunnerParams;
+import android.support.test.runner.AndroidJUnit4;
+import junit.framework.TestCase;
+import org.junit.runner.RunWith;
+import org.junit.runner.Runner;
+import org.junit.runners.BlockJUnit4ClassRunner;
+import org.junit.runners.JUnit4;
+import org.junit.runners.model.RunnerBuilder;
+
+/**
+ * Extends {@link AndroidAnnotatedBuilder} to add support for passing the
+ * {@link AndroidRunnerParams} object to the constructor of any {@link RunnerBuilder}
+ * implementation that is not a {@link BlockJUnit4ClassRunner}.
+ *
+ * <p>If {@link AndroidRunnerParams#isSkipExecution()} is {@code true} the super class will create
+ * a {@link RunnerBuilder} that will fire appropriate events as if the tests are being run but will
+ * not actually run the test. Unfortunately, when it does that it appears to assume that the runner
+ * extends {@link BlockJUnit4ClassRunner}, returns a skipping {@link RunnerBuilder} appropriate for
+ * that and ignores the actual {@code runnerClass}. That is a problem because it will not work for
+ * custom {@link RunnerBuilder} instances that do not extend {@link BlockJUnit4ClassRunner}.
+ *
+ * <p>Therefore, when skipping execution this does some additional checks to make sure that the
+ * {@code runnerClass} does extend {@link BlockJUnit4ClassRunner} before calling the overridden
+ * method.
+ *
+ * <p>It then attempts to construct a {@link RunnerBuilder} by calling the constructor with the
+ * signature {@code <init>(Class, AndroidRunnerParams)}. If that doesn't exist it falls back to
+ * the overridden behavior.
+ */
+class ExtendedAndroidAnnotatedBuilder extends AndroidAnnotatedBuilder {
+
+    private final AndroidRunnerParams runnerParams;
+
+    public ExtendedAndroidAnnotatedBuilder(RunnerBuilder suiteBuilder,
+            AndroidRunnerParams runnerParams) {
+        super(suiteBuilder, runnerParams);
+        this.runnerParams = runnerParams;
+    }
+
+    @Override
+    public Runner runnerForClass(Class<?> testClass) throws Exception {
+
+        RunWith annotation = testClass.getAnnotation(RunWith.class);
+        if (annotation != null) {
+            Class<? extends Runner> runnerClass = annotation.value();
+
+            // If the runner is expected to skip execution and it is a JUnit4, AndroidJUnit4 or
+            // a JUnit3 test class then return a special skipping runner.
+            if (runnerParams.isSkipExecution()) {
+                if (runnerClass == AndroidJUnit4.class || runnerClass == JUnit4.class
+                        || TestCase.class.isAssignableFrom(testClass)) {
+                    return super.runnerForClass(testClass);
+                }
+            }
+
+            try {
+                // try to build an AndroidJUnit4 runner
+                Runner runner = buildAndroidRunner(runnerClass, testClass);
+                if (runner != null) {
+                    return runner;
+                }
+            } catch (NoSuchMethodException e) {
+                // let the super class handle the error for us and throw an InitializationError
+                // exception.
+                return super.buildRunner(runnerClass, testClass);
+            }
+        }
+
+        return null;
+    }
+}
diff --git a/tests/core/runner/src/com/android/cts/core/runner/support/ExtendedAndroidRunnerBuilder.java b/tests/core/runner/src/com/android/cts/core/runner/support/ExtendedAndroidRunnerBuilder.java
new file mode 100644
index 0000000..1f76922
--- /dev/null
+++ b/tests/core/runner/src/com/android/cts/core/runner/support/ExtendedAndroidRunnerBuilder.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.core.runner.support;
+
+import android.support.test.internal.runner.junit4.AndroidAnnotatedBuilder;
+import android.support.test.internal.util.AndroidRunnerParams;
+import org.junit.internal.builders.AnnotatedBuilder;
+import org.junit.runners.model.RunnerBuilder;
+
+/**
+ * Extends {@link AndroidRunnerBuilder} in order to provide alternate {@link RunnerBuilder}
+ * implementations.
+ */
+public class ExtendedAndroidRunnerBuilder extends AndroidRunnerBuilder {
+
+    private final AndroidAnnotatedBuilder mAndroidAnnotatedBuilder;
+
+    /**
+     * @param runnerParams {@link AndroidRunnerParams} that stores common runner parameters
+     */
+    public ExtendedAndroidRunnerBuilder(AndroidRunnerParams runnerParams) {
+        super(runnerParams, false /* CTSv1 filtered out Test suite() classes. */);
+        mAndroidAnnotatedBuilder = new ExtendedAndroidAnnotatedBuilder(this, runnerParams);
+    }
+
+    @Override
+    protected AnnotatedBuilder annotatedBuilder() {
+        return mAndroidAnnotatedBuilder;
+    }
+}
diff --git a/tests/core/runner/src/com/android/cts/core/runner/support/package-info.java b/tests/core/runner/src/com/android/cts/core/runner/support/package-info.java
new file mode 100644
index 0000000..3ccec3c
--- /dev/null
+++ b/tests/core/runner/src/com/android/cts/core/runner/support/package-info.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Contains all the changes needed to the {@code android.support.test.internal.runner} classes.
+ *
+ * <p>As its name suggests {@code android.support.test.internal.runner} are internal classes that
+ * are not designed to be extended from outside those packages. This package encapsulates all the
+ * workarounds needed to overcome that limitation, from duplicating classes to using reflection.
+ * The intention is that these changes are temporary and they (or a better equivalent) will be
+ * quickly integrated into the internal classes.
+ */
+package com.android.cts.core.runner.support;
diff --git a/tests/deviceadmin/Android.mk b/tests/deviceadmin/Android.mk
index 2e89d34..3d02f9c 100644
--- a/tests/deviceadmin/Android.mk
+++ b/tests/deviceadmin/Android.mk
@@ -1,4 +1,4 @@
-# Copyright (C) 2011 The Android Open Source Project
+# Copyright (C) 2016 The Android Open 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,20 +14,4 @@
 
 LOCAL_PATH:= $(call my-dir)
 
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-
-LOCAL_JAVA_LIBRARIES := guava
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_PACKAGE_NAME := CtsDeviceAdmin
-
-LOCAL_SDK_VERSION := current
-
-LOCAL_DEX_PREOPT := false
-
-include $(BUILD_CTS_SUPPORT_PACKAGE)
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/deviceadmin/AndroidManifest.xml b/tests/deviceadmin/AndroidManifest.xml
deleted file mode 100644
index f70a677..0000000
--- a/tests/deviceadmin/AndroidManifest.xml
+++ /dev/null
@@ -1,113 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="android.deviceadmin.cts">
-    <application>
-
-        <uses-library android:name="android.test.runner"/>
-
-        <receiver android:name="android.deviceadmin.cts.CtsDeviceAdminReceiver"
-                android:permission="android.permission.BIND_DEVICE_ADMIN">
-            <meta-data android:name="android.app.device_admin"
-                    android:resource="@xml/device_admin" />
-            <intent-filter>
-                <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
-            </intent-filter>
-        </receiver>
-        
-        <receiver android:name="android.deviceadmin.cts.CtsDeviceAdminReceiver2"
-                android:permission="android.permission.BIND_DEVICE_ADMIN">
-            <meta-data android:name="android.app.device_admin"
-                    android:resource="@xml/device_admin_2" />
-            <intent-filter>
-                <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
-            </intent-filter>
-        </receiver>
-
-        <!-- Device Admin that needs to be in the deactivated state in order
-             for tests to pass. -->
-        <receiver android:name="android.deviceadmin.cts.CtsDeviceAdminDeactivatedReceiver"
-                android:permission="android.permission.BIND_DEVICE_ADMIN">
-            <meta-data android:name="android.app.device_admin"
-                    android:resource="@xml/device_admin" />
-            <intent-filter>
-                <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
-            </intent-filter>
-        </receiver>
-
-        <!-- Helper Activity used by Device Admin activation tests -->
-        <activity android:name="android.deviceadmin.cts.CtsDeviceAdminActivationTestActivity"
-                android:label="Device Admin activation test" />
-
-        <!-- Broken device admin: meta-data missing -->
-        <receiver android:name="android.deviceadmin.cts.CtsDeviceAdminBrokenReceiver"
-                android:permission="android.permission.BIND_DEVICE_ADMIN">
-            <intent-filter>
-                <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
-            </intent-filter>
-        </receiver>
-
-        <!-- Broken device admin: filter doesn't match an Intent with action
-             android.app.action.DEVICE_ADMIN_ENABLED and nothing else (e.g.,
-             data) set -->
-        <receiver android:name="android.deviceadmin.cts.CtsDeviceAdminBrokenReceiver2"
-                android:permission="android.permission.BIND_DEVICE_ADMIN">
-            <meta-data android:name="android.app.device_admin"
-                    android:resource="@xml/device_admin" />
-            <intent-filter>
-                <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
-                <data android:scheme="https" />
-            </intent-filter>
-        </receiver>
-
-        <!-- Broken device admin: meta-data element doesn't point to valid
-             Device Admin configuration/description -->
-        <receiver android:name="android.deviceadmin.cts.CtsDeviceAdminBrokenReceiver3"
-                android:permission="android.permission.BIND_DEVICE_ADMIN">
-            <meta-data android:name="android.app.device_admin"
-                    android:resource="@xml/broken_device_admin" />
-            <intent-filter>
-                <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
-            </intent-filter>
-        </receiver>
-
-        <!-- Broken device admin: filter doesn't match Intents with action
-             android.app.action.DEVICE_ADMIN_ENABLED -->
-        <receiver android:name="android.deviceadmin.cts.CtsDeviceAdminBrokenReceiver4"
-                android:permission="android.permission.BIND_DEVICE_ADMIN">
-            <meta-data android:name="android.app.device_admin"
-                    android:resource="@xml/device_admin" />
-            <intent-filter>
-                <action android:name="android.app.action.DEVICE_ADMIN_DISABLED" />
-            </intent-filter>
-        </receiver>
-
-        <!-- Broken device admin: no intent-filter -->
-        <receiver android:name="android.deviceadmin.cts.CtsDeviceAdminBrokenReceiver5"
-                android:permission="android.permission.BIND_DEVICE_ADMIN">
-            <meta-data android:name="android.app.device_admin"
-                    android:resource="@xml/device_admin" />
-        </receiver>
-
-    </application>
-
-    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-            android:targetPackage="com.android.cts.admin"
-            android:label="Tests for the device admin APIs."/>
-</manifest>
diff --git a/tests/deviceadmin/deviceadminapp/Android.mk b/tests/deviceadmin/deviceadminapp/Android.mk
new file mode 100644
index 0000000..29c7cb3
--- /dev/null
+++ b/tests/deviceadmin/deviceadminapp/Android.mk
@@ -0,0 +1,34 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := CtsEmptyDeviceAdmin
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_RESOURCE_DIR += $(LOCAL_PATH)/res
+
+LOCAL_SDK_VERSION := current
+
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+include $(BUILD_PACKAGE)
diff --git a/tests/deviceadmin/deviceadminapp/AndroidManifest.xml b/tests/deviceadmin/deviceadminapp/AndroidManifest.xml
new file mode 100644
index 0000000..9ce61a6
--- /dev/null
+++ b/tests/deviceadmin/deviceadminapp/AndroidManifest.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="android.devicepolicy.cts.emptydeviceadmin" >
+
+    <uses-sdk android:minSdkVersion="23" android:targetSdkVersion="24"/>
+
+    <application>
+        <receiver
+                android:name=".EmptyDeviceAdmin"
+                android:permission="android.permission.BIND_DEVICE_ADMIN"
+                >
+            <meta-data android:name="android.app.device_admin"
+                    android:resource="@xml/device_admin" />
+            <intent-filter>
+                <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
+            </intent-filter>
+        </receiver>
+    </application>
+</manifest>
diff --git a/tests/deviceadmin/deviceadminapp/res/xml/device_admin.xml b/tests/deviceadmin/deviceadminapp/res/xml/device_admin.xml
new file mode 100644
index 0000000..c601371
--- /dev/null
+++ b/tests/deviceadmin/deviceadminapp/res/xml/device_admin.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<device-admin xmlns:android="http://schemas.android.com/apk/res/android" android:visible="false">
+    <uses-policies>
+        <limit-password />
+        <watch-login />
+        <reset-password />
+        <force-lock />
+        <wipe-data />
+        <expire-password />
+        <encrypted-storage />
+        <disable-camera />
+        <disable-keyguard-features />
+    </uses-policies>
+</device-admin>
diff --git a/tests/deviceadmin/deviceadminapp/src/android/devicepolicy/cts/emptydeviceadmin/EmptyDeviceAdmin.java b/tests/deviceadmin/deviceadminapp/src/android/devicepolicy/cts/emptydeviceadmin/EmptyDeviceAdmin.java
new file mode 100644
index 0000000..82339ef
--- /dev/null
+++ b/tests/deviceadmin/deviceadminapp/src/android/devicepolicy/cts/emptydeviceadmin/EmptyDeviceAdmin.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.devicepolicy.cts.emptydeviceadmin;
+
+import android.app.admin.DeviceAdminReceiver;
+
+public class EmptyDeviceAdmin extends DeviceAdminReceiver {
+}
diff --git a/tests/deviceadmin/src/android/deviceadmin/cts/CtsDeviceAdminActivationTestActivity.java b/tests/deviceadmin/src/android/deviceadmin/cts/CtsDeviceAdminActivationTestActivity.java
deleted file mode 100644
index 1779ec8..0000000
--- a/tests/deviceadmin/src/android/deviceadmin/cts/CtsDeviceAdminActivationTestActivity.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.deviceadmin.cts;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.os.Bundle;
-import android.view.WindowManager;
-
-import com.google.common.annotations.VisibleForTesting;
-
-/**
- * Helper {@link Activity} for CTS tests of Device Admin activation. The {@code Activity}
- * enables tests to capture the invocations of its {@link #onActivityResult(int, int, Intent)} by
- * providing a {@link OnActivityResultListener}.
- */
-public class CtsDeviceAdminActivationTestActivity extends Activity {
-    public interface OnActivityResultListener {
-        void onActivityResult(int requestCode, int resultCode, Intent data);
-    }
-
-    private OnActivityResultListener mOnActivityResultListener;
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        // Dismiss keyguard and keep screen on while this Activity is displayed.
-        // This is needed because on older platforms, when the keyguard is on, onActivityResult is
-        // not invoked when a Device Admin activation is rejected without user interaction.
-        getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
-                | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
-                | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
-    }
-
-    @VisibleForTesting
-    public void setOnActivityResultListener(OnActivityResultListener listener) {
-        mOnActivityResultListener = listener;
-    }
-
-    @Override
-    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
-        if (mOnActivityResultListener != null) {
-            mOnActivityResultListener.onActivityResult(requestCode, resultCode, data);
-            return;
-        }
-
-        super.onActivityResult(requestCode, resultCode, data);
-    }
-}
diff --git a/tests/deviceadmin/src/android/deviceadmin/cts/CtsDeviceAdminBrokenReceiver.java b/tests/deviceadmin/src/android/deviceadmin/cts/CtsDeviceAdminBrokenReceiver.java
deleted file mode 100644
index f64c6b6..0000000
--- a/tests/deviceadmin/src/android/deviceadmin/cts/CtsDeviceAdminBrokenReceiver.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.deviceadmin.cts;
-
-import android.app.admin.DeviceAdminReceiver;
-
-public class CtsDeviceAdminBrokenReceiver extends DeviceAdminReceiver {
-}
diff --git a/tests/deviceadmin/src/android/deviceadmin/cts/CtsDeviceAdminBrokenReceiver2.java b/tests/deviceadmin/src/android/deviceadmin/cts/CtsDeviceAdminBrokenReceiver2.java
deleted file mode 100644
index 492a7cb..0000000
--- a/tests/deviceadmin/src/android/deviceadmin/cts/CtsDeviceAdminBrokenReceiver2.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.deviceadmin.cts;
-
-import android.app.admin.DeviceAdminReceiver;
-
-public class CtsDeviceAdminBrokenReceiver2 extends DeviceAdminReceiver {
-}
diff --git a/tests/deviceadmin/src/android/deviceadmin/cts/CtsDeviceAdminBrokenReceiver3.java b/tests/deviceadmin/src/android/deviceadmin/cts/CtsDeviceAdminBrokenReceiver3.java
deleted file mode 100644
index 92bc878..0000000
--- a/tests/deviceadmin/src/android/deviceadmin/cts/CtsDeviceAdminBrokenReceiver3.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.deviceadmin.cts;
-
-import android.app.admin.DeviceAdminReceiver;
-
-public class CtsDeviceAdminBrokenReceiver3 extends DeviceAdminReceiver {
-}
diff --git a/tests/deviceadmin/src/android/deviceadmin/cts/CtsDeviceAdminBrokenReceiver4.java b/tests/deviceadmin/src/android/deviceadmin/cts/CtsDeviceAdminBrokenReceiver4.java
deleted file mode 100644
index 53f15a7..0000000
--- a/tests/deviceadmin/src/android/deviceadmin/cts/CtsDeviceAdminBrokenReceiver4.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.deviceadmin.cts;
-
-import android.app.admin.DeviceAdminReceiver;
-
-public class CtsDeviceAdminBrokenReceiver4 extends DeviceAdminReceiver {
-}
diff --git a/tests/deviceadmin/src/android/deviceadmin/cts/CtsDeviceAdminBrokenReceiver5.java b/tests/deviceadmin/src/android/deviceadmin/cts/CtsDeviceAdminBrokenReceiver5.java
deleted file mode 100644
index 2dc7100..0000000
--- a/tests/deviceadmin/src/android/deviceadmin/cts/CtsDeviceAdminBrokenReceiver5.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.deviceadmin.cts;
-
-import android.app.admin.DeviceAdminReceiver;
-
-public class CtsDeviceAdminBrokenReceiver5 extends DeviceAdminReceiver {
-}
diff --git a/tests/deviceadmin/src/android/deviceadmin/cts/CtsDeviceAdminDeactivatedReceiver.java b/tests/deviceadmin/src/android/deviceadmin/cts/CtsDeviceAdminDeactivatedReceiver.java
deleted file mode 100644
index ec59f63..0000000
--- a/tests/deviceadmin/src/android/deviceadmin/cts/CtsDeviceAdminDeactivatedReceiver.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.deviceadmin.cts;
-
-import android.app.admin.DeviceAdminReceiver;
-
-public class CtsDeviceAdminDeactivatedReceiver extends DeviceAdminReceiver {
-}
diff --git a/tests/deviceadmin/src/android/deviceadmin/cts/CtsDeviceAdminReceiver.java b/tests/deviceadmin/src/android/deviceadmin/cts/CtsDeviceAdminReceiver.java
deleted file mode 100644
index 43485d7..0000000
--- a/tests/deviceadmin/src/android/deviceadmin/cts/CtsDeviceAdminReceiver.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.deviceadmin.cts;
-
-import android.app.admin.DeviceAdminReceiver;
-
-public class CtsDeviceAdminReceiver extends DeviceAdminReceiver {
-}
diff --git a/tests/deviceadmin/src/android/deviceadmin/cts/CtsDeviceAdminReceiver2.java b/tests/deviceadmin/src/android/deviceadmin/cts/CtsDeviceAdminReceiver2.java
deleted file mode 100644
index eadf31b..0000000
--- a/tests/deviceadmin/src/android/deviceadmin/cts/CtsDeviceAdminReceiver2.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.deviceadmin.cts;
-
-import android.app.admin.DeviceAdminReceiver;
-
-public class CtsDeviceAdminReceiver2 extends DeviceAdminReceiver {
-}
diff --git a/tests/deviceadmin/uninstalltest/Android.mk b/tests/deviceadmin/uninstalltest/Android.mk
new file mode 100644
index 0000000..03831e2
--- /dev/null
+++ b/tests/deviceadmin/uninstalltest/Android.mk
@@ -0,0 +1,34 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := CtsDeviceAdminUninstallerTestCases
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_STATIC_JAVA_LIBRARIES := ub-uiautomator android-support-test
+
+LOCAL_SDK_VERSION := current
+
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+include $(BUILD_PACKAGE)
diff --git a/tests/deviceadmin/uninstalltest/AndroidManifest.xml b/tests/deviceadmin/uninstalltest/AndroidManifest.xml
new file mode 100644
index 0000000..52a681a
--- /dev/null
+++ b/tests/deviceadmin/uninstalltest/AndroidManifest.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="android.devicepolicy.cts.uiautomatertest" >
+
+    <uses-sdk android:minSdkVersion="23" android:targetSdkVersion="24"/>
+
+    <application>
+        <uses-library android:name="android.test.runner"/>
+    </application>
+
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+          android:functionalTest="true"
+          android:targetPackage="android.devicepolicy.cts.uiautomatertest"
+          android:label="Device Admin Uninstall CTS tests"/>
+</manifest>
diff --git a/tests/deviceadmin/uninstalltest/AndroidTest.xml b/tests/deviceadmin/uninstalltest/AndroidTest.xml
new file mode 100644
index 0000000..51615f7
--- /dev/null
+++ b/tests/deviceadmin/uninstalltest/AndroidTest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for the CTS device admin uninstall tests">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsEmptyDeviceAdmin.apk" />
+        <option name="test-file-name" value="CtsDeviceAdminUninstallerTestCases.apk" />
+    </target_preparer>
+
+    <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+        <option name="run-command" value="dpm set-active-admin --user cur android.devicepolicy.cts.emptydeviceadmin/.EmptyDeviceAdmin" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.devicepolicy.cts.uiautomatertest" />
+    </test>
+
+</configuration>
\ No newline at end of file
diff --git a/tests/deviceadmin/uninstalltest/src/android/devicepolicy/cts/uiautomatertest/DeviceAdminUninstallTest.java b/tests/deviceadmin/uninstalltest/src/android/devicepolicy/cts/uiautomatertest/DeviceAdminUninstallTest.java
new file mode 100644
index 0000000..23b3755
--- /dev/null
+++ b/tests/deviceadmin/uninstalltest/src/android/devicepolicy/cts/uiautomatertest/DeviceAdminUninstallTest.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.devicepolicy.cts.uiautomatertest;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.net.Uri;
+import android.provider.Settings;
+import android.widget.ScrollView;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.List;
+
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.test.filters.LargeTest;
+import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.BySelector;
+import android.support.test.uiautomator.UiDevice;
+import android.support.test.uiautomator.UiObject;
+import android.support.test.uiautomator.UiObjectNotFoundException;
+import android.support.test.uiautomator.UiScrollable;
+import android.support.test.uiautomator.UiSelector;
+import android.support.test.uiautomator.Until;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class DeviceAdminUninstallTest {
+
+    private static final String DEVICE_ADMIN_PACKAGE_NAME =
+            "android.devicepolicy.cts.emptydeviceadmin";
+    private static final String URI_PACKAGE_PREFIX = "package:";
+
+    private static final UiSelector DEACTIVATE_AND_UNINSTALL_BUTTON_SELECTOR = new UiSelector()
+            .resourceId("com.android.settings:id/action_button");
+    private static final UiSelector UNINSTALL_BUTTON_SELECTOR = new UiSelector()
+            .resourceId("com.android.settings:id/left_button");
+    private static final BySelector UNINSTALL_BUTTON_BYSELECTOR = By
+            .res("com.android.settings", "left_button");
+    private static final UiSelector OK_BUTTON_SELECTOR = new UiSelector()
+            .resourceId("android:id/button1");
+    private static final long DEACTIVATE_ADMIN_TIMEOUT = 15000;
+    private static final long WAIT_FOR_ACTIVITY_TIMEOUT = 6000;
+
+    private UiDevice mUiDevice;
+    private Context mContext;
+    private DevicePolicyManager mDpm;
+    private PackageManager mPm;
+
+    @Before
+    public void setUp() throws Exception {
+        mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
+        mContext = InstrumentationRegistry.getTargetContext();
+        mDpm = mContext.getSystemService(DevicePolicyManager.class);
+        mPm = mContext.getPackageManager();
+    }
+
+    private boolean hasActiveAdmin() {
+        final List<ComponentName> activeAdmins = mDpm.getActiveAdmins();
+        if (activeAdmins == null) {
+            return false;
+        }
+        for (ComponentName activeAdmin : activeAdmins) {
+            if (DEVICE_ADMIN_PACKAGE_NAME.equals(activeAdmin.getPackageName())) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private void waitTillNoActiveAdmin() {
+        boolean interrupted = false;
+        final long timeOut = System.currentTimeMillis() + DEACTIVATE_ADMIN_TIMEOUT;
+        while (hasActiveAdmin() && System.currentTimeMillis() <= timeOut) {
+            try {
+                Thread.sleep(2500);
+            } catch (InterruptedException err) {
+                interrupted = true;
+            }
+        }
+        if (interrupted) {
+            Thread.currentThread().interrupt();
+        }
+        Assert.assertFalse(
+                "Package " + DEVICE_ADMIN_PACKAGE_NAME + " still has an active device admin",
+                hasActiveAdmin());
+    }
+
+    private boolean packageExists() {
+        PackageInfo packageInfo = null;
+        try {
+            packageInfo = mPm.getPackageInfo(DEVICE_ADMIN_PACKAGE_NAME, 0);
+        } catch (NameNotFoundException exc) {
+        }
+        return packageInfo != null;
+    }
+
+    private void launchApplicationDetailsActivity() {
+        final Uri packageURI = Uri.parse(URI_PACKAGE_PREFIX + DEVICE_ADMIN_PACKAGE_NAME);
+        final Intent displayAppDetailsIntent = new Intent(
+                Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
+                packageURI);
+        displayAppDetailsIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        mContext.startActivity(displayAppDetailsIntent);
+    }
+
+    private void automateUninstallThroughUi() {
+        StringBuilder failMessageBuilder = new StringBuilder();
+        UiObject uninstallButton = mUiDevice
+                .findObject(UNINSTALL_BUTTON_SELECTOR);
+        UiScrollable scrollable = new UiScrollable(new UiSelector().className(ScrollView.class));
+        UiObject deactivateButton = mUiDevice
+                .findObject(DEACTIVATE_AND_UNINSTALL_BUTTON_SELECTOR);
+        UiObject okButton = mUiDevice
+                .findObject(OK_BUTTON_SELECTOR);
+        mUiDevice.wait(Until.hasObject(UNINSTALL_BUTTON_BYSELECTOR), WAIT_FOR_ACTIVITY_TIMEOUT);
+        try {
+            uninstallButton.clickAndWaitForNewWindow();
+            scrollable.scrollIntoView(DEACTIVATE_AND_UNINSTALL_BUTTON_SELECTOR);
+            deactivateButton.clickAndWaitForNewWindow();
+            waitTillNoActiveAdmin();
+            okButton.clickAndWaitForNewWindow();
+        } catch (UiObjectNotFoundException exc) {
+            failMessageBuilder.append(exc.getMessage());
+        } finally {
+            Assert.assertFalse(
+                    "Package " + DEVICE_ADMIN_PACKAGE_NAME + " was not uninstalled.\n"
+                    + failMessageBuilder.toString(), packageExists());
+        }
+    }
+
+    @Test
+    public void uninstallPackageWithActiveAdmin() {
+        Assert.assertTrue("Package " + DEVICE_ADMIN_PACKAGE_NAME + " was not found installed",
+                packageExists());
+        Assert.assertTrue("Package " + DEVICE_ADMIN_PACKAGE_NAME
+                + " does not have any active admin component", hasActiveAdmin());
+        launchApplicationDetailsActivity();
+        automateUninstallThroughUi();
+    }
+}
diff --git a/tests/dram/Android.mk b/tests/dram/Android.mk
new file mode 100644
index 0000000..8997003
--- /dev/null
+++ b/tests/dram/Android.mk
@@ -0,0 +1,39 @@
+# Copyright (C) 2012 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+# don't include this package in any target
+LOCAL_MODULE_TAGS := tests
+
+# Include both the 32 and 64 bit versions
+LOCAL_MULTILIB := both
+
+LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil compatibility-device-util ctstestrunner
+
+LOCAL_JNI_SHARED_LIBRARIES := libctsdram_jni
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := CtsDramTestCases
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_SDK_VERSION := 16
+
+include $(BUILD_CTS_PACKAGE)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/dram/AndroidManifest.xml b/tests/dram/AndroidManifest.xml
new file mode 100644
index 0000000..d43fe79
--- /dev/null
+++ b/tests/dram/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="android.dram.cts">
+
+    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+            android:targetPackage="android.dram.cts"
+            android:label="DRAM bandwidth measurement" />
+</manifest>
diff --git a/tests/dram/AndroidTest.xml b/tests/dram/AndroidTest.xml
new file mode 100644
index 0000000..019c15d
--- /dev/null
+++ b/tests/dram/AndroidTest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS Dram test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsDramTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.dram.cts" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/suite/cts/deviceTests/dram/jni/Android.mk b/tests/dram/jni/Android.mk
similarity index 100%
rename from suite/cts/deviceTests/dram/jni/Android.mk
rename to tests/dram/jni/Android.mk
diff --git a/tests/dram/jni/MemoryNativeJni.cpp b/tests/dram/jni/MemoryNativeJni.cpp
new file mode 100644
index 0000000..cbf145c
--- /dev/null
+++ b/tests/dram/jni/MemoryNativeJni.cpp
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 <jni.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/time.h>
+
+double currentTimeMillis()
+{
+    struct timeval tv;
+    gettimeofday(&tv, (struct timezone *) NULL);
+    return tv.tv_sec * 1000.0 + tv.tv_usec / 1000.0;
+}
+
+extern "C" JNIEXPORT jdouble JNICALL Java_android_dram_cts_MemoryNative_runMemcpy(JNIEnv* env,
+        jclass clazz, jint bufferSize, jint repetition)
+{
+    char* src = new char[bufferSize];
+    char* dst = new char[bufferSize];
+    if ((src == NULL) || (dst == NULL)) {
+        delete[] src;
+        delete[] dst;
+        env->ThrowNew(env->FindClass("java/lang/OutOfMemoryError"), "No memory");
+        return -1;
+    }
+    memset(src, 0, bufferSize);
+    memset(dst, 0, bufferSize);
+    double start = currentTimeMillis();
+    for (int i = 0; i < repetition; i++) {
+        memcpy(dst, src, bufferSize);
+        src[bufferSize - 1] = i & 0xff;
+    }
+    double end = currentTimeMillis();
+    delete[] src;
+    delete[] dst;
+    return end - start;
+}
+
+extern "C" JNIEXPORT jdouble JNICALL Java_android_dram_cts_MemoryNative_runMemset(JNIEnv* env,
+        jclass clazz, jint bufferSize, jint repetition, jint c)
+{
+    char* dst = new char[bufferSize];
+    if (dst == NULL) {
+        delete[] dst;
+        env->ThrowNew(env->FindClass("java/lang/OutOfMemoryError"), "No memory");
+        return -1;
+    }
+    memset(dst, 0, bufferSize);
+    double start = currentTimeMillis();
+    for (int i = 0; i < repetition; i++) {
+        memset(dst, (c + i) & 0xff, bufferSize);
+    }
+    double end = currentTimeMillis();
+    delete[] dst;
+    return end - start;
+}
+
diff --git a/tests/dram/src/android/dram/cts/BandwidthTest.java b/tests/dram/src/android/dram/cts/BandwidthTest.java
new file mode 100644
index 0000000..2096402
--- /dev/null
+++ b/tests/dram/src/android/dram/cts/BandwidthTest.java
@@ -0,0 +1,225 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.dram.cts;
+
+import android.content.Context;
+import android.cts.util.CtsAndroidTestCase;
+import android.graphics.Point;
+import android.util.Log;
+import android.view.WindowManager;
+
+import com.android.compatibility.common.util.DeviceReportLog;
+import com.android.compatibility.common.util.ResultType;
+import com.android.compatibility.common.util.ResultUnit;
+import com.android.compatibility.common.util.Stat;
+
+/**
+ * check how many screens the memcpy function can copy in a sec.
+ * Note that this does not represent the total memory bandwidth available in the system
+ * as typically CPU cannot use the whole bandwidth.
+ * Smaller buffers can fit into L1 or L2 cache, which can show big boost.
+ */
+public class BandwidthTest extends CtsAndroidTestCase {
+    private static final String TAG = BandwidthTest.class.getSimpleName();
+    private static final int MEMCPY_REPETITION = 10;
+    private static final int MEMSET_REPETITION = 30;
+    private static final int REPEAT_IN_EACH_CALL = 100;
+    private static final int KB = 1024;
+    private static final int MB = 1024 * 1024;
+    private static final int MEMSET_CHAR = 0xa5;
+    // reject data outside +/- this value * median
+    private static final double OUTLIER_THRESHOLD = 0.1;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        // warm-up
+        MemoryNative.runMemcpy(2 * MB, 100);
+    }
+
+    public void testMemcpyK004() {
+        doRunMemcpy(4 * KB);
+    }
+
+    public void testMemcpyK008() {
+        doRunMemcpy(8 * KB);
+    }
+
+    public void testMemcpyK016() {
+        doRunMemcpy(16 * KB);
+    }
+
+    public void testMemcpyK032() {
+        doRunMemcpy(32 * KB);
+    }
+
+    public void testMemcpyK064() {
+        doRunMemcpy(64 * KB);
+    }
+
+    public void testMemcpyK128() {
+        doRunMemcpy(128 * KB);
+    }
+
+    public void testMemcpyK256() {
+        doRunMemcpy(256 * KB);
+    }
+
+    public void testMemcpyK512() {
+        doRunMemcpy(512 * KB);
+    }
+
+    public void testMemcpyM001() {
+        doRunMemcpy(1 * MB);
+    }
+
+    public void testMemcpyM002() {
+        doRunMemcpy(2 * MB);
+    }
+
+    public void testMemcpyM004() {
+        doRunMemcpy(4 * MB);
+    }
+
+    public void testMemcpyM008() {
+        doRunMemcpy(8 * MB);
+    }
+
+    public void testMemcpyM016() {
+        doRunMemcpy(16 * MB);
+    }
+
+    public void testMemsetK004() {
+        doRunMemset(4 * KB);
+    }
+
+    public void testMemsetK008() {
+        doRunMemset(8 * KB);
+    }
+
+    public void testMemsetK016() {
+        doRunMemset(16 * KB);
+    }
+
+    public void testMemsetK032() {
+        doRunMemset(32 * KB);
+    }
+
+    public void testMemsetK064() {
+        doRunMemset(64 * KB);
+    }
+
+    public void testMemsetK128() {
+        doRunMemset(128 * KB);
+    }
+
+    public void testMemsetK256() {
+        doRunMemset(256 * KB);
+    }
+
+    public void testMemsetK512() {
+        doRunMemset(512 * KB);
+    }
+
+    public void testMemsetM001() {
+        doRunMemset(1 * MB);
+    }
+
+    public void testMemsetM002() {
+        doRunMemset(2 * MB);
+    }
+
+    public void testMemsetM004() {
+        doRunMemset(4 * MB);
+    }
+
+    public void testMemsetM008() {
+        doRunMemset(8 * MB);
+    }
+
+    public void testMemsetM016() {
+        doRunMemset(16 * MB);
+    }
+
+    private void doRunMemcpy(int bufferSize) {
+        double[] result = new double[MEMCPY_REPETITION];
+        int repeatInEachCall = REPEAT_IN_EACH_CALL;
+        if (bufferSize < (1 * MB)) {
+            // too small buffer size finishes too early to give accurate result.
+            repeatInEachCall *= (1 * MB / bufferSize);
+        }
+        for (int i = 0; i < MEMCPY_REPETITION; i++) {
+            result[i] = MemoryNative.runMemcpy(bufferSize, repeatInEachCall);
+        }
+        DeviceReportLog report = new DeviceReportLog();
+        report.addValues("memcpy time", result, ResultType.LOWER_BETTER,
+                ResultUnit.MS);
+        double[] mbps = Stat.calcRatePerSecArray(
+                (double)bufferSize * repeatInEachCall / 1024.0 / 1024.0, result);
+        report.addValues("memcpy throughput", mbps, ResultType.HIGHER_BETTER,
+                ResultUnit.MBPS);
+        Stat.StatResult stat = Stat.getStatWithOutlierRejection(mbps, OUTLIER_THRESHOLD);
+        if (stat.mDataCount != result.length) {
+            Log.w(TAG, "rejecting " + (result.length - stat.mDataCount) + " outliers");
+        }
+        WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
+        Point size = new Point();
+        wm.getDefaultDisplay().getSize(size);
+        Log.i(TAG, " x " + size.x + " y " + size.y);
+        double pixels = size.x * size.y;
+        // now this represents how many times the whole screen can be copied in a sec.
+        double screensPerSecAverage = stat.mAverage / pixels * 1024.0 * 1024.0 / 4.0;
+        report.addValue("memcpy in fps", screensPerSecAverage,
+                ResultType.HIGHER_BETTER, ResultUnit.FPS);
+        report.setSummary("memcpy throughput", stat.mAverage, ResultType.HIGHER_BETTER,
+                ResultUnit.MBPS);
+        report.submit(getInstrumentation());
+    }
+
+    private void doRunMemset(int bufferSize) {
+        double[] result = new double[MEMSET_REPETITION];
+        int repeatInEachCall = REPEAT_IN_EACH_CALL;
+        if (bufferSize < (1 * MB)) {
+            // too small buffer size finishes too early to give accurate result.
+            repeatInEachCall *= (1 * MB / bufferSize);
+        }
+        for (int i = 0; i < MEMSET_REPETITION; i++) {
+            result[i] = MemoryNative.runMemset(bufferSize, repeatInEachCall, MEMSET_CHAR);
+        }
+        DeviceReportLog report = new DeviceReportLog();
+        report.addValues("memset time", result, ResultType.LOWER_BETTER, ResultUnit.MS);
+        double[] mbps = Stat.calcRatePerSecArray(
+                (double)bufferSize * repeatInEachCall / 1024.0 / 1024.0, result);
+        report.addValues("memset throughput", mbps, ResultType.HIGHER_BETTER, ResultUnit.MBPS);
+        Stat.StatResult stat = Stat.getStatWithOutlierRejection(mbps, OUTLIER_THRESHOLD);
+        if (stat.mDataCount != result.length) {
+            Log.w(TAG, "rejecting " + (result.length - stat.mDataCount) + " outliers");
+        }
+        WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
+        Point size = new Point();
+        wm.getDefaultDisplay().getSize(size);
+        Log.i(TAG, " x " + size.x + " y " + size.y);
+        double pixels = size.x * size.y;
+        // now this represents how many times the whole screen can be copied in a sec.
+        double screensPerSecAverage = stat.mAverage / pixels * 1024.0 * 1024.0 / 4.0;
+        report.addValue("memset in fps", screensPerSecAverage,
+                ResultType.HIGHER_BETTER, ResultUnit.FPS);
+        report.setSummary("memset throughput", stat.mAverage, ResultType.HIGHER_BETTER,
+                ResultUnit.MBPS);
+        report.submit(getInstrumentation());
+    }
+}
diff --git a/tests/dram/src/android/dram/cts/MemoryNative.java b/tests/dram/src/android/dram/cts/MemoryNative.java
new file mode 100644
index 0000000..7fa4c46
--- /dev/null
+++ b/tests/dram/src/android/dram/cts/MemoryNative.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.dram.cts;
+
+public class MemoryNative {
+    static {
+        System.loadLibrary("ctsdram_jni");
+    }
+    /**
+     * run memcpy for given number of repetition from a source to a destination buffers
+     * with each having the size of bufferSize.
+     * @param bufferSize
+     * @param repetition
+     * @return time spent in copying in ms.
+     */
+    public static native double runMemcpy(int bufferSize, int repetition);
+
+    /**
+     * run memset for given number of repetition from a source to a destination buffers
+     * with each having the size of bufferSize.
+     * @param bufferSize
+     * @param repetition
+     * @param c char to set. Only LSBs will be used to get char value.
+     * @return time spent in memset in ms.
+     */
+    public static native double runMemset(int bufferSize, int repetition, int c);
+}
diff --git a/tests/expectations/knownfailures.txt b/tests/expectations/knownfailures.txt
index 3f966bb..3f84aa2 100644
--- a/tests/expectations/knownfailures.txt
+++ b/tests/expectations/knownfailures.txt
@@ -201,20 +201,6 @@
   bug: 18030049
 },
 {
-  description: "The new recording test is not yet passing on all devices",
-  names: [
-    "android.hardware.camera2.cts.RecordingTest#testRecordingFramerateLowToHigh"
-  ],
-  bug: 18705837
-},
-{
-  description: "The new image reader test is not yet passing on all devices",
-  names: [
-    "android.hardware.camera2.cts.ImageReaderTest#testAllOutputYUVResolutions"
-  ],
-  bug: 18689511
-},
-{
   description: "The new prepare performance test is not yet passing on all devices",
   names: [
     "android.hardware.camera2.cts.SurfaceViewPreviewTest#testPreparePerformance"
@@ -222,14 +208,6 @@
   bug: 17989532
 },
 {
-  description: "The new long processing test is not yet passing on all devices",
-  names: [
-    "android.hardware.camera2.cts.ImageReaderTest#testLongProcessingRepeatingRaw",
-    "android.hardware.camera2.cts.ImageReaderTest#testLongProcessingRepeatingFlexibleYuv"
-  ],
-  bug: 22861512
-},
-{
   description: "The timing measurements for preview callbacks are not reliable",
   names: [
     "android.hardware.cts.CameraTest#testPreviewFpsRange"
@@ -239,7 +217,7 @@
 {
   description: "Light status bar CTS coming in late",
   names: [
-    "com.android.cts.systemui.LightStatusBarTests#testLightStatusBarIcons"
+    "android.systemui.cts.LightStatusBarTests#testLightStatusBarIcons"
   ],
   bug: 23427621
 },
@@ -337,18 +315,18 @@
   bug: 25651805
 },
 {
-  description: "Read from invalid parcel not working",
+  description: "unit testing for MediaPreparer lives within mediastress module",
   names: [
-    "android.view.cts.MotionEventTest#testReadFromParcelWithInvalidSampleSize"
+    "android.mediastress.cts.preconditions.MediaPreparerTest"
   ],
-  bug: 25652250
+  bug: 25850508
 },
 {
-  description: "Wired headset tests are no longer a requirement per CDD",
+  description: "Tests for the signature tests should not be in CTS",
   names: [
-    "android.telecom.cts.WiredHeadsetTest"
+    "android.signature.cts.tests"
   ],
-  bug: 26149528
+  bug: 26150806
 },
 {
   description: "android.security.cts is using a Non-NDK library, libmedia_jni.so",
diff --git a/tests/filesystem/Android.mk b/tests/filesystem/Android.mk
new file mode 100644
index 0000000..bf88148
--- /dev/null
+++ b/tests/filesystem/Android.mk
@@ -0,0 +1,33 @@
+# Copyright (C) 2012 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+# don't include this package in any target
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil compatibility-device-util ctstestrunner
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := CtsFileSystemTestCases
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_SDK_VERSION := 16
+
+include $(BUILD_CTS_PACKAGE)
+
diff --git a/tests/filesystem/AndroidManifest.xml b/tests/filesystem/AndroidManifest.xml
new file mode 100644
index 0000000..c02ac77
--- /dev/null
+++ b/tests/filesystem/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="android.filesystem.cts">
+
+    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+            android:targetPackage="android.filesystem.cts"
+            android:label="CTS tests for file system" />
+</manifest>
diff --git a/tests/filesystem/AndroidTest.xml b/tests/filesystem/AndroidTest.xml
new file mode 100644
index 0000000..d05134d
--- /dev/null
+++ b/tests/filesystem/AndroidTest.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS File System test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsFileSystemTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.filesystem.cts" />
+        <option name="runtime-hint" value="22m48s" />
+    </test>
+</configuration>
diff --git a/tests/filesystem/src/android/filesystem/cts/AlmostFullTest.java b/tests/filesystem/src/android/filesystem/cts/AlmostFullTest.java
new file mode 100644
index 0000000..991f9bf
--- /dev/null
+++ b/tests/filesystem/src/android/filesystem/cts/AlmostFullTest.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.filesystem.cts;
+
+import android.util.Log;
+
+import android.cts.util.CtsAndroidTestCase;
+import android.cts.util.SystemUtil;
+
+import com.android.compatibility.common.util.DeviceReportLog;
+import com.android.cts.util.TimeoutReq;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class AlmostFullTest extends CtsAndroidTestCase {
+
+    private static final String DIR_INITIAL_FILL = "INITIAL_FILL";
+    private static final String DIR_SEQ_UPDATE = "SEQ_UPDATE";
+    private static final String DIR_RANDOM_WR = "RANDOM_WR";
+    private static final String DIR_RANDOM_RD = "RANDOM_RD";
+    private static final String TAG = "AlmostFullTest";
+
+    private static final long FREE_SPACE_FINAL = 1000L * 1024 * 1024L;
+
+    // test runner creates multiple instances at the begging.
+    // use that to fill disk only once.
+    // set as final to initialize it only once
+    private static final AtomicInteger mRefCounter = new AtomicInteger(0);
+    private static final AtomicBoolean mDiskFilled = new AtomicBoolean(false);
+
+    public AlmostFullTest() {
+        int currentCounter = mRefCounter.incrementAndGet();
+        Log.i(TAG, "++currentCounter: " + currentCounter);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        if (mDiskFilled.compareAndSet(false, true)) {
+            Log.i(TAG, "Filling disk");
+            // initial fill done in two stage as disk can be filled by other
+            // components
+            long freeDisk = SystemUtil.getFreeDiskSize(getContext());
+            long diskToFill = freeDisk - FREE_SPACE_FINAL;
+            if (diskToFill >= 0) {
+                Log.i(TAG, "free disk " + freeDisk + ", to fill " + diskToFill);
+            } else {
+                Log.i(TAG, "free disk " + freeDisk + " too small, needs " + FREE_SPACE_FINAL);
+                return;
+            }
+            final long MAX_FILE_SIZE_TO_FILL = 1024L * 1024L * 1024L;
+            long filled = 0;
+            while (filled < diskToFill) {
+                long toFill = diskToFill - filled;
+                if (toFill > MAX_FILE_SIZE_TO_FILL) {
+                    toFill = MAX_FILE_SIZE_TO_FILL;
+                }
+                Log.i(TAG, "Generating file " + toFill);
+                FileUtil.createNewFilledFile(getContext(),
+                        DIR_INITIAL_FILL, toFill);
+                filled += toFill;
+            }
+        }
+        Log.i(TAG, "free disk " + SystemUtil.getFreeDiskSize(getContext()));
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        Log.i(TAG, "tearDown free disk " + SystemUtil.getFreeDiskSize(getContext()));
+        int currentCounter = mRefCounter.decrementAndGet();
+        Log.i(TAG, "--currentCounter: " + currentCounter);
+        if (currentCounter == 0) {
+            FileUtil.removeFileOrDir(getContext(), DIR_INITIAL_FILL);
+        }
+        FileUtil.removeFileOrDir(getContext(), DIR_SEQ_UPDATE);
+        FileUtil.removeFileOrDir(getContext(), DIR_RANDOM_WR);
+        FileUtil.removeFileOrDir(getContext(), DIR_RANDOM_RD);
+        Log.i(TAG, "tearDown free disk " + SystemUtil.getFreeDiskSize(getContext()));
+        super.tearDown();
+    }
+
+    @TimeoutReq(minutes = 30)
+    public void testSequentialUpdate() throws Exception {
+        // now about freeSpaceToLeave should be left
+        // and try updating exceeding the free space size
+        final long FILE_SIZE = 400L * 1024L * 1024L;
+        long freeDisk = SystemUtil.getFreeDiskSize(getContext());
+        Log.i(TAG, "Now free space is " + freeDisk);
+        if (freeDisk < FILE_SIZE) {
+            Log.w(TAG, "too little space: " + freeDisk);
+            return;
+        }
+        final int BUFFER_SIZE = 10 * 1024 * 1024;
+        final int NUMBER_REPETITION = 10;
+        DeviceReportLog report = new DeviceReportLog();
+        FileUtil.doSequentialUpdateTest(getContext(), DIR_SEQ_UPDATE, report, FILE_SIZE,
+                BUFFER_SIZE, NUMBER_REPETITION);
+        report.submit(getInstrumentation());
+    }
+
+    // TODO: file size too small and caching will give wrong better result.
+    // needs to flush cache by reading big files per each read.
+    @TimeoutReq(minutes = 60)
+    public void testRandomRead() throws Exception {
+        final int BUFFER_SIZE = 4 * 1024;
+        final long fileSize = 400L * 1024L * 1024L;
+        long freeDisk = SystemUtil.getFreeDiskSize(getContext());
+        if (freeDisk < fileSize) {
+            Log.w(TAG, "too little space: " + freeDisk);
+            return;
+        }
+        DeviceReportLog report = new DeviceReportLog();
+        FileUtil.doRandomReadTest(getContext(), DIR_RANDOM_RD, report, fileSize, BUFFER_SIZE);
+        report.submit(getInstrumentation());
+    }
+
+    @TimeoutReq(minutes = 60)
+    public void testRandomUpdate() throws Exception {
+        final int BUFFER_SIZE = 4 * 1024;
+        final long fileSize = 256L * 1024L * 1024L;
+        long freeDisk = SystemUtil.getFreeDiskSize(getContext());
+        if (freeDisk < fileSize) {
+            Log.w(TAG, "too little space: " + freeDisk);
+            return;
+        }
+        DeviceReportLog report = new DeviceReportLog();
+        FileUtil.doRandomWriteTest(getContext(), DIR_RANDOM_WR, report, fileSize, BUFFER_SIZE);
+        report.submit(getInstrumentation());
+    }
+}
diff --git a/tests/filesystem/src/android/filesystem/cts/FileUtil.java b/tests/filesystem/src/android/filesystem/cts/FileUtil.java
new file mode 100755
index 0000000..baefaa0
--- /dev/null
+++ b/tests/filesystem/src/android/filesystem/cts/FileUtil.java
@@ -0,0 +1,411 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.filesystem.cts;
+
+import android.content.Context;
+import android.cts.util.SystemUtil;
+import android.util.Log;
+
+import com.android.compatibility.common.util.MeasureRun;
+import com.android.compatibility.common.util.MeasureTime;
+import com.android.compatibility.common.util.ReportLog;
+import com.android.compatibility.common.util.ResultType;
+import com.android.compatibility.common.util.ResultUnit;
+import com.android.compatibility.common.util.Stat;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.RandomAccessFile;
+import java.util.Random;
+
+public class FileUtil {
+    private static final String TAG = "FileUtil";
+    private static final Random mRandom = new Random(0);
+    private static long mFileId = 0;
+    /**
+     * create array with different data per each call
+     *
+     * @param length
+     * @param randomSeed
+     * @return
+     */
+    public static byte[] generateRandomData(int length) {
+        byte[] buffer = new byte[length];
+        int val = mRandom.nextInt();
+        for (int i = 0; i < length / 4; i++) {
+            // in little-endian
+            buffer[i * 4] = (byte)(val & 0x000000ff);
+            buffer[i * 4 + 1] = (byte)((val & 0x0000ff00) >> 8);
+            buffer[i * 4 + 2] = (byte)((val & 0x00ff0000) >> 16);
+            buffer[i * 4 + 3] = (byte)((val & 0xff000000) >> 24);
+            val++;
+        }
+        for (int i = (length / 4) * 4; i < length; i++) {
+            buffer[i] = 0;
+        }
+        return buffer;
+    }
+
+    /**
+     * create a new file under the given dirName.
+     * Existing files will not be affected.
+     * @param context
+     * @param dirName
+     * @return
+     */
+    public static File createNewFile(Context context, String dirName) {
+        File topDir = new File(context.getFilesDir(), dirName);
+        topDir.mkdir();
+        String[] list = topDir.list();
+
+        String newFileName;
+        while (true) {
+            newFileName = Long.toString(mFileId);
+            boolean fileExist = false;
+            for (String child : list) {
+                if (child.equals(newFileName)) {
+                    fileExist = true;
+                    break;
+                }
+            }
+            if (!fileExist) {
+                break;
+            }
+            mFileId++;
+        }
+        mFileId++;
+        //Log.i(TAG, "filename" + Long.toString(mFileId));
+        return new File(topDir, newFileName);
+    }
+
+    /**
+     * create multiple new files
+     * @param context
+     * @param dirName
+     * @param count number of files to create
+     * @return
+     */
+    public static File[] createNewFiles(Context context, String dirName, int count) {
+        File[] files = new File[count];
+        for (int i = 0; i < count; i++) {
+            files[i] = createNewFile(context, dirName);
+        }
+        return files;
+    }
+
+    /**
+     * write file with given byte array
+     * @param file
+     * @param data
+     * @param append will append if set true. Otherwise, write from beginning
+     * @throws IOException
+     */
+    public static void writeFile(File file, byte[] data, boolean append) throws IOException {
+        final RandomAccessFile randomFile = new RandomAccessFile(file, "rwd"); // force O_SYNC
+        if (append) {
+            randomFile.seek(randomFile.length());
+        } else {
+            randomFile.seek(0L);
+        }
+        randomFile.write(data);
+        randomFile.close();
+    }
+
+    /**
+     * create a new file with given length.
+     * @param context
+     * @param dirName
+     * @param length
+     * @return
+     * @throws IOException
+     */
+    public static File createNewFilledFile(Context context, String dirName, long length)
+            throws IOException {
+        final int BUFFER_SIZE = 10 * 1024 * 1024;
+        File file = createNewFile(context, dirName);
+        FileOutputStream out = new FileOutputStream(file);
+        byte[] data = generateRandomData(BUFFER_SIZE);
+        long written = 0;
+        while (written < length) {
+            out.write(data);
+            written += BUFFER_SIZE;
+        }
+        out.flush();
+        out.close();
+        return file;
+    }
+
+    /**
+     * remove given file or directory under the current app's files dir.
+     * @param context
+     * @param name
+     */
+    public static void removeFileOrDir(Context context, String name) {
+        File entry = new File(context.getFilesDir(), name);
+        if (entry.exists()) {
+            removeEntry(entry);
+        }
+    }
+
+    private static void removeEntry(File entry) {
+        if (entry.isDirectory()) {
+            String[] children = entry.list();
+            for (String child : children) {
+                removeEntry(new File(entry, child));
+            }
+        }
+        Log.i(TAG, "delete file " + entry.getAbsolutePath());
+        entry.delete();
+    }
+
+    /**
+     * measure time taken for each IO run with amount R/W
+     * @param count
+     * @param run
+     * @param readAmount returns amount of read in bytes for each interval.
+     *        Value will not be written if /proc/self/io does not exist.
+     * @param writeAmount returns amount of write in bytes for each interval.
+     * @return time per each interval
+     * @throws IOException
+     */
+    public static double[] measureIO(int count, double[] readAmount, double[] writeAmount,
+            MeasureRun run)  throws Exception {
+        double[] result = new double[count];
+        File procIo = new File("/proc/self/io");
+        boolean measureIo = procIo.exists() && procIo.canRead();
+        long prev = System.currentTimeMillis();
+        RWAmount prevAmount = new RWAmount();
+        if (measureIo) {
+            prevAmount = getRWAmount(procIo);
+        }
+        for (int i = 0; i < count; i++) {
+            run.run(i);
+            long current =  System.currentTimeMillis();
+            result[i] = current - prev;
+            prev = current;
+            if (measureIo) {
+                RWAmount currentAmount = getRWAmount(procIo);
+                readAmount[i] = currentAmount.mRd - prevAmount.mRd;
+                writeAmount[i] = currentAmount.mWr - prevAmount.mWr;
+                prevAmount = currentAmount;
+            }
+        }
+        return result;
+    }
+
+    private static class RWAmount {
+        public double mRd = 0.0;
+        public double mWr = 0.0;
+    };
+
+    private static RWAmount getRWAmount(File file) throws IOException {
+        RWAmount amount = new RWAmount();
+
+        BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
+        String line;
+        while((line = br.readLine())!= null) {
+            if (line.startsWith("read_bytes")) {
+                amount.mRd = Double.parseDouble(line.split(" ")[1]);
+            } else if (line.startsWith("write_bytes")) {
+                amount.mWr = Double.parseDouble(line.split(" ")[1]);
+            }
+        }
+        br.close();
+        return amount;
+    }
+
+    /**
+     * get file size exceeding total memory size ( 2x total memory).
+     * The size is rounded in bufferSize. And the size will be bigger than 400MB.
+     * @param context
+     * @param bufferSize
+     * @return file size or 0 if there is not enough space.
+     */
+    public static long getFileSizeExceedingMemory(Context context, int bufferSize) {
+        long freeDisk = SystemUtil.getFreeDiskSize(context);
+        long memSize = SystemUtil.getTotalMemory(context);
+        long diskSizeTarget = (2 * memSize / bufferSize) * bufferSize;
+        final long minimumDiskSize = (512L * 1024L * 1024L / bufferSize) * bufferSize;
+        final long reservedDiskSize = (50L * 1024L * 1024L / bufferSize) * bufferSize;
+        if ( diskSizeTarget < minimumDiskSize ) {
+            diskSizeTarget = minimumDiskSize;
+        }
+        if (diskSizeTarget > freeDisk) {
+            Log.i(TAG, "Free disk size " + freeDisk + " too small");
+            return 0;
+        }
+        if ((freeDisk - diskSizeTarget) < reservedDiskSize) {
+            diskSizeTarget -= reservedDiskSize;
+        }
+        return diskSizeTarget;
+    }
+
+    /**
+     *
+     * @param context
+     * @param dirName
+     * @param report
+     * @param fileSize
+     * @param bufferSize should be power of two
+     * @throws IOException
+     */
+    public static void doRandomReadTest(Context context, String dirName, ReportLog report,
+            long fileSize, int bufferSize) throws Exception {
+        File file = FileUtil.createNewFilledFile(context,
+                dirName, fileSize);
+
+        final byte[] data = FileUtil.generateRandomData(bufferSize);
+        Random random = new Random(0);
+        final int totalReadCount = (int)(fileSize / bufferSize);
+        final int[] readOffsets = new int[totalReadCount];
+        for (int i = 0; i < totalReadCount; i++) {
+            // align in buffer size
+            readOffsets[i] = (int)(random.nextFloat() * (fileSize - bufferSize)) &
+                    ~(bufferSize - 1);
+        }
+        final int runsInOneGo = 16;
+        final int readsInOneMeasure = totalReadCount / runsInOneGo;
+
+        final RandomAccessFile randomFile = new RandomAccessFile(file, "rw"); // do not need O_SYNC
+        double[] rdAmount = new double[runsInOneGo];
+        double[] wrAmount = new double[runsInOneGo];
+        double[] times = FileUtil.measureIO(runsInOneGo, rdAmount, wrAmount, new MeasureRun() {
+
+            @Override
+            public void run(int i) throws IOException {
+                Log.i(TAG, "starting " + i + " -th round");
+                int start = i * readsInOneMeasure;
+                int end = (i + 1) * readsInOneMeasure;
+                for (int j = start; j < end; j++) {
+                    randomFile.seek(readOffsets[j]);
+                    randomFile.read(data);
+                }
+            }
+        });
+        randomFile.close();
+        double[] mbps = Stat.calcRatePerSecArray((double)fileSize / runsInOneGo / 1024 / 1024,
+                times);
+        report.addValues("read throughput",
+                mbps, ResultType.HIGHER_BETTER, ResultUnit.MBPS);
+        // This is just the amount of IO returned from kernel. So this is performance neutral.
+        report.addValues("read amount", rdAmount, ResultType.NEUTRAL, ResultUnit.BYTE);
+        Stat.StatResult stat = Stat.getStat(mbps);
+
+        report.setSummary("read throughput", stat.mAverage, ResultType.HIGHER_BETTER,
+                ResultUnit.MBPS);
+    }
+
+    /**
+     *
+     * @param context
+     * @param dirName
+     * @param report
+     * @param fileSize
+     * @param bufferSize should be power of two
+     * @throws IOException
+     */
+    public static void doRandomWriteTest(Context context, String dirName, ReportLog report,
+            long fileSize, int bufferSize) throws Exception {
+        File file = FileUtil.createNewFilledFile(context,
+                dirName, fileSize);
+        final byte[] data = FileUtil.generateRandomData(bufferSize);
+        Random random = new Random(0);
+        final int totalWriteCount = (int)(fileSize / bufferSize);
+        final int[] writeOffsets = new int[totalWriteCount];
+        for (int i = 0; i < totalWriteCount; i++) {
+            writeOffsets[i] = (int)(random.nextFloat() * (fileSize - bufferSize)) &
+                    ~(bufferSize - 1);
+        }
+        final int runsInOneGo = 16;
+        final int writesInOneMeasure = totalWriteCount / runsInOneGo;
+
+        final RandomAccessFile randomFile = new RandomAccessFile(file, "rwd"); // force O_SYNC
+        double[] rdAmount = new double[runsInOneGo];
+        double[] wrAmount = new double[runsInOneGo];
+        double[] times = FileUtil.measureIO(runsInOneGo, rdAmount, wrAmount, new MeasureRun() {
+
+            @Override
+            public void run(int i) throws IOException {
+                Log.i(TAG, "starting " + i + " -th round");
+                int start = i * writesInOneMeasure;
+                int end = (i + 1) * writesInOneMeasure;
+                for (int j = start; j < end; j++) {
+                    randomFile.seek(writeOffsets[j]);
+                    randomFile.write(data);
+                }
+            }
+        });
+        randomFile.close();
+        double[] mbps = Stat.calcRatePerSecArray((double)fileSize / runsInOneGo / 1024 / 1024,
+                times);
+        report.addValues("write throughput",
+                mbps, ResultType.HIGHER_BETTER, ResultUnit.MBPS);
+        report.addValues("write amount", wrAmount, ResultType.NEUTRAL,
+                ResultUnit.BYTE);
+        Stat.StatResult stat = Stat.getStat(mbps);
+
+        report.setSummary("write throughput", stat.mAverage, ResultType.HIGHER_BETTER,
+                ResultUnit.MBPS);
+    }
+
+    /**
+     *
+     * @param context
+     * @param dirName
+     * @param report
+     * @param fileSize fileSize should be multiple of bufferSize.
+     * @param bufferSize
+     * @param numberRepetition
+     * @throws IOException
+     */
+    public static void doSequentialUpdateTest(Context context, String dirName, ReportLog report,
+            long fileSize, int bufferSize, int numberRepetition) throws Exception {
+        File file = FileUtil.createNewFilledFile(context,
+                dirName, fileSize);
+        final byte[] data = FileUtil.generateRandomData(bufferSize);
+        int numberRepeatInOneRun = (int)(fileSize / bufferSize);
+        double[] mbpsAll = new double[numberRepetition * numberRepeatInOneRun];
+        for (int i = 0; i < numberRepetition; i++) {
+            Log.i(TAG, "starting " + i + " -th round");
+            final RandomAccessFile randomFile = new RandomAccessFile(file, "rwd");  // force O_SYNC
+            randomFile.seek(0L);
+            double[] times = MeasureTime.measure(numberRepeatInOneRun, new MeasureRun() {
+
+                @Override
+                public void run(int i) throws IOException {
+                    randomFile.write(data);
+                }
+            });
+            randomFile.close();
+            double[] mbps = Stat.calcRatePerSecArray((double)bufferSize / 1024 / 1024,
+                    times);
+            report.addValues(i + "-th round throughput",
+                    mbps, ResultType.HIGHER_BETTER, ResultUnit.MBPS);
+            int offset = i * numberRepeatInOneRun;
+            for (int j = 0; j < mbps.length; j++) {
+                mbpsAll[offset + j] = mbps[j];
+            }
+        }
+        Stat.StatResult stat = Stat.getStat(mbpsAll);
+        report.setSummary("update throughput", stat.mAverage, ResultType.HIGHER_BETTER,
+                ResultUnit.MBPS);
+    }
+}
diff --git a/tests/filesystem/src/android/filesystem/cts/RandomRWTest.java b/tests/filesystem/src/android/filesystem/cts/RandomRWTest.java
new file mode 100644
index 0000000..dff3723
--- /dev/null
+++ b/tests/filesystem/src/android/filesystem/cts/RandomRWTest.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.filesystem.cts;
+
+import android.cts.util.CtsAndroidTestCase;
+
+import com.android.compatibility.common.util.DeviceReportLog;
+import com.android.cts.util.TimeoutReq;
+
+public class RandomRWTest extends CtsAndroidTestCase {
+    private static final String DIR_RANDOM_WR = "RANDOM_WR";
+    private static final String DIR_RANDOM_RD = "RANDOM_RD";
+
+    @Override
+    protected void tearDown() throws Exception {
+        FileUtil.removeFileOrDir(getContext(), DIR_RANDOM_WR);
+        FileUtil.removeFileOrDir(getContext(), DIR_RANDOM_RD);
+        super.tearDown();
+    }
+
+    @TimeoutReq(minutes = 60)
+    public void testRandomRead() throws Exception {
+        final int READ_BUFFER_SIZE = 4 * 1024;
+        final long fileSize = FileUtil.getFileSizeExceedingMemory(getContext(), READ_BUFFER_SIZE);
+        if (fileSize == 0) { // not enough space, give up
+            return;
+        }
+        DeviceReportLog report = new DeviceReportLog();
+        FileUtil.doRandomReadTest(getContext(), DIR_RANDOM_RD, report, fileSize,
+                READ_BUFFER_SIZE);
+        report.submit(getInstrumentation());
+    }
+
+    // It is taking too long in some device, and thus cannot run multiple times
+    @TimeoutReq(minutes = 60)
+    public void testRandomUpdate() throws Exception {
+        final int WRITE_BUFFER_SIZE = 4 * 1024;
+        final long fileSize = 256 * 1024 * 1024;
+        DeviceReportLog report = new DeviceReportLog();
+        FileUtil.doRandomWriteTest(getContext(), DIR_RANDOM_WR, report, fileSize,
+                WRITE_BUFFER_SIZE);
+        report.submit(getInstrumentation());
+    }
+}
diff --git a/tests/filesystem/src/android/filesystem/cts/SequentialRWTest.java b/tests/filesystem/src/android/filesystem/cts/SequentialRWTest.java
new file mode 100644
index 0000000..3b7a45f
--- /dev/null
+++ b/tests/filesystem/src/android/filesystem/cts/SequentialRWTest.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.filesystem.cts;
+
+import android.cts.util.CtsAndroidTestCase;
+
+import com.android.compatibility.common.util.DeviceReportLog;
+import com.android.compatibility.common.util.MeasureRun;
+import com.android.compatibility.common.util.MeasureTime;
+import com.android.compatibility.common.util.ResultType;
+import com.android.compatibility.common.util.ResultUnit;
+import com.android.compatibility.common.util.Stat;
+import com.android.cts.util.TimeoutReq;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+
+public class SequentialRWTest extends CtsAndroidTestCase {
+    private static final String DIR_SEQ_WR = "SEQ_WR";
+    private static final String DIR_SEQ_UPDATE = "SEQ_UPDATE";
+    private static final String DIR_SEQ_RD = "SEQ_RD";
+    private static final int BUFFER_SIZE = 10 * 1024 * 1024;
+
+    @Override
+    protected void tearDown() throws Exception {
+        FileUtil.removeFileOrDir(getContext(), DIR_SEQ_WR);
+        FileUtil.removeFileOrDir(getContext(), DIR_SEQ_UPDATE);
+        FileUtil.removeFileOrDir(getContext(), DIR_SEQ_RD);
+        super.tearDown();
+    }
+
+    @TimeoutReq(minutes = 30)
+    public void testSingleSequentialWrite() throws Exception {
+        final long fileSize = FileUtil.getFileSizeExceedingMemory(getContext(), BUFFER_SIZE);
+        if (fileSize == 0) { // not enough space, give up
+            return;
+        }
+        final int numberOfFiles =(int)(fileSize / BUFFER_SIZE);
+        DeviceReportLog report = new DeviceReportLog();
+        report.addValue("files", numberOfFiles, ResultType.NEUTRAL, ResultUnit.COUNT);
+        final byte[] data = FileUtil.generateRandomData(BUFFER_SIZE);
+        final File[] files = FileUtil.createNewFiles(getContext(), DIR_SEQ_WR,
+                numberOfFiles);
+        double[] rdAmount = new double[numberOfFiles];
+        double[] wrAmount = new double[numberOfFiles];
+        double[] times = FileUtil.measureIO(numberOfFiles, rdAmount, wrAmount, new MeasureRun() {
+
+            @Override
+            public void run(int i) throws IOException {
+                FileUtil.writeFile(files[i], data, false);
+            }
+        });
+        double[] mbps = Stat.calcRatePerSecArray((double)BUFFER_SIZE / 1024 / 1024, times);
+        report.addValues("write throughput",
+                mbps, ResultType.HIGHER_BETTER, ResultUnit.MBPS);
+        report.addValues("write amount", wrAmount, ResultType.NEUTRAL,
+                ResultUnit.BYTE);
+        Stat.StatResult stat = Stat.getStat(mbps);
+        report.setSummary("write throughput", stat.mAverage, ResultType.HIGHER_BETTER,
+                ResultUnit.MBPS);
+        report.submit(getInstrumentation());
+    }
+
+    @TimeoutReq(minutes = 60)
+    public void testSingleSequentialUpdate() throws Exception {
+        final long fileSize = FileUtil.getFileSizeExceedingMemory(getContext(), BUFFER_SIZE);
+        if (fileSize == 0) { // not enough space, give up
+            return;
+        }
+        final int NUMBER_REPETITION = 6;
+        DeviceReportLog report = new DeviceReportLog();
+        FileUtil.doSequentialUpdateTest(getContext(), DIR_SEQ_UPDATE, report, fileSize,
+                BUFFER_SIZE, NUMBER_REPETITION);
+        report.submit(getInstrumentation());
+    }
+
+    @TimeoutReq(minutes = 30)
+    public void testSingleSequentialRead() throws Exception {
+        final long fileSize = FileUtil.getFileSizeExceedingMemory(getContext(), BUFFER_SIZE);
+        if (fileSize == 0) { // not enough space, give up
+            return;
+        }
+        long start = System.currentTimeMillis();
+        final File file = FileUtil.createNewFilledFile(getContext(),
+                DIR_SEQ_RD, fileSize);
+        long finish = System.currentTimeMillis();
+        DeviceReportLog report = new DeviceReportLog();
+        report.addValue("write throughput for test file of length " + fileSize,
+                Stat.calcRatePerSec((double)fileSize / 1024 / 1024, finish - start),
+                ResultType.HIGHER_BETTER, ResultUnit.MBPS);
+
+        final int NUMBER_READ = 10;
+
+        final byte[] data = new byte[BUFFER_SIZE];
+        double[] times = MeasureTime.measure(NUMBER_READ, new MeasureRun() {
+
+            @Override
+            public void run(int i) throws IOException {
+                final FileInputStream in = new FileInputStream(file);
+                long read = 0;
+                while (read < fileSize) {
+                    in.read(data);
+                    read += BUFFER_SIZE;
+                }
+                in.close();
+            }
+        });
+        double[] mbps = Stat.calcRatePerSecArray((double)fileSize / 1024 / 1024, times);
+        report.addValues("read throughput",
+                mbps, ResultType.HIGHER_BETTER, ResultUnit.MBPS);
+        Stat.StatResult stat = Stat.getStat(mbps);
+        report.setSummary("read throughput", stat.mAverage, ResultType.HIGHER_BETTER,
+                ResultUnit.MBPS);
+        report.submit(getInstrumentation());
+    }
+}
diff --git a/tests/fragment/Android.mk b/tests/fragment/Android.mk
new file mode 100644
index 0000000..2352564
--- /dev/null
+++ b/tests/fragment/Android.mk
@@ -0,0 +1,40 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := CtsFragmentTestCases
+
+# don't include this package in any target
+LOCAL_MODULE_TAGS := tests
+
+# and when built explicitly put it in the data partition
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_DEX_PREOPT := false
+
+LOCAL_PROGUARD_ENABLED := disabled
+
+LOCAL_STATIC_JAVA_LIBRARIES := compatibility-device-util android-support-test
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_PACKAGE)
diff --git a/tests/fragment/AndroidManifest.xml b/tests/fragment/AndroidManifest.xml
new file mode 100644
index 0000000..05027b5
--- /dev/null
+++ b/tests/fragment/AndroidManifest.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.fragment.cts">
+
+    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+
+        <activity android:name=".FragmentTestActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="android.fragment.cts"
+                     android:label="CTS tests of android.app Fragments" />
+
+</manifest>
+
diff --git a/tests/fragment/AndroidTest.xml b/tests/fragment/AndroidTest.xml
new file mode 100644
index 0000000..f3e302a
--- /dev/null
+++ b/tests/fragment/AndroidTest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Configuration for app.usage Tests">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsFragmentTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.fragment.cts" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/fragment/res/layout/strict_view_fragment.xml b/tests/fragment/res/layout/strict_view_fragment.xml
new file mode 100644
index 0000000..324f8d0
--- /dev/null
+++ b/tests/fragment/res/layout/strict_view_fragment.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+* Copyright 2016, The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+-->
+<TextView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:id="@+id/text1" />
diff --git a/tests/fragment/src/android/fragment/cts/FragmentLifecycleTest.java b/tests/fragment/src/android/fragment/cts/FragmentLifecycleTest.java
new file mode 100644
index 0000000..01c4e70
--- /dev/null
+++ b/tests/fragment/src/android/fragment/cts/FragmentLifecycleTest.java
@@ -0,0 +1,234 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.fragment.cts;
+
+import android.app.FragmentManager;
+import android.support.test.rule.ActivityTestRule;
+import android.support.test.runner.AndroidJUnit4;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.View;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.TestCase.*;
+
+@RunWith(AndroidJUnit4.class)
+public class FragmentLifecycleTest {
+
+    @Rule
+    public ActivityTestRule<FragmentTestActivity> mActivityRule =
+            new ActivityTestRule<FragmentTestActivity>(FragmentTestActivity.class);
+
+    @Test
+    @MediumTest
+    public void basicLifecycle() throws Throwable {
+        final FragmentManager fm = mActivityRule.getActivity().getFragmentManager();
+        final StrictFragment strictFragment = new StrictFragment();
+
+        // Add fragment; StrictFragment will throw if it detects any violation
+        // in standard lifecycle method ordering or expected preconditions.
+        fm.beginTransaction().add(strictFragment, "EmptyHeadless").commit();
+        executePendingTransactions(fm);
+
+        assertTrue("fragment is not added", strictFragment.isAdded());
+        assertFalse("fragment is detached", strictFragment.isDetached());
+        assertTrue("fragment is not resumed", strictFragment.isResumed());
+
+        // Test removal as well; StrictFragment will throw here too.
+        fm.beginTransaction().remove(strictFragment).commit();
+        executePendingTransactions(fm);
+
+        assertFalse("fragment is added", strictFragment.isAdded());
+        assertFalse("fragment is resumed", strictFragment.isResumed());
+
+        // This one is perhaps counterintuitive; "detached" means specifically detached
+        // but still managed by a FragmentManager. The .remove call above
+        // should not enter this state.
+        assertFalse("fragment is detached", strictFragment.isDetached());
+    }
+
+    @Test
+    @MediumTest
+    public void detachment() throws Throwable {
+        final FragmentManager fm = mActivityRule.getActivity().getFragmentManager();
+        final StrictFragment f1 = new StrictFragment();
+        final StrictFragment f2 = new StrictFragment();
+
+        fm.beginTransaction().add(f1, "1").add(f2, "2").commit();
+        executePendingTransactions(fm);
+
+        assertTrue("fragment 1 is not added", f1.isAdded());
+        assertTrue("fragment 2 is not added", f2.isAdded());
+
+        // Test detaching fragments using StrictFragment to throw on errors.
+        fm.beginTransaction().detach(f1).detach(f2).commit();
+        executePendingTransactions(fm);
+
+        assertTrue("fragment 1 is not detached", f1.isDetached());
+        assertTrue("fragment 2 is not detached", f2.isDetached());
+        assertFalse("fragment 1 is added", f1.isAdded());
+        assertFalse("fragment 2 is added", f2.isAdded());
+
+        // Only reattach f1; leave v2 detached.
+        fm.beginTransaction().attach(f1).commit();
+        executePendingTransactions(fm);
+
+        assertTrue("fragment 1 is not added", f1.isAdded());
+        assertFalse("fragment 1 is detached", f1.isDetached());
+        assertTrue("fragment 2 is not detached", f2.isDetached());
+
+        // Remove both from the FragmentManager.
+        fm.beginTransaction().remove(f1).remove(f2).commit();
+        executePendingTransactions(fm);
+
+        assertFalse("fragment 1 is added", f1.isAdded());
+        assertFalse("fragment 2 is added", f2.isAdded());
+        assertFalse("fragment 1 is detached", f1.isDetached());
+        assertFalse("fragment 2 is detached", f2.isDetached());
+    }
+
+    @Test
+    @MediumTest
+    public void basicBackStack() throws Throwable {
+        final FragmentManager fm = mActivityRule.getActivity().getFragmentManager();
+        final StrictFragment f1 = new StrictFragment();
+        final StrictFragment f2 = new StrictFragment();
+
+        // Add a fragment normally to set up
+        fm.beginTransaction().add(f1, "1").commit();
+        executePendingTransactions(fm);
+
+        assertTrue("fragment 1 is not added", f1.isAdded());
+
+        // Remove the first one and add a second. We're not using replace() here since
+        // these fragments are headless and as of this test writing, replace() only works
+        // for fragments with views and a container view id.
+        // Add it to the back stack so we can pop it afterwards.
+        fm.beginTransaction().remove(f1).add(f2, "2").addToBackStack("stack1").commit();
+        executePendingTransactions(fm);
+
+        assertFalse("fragment 1 is added", f1.isAdded());
+        assertTrue("fragment 2 is not added", f2.isAdded());
+
+        // Test popping the stack
+        fm.popBackStack();
+        executePendingTransactions(fm);
+
+        assertFalse("fragment 2 is added", f2.isAdded());
+        assertTrue("fragment 1 is not added", f1.isAdded());
+    }
+
+    @Test
+    @MediumTest
+    public void attachBackStack() throws Throwable {
+        final FragmentManager fm = mActivityRule.getActivity().getFragmentManager();
+        final StrictFragment f1 = new StrictFragment();
+        final StrictFragment f2 = new StrictFragment();
+
+        // Add a fragment normally to set up
+        fm.beginTransaction().add(f1, "1").commit();
+        executePendingTransactions(fm);
+
+        assertTrue("fragment 1 is not added", f1.isAdded());
+
+        fm.beginTransaction().detach(f1).add(f2, "2").addToBackStack("stack1").commit();
+        executePendingTransactions(fm);
+
+        assertTrue("fragment 1 is not detached", f1.isDetached());
+        assertFalse("fragment 2 is detached", f2.isDetached());
+        assertFalse("fragment 1 is added", f1.isAdded());
+        assertTrue("fragment 2 is not added", f2.isAdded());
+    }
+
+    @Test
+    @MediumTest
+    public void viewLifecycle() throws Throwable {
+        // Test basic lifecycle when the fragment creates a view
+
+        final FragmentManager fm = mActivityRule.getActivity().getFragmentManager();
+        final StrictViewFragment f1 = new StrictViewFragment();
+
+        fm.beginTransaction().add(android.R.id.content, f1).commit();
+        executePendingTransactions(fm);
+
+        assertTrue("fragment 1 is not added", f1.isAdded());
+        final View view = f1.getView();
+        assertNotNull("fragment 1 returned null from getView", view);
+        assertTrue("fragment 1's view is not attached to a window", view.isAttachedToWindow());
+
+        fm.beginTransaction().remove(f1).commit();
+        executePendingTransactions(fm);
+
+        assertFalse("fragment 1 is added", f1.isAdded());
+        assertNull("fragment 1 returned non-null from getView after removal", f1.getView());
+        assertFalse("fragment 1's previous view is still attached to a window",
+                view.isAttachedToWindow());
+    }
+
+    @Test
+    @MediumTest
+    public void viewReplace() throws Throwable {
+        // Replace one view with another, then reverse it with the back stack
+
+        final FragmentManager fm = mActivityRule.getActivity().getFragmentManager();
+        final StrictViewFragment f1 = new StrictViewFragment();
+        final StrictViewFragment f2 = new StrictViewFragment();
+
+        fm.beginTransaction().add(android.R.id.content, f1).commit();
+        executePendingTransactions(fm);
+
+        assertTrue("fragment 1 is not added", f1.isAdded());
+
+        View origView1 = f1.getView();
+        assertNotNull("fragment 1 returned null view", origView1);
+        assertTrue("fragment 1's view not attached", origView1.isAttachedToWindow());
+
+        fm.beginTransaction().replace(android.R.id.content, f2).addToBackStack("stack1").commit();
+        executePendingTransactions(fm);
+
+        assertFalse("fragment 1 is added", f1.isAdded());
+        assertTrue("fragment 2 is added", f2.isAdded());
+        assertNull("fragment 1 returned non-null view", f1.getView());
+        assertFalse("fragment 1's old view still attached", origView1.isAttachedToWindow());
+        View origView2 = f2.getView();
+        assertNotNull("fragment 2 returned null view", origView2);
+        assertTrue("fragment 2's view not attached", origView2.isAttachedToWindow());
+
+        fm.popBackStack();
+        executePendingTransactions(fm);
+
+        assertTrue("fragment 1 is not added", f1.isAdded());
+        assertFalse("fragment 2 is added", f2.isAdded());
+        assertNull("fragment 2 returned non-null view", f2.getView());
+        assertFalse("fragment 2's view still attached", origView2.isAttachedToWindow());
+        View newView1 = f1.getView();
+        assertNotSame("fragment 1 had same view from last attachment", origView1, newView1);
+        assertTrue("fragment 1's view not attached", newView1.isAttachedToWindow());
+    }
+
+    private void executePendingTransactions(final FragmentManager fm) throws Throwable {
+        mActivityRule.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                fm.executePendingTransactions();
+            }
+        });
+    }
+}
diff --git a/tests/fragment/src/android/fragment/cts/FragmentTestActivity.java b/tests/fragment/src/android/fragment/cts/FragmentTestActivity.java
new file mode 100644
index 0000000..fd26d0a
--- /dev/null
+++ b/tests/fragment/src/android/fragment/cts/FragmentTestActivity.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.fragment.cts;
+
+import android.app.Activity;
+
+public class FragmentTestActivity extends Activity {
+}
diff --git a/tests/fragment/src/android/fragment/cts/StrictFragment.java b/tests/fragment/src/android/fragment/cts/StrictFragment.java
new file mode 100644
index 0000000..f0c4a8a
--- /dev/null
+++ b/tests/fragment/src/android/fragment/cts/StrictFragment.java
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.fragment.cts;
+
+import android.app.Fragment;
+import android.content.Context;
+import android.os.Bundle;
+
+/**
+ * This fragment watches its primary lifecycle events and throws IllegalStateException
+ * if any of them are called out of order or from a bad/unexpected state.
+ */
+public class StrictFragment extends Fragment {
+    public static final int DETACHED = 0;
+    public static final int ATTACHED = 1;
+    public static final int CREATED = 2;
+    public static final int ACTIVITY_CREATED = 3;
+    public static final int STARTED = 4;
+    public static final int RESUMED = 5;
+
+    int mState;
+
+    boolean mCalledOnAttach, mCalledOnCreate, mCalledOnActivityCreated,
+            mCalledOnStart, mCalledOnResume, mCalledOnSaveInstanceState,
+            mCalledOnPause, mCalledOnStop, mCalledOnDestroy, mCalledOnDetach;
+
+    static String stateToString(int state) {
+        switch (state) {
+            case DETACHED: return "DETACHED";
+            case ATTACHED: return "ATTACHED";
+            case CREATED: return "CREATED";
+            case ACTIVITY_CREATED: return "ACTIVITY_CREATED";
+            case STARTED: return "STARTED";
+            case RESUMED: return "RESUMED";
+        }
+        return "(unknown " + state + ")";
+    }
+
+    public void checkGetActivity() {
+        if (getActivity() == null) {
+            throw new IllegalStateException("getActivity() returned null at unexpected time");
+        }
+    }
+
+    public void checkState(String caller, int... expected) {
+        if (expected == null || expected.length == 0) {
+            throw new IllegalArgumentException("must supply at least one expected state");
+        }
+        for (int expect : expected) {
+            if (mState == expect) {
+                return;
+            }
+        }
+        final StringBuilder expectString = new StringBuilder(stateToString(expected[0]));
+        for (int i = 1; i < expected.length; i++) {
+            expectString.append(" or ").append(stateToString(expected[i]));
+        }
+        throw new IllegalStateException(caller + " called while fragment was "
+                + stateToString(mState) + "; expected " + expectString.toString());
+    }
+
+    public void checkStateAtLeast(String caller, int minState) {
+        if (mState < minState) {
+            throw new IllegalStateException(caller + " called while fragment was "
+                    + stateToString(mState) + "; expected at least " + stateToString(minState));
+        }
+    }
+
+    @Override
+    public void onAttach(Context context) {
+        super.onAttach(context);
+        mCalledOnAttach = true;
+        checkState("onAttach", DETACHED);
+        mState = ATTACHED;
+        checkGetActivity();
+    }
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        if (mCalledOnCreate) {
+            throw new IllegalStateException("onCreate called more than once");
+        }
+        mCalledOnCreate = true;
+        checkState("onCreate", ATTACHED);
+        mState = CREATED;
+        checkGetActivity();
+    }
+
+    @Override
+    public void onActivityCreated(Bundle savedInstanceState) {
+        super.onActivityCreated(savedInstanceState);
+        mCalledOnActivityCreated = true;
+        checkState("onActivityCreated", ATTACHED, CREATED);
+        mState = ACTIVITY_CREATED;
+        checkGetActivity();
+    }
+
+    @Override
+    public void onStart() {
+        super.onStart();
+        mCalledOnStart = true;
+        checkState("onStart", ACTIVITY_CREATED);
+        mState = STARTED;
+        checkGetActivity();
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        mCalledOnResume = true;
+        checkState("onResume", STARTED);
+        mState = RESUMED;
+        checkGetActivity();
+    }
+
+    @Override
+    public void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+        mCalledOnSaveInstanceState = true;
+        checkGetActivity();
+        checkStateAtLeast("onSaveInstanceState", STARTED);
+    }
+
+    @Override
+    public void onPause() {
+        super.onPause();
+        mCalledOnPause = true;
+        checkState("onPause", RESUMED);
+        mState = STARTED;
+        checkGetActivity();
+    }
+
+    @Override
+    public void onStop() {
+        super.onStop();
+        mCalledOnStop = true;
+        checkState("onStop", STARTED);
+        mState = CREATED;
+        checkGetActivity();
+    }
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+        mCalledOnDestroy = true;
+        checkState("onDestroy", CREATED);
+        mState = ATTACHED;
+        checkGetActivity();
+    }
+
+    @Override
+    public void onDetach() {
+        super.onDetach();
+        mCalledOnDetach = true;
+        checkState("onDestroy", CREATED, ATTACHED);
+        mState = DETACHED;
+        checkGetActivity();
+    }
+}
diff --git a/tests/fragment/src/android/fragment/cts/StrictViewFragment.java b/tests/fragment/src/android/fragment/cts/StrictViewFragment.java
new file mode 100644
index 0000000..8c0ab51
--- /dev/null
+++ b/tests/fragment/src/android/fragment/cts/StrictViewFragment.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.fragment.cts;
+
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+public class StrictViewFragment extends StrictFragment {
+    boolean mOnCreateViewCalled, mOnViewCreatedCalled, mOnDestroyViewCalled;
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+            Bundle savedInstanceState) {
+        checkGetActivity();
+        checkState("onCreateView", CREATED);
+        final View result = inflater.inflate(R.layout.strict_view_fragment, container, false);
+        mOnCreateViewCalled = true;
+        return result;
+    }
+
+    @Override
+    public void onViewCreated(View view, Bundle savedInstanceState) {
+        if (view == null) {
+            throw new IllegalArgumentException("onViewCreated view argument should not be null");
+        }
+        checkGetActivity();
+        checkState("onViewCreated", CREATED);
+        mOnViewCreatedCalled = true;
+    }
+
+    @Override
+    public void onDestroyView() {
+        super.onDestroyView();
+        if (getView() == null) {
+            throw new IllegalStateException("getView returned null in onDestroyView");
+        }
+        checkGetActivity();
+        checkState("onDestroyView", CREATED);
+        mOnDestroyViewCalled = true;
+    }
+}
diff --git a/tests/inputmethod/Android.mk b/tests/inputmethod/Android.mk
new file mode 100644
index 0000000..3a90fa9
--- /dev/null
+++ b/tests/inputmethod/Android.mk
@@ -0,0 +1,29 @@
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := CtsInputMethodTestCases
+
+LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner android-support-test
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/inputmethod/AndroidManifest.xml b/tests/inputmethod/AndroidManifest.xml
new file mode 100644
index 0000000..038b164
--- /dev/null
+++ b/tests/inputmethod/AndroidManifest.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+    Copyright (C) 2015 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="android.inputmethod.cts">
+
+    <application >
+        <uses-library android:name="android.test.runner"/>
+
+        <activity android:name="android.inputmethod.cts.TestActivity" />
+        <service android:name="android.inputmethod.cts.MockInputMethodService"
+                 android:permission="android.permission.BIND_INPUT_METHOD">
+            <intent-filter>
+                <action android:name="android.view.InputMethod" />
+            </intent-filter>
+            <meta-data android:name="android.view.im" android:resource="@xml/method" />
+        </service>
+    </application>
+
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="android.inputmethod.cts"
+                     android:label="Tests for the InputMethod APIs."/>
+
+</manifest>
diff --git a/tests/inputmethod/AndroidTest.xml b/tests/inputmethod/AndroidTest.xml
new file mode 100644
index 0000000..3a52042
--- /dev/null
+++ b/tests/inputmethod/AndroidTest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS Input test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsInputMethodTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.inputmethod.cts" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/inputmethod/res/xml/method.xml b/tests/inputmethod/res/xml/method.xml
new file mode 100644
index 0000000..fc2ec95
--- /dev/null
+++ b/tests/inputmethod/res/xml/method.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+    Copyright (C) 2015 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+
+<input-method xmlns:android="http://schemas.android.com/apk/res/android"
+              android:isDefault="True">
+    <subtype android:imeSubtypeLocale="en_US" android:imeSubtypeMode="keyboard" />
+</input-method>
diff --git a/tests/inputmethod/src/android/inputmethod/cts/InputMethodServiceTest.java b/tests/inputmethod/src/android/inputmethod/cts/InputMethodServiceTest.java
new file mode 100644
index 0000000..c68d448
--- /dev/null
+++ b/tests/inputmethod/src/android/inputmethod/cts/InputMethodServiceTest.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.inputmethod.cts;
+
+import android.annotation.NonNull;
+import android.content.pm.PackageManager;
+import android.os.IBinder;
+import android.inputmethodservice.InputMethodService;
+import android.test.InstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.inputmethod.InputMethodManager;
+
+import java.util.List;
+
+public class InputMethodServiceTest extends InstrumentationTestCase {
+    private String mTestImeId;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        mTestImeId = getInstrumentation().getContext().getPackageName() +
+                "/" + MockInputMethodService.class.getName();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    /**
+     * Ensures that the IME with {@code imeId} is not enabled.
+     *
+     * This method ensures that no IME with {@code imeId} is enabled. If the given IME is currently
+     * in use, switches to another IME first. Then, if the given IME is enabled, disables it.
+     */
+    private void ensureImeNotEnabled(@NonNull final String imeId) {
+        final String currentImeId =
+                InputMethodServiceTestUtil.getCurrentImeId(getInstrumentation());
+        if (currentImeId.equals(imeId)) {
+            // Requested IME is already used. This typically happens if the previous test case is
+            // not finished gracefully. In this case, selects another IME.
+            String otherImeCandidate = null;
+            final List<String> enabledImes =
+                    InputMethodServiceTestUtil.getEnabledImeIds(getInstrumentation());
+            for (final String enabledIme : enabledImes) {
+                if (!enabledIme.equals(imeId)) {
+                    otherImeCandidate = imeId;
+                    break;
+                }
+            }
+            if (otherImeCandidate == null) {
+                // When PackageManager.hasSystemFeature(PackageManager.FEATURE_INPUT_METHODS)
+                // returns true, this case must not happen.
+                throw new IllegalStateException(
+                        "No other IME is available. Unable to continue tests.");
+            }
+            assertTrue(InputMethodServiceTestUtil.setIme(getInstrumentation(), otherImeCandidate));
+        }
+
+        if (InputMethodServiceTestUtil.isImeEnabled(getInstrumentation(), imeId)) {
+            assertTrue(InputMethodServiceTestUtil.disableIme(getInstrumentation(), imeId));
+        }
+    }
+
+    /**
+     * Asserts the given service is not running.
+     */
+    private void assertServiceNotRunning() {
+        assertTrue(MockInputMethodService.getInstance() == null ||
+                MockInputMethodService.getInstance().getCallCount("onCreate") == 0);
+    }
+
+    /**
+     * This test checks the following APIs.
+     * <ul>
+     *   <li>{@link InputMethodManager#getEnabledInputMethodList()}</li>
+     *   <li>{@link InputMethodManager#getInputMethodList()}</li>
+     *   <li>{@link InputMethodManager#setInputMethod(IBinder, String)}</li>
+     *   <li>{@link InputMethodService#onCreate()}</li>
+     *   <li>{@link InputMethodService#onDestroy()}</li>
+     * </ul>
+     */
+    @MediumTest
+    public void testCreateAndDestroy() {
+        if (!getInstrumentation().getContext().getPackageManager().hasSystemFeature(
+                PackageManager.FEATURE_INPUT_METHODS)) {
+            // The "input method" system feature is not supported on this device.
+            return;
+        }
+
+        // Clear the counter in the mock service, since it might have been used in a previous test.
+        MockInputMethodService.resetCounter();
+
+        ensureImeNotEnabled(mTestImeId);
+
+        final String ImeIdToRestore =
+                InputMethodServiceTestUtil.getCurrentImeId(getInstrumentation());
+        MockInputMethodService service = MockInputMethodService.getInstance();
+        assertServiceNotRunning();
+
+        try {
+            // Enable test IME.
+            assertTrue(InputMethodServiceTestUtil.enableIme(getInstrumentation(), mTestImeId));
+            service = MockInputMethodService.getInstance();
+            assertServiceNotRunning();
+
+            // Select test IME.
+            assertTrue(InputMethodServiceTestUtil.setIme(getInstrumentation(), mTestImeId));
+            service = MockInputMethodService.getInstance();
+            assertNotNull(service);
+            assertEquals(1, MockInputMethodService.getCallCount("<init>"));
+            assertEquals(1, MockInputMethodService.getCallCount("onCreate"));
+        } finally {
+            // Restores IMEs to original one.
+            InputMethodServiceTestUtil.setIme(getInstrumentation(), ImeIdToRestore);
+            InputMethodServiceTestUtil.disableIme(getInstrumentation(), mTestImeId);
+            assertEquals(1, MockInputMethodService.getCallCount("onDestroy"));
+        }
+    }
+}
diff --git a/tests/inputmethod/src/android/inputmethod/cts/InputMethodServiceTestUtil.java b/tests/inputmethod/src/android/inputmethod/cts/InputMethodServiceTestUtil.java
new file mode 100644
index 0000000..aa46c38
--- /dev/null
+++ b/tests/inputmethod/src/android/inputmethod/cts/InputMethodServiceTestUtil.java
@@ -0,0 +1,193 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.inputmethod.cts;
+
+import android.annotation.NonNull;
+import android.app.Instrumentation;
+import android.app.UiAutomation;
+import android.content.Context;
+import android.os.IBinder;
+import android.os.ParcelFileDescriptor;
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.inputmethod.InputMethodInfo;
+import android.view.inputmethod.InputMethodManager;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Utility functions for testing of input method stuff.
+ */
+public final class InputMethodServiceTestUtil {
+    private static final String TAG = InputMethodServiceTestUtil.class.getSimpleName();
+
+    // Prevents this from being instantiated.
+    private InputMethodServiceTestUtil() {}
+
+    @NonNull
+    private static String executeShellCommand(final UiAutomation uiAutomation, final String[] cmd) {
+        final String flattenCmd = TextUtils.join(" ", cmd);
+        List<String> output = new ArrayList<>();
+
+        try (final ParcelFileDescriptor fd = uiAutomation.executeShellCommand(flattenCmd);
+             final FileReader fr = new FileReader(fd.getFileDescriptor());
+             final BufferedReader br = new BufferedReader(fr)) {
+
+            String line;
+            while ((line = br.readLine()) != null) {
+                output.add(line);
+            }
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+
+        // The output from the "ime" command should be only one line.
+        if (output.size() != 1) {
+            throw new IllegalStateException(
+                    "The output from 'ime' command should be one line, but it outputs multiples: " +
+                    TextUtils.join("\n", output));
+        }
+        return output.get(0);
+    }
+
+    @NonNull
+    public static String getCurrentImeId(final Instrumentation inst) {
+        return Settings.Secure.getString(inst.getContext().getContentResolver(),
+                Settings.Secure.DEFAULT_INPUT_METHOD);
+    }
+
+    public static boolean isImeEnabled(final Instrumentation inst, final String imeId) {
+        final List<String> enabledImes = getEnabledImeIds(inst);
+        return enabledImes.contains(imeId);
+    }
+
+    @NonNull
+    public static List<String> getEnabledImeIds(final Instrumentation inst) {
+        InputMethodManager imm = (InputMethodManager) inst.getContext().getSystemService(
+                Context.INPUT_METHOD_SERVICE);
+        final List<InputMethodInfo> enabledImes = imm.getEnabledInputMethodList();
+        List<String> result = new ArrayList<>();
+        for (final InputMethodInfo enabledIme : enabledImes) {
+            result.add(enabledIme.getId());
+        }
+        return result;
+    }
+
+    /**
+     * Puts the specified IME into the available input method list.
+     *
+     * This operation will be done synchronously in "ime" command using
+     * {@link com.android.server.InputMethodManagerService#setInputMethodEnabled(String, boolean)},
+     * which is synchronous.
+     *
+     * @param imeId IME ID to be enabled.
+     * @return {@code true} if the target IME gets enabled successfully. {@code false} if failed.
+     */
+    public static boolean enableIme(final Instrumentation inst, final String imeId) {
+        // Needs to check the output message from the checking command, since executeShellCommand()
+        // does not pass the exit status code back to the test.
+        final String output = executeShellCommand(
+                inst.getUiAutomation(), new String[]{"ime", "enable", imeId});
+        final String expectedOutput = "Input method " + imeId + ": now enabled";
+        if (!output.equals(expectedOutput)) {
+            Log.e(TAG, "Unexpected output message. Expected: " + expectedOutput +
+                    ", Actual: " + output);
+            return false;
+        }
+
+        final InputMethodManager imm = (InputMethodManager) inst.getContext().getSystemService(
+                Context.INPUT_METHOD_SERVICE);
+        final List<InputMethodInfo> enabledInputMethods = imm.getEnabledInputMethodList();
+        for (final InputMethodInfo imi : enabledInputMethods) {
+            if (imi.getId().equals(imeId))
+                return true;
+        }
+
+        Log.e(TAG, "Failed to enable the given IME (IME ID: " + imeId + ").");
+        return false;
+    }
+
+    /**
+     * Removes the specified IME from the available input method list.
+     *
+     * This operation will {@code @NonNull} final be done synchronously in "ime" command using
+     * {@link com.android.server.InputMethodManagerService#setInputMethodEnabled(String, boolean)},
+     * which is synchronous.
+     *
+     * @param imeId IME ID to be disabled.
+     * @return {@code true} if the target IME gets disabled successfully. {@code false} if failed.
+     */
+    public static boolean disableIme(final Instrumentation inst, final String imeId) {
+        // Needs to check the output message from the checking command, since executeShellCommand()
+        // does not pass the exit status code back to the test.
+        final String output = executeShellCommand(
+                inst.getUiAutomation(), new String[]{"ime", "disable", imeId});
+        final String expectedOutput = "Input method " + imeId + ": now disabled";
+        if (!output.equals(expectedOutput)) {
+            Log.w(TAG, "Unexpected output message. Expected: " + expectedOutput +
+                    ", Actual: " + output);
+            return false;
+        }
+
+        final InputMethodManager imm = (InputMethodManager) inst.getContext().getSystemService(
+                Context.INPUT_METHOD_SERVICE);
+        final List<InputMethodInfo> enabledInputMethods = imm.getEnabledInputMethodList();
+        for (final InputMethodInfo imi : enabledInputMethods) {
+            if (imi.getId().equals(imeId)) {
+                Log.e(TAG, "Failed to disable the given IME (IME ID: " + imeId + ").");
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Switches to the specified IME.
+     *
+     * This operation will be done synchronously in the "ime" command using
+     * {@link InputMethodManager#setInputMethod(IBinder, String)}, which is synchronous.
+     *
+     * @param imeId IME ID to be switched to.
+     * @return {@code true} if the target IME gets active successfully. {@code false} if failed.
+     */
+    public static boolean setIme(final Instrumentation inst, final String imeId) {
+        // Needs to check the output message from the checking command, since executeShellCommand()
+        // does not pass the exit status code back to the test.
+        final String output = executeShellCommand(
+                inst.getUiAutomation(), new String[]{"ime", "set", imeId});
+        final String expectedOutput = "Input method " + imeId + " selected";
+        if (!output.equals(expectedOutput)) {
+            Log.w(TAG, "Unexpected output message. Expected: " + expectedOutput +  ", Actual: " +
+                    output);
+            return false;
+        }
+
+        final String currentImeId = getCurrentImeId(inst);
+        if (!TextUtils.equals(currentImeId, imeId)) {
+            Log.e(TAG, "Failed to switch the current IME. Expected: " + imeId +  ", Actual: " +
+                    currentImeId);
+            return false;
+        }
+
+        return true;
+    }
+}
diff --git a/tests/inputmethod/src/android/inputmethod/cts/MockInputMethodService.java b/tests/inputmethod/src/android/inputmethod/cts/MockInputMethodService.java
new file mode 100644
index 0000000..12b80a5
--- /dev/null
+++ b/tests/inputmethod/src/android/inputmethod/cts/MockInputMethodService.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.inputmethod.cts;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.inputmethodservice.InputMethodService;
+
+import java.util.HashMap;
+import java.util.concurrent.atomic.AtomicReference;
+
+/**
+ * A mock implementation of {@link InputMethodService} for testing purpose.
+ */
+public class MockInputMethodService extends InputMethodService {
+    private static AtomicReference<MockInputMethodService> sCurrentInstance =
+            new AtomicReference<>();
+    private static final HashMap<String, Integer> mCallCounter = new HashMap<>();
+
+    /**
+     * @return The instance of {@code MockInputMethodService}. If the service has not been created
+     * yet or already been destroyed, returns {@code null}.
+     */
+    @Nullable
+    public static MockInputMethodService getInstance() {
+        return sCurrentInstance.get();
+    }
+
+    public static void resetCounter() {
+        synchronized (mCallCounter) {
+            mCallCounter.clear();
+        }
+    }
+
+    private static void incrementCallCount(@NonNull final String methodName) {
+        synchronized (mCallCounter) {
+            if (!mCallCounter.containsKey(methodName)) {
+                mCallCounter.put(methodName, 0);
+            }
+            mCallCounter.put(methodName, mCallCounter.get(methodName) + 1);
+        }
+    }
+
+    public static int getCallCount(@NonNull final String methodName) {
+        synchronized (mCallCounter) {
+            if (!mCallCounter.containsKey(methodName)) {
+                return 0;
+            }
+            return mCallCounter.get(methodName);
+        }
+    }
+
+    public MockInputMethodService() {
+        incrementCallCount("<init>");
+    }
+
+    @Override
+    public void onCreate() {
+        if (!sCurrentInstance.compareAndSet(null, this)) {
+            throw new IllegalStateException("New MockInputMethodService instance is being created "
+                    + "before the existing instance is destroyed.");
+        }
+
+        super.onCreate();
+        incrementCallCount("onCreate");
+    }
+
+    @Override
+    public void onDestroy() {
+        sCurrentInstance.lazySet(null);
+        super.onDestroy();
+        incrementCallCount("onDestroy");
+    }
+}
+
diff --git a/tests/jank/Android.mk b/tests/jank/Android.mk
new file mode 100644
index 0000000..a42a68b
--- /dev/null
+++ b/tests/jank/Android.mk
@@ -0,0 +1,34 @@
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := CtsJankDeviceTestCases
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil compatibility-device-util ctstestrunner ub-uiautomator ub-janktesthelper
+
+LOCAL_CTS_MODULE_CONFIG := $(LOCAL_PATH)/Old$(CTS_MODULE_TEST_CONFIG)
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/jank/AndroidManifest.xml b/tests/jank/AndroidManifest.xml
new file mode 100644
index 0000000..f7b3232
--- /dev/null
+++ b/tests/jank/AndroidManifest.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="android.jank.cts">
+
+  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+  <application>
+      <uses-library android:name="android.test.runner"/>
+  </application>
+
+  <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                   android:targetPackage="android.jank.cts"
+                   android:label="Jank tests">
+        <meta-data android:name="listener"
+            android:value="com.android.cts.runner.CtsTestRunListener" />
+    </instrumentation>
+
+</manifest>
diff --git a/tests/jank/AndroidTest.xml b/tests/jank/AndroidTest.xml
new file mode 100644
index 0000000..c7e476a
--- /dev/null
+++ b/tests/jank/AndroidTest.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS Jank test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsUiDeviceTestCases.apk" />
+        <option name="test-file-name" value="CtsJankDeviceTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.jank.cts" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/jank/OldAndroidTest.xml b/tests/jank/OldAndroidTest.xml
new file mode 100644
index 0000000..633f650
--- /dev/null
+++ b/tests/jank/OldAndroidTest.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS Jank Test Cases">
+    <include name="common-config" />
+    <option name="cts-apk-installer:test-file-name" value="CtsUiDeviceTestCases.apk" />
+</configuration>
diff --git a/tests/jank/src/android/jank/cts/CtsJankTestBase.java b/tests/jank/src/android/jank/cts/CtsJankTestBase.java
new file mode 100644
index 0000000..fb2f867
--- /dev/null
+++ b/tests/jank/src/android/jank/cts/CtsJankTestBase.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.jank.cts;
+
+import android.os.Bundle;
+import android.support.test.jank.JankTestBase;
+import android.support.test.jank.WindowContentFrameStatsMonitor;
+import android.support.test.uiautomator.UiDevice;
+
+import com.android.compatibility.common.util.DeviceReportLog;
+import com.android.compatibility.common.util.ResultType;
+import com.android.compatibility.common.util.ResultUnit;
+
+public abstract class CtsJankTestBase extends JankTestBase {
+
+    private UiDevice mDevice;
+    private DeviceReportLog mLog;
+
+    @Override
+    public void afterTest(Bundle metrics) {
+        String source = String.format("%s#%s", getClass().getCanonicalName(), getName());
+        mLog.addValue(source, WindowContentFrameStatsMonitor.KEY_AVG_FPS,
+                metrics.getDouble(WindowContentFrameStatsMonitor.KEY_AVG_FPS),
+                ResultType.HIGHER_BETTER, ResultUnit.FPS);
+        mLog.addValue(source, WindowContentFrameStatsMonitor.KEY_AVG_LONGEST_FRAME,
+                metrics.getDouble(WindowContentFrameStatsMonitor.KEY_AVG_LONGEST_FRAME),
+                ResultType.LOWER_BETTER, ResultUnit.MS);
+        mLog.addValue(source, WindowContentFrameStatsMonitor.KEY_MAX_NUM_JANKY,
+                metrics.getInt(WindowContentFrameStatsMonitor.KEY_MAX_NUM_JANKY),
+                ResultType.LOWER_BETTER, ResultUnit.COUNT);
+        mLog.setSummary(WindowContentFrameStatsMonitor.KEY_AVG_NUM_JANKY,
+                metrics.getDouble(WindowContentFrameStatsMonitor.KEY_AVG_NUM_JANKY),
+                ResultType.LOWER_BETTER, ResultUnit.COUNT);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mLog = new DeviceReportLog();
+        // fix device orientation
+        mDevice = UiDevice.getInstance(getInstrumentation());
+        mDevice.setOrientationNatural();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        mLog.submit(getInstrumentation());
+        // restore device orientation
+        mDevice.unfreezeRotation();
+        super.tearDown();
+    }
+
+    protected UiDevice getUiDevice() {
+        return mDevice;
+    }
+}
diff --git a/tests/jank/src/android/jank/cts/ui/CtsDeviceJankUi.java b/tests/jank/src/android/jank/cts/ui/CtsDeviceJankUi.java
new file mode 100644
index 0000000..2e389d7
--- /dev/null
+++ b/tests/jank/src/android/jank/cts/ui/CtsDeviceJankUi.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 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.jank.cts.ui;
+
+import android.content.ComponentName;
+import android.content.Intent;
+import android.jank.cts.CtsJankTestBase;
+import android.os.SystemClock;
+import android.support.test.jank.JankTest;
+import android.support.test.jank.WindowContentFrameStatsMonitor;
+import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.Direction;
+import android.support.test.uiautomator.Until;
+import android.widget.ListView;
+
+import java.io.IOException;
+
+public class CtsDeviceJankUi extends CtsJankTestBase {
+    private final static int NUM_ELEMENTS = 1000;
+    private static final long DEFAULT_ANIMATION_TIME = 2 * 1000;
+    private static final long POST_SCROLL_IDLE_TIME = 2 *1000;
+    private final static String PACKAGE = "android.ui.cts";
+    private final static String CLASS = PACKAGE + ".ScrollingActivity";
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        // launch the activity as part of the set up
+        Intent intent = new Intent(Intent.ACTION_MAIN);
+        intent.setComponent(new ComponentName(PACKAGE, CLASS));
+        intent.putExtra("num_elements", NUM_ELEMENTS);
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        getInstrumentation().getTargetContext().startActivity(intent);
+        getUiDevice().wait(Until.hasObject(By.pkg(PACKAGE)), DEFAULT_ANIMATION_TIME);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        getUiDevice().pressHome();
+        super.tearDown();
+    }
+
+    @JankTest(expectedFrames=50, defaultIterationCount=5)
+    @WindowContentFrameStatsMonitor
+    public void testScrolling() throws IOException {
+        getUiDevice().findObject(By.clazz(ListView.class)).fling(Direction.DOWN);
+        SystemClock.sleep(POST_SCROLL_IDLE_TIME);
+    }
+}
diff --git a/tests/leanbackjank/Android.mk b/tests/leanbackjank/Android.mk
index b3adfb1..b762dc9 100644
--- a/tests/leanbackjank/Android.mk
+++ b/tests/leanbackjank/Android.mk
@@ -21,11 +21,22 @@
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src) \
-        ./app/src/android/cts/jank/leanback/IntentKeys.java
+        ./app/src/android/leanbackjank/app/IntentKeys.java
 
 LOCAL_PACKAGE_NAME := CtsLeanbackJankTestCases
 
-LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctstestrunner ub-uiautomator ub-janktesthelper android-support-v17-leanback
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
+    ctsdeviceutil \
+    ctstestrunner \
+    ub-uiautomator \
+    ub-janktesthelper \
+    android-support-v17-leanback \
+    android-support-v4
+
+LOCAL_CTS_MODULE_CONFIG := $(LOCAL_PATH)/Old$(CTS_MODULE_TEST_CONFIG)
 
 include $(BUILD_CTS_PACKAGE)
 
diff --git a/tests/leanbackjank/AndroidManifest.xml b/tests/leanbackjank/AndroidManifest.xml
index 1cd552d..27cdbe6 100644
--- a/tests/leanbackjank/AndroidManifest.xml
+++ b/tests/leanbackjank/AndroidManifest.xml
@@ -17,15 +17,15 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-        package="android.cts.leanbackjank">
+        package="android.leanbackjank.cts">
 
   <application>
       <uses-library android:name="android.test.runner"/>
   </application>
 
   <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                   android:targetPackage="android.cts.leanbackjank"
-                   android:label="Jank tests">
+                   android:targetPackage="android.leanbackjank.cts"
+                   android:label="LeanbackJank tests">
         <meta-data android:name="listener"
             android:value="com.android.cts.runner.CtsTestRunListener" />
     </instrumentation>
diff --git a/tests/leanbackjank/AndroidTest.xml b/tests/leanbackjank/AndroidTest.xml
index e61c58d..a07c2eb 100644
--- a/tests/leanbackjank/AndroidTest.xml
+++ b/tests/leanbackjank/AndroidTest.xml
@@ -13,7 +13,13 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<configuration description="CTS Jank test config">
-    <include name="common-config" />
-    <option name="cts-apk-installer:test-file-name" value="CtsLeanbackJank.apk" />
+<configuration description="Config for CTS LeanbackJank test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsLeanbackJankTestCases.apk" />
+        <option name="test-file-name" value="CtsLeanbackJankApp.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.leanbackjank.cts" />
+    </test>
 </configuration>
diff --git a/tests/leanbackjank/OldAndroidTest.xml b/tests/leanbackjank/OldAndroidTest.xml
new file mode 100644
index 0000000..1ee5722
--- /dev/null
+++ b/tests/leanbackjank/OldAndroidTest.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS LeanbackJank Test Cases">
+    <include name="common-config" />
+    <option name="cts-apk-installer:test-file-name" value="CtsLeanbackJankApp.apk" />
+</configuration>
diff --git a/tests/leanbackjank/app/Android.mk b/tests/leanbackjank/app/Android.mk
index 5abe1a7..e2cbf89 100644
--- a/tests/leanbackjank/app/Android.mk
+++ b/tests/leanbackjank/app/Android.mk
@@ -22,7 +22,10 @@
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
-LOCAL_PACKAGE_NAME := CtsLeanbackJank
+LOCAL_PACKAGE_NAME := CtsLeanbackJankApp
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
 
 LOCAL_RESOURCE_DIR := \
     $(TOP)/frameworks/support/v17/leanback/res \
diff --git a/tests/leanbackjank/app/AndroidManifest.xml b/tests/leanbackjank/app/AndroidManifest.xml
index 333399e..1e1ff3b 100644
--- a/tests/leanbackjank/app/AndroidManifest.xml
+++ b/tests/leanbackjank/app/AndroidManifest.xml
@@ -16,7 +16,7 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.cts.jank.leanback"
+    package="android.leanbackjank.app"
     android:versionCode="1"
     android:versionName="1.1" >
 
diff --git a/tests/leanbackjank/app/src/android/cts/jank/leanback/IntentKeys.java b/tests/leanbackjank/app/src/android/cts/jank/leanback/IntentKeys.java
deleted file mode 100644
index e9c5e6e..0000000
--- a/tests/leanbackjank/app/src/android/cts/jank/leanback/IntentKeys.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package android.cts.jank.leanback;
-
-/**
- * Intent key strings of the leanback jank test helper app.
- */
-public class IntentKeys {
-    public static final String SCROLL_COUNT = "SCROLL_COUNT";
-    public static final String SCROLL_DELAY = "SCROLL_DELAY";
-    public static final String SCROLL_INTERVAL = "SCROLL_INTERVAL";
-}
diff --git a/tests/leanbackjank/app/src/android/cts/jank/leanback/Utils.java b/tests/leanbackjank/app/src/android/cts/jank/leanback/Utils.java
deleted file mode 100644
index de6d6af..0000000
--- a/tests/leanbackjank/app/src/android/cts/jank/leanback/Utils.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.cts.jank.leanback;
-
-import android.app.Activity;
-import android.content.Context;
-import android.graphics.Point;
-import android.media.MediaMetadataRetriever;
-import android.os.Build;
-import android.util.DisplayMetrics;
-import android.view.Display;
-import android.view.WindowManager;
-import android.widget.FrameLayout;
-import android.widget.Toast;
-import android.widget.VideoView;
-
-import java.util.HashMap;
-
-/**
- * A collection of utility methods, all static.
- */
-public class Utils {
-
-    public interface MediaDimensions {
-        double MEDIA_HEIGHT = 0.95;
-        double MEDIA_WIDTH = 0.95;
-        double MEDIA_TOP_MARGIN = 0.025;
-        double MEDIA_RIGHT_MARGIN = 0.025;
-        double MEDIA_BOTTOM_MARGIN = 0.025;
-        double MEDIA_LEFT_MARGIN = 0.025;
-    }
-
-    /*
-     * Making sure public utility methods remain static
-     */
-    private Utils() {
-    }
-
-    /**
-     * Returns the screen/display size
-     */
-    public static Point getDisplaySize(Context context) {
-        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
-        Display display = wm.getDefaultDisplay();
-        Point size = new Point();
-        display.getSize(size);
-        return size;
-    }
-
-    /**
-     * Shows a (long) toast
-     */
-    public static void showToast(Context context, String msg) {
-        Toast.makeText(context, msg, Toast.LENGTH_LONG).show();
-    }
-
-    /**
-     * Shows a (long) toast.
-     */
-    public static void showToast(Context context, int resourceId) {
-        Toast.makeText(context, context.getString(resourceId), Toast.LENGTH_LONG).show();
-    }
-
-    public static int convertDpToPixel(Context ctx, int dp) {
-        float density = ctx.getResources().getDisplayMetrics().density;
-        return Math.round((float) dp * density);
-    }
-
-
-    /**
-     * Example for handling resizing content for overscan.  Typically you won't need to resize
-     * when using the Leanback support library.
-     */
-    public void overScan(Activity activity, VideoView videoView) {
-        DisplayMetrics metrics = new DisplayMetrics();
-        activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
-        int w = (int) (metrics.widthPixels * MediaDimensions.MEDIA_WIDTH);
-        int h = (int) (metrics.heightPixels * MediaDimensions.MEDIA_HEIGHT);
-        int marginLeft = (int) (metrics.widthPixels * MediaDimensions.MEDIA_LEFT_MARGIN);
-        int marginTop = (int) (metrics.heightPixels * MediaDimensions.MEDIA_TOP_MARGIN);
-        int marginRight = (int) (metrics.widthPixels * MediaDimensions.MEDIA_RIGHT_MARGIN);
-        int marginBottom = (int) (metrics.heightPixels * MediaDimensions.MEDIA_BOTTOM_MARGIN);
-        FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(w, h);
-        lp.setMargins(marginLeft, marginTop, marginRight, marginBottom);
-        videoView.setLayoutParams(lp);
-    }
-
-
-    public static long getDuration(String videoUrl) {
-        MediaMetadataRetriever mmr = new MediaMetadataRetriever();
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
-            mmr.setDataSource(videoUrl, new HashMap<String, String>());
-        } else {
-            mmr.setDataSource(videoUrl);
-        }
-        return Long.parseLong(mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION));
-    }
-}
diff --git a/tests/leanbackjank/app/src/android/cts/jank/leanback/data/VideoProvider.java b/tests/leanbackjank/app/src/android/cts/jank/leanback/data/VideoProvider.java
deleted file mode 100644
index fa317ed..0000000
--- a/tests/leanbackjank/app/src/android/cts/jank/leanback/data/VideoProvider.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.cts.jank.leanback.data;
-
-import android.cts.jank.leanback.model.Movie;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-
-/**
- * Provides synthesized movie data.
- */
-public class VideoProvider {
-    private static HashMap<String, List<Movie>> sMovieList;
-    private static HashMap<String, Movie> sMovieListById;
-
-    public static Movie getMovieById(String mediaId) {
-        return sMovieListById.get(mediaId);
-    }
-
-    public static HashMap<String, List<Movie>> getMovieList() {
-        return sMovieList;
-    }
-
-    public static HashMap<String, List<Movie>> buildMedia(int nCategories) {
-        if (null != sMovieList) {
-            return sMovieList;
-        }
-        sMovieList = new HashMap<>();
-        sMovieListById = new HashMap<>();
-
-        String title = new String();
-        String studio = new String();
-        for (int i = 0; i < nCategories; i++) {
-            String category_name = String.format("Category %d",  i);
-            List<Movie> categoryList = new ArrayList<Movie>();
-            for (int j = 0; j < 20; j++) {
-                String description = "This is description of a movie.";
-                title = String.format("Video %d-%d", i, j);
-                studio = String.format("Studio %d", (i + j) % 7);
-                Movie movie = buildMovieInfo(category_name, title, description, studio);
-                sMovieListById.put(movie.getId(), movie);
-                categoryList.add(movie);
-            }
-            sMovieList.put(category_name, categoryList);
-        }
-        return sMovieList;
-    }
-
-    private static Movie buildMovieInfo(String category,
-                                        String title,
-                                        String description,
-                                        String studio) {
-        Movie movie = new Movie();
-        movie.setId(Movie.getCount());
-        Movie.incrementCount();
-        movie.setTitle(title);
-        movie.setDescription(description);
-        movie.setStudio(studio);
-        movie.setCategory(category);
-
-        return movie;
-    }
-}
diff --git a/tests/leanbackjank/app/src/android/cts/jank/leanback/model/Movie.java b/tests/leanbackjank/app/src/android/cts/jank/leanback/model/Movie.java
deleted file mode 100644
index 874bb00..0000000
--- a/tests/leanbackjank/app/src/android/cts/jank/leanback/model/Movie.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.cts.jank.leanback.model;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * Movie class represents video entity with title, description, image thumbs and video url.
- */
-public class Movie implements Parcelable {
-    static final long serialVersionUID = 727566175075960653L;
-    private static int sCount = 0;
-    private String mId;
-    private String mTitle;
-    private String mDescription;
-    private String mStudio;
-    private String mCategory;
-
-    public Movie() {
-    }
-
-    public Movie(Parcel in){
-        String[] data = new String[5];
-
-        in.readStringArray(data);
-        mId = data[0];
-        mTitle = data[1];
-        mDescription = data[2];
-        mStudio = data[3];
-        mCategory = data[4];
-    }
-
-    public static String getCount() {
-        return Integer.toString(sCount);
-    }
-
-    public static void incrementCount() {
-        sCount++;
-    }
-
-    public String getId() {
-        return mId;
-    }
-
-    public void setId(String id) {
-        mId = id;
-    }
-
-    public String getTitle() {
-        return mTitle;
-    }
-
-    public void setTitle(String title) {
-        mTitle = title;
-    }
-
-    public String getDescription() {
-        return mDescription;
-    }
-
-    public void setDescription(String description) {
-        mDescription = description;
-    }
-
-    public String getStudio() {
-        return mStudio;
-    }
-
-    public void setStudio(String studio) {
-        mStudio = studio;
-    }
-
-    public String getCategory() {
-        return mCategory;
-    }
-
-    public void setCategory(String category) {
-        mCategory = category;
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeStringArray(new String[] {mId,
-                mTitle,
-                mDescription,
-                mStudio,
-                mCategory});
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder sb = new StringBuilder(200);
-        sb.append("Movie{");
-        sb.append("mId=" + mId);
-        sb.append(", mTitle='" + mTitle + '\'');
-        sb.append('}');
-        return sb.toString();
-    }
-
-    public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
-        public Movie createFromParcel(Parcel in) {
-            return new Movie(in);
-        }
-
-        public Movie[] newArray(int size) {
-            return new Movie[size];
-        }
-    };
-}
diff --git a/tests/leanbackjank/app/src/android/cts/jank/leanback/presenter/CardPresenter.java b/tests/leanbackjank/app/src/android/cts/jank/leanback/presenter/CardPresenter.java
deleted file mode 100644
index 9f425ca..0000000
--- a/tests/leanbackjank/app/src/android/cts/jank/leanback/presenter/CardPresenter.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.cts.jank.leanback.presenter;
-
-import android.graphics.drawable.Drawable;
-import android.support.v17.leanback.widget.ImageCardView;
-import android.support.v17.leanback.widget.Presenter;
-import android.view.ViewGroup;
-
-import com.bumptech.glide.Glide;
-import android.cts.jank.leanback.R;
-import android.cts.jank.leanback.model.Movie;
-
-/**
- * A CardPresenter is used to generate Views and bind Objects to them on demand.
- * It contains an Image CardView
- */
-public class CardPresenter extends Presenter {
-    private static int CARD_WIDTH = 313;
-    private static int CARD_HEIGHT = 176;
-    private static int sSelectedBackgroundColor;
-    private static int sDefaultBackgroundColor;
-    private Drawable mDefaultCardImage;
-
-    @Override
-    public ViewHolder onCreateViewHolder(ViewGroup parent) {
-        sDefaultBackgroundColor = parent.getResources().getColor(R.color.default_background, null);
-        sSelectedBackgroundColor =
-                parent.getResources().getColor(R.color.selected_background, null);
-        mDefaultCardImage = parent.getResources().getDrawable(R.drawable.movie, null);
-
-        ImageCardView cardView = new ImageCardView(parent.getContext()) {
-            @Override
-            public void setSelected(boolean selected) {
-                updateCardBackgroundColor(this, selected);
-                super.setSelected(selected);
-            }
-        };
-
-        cardView.setFocusable(true);
-        cardView.setFocusableInTouchMode(true);
-        updateCardBackgroundColor(cardView, false);
-        return new ViewHolder(cardView);
-    }
-
-    private static void updateCardBackgroundColor(ImageCardView view, boolean selected) {
-        int color = selected ? sSelectedBackgroundColor : sDefaultBackgroundColor;
-        // Both background colors should be set because the view's background is temporarily visible
-        // during animations.
-        view.setBackgroundColor(color);
-        view.findViewById(R.id.info_field).setBackgroundColor(color);
-    }
-
-    @Override
-    public void onBindViewHolder(Presenter.ViewHolder viewHolder, Object item) {
-        Movie movie = (Movie) item;
-        ImageCardView cardView = (ImageCardView) viewHolder.view;
-
-        cardView.setTitleText(movie.getTitle());
-        cardView.setContentText(movie.getStudio());
-        cardView.setMainImageDimensions(CARD_WIDTH, CARD_HEIGHT);
-        Glide.with(viewHolder.view.getContext())
-                .load(R.drawable.gradation)
-                .centerCrop()
-                .error(mDefaultCardImage)
-                .into(cardView.getMainImageView());
-    }
-
-    @Override
-    public void onUnbindViewHolder(Presenter.ViewHolder viewHolder) {
-        ImageCardView cardView = (ImageCardView) viewHolder.view;
-        // Remove references to images so that the garbage collector can free up memory
-        cardView.setBadgeImage(null);
-        cardView.setMainImage(null);
-    }
-}
diff --git a/tests/leanbackjank/app/src/android/cts/jank/leanback/presenter/GridItemPresenter.java b/tests/leanbackjank/app/src/android/cts/jank/leanback/presenter/GridItemPresenter.java
deleted file mode 100644
index 4084383..0000000
--- a/tests/leanbackjank/app/src/android/cts/jank/leanback/presenter/GridItemPresenter.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.cts.jank.leanback.presenter;
-
-import android.graphics.Color;
-import android.support.v17.leanback.widget.Presenter;
-import android.view.Gravity;
-import android.view.ViewGroup;
-import android.widget.TextView;
-
-import android.cts.jank.leanback.R;
-import android.cts.jank.leanback.ui.MainFragment;
-
-public class GridItemPresenter extends Presenter {
-    private static int GRID_ITEM_WIDTH = 200;
-    private static int GRID_ITEM_HEIGHT = 200;
-
-    private MainFragment mainFragment;
-
-    public GridItemPresenter(MainFragment mainFragment) {
-        this.mainFragment = mainFragment;
-    }
-
-    @Override
-    public ViewHolder onCreateViewHolder(ViewGroup parent) {
-        TextView view = new TextView(parent.getContext());
-        view.setLayoutParams(new ViewGroup.LayoutParams(GRID_ITEM_WIDTH, GRID_ITEM_HEIGHT));
-        view.setFocusable(true);
-        view.setFocusableInTouchMode(true);
-        view.setBackgroundColor(
-            mainFragment.getResources().getColor(R.color.default_background, null));
-        view.setTextColor(Color.WHITE);
-        view.setGravity(Gravity.CENTER);
-        return new ViewHolder(view);
-    }
-
-    @Override
-    public void onBindViewHolder(ViewHolder viewHolder, Object item) {
-        ((TextView) viewHolder.view).setText((String) item);
-    }
-
-    @Override
-    public void onUnbindViewHolder(ViewHolder viewHolder) {
-    }
-}
diff --git a/tests/leanbackjank/app/src/android/cts/jank/leanback/presenter/IconHeaderItemPresenter.java b/tests/leanbackjank/app/src/android/cts/jank/leanback/presenter/IconHeaderItemPresenter.java
deleted file mode 100644
index 42e4c0c..0000000
--- a/tests/leanbackjank/app/src/android/cts/jank/leanback/presenter/IconHeaderItemPresenter.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.cts.jank.leanback.presenter;
-
-import android.content.Context;
-import android.graphics.drawable.Drawable;
-import android.support.v17.leanback.widget.HeaderItem;
-import android.support.v17.leanback.widget.ListRow;
-import android.support.v17.leanback.widget.Presenter;
-import android.support.v17.leanback.widget.RowHeaderPresenter;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import android.cts.jank.leanback.R;
-
-public class IconHeaderItemPresenter extends RowHeaderPresenter {
-    private float mUnselectedAlpha;
-
-    @Override
-    public ViewHolder onCreateViewHolder(ViewGroup viewGroup) {
-        mUnselectedAlpha = viewGroup.getResources()
-                .getFraction(R.fraction.lb_browse_header_unselect_alpha, 1, 1);
-        LayoutInflater inflater = (LayoutInflater) viewGroup.getContext()
-                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-
-        View view = inflater.inflate(R.layout.icon_header_item, null);
-
-        return new ViewHolder(view);
-    }
-
-    @Override
-    public void onBindViewHolder(Presenter.ViewHolder viewHolder, Object o) {
-        HeaderItem headerItem = ((ListRow) o).getHeaderItem();
-        View rootView = viewHolder.view;
-
-        ImageView iconView = (ImageView) rootView.findViewById(R.id.header_icon);
-        Drawable icon = rootView.getResources().getDrawable(R.drawable.android_header, null);
-        iconView.setImageDrawable(icon);
-
-        TextView label = (TextView) rootView.findViewById(R.id.header_label);
-        label.setText(headerItem.getName());
-    }
-
-    @Override
-    public void onUnbindViewHolder(Presenter.ViewHolder viewHolder) {
-    }
-
-    // TODO: TEMP - remove me when leanback onCreateViewHolder no longer sets the mUnselectAlpha,AND
-    // also assumes the xml inflation will return a RowHeaderView
-    @Override
-    protected void onSelectLevelChanged(RowHeaderPresenter.ViewHolder holder) {
-        // this is a temporary fix
-        holder.view.setAlpha(mUnselectedAlpha + holder.getSelectLevel() *
-                (1.0f - mUnselectedAlpha));
-    }
-}
\ No newline at end of file
diff --git a/tests/leanbackjank/app/src/android/cts/jank/leanback/ui/MainActivity.java b/tests/leanbackjank/app/src/android/cts/jank/leanback/ui/MainActivity.java
deleted file mode 100644
index fb27fa1..0000000
--- a/tests/leanbackjank/app/src/android/cts/jank/leanback/ui/MainActivity.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 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.cts.jank.leanback.ui;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.cts.jank.leanback.R;
-
-/**
- * MainActivity class that loads MainFragment
- */
-public class MainActivity extends Activity {
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.main);
-    }
-
-    @Override
-    public boolean onSearchRequested() {
-        return false;
-    }
-}
diff --git a/tests/leanbackjank/app/src/android/cts/jank/leanback/ui/MainFragment.java b/tests/leanbackjank/app/src/android/cts/jank/leanback/ui/MainFragment.java
deleted file mode 100644
index 037ec13..0000000
--- a/tests/leanbackjank/app/src/android/cts/jank/leanback/ui/MainFragment.java
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 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.cts.jank.leanback.ui;
-
-import android.content.Intent;
-import android.content.res.Resources.Theme;
-import android.cts.jank.leanback.IntentKeys;
-import android.cts.jank.leanback.R;
-import android.cts.jank.leanback.data.VideoProvider;
-import android.cts.jank.leanback.model.Movie;
-import android.cts.jank.leanback.presenter.CardPresenter;
-import android.cts.jank.leanback.presenter.GridItemPresenter;
-import android.cts.jank.leanback.presenter.IconHeaderItemPresenter;
-import android.os.Bundle;
-import android.os.Handler;
-import android.support.v17.leanback.app.BackgroundManager;
-import android.support.v17.leanback.app.BrowseFragment;
-import android.support.v17.leanback.widget.ArrayObjectAdapter;
-import android.support.v17.leanback.widget.HeaderItem;
-import android.support.v17.leanback.widget.ListRow;
-import android.support.v17.leanback.widget.ListRowPresenter;
-import android.support.v17.leanback.widget.Presenter;
-import android.support.v17.leanback.widget.PresenterSelector;
-import android.util.DisplayMetrics;
-import android.view.View;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Timer;
-import java.util.TimerTask;
-
-class ScrollPatternGenerator {
-    private int currentRow;
-    private int topRow;
-    private int bottomRow;
-    private enum ScrollDirection {DOWN, UP};
-    private ScrollDirection direction;
-
-    public ScrollPatternGenerator(int topRow, int bottomRow) {
-        this.topRow = topRow;
-        this.bottomRow = bottomRow;
-        assert(topRow < bottomRow);
-        direction = ScrollDirection.DOWN;
-        currentRow = topRow;
-    }
-
-    public int next() {
-        if (currentRow == bottomRow) {
-            direction = ScrollDirection.UP;
-        } else if (currentRow == topRow) {
-            direction = ScrollDirection.DOWN;
-        }
-        if (direction == ScrollDirection.DOWN) {
-            currentRow++;
-        } else {
-            currentRow--;
-        }
-        return currentRow;
-    }
-}
-
-/**
- * Main class to show BrowseFragment with header and rows of videos
- */
-public class MainFragment extends BrowseFragment {
-    private static final int NUM_ROWS = 20;
-
-    // Minimum number of rows that should show above / below the cursor by auto scroll.
-    // This is intended to avoid that the work load fluctuates largely when # of cards in the
-    // display lowers when the cursor is positioned near the top or bottom of the list.
-    private static final int MARGIN_ROWS = 4;
-
-    private final Handler mHandler = new Handler();
-    private Timer mAutoScrollTimer;
-    private int mAutoScrollCount;
-
-    private ArrayObjectAdapter mRowsAdapter;
-    private DisplayMetrics mMetrics;
-    private BackgroundManager mBackgroundManager;
-    private ScrollPatternGenerator scrollPatternGenerator;
-
-    @Override
-    public void onActivityCreated(Bundle savedInstanceState) {
-        super.onActivityCreated(savedInstanceState);
-
-        buildRowAdapterItems(VideoProvider.buildMedia(NUM_ROWS));
-        prepareBackgroundManager();
-        setupUIElements();
-        setupEventListeners();
-        Intent intent = getActivity().getIntent();
-        if (intent.getExtras() != null) {
-            int initialDelay = intent.getExtras().getInt(IntentKeys.SCROLL_DELAY);
-            int scrollCount = intent.getExtras().getInt(IntentKeys.SCROLL_COUNT);
-            int scrollInterval = intent.getExtras().getInt(IntentKeys.SCROLL_INTERVAL);
-            if (scrollInterval != 0 && scrollCount != 0) {
-                startAutoScrollTimer(initialDelay, scrollInterval, scrollCount);
-            }
-            scrollPatternGenerator =
-                    new ScrollPatternGenerator(MARGIN_ROWS, NUM_ROWS - 1 - MARGIN_ROWS);
-        }
-    }
-
-    @Override
-    public void onDestroy() {
-        if (null != mAutoScrollTimer) {
-            mAutoScrollTimer.cancel();
-            mAutoScrollTimer = null;
-        }
-        super.onDestroy();
-    }
-
-    @Override
-    public void onStop() {
-        mBackgroundManager.release();
-        super.onStop();
-    }
-
-    private void prepareBackgroundManager() {
-        mBackgroundManager = BackgroundManager.getInstance(getActivity());
-        mBackgroundManager.attach(getActivity().getWindow());
-        mBackgroundManager.setDrawable(getActivity().getResources().getDrawable(
-                R.drawable.default_background, getContext().getTheme()));
-        mMetrics = new DisplayMetrics();
-        getActivity().getWindowManager().getDefaultDisplay().getMetrics(mMetrics);
-    }
-
-    private void setupUIElements() {
-        setBadgeDrawable(getActivity().getResources().getDrawable(
-                R.drawable.videos_by_google_banner, getContext().getTheme()));
-        setTitle(getString(R.string.browse_title));
-        setHeadersState(HEADERS_ENABLED);
-        setHeadersTransitionOnBackEnabled(true);
-
-        Theme theme = getContext().getTheme();
-        setBrandColor(getResources().getColor(R.color.fastlane_background, theme));
-
-        setSearchAffordanceColor(getResources().getColor(R.color.search_opaque, theme));
-
-        setHeaderPresenterSelector(new PresenterSelector() {
-            @Override
-            public Presenter getPresenter(Object o) {
-                return new IconHeaderItemPresenter();
-            }
-        });
-    }
-
-    private void setupEventListeners() {
-        // Add lister to show the search button.
-        setOnSearchClickedListener(new View.OnClickListener() {
-            @Override
-            public void onClick(View view) {
-            }
-        });
-    }
-
-    public void buildRowAdapterItems(HashMap<String, List<Movie>> data) {
-        mRowsAdapter = new ArrayObjectAdapter(new ListRowPresenter());
-        CardPresenter cardPresenter = new CardPresenter();
-
-        int i = 0;
-
-        for (Map.Entry<String, List<Movie>> entry : data.entrySet()) {
-            ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(cardPresenter);
-            List<Movie> list = entry.getValue();
-
-            for (int j = 0; j < list.size(); j++) {
-                listRowAdapter.add(list.get(j));
-            }
-            HeaderItem header = new HeaderItem(i, entry.getKey());
-            i++;
-            mRowsAdapter.add(new ListRow(header, listRowAdapter));
-        }
-
-        HeaderItem gridHeader = new HeaderItem(i, getString(R.string.settings));
-
-        GridItemPresenter gridPresenter = new GridItemPresenter(this);
-        ArrayObjectAdapter gridRowAdapter = new ArrayObjectAdapter(gridPresenter);
-        for (int j = 0; j < 10; j++) {
-            gridRowAdapter.add(getString(R.string.grid_item_template, j));
-        }
-        mRowsAdapter.add(new ListRow(gridHeader, gridRowAdapter));
-
-        setAdapter(mRowsAdapter);
-    }
-
-    private class UpdateAutoScrollTask extends TimerTask {
-        @Override
-        public void run() {
-            mHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    if (mAutoScrollCount == 0) {
-                      mAutoScrollTimer.cancel();
-                      return;
-                    }
-                    setSelectedPosition(scrollPatternGenerator.next());
-                    mAutoScrollCount--;
-                }
-            });
-        }
-    }
-
-    private void startAutoScrollTimer(int initialDelay, int interval, int count) {
-        if (null != mAutoScrollTimer) {
-            mAutoScrollTimer.cancel();
-        }
-        mAutoScrollCount = count;
-        mAutoScrollTimer = new Timer();
-        mAutoScrollTimer.schedule(new UpdateAutoScrollTask(), initialDelay, interval);
-    }
-
-    public void selectRow(int row) {
-        setSelectedPosition(row);
-    }
-}
diff --git a/tests/leanbackjank/app/src/android/leanbackjank/app/IntentKeys.java b/tests/leanbackjank/app/src/android/leanbackjank/app/IntentKeys.java
new file mode 100644
index 0000000..b459aa9
--- /dev/null
+++ b/tests/leanbackjank/app/src/android/leanbackjank/app/IntentKeys.java
@@ -0,0 +1,10 @@
+package android.leanbackjank.app;
+
+/**
+ * Intent key strings of the leanback jank test helper app.
+ */
+public class IntentKeys {
+    public static final String SCROLL_COUNT = "SCROLL_COUNT";
+    public static final String SCROLL_DELAY = "SCROLL_DELAY";
+    public static final String SCROLL_INTERVAL = "SCROLL_INTERVAL";
+}
diff --git a/tests/leanbackjank/app/src/android/leanbackjank/app/Utils.java b/tests/leanbackjank/app/src/android/leanbackjank/app/Utils.java
new file mode 100644
index 0000000..b464abf
--- /dev/null
+++ b/tests/leanbackjank/app/src/android/leanbackjank/app/Utils.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.leanbackjank.app;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Point;
+import android.media.MediaMetadataRetriever;
+import android.os.Build;
+import android.util.DisplayMetrics;
+import android.view.Display;
+import android.view.WindowManager;
+import android.widget.FrameLayout;
+import android.widget.Toast;
+import android.widget.VideoView;
+
+import java.util.HashMap;
+
+/**
+ * A collection of utility methods, all static.
+ */
+public class Utils {
+
+    public interface MediaDimensions {
+        double MEDIA_HEIGHT = 0.95;
+        double MEDIA_WIDTH = 0.95;
+        double MEDIA_TOP_MARGIN = 0.025;
+        double MEDIA_RIGHT_MARGIN = 0.025;
+        double MEDIA_BOTTOM_MARGIN = 0.025;
+        double MEDIA_LEFT_MARGIN = 0.025;
+    }
+
+    /*
+     * Making sure public utility methods remain static
+     */
+    private Utils() {
+    }
+
+    /**
+     * Returns the screen/display size
+     */
+    public static Point getDisplaySize(Context context) {
+        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
+        Display display = wm.getDefaultDisplay();
+        Point size = new Point();
+        display.getSize(size);
+        return size;
+    }
+
+    /**
+     * Shows a (long) toast
+     */
+    public static void showToast(Context context, String msg) {
+        Toast.makeText(context, msg, Toast.LENGTH_LONG).show();
+    }
+
+    /**
+     * Shows a (long) toast.
+     */
+    public static void showToast(Context context, int resourceId) {
+        Toast.makeText(context, context.getString(resourceId), Toast.LENGTH_LONG).show();
+    }
+
+    public static int convertDpToPixel(Context ctx, int dp) {
+        float density = ctx.getResources().getDisplayMetrics().density;
+        return Math.round((float) dp * density);
+    }
+
+
+    /**
+     * Example for handling resizing content for overscan.  Typically you won't need to resize
+     * when using the Leanback support library.
+     */
+    public void overScan(Activity activity, VideoView videoView) {
+        DisplayMetrics metrics = new DisplayMetrics();
+        activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
+        int w = (int) (metrics.widthPixels * MediaDimensions.MEDIA_WIDTH);
+        int h = (int) (metrics.heightPixels * MediaDimensions.MEDIA_HEIGHT);
+        int marginLeft = (int) (metrics.widthPixels * MediaDimensions.MEDIA_LEFT_MARGIN);
+        int marginTop = (int) (metrics.heightPixels * MediaDimensions.MEDIA_TOP_MARGIN);
+        int marginRight = (int) (metrics.widthPixels * MediaDimensions.MEDIA_RIGHT_MARGIN);
+        int marginBottom = (int) (metrics.heightPixels * MediaDimensions.MEDIA_BOTTOM_MARGIN);
+        FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(w, h);
+        lp.setMargins(marginLeft, marginTop, marginRight, marginBottom);
+        videoView.setLayoutParams(lp);
+    }
+
+
+    public static long getDuration(String videoUrl) {
+        MediaMetadataRetriever mmr = new MediaMetadataRetriever();
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
+            mmr.setDataSource(videoUrl, new HashMap<String, String>());
+        } else {
+            mmr.setDataSource(videoUrl);
+        }
+        return Long.parseLong(mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION));
+    }
+}
diff --git a/tests/leanbackjank/app/src/android/leanbackjank/app/data/VideoProvider.java b/tests/leanbackjank/app/src/android/leanbackjank/app/data/VideoProvider.java
new file mode 100644
index 0000000..6ea19c1
--- /dev/null
+++ b/tests/leanbackjank/app/src/android/leanbackjank/app/data/VideoProvider.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.leanbackjank.app.data;
+
+import android.leanbackjank.app.model.Movie;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * Provides synthesized movie data.
+ */
+public class VideoProvider {
+    private static HashMap<String, List<Movie>> sMovieList;
+    private static HashMap<String, Movie> sMovieListById;
+
+    public static Movie getMovieById(String mediaId) {
+        return sMovieListById.get(mediaId);
+    }
+
+    public static HashMap<String, List<Movie>> getMovieList() {
+        return sMovieList;
+    }
+
+    public static HashMap<String, List<Movie>> buildMedia(int nCategories) {
+        if (null != sMovieList) {
+            return sMovieList;
+        }
+        sMovieList = new HashMap<>();
+        sMovieListById = new HashMap<>();
+
+        String title = new String();
+        String studio = new String();
+        for (int i = 0; i < nCategories; i++) {
+            String category_name = String.format("Category %d",  i);
+            List<Movie> categoryList = new ArrayList<Movie>();
+            for (int j = 0; j < 20; j++) {
+                String description = "This is description of a movie.";
+                title = String.format("Video %d-%d", i, j);
+                studio = String.format("Studio %d", (i + j) % 7);
+                Movie movie = buildMovieInfo(category_name, title, description, studio);
+                sMovieListById.put(movie.getId(), movie);
+                categoryList.add(movie);
+            }
+            sMovieList.put(category_name, categoryList);
+        }
+        return sMovieList;
+    }
+
+    private static Movie buildMovieInfo(String category,
+                                        String title,
+                                        String description,
+                                        String studio) {
+        Movie movie = new Movie();
+        movie.setId(Movie.getCount());
+        Movie.incrementCount();
+        movie.setTitle(title);
+        movie.setDescription(description);
+        movie.setStudio(studio);
+        movie.setCategory(category);
+
+        return movie;
+    }
+}
diff --git a/tests/leanbackjank/app/src/android/leanbackjank/app/model/Movie.java b/tests/leanbackjank/app/src/android/leanbackjank/app/model/Movie.java
new file mode 100644
index 0000000..1b68aee
--- /dev/null
+++ b/tests/leanbackjank/app/src/android/leanbackjank/app/model/Movie.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.leanbackjank.app.model;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Movie class represents video entity with title, description, image thumbs and video url.
+ */
+public class Movie implements Parcelable {
+    static final long serialVersionUID = 727566175075960653L;
+    private static int sCount = 0;
+    private String mId;
+    private String mTitle;
+    private String mDescription;
+    private String mStudio;
+    private String mCategory;
+
+    public Movie() {
+    }
+
+    public Movie(Parcel in){
+        String[] data = new String[5];
+
+        in.readStringArray(data);
+        mId = data[0];
+        mTitle = data[1];
+        mDescription = data[2];
+        mStudio = data[3];
+        mCategory = data[4];
+    }
+
+    public static String getCount() {
+        return Integer.toString(sCount);
+    }
+
+    public static void incrementCount() {
+        sCount++;
+    }
+
+    public String getId() {
+        return mId;
+    }
+
+    public void setId(String id) {
+        mId = id;
+    }
+
+    public String getTitle() {
+        return mTitle;
+    }
+
+    public void setTitle(String title) {
+        mTitle = title;
+    }
+
+    public String getDescription() {
+        return mDescription;
+    }
+
+    public void setDescription(String description) {
+        mDescription = description;
+    }
+
+    public String getStudio() {
+        return mStudio;
+    }
+
+    public void setStudio(String studio) {
+        mStudio = studio;
+    }
+
+    public String getCategory() {
+        return mCategory;
+    }
+
+    public void setCategory(String category) {
+        mCategory = category;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeStringArray(new String[] {mId,
+                mTitle,
+                mDescription,
+                mStudio,
+                mCategory});
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder(200);
+        sb.append("Movie{");
+        sb.append("mId=" + mId);
+        sb.append(", mTitle='" + mTitle + '\'');
+        sb.append('}');
+        return sb.toString();
+    }
+
+    public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
+        public Movie createFromParcel(Parcel in) {
+            return new Movie(in);
+        }
+
+        public Movie[] newArray(int size) {
+            return new Movie[size];
+        }
+    };
+}
diff --git a/tests/leanbackjank/app/src/android/leanbackjank/app/presenter/CardPresenter.java b/tests/leanbackjank/app/src/android/leanbackjank/app/presenter/CardPresenter.java
new file mode 100644
index 0000000..f237438
--- /dev/null
+++ b/tests/leanbackjank/app/src/android/leanbackjank/app/presenter/CardPresenter.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.leanbackjank.app.presenter;
+
+import android.graphics.drawable.Drawable;
+import android.support.v17.leanback.widget.ImageCardView;
+import android.support.v17.leanback.widget.Presenter;
+import android.view.ViewGroup;
+
+import com.bumptech.glide.Glide;
+import android.leanbackjank.app.R;
+import android.leanbackjank.app.model.Movie;
+
+/**
+ * A CardPresenter is used to generate Views and bind Objects to them on demand.
+ * It contains an Image CardView
+ */
+public class CardPresenter extends Presenter {
+    private static int CARD_WIDTH = 313;
+    private static int CARD_HEIGHT = 176;
+    private static int sSelectedBackgroundColor;
+    private static int sDefaultBackgroundColor;
+    private Drawable mDefaultCardImage;
+
+    @Override
+    public ViewHolder onCreateViewHolder(ViewGroup parent) {
+        sDefaultBackgroundColor = parent.getResources().getColor(R.color.default_background, null);
+        sSelectedBackgroundColor =
+                parent.getResources().getColor(R.color.selected_background, null);
+        mDefaultCardImage = parent.getResources().getDrawable(R.drawable.movie, null);
+
+        ImageCardView cardView = new ImageCardView(parent.getContext()) {
+            @Override
+            public void setSelected(boolean selected) {
+                updateCardBackgroundColor(this, selected);
+                super.setSelected(selected);
+            }
+        };
+
+        cardView.setFocusable(true);
+        cardView.setFocusableInTouchMode(true);
+        updateCardBackgroundColor(cardView, false);
+        return new ViewHolder(cardView);
+    }
+
+    private static void updateCardBackgroundColor(ImageCardView view, boolean selected) {
+        int color = selected ? sSelectedBackgroundColor : sDefaultBackgroundColor;
+        // Both background colors should be set because the view's background is temporarily visible
+        // during animations.
+        view.setBackgroundColor(color);
+        view.findViewById(R.id.info_field).setBackgroundColor(color);
+    }
+
+    @Override
+    public void onBindViewHolder(Presenter.ViewHolder viewHolder, Object item) {
+        Movie movie = (Movie) item;
+        ImageCardView cardView = (ImageCardView) viewHolder.view;
+
+        cardView.setTitleText(movie.getTitle());
+        cardView.setContentText(movie.getStudio());
+        cardView.setMainImageDimensions(CARD_WIDTH, CARD_HEIGHT);
+        Glide.with(viewHolder.view.getContext())
+                .load(R.drawable.gradation)
+                .centerCrop()
+                .error(mDefaultCardImage)
+                .into(cardView.getMainImageView());
+    }
+
+    @Override
+    public void onUnbindViewHolder(Presenter.ViewHolder viewHolder) {
+        ImageCardView cardView = (ImageCardView) viewHolder.view;
+        // Remove references to images so that the garbage collector can free up memory
+        cardView.setBadgeImage(null);
+        cardView.setMainImage(null);
+    }
+}
diff --git a/tests/leanbackjank/app/src/android/leanbackjank/app/presenter/GridItemPresenter.java b/tests/leanbackjank/app/src/android/leanbackjank/app/presenter/GridItemPresenter.java
new file mode 100644
index 0000000..1ab7e8d
--- /dev/null
+++ b/tests/leanbackjank/app/src/android/leanbackjank/app/presenter/GridItemPresenter.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.leanbackjank.app.presenter;
+
+import android.graphics.Color;
+import android.support.v17.leanback.widget.Presenter;
+import android.view.Gravity;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import android.leanbackjank.app.R;
+import android.leanbackjank.app.ui.MainFragment;
+
+public class GridItemPresenter extends Presenter {
+    private static int GRID_ITEM_WIDTH = 200;
+    private static int GRID_ITEM_HEIGHT = 200;
+
+    private MainFragment mainFragment;
+
+    public GridItemPresenter(MainFragment mainFragment) {
+        this.mainFragment = mainFragment;
+    }
+
+    @Override
+    public ViewHolder onCreateViewHolder(ViewGroup parent) {
+        TextView view = new TextView(parent.getContext());
+        view.setLayoutParams(new ViewGroup.LayoutParams(GRID_ITEM_WIDTH, GRID_ITEM_HEIGHT));
+        view.setFocusable(true);
+        view.setFocusableInTouchMode(true);
+        view.setBackgroundColor(
+            mainFragment.getResources().getColor(R.color.default_background, null));
+        view.setTextColor(Color.WHITE);
+        view.setGravity(Gravity.CENTER);
+        return new ViewHolder(view);
+    }
+
+    @Override
+    public void onBindViewHolder(ViewHolder viewHolder, Object item) {
+        ((TextView) viewHolder.view).setText((String) item);
+    }
+
+    @Override
+    public void onUnbindViewHolder(ViewHolder viewHolder) {
+    }
+}
diff --git a/tests/leanbackjank/app/src/android/leanbackjank/app/presenter/IconHeaderItemPresenter.java b/tests/leanbackjank/app/src/android/leanbackjank/app/presenter/IconHeaderItemPresenter.java
new file mode 100644
index 0000000..32dae35
--- /dev/null
+++ b/tests/leanbackjank/app/src/android/leanbackjank/app/presenter/IconHeaderItemPresenter.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.leanbackjank.app.presenter;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.support.v17.leanback.widget.HeaderItem;
+import android.support.v17.leanback.widget.ListRow;
+import android.support.v17.leanback.widget.Presenter;
+import android.support.v17.leanback.widget.RowHeaderPresenter;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import android.leanbackjank.app.R;
+
+public class IconHeaderItemPresenter extends RowHeaderPresenter {
+    private float mUnselectedAlpha;
+
+    @Override
+    public ViewHolder onCreateViewHolder(ViewGroup viewGroup) {
+        mUnselectedAlpha = viewGroup.getResources()
+                .getFraction(R.fraction.lb_browse_header_unselect_alpha, 1, 1);
+        LayoutInflater inflater = (LayoutInflater) viewGroup.getContext()
+                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+
+        View view = inflater.inflate(R.layout.icon_header_item, null);
+
+        return new ViewHolder(view);
+    }
+
+    @Override
+    public void onBindViewHolder(Presenter.ViewHolder viewHolder, Object o) {
+        HeaderItem headerItem = ((ListRow) o).getHeaderItem();
+        View rootView = viewHolder.view;
+
+        ImageView iconView = (ImageView) rootView.findViewById(R.id.header_icon);
+        Drawable icon = rootView.getResources().getDrawable(R.drawable.android_header, null);
+        iconView.setImageDrawable(icon);
+
+        TextView label = (TextView) rootView.findViewById(R.id.header_label);
+        label.setText(headerItem.getName());
+    }
+
+    @Override
+    public void onUnbindViewHolder(Presenter.ViewHolder viewHolder) {
+    }
+
+    // TODO: TEMP - remove me when leanback onCreateViewHolder no longer sets the mUnselectAlpha,AND
+    // also assumes the xml inflation will return a RowHeaderView
+    @Override
+    protected void onSelectLevelChanged(RowHeaderPresenter.ViewHolder holder) {
+        // this is a temporary fix
+        holder.view.setAlpha(mUnselectedAlpha + holder.getSelectLevel() *
+                (1.0f - mUnselectedAlpha));
+    }
+}
diff --git a/tests/leanbackjank/app/src/android/leanbackjank/app/ui/MainActivity.java b/tests/leanbackjank/app/src/android/leanbackjank/app/ui/MainActivity.java
new file mode 100644
index 0000000..356c2ac
--- /dev/null
+++ b/tests/leanbackjank/app/src/android/leanbackjank/app/ui/MainActivity.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 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.leanbackjank.app.ui;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.leanbackjank.app.R;
+
+/**
+ * MainActivity class that loads MainFragment
+ */
+public class MainActivity extends Activity {
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.main);
+    }
+
+    @Override
+    public boolean onSearchRequested() {
+        return false;
+    }
+}
diff --git a/tests/leanbackjank/app/src/android/leanbackjank/app/ui/MainFragment.java b/tests/leanbackjank/app/src/android/leanbackjank/app/ui/MainFragment.java
new file mode 100644
index 0000000..78032c2
--- /dev/null
+++ b/tests/leanbackjank/app/src/android/leanbackjank/app/ui/MainFragment.java
@@ -0,0 +1,228 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 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.leanbackjank.app.ui;
+
+import android.content.Intent;
+import android.content.res.Resources.Theme;
+import android.leanbackjank.app.IntentKeys;
+import android.leanbackjank.app.R;
+import android.leanbackjank.app.data.VideoProvider;
+import android.leanbackjank.app.model.Movie;
+import android.leanbackjank.app.presenter.CardPresenter;
+import android.leanbackjank.app.presenter.GridItemPresenter;
+import android.leanbackjank.app.presenter.IconHeaderItemPresenter;
+import android.os.Bundle;
+import android.os.Handler;
+import android.support.v17.leanback.app.BackgroundManager;
+import android.support.v17.leanback.app.BrowseFragment;
+import android.support.v17.leanback.widget.ArrayObjectAdapter;
+import android.support.v17.leanback.widget.HeaderItem;
+import android.support.v17.leanback.widget.ListRow;
+import android.support.v17.leanback.widget.ListRowPresenter;
+import android.support.v17.leanback.widget.Presenter;
+import android.support.v17.leanback.widget.PresenterSelector;
+import android.util.DisplayMetrics;
+import android.view.View;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Timer;
+import java.util.TimerTask;
+
+class ScrollPatternGenerator {
+    private int currentRow;
+    private int topRow;
+    private int bottomRow;
+    private enum ScrollDirection {DOWN, UP};
+    private ScrollDirection direction;
+
+    public ScrollPatternGenerator(int topRow, int bottomRow) {
+        this.topRow = topRow;
+        this.bottomRow = bottomRow;
+        assert(topRow < bottomRow);
+        direction = ScrollDirection.DOWN;
+        currentRow = topRow;
+    }
+
+    public int next() {
+        if (currentRow == bottomRow) {
+            direction = ScrollDirection.UP;
+        } else if (currentRow == topRow) {
+            direction = ScrollDirection.DOWN;
+        }
+        if (direction == ScrollDirection.DOWN) {
+            currentRow++;
+        } else {
+            currentRow--;
+        }
+        return currentRow;
+    }
+}
+
+/**
+ * Main class to show BrowseFragment with header and rows of videos
+ */
+public class MainFragment extends BrowseFragment {
+    private static final int NUM_ROWS = 20;
+
+    // Minimum number of rows that should show above / below the cursor by auto scroll.
+    // This is intended to avoid that the work load fluctuates largely when # of cards in the
+    // display lowers when the cursor is positioned near the top or bottom of the list.
+    private static final int MARGIN_ROWS = 4;
+
+    private final Handler mHandler = new Handler();
+    private Timer mAutoScrollTimer;
+    private int mAutoScrollCount;
+
+    private ArrayObjectAdapter mRowsAdapter;
+    private DisplayMetrics mMetrics;
+    private BackgroundManager mBackgroundManager;
+    private ScrollPatternGenerator scrollPatternGenerator;
+
+    @Override
+    public void onActivityCreated(Bundle savedInstanceState) {
+        super.onActivityCreated(savedInstanceState);
+
+        buildRowAdapterItems(VideoProvider.buildMedia(NUM_ROWS));
+        prepareBackgroundManager();
+        setupUIElements();
+        setupEventListeners();
+        Intent intent = getActivity().getIntent();
+        if (intent.getExtras() != null) {
+            int initialDelay = intent.getExtras().getInt(IntentKeys.SCROLL_DELAY);
+            int scrollCount = intent.getExtras().getInt(IntentKeys.SCROLL_COUNT);
+            int scrollInterval = intent.getExtras().getInt(IntentKeys.SCROLL_INTERVAL);
+            if (scrollInterval != 0 && scrollCount != 0) {
+                startAutoScrollTimer(initialDelay, scrollInterval, scrollCount);
+            }
+            scrollPatternGenerator =
+                    new ScrollPatternGenerator(MARGIN_ROWS, NUM_ROWS - 1 - MARGIN_ROWS);
+        }
+    }
+
+    @Override
+    public void onDestroy() {
+        if (null != mAutoScrollTimer) {
+            mAutoScrollTimer.cancel();
+            mAutoScrollTimer = null;
+        }
+        super.onDestroy();
+    }
+
+    @Override
+    public void onStop() {
+        mBackgroundManager.release();
+        super.onStop();
+    }
+
+    private void prepareBackgroundManager() {
+        mBackgroundManager = BackgroundManager.getInstance(getActivity());
+        mBackgroundManager.attach(getActivity().getWindow());
+        mBackgroundManager.setDrawable(getActivity().getResources().getDrawable(
+                R.drawable.default_background, getContext().getTheme()));
+        mMetrics = new DisplayMetrics();
+        getActivity().getWindowManager().getDefaultDisplay().getMetrics(mMetrics);
+    }
+
+    private void setupUIElements() {
+        setBadgeDrawable(getActivity().getResources().getDrawable(
+                R.drawable.videos_by_google_banner, getContext().getTheme()));
+        setTitle(getString(R.string.browse_title));
+        setHeadersState(HEADERS_ENABLED);
+        setHeadersTransitionOnBackEnabled(true);
+
+        Theme theme = getContext().getTheme();
+        setBrandColor(getResources().getColor(R.color.fastlane_background, theme));
+
+        setSearchAffordanceColor(getResources().getColor(R.color.search_opaque, theme));
+
+        setHeaderPresenterSelector(new PresenterSelector() {
+            @Override
+            public Presenter getPresenter(Object o) {
+                return new IconHeaderItemPresenter();
+            }
+        });
+    }
+
+    private void setupEventListeners() {
+        // Add lister to show the search button.
+        setOnSearchClickedListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View view) {
+            }
+        });
+    }
+
+    public void buildRowAdapterItems(HashMap<String, List<Movie>> data) {
+        mRowsAdapter = new ArrayObjectAdapter(new ListRowPresenter());
+        CardPresenter cardPresenter = new CardPresenter();
+
+        int i = 0;
+
+        for (Map.Entry<String, List<Movie>> entry : data.entrySet()) {
+            ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(cardPresenter);
+            List<Movie> list = entry.getValue();
+
+            for (int j = 0; j < list.size(); j++) {
+                listRowAdapter.add(list.get(j));
+            }
+            HeaderItem header = new HeaderItem(i, entry.getKey());
+            i++;
+            mRowsAdapter.add(new ListRow(header, listRowAdapter));
+        }
+
+        HeaderItem gridHeader = new HeaderItem(i, getString(R.string.settings));
+
+        GridItemPresenter gridPresenter = new GridItemPresenter(this);
+        ArrayObjectAdapter gridRowAdapter = new ArrayObjectAdapter(gridPresenter);
+        for (int j = 0; j < 10; j++) {
+            gridRowAdapter.add(getString(R.string.grid_item_template, j));
+        }
+        mRowsAdapter.add(new ListRow(gridHeader, gridRowAdapter));
+
+        setAdapter(mRowsAdapter);
+    }
+
+    private class UpdateAutoScrollTask extends TimerTask {
+        @Override
+        public void run() {
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    if (mAutoScrollCount == 0) {
+                      mAutoScrollTimer.cancel();
+                      return;
+                    }
+                    setSelectedPosition(scrollPatternGenerator.next());
+                    mAutoScrollCount--;
+                }
+            });
+        }
+    }
+
+    private void startAutoScrollTimer(int initialDelay, int interval, int count) {
+        if (null != mAutoScrollTimer) {
+            mAutoScrollTimer.cancel();
+        }
+        mAutoScrollCount = count;
+        mAutoScrollTimer = new Timer();
+        mAutoScrollTimer.schedule(new UpdateAutoScrollTask(), initialDelay, interval);
+    }
+
+    public void selectRow(int row) {
+        setSelectedPosition(row);
+    }
+}
diff --git a/tests/leanbackjank/src/android/cts/leanbackjank/CtsDeviceLeanback.java b/tests/leanbackjank/src/android/cts/leanbackjank/CtsDeviceLeanback.java
deleted file mode 100644
index 3d6170e..0000000
--- a/tests/leanbackjank/src/android/cts/leanbackjank/CtsDeviceLeanback.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 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.cts.leanbackjank;
-
-import android.content.ComponentName;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.cts.jank.leanback.IntentKeys;
-import android.os.SystemClock;
-import android.support.test.jank.GfxMonitor;
-import android.support.test.jank.JankTest;
-import android.support.test.jank.WindowContentFrameStatsMonitor;
-import android.support.test.uiautomator.By;
-import android.support.test.uiautomator.Until;
-import android.util.Log;
-
-public class CtsDeviceLeanback extends CtsJankTestBase {
-    private static final String TAG = "CtsDeviceLeanback";
-    private static final int MILLIS_PER_SECOND = 1000;
-    private static final long WAIT_TIMEOUT = 5 * MILLIS_PER_SECOND;
-    private static final int SCROLL_COUNT = 100;
-    private static final int SCROLL_INTERVAL_MILLIS = 200;
-    private static final int PRE_SCROLL_DELAY_MILLIS = 0;
-    private static final int PRE_SCROLL_IDLE_TIME = 2 * MILLIS_PER_SECOND;
-    private static final int SAMPLING_DURATION_SECONDS = 2;
-    private static final int SAMPLING_DURATION_MILLIS =
-            SAMPLING_DURATION_SECONDS * MILLIS_PER_SECOND;
-    private final static String APP_PACKAGE = "android.cts.jank.leanback";
-    private final static String JAVA_PACKAGE = "android.cts.jank.leanback.ui";
-    private final static String CLASS = JAVA_PACKAGE + ".MainActivity";
-
-    private boolean shouldSkip() {
-	PackageManager packageManager =
-                getInstrumentation().getTargetContext().getPackageManager();
-        if (!packageManager.hasSystemFeature(
-                PackageManager.FEATURE_LEANBACK)) {
-            return true;
-        }
-        return false;
-    }
-
-    @Override
-    protected void runTest() throws Throwable {
-        if (shouldSkip()) {
-            return;
-        }
-        super.runTest();
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        if (shouldSkip()) {
-            return;
-        }
-        Intent intent = new Intent(Intent.ACTION_MAIN);
-        intent.setComponent(new ComponentName(APP_PACKAGE, CLASS));
-
-        // Trigger automated scroll of the helper app.
-        intent.putExtra(IntentKeys.SCROLL_DELAY, PRE_SCROLL_DELAY_MILLIS);
-        intent.putExtra(IntentKeys.SCROLL_COUNT, SCROLL_COUNT);
-        intent.putExtra(IntentKeys.SCROLL_INTERVAL, SCROLL_INTERVAL_MILLIS);
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        getInstrumentation().getTargetContext().startActivity(intent);
-        if (!getUiDevice().wait(Until.hasObject(By.pkg(APP_PACKAGE)), WAIT_TIMEOUT)) {
-            fail("Test helper app package not found on device");
-        }
-
-        // Wait until scroll animation starts.
-        SystemClock.sleep(PRE_SCROLL_IDLE_TIME);
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        getUiDevice().pressHome();
-        super.tearDown();
-    }
-
-    // Requires at least 50 fps on average to pass the test.
-    @JankTest(expectedFrames = 50 * SAMPLING_DURATION_SECONDS, defaultIterationCount = 2)
-    @GfxMonitor(processName = APP_PACKAGE)
-    @WindowContentFrameStatsMonitor
-    public void testScrollingByTimer() {
-        SystemClock.sleep(SAMPLING_DURATION_MILLIS);
-    }
-}
diff --git a/tests/leanbackjank/src/android/cts/leanbackjank/CtsJankTestBase.java b/tests/leanbackjank/src/android/cts/leanbackjank/CtsJankTestBase.java
deleted file mode 100644
index 4de0702..0000000
--- a/tests/leanbackjank/src/android/cts/leanbackjank/CtsJankTestBase.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.cts.leanbackjank;
-
-import android.cts.util.DeviceReportLog;
-import android.os.Bundle;
-import android.support.test.jank.GfxMonitor;
-import android.support.test.jank.JankTestBase;
-import android.support.test.jank.WindowContentFrameStatsMonitor;
-import android.support.test.uiautomator.UiDevice;
-
-import com.android.cts.util.ResultType;
-import com.android.cts.util.ResultUnit;
-
-public abstract class CtsJankTestBase extends JankTestBase {
-
-    private UiDevice mDevice;
-    private DeviceReportLog mLog;
-
-    private void printIntValueWithKey(String source, Bundle metrics, String key,
-            ResultType resultType, ResultUnit resultUnit) {
-        if (!metrics.containsKey(key)) {
-            return;
-        }
-        mLog.printValue(source, key, metrics.getInt(key), resultType, resultUnit);
-    }
-
-    private void printDoubleValueWithKey(String source, Bundle metrics, String key,
-            ResultType resultType, ResultUnit resultUnit) {
-        if (!metrics.containsKey(key)) {
-            return;
-        }
-        mLog.printValue(source, key, metrics.getDouble(key), resultType, resultUnit);
-    }
-
-    @Override
-    public void afterTest(Bundle metrics) {
-        String source = String.format("%s#%s", getClass().getCanonicalName(), getName());
-        printDoubleValueWithKey(source, metrics, WindowContentFrameStatsMonitor.KEY_AVG_FPS,
-                ResultType.HIGHER_BETTER, ResultUnit.FPS);
-        printDoubleValueWithKey(source, metrics,
-                WindowContentFrameStatsMonitor.KEY_AVG_LONGEST_FRAME,
-                ResultType.LOWER_BETTER, ResultUnit.MS);
-        printIntValueWithKey(source, metrics, WindowContentFrameStatsMonitor.KEY_MAX_NUM_JANKY,
-                ResultType.LOWER_BETTER, ResultUnit.COUNT);
-        mLog.printSummary(WindowContentFrameStatsMonitor.KEY_AVG_NUM_JANKY,
-                metrics.getDouble(WindowContentFrameStatsMonitor.KEY_AVG_NUM_JANKY),
-                ResultType.LOWER_BETTER, ResultUnit.COUNT);
-
-        printDoubleValueWithKey(source, metrics, GfxMonitor.KEY_AVG_NUM_JANKY,
-                ResultType.LOWER_BETTER, ResultUnit.COUNT);
-        printDoubleValueWithKey(source, metrics, GfxMonitor.KEY_AVG_FRAME_TIME_90TH_PERCENTILE,
-                ResultType.LOWER_BETTER, ResultUnit.MS);
-        printDoubleValueWithKey(source, metrics, GfxMonitor.KEY_AVG_FRAME_TIME_95TH_PERCENTILE,
-                ResultType.LOWER_BETTER, ResultUnit.MS);
-        printDoubleValueWithKey(source, metrics, GfxMonitor.KEY_AVG_FRAME_TIME_99TH_PERCENTILE,
-                ResultType.LOWER_BETTER, ResultUnit.MS);
-        printDoubleValueWithKey(source, metrics, GfxMonitor.KEY_AVG_MISSED_VSYNC,
-                ResultType.LOWER_BETTER, ResultUnit.COUNT);
-        printDoubleValueWithKey(source, metrics, GfxMonitor.KEY_AVG_SLOW_UI_THREAD,
-                ResultType.LOWER_BETTER, ResultUnit.COUNT);
-        printDoubleValueWithKey(source, metrics, GfxMonitor.KEY_AVG_SLOW_BITMAP_UPLOADS,
-                ResultType.LOWER_BETTER, ResultUnit.COUNT);
-        printDoubleValueWithKey(source, metrics, GfxMonitor.KEY_AVG_SLOW_DRAW,
-                ResultType.LOWER_BETTER, ResultUnit.COUNT);
-        printDoubleValueWithKey(source, metrics, GfxMonitor.KEY_AVG_HIGH_INPUT_LATENCY,
-                ResultType.LOWER_BETTER, ResultUnit.COUNT);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mLog = new DeviceReportLog();
-        // fix device orientation
-        mDevice = UiDevice.getInstance(getInstrumentation());
-        mDevice.setOrientationNatural();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        mLog.deliverReportToHost(getInstrumentation());
-        // restore device orientation
-        mDevice.unfreezeRotation();
-        super.tearDown();
-    }
-
-    protected UiDevice getUiDevice() {
-        return mDevice;
-    }
-}
diff --git a/tests/leanbackjank/src/android/leanbackjank/cts/CtsDeviceLeanback.java b/tests/leanbackjank/src/android/leanbackjank/cts/CtsDeviceLeanback.java
new file mode 100644
index 0000000..ded9ea1
--- /dev/null
+++ b/tests/leanbackjank/src/android/leanbackjank/cts/CtsDeviceLeanback.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 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.leanbackjank.cts;
+
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.leanbackjank.app.IntentKeys;
+import android.os.SystemClock;
+import android.support.test.jank.GfxMonitor;
+import android.support.test.jank.JankTest;
+import android.support.test.jank.WindowContentFrameStatsMonitor;
+import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.Until;
+import android.util.Log;
+
+public class CtsDeviceLeanback extends CtsJankTestBase {
+    private static final String TAG = "CtsDeviceLeanback";
+    private static final int MILLIS_PER_SECOND = 1000;
+    private static final long WAIT_TIMEOUT = 5 * MILLIS_PER_SECOND;
+    private static final int SCROLL_COUNT = 100;
+    private static final int SCROLL_INTERVAL_MILLIS = 200;
+    private static final int PRE_SCROLL_DELAY_MILLIS = 0;
+    private static final int PRE_SCROLL_IDLE_TIME = 2 * MILLIS_PER_SECOND;
+    private static final int SAMPLING_DURATION_SECONDS = 2;
+    private static final int SAMPLING_DURATION_MILLIS =
+            SAMPLING_DURATION_SECONDS * MILLIS_PER_SECOND;
+    private final static String APP_PACKAGE = "android.leanbackjank.app";
+    private final static String JAVA_PACKAGE = "android.leanbackjank.app.ui";
+    private final static String CLASS = JAVA_PACKAGE + ".MainActivity";
+
+    private boolean shouldSkip() {
+	PackageManager packageManager =
+                getInstrumentation().getTargetContext().getPackageManager();
+        if (!packageManager.hasSystemFeature(
+                PackageManager.FEATURE_LEANBACK)) {
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    protected void runTest() throws Throwable {
+        if (shouldSkip()) {
+            return;
+        }
+        super.runTest();
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        if (shouldSkip()) {
+            return;
+        }
+        Intent intent = new Intent(Intent.ACTION_MAIN);
+        intent.setComponent(new ComponentName(APP_PACKAGE, CLASS));
+
+        // Trigger automated scroll of the helper app.
+        intent.putExtra(IntentKeys.SCROLL_DELAY, PRE_SCROLL_DELAY_MILLIS);
+        intent.putExtra(IntentKeys.SCROLL_COUNT, SCROLL_COUNT);
+        intent.putExtra(IntentKeys.SCROLL_INTERVAL, SCROLL_INTERVAL_MILLIS);
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        getInstrumentation().getTargetContext().startActivity(intent);
+        if (!getUiDevice().wait(Until.hasObject(By.pkg(APP_PACKAGE)), WAIT_TIMEOUT)) {
+            fail("Test helper app package not found on device");
+        }
+
+        // Wait until scroll animation starts.
+        SystemClock.sleep(PRE_SCROLL_IDLE_TIME);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        getUiDevice().pressHome();
+        super.tearDown();
+    }
+
+    // Requires at least 50 fps on average to pass the test.
+    @JankTest(expectedFrames = 50 * SAMPLING_DURATION_SECONDS, defaultIterationCount = 2)
+    @GfxMonitor(processName = APP_PACKAGE)
+    @WindowContentFrameStatsMonitor
+    public void testScrollingByTimer() {
+        SystemClock.sleep(SAMPLING_DURATION_MILLIS);
+    }
+}
diff --git a/tests/leanbackjank/src/android/leanbackjank/cts/CtsJankTestBase.java b/tests/leanbackjank/src/android/leanbackjank/cts/CtsJankTestBase.java
new file mode 100644
index 0000000..77a1d1c
--- /dev/null
+++ b/tests/leanbackjank/src/android/leanbackjank/cts/CtsJankTestBase.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.leanbackjank.cts;
+
+import android.cts.util.DeviceReportLog;
+import android.os.Bundle;
+import android.support.test.jank.GfxMonitor;
+import android.support.test.jank.JankTestBase;
+import android.support.test.jank.WindowContentFrameStatsMonitor;
+import android.support.test.uiautomator.UiDevice;
+
+import com.android.cts.util.ResultType;
+import com.android.cts.util.ResultUnit;
+
+public abstract class CtsJankTestBase extends JankTestBase {
+
+    private UiDevice mDevice;
+    private DeviceReportLog mLog;
+
+    private void printIntValueWithKey(String source, Bundle metrics, String key,
+            ResultType resultType, ResultUnit resultUnit) {
+        if (!metrics.containsKey(key)) {
+            return;
+        }
+        mLog.printValue(source, key, metrics.getInt(key), resultType, resultUnit);
+    }
+
+    private void printDoubleValueWithKey(String source, Bundle metrics, String key,
+            ResultType resultType, ResultUnit resultUnit) {
+        if (!metrics.containsKey(key)) {
+            return;
+        }
+        mLog.printValue(source, key, metrics.getDouble(key), resultType, resultUnit);
+    }
+
+    @Override
+    public void afterTest(Bundle metrics) {
+        String source = String.format("%s#%s", getClass().getCanonicalName(), getName());
+        printDoubleValueWithKey(source, metrics, WindowContentFrameStatsMonitor.KEY_AVG_FPS,
+                ResultType.HIGHER_BETTER, ResultUnit.FPS);
+        printDoubleValueWithKey(source, metrics,
+                WindowContentFrameStatsMonitor.KEY_AVG_LONGEST_FRAME,
+                ResultType.LOWER_BETTER, ResultUnit.MS);
+        printIntValueWithKey(source, metrics, WindowContentFrameStatsMonitor.KEY_MAX_NUM_JANKY,
+                ResultType.LOWER_BETTER, ResultUnit.COUNT);
+        mLog.printSummary(WindowContentFrameStatsMonitor.KEY_AVG_NUM_JANKY,
+                metrics.getDouble(WindowContentFrameStatsMonitor.KEY_AVG_NUM_JANKY),
+                ResultType.LOWER_BETTER, ResultUnit.COUNT);
+
+        printDoubleValueWithKey(source, metrics, GfxMonitor.KEY_AVG_NUM_JANKY,
+                ResultType.LOWER_BETTER, ResultUnit.COUNT);
+        printDoubleValueWithKey(source, metrics, GfxMonitor.KEY_AVG_FRAME_TIME_90TH_PERCENTILE,
+                ResultType.LOWER_BETTER, ResultUnit.MS);
+        printDoubleValueWithKey(source, metrics, GfxMonitor.KEY_AVG_FRAME_TIME_95TH_PERCENTILE,
+                ResultType.LOWER_BETTER, ResultUnit.MS);
+        printDoubleValueWithKey(source, metrics, GfxMonitor.KEY_AVG_FRAME_TIME_99TH_PERCENTILE,
+                ResultType.LOWER_BETTER, ResultUnit.MS);
+        printDoubleValueWithKey(source, metrics, GfxMonitor.KEY_AVG_MISSED_VSYNC,
+                ResultType.LOWER_BETTER, ResultUnit.COUNT);
+        printDoubleValueWithKey(source, metrics, GfxMonitor.KEY_AVG_SLOW_UI_THREAD,
+                ResultType.LOWER_BETTER, ResultUnit.COUNT);
+        printDoubleValueWithKey(source, metrics, GfxMonitor.KEY_AVG_SLOW_BITMAP_UPLOADS,
+                ResultType.LOWER_BETTER, ResultUnit.COUNT);
+        printDoubleValueWithKey(source, metrics, GfxMonitor.KEY_AVG_SLOW_DRAW,
+                ResultType.LOWER_BETTER, ResultUnit.COUNT);
+        printDoubleValueWithKey(source, metrics, GfxMonitor.KEY_AVG_HIGH_INPUT_LATENCY,
+                ResultType.LOWER_BETTER, ResultUnit.COUNT);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mLog = new DeviceReportLog();
+        // fix device orientation
+        mDevice = UiDevice.getInstance(getInstrumentation());
+        mDevice.setOrientationNatural();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        mLog.deliverReportToHost(getInstrumentation());
+        // restore device orientation
+        mDevice.unfreezeRotation();
+        super.tearDown();
+    }
+
+    protected UiDevice getUiDevice() {
+        return mDevice;
+    }
+}
diff --git a/tests/libcore/Android.mk b/tests/libcore/Android.mk
new file mode 100644
index 0000000..47eace3
--- /dev/null
+++ b/tests/libcore/Android.mk
@@ -0,0 +1,65 @@
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := CtsLibcoreTestCases
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
+    apache-harmony-tests \
+    bouncycastle-nojarjar \
+    conscrypt-tests \
+    core-tests \
+    cts-core-test-runner \
+    jsr166-tests \
+    mockito-target \
+    okhttp-nojarjar \
+    okhttp-tests-nojarjar \
+    tzdata_update-tests
+
+#LOCAL_JAVA_LIBRARIES := android-support-test android.test.runner bouncycastle conscrypt
+
+# Don't include this package in any target
+LOCAL_MODULE_TAGS := tests
+
+# When built, explicitly put it in the data partition.
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_DEX_PREOPT := false
+LOCAL_JACK_FLAGS := --multi-dex native
+
+LOCAL_PROGUARD_ENABLED := disabled
+
+LOCAL_JNI_SHARED_LIBRARIES := libjavacoretests libsqlite_jni libnativehelper_compat_libc++ libc++
+
+# Include both the 32 and 64 bit versions of libjavacoretests,
+# where applicable.
+LOCAL_MULTILIB := both
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_JAVA_RESOURCE_DIRS := resources
+
+LOCAL_JAVA_RESOURCE_FILES := art/tools/libcore_failures.txt \
+    libcore/expectations/brokentests.txt \
+    libcore/expectations/icebox.txt \
+    libcore/expectations/knownfailures.txt \
+    libcore/expectations/taggedtests.txt
+
+LOCAL_JAVA_LANGUAGE_VERSION := 1.8
+
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/tests/libcore/AndroidManifest.xml b/tests/libcore/AndroidManifest.xml
new file mode 100644
index 0000000..c09f9ac
--- /dev/null
+++ b/tests/libcore/AndroidManifest.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android.libcore.cts">
+    <uses-permission android:name="android.permission.INTERNET" />
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="com.android.cts.core.runner.CoreTestRunner"
+                     android:targetPackage="android.libcore.cts"
+                     android:label="CTS Libcore test cases" />
+
+</manifest>
diff --git a/tests/libcore/AndroidTest.xml b/tests/libcore/AndroidTest.xml
new file mode 100644
index 0000000..f1802be
--- /dev/null
+++ b/tests/libcore/AndroidTest.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS Libcore test cases">
+    <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+        <option name="run-command" value="mkdir -p /data/local/tmp/ctslibcore/java.io.tmpdir" />
+        <option name="run-command" value="mkdir -p /data/local/tmp/ctslibcore/user.home" />
+        <option name="teardown-command" value="rm -rf /data/local/tmp/ctslibcore" />
+    </target_preparer>
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsLibcoreTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <!-- override AJUR -->
+        <option name="runner" value="com.android.cts.core.runner.CoreTestRunner" />
+        <option name="package" value="android.libcore.cts" />
+        <option name="instrumentation-arg" key="core-listener"
+                value="com.android.cts.runner.CtsTestRunListener"/>
+        <option name="instrumentation-arg" key="core-expectations"
+                value="/knownfailures.txt,/brokentests.txt,/icebox.txt,/libcore_failures.txt,/taggedtests.txt,/expectations/cts-runner-specific-failures.txt" />
+        <option name="runtime-hint" value="45m"/>
+    </test>
+</configuration>
diff --git a/tests/libcore/resources/expectations/cts-runner-specific-failures.txt b/tests/libcore/resources/expectations/cts-runner-specific-failures.txt
new file mode 100644
index 0000000..367bbe1
--- /dev/null
+++ b/tests/libcore/resources/expectations/cts-runner-specific-failures.txt
@@ -0,0 +1,113 @@
+/*
+ * This file contains expectations that occur due to differences in the way that the CTSv2 runner
+ * works.
+ *
+ * In CTSv1 the list of tests to run is generated at build time. The tool that does that
+ * (cts/tools/utils/CollectAllTests.java) filters out a lot of tests that would cause
+ * initializationError failures if they were run. The tests that are silently (in that it doesn't
+ * break the build) filtered out are as follows:
+ * - Those that extend junit.framework.Test but do not extend junit.framework.TestCase. The runner
+ *   only requires that the class extend junit.framework.Test.
+ */
+[
+{
+  description: "Extends TestSuite but have no tests",
+  names: [
+    "org.w3c.domts.JUnitTestSuiteAdapter",
+    "org.w3c.domts.level1.core.TestBatik",
+    "org.w3c.domts.level1.core.TestCrimson",
+    "org.w3c.domts.level1.core.TestCrimsonAltConfig",
+    "org.w3c.domts.level1.core.TestDefaultLS",
+    "org.w3c.domts.level1.core.TestDefaultLSAltConfig",
+    "org.w3c.domts.level1.core.TestDefaultParser",
+    "org.w3c.domts.level1.core.TestDefaultParserAltConfig",
+    "org.w3c.domts.level1.core.TestDOM4J",
+    "org.w3c.domts.level1.core.TestGNUJAXP",
+    "org.w3c.domts.level1.core.TestGNUJAXPAltConfig",
+    "org.w3c.domts.level1.core.TestJTidy",
+    "org.w3c.domts.level1.core.TestOracle",
+    "org.w3c.domts.level1.core.TestOracleAltConfig",
+    "org.w3c.domts.level1.core.TestXerces",
+    "org.w3c.domts.level1.core.TestXercesAltConfig",
+    "org.w3c.domts.level1.html.TestDefaultLS",
+    "org.w3c.domts.level1.html.TestDefaultLSAltConfig",
+    "org.w3c.domts.level1.html.TestXercesHTML",
+    "org.w3c.domts.level2.core.TestBatik",
+    "org.w3c.domts.level2.core.TestCrimson",
+    "org.w3c.domts.level2.core.TestCrimsonAltConfig",
+    "org.w3c.domts.level2.core.TestDefaultLS",
+    "org.w3c.domts.level2.core.TestDefaultLSAltConfig",
+    "org.w3c.domts.level2.core.TestDefaultParser",
+    "org.w3c.domts.level2.core.TestDefaultParserAltConfig",
+    "org.w3c.domts.level2.core.TestDOM4J",
+    "org.w3c.domts.level2.core.TestGNUJAXP",
+    "org.w3c.domts.level2.core.TestGNUJAXPAltConfig",
+    "org.w3c.domts.level2.core.TestJTidy",
+    "org.w3c.domts.level2.core.TestOracle",
+    "org.w3c.domts.level2.core.TestOracleAltConfig",
+    "org.w3c.domts.level2.core.TestXerces",
+    "org.w3c.domts.level2.core.TestXercesAltConfig",
+    "org.w3c.domts.level2.events.TestBatik",
+    "org.w3c.domts.level2.events.TestDefaultLS",
+    "org.w3c.domts.level2.events.TestDefaultLSAltConfig",
+    "org.w3c.domts.level2.events.TestDefaultParser",
+    "org.w3c.domts.level2.events.TestDefaultParserAltConfig",
+    "org.w3c.domts.level2.events.TestOracle",
+    "org.w3c.domts.level2.events.TestOracleAltConfig",
+    "org.w3c.domts.level2.events.TestXerces",
+    "org.w3c.domts.level2.events.TestXercesAltConfig",
+    "org.w3c.domts.level2.html.TestDefaultLS",
+    "org.w3c.domts.level2.html.TestDefaultLSAltConfig",
+    "org.w3c.domts.level2.html.TestXercesHTML",
+    "org.w3c.domts.level3.core.TestBatik",
+    "org.w3c.domts.level3.core.TestDefaultLS",
+    "org.w3c.domts.level3.core.TestDefaultLSAltConfig",
+    "org.w3c.domts.level3.core.TestDefaultParser",
+    "org.w3c.domts.level3.core.TestDefaultParserAltConfig",
+    "org.w3c.domts.level3.core.TestOracle",
+    "org.w3c.domts.level3.core.TestOracleAltConfig",
+    "org.w3c.domts.level3.core.TestXerces",
+    "org.w3c.domts.level3.core.TestXercesAltConfig",
+    "org.w3c.domts.level3.ls.TestBatik",
+    "org.w3c.domts.level3.ls.TestDefaultLS",
+    "org.w3c.domts.level3.ls.TestDefaultParser",
+    "org.w3c.domts.level3.ls.TestOracle",
+    "org.w3c.domts.level3.ls.TestXerces",
+    "org.w3c.domts.level3.validation.TestBatik",
+    "org.w3c.domts.level3.validation.TestDefaultLS",
+    "org.w3c.domts.level3.validation.TestDefaultLSAltConfig",
+    "org.w3c.domts.level3.validation.TestDefaultParser",
+    "org.w3c.domts.level3.validation.TestDefaultParserAltConfig",
+    "org.w3c.domts.level3.validation.TestOracle",
+    "org.w3c.domts.level3.validation.TestOracleAltConfig",
+    "org.w3c.domts.level3.xpath.TestBatik",
+    "org.w3c.domts.level3.xpath.TestDefaultLS",
+    "org.w3c.domts.level3.xpath.TestDefaultLSAltConfig",
+    "org.w3c.domts.level3.xpath.TestDefaultParser",
+    "org.w3c.domts.level3.xpath.TestDefaultParserAltConfig",
+    "org.w3c.domts.level3.xpath.TestXalan",
+    "org.w3c.domts.level3.xpath.TestXalanAltConfig"
+  ],
+  bug: "1234"
+},
+{
+  description: "CTS: SSLSocketTest#test_SSLSocket_endpointIdentification_Failure failing",
+  name: "libcore.javax.net.ssl.SSLSocketTest#test_SSLSocket_endpointIdentification_Failure",
+  bug: "27271561"
+},
+{
+  description: "Re-enable blacklisted libcore tests in enso",
+  name: "org.apache.harmony.tests.java.net.ServerSocketTest#test_toString",
+  bug: "26352408"
+},
+{
+  description: "JarEntry.getCertificates(), getCodeSigners() should return null until the entry has been read",
+  names: [
+    "org.apache.harmony.tests.java.util.jar.JarEntryTest#testCertificatesAndCodesigners",
+    "org.apache.harmony.tests.java.util.jar.JarEntryTest#test_getCodeSigners",
+    "org.apache.harmony.tests.java.util.jar.JarFileTest#testJarFile_Signed_InvalidChain",
+    "org.apache.harmony.tests.java.util.jar.JarFileTest#testJarFile_Signed_ValidChain"
+  ],
+  bug: "1864326"
+}
+]
diff --git a/tests/netlegacy22.api/Android.mk b/tests/netlegacy22.api/Android.mk
index 68fd6f8..93f848b 100644
--- a/tests/netlegacy22.api/Android.mk
+++ b/tests/netlegacy22.api/Android.mk
@@ -29,4 +29,7 @@
 
 LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_CTS_PACKAGE)
diff --git a/tests/netlegacy22.api/AndroidManifest.xml b/tests/netlegacy22.api/AndroidManifest.xml
index f13805c..e900ceb 100644
--- a/tests/netlegacy22.api/AndroidManifest.xml
+++ b/tests/netlegacy22.api/AndroidManifest.xml
@@ -16,7 +16,7 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.netlegacy22.api">
+    package="android.netlegacy22.api.cts">
 
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
@@ -30,7 +30,7 @@
     </application>
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.cts.netlegacy22.api"
+                     android:targetPackage="android.netlegacy22.api.cts"
                      android:label="CTS tests of legacy android.net APIs as of API 22">
         <meta-data android:name="listener"
             android:value="com.android.cts.runner.CtsTestRunListener" />
diff --git a/tests/netlegacy22.api/AndroidTest.xml b/tests/netlegacy22.api/AndroidTest.xml
new file mode 100644
index 0000000..b40f21a
--- /dev/null
+++ b/tests/netlegacy22.api/AndroidTest.xml
@@ -0,0 +1,23 @@
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS Legacy android.net APIs test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsNetTestCasesLegacyApi22.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.netlegacy22.api.cts" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/netlegacy22.permission/Android.mk b/tests/netlegacy22.permission/Android.mk
index fff9d85..8f6f12e 100644
--- a/tests/netlegacy22.permission/Android.mk
+++ b/tests/netlegacy22.permission/Android.mk
@@ -29,4 +29,7 @@
 
 LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_CTS_PACKAGE)
diff --git a/tests/netlegacy22.permission/AndroidManifest.xml b/tests/netlegacy22.permission/AndroidManifest.xml
index cd1d2ba..af22b47 100644
--- a/tests/netlegacy22.permission/AndroidManifest.xml
+++ b/tests/netlegacy22.permission/AndroidManifest.xml
@@ -16,7 +16,7 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.netlegacy22.permission">
+    package="android.netlegacy22.permission.cts">
 
     <uses-permission android:name="android.permission.INJECT_EVENTS" />
     <application>
@@ -41,7 +41,7 @@
         relies on hidden APIs.
     -->
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.cts.netlegacy22.permission"
+                     android:targetPackage="android.netlegacy22.permission.cts"
                      android:label="CTS tests of legacy android.net permissions as of API 22">
         <meta-data android:name="listener"
             android:value="com.android.cts.runner.CtsTestRunListener" />
diff --git a/tests/netlegacy22.permission/AndroidTest.xml b/tests/netlegacy22.permission/AndroidTest.xml
new file mode 100644
index 0000000..490e979
--- /dev/null
+++ b/tests/netlegacy22.permission/AndroidTest.xml
@@ -0,0 +1,23 @@
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS Legacy android.net Permission test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsNetTestCasesLegacyPermission22.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.netlegacy22.permission.cts" />
+    </test>
+</configuration>
diff --git a/tests/netsecpolicy/usescleartexttraffic-false/Android.mk b/tests/netsecpolicy/usescleartexttraffic-false/Android.mk
index 1af3b49..6b24a37 100644
--- a/tests/netsecpolicy/usescleartexttraffic-false/Android.mk
+++ b/tests/netsecpolicy/usescleartexttraffic-false/Android.mk
@@ -25,6 +25,9 @@
 
 LOCAL_PACKAGE_NAME := CtsNetSecPolicyUsesCleartextTrafficFalse
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_SDK_VERSION := current
 
 include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/tests/netsecpolicy/usescleartexttraffic-false/AndroidManifest.xml b/tests/netsecpolicy/usescleartexttraffic-false/AndroidManifest.xml
index c87b800..a18f87a 100644
--- a/tests/netsecpolicy/usescleartexttraffic-false/AndroidManifest.xml
+++ b/tests/netsecpolicy/usescleartexttraffic-false/AndroidManifest.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 
 <!--
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/netsecpolicy/usescleartexttraffic-true/Android.mk b/tests/netsecpolicy/usescleartexttraffic-true/Android.mk
index 5effc57..9727959 100644
--- a/tests/netsecpolicy/usescleartexttraffic-true/Android.mk
+++ b/tests/netsecpolicy/usescleartexttraffic-true/Android.mk
@@ -25,6 +25,9 @@
 
 LOCAL_PACKAGE_NAME := CtsNetSecPolicyUsesCleartextTrafficTrue
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_SDK_VERSION := current
 
 include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/tests/netsecpolicy/usescleartexttraffic-true/AndroidManifest.xml b/tests/netsecpolicy/usescleartexttraffic-true/AndroidManifest.xml
index da15ddd..d4b7d5b 100644
--- a/tests/netsecpolicy/usescleartexttraffic-true/AndroidManifest.xml
+++ b/tests/netsecpolicy/usescleartexttraffic-true/AndroidManifest.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 
 <!--
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/netsecpolicy/usescleartexttraffic-unspecified/Android.mk b/tests/netsecpolicy/usescleartexttraffic-unspecified/Android.mk
index 685a16f..7a964cc 100644
--- a/tests/netsecpolicy/usescleartexttraffic-unspecified/Android.mk
+++ b/tests/netsecpolicy/usescleartexttraffic-unspecified/Android.mk
@@ -25,6 +25,9 @@
 
 LOCAL_PACKAGE_NAME := CtsNetSecPolicyUsesCleartextTrafficUnspecified
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_SDK_VERSION := current
 
 include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/tests/netsecpolicy/usescleartexttraffic-unspecified/AndroidManifest.xml b/tests/netsecpolicy/usescleartexttraffic-unspecified/AndroidManifest.xml
index 5b3a181..07731b9 100644
--- a/tests/netsecpolicy/usescleartexttraffic-unspecified/AndroidManifest.xml
+++ b/tests/netsecpolicy/usescleartexttraffic-unspecified/AndroidManifest.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 
 <!--
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/openglperf2/Android.mk b/tests/openglperf2/Android.mk
new file mode 100644
index 0000000..f4295ca
--- /dev/null
+++ b/tests/openglperf2/Android.mk
@@ -0,0 +1,39 @@
+# Copyright (C) 2013 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+# don't include this package in any target
+LOCAL_MODULE_TAGS := tests
+
+# Include both the 32 and 64 bit versions
+LOCAL_MULTILIB := both
+
+LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil compatibility-device-util ctstestrunner
+
+LOCAL_JNI_SHARED_LIBRARIES := libctsopengl_jni
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := CtsOpenGlPerf2TestCases
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_SDK_VERSION := 16
+
+include $(BUILD_CTS_PACKAGE)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/openglperf2/AndroidManifest.xml b/tests/openglperf2/AndroidManifest.xml
new file mode 100644
index 0000000..b1051a4d
--- /dev/null
+++ b/tests/openglperf2/AndroidManifest.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.opengl2.cts"
+    android:versionCode="1"
+    android:versionName="1.0" >
+
+    <uses-sdk
+        android:minSdkVersion="16"
+        android:targetSdkVersion="17" />
+
+    <uses-feature
+        android:glEsVersion="0x00020000"
+        android:required="true" />
+
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+
+    <application android:allowBackup="false" >
+        <uses-library android:name="android.test.runner" />
+
+        <activity
+            android:name=".primitive.GLPrimitiveActivity"
+            android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode"
+            android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity
+            android:name=".reference.GLReferenceActivity"
+            android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode"
+            android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity
+            android:name=".reference.GLGameActivity"
+            android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode"
+            android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >
+        </activity>
+    </application>
+
+    <instrumentation
+        android:name="android.support.test.runner.AndroidJUnitRunner"
+        android:label="OpenGL ES Benchmark"
+        android:targetPackage="android.opengl2.cts" />
+
+</manifest>
\ No newline at end of file
diff --git a/tests/openglperf2/AndroidTest.xml b/tests/openglperf2/AndroidTest.xml
new file mode 100644
index 0000000..b4ca796
--- /dev/null
+++ b/tests/openglperf2/AndroidTest.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS OpenGL test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsOpenGlPerf2TestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.opengl2.cts" />
+        <option name="runtime-hint" value="4m" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/suite/cts/deviceTests/opengl/README b/tests/openglperf2/README
similarity index 100%
rename from suite/cts/deviceTests/opengl/README
rename to tests/openglperf2/README
diff --git a/suite/cts/deviceTests/opengl/assets/fragment/basic b/tests/openglperf2/assets/fragment/basic
similarity index 100%
rename from suite/cts/deviceTests/opengl/assets/fragment/basic
rename to tests/openglperf2/assets/fragment/basic
diff --git a/suite/cts/deviceTests/opengl/assets/fragment/blur b/tests/openglperf2/assets/fragment/blur
similarity index 100%
rename from suite/cts/deviceTests/opengl/assets/fragment/blur
rename to tests/openglperf2/assets/fragment/blur
diff --git a/suite/cts/deviceTests/opengl/assets/fragment/perspective b/tests/openglperf2/assets/fragment/perspective
similarity index 100%
rename from suite/cts/deviceTests/opengl/assets/fragment/perspective
rename to tests/openglperf2/assets/fragment/perspective
diff --git a/suite/cts/deviceTests/opengl/assets/fragment/water b/tests/openglperf2/assets/fragment/water
similarity index 100%
rename from suite/cts/deviceTests/opengl/assets/fragment/water
rename to tests/openglperf2/assets/fragment/water
diff --git a/suite/cts/deviceTests/opengl/assets/mesh/arc.cob b/tests/openglperf2/assets/mesh/arc.cob
similarity index 100%
rename from suite/cts/deviceTests/opengl/assets/mesh/arc.cob
rename to tests/openglperf2/assets/mesh/arc.cob
Binary files differ
diff --git a/suite/cts/deviceTests/opengl/assets/mesh/fish.cob b/tests/openglperf2/assets/mesh/fish.cob
similarity index 100%
rename from suite/cts/deviceTests/opengl/assets/mesh/fish.cob
rename to tests/openglperf2/assets/mesh/fish.cob
Binary files differ
diff --git a/suite/cts/deviceTests/opengl/assets/mesh/plane.cob b/tests/openglperf2/assets/mesh/plane.cob
similarity index 100%
rename from suite/cts/deviceTests/opengl/assets/mesh/plane.cob
rename to tests/openglperf2/assets/mesh/plane.cob
Binary files differ
diff --git a/suite/cts/deviceTests/opengl/assets/texture/arc.png b/tests/openglperf2/assets/texture/arc.png
similarity index 100%
rename from suite/cts/deviceTests/opengl/assets/texture/arc.png
rename to tests/openglperf2/assets/texture/arc.png
Binary files differ
diff --git a/suite/cts/deviceTests/opengl/assets/texture/background.png b/tests/openglperf2/assets/texture/background.png
similarity index 100%
rename from suite/cts/deviceTests/opengl/assets/texture/background.png
rename to tests/openglperf2/assets/texture/background.png
Binary files differ
diff --git a/suite/cts/deviceTests/opengl/assets/texture/fish.png b/tests/openglperf2/assets/texture/fish.png
similarity index 100%
rename from suite/cts/deviceTests/opengl/assets/texture/fish.png
rename to tests/openglperf2/assets/texture/fish.png
Binary files differ
diff --git a/suite/cts/deviceTests/opengl/assets/texture/fish_dark.png b/tests/openglperf2/assets/texture/fish_dark.png
similarity index 100%
rename from suite/cts/deviceTests/opengl/assets/texture/fish_dark.png
rename to tests/openglperf2/assets/texture/fish_dark.png
Binary files differ
diff --git a/suite/cts/deviceTests/opengl/assets/texture/water1.png b/tests/openglperf2/assets/texture/water1.png
similarity index 100%
rename from suite/cts/deviceTests/opengl/assets/texture/water1.png
rename to tests/openglperf2/assets/texture/water1.png
Binary files differ
diff --git a/suite/cts/deviceTests/opengl/assets/texture/water2.png b/tests/openglperf2/assets/texture/water2.png
similarity index 100%
rename from suite/cts/deviceTests/opengl/assets/texture/water2.png
rename to tests/openglperf2/assets/texture/water2.png
Binary files differ
diff --git a/suite/cts/deviceTests/opengl/assets/vertex/basic b/tests/openglperf2/assets/vertex/basic
similarity index 100%
rename from suite/cts/deviceTests/opengl/assets/vertex/basic
rename to tests/openglperf2/assets/vertex/basic
diff --git a/suite/cts/deviceTests/opengl/assets/vertex/blur b/tests/openglperf2/assets/vertex/blur
similarity index 100%
rename from suite/cts/deviceTests/opengl/assets/vertex/blur
rename to tests/openglperf2/assets/vertex/blur
diff --git a/suite/cts/deviceTests/opengl/assets/vertex/perspective b/tests/openglperf2/assets/vertex/perspective
similarity index 100%
rename from suite/cts/deviceTests/opengl/assets/vertex/perspective
rename to tests/openglperf2/assets/vertex/perspective
diff --git a/suite/cts/deviceTests/opengl/assets/vertex/water b/tests/openglperf2/assets/vertex/water
similarity index 100%
rename from suite/cts/deviceTests/opengl/assets/vertex/water
rename to tests/openglperf2/assets/vertex/water
diff --git a/suite/cts/deviceTests/opengl/cob_exporter.py b/tests/openglperf2/cob_exporter.py
similarity index 100%
rename from suite/cts/deviceTests/opengl/cob_exporter.py
rename to tests/openglperf2/cob_exporter.py
diff --git a/tests/openglperf2/jni/Android.mk b/tests/openglperf2/jni/Android.mk
new file mode 100644
index 0000000..c2bb7a8
--- /dev/null
+++ b/tests/openglperf2/jni/Android.mk
@@ -0,0 +1,37 @@
+# Copyright (C) 2013 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libctsopengl_jni
+
+# Needed in order to use fences for synchronization
+LOCAL_CFLAGS += -DEGL_EGLEXT_PROTOTYPES -funsigned-char
+
+# Get all cpp files but not hidden files
+LOCAL_SRC_FILES := $(call all-subdir-cpp-files)
+
+LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
+
+LOCAL_SHARED_LIBRARIES := libEGL libGLESv2 libandroid liblog
+
+LOCAL_CXX_STL := libc++_static
+
+# TODO (dimitry): replace LOCAL_CXX_STL with LOCAL_SDK_VERSION+LOCAL_NDK_STL_VARIANT
+# LOCAL_SDK_VERSION := 23
+# LOCAL_NDK_STL_VARIANT := c++_static
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/suite/cts/deviceTests/opengl/jni/Trace.h b/tests/openglperf2/jni/Trace.h
similarity index 100%
rename from suite/cts/deviceTests/opengl/jni/Trace.h
rename to tests/openglperf2/jni/Trace.h
diff --git a/tests/openglperf2/jni/graphics/GLUtils.cpp b/tests/openglperf2/jni/graphics/GLUtils.cpp
new file mode 100644
index 0000000..e6beecc
--- /dev/null
+++ b/tests/openglperf2/jni/graphics/GLUtils.cpp
@@ -0,0 +1,239 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+#include "GLUtils.h"
+#include <stdlib.h>
+#include <sys/time.h>
+
+#include <android/asset_manager_jni.h>
+
+#define LOG_TAG "CTS_OPENGL"
+#define LOG_NDEBUG 0
+#include <android/log.h>
+
+static JNIEnv* sEnv = NULL;
+static jobject sAssetManager = NULL;
+
+void GLUtils::setEnvAndAssetManager(JNIEnv* env, jobject assetManager) {
+    sEnv = env;
+    sAssetManager = assetManager;
+}
+
+static AAsset* loadAsset(const char* path) {
+    AAssetManager* nativeManager = AAssetManager_fromJava(sEnv, sAssetManager);
+    if (nativeManager == NULL) {
+        return NULL;
+    }
+    return AAssetManager_open(nativeManager, path, AASSET_MODE_UNKNOWN);;
+}
+
+char* GLUtils::openTextFile(const char* path) {
+    AAsset* asset = loadAsset(path);
+    if (asset == NULL) {
+        __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "Couldn't load %s", path);
+        return NULL;
+    }
+    off_t length = AAsset_getLength(asset);
+    char* buffer = new char[length + 1];
+    int num = AAsset_read(asset, buffer, length);
+    AAsset_close(asset);
+    if (num != length) {
+        __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "Couldn't read %s", path);
+        delete[] buffer;
+        return NULL;
+    }
+    buffer[length] = '\0';
+    return buffer;
+}
+
+GLuint GLUtils::loadTexture(const char* path) {
+    GLuint textureId = 0;
+    jclass activityClass = sEnv->FindClass("android/opengl2/cts/reference/GLGameActivity");
+    if (activityClass == NULL) {
+        __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "Couldn't find activity class");
+        return -1;
+    }
+    jmethodID loadTexture = sEnv->GetStaticMethodID(activityClass, "loadTexture",
+            "(Landroid/content/res/AssetManager;Ljava/lang/String;)I");
+    if (loadTexture == NULL) {
+        __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "Couldn't find loadTexture method");
+        return -1;
+    }
+    jstring pathStr = sEnv->NewStringUTF(path);
+    textureId = sEnv->CallStaticIntMethod(activityClass, loadTexture, sAssetManager, pathStr);
+    sEnv->DeleteLocalRef(pathStr);
+    return textureId;
+}
+
+static int readInt(char* b) {
+    unsigned char* ub = (unsigned char*) b;
+    return (((int) ub[0]) << 24) | (((int) ub[1]) << 16) | (((int) ub[2]) << 8) | ((int) ub[3]);
+}
+
+static float readFloat(char* b) {
+    union {
+        int input;
+        float output;
+    } data;
+    data.input = readInt(b);
+    return data.output;
+}
+
+Mesh* GLUtils::loadMesh(const char* path) {
+    char* buffer = openTextFile(path);
+    if (buffer == NULL) {
+        return NULL;
+    }
+    int index = 0;
+    int numVertices = readInt(buffer + index);
+    index += 4;
+    float* vertices = new float[numVertices * 3];
+    float* normals = new float[numVertices * 3];
+    float* texCoords = new float[numVertices * 2];
+    for (int i = 0; i < numVertices; i++) {
+        // Vertices
+        int vIndex = i * 3;
+        vertices[vIndex + 0] = readFloat(buffer + index);
+        index += 4;
+        vertices[vIndex + 1] = readFloat(buffer + index);
+        index += 4;
+        vertices[vIndex + 2] = readFloat(buffer + index);
+        index += 4;
+        // Normals
+        normals[vIndex + 0] = readFloat(buffer + index);
+        index += 4;
+        normals[vIndex + 1] = readFloat(buffer + index);
+        index += 4;
+        normals[vIndex + 2] = readFloat(buffer + index);
+        index += 4;
+        // Texture Coordinates
+        int tIndex = i * 2;
+        texCoords[tIndex + 0] = readFloat(buffer + index);
+        index += 4;
+        texCoords[tIndex + 1] = readFloat(buffer + index);
+        index += 4;
+    }
+    return new Mesh(vertices, normals, texCoords, numVertices);
+}
+
+// Loads the given source code as a shader of the given type.
+static GLuint loadShader(GLenum shaderType, const char** source) {
+    GLuint shader = glCreateShader(shaderType);
+    if (shader) {
+        glShaderSource(shader, 1, source, NULL);
+        glCompileShader(shader);
+        GLint compiled = 0;
+        glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
+        if (!compiled) {
+            GLint infoLen = 0;
+            glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
+            if (infoLen > 0) {
+                char* infoLog = (char*) malloc(sizeof(char) * infoLen);
+                glGetShaderInfoLog(shader, infoLen, NULL, infoLog);
+                __android_log_print(ANDROID_LOG_ERROR, LOG_TAG,
+                                    "Error compiling shader:\n%s\n", infoLog);
+                free(infoLog);
+            }
+            glDeleteShader(shader);
+            shader = 0;
+        }
+    }
+    return shader;
+}
+
+GLuint GLUtils::createProgram(const char** vertexSource, const char** fragmentSource) {
+    GLuint vertexShader = loadShader(GL_VERTEX_SHADER, vertexSource);
+    if (!vertexShader) {
+        return 0;
+    }
+
+    GLuint fragmentShader = loadShader(GL_FRAGMENT_SHADER, fragmentSource);
+    if (!fragmentShader) {
+        return 0;
+    }
+
+    GLuint program = glCreateProgram();
+    if (program) {
+        glAttachShader(program, vertexShader);
+        glAttachShader(program, fragmentShader);
+
+        GLint linkStatus;
+        glLinkProgram(program);
+        glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
+
+        if (!linkStatus) {
+            GLint infoLen = 0;
+            glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLen);
+            if (infoLen > 0) {
+                char* infoLog = (char*) malloc(sizeof(char) * infoLen);
+                glGetProgramInfoLog(program, infoLen, NULL, infoLog);
+                __android_log_print(ANDROID_LOG_ERROR, LOG_TAG,
+                                    "Error linking program:\n%s\n", infoLog);
+                free(infoLog);
+            }
+            glDeleteProgram(program);
+            program = 0;
+        }
+    }
+    return program;
+}
+
+double GLUtils::currentTimeMillis() {
+    struct timeval tv;
+    gettimeofday(&tv, (struct timezone *) NULL);
+    return tv.tv_sec * 1000.0 + tv.tv_usec / 1000.0;
+}
+
+// Rounds a number up to the smallest power of 2 that is greater than or equal to x.
+int GLUtils::roundUpToSmallestPowerOf2(int x) {
+    if (x < 0) {
+        return 0;
+    }
+    --x;
+    x |= x >> 1;
+    x |= x >> 2;
+    x |= x >> 4;
+    x |= x >> 8;
+    x |= x >> 16;
+    return x + 1;
+}
+
+GLuint GLUtils::genTexture(int texWidth, int texHeight, int fill) {
+    GLuint textureId = 0;
+    int w = roundUpToSmallestPowerOf2(texWidth);
+    int h = roundUpToSmallestPowerOf2(texHeight);
+    uint32_t* m = new uint32_t[w * h];
+    if (m != NULL) {
+        uint32_t* d = m;
+        for (int y = 0; y < h; y++) {
+            for (int x = 0; x < w; x++) {
+                if (fill == RANDOM_FILL) {
+                    *d = 0xff000000 | ((y & 0xff) << 16) | ((x & 0xff) << 8) | ((x + y) & 0xff);
+                } else {
+                    *d = 0xff000000 | fill;
+                }
+                d++;
+            }
+        }
+        glGenTextures(1, &textureId);
+        glBindTexture(GL_TEXTURE_2D, textureId);
+        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, m);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+    }
+    delete[] m;
+    return textureId;
+}
diff --git a/suite/cts/deviceTests/opengl/jni/graphics/GLUtils.h b/tests/openglperf2/jni/graphics/GLUtils.h
similarity index 100%
rename from suite/cts/deviceTests/opengl/jni/graphics/GLUtils.h
rename to tests/openglperf2/jni/graphics/GLUtils.h
diff --git a/tests/openglperf2/jni/graphics/Matrix.cpp b/tests/openglperf2/jni/graphics/Matrix.cpp
new file mode 100644
index 0000000..463338a
--- /dev/null
+++ b/tests/openglperf2/jni/graphics/Matrix.cpp
@@ -0,0 +1,328 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+#include "Matrix.h"
+#include <string.h>
+#include <cmath>
+
+#define LOG_TAG "CTS_OPENGL"
+#define LOG_NDEBUG 0
+#include "android/log.h"
+
+Matrix::Matrix() {
+    identity();
+}
+
+Matrix::Matrix(const Matrix& src) {
+    loadWith(src);
+}
+
+void Matrix::print(const char* label) {
+    __android_log_print(ANDROID_LOG_INFO, LOG_TAG, "%c", *label);
+    for (int i = 0; i < 4; i++) {
+        const float* d = &(mData[i * 4]);
+        __android_log_print(ANDROID_LOG_INFO, LOG_TAG, "%f %f %f %f\n", d[0], d[1], d[2], d[3]);
+    }
+}
+
+bool Matrix::equals(const Matrix& src) {
+    bool equals = true;
+    const float* d = src.mData;
+    for (int i = 0; i < MATRIX_SIZE && equals; i++) {
+        if (mData[i] != d[i]) {
+            equals = false;
+        }
+    }
+    return equals;
+}
+
+void Matrix::loadWith(const Matrix& src) {
+    memcpy(mData, src.mData, MATRIX_SIZE * sizeof(float));
+}
+
+void Matrix::identity() {
+    mData[0] = 1.0f;
+    mData[1] = 0.0f;
+    mData[2] = 0.0f;
+    mData[3] = 0.0f;
+
+    mData[4] = 0.0f;
+    mData[5] = 1.0f;
+    mData[6] = 0.0f;
+    mData[7] = 0.0f;
+
+    mData[8] = 0.0f;
+    mData[9] = 0.0f;
+    mData[10] = 1.0f;
+    mData[11] = 0.0f;
+
+    mData[12] = 0.0f;
+    mData[13] = 0.0f;
+    mData[14] = 0.0f;
+    mData[15] = 1.0f;
+}
+
+void Matrix::translate(float x, float y, float z) {
+    Matrix* m = newTranslate(x, y, z);
+    Matrix* temp = new Matrix(*this);
+    if (m != NULL && temp != NULL) {
+        multiply(*temp, *m);
+    }
+    delete m;
+    delete temp;
+}
+
+void Matrix::scale(float x, float y, float z) {
+    Matrix* m = newScale(x, y, z);
+    Matrix* temp = new Matrix(*this);
+    if (m != NULL && temp != NULL) {
+        multiply(*temp, *m);
+    }
+    delete m;
+    delete temp;
+}
+
+void Matrix::rotate(float radians, float x, float y, float z) {
+    Matrix* m = newRotate(radians, x, y, z);
+    Matrix* temp = new Matrix(*this);
+    if (m != NULL && temp != NULL) {
+        multiply(*temp, *m);
+    }
+    delete m;
+    delete temp;
+}
+
+void Matrix::multiply(const Matrix& l, const Matrix& r) {
+    float const* const lhs = l.mData;
+    float const* const rhs = r.mData;
+    for (int i = 0; i < 4; i++) {
+        const int i4 = i * 4;
+        float x = 0;
+        float y = 0;
+        float z = 0;
+        float w = 0;
+
+        for (int j = 0; j < 4; j++) {
+            const int j4 = j * 4;
+            const float e = rhs[i4 + j];
+            x += lhs[j4 + 0] * e;
+            y += lhs[j4 + 1] * e;
+            z += lhs[j4 + 2] * e;
+            w += lhs[j4 + 3] * e;
+        }
+
+        mData[i4 + 0] = x;
+        mData[i4 + 1] = y;
+        mData[i4 + 2] = z;
+        mData[i4 + 3] = w;
+    }
+}
+
+Matrix* Matrix::newLookAt(float eyeX, float eyeY, float eyeZ, float centerX,
+        float centerY, float centerZ, float upX, float upY, float upZ) {
+    Matrix* m = new Matrix();
+    if (m != NULL) {
+        // See the OpenGL GLUT documentation for gluLookAt for a description
+        // of the algorithm. We implement it in a straightforward way:
+
+        float fx = centerX - eyeX;
+        float fy = centerY - eyeY;
+        float fz = centerZ - eyeZ;
+
+        // Normalize f
+        float rlf = 1.0f / (float) sqrt(fx * fx + fy * fy + fz * fz);
+        fx *= rlf;
+        fy *= rlf;
+        fz *= rlf;
+
+        // compute s = f x up (x means "cross product")
+        float sx = fy * upZ - fz * upY;
+        float sy = fz * upX - fx * upZ;
+        float sz = fx * upY - fy * upX;
+
+        // and normalize s
+        float rls = 1.0f / (float) sqrt(sx * sx + sy * sy + sz * sz);
+        sx *= rls;
+        sy *= rls;
+        sz *= rls;
+
+        // compute u = s x f
+        float ux = sy * fz - sz * fy;
+        float uy = sz * fx - sx * fz;
+        float uz = sx * fy - sy * fx;
+
+        float* d = m->mData;
+        d[0] = sx;
+        d[1] = ux;
+        d[2] = -fx;
+        d[3] = 0.0f;
+
+        d[4] = sy;
+        d[5] = uy;
+        d[6] = -fy;
+        d[7] = 0.0f;
+
+        d[8] = sz;
+        d[9] = uz;
+        d[10] = -fz;
+        d[11] = 0.0f;
+
+        d[12] = 0.0f;
+        d[13] = 0.0f;
+        d[14] = 0.0f;
+        d[15] = 1.0f;
+
+        m->translate(-eyeX, -eyeY, -eyeZ);
+    }
+    return m;
+}
+
+Matrix* Matrix::newFrustum(float left, float right, float bottom, float top,
+        float near, float far) {
+    const float r_width = 1.0f / (right - left);
+    const float r_height = 1.0f / (top - bottom);
+    const float r_depth = 1.0f / (near - far);
+    const float x = 2.0f * (near * r_width);
+    const float y = 2.0f * (near * r_height);
+    const float A = (right + left) * r_width;
+    const float B = (top + bottom) * r_height;
+    const float C = (far + near) * r_depth;
+    const float D = 2.0f * (far * near * r_depth);
+    Matrix* m = new Matrix();
+    if (m != NULL) {
+        float* d = m->mData;
+        d[0] = x;
+        d[5] = y;
+        d[8] = A;
+        d[9] = B;
+        d[10] = C;
+        d[14] = D;
+        d[11] = -1.0f;
+        d[1] = 0.0f;
+        d[2] = 0.0f;
+        d[3] = 0.0f;
+        d[4] = 0.0f;
+        d[6] = 0.0f;
+        d[7] = 0.0f;
+        d[12] = 0.0f;
+        d[13] = 0.0f;
+        d[15] = 0.0f;
+    }
+    return m;
+}
+
+Matrix* Matrix::newTranslate(float x, float y, float z) {
+    Matrix* m = new Matrix();
+    if (m != NULL) {
+        float* d = m->mData;
+        d[12] = x;
+        d[13] = y;
+        d[14] = z;
+    }
+    return m;
+}
+Matrix* Matrix::newScale(float x, float y, float z) {
+    Matrix* m = new Matrix();
+    if (m != NULL) {
+        float* d = m->mData;
+        d[0] = x;
+        d[5] = y;
+        d[10] = z;
+    }
+    return m;
+}
+Matrix* Matrix::newRotate(float radians, float x, float y, float z) {
+    Matrix* m = new Matrix();
+    if (m != NULL) {
+        float* d = m->mData;
+        d[3] = 0;
+        d[7] = 0;
+        d[11] = 0;
+        d[12] = 0;
+        d[13] = 0;
+        d[14] = 0;
+        d[15] = 1;
+        float s = (float) sinf(radians);
+        float c = (float) cosf(radians);
+        if (1.0f == x && 0.0f == y && 0.0f == z) {
+            d[5] = c;
+            d[10] = c;
+            d[6] = s;
+            d[9] = -s;
+            d[1] = 0;
+            d[2] = 0;
+            d[4] = 0;
+            d[8] = 0;
+            d[0] = 1;
+        } else if (0.0f == x && 1.0f == y && 0.0f == z) {
+            d[0] = c;
+            d[10] = c;
+            d[8] = s;
+            d[2] = -s;
+            d[1] = 0;
+            d[4] = 0;
+            d[6] = 0;
+            d[9] = 0;
+            d[5] = 1;
+        } else if (0.0f == x && 0.0f == y && 1.0f == z) {
+            d[0] = c;
+            d[5] = c;
+            d[1] = s;
+            d[4] = -s;
+            d[2] = 0;
+            d[6] = 0;
+            d[8] = 0;
+            d[9] = 0;
+            d[10] = 1;
+        } else {
+            float len = sqrt((x * x) + (y * y) + (z * z));
+            if (1.0f != len) {
+                float recipLen = 1.0f / len;
+                x *= recipLen;
+                y *= recipLen;
+                z *= recipLen;
+            }
+            float nc = 1.0f - c;
+            float xy = x * y;
+            float yz = y * z;
+            float zx = z * x;
+            float xs = x * s;
+            float ys = y * s;
+            float zs = z * s;
+            d[0] = x * x * nc + c;
+            d[4] = xy * nc - zs;
+            d[8] = zx * nc + ys;
+            d[1] = xy * nc + zs;
+            d[5] = y * y * nc + c;
+            d[9] = yz * nc - xs;
+            d[2] = zx * nc - ys;
+            d[6] = yz * nc + xs;
+            d[10] = z * z * nc + c;
+        }
+    }
+    return m;
+}
+
+void Matrix::multiplyVector(float* result, const Matrix& lhs,
+        const float* rhs) {
+    const float* d = lhs.mData;
+    const float x = rhs[0];
+    const float y = rhs[1];
+    const float z = rhs[2];
+    const float w = rhs[3];
+    for (int i = 0; i < 4; i++) {
+        const int j = i * 4;
+        result[i] = d[j + 0] * x + d[j + 1] * y + d[j + 2] * z + d[j + 3] * w;
+    }
+}
diff --git a/suite/cts/deviceTests/opengl/jni/graphics/Matrix.h b/tests/openglperf2/jni/graphics/Matrix.h
similarity index 100%
rename from suite/cts/deviceTests/opengl/jni/graphics/Matrix.h
rename to tests/openglperf2/jni/graphics/Matrix.h
diff --git a/suite/cts/deviceTests/opengl/jni/graphics/Mesh.cpp b/tests/openglperf2/jni/graphics/Mesh.cpp
similarity index 100%
rename from suite/cts/deviceTests/opengl/jni/graphics/Mesh.cpp
rename to tests/openglperf2/jni/graphics/Mesh.cpp
diff --git a/suite/cts/deviceTests/opengl/jni/graphics/Mesh.h b/tests/openglperf2/jni/graphics/Mesh.h
similarity index 100%
rename from suite/cts/deviceTests/opengl/jni/graphics/Mesh.h
rename to tests/openglperf2/jni/graphics/Mesh.h
diff --git a/suite/cts/deviceTests/opengl/jni/graphics/MeshNode.cpp b/tests/openglperf2/jni/graphics/MeshNode.cpp
similarity index 100%
rename from suite/cts/deviceTests/opengl/jni/graphics/MeshNode.cpp
rename to tests/openglperf2/jni/graphics/MeshNode.cpp
diff --git a/suite/cts/deviceTests/opengl/jni/graphics/MeshNode.h b/tests/openglperf2/jni/graphics/MeshNode.h
similarity index 100%
rename from suite/cts/deviceTests/opengl/jni/graphics/MeshNode.h
rename to tests/openglperf2/jni/graphics/MeshNode.h
diff --git a/suite/cts/deviceTests/opengl/jni/graphics/PerspectiveMeshNode.cpp b/tests/openglperf2/jni/graphics/PerspectiveMeshNode.cpp
similarity index 100%
rename from suite/cts/deviceTests/opengl/jni/graphics/PerspectiveMeshNode.cpp
rename to tests/openglperf2/jni/graphics/PerspectiveMeshNode.cpp
diff --git a/suite/cts/deviceTests/opengl/jni/graphics/PerspectiveMeshNode.h b/tests/openglperf2/jni/graphics/PerspectiveMeshNode.h
similarity index 100%
rename from suite/cts/deviceTests/opengl/jni/graphics/PerspectiveMeshNode.h
rename to tests/openglperf2/jni/graphics/PerspectiveMeshNode.h
diff --git a/suite/cts/deviceTests/opengl/jni/graphics/PerspectiveProgram.cpp b/tests/openglperf2/jni/graphics/PerspectiveProgram.cpp
similarity index 100%
rename from suite/cts/deviceTests/opengl/jni/graphics/PerspectiveProgram.cpp
rename to tests/openglperf2/jni/graphics/PerspectiveProgram.cpp
diff --git a/suite/cts/deviceTests/opengl/jni/graphics/PerspectiveProgram.h b/tests/openglperf2/jni/graphics/PerspectiveProgram.h
similarity index 100%
rename from suite/cts/deviceTests/opengl/jni/graphics/PerspectiveProgram.h
rename to tests/openglperf2/jni/graphics/PerspectiveProgram.h
diff --git a/suite/cts/deviceTests/opengl/jni/graphics/Program.cpp b/tests/openglperf2/jni/graphics/Program.cpp
similarity index 100%
rename from suite/cts/deviceTests/opengl/jni/graphics/Program.cpp
rename to tests/openglperf2/jni/graphics/Program.cpp
diff --git a/suite/cts/deviceTests/opengl/jni/graphics/Program.h b/tests/openglperf2/jni/graphics/Program.h
similarity index 100%
rename from suite/cts/deviceTests/opengl/jni/graphics/Program.h
rename to tests/openglperf2/jni/graphics/Program.h
diff --git a/suite/cts/deviceTests/opengl/jni/graphics/ProgramNode.cpp b/tests/openglperf2/jni/graphics/ProgramNode.cpp
similarity index 100%
rename from suite/cts/deviceTests/opengl/jni/graphics/ProgramNode.cpp
rename to tests/openglperf2/jni/graphics/ProgramNode.cpp
diff --git a/suite/cts/deviceTests/opengl/jni/graphics/ProgramNode.h b/tests/openglperf2/jni/graphics/ProgramNode.h
similarity index 100%
rename from suite/cts/deviceTests/opengl/jni/graphics/ProgramNode.h
rename to tests/openglperf2/jni/graphics/ProgramNode.h
diff --git a/tests/openglperf2/jni/graphics/Renderer.cpp b/tests/openglperf2/jni/graphics/Renderer.cpp
new file mode 100644
index 0000000..effd5aca
--- /dev/null
+++ b/tests/openglperf2/jni/graphics/Renderer.cpp
@@ -0,0 +1,294 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+#include "Renderer.h"
+#include <graphics/GLUtils.h>
+
+#define LOG_TAG "CTS_OPENGL"
+#define LOG_NDEBUG 0
+#include <android/log.h>
+
+#include <Trace.h>
+
+// Used to center the grid on the screen.
+#define CENTER_GRID(x) ((((x) * 2.0 + 1) - OFFSCREEN_GRID_SIZE) / OFFSCREEN_GRID_SIZE)
+// Leave a good error message if something fails.
+#define EGL_RESULT_CHECK(X) do { \
+                                   EGLint error = eglGetError(); \
+                                   if (!(X) || error != EGL_SUCCESS) { \
+                                       __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, \
+                                          "EGL error '%d' at %s:%d", error, __FILE__, __LINE__);\
+                                       return false; \
+                                    } \
+                            } while (0)
+
+static const int FBO_NUM_VERTICES = 6;
+
+static const float FBO_VERTICES[FBO_NUM_VERTICES * 3] = {
+        0.1f, 0.1f, -0.1f,
+        -0.1f, 0.1f, -0.1f,
+        -0.1f, -0.1f, -0.1f,
+        -0.1f, -0.1f, -0.1f,
+        0.1f, -0.1f, -0.1f,
+        0.1f, 0.1f, -0.1f };
+static const float FBO_TEX_COORDS[FBO_NUM_VERTICES * 2] = {
+        1.0f, 1.0f,
+        0.0f, 1.0f,
+        0.0f, 0.0f,
+        0.0f, 0.0f,
+        1.0f, 0.0f,
+        1.0f, 1.0f };
+
+static const char* FBO_VERTEX =
+        "attribute vec4 a_Position;"
+        "attribute vec2 a_TexCoord;"
+        "uniform float u_XOffset;"
+        "uniform float u_YOffset;"
+        "varying vec2 v_TexCoord;"
+        "void main() {"
+        "  v_TexCoord = a_TexCoord;"
+        "  gl_Position.x = a_Position.x + u_XOffset;"
+        "  gl_Position.y = a_Position.y + u_YOffset;"
+        "  gl_Position.zw = a_Position.zw;"
+        "}";
+
+static const char* FBO_FRAGMENT =
+        "precision mediump float;"
+        "uniform sampler2D u_Texture;"
+        "varying vec2 v_TexCoord;"
+        "void main() {"
+        "  gl_FragColor = texture2D(u_Texture, v_TexCoord);"
+        "}";
+
+static const EGLint contextAttribs[] = {
+        EGL_CONTEXT_CLIENT_VERSION, 2,
+        EGL_NONE };
+
+static const EGLint configAttribs[] = {
+        EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
+        EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+        EGL_RED_SIZE, 8,
+        EGL_GREEN_SIZE, 8,
+        EGL_BLUE_SIZE, 8,
+        EGL_ALPHA_SIZE, 8,
+        EGL_DEPTH_SIZE, 16,
+        EGL_STENCIL_SIZE, 8,
+        EGL_NONE };
+
+static const int FBO_SIZE = 128;
+
+Renderer::Renderer(EGLNativeWindowType window, bool offscreen) :
+        mOffscreen(offscreen), mEglDisplay(EGL_NO_DISPLAY), mEglSurface(EGL_NO_SURFACE),
+        mEglContext(EGL_NO_CONTEXT), mWindow(window)  {
+}
+
+bool Renderer::eglSetUp() {
+    SCOPED_TRACE();
+    mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+    EGL_RESULT_CHECK(mEglDisplay != EGL_NO_DISPLAY);
+
+    EGLint major;
+    EGLint minor;
+    EGL_RESULT_CHECK(eglInitialize(mEglDisplay, &major, &minor));
+
+    EGLint numConfigs = 0;
+    EGL_RESULT_CHECK(eglChooseConfig(mEglDisplay, configAttribs, &mGlConfig, 1, &numConfigs)
+                     && (numConfigs > 0));
+
+    mEglSurface = eglCreateWindowSurface(mEglDisplay, mGlConfig, mWindow, NULL);
+    EGL_RESULT_CHECK(mEglSurface != EGL_NO_SURFACE);
+
+    mEglContext = eglCreateContext(mEglDisplay, mGlConfig, EGL_NO_CONTEXT, contextAttribs);
+    EGL_RESULT_CHECK(mEglContext != EGL_NO_CONTEXT);
+
+    EGL_RESULT_CHECK(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext));
+    EGL_RESULT_CHECK(eglQuerySurface(mEglDisplay, mEglSurface, EGL_WIDTH, &mWidth));
+    EGL_RESULT_CHECK(eglQuerySurface(mEglDisplay, mEglSurface, EGL_HEIGHT, &mHeight));
+
+    return true;
+}
+
+void Renderer::eglTearDown() {
+    SCOPED_TRACE();
+    eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+
+    if (mEglContext != EGL_NO_CONTEXT) {
+        eglDestroyContext(mEglDisplay, mEglContext);
+        mEglContext = EGL_NO_CONTEXT;
+    }
+
+    if (mEglSurface != EGL_NO_SURFACE) {
+        mEglSurface = EGL_NO_SURFACE;
+    }
+
+    if (mEglDisplay != EGL_NO_DISPLAY) {
+        eglTerminate(mEglDisplay);
+        mEglDisplay = EGL_NO_DISPLAY;
+    }
+}
+
+bool Renderer::setUp(int /*workload*/) {
+    SCOPED_TRACE();
+
+    EGL_RESULT_CHECK(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext));
+
+    if (mOffscreen) {
+        mFboWidth = FBO_SIZE;
+        mFboHeight = FBO_SIZE;
+
+        glGenFramebuffers(1, &mFboId);
+        glBindFramebuffer(GL_FRAMEBUFFER, mFboId);
+
+        glGenRenderbuffers(1, &mFboDepthId);
+        glBindRenderbuffer(GL_RENDERBUFFER, mFboDepthId);
+        glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, mFboWidth, mFboHeight);
+        glBindRenderbuffer(GL_RENDERBUFFER, 0);
+        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
+                                  GL_RENDERBUFFER, mFboDepthId);
+
+        mFboTexId = GLUtils::genTexture(mFboWidth, mFboHeight, 0);
+        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mFboTexId, 0);
+
+        GLuint err = glGetError();
+        if (err != GL_NO_ERROR) {
+            __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "GLError %d", err);
+            return false;
+        }
+
+        GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+        if (status != GL_FRAMEBUFFER_COMPLETE) {
+           __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "Framebuffer not complete: %d", status);
+            return false;
+        }
+        // Create fbo program.
+        mFboProgId = GLUtils::createProgram(&FBO_VERTEX, &FBO_FRAGMENT);
+        if (mFboProgId == 0) {
+            return false;
+        }
+        // Bind attributes.
+        mFboTexUniformHandle = glGetUniformLocation(mFboProgId, "u_Texture");
+        mFboXOffsetUniformHandle = glGetUniformLocation(mFboProgId, "u_XOffset");
+        mFboYOffsetUniformHandle = glGetUniformLocation(mFboProgId, "u_YOffset");
+        mFboPositionHandle = glGetAttribLocation(mFboProgId, "a_Position");
+        mFboTexCoordHandle = glGetAttribLocation(mFboProgId, "a_TexCoord");
+    } else {
+        mFboWidth = 0;
+        mFboHeight = 0;
+        mFboId = 0;
+        mFboDepthId = 0;
+        mFboTexId = 0;
+    }
+
+    GLuint err = glGetError();
+    if (err != GL_NO_ERROR) {
+        __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "GLError %d in setUp", err);
+        return false;
+    }
+
+    return true;
+}
+
+bool Renderer::tearDown() {
+    SCOPED_TRACE();
+    if (mOffscreen) {
+        if (mFboId != 0) {
+            glDeleteFramebuffers(1, &mFboId);
+            mFboId = 0;
+        }
+        if (mFboDepthId != 0) {
+            glDeleteRenderbuffers(1, &mFboDepthId);
+            mFboDepthId = 0;
+        }
+        if (mFboTexId != 0) {
+            glDeleteTextures(1, &mFboTexId);
+            mFboTexId = 0;
+        }
+    }
+    GLuint err = glGetError();
+    if (err != GL_NO_ERROR) {
+        __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "GLError %d in tearDown", err);
+        return false;
+    }
+
+    return true;
+}
+
+bool Renderer::draw() {
+    SCOPED_TRACE();
+
+    EGL_RESULT_CHECK(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext));
+
+    glBindFramebuffer(GL_FRAMEBUFFER, 0);
+    glViewport(0, 0, mWidth, mHeight);
+
+    if (mOffscreen) {
+        // Set the background clear color to black.
+        glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+        glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
+        for (int i = 0; i < OFFSCREEN_INNER_FRAMES; i++) {
+            // Switch to FBO and re-attach.
+            glBindFramebuffer(GL_FRAMEBUFFER, mFboId);
+            glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
+                                    GL_RENDERBUFFER, mFboDepthId);
+            glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+                                 GL_TEXTURE_2D, mFboTexId, 0);
+            glViewport(0, 0, mFboWidth, mFboHeight);
+
+            // Render workload.
+            drawWorkload();
+            glFlush();
+
+            // Switch back to display.
+            glBindFramebuffer(GL_FRAMEBUFFER, 0);
+            glViewport(0, 0, mWidth, mHeight);
+
+            // No culling of back faces
+            glDisable (GL_CULL_FACE);
+            // No depth testing
+            glDisable (GL_DEPTH_TEST);
+            // No blending
+            glDisable (GL_BLEND);
+
+            glUseProgram(mFboProgId);
+
+            // Set the texture.
+            glActiveTexture (GL_TEXTURE0);
+            glBindTexture(GL_TEXTURE_2D, mFboTexId);
+            glUniform1i(mFboTexUniformHandle, 0);
+
+            // Set the offsets
+            glUniform1f(mFboXOffsetUniformHandle, CENTER_GRID(i / OFFSCREEN_GRID_SIZE));
+            glUniform1f(mFboYOffsetUniformHandle, CENTER_GRID(i % OFFSCREEN_GRID_SIZE));
+
+            glEnableVertexAttribArray(mFboPositionHandle);
+            glEnableVertexAttribArray(mFboTexCoordHandle);
+            glVertexAttribPointer(mFboPositionHandle, 3, GL_FLOAT, false, 0, FBO_VERTICES);
+            glVertexAttribPointer(mFboTexCoordHandle, 2, GL_FLOAT, false, 0, FBO_TEX_COORDS);
+
+            // Render FBO to display.
+            glDrawArrays(GL_TRIANGLES, 0, FBO_NUM_VERTICES);
+        }
+    } else {
+        // Render workload.
+        drawWorkload();
+    }
+
+    GLuint err = glGetError();
+    if (err != GL_NO_ERROR) {
+        __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "GLError %d in draw", err);
+        return false;
+    }
+
+    EGL_RESULT_CHECK(eglSwapBuffers(mEglDisplay, mEglSurface)); 
+    return true;
+}
diff --git a/suite/cts/deviceTests/opengl/jni/graphics/Renderer.h b/tests/openglperf2/jni/graphics/Renderer.h
similarity index 100%
rename from suite/cts/deviceTests/opengl/jni/graphics/Renderer.h
rename to tests/openglperf2/jni/graphics/Renderer.h
diff --git a/tests/openglperf2/jni/graphics/SceneGraphNode.cpp b/tests/openglperf2/jni/graphics/SceneGraphNode.cpp
new file mode 100644
index 0000000..5581e95
--- /dev/null
+++ b/tests/openglperf2/jni/graphics/SceneGraphNode.cpp
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+#include "SceneGraphNode.h"
+
+SceneGraphNode::~SceneGraphNode() {
+    for (size_t i = 0; i < mChildren.size(); i++) {
+        delete mChildren[i];
+    }
+}
+
+void SceneGraphNode::addChild(SceneGraphNode* child) {
+    mChildren.push_back(child);
+}
+
+void SceneGraphNode::draw(Program& program, Matrix& model, Matrix& view, Matrix& projection) {
+    before(program, model, view, projection);
+    for (size_t i = 0; i < mChildren.size(); i++) {
+        mChildren[i]->draw(program, model, view, projection);
+    }
+    after(program, model, view, projection);
+}
diff --git a/tests/openglperf2/jni/graphics/SceneGraphNode.h b/tests/openglperf2/jni/graphics/SceneGraphNode.h
new file mode 100644
index 0000000..41f5a6d
--- /dev/null
+++ b/tests/openglperf2/jni/graphics/SceneGraphNode.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+#ifndef SCENEGRAPHNODE_H
+#define SCENEGRAPHNODE_H
+
+#include <vector>
+#include "Matrix.h"
+#include "Program.h"
+
+class SceneGraphNode {
+public:
+    SceneGraphNode() {};
+    virtual ~SceneGraphNode();
+    void addChild(SceneGraphNode* child);
+protected:
+    virtual void before(Program& program, Matrix& model, Matrix& view, Matrix& projection) = 0;
+    virtual void after(Program& program, Matrix& model, Matrix& view, Matrix& projection) = 0;
+    void draw(Program& program, Matrix& model, Matrix& view, Matrix& projection);
+private:
+    std::vector<SceneGraphNode*> mChildren;
+};
+
+#endif
diff --git a/suite/cts/deviceTests/opengl/jni/graphics/TexturedMeshNode.cpp b/tests/openglperf2/jni/graphics/TexturedMeshNode.cpp
similarity index 100%
rename from suite/cts/deviceTests/opengl/jni/graphics/TexturedMeshNode.cpp
rename to tests/openglperf2/jni/graphics/TexturedMeshNode.cpp
diff --git a/suite/cts/deviceTests/opengl/jni/graphics/TexturedMeshNode.h b/tests/openglperf2/jni/graphics/TexturedMeshNode.h
similarity index 100%
rename from suite/cts/deviceTests/opengl/jni/graphics/TexturedMeshNode.h
rename to tests/openglperf2/jni/graphics/TexturedMeshNode.h
diff --git a/suite/cts/deviceTests/opengl/jni/graphics/TransformationNode.cpp b/tests/openglperf2/jni/graphics/TransformationNode.cpp
similarity index 100%
rename from suite/cts/deviceTests/opengl/jni/graphics/TransformationNode.cpp
rename to tests/openglperf2/jni/graphics/TransformationNode.cpp
diff --git a/suite/cts/deviceTests/opengl/jni/graphics/TransformationNode.h b/tests/openglperf2/jni/graphics/TransformationNode.h
similarity index 100%
rename from suite/cts/deviceTests/opengl/jni/graphics/TransformationNode.h
rename to tests/openglperf2/jni/graphics/TransformationNode.h
diff --git a/suite/cts/deviceTests/opengl/jni/graphics/Vector2D.cpp b/tests/openglperf2/jni/graphics/Vector2D.cpp
similarity index 100%
rename from suite/cts/deviceTests/opengl/jni/graphics/Vector2D.cpp
rename to tests/openglperf2/jni/graphics/Vector2D.cpp
diff --git a/suite/cts/deviceTests/opengl/jni/graphics/Vector2D.h b/tests/openglperf2/jni/graphics/Vector2D.h
similarity index 100%
rename from suite/cts/deviceTests/opengl/jni/graphics/Vector2D.h
rename to tests/openglperf2/jni/graphics/Vector2D.h
diff --git a/tests/openglperf2/jni/primitive/GLPrimitive.cpp b/tests/openglperf2/jni/primitive/GLPrimitive.cpp
new file mode 100644
index 0000000..8cf2a3f
--- /dev/null
+++ b/tests/openglperf2/jni/primitive/GLPrimitive.cpp
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+#include <jni.h>
+
+#include <stdlib.h>
+#include <android/log.h>
+
+#include <android/native_window.h>
+#include <android/native_window_jni.h>
+
+#include <graphics/GLUtils.h>
+#include <graphics/Renderer.h>
+
+#include "fullpipeline/FullPipelineRenderer.h"
+#include "pixeloutput/PixelOutputRenderer.h"
+#include "shaderperf/ShaderPerfRenderer.h"
+#include "contextswitch/ContextSwitchRenderer.h"
+
+// Holds the current benchmark's renderer.
+Renderer* gRenderer = NULL;
+ANativeWindow* gNativeWindow = NULL;
+
+enum {
+    FULL_PIPELINE_BENCHMARK = 0,
+    PIXEL_OUTPUT_BENCHMARK = 1,
+    SHADER_PERF_BENCHMARK = 2,
+    CONTEXT_SWITCH_BENCHMARK = 3
+};
+
+extern "C" JNIEXPORT jboolean JNICALL
+Java_android_opengl2_cts_primitive_GLPrimitiveActivity_startBenchmark(
+        JNIEnv* env, jclass /*clazz*/, jint workload, jint numFrames, jdoubleArray frameTimes) {
+    if (gRenderer == NULL) {
+        return false;
+    }
+
+    // Sets up the renderer.
+    bool success = gRenderer->setUp(workload);
+
+    // Records the start time.
+    double start = GLUtils::currentTimeMillis();
+
+    // Offscreen renders 100 tiles per frame so reduce the number of frames to render.
+    if (gRenderer->mOffscreen) {
+        numFrames /= Renderer::OFFSCREEN_INNER_FRAMES;
+    }
+
+    // Draw off the screen.
+    for (int i = 0; i < numFrames && success; i++) {
+        // Draw a frame.
+        success = gRenderer->draw();
+    }
+
+    // Records the end time.
+    double end = GLUtils::currentTimeMillis();
+
+    // Sets the times in the Java array.
+    double times[] = {start, end};
+    env->SetDoubleArrayRegion(frameTimes, 0, 2, times);
+
+    success = gRenderer->tearDown() && success;
+    return success;
+}
+
+// The following functions create the renderers for the various benchmarks.
+extern "C" JNIEXPORT void JNICALL
+Java_android_opengl2_cts_primitive_GLPrimitiveActivity_setupBenchmark(
+        JNIEnv* env, jclass /*clazz*/, jobject surface, jint benchmark,
+        jboolean offscreen) {
+    gNativeWindow = ANativeWindow_fromSurface(env, surface);
+    switch (benchmark) {
+        case FULL_PIPELINE_BENCHMARK:
+            gRenderer = new FullPipelineRenderer(gNativeWindow, offscreen);
+            break;
+        case PIXEL_OUTPUT_BENCHMARK:
+            gRenderer = new PixelOutputRenderer(gNativeWindow, offscreen);
+            break;
+        case SHADER_PERF_BENCHMARK:
+            gRenderer = new ShaderPerfRenderer(gNativeWindow, offscreen);
+            break;
+        case CONTEXT_SWITCH_BENCHMARK:
+            gRenderer = new ContextSwitchRenderer(gNativeWindow, offscreen);
+            break;
+        default:
+            __android_log_print(ANDROID_LOG_ERROR, "GLPrimitive",
+                    "Unknown benchmark '%d'", benchmark);
+            ANativeWindow_release(gNativeWindow);
+            gNativeWindow = NULL;
+            return;
+    }
+
+    // Set up call will log error conditions
+    if (!gRenderer->eglSetUp()) {
+        delete gRenderer;
+        gRenderer = NULL;
+
+        ANativeWindow_release(gNativeWindow);
+        gNativeWindow = NULL;
+    }
+}
+
+extern "C" JNIEXPORT void JNICALL
+Java_android_opengl2_cts_primitive_GLPrimitiveActivity_tearDownBenchmark(
+        JNIEnv* /*env*/, jclass /*clazz*/) {
+    if (gRenderer == NULL) {
+        return;
+    }
+    gRenderer->eglTearDown();
+    delete gRenderer;
+    gRenderer = NULL;
+
+    ANativeWindow_release(gNativeWindow);
+    gNativeWindow = NULL;
+}
diff --git a/tests/openglperf2/jni/primitive/contextswitch/ContextSwitchRenderer.cpp b/tests/openglperf2/jni/primitive/contextswitch/ContextSwitchRenderer.cpp
new file mode 100644
index 0000000..5e9b414
--- /dev/null
+++ b/tests/openglperf2/jni/primitive/contextswitch/ContextSwitchRenderer.cpp
@@ -0,0 +1,239 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+#include <android/native_window.h>
+
+#include <stdlib.h>
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+#include "ContextSwitchRenderer.h"
+#include <graphics/GLUtils.h>
+
+#define LOG_TAG "CTS_OPENGL"
+#define LOG_NDEBUG 0
+#include <android/log.h>
+#include <Trace.h>
+
+static const EGLint contextAttribs[] = {
+        EGL_CONTEXT_CLIENT_VERSION, 2,
+        EGL_NONE };
+
+static const int NUM_WORKER_CONTEXTS = 7;
+
+static const int CS_TEXTURE_SIZE = 64;
+
+static const int CS_NUM_VERTICES = 6;
+
+static const float CS_VERTICES[CS_NUM_VERTICES * 3] = {
+        0.1f, 0.1f, -0.1f,
+        -0.1f, 0.1f, -0.1f,
+        -0.1f, -0.1f, -0.1f,
+        -0.1f, -0.1f, -0.1f,
+        0.1f, -0.1f, -0.1f,
+        0.1f, 0.1f, -0.1f };
+
+static const float CS_TEX_COORDS[CS_NUM_VERTICES * 2] = {
+        1.0f, 1.0f,
+        0.0f, 1.0f,
+        0.0f, 0.0f,
+        0.0f, 0.0f,
+        1.0f, 0.0f,
+        1.0f, 1.0f };
+
+static const char* CS_VERTEX =
+        "attribute vec4 a_Position;"
+        "attribute vec2 a_TexCoord;"
+        "uniform float u_Translate;"
+        "varying vec2 v_TexCoord;"
+        "void main() {"
+        "  v_TexCoord = a_TexCoord;"
+        "  gl_Position.x = a_Position.x + u_Translate;"
+        "  gl_Position.yzw = a_Position.yzw;"
+        "}";
+
+static const char* CS_FRAGMENT =
+        "precision mediump float;"
+        "uniform sampler2D u_Texture;"
+        "varying vec2 v_TexCoord;"
+        "void main() {"
+        "  gl_FragColor = texture2D(u_Texture, v_TexCoord);"
+        "}";
+
+ContextSwitchRenderer::ContextSwitchRenderer(ANativeWindow* window, bool offscreen) :
+        Renderer(window, offscreen), mContexts(NULL), mWorkload(0) {
+}
+
+bool ContextSwitchRenderer::setUp(int workload) {
+    SCOPED_TRACE();
+    mWorkload = workload;
+    if (!Renderer::setUp(workload)) {
+        return false;
+    }
+
+    // Setup texture.
+    mTextureId = GLUtils::genTexture(CS_TEXTURE_SIZE, CS_TEXTURE_SIZE, GLUtils::RANDOM_FILL);
+    if (mTextureId == 0) {
+        return false;
+    }
+
+    // Create program.
+    mProgramId = GLUtils::createProgram(&CS_VERTEX, &CS_FRAGMENT);
+    if (mProgramId == 0) {
+        return false;
+    }
+    // Bind attributes.
+    mTextureUniformHandle = glGetUniformLocation(mProgramId, "u_Texture");
+    mTranslateUniformHandle = glGetUniformLocation(mProgramId, "u_Translate");
+    mPositionHandle = glGetAttribLocation(mProgramId, "a_Position");
+    mTexCoordHandle = glGetAttribLocation(mProgramId, "a_TexCoord");
+
+    mContexts = new EGLContext[NUM_WORKER_CONTEXTS];
+    mFboIds = new GLuint[NUM_WORKER_CONTEXTS];
+    for (int i = 0; i < NUM_WORKER_CONTEXTS; i++) {
+        // Create the contexts, they share data with the main one.
+        mContexts[i] = eglCreateContext(mEglDisplay, mGlConfig, mEglContext, contextAttribs);
+        if (EGL_NO_CONTEXT == mContexts[i] || EGL_SUCCESS != eglGetError()) {
+            return false;
+        }
+
+        if (!eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mContexts[i])
+                || EGL_SUCCESS != eglGetError()) {
+            return false;
+        }
+        if (mOffscreen) {
+            // FBOs are not shared across contexts, textures and renderbuffers are though.
+            glGenFramebuffers(1, &mFboIds[i]);
+            glBindFramebuffer(GL_FRAMEBUFFER, mFboIds[i]);
+
+            glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
+                                      GL_RENDERBUFFER, mFboDepthId);
+
+            glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+                                   GL_TEXTURE_2D, mFboTexId, 0);
+            GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+            if (status != GL_FRAMEBUFFER_COMPLETE) {
+                __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "Framebuffer not complete: %d", status);
+                return false;
+            }
+        }
+    }
+    return true;
+}
+
+bool ContextSwitchRenderer::tearDown() {
+    SCOPED_TRACE();
+    if (mContexts) {
+        // Destroy the contexts, the main one will be handled by Renderer::eglTearDown().
+        for (int i = 0; i < NUM_WORKER_CONTEXTS; i++) {
+            if (mOffscreen) {
+                if (mFboIds[i] != 0) {
+                    eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mContexts[i]);
+                    glDeleteFramebuffers(1, &mFboIds[i]);
+                    mFboIds[i] = 0;
+                }
+            }
+            eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+            eglDestroyContext(mEglDisplay, mContexts[i]);
+        }
+        delete[] mContexts;
+    }
+    eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext);
+    if (mTextureId != 0) {
+        glDeleteTextures(1, &mTextureId);
+        mTextureId = 0;
+    }
+    if (!Renderer::tearDown()) {
+        return false;
+    }
+    return true;
+}
+
+void ContextSwitchRenderer::drawWorkload() {
+    SCOPED_TRACE();
+
+    if (mWorkload > 8) {
+        return; // This test does not support higher workloads.
+    }
+
+    // Set the background clear color to black.
+    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
+    // No culling of back faces
+    glDisable(GL_CULL_FACE);
+    // No depth testing
+    glDisable(GL_DEPTH_TEST);
+
+    EGLSyncKHR fence = eglCreateSyncKHR(mEglDisplay, EGL_SYNC_FENCE_KHR, NULL);
+
+    const int TOTAL_NUM_CONTEXTS = NUM_WORKER_CONTEXTS + 1;
+    const float TRANSLATION = 0.9f - (TOTAL_NUM_CONTEXTS * 0.2f);
+    for (int i = 0; i < TOTAL_NUM_CONTEXTS; i++) {
+        eglWaitSyncKHR(mEglDisplay, fence, 0);
+        eglDestroySyncKHR(mEglDisplay, fence);
+        glUseProgram(mProgramId);
+
+        // Set the texture.
+        glActiveTexture (GL_TEXTURE0);
+        glBindTexture(GL_TEXTURE_2D, mTextureId);
+        glUniform1i(mTextureUniformHandle, 0);
+
+        // Set the x translate.
+        glUniform1f(mTranslateUniformHandle, (i * 0.2f) + TRANSLATION);
+
+        glEnableVertexAttribArray(mPositionHandle);
+        glEnableVertexAttribArray(mTexCoordHandle);
+        glVertexAttribPointer(mPositionHandle, 3, GL_FLOAT, false, 0, CS_VERTICES);
+        glVertexAttribPointer(mTexCoordHandle, 2, GL_FLOAT, false, 0, CS_TEX_COORDS);
+
+        glDrawArrays(GL_TRIANGLES, 0, CS_NUM_VERTICES);
+        fence = eglCreateSyncKHR(mEglDisplay, EGL_SYNC_FENCE_KHR, NULL);
+
+        // Switch to next context.
+        if (i < (mWorkload - 1)) {
+            eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mContexts[i]);
+            // Switch to FBO and re-attach.
+            if (mOffscreen) {
+                glBindFramebuffer(GL_FRAMEBUFFER, mFboIds[i]);
+                glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
+                                        GL_RENDERBUFFER, mFboDepthId);
+                glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+                                     GL_TEXTURE_2D, mFboTexId, 0);
+                glViewport(0, 0, mFboWidth, mFboHeight);
+            }
+        }
+        GLuint err = glGetError();
+        if (err != GL_NO_ERROR) {
+            __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "GLError %d in drawWorkload", err);
+            break;
+        }
+    }
+
+    eglWaitSyncKHR(mEglDisplay, fence, 0);
+    eglDestroySyncKHR(mEglDisplay, fence);
+
+    // Switch back to the main context.
+    eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext);
+    if (mOffscreen) {
+        glBindFramebuffer(GL_FRAMEBUFFER, mFboId);
+        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
+                                GL_RENDERBUFFER, mFboDepthId);
+        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+                             GL_TEXTURE_2D, mFboTexId, 0);
+        glViewport(0, 0, mFboWidth, mFboHeight);
+    }
+}
diff --git a/suite/cts/deviceTests/opengl/jni/primitive/contextswitch/ContextSwitchRenderer.h b/tests/openglperf2/jni/primitive/contextswitch/ContextSwitchRenderer.h
similarity index 100%
rename from suite/cts/deviceTests/opengl/jni/primitive/contextswitch/ContextSwitchRenderer.h
rename to tests/openglperf2/jni/primitive/contextswitch/ContextSwitchRenderer.h
diff --git a/suite/cts/deviceTests/opengl/jni/primitive/fullpipeline/FullPipelineRenderer.cpp b/tests/openglperf2/jni/primitive/fullpipeline/FullPipelineRenderer.cpp
similarity index 100%
rename from suite/cts/deviceTests/opengl/jni/primitive/fullpipeline/FullPipelineRenderer.cpp
rename to tests/openglperf2/jni/primitive/fullpipeline/FullPipelineRenderer.cpp
diff --git a/suite/cts/deviceTests/opengl/jni/primitive/fullpipeline/FullPipelineRenderer.h b/tests/openglperf2/jni/primitive/fullpipeline/FullPipelineRenderer.h
similarity index 100%
rename from suite/cts/deviceTests/opengl/jni/primitive/fullpipeline/FullPipelineRenderer.h
rename to tests/openglperf2/jni/primitive/fullpipeline/FullPipelineRenderer.h
diff --git a/suite/cts/deviceTests/opengl/jni/primitive/pixeloutput/PixelOutputRenderer.cpp b/tests/openglperf2/jni/primitive/pixeloutput/PixelOutputRenderer.cpp
similarity index 100%
rename from suite/cts/deviceTests/opengl/jni/primitive/pixeloutput/PixelOutputRenderer.cpp
rename to tests/openglperf2/jni/primitive/pixeloutput/PixelOutputRenderer.cpp
diff --git a/suite/cts/deviceTests/opengl/jni/primitive/pixeloutput/PixelOutputRenderer.h b/tests/openglperf2/jni/primitive/pixeloutput/PixelOutputRenderer.h
similarity index 100%
rename from suite/cts/deviceTests/opengl/jni/primitive/pixeloutput/PixelOutputRenderer.h
rename to tests/openglperf2/jni/primitive/pixeloutput/PixelOutputRenderer.h
diff --git a/suite/cts/deviceTests/opengl/jni/primitive/shaderperf/ShaderPerfRenderer.cpp b/tests/openglperf2/jni/primitive/shaderperf/ShaderPerfRenderer.cpp
similarity index 100%
rename from suite/cts/deviceTests/opengl/jni/primitive/shaderperf/ShaderPerfRenderer.cpp
rename to tests/openglperf2/jni/primitive/shaderperf/ShaderPerfRenderer.cpp
diff --git a/suite/cts/deviceTests/opengl/jni/primitive/shaderperf/ShaderPerfRenderer.h b/tests/openglperf2/jni/primitive/shaderperf/ShaderPerfRenderer.h
similarity index 100%
rename from suite/cts/deviceTests/opengl/jni/primitive/shaderperf/ShaderPerfRenderer.h
rename to tests/openglperf2/jni/primitive/shaderperf/ShaderPerfRenderer.h
diff --git a/tests/openglperf2/jni/reference/GLReference.cpp b/tests/openglperf2/jni/reference/GLReference.cpp
new file mode 100644
index 0000000..9af018a
--- /dev/null
+++ b/tests/openglperf2/jni/reference/GLReference.cpp
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+#include <jni.h>
+
+#include <android/native_window.h>
+#include <android/native_window_jni.h>
+
+#include <graphics/GLUtils.h>
+#include <graphics/Renderer.h>
+
+#include "ReferenceRenderer.h"
+
+extern "C" JNIEXPORT jboolean JNICALL
+Java_android_opengl2_cts_reference_GLGameActivity_startBenchmark(
+    JNIEnv* env, jclass /*clazz*/, jobject assetManager, jobject surface, jint numFrames,
+        jdoubleArray setUpTimes, jdoubleArray updateTimes, jdoubleArray renderTimes) {
+
+    GLUtils::setEnvAndAssetManager(env, assetManager);
+
+    if (numFrames > (ReferenceRenderer::FRAMES_PER_SCENE * ReferenceRenderer::NUM_SCENES)) {
+        return false;
+    }
+
+    ANativeWindow* nativeWindow = ANativeWindow_fromSurface(env, surface);
+    ReferenceRenderer* renderer = new ReferenceRenderer(nativeWindow);
+    bool success = renderer->eglSetUp();
+    success = renderer->setUp(0) && success;
+    env->SetDoubleArrayRegion(
+            setUpTimes, 0, ReferenceRenderer::NUM_SETUP_TIMES, renderer->mSetUpTimes);
+
+    double updates[numFrames];
+    double renders[numFrames];
+    for (int i = 0; i < numFrames && success; i++) {
+        double t0 = GLUtils::currentTimeMillis();
+        success = renderer->update(i);
+        double t1 = GLUtils::currentTimeMillis();
+        success = success && renderer->draw();
+        double t2 = GLUtils::currentTimeMillis();
+        updates[i] = t1 - t0;
+        renders[i] = t2 - t1;
+    }
+
+    env->SetDoubleArrayRegion(updateTimes, 0, numFrames, updates);
+    env->SetDoubleArrayRegion(renderTimes, 0, numFrames, renders);
+
+    success = renderer->tearDown() && success;
+    renderer->eglTearDown();
+    delete renderer;
+    renderer = NULL;
+
+    ANativeWindow_release(nativeWindow);
+
+    return success;
+}
diff --git a/tests/openglperf2/jni/reference/ReferenceRenderer.cpp b/tests/openglperf2/jni/reference/ReferenceRenderer.cpp
new file mode 100644
index 0000000..7e629a8
--- /dev/null
+++ b/tests/openglperf2/jni/reference/ReferenceRenderer.cpp
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+#include "ReferenceRenderer.h"
+
+#include "scene/flocking/FlockingScene.h"
+#include "scene/glowing/GlowingScene.h"
+
+#include <graphics/GLUtils.h>
+#include <graphics/ProgramNode.h>
+
+#include <android/log.h>
+#include <Trace.h>
+
+ReferenceRenderer::ReferenceRenderer(ANativeWindow* window) :
+        Renderer(window, false) {
+}
+
+bool ReferenceRenderer::setUp(int workload) {
+    SCOPED_TRACE();
+    // Reset the times.
+    for (int i = 0; i < NUM_SETUP_TIMES; i++) {
+        mSetUpTimes[i] = 0;
+    }
+    // Set up OpenGLES.
+    double start = GLUtils::currentTimeMillis();
+    if (!Renderer::setUp(workload)) {
+        return false;
+    }
+    mSetUpTimes[0] = GLUtils::currentTimeMillis() - start;
+
+    // Create the scenes.
+    mScenes[0] = new FlockingScene(mWidth, mHeight);
+    mScenes[1] = new GlowingScene(mWidth, mHeight);
+    // TODO add more scenes to do a comprehensive test.
+
+    // Set up the scenes.
+    double times[NUM_SETUP_TIMES];
+    for (int i = 0; i < NUM_SCENES; i++) {
+        times[0] = GLUtils::currentTimeMillis();
+        mScenes[i]->setUpContext();
+        times[1] = GLUtils::currentTimeMillis();
+        mScenes[i]->setUpTextures();
+        times[2] = GLUtils::currentTimeMillis();
+        mScenes[i]->setUpMeshes();
+        times[3] = GLUtils::currentTimeMillis();
+
+        for (int i = 1; i < NUM_SETUP_TIMES; i++) {
+            // Add on the set up times.
+            mSetUpTimes[i] += times[i] - times[i - 1];
+        }
+    }
+    return true;
+}
+
+bool ReferenceRenderer::tearDown() {
+    SCOPED_TRACE();
+    for (int i = 0; i < NUM_SCENES; i++) {
+        mScenes[i]->tearDown();
+        delete mScenes[i];
+    }
+    mCurrentScene = NULL;
+    if (!Renderer::tearDown()) {
+        return false;
+    }
+    return true;
+}
+
+bool ReferenceRenderer::update(int frame) {
+    SCOPED_TRACE();
+    int sceneId = frame / ReferenceRenderer::FRAMES_PER_SCENE;
+    int localFrame = frame % ReferenceRenderer::FRAMES_PER_SCENE;
+    mCurrentScene = mScenes[sceneId];
+    mCurrentScene->update(localFrame);
+    return true;
+}
+
+void ReferenceRenderer::drawWorkload() {
+    SCOPED_TRACE();
+    // Set the background clear color to black.
+    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+    // Use culling to remove back faces.
+    glEnable (GL_CULL_FACE);
+    // Use depth testing.
+    glEnable (GL_DEPTH_TEST);
+
+    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
+    if (!mCurrentScene->draw()) {
+        __android_log_print(ANDROID_LOG_ERROR, "ReferenceRenderer", "Error when rendering scene");
+    }
+}
diff --git a/suite/cts/deviceTests/opengl/jni/reference/ReferenceRenderer.h b/tests/openglperf2/jni/reference/ReferenceRenderer.h
similarity index 100%
rename from suite/cts/deviceTests/opengl/jni/reference/ReferenceRenderer.h
rename to tests/openglperf2/jni/reference/ReferenceRenderer.h
diff --git a/suite/cts/deviceTests/opengl/jni/reference/scene/Scene.cpp b/tests/openglperf2/jni/reference/scene/Scene.cpp
similarity index 100%
rename from suite/cts/deviceTests/opengl/jni/reference/scene/Scene.cpp
rename to tests/openglperf2/jni/reference/scene/Scene.cpp
diff --git a/tests/openglperf2/jni/reference/scene/Scene.h b/tests/openglperf2/jni/reference/scene/Scene.h
new file mode 100644
index 0000000..01a2c0c
--- /dev/null
+++ b/tests/openglperf2/jni/reference/scene/Scene.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+#ifndef SCENE_H
+#define SCENE_H
+
+#include <graphics/Matrix.h>
+#include <graphics/Mesh.h>
+#include <graphics/Program.h>
+#include <graphics/ProgramNode.h>
+
+#include <vector>
+
+class Scene {
+public:
+    Scene(int width, int height);
+    virtual ~Scene() {};
+    virtual bool setUpContext();
+    virtual bool setUpTextures() = 0;
+    virtual bool setUpMeshes() = 0;
+    virtual bool tearDown();
+    virtual bool update(int frame);
+    virtual bool draw() = 0;
+    void drawSceneGraph(int index);
+protected:
+    virtual bool setUpPrograms() = 0;
+    virtual Matrix* setUpModelMatrix() = 0;
+    virtual Matrix* setUpViewMatrix() = 0;
+    virtual Matrix* setUpProjectionMatrix(float width, float height) = 0;
+    virtual bool updateSceneGraphs(int frame) = 0;
+    int mWidth;
+    int mHeight;
+    std::vector<Mesh*> mMeshes;
+    std::vector<GLuint> mTextureIds;
+    std::vector<ProgramNode*> mSceneGraphs;
+private:
+    Matrix* mModelMatrix;
+    Matrix* mViewMatrix;
+    Matrix* mProjectionMatrix;
+};
+#endif
diff --git a/suite/cts/deviceTests/opengl/jni/reference/scene/flocking/Boid.cpp b/tests/openglperf2/jni/reference/scene/flocking/Boid.cpp
similarity index 100%
rename from suite/cts/deviceTests/opengl/jni/reference/scene/flocking/Boid.cpp
rename to tests/openglperf2/jni/reference/scene/flocking/Boid.cpp
diff --git a/tests/openglperf2/jni/reference/scene/flocking/Boid.h b/tests/openglperf2/jni/reference/scene/flocking/Boid.h
new file mode 100644
index 0000000..994126e
--- /dev/null
+++ b/tests/openglperf2/jni/reference/scene/flocking/Boid.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+// An implementation of Craig Reynold's Boid Simulation.
+#ifndef BOID_H
+#define BOID_H
+
+#include <graphics/Vector2D.h>
+
+class Boid {
+public:
+    Boid(float x, float y);
+    void resetAcceleration();
+    void flock(const Boid* boids[], int numBoids, int index, float limitX, float limitY);
+    // The following floats are the parameters for the flocking algorithm, changing these
+    // modifies the boid's behaviour.
+    static const constexpr float MAX_SPEED = 2.0f;// Upper limit of boid velocity.
+    static const constexpr float MAX_FORCE = 0.05f;// Upper limit of the force used to push a boid.
+    static const constexpr float NEIGHBOUR_RADIUS = 70.0f;// Radius used to find neighbours, was 50.
+    static const constexpr float DESIRED_BOID_DIST = 35.0f;// Distance boids want to be from others, was 25.
+    // The weightings of the components.
+    static const constexpr float SEPARATION_WEIGHT = 2.0f;
+    static const constexpr float ALIGNMENT_WEIGHT = 1.0f;
+    static const constexpr float COHESION_WEIGHT = 1.0f;
+    Vector2D mPosition;
+    Vector2D mVelocity;
+    Vector2D mAcceleration;
+};
+#endif
diff --git a/tests/openglperf2/jni/reference/scene/flocking/FlockingScene.cpp b/tests/openglperf2/jni/reference/scene/flocking/FlockingScene.cpp
new file mode 100644
index 0000000..241a6fe
--- /dev/null
+++ b/tests/openglperf2/jni/reference/scene/flocking/FlockingScene.cpp
@@ -0,0 +1,193 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+#include "FlockingScene.h"
+
+#include "WaterMeshNode.h"
+
+#include <cstdlib>
+#include <cmath>
+
+#include <Trace.h>
+
+#include <graphics/PerspectiveMeshNode.h>
+#include <graphics/PerspectiveProgram.h>
+#include <graphics/GLUtils.h>
+#include <graphics/Matrix.h>
+#include <graphics/Mesh.h>
+#include <graphics/ProgramNode.h>
+#include <graphics/TransformationNode.h>
+
+FlockingScene::FlockingScene(int width, int height) :
+        Scene(width, height), mMainProgram(NULL), mWaterProgram(NULL) {
+    for (int i = 0; i < NUM_BOIDS; i++) {
+        // Generate a boid with a random position. (-50, 50)
+        float x = (rand() % 101) - 50.0f;
+        float y = (rand() % 101) - 50.0f;
+        mBoids[i] = new Boid(x, y);
+    }
+}
+
+bool FlockingScene::setUpPrograms() {
+    // Main Program
+    const char* vertex = GLUtils::openTextFile("vertex/perspective");
+    const char* fragment = GLUtils::openTextFile("fragment/perspective");
+    if (vertex == NULL || fragment == NULL) {
+        return false;
+    }
+    GLuint programId = GLUtils::createProgram(&vertex, &fragment);
+    delete[] vertex;
+    delete[] fragment;
+    if (programId == 0) {
+        return false;
+    }
+    mMainProgram = new PerspectiveProgram(programId);
+    // Water Program
+    vertex = GLUtils::openTextFile("vertex/water");
+    fragment = GLUtils::openTextFile("fragment/water");
+    if (vertex == NULL || fragment == NULL) {
+        return false;
+    }
+    programId = GLUtils::createProgram(&vertex, &fragment);
+    delete[] vertex;
+    delete[] fragment;
+    if (programId == 0) {
+        return false;
+    }
+    mWaterProgram = new PerspectiveProgram(programId);
+    return true;
+}
+
+Matrix* FlockingScene::setUpModelMatrix() {
+    return new Matrix();
+}
+
+Matrix* FlockingScene::setUpViewMatrix() {
+    // Position the eye in front of the origin.
+    float eyeX = 0.0f;
+    float eyeY = 0.0f;
+    float eyeZ = 10.0f;
+
+    // We are looking at the origin
+    float centerX = 0.0f;
+    float centerY = 0.0f;
+    float centerZ = 0.0f;
+
+    // Set our up vector.
+    float upX = 0.0f;
+    float upY = 1.0f;
+    float upZ = 0.0f;
+
+    // Set the view matrix.
+    return Matrix::newLookAt(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ);
+}
+
+Matrix* FlockingScene::setUpProjectionMatrix(float width, float height) {
+    // Create a new perspective projection matrix. The height will stay the same
+    // while the width will vary as per aspect ratio.
+    mDisplayRatio = width / height;
+    // Set board dimensions
+    mBoardHeight = 1000.0f;
+    mBoardWidth = mDisplayRatio * mBoardHeight;
+    float left = -mDisplayRatio;
+    float right = mDisplayRatio;
+    float bottom = -1.0f;
+    float top = 1.0f;
+    float near = 8.0f;
+    float far = 12.0f;
+
+    return Matrix::newFrustum(left, right, bottom, top, near, far);
+}
+
+bool FlockingScene::setUpTextures() {
+    SCOPED_TRACE();
+    mTextureIds.push_back(GLUtils::loadTexture("texture/fish_dark.png"));
+    mTextureIds.push_back(GLUtils::loadTexture("texture/background.png"));
+    mTextureIds.push_back(GLUtils::loadTexture("texture/water1.png"));
+    mTextureIds.push_back(GLUtils::loadTexture("texture/water2.png"));
+    return true;
+}
+
+bool FlockingScene::setUpMeshes() {
+    SCOPED_TRACE();
+    mMeshes.push_back(GLUtils::loadMesh("mesh/fish.cob"));
+    mMeshes.push_back(GLUtils::loadMesh("mesh/plane.cob"));
+    return true;
+}
+
+bool FlockingScene::tearDown() {
+    SCOPED_TRACE();
+    for (int i = 0; i < NUM_BOIDS; i++) {
+        delete mBoids[i];
+    }
+    delete mMainProgram;
+    delete mWaterProgram;
+    return Scene::tearDown();
+}
+
+bool FlockingScene::updateSceneGraphs(int frame) {
+    const float MAIN_SCALE = 1.25f; // Scale up as the camera is far away.
+    const float LIMIT_X = mBoardWidth / 2.0f;
+    const float LIMIT_Y = mBoardHeight / 2.0f;
+
+    ProgramNode* mainSceneGraph = new ProgramNode(*mMainProgram);
+    mSceneGraphs.push_back(mainSceneGraph);
+    // Bottom
+    Matrix* transformMatrix = Matrix::newScale(MAIN_SCALE * mDisplayRatio, MAIN_SCALE, 0.0f);
+    TransformationNode* transformNode = new TransformationNode(transformMatrix);
+    mainSceneGraph->addChild(transformNode);
+    MeshNode* meshNode = new PerspectiveMeshNode(mMeshes[1], mTextureIds[1]);
+    transformNode->addChild(meshNode);
+    // Boids
+    const float MARGIN = 30.0f; // So the fish dont disappear and appear at the edges.
+    for (int i = 0; i < NUM_BOIDS; i++) {
+        Boid* b = mBoids[i];
+        b->flock((const Boid**) &mBoids, NUM_BOIDS, i, LIMIT_X + MARGIN, LIMIT_Y + MARGIN);
+        Vector2D* pos = &(b->mPosition);
+        Vector2D* vel = &(b->mVelocity);
+
+        // Normalize to (-1,1)
+        float x = pos->mX / (LIMIT_X * BOID_SCALE) * mDisplayRatio;
+        float y = pos->mY / (LIMIT_Y * BOID_SCALE);
+
+        const float SCALE = BOID_SCALE * MAIN_SCALE;
+        transformMatrix = Matrix::newScale(SCALE, SCALE, SCALE);
+        transformMatrix->translate(x, y, 1.0f);
+        transformMatrix->rotate(atan2(vel->mY, vel->mX) + M_PI, 0, 0, 1);
+        transformNode = new TransformationNode(transformMatrix);
+        mainSceneGraph->addChild(transformNode);
+        meshNode = new PerspectiveMeshNode(mMeshes[0], mTextureIds[0]);
+        transformNode->addChild(meshNode);
+    }
+    ProgramNode* waterSceneGraph = new ProgramNode(*mWaterProgram);
+    mSceneGraphs.push_back(waterSceneGraph);
+    // Top
+    transformMatrix = Matrix::newScale(MAIN_SCALE * mDisplayRatio, MAIN_SCALE, 1.0f);
+    transformMatrix->translate(0, 0, 0.1f);
+    transformNode = new TransformationNode(transformMatrix);
+    waterSceneGraph->addChild(transformNode);
+    meshNode = new WaterMeshNode(mMeshes[1], frame, mTextureIds[2], mTextureIds[3]);
+    transformNode->addChild(meshNode);
+    return true;
+}
+
+bool FlockingScene::draw() {
+    SCOPED_TRACE();
+    drawSceneGraph(0); // Draw fish and pond bottom
+    // Use blending.
+    glEnable (GL_BLEND);
+    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+    drawSceneGraph(1); // Draw water
+    glDisable(GL_BLEND);
+    return true;
+}
diff --git a/tests/openglperf2/jni/reference/scene/flocking/FlockingScene.h b/tests/openglperf2/jni/reference/scene/flocking/FlockingScene.h
new file mode 100644
index 0000000..191ebba
--- /dev/null
+++ b/tests/openglperf2/jni/reference/scene/flocking/FlockingScene.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+#ifndef FLOCKINGSCENE_H
+#define FLOCKINGSCENE_H
+
+#include <graphics/Program.h>
+
+#include "../Scene.h"
+#include "Boid.h"
+
+class FlockingScene : public Scene {
+public:
+    FlockingScene(int width, int height);
+    virtual ~FlockingScene() {};
+    bool setUpTextures();
+    bool setUpMeshes();
+    bool tearDown();
+    bool draw();
+    static const int NUM_BOIDS = 100;
+protected:
+    bool setUpPrograms();
+    Matrix* setUpModelMatrix();
+    Matrix* setUpViewMatrix();
+    Matrix* setUpProjectionMatrix(float width, float height);
+    bool updateSceneGraphs(int frame);
+private:
+    Boid* mBoids[NUM_BOIDS];
+    float mDisplayRatio;
+    float mBoardWidth;
+    float mBoardHeight;
+    Program* mMainProgram;
+    Program* mWaterProgram;
+    static const constexpr float BOID_SCALE = 1.0f / 50.0f;
+};
+#endif
diff --git a/suite/cts/deviceTests/opengl/jni/reference/scene/flocking/WaterMeshNode.cpp b/tests/openglperf2/jni/reference/scene/flocking/WaterMeshNode.cpp
similarity index 100%
rename from suite/cts/deviceTests/opengl/jni/reference/scene/flocking/WaterMeshNode.cpp
rename to tests/openglperf2/jni/reference/scene/flocking/WaterMeshNode.cpp
diff --git a/suite/cts/deviceTests/opengl/jni/reference/scene/flocking/WaterMeshNode.h b/tests/openglperf2/jni/reference/scene/flocking/WaterMeshNode.h
similarity index 100%
rename from suite/cts/deviceTests/opengl/jni/reference/scene/flocking/WaterMeshNode.h
rename to tests/openglperf2/jni/reference/scene/flocking/WaterMeshNode.h
diff --git a/suite/cts/deviceTests/opengl/jni/reference/scene/glowing/BlurMeshNode.cpp b/tests/openglperf2/jni/reference/scene/glowing/BlurMeshNode.cpp
similarity index 100%
rename from suite/cts/deviceTests/opengl/jni/reference/scene/glowing/BlurMeshNode.cpp
rename to tests/openglperf2/jni/reference/scene/glowing/BlurMeshNode.cpp
diff --git a/suite/cts/deviceTests/opengl/jni/reference/scene/glowing/BlurMeshNode.h b/tests/openglperf2/jni/reference/scene/glowing/BlurMeshNode.h
similarity index 100%
rename from suite/cts/deviceTests/opengl/jni/reference/scene/glowing/BlurMeshNode.h
rename to tests/openglperf2/jni/reference/scene/glowing/BlurMeshNode.h
diff --git a/tests/openglperf2/jni/reference/scene/glowing/GlowingScene.cpp b/tests/openglperf2/jni/reference/scene/glowing/GlowingScene.cpp
new file mode 100644
index 0000000..6529236
--- /dev/null
+++ b/tests/openglperf2/jni/reference/scene/glowing/GlowingScene.cpp
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+#include "GlowingScene.h"
+#include "BlurMeshNode.h"
+
+#include <Trace.h>
+
+#include <graphics/PerspectiveMeshNode.h>
+#include <graphics/PerspectiveProgram.h>
+#include <graphics/Program.h>
+#include <graphics/GLUtils.h>
+#include <graphics/Mesh.h>
+#include <graphics/ProgramNode.h>
+#include <graphics/TransformationNode.h>
+
+GlowingScene::GlowingScene(int width, int height) :
+        Scene(width, height), mFboId(0), mMainProgram(NULL), mBlurProgram(NULL) {
+    mFboWidth = GLUtils::roundUpToSmallestPowerOf2(width);
+    mFboHeight = GLUtils::roundUpToSmallestPowerOf2(height);
+    mFboRatio = mFboWidth / mFboHeight;
+    mFboModelMatrix = setUpModelMatrix();
+    mFboViewMatrix = setUpViewMatrix();
+    mFboProjectionMatrix = setUpProjectionMatrix(mFboWidth, mFboHeight);
+}
+
+bool GlowingScene::setUpContext() {
+    if (!Scene::setUpContext()) {
+        return false;
+    }
+    // Create a fbo
+    glGenFramebuffers(1, &mFboId);
+    return true;
+}
+
+bool GlowingScene::setUpPrograms() {
+    // Main Program
+    const char* vertex = GLUtils::openTextFile("vertex/perspective");
+    const char* fragment = GLUtils::openTextFile("fragment/perspective");
+    if (vertex == NULL || fragment == NULL) {
+        return false;
+    }
+    GLuint programId = GLUtils::createProgram(&vertex, &fragment);
+    delete[] vertex;
+    delete[] fragment;
+    if (programId == 0) {
+        return false;
+    }
+    mMainProgram = new PerspectiveProgram(programId);
+    // Blur Program
+    vertex = GLUtils::openTextFile("vertex/blur");
+    fragment = GLUtils::openTextFile("fragment/blur");
+    if (vertex == NULL || fragment == NULL) {
+        return false;
+    }
+    programId = GLUtils::createProgram(&vertex, &fragment);
+    delete[] vertex;
+    delete[] fragment;
+    if (programId == 0) {
+        return false;
+    }
+    mBlurProgram = new Program(programId);
+    return true;
+}
+
+Matrix* GlowingScene::setUpModelMatrix() {
+    return new Matrix();
+}
+
+Matrix* GlowingScene::setUpViewMatrix() {
+    // Position the eye in front of the origin.
+    float eyeX = 0.0f;
+    float eyeY = 0.0f;
+    float eyeZ = 10.0f;
+
+    // Look at the origin
+    float centerX = 0.0f;
+    float centerY = 0.0f;
+    float centerZ = 0.0f;
+
+    // Set up vector.
+    float upX = 0.0f;
+    float upY = 1.0f;
+    float upZ = 0.0f;
+
+    // Set the view matrix.
+    return Matrix::newLookAt(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ);
+}
+
+Matrix* GlowingScene::setUpProjectionMatrix(float width, float height) {
+    // Create a new perspective projection matrix. The height will stay the same
+    // while the width will vary as per aspect ratio.
+    float ratio = width / height;
+    float left = -ratio;
+    float right = ratio;
+    float bottom = -1.0f;
+    float top = 1.0f;
+    float near = 8.0f;
+    float far = 12.0f;
+
+    return Matrix::newFrustum(left, right, bottom, top, near, far);
+}
+
+bool GlowingScene::setUpTextures() {
+    SCOPED_TRACE();
+    mTextureIds.push_back(GLUtils::genTexture(mWidth, mHeight, 0)); // fbo
+    mTextureIds.push_back(GLUtils::genTexture(mWidth, mHeight, 0)); // tmp1
+    mTextureIds.push_back(GLUtils::genTexture(mWidth, mHeight, 0)); // tmp2
+    mTextureIds.push_back(GLUtils::loadTexture("texture/arc.png"));
+    return true;
+}
+
+bool GlowingScene::setUpMeshes() {
+    SCOPED_TRACE();
+    mMeshes.push_back(GLUtils::loadMesh("mesh/plane.cob"));
+    mMeshes.push_back(GLUtils::loadMesh("mesh/arc.cob"));
+    return true;
+}
+
+bool GlowingScene::tearDown() {
+    SCOPED_TRACE();
+    if (mMainProgram != NULL) {
+        delete mMainProgram;
+        mMainProgram = NULL;
+    }
+    if (mBlurProgram != NULL) {
+        delete mBlurProgram;
+        mBlurProgram = NULL;
+    }
+    if (mFboId != 0) {
+        glDeleteFramebuffers(1, &mFboId);
+        mFboId = 0;
+    }
+    delete mFboModelMatrix;
+    mFboModelMatrix = NULL;
+    delete mFboViewMatrix;
+    mFboViewMatrix = NULL;
+    delete mFboProjectionMatrix;
+    mFboProjectionMatrix = NULL;
+    return Scene::tearDown();
+}
+
+bool GlowingScene::updateSceneGraphs(int frame) {
+    // To render the mesh to the FBO
+    ProgramNode* lightSceneGraph = new ProgramNode(*mMainProgram);
+    mSceneGraphs.push_back(lightSceneGraph);
+    MeshNode* meshNode = new PerspectiveMeshNode(mMeshes[1], mTextureIds[3]);
+    lightSceneGraph->addChild(meshNode);
+
+    // To blur the image
+    ProgramNode* blurSceneGraph = new ProgramNode(*mBlurProgram);
+    mSceneGraphs.push_back(blurSceneGraph);
+    meshNode = new BlurMeshNode(mMeshes[0], mTextureIds[0], mTextureIds[1], mTextureIds[2],
+            mFboWidth, mFboHeight);
+    blurSceneGraph->addChild(meshNode);
+
+    // Blur To screen
+    ProgramNode* glowSceneGraph = new ProgramNode(*mMainProgram);
+    mSceneGraphs.push_back(glowSceneGraph);
+    Matrix* transformMatrix = Matrix::newScale(mFboRatio, 1.0f, 1.0f);
+    TransformationNode* transformNode = new TransformationNode(transformMatrix);
+    glowSceneGraph->addChild(transformNode);
+    meshNode = new PerspectiveMeshNode(mMeshes[0], mTextureIds[2]);
+    transformNode->addChild(meshNode);
+    return true;
+}
+
+bool GlowingScene::draw() {
+    SCOPED_TRACE();
+    glBindFramebuffer(GL_FRAMEBUFFER, mFboId); // Use FBO
+    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextureIds[0], 0);
+    if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
+        return false;
+    }
+    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+    glClear (GL_COLOR_BUFFER_BIT);
+    glViewport(0, 0, mFboWidth, mFboHeight);
+    mFboModelMatrix->identity();
+    mSceneGraphs[0]->drawProgram(*mFboModelMatrix, *mFboViewMatrix, *mFboProjectionMatrix); // Mesh
+    mFboModelMatrix->identity();
+    mSceneGraphs[1]->drawProgram(*mFboModelMatrix, *mFboViewMatrix, *mFboProjectionMatrix); // Blur
+
+    glBindFramebuffer(GL_FRAMEBUFFER, 0); // Use Screen
+    glViewport(0, 0, mWidth, mHeight);
+    Scene::drawSceneGraph(2); // Blur to Screen
+    return true;
+}
diff --git a/suite/cts/deviceTests/opengl/jni/reference/scene/glowing/GlowingScene.h b/tests/openglperf2/jni/reference/scene/glowing/GlowingScene.h
similarity index 100%
rename from suite/cts/deviceTests/opengl/jni/reference/scene/glowing/GlowingScene.h
rename to tests/openglperf2/jni/reference/scene/glowing/GlowingScene.h
diff --git a/tests/openglperf2/src/android/opengl2/cts/GLActivityIntentKeys.java b/tests/openglperf2/src/android/opengl2/cts/GLActivityIntentKeys.java
new file mode 100644
index 0000000..fcd5f1a
--- /dev/null
+++ b/tests/openglperf2/src/android/opengl2/cts/GLActivityIntentKeys.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package android.opengl2.cts;
+
+public class GLActivityIntentKeys {
+    /**
+     * Holds the name of the benchmark to run.
+     */
+    public final static String INTENT_EXTRA_BENCHMARK_NAME = "benchmark_name";
+    /**
+     * Holds whether or not the benchmark is to be run offscreen.
+     */
+    public final static String INTENT_EXTRA_OFFSCREEN = "offscreen";
+    /**
+     * The number of frames to render for each workload.
+     */
+    public final static String INTENT_EXTRA_NUM_FRAMES = "num_frames";
+    /**
+     * The number of iterations to run, the workload increases with each iteration.
+     */
+    public final static String INTENT_EXTRA_NUM_ITERATIONS = "num_iterations";
+    /**
+     * The number of milliseconds to wait before timing out.
+     */
+    public final static String INTENT_EXTRA_TIMEOUT = "timeout";
+}
diff --git a/tests/openglperf2/src/android/opengl2/cts/primitive/BenchmarkName.java b/tests/openglperf2/src/android/opengl2/cts/primitive/BenchmarkName.java
new file mode 100644
index 0000000..02acfdc
--- /dev/null
+++ b/tests/openglperf2/src/android/opengl2/cts/primitive/BenchmarkName.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package android.opengl2.cts.primitive;
+
+/**
+ * Represents the different primitive benchmarks.
+ */
+public enum BenchmarkName {
+    FullPipeline,
+    PixelOutput,
+    ShaderPerf,
+    ContextSwitch;
+}
diff --git a/tests/openglperf2/src/android/opengl2/cts/primitive/GLPrimitiveActivity.java b/tests/openglperf2/src/android/opengl2/cts/primitive/GLPrimitiveActivity.java
new file mode 100644
index 0000000..6558786
--- /dev/null
+++ b/tests/openglperf2/src/android/opengl2/cts/primitive/GLPrimitiveActivity.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package android.opengl2.cts.primitive;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.cts.util.WatchDog;
+import android.opengl2.cts.GLActivityIntentKeys;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.Surface;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Semaphore;
+
+public class GLPrimitiveActivity extends Activity {
+
+    public final static String TAG = "GLPrimitiveActivity";
+
+    private volatile Exception mException;
+    private volatile Surface mSurface = null;
+    private CountDownLatch mStartSignal = new CountDownLatch(1);
+    private Semaphore mSemaphore = new Semaphore(0);
+
+    private BenchmarkName mBenchmark;
+    private boolean mOffscreen;
+    private int mNumFrames;
+    private int mNumIterations;
+    private int mTimeout;
+    public double[] mFpsValues;
+
+    @Override
+    public void onCreate(Bundle data) {
+        super.onCreate(data);
+        System.loadLibrary("ctsopengl_jni");
+        Intent intent = getIntent();
+        mBenchmark = BenchmarkName.valueOf(
+                intent.getStringExtra(GLActivityIntentKeys.INTENT_EXTRA_BENCHMARK_NAME));
+        mOffscreen = intent.getBooleanExtra(GLActivityIntentKeys.INTENT_EXTRA_OFFSCREEN, false);
+        mNumFrames = intent.getIntExtra(GLActivityIntentKeys.INTENT_EXTRA_NUM_FRAMES, 0);
+        mNumIterations = intent.getIntExtra(GLActivityIntentKeys.INTENT_EXTRA_NUM_ITERATIONS, 0);
+        mTimeout = intent.getIntExtra(GLActivityIntentKeys.INTENT_EXTRA_TIMEOUT, 0);
+        mFpsValues = new double[mNumIterations];
+
+        Log.i(TAG, "Benchmark: " + mBenchmark);
+        Log.i(TAG, "Offscreen: " + mOffscreen);
+        Log.i(TAG, "Num Frames: " + mNumFrames);
+        Log.i(TAG, "Num Iterations: " + mNumIterations);
+        Log.i(TAG, "Time Out: " + mTimeout);
+
+        SurfaceView surfaceView = new SurfaceView(this);
+        surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
+            @Override
+            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
+                mSurface = holder.getSurface();
+                mStartSignal.countDown();
+            }
+
+            @Override
+            public void surfaceCreated(SurfaceHolder holder) {}
+
+            @Override
+            public void surfaceDestroyed(SurfaceHolder holder) {}
+        });
+        setContentView(surfaceView);
+        // Spawns a worker to run the benchmark.
+        Worker worker = new Worker();
+        worker.start();
+    }
+
+    public void waitForCompletion() throws Exception {
+        // Wait for semiphore.
+        mSemaphore.acquire();
+        if (mException != null) {
+            throw mException;
+        }
+    }
+
+    private void complete() {
+        // Release semiphore.
+        mSemaphore.release();
+        finish();
+    }
+
+    private synchronized void setException(Exception e) {
+        if (mException == null) {
+            mException = e;
+        }
+    }
+
+    private static native boolean setupBenchmark(
+            Surface surface, int benchmark, boolean offscreen);
+
+    private static native boolean startBenchmark(int workload, int numFrames, double[] frameTimes);
+
+    private static native void tearDownBenchmark();
+
+    /**
+     * This thread runs the benchmarks, freeing the UI thread.
+     */
+    private class Worker extends Thread implements WatchDog.TimeoutCallback {
+
+        private WatchDog watchDog;
+        private volatile boolean success = true;
+
+        @Override
+        public void run() {
+            try {
+                mStartSignal.await();
+            } catch (InterruptedException e) {
+                setException(e);
+                complete();
+                return;
+            }
+            Log.i(TAG, mBenchmark + " Benchmark Started");
+            // Creates a watchdog to ensure a iteration doesn't exceed the timeout.
+            watchDog = new WatchDog(mTimeout, this);
+            // Used to record the start and end time of the iteration.
+            double[] times = new double[2];
+            try {
+                // Setup the benchmark.
+                setupBenchmark(mSurface, mBenchmark.ordinal(), mOffscreen);
+                for (int i = 0; i < mNumIterations && success; i++) {
+                    // The workload to use for this iteration.
+                    int workload = i + 1;
+                    watchDog.start();
+                    // Start benchmark.
+                    success = startBenchmark(workload, mNumFrames, times);
+                    watchDog.stop();
+                    if (!success) {
+                        setException(new Exception("Benchmark failed to run"));
+                    } else {
+                        // Calculate FPS.
+                        mFpsValues[i] = mNumFrames * 1000.0f / (times[1] - times[0]);
+                    }
+                }
+            }
+            finally
+            {
+                tearDownBenchmark();
+            }
+
+            complete();
+            Log.i(TAG, mBenchmark + " Benchmark Completed");
+        }
+
+        public void onTimeout() {
+            setException(new Exception("Benchmark timed out"));
+            complete();
+        }
+
+    }
+}
diff --git a/tests/openglperf2/src/android/opengl2/cts/primitive/GLPrimitiveBenchmark.java b/tests/openglperf2/src/android/opengl2/cts/primitive/GLPrimitiveBenchmark.java
new file mode 100644
index 0000000..d737dbf
--- /dev/null
+++ b/tests/openglperf2/src/android/opengl2/cts/primitive/GLPrimitiveBenchmark.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package android.opengl2.cts.primitive;
+
+import android.content.Intent;
+import android.opengl2.cts.GLActivityIntentKeys;
+import android.test.ActivityInstrumentationTestCase2;
+
+import com.android.compatibility.common.util.DeviceReportLog;
+import com.android.compatibility.common.util.ResultType;
+import com.android.compatibility.common.util.ResultUnit;
+import com.android.cts.util.TimeoutReq;
+
+/**
+ * Runs the Primitive OpenGL ES 2.0 Benchmarks.
+ */
+public class GLPrimitiveBenchmark extends ActivityInstrumentationTestCase2<GLPrimitiveActivity> {
+
+    private static final int NUM_FRAMES = 100;
+    private static final int NUM_ITERATIONS = 8;
+    private static final int TIMEOUT = 1000000;
+
+    public GLPrimitiveBenchmark() {
+        super(GLPrimitiveActivity.class);
+    }
+
+    /**
+     * Runs the full OpenGL ES 2.0 pipeline test offscreen.
+     */
+    @TimeoutReq(minutes = 100)
+    public void testFullPipelineOffscreen() throws Exception {
+        runBenchmark(BenchmarkName.FullPipeline, true, NUM_FRAMES, NUM_ITERATIONS, TIMEOUT);
+    }
+
+    /**
+     * Runs the full OpenGL ES 2.0 pipeline test onscreen.
+     */
+    @TimeoutReq(minutes = 100)
+    public void testFullPipelineOnscreen() throws Exception {
+        runBenchmark(BenchmarkName.FullPipeline, false, NUM_FRAMES, NUM_ITERATIONS, TIMEOUT);
+    }
+
+    /**
+     * Runs the pixel output test offscreen.
+     */
+    @TimeoutReq(minutes = 100)
+    public void testPixelOutputOffscreen() throws Exception {
+        runBenchmark(BenchmarkName.PixelOutput, true, NUM_FRAMES, NUM_ITERATIONS, TIMEOUT);
+    }
+
+    /**
+     * Runs the pixel output test onscreen.
+     */
+    @TimeoutReq(minutes = 100)
+    public void testPixelOutputOnscreen() throws Exception {
+        runBenchmark(BenchmarkName.PixelOutput, false, NUM_FRAMES, NUM_ITERATIONS, TIMEOUT);
+    }
+
+    /**
+     * Runs the shader performance test offscreen.
+     */
+    @TimeoutReq(minutes = 100)
+    public void testShaderPerfOffscreen() throws Exception {
+        runBenchmark(BenchmarkName.ShaderPerf, true, NUM_FRAMES, NUM_ITERATIONS, TIMEOUT);
+    }
+
+    /**
+     * Runs the shader performance test onscreen.
+     */
+    @TimeoutReq(minutes = 100)
+    public void testShaderPerfOnscreen() throws Exception {
+        runBenchmark(BenchmarkName.ShaderPerf, false, NUM_FRAMES, NUM_ITERATIONS, TIMEOUT);
+    }
+
+    /**
+     * Runs the context switch overhead test offscreen.
+     */
+    @TimeoutReq(minutes = 100)
+    public void testContextSwitchOffscreen() throws Exception {
+        runBenchmark(BenchmarkName.ContextSwitch, true, NUM_FRAMES, NUM_ITERATIONS, TIMEOUT);
+    }
+
+    /**
+     * Runs the context switch overhead test onscreen.
+     */
+    @TimeoutReq(minutes = 100)
+    public void testContextSwitchOnscreen() throws Exception {
+        runBenchmark(BenchmarkName.ContextSwitch, false, NUM_FRAMES, NUM_ITERATIONS, TIMEOUT);
+    }
+
+    /**
+     * Runs the specified test.
+     *
+     * @param benchmark An enum representing the benchmark to run.
+     * @param offscreen Whether to render to an offscreen framebuffer rather than the screen.
+     * @param numFrames The number of frames to render.
+     * @param numIterations The number of iterations to run, each iteration has a bigger workload.
+     * @param timeout The milliseconds to wait for an iteration of the benchmark before timing out.
+     * @throws Exception If the benchmark could not be run.
+     */
+    private void runBenchmark(BenchmarkName benchmark, boolean offscreen, int numFrames,
+            int numIterations, int timeout) throws Exception {
+        String benchmarkName = benchmark.toString();
+        Intent intent = new Intent();
+        intent.putExtra(GLActivityIntentKeys.INTENT_EXTRA_BENCHMARK_NAME, benchmarkName);
+        intent.putExtra(GLActivityIntentKeys.INTENT_EXTRA_OFFSCREEN, offscreen);
+        intent.putExtra(GLActivityIntentKeys.INTENT_EXTRA_NUM_FRAMES, numFrames);
+        intent.putExtra(GLActivityIntentKeys.INTENT_EXTRA_NUM_ITERATIONS, numIterations);
+        intent.putExtra(GLActivityIntentKeys.INTENT_EXTRA_TIMEOUT, timeout);
+
+        setActivityIntent(intent);
+        GLPrimitiveActivity activity = getActivity();
+        if (activity != null) {
+            activity.waitForCompletion();
+            double[] fpsValues = activity.mFpsValues;
+            double score = 0;
+            for (double d : fpsValues) {
+                score += d;
+            }
+            score /= numIterations;// Average.
+
+            // TODO: maybe standard deviation / RMSE will be useful?
+
+            DeviceReportLog report = new DeviceReportLog();
+            report.setSummary("Average FPS", score, ResultType.HIGHER_BETTER, ResultUnit.SCORE);
+            report.submit(getInstrumentation());
+        }
+    }
+}
diff --git a/tests/openglperf2/src/android/opengl2/cts/reference/GLGameActivity.java b/tests/openglperf2/src/android/opengl2/cts/reference/GLGameActivity.java
new file mode 100644
index 0000000..0bfb38b
--- /dev/null
+++ b/tests/openglperf2/src/android/opengl2/cts/reference/GLGameActivity.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package android.opengl2.cts.reference;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.content.res.AssetManager;
+import android.cts.util.WatchDog;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.opengl.GLES20;
+import android.opengl.GLUtils;
+import android.opengl2.cts.GLActivityIntentKeys;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.view.Surface;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.concurrent.CountDownLatch;
+
+public class GLGameActivity extends Activity {
+
+    public final static String SET_UP_TIME = "set_up_time";
+    public final static String UPDATE_TIMES = "update_times";
+    public final static String RENDER_TIMES = "render_times";
+
+    private int mNumFrames;
+    private int mTimeout;
+    private double[] mSetUpTimes;
+    private double[] mUpdateTimes;
+    private double[] mRenderTimes;
+    private volatile Surface mSurface = null;
+    private CountDownLatch mStartSignal = new CountDownLatch(1);
+
+    @Override
+    public void onCreate(Bundle data) {
+        super.onCreate(data);
+        System.loadLibrary("ctsopengl_jni");
+
+        Intent intent = getIntent();
+        mNumFrames = intent.getIntExtra(GLActivityIntentKeys.INTENT_EXTRA_NUM_FRAMES, 1000);
+        mTimeout = intent.getIntExtra(GLActivityIntentKeys.INTENT_EXTRA_TIMEOUT, 1000000);
+
+        SurfaceView surfaceView = new SurfaceView(this);
+        surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
+            @Override
+            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
+                mSurface = holder.getSurface();
+                mStartSignal.countDown();
+            }
+
+            @Override
+            public void surfaceCreated(SurfaceHolder holder) {}
+
+            @Override
+            public void surfaceDestroyed(SurfaceHolder holder) {}
+        });
+        setContentView(surfaceView);
+
+        // Spawns a worker.
+        Worker worker = new Worker(new Handler() {
+            @Override
+            public void handleMessage(Message msg) {
+                Intent intent = new Intent();
+                intent.putExtra(SET_UP_TIME, mSetUpTimes);
+                intent.putExtra(UPDATE_TIMES, mUpdateTimes);
+                intent.putExtra(RENDER_TIMES, mRenderTimes);
+                setResult((msg.what == 1) ? RESULT_OK : RESULT_CANCELED, intent);
+                finish();
+            }
+        });
+        worker.start();
+    }
+
+    private static native boolean startBenchmark(AssetManager manager,
+            Surface surface,
+            int numFrames,
+            double[] setUpTimes,
+            double[] updateTimes,
+            double[] renderTimes);
+
+    /**
+     * This thread renderers the benchmarks, freeing the UI thread.
+     */
+    private class Worker extends Thread implements WatchDog.TimeoutCallback {
+
+        private WatchDog watchDog;
+        private Handler mHandler;
+
+        public Worker(Handler handler) {
+            mHandler = handler;
+        }
+
+        @Override
+        public void run() {
+            try {
+                mStartSignal.await();
+            } catch (InterruptedException e) {
+                mHandler.sendEmptyMessage(0);
+                return;
+            }
+            // Creates a watchdog to ensure a iteration doesn't exceed the timeout.
+            watchDog = new WatchDog(mTimeout, this);
+            watchDog.start();
+
+            // Used to record the time taken to setup (GL, context, textures, meshes).
+            mSetUpTimes = new double[4];
+            // Used to record the times taken to update.
+            mUpdateTimes = new double[mNumFrames];
+            // Used to record the times taken to render.
+            mRenderTimes = new double[mNumFrames];
+            boolean success = startBenchmark(getAssets(),
+                    mSurface,
+                    mNumFrames,
+                    mSetUpTimes,
+                    mUpdateTimes,
+                    mRenderTimes);
+
+            watchDog.stop();
+            mHandler.sendEmptyMessage((success) ? 1 : 0);
+        }
+
+        @Override
+        public void onTimeout() {
+            mHandler.sendEmptyMessage(0);
+        }
+
+    }
+
+    public static int loadTexture(AssetManager manager, String path) {
+        InputStream in = null;
+        try {
+            in = manager.open(path);
+        } catch (IOException e) {
+            e.printStackTrace();
+            return -1;
+        }
+        BitmapFactory.Options op = new BitmapFactory.Options();
+        op.inPreferredConfig = Bitmap.Config.ARGB_8888;
+        Bitmap bmp = BitmapFactory.decodeStream(in, null, op);
+        // generate textureID
+        int[] textures = new int[1];
+        GLES20.glGenTextures(1, textures, 0);
+        int textureID = textures[0];
+
+        // create texture
+        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureID);
+        GLES20.glTexParameteri(
+                GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
+        GLES20.glTexParameteri(
+                GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
+        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_REPEAT);
+        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_REPEAT);
+        GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bmp, 0);
+
+        // clean up
+        try {
+            in.close();
+        } catch (IOException e) {
+            e.printStackTrace();
+        } finally {
+            bmp.recycle();
+        }
+        return textureID;
+    }
+}
diff --git a/tests/openglperf2/src/android/opengl2/cts/reference/GLReferenceActivity.java b/tests/openglperf2/src/android/opengl2/cts/reference/GLReferenceActivity.java
new file mode 100644
index 0000000..7a800a5
--- /dev/null
+++ b/tests/openglperf2/src/android/opengl2/cts/reference/GLReferenceActivity.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package android.opengl2.cts.reference;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.opengl2.cts.GLActivityIntentKeys;
+import android.os.Bundle;
+
+import java.util.concurrent.Semaphore;
+
+public class GLReferenceActivity extends Activity {
+
+    private final static int GAME_ACTIVITY_CODE = 1;
+
+    private volatile Exception mException;
+    private int mNumFrames;
+    private int mTimeout;
+
+    public double[] mSetUpTimes;
+    public double[] mUpdateTimes;
+    public double[] mRenderTimes;
+
+    private Semaphore mSemaphore = new Semaphore(0);
+
+    @Override
+    public void onCreate(Bundle data) {
+        super.onCreate(data);
+        Intent intent = getIntent();
+        mNumFrames = intent.getIntExtra(GLActivityIntentKeys.INTENT_EXTRA_NUM_FRAMES, 0);
+        mTimeout = intent.getIntExtra(GLActivityIntentKeys.INTENT_EXTRA_TIMEOUT, 0);
+
+        // Start benchmark
+        intent = new Intent(this, GLGameActivity.class);
+        intent.putExtra(GLActivityIntentKeys.INTENT_EXTRA_NUM_FRAMES, mNumFrames);
+        intent.putExtra(GLActivityIntentKeys.INTENT_EXTRA_TIMEOUT, mTimeout);
+        startActivityForResult(intent, GAME_ACTIVITY_CODE);
+    }
+
+    public void waitForCompletion() throws Exception {
+        // Wait for semiphore.
+        mSemaphore.acquire();
+        if (mException != null) {
+            throw mException;
+        }
+    }
+
+    private synchronized void setException(Exception e) {
+        if (mException == null) {
+            mException = e;
+        }
+    }
+
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        if (requestCode == GAME_ACTIVITY_CODE) {
+            if (resultCode == RESULT_OK) {
+                // Benchmark passed
+                mSetUpTimes = data.getDoubleArrayExtra(GLGameActivity.SET_UP_TIME);
+                mUpdateTimes = data.getDoubleArrayExtra(GLGameActivity.UPDATE_TIMES);
+                mRenderTimes = data.getDoubleArrayExtra(GLGameActivity.RENDER_TIMES);
+            } else {
+                setException(new Exception("Benchmark failed to run"));
+            }
+            // Release semiphore.
+            mSemaphore.release();
+            finish();
+        }
+    }
+
+}
diff --git a/tests/openglperf2/src/android/opengl2/cts/reference/GLReferenceBenchmark.java b/tests/openglperf2/src/android/opengl2/cts/reference/GLReferenceBenchmark.java
new file mode 100644
index 0000000..196207c
--- /dev/null
+++ b/tests/openglperf2/src/android/opengl2/cts/reference/GLReferenceBenchmark.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package android.opengl2.cts.reference;
+
+import android.content.Intent;
+import android.opengl2.cts.GLActivityIntentKeys;
+import android.test.ActivityInstrumentationTestCase2;
+
+import com.android.compatibility.common.util.DeviceReportLog;
+import com.android.compatibility.common.util.ResultType;
+import com.android.compatibility.common.util.ResultUnit;
+import com.android.cts.util.TimeoutReq;
+
+/**
+ * Runs the Reference OpenGL ES 2.0 Benchmark.
+ */
+public class GLReferenceBenchmark extends ActivityInstrumentationTestCase2<GLReferenceActivity> {
+
+    private static final int NUM_FRAMES_PER_SCENE = 500;
+    private static final int NUM_SCENES = 2;
+    private static final int NUM_FRAMES = NUM_FRAMES_PER_SCENE * NUM_SCENES;
+    private static final int TIMEOUT = 1000000;
+
+    public GLReferenceBenchmark() {
+        super(GLReferenceActivity.class);
+    }
+
+    /**
+     * Runs the reference benchmark.
+     */
+    @TimeoutReq(minutes = 30)
+    public void testReferenceBenchmark() throws Exception {
+        Intent intent = new Intent();
+        intent.putExtra(GLActivityIntentKeys.INTENT_EXTRA_NUM_FRAMES, NUM_FRAMES);
+        intent.putExtra(GLActivityIntentKeys.INTENT_EXTRA_TIMEOUT, TIMEOUT);
+
+        GLReferenceActivity activity = null;
+        setActivityIntent(intent);
+        activity = getActivity();
+        if (activity != null) {
+            activity.waitForCompletion();
+            double totalTime = 0;
+            double[] setUpTimes = activity.mSetUpTimes;
+            double[] updateTimes = activity.mUpdateTimes;
+            double[] renderTimes = activity.mRenderTimes;
+
+            // Calculate update and render average.
+            double updateSum = updateTimes[0];
+            double renderSum = renderTimes[0];
+            for (int i = 0; i < NUM_FRAMES - 1; i++) {
+                updateSum += updateTimes[i + 1];
+                renderSum += renderTimes[i + 1];
+            }
+            double updateAverage = updateSum / NUM_FRAMES;
+            double renderAverage = renderSum / NUM_FRAMES;
+
+            DeviceReportLog report = new DeviceReportLog();
+            report.addValues("Set Up Times", setUpTimes, ResultType.LOWER_BETTER, ResultUnit.MS);
+            report.addValue("Update Time Average", updateAverage, ResultType.LOWER_BETTER,
+                    ResultUnit.MS);
+            report.addValue("Render Time Average", renderAverage, ResultType.LOWER_BETTER,
+                    ResultUnit.MS);
+            totalTime = setUpTimes[0] + setUpTimes[1] + setUpTimes[2] + setUpTimes[3] +
+                    updateAverage + renderAverage;
+            report.setSummary("Total Time Average", totalTime, ResultType.LOWER_BETTER,
+                    ResultUnit.MS);
+            report.submit(getInstrumentation());
+        }
+    }
+}
diff --git a/tests/openglperf2/test/Android.mk b/tests/openglperf2/test/Android.mk
new file mode 100644
index 0000000..e83e584
--- /dev/null
+++ b/tests/openglperf2/test/Android.mk
@@ -0,0 +1,26 @@
+#
+# Copyright (C) 2013 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(call all-subdir-cpp-files)
+LOCAL_SRC_FILES += ../jni/graphics/Matrix.cpp
+
+LOCAL_C_INCLUDES += external/gtest/include $(LOCAL_PATH)/../jni/graphics/
+LOCAL_STATIC_LIBRARIES := libgtest_host libgtest_main_host liblog
+LOCAL_LDFLAGS:= -g -lpthread
+LOCAL_MODULE_HOST_OS := linux
+LOCAL_MODULE:= cts_device_opengl_test
+include $(BUILD_HOST_EXECUTABLE)
diff --git a/suite/cts/deviceTests/opengl/test/MatrixTest.cpp b/tests/openglperf2/test/MatrixTest.cpp
similarity index 100%
rename from suite/cts/deviceTests/opengl/test/MatrixTest.cpp
rename to tests/openglperf2/test/MatrixTest.cpp
diff --git a/tests/sample/Android.mk b/tests/sample/Android.mk
index 5e8f571..419faa5 100755
--- a/tests/sample/Android.mk
+++ b/tests/sample/Android.mk
@@ -16,19 +16,24 @@
 
 include $(CLEAR_VARS)
 
-# Don't include this package in any target.
-LOCAL_MODULE_TAGS := optional
-
+# Don't include this package in any target
+LOCAL_MODULE_TAGS := tests
 # When built, explicitly put it in the data partition.
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
 
-LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctstestrunner
+LOCAL_DEX_PREOPT := false
+
+LOCAL_PROGUARD_ENABLED := disabled
+
+LOCAL_STATIC_JAVA_LIBRARIES := compatibility-device-util android-support-test
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
-# Must match the package name in CtsTestCaseList.mk
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_PACKAGE_NAME := CtsSampleDeviceTestCases
 
 LOCAL_SDK_VERSION := current
 
-include $(BUILD_CTS_PACKAGE)
+include $(BUILD_PACKAGE)
diff --git a/tests/sample/AndroidManifest.xml b/tests/sample/AndroidManifest.xml
index f07ebbe..108321f 100755
--- a/tests/sample/AndroidManifest.xml
+++ b/tests/sample/AndroidManifest.xml
@@ -18,7 +18,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="android.sample.cts">
 
-    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
     <application>
         <uses-library android:name="android.test.runner" />
         <activity android:name="android.sample.SampleDeviceActivity" >
@@ -34,9 +34,6 @@
         android:name="android.support.test.runner.AndroidJUnitRunner"
         android:label="CTS sample tests"
         android:targetPackage="android.sample.cts" >
-        <meta-data
-            android:name="listener"
-            android:value="com.android.cts.runner.CtsTestRunListener" />
     </instrumentation>
 </manifest>
 
diff --git a/tests/sample/AndroidTest.xml b/tests/sample/AndroidTest.xml
new file mode 100644
index 0000000..ae790fb
--- /dev/null
+++ b/tests/sample/AndroidTest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS Sample test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsSampleDeviceTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.sample.cts" />
+    </test>
+</configuration>
diff --git a/tests/sample/src/android/sample/cts/SampleDeviceReportLogTest.java b/tests/sample/src/android/sample/cts/SampleDeviceReportLogTest.java
new file mode 100644
index 0000000..7f8e2f6
--- /dev/null
+++ b/tests/sample/src/android/sample/cts/SampleDeviceReportLogTest.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.sample.cts;
+
+import android.sample.SampleDeviceActivity;
+import android.test.ActivityInstrumentationTestCase2;
+
+import com.android.compatibility.common.util.DeviceReportLog;
+import com.android.compatibility.common.util.ResultType;
+import com.android.compatibility.common.util.ResultUnit;
+
+/**
+ * A simple compatibility test which includes results in the report.
+ *
+ * This class has 3 dummy tests that create report logs and log dummy metrics.
+ */
+public class SampleDeviceReportLogTest
+        extends ActivityInstrumentationTestCase2<SampleDeviceActivity> {
+
+    /**
+     * Sample numbers used by the sample tests.
+     */
+    private static final int MULTIPLICATION_NUMBER_1 = 23;
+    private static final int MULTIPLICATION_NUMBER_2 = 97;
+    private static final int MULTIPLICATION_RESULT = 2231;
+    private static final int COUNT_START = 1;
+    private static final int COUNT_END = 1000;
+
+    private static final String EXPECTED_PRODUCT_TAG = "expected_product";
+    private static final String ACTUAL_PRODUCT_TAG = "actual_product";
+    private static final String START_TAG = "count_start";
+    private static final String END_TAG = "actual_end";
+
+    /**
+     * Constructor which passes the class of the activity to be instrumented.
+     */
+    public SampleDeviceReportLogTest() {
+        super(SampleDeviceActivity.class);
+    }
+
+    /**
+     * Sample test that creates and logs test metrics into a report log.
+     */
+    public void testMultiplication() {
+        // Perform test.
+        int product = MULTIPLICATION_NUMBER_1 * MULTIPLICATION_NUMBER_2;
+        assertTrue("Multiplication result do not match", product == MULTIPLICATION_RESULT);
+
+        // Log metrics from the test.
+        String reportLogName = "SampleDeviceTestMetrics";
+        String streamName = "test_multiplication_metrics";
+        DeviceReportLog reportLog = new DeviceReportLog(reportLogName, streamName);
+        reportLog.addValue(EXPECTED_PRODUCT_TAG, 1.0 * MULTIPLICATION_RESULT, ResultType.NEUTRAL,
+                ResultUnit.NONE);
+        reportLog.addValue(ACTUAL_PRODUCT_TAG, 1.0 * product, ResultType.NEUTRAL, ResultUnit.NONE);
+        reportLog.setSummary(ACTUAL_PRODUCT_TAG, 1.0 * product, ResultType.NEUTRAL, ResultUnit.NONE);
+        reportLog.submit(getInstrumentation());
+    }
+
+    /**
+     * Sample test to check counting up.
+     */
+    public void testCountUp() {
+        String streamName = "test_count_up_metrics";
+        countHelper(1, streamName);
+    }
+
+    /**
+     * Sample test to check counting down.
+     */
+    public void testCountDown() {
+        String streamName = "test_count_down_metrics";
+        countHelper(2, streamName);
+    }
+
+    /**
+     * Sample test function that counts up or down based on test parameter. It creates and logs test
+     * metrics into a report log.
+     * @param testParameter {@link String} parameter passed by caller test function.
+     * @param streamName {@link String} name of the report log stream retrieved from dynamic config.
+     */
+    private void countHelper(int testParameter, String streamName) {
+        // Perform test.
+        int start;
+        int end;
+        if (testParameter == 1) {
+            start = COUNT_START;
+            end = COUNT_END;
+            for (int i = start; i <= end;) {
+                i++;
+            }
+        } else {
+            start = COUNT_END;
+            end = COUNT_START;
+            for (int i = start; i >= end;) {
+                i--;
+            }
+        }
+
+        // Log metrics.
+        String reportLogName = "SampleDeviceTestMetrics";
+        DeviceReportLog reportLog = new DeviceReportLog(reportLogName, streamName);
+        reportLog.addValue(START_TAG, 1.0 * start, ResultType.NEUTRAL, ResultUnit.NONE);
+        reportLog.addValue(END_TAG, 1.0 * end, ResultType.NEUTRAL, ResultUnit.NONE);
+        reportLog.setSummary(END_TAG, 1.0 * end, ResultType.NEUTRAL, ResultUnit.NONE);
+        reportLog.submit(getInstrumentation());
+    }
+}
diff --git a/tests/sample/src/android/sample/cts/SampleDeviceResultTest.java b/tests/sample/src/android/sample/cts/SampleDeviceResultTest.java
index 6bf883f..f8f7a6b 100644
--- a/tests/sample/src/android/sample/cts/SampleDeviceResultTest.java
+++ b/tests/sample/src/android/sample/cts/SampleDeviceResultTest.java
@@ -15,21 +15,25 @@
  */
 package android.sample.cts;
 
-import com.android.cts.util.MeasureRun;
-import com.android.cts.util.MeasureTime;
-import com.android.cts.util.ReportLog;
-import com.android.cts.util.ResultType;
-import com.android.cts.util.ResultUnit;
-import com.android.cts.util.Stat;
+import android.sample.SampleDeviceActivity;
+import android.test.ActivityInstrumentationTestCase2;
 
-import android.cts.util.CtsAndroidTestCase;
+import com.android.compatibility.common.util.DeviceReportLog;
+import com.android.compatibility.common.util.MeasureRun;
+import com.android.compatibility.common.util.MeasureTime;
+import com.android.compatibility.common.util.ResultType;
+import com.android.compatibility.common.util.ResultUnit;
+import com.android.compatibility.common.util.Stat;
+
+import java.util.Arrays;
+import java.util.Random;
 
 /**
  * A simple compatibility test which includes results in the report.
  *
  * This test measures the time taken to run a workload and adds in the report.
  */
-public class SampleDeviceResultTest extends CtsAndroidTestCase {
+public class SampleDeviceResultTest extends ActivityInstrumentationTestCase2<SampleDeviceActivity> {
 
     /**
      * The number of times to repeat the test.
@@ -37,86 +41,75 @@
     private static final int REPEAT = 5;
 
     /**
-     * The input number for the factorial.
+     * A {@link Random} to generate random integers to test the sort.
      */
-    private static final int IN = 15;
+    private static final Random random = new Random(12345);
 
     /**
-     * The expected output number for the factorial.
+     * Constructor which passes the class of the activity to be instrumented.
      */
-    private static final long OUT = 1307674368000L;
-
-    /**
-     * Measures the time taken to compute the factorial of 15 with a recursive method.
-     *
-     * @throws Exception
-     */
-    public void testFactorialRecursive() throws Exception {
-        runTest(new MeasureRun() {
-            @Override
-            public void run(int i) throws Exception {
-                // Compute the factorial and assert it is correct.
-                assertEquals("Incorrect result", OUT, factorialRecursive(IN));
-            }
-        });
+    public SampleDeviceResultTest() {
+        super(SampleDeviceActivity.class);
     }
 
     /**
-     * Measures the time taken to compute the factorial of 15 with a iterative method.
-     *
-     * @throws Exception
+     * Measures the time taken to sort an array.
      */
-    public void testFactorialIterative() throws Exception {
-        runTest(new MeasureRun() {
-            @Override
-            public void run(int i) throws Exception {
-                // Compute the factorial and assert it is correct.
-                assertEquals("Incorrect result", OUT, factorialIterative(IN));
-            }
-        });
-    }
-
-    /**
-     * Computes the factorial of a number with a recursive method.
-     *
-     * @param num The number to compute the factorial of.
-     */
-    private static long factorialRecursive(int num) {
-        if (num <= 0) {
-            return 1;
-        }
-        return num * factorialRecursive(num - 1);
-    }
-
-    /**
-     * Computes the factorial of a number with a iterative method.
-     *
-     * @param num The number to compute the factorial of.
-     */
-    private static long factorialIterative(int num) {
-        long result = 1;
-        for (int i = 2; i <= num; i++) {
-            result *= i;
-        }
-        return result;
-    }
-
-    /**
-     * Runs the workload and records the result to the report log.
-     *
-     * @param workload
-     */
-    private void runTest(MeasureRun workload) throws Exception {
+    public void testSort() throws Exception {
         // MeasureTime runs the workload N times and records the time taken by each run.
-        double[] result = MeasureTime.measure(REPEAT, workload);
+        double[] result = MeasureTime.measure(REPEAT, new MeasureRun() {
+            /**
+             * The size of the array to sort.
+             */
+            private static final int ARRAY_SIZE = 100000;
+            private int[] array;
+            @Override
+            public void prepare(int i) throws Exception {
+                array = createArray(ARRAY_SIZE);
+            }
+            @Override
+            public void run(int i) throws Exception {
+                Arrays.sort(array);
+                assertTrue("Array not sorted", isSorted(array));
+            }
+        });
         // Compute the stats.
         Stat.StatResult stat = Stat.getStat(result);
-        // Get the report for this test and add the results to record.
-        ReportLog log = getReportLog();
-        log.printArray("Times", result, ResultType.LOWER_BETTER, ResultUnit.MS);
-        log.printValue("Min", stat.mMin, ResultType.LOWER_BETTER, ResultUnit.MS);
-        log.printValue("Max", stat.mMax, ResultType.LOWER_BETTER, ResultUnit.MS);
+        // Create a new report to hold the metrics.
+        String reportLogName = "SampleDeviceTestMetrics";
+        String streamName = "test_sort_metrics";
+        DeviceReportLog reportLog = new DeviceReportLog(reportLogName, streamName);
+        // Add the results to the report.
+        reportLog.addValues("times", result, ResultType.LOWER_BETTER, ResultUnit.MS);
+        reportLog.addValue("min", stat.mMin, ResultType.LOWER_BETTER, ResultUnit.MS);
+        reportLog.addValue("max", stat.mMax, ResultType.LOWER_BETTER, ResultUnit.MS);
         // Every report must have a summary,
-        log.printSummary("Average", stat.mAverage, ResultType.LOWER_BETTER, ResultUnit.MS);
+        reportLog.setSummary("average", stat.mAverage, ResultType.LOWER_BETTER, ResultUnit.MS);
+        // Submit the report to the given instrumentation.
+        reportLog.submit(getInstrumentation());
+    }
+
+    /**
+     * Creates an array filled with random numbers of the given size.
+     */
+    private static int[] createArray(int size) {
+        int[] array = new int[size];
+        for (int i = 0; i < size; i++) {
+            array[i] = random.nextInt();
+        }
+        return array;
+    }
+
+    /**
+     * Tests an array is sorted.
+     */
+    private static boolean isSorted(int[] array) {
+        int len = array.length;
+        for (int i = 0, j = 1; j < len; i++, j++) {
+            if (array[i] > array[j]) {
+                return false;
+            }
+        }
+        return true;
     }
 }
diff --git a/tests/sample/src/android/sample/cts/SampleJUnit4DeviceTest.java b/tests/sample/src/android/sample/cts/SampleJUnit4DeviceTest.java
new file mode 100755
index 0000000..c8863b3
--- /dev/null
+++ b/tests/sample/src/android/sample/cts/SampleJUnit4DeviceTest.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.sample.cts;
+
+import org.junit.Assert;
+import org.junit.runner.RunWith;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import android.app.Activity;
+import android.sample.SampleDeviceActivity;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.rule.ActivityTestRule;
+import android.support.test.runner.AndroidJUnit4;
+import android.test.ActivityInstrumentationTestCase2;
+
+/**
+ * A simple compatibility test which tests the SharedPreferences API.
+ *
+ * This test uses {@link ActivityTestRule} to instrument the
+ * {@link android.sample.SampleDeviceActivity}.
+ */
+@RunWith(AndroidJUnit4.class)
+public class SampleJUnit4DeviceTest {
+
+    private static final String KEY = "foo";
+
+    private static final String VALUE = "bar";
+
+    @Rule
+    public ActivityTestRule<SampleDeviceActivity> mActivityRule =
+        new ActivityTestRule(SampleDeviceActivity.class);
+
+
+    /**
+     * This inserts the key value pair and assert they can be retrieved. Then it clears the
+     * preferences and asserts they can no longer be retrieved.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void shouldSaveSharedPreferences() throws Exception {
+        // Save the key value pair to the preferences and assert they were saved.
+        mActivityRule.getActivity().savePreference(KEY, VALUE);
+        Assert.assertEquals("Preferences were not saved", VALUE,
+            mActivityRule.getActivity().getPreference(KEY));
+
+        // Clear the shared preferences and assert the data was removed.
+        mActivityRule.getActivity().clearPreferences();
+        Assert.assertNull("Preferences were not cleared",
+            mActivityRule.getActivity().getPreference(KEY));
+    }
+}
diff --git a/tests/signature/Android.mk b/tests/signature/Android.mk
index 53ba50d..2e9f7de 100644
--- a/tests/signature/Android.mk
+++ b/tests/signature/Android.mk
@@ -22,68 +22,18 @@
 
 LOCAL_PACKAGE_NAME := CtsSignatureTestCases
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+# For CTS v1
+LOCAL_CTS_MODULE_CONFIG := $(LOCAL_PATH)/Old$(CTS_MODULE_TEST_CONFIG)
+
 LOCAL_SDK_VERSION := current
 
 LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
 
-# To be passed in on command line
-CTS_API_VERSION ?= current
-ifeq (current,$(CTS_API_VERSION))
-android_api_description := frameworks/base/api/$(CTS_API_VERSION).txt
-else
-android_api_description := $(SRC_API_DIR)/$(CTS_API_VERSION).txt
-endif
-
-# Can't call local-intermediates-dir directly here because we have to
-# include BUILD_CTS_PACKAGE first.  Can't include BUILD_CTS_PACKAGE first
-# because we have to override LOCAL_RESOURCE_DIR first.  Hence this
-# hack.
-intermediates.COMMON := $(call intermediates-dir-for,APPS,$(LOCAL_PACKAGE_NAME),,COMMON)
-signature_res_dir := $(intermediates.COMMON)/genres
-LOCAL_RESOURCE_DIR := $(signature_res_dir) $(LOCAL_PATH)/res
-
 include $(BUILD_CTS_PACKAGE)
 
-generated_res_stamp := $(intermediates.COMMON)/genres.stamp
-api_ver_file := $(intermediates.COMMON)/api_ver_is_$(CTS_API_VERSION)
-
-# The api_ver_file keeps track of which api version was last built.
-# By only ever having one of these magic files in existence and making
-# sure the generated resources rule depend on it, we can ensure that
-# the proper version of the api resource gets generated.
-$(api_ver_file):
-	$(hide) rm -f $(dir $@)/api_ver_is_* \
-		&& mkdir -p $(dir $@) && touch $@
-
-android_api_xml_description := $(intermediates.COMMON)/api.xml
-$(android_api_xml_description): $(android_api_description) | $(APICHECK)
-	@ echo "Convert api file to xml: $@"
-	@ mkdir -p $(dir $@)
-	$(hide) $(APICHECK_COMMAND) -convert2xml $< $@
-
-# Split up config/api/1.xml by "package" and save the files as the
-# resource files of SignatureTest.
-$(generated_res_stamp): PRIVATE_PATH := $(LOCAL_PATH)
-$(generated_res_stamp): PRIVATE_MODULE := $(LOCAL_MODULE)
-$(generated_res_stamp): PRIVATE_RES_DIR := $(signature_res_dir)
-$(generated_res_stamp): PRIVATE_API_XML_DESC := $(android_api_xml_description)
-$(generated_res_stamp): $(api_ver_file)
-$(generated_res_stamp): $(android_api_xml_description)
-	@ echo "Copy generated resources: $(PRIVATE_MODULE)"
-	$(hide) python cts/tools/utils/android_api_description_splitter.py \
-		$(PRIVATE_API_XML_DESC) $(PRIVATE_RES_DIR) package
-	$(hide) touch $@
-
-$(R_file_stamp): $(generated_res_stamp)
-
-# clean up temp vars
-android_api_xml_description :=
-api_ver_file :=
-generated_res_stamp :=
-signature_res_dir :=
-android_api_description :=
-CTS_API_VERSION :=
-
 # signature-hostside java library (for testing)
 # ============================================================
 
@@ -98,4 +48,6 @@
 
 LOCAL_MODULE_TAGS := optional
 
-include $(BUILD_HOST_JAVA_LIBRARY)
\ No newline at end of file
+include $(BUILD_HOST_JAVA_LIBRARY)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/signature/AndroidManifest.xml b/tests/signature/AndroidManifest.xml
index e42302e..52090ce 100644
--- a/tests/signature/AndroidManifest.xml
+++ b/tests/signature/AndroidManifest.xml
@@ -16,7 +16,7 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="android.signature">
+          package="android.signature.cts">
     <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
 
     <application>
@@ -24,7 +24,7 @@
     </application>
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="android.signature"
+                     android:targetPackage="android.signature.cts"
                      android:label="API Signature Test"/>
 
 </manifest>
\ No newline at end of file
diff --git a/tests/signature/AndroidTest.xml b/tests/signature/AndroidTest.xml
new file mode 100644
index 0000000..e3561cc
--- /dev/null
+++ b/tests/signature/AndroidTest.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS Signature test cases">
+    <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+        <option name="run-command" value="mkdir -p /data/local/tmp/signature-test" />
+        <option name="teardown-command" value="rm -rf /data/local/tmp/signature-test" />
+    </target_preparer>
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
+        <option name="push" value="current.api->/data/local/tmp/signature-test/current.api" />
+    </target_preparer>
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsSignatureTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.signature.cts" />
+        <option name="runtime-hint" value="1m11s" />
+    </test>
+</configuration>
diff --git a/tests/signature/OldAndroidTest.xml b/tests/signature/OldAndroidTest.xml
new file mode 100644
index 0000000..b4338da
--- /dev/null
+++ b/tests/signature/OldAndroidTest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS Signature test cases">
+    <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+        <option name="run-command" value="mkdir -p /data/local/tmp/signature-test" />
+        <option name="teardown-command" value="rm -rf /data/local/tmp/signature-test" />
+    </target_preparer>
+    <target_preparer class="com.android.cts.tradefed.targetprep.CtsFilePusher">
+        <option name="push" value="current.api->/data/local/tmp/signature-test/current.api" />
+    </target_preparer>
+</configuration>
diff --git a/tests/signature/api/Android.mk b/tests/signature/api/Android.mk
new file mode 100644
index 0000000..4e30cce
--- /dev/null
+++ b/tests/signature/api/Android.mk
@@ -0,0 +1,42 @@
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# We define this in a subdir so that it won't pick up the parent's Android.xml by default.
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+# current api, in XML format.
+# ============================================================
+include $(CLEAR_VARS)
+LOCAL_MODULE := cts-current-api
+LOCAL_MODULE_STEM := current.api
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_ETC)
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+include $(BUILD_SYSTEM)/base_rules.mk
+$(LOCAL_BUILT_MODULE) : frameworks/base/api/current.txt | $(APICHECK)
+	@echo "Convert API file $@"
+	@mkdir -p $(dir $@)
+	$(hide) $(APICHECK_COMMAND) -convert2xml $< $@
+
+# For CTS v1
+cts_api_xml_v1 := $(CTS_TESTCASES_OUT)/current.api
+$(cts_api_xml_v1):  $(LOCAL_BUILT_MODULE) | $(ACP)
+	$(call copy-file-to-new-target)
+
+$(CTS_TESTCASES_OUT)/CtsSignatureTestCases.xml: $(cts_api_xml_v1)
diff --git a/tests/signature/src/android/signature/cts/JDiffClassDescription.java b/tests/signature/src/android/signature/cts/JDiffClassDescription.java
index afcaa15..2e13650 100644
--- a/tests/signature/src/android/signature/cts/JDiffClassDescription.java
+++ b/tests/signature/src/android/signature/cts/JDiffClassDescription.java
@@ -462,7 +462,7 @@
      * @param apiMethod the method read from the api file.
      * @param reflectedMethod the method found via reflections.
      */
-    private boolean areMethodModifiedCompatibile(JDiffMethod apiMethod ,
+    private boolean areMethodsModifiedCompatible(JDiffMethod apiMethod ,
             Method reflectedMethod) {
 
         // If the apiMethod isn't synchronized
@@ -475,10 +475,11 @@
 
         // Mask off NATIVE since it is a don't care.  Also mask off
         // SYNCHRONIZED since we've already handled that check.
-        int mod1 = reflectedMethod.getModifiers() & ~(Modifier.NATIVE | Modifier.SYNCHRONIZED);
-        int mod2 = apiMethod.mModifier & ~(Modifier.NATIVE | Modifier.SYNCHRONIZED);
+        int ignoredMods = (Modifier.NATIVE | Modifier.SYNCHRONIZED | Modifier.STRICT);
+        int mod1 = reflectedMethod.getModifiers() & ~ignoredMods;
+        int mod2 = apiMethod.mModifier & ~ignoredMods;
 
-        // We can ignore FINAL for final classes
+        // We can ignore FINAL for classes
         if ((mModifier & Modifier.FINAL) != 0) {
             mod1 &= ~Modifier.FINAL;
             mod2 &= ~Modifier.FINAL;
@@ -494,10 +495,6 @@
     private void checkMethodCompliance() {
         for (JDiffMethod method : jDiffMethods) {
             try {
-                // this is because jdiff think a method in an interface is not abstract
-                if (JDiffType.INTERFACE.equals(mClassType)) {
-                    method.mModifier |= Modifier.ABSTRACT;
-                }
 
                 Method m = findMatchingMethod(method);
                 if (m == null) {
@@ -521,7 +518,7 @@
                         return;
                     }
 
-                    if (!areMethodModifiedCompatibile(method, m)) {
+                    if (!areMethodsModifiedCompatible(method, m)) {
                         mResultObserver.notifyFailure(FailureType.MISMATCH_METHOD,
                                 method.toReadableString(mAbsoluteClassName),
                                 "Non-compatible method found when looking for " +
@@ -544,35 +541,62 @@
      * @param method the reflected method to compare
      * @return true, if both methods are the same
      */
-    private boolean matches(JDiffMethod jDiffMethod, Method method) {
+    private boolean matches(JDiffMethod jDiffMethod, Method reflectedMethod) {
         // If the method names aren't equal, the methods can't match.
-        if (jDiffMethod.mName.equals(method.getName())) {
-            String jdiffReturnType = jDiffMethod.mReturnType;
-            String reflectionReturnType = typeToString(method.getGenericReturnType());
-            List<String> jdiffParamList = jDiffMethod.mParamList;
-
-            // Next, compare the return types of the two methods.  If
-            // they aren't equal, the methods can't match.
-            if (jdiffReturnType.equals(reflectionReturnType)) {
-                Type[] params = method.getGenericParameterTypes();
-                // Next, check the method parameters.  If they have
-                // different number of parameters, the two methods
-                // can't match.
-                if (jdiffParamList.size() == params.length) {
-                    // If any of the parameters don't match, the
-                    // methods can't match.
-                    for (int i = 0; i < jdiffParamList.size(); i++) {
-                        if (!compareParam(jdiffParamList.get(i), params[i])) {
-                            return false;
-                        }
-                    }
-                    // We've passed all the tests, the methods do
-                    // match.
-                    return true;
-                }
-            }
+        if (!jDiffMethod.mName.equals(reflectedMethod.getName())) {
+            return false;
         }
-        return false;
+        String jdiffReturnType = jDiffMethod.mReturnType;
+        String reflectionReturnType = typeToString(reflectedMethod.getGenericReturnType());
+        List<String> jdiffParamList = jDiffMethod.mParamList;
+
+        // Next, compare the return types of the two methods.  If
+        // they aren't equal, the methods can't match.
+        if (!jdiffReturnType.equals(reflectionReturnType)) {
+            return false;
+        }
+
+        Type[] params = reflectedMethod.getGenericParameterTypes();
+
+        // Next, check the method parameters.  If they have different
+        // parameter lengths, the two methods can't match.
+        if (jdiffParamList.size() != params.length) {
+            return false;
+        }
+
+        boolean piecewiseParamsMatch = true;
+
+        // Compare method parameters piecewise and return true if they all match.
+        for (int i = 0; i < jdiffParamList.size(); i++) {
+            piecewiseParamsMatch &= compareParam(jdiffParamList.get(i), params[i]);
+        }
+        if (piecewiseParamsMatch) {
+            return true;
+        }
+
+        /** NOTE: There are cases where piecewise method parameter checking
+         * fails even though the strings are equal, so compare entire strings
+         * against each other. This is not done by default to avoid a
+         * TransactionTooLargeException.
+         * Additionally, this can fail anyway due to extra
+         * information dug up by reflection.
+         *
+         * TODO: fix parameter equality checking and reflection matching
+         * See https://b.corp.google.com/issues/27726349
+         */
+
+        StringBuilder reflectedMethodParams = new StringBuilder("");
+        StringBuilder jdiffMethodParams = new StringBuilder("");
+
+        for (int i = 0; i < jdiffParamList.size(); i++) {
+            jdiffMethodParams.append(jdiffParamList.get(i));
+            reflectedMethodParams.append(params[i]);
+        }
+
+        String jDiffFName = jdiffMethodParams.toString();
+        String refName = reflectedMethodParams.toString();
+
+        return jDiffFName.equals(refName);
     }
 
     /**
diff --git a/tests/signature/src/android/signature/cts/SignatureTest.java b/tests/signature/src/android/signature/cts/SignatureTest.java
index 85b77f8..139fb30 100644
--- a/tests/signature/src/android/signature/cts/SignatureTest.java
+++ b/tests/signature/src/android/signature/cts/SignatureTest.java
@@ -17,7 +17,6 @@
 package android.signature.cts;
 
 import android.content.res.Resources;
-import android.signature.R;
 import android.signature.cts.JDiffClassDescription.JDiffConstructor;
 import android.signature.cts.JDiffClassDescription.JDiffField;
 import android.signature.cts.JDiffClassDescription.JDiffMethod;
@@ -26,13 +25,17 @@
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlPullParserFactory;
 
+import java.io.File;
+import java.io.FileInputStream;
 import java.io.IOException;
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashSet;
+import java.util.Scanner;
 
 /**
  * Performs the signature check via a JUnit test.
@@ -40,6 +43,7 @@
 public class SignatureTest extends AndroidTestCase {
 
     private static final String TAG = SignatureTest.class.getSimpleName();
+    private static final String CURRENT_API_FILE = "/data/local/tmp/signature-test/current.api";
 
     private static final String TAG_ROOT = "api";
     private static final String TAG_PACKAGE = "package";
@@ -104,25 +108,21 @@
      * Will check the entire API, and then report the complete list of failures
      */
     public void testSignature() {
-        Resources r = getContext().getResources();
-        Class rClass = R.xml.class;
-        logd(String.format("Class: %s", rClass.toString()));
-        Field[] fs = rClass.getFields();
-        for (Field f : fs) {
-            logd(String.format("Field: %s", f.toString()));
-            try {
-                start(r.getXml(f.getInt(rClass)));
-            } catch (Exception e) {
-                mResultObserver.notifyFailure(FailureType.CAUGHT_EXCEPTION, e.getMessage(),
-                        e.getMessage());
-            }
+        try {
+            XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
+            XmlPullParser parser = factory.newPullParser();
+            parser.setInput(new FileInputStream(new File(CURRENT_API_FILE)), null);
+            start(parser);
+        } catch (Exception e) {
+            mResultObserver.notifyFailure(FailureType.CAUGHT_EXCEPTION, e.getMessage(),
+                    e.getMessage());
         }
         if (mResultObserver.mDidFail) {
             fail(mResultObserver.mErrorString.toString());
         }
     }
 
-    private  void beginDocument(XmlPullParser parser, String firstElementName)
+    private void beginDocument(XmlPullParser parser, String firstElementName)
             throws XmlPullParserException, IOException {
         int type;
         while ((type=parser.next()) != XmlPullParser.START_TAG
diff --git a/tests/signature-tests/Android.mk b/tests/signature/tests/Android.mk
similarity index 100%
rename from tests/signature-tests/Android.mk
rename to tests/signature/tests/Android.mk
diff --git a/tests/signature-tests/run_unit_tests.sh b/tests/signature/tests/run_unit_tests.sh
similarity index 100%
rename from tests/signature-tests/run_unit_tests.sh
rename to tests/signature/tests/run_unit_tests.sh
diff --git a/tests/signature-tests/src/android/signature/cts/tests/AllTests.java b/tests/signature/tests/src/android/signature/cts/tests/AllTests.java
similarity index 100%
rename from tests/signature-tests/src/android/signature/cts/tests/AllTests.java
rename to tests/signature/tests/src/android/signature/cts/tests/AllTests.java
diff --git a/tests/signature-tests/src/android/signature/cts/tests/JDiffClassDescriptionTest.java b/tests/signature/tests/src/android/signature/cts/tests/JDiffClassDescriptionTest.java
similarity index 100%
rename from tests/signature-tests/src/android/signature/cts/tests/JDiffClassDescriptionTest.java
rename to tests/signature/tests/src/android/signature/cts/tests/JDiffClassDescriptionTest.java
diff --git a/tests/signature-tests/src/android/signature/cts/tests/data/AbstractClass.java b/tests/signature/tests/src/android/signature/cts/tests/data/AbstractClass.java
similarity index 100%
rename from tests/signature-tests/src/android/signature/cts/tests/data/AbstractClass.java
rename to tests/signature/tests/src/android/signature/cts/tests/data/AbstractClass.java
diff --git a/tests/signature-tests/src/android/signature/cts/tests/data/FinalClass.java b/tests/signature/tests/src/android/signature/cts/tests/data/FinalClass.java
similarity index 100%
rename from tests/signature-tests/src/android/signature/cts/tests/data/FinalClass.java
rename to tests/signature/tests/src/android/signature/cts/tests/data/FinalClass.java
diff --git a/tests/signature-tests/src/android/signature/cts/tests/data/NormalClass.java b/tests/signature/tests/src/android/signature/cts/tests/data/NormalClass.java
similarity index 100%
rename from tests/signature-tests/src/android/signature/cts/tests/data/NormalClass.java
rename to tests/signature/tests/src/android/signature/cts/tests/data/NormalClass.java
diff --git a/tests/signature-tests/src/android/signature/cts/tests/data/NormalException.java b/tests/signature/tests/src/android/signature/cts/tests/data/NormalException.java
similarity index 100%
rename from tests/signature-tests/src/android/signature/cts/tests/data/NormalException.java
rename to tests/signature/tests/src/android/signature/cts/tests/data/NormalException.java
diff --git a/tests/signature-tests/src/android/signature/cts/tests/data/NormalInterface.java b/tests/signature/tests/src/android/signature/cts/tests/data/NormalInterface.java
similarity index 100%
rename from tests/signature-tests/src/android/signature/cts/tests/data/NormalInterface.java
rename to tests/signature/tests/src/android/signature/cts/tests/data/NormalInterface.java
diff --git a/tests/simplecpu/Android.mk b/tests/simplecpu/Android.mk
new file mode 100644
index 0000000..7183b2c
--- /dev/null
+++ b/tests/simplecpu/Android.mk
@@ -0,0 +1,39 @@
+# Copyright (C) 2012 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+# don't include this package in any target
+LOCAL_MODULE_TAGS := tests
+
+# Include both the 32 and 64 bit versions
+LOCAL_MULTILIB := both
+
+LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil compatibility-device-util ctstestrunner
+
+LOCAL_JNI_SHARED_LIBRARIES := libctscpu_jni
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := CtsSimpleCpuTestCases
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_SDK_VERSION := 16
+
+include $(BUILD_CTS_PACKAGE)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/simplecpu/AndroidManifest.xml b/tests/simplecpu/AndroidManifest.xml
new file mode 100644
index 0000000..4b5febf
--- /dev/null
+++ b/tests/simplecpu/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="android.simplecpu.cts">
+
+    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+            android:targetPackage="android.simplecpu.cts"
+            android:label="CTS tests for simple CPU" />
+</manifest>
diff --git a/tests/simplecpu/AndroidTest.xml b/tests/simplecpu/AndroidTest.xml
new file mode 100644
index 0000000..2a347f2
--- /dev/null
+++ b/tests/simplecpu/AndroidTest.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS File System test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsSimpleCpuTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.simplecpu.cts" />
+        <option name="runtime-hint" value="6m51s" />
+    </test>
+</configuration>
diff --git a/suite/cts/deviceTests/simplecpu/jni/Android.mk b/tests/simplecpu/jni/Android.mk
similarity index 100%
rename from suite/cts/deviceTests/simplecpu/jni/Android.mk
rename to tests/simplecpu/jni/Android.mk
diff --git a/tests/simplecpu/jni/CpuNativeJni.cpp b/tests/simplecpu/jni/CpuNativeJni.cpp
new file mode 100644
index 0000000..4ea0dc0
--- /dev/null
+++ b/tests/simplecpu/jni/CpuNativeJni.cpp
@@ -0,0 +1,270 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 <jni.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/time.h>
+
+/* Code from now to qsort_local all copied from bionic source.
+ * The code is duplicated here to remove dependency on optimized bionic
+ */
+static __inline char    *med3(char *, char *, char *, int (*)(const void *, const void *));
+static __inline void     swapfunc(char *, char *, int, int);
+
+#define min(a, b)   (a) < (b) ? a : b
+
+/*
+ * Qsort routine from Bentley & McIlroy's "Engineering a Sort Function".
+ */
+#define swapcode(TYPE, parmi, parmj, n) {       \
+    long i = (n) / sizeof (TYPE);           \
+    TYPE *pi = (TYPE *) (parmi);            \
+    TYPE *pj = (TYPE *) (parmj);            \
+    do {                        \
+        TYPE    t = *pi;            \
+        *pi++ = *pj;                \
+        *pj++ = t;              \
+        } while (--i > 0);              \
+}
+
+#define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \
+    es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1;
+
+static __inline void
+swapfunc(char *a, char *b, int n, int swaptype)
+{
+    if (swaptype <= 1)
+        swapcode(long, a, b, n)
+    else
+        swapcode(char, a, b, n)
+}
+
+#define swap(a, b)                  \
+    if (swaptype == 0) {                \
+        long t = *(long *)(a);          \
+        *(long *)(a) = *(long *)(b);        \
+        *(long *)(b) = t;           \
+    } else                      \
+        swapfunc(a, b, es, swaptype)
+
+#define vecswap(a, b, n)    if ((n) > 0) swapfunc(a, b, n, swaptype)
+
+static __inline char *
+med3(char *a, char *b, char *c, int (*cmp)(const void *, const void *))
+{
+    return cmp(a, b) < 0 ?
+           (cmp(b, c) < 0 ? b : (cmp(a, c) < 0 ? c : a ))
+              :(cmp(b, c) > 0 ? b : (cmp(a, c) < 0 ? a : c ));
+}
+
+void
+qsort_local(void *aa, size_t n, size_t es, int (*cmp)(const void *, const void *))
+{
+    char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
+    int d, r, swaptype, swap_cnt;
+    char *a = (char*)aa;
+
+loop:   SWAPINIT(a, es);
+    swap_cnt = 0;
+    if (n < 7) {
+        for (pm = (char *)a + es; pm < (char *) a + n * es; pm += es)
+            for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0;
+                 pl -= es)
+                swap(pl, pl - es);
+        return;
+    }
+    pm = (char *)a + (n / 2) * es;
+    if (n > 7) {
+        pl = (char *)a;
+        pn = (char *)a + (n - 1) * es;
+        if (n > 40) {
+            d = (n / 8) * es;
+            pl = med3(pl, pl + d, pl + 2 * d, cmp);
+            pm = med3(pm - d, pm, pm + d, cmp);
+            pn = med3(pn - 2 * d, pn - d, pn, cmp);
+        }
+        pm = med3(pl, pm, pn, cmp);
+    }
+    swap(a, pm);
+    pa = pb = (char *)a + es;
+
+    pc = pd = (char *)a + (n - 1) * es;
+    for (;;) {
+        while (pb <= pc && (r = cmp(pb, a)) <= 0) {
+            if (r == 0) {
+                swap_cnt = 1;
+                swap(pa, pb);
+                pa += es;
+            }
+            pb += es;
+        }
+        while (pb <= pc && (r = cmp(pc, a)) >= 0) {
+            if (r == 0) {
+                swap_cnt = 1;
+                swap(pc, pd);
+                pd -= es;
+            }
+            pc -= es;
+        }
+        if (pb > pc)
+            break;
+        swap(pb, pc);
+        swap_cnt = 1;
+        pb += es;
+        pc -= es;
+    }
+    if (swap_cnt == 0) {  /* Switch to insertion sort */
+        for (pm = (char *) a + es; pm < (char *) a + n * es; pm += es)
+            for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0;
+                 pl -= es)
+                swap(pl, pl - es);
+        return;
+    }
+
+    pn = (char *)a + n * es;
+    r = min(pa - (char *)a, pb - pa);
+    vecswap(a, pb - r, r);
+    r = min(pd - pc, pn - pd - (int)es);
+    vecswap(pb, pn - r, r);
+    if ((r = pb - pa) > (int)es)
+        qsort_local(a, r / es, es, cmp);
+    if ((r = pd - pc) > (int)es) {
+        /* Iterate rather than recurse to save stack space */
+        a = pn - r;
+        n = r / es;
+        goto loop;
+    }
+    /* qsort(pn - r, r / es, es, cmp); */
+}
+
+/* code duplication ends here */
+
+/**
+ * Util for getting time stamp
+ */
+double currentTimeMillis()
+{
+    struct timeval tv;
+    gettimeofday(&tv, (struct timezone *) NULL);
+    return tv.tv_sec * 1000.0 + tv.tv_usec / 1000.0;
+}
+
+/**
+ * Initialize given array randomly for the given seed
+ */
+template <typename T> void randomInitArray(T* array, int len, unsigned int seed)
+{
+    srand(seed);
+    for (int i = 0; i < len; i++) {
+        array[i] = (T) rand();
+    }
+}
+
+/**
+ * comparison function for int, for qsort
+ */
+int cmpint(const void* p1, const void* p2)
+{
+    return *(int*)p1 - *(int*)p2;
+}
+
+extern "C" JNIEXPORT jdouble JNICALL Java_android_simplecpu_cts_CpuNative_runSort(JNIEnv* env,
+        jclass clazz, jint numberElements, jint repetition)
+{
+    int* data = new int[numberElements];
+    if (data == NULL) {
+        env->ThrowNew(env->FindClass("java/lang/OutOfMemoryError"), "No memory");
+        return -1;
+    }
+    double totalTime = 0;
+    for (int i = 0; i < repetition; i++) {
+        randomInitArray<int>(data, numberElements, 0);
+        double start = currentTimeMillis();
+        qsort_local(data, numberElements, sizeof(int), cmpint);
+        double end = currentTimeMillis();
+        totalTime += (end - start);
+    }
+    delete[] data;
+    return totalTime;
+}
+
+
+/**
+ * Do matrix multiplication, C = A x B with all matrices having dimension of n x n
+ * The implementation is not in the most efficient, but it is good enough for benchmarking purpose.
+ * @param n should be multiple of 8
+ */
+void doMatrixMultiplication(float* A, float* B, float* C, int n)
+{
+    // batch size
+    const int M = 8;
+    for (int i = 0; i < n; i++) {
+        for (int j = 0; j < n; j += M) {
+            float sum[M];
+            for (int k = 0; k < M; k++) {
+                sum[k] = 0;
+            }
+            // re-use the whole cache line for accessing B.
+            // otherwise, the whole line will be read and only one value will be used.
+
+            for (int k = 0; k < n; k++) {
+                float a = A[i * n + k];
+                sum[0] += a * B[k * n + j];
+                sum[1] += a * B[k * n + j + 1];
+                sum[2] += a * B[k * n + j + 2];
+                sum[3] += a * B[k * n + j + 3];
+                sum[4] += a * B[k * n + j + 4];
+                sum[5] += a * B[k * n + j + 5];
+                sum[6] += a * B[k * n + j + 6];
+                sum[7] += a * B[k * n + j + 7];
+            }
+            for (int k = 0; k < M; k++) {
+                C[i * n + j + k] = sum[k];
+            }
+        }
+    }
+}
+
+extern "C" JNIEXPORT jdouble JNICALL Java_android_simplecpu_cts_CpuNative_runMatrixMultiplication(
+        JNIEnv* env, jclass clazz, jint n, jint repetition)
+{
+    // C = A x B
+    float* A = new float[n * n];
+    float* B = new float[n * n];
+    float* C = new float[n * n];
+    if ((A == NULL) || (B == NULL) || (C == NULL)) {
+        delete[] A;
+        delete[] B;
+        delete[] C;
+        env->ThrowNew(env->FindClass("java/lang/OutOfMemoryError"), "No memory");
+        return -1;
+    }
+    double totalTime = 0;
+    for (int i = 0; i < repetition; i++) {
+        randomInitArray<float>(A, n * n, 0);
+        randomInitArray<float>(B, n * n, 1);
+        double start = currentTimeMillis();
+        doMatrixMultiplication(A, B, C, n);
+        double end = currentTimeMillis();
+        totalTime += (end - start);
+    }
+    delete[] A;
+    delete[] B;
+    delete[] C;
+    return totalTime;
+}
+
diff --git a/tests/simplecpu/src/android/simplecpu/cts/CpuNative.java b/tests/simplecpu/src/android/simplecpu/cts/CpuNative.java
new file mode 100644
index 0000000..231cba6
--- /dev/null
+++ b/tests/simplecpu/src/android/simplecpu/cts/CpuNative.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.simplecpu.cts;
+
+public class CpuNative {
+    static {
+        System.loadLibrary("ctscpu_jni");
+    }
+    /**
+     * run qsort for given number of repetition
+     * with each having the size of bufferSize.
+     * @param numberElements
+     * @param repeatition
+     * @return time taken for computation, added for all repetition in ms
+     */
+    public static native double runSort(int numberElements, int repetition);
+
+    /**
+     * run matrix multiplication of (n x n) x (n x n)
+     *
+     * @param n dimension, should be multiple of 8
+     * @param repetition
+     * @return time taken for computation, added for all repetition in ms
+     */
+    public static native double runMatrixMultiplication(int n, int repetition);
+}
diff --git a/tests/simplecpu/src/android/simplecpu/cts/SimpleCpuTest.java b/tests/simplecpu/src/android/simplecpu/cts/SimpleCpuTest.java
new file mode 100644
index 0000000..fa7f402
--- /dev/null
+++ b/tests/simplecpu/src/android/simplecpu/cts/SimpleCpuTest.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.simplecpu.cts;
+
+import android.cts.util.CtsAndroidTestCase;
+import android.util.Log;
+
+import com.android.compatibility.common.util.DeviceReportLog;
+import com.android.compatibility.common.util.ResultType;
+import com.android.compatibility.common.util.ResultUnit;
+import com.android.compatibility.common.util.Stat;
+import com.android.cts.util.TimeoutReq;
+
+/**
+ * Very simple CPU benchmarking to check the basic capability of CPU.
+ * Cases include
+ *   qsort
+ *   matrix multiplication (for floating point performance)
+ */
+public class SimpleCpuTest extends CtsAndroidTestCase {
+    private static final String TAG = "BandwidthTest";
+    private static final int KB = 1024;
+    private static final int MB = 1024 * 1024;
+    private static final int NUMBER_REPEAT = 20;
+    // reject data outside +/- this value * median
+    private static final double OUTLIER_THRESHOLD = 0.1;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        warmUpCpu();
+    }
+
+    public void testSort004KB() {
+        doTestSort(NUMBER_REPEAT, 4 * KB);
+    }
+
+    public void testSort128KB() {
+        doTestSort(NUMBER_REPEAT, 128 * KB);
+    }
+
+    public void testSort001MB() {
+        doTestSort(NUMBER_REPEAT, 1 * MB);
+    }
+
+    // will fit into L1
+    public void testMatrixMultiplication032() {
+        doMatrixMultiplication(NUMBER_REPEAT, 32);
+    }
+
+    // mostly fit into L2
+    public void testMatrixMultiplication128() {
+        doMatrixMultiplication(NUMBER_REPEAT, 128);
+    }
+
+    // may fit into L2
+    public void testMatrixMultiplication200() {
+        doMatrixMultiplication(NUMBER_REPEAT, 200);
+    }
+
+    public void testMatrixMultiplication400() {
+        doMatrixMultiplication(NUMBER_REPEAT, 400);
+    }
+
+    // will exceed L2
+    @TimeoutReq(minutes = 30)
+    public void testMatrixMultiplication600() {
+        doMatrixMultiplication(NUMBER_REPEAT, 600);
+    }
+
+    /**
+     * run some code to force full CPU freq.
+     */
+    private void warmUpCpu() {
+        CpuNative.runSort(1 * MB, 10);
+    }
+
+    /**
+     * qsort test
+     * @param numberRepeat
+     * @param arrayLength
+     */
+    private void doTestSort(int numberRepeat, int arrayLength) {
+        final int numberRepeatInEachCall = 10;
+        double[] result = new double[numberRepeat];
+        for (int i = 0; i < numberRepeat; i++) {
+            result[i] = CpuNative.runSort(arrayLength, numberRepeatInEachCall);
+        }
+        DeviceReportLog report = new DeviceReportLog();
+        report.addValues("sorting time", result, ResultType.LOWER_BETTER, ResultUnit.MS);
+        Stat.StatResult stat = Stat.getStatWithOutlierRejection(result, OUTLIER_THRESHOLD);
+        if (stat.mDataCount != result.length) {
+            Log.w(TAG, "rejecting " + (result.length - stat.mDataCount) + " outliers");
+        }
+        report.setSummary("sorting time", stat.mAverage, ResultType.LOWER_BETTER, ResultUnit.MS);
+        report.submit(getInstrumentation());
+    }
+
+    /**
+     * Matrix multiplication test, nxn matrix multiplication
+     * @param numberRepeat
+     * @param n should be multiple of 8
+     */
+    private void doMatrixMultiplication(int numberRepeat, int n) {
+        assertTrue(n % 8 == 0);
+        final int numberRepeatInEachCall = 10;
+        double[] result = new double[numberRepeat];
+        for (int i = 0; i < numberRepeat; i++) {
+            result[i] = CpuNative.runMatrixMultiplication(n, numberRepeatInEachCall);
+        }
+        DeviceReportLog report = new DeviceReportLog();
+        report.addValues("matrix mutiplication time", result, ResultType.LOWER_BETTER,
+                ResultUnit.MS);
+        Stat.StatResult stat = Stat.getStatWithOutlierRejection(result, OUTLIER_THRESHOLD);
+        if (stat.mDataCount != result.length) {
+            Log.w(TAG, "rejecting " + (result.length - stat.mDataCount) + " outliers");
+        }
+        report.setSummary("matrix mutiplication time", stat.mAverage,
+                ResultType.LOWER_BETTER, ResultUnit.MS);
+        report.submit(getInstrumentation());
+    }
+
+}
diff --git a/tests/tests/acceleration/Android.mk b/tests/tests/acceleration/Android.mk
deleted file mode 100644
index d417371..0000000
--- a/tests/tests/acceleration/Android.mk
+++ /dev/null
@@ -1,33 +0,0 @@
-# Copyright (C) 2011 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-
-LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_PACKAGE_NAME := CtsAccelerationTestCases
-
-LOCAL_INSTRUMENTATION_FOR := CtsAccelerationTestStubs
-
-LOCAL_SDK_VERSION := current
-
-include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/acceleration/AndroidManifest.xml b/tests/tests/acceleration/AndroidManifest.xml
deleted file mode 100644
index 0dd2722..0000000
--- a/tests/tests/acceleration/AndroidManifest.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-        package="com.android.cts.acceleration">
-
-  <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
-  <application>
-      <uses-library android:name="android.test.runner" />
-  </application>
-
-  <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                   android:targetPackage="com.android.cts.acceleration.stub"
-                   android:label="Tests for the Hardware Acceleration APIs." >
-        <meta-data android:name="listener"
-            android:value="com.android.cts.runner.CtsTestRunListener" />
-    </instrumentation>
-
-</manifest>
diff --git a/tests/tests/acceleration/src/android/acceleration/cts/BaseAccelerationTest.java b/tests/tests/acceleration/src/android/acceleration/cts/BaseAccelerationTest.java
deleted file mode 100644
index d2f1d9f..0000000
--- a/tests/tests/acceleration/src/android/acceleration/cts/BaseAccelerationTest.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.acceleration.cts;
-
-import android.app.ActivityManager;
-import android.content.Context;
-import android.content.pm.ConfigurationInfo;
-import android.content.pm.FeatureInfo;
-import android.test.ActivityInstrumentationTestCase2;
-import android.view.View;
-
-abstract class BaseAccelerationTest<B extends BaseAcceleratedActivity>
-        extends ActivityInstrumentationTestCase2<B> {
-
-    protected B mActivity;
-
-    /** View with android:layerType="hardware" set */
-    protected AcceleratedView mHardwareView;
-
-    /** View with android:layerType="software" set */
-    protected AcceleratedView mSoftwareView;
-
-    /** View with setLayerType(HARDWARE) called */
-    protected AcceleratedView mManualHardwareView;
-
-    /** View with setLayerType(SOFTWARE) called */
-    protected AcceleratedView mManualSoftwareView;
-
-    BaseAccelerationTest(Class<B> clazz) {
-        super(clazz);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mActivity = getActivity();
-        mHardwareView = mActivity.getHardwareAcceleratedView();
-        mSoftwareView = mActivity.getSoftwareAcceleratedView();
-        mManualHardwareView = mActivity.getManualHardwareAcceleratedView();
-        mManualSoftwareView = mActivity.getManualSoftwareAcceleratedView();
-    }
-
-    public void testNotAttachedView() {
-        // Views that are not attached can't be attached to an accelerated window.
-        View view = new View(mActivity);
-        assertFalse(view.isHardwareAccelerated());
-    }
-
-    protected static int getGlEsVersion(Context context) {
-        ActivityManager activityManager =
-                (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
-        ConfigurationInfo configInfo = activityManager.getDeviceConfigurationInfo();
-        if (configInfo.reqGlEsVersion != ConfigurationInfo.GL_ES_VERSION_UNDEFINED) {
-            return getMajorVersion(configInfo.reqGlEsVersion);
-        } else {
-            return 1; // Lack of property means OpenGL ES version 1
-        }
-    }
-
-    /** @see FeatureInfo#getGlEsVersion() */
-    private static int getMajorVersion(int glEsVersion) {
-        return ((glEsVersion & 0xffff0000) >> 16);
-    }
-}
diff --git a/tests/tests/acceleration/src/android/acceleration/cts/HardwareAccelerationTest.java b/tests/tests/acceleration/src/android/acceleration/cts/HardwareAccelerationTest.java
deleted file mode 100644
index eddd34f..0000000
--- a/tests/tests/acceleration/src/android/acceleration/cts/HardwareAccelerationTest.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.acceleration.cts;
-
-/**
- * Test that uses an Activity with hardware acceleration enabled.
- */
-public class HardwareAccelerationTest
-        extends BaseAccelerationTest<HardwareAcceleratedActivity> {
-
-    public HardwareAccelerationTest() {
-        super(HardwareAcceleratedActivity.class);
-    }
-
-    public void testIsHardwareAccelerated() {
-        // Hardware acceleration should be available on devices with GL ES 2 or higher...
-        if (getGlEsVersion(mActivity) >= 2) {
-            // Both of the views are attached to a hardware accelerated window
-            assertTrue(mHardwareView.isHardwareAccelerated());
-            assertTrue(mSoftwareView.isHardwareAccelerated());
-            assertTrue(mManualHardwareView.isHardwareAccelerated());
-            assertTrue(mManualSoftwareView.isHardwareAccelerated());
-
-            assertTrue(mHardwareView.isCanvasHardwareAccelerated());
-            assertFalse(mSoftwareView.isCanvasHardwareAccelerated());
-            assertTrue(mManualHardwareView.isCanvasHardwareAccelerated());
-            assertFalse(mManualSoftwareView.isCanvasHardwareAccelerated());
-        } else {
-            assertFalse(mHardwareView.isHardwareAccelerated());
-            assertFalse(mSoftwareView.isHardwareAccelerated());
-            assertFalse(mManualHardwareView.isHardwareAccelerated());
-            assertFalse(mManualSoftwareView.isHardwareAccelerated());
-
-            assertFalse(mHardwareView.isCanvasHardwareAccelerated());
-            assertFalse(mSoftwareView.isCanvasHardwareAccelerated());
-            assertFalse(mManualHardwareView.isCanvasHardwareAccelerated());
-            assertFalse(mManualSoftwareView.isCanvasHardwareAccelerated());
-        }
-    }
-}
diff --git a/tests/tests/acceleration/src/android/acceleration/cts/SoftwareAccelerationTest.java b/tests/tests/acceleration/src/android/acceleration/cts/SoftwareAccelerationTest.java
deleted file mode 100644
index 146fa6a..0000000
--- a/tests/tests/acceleration/src/android/acceleration/cts/SoftwareAccelerationTest.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.acceleration.cts;
-
-/**
- * Test that uses an Activity with hardware acceleration explicitly disabled
- * and makes sure that all views are rendered using software acceleration.
- */
-public class SoftwareAccelerationTest
-        extends BaseAccelerationTest<SoftwareAcceleratedActivity> {
-
-    public SoftwareAccelerationTest() {
-        super(SoftwareAcceleratedActivity.class);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mActivity = getActivity();
-    }
-
-    public void testIsHardwareAccelerated() {
-        // Both of the views are not attached to a hardware accelerated window
-        assertFalse(mHardwareView.isHardwareAccelerated());
-        assertFalse(mSoftwareView.isHardwareAccelerated());
-        assertFalse(mManualHardwareView.isHardwareAccelerated());
-        assertFalse(mManualSoftwareView.isHardwareAccelerated());
-
-        assertFalse(mHardwareView.isCanvasHardwareAccelerated());
-        assertFalse(mSoftwareView.isCanvasHardwareAccelerated());
-        assertFalse(mManualHardwareView.isCanvasHardwareAccelerated());
-        assertFalse(mManualSoftwareView.isCanvasHardwareAccelerated());
-    }
-}
diff --git a/tests/tests/acceleration/src/android/acceleration/cts/WindowFlagHardwareAccelerationTest.java b/tests/tests/acceleration/src/android/acceleration/cts/WindowFlagHardwareAccelerationTest.java
deleted file mode 100644
index bfbbe63..0000000
--- a/tests/tests/acceleration/src/android/acceleration/cts/WindowFlagHardwareAccelerationTest.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.acceleration.cts;
-
-/**
- * Test that uses an Activity with hardware acceleration enabled.
- */
-public class WindowFlagHardwareAccelerationTest
-        extends BaseAccelerationTest<WindowFlagHardwareAcceleratedActivity> {
-
-    public WindowFlagHardwareAccelerationTest() {
-        super(WindowFlagHardwareAcceleratedActivity.class);
-    }
-
-    public void testIsHardwareAccelerated() {
-        // Hardware acceleration should be available on devices with GL ES 2 or higher...
-        if (getGlEsVersion(mActivity) >= 2) {
-            // Both of the views are attached to a hardware accelerated window
-            assertTrue(mHardwareView.isHardwareAccelerated());
-            assertTrue(mSoftwareView.isHardwareAccelerated());
-            assertTrue(mManualHardwareView.isHardwareAccelerated());
-            assertTrue(mManualSoftwareView.isHardwareAccelerated());
-
-            assertTrue(mHardwareView.isCanvasHardwareAccelerated());
-            assertFalse(mSoftwareView.isCanvasHardwareAccelerated());
-            assertTrue(mManualHardwareView.isCanvasHardwareAccelerated());
-            assertFalse(mManualSoftwareView.isCanvasHardwareAccelerated());
-        } else {
-            assertFalse(mHardwareView.isHardwareAccelerated());
-            assertFalse(mSoftwareView.isHardwareAccelerated());
-            assertFalse(mManualHardwareView.isHardwareAccelerated());
-            assertFalse(mManualSoftwareView.isHardwareAccelerated());
-
-            assertFalse(mHardwareView.isCanvasHardwareAccelerated());
-            assertFalse(mSoftwareView.isCanvasHardwareAccelerated());
-            assertFalse(mManualHardwareView.isCanvasHardwareAccelerated());
-            assertFalse(mManualSoftwareView.isCanvasHardwareAccelerated());
-        }
-    }
-}
diff --git a/tests/tests/accessibility/Android.mk b/tests/tests/accessibility/Android.mk
deleted file mode 100644
index 263c47b..0000000
--- a/tests/tests/accessibility/Android.mk
+++ /dev/null
@@ -1,31 +0,0 @@
-# Copyright (C) 2012 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_PACKAGE_NAME := CtsAccessibilityTestCases
-
-LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctstestrunner
-
-LOCAL_SDK_VERSION := current
-
-include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/accessibility/AndroidManifest.xml b/tests/tests/accessibility/AndroidManifest.xml
deleted file mode 100644
index b3bcbc8..0000000
--- a/tests/tests/accessibility/AndroidManifest.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="android.view.cts.accessibility">
-
-    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
-
-    <application android:theme="@android:style/Theme.Holo.NoActionBar" >
-        <uses-library android:name="android.test.runner"/>
-    </application>
-
-    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="android.view.cts.accessibility"
-                     android:label="Tests for the accessibility APIs.">
-        <meta-data android:name="listener"
-                   android:value="com.android.cts.runner.CtsTestRunListener" />
-    </instrumentation>
-
-</manifest>
diff --git a/tests/tests/accessibility/AndroidTest.xml b/tests/tests/accessibility/AndroidTest.xml
deleted file mode 100644
index 7832508..0000000
--- a/tests/tests/accessibility/AndroidTest.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<configuration description="Base config for CTS package preparer">
-    <include name="common-config" />
-    <option name="run-command:run-command" value="settings put secure enabled_accessibility_services android.view.accessibility.services/.SpeakingAccessibilityService:android.view.accessibility.services/.VibratingAccessibilityService" />
-    <option name="run-command:run-command" value="settings put secure touch_exploration_granted_accessibility_services android.view.accessibility.services/.SpeakingAccessibilityService:android.view.accessibility.services/.VibratingAccessibilityService" />
-    <option name="run-command:run-command" value="settings put secure accessibility_enabled 1" />
-    <option name="run-command:teardown-command" value="settings put secure enabled_accessibility_services &quot;&quot;" />
-    <option name="run-command:teardown-command" value="settings put secure touch_exploration_granted_accessibility_services &quot;&quot;" />
-    <option name="run-command:teardown-command" value="settings put secure accessibility_enabled 0" />
-    <option name="cts-apk-installer:test-file-name" value="CtsSomeAccessibilityServices.apk" />
-</configuration>
diff --git a/tests/tests/accessibility/src/android/view/accessibility/cts/AccessibilityManagerTest.java b/tests/tests/accessibility/src/android/view/accessibility/cts/AccessibilityManagerTest.java
deleted file mode 100644
index 7ac0572..0000000
--- a/tests/tests/accessibility/src/android/view/accessibility/cts/AccessibilityManagerTest.java
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.view.accessibility.cts;
-
-import android.accessibilityservice.AccessibilityServiceInfo;
-import android.app.Service;
-import android.content.pm.ServiceInfo;
-import android.cts.util.PollingCheck;
-import android.provider.Settings;
-import android.test.AndroidTestCase;
-import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityManager;
-import android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener;
-
-import java.util.List;
-
-/**
- * Class for testing {@link AccessibilityManager}.
- */
-public class AccessibilityManagerTest extends AndroidTestCase {
-
-    private static final String SOME_ACCESSIBLITY_SERVICES_PACKAGE_NAME =
-        "android.view.accessibility.services";
-
-    private static final String SPEAKING_ACCESSIBLITY_SERVICE_NAME =
-        "android.view.accessibility.services.SpeakingAccessibilityService";
-
-    private static final String VIBRATING_ACCESSIBLITY_SERVICE_NAME =
-        "android.view.accessibility.services.VibratingAccessibilityService";
-
-    private AccessibilityManager mAccessibilityManager;
-
-    @Override
-    public void setUp() throws Exception {
-        mAccessibilityManager = (AccessibilityManager)
-            getContext().getSystemService(Service.ACCESSIBILITY_SERVICE);
-
-        assertEquals("Accessibility should have been enabled by the test runner.",
-                1, Settings.Secure.getInt(mContext.getContentResolver(),
-                        Settings.Secure.ACCESSIBILITY_ENABLED));
-    }
-
-    public void testAddAndRemoveAccessibilityStateChangeListener() throws Exception {
-        AccessibilityStateChangeListener listener = new AccessibilityStateChangeListener() {
-            @Override
-            public void onAccessibilityStateChanged(boolean enabled) {
-                /* do nothing */
-            }
-        };
-        assertTrue(mAccessibilityManager.addAccessibilityStateChangeListener(listener));
-        assertTrue(mAccessibilityManager.removeAccessibilityStateChangeListener(listener));
-    }
-
-    public void testIsTouchExplorationEnabled() throws Exception {
-        new PollingCheck() {
-            @Override
-            protected boolean check() {
-                return mAccessibilityManager.isTouchExplorationEnabled();
-            }
-        }.run();
-    }
-
-    public void testGetInstalledAccessibilityServicesList() throws Exception {
-        List<AccessibilityServiceInfo> installedServices =
-            mAccessibilityManager.getInstalledAccessibilityServiceList();
-        assertFalse("There must be at least one installed service.", installedServices.isEmpty());
-        boolean speakingServiceInstalled = false;
-        boolean vibratingServiceInstalled = false;
-        final int serviceCount = installedServices.size();
-        for (int i = 0; i < serviceCount; i++) {
-            AccessibilityServiceInfo installedService = installedServices.get(i);
-            ServiceInfo serviceInfo = installedService.getResolveInfo().serviceInfo;
-            if (SOME_ACCESSIBLITY_SERVICES_PACKAGE_NAME.equals(serviceInfo.packageName)
-                    && SPEAKING_ACCESSIBLITY_SERVICE_NAME.equals(serviceInfo.name)) {
-                speakingServiceInstalled = true;
-            }
-            if (SOME_ACCESSIBLITY_SERVICES_PACKAGE_NAME.equals(serviceInfo.packageName)
-                    && VIBRATING_ACCESSIBLITY_SERVICE_NAME.equals(serviceInfo.name)) {
-                vibratingServiceInstalled = true;
-            }
-        }
-        assertTrue("The speaking service should be installed.", speakingServiceInstalled);
-        assertTrue("The vibrating service should be installed.", vibratingServiceInstalled);
-    }
-
-    public void testGetEnabledAccessibilityServiceList() throws Exception {
-        List<AccessibilityServiceInfo> enabledServices =
-            mAccessibilityManager.getEnabledAccessibilityServiceList(
-                    AccessibilityServiceInfo.FEEDBACK_ALL_MASK);
-        boolean speakingServiceEnabled = false;
-        boolean vibratingServiceEnabled = false;
-        final int serviceCount = enabledServices.size();
-        for (int i = 0; i < serviceCount; i++) {
-            AccessibilityServiceInfo enabledService = enabledServices.get(i);
-            ServiceInfo serviceInfo = enabledService.getResolveInfo().serviceInfo;
-            if (SOME_ACCESSIBLITY_SERVICES_PACKAGE_NAME.equals(serviceInfo.packageName)
-                    && SPEAKING_ACCESSIBLITY_SERVICE_NAME.equals(serviceInfo.name)) {
-                speakingServiceEnabled = true;
-            }
-            if (SOME_ACCESSIBLITY_SERVICES_PACKAGE_NAME.equals(serviceInfo.packageName)
-                    && VIBRATING_ACCESSIBLITY_SERVICE_NAME.equals(serviceInfo.name)) {
-                vibratingServiceEnabled = true;
-            }
-        }
-        assertTrue("The speaking service should be enabled.", speakingServiceEnabled);
-        assertTrue("The vibrating service should be enabled.", vibratingServiceEnabled);
-    }
-
-    public void testGetEnabledAccessibilityServiceListForType() throws Exception {
-        List<AccessibilityServiceInfo> enabledServices =
-            mAccessibilityManager.getEnabledAccessibilityServiceList(
-                    AccessibilityServiceInfo.FEEDBACK_SPOKEN);
-        assertSame("There should be only one enabled speaking service.", 1, enabledServices.size());
-        final int serviceCount = enabledServices.size();
-        for (int i = 0; i < serviceCount; i++) {
-            AccessibilityServiceInfo enabledService = enabledServices.get(i);
-            ServiceInfo serviceInfo = enabledService.getResolveInfo().serviceInfo;
-            if (SOME_ACCESSIBLITY_SERVICES_PACKAGE_NAME.equals(serviceInfo.packageName)
-                    && SPEAKING_ACCESSIBLITY_SERVICE_NAME.equals(serviceInfo.name)) {
-                return;
-            }
-        }
-        fail("The speaking service is not enabled.");
-    }
-
-    @SuppressWarnings("deprecation")
-    public void testGetAccessibilityServiceList() throws Exception {
-        List<ServiceInfo> services = mAccessibilityManager.getAccessibilityServiceList();
-        boolean speakingServiceInstalled = false;
-        boolean vibratingServiceInstalled = false;
-        final int serviceCount = services.size();
-        for (int i = 0; i < serviceCount; i++) {
-            ServiceInfo serviceInfo = services.get(i);
-            if (SOME_ACCESSIBLITY_SERVICES_PACKAGE_NAME.equals(serviceInfo.packageName)
-                    && SPEAKING_ACCESSIBLITY_SERVICE_NAME.equals(serviceInfo.name)) {
-                speakingServiceInstalled = true;
-            }
-            if (SOME_ACCESSIBLITY_SERVICES_PACKAGE_NAME.equals(serviceInfo.packageName)
-                    && VIBRATING_ACCESSIBLITY_SERVICE_NAME.equals(serviceInfo.name)) {
-                vibratingServiceInstalled = true;
-            }
-        }
-        assertTrue("The speaking service should be installed.", speakingServiceInstalled);
-        assertTrue("The vibrating service should be installed.", vibratingServiceInstalled);
-    }
-
-    public void testInterrupt() throws Exception {
-        // The APIs are heavily tested in the android.accessibiliyservice package.
-        // This just makes sure the call does not throw an exception.
-        mAccessibilityManager.interrupt();
-    }
-
-    public void testSendAccessibilityEvent() throws Exception {
-        // The APIs are heavily tested in the android.accessibiliyservice package.
-        // This just makes sure the call does not throw an exception.
-        mAccessibilityManager.sendAccessibilityEvent(AccessibilityEvent.obtain(
-                AccessibilityEvent.TYPE_VIEW_CLICKED));
-    }
-}
diff --git a/tests/tests/accessibility/src/android/view/accessibility/cts/AccessibilityNodeInfoTest.java b/tests/tests/accessibility/src/android/view/accessibility/cts/AccessibilityNodeInfoTest.java
deleted file mode 100644
index 506c022..0000000
--- a/tests/tests/accessibility/src/android/view/accessibility/cts/AccessibilityNodeInfoTest.java
+++ /dev/null
@@ -1,297 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.view.accessibility.cts;
-
-import android.graphics.Rect;
-import android.os.Parcel;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.view.View;
-import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityNodeInfo;
-import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
-import android.view.cts.accessibility.R;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Class for testing {@link AccessibilityNodeInfo}.
- */
-public class AccessibilityNodeInfoTest extends AndroidTestCase {
-
-    /** The number of properties of the {@link AccessibilityNodeInfo} class. */
-    private static final int NON_STATIC_FIELD_COUNT = 30;
-
-    @SmallTest
-    public void testMarshaling() throws Exception {
-        // no new fields, so we are testing marshaling of all such
-        AccessibilityRecordTest.assertNoNewNonStaticFieldsAdded(AccessibilityNodeInfo.class,
-                NON_STATIC_FIELD_COUNT);
-
-        // fully populate the node info to marshal
-        AccessibilityNodeInfo sentInfo = AccessibilityNodeInfo.obtain(new View(getContext()));
-        fullyPopulateAccessibilityNodeInfo(sentInfo);
-
-        // marshal and unmarshal the node info
-        Parcel parcel = Parcel.obtain();
-        sentInfo.writeToParcel(parcel, 0);
-        parcel.setDataPosition(0);
-        AccessibilityNodeInfo receivedInfo = AccessibilityNodeInfo.CREATOR.createFromParcel(parcel);
-
-        // make sure all fields properly marshaled
-        assertEqualsAccessibilityNodeInfo(sentInfo, receivedInfo);
-    }
-
-    /**
-     * Tests if {@link AccessibilityNodeInfo}s are properly reused.
-     */
-    @SmallTest
-    public void testReuse() {
-        AccessibilityEvent firstInfo = AccessibilityEvent.obtain();
-        firstInfo.recycle();
-        AccessibilityEvent secondInfo = AccessibilityEvent.obtain();
-        assertSame("AccessibilityNodeInfo not properly reused", firstInfo, secondInfo);
-    }
-
-    /**
-     * Tests if {@link AccessibilityNodeInfo} are properly recycled.
-     */
-    @SmallTest
-    public void testRecycle() {
-        // obtain and populate an node info
-        AccessibilityNodeInfo populatedInfo = AccessibilityNodeInfo.obtain();
-        fullyPopulateAccessibilityNodeInfo(populatedInfo);
-
-        // recycle and obtain the same recycled instance
-        populatedInfo.recycle();
-        AccessibilityNodeInfo recycledInfo = AccessibilityNodeInfo.obtain();
-
-        // check expectations
-        assertAccessibilityNodeInfoCleared(recycledInfo);
-    }
-
-    /**
-     * Tests whether the event describes its contents consistently.
-     */
-    @SmallTest
-    public void testDescribeContents() {
-        AccessibilityNodeInfo info = AccessibilityNodeInfo.obtain();
-        assertSame("Accessibility node infos always return 0 for this method.", 0,
-                info.describeContents());
-        fullyPopulateAccessibilityNodeInfo(info);
-        assertSame("Accessibility node infos always return 0 for this method.", 0,
-                info.describeContents());
-    }
-
-    /**
-     * Tests whether accessibility actions are properly added.
-     */
-    @SmallTest
-    public void testAddActions() {
-        List<AccessibilityAction> customActions = new ArrayList<AccessibilityAction>();
-        customActions.add(new AccessibilityAction(AccessibilityNodeInfo.ACTION_FOCUS, "Foo"));
-        customActions.add(new AccessibilityAction(R.id.foo_custom_action, "Foo"));
-
-        AccessibilityNodeInfo info = AccessibilityNodeInfo.obtain();
-        info.addAction(AccessibilityNodeInfo.ACTION_FOCUS);
-        info.addAction(AccessibilityNodeInfo.ACTION_CLEAR_FOCUS);
-        for (AccessibilityAction customAction : customActions) {
-            info.addAction(customAction);
-        }
-
-        assertSame(info.getActions(), (AccessibilityNodeInfo.ACTION_FOCUS
-                | AccessibilityNodeInfo.ACTION_CLEAR_FOCUS));
-
-        List<AccessibilityAction> allActions = new ArrayList<AccessibilityAction>();
-        allActions.add(AccessibilityAction.ACTION_CLEAR_FOCUS);
-        allActions.addAll(customActions);
-        assertEquals(info.getActionList(), allActions);
-    }
-
-    /**
-     * Tests whether we catch addition of an action with invalid id.
-     */
-    @SmallTest
-    public void testCreateInvalidActionId() {
-        try {
-            new AccessibilityAction(3, null);
-        } catch (IllegalArgumentException iae) {
-            /* expected */
-        }
-    }
-
-    /**
-     * Tests whether accessibility actions are properly removed.
-     */
-    @SmallTest
-    public void testRemoveActions() {
-        AccessibilityNodeInfo info = AccessibilityNodeInfo.obtain();
-
-        info.addAction(AccessibilityNodeInfo.ACTION_FOCUS);
-        assertSame(info.getActions(), AccessibilityNodeInfo.ACTION_FOCUS);
-
-        info.removeAction(AccessibilityNodeInfo.ACTION_FOCUS);
-        assertSame(info.getActions(), 0);
-        assertTrue(info.getActionList().isEmpty());
-
-        AccessibilityAction customFocus = new AccessibilityAction(
-                AccessibilityNodeInfo.ACTION_FOCUS, "Foo");
-        info.addAction(AccessibilityNodeInfo.ACTION_FOCUS);
-        info.addAction(customFocus);
-        assertSame(info.getActionList().size(), 1);
-        assertEquals(info.getActionList().get(0), customFocus);
-        assertSame(info.getActions(), AccessibilityNodeInfo.ACTION_FOCUS);
-
-        info.removeAction(customFocus);
-        assertSame(info.getActions(), 0);
-        assertTrue(info.getActionList().isEmpty());
-    }
-
-    /**
-     * Fully populates the {@link AccessibilityNodeInfo} to marshal.
-     *
-     * @param info The node info to populate.
-     */
-    private void fullyPopulateAccessibilityNodeInfo(AccessibilityNodeInfo info) {
-        info.setParent(new View(getContext()));
-        info.setSource(new View(getContext()));
-        info.addChild(new View(getContext()));
-        info.addChild(new View(getContext()), 1);
-        info.setBoundsInParent(new Rect(1,1,1,1));
-        info.setBoundsInScreen(new Rect(2,2,2,2));
-        info.setClassName("foo.bar.baz.Class");
-        info.setContentDescription("content description");
-        info.setPackageName("foo.bar.baz");
-        info.setText("text");
-        info.setCheckable(true);
-        info.setChecked(true);
-        info.setClickable(true);
-        info.setEnabled(true);
-        info.setFocusable(true);
-        info.setFocused(true);
-        info.setLongClickable(true);
-        info.setContextClickable(true);
-        info.setPassword(true);
-        info.setScrollable(true);
-        info.setSelected(true);
-        info.addAction(AccessibilityNodeInfo.ACTION_FOCUS);
-        info.addAction(AccessibilityNodeInfo.ACTION_CLEAR_FOCUS);
-        info.addAction(new AccessibilityAction(AccessibilityNodeInfo.ACTION_FOCUS, "Foo"));
-        info.addAction(new AccessibilityAction(R.id.foo_custom_action, "Foo"));
-        info.setAccessibilityFocused(true);
-        info.setMovementGranularities(AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE);
-        info.setLabeledBy(new View(getContext()));
-        info.setLabelFor(new View(getContext()));
-        info.setViewIdResourceName("foo.bar:id/baz");
-    }
-
-    /**
-     * Compares all properties of the <code>expectedInfo</code> and the
-     * <code>receviedInfo</code> to verify that the received node info is
-     * the one that is expected.
-     */
-    public static void assertEqualsAccessibilityNodeInfo(AccessibilityNodeInfo expectedInfo,
-            AccessibilityNodeInfo receivedInfo) {
-        Rect expectedBounds = new Rect();
-        Rect receivedBounds = new Rect();
-        expectedInfo.getBoundsInParent(expectedBounds);
-        receivedInfo.getBoundsInParent(receivedBounds);
-        assertEquals("boundsInParent has incorrect value", expectedBounds, receivedBounds);
-        expectedInfo.getBoundsInScreen(expectedBounds);
-        receivedInfo.getBoundsInScreen(receivedBounds);
-        assertEquals("boundsInScreen has incorrect value", expectedBounds, receivedBounds);
-        assertEquals("className has incorrect value", expectedInfo.getClassName(),
-                receivedInfo.getClassName());
-        assertEquals("contentDescription has incorrect value", expectedInfo.getContentDescription(),
-                receivedInfo.getContentDescription());
-        assertEquals("packageName has incorrect value", expectedInfo.getPackageName(),
-                receivedInfo.getPackageName());
-        assertEquals("text has incorrect value", expectedInfo.getText(), receivedInfo.getText());
-        assertSame("checkable has incorrect value", expectedInfo.isCheckable(),
-                receivedInfo.isCheckable());
-        assertSame("checked has incorrect value", expectedInfo.isChecked(),
-                receivedInfo.isChecked());
-        assertSame("clickable has incorrect value", expectedInfo.isClickable(),
-                receivedInfo.isClickable());
-        assertSame("enabled has incorrect value", expectedInfo.isEnabled(),
-                receivedInfo.isEnabled());
-        assertSame("focusable has incorrect value", expectedInfo.isFocusable(),
-                receivedInfo.isFocusable());
-        assertSame("focused has incorrect value", expectedInfo.isFocused(),
-                receivedInfo.isFocused());
-        assertSame("longClickable has incorrect value", expectedInfo.isLongClickable(),
-                receivedInfo.isLongClickable());
-        assertSame("contextClickable has incorrect value", expectedInfo.isContextClickable(),
-                receivedInfo.isContextClickable());
-        assertSame("password has incorrect value", expectedInfo.isPassword(),
-                receivedInfo.isPassword());
-        assertSame("scrollable has incorrect value", expectedInfo.isScrollable(),
-                receivedInfo.isScrollable());
-        assertSame("selected has incorrect value", expectedInfo.isSelected(),
-                receivedInfo.isSelected());
-        assertSame("actions has incorrect value", expectedInfo.getActions(),
-                receivedInfo.getActions());
-        assertEquals("actionsSet has incorrect value", expectedInfo.getActionList(),
-                receivedInfo.getActionList());
-        assertSame("childCount has incorrect value", expectedInfo.getChildCount(),
-                receivedInfo.getChildCount());
-        assertSame("childCount has incorrect value", expectedInfo.getChildCount(),
-                receivedInfo.getChildCount());
-        assertSame("accessibilityFocused has incorrect value",
-                expectedInfo.isAccessibilityFocused(),
-                receivedInfo.isAccessibilityFocused());
-        assertSame("movementGranularities has incorrect value",
-                expectedInfo.getMovementGranularities(),
-                receivedInfo.getMovementGranularities());
-        assertEquals("viewId has incorrect value", expectedInfo.getViewIdResourceName(),
-                receivedInfo.getViewIdResourceName());
-    }
-
-    /**
-     * Asserts that an {@link AccessibilityNodeInfo} is cleared.
-     *
-     * @param info The node info to check.
-     */
-    public static void assertAccessibilityNodeInfoCleared(AccessibilityNodeInfo info) {
-        Rect bounds = new Rect();
-        info.getBoundsInParent(bounds);
-        assertTrue("boundsInParent not properly recycled", bounds.isEmpty());
-        info.getBoundsInScreen(bounds);
-        assertTrue("boundsInScreen not properly recycled", bounds.isEmpty());
-        assertNull("className not properly recycled", info.getClassName());
-        assertNull("contentDescription not properly recycled", info.getContentDescription());
-        assertNull("packageName not properly recycled", info.getPackageName());
-        assertNull("text not properly recycled", info.getText());
-        assertFalse("checkable not properly recycled", info.isCheckable());
-        assertFalse("checked not properly recycled", info.isChecked());
-        assertFalse("clickable not properly recycled", info.isClickable());
-        assertFalse("enabled not properly recycled", info.isEnabled());
-        assertFalse("focusable not properly recycled", info.isFocusable());
-        assertFalse("focused not properly recycled", info.isFocused());
-        assertFalse("longClickable not properly recycled", info.isLongClickable());
-        assertFalse("contextClickable not properly recycled", info.isContextClickable());
-        assertFalse("password not properly recycled", info.isPassword());
-        assertFalse("scrollable not properly recycled", info.isScrollable());
-        assertFalse("selected not properly recycled", info.isSelected());
-        assertSame("actions not properly recycled", 0, info.getActions());
-        assertFalse("accessibilityFocused not properly recycled", info.isAccessibilityFocused());
-        assertSame("movementGranularities not properly recycled", 0,
-                info.getMovementGranularities());
-        assertNull("viewId not properly recycled", info.getViewIdResourceName());
-    }
-}
diff --git a/tests/tests/accessibility/src/android/view/accessibility/cts/AccessibilityServiceInfoTest.java b/tests/tests/accessibility/src/android/view/accessibility/cts/AccessibilityServiceInfoTest.java
deleted file mode 100644
index f0d831e..0000000
--- a/tests/tests/accessibility/src/android/view/accessibility/cts/AccessibilityServiceInfoTest.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view.accessibility.cts;
-
-import android.accessibilityservice.AccessibilityServiceInfo;
-import android.app.Service;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.MediumTest;
-import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityManager;
-
-import java.util.List;
-
-/**
- * Tests whether accessibility service infos are properly reported. Logically,
- * this test belongs to cts/test/test/accessibilityservice but the tests there
- * are using the new UiAutomation API which disables all currently active
- * accessibility service and the fake service used for implementing the UI
- * automation is not reported through the APIs.
- */
-public class AccessibilityServiceInfoTest  extends AndroidTestCase {
-
-    /**
-     * Tests whether a service can that requested it can retrieve
-     * window content.
-     */
-    @MediumTest
-    @SuppressWarnings("deprecation")
-    public void testAccessibilityServiceInfoForEnabledService() {
-        AccessibilityManager accessibilityManager = (AccessibilityManager)
-            getContext().getSystemService(Service.ACCESSIBILITY_SERVICE);
-        List<AccessibilityServiceInfo> enabledServices =
-            accessibilityManager.getEnabledAccessibilityServiceList(
-                    AccessibilityServiceInfo.FEEDBACK_SPOKEN);
-        assertSame("There should be one speaking service.", 1, enabledServices.size());
-        AccessibilityServiceInfo speakingService = enabledServices.get(0);
-        assertSame(AccessibilityEvent.TYPES_ALL_MASK, speakingService.eventTypes);
-        assertSame(AccessibilityServiceInfo.FEEDBACK_SPOKEN, speakingService.feedbackType);
-        assertSame(AccessibilityServiceInfo.DEFAULT
-                | AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS
-                | AccessibilityServiceInfo.FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY
-                | AccessibilityServiceInfo.FLAG_REQUEST_TOUCH_EXPLORATION_MODE
-                | AccessibilityServiceInfo.FLAG_REQUEST_FILTER_KEY_EVENTS
-                | AccessibilityServiceInfo.FLAG_REPORT_VIEW_IDS,
-                speakingService.flags);
-        assertSame(0l, speakingService.notificationTimeout);
-        assertEquals("Some description", speakingService.getDescription());
-        assertNull(speakingService.packageNames /*all packages*/);
-        assertNotNull(speakingService.getId());
-        assertSame(speakingService.getCapabilities(),
-                AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY
-                | AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS
-                | AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION
-                | AccessibilityServiceInfo.CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT);
-        assertEquals("foo.bar.Activity", speakingService.getSettingsActivityName());
-        assertEquals("Some description", speakingService.loadDescription(
-                getContext().getPackageManager()));
-        assertNotNull(speakingService.getResolveInfo());
-    }
-}
diff --git a/tests/tests/accessibility/src/android/view/accessibility/cts/CaptioningManagerTest.java b/tests/tests/accessibility/src/android/view/accessibility/cts/CaptioningManagerTest.java
deleted file mode 100644
index 53eb215..0000000
--- a/tests/tests/accessibility/src/android/view/accessibility/cts/CaptioningManagerTest.java
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.view.accessibility.cts;
-
-import android.app.UiAutomation;
-import android.os.ParcelFileDescriptor;
-import android.test.InstrumentationTestCase;
-import android.view.accessibility.CaptioningManager;
-import android.view.accessibility.CaptioningManager.CaptionStyle;
-import android.view.accessibility.CaptioningManager.CaptioningChangeListener;
-
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Locale;
-
-/**
- * Tests whether the CaptioningManager APIs are functional.
- */
-public class CaptioningManagerTest extends InstrumentationTestCase {
-    private CaptioningManager mManager;
-    private UiAutomation mUiAutomation;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-
-        mManager = getInstrumentation().getTargetContext().getSystemService(
-                CaptioningManager.class);
-
-        assertNotNull("Obtained captioning manager", mManager);
-
-        mUiAutomation = getInstrumentation().getUiAutomation();
-    }
-
-    /**
-     * Tests whether a client can observe changes in caption properties.
-     */
-    public void testChangeListener() {
-        putSecureSetting("accessibility_captioning_enabled","0");
-        putSecureSetting("accessibility_captioning_preset", "1");
-        putSecureSetting("accessibility_captioning_locale", "en_US");
-        putSecureSetting("accessibility_captioning_font_scale", "1.0");
-
-        MockCaptioningChangeListener listener = new MockCaptioningChangeListener();
-        mManager.addCaptioningChangeListener(listener);
-
-        putSecureSetting("accessibility_captioning_enabled", "1");
-        assertTrue("Observed enabled change", listener.wasEnabledChangedCalled);
-
-        putSecureSetting("accessibility_captioning_preset", "-1");
-        assertTrue("Observed user style change", listener.wasUserStyleChangedCalled);
-
-        putSecureSetting("accessibility_captioning_locale", "ja_JP");
-        assertTrue("Observed locale change", listener.wasLocaleChangedCalled);
-
-        putSecureSetting("accessibility_captioning_font_scale", "2.0");
-        assertTrue("Observed font scale change", listener.wasFontScaleChangedCalled);
-
-        mManager.removeCaptioningChangeListener(listener);
-
-        listener.reset();
-
-        putSecureSetting("accessibility_captioning_enabled","0");
-        assertFalse("Did not observe enabled change", listener.wasEnabledChangedCalled);
-
-        try {
-            mManager.removeCaptioningChangeListener(listener);
-        } catch (Exception e) {
-            throw new AssertionError("Fails silently when removing listener twice", e);
-        }
-    }
-
-    public void testProperties() {
-        putSecureSetting("accessibility_captioning_font_scale", "2.0");
-        putSecureSetting("accessibility_captioning_locale", "ja_JP");
-        putSecureSetting("accessibility_captioning_enabled", "1");
-
-        assertEquals("Test runner set font scale to 2.0", 2.0f, mManager.getFontScale());
-        assertEquals("Test runner set locale to Japanese", Locale.JAPAN, mManager.getLocale());
-        assertEquals("Test runner set enabled to true", true, mManager.isEnabled());
-    }
-
-    public void testUserStyle() {
-        putSecureSetting("accessibility_captioning_preset", "-1");
-        putSecureSetting("accessibility_captioning_foreground_color", "511");
-        putSecureSetting("accessibility_captioning_background_color", "511");
-        putSecureSetting("accessibility_captioning_window_color", "511");
-        putSecureSetting("accessibility_captioning_edge_color", "511");
-        putSecureSetting("accessibility_captioning_edge_type", "-1");
-        deleteSecureSetting("accessibility_captioning_typeface");
-
-        CaptionStyle userStyle = mManager.getUserStyle();
-        assertNotNull("Default user style is not null", userStyle);
-        assertFalse("Default user style has no edge type", userStyle.hasEdgeType());
-        assertFalse("Default user style has no edge color", userStyle.hasEdgeColor());
-        assertFalse("Default user style has no foreground color", userStyle.hasForegroundColor());
-        assertFalse("Default user style has no background color", userStyle.hasBackgroundColor());
-        assertFalse("Default user style has no window color", userStyle.hasWindowColor());
-        assertNull("Default user style has no typeface", userStyle.getTypeface());
-    }
-
-    private void deleteSecureSetting(String name) {
-        execShellCommand("settings delete secure " + name);
-    }
-
-    private void putSecureSetting(String name, String value) {
-        execShellCommand("settings put secure " + name + " " + value);
-    }
-
-    private void execShellCommand(String cmd) {
-        ParcelFileDescriptor pfd = mUiAutomation.executeShellCommand(cmd);
-        InputStream is = new FileInputStream(pfd.getFileDescriptor());
-        try {
-            final byte[] buffer = new byte[8192];
-            while ((is.read(buffer)) != -1);
-        } catch (IOException e) {
-            throw new RuntimeException("Failed to exec: " + cmd);
-        }
-    }
-
-    private static class MockCaptioningChangeListener extends CaptioningChangeListener {
-        boolean wasEnabledChangedCalled = false;
-        boolean wasUserStyleChangedCalled = false;
-        boolean wasLocaleChangedCalled = false;
-        boolean wasFontScaleChangedCalled = false;
-
-        @Override
-        public void onEnabledChanged(boolean enabled) {
-            super.onEnabledChanged(enabled);
-            wasEnabledChangedCalled = true;
-        }
-
-        @Override
-        public void onUserStyleChanged(CaptionStyle userStyle) {
-            super.onUserStyleChanged(userStyle);
-            wasUserStyleChangedCalled = true;
-        }
-
-        @Override
-        public void onLocaleChanged(Locale locale) {
-            super.onLocaleChanged(locale);
-            wasLocaleChangedCalled = true;
-        }
-
-        @Override
-        public void onFontScaleChanged(float fontScale) {
-            super.onFontScaleChanged(fontScale);
-            wasFontScaleChangedCalled = true;
-        }
-
-        public void reset() {
-            wasEnabledChangedCalled = false;
-            wasUserStyleChangedCalled = false;
-            wasLocaleChangedCalled = false;
-            wasFontScaleChangedCalled = false;
-        }
-    }
-}
diff --git a/tests/tests/accessibilityservice/Android.mk b/tests/tests/accessibilityservice/Android.mk
deleted file mode 100644
index b27dbcc..0000000
--- a/tests/tests/accessibilityservice/Android.mk
+++ /dev/null
@@ -1,29 +0,0 @@
-# Copyright (C) 2010 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_PACKAGE_NAME := CtsAccessibilityServiceTestCases
-
-LOCAL_SDK_VERSION := current
-
-include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/accessibilityservice/AndroidManifest.xml b/tests/tests/accessibilityservice/AndroidManifest.xml
deleted file mode 100644
index e172913..0000000
--- a/tests/tests/accessibilityservice/AndroidManifest.xml
+++ /dev/null
@@ -1,52 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-        package="com.android.cts.accessibilityservice">
-
-    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
-
-    <application android:theme="@android:style/Theme.Holo.NoActionBar" >
-
-      <uses-library android:name="android.test.runner"/>
-
-      <activity android:label="@string/accessibility_end_to_end_test_activity"
-              android:name="android.accessibilityservice.cts.AccessibilityEndToEndActivity"/>
-
-      <activity android:label="@string/accessibility_query_window_test_activity"
-              android:name="android.accessibilityservice.cts.AccessibilityWindowQueryActivity"/>
-
-      <activity android:label="@string/accessibility_view_tree_reporting_test_activity"
-              android:name="android.accessibilityservice.cts.AccessibilityViewTreeReportingActivity"/>
-
-      <activity android:label="@string/accessibility_focus_and_input_focus_sync_test_activity"
-              android:name="android.accessibilityservice.cts.AccessibilityFocusAndInputFocusSyncActivity"/>
-
-      <activity android:label="@string/accessibility_text_traversal_test_activity"
-              android:name="android.accessibilityservice.cts.AccessibilityTextTraversalActivity"/>
-
-  </application>
-
-  <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                   android:targetPackage="com.android.cts.accessibilityservice"
-                   android:label="Tests for the accessibility APIs.">
-        <meta-data android:name="listener"
-            android:value="com.android.cts.runner.CtsTestRunListener" />
-    </instrumentation>
-
-</manifest>
diff --git a/tests/tests/accessibilityservice/res/layout/accessibility_text_traversal_test.xml b/tests/tests/accessibilityservice/res/layout/accessibility_text_traversal_test.xml
deleted file mode 100644
index 9906227..0000000
--- a/tests/tests/accessibilityservice/res/layout/accessibility_text_traversal_test.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 2012, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:orientation="vertical"
-    android:layout_width="fill_parent"
-    android:layout_height="wrap_content"
-    >
-
-   <View
-       android:id="@+id/view"
-       android:layout_width="50dip"
-       android:layout_height="50dip"
-       android:visibility="gone"
-       />
-
-   <TextView
-       android:id="@+id/text"
-       android:layout_width="80dip"
-       android:layout_height="80dip"
-       android:includeFontPadding="false"
-       android:textSize="10dip"
-       android:textStyle="normal"
-       android:fontFamily="sans-serif"
-       android:visibility="gone"
-       />
-
-   <EditText
-       android:id="@+id/edit"
-       android:layout_width="80dip"
-       android:layout_height="80dip"
-       android:maxLines="1000"
-       android:scrollbars="vertical"
-       android:focusable="false"
-       android:includeFontPadding="false"
-       android:textSize="10dip"
-       android:textStyle="normal"
-       android:fontFamily="sans-serif"
-       android:visibility="gone"
-       />
-
-</LinearLayout>
diff --git a/tests/tests/accessibilityservice/res/values/strings.xml b/tests/tests/accessibilityservice/res/values/strings.xml
deleted file mode 100644
index 0b97d3f..0000000
--- a/tests/tests/accessibilityservice/res/values/strings.xml
+++ /dev/null
@@ -1,145 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!-- Copyright (C) 2010 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<resources>
-
-    <!-- AccessibilityEndToEndTest -->
-
-    <!-- String title of the accessibility end-to-end test activity -->
-    <string name="accessibility_end_to_end_test_activity">End-to-end test</string>
-
-    <!-- String value of used as text input -->
-    <string name="text_input_blah">Blah</string>
-
-    <!-- String value of used as text input -->
-    <string name="text_input_blah_blah">Blah blah</string>
-
-    <!-- String title of the button -->
-    <string name="button_title">Click me</string>
-
-    <!-- String value of the first list item -->
-    <string name="first_list_item">First list item</string>
-
-    <!-- String value of the second list item -->
-    <string name="second_list_item">Second list item</string>
-
-    <!-- String alert title -->
-    <string name="alert_title">Alert title</string>
-
-    <!-- String alert message -->
-    <string name="alert_message">Alert message</string>
-
-    <!-- String notification message -->
-    <string name="notification_message">Notification message</string>
-
-    <!-- AccessibilityWindowQueryTest -->
-
-    <!-- String title of the accessibility query window test activity -->
-    <string name="accessibility_query_window_test_activity">Query window test</string>
-
-    <!-- String Button1 text -->
-    <string name="button1">B1</string>
-
-    <!-- String Button2 text -->
-    <string name="button2">B2</string>
-
-    <!-- String Button3 text -->
-    <string name="button3">B3</string>
-
-    <!-- String Button4 text -->
-    <string name="button4">B4</string>
-
-    <!-- String Button5 text -->
-    <string name="button5">B5</string>
-
-    <!-- String Button6 text -->
-    <string name="button6">B6</string>
-
-    <!-- String with content description for Button6 -->
-    <string name="contentDescription">contentDescription</string>
-
-    <!-- String Button7 text -->
-    <string name="button7">B7</string>
-
-    <!-- String Button8 text -->
-    <string name="button8">B8</string>
-
-    <!-- String Button9 text -->
-    <string name="button9">B9</string>
-
-    <!-- AccessibilityFocusTest -->
-
-    <!-- String title of the accessibility hierarchical focus test activity -->
-    <string name="accessibility_view_tree_reporting_test_activity">Accessibility view three reporting test</string>
-
-    <!-- String root LinearLayout text -->
-    <string name="rootLinearLayout">rLL</string>
-
-    <!-- String first FrameLayout text -->
-    <string name="firstFrameLayout">fFL</string>
-
-    <!-- String first LinearLayout text -->
-    <string name="firstLinearLayout">fLL</string>
-
-    <!-- String first TextView text -->
-    <string name="firstTextView">fTV</string>
-
-    <!-- String first EditText text -->
-    <string name="firstEditText">fET</string>
-
-    <!-- String first Button text -->
-    <string name="firstButton">fB</string>
-
-    <!-- String second FrameLayout text -->
-    <string name="secondFrameLayout">sFL</string>
-
-    <!-- String second LinearLayout text -->
-    <string name="secondLinearLayout">sLL</string>
-
-    <!-- String second TextView text -->
-    <string name="secondTextView">sTV</string>
-
-    <!-- String second EditText text -->
-    <string name="secondEditText">sET</string>
-
-    <!-- String second Button text -->
-    <string name="secondButton">sB</string>
-
-    <!-- String title of the accessibility focus and input focus sync test activity -->
-    <string name="accessibility_focus_and_input_focus_sync_test_activity">Accessibility focus and input focus sync test</string>
-
-    <!-- String title of the accessibility text traversal test activity. -->
-    <string name="accessibility_text_traversal_test_activity">Accessibility text traversal test</string>
-
-    <string name="android_wiki_short">
-        Android is a\nLinux-based\noperating</string>
-
-    <string name="android_wiki">
-        Android is a Linux-based operating system for mobile devices such as smartphones and tablet
-        computers. It is developed by the Open Handset Alliance, more</string>
-
-    <string name="a_b">A B</string>
-
-    <string name="android_wiki_search">Android is a Linux-based</string>
-
-    <string name="foo_bar_baz">Foo bar baz.</string>
-
-    <string name="android_wiki_paragraphs">
-        \n\nAndroid is a\n\n It is developed\n The
-        unveiling\n\n</string>
-
-</resources>
diff --git a/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEndToEndActivity.java b/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEndToEndActivity.java
deleted file mode 100644
index 157a3dc..0000000
--- a/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEndToEndActivity.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.accessibilityservice.cts;
-
-import com.android.cts.accessibilityservice.R;
-
-import android.os.Bundle;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.BaseAdapter;
-import android.widget.ListAdapter;
-import android.widget.ListView;
-import android.widget.TextView;
-
-/**
- * This class is an {@link android.app.Activity} used to perform end-to-end
- * testing of the accessibility feature by interaction with the
- * UI widgets.
- */
-public class AccessibilityEndToEndActivity extends AccessibilityTestActivity {
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.end_to_end_test);
-
-        ListAdapter listAdapter = new BaseAdapter() {
-            public View getView(int position, View convertView, ViewGroup parent) {
-                TextView textView = (TextView) View
-                        .inflate(AccessibilityEndToEndActivity.this, R.layout.list_view_row, null);
-                textView.setText((String) getItem(position));
-                return textView;
-            }
-
-            public long getItemId(int position) {
-                return position;
-            }
-
-            public Object getItem(int position) {
-                if (position == 0) {
-                    return AccessibilityEndToEndActivity.this.getString(R.string.first_list_item);
-                } else {
-                    return AccessibilityEndToEndActivity.this.getString(R.string.second_list_item);
-                }
-            }
-
-            public int getCount() {
-                return 2;
-            }
-        };
-
-        ListView listView = (ListView) findViewById(R.id.listview);
-        listView.setAdapter(listAdapter);
-    }
-}
diff --git a/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEndToEndTest.java b/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEndToEndTest.java
deleted file mode 100644
index f5b29cf..0000000
--- a/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEndToEndTest.java
+++ /dev/null
@@ -1,437 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.accessibilityservice.cts;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.app.Notification;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.app.Service;
-import android.app.UiAutomation;
-import android.content.Intent;
-import android.content.res.Configuration;
-import android.test.suitebuilder.annotation.MediumTest;
-import android.text.TextUtils;
-import android.util.Log;
-import android.view.accessibility.AccessibilityEvent;
-import android.widget.Button;
-import android.widget.EditText;
-import android.widget.ListView;
-
-import com.android.cts.accessibilityservice.R;
-
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * This class performs end-to-end testing of the accessibility feature by
- * creating an {@link Activity} and poking around so {@link AccessibilityEvent}s
- * are generated and their correct dispatch verified.
- */
-public class AccessibilityEndToEndTest extends
-        AccessibilityActivityTestCase<AccessibilityEndToEndActivity> {
-
-    private static final String LOG_TAG = "AccessibilityEndToEndTest";
-
-    /**
-     * Creates a new instance for testing {@link AccessibilityEndToEndActivity}.
-     */
-    public AccessibilityEndToEndTest() {
-        super(AccessibilityEndToEndActivity.class);
-    }
-
-    @MediumTest
-    public void testTypeViewSelectedAccessibilityEvent() throws Throwable {
-        // create and populate the expected event
-        final AccessibilityEvent expected = AccessibilityEvent.obtain();
-        expected.setEventType(AccessibilityEvent.TYPE_VIEW_SELECTED);
-        expected.setClassName(ListView.class.getName());
-        expected.setPackageName(getActivity().getPackageName());
-        expected.getText().add(getActivity().getString(R.string.second_list_item));
-        expected.setItemCount(2);
-        expected.setCurrentItemIndex(1);
-        expected.setEnabled(true);
-        expected.setScrollable(false);
-        expected.setFromIndex(0);
-        expected.setToIndex(1);
-
-        final ListView listView = (ListView) getActivity().findViewById(R.id.listview);
-
-        AccessibilityEvent awaitedEvent =
-            getInstrumentation().getUiAutomation().executeAndWaitForEvent(
-                new Runnable() {
-            @Override
-            public void run() {
-                // trigger the event
-                getActivity().runOnUiThread(new Runnable() {
-                    @Override
-                    public void run() {
-                        listView.setSelection(1);
-                    }
-                });
-            }},
-            new UiAutomation.AccessibilityEventFilter() {
-                // check the received event
-                @Override
-                public boolean accept(AccessibilityEvent event) {
-                    return equalsAccessiblityEvent(event, expected);
-                }
-            },
-            TIMEOUT_ASYNC_PROCESSING);
-        assertNotNull("Did not receive expected event: " + expected, awaitedEvent);
-    }
-
-    @MediumTest
-    public void testTypeViewClickedAccessibilityEvent() throws Throwable {
-        // create and populate the expected event
-        final AccessibilityEvent expected = AccessibilityEvent.obtain();
-        expected.setEventType(AccessibilityEvent.TYPE_VIEW_CLICKED);
-        expected.setClassName(Button.class.getName());
-        expected.setPackageName(getActivity().getPackageName());
-        expected.getText().add(getActivity().getString(R.string.button_title));
-        expected.setEnabled(true);
-
-        final Button button = (Button) getActivity().findViewById(R.id.button);
-
-        AccessibilityEvent awaitedEvent =
-            getInstrumentation().getUiAutomation().executeAndWaitForEvent(
-                new Runnable() {
-            @Override
-            public void run() {
-                // trigger the event
-                getActivity().runOnUiThread(new Runnable() {
-                    @Override
-                    public void run() {
-                        button.performClick();
-                    }
-                });
-            }},
-            new UiAutomation.AccessibilityEventFilter() {
-                // check the received event
-                @Override
-                public boolean accept(AccessibilityEvent event) {
-                    return equalsAccessiblityEvent(event, expected);
-                }
-            },
-            TIMEOUT_ASYNC_PROCESSING);
-        assertNotNull("Did not receive expected event: " + expected, awaitedEvent);
-    }
-
-    @MediumTest
-    public void testTypeViewLongClickedAccessibilityEvent() throws Throwable {
-        // create and populate the expected event
-        final AccessibilityEvent expected = AccessibilityEvent.obtain();
-        expected.setEventType(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED);
-        expected.setClassName(Button.class.getName());
-        expected.setPackageName(getActivity().getPackageName());
-        expected.getText().add(getActivity().getString(R.string.button_title));
-        expected.setEnabled(true);
-
-        final Button button = (Button) getActivity().findViewById(R.id.button);
-
-        AccessibilityEvent awaitedEvent =
-            getInstrumentation().getUiAutomation().executeAndWaitForEvent(
-                new Runnable() {
-            @Override
-            public void run() {
-                // trigger the event
-                getActivity().runOnUiThread(new Runnable() {
-                    @Override
-                    public void run() {
-                        button.performLongClick();
-                    }
-                });
-            }},
-            new UiAutomation.AccessibilityEventFilter() {
-                // check the received event
-                @Override
-                public boolean accept(AccessibilityEvent event) {
-                    return equalsAccessiblityEvent(event, expected);
-                }
-            },
-            TIMEOUT_ASYNC_PROCESSING);
-        assertNotNull("Did not receive expected event: " + expected, awaitedEvent);
-    }
-
-    @MediumTest
-    public void testTypeViewFocusedAccessibilityEvent() throws Throwable {
-        // create and populate the expected event
-        final AccessibilityEvent expected = AccessibilityEvent.obtain();
-        expected.setEventType(AccessibilityEvent.TYPE_VIEW_FOCUSED);
-        expected.setClassName(Button.class.getName());
-        expected.setPackageName(getActivity().getPackageName());
-        expected.getText().add(getActivity().getString(R.string.button_title));
-        expected.setItemCount(3);
-        expected.setCurrentItemIndex(2);
-        expected.setEnabled(true);
-
-        final Button button = (Button) getActivity().findViewById(R.id.button);
-
-        AccessibilityEvent awaitedEvent =
-            getInstrumentation().getUiAutomation().executeAndWaitForEvent(
-                new Runnable() {
-            @Override
-            public void run() {
-                // trigger the event
-                getActivity().runOnUiThread(new Runnable() {
-                    @Override
-                    public void run() {
-                        button.requestFocus();
-                    }
-                });
-            }},
-            new UiAutomation.AccessibilityEventFilter() {
-                // check the received event
-                @Override
-                public boolean accept(AccessibilityEvent event) {
-                    return equalsAccessiblityEvent(event, expected);
-                }
-            },
-            TIMEOUT_ASYNC_PROCESSING);
-        assertNotNull("Did not receive expected event: " + expected, awaitedEvent);
-    }
-
-    @MediumTest
-    public void testTypeViewTextChangedAccessibilityEvent() throws Throwable {
-        // focus the edit text
-        final EditText editText = (EditText) getActivity().findViewById(R.id.edittext);
-
-        AccessibilityEvent awaitedFocusEvent =
-            getInstrumentation().getUiAutomation().executeAndWaitForEvent(
-                new Runnable() {
-            @Override
-            public void run() {
-                // trigger the event
-                getActivity().runOnUiThread(new Runnable() {
-                    @Override
-                    public void run() {
-                        editText.requestFocus();
-                    }
-                });
-            }},
-            new UiAutomation.AccessibilityEventFilter() {
-                // check the received event
-                @Override
-                public boolean accept(AccessibilityEvent event) {
-                    return event.getEventType() == AccessibilityEvent.TYPE_VIEW_FOCUSED;
-                }
-            },
-            TIMEOUT_ASYNC_PROCESSING);
-        assertNotNull("Did not receive expected focuss event.", awaitedFocusEvent);
-
-        final String beforeText = getActivity().getString(R.string.text_input_blah);
-        final String newText = getActivity().getString(R.string.text_input_blah_blah);
-        final String afterText = beforeText.substring(0, 3) + newText;
-
-        // create and populate the expected event
-        final AccessibilityEvent expected = AccessibilityEvent.obtain();
-        expected.setEventType(AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED);
-        expected.setClassName(EditText.class.getName());
-        expected.setPackageName(getActivity().getPackageName());
-        expected.getText().add(afterText);
-        expected.setBeforeText(beforeText);
-        expected.setFromIndex(3);
-        expected.setAddedCount(9);
-        expected.setRemovedCount(1);
-        expected.setEnabled(true);
-
-        AccessibilityEvent awaitedTextChangeEvent =
-            getInstrumentation().getUiAutomation().executeAndWaitForEvent(
-                new Runnable() {
-            @Override
-            public void run() {
-                // trigger the event
-                getActivity().runOnUiThread(new Runnable() {
-                    @Override
-                    public void run() {
-                        editText.getEditableText().replace(3, 4, newText);
-                    }
-                });
-            }},
-            new UiAutomation.AccessibilityEventFilter() {
-                // check the received event
-                @Override
-                public boolean accept(AccessibilityEvent event) {
-                    return equalsAccessiblityEvent(event, expected);
-                }
-            },
-            TIMEOUT_ASYNC_PROCESSING);
-        assertNotNull("Did not receive expected event: " + expected, awaitedTextChangeEvent);
-    }
-
-    @MediumTest
-    public void testTypeWindowStateChangedAccessibilityEvent() throws Throwable {
-        // create and populate the expected event
-        final AccessibilityEvent expected = AccessibilityEvent.obtain();
-        expected.setEventType(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
-        expected.setClassName(AlertDialog.class.getName());
-        expected.setPackageName(getActivity().getPackageName());
-        expected.getText().add(getActivity().getString(R.string.alert_title));
-        expected.getText().add(getActivity().getString(R.string.alert_message));
-        expected.setEnabled(true);
-
-        AccessibilityEvent awaitedEvent =
-            getInstrumentation().getUiAutomation().executeAndWaitForEvent(
-                new Runnable() {
-            @Override
-            public void run() {
-                // trigger the event
-                getActivity().runOnUiThread(new Runnable() {
-                    @Override
-                    public void run() {
-                        (new AlertDialog.Builder(getActivity()).setTitle(R.string.alert_title)
-                                .setMessage(R.string.alert_message)).create().show();
-                    }
-                });
-            }},
-            new UiAutomation.AccessibilityEventFilter() {
-                // check the received event
-                @Override
-                public boolean accept(AccessibilityEvent event) {
-                    return equalsAccessiblityEvent(event, expected);
-                }
-            },
-            TIMEOUT_ASYNC_PROCESSING);
-        assertNotNull("Did not receive expected event: " + expected, awaitedEvent);
-    }
-
-    @MediumTest
-    @SuppressWarnings("deprecation")
-    public void testTypeNotificationStateChangedAccessibilityEvent() throws Throwable {
-        // No notification UI on televisions.
-        if((getActivity().getResources().getConfiguration().uiMode
-                & Configuration.UI_MODE_TYPE_MASK) == Configuration.UI_MODE_TYPE_TELEVISION) {
-            Log.i(LOG_TAG, "Skipping: testTypeNotificationStateChangedAccessibilityEvent" +
-                    " - No notification UI on televisions.");
-            return;
-        }
-
-        String message = getActivity().getString(R.string.notification_message);
-
-        // create the notification to send
-        final int notificationId = 1;
-        final Notification notification = new Notification.Builder(getActivity())
-                .setSmallIcon(android.R.drawable.stat_notify_call_mute)
-                .setContentIntent(PendingIntent.getActivity(getActivity(), 0, new Intent(),
-                        PendingIntent.FLAG_CANCEL_CURRENT))
-                .setTicker(message)
-                .setContentTitle("")
-                .setContentText("")
-                // Mark the notification as "interruptive" by specifying a vibration pattern. This
-                // ensures it's announced properly on watch-type devices.
-                .setVibrate(new long[] {})
-                .build();
-
-        // create and populate the expected event
-        final AccessibilityEvent expected = AccessibilityEvent.obtain();
-        expected.setEventType(AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED);
-        expected.setClassName(Notification.class.getName());
-        expected.setPackageName(getActivity().getPackageName());
-        expected.getText().add(message);
-        expected.setParcelableData(notification);
-
-        AccessibilityEvent awaitedEvent =
-            getInstrumentation().getUiAutomation().executeAndWaitForEvent(
-                new Runnable() {
-            @Override
-            public void run() {
-                // trigger the event
-                getActivity().runOnUiThread(new Runnable() {
-                    @Override
-                    public void run() {
-                        // trigger the event
-                        NotificationManager notificationManager =
-                            (NotificationManager) getActivity().getSystemService(
-                                    Service.NOTIFICATION_SERVICE);
-                        notificationManager.notify(notificationId, notification);
-                        getActivity().finish();
-                    }
-                });
-            }},
-            new UiAutomation.AccessibilityEventFilter() {
-                // check the received event
-                @Override
-                public boolean accept(AccessibilityEvent event) {
-                    return equalsAccessiblityEvent(event, expected);
-                }
-            },
-            TIMEOUT_ASYNC_PROCESSING);
-        assertNotNull("Did not receive expected event: " + expected, awaitedEvent);
-    }
-
-    /**
-     * Compares all properties of the <code>first</code> and the
-     * <code>second</code>.
-     */
-    private boolean equalsAccessiblityEvent(AccessibilityEvent first, AccessibilityEvent second) {
-         return first.getEventType() == second.getEventType()
-            && first.isChecked() == second.isChecked()
-            && first.getCurrentItemIndex() == second.getCurrentItemIndex()
-            && first.isEnabled() == second.isEnabled()
-            && first.getFromIndex() == second.getFromIndex()
-            && first.getItemCount() == second.getItemCount()
-            && first.isPassword() == second.isPassword()
-            && first.getRemovedCount() == second.getRemovedCount()
-            && first.isScrollable()== second.isScrollable()
-            && first.getToIndex() == second.getToIndex()
-            && first.getRecordCount() == second.getRecordCount()
-            && first.getScrollX() == second.getScrollX()
-            && first.getScrollY() == second.getScrollY()
-            && first.getAddedCount() == second.getAddedCount()
-            && TextUtils.equals(first.getBeforeText(), second.getBeforeText())
-            && TextUtils.equals(first.getClassName(), second.getClassName())
-            && TextUtils.equals(first.getContentDescription(), second.getContentDescription())
-            && equalsNotificationAsParcelableData(first, second)
-            && equalsText(first, second);
-    }
-
-    /**
-     * Compares the {@link android.os.Parcelable} data of the
-     * <code>first</code> and <code>second</code>.
-     */
-    private boolean equalsNotificationAsParcelableData(AccessibilityEvent first,
-            AccessibilityEvent second) {
-        Notification firstNotification = (Notification) first.getParcelableData();
-        Notification secondNotification = (Notification) second.getParcelableData();
-        if (firstNotification == null) {
-            return (secondNotification == null);
-        } else if (secondNotification == null) {
-            return false;
-        }
-        return TextUtils.equals(firstNotification.tickerText, secondNotification.tickerText);
-    }
-
-    /**
-     * Compares the text of the <code>first</code> and <code>second</code> text.
-     */
-    private boolean equalsText(AccessibilityEvent first, AccessibilityEvent second) {
-        List<CharSequence> firstText = first.getText();
-        List<CharSequence> secondText = second.getText();
-        if (firstText.size() != secondText.size()) {
-            return false;
-        }
-        Iterator<CharSequence> firstIterator = firstText.iterator();
-        Iterator<CharSequence> secondIterator = secondText.iterator();
-        for (int i = 0; i < firstText.size(); i++) {
-            if (!firstIterator.next().toString().equals(secondIterator.next().toString())) {
-                return false;
-            }
-        }
-        return true;
-    }
-}
diff --git a/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityFocusAndInputFocusSyncActivity.java b/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityFocusAndInputFocusSyncActivity.java
deleted file mode 100644
index 46f04aa..0000000
--- a/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityFocusAndInputFocusSyncActivity.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/**
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 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.accessibilityservice.cts;
-
-import android.os.Bundle;
-
-import com.android.cts.accessibilityservice.R;
-
-/**
- * Activity for testing the accessibility focus APIs exposed to
- * accessibility services. These APIs allow moving accessibility
- * focus in the view tree from an AccessiiblityService. Specifically,
- * this activity is for verifying the the sync between accessibility
- * and input focus.
- */
-public class AccessibilityFocusAndInputFocusSyncActivity extends AccessibilityTestActivity {
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.accessibility_focus_and_input_focus_sync_test);
-    }
-}
diff --git a/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityFocusAndInputFocusSyncTest.java b/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityFocusAndInputFocusSyncTest.java
deleted file mode 100644
index 93b026c..0000000
--- a/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityFocusAndInputFocusSyncTest.java
+++ /dev/null
@@ -1,229 +0,0 @@
-/**
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 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.accessibilityservice.cts;
-
-import static android.view.accessibility.AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS;
-import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS;
-
-import android.app.UiAutomation;
-import android.test.suitebuilder.annotation.MediumTest;
-import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityNodeInfo;
-
-import com.android.cts.accessibilityservice.R;
-
-import java.util.LinkedList;
-import java.util.Queue;
-
-/**
- * Test cases for testing the accessibility focus APIs exposed to accessibility
- * services. These APIs allow moving accessibility focus in the view tree from
- * an AccessiiblityService. Specifically, this activity is for verifying the the
- * sync between accessibility and input focus.
- */
-public class AccessibilityFocusAndInputFocusSyncTest
-        extends AccessibilityActivityTestCase<AccessibilityFocusAndInputFocusSyncActivity>{
-
-    public AccessibilityFocusAndInputFocusSyncTest() {
-        super(AccessibilityFocusAndInputFocusSyncActivity.class);
-    }
-
-    @MediumTest
-    public void testFindAccessibilityFocus() throws Exception {
-        // Get the view that has input and accessibility focus.
-        final AccessibilityNodeInfo expected = getInstrumentation().getUiAutomation()
-                .getRootInActiveWindow().findAccessibilityNodeInfosByText(
-                        getString(R.string.firstEditText)).get(0);
-        assertNotNull(expected);
-        assertFalse(expected.isAccessibilityFocused());
-        assertTrue(expected.isFocused());
-
-        getInstrumentation().getUiAutomation().executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                // Perform a focus action and check for success.
-                assertTrue(expected.performAction(ACTION_ACCESSIBILITY_FOCUS));
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return event.getEventType() == AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED;
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Get the second expected node info.
-        AccessibilityNodeInfo received = getInstrumentation().getUiAutomation()
-                .getRootInActiveWindow().findFocus(AccessibilityNodeInfo.FOCUS_ACCESSIBILITY);
-        assertNotNull(received);
-        assertTrue(received.isAccessibilityFocused());
-
-        // Make sure we got the expected focusable.
-        assertEquals(expected, received);
-    }
-
-    @MediumTest
-    public void testInitialStateNoAccessibilityFocus() throws Exception {
-        // Get the root which is only accessibility focused.
-        AccessibilityNodeInfo focused = getInstrumentation().getUiAutomation()
-                .getRootInActiveWindow().findFocus(AccessibilityNodeInfo.FOCUS_ACCESSIBILITY);
-        assertNull(focused);
-    }
-
-    @MediumTest
-    public void testActionAccessibilityFocus() throws Exception {
-        // Get the root linear layout info.
-        final AccessibilityNodeInfo rootLinearLayout = getInstrumentation().getUiAutomation()
-                .getRootInActiveWindow().findAccessibilityNodeInfosByText(
-                        getString(R.string.rootLinearLayout)).get(0);
-        assertNotNull(rootLinearLayout);
-        assertFalse(rootLinearLayout.isAccessibilityFocused());
-
-        getInstrumentation().getUiAutomation().executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                // Perform a focus action and check for success.
-                assertTrue(rootLinearLayout.performAction(ACTION_ACCESSIBILITY_FOCUS));
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return event.getEventType() == AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED;
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Get the node info again.
-        rootLinearLayout.refresh();
-
-        // Check if the node info is focused.
-        assertTrue(rootLinearLayout.isAccessibilityFocused());
-    }
-
-    @MediumTest
-    public void testActionClearAccessibilityFocus() throws Exception {
-        // Get the root linear layout info.
-        final AccessibilityNodeInfo rootLinearLayout = getInstrumentation().getUiAutomation()
-                .getRootInActiveWindow().findAccessibilityNodeInfosByText(
-                        getString(R.string.rootLinearLayout)).get(0);
-        assertNotNull(rootLinearLayout);
-
-        getInstrumentation().getUiAutomation().executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                // Perform a focus action and check for success.
-                assertTrue(rootLinearLayout.performAction(ACTION_ACCESSIBILITY_FOCUS));
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return event.getEventType() == AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED;
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Refresh the node info.
-        rootLinearLayout.refresh();
-
-        // Check if the node info is focused.
-        assertTrue(rootLinearLayout.isAccessibilityFocused());
-
-        getInstrumentation().getUiAutomation().executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                // Perform a clear focus action and check for success.
-                assertTrue(rootLinearLayout.performAction(ACTION_CLEAR_ACCESSIBILITY_FOCUS));
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return event.getEventType()
-                        == AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED;
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Refresh the node info.
-        rootLinearLayout.refresh();
-
-        // Check if the node info is not focused.
-        assertFalse(rootLinearLayout.isAccessibilityFocused());
-    }
-
-    @MediumTest
-    public void testOnlyOneNodeHasAccessibilityFocus() throws Exception {
-        // Get the first not focused edit text.
-        final AccessibilityNodeInfo firstEditText = getInstrumentation().getUiAutomation()
-                .getRootInActiveWindow().findAccessibilityNodeInfosByText(
-                        getString(R.string.firstEditText)).get(0);
-        assertNotNull(firstEditText);
-        assertTrue(firstEditText.isFocusable());
-        assertTrue(firstEditText.isFocused());
-        assertFalse(firstEditText.isAccessibilityFocused());
-
-        getInstrumentation().getUiAutomation().executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                // Perform a set focus action and check for success.
-                assertTrue(firstEditText.performAction(ACTION_ACCESSIBILITY_FOCUS));
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return event.getEventType() == AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED;
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Get the second not focused edit text.
-        final AccessibilityNodeInfo secondEditText = getInstrumentation().getUiAutomation()
-                .getRootInActiveWindow().findAccessibilityNodeInfosByText(
-                        getString(R.string.secondEditText)).get(0);
-        assertNotNull(secondEditText);
-        assertTrue(secondEditText.isFocusable());
-        assertFalse(secondEditText.isFocused());
-        assertFalse(secondEditText.isAccessibilityFocused());
-
-        getInstrumentation().getUiAutomation().executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                // Perform a set focus action and check for success.
-                assertTrue(secondEditText.performAction(ACTION_ACCESSIBILITY_FOCUS));
-                
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return event.getEventType() == AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED;
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Get the node info again.
-        secondEditText.refresh();
-
-        // Make sure no other node has accessibility focus.
-        AccessibilityNodeInfo root = getInstrumentation().getUiAutomation().getRootInActiveWindow();
-        Queue<AccessibilityNodeInfo> workQueue = new LinkedList<AccessibilityNodeInfo>();
-        workQueue.add(root);
-        while (!workQueue.isEmpty()) {
-            AccessibilityNodeInfo current = workQueue.poll();
-            if (current.isAccessibilityFocused() && !current.equals(secondEditText)) {
-                fail();
-            }
-            final int childCount = current.getChildCount();
-            for (int i = 0; i < childCount; i++) {
-                AccessibilityNodeInfo child = current.getChild(i);
-                if (child != null) {
-                    workQueue.offer(child);
-                }
-            }
-        }
-    }
-}
diff --git a/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTextTraversalActivity.java b/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTextTraversalActivity.java
deleted file mode 100644
index 4a4a4ba..0000000
--- a/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTextTraversalActivity.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/**
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 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.accessibilityservice.cts;
-
-import android.os.Bundle;
-
-import com.android.cts.accessibilityservice.R;
-
-/**
- * Activity for testing the accessibility APIs for traversing the
- * text content of a View at several granularities.
- */
-public class AccessibilityTextTraversalActivity extends AccessibilityTestActivity {
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.accessibility_text_traversal_test);
-    }
-}
diff --git a/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTextTraversalTest.java b/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTextTraversalTest.java
deleted file mode 100644
index cb0877d..0000000
--- a/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTextTraversalTest.java
+++ /dev/null
@@ -1,4646 +0,0 @@
-/**
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 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.accessibilityservice.cts;
-
-import android.app.UiAutomation;
-import android.content.pm.PackageManager;
-import android.os.Bundle;
-import android.test.suitebuilder.annotation.MediumTest;
-import android.text.Selection;
-import android.text.TextUtils;
-import android.view.View;
-import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityNodeInfo;
-import android.widget.EditText;
-import android.widget.TextView;
-
-import com.android.cts.accessibilityservice.R;
-
-/**
- * Test cases for testing the accessibility APIs for traversing the text content of
- * a View at several granularities.
- */
-public class AccessibilityTextTraversalTest
-        extends AccessibilityActivityTestCase<AccessibilityTextTraversalActivity>{
-
-    public AccessibilityTextTraversalTest() {
-        super(AccessibilityTextTraversalActivity.class);
-    }
-
-    @MediumTest
-    public void testActionNextAndPreviousAtGranularityCharacterOverContentDescription()
-            throws Exception {
-        final View view = getActivity().findViewById(R.id.view);
-
-        getInstrumentation().runOnMainSync(new Runnable() {
-            @Override
-            public void run() {
-                view.setVisibility(View.VISIBLE);
-                view.setContentDescription(getString(R.string.a_b));
-            }
-        });
-
-        final AccessibilityNodeInfo text = getInstrumentation().getUiAutomation()
-                .getRootInActiveWindow().findAccessibilityNodeInfosByText(
-                        getString(R.string.a_b)).get(0);
-
-        final int granularities = text.getMovementGranularities();
-        assertEquals(granularities, AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER
-                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD
-                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH);
-
-        final Bundle arguments = new Bundle();
-        arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT,
-                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER);
-
-        // Move to the next character and wait for an event.
-        AccessibilityEvent firstExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY,
-                        arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(View.class.getName())
-                        && event.getContentDescription().toString().equals(
-                                getString(R.string.a_b))
-                        && event.getFromIndex() == 0
-                        && event.getToIndex() == 1
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(firstExpected);
-
-        // Move to the next character and wait for an event.
-        AccessibilityEvent secondExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY,
-                        arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(View.class.getName())
-                        && event.getContentDescription().toString().equals(
-                                getString(R.string.a_b))
-                        && event.getFromIndex() == 1
-                        && event.getToIndex() == 2
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(secondExpected);
-
-        // Move to the next character and wait for an event.
-        AccessibilityEvent thirdExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY,
-                        arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(View.class.getName())
-                        && event.getContentDescription().toString().equals(
-                                getString(R.string.a_b))
-                        && event.getFromIndex() == 2
-                        && event.getToIndex() == 3
-                        && event.getMovementGranularity() ==
-                                 AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(thirdExpected);
-
-        // Make sure there is no next.
-        assertFalse(text.performAction(AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY,
-                arguments));
-
-        // Move to the previous character and wait for an event.
-        AccessibilityEvent fourthExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY,
-                        arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(View.class.getName())
-                        && event.getContentDescription().toString().equals(
-                                getString(R.string.a_b))
-                        && event.getFromIndex() == 2
-                        && event.getToIndex() == 3
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(fourthExpected);
-
-        // Move to the previous character and wait for an event.
-        AccessibilityEvent fifthExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY,
-                        arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(View.class.getName())
-                        && event.getContentDescription().toString().equals(
-                                getString(R.string.a_b))
-                        && event.getFromIndex() == 1
-                        && event.getToIndex() == 2
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(fifthExpected);
-
-        // Move to the next character and wait for an event.
-        AccessibilityEvent sixthExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY,
-                        arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(View.class.getName())
-                        && event.getContentDescription().toString().equals(
-                                getString(R.string.a_b))
-                        && event.getFromIndex() == 0
-                        && event.getToIndex() == 1
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(sixthExpected);
-
-        // Make sure there is no previous.
-        assertFalse(text.performAction(
-                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments));
-    }
-
-    @MediumTest
-    public void testActionNextAndPreviousAtGranularityWordOverContentDescription()
-            throws Exception {
-        final View view = getActivity().findViewById(R.id.view);
-
-        getInstrumentation().runOnMainSync(new Runnable() {
-            @Override
-            public void run() {
-                view.setVisibility(View.VISIBLE);
-                view.setContentDescription(getString(R.string.foo_bar_baz));
-            }
-        });
-
-        final AccessibilityNodeInfo text = getInstrumentation().getUiAutomation()
-                .getRootInActiveWindow().findAccessibilityNodeInfosByText(
-                        getString(R.string.foo_bar_baz)).get(0);
-
-        final int granularities = text.getMovementGranularities();
-        assertEquals(granularities, AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER
-                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD
-                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH);
-
-        final Bundle arguments = new Bundle();
-        arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT,
-                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
-
-        // Move to the next character and wait for an event.
-        AccessibilityEvent firstExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(View.class.getName())
-                        && event.getContentDescription().toString().equals(
-                                getString(R.string.foo_bar_baz))
-                        && event.getFromIndex() == 0
-                        && event.getToIndex() == 3
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(firstExpected);
-
-        // Move to the next character and wait for an event.
-        AccessibilityEvent secondExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(View.class.getName())
-                        && event.getContentDescription().toString().equals(
-                                getString(R.string.foo_bar_baz))
-                        && event.getFromIndex() == 4
-                        && event.getToIndex() == 7
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(secondExpected);
-
-        // Move to the next character and wait for an event.
-        AccessibilityEvent thirdExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(View.class.getName())
-                        && event.getContentDescription().toString().equals(
-                                getString(R.string.foo_bar_baz))
-                        && event.getFromIndex() == 8
-                        && event.getToIndex() == 11
-                        && event.getMovementGranularity() ==
-                               AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(thirdExpected);
-
-        // Make sure there is no next.
-        assertFalse(text.performAction(
-                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments));
-
-        // Move to the next character and wait for an event.
-        AccessibilityEvent fourthExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(View.class.getName())
-                        && event.getContentDescription().toString().equals(
-                                getString(R.string.foo_bar_baz))
-                        && event.getFromIndex() == 8
-                        && event.getToIndex() == 11
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(fourthExpected);
-
-        // Move to the next character and wait for an event.
-        AccessibilityEvent fifthExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(View.class.getName())
-                        && event.getContentDescription().toString().equals(
-                                getString(R.string.foo_bar_baz))
-                        && event.getFromIndex() == 4
-                        && event.getToIndex() == 7
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(fifthExpected);
-
-        // Move to the next character and wait for an event.
-        AccessibilityEvent sixthExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(View.class.getName())
-                        && event.getContentDescription().toString().equals(
-                                getString(R.string.foo_bar_baz))
-                        && event.getFromIndex() == 0
-                        && event.getToIndex() == 3
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(sixthExpected);
-
-        // Make sure there is no previous.
-        assertFalse(text.performAction(
-                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments));
-    }
-
-    @MediumTest
-    public void testActionNextAndPreviousAtGranularityCharacterOverText()
-            throws Exception {
-        final TextView textView = (TextView) getActivity().findViewById(R.id.text);
-
-        getInstrumentation().runOnMainSync(new Runnable() {
-            @Override
-            public void run() {
-                textView.setVisibility(View.VISIBLE);
-                textView.setText(getString(R.string.a_b));
-            }
-        });
-
-        final AccessibilityNodeInfo text = getInstrumentation().getUiAutomation()
-               .getRootInActiveWindow().findAccessibilityNodeInfosByText(
-                       getString(R.string.a_b)).get(0);
-
-        final int granularities = text.getMovementGranularities();
-        assertEquals(granularities, AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER
-                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD
-                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE
-                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH
-                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
-
-        final Bundle arguments = new Bundle();
-        arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT,
-                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER);
-
-        // Move to the next character and wait for an event.
-        AccessibilityEvent firstExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(TextView.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(R.string.a_b))
-                        && event.getFromIndex() == 0
-                        && event.getToIndex() == 1
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(firstExpected);
-
-        // Verify the selection position.
-        assertEquals(1, Selection.getSelectionStart(textView.getText()));
-        assertEquals(1, Selection.getSelectionEnd(textView.getText()));
-
-        // Move to the next character and wait for an event.
-        AccessibilityEvent secondExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(TextView.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(R.string.a_b))
-                        && event.getFromIndex() == 1
-                        && event.getToIndex() == 2
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(secondExpected);
-
-        // Verify the selection position.
-        assertEquals(2, Selection.getSelectionStart(textView.getText()));
-        assertEquals(2, Selection.getSelectionEnd(textView.getText()));
-
-        // Move to the next character and wait for an event.
-        AccessibilityEvent thirdExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(TextView.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(R.string.a_b))
-                        && event.getFromIndex() == 2
-                        && event.getToIndex() == 3
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(thirdExpected);
-
-        // Verify the selection position.
-        assertEquals(3, Selection.getSelectionStart(textView.getText()));
-        assertEquals(3, Selection.getSelectionEnd(textView.getText()));
-
-        // Make sure there is no next.
-        assertFalse(text.performAction(
-                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments));
-
-        // Verify the selection position.
-        assertEquals(3, Selection.getSelectionStart(textView.getText()));
-        assertEquals(3, Selection.getSelectionEnd(textView.getText()));
-
-        // Move to the previous character and wait for an event.
-        AccessibilityEvent fifthExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(TextView.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(R.string.a_b))
-                        && event.getFromIndex() == 2
-                        && event.getToIndex() == 3
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(fifthExpected);
-
-        // Verify the selection position.
-        assertEquals(2, Selection.getSelectionStart(textView.getText()));
-        assertEquals(2, Selection.getSelectionEnd(textView.getText()));
-
-        // Move to the previous character and wait for an event.
-        AccessibilityEvent sixthExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(TextView.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(R.string.a_b))
-                        && event.getFromIndex() == 1
-                        && event.getToIndex() == 2
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(sixthExpected);
-
-        // Verify the selection position.
-        assertEquals(1, Selection.getSelectionStart(textView.getText()));
-        assertEquals(1, Selection.getSelectionEnd(textView.getText()));
-
-        // Move to the previous character and wait for an event.
-        AccessibilityEvent seventhExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(TextView.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(R.string.a_b))
-                        && event.getFromIndex() == 0
-                        && event.getToIndex() == 1
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(seventhExpected);
-
-        // Verify the selection position.
-        assertEquals(0, Selection.getSelectionStart(textView.getText()));
-        assertEquals(0, Selection.getSelectionEnd(textView.getText()));
-
-        // Make sure there is no previous.
-        assertFalse(text.performAction(
-                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments));
-
-        // Verify the selection position.
-        assertEquals(0, Selection.getSelectionStart(textView.getText()));
-        assertEquals(0, Selection.getSelectionEnd(textView.getText()));
-    }
-
-    @MediumTest
-    public void testActionNextAndPreviousAtGranularityCharacterOverTextExtend()
-            throws Exception {
-        final EditText editText = (EditText) getActivity().findViewById(R.id.edit);
-
-        getInstrumentation().runOnMainSync(new Runnable() {
-            @Override
-            public void run() {
-                editText.setVisibility(View.VISIBLE);
-                editText.setText(getString(R.string.a_b));
-                Selection.removeSelection(editText.getText());
-            }
-        });
-
-        final AccessibilityNodeInfo text = getInstrumentation().getUiAutomation()
-               .getRootInActiveWindow().findAccessibilityNodeInfosByText(
-                       getString(R.string.a_b)).get(0);
-
-        final int granularities = text.getMovementGranularities();
-        assertEquals(granularities, AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER
-                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD
-                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE
-                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH
-                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
-
-        final Bundle arguments = new Bundle();
-        arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT,
-                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER);
-        arguments.putBoolean(AccessibilityNodeInfo.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN, true);
-
-        // Move to the next character and wait for an event.
-        AccessibilityEvent firstExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(R.string.a_b))
-                        && event.getFromIndex() == 0
-                        && event.getToIndex() == 1
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(firstExpected);
-
-        // Verify the selection position.
-        assertEquals(0, Selection.getSelectionStart(editText.getText()));
-        assertEquals(1, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the next character and wait for an event.
-        AccessibilityEvent secondExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(R.string.a_b))
-                        && event.getFromIndex() == 1
-                        && event.getToIndex() == 2
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(secondExpected);
-
-        // Verify the selection position.
-        assertEquals(0, Selection.getSelectionStart(editText.getText()));
-        assertEquals(2, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the next character and wait for an event.
-        AccessibilityEvent thirdExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(R.string.a_b))
-                        && event.getFromIndex() == 2
-                        && event.getToIndex() == 3
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(thirdExpected);
-
-        // Verify the selection position.
-        assertEquals(0, Selection.getSelectionStart(editText.getText()));
-        assertEquals(3, Selection.getSelectionEnd(editText.getText()));
-
-        // Make sure there is no next.
-        assertFalse(text.performAction(
-                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments));
-
-        // Verify the selection position.
-        assertEquals(0, Selection.getSelectionStart(editText.getText()));
-        assertEquals(3, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the previous character and wait for an event.
-        AccessibilityEvent fourthExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(R.string.a_b))
-                        && event.getFromIndex() == 2
-                        && event.getToIndex() == 3
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(fourthExpected);
-
-        // Verify the selection position.
-        assertEquals(0, Selection.getSelectionStart(editText.getText()));
-        assertEquals(2, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the previous character and wait for an event.
-        AccessibilityEvent fifthExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(R.string.a_b))
-                        && event.getFromIndex() == 1
-                        && event.getToIndex() == 2
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(fifthExpected);
-
-        // Verify the selection position.
-        assertEquals(0, Selection.getSelectionStart(editText.getText()));
-        assertEquals(1, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the previous character and wait for an event.
-        AccessibilityEvent sixthExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(R.string.a_b))
-                        && event.getFromIndex() == 0
-                        && event.getToIndex() == 1
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(sixthExpected);
-
-        // Verify the selection position.
-        assertEquals(0, Selection.getSelectionStart(editText.getText()));
-        assertEquals(0, Selection.getSelectionEnd(editText.getText()));
-
-        // Make sure there is no previous.
-        assertFalse(text.performAction(
-                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments));
-
-        // Verify the selection position.
-        assertEquals(0, Selection.getSelectionStart(editText.getText()));
-        assertEquals(0, Selection.getSelectionEnd(editText.getText()));
-
-        // Focus the view so we can change selection.
-        getInstrumentation().runOnMainSync(new Runnable() {
-            @Override
-            public void run() {
-                editText.setFocusable(true);
-                editText.requestFocus();
-            }
-        });
-
-        // Put selection at the end of the text.
-        Bundle setSelectionArgs = new Bundle();
-        setSelectionArgs.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT, 3);
-        setSelectionArgs.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT, 3);
-        assertTrue(text.performAction(
-                AccessibilityNodeInfo.ACTION_SET_SELECTION, setSelectionArgs));
-
-        // Verify the selection position.
-        assertEquals(3, Selection.getSelectionStart(editText.getText()));
-        assertEquals(3, Selection.getSelectionEnd(editText.getText()));
-
-        // Unfocus the view so we can get rid of the soft-keyboard.
-        getInstrumentation().runOnMainSync(new Runnable() {
-            @Override
-            public void run() {
-                editText.clearFocus();
-                editText.setFocusable(false);
-            }
-        });
-
-        // Move to the previous character and wait for an event.
-        AccessibilityEvent seventhExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(R.string.a_b))
-                        && event.getFromIndex() == 2
-                        && event.getToIndex() == 3
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(seventhExpected);
-
-        // Verify the selection position.
-        assertEquals(3, Selection.getSelectionStart(editText.getText()));
-        assertEquals(2, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the previous character and wait for an event.
-        AccessibilityEvent eightExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(R.string.a_b))
-                        && event.getFromIndex() == 1
-                        && event.getToIndex() == 2
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(eightExpected);
-
-        // Verify the selection position.
-        assertEquals(3, Selection.getSelectionStart(editText.getText()));
-        assertEquals(1, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the previous character and wait for an event.
-        AccessibilityEvent ninethExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(R.string.a_b))
-                        && event.getFromIndex() == 0
-                        && event.getToIndex() == 1
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(ninethExpected);
-
-        // Verify the selection position.
-        assertEquals(3, Selection.getSelectionStart(editText.getText()));
-        assertEquals(0, Selection.getSelectionEnd(editText.getText()));
-
-        // Make sure there is no previous.
-        assertFalse(text.performAction(
-                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments));
-
-        // Verify the selection position.
-        assertEquals(3, Selection.getSelectionStart(editText.getText()));
-        assertEquals(0, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the next character and wait for an event.
-        AccessibilityEvent tenthExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(R.string.a_b))
-                        && event.getFromIndex() == 0
-                        && event.getToIndex() == 1
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(tenthExpected);
-
-        // Verify the selection position.
-        assertEquals(3, Selection.getSelectionStart(editText.getText()));
-        assertEquals(1, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the next character and wait for an event.
-        AccessibilityEvent eleventhExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(R.string.a_b))
-                        && event.getFromIndex() == 1
-                        && event.getToIndex() == 2
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(eleventhExpected);
-
-        // Verify the selection position.
-        assertEquals(3, Selection.getSelectionStart(editText.getText()));
-        assertEquals(2, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the next character and wait for an event.
-        AccessibilityEvent twelvethExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(R.string.a_b))
-                        && event.getFromIndex() == 2
-                        && event.getToIndex() == 3
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(twelvethExpected);
-
-        // Verify the selection position.
-        assertEquals(3, Selection.getSelectionStart(editText.getText()));
-        assertEquals(3, Selection.getSelectionEnd(editText.getText()));
-
-        // Make sure there is no next.
-        assertFalse(text.performAction(
-                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments));
-
-        // Verify the selection position.
-        assertEquals(3, Selection.getSelectionStart(editText.getText()));
-        assertEquals(3, Selection.getSelectionEnd(editText.getText()));
-    }
-
-    @MediumTest
-    public void testActionNextAndPreviousAtGranularityWordOverText() throws Exception {
-        final TextView textView = (TextView) getActivity().findViewById(R.id.text);
-
-        getInstrumentation().runOnMainSync(new Runnable() {
-            @Override
-            public void run() {
-                textView.setVisibility(View.VISIBLE);
-                textView.setText(getString(R.string.foo_bar_baz));
-            }
-        });
-
-        final AccessibilityNodeInfo text = getInstrumentation().getUiAutomation()
-               .getRootInActiveWindow().findAccessibilityNodeInfosByText(getString(
-                       R.string.foo_bar_baz)).get(0);
-
-        final int granularities = text.getMovementGranularities();
-        assertEquals(granularities, AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER
-                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD
-                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE
-                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH
-                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
-
-        final Bundle arguments = new Bundle();
-        arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT,
-                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
-
-        // Move to the next word and wait for an event.
-        AccessibilityEvent firstExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(TextView.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(R.string.foo_bar_baz))
-                        && event.getFromIndex() == 0
-                        && event.getToIndex() == 3
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(firstExpected);
-
-        // Verify the selection position.
-        assertEquals(3, Selection.getSelectionStart(textView.getText()));
-        assertEquals(3, Selection.getSelectionEnd(textView.getText()));
-
-        // Move to the next word and wait for an event.
-        AccessibilityEvent secondExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(TextView.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(R.string.foo_bar_baz))
-                        && event.getFromIndex() == 4
-                        && event.getToIndex() == 7
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(secondExpected);
-
-        // Verify the selection position.
-        assertEquals(7, Selection.getSelectionStart(textView.getText()));
-        assertEquals(7, Selection.getSelectionEnd(textView.getText()));
-
-        // Move to the next word and wait for an event.
-        AccessibilityEvent thirdExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(TextView.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(R.string.foo_bar_baz))
-                        && event.getFromIndex() == 8
-                        && event.getToIndex() == 11
-                        && event.getMovementGranularity() ==
-                                 AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(thirdExpected);
-
-        // Verify the selection position.
-        assertEquals(11, Selection.getSelectionStart(textView.getText()));
-        assertEquals(11, Selection.getSelectionEnd(textView.getText()));
-
-        // Make sure there is no next.
-        assertFalse(text.performAction(
-                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments));
-
-        // Verify the selection position.
-        assertEquals(11, Selection.getSelectionStart(textView.getText()));
-        assertEquals(11, Selection.getSelectionEnd(textView.getText()));
-
-        // Move to the next word and wait for an event.
-        AccessibilityEvent fourthExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(TextView.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(R.string.foo_bar_baz))
-                        && event.getFromIndex() == 8
-                        && event.getToIndex() == 11
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(fourthExpected);
-
-        // Verify the selection position.
-        assertEquals(8, Selection.getSelectionStart(textView.getText()));
-        assertEquals(8, Selection.getSelectionEnd(textView.getText()));
-
-        // Move to the next word and wait for an event.
-        AccessibilityEvent fifthExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(TextView.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(R.string.foo_bar_baz))
-                        && event.getFromIndex() == 4
-                        && event.getToIndex() == 7
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(fifthExpected);
-
-        // Verify the selection position.
-        assertEquals(4, Selection.getSelectionStart(textView.getText()));
-        assertEquals(4, Selection.getSelectionEnd(textView.getText()));
-
-        // Move to the next character and wait for an event.
-        AccessibilityEvent sixthExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(TextView.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(R.string.foo_bar_baz))
-                        && event.getFromIndex() == 0
-                        && event.getToIndex() == 3
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(sixthExpected);
-
-        // Verify the selection position.
-        assertEquals(0, Selection.getSelectionStart(textView.getText()));
-        assertEquals(0, Selection.getSelectionEnd(textView.getText()));
-
-        // Make sure there is no previous.
-        assertFalse(text.performAction(
-                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments));
-
-        // Verify the selection position.
-        assertEquals(0, Selection.getSelectionStart(textView.getText()));
-        assertEquals(0, Selection.getSelectionEnd(textView.getText()));
-    }
-
-    @MediumTest
-    public void testActionNextAndPreviousAtGranularityWordOverEditTextWithContentDescription()
-            throws Exception {
-        final EditText editText = (EditText) getActivity().findViewById(R.id.edit);
-
-        getInstrumentation().runOnMainSync(new Runnable() {
-            @Override
-            public void run() {
-                editText.setVisibility(View.VISIBLE);
-                editText.setText(getString(R.string.foo_bar_baz));
-                editText.setContentDescription(getString(R.string.android_wiki));
-            }
-        });
-
-        final AccessibilityNodeInfo text = getInstrumentation().getUiAutomation()
-               .getRootInActiveWindow().findAccessibilityNodeInfosByText(getString(
-                       R.string.foo_bar_baz)).get(0);
-
-        final int granularities = text.getMovementGranularities();
-        assertEquals(granularities, AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER
-                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD
-                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE
-                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH
-                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
-
-        final Bundle arguments = new Bundle();
-        arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT,
-                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
-
-        // Move to the next word and wait for an event.
-        AccessibilityEvent firstExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(R.string.foo_bar_baz))
-                        && event.getContentDescription().equals(getString(R.string.android_wiki))
-                        && event.getFromIndex() == 0
-                        && event.getToIndex() == 3
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(firstExpected);
-
-        // Verify the selection position.
-        assertEquals(3, editText.getSelectionStart());
-        assertEquals(3, editText.getSelectionEnd());
-
-        // Move to the next word and wait for an event.
-        AccessibilityEvent secondExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(R.string.foo_bar_baz))
-                        && event.getContentDescription().equals(getString(R.string.android_wiki))
-                        && event.getFromIndex() == 4
-                        && event.getToIndex() == 7
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(secondExpected);
-
-        // Verify the selection position.
-        assertEquals(7, editText.getSelectionStart());
-        assertEquals(7, editText.getSelectionEnd());
-
-        // Move to the next word and wait for an event.
-        AccessibilityEvent thirdExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(R.string.foo_bar_baz))
-                        && event.getContentDescription().equals(getString(R.string.android_wiki))
-                        && event.getFromIndex() == 8
-                        && event.getToIndex() == 11
-                        && event.getMovementGranularity() ==
-                                 AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(thirdExpected);
-
-        // Verify the selection position.
-        assertEquals(11, editText.getSelectionStart());
-        assertEquals(11, editText.getSelectionEnd());
-
-        // Make sure there is no next.
-        assertFalse(text.performAction(
-                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments));
-
-        // Verify the selection position.
-        assertEquals(11, editText.getSelectionStart());
-        assertEquals(11, editText.getSelectionEnd());
-
-        // Move to the next word and wait for an event.
-        AccessibilityEvent fourthExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(R.string.foo_bar_baz))
-                        && event.getContentDescription().equals(getString(R.string.android_wiki))
-                        && event.getFromIndex() == 8
-                        && event.getToIndex() == 11
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(fourthExpected);
-
-        // Verify the selection position.
-        assertEquals(8, editText.getSelectionStart());
-        assertEquals(8, editText.getSelectionEnd());
-
-        // Move to the next word and wait for an event.
-        AccessibilityEvent fifthExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(R.string.foo_bar_baz))
-                        && event.getContentDescription().equals(getString(R.string.android_wiki))
-                        && event.getFromIndex() == 4
-                        && event.getToIndex() == 7
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(fifthExpected);
-
-        // Verify the selection position.
-        assertEquals(4, editText.getSelectionStart());
-        assertEquals(4, editText.getSelectionEnd());
-
-        // Move to the next character and wait for an event.
-        AccessibilityEvent sixthExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(R.string.foo_bar_baz))
-                        && event.getContentDescription().equals(getString(R.string.android_wiki))
-                        && event.getFromIndex() == 0
-                        && event.getToIndex() == 3
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(sixthExpected);
-
-        // Verify the selection position.
-        assertEquals(0, editText.getSelectionStart());
-        assertEquals(0, editText.getSelectionEnd());
-
-        // Make sure there is no previous.
-        assertFalse(text.performAction(
-                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments));
-
-        // Verify the selection position.
-        assertEquals(0, editText.getSelectionStart());
-        assertEquals(0, editText.getSelectionEnd());
-    }
-
-    @MediumTest
-    public void testActionNextAndPreviousAtGranularityWordOverTextExtend() throws Exception {
-        final EditText editText = (EditText) getActivity().findViewById(R.id.edit);
-
-        getInstrumentation().runOnMainSync(new Runnable() {
-            @Override
-            public void run() {
-                editText.setVisibility(View.VISIBLE);
-                editText.setText(getString(R.string.foo_bar_baz));
-                Selection.removeSelection(editText.getText());
-            }
-        });
-
-        final AccessibilityNodeInfo text = getInstrumentation().getUiAutomation()
-               .getRootInActiveWindow().findAccessibilityNodeInfosByText(getString(
-                       R.string.foo_bar_baz)).get(0);
-
-        final int granularities = text.getMovementGranularities();
-        assertEquals(granularities, AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER
-                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD
-                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE
-                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH
-                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
-
-        final Bundle arguments = new Bundle();
-        arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT,
-                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
-        arguments.putBoolean(AccessibilityNodeInfo.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN, true);
-
-        // Move to the next word and wait for an event.
-        AccessibilityEvent firstExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(R.string.foo_bar_baz))
-                        && event.getFromIndex() == 0
-                        && event.getToIndex() == 3
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(firstExpected);
-
-        // Verify the selection position.
-        assertEquals(0, Selection.getSelectionStart(editText.getText()));
-        assertEquals(3, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the next word and wait for an event.
-        AccessibilityEvent secondExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(R.string.foo_bar_baz))
-                        && event.getFromIndex() == 4
-                        && event.getToIndex() == 7
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(secondExpected);
-
-        // Verify the selection position.
-        assertEquals(0, Selection.getSelectionStart(editText.getText()));
-        assertEquals(7, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the next word and wait for an event.
-        AccessibilityEvent thirdExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(R.string.foo_bar_baz))
-                        && event.getFromIndex() == 8
-                        && event.getToIndex() == 11
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(thirdExpected);
-
-        // Verify the selection position.
-        assertEquals(0, Selection.getSelectionStart(editText.getText()));
-        assertEquals(11, Selection.getSelectionEnd(editText.getText()));
-
-        // Make sure there is no next.
-        assertFalse(text.performAction(
-                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments));
-
-        // Move to the previous word and wait for an event.
-        AccessibilityEvent fourthExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(R.string.foo_bar_baz))
-                        && event.getFromIndex() == 8
-                        && event.getToIndex() == 11
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(fourthExpected);
-
-        // Verify the selection position.
-        assertEquals(0, Selection.getSelectionStart(editText.getText()));
-        assertEquals(8, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the previous word and wait for an event.
-        AccessibilityEvent fifthExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(R.string.foo_bar_baz))
-                        && event.getFromIndex() == 4
-                        && event.getToIndex() == 7
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(fifthExpected);
-
-        // Verify the selection position.
-        assertEquals(0, Selection.getSelectionStart(editText.getText()));
-        assertEquals(4, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the previous character and wait for an event.
-        AccessibilityEvent sixthExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(R.string.foo_bar_baz))
-                        && event.getFromIndex() == 0
-                        && event.getToIndex() == 3
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(sixthExpected);
-
-        // Verify the selection position.
-        assertEquals(0, Selection.getSelectionStart(editText.getText()));
-        assertEquals(0, Selection.getSelectionEnd(editText.getText()));
-
-        // Make sure there is no previous.
-        assertFalse(text.performAction(
-                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments));
-
-        // Verify the selection position.
-        assertEquals(0, Selection.getSelectionStart(editText.getText()));
-        assertEquals(0, Selection.getSelectionEnd(editText.getText()));
-
-        // Focus the view so we can change selection.
-        getInstrumentation().runOnMainSync(new Runnable() {
-            @Override
-            public void run() {
-                editText.setFocusable(true);
-                editText.requestFocus();
-            }
-        });
-
-        // Put selection at the end of the text.
-        Bundle setSelectionArgs = new Bundle();
-        setSelectionArgs.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT, 11);
-        setSelectionArgs.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT, 11);
-        assertTrue(text.performAction(
-                AccessibilityNodeInfo.ACTION_SET_SELECTION, setSelectionArgs));
-
-        // Verify the selection position.
-        assertEquals(11, Selection.getSelectionStart(editText.getText()));
-        assertEquals(11, Selection.getSelectionEnd(editText.getText()));
-
-        // Unfocus the view so we can get rid of the soft-keyboard.
-        getInstrumentation().runOnMainSync(new Runnable() {
-            @Override
-            public void run() {
-                editText.clearFocus();
-                editText.setFocusable(false);
-            }
-        });
-
-        // Move to the previous word and wait for an event.
-        AccessibilityEvent seventhExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(R.string.foo_bar_baz))
-                        && event.getFromIndex() == 8
-                        && event.getToIndex() == 11
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(seventhExpected);
-
-        // Verify the selection position.
-        assertEquals(11, Selection.getSelectionStart(editText.getText()));
-        assertEquals(8, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the previous word and wait for an event.
-        AccessibilityEvent eightExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(R.string.foo_bar_baz))
-                        && event.getFromIndex() == 4
-                        && event.getToIndex() == 7
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(eightExpected);
-
-        // Verify the selection position.
-        assertEquals(11, Selection.getSelectionStart(editText.getText()));
-        assertEquals(4, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the previous character and wait for an event.
-        AccessibilityEvent ninethExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(R.string.foo_bar_baz))
-                        && event.getFromIndex() == 0
-                        && event.getToIndex() == 3
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(ninethExpected);
-
-        // Verify the selection position.
-        assertEquals(11, Selection.getSelectionStart(editText.getText()));
-        assertEquals(0, Selection.getSelectionEnd(editText.getText()));
-
-        // Make sure there is no previous.
-        assertFalse(text.performAction(
-                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments));
-
-        // Verify the selection position.
-        assertEquals(11, Selection.getSelectionStart(editText.getText()));
-        assertEquals(0, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the next word and wait for an event.
-        AccessibilityEvent tenthExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(R.string.foo_bar_baz))
-                        && event.getFromIndex() == 0
-                        && event.getToIndex() == 3
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(tenthExpected);
-
-        // Verify the selection position.
-        assertEquals(11, Selection.getSelectionStart(editText.getText()));
-        assertEquals(3, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the next word and wait for an event.
-        AccessibilityEvent eleventhExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(R.string.foo_bar_baz))
-                        && event.getFromIndex() == 4
-                        && event.getToIndex() == 7
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(eleventhExpected);
-
-        // Verify the selection position.
-        assertEquals(11, Selection.getSelectionStart(editText.getText()));
-        assertEquals(7, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the next word and wait for an event.
-        AccessibilityEvent twelvthExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(R.string.foo_bar_baz))
-                        && event.getFromIndex() == 8
-                        && event.getToIndex() == 11
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(twelvthExpected);
-
-        // Verify the selection position.
-        assertEquals(11, Selection.getSelectionStart(editText.getText()));
-        assertEquals(11, Selection.getSelectionEnd(editText.getText()));
-
-        // Make sure there is no next.
-        assertFalse(text.performAction(
-                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments));
-
-        // Verify the selection position.
-        assertEquals(11, Selection.getSelectionStart(editText.getText()));
-        assertEquals(11, Selection.getSelectionEnd(editText.getText()));
-    }
-
-    @MediumTest
-    public void testActionNextAndPreviousAtGranularityLineOverText() throws Exception {
-        final TextView textView = (TextView) getActivity().findViewById(R.id.text);
-
-        getInstrumentation().runOnMainSync(new Runnable() {
-            @Override
-            public void run() {
-                textView.setVisibility(View.VISIBLE);
-                textView.setText(getString(R.string.android_wiki_short));
-            }
-        });
-
-        final AccessibilityNodeInfo text = getInstrumentation().getUiAutomation()
-               .getRootInActiveWindow().findAccessibilityNodeInfosByText(getString(
-                       R.string.android_wiki_short)).get(0);
-
-        final int granularities = text.getMovementGranularities();
-        assertEquals(granularities, AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER
-                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD
-                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE
-                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH
-                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
-
-        final Bundle arguments = new Bundle();
-        arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT,
-                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE);
-
-        // Move to the next line and wait for an event.
-        AccessibilityEvent firstExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(TextView.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki_short))
-                        && event.getFromIndex() == 0
-                        && event.getToIndex() == 13
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(firstExpected);
-
-        // Verify the selection position.
-        assertEquals(13, Selection.getSelectionStart(textView.getText()));
-        assertEquals(13, Selection.getSelectionEnd(textView.getText()));
-
-        // Move to the next line and wait for an event.
-        AccessibilityEvent secondExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(TextView.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki_short))
-                        && event.getFromIndex() == 13
-                        && event.getToIndex() == 25
-                        && event.getMovementGranularity() ==
-                                 AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(secondExpected);
-
-        // Verify the selection position.
-        assertEquals(25, Selection.getSelectionStart(textView.getText()));
-        assertEquals(25, Selection.getSelectionEnd(textView.getText()));
-
-        // Move to the next line and wait for an event.
-        AccessibilityEvent thirdExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(TextView.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki_short))
-                        && event.getFromIndex() == 25
-                        && event.getToIndex() == 34
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(thirdExpected);
-
-        // Verify the selection position.
-        assertEquals(34, Selection.getSelectionStart(textView.getText()));
-        assertEquals(34, Selection.getSelectionEnd(textView.getText()));
-
-        // Make sure there is no next.
-        assertFalse(text.performAction(
-                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments));
-
-        // Verify the selection position.
-        assertEquals(34, Selection.getSelectionStart(textView.getText()));
-        assertEquals(34, Selection.getSelectionEnd(textView.getText()));
-
-        // Move to the previous line and wait for an event.
-        AccessibilityEvent fourthExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(TextView.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki_short))
-                        && event.getFromIndex() == 25
-                        && event.getToIndex() == 34
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(fourthExpected);
-
-        // Verify the selection position.
-        assertEquals(25, Selection.getSelectionStart(textView.getText()));
-        assertEquals(25, Selection.getSelectionEnd(textView.getText()));
-
-        // Move to the previous line and wait for an event.
-        AccessibilityEvent fifthExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(TextView.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki_short))
-                        && event.getFromIndex() == 13
-                        && event.getToIndex() == 25
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(fifthExpected);
-
-        // Verify the selection position.
-        assertEquals(13, Selection.getSelectionStart(textView.getText()));
-        assertEquals(13, Selection.getSelectionEnd(textView.getText()));
-
-        // Move to the previous line and wait for an event.
-        AccessibilityEvent sixthExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(TextView.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki_short))
-                        && event.getFromIndex() == 0
-                        && event.getToIndex() == 13
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(sixthExpected);
-
-        // Verify the selection position.
-        assertEquals(0, Selection.getSelectionStart(textView.getText()));
-        assertEquals(0, Selection.getSelectionEnd(textView.getText()));
-
-        // Make sure there is no previous.
-        assertFalse(text.performAction(
-                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments));
-
-        // Verify the selection position.
-        assertEquals(0, Selection.getSelectionStart(textView.getText()));
-        assertEquals(0, Selection.getSelectionEnd(textView.getText()));
-    }
-
-    @MediumTest
-    public void testActionNextAndPreviousAtGranularityLineOverTextExtend() throws Exception {
-        final EditText editText = (EditText) getActivity().findViewById(R.id.edit);
-
-        getInstrumentation().runOnMainSync(new Runnable() {
-            @Override
-            public void run() {
-                editText.setVisibility(View.VISIBLE);
-                editText.setText(getString(R.string.android_wiki_short));
-                Selection.removeSelection(editText.getText());
-            }
-        });
-
-        final AccessibilityNodeInfo text = getInstrumentation().getUiAutomation()
-               .getRootInActiveWindow().findAccessibilityNodeInfosByText(getString(
-                       R.string.android_wiki_short)).get(0);
-
-        final int granularities = text.getMovementGranularities();
-        assertEquals(granularities, AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER
-                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD
-                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE
-                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH
-                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
-
-        final Bundle arguments = new Bundle();
-        arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT,
-                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE);
-        arguments.putBoolean(AccessibilityNodeInfo.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN, true);
-
-        // Move to the next line and wait for an event.
-        AccessibilityEvent firstExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki_short))
-                        && event.getFromIndex() == 0
-                        && event.getToIndex() == 13
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(firstExpected);
-
-        // Verify the selection position.
-        assertEquals(0, Selection.getSelectionStart(editText.getText()));
-        assertEquals(13, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the next line and wait for an event.
-        AccessibilityEvent secondExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki_short))
-                        && event.getFromIndex() == 13
-                        && event.getToIndex() == 25
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(secondExpected);
-
-        // Verify the selection position.
-        assertEquals(0, Selection.getSelectionStart(editText.getText()));
-        assertEquals(25, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the next line and wait for an event.
-        AccessibilityEvent thirdExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki_short))
-                        && event.getFromIndex() == 25
-                        && event.getToIndex() == 34
-                        && event.getMovementGranularity() ==
-                                 AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(thirdExpected);
-
-        // Verify the selection position.
-        assertEquals(0, Selection.getSelectionStart(editText.getText()));
-        assertEquals(34, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the previous line and wait for an event.
-        AccessibilityEvent fourthExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki_short))
-                        && event.getFromIndex() == 25
-                        && event.getToIndex() == 34
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(fourthExpected);
-
-        // Verify the selection position.
-        assertEquals(0, Selection.getSelectionStart(editText.getText()));
-        assertEquals(25, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the previous line and wait for an event.
-        AccessibilityEvent fifthExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki_short))
-                        && event.getFromIndex() == 13
-                        && event.getToIndex() == 25
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(fifthExpected);
-
-        // Verify the selection position.
-        assertEquals(0, Selection.getSelectionStart(editText.getText()));
-        assertEquals(13, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the previous line and wait for an event.
-        AccessibilityEvent sixthExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                               AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki_short))
-                        && event.getFromIndex() == 0
-                        && event.getToIndex() == 13
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(sixthExpected);
-
-        // Verify the selection position.
-        assertEquals(0, Selection.getSelectionStart(editText.getText()));
-        assertEquals(0, Selection.getSelectionEnd(editText.getText()));
-
-        // Make sure there is no previous.
-        assertFalse(text.performAction(
-                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments));
-
-        // Verify the selection position.
-        assertEquals(0, Selection.getSelectionStart(editText.getText()));
-        assertEquals(0, Selection.getSelectionEnd(editText.getText()));
-
-        // Focus the view so we can change selection.
-        getInstrumentation().runOnMainSync(new Runnable() {
-            @Override
-            public void run() {
-                editText.setFocusable(true);
-                editText.requestFocus();
-            }
-        });
-
-        // Put selection at the end of the text.
-        Bundle setSelectionArgs = new Bundle();
-        setSelectionArgs.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT, 34);
-        setSelectionArgs.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT, 34);
-        assertTrue(text.performAction(
-                AccessibilityNodeInfo.ACTION_SET_SELECTION, setSelectionArgs));
-
-        // Verify the selection position.
-        assertEquals(34, Selection.getSelectionStart(editText.getText()));
-        assertEquals(34, Selection.getSelectionEnd(editText.getText()));
-
-        // Unocus the view so we can hide the keyboard.
-        getInstrumentation().runOnMainSync(new Runnable() {
-            @Override
-            public void run() {
-                editText.clearFocus();
-                editText.setFocusable(false);
-            }
-        });
-
-        // Move to the previous line and wait for an event.
-        AccessibilityEvent seventhExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki_short))
-                        && event.getFromIndex() == 25
-                        && event.getToIndex() == 34
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(seventhExpected);
-
-        // Verify the selection position.
-        assertEquals(34, Selection.getSelectionStart(editText.getText()));
-        assertEquals(25, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the previous line and wait for an event.
-        AccessibilityEvent eightExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki_short))
-                        && event.getFromIndex() == 13
-                        && event.getToIndex() == 25
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(eightExpected);
-
-        // Verify the selection position.
-        assertEquals(34, Selection.getSelectionStart(editText.getText()));
-        assertEquals(13, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the previous line and wait for an event.
-        AccessibilityEvent ninethExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                               AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki_short))
-                        && event.getFromIndex() == 0
-                        && event.getToIndex() == 13
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(ninethExpected);
-
-        // Verify the selection position.
-        assertEquals(34, Selection.getSelectionStart(editText.getText()));
-        assertEquals(0, Selection.getSelectionEnd(editText.getText()));
-
-        // Make sure there is no previous.
-        assertFalse(text.performAction(
-                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments));
-
-        // Verify the selection position.
-        assertEquals(34, Selection.getSelectionStart(editText.getText()));
-        assertEquals(0, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the next line and wait for an event.
-        AccessibilityEvent tenthExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki_short))
-                        && event.getFromIndex() == 0
-                        && event.getToIndex() == 13
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(tenthExpected);
-
-        // Verify the selection position.
-        assertEquals(34, Selection.getSelectionStart(editText.getText()));
-        assertEquals(13, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the next line and wait for an event.
-        AccessibilityEvent eleventhExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki_short))
-                        && event.getFromIndex() == 13
-                        && event.getToIndex() == 25
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(eleventhExpected);
-
-        // Verify the selection position.
-        assertEquals(34, Selection.getSelectionStart(editText.getText()));
-        assertEquals(25, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the next line and wait for an event.
-        AccessibilityEvent twelvethExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki_short))
-                        && event.getFromIndex() == 25
-                        && event.getToIndex() == 34
-                        && event.getMovementGranularity() ==
-                                 AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(twelvethExpected);
-
-        // Verify the selection position.
-        assertEquals(34, Selection.getSelectionStart(editText.getText()));
-        assertEquals(34, Selection.getSelectionEnd(editText.getText()));
-    }
-
-    @MediumTest
-    public void testActionNextAndPreviousAtGranularityPageOverText() throws Exception {
-        final EditText editText = (EditText) getActivity().findViewById(R.id.edit);
-
-        getInstrumentation().runOnMainSync(new Runnable() {
-            @Override
-            public void run() {
-                editText.setVisibility(View.VISIBLE);
-                editText.setText(getString(R.string.android_wiki));
-                Selection.removeSelection(editText.getText());
-            }
-        });
-
-        final AccessibilityNodeInfo text = getInstrumentation().getUiAutomation()
-               .getRootInActiveWindow().findAccessibilityNodeInfosByText(getString(
-                       R.string.android_wiki)).get(0);
-
-        final int granularities = text.getMovementGranularities();
-        assertEquals(granularities, AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER
-                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD
-                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE
-                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH
-                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
-
-        final Bundle arguments = new Bundle();
-        arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT,
-                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
-
-        // Move to the next page and wait for an event.
-        AccessibilityEvent firstExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki))
-                        && event.getFromIndex() == 0
-                        && event.getToIndex() == 53
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(firstExpected);
-
-        // Verify the selection position.
-        assertEquals(53, Selection.getSelectionStart(editText.getText()));
-        assertEquals(53, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the next page and wait for an event.
-        AccessibilityEvent secondExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki))
-                        && event.getFromIndex() == 53
-                        && event.getToIndex() == 103
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(secondExpected);
-
-        // Verify the selection position.
-        assertEquals(103, Selection.getSelectionStart(editText.getText()));
-        assertEquals(103, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the next page and wait for an event.
-        AccessibilityEvent thirdExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki))
-                        && event.getFromIndex() == 103
-                        && event.getToIndex() == 153
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(thirdExpected);
-
-        // Verify the selection position.
-        assertEquals(153, Selection.getSelectionStart(editText.getText()));
-        assertEquals(153, Selection.getSelectionEnd(editText.getText()));
-
-        // Make sure there is no next.
-        assertFalse(text.performAction(
-                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments));
-
-        // Verify the selection position.
-        assertEquals(153, Selection.getSelectionStart(editText.getText()));
-        assertEquals(153, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the previous page and wait for an event.
-        AccessibilityEvent fourthExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki))
-                        && event.getFromIndex() == 103
-                        && event.getToIndex() == 153
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(fourthExpected);
-
-        // Verify the selection position.
-        assertEquals(103, Selection.getSelectionStart(editText.getText()));
-        assertEquals(103, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the previous page and wait for an event.
-        AccessibilityEvent fifthExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki))
-                        && event.getFromIndex() == 53
-                        && event.getToIndex() == 103
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(fifthExpected);
-
-        // Verify the selection position.
-        assertEquals(53, Selection.getSelectionStart(editText.getText()));
-        assertEquals(53, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the previous page and wait for an event.
-        AccessibilityEvent sixthExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki))
-                        && event.getFromIndex() == 0
-                        && event.getToIndex() == 53
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(sixthExpected);
-
-        // Verify the selection position.
-        assertEquals(0, Selection.getSelectionStart(editText.getText()));
-        assertEquals(0, Selection.getSelectionEnd(editText.getText()));
-
-        // Make sure there is no previous.
-        assertFalse(text.performAction(
-                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments));
-
-        // Verify the selection position.
-        assertEquals(0, Selection.getSelectionStart(editText.getText()));
-        assertEquals(0, Selection.getSelectionEnd(editText.getText()));
-    }
-
-    @MediumTest
-    public void testActionNextAndPreviousAtGranularityPageOverTextExtend() throws Exception {
-        final EditText editText = (EditText) getActivity().findViewById(R.id.edit);
-
-        getInstrumentation().runOnMainSync(new Runnable() {
-            @Override
-            public void run() {
-                editText.setVisibility(View.VISIBLE);
-                editText.setText(getString(R.string.android_wiki));
-                Selection.removeSelection(editText.getText());
-            }
-        });
-
-        final AccessibilityNodeInfo text = getInstrumentation().getUiAutomation()
-               .getRootInActiveWindow().findAccessibilityNodeInfosByText(getString(
-                       R.string.android_wiki)).get(0);
-
-        final int granularities = text.getMovementGranularities();
-        assertEquals(granularities, AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER
-                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD
-                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE
-                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH
-                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
-
-        final Bundle arguments = new Bundle();
-        arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT,
-                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
-        arguments.putBoolean(AccessibilityNodeInfo.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN, true);
-
-        // Move to the next page and wait for an event.
-        AccessibilityEvent firstExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki))
-                        && event.getFromIndex() == 0
-                        && event.getToIndex() == 53
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(firstExpected);
-
-        // Verify the selection position.
-        assertEquals(0, Selection.getSelectionStart(editText.getText()));
-        assertEquals(53, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the next page and wait for an event.
-        AccessibilityEvent secondExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki))
-                        && event.getFromIndex() == 53
-                        && event.getToIndex() == 103
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(secondExpected);
-
-        // Verify the selection position.
-        assertEquals(0, Selection.getSelectionStart(editText.getText()));
-        assertEquals(103, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the next page and wait for an event.
-        AccessibilityEvent thirdExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki))
-                        && event.getFromIndex() == 103
-                        && event.getToIndex() == 153
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(thirdExpected);
-
-        // Verify the selection position.
-        assertEquals(0, Selection.getSelectionStart(editText.getText()));
-        assertEquals(153, Selection.getSelectionEnd(editText.getText()));
-
-        // Make sure there is no next.
-        assertFalse(text.performAction(
-                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments));
-
-        // Move to the previous page and wait for an event.
-        AccessibilityEvent fourthExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                 AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki))
-                        && event.getFromIndex() == 103
-                        && event.getToIndex() == 153
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(fourthExpected);
-
-        // Verify the selection position.
-        assertEquals(0, Selection.getSelectionStart(editText.getText()));
-        assertEquals(103, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the previous page and wait for an event.
-        AccessibilityEvent fifthExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki))
-                        && event.getFromIndex() == 53
-                        && event.getToIndex() == 103
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(fifthExpected);
-
-        // Verify the selection position.
-        assertEquals(0, Selection.getSelectionStart(editText.getText()));
-        assertEquals(53, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the previous page and wait for an event.
-        AccessibilityEvent sixthExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki))
-                        && event.getFromIndex() == 0
-                        && event.getToIndex() == 53
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(sixthExpected);
-
-        // Verify the selection position.
-        assertEquals(0, Selection.getSelectionStart(editText.getText()));
-        assertEquals(0, Selection.getSelectionEnd(editText.getText()));
-
-        // Make sure there is no previous.
-        assertFalse(text.performAction(
-                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments));
-
-        // Verify the selection position.
-        assertEquals(0, Selection.getSelectionStart(editText.getText()));
-        assertEquals(0, Selection.getSelectionEnd(editText.getText()));
-
-        // Focus the view so we can change selection.
-        getInstrumentation().runOnMainSync(new Runnable() {
-            @Override
-            public void run() {
-                editText.setFocusable(true);
-                editText.requestFocus();
-            }
-        });
-
-        // Put selection at the end of the text.
-        Bundle setSelectionArgs = new Bundle();
-        setSelectionArgs.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT, 153);
-        setSelectionArgs.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT, 153);
-        assertTrue(text.performAction(
-                AccessibilityNodeInfo.ACTION_SET_SELECTION, setSelectionArgs));
-
-        // Verify the selection position.
-        assertEquals(153, Selection.getSelectionStart(editText.getText()));
-        assertEquals(153, Selection.getSelectionEnd(editText.getText()));
-
-        // Unfocus the view so we can hide the soft-keyboard.
-        getInstrumentation().runOnMainSync(new Runnable() {
-            @Override
-            public void run() {
-                editText.clearFocus();
-                editText.setFocusable(false);
-            }
-        });
-
-        // Move to the previous page and wait for an event.
-        AccessibilityEvent seventhExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                 AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki))
-                        && event.getFromIndex() == 103
-                        && event.getToIndex() == 153
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(seventhExpected);
-
-        // Verify the selection position.
-        assertEquals(153, Selection.getSelectionStart(editText.getText()));
-        assertEquals(103, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the previous page and wait for an event.
-        AccessibilityEvent eightExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki))
-                        && event.getFromIndex() == 53
-                        && event.getToIndex() == 103
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(eightExpected);
-
-        // Verify the selection position.
-        assertEquals(153, Selection.getSelectionStart(editText.getText()));
-        assertEquals(53, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the previous page and wait for an event.
-        AccessibilityEvent ninethExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki))
-                        && event.getFromIndex() == 0
-                        && event.getToIndex() == 53
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(ninethExpected);
-
-        // Verify the selection position.
-        assertEquals(153, Selection.getSelectionStart(editText.getText()));
-        assertEquals(0, Selection.getSelectionEnd(editText.getText()));
-
-        // Make sure there is no previous.
-        assertFalse(text.performAction(
-                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments));
-
-        // Verify the selection position.
-        assertEquals(153, Selection.getSelectionStart(editText.getText()));
-        assertEquals(0, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the next page and wait for an event.
-        AccessibilityEvent tenthExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki))
-                        && event.getFromIndex() == 0
-                        && event.getToIndex() == 53
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(tenthExpected);
-
-        // Verify the selection position.
-        assertEquals(153, Selection.getSelectionStart(editText.getText()));
-        assertEquals(53, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the next page and wait for an event.
-        AccessibilityEvent eleventhExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki))
-                        && event.getFromIndex() == 53
-                        && event.getToIndex() == 103
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(eleventhExpected);
-
-        // Verify the selection position.
-        assertEquals(153, Selection.getSelectionStart(editText.getText()));
-        assertEquals(103, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the next page and wait for an event.
-        AccessibilityEvent twelvethExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki))
-                        && event.getFromIndex() == 103
-                        && event.getToIndex() == 153
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(twelvethExpected);
-
-        // Verify the selection position.
-        assertEquals(153, Selection.getSelectionStart(editText.getText()));
-        assertEquals(153, Selection.getSelectionEnd(editText.getText()));
-    }
-
-    @MediumTest
-    public void testActionNextAndPreviousAtGranularityParagraphOverText() throws Exception {
-        final TextView textView = (TextView) getActivity().findViewById(R.id.edit);
-
-        getInstrumentation().runOnMainSync(new Runnable() {
-            @Override
-            public void run() {
-                textView.setVisibility(View.VISIBLE);
-                textView.setText(getString(R.string.android_wiki_paragraphs));
-            }
-        });
-
-        final AccessibilityNodeInfo text = getInstrumentation().getUiAutomation()
-               .getRootInActiveWindow().findAccessibilityNodeInfosByText(getString(
-                       R.string.android_wiki_paragraphs)).get(0);
-
-        final int granularities = text.getMovementGranularities();
-        assertEquals(granularities, AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER
-                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD
-                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE
-                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH
-                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
-
-        final Bundle arguments = new Bundle();
-        arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT,
-                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH);
-
-        // Move to the next paragraph and wait for an event.
-        AccessibilityEvent firstExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki_paragraphs))
-                        && event.getFromIndex() == 2
-                        && event.getToIndex() == 14
-                        && event.getMovementGranularity() ==
-                                 AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(firstExpected);
-
-        // Verify the selection position.
-        assertEquals(14, Selection.getSelectionStart(textView.getText()));
-        assertEquals(14, Selection.getSelectionEnd(textView.getText()));
-
-        // Move to the next paragraph and wait for an event.
-        AccessibilityEvent secondExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                 AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki_paragraphs))
-                        && event.getFromIndex() == 16
-                        && event.getToIndex() == 32
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(secondExpected);
-
-        // Verify the selection position.
-        assertEquals(32, Selection.getSelectionStart(textView.getText()));
-        assertEquals(32, Selection.getSelectionEnd(textView.getText()));
-
-        // Move to the next paragraph and wait for an event.
-        AccessibilityEvent thirdExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki_paragraphs))
-                        && event.getFromIndex() == 33
-                        && event.getToIndex() == 47
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(thirdExpected);
-
-        // Verify the selection position.
-        assertEquals(47, Selection.getSelectionStart(textView.getText()));
-        assertEquals(47, Selection.getSelectionEnd(textView.getText()));
-
-        // Make sure there is no next.
-        assertFalse(text.performAction(
-                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments));
-
-        // Verify the selection position.
-        assertEquals(47, Selection.getSelectionStart(textView.getText()));
-        assertEquals(47, Selection.getSelectionEnd(textView.getText()));
-
-        // Move to the previous paragraph and wait for an event.
-        AccessibilityEvent fourthExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki_paragraphs))
-                        && event.getFromIndex() == 33
-                        && event.getToIndex() == 47
-                        && event.getMovementGranularity() ==
-                                 AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(fourthExpected);
-
-        // Verify the selection position.
-        assertEquals(33, Selection.getSelectionStart(textView.getText()));
-        assertEquals(33, Selection.getSelectionEnd(textView.getText()));
-
-        // Move to the previous paragraph and wait for an event.
-        AccessibilityEvent fifthExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki_paragraphs))
-                        && event.getFromIndex() == 16
-                        && event.getToIndex() == 32
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(fifthExpected);
-
-        // Verify the selection position.
-        assertEquals(16, Selection.getSelectionStart(textView.getText()));
-        assertEquals(16, Selection.getSelectionEnd(textView.getText()));
-
-        // Move to the previous paragraph and wait for an event.
-        AccessibilityEvent sixthExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki_paragraphs))
-                        && event.getFromIndex() == 2
-                        && event.getToIndex() == 14
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(sixthExpected);
-
-        // Verify the selection position.
-        assertEquals(2, Selection.getSelectionStart(textView.getText()));
-        assertEquals(2, Selection.getSelectionEnd(textView.getText()));
-
-        // Make sure there is no previous.
-        assertFalse(text.performAction(
-                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments));
-
-        // Verify the selection position.
-        assertEquals(2, Selection.getSelectionStart(textView.getText()));
-        assertEquals(2, Selection.getSelectionEnd(textView.getText()));
-    }
-
-    @MediumTest
-    public void testActionNextAndPreviousAtGranularityParagraphOverTextExtend() throws Exception {
-        final EditText editText = (EditText) getActivity().findViewById(R.id.edit);
-
-        getInstrumentation().runOnMainSync(new Runnable() {
-            @Override
-            public void run() {
-                editText.setVisibility(View.VISIBLE);
-                editText.setText(getString(R.string.android_wiki_paragraphs));
-                Selection.removeSelection(editText.getText());
-            }
-        });
-
-        final AccessibilityNodeInfo text = getInstrumentation().getUiAutomation()
-               .getRootInActiveWindow().findAccessibilityNodeInfosByText(getString(
-                       R.string.android_wiki_paragraphs)).get(0);
-
-        final int granularities = text.getMovementGranularities();
-        assertEquals(granularities, AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER
-                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD
-                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE
-                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH
-                | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
-
-        final Bundle arguments = new Bundle();
-        arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT,
-                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH);
-        arguments.putBoolean(AccessibilityNodeInfo.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN, true);
-
-        // Move to the next paragraph and wait for an event.
-        AccessibilityEvent firstExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki_paragraphs))
-                        && event.getFromIndex() == 2
-                        && event.getToIndex() == 14
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(firstExpected);
-
-        // Verify the selection position.
-        assertEquals(2, Selection.getSelectionStart(editText.getText()));
-        assertEquals(14, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the next paragraph and wait for an event.
-        AccessibilityEvent secondExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki_paragraphs))
-                        && event.getFromIndex() == 16
-                        && event.getToIndex() == 32
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(secondExpected);
-
-        // Verify the selection position.
-        assertEquals(2, Selection.getSelectionStart(editText.getText()));
-        assertEquals(32, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the next paragraph and wait for an event.
-        AccessibilityEvent thirdExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki_paragraphs))
-                        && event.getFromIndex() == 33
-                        && event.getToIndex() == 47
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(thirdExpected);
-
-        // Verify the selection position.
-        assertEquals(2, Selection.getSelectionStart(editText.getText()));
-        assertEquals(47, Selection.getSelectionEnd(editText.getText()));
-
-        // Make sure there is no next.
-        assertFalse(text.performAction(
-                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments));
-
-        // Verify the selection position.
-        assertEquals(2, Selection.getSelectionStart(editText.getText()));
-        assertEquals(47, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the previous paragraph and wait for an event.
-        AccessibilityEvent fourthExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki_paragraphs))
-                        && event.getFromIndex() == 33
-                        && event.getToIndex() == 47
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(fourthExpected);
-
-        // Verify the selection position.
-        assertEquals(2, Selection.getSelectionStart(editText.getText()));
-        assertEquals(33, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the previous paragraph and wait for an event.
-        AccessibilityEvent fifthExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki_paragraphs))
-                        && event.getFromIndex() == 16
-                        && event.getToIndex() == 32
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(fifthExpected);
-
-        // Verify the selection position.
-        assertEquals(2, Selection.getSelectionStart(editText.getText()));
-        assertEquals(16, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the previous paragraph and wait for an event.
-        AccessibilityEvent sixthExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki_paragraphs))
-                        && event.getFromIndex() == 2
-                        && event.getToIndex() == 14
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(sixthExpected);
-
-        // Verify the selection position.
-        assertEquals(2, Selection.getSelectionStart(editText.getText()));
-        assertEquals(2, Selection.getSelectionEnd(editText.getText()));
-
-        // Make sure there is no previous.
-        assertFalse(text.performAction(
-                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments));
-
-        // Verify the selection position.
-        assertEquals(2, Selection.getSelectionStart(editText.getText()));
-        assertEquals(2, Selection.getSelectionEnd(editText.getText()));
-
-        // Focus the view so we can change selection.
-        getInstrumentation().runOnMainSync(new Runnable() {
-            @Override
-            public void run() {
-                editText.setFocusable(true);
-                editText.requestFocus();
-            }
-        });
-
-        // Put selection at the end of the text.
-        Bundle setSelectionArgs = new Bundle();
-        setSelectionArgs.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT, 47);
-        setSelectionArgs.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT, 47);
-        assertTrue(text.performAction(
-                AccessibilityNodeInfo.ACTION_SET_SELECTION, setSelectionArgs));
-
-        // Verify the selection position.
-        assertEquals(47, Selection.getSelectionStart(editText.getText()));
-        assertEquals(47, Selection.getSelectionEnd(editText.getText()));
-
-        // Unfocus the view so we can get rid of the soft-keyboard.
-        getInstrumentation().runOnMainSync(new Runnable() {
-            @Override
-            public void run() {
-                editText.clearFocus();
-                editText.setFocusable(false);
-            }
-        });
-
-        // Move to the previous paragraph and wait for an event.
-        AccessibilityEvent seventhExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki_paragraphs))
-                        && event.getFromIndex() == 33
-                        && event.getToIndex() == 47
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(seventhExpected);
-
-        // Verify the selection position.
-        assertEquals(47, Selection.getSelectionStart(editText.getText()));
-        assertEquals(33, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the previous paragraph and wait for an event.
-        AccessibilityEvent eightExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki_paragraphs))
-                        && event.getFromIndex() == 16
-                        && event.getToIndex() == 32
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(eightExpected);
-
-        // Verify the selection position.
-        assertEquals(47, Selection.getSelectionStart(editText.getText()));
-        assertEquals(16, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the previous paragraph and wait for an event.
-        AccessibilityEvent ninethExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki_paragraphs))
-                        && event.getFromIndex() == 2
-                        && event.getToIndex() == 14
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(ninethExpected);
-
-        // Verify the selection position.
-        assertEquals(47, Selection.getSelectionStart(editText.getText()));
-        assertEquals(2, Selection.getSelectionEnd(editText.getText()));
-
-        // Make sure there is no previous.
-        assertFalse(text.performAction(
-                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments));
-
-        // Verify the selection position.
-        assertEquals(47, Selection.getSelectionStart(editText.getText()));
-        assertEquals(2, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the next paragraph and wait for an event.
-        AccessibilityEvent tenthExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki_paragraphs))
-                        && event.getFromIndex() == 2
-                        && event.getToIndex() == 14
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(tenthExpected);
-
-        // Verify the selection position.
-        assertEquals(47, Selection.getSelectionStart(editText.getText()));
-        assertEquals(14, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the next paragraph and wait for an event.
-        AccessibilityEvent eleventhExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki_paragraphs))
-                        && event.getFromIndex() == 16
-                        && event.getToIndex() == 32
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(eleventhExpected);
-
-        // Verify the selection position.
-        assertEquals(47, Selection.getSelectionStart(editText.getText()));
-        assertEquals(32, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the next paragraph and wait for an event.
-        AccessibilityEvent twlevethExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki_paragraphs))
-                        && event.getFromIndex() == 33
-                        && event.getToIndex() == 47
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(twlevethExpected);
-
-        // Verify the selection position.
-        assertEquals(47, Selection.getSelectionStart(editText.getText()));
-        assertEquals(47, Selection.getSelectionEnd(editText.getText()));
-
-        // Make sure there is no next.
-        assertFalse(text.performAction(
-                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments));
-
-        // Verify the selection position.
-        assertEquals(47, Selection.getSelectionStart(editText.getText()));
-        assertEquals(47, Selection.getSelectionEnd(editText.getText()));
-    }
-
-    @MediumTest
-    public void testTextEditingActions() throws Exception {
-        if (!getActivity().getPackageManager().hasSystemFeature(
-                PackageManager.FEATURE_INPUT_METHODS)) {
-            return;
-        }
-
-        final EditText editText = (EditText) getActivity().findViewById(R.id.edit);
-        final String textContent = getString(R.string.foo_bar_baz);
-
-        getInstrumentation().runOnMainSync(new Runnable() {
-            @Override
-            public void run() {
-                editText.setVisibility(View.VISIBLE);
-                editText.setFocusable(true);
-                editText.requestFocus();
-                editText.setText(getString(R.string.foo_bar_baz));
-                Selection.removeSelection(editText.getText());
-            }
-        });
-
-        final AccessibilityNodeInfo text = getInstrumentation().getUiAutomation()
-               .getRootInActiveWindow().findAccessibilityNodeInfosByText(
-                       getString(R.string.foo_bar_baz)).get(0);
-
-        // Select all text.
-        Bundle arguments = new Bundle();
-        arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT, 0);
-        arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT,
-                editText.getText().length());
-        assertTrue(text.performAction(
-                AccessibilityNodeInfo.ACTION_SET_SELECTION, arguments));
-
-        // Copy the selected text.
-        text.performAction(AccessibilityNodeInfo.ACTION_COPY);
-
-        // Set selection at the end.
-        final int textLength = editText.getText().length();
-        // Verify the selection position.
-        assertEquals(textLength, Selection.getSelectionStart(editText.getText()));
-        assertEquals(textLength, Selection.getSelectionEnd(editText.getText()));
-
-        // Paste the selected text.
-        assertTrue(text.performAction(
-                AccessibilityNodeInfo.ACTION_PASTE));
-
-        // Verify the content.
-        assertEquals(editText.getText().toString(), textContent + textContent);
-
-        // Select all text.
-        arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT, 0);
-        arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT,
-                editText.getText().length());
-        assertTrue(text.performAction(
-                AccessibilityNodeInfo.ACTION_SET_SELECTION, arguments));
-
-        // Cut the selected text.
-        assertTrue(text.performAction(
-                AccessibilityNodeInfo.ACTION_CUT));
-
-        // Verify the content.
-        assertTrue(TextUtils.isEmpty(editText.getText()));
-    }
-
-    public void testSetSelectionInContentDescription() throws Exception {
-        final View view = getActivity().findViewById(R.id.view);
-
-        getInstrumentation().runOnMainSync(new Runnable() {
-            @Override
-            public void run() {
-                view.setVisibility(View.VISIBLE);
-                view.setContentDescription(getString(R.string.foo_bar_baz));
-            }
-        });
-
-        AccessibilityNodeInfo text = getInstrumentation().getUiAutomation()
-               .getRootInActiveWindow().findAccessibilityNodeInfosByText(
-                       getString(R.string.foo_bar_baz)).get(0);
-
-        // Set the cursor position.
-        Bundle arguments = new Bundle();
-        arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT, 4);
-        arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT, 4);
-        assertTrue(text.performAction(
-                AccessibilityNodeInfo.ACTION_SET_SELECTION, arguments));
-
-        // Try and fail to set the selection longer than zero.
-        arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT, 4);
-        arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT, 5);
-        assertFalse(text.performAction(
-                AccessibilityNodeInfo.ACTION_SET_SELECTION, arguments));
-    }
-
-    public void testSelectionPositionForNonEditableView() throws Exception {
-        final View view = getActivity().findViewById(R.id.view);
-
-        getInstrumentation().runOnMainSync(new Runnable() {
-            @Override
-            public void run() {
-                view.setVisibility(View.VISIBLE);
-                view.setContentDescription(getString(R.string.foo_bar_baz));
-            }
-        });
-
-        final AccessibilityNodeInfo text = getInstrumentation().getUiAutomation()
-               .getRootInActiveWindow().findAccessibilityNodeInfosByText(
-                       getString(R.string.foo_bar_baz)).get(0);
-
-        // Check the initial node properties.
-        assertFalse(text.isEditable());
-        assertSame(text.getTextSelectionStart(), -1);
-        assertSame(text.getTextSelectionEnd(), -1);
-
-        // Set the cursor position.
-        getInstrumentation().getUiAutomation().executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                Bundle arguments = new Bundle();
-                arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT, 4);
-                arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT, 4);
-                assertTrue(text.performAction(
-                        AccessibilityNodeInfo.ACTION_SET_SELECTION, arguments));
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return (event.getEventType()
-                        == AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Refresh the node.
-        AccessibilityNodeInfo refreshedText = getInstrumentation().getUiAutomation()
-                .getRootInActiveWindow().findAccessibilityNodeInfosByText(
-                        getString(R.string.foo_bar_baz)).get(0);
-
-        // Check the related node properties.
-        assertFalse(refreshedText.isEditable());
-        assertSame(refreshedText.getTextSelectionStart(), 4);
-        assertSame(refreshedText.getTextSelectionEnd(), 4);
-
-        // Try to set to an invalid cursor position.
-        Bundle arguments = new Bundle();
-        arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT, 4);
-        arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT, 5);
-        assertFalse(text.performAction(
-                AccessibilityNodeInfo.ACTION_SET_SELECTION, arguments));
-
-        // Refresh the node.
-        refreshedText = getInstrumentation().getUiAutomation()
-                .getRootInActiveWindow().findAccessibilityNodeInfosByText(
-                        getString(R.string.foo_bar_baz)).get(0);
-
-        // Check the related node properties.
-        assertFalse(refreshedText.isEditable());
-        assertSame(refreshedText.getTextSelectionStart(), 4);
-        assertSame(refreshedText.getTextSelectionEnd(), 4);
-    }
-}
diff --git a/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityViewTreeReportingActivity.java b/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityViewTreeReportingActivity.java
deleted file mode 100644
index 6aa4f44..0000000
--- a/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityViewTreeReportingActivity.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/**
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 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.accessibilityservice.cts;
-
-import android.os.Bundle;
-
-import com.android.cts.accessibilityservice.R;
-
-/**
- * Activity for testing the accessibility focus APIs exposed to
- * accessibility services. These APIs allow moving accessibility
- * focus in the view tree from an AccessiiblityService. Specifically,
- * this activity is for verifying the hierarchical movement of the
- * accessibility focus.
- */
-public class AccessibilityViewTreeReportingActivity extends AccessibilityTestActivity {
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.accessibility_view_tree_reporting_test);
-    }
-}
diff --git a/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityViewTreeReportingTest.java b/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityViewTreeReportingTest.java
deleted file mode 100644
index 9785ab4..0000000
--- a/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityViewTreeReportingTest.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/**
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 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.accessibilityservice.cts;
-
-import android.test.suitebuilder.annotation.MediumTest;
-import android.view.accessibility.AccessibilityNodeInfo;
-
-import com.android.cts.accessibilityservice.R;
-
-/**
- * Test cases for testing the accessibility focus APIs exposed to accessibility
- * services. This test checks how the view hierarchy is reported to accessibility
- * services.
- */
-public class AccessibilityViewTreeReportingTest
-        extends AccessibilityActivityTestCase<AccessibilityViewTreeReportingActivity>{
-
-    public AccessibilityViewTreeReportingTest() {
-        super(AccessibilityViewTreeReportingActivity.class);
-    }
-
-    @MediumTest
-    public void testDescendantsOfNotImportantViewReportedInOrder1() throws Exception {
-        AccessibilityNodeInfo firstFrameLayout = getInstrumentation().getUiAutomation()
-            .getRootInActiveWindow().findAccessibilityNodeInfosByText(
-                    getString(R.string.firstFrameLayout)).get(0);
-        assertNotNull(firstFrameLayout);
-        assertSame(3, firstFrameLayout.getChildCount());
-
-        // Check if the first child is the right one.
-        AccessibilityNodeInfo firstTextView = getInstrumentation().getUiAutomation()
-            .getRootInActiveWindow().findAccessibilityNodeInfosByText(getString(
-                    R.string.firstTextView)).get(0);
-        assertEquals(firstTextView, firstFrameLayout.getChild(0));
-
-        // Check if the second child is the right one.
-        AccessibilityNodeInfo firstEditText = getInstrumentation().getUiAutomation()
-            .getRootInActiveWindow().findAccessibilityNodeInfosByText(getString(
-                    R.string.firstEditText)).get(0);
-        assertEquals(firstEditText, firstFrameLayout.getChild(1));
-
-        // Check if the third child is the right one.
-        AccessibilityNodeInfo firstButton = getInstrumentation().getUiAutomation()
-            .getRootInActiveWindow().findAccessibilityNodeInfosByText(
-                    getString(R.string.firstButton)).get(0);
-        assertEquals(firstButton, firstFrameLayout.getChild(2));
-    }
-
-    @MediumTest
-    public void testDescendantsOfNotImportantViewReportedInOrder2() throws Exception {
-        AccessibilityNodeInfo secondFrameLayout = getInstrumentation().getUiAutomation()
-            .getRootInActiveWindow().findAccessibilityNodeInfosByText(
-                    getString(R.string.secondFrameLayout)).get(0);
-        assertNotNull(secondFrameLayout);
-        assertSame(3, secondFrameLayout.getChildCount());
-
-        // Check if the first child is the right one.
-        AccessibilityNodeInfo secondTextView = getInstrumentation().getUiAutomation()
-            .getRootInActiveWindow().findAccessibilityNodeInfosByText(
-                    getString(R.string.secondTextView)).get(0);
-        assertEquals(secondTextView, secondFrameLayout.getChild(0));
-
-        // Check if the second child is the right one.
-        AccessibilityNodeInfo secondEditText = getInstrumentation().getUiAutomation()
-            .getRootInActiveWindow().findAccessibilityNodeInfosByText(
-                    getString(R.string.secondEditText)).get(0);
-        assertEquals(secondEditText, secondFrameLayout.getChild(1));
-
-        // Check if the third child is the right one.
-        AccessibilityNodeInfo secondButton = getInstrumentation().getUiAutomation()
-            .getRootInActiveWindow().findAccessibilityNodeInfosByText(
-                    getString(R.string.secondButton)).get(0);
-        assertEquals(secondButton, secondFrameLayout.getChild(2));
-    }
-
-    @MediumTest
-    public void testDescendantsOfNotImportantViewReportedInOrder3() throws Exception {
-        AccessibilityNodeInfo rootLinearLayout = getInstrumentation().getUiAutomation()
-            .getRootInActiveWindow().findAccessibilityNodeInfosByText(
-                    getString(R.string.rootLinearLayout)).get(0);
-        assertNotNull(rootLinearLayout);
-        assertSame(4, rootLinearLayout.getChildCount());
-
-        // Check if the first child is the right one.
-        AccessibilityNodeInfo firstFrameLayout = getInstrumentation().getUiAutomation()
-            .getRootInActiveWindow().findAccessibilityNodeInfosByText(
-                    getString(R.string.firstFrameLayout)).get(0);
-        assertEquals(firstFrameLayout, rootLinearLayout.getChild(0));
-
-        // Check if the second child is the right one.
-        AccessibilityNodeInfo secondTextView = getInstrumentation().getUiAutomation()
-            .getRootInActiveWindow().findAccessibilityNodeInfosByText(
-                    getString(R.string.secondTextView)).get(0);
-        assertEquals(secondTextView, rootLinearLayout.getChild(1));
-
-        // Check if the third child is the right one.
-        AccessibilityNodeInfo secondEditText = getInstrumentation().getUiAutomation()
-            .getRootInActiveWindow().findAccessibilityNodeInfosByText(
-                    getString(R.string.secondEditText)).get(0);
-        assertEquals(secondEditText, rootLinearLayout.getChild(2));
-
-        // Check if the fourth child is the right one.
-        AccessibilityNodeInfo secondButton = getInstrumentation().getUiAutomation()
-            .getRootInActiveWindow().findAccessibilityNodeInfosByText(
-                    getString(R.string.secondButton)).get(0);
-        assertEquals(secondButton, rootLinearLayout.getChild(3));
-    }
-}
diff --git a/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowQueryActivity.java b/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowQueryActivity.java
deleted file mode 100644
index aa66a45..0000000
--- a/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowQueryActivity.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/**
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 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.accessibilityservice.cts;
-
-import android.os.Bundle;
-import android.view.View;
-
-import android.view.accessibility.AccessibilityNodeInfo;
-import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
-import com.android.cts.accessibilityservice.R;
-
-/**
- * Activity for testing the accessibility APIs for querying of
- * the screen content. These APIs allow exploring the screen and
- * requesting an action to be performed on a given view from an
- * AccessibilityService.
- */
-public class AccessibilityWindowQueryActivity extends AccessibilityTestActivity {
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.query_window_test);
-
-        findViewById(R.id.button5).setOnClickListener(new View.OnClickListener() {
-            public void onClick(View v) {
-                /* do nothing */
-            }
-        });
-        findViewById(R.id.button5).setOnLongClickListener(new View.OnLongClickListener() {
-            public boolean onLongClick(View v) {
-                return true;
-            }
-        });
-
-        findViewById(R.id.button5).setAccessibilityDelegate(new View.AccessibilityDelegate() {
-            @Override
-            public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
-                super.onInitializeAccessibilityNodeInfo(host, info);
-                info.addAction(new AccessibilityAction(R.id.foo_custom_action, "Foo"));
-            }
-
-            @Override
-            public boolean performAccessibilityAction(View host, int action, Bundle args) {
-                if (action == R.id.foo_custom_action) {
-                    return true;
-                }
-                return super.performAccessibilityAction(host, action, args);
-            }
-        });
-    }
-}
diff --git a/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowQueryTest.java b/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowQueryTest.java
deleted file mode 100755
index 131b8d6..0000000
--- a/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowQueryTest.java
+++ /dev/null
@@ -1,903 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.accessibilityservice.cts;
-
-import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLEAR_FOCUS;
-import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLEAR_SELECTION;
-import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLICK;
-import static android.view.accessibility.AccessibilityNodeInfo.ACTION_FOCUS;
-import static android.view.accessibility.AccessibilityNodeInfo.ACTION_LONG_CLICK;
-import static android.view.accessibility.AccessibilityNodeInfo.ACTION_SELECT;
-
-import android.accessibilityservice.AccessibilityService;
-import android.accessibilityservice.AccessibilityServiceInfo;
-import android.app.UiAutomation;
-import android.graphics.Rect;
-import android.os.SystemClock;
-import android.test.suitebuilder.annotation.MediumTest;
-import android.view.Gravity;
-import android.view.Window;
-import android.view.WindowManager;
-import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityNodeInfo;
-import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
-import android.view.accessibility.AccessibilityWindowInfo;
-
-import android.widget.Button;
-import com.android.cts.accessibilityservice.R;
-
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Queue;
-import java.util.concurrent.TimeoutException;
-
-/**
- * Test cases for testing the accessibility APIs for querying of the screen content.
- * These APIs allow exploring the screen and requesting an action to be performed
- * on a given view from an AccessibilityService.
- */
-public class AccessibilityWindowQueryTest
-        extends AccessibilityActivityTestCase<AccessibilityWindowQueryActivity> {
-
-    private static final long TIMEOUT_WINDOW_STATE_IDLE = 500;
-
-    public AccessibilityWindowQueryTest() {
-        super(AccessibilityWindowQueryActivity.class);
-    }
-
-    @MediumTest
-    public void testFindByText() throws Exception {
-        // find a view by text
-        List<AccessibilityNodeInfo> buttons = getInstrumentation().getUiAutomation()
-                .getRootInActiveWindow().findAccessibilityNodeInfosByText("b");
-        assertEquals(9, buttons.size());
-    }
-
-    @MediumTest
-    public void testFindByContentDescription() throws Exception {
-        // find a view by text
-        AccessibilityNodeInfo button = getInstrumentation().getUiAutomation()
-                .getRootInActiveWindow().findAccessibilityNodeInfosByText(
-                        getString(R.string.contentDescription)).get(0);
-        assertNotNull(button);
-    }
-
-    @MediumTest
-    public void testTraverseWindow() throws Exception {
-        verifyNodesInAppWindow(getInstrumentation().getUiAutomation().getRootInActiveWindow());
-    }
-
-    @MediumTest
-    public void testNoWindowsAccessIfFlagNotSet() throws Exception {
-        // Make sure the windows cannot be accessed.
-        UiAutomation uiAutomation = getInstrumentation().getUiAutomation();
-        assertTrue(uiAutomation.getWindows().isEmpty());
-
-        // Find a button to click on.
-        final AccessibilityNodeInfo button1 = uiAutomation.getRootInActiveWindow()
-                .findAccessibilityNodeInfosByViewId(
-                        "com.android.cts.accessibilityservice:id/button1").get(0);
-
-        // Argh...
-        final List<AccessibilityEvent> events = new ArrayList<AccessibilityEvent>();
-
-        // Click the button.
-        uiAutomation.executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                button1.performAction(AccessibilityNodeInfo.ACTION_CLICK);
-            }
-        },
-        new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_CLICKED) {
-                    events.add(event);
-                    return true;
-                }
-                return false;
-            }
-        },
-        TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure the source window cannot be accessed.
-        AccessibilityEvent event = events.get(0);
-        assertNull(event.getSource().getWindow());
-    }
-
-    @MediumTest
-    public void testTraverseAllWindows() throws Exception {
-        setAccessInteractiveWindowsFlag();
-        try {
-            UiAutomation uiAutomation = getInstrumentation().getUiAutomation();
-
-            List<AccessibilityWindowInfo> windows = uiAutomation.getWindows();
-            Rect boundsInScreen = new Rect();
-
-            final int windowCount = windows.size();
-            for (int i = 0; i < windowCount; i++) {
-                AccessibilityWindowInfo window = windows.get(i);
-
-                window.getBoundsInScreen(boundsInScreen);
-                assertFalse(boundsInScreen.isEmpty()); // Varies on screen size, emptiness check.
-                assertNull(window.getParent());
-                assertSame(0, window.getChildCount());
-                assertNull(window.getParent());
-                assertNotNull(window.getRoot());
-
-                if (window.getType() == AccessibilityWindowInfo.TYPE_APPLICATION) {
-                    assertTrue(window.isFocused());
-                    assertTrue(window.isActive());
-                    verifyNodesInAppWindow(window.getRoot());
-                } else if (window.getType() == AccessibilityWindowInfo.TYPE_SYSTEM) {
-                    assertFalse(window.isFocused());
-                    assertFalse(window.isActive());
-                }
-            }
-        } finally {
-            clearAccessInteractiveWindowsFlag();
-        }
-    }
-
-    @MediumTest
-    public void testTraverseWindowFromEvent() throws Exception {
-        setAccessInteractiveWindowsFlag();
-        try {
-            UiAutomation uiAutomation = getInstrumentation().getUiAutomation();
-
-            // Find a button to click on.
-            final AccessibilityNodeInfo button1 = uiAutomation.getRootInActiveWindow()
-                    .findAccessibilityNodeInfosByViewId(
-                            "com.android.cts.accessibilityservice:id/button1").get(0);
-
-            // Argh...
-            final List<AccessibilityEvent> events = new ArrayList<AccessibilityEvent>();
-
-            // Click the button.
-            uiAutomation.executeAndWaitForEvent(new Runnable() {
-                @Override
-                public void run() {
-                    button1.performAction(AccessibilityNodeInfo.ACTION_CLICK);
-                }
-            },
-            new UiAutomation.AccessibilityEventFilter() {
-                @Override
-                public boolean accept(AccessibilityEvent event) {
-                    if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_CLICKED) {
-                        events.add(event);
-                        return true;
-                    }
-                    return false;
-                }
-            },
-            TIMEOUT_ASYNC_PROCESSING);
-
-            // Get the source window.
-            AccessibilityEvent event = events.get(0);
-            AccessibilityWindowInfo window = event.getSource().getWindow();
-
-            // Verify the application window.
-            Rect boundsInScreen = new Rect();
-            window.getBoundsInScreen(boundsInScreen);
-            assertFalse(boundsInScreen.isEmpty()); // Varies on screen size, so just emptiness check.
-            assertSame(window.getType(), AccessibilityWindowInfo.TYPE_APPLICATION);
-            assertTrue(window.isFocused());
-            assertTrue(window.isActive());
-            assertNull(window.getParent());
-            assertSame(0, window.getChildCount());
-            assertNotNull(window.getRoot());
-
-            // Verify the window content.
-            verifyNodesInAppWindow(window.getRoot());
-        } finally {
-            clearAccessInteractiveWindowsFlag();
-        }
-    }
-
-    @MediumTest
-    public void testInteractWithAppWindow() throws Exception {
-        setAccessInteractiveWindowsFlag();
-        try {
-            UiAutomation uiAutomation = getInstrumentation().getUiAutomation();
-
-            // Find a button to click on.
-            final AccessibilityNodeInfo button1 = uiAutomation.getRootInActiveWindow()
-                    .findAccessibilityNodeInfosByViewId(
-                            "com.android.cts.accessibilityservice:id/button1").get(0);
-
-            // Argh...
-            final List<AccessibilityEvent> events = new ArrayList<AccessibilityEvent>();
-
-            // Click the button.
-            uiAutomation.executeAndWaitForEvent(new Runnable() {
-                @Override
-                public void run() {
-                    button1.performAction(AccessibilityNodeInfo.ACTION_CLICK);
-                }
-            },
-            new UiAutomation.AccessibilityEventFilter() {
-                @Override
-                public boolean accept(AccessibilityEvent event) {
-                    if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_CLICKED) {
-                        events.add(event);
-                        return true;
-                    }
-                    return false;
-                }
-            },
-            TIMEOUT_ASYNC_PROCESSING);
-
-            // Get the source window.
-            AccessibilityEvent event = events.get(0);
-            AccessibilityWindowInfo window = event.getSource().getWindow();
-
-            // Find a another button from the event's window.
-            final AccessibilityNodeInfo button2 = window.getRoot()
-                    .findAccessibilityNodeInfosByViewId(
-                            "com.android.cts.accessibilityservice:id/button2").get(0);
-
-            // Click the second button.
-            uiAutomation.executeAndWaitForEvent(new Runnable() {
-                @Override
-                public void run() {
-                    button2.performAction(AccessibilityNodeInfo.ACTION_CLICK);
-                }
-            },
-            new UiAutomation.AccessibilityEventFilter() {
-                @Override
-                public boolean accept(AccessibilityEvent event) {
-                    return event.getEventType() == AccessibilityEvent.TYPE_VIEW_CLICKED;
-                }
-            },
-            TIMEOUT_ASYNC_PROCESSING);
-        } finally {
-            clearAccessInteractiveWindowsFlag();
-        }
-    }
-
-    @MediumTest
-    public void testSingleAccessibilityFocusAcrossWindows() throws Exception {
-        setAccessInteractiveWindowsFlag();
-        try {
-            // Add two more windows.
-            addTwoAppPanelWindows();
-
-            // Put accessibility focus in the first app window.
-            ensureAppWindowFocusedOrFail(0);
-            // Make sure there only one accessibility focus.
-            assertSingleAccessibilityFocus();
-
-            // Put accessibility focus in the second app window.
-            ensureAppWindowFocusedOrFail(1);
-            // Make sure there only one accessibility focus.
-            assertSingleAccessibilityFocus();
-
-            // Put accessibility focus in the third app window.
-            ensureAppWindowFocusedOrFail(2);
-            // Make sure there only one accessibility focus.
-            assertSingleAccessibilityFocus();
-        } finally {
-            ensureAccessibilityFocusCleared();
-            clearAccessInteractiveWindowsFlag();
-        }
-    }
-
-    @MediumTest
-    public void testPerformActionFocus() throws Exception {
-        // find a view and make sure it is not focused
-        AccessibilityNodeInfo button = getInstrumentation().getUiAutomation()
-                .getRootInActiveWindow().findAccessibilityNodeInfosByText(
-                        getString(R.string.button5)).get(0);
-        assertFalse(button.isFocused());
-
-        // focus the view
-        assertTrue(button.performAction(ACTION_FOCUS));
-
-        // find the view again and make sure it is focused
-        button = getInstrumentation().getUiAutomation().getRootInActiveWindow()
-                .findAccessibilityNodeInfosByText(getString(R.string.button5)).get(0);
-        assertTrue(button.isFocused());
-    }
-
-    @MediumTest
-    public void testPerformActionClearFocus() throws Exception {
-        // find a view and make sure it is not focused
-        AccessibilityNodeInfo button = getInstrumentation().getUiAutomation()
-                .getRootInActiveWindow().findAccessibilityNodeInfosByText(
-                        getString(R.string.button5)).get(0);
-        assertFalse(button.isFocused());
-
-        // focus the view
-        assertTrue(button.performAction(ACTION_FOCUS));
-
-        // find the view again and make sure it is focused
-        button = getInstrumentation().getUiAutomation().getRootInActiveWindow()
-                .findAccessibilityNodeInfosByText(getString(R.string.button5)).get(0);
-        assertTrue(button.isFocused());
-
-        // unfocus the view
-        assertTrue(button.performAction(ACTION_CLEAR_FOCUS));
-
-        // find the view again and make sure it is not focused
-        button = getInstrumentation().getUiAutomation().getRootInActiveWindow()
-                .findAccessibilityNodeInfosByText(getString(R.string.button5)).get(0);
-        assertFalse(button.isFocused());
-    }
-
-    @MediumTest
-    public void testPerformActionSelect() throws Exception {
-        // find a view and make sure it is not selected
-        AccessibilityNodeInfo button = getInstrumentation().getUiAutomation()
-                .getRootInActiveWindow().findAccessibilityNodeInfosByText(
-                        getString(R.string.button5)).get(0);
-        assertFalse(button.isSelected());
-
-        // select the view
-        assertTrue(button.performAction(ACTION_SELECT));
-
-        // find the view again and make sure it is selected
-        button = getInstrumentation().getUiAutomation().getRootInActiveWindow()
-                .findAccessibilityNodeInfosByText(getString(R.string.button5)).get(0);
-        assertTrue(button.isSelected());
-    }
-
-    @MediumTest
-    public void testPerformActionClearSelection() throws Exception {
-        // find a view and make sure it is not selected
-        AccessibilityNodeInfo button = getInstrumentation().getUiAutomation()
-                .getRootInActiveWindow().findAccessibilityNodeInfosByText(
-                        getString(R.string.button5)).get(0);
-        assertFalse(button.isSelected());
-
-        // select the view
-        assertTrue(button.performAction(ACTION_SELECT));
-
-        // find the view again and make sure it is selected
-        button = getInstrumentation().getUiAutomation().getRootInActiveWindow()
-                .findAccessibilityNodeInfosByText(getString(R.string.button5)).get(0);
-
-        assertTrue(button.isSelected());
-
-        // unselect the view
-        assertTrue(button.performAction(ACTION_CLEAR_SELECTION));
-
-        // find the view again and make sure it is not selected
-        button = getInstrumentation().getUiAutomation().getRootInActiveWindow()
-                .findAccessibilityNodeInfosByText(getString(R.string.button5)).get(0);
-        assertFalse(button.isSelected());
-    }
-
-    @MediumTest
-    public void testPerformActionClick() throws Exception {
-        // find a view and make sure it is not selected
-        final AccessibilityNodeInfo button = getInstrumentation().getUiAutomation()
-                .getRootInActiveWindow().findAccessibilityNodeInfosByText(
-                        getString(R.string.button5)).get(0);
-        assertFalse(button.isSelected());
-
-        // Make an action and wait for an event.
-        AccessibilityEvent expected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                button.performAction(ACTION_CLICK);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return (event.getEventType() == AccessibilityEvent.TYPE_VIEW_CLICKED);
-            }
-        },
-        TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure the expected event was received.
-        assertNotNull(expected);
-    }
-
-    @MediumTest
-    public void testPerformActionLongClick() throws Exception {
-        // find a view and make sure it is not selected
-        final AccessibilityNodeInfo button = getInstrumentation().getUiAutomation()
-                .getRootInActiveWindow().findAccessibilityNodeInfosByText(
-                        getString(R.string.button5)).get(0);
-        assertFalse(button.isSelected());
-
-        // Make an action and wait for an event.
-        AccessibilityEvent expected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                button.performAction(ACTION_LONG_CLICK);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return (event.getEventType() == AccessibilityEvent.TYPE_VIEW_LONG_CLICKED);
-            }
-        },
-        TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure the expected event was received.
-        assertNotNull(expected);
-    }
-
-
-    @MediumTest
-    public void testPerformCustomAction() throws Exception {
-        // find a view and make sure it is not selected
-        AccessibilityNodeInfo button = getInstrumentation().getUiAutomation()
-                .getRootInActiveWindow().findAccessibilityNodeInfosByText(
-                        getString(R.string.button5)).get(0);
-
-        // find the custom action and perform it
-        List<AccessibilityAction> actions = button.getActionList();
-        final int actionCount = actions.size();
-        for (int i = 0; i < actionCount; i++) {
-            AccessibilityAction action = actions.get(i);
-            if (action.getId() == R.id.foo_custom_action) {
-                assertSame(action.getLabel(), "Foo");
-                // perform the action
-                assertTrue(button.performAction(action.getId()));
-                return;
-            }
-        }
-    }
-
-    @MediumTest
-    public void testGetEventSource() throws Exception {
-        // find a view and make sure it is not focused
-        final AccessibilityNodeInfo button = getInstrumentation().getUiAutomation()
-                .getRootInActiveWindow().findAccessibilityNodeInfosByText(
-                        getString(R.string.button5)).get(0);
-        assertFalse(button.isSelected());
-
-        // focus and wait for the event
-        AccessibilityEvent awaitedEvent = getInstrumentation().getUiAutomation()
-            .executeAndWaitForEvent(
-                new Runnable() {
-            @Override
-            public void run() {
-                assertTrue(button.performAction(ACTION_FOCUS));
-            }
-        },
-                new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return (event.getEventType() == AccessibilityEvent.TYPE_VIEW_FOCUSED);
-            }
-        },
-        TIMEOUT_ASYNC_PROCESSING);
-
-        assertNotNull(awaitedEvent);
-
-        // check that last event source
-        AccessibilityNodeInfo source = awaitedEvent.getSource();
-        assertNotNull(source);
-
-        // bounds
-        Rect buttonBounds = new Rect();
-        button.getBoundsInParent(buttonBounds);
-        Rect sourceBounds = new Rect();
-        source.getBoundsInParent(sourceBounds);
-
-        assertEquals(buttonBounds.left, sourceBounds.left);
-        assertEquals(buttonBounds.right, sourceBounds.right);
-        assertEquals(buttonBounds.top, sourceBounds.top);
-        assertEquals(buttonBounds.bottom, sourceBounds.bottom);
-
-        // char sequence attributes
-        assertEquals(button.getPackageName(), source.getPackageName());
-        assertEquals(button.getClassName(), source.getClassName());
-        assertEquals(button.getText().toString(), source.getText().toString());
-        assertSame(button.getContentDescription(), source.getContentDescription());
-
-        // boolean attributes
-        assertSame(button.isFocusable(), source.isFocusable());
-        assertSame(button.isClickable(), source.isClickable());
-        assertSame(button.isEnabled(), source.isEnabled());
-        assertNotSame(button.isFocused(), source.isFocused());
-        assertSame(button.isLongClickable(), source.isLongClickable());
-        assertSame(button.isPassword(), source.isPassword());
-        assertSame(button.isSelected(), source.isSelected());
-        assertSame(button.isCheckable(), source.isCheckable());
-        assertSame(button.isChecked(), source.isChecked());
-    }
-
-    @MediumTest
-    public void testPerformGlobalActionBack() throws Exception {
-        assertTrue(getInstrumentation().getUiAutomation().performGlobalAction(
-                AccessibilityService.GLOBAL_ACTION_BACK));
-
-        // Sleep a bit so the UI is settles.
-        waitForIdle();
-    }
-
-    @MediumTest
-    public void testPerformGlobalActionHome() throws Exception {
-        assertTrue(getInstrumentation().getUiAutomation().performGlobalAction(
-                AccessibilityService.GLOBAL_ACTION_HOME));
-
-        // Sleep a bit so the UI is settles.
-        waitForIdle();
-    }
-
-    @MediumTest
-    public void testPerformGlobalActionRecents() throws Exception {
-        // Check whether the action succeeded.
-        assertTrue(getInstrumentation().getUiAutomation().performGlobalAction(
-                AccessibilityService.GLOBAL_ACTION_RECENTS));
-
-        // Sleep a bit so the UI is settles.
-        waitForIdle();
-
-        // This is a necessary since the back action does not
-        // dismiss recents until they stop animating. Sigh...
-        SystemClock.sleep(5000);
-
-        // Clean up.
-        getInstrumentation().getUiAutomation().performGlobalAction(
-                AccessibilityService.GLOBAL_ACTION_BACK);
-
-        // Sleep a bit so the UI is settles.
-        waitForIdle();
-    }
-
-    @MediumTest
-    public void testPerformGlobalActionNotifications() throws Exception {
-        // Perform the action under test
-        assertTrue(getInstrumentation().getUiAutomation().performGlobalAction(
-                AccessibilityService.GLOBAL_ACTION_NOTIFICATIONS));
-
-        // Sleep a bit so the UI is settles.
-        waitForIdle();
-
-        // Clean up.
-        assertTrue(getInstrumentation().getUiAutomation().performGlobalAction(
-                AccessibilityService.GLOBAL_ACTION_BACK));
-
-        // Sleep a bit so the UI is settles.
-        waitForIdle();
-    }
-
-    @MediumTest
-    public void testPerformGlobalActionQuickSettings() throws Exception {
-        // Check whether the action succeeded.
-        assertTrue(getInstrumentation().getUiAutomation().performGlobalAction(
-                AccessibilityService.GLOBAL_ACTION_QUICK_SETTINGS));
-
-        // Sleep a bit so the UI is settles.
-        waitForIdle();
-
-        // Clean up.
-        getInstrumentation().getUiAutomation().performGlobalAction(
-                AccessibilityService.GLOBAL_ACTION_BACK);
-
-        // Sleep a bit so the UI is settles.
-        waitForIdle();
-    }
-
-    @MediumTest
-    public void testPerformGlobalActionPowerDialog() throws Exception {
-        // Check whether the action succeeded.
-        assertTrue(getInstrumentation().getUiAutomation().performGlobalAction(
-                AccessibilityService.GLOBAL_ACTION_POWER_DIALOG));
-
-        // Sleep a bit so the UI is settles.
-        waitForIdle();
-
-        // Clean up.
-        getInstrumentation().getUiAutomation().performGlobalAction(
-                AccessibilityService.GLOBAL_ACTION_BACK);
-
-        // Sleep a bit so the UI is settles.
-        waitForIdle();
-    }
-
-    @MediumTest
-    public void testObjectContract() throws Exception {
-        try {
-            AccessibilityServiceInfo info = getInstrumentation().getUiAutomation().getServiceInfo();
-            info.flags |= AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS;
-            getInstrumentation().getUiAutomation().setServiceInfo(info);
-
-            // find a view and make sure it is not focused
-            AccessibilityNodeInfo button = getInstrumentation().getUiAutomation()
-                    .getRootInActiveWindow().findAccessibilityNodeInfosByText(
-                            getString(R.string.button5)).get(0);
-            AccessibilityNodeInfo parent = button.getParent();
-            final int childCount = parent.getChildCount();
-            for (int i = 0; i < childCount; i++) {
-                AccessibilityNodeInfo child = parent.getChild(i);
-                assertNotNull(child);
-                if (child.equals(button)) {
-                    assertEquals("Equal objects must have same hasCode.", button.hashCode(),
-                            child.hashCode());
-                    return;
-                }
-            }
-            fail("Parent's children do not have the info whose parent is the parent.");
-        } finally {
-            AccessibilityServiceInfo info = getInstrumentation().getUiAutomation().getServiceInfo();
-            info.flags &= ~AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS;
-            getInstrumentation().getUiAutomation().setServiceInfo(info);
-        }
-    }
-
-    private void assertSingleAccessibilityFocus() {
-        UiAutomation uiAutomation = getInstrumentation().getUiAutomation();
-        List<AccessibilityWindowInfo> windows = uiAutomation.getWindows();
-        AccessibilityWindowInfo focused = null;
-
-        final int windowCount = windows.size();
-        for (int i = 0; i < windowCount; i++) {
-            AccessibilityWindowInfo window = windows.get(i);
-
-            if (window.isAccessibilityFocused()) {
-                if (focused == null) {
-                    focused = window;
-
-                    AccessibilityNodeInfo root = window.getRoot();
-                    assertEquals(uiAutomation.findFocus(
-                            AccessibilityNodeInfo.FOCUS_ACCESSIBILITY), root);
-                    assertEquals(root.findFocus(
-                            AccessibilityNodeInfo.FOCUS_ACCESSIBILITY), root);
-                } else {
-                    throw new AssertionError("Duplicate accessibility focus");
-                }
-            } else {
-                assertNull(window.getRoot().findFocus(
-                        AccessibilityNodeInfo.FOCUS_ACCESSIBILITY));
-            }
-        }
-    }
-
-    private void ensureAppWindowFocusedOrFail(int appWindowIndex) throws TimeoutException {
-        UiAutomation uiAutomation = getInstrumentation().getUiAutomation();
-        List<AccessibilityWindowInfo> windows = uiAutomation.getWindows();
-        AccessibilityWindowInfo focusTareget = null;
-
-        int visitedAppWindows = -1;
-        final int windowCount = windows.size();
-        for (int i = 0; i < windowCount; i++) {
-            AccessibilityWindowInfo window = windows.get(i);
-            if (window.getType() == AccessibilityWindowInfo.TYPE_APPLICATION) {
-                visitedAppWindows++;
-                if (appWindowIndex <= visitedAppWindows) {
-                    focusTareget = window;
-                    break;
-                }
-            }
-        }
-
-        if (focusTareget == null) {
-            throw new IllegalStateException("Couldn't find app window: " + appWindowIndex);
-        }
-
-        if (focusTareget.isAccessibilityFocused()) {
-            return;
-        }
-
-        final AccessibilityWindowInfo finalFocusTarget = focusTareget;
-        uiAutomation.executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                assertTrue(finalFocusTarget.getRoot().performAction(
-                        AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS));
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return event.getEventType() == AccessibilityEvent.TYPE_WINDOWS_CHANGED;
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        windows = uiAutomation.getWindows();
-        for (int i = 0; i < windowCount; i++) {
-            AccessibilityWindowInfo window = windows.get(i);
-            if (window.getId() == focusTareget.getId()) {
-                assertTrue(window.isAccessibilityFocused());
-                break;
-            }
-        }
-    }
-
-    private void addTwoAppPanelWindows() throws TimeoutException {
-        final UiAutomation uiAutomation = getInstrumentation().getUiAutomation();
-
-        uiAutomation.waitForIdle(TIMEOUT_WINDOW_STATE_IDLE, TIMEOUT_ASYNC_PROCESSING);
-
-        // Add the first window.
-        uiAutomation.executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                getInstrumentation().runOnMainSync(new Runnable() {
-                    @Override
-                    public void run() {
-                        WindowManager.LayoutParams params = new WindowManager.LayoutParams();
-                        params.gravity = Gravity.TOP;
-                        params.y = getStatusBarHeight();
-                        params.width = WindowManager.LayoutParams.MATCH_PARENT;
-                        params.height = WindowManager.LayoutParams.WRAP_CONTENT;
-                        params.flags = WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
-                                | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR
-                                | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
-                                | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
-                        params.type = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
-                        params.token = getActivity().getWindow().getDecorView().getWindowToken();
-
-                        Button button = new Button(getActivity());
-                        button.setText(R.string.button1);
-                        getActivity().getWindowManager().addView(button, params);
-                    }
-                });
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return event.getEventType() == AccessibilityEvent.TYPE_WINDOWS_CHANGED;
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Add the second window.
-        uiAutomation.executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                getInstrumentation().runOnMainSync(new Runnable() {
-                    @Override
-                    public void run() {
-                        WindowManager.LayoutParams params = new WindowManager.LayoutParams();
-                        params.gravity = Gravity.BOTTOM;
-                        params.width = WindowManager.LayoutParams.MATCH_PARENT;
-                        params.height = WindowManager.LayoutParams.WRAP_CONTENT;
-                        params.flags = WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
-                                | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR
-                                | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
-                                | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
-                        params.type = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
-                        params.token = getActivity().getWindow().getDecorView().getWindowToken();
-
-                        Button button = new Button(getActivity());
-                        button.setText(R.string.button2);
-                        getActivity().getWindowManager().addView(button, params);
-                    }
-                });
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return event.getEventType() == AccessibilityEvent.TYPE_WINDOWS_CHANGED;
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-    }
-
-    private int getStatusBarHeight() {
-        final Rect rect = new Rect();
-        Window window = getActivity().getWindow();
-        window.getDecorView().getWindowVisibleDisplayFrame(rect);
-        return rect.top;
-    }
-
-    private void setAccessInteractiveWindowsFlag () {
-        UiAutomation uiAutomation = getInstrumentation().getUiAutomation();
-        AccessibilityServiceInfo info = uiAutomation.getServiceInfo();
-        info.flags |= AccessibilityServiceInfo.FLAG_RETRIEVE_INTERACTIVE_WINDOWS;
-        uiAutomation.setServiceInfo(info);
-    }
-
-    private void clearAccessInteractiveWindowsFlag () {
-        UiAutomation uiAutomation = getInstrumentation().getUiAutomation();
-        AccessibilityServiceInfo info = uiAutomation.getServiceInfo();
-        info.flags &= ~AccessibilityServiceInfo.FLAG_RETRIEVE_INTERACTIVE_WINDOWS;
-        uiAutomation.setServiceInfo(info);
-    }
-
-    private void ensureAccessibilityFocusCleared() {
-        try {
-            final UiAutomation uiAutomation = getInstrumentation().getUiAutomation();
-            uiAutomation.executeAndWaitForEvent(new Runnable() {
-                @Override
-                public void run() {
-                    List<AccessibilityWindowInfo> windows = uiAutomation.getWindows();
-                    final int windowCount = windows.size();
-                    for (int i = 0; i < windowCount; i++) {
-                        AccessibilityWindowInfo window = windows.get(i);
-                        if (window.isAccessibilityFocused()) {
-                            window.getRoot().performAction(
-                                    AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS);
-                        }
-                    }
-                }
-            }, new UiAutomation.AccessibilityEventFilter() {
-                @Override
-                public boolean accept(AccessibilityEvent event) {
-                    return event.getEventType() ==
-                            AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED;
-                }
-            }, TIMEOUT_ASYNC_PROCESSING);
-        } catch (TimeoutException te) {
-            /* ignore */
-        }
-    }
-
-    private void verifyNodesInAppWindow(AccessibilityNodeInfo root) throws Exception {
-        try {
-            AccessibilityServiceInfo info = getInstrumentation().getUiAutomation().getServiceInfo();
-            info.flags |= AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS;
-            getInstrumentation().getUiAutomation().setServiceInfo(info);
-
-            root.refresh();
-
-            // make list of expected nodes
-            List<String> classNameAndTextList = new ArrayList<String>();
-            classNameAndTextList.add("android.widget.LinearLayout");
-            classNameAndTextList.add("android.widget.LinearLayout");
-            classNameAndTextList.add("android.widget.LinearLayout");
-            classNameAndTextList.add("android.widget.LinearLayout");
-            classNameAndTextList.add("android.widget.ButtonB1");
-            classNameAndTextList.add("android.widget.ButtonB2");
-            classNameAndTextList.add("android.widget.ButtonB3");
-            classNameAndTextList.add("android.widget.ButtonB4");
-            classNameAndTextList.add("android.widget.ButtonB5");
-            classNameAndTextList.add("android.widget.ButtonB6");
-            classNameAndTextList.add("android.widget.ButtonB7");
-            classNameAndTextList.add("android.widget.ButtonB8");
-            classNameAndTextList.add("android.widget.ButtonB9");
-
-            String contentViewIdResName = "com.android.cts.accessibilityservice:id/added_content";
-            boolean verifyContent = false;
-
-            Queue<AccessibilityNodeInfo> fringe = new LinkedList<AccessibilityNodeInfo>();
-            fringe.add(root);
-
-            // do a BFS traversal and check nodes
-            while (!fringe.isEmpty()) {
-                AccessibilityNodeInfo current = fringe.poll();
-
-                if (!verifyContent
-                        && contentViewIdResName.equals(current.getViewIdResourceName())) {
-                    verifyContent = true;
-                }
-
-                if (verifyContent) {
-                    CharSequence text = current.getText();
-                    String receivedClassNameAndText = current.getClassName().toString()
-                            + ((text != null) ? text.toString() : "");
-                    String expectedClassNameAndText = classNameAndTextList.remove(0);
-
-                    assertEquals("Did not get the expected node info",
-                            expectedClassNameAndText, receivedClassNameAndText);
-                }
-
-                final int childCount = current.getChildCount();
-                for (int i = 0; i < childCount; i++) {
-                    AccessibilityNodeInfo child = current.getChild(i);
-                    fringe.add(child);
-                }
-            }
-        } finally {
-            AccessibilityServiceInfo info = getInstrumentation().getUiAutomation().getServiceInfo();
-            info.flags &= ~AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS;
-            getInstrumentation().getUiAutomation().setServiceInfo(info);
-        }
-    }
-
-    @Override
-    protected void scrubClass(Class<?> testCaseClass) {
-        /* intentionally do not scrub */
-    }
-}
diff --git a/tests/tests/accounts/Android.mk b/tests/tests/accounts/Android.mk
index 6ed35c6..dc17e0e 100644
--- a/tests/tests/accounts/Android.mk
+++ b/tests/tests/accounts/Android.mk
@@ -21,7 +21,8 @@
 # and when built explicitly put it in the data partition
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
 
-LOCAL_STATIC_JAVA_LIBRARIES := CtsAccountTestsCommon ctstestrunner
+LOCAL_STATIC_JAVA_LIBRARIES := \
+    CtsAccountTestsCommon ctstestrunner platform-test-annotations
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
@@ -29,5 +30,10 @@
 
 LOCAL_SDK_VERSION := current
 
+LOCAL_CTS_MODULE_CONFIG := $(LOCAL_PATH)/Old$(CTS_MODULE_TEST_CONFIG)
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_CTS_PACKAGE)
 include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/tests/accounts/AndroidTest.xml b/tests/tests/accounts/AndroidTest.xml
index 3e29c9c..c15cdce 100644
--- a/tests/tests/accounts/AndroidTest.xml
+++ b/tests/tests/accounts/AndroidTest.xml
@@ -1,3 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
 <!-- Copyright (C) 2015 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
@@ -12,7 +13,14 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<configuration description="Test module config for Account apis">
-    <include name="common-config" />
-    <option name="cts-apk-installer:test-file-name" value="CtsUnaffiliatedAccountAuthenticators.apk" />
-</configuration>
+<configuration description="Config for CTS Accounts test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsUnaffiliatedAccountAuthenticators.apk" />
+        <option name="test-file-name" value="CtsAccountManagerTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.accounts.cts" />
+        <option name="runtime-hint" value="1m25s" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/tests/accounts/CtsUnaffiliatedAccountAuthenticators/Android.mk b/tests/tests/accounts/CtsUnaffiliatedAccountAuthenticators/Android.mk
index cb504da..73fb4f3 100644
--- a/tests/tests/accounts/CtsUnaffiliatedAccountAuthenticators/Android.mk
+++ b/tests/tests/accounts/CtsUnaffiliatedAccountAuthenticators/Android.mk
@@ -26,7 +26,7 @@
 LOCAL_SDK_VERSION := current
 
 LOCAL_STATIC_JAVA_LIBRARIES := \
-        ctstestrunner \
+	ctstestrunner \
 	CtsAccountTestsCommon
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
@@ -35,6 +35,9 @@
 
 LOCAL_PACKAGE_NAME := CtsUnaffiliatedAccountAuthenticators
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_SDK_VERSION := current
 
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey2
diff --git a/tests/tests/accounts/OldAndroidTest.xml b/tests/tests/accounts/OldAndroidTest.xml
new file mode 100644
index 0000000..3e29c9c
--- /dev/null
+++ b/tests/tests/accounts/OldAndroidTest.xml
@@ -0,0 +1,18 @@
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Test module config for Account apis">
+    <include name="common-config" />
+    <option name="cts-apk-installer:test-file-name" value="CtsUnaffiliatedAccountAuthenticators.apk" />
+</configuration>
diff --git a/tests/tests/accounts/src/android/accounts/cts/AccountManagerTest.java b/tests/tests/accounts/src/android/accounts/cts/AccountManagerTest.java
index 4350191..3520d9c 100644
--- a/tests/tests/accounts/src/android/accounts/cts/AccountManagerTest.java
+++ b/tests/tests/accounts/src/android/accounts/cts/AccountManagerTest.java
@@ -26,11 +26,13 @@
 import android.accounts.OperationCanceledException;
 import android.app.Activity;
 import android.content.Context;
+import android.content.Intent;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.Looper;
 import android.os.StrictMode;
+import android.platform.test.annotations.Presubmit;
 import android.test.ActivityInstrumentationTestCase2;
 
 import java.io.IOException;
@@ -89,6 +91,8 @@
     public static final Account ACCOUNT = new Account(ACCOUNT_NAME, ACCOUNT_TYPE);
     public static final Account ACCOUNT_FOR_NEW_REMOVE_ACCOUNT_API = new Account(
             MockAccountAuthenticator.ACCOUNT_NAME_FOR_NEW_REMOVE_API, ACCOUNT_TYPE);
+    public static final Account ACCOUNT_FOR_DEFAULT_IMPL = new Account(
+            MockAccountAuthenticator.ACCOUNT_NAME_FOR_DEFAULT_IMPL, ACCOUNT_TYPE);
     public static final Account ACCOUNT_SAME_TYPE = new Account(ACCOUNT_NAME_OTHER, ACCOUNT_TYPE);
 
     public static final Account CUSTOM_TOKEN_ACCOUNT =
@@ -406,6 +410,26 @@
     }
 
     /**
+     * Test creation of intent
+     */
+    public void testNewChooseAccountIntent() {
+        Intent intent = AccountManager.newChooseAccountIntent(null, null, null,
+                null, null,
+                null, null);
+        assertNotNull(intent);
+    }
+
+    /**
+     * Test creation of intent
+     */
+    public void testNewChooseAccountIntentDepracated() {
+        Intent intent = AccountManager.newChooseAccountIntent(null, null, null, false,
+                null, null,
+                null, null);
+        assertNotNull(intent);
+    }
+
+    /**
      * Test a basic addAccount()
      */
     public void testAddAccount() throws IOException, AuthenticatorException,
@@ -443,6 +467,29 @@
         testAddAccountWithCallbackAndHandler(new Handler(Looper.getMainLooper()));
     }
 
+    /**
+     * Test addAccount() with no associated account authenticator
+     */
+    public void testAddAccountWithNoAuthenticator() throws IOException,
+            AuthenticatorException, OperationCanceledException {
+
+        try {
+            AccountManagerFuture<Bundle> futureBundle = am.addAccount(
+                    "nonExistingAccountType",
+                    null,
+                    null,
+                    null,
+                    null,
+                    null,
+                    null);
+
+            futureBundle.getResult();
+            fail();
+        } catch (AuthenticatorException expectedException) {
+            return;
+        }
+    }
+
     private void testAddAccountWithCallbackAndHandler(Handler handler) throws IOException,
             AuthenticatorException, OperationCanceledException {
 
@@ -550,6 +597,31 @@
     }
 
     /**
+     * Test addAccountExplicitly(), renameAccount() and removeAccount() calling
+     * into default implementations.
+     */
+    public void testAddAccountExplicitlyAndRemoveAccountWithDefaultImpl() throws IOException,
+            AuthenticatorException, OperationCanceledException {
+
+        final int expectedAccountsCount = getAccountsCount();
+
+        addAccountExplicitly(ACCOUNT_FOR_DEFAULT_IMPL, ACCOUNT_PASSWORD, null /* userData */);
+
+        // Assert that we have one more account
+        Account[] accounts = am.getAccounts();
+        assertNotNull(accounts);
+        assertEquals(1 + expectedAccountsCount, accounts.length);
+        assertTrue(isAccountPresent(am.getAccounts(), ACCOUNT_FOR_DEFAULT_IMPL));
+        // Check removal of account
+        assertTrue(removeAccountWithIntentLaunch(am, ACCOUNT_FOR_DEFAULT_IMPL, mActivity, null /* callback */)
+                .getBoolean(AccountManager.KEY_BOOLEAN_RESULT));
+        // and verify that we go back to the initial state
+        accounts = am.getAccounts();
+        assertNotNull(accounts);
+        assertEquals(expectedAccountsCount, accounts.length);
+    }
+
+    /**
      * Test addAccountExplicitly(), renameAccount() and removeAccount().
      */
     public void testAddAccountExplicitlyAndRemoveAccountWithDeprecatedApi() throws IOException,
@@ -1369,6 +1441,7 @@
     /**
      * Test confirmCredentials()
      */
+    @Presubmit
     public void testConfirmCredentials() throws IOException, AuthenticatorException,
             OperationCanceledException {
 
diff --git a/tests/tests/accounts/src/android/accounts/cts/AccountTest.java b/tests/tests/accounts/src/android/accounts/cts/AccountTest.java
new file mode 100644
index 0000000..64a1415
--- /dev/null
+++ b/tests/tests/accounts/src/android/accounts/cts/AccountTest.java
@@ -0,0 +1,49 @@
+package android.accounts.cts;
+
+import android.accounts.Account;
+import android.os.Parcel;
+
+import junit.framework.TestCase;
+
+public class AccountTest extends TestCase {
+
+    private Account account;
+
+    @Override
+    public void setUp() throws Exception {
+        account = new Account("abc@xyz.org", "com.my.auth");
+    }
+
+    public void testAccountObjectCreationWithNullName() {
+        try {
+            new Account(null, "com.my.auth");
+            fail();
+        } catch (IllegalArgumentException expectedException) {
+        }
+    }
+
+    public void testAccountObjectCreationWithNullAccountType() {
+        try {
+            new Account("abc@xyz.org", null);
+            fail();
+        } catch (IllegalArgumentException expectedException) {
+        }
+    }
+
+    public void testDescribeContents() {
+        assertEquals(0, account.describeContents());
+    }
+
+    public void testWriteToParcel() {
+        Parcel parcel = Parcel.obtain();
+        parcel.setDataPosition(0);
+        account.writeToParcel(parcel, 0);
+        // Reset the position to initial.
+        parcel.setDataPosition(0);
+        // Create a new account object from just populated parcel,
+        // and verify it is equivalent to the original account.
+        Account newAccount = new Account(parcel);
+        assertEquals(account, newAccount);
+    }
+
+}
diff --git a/tests/tests/accounts/src/android/accounts/cts/AuthenticatorDescriptionTest.java b/tests/tests/accounts/src/android/accounts/cts/AuthenticatorDescriptionTest.java
new file mode 100644
index 0000000..adeb492
--- /dev/null
+++ b/tests/tests/accounts/src/android/accounts/cts/AuthenticatorDescriptionTest.java
@@ -0,0 +1,48 @@
+package android.accounts.cts;
+
+import android.accounts.AuthenticatorDescription;
+
+import junit.framework.TestCase;
+
+public class AuthenticatorDescriptionTest extends TestCase {
+
+    private String accountType = "com.my.auth";
+    private String packageName = "com.android.my.app";
+    private AuthenticatorDescription desc;
+
+    @Override
+    public void setUp() throws Exception {
+        desc = new AuthenticatorDescription(accountType, packageName, 1, 1, 1, 1, true);
+    }
+
+    public void testObjectCreationWithNullAccountType() {
+        try {
+            new AuthenticatorDescription(null, packageName, 1, 1, 1, 1);
+            fail();
+        } catch (IllegalArgumentException expectedException) {
+        }
+    }
+
+    public void testAccountObjectCreationWithNullPackageName() {
+        try {
+            new AuthenticatorDescription(accountType, null, 1, 1, 1, 1);
+            fail();
+        } catch (IllegalArgumentException expectedException) {
+        }
+    }
+
+    public void testObjectCreation() {
+        new AuthenticatorDescription(accountType, packageName, -1, 0, -1, 1);
+        new AuthenticatorDescription(accountType, packageName, -1, 0, -1, 1, true);
+        // no error signifies success.
+    }
+
+    public void testDescribeContents() {
+        assertEquals(0, desc.describeContents());
+    }
+
+    public void testNewKey() {
+        AuthenticatorDescription desc = AuthenticatorDescription.newKey(accountType);
+        assertEquals(desc.type, accountType);
+    }
+}
diff --git a/tests/tests/accounts/src/android/accounts/cts/ExceptionTest.java b/tests/tests/accounts/src/android/accounts/cts/ExceptionTest.java
new file mode 100644
index 0000000..20c6bf6
--- /dev/null
+++ b/tests/tests/accounts/src/android/accounts/cts/ExceptionTest.java
@@ -0,0 +1,78 @@
+package android.accounts.cts;
+
+import android.accounts.AccountsException;
+import android.accounts.AuthenticatorException;
+import android.accounts.NetworkErrorException;
+import android.accounts.OperationCanceledException;
+
+import junit.framework.TestCase;
+
+public class ExceptionTest extends TestCase {
+
+    private String message = "Message";
+    private Throwable cause = new Throwable("Throwable casue");
+
+    public void testAccountsException() {
+        new AccountsException();
+    }
+
+    public void testAccountsExceptionWithMessage() {
+        new AccountsException(message);
+    }
+
+    public void testAccountsExceptionWithThrowableCause() {
+        new AccountsException(cause);
+    }
+
+    public void testAccountsExceptionWithMessageAndThrowableCause() {
+        new AccountsException(message, cause);
+    }
+
+    public void testNetworkErrorException() {
+        new NetworkErrorException();
+    }
+
+    public void testNetworkErrorExceptionWithMessage() {
+        new NetworkErrorException(message);
+    }
+
+    public void testNetworkErrorExceptionWithThrowableCause() {
+        new NetworkErrorException(cause);
+    }
+
+    public void testNetworkErrorExceptionWithMessageAndThrowableCause() {
+        new NetworkErrorException(message, cause);
+    }
+
+    public void testAuthenticatorException() {
+        new AuthenticatorException();
+    }
+
+    public void testAuthenticatorExceptionWithMessage() {
+        new AuthenticatorException(message);
+    }
+
+    public void testAuthenticatorExceptionWithThrowableCause() {
+        new AuthenticatorException(cause);
+    }
+
+    public void testAuthenticatorExceptionWithMessageAndThrowableCause() {
+        new AuthenticatorException(message, cause);
+    }
+
+    public void testOperationCanceledException() {
+        new OperationCanceledException();
+    }
+
+    public void testOperationCanceledExceptionWithMessage() {
+        new OperationCanceledException(message);
+    }
+
+    public void testOperationCanceledExceptionWithThrowableCause() {
+        new OperationCanceledException(cause);
+    }
+
+    public void testOperationCanceledExceptionWithMessageAndThrowableCause() {
+        new OperationCanceledException(message, cause);
+    }
+}
diff --git a/tests/tests/accounts/src/android/accounts/cts/MockAccountAuthenticator.java b/tests/tests/accounts/src/android/accounts/cts/MockAccountAuthenticator.java
index c1b08de..470b629 100644
--- a/tests/tests/accounts/src/android/accounts/cts/MockAccountAuthenticator.java
+++ b/tests/tests/accounts/src/android/accounts/cts/MockAccountAuthenticator.java
@@ -39,6 +39,7 @@
     public static String KEY_ACCOUNT_INFO = "key_account_info";
     public static String KEY_ACCOUNT_AUTHENTICATOR_RESPONSE = "key_account_authenticator_response";
     public static String ACCOUNT_NAME_FOR_NEW_REMOVE_API = "call new removeAccount api";
+    public static String ACCOUNT_NAME_FOR_DEFAULT_IMPL = "call super api";
     // Key for triggering return intent flow
     public static String KEY_RETURN_INTENT = "return an intent";
     public static String ACCOUNT_NAME_FOR_NEW_REMOVE_API1 = "call new removeAccount api";
@@ -290,9 +291,25 @@
             // requests
             // coming from old removeAccount API.
             result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, false);
+        } else if (ACCOUNT_NAME_FOR_DEFAULT_IMPL.equals(account.name)) {
+            return super.getAccountRemovalAllowed(response, account);
         } else {
             result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, true);
         }
         return result;
     }
+
+    @Override
+    public Bundle addAccountFromCredentials(final AccountAuthenticatorResponse response,
+            Account account,
+            Bundle accountCredentials) throws NetworkErrorException {
+        return super.addAccountFromCredentials(response, account, accountCredentials);
+    }
+
+    @Override
+    public Bundle getAccountCredentialsForCloning(final AccountAuthenticatorResponse response,
+            final Account account) throws NetworkErrorException {
+        return super.getAccountCredentialsForCloning(response, account);
+    }
+
 }
diff --git a/tests/tests/admin/Android.mk b/tests/tests/admin/Android.mk
deleted file mode 100644
index 7a5ae34..0000000
--- a/tests/tests/admin/Android.mk
+++ /dev/null
@@ -1,33 +0,0 @@
-# Copyright (C) 2011 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-
-LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner mockito-target
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_PACKAGE_NAME := CtsAdminTestCases
-
-LOCAL_INSTRUMENTATION_FOR := CtsDeviceAdmin
-
-LOCAL_SDK_VERSION := current
-
-include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/admin/AndroidManifest.xml b/tests/tests/admin/AndroidManifest.xml
deleted file mode 100644
index bbd7918..0000000
--- a/tests/tests/admin/AndroidManifest.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-        package="com.android.cts.admin">
-
-  <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
-  <application>
-
-      <uses-library android:name="android.test.runner"/>
-
-  </application>
-
-  <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                   android:targetPackage="android.deviceadmin.cts"
-                   android:label="Tests for the admin APIs.">
-        <meta-data android:name="listener"
-            android:value="com.android.cts.runner.CtsTestRunListener" />
-    </instrumentation>
-
-</manifest>
diff --git a/tests/tests/admin/AndroidTest.xml b/tests/tests/admin/AndroidTest.xml
deleted file mode 100644
index c29d404..0000000
--- a/tests/tests/admin/AndroidTest.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<configuration description="CTS device admin test config">
-    <include name="common-config" />
-    <option name="run-command:run-command" value="dpm set-active-admin android.deviceadmin.cts/.CtsDeviceAdminReceiver" />
-    <option name="run-command:run-command" value="dpm set-active-admin android.deviceadmin.cts/.CtsDeviceAdminReceiver2" />
-</configuration>
diff --git a/tests/tests/admin/src/android/admin/cts/DeviceAdminActivationTest.java b/tests/tests/admin/src/android/admin/cts/DeviceAdminActivationTest.java
deleted file mode 100644
index 6fcd0de..0000000
--- a/tests/tests/admin/src/android/admin/cts/DeviceAdminActivationTest.java
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.admin.cts;
-
-import android.app.Activity;
-import android.app.admin.DevicePolicyManager;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.deviceadmin.cts.CtsDeviceAdminBrokenReceiver;
-import android.deviceadmin.cts.CtsDeviceAdminBrokenReceiver2;
-import android.deviceadmin.cts.CtsDeviceAdminBrokenReceiver3;
-import android.deviceadmin.cts.CtsDeviceAdminBrokenReceiver4;
-import android.deviceadmin.cts.CtsDeviceAdminBrokenReceiver5;
-import android.deviceadmin.cts.CtsDeviceAdminDeactivatedReceiver;
-import android.deviceadmin.cts.CtsDeviceAdminActivationTestActivity;
-import android.deviceadmin.cts.CtsDeviceAdminActivationTestActivity.OnActivityResultListener;
-import android.os.SystemClock;
-import android.test.ActivityInstrumentationTestCase2;
-import android.util.Log;
-
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-
-/**
- * Tests for the standard way of activating a Device Admin: by starting system UI via an
- * {@link Intent} with {@link DevicePolicyManager#ACTION_ADD_DEVICE_ADMIN}. The test requires that
- * the {@code CtsDeviceAdmin.apk} be installed.
- */
-public class DeviceAdminActivationTest
-    extends ActivityInstrumentationTestCase2<CtsDeviceAdminActivationTestActivity> {
-
-    private static final String TAG = DeviceAdminActivationTest.class.getSimpleName();
-
-    // IMPLEMENTATION NOTE: Because Device Admin activation requires the use of
-    // Activity.startActivityForResult, this test creates an empty Activity which then invokes
-    // startActivityForResult.
-
-    private static final int REQUEST_CODE_ACTIVATE_ADMIN = 1;
-
-    /**
-     * Maximum duration of time (milliseconds) after which the effects of programmatic actions in
-     * this test should have affected the UI.
-     */
-    private static final int UI_EFFECT_TIMEOUT_MILLIS = 5000;
-
-    private boolean mDeviceAdmin;
-    @Mock private OnActivityResultListener mMockOnActivityResultListener;
-
-    public DeviceAdminActivationTest() {
-        super(CtsDeviceAdminActivationTestActivity.class);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        MockitoAnnotations.initMocks(this);
-        getActivity().setOnActivityResultListener(mMockOnActivityResultListener);
-        mDeviceAdmin = getInstrumentation().getContext().getPackageManager().hasSystemFeature(
-                PackageManager.FEATURE_DEVICE_ADMIN);
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        try {
-            finishActivateDeviceAdminActivity();
-        } finally {
-            super.tearDown();
-        }
-    }
-
-    public void testActivateGoodReceiverDisplaysActivationUi() throws Exception {
-        if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testActivateGoodReceiverDisplaysActivationUi");
-            return;
-        }
-        assertDeviceAdminDeactivated(CtsDeviceAdminDeactivatedReceiver.class);
-        startAddDeviceAdminActivityForResult(CtsDeviceAdminDeactivatedReceiver.class);
-        assertWithTimeoutOnActivityResultNotInvoked();
-        // The UI is up and running. Assert that dismissing the UI returns the corresponding result
-        // to the test activity.
-        finishActivateDeviceAdminActivity();
-        assertWithTimeoutOnActivityResultInvokedWithResultCode(Activity.RESULT_CANCELED);
-        assertDeviceAdminDeactivated(CtsDeviceAdminDeactivatedReceiver.class);
-    }
-
-    public void testActivateBrokenReceiverFails() throws Exception {
-        if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testActivateBrokenReceiverFails");
-            return;
-        }
-        assertDeviceAdminDeactivated(CtsDeviceAdminBrokenReceiver.class);
-        startAddDeviceAdminActivityForResult(CtsDeviceAdminBrokenReceiver.class);
-        assertWithTimeoutOnActivityResultInvokedWithResultCode(Activity.RESULT_CANCELED);
-        assertDeviceAdminDeactivated(CtsDeviceAdminBrokenReceiver.class);
-    }
-
-    public void testActivateBrokenReceiver2Fails() throws Exception {
-        if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testActivateBrokenReceiver2Fails");
-            return;
-        }
-        assertDeviceAdminDeactivated(CtsDeviceAdminBrokenReceiver2.class);
-        startAddDeviceAdminActivityForResult(CtsDeviceAdminBrokenReceiver2.class);
-        assertWithTimeoutOnActivityResultInvokedWithResultCode(Activity.RESULT_CANCELED);
-        assertDeviceAdminDeactivated(CtsDeviceAdminBrokenReceiver2.class);
-    }
-
-    public void testActivateBrokenReceiver3Fails() throws Exception {
-        if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testActivateBrokenReceiver3Fails");
-            return;
-        }
-        assertDeviceAdminDeactivated(CtsDeviceAdminBrokenReceiver3.class);
-        startAddDeviceAdminActivityForResult(CtsDeviceAdminBrokenReceiver3.class);
-        assertWithTimeoutOnActivityResultInvokedWithResultCode(Activity.RESULT_CANCELED);
-        assertDeviceAdminDeactivated(CtsDeviceAdminBrokenReceiver3.class);
-    }
-
-    public void testActivateBrokenReceiver4Fails() throws Exception {
-        if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testActivateBrokenReceiver4Fails");
-            return;
-        }
-        assertDeviceAdminDeactivated(CtsDeviceAdminBrokenReceiver4.class);
-        startAddDeviceAdminActivityForResult(CtsDeviceAdminBrokenReceiver4.class);
-        assertWithTimeoutOnActivityResultInvokedWithResultCode(Activity.RESULT_CANCELED);
-        assertDeviceAdminDeactivated(CtsDeviceAdminBrokenReceiver4.class);
-    }
-
-    public void testActivateBrokenReceiver5Fails() throws Exception {
-        if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testActivateBrokenReceiver5Fails");
-            return;
-        }
-        assertDeviceAdminDeactivated(CtsDeviceAdminBrokenReceiver5.class);
-        startAddDeviceAdminActivityForResult(CtsDeviceAdminBrokenReceiver5.class);
-        assertWithTimeoutOnActivityResultInvokedWithResultCode(Activity.RESULT_CANCELED);
-        assertDeviceAdminDeactivated(CtsDeviceAdminBrokenReceiver5.class);
-    }
-
-    private void startAddDeviceAdminActivityForResult(Class<?> receiverClass) {
-        getActivity().startActivityForResult(
-                getAddDeviceAdminIntent(receiverClass),
-                REQUEST_CODE_ACTIVATE_ADMIN);
-    }
-
-    private Intent getAddDeviceAdminIntent(Class<?> receiverClass) {
-        return new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN)
-            .putExtra(
-                    DevicePolicyManager.EXTRA_DEVICE_ADMIN,
-                    new ComponentName(
-                            getInstrumentation().getTargetContext(),
-                            receiverClass));
-    }
-
-    private void assertWithTimeoutOnActivityResultNotInvoked() {
-        SystemClock.sleep(UI_EFFECT_TIMEOUT_MILLIS);
-        Mockito.verify(mMockOnActivityResultListener, Mockito.never())
-                .onActivityResult(
-                        Mockito.eq(REQUEST_CODE_ACTIVATE_ADMIN),
-                        Mockito.anyInt(),
-                        Mockito.any(Intent.class));
-    }
-
-    private void assertWithTimeoutOnActivityResultInvokedWithResultCode(int expectedResultCode) {
-        ArgumentCaptor<Integer> resultCodeCaptor = ArgumentCaptor.forClass(int.class);
-        Mockito.verify(mMockOnActivityResultListener, Mockito.timeout(UI_EFFECT_TIMEOUT_MILLIS))
-                .onActivityResult(
-                        Mockito.eq(REQUEST_CODE_ACTIVATE_ADMIN),
-                        resultCodeCaptor.capture(),
-                        Mockito.any(Intent.class));
-        assertEquals(expectedResultCode, (int) resultCodeCaptor.getValue());
-    }
-
-    private void finishActivateDeviceAdminActivity() {
-        getActivity().finishActivity(REQUEST_CODE_ACTIVATE_ADMIN);
-    }
-
-    private void assertDeviceAdminDeactivated(Class<?> receiverClass) {
-        DevicePolicyManager devicePolicyManager =
-                (DevicePolicyManager) getActivity().getSystemService(
-                        Context.DEVICE_POLICY_SERVICE);
-        assertFalse(devicePolicyManager.isAdminActive(
-                new ComponentName(getInstrumentation().getTargetContext(), receiverClass)));
-    }
-}
diff --git a/tests/tests/admin/src/android/admin/cts/DeviceAdminInfoTest.java b/tests/tests/admin/src/android/admin/cts/DeviceAdminInfoTest.java
deleted file mode 100644
index fe68073..0000000
--- a/tests/tests/admin/src/android/admin/cts/DeviceAdminInfoTest.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.admin.cts;
-
-import android.app.admin.DeviceAdminInfo;
-import android.content.ComponentName;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.test.AndroidTestCase;
-import android.util.Log;
-
-public class DeviceAdminInfoTest extends AndroidTestCase {
-
-    private static final String TAG = DeviceAdminInfoTest.class.getSimpleName();
-
-    private PackageManager mPackageManager;
-    private ComponentName mComponent;
-    private ComponentName mSecondComponent;
-    private boolean mDeviceAdmin;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mPackageManager = mContext.getPackageManager();
-        mComponent = getReceiverComponent();
-        mSecondComponent = getSecondReceiverComponent();
-        mDeviceAdmin =
-                mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN);
-    }
-
-    static ComponentName getReceiverComponent() {
-        return new ComponentName("android.deviceadmin.cts",
-                "android.deviceadmin.cts.CtsDeviceAdminReceiver");
-    }
-
-    static ComponentName getSecondReceiverComponent() {
-        return new ComponentName("android.deviceadmin.cts",
-                "android.deviceadmin.cts.CtsDeviceAdminReceiver2");
-    }
-
-    public void testDeviceAdminInfo() throws Exception {
-        if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testDeviceAdminInfo");
-            return;
-        }
-        ResolveInfo resolveInfo = new ResolveInfo();
-        resolveInfo.activityInfo = mPackageManager.getReceiverInfo(mComponent,
-                PackageManager.GET_META_DATA);
-
-        DeviceAdminInfo info = new DeviceAdminInfo(mContext, resolveInfo);
-        assertEquals(mComponent, info.getComponent());
-        assertEquals(mComponent.getPackageName(), info.getPackageName());
-        assertEquals(mComponent.getClassName(), info.getReceiverName());
-
-        assertTrue(info.usesPolicy(DeviceAdminInfo.USES_POLICY_FORCE_LOCK));
-        assertTrue(info.usesPolicy(DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD));
-        assertTrue(info.usesPolicy(DeviceAdminInfo.USES_POLICY_RESET_PASSWORD));
-        assertTrue(info.usesPolicy(DeviceAdminInfo.USES_POLICY_WATCH_LOGIN));
-        assertTrue(info.usesPolicy(DeviceAdminInfo.USES_POLICY_WIPE_DATA));
-
-        assertEquals("force-lock",
-                info.getTagForPolicy(DeviceAdminInfo.USES_POLICY_FORCE_LOCK));
-        assertEquals("limit-password",
-                info.getTagForPolicy(DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD));
-        assertEquals("reset-password",
-                info.getTagForPolicy(DeviceAdminInfo.USES_POLICY_RESET_PASSWORD));
-        assertEquals("watch-login",
-                info.getTagForPolicy(DeviceAdminInfo.USES_POLICY_WATCH_LOGIN));
-        assertEquals("wipe-data",
-                info.getTagForPolicy(DeviceAdminInfo.USES_POLICY_WIPE_DATA));
-    }
-
-    public void testDeviceAdminInfo2() throws Exception {
-        if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testDeviceAdminInfo2");
-            return;
-        }
-        ResolveInfo resolveInfo = new ResolveInfo();
-        resolveInfo.activityInfo = mPackageManager.getReceiverInfo(mSecondComponent,
-                PackageManager.GET_META_DATA);
-
-        DeviceAdminInfo info = new DeviceAdminInfo(mContext, resolveInfo);
-        assertEquals(mSecondComponent, info.getComponent());
-        assertEquals(mSecondComponent.getPackageName(), info.getPackageName());
-        assertEquals(mSecondComponent.getClassName(), info.getReceiverName());
-
-        assertFalse(info.usesPolicy(DeviceAdminInfo.USES_POLICY_FORCE_LOCK));
-        assertTrue(info.usesPolicy(DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD));
-        assertTrue(info.usesPolicy(DeviceAdminInfo.USES_POLICY_RESET_PASSWORD));
-        assertFalse(info.usesPolicy(DeviceAdminInfo.USES_POLICY_WATCH_LOGIN));
-        assertTrue(info.usesPolicy(DeviceAdminInfo.USES_POLICY_WIPE_DATA));
-
-        assertEquals("force-lock",
-                info.getTagForPolicy(DeviceAdminInfo.USES_POLICY_FORCE_LOCK));
-        assertEquals("limit-password",
-                info.getTagForPolicy(DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD));
-        assertEquals("reset-password",
-                info.getTagForPolicy(DeviceAdminInfo.USES_POLICY_RESET_PASSWORD));
-        assertEquals("watch-login",
-                info.getTagForPolicy(DeviceAdminInfo.USES_POLICY_WATCH_LOGIN));
-        assertEquals("wipe-data",
-                info.getTagForPolicy(DeviceAdminInfo.USES_POLICY_WIPE_DATA));
-    }
-}
diff --git a/tests/tests/admin/src/android/admin/cts/DeviceAdminReceiverTest.java b/tests/tests/admin/src/android/admin/cts/DeviceAdminReceiverTest.java
deleted file mode 100644
index b804625..0000000
--- a/tests/tests/admin/src/android/admin/cts/DeviceAdminReceiverTest.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.admin.cts;
-
-import android.app.admin.DeviceAdminReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.test.AndroidTestCase;
-import android.util.Log;
-
-public class DeviceAdminReceiverTest extends AndroidTestCase {
-
-    private static final String TAG = DeviceAdminReceiverTest.class.getSimpleName();
-    private static final String DISABLE_WARNING = "Disable Warning";
-
-    private static final int PASSWORD_CHANGED = 0x1;
-    private static final int PASSWORD_FAILED = 0x2;
-    private static final int PASSWORD_SUCCEEDED = 0x4;
-    private static final int DEVICE_ADMIN_ENABLED = 0x8;
-    private static final int DEVICE_ADMIN_DISABLE_REQUESTED = 0x10;
-    private static final int DEVICE_ADMIN_DISABLED = 0x20;
-
-    private TestReceiver mReceiver;
-    private boolean mDeviceAdmin;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mReceiver = new TestReceiver();
-        mDeviceAdmin =
-                mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN);
-    }
-
-    public void testOnReceive() {
-        if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testOnReceive");
-            return;
-        }
-        mReceiver.reset();
-        mReceiver.onReceive(mContext, new Intent(DeviceAdminReceiver.ACTION_PASSWORD_CHANGED));
-        assertTrue(mReceiver.hasFlags(PASSWORD_CHANGED));
-
-        mReceiver.reset();
-        mReceiver.onReceive(mContext, new Intent(DeviceAdminReceiver.ACTION_PASSWORD_FAILED));
-        assertTrue(mReceiver.hasFlags(PASSWORD_FAILED));
-
-        mReceiver.reset();
-        mReceiver.onReceive(mContext, new Intent(DeviceAdminReceiver.ACTION_PASSWORD_SUCCEEDED));
-        assertTrue(mReceiver.hasFlags(PASSWORD_SUCCEEDED));
-
-        mReceiver.reset();
-        mReceiver.onReceive(mContext, new Intent(DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED));
-        assertTrue(mReceiver.hasFlags(DEVICE_ADMIN_ENABLED));
-
-        mReceiver.reset();
-        mReceiver.onReceive(mContext, new Intent(DeviceAdminReceiver.ACTION_DEVICE_ADMIN_DISABLED));
-        assertTrue(mReceiver.hasFlags(DEVICE_ADMIN_DISABLED));
-    }
-
-    private class TestReceiver extends DeviceAdminReceiver {
-
-        private int mFlags = 0;
-
-        void reset() {
-            mFlags = 0;
-        }
-
-        boolean hasFlags(int flags) {
-            return mFlags == flags;
-        }
-
-        @Override
-        public void onPasswordChanged(Context context, Intent intent) {
-            super.onPasswordChanged(context, intent);
-            mFlags |= PASSWORD_CHANGED;
-        }
-
-        @Override
-        public void onPasswordFailed(Context context, Intent intent) {
-            super.onPasswordFailed(context, intent);
-            mFlags |= PASSWORD_FAILED;
-        }
-
-        @Override
-        public void onPasswordSucceeded(Context context, Intent intent) {
-            super.onPasswordSucceeded(context, intent);
-            mFlags |= PASSWORD_SUCCEEDED;
-        }
-
-        @Override
-        public void onEnabled(Context context, Intent intent) {
-            super.onEnabled(context, intent);
-            mFlags |= DEVICE_ADMIN_ENABLED;
-        }
-
-        @Override
-        public CharSequence onDisableRequested(Context context, Intent intent) {
-            mFlags |= DEVICE_ADMIN_DISABLE_REQUESTED;
-            return DISABLE_WARNING;
-        }
-
-        @Override
-        public void onDisabled(Context context, Intent intent) {
-            super.onDisabled(context, intent);
-            mFlags |= DEVICE_ADMIN_DISABLED;
-        }
-    }
-}
diff --git a/tests/tests/admin/src/android/admin/cts/DevicePolicyManagerTest.java b/tests/tests/admin/src/android/admin/cts/DevicePolicyManagerTest.java
deleted file mode 100644
index 66e12c0..0000000
--- a/tests/tests/admin/src/android/admin/cts/DevicePolicyManagerTest.java
+++ /dev/null
@@ -1,1139 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.admin.cts;
-
-import android.app.admin.DevicePolicyManager;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.pm.ResolveInfo;
-import android.os.Build;
-import android.os.UserManager;
-import android.provider.Settings;
-import android.test.AndroidTestCase;
-import android.util.Log;
-
-import java.util.List;
-
-import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_COMPLEX;
-
-/**
- * Test that exercises {@link DevicePolicyManager}. The test requires that the
- * CtsDeviceAdminReceiver be installed via the CtsDeviceAdmin.apk and be
- * activated via "Settings > Location & security > Select device administrators".
- */
-public class DevicePolicyManagerTest extends AndroidTestCase {
-
-    private static final String TAG = DevicePolicyManagerTest.class.getSimpleName();
-
-    private DevicePolicyManager mDevicePolicyManager;
-    private ComponentName mComponent;
-    private ComponentName mSecondComponent;
-    private boolean mDeviceAdmin;
-    private boolean mManagedProfiles;
-    private PackageManager mPackageManager;
-
-    private static final String TEST_CA_STRING1 =
-            "-----BEGIN CERTIFICATE-----\n" +
-            "MIICVzCCAgGgAwIBAgIJAMvnLHnnfO/IMA0GCSqGSIb3DQEBBQUAMIGGMQswCQYD\n" +
-            "VQQGEwJJTjELMAkGA1UECAwCQVAxDDAKBgNVBAcMA0hZRDEVMBMGA1UECgwMSU1G\n" +
-            "TCBQVlQgTFREMRAwDgYDVQQLDAdJTUZMIE9VMRIwEAYDVQQDDAlJTUZMLklORk8x\n" +
-            "HzAdBgkqhkiG9w0BCQEWEHJhbWVzaEBpbWZsLmluZm8wHhcNMTMwODI4MDk0NDA5\n" +
-            "WhcNMjMwODI2MDk0NDA5WjCBhjELMAkGA1UEBhMCSU4xCzAJBgNVBAgMAkFQMQww\n" +
-            "CgYDVQQHDANIWUQxFTATBgNVBAoMDElNRkwgUFZUIExURDEQMA4GA1UECwwHSU1G\n" +
-            "TCBPVTESMBAGA1UEAwwJSU1GTC5JTkZPMR8wHQYJKoZIhvcNAQkBFhByYW1lc2hA\n" +
-            "aW1mbC5pbmZvMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJ738cbTQlNIO7O6nV/f\n" +
-            "DJTMvWbPkyHYX8CQ7yXiAzEiZ5bzKJjDJmpRAkUrVinljKns2l6C4++l/5A7pFOO\n" +
-            "33kCAwEAAaNQME4wHQYDVR0OBBYEFOdbZP7LaMbgeZYPuds2CeSonmYxMB8GA1Ud\n" +
-            "IwQYMBaAFOdbZP7LaMbgeZYPuds2CeSonmYxMAwGA1UdEwQFMAMBAf8wDQYJKoZI\n" +
-            "hvcNAQEFBQADQQBdrk6J9koyylMtl/zRfiMAc2zgeC825fgP6421NTxs1rjLs1HG\n" +
-            "VcUyQ1/e7WQgOaBHi9TefUJi+4PSVSluOXon\n" +
-            "-----END CERTIFICATE-----";
-
-    private static final String MANAGED_PROVISIONING_PKG = "com.android.managedprovisioning";
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mDevicePolicyManager = (DevicePolicyManager)
-                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
-        mComponent = DeviceAdminInfoTest.getReceiverComponent();
-        mPackageManager = mContext.getPackageManager();
-        mSecondComponent = DeviceAdminInfoTest.getSecondReceiverComponent();
-        mDeviceAdmin = mPackageManager.hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN);
-        mManagedProfiles = mDeviceAdmin
-                && mPackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS);
-        setBlankPassword();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-        setBlankPassword();
-    }
-
-    private void setBlankPassword() {
-        if (!mDeviceAdmin) {
-            return;
-        }
-        // Reset the password to nothing for future tests...
-        mDevicePolicyManager.setPasswordQuality(mComponent,
-                DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED);
-        mDevicePolicyManager.setPasswordMinimumLength(mComponent, 0);
-        assertTrue(mDevicePolicyManager.resetPassword("", 0));
-    }
-
-    public void testGetActiveAdmins() {
-        if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testGetActiveAdmins");
-            return;
-        }
-        List<ComponentName> activeAdmins = mDevicePolicyManager.getActiveAdmins();
-        assertFalse(activeAdmins.isEmpty());
-        assertTrue(activeAdmins.contains(mComponent));
-        assertTrue(mDevicePolicyManager.isAdminActive(mComponent));
-    }
-
-    public void testGetMaximumFailedPasswordsForWipe() {
-        if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testGetMaximumFailedPasswordsForWipe");
-            return;
-        }
-        mDevicePolicyManager.setMaximumFailedPasswordsForWipe(mComponent, 3);
-        assertEquals(3, mDevicePolicyManager.getMaximumFailedPasswordsForWipe(mComponent));
-
-        mDevicePolicyManager.setMaximumFailedPasswordsForWipe(mComponent, 5);
-        assertEquals(5, mDevicePolicyManager.getMaximumFailedPasswordsForWipe(mComponent));
-    }
-
-    public void testPasswordQuality_something() {
-        if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testPasswordQuality_something");
-            return;
-        }
-        mDevicePolicyManager.setPasswordQuality(mComponent,
-                DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
-        assertEquals(DevicePolicyManager.PASSWORD_QUALITY_SOMETHING,
-                mDevicePolicyManager.getPasswordQuality(mComponent));
-        assertFalse(mDevicePolicyManager.isActivePasswordSufficient());
-
-        String caseDescription = "initial";
-        assertPasswordSucceeds("1234", caseDescription);
-        assertPasswordSucceeds("abcd", caseDescription);
-        assertPasswordSucceeds("abcd1234", caseDescription);
-
-        mDevicePolicyManager.setPasswordMinimumLength(mComponent, 10);
-        caseDescription = "minimum password length = 10";
-        assertEquals(10, mDevicePolicyManager.getPasswordMinimumLength(mComponent));
-        assertFalse(mDevicePolicyManager.isActivePasswordSufficient());
-
-        assertPasswordFails("1234", caseDescription);
-        assertPasswordFails("abcd", caseDescription);
-        assertPasswordFails("abcd1234", caseDescription);
-
-        mDevicePolicyManager.setPasswordMinimumLength(mComponent, 4);
-        caseDescription = "minimum password length = 4";
-        assertEquals(4, mDevicePolicyManager.getPasswordMinimumLength(
-                mComponent));
-        assertTrue(mDevicePolicyManager.isActivePasswordSufficient());
-
-        assertPasswordSucceeds("1234", caseDescription);
-        assertPasswordSucceeds("abcd", caseDescription);
-        assertPasswordSucceeds("abcd1234", caseDescription);
-    }
-
-    public void testPasswordQuality_numeric() {
-        if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testPasswordQuality_numeric");
-            return;
-        }
-        mDevicePolicyManager.setPasswordQuality(mComponent,
-                DevicePolicyManager.PASSWORD_QUALITY_NUMERIC);
-        assertEquals(DevicePolicyManager.PASSWORD_QUALITY_NUMERIC,
-                mDevicePolicyManager.getPasswordQuality(mComponent));
-        assertFalse(mDevicePolicyManager.isActivePasswordSufficient());
-
-        String caseDescription = "initial";
-        assertPasswordSucceeds("1234", caseDescription);
-        assertPasswordSucceeds("abcd", caseDescription);
-        assertPasswordSucceeds("abcd1234", caseDescription);
-
-        mDevicePolicyManager.setPasswordMinimumLength(mComponent, 10);
-        caseDescription = "minimum password length = 10";
-        assertEquals(10, mDevicePolicyManager.getPasswordMinimumLength(mComponent));
-        assertFalse(mDevicePolicyManager.isActivePasswordSufficient());
-
-        assertPasswordFails("1234", caseDescription);
-        assertPasswordFails("abcd", caseDescription);
-        assertPasswordFails("abcd1234", caseDescription);
-
-        mDevicePolicyManager.setPasswordMinimumLength(mComponent, 4);
-        caseDescription = "minimum password length = 4";
-        assertEquals(4, mDevicePolicyManager.getPasswordMinimumLength(
-                mComponent));
-        assertTrue(mDevicePolicyManager.isActivePasswordSufficient());
-
-        assertPasswordSucceeds("1234", caseDescription);
-        assertPasswordSucceeds("abcd", caseDescription);
-        assertPasswordSucceeds("abcd1234", caseDescription);
-    }
-
-    public void testPasswordQuality_alphabetic() {
-        if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testPasswordQuality_alphabetic");
-            return;
-        }
-        mDevicePolicyManager.setPasswordQuality(mComponent,
-                DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC);
-        assertEquals(DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC,
-                mDevicePolicyManager.getPasswordQuality(mComponent));
-        assertFalse(mDevicePolicyManager.isActivePasswordSufficient());
-
-        String caseDescription = "initial";
-        assertPasswordFails("1234", caseDescription);
-        assertPasswordSucceeds("abcd", caseDescription);
-        assertPasswordSucceeds("abcd1234", caseDescription);
-
-        mDevicePolicyManager.setPasswordMinimumLength(mComponent, 10);
-        caseDescription = "minimum password length = 10";
-        assertEquals(10, mDevicePolicyManager.getPasswordMinimumLength(mComponent));
-        assertFalse(mDevicePolicyManager.isActivePasswordSufficient());
-
-        assertPasswordFails("1234", caseDescription);
-        assertPasswordFails("abcd", caseDescription);
-        assertPasswordFails("abcd1234", caseDescription);
-
-        mDevicePolicyManager.setPasswordMinimumLength(mComponent, 4);
-        caseDescription = "minimum password length = 4";
-        assertEquals(4, mDevicePolicyManager.getPasswordMinimumLength(
-                mComponent));
-        assertTrue(mDevicePolicyManager.isActivePasswordSufficient());
-
-        assertPasswordFails("1234", caseDescription);
-        assertPasswordSucceeds("abcd", caseDescription);
-        assertPasswordSucceeds("abcd1234", caseDescription);
-    }
-
-    public void testPasswordQuality_alphanumeric() {
-        if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testPasswordQuality_alphanumeric");
-            return;
-        }
-        mDevicePolicyManager.setPasswordQuality(mComponent,
-                DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC);
-        assertEquals(DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC,
-                mDevicePolicyManager.getPasswordQuality(mComponent));
-        assertFalse(mDevicePolicyManager.isActivePasswordSufficient());
-
-        String caseDescription = "initial";
-        assertPasswordFails("1234", caseDescription);
-        assertPasswordFails("abcd", caseDescription);
-        assertPasswordSucceeds("abcd1234", caseDescription);
-
-        mDevicePolicyManager.setPasswordMinimumLength(mComponent, 10);
-        caseDescription = "minimum password length = 10";
-        assertEquals(10, mDevicePolicyManager.getPasswordMinimumLength(mComponent));
-        assertFalse(mDevicePolicyManager.isActivePasswordSufficient());
-
-        assertPasswordFails("1234", caseDescription);
-        assertPasswordFails("abcd", caseDescription);
-        assertPasswordFails("abcd1234", caseDescription);
-
-        mDevicePolicyManager.setPasswordMinimumLength(mComponent, 4);
-        caseDescription = "minimum password length = 4";
-        assertEquals(4, mDevicePolicyManager.getPasswordMinimumLength(
-                mComponent));
-        assertTrue(mDevicePolicyManager.isActivePasswordSufficient());
-
-        assertPasswordFails("1234", caseDescription);
-        assertPasswordFails("abcd", caseDescription);
-        assertPasswordSucceeds("abcd1234", caseDescription);
-    }
-
-    public void testPasswordQuality_complexUpperCase() {
-        if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testPasswordQuality_complexUpperCase");
-            return;
-        }
-
-        mDevicePolicyManager.setPasswordQuality(mComponent, PASSWORD_QUALITY_COMPLEX);
-        assertEquals(PASSWORD_QUALITY_COMPLEX, mDevicePolicyManager.getPasswordQuality(mComponent));
-        resetComplexPasswordRestrictions();
-
-        String caseDescription = "minimum UpperCase=0";
-        assertPasswordSucceeds("abc1", caseDescription);
-        assertPasswordSucceeds("aBc1", caseDescription);
-        assertPasswordSucceeds("ABC1", caseDescription);
-        assertPasswordSucceeds("ABCD", caseDescription);
-        assertPasswordFails("123", caseDescription); // too short
-
-        mDevicePolicyManager.setPasswordMinimumUpperCase(mComponent, 1);
-        assertEquals(1, mDevicePolicyManager.getPasswordMinimumUpperCase(mComponent));
-        caseDescription = "minimum UpperCase=1";
-        assertPasswordFails("abc1", caseDescription);
-        assertPasswordSucceeds("aBc1", caseDescription);
-        assertPasswordSucceeds("ABC1", caseDescription);
-        assertPasswordSucceeds("ABCD", caseDescription);
-        assertPasswordFails("123", caseDescription); // too short
-
-        mDevicePolicyManager.setPasswordMinimumUpperCase(mComponent, 3);
-        assertEquals(3, mDevicePolicyManager.getPasswordMinimumUpperCase(mComponent));
-        caseDescription = "minimum UpperCase=3";
-        assertPasswordFails("abc1", caseDescription);
-        assertPasswordFails("aBC1", caseDescription);
-        assertPasswordSucceeds("ABC1", caseDescription);
-        assertPasswordSucceeds("ABCD", caseDescription);
-        assertPasswordFails("123", caseDescription); // too short
-    }
-
-    public void testPasswordQuality_complexLowerCase() {
-        if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testPasswordQuality_complexLowerCase");
-            return;
-        }
-
-        mDevicePolicyManager.setPasswordQuality(mComponent, PASSWORD_QUALITY_COMPLEX);
-        assertEquals(PASSWORD_QUALITY_COMPLEX, mDevicePolicyManager.getPasswordQuality(mComponent));
-        resetComplexPasswordRestrictions();
-
-        String caseDescription = "minimum LowerCase=0";
-        assertPasswordSucceeds("ABCD", caseDescription);
-        assertPasswordSucceeds("aBC1", caseDescription);
-        assertPasswordSucceeds("abc1", caseDescription);
-        assertPasswordSucceeds("abcd", caseDescription);
-        assertPasswordFails("123", caseDescription); // too short
-
-        mDevicePolicyManager.setPasswordMinimumLowerCase(mComponent, 1);
-        assertEquals(1, mDevicePolicyManager.getPasswordMinimumLowerCase(mComponent));
-        caseDescription = "minimum LowerCase=1";
-        assertPasswordFails("ABCD", caseDescription);
-        assertPasswordSucceeds("aBC1", caseDescription);
-        assertPasswordSucceeds("abc1", caseDescription);
-        assertPasswordSucceeds("abcd", caseDescription);
-        assertPasswordFails("123", caseDescription); // too short
-
-        mDevicePolicyManager.setPasswordMinimumLowerCase(mComponent, 3);
-        assertEquals(3, mDevicePolicyManager.getPasswordMinimumLowerCase(mComponent));
-        caseDescription = "minimum LowerCase=3";
-        assertPasswordFails("ABCD", caseDescription);
-        assertPasswordFails("aBC1", caseDescription);
-        assertPasswordSucceeds("abc1", caseDescription);
-        assertPasswordSucceeds("abcd", caseDescription);
-        assertPasswordFails("123", caseDescription); // too short
-    }
-
-    public void testPasswordQuality_complexLetters() {
-        if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testPasswordQuality_complexLetters");
-            return;
-        }
-
-        mDevicePolicyManager.setPasswordQuality(mComponent, PASSWORD_QUALITY_COMPLEX);
-        assertEquals(PASSWORD_QUALITY_COMPLEX, mDevicePolicyManager.getPasswordQuality(mComponent));
-        resetComplexPasswordRestrictions();
-
-        String caseDescription = "minimum Letters=0";
-        assertPasswordSucceeds("1234", caseDescription);
-        assertPasswordSucceeds("a123", caseDescription);
-        assertPasswordSucceeds("abc1", caseDescription);
-        assertPasswordSucceeds("abcd", caseDescription);
-        assertPasswordFails("123", caseDescription); // too short
-
-        mDevicePolicyManager.setPasswordMinimumLetters(mComponent, 1);
-        assertEquals(1, mDevicePolicyManager.getPasswordMinimumLetters(mComponent));
-        caseDescription = "minimum Letters=1";
-        assertPasswordFails("1234", caseDescription);
-        assertPasswordSucceeds("a123", caseDescription);
-        assertPasswordSucceeds("abc1", caseDescription);
-        assertPasswordSucceeds("abcd", caseDescription);
-        assertPasswordFails("123", caseDescription); // too short
-
-        mDevicePolicyManager.setPasswordMinimumLetters(mComponent, 3);
-        assertEquals(3, mDevicePolicyManager.getPasswordMinimumLetters(mComponent));
-        caseDescription = "minimum Letters=3";
-        assertPasswordFails("1234", caseDescription);
-        assertPasswordFails("a123", caseDescription);
-        assertPasswordSucceeds("abc1", caseDescription);
-        assertPasswordSucceeds("abcd", caseDescription);
-        assertPasswordFails("123", caseDescription); // too short
-    }
-
-    public void testPasswordQuality_complexNumeric() {
-        if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testPasswordQuality_complexNumeric");
-            return;
-        }
-
-        mDevicePolicyManager.setPasswordQuality(mComponent, PASSWORD_QUALITY_COMPLEX);
-        assertEquals(PASSWORD_QUALITY_COMPLEX, mDevicePolicyManager.getPasswordQuality(mComponent));
-        resetComplexPasswordRestrictions();
-
-        String caseDescription = "minimum Numeric=0";
-        assertPasswordSucceeds("abcd", caseDescription);
-        assertPasswordSucceeds("1abc", caseDescription);
-        assertPasswordSucceeds("123a", caseDescription);
-        assertPasswordSucceeds("1234", caseDescription);
-        assertPasswordFails("123", caseDescription); // too short
-
-        mDevicePolicyManager.setPasswordMinimumNumeric(mComponent, 1);
-        assertEquals(1, mDevicePolicyManager.getPasswordMinimumNumeric(mComponent));
-        caseDescription = "minimum Numeric=1";
-        assertPasswordFails("abcd", caseDescription);
-        assertPasswordSucceeds("1abc", caseDescription);
-        assertPasswordSucceeds("123a", caseDescription);
-        assertPasswordSucceeds("1234", caseDescription);
-        assertPasswordFails("123", caseDescription); // too short
-
-        mDevicePolicyManager.setPasswordMinimumNumeric(mComponent, 3);
-        assertEquals(3, mDevicePolicyManager.getPasswordMinimumNumeric(mComponent));
-        caseDescription = "minimum Numeric=3";
-        assertPasswordFails("abcd", caseDescription);
-        assertPasswordFails("1abc", caseDescription);
-        assertPasswordSucceeds("123a", caseDescription);
-        assertPasswordSucceeds("1234", caseDescription);
-        assertPasswordFails("123", caseDescription); // too short
-    }
-
-    public void testPasswordQuality_complexSymbols() {
-        if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testPasswordQuality_complexSymbols");
-            return;
-        }
-
-        mDevicePolicyManager.setPasswordQuality(mComponent, PASSWORD_QUALITY_COMPLEX);
-        assertEquals(PASSWORD_QUALITY_COMPLEX, mDevicePolicyManager.getPasswordQuality(mComponent));
-        resetComplexPasswordRestrictions();
-
-        String caseDescription = "minimum Symbols=0";
-        assertPasswordSucceeds("abcd", caseDescription);
-        assertPasswordSucceeds("_bc1", caseDescription);
-        assertPasswordSucceeds("@#!1", caseDescription);
-        assertPasswordSucceeds("_@#!", caseDescription);
-        assertPasswordFails("123", caseDescription); // too short
-
-        mDevicePolicyManager.setPasswordMinimumSymbols(mComponent, 1);
-        assertEquals(1, mDevicePolicyManager.getPasswordMinimumSymbols(mComponent));
-        caseDescription = "minimum Symbols=1";
-        assertPasswordFails("abcd", caseDescription);
-        assertPasswordSucceeds("_bc1", caseDescription);
-        assertPasswordSucceeds("@#!1", caseDescription);
-        assertPasswordSucceeds("_@#!", caseDescription);
-        assertPasswordFails("123", caseDescription); // too short
-
-        mDevicePolicyManager.setPasswordMinimumSymbols(mComponent, 3);
-        assertEquals(3, mDevicePolicyManager.getPasswordMinimumSymbols(mComponent));
-        caseDescription = "minimum Symbols=3";
-        assertPasswordFails("abcd", caseDescription);
-        assertPasswordFails("_bc1", caseDescription);
-        assertPasswordSucceeds("@#!1", caseDescription);
-        assertPasswordSucceeds("_@#!", caseDescription);
-        assertPasswordFails("123", caseDescription); // too short
-    }
-
-    public void testPasswordQuality_complexNonLetter() {
-        if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testPasswordQuality_complexNonLetter");
-            return;
-        }
-
-        mDevicePolicyManager.setPasswordQuality(mComponent, PASSWORD_QUALITY_COMPLEX);
-        assertEquals(PASSWORD_QUALITY_COMPLEX, mDevicePolicyManager.getPasswordQuality(mComponent));
-        resetComplexPasswordRestrictions();
-
-        String caseDescription = "minimum NonLetter=0";
-        assertPasswordSucceeds("Abcd", caseDescription);
-        assertPasswordSucceeds("_bcd", caseDescription);
-        assertPasswordSucceeds("3bcd", caseDescription);
-        assertPasswordSucceeds("_@3c", caseDescription);
-        assertPasswordSucceeds("_25!", caseDescription);
-        assertPasswordFails("123", caseDescription); // too short
-
-        mDevicePolicyManager.setPasswordMinimumNonLetter(mComponent, 1);
-        assertEquals(1, mDevicePolicyManager.getPasswordMinimumNonLetter(mComponent));
-        caseDescription = "minimum NonLetter=1";
-        assertPasswordFails("Abcd", caseDescription);
-        assertPasswordSucceeds("_bcd", caseDescription);
-        assertPasswordSucceeds("3bcd", caseDescription);
-        assertPasswordSucceeds("_@3c", caseDescription);
-        assertPasswordSucceeds("_25!", caseDescription);
-        assertPasswordFails("123", caseDescription); // too short
-
-        mDevicePolicyManager.setPasswordMinimumNonLetter(mComponent, 3);
-        assertEquals(3, mDevicePolicyManager.getPasswordMinimumNonLetter(mComponent));
-        caseDescription = "minimum NonLetter=3";
-        assertPasswordFails("Abcd", caseDescription);
-        assertPasswordFails("_bcd", caseDescription);
-        assertPasswordFails("3bcd", caseDescription);
-        assertPasswordSucceeds("_@3c", caseDescription);
-        assertPasswordSucceeds("_25!", caseDescription);
-        assertPasswordFails("123", caseDescription); // too short
-    }
-
-    public void testPasswordHistoryLength() {
-        if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testPasswordHistoryLength");
-            return;
-        }
-        // Password history length restriction is only imposed if password quality is at least
-        // numeric.
-        mDevicePolicyManager.setPasswordQuality(mComponent,
-                DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC);
-        int originalValue = mDevicePolicyManager.getPasswordHistoryLength(mComponent);
-        try {
-            mDevicePolicyManager.setPasswordHistoryLength(mComponent, 3);
-            assertEquals(3, mDevicePolicyManager.getPasswordHistoryLength(mComponent));
-            // Although it would make sense we cannot test if password history restrictions
-            // are enforced as DevicePolicyManagerService.resetPassword fails to do so at the
-            // moment. See b/17707820
-        } finally {
-            mDevicePolicyManager.setPasswordHistoryLength(mComponent, originalValue);
-        }
-    }
-
-    public void testPasswordExpirationTimeout() {
-        if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testPasswordExpirationTimeout");
-            return;
-        }
-        long originalValue = mDevicePolicyManager.getPasswordExpirationTimeout(mComponent);
-        try {
-            for (long testLength : new long[] {
-                    0L, 864000000L /* ten days */, 8640000000L /* 100 days */}) {
-                mDevicePolicyManager.setPasswordExpirationTimeout(mComponent, testLength);
-                assertEquals(testLength,
-                        mDevicePolicyManager.getPasswordExpirationTimeout(mComponent));
-            }
-        } finally {
-            mDevicePolicyManager.setPasswordExpirationTimeout(mComponent, originalValue);
-        }
-    }
-
-    public void testKeyguardDisabledFeatures() {
-        if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testKeyguardDisabledFeatures");
-            return;
-        }
-        int originalValue = mDevicePolicyManager.getKeyguardDisabledFeatures(mComponent);
-        try {
-            for (int which = DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_NONE;
-                    which < 2 * DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT; ++which) {
-                mDevicePolicyManager.setKeyguardDisabledFeatures(mComponent, which);
-                assertEquals(which, mDevicePolicyManager.getKeyguardDisabledFeatures(mComponent));
-            }
-        } finally {
-            mDevicePolicyManager.setKeyguardDisabledFeatures(mComponent, originalValue);
-        }
-    }
-
-    public void testCreateUser_failIfNotDeviceOwner() {
-        if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testCreateUser_failIfNotDeviceOwner");
-            return;
-        }
-        try {
-            mDevicePolicyManager.createUser(mComponent, "user name");
-            fail("did not throw expected SecurityException");
-        } catch (SecurityException e) {
-            assertDeviceOwnerMessage(e.getMessage());
-        }
-    }
-
-    public void testRemoveUser_failIfNotDeviceOwner() {
-        if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testRemoveUser_failIfNotDeviceOwner");
-            return;
-        }
-        try {
-            mDevicePolicyManager.removeUser(mComponent, null);
-            fail("did not throw expected SecurityException");
-        } catch (SecurityException e) {
-            assertDeviceOwnerMessage(e.getMessage());
-        }
-    }
-
-    public void testSetApplicationHidden_failIfNotDeviceOrProfileOwner() {
-        if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testSetApplicationHidden_failIfNotDeviceOrProfileOwner");
-            return;
-        }
-        try {
-            mDevicePolicyManager.setApplicationHidden(mComponent, "com.google.anything", true);
-            fail("did not throw expected SecurityException");
-        } catch (SecurityException e) {
-            assertProfileOwnerMessage(e.getMessage());
-        }
-    }
-
-    public void testIsApplicationHidden_failIfNotDeviceOrProfileOwner() {
-        if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testIsApplicationHidden_failIfNotDeviceOrProfileOwner");
-            return;
-        }
-        try {
-            mDevicePolicyManager.isApplicationHidden(mComponent, "com.google.anything");
-            fail("did not throw expected SecurityException");
-        } catch (SecurityException e) {
-            assertProfileOwnerMessage(e.getMessage());
-        }
-    }
-
-    public void testSetGlobalSetting_failIfNotDeviceOwner() {
-        if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testSetGlobalSetting_failIfNotDeviceOwner");
-            return;
-        }
-        try {
-            mDevicePolicyManager.setGlobalSetting(mComponent,
-                    Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, "1");
-            fail("did not throw expected SecurityException");
-        } catch (SecurityException e) {
-            assertDeviceOwnerMessage(e.getMessage());
-        }
-    }
-
-    public void testSetSecureSetting_failIfNotDeviceOrProfileOwner() {
-        if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testSetSecureSetting_failIfNotDeviceOrProfileOwner");
-            return;
-        }
-        try {
-            mDevicePolicyManager.setSecureSetting(mComponent,
-                    Settings.Secure.INSTALL_NON_MARKET_APPS, "1");
-            fail("did not throw expected SecurityException");
-        } catch (SecurityException e) {
-            assertProfileOwnerMessage(e.getMessage());
-        }
-    }
-
-    public void testSetMasterVolumeMuted_failIfNotDeviceOrProfileOwner() {
-        if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testSetMasterVolumeMuted_failIfNotDeviceOrProfileOwner");
-            return;
-        }
-        try {
-            mDevicePolicyManager.setMasterVolumeMuted(mComponent, true);
-            fail("did not throw expected SecurityException");
-        } catch (SecurityException e) {
-            assertProfileOwnerMessage(e.getMessage());
-        }
-    }
-
-    public void testIsMasterVolumeMuted_failIfNotDeviceOrProfileOwner() {
-        if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testSetMasterVolumeMuted_failIfNotDeviceOrProfileOwner");
-            return;
-        }
-        try {
-            mDevicePolicyManager.isMasterVolumeMuted(mComponent);
-            fail("did not throw expected SecurityException");
-        } catch (SecurityException e) {
-            assertProfileOwnerMessage(e.getMessage());
-        }
-    }
-
-    public void testSetRecommendedGlobalProxy_failIfNotDeviceOwner() {
-        if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testSetRecommendedGlobalProxy_failIfNotDeviceOwner");
-            return;
-        }
-        try {
-            mDevicePolicyManager.setRecommendedGlobalProxy(mComponent, null);
-            fail("did not throw expected SecurityException");
-        } catch (SecurityException e) {
-            assertDeviceOwnerMessage(e.getMessage());
-        }
-    }
-
-    public void testSetLockTaskPackages_failIfNotDeviceOwner() {
-        if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testSetLockTaskPackages_failIfNotDeviceOwner");
-            return;
-        }
-        try {
-            mDevicePolicyManager.setLockTaskPackages(mComponent, new String[] {"package"});
-            fail("did not throw expected SecurityException");
-        } catch (SecurityException e) {
-        }
-    }
-
-    public void testClearDeviceOwnerApp_failIfNotDeviceOwner() {
-        if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testClearDeviceOwnerApp_failIfNotDeviceOwner");
-            return;
-        }
-        try {
-            mDevicePolicyManager.clearDeviceOwnerApp("android.deviceadmin.cts");
-            fail("did not throw expected SecurityException");
-        } catch (SecurityException e) {
-            assertDeviceOwnerMessage(e.getMessage());
-        }
-    }
-
-    public void testSwitchUser_failIfNotDeviceOwner() {
-        if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testSwitchUser_failIfNotDeviceOwner");
-            return;
-        }
-        try {
-            mDevicePolicyManager.switchUser(mComponent, null);
-            fail("did not throw expected SecurityException");
-        } catch (SecurityException e) {
-            assertDeviceOwnerMessage(e.getMessage());
-        }
-    }
-
-    public void testCreateAndInitializeUser_failIfNotDeviceOwner() {
-        if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testCreateAndInitializeUser_failIfNotDeviceOwner");
-            return;
-        }
-        try {
-            mDevicePolicyManager.createAndInitializeUser(mComponent, "name", "admin name",
-                        mComponent, null);
-            fail("did not throw expected SecurityException");
-        } catch (SecurityException e) {
-            assertDeviceOwnerMessage(e.getMessage());
-        }
-    }
-
-    public void testInstallCaCert_failIfNotProfileOwner() {
-        if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testInstallCaCert_failIfNotProfileOwner");
-            return;
-        }
-        try {
-            mDevicePolicyManager.installCaCert(mComponent,
-                    TEST_CA_STRING1.getBytes());
-            fail("did not throw expected SecurityException");
-        } catch (SecurityException e) {
-            assertProfileOwnerMessage(e.getMessage());
-        }
-    }
-
-    public void testInstallCaCert_failIfNotCertInstaller() {
-        if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testInstallCaCert_failIfNotCertInstaller");
-            return;
-        }
-        try {
-            // Delegated cert installer is identified by using null as the first argument.
-            mDevicePolicyManager.installCaCert(null, TEST_CA_STRING1.getBytes());
-            fail("did not throw expected SecurityException");
-        } catch (SecurityException expected) {
-        }
-    }
-
-    public void testUninstallCaCert_failIfNotProfileOwner() {
-        if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testUninstallCaCert_failIfNotProfileOwner");
-            return;
-        }
-        try {
-            mDevicePolicyManager.uninstallCaCert(mComponent,
-                    TEST_CA_STRING1.getBytes());
-            fail("did not throw expected SecurityException");
-        } catch (SecurityException e) {
-            assertProfileOwnerMessage(e.getMessage());
-        }
-    }
-
-    public void testUninstallCaCert_failIfNotCertInstaller() {
-        if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testUninstallCaCert_failIfNotCertInstaller");
-            return;
-        }
-        try {
-            // Delegated cert installer is identified by using null as the first argument.
-            mDevicePolicyManager.uninstallCaCert(null, TEST_CA_STRING1.getBytes());
-            fail("did not throw expected SecurityException");
-        } catch (SecurityException expected) {
-        }
-    }
-
-    public void testGetInstalledCaCerts_failIfNotProfileOwner() {
-        if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testGetInstalledCaCerts_failIfNotProfileOwner");
-            return;
-        }
-        try {
-            mDevicePolicyManager.getInstalledCaCerts(mComponent);
-            fail("did not throw expected SecurityException");
-        } catch (SecurityException e) {
-            assertProfileOwnerMessage(e.getMessage());
-        }
-    }
-
-    public void testGetInstalledCaCerts_failIfNotCertInstaller() {
-        if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testGetInstalledCaCerts_failIfNotCertInstaller");
-            return;
-        }
-        try {
-            // Delegated cert installer is identified by using null as the first argument.
-            mDevicePolicyManager.getInstalledCaCerts(null);
-            fail("did not throw expected SecurityException");
-        } catch (SecurityException expected) {
-        }
-    }
-
-    public void testHasCaCertInstalled_failIfNotProfileOwner() {
-        if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testHasCaCertInstalled_failIfNotProfileOwner");
-            return;
-        }
-        try {
-            mDevicePolicyManager.hasCaCertInstalled(mComponent,
-                    TEST_CA_STRING1.getBytes());
-            fail("did not throw expected SecurityException");
-        } catch (SecurityException e) {
-            assertProfileOwnerMessage(e.getMessage());
-        }
-    }
-
-    public void testHasCaCertInstalled_failIfNotCertInstaller() {
-        if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testHasCaCertInstalled_failIfNotCertInstaller");
-            return;
-        }
-        try {
-            // Delegated cert installer is identified by using null as the first argument.
-            mDevicePolicyManager.hasCaCertInstalled(null, TEST_CA_STRING1.getBytes());
-            fail("did not throw expected SecurityException");
-        } catch (SecurityException expected) {
-        }
-    }
-
-    public void testUninstallAllUserCaCerts_failIfNotProfileOwner() {
-        if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testUninstallAllUserCaCerts_failIfNotProfileOwner");
-            return;
-        }
-        try {
-            mDevicePolicyManager.uninstallAllUserCaCerts(mComponent);
-            fail("did not throw expected SecurityException");
-        } catch (SecurityException e) {
-            assertProfileOwnerMessage(e.getMessage());
-        }
-    }
-
-    public void testUninstallAllUserCaCerts_failIfNotCertInstaller() {
-        if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testUninstallAllUserCaCerts_failIfNotCertInstaller");
-            return;
-        }
-        try {
-            // Delegated cert installer is identified by using null as the first argument.
-            mDevicePolicyManager.uninstallAllUserCaCerts(null);
-            fail("did not throw expected SecurityException");
-        } catch (SecurityException expected) {
-        }
-    }
-
-    public void testSetScreenCaptureDisabled_failIfNotProfileOwner() {
-        if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testSetScreenCaptureDisabled_failIfNotProfileOwner");
-            return;
-        }
-        try {
-            mDevicePolicyManager.setScreenCaptureDisabled(mComponent, true);
-            fail("did not throw expected SecurityException");
-        } catch (SecurityException e) {
-            assertProfileOwnerMessage(e.getMessage());
-        }
-    }
-
-    public void testSetAutoTimeRequired_failIfNotDeviceOwner() {
-        if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testSetAutoTimeRequired_failIfNotDeviceOwner");
-            return;
-        }
-        try {
-            mDevicePolicyManager.setAutoTimeRequired(mComponent, true);
-            fail("did not throw expected SecurityException");
-        } catch (SecurityException e) {
-            assertDeviceOwnerMessage(e.getMessage());
-        }
-    }
-
-    public void testAddPersistentPreferredActivity_failIfNotProfileOwner() {
-        if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testAddPersistentPreferredActivity_failIfNotProfileOwner");
-            return;
-        }
-        try {
-            mDevicePolicyManager.addPersistentPreferredActivity(mComponent,
-                    new IntentFilter(Intent.ACTION_MAIN),
-                    new ComponentName("android.admin.cts", "dummy"));
-            fail("did not throw expected SecurityException");
-        } catch (SecurityException e) {
-            assertProfileOwnerMessage(e.getMessage());
-        }
-    }
-
-    public void testClearPackagePersistentPreferredActivities_failIfNotProfileOwner() {
-        if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testClearPackagePersistentPreferredActivities_failIfNotProfileOwner");
-            return;
-        }
-        try {
-            mDevicePolicyManager.clearPackagePersistentPreferredActivities(mComponent,
-                    "android.admin.cts");
-            fail("did not throw expected SecurityException");
-        } catch (SecurityException e) {
-            assertProfileOwnerMessage(e.getMessage());
-        }
-    }
-
-    public void testSetApplicationRestrictions_failIfNotProfileOwner() {
-        if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testSetApplicationRestrictions_failIfNotProfileOwner");
-            return;
-        }
-        try {
-            mDevicePolicyManager.setApplicationRestrictions(mComponent,
-                    "android.admin.cts", null);
-            fail("did not throw expected SecurityException");
-        } catch (SecurityException e) {
-            assertProfileOwnerMessage(e.getMessage());
-        }
-    }
-
-    public void testAddUserRestriction_failIfNotProfileOwner() {
-        if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testAddUserRestriction_failIfNotProfileOwner");
-            return;
-        }
-        try {
-            mDevicePolicyManager.addUserRestriction(mComponent,
-                    UserManager.DISALLOW_SMS);
-            fail("did not throw expected SecurityException");
-        } catch (SecurityException e) {
-            assertProfileOwnerMessage(e.getMessage());
-        }
-    }
-
-    public void testSetAccountManagementDisabled_failIfNotProfileOwner() {
-        if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testSetAccountManagementDisabled_failIfNotProfileOwner");
-            return;
-        }
-        try {
-            mDevicePolicyManager.setAccountManagementDisabled(mComponent,
-                    "dummy", true);
-            fail("did not throw expected SecurityException");
-        } catch (SecurityException e) {
-            assertProfileOwnerMessage(e.getMessage());
-        }
-    }
-
-    public void testSetRestrictionsProvider_failIfNotProfileOwner() {
-        if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testSetRestrictionsProvider_failIfNotProfileOwner");
-            return;
-        }
-        try {
-            mDevicePolicyManager.setRestrictionsProvider(mComponent,
-                    new ComponentName("android.admin.cts", "dummy"));
-            fail("did not throw expected SecurityException");
-        } catch (SecurityException e) {
-            assertProfileOwnerMessage(e.getMessage());
-        }
-    }
-
-    public void testSetUninstallBlocked_failIfNotProfileOwner() {
-        if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testSetUninstallBlocked_failIfNotProfileOwner");
-            return;
-        }
-        try {
-            mDevicePolicyManager.setUninstallBlocked(mComponent,
-                    "android.admin.cts", true);
-            fail("did not throw expected SecurityException");
-        } catch (SecurityException e) {
-            assertProfileOwnerMessage(e.getMessage());
-        }
-    }
-
-    public void testSetPermittedAccessibilityServices_failIfNotProfileOwner() {
-        if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testSetPermittedAccessibilityServices_failIfNotProfileOwner");
-            return;
-        }
-        try {
-            mDevicePolicyManager.setPermittedAccessibilityServices(mComponent, null);
-            fail("did not throw expected SecurityException");
-        } catch (SecurityException e) {
-            assertProfileOwnerMessage(e.getMessage());
-        }
-    }
-
-    public void testSetBluetoothContactSharingDisabled_failIfNotProfileOwner() {
-        if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testSetBluetoothContactSharingDisabled_failIfNotProfileOwner");
-            return;
-        }
-        try {
-            mDevicePolicyManager.setBluetoothContactSharingDisabled(mComponent, true);
-            fail("did not throw expected SecurityException");
-        } catch (SecurityException e) {
-            assertProfileOwnerMessage(e.getMessage());
-        }
-    }
-
-    public void testSetPermittedInputMethods_failIfNotProfileOwner() {
-        if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testSetPermittedInputMethods_failIfNotProfileOwner");
-            return;
-        }
-        try {
-            mDevicePolicyManager.setPermittedInputMethods(mComponent, null);
-            fail("did not throw expected SecurityException");
-        } catch (SecurityException e) {
-            assertProfileOwnerMessage(e.getMessage());
-        }
-    }
-
-    /**
-     * Test whether the version of the pre-installed launcher is at least L. This is needed for
-     * managed profile support.
-     */
-    public void testLauncherVersionAtLeastL() throws Exception {
-        if (!mManagedProfiles) {
-            return;
-        }
-
-        Intent intent = new Intent(Intent.ACTION_MAIN);
-        intent.addCategory(Intent.CATEGORY_HOME);
-        List<ResolveInfo> resolveInfos = mPackageManager.queryIntentActivities(intent,
-                0 /* default flags */);
-        assertFalse("No launcher present", resolveInfos.isEmpty());
-
-        for (ResolveInfo resolveInfo : resolveInfos) {
-            ApplicationInfo launcherAppInfo = mPackageManager.getApplicationInfo(
-                    resolveInfo.activityInfo.packageName, 0 /* default flags */);
-            if ((launcherAppInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0 &&
-                    launcherAppInfo.targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP) {
-                return;
-            }
-        }
-        fail("No system launcher with version L+ present present on device.");
-    }
-
-    /**
-     * Test that managed provisioning is pre-installed if and only if the device declares the
-     * device admin feature.
-     */
-    public void testManagedProvisioningPreInstalled() throws Exception {
-        assertEquals(mDeviceAdmin, isPackageInstalledOnSystemImage(MANAGED_PROVISIONING_PKG));
-    }
-
-    private void assertDeviceOwnerMessage(String message) {
-        assertTrue("message is: "+ message, message.contains("does not own the device")
-                || message.contains("can only be called by the device owner"));
-    }
-
-    private void assertProfileOwnerMessage(String message) {
-        assertTrue("message is: "+ message,
-                message.contains("does not own the profile"));
-    }
-
-    private void resetComplexPasswordRestrictions() {
-        /**
-         * Not enough to reset only mComponent as
-         * {@link DevicePolicyManager#resetPassword(String, int)} checks restrictions across all
-         * admin components.
-         */
-        for (ComponentName adminComponent : new ComponentName[] {mComponent, mSecondComponent}) {
-            mDevicePolicyManager.setPasswordMinimumLength(adminComponent, 0);
-            mDevicePolicyManager.setPasswordMinimumUpperCase(adminComponent, 0);
-            mDevicePolicyManager.setPasswordMinimumLowerCase(adminComponent, 0);
-            mDevicePolicyManager.setPasswordMinimumLetters(adminComponent, 0);
-            mDevicePolicyManager.setPasswordMinimumNumeric(adminComponent, 0);
-            mDevicePolicyManager.setPasswordMinimumSymbols(adminComponent, 0);
-            mDevicePolicyManager.setPasswordMinimumNonLetter(adminComponent, 0);
-        }
-    }
-
-    private void assertPasswordFails(String password, String restriction) {
-        try {
-            boolean passwordResetResult = mDevicePolicyManager.resetPassword(password, /* flags= */0);
-            assertFalse("Password '" + password + "' should have failed on " + restriction,
-                    passwordResetResult);
-        } catch (IllegalArgumentException e) {
-            // yesss, we have failed!
-        }
-    }
-
-    private void assertPasswordSucceeds(String password, String restriction) {
-        boolean passwordResetResult = mDevicePolicyManager.resetPassword(password, /* flags= */0);
-        assertTrue("Password '" + password + "' failed on " + restriction, passwordResetResult);
-        assertTrue(mDevicePolicyManager.isActivePasswordSufficient());
-    }
-
-    public void testSetDelegatedCertInstaller_failIfNotProfileOwner() {
-        if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testSetDelegatedCertInstaller_failIfNotProfileOwner");
-            return;
-        }
-        try {
-            mDevicePolicyManager.setCertInstallerPackage(mComponent, "com.test.package");
-            fail("did not throw expected SecurityException");
-        } catch (SecurityException e) {
-            assertProfileOwnerMessage(e.getMessage());
-        }
-    }
-
-    public void testGetDelegatedCertInstaller_failIfNotProfileOwner() {
-        if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testGetDelegatedCertInstaller_failIfNotProfileOwner");
-            return;
-        }
-        try {
-            mDevicePolicyManager.getCertInstallerPackage(mComponent);
-            fail("did not throw expected SecurityException");
-        } catch (SecurityException e) {
-            assertProfileOwnerMessage(e.getMessage());
-        }
-    }
-
-    public void testSetSystemUpdatePolicy_failIfNotDeviceOwner() {
-        if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testSetSystemUpdatePolicy_failIfNotDeviceOwner");
-            return;
-        }
-        try {
-            mDevicePolicyManager.setSystemUpdatePolicy(mComponent, null);
-            fail("did not throw expected SecurityException");
-        } catch (SecurityException e) {
-            assertDeviceOwnerMessage(e.getMessage());
-        }
-    }
-
-    private boolean isPackageInstalledOnSystemImage(String packagename) {
-        try {
-            ApplicationInfo info = mPackageManager.getApplicationInfo(packagename,
-                    0 /* default flags */);
-            return (info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
-        } catch (NameNotFoundException e) {
-            return false;
-        }
-    }
-}
diff --git a/tests/tests/alarmclock/Android.mk b/tests/tests/alarmclock/Android.mk
index 6c30bc7..e83accf 100644
--- a/tests/tests/alarmclock/Android.mk
+++ b/tests/tests/alarmclock/Android.mk
@@ -29,5 +29,10 @@
 
 LOCAL_SDK_VERSION := current
 
+LOCAL_CTS_MODULE_CONFIG := $(LOCAL_PATH)/Old$(CTS_MODULE_TEST_CONFIG)
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_CTS_PACKAGE)
 include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/tests/alarmclock/AndroidTest.xml b/tests/tests/alarmclock/AndroidTest.xml
index aafdb61..525257e 100644
--- a/tests/tests/alarmclock/AndroidTest.xml
+++ b/tests/tests/alarmclock/AndroidTest.xml
@@ -1,3 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
 <!-- Copyright (C) 2015 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
@@ -12,10 +13,19 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<configuration description="Test module config for AlarmClock">
-    <include name="common-config" />
-    <option name="cts-apk-installer:test-file-name" value="CtsAlarmClockService.apk" />
-    <option name="run-command:run-command"
-         value="settings put secure voice_interaction_service android.alarmclock.service/.MainInteractionService" />
-    <option name="cts-apk-installer:test-file-name" value="CtsAlarmClockTestCases.apk" />
-</configuration>
+<configuration description="Configuration for AlarmClock Tests">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsAlarmClockService.apk" />
+        <option name="test-file-name" value="CtsAlarmClockTestCases.apk" />
+    </target_preparer>
+
+    <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">    
+        <option name="run-command"
+             value="settings put secure voice_interaction_service android.alarmclock.service/.MainInteractionService" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest">
+        <option name="package" value="android.alarmclock.cts" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/tests/alarmclock/OldAndroidTest.xml b/tests/tests/alarmclock/OldAndroidTest.xml
new file mode 100644
index 0000000..aafdb61
--- /dev/null
+++ b/tests/tests/alarmclock/OldAndroidTest.xml
@@ -0,0 +1,21 @@
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Test module config for AlarmClock">
+    <include name="common-config" />
+    <option name="cts-apk-installer:test-file-name" value="CtsAlarmClockService.apk" />
+    <option name="run-command:run-command"
+         value="settings put secure voice_interaction_service android.alarmclock.service/.MainInteractionService" />
+    <option name="cts-apk-installer:test-file-name" value="CtsAlarmClockTestCases.apk" />
+</configuration>
diff --git a/tests/tests/alarmclock/common/Android.mk b/tests/tests/alarmclock/common/Android.mk
index d460ade..ec0022b 100644
--- a/tests/tests/alarmclock/common/Android.mk
+++ b/tests/tests/alarmclock/common/Android.mk
@@ -27,4 +27,7 @@
 
 LOCAL_SDK_VERSION := current
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/tests/tests/alarmclock/service/Android.mk b/tests/tests/alarmclock/service/Android.mk
index 53dc564..8f0b185 100644
--- a/tests/tests/alarmclock/service/Android.mk
+++ b/tests/tests/alarmclock/service/Android.mk
@@ -29,4 +29,7 @@
 
 LOCAL_SDK_VERSION := current
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/tests/tests/animation/Android.mk b/tests/tests/animation/Android.mk
index 3d8daf7..205adda 100644
--- a/tests/tests/animation/Android.mk
+++ b/tests/tests/animation/Android.mk
@@ -28,6 +28,9 @@
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_SDK_VERSION := current
 
 include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/animation/AndroidManifest.xml b/tests/tests/animation/AndroidManifest.xml
index fdc5ad9..3744a2a 100644
--- a/tests/tests/animation/AndroidManifest.xml
+++ b/tests/tests/animation/AndroidManifest.xml
@@ -15,20 +15,22 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.animation">
+    package="android.animation.cts">
     <uses-sdk android:minSdkVersion="11" />
     <uses-permission android:name="android.permission.INJECT_EVENTS" />
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <application>
         <activity android:name="android.animation.cts.AnimationActivity"
-            android:label="AnimationActivity"/>
+                  android:label="AnimationActivity"/>
+        <activity android:name="android.animation.cts.ButtonViewActivity"
+                  android:label="ButtonViewActivity"/>
         <activity
            android:name="android.animation.cts.LayoutAnimationActivity" />
         <uses-library android:name="android.test.runner" />
     </application>
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.cts.animation"
+                     android:targetPackage="android.animation.cts"
                      android:label="CTS tests for android.animation package">
         <meta-data android:name="listener"
             android:value="com.android.cts.runner.CtsTestRunListener" />
diff --git a/tests/tests/animation/AndroidTest.xml b/tests/tests/animation/AndroidTest.xml
new file mode 100644
index 0000000..b4a0ad5
--- /dev/null
+++ b/tests/tests/animation/AndroidTest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS Animation test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsAnimationTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.animation.cts" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/tests/animation/res/animator/object_animator.xml b/tests/tests/animation/res/animator/object_animator.xml
new file mode 100644
index 0000000..17fcd60
--- /dev/null
+++ b/tests/tests/animation/res/animator/object_animator.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
+          android:propertyName="x" android:valueFrom="0" android:valueTo="1">
+
+</objectAnimator>
\ No newline at end of file
diff --git a/tests/tests/animation/res/animator/object_animator_pvh1.xml b/tests/tests/animation/res/animator/object_animator_pvh1.xml
new file mode 100644
index 0000000..7e16bc8
--- /dev/null
+++ b/tests/tests/animation/res/animator/object_animator_pvh1.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android">
+    <propertyValuesHolder android:propertyName="x" android:valueFrom="0" android:valueTo="1"/>
+    <propertyValuesHolder android:propertyName="y" android:valueFrom="10" android:valueTo="11"/>
+</objectAnimator>
\ No newline at end of file
diff --git a/tests/tests/animation/res/animator/object_animator_pvh_kf1.xml b/tests/tests/animation/res/animator/object_animator_pvh_kf1.xml
new file mode 100644
index 0000000..b99b819
--- /dev/null
+++ b/tests/tests/animation/res/animator/object_animator_pvh_kf1.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android">
+    <propertyValuesHolder android:propertyName="x" android:valueFrom="0" android:valueTo="1"/>
+    <propertyValuesHolder android:propertyName="y" >
+        <keyframe android:fraction="0" android:value="10"/>
+        <keyframe android:fraction="1" android:value="11"/>
+    </propertyValuesHolder>
+</objectAnimator>
\ No newline at end of file
diff --git a/tests/tests/animation/res/animator/value_animator.xml b/tests/tests/animation/res/animator/value_animator.xml
new file mode 100644
index 0000000..4c1abfe
--- /dev/null
+++ b/tests/tests/animation/res/animator/value_animator.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<animator xmlns:android="http://schemas.android.com/apk/res/android"
+        android:valueFrom="0" android:valueTo="1">
+
+</animator>
\ No newline at end of file
diff --git a/tests/tests/animation/res/animator/value_animator_pvh1.xml b/tests/tests/animation/res/animator/value_animator_pvh1.xml
new file mode 100644
index 0000000..30540ec
--- /dev/null
+++ b/tests/tests/animation/res/animator/value_animator_pvh1.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<animator xmlns:android="http://schemas.android.com/apk/res/android">
+    <propertyValuesHolder android:valueFrom="0" android:valueTo="1"/>
+
+</animator>
\ No newline at end of file
diff --git a/tests/tests/animation/res/animator/value_animator_pvh2.xml b/tests/tests/animation/res/animator/value_animator_pvh2.xml
new file mode 100644
index 0000000..2c07b4e
--- /dev/null
+++ b/tests/tests/animation/res/animator/value_animator_pvh2.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<animator xmlns:android="http://schemas.android.com/apk/res/android">
+    <propertyValuesHolder android:valueFrom="0" android:valueTo="1"></propertyValuesHolder>
+
+</animator>
\ No newline at end of file
diff --git a/tests/tests/animation/res/animator/value_animator_pvh_kf1.xml b/tests/tests/animation/res/animator/value_animator_pvh_kf1.xml
new file mode 100644
index 0000000..e8fb9cc
--- /dev/null
+++ b/tests/tests/animation/res/animator/value_animator_pvh_kf1.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<animator xmlns:android="http://schemas.android.com/apk/res/android">
+    <propertyValuesHolder>
+        <keyframe android:fraction="0" android:value="0"/>
+        <keyframe android:fraction="1" android:value="1"/>
+    </propertyValuesHolder>
+</animator>
\ No newline at end of file
diff --git a/tests/tests/animation/res/animator/value_animator_pvh_kf2.xml b/tests/tests/animation/res/animator/value_animator_pvh_kf2.xml
new file mode 100644
index 0000000..be8184f
--- /dev/null
+++ b/tests/tests/animation/res/animator/value_animator_pvh_kf2.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<animator xmlns:android="http://schemas.android.com/apk/res/android">
+    <propertyValuesHolder>
+        <keyframe android:fraction="0" android:value="0"></keyframe>
+        <keyframe android:fraction="1" android:value="1"/>
+    </propertyValuesHolder>
+</animator>
\ No newline at end of file
diff --git a/tests/tests/animation/res/animator/value_animator_pvh_kf3.xml b/tests/tests/animation/res/animator/value_animator_pvh_kf3.xml
new file mode 100644
index 0000000..5d6dd4b
--- /dev/null
+++ b/tests/tests/animation/res/animator/value_animator_pvh_kf3.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<animator xmlns:android="http://schemas.android.com/apk/res/android">
+    <propertyValuesHolder>
+        <keyframe android:fraction="0" android:value="0"></keyframe>
+        <keyframe android:fraction=".4" android:value=".2"/>
+        <keyframe android:fraction=".6" android:value=".2"/>
+        <keyframe android:fraction="1" android:value="1"/>
+    </propertyValuesHolder>
+</animator>
\ No newline at end of file
diff --git a/tests/tests/animation/res/animator/value_animator_pvh_kf4.xml b/tests/tests/animation/res/animator/value_animator_pvh_kf4.xml
new file mode 100644
index 0000000..a59fb84
--- /dev/null
+++ b/tests/tests/animation/res/animator/value_animator_pvh_kf4.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<animator xmlns:android="http://schemas.android.com/apk/res/android">
+    <propertyValuesHolder>
+        <keyframe android:value="0"></keyframe>
+        <keyframe android:value=".2"/>
+        <keyframe android:value=".2"/>
+        <keyframe android:value="1"/>
+    </propertyValuesHolder>
+</animator>
\ No newline at end of file
diff --git a/tests/tests/animation/res/layout/button_view.xml b/tests/tests/animation/res/layout/button_view.xml
new file mode 100644
index 0000000..349fedf
--- /dev/null
+++ b/tests/tests/animation/res/layout/button_view.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:orientation="vertical"
+              android:layout_width="fill_parent"
+              android:layout_height="fill_parent"
+              android:id="@+id/container">
+    <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/button"
+            android:id="@+id/button"/>
+    <View
+            android:layout_width="200dp"
+            android:layout_height="200dp"
+            android:background="#fff"
+            android:id="@+id/square"/>
+</LinearLayout>
\ No newline at end of file
diff --git a/tests/tests/animation/res/values/strings.xml b/tests/tests/animation/res/values/strings.xml
index 8d167fd..587930b 100644
--- a/tests/tests/animation/res/values/strings.xml
+++ b/tests/tests/animation/res/values/strings.xml
@@ -15,4 +15,5 @@
 -->
 <resources>
     <string name="add_button">Add Button</string>
+    <string name="button">Button</string>
 </resources>
diff --git a/tests/tests/animation/src/android/animation/cts/AnimationActivity.java b/tests/tests/animation/src/android/animation/cts/AnimationActivity.java
index 225a97e..598048e 100644
--- a/tests/tests/animation/src/android/animation/cts/AnimationActivity.java
+++ b/tests/tests/animation/src/android/animation/cts/AnimationActivity.java
@@ -39,7 +39,7 @@
 import android.view.animation.AccelerateInterpolator;
 import java.util.ArrayList;
 
-import com.android.cts.animation.R;
+import android.animation.cts.R;
 
 public class AnimationActivity extends Activity {
     private static final String BALL_HEIGHT = "ballwidth";
diff --git a/tests/tests/animation/src/android/animation/cts/AnimatorSetTest.java b/tests/tests/animation/src/android/animation/cts/AnimatorSetTest.java
index 0163a58..b57299f 100644
--- a/tests/tests/animation/src/android/animation/cts/AnimatorSetTest.java
+++ b/tests/tests/animation/src/android/animation/cts/AnimatorSetTest.java
@@ -15,9 +15,14 @@
  */
 package android.animation.cts;
 
+import java.lang.Override;
+import java.lang.Runnable;
+import java.lang.Thread;
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.Set;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
@@ -55,15 +60,81 @@
     }
 
      public void testPlaySequentially() throws Throwable {
+         xAnimator.setRepeatCount(0);
+         yAnimator.setRepeatCount(0);
+         xAnimator.setDuration(50);
+         yAnimator.setDuration(50);
          Animator[] animatorArray = {xAnimator, yAnimator};
-
          mAnimatorSet = new AnimatorSet();
          mAnimatorSet.playSequentially(animatorArray);
+         verifySequentialPlayOrder(mAnimatorSet, animatorArray);
 
-         assertFalse(mAnimatorSet.isRunning());
-         startAnimation(mAnimatorSet);
-         Thread.sleep(100);
-         assertTrue(mAnimatorSet.isRunning());
+         ValueAnimator anim1 = ValueAnimator.ofFloat(0f, 1f);
+         ValueAnimator anim2 = ValueAnimator.ofInt(0, 100);
+         anim1.setDuration(50);
+         anim2.setDuration(50);
+         AnimatorSet set = new AnimatorSet();
+         set.playSequentially(anim1, anim2);
+         verifySequentialPlayOrder(set, new Animator[] {anim1, anim2});
+    }
+
+    /**
+     * Start the animator, and verify the animators are played sequentially in the order that is
+     * defined in the array.
+     *
+     * @param set AnimatorSet to be started and verified
+     * @param animators animators that we put in the AnimatorSet, in the order that they'll play
+     */
+    private void verifySequentialPlayOrder(final AnimatorSet set, Animator[] animators)
+            throws Throwable {
+
+        final MyListener[] listeners = new MyListener[animators.length];
+        for (int i = 0; i < animators.length; i++) {
+            if (i == 0) {
+                listeners[i] = new MyListener();
+            } else {
+                final int current = i;
+                listeners[i] = new MyListener() {
+                    @Override
+                    public void onAnimationStart(Animator anim) {
+                        super.onAnimationStart(anim);
+                        // Check that the previous animator has finished.
+                        assertTrue(listeners[current - 1].mEndIsCalled);
+                    }
+                };
+            }
+            animators[i].addListener(listeners[i]);
+        }
+
+        final CountDownLatch startLatch = new CountDownLatch(1);
+        final CountDownLatch endLatch = new CountDownLatch(1);
+
+        set.addListener(new MyListener() {
+            @Override
+            public void onAnimationEnd(Animator anim) {
+                endLatch.countDown();
+            }
+        });
+
+        long totalDuration = set.getTotalDuration();
+        assertFalse(set.isRunning());
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                set.start();
+                startLatch.countDown();
+            }
+        });
+
+        // Set timeout to 100ms, if current count reaches 0 before the timeout, startLatch.await(...)
+        // will return immediately.
+        assertTrue(startLatch.await(100, TimeUnit.MILLISECONDS));
+        assertTrue(set.isRunning());
+        assertTrue(endLatch.await(totalDuration * 2, TimeUnit.MILLISECONDS));
+        // Check that all the animators have finished.
+        for (int i = 0; i < listeners.length; i++) {
+            assertTrue(listeners[i].mEndIsCalled);
+        }
     }
 
     public void testPlayTogether() throws Throwable {
@@ -74,10 +145,44 @@
         mAnimatorSet.playTogether(animatorArray);
 
         assertFalse(mAnimatorSet.isRunning());
+        assertFalse(xAnimator.isRunning());
+        assertFalse(yAnimator.isRunning());
         startAnimation(mAnimatorSet);
         Thread.sleep(100);
         assertTrue(mAnimatorSet.isRunning());
-   }
+        assertTrue(xAnimator.isRunning());
+        assertTrue(yAnimator.isRunning());
+
+        // Now assemble another animator set
+        ValueAnimator anim1 = ValueAnimator.ofFloat(0f, 100f);
+        ValueAnimator anim2 = ValueAnimator.ofFloat(10f, 100f);
+        AnimatorSet set = new AnimatorSet();
+        set.playTogether(anim1, anim2);
+
+        assertFalse(set.isRunning());
+        assertFalse(anim1.isRunning());
+        assertFalse(anim2.isRunning());
+        startAnimation(set);
+        Thread.sleep(100);
+        assertTrue(set.isRunning());
+        assertTrue(anim1.isRunning());
+        assertTrue(anim2.isRunning());
+    }
+
+    public void testPlayBeforeAfter() throws Throwable {
+        xAnimator.setRepeatCount(0);
+        yAnimator.setRepeatCount(0);
+        final ValueAnimator zAnimator = ValueAnimator.ofFloat(0f, 100f);
+
+        xAnimator.setDuration(50);
+        yAnimator.setDuration(50);
+        zAnimator.setDuration(50);
+
+        AnimatorSet set = new AnimatorSet();
+        set.play(yAnimator).before(zAnimator).after(xAnimator);
+
+        verifySequentialPlayOrder(set, new Animator[] {xAnimator, yAnimator, zAnimator});
+    }
 
     public void testDuration() throws Throwable {
         xAnimator.setRepeatCount(ValueAnimator.INFINITE);
@@ -243,4 +348,17 @@
         int x = 1;
         int y = 2;
     }
+
+    class MyListener extends AnimatorListenerAdapter {
+        boolean mStartIsCalled = false;
+        boolean mEndIsCalled = false;
+
+        public void onAnimationStart(Animator animation) {
+            mStartIsCalled = true;
+        }
+
+        public void onAnimationEnd(Animator animation) {
+            mEndIsCalled = true;
+        }
+    }
 }
diff --git a/tests/tests/animation/src/android/animation/cts/ArgbEvaluatorTest.java b/tests/tests/animation/src/android/animation/cts/ArgbEvaluatorTest.java
deleted file mode 100644
index 4fee87d..0000000
--- a/tests/tests/animation/src/android/animation/cts/ArgbEvaluatorTest.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.animation.cts;
-
-import android.animation.ArgbEvaluator;
-import android.graphics.Color;
-import android.test.InstrumentationTestCase;
-
-public class ArgbEvaluatorTest extends InstrumentationTestCase {
-    public void testEvaluate() throws Throwable {
-        final int RED =  0xffFF8080;
-        final int BLUE = 0xff8080FF;
-        int aRED = Color.alpha(RED);
-        int rRED = Color.red(RED);
-        int gRED = Color.green(RED);
-        int bRED = Color.blue(RED);
-        int aBLUE = Color.alpha(BLUE);
-        int rBLUE = Color.red(BLUE);
-        int gBLUE = Color.green(BLUE);
-        int bBLUE = Color.blue(BLUE);
-
-        final ArgbEvaluator evaluator = new ArgbEvaluator();
-        class AnimationRunnable implements Runnable{
-            int result;
-            public void run() {
-                result = (Integer) evaluator.evaluate(0.5f, RED, BLUE);
-            }
-        }
-        AnimationRunnable aRunnable = new AnimationRunnable();
-        this.runTestOnUiThread(aRunnable);
-        Thread.sleep(100);
-        int result = aRunnable.result;
-
-        int aResult = Color.alpha(result);
-        int rResult = Color.red(result);
-        int gResult = Color.green(result);
-        int bResult = Color.blue(result);
-        assertTrue(aResult >= aRED);
-        assertTrue(aResult <= aBLUE);
-        assertTrue(rResult <= rRED);
-        assertTrue(rResult >= rBLUE);
-        assertTrue(gResult >= gRED);
-        assertTrue(gResult <= gBLUE);
-        assertTrue(bResult >= bRED);
-        assertTrue(bResult <= bBLUE);
-    }
-}
-
diff --git a/tests/tests/animation/src/android/animation/cts/ButtonViewActivity.java b/tests/tests/animation/src/android/animation/cts/ButtonViewActivity.java
new file mode 100644
index 0000000..fe66951
--- /dev/null
+++ b/tests/tests/animation/src/android/animation/cts/ButtonViewActivity.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.animation.cts;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+import android.animation.cts.R;
+
+public class ButtonViewActivity extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.button_view);
+    }
+}
diff --git a/tests/tests/animation/src/android/animation/cts/CreationTest.java b/tests/tests/animation/src/android/animation/cts/CreationTest.java
new file mode 100644
index 0000000..f45f64b
--- /dev/null
+++ b/tests/tests/animation/src/android/animation/cts/CreationTest.java
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.animation.cts;
+
+import android.animation.AnimatorInflater;
+import android.animation.ObjectAnimator;
+import android.animation.PropertyValuesHolder;
+import android.animation.ValueAnimator;
+import android.os.Debug;
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.UiThreadTest;
+
+import android.animation.cts.R;
+
+public class CreationTest extends ActivityInstrumentationTestCase2<ButtonViewActivity> {
+
+    private ButtonViewActivity mActivity;
+
+    public CreationTest() {
+        super(ButtonViewActivity.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        setActivityInitialTouchMode(false);
+        mActivity = getActivity();
+    }
+
+    @UiThreadTest
+    public void testValueAnimatorCreation() {
+        ValueAnimator animator = ValueAnimator.ofFloat(0, 1);
+        verifyValues(animator, 0, 1);
+    }
+
+    @UiThreadTest
+    public void testValueAnimatorResourceCreation() {
+        ValueAnimator animator = (ValueAnimator)
+                AnimatorInflater.loadAnimator(mActivity, R.animator.value_animator);
+        verifyValues(animator, 0, 1);
+    }
+
+    @UiThreadTest
+    public void testValueAnimatorPvh1() {
+        ValueAnimator animator = (ValueAnimator)
+                AnimatorInflater.loadAnimator(mActivity, R.animator.value_animator_pvh1);
+        verifyValues(animator, 0, 1);
+    }
+
+    @UiThreadTest
+    public void testValueAnimatorPvh2() {
+        ValueAnimator animator = (ValueAnimator)
+                AnimatorInflater.loadAnimator(mActivity, R.animator.value_animator_pvh2);
+        verifyValues(animator, 0, 1);
+    }
+
+    @UiThreadTest
+    public void testValueAnimatorPvhKf1() {
+        ValueAnimator animator = (ValueAnimator)
+                AnimatorInflater.loadAnimator(mActivity, R.animator.value_animator_pvh_kf1);
+        verifyValues(animator, 0, 1);
+    }
+
+    @UiThreadTest
+    public void testValueAnimatorPvhKf2() {
+        ValueAnimator animator = (ValueAnimator)
+                AnimatorInflater.loadAnimator(mActivity, R.animator.value_animator_pvh_kf2);
+        verifyValues(animator, 0, 1);
+    }
+
+    @UiThreadTest
+    public void testValueAnimatorPvhKf3() {
+        ValueAnimator animator = (ValueAnimator)
+                AnimatorInflater.loadAnimator(mActivity, R.animator.value_animator_pvh_kf3);
+        verifyValues(animator, 0, .2f, 1);
+    }
+
+    @UiThreadTest
+    public void testValueAnimatorPvhKf4() {
+        ValueAnimator animator = (ValueAnimator)
+                AnimatorInflater.loadAnimator(mActivity, R.animator.value_animator_pvh_kf4);
+        verifyValues(animator, 0, .2f, 1);
+    }
+
+    @UiThreadTest
+    public void testObjectAnimator() {
+        ObjectAnimator animator = (ObjectAnimator)
+                AnimatorInflater.loadAnimator(mActivity, R.animator.object_animator);
+        animator.setTarget(new DummyAnimatorTarget());
+        verifyValues(animator, "x", 0, 1);
+    }
+
+    @UiThreadTest
+    public void testObjectAnimatorPvh1() {
+        ObjectAnimator animator = (ObjectAnimator)
+                AnimatorInflater.loadAnimator(mActivity, R.animator.object_animator_pvh1);
+        animator.setTarget(new DummyAnimatorTarget());
+        verifyValues(animator, "x", 0, 1);
+        verifyValues(animator, "y", 10, 11);
+    }
+
+    @UiThreadTest
+    public void testObjectAnimatorPvhKf1() {
+        ObjectAnimator animator = (ObjectAnimator)
+                AnimatorInflater.loadAnimator(mActivity, R.animator.object_animator_pvh_kf1);
+        animator.setTarget(new DummyAnimatorTarget());
+        verifyValues(animator, "x", 0, 1);
+        verifyValues(animator, "y", 10, 11);
+    }
+
+    class DummyAnimatorTarget {
+        public float getX() {
+            return 0;
+        }
+
+        public void setX(float x) {
+        }
+
+        public float getY() {
+            return 0;
+        }
+
+        public void setY(float y) {
+        }
+    }
+
+    private void assertRoughlyEqual(float checkValue, float correctValue) {
+        // use epsilon for float compares
+        final float epsilon = .0001f;
+        assertTrue(checkValue > correctValue - epsilon && checkValue < correctValue + epsilon);
+    }
+
+    private void verifyValues(ValueAnimator animator, float... values) {
+        animator.setCurrentFraction(0);
+        assertRoughlyEqual((Float) animator.getAnimatedValue(), values[0]);
+        for (int i = 1; i < values.length - 1; ++i) {
+            animator.setCurrentFraction((float) i / (values.length - 1));
+            assertRoughlyEqual((Float) animator.getAnimatedValue(), values[i]);
+        }
+        animator.setCurrentFraction(1);
+        assertRoughlyEqual((Float) animator.getAnimatedValue(), values[values.length - 1]);
+    }
+
+    private void verifyValues(ObjectAnimator animator, String propertyName, float... values) {
+        animator.setCurrentFraction(0);
+        assertRoughlyEqual((Float) animator.getAnimatedValue(propertyName), values[0]);
+        for (int i = 1; i < values.length - 1; ++i) {
+            animator.setCurrentFraction((float) i / (values.length - 1));
+            assertRoughlyEqual((Float) animator.getAnimatedValue(propertyName), values[i]);
+        }
+        animator.setCurrentFraction(1);
+        assertRoughlyEqual((Float) animator.getAnimatedValue(propertyName),
+                values[values.length - 1]);
+    }
+}
diff --git a/tests/tests/animation/src/android/animation/cts/EvaluatorTest.java b/tests/tests/animation/src/android/animation/cts/EvaluatorTest.java
new file mode 100644
index 0000000..0812351
--- /dev/null
+++ b/tests/tests/animation/src/android/animation/cts/EvaluatorTest.java
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.animation.cts;
+
+import android.animation.ArgbEvaluator;
+import android.animation.FloatArrayEvaluator;
+import android.animation.FloatEvaluator;
+import android.animation.IntArrayEvaluator;
+import android.animation.IntEvaluator;
+import android.animation.PointFEvaluator;
+import android.animation.RectEvaluator;
+import android.graphics.Color;
+import android.graphics.PointF;
+import android.graphics.Rect;
+import android.test.InstrumentationTestCase;
+
+/**
+ * Tests for the various Evaluator classes in android.animation
+ */
+public class EvaluatorTest extends InstrumentationTestCase {
+
+    public void testFloatEvaluator() {
+        float start = 0.0f;
+        float end = 1.0f;
+        float fraction = 0.5f;
+        FloatEvaluator floatEvaluator = new FloatEvaluator();
+
+        float result = floatEvaluator.evaluate(0, start, end);
+        assertEquals(start, result, .001f);
+
+        result = floatEvaluator.evaluate(fraction, start, end);
+        assertEquals(.5f, result, .001f);
+
+        result = floatEvaluator.evaluate(1, start, end);
+        assertEquals(end, result, .001f);
+    }
+
+    public void testFloatArrayEvaluator() {
+        float[] start = {0f, 0f};
+        float[] end = {.8f, 1.0f};
+        float fraction = 0.5f;
+        FloatArrayEvaluator evaluator = new FloatArrayEvaluator();
+
+        float[] result = evaluator.evaluate(0, start, end);
+        assertEquals(start[0], result[0], .001f);
+        assertEquals(start[1], result[1], .001f);
+
+        result = evaluator.evaluate(fraction, start, end);
+        assertEquals(.4f, result[0], .001f);
+        assertEquals(.5f, result[1], .001f);
+
+        result = evaluator.evaluate(1, start, end);
+        assertEquals(end[0], result[0], .001f);
+        assertEquals(end[1], result[1], .001f);
+    }
+
+    public void testArgbEvaluator() throws Throwable {
+        final int RED =  0xffFF8080;
+        final int BLUE = 0xff8080FF;
+        int aRED = Color.alpha(RED);
+        int rRED = Color.red(RED);
+        int gRED = Color.green(RED);
+        int bRED = Color.blue(RED);
+        int aBLUE = Color.alpha(BLUE);
+        int rBLUE = Color.red(BLUE);
+        int gBLUE = Color.green(BLUE);
+        int bBLUE = Color.blue(BLUE);
+
+        final ArgbEvaluator evaluator = new ArgbEvaluator();
+
+        int result = (Integer) evaluator.evaluate(0, RED, BLUE);
+        int aResult = Color.alpha(result);
+        int rResult = Color.red(result);
+        int gResult = Color.green(result);
+        int bResult = Color.blue(result);
+        assertEquals(aRED, aResult);
+        assertEquals(rRED, rResult);
+        assertEquals(gRED, gResult);
+        assertEquals(bRED, bResult);
+
+        result = (Integer) evaluator.evaluate(.5f, RED, BLUE);
+        aResult = Color.alpha(result);
+        rResult = Color.red(result);
+        gResult = Color.green(result);
+        bResult = Color.blue(result);
+        assertEquals(0xff, aResult);
+        assertEquals(rRED + (int)(.5f * (rBLUE - rRED)), rResult);
+        assertEquals(gRED + (int)(.5f * (gBLUE - gRED)), gResult);
+        assertEquals(bRED + (int)(.5f * (bBLUE - bRED)), bResult);
+
+        result = (Integer) evaluator.evaluate(1, RED, BLUE);
+        aResult = Color.alpha(result);
+        rResult = Color.red(result);
+        gResult = Color.green(result);
+        bResult = Color.blue(result);
+        assertEquals(aBLUE, aResult);
+        assertEquals(rBLUE, rResult);
+        assertEquals(gBLUE, gResult);
+        assertEquals(bBLUE, bResult);
+    }
+
+    public void testIntEvaluator() throws Throwable {
+        final int start = 0;
+        final int end = 100;
+        final float fraction = 0.5f;
+        final IntEvaluator intEvaluator = new IntEvaluator();
+
+        int result = intEvaluator.evaluate(0, start, end);
+        assertEquals(start, result);
+
+        result = intEvaluator.evaluate(fraction, start, end);
+        assertEquals(50, result);
+
+        result = intEvaluator.evaluate(1, start, end);
+        assertEquals(end, result);
+    }
+
+    public void testIntArrayEvaluator() {
+        int[] start = {0, 0};
+        int[] end = {80, 100};
+        float fraction = 0.5f;
+        IntArrayEvaluator evaluator = new IntArrayEvaluator();
+
+        int[] result = evaluator.evaluate(0, start, end);
+        assertEquals(start[0], result[0]);
+        assertEquals(start[1], result[1]);
+
+        result = evaluator.evaluate(fraction, start, end);
+        assertEquals(40, result[0]);
+        assertEquals(50, result[1]);
+
+        result = evaluator.evaluate(1, start, end);
+        assertEquals(end[0], result[0]);
+        assertEquals(end[1], result[1]);
+    }
+
+    public void testRectEvaluator() throws Throwable {
+        final RectEvaluator evaluator = new RectEvaluator();
+        final Rect start = new Rect(0, 0, 0, 0);
+        final Rect end = new Rect(100, 200, 300, 400);
+        final float fraction = 0.5f;
+
+        Rect result = evaluator.evaluate(0, start, end);
+        assertEquals(start.left, result.left, .001f);
+        assertEquals(start.top, result.top, .001f);
+        assertEquals(start.right, result.right, .001f);
+        assertEquals(start.bottom, result.bottom, 001f);
+
+        result = evaluator.evaluate(fraction, start, end);
+        assertEquals(50, result.left, .001f);
+        assertEquals(100, result.top, .001f);
+        assertEquals(150, result.right, .001f);
+        assertEquals(200, result.bottom, .001f);
+
+        result = evaluator.evaluate(1, start, end);
+        assertEquals(end.left, result.left, .001f);
+        assertEquals(end.top, result.top, .001f);
+        assertEquals(end.right, result.right, .001f);
+        assertEquals(end.bottom, result.bottom, .001f);
+    }
+
+    public void testPointFEvaluator() throws Throwable {
+        final PointFEvaluator evaluator = new PointFEvaluator();
+        final PointF start = new PointF(0, 0);
+        final PointF end = new PointF(100, 200);
+        final float fraction = 0.5f;
+
+        PointF result = evaluator.evaluate(0, start, end);
+        assertEquals(start.x, result.x, .001f);
+        assertEquals(start.y, result.y, .001f);
+
+        result = evaluator.evaluate(fraction, start, end);
+        assertEquals(50, result.x, .001f);
+        assertEquals(100, result.y, .001f);
+
+        result = evaluator.evaluate(1, start, end);
+        assertEquals(end.x, result.x, .001f);
+        assertEquals(end.y, result.y, .001f);
+    }
+
+    /**
+     * Utility method to compare float values. Exact equality is error-prone
+     * with floating point values, so we ensure that the actual value is at least
+     * within some epsilon of the expected value.
+     */
+    private void assertEquals(float expected, float actual) {
+        if (expected != actual) {
+            final float epsilon = .001f;
+            assertTrue(actual <= expected + epsilon);
+            assertTrue(actual >= expected - epsilon);
+        }
+    }
+}
+
diff --git a/tests/tests/animation/src/android/animation/cts/FloatEvaluatorTest.java b/tests/tests/animation/src/android/animation/cts/FloatEvaluatorTest.java
deleted file mode 100644
index ebc7f58..0000000
--- a/tests/tests/animation/src/android/animation/cts/FloatEvaluatorTest.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.animation.cts;
-
-import android.animation.FloatEvaluator;
-import android.test.InstrumentationTestCase;
-
-public class FloatEvaluatorTest extends InstrumentationTestCase {
-    public void testEvaluate() {
-        float start = 0.0f;
-        float end = 1.0f;
-        float fraction = 0.5f;
-        FloatEvaluator floatEvaluator = new FloatEvaluator();
-        float result = floatEvaluator.evaluate(fraction, start, end);
-        assertTrue(result >= (fraction*start));
-        assertTrue(result <= (fraction*end));
-    }
-}
-
diff --git a/tests/tests/animation/src/android/animation/cts/IntEvaluatorTest.java b/tests/tests/animation/src/android/animation/cts/IntEvaluatorTest.java
deleted file mode 100644
index 2b95993..0000000
--- a/tests/tests/animation/src/android/animation/cts/IntEvaluatorTest.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.animation.cts;
-
-import android.animation.IntEvaluator;
-import android.test.InstrumentationTestCase;
-
-public class IntEvaluatorTest extends InstrumentationTestCase {
-    public void testEvaluate() throws Throwable {
-        final int start = 0;
-        final int end = 100;
-        final float fraction = 0.5f;
-        final IntEvaluator intEvaluator = new IntEvaluator();
-        class AnimationRunnable implements Runnable{
-            int result;
-            public void run() {
-                result = intEvaluator.evaluate(fraction, start, end);
-            }
-        }
-        AnimationRunnable aRunnable = new AnimationRunnable();
-        this.runTestOnUiThread(aRunnable);
-        Thread.sleep(1);
-        int result = aRunnable.result;
-        assertTrue(result >= (fraction*start));
-        assertTrue(result <= (fraction*end));
-    }
-}
-
diff --git a/tests/tests/animation/src/android/animation/cts/LayoutAnimationActivity.java b/tests/tests/animation/src/android/animation/cts/LayoutAnimationActivity.java
index 9b2eaff..fb5426e 100644
--- a/tests/tests/animation/src/android/animation/cts/LayoutAnimationActivity.java
+++ b/tests/tests/animation/src/android/animation/cts/LayoutAnimationActivity.java
@@ -15,7 +15,7 @@
  */
 package android.animation.cts;
 
-import com.android.cts.animation.R;
+import android.animation.cts.R;
 import android.app.Activity;
 import android.os.Bundle;
 import android.view.View;
diff --git a/tests/tests/animation/src/android/animation/cts/LayoutAnimationTest.java b/tests/tests/animation/src/android/animation/cts/LayoutAnimationTest.java
index f9918a8..f39fe505 100644
--- a/tests/tests/animation/src/android/animation/cts/LayoutAnimationTest.java
+++ b/tests/tests/animation/src/android/animation/cts/LayoutAnimationTest.java
@@ -19,7 +19,7 @@
 import java.util.LinkedList;
 import java.util.List;
 
-import com.android.cts.animation.R;
+import android.animation.cts.R;
 
 import android.animation.Animator;
 import android.animation.LayoutTransition;
@@ -28,7 +28,6 @@
 import android.animation.PropertyValuesHolder;
 import android.animation.TimeInterpolator;
 import android.test.ActivityInstrumentationTestCase2;
-import android.test.TouchUtils;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.animation.AccelerateInterpolator;
@@ -41,6 +40,7 @@
     private MyLayoutTransition mLayoutTransition;
     private LinearLayout mView;
     private Button mButton;
+
     public LayoutAnimationTest() {
         super(LayoutAnimationActivity.class);
     }
@@ -65,14 +65,14 @@
         assertEquals(listener, actualListener);
     }
 
-    public void testIsRunning() {
+    public void testIsRunning() throws Throwable {
         setDefaultTransition();
         assertFalse(mLayoutTransition.isRunning());
-        TouchUtils.clickView(this, mButton);
+        clickButton();
         assertTrue(mLayoutTransition.isRunning());
     }
 
-    public void testIsChangingLayout() {
+    public void testIsChangingLayout() throws Throwable {
         long duration = 2000l;
         mView.setLayoutTransition(mLayoutTransition);
         mLayoutTransition.setDuration(duration);
@@ -80,7 +80,7 @@
                 new AccelerateInterpolator());
 
         assertFalse(mLayoutTransition.isChangingLayout());
-        TouchUtils.clickView(this, mButton);
+        clickButton();
         assertTrue(mLayoutTransition.isChangingLayout());
     }
 
@@ -138,7 +138,7 @@
         mLayoutTransition.setAnimator(LayoutTransition.APPEARING, appearingAnimator);
 
         List<Float> alphaList = new LinkedList<Float>();
-        TouchUtils.clickView(this, mButton);
+        clickButton();
         while(listener.mTransition) {
             float alpha = mActivity.getLastButton().getAlpha();
             alphaList.add(alpha);
@@ -177,6 +177,15 @@
                 new AccelerateInterpolator());
     }
 
+    private void clickButton() throws Throwable {
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                mButton.callOnClick();
+            }
+        });
+        getInstrumentation().waitForIdleSync();
+    }
+
     class MyTransitionListener implements LayoutTransition.TransitionListener {
         ViewGroup mContainer;
         View mView;
diff --git a/tests/tests/animation/src/android/animation/cts/ObjectAnimatorTest.java b/tests/tests/animation/src/android/animation/cts/ObjectAnimatorTest.java
index f0db168..6ff1cf9 100644
--- a/tests/tests/animation/src/android/animation/cts/ObjectAnimatorTest.java
+++ b/tests/tests/animation/src/android/animation/cts/ObjectAnimatorTest.java
@@ -21,6 +21,7 @@
 import android.animation.PropertyValuesHolder;
 import android.animation.ValueAnimator;
 import android.test.ActivityInstrumentationTestCase2;
+import android.util.Property;
 import android.view.animation.AccelerateInterpolator;
 import android.view.animation.Interpolator;
 
@@ -246,6 +247,106 @@
         Thread.sleep(100);
     }
 
+    public void testSetStartEndValues() throws Throwable {
+        final float startValue = 100, endValue = 500;
+        final AnimTarget target = new AnimTarget();
+        final ObjectAnimator anim1 = ObjectAnimator.ofFloat(target, "testValue", 0);
+        target.setTestValue(startValue);
+        anim1.setupStartValues();
+        target.setTestValue(endValue);
+        anim1.setupEndValues();
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                anim1.start();
+                assertEquals(startValue, (Float) anim1.getAnimatedValue());
+                anim1.setCurrentFraction(1);
+                assertEquals(endValue, (Float) anim1.getAnimatedValue());
+                anim1.cancel();
+            }
+        });
+
+        final Property property = AnimTarget.TEST_VALUE;
+        final ObjectAnimator anim2 = ObjectAnimator.ofFloat(target, AnimTarget.TEST_VALUE, 0);
+        target.setTestValue(startValue);
+        final float startValueExpected = (Float) property.get(target);
+        anim2.setupStartValues();
+        target.setTestValue(endValue);
+        final float endValueExpected = (Float) property.get(target);
+        anim2.setupEndValues();
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                anim2.start();
+                assertEquals(startValueExpected, (Float) anim2.getAnimatedValue());
+                anim2.setCurrentFraction(1);
+                assertEquals(endValueExpected, (Float) anim2.getAnimatedValue());
+                anim2.cancel();
+            }
+        });
+
+        // This is a test that ensures that the values set on a Property-based animator
+        // are determined by the property, not by the setter/getter of the target object
+        final Property doubler = AnimTarget.TEST_DOUBLING_VALUE;
+        final ObjectAnimator anim3 = ObjectAnimator.ofFloat(target,
+                doubler, 0);
+        target.setTestValue(startValue);
+        final float startValueExpected3 = (Float) doubler.get(target);
+        anim3.setupStartValues();
+        target.setTestValue(endValue);
+        final float endValueExpected3 = (Float) doubler.get(target);
+        anim3.setupEndValues();
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                anim3.start();
+                assertEquals(startValueExpected3, (Float) anim3.getAnimatedValue());
+                anim3.setCurrentFraction(1);
+                assertEquals(endValueExpected3, (Float) anim3.getAnimatedValue());
+                anim3.cancel();
+            }
+        });
+    }
+
+    static class AnimTarget {
+        private float mTestValue = 0;
+
+        public void setTestValue(float value) {
+            mTestValue = value;
+        }
+
+        public float getTestValue() {
+            return mTestValue;
+        }
+
+        public static final Property<AnimTarget, Float> TEST_VALUE =
+                new Property<AnimTarget, Float>(Float.class, "testValue") {
+                    @Override
+                    public void set(AnimTarget object, Float value) {
+                        object.setTestValue(value);
+                    }
+
+                    @Override
+                    public Float get(AnimTarget object) {
+                        return object.getTestValue();
+                    }
+                };
+        public static final Property<AnimTarget, Float> TEST_DOUBLING_VALUE =
+                new Property<AnimTarget, Float>(Float.class, "testValue") {
+                    @Override
+                    public void set(AnimTarget object, Float value) {
+                        object.setTestValue(value);
+                    }
+
+                    @Override
+                    public Float get(AnimTarget object) {
+                        // purposely different from getTestValue, to verify that properties
+                        // are independent of setters/getters
+                        return object.getTestValue() * 2;
+                    }
+                };
+    }
+
     private void startAnimation(final ObjectAnimator mObjectAnimator) throws Throwable {
         Thread mAnimationRunnable = new Thread() {
             public void run() {
diff --git a/tests/tests/animation/src/android/animation/cts/ValueAnimatorTest.java b/tests/tests/animation/src/android/animation/cts/ValueAnimatorTest.java
index 5451472..a005aa3 100644
--- a/tests/tests/animation/src/android/animation/cts/ValueAnimatorTest.java
+++ b/tests/tests/animation/src/android/animation/cts/ValueAnimatorTest.java
@@ -15,10 +15,15 @@
  */
 package android.animation.cts;
 
+import android.animation.Animator;
 import android.animation.ObjectAnimator;
 import android.animation.ValueAnimator;
 import android.test.ActivityInstrumentationTestCase2;
 import android.view.animation.AccelerateInterpolator;
+import android.view.animation.LinearInterpolator;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 
 public class ValueAnimatorTest extends
         ActivityInstrumentationTestCase2<AnimationActivity> {
@@ -82,20 +87,138 @@
         assertEquals(startDelay, mValueAnimator.getStartDelay());
     }
 
-    public void testCurrentPlayTime() throws Throwable {
+    public void testGetCurrentPlayTime() throws Throwable {
         startAnimation(mValueAnimator);
         Thread.sleep(100);
         long currentPlayTime = mValueAnimator.getCurrentPlayTime();
         assertTrue(currentPlayTime  >  0);
     }
 
+    /**
+     * Test for equality within some epsilon. This accounts for minor differences
+     * due to floating-point accuracy.
+     */
+    private void assertRoughlyEqual(float expected, float actual) {
+        final float epsilon = .001f;
+        assertTrue(actual > (expected - epsilon) && actual < (expected + epsilon));
+    }
+
+    public void testSetCurrentPlayTime() throws Throwable {
+        final ValueAnimator anim = ValueAnimator.ofFloat(0, 100).setDuration(mDuration);
+        final ValueAnimator delayedAnim = ValueAnimator.ofFloat(0, 100).setDuration(mDuration);
+        delayedAnim.setStartDelay(mDuration);
+        final long proposedCurrentPlayTime = mDuration / 2;
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                anim.setCurrentPlayTime(mDuration / 2);
+                long currentPlayTime = anim.getCurrentPlayTime();
+                float currentFraction = anim.getAnimatedFraction();
+                float currentValue = (Float) anim.getAnimatedValue();
+                assertEquals(proposedCurrentPlayTime, currentPlayTime);
+                assertRoughlyEqual(.5f, currentFraction);
+                assertRoughlyEqual(50, currentValue);
+
+                delayedAnim.setCurrentPlayTime(mDuration / 2);
+                currentPlayTime = delayedAnim.getCurrentPlayTime();
+                currentFraction = delayedAnim.getAnimatedFraction();
+                currentValue = (Float) delayedAnim.getAnimatedValue();
+                assertEquals(proposedCurrentPlayTime, currentPlayTime);
+                assertRoughlyEqual(.5f, currentFraction);
+                assertRoughlyEqual(50, currentValue);
+            }
+        });
+        // Now make sure that it's still true a little later, to test that we're
+        // getting a result based on the seek time, not the wall clock time
+        Thread.sleep(100);
+        long currentPlayTime = anim.getCurrentPlayTime();
+        float currentFraction = anim.getAnimatedFraction();
+        float currentValue = (Float) anim.getAnimatedValue();
+        assertEquals(proposedCurrentPlayTime, currentPlayTime);
+        assertRoughlyEqual(.5f, currentFraction);
+        assertRoughlyEqual(50, currentValue);
+
+        currentPlayTime = delayedAnim.getCurrentPlayTime();
+        currentFraction = delayedAnim.getAnimatedFraction();
+        currentValue = (Float) delayedAnim.getAnimatedValue();
+        assertEquals(proposedCurrentPlayTime, currentPlayTime);
+        assertRoughlyEqual(.5f, currentFraction);
+        assertRoughlyEqual(50, currentValue);
+
+        // Finally, start() the delayed animation and check that the play time was
+        // not affected by playing during the delay
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                delayedAnim.start();
+                long currentPlayTime = delayedAnim.getCurrentPlayTime();
+                float currentFraction = delayedAnim.getAnimatedFraction();
+                float currentValue = (Float) delayedAnim.getAnimatedValue();
+                assertEquals(proposedCurrentPlayTime, currentPlayTime);
+                assertRoughlyEqual(.5f, currentFraction);
+                assertRoughlyEqual(50, currentValue);
+            }
+        });
+
+        Thread.sleep(100);
+        currentPlayTime = delayedAnim.getCurrentPlayTime();
+        currentFraction = delayedAnim.getAnimatedFraction();
+        currentValue = (Float) delayedAnim.getAnimatedValue();
+        assertEquals(proposedCurrentPlayTime, currentPlayTime);
+        assertRoughlyEqual(.5f, currentFraction);
+        assertRoughlyEqual(50, currentValue);
+
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                delayedAnim.cancel();
+            }
+        });
+    }
+
+    public void testSetCurrentFraction() throws Throwable {
+        final ValueAnimator anim = ValueAnimator.ofFloat(0, 100).setDuration(mDuration);
+        final long proposedCurrentPlayTime = mDuration / 2;
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                anim.setCurrentFraction(.5f);
+                long currentPlayTime = anim.getCurrentPlayTime();
+                float currentFraction = anim.getAnimatedFraction();
+                float currentValue = (Float) anim.getAnimatedValue();
+                assertEquals(proposedCurrentPlayTime, currentPlayTime);
+                assertRoughlyEqual(.5f, currentFraction);
+                assertRoughlyEqual(50, currentValue);
+            }
+        });
+        // Now make sure that it's still true a little later, to test that we're
+        // getting a result based on the seek time, not the wall clock time
+        Thread.sleep(100);
+        long currentPlayTime = anim.getCurrentPlayTime();
+        float currentFraction = anim.getAnimatedFraction();
+        float currentValue = (Float) anim.getAnimatedValue();
+        assertEquals(proposedCurrentPlayTime, currentPlayTime);
+        assertRoughlyEqual(.5f, currentFraction);
+        assertRoughlyEqual(50, currentValue);
+    }
+
     public void testGetFrameDelay() throws Throwable {
-        long frameDelay = 10;
-        mValueAnimator.setFrameDelay(frameDelay);
+        final long frameDelay = 10;
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mValueAnimator.setFrameDelay(frameDelay);
+            }
+        });
         startAnimation(mValueAnimator);
         Thread.sleep(100);
-        long actualFrameDelay = mValueAnimator.getFrameDelay();
-        assertEquals(frameDelay, actualFrameDelay);
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                long actualFrameDelay = mValueAnimator.getFrameDelay();
+                assertEquals(frameDelay, actualFrameDelay);
+            }
+        });
     }
 
     public void testSetInterpolator() throws Throwable {
@@ -212,6 +335,31 @@
         assertTrue(animatedValue <= end);
     }
 
+    public void testNoDelayOnSeekAnimation() throws Throwable {
+        ValueAnimator animator = ValueAnimator.ofFloat(0, 1);
+        animator.setInterpolator(new LinearInterpolator());
+        animator.setStartDelay(1000);
+        animator.setDuration(300);
+        animator.setCurrentPlayTime(150);
+        EventWatcher watcher = new EventWatcher();
+        animator.addListener(watcher);
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                animator.start();
+            }
+        });
+        assertTrue(watcher.start.await(0, TimeUnit.MILLISECONDS));
+        assertTrue(((Float)animator.getAnimatedValue()) >= 0.5f);
+        assertTrue(animator.getAnimatedFraction() >= 0.5f);
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                animator.cancel();
+            }
+        });
+    }
+
     private ValueAnimator getAnimator() {
         Object object = mActivity.view.newBall;
         String property = "y";
@@ -274,4 +422,27 @@
         }
         return message.toString();
     }
+
+    class EventWatcher implements Animator.AnimatorListener {
+        public CountDownLatch start = new CountDownLatch(1);
+        public CountDownLatch end = new CountDownLatch(1);
+        public CountDownLatch cancel = new CountDownLatch(1);
+        public CountDownLatch repeat = new CountDownLatch(1);
+
+        public void onAnimationCancel(Animator animation) {
+            cancel.countDown();
+        }
+
+        public void onAnimationEnd(Animator animation) {
+            end.countDown();
+        }
+
+        public void onAnimationRepeat(Animator animation) {
+            repeat.countDown();
+        }
+
+        public void onAnimationStart(Animator animation) {
+            start.countDown();
+        }
+    }
 }
diff --git a/tests/tests/app.usage/Android.mk b/tests/tests/app.usage/Android.mk
index f245e5f..4cc3606 100644
--- a/tests/tests/app.usage/Android.mk
+++ b/tests/tests/app.usage/Android.mk
@@ -30,4 +30,7 @@
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/app.usage/AndroidManifest.xml b/tests/tests/app.usage/AndroidManifest.xml
index 7869223..462736a 100644
--- a/tests/tests/app.usage/AndroidManifest.xml
+++ b/tests/tests/app.usage/AndroidManifest.xml
@@ -34,6 +34,7 @@
         <activity android:name=".Activities$ActivityThree" />
         <activity android:name=".Activities$ActivityFour" />
         <activity android:name=".ActivityTransitionActivity" />
+        <activity android:name=".FragmentTestActivity" />
     </application>
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
diff --git a/tests/tests/app.usage/AndroidTest.xml b/tests/tests/app.usage/AndroidTest.xml
new file mode 100644
index 0000000..d4967f9
--- /dev/null
+++ b/tests/tests/app.usage/AndroidTest.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Configuration for app.usage Tests">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsUsageStatsTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.app.usage.cts" />
+        <option name="runtime-hint" value="1m47s" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/tests/app.usage/res/animator/long_fade_in.xml b/tests/tests/app.usage/res/animator/long_fade_in.xml
new file mode 100644
index 0000000..36e1714
--- /dev/null
+++ b/tests/tests/app.usage/res/animator/long_fade_in.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>

+

+<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"

+                android:valueFrom="0.0" android:valueTo="1.0"

+                android:propertyName="alpha"

+                android:duration="5000"/>

diff --git a/tests/tests/app.usage/res/animator/long_fade_out.xml b/tests/tests/app.usage/res/animator/long_fade_out.xml
new file mode 100644
index 0000000..f383a24
--- /dev/null
+++ b/tests/tests/app.usage/res/animator/long_fade_out.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>

+

+<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"

+                android:valueFrom="1.0" android:valueTo="0.0"

+                android:propertyName="alpha"

+                android:duration="5000"/>

diff --git a/tests/tests/app.usage/res/layout/fragment_a.xml b/tests/tests/app.usage/res/layout/fragment_a.xml
new file mode 100644
index 0000000..38e0423
--- /dev/null
+++ b/tests/tests/app.usage/res/layout/fragment_a.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent"
+              android:orientation="vertical">
+    <TextView android:layout_width="wrap_content"
+              android:layout_height="wrap_content"
+              android:id="@+id/textA"
+              android:text="@string/hello"/>
+</LinearLayout>
diff --git a/tests/tests/app.usage/res/layout/fragment_b.xml b/tests/tests/app.usage/res/layout/fragment_b.xml
new file mode 100644
index 0000000..d8ed961
--- /dev/null
+++ b/tests/tests/app.usage/res/layout/fragment_b.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent"
+              android:orientation="vertical">
+    <TextView android:layout_width="wrap_content"
+              android:layout_height="wrap_content"
+              android:id="@+id/textB"
+              android:text="@string/hello"/>
+</LinearLayout>
diff --git a/tests/tests/app.usage/res/layout/fragment_container.xml b/tests/tests/app.usage/res/layout/fragment_container.xml
new file mode 100644
index 0000000..c96ab4c
--- /dev/null
+++ b/tests/tests/app.usage/res/layout/fragment_container.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+             android:id="@+id/container"
+             android:layout_width="match_parent"
+             android:layout_height="match_parent"/>
diff --git a/tests/tests/app.usage/src/android/app/usage/cts/ActivityTransitionActivity.java b/tests/tests/app.usage/src/android/app/usage/cts/ActivityTransitionActivity.java
index 10ac4ea..0e413c9 100644
--- a/tests/tests/app.usage/src/android/app/usage/cts/ActivityTransitionActivity.java
+++ b/tests/tests/app.usage/src/android/app/usage/cts/ActivityTransitionActivity.java
@@ -18,7 +18,6 @@
 
 import android.app.Activity;
 import android.app.SharedElementCallback;
-import android.app.usage.cts.R;
 import android.content.Intent;
 import android.os.Bundle;
 import android.os.ResultReceiver;
@@ -28,9 +27,11 @@
 import android.transition.Fade;
 import android.transition.Transition;
 import android.transition.Transition.TransitionListener;
+import android.transition.Transition.TransitionListenerAdapter;
 import android.view.View;
 
 import java.util.List;
+import java.util.concurrent.CountDownLatch;
 
 /**
  * A simple activity containing the start state for an Activity Transition
@@ -41,6 +42,10 @@
     public static final String LAYOUT_ID = "layoutId";
     public static final String TEST = "test";
     public static final String RESULT_RECEIVER = "resultReceiver";
+    public static final String PAUSE_ON_RESTART = "pauseOnRestart";
+    public static final String QUICK_FINISH = "quickFinish";
+    public static final String ALLOW_OVERLAP = "allowOverlap";
+    public static final String NO_RETURN_TRANSITION = "noReturnTransition";
 
     public static final int NO_TEST = 0;
     public static final int TEST_ARRIVE = 1;
@@ -53,6 +58,9 @@
     public static final String ARRIVE_RETURN_TIME_READY = "arriveReturnTimeReady";
     public static final String ARRIVE_RETURN_TIME = "arriveReturnTime";
 
+    public static final String ENTER_VISIBILITY = "enterVisibility";
+    public static final String RETURN_VISIBILITY = "returnVisibility";
+
     private int mLayoutId;
     private int mTest;
     private ResultReceiver mResultReceiver;
@@ -61,20 +69,29 @@
 
     public int resultCode = 0;
     public Bundle result = new Bundle();
+    public final OptionalVisibility exitVisibility = new OptionalVisibility();
+    public final OptionalVisibility reenterVisibility = new OptionalVisibility();
+
+    public boolean mPauseOnRestart;
+    public boolean mQuickFinish;
+    public boolean mAllowOverlap;
+    public boolean mNoReturnTransition;
+
+    public CountDownLatch returnLatch = new CountDownLatch(1);
+    public CountDownLatch reenterLatch = new CountDownLatch(1);
 
     @Override
     public void onCreate(Bundle icicle) {
         super.onCreate(icicle);
-        getWindow().setSharedElementEnterTransition(new ChangeBounds().setDuration(DURATION));
-        getWindow().setSharedElementReturnTransition(new ChangeBounds().setDuration(DURATION));
-        getWindow().setEnterTransition(new Explode().setDuration(DURATION));
-        getWindow().setReturnTransition(new Explode().setDuration(DURATION));
-        getWindow().setExitTransition(new Fade().setDuration(DURATION));
         mLayoutId = 0;
         if (icicle != null) {
             mLayoutId =  icicle.getInt(LAYOUT_ID);
             mTest = icicle.getInt(TEST);
             mResultReceiver = icicle.getParcelable(RESULT_RECEIVER);
+            mPauseOnRestart = icicle.getBoolean(PAUSE_ON_RESTART);
+            mQuickFinish = icicle.getBoolean(QUICK_FINISH);
+            mAllowOverlap = icicle.getBoolean(ALLOW_OVERLAP, true);
+            mNoReturnTransition = icicle.getBoolean(NO_RETURN_TRANSITION);
         }
 
         if (mLayoutId == 0) {
@@ -82,18 +99,55 @@
             mLayoutId = intent.getIntExtra(LAYOUT_ID, R.layout.start);
             mTest = intent.getIntExtra(TEST, 0);
             mResultReceiver = intent.getParcelableExtra(RESULT_RECEIVER);
+            mPauseOnRestart = intent.getBooleanExtra(PAUSE_ON_RESTART, false);
+            mQuickFinish = intent.getBooleanExtra(QUICK_FINISH, false);
+            mAllowOverlap = intent.getBooleanExtra(ALLOW_OVERLAP, true);
+            mNoReturnTransition = intent.getBooleanExtra(NO_RETURN_TRANSITION, false);
         }
 
+        getWindow().setSharedElementEnterTransition(new ChangeBounds().setDuration(DURATION));
+        getWindow().setSharedElementReturnTransition(new ChangeBounds().setDuration(DURATION));
+        getWindow().setEnterTransition(createVisibilityTransition(true, ENTER_VISIBILITY));
+        getWindow().setReturnTransition(createVisibilityTransition(true, RETURN_VISIBILITY));
+        getWindow().setExitTransition(createVisibilityTransition(false, exitVisibility));
+        getWindow().setReenterTransition(createVisibilityTransition(false, reenterVisibility));
+        getWindow().getReenterTransition().addListener(new TransitionListenerAdapter() {
+            @Override
+            public void onTransitionEnd(Transition transition) {
+                reenterLatch.countDown();
+            }
+        });
+
         setContentView(mLayoutId);
+        getWindow().setAllowReturnTransitionOverlap(mAllowOverlap);
+        if (mNoReturnTransition) {
+            getWindow().setReturnTransition(null);
+            getWindow().setSharedElementReturnTransition(null);
+        }
 
         startTest();
     }
 
+    private Transition createVisibilityTransition(boolean isExplode, OptionalVisibility visibility) {
+        final Transition transition = isExplode ? new Explode() : new Fade();
+        transition.setDuration(DURATION);
+        transition.addListener(new VisibilityCheck(R.id.redSquare, visibility));
+        return transition;
+    }
+
+    private Transition createVisibilityTransition(boolean isExplode, String propertyName) {
+        final Transition transition = isExplode ? new Explode() : new Fade();
+        transition.setDuration(DURATION);
+        transition.addListener(new VisibilityCheck(R.id.redSquare, propertyName));
+        return transition;
+    }
+
     @Override
     protected void onSaveInstanceState(Bundle outState) {
         outState.putInt(LAYOUT_ID, mLayoutId);
         outState.putInt(TEST, mTest);
         outState.putParcelable(RESULT_RECEIVER, mResultReceiver);
+        outState.putBoolean(PAUSE_ON_RESTART, mPauseOnRestart);
     }
 
     private void startTest() {
@@ -129,44 +183,107 @@
                     }, SHARED_ELEMENT_READY_DELAY);
                 }
             });
-            getWindow().getEnterTransition().addListener(new TransitionListener() {
-                @Override
-                public void onTransitionStart(Transition transition) {
-                }
-
-                @Override
-                public void onTransitionEnd(Transition transition) {
-                    mEntering = false;
-                    setResult(RESULT_OK);
-                    getWindow().getDecorView().post(new Runnable() {
-                        @Override
-                        public void run() {
-                            finishAfterTransition();
-                        }
-                    });
-                }
-
-                @Override
-                public void onTransitionCancel(Transition transition) {
-                }
-
-                @Override
-                public void onTransitionPause(Transition transition) {
-                }
-
-                @Override
-                public void onTransitionResume(Transition transition) {
-                }
-            });
         }
+        getWindow().getEnterTransition().addListener(new TransitionListener() {
+            @Override
+            public void onTransitionStart(Transition transition) {
+            }
+
+            @Override
+            public void onTransitionEnd(Transition transition) {
+                mEntering = false;
+                setResult(RESULT_OK);
+                getWindow().getDecorView().post(new Runnable() {
+                    @Override
+                    public void run() {
+                        finishAfterTransition();
+                        if (mQuickFinish) {
+                            finish();
+                        }
+                    }
+                });
+            }
+
+            @Override
+            public void onTransitionCancel(Transition transition) {
+            }
+
+            @Override
+            public void onTransitionPause(Transition transition) {
+            }
+
+            @Override
+            public void onTransitionResume(Transition transition) {
+            }
+        });
     }
 
     @Override
     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
-        synchronized (this) {
-            super.onActivityResult(requestCode, resultCode, data);
-            this.resultCode = resultCode;
-            this.notifyAll();
+        super.onActivityResult(requestCode, resultCode, data);
+        this.resultCode = resultCode;
+        returnLatch.countDown();
+    }
+
+    @Override
+    protected void onRestart() {
+        super.onRestart();
+        if (mPauseOnRestart) {
+            postponeEnterTransition();
+            getWindow().getDecorView().postDelayed(new Runnable() {
+                @Override
+                public void run() {
+                    startPostponedEnterTransition();
+                }
+            }, 500);
+        }
+    }
+
+    private class VisibilityCheck extends TransitionListenerAdapter {
+        private final int mViewId;
+        private final OptionalVisibility mVisibility;
+        private final String mPropertyName;
+
+        public VisibilityCheck(int viewId, OptionalVisibility visibility) {
+            mViewId = viewId;
+            mVisibility = visibility;
+            mPropertyName = null;
+        }
+
+        public VisibilityCheck(int viewId, String propertyName) {
+            mViewId = viewId;
+            mVisibility = null;
+            mPropertyName = propertyName;
+        }
+
+        @Override
+        public void onTransitionEnd(Transition transition) {
+            final View view = findViewById(mViewId);
+            if (mPropertyName != null) {
+                if (mResultReceiver != null) {
+                    Bundle data = new Bundle();
+                    data.putInt(mPropertyName, view.getVisibility());
+                    mResultReceiver.send(RESULT_OK, data);
+                }
+            } else {
+                mVisibility.set(view.getVisibility());
+            }
+        }
+    }
+
+    public static class OptionalVisibility {
+        private int mVisibility = -1;
+
+        public void set(int visibility) {
+            mVisibility = visibility;
+        }
+
+        public int get() {
+            return mVisibility;
+        }
+
+        public boolean isSet() {
+            return mVisibility != -1;
         }
     }
 }
diff --git a/tests/tests/app.usage/src/android/app/usage/cts/ActivityTransitionTest.java b/tests/tests/app.usage/src/android/app/usage/cts/ActivityTransitionTest.java
index ef126fe..25d885a 100644
--- a/tests/tests/app.usage/src/android/app/usage/cts/ActivityTransitionTest.java
+++ b/tests/tests/app.usage/src/android/app/usage/cts/ActivityTransitionTest.java
@@ -17,16 +17,19 @@
 
 import android.app.ActivityOptions;
 import android.app.SharedElementCallback;
-import android.app.usage.cts.R;
 import android.content.Intent;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.ResultReceiver;
 import android.os.SystemClock;
 import android.test.ActivityInstrumentationTestCase2;
+import android.transition.Transition;
+import android.transition.Transition.TransitionListener;
 import android.view.View;
 
 import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 
 public class ActivityTransitionTest extends
         ActivityInstrumentationTestCase2<ActivityTransitionActivity> {
@@ -94,16 +97,9 @@
             }
         });
 
-        long endTime = SystemClock.uptimeMillis() + 1500;
-        synchronized (mActivity) {
-            while (mActivity.resultCode == 0) {
-                long waitTime = endTime - SystemClock.uptimeMillis();
-                if (waitTime <= 0) {
-                    fail("Activity didn't finish!");
-                }
-                mActivity.wait(waitTime);
-            }
-        }
+        assertTrue("Activity didn't finish!",
+                mActivity.returnLatch.await(1500, TimeUnit.MILLISECONDS));
+        assertTrue(mActivity.reenterLatch.await(300, TimeUnit.MILLISECONDS));
         assertNotNull(mReceiver.resultData);
         assertEquals(2, mReceiver.resultData.getInt(
                 ActivityTransitionActivity.ARRIVE_COUNT, -1));
@@ -128,11 +124,193 @@
         assertTrue(returnTime < returnTimeReady);
         assertTrue(returnTimeReady <= mReenterTime);
         assertTrue(mReenterTime < mReenterTimeReady);
+        checkNormalTransitionVisibility();
+    }
+
+    public void testFinishPostponed() throws Throwable {
+        getInstrumentation().waitForIdleSync();
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mReceiver = new PassInfo(new Handler());
+                mActivity.mPauseOnRestart = true;
+                Bundle options = ActivityOptions.makeSceneTransitionAnimation(mActivity,
+                        mActivity.findViewById(R.id.hello), "target").toBundle();
+                Intent intent = new Intent(mActivity, ActivityTransitionActivity.class);
+                intent.putExtra(ActivityTransitionActivity.LAYOUT_ID, R.layout.end);
+                intent.putExtra(ActivityTransitionActivity.QUICK_FINISH, true);
+                intent.putExtra(ActivityTransitionActivity.RESULT_RECEIVER, mReceiver);
+                mActivity.startActivityForResult(intent, 0, options);
+            }
+        });
+        CountDownLatch latch = setReenterLatch();
+
+        assertTrue("Activity didn't finish!",
+                mActivity.returnLatch.await(2000, TimeUnit.MILLISECONDS));
+        assertTrue("Reenter transition didn't finish", latch.await(1000, TimeUnit.MILLISECONDS));
+        assertTrue(mActivity.reenterLatch.await(300, TimeUnit.MILLISECONDS));
+        getInstrumentation().waitForIdleSync();
+        checkNoReturnTransitionVisibility();
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                final View greenSquare = mActivity.findViewById(R.id.greenSquare);
+                final View hello = mActivity.findViewById(R.id.hello);
+                assertEquals(View.VISIBLE, greenSquare.getVisibility());
+                assertEquals(View.VISIBLE, hello.getVisibility());
+            }
+        });
+    }
+
+    public void testFinishNoOverlap() throws Throwable {
+        getInstrumentation().waitForIdleSync();
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mReceiver = new PassInfo(new Handler());
+                Bundle options = ActivityOptions.makeSceneTransitionAnimation(mActivity,
+                        mActivity.findViewById(R.id.hello), "target").toBundle();
+                Intent intent = new Intent(mActivity, ActivityTransitionActivity.class);
+                intent.putExtra(ActivityTransitionActivity.LAYOUT_ID, R.layout.end);
+                intent.putExtra(ActivityTransitionActivity.QUICK_FINISH, true);
+                intent.putExtra(ActivityTransitionActivity.ALLOW_OVERLAP, false);
+                intent.putExtra(ActivityTransitionActivity.RESULT_RECEIVER, mReceiver);
+                mActivity.startActivityForResult(intent, 0, options);
+            }
+        });
+
+        assertTrue("Activity didn't finish!",
+                mActivity.returnLatch.await(1500, TimeUnit.MILLISECONDS));
+        assertTrue(mActivity.reenterLatch.await(300, TimeUnit.MILLISECONDS));
+        getInstrumentation().waitForIdleSync();
+        checkNoReturnTransitionVisibility();
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                final View greenSquare = mActivity.findViewById(R.id.greenSquare);
+                final View hello = mActivity.findViewById(R.id.hello);
+                assertEquals(View.VISIBLE, greenSquare.getVisibility());
+                assertEquals(View.VISIBLE, hello.getVisibility());
+            }
+        });
+    }
+
+    public void testFinishWithOverlap() throws Throwable {
+        getInstrumentation().waitForIdleSync();
+        CountDownLatch latch = setReenterLatch();
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mReceiver = new PassInfo(new Handler());
+                Bundle options = ActivityOptions.makeSceneTransitionAnimation(mActivity,
+                        mActivity.findViewById(R.id.hello), "target").toBundle();
+                Intent intent = new Intent(mActivity, ActivityTransitionActivity.class);
+                intent.putExtra(ActivityTransitionActivity.LAYOUT_ID, R.layout.end);
+                intent.putExtra(ActivityTransitionActivity.QUICK_FINISH, true);
+                intent.putExtra(ActivityTransitionActivity.ALLOW_OVERLAP, true);
+                intent.putExtra(ActivityTransitionActivity.RESULT_RECEIVER, mReceiver);
+                mActivity.startActivityForResult(intent, 0, options);
+            }
+        });
+
+        assertTrue("Activity didn't finish!",
+                mActivity.returnLatch.await(1500, TimeUnit.MILLISECONDS));
+        assertTrue("Reenter transition didn't finish", latch.await(1000, TimeUnit.MILLISECONDS));
+        assertTrue(mActivity.reenterLatch.await(300, TimeUnit.MILLISECONDS));
+        getInstrumentation().waitForIdleSync();
+        checkNoReturnTransitionVisibility();
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                final View greenSquare = mActivity.findViewById(R.id.greenSquare);
+                final View hello = mActivity.findViewById(R.id.hello);
+                assertEquals(View.VISIBLE, greenSquare.getVisibility());
+                assertEquals(View.VISIBLE, hello.getVisibility());
+            }
+        });
+    }
+
+    public void testFinishNoReturnTransition() throws Throwable {
+        getInstrumentation().waitForIdleSync();
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mReceiver = new PassInfo(new Handler());
+                Bundle options = ActivityOptions.makeSceneTransitionAnimation(mActivity,
+                        mActivity.findViewById(R.id.hello), "target").toBundle();
+                Intent intent = new Intent(mActivity, ActivityTransitionActivity.class);
+                intent.putExtra(ActivityTransitionActivity.LAYOUT_ID, R.layout.end);
+                intent.putExtra(ActivityTransitionActivity.QUICK_FINISH, true);
+                intent.putExtra(ActivityTransitionActivity.ALLOW_OVERLAP, true);
+                intent.putExtra(ActivityTransitionActivity.NO_RETURN_TRANSITION, true);
+                intent.putExtra(ActivityTransitionActivity.RESULT_RECEIVER, mReceiver);
+                mActivity.startActivityForResult(intent, 0, options);
+            }
+        });
+
+        assertTrue("Activity didn't finish!",
+                mActivity.returnLatch.await(1500, TimeUnit.MILLISECONDS));
+        assertTrue(mActivity.reenterLatch.await(300, TimeUnit.MILLISECONDS));
+        getInstrumentation().waitForIdleSync();
+        checkNoReturnTransitionVisibility();
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                final View greenSquare = mActivity.findViewById(R.id.greenSquare);
+                final View hello = mActivity.findViewById(R.id.hello);
+                assertEquals(View.VISIBLE, greenSquare.getVisibility());
+                assertEquals(View.VISIBLE, hello.getVisibility());
+            }
+        });
+    }
+
+    private void checkNormalTransitionVisibility() {
+        checkNoReturnTransitionVisibility();
+        assertEquals(View.INVISIBLE,
+                mReceiver.resultData.getInt(ActivityTransitionActivity.RETURN_VISIBILITY, -1));
+    }
+
+    private void checkNoReturnTransitionVisibility() {
+        assertTrue(mActivity.exitVisibility.isSet());
+        assertTrue(mActivity.reenterVisibility.isSet());
+
+        assertEquals(View.VISIBLE,
+                mReceiver.resultData.getInt(ActivityTransitionActivity.ENTER_VISIBILITY, -1));
+        assertEquals(View.INVISIBLE, mActivity.exitVisibility.get());
+        assertEquals(View.VISIBLE, mActivity.reenterVisibility.get());
+    }
+
+    private CountDownLatch setReenterLatch() {
+        final CountDownLatch latch = new CountDownLatch(1);
+        TransitionListener listener = new TransitionListener() {
+            @Override
+            public void onTransitionStart(Transition transition) {
+            }
+
+            @Override
+            public void onTransitionEnd(Transition transition) {
+                latch.countDown();
+            }
+
+            @Override
+            public void onTransitionCancel(Transition transition) {
+            }
+
+            @Override
+            public void onTransitionPause(Transition transition) {
+            }
+
+            @Override
+            public void onTransitionResume(Transition transition) {
+            }
+        };
+        mActivity.getWindow().getReenterTransition().addListener(listener);
+        return latch;
     }
 
     public static class PassInfo extends ResultReceiver {
         public int resultCode;
-        public Bundle resultData;
+        public Bundle resultData = new Bundle();
 
         public PassInfo(Handler handler) {
             super(handler);
@@ -141,7 +319,9 @@
         @Override
         protected void onReceiveResult(int resultCode, Bundle resultData) {
             this.resultCode = resultCode;
-            this.resultData = resultData;
+            if (resultData != null) {
+                this.resultData.putAll(resultData);
+            }
         }
     }
 }
diff --git a/tests/tests/app.usage/src/android/app/usage/cts/FragmentTest.java b/tests/tests/app.usage/src/android/app/usage/cts/FragmentTest.java
new file mode 100644
index 0000000..904aaf4
--- /dev/null
+++ b/tests/tests/app.usage/src/android/app/usage/cts/FragmentTest.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.usage.cts;
+
+import android.annotation.TargetApi;
+import android.app.Fragment;
+import android.app.usage.cts.R;
+import android.os.Build.VERSION_CODES;
+import android.os.Bundle;
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.UiThreadTest;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class FragmentTest extends ActivityInstrumentationTestCase2<FragmentTestActivity> {
+    protected FragmentTestActivity mActivity;
+
+    public FragmentTest() {
+        super(FragmentTestActivity.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        setActivityInitialTouchMode(false);
+        mActivity = getActivity();
+    }
+
+    @UiThreadTest
+    public void testOnCreateOrder() throws Throwable {
+        TestFragment fragment1 = new TestFragment();
+        TestFragment fragment2 = new TestFragment();
+        mActivity.getFragmentManager()
+                .beginTransaction()
+                .add(R.id.container, fragment1)
+                .add(R.id.container, fragment2)
+                .commitNow();
+        assertEquals(0, fragment1.createOrder);
+        assertEquals(1, fragment2.createOrder);
+    }
+
+    public void testChildFragmentManagerGone() throws Throwable {
+        final FragmentA fragmentA = new FragmentA();
+        final FragmentB fragmentB = new FragmentB();
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mActivity.getFragmentManager().beginTransaction()
+                        .add(R.id.container, fragmentA)
+                        .commitNow();
+            }
+        });
+        getInstrumentation().waitForIdleSync();
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mActivity.getFragmentManager().beginTransaction()
+                        .setCustomAnimations(R.animator.long_fade_in, R.animator.long_fade_out,
+                                R.animator.long_fade_in, R.animator.long_fade_out)
+                        .replace(R.id.container, fragmentB)
+                        .addToBackStack(null)
+                        .commit();
+            }
+        });
+        // Wait for the middle of the animation
+        Thread.sleep(150);
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mActivity.getFragmentManager().beginTransaction()
+                        .setCustomAnimations(R.animator.long_fade_in, R.animator.long_fade_out,
+                                R.animator.long_fade_in, R.animator.long_fade_out)
+                        .replace(R.id.container, fragmentA)
+                        .addToBackStack(null)
+                        .commit();
+            }
+        });
+        // Wait for the middle of the animation
+        Thread.sleep(150);
+        getInstrumentation().waitForIdleSync();
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mActivity.getFragmentManager().popBackStack();
+            }
+        });
+        // Wait for the middle of the animation
+        Thread.sleep(150);
+        getInstrumentation().waitForIdleSync();
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mActivity.getFragmentManager().popBackStack();
+            }
+        });
+    }
+
+    @TargetApi(VERSION_CODES.HONEYCOMB)
+    public static class TestFragment extends Fragment {
+        private static AtomicInteger sOrder = new AtomicInteger();
+        public int createOrder = -1;
+
+        @Override
+        public void onCreate(Bundle savedInstanceState) {
+            createOrder = sOrder.getAndIncrement();
+            super.onCreate(savedInstanceState);
+        }
+    }
+
+    public static class FragmentA extends Fragment {
+        @Override
+        public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                Bundle savedInstanceState) {
+            return inflater.inflate(R.layout.fragment_a, container, false);
+        }
+    }
+
+    public static class FragmentB extends Fragment {
+        @Override
+        public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                Bundle savedInstanceState) {
+            return inflater.inflate(R.layout.fragment_b, container, false);
+        }
+    }
+}
diff --git a/tests/tests/app.usage/src/android/app/usage/cts/FragmentTestActivity.java b/tests/tests/app.usage/src/android/app/usage/cts/FragmentTestActivity.java
new file mode 100644
index 0000000..2f900ad
--- /dev/null
+++ b/tests/tests/app.usage/src/android/app/usage/cts/FragmentTestActivity.java
@@ -0,0 +1,29 @@
+/**
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy
+ * of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES 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.app.usage.cts;
+
+import android.annotation.Nullable;
+import android.app.Activity;
+import android.app.usage.cts.R;
+import android.os.Bundle;
+
+public class FragmentTestActivity extends Activity {
+    @Override
+    protected void onCreate(@Nullable Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.fragment_container);
+    }
+}
diff --git a/tests/tests/app/Android.mk b/tests/tests/app/Android.mk
index 301f931..08201a6 100644
--- a/tests/tests/app/Android.mk
+++ b/tests/tests/app/Android.mk
@@ -1,4 +1,4 @@
-# Copyright (C) 2008 The Android Open Source Project
+# Copyright (C) 2016 The Android Open 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,21 +16,21 @@
 
 include $(CLEAR_VARS)
 
+LOCAL_PACKAGE_NAME := CtsAndroidAppTestCases
+
 # don't include this package in any target
 LOCAL_MODULE_TAGS := optional
+
 # and when built explicitly put it in the data partition
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
 
-LOCAL_JAVA_LIBRARIES := android.test.runner telephony-common voip-common org.apache.http.legacy
+LOCAL_JAVA_LIBRARIES := android.test.runner
 
-LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctstestrunner ctstestserver
+LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
 
-LOCAL_SRC_FILES := $(call all-java-files-under, src) \
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
-LOCAL_PACKAGE_NAME := CtsAppTestCases
-
-LOCAL_INSTRUMENTATION_FOR := CtsAppTestStubs
-
-LOCAL_SDK_VERSION := current
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
 
 include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/app/AndroidManifest.xml b/tests/tests/app/AndroidManifest.xml
index d05648c..be903e3 100644
--- a/tests/tests/app/AndroidManifest.xml
+++ b/tests/tests/app/AndroidManifest.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
- * Copyright (C) 2007 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open 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,18 +16,17 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.app">
+    package="android.app.cts">
 
-    <uses-sdk android:minSdkVersion="11" />
-    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
-    <uses-permission android:name="android.permission.BODY_SENSORS" />
     <application>
         <uses-library android:name="android.test.runner" />
-        <uses-library android:name="org.apache.http.legacy" android:required="false" />
+
+        <activity android:name=".ApplyOverrideConfigurationActivity"
+                  android:configChanges="orientation|screenSize" />
     </application>
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.cts.app.stub"
+                     android:targetPackage="android.app.cts"
                      android:label="CTS tests of android.app">
         <meta-data android:name="listener"
             android:value="com.android.cts.runner.CtsTestRunListener" />
diff --git a/tests/tests/app/AndroidTest.xml b/tests/tests/app/AndroidTest.xml
index 01ebbcb..739e0ba 100644
--- a/tests/tests/app/AndroidTest.xml
+++ b/tests/tests/app/AndroidTest.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
+<!-- Copyright (C) 2016 The Android Open 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,7 +13,13 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<configuration description="Base config for CTS package preparer">
-    <include name="common-config" />
-    <option name="cts-apk-installer:test-file-name" value="CtsSimpleApp.apk" />
+<configuration description="Configuration for app Tests">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsAndroidAppTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.app.cts" />
+        <option name="runtime-hint" value="1s" />
+    </test>
 </configuration>
diff --git a/tests/tests/app/src/android/app/backup/cts/BackupManagerTest.java b/tests/tests/app/src/android/app/backup/cts/BackupManagerTest.java
deleted file mode 100644
index 1b0a401..0000000
--- a/tests/tests/app/src/android/app/backup/cts/BackupManagerTest.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.backup.cts;
-
-import android.app.backup.BackupManager;
-import android.app.backup.RestoreObserver;
-import android.test.AndroidTestCase;
-
-public class BackupManagerTest extends AndroidTestCase {
-
-    public void testBackupManager() throws Exception {
-        // Check that these don't crash as if they were called in an app...
-        BackupManager backupManager = new BackupManager(mContext);
-        backupManager.dataChanged();
-        BackupManager.dataChanged("com.android.cts.app.stub");
-
-        // Backup isn't expected to work in this test but check for obvious bugs...
-        int result = backupManager.requestRestore(new RestoreObserver() {});
-        assertTrue(result != 0);
-    }
-}
diff --git a/tests/tests/app/src/android/app/cts/ActionBarTest.java b/tests/tests/app/src/android/app/cts/ActionBarTest.java
deleted file mode 100644
index 75e7807..0000000
--- a/tests/tests/app/src/android/app/cts/ActionBarTest.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-import android.app.ActionBar;
-import android.app.ActionBar.Tab;
-import android.app.ActionBar.TabListener;
-import android.app.FragmentTransaction;
-import android.test.ActivityInstrumentationTestCase2;
-import android.test.UiThreadTest;
-
-public class ActionBarTest extends ActivityInstrumentationTestCase2<ActionBarActivity> {
-
-    private ActionBarActivity mActivity;
-    private ActionBar mBar;
-
-    public ActionBarTest() {
-        super(ActionBarActivity.class);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mActivity = getActivity();
-        mBar = mActivity.getActionBar();
-    }
-
-    @UiThreadTest
-    public void testAddTab() {
-        if (mBar == null) {
-            return;
-        }
-        assertEquals(0, mBar.getTabCount());
-
-        Tab t1 = createTab("Tab 1");
-        mBar.addTab(t1);
-        assertEquals(1, mBar.getTabCount());
-        assertEquals(t1, mBar.getSelectedTab());
-        assertEquals(t1, mBar.getTabAt(0));
-
-        Tab t2 = createTab("Tab 2");
-        mBar.addTab(t2);
-        assertEquals(2, mBar.getTabCount());
-        assertEquals(t1, mBar.getSelectedTab());
-        assertEquals(t2, mBar.getTabAt(1));
-
-        Tab t3 = createTab("Tab 3");
-        mBar.addTab(t3, true);
-        assertEquals(3, mBar.getTabCount());
-        assertEquals(t3, mBar.getSelectedTab());
-        assertEquals(t3, mBar.getTabAt(2));
-
-        Tab t4 = createTab("Tab 2.5");
-        mBar.addTab(t4, 2);
-        assertEquals(4, mBar.getTabCount());
-        assertEquals(t4, mBar.getTabAt(2));
-        assertEquals(t3, mBar.getTabAt(3));
-
-        Tab t5 = createTab("Tab 0.5");
-        mBar.addTab(t5, 0, true);
-        assertEquals(5, mBar.getTabCount());
-        assertEquals(t5, mBar.getSelectedTab());
-        assertEquals(t5, mBar.getTabAt(0));
-        assertEquals(t1, mBar.getTabAt(1));
-        assertEquals(t2, mBar.getTabAt(2));
-        assertEquals(t4, mBar.getTabAt(3));
-        assertEquals(t3, mBar.getTabAt(4));
-    }
-
-    private Tab createTab(String name) {
-        return mBar.newTab().setText("Tab 1").setTabListener(new TestTabListener());
-    }
-
-    static class TestTabListener implements TabListener {
-        @Override
-        public void onTabSelected(Tab tab, FragmentTransaction ft) {
-        }
-
-        @Override
-        public void onTabUnselected(Tab tab, FragmentTransaction ft) {
-        }
-
-        @Override
-        public void onTabReselected(Tab tab, FragmentTransaction ft) {
-        }
-    }
-}
diff --git a/tests/tests/app/src/android/app/cts/ActivityGroupTest.java b/tests/tests/app/src/android/app/cts/ActivityGroupTest.java
deleted file mode 100644
index f5fc0bd..0000000
--- a/tests/tests/app/src/android/app/cts/ActivityGroupTest.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-
-import android.app.ActivityGroup;
-import android.content.ComponentName;
-import android.content.Intent;
-import android.os.Bundle;
-
-public class ActivityGroupTest extends ActivityTestsBase {
-    private Intent mTabIntent;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mTabIntent = new Intent(mContext, LaunchpadTabActivity.class);
-        mTabIntent.putExtra("tab", new ComponentName(mContext, LaunchpadActivity.class));
-    }
-
-    public void testTabBasic() throws Exception {
-        mIntent = mTabIntent;
-        runLaunchpad(LaunchpadActivity.LIFECYCLE_BASIC);
-    }
-
-    public void testTabScreen() throws Exception {
-        mIntent = mTabIntent;
-        runLaunchpad(LaunchpadActivity.LIFECYCLE_SCREEN);
-    }
-
-    public void testTabDialog() throws Exception {
-        mIntent = mTabIntent;
-        runLaunchpad(LaunchpadActivity.LIFECYCLE_DIALOG);
-    }
-}
diff --git a/tests/tests/app/src/android/app/cts/ActivityManagerMemoryClassTest.java b/tests/tests/app/src/android/app/cts/ActivityManagerMemoryClassTest.java
deleted file mode 100644
index 639741d..0000000
--- a/tests/tests/app/src/android/app/cts/ActivityManagerMemoryClassTest.java
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-import android.app.Activity;
-import android.app.ActivityManager;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.res.Configuration;
-import android.test.ActivityInstrumentationTestCase2;
-import android.util.DisplayMetrics;
-import android.view.Display;
-import android.view.WindowManager;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * {@link ActivityInstrumentationTestCase2} that tests {@link ActivityManager#getMemoryClass()}
- * by checking that the memory class matches the proper screen density and by launching an
- * application that attempts to allocate memory on the heap.
- */
-public class ActivityManagerMemoryClassTest
-        extends ActivityInstrumentationTestCase2<ActivityManagerMemoryClassLaunchActivity> {
-
-    public ActivityManagerMemoryClassTest() {
-        super(ActivityManagerMemoryClassLaunchActivity.class);
-    }
-
-    public static class ExpectedMemorySizesClass {
-        private static final Map<Integer, Integer> expectedMemorySizeForWatch
-            =  new HashMap<Integer, Integer>();
-        private static final Map<Integer, Integer> expectedMemorySizeForSmallNormalScreen
-            =  new HashMap<Integer, Integer>();
-        private static final Map<Integer, Integer> expectedMemorySizeForLargeScreen
-            =  new HashMap<Integer, Integer>();
-        private static final Map<Integer, Integer> expectedMemorySizeForXLargeScreen
-            =  new HashMap<Integer, Integer>();
-
-        static {
-            expectedMemorySizeForWatch.put(DisplayMetrics.DENSITY_LOW, 32);
-            expectedMemorySizeForWatch.put(DisplayMetrics.DENSITY_MEDIUM, 32);
-            expectedMemorySizeForWatch.put(DisplayMetrics.DENSITY_TV, 32);
-            expectedMemorySizeForWatch.put(DisplayMetrics.DENSITY_HIGH, 36);
-            expectedMemorySizeForWatch.put(DisplayMetrics.DENSITY_280, 36);
-            expectedMemorySizeForWatch.put(DisplayMetrics.DENSITY_XHIGH, 48);
-            expectedMemorySizeForWatch.put(DisplayMetrics.DENSITY_360, 48);
-            expectedMemorySizeForWatch.put(DisplayMetrics.DENSITY_400, 56);
-            expectedMemorySizeForWatch.put(DisplayMetrics.DENSITY_420, 64);
-            expectedMemorySizeForWatch.put(DisplayMetrics.DENSITY_XXHIGH, 88);
-            expectedMemorySizeForWatch.put(DisplayMetrics.DENSITY_560, 112);
-            expectedMemorySizeForWatch.put(DisplayMetrics.DENSITY_XXXHIGH, 154);
-        }
-
-        static {
-            expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_LOW, 32);
-            expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_MEDIUM, 32);
-            expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_TV, 48);
-            expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_HIGH, 48);
-            expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_280, 48);
-            expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_XHIGH, 80);
-            expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_360, 80);
-            expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_400, 96);
-            expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_420, 112);
-            expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_XXHIGH, 128);
-            expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_560, 192);
-            expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_XXXHIGH, 256);
-        }
-
-        static {
-            expectedMemorySizeForLargeScreen.put(DisplayMetrics.DENSITY_LOW, 32);
-            expectedMemorySizeForLargeScreen.put(DisplayMetrics.DENSITY_MEDIUM, 64);
-            expectedMemorySizeForLargeScreen.put(DisplayMetrics.DENSITY_TV, 80);
-            expectedMemorySizeForLargeScreen.put(DisplayMetrics.DENSITY_HIGH, 80);
-            expectedMemorySizeForLargeScreen.put(DisplayMetrics.DENSITY_280, 96);
-            expectedMemorySizeForLargeScreen.put(DisplayMetrics.DENSITY_XHIGH, 128);
-            expectedMemorySizeForLargeScreen.put(DisplayMetrics.DENSITY_360, 160);
-            expectedMemorySizeForLargeScreen.put(DisplayMetrics.DENSITY_400, 192);
-            expectedMemorySizeForLargeScreen.put(DisplayMetrics.DENSITY_420, 228);
-            expectedMemorySizeForLargeScreen.put(DisplayMetrics.DENSITY_XXHIGH, 256);
-            expectedMemorySizeForLargeScreen.put(DisplayMetrics.DENSITY_560, 384);
-            expectedMemorySizeForLargeScreen.put(DisplayMetrics.DENSITY_XXXHIGH, 512);
-        }
-
-        static {
-            expectedMemorySizeForXLargeScreen.put(DisplayMetrics.DENSITY_LOW, 48);
-            expectedMemorySizeForXLargeScreen.put(DisplayMetrics.DENSITY_MEDIUM, 80);
-            expectedMemorySizeForXLargeScreen.put(DisplayMetrics.DENSITY_TV, 96);
-            expectedMemorySizeForXLargeScreen.put(DisplayMetrics.DENSITY_HIGH, 96);
-            expectedMemorySizeForXLargeScreen.put(DisplayMetrics.DENSITY_280, 144);
-            expectedMemorySizeForXLargeScreen.put(DisplayMetrics.DENSITY_XHIGH, 192);
-            expectedMemorySizeForXLargeScreen.put(DisplayMetrics.DENSITY_360, 240);
-            expectedMemorySizeForXLargeScreen.put(DisplayMetrics.DENSITY_400, 288);
-            expectedMemorySizeForXLargeScreen.put(DisplayMetrics.DENSITY_420, 336);
-            expectedMemorySizeForXLargeScreen.put(DisplayMetrics.DENSITY_XXHIGH, 384);
-            expectedMemorySizeForXLargeScreen.put(DisplayMetrics.DENSITY_560, 576);
-            expectedMemorySizeForXLargeScreen.put(DisplayMetrics.DENSITY_XXXHIGH, 768);
-        }
-
-        public static Integer getExpectedMemorySize(
-                int screenSize,
-                int screenDensity,
-                boolean isWatch) {
-
-           if (isWatch) {
-              return expectedMemorySizeForWatch.get(screenDensity);
-           }
-
-           switch (screenSize) {
-                case Configuration.SCREENLAYOUT_SIZE_SMALL:
-                case Configuration.SCREENLAYOUT_SIZE_NORMAL:
-                    return expectedMemorySizeForSmallNormalScreen.get(screenDensity);
-                case Configuration.SCREENLAYOUT_SIZE_LARGE:
-                    return expectedMemorySizeForLargeScreen.get(screenDensity);
-                case Configuration.SCREENLAYOUT_SIZE_XLARGE:
-                    return expectedMemorySizeForXLargeScreen.get(screenDensity);
-                default:
-                    throw new IllegalArgumentException("No memory requirement specified "
-                        + " for screen layout size " + screenSize);
-           }
-        }
-    }
-
-    public void testGetMemoryClass() throws Exception {
-        int memoryClass = getMemoryClass();
-        int screenDensity = getScreenDensity();
-        int screenSize = getScreenSize();
-        assertMemoryForScreenDensity(memoryClass, screenDensity, screenSize);
-
-        runHeapTestApp(memoryClass);
-    }
-
-    private int getMemoryClass() {
-        Context context = getInstrumentation().getTargetContext();
-        ActivityManager activityManager =
-                (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
-        return activityManager.getMemoryClass();
-    }
-
-    private int getScreenDensity() {
-        Context context = getInstrumentation().getTargetContext();
-        WindowManager windowManager =
-                (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
-        Display display = windowManager.getDefaultDisplay();
-        DisplayMetrics metrics = new DisplayMetrics();
-        display.getMetrics(metrics);
-        return metrics.densityDpi;
-    }
-
-    private int getScreenSize() {
-        Context context = getInstrumentation().getTargetContext();
-        Configuration config = context.getResources().getConfiguration();
-        return config.screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK;
-    }
-
-    private void assertMemoryForScreenDensity(int memoryClass, int screenDensity, int screenSize) {
-        Context context = getInstrumentation().getTargetContext();
-        boolean isWatch =
-            context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH);
-        int expectedMinimumMemory =
-            ExpectedMemorySizesClass.getExpectedMemorySize(screenSize, screenDensity, isWatch);
-
-        assertTrue("Expected to have at least " + expectedMinimumMemory
-                + "mb of memory for screen density " + screenDensity,
-                        memoryClass >= expectedMinimumMemory);
-    }
-
-    private void runHeapTestApp(int memoryClass) throws InterruptedException {
-        Intent intent = new Intent();
-        intent.putExtra(ActivityManagerMemoryClassLaunchActivity.MEMORY_CLASS_EXTRA,
-                memoryClass);
-        setActivityIntent(intent);
-        ActivityManagerMemoryClassLaunchActivity activity = getActivity();
-        assertEquals("The test application couldn't allocate memory close to the amount "
-                + " specified by the memory class.", Activity.RESULT_OK, activity.getResult());
-    }
-}
diff --git a/tests/tests/app/src/android/app/cts/ActivityManagerTest.java b/tests/tests/app/src/android/app/cts/ActivityManagerTest.java
deleted file mode 100644
index 02d13ef..0000000
--- a/tests/tests/app/src/android/app/cts/ActivityManagerTest.java
+++ /dev/null
@@ -1,526 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import android.app.Activity;
-import android.app.ActivityManager;
-import android.app.ActivityManager.RecentTaskInfo;
-import android.app.ActivityManager.RunningAppProcessInfo;
-import android.app.ActivityManager.RunningServiceInfo;
-import android.app.ActivityManager.RunningTaskInfo;
-import android.app.ActivityOptions;
-import android.app.Instrumentation;
-import android.app.Instrumentation.ActivityMonitor;
-import android.app.Instrumentation.ActivityResult;
-import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.ConfigurationInfo;
-import android.test.InstrumentationTestCase;
-
-public class ActivityManagerTest extends InstrumentationTestCase {
-    private static final String STUB_PACKAGE_NAME = "com.android.cts.app.stub";
-    private static final int WAITFOR_MSEC = 5000;
-    private static final String SERVICE_NAME = "android.app.cts.MockService";
-    private static final int WAIT_TIME = 2000;
-    // A secondary test activity from another APK.
-    private static final String SIMPLE_PACKAGE_NAME = "com.android.cts.launcherapps.simpleapp";
-    private static final String SIMPLE_ACTIVITY = ".SimpleActivity";
-    private static final String SIMPLE_ACTIVITY_IMMEDIATE_EXIT = ".SimpleActivityImmediateExit";
-    private static final String SIMPLE_ACTIVITY_CHAIN_EXIT = ".SimpleActivityChainExit";
-    // The action sent back by the SIMPLE_APP after a restart.
-    private static final String ACTIVITY_LAUNCHED_ACTION =
-            "com.android.cts.launchertests.LauncherAppsTests.LAUNCHED_ACTION";
-    // The action sent back by the SIMPLE_APP_IMMEDIATE_EXIT when it terminates.
-    private static final String ACTIVITY_EXIT_ACTION =
-            "com.android.cts.launchertests.LauncherAppsTests.EXIT_ACTION";
-    // The action sent back by the SIMPLE_APP_CHAIN_EXIT when the task chain ends. 
-    private static final String ACTIVITY_CHAIN_EXIT_ACTION =
-            "com.android.cts.launchertests.LauncherAppsTests.CHAIN_EXIT_ACTION";
-    // The action sent to identify the time track info.
-    private static final String ACTIVITY_TIME_TRACK_INFO = "com.android.cts.TIME_TRACK_INFO";
-    // Return states of the ActivityReceiverFilter.
-    public static final int RESULT_PASS = 1;
-    public static final int RESULT_FAIL = 2;
-    public static final int RESULT_TIMEOUT = 3;
-
-    private Context mContext;
-    private ActivityManager mActivityManager;
-    private Intent mIntent;
-    private List<Activity> mStartedActivityList;
-    private int mErrorProcessID;
-    private Instrumentation mInstrumentation;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mInstrumentation = getInstrumentation();
-        mContext = mInstrumentation.getContext();
-        mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
-        mStartedActivityList = new ArrayList<Activity>();
-        mErrorProcessID = -1;
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-        if (mIntent != null) {
-            mInstrumentation.getContext().stopService(mIntent);
-        }
-        for (int i = 0; i < mStartedActivityList.size(); i++) {
-            mStartedActivityList.get(i).finish();
-        }
-        if (mErrorProcessID != -1) {
-            android.os.Process.killProcess(mErrorProcessID);
-        }
-    }
-
-    public void testGetRecentTasks() throws Exception {
-        int maxNum = 0;
-        int flags = 0;
-
-        List<RecentTaskInfo> recentTaskList;
-        // Test parameter: maxNum is set to 0
-        recentTaskList = mActivityManager.getRecentTasks(maxNum, flags);
-        assertNotNull(recentTaskList);
-        assertTrue(recentTaskList.size() == 0);
-        // Test parameter: maxNum is set to 50
-        maxNum = 50;
-        recentTaskList = mActivityManager.getRecentTasks(maxNum, flags);
-        assertNotNull(recentTaskList);
-        // start recent1_activity.
-        startSubActivity(ActivityManagerRecentOneActivity.class);
-        Thread.sleep(WAIT_TIME);
-        // start recent2_activity
-        startSubActivity(ActivityManagerRecentTwoActivity.class);
-        Thread.sleep(WAIT_TIME);
-        /*
-         * assert both recent1_activity and recent2_activity exist in the recent
-         * tasks list. Moreover,the index of the recent2_activity is smaller
-         * than the index of recent1_activity
-         */
-        recentTaskList = mActivityManager.getRecentTasks(maxNum, flags);
-        int indexRecentOne = -1;
-        int indexRecentTwo = -1;
-        int i = 0;
-        for (RecentTaskInfo rti : recentTaskList) {
-            if (rti.baseIntent.getComponent().getClassName().equals(
-                    ActivityManagerRecentOneActivity.class.getName())) {
-                indexRecentOne = i;
-            } else if (rti.baseIntent.getComponent().getClassName().equals(
-                    ActivityManagerRecentTwoActivity.class.getName())) {
-                indexRecentTwo = i;
-            }
-            i++;
-        }
-        assertTrue(indexRecentOne != -1 && indexRecentTwo != -1);
-        assertTrue(indexRecentTwo < indexRecentOne);
-
-        try {
-            mActivityManager.getRecentTasks(-1, 0);
-            fail("Should throw IllegalArgumentException");
-        } catch (IllegalArgumentException e) {
-            // expected exception
-        }
-    }
-
-    public void testGetRecentTasksLimitedToCurrentAPK() throws Exception {
-        int maxNum = 0;
-        int flags = 0;
-
-        // Check the number of tasks at this time.
-        List<RecentTaskInfo>  recentTaskList;
-        recentTaskList = mActivityManager.getRecentTasks(maxNum, flags);
-        int numberOfEntriesFirstRun = recentTaskList.size();
-
-        // Start another activity from another APK.
-        Intent intent = new Intent(Intent.ACTION_MAIN);
-        intent.setClassName(SIMPLE_PACKAGE_NAME, SIMPLE_PACKAGE_NAME + SIMPLE_ACTIVITY);
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        ActivityReceiverFilter receiver = new ActivityReceiverFilter(ACTIVITY_LAUNCHED_ACTION);
-        mContext.startActivity(intent);
-
-        // Make sure the activity has really started.
-        assertEquals(RESULT_PASS, receiver.waitForActivity());
-        receiver.close();
-
-        // There shouldn't be any more tasks in this list at this time.
-        recentTaskList = mActivityManager.getRecentTasks(maxNum, flags);
-        int numberOfEntriesSecondRun = recentTaskList.size();
-        assertTrue(numberOfEntriesSecondRun == numberOfEntriesFirstRun);
-    }
-
-    // The receiver filter needs to be instantiated with the command to filter for before calling
-    // startActivity.
-    private class ActivityReceiverFilter extends BroadcastReceiver {
-        // The activity we want to filter for.
-        private String mActivityToFilter;
-        private int result = RESULT_TIMEOUT;
-        public long mTimeUsed = 0;
-        private static final int TIMEOUT_IN_MS = 1000;
-
-        // Create the filter with the intent to look for.
-        public ActivityReceiverFilter(String activityToFilter) {
-            mActivityToFilter = activityToFilter;
-            IntentFilter filter = new IntentFilter();
-            filter.addAction(mActivityToFilter);
-            mInstrumentation.getTargetContext().registerReceiver(this, filter);
-        }
-
-        // Turn off the filter.
-        public void close() {
-            mInstrumentation.getTargetContext().unregisterReceiver(this);
-        }
-
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (intent.getAction().equals(mActivityToFilter)) {
-                synchronized(this) {
-                   result = RESULT_PASS;
-                   if (mActivityToFilter.equals(ACTIVITY_TIME_TRACK_INFO)) {
-                       mTimeUsed = intent.getExtras().getLong(
-                               ActivityOptions.EXTRA_USAGE_TIME_REPORT);
-                   }
-                   notifyAll();
-                }
-            }
-        }
-
-        public int waitForActivity() {
-            synchronized(this) {
-                try {
-                    wait(TIMEOUT_IN_MS);
-                } catch (InterruptedException e) {
-                }
-            }
-            return result;
-        }
-    }
-
-    private final <T extends Activity> void startSubActivity(Class<T> activityClass) {
-        final Instrumentation.ActivityResult result = new ActivityResult(0, new Intent());
-        final ActivityMonitor monitor = new ActivityMonitor(activityClass.getName(), result, false);
-        mInstrumentation.addMonitor(monitor);
-        launchActivity(STUB_PACKAGE_NAME, activityClass, null);
-        mStartedActivityList.add(monitor.waitForActivity());
-    }
-
-    public void testGetRunningTasks() {
-        // Test illegal parameter
-        List<RunningTaskInfo> runningTaskList;
-        runningTaskList = mActivityManager.getRunningTasks(-1);
-        assertTrue(runningTaskList.size() == 0);
-
-        runningTaskList = mActivityManager.getRunningTasks(0);
-        assertTrue(runningTaskList.size() == 0);
-
-        runningTaskList = mActivityManager.getRunningTasks(20);
-        int taskSize = runningTaskList.size();
-        assertTrue(taskSize >= 0 && taskSize <= 20);
-
-        // start recent1_activity.
-        startSubActivity(ActivityManagerRecentOneActivity.class);
-        // start recent2_activity
-        startSubActivity(ActivityManagerRecentTwoActivity.class);
-
-        /*
-         * assert both recent1_activity and recent2_activity exist in the
-         * running tasks list. Moreover,the index of the recent2_activity is
-         * smaller than the index of recent1_activity
-         */
-        runningTaskList = mActivityManager.getRunningTasks(20);
-        int indexRecentOne = -1;
-        int indexRecentTwo = -1;
-        int i = 0;
-        for (RunningTaskInfo rti : runningTaskList) {
-            if (rti.baseActivity.getClassName().equals(
-                    ActivityManagerRecentOneActivity.class.getName())) {
-                indexRecentOne = i;
-            } else if (rti.baseActivity.getClassName().equals(
-                    ActivityManagerRecentTwoActivity.class.getName())) {
-                indexRecentTwo = i;
-            }
-            i++;
-        }
-        assertTrue(indexRecentOne != -1 && indexRecentTwo != -1);
-        assertTrue(indexRecentTwo < indexRecentOne);
-    }
-
-    public void testGetRunningServices() throws Exception {
-        // Test illegal parameter
-        List<RunningServiceInfo> runningServiceInfo;
-        runningServiceInfo = mActivityManager.getRunningServices(-1);
-        assertTrue(runningServiceInfo.size() == 0);
-
-        runningServiceInfo = mActivityManager.getRunningServices(0);
-        assertTrue(runningServiceInfo.size() == 0);
-
-        runningServiceInfo = mActivityManager.getRunningServices(5);
-        assertTrue(runningServiceInfo.size() >= 0 && runningServiceInfo.size() <= 5);
-
-        Intent intent = new Intent();
-        intent.setClass(mInstrumentation.getTargetContext(), MockService.class);
-        mInstrumentation.getTargetContext().startService(intent);
-        Thread.sleep(WAIT_TIME);
-
-        runningServiceInfo = mActivityManager.getRunningServices(Integer.MAX_VALUE);
-        boolean foundService = false;
-        for (RunningServiceInfo rs : runningServiceInfo) {
-            if (rs.service.getClassName().equals(SERVICE_NAME)) {
-                foundService = true;
-                break;
-            }
-        }
-        assertTrue(foundService);
-        mContext.stopService(intent);
-        Thread.sleep(WAIT_TIME);
-    }
-
-    public void testGetMemoryInfo() {
-        ActivityManager.MemoryInfo outInfo = new ActivityManager.MemoryInfo();
-        mActivityManager.getMemoryInfo(outInfo);
-        assertTrue(outInfo.lowMemory == (outInfo.availMem <= outInfo.threshold));
-    }
-
-    public void testGetRunningAppProcesses() throws Exception {
-        List<RunningAppProcessInfo> list = mActivityManager.getRunningAppProcesses();
-        assertNotNull(list);
-        final String SYSTEM_PROCESS = "system";
-        boolean hasSystemProcess = false;
-        // The package name is also the default name for the application process
-        final String TEST_PROCESS = STUB_PACKAGE_NAME;
-        boolean hasTestProcess = false;
-        for (RunningAppProcessInfo ra : list) {
-            if (ra.processName.equals(SYSTEM_PROCESS)) {
-                hasSystemProcess = true;
-            } else if (ra.processName.equals(TEST_PROCESS)) {
-                hasTestProcess = true;
-            }
-        }
-        // For security reasons the system process is not exposed.
-        assertTrue(!hasSystemProcess && hasTestProcess);
-
-        for (RunningAppProcessInfo ra : list) {
-            if (ra.processName.equals("com.android.cts.app.stub:remote")) {
-                fail("should be no process named com.android.cts.app.stub:remote");
-            }
-        }
-        // start a new process
-        mIntent = new Intent("android.app.REMOTESERVICE");
-        mIntent.setPackage("com.android.cts.app.stub");
-        mInstrumentation.getTargetContext().startService(mIntent);
-        Thread.sleep(WAITFOR_MSEC);
-
-        List<RunningAppProcessInfo> listNew = mActivityManager.getRunningAppProcesses();
-        assertTrue(list.size() <= listNew.size());
-
-        for (RunningAppProcessInfo ra : listNew) {
-            if (ra.processName.equals("com.android.cts.app.stub:remote")) {
-                return;
-            }
-        }
-        fail("com.android.cts.app.stub:remote process should be available");
-    }
-
-    public void testGetProcessInErrorState() throws Exception {
-        List<ActivityManager.ProcessErrorStateInfo> errList = null;
-        errList = mActivityManager.getProcessesInErrorState();
-    }
-
-    public void testRestartPackage() {
-    }
-
-    public void testGetDeviceConfigurationInfo() {
-        ConfigurationInfo conInf = mActivityManager.getDeviceConfigurationInfo();
-        assertNotNull(conInf);
-    }
-
-    /**
-     * Simple test for {@link ActivityManager.isUserAMonkey()} - verifies its false.
-     *
-     * TODO: test positive case
-     */
-    public void testIsUserAMonkey() {
-        assertFalse(ActivityManager.isUserAMonkey());
-    }
-
-    /**
-     * Verify that {@link ActivityManager.isRunningInTestHarness()} is false.
-     */
-    public void testIsRunningInTestHarness() {
-        assertFalse("isRunningInTestHarness must be false in production builds",
-                ActivityManager.isRunningInTestHarness());
-    }
-
-    /**
-     * Go back to the home screen since running applications can interfere with application
-     * lifetime tests.
-     */
-    private void launchHome() throws Exception {
-        Intent intent = new Intent(Intent.ACTION_MAIN);
-        intent.addCategory(Intent.CATEGORY_HOME);
-        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        mContext.startActivity(intent);
-        Thread.sleep(WAIT_TIME);
-    }
-
-    /**
-     * Verify that the TimeTrackingAPI works properly when starting and ending an activity.
-     */
-    public void testTimeTrackingAPI_SimpleStartExit() throws Exception {
-        launchHome();
-        // Prepare to start an activity from another APK.
-        Intent intent = new Intent(Intent.ACTION_MAIN);
-        intent.setClassName(SIMPLE_PACKAGE_NAME,
-                SIMPLE_PACKAGE_NAME + SIMPLE_ACTIVITY_IMMEDIATE_EXIT);
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-
-        // Prepare the time receiver action.
-        Context context = mInstrumentation.getTargetContext();
-        ActivityOptions options = ActivityOptions.makeBasic();
-        Intent receiveIntent = new Intent(ACTIVITY_TIME_TRACK_INFO);
-        options.requestUsageTimeReport(PendingIntent.getBroadcast(context,
-                0, receiveIntent, PendingIntent.FLAG_CANCEL_CURRENT));
-
-        // The application finished tracker.
-        ActivityReceiverFilter appEndReceiver = new ActivityReceiverFilter(ACTIVITY_EXIT_ACTION);
-
-        // The filter for the time event.
-        ActivityReceiverFilter timeReceiver = new ActivityReceiverFilter(ACTIVITY_TIME_TRACK_INFO);
-
-        // Run the activity.
-        mContext.startActivity(intent, options.toBundle());
-
-        // Wait until it finishes and end the reciever then.
-        assertEquals(RESULT_PASS, appEndReceiver.waitForActivity());
-        appEndReceiver.close();
-
-        // At this time the timerReceiver should not fire, even though the activity has shut down,
-        // because we are back to the home screen.
-        assertEquals(RESULT_TIMEOUT, timeReceiver.waitForActivity());
-        assertTrue(timeReceiver.mTimeUsed == 0);
-
-        // Issuing now another activity will trigger the timing information release.
-        final Intent dummyIntent = new Intent(context, MockApplicationActivity.class);
-        dummyIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        final Activity activity = mInstrumentation.startActivitySync(dummyIntent);
-
-        // Wait until it finishes and end the reciever then.
-        assertEquals(RESULT_PASS, timeReceiver.waitForActivity());
-        timeReceiver.close();
-        assertTrue(timeReceiver.mTimeUsed != 0);
-    }
-
-    /**
-     * Verify that the TimeTrackingAPI works properly when switching away from the monitored task.
-     */
-    public void testTimeTrackingAPI_SwitchAwayTriggers() throws Exception {
-        launchHome();
-
-        // Prepare to start an activity from another APK.
-        Intent intent = new Intent(Intent.ACTION_MAIN);
-        intent.setClassName(SIMPLE_PACKAGE_NAME, SIMPLE_PACKAGE_NAME + SIMPLE_ACTIVITY);
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-
-        // Prepare the time receiver action.
-        Context context = mInstrumentation.getTargetContext();
-        ActivityOptions options = ActivityOptions.makeBasic();
-        Intent receiveIntent = new Intent(ACTIVITY_TIME_TRACK_INFO);
-        options.requestUsageTimeReport(PendingIntent.getBroadcast(context,
-                0, receiveIntent, PendingIntent.FLAG_CANCEL_CURRENT));
-
-        // The application started tracker.
-        ActivityReceiverFilter appStartedReceiver = new ActivityReceiverFilter(
-                ACTIVITY_LAUNCHED_ACTION);
-
-        // The filter for the time event.
-        ActivityReceiverFilter timeReceiver = new ActivityReceiverFilter(ACTIVITY_TIME_TRACK_INFO);
-
-        // Run the activity.
-        mContext.startActivity(intent, options.toBundle());
-
-        // Wait until it finishes and end the reciever then.
-        assertEquals(RESULT_PASS, appStartedReceiver.waitForActivity());
-        appStartedReceiver.close();
-
-        // At this time the timerReceiver should not fire since our app is running.
-        assertEquals(RESULT_TIMEOUT, timeReceiver.waitForActivity());
-        assertTrue(timeReceiver.mTimeUsed == 0);
-
-        // Starting now another activity will put ours into the back hence releasing the timing.
-        final Intent dummyIntent = new Intent(context, MockApplicationActivity.class);
-        dummyIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        final Activity activity = mInstrumentation.startActivitySync(dummyIntent);
-
-        // Wait until it finishes and end the reciever then.
-        assertEquals(RESULT_PASS, timeReceiver.waitForActivity());
-        timeReceiver.close();
-        assertTrue(timeReceiver.mTimeUsed != 0);
-    }
-
-    /**
-     * Verify that the TimeTrackingAPI works properly when handling an activity chain gets started
-     * and ended.
-     */
-    public void testTimeTrackingAPI_ChainedActivityExit() throws Exception {
-        launchHome();
-        // Prepare to start an activity from another APK.
-        Intent intent = new Intent(Intent.ACTION_MAIN);
-        intent.setClassName(SIMPLE_PACKAGE_NAME,
-                SIMPLE_PACKAGE_NAME + SIMPLE_ACTIVITY_CHAIN_EXIT);
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-
-        // Prepare the time receiver action.
-        Context context = mInstrumentation.getTargetContext();
-        ActivityOptions options = ActivityOptions.makeBasic();
-        Intent receiveIntent = new Intent(ACTIVITY_TIME_TRACK_INFO);
-        options.requestUsageTimeReport(PendingIntent.getBroadcast(context,
-                0, receiveIntent, PendingIntent.FLAG_CANCEL_CURRENT));
-
-        // The application finished tracker.
-        ActivityReceiverFilter appEndReceiver = new ActivityReceiverFilter(
-                ACTIVITY_CHAIN_EXIT_ACTION);
-
-        // The filter for the time event.
-        ActivityReceiverFilter timeReceiver = new ActivityReceiverFilter(ACTIVITY_TIME_TRACK_INFO);
-
-        // Run the activity.
-        mContext.startActivity(intent, options.toBundle());
-
-        // Wait until it finishes and end the reciever then.
-        assertEquals(RESULT_PASS, appEndReceiver.waitForActivity());
-        appEndReceiver.close();
-
-        // At this time the timerReceiver should not fire, even though the activity has shut down.
-        assertEquals(RESULT_TIMEOUT, timeReceiver.waitForActivity());
-        assertTrue(timeReceiver.mTimeUsed == 0);
-
-        // Issue another activity so that the timing information gets released.
-        final Intent dummyIntent = new Intent(context, MockApplicationActivity.class);
-        dummyIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        final Activity activity = mInstrumentation.startActivitySync(dummyIntent);
-
-        // Wait until it finishes and end the reciever then.
-        assertEquals(RESULT_PASS, timeReceiver.waitForActivity());
-        timeReceiver.close();
-        assertTrue(timeReceiver.mTimeUsed != 0);
-    }
-}
diff --git a/tests/tests/app/src/android/app/cts/ActivityManager_RunningServiceInfoTest.java b/tests/tests/app/src/android/app/cts/ActivityManager_RunningServiceInfoTest.java
deleted file mode 100644
index a6a38ae..0000000
--- a/tests/tests/app/src/android/app/cts/ActivityManager_RunningServiceInfoTest.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-import android.app.ActivityManager;
-import android.content.ComponentName;
-import android.os.Parcel;
-import android.test.AndroidTestCase;
-
-public class ActivityManager_RunningServiceInfoTest extends AndroidTestCase {
-    private ActivityManager.RunningServiceInfo mRunningServiceInfo;
-    private ComponentName mService;
-    private static final String PROCESS = "process";
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mRunningServiceInfo = new ActivityManager.RunningServiceInfo();
-        mService = new ComponentName(getContext(), MockActivity.class);
-
-        mRunningServiceInfo.service = mService;
-        mRunningServiceInfo.pid = 1;
-        mRunningServiceInfo.process = PROCESS;
-        mRunningServiceInfo.foreground = true;
-        mRunningServiceInfo.activeSince = 1l;
-        mRunningServiceInfo.started = true;
-        mRunningServiceInfo.clientCount = 2;
-        mRunningServiceInfo.crashCount = 1;
-        mRunningServiceInfo.lastActivityTime = 1l;
-        mRunningServiceInfo.restarting = 1l;
-    }
-
-    public void testConstructor() {
-        new ActivityManager.RunningServiceInfo();
-    }
-
-    public void testDescribeContents() {
-        assertEquals(0, mRunningServiceInfo.describeContents());
-    }
-
-    public void testWriteToParcel() throws Exception {
-
-        Parcel parcel = Parcel.obtain();
-        mRunningServiceInfo.writeToParcel(parcel, 0);
-        parcel.setDataPosition(0);
-        ActivityManager.RunningServiceInfo values =
-            ActivityManager.RunningServiceInfo.CREATOR.createFromParcel(parcel);
-        assertEquals(mService, values.service);
-        assertEquals(1, values.pid);
-        assertEquals(PROCESS, values.process);
-        assertTrue(values.foreground);
-        assertEquals(1l, values.activeSince);
-        assertTrue(values.started);
-        assertEquals(2, values.clientCount);
-        assertEquals(1, values.crashCount);
-        assertEquals(1l, values.lastActivityTime);
-        assertEquals(1l, values.restarting);
-    }
-
-    public void testReadFromParcel() throws Exception {
-
-        Parcel parcel = Parcel.obtain();
-        mRunningServiceInfo.writeToParcel(parcel, 0);
-        parcel.setDataPosition(0);
-        ActivityManager.RunningServiceInfo values =
-            new ActivityManager.RunningServiceInfo();
-        values.readFromParcel(parcel);
-        assertEquals(mService, values.service);
-        assertEquals(1, values.pid);
-        assertEquals(PROCESS, values.process);
-        assertTrue(values.foreground);
-        assertEquals(1l, values.activeSince);
-        assertTrue(values.started);
-        assertEquals(2, values.clientCount);
-        assertEquals(1, values.crashCount);
-        assertEquals(1l, values.lastActivityTime);
-        assertEquals(1l, values.restarting);
-    }
-
-}
diff --git a/tests/tests/app/src/android/app/cts/AlarmManagerTest.java b/tests/tests/app/src/android/app/cts/AlarmManagerTest.java
deleted file mode 100644
index b85c616..0000000
--- a/tests/tests/app/src/android/app/cts/AlarmManagerTest.java
+++ /dev/null
@@ -1,350 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-
-import android.app.AlarmManager;
-import android.app.AlarmManager.AlarmClockInfo;
-import android.app.PendingIntent;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.cts.util.PollingCheck;
-import android.os.Build;
-import android.os.SystemClock;
-import android.test.AndroidTestCase;
-import android.util.Log;
-import android.test.MoreAsserts;
-
-public class AlarmManagerTest extends AndroidTestCase {
-    public static final String MOCKACTION = "android.app.AlarmManagerTest.TEST_ALARMRECEIVER";
-    public static final String MOCKACTION2 = "android.app.AlarmManagerTest.TEST_ALARMRECEIVER2";
-
-    private AlarmManager mAm;
-    private Intent mIntent;
-    private PendingIntent mSender;
-    private Intent mIntent2;
-    private PendingIntent mSender2;
-
-    /*
-     *  The default snooze delay: 5 seconds
-     */
-    private static final long SNOOZE_DELAY = 5 * 1000L;
-    private long mWakeupTime;
-    private MockAlarmReceiver mMockAlarmReceiver;
-    private MockAlarmReceiver mMockAlarmReceiver2;
-
-    private static final int TIME_DELTA = 1000;
-    private static final int TIME_DELAY = 10000;
-    private static final int REPEAT_PERIOD = 60000;
-
-    // Receiver registration/unregistration between tests races with the system process, so
-    // we add a little buffer time here to allow the system to process before we proceed.
-    // This value is in milliseconds.
-    private static final long REGISTER_PAUSE = 250;
-
-    // Constants used for validating exact vs inexact alarm batching immunity.  We run a few
-    // trials of an exact alarm that is placed within an inexact alarm's window of opportunity,
-    // and mandate that the average observed delivery skew between the two be statistically
-    // significant -- i.e. that the two alarms are not being coalesced.  We also place an
-    // additional exact alarm only a short time after the inexact alarm's nominal trigger time.
-    // If exact alarms are allowed to batch with inexact ones this will tend to have no effect,
-    // but in the correct behavior -- inexact alarms not permitted to batch with exact ones --
-    // this additional exact alarm will have the effect of guaranteeing that the inexact alarm
-    // must fire no later than it -- i.e. a considerable time before the significant, later
-    // exact alarm.
-    //
-    // The test essentially amounts to requiring that the inexact MOCKACTION alarm and
-    // the much later exact MOCKACTION2 alarm fire far apart, always; with an implicit
-    // insistence that alarm batches are delivered at the head of their window.
-    private static final long TEST_WINDOW_LENGTH = 5 * 1000L;
-    private static final long TEST_ALARM_FUTURITY = 6 * 1000L;
-    private static final long FAIL_DELTA = 50;
-    private static final long NUM_TRIALS = 5;
-    private static final long MAX_NEAR_DELIVERIES = 2;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-
-        mAm = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
-
-        mIntent = new Intent(MOCKACTION)
-                .addFlags(Intent.FLAG_RECEIVER_FOREGROUND | Intent.FLAG_RECEIVER_REGISTERED_ONLY);
-        mSender = PendingIntent.getBroadcast(mContext, 0, mIntent, 0);
-        mMockAlarmReceiver = new MockAlarmReceiver(mIntent.getAction());
-
-        mIntent2 = new Intent(MOCKACTION2)
-                .addFlags(Intent.FLAG_RECEIVER_FOREGROUND | Intent.FLAG_RECEIVER_REGISTERED_ONLY);
-        mSender2 = PendingIntent.getBroadcast(mContext, 0, mIntent2, 0);
-        mMockAlarmReceiver2 = new MockAlarmReceiver(mIntent2.getAction());
-
-        IntentFilter filter = new IntentFilter(mIntent.getAction());
-        mContext.registerReceiver(mMockAlarmReceiver, filter);
-
-        IntentFilter filter2 = new IntentFilter(mIntent2.getAction());
-        mContext.registerReceiver(mMockAlarmReceiver2, filter2);
-
-        Thread.sleep(REGISTER_PAUSE);
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-        mContext.unregisterReceiver(mMockAlarmReceiver);
-        mContext.unregisterReceiver(mMockAlarmReceiver2);
-
-        Thread.sleep(REGISTER_PAUSE);
-    }
-
-    public void testSetTypes() throws Exception {
-        // TODO: try to find a way to make device sleep then test whether
-        // AlarmManager perform the expected way
-
-        // test parameter type is RTC_WAKEUP
-        mMockAlarmReceiver.setAlarmedFalse();
-        mWakeupTime = System.currentTimeMillis() + SNOOZE_DELAY;
-        mAm.setExact(AlarmManager.RTC_WAKEUP, mWakeupTime, mSender);
-        new PollingCheck(SNOOZE_DELAY + TIME_DELAY) {
-            @Override
-            protected boolean check() {
-                return mMockAlarmReceiver.alarmed;
-            }
-        }.run();
-        assertEquals(mMockAlarmReceiver.rtcTime, mWakeupTime, TIME_DELTA);
-
-        // test parameter type is RTC
-        mMockAlarmReceiver.setAlarmedFalse();
-        mWakeupTime = System.currentTimeMillis() + SNOOZE_DELAY;
-        mAm.setExact(AlarmManager.RTC, mWakeupTime, mSender);
-        new PollingCheck(SNOOZE_DELAY + TIME_DELAY) {
-            @Override
-            protected boolean check() {
-                return mMockAlarmReceiver.alarmed;
-            }
-        }.run();
-        assertEquals(mMockAlarmReceiver.rtcTime, mWakeupTime, TIME_DELTA);
-
-        // test parameter type is ELAPSED_REALTIME
-        mMockAlarmReceiver.setAlarmedFalse();
-        mWakeupTime = SystemClock.elapsedRealtime() + SNOOZE_DELAY;
-        mAm.setExact(AlarmManager.ELAPSED_REALTIME, mWakeupTime, mSender);
-        new PollingCheck(SNOOZE_DELAY + TIME_DELAY) {
-            @Override
-            protected boolean check() {
-                return mMockAlarmReceiver.alarmed;
-            }
-        }.run();
-        assertEquals(mMockAlarmReceiver.elapsedTime, mWakeupTime, TIME_DELTA);
-
-        // test parameter type is ELAPSED_REALTIME_WAKEUP
-        mMockAlarmReceiver.setAlarmedFalse();
-        mWakeupTime = SystemClock.elapsedRealtime() + SNOOZE_DELAY;
-        mAm.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, mWakeupTime, mSender);
-        new PollingCheck(SNOOZE_DELAY + TIME_DELAY) {
-            @Override
-            protected boolean check() {
-                return mMockAlarmReceiver.alarmed;
-            }
-        }.run();
-        assertEquals(mMockAlarmReceiver.elapsedTime, mWakeupTime, TIME_DELTA);
-    }
-
-    public void testAlarmTriggersImmediatelyIfSetTimeIsNegative() throws Exception {
-        // An alarm with a negative wakeup time should be triggered immediately.
-        // This exercises a workaround for a limitation of the /dev/alarm driver
-        // that would instead cause such alarms to never be triggered.
-        mMockAlarmReceiver.setAlarmedFalse();
-        mWakeupTime = -1000;
-        mAm.set(AlarmManager.RTC, mWakeupTime, mSender);
-        new PollingCheck(TIME_DELAY) {
-            @Override
-            protected boolean check() {
-                return mMockAlarmReceiver.alarmed;
-            }
-        }.run();
-    }
-
-    public void testExactAlarmBatching() throws Exception {
-        int deliveriesTogether = 0;
-        for (int i = 0; i < NUM_TRIALS; i++) {
-            final long now = System.currentTimeMillis();
-            final long windowStart = now + TEST_ALARM_FUTURITY;
-            final long exactStart = windowStart + TEST_WINDOW_LENGTH - 1;
-
-            mMockAlarmReceiver.setAlarmedFalse();
-            mMockAlarmReceiver2.setAlarmedFalse();
-            mAm.setWindow(AlarmManager.RTC_WAKEUP, windowStart, TEST_WINDOW_LENGTH, mSender);
-            mAm.setExact(AlarmManager.RTC_WAKEUP, exactStart, mSender2);
-
-            // Wait until a half-second beyond its target window, just to provide a
-            // little safety slop.
-            new PollingCheck(TEST_WINDOW_LENGTH + (windowStart - now) + 500) {
-                @Override
-                protected boolean check() {
-                    return mMockAlarmReceiver.alarmed;
-                }
-            }.run();
-
-            // Now wait until 1 sec beyond the expected exact alarm fire time, or for at
-            // least one second if we're already past the nominal exact alarm fire time
-            long timeToExact = Math.max(exactStart - System.currentTimeMillis() + 1000, 1000);
-            new PollingCheck(timeToExact) {
-                @Override
-                protected boolean check() {
-                    return mMockAlarmReceiver2.alarmed;
-                }
-            }.run();
-
-            // Success when we observe that the exact and windowed alarm are not being often
-            // delivered close together -- that is, when we can be confident that they are not
-            // being coalesced.
-            final long delta = Math.abs(mMockAlarmReceiver2.rtcTime - mMockAlarmReceiver.rtcTime);
-            Log.i("TEST", "[" + i + "]  delta = " + delta);
-            if (delta < FAIL_DELTA) {
-                deliveriesTogether++;
-                assertTrue("Exact alarms appear to be coalescing with inexact alarms",
-                        deliveriesTogether <= MAX_NEAR_DELIVERIES);
-            }
-        }
-    }
-
-    public void testSetRepeating() throws Exception {
-        mMockAlarmReceiver.setAlarmedFalse();
-        mWakeupTime = System.currentTimeMillis() + TEST_ALARM_FUTURITY;
-        mAm.setRepeating(AlarmManager.RTC_WAKEUP, mWakeupTime, REPEAT_PERIOD, mSender);
-
-        // wait beyond the initial alarm's possible delivery window to verify that it fires the first time
-        new PollingCheck(TEST_ALARM_FUTURITY + REPEAT_PERIOD) {
-            @Override
-            protected boolean check() {
-                return mMockAlarmReceiver.alarmed;
-            }
-        }.run();
-        assertTrue(mMockAlarmReceiver.alarmed);
-
-        // Now reset the receiver and wait for the intended repeat alarm to fire as expected
-        mMockAlarmReceiver.setAlarmedFalse();
-        new PollingCheck(REPEAT_PERIOD*2) {
-            @Override
-            protected boolean check() {
-                return mMockAlarmReceiver.alarmed;
-            }
-        }.run();
-        assertTrue(mMockAlarmReceiver.alarmed);
-
-        mAm.cancel(mSender);
-    }
-
-    public void testCancel() throws Exception {
-        mMockAlarmReceiver.setAlarmedFalse();
-        mMockAlarmReceiver2.setAlarmedFalse();
-
-        // set two alarms
-        final long when1 = System.currentTimeMillis() + TEST_ALARM_FUTURITY;
-        mAm.setExact(AlarmManager.RTC_WAKEUP, when1, mSender);
-        final long when2 = when1 + TIME_DELTA; // will fire after when1's target time
-        mAm.setExact(AlarmManager.RTC_WAKEUP, when2, mSender2);
-
-        // cancel the earlier one
-        mAm.cancel(mSender);
-
-        // and verify that only the later one fired
-        new PollingCheck(TIME_DELAY) {
-            @Override
-            protected boolean check() {
-                return mMockAlarmReceiver2.alarmed;
-            }
-        }.run();
-
-        assertFalse(mMockAlarmReceiver.alarmed);
-        assertTrue(mMockAlarmReceiver2.alarmed);
-    }
-
-    public void testSetInexactRepeating() throws Exception {
-        mAm.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(),
-                AlarmManager.INTERVAL_FIFTEEN_MINUTES, mSender);
-        SystemClock.setCurrentTimeMillis(System.currentTimeMillis()
-                + AlarmManager.INTERVAL_FIFTEEN_MINUTES);
-        // currently there is no way to write Android system clock. When try to
-        // write the system time, there will be log as
-        // " Unable to open alarm driver: Permission denied". But still fail
-        // after tried many permission.
-    }
-
-    public void testSetAlarmClock() throws Exception {
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
-            mMockAlarmReceiver.setAlarmedFalse();
-            mMockAlarmReceiver2.setAlarmedFalse();
-
-            // Set first alarm clock.
-            final long wakeupTimeFirst = System.currentTimeMillis()
-                    + 2 * TEST_ALARM_FUTURITY;
-            mAm.setAlarmClock(new AlarmClockInfo(wakeupTimeFirst, null), mSender);
-
-            // Verify getNextAlarmClock returns first alarm clock.
-            AlarmClockInfo nextAlarmClock = mAm.getNextAlarmClock();
-            assertEquals(wakeupTimeFirst, nextAlarmClock.getTriggerTime());
-            assertNull(nextAlarmClock.getShowIntent());
-
-            // Set second alarm clock, earlier than first.
-            final long wakeupTimeSecond = System.currentTimeMillis()
-                    + TEST_ALARM_FUTURITY;
-            PendingIntent showIntentSecond = PendingIntent.getBroadcast(getContext(), 0,
-                    new Intent(getContext(), AlarmManagerTest.class).setAction("SHOW_INTENT"), 0);
-            mAm.setAlarmClock(new AlarmClockInfo(wakeupTimeSecond, showIntentSecond),
-                    mSender2);
-
-            // Verify getNextAlarmClock returns second alarm clock now.
-            nextAlarmClock = mAm.getNextAlarmClock();
-            assertEquals(wakeupTimeSecond, nextAlarmClock.getTriggerTime());
-            assertEquals(showIntentSecond, nextAlarmClock.getShowIntent());
-
-            // Cancel second alarm.
-            mAm.cancel(mSender2);
-
-            // Verify getNextAlarmClock returns first alarm clock again.
-            nextAlarmClock = mAm.getNextAlarmClock();
-            assertEquals(wakeupTimeFirst, nextAlarmClock.getTriggerTime());
-            assertNull(nextAlarmClock.getShowIntent());
-
-            // Wait for first alarm to trigger.
-            assertFalse(mMockAlarmReceiver.alarmed);
-            new PollingCheck(2 * TEST_ALARM_FUTURITY + TIME_DELAY) {
-                @Override
-                protected boolean check() {
-                    return mMockAlarmReceiver.alarmed;
-                }
-            }.run();
-
-            // Verify first alarm fired at the right time.
-            assertEquals(mMockAlarmReceiver.rtcTime, wakeupTimeFirst, TIME_DELTA);
-
-            // Verify second alarm didn't fire.
-            assertFalse(mMockAlarmReceiver2.alarmed);
-
-            // Verify the next alarm is not returning neither the first nor the second alarm.
-            nextAlarmClock = mAm.getNextAlarmClock();
-            MoreAsserts.assertNotEqual(wakeupTimeFirst, nextAlarmClock != null
-                    ? nextAlarmClock.getTriggerTime()
-                    : null);
-            MoreAsserts.assertNotEqual(wakeupTimeSecond, nextAlarmClock != null
-                    ? nextAlarmClock.getTriggerTime()
-                    : null);
-        }
-    }
-}
diff --git a/tests/tests/app/src/android/app/cts/AlertDialogTest.java b/tests/tests/app/src/android/app/cts/AlertDialogTest.java
deleted file mode 100644
index 3e9f3b2..0000000
--- a/tests/tests/app/src/android/app/cts/AlertDialogTest.java
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-
-import android.app.AlertDialog;
-import android.app.Instrumentation;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.DialogInterface.OnCancelListener;
-import android.content.DialogInterface.OnClickListener;
-import android.cts.util.PollingCheck;
-import android.graphics.drawable.Drawable;
-import android.os.Bundle;
-import android.os.Message;
-import android.test.ActivityInstrumentationTestCase2;
-import android.view.KeyEvent;
-import android.view.View;
-import android.widget.Button;
-
-/*
- * Test AlertDialog
- */
-public class AlertDialogTest extends ActivityInstrumentationTestCase2<DialogStubActivity> {
-    private static final String ALERTDIALOG_CUSTOM_TITLE = "Hello, World!";
-
-    private Instrumentation mInstrumentation;
-    private DialogStubActivity mActivity;
-    private Button mPositiveButton;
-    private Button mNegativeButton;
-    private Button mNeutralButton;
-
-    public AlertDialogTest() {
-        super("com.android.cts.app.stub", DialogStubActivity.class);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mInstrumentation = getInstrumentation();
-    }
-
-    protected void startDialogActivity(int dialogNumber) {
-        mActivity = DialogStubActivity.startDialogActivity(this, dialogNumber);
-        new PollingCheck() {
-            @Override
-            protected boolean check() {
-                return mActivity.getDialog().isShowing();
-            }
-        }.run();
-    }
-
-    public void testAlertDialog() throws Throwable {
-        doTestAlertDialog(DialogStubActivity.TEST_ALERTDIALOG);
-    }
-
-    private void doTestAlertDialog(int index) throws Throwable {
-        startDialogActivity(index);
-        assertTrue(mActivity.getDialog().isShowing());
-
-        mPositiveButton = ((AlertDialog) (mActivity.getDialog())).getButton(
-                DialogInterface.BUTTON_POSITIVE);
-        assertNotNull(mPositiveButton);
-        assertEquals(mActivity.getString(com.android.cts.app.stub.R.string.alert_dialog_positive),
-                mPositiveButton.getText());
-        mNeutralButton = ((AlertDialog) (mActivity.getDialog())).getButton(
-                DialogInterface.BUTTON_NEUTRAL);
-        assertNotNull(mNeutralButton);
-        assertEquals(mActivity.getString(com.android.cts.app.stub.R.string.alert_dialog_neutral),
-                mNeutralButton.getText());
-        mNegativeButton = ((AlertDialog) (mActivity.getDialog())).getButton(
-                DialogInterface.BUTTON_NEGATIVE);
-        assertNotNull(mNegativeButton);
-        assertEquals(mActivity.getString(com.android.cts.app.stub.R.string.alert_dialog_negative),
-                mNegativeButton.getText());
-
-        assertFalse(mActivity.isPositiveButtonClicked);
-        performClick(mPositiveButton);
-        assertTrue(mActivity.isPositiveButtonClicked);
-
-        assertFalse(mActivity.isNegativeButtonClicked);
-        performClick(mNegativeButton);
-        assertTrue(mActivity.isNegativeButtonClicked);
-
-        assertFalse(mActivity.isNeutralButtonClicked);
-        performClick(mNeutralButton);
-        assertTrue(mActivity.isNeutralButtonClicked);
-    }
-
-    public void testAlertDialogDeprecatedAPI() throws Throwable {
-        doTestAlertDialog(DialogStubActivity.TEST_ALERTDIALOG_DEPRECATED);
-    }
-
-    public void testAlertDialogDeprecatedAPIWithMessage() throws Throwable {
-        startDialogActivity(DialogStubActivity.TEST_ALERTDIALOG_DEPRECATED_WITH_MESSAGE);
-        assertTrue(mActivity.getDialog().isShowing());
-
-        mPositiveButton = ((AlertDialog) (mActivity.getDialog())).getButton(
-                DialogInterface.BUTTON_POSITIVE);
-        assertNotNull(mPositiveButton);
-        assertEquals(mActivity.getString(com.android.cts.app.stub.R.string.alert_dialog_positive),
-                mPositiveButton.getText());
-        mNegativeButton = ((AlertDialog) (mActivity.getDialog())).getButton(
-                DialogInterface.BUTTON_NEGATIVE);
-        assertNotNull(mNegativeButton);
-        assertEquals(mActivity.getString(com.android.cts.app.stub.R.string.alert_dialog_negative),
-                mNegativeButton.getText());
-        mNeutralButton = ((AlertDialog) (mActivity.getDialog())).getButton(
-                DialogInterface.BUTTON_NEUTRAL);
-        assertNotNull(mNeutralButton);
-        assertEquals(mActivity.getString(com.android.cts.app.stub.R.string.alert_dialog_neutral),
-                mNeutralButton.getText());
-
-        DialogStubActivity.buttonIndex = 0;
-        performClick(mPositiveButton);
-        assertEquals(DialogInterface.BUTTON_POSITIVE, DialogStubActivity.buttonIndex);
-
-        DialogStubActivity.buttonIndex = 0;
-        performClick(mNeutralButton);
-        assertEquals(DialogInterface.BUTTON_NEUTRAL, DialogStubActivity.buttonIndex);
-
-        DialogStubActivity.buttonIndex = 0;
-        performClick(mNegativeButton);
-        assertEquals(DialogInterface.BUTTON_NEGATIVE, DialogStubActivity.buttonIndex);
-    }
-
-    private void performClick(final Button button) throws Throwable {
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-                button.performClick();
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-    }
-
-    public void testCustomAlertDialog() {
-        startDialogActivity(DialogStubActivity.TEST_CUSTOM_ALERTDIALOG);
-        assertTrue(mActivity.getDialog().isShowing());
-    }
-
-    public void testCustomAlertDialogView() {
-        startDialogActivity(DialogStubActivity.TEST_CUSTOM_ALERTDIALOG_VIEW);
-        assertTrue(mActivity.getDialog().isShowing());
-    }
-
-
-    public void testCallback() {
-        startDialogActivity(DialogStubActivity.TEST_ALERTDIALOG_CALLBACK);
-        assertTrue(mActivity.onCreateCalled);
-
-        mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_0);
-        assertTrue(mActivity.onKeyDownCalled);
-        mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_0);
-        assertTrue(mActivity.onKeyUpCalled);
-    }
-
-    public void testAlertDialogTheme() throws Exception {
-        startDialogActivity(DialogStubActivity.TEST_ALERTDIALOG_THEME);
-        assertTrue(mActivity.getDialog().isShowing());
-    }
-
-    public void testAlertDialogCancelable() throws Exception {
-        startDialogActivity(DialogStubActivity.TEST_ALERTDIALOG_CANCELABLE);
-        assertTrue(mActivity.getDialog().isShowing());
-        assertFalse(mActivity.onCancelCalled);
-        mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_BACK);
-        mInstrumentation.waitForIdleSync();
-        assertTrue(mActivity.onCancelCalled);
-    }
-
-    public void testAlertDialogNotCancelable() throws Exception {
-        startDialogActivity(DialogStubActivity.TEST_ALERTDIALOG_NOT_CANCELABLE);
-        assertTrue(mActivity.getDialog().isShowing());
-        assertFalse(mActivity.onCancelCalled);
-        mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_BACK);
-        assertFalse(mActivity.onCancelCalled);
-    }
-}
diff --git a/tests/tests/app/src/android/app/cts/AlertDialog_BuilderTest.java b/tests/tests/app/src/android/app/cts/AlertDialog_BuilderTest.java
deleted file mode 100644
index 58e69b8..0000000
--- a/tests/tests/app/src/android/app/cts/AlertDialog_BuilderTest.java
+++ /dev/null
@@ -1,667 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-import java.util.ArrayList;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.app.Instrumentation;
-import android.app.AlertDialog.Builder;
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.DialogInterface.OnCancelListener;
-import android.content.DialogInterface.OnClickListener;
-import android.content.DialogInterface.OnKeyListener;
-import android.content.DialogInterface.OnMultiChoiceClickListener;
-import android.cts.util.PollingCheck;
-import android.database.Cursor;
-import android.database.CursorWrapper;
-import android.graphics.drawable.Drawable;
-import android.provider.Contacts.People;
-import android.test.ActivityInstrumentationTestCase2;
-import android.view.KeyEvent;
-import android.view.View;
-import android.widget.AdapterView;
-import android.widget.ArrayAdapter;
-import android.widget.Button;
-import android.widget.FrameLayout;
-import android.widget.ListAdapter;
-import android.widget.ListView;
-import android.widget.AdapterView.OnItemSelectedListener;
-
-
-public class AlertDialog_BuilderTest extends ActivityInstrumentationTestCase2<DialogStubActivity> {
-    private Builder mBuilder;
-    private Context mContext;
-    private Instrumentation mInstrumentation;
-    private final CharSequence mTitle = "title";
-    private Drawable mDrawable;
-    private AlertDialog mDialog;
-    private Button mButton;
-    private boolean mResult;
-    private boolean mItemSelected;
-    private CharSequence mSelectedItem;
-    private final String[] mPROJECTION = new String[] {
-            People._ID, People.NAME
-    };
-
-    private View mView;
-    private ListView mListView;
-    private ArrayList<Integer> mSelectedItems;
-    private FrameLayout mFrameLayout;
-
-    private OnClickListener mOnClickListener = new OnClickListener() {
-        public void onClick(DialogInterface dialog, int which) {
-            mResult = true;
-        }
-    };
-
-    private OnCancelListener mOnCancelListener = new OnCancelListener() {
-        public void onCancel(DialogInterface dialog) {
-            mResult = true;
-        }
-    };
-
-    private OnKeyListener mOnKeyListener = new OnKeyListener() {
-        public boolean onKey(DialogInterface dialog, int key, KeyEvent envnt) {
-            mResult = true;
-            return true;
-        }
-    };
-
-    private OnItemSelectedListener mOnItemSelectedListener = new OnItemSelectedListener() {
-        public void onItemSelected(AdapterView parent, View v, int position, long id) {
-            mItemSelected = true;
-        }
-
-        public void onNothingSelected(AdapterView parent) {
-        }
-
-    };
-
-    private OnMultiChoiceClickListener mOnMultiChoiceClickListener =
-        new OnMultiChoiceClickListener() {
-        public void onClick(DialogInterface dialog, int which, boolean isChecked) {
-            mSelectedItems.add(which);
-            mResult = true;
-        }
-    };
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mBuilder = null;
-        mInstrumentation = getInstrumentation();
-        mContext = getActivity();
-        final Activity activity = getActivity();
-        new PollingCheck() {
-            @Override
-            protected boolean check() {
-                return activity.hasWindowFocus();
-            }
-        }.run();
-        mButton = null;
-        mView = null;
-        mListView = null;
-        mDialog = null;
-        mItemSelected = false;
-        mSelectedItem = null;
-        mSelectedItems = new ArrayList<Integer>();
-    }
-
-    public AlertDialog_BuilderTest() {
-        super("com.android.cts.app.stub", DialogStubActivity.class);
-    }
-
-    public void testConstructor() {
-        new AlertDialog.Builder(mContext);
-    }
-
-    public void testSetIconWithParamInt() throws Throwable {
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-                mDrawable = mContext.getResources().getDrawable(android.R.drawable.btn_default);
-                mBuilder = new AlertDialog.Builder(mContext);
-                mBuilder.setIcon(android.R.drawable.btn_default);
-                mDialog = mBuilder.show();
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-    }
-
-    public void testSetIconWithParamDrawable() throws Throwable {
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-                mDrawable = mContext.getResources().getDrawable(android.R.drawable.btn_default);
-                mBuilder = new AlertDialog.Builder(mContext);
-                mBuilder.setIcon(mDrawable);
-                mDialog = mBuilder.show();
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-    }
-
-    public void testSetPositiveButtonWithParamInt() throws Throwable {
-       runTestOnUiThread(new Runnable() {
-            public void run() {
-                mBuilder = new AlertDialog.Builder(mContext);
-                mBuilder.setPositiveButton(android.R.string.yes, mOnClickListener);
-                mDialog = mBuilder.show();
-                mButton = mDialog.getButton(DialogInterface.BUTTON_POSITIVE);
-                mButton.performClick();
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-
-        assertEquals(mContext.getText(android.R.string.yes), mButton.getText());
-        assertTrue(mResult);
-    }
-
-    public void testSetPositiveButtonWithParamCharSequence() throws Throwable {
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-                mBuilder = new AlertDialog.Builder(mContext);
-                mBuilder.setPositiveButton(android.R.string.yes, mOnClickListener);
-                mDialog = mBuilder.show();
-                mButton = mDialog.getButton(DialogInterface.BUTTON_POSITIVE);
-                mButton.performClick();
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-        assertEquals(mContext.getText(android.R.string.yes), mButton.getText());
-        assertTrue(mResult);
-    }
-
-    public void testSetNegativeButtonWithParamCharSequence() throws Throwable {
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-                mBuilder = new AlertDialog.Builder(mContext);
-                mBuilder.setNegativeButton(mTitle, mOnClickListener);
-                mDialog = mBuilder.show();
-                mButton = mDialog.getButton(DialogInterface.BUTTON_NEGATIVE);
-                mButton.performClick();
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-        assertEquals(mTitle, mButton.getText());
-        assertTrue(mResult);
-    }
-
-    public void testSetNegativeButtonWithParamInt() throws Throwable {
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-                mBuilder = new AlertDialog.Builder(mContext);
-                mBuilder.setNegativeButton(com.android.cts.app.stub.R.string.notify, mOnClickListener);
-                mDialog = mBuilder.show();
-                mButton = mDialog.getButton(DialogInterface.BUTTON_NEGATIVE);
-                mButton.performClick();
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-        assertEquals(mContext.getText(com.android.cts.app.stub.R.string.notify), mButton.getText());
-        assertTrue(mResult);
-    }
-
-    public void testSetNeutralButtonWithParamInt() throws Throwable {
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-                mBuilder = new AlertDialog.Builder(mContext);
-                mBuilder.setNeutralButton(com.android.cts.app.stub.R.string.notify, mOnClickListener);
-                mDialog = mBuilder.show();
-                mButton = mDialog.getButton(DialogInterface.BUTTON_NEUTRAL);
-                mButton.performClick();
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-        assertEquals(mContext.getText(com.android.cts.app.stub.R.string.notify), mButton.getText());
-        assertTrue(mResult);
-    }
-
-    public void testSetNeutralButtonWithParamCharSequence() throws Throwable {
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-                mBuilder = new AlertDialog.Builder(mContext);
-                mBuilder.setNeutralButton(mTitle, mOnClickListener);
-                mDialog = mBuilder.show();
-                mButton = mDialog.getButton(DialogInterface.BUTTON_NEUTRAL);
-                mButton.performClick();
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-        assertEquals(mTitle, mButton.getText());
-        assertTrue(mResult);
-    }
-
-    private void testCancelable(final boolean cancelable) throws Throwable {
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-                mBuilder = new AlertDialog.Builder(mContext);
-                mBuilder.setCancelable(cancelable);
-                mDialog = mBuilder.show();
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-        new PollingCheck() {
-            @Override
-            protected boolean check() {
-                return mDialog.isShowing();
-            }
-        }.run();
-        mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_BACK);
-        mInstrumentation.waitForIdleSync();
-        new PollingCheck() {
-            @Override
-            protected boolean check() {
-                boolean showing = mDialog.isShowing();
-                if (cancelable) {
-                    // if the dialog is cancelable, then pressing back
-                    // should cancel it. Thus it should not be showing
-                    return !showing;
-                } else {
-                    // if the dialog is not cancelable, pressing back
-                    // should so nothing and it should still be showing
-                    return showing;
-                }
-            }
-        }.run();
-    }
-
-    public void testSetCancelable() throws Throwable {
-        testCancelable(true);
-    }
-
-    public void testDisableCancelable() throws Throwable {
-        testCancelable(false);
-    }
-
-    public void testSetOnCancelListener() throws Throwable {
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-                mBuilder = new AlertDialog.Builder(mContext);
-                mBuilder.setOnCancelListener(mOnCancelListener);
-                mDialog = mBuilder.show();
-                mDialog.cancel();
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-        assertTrue(mResult);
-    }
-
-    public void testSetOnKeyListener() throws Throwable {
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-                mBuilder = new AlertDialog.Builder(mContext);
-                mBuilder.setOnKeyListener(mOnKeyListener);
-                mDialog = mBuilder.show();
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-        sendKeys(KeyEvent.ACTION_DOWN, KeyEvent.ACTION_DOWN);
-        assertTrue(mResult);
-    }
-
-    public void testSetItemsWithParamInt() throws Throwable {
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-                mBuilder = new AlertDialog.Builder(mContext);
-                mBuilder.setItems(com.android.cts.app.stub.R.array.difficultyLevel, mOnClickListener);
-                mDialog = mBuilder.show();
-                mListView = mDialog.getListView();
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-
-        final CharSequence[] levels = mContext.getResources().getTextArray(
-                com.android.cts.app.stub.R.array.difficultyLevel);
-        assertEquals(levels[0], mListView.getItemAtPosition(0));
-    }
-
-    public void testSetItemsWithParamCharSequence() throws Throwable {
-        final CharSequence[] expect = mContext.getResources().getTextArray(
-                com.android.cts.app.stub.R.array.difficultyLevel);
-
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-                mBuilder = new AlertDialog.Builder(mContext);
-                mBuilder.setItems(expect, mOnClickListener);
-                mDialog = mBuilder.show();
-                mListView = mDialog.getListView();
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-        assertEquals(expect[0], mListView.getItemAtPosition(0));
-    }
-
-    public void testSetAdapter() throws Throwable {
-        final ListAdapter adapter = new AdapterTest();
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-                mBuilder = new AlertDialog.Builder(mContext);
-                mBuilder.setAdapter(adapter, mOnClickListener);
-                mDialog = mBuilder.show();
-                mListView = mDialog.getListView();
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-        assertEquals(adapter, mListView.getAdapter());
-    }
-
-    public void testSetCursor() throws Throwable {
-        preparePeople();
-        final Cursor c = mContext.getContentResolver().query(People.CONTENT_URI, mPROJECTION, null,
-                null, null);
-
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-                mBuilder = new AlertDialog.Builder(mContext);
-                mBuilder.setCursor(c, mOnClickListener, People.NAME);
-                mDialog = mBuilder.show();
-                mListView = mDialog.getListView();
-                mListView.performItemClick(null, 0, 0);
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-        final CursorWrapper selected = (CursorWrapper)mListView.getSelectedItem();
-        assertEquals(c.getString(1), selected.getString(1));
-        assertTrue(mResult);
-    }
-
-    public void testSetMultiChoiceItemsWithParamInt() throws Throwable {
-
-        final CharSequence[] items = mContext.getResources().getTextArray(
-                com.android.cts.app.stub.R.array.difficultyLevel);
-
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-                mBuilder = new AlertDialog.Builder(mContext);
-                mBuilder.setMultiChoiceItems(com.android.cts.app.stub.R.array.difficultyLevel, null,
-                        mOnMultiChoiceClickListener);
-                mDialog = mBuilder.show();
-                mListView = mDialog.getListView();
-                mSelectedItem = (CharSequence)mListView.getSelectedItem();
-                mListView.performItemClick(null, 0, 0);
-                mListView.performItemClick(null, 1, 0);
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-        assertEquals(items[0], mSelectedItem);
-        assertEquals(2, mSelectedItems.size());
-        assertEquals(items[0], mListView.getItemAtPosition(0));
-        assertTrue(mResult);
-    }
-
-    public void testSetMultiChoiceItemsWithParamCharSequence() throws Throwable {
-        final CharSequence[] items = mContext.getResources().getTextArray(
-                com.android.cts.app.stub.R.array.difficultyLevel);
-
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-                mBuilder = new AlertDialog.Builder(mContext);
-                mBuilder.setMultiChoiceItems(items, null, mOnMultiChoiceClickListener);
-                mDialog = mBuilder.show();
-                mListView = mDialog.getListView();
-                mSelectedItem = (CharSequence)mListView.getSelectedItem();
-                mListView.performItemClick(null, 0, 0);
-                mListView.performItemClick(null, 1, 0);
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-        assertEquals(items[0], mSelectedItem);
-        assertEquals(2, mSelectedItems.size());
-        assertEquals(items[0], mListView.getItemAtPosition(0));
-        assertTrue(mResult);
-    }
-
-    public void testSetMultiChoiceItemsWithParamCursor() throws Throwable {
-        preparePeople();
-        final Cursor c = mContext.getContentResolver().query(People.CONTENT_URI, mPROJECTION, null,
-                null, null);
-
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-                mBuilder = new AlertDialog.Builder(mContext);
-                mBuilder.setMultiChoiceItems(c, People.NAME, People.NAME,
-                        mOnMultiChoiceClickListener);
-                mDialog = mBuilder.show();
-                mListView = mDialog.getListView();
-                mListView.performItemClick(null, 0, 0);
-                mListView.performItemClick(null, 1, 0);
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-        final CursorWrapper selected = (CursorWrapper)mListView.getSelectedItem();
-        assertEquals(c.getString(1), selected.getString(1));
-        assertEquals(2, mSelectedItems.size());
-        assertTrue(mResult);
-    }
-
-    public void testSetSingleChoiceItemsWithParamInt() throws Throwable {
-        final CharSequence[] items = mContext.getResources().getTextArray(
-                com.android.cts.app.stub.R.array.difficultyLevel);
-
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-                mBuilder = new AlertDialog.Builder(mContext);
-                mBuilder.setSingleChoiceItems(com.android.cts.app.stub.R.array.difficultyLevel, 0,
-                        mOnClickListener);
-                mDialog = mBuilder.show();
-                mListView = mDialog.getListView();
-                mSelectedItem = (CharSequence)mListView.getSelectedItem();
-                mListView.performItemClick(null, 0, 0);
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-        assertEquals(items[0], mSelectedItem);
-        assertEquals(items[0], mListView.getItemAtPosition(0));
-        assertTrue(mResult);
-    }
-
-    private void preparePeople() {
-        final ContentResolver mResolver = mContext.getContentResolver();
-        mResolver.delete(People.CONTENT_URI, null, null);
-        final ContentValues valuse = new ContentValues();
-        valuse.put(People._ID, "1");
-        valuse.put(People.NAME, "name");
-        mResolver.insert(People.CONTENT_URI, valuse);
-    }
-
-    public void testSetSingleChoiceItemsWithParamCursor() throws Throwable {
-        final String[] PROJECTION = new String[] {
-                People._ID, People.NAME
-        };
-        preparePeople();
-        final Cursor c = mContext.getContentResolver().query(People.CONTENT_URI, PROJECTION, null,
-                null, null);
-
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-                mBuilder = new AlertDialog.Builder(mContext);
-                mBuilder.setSingleChoiceItems(c, 0, People.NAME, mOnClickListener);
-                mDialog = mBuilder.show();
-                mListView = mDialog.getListView();
-                mListView.performItemClick(null, 0, 0);
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-        final CursorWrapper selected = (CursorWrapper)mListView.getSelectedItem();
-        assertEquals(c.getString(1), selected.getString(1));
-        assertTrue(mResult);
-    }
-
-    public void testSetSingleChoiceItemsWithParamCharSequence() throws Throwable {
-        final CharSequence[] items = mContext.getResources().getTextArray(
-                com.android.cts.app.stub.R.array.difficultyLevel);
-
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-                mBuilder = new AlertDialog.Builder(mContext);
-                mBuilder.setSingleChoiceItems(items, 0, mOnClickListener);
-                mDialog = mBuilder.show();
-                mListView = mDialog.getListView();
-                mSelectedItem = (CharSequence)mListView.getSelectedItem();
-                mListView.performItemClick(null, 0, 0);
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-        assertEquals(items[0], mSelectedItem);
-        assertEquals(items[0], mListView.getItemAtPosition(0));
-        assertTrue(mResult);
-    }
-
-    public void testSetSingleChoiceItems() throws Throwable {
-        final CharSequence[] items = mContext.getResources().getTextArray(
-                com.android.cts.app.stub.R.array.difficultyLevel);
-
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-                mBuilder = new AlertDialog.Builder(mContext);
-                mBuilder.setSingleChoiceItems(new ArrayAdapter<CharSequence>(mContext,
-                        android.R.layout.select_dialog_singlechoice, android.R.id.text1, items), 0,
-                        mOnClickListener);
-                mDialog = mBuilder.show();
-                mListView = mDialog.getListView();
-                mSelectedItem = (CharSequence)mListView.getSelectedItem();
-                mListView.performItemClick(null, 0, 0);
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-        assertEquals(items[0], mSelectedItem);
-        assertEquals(items[0], mListView.getItemAtPosition(0));
-        assertTrue(mResult);
-    }
-
-    public void testSetOnItemSelectedListener() throws Throwable {
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-                mBuilder = new AlertDialog.Builder(mContext);
-                mBuilder.setOnItemSelectedListener(mOnItemSelectedListener);
-                mBuilder.setItems(com.android.cts.app.stub.R.array.difficultyLevel, mOnClickListener);
-                mDialog = mBuilder.show();
-                mListView = mDialog.getListView();
-                mListView.pointToPosition(0, 0);
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-        assertTrue(mItemSelected);
-    }
-
-    public void testSetView() throws Throwable {
-        final View view = new View(mContext);
-        view.setId(100);
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-                mBuilder = new AlertDialog.Builder(mContext);
-                mBuilder.setView(view);
-                mDialog = mBuilder.show();
-                mView = mDialog.getWindow().findViewById(100);
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-        assertEquals(view, mView);
-    }
-
-    public void testSetInverseBackgroundForced() throws Throwable {
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-                mBuilder = new AlertDialog.Builder(mContext);
-                mBuilder.setInverseBackgroundForced(true);
-                mDialog = mBuilder.create();
-                mDialog.show();
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-    }
-
-    public void testCreate() throws Throwable {
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-                mBuilder = new AlertDialog.Builder(mContext);
-                mDialog = mBuilder.create();
-                mDialog.show();
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-        assertNotNull(mDialog);
-        assertTrue(mDialog.isShowing());
-    }
-
-    public void testShow() throws Throwable {
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-                mBuilder = new AlertDialog.Builder(mContext);
-                mDialog = mBuilder.show();
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-        assertTrue(mDialog.isShowing());
-    }
-
-    private static class AdapterTest implements android.widget.ListAdapter {
-        public boolean areAllItemsEnabled() {
-            return true;
-        }
-
-        public boolean isEnabled(int position) {
-            return false;
-        }
-
-        public int getCount() {
-            return 0;
-        }
-
-        public Object getItem(int position) {
-            return null;
-        }
-
-        public long getItemId(int position) {
-            return 0;
-        }
-
-        public int getItemViewType(int position) {
-            return 0;
-        }
-
-        public android.view.View getView( int position,
-                                          android.view.View convertView,
-                                          android.view.ViewGroup parent){
-            return null;
-        }
-
-        public int getViewTypeCount() {
-            return 1;
-        }
-
-        public boolean hasStableIds() {
-            return false;
-        }
-
-        public boolean isEmpty() {
-            return true;
-        }
-
-        public void registerDataSetObserver(
-            android.database.DataSetObserver observer) {
-        }
-
-        public void unregisterDataSetObserver(
-            android.database.DataSetObserver observer) {
-        }
-    }
-}
diff --git a/tests/tests/app/src/android/app/cts/AliasActivityTest.java b/tests/tests/app/src/android/app/cts/AliasActivityTest.java
deleted file mode 100644
index d44050f..0000000
--- a/tests/tests/app/src/android/app/cts/AliasActivityTest.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-import android.app.AliasActivity;
-import android.app.Instrumentation;
-import android.content.Context;
-import android.content.Intent;
-import android.test.InstrumentationTestCase;
-
-public class AliasActivityTest extends InstrumentationTestCase {
-
-    private static final long SLEEP_TIME = 1000;
-
-    public void testAliasActivity() throws Throwable {
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-                new AliasActivity();
-            }
-        });
-        getInstrumentation().waitForIdleSync();
-        Context context = getInstrumentation().getTargetContext();
-
-        Intent intent = new Intent();
-        intent.setClass(context, AliasActivityStub.class);
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-
-        assertFalse(ChildActivity.isStarted);
-        assertFalse(AliasActivityStub.isOnCreateCalled);
-        context.startActivity(intent);
-        Thread.sleep(SLEEP_TIME);
-        assertTrue(AliasActivityStub.isOnCreateCalled);
-        assertTrue(ChildActivity.isStarted);
-        assertTrue(AliasActivityStub.isFinished);
-    }
-
-}
diff --git a/tests/tests/app/src/android/app/cts/ApplicationTest.java b/tests/tests/app/src/android/app/cts/ApplicationTest.java
deleted file mode 100644
index 99cc8ba..0000000
--- a/tests/tests/app/src/android/app/cts/ApplicationTest.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-
-import android.app.Activity;
-import android.app.Application;
-import android.app.Instrumentation;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.test.InstrumentationTestCase;
-
-/**
- * Test {@link Application}.
- */
-public class ApplicationTest extends InstrumentationTestCase {
-
-    public void testApplication() throws Throwable {
-        final Instrumentation instrumentation = getInstrumentation();
-        final Context targetContext = instrumentation.getTargetContext();
-
-        final Intent intent = new Intent(targetContext, MockApplicationActivity.class);
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-
-        final Activity activity = instrumentation.startActivitySync(intent);
-        final MockApplication mockApp = (MockApplication) activity.getApplication();
-        assertTrue(mockApp.isConstructorCalled);
-        assertTrue(mockApp.isOnCreateCalled);
-
-        //skip if the device doesn't support both of portrait and landscape orientation screens.
-        final PackageManager pm = targetContext.getPackageManager();
-        if(!(pm.hasSystemFeature(PackageManager.FEATURE_SCREEN_LANDSCAPE)
-                && pm.hasSystemFeature(PackageManager.FEATURE_SCREEN_PORTRAIT))){
-            return;
-        }
-
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-               OrientationTestUtils.toggleOrientation(activity);
-            }
-        });
-        instrumentation.waitForIdleSync();
-        assertTrue(mockApp.isOnConfigurationChangedCalled);
-    }
-
-}
diff --git a/tests/tests/app/src/android/app/cts/ApplyOverrideConfigurationActivity.java b/tests/tests/app/src/android/app/cts/ApplyOverrideConfigurationActivity.java
new file mode 100644
index 0000000..305d0a8
--- /dev/null
+++ b/tests/tests/app/src/android/app/cts/ApplyOverrideConfigurationActivity.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES 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.app.cts;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.res.Configuration;
+
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.Future;
+
+public class ApplyOverrideConfigurationActivity extends Activity {
+    public static final int OVERRIDE_SMALLEST_WIDTH = 99999;
+
+    private CompletableFuture<Configuration> mOnConfigurationChangedFuture = null;
+
+    @Override
+    protected void attachBaseContext(Context newBase) {
+        super.attachBaseContext(newBase);
+
+        final Configuration overrideConfig = new Configuration();
+        overrideConfig.smallestScreenWidthDp = OVERRIDE_SMALLEST_WIDTH;
+        applyOverrideConfiguration(overrideConfig);
+    }
+
+    @Override
+    public void onConfigurationChanged(Configuration newConfig) {
+        super.onConfigurationChanged(newConfig);
+
+        synchronized (this) {
+            if (mOnConfigurationChangedFuture != null) {
+                mOnConfigurationChangedFuture.complete(new Configuration(newConfig));
+                mOnConfigurationChangedFuture = null;
+            }
+        }
+    }
+
+    /**
+     * Hands back a Future that will be completed when onConfigurationChanged() is called.
+     * It will only report a single call to onConfigurationChanged(). Subsequent calls can be
+     * captured by calling this method again. Calling this method will cancel all past
+     * Futures received from this method.
+     * @return A Future that completes with the configuration passed in to onConfigurationChanged().
+     */
+    public synchronized Future<Configuration> watchForSingleOnConfigurationChangedCallback() {
+        if (mOnConfigurationChangedFuture != null) {
+            mOnConfigurationChangedFuture.cancel(true);
+        }
+
+        mOnConfigurationChangedFuture = new CompletableFuture<>();
+        return mOnConfigurationChangedFuture;
+    }
+}
diff --git a/tests/tests/app/src/android/app/cts/ApplyOverrideConfigurationTest.java b/tests/tests/app/src/android/app/cts/ApplyOverrideConfigurationTest.java
new file mode 100644
index 0000000..a8f1473
--- /dev/null
+++ b/tests/tests/app/src/android/app/cts/ApplyOverrideConfigurationTest.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES 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.app.cts;
+
+import android.app.UiAutomation;
+import android.content.res.Configuration;
+import android.support.test.filters.SmallTest;
+import android.test.ActivityInstrumentationTestCase2;
+
+import java.util.concurrent.Future;
+
+/**
+ * Tests the {@link android.view.ContextThemeWrapper#applyOverrideConfiguration(Configuration)}
+ * method and how it affects the Activity's resources and lifecycle callbacks.
+ */
+public class ApplyOverrideConfigurationTest extends
+        ActivityInstrumentationTestCase2<ApplyOverrideConfigurationActivity> {
+    public ApplyOverrideConfigurationTest() {
+        super(ApplyOverrideConfigurationActivity.class);
+    }
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        getInstrumentation().getUiAutomation().setRotation(UiAutomation.ROTATION_FREEZE_0);
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        getInstrumentation().getUiAutomation().setRotation(UiAutomation.ROTATION_UNFREEZE);
+        super.tearDown();
+    }
+
+    @SmallTest
+    public void testOverriddenConfigurationIsPassedIntoCallback() throws Exception {
+        final Configuration config = getActivity().getResources().getConfiguration();
+        final int originalOrientation = config.orientation;
+        assertEquals(ApplyOverrideConfigurationActivity.OVERRIDE_SMALLEST_WIDTH,
+                config.smallestScreenWidthDp);
+
+        Future<Configuration> callback =
+                getActivity().watchForSingleOnConfigurationChangedCallback();
+
+        getInstrumentation().getUiAutomation().setRotation(UiAutomation.ROTATION_FREEZE_90);
+
+        final Configuration callbackConfig = callback.get();
+        assertNotNull(callbackConfig);
+
+        final Configuration newConfig = getActivity().getResources().getConfiguration();
+        assertTrue(newConfig.orientation != originalOrientation);
+        assertEquals(ApplyOverrideConfigurationActivity.OVERRIDE_SMALLEST_WIDTH,
+                newConfig.smallestScreenWidthDp);
+
+        assertEquals(newConfig, callbackConfig);
+    }
+}
diff --git a/tests/tests/app/src/android/app/cts/DialogTest.java b/tests/tests/app/src/android/app/cts/DialogTest.java
deleted file mode 100755
index 4e8d588..0000000
--- a/tests/tests/app/src/android/app/cts/DialogTest.java
+++ /dev/null
@@ -1,937 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-import com.android.cts.app.stub.R;
-
-import android.app.Dialog;
-import android.app.Instrumentation;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.DialogInterface.OnCancelListener;
-import android.content.DialogInterface.OnDismissListener;
-import android.content.DialogInterface.OnKeyListener;
-import android.content.pm.PackageManager;
-import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.cts.util.PollingCheck;
-import android.graphics.Canvas;
-import android.graphics.ColorFilter;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.os.Message;
-import android.os.SystemClock;
-import android.test.ActivityInstrumentationTestCase2;
-import android.test.UiThreadTest;
-import android.view.KeyEvent;
-import android.view.LayoutInflater;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.Window;
-import android.view.WindowManager;
-import android.widget.LinearLayout;
-
-import java.lang.ref.WeakReference;
-
-public class DialogTest extends ActivityInstrumentationTestCase2<DialogStubActivity> {
-
-    protected static final long SLEEP_TIME = 200;
-    private static final String STUB_ACTIVITY_PACKAGE = "com.android.cts.app.stub";
-    private static final long TEST_TIMEOUT = 1000L;
-
-    /**
-     *  please refer to Dialog
-     */
-    private static final int DISMISS = 0x43;
-    private static final int CANCEL = 0x44;
-
-    private boolean mCalledCallback;
-    private boolean mIsKey0Listened;
-    private boolean mIsKey1Listened;
-    private boolean mOnCancelListenerCalled;
-
-    private Instrumentation mInstrumentation;
-    private Context mContext;
-    private DialogStubActivity mActivity;
-
-
-    public DialogTest() {
-        super(STUB_ACTIVITY_PACKAGE, DialogStubActivity.class);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mInstrumentation = getInstrumentation();
-        mContext = mInstrumentation.getContext();
-    }
-
-    private void startDialogActivity(int dialogNumber) {
-        mActivity = DialogStubActivity.startDialogActivity(this, dialogNumber);
-    }
-
-    @UiThreadTest
-    public void testConstructor() {
-        new Dialog(mContext);
-        Dialog d = new Dialog(mContext, 0);
-        // According to javadoc of constructors, it will set theme to system default theme,
-        // when we set no theme id or set it theme id to 0.
-        // But CTS can no assert dialog theme equals system internal theme.
-
-        d = new Dialog(mContext, R.style.TextAppearance);
-        TypedArray ta =
-            d.getContext().getTheme().obtainStyledAttributes(R.styleable.TextAppearance);
-        assertTextAppearanceStyle(ta);
-
-        final Window w = d.getWindow();
-        ta = w.getContext().getTheme().obtainStyledAttributes(R.styleable.TextAppearance);
-        assertTextAppearanceStyle(ta);
-    }
-
-    public void testConstructor_protectedCancellable() {
-        startDialogActivity(DialogStubActivity.TEST_PROTECTED_CANCELABLE);
-        mActivity.onCancelListenerCalled = false;
-        sendKeys(KeyEvent.KEYCODE_BACK);
-        assertTrue(mActivity.onCancelListenerCalled);
-    }
-
-    public void testConstructor_protectedNotCancellable() {
-        startDialogActivity(DialogStubActivity.TEST_PROTECTED_NOT_CANCELABLE);
-        mActivity.onCancelListenerCalled = false;
-        sendKeys(KeyEvent.KEYCODE_BACK);
-        assertFalse(mActivity.onCancelListenerCalled);
-    }
-
-    private void assertTextAppearanceStyle(TypedArray ta) {
-        final int defValue = -1;
-        // get Theme and assert
-        final Resources.Theme expected = mContext.getResources().newTheme();
-        expected.setTo(mContext.getTheme());
-        expected.applyStyle(R.style.TextAppearance, true);
-        TypedArray expectedTa = expected.obtainStyledAttributes(R.styleable.TextAppearance);
-        assertEquals(expectedTa.getIndexCount(), ta.getIndexCount());
-        assertEquals(expectedTa.getColor(R.styleable.TextAppearance_textColor, defValue),
-                ta.getColor(R.styleable.TextAppearance_textColor, defValue));
-        assertEquals(expectedTa.getColor(R.styleable.TextAppearance_textColorHint, defValue),
-                ta.getColor(R.styleable.TextAppearance_textColorHint, defValue));
-        assertEquals(expectedTa.getColor(R.styleable.TextAppearance_textColorLink, defValue),
-                ta.getColor(R.styleable.TextAppearance_textColorLink, defValue));
-        assertEquals(expectedTa.getColor(R.styleable.TextAppearance_textColorHighlight, defValue),
-                ta.getColor(R.styleable.TextAppearance_textColorHighlight, defValue));
-        assertEquals(expectedTa.getDimension(R.styleable.TextAppearance_textSize, defValue),
-                ta.getDimension(R.styleable.TextAppearance_textSize, defValue));
-        assertEquals(expectedTa.getInt(R.styleable.TextAppearance_textStyle, defValue),
-                ta.getInt(R.styleable.TextAppearance_textStyle, defValue));
-    }
-
-    public void testOnStartCreateStop(){
-        startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
-        final TestDialog d = (TestDialog) mActivity.getDialog();
-
-        assertTrue(d.isOnStartCalled);
-        assertTrue(d.isOnCreateCalled);
-
-        assertFalse(d.isOnStopCalled);
-        sendKeys(KeyEvent.KEYCODE_BACK);
-        assertTrue(d.isOnStopCalled);
-    }
-
-    public void testAccessOwnerActivity() throws Throwable {
-        startDialogActivity(DialogStubActivity.TEST_DIALOG_WITHOUT_THEME);
-        Dialog d = mActivity.getDialog();
-        assertNotNull(d);
-        assertSame(mActivity, d.getOwnerActivity());
-        d.setVolumeControlStream(d.getVolumeControlStream() + 1);
-        assertEquals(d.getOwnerActivity().getVolumeControlStream() + 1, d.getVolumeControlStream());
-
-        try {
-            d.setOwnerActivity(null);
-            fail("Should throw NullPointerException");
-        } catch (NullPointerException e) {
-            // expected
-        }
-
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-                Dialog dialog = new Dialog(mContext);
-                assertNull(dialog.getOwnerActivity());
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-    }
-
-    public void testShow() throws Throwable {
-        startDialogActivity(DialogStubActivity.TEST_DIALOG_WITHOUT_THEME);
-        final Dialog d = mActivity.getDialog();
-        final View decor = d.getWindow().getDecorView();
-
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-                d.hide();
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-
-        assertEquals(View.GONE, decor.getVisibility());
-        assertTrue(d.isShowing());
-
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-                d.show();
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-
-        assertEquals(View.VISIBLE, decor.getVisibility());
-        assertTrue(d.isShowing());
-        dialogDismiss(d);
-        assertFalse(d.isShowing());
-    }
-
-    public void testOnSaveInstanceState() {
-        startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
-        final TestDialog d = (TestDialog) mActivity.getDialog();
-
-        assertFalse(d.isOnSaveInstanceStateCalled);
-        assertFalse(TestDialog.isOnRestoreInstanceStateCalled);
-
-        //skip if the device doesn't support both of portrait and landscape orientation screens.
-        final PackageManager pm = mContext.getPackageManager();
-        if(!(pm.hasSystemFeature(PackageManager.FEATURE_SCREEN_LANDSCAPE)
-                && pm.hasSystemFeature(PackageManager.FEATURE_SCREEN_PORTRAIT))){
-            return;
-        }
-
-        OrientationTestUtils.toggleOrientationSync(mActivity, mInstrumentation);
-
-        assertTrue(d.isOnSaveInstanceStateCalled);
-        assertTrue(TestDialog.isOnRestoreInstanceStateCalled);
-    }
-
-    public void testGetCurrentFocus() throws Throwable {
-        startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
-        final TestDialog d = (TestDialog) mActivity.getDialog();
-        assertNull(d.getCurrentFocus());
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-                d.takeKeyEvents(true);
-                d.setContentView(R.layout.alert_dialog_text_entry);
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-
-        sendKeys(KeyEvent.KEYCODE_0);
-        // When mWindow is not null getCUrrentFocus is the view in dialog
-        assertEquals(d.getWindow().getCurrentFocus(), d.getCurrentFocus());
-    }
-
-    public void testSetContentView() throws Throwable {
-        startDialogActivity(DialogStubActivity.TEST_DIALOG_WITHOUT_THEME);
-        final Dialog d = mActivity.getDialog();
-        assertNotNull(d);
-
-        // set content view to a four elements layout
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-                d.setContentView(R.layout.alert_dialog_text_entry);
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-
-        // check if four elements are right there
-        assertNotNull(d.findViewById(R.id.username_view));
-        assertNotNull(d.findViewById(R.id.username_edit));
-        assertNotNull(d.findViewById(R.id.password_view));
-        assertNotNull(d.findViewById(R.id.password_edit));
-
-        final LayoutInflater inflate1 = d.getLayoutInflater();
-
-        // set content view to a two elements layout
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-                d.setContentView(inflate1.inflate(R.layout.alert_dialog_text_entry_2, null));
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-
-        // check if only two elements are right there
-        assertNotNull(d.findViewById(R.id.username_view));
-        assertNotNull(d.findViewById(R.id.username_edit));
-        assertNull(d.findViewById(R.id.password_view));
-        assertNull(d.findViewById(R.id.password_edit));
-
-        final WindowManager.LayoutParams lp = d.getWindow().getAttributes();
-        final LayoutInflater inflate2 = mActivity.getLayoutInflater();
-
-        // set content view to a four elements layout
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-                d.setContentView(inflate2.inflate(R.layout.alert_dialog_text_entry, null), lp);
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-
-        // check if four elements are right there
-        assertNotNull(d.findViewById(R.id.username_view));
-        assertNotNull(d.findViewById(R.id.username_edit));
-        assertNotNull(d.findViewById(R.id.password_view));
-        assertNotNull(d.findViewById(R.id.password_edit));
-
-        final WindowManager.LayoutParams lp2 = d.getWindow().getAttributes();
-        final LayoutInflater inflate3 = mActivity.getLayoutInflater();
-        lp2.height = ViewGroup.LayoutParams.WRAP_CONTENT;
-        lp2.width = ViewGroup.LayoutParams.WRAP_CONTENT;
-
-        // add a check box view
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-                d.addContentView(inflate3.inflate(R.layout.checkbox_layout, null), lp2);
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-
-        // check if four elements are right there, and new add view there.
-        assertNotNull(d.findViewById(R.id.check_box));
-        assertNotNull(d.findViewById(R.id.username_view));
-        assertNotNull(d.findViewById(R.id.username_edit));
-        assertNotNull(d.findViewById(R.id.password_view));
-        assertNotNull(d.findViewById(R.id.password_edit));
-    }
-
-    public void testSetTitle() {
-        final String expectedTitle = "Test Dialog Without theme";
-        startDialogActivity(DialogStubActivity.TEST_DIALOG_WITHOUT_THEME);
-
-        assertNotNull(mActivity.getDialog());
-        mActivity.setUpTitle(expectedTitle);
-        mInstrumentation.waitForIdleSync();
-
-        final Dialog d = mActivity.getDialog();
-        assertEquals(expectedTitle, (String) d.getWindow().getAttributes().getTitle());
-
-        mActivity.setUpTitle(R.string.hello_android);
-        mInstrumentation.waitForIdleSync();
-        assertEquals(mActivity.getResources().getString(R.string.hello_android),
-                (String) d.getWindow().getAttributes().getTitle());
-    }
-
-    public void testOnKeyDownKeyUp() {
-        startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
-        final TestDialog d = (TestDialog) mActivity.getDialog();
-        assertFalse(d.isOnKeyDownCalled);
-        assertFalse(d.isOnKeyUpCalled);
-
-        // send key 0 down and up events, onKeyDown return false
-        mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_0);
-        assertTrue(d.isOnKeyDownCalled);
-        assertTrue(d.isOnKeyUpCalled);
-        assertEquals(KeyEvent.KEYCODE_0, d.keyDownCode);
-        assertFalse(d.onKeyDownReturn);
-
-        // send key back down and up events, onKeyDown return true
-        mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_BACK);
-        assertEquals(KeyEvent.KEYCODE_BACK, d.keyDownCode);
-        assertTrue(d.onKeyDownReturn);
-    }
-
-     public void testOnKeyMultiple() {
-         startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
-         final TestDialog d = (TestDialog) mActivity.getDialog();
-
-         assertNull(d.keyMultipleEvent);
-         d.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_MULTIPLE, KeyEvent.KEYCODE_UNKNOWN));
-         assertTrue(d.isOnKeyMultipleCalled);
-         assertFalse(d.onKeyMultipleReturn);
-         assertEquals(KeyEvent.KEYCODE_UNKNOWN, d.keyMultipleEvent.getKeyCode());
-         assertEquals(KeyEvent.ACTION_MULTIPLE, d.keyMultipleEvent.getAction());
-     }
-
-    public void testTouchEvent() {
-        startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
-        final TestDialog d = (TestDialog) mActivity.getDialog();
-
-        assertNull(d.onTouchEvent);
-        assertNull(d.touchEvent);
-        assertFalse(d.isOnTouchEventCalled);
-
-        // Send a touch event outside the activity.  The event will be ignored
-        // because closeOnTouchOutside is false.
-        d.setCanceledOnTouchOutside(false);
-
-        long now = SystemClock.uptimeMillis();
-        MotionEvent touchMotionEvent = MotionEvent.obtain(now, now, MotionEvent.ACTION_DOWN,
-                1, getStatusBarHeight(), 0);
-        mInstrumentation.sendPointerSync(touchMotionEvent);
-
-        new PollingCheck(TEST_TIMEOUT) {
-            protected boolean check() {
-                return !d.dispatchTouchEventResult;
-            }
-        }.run();
-
-        assertMotionEventEquals(touchMotionEvent, d.touchEvent);
-
-        assertTrue(d.isOnTouchEventCalled);
-        assertMotionEventEquals(touchMotionEvent, d.onTouchEvent);
-        d.isOnTouchEventCalled = false;
-        assertTrue(d.isShowing());
-
-        // Watch activities cover the entire screen, so there is no way to touch outside.
-        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH)) {
-            // Send a touch event outside the activity.  This time the dialog will be dismissed
-            // because closeOnTouchOutside is true.
-            d.setCanceledOnTouchOutside(true);
-
-            touchMotionEvent = MotionEvent.obtain(now, now + 1, MotionEvent.ACTION_DOWN,
-                    1, getStatusBarHeight(), 0);
-            mInstrumentation.sendPointerSync(touchMotionEvent);
-
-            new PollingCheck(TEST_TIMEOUT) {
-                protected boolean check() {
-                    return d.dispatchTouchEventResult;
-                }
-            }.run();
-
-            assertMotionEventEquals(touchMotionEvent, d.touchEvent);
-
-            assertTrue(d.isOnTouchEventCalled);
-            assertMotionEventEquals(touchMotionEvent, d.onTouchEvent);
-            assertFalse(d.isShowing());
-        }
-    }
-
-    private int getStatusBarHeight() {
-        final Rect rect = new Rect();
-        Window window = mActivity.getWindow();
-        window.getDecorView().getWindowVisibleDisplayFrame(rect);
-        return rect.top;
-    }
-
-    public void testTrackballEvent() {
-        startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
-        final TestDialog d = (TestDialog) mActivity.getDialog();
-        long eventTime = SystemClock.uptimeMillis();
-        final MotionEvent trackBallEvent = MotionEvent.obtain(eventTime, eventTime,
-                MotionEvent.ACTION_DOWN, 0.0f, 0.0f, 0);
-
-        assertNull(d.trackballEvent);
-        assertNull(d.onTrackballEvent);
-
-        assertFalse(d.isOnTrackballEventCalled);
-        mInstrumentation.sendTrackballEventSync(trackBallEvent);
-        assertTrue(d.isOnTrackballEventCalled);
-        assertMotionEventEquals(trackBallEvent, d.trackballEvent);
-        assertMotionEventEquals(trackBallEvent, d.onTrackballEvent);
-
-    }
-
-    private void assertMotionEventEquals(final MotionEvent expected, final MotionEvent actual) {
-        assertEquals(expected.getDownTime(), actual.getDownTime());
-        assertEquals(expected.getEventTime(), actual.getEventTime());
-        assertEquals(expected.getAction(), actual.getAction());
-        assertEquals(expected.getMetaState(), actual.getMetaState());
-        assertEquals(expected.getSize(), actual.getSize());
-        // As MotionEvent doc says the value of X and Y coordinate may have
-        // a fraction for input devices that are sub-pixel precise,
-        // so we won't assert them here.
-    }
-
-    public void testOnWindowAttributesChanged() throws Throwable {
-        startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
-        final TestDialog d = (TestDialog) mActivity.getDialog();
-
-        assertTrue(d.isOnWindowAttributesChangedCalled);
-        d.isOnWindowAttributesChangedCalled = false;
-
-        final WindowManager.LayoutParams lp = d.getWindow().getAttributes();
-        lp.setTitle("test OnWindowAttributesChanged");
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-                d.getWindow().setAttributes(lp);
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-
-        assertTrue(d.isOnWindowAttributesChangedCalled);
-        assertSame(lp, d.getWindow().getAttributes());
-    }
-
-    public void testOnContentChanged() throws Throwable {
-        startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
-        final TestDialog d = (TestDialog) mActivity.getDialog();
-        assertNotNull(d);
-
-        assertFalse(d.isOnContentChangedCalled);
-
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-                d.setContentView(R.layout.alert_dialog_text_entry);
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-
-        assertTrue(d.isOnContentChangedCalled);
-    }
-
-    public void testOnWindowFocusChanged() throws Throwable {
-        startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
-        final TestDialog d = (TestDialog) mActivity.getDialog();
-        assertTrue(d.isOnWindowFocusChangedCalled);
-        d.isOnWindowFocusChangedCalled = false;
-
-        // show a new dialog, the new dialog get focus
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-                mActivity.showDialog(DialogStubActivity.TEST_DIALOG_WITHOUT_THEME);
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-
-        // Wait until TestDialog#OnWindowFocusChanged() is called
-        new PollingCheck(TEST_TIMEOUT) {
-            protected boolean check() {
-                return d.isOnWindowFocusChangedCalled;
-            }
-        }.run();
-    }
-
-    public void testDispatchKeyEvent() {
-        startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
-        final TestDialog d = (TestDialog) mActivity.getDialog();
-
-        sendKeys(KeyEvent.KEYCODE_0);
-        assertFalse(d.dispatchKeyEventResult);
-        assertEquals(KeyEvent.KEYCODE_0, d.keyEvent.getKeyCode());
-
-        d.setOnKeyListener(new OnKeyListener() {
-            public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
-                if (KeyEvent.ACTION_DOWN == event.getAction()) {
-                    if (KeyEvent.KEYCODE_0 == keyCode) {
-                        mIsKey0Listened = true;
-                        return true;
-                    }
-
-                    if (KeyEvent.KEYCODE_1 == keyCode) {
-                        mIsKey1Listened = true;
-                        return true;
-                    }
-                }
-
-                return false;
-            }
-        });
-
-        mIsKey1Listened = false;
-        sendKeys(KeyEvent.KEYCODE_1);
-        assertTrue(mIsKey1Listened);
-
-        mIsKey0Listened = false;
-        sendKeys(KeyEvent.KEYCODE_0);
-        assertTrue(mIsKey0Listened);
-    }
-
-    /*
-     * Test point
-     * 1. registerForContextMenu() will OnCreateContextMenuListener on the view to this activity,
-     * so onCreateContextMenu() will be called when it is time to show the context menu.
-     * 2. Close context menu will make onPanelClosed to be called,
-     * and onPanelClosed will calls through to the new onPanelClosed method.
-     * 3. unregisterForContextMenu() will remove the OnCreateContextMenuListener on the view,
-     * so onCreateContextMenu() will not be called when try to open context menu.
-     * 4. Selected a item of context menu will make onMenuItemSelected() to be called,
-     * and onMenuItemSelected will calls through to the new onContextItemSelected method.
-     * 5. onContextMenuClosed is called whenever the context menu is being closed (either by
-     * the user canceling the menu with the back/menu button, or when an item is selected).
-     */
-    public void testContextMenu() throws Throwable {
-        startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
-        final TestDialog d = (TestDialog) mActivity.getDialog();
-        final LinearLayout parent = new LinearLayout(mContext);
-        final MockView v = new MockView(mContext);
-        parent.addView(v);
-        assertFalse(v.isShowContextMenuCalled);
-        // Register for context menu and open it
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-                d.addContentView(parent, new LinearLayout.LayoutParams(
-                        ViewGroup.LayoutParams.MATCH_PARENT,
-                        ViewGroup.LayoutParams.WRAP_CONTENT));
-                d.registerForContextMenu(v);
-                d.openContextMenu(v);
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-
-        assertTrue(v.isShowContextMenuCalled);
-        assertTrue(d.isOnCreateContextMenuCalled);
-
-        assertFalse(d.isOnPanelClosedCalled);
-        assertFalse(d.isOnContextMenuClosedCalled);
-        // Closed context menu
-        sendKeys(KeyEvent.KEYCODE_BACK);
-        assertTrue(d.isOnPanelClosedCalled);
-        // Here isOnContextMenuClosedCalled should be true, see bug 1716918.
-        assertFalse(d.isOnContextMenuClosedCalled);
-
-        v.isShowContextMenuCalled = false;
-        d.isOnCreateContextMenuCalled = false;
-        // Unregister for context menu, and try to open it
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-                d.unregisterForContextMenu(v);
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-                d.openContextMenu(v);
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-
-        assertTrue(v.isShowContextMenuCalled);
-        assertFalse(d.isOnCreateContextMenuCalled);
-
-        // Register for context menu and open it again
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-                d.registerForContextMenu(v);
-                d.openContextMenu(v);
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-
-        assertFalse(d.isOnContextItemSelectedCalled);
-        assertFalse(d.isOnMenuItemSelectedCalled);
-        d.isOnPanelClosedCalled = false;
-        assertFalse(d.isOnContextMenuClosedCalled);
-        // select a context menu item
-        sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
-        assertTrue(d.isOnMenuItemSelectedCalled);
-        // Here isOnContextItemSelectedCalled should be true, see bug 1716918.
-        assertFalse(d.isOnContextItemSelectedCalled);
-        assertTrue(d.isOnPanelClosedCalled);
-        // Here isOnContextMenuClosedCalled should be true, see bug 1716918.
-        assertFalse(d.isOnContextMenuClosedCalled);
-    }
-
-    public void testOnSearchRequested() {
-    }
-
-    public void testTakeKeyEvents() throws Throwable {
-        startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
-        final TestDialog d = (TestDialog) mActivity.getDialog();
-        final View v = d.getWindow().getDecorView();
-        assertNull(d.getCurrentFocus());
-        takeKeyEvents(d, true);
-        assertTrue(v.isFocusable());
-        sendKeys(KeyEvent.KEYCODE_0);
-        assertEquals(KeyEvent.KEYCODE_0, d.keyEvent.getKeyCode());
-        d.keyEvent = null;
-
-        takeKeyEvents(d, false);
-        assertNull(d.getCurrentFocus());
-        assertFalse(v.isFocusable());
-        sendKeys(KeyEvent.KEYCODE_0);
-        // d.keyEvent should be null
-    }
-
-    private void takeKeyEvents(final Dialog d, final boolean get) throws Throwable {
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-                d.takeKeyEvents(get);
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-    }
-
-    public void testRequestWindowFeature() {
-        startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
-        // called requestWindowFeature at TestDialog onCreate method
-        assertTrue(((TestDialog) mActivity.getDialog()).isRequestWindowFeature);
-    }
-
-    public void testSetFeatureDrawableResource() throws Throwable {
-        startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-                mActivity.getDialog().setFeatureDrawableResource(Window.FEATURE_LEFT_ICON,
-                        R.drawable.robot);
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-    }
-
-    public void testSetFeatureDrawableUri() throws Throwable {
-        startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-                mActivity.getDialog().setFeatureDrawableUri(Window.FEATURE_LEFT_ICON,
-                        Uri.parse("http://www.google.com"));
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-    }
-
-    public void testSetFeatureDrawable() throws Throwable {
-        startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-                mActivity.getDialog().setFeatureDrawable(Window.FEATURE_LEFT_ICON, 
-                        new MockDrawable());
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-    }
-
-    public void testSetFeatureDrawableAlpha() throws Throwable {
-        startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-                mActivity.getDialog().setFeatureDrawableAlpha(Window.FEATURE_LEFT_ICON, 0);
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-    }
-
-    public void testGetLayoutInflater() {
-        startDialogActivity(DialogStubActivity.TEST_DIALOG_WITHOUT_THEME);
-        final Dialog d = mActivity.getDialog();
-        assertEquals(d.getWindow().getLayoutInflater(), d.getLayoutInflater());
-    }
-
-    public void testSetCancelable_true() {
-        startDialogActivity(DialogStubActivity.TEST_DIALOG_WITHOUT_THEME);
-        final Dialog d = mActivity.getDialog();
-
-        d.setCancelable(true);
-        assertTrue(d.isShowing());
-        sendKeys(KeyEvent.KEYCODE_BACK);
-        assertFalse(d.isShowing());
-    }
-
-    public void testSetCancellable_false() {
-        startDialogActivity(DialogStubActivity.TEST_DIALOG_WITHOUT_THEME);
-        final Dialog d = mActivity.getDialog();
-
-        d.setCancelable(false);
-        assertTrue(d.isShowing());
-        sendKeys(KeyEvent.KEYCODE_BACK);
-        assertTrue(d.isShowing());
-    }
-
-    /*
-     * Test point
-     * 1. Cancel the dialog.
-     * 2. Set a listener to be invoked when the dialog is canceled.
-     */
-    public void testCancel_listener() throws Throwable {
-        startDialogActivity(DialogStubActivity.TEST_DIALOG_WITHOUT_THEME);
-        final Dialog d = mActivity.getDialog();
-
-        assertTrue(d.isShowing());
-        mOnCancelListenerCalled = false;
-        d.setOnCancelListener(new OnCancelListener() {
-            public void onCancel(DialogInterface dialog) {
-                mOnCancelListenerCalled = true;
-            }
-        });
-        dialogCancel(d);
-
-        assertFalse(d.isShowing());
-        assertTrue(mOnCancelListenerCalled);
-    }
-
-    public void testCancel_noListener() throws Throwable {
-        startDialogActivity(DialogStubActivity.TEST_DIALOG_WITHOUT_THEME);
-        final Dialog d = mActivity.getDialog();
-
-        assertTrue(d.isShowing());
-        mOnCancelListenerCalled = false;
-        d.setOnCancelListener(null);
-        dialogCancel(d);
-
-        assertFalse(d.isShowing());
-        assertFalse(mOnCancelListenerCalled);
-    }
-
-    public void testSetCancelMessage() throws Exception {
-        mCalledCallback = false;
-        startDialogActivity(DialogStubActivity.TEST_ONSTART_AND_ONSTOP);
-        final TestDialog d = (TestDialog) mActivity.getDialog();
-        final HandlerThread ht = new HandlerThread("DialogTest");
-        ht.start();
-
-        d.setCancelMessage(new MockDismissCancelHandler(d, ht.getLooper()).obtainMessage(CANCEL,
-                new OnCancelListener() {
-                    public void onCancel(DialogInterface dialog) {
-                        mCalledCallback = true;
-                    }
-                }));
-        assertTrue(d.isShowing());
-        assertFalse(mCalledCallback);
-        sendKeys(KeyEvent.KEYCODE_BACK);
-        assertTrue(mCalledCallback);
-        assertFalse(d.isShowing());
-
-        ht.join(100);
-    }
-
-    /*
-     * Test point
-     * 1. Set a listener to be invoked when the dialog is dismissed.
-     * 2. set onDismissListener to null, it will not changed flag after dialog dismissed.
-     */
-    public void testSetOnDismissListener_listener() throws Throwable {
-        mCalledCallback = false;
-        startDialogActivity(DialogStubActivity.TEST_DIALOG_WITHOUT_THEME);
-        final Dialog d = mActivity.getDialog();
-
-        d.setOnDismissListener(new OnDismissListener() {
-            public void onDismiss(DialogInterface dialog) {
-                mCalledCallback = true;
-            }
-        });
-
-        assertTrue(d.isShowing());
-        assertFalse(mCalledCallback);
-        dialogDismiss(d);
-        assertTrue(mCalledCallback);
-        assertFalse(d.isShowing());
-    }
-
-    public void testSetOnDismissListener_noListener() throws Throwable {
-        startDialogActivity(DialogStubActivity.TEST_DIALOG_WITHOUT_THEME);
-        final Dialog d = mActivity.getDialog();
-        assertTrue(d.isShowing());
-        mCalledCallback = false;
-        d.setOnDismissListener(null);
-        dialogDismiss(d);
-        assertFalse(mCalledCallback);
-        assertFalse(d.isShowing());
-    }
-
-    public void testSetDismissMessage() throws Throwable {
-        mCalledCallback = false;
-        startDialogActivity(DialogStubActivity.TEST_DIALOG_WITHOUT_THEME);
-        final Dialog d = mActivity.getDialog();
-
-        final HandlerThread ht = new HandlerThread("DialogTest");
-        ht.start();
-
-        d.setDismissMessage(new MockDismissCancelHandler(d, ht.getLooper()).obtainMessage(DISMISS,
-                new OnDismissListener() {
-                    public void onDismiss(DialogInterface dialog) {
-                        mCalledCallback = true;
-                    }
-                }));
-        assertTrue(d.isShowing());
-        assertFalse(mCalledCallback);
-        dialogDismiss(d);
-        ht.join(100);
-        assertTrue(mCalledCallback);
-        assertFalse(d.isShowing());
-    }
-
-    private void dialogDismiss(final Dialog d) throws Throwable {
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-                d.dismiss();
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-    }
-
-    private void dialogCancel(final Dialog d) throws Throwable {
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-                d.cancel();
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-    }
-
-    private static class MockDismissCancelHandler extends Handler {
-        private WeakReference<DialogInterface> mDialog;
-
-        public MockDismissCancelHandler(Dialog dialog, Looper looper) {
-            super(looper);
-
-            mDialog = new WeakReference<DialogInterface>(dialog);
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-            case DISMISS:
-                ((OnDismissListener) msg.obj).onDismiss(mDialog.get());
-                break;
-            case CANCEL:
-                ((OnCancelListener) msg.obj).onCancel(mDialog.get());
-                break;
-            }
-        }
-    }
-
-    private static class MockDrawable extends Drawable {
-        @Override
-        public void draw(Canvas canvas) {
-        }
-
-        @Override
-        public int getOpacity() {
-            return 0;
-        }
-
-        @Override
-        public void setAlpha(int alpha) {
-        }
-
-        @Override
-        public void setColorFilter(ColorFilter cf) {
-        }
-    }
-
-    private static class MockView extends View {
-        public boolean isShowContextMenuCalled;
-        protected OnCreateContextMenuListener mOnCreateContextMenuListener;
-
-        public MockView(Context context) {
-            super(context);
-        }
-
-        public void setOnCreateContextMenuListener(OnCreateContextMenuListener l) {
-            super.setOnCreateContextMenuListener(l);
-            mOnCreateContextMenuListener = l;
-        }
-
-        public OnCreateContextMenuListener getOnCreateContextMenuListener() {
-            return mOnCreateContextMenuListener;
-        }
-
-        @Override
-        public boolean showContextMenu() {
-            isShowContextMenuCalled = true;
-            return super.showContextMenu();
-        }
-    }
-}
diff --git a/tests/tests/app/src/android/app/cts/DownloadManagerTest.java b/tests/tests/app/src/android/app/cts/DownloadManagerTest.java
deleted file mode 100644
index 21a227b..0000000
--- a/tests/tests/app/src/android/app/cts/DownloadManagerTest.java
+++ /dev/null
@@ -1,482 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-import android.app.DownloadManager;
-import android.app.DownloadManager.Query;
-import android.app.DownloadManager.Request;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.PackageManager;
-import android.cts.util.PollingCheck;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Environment;
-import android.os.ParcelFileDescriptor;
-import android.os.SystemClock;
-import android.test.AndroidTestCase;
-import android.text.format.DateUtils;
-import android.util.Log;
-import android.webkit.cts.CtsTestServer;
-
-import java.io.File;
-import java.util.Arrays;
-import java.util.HashSet;
-
-public class DownloadManagerTest extends AndroidTestCase {
-    private static final String TAG = "DownloadManagerTest";
-
-    /**
-     * According to the CDD Section 7.6.1, the DownloadManager implementation must be able to
-     * download individual files of 100 MB.
-     */
-    private static final int MINIMUM_DOWNLOAD_BYTES = 100 * 1024 * 1024;
-
-    private static final long SHORT_TIMEOUT = 5 * DateUtils.SECOND_IN_MILLIS;
-    private static final long LONG_TIMEOUT = 3 * DateUtils.MINUTE_IN_MILLIS;
-
-    private DownloadManager mDownloadManager;
-
-    private CtsTestServer mWebServer;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mDownloadManager = (DownloadManager) mContext.getSystemService(Context.DOWNLOAD_SERVICE);
-        mWebServer = new CtsTestServer(mContext);
-        clearDownloads();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-        mWebServer.shutdown();
-    }
-
-    public void testDownloadManager() throws Exception {
-        final DownloadCompleteReceiver receiver = new DownloadCompleteReceiver();
-        try {
-            IntentFilter intentFilter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
-            mContext.registerReceiver(receiver, intentFilter);
-
-            long goodId = mDownloadManager.enqueue(new Request(getGoodUrl()));
-            long badId = mDownloadManager.enqueue(new Request(getBadUrl()));
-
-            int allDownloads = getTotalNumberDownloads();
-            assertEquals(2, allDownloads);
-
-            assertDownloadQueryableById(goodId);
-            assertDownloadQueryableById(badId);
-
-            receiver.waitForDownloadComplete(SHORT_TIMEOUT, goodId, badId);
-
-            assertDownloadQueryableByStatus(DownloadManager.STATUS_SUCCESSFUL);
-            assertDownloadQueryableByStatus(DownloadManager.STATUS_FAILED);
-
-            assertRemoveDownload(goodId, allDownloads - 1);
-            assertRemoveDownload(badId, allDownloads - 2);
-        } finally {
-            mContext.unregisterReceiver(receiver);
-        }
-    }
-
-    public void testDownloadManagerSupportsHttp() throws Exception {
-        final DownloadCompleteReceiver receiver = new DownloadCompleteReceiver();
-        try {
-            IntentFilter intentFilter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
-            mContext.registerReceiver(receiver, intentFilter);
-
-            long id = mDownloadManager.enqueue(new Request(getGoodUrl()));
-
-            assertEquals(1, getTotalNumberDownloads());
-
-            assertDownloadQueryableById(id);
-
-            receiver.waitForDownloadComplete(SHORT_TIMEOUT, id);
-
-            assertDownloadQueryableByStatus(DownloadManager.STATUS_SUCCESSFUL);
-
-            assertRemoveDownload(id, 0);
-        } finally {
-            mContext.unregisterReceiver(receiver);
-        }
-    }
-
-    public void testDownloadManagerSupportsHttpWithExternalWebServer() throws Exception {
-        if (!hasInternetConnection()) {
-            Log.i(TAG, "testDownloadManagerSupportsHttpWithExternalWebServer() ignored on device without Internet");
-            return;
-        }
-
-        // As a result of testDownloadManagerSupportsHttpsWithExternalWebServer relying on an
-        // external resource https://www.example.com this test uses http://www.example.com to help
-        // disambiguate errors from testDownloadManagerSupportsHttpsWithExternalWebServer.
-
-        final DownloadCompleteReceiver receiver = new DownloadCompleteReceiver();
-        try {
-            IntentFilter intentFilter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
-            mContext.registerReceiver(receiver, intentFilter);
-
-            long id = mDownloadManager.enqueue(new Request(Uri.parse("http://www.example.com")));
-
-            assertEquals(1, getTotalNumberDownloads());
-
-            assertDownloadQueryableById(id);
-
-            receiver.waitForDownloadComplete(LONG_TIMEOUT, id);
-
-            assertDownloadQueryableByStatus(DownloadManager.STATUS_SUCCESSFUL);
-
-            assertRemoveDownload(id, 0);
-        } finally {
-            mContext.unregisterReceiver(receiver);
-        }
-    }
-
-    public void testDownloadManagerSupportsHttpsWithExternalWebServer() throws Exception {
-        if (!hasInternetConnection()) {
-            Log.i(TAG, "testDownloadManagerSupportsHttpsWithExternalWebServer() ignored on device without Internet");
-            return;
-        }
-
-        // For HTTPS, DownloadManager trusts only SSL server certs issued by CAs trusted by the
-        // system. Unfortunately, this means that it cannot trust the mock web server's SSL cert.
-        // Until this is resolved (e.g., by making it possible to specify additional CA certs to
-        // trust for a particular download), this test relies on https://www.example.com being
-        // operational and reachable from the Android under test.
-
-        final DownloadCompleteReceiver receiver = new DownloadCompleteReceiver();
-        try {
-            IntentFilter intentFilter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
-            mContext.registerReceiver(receiver, intentFilter);
-
-            long id = mDownloadManager.enqueue(new Request(Uri.parse("https://www.example.com")));
-
-            assertEquals(1, getTotalNumberDownloads());
-
-            assertDownloadQueryableById(id);
-
-            receiver.waitForDownloadComplete(LONG_TIMEOUT, id);
-
-            assertDownloadQueryableByStatus(DownloadManager.STATUS_SUCCESSFUL);
-
-            assertRemoveDownload(id, 0);
-        } finally {
-            mContext.unregisterReceiver(receiver);
-        }
-    }
-
-    public void testMinimumDownload() throws Exception {
-        final DownloadCompleteReceiver receiver = new DownloadCompleteReceiver();
-        try {
-            IntentFilter intentFilter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
-            mContext.registerReceiver(receiver, intentFilter);
-
-            long id = mDownloadManager.enqueue(new Request(getMinimumDownloadUrl()));
-            receiver.waitForDownloadComplete(LONG_TIMEOUT, id);
-
-            ParcelFileDescriptor fileDescriptor = mDownloadManager.openDownloadedFile(id);
-            assertEquals(MINIMUM_DOWNLOAD_BYTES, fileDescriptor.getStatSize());
-
-            Cursor cursor = null;
-            try {
-                cursor = mDownloadManager.query(new Query().setFilterById(id));
-                assertTrue(cursor.moveToNext());
-                assertEquals(DownloadManager.STATUS_SUCCESSFUL, cursor.getInt(
-                        cursor.getColumnIndex(DownloadManager.COLUMN_STATUS)));
-                assertEquals(MINIMUM_DOWNLOAD_BYTES, cursor.getInt(
-                        cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES)));
-                assertFalse(cursor.moveToNext());
-            } finally {
-                if (cursor != null) {
-                    cursor.close();
-                }
-            }
-
-            assertRemoveDownload(id, 0);
-        } finally {
-            mContext.unregisterReceiver(receiver);
-        }
-    }
-
-    /**
-     * Set download locations and verify that file is downloaded to correct location.
-     *
-     * Checks three different methods of setting location: directly via setDestinationUri, and
-     * indirectly through setDestinationInExternalFilesDir and setDestinationinExternalPublicDir.
-     */
-    public void testDownloadManagerDestination() throws Exception {
-        File uriLocation = new File(mContext.getExternalFilesDir(null), "uriFile.bin");
-        if (uriLocation.exists()) {
-            assertTrue(uriLocation.delete());
-        }
-
-        File extFileLocation = new File(mContext.getExternalFilesDir(null), "extFile.bin");
-        if (extFileLocation.exists()) {
-            assertTrue(extFileLocation.delete());
-        }
-
-        File publicLocation = new File(
-                Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS),
-                "publicFile.bin");
-        if (publicLocation.exists()) {
-            assertTrue(publicLocation.delete());
-        }
-
-        final DownloadCompleteReceiver receiver = new DownloadCompleteReceiver();
-        try {
-            IntentFilter intentFilter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
-            mContext.registerReceiver(receiver, intentFilter);
-
-            Request requestUri = new Request(getGoodUrl());
-            requestUri.setDestinationUri(Uri.fromFile(uriLocation));
-            long uriId = mDownloadManager.enqueue(requestUri);
-
-            Request requestExtFile = new Request(getGoodUrl());
-            requestExtFile.setDestinationInExternalFilesDir(mContext, null, "extFile.bin");
-            long extFileId = mDownloadManager.enqueue(requestExtFile);
-
-            Request requestPublic = new Request(getGoodUrl());
-            requestPublic.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS,
-                    "publicFile.bin");
-            long publicId = mDownloadManager.enqueue(requestPublic);
-
-            int allDownloads = getTotalNumberDownloads();
-            assertEquals(3, allDownloads);
-
-            receiver.waitForDownloadComplete(SHORT_TIMEOUT, uriId, extFileId, publicId);
-
-            assertSuccessfulDownload(uriId, uriLocation);
-            assertSuccessfulDownload(extFileId, extFileLocation);
-            assertSuccessfulDownload(publicId, publicLocation);
-
-            assertRemoveDownload(uriId, allDownloads - 1);
-            assertRemoveDownload(extFileId, allDownloads - 2);
-            assertRemoveDownload(publicId, allDownloads - 3);
-        } finally {
-            mContext.unregisterReceiver(receiver);
-        }
-    }
-
-    /**
-     * Set the download location and verify that the extension of the file name is left unchanged.
-     */
-    public void testDownloadManagerDestinationExtension() throws Exception {
-        String noExt = "noiseandchirps";
-        File noExtLocation = new File(mContext.getExternalFilesDir(null), noExt);
-        if (noExtLocation.exists()) {
-            assertTrue(noExtLocation.delete());
-        }
-
-        String wrongExt = "noiseandchirps.wrong";
-        File wrongExtLocation = new File(mContext.getExternalFilesDir(null), wrongExt);
-        if (wrongExtLocation.exists()) {
-            assertTrue(wrongExtLocation.delete());
-        }
-
-        final DownloadCompleteReceiver receiver = new DownloadCompleteReceiver();
-        try {
-            IntentFilter intentFilter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
-            mContext.registerReceiver(receiver, intentFilter);
-
-            Request requestNoExt = new Request(getAssetUrl(noExt));
-            requestNoExt.setDestinationUri(Uri.fromFile(noExtLocation));
-            long noExtId = mDownloadManager.enqueue(requestNoExt);
-
-            Request requestWrongExt = new Request(getAssetUrl(wrongExt));
-            requestWrongExt.setDestinationUri(Uri.fromFile(wrongExtLocation));
-            long wrongExtId = mDownloadManager.enqueue(requestWrongExt);
-
-            int allDownloads = getTotalNumberDownloads();
-            assertEquals(2, allDownloads);
-
-            receiver.waitForDownloadComplete(SHORT_TIMEOUT, noExtId, wrongExtId);
-
-            assertSuccessfulDownload(noExtId, noExtLocation);
-            assertSuccessfulDownload(wrongExtId, wrongExtLocation);
-
-            assertRemoveDownload(noExtId, allDownloads - 1);
-            assertRemoveDownload(wrongExtId, allDownloads - 2);
-        } finally {
-            mContext.unregisterReceiver(receiver);
-        }
-    }
-
-    private class DownloadCompleteReceiver extends BroadcastReceiver {
-        private HashSet<Long> mCompleteIds = new HashSet<>();
-
-        public DownloadCompleteReceiver() {
-        }
-
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            synchronized (mCompleteIds) {
-                mCompleteIds.add(intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1));
-                mCompleteIds.notifyAll();
-            }
-        }
-
-        private boolean isCompleteLocked(long... ids) {
-            for (long id : ids) {
-                if (!mCompleteIds.contains(id)) {
-                    return false;
-                }
-            }
-            return true;
-        }
-
-        public void waitForDownloadComplete(long timeoutMillis, long... waitForIds)
-                throws InterruptedException {
-            if (waitForIds.length == 0) {
-                throw new IllegalArgumentException("Missing IDs to wait for");
-            }
-
-            final long startTime = SystemClock.elapsedRealtime();
-            do {
-                synchronized (mCompleteIds) {
-                    mCompleteIds.wait(timeoutMillis);
-                    if (isCompleteLocked(waitForIds)) return;
-                }
-            } while ((SystemClock.elapsedRealtime() - startTime) < timeoutMillis);
-
-            throw new InterruptedException("Timeout waiting for IDs " + Arrays.toString(waitForIds)
-                    + "; received " + mCompleteIds.toString()
-                    + ".  Make sure you have WiFi or some other connectivity for this test.");
-        }
-    }
-
-    private void clearDownloads() {
-        if (getTotalNumberDownloads() > 0) {
-            Cursor cursor = null;
-            try {
-                Query query = new Query();
-                cursor = mDownloadManager.query(query);
-                int columnIndex = cursor.getColumnIndex(DownloadManager.COLUMN_ID);
-                long[] removeIds = new long[cursor.getCount()];
-                for (int i = 0; cursor.moveToNext(); i++) {
-                    removeIds[i] = cursor.getLong(columnIndex);
-                }
-                assertEquals(removeIds.length, mDownloadManager.remove(removeIds));
-                assertEquals(0, getTotalNumberDownloads());
-            } finally {
-                if (cursor != null) {
-                    cursor.close();
-                }
-            }
-        }
-    }
-
-    private Uri getGoodUrl() {
-        return Uri.parse(mWebServer.getTestDownloadUrl("cts-good-download", 0));
-    }
-
-    private Uri getBadUrl() {
-        return Uri.parse(mWebServer.getBaseUri() + "/nosuchurl");
-    }
-
-    private Uri getMinimumDownloadUrl() {
-        return Uri.parse(mWebServer.getTestDownloadUrl("cts-minimum-download",
-                MINIMUM_DOWNLOAD_BYTES));
-    }
-
-    private Uri getAssetUrl(String asset) {
-        return Uri.parse(mWebServer.getAssetUrl(asset));
-    }
-
-    private int getTotalNumberDownloads() {
-        Cursor cursor = null;
-        try {
-            Query query = new Query();
-            cursor = mDownloadManager.query(query);
-            return cursor.getCount();
-        } finally {
-            if (cursor != null) {
-                cursor.close();
-            }
-        }
-    }
-
-    private void assertDownloadQueryableById(long downloadId) {
-        Cursor cursor = null;
-        try {
-            Query query = new Query().setFilterById(downloadId);
-            cursor = mDownloadManager.query(query);
-            assertEquals(1, cursor.getCount());
-        } finally {
-            if (cursor != null) {
-                cursor.close();
-            }
-        }
-    }
-
-    private void assertDownloadQueryableByStatus(final int status) {
-        new PollingCheck() {
-            @Override
-            protected boolean check() {
-                Cursor cursor= null;
-                try {
-                    Query query = new Query().setFilterByStatus(status);
-                    cursor = mDownloadManager.query(query);
-                    return 1 == cursor.getCount();
-                } finally {
-                    if (cursor != null) {
-                        cursor.close();
-                    }
-                }
-            }
-        }.run();
-    }
-
-    private void assertSuccessfulDownload(long id, File location) {
-        Cursor cursor = null;
-        try {
-            cursor = mDownloadManager.query(new Query().setFilterById(id));
-            assertTrue(cursor.moveToNext());
-            assertEquals(DownloadManager.STATUS_SUCCESSFUL, cursor.getInt(
-                    cursor.getColumnIndex(DownloadManager.COLUMN_STATUS)));
-            assertEquals(Uri.fromFile(location).toString(),
-                    cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI)));
-            assertTrue(location.exists());
-        } finally {
-            if (cursor != null) {
-                cursor.close();
-            }
-        }
-    }
-
-    private void assertRemoveDownload(long removeId, int expectedNumDownloads) {
-        Cursor cursor = null;
-        try {
-            assertEquals(1, mDownloadManager.remove(removeId));
-            Query query = new Query();
-            cursor = mDownloadManager.query(query);
-            assertEquals(expectedNumDownloads, cursor.getCount());
-        } finally {
-            if (cursor != null) {
-                cursor.close();
-            }
-        }
-    }
-
-    private boolean hasInternetConnection() {
-        // TODO: expand this to include devices with ethernet
-        final PackageManager pm = getContext().getPackageManager();
-        return pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)
-                || pm.hasSystemFeature(PackageManager.FEATURE_WIFI);
-    }
-}
diff --git a/tests/tests/app/src/android/app/cts/ExpandableListActivityTest.java b/tests/tests/app/src/android/app/cts/ExpandableListActivityTest.java
deleted file mode 100644
index 9d97296..0000000
--- a/tests/tests/app/src/android/app/cts/ExpandableListActivityTest.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-import android.app.ExpandableListActivity;
-import android.content.ComponentName;
-
-public class ExpandableListActivityTest extends ActivityTestsBase {
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mIntent.putExtra("component", new ComponentName(getContext(),
-                ExpandableListTestActivity.class));
-    }
-
-    public void testSelect() {
-        runLaunchpad(LaunchpadActivity.EXPANDLIST_SELECT);
-    }
-
-    public void testView() {
-        runLaunchpad(LaunchpadActivity.EXPANDLIST_VIEW);
-    }
-
-    public void testCallback() {
-        runLaunchpad(LaunchpadActivity.EXPANDLIST_CALLBACK);
-    }
-}
\ No newline at end of file
diff --git a/tests/tests/app/src/android/app/cts/InstrumentationTest.java b/tests/tests/app/src/android/app/cts/InstrumentationTest.java
deleted file mode 100644
index 25403f3..0000000
--- a/tests/tests/app/src/android/app/cts/InstrumentationTest.java
+++ /dev/null
@@ -1,708 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-import com.android.cts.app.stub.R;
-
-import android.app.Activity;
-import android.app.Application;
-import android.app.Instrumentation;
-import android.app.Instrumentation.ActivityMonitor;
-import android.app.Instrumentation.ActivityResult;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.ActivityInfo;
-import android.content.res.Configuration;
-import android.graphics.Point;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Debug;
-import android.os.IBinder;
-import android.os.SystemClock;
-import android.test.InstrumentationTestCase;
-import android.test.UiThreadTest;
-import android.view.InputQueue;
-import android.view.KeyCharacterMap;
-import android.view.KeyEvent;
-import android.view.LayoutInflater;
-import android.view.MotionEvent;
-import android.view.SurfaceHolder;
-import android.view.View;
-import android.view.Window;
-import android.view.ViewGroup.LayoutParams;
-
-import java.util.List;
-
-public class InstrumentationTest extends InstrumentationTestCase {
-
-    private static final int WAIT_TIME = 1000;
-    private Instrumentation mInstrumentation;
-    private InstrumentationTestActivity mActivity;
-    private Intent mIntent;
-    private boolean mRunOnMainSyncResult;
-    private Context mContext;
-    private MockActivity mMockActivity;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mInstrumentation = getInstrumentation();
-        mContext = mInstrumentation.getTargetContext();
-        mIntent = new Intent(mContext, InstrumentationTestActivity.class);
-        mIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        mActivity = (InstrumentationTestActivity) mInstrumentation.startActivitySync(mIntent);
-    }
-
-    protected void tearDown() throws Exception {
-        mInstrumentation = null;
-        mIntent = null;
-        if (mActivity != null) {
-            mActivity.finish();
-            mActivity = null;
-        }
-        super.tearDown();
-    }
-
-    public void testConstructor() throws Exception {
-        new Instrumentation();
-    }
-
-    public void testMonitor() throws Exception {
-        if (mActivity != null)
-            mActivity.finish();
-        ActivityResult result = new ActivityResult(Activity.RESULT_OK, new Intent());
-        ActivityMonitor monitor = new ActivityMonitor(
-                InstrumentationTestActivity.class.getName(), result, false);
-        mInstrumentation.addMonitor(monitor);
-        Intent intent = new Intent(mContext, InstrumentationTestActivity.class);
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        mContext.startActivity(intent);
-        Activity activity = mInstrumentation.waitForMonitorWithTimeout(monitor, WAIT_TIME);
-        assertTrue(activity instanceof InstrumentationTestActivity);
-        assertTrue(mInstrumentation.checkMonitorHit(monitor, 1));
-        activity.finish();
-
-        mInstrumentation.addMonitor(monitor);
-        mInstrumentation.removeMonitor(monitor);
-        Activity a = mInstrumentation.startActivitySync(intent);
-        assertTrue(a instanceof InstrumentationTestActivity);
-        activity = mInstrumentation.waitForMonitorWithTimeout(monitor, WAIT_TIME);
-        assertNull(activity);
-        a.finish();
-
-        IntentFilter filter = new IntentFilter();
-        ActivityMonitor am = mInstrumentation.addMonitor(filter, result, false);
-        mContext.startActivity(intent);
-        mInstrumentation.waitForIdleSync();
-        activity = am.waitForActivity();
-        assertTrue(activity instanceof InstrumentationTestActivity);
-        activity.finish();
-        mInstrumentation.removeMonitor(am);
-        am = mInstrumentation
-                .addMonitor(InstrumentationTestActivity.class.getName(), result, false);
-        mContext.startActivity(intent);
-        activity = am.waitForActivity();
-        assertTrue(activity instanceof InstrumentationTestActivity);
-        activity.finish();
-        mInstrumentation.removeMonitor(am);
-    }
-
-    public void testCallActivityOnCreate() throws Throwable {
-        mActivity.setOnCreateCalled(false);
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-                mInstrumentation.callActivityOnCreate(mActivity, new Bundle());
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-        assertTrue(mActivity.isOnCreateCalled());
-    }
-
-    public void testAllocCounting() throws Exception {
-        mInstrumentation.startAllocCounting();
-
-        Bundle b = mInstrumentation.getAllocCounts();
-        assertTrue(b.size() > 0);
-        b = mInstrumentation.getBinderCounts();
-        assertTrue(b.size() > 0);
-
-        int globeAllocCount = Debug.getGlobalAllocCount();
-        int globeAllocSize = Debug.getGlobalAllocSize();
-        int globeExternalAllCount = Debug.getGlobalExternalAllocCount();
-        int globeExternalAllSize = Debug.getGlobalExternalAllocSize();
-        int threadAllocCount = Debug.getThreadAllocCount();
-
-        assertTrue(Debug.getGlobalAllocCount() >= globeAllocCount);
-        assertTrue(Debug.getGlobalAllocSize() >= globeAllocSize);
-        assertTrue(Debug.getGlobalExternalAllocCount() >= globeExternalAllCount);
-        assertTrue(Debug.getGlobalExternalAllocSize() >= globeExternalAllSize);
-        assertTrue(Debug.getThreadAllocCount() >= threadAllocCount);
-
-        mInstrumentation.stopAllocCounting();
-
-        globeAllocCount = Debug.getGlobalAllocCount();
-        globeAllocSize = Debug.getGlobalAllocSize();
-        globeExternalAllCount = Debug.getGlobalExternalAllocCount();
-        globeExternalAllSize = Debug.getGlobalExternalAllocSize();
-        threadAllocCount = Debug.getThreadAllocCount();
-        assertEquals(globeAllocCount, Debug.getGlobalAllocCount());
-        assertEquals(globeAllocSize, Debug.getGlobalAllocSize());
-        assertEquals(globeExternalAllCount, Debug.getGlobalExternalAllocCount());
-        assertEquals(globeExternalAllSize, Debug.getGlobalExternalAllocSize());
-        assertEquals(threadAllocCount, Debug.getThreadAllocCount());
-    }
-
-    public void testSendTrackballEventSync() throws Exception {
-        long now = SystemClock.uptimeMillis();
-        MotionEvent orig = MotionEvent.obtain(now, now, MotionEvent.ACTION_DOWN,
-                100, 100, 0);
-        mInstrumentation.sendTrackballEventSync(orig);
-        mInstrumentation.waitForIdleSync();
-
-        MotionEvent motionEvent = mActivity.getMotionEvent();
-        assertEquals(orig.getMetaState(), motionEvent.getMetaState());
-        assertEquals(orig.getEventTime(), motionEvent.getEventTime());
-        assertEquals(orig.getDownTime(), motionEvent.getDownTime());
-    }
-
-    public void testCallApplicationOnCreate() throws Exception {
-        InstrumentationTestStub ca = new InstrumentationTestStub();
-        mInstrumentation.callApplicationOnCreate(ca);
-        assertTrue(ca.mIsOnCreateCalled);
-    }
-
-    public void testContext() throws Exception {
-        Context c1 = mInstrumentation.getContext();
-        Context c2 = mInstrumentation.getTargetContext();
-        assertNotSame(c1.getPackageName(), c2.getPackageName());
-    }
-
-    public void testInvokeMenuActionSync() throws Exception {
-        final int resId = R.id.goto_menu_id;
-        if (mActivity.getWindow().hasFeature(Window.FEATURE_OPTIONS_PANEL)) {
-            mInstrumentation.invokeMenuActionSync(mActivity, resId, 0);
-            mInstrumentation.waitForIdleSync();
-    
-            assertEquals(resId, mActivity.getMenuID());
-        }
-    }
-
-    public void testCallActivityOnPostCreate() throws Throwable {
-        mActivity.setOnPostCreate(false);
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-                mInstrumentation.callActivityOnPostCreate(mActivity, new Bundle());
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-        assertTrue(mActivity.isOnPostCreate());
-    }
-
-    public void testCallActivityOnNewIntent() throws Throwable {
-        mActivity.setOnNewIntentCalled(false);
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-                mInstrumentation.callActivityOnNewIntent(mActivity, null);
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-
-        assertTrue(mActivity.isOnNewIntentCalled());
-    }
-
-    public void testCallActivityOnResume() throws Throwable {
-        mActivity.setOnResume(false);
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-                mInstrumentation.callActivityOnResume(mActivity);
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-        assertTrue(mActivity.isOnResume());
-    }
-
-    public void testMisc() throws Exception {
-    }
-
-    public void testPerformanceSnapshot() throws Exception {
-        mInstrumentation.setAutomaticPerformanceSnapshots();
-        mInstrumentation.startPerformanceSnapshot();
-        mInstrumentation.endPerformanceSnapshot();
-    }
-
-    public void testProfiling() throws Exception {
-        // by default, profiling was disabled. but after set the handleProfiling attribute in the
-        // manifest file for this Instrumentation to true, the profiling was also disabled.
-        assertFalse(mInstrumentation.isProfiling());
-
-        mInstrumentation.startProfiling();
-        mInstrumentation.stopProfiling();
-    }
-
-    public void testInvokeContextMenuAction() throws Exception {
-        mActivity.runOnUiThread(new Runnable() {
-            public void run() {
-                mMockActivity = new MockActivity();
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-        final int id = 1;
-        final int flag = 2;
-        mInstrumentation.invokeContextMenuAction(mMockActivity, id, flag);
-        mInstrumentation.waitForIdleSync();
-
-        assertEquals(id, mMockActivity.mWindow.mId);
-        assertEquals(flag, mMockActivity.mWindow.mFlags);
-    }
-
-    public void testSendStringSync() {
-        final String text = "abcd";
-        mInstrumentation.sendStringSync(text);
-        mInstrumentation.waitForIdleSync();
-
-        List<KeyEvent> keyUpList = mActivity.getKeyUpList();
-        List<KeyEvent> keyDownList = mActivity.getKeyDownList();
-        assertEquals(text.length(), keyDownList.size());
-        assertEquals(text.length(), keyUpList.size());
-
-        KeyCharacterMap kcm = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD);
-        KeyEvent[] keyEvents = kcm.getEvents(text.toCharArray());
-
-        int i = 0;
-        for (int j = 0; j < keyDownList.size(); j++) {
-            assertEquals(keyEvents[i++].getKeyCode(), keyDownList.get(j).getKeyCode());
-            assertEquals(keyEvents[i++].getKeyCode(), keyUpList.get(j).getKeyCode());
-        }
-    }
-
-    public void testCallActivityOnSaveInstanceState() throws Throwable {
-        final Bundle bundle = new Bundle();
-        mActivity.setOnSaveInstanceState(false);
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-                mInstrumentation.callActivityOnSaveInstanceState(mActivity, bundle);
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-
-        assertTrue(mActivity.isOnSaveInstanceState());
-        assertSame(bundle, mActivity.getBundle());
-    }
-
-    public void testSendPointerSync() throws Exception {
-        mInstrumentation.waitForIdleSync();
-        mInstrumentation.setInTouchMode(true);
-
-        // Send a touch event to the middle of the activity.
-        // We assume that the Activity is empty so there won't be anything in the middle
-        // to handle the touch.  Consequently the Activity should receive onTouchEvent
-        // because nothing else handled it.
-        Point size = new Point();
-        mActivity.getWindowManager().getDefaultDisplay().getSize(size);
-        final int x = size.x / 2;
-        final int y = size.y / 2;
-        long now = SystemClock.uptimeMillis();
-        MotionEvent orig = MotionEvent.obtain(now, now, MotionEvent.ACTION_DOWN,
-                x, y, 0);
-        mInstrumentation.sendPointerSync(orig);
-
-        mInstrumentation.waitForIdleSync();
-        assertTrue(mActivity.isOnTouchEventCalled());
-        mActivity.setOnTouchEventCalled(false);
-    }
-
-    public void testGetComponentName() throws Exception {
-        ComponentName com = getInstrumentation().getComponentName();
-        assertNotNull(com.getPackageName());
-        assertNotNull(com.getClassName());
-        assertNotNull(com.getShortClassName());
-    }
-
-    public void testNewApplication() throws Exception {
-        final String className = "android.app.cts.MockApplication";
-        ClassLoader cl = getClass().getClassLoader();
-
-        Application app = mInstrumentation.newApplication(cl, className, mContext);
-        assertEquals(className, app.getClass().getName());
-
-        app = Instrumentation.newApplication(MockApplication.class, mContext);
-        assertEquals(className, app.getClass().getName());
-    }
-
-    public void testRunOnMainSync() throws Exception {
-        mRunOnMainSyncResult = false;
-        mInstrumentation.runOnMainSync(new Runnable() {
-            public void run() {
-                mRunOnMainSyncResult = true;
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-        assertTrue(mRunOnMainSyncResult);
-    }
-
-    public void testCallActivityOnPause() throws Exception {
-        mActivity.setOnPauseCalled(false);
-        mInstrumentation.callActivityOnPause(mActivity);
-        mInstrumentation.waitForIdleSync();
-        assertTrue(mActivity.isOnPauseCalled());
-    }
-
-    public void testSendKeyDownUpSync() throws Exception {
-        mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_0);
-        mInstrumentation.waitForIdleSync();
-        assertEquals(1, mActivity.getKeyUpList().size());
-        assertEquals(1, mActivity.getKeyDownList().size());
-        assertEquals(KeyEvent.KEYCODE_0, mActivity.getKeyUpList().get(0).getKeyCode());
-        assertEquals(KeyEvent.KEYCODE_0, mActivity.getKeyDownList().get(0).getKeyCode());
-    }
-
-    @UiThreadTest
-    public void testNewActivity() throws Exception {
-        Intent intent = new Intent();
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-
-        ClassLoader cl = getClass().getClassLoader();
-        Activity activity = mInstrumentation.newActivity(cl, InstrumentationTestActivity.class
-                .getName(), intent);
-        assertEquals(InstrumentationTestActivity.class.getName(), activity.getClass().getName());
-        activity.finish();
-        activity = null;
-
-        intent = new Intent(mContext, InstrumentationTestActivity.class);
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-
-        Activity father = new Activity();
-        ActivityInfo info = new ActivityInfo();
-
-        activity = mInstrumentation
-                .newActivity(InstrumentationTestActivity.class, mContext, null, null, intent, info,
-                        InstrumentationTestActivity.class.getName(), father, null, null);
-
-        assertEquals(father, activity.getParent());
-        assertEquals(InstrumentationTestActivity.class.getName(), activity.getClass().getName());
-        activity.finish();
-    }
-
-    public void testCallActivityOnStart() throws Exception {
-        mActivity.setOnStart(false);
-        mInstrumentation.callActivityOnStart(mActivity);
-        mInstrumentation.waitForIdleSync();
-        assertTrue(mActivity.isOnStart());
-    }
-
-    public void testWaitForIdle() throws Exception {
-        MockRunnable mr = new MockRunnable();
-        assertFalse(mr.isRunCalled());
-        mInstrumentation.waitForIdle(mr);
-        Thread.sleep(WAIT_TIME);
-        assertTrue(mr.isRunCalled());
-    }
-
-    public void testSendCharacterSync() throws Exception {
-        mInstrumentation.sendCharacterSync(KeyEvent.KEYCODE_0);
-        mInstrumentation.waitForIdleSync();
-        assertEquals(KeyEvent.KEYCODE_0, mActivity.getKeyDownCode());
-        assertEquals(KeyEvent.KEYCODE_0, mActivity.getKeyUpCode());
-    }
-
-    public void testCallActivityOnRestart() throws Exception {
-        mActivity.setOnRestart(false);
-        mInstrumentation.callActivityOnRestart(mActivity);
-        mInstrumentation.waitForIdleSync();
-        assertTrue(mActivity.isOnRestart());
-    }
-
-    public void testCallActivityOnStop() throws Exception {
-        mActivity.setOnStop(false);
-        mInstrumentation.callActivityOnStop(mActivity);
-        mInstrumentation.waitForIdleSync();
-        assertTrue(mActivity.isOnStop());
-    }
-
-    public void testCallActivityOnUserLeaving() throws Exception {
-        assertFalse(mActivity.isOnLeave());
-        mInstrumentation.callActivityOnUserLeaving(mActivity);
-        mInstrumentation.waitForIdleSync();
-        assertTrue(mActivity.isOnLeave());
-    }
-
-    public void testCallActivityOnRestoreInstanceState() throws Exception {
-        mActivity.setOnRestoreInstanceState(false);
-        mInstrumentation.callActivityOnRestoreInstanceState(mActivity, new Bundle());
-        mInstrumentation.waitForIdleSync();
-        assertTrue(mActivity.isOnRestoreInstanceState());
-    }
-
-    public void testSendKeySync() throws Exception {
-        KeyEvent key = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_0);
-        mInstrumentation.sendKeySync(key);
-        mInstrumentation.waitForIdleSync();
-        assertEquals(KeyEvent.KEYCODE_0, mActivity.getKeyDownCode());
-    }
-
-    private static class MockRunnable implements Runnable {
-        private boolean mIsRunCalled ;
-
-        public void run() {
-            mIsRunCalled = true;
-        }
-
-        public boolean isRunCalled() {
-            return mIsRunCalled;
-        }
-    }
-
-    private class MockActivity extends Activity {
-        MockWindow mWindow = new MockWindow(mContext);
-
-        @Override
-        public Window getWindow() {
-            return mWindow;
-        }
-
-        private class MockWindow extends Window {
-
-            public int mId;
-            public int mFlags;
-
-            public MockWindow(Context context) {
-                super(context);
-            }
-
-            @Override
-            public void addContentView(View view, LayoutParams params) {
-            }
-
-            @Override
-            public void closeAllPanels() {
-            }
-
-            @Override
-            public void closePanel(int featureId) {
-            }
-
-            @Override
-            public View getCurrentFocus() {
-                return null;
-            }
-
-            @Override
-            public View getDecorView() {
-                return null;
-            }
-
-            @Override
-            public LayoutInflater getLayoutInflater() {
-                return null;
-            }
-
-            @Override
-            public int getVolumeControlStream() {
-                return 0;
-            }
-
-            @Override
-            public boolean isFloating() {
-                return false;
-            }
-
-            @Override
-            public boolean isShortcutKey(int keyCode, KeyEvent event) {
-                return false;
-            }
-
-            @Override
-            protected void onActive() {
-            }
-
-            @Override
-            public void onConfigurationChanged(Configuration newConfig) {
-            }
-
-            @Override
-            public void openPanel(int featureId, KeyEvent event) {
-            }
-
-            public void alwaysReadCloseOnTouchAttr() {
-            }
-
-            @Override
-            public View peekDecorView() {
-                return null;
-            }
-
-            @Override
-            public boolean performContextMenuIdentifierAction(int id, int flags) {
-                mId = id;
-                mFlags = flags;
-                return false;
-            }
-
-            @Override
-            public boolean performPanelIdentifierAction(int featureId, int id, int flags) {
-                return false;
-            }
-
-            @Override
-            public boolean performPanelShortcut(int featureId, int keyCode,
-                    KeyEvent event, int flags) {
-                return false;
-            }
-
-            @Override
-            public void restoreHierarchyState(Bundle savedInstanceState) {
-            }
-
-            @Override
-            public Bundle saveHierarchyState() {
-                return null;
-            }
-
-            @Override
-            public void setBackgroundDrawable(Drawable drawable) {
-            }
-
-            @Override
-            public void setChildDrawable(int featureId, Drawable drawable) {
-            }
-
-            @Override
-            public void setChildInt(int featureId, int value) {
-            }
-
-            @Override
-            public void setContentView(int layoutResID) {
-            }
-
-            @Override
-            public void setContentView(View view) {
-            }
-
-            @Override
-            public void setContentView(View view, LayoutParams params) {
-            }
-
-            @Override
-            public void setFeatureDrawable(int featureId, Drawable drawable) {
-            }
-
-            @Override
-            public void setFeatureDrawableAlpha(int featureId, int alpha) {
-            }
-
-            @Override
-            public void setFeatureDrawableResource(int featureId, int resId) {
-            }
-
-            @Override
-            public void setFeatureDrawableUri(int featureId, Uri uri) {
-            }
-
-            @Override
-            public void setFeatureInt(int featureId, int value) {
-            }
-
-            @Override
-            public void setTitle(CharSequence title) {
-            }
-
-            @Override
-            public void setTitleColor(int textColor) {
-            }
-
-            @Override
-            public void setVolumeControlStream(int streamType) {
-            }
-
-            @Override
-            public boolean superDispatchKeyEvent(KeyEvent event) {
-                return false;
-            }
-
-            @Override
-            public boolean superDispatchKeyShortcutEvent(KeyEvent event) {
-                return false;
-            }
-
-            @Override
-            public boolean superDispatchTouchEvent(MotionEvent event) {
-                return false;
-            }
-
-            @Override
-            public boolean superDispatchTrackballEvent(MotionEvent event) {
-                return false;
-            }
-
-            @Override
-            public boolean superDispatchGenericMotionEvent(MotionEvent event) {
-                return false;
-            }
-
-            @Override
-            public void takeKeyEvents(boolean get) {
-            }
-
-            @Override
-            public void togglePanel(int featureId, KeyEvent event) {
-            }
-
-            @Override
-            public void invalidatePanelMenu(int featureId) {
-            }
-
-            @Override
-            public void takeSurface(SurfaceHolder.Callback2 callback) {
-            }
-
-            @Override
-            public void takeInputQueue(InputQueue.Callback queue) {
-            }
-
-            @Override
-            public void setStatusBarColor(int color) {
-            }
-
-            @Override
-            public int getStatusBarColor() {
-                return 0;
-            }
-
-            @Override
-            public void setNavigationBarColor(int color) {
-            }
-
-            @Override
-            public int getNavigationBarColor() {
-                return 0;
-            }
-        }
-    }
-
-    private static class InstrumentationTestStub extends Application {
-        boolean mIsOnCreateCalled = false;
-
-        @Override
-        public void onCreate() {
-            super.onCreate();
-            mIsOnCreateCalled = true;
-        }
-    }
-}
diff --git a/tests/tests/app/src/android/app/cts/Instrumentation_ActivityMonitorTest.java b/tests/tests/app/src/android/app/cts/Instrumentation_ActivityMonitorTest.java
deleted file mode 100644
index 767142c..0000000
--- a/tests/tests/app/src/android/app/cts/Instrumentation_ActivityMonitorTest.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-import android.app.Activity;
-import android.app.Instrumentation;
-import android.app.Instrumentation.ActivityMonitor;
-import android.app.Instrumentation.ActivityResult;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.test.InstrumentationTestCase;
-
-public class Instrumentation_ActivityMonitorTest extends InstrumentationTestCase {
-
-    private static final long WAIT_TIMEOUT = 100;
-
-    /**
-     * check points:
-     * 1 Constructor with blocking true and false
-     * 2 waitForActivity with timeout and no timeout
-     * 3 get info about ActivityMonitor
-     */
-    public void testActivityMonitor() throws Exception {
-        ActivityResult result = new ActivityResult(Activity.RESULT_OK, new Intent());
-        Instrumentation instrumentation = getInstrumentation();
-        ActivityMonitor am = instrumentation.addMonitor(
-                InstrumentationTestActivity.class.getName(), result, false);
-        Context context = instrumentation.getTargetContext();
-        Intent intent = new Intent(context, InstrumentationTestActivity.class);
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        context.startActivity(intent);
-        Activity lastActivity = am.getLastActivity();
-        final long TIMEOUT_MSEC = 5000;
-        long timeout = System.currentTimeMillis() + TIMEOUT_MSEC;
-        while (lastActivity == null && System.currentTimeMillis() < timeout) {
-            Thread.sleep(WAIT_TIMEOUT);
-            lastActivity = am.getLastActivity();
-        }
-        Activity activity = am.waitForActivity();
-        assertSame(activity, lastActivity);
-        assertEquals(1, am.getHits());
-        assertTrue(activity instanceof InstrumentationTestActivity);
-        activity.finish();
-        instrumentation.waitForIdleSync();
-        context.startActivity(intent);
-        timeout = System.currentTimeMillis() + TIMEOUT_MSEC;
-        activity = null;
-        while (activity == null && System.currentTimeMillis() < timeout) {
-            Thread.sleep(WAIT_TIMEOUT);
-            activity = am.waitForActivityWithTimeout(WAIT_TIMEOUT);
-        }
-        assertNotNull(activity);
-        activity.finish();
-        instrumentation.removeMonitor(am);
-
-        am = new ActivityMonitor(InstrumentationTestActivity.class.getName(), result, true);
-        assertSame(result, am.getResult());
-        assertTrue(am.isBlocking());
-        IntentFilter which = new IntentFilter();
-        am = new ActivityMonitor(which, result, false);
-        assertSame(which, am.getFilter());
-        assertFalse(am.isBlocking());
-    }
-}
diff --git a/tests/tests/app/src/android/app/cts/IntentServiceTest.java b/tests/tests/app/src/android/app/cts/IntentServiceTest.java
deleted file mode 100644
index 42c4730..0000000
--- a/tests/tests/app/src/android/app/cts/IntentServiceTest.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.cts.util.PollingCheck;
-import android.os.IBinder;
-
-import java.util.concurrent.Callable;
-
-
-public class IntentServiceTest extends ActivityTestsBase {
-
-    private Intent mIntent;
-    private static final int TIMEOUT_MSEC = 30000;
-    private boolean mConnected;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        IntentServiceStub.reset();
-        mIntent = new Intent(mContext, IntentServiceStub.class);
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-        mContext.stopService(mIntent);
-    }
-
-    public void testIntents() throws Throwable {
-        final int value = 42;
-        final int adds = 3;
-
-        Intent addIntent = new Intent(mContext, IntentServiceStub.class);
-
-        addIntent.setAction(IntentServiceStub.ISS_ADD);
-        addIntent.putExtra(IntentServiceStub.ISS_VALUE, 42);
-
-        for (int i = 0; i < adds; i++) {
-            mContext.startService(addIntent);
-        }
-
-        PollingCheck.check("onHandleIntentCalled not called enough", TIMEOUT_MSEC,
-                new Callable<Boolean>() {
-            @Override
-            public Boolean call() throws Exception {
-                return IntentServiceStub.getOnHandleIntentCalledCount() == adds;
-            }
-        });
-
-        PollingCheck.check("accumulator not correct", TIMEOUT_MSEC, new Callable<Boolean>() {
-            @Override
-            public Boolean call() throws Exception {
-                return IntentServiceStub.getAccumulator() == adds * value;
-            }
-        });
-
-        PollingCheck.check("onDestroyCalled not called", TIMEOUT_MSEC, new Callable<Boolean>() {
-            @Override
-            public Boolean call() throws Exception {
-                return IntentServiceStub.isOnDestroyCalled();
-            }
-        });
-    }
-
-    public void testIntentServiceLifeCycle() throws Throwable {
-        // start service
-        mContext.startService(mIntent);
-        new PollingCheck(TIMEOUT_MSEC) {
-            protected boolean check() {
-                return IntentServiceStub.getOnHandleIntentCalledCount() > 0;
-            }
-        }.run();
-        assertTrue(IntentServiceStub.isOnCreateCalled());
-        assertTrue(IntentServiceStub.isOnStartCalled());
-
-        // bind service
-        ServiceConnection conn = new TestConnection();
-        mContext.bindService(mIntent, conn, Context.BIND_AUTO_CREATE);
-        new PollingCheck(TIMEOUT_MSEC) {
-            protected boolean check() {
-                return mConnected;
-            }
-        }.run();
-        assertTrue(IntentServiceStub.isOnBindCalled());
-
-        // unbind service
-        mContext.unbindService(conn);
-        // stop service
-        mContext.stopService(mIntent);
-        IntentServiceStub.waitToFinish(TIMEOUT_MSEC);
-    }
-
-    private class TestConnection implements ServiceConnection {
-
-        public void onServiceConnected(ComponentName name, IBinder service) {
-            mConnected = true;
-        }
-
-        public void onServiceDisconnected(ComponentName name) {
-        }
-    }
-}
diff --git a/tests/tests/app/src/android/app/cts/KeyguardManagerKeyguardLockTest.java b/tests/tests/app/src/android/app/cts/KeyguardManagerKeyguardLockTest.java
deleted file mode 100644
index 7a9f534..0000000
--- a/tests/tests/app/src/android/app/cts/KeyguardManagerKeyguardLockTest.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-
-import android.app.KeyguardManager;
-import android.test.InstrumentationTestCase;
-
-public class KeyguardManagerKeyguardLockTest extends InstrumentationTestCase {
-
-    public void testDisableKeyguard() {
-    }
-
-    public void testReenableKeyguard() {
-    }
-}
diff --git a/tests/tests/app/src/android/app/cts/KeyguardManagerTest.java b/tests/tests/app/src/android/app/cts/KeyguardManagerTest.java
deleted file mode 100644
index cb7cd4a..0000000
--- a/tests/tests/app/src/android/app/cts/KeyguardManagerTest.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-
-import android.app.KeyguardManager;
-import android.content.Context;
-import android.test.ActivityInstrumentationTestCase2;
-
-public class KeyguardManagerTest
-        extends ActivityInstrumentationTestCase2<KeyguardManagerActivity> {
-
-    private static final String TAG = "KeyguardManagerTest";
-
-    public KeyguardManagerTest() {
-        super("com.android.cts.app.stub", KeyguardManagerActivity.class);
-    }
-
-    public void testNewKeyguardLock() {
-        final Context c = getInstrumentation().getContext();
-        final KeyguardManager keyguardManager = (KeyguardManager) c.getSystemService(
-                Context.KEYGUARD_SERVICE);
-        final KeyguardManager.KeyguardLock keyLock = keyguardManager.newKeyguardLock(TAG);
-        assertNotNull(keyLock);
-    }
-
-    public void testInKeyguardRestrictedInputMode() {
-    }
-
-    public void testExitKeyguardSecurely() {
-    }
-}
diff --git a/tests/tests/app/src/android/app/cts/LaunchTest.java b/tests/tests/app/src/android/app/cts/LaunchTest.java
deleted file mode 100644
index 26cdc20..0000000
--- a/tests/tests/app/src/android/app/cts/LaunchTest.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-import android.app.Activity;
-import android.app.Dialog;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.res.Resources.Theme;
-import android.database.Cursor;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
-import android.os.Bundle;
-import android.util.AttributeSet;
-import android.view.ContextMenu;
-import android.view.KeyEvent;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ContextMenu.ContextMenuInfo;
-import android.view.WindowManager.LayoutParams;
-
-public class LaunchTest extends ActivityTestsBase {
-
-    public void testClearTopWhilResumed() {
-        mIntent.putExtra("component", new ComponentName(getContext(), ClearTop.class));
-        mIntent.putExtra(ClearTop.WAIT_CLEAR_TASK, true);
-        runLaunchpad(LaunchpadActivity.LAUNCH);
-    }
-
-    public void testClearTopInCreate() throws Exception {
-        mIntent.putExtra("component", new ComponentName(getContext(), ClearTop.class));
-        runLaunchpad(LaunchpadActivity.LAUNCH);
-    }
-
-    public void testForwardResult() {
-        runLaunchpad(LaunchpadActivity.FORWARD_RESULT);
-    }
-
-    public void testLocalScreen() {
-        mIntent.putExtra("component", new ComponentName(getContext(), LocalScreen.class));
-        runLaunchpad(LaunchpadActivity.LAUNCH);
-    }
-
-    public void testColdScreen() {
-        mIntent.putExtra("component", new ComponentName(getContext(), TestedScreen.class));
-        runLaunchpad(LaunchpadActivity.LAUNCH);
-    }
-
-    public void testLocalActivity() {
-        mIntent.putExtra("component", new ComponentName(getContext(), LocalActivity.class));
-        runLaunchpad(LaunchpadActivity.LAUNCH);
-    }
-
-    public void testColdActivity() {
-        mIntent.putExtra("component", new ComponentName(getContext(), TestedActivity.class));
-        runLaunchpad(LaunchpadActivity.LAUNCH);
-    }
-}
diff --git a/tests/tests/app/src/android/app/cts/LauncherActivityTest.java b/tests/tests/app/src/android/app/cts/LauncherActivityTest.java
deleted file mode 100644
index 3eea0b7..0000000
--- a/tests/tests/app/src/android/app/cts/LauncherActivityTest.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-import android.app.Activity;
-import android.app.Instrumentation;
-import android.app.LauncherActivity;
-import android.app.LauncherActivity.ListItem;
-import android.content.Context;
-import android.content.Intent;
-import android.test.InstrumentationTestCase;
-import android.test.ActivityInstrumentationTestCase2;
-import android.test.UiThreadTest;
-import android.view.KeyEvent;
-
-import java.util.List;
-
-public class LauncherActivityTest
-        extends ActivityInstrumentationTestCase2<LauncherActivityStub> {
-
-    private Instrumentation mInstrumentation;
-    private LauncherActivityStub mActivity;
-
-    public LauncherActivityTest() {
-        super("com.android.cts.app.stub", LauncherActivityStub.class);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mInstrumentation = getInstrumentation();
-        mActivity = getActivity();
-    }
-
-    public void testLaunchActivity() throws Throwable {
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-                // Test getTargetIntent. LaunchActivity#getTargetIntent() just returns a Intent() instance
-                // with no content, so we use LaunchActivityStub#getSuperIntent() to get the default Intent,
-                // and create a new intent for other tests.
-                assertNotNull(mActivity.getSuperIntent());
-
-                // Test makeListItems. Make sure the size > 0. The sorted order is related to the sort
-                // way, so it's mutable.
-                final List<ListItem> list = mActivity.makeListItems();
-                assertTrue(list.size() > 0);
-
-                // There should be an activity(but with uncertain content) in position 0.
-                assertNotNull(mActivity.intentForPosition(0));
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-        // Test onListItemClick
-        sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
-        sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
-        sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
-        sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
-        assertTrue(mActivity.isOnListItemClick);
-    }
-}
diff --git a/tests/tests/app/src/android/app/cts/LauncherActivity_IconResizerTest.java b/tests/tests/app/src/android/app/cts/LauncherActivity_IconResizerTest.java
deleted file mode 100644
index 2fdc8ec..0000000
--- a/tests/tests/app/src/android/app/cts/LauncherActivity_IconResizerTest.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-import com.android.cts.app.stub.R;
-
-
-import android.app.LauncherActivity;
-import android.app.LauncherActivity.IconResizer;
-import android.graphics.drawable.Drawable;
-import android.test.ActivityInstrumentationTestCase2;
-
-public class LauncherActivity_IconResizerTest extends
-        ActivityInstrumentationTestCase2<LauncherActivityStub> {
-
-    private static final String PACKAGE = "com.android.cts.app.stub";
-    private LauncherActivityStub mActivity;
-
-    public LauncherActivity_IconResizerTest() {
-        super(PACKAGE, LauncherActivityStub.class);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mActivity = getActivity();
-    }
-
-    public void testIconResizer() throws Throwable {
-        final IconResizer ir = mActivity.new IconResizer();
-        final Drawable d = mActivity.getResources().getDrawable(R.drawable.pass);
-        assertNotNull(d);
-
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-                Drawable thumbNail = ir.createIconThumbnail(d);
-                assertNotNull(thumbNail);
-                // The size of the thumbnail is defined by inner R resource file
-                // whose details are not open.
-                assertTrue(thumbNail.getIntrinsicHeight() > 0);
-                assertTrue(thumbNail.getIntrinsicWidth() > 0);
-            }
-        });
-        getInstrumentation().waitForIdleSync();
-    }
-}
diff --git a/tests/tests/app/src/android/app/cts/LauncherActivity_ListItemTest.java b/tests/tests/app/src/android/app/cts/LauncherActivity_ListItemTest.java
deleted file mode 100644
index 14ef831..0000000
--- a/tests/tests/app/src/android/app/cts/LauncherActivity_ListItemTest.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-
-import android.app.LauncherActivity;
-import android.test.AndroidTestCase;
-
-public class LauncherActivity_ListItemTest extends AndroidTestCase {
-    public void testConstructor() {
-        // Test public constructor
-        new LauncherActivity.ListItem();
-    }
-}
diff --git a/tests/tests/app/src/android/app/cts/LifecycleTest.java b/tests/tests/app/src/android/app/cts/LifecycleTest.java
deleted file mode 100644
index 5d2ded7..0000000
--- a/tests/tests/app/src/android/app/cts/LifecycleTest.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-
-import android.app.Activity;
-import android.app.Dialog;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.res.Configuration;
-import android.content.res.Resources.Theme;
-import android.database.Cursor;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
-import android.os.Bundle;
-import android.util.AttributeSet;
-import android.view.ContextMenu;
-import android.view.KeyEvent;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ContextMenu.ContextMenuInfo;
-import android.view.WindowManager.LayoutParams;
-
-public class LifecycleTest extends ActivityTestsBase {
-    private Intent mTopIntent;
-    private Intent mTabIntent;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mTopIntent = mIntent;
-        mTabIntent = new Intent(mContext, LaunchpadTabActivity.class);
-        mTabIntent.putExtra("tab", new ComponentName(mContext, LaunchpadActivity.class));
-    }
-
-    public void testTabDialog() {
-        mIntent = mTabIntent;
-        runLaunchpad(LaunchpadActivity.LIFECYCLE_DIALOG);
-    }
-
-    public void testDialog() {
-        mIntent = mTopIntent;
-        runLaunchpad(LaunchpadActivity.LIFECYCLE_DIALOG);
-    }
-
-    public void testTabScreen() {
-        mIntent = mTabIntent;
-        runLaunchpad(LaunchpadActivity.LIFECYCLE_SCREEN);
-    }
-
-    public void testScreen() {
-        mIntent = mTopIntent;
-        runLaunchpad(LaunchpadActivity.LIFECYCLE_SCREEN);
-    }
-
-    public void testTabBasic() {
-        mIntent = mTabIntent;
-        runLaunchpad(LaunchpadActivity.LIFECYCLE_BASIC);
-    }
-
-    public void testBasic() {
-        mIntent = mTopIntent;
-        runLaunchpad(LaunchpadActivity.LIFECYCLE_BASIC);
-    }
-}
diff --git a/tests/tests/app/src/android/app/cts/LocalActivityManagerTest.java b/tests/tests/app/src/android/app/cts/LocalActivityManagerTest.java
deleted file mode 100644
index db3baba..0000000
--- a/tests/tests/app/src/android/app/cts/LocalActivityManagerTest.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-import android.app.Activity;
-import android.app.Instrumentation;
-import android.app.LocalActivityManager;
-import android.content.Intent;
-import android.cts.util.CTSResult;
-import android.test.InstrumentationTestCase;
-import android.test.UiThreadTest;
-
-public class LocalActivityManagerTest extends InstrumentationTestCase implements CTSResult {
-
-    private Instrumentation mInstrumentation;
-
-    private Sync mSync = new Sync();
-    private static class Sync {
-        public boolean mHasNotify;
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mInstrumentation = getInstrumentation();
-        mSync = new Sync();
-    }
-
-    private void setupActivity(final String action) {
-        final Intent intent = new Intent(mInstrumentation.getTargetContext(),
-                LocalActivityManagerTestHelper.class);
-        intent.setAction(action);
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        mInstrumentation.getTargetContext().startActivity(intent);
-    }
-
-    @UiThreadTest
-    public void testConstructor() {
-        new LocalActivityManager(new Activity(), true);
-        new LocalActivityManager(new Activity(), false);
-        new LocalActivityManager(null, false);
-        new LocalActivityManager(null, true);
-    }
-
-    public void testDispatchResume() throws InterruptedException {
-        LocalActivityManagerTestHelper.setResult(this);
-        setupActivity(LocalActivityManagerTestHelper.ACTION_DISPATCH_RESUME);
-        waitForResult();
-    }
-
-    private void waitForResult() throws InterruptedException {
-        synchronized (mSync) {
-            if (!mSync.mHasNotify) {
-                mSync.wait();
-            }
-        }
-    }
-
-    public void testStartActivity() throws InterruptedException {
-        LocalActivityManagerTestHelper.setResult(this);
-        setupActivity(LocalActivityManagerTestHelper.ACTION_START_ACTIVITY);
-        waitForResult();
-    }
-
-    public void testDispatchCreate() throws InterruptedException {
-        LocalActivityManagerTestHelper.setResult(this);
-        setupActivity(LocalActivityManagerTestHelper.ACTION_DISPATCH_CREATE);
-        waitForResult();
-    }
-
-    public void testDispatchStop() throws InterruptedException {
-        LocalActivityManagerTestHelper.setResult(this);
-        setupActivity(LocalActivityManagerTestHelper.ACTION_DISPATCH_STOP);
-        waitForResult();
-    }
-
-    public void testDispatchPauseTrue() throws InterruptedException {
-        LocalActivityManagerTestHelper.setResult(this);
-        setupActivity(LocalActivityManagerTestHelper.ACTION_DISPATCH_PAUSE_TRUE);
-        waitForResult();
-    }
-
-    public void testDispatchPauseFalse() throws InterruptedException {
-        LocalActivityManagerTestHelper.setResult(this);
-        setupActivity(LocalActivityManagerTestHelper.ACTION_DISPATCH_PAUSE_FALSE);
-        waitForResult();
-    }
-
-    public void testSaveInstanceState() throws InterruptedException {
-        LocalActivityManagerTestHelper.setResult(this);
-        setupActivity(LocalActivityManagerTestHelper.ACTION_SAVE_INSTANCE_STATE);
-        waitForResult();
-    }
-
-    public void testDispatchDestroy() throws InterruptedException {
-        LocalActivityManagerTestHelper.setResult(this);
-        setupActivity(LocalActivityManagerTestHelper.ACTION_DISPATCH_DESTROY);
-        waitForResult();
-    }
-
-    public void testRemoveAllActivities() throws InterruptedException {
-        LocalActivityManagerTestHelper.setResult(this);
-        setupActivity(LocalActivityManagerTestHelper.ACTION_REMOVE_ALL_ACTIVITY);
-        waitForResult();
-    }
-
-    public void setResult(final int resultCode) {
-        synchronized (mSync) {
-            mSync.mHasNotify = true;
-            mSync.notify();
-            assertEquals(CTSResult.RESULT_OK, resultCode);
-        }
-    }
-
-    public void setResult(Exception e) {
-        setResult(CTSResult.RESULT_FAIL);
-    }
-
-}
diff --git a/tests/tests/app/src/android/app/cts/NotificationManagerTest.java b/tests/tests/app/src/android/app/cts/NotificationManagerTest.java
deleted file mode 100644
index c5a41c3..0000000
--- a/tests/tests/app/src/android/app/cts/NotificationManagerTest.java
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-import android.app.Notification;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.content.Context;
-import android.content.Intent;
-import android.provider.Telephony.Threads;
-import android.service.notification.StatusBarNotification;
-import android.test.AndroidTestCase;
-import android.util.Log;
-
-import com.android.cts.app.stub.R;
-
-
-public class NotificationManagerTest extends AndroidTestCase {
-    final String TAG = NotificationManagerTest.class.getSimpleName();
-    final boolean DEBUG = false;
-
-    private NotificationManager mNotificationManager;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mNotificationManager = (NotificationManager) mContext.getSystemService(
-                Context.NOTIFICATION_SERVICE);
-        // clear the deck so that our getActiveNotifications results are predictable
-        mNotificationManager.cancelAll();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-        mNotificationManager.cancelAll();
-    }
-
-    public void testNotify() {
-        mNotificationManager.cancelAll();
-
-        final int id = 1;
-        sendNotification(id, R.drawable.black);
-        // test updating the same notification
-        sendNotification(id, R.drawable.blue);
-        sendNotification(id, R.drawable.yellow);
-
-        // assume that sendNotification tested to make sure individual notifications were present
-        StatusBarNotification[] sbns = mNotificationManager.getActiveNotifications();
-        for (StatusBarNotification sbn : sbns) {
-            if (sbn.getId() != id) {
-                fail("we got back other notifications besides the one we posted: "
-                        + sbn.getKey());
-            }
-        }
-    }
-
-    public void testCancel() {
-        final int id = 9;
-        sendNotification(id, R.drawable.black);
-        mNotificationManager.cancel(id);
-
-        if (!checkNotificationExistence(id, /*shouldExist=*/ false)) {
-            fail("canceled notification was still alive, id=" + id);
-        }
-    }
-
-    public void testCancelAll() {
-        sendNotification(1, R.drawable.black);
-        sendNotification(2, R.drawable.blue);
-        sendNotification(3, R.drawable.yellow);
-
-        if (DEBUG) {
-            Log.d(TAG, "posted 3 notifications, here they are: ");
-            StatusBarNotification[] sbns = mNotificationManager.getActiveNotifications();
-            for (StatusBarNotification sbn : sbns) {
-                Log.d(TAG, "  " + sbn);
-            }
-            Log.d(TAG, "about to cancel...");
-        }
-        mNotificationManager.cancelAll();
-
-        StatusBarNotification[] sbns = mNotificationManager.getActiveNotifications();
-        assertTrue("notification list was not empty after cancelAll", sbns.length == 0);
-    }
-
-    private void sendNotification(final int id, final int icon) {
-        final Intent intent = new Intent(Intent.ACTION_MAIN, Threads.CONTENT_URI);
-
-        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP
-                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
-        intent.setAction(Intent.ACTION_MAIN);
-
-        final PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, intent, 0);
-        final Notification notification = new Notification.Builder(mContext)
-                .setSmallIcon(icon)
-                .setWhen(System.currentTimeMillis())
-                .setContentTitle("notify#" + id)
-                .setContentText("This is #" + id + "notification  ")
-                .setContentIntent(pendingIntent)
-                .build();
-        mNotificationManager.notify(id, notification);
-
-
-        if (!checkNotificationExistence(id, /*shouldExist=*/ true)) {
-            fail("couldn't find posted notification id=" + id);
-        }
-    }
-
-    private boolean checkNotificationExistence(int id, boolean shouldExist) {
-        // notification is a bit asynchronous so it may take a few ms to appear in getActiveNotifications()
-        // we will check for it for up to 200ms before giving up
-        boolean found = false;
-        for (int tries=3; tries-->0;) {
-            // Need reset flag.
-            found = false;
-            final StatusBarNotification[] sbns = mNotificationManager.getActiveNotifications();
-            for (StatusBarNotification sbn : sbns) {
-                if (sbn.getId() == id) {
-                    found = true;
-                    break;
-                }
-            }
-            if (found == shouldExist) break;
-            try {
-                Thread.sleep(100);
-            } catch (InterruptedException ex) {
-                // pass
-            }
-        }
-        return found == shouldExist;
-    }
-}
diff --git a/tests/tests/app/src/android/app/cts/NotificationTest.java b/tests/tests/app/src/android/app/cts/NotificationTest.java
deleted file mode 100644
index 6179922..0000000
--- a/tests/tests/app/src/android/app/cts/NotificationTest.java
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-import android.app.Notification;
-import android.app.PendingIntent;
-import android.content.Context;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Parcel;
-import android.test.AndroidTestCase;
-import android.widget.RemoteViews;
-
-public class NotificationTest extends AndroidTestCase {
-
-    private Notification mNotification;
-    private Context mContext;
-
-    private static final String TICKER_TEXT = "tickerText";
-    private static final String CONTENT_TITLE = "contentTitle";
-    private static final String CONTENT_TEXT = "contentText";
-    private static final String URI_STRING = "uriString";
-    private static final int TOLERANCE = 200;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mContext = getContext();
-        mNotification = new Notification();
-    }
-
-    public void testConstructor() {
-        mNotification = null;
-        mNotification = new Notification();
-        assertNotNull(mNotification);
-        assertTrue(System.currentTimeMillis() - mNotification.when < TOLERANCE);
-
-        mNotification = null;
-        final int notificationTime = 200;
-        mNotification = new Notification(0, TICKER_TEXT, notificationTime);
-        assertEquals(notificationTime, mNotification.when);
-        assertEquals(0, mNotification.icon);
-        assertEquals(TICKER_TEXT, mNotification.tickerText);
-    }
-
-    public void testDescribeContents() {
-        final int expected = 0;
-        mNotification = new Notification();
-        assertEquals(expected, mNotification.describeContents());
-    }
-
-    public void testWriteToParcel() {
-        mNotification = new Notification();
-        mNotification.icon = 0;
-        mNotification.number = 1;
-        final Intent intent = new Intent();
-        final PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0);
-        mNotification.contentIntent = pendingIntent;
-        final Intent deleteIntent = new Intent();
-        final PendingIntent delPendingIntent = PendingIntent.getBroadcast(
-                mContext, 0, deleteIntent, 0);
-        mNotification.deleteIntent = delPendingIntent;
-        mNotification.tickerText = TICKER_TEXT;
-
-        final RemoteViews contentView = new RemoteViews(mContext.getPackageName(),
-                android.R.layout.simple_list_item_1);
-        mNotification.contentView = contentView;
-        mNotification.defaults = 0;
-        mNotification.flags = 0;
-        final Uri uri = Uri.parse(URI_STRING);
-        mNotification.sound = uri;
-        mNotification.audioStreamType = 0;
-        final long[] longArray = { 1l, 2l, 3l };
-        mNotification.vibrate = longArray;
-        mNotification.ledARGB = 0;
-        mNotification.ledOnMS = 0;
-        mNotification.ledOffMS = 0;
-        mNotification.iconLevel = 0;
-        Parcel parcel = Parcel.obtain();
-        mNotification.writeToParcel(parcel, 0);
-        parcel.setDataPosition(0);
-        // Test Notification(Parcel)
-        Notification result = new Notification(parcel);
-        assertEquals(mNotification.icon, result.icon);
-        assertEquals(mNotification.when, result.when);
-        assertEquals(mNotification.number, result.number);
-        assertNotNull(result.contentIntent);
-        assertNotNull(result.deleteIntent);
-        assertEquals(mNotification.tickerText, result.tickerText);
-        assertNotNull(result.contentView);
-        assertEquals(mNotification.defaults, result.defaults);
-        assertEquals(mNotification.flags, result.flags);
-        assertNotNull(result.sound);
-        assertEquals(mNotification.audioStreamType, result.audioStreamType);
-        assertEquals(mNotification.vibrate[0], result.vibrate[0]);
-        assertEquals(mNotification.vibrate[1], result.vibrate[1]);
-        assertEquals(mNotification.vibrate[2], result.vibrate[2]);
-        assertEquals(mNotification.ledARGB, result.ledARGB);
-        assertEquals(mNotification.ledOnMS, result.ledOnMS);
-        assertEquals(mNotification.ledOffMS, result.ledOffMS);
-        assertEquals(mNotification.iconLevel, result.iconLevel);
-
-        mNotification.contentIntent = null;
-        parcel = Parcel.obtain();
-        mNotification.writeToParcel(parcel, 0);
-        parcel.setDataPosition(0);
-        result = new Notification(parcel);
-        assertNull(result.contentIntent);
-
-        mNotification.deleteIntent = null;
-        parcel = Parcel.obtain();
-        mNotification.writeToParcel(parcel, 0);
-        parcel.setDataPosition(0);
-        result = new Notification(parcel);
-        assertNull(result.deleteIntent);
-
-        mNotification.tickerText = null;
-        parcel = Parcel.obtain();
-        mNotification.writeToParcel(parcel, 0);
-        parcel.setDataPosition(0);
-        result = new Notification(parcel);
-        assertNull(result.tickerText);
-
-        mNotification.contentView = null;
-        parcel = Parcel.obtain();
-        mNotification.writeToParcel(parcel, 0);
-        parcel.setDataPosition(0);
-        result = new Notification(parcel);
-        assertNull(result.contentView);
-
-        mNotification.sound = null;
-        parcel = Parcel.obtain();
-        mNotification.writeToParcel(parcel, 0);
-        parcel.setDataPosition(0);
-        result = new Notification(parcel);
-        assertNull(result.sound);
-    }
-
-    public void testBuilder() {
-        final Intent intent = new Intent();
-        final PendingIntent contentIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0);
-        mNotification = new Notification.Builder(mContext)
-                .setSmallIcon(1)
-                .setContentTitle(CONTENT_TITLE)
-                .setContentText(CONTENT_TEXT)
-                .setContentIntent(contentIntent)
-                .build();
-        assertEquals(CONTENT_TEXT, mNotification.extras.getString(Notification.EXTRA_TEXT));
-        assertEquals(CONTENT_TITLE, mNotification.extras.getString(Notification.EXTRA_TITLE));
-        assertEquals(1, mNotification.icon);
-        assertEquals(contentIntent, mNotification.contentIntent);
-        assertNotNull(mNotification.contentView);
-    }
-
-    public void testToString() {
-        mNotification = new Notification();
-        assertNotNull(mNotification.toString());
-    }
-}
diff --git a/tests/tests/app/src/android/app/cts/PendingIntentTest.java b/tests/tests/app/src/android/app/cts/PendingIntentTest.java
deleted file mode 100644
index d2c1b31..0000000
--- a/tests/tests/app/src/android/app/cts/PendingIntentTest.java
+++ /dev/null
@@ -1,453 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-import android.app.PendingIntent;
-import android.app.PendingIntent.CanceledException;
-import android.content.Context;
-import android.content.Intent;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.os.Parcel;
-import android.test.AndroidTestCase;
-
-public class PendingIntentTest extends AndroidTestCase {
-
-    private static final int WAIT_TIME = 5000;
-    private PendingIntent mPendingIntent;
-    private Intent mIntent;
-    private Context mContext;
-    private boolean mFinishResult;
-    private boolean mHandleResult;
-    private String mResultAction;
-    private PendingIntent.OnFinished mFinish;
-    private boolean mLooperStart;
-    private Looper mLooper;
-    private Handler mHandler;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mContext = getContext();
-        mFinish = new PendingIntent.OnFinished() {
-            public void onSendFinished(PendingIntent pi, Intent intent, int resultCode,
-                    String resultData, Bundle resultExtras) {
-                mFinishResult = true;
-                if (intent != null) {
-                    mResultAction = intent.getAction();
-                }
-            }
-        };
-
-        new Thread() {
-            @Override
-            public void run() {
-                Looper.prepare();
-                mLooper = Looper.myLooper();
-                mLooperStart = true;
-                Looper.loop();
-            }
-        }.start();
-        while (!mLooperStart) {
-            Thread.sleep(50);
-        }
-        mHandler = new Handler(mLooper) {
-            @Override
-            public void dispatchMessage(Message msg) {
-                mHandleResult = true;
-                super.dispatchMessage(msg);
-            }
-
-            @Override
-            public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
-                mHandleResult = true;
-                return super.sendMessageAtTime(msg, uptimeMillis);
-            }
-
-            @Override
-            public void handleMessage(Message msg) {
-                super.handleMessage(msg);
-                mHandleResult = true;
-            }
-        };
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-        mLooper.quit();
-    }
-
-    public void testGetActivity() throws InterruptedException, CanceledException {
-        PendingIntentStubActivity.status = PendingIntentStubActivity.INVALIDATE;
-        mPendingIntent = null;
-        mIntent = new Intent();
-
-        mIntent.setClass(mContext, PendingIntentStubActivity.class);
-        mIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        mPendingIntent = PendingIntent.getActivity(mContext, 1, mIntent,
-                PendingIntent.FLAG_CANCEL_CURRENT);
-        assertEquals(mContext.getPackageName(), mPendingIntent.getTargetPackage());
-
-        mPendingIntent.send();
-
-        Thread.sleep(WAIT_TIME);
-        assertNotNull(mPendingIntent);
-        assertEquals(PendingIntentStubActivity.status, PendingIntentStubActivity.ON_CREATE);
-
-        // test getActivity return null
-        mPendingIntent.cancel();
-        mPendingIntent = PendingIntent.getActivity(mContext, 1, mIntent,
-                PendingIntent.FLAG_NO_CREATE);
-        assertNull(mPendingIntent);
-
-        mPendingIntent = PendingIntent.getActivity(mContext, 1, mIntent,
-                PendingIntent.FLAG_ONE_SHOT);
-
-        pendingIntentSendError(mPendingIntent);
-    }
-
-    private void pendingIntentSendError(PendingIntent pendingIntent) {
-        try {
-            // From the doc send function will throw CanceledException if the PendingIntent
-            // is no longer allowing more intents to be sent through it. So here call it twice then
-            // a CanceledException should be caught.
-            mPendingIntent.send();
-            mPendingIntent.send();
-            fail("CanceledException expected, but not thrown");
-        } catch (PendingIntent.CanceledException e) {
-            // expected
-        }
-    }
-
-    public void testGetBroadcast() throws InterruptedException, CanceledException {
-        MockReceiver.sAction = null;
-        mIntent = new Intent(MockReceiver.MOCKACTION);
-        mIntent.setClass(mContext, MockReceiver.class);
-        mPendingIntent = PendingIntent.getBroadcast(mContext, 1, mIntent,
-                PendingIntent.FLAG_CANCEL_CURRENT);
-
-        mPendingIntent.send();
-
-        Thread.sleep(WAIT_TIME);
-        assertEquals(MockReceiver.MOCKACTION, MockReceiver.sAction);
-
-        // test getBroadcast return null
-        mPendingIntent.cancel();
-        mPendingIntent = PendingIntent.getBroadcast(mContext, 1, mIntent,
-                PendingIntent.FLAG_NO_CREATE);
-        assertNull(mPendingIntent);
-
-        mPendingIntent = PendingIntent.getBroadcast(mContext, 1, mIntent,
-                PendingIntent.FLAG_ONE_SHOT);
-
-        pendingIntentSendError(mPendingIntent);
-    }
-
-    public void testGetService() throws InterruptedException, CanceledException {
-        MockService.result = false;
-        mIntent = new Intent();
-        mIntent.setClass(mContext, MockService.class);
-        mPendingIntent = PendingIntent.getService(mContext, 1, mIntent,
-                PendingIntent.FLAG_CANCEL_CURRENT);
-
-        mPendingIntent.send();
-
-        Thread.sleep(WAIT_TIME);
-        assertTrue(MockService.result);
-
-        // test getService return null
-        mPendingIntent.cancel();
-        mPendingIntent = PendingIntent.getService(mContext, 1, mIntent,
-                PendingIntent.FLAG_NO_CREATE);
-        assertNull(mPendingIntent);
-
-        mPendingIntent = PendingIntent.getService(mContext, 1, mIntent,
-                PendingIntent.FLAG_ONE_SHOT);
-
-        pendingIntentSendError(mPendingIntent);
-    }
-
-    public void testCancel() throws CanceledException {
-        mIntent = new Intent();
-        mIntent.setClass(mContext, MockService.class);
-        mPendingIntent = PendingIntent.getBroadcast(mContext, 1, mIntent,
-                PendingIntent.FLAG_CANCEL_CURRENT);
-
-        mPendingIntent.send();
-
-        mPendingIntent.cancel();
-        pendingIntentSendShouldFail(mPendingIntent);
-    }
-
-    private void pendingIntentSendShouldFail(PendingIntent pendingIntent) {
-        try {
-            pendingIntent.send();
-            fail("CanceledException expected, but not thrown");
-        } catch (CanceledException e) {
-            // expected
-        }
-    }
-
-    public void testSend() throws InterruptedException, CanceledException {
-        MockReceiver.sAction = null;
-        MockReceiver.sResultCode = -1;
-        mIntent = new Intent();
-        mIntent.setAction(MockReceiver.MOCKACTION);
-        mIntent.setClass(mContext, MockReceiver.class);
-        mPendingIntent = PendingIntent.getBroadcast(mContext, 1, mIntent,
-                PendingIntent.FLAG_CANCEL_CURRENT);
-
-        mPendingIntent.send();
-
-        Thread.sleep(WAIT_TIME);
-
-        // send function to send default code 0
-        assertEquals(0, MockReceiver.sResultCode);
-        assertEquals(MockReceiver.MOCKACTION, MockReceiver.sAction);
-        mPendingIntent.cancel();
-
-        pendingIntentSendShouldFail(mPendingIntent);
-    }
-
-    public void testSendWithParamInt() throws InterruptedException, CanceledException {
-        mIntent = new Intent(MockReceiver.MOCKACTION);
-        mIntent.setClass(mContext, MockReceiver.class);
-        mPendingIntent = PendingIntent.getBroadcast(mContext, 1, mIntent,
-                PendingIntent.FLAG_CANCEL_CURRENT);
-        MockReceiver.sResultCode = 0;
-        MockReceiver.sAction = null;
-        // send result code 1.
-        mPendingIntent.send(1);
-        Thread.sleep(WAIT_TIME);
-        assertEquals(MockReceiver.MOCKACTION, MockReceiver.sAction);
-
-        // assert the result code
-        assertEquals(1, MockReceiver.sResultCode);
-        assertEquals(mResultAction, null);
-
-        mResultAction = null;
-        MockReceiver.sResultCode = 0;
-        // send result code 2
-        mPendingIntent.send(2);
-        Thread.sleep(WAIT_TIME);
-
-        assertEquals(MockReceiver.MOCKACTION, MockReceiver.sAction);
-
-        // assert the result code
-        assertEquals(2, MockReceiver.sResultCode);
-        assertEquals(MockReceiver.sAction, MockReceiver.MOCKACTION);
-        assertNull(mResultAction);
-        mPendingIntent.cancel();
-        pendingIntentSendShouldFail(mPendingIntent);
-    }
-
-    public void testSendWithParamContextIntIntent() throws InterruptedException, CanceledException {
-        mIntent = new Intent(MockReceiver.MOCKACTION);
-        mIntent.setClass(mContext, MockReceiver.class);
-
-        MockReceiver.sAction = null;
-        MockReceiver.sResultCode = 0;
-
-        mPendingIntent = PendingIntent.getBroadcast(mContext, 1, mIntent, 1);
-
-        mPendingIntent.send(mContext, 1, null);
-        Thread.sleep(WAIT_TIME);
-
-        assertEquals(MockReceiver.MOCKACTION, MockReceiver.sAction);
-        assertEquals(1, MockReceiver.sResultCode);
-        mPendingIntent.cancel();
-
-        mPendingIntent = PendingIntent.getBroadcast(mContext, 1, mIntent, 1);
-        MockReceiver.sAction = null;
-        MockReceiver.sResultCode = 0;
-
-        mPendingIntent.send(mContext, 2, mIntent);
-        Thread.sleep(WAIT_TIME);
-        assertEquals(MockReceiver.MOCKACTION, MockReceiver.sAction);
-        assertEquals(2, MockReceiver.sResultCode);
-        mPendingIntent.cancel();
-    }
-
-    public void testSendWithParamIntOnFinishedHandler() throws InterruptedException,
-            CanceledException {
-        mIntent = new Intent(MockReceiver.MOCKACTION);
-        mIntent.setClass(mContext, MockReceiver.class);
-
-        mPendingIntent = PendingIntent.getBroadcast(mContext, 1, mIntent, 1);
-        mFinishResult = false;
-        mHandleResult = false;
-        MockReceiver.sAction = null;
-        MockReceiver.sResultCode = 0;
-
-        mPendingIntent.send(1, null, null);
-        Thread.sleep(WAIT_TIME);
-        assertFalse(mFinishResult);
-        assertFalse(mHandleResult);
-        assertEquals(MockReceiver.MOCKACTION, MockReceiver.sAction);
-
-        // assert result code
-        assertEquals(1, MockReceiver.sResultCode);
-        mPendingIntent.cancel();
-
-        mPendingIntent = PendingIntent.getBroadcast(mContext, 1, mIntent, 1);
-        mFinishResult = false;
-        MockReceiver.sAction = null;
-        MockReceiver.sResultCode = 0;
-        mHandleResult = false;
-
-        mPendingIntent.send(2, mFinish, null);
-        Thread.sleep(WAIT_TIME);
-        assertTrue(mFinishResult);
-        assertFalse(mHandleResult);
-        assertEquals(MockReceiver.MOCKACTION, MockReceiver.sAction);
-
-        // assert result code
-        assertEquals(2, MockReceiver.sResultCode);
-        mPendingIntent.cancel();
-
-        mHandleResult = false;
-        mFinishResult = false;
-        mPendingIntent = PendingIntent.getBroadcast(mContext, 1, mIntent, 1);
-        MockReceiver.sAction = null;
-        mPendingIntent.send(3, mFinish, mHandler);
-        Thread.sleep(WAIT_TIME);
-        assertTrue(mHandleResult);
-        assertTrue(mFinishResult);
-        assertEquals(MockReceiver.MOCKACTION, MockReceiver.sAction);
-
-        // assert result code
-        assertEquals(3, MockReceiver.sResultCode);
-        mPendingIntent.cancel();
-    }
-
-    public void testSendWithParamContextIntIntentOnFinishedHandler() throws InterruptedException,
-            CanceledException {
-        mIntent = new Intent(MockReceiver.MOCKACTION);
-        mIntent.setAction(MockReceiver.MOCKACTION);
-
-        mPendingIntent = PendingIntent.getBroadcast(mContext, 1, mIntent, 1);
-        mFinishResult = false;
-        mResultAction = null;
-        mHandleResult = false;
-        mPendingIntent.send(mContext, 1, mIntent, null, null);
-        Thread.sleep(WAIT_TIME);
-        assertFalse(mFinishResult);
-        assertFalse(mHandleResult);
-        assertNull(mResultAction);
-        mPendingIntent.cancel();
-
-        mPendingIntent = PendingIntent.getBroadcast(mContext, 1, mIntent, 1);
-        mFinishResult = false;
-        mResultAction = null;
-        mHandleResult = false;
-        mPendingIntent.send(mContext, 1, mIntent, mFinish, null);
-        Thread.sleep(WAIT_TIME);
-        assertTrue(mFinishResult);
-        assertEquals(mResultAction, MockReceiver.MOCKACTION);
-        assertFalse(mHandleResult);
-        mPendingIntent.cancel();
-
-        mPendingIntent = PendingIntent.getBroadcast(mContext, 1, mIntent, 1);
-        mFinishResult = false;
-        mResultAction = null;
-        mHandleResult = false;
-        mPendingIntent.send(mContext, 1, mIntent, mFinish, mHandler);
-        Thread.sleep(WAIT_TIME);
-        assertTrue(mHandleResult);
-        assertEquals(mResultAction, MockReceiver.MOCKACTION);
-        assertTrue(mFinishResult);
-        mPendingIntent.cancel();
-    }
-
-    public void testGetTargetPackage() {
-        mIntent = new Intent();
-        mPendingIntent = PendingIntent.getActivity(mContext, 1, mIntent,
-                PendingIntent.FLAG_CANCEL_CURRENT);
-        assertEquals(mContext.getPackageName(), mPendingIntent.getTargetPackage());
-    }
-
-    public void testEquals() {
-        mIntent = new Intent();
-        mPendingIntent = PendingIntent.getActivity(mContext, 1, mIntent,
-                PendingIntent.FLAG_CANCEL_CURRENT);
-
-        PendingIntent target = PendingIntent.getActivity(mContext, 1, mIntent,
-                PendingIntent.FLAG_CANCEL_CURRENT);
-
-        assertFalse(mPendingIntent.equals(target));
-        assertFalse(mPendingIntent.hashCode() == target.hashCode());
-        mPendingIntent = PendingIntent.getActivity(mContext, 1, mIntent, 1);
-
-        target = PendingIntent.getActivity(mContext, 1, mIntent, 1);
-        assertTrue(mPendingIntent.equals(target));
-
-        mIntent = new Intent(MockReceiver.MOCKACTION);
-        target = PendingIntent.getBroadcast(mContext, 1, mIntent, 1);
-        assertFalse(mPendingIntent.equals(target));
-        assertFalse(mPendingIntent.hashCode() == target.hashCode());
-
-        mPendingIntent = PendingIntent.getActivity(mContext, 1, mIntent, 1);
-        target = PendingIntent.getActivity(mContext, 1, mIntent, 1);
-
-        assertTrue(mPendingIntent.equals(target));
-        assertEquals(mPendingIntent.hashCode(), target.hashCode());
-    }
-
-    public void testDescribeContents() {
-        mIntent = new Intent();
-        mPendingIntent = PendingIntent.getActivity(mContext, 1, mIntent,
-                PendingIntent.FLAG_CANCEL_CURRENT);
-        final int expected = 0;
-        assertEquals(expected, mPendingIntent.describeContents());
-    }
-
-    public void testWriteToParcel() {
-        mIntent = new Intent();
-        mPendingIntent = PendingIntent.getActivity(mContext, 1, mIntent,
-                PendingIntent.FLAG_CANCEL_CURRENT);
-        Parcel parcel = Parcel.obtain();
-
-        mPendingIntent.writeToParcel(parcel, 0);
-        parcel.setDataPosition(0);
-        PendingIntent pendingIntent = PendingIntent.CREATOR.createFromParcel(parcel);
-        assertTrue(mPendingIntent.equals(pendingIntent));
-    }
-
-    public void testReadAndWritePendingIntentOrNullToParcel() {
-        mIntent = new Intent();
-        mPendingIntent = PendingIntent.getActivity(mContext, 1, mIntent,
-                PendingIntent.FLAG_CANCEL_CURRENT);
-        assertNotNull(mPendingIntent.toString());
-
-        Parcel parcel = Parcel.obtain();
-        PendingIntent.writePendingIntentOrNullToParcel(mPendingIntent, parcel);
-        parcel.setDataPosition(0);
-        PendingIntent target = PendingIntent.readPendingIntentOrNullFromParcel(parcel);
-        assertEquals(mPendingIntent, target);
-        assertEquals(mPendingIntent.getTargetPackage(), target.getTargetPackage());
-
-        mPendingIntent = null;
-        parcel = Parcel.obtain();
-        PendingIntent.writePendingIntentOrNullToParcel(mPendingIntent, parcel);
-        target = PendingIntent.readPendingIntentOrNullFromParcel(parcel);
-        assertNull(target);
-    }
-
-}
diff --git a/tests/tests/app/src/android/app/cts/ProgressDialogTest.java b/tests/tests/app/src/android/app/cts/ProgressDialogTest.java
deleted file mode 100644
index b2037b6..0000000
--- a/tests/tests/app/src/android/app/cts/ProgressDialogTest.java
+++ /dev/null
@@ -1,364 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-
-import android.app.Instrumentation;
-import android.app.ProgressDialog;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.DialogInterface.OnCancelListener;
-import android.graphics.drawable.Drawable;
-import android.os.Bundle;
-import android.test.ActivityInstrumentationTestCase2;
-import android.test.UiThreadTest;
-import android.view.KeyEvent;
-import android.view.Window;
-import android.widget.ProgressBar;
-
-/**
- * Test {@link ProgressDialog}.
- */
-public class ProgressDialogTest extends ActivityInstrumentationTestCase2<MockActivity> {
-    private final CharSequence TITLE = "title";
-    private final CharSequence MESSAGE = "message";
-
-    private boolean mCanceled;
-    private Drawable mDrawable;
-    private Drawable mActualDrawableNull;
-    private Drawable mActualDrawable;
-    private ProgressBar mProgressBar;
-    private int mProgress1;
-    private int mProgress2;
-
-    private Context mContext;
-    private Instrumentation mInstrumentation;
-    private MockActivity mActivity;
-
-    public ProgressDialogTest() {
-        super("com.android.cts.app.stub", MockActivity.class);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-
-        mCanceled = false;
-        mInstrumentation = getInstrumentation();
-        mActivity = getActivity();
-        mContext = mActivity;
-        mDrawable = getActivity().getResources().getDrawable(
-                com.android.cts.app.stub.R.drawable.yellow);
-    }
-
-    @UiThreadTest
-    public void testProgressDialog1(){
-        new ProgressDialog(mContext);
-    }
-
-    @UiThreadTest
-    public void testProgressDialog2(){
-        new ProgressDialog(mContext, com.android.cts.app.stub.R.style.Theme_AlertDialog);
-    }
-
-    @UiThreadTest
-    public void testOnStartCreateStop() {
-        MockProgressDialog pd = new MockProgressDialog(mContext);
-
-        assertFalse(pd.mIsOnCreateCalled);
-        assertFalse(pd.mIsOnStartCalled);
-        pd.show();
-        assertTrue(pd.mIsOnCreateCalled);
-        assertTrue(pd.mIsOnStartCalled);
-
-        assertFalse(pd.mIsOnStopCalled);
-        pd.dismiss();
-        assertTrue(pd.mIsOnStopCalled);
-    }
-
-    @UiThreadTest
-    public void testShow1() {
-        ProgressDialog.show(mContext, TITLE, MESSAGE);
-    }
-
-    @UiThreadTest
-    public void testShow2() {
-        ProgressDialog dialog = ProgressDialog.show(mContext, TITLE, MESSAGE, false);
-
-        /*
-         * note: the progress bar's style only supports indeterminate mode,
-         * so can't change indeterminate
-         */
-        assertTrue(dialog.isIndeterminate());
-
-        dialog = ProgressDialog.show(mContext, TITLE, MESSAGE, true);
-        assertTrue(dialog.isIndeterminate());
-    }
-
-    public void testShow3() throws Throwable {
-        final OnCancelListener cL = new OnCancelListener(){
-            public void onCancel(DialogInterface dialog) {
-                mCanceled = true;
-            }
-        };
-
-        // cancelable is false
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-                ProgressDialog dialog = ProgressDialog.show(mContext, TITLE, MESSAGE, true, false);
-
-                dialog.setOnCancelListener(cL);
-                dialog.onBackPressed();
-                dialog.dismiss();
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-
-        assertFalse(mCanceled);
-
-        // cancelable is true
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-                ProgressDialog dialog = ProgressDialog.show(mContext, TITLE, MESSAGE, true, true);
-                assertFalse(mCanceled);
-                dialog.setOnCancelListener(cL);
-                dialog.onBackPressed();
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-
-        assertTrue(mCanceled);
-    }
-
-    public void testShow4() throws Throwable {
-        final OnCancelListener cL = new OnCancelListener(){
-            public void onCancel(DialogInterface dialog) {
-                mCanceled = true;
-            }
-        };
-
-        // cancelable is false
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-                ProgressDialog dialog = ProgressDialog.show(
-                        mContext, TITLE, MESSAGE, true, false, cL);
-
-                dialog.onBackPressed();
-                dialog.dismiss();;
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-
-        assertFalse(mCanceled);
-
-        // cancelable is true
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-                ProgressDialog dialog = ProgressDialog.show(
-                        mContext, TITLE, MESSAGE, true, true, cL);
-
-                assertFalse(mCanceled);
-                dialog.onBackPressed();
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-
-        assertTrue(mCanceled);
-    }
-
-    @UiThreadTest
-    public void testAccessMax() {
-        // progressDialog is null
-        ProgressDialog progressDialog = buildDialog();
-        progressDialog.setMax(2008);
-        assertEquals(2008, progressDialog.getMax());
-
-        // progressDialog is not null
-        progressDialog = ProgressDialog.show(mContext, TITLE, MESSAGE);
-        progressDialog.setMax(2009);
-        assertEquals(2009, progressDialog.getMax());
-    }
-
-    @UiThreadTest
-    public void testAccessProgress() {
-        // progressDialog is null
-        ProgressDialog progressDialog = buildDialog();
-        progressDialog.setProgress(11);
-        assertEquals(11, progressDialog.getProgress());
-
-        /* progressDialog is not null
-         * note: the progress bar's style only supports indeterminate mode,
-         * so can't change progress
-         */
-        progressDialog = ProgressDialog.show(mContext, TITLE, MESSAGE);
-        progressDialog.setProgress(12);
-        assertEquals(0, progressDialog.getProgress());
-    }
-
-    @UiThreadTest
-    public void testAccessSecondaryProgress() {
-        // dialog is null
-        ProgressDialog dialog = buildDialog();
-        dialog.setSecondaryProgress(17);
-        assertEquals(17, dialog.getSecondaryProgress());
-
-        /* mProgress is not null
-         * note: the progress bar's style only supports indeterminate mode,
-         * so can't change secondary progress
-         */
-        dialog = ProgressDialog.show(mContext, TITLE, MESSAGE);
-        dialog.setSecondaryProgress(18);
-        assertEquals(0, dialog.getSecondaryProgress());
-    }
-
-    @UiThreadTest
-    public void testSetIndeterminate() {
-        // progress is null
-        ProgressDialog dialog = buildDialog();
-        dialog.setIndeterminate(true);
-        assertTrue(dialog.isIndeterminate());
-        dialog.setIndeterminate(false);
-        assertFalse(dialog.isIndeterminate());
-
-        /* mProgress is not null
-         * note: the progress bar's style only supports indeterminate mode,
-         * so can't change indeterminate
-         */
-        dialog = ProgressDialog.show(mContext, TITLE, MESSAGE);
-        dialog.setIndeterminate(true);
-        assertTrue(dialog.isIndeterminate());
-        dialog.setIndeterminate(false);
-        assertTrue(dialog.isIndeterminate());
-    }
-
-    @UiThreadTest
-    public void testIncrementProgressBy() throws Throwable {
-        ProgressDialog dialog = new ProgressDialog(mContext);
-        dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
-        dialog.show();
-        dialog.setProgress(10);
-        mProgress1 = dialog.getProgress();
-        dialog.incrementProgressBy(60);
-        mProgress2 = dialog.getProgress();
-        dialog.cancel();
-
-        assertEquals(10, mProgress1);
-        assertEquals(70, mProgress2);
-    }
-
-    @UiThreadTest
-    public void testIncrementSecondaryProgressBy() throws Throwable {
-        ProgressDialog dialog = new ProgressDialog(mContext);
-        dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
-        dialog.show();
-        dialog.setSecondaryProgress(10);
-        mProgress1 = dialog.getSecondaryProgress();
-        dialog.incrementSecondaryProgressBy(60);
-        mProgress2 = dialog.getSecondaryProgress();
-
-        assertEquals(10, mProgress1);
-        assertEquals(70, mProgress2);
-    }
-
-    @UiThreadTest
-    public void testSetProgressDrawable() throws Throwable {
-        ProgressDialog dialog = ProgressDialog.show(mContext, TITLE, MESSAGE);
-        Window w = dialog.getWindow();
-        ProgressBar progressBar = (ProgressBar) w.findViewById(android.R.id.progress);
-
-        dialog.setProgressDrawable(mDrawable);
-        mActualDrawable = progressBar.getProgressDrawable();
-
-        dialog.setProgressDrawable(null);
-        mActualDrawableNull = progressBar.getProgressDrawable();
-        assertEquals(mDrawable, mActualDrawable);
-        assertEquals(null, mActualDrawableNull);
-    }
-
-    @UiThreadTest
-    public void testSetIndeterminateDrawable() throws Throwable {
-        ProgressDialog dialog = ProgressDialog.show(mContext, TITLE, MESSAGE);
-        Window w = dialog.getWindow();
-        mProgressBar = (ProgressBar) w.findViewById(android.R.id.progress);
-
-        dialog.setIndeterminateDrawable(mDrawable);
-        mActualDrawable = mProgressBar.getIndeterminateDrawable();
-        assertEquals(mDrawable, mActualDrawable);
-
-        dialog.setIndeterminateDrawable(null);
-        mActualDrawableNull = mProgressBar.getIndeterminateDrawable();
-        assertEquals(null, mActualDrawableNull);
-    }
-
-    @UiThreadTest
-    public void testSetMessage() throws Throwable {
-        ProgressDialog dialog = new ProgressDialog(mContext);
-        dialog = new ProgressDialog(mContext);
-        dialog.setMessage(MESSAGE);
-        dialog.show();
-        // dialog is not null
-        dialog = ProgressDialog.show(mContext, TITLE, MESSAGE);
-        dialog.setMessage("Chuck Norris");
-    }
-
-    @UiThreadTest
-    public void testSetProgressStyle() throws Throwable {
-        ProgressDialog dialog = new ProgressDialog(mContext);
-        setProgressStyle(dialog, ProgressDialog.STYLE_HORIZONTAL);
-        setProgressStyle(dialog, ProgressDialog.STYLE_SPINNER);
-        setProgressStyle(dialog, 100);
-    }
-
-    private void setProgressStyle(ProgressDialog dialog, int style) {
-        dialog.setProgressStyle(style);
-        dialog.show();
-        dialog.setProgress(10);
-        dialog.setMax(100);
-    }
-
-    private static class MockProgressDialog extends ProgressDialog {
-        public boolean mIsOnStopCalled;
-        public boolean mIsOnStartCalled;
-        public boolean mIsOnCreateCalled;
-
-        public MockProgressDialog(Context context) {
-            super(context);
-        }
-
-        @Override
-        protected void onCreate(Bundle savedInstanceState) {
-            super.onCreate(savedInstanceState);
-            mIsOnCreateCalled = true;
-        }
-
-        @Override
-        public void onStart(){
-            super.onStart();
-            mIsOnStartCalled = true;
-        }
-
-        @Override
-        public void onStop() {
-            super.onStop();
-            mIsOnStopCalled = true;
-        }
-    }
-
-    private ProgressDialog buildDialog() {
-        return new ProgressDialog(mContext);
-    }
-}
diff --git a/tests/tests/app/src/android/app/cts/SearchManagerTest.java b/tests/tests/app/src/android/app/cts/SearchManagerTest.java
deleted file mode 100644
index 1cece76..0000000
--- a/tests/tests/app/src/android/app/cts/SearchManagerTest.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-import android.content.Intent;
-import android.cts.util.CTSResult;
-
-public class SearchManagerTest extends CTSActivityTestCaseBase {
-
-    private void setupActivity(String action) {
-        Intent intent = new Intent();
-        intent.setAction(action);
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        intent.setClass(getInstrumentation().getTargetContext(), SearchManagerStubActivity.class);
-        getInstrumentation().getTargetContext().startActivity(intent);
-    }
-
-    public void testStopSearch() throws InterruptedException {
-        SearchManagerStubActivity.setCTSResult(this);
-        setupActivity(SearchManagerStubActivity.TEST_STOP_SEARCH);
-        waitForResult();
-    }
-
-    public void testSetOnDismissListener() throws InterruptedException {
-        SearchManagerStubActivity.setCTSResult(this);
-        setupActivity(SearchManagerStubActivity.TEST_ON_DISMISSLISTENER);
-        waitForResult();
-    }
-
-    public void testSetOnCancelListener() throws InterruptedException {
-        SearchManagerStubActivity.setCTSResult(this);
-        setupActivity(SearchManagerStubActivity.TEST_ON_CANCELLISTENER);
-        waitForResult();
-    }
-}
diff --git a/tests/tests/app/src/android/app/cts/ServiceTest.java b/tests/tests/app/src/android/app/cts/ServiceTest.java
deleted file mode 100644
index 8ba1816..0000000
--- a/tests/tests/app/src/android/app/cts/ServiceTest.java
+++ /dev/null
@@ -1,464 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.cts.util.IBinderParcelable;
-import android.os.Binder;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.Parcel;
-import android.os.RemoteException;
-import android.test.suitebuilder.annotation.MediumTest;
-
-public class ServiceTest extends ActivityTestsBase {
-    private static final int STATE_START_1 = 0;
-    private static final int STATE_START_2 = 1;
-    private static final int STATE_UNBIND = 2;
-    private static final int STATE_DESTROY = 3;
-    private static final int STATE_REBIND = 4;
-    private static final int STATE_UNBIND_ONLY = 5;
-    private static final int DELAY = 5000;
-    private static final
-        String EXIST_CONN_TO_RECEIVE_SERVICE = "existing connection to receive service";
-    private static final String EXIST_CONN_TO_LOSE_SERVICE = "existing connection to lose service";
-    private int mExpectedServiceState;
-    private Context mContext;
-    private Intent mLocalService;
-    private Intent mLocalDeniedService;
-    private Intent mLocalGrantedService;
-    private Intent mLocalService_ApplicationHasPermission;
-    private Intent mLocalService_ApplicationDoesNotHavePermission;
-
-    private IBinder mStateReceiver;
-
-    private static class EmptyConnection implements ServiceConnection {
-        @Override
-        public void onServiceConnected(ComponentName name, IBinder service) {
-        }
-
-        @Override
-        public void onServiceDisconnected(ComponentName name) {
-        }
-    }
-
-    private class TestConnection implements ServiceConnection {
-        private final boolean mExpectDisconnect;
-        private final boolean mSetReporter;
-        private boolean mMonitor;
-        private int mCount;
-
-        public TestConnection(boolean expectDisconnect, boolean setReporter) {
-            mExpectDisconnect = expectDisconnect;
-            mSetReporter = setReporter;
-            mMonitor = !setReporter;
-        }
-
-        void setMonitor(boolean v) {
-            mMonitor = v;
-        }
-
-        @Override
-        public void onServiceConnected(ComponentName name, IBinder service) {
-            if (mSetReporter) {
-                Parcel data = Parcel.obtain();
-                data.writeInterfaceToken(LocalService.SERVICE_LOCAL);
-                data.writeStrongBinder(mStateReceiver);
-                try {
-                    service.transact(LocalService.SET_REPORTER_CODE, data, null, 0);
-                } catch (RemoteException e) {
-                    finishBad("DeadObjectException when sending reporting object");
-                }
-                data.recycle();
-            }
-
-            if (mMonitor) {
-                mCount++;
-                if (mExpectedServiceState == STATE_START_1) {
-                    if (mCount == 1) {
-                        finishGood();
-                    } else {
-                        finishBad("onServiceConnected() again on an object when it "
-                                + "should have been the first time");
-                    }
-                } else if (mExpectedServiceState == STATE_START_2) {
-                    if (mCount == 2) {
-                        finishGood();
-                    } else {
-                        finishBad("onServiceConnected() the first time on an object "
-                                + "when it should have been the second time");
-                    }
-                } else {
-                    finishBad("onServiceConnected() called unexpectedly");
-                }
-            }
-        }
-
-        @Override
-        public void onServiceDisconnected(ComponentName name) {
-            if (mMonitor) {
-                if (mExpectedServiceState == STATE_DESTROY) {
-                    if (mExpectDisconnect) {
-                        finishGood();
-                    } else {
-                        finishBad("onServiceDisconnected() when it shouldn't have been");
-                    }
-                } else {
-                    finishBad("onServiceDisconnected() called unexpectedly");
-                }
-            }
-        }
-    }
-
-    private void startExpectResult(Intent service) {
-        startExpectResult(service, new Bundle());
-    }
-
-    private void startExpectResult(Intent service, Bundle bundle) {
-        bundle.putParcelable(LocalService.REPORT_OBJ_NAME, new IBinderParcelable(mStateReceiver));
-
-        boolean success = false;
-        try {
-            mExpectedServiceState = STATE_START_1;
-            mContext.startService(new Intent(service).putExtras(bundle));
-            waitForResultOrThrow(DELAY, "service to start first time");
-            mExpectedServiceState = STATE_START_2;
-            mContext.startService(new Intent(service).putExtras(bundle));
-            waitForResultOrThrow(DELAY, "service to start second time");
-            success = true;
-        } finally {
-            if (!success) {
-                mContext.stopService(service);
-            }
-        }
-        mExpectedServiceState = STATE_DESTROY;
-        mContext.stopService(service);
-        waitForResultOrThrow(DELAY, "service to be destroyed");
-    }
-
-    /**
-     * test the service lifecycle, a service can be used in two ways:
-     * 1  It can be started and allowed to run until someone stops it or it stops itself.
-     *    In this mode, it's started by calling Context.startService()
-     *    and stopped by calling Context.stopService().
-     *    It can stop itself by calling Service.stopSelf() or Service.stopSelfResult().
-     *    Only one stopService() call is needed to stop the service,
-     *    no matter how many times startService() was called.
-     * 2  It can be operated programmatically using an interface that it defines and exports.
-     *    Clients establish a connection to the Service object
-     *    and use that connection to call into the service.
-     *    The connection is established by calling Context.bindService(),
-     *    and is closed by calling Context.unbindService().
-     *    Multiple clients can bind to the same service.
-     *    If the service has not already been launched, bindService() can optionally launch it.
-     */
-    private void bindExpectResult(Intent service) {
-        TestConnection conn = new TestConnection(true, false);
-        TestConnection conn2 = new TestConnection(false, false);
-        boolean success = false;
-        try {
-            // Expect to see the TestConnection connected.
-            mExpectedServiceState = STATE_START_1;
-            mContext.bindService(service, conn, 0);
-            mContext.startService(service);
-            waitForResultOrThrow(DELAY, EXIST_CONN_TO_RECEIVE_SERVICE);
-
-            // Expect to see the second TestConnection connected.
-            mContext.bindService(service, conn2, 0);
-            waitForResultOrThrow(DELAY, "new connection to receive service");
-
-            mContext.unbindService(conn2);
-            success = true;
-        } finally {
-            if (!success) {
-                mContext.unbindService(conn);
-                mContext.unbindService(conn2);
-                mContext.stopService(service);
-            }
-        }
-
-        // Expect to see the TestConnection disconnected.
-        mExpectedServiceState = STATE_DESTROY;
-        mContext.stopService(service);
-        waitForResultOrThrow(DELAY, EXIST_CONN_TO_LOSE_SERVICE);
-
-        mContext.unbindService(conn);
-
-        conn = new TestConnection(true, true);
-        success = false;
-        try {
-            // Expect to see the TestConnection connected.
-            conn.setMonitor(true);
-            mExpectedServiceState = STATE_START_1;
-            mContext.bindService(service, conn, 0);
-            mContext.startService(service);
-            waitForResultOrThrow(DELAY, EXIST_CONN_TO_RECEIVE_SERVICE);
-
-            success = true;
-        } finally {
-            if (!success) {
-                mContext.unbindService(conn);
-                mContext.stopService(service);
-            }
-        }
-
-        // Expect to see the service unbind and then destroyed.
-        conn.setMonitor(false);
-        mExpectedServiceState = STATE_UNBIND;
-        mContext.stopService(service);
-        waitForResultOrThrow(DELAY, EXIST_CONN_TO_LOSE_SERVICE);
-
-        mContext.unbindService(conn);
-
-        conn = new TestConnection(true, true);
-        success = false;
-        try {
-            // Expect to see the TestConnection connected.
-            conn.setMonitor(true);
-            mExpectedServiceState = STATE_START_1;
-            mContext.bindService(service, conn, 0);
-            mContext.startService(service);
-            waitForResultOrThrow(DELAY, EXIST_CONN_TO_RECEIVE_SERVICE);
-
-            success = true;
-        } finally {
-            if (!success) {
-                mContext.unbindService(conn);
-                mContext.stopService(service);
-            }
-        }
-
-        // Expect to see the service unbind but not destroyed.
-        conn.setMonitor(false);
-        mExpectedServiceState = STATE_UNBIND_ONLY;
-        mContext.unbindService(conn);
-        waitForResultOrThrow(DELAY, "existing connection to unbind service");
-
-        // Expect to see the service rebound.
-        mExpectedServiceState = STATE_REBIND;
-        mContext.bindService(service, conn, 0);
-        waitForResultOrThrow(DELAY, "existing connection to rebind service");
-
-        // Expect to see the service unbind and then destroyed.
-        mExpectedServiceState = STATE_UNBIND;
-        mContext.stopService(service);
-        waitForResultOrThrow(DELAY, EXIST_CONN_TO_LOSE_SERVICE);
-
-        mContext.unbindService(conn);
-    }
-
-    /**
-     * test automatically create the service as long as the binding exists
-     * and disconnect from an application service
-     */
-    private void bindAutoExpectResult(Intent service) {
-        TestConnection conn = new TestConnection(false, true);
-        boolean success = false;
-        try {
-            conn.setMonitor(true);
-            mExpectedServiceState = STATE_START_1;
-            mContext.bindService(
-                    service, conn, Context.BIND_AUTO_CREATE);
-            waitForResultOrThrow(DELAY, "connection to start and receive service");
-            success = true;
-        } finally {
-            if (!success) {
-                mContext.unbindService(conn);
-            }
-        }
-        mExpectedServiceState = STATE_UNBIND;
-        mContext.unbindService(conn);
-        waitForResultOrThrow(DELAY, "disconnecting from service");
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mContext = getContext();
-        mLocalService = new Intent(mContext, LocalService.class);
-        mLocalDeniedService = new Intent(mContext, LocalDeniedService.class);
-        mLocalGrantedService = new Intent(mContext, LocalGrantedService.class);
-        mLocalService_ApplicationHasPermission = new Intent(
-                LocalService.SERVICE_LOCAL_GRANTED, null /*uri*/, mContext, LocalService.class);
-        mLocalService_ApplicationDoesNotHavePermission = new Intent(
-                LocalService.SERVICE_LOCAL_DENIED, null /*uri*/, mContext, LocalService.class);
-        mStateReceiver = new MockBinder();
-    }
-
-    private class MockBinder extends Binder {
-        @Override
-        protected boolean onTransact(int code, Parcel data, Parcel reply,
-                int flags) throws RemoteException {
-            if (code == LocalService.STARTED_CODE) {
-                data.enforceInterface(LocalService.SERVICE_LOCAL);
-                int count = data.readInt();
-                if (mExpectedServiceState == STATE_START_1) {
-                    if (count == 1) {
-                        finishGood();
-                    } else {
-                        finishBad("onStart() again on an object when it "
-                                + "should have been the first time");
-                    }
-                } else if (mExpectedServiceState == STATE_START_2) {
-                    if (count == 2) {
-                        finishGood();
-                    } else {
-                        finishBad("onStart() the first time on an object when it "
-                                + "should have been the second time");
-                    }
-                } else {
-                    finishBad("onStart() was called when not expected (state="
-                            + mExpectedServiceState + ")");
-                }
-                return true;
-            } else if (code == LocalService.DESTROYED_CODE) {
-                data.enforceInterface(LocalService.SERVICE_LOCAL);
-                if (mExpectedServiceState == STATE_DESTROY) {
-                    finishGood();
-                } else {
-                    finishBad("onDestroy() was called when not expected (state="
-                            + mExpectedServiceState + ")");
-                }
-                return true;
-            } else if (code == LocalService.UNBIND_CODE) {
-                data.enforceInterface(LocalService.SERVICE_LOCAL);
-                if (mExpectedServiceState == STATE_UNBIND) {
-                    mExpectedServiceState = STATE_DESTROY;
-                } else if (mExpectedServiceState == STATE_UNBIND_ONLY) {
-                    finishGood();
-                } else {
-                    finishBad("onUnbind() was called when not expected (state="
-                            + mExpectedServiceState + ")");
-                }
-                return true;
-            } else if (code == LocalService.REBIND_CODE) {
-                data.enforceInterface(LocalService.SERVICE_LOCAL);
-                if (mExpectedServiceState == STATE_REBIND) {
-                    finishGood();
-                } else {
-                    finishBad("onRebind() was called when not expected (state="
-                            + mExpectedServiceState + ")");
-                }
-                return true;
-            } else {
-                return super.onTransact(code, data, reply, flags);
-            }
-        }
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-        mContext.stopService(mLocalService);
-        mContext.stopService(mLocalGrantedService);
-        mContext.stopService(mLocalService_ApplicationHasPermission);
-    }
-
-    public void testLocalStartClass() throws Exception {
-        startExpectResult(mLocalService);
-    }
-
-    public void testLocalStartAction() throws Exception {
-        startExpectResult(new Intent(
-                LocalService.SERVICE_LOCAL, null /*uri*/, mContext, LocalService.class));
-    }
-
-    public void testLocalBindClass() throws Exception {
-        bindExpectResult(mLocalService);
-    }
-
-    @MediumTest
-    public void testLocalBindAction() throws Exception {
-        bindExpectResult(new Intent(
-                LocalService.SERVICE_LOCAL, null /*uri*/, mContext, LocalService.class));
-    }
-
-    @MediumTest
-    public void testLocalBindAutoClass() throws Exception {
-        bindAutoExpectResult(mLocalService);
-    }
-
-    @MediumTest
-    public void testLocalBindAutoAction() throws Exception {
-        bindAutoExpectResult(new Intent(
-                LocalService.SERVICE_LOCAL, null /*uri*/, mContext, LocalService.class));
-    }
-
-    @MediumTest
-    public void testLocalStartClassPermissions() throws Exception {
-        startExpectResult(mLocalGrantedService);
-        startExpectResult(mLocalDeniedService);
-    }
-
-    @MediumTest
-    public void testLocalStartActionPermissions() throws Exception {
-        startExpectResult(mLocalService_ApplicationHasPermission);
-        startExpectResult(mLocalService_ApplicationDoesNotHavePermission);
-    }
-
-    @MediumTest
-    public void testLocalBindClassPermissions() throws Exception {
-        bindExpectResult(mLocalGrantedService);
-        bindExpectResult(mLocalDeniedService);
-    }
-
-    @MediumTest
-    public void testLocalBindActionPermissions() throws Exception {
-        bindExpectResult(mLocalService_ApplicationHasPermission);
-        bindExpectResult(mLocalService_ApplicationDoesNotHavePermission);
-    }
-
-    @MediumTest
-    public void testLocalBindAutoClassPermissionGranted() throws Exception {
-        bindAutoExpectResult(mLocalGrantedService);
-    }
-
-    @MediumTest
-    public void testLocalBindAutoActionPermissionGranted() throws Exception {
-        bindAutoExpectResult(mLocalService_ApplicationHasPermission);
-    }
-
-    @MediumTest
-    public void testLocalUnbindTwice() throws Exception {
-        EmptyConnection conn = new EmptyConnection();
-        mContext.bindService(
-                mLocalService_ApplicationHasPermission, conn, 0);
-        mContext.unbindService(conn);
-        try {
-            mContext.unbindService(conn);
-            fail("No exception thrown on the second unbind");
-        } catch (IllegalArgumentException e) {
-            // expected
-        }
-    }
-
-    @MediumTest
-    public void testImplicitIntentFailsOnApiLevel21() throws Exception {
-        Intent intent = new Intent(LocalService.SERVICE_LOCAL);
-        EmptyConnection conn = new EmptyConnection();
-        try {
-            mContext.bindService(intent, conn, 0);
-            mContext.unbindService(conn);
-            fail("Implicit intents should be disallowed for apps targeting API 21+");
-        } catch (IllegalArgumentException e) {
-            // expected
-        }
-    }
-}
diff --git a/tests/tests/app/src/android/app/cts/SystemFeaturesTest.java b/tests/tests/app/src/android/app/cts/SystemFeaturesTest.java
deleted file mode 100644
index 39b1713..0000000
--- a/tests/tests/app/src/android/app/cts/SystemFeaturesTest.java
+++ /dev/null
@@ -1,503 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-import android.app.ActivityManager;
-import android.app.Instrumentation;
-import android.app.WallpaperManager;
-import android.bluetooth.BluetoothAdapter;
-import android.content.ActivityNotFoundException;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.ConfigurationInfo;
-import android.content.pm.FeatureInfo;
-import android.content.pm.PackageManager;
-import android.content.res.Configuration;
-import android.hardware.Camera;
-import android.hardware.Sensor;
-import android.hardware.SensorManager;
-import android.hardware.Camera.CameraInfo;
-import android.hardware.Camera.Parameters;
-import android.hardware.camera2.CameraCharacteristics;
-import android.hardware.camera2.CameraManager;
-import android.hardware.camera2.CameraMetadata;
-import android.location.LocationManager;
-import android.net.sip.SipManager;
-import android.net.wifi.WifiManager;
-import android.nfc.NfcAdapter;
-import android.telephony.TelephonyManager;
-import android.test.InstrumentationTestCase;
-
-import java.lang.reflect.Field;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-/**
- * Test for checking that the {@link PackageManager} is reporting the correct features.
- */
-public class SystemFeaturesTest extends InstrumentationTestCase {
-
-    private Context mContext;
-    private PackageManager mPackageManager;
-    private HashSet<String> mAvailableFeatures;
-
-    private ActivityManager mActivityManager;
-    private LocationManager mLocationManager;
-    private SensorManager mSensorManager;
-    private TelephonyManager mTelephonyManager;
-    private WifiManager mWifiManager;
-    private CameraManager mCameraManager;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        Instrumentation instrumentation = getInstrumentation();
-        mContext = instrumentation.getTargetContext();
-        mPackageManager = mContext.getPackageManager();
-        mAvailableFeatures = new HashSet<String>();
-        if (mPackageManager.getSystemAvailableFeatures() != null) {
-            for (FeatureInfo feature : mPackageManager.getSystemAvailableFeatures()) {
-                mAvailableFeatures.add(feature.name);
-            }
-        }
-        mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
-        mLocationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
-        mSensorManager = (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE);
-        mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
-        mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
-        mCameraManager = (CameraManager) mContext.getSystemService(Context.CAMERA_SERVICE);
-    }
-
-    /**
-     * Check for features improperly prefixed with "android." that are not defined in
-     * {@link PackageManager}.
-     */
-    public void testFeatureNamespaces() throws IllegalArgumentException, IllegalAccessException {
-        Set<String> officialFeatures = getFeatureConstantsNames("FEATURE_");
-        assertFalse(officialFeatures.isEmpty());
-
-        Set<String> notOfficialFeatures = new HashSet<String>(mAvailableFeatures);
-        notOfficialFeatures.removeAll(officialFeatures);
-
-        for (String featureName : notOfficialFeatures) {
-            if (featureName != null) {
-                assertFalse("Use a different namespace than 'android' for " + featureName,
-                        featureName.startsWith("android"));
-            }
-        }
-    }
-
-    public void testBluetoothFeature() {
-        if (BluetoothAdapter.getDefaultAdapter() != null) {
-            assertAvailable(PackageManager.FEATURE_BLUETOOTH);
-        } else {
-            assertNotAvailable(PackageManager.FEATURE_BLUETOOTH);
-        }
-    }
-
-    public void testCameraFeatures() throws Exception {
-        int numCameras = Camera.getNumberOfCameras();
-        if (numCameras == 0) {
-            assertNotAvailable(PackageManager.FEATURE_CAMERA);
-            assertNotAvailable(PackageManager.FEATURE_CAMERA_AUTOFOCUS);
-            assertNotAvailable(PackageManager.FEATURE_CAMERA_FLASH);
-            assertNotAvailable(PackageManager.FEATURE_CAMERA_FRONT);
-            assertNotAvailable(PackageManager.FEATURE_CAMERA_ANY);
-            assertNotAvailable(PackageManager.FEATURE_CAMERA_LEVEL_FULL);
-            assertNotAvailable(PackageManager.FEATURE_CAMERA_CAPABILITY_MANUAL_SENSOR);
-            assertNotAvailable(PackageManager.FEATURE_CAMERA_CAPABILITY_MANUAL_POST_PROCESSING);
-            assertNotAvailable(PackageManager.FEATURE_CAMERA_CAPABILITY_RAW);
-
-            assertFalse("Devices supporting external cameras must have a representative camera " +
-                    "connected for testing",
-                    mPackageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_EXTERNAL));
-        } else {
-            assertAvailable(PackageManager.FEATURE_CAMERA_ANY);
-            checkFrontCamera();
-            checkRearCamera();
-            checkCamera2Features();
-        }
-    }
-
-    private void checkCamera2Features() throws Exception {
-        String[] cameraIds = mCameraManager.getCameraIdList();
-        boolean fullCamera = false;
-        boolean manualSensor = false;
-        boolean manualPostProcessing = false;
-        boolean raw = false;
-        CameraCharacteristics[] cameraChars = new CameraCharacteristics[cameraIds.length];
-        for (String cameraId : cameraIds) {
-            CameraCharacteristics chars = mCameraManager.getCameraCharacteristics(cameraId);
-            Integer hwLevel = chars.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);
-            int[] capabilities = chars.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES);
-            if (hwLevel == CameraMetadata.INFO_SUPPORTED_HARDWARE_LEVEL_FULL) {
-                fullCamera = true;
-            }
-            for (int capability : capabilities) {
-                switch (capability) {
-                    case CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR:
-                        manualSensor = true;
-                        break;
-                    case CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING:
-                        manualPostProcessing = true;
-                        break;
-                    case CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_RAW:
-                        raw = true;
-                        break;
-                    default:
-                        // Capabilities don't have a matching system feature
-                        break;
-                }
-            }
-        }
-        assertFeature(fullCamera, PackageManager.FEATURE_CAMERA_LEVEL_FULL);
-        assertFeature(manualSensor, PackageManager.FEATURE_CAMERA_CAPABILITY_MANUAL_SENSOR);
-        assertFeature(manualPostProcessing,
-                PackageManager.FEATURE_CAMERA_CAPABILITY_MANUAL_POST_PROCESSING);
-        assertFeature(raw, PackageManager.FEATURE_CAMERA_CAPABILITY_RAW);
-    }
-
-    private void checkFrontCamera() {
-        CameraInfo info = new CameraInfo();
-        int numCameras = Camera.getNumberOfCameras();
-        int frontCameraId = -1;
-        for (int i = 0; i < numCameras; i++) {
-            Camera.getCameraInfo(i, info);
-            if (info.facing == CameraInfo.CAMERA_FACING_FRONT) {
-                frontCameraId = i;
-            }
-        }
-
-        if (frontCameraId > -1) {
-            assertTrue("Device has front-facing camera but does not report either " +
-                    "the FEATURE_CAMERA_FRONT or FEATURE_CAMERA_EXTERNAL feature",
-                    mPackageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_FRONT) ||
-                    mPackageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_EXTERNAL));
-        } else {
-            assertFalse("Device does not have front-facing camera but reports either " +
-                    "the FEATURE_CAMERA_FRONT or FEATURE_CAMERA_EXTERNAL feature",
-                    mPackageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_FRONT) ||
-                    mPackageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_EXTERNAL));
-        }
-    }
-
-    private void checkRearCamera() {
-        Camera camera = null;
-        try {
-            camera = Camera.open();
-            if (camera != null) {
-                assertAvailable(PackageManager.FEATURE_CAMERA);
-
-                Camera.Parameters params = camera.getParameters();
-                if (params.getSupportedFocusModes().contains(Parameters.FOCUS_MODE_AUTO)) {
-                    assertAvailable(PackageManager.FEATURE_CAMERA_AUTOFOCUS);
-                } else {
-                    assertNotAvailable(PackageManager.FEATURE_CAMERA_AUTOFOCUS);
-                }
-
-                if (params.getFlashMode() != null) {
-                    assertAvailable(PackageManager.FEATURE_CAMERA_FLASH);
-                } else {
-                    assertNotAvailable(PackageManager.FEATURE_CAMERA_FLASH);
-                }
-            } else {
-                assertNotAvailable(PackageManager.FEATURE_CAMERA);
-                assertNotAvailable(PackageManager.FEATURE_CAMERA_AUTOFOCUS);
-                assertNotAvailable(PackageManager.FEATURE_CAMERA_FLASH);
-            }
-        } finally {
-            if (camera != null) {
-                camera.release();
-            }
-        }
-    }
-
-    public void testLiveWallpaperFeature() {
-        try {
-            Intent intent = new Intent(WallpaperManager.ACTION_LIVE_WALLPAPER_CHOOSER);
-            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-            mContext.startActivity(intent);
-            assertAvailable(PackageManager.FEATURE_LIVE_WALLPAPER);
-        } catch (ActivityNotFoundException e) {
-            assertNotAvailable(PackageManager.FEATURE_LIVE_WALLPAPER);
-        }
-    }
-
-    public void testLocationFeatures() {
-        if (mLocationManager.getProvider(LocationManager.GPS_PROVIDER) != null) {
-            assertAvailable(PackageManager.FEATURE_LOCATION);
-            assertAvailable(PackageManager.FEATURE_LOCATION_GPS);
-        } else {
-            assertNotAvailable(PackageManager.FEATURE_LOCATION_GPS);
-        }
-
-        if (mLocationManager.getProvider(LocationManager.NETWORK_PROVIDER) != null) {
-            assertAvailable(PackageManager.FEATURE_LOCATION);
-            assertAvailable(PackageManager.FEATURE_LOCATION_NETWORK);
-        } else {
-            assertNotAvailable(PackageManager.FEATURE_LOCATION_NETWORK);
-        }
-    }
-
-    public void testNfcFeatures() {
-        if (NfcAdapter.getDefaultAdapter(mContext) != null) {
-            assertAvailable(PackageManager.FEATURE_NFC);
-            assertAvailable(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION);
-        } else {
-            assertNotAvailable(PackageManager.FEATURE_NFC);
-        }
-    }
-
-    public void testScreenFeatures() {
-        assertTrue(mPackageManager.hasSystemFeature(PackageManager.FEATURE_SCREEN_LANDSCAPE)
-                || mPackageManager.hasSystemFeature(PackageManager.FEATURE_SCREEN_PORTRAIT));
-    }
-
-    /**
-     * Check that the sensor features reported by the PackageManager correspond to the sensors
-     * returned by {@link SensorManager#getSensorList(int)}.
-     */
-    public void testSensorFeatures() throws Exception {
-        Set<String> featuresLeft = getFeatureConstantsNames("FEATURE_SENSOR_");
-
-        assertFeatureForSensor(featuresLeft, PackageManager.FEATURE_SENSOR_ACCELEROMETER,
-                Sensor.TYPE_ACCELEROMETER);
-        assertFeatureForSensor(featuresLeft, PackageManager.FEATURE_SENSOR_BAROMETER,
-                Sensor.TYPE_PRESSURE);
-        assertFeatureForSensor(featuresLeft, PackageManager.FEATURE_SENSOR_COMPASS,
-                Sensor.TYPE_MAGNETIC_FIELD);
-        assertFeatureForSensor(featuresLeft, PackageManager.FEATURE_SENSOR_GYROSCOPE,
-                Sensor.TYPE_GYROSCOPE);
-        assertFeatureForSensor(featuresLeft, PackageManager.FEATURE_SENSOR_LIGHT,
-                Sensor.TYPE_LIGHT);
-        assertFeatureForSensor(featuresLeft, PackageManager.FEATURE_SENSOR_PROXIMITY,
-                Sensor.TYPE_PROXIMITY);
-        assertFeatureForSensor(featuresLeft, PackageManager.FEATURE_SENSOR_STEP_COUNTER,
-                Sensor.TYPE_STEP_COUNTER);
-        assertFeatureForSensor(featuresLeft, PackageManager.FEATURE_SENSOR_STEP_DETECTOR,
-                Sensor.TYPE_STEP_DETECTOR);
-        assertFeatureForSensor(featuresLeft, PackageManager.FEATURE_SENSOR_AMBIENT_TEMPERATURE,
-                Sensor.TYPE_AMBIENT_TEMPERATURE);
-        assertFeatureForSensor(featuresLeft, PackageManager.FEATURE_SENSOR_RELATIVE_HUMIDITY,
-                Sensor.TYPE_RELATIVE_HUMIDITY);
-
-
-        /*
-         * We have three cases to test for :
-         * Case 1:  Device does not have an HRM
-         * FEATURE_SENSOR_HEART_RATE               false
-         * FEATURE_SENSOR_HEART_RATE_ECG           false
-         * assertFeatureForSensor(TYPE_HEART_RATE) false
-         *
-         * Case 2:  Device has a PPG HRM
-         * FEATURE_SENSOR_HEART_RATE               true
-         * FEATURE_SENSOR_HEART_RATE_ECG           false
-         * assertFeatureForSensor(TYPE_HEART_RATE) true
-         *
-         * Case 3:  Device has an ECG HRM
-         * FEATURE_SENSOR_HEART_RATE               false
-         * FEATURE_SENSOR_HEART_RATE_ECG           true
-         * assertFeatureForSensor(TYPE_HEART_RATE) true
-         */
-
-        if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_SENSOR_HEART_RATE_ECG)) {
-                /* Case 3 for FEATURE_SENSOR_HEART_RATE_ECG true case */
-                assertFeatureForSensor(featuresLeft, PackageManager.FEATURE_SENSOR_HEART_RATE_ECG,
-                        Sensor.TYPE_HEART_RATE);
-
-                /* Remove HEART_RATE from featuresLeft, no way to test that one */
-                assertTrue("Features left " + featuresLeft + " to check did not include "
-                        + PackageManager.FEATURE_SENSOR_HEART_RATE,
-                        featuresLeft.remove(PackageManager.FEATURE_SENSOR_HEART_RATE));
-        } else if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_SENSOR_HEART_RATE)) {
-                /* Case 1 & 2 for FEATURE_SENSOR_HEART_RATE_ECG false case */
-                assertFeatureForSensor(featuresLeft, PackageManager.FEATURE_SENSOR_HEART_RATE_ECG,
-                        Sensor.TYPE_HEART_RATE);
-
-                /* Case 1 & 3 for FEATURE_SENSOR_HEART_RATE false case */
-                assertFeatureForSensor(featuresLeft, PackageManager.FEATURE_SENSOR_HEART_RATE,
-                        Sensor.TYPE_HEART_RATE);
-        } else {
-                /* Case 2 for FEATURE_SENSOR_HEART_RATE true case */
-                assertFeatureForSensor(featuresLeft, PackageManager.FEATURE_SENSOR_HEART_RATE,
-                        Sensor.TYPE_HEART_RATE);
-
-                /* Remove HEART_RATE_ECG from featuresLeft, no way to test that one */
-                assertTrue("Features left " + featuresLeft + " to check did not include "
-                        + PackageManager.FEATURE_SENSOR_HEART_RATE_ECG,
-                        featuresLeft.remove(PackageManager.FEATURE_SENSOR_HEART_RATE_ECG));
-        }
-
-        assertTrue("Assertions need to be added to this test for " + featuresLeft,
-                featuresLeft.isEmpty());
-    }
-
-    /** Get a list of feature constants in PackageManager matching a prefix. */
-    private static Set<String> getFeatureConstantsNames(String prefix)
-            throws IllegalArgumentException, IllegalAccessException {
-        Set<String> features = new HashSet<String>();
-        Field[] fields = PackageManager.class.getFields();
-        for (Field field : fields) {
-            if (field.getName().startsWith(prefix)) {
-                String feature = (String) field.get(null);
-                features.add(feature);
-            }
-        }
-        return features;
-    }
-
-    public void testSipFeatures() {
-        if (SipManager.newInstance(mContext) != null) {
-            assertAvailable(PackageManager.FEATURE_SIP);
-        } else {
-            assertNotAvailable(PackageManager.FEATURE_SIP);
-            assertNotAvailable(PackageManager.FEATURE_SIP_VOIP);
-        }
-
-        if (SipManager.isApiSupported(mContext)) {
-            assertAvailable(PackageManager.FEATURE_SIP);
-        } else {
-            assertNotAvailable(PackageManager.FEATURE_SIP);
-            assertNotAvailable(PackageManager.FEATURE_SIP_VOIP);
-        }
-
-        if (SipManager.isVoipSupported(mContext)) {
-            assertAvailable(PackageManager.FEATURE_SIP);
-            assertAvailable(PackageManager.FEATURE_SIP_VOIP);
-        } else {
-            assertNotAvailable(PackageManager.FEATURE_SIP_VOIP);
-        }
-    }
-
-    /**
-     * Check that if the PackageManager declares a sensor feature that the device has at least
-     * one sensor that matches that feature. Also check that if a PackageManager does not declare
-     * a sensor that the device also does not have such a sensor.
-     *
-     * @param featuresLeft to check in order to make sure the test covers all sensor features
-     * @param expectedFeature that the PackageManager may report
-     * @param expectedSensorType that that {@link SensorManager#getSensorList(int)} may have
-     */
-    private void assertFeatureForSensor(Set<String> featuresLeft, String expectedFeature,
-            int expectedSensorType) {
-        assertTrue("Features left " + featuresLeft + " to check did not include "
-                + expectedFeature, featuresLeft.remove(expectedFeature));
-
-        boolean hasSensorFeature = mPackageManager.hasSystemFeature(expectedFeature);
-
-        List<Sensor> sensors = mSensorManager.getSensorList(expectedSensorType);
-        List<String> sensorNames = new ArrayList<String>(sensors.size());
-        for (Sensor sensor : sensors) {
-            sensorNames.add(sensor.getName());
-        }
-        boolean hasSensorType = !sensors.isEmpty();
-
-        String message = "PackageManager#hasSystemFeature(" + expectedFeature + ") returns "
-                + hasSensorFeature
-                + " but SensorManager#getSensorList(" + expectedSensorType + ") shows sensors "
-                + sensorNames;
-
-        assertEquals(message, hasSensorFeature, hasSensorType);
-    }
-
-    /**
-     * Check that the {@link TelephonyManager#getPhoneType()} matches the reported features.
-     */
-    public void testTelephonyFeatures() {
-        if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
-            return;
-        }
-
-        int phoneType = mTelephonyManager.getPhoneType();
-        switch (phoneType) {
-            case TelephonyManager.PHONE_TYPE_GSM:
-                assertAvailable(PackageManager.FEATURE_TELEPHONY_GSM);
-                break;
-
-            case TelephonyManager.PHONE_TYPE_CDMA:
-                assertAvailable(PackageManager.FEATURE_TELEPHONY_CDMA);
-                break;
-
-            case TelephonyManager.PHONE_TYPE_NONE:
-                fail("FEATURE_TELEPHONY is present; phone type should not be PHONE_TYPE_NONE");
-                break;
-
-            default:
-                throw new IllegalArgumentException("Did you add a new phone type? " + phoneType);
-        }
-    }
-
-    public void testTouchScreenFeatures() {
-        ConfigurationInfo configInfo = mActivityManager.getDeviceConfigurationInfo();
-        if (configInfo.reqTouchScreen != Configuration.TOUCHSCREEN_NOTOUCH) {
-            assertAvailable(PackageManager.FEATURE_TOUCHSCREEN);
-            assertAvailable(PackageManager.FEATURE_FAKETOUCH);
-        } else {
-            assertNotAvailable(PackageManager.FEATURE_TOUCHSCREEN);
-        }
-
-        // TODO: Add tests for the other touchscreen features.
-    }
-
-    public void testUsbAccessory() {
-        assertAvailable(PackageManager.FEATURE_USB_ACCESSORY);
-    }
-
-    public void testWifiFeature() throws Exception {
-        if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI)) {
-            // no WiFi, skip the test
-            return;
-        }
-        boolean enabled = mWifiManager.isWifiEnabled();
-        try {
-            // WifiManager is hard-coded to return true,
-            // the case without WiFi is already handled,
-            // so this case MUST have WiFi.
-            if (mWifiManager.setWifiEnabled(true)) {
-                assertAvailable(PackageManager.FEATURE_WIFI);
-            }
-        } finally {
-            if (!enabled) {
-                mWifiManager.setWifiEnabled(false);
-            }
-        }
-    }
-
-    private void assertAvailable(String feature) {
-        assertTrue("PackageManager#hasSystemFeature should return true for " + feature,
-                mPackageManager.hasSystemFeature(feature));
-        assertTrue("PackageManager#getSystemAvailableFeatures should have " + feature,
-                mAvailableFeatures.contains(feature));
-    }
-
-    private void assertNotAvailable(String feature) {
-        assertFalse("PackageManager#hasSystemFeature should NOT return true for " + feature,
-                mPackageManager.hasSystemFeature(feature));
-        assertFalse("PackageManager#getSystemAvailableFeatures should NOT have " + feature,
-                mAvailableFeatures.contains(feature));
-    }
-
-    private void assertFeature(boolean exist, String feature) {
-        if (exist) {
-            assertAvailable(feature);
-        } else {
-            assertNotAvailable(feature);
-        }
-    }
-}
diff --git a/tests/tests/app/src/android/app/cts/TabActivityTest.java b/tests/tests/app/src/android/app/cts/TabActivityTest.java
deleted file mode 100644
index 9c028a1..0000000
--- a/tests/tests/app/src/android/app/cts/TabActivityTest.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-
-import android.app.Activity;
-import android.app.Instrumentation;
-import android.app.TabActivity;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.ActivityInfo;
-import android.test.InstrumentationTestCase;
-import android.test.UiThreadTest;
-import android.widget.TabHost;
-
-public class TabActivityTest extends InstrumentationTestCase {
-    private Instrumentation mInstrumentation;
-    private MockTabActivity mActivity;
-    private Activity mChildActivity;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mInstrumentation = super.getInstrumentation();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        if (mActivity != null) {
-            if (!mActivity.isFinishing()) {
-                mActivity.finish();
-            } else if (mChildActivity != null) {
-                if (!mChildActivity.isFinishing()) {
-                    mChildActivity.finish();
-                }
-            }
-        }
-        super.tearDown();
-    }
-
-    public void testTabActivity() throws Throwable {
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-                // Test constructor
-                new TabActivity();
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-        final String packageName = "com.android.cts.app.stub";
-        final Intent intent = new Intent(Intent.ACTION_MAIN);
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        intent.setClassName(packageName, MockTabActivity.class.getName());
-        mActivity = (MockTabActivity) mInstrumentation.startActivitySync(intent);
-        // Test onPostCreate, onContentChanged. These two methods are invoked in starting
-        // activity. Default values of isOnContentChangedCalled, isOnPostCreateCalled are false.
-        assertTrue(mActivity.isOnContentChangedCalled);
-        assertTrue(mActivity.isOnPostCreateCalled);
-
-        // Can't get default value.
-        final int defaultIndex = 1;
-        mActivity.setDefaultTab(defaultIndex);
-        final String defaultTab = "DefaultTab";
-        mActivity.setDefaultTab(defaultTab);
-        // Test getTabHost, getTabWidget
-        final TabHost tabHost = mActivity.getTabHost();
-        assertNotNull(tabHost);
-        assertNotNull(tabHost.getTabWidget());
-    }
-
-    @UiThreadTest
-    public void testChildTitleCallback() throws Exception {
-        final Context context = mInstrumentation.getTargetContext();
-        final Intent intent = new Intent(context, MockTabActivity.class);
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-
-        final MockTabActivity father = new MockTabActivity();
-        final ComponentName componentName = new ComponentName(context, MockTabActivity.class);
-        final ActivityInfo info = context.getPackageManager().getActivityInfo(componentName, 0);
-        mChildActivity = mInstrumentation.newActivity(MockTabActivity.class, mInstrumentation
-                .getTargetContext(), null, null, intent, info, MockTabActivity.class.getName(),
-                father, null, null);
-
-        assertNotNull(mChildActivity);
-        final String newTitle = "New Title";
-        mChildActivity.setTitle(newTitle);
-        assertTrue(father.isOnChildTitleChangedCalled);
-    }
-}
diff --git a/tests/tests/app/src/android/app/cts/TimePickerDialogTest.java b/tests/tests/app/src/android/app/cts/TimePickerDialogTest.java
deleted file mode 100644
index 79a91a1..0000000
--- a/tests/tests/app/src/android/app/cts/TimePickerDialogTest.java
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-
-import android.app.TimePickerDialog;
-import android.app.TimePickerDialog.OnTimeSetListener;
-import android.content.Context;
-import android.os.Bundle;
-import android.test.ActivityInstrumentationTestCase2;
-import android.test.UiThreadTest;
-import android.widget.TimePicker;
-
-/**
- * Test {@link TimePickerDialog}.
- */
-public class TimePickerDialogTest extends ActivityInstrumentationTestCase2<DialogStubActivity> {
-    private static final String HOUR = "hour";
-    private static final String MINUTE = "minute";
-    private static final String IS_24_HOUR = "is24hour";
-
-    private static final int TARGET_HOUR = 15;
-    private static final int TARGET_MINUTE = 9;
-
-    private int mCallbackHour;
-    private int mCallbackMinute;
-
-    private OnTimeSetListener mOnTimeSetListener;
-
-    private Context mContext;
-    private DialogStubActivity mActivity;
-
-    public TimePickerDialogTest() {
-        super("com.android.cts.app.stub", DialogStubActivity.class);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-
-        mContext = getInstrumentation().getContext();
-        mOnTimeSetListener = new OnTimeSetListener(){
-            public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
-                mCallbackHour = hourOfDay;
-                mCallbackMinute = minute;
-            }
-        };
-    }
-
-    @UiThreadTest
-    public void testSaveInstanceState() {
-        TimePickerDialog tD = new TimePickerDialog(
-            mContext, mOnTimeSetListener, TARGET_HOUR, TARGET_MINUTE, true);
-
-        Bundle b = tD.onSaveInstanceState();
-
-        assertEquals(TARGET_HOUR, b.getInt(HOUR));
-        assertEquals(TARGET_MINUTE, b.getInt(MINUTE));
-        assertTrue(b.getBoolean(IS_24_HOUR));
-
-        int minute = 13;
-        tD = new TimePickerDialog(
-                mContext, com.android.cts.app.stub.R.style.Theme_AlertDialog,
-                    mOnTimeSetListener, TARGET_HOUR, minute, false);
-
-        b = tD.onSaveInstanceState();
-
-        assertEquals(TARGET_HOUR, b.getInt(HOUR));
-        assertEquals(minute, b.getInt(MINUTE));
-        assertFalse(b.getBoolean(IS_24_HOUR));
-    }
-
-    @UiThreadTest
-    public void testOnClick() {
-        TimePickerDialog timePickerDialog = buildDialog();
-        timePickerDialog.onClick(null, TimePickerDialog.BUTTON_POSITIVE);
-
-        assertEquals(TARGET_HOUR, mCallbackHour);
-        assertEquals(TARGET_MINUTE, mCallbackMinute);
-    }
-
-    public void testOnTimeChanged() throws Throwable {
-        final int minute = 34;
-        startDialogActivity(DialogStubActivity.TEST_TIMEPICKERDIALOG);
-        final TimePickerDialog d = (TimePickerDialog) mActivity.getDialog();
-
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-                d.onTimeChanged(null, TARGET_HOUR, minute);
-            }
-        });
-        getInstrumentation().waitForIdleSync();
-
-    }
-
-    @UiThreadTest
-    public void testUpdateTime() {
-        TimePickerDialog timePickerDialog = buildDialog();
-        int minute = 18;
-        timePickerDialog.updateTime(TARGET_HOUR, minute);
-
-        // here call onSaveInstanceState is to check the data put by updateTime
-        Bundle b = timePickerDialog.onSaveInstanceState();
-
-        assertEquals(TARGET_HOUR, b.getInt(HOUR));
-        assertEquals(minute, b.getInt(MINUTE));
-    }
-
-    @UiThreadTest
-    public void testOnRestoreInstanceState() {
-        int minute = 27;
-        Bundle b1 = new Bundle();
-        b1.putInt(HOUR, TARGET_HOUR);
-        b1.putInt(MINUTE, minute);
-        b1.putBoolean(IS_24_HOUR, false);
-
-        TimePickerDialog timePickerDialog = buildDialog();
-        timePickerDialog.onRestoreInstanceState(b1);
-
-        //here call onSaveInstanceState is to check the data put by onRestoreInstanceState
-        Bundle b2 = timePickerDialog.onSaveInstanceState();
-
-        assertEquals(TARGET_HOUR, b2.getInt(HOUR));
-        assertEquals(minute, b2.getInt(MINUTE));
-        assertFalse(b2.getBoolean(IS_24_HOUR));
-    }
-
-    private void startDialogActivity(int dialogNumber) {
-        mActivity = DialogStubActivity.startDialogActivity(this, dialogNumber);
-    }
-
-    private TimePickerDialog buildDialog() {
-        return new TimePickerDialog(
-                mContext, mOnTimeSetListener, TARGET_HOUR, TARGET_MINUTE, true);
-    }
-}
diff --git a/tests/tests/app/src/android/app/cts/WallpaperManagerTest.java b/tests/tests/app/src/android/app/cts/WallpaperManagerTest.java
deleted file mode 100644
index 65f89f3..0000000
--- a/tests/tests/app/src/android/app/cts/WallpaperManagerTest.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.app.cts;
-
-import android.app.WallpaperManager;
-import android.content.Context;
-import android.graphics.Point;
-import android.test.AndroidTestCase;
-import android.view.Display;
-import android.view.WindowManager;
-
-public class WallpaperManagerTest extends AndroidTestCase {
-
-    private WallpaperManager mWallpaperManager;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mWallpaperManager = WallpaperManager.getInstance(mContext);
-    }
-
-    /**
-     * Suggesting desired dimensions is only a hint to the system that can be ignored.
-     *
-     * Test if the desired minimum width or height the WallpaperManager returns
-     * is greater than 0. If so, then we check whether that the size is at least the
-     * as big as the screen.
-     */
-    public void testSuggestDesiredDimensions() {
-        final Point min = getScreenSize();
-        final int w = min.x * 3;
-        final int h = min.y * 2;
-
-        assertDesiredMinimum(new Point(min.x / 2, min.y / 2), min);
-
-        assertDesiredMinimum(new Point(w, h),
-                             new Point(w, h));
-
-        assertDesiredMinimum(new Point(min.x / 2, h),
-                             new Point(min.x, h));
-
-        assertDesiredMinimum(new Point(w, min.y / 2),
-                             new Point(w, min.y));
-    }
-
-    private void assertDesiredMinimum(Point suggestedSize, Point expectedSize) {
-        mWallpaperManager.suggestDesiredDimensions(suggestedSize.x, suggestedSize.y);
-        Point actualSize = new Point(mWallpaperManager.getDesiredMinimumWidth(),
-                mWallpaperManager.getDesiredMinimumHeight());
-        if (actualSize.x > 0 || actualSize.y > 0) {
-            assertEquals(expectedSize, actualSize);
-        }
-    }
-
-    private Point getScreenSize() {
-        WindowManager wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
-        Display d = wm.getDefaultDisplay();
-        Point p = new Point();
-        d.getRealSize(p);
-        return p;
-    }
-}
diff --git a/tests/tests/appwidget/Android.mk b/tests/tests/appwidget/Android.mk
index 8641d53..efd15d3 100644
--- a/tests/tests/appwidget/Android.mk
+++ b/tests/tests/appwidget/Android.mk
@@ -26,4 +26,7 @@
 
 LOCAL_STATIC_JAVA_LIBRARIES := mockito-target ctstestrunner
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/appwidget/AndroidManifest.xml b/tests/tests/appwidget/AndroidManifest.xml
index 4d9b61d..6f7d053 100644
--- a/tests/tests/appwidget/AndroidManifest.xml
+++ b/tests/tests/appwidget/AndroidManifest.xml
@@ -17,7 +17,7 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.cts.appwidget">
+    package="android.appwidget.cts">
 
   <application>
       <uses-library android:name="android.test.runner"/>
@@ -45,7 +45,7 @@
   </application>
 
   <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-      android:targetPackage="android.cts.appwidget"
+      android:targetPackage="android.appwidget.cts"
       android:label="Tests for the app widget APIs.">
       <meta-data android:name="listener"
           android:value="com.android.cts.runner.CtsTestRunListener" />
diff --git a/tests/tests/appwidget/AndroidTest.xml b/tests/tests/appwidget/AndroidTest.xml
new file mode 100644
index 0000000..fcee457
--- /dev/null
+++ b/tests/tests/appwidget/AndroidTest.xml
@@ -0,0 +1,24 @@
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS App Widget test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsAppWidgetTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.appwidget.cts" />
+        <option name="runtime-hint" value="3m30s" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/tests/appwidget/src/android/appwidget/cts/AppWidgetTest.java b/tests/tests/appwidget/src/android/appwidget/cts/AppWidgetTest.java
index a385ebe..61b964d 100644
--- a/tests/tests/appwidget/src/android/appwidget/cts/AppWidgetTest.java
+++ b/tests/tests/appwidget/src/android/appwidget/cts/AppWidgetTest.java
@@ -40,7 +40,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
-import android.cts.appwidget.R;
+import android.appwidget.cts.R;
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
 import android.os.Bundle;
diff --git a/tests/tests/assist/Android.mk b/tests/tests/assist/Android.mk
index 89d2c49..0886340 100644
--- a/tests/tests/assist/Android.mk
+++ b/tests/tests/assist/Android.mk
@@ -21,6 +21,11 @@
 # and when built explicitly put it in the data partition
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_CTS_MODULE_CONFIG := $(LOCAL_PATH)/Old$(CTS_MODULE_TEST_CONFIG)
+
 LOCAL_STATIC_JAVA_LIBRARIES := CtsAssistCommon ctstestrunner ctsdeviceutil
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
diff --git a/tests/tests/assist/AndroidTest.xml b/tests/tests/assist/AndroidTest.xml
index 329692d..f1af0c4 100644
--- a/tests/tests/assist/AndroidTest.xml
+++ b/tests/tests/assist/AndroidTest.xml
@@ -13,11 +13,17 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<configuration description="Test module config for Assist">
-    <include name="common-config" />
-    <option name="cts-apk-installer:test-file-name" value="CtsAssistService.apk" />
-    <option name="cts-apk-installer:test-file-name" value="CtsAssistApp.apk" />
-    <option name="run-command:run-command"
-         value="settings put secure voice_interaction_service android.assist.service/.MainInteractionService" />
-    <option name="cts-apk-installer:test-file-name" value="CtsAssistTestCases.apk" />
-</configuration>
+<configuration description="Config for CTS Assist test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsAssistService.apk" />
+        <option name="test-file-name" value="CtsAssistApp.apk" />
+        <option name="test-file-name" value="CtsAssistTestCases.apk" />
+    </target_preparer>
+    <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+        <option name="run-command" value="settings put secure voice_interaction_service android.assist.service/.MainInteractionService" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.assist.cts" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/tests/assist/OldAndroidTest.xml b/tests/tests/assist/OldAndroidTest.xml
new file mode 100644
index 0000000..26db4cf
--- /dev/null
+++ b/tests/tests/assist/OldAndroidTest.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Test module config for Assist">
+    <include name="common-config" />
+    <option name="cts-apk-installer:test-file-name" value="CtsAssistService.apk" />
+    <option name="cts-apk-installer:test-file-name" value="CtsAssistApp.apk" />
+    <option name="run-command:run-command"
+         value="settings put secure voice_interaction_service android.assist.service/.MainInteractionService" />
+</configuration>
diff --git a/tests/tests/assist/service/Android.mk b/tests/tests/assist/service/Android.mk
index 07dc228..2f72853 100644
--- a/tests/tests/assist/service/Android.mk
+++ b/tests/tests/assist/service/Android.mk
@@ -27,6 +27,9 @@
 
 LOCAL_PACKAGE_NAME := CtsAssistService
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_SDK_VERSION := current
 
 include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/tests/tests/assist/src/android/assist/cts/AssistStructureTest.java b/tests/tests/assist/src/android/assist/cts/AssistStructureTest.java
index c21bc9c..d0a00c9 100644
--- a/tests/tests/assist/src/android/assist/cts/AssistStructureTest.java
+++ b/tests/tests/assist/src/android/assist/cts/AssistStructureTest.java
@@ -79,7 +79,7 @@
         }
     }
 
-    public void testAssistStructure() throws Exception {
+    public void testAssistStructure() throws Throwable {
         if (mActivityManager.isLowRamDevice()) {
             Log.d(TAG, "Not running assist tests on low-RAM device.");
             return;
@@ -90,10 +90,14 @@
         waitForOnResume();
         startSession();
         waitForContext();
-        verifyAssistDataNullness(false, false, false, false);
-
-        verifyAssistStructure(Utils.getTestAppComponent(TEST_CASE_TYPE),
-                false /*FLAG_SECURE set*/);
+        getInstrumentation().waitForIdleSync();
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                verifyAssistDataNullness(false, false, false, false);
+                verifyAssistStructure(Utils.getTestAppComponent(TEST_CASE_TYPE), false /*FLAG_SECURE set*/);
+            }
+        });
     }
 
     private class AssistStructureTestBroadcastReceiver extends BroadcastReceiver {
diff --git a/tests/tests/assist/testapp/Android.mk b/tests/tests/assist/testapp/Android.mk
index 68297ef..f21fc39 100644
--- a/tests/tests/assist/testapp/Android.mk
+++ b/tests/tests/assist/testapp/Android.mk
@@ -27,6 +27,9 @@
 
 LOCAL_PACKAGE_NAME := CtsAssistApp
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_SDK_VERSION := current
 
 include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/tests/tests/bionic/Android.mk b/tests/tests/bionic/Android.mk
index 06b7920..627841f 100644
--- a/tests/tests/bionic/Android.mk
+++ b/tests/tests/bionic/Android.mk
@@ -1,6 +1,6 @@
 LOCAL_PATH := $(call my-dir)
 
-test_executable := bionic-unit-tests-cts
+test_executable := CtsBionicTestCases
 list_executable := $(test_executable)_list
 
 include $(CLEAR_VARS)
@@ -26,6 +26,9 @@
     liblog \
     libgtest \
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_CTS_TEST_PACKAGE := android.bionic
 include $(BUILD_CTS_EXECUTABLE)
 
diff --git a/tests/tests/bionic/AndroidTest.xml b/tests/tests/bionic/AndroidTest.xml
new file mode 100644
index 0000000..97a9a0a
--- /dev/null
+++ b/tests/tests/bionic/AndroidTest.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS Bionic test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
+        <option name="cleanup" value="true" />
+        <option name="push" value="CtsBionicTestCases->/data/local/tmp/CtsBionicTestCases" />
+        <option name="append-bitness" value="true" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="CtsBionicTestCases" />
+        <option name="runtime-hint" value="1m10s" />
+    </test>
+</configuration>
diff --git a/tests/tests/bluetooth/Android.mk b/tests/tests/bluetooth/Android.mk
index 4f837fc..d980e37 100644
--- a/tests/tests/bluetooth/Android.mk
+++ b/tests/tests/bluetooth/Android.mk
@@ -30,4 +30,7 @@
 
 LOCAL_SDK_VERSION := current
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/bluetooth/AndroidManifest.xml b/tests/tests/bluetooth/AndroidManifest.xml
index 12838f3..3c751d7 100644
--- a/tests/tests/bluetooth/AndroidManifest.xml
+++ b/tests/tests/bluetooth/AndroidManifest.xml
@@ -15,7 +15,7 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.bluetooth">
+    package="android.bluetooth.cts">
 
     <uses-permission android:name="android.permission.BLUETOOTH" />
     <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
@@ -28,7 +28,7 @@
 
     <!-- This is a self-instrumenting test package. -->
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.cts.bluetooth"
+                     android:targetPackage="android.bluetooth.cts"
                      android:label="CTS tests of bluetooth component">
         <meta-data android:name="listener"
             android:value="com.android.cts.runner.CtsTestRunListener" />
diff --git a/tests/tests/bluetooth/AndroidTest.xml b/tests/tests/bluetooth/AndroidTest.xml
new file mode 100644
index 0000000..fb4b205
--- /dev/null
+++ b/tests/tests/bluetooth/AndroidTest.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS Bluetooth test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsBluetoothTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.bluetooth.cts" />
+        <option name="runtime-hint" value="1m11s" />
+    </test>
+</configuration>
diff --git a/tests/tests/calendarcommon/Android.mk b/tests/tests/calendarcommon/Android.mk
index fa4b6c5..7a8296c 100644
--- a/tests/tests/calendarcommon/Android.mk
+++ b/tests/tests/calendarcommon/Android.mk
@@ -31,4 +31,7 @@
 
 LOCAL_SDK_VERSION := current
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/calendarcommon/AndroidManifest.xml b/tests/tests/calendarcommon/AndroidManifest.xml
index 17520a3..4f21b18 100644
--- a/tests/tests/calendarcommon/AndroidManifest.xml
+++ b/tests/tests/calendarcommon/AndroidManifest.xml
@@ -15,7 +15,7 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.calendarcommon2">
+    package="android.calendarcommon2.cts">
 
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <application>
@@ -24,7 +24,7 @@
 
     <!-- This is a self-instrumenting test package. -->
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.cts.calendarcommon2"
+                     android:targetPackage="android.calendarcommon2.cts"
                      android:label="CTS tests of calendarcommon">
         <meta-data android:name="listener"
             android:value="com.android.cts.runner.CtsTestRunListener" />
diff --git a/tests/tests/calendarcommon/AndroidTest.xml b/tests/tests/calendarcommon/AndroidTest.xml
new file mode 100644
index 0000000..65f2d7a
--- /dev/null
+++ b/tests/tests/calendarcommon/AndroidTest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS Calendar test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsCalendarcommon2TestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.calendarcommon2.cts" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/tests/calllog/Android.mk b/tests/tests/calllog/Android.mk
index 6a7e96a..105f188 100644
--- a/tests/tests/calllog/Android.mk
+++ b/tests/tests/calllog/Android.mk
@@ -32,4 +32,7 @@
 
 LOCAL_SDK_VERSION := current
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/calllog/AndroidManifest.xml b/tests/tests/calllog/AndroidManifest.xml
index 50fe115..d66559f 100644
--- a/tests/tests/calllog/AndroidManifest.xml
+++ b/tests/tests/calllog/AndroidManifest.xml
@@ -15,7 +15,7 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-        package="com.android.cts.calllog">
+        package="android.calllog.cts">
     <uses-sdk android:minSdkVersion="21" />
 
     <uses-permission android:name="android.permission.READ_CALL_LOG" />
@@ -29,7 +29,7 @@
     </application>
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.cts.calllog"
+                     android:targetPackage="android.calllog.cts"
                      android:label="CTS tests for android.calllog package">
         <meta-data android:name="listener"
             android:value="com.android.cts.runner.CtsTestRunListener" />
diff --git a/tests/tests/calllog/AndroidTest.xml b/tests/tests/calllog/AndroidTest.xml
new file mode 100644
index 0000000..408aaac
--- /dev/null
+++ b/tests/tests/calllog/AndroidTest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS Call Log test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsCallLogTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.calllog.cts" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/tests/calllog/src/android/calllog/cts/CallLogBackupTest.java b/tests/tests/calllog/src/android/calllog/cts/CallLogBackupTest.java
index 695a138..56cb3da 100644
--- a/tests/tests/calllog/src/android/calllog/cts/CallLogBackupTest.java
+++ b/tests/tests/calllog/src/android/calllog/cts/CallLogBackupTest.java
@@ -61,6 +61,8 @@
     private static final int CALL_START_TIME = 0;
     private static final int CALL_DURATION = 2000;
     private static final int TIMEOUT_BACKUP = 4000;
+    private static final String TEST_POST_DIAL_DIGITS = ";1234";
+    private static final String TEST_VIA_NUMBER = "555-1112";
 
     private static final Pattern BMGR_ENABLED_PATTERN = Pattern.compile(
             "^Backup Manager currently (enabled|disabled)$");
@@ -77,7 +79,9 @@
         CallLog.Calls.PHONE_ACCOUNT_COMPONENT_NAME,
         CallLog.Calls.PHONE_ACCOUNT_ID,
         CallLog.Calls.DATA_USAGE,
-        CallLog.Calls.FEATURES
+        CallLog.Calls.FEATURES,
+        CallLog.Calls.POST_DIAL_DIGITS,
+        CallLog.Calls.VIA_NUMBER
     };
 
     class Call {
@@ -89,6 +93,8 @@
         String phoneAccountComponent;
         String phoneAccountId;
         int presentation;
+        String postDialDigits;
+        String viaNumber;
     }
 
     private String mCallLogBackupPackageName;
@@ -175,6 +181,8 @@
         assertEquals(CALL_START_TIME, call.date);
         assertEquals(CALL_DURATION, call.duration);
         assertEquals(Calls.OUTGOING_TYPE, call.type);
+        assertEquals(TEST_POST_DIAL_DIGITS, call.postDialDigits);
+        assertEquals(TEST_VIA_NUMBER, call.viaNumber);
         return call;
     }
 
@@ -248,6 +256,8 @@
         values.put(Calls.DATE, Long.valueOf(CALL_START_TIME));
         values.put(Calls.DURATION, Long.valueOf(CALL_DURATION));
         values.put(Calls.NEW, Integer.valueOf(1));
+        values.put(Calls.POST_DIAL_DIGITS, TEST_POST_DIAL_DIGITS);
+        values.put(Calls.VIA_NUMBER, TEST_VIA_NUMBER);
 
         getContext().getContentResolver().insert(Calls.CONTENT_URI, values);
     }
@@ -272,6 +282,10 @@
                             cursor.getColumnIndex(Calls.PHONE_ACCOUNT_ID));
                     call.presentation = cursor.getInt(
                             cursor.getColumnIndex(Calls.NUMBER_PRESENTATION));
+                    call.postDialDigits = cursor.getString(
+                            cursor.getColumnIndex(Calls.POST_DIAL_DIGITS));
+                    call.viaNumber = cursor.getString(
+                            cursor.getColumnIndex(Calls.VIA_NUMBER));
                     calls.add(call);
                 }
             } finally {
diff --git a/tests/tests/car/Android.mk b/tests/tests/car/Android.mk
new file mode 100644
index 0000000..0138317
--- /dev/null
+++ b/tests/tests/car/Android.mk
@@ -0,0 +1,38 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := CtsCarTestCases
+
+# Don't include this package in any target.
+LOCAL_MODULE_TAGS := optional
+
+# When built, explicitly put it in the data partition.
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
+
+LOCAL_JAVA_LIBRARIES := android.car
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/car/AndroidManifest.xml b/tests/tests/car/AndroidManifest.xml
new file mode 100644
index 0000000..984d896
--- /dev/null
+++ b/tests/tests/car/AndroidManifest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.car.cts">
+    <uses-feature android:name="android.hardware.type.automotive" />
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="android.car.cts"
+                     android:label="CTS tests for Automotive">
+        <meta-data android:name="listener"
+            android:value="com.android.cts.runner.CtsTestRunListener" />
+    </instrumentation>
+</manifest>
+
diff --git a/tests/tests/car/AndroidTest.xml b/tests/tests/car/AndroidTest.xml
new file mode 100644
index 0000000..d82c101
--- /dev/null
+++ b/tests/tests/car/AndroidTest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS Automotive test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsCarTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.car.cts" />
+    </test>
+</configuration>
diff --git a/tests/tests/car/src/android/car/cts/CarApiTestBase.java b/tests/tests/car/src/android/car/cts/CarApiTestBase.java
new file mode 100644
index 0000000..69750d5
--- /dev/null
+++ b/tests/tests/car/src/android/car/cts/CarApiTestBase.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.car.cts;
+
+import android.car.Car;
+import android.content.ComponentName;
+import android.content.ServiceConnection;
+import android.os.IBinder;
+import android.os.Looper;
+import android.test.AndroidTestCase;
+
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+public class CarApiTestBase extends AndroidTestCase {
+    protected static final long DEFAULT_WAIT_TIMEOUT_MS = 1000;
+
+    private Car mCar;
+
+    private final DefaultServiceConnectionListener mConnectionListener =
+            new DefaultServiceConnectionListener();
+
+    protected void assertMainThread() {
+        assertTrue(Looper.getMainLooper().isCurrentThread());
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mCar = Car.createCar(getContext(), mConnectionListener, null);
+        mCar.connect();
+        mConnectionListener.waitForConnection(DEFAULT_WAIT_TIMEOUT_MS);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+        mCar.disconnect();
+    }
+
+    protected synchronized Car getCar() {
+        return mCar;
+    }
+
+    protected class DefaultServiceConnectionListener implements ServiceConnection {
+        private final Semaphore mConnectionWait = new Semaphore(0);
+
+        public void waitForConnection(long timeoutMs) throws InterruptedException {
+            mConnectionWait.tryAcquire(timeoutMs, TimeUnit.MILLISECONDS);
+        }
+
+        @Override
+        public void onServiceDisconnected(ComponentName name) {
+            assertMainThread();
+        }
+
+        @Override
+        public void onServiceConnected(ComponentName name, IBinder service) {
+            assertMainThread();
+            mConnectionWait.release();
+        }
+    }
+}
diff --git a/tests/tests/car/src/android/car/cts/CarAppContextManagerTest.java b/tests/tests/car/src/android/car/cts/CarAppContextManagerTest.java
new file mode 100644
index 0000000..dffdd3e
--- /dev/null
+++ b/tests/tests/car/src/android/car/cts/CarAppContextManagerTest.java
@@ -0,0 +1,238 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.car.cts;
+
+import android.car.Car;
+import android.car.CarAppContextManager;
+import android.util.Log;
+
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+public class CarAppContextManagerTest extends CarApiTestBase {
+    private static final String TAG = CarAppContextManager.class.getSimpleName();
+    private CarAppContextManager mManager;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mManager = (CarAppContextManager) getCar().getCarManager(Car.APP_CONTEXT_SERVICE);
+        assertNotNull(mManager);
+    }
+
+    public void testSetActiveNullListener() throws Exception {
+        try {
+            mManager.setActiveContexts(null, CarAppContextManager.APP_CONTEXT_NAVIGATION);
+            fail();
+        } catch (IllegalStateException e) {
+            // Expected.
+        }
+    }
+
+    public void testRegisterNull() throws Exception {
+        try {
+            mManager.registerContextListener(null, 0);
+            fail();
+        } catch (IllegalArgumentException e) {
+            // Expected.
+        }
+    }
+
+    public void testRegisterUnregister() throws Exception {
+        ContextChangeListener listener = new ContextChangeListener();
+        ContextChangeListener listener2 = new ContextChangeListener();
+        mManager.registerContextListener(listener, 0);
+        mManager.registerContextListener(listener2, 0);
+        mManager.unregisterContextListener();
+        // this one is no-op
+        mManager.unregisterContextListener();
+    }
+
+    public void testContextChange() throws Exception {
+        DefaultServiceConnectionListener connectionListener =
+                new DefaultServiceConnectionListener();
+        Car car2 = Car.createCar(getContext(), connectionListener, null);
+        car2.connect();
+        connectionListener.waitForConnection(DEFAULT_WAIT_TIMEOUT_MS);
+        CarAppContextManager manager2 = (CarAppContextManager)
+                car2.getCarManager(Car.APP_CONTEXT_SERVICE);
+        assertNotNull(manager2);
+
+        assertEquals(0, mManager.getActiveAppContexts());
+        ContextChangeListener change = new ContextChangeListener();
+        ContextChangeListener change2 = new ContextChangeListener();
+        ContextOwnershipChangeListener owner = new ContextOwnershipChangeListener();
+        ContextOwnershipChangeListener owner2 = new ContextOwnershipChangeListener();
+        mManager.registerContextListener(change, CarAppContextManager.APP_CONTEXT_NAVIGATION |
+                CarAppContextManager.APP_CONTEXT_VOICE_COMMAND);
+        manager2.registerContextListener(change2, CarAppContextManager.APP_CONTEXT_NAVIGATION |
+                CarAppContextManager.APP_CONTEXT_VOICE_COMMAND);
+
+        mManager.setActiveContexts(owner, CarAppContextManager.APP_CONTEXT_NAVIGATION);
+        int expectedContexts = CarAppContextManager.APP_CONTEXT_NAVIGATION;
+        assertEquals(expectedContexts, mManager.getActiveAppContexts());
+        assertEquals(expectedContexts, manager2.getActiveAppContexts());
+        assertTrue(mManager.isOwningContext(expectedContexts));
+        assertFalse(mManager.isOwningContext(CarAppContextManager.APP_CONTEXT_VOICE_COMMAND));
+        assertFalse(mManager.isOwningContext(CarAppContextManager.APP_CONTEXT_NAVIGATION |
+                CarAppContextManager.APP_CONTEXT_VOICE_COMMAND));
+        assertFalse(manager2.isOwningContext(CarAppContextManager.APP_CONTEXT_NAVIGATION));
+        assertFalse(manager2.isOwningContext(CarAppContextManager.APP_CONTEXT_VOICE_COMMAND));
+        assertTrue(change2.waitForContextChangeAndAssert(DEFAULT_WAIT_TIMEOUT_MS,
+                expectedContexts));
+        // change should not get notification for its own change
+        assertFalse(change.waitForContextChangeAndAssert(DEFAULT_WAIT_TIMEOUT_MS, 0));
+
+        mManager.setActiveContexts(owner, CarAppContextManager.APP_CONTEXT_VOICE_COMMAND);
+        expectedContexts = CarAppContextManager.APP_CONTEXT_NAVIGATION |
+                CarAppContextManager.APP_CONTEXT_VOICE_COMMAND;
+        assertTrue(mManager.isOwningContext(CarAppContextManager.APP_CONTEXT_NAVIGATION));
+        assertTrue(mManager.isOwningContext(CarAppContextManager.APP_CONTEXT_VOICE_COMMAND));
+        assertTrue(mManager.isOwningContext(CarAppContextManager.APP_CONTEXT_NAVIGATION |
+                CarAppContextManager.APP_CONTEXT_VOICE_COMMAND));
+        assertFalse(manager2.isOwningContext(CarAppContextManager.APP_CONTEXT_NAVIGATION));
+        assertFalse(manager2.isOwningContext(CarAppContextManager.APP_CONTEXT_VOICE_COMMAND));
+        assertEquals(expectedContexts, mManager.getActiveAppContexts());
+        assertEquals(expectedContexts, manager2.getActiveAppContexts());
+        assertTrue(change2.waitForContextChangeAndAssert(DEFAULT_WAIT_TIMEOUT_MS,
+                expectedContexts));
+        // change should not get notification for its own change
+        assertFalse(change.waitForContextChangeAndAssert(DEFAULT_WAIT_TIMEOUT_MS, 0));
+
+        // this should be no-op
+        mManager.setActiveContexts(owner, CarAppContextManager.APP_CONTEXT_NAVIGATION);
+        assertEquals(expectedContexts, mManager.getActiveAppContexts());
+        assertEquals(expectedContexts, manager2.getActiveAppContexts());
+        assertFalse(change2.waitForContextChangeAndAssert(DEFAULT_WAIT_TIMEOUT_MS, 0));
+        assertFalse(change.waitForContextChangeAndAssert(DEFAULT_WAIT_TIMEOUT_MS, 0));
+
+        manager2.setActiveContexts(owner2, CarAppContextManager.APP_CONTEXT_NAVIGATION);
+        assertFalse(mManager.isOwningContext(CarAppContextManager.APP_CONTEXT_NAVIGATION));
+        assertTrue(mManager.isOwningContext(CarAppContextManager.APP_CONTEXT_VOICE_COMMAND));
+        assertTrue(manager2.isOwningContext(CarAppContextManager.APP_CONTEXT_NAVIGATION));
+        assertFalse(manager2.isOwningContext(CarAppContextManager.APP_CONTEXT_VOICE_COMMAND));
+        assertEquals(expectedContexts, mManager.getActiveAppContexts());
+        assertEquals(expectedContexts, manager2.getActiveAppContexts());
+        assertTrue(owner.waitForOwnershipLossAndAssert(DEFAULT_WAIT_TIMEOUT_MS,
+                CarAppContextManager.APP_CONTEXT_NAVIGATION));
+
+        // no-op as it is not owning it
+        mManager.resetActiveContexts(CarAppContextManager.APP_CONTEXT_NAVIGATION);
+        assertFalse(mManager.isOwningContext(CarAppContextManager.APP_CONTEXT_NAVIGATION));
+        assertTrue(mManager.isOwningContext(CarAppContextManager.APP_CONTEXT_VOICE_COMMAND));
+        assertTrue(manager2.isOwningContext(CarAppContextManager.APP_CONTEXT_NAVIGATION));
+        assertFalse(manager2.isOwningContext(CarAppContextManager.APP_CONTEXT_VOICE_COMMAND));
+        assertEquals(expectedContexts, mManager.getActiveAppContexts());
+        assertEquals(expectedContexts, manager2.getActiveAppContexts());
+
+        mManager.resetActiveContexts(CarAppContextManager.APP_CONTEXT_VOICE_COMMAND);
+        assertFalse(mManager.isOwningContext(CarAppContextManager.APP_CONTEXT_NAVIGATION));
+        assertFalse(mManager.isOwningContext(CarAppContextManager.APP_CONTEXT_VOICE_COMMAND));
+        assertTrue(manager2.isOwningContext(CarAppContextManager.APP_CONTEXT_NAVIGATION));
+        assertFalse(manager2.isOwningContext(CarAppContextManager.APP_CONTEXT_VOICE_COMMAND));
+        expectedContexts = CarAppContextManager.APP_CONTEXT_NAVIGATION;
+        assertEquals(expectedContexts, mManager.getActiveAppContexts());
+        assertEquals(expectedContexts, manager2.getActiveAppContexts());
+        assertTrue(change2.waitForContextChangeAndAssert(DEFAULT_WAIT_TIMEOUT_MS,
+                CarAppContextManager.APP_CONTEXT_NAVIGATION));
+        assertFalse(change.waitForContextChangeAndAssert(DEFAULT_WAIT_TIMEOUT_MS, 0));
+
+        manager2.resetActiveContexts(CarAppContextManager.APP_CONTEXT_NAVIGATION);
+        assertFalse(mManager.isOwningContext(CarAppContextManager.APP_CONTEXT_NAVIGATION));
+        assertFalse(mManager.isOwningContext(CarAppContextManager.APP_CONTEXT_VOICE_COMMAND));
+        assertFalse(manager2.isOwningContext(CarAppContextManager.APP_CONTEXT_NAVIGATION));
+        assertFalse(manager2.isOwningContext(CarAppContextManager.APP_CONTEXT_VOICE_COMMAND));
+        expectedContexts = 0;
+        assertEquals(expectedContexts, mManager.getActiveAppContexts());
+        assertEquals(expectedContexts, manager2.getActiveAppContexts());
+        assertTrue(change.waitForContextChangeAndAssert(DEFAULT_WAIT_TIMEOUT_MS, 0));
+        mManager.unregisterContextListener();
+        manager2.unregisterContextListener();
+    }
+
+    public void testFilter() throws Exception {
+        DefaultServiceConnectionListener connectionListener =
+                new DefaultServiceConnectionListener();
+        Car car2 = Car.createCar(getContext(), connectionListener);
+        car2.connect();
+        connectionListener.waitForConnection(DEFAULT_WAIT_TIMEOUT_MS);
+        CarAppContextManager manager2 = (CarAppContextManager)
+                car2.getCarManager(Car.APP_CONTEXT_SERVICE);
+        assertNotNull(manager2);
+
+        assertEquals(0, mManager.getActiveAppContexts());
+        ContextChangeListener change = new ContextChangeListener();
+        ContextChangeListener listener = new ContextChangeListener();
+        ContextOwnershipChangeListener owner = new ContextOwnershipChangeListener();
+        mManager.registerContextListener(change, CarAppContextManager.APP_CONTEXT_NAVIGATION |
+                CarAppContextManager.APP_CONTEXT_VOICE_COMMAND);
+        manager2.registerContextListener(listener, CarAppContextManager.APP_CONTEXT_NAVIGATION);
+        mManager.setActiveContexts(owner, CarAppContextManager.APP_CONTEXT_NAVIGATION);
+        assertTrue(listener.waitForContextChangeAndAssert(DEFAULT_WAIT_TIMEOUT_MS,
+                CarAppContextManager.APP_CONTEXT_NAVIGATION));
+        mManager.setActiveContexts(owner, CarAppContextManager.APP_CONTEXT_VOICE_COMMAND);
+        assertFalse(listener.waitForContextChangeAndAssert(DEFAULT_WAIT_TIMEOUT_MS, 0));
+        mManager.resetActiveContexts(CarAppContextManager.APP_CONTEXT_VOICE_COMMAND);
+        assertFalse(listener.waitForContextChangeAndAssert(DEFAULT_WAIT_TIMEOUT_MS, 0));
+        mManager.resetActiveContexts(CarAppContextManager.APP_CONTEXT_NAVIGATION);
+        assertTrue(listener.waitForContextChangeAndAssert(DEFAULT_WAIT_TIMEOUT_MS, 0));
+    }
+
+    private class ContextChangeListener implements CarAppContextManager.AppContextChangeListener {
+        private int mLastChangeEvent;
+        private final Semaphore mChangeWait = new Semaphore(0);
+
+        public boolean waitForContextChangeAndAssert(long timeoutMs, int expectedContexts)
+                throws Exception {
+            if (!mChangeWait.tryAcquire(timeoutMs, TimeUnit.MILLISECONDS)) {
+                return false;
+            }
+            assertEquals(expectedContexts, mLastChangeEvent);
+            return true;
+        }
+
+        @Override
+        public void onAppContextChange(int activeContexts) {
+            Log.i(TAG, "onAppContextChange " + Integer.toHexString(activeContexts));
+            assertMainThread();
+            mLastChangeEvent = activeContexts;
+            mChangeWait.release();
+        }
+    }
+
+    private class ContextOwnershipChangeListener
+            implements CarAppContextManager.AppContextOwnershipChangeListener {
+        private int mLastLossEvent;
+        private final Semaphore mLossEventWait = new Semaphore(0);
+
+        public boolean waitForOwnershipLossAndAssert(long timeoutMs, int expectedContexts)
+                throws Exception {
+            if (!mLossEventWait.tryAcquire(timeoutMs, TimeUnit.MILLISECONDS)) {
+                return false;
+            }
+            assertEquals(expectedContexts, mLastLossEvent);
+            return true;
+        }
+
+        @Override
+        public void onAppContextOwnershipLoss(int context) {
+            Log.i(TAG, "onAppContextOwnershipLoss " + Integer.toHexString(context));
+            assertMainThread();
+            mLastLossEvent = context;
+            mLossEventWait.release();
+        }
+    }
+}
diff --git a/tests/tests/car/src/android/car/cts/CarAudioManagerTest.java b/tests/tests/car/src/android/car/cts/CarAudioManagerTest.java
new file mode 100644
index 0000000..cec1db6
--- /dev/null
+++ b/tests/tests/car/src/android/car/cts/CarAudioManagerTest.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.car.cts;
+
+import android.car.Car;
+import android.car.media.CarAudioManager;
+import android.media.AudioAttributes;
+
+/** Unit tests for {@link CarAudioManager}. */
+public class CarAudioManagerTest extends CarApiTestBase {
+    private static final String TAG = CarAudioManagerTest.class.getSimpleName();
+    private CarAudioManager mManager;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mManager = (CarAudioManager) getCar().getCarManager(Car.AUDIO_SERVICE);
+        assertNotNull(mManager);
+    }
+
+    public void testGetAudioAttributesForCarUsageForMusic() throws Exception {
+        AudioAttributes.Builder musicBuilder = new AudioAttributes.Builder();
+        musicBuilder.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
+                .setUsage(AudioAttributes.USAGE_MEDIA);
+
+        assertEquals(musicBuilder.build(), mManager.getAudioAttributesForCarUsage(
+                             CarAudioManager.CAR_AUDIO_USAGE_MUSIC));
+    }
+
+    public void testGetAudioAttributesForCarUsageForUnknown() throws Exception {
+        AudioAttributes.Builder unknownBuilder = new AudioAttributes.Builder();
+        unknownBuilder.setContentType(AudioAttributes.CONTENT_TYPE_UNKNOWN)
+                .setUsage(AudioAttributes.USAGE_UNKNOWN);
+
+        assertEquals(unknownBuilder.build(), mManager.getAudioAttributesForCarUsage(10007));
+    }
+}
diff --git a/tests/tests/car/src/android/car/cts/CarInfoManagerTest.java b/tests/tests/car/src/android/car/cts/CarInfoManagerTest.java
new file mode 100644
index 0000000..1cde840
--- /dev/null
+++ b/tests/tests/car/src/android/car/cts/CarInfoManagerTest.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.car.cts;
+
+import android.car.Car;
+import android.car.CarInfoManager;
+
+public class CarInfoManagerTest extends CarApiTestBase {
+
+    private CarInfoManager mCarInfoManager;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mCarInfoManager = (CarInfoManager) getCar().getCarManager(Car.INFO_SERVICE);
+    }
+
+    public void testManufacturer() throws Exception {
+        // The values are not guaranteed, so just checking data types here.
+        mCarInfoManager.getString(CarInfoManager.KEY_MANUFACTURER);
+        mCarInfoManager.getInt(CarInfoManager.KEY_MODEL_YEAR);
+        mCarInfoManager.getString(CarInfoManager.KEY_VEHICLE_ID);
+        mCarInfoManager.getString(CarInfoManager.KEY_MODEL);
+        try {
+            mCarInfoManager.getFloat(CarInfoManager.KEY_MANUFACTURER);
+            fail("type check failed");
+        } catch (IllegalArgumentException e) {
+            // Expected.
+        }
+        try {
+            mCarInfoManager.getInt(CarInfoManager.KEY_MANUFACTURER);
+            fail("type check failed");
+        } catch (IllegalArgumentException e) {
+            // Expected.
+        }
+    }
+
+    public void testNoSuchInfo() throws Exception {
+        final String NO_SUCH_NAME = "no-such-information-available";
+        try {
+            mCarInfoManager.getString(NO_SUCH_NAME);
+            fail("wrong param check");
+        } catch (IllegalArgumentException e) {
+            // Expected.
+        }
+        try {
+            mCarInfoManager.getInt(NO_SUCH_NAME);
+            fail("wrong param check");
+        } catch (IllegalArgumentException e) {
+            // Expected.
+        }
+        try {
+            mCarInfoManager.getFloat(NO_SUCH_NAME);
+            fail("wrong param check");
+        } catch (IllegalArgumentException e) {
+            // Expected.
+        }
+    }
+}
diff --git a/tests/tests/car/src/android/car/cts/CarPackageManagerTest.java b/tests/tests/car/src/android/car/cts/CarPackageManagerTest.java
new file mode 100644
index 0000000..dc5fe0a
--- /dev/null
+++ b/tests/tests/car/src/android/car/cts/CarPackageManagerTest.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.car.cts;
+
+import android.car.Car;
+import android.car.CarNotConnectedException;
+import android.car.content.pm.CarPackageManager;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+
+import java.util.List;
+
+public class CarPackageManagerTest extends CarApiTestBase {
+
+    private CarPackageManager mCarPm;
+    private static String TAG = CarPackageManagerTest.class.getSimpleName();
+
+    /** Name of the meta-data attribute for the automotive application XML resource */
+    private static final String METADATA_ATTRIBUTE = "android.car.application";
+
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mCarPm = (CarPackageManager) getCar().getCarManager(Car.PACKAGE_SERVICE);
+    }
+
+   public void testActivityAllowedWhileDriving() throws Exception {
+       assertFalse(mCarPm.isActivityAllowedWhileDriving("com.basic.package", "DummyActivity"));
+       // Real system activity is not allowed as well.
+       assertFalse(mCarPm.isActivityAllowedWhileDriving("com.android.phone", "CallActivity"));
+
+       try {
+           mCarPm.isActivityAllowedWhileDriving("com.android.settings", null);
+           fail();
+       } catch (IllegalArgumentException expected) {
+           // Expected.
+       }
+       try {
+           mCarPm.isActivityAllowedWhileDriving(null, "Any");
+           fail();
+       } catch (IllegalArgumentException expected) {
+           // Expected.
+       }
+       try {
+           mCarPm.isActivityAllowedWhileDriving(null, null);
+           fail();
+       } catch (IllegalArgumentException expected) {
+           // Expected.
+       }
+   }
+
+    public void testSystemActivitiesAllowed() throws CarNotConnectedException {
+        List<PackageInfo> packages = getContext().getPackageManager().getInstalledPackages(
+                PackageManager.GET_ACTIVITIES | PackageManager.GET_META_DATA);
+
+        for (PackageInfo info : packages) {
+            if (info.applicationInfo == null) {
+                continue;
+            }
+            if ((info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0 ||
+                    ((info.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0)) {
+
+                Bundle metaData = info.applicationInfo.metaData;
+                if (metaData == null || metaData.getInt(METADATA_ATTRIBUTE, 0) == 0) {
+                    continue;  // No car metadata, ignoring this app.
+                }
+
+                if (info.activities != null && info.activities.length > 0) {
+                    String activity = info.activities[0].name;
+                    String packageName = info.packageName;
+                    assertTrue("Failed for package: " + packageName + ", activity: " + activity,
+                            mCarPm.isActivityAllowedWhileDriving(packageName, activity));
+                }
+            }
+        }
+    }
+
+    public void testServiceAllowedWhileDriving() throws Exception {
+        assertFalse(mCarPm.isServiceAllowedWhileDriving("com.basic.package", ""));
+        assertTrue(mCarPm.isServiceAllowedWhileDriving("com.android.settings", "Any"));
+        assertTrue(mCarPm.isServiceAllowedWhileDriving("com.android.settings", ""));
+        assertTrue(mCarPm.isServiceAllowedWhileDriving("com.android.settings", null));
+
+        try {
+            mCarPm.isServiceAllowedWhileDriving(null, "Any");
+            fail();
+        } catch (IllegalArgumentException expected) {
+            // Expected.
+        }
+    }
+
+}
diff --git a/tests/tests/car/src/android/car/cts/CarSensorManagerTest.java b/tests/tests/car/src/android/car/cts/CarSensorManagerTest.java
new file mode 100644
index 0000000..ddcc52e
--- /dev/null
+++ b/tests/tests/car/src/android/car/cts/CarSensorManagerTest.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.car.cts;
+
+import android.car.Car;
+import android.car.hardware.CarSensorEvent;
+import android.car.hardware.CarSensorManager;
+
+public class CarSensorManagerTest extends CarApiTestBase {
+
+    private CarSensorManager mCarSensorManager;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mCarSensorManager = (CarSensorManager) getCar().getCarManager(Car.SENSOR_SERVICE);
+    }
+
+    public void testDrivingPolicy() throws Exception {
+        int[] supportedSensors = mCarSensorManager.getSupportedSensors();
+        assertNotNull(supportedSensors);
+        boolean found = false;
+        for (int sensor: supportedSensors) {
+            if (sensor == CarSensorManager.SENSOR_TYPE_DRIVING_STATUS) {
+                found = true;
+                break;
+            }
+        }
+        assertTrue(found);
+        assertTrue(mCarSensorManager.isSensorSupported(
+                CarSensorManager.SENSOR_TYPE_DRIVING_STATUS));
+        assertTrue(CarSensorManager.isSensorSupported(supportedSensors,
+                CarSensorManager.SENSOR_TYPE_DRIVING_STATUS));
+        CarSensorEvent lastEvent = mCarSensorManager.getLatestSensorEvent(
+                CarSensorManager.SENSOR_TYPE_DRIVING_STATUS);
+        assertNotNull(lastEvent);
+    }
+}
diff --git a/tests/tests/car/src/android/car/cts/CarTest.java b/tests/tests/car/src/android/car/cts/CarTest.java
new file mode 100644
index 0000000..4c0bb21
--- /dev/null
+++ b/tests/tests/car/src/android/car/cts/CarTest.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.car.cts;
+
+import android.car.Car;
+import android.content.ComponentName;
+import android.content.ServiceConnection;
+import android.os.IBinder;
+import android.test.AndroidTestCase;
+
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+public class CarTest extends AndroidTestCase {
+
+    private static final long DEFAULT_WAIT_TIMEOUT_MS = 2000;
+
+    private Car mCar;
+    private DefaultServiceConnectionListener mServiceConnectionListener;
+
+    public void testConnection() throws Exception {
+        mServiceConnectionListener = new DefaultServiceConnectionListener();
+        mCar = Car.createCar(getContext(), mServiceConnectionListener);
+        assertFalse(mCar.isConnected());
+        assertFalse(mCar.isConnecting());
+        mCar.connect();
+        mServiceConnectionListener.waitForConnection(DEFAULT_WAIT_TIMEOUT_MS);
+        assertTrue(mServiceConnectionListener.isConnected());
+        assertEquals(Car.CONNECTION_TYPE_EMBEDDED, mCar.getCarConnectionType());
+        mCar.disconnect();
+        assertFalse(mCar.isConnected());
+        assertFalse(mCar.isConnecting());
+    }
+
+    protected class DefaultServiceConnectionListener implements ServiceConnection {
+        private final Semaphore mConnectionWait = new Semaphore(0);
+
+        private boolean mIsconnected = false;
+
+        public synchronized boolean isConnected() {
+            return mIsconnected;
+        }
+
+        public void waitForConnection(long timeoutMs) throws InterruptedException {
+            mConnectionWait.tryAcquire(timeoutMs, TimeUnit.MILLISECONDS);
+        }
+
+        @Override
+        public void onServiceDisconnected(ComponentName name) {
+            synchronized (this) {
+                mIsconnected = false;
+            }
+        }
+
+        @Override
+        public void onServiceConnected(ComponentName name, IBinder service) {
+            synchronized (this) {
+                mIsconnected = true;
+            }
+            mConnectionWait.release();
+        }
+    }
+}
diff --git a/tests/tests/car/src/android/car/cts/CarUiProviderTest.java b/tests/tests/car/src/android/car/cts/CarUiProviderTest.java
new file mode 100644
index 0000000..a6bc696
--- /dev/null
+++ b/tests/tests/car/src/android/car/cts/CarUiProviderTest.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.car.cts;
+
+import android.car.app.menu.CarMenuCallbacks;
+import android.car.app.menu.SearchBoxEditListener;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.graphics.Bitmap;
+import android.os.Bundle;
+import android.test.AndroidTestCase;
+import android.util.Log;
+import android.view.View;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Test the existence of compatibility apis in the car ui provider.
+ *
+ * This test will only be run on devices with automotive feature.
+ */
+public class CarUiProviderTest extends AndroidTestCase {
+    private static final String TAG = "CarUiProviderTest";
+    private static final String UI_ENTRY_CLASS_NAME = ".CarUiEntry";
+    private static final String CAR_UI_PROVIDER_PKG = "android.car.ui.provider";
+
+    private static final Map<String, Class<?>[]> COMPATIBILITY_APIS =
+            new HashMap<String, Class<?>[]>();
+
+    static {
+        COMPATIBILITY_APIS.put("onStart", new Class<?>[]{});
+        COMPATIBILITY_APIS.put("onResume", new Class<?>[]{});
+        COMPATIBILITY_APIS.put("onPause", new Class<?>[]{});
+        COMPATIBILITY_APIS.put("onStop", new Class<?>[]{});
+        COMPATIBILITY_APIS.put("getContentView", new Class<?>[]{});
+        COMPATIBILITY_APIS.put("setCarMenuCallbacks", new Class<?>[]{CarMenuCallbacks.class});
+        COMPATIBILITY_APIS.put("getFragmentContainerId", new Class<?>[]{});
+        COMPATIBILITY_APIS.put("setBackground", new Class<?>[]{Bitmap.class});
+        COMPATIBILITY_APIS.put("hideMenuButton", new Class<?>[]{});
+        COMPATIBILITY_APIS.put("restoreMenuDrawable", new Class<?>[]{});
+        COMPATIBILITY_APIS.put("setMenuProgress", new Class<?>[]{float.class});
+        COMPATIBILITY_APIS.put("setScrimColor", new Class<?>[]{int.class});
+        COMPATIBILITY_APIS.put("setTitle", new Class<?>[]{CharSequence.class});
+        COMPATIBILITY_APIS.put("setTitleText", new Class<?>[]{CharSequence.class});
+        COMPATIBILITY_APIS.put("closeDrawer", new Class<?>[]{});
+        COMPATIBILITY_APIS.put("openDrawer", new Class<?>[]{});
+        COMPATIBILITY_APIS.put("showMenu", new Class<?>[]{String.class, String.class});
+        COMPATIBILITY_APIS.put("setMenuButtonColor", new Class<?>[]{int.class});
+        COMPATIBILITY_APIS.put("showTitle", new Class<?>[]{});
+        COMPATIBILITY_APIS.put("hideTitle", new Class<?>[]{});
+        COMPATIBILITY_APIS.put("setLightMode", new Class<?>[]{});
+        COMPATIBILITY_APIS.put("setDarkMode", new Class<?>[]{});
+        COMPATIBILITY_APIS.put("setAutoLightDarkMode", new Class<?>[]{});
+        COMPATIBILITY_APIS.put("onRestoreInstanceState", new Class<?>[]{Bundle.class});
+        COMPATIBILITY_APIS.put("onSaveInstanceState", new Class<?>[]{Bundle.class});
+        COMPATIBILITY_APIS.put("showSearchBox", new Class<?>[]{View.OnClickListener.class});
+        COMPATIBILITY_APIS.put("setSearchBoxEndView", new Class<?>[]{View.class});
+        COMPATIBILITY_APIS.put("getSearchBoxText", new Class<?>[]{});
+        COMPATIBILITY_APIS.put("showToast", new Class<?>[]{String.class, long.class});
+        COMPATIBILITY_APIS.put("stopInput", new Class<?>[]{});
+        COMPATIBILITY_APIS.put("startInput", new Class<?>[]{String.class,
+                View.OnClickListener.class});
+        COMPATIBILITY_APIS.put("setSearchBoxEditListener",
+                new Class<?>[]{SearchBoxEditListener.class});
+        COMPATIBILITY_APIS.put("setSearchBoxColors", new Class<?>[]{int.class, int.class, int.class,
+                int.class});
+    }
+
+    private boolean mIsCar = false;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mIsCar = getContext().getPackageManager().hasSystemFeature(
+                PackageManager.FEATURE_AUTOMOTIVE
+        );
+    }
+
+    public void testCarUiProvider() throws Exception {
+        if (!mIsCar) {
+            Log.d(TAG, "Bypass CarUiProviderTest on non-automotive devices");
+            return;
+        }
+        checkCompatibilityApi();
+    }
+
+    private void checkCompatibilityApi() {
+        List<String> missingApis = new ArrayList<String>();
+        Class<?> loadedClass = null;
+        try {
+            Context carUiContext = getContext().createPackageContext(
+                    CAR_UI_PROVIDER_PKG,
+                    Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY);
+
+            int flag = getContext().getPackageManager()
+                    .getApplicationInfo(CAR_UI_PROVIDER_PKG, 0).flags;
+            assertEquals(true, (flag & ApplicationInfo.FLAG_SYSTEM) != 0
+                    || (flag & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0);
+
+            ClassLoader classLoader = carUiContext.getClassLoader();
+            loadedClass = classLoader.loadClass(CAR_UI_PROVIDER_PKG + UI_ENTRY_CLASS_NAME);
+        } catch (PackageManager.NameNotFoundException e) {
+            fail("CarUiProvider package does not exsit");
+        } catch (ClassNotFoundException e) {
+            fail("CarUiEntry class not found");
+        }
+
+        if (loadedClass == null) {
+            fail("Fail to load CarUiEntry class");
+        }
+
+        for (Map.Entry<String, Class<?>[]> method : COMPATIBILITY_APIS.entrySet()) {
+            try {
+                loadedClass.getDeclaredMethod(method.getKey(), method.getValue());
+            } catch (NoSuchMethodException e) {
+                missingApis.add(method.getKey());
+            }
+        }
+        assertEquals("Missing the following APIs from CarUiProvider"
+                + Arrays.toString(missingApis.toArray()), 0, missingApis.size());
+    }
+}
diff --git a/tests/tests/car/src/android/car/cts/ExceptionsTest.java b/tests/tests/car/src/android/car/cts/ExceptionsTest.java
new file mode 100644
index 0000000..496867b
--- /dev/null
+++ b/tests/tests/car/src/android/car/cts/ExceptionsTest.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.car.cts;
+
+import android.car.CarNotConnectedException;
+import android.car.CarNotSupportedException;
+import android.test.AndroidTestCase;
+
+public class ExceptionsTest extends AndroidTestCase {
+    private static final String MESSAGE = "Oops!";
+    private static final Exception CAUSE = new RuntimeException();
+
+    public void testCarNotConnectedException() {
+        CarNotConnectedException exception = new CarNotConnectedException();
+        assertNull(exception.getMessage());
+        assertNull(exception.getCause());
+
+        exception = new CarNotConnectedException(MESSAGE);
+        assertEquals(MESSAGE, exception.getMessage());
+        assertNull(exception.getCause());
+
+        exception = new CarNotConnectedException(MESSAGE, CAUSE);
+        assertEquals(MESSAGE, exception.getMessage());
+        assertEquals(CAUSE, exception.getCause());
+
+        exception = new CarNotConnectedException(CAUSE);
+        assertEquals(CAUSE, exception.getCause());
+    }
+
+    public void testCarNotSupportedException() {
+        CarNotSupportedException exception = new CarNotSupportedException();
+        assertNull(exception.getMessage());
+        assertNull(exception.getCause());
+
+        exception = new CarNotSupportedException(MESSAGE);
+        assertEquals(MESSAGE, exception.getMessage());
+        assertNull(exception.getCause());
+
+        exception = new CarNotSupportedException(MESSAGE, CAUSE);
+        assertEquals(MESSAGE, exception.getMessage());
+        assertEquals(CAUSE, exception.getCause());
+
+        exception = new CarNotSupportedException(CAUSE);
+        assertEquals(CAUSE, exception.getCause());
+    }
+}
diff --git a/tests/tests/carrierapi/Android.mk b/tests/tests/carrierapi/Android.mk
new file mode 100644
index 0000000..53e051f
--- /dev/null
+++ b/tests/tests/carrierapi/Android.mk
@@ -0,0 +1,36 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+# don't include this package in any target
+LOCAL_MODULE_TAGS := optional
+# and when built explicitly put it in the data partition
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner ctsdeviceutil
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := CtsCarrierApiTestCases
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_JAVA_LIBRARIES += android.test.runner telephony-common
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/carrierapi/AndroidManifest.xml b/tests/tests/carrierapi/AndroidManifest.xml
new file mode 100644
index 0000000..0338d99
--- /dev/null
+++ b/tests/tests/carrierapi/AndroidManifest.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.carrierapi.cts">
+
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="android.carrierapi.cts">
+        <meta-data android:name="listener"
+            android:value="com.android.cts.runner.CtsTestRunListener" />
+    </instrumentation>
+
+</manifest>
+
diff --git a/tests/tests/carrierapi/AndroidTest.xml b/tests/tests/carrierapi/AndroidTest.xml
new file mode 100644
index 0000000..2091d97
--- /dev/null
+++ b/tests/tests/carrierapi/AndroidTest.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS Carrier APIs test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.TokenRequirement">
+        <option name="token" value="sim-card" />
+    </target_preparer>
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsCarrierApiTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.carrierapi.cts" />
+    </test>
+</configuration>
diff --git a/tests/tests/carrierapi/src/android/carrierapi/cts/CarrierApiTest.java b/tests/tests/carrierapi/src/android/carrierapi/cts/CarrierApiTest.java
new file mode 100644
index 0000000..be6a759
--- /dev/null
+++ b/tests/tests/carrierapi/src/android/carrierapi/cts/CarrierApiTest.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.carrierapi.cts;
+
+import android.content.Context;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.Signature;
+import android.net.ConnectivityManager;
+import android.os.PersistableBundle;
+import android.telephony.CarrierConfigManager;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+import android.test.AndroidTestCase;
+import android.util.Log;
+
+import com.android.internal.telephony.uicc.IccUtils;
+
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+public class CarrierApiTest extends AndroidTestCase {
+    private static final String TAG = "CarrierApiTest";
+    private TelephonyManager mTelephonyManager;
+    private PackageManager mPackageManager;
+    private boolean hasCellular;
+    private String selfPackageName;
+    private String selfCertHash;
+
+    private static final String FiDevCert = "24EB92CBB156B280FA4E1429A6ECEEB6E5C1BFE4";
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mTelephonyManager = (TelephonyManager)
+                getContext().getSystemService(Context.TELEPHONY_SERVICE);
+        mPackageManager = getContext().getPackageManager();
+        selfPackageName = getContext().getPackageName();
+        selfCertHash = getCertHash(selfPackageName);
+        hasCellular = hasCellular();
+        if (!hasCellular) {
+            Log.e(TAG, "No cellular support, all tests will be skipped.");
+        }
+    }
+
+    /**
+     * Checks whether the cellular stack should be running on this device.
+     */
+    private boolean hasCellular() {
+        ConnectivityManager mgr =
+                (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
+        return mgr.isNetworkSupported(ConnectivityManager.TYPE_MOBILE);
+    }
+
+    private boolean isSimCardPresent() {
+        return mTelephonyManager.getPhoneType() != TelephonyManager.PHONE_TYPE_NONE &&
+                mTelephonyManager.getSimState() != TelephonyManager.SIM_STATE_ABSENT;
+    }
+
+    private String getCertHash(String pkgName) {
+        try {
+            PackageInfo pInfo = mPackageManager.getPackageInfo(pkgName,
+                    PackageManager.GET_SIGNATURES | PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS);
+            MessageDigest md = MessageDigest.getInstance("SHA-1");
+            return IccUtils.bytesToHexString(md.digest(pInfo.signatures[0].toByteArray()));
+        } catch (PackageManager.NameNotFoundException ex) {
+            Log.e(TAG, pkgName + " not found", ex);
+        } catch (NoSuchAlgorithmException ex) {
+            Log.e(TAG, "Algorithm SHA1 is not found.");
+        }
+        return "";
+    }
+
+    private void failMessage() {
+        if (FiDevCert.equalsIgnoreCase(selfCertHash)) {
+            fail("This test requires a Project Fi SIM card.");
+        } else {
+            fail("This test requires a SIM card with carrier privilege rule on it.\n" +
+                 "Cert hash: " + selfCertHash + "\n" +
+                 "Visit https://source.android.com/devices/tech/config/uicc.html");
+        }
+    }
+
+    public void testSimCardPresent() {
+        if (!hasCellular) return;
+        assertTrue("This test requires SIM card.", isSimCardPresent());
+    }
+
+    public void testHasCarrierPrivileges() {
+        if (!hasCellular) return;
+        if (!mTelephonyManager.hasCarrierPrivileges()) {
+            failMessage();
+        }
+    }
+
+}
diff --git a/tests/tests/content/Android.mk b/tests/tests/content/Android.mk
index 7d7858a..a22d539 100644
--- a/tests/tests/content/Android.mk
+++ b/tests/tests/content/Android.mk
@@ -23,7 +23,7 @@
 
 LOCAL_JAVA_LIBRARIES := android.test.runner
 
-LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctstestrunner services.core
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4 ctsdeviceutil ctstestrunner services.core
 
 # Resource unit tests use a private locale and some densities
 LOCAL_AAPT_FLAGS = -c xx_YY -c cs -c small -c normal -c large -c xlarge \
@@ -34,4 +34,7 @@
 
 LOCAL_PACKAGE_NAME := CtsContentTestCases
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/content/AndroidManifest.xml b/tests/tests/content/AndroidManifest.xml
index bffb1f7..d4f203e 100644
--- a/tests/tests/content/AndroidManifest.xml
+++ b/tests/tests/content/AndroidManifest.xml
@@ -15,13 +15,12 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.content">
+    package="android.content.cts">
 
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <!-- content sync tests -->
     <uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
     <uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
-    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
     <uses-permission android:name="android.permission.USE_CREDENTIALS" />
     <uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
     <uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
@@ -35,7 +34,7 @@
     <uses-permission android:name="android.permission.INTERNET" />
 
     <!-- Used for PackageManager test, don't delete this permission-tree -->
-    <permission-tree android:name="com.android.cts.content.permission.TEST_DYNAMIC"
+    <permission-tree android:name="android.content.cts.permission.TEST_DYNAMIC"
                     android:label="Test Tree"/>
 
     <!-- Used for PackageManager test, don't delete this permission-group -->
@@ -43,7 +42,7 @@
             android:label="@string/permlab_costMoney"
             android:description="@string/permdesc_costMoney"/>
 
-    <permission android:name="com.android.cts.content.CALL_ABROAD_PERMISSION"
+    <permission android:name="android.content.cts.CALL_ABROAD_PERMISSION"
                 android:label="@string/permlab_callAbroad"
                 android:description="@string/permdesc_callAbroad"
                 android:protectionLevel="normal"
@@ -75,16 +74,16 @@
             <meta-data android:name="android.app.intent.filter"
                 android:resource="@xml/intentfilter" />
             <intent-filter>
-                <action android:name="com.android.cts.content.action.TEST_ACTION" />
+                <action android:name="android.content.cts.action.TEST_ACTION" />
                 <category android:name="android.intent.category.DEFAULT" />
-                <category android:name="com.android.cts.content.category.TEST_CATEGORY" />
+                <category android:name="android.content.cts.category.TEST_CATEGORY" />
             </intent-filter>
         </activity>
 
         <activity-alias android:name="android.content.cts.MockActivity2"
                 android:targetActivity="android.content.cts.MockActivity">
             <intent-filter>
-                <action android:name="com.android.cts.content.action.TEST_ACTION" />
+                <action android:name="android.content.cts.action.TEST_ACTION" />
                 <category android:name="android.intent.category.DEFAULT" />
             </intent-filter>
         </activity-alias>
@@ -170,6 +169,13 @@
         <provider android:name="android.content.cts.MockRemoteContentProvider"
             android:authorities="remotectstest"
             android:process=":remoteprovider" android:multiprocess="false" />
+        <provider android:name="android.support.v4.content.FileProvider"
+            android:authorities="android.content.cts.fileprovider"
+            android:grantUriPermissions="true">
+            <meta-data
+                android:name="android.support.FILE_PROVIDER_PATHS"
+                android:resource="@xml/file_paths" />
+        </provider>
 
         <service android:name="android.content.cts.MockService" />
 
@@ -194,7 +200,7 @@
 
         <activity android:name="android.content.cts.ClipboardManagerListenerActivity"/>
 
-        <activity android:name="com.android.cts.content.ImageCaptureActivity"
+        <activity android:name="android.content.cts.ImageCaptureActivity"
                   android:exported="true">
             <intent-filter>
                 <action android:name="android.media.action.IMAGE_CAPTURE" />
@@ -204,7 +210,7 @@
             </intent-filter>
         </activity>
 
-        <activity android:name="com.android.cts.content.ReadableFileReceiverActivity"
+        <activity android:name="android.content.cts.ReadableFileReceiverActivity"
                   android:exported="true">
             <intent-filter>
                 <action android:name="android.intent.action.SEND" />
@@ -216,7 +222,7 @@
     </application>
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.cts.content"
+                     android:targetPackage="android.content.cts"
                      android:label="CTS tests of android.content">
         <meta-data android:name="listener"
             android:value="com.android.cts.runner.CtsTestRunListener" />
diff --git a/tests/tests/content/AndroidTest.xml b/tests/tests/content/AndroidTest.xml
new file mode 100644
index 0000000..a8a8727
--- /dev/null
+++ b/tests/tests/content/AndroidTest.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS Content test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.WifiCheck" />
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsContentTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.content.cts" />
+        <option name="runtime-hint" value="3m30s" />
+    </test>
+</configuration>
diff --git a/tests/tests/content/res/color-land/testcolor_orientation.xml b/tests/tests/content/res/color-land/testcolor_orientation.xml
new file mode 100644
index 0000000..f9e285b
--- /dev/null
+++ b/tests/tests/content/res/color-land/testcolor_orientation.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:color="@android:color/white" />
+</selector>
diff --git a/tests/tests/content/res/drawable/testcolor.xml b/tests/tests/content/res/color/testcolor.xml
similarity index 100%
rename from tests/tests/content/res/drawable/testcolor.xml
rename to tests/tests/content/res/color/testcolor.xml
diff --git a/tests/tests/content/res/color/testcolor_orientation.xml b/tests/tests/content/res/color/testcolor_orientation.xml
new file mode 100644
index 0000000..bef1ef6
--- /dev/null
+++ b/tests/tests/content/res/color/testcolor_orientation.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:color="@android:color/black" />
+</selector>
diff --git a/tests/tests/content/res/color/testcolor_themed.xml b/tests/tests/content/res/color/testcolor_themed.xml
new file mode 100644
index 0000000..eee0526
--- /dev/null
+++ b/tests/tests/content/res/color/testcolor_themed.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:color="?attr/themeColor" />
+</selector>
diff --git a/tests/tests/content/res/drawable-hdpi/density_test.xml b/tests/tests/content/res/drawable-hdpi/density_test.xml
new file mode 100644
index 0000000..e4a4b4a
--- /dev/null
+++ b/tests/tests/content/res/drawable-hdpi/density_test.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid
+        android:color="#0000ff" />
+    <size
+        android:width="100px"
+        android:height="100px"/>
+</shape>
diff --git a/tests/tests/content/res/drawable-ldpi/density_test.xml b/tests/tests/content/res/drawable-ldpi/density_test.xml
new file mode 100644
index 0000000..302987f
--- /dev/null
+++ b/tests/tests/content/res/drawable-ldpi/density_test.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid
+        android:color="#ff0000" />
+    <size
+        android:width="300px"
+        android:height="300px"/>
+</shape>
diff --git a/tests/tests/content/res/drawable-mdpi/density_test.xml b/tests/tests/content/res/drawable-mdpi/density_test.xml
new file mode 100644
index 0000000..60514c5
--- /dev/null
+++ b/tests/tests/content/res/drawable-mdpi/density_test.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid
+        android:color="#00ff00" />
+    <size
+        android:width="200px"
+        android:height="200px"/>
+</shape>
diff --git a/tests/tests/content/res/drawable/colordrawable_themed.xml b/tests/tests/content/res/drawable/colordrawable_themed.xml
new file mode 100644
index 0000000..eacbe65
--- /dev/null
+++ b/tests/tests/content/res/drawable/colordrawable_themed.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+-->
+<color xmlns:android="http://schemas.android.com/apk/res/android"
+       android:color="?attr/themeColor" />
diff --git a/tests/tests/content/res/drawable/density_test.xml b/tests/tests/content/res/drawable/density_test.xml
new file mode 100644
index 0000000..2b70eb8
--- /dev/null
+++ b/tests/tests/content/res/drawable/density_test.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid
+        android:color="#ffffff" />
+    <size
+        android:width="1px"
+        android:height="1px"/>
+</shape>
diff --git a/tests/tests/content/res/values-hdpi/strings.xml b/tests/tests/content/res/values-hdpi/strings.xml
new file mode 100644
index 0000000..0ea4779
--- /dev/null
+++ b/tests/tests/content/res/values-hdpi/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+    <string name="density_string">hdpi</string>
+</resources>
diff --git a/tests/tests/content/res/values-ldpi/strings.xml b/tests/tests/content/res/values-ldpi/strings.xml
new file mode 100644
index 0000000..8a49f34
--- /dev/null
+++ b/tests/tests/content/res/values-ldpi/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+    <string name="density_string">ldpi</string>
+</resources>
diff --git a/tests/tests/content/res/values-mdpi/strings.xml b/tests/tests/content/res/values-mdpi/strings.xml
new file mode 100644
index 0000000..721481f
--- /dev/null
+++ b/tests/tests/content/res/values-mdpi/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+    <string name="density_string">mdpi</string>
+</resources>
diff --git a/tests/tests/content/res/values-v24/strings.xml b/tests/tests/content/res/values-v24/strings.xml
new file mode 100644
index 0000000..b84c3a6
--- /dev/null
+++ b/tests/tests/content/res/values-v24/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+   <string name="version_cur">v24cur</string>
+</resources>
diff --git a/tests/tests/content/res/values/attrs.xml b/tests/tests/content/res/values/attrs.xml
index ac88ef6..12b731b 100644
--- a/tests/tests/content/res/values/attrs.xml
+++ b/tests/tests/content/res/values/attrs.xml
@@ -48,6 +48,9 @@
     <attr name="type14" format="string"/>
     <attr name="type15" format="reference"/>
     <attr name="type16" format="string"/>
+    <attr name="type17" format="reference|color"/>
+    <attr name="typeEmpty" format="reference"/>
+    <attr name="typeUndefined" format="reference"/>
     <declare-styleable name="style1">
         <attr name="type1"/>
         <attr name="type2"/>
@@ -65,6 +68,9 @@
         <attr name="type14"/>
         <attr name="type15"/>
         <attr name="type16"/>
+        <attr name="type17"/>
+        <attr name="typeEmpty"/>
+        <attr name="typeUndefined"/>
     </declare-styleable>
     <attr name="testEnum">
         <enum name="val1" value="1" />
diff --git a/tests/tests/content/res/values/strings.xml b/tests/tests/content/res/values/strings.xml
index 8ffb477..0d72c9f 100644
--- a/tests/tests/content/res/values/strings.xml
+++ b/tests/tests/content/res/values/strings.xml
@@ -182,4 +182,5 @@
     <string name="permlab_callAbroad">Call abroad</string>
     <string name="permdesc_callAbroad">Make calls abroad</string>
 
+    <string name="density_string">default</string>
 </resources>
diff --git a/tests/tests/content/res/values/styles.xml b/tests/tests/content/res/values/styles.xml
index b27968d..c6e4b1d 100644
--- a/tests/tests/content/res/values/styles.xml
+++ b/tests/tests/content/res/values/styles.xml
@@ -33,6 +33,9 @@
         <item name="type14">TypedArray Test!</item>
         <item name="type15">@array/difficultyLevel</item>
         <item name="type16">Typed Value!</item>
+        <item name="type17">@color/testcolor_orientation</item>
+        <item name="typeEmpty">@empty</item>
+        <item name="typeUndefined">@null</item>
     </style>
 
     <style name="TextViewWithoutColorAndAppearance">
diff --git a/tests/tests/content/res/xml/alias.xml b/tests/tests/content/res/xml/alias.xml
index c245ba8..624b029 100644
--- a/tests/tests/content/res/xml/alias.xml
+++ b/tests/tests/content/res/xml/alias.xml
@@ -19,7 +19,7 @@
 
 <alias xmlns:android="http://schemas.android.com/apk/res/android">
     <intent android:action="android.intent.action.MAIN"
-        android:targetPackage="com.android.cts.content"
+        android:targetPackage="android.content.cts"
         android:targetClass="android.content.cts.ChildActivity"
         android:data="http://www.google.com/">
     </intent>
diff --git a/tests/tests/content/res/xml/file_paths.xml b/tests/tests/content/res/xml/file_paths.xml
new file mode 100644
index 0000000..e8d2861
--- /dev/null
+++ b/tests/tests/content/res/xml/file_paths.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 Google Inc. All Rights Reserved. -->
+
+<!-- Specify the storage area and path used in file provider. -->
+<paths xmlns:android="http://schemas.android.com/apk/res/android">
+    <files-path name="debug" path="debug/"/>
+</paths>
\ No newline at end of file
diff --git a/tests/tests/content/src/android/content/cts/AvailableIntentsActivity.java b/tests/tests/content/src/android/content/cts/AvailableIntentsActivity.java
index 773defc..acd615c 100644
--- a/tests/tests/content/src/android/content/cts/AvailableIntentsActivity.java
+++ b/tests/tests/content/src/android/content/cts/AvailableIntentsActivity.java
@@ -16,7 +16,7 @@
 
 package android.content.cts;
 
-import com.android.cts.content.R;
+import android.content.cts.R;
 
 import android.app.Activity;
 import android.os.Bundle;
diff --git a/tests/tests/content/src/android/content/cts/BroadcastReceiverTest.java b/tests/tests/content/src/android/content/cts/BroadcastReceiverTest.java
index 43d6cfe..588a915 100644
--- a/tests/tests/content/src/android/content/cts/BroadcastReceiverTest.java
+++ b/tests/tests/content/src/android/content/cts/BroadcastReceiverTest.java
@@ -49,15 +49,15 @@
     private static final String ACTION_BROADCAST_DISABLED =
             "android.content.cts.BroadcastReceiverTest.BROADCAST_DISABLED";
 
-    private static final long SEND_BROADCAST_TIMEOUT = 5000;
+    private static final long SEND_BROADCAST_TIMEOUT = 15000;
     private static final long START_SERVICE_TIMEOUT  = 3000;
 
     private static final ComponentName DISABLEABLE_RECEIVER =
-            new ComponentName("com.android.cts.content",
+            new ComponentName("android.content.cts",
                     "android.content.cts.MockReceiverDisableable");
 
     public BroadcastReceiverTest() {
-        super("com.android.cts.content", MockActivity.class);
+        super("android.content.cts", MockActivity.class);
     }
 
     @Override
@@ -166,7 +166,8 @@
         assertEquals(null, internalReceiver.getResultData());
         assertEquals(null, internalReceiver.getResultExtras(false));
 
-        activity.sendBroadcast(new Intent(ACTION_BROADCAST_INTERNAL));
+        activity.sendBroadcast(new Intent(ACTION_BROADCAST_INTERNAL)
+                .addFlags(Intent.FLAG_RECEIVER_FOREGROUND));
         internalReceiver.waitForReceiver(SEND_BROADCAST_TIMEOUT);
 
         activity.unregisterReceiver(internalReceiver);
@@ -181,7 +182,8 @@
         map.putString(MockReceiver.RESULT_EXTRAS_REMOVE_KEY,
                 MockReceiver.RESULT_EXTRAS_REMOVE_VALUE);
         getInstrumentation().getContext().sendOrderedBroadcast(
-                new Intent(ACTION_BROADCAST_MOCKTEST), null, internalOrderReceiver,
+                new Intent(ACTION_BROADCAST_MOCKTEST).addFlags(Intent.FLAG_RECEIVER_FOREGROUND),
+                null, internalOrderReceiver,
                 null, RESULT_INITIAL_CODE, RESULT_INITIAL_DATA, map);
         internalOrderReceiver.waitForReceiver(SEND_BROADCAST_TIMEOUT);
 
@@ -212,7 +214,8 @@
         // MockReceiverFirst --> MockReceiverAbort --> MockReceiver --> internalOrderReceiver.
         // And MockReceiver is the receiver which will be aborted.
         getInstrumentation().getContext().sendOrderedBroadcast(
-                new Intent(ACTION_BROADCAST_TESTABORT), null, internalOrderReceiver,
+                new Intent(ACTION_BROADCAST_TESTABORT).addFlags(Intent.FLAG_RECEIVER_FOREGROUND),
+                null, internalOrderReceiver,
                 null, RESULT_INITIAL_CODE, RESULT_INITIAL_DATA, map);
         internalOrderReceiver.waitForReceiver(SEND_BROADCAST_TIMEOUT);
 
@@ -242,7 +245,8 @@
                 PackageManager.DONT_KILL_APP);
 
         context.sendOrderedBroadcast(
-                new Intent(ACTION_BROADCAST_DISABLED), null, lastReceiver,
+                new Intent(ACTION_BROADCAST_DISABLED).addFlags(Intent.FLAG_RECEIVER_FOREGROUND),
+                null, lastReceiver,
                 null, RESULT_INITIAL_CODE, RESULT_INITIAL_DATA, new Bundle());
         lastReceiver.waitForReceiver(SEND_BROADCAST_TIMEOUT);
 
@@ -257,7 +261,8 @@
         filter.addAction(ACTION_BROADCAST_INTERNAL);
         activity.registerReceiver(internalReceiver, filter);
 
-        activity.sendBroadcast(new Intent(ACTION_BROADCAST_INTERNAL));
+        activity.sendBroadcast(new Intent(ACTION_BROADCAST_INTERNAL)
+                .addFlags(Intent.FLAG_RECEIVER_FOREGROUND));
         internalReceiver.waitForReceiver(SEND_BROADCAST_TIMEOUT);
         assertNull(internalReceiver.getIBinder());
 
@@ -267,7 +272,8 @@
         assertTrue(msc.waitForService(START_SERVICE_TIMEOUT));
 
         internalReceiver.reset();
-        activity.sendBroadcast(new Intent(ACTION_BROADCAST_INTERNAL));
+        activity.sendBroadcast(new Intent(ACTION_BROADCAST_INTERNAL)
+                .addFlags(Intent.FLAG_RECEIVER_FOREGROUND));
         internalReceiver.waitForReceiver(SEND_BROADCAST_TIMEOUT);
         assertNotNull(internalReceiver.getIBinder());
         activity.unbindService(msc);
diff --git a/tests/tests/content/src/android/content/cts/ComponentNameTest.java b/tests/tests/content/src/android/content/cts/ComponentNameTest.java
index 6277bd6..23a2e00 100644
--- a/tests/tests/content/src/android/content/cts/ComponentNameTest.java
+++ b/tests/tests/content/src/android/content/cts/ComponentNameTest.java
@@ -85,14 +85,14 @@
     }
 
     public void testFlattenToString() {
-        assertEquals("com.android.cts.content/android.content.cts.ComponentNameTest",
+        assertEquals("android.content.cts/android.content.cts.ComponentNameTest",
                 getComponentName().flattenToString());
     }
 
     public void testGetShortClassName() {
         // set the expected value, test normal value
         String actual = getComponentName().getShortClassName();
-        assertEquals("android.content.cts.ComponentNameTest", actual);
+        assertEquals(".ComponentNameTest", actual);
 
         // Test class name which can be abbreviated
         ComponentName componentName = new ComponentName("com.android.view",
@@ -121,7 +121,7 @@
 
     public void testGetPackageName() {
         final String actual = getComponentName().getPackageName();
-        assertEquals("com.android.cts.content", actual);
+        assertEquals("android.content.cts", actual);
     }
 
     public void testUnflattenFromString() {
@@ -135,7 +135,7 @@
     public void testFlattenToShortString() {
         // Test normal
         String actual = getComponentName().flattenToShortString();
-        assertEquals("com.android.cts.content/android.content.cts.ComponentNameTest", actual);
+        assertEquals("android.content.cts/.ComponentNameTest", actual);
 
         // Test long class name
         final ComponentName componentName = new ComponentName("com.android.view",
@@ -152,12 +152,12 @@
         // new the ComponentName instances, both are the same.
         final ComponentName componentName1 = getComponentName();
         ComponentName componentName2 = new ComponentName(componentName1.getPackageName(),
-                componentName1.getShortClassName());
+                componentName1.getClassName());
         assertTrue(componentName1.equals(componentName2));
 
         // new the ComponentName instances, are not the same.
         componentName2 = new ComponentName(componentName1.getPackageName(),
-                componentName1.getShortClassName() + "different name");
+                componentName1.getClassName() + "different name");
         assertFalse(componentName1.equals(componentName2));
     }
 
@@ -168,7 +168,7 @@
     public void testToShortString() {
         // Test normal string
         final String shortString = getComponentName().toShortString();
-        assertEquals("{com.android.cts.content/android.content.cts.ComponentNameTest}", shortString);
+        assertEquals("{android.content.cts/android.content.cts.ComponentNameTest}", shortString);
     }
 
     public void testGetClassName() {
@@ -196,7 +196,7 @@
         ComponentName.writeToParcel(componentName, parcel);
         parcel.setDataPosition(0);
         assertFalse(0 == parcel.dataAvail());
-        assertEquals("com.android.cts.content", parcel.readString());
+        assertEquals("android.content.cts", parcel.readString());
         assertEquals("android.content.cts.ComponentNameTest", parcel.readString());
 
         // Test null data
diff --git a/tests/tests/content/src/android/content/cts/ContentProviderTest.java b/tests/tests/content/src/android/content/cts/ContentProviderTest.java
index 5fee379..e7d8a05 100644
--- a/tests/tests/content/src/android/content/cts/ContentProviderTest.java
+++ b/tests/tests/content/src/android/content/cts/ContentProviderTest.java
@@ -27,7 +27,7 @@
 import android.os.ParcelFileDescriptor;
 import android.test.AndroidTestCase;
 
-import com.android.cts.content.R;
+import android.content.cts.R;
 
 import java.io.File;
 import java.io.FileNotFoundException;
@@ -37,7 +37,7 @@
  * Test {@link ContentProvider}.
  */
 public class ContentProviderTest extends AndroidTestCase {
-    private static final String TEST_PACKAGE_NAME = "com.android.cts.content";
+    private static final String TEST_PACKAGE_NAME = "android.content.cts";
     private static final String TEST_FILE_NAME = "testFile.tmp";
     private static final String TEST_DB_NAME = "test.db";
 
diff --git a/tests/tests/content/src/android/content/cts/ContentResolverTest.java b/tests/tests/content/src/android/content/cts/ContentResolverTest.java
index 628f956..ea1227c 100644
--- a/tests/tests/content/src/android/content/cts/ContentResolverTest.java
+++ b/tests/tests/content/src/android/content/cts/ContentResolverTest.java
@@ -16,7 +16,7 @@
 
 package android.content.cts;
 
-import com.android.cts.content.R;
+import android.content.cts.R;
 
 
 import android.accounts.Account;
@@ -80,7 +80,7 @@
     private static final int VALUE2 = 2;
     private static final int VALUE3 = 3;
 
-    private static final String TEST_PACKAGE_NAME = "com.android.cts.content";
+    private static final String TEST_PACKAGE_NAME = "android.content.cts";
 
     private Context mContext;
     private ContentResolver mContentResolver;
diff --git a/tests/tests/content/src/android/content/cts/ContextTest.java b/tests/tests/content/src/android/content/cts/ContextTest.java
index d77c1b1..0d9c56d 100644
--- a/tests/tests/content/src/android/content/cts/ContextTest.java
+++ b/tests/tests/content/src/android/content/cts/ContextTest.java
@@ -16,10 +16,6 @@
 
 package android.content.cts;
 
-import com.android.cts.content.R;
-
-import org.xmlpull.v1.XmlPullParserException;
-
 import android.content.Context;
 import android.content.cts.util.XmlUtils;
 import android.content.res.ColorStateList;
@@ -27,14 +23,23 @@
 import android.content.res.Resources.Theme;
 import android.content.res.TypedArray;
 import android.content.res.XmlResourceParser;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
 import android.test.AndroidTestCase;
 import android.util.AttributeSet;
+import android.util.Log;
 import android.util.Xml;
 import android.view.WindowManager;
 
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.File;
+import java.io.FileOutputStream;
 import java.io.IOException;
 
 public class ContextTest extends AndroidTestCase {
+    private static final String TAG = "ContextTest";
+
     private Context mContext;
 
     @Override
@@ -81,6 +86,108 @@
         }
     }
 
+    /**
+     * Ensure that default and device encrypted storage areas are stored
+     * separately on disk. All devices must support these storage areas, even if
+     * they don't have file-based encryption, so that apps can go through a
+     * backup/restore cycle between FBE and non-FBE devices.
+     */
+    public void testCreateDeviceProtectedStorageContext() throws Exception {
+        final Context deviceContext = mContext.createDeviceProtectedStorageContext();
+
+        assertFalse(mContext.isDeviceProtectedStorage());
+        assertTrue(deviceContext.isDeviceProtectedStorage());
+
+        final File defaultFile = new File(mContext.getFilesDir(), "test");
+        final File deviceFile = new File(deviceContext.getFilesDir(), "test");
+
+        assertFalse(deviceFile.equals(defaultFile));
+
+        deviceFile.createNewFile();
+
+        // Make sure storage areas are mutually exclusive
+        assertFalse(defaultFile.exists());
+        assertTrue(deviceFile.exists());
+    }
+
+    public void testMoveSharedPreferencesFrom() throws Exception {
+        final Context deviceContext = mContext.createDeviceProtectedStorageContext();
+
+        mContext.getSharedPreferences("test", Context.MODE_PRIVATE).edit().putInt("answer", 42)
+                .commit();
+
+        // Verify that we can migrate
+        assertTrue(deviceContext.moveSharedPreferencesFrom(mContext, "test"));
+        assertEquals(0, mContext.getSharedPreferences("test", Context.MODE_PRIVATE)
+                .getInt("answer", 0));
+        assertEquals(42, deviceContext.getSharedPreferences("test", Context.MODE_PRIVATE)
+                .getInt("answer", 0));
+
+        // Trying to migrate again when already done is a no-op
+        assertTrue(deviceContext.moveSharedPreferencesFrom(mContext, "test"));
+        assertEquals(0, mContext.getSharedPreferences("test", Context.MODE_PRIVATE)
+                .getInt("answer", 0));
+        assertEquals(42, deviceContext.getSharedPreferences("test", Context.MODE_PRIVATE)
+                .getInt("answer", 0));
+
+        // Add a new value and verify that we can migrate back
+        deviceContext.getSharedPreferences("test", Context.MODE_PRIVATE).edit()
+                .putInt("question", 24).commit();
+
+        assertTrue(mContext.moveSharedPreferencesFrom(deviceContext, "test"));
+        assertEquals(42, mContext.getSharedPreferences("test", Context.MODE_PRIVATE)
+                .getInt("answer", 0));
+        assertEquals(24, mContext.getSharedPreferences("test", Context.MODE_PRIVATE)
+                .getInt("question", 0));
+        assertEquals(0, deviceContext.getSharedPreferences("test", Context.MODE_PRIVATE)
+                .getInt("answer", 0));
+        assertEquals(0, deviceContext.getSharedPreferences("test", Context.MODE_PRIVATE)
+                .getInt("question", 0));
+    }
+
+    public void testMoveDatabaseFrom() throws Exception {
+        final Context deviceContext = mContext.createDeviceProtectedStorageContext();
+
+        SQLiteDatabase db = mContext.openOrCreateDatabase("test.db",
+                Context.MODE_PRIVATE | Context.MODE_ENABLE_WRITE_AHEAD_LOGGING, null);
+        db.execSQL("CREATE TABLE list(item TEXT);");
+        db.execSQL("INSERT INTO list VALUES ('cat')");
+        db.execSQL("INSERT INTO list VALUES ('dog')");
+        db.close();
+
+        // Verify that we can migrate
+        assertTrue(deviceContext.moveDatabaseFrom(mContext, "test.db"));
+        db = deviceContext.openOrCreateDatabase("test.db",
+                Context.MODE_PRIVATE | Context.MODE_ENABLE_WRITE_AHEAD_LOGGING, null);
+        Cursor c = db.query("list", null, null, null, null, null, null);
+        assertEquals(2, c.getCount());
+        assertTrue(c.moveToFirst());
+        assertEquals("cat", c.getString(0));
+        assertTrue(c.moveToNext());
+        assertEquals("dog", c.getString(0));
+        c.close();
+        db.execSQL("INSERT INTO list VALUES ('mouse')");
+        db.close();
+
+        // Trying to migrate again when already done is a no-op
+        assertTrue(deviceContext.moveDatabaseFrom(mContext, "test.db"));
+
+        // Verify that we can migrate back
+        assertTrue(mContext.moveDatabaseFrom(deviceContext, "test.db"));
+        db = mContext.openOrCreateDatabase("test.db",
+                Context.MODE_PRIVATE | Context.MODE_ENABLE_WRITE_AHEAD_LOGGING, null);
+        c = db.query("list", null, null, null, null, null, null);
+        assertEquals(3, c.getCount());
+        assertTrue(c.moveToFirst());
+        assertEquals("cat", c.getString(0));
+        assertTrue(c.moveToNext());
+        assertEquals("dog", c.getString(0));
+        assertTrue(c.moveToNext());
+        assertEquals("mouse", c.getString(0));
+        c.close();
+        db.close();
+    }
+
     public void testAccessTheme() {
         mContext.setTheme(R.style.Test_Theme);
         final Theme testTheme = mContext.getTheme();
@@ -200,6 +307,44 @@
         assertEquals(0xffffff00, color);
     }
 
+    /**
+     * Developers have come to expect at least ext4-style filename behavior, so
+     * verify that the underlying filesystem supports them.
+     */
+    public void testFilenames() throws Exception {
+        final File base = mContext.getFilesDir();
+        assertValidFile(new File(base, "foo"));
+        assertValidFile(new File(base, ".bar"));
+        assertValidFile(new File(base, "foo.bar"));
+        assertValidFile(new File(base, "\u2603"));
+        assertValidFile(new File(base, "\uD83D\uDCA9"));
+
+        final int pid = android.os.Process.myPid();
+        final StringBuilder sb = new StringBuilder(255);
+        while (sb.length() <= 255) {
+            sb.append(pid);
+            sb.append(mContext.getPackageName());
+        }
+        sb.setLength(255);
+
+        final String longName = sb.toString();
+        final File longDir = new File(base, longName);
+        assertValidFile(longDir);
+        longDir.mkdir();
+        final File longFile = new File(longDir, longName);
+        assertValidFile(longFile);
+    }
+
+    private void assertValidFile(File file) throws Exception {
+        Log.d(TAG, "Checking " + file);
+        assertTrue("Failed to create " + file, file.createNewFile());
+        assertTrue("Doesn't exist after create " + file, file.exists());
+        assertTrue("Failed to delete after create " + file, file.delete());
+        new FileOutputStream(file).close();
+        assertTrue("Doesn't exist after stream " + file, file.exists());
+        assertTrue("Failed to delete after stream " + file, file.delete());
+    }
+
     private AttributeSet getAttributeSet(int resourceId) {
         final XmlResourceParser parser = getContext().getResources().getXml(
                 resourceId);
diff --git a/tests/tests/content/src/android/content/cts/ContextWrapperCtsActivity.java b/tests/tests/content/src/android/content/cts/ContextWrapperCtsActivity.java
index 9ff4df9..7ea2ab7 100644
--- a/tests/tests/content/src/android/content/cts/ContextWrapperCtsActivity.java
+++ b/tests/tests/content/src/android/content/cts/ContextWrapperCtsActivity.java
@@ -21,7 +21,7 @@
 import android.app.Activity;
 import android.os.Bundle;
 
-import com.android.cts.content.R;
+import android.content.cts.R;
 
 public class ContextWrapperCtsActivity extends Activity {
     @Override
diff --git a/tests/tests/content/src/android/content/cts/ContextWrapperTest.java b/tests/tests/content/src/android/content/cts/ContextWrapperTest.java
index edc9538..4ffe490 100644
--- a/tests/tests/content/src/android/content/cts/ContextWrapperTest.java
+++ b/tests/tests/content/src/android/content/cts/ContextWrapperTest.java
@@ -16,7 +16,7 @@
 
 package android.content.cts;
 
-import com.android.cts.content.R;
+import android.content.cts.R;
 
 import android.content.ActivityNotFoundException;
 import android.content.BroadcastReceiver;
@@ -346,11 +346,11 @@
 
         // Test openOrCreateDatabase with null and actual factory
         mDatabase = mContextWrapper.openOrCreateDatabase(DATABASE_NAME1,
-                ContextWrapper.MODE_WORLD_READABLE | ContextWrapper.MODE_WORLD_WRITEABLE, factory);
+                ContextWrapper.MODE_PRIVATE, factory);
         assertNotNull(mDatabase);
         mDatabase.close();
         mDatabase = mContextWrapper.openOrCreateDatabase(DATABASE_NAME2,
-                ContextWrapper.MODE_WORLD_READABLE | ContextWrapper.MODE_WORLD_WRITEABLE, factory);
+                ContextWrapper.MODE_PRIVATE, factory);
         assertNotNull(mDatabase);
         mDatabase.close();
 
@@ -477,7 +477,7 @@
     }
 
     public void testGetPackageName() {
-        assertEquals("com.android.cts.content", mContextWrapper.getPackageName());
+        assertEquals("android.content.cts", mContextWrapper.getPackageName());
     }
 
     public void testGetCacheDir() {
@@ -634,7 +634,7 @@
     }
 
     public void testGetDir() {
-        File dir = mContextWrapper.getDir("testpath", Context.MODE_WORLD_WRITEABLE);
+        File dir = mContextWrapper.getDir("testpath", Context.MODE_PRIVATE);
         assertNotNull(dir);
         dir.delete();
     }
diff --git a/tests/tests/content/src/android/content/cts/DummyProvider.java b/tests/tests/content/src/android/content/cts/DummyProvider.java
index 9c50cb9..926ec1d 100644
--- a/tests/tests/content/src/android/content/cts/DummyProvider.java
+++ b/tests/tests/content/src/android/content/cts/DummyProvider.java
@@ -16,8 +16,6 @@
 
 package android.content.cts;
 
-import dalvik.annotation.TestTargetClass;
-
 import android.content.ContentProvider;
 import android.content.ContentValues;
 import android.content.Context;
@@ -33,7 +31,6 @@
  * @see AsyncQueryHandlerTest
  * @see ContentQueryMapTest
  */
-@TestTargetClass(ContentProvider.class)
 public class DummyProvider extends ContentProvider {
     private static final String MOCK_OPERATION = "mockOperation";
 
diff --git a/tests/tests/content/src/android/content/cts/ImageCaptureActivity.java b/tests/tests/content/src/android/content/cts/ImageCaptureActivity.java
index 71bf250..d8ba494 100644
--- a/tests/tests/content/src/android/content/cts/ImageCaptureActivity.java
+++ b/tests/tests/content/src/android/content/cts/ImageCaptureActivity.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.cts.content;
+package android.content.cts;
 
 import android.app.Activity;
 import android.content.ClipData;
@@ -30,7 +30,7 @@
 import java.io.Writer;
 
 public class ImageCaptureActivity extends Activity {
-    public static final String ACTION_FILE_READY = "com.android.cts.content.action.file_ready";
+    public static final String ACTION_FILE_READY = "android.content.cts.action.file_ready";
     private static final String TAG = ImageCaptureUriExtraToClipDataTest.TAG;
 
     protected void onCreate(Bundle savedInstanceState) {
diff --git a/tests/tests/content/src/android/content/cts/ImageCaptureUriExtraToClipDataTest.java b/tests/tests/content/src/android/content/cts/ImageCaptureUriExtraToClipDataTest.java
index bb2a43d..b2a90f2 100644
--- a/tests/tests/content/src/android/content/cts/ImageCaptureUriExtraToClipDataTest.java
+++ b/tests/tests/content/src/android/content/cts/ImageCaptureUriExtraToClipDataTest.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.cts.content;
+package android.content.cts;
 
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
@@ -87,8 +87,8 @@
 
     private void startActivityWithAction(String action) {
         Intent intent = new Intent(action);
-        intent.setComponent(new ComponentName("com.android.cts.content",
-                        "com.android.cts.content.ImageCaptureActivity"));
+        intent.setComponent(new ComponentName("android.content.cts",
+                        "android.content.cts.ImageCaptureActivity"));
         intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mTestFile));
         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
         getContext().startActivity(intent);
diff --git a/tests/tests/content/src/android/content/cts/IntentTest.java b/tests/tests/content/src/android/content/cts/IntentTest.java
index 677b31f..65da548 100644
--- a/tests/tests/content/src/android/content/cts/IntentTest.java
+++ b/tests/tests/content/src/android/content/cts/IntentTest.java
@@ -720,33 +720,33 @@
     }
 
     public void testResolveActivitySingleMatch() {
-        final Intent intent = new Intent("com.android.cts.content.action.TEST_ACTION");
-        intent.addCategory("com.android.cts.content.category.TEST_CATEGORY");
+        final Intent intent = new Intent("android.content.cts.action.TEST_ACTION");
+        intent.addCategory("android.content.cts.category.TEST_CATEGORY");
 
         // Should only have one activity responding to narrow category
         final ComponentName target = intent.resolveActivity(mPm);
-        assertEquals("com.android.cts.content", target.getPackageName());
+        assertEquals("android.content.cts", target.getPackageName());
         assertEquals("android.content.cts.MockActivity", target.getClassName());
     }
 
     public void testResolveActivityShortcutMatch() {
-        final Intent intent = new Intent("com.android.cts.content.action.TEST_ACTION");
+        final Intent intent = new Intent("android.content.cts.action.TEST_ACTION");
         intent.setComponent(
-                new ComponentName("com.android.cts.content", "android.content.cts.MockActivity2"));
+                new ComponentName("android.content.cts", "android.content.cts.MockActivity2"));
 
         // Multiple activities match, but we asked for explicit component
         final ComponentName target = intent.resolveActivity(mPm);
-        assertEquals("com.android.cts.content", target.getPackageName());
+        assertEquals("android.content.cts", target.getPackageName());
         assertEquals("android.content.cts.MockActivity2", target.getClassName());
     }
 
     public void testResolveActivityMultipleMatch() {
-        final Intent intent = new Intent("com.android.cts.content.action.TEST_ACTION");
+        final Intent intent = new Intent("android.content.cts.action.TEST_ACTION");
 
         // Should have multiple activities, resulting in resolver dialog
         final ComponentName target = intent.resolveActivity(mPm);
         final String pkgName = target.getPackageName();
-        assertFalse("com.android.cts.content".equals(pkgName));
+        assertFalse("android.content.cts".equals(pkgName));
 
         // Whoever they are must be able to set preferred activities
         if (!"android".equals(pkgName)) {
diff --git a/tests/tests/content/src/android/content/cts/Intent_ShortcutIconResourceTest.java b/tests/tests/content/src/android/content/cts/Intent_ShortcutIconResourceTest.java
index 062ef90..ce45f1c 100644
--- a/tests/tests/content/src/android/content/cts/Intent_ShortcutIconResourceTest.java
+++ b/tests/tests/content/src/android/content/cts/Intent_ShortcutIconResourceTest.java
@@ -29,7 +29,7 @@
 
     ShortcutIconResource mShortcutIconResource;
     Context mContext;
-    final int resourceId = com.android.cts.content.R.string.notify;
+    final int resourceId = android.content.cts.R.string.notify;
 
     @Override
     protected void setUp() throws Exception {
@@ -63,7 +63,7 @@
     public void testWriteToParcel() {
 
         mShortcutIconResource = ShortcutIconResource.fromContext(mContext,
-                com.android.cts.content.R.string.notify);
+                android.content.cts.R.string.notify);
         assertNotNull(mShortcutIconResource);
         Parcel parce = Parcel.obtain();
         mShortcutIconResource.writeToParcel(parce, 1);
diff --git a/tests/tests/content/src/android/content/cts/ReadableFileReceiverActivity.java b/tests/tests/content/src/android/content/cts/ReadableFileReceiverActivity.java
index bab516e..d5a8b72 100644
--- a/tests/tests/content/src/android/content/cts/ReadableFileReceiverActivity.java
+++ b/tests/tests/content/src/android/content/cts/ReadableFileReceiverActivity.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.cts.content;
+package android.content.cts;
 
 import android.app.Activity;
 import android.content.ClipData;
@@ -32,7 +32,7 @@
 
 public class ReadableFileReceiverActivity extends Activity {
     public static final String ACTION_CONFIRM_READ_SUCCESS
-        = "com.android.cts.content.action.CONFIRM_READ_SUCCESS";
+        = "android.content.cts.action.CONFIRM_READ_SUCCESS";
     private static final String TAG = ReadableUriExtraToClipDataTest.TAG;
 
     protected void onCreate(Bundle savedInstanceState) {
diff --git a/tests/tests/content/src/android/content/cts/ReadableUriExtraToClipDataTest.java b/tests/tests/content/src/android/content/cts/ReadableUriExtraToClipDataTest.java
index 129d964..8b89497 100644
--- a/tests/tests/content/src/android/content/cts/ReadableUriExtraToClipDataTest.java
+++ b/tests/tests/content/src/android/content/cts/ReadableUriExtraToClipDataTest.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.cts.content;
+package android.content.cts;
 
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
diff --git a/tests/tests/content/src/android/content/cts/SharedPreferencesTest.java b/tests/tests/content/src/android/content/cts/SharedPreferencesTest.java
index c271483..b4fcb31 100644
--- a/tests/tests/content/src/android/content/cts/SharedPreferencesTest.java
+++ b/tests/tests/content/src/android/content/cts/SharedPreferencesTest.java
@@ -18,8 +18,9 @@
 
 import android.app.QueuedWork;
 import android.content.Context;
-import android.content.ContextWrapper;
 import android.content.SharedPreferences;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
 import android.os.StrictMode;
 import android.preference.PreferenceManager;
 import android.test.AndroidTestCase;
@@ -39,7 +40,6 @@
     private static final String TAG = "SharedPreferencesTest";
 
     private Context mContext;
-    private ContextWrapper mContextWrapper;
 
     private File mPrefsFile;
 
@@ -47,15 +47,17 @@
     protected void setUp() throws Exception {
         super.setUp();
         mContext = getContext();
-        mContextWrapper = new ContextWrapper(mContext);
 
         SharedPreferences prefs = getPrefs();
         prefs.edit().clear().commit();
-
-        // Duplicated from ContextImpl.java.  Not ideal, but there wasn't a better
-        // way to reach into Context{Wrapper,Impl} to ask where this file lives.
-        mPrefsFile = new File("/data/data/com.android.cts.content/shared_prefs",
-                              "com.android.cts.content_preferences.xml");
+        try {
+            ApplicationInfo applicationInfo = mContext.getPackageManager().getApplicationInfo(
+                    mContext.getPackageName(), 0);
+            mPrefsFile = new File(applicationInfo.dataDir,
+                    "shared_prefs/android.content.cts_preferences.xml");
+        } catch (PackageManager.NameNotFoundException e) {
+            throw new IllegalStateException(e);
+        }
         mPrefsFile.delete();
     }
 
diff --git a/tests/tests/content/src/android/content/pm/cts/ApplicationInfoTest.java b/tests/tests/content/src/android/content/pm/cts/ApplicationInfoTest.java
index 1e9f5a2..6a06eb8 100644
--- a/tests/tests/content/src/android/content/pm/cts/ApplicationInfoTest.java
+++ b/tests/tests/content/src/android/content/pm/cts/ApplicationInfoTest.java
@@ -16,7 +16,7 @@
 
 package android.content.pm.cts;
 
-import com.android.cts.content.R;
+import android.content.cts.R;
 
 
 import android.content.pm.ApplicationInfo;
diff --git a/tests/tests/content/src/android/content/pm/cts/ApplicationInfo_DisplayNameComparatorTest.java b/tests/tests/content/src/android/content/pm/cts/ApplicationInfo_DisplayNameComparatorTest.java
index 211a2ca..713c60b 100644
--- a/tests/tests/content/src/android/content/pm/cts/ApplicationInfo_DisplayNameComparatorTest.java
+++ b/tests/tests/content/src/android/content/pm/cts/ApplicationInfo_DisplayNameComparatorTest.java
@@ -26,7 +26,7 @@
  * Test {@link DisplayNameComparator}.
  */
 public class ApplicationInfo_DisplayNameComparatorTest extends AndroidTestCase {
-    private static final String PACKAGE_NAME = "com.android.cts.content";
+    private static final String PACKAGE_NAME = "android.content.cts";
     DisplayNameComparator mDisplayNameComparator;
 
     @Override
diff --git a/tests/tests/content/src/android/content/pm/cts/ComponentInfoTest.java b/tests/tests/content/src/android/content/pm/cts/ComponentInfoTest.java
index 14a42c01..e11beec 100644
--- a/tests/tests/content/src/android/content/pm/cts/ComponentInfoTest.java
+++ b/tests/tests/content/src/android/content/pm/cts/ComponentInfoTest.java
@@ -28,14 +28,14 @@
 import android.util.Printer;
 import android.util.StringBuilderPrinter;
 
-import com.android.cts.content.R;
+import android.content.cts.R;
 
 
 /**
  * Test {@link ComponentInfo}.
  */
 public class ComponentInfoTest extends AndroidTestCase {
-    private final String PACKAGE_NAME = "com.android.cts.content";
+    private final String PACKAGE_NAME = "android.content.cts";
     private ComponentInfo mComponentInfo;
 
     public void testConstructor() {
diff --git a/tests/tests/content/src/android/content/pm/cts/InstrumentationInfoTest.java b/tests/tests/content/src/android/content/pm/cts/InstrumentationInfoTest.java
index 5b7747d..ed9366b 100644
--- a/tests/tests/content/src/android/content/pm/cts/InstrumentationInfoTest.java
+++ b/tests/tests/content/src/android/content/pm/cts/InstrumentationInfoTest.java
@@ -25,7 +25,7 @@
 import android.test.AndroidTestCase;
 
 public class InstrumentationInfoTest extends AndroidTestCase {
-    private static final String PACKAGE_NAME = "com.android.cts.content";
+    private static final String PACKAGE_NAME = "android.content.cts";
     private static final String INSTRUMENTATION_NAME =
             "android.content.pm.cts.TestPmInstrumentation";
 
diff --git a/tests/tests/content/src/android/content/pm/cts/PackageInfoTest.java b/tests/tests/content/src/android/content/pm/cts/PackageInfoTest.java
index 0540e0b..886b4f5 100644
--- a/tests/tests/content/src/android/content/pm/cts/PackageInfoTest.java
+++ b/tests/tests/content/src/android/content/pm/cts/PackageInfoTest.java
@@ -32,7 +32,7 @@
     private PackageManager mPackageManager;
     private PackageInfo mPackageInfo;
     private PackageInfo mPackageInfoCmp;
-    private static final String PACKAGE_NAME = "com.android.cts.content";
+    private static final String PACKAGE_NAME = "android.content.cts";
 
     @Override
     protected void setUp() throws Exception {
diff --git a/tests/tests/content/src/android/content/pm/cts/PackageItemInfoTest.java b/tests/tests/content/src/android/content/pm/cts/PackageItemInfoTest.java
index 53e69da..48db1b8 100644
--- a/tests/tests/content/src/android/content/pm/cts/PackageItemInfoTest.java
+++ b/tests/tests/content/src/android/content/pm/cts/PackageItemInfoTest.java
@@ -16,7 +16,7 @@
 
 package android.content.pm.cts;
 
-import com.android.cts.content.R;
+import android.content.cts.R;
 
 
 import android.content.ComponentName;
@@ -30,7 +30,7 @@
 import android.util.Printer;
 
 public class PackageItemInfoTest extends AndroidTestCase {
-    private static final String PACKAGE_NAME = "com.android.cts.content";
+    private static final String PACKAGE_NAME = "android.content.cts";
     private static final String ACTIVITY_NAME = "android.content.pm.cts.TestPmActivity";
     private static final String METADATA_NAME = "android.content.pm.cts.xmltest";
     private PackageManager mPackageManager;
diff --git a/tests/tests/content/src/android/content/pm/cts/PackageItemInfo_DisplayNameComparatorTest.java b/tests/tests/content/src/android/content/pm/cts/PackageItemInfo_DisplayNameComparatorTest.java
index 0cfd1dd..4624c85 100644
--- a/tests/tests/content/src/android/content/pm/cts/PackageItemInfo_DisplayNameComparatorTest.java
+++ b/tests/tests/content/src/android/content/pm/cts/PackageItemInfo_DisplayNameComparatorTest.java
@@ -26,7 +26,7 @@
 import android.test.AndroidTestCase;
 
 public class PackageItemInfo_DisplayNameComparatorTest extends AndroidTestCase {
-    private static final String PACKAGE_NAME = "com.android.cts.content";
+    private static final String PACKAGE_NAME = "android.content.cts";
     private static final String ACTIVITY_NAME = "android.content.pm.cts.TestPmActivity";
     private static final String CMPACTIVITY_NAME = "android.content.pm.cts.TestPmCompare";
 
diff --git a/tests/tests/content/src/android/content/pm/cts/PackageManagerTest.java b/tests/tests/content/src/android/content/pm/cts/PackageManagerTest.java
index cb3de2a..490da35e 100644
--- a/tests/tests/content/src/android/content/pm/cts/PackageManagerTest.java
+++ b/tests/tests/content/src/android/content/pm/cts/PackageManagerTest.java
@@ -16,7 +16,7 @@
 
 package android.content.pm.cts;
 
-import com.android.cts.content.R;
+import android.content.cts.R;
 
 
 import android.content.ComponentName;
@@ -44,8 +44,8 @@
  */
 public class PackageManagerTest extends AndroidTestCase {
     private PackageManager mPackageManager;
-    private static final String PACKAGE_NAME = "com.android.cts.content";
-    private static final String CONTENT_PKG_NAME = "com.android.cts.content";
+    private static final String PACKAGE_NAME = "android.content.cts";
+    private static final String CONTENT_PKG_NAME = "android.content.cts";
     private static final String ACTIVITY_ACTION_NAME = "android.intent.action.PMTEST";
     private static final String MAIN_ACTION_NAME = "android.intent.action.MAIN";
     private static final String SERVICE_ACTION_NAME =
@@ -110,7 +110,7 @@
         String testPermissionsGroup = "android.permission-group.COST_MONEY";
         List<PermissionInfo> permissions = mPackageManager.queryPermissionsByGroup(
                 testPermissionsGroup, PackageManager.GET_META_DATA);
-        checkPermissionInfoName("com.android.cts.content.CALL_ABROAD_PERMISSION", permissions);
+        checkPermissionInfoName("android.content.cts.CALL_ABROAD_PERMISSION", permissions);
 
         ApplicationInfo appInfo = mPackageManager.getApplicationInfo(PACKAGE_NAME, 0);
         List<ProviderInfo> providers = mPackageManager.queryContentProviders(PACKAGE_NAME,
@@ -390,7 +390,7 @@
 
     public void testOpPermission() {
         PermissionInfo permissionInfo = new PermissionInfo();
-        String permissionName = "com.android.cts.content.permission.TEST_DYNAMIC.ADD";
+        String permissionName = "android.content.cts.permission.TEST_DYNAMIC.ADD";
         permissionInfo.name = permissionName;
         permissionInfo.labelRes = R.string.permlab_testDynamic;
         permissionInfo.nonLocalizedLabel = "Test Tree";
@@ -445,7 +445,7 @@
     public void testGetResources() throws NameNotFoundException {
         ComponentName componentName = new ComponentName(PACKAGE_NAME, ACTIVITY_NAME);
         int resourceId = R.xml.pm_test;
-        String xmlName = "com.android.cts.content:xml/pm_test";
+        String xmlName = "android.content.cts:xml/pm_test";
         ApplicationInfo appInfo = mPackageManager.getApplicationInfo(PACKAGE_NAME, 0);
         assertNotNull(mPackageManager.getXml(PACKAGE_NAME, resourceId, appInfo));
         assertEquals(xmlName, mPackageManager.getResourcesForActivity(componentName)
diff --git a/tests/tests/content/src/android/content/pm/cts/PackageStatsTest.java b/tests/tests/content/src/android/content/pm/cts/PackageStatsTest.java
index 6425209..722175b 100644
--- a/tests/tests/content/src/android/content/pm/cts/PackageStatsTest.java
+++ b/tests/tests/content/src/android/content/pm/cts/PackageStatsTest.java
@@ -22,7 +22,7 @@
 import android.test.AndroidTestCase;
 
 public class PackageStatsTest extends AndroidTestCase {
-    private static final String PACKAGE_NAME = "com.android.cts.content";
+    private static final String PACKAGE_NAME = "android.content.cts";
 
     public void testPackageStats() {
         // Set mock data to make sure the functionality of constructor
diff --git a/tests/tests/content/src/android/content/pm/cts/ProviderInfoTest.java b/tests/tests/content/src/android/content/pm/cts/ProviderInfoTest.java
index 6256a69..4e07312 100644
--- a/tests/tests/content/src/android/content/pm/cts/ProviderInfoTest.java
+++ b/tests/tests/content/src/android/content/pm/cts/ProviderInfoTest.java
@@ -21,14 +21,17 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ProviderInfo;
 import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.res.XmlResourceParser;
 import android.os.Parcel;
 import android.test.AndroidTestCase;
 
+import libcore.io.IoUtils;
+
 import java.util.Iterator;
 import java.util.List;
 
 public class ProviderInfoTest extends AndroidTestCase {
-    private static final String PACKAGE_NAME = "com.android.cts.content";
+    private static final String PACKAGE_NAME = "android.content.cts";
     private static final String PROVIDER_NAME = "android.content.cts.MockContentProvider";
 
     public void testProviderInfo() throws NameNotFoundException {
@@ -50,6 +53,19 @@
         }
     }
 
+    public void testProviderMetaData() {
+        final ProviderInfo info = getContext().getPackageManager()
+                .resolveContentProvider("android.content.cts.fileprovider",
+                        PackageManager.GET_META_DATA);
+        final XmlResourceParser in = info.loadXmlMetaData(
+                getContext().getPackageManager(), "android.support.FILE_PROVIDER_PATHS");
+        try {
+            assertNotNull(in);
+        } finally {
+            IoUtils.closeQuietly(in);
+        }
+    }
+
     private void checkProviderInfoMethods(ProviderInfo providerInfo, Parcel p) {
         // Test toString, describeContents
         assertNotNull(providerInfo.toString());
diff --git a/tests/tests/content/src/android/content/pm/cts/ResolveInfoTest.java b/tests/tests/content/src/android/content/pm/cts/ResolveInfoTest.java
index af3f161..9b149f5 100644
--- a/tests/tests/content/src/android/content/pm/cts/ResolveInfoTest.java
+++ b/tests/tests/content/src/android/content/pm/cts/ResolveInfoTest.java
@@ -26,7 +26,7 @@
 import android.util.Printer;
 
 public class ResolveInfoTest extends AndroidTestCase {
-    private static final String PACKAGE_NAME = "com.android.cts.content";
+    private static final String PACKAGE_NAME = "android.content.cts";
     private static final String MAIN_ACTION_NAME = "android.intent.action.MAIN";
     private static final String ACTIVITY_NAME = "android.content.pm.cts.TestPmActivity";
     private static final String SERVICE_NAME = "android.content.pm.cts.activity.PMTEST_SERVICE";
diff --git a/tests/tests/content/src/android/content/pm/cts/ServiceInfoTest.java b/tests/tests/content/src/android/content/pm/cts/ServiceInfoTest.java
index 297ab69..4298586 100644
--- a/tests/tests/content/src/android/content/pm/cts/ServiceInfoTest.java
+++ b/tests/tests/content/src/android/content/pm/cts/ServiceInfoTest.java
@@ -25,7 +25,7 @@
 import android.test.AndroidTestCase;
 
 public class ServiceInfoTest extends AndroidTestCase {
-    private static final String PACKAGE_NAME = "com.android.cts.content";
+    private static final String PACKAGE_NAME = "android.content.cts";
     private static final String SERVICE_NAME = "android.content.pm.cts.TestPmService";
 
     public void testServiceInfo() throws NameNotFoundException {
diff --git a/tests/tests/content/src/android/content/res/cts/ArrayTest.java b/tests/tests/content/src/android/content/res/cts/ArrayTest.java
index 909fbf6..7ac1133 100644
--- a/tests/tests/content/src/android/content/res/cts/ArrayTest.java
+++ b/tests/tests/content/src/android/content/res/cts/ArrayTest.java
@@ -20,7 +20,7 @@
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
 
-import com.android.cts.content.R;
+import android.content.cts.R;
 
 public class ArrayTest extends AndroidTestCase {
     private Resources mResources;
diff --git a/tests/tests/content/src/android/content/res/cts/AssetFileDescriptorTest.java b/tests/tests/content/src/android/content/res/cts/AssetFileDescriptorTest.java
index e4a9500..f5dc5ca 100644
--- a/tests/tests/content/src/android/content/res/cts/AssetFileDescriptorTest.java
+++ b/tests/tests/content/src/android/content/res/cts/AssetFileDescriptorTest.java
@@ -24,9 +24,11 @@
 import java.util.Arrays;
 
 import android.content.res.AssetFileDescriptor;
+import android.os.Bundle;
 import android.os.Parcel;
 import android.os.ParcelFileDescriptor;
 import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
 
 public class AssetFileDescriptorTest extends AndroidTestCase {
     private static final long START_OFFSET = 0;
@@ -66,6 +68,31 @@
         getContext().deleteFile(FILE_NAME);
     }
 
+    @SmallTest
+    public void testConstructor() throws IOException {
+        ParcelFileDescriptor fd = ParcelFileDescriptor.open(
+                mFile, ParcelFileDescriptor.MODE_READ_WRITE);
+        AssetFileDescriptor assetFileDes;
+        Bundle extras;
+
+        assetFileDes = new AssetFileDescriptor(fd, START_OFFSET, LENGTH);
+        assertNotNull(assetFileDes);
+        assetFileDes.close();
+
+        extras = null;
+        assetFileDes = new AssetFileDescriptor(fd, START_OFFSET, LENGTH, extras);
+        assertEquals(extras, assetFileDes.getExtras());
+        assertNotNull(assetFileDes);
+        assetFileDes.close();
+
+        extras = new Bundle();
+        assetFileDes = new AssetFileDescriptor(fd, START_OFFSET, LENGTH, extras);
+        assertEquals(extras, assetFileDes.getExtras());
+        assertNotNull(assetFileDes);
+        assetFileDes.close();
+    }
+
+    @SmallTest
     public void testInputOutputStream() throws IOException {
         /*
          * test createOutputStream() and createInputStrean()
@@ -150,6 +177,7 @@
         }
     }
 
+    @SmallTest
     public void testMiscMethod() {
         // test getLength()
         assertEquals(LENGTH, mAssetFileDes.getLength());
diff --git a/tests/tests/content/src/android/content/res/cts/AssetManagerTest.java b/tests/tests/content/src/android/content/res/cts/AssetManagerTest.java
index e8d363b..4893ec1 100644
--- a/tests/tests/content/src/android/content/res/cts/AssetManagerTest.java
+++ b/tests/tests/content/src/android/content/res/cts/AssetManagerTest.java
@@ -15,7 +15,7 @@
  */
 package android.content.res.cts;
 
-import com.android.cts.content.R;
+import android.content.cts.R;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
@@ -26,12 +26,15 @@
 import android.content.res.Resources;
 import android.content.res.XmlResourceParser;
 import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
 import android.util.TypedValue;
 
 import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
+import java.util.Arrays;
+import java.util.HashSet;
 
 
 public class AssetManagerTest extends AndroidTestCase{
@@ -43,6 +46,7 @@
         mAssets = mContext.getAssets();
     }
 
+    @SmallTest
     public void testAssetOperations() throws IOException, XmlPullParserException {
         final Resources res = getContext().getResources();
         final TypedValue value = new TypedValue();
@@ -115,6 +119,65 @@
 
     }
 
+    @SmallTest
+    public void testClose() throws IOException, XmlPullParserException {
+        final AssetManager assets = new AssetManager();
+        assets.close();
+
+        // Should no-op.
+        assets.close();
+
+        try {
+            assets.openXmlResourceParser("AndroidManifest.xml");
+            fail("Expected RuntimeException");
+        } catch (RuntimeException e) {
+            // Expected.
+        }
+    }
+
+    @SmallTest
+    public void testGetNonSystemLocales() {
+        // This is the list of locales built into this test package. It is basically the locales
+        // specified in the Android.mk files (assuming they have corresponding resources), plus the
+        // special case for Filipino.
+        final String KNOWN_LOCALES[] = {
+            "cs",
+            "fil",
+            "fil-PH",
+            "fr",
+            "fr-FR",
+            "kok",
+            "kok-419",
+            "kok-419-variant",
+            "kok-IN",
+            "kok-Knda",
+            "kok-Knda-419",
+            "kok-Knda-419-variant",
+            "kok-variant",
+            "tgl",
+            "tgl-PH",
+            "xx",
+            "xx-YY"
+        };
+
+        final HashSet<String> KNOWN_LOCALES_SET =
+                new HashSet<String>(Arrays.asList(KNOWN_LOCALES));
+
+        final String PSEUDO_OR_EMPTY_LOCALES[] = {
+            "",
+            "en-XA",
+            "ar-XB"
+        };
+
+        String locales[] = mAssets.getNonSystemLocales();
+        HashSet<String> localesSet = new HashSet<String>(Arrays.asList(locales));
+        for (String l : PSEUDO_OR_EMPTY_LOCALES) {
+            localesSet.remove(l);
+        }
+
+        assertEquals(KNOWN_LOCALES_SET, localesSet);
+    }
+
     private void assertContextEquals(final String expect, final InputStream inputStream)
             throws IOException {
         final BufferedReader bf = new BufferedReader(new InputStreamReader(inputStream));
diff --git a/tests/tests/content/src/android/content/res/cts/ColorStateListTest.java b/tests/tests/content/src/android/content/res/cts/ColorStateListTest.java
index 88f5798..2029b95 100644
--- a/tests/tests/content/src/android/content/res/cts/ColorStateListTest.java
+++ b/tests/tests/content/src/android/content/res/cts/ColorStateListTest.java
@@ -20,51 +20,110 @@
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
+import android.content.pm.ActivityInfo;
 import android.content.res.ColorStateList;
 import android.content.res.Resources;
 import android.content.res.Resources.NotFoundException;
+import android.content.res.Resources.Theme;
 import android.graphics.Color;
 import android.os.Parcel;
 import android.test.AndroidTestCase;
 
-import com.android.cts.content.R;
-
+import android.content.cts.R;
+import android.test.suitebuilder.annotation.SmallTest;
 
 public class ColorStateListTest extends AndroidTestCase {
-    public void testColorStateList() throws NotFoundException, XmlPullParserException, IOException {
-        final int[][] state = new int[][] { { 0 }, { 0 } };
-        final int[] colors = new int[] { Color.RED, Color.BLUE };
-        ColorStateList c = new ColorStateList(state, colors);
+
+    @SmallTest
+    public void testConstructor() {
+        final int[][] state = new int[][]{{0}, {0}};
+        final int[] colors = new int[]{Color.RED, Color.BLUE};
+        final ColorStateList c = new ColorStateList(state, colors);
         assertTrue(c.isStateful());
         assertEquals(Color.RED, c.getDefaultColor());
+    }
 
-        final int alpha = 36;
-        final ColorStateList c1 = c.withAlpha(alpha);
-        assertNotSame(Color.RED, c1.getDefaultColor());
-        // check alpha
-        assertEquals(alpha, c1.getDefaultColor() >>> 24);
-        assertEquals(Color.RED & 0x00FF0000, c1.getDefaultColor() & 0x00FF0000);
-
-        final int xmlId = R.drawable.testcolor;
-        final int colorInXml = 0xFFA6C839;// this color value is define in testcolor.xml file.
+    @SmallTest
+    public void testCreateFromXml() throws Exception {
+        final int xmlId = R.color.testcolor;
+        final int colorInXml = 0xFFA6C839; // this color value is defined in testcolor.xml file.
         final Resources res = getContext().getResources();
-        c = ColorStateList.createFromXml(res, res.getXml(xmlId));
+        final ColorStateList c = ColorStateList.createFromXml(res, res.getXml(xmlId));
         assertEquals(colorInXml, c.getDefaultColor());
         assertEquals(0, c.describeContents());
         assertFalse(c.isStateful());
         assertNotNull(c.toString());
         assertEquals(colorInXml, c.getColorForState(new int[]{0}, 0));
+    }
 
-        c = ColorStateList.valueOf(Color.GRAY);
+    @SmallTest
+    public void testCreateFromXmlThemed() throws Exception {
+        final int xmlId = R.color.testcolor_themed;
+        final int colorInXml = Color.BLACK; // this color value is defined in styles.xml file.
+        final Resources res = getContext().getResources();
+        final Theme theme = res.newTheme();
+        theme.applyStyle(R.style.Theme_ThemedDrawableTest, true);
+        final ColorStateList c = ColorStateList.createFromXml(res, res.getXml(xmlId), theme);
+        assertEquals(colorInXml, c.getDefaultColor());
+        assertEquals(0, c.describeContents());
+        assertFalse(c.isStateful());
+        assertNotNull(c.toString());
+        assertEquals(colorInXml, c.getColorForState(new int[]{0}, 0));
+    }
+
+    @SmallTest
+    public void testGetChangingConfigurations() {
+        final Resources res = getContext().getResources();
+        ColorStateList c;
+
+        c = res.getColorStateList(R.color.testcolor, null);
+        assertEquals(c.getChangingConfigurations(), 0);
+
+        c = res.getColorStateList(R.color.testcolor_orientation, null);
+        assertEquals(ActivityInfo.CONFIG_ORIENTATION, c.getChangingConfigurations());
+    }
+
+    @SmallTest
+    public void testWithAlpha() {
+        final int[][] state = new int[][]{{0}, {0}};
+        final int[] colors = new int[]{Color.RED, Color.BLUE};
+        final ColorStateList c = new ColorStateList(state, colors);
+        final int alpha = 36;
+        final ColorStateList c1 = c.withAlpha(alpha);
+        assertNotSame(Color.RED, c1.getDefaultColor());
+        assertEquals(alpha, c1.getDefaultColor() >>> 24);
+        assertEquals(Color.RED & 0x00FF0000, c1.getDefaultColor() & 0x00FF0000);
+    }
+
+    @SmallTest
+    public void testValueOf() {
+        final ColorStateList c = ColorStateList.valueOf(Color.GRAY);
         assertEquals(Color.GRAY, c.getDefaultColor());
+    }
 
+    @SmallTest
+    public void testParcelable() {
+        final ColorStateList c = ColorStateList.valueOf(Color.GRAY);
         final Parcel parcel = Parcel.obtain();
         c.writeToParcel(parcel, 0);
         parcel.setDataPosition(0);
-        ColorStateList actual = ColorStateList.CREATOR.createFromParcel(parcel);
-        // can only compare the state and the default color. because no API to
-        // get every color of ColorStateList
+
+        final ColorStateList actual = ColorStateList.CREATOR.createFromParcel(parcel);
         assertEquals(c.isStateful(), actual.isStateful());
         assertEquals(c.getDefaultColor(), actual.getDefaultColor());
     }
+
+    @SmallTest
+    public void testIsOpaque() {
+        ColorStateList c;
+
+        c = ColorStateList.valueOf(Color.GRAY);
+        assertTrue(c.isOpaque());
+
+        c = ColorStateList.valueOf(0x80FFFFFF);
+        assertFalse(c.isOpaque());
+
+        c = ColorStateList.valueOf(Color.TRANSPARENT);
+        assertFalse(c.isOpaque());
+    }
 }
diff --git a/tests/tests/content/src/android/content/res/cts/ConfigTest.java b/tests/tests/content/src/android/content/res/cts/ConfigTest.java
index 0b94b6f..2390146 100644
--- a/tests/tests/content/src/android/content/res/cts/ConfigTest.java
+++ b/tests/tests/content/src/android/content/res/cts/ConfigTest.java
@@ -31,7 +31,7 @@
 import android.util.DisplayMetrics;
 import android.util.Log;
 
-import com.android.cts.content.R;
+import android.content.cts.R;
 
 public class ConfigTest extends AndroidTestCase {
     enum Properties {
diff --git a/tests/tests/content/src/android/content/res/cts/ConfigurationTest.java b/tests/tests/content/src/android/content/res/cts/ConfigurationTest.java
index 30c78a8..bc0f42e 100644
--- a/tests/tests/content/src/android/content/res/cts/ConfigurationTest.java
+++ b/tests/tests/content/src/android/content/res/cts/ConfigurationTest.java
@@ -22,6 +22,7 @@
 import android.content.res.Configuration;
 import android.os.Parcel;
 import android.test.AndroidTestCase;
+import android.util.LocaleList;
 import android.view.View;
 
 public class ConfigurationTest extends AndroidTestCase {
@@ -40,7 +41,7 @@
         mConfig = new Configuration();
         mConfig.fontScale = 2;
         mConfig.mcc = mConfig.mnc = 1;
-        mConfig.locale = Locale.getDefault();
+        mConfig.setLocale(Locale.getDefault());
         mConfig.touchscreen = Configuration.TOUCHSCREEN_NOTOUCH;
         mConfig.keyboard = Configuration.KEYBOARD_NOKEYS;
         mConfig.keyboardHidden = Configuration.KEYBOARDHIDDEN_NO;
@@ -93,6 +94,27 @@
         cfg2.touchscreen = 2;
         assertEquals(1, cfg1.compareTo(cfg2));
 
+        cfg1.setLocales(LocaleList.forLanguageTags("fr"));
+        cfg2.setLocales(LocaleList.forLanguageTags("fr,en"));
+        assertTrue(cfg1.compareTo(cfg2) < 0);
+        cfg1.setLocales(LocaleList.forLanguageTags("fr,en"));
+        cfg2.setLocales(LocaleList.forLanguageTags("fr"));
+        assertTrue(cfg1.compareTo(cfg2) > 0);
+
+        cfg1.setLocales(LocaleList.forLanguageTags("fr,en"));
+        cfg2.setLocales(LocaleList.forLanguageTags("fr,en-US"));
+        assertTrue(cfg1.compareTo(cfg2) < 0);
+        cfg1.setLocales(LocaleList.forLanguageTags("fr,en-US"));
+        cfg2.setLocales(LocaleList.forLanguageTags("fr,en"));
+        assertTrue(cfg1.compareTo(cfg2) > 0);
+
+        cfg1.locale = Locale.forLanguageTag("en");
+        cfg2.locale = Locale.forLanguageTag("en-Shaw");
+        assertTrue(cfg1.compareTo(cfg2) < 0);
+        cfg1.locale = Locale.forLanguageTag("en-Shaw");
+        cfg2.locale = Locale.forLanguageTag("en");
+        assertTrue(cfg1.compareTo(cfg2) > 0);
+
         cfg1.locale = new Locale("", "", "2");
         cfg2.locale = new Locale("", "", "3");
         assertEquals(-1, cfg1.compareTo(cfg2));
@@ -114,6 +136,13 @@
         cfg2.locale = new Locale("2", "", "");
         assertEquals(1, cfg1.compareTo(cfg2));
 
+        cfg1.locale = new Locale("");
+        cfg2.locale = null;
+        assertTrue(cfg1.compareTo(cfg2) < 0);
+        cfg1.locale = null;
+        cfg2.locale = new Locale("");
+        assertTrue(cfg1.compareTo(cfg2) > 0);
+
         cfg1.mnc = 2;
         cfg2.mnc = 3;
         assertEquals(-1, cfg1.compareTo(cfg2));
@@ -160,6 +189,11 @@
                 | ActivityInfo.CONFIG_MNC
                 | ActivityInfo.CONFIG_LOCALE
                 | ActivityInfo.CONFIG_LAYOUT_DIRECTION, mConfigDefault, config);
+        config.setLocales(LocaleList.forLanguageTags("fr,en"));
+        doConfigCompare(ActivityInfo.CONFIG_MCC
+                | ActivityInfo.CONFIG_MNC
+                | ActivityInfo.CONFIG_LOCALE
+                | ActivityInfo.CONFIG_LAYOUT_DIRECTION, mConfigDefault, config);
         config.screenLayout = 1;
         doConfigCompare(ActivityInfo.CONFIG_MCC
                 | ActivityInfo.CONFIG_MNC
@@ -282,6 +316,7 @@
         assertFalse(temp.equals(mConfigDefault));
         temp.setToDefaults();
         assertTrue(temp.equals(mConfigDefault));
+        assertTrue(temp.getLocales().isEmpty());
     }
 
     public void testToString() {
@@ -289,47 +324,62 @@
     }
 
     public void testWriteToParcel() {
-        assertWriteToParcel(createConfig(null), Parcel.obtain());
+        assertWriteToParcel(createConfig((Locale) null), Parcel.obtain());
+        assertWriteToParcel(createConfig(new Locale("")), Parcel.obtain());
         assertWriteToParcel(createConfig(Locale.JAPAN), Parcel.obtain());
+        assertWriteToParcel(createConfig(Locale.forLanguageTag("en-Shaw")), Parcel.obtain());
+        assertWriteToParcel(createConfig(LocaleList.forLanguageTags("fr,en-US")), Parcel.obtain());
     }
 
     public void testSetLocale() {
         Configuration config = new Configuration();
 
+        config.setLocale(null);
+        assertNull(config.locale);
+        assertTrue(config.getLocales().isEmpty());
+
         config.setLocale(Locale.getDefault());
         assertEquals(Locale.getDefault(), config.locale);
-        assertEquals(View.LAYOUT_DIRECTION_LTR, config.getLayoutDirection());
+        assertEquals(new LocaleList(Locale.getDefault()), config.getLocales());
 
         config.setLocale(Locale.ENGLISH);
         assertEquals(Locale.ENGLISH, config.locale);
+        assertEquals(new LocaleList(Locale.ENGLISH), config.getLocales());
         assertEquals(View.LAYOUT_DIRECTION_LTR, config.getLayoutDirection());
 
         config.setLocale(Locale.US);
         assertEquals(Locale.US, config.locale);
+        assertEquals(new LocaleList(Locale.US), config.getLocales());
         assertEquals(View.LAYOUT_DIRECTION_LTR, config.getLayoutDirection());
 
         final Locale arEGLocale = new Locale("ar", "EG");
         config.setLocale(arEGLocale);
         assertEquals(arEGLocale, config.locale);
+        assertEquals(new LocaleList(arEGLocale), config.getLocales());
         assertEquals(View.LAYOUT_DIRECTION_RTL, config.getLayoutDirection());
 
-        final Locale faFALocale = new Locale("fa", "FA");
-        config.setLocale(faFALocale);
-        assertEquals(faFALocale, config.locale);
+        final Locale faIRLocale = new Locale("fa", "IR");
+        config.setLocale(faIRLocale);
+        assertEquals(faIRLocale, config.locale);
+        assertEquals(new LocaleList(faIRLocale), config.getLocales());
         assertEquals(View.LAYOUT_DIRECTION_RTL, config.getLayoutDirection());
 
         final Locale iwILLocale = new Locale("iw", "IL");
         config.setLocale(iwILLocale);
         assertEquals(iwILLocale, config.locale);
+        assertEquals(new LocaleList(iwILLocale), config.getLocales());
+        assertEquals(View.LAYOUT_DIRECTION_RTL, config.getLayoutDirection());
+
+        final Locale urPKLocale = new Locale("ur", "PK");
+        config.setLocale(urPKLocale);
+        assertEquals(urPKLocale, config.locale);
+        assertEquals(new LocaleList(urPKLocale), config.getLocales());
         assertEquals(View.LAYOUT_DIRECTION_RTL, config.getLayoutDirection());
     }
 
     public void testSetGetLayoutDirection() {
         Configuration config = new Configuration();
 
-        config.setLayoutDirection(Locale.getDefault());
-        assertEquals(View.LAYOUT_DIRECTION_LTR, config.getLayoutDirection());
-
         config.setLayoutDirection(Locale.ENGLISH);
         assertEquals(View.LAYOUT_DIRECTION_LTR, config.getLayoutDirection());
 
@@ -340,21 +390,248 @@
         config.setLayoutDirection(arEGLocale);
         assertEquals(View.LAYOUT_DIRECTION_RTL, config.getLayoutDirection());
 
-        final Locale faFALocale = new Locale("fa", "FA");
-        config.setLayoutDirection(faFALocale);
+        final Locale faIRLocale = new Locale("fa", "IR");
+        config.setLayoutDirection(faIRLocale);
         assertEquals(View.LAYOUT_DIRECTION_RTL, config.getLayoutDirection());
 
         final Locale iwILLocale = new Locale("iw", "IL");
         config.setLayoutDirection(iwILLocale);
         assertEquals(View.LAYOUT_DIRECTION_RTL, config.getLayoutDirection());
+
+        final Locale urPKLocale = new Locale("ur", "PK");
+        config.setLayoutDirection(urPKLocale);
+        assertEquals(View.LAYOUT_DIRECTION_RTL, config.getLayoutDirection());
+    }
+
+    public void testIsScreenRound() {
+        Configuration config = new Configuration();
+        assertFalse(config.isScreenRound());
+
+        config.screenLayout |= Configuration.SCREENLAYOUT_ROUND_YES;
+        assertTrue(config.isScreenRound());
+    }
+
+    public void testFixUpLocaleList() {
+        Configuration config = new Configuration();
+
+        config.setLocales(LocaleList.forLanguageTags("fr"));
+        config.locale = null;
+        assertEquals(LocaleList.getEmptyLocaleList(), config.getLocales());
+
+        config.setLocales(LocaleList.forLanguageTags("fr,en"));
+        config.locale = Locale.forLanguageTag("en");
+        assertEquals(LocaleList.forLanguageTags("en"), config.getLocales());
+
+        config.setLocales(LocaleList.forLanguageTags("fr,en"));
+        config.locale = Locale.forLanguageTag("fr");
+        assertEquals(LocaleList.forLanguageTags("fr,en"), config.getLocales());
+    }
+
+    public void testSetTo_nullLocale() {
+        Configuration config1 = new Configuration();
+        Configuration config2 = new Configuration();
+        assertEquals(null, config2.locale);
+
+        config1.setLocale(Locale.FRENCH);
+        config1.setTo(config2);
+        assertEquals(null, config1.locale);
+    }
+
+    public void testSetTo_localeFixUp() {
+        Configuration config1 = new Configuration();
+        Configuration config2 = new Configuration();
+        config2.locale = Locale.FRENCH;
+
+        config1.setTo(config2);
+        assertEquals(Locale.FRENCH, config1.locale);
+        assertEquals(new LocaleList(Locale.FRENCH), config1.getLocales());
+        assertEquals(new LocaleList(Locale.FRENCH), config2.getLocales());
+    }
+
+    public void testToString_localeFixUp() {
+        Configuration config1 = new Configuration();
+        Configuration config2 = new Configuration();
+        config1.setLocales(LocaleList.forLanguageTags("fr,en"));
+        config1.locale = Locale.forLanguageTag("en");
+        config2.setLocales(LocaleList.forLanguageTags("en"));
+
+        assertEquals(config1.toString(), config2.toString());
+    }
+
+    public void testUpdateFrom_localeFixUp() {
+        Configuration config1, config2;
+        int changed;
+
+        config1 = new Configuration();
+        config2 = new Configuration();
+        config1.locale = Locale.FRENCH;
+        changed = config1.updateFrom(config2);
+        assertEquals(0, changed);
+        assertEquals(Locale.FRENCH, config1.locale);
+        assertEquals(new LocaleList(Locale.FRENCH), config1.getLocales());
+
+        config1 = new Configuration();
+        config2 = new Configuration();
+        config2.locale = Locale.FRENCH;
+        changed = config1.updateFrom(config2);
+        assertEquals(ActivityInfo.CONFIG_LOCALE | ActivityInfo.CONFIG_LAYOUT_DIRECTION, changed);
+        assertEquals(Locale.FRENCH, config1.locale);
+        assertEquals(new LocaleList(Locale.FRENCH), config1.getLocales());
+        assertEquals(new LocaleList(Locale.FRENCH), config2.getLocales());
+
+        config1 = new Configuration();
+        config2 = new Configuration();
+        config1.setLocales(LocaleList.forLanguageTags("en,fr"));
+        config1.locale = Locale.forLanguageTag("fr");
+        config2.setLocales(LocaleList.forLanguageTags("en,de"));
+        config2.locale = Locale.forLanguageTag("fr");
+        changed = config1.updateFrom(config2);
+        assertEquals(0, changed);
+        assertEquals(Locale.forLanguageTag("fr"), config1.locale);
+        assertEquals(LocaleList.forLanguageTags("fr"), config1.getLocales());
+        assertEquals(LocaleList.forLanguageTags("fr"), config2.getLocales());
+    }
+
+    public void testUpdateFrom_layoutDirection() {
+        Configuration config1, config2;
+        int changed;
+
+        config1 = new Configuration();
+        config2 = new Configuration();
+        config1.setLocales(LocaleList.forLanguageTags("fr,en"));
+        config2.setLocales(LocaleList.forLanguageTags("de,en"));
+        changed = config1.updateFrom(config2);
+        assertTrue((changed & ActivityInfo.CONFIG_LAYOUT_DIRECTION) != 0);
+
+        config1 = new Configuration();
+        config2 = new Configuration();
+        config1.setLocales(LocaleList.forLanguageTags("fr,en"));
+        config2.setLocales(LocaleList.forLanguageTags("fr,de"));
+        changed = config1.updateFrom(config2);
+        assertEquals(0, changed & ActivityInfo.CONFIG_LAYOUT_DIRECTION);
+    }
+
+    public void testDiff_localeFixUp() {
+        Configuration config1 = new Configuration();
+        Configuration config2 = new Configuration();
+        config1.setLocales(LocaleList.forLanguageTags("en,fr"));
+        config1.locale = Locale.forLanguageTag("fr");
+        config2.setLocales(LocaleList.forLanguageTags("en,de"));
+        config2.locale = Locale.forLanguageTag("fr");
+
+        int diff = config1.diff(config2);
+        assertEquals(0, diff);
+    }
+
+    public void testCompareTo_localeFixUp() {
+        Configuration config1 = new Configuration();
+        Configuration config2 = new Configuration();
+        config1.setLocales(LocaleList.forLanguageTags("en,fr"));
+        config2.setLocales(LocaleList.forLanguageTags("en,fr"));
+        assertEquals(0, config1.compareTo(config2));
+        config1.locale = new Locale("2");
+        config2.locale = new Locale("3");
+        assertEquals(-1, config1.compareTo(config2));
+    }
+
+    public void testSetLocales_null() {
+        Configuration config = new Configuration();
+        config.setLocales(null);
+        assertNull(config.locale);
+        assertNotNull(config.getLocales());
+        assertTrue(config.getLocales().isEmpty());
+        assertEquals(View.LAYOUT_DIRECTION_LTR, config.getLayoutDirection());
+    }
+
+    public void testSetLocales_emptyList() {
+        Configuration config = new Configuration();
+        config.setLocales(LocaleList.getEmptyLocaleList());
+        assertNull(config.locale);
+        assertNotNull(config.getLocales());
+        assertTrue(config.getLocales().isEmpty());
+        assertEquals(View.LAYOUT_DIRECTION_LTR, config.getLayoutDirection());
+    }
+
+    public void testSetLocales_oneLtr() {
+        Configuration config = new Configuration();
+        Locale loc = Locale.forLanguageTag("en");
+        LocaleList ll = new LocaleList(loc);
+        config.setLocales(ll);
+        assertEquals(loc, config.locale);
+        assertEquals(ll, config.getLocales());
+        assertEquals(View.LAYOUT_DIRECTION_LTR, config.getLayoutDirection());
+    }
+
+    public void testSetLocales_oneRtl() {
+        Configuration config = new Configuration();
+        Locale loc = Locale.forLanguageTag("az-Arab");
+        LocaleList ll = new LocaleList(loc);
+        config.setLocales(ll);
+        assertEquals(loc, config.locale);
+        assertEquals(ll, config.getLocales());
+        assertEquals(View.LAYOUT_DIRECTION_RTL, config.getLayoutDirection());
+    }
+
+    public void testSetLocales_twoLocales() {
+        Configuration config = new Configuration();
+        Locale rtlLoc = Locale.forLanguageTag("az-Arab");
+        Locale ltrLoc = Locale.forLanguageTag("en");
+        LocaleList ll = LocaleList.forLanguageTags("az-Arab,en");
+        config.setLocales(ll);
+        assertEquals(rtlLoc, config.locale);
+        assertEquals(ll, config.getLocales());
+        assertEquals(View.LAYOUT_DIRECTION_RTL, config.getLayoutDirection());
+    }
+
+    public void testSetLocales_overridesLocale() {
+        Configuration config = new Configuration();
+        config.locale = Locale.forLanguageTag("en");
+        LocaleList ll = LocaleList.forLanguageTags("az-Arab,en");
+        config.setLocales(ll);
+
+        assertEquals(Locale.forLanguageTag("az-Arab"), config.locale);
+        assertEquals(ll, config.getLocales());
+        assertEquals(View.LAYOUT_DIRECTION_RTL, config.getLayoutDirection());
+    }
+
+    public void testSetLocales_overridesSetLocale() {
+        Configuration config = new Configuration();
+        config.setLocale(Locale.forLanguageTag("en"));
+        LocaleList ll = LocaleList.forLanguageTags("az-Arab,en");
+        config.setLocales(ll);
+
+        assertEquals(Locale.forLanguageTag("az-Arab"), config.locale);
+        assertEquals(ll, config.getLocales());
+        assertEquals(View.LAYOUT_DIRECTION_RTL, config.getLayoutDirection());
+    }
+
+    public void testSetLocale_overridesSetLocales() {
+        Configuration config = new Configuration();
+        config.setLocales(LocaleList.forLanguageTags("az-Arab,en"));
+        config.setLocale(Locale.ENGLISH);
+
+        assertEquals(Locale.ENGLISH, config.locale);
+        assertEquals(new LocaleList(Locale.ENGLISH), config.getLocales());
+        assertEquals(View.LAYOUT_DIRECTION_LTR, config.getLayoutDirection());
+    }
+
+    private Configuration createConfig(LocaleList list) {
+        Configuration config = createConfig();
+        config.setLocales(list);
+        return config;
     }
 
     private Configuration createConfig(Locale locale) {
+        Configuration config = createConfig();
+        config.locale = locale;
+        return config;
+    }
+
+    private Configuration createConfig() {
         Configuration config = new Configuration();
         config.fontScale = 13.37f;
         config.mcc = 0;
         config.mnc = 1;
-        config.locale = locale;
         config.touchscreen = Configuration.TOUCHSCREEN_STYLUS;
         config.keyboard = Configuration.KEYBOARD_UNDEFINED;
         config.keyboardHidden = Configuration.KEYBOARDHIDDEN_YES;
diff --git a/tests/tests/content/src/android/content/res/cts/FractionTest.java b/tests/tests/content/src/android/content/res/cts/FractionTest.java
index 2c3e797..6a65915 100644
--- a/tests/tests/content/src/android/content/res/cts/FractionTest.java
+++ b/tests/tests/content/src/android/content/res/cts/FractionTest.java
@@ -20,7 +20,7 @@
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.util.TypedValue;
-import com.android.cts.content.R;
+import android.content.cts.R;
 
 public class FractionTest extends AndroidTestCase {
 
diff --git a/tests/tests/content/src/android/content/res/cts/PluralResourcesTest.java b/tests/tests/content/src/android/content/res/cts/PluralResourcesTest.java
index 1fd204d..7c42c9e 100644
--- a/tests/tests/content/src/android/content/res/cts/PluralResourcesTest.java
+++ b/tests/tests/content/src/android/content/res/cts/PluralResourcesTest.java
@@ -25,7 +25,7 @@
 import android.test.suitebuilder.annotation.SmallTest;
 import android.util.Log;
 
-import com.android.cts.content.R;
+import android.content.cts.R;
 
 public class PluralResourcesTest extends AndroidTestCase {
     public static boolean DEBUG = false;
@@ -42,7 +42,7 @@
     private Resources resourcesForLanguage(final String lang) {
         final Configuration config = new Configuration();
         config.updateFrom(mResources.getConfiguration());
-        config.locale = new Locale(lang);
+        config.setLocale(new Locale(lang));
         return new Resources(mResources.getAssets(), mResources.getDisplayMetrics(), config);
     }
 
diff --git a/tests/tests/content/src/android/content/res/cts/PrimitiveTest.java b/tests/tests/content/src/android/content/res/cts/PrimitiveTest.java
index 8eeb086..a612a15 100644
--- a/tests/tests/content/src/android/content/res/cts/PrimitiveTest.java
+++ b/tests/tests/content/src/android/content/res/cts/PrimitiveTest.java
@@ -21,7 +21,7 @@
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.util.TypedValue;
-import com.android.cts.content.R;
+import android.content.cts.R;
 
 public class PrimitiveTest extends AndroidTestCase {
     private Resources mResources;
diff --git a/tests/tests/content/src/android/content/res/cts/RawResourceTest.java b/tests/tests/content/src/android/content/res/cts/RawResourceTest.java
index c92efc7..3ca0055 100644
--- a/tests/tests/content/src/android/content/res/cts/RawResourceTest.java
+++ b/tests/tests/content/src/android/content/res/cts/RawResourceTest.java
@@ -19,7 +19,7 @@
 import android.content.res.Resources;
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
-import com.android.cts.content.R;
+import android.content.cts.R;
 
 import java.io.IOException;
 import java.io.InputStream;
diff --git a/tests/tests/content/src/android/content/res/cts/ResourceNameTest.java b/tests/tests/content/src/android/content/res/cts/ResourceNameTest.java
index a7cc03b..dde2422 100644
--- a/tests/tests/content/src/android/content/res/cts/ResourceNameTest.java
+++ b/tests/tests/content/src/android/content/res/cts/ResourceNameTest.java
@@ -20,7 +20,7 @@
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
 
-import com.android.cts.content.R;
+import android.content.cts.R;
 
 public class ResourceNameTest extends AndroidTestCase {
 
@@ -29,10 +29,10 @@
         final Resources res = mContext.getResources();
 
         final String fullName = res.getResourceName(R.configVarying.simple);
-        assertEquals("com.android.cts.content:configVarying/simple", fullName);
+        assertEquals("android.content.cts:configVarying/simple", fullName);
 
         final String packageName = res.getResourcePackageName(R.configVarying.simple);
-        assertEquals("com.android.cts.content", packageName);
+        assertEquals("android.content.cts", packageName);
 
         final String typeName = res.getResourceTypeName(R.configVarying.simple);
         assertEquals("configVarying", typeName);
@@ -45,16 +45,16 @@
     public void testGetResourceIdentifier() {
         final Resources res = mContext.getResources();
         int resid = res.getIdentifier(
-                "com.android.cts.content:configVarying/simple",
+                "android.content.cts:configVarying/simple",
                 null, null);
         assertEquals(R.configVarying.simple, resid);
 
         resid = res.getIdentifier("configVarying/simple", null,
-                "com.android.cts.content");
+                "android.content.cts");
         assertEquals(R.configVarying.simple, resid);
 
         resid = res.getIdentifier("simple", "configVarying",
-                "com.android.cts.content");
+                "android.content.cts");
         assertEquals(R.configVarying.simple, resid);
     }
 }
diff --git a/tests/tests/content/src/android/content/res/cts/ResourcesTest.java b/tests/tests/content/src/android/content/res/cts/ResourcesTest.java
index 4e2d60a..f264f1c 100644
--- a/tests/tests/content/src/android/content/res/cts/ResourcesTest.java
+++ b/tests/tests/content/src/android/content/res/cts/ResourcesTest.java
@@ -16,7 +16,7 @@
 
 package android.content.res.cts;
 
-import com.android.cts.content.R;
+import android.content.cts.R;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
@@ -35,6 +35,7 @@
 import android.test.AndroidTestCase;
 import android.util.AttributeSet;
 import android.util.DisplayMetrics;
+import android.util.LocaleList;
 import android.util.TypedValue;
 import android.util.Xml;
 import android.view.Display;
@@ -48,9 +49,9 @@
     private static final String CONFIG_VARYING = "configVarying";
     private static final String SIMPLE = "simple";
     private static final String CONFIG_VARYING_SIMPLE = "configVarying/simple";
-    private static final String PACKAGE_NAME = "com.android.cts.content";
+    private static final String PACKAGE_NAME = "android.content.cts";
     private static final String COM_ANDROID_CTS_STUB_IDENTIFIER =
-                "com.android.cts.content:configVarying/simple";
+                "android.content.cts:configVarying/simple";
     private Resources mResources;
 
     @Override
@@ -216,14 +217,59 @@
         assertEquals(0xff00ff00, color);
     }
 
+    public Resources createNewResources() {
+        final DisplayMetrics dm = new DisplayMetrics();
+        dm.setToDefaults();
+        final Configuration cfg = new Configuration();
+        cfg.setToDefaults();
+        return new Resources(new AssetManager(), dm, cfg);
+    }
+
     public void testUpdateConfiguration() {
-        final Configuration cfg = mResources.getConfiguration();
+        Resources res = createNewResources();
+        final Configuration cfg = new Configuration(res.getConfiguration());
         assertTrue(cfg.fontScale != 5);
 
         cfg.fontScale = 5;
-        mResources.updateConfiguration(cfg, null);
-        Configuration cfgNew = mResources.getConfiguration();
-        assertEquals(5.0f, cfgNew.fontScale, 0.001f);
+        res.updateConfiguration(cfg, null);
+        assertEquals(5.0f, res.getConfiguration().fontScale, 0.001f);
+    }
+
+    public void testUpdateConfiguration_emptyLocaleIsOverridden() {
+        Resources res = createNewResources();
+        res.getConfiguration().setLocales(null);
+        assertTrue(res.getConfiguration().getLocales().isEmpty());
+
+        final Configuration cfg = new Configuration();
+        cfg.setToDefaults();
+        assertTrue(cfg.getLocales().isEmpty());
+
+        res.updateConfiguration(cfg, null);
+        assertEquals(LocaleList.getDefault(), res.getConfiguration().getLocales());
+    }
+
+    public void testUpdateConfiguration_copyLocales() {
+        Resources res = createNewResources();
+        final Configuration cfg = new Configuration(res.getConfiguration());
+
+        cfg.setLocales(LocaleList.forLanguageTags("az-Arab,ru"));
+
+        res.updateConfiguration(cfg, null);
+        assertEquals(LocaleList.forLanguageTags("az-Arab,ru"), res.getConfiguration().getLocales());
+    }
+
+    public void testUpdateConfiguration_emptyAfterUpdate() {
+        Resources res = createNewResources();
+        final Configuration cfg = new Configuration(res.getConfiguration());
+        cfg.setLocales(LocaleList.forLanguageTags("az-Arab"));
+
+        res.updateConfiguration(cfg, null);
+        assertEquals(LocaleList.forLanguageTags("az-Arab"), res.getConfiguration().getLocales());
+
+        res.getConfiguration().setLocales(null);
+        cfg.setLocales(null);
+        res.updateConfiguration(cfg, null);
+        assertEquals(LocaleList.getDefault(), res.getConfiguration().getLocales());
     }
 
     public void testGetDimensionPixelSize() {
@@ -256,6 +302,20 @@
         assertEquals(142 * targetDensity / defaultDensity, draw.getIntrinsicHeight(), 1);
     }
 
+    public void testGetDrawableForDensity() {
+        final Drawable ldpi = mResources.getDrawableForDensity(
+                R.drawable.density_test, DisplayMetrics.DENSITY_LOW);
+        assertEquals(300, ldpi.getIntrinsicWidth());
+
+        final Drawable mdpi = mResources.getDrawableForDensity(
+                R.drawable.density_test, DisplayMetrics.DENSITY_MEDIUM);
+        assertEquals(200, mdpi.getIntrinsicWidth());
+
+        final Drawable hdpi = mResources.getDrawableForDensity(
+                R.drawable.density_test, DisplayMetrics.DENSITY_HIGH);
+        assertEquals(100, hdpi.getIntrinsicWidth());
+    }
+
     public void testGetAnimation() throws Exception {
         try {
             mResources.getAnimation(-1);
@@ -319,11 +379,27 @@
             //expected
         }
 
-        mResources.getValue("com.android.cts.content:raw/text", tv, false);
+        mResources.getValue("android.content.cts:raw/text", tv, false);
         assertNotNull(tv);
         assertEquals("res/raw/text.txt", tv.coerceToString());
     }
 
+    public void testGetValueForDensity() {
+        final TypedValue tv = new TypedValue();
+
+        mResources.getValueForDensity(R.string.density_string,
+                DisplayMetrics.DENSITY_LOW, tv, false);
+        assertEquals("ldpi", tv.coerceToString());
+
+        mResources.getValueForDensity(R.string.density_string,
+                DisplayMetrics.DENSITY_MEDIUM, tv, false);
+        assertEquals("mdpi", tv.coerceToString());
+
+        mResources.getValueForDensity(R.string.density_string,
+                DisplayMetrics.DENSITY_HIGH, tv, false);
+        assertEquals("hdpi", tv.coerceToString());
+    }
+
     public void testGetAssets() {
         final AssetManager aM = mResources.getAssets();
         assertNotNull(aM);
@@ -456,7 +532,7 @@
     private Resources resourcesForLanguage(final String lang) {
         final Configuration config = new Configuration();
         config.updateFrom(mResources.getConfiguration());
-        config.locale = new Locale(lang);
+        config.setLocale(new Locale(lang));
         return new Resources(mResources.getAssets(), mResources.getDisplayMetrics(), config);
     }
 
diff --git a/tests/tests/content/src/android/content/res/cts/Resources_NotFoundExceptionTest.java b/tests/tests/content/src/android/content/res/cts/Resources_NotFoundExceptionTest.java
index 8fa8d7b..d75fcdd 100644
--- a/tests/tests/content/src/android/content/res/cts/Resources_NotFoundExceptionTest.java
+++ b/tests/tests/content/src/android/content/res/cts/Resources_NotFoundExceptionTest.java
@@ -23,41 +23,57 @@
 public class Resources_NotFoundExceptionTest extends TestCase {
 
     public void testNotFoundException() {
-        NotFoundException ne = null;
-        boolean isThrowed = false;
-        boolean isFinnalyRun = false;
+        NotFoundException ne;
+        boolean wasThrown;
+
+        wasThrown = false;
+        ne = new NotFoundException();
+
         try {
-            ne = new NotFoundException();
             throw ne;
         } catch (NotFoundException e) {
             // expected
             assertSame(ne, e);
-            isThrowed = true;
+            wasThrown = true;
         } finally {
-            if (!isThrowed) {
+            if (!wasThrown) {
                 fail("should throw out NotFoundException");
             }
-            isFinnalyRun = true;
         }
-        assertTrue(isFinnalyRun);
 
-        isThrowed = false;
-        isFinnalyRun = false;
         final String MESSAGE = "test";
+        wasThrown = false;
+        ne = new NotFoundException(MESSAGE);
+
         try {
-            ne = new NotFoundException(MESSAGE);
             throw ne;
         } catch (NotFoundException e) {
             // expected
             assertSame(ne, e);
             assertEquals(MESSAGE, e.getMessage());
-            isThrowed = true;
+            wasThrown = true;
         } finally {
-            if (!isThrowed) {
+            if (!wasThrown) {
                 fail("should throw out NotFoundException");
             }
-            isFinnalyRun = true;
         }
-        assertTrue(isFinnalyRun);
+
+        final Exception CAUSE = new NullPointerException();
+        wasThrown = false;
+        ne = new NotFoundException(MESSAGE, CAUSE);
+
+        try {
+            throw ne;
+        } catch (NotFoundException e) {
+            // expected
+            assertSame(ne, e);
+            assertEquals(MESSAGE, e.getMessage());
+            assertEquals(CAUSE, e.getCause());
+            wasThrown = true;
+        } finally {
+            if (!wasThrown) {
+                fail("should throw out NotFoundException");
+            }
+        }
     }
 }
diff --git a/tests/tests/content/src/android/content/res/cts/Resources_ThemeTest.java b/tests/tests/content/src/android/content/res/cts/Resources_ThemeTest.java
index 6d1c2e4..b7a621f 100644
--- a/tests/tests/content/src/android/content/res/cts/Resources_ThemeTest.java
+++ b/tests/tests/content/src/android/content/res/cts/Resources_ThemeTest.java
@@ -23,13 +23,16 @@
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.content.res.Resources.Theme;
+import android.graphics.Color;
+import android.graphics.drawable.ColorDrawable;
 import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
 import android.util.AttributeSet;
 import android.util.TypedValue;
 import android.util.Xml;
 import android.view.View;
 
-import com.android.cts.content.R;
+import android.content.cts.R;
 
 import java.util.Locale;
 
@@ -44,6 +47,7 @@
         mResTheme = getContext().getResources().newTheme();
     }
 
+    @SmallTest
     public void testSetMethods() {
         // call a native method, and have no way to get the style
         mResTheme.applyStyle(R.raw.testmp3, false);
@@ -54,6 +58,7 @@
         mResTheme.setTo(other);
     }
 
+    @SmallTest
     public void testObtainStyledAttributes() {
         final int[] attrs = new int[1];
         attrs[0] = R.raw.testmp3;
@@ -77,12 +82,14 @@
         testTypedArray.recycle();
     }
 
+    @SmallTest
     public void testResolveAttribute() {
         final TypedValue value = new TypedValue();
         getContext().getResources().getValue(R.raw.testmp3, value, true);
         assertFalse(mResTheme.resolveAttribute(R.raw.testmp3, value, false));
     }
 
+    @SmallTest
     public void testGetChangingConfigurations() {
         Resources.Theme theme = getContext().getResources().newTheme();
         assertEquals("Initial changing configuration mask is empty",
@@ -104,10 +111,13 @@
                 theme.getChangingConfigurations());
     }
 
+    @SmallTest
     public void testRebase() {
         Resources res = getContext().getResources();
         Configuration config = res.getConfiguration();
         config.setLocale(Locale.ENGLISH);
+        res.updateConfiguration(config, null);
+
         assertEquals("Theme will be created in LTR config",
                 View.LAYOUT_DIRECTION_LTR, config.getLayoutDirection());
 
@@ -130,4 +140,21 @@
         assertEquals("Theme was rebased in RTL config", true, t.getBoolean(0, false));
         t.recycle();
     }
+
+    @SmallTest
+    public void testGetDrawable() {
+        final Resources res = getContext().getResources();
+        final Theme theme = res.newTheme();
+        theme.applyStyle(R.style.Theme_ThemedDrawableTest, true);
+
+        final ColorDrawable dr = (ColorDrawable) theme.getDrawable(R.drawable.colordrawable_themed);
+        assertEquals(Color.BLACK, dr.getColor());
+    }
+
+    @SmallTest
+    public void testGetResources() {
+        final Resources res = getContext().getResources();
+        final Theme theme = res.newTheme();
+        assertSame(res, theme.getResources());
+    }
 }
diff --git a/tests/tests/content/src/android/content/res/cts/TypedArrayTest.java b/tests/tests/content/src/android/content/res/cts/TypedArrayTest.java
index 346bb9b..ee7449c 100644
--- a/tests/tests/content/src/android/content/res/cts/TypedArrayTest.java
+++ b/tests/tests/content/src/android/content/res/cts/TypedArrayTest.java
@@ -16,11 +16,11 @@
 
 package android.content.res.cts;
 
-import com.android.cts.content.R;
-
 import org.xmlpull.v1.XmlPullParserException;
 
+import android.content.cts.R;
 import android.content.cts.util.XmlUtils;
+import android.content.pm.ActivityInfo;
 import android.content.res.TypedArray;
 import android.content.res.XmlResourceParser;
 import android.test.AndroidTestCase;
@@ -30,12 +30,10 @@
 
 import java.io.IOException;
 
-
-public class TypedArrayTest extends AndroidTestCase{
-    private TypedArray mTypedArray;
+public class TypedArrayTest extends AndroidTestCase {
     private static final int DEFINT = -1;
     private static final float DEFFLOAT = -1.0f;
-    private static final int EXPECTEDCLOLOR = 0xff0000ff;
+    private static final int EXPECTED_COLOR = 0xff0000ff;
     private static final int EXPECTED_COLOR_STATE = 0xff00ff00;
     private static final float EXPECTED_DIMENSION = 0.75f;
     private static final int EXPECTED_PIXEL_OFFSET = 10;
@@ -47,20 +45,23 @@
     private static final String EXPECTED_STRING = "Hello, Android!";
     private static final String EXPECTED_TEXT = "TypedArray Test!";
     private static final String[] EXPECTED_TEXT_ARRAY = {"Easy", "Medium", "Hard"};
-    private static final int EXPETED_INDEX = 15;
+    private static final int EXPECTED_INDEX = 15;
     private static final TypedValue DEF_VALUE = new TypedValue();
-    private static final int EXPECTED_INDEX_COUNT = 16;
+    private static final int EXPECTED_INDEX_COUNT = 17;
     private static final String EXPTECTED_POS_DESCRIP = "<internal>";
-    private static final int EXPECTED_LENGTH = 16;
+    private static final int EXPECTED_LENGTH = 19;
     private static final String EXPECTED_NON_RESOURCE_STRING = "testNonResourcesString";
     private static final String XML_BEGIN = "resources";
     private static final int EXPECTED_INT_ATT = 86400;
+    private static final int EXPECTED_CHANGING_CONFIG =
+            ActivityInfo.CONFIG_ORIENTATION | ActivityInfo.CONFIG_LOCALE;
+
+    private TypedArray mTypedArray;
 
     @Override
     protected void setUp() throws Exception {
         super.setUp();
-        final int[] attrs = R.styleable.style1;
-        mTypedArray = getContext().getTheme().obtainStyledAttributes(R.style.Whatever, attrs);
+        mTypedArray = getContext().getTheme().obtainStyledAttributes(R.style.Whatever, R.styleable.style1);
     }
 
     @Override
@@ -69,85 +70,126 @@
         mTypedArray.recycle();
     }
 
-    /*
-     * Test all get attrs methods, all test value are in styles.xml and attrs.xml.
-     */
-    public void testAttrsMethod() {
-        // getBoolean test
-        assertTrue(mTypedArray.getBoolean(R.styleable.style1_type1, false));
-        assertFalse(mTypedArray.getBoolean(R.styleable.style1_type2, true));
+    public void testGetType() {
+        final TypedArray t = getContext().getTheme().obtainStyledAttributes(
+                R.style.Whatever, R.styleable.style1);
 
-        assertEquals(EXPECTEDCLOLOR, mTypedArray.getColor(R.styleable.style1_type3, DEFINT));
+        assertEquals(TypedValue.TYPE_INT_BOOLEAN, t.getType(R.styleable.style1_type1));
+        assertEquals(TypedValue.TYPE_INT_BOOLEAN, t.getType(R.styleable.style1_type2));
+        assertEquals(TypedValue.TYPE_INT_COLOR_ARGB8, t.getType(R.styleable.style1_type3));
+        assertEquals(TypedValue.TYPE_INT_COLOR_ARGB8, t.getType(R.styleable.style1_type4));
+        assertEquals(TypedValue.TYPE_DIMENSION, t.getType(R.styleable.style1_type5));
+        assertEquals(TypedValue.TYPE_DIMENSION, t.getType(R.styleable.style1_type6));
+        assertEquals(TypedValue.TYPE_DIMENSION, t.getType(R.styleable.style1_type7));
+        assertEquals(TypedValue.TYPE_STRING, t.getType(R.styleable.style1_type8));
+        assertEquals(TypedValue.TYPE_FLOAT, t.getType(R.styleable.style1_type9));
+        assertEquals(TypedValue.TYPE_FRACTION, t.getType(R.styleable.style1_type10));
+        assertEquals(TypedValue.TYPE_INT_DEC, t.getType(R.styleable.style1_type11));
+        assertEquals(TypedValue.TYPE_INT_DEC, t.getType(R.styleable.style1_type12));
+        assertEquals(TypedValue.TYPE_STRING, t.getType(R.styleable.style1_type13));
+        assertEquals(TypedValue.TYPE_STRING, t.getType(R.styleable.style1_type14));
+        assertEquals(TypedValue.TYPE_REFERENCE, t.getType(R.styleable.style1_type15));
+        assertEquals(TypedValue.TYPE_STRING, t.getType(R.styleable.style1_type16));
+        assertEquals(TypedValue.TYPE_NULL, t.getType(R.styleable.style1_typeEmpty));
+        assertEquals(TypedValue.TYPE_NULL, t.getType(R.styleable.style1_typeUndefined));
 
-        // getColorStateList test
-        final int[] set = new int[1];
-        set[0] = 0;
+        t.recycle();
+    }
+
+    public void testBasics() {
+        final TypedArray t = getContext().getTheme().obtainStyledAttributes(
+                R.style.Whatever, R.styleable.style1);
+
+        assertEquals(EXPECTED_CHANGING_CONFIG, t.getChangingConfigurations());
+        assertEquals(EXPECTED_INDEX_COUNT, t.getIndexCount());
+        assertEquals(EXPTECTED_POS_DESCRIP, t.getPositionDescription());
+        assertEquals(EXPECTED_LENGTH, t.length());
+        assertEquals(getContext().getResources(), t.getResources());
+        assertNotNull(t.toString());
+
+        t.recycle();
+    }
+
+    public void testGetAttributes() {
+        final TypedArray t = getContext().getTheme().obtainStyledAttributes(
+                R.style.Whatever, R.styleable.style1);
+
+        assertTrue(t.getBoolean(R.styleable.style1_type1, false));
+        assertFalse(t.getBoolean(R.styleable.style1_type2, true));
+
+        assertEquals(EXPECTED_COLOR,
+                t.getColor(R.styleable.style1_type3, DEFINT));
         assertEquals(EXPECTED_COLOR_STATE,
-                mTypedArray.getColorStateList(R.styleable.style1_type4).
-                getColorForState(set, DEFINT));
+                t.getColorStateList(R.styleable.style1_type4).getDefaultColor());
 
         // This get values equals attribute dimension value set in styles.xml
         // multiplied by the appropriate metric, the metric is unknown.
         assertEquals(EXPECTED_DIMENSION,
-                mTypedArray.getDimension(R.styleable.style1_type5, DEFFLOAT));
+                t.getDimension(R.styleable.style1_type5, DEFFLOAT));
+
         assertEquals(EXPECTED_PIXEL_OFFSET,
-                mTypedArray.getDimensionPixelOffset(R.styleable.style1_type6, DEFINT));
+                t.getDimensionPixelOffset(R.styleable.style1_type6, DEFINT));
         assertEquals(EXPECTED_LAYOUT_DIMENSION,
-                mTypedArray.getLayoutDimension(R.styleable.style1_type6, "type6"));
+                t.getLayoutDimension(R.styleable.style1_type6, "type6"));
         assertEquals(EXPECTED_LAYOUT_DIMENSION,
-                mTypedArray.getLayoutDimension(R.styleable.style1_type6, 0));
+                t.getLayoutDimension(R.styleable.style1_type6, 0));
+
         assertEquals(EXPECTED_PIXEL_SIZE,
-                mTypedArray.getDimensionPixelSize(R.styleable.style1_type7, DEFINT));
+                t.getDimensionPixelSize(R.styleable.style1_type7, DEFINT));
 
-        // getDrawable test
-        assertNotNull(mTypedArray.getDrawable(R.styleable.style1_type8));
-        // getResourceId test
-        assertEquals(R.drawable.pass,
-                mTypedArray.getResourceId(R.styleable.style1_type8, DEFINT));
+        assertNotNull(t.getDrawable(R.styleable.style1_type8));
+        assertEquals(R.drawable.pass, t.getResourceId(R.styleable.style1_type8, DEFINT));
 
-        assertEquals(EXPECTED_FLOAT, mTypedArray.getFloat(R.styleable.style1_type9, DEFFLOAT));
-
+        assertEquals(EXPECTED_FLOAT,
+                t.getFloat(R.styleable.style1_type9, DEFFLOAT));
         assertEquals(EXPECTED_FRACTION,
-                mTypedArray.getFraction(R.styleable.style1_type10, 10, 10, DEFFLOAT));
+                t.getFraction(R.styleable.style1_type10, 10, 10, DEFFLOAT));
+        assertEquals(EXPECTED_INT,
+                t.getInt(R.styleable.style1_type11, DEFINT));
+        assertEquals(EXPECTED_INT_ATT,
+                t.getInteger(R.styleable.style1_type12, DEFINT));
 
-        assertEquals(EXPECTED_INT, mTypedArray.getInt(R.styleable.style1_type11, DEFINT));
+        assertEquals(EXPECTED_STRING, t.getString(R.styleable.style1_type13));
+        assertNull(t.getNonResourceString(R.styleable.style1_type14));
+        assertEquals(EXPECTED_TEXT, t.getText(R.styleable.style1_type14));
 
-        assertEquals(EXPECTED_INT_ATT, mTypedArray.getInteger(R.styleable.style1_type12, DEFINT));
-
-        assertEquals(EXPECTED_STRING, mTypedArray.getString(R.styleable.style1_type13));
-
-        // getNonResourceString test
-        assertNull(mTypedArray.getNonResourceString(R.styleable.style1_type14));
-
-        assertEquals(EXPECTED_TEXT, mTypedArray.getText(R.styleable.style1_type14));
-
-        CharSequence[] textArray = mTypedArray.getTextArray(R.styleable.style1_type15);
+        final CharSequence[] textArray = t.getTextArray(R.styleable.style1_type15);
         assertEquals(EXPECTED_TEXT_ARRAY[0], textArray[0]);
         assertEquals(EXPECTED_TEXT_ARRAY[1], textArray[1]);
         assertEquals(EXPECTED_TEXT_ARRAY[2], textArray[2]);
 
-        // getIndex test
-        int index = mTypedArray.getIndex(R.styleable.style1_type16);
-        assertEquals(EXPETED_INDEX, index);
-        assertTrue(mTypedArray.getValue(index, DEF_VALUE));
-        // hasValue test
-        assertTrue(mTypedArray.hasValue(R.styleable.style1_type16));
+        final int index = t.getIndex(R.styleable.style1_type16);
+        assertEquals(EXPECTED_INDEX, index);
+        assertTrue(t.getValue(index, DEF_VALUE));
+    }
 
-        // peekValue test
-        assertNotNull(mTypedArray.peekValue(R.styleable.style1_type16));
+    public void testPeekValue() {
+        final TypedArray t = getContext().getTheme().obtainStyledAttributes(
+                R.style.Whatever, R.styleable.style1);
 
-        assertEquals(EXPECTED_INDEX_COUNT, mTypedArray.getIndexCount());
+        final TypedValue v = t.peekValue(R.styleable.style1_type11);
+        assertNotNull(v);
+        assertEquals(TypedValue.TYPE_INT_DEC, v.type);
+        assertEquals(EXPECTED_INT, v.data);
 
-        assertEquals(EXPTECTED_POS_DESCRIP,
-                mTypedArray.getPositionDescription());
+        t.recycle();
+    }
 
-        // getResources test
-        assertEquals(getContext().getResources(), mTypedArray.getResources());
+    public void testHasValue() {
+        final TypedArray t = getContext().getTheme().obtainStyledAttributes(
+                R.style.Whatever, R.styleable.style1);
 
-        assertEquals(EXPECTED_LENGTH, mTypedArray.length());
+        // hasValue()
+        assertTrue(t.hasValue(R.styleable.style1_type16));
+        assertFalse(t.hasValue(R.styleable.style1_typeEmpty));
+        assertFalse(t.hasValue(R.styleable.style1_typeUndefined));
 
-        // toString test
-        assertNotNull(mTypedArray.toString());
+        // hasValueOrEmpty()
+        assertTrue(t.hasValueOrEmpty(R.styleable.style1_type16));
+        assertTrue(t.hasValueOrEmpty(R.styleable.style1_typeEmpty));
+        assertFalse(t.hasValueOrEmpty(R.styleable.style1_typeUndefined));
+
+        t.recycle();
     }
 
     public void testRecycle() {
diff --git a/tests/tests/database/Android.mk b/tests/tests/database/Android.mk
index 8557c60..36ca51b 100644
--- a/tests/tests/database/Android.mk
+++ b/tests/tests/database/Android.mk
@@ -29,4 +29,7 @@
 
 LOCAL_PACKAGE_NAME := CtsDatabaseTestCases
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/database/AndroidManifest.xml b/tests/tests/database/AndroidManifest.xml
index fefcc1f..f9043db 100644
--- a/tests/tests/database/AndroidManifest.xml
+++ b/tests/tests/database/AndroidManifest.xml
@@ -16,7 +16,7 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.database">
+    package="android.database.cts">
 
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <application>
@@ -24,7 +24,7 @@
     </application>
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.cts.database"
+                     android:targetPackage="android.database.cts"
                      android:label="CTS tests of android.database">
         <meta-data android:name="listener"
             android:value="com.android.cts.runner.CtsTestRunListener" />
diff --git a/tests/tests/database/AndroidTest.xml b/tests/tests/database/AndroidTest.xml
new file mode 100644
index 0000000..046215d
--- /dev/null
+++ b/tests/tests/database/AndroidTest.xml
@@ -0,0 +1,23 @@
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS Database test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsDatabaseTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.database.cts" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/tests/database/src/android/database/cts/AbstractCursorTest.java b/tests/tests/database/src/android/database/cts/AbstractCursorTest.java
index 1ea6ff0..ec3ca74 100644
--- a/tests/tests/database/src/android/database/cts/AbstractCursorTest.java
+++ b/tests/tests/database/src/android/database/cts/AbstractCursorTest.java
@@ -417,7 +417,7 @@
 
     private void setupDatabase() {
         File dbDir = getInstrumentation().getTargetContext().getDir("tests",
-                Context.MODE_WORLD_WRITEABLE);
+                Context.MODE_PRIVATE);
         mDatabaseFile = new File(dbDir, "database_test.db");
         if (mDatabaseFile.exists()) {
             mDatabaseFile.delete();
diff --git a/tests/tests/display/Android.mk b/tests/tests/display/Android.mk
index f17f580..5de5610 100644
--- a/tests/tests/display/Android.mk
+++ b/tests/tests/display/Android.mk
@@ -16,17 +16,26 @@
 
 include $(CLEAR_VARS)
 
-# don't include this package in any target
-LOCAL_MODULE_TAGS := optional
-# and when built explicitly put it in the data partition
+# Don't include this package in any target
+LOCAL_MODULE_TAGS := tests
+# When built explicitly put it in the data partition
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
 
-LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
+LOCAL_DEX_PREOPT := false
+
+LOCAL_PROGUARD_ENABLED := disabled
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-test platform-test-annotations
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_PACKAGE_NAME := CtsDisplayTestCases
 
+LOCAL_CTS_MODULE_CONFIG := $(LOCAL_PATH)/Old$(CTS_MODULE_TEST_CONFIG)
+
 LOCAL_SDK_VERSION := current
 
 include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/display/AndroidManifest.xml b/tests/tests/display/AndroidManifest.xml
index bf84219..22cc824 100644
--- a/tests/tests/display/AndroidManifest.xml
+++ b/tests/tests/display/AndroidManifest.xml
@@ -16,9 +16,8 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.display">
+    package="android.display.cts">
 
-    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <!-- For special presentation windows when testing mode switches. -->
     <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
 
@@ -26,12 +25,11 @@
         <uses-library android:name="android.test.runner" />
     </application>
 
-    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.cts.display"
-                     android:label="CTS tests of android.view.display">
-        <meta-data
-            android:name="listener"
-            android:value="com.android.cts.runner.CtsTestRunListener" />
+    <!--  self-instrumenting test package. -->
+    <instrumentation
+        android:name="android.support.test.runner.AndroidJUnitRunner"
+        android:targetPackage="android.display.cts"
+        android:label="CTS tests of android.display">
     </instrumentation>
 
 </manifest>
diff --git a/tests/tests/display/AndroidTest.xml b/tests/tests/display/AndroidTest.xml
index dd42984..f346c22 100644
--- a/tests/tests/display/AndroidTest.xml
+++ b/tests/tests/display/AndroidTest.xml
@@ -13,9 +13,17 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<configuration description="Base config for CTS package preparer">
-    <include name="common-config" />
-    <!-- Use a non-standard pattern, must match values in tests/tests/display/.../DisplayTest.java -->
-    <option name="run-command:run-command" value="settings put global overlay_display_devices '181x161/214|181x161/214'" />
-    <option name="run-command:teardown-command" value="settings put global overlay_display_devices &quot;&quot;" />
-</configuration>
+<configuration description="Config for CTS Acceleration test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsDisplayTestCases.apk" />
+    </target_preparer>
+    <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+        <!-- Use a non-standard pattern, must match values in tests/tests/display/.../DisplayTest.java -->
+        <option name="run-command" value="settings put global overlay_display_devices '181x161/214|181x161/214'" />
+        <option name="teardown-command" value="settings put global overlay_display_devices &quot;&quot;" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.display.cts" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/tests/display/OldAndroidTest.xml b/tests/tests/display/OldAndroidTest.xml
new file mode 100644
index 0000000..dd42984
--- /dev/null
+++ b/tests/tests/display/OldAndroidTest.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Base config for CTS package preparer">
+    <include name="common-config" />
+    <!-- Use a non-standard pattern, must match values in tests/tests/display/.../DisplayTest.java -->
+    <option name="run-command:run-command" value="settings put global overlay_display_devices '181x161/214|181x161/214'" />
+    <option name="run-command:teardown-command" value="settings put global overlay_display_devices &quot;&quot;" />
+</configuration>
diff --git a/tests/tests/display/src/android/display/cts/DisplayTest.java b/tests/tests/display/src/android/display/cts/DisplayTest.java
index 1f9f8d1..1d1db2b 100644
--- a/tests/tests/display/src/android/display/cts/DisplayTest.java
+++ b/tests/tests/display/src/android/display/cts/DisplayTest.java
@@ -28,6 +28,7 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.os.ParcelFileDescriptor;
+import android.platform.test.annotations.Presubmit;
 import android.test.InstrumentationTestCase;
 import android.util.DisplayMetrics;
 import android.view.Display;
@@ -139,6 +140,7 @@
     /**
      * Verify that the WindowManager returns the default display.
      */
+    @Presubmit
     public void testDefaultDisplay() {
         assertEquals(Display.DEFAULT_DISPLAY, mWindowManager.getDefaultDisplay().getDisplayId());
     }
diff --git a/tests/tests/dpi/Android.mk b/tests/tests/dpi/Android.mk
index 4c05ecf..3f4cde5 100644
--- a/tests/tests/dpi/Android.mk
+++ b/tests/tests/dpi/Android.mk
@@ -17,7 +17,7 @@
 
 include $(CLEAR_VARS)
 
-LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
+LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner platform-test-annotations
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
@@ -30,6 +30,9 @@
 
 LOCAL_SDK_VERSION := current
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_CTS_PACKAGE)
 
 # ============================================================
diff --git a/tests/tests/dpi/AndroidManifest.xml b/tests/tests/dpi/AndroidManifest.xml
index 0197056..118050e 100644
--- a/tests/tests/dpi/AndroidManifest.xml
+++ b/tests/tests/dpi/AndroidManifest.xml
@@ -16,7 +16,7 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.dpi">
+    package="android.dpi.cts">
 
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <application>
@@ -27,7 +27,7 @@
     </application>
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.cts.dpi"
+                     android:targetPackage="android.dpi.cts"
                      android:label="CTS tests for DPI">
         <meta-data android:name="listener"
             android:value="com.android.cts.runner.CtsTestRunListener" />
diff --git a/tests/tests/dpi/AndroidTest.xml b/tests/tests/dpi/AndroidTest.xml
new file mode 100644
index 0000000..b8d941b
--- /dev/null
+++ b/tests/tests/dpi/AndroidTest.xml
@@ -0,0 +1,23 @@
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS DPI test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsDpiTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.dpi.cts" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/tests/dpi/src/android/dpi/cts/ConfigurationTest.java b/tests/tests/dpi/src/android/dpi/cts/ConfigurationTest.java
index e722646..fc38fdd 100644
--- a/tests/tests/dpi/src/android/dpi/cts/ConfigurationTest.java
+++ b/tests/tests/dpi/src/android/dpi/cts/ConfigurationTest.java
@@ -18,6 +18,7 @@
 
 import android.content.Context;
 import android.content.pm.PackageManager;
+import android.platform.test.annotations.Presubmit;
 import android.test.AndroidTestCase;
 import android.util.DisplayMetrics;
 import android.view.Display;
@@ -31,6 +32,7 @@
  */
 public class ConfigurationTest extends AndroidTestCase {
 
+    @Presubmit
     public void testScreenConfiguration() {
         WindowManager windowManager =
                 (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
diff --git a/tests/tests/dpi/src/android/dpi/cts/DefaultManifestAttributesSdkTest.java b/tests/tests/dpi/src/android/dpi/cts/DefaultManifestAttributesSdkTest.java
index 9253eca..d11f3ae 100644
--- a/tests/tests/dpi/src/android/dpi/cts/DefaultManifestAttributesSdkTest.java
+++ b/tests/tests/dpi/src/android/dpi/cts/DefaultManifestAttributesSdkTest.java
@@ -24,7 +24,7 @@
  */
 public class DefaultManifestAttributesSdkTest extends DefaultManifestAttributesTest {
     protected String getPackageName() {
-        return "com.android.cts.dpi";
+        return "android.dpi.cts";
     }
 
     // This is a sanity test to make sure that we're instrumenting the proper package
diff --git a/tests/tests/dpi2/Android.mk b/tests/tests/dpi2/Android.mk
index 03a687d..2919ef8 100644
--- a/tests/tests/dpi2/Android.mk
+++ b/tests/tests/dpi2/Android.mk
@@ -30,4 +30,7 @@
 
 LOCAL_SDK_VERSION := current
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/dpi2/AndroidManifest.xml b/tests/tests/dpi2/AndroidManifest.xml
index 6dbdc23..bb21910 100644
--- a/tests/tests/dpi2/AndroidManifest.xml
+++ b/tests/tests/dpi2/AndroidManifest.xml
@@ -16,7 +16,7 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.dpi2">
+    package="android.dpi2.cts">
 
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <application>
@@ -28,7 +28,7 @@
     <uses-sdk android:targetSdkVersion="3" />
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.cts.dpi2"
+                     android:targetPackage="android.dpi2.cts"
                      android:label="CTS tests for DPI">
         <meta-data android:name="listener"
             android:value="com.android.cts.runner.CtsTestRunListener" />
diff --git a/tests/tests/dpi2/AndroidTest.xml b/tests/tests/dpi2/AndroidTest.xml
new file mode 100644
index 0000000..dfb1730
--- /dev/null
+++ b/tests/tests/dpi2/AndroidTest.xml
@@ -0,0 +1,23 @@
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS DPI test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsDpiTestCases2.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.dpi2.cts" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/tests/dpi2/src/android/dpi2/cts/DefaultManifestAttributesCupcakeTest.java b/tests/tests/dpi2/src/android/dpi2/cts/DefaultManifestAttributesCupcakeTest.java
index 27a082b..04db412 100644
--- a/tests/tests/dpi2/src/android/dpi2/cts/DefaultManifestAttributesCupcakeTest.java
+++ b/tests/tests/dpi2/src/android/dpi2/cts/DefaultManifestAttributesCupcakeTest.java
@@ -29,7 +29,7 @@
  */
 public class DefaultManifestAttributesCupcakeTest extends DefaultManifestAttributesTest {
     protected String getPackageName() {
-        return "com.android.cts.dpi2";
+        return "android.dpi2.cts";
     }
 
     // This is a sanity test to make sure that we're instrumenting the proper package
diff --git a/tests/tests/draganddrop/Android.mk b/tests/tests/draganddrop/Android.mk
new file mode 100644
index 0000000..8b59788
--- /dev/null
+++ b/tests/tests/draganddrop/Android.mk
@@ -0,0 +1,41 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+# Don't include this package in any target
+LOCAL_MODULE_TAGS := tests
+# When built, explicitly put it in the data partition.
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_DEX_PREOPT := false
+
+LOCAL_PROGUARD_ENABLED := disabled
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_STATIC_JAVA_LIBRARIES := ub-uiautomator android-support-test
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_PACKAGE_NAME := CtsDragAndDropTestCases
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_PACKAGE)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
\ No newline at end of file
diff --git a/tests/tests/draganddrop/AndroidManifest.xml b/tests/tests/draganddrop/AndroidManifest.xml
new file mode 100644
index 0000000..94540bb
--- /dev/null
+++ b/tests/tests/draganddrop/AndroidManifest.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="android.dnd.cts">
+
+    <application>
+        <uses-library android:name="android.test.runner"/>
+    </application>
+
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="android.dnd.cts"/>
+
+</manifest>
\ No newline at end of file
diff --git a/tests/tests/draganddrop/AndroidTest.xml b/tests/tests/draganddrop/AndroidTest.xml
new file mode 100644
index 0000000..ef2f491
--- /dev/null
+++ b/tests/tests/draganddrop/AndroidTest.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<configuration description="Config for the CTS Drag and Drop tests">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsDragSourceApp.apk" />
+        <option name="test-file-name" value="CtsDropTargetApp.apk" />
+        <option name="test-file-name" value="CtsDragAndDropTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.dnd.cts" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/tests/draganddrop/dragsource/Android.mk b/tests/tests/draganddrop/dragsource/Android.mk
new file mode 100644
index 0000000..066759d
--- /dev/null
+++ b/tests/tests/draganddrop/dragsource/Android.mk
@@ -0,0 +1,37 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+# Don't include this package in any target
+LOCAL_MODULE_TAGS := tests
+# When built, explicitly put it in the data partition.
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_DEX_PREOPT := false
+
+LOCAL_PROGUARD_ENABLED := disabled
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_PACKAGE_NAME := CtsDragSourceApp
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_PACKAGE)
\ No newline at end of file
diff --git a/tests/tests/draganddrop/dragsource/AndroidManifest.xml b/tests/tests/draganddrop/dragsource/AndroidManifest.xml
new file mode 100644
index 0000000..d7c9011
--- /dev/null
+++ b/tests/tests/draganddrop/dragsource/AndroidManifest.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="android.dnd.cts.dragsource">
+    <application android:label="DragSource">
+        <activity android:name="android.dnd.cts.dragsource.DragSource">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.intent.category.LAUNCHER"/>
+            </intent-filter>
+        </activity>
+        <provider android:name=".DragSourceContentProvider"
+                  android:authorities="android.dnd.cts.dragsource.contentprovider"
+                  android:grantUriPermissions="true"/>
+    </application>
+</manifest>
diff --git a/tests/tests/draganddrop/dragsource/res/layout/main_activity.xml b/tests/tests/draganddrop/dragsource/res/layout/main_activity.xml
new file mode 100644
index 0000000..cac6a082
--- /dev/null
+++ b/tests/tests/draganddrop/dragsource/res/layout/main_activity.xml
@@ -0,0 +1,111 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<LinearLayout
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:orientation="vertical">
+
+    <TextView
+            android:id="@+id/dont_grant"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="center"
+            android:layout_margin="@dimen/item_margin"
+            android:padding="@dimen/item_padding"
+            android:background="#ddd"
+            android:text="@string/dont_grant_label">
+    </TextView>
+
+    <TextView
+            android:id="@+id/grant_read"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="center"
+            android:layout_margin="@dimen/item_margin"
+            android:padding="@dimen/item_padding"
+            android:background="#ddd"
+            android:text="@string/grant_read_label">
+    </TextView>
+
+    <TextView
+            android:id="@+id/grant_write"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="center"
+            android:layout_margin="@dimen/item_margin"
+            android:padding="@dimen/item_padding"
+            android:background="#ddd"
+            android:text="@string/grant_write_label">
+    </TextView>
+
+    <TextView
+            android:id="@+id/grant_read_prefix"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="center"
+            android:layout_margin="@dimen/item_margin"
+            android:padding="@dimen/item_padding"
+            android:background="#ddd"
+            android:text="@string/grant_read_prefix_label">
+    </TextView>
+
+    <TextView
+            android:id="@+id/grant_read_noprefix"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="center"
+            android:layout_margin="@dimen/item_margin"
+            android:padding="@dimen/item_padding"
+            android:background="#ddd"
+            android:text="@string/grant_read_noprefix_label">
+    </TextView>
+
+    <TextView
+            android:id="@+id/grant_read_persistable"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="center"
+            android:layout_margin="@dimen/item_margin"
+            android:padding="@dimen/item_padding"
+            android:background="#ddd"
+            android:text="@string/grant_read_persistable_label">
+    </TextView>
+
+    <TextView
+            android:id="@+id/disallow_global"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="center"
+            android:layout_margin="@dimen/item_margin"
+            android:padding="@dimen/item_padding"
+            android:background="#aaa"
+            android:text="@string/disallow_global_label">
+    </TextView>
+
+    <TextView
+            android:id="@+id/cancel_soon"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="center"
+            android:layout_margin="@dimen/item_margin"
+            android:padding="@dimen/item_padding"
+            android:background="#aaa"
+            android:text="@string/cancel_soon_label">
+    </TextView>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/tests/tests/draganddrop/dragsource/res/values/dimen.xml b/tests/tests/draganddrop/dragsource/res/values/dimen.xml
new file mode 100644
index 0000000..4923a32
--- /dev/null
+++ b/tests/tests/draganddrop/dragsource/res/values/dimen.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+    <dimen name="item_margin">6dp</dimen>
+    <dimen name="item_padding">6dp</dimen>
+</resources>
diff --git a/tests/tests/draganddrop/dragsource/res/values/strings.xml b/tests/tests/draganddrop/dragsource/res/values/strings.xml
new file mode 100644
index 0000000..28cd792
--- /dev/null
+++ b/tests/tests/draganddrop/dragsource/res/values/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+
+     <string name="dont_grant_label">Do not grant permissions</string>
+     <string name="disallow_global_label">Disallow global drag</string>
+     <string name="cancel_soon_label">Cancel soon after start</string>
+     <string name="grant_read_label">Grant read permissions</string>
+     <string name="grant_write_label">Grant write permissions</string>
+     <string name="grant_read_prefix_label">Grant read+prefix permissions</string>
+     <string name="grant_read_noprefix_label">Grant read, no prefix permissions</string>
+     <string name="grant_read_persistable_label">Grant read+persistable</string>
+
+</resources>
diff --git a/tests/tests/draganddrop/dragsource/src/android/dnd/cts/dragsource/DragSource.java b/tests/tests/draganddrop/dragsource/src/android/dnd/cts/dragsource/DragSource.java
new file mode 100644
index 0000000..bbba70d
--- /dev/null
+++ b/tests/tests/draganddrop/dragsource/src/android/dnd/cts/dragsource/DragSource.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.dnd.cts.dragsource;
+
+import android.app.Activity;
+import android.content.ClipData;
+import android.content.ClipDescription;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.PersistableBundle;
+import android.view.View;
+
+public class DragSource extends Activity{
+    private static final String URI_PREFIX =
+            "content://" + DragSourceContentProvider.AUTHORITY + "/data";
+
+    private static final String MAGIC_VALUE = "42";
+    public static final long TIMEOUT_CANCEL = 150;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        View view = getLayoutInflater().inflate(R.layout.main_activity, null);
+        setContentView(view);
+
+        final Uri plainUri = Uri.parse(URI_PREFIX + "/" + MAGIC_VALUE);
+
+        setUpDragSource(R.id.disallow_global, plainUri, 0);
+        setUpDragSource(R.id.cancel_soon, plainUri, View.DRAG_FLAG_GLOBAL);
+
+        setUpDragSource(R.id.dont_grant, plainUri, View.DRAG_FLAG_GLOBAL);
+        setUpDragSource(R.id.grant_read, plainUri,
+                View.DRAG_FLAG_GLOBAL | View.DRAG_FLAG_GLOBAL_URI_READ);
+        setUpDragSource(R.id.grant_write, plainUri,
+                View.DRAG_FLAG_GLOBAL | View.DRAG_FLAG_GLOBAL_URI_WRITE);
+        setUpDragSource(R.id.grant_read_persistable, plainUri,
+                View.DRAG_FLAG_GLOBAL | View.DRAG_FLAG_GLOBAL_URI_READ |
+                        View.DRAG_FLAG_GLOBAL_PERSISTABLE_URI_PERMISSION);
+
+        final Uri prefixUri = Uri.parse(URI_PREFIX);
+
+        setUpDragSource(R.id.grant_read_prefix, prefixUri,
+                View.DRAG_FLAG_GLOBAL | View.DRAG_FLAG_GLOBAL_URI_READ |
+                        View.DRAG_FLAG_GLOBAL_PREFIX_URI_PERMISSION);
+        setUpDragSource(R.id.grant_read_noprefix, prefixUri,
+                View.DRAG_FLAG_GLOBAL | View.DRAG_FLAG_GLOBAL_URI_READ);
+
+    }
+
+    private void setUpDragSource(final int resourceId, final Uri uri, final int flags) {
+        findViewById(resourceId).setOnLongClickListener(new View.OnLongClickListener() {
+            @Override
+            public boolean onLongClick(final View v) {
+                final ClipDescription clipDescription = new ClipDescription("", new String[] {
+                        ClipDescription.MIMETYPE_TEXT_URILIST });
+                PersistableBundle extras = new PersistableBundle(1);
+                extras.putString("extraKey", "extraValue");
+                clipDescription.setExtras(extras);
+                final ClipData clipData = new ClipData(clipDescription, new ClipData.Item(uri));
+                v.startDragAndDrop(
+                        clipData,
+                        new View.DragShadowBuilder(v),
+                        null,
+                        flags);
+                if (resourceId == R.id.cancel_soon) {
+                    new Handler().postDelayed(new Runnable() {
+                        @Override
+                        public void run() {
+                            v.cancelDragAndDrop();
+                        }
+                    }, TIMEOUT_CANCEL);
+                }
+                return false;
+            }
+        });
+    }
+}
diff --git a/tests/tests/draganddrop/dragsource/src/android/dnd/cts/dragsource/DragSourceContentProvider.java b/tests/tests/draganddrop/dragsource/src/android/dnd/cts/dragsource/DragSourceContentProvider.java
new file mode 100644
index 0000000..5b93832
--- /dev/null
+++ b/tests/tests/draganddrop/dragsource/src/android/dnd/cts/dragsource/DragSourceContentProvider.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.dnd.cts.dragsource;
+
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.content.UriMatcher;
+import android.database.Cursor;
+import android.net.Uri;
+
+public class DragSourceContentProvider extends ContentProvider {
+
+    public static final String AUTHORITY = "android.dnd.cts.dragsource.contentprovider";
+
+    private static final UriMatcher sMatcher = new UriMatcher(UriMatcher.NO_MATCH);
+
+    private static final int URI_DATA = 1;
+
+    static {
+        sMatcher.addURI(AUTHORITY, "data/#", URI_DATA);
+    }
+
+    @Override
+    public boolean onCreate() {
+        return false;
+    }
+
+    @Override
+    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
+                        String sortOrder) {
+        switch (sMatcher.match(uri)) {
+            case URI_DATA:
+                return new DragSourceCursor(uri.getLastPathSegment());
+        }
+        return null;
+    }
+
+    @Override
+    public String getType(Uri uri) {
+        return null;
+    }
+
+    @Override
+    public Uri insert(Uri uri, ContentValues values) {
+        return null;
+    }
+
+    @Override
+    public int delete(Uri uri, String selection, String[] selectionArgs) {
+        return 0;
+    }
+
+    @Override
+    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+        return 0;
+    }
+}
diff --git a/tests/tests/draganddrop/dragsource/src/android/dnd/cts/dragsource/DragSourceCursor.java b/tests/tests/draganddrop/dragsource/src/android/dnd/cts/dragsource/DragSourceCursor.java
new file mode 100644
index 0000000..aa036fb
--- /dev/null
+++ b/tests/tests/draganddrop/dragsource/src/android/dnd/cts/dragsource/DragSourceCursor.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.dnd.cts.dragsource;
+
+import android.database.AbstractCursor;
+
+public class DragSourceCursor extends AbstractCursor {
+    private static final String COLUMN_KEY = "key";
+
+    private final String mValue;
+
+    public DragSourceCursor(String value) {
+        mValue = value;
+    }
+
+    @Override
+    public int getCount() {
+        return 1;
+    }
+
+    @Override
+    public String[] getColumnNames() {
+        return new String[] {COLUMN_KEY};
+    }
+
+    @Override
+    public String getString(int column) {
+        if (getPosition() != 0) {
+            throw new IllegalArgumentException("Incorrect position: " + getPosition());
+        }
+        if (column != 0) {
+            throw new IllegalArgumentException("Incorrect column: " + column);
+        }
+        return mValue;
+    }
+
+    @Override
+    public short getShort(int column) {
+        return 0;
+    }
+
+    @Override
+    public int getInt(int column) {
+        return 0;
+    }
+
+    @Override
+    public long getLong(int column) {
+        return 0;
+    }
+
+    @Override
+    public float getFloat(int column) {
+        return 0;
+    }
+
+    @Override
+    public double getDouble(int column) {
+        return 0;
+    }
+
+    @Override
+    public boolean isNull(int column) {
+        return false;
+    }
+}
diff --git a/tests/tests/draganddrop/droptarget/Android.mk b/tests/tests/draganddrop/droptarget/Android.mk
new file mode 100644
index 0000000..a729f71
--- /dev/null
+++ b/tests/tests/draganddrop/droptarget/Android.mk
@@ -0,0 +1,37 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+# Don't include this package in any target
+LOCAL_MODULE_TAGS := tests
+# When built, explicitly put it in the data partition.
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_DEX_PREOPT := false
+
+LOCAL_PROGUARD_ENABLED := disabled
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_PACKAGE_NAME := CtsDropTargetApp
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_PACKAGE)
\ No newline at end of file
diff --git a/tests/tests/draganddrop/droptarget/AndroidManifest.xml b/tests/tests/draganddrop/droptarget/AndroidManifest.xml
new file mode 100644
index 0000000..83d7005
--- /dev/null
+++ b/tests/tests/draganddrop/droptarget/AndroidManifest.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="android.dnd.cts.droptarget">
+    <application android:label="DropTarget">
+        <activity android:name="android.dnd.cts.droptarget.DropTarget">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.intent.category.LAUNCHER"/>
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
diff --git a/tests/tests/draganddrop/droptarget/res/layout/main_activity.xml b/tests/tests/draganddrop/droptarget/res/layout/main_activity.xml
new file mode 100644
index 0000000..4a5a5b1
--- /dev/null
+++ b/tests/tests/draganddrop/droptarget/res/layout/main_activity.xml
@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<LinearLayout
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:orientation="vertical">
+
+    <TextView
+            android:id="@+id/dont_request"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="center"
+            android:layout_margin="@dimen/item_margin"
+            android:padding="@dimen/item_padding"
+            android:background="#ddd"
+            android:text="@string/dont_request_label">
+    </TextView>
+
+    <TextView
+        android:id="@+id/request_read"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:gravity="center"
+        android:layout_margin="@dimen/item_margin"
+        android:padding="@dimen/item_padding"
+        android:background="#ddd"
+        android:text="@string/request_read_label">
+    </TextView>
+
+    <TextView
+        android:id="@+id/request_write"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:gravity="center"
+        android:layout_margin="@dimen/item_margin"
+        android:padding="@dimen/item_padding"
+        android:background="#ddd"
+        android:text="@string/request_write_label">
+    </TextView>
+
+    <TextView
+        android:id="@+id/request_read_nested"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:gravity="center"
+        android:layout_margin="@dimen/item_margin"
+        android:padding="@dimen/item_padding"
+        android:background="#ddd"
+        android:text="@string/request_read_nested_label">
+    </TextView>
+
+    <TextView
+        android:id="@+id/request_take_persistable"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:gravity="center"
+        android:layout_margin="@dimen/item_margin"
+        android:padding="@dimen/item_padding"
+        android:background="#ddd"
+        android:text="@string/request_take_persistable_label">
+    </TextView>
+
+    <TextView
+            android:id="@+id/result"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginLeft="10dp"
+            android:text="@string/not_available_label">
+    </TextView>
+
+    <TextView
+            android:id="@+id/drag_started"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginLeft="10dp"
+            android:text="@string/not_available_label">
+    </TextView>
+
+    <TextView
+            android:id="@+id/extra_value"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginLeft="10dp"
+            android:text="@string/not_available_label">
+    </TextView>
+
+    <TextView
+            android:id="@+id/details"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginLeft="10dp">
+    </TextView>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/tests/tests/draganddrop/droptarget/res/values/dimen.xml b/tests/tests/draganddrop/droptarget/res/values/dimen.xml
new file mode 100644
index 0000000..4923a32
--- /dev/null
+++ b/tests/tests/draganddrop/droptarget/res/values/dimen.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+    <dimen name="item_margin">6dp</dimen>
+    <dimen name="item_padding">6dp</dimen>
+</resources>
diff --git a/tests/tests/draganddrop/droptarget/res/values/strings.xml b/tests/tests/draganddrop/droptarget/res/values/strings.xml
new file mode 100644
index 0000000..9fa4619
--- /dev/null
+++ b/tests/tests/draganddrop/droptarget/res/values/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+
+     <string name="dont_request_label">Do not request permissions, read</string>
+     <string name="request_read_label">Request permissions, read</string>
+     <string name="request_write_label">Request permissions, write</string>
+     <string name="request_read_nested_label">Request permissions, read nested</string>
+     <string name="request_take_persistable_label">Request permissions, take persistable</string>
+     <string name="not_available_label">N/A</string>
+
+</resources>
diff --git a/tests/tests/draganddrop/droptarget/src/android/dnd/cts/droptarget/DropTarget.java b/tests/tests/draganddrop/droptarget/src/android/dnd/cts/droptarget/DropTarget.java
new file mode 100644
index 0000000..2be57d4
--- /dev/null
+++ b/tests/tests/draganddrop/droptarget/src/android/dnd/cts/droptarget/DropTarget.java
@@ -0,0 +1,228 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.dnd.cts.droptarget;
+
+import android.app.Activity;
+import android.content.ClipData;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.PersistableBundle;
+import android.view.DragEvent;
+import android.view.DropPermissions;
+import android.view.View;
+import android.widget.TextView;
+
+public class DropTarget extends Activity {
+
+    private static final String MAGIC_VALUE = "42";
+    public static final String RESULT_OK = "OK";
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        View view = getLayoutInflater().inflate(R.layout.main_activity, null);
+        setContentView(view);
+
+        setUpDropTarget(R.id.dont_request, new OnDragUriReadListener(false));
+        setUpDropTarget(R.id.request_read, new OnDragUriReadListener());
+        setUpDropTarget(R.id.request_write, new OnDragUriWriteListener());
+        setUpDropTarget(R.id.request_read_nested, new OnDragUriReadPrefixListener());
+        setUpDropTarget(R.id.request_take_persistable, new OnDragUriTakePersistableListener());
+    }
+
+    private void setUpDropTarget(final int targetResourceId, OnDragUriListener listener) {
+        findViewById(targetResourceId).setOnDragListener(listener);
+    }
+
+    private String checkExtraValue(DragEvent event) {
+        PersistableBundle extras = event.getClipDescription().getExtras();
+        if (extras == null) {
+            return "Null";
+        }
+
+        final String value = extras.getString("extraKey");
+        if ("extraValue".equals(value)) {
+            return RESULT_OK;
+        }
+        return value;
+    }
+
+    private abstract class OnDragUriListener implements View.OnDragListener {
+        private final boolean requestPermissions;
+
+        public OnDragUriListener(boolean requestPermissions) {
+            this.requestPermissions = requestPermissions;
+        }
+
+        @Override
+        public boolean onDrag(View v, DragEvent event) {
+            switch (event.getAction()) {
+                case DragEvent.ACTION_DRAG_STARTED:
+                    ((TextView) findViewById(R.id.drag_started)).setText("DRAG_STARTED");
+                    ((TextView) findViewById(R.id.extra_value)).setText(checkExtraValue(event));
+                    return true;
+
+                case DragEvent.ACTION_DRAG_ENTERED:
+                    return true;
+
+                case DragEvent.ACTION_DRAG_LOCATION:
+                    return true;
+
+                case DragEvent.ACTION_DRAG_EXITED:
+                    return true;
+
+                case DragEvent.ACTION_DROP:
+                    String result;
+                    try {
+                        result = processDrop(event, requestPermissions);
+                    } catch (Exception e) {
+                        result = "Exception";
+                        ((TextView) findViewById(R.id.details)).setText(e.getMessage());
+                    }
+                    ((TextView) findViewById(R.id.result)).setText(result);
+                    return true;
+
+                case DragEvent.ACTION_DRAG_ENDED:
+                    return true;
+
+                default:
+                    return false;
+            }
+        }
+
+        private String processDrop(DragEvent event, boolean requestPermissions) {
+            final ClipData clipData = event.getClipData();
+            if (clipData == null) {
+                return "Null ClipData";
+            }
+            if (clipData.getItemCount() == 0) {
+                return "Empty ClipData";
+            }
+            ClipData.Item item = clipData.getItemAt(0);
+            if (item == null) {
+                return "Null ClipData.Item";
+            }
+            Uri uri = item.getUri();
+            if (uri == null) {
+                return "Null Uri";
+            }
+
+            DropPermissions dp = null;
+            if (requestPermissions) {
+                dp = requestDropPermissions(event);
+                if (dp == null) {
+                    return "Null DropPermissions";
+                }
+            }
+
+            try {
+                return processUri(uri);
+            } finally {
+                if (dp != null) {
+                    dp.release();
+                }
+            }
+        }
+
+        abstract protected String processUri(Uri uri);
+    }
+
+    private class OnDragUriReadListener extends OnDragUriListener {
+        public OnDragUriReadListener(boolean requestPermissions) {
+            super(requestPermissions);
+        }
+
+        public OnDragUriReadListener() {
+            super(true);
+        }
+
+        protected String processUri(Uri uri) {
+            return checkQueryResult(uri, MAGIC_VALUE);
+        }
+
+        protected String checkQueryResult(Uri uri, String expectedValue) {
+            Cursor cursor = null;
+            try {
+                cursor = getContentResolver().query(uri, null, null, null, null);
+                if (cursor == null) {
+                    return "Null Cursor";
+                }
+                cursor.moveToPosition(0);
+                String value = cursor.getString(0);
+                if (!expectedValue.equals(value)) {
+                    return "Wrong value: " + value;
+                }
+                return RESULT_OK;
+            } finally {
+                if (cursor != null) {
+                    cursor.close();
+                }
+            }
+        }
+    }
+
+    private class OnDragUriWriteListener extends OnDragUriListener {
+        public OnDragUriWriteListener() {
+            super(true);
+        }
+
+        protected String processUri(Uri uri) {
+            ContentValues values = new ContentValues();
+            values.put("key", 100);
+            getContentResolver().update(uri, values, null, null);
+            return RESULT_OK;
+        }
+    }
+
+    private class OnDragUriReadPrefixListener extends OnDragUriReadListener {
+        @Override
+        protected String processUri(Uri uri) {
+            final String result1 = queryPrefixed(uri, "1");
+            if (!result1.equals(RESULT_OK)) {
+                return result1;
+            }
+            final String result2 = queryPrefixed(uri, "2");
+            if (!result2.equals(RESULT_OK)) {
+                return result2;
+            }
+            return queryPrefixed(uri, "3");
+        }
+
+        private String queryPrefixed(Uri uri, String selector) {
+            final Uri prefixedUri = Uri.parse(uri.toString() + "/" + selector);
+            return checkQueryResult(prefixedUri, selector);
+        }
+    }
+
+    private class OnDragUriTakePersistableListener extends OnDragUriListener {
+        public OnDragUriTakePersistableListener() {
+            super(true);
+        }
+
+        @Override
+        protected String processUri(Uri uri) {
+            getContentResolver().takePersistableUriPermission(
+                    uri, View.DRAG_FLAG_GLOBAL_URI_READ);
+            getContentResolver().releasePersistableUriPermission(
+                    uri, View.DRAG_FLAG_GLOBAL_URI_READ);
+            return RESULT_OK;
+        }
+    }
+}
diff --git a/tests/tests/draganddrop/src/android/dnd/cts/DragAndDropTest.java b/tests/tests/draganddrop/src/android/dnd/cts/DragAndDropTest.java
new file mode 100644
index 0000000..5519581
--- /dev/null
+++ b/tests/tests/draganddrop/src/android/dnd/cts/DragAndDropTest.java
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.dnd.cts;
+
+import android.app.ActivityOptions;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Point;
+import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.UiDevice;
+import android.support.test.uiautomator.UiObject2;
+import android.support.test.uiautomator.Until;
+import android.test.InstrumentationTestCase;
+
+import java.lang.reflect.Method;
+import java.util.concurrent.TimeoutException;
+
+public class DragAndDropTest extends InstrumentationTestCase {
+
+    private static final String DRAG_SOURCE_PKG = "android.dnd.cts.dragsource";
+    private static final String DROP_TARGET_PKG = "android.dnd.cts.droptarget";
+
+    private static final int TIMEOUT = 5000;
+
+    // Constants copied from ActivityManager.StackId. If they are changed there, these must be
+    // updated.
+    public static final int FREEFORM_WORKSPACE_STACK_ID = 1;
+    public static final int DOCKED_STACK_ID = 3;
+
+    private UiDevice mDevice;
+
+    public void setUp() throws TimeoutException {
+        mDevice = UiDevice.getInstance(getInstrumentation());
+    }
+
+    /** ActivityOptions#setLaunchStackId is a @hidden API so we access it through reflection. */
+    private static void setLaunchStackId(ActivityOptions options, int stackId) throws Exception {
+        final Method method = options.getClass().getDeclaredMethod("setLaunchStackId", int.class);
+
+        method.setAccessible(true);
+        method.invoke(options, stackId);
+    }
+
+    private void startAppInStack(String packageName, int stackId) {
+        Context context = getInstrumentation().getContext();
+        Intent intent = context.getPackageManager().getLaunchIntentForPackage(packageName);
+        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
+
+        ActivityOptions options = ActivityOptions.makeBasic();
+        try {
+            setLaunchStackId(options, stackId);
+        } catch (Exception e) {
+            fail(e.getMessage());
+        }
+        context.startActivity(intent, options.toBundle());
+
+        // Wait for the app to appear
+        mDevice.wait(Until.hasObject(By.pkg(packageName).depth(0)), TIMEOUT);
+    }
+
+    private Point getVisibleCenter(String packageName, String sourceViewId) {
+        return findObject(packageName, sourceViewId).getVisibleCenter();
+    }
+
+    private UiObject2 findObject(String packageName, String id) {
+        return mDevice.findObject(By.res(packageName, id));
+    }
+
+    private void drag(Point srcPosition, Point tgtPosition) {
+        mDevice.drag(srcPosition.x, srcPosition.y, tgtPosition.x, tgtPosition.y, 100);
+    }
+
+    private void doCrossAppDrag(String sourceViewId, String targetViewId, String expectedResult) {
+        startAppInStack(DRAG_SOURCE_PKG, DOCKED_STACK_ID);
+        Point srcPosition = getVisibleCenter(DRAG_SOURCE_PKG, sourceViewId);
+
+        startAppInStack(DROP_TARGET_PKG, FREEFORM_WORKSPACE_STACK_ID);
+        Point tgtPosition = getVisibleCenter(DROP_TARGET_PKG, targetViewId);
+
+        drag(srcPosition, tgtPosition);
+
+        // If we don't do that the next 'findObject' often fails.
+        mDevice.click(tgtPosition.x, tgtPosition.y);
+
+        UiObject2 result = findObject(DROP_TARGET_PKG, "result");
+        assertNotNull("Result widget not found", result);
+        assertEquals(expectedResult, result.getText());
+    }
+
+    private void assertDragStarted(String expectedResult) {
+        UiObject2 drag_started = findObject(DROP_TARGET_PKG, "drag_started");
+        assertEquals(expectedResult, drag_started.getText());
+    }
+
+    private void assertExtraValue(String expectedResult) {
+        UiObject2 extra_value = findObject(DROP_TARGET_PKG, "extra_value");
+        assertEquals(expectedResult, extra_value.getText());
+    }
+
+    public void testLocal() {
+        doCrossAppDrag("disallow_global", "dont_request", "N/A");
+        assertDragStarted("N/A");
+        assertExtraValue("N/A");
+    }
+
+    public void testCancel() {
+        doCrossAppDrag("cancel_soon", "dont_request", "N/A");
+        assertDragStarted("DRAG_STARTED");
+        assertExtraValue("OK");
+    }
+
+    public void testDontGrantDontRequest() {
+        doCrossAppDrag("dont_grant", "dont_request", "Exception");
+        assertDragStarted("DRAG_STARTED");
+        assertExtraValue("OK");
+    }
+
+    public void testDontGrantRequestRead() {
+        doCrossAppDrag("dont_grant", "request_read", "Null DropPermissions");
+    }
+
+    public void testDontGrantRequestWrite() {
+        doCrossAppDrag("dont_grant", "request_write", "Null DropPermissions");
+    }
+
+    public void testGrantReadDontRequest() {
+        doCrossAppDrag("grant_read", "dont_request", "Exception");
+    }
+
+    public void testGrantReadRequestRead() {
+        doCrossAppDrag("grant_read", "request_read", "OK");
+    }
+
+    public void testGrantReadRequestWrite() {
+        doCrossAppDrag("grant_read", "request_write", "Exception");
+    }
+
+    public void testGrantWriteDontRequest() {
+        doCrossAppDrag("grant_write", "dont_request", "Exception");
+    }
+
+    public void testGrantWriteRequestRead() {
+        doCrossAppDrag("grant_write", "request_read", "Exception");
+    }
+
+    public void testGrantWriteRequestWrite() {
+        doCrossAppDrag("grant_write", "request_write", "OK");
+    }
+
+    public void testGrantReadPrefixRequestReadNested() {
+        doCrossAppDrag("grant_read_prefix", "request_read_nested", "OK");
+    }
+
+    public void testGrantReadNoPrefixRequestReadNested() {
+        doCrossAppDrag("grant_read_noprefix", "request_read_nested", "Exception");
+    }
+
+    public void testGrantPersistableRequestTakePersistable() {
+        doCrossAppDrag("grant_read_persistable", "request_take_persistable", "OK");
+    }
+
+    public void testGrantReadRequestTakePersistable() {
+        doCrossAppDrag("grant_read", "request_take_persistable", "Exception");
+    }
+}
diff --git a/tests/tests/dreams/Android.mk b/tests/tests/dreams/Android.mk
index 87bd357..b268e37 100644
--- a/tests/tests/dreams/Android.mk
+++ b/tests/tests/dreams/Android.mk
@@ -33,4 +33,7 @@
 # Need access to ServiceManager - see b/13307221
 #LOCAL_SDK_VERSION := current
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/dreams/AndroidManifest.xml b/tests/tests/dreams/AndroidManifest.xml
index b395a4f..8f1d75e 100644
--- a/tests/tests/dreams/AndroidManifest.xml
+++ b/tests/tests/dreams/AndroidManifest.xml
@@ -14,7 +14,7 @@
      limitations under the License.
 -->
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.dreams">
+    package="android.dreams.cts">
 
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <application>
@@ -23,7 +23,7 @@
 
     <!-- This is a self-instrumenting test package. -->
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.cts.dreams"
+                     android:targetPackage="android.dreams.cts"
                      android:label="CTS tests for the android.service.dreams package">
         <meta-data android:name="listener"
             android:value="com.android.cts.runner.CtsTestRunListener" />
diff --git a/tests/tests/dreams/AndroidTest.xml b/tests/tests/dreams/AndroidTest.xml
new file mode 100644
index 0000000..b334ade
--- /dev/null
+++ b/tests/tests/dreams/AndroidTest.xml
@@ -0,0 +1,23 @@
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS Dreams test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsDreamsTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.dreams.cts" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/tests/drm/Android.mk b/tests/tests/drm/Android.mk
index 6272e9c..02567be 100644
--- a/tests/tests/drm/Android.mk
+++ b/tests/tests/drm/Android.mk
@@ -28,6 +28,9 @@
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_PACKAGE_NAME := CtsDrmTestCases
 
 LOCAL_JNI_SHARED_LIBRARIES := \
diff --git a/tests/tests/drm/AndroidManifest.xml b/tests/tests/drm/AndroidManifest.xml
index 527d498..c4ea03d 100644
--- a/tests/tests/drm/AndroidManifest.xml
+++ b/tests/tests/drm/AndroidManifest.xml
@@ -14,8 +14,7 @@
      limitations under the License.
 -->
 
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.drm">
+<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android.drm.cts">
 
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <application>
@@ -23,11 +22,10 @@
     </application>
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.cts.drm"
+                     android:targetPackage="android.drm.cts"
                      android:label="CTS tests of android.drm">
         <meta-data android:name="listener"
             android:value="com.android.cts.runner.CtsTestRunListener" />
     </instrumentation>
 
 </manifest>
-
diff --git a/tests/tests/drm/AndroidTest.xml b/tests/tests/drm/AndroidTest.xml
new file mode 100644
index 0000000..48287aa
--- /dev/null
+++ b/tests/tests/drm/AndroidTest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS DRM test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsDrmTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.drm.cts" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/tests/drm/jni/Android.mk b/tests/tests/drm/jni/Android.mk
index 06b2df9..87f00a4 100644
--- a/tests/tests/drm/jni/Android.mk
+++ b/tests/tests/drm/jni/Android.mk
@@ -28,5 +28,6 @@
 LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
 
 LOCAL_SHARED_LIBRARIES := liblog libdl
+LOCAL_SDK_VERSION := 23
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/tests/tests/drm/jni/android_drm_cts_NativeCodeTest.cpp b/tests/tests/drm/jni/android_drm_cts_NativeCodeTest.cpp
index e5c9f960..9fe4bb2 100644
--- a/tests/tests/drm/jni/android_drm_cts_NativeCodeTest.cpp
+++ b/tests/tests/drm/jni/android_drm_cts_NativeCodeTest.cpp
@@ -15,11 +15,11 @@
  */
 
 #include <jni.h>
-#include <sys/types.h>
+#include <stdio.h>
 #include <string.h>
-#include <unistd.h>
 #include <sys/syscall.h>
-#include <utils/Log.h>
+#include <sys/types.h>
+#include <unistd.h>
 
 /*
  * Returns true iff this device may be vulnerable to installation of rogue drm
diff --git a/tests/tests/drm/lib/Android.mk b/tests/tests/drm/lib/Android.mk
index 3ebc4a0..a061abd 100644
--- a/tests/tests/drm/lib/Android.mk
+++ b/tests/tests/drm/lib/Android.mk
@@ -16,6 +16,9 @@
 
 include $(CLEAR_VARS)
 
+LOCAL_CFLAGS := $(libc_common_cflags) \
+    -Wno-unused-parameter \
+
 LOCAL_MODULE := libdrmtestplugin
 
 LOCAL_MODULE_TAGS := tests
diff --git a/tests/tests/effect/Android.mk b/tests/tests/effect/Android.mk
index 6a9778e..c347152 100644
--- a/tests/tests/effect/Android.mk
+++ b/tests/tests/effect/Android.mk
@@ -28,6 +28,9 @@
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_SDK_VERSION := current
 
 include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/effect/AndroidManifest.xml b/tests/tests/effect/AndroidManifest.xml
index 481be14..81f3bbf 100644
--- a/tests/tests/effect/AndroidManifest.xml
+++ b/tests/tests/effect/AndroidManifest.xml
@@ -14,8 +14,7 @@
      limitations under the License.
 -->
 
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.effect">
+<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android.effect.cts">
 
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <application>
@@ -24,7 +23,7 @@
 
     <!-- This is a self-instrumenting test package. -->
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.cts.effect"
+                     android:targetPackage="android.effect.cts"
                      android:label="CTS tests of android.media.effect component">
         <meta-data android:name="listener"
             android:value="com.android.cts.runner.CtsTestRunListener" />
diff --git a/tests/tests/effect/AndroidTest.xml b/tests/tests/effect/AndroidTest.xml
new file mode 100644
index 0000000..abf2b22
--- /dev/null
+++ b/tests/tests/effect/AndroidTest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS Effect test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsEffectTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.effect.cts" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/tests/externalservice/Android.mk b/tests/tests/externalservice/Android.mk
new file mode 100644
index 0000000..c438dd6
--- /dev/null
+++ b/tests/tests/externalservice/Android.mk
@@ -0,0 +1,42 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+# Don't include this package in any target
+LOCAL_MODULE_TAGS := tests
+# When built, explicitly put it in the data partition.
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_DEX_PREOPT := false
+
+LOCAL_PROGUARD_ENABLED := disabled
+
+LOCAL_STATIC_JAVA_LIBRARIES := CtsExternalServiceCommon ctsdeviceutil ctstestrunner
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_CTS_MODULE_CONFIG := $(LOCAL_PATH)/Old$(CTS_MODULE_TEST_CONFIG)
+
+LOCAL_PACKAGE_NAME := CtsExternalServiceTestCases
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_PACKAGE)
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/tests/externalservice/AndroidManifest.xml b/tests/tests/externalservice/AndroidManifest.xml
new file mode 100644
index 0000000..0c5ea5d
--- /dev/null
+++ b/tests/tests/externalservice/AndroidManifest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.externalservice.cts">
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation
+        android:name="android.support.test.runner.AndroidJUnitRunner"
+        android:label="CTS external service tests"
+        android:targetPackage="android.externalservice.cts" >
+    </instrumentation>
+</manifest>
+
diff --git a/tests/tests/externalservice/AndroidTest.xml b/tests/tests/externalservice/AndroidTest.xml
new file mode 100644
index 0000000..b07f248
--- /dev/null
+++ b/tests/tests/externalservice/AndroidTest.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS External Service test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsExternalServiceService.apk" />
+        <option name="test-file-name" value="CtsExternalServiceTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.externalservice.cts" />
+    </test>
+</configuration>
diff --git a/tests/tests/externalservice/OldAndroidTest.xml b/tests/tests/externalservice/OldAndroidTest.xml
new file mode 100644
index 0000000..838db60
--- /dev/null
+++ b/tests/tests/externalservice/OldAndroidTest.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS External Service test cases">
+    <include name="common-config" />
+    <option name="cts-apk-installer:test-file-name" value="CtsExternalServiceService.apk" />
+    <option name="cts-apk-installer:test-file-name" value="CtsExternalServiceTestCases.apk" />
+</configuration>
diff --git a/tests/tests/externalservice/common/Android.mk b/tests/tests/externalservice/common/Android.mk
new file mode 100644
index 0000000..1ebf149
--- /dev/null
+++ b/tests/tests/externalservice/common/Android.mk
@@ -0,0 +1,30 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+# don't include this package in any target
+LOCAL_MODULE_TAGS := optional
+# and when built explicitly put it in the data partition
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_MODULE := CtsExternalServiceCommon
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/tests/tests/externalservice/common/src/android/externalservice/common/ServiceMessages.java b/tests/tests/externalservice/common/src/android/externalservice/common/ServiceMessages.java
new file mode 100644
index 0000000..8d23bc0
--- /dev/null
+++ b/tests/tests/externalservice/common/src/android/externalservice/common/ServiceMessages.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.externalservice.common;
+
+import android.os.IBinder;
+
+public class ServiceMessages {
+    // No arguments. Gets the UID and PID of the service.
+    public static final int MSG_IDENTIFY = IBinder.FIRST_CALL_TRANSACTION + 1;
+    // Response to MSG_IDENTIFY. arg1 is the UID, arg2 is the PID.
+    public static final int MSG_IDENTIFY_RESPONSE = MSG_IDENTIFY + 100;
+
+    // Bundle key in MSG_IDENTIFY_RESPONSE containing the package name.
+    public static final String IDENTIFY_PACKAGE = "packageName";
+
+    // No arguments. Starts an external service.
+    public static final int MSG_CREATE_EXTERNAL_SERVICE = IBinder.FIRST_CALL_TRANSACTION + 2;
+    // Responds to MSG_CREATE_EXTERNAL_SERVICE. obj is the IBinder on success, null on failure.
+    public static final int MSG_CREATE_EXTERNAL_SERVICE_RESPONSE =
+        MSG_CREATE_EXTERNAL_SERVICE + 100;
+
+    private ServiceMessages() {}
+}
diff --git a/tests/tests/externalservice/service/Android.mk b/tests/tests/externalservice/service/Android.mk
new file mode 100644
index 0000000..9541b0e
--- /dev/null
+++ b/tests/tests/externalservice/service/Android.mk
@@ -0,0 +1,35 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+# don't include this package in any target
+LOCAL_MODULE_TAGS := optional
+# and when built explicitly put it in the data partition
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_STATIC_JAVA_LIBRARIES := CtsExternalServiceCommon ctstestrunner ctsdeviceutil
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := CtsExternalServiceService
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/tests/tests/externalservice/service/AndroidManifest.xml b/tests/tests/externalservice/service/AndroidManifest.xml
new file mode 100644
index 0000000..06fa80e
--- /dev/null
+++ b/tests/tests/externalservice/service/AndroidManifest.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.externalservice.service">
+
+    <application android:label="External Service Host">
+        <!-- Service used to start .ExternalService from this package. -->
+        <service android:name=".ServiceCreator"
+                 android:isolatedProcess="false"
+                 android:externalService="false"
+                 android:exported="true" />
+
+        <!-- These services only respond to MSG_IDENTIFY for testing bindService(). -->
+        <service android:name=".IsolatedService"
+                 android:isolatedProcess="true"
+                 android:externalService="false"
+                 android:exported="false"/>
+        <service android:name=".ExportedService"
+                 android:isolatedProcess="true"
+                 android:externalService="false"
+                 android:exported="true"/>
+        <service android:name=".ExternalNonExportedService"
+                 android:isolatedProcess="true"
+                 android:externalService="true"
+                 android:exported="false"/>
+        <service android:name=".ExternalNonIsolatedService"
+                 android:isolatedProcess="false"
+                 android:externalService="true"
+                 android:exported="true"/>
+
+        <!-- The only valid, externalService entry. -->
+        <service android:name=".ExternalService"
+                 android:isolatedProcess="true"
+                 android:externalService="true"
+                 android:exported="true"/>
+    </application>
+
+</manifest>
diff --git a/tests/tests/externalservice/service/src/android/externalservice/service/BaseService.java b/tests/tests/externalservice/service/src/android/externalservice/service/BaseService.java
new file mode 100644
index 0000000..a14adbe
--- /dev/null
+++ b/tests/tests/externalservice/service/src/android/externalservice/service/BaseService.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.externalservice.service;
+
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.os.IBinder;
+import android.os.Handler;
+import android.os.Message;
+import android.os.Messenger;
+import android.os.Process;
+import android.os.RemoteException;
+import android.util.Log;
+
+import android.externalservice.common.ServiceMessages;
+
+public class BaseService extends Service {
+    private static final String TAG = "ExternalServiceTest.Service";
+
+    private final Handler mHandler = new BaseHandler(this);
+    private final Messenger mMessenger = new Messenger(mHandler);
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        Log.d(TAG, "onBind " + intent);
+        return mMessenger.getBinder();
+    }
+
+    static class BaseHandler extends Handler {
+        private Context mContext;
+
+        public BaseHandler(Context context) {
+            mContext = context;
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            Log.d(TAG, "Received message: " + msg);
+            switch (msg.what) {
+                case ServiceMessages.MSG_IDENTIFY:
+                    Message reply = Message.obtain(null, ServiceMessages.MSG_IDENTIFY_RESPONSE,
+                            Process.myUid(), Process.myPid());
+                    reply.getData().putString(ServiceMessages.IDENTIFY_PACKAGE,
+                            mContext.getPackageName());
+                    try {
+                        msg.replyTo.send(reply);
+                    } catch (RemoteException e) {
+                        Log.e(TAG, "Error sending MSG_IDENTIFY_RESPONSE", e);
+                    }
+                    break;
+            }
+            super.handleMessage(msg);
+        }
+    }
+}
diff --git a/tests/tests/externalservice/service/src/android/externalservice/service/ExportedService.java b/tests/tests/externalservice/service/src/android/externalservice/service/ExportedService.java
new file mode 100644
index 0000000..faee786
--- /dev/null
+++ b/tests/tests/externalservice/service/src/android/externalservice/service/ExportedService.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.externalservice.service;
+
+public class ExportedService extends BaseService {
+}
diff --git a/tests/tests/externalservice/service/src/android/externalservice/service/ExternalNonExportedService.java b/tests/tests/externalservice/service/src/android/externalservice/service/ExternalNonExportedService.java
new file mode 100644
index 0000000..91ab426
--- /dev/null
+++ b/tests/tests/externalservice/service/src/android/externalservice/service/ExternalNonExportedService.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.externalservice.service;
+
+public class ExternalNonExportedService extends BaseService {
+}
diff --git a/tests/tests/externalservice/service/src/android/externalservice/service/ExternalNonIsolatedService.java b/tests/tests/externalservice/service/src/android/externalservice/service/ExternalNonIsolatedService.java
new file mode 100644
index 0000000..c8f4a50
--- /dev/null
+++ b/tests/tests/externalservice/service/src/android/externalservice/service/ExternalNonIsolatedService.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.externalservice.service;
+
+public class ExternalNonIsolatedService extends BaseService {
+}
diff --git a/tests/tests/externalservice/service/src/android/externalservice/service/ExternalService.java b/tests/tests/externalservice/service/src/android/externalservice/service/ExternalService.java
new file mode 100644
index 0000000..50b475a
--- /dev/null
+++ b/tests/tests/externalservice/service/src/android/externalservice/service/ExternalService.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.externalservice.service;
+
+public class ExternalService extends BaseService {
+}
diff --git a/tests/tests/externalservice/service/src/android/externalservice/service/IsolatedService.java b/tests/tests/externalservice/service/src/android/externalservice/service/IsolatedService.java
new file mode 100644
index 0000000..94db76f
--- /dev/null
+++ b/tests/tests/externalservice/service/src/android/externalservice/service/IsolatedService.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.externalservice.service;
+
+public class IsolatedService extends BaseService {
+}
diff --git a/tests/tests/externalservice/service/src/android/externalservice/service/ServiceCreator.java b/tests/tests/externalservice/service/src/android/externalservice/service/ServiceCreator.java
new file mode 100644
index 0000000..3af5c98
--- /dev/null
+++ b/tests/tests/externalservice/service/src/android/externalservice/service/ServiceCreator.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.externalservice.service;
+
+import android.app.Service;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.Messenger;
+import android.os.Process;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.util.ArrayList;
+
+import android.externalservice.common.ServiceMessages;
+
+public class ServiceCreator extends Service {
+    private static final String TAG = "ExternalServiceTest.ServiceCreator";
+
+    private final ArrayList<CreatorConnection> mConnections = new ArrayList<>();
+
+    private final Handler mHandler = new BaseService.BaseHandler(this) {
+        @Override
+        public void handleMessage(Message msg) {
+            Log.d(TAG, "Received message: " + msg);
+            switch (msg.what) {
+                case ServiceMessages.MSG_CREATE_EXTERNAL_SERVICE:
+                    final Context context = ServiceCreator.this;
+                    final String pkgName = context.getPackageName();
+                    Intent intent = new Intent();
+                    intent.setComponent(new ComponentName(pkgName, pkgName+".ExternalService"));
+                    CreatorConnection conn = new CreatorConnection(msg.replyTo);
+                    boolean result = context.bindService(intent, conn,
+                            Context.BIND_AUTO_CREATE | Context.BIND_EXTERNAL_SERVICE);
+                    if (result) {
+                        mConnections.add(conn);
+                    } else {
+                        Message reply = Message.obtain();
+                        reply.what = ServiceMessages.MSG_CREATE_EXTERNAL_SERVICE_RESPONSE;
+                        try {
+                            msg.replyTo.send(reply);
+                        } catch (RemoteException e) {
+                            Log.e(TAG, "Failed to send MSG_CREATE_EXTERNAL_SERVICE_RESPONSE", e);
+                        }
+                    }
+            }
+            super.handleMessage(msg);
+        }
+    };
+
+    private final Messenger mMessenger = new Messenger(mHandler);
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        Log.d(TAG, "onBind " + intent);
+        return mMessenger.getBinder();
+    }
+
+    @Override
+    public void onDestroy() {
+        for (final CreatorConnection conn : mConnections) {
+            unbindService(conn);
+        }
+        super.onDestroy();
+    }
+
+    private class CreatorConnection implements ServiceConnection {
+        private IBinder mService = null;
+        private Messenger mReplyTo = null;
+
+        public CreatorConnection(Messenger replyTo) {
+            mReplyTo = replyTo;
+        }
+
+        @Override
+        public void onServiceConnected(ComponentName name, IBinder service) {
+            Log.d(TAG, "onServiceConnected " + name);
+            Message msg =
+                    Message.obtain(null, ServiceMessages.MSG_CREATE_EXTERNAL_SERVICE_RESPONSE);
+            msg.obj = new Messenger(service);
+            try {
+                mReplyTo.send(msg);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Failed to send MSG_CREATE_EXTERNAL_SERVICE_RESPONSE", e);
+            }
+            mReplyTo = null;
+        }
+
+        @Override
+        public void onServiceDisconnected(ComponentName name) {
+            Log.d(TAG, "onServiceDisconnected " + name);
+            mService = null;
+        }
+    }
+}
diff --git a/tests/tests/externalservice/src/android/externalservice/cts/ExternalServiceTest.java b/tests/tests/externalservice/src/android/externalservice/cts/ExternalServiceTest.java
new file mode 100644
index 0000000..37c8613
--- /dev/null
+++ b/tests/tests/externalservice/src/android/externalservice/cts/ExternalServiceTest.java
@@ -0,0 +1,350 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.externalservice.cts;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.ConditionVariable;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.Messenger;
+import android.os.Parcel;
+import android.os.Process;
+import android.os.RemoteException;
+import android.test.AndroidTestCase;
+import android.util.Log;
+
+import android.externalservice.common.ServiceMessages;
+
+public class ExternalServiceTest extends AndroidTestCase {
+    private static final String TAG = "ExternalServiceTest";
+
+    static final String sServicePackage = "android.externalservice.service";
+
+    private Connection mConnection = new Connection();
+
+    private ConditionVariable mCondition = new ConditionVariable(false);
+
+    static final int CONDITION_TIMEOUT = 10 * 1000 /* 10 seconds */;
+
+    public void tearDown() {
+        if (mConnection.service != null)
+            getContext().unbindService(mConnection);
+    }
+
+    /** Tests that an isolatedProcess service cannot be bound to by an external package. */
+    public void testFailBindIsolated() {
+        Intent intent = new Intent();
+        intent.setComponent(new ComponentName(sServicePackage, sServicePackage+".IsolatedService"));
+        try {
+            getContext().bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
+            fail("Should not be able to bind to non-exported, non-external service");
+        } catch (SecurityException e) {
+        }
+    }
+
+    /** Tests that BIND_EXTERNAL_SERVICE does not work with plain isolatedProcess services. */
+    public void testFailBindExternalIsolated() {
+        Intent intent = new Intent();
+        intent.setComponent(new ComponentName(sServicePackage, sServicePackage+".IsolatedService"));
+        try {
+            getContext().bindService(intent, mConnection,
+                    Context.BIND_AUTO_CREATE | Context.BIND_EXTERNAL_SERVICE);
+            fail("Should not be able to BIND_EXTERNAL_SERVICE to non-exported, non-external service");
+        } catch (SecurityException e) {
+        }
+    }
+
+    /** Tests that BIND_EXTERNAL_SERVICE does not work with exported, isolatedProcess services (
+     * requires externalService as well). */
+    public void testFailBindExternalExported() {
+        Intent intent = new Intent();
+        intent.setComponent(new ComponentName(sServicePackage, sServicePackage+".ExportedService"));
+        try {
+            getContext().bindService(intent, mConnection,
+                    Context.BIND_AUTO_CREATE | Context.BIND_EXTERNAL_SERVICE);
+            fail("Should not be able to BIND_EXTERNAL_SERVICE to non-external service");
+        } catch (SecurityException e) {
+        }
+    }
+
+    /** Tests that BIND_EXTERNAL_SERVICE requires that an externalService be exported. */
+    public void testFailBindExternalNonExported() {
+        Intent intent = new Intent();
+        intent.setComponent(
+                new ComponentName(sServicePackage, sServicePackage+".ExternalNonExportedService"));
+        try {
+            getContext().bindService(intent, mConnection,
+                    Context.BIND_AUTO_CREATE | Context.BIND_EXTERNAL_SERVICE);
+            fail("Should not be able to BIND_EXTERNAL_SERVICE to non-exported service");
+        } catch (SecurityException e) {
+        }
+    }
+
+    /** Tests that BIND_EXTERNAL_SERVICE requires the service be an isolatedProcess. */
+    public void testFailBindExternalNonIsolated() {
+        Intent intent = new Intent();
+        intent.setComponent(
+                new ComponentName(sServicePackage, sServicePackage+".ExternalNonIsolatedService"));
+        try {
+            getContext().bindService(intent, mConnection,
+                    Context.BIND_AUTO_CREATE | Context.BIND_EXTERNAL_SERVICE);
+            fail("Should not be able to BIND_EXTERNAL_SERVICE to non-isolated service");
+        } catch (SecurityException e) {
+        }
+    }
+
+    /** Tests that an externalService can only be bound with BIND_EXTERNAL_SERVICE. */
+    public void testFailBindWithoutBindExternal() {
+        Intent intent = new Intent();
+        intent.setComponent(new ComponentName(sServicePackage, sServicePackage+".ExternalService"));
+        try {
+            getContext().bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
+            fail("Should not be able to bind to an external service without BIND_EXTERNAL_SERVICE");
+        } catch (SecurityException e) {
+        }
+    }
+
+    /** Tests that an external service can be bound, and that it runs as a different principal. */
+    public void testBindExternalService() {
+        // Start the service and wait for connection.
+        Intent intent = new Intent();
+        intent.setComponent(new ComponentName(sServicePackage, sServicePackage+".ExternalService"));
+
+        mCondition.close();
+        assertTrue(getContext().bindService(intent, mConnection,
+                    Context.BIND_AUTO_CREATE | Context.BIND_EXTERNAL_SERVICE));
+
+        assertTrue(mCondition.block(CONDITION_TIMEOUT));
+        assertEquals(getContext().getPackageName(), mConnection.name.getPackageName());
+        assertNotSame(sServicePackage, mConnection.name.getPackageName());
+
+        // Check the identity of the service.
+        Messenger remote = new Messenger(mConnection.service);
+        ServiceIdentity id = identifyService(remote);
+        assertNotNull(id);
+
+        assertFalse(id.uid == 0 || id.pid == 0);
+        assertNotEquals(Process.myUid(), id.uid);
+        assertNotEquals(Process.myPid(), id.pid);
+        assertEquals(getContext().getPackageName(), id.packageName);
+    }
+
+    /** Tests that the APK providing the externalService can bind the service itself, and that
+     * other APKs bind to a different instance of it. */
+    public void testBindExternalServiceWithRunningOwn() {
+        // Start the service that will create the externalService.
+        final Connection creatorConnection = new Connection();
+        Intent intent = new Intent();
+        intent.setComponent(new ComponentName(sServicePackage, sServicePackage+".ServiceCreator"));
+
+        mCondition.close();
+        assertTrue(getContext().bindService(intent, creatorConnection, Context.BIND_AUTO_CREATE));
+        assertTrue(mCondition.block(CONDITION_TIMEOUT));
+
+        // Get the identity of the creator.
+        Messenger remoteCreator = new Messenger(creatorConnection.service);
+        ServiceIdentity creatorId = identifyService(remoteCreator);
+        assertNotNull(creatorId);
+        assertFalse(creatorId.uid == 0 || creatorId.pid == 0);
+
+        // Have the creator actually start its service.
+        final Message creatorMsg =
+                Message.obtain(null, ServiceMessages.MSG_CREATE_EXTERNAL_SERVICE);
+        Handler creatorHandler = new Handler(Looper.getMainLooper()) {
+            @Override
+            public void handleMessage(Message msg) {
+                Log.d(TAG, "Received message: " + msg);
+                switch (msg.what) {
+                    case ServiceMessages.MSG_CREATE_EXTERNAL_SERVICE_RESPONSE:
+                        creatorMsg.copyFrom(msg);
+                        mCondition.open();
+                        break;
+                }
+                super.handleMessage(msg);
+            }
+        };
+        Messenger localCreator = new Messenger(creatorHandler);
+        creatorMsg.replyTo = localCreator;
+        try {
+            mCondition.close();
+            remoteCreator.send(creatorMsg);
+        } catch (RemoteException e) {
+            fail("Unexpected remote exception" + e);
+            return;
+        }
+        assertTrue(mCondition.block(CONDITION_TIMEOUT));
+
+        // Get the connection to the creator's service.
+        assertNotNull(creatorMsg.obj);
+        Messenger remoteCreatorService = (Messenger) creatorMsg.obj;
+        ServiceIdentity creatorServiceId = identifyService(remoteCreatorService);
+        assertNotNull(creatorServiceId);
+        assertFalse(creatorServiceId.uid == 0 || creatorId.pid == 0);
+
+        // Create an external service from this (the test) process.
+        intent = new Intent();
+        intent.setComponent(new ComponentName(sServicePackage, sServicePackage+".ExternalService"));
+
+        mCondition.close();
+        assertTrue(getContext().bindService(intent, mConnection,
+                    Context.BIND_AUTO_CREATE | Context.BIND_EXTERNAL_SERVICE));
+        assertTrue(mCondition.block(CONDITION_TIMEOUT));
+        ServiceIdentity serviceId = identifyService(new Messenger(mConnection.service));
+        assertNotNull(serviceId);
+        assertFalse(serviceId.uid == 0 || serviceId.pid == 0);
+
+        // Make sure that all the processes are unique.
+        int myUid = Process.myUid();
+        int myPid = Process.myPid();
+        String myPkg = getContext().getPackageName();
+
+        assertNotEquals(myUid, creatorId.uid);
+        assertNotEquals(myUid, creatorServiceId.uid);
+        assertNotEquals(myUid, serviceId.uid);
+        assertNotEquals(myPid, creatorId.pid);
+        assertNotEquals(myPid, creatorServiceId.pid);
+        assertNotEquals(myPid, serviceId.pid);
+
+        assertNotEquals(creatorId.uid, creatorServiceId.uid);
+        assertNotEquals(creatorId.uid, serviceId.uid);
+        assertNotEquals(creatorId.pid, creatorServiceId.pid);
+        assertNotEquals(creatorId.pid, serviceId.pid);
+
+        assertNotEquals(creatorServiceId.uid, serviceId.uid);
+        assertNotEquals(creatorServiceId.pid, serviceId.pid);
+
+        assertNotEquals(myPkg, creatorId.packageName);
+        assertNotEquals(myPkg, creatorServiceId.packageName);
+        assertEquals(creatorId.packageName, creatorServiceId.packageName);
+        assertEquals(myPkg, serviceId.packageName);
+
+        getContext().unbindService(creatorConnection);
+    }
+
+    /** Tests that the binding to an externalService can be changed. */
+    public void testBindExternalAboveClient() {
+        // Start the service and wait for connection.
+        Intent intent = new Intent();
+        intent.setComponent(new ComponentName(sServicePackage, sServicePackage+".ExternalService"));
+
+        mCondition.close();
+        Connection initialConn = new Connection();
+        assertTrue(getContext().bindService(intent, initialConn,
+                    Context.BIND_AUTO_CREATE | Context.BIND_EXTERNAL_SERVICE));
+
+        assertTrue(mCondition.block(CONDITION_TIMEOUT));
+
+        ServiceIdentity idOne = identifyService(new Messenger(initialConn.service));
+        assertNotNull(idOne);
+        assertFalse(idOne.uid == 0 || idOne.pid == 0);
+
+        // Bind the service with a different priority.
+        mCondition.close();
+        Connection prioConn = new Connection();
+        assertTrue(getContext().bindService(intent, prioConn,
+                    Context.BIND_AUTO_CREATE | Context.BIND_EXTERNAL_SERVICE |
+                            Context.BIND_ABOVE_CLIENT));
+
+        assertTrue(mCondition.block(CONDITION_TIMEOUT));
+
+        ServiceIdentity idTwo = identifyService(new Messenger(prioConn.service));
+        assertNotNull(idTwo);
+        assertFalse(idTwo.uid == 0 || idTwo.pid == 0);
+
+        assertEquals(idOne.uid, idTwo.uid);
+        assertEquals(idOne.pid, idTwo.pid);
+        assertEquals(idOne.packageName, idTwo.packageName);
+        assertNotEquals(Process.myUid(), idOne.uid);
+        assertNotEquals(Process.myPid(), idOne.pid);
+        assertEquals(getContext().getPackageName(), idOne.packageName);
+
+        getContext().unbindService(prioConn);
+        getContext().unbindService(initialConn);
+    }
+
+    /** Contains information about the security principal of a Service. */
+    private static class ServiceIdentity {
+        int uid;
+        int pid;
+        String packageName;
+    }
+
+    /** Given a Messenger, this will message the service to retrieve its UID, PID, and package name.
+     * On success, returns a ServiceIdentity. On failure, returns null. */
+    private ServiceIdentity identifyService(Messenger service) {
+        final ServiceIdentity id = new ServiceIdentity();
+        Handler handler = new Handler(Looper.getMainLooper()) {
+            @Override
+            public void handleMessage(Message msg) {
+                Log.d(TAG, "Received message: " + msg);
+                switch (msg.what) {
+                    case ServiceMessages.MSG_IDENTIFY_RESPONSE:
+                        id.uid = msg.arg1;
+                        id.pid = msg.arg2;
+                        id.packageName = msg.getData().getString(ServiceMessages.IDENTIFY_PACKAGE);
+                        mCondition.open();
+                        break;
+                }
+                super.handleMessage(msg);
+            }
+        };
+        Messenger local = new Messenger(handler);
+
+        Message msg = Message.obtain(null, ServiceMessages.MSG_IDENTIFY);
+        msg.replyTo = local;
+        try {
+            mCondition.close();
+            service.send(msg);
+        } catch (RemoteException e) {
+            fail("Unexpected remote exception: " + e);
+            return null;
+        }
+
+        if (!mCondition.block(CONDITION_TIMEOUT))
+            return null;
+        return id;
+    }
+
+    private class Connection implements ServiceConnection {
+        IBinder service = null;
+        ComponentName name = null;
+        boolean disconnected = false;
+
+        @Override
+        public void onServiceConnected(ComponentName name, IBinder service) {
+            Log.d(TAG, "onServiceConnected " + name);
+            this.service = service;
+            this.name = name;
+            mCondition.open();
+        }
+
+        @Override
+        public void onServiceDisconnected(ComponentName name) {
+            Log.d(TAG, "onServiceDisconnected " + name);
+        }
+    }
+
+    private <T> void assertNotEquals(T expected, T actual) {
+        assertFalse("Expected <" + expected + "> should not be equal to actual <" + actual + ">",
+                expected.equals(actual));
+    }
+}
diff --git a/tests/tests/gesture/Android.mk b/tests/tests/gesture/Android.mk
index 4a97931..7d71585 100755
--- a/tests/tests/gesture/Android.mk
+++ b/tests/tests/gesture/Android.mk
@@ -16,15 +16,22 @@
 
 include $(CLEAR_VARS)
 
-# don't include this package in any target
-LOCAL_MODULE_TAGS := optional
-# and when built explicitly put it in the data partition
+# Don't include this package in any target
+LOCAL_MODULE_TAGS := tests
+# When built explicitly put it in the data partition
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
 
-LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
+LOCAL_DEX_PREOPT := false
+
+LOCAL_PROGUARD_ENABLED := disabled
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_PACKAGE_NAME := CtsGestureTestCases
 
 LOCAL_SDK_VERSION := current
diff --git a/tests/tests/gesture/AndroidManifest.xml b/tests/tests/gesture/AndroidManifest.xml
index b288cd2..fb3ee51 100755
--- a/tests/tests/gesture/AndroidManifest.xml
+++ b/tests/tests/gesture/AndroidManifest.xml
@@ -16,19 +16,17 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.gesture">
+    package="android.gesture.cts">
 
-    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <application>
         <uses-library android:name="android.test.runner" />
     </application>
 
     <!--  self-instrumenting test package. -->
-    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.cts.gesture"
-                     android:label="CTS tests of android.gesture">
-        <meta-data android:name="listener"
-            android:value="com.android.cts.runner.CtsTestRunListener" />
+    <instrumentation
+        android:name="android.support.test.runner.AndroidJUnitRunner"
+        android:targetPackage="android.gesture.cts"
+        android:label="CTS tests of android.gesture">
     </instrumentation>
 
 </manifest>
diff --git a/tests/tests/gesture/AndroidTest.xml b/tests/tests/gesture/AndroidTest.xml
new file mode 100644
index 0000000..497cad1
--- /dev/null
+++ b/tests/tests/gesture/AndroidTest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS Gesture test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsGestureTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.gesture.cts" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/tests/graphics/Android.mk b/tests/tests/graphics/Android.mk
index 773b47d..b6d8bc9 100644
--- a/tests/tests/graphics/Android.mk
+++ b/tests/tests/graphics/Android.mk
@@ -18,12 +18,17 @@
 
 LOCAL_MODULE_TAGS := tests
 
-LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctstestrunner
+LOCAL_JAVA_LIBRARIES := android.test.runner
+
+LOCAL_STATIC_JAVA_LIBRARIES := mockito-target ctsdeviceutil ctstestrunner
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
 LOCAL_PACKAGE_NAME := CtsGraphicsTestCases
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_SDK_VERSION := current
 
 include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/graphics/AndroidManifest.xml b/tests/tests/graphics/AndroidManifest.xml
index 4249bb3..f14506f 100644
--- a/tests/tests/graphics/AndroidManifest.xml
+++ b/tests/tests/graphics/AndroidManifest.xml
@@ -16,7 +16,7 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.graphics">
+    package="android.graphics.cts">
 
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
@@ -54,7 +54,7 @@
     </application>
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.cts.graphics"
+                     android:targetPackage="android.graphics.cts"
                      android:label="CTS tests of android.graphics">
         <meta-data android:name="listener"
             android:value="com.android.cts.runner.CtsTestRunListener" />
diff --git a/tests/tests/graphics/AndroidTest.xml b/tests/tests/graphics/AndroidTest.xml
new file mode 100644
index 0000000..a9f746b
--- /dev/null
+++ b/tests/tests/graphics/AndroidTest.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS Graphics test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsGraphicsTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.graphics.cts" />
+        <option name="runtime-hint" value="5m" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/color/fill_gradient_linear.xml b/tests/tests/graphics/res/color/fill_gradient_linear.xml
new file mode 100644
index 0000000..d9b7497
--- /dev/null
+++ b/tests/tests/graphics/res/color/fill_gradient_linear.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+-->
+<gradient xmlns:android="http://schemas.android.com/apk/res/android"
+          android:angle="90"
+          android:startColor="?attr/themeColor"
+          android:endColor="#0f0"
+          android:centerColor="#00ff0000"
+          android:startX="0"
+          android:startY="0"
+          android:endX="100"
+          android:endY="100"
+          android:type="linear">
+</gradient>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/color/fill_gradient_linear_clamp.xml b/tests/tests/graphics/res/color/fill_gradient_linear_clamp.xml
new file mode 100644
index 0000000..56d9fc8
--- /dev/null
+++ b/tests/tests/graphics/res/color/fill_gradient_linear_clamp.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+-->
+<gradient xmlns:android="http://schemas.android.com/apk/res/android"
+          android:angle="90"
+          android:startColor="?attr/themeColor"
+          android:endColor="#0f0"
+          android:centerColor="#00ff0000"
+          android:startX="0"
+          android:startY="0"
+          android:endX="50"
+          android:endY="50"
+          android:type="linear"
+          android:tileMode="clamp">
+</gradient>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/color/fill_gradient_linear_item.xml b/tests/tests/graphics/res/color/fill_gradient_linear_item.xml
new file mode 100644
index 0000000..c1fb560
--- /dev/null
+++ b/tests/tests/graphics/res/color/fill_gradient_linear_item.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+-->
+<gradient xmlns:android="http://schemas.android.com/apk/res/android"
+          android:angle="90"
+          android:startColor="?attr/themeColor"
+          android:endColor="#0f0"
+          android:centerColor="#f00"
+          android:startX="0"
+          android:startY="0"
+          android:endX="100"
+          android:endY="100"
+          android:type="linear">
+    <item android:offset="0.1" android:color="?attr/themeColor"/>
+    <item android:offset="0.4" android:color="#fff"/>
+    <item android:offset="0.9" android:color="#0f0"/>
+</gradient>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/color/fill_gradient_linear_item_overlap.xml b/tests/tests/graphics/res/color/fill_gradient_linear_item_overlap.xml
new file mode 100644
index 0000000..a5b261a
--- /dev/null
+++ b/tests/tests/graphics/res/color/fill_gradient_linear_item_overlap.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+-->
+<gradient xmlns:android="http://schemas.android.com/apk/res/android"
+          android:angle="90"
+          android:startColor="?attr/themeColor"
+          android:endColor="#0f0"
+          android:centerColor="#f00"
+          android:startX="0"
+          android:startY="0"
+          android:endX="100"
+          android:endY="100"
+          android:type="linear">
+    <item android:offset="0.1" android:color="?attr/themeColor"/>
+    <item android:offset="0.4" android:color="#f00"/>
+    <item android:offset="0.4" android:color="#fff"/>
+    <item android:offset="0.9" android:color="#0f0"/>
+</gradient>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/color/fill_gradient_linear_item_overlap_mirror.xml b/tests/tests/graphics/res/color/fill_gradient_linear_item_overlap_mirror.xml
new file mode 100644
index 0000000..009eb52
--- /dev/null
+++ b/tests/tests/graphics/res/color/fill_gradient_linear_item_overlap_mirror.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+-->
+<gradient xmlns:android="http://schemas.android.com/apk/res/android"
+          android:angle="90"
+          android:startColor="?attr/themeColor"
+          android:endColor="#0f0"
+          android:centerColor="#f00"
+          android:startX="0"
+          android:startY="0"
+          android:endX="50"
+          android:endY="50"
+          android:type="linear"
+          android:tileMode="mirror">
+    <item android:offset="0.1" android:color="?attr/themeColor"/>
+    <item android:offset="0.4" android:color="#f00"/>
+    <item android:offset="0.4" android:color="#fff"/>
+    <item android:offset="0.9" android:color="#0f0"/>
+</gradient>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/color/fill_gradient_linear_item_repeat.xml b/tests/tests/graphics/res/color/fill_gradient_linear_item_repeat.xml
new file mode 100644
index 0000000..c89e981
--- /dev/null
+++ b/tests/tests/graphics/res/color/fill_gradient_linear_item_repeat.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+-->
+<gradient xmlns:android="http://schemas.android.com/apk/res/android"
+          android:angle="90"
+          android:startColor="?attr/themeColor"
+          android:endColor="#0f0"
+          android:centerColor="#f00"
+          android:startX="0"
+          android:startY="0"
+          android:endX="50"
+          android:endY="50"
+          android:type="linear"
+          android:tileMode="repeat">
+    <item android:offset="0.1" android:color="?attr/themeColor"/>
+    <item android:offset="0.4" android:color="#fff"/>
+    <item android:offset="0.9" android:color="#0f0"/>
+</gradient>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/color/fill_gradient_radial.xml b/tests/tests/graphics/res/color/fill_gradient_radial.xml
new file mode 100644
index 0000000..389a0fc
--- /dev/null
+++ b/tests/tests/graphics/res/color/fill_gradient_radial.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+-->
+<gradient xmlns:android="http://schemas.android.com/apk/res/android"
+          android:centerColor="#ff0000"
+          android:endColor="#0f0"
+          android:centerX="300"
+          android:centerY="300"
+          android:gradientRadius="100"
+          android:startColor="?attr/themeColor"
+          android:type="radial">
+</gradient>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/color/fill_gradient_radial_clamp.xml b/tests/tests/graphics/res/color/fill_gradient_radial_clamp.xml
new file mode 100644
index 0000000..ff29134
--- /dev/null
+++ b/tests/tests/graphics/res/color/fill_gradient_radial_clamp.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+-->
+<gradient xmlns:android="http://schemas.android.com/apk/res/android"
+          android:centerColor="#ff0000"
+          android:endColor="#0f0"
+          android:centerX="300"
+          android:centerY="300"
+          android:gradientRadius="50"
+          android:startColor="?attr/themeColor"
+          android:type="radial"
+          android:tileMode="clamp">
+</gradient>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/color/fill_gradient_radial_item.xml b/tests/tests/graphics/res/color/fill_gradient_radial_item.xml
new file mode 100644
index 0000000..2f116c9
--- /dev/null
+++ b/tests/tests/graphics/res/color/fill_gradient_radial_item.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+-->
+<gradient xmlns:android="http://schemas.android.com/apk/res/android"
+          android:centerColor="#ff0000"
+          android:endColor="#ff0000ff"
+          android:centerX="300"
+          android:centerY="300"
+          android:gradientRadius="100"
+          android:startColor="#ffffffff"
+          android:type="radial">
+    <item android:offset="0.1" android:color="?attr/themeColor"/>
+    <item android:offset="0.4" android:color="#fff"/>
+    <item android:offset="0.9" android:color="#0f0"/>
+</gradient>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/color/fill_gradient_radial_item_repeat.xml b/tests/tests/graphics/res/color/fill_gradient_radial_item_repeat.xml
new file mode 100644
index 0000000..d17fc48
--- /dev/null
+++ b/tests/tests/graphics/res/color/fill_gradient_radial_item_repeat.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+-->
+<gradient xmlns:android="http://schemas.android.com/apk/res/android"
+          android:centerColor="#ff0000"
+          android:endColor="#ff0000ff"
+          android:centerX="300"
+          android:centerY="300"
+          android:gradientRadius="50"
+          android:startColor="#ffffffff"
+          android:type="radial"
+          android:tileMode="repeat">
+    <item android:offset="0.1" android:color="?attr/themeColor"/>
+    <item android:offset="0.4" android:color="#fff"/>
+    <item android:offset="0.9" android:color="#0f0"/>
+</gradient>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/color/fill_gradient_radial_item_short.xml b/tests/tests/graphics/res/color/fill_gradient_radial_item_short.xml
new file mode 100644
index 0000000..111d023
--- /dev/null
+++ b/tests/tests/graphics/res/color/fill_gradient_radial_item_short.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+-->
+<gradient xmlns:android="http://schemas.android.com/apk/res/android"
+          android:centerX="300"
+          android:centerY="300"
+          android:gradientRadius="100"
+          android:type="radial">
+    <item android:offset="0.1" android:color="?attr/themeColor"/>
+    <item android:offset="0.9" android:color="#0f0"/>
+</gradient>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/color/fill_gradient_radial_item_short_mirror.xml b/tests/tests/graphics/res/color/fill_gradient_radial_item_short_mirror.xml
new file mode 100644
index 0000000..1aa110c
--- /dev/null
+++ b/tests/tests/graphics/res/color/fill_gradient_radial_item_short_mirror.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+-->
+<gradient xmlns:android="http://schemas.android.com/apk/res/android"
+          android:centerX="300"
+          android:centerY="300"
+          android:gradientRadius="50"
+          android:type="radial"
+          android:tileMode="mirror">
+    <item android:offset="0.1" android:color="?attr/themeColor"/>
+    <item android:offset="0.9" android:color="#0f0"/>
+</gradient>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/color/fill_gradient_sweep.xml b/tests/tests/graphics/res/color/fill_gradient_sweep.xml
new file mode 100644
index 0000000..e1fbd10
--- /dev/null
+++ b/tests/tests/graphics/res/color/fill_gradient_sweep.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+-->
+<gradient xmlns:android="http://schemas.android.com/apk/res/android"
+          android:centerColor="#ff0000"
+          android:endColor="#ff0000ff"
+          android:centerX="500"
+          android:centerY="500"
+          android:gradientRadius="10"
+          android:startColor="#ffffffff"
+          android:type="sweep">
+</gradient>
diff --git a/tests/tests/graphics/res/color/fill_gradient_sweep_clamp.xml b/tests/tests/graphics/res/color/fill_gradient_sweep_clamp.xml
new file mode 100644
index 0000000..80f39f3
--- /dev/null
+++ b/tests/tests/graphics/res/color/fill_gradient_sweep_clamp.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+-->
+<gradient xmlns:android="http://schemas.android.com/apk/res/android"
+          android:centerColor="#ff0000"
+          android:endColor="#ff0000ff"
+          android:centerX="500"
+          android:centerY="500"
+          android:gradientRadius="10"
+          android:startColor="#ffffffff"
+          android:type="sweep"
+          android:tileMode="clamp">
+</gradient>
diff --git a/tests/tests/graphics/res/color/fill_gradient_sweep_item.xml b/tests/tests/graphics/res/color/fill_gradient_sweep_item.xml
new file mode 100644
index 0000000..2a010c0
--- /dev/null
+++ b/tests/tests/graphics/res/color/fill_gradient_sweep_item.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+-->
+<gradient xmlns:android="http://schemas.android.com/apk/res/android"
+          android:centerColor="#ff0000"
+          android:endColor="#ff0000ff"
+          android:centerX="500"
+          android:centerY="500"
+          android:gradientRadius="10"
+          android:startColor="#ffffffff"
+          android:type="sweep">
+    <item android:offset="0.1" android:color="?attr/themeColor"/>
+    <item android:offset="0.4" android:color="#fff"/>
+    <item android:offset="0.9" android:color="#0f0"/>
+</gradient>
diff --git a/tests/tests/graphics/res/color/fill_gradient_sweep_item_long.xml b/tests/tests/graphics/res/color/fill_gradient_sweep_item_long.xml
new file mode 100644
index 0000000..7b0bbef
--- /dev/null
+++ b/tests/tests/graphics/res/color/fill_gradient_sweep_item_long.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+-->
+<gradient xmlns:android="http://schemas.android.com/apk/res/android"
+          android:centerX="500"
+          android:centerY="500"
+          android:gradientRadius="10"
+          android:type="sweep">
+    <item android:offset="-0.3" android:color="#f00"/>
+    <item android:offset="0.1" android:color="?attr/themeColor"/>
+    <item android:offset="0.4" android:color="#0f0"/>
+    <item android:offset="0.6" android:color="#00f"/>
+    <item android:offset="0.7" android:color="#0f0"/>
+    <item android:offset="1.5" android:color="#00f"/>
+</gradient>
diff --git a/tests/tests/graphics/res/color/fill_gradient_sweep_item_long_mirror.xml b/tests/tests/graphics/res/color/fill_gradient_sweep_item_long_mirror.xml
new file mode 100644
index 0000000..2a73a4f
--- /dev/null
+++ b/tests/tests/graphics/res/color/fill_gradient_sweep_item_long_mirror.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+-->
+<gradient xmlns:android="http://schemas.android.com/apk/res/android"
+          android:centerX="500"
+          android:centerY="500"
+          android:gradientRadius="10"
+          android:type="sweep"
+          android:tileMode="mirror">
+    <item android:offset="-0.3" android:color="#f00"/>
+    <item android:offset="0.1" android:color="?attr/themeColor"/>
+    <item android:offset="0.4" android:color="#0f0"/>
+    <item android:offset="0.6" android:color="#00f"/>
+    <item android:offset="0.7" android:color="#0f0"/>
+    <item android:offset="1.5" android:color="#00f"/>
+</gradient>
diff --git a/tests/tests/graphics/res/color/fill_gradient_sweep_item_repeat.xml b/tests/tests/graphics/res/color/fill_gradient_sweep_item_repeat.xml
new file mode 100644
index 0000000..62e6f66
--- /dev/null
+++ b/tests/tests/graphics/res/color/fill_gradient_sweep_item_repeat.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+-->
+<gradient xmlns:android="http://schemas.android.com/apk/res/android"
+          android:centerColor="#ff0000"
+          android:endColor="#ff0000ff"
+          android:centerX="500"
+          android:centerY="500"
+          android:gradientRadius="10"
+          android:startColor="#ffffffff"
+          android:type="sweep"
+          android:tileMode="repeat">
+    <item android:offset="0.1" android:color="?attr/themeColor"/>
+    <item android:offset="0.4" android:color="#fff"/>
+    <item android:offset="0.9" android:color="#0f0"/>
+</gradient>
diff --git a/tests/tests/graphics/res/color/stroke_gradient.xml b/tests/tests/graphics/res/color/stroke_gradient.xml
new file mode 100644
index 0000000..cb324c9
--- /dev/null
+++ b/tests/tests/graphics/res/color/stroke_gradient.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+-->
+<gradient xmlns:android="http://schemas.android.com/apk/res/android"
+          android:angle="90"
+          android:centerColor="#7f7f7f"
+          android:endColor="#ffffff"
+          android:startColor="#000000"
+          android:startX="0"
+          android:endX="100"
+          android:startY="0"
+          android:endY="0"
+          android:type="linear">
+</gradient>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/color/stroke_gradient_clamp.xml b/tests/tests/graphics/res/color/stroke_gradient_clamp.xml
new file mode 100644
index 0000000..3d746e7
--- /dev/null
+++ b/tests/tests/graphics/res/color/stroke_gradient_clamp.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+-->
+<gradient xmlns:android="http://schemas.android.com/apk/res/android"
+          android:angle="90"
+          android:centerColor="#7f7f7f"
+          android:endColor="#ffffff"
+          android:startColor="#000000"
+          android:startX="0"
+          android:endX="50"
+          android:startY="0"
+          android:endY="0"
+          android:type="linear"
+          android:tileMode="clamp">
+</gradient>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/color/stroke_gradient_item.xml b/tests/tests/graphics/res/color/stroke_gradient_item.xml
new file mode 100644
index 0000000..15d948c
--- /dev/null
+++ b/tests/tests/graphics/res/color/stroke_gradient_item.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+-->
+<gradient xmlns:android="http://schemas.android.com/apk/res/android"
+          android:angle="90"
+          android:centerColor="#7f7f7f"
+          android:endColor="#ffffff"
+          android:startColor="#000000"
+          android:startX="0"
+          android:endX="100"
+          android:startY="0"
+          android:endY="0"
+          android:type="linear">
+    <item android:offset="0.1" android:color="#f00"/>
+    <item android:offset="0.2" android:color="#f0f"/>
+    <item android:offset="0.9" android:color="#f00f"/>
+</gradient>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/color/stroke_gradient_item_alpha.xml b/tests/tests/graphics/res/color/stroke_gradient_item_alpha.xml
new file mode 100644
index 0000000..fda2b88
--- /dev/null
+++ b/tests/tests/graphics/res/color/stroke_gradient_item_alpha.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+-->
+<gradient xmlns:android="http://schemas.android.com/apk/res/android"
+          android:startX="0"
+          android:endX="100"
+          android:startY="0"
+          android:endY="0"
+          android:type="linear">
+    <item android:offset="0.1" android:color="#f00"/>
+    <item android:offset="0.2" android:color="#2f0f"/>
+    <item android:offset="0.9" android:color="#f00f"/>
+</gradient>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/color/stroke_gradient_item_alpha_mirror.xml b/tests/tests/graphics/res/color/stroke_gradient_item_alpha_mirror.xml
new file mode 100644
index 0000000..352a2fd
--- /dev/null
+++ b/tests/tests/graphics/res/color/stroke_gradient_item_alpha_mirror.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+-->
+<gradient xmlns:android="http://schemas.android.com/apk/res/android"
+          android:startX="0"
+          android:endX="50"
+          android:startY="0"
+          android:endY="0"
+          android:type="linear"
+          android:tileMode="mirror">
+    <item android:offset="0.1" android:color="#f00"/>
+    <item android:offset="0.2" android:color="#2f0f"/>
+    <item android:offset="0.9" android:color="#f00f"/>
+</gradient>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/color/stroke_gradient_item_repeat.xml b/tests/tests/graphics/res/color/stroke_gradient_item_repeat.xml
new file mode 100644
index 0000000..42281d1
--- /dev/null
+++ b/tests/tests/graphics/res/color/stroke_gradient_item_repeat.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+-->
+<gradient xmlns:android="http://schemas.android.com/apk/res/android"
+          android:angle="90"
+          android:centerColor="#7f7f7f"
+          android:endColor="#ffffff"
+          android:startColor="#000000"
+          android:startX="0"
+          android:endX="50"
+          android:startY="0"
+          android:endY="0"
+          android:type="linear"
+          android:tileMode="repeat">
+    <item android:offset="0.1" android:color="#f00"/>
+    <item android:offset="0.2" android:color="#f0f"/>
+    <item android:offset="0.9" android:color="#f00f"/>
+</gradient>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/color/vector_icon_fill_state_list.xml b/tests/tests/graphics/res/color/vector_icon_fill_state_list.xml
new file mode 100644
index 0000000..f5b4632
--- /dev/null
+++ b/tests/tests/graphics/res/color/vector_icon_fill_state_list.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:color="#00ff00" android:state_pressed="true" />
+    <item android:color="#0000ff" />
+</selector>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/color/vector_icon_stroke_state_list.xml b/tests/tests/graphics/res/color/vector_icon_stroke_state_list.xml
new file mode 100644
index 0000000..bbc635e
--- /dev/null
+++ b/tests/tests/graphics/res/color/vector_icon_stroke_state_list.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:color="#0000ff" android:state_pressed="true" />
+    <item android:color="#00ff00" />
+</selector>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/drawable-nodpi/bitmap_density_golden_160.png b/tests/tests/graphics/res/drawable-nodpi/bitmap_density_golden_160.png
new file mode 100644
index 0000000..de48ed9
--- /dev/null
+++ b/tests/tests/graphics/res/drawable-nodpi/bitmap_density_golden_160.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/bitmap_density_golden_320.png b/tests/tests/graphics/res/drawable-nodpi/bitmap_density_golden_320.png
new file mode 100644
index 0000000..0682813
--- /dev/null
+++ b/tests/tests/graphics/res/drawable-nodpi/bitmap_density_golden_320.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/bitmap_density_golden_80.png b/tests/tests/graphics/res/drawable-nodpi/bitmap_density_golden_80.png
new file mode 100644
index 0000000..5588a5a
--- /dev/null
+++ b/tests/tests/graphics/res/drawable-nodpi/bitmap_density_golden_80.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/nine_patch_density_golden_160.png b/tests/tests/graphics/res/drawable-nodpi/nine_patch_density_golden_160.png
new file mode 100644
index 0000000..8110d8f
--- /dev/null
+++ b/tests/tests/graphics/res/drawable-nodpi/nine_patch_density_golden_160.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/nine_patch_density_golden_320.png b/tests/tests/graphics/res/drawable-nodpi/nine_patch_density_golden_320.png
new file mode 100644
index 0000000..c48c78e
--- /dev/null
+++ b/tests/tests/graphics/res/drawable-nodpi/nine_patch_density_golden_320.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/nine_patch_density_golden_80.png b/tests/tests/graphics/res/drawable-nodpi/nine_patch_density_golden_80.png
new file mode 100644
index 0000000..173150f
--- /dev/null
+++ b/tests/tests/graphics/res/drawable-nodpi/nine_patch_density_golden_80.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_arcto_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_arcto_golden.png
new file mode 100644
index 0000000..7ba0f17
--- /dev/null
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_arcto_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_filltype_evenodd_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_filltype_evenodd_golden.png
new file mode 100644
index 0000000..bef75d4
--- /dev/null
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_filltype_evenodd_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_filltype_nonzero_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_filltype_nonzero_golden.png
new file mode 100644
index 0000000..85cf20b
--- /dev/null
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_filltype_nonzero_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_1_clamp_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_1_clamp_golden.png
new file mode 100644
index 0000000..a137784
--- /dev/null
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_1_clamp_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_1_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_1_golden.png
new file mode 100644
index 0000000..d5288d1
--- /dev/null
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_1_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_2_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_2_golden.png
new file mode 100644
index 0000000..54fbca7
--- /dev/null
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_2_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_2_repeat_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_2_repeat_golden.png
new file mode 100644
index 0000000..40432cd
--- /dev/null
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_2_repeat_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_3_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_3_golden.png
new file mode 100644
index 0000000..09fd92f
--- /dev/null
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_3_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_3_mirror_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_3_mirror_golden.png
new file mode 100644
index 0000000..9f1b257
--- /dev/null
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_3_mirror_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_implicit_lineto_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_implicit_lineto_golden.png
new file mode 100644
index 0000000..9d74952
--- /dev/null
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_implicit_lineto_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_random_path_2_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_random_path_2_golden.png
index c60dfba..d24321c 100644
--- a/tests/tests/graphics/res/drawable-nodpi/vector_icon_random_path_2_golden.png
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_random_path_2_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_repeated_a_1_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_repeated_a_1_golden.png
index e7cc4d1..7e35798 100644
--- a/tests/tests/graphics/res/drawable-nodpi/vector_icon_repeated_a_1_golden.png
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_repeated_a_1_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_repeated_a_2_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_repeated_a_2_golden.png
index c7c049b..1427f4b 100644
--- a/tests/tests/graphics/res/drawable-nodpi/vector_icon_repeated_a_2_golden.png
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_repeated_a_2_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_state_list_2_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_state_list_2_golden.png
new file mode 100644
index 0000000..3936c89
--- /dev/null
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_state_list_2_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_state_list_2_golden_pressed.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_state_list_2_golden_pressed.png
new file mode 100644
index 0000000..c5d06f6
--- /dev/null
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_state_list_2_golden_pressed.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_state_list_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_state_list_golden.png
new file mode 100644
index 0000000..3936c89
--- /dev/null
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_state_list_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_state_list_golden_pressed.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_state_list_golden_pressed.png
new file mode 100644
index 0000000..c5d06f6
--- /dev/null
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_state_list_golden_pressed.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable/animated_state_list_density.xml b/tests/tests/graphics/res/drawable/animated_state_list_density.xml
new file mode 100644
index 0000000..ca47806
--- /dev/null
+++ b/tests/tests/graphics/res/drawable/animated_state_list_density.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<animated-selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item
+        android:state_focused="true"
+        android:id="@+id/focused"
+        android:drawable="@drawable/state_list_density_1" />
+    <item
+        android:id="@+id/unfocused"
+        android:drawable="@drawable/state_list_density_2" />
+    <transition
+        android:fromId="@+id/unfocused"
+        android:toId="@+id/focused">
+        <animation-list>
+            <item
+                android:duration="15"
+                android:drawable="@drawable/state_list_density_1" />
+        </animation-list>
+    </transition>
+    <transition
+        android:fromId="@+id/focused"
+        android:toId="@+id/unfocused">
+        <animation-list>
+            <item
+                android:duration="15"
+                android:drawable="@drawable/state_list_density_2" />
+        </animation-list>
+    </transition>
+</animated-selector>
diff --git a/tests/tests/graphics/res/drawable/animated_state_list_density_constant_size.xml b/tests/tests/graphics/res/drawable/animated_state_list_density_constant_size.xml
new file mode 100644
index 0000000..5bbee4d
--- /dev/null
+++ b/tests/tests/graphics/res/drawable/animated_state_list_density_constant_size.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<animated-selector xmlns:android="http://schemas.android.com/apk/res/android"
+                   android:constantSize="true">
+    <item
+        android:state_focused="true"
+        android:id="@+id/focused"
+        android:drawable="@drawable/state_list_density_1" />
+    <item
+        android:id="@+id/unfocused"
+        android:drawable="@drawable/state_list_density_2" />
+    <transition
+        android:fromId="@+id/unfocused"
+        android:toId="@+id/focused">
+        <animation-list>
+            <item
+                android:duration="15"
+                android:drawable="@drawable/state_list_density_1" />
+        </animation-list>
+    </transition>
+    <transition
+        android:fromId="@+id/focused"
+        android:toId="@+id/unfocused">
+        <animation-list>
+            <item
+                android:duration="15"
+                android:drawable="@drawable/state_list_density_2" />
+        </animation-list>
+    </transition>
+</animated-selector>
diff --git a/tests/tests/graphics/res/drawable/avd_single_frame.xml b/tests/tests/graphics/res/drawable/avd_single_frame.xml
new file mode 100644
index 0000000..483a0f3
--- /dev/null
+++ b/tests/tests/graphics/res/drawable/avd_single_frame.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<animated-vector xmlns:aapt="http://schemas.android.com/aapt"
+                 xmlns:android="http://schemas.android.com/apk/res/android">
+    <aapt:attr name="android:drawable">
+        <vector
+                android:width="32dp"
+                android:viewportWidth="32"
+                android:height="32dp"
+                android:viewportHeight="32">
+            <group
+                    android:name="btn_radio_to_off_mtrl_0"
+                    android:translateX="16"
+                    android:translateY="16">
+                <group
+                        android:name="ring_outer">
+                    <path
+                            android:name="ring_outer_path"
+                            android:fillColor="#FF000000"
+                            android:pathData="M 0.0,-9.0 c 4.9705627482,0.0 9.0,4.0294372518 9.0,9.0 c 0.0,4.9705627482 -4.0294372518,9.0 -9.0,9.0 c -4.9705627482,0.0 -9.0,-4.0294372518 -9.0,-9.0 c 0.0,-4.9705627482 4.0294372518,-9.0 9.0,-9.0 Z"/>
+                </group>
+            </group>
+        </vector>
+    </aapt:attr>
+    <target android:name="ring_outer_path">
+        <aapt:attr name="android:animation">
+            <set
+                    xmlns:android="http://schemas.android.com/apk/res/android" >
+                <objectAnimator
+                        android:duration="16"
+                        android:propertyName="fillColor"
+                        android:valueFrom="#f00"
+                        android:valueTo="#0f0"
+                        android:valueType="intType"
+                        android:interpolator="@interpolator/avd_single_frame_interpolator" />
+
+            </set>
+        </aapt:attr>
+    </target>
+</animated-vector>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/drawable/bitmap_density.xml b/tests/tests/graphics/res/drawable/bitmap_density.xml
new file mode 100644
index 0000000..5fb3611
--- /dev/null
+++ b/tests/tests/graphics/res/drawable/bitmap_density.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2016 The Android Open Source Project
+    
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+    
+          http://www.apache.org/licenses/LICENSE-2.0
+    
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+        android:src="@drawable/bitmap_density_internal" />
diff --git a/tests/tests/graphics/res/drawable/bitmap_density_internal.png b/tests/tests/graphics/res/drawable/bitmap_density_internal.png
new file mode 100644
index 0000000..a4add51
--- /dev/null
+++ b/tests/tests/graphics/res/drawable/bitmap_density_internal.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable/custom_drawable.xml b/tests/tests/graphics/res/drawable/custom_drawable.xml
new file mode 100644
index 0000000..cfb9bdb
--- /dev/null
+++ b/tests/tests/graphics/res/drawable/custom_drawable.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<drawable xmlns:android="http://schemas.android.com/apk/res/android"
+    class="android.graphics.drawable.cts.CustomDrawableTest$CustomDrawable"
+    android:color="#ffff0000" />
diff --git a/tests/tests/graphics/res/drawable/gradient_drawable_density.xml b/tests/tests/graphics/res/drawable/gradient_drawable_density.xml
new file mode 100644
index 0000000..ad3a3be
--- /dev/null
+++ b/tests/tests/graphics/res/drawable/gradient_drawable_density.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<shape
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="ring"
+    android:innerRadius="10dp"
+    android:thickness="4dp">
+    <gradient
+        android:gradientRadius="10dp" />
+    <corners
+        android:topLeftRadius="8dp"
+        android:topRightRadius="9dp"
+        android:bottomLeftRadius="10dp"
+        android:bottomRightRadius="11dp" />
+    <padding
+        android:left="11dp"
+        android:top="12dp"
+        android:right="13dp"
+        android:bottom="14dp" />
+    <stroke
+        android:color="@android:color/black"
+        android:dashGap="4dp"
+        android:dashWidth="4dp"
+        android:width="2dp" />
+    <size
+        android:width="200dp"
+        android:height="200dp" />
+</shape>
diff --git a/tests/tests/graphics/res/drawable/grayscale_jpg.jpg b/tests/tests/graphics/res/drawable/grayscale_jpg.jpg
new file mode 100644
index 0000000..6c6ae32
--- /dev/null
+++ b/tests/tests/graphics/res/drawable/grayscale_jpg.jpg
Binary files differ
diff --git a/tests/tests/graphics/res/drawable/grayscale_png.png b/tests/tests/graphics/res/drawable/grayscale_png.png
new file mode 100644
index 0000000..9f1beac
--- /dev/null
+++ b/tests/tests/graphics/res/drawable/grayscale_png.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable/inset_color.xml b/tests/tests/graphics/res/drawable/inset_color.xml
new file mode 100644
index 0000000..55cdf22
--- /dev/null
+++ b/tests/tests/graphics/res/drawable/inset_color.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<inset xmlns:android="http://schemas.android.com/apk/res/android"
+       android:drawable="@android:color/white"
+       android:inset="10dp" />
+
diff --git a/tests/tests/graphics/res/drawable/inset_density.xml b/tests/tests/graphics/res/drawable/inset_density.xml
new file mode 100644
index 0000000..7e0823e
--- /dev/null
+++ b/tests/tests/graphics/res/drawable/inset_density.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<inset xmlns:android="http://schemas.android.com/apk/res/android"
+       android:drawable="@drawable/inset_testimage"
+       android:insetLeft="16dp" />
diff --git a/tests/tests/graphics/res/drawable/inset_mutate.xml b/tests/tests/graphics/res/drawable/inset_mutate.xml
index ba613e9..feeeda1 100644
--- a/tests/tests/graphics/res/drawable/inset_mutate.xml
+++ b/tests/tests/graphics/res/drawable/inset_mutate.xml
@@ -16,4 +16,4 @@
  -->
 
 <inset xmlns:android="http://schemas.android.com/apk/res/android"
-       android:drawable="@drawable/inset_mutate_testimage" />
+       android:drawable="@drawable/inset_testimage" />
diff --git a/tests/tests/graphics/res/drawable/inset_mutate_testimage.jpg b/tests/tests/graphics/res/drawable/inset_testimage.jpg
similarity index 100%
rename from tests/tests/graphics/res/drawable/inset_mutate_testimage.jpg
rename to tests/tests/graphics/res/drawable/inset_testimage.jpg
Binary files differ
diff --git a/tests/tests/graphics/res/drawable/layer_drawable_density.xml b/tests/tests/graphics/res/drawable/layer_drawable_density.xml
new file mode 100644
index 0000000..3012539
--- /dev/null
+++ b/tests/tests/graphics/res/drawable/layer_drawable_density.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<layer-list
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:paddingTop="8dp"
+    android:paddingBottom="8dp"
+    android:paddingLeft="8dp"
+    android:paddingRight="8dp"
+    android:paddingMode="nest">
+    <item
+        android:left="16dp"
+        android:right="16dp"
+        android:top="16dp"
+        android:bottom="16dp"
+        android:width="32dp"
+        android:height="32dp">
+        <color
+            android:color="@android:color/black" />
+    </item>
+</layer-list>
diff --git a/tests/tests/graphics/res/drawable/layer_drawable_intrinsic.xml b/tests/tests/graphics/res/drawable/layer_drawable_intrinsic.xml
new file mode 100644
index 0000000..0a8cd98
--- /dev/null
+++ b/tests/tests/graphics/res/drawable/layer_drawable_intrinsic.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:left="5dp"
+          android:right="5dp"
+          android:top="5dp"
+          android:bottom="5dp"
+          android:drawable="@android:color/black" />
+</layer-list>
diff --git a/tests/tests/graphics/res/drawable/layer_drawable_intrinsic_mixed.xml b/tests/tests/graphics/res/drawable/layer_drawable_intrinsic_mixed.xml
new file mode 100644
index 0000000..a590f90
--- /dev/null
+++ b/tests/tests/graphics/res/drawable/layer_drawable_intrinsic_mixed.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:left="2dp"
+          android:right="2dp"
+          android:top="2dp"
+          android:bottom="2dp"
+          android:drawable="@drawable/size_48x48" />
+    <item android:left="100dp"
+          android:right="100dp"
+          android:top="100dp"
+          android:bottom="100dp"
+          android:drawable="@android:color/black" />
+</layer-list>
diff --git a/tests/tests/graphics/res/drawable/nine_patch_density.xml b/tests/tests/graphics/res/drawable/nine_patch_density.xml
new file mode 100644
index 0000000..918c76e
--- /dev/null
+++ b/tests/tests/graphics/res/drawable/nine_patch_density.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
+            android:src="@drawable/nine_patch_density_internal" />
diff --git a/tests/tests/graphics/res/drawable/nine_patch_density_internal.9.png b/tests/tests/graphics/res/drawable/nine_patch_density_internal.9.png
new file mode 100644
index 0000000..1a3181b
--- /dev/null
+++ b/tests/tests/graphics/res/drawable/nine_patch_density_internal.9.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable/nine_patch_odd_insets.xml b/tests/tests/graphics/res/drawable/nine_patch_odd_insets.xml
new file mode 100644
index 0000000..da0ddc1
--- /dev/null
+++ b/tests/tests/graphics/res/drawable/nine_patch_odd_insets.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
+            android:src="@drawable/nine_patch_odd_insets_internal" />
diff --git a/tests/tests/graphics/res/drawable/nine_patch_odd_insets_internal.9.png b/tests/tests/graphics/res/drawable/nine_patch_odd_insets_internal.9.png
new file mode 100644
index 0000000..905035a
--- /dev/null
+++ b/tests/tests/graphics/res/drawable/nine_patch_odd_insets_internal.9.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable/rotatedrawable_abs.xml b/tests/tests/graphics/res/drawable/rotatedrawable_abs.xml
new file mode 100644
index 0000000..8f5f619
--- /dev/null
+++ b/tests/tests/graphics/res/drawable/rotatedrawable_abs.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<rotate xmlns:android="http://schemas.android.com/apk/res/android"
+        android:pivotX="0.3"
+        android:pivotY="0.3"
+        android:fromDegrees="180"
+        android:toDegrees="-180"
+        android:drawable="@drawable/testimage" />
diff --git a/tests/tests/graphics/res/drawable/rotatedrawable_rel.xml b/tests/tests/graphics/res/drawable/rotatedrawable_rel.xml
new file mode 100644
index 0000000..c5b5de3
--- /dev/null
+++ b/tests/tests/graphics/res/drawable/rotatedrawable_rel.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<rotate xmlns:android="http://schemas.android.com/apk/res/android"
+        android:pivotX="10%"
+        android:pivotY="20%"
+        android:fromDegrees="360"
+        android:toDegrees="360"
+        android:drawable="@drawable/testimage" />
diff --git a/tests/tests/graphics/res/drawable/state_list_density.xml b/tests/tests/graphics/res/drawable/state_list_density.xml
new file mode 100644
index 0000000..9a17384
--- /dev/null
+++ b/tests/tests/graphics/res/drawable/state_list_density.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+   <item android:state_focused="true" android:drawable="@drawable/state_list_density_1" />
+   <item android:drawable="@drawable/state_list_density_2" />
+</selector>
+
diff --git a/tests/tests/graphics/res/drawable/inset_mutate_testimage.jpg b/tests/tests/graphics/res/drawable/state_list_density_1.jpg
similarity index 100%
copy from tests/tests/graphics/res/drawable/inset_mutate_testimage.jpg
copy to tests/tests/graphics/res/drawable/state_list_density_1.jpg
Binary files differ
diff --git a/tests/tests/graphics/res/drawable/state_list_density_2.jpg b/tests/tests/graphics/res/drawable/state_list_density_2.jpg
new file mode 100644
index 0000000..f963c86
--- /dev/null
+++ b/tests/tests/graphics/res/drawable/state_list_density_2.jpg
Binary files differ
diff --git a/tests/tests/graphics/res/drawable/state_list_density_constant_size.xml b/tests/tests/graphics/res/drawable/state_list_density_constant_size.xml
new file mode 100644
index 0000000..4e183f3
--- /dev/null
+++ b/tests/tests/graphics/res/drawable/state_list_density_constant_size.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android"
+          android:constantSize="true">
+   <item android:state_focused="true" android:drawable="@drawable/state_list_density_1" />
+   <item android:drawable="@drawable/state_list_density_2" />
+</selector>
+
diff --git a/tests/tests/graphics/res/drawable/vector_density.xml b/tests/tests/graphics/res/drawable/vector_density.xml
new file mode 100644
index 0000000..c3ca1981
--- /dev/null
+++ b/tests/tests/graphics/res/drawable/vector_density.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:height="64dp"
+        android:width="64dp"
+        android:viewportHeight="24"
+        android:viewportWidth="24" >
+
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M16.0,5.0c-1.955.0 -3.83,1.268 -4.5,3.0c-0.67-1.732 -2.547-3.0 -4.5-3.0C4.4570007,5.0 2.5,6.931999 2.5,9.5c0.0,3.529 3.793,6.258 9.0,11.5c5.207-5.242 9.0-7.971 9.0-11.5C20.5,6.931999 18.543,5.0 16.0,5.0z" />
+
+</vector>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/drawable/vector_icon_arcto.xml b/tests/tests/graphics/res/drawable/vector_icon_arcto.xml
new file mode 100644
index 0000000..6038d2b
--- /dev/null
+++ b/tests/tests/graphics/res/drawable/vector_icon_arcto.xml
@@ -0,0 +1,24 @@
+<!--
+ Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="20dp"
+        android:height="50dp"
+        android:viewportWidth="20.0"
+        android:viewportHeight="50.0">
+    <path
+        android:pathData="M14.285706,47.362198A50.71429,62.14286 0,0 0,1.0630035 5.5146027"
+        android:fillColor="#ff55ff"/>
+</vector>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/drawable/vector_icon_filltype_evenodd.xml b/tests/tests/graphics/res/drawable/vector_icon_filltype_evenodd.xml
new file mode 100644
index 0000000..d5d86d8
--- /dev/null
+++ b/tests/tests/graphics/res/drawable/vector_icon_filltype_evenodd.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+-->
+<vector android:height="24dp" android:viewportHeight="400.0"
+        android:viewportWidth="1200.0" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+    <path android:fillType="evenOdd"
+          android:fillColor="#f00"
+          android:pathData="M250,75L323,301 131,161 369,161 177,301z"
+          android:strokeColor="#000" android:strokeWidth="3"/>
+    <path android:fillType="evenOdd"
+          android:fillColor="#f00"
+          android:pathData="M600,81A107,107 0,0 1,600 295A107,107 0,0 1,600 81zM600,139A49,49 0,0 1,600 237A49,49 0,0 1,600 139z"
+          android:strokeColor="#000" android:strokeWidth="3"/>
+    <path android:fillType="evenOdd"
+          android:fillColor="#f00"
+          android:pathData="M950,81A107,107 0,0 1,950 295A107,107 0,0 1,950 81zM950,139A49,49 0,0 0,950 237A49,49 0,0 0,950 139z"
+          android:strokeColor="#000" android:strokeWidth="3"/>
+</vector>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/drawable/vector_icon_filltype_nonzero.xml b/tests/tests/graphics/res/drawable/vector_icon_filltype_nonzero.xml
new file mode 100644
index 0000000..9754e4b
--- /dev/null
+++ b/tests/tests/graphics/res/drawable/vector_icon_filltype_nonzero.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+-->
+<vector android:height="24dp" android:viewportHeight="400.0"
+        android:viewportWidth="1200.0" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+    <path android:fillType="nonZero"
+          android:fillColor="#f00"
+          android:pathData="M250,75L323,301 131,161 369,161 177,301z"
+          android:strokeColor="#000" android:strokeWidth="3"/>
+    <path android:fillType="nonZero"
+          android:fillColor="#f00"
+          android:pathData="M600,81A107,107 0,0 1,600 295A107,107 0,0 1,600 81zM600,139A49,49 0,0 1,600 237A49,49 0,0 1,600 139z"
+          android:strokeColor="#000" android:strokeWidth="3"/>
+    <path android:fillType="nonZero"
+          android:fillColor="#f00"
+          android:pathData="M950,81A107,107 0,0 1,950 295A107,107 0,0 1,950 81zM950,139A49,49 0,0 0,950 237A49,49 0,0 0,950 139z"
+          android:strokeColor="#000" android:strokeWidth="3"/>
+</vector>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/drawable/vector_icon_gradient_1.xml b/tests/tests/graphics/res/drawable/vector_icon_gradient_1.xml
new file mode 100644
index 0000000..d67aca7
--- /dev/null
+++ b/tests/tests/graphics/res/drawable/vector_icon_gradient_1.xml
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:height="64dp"
+        android:width="64dp"
+        android:viewportHeight="400"
+        android:viewportWidth="400" >
+
+<group android:name="backgroundGroup"
+       android:scaleX="0.5"
+       android:scaleY="0.5">
+    <path
+            android:name="background1"
+            android:fillColor="@color/fill_gradient_linear"
+            android:pathData="M 0,0 l 200,0 l 0, 200 l -200, 0 z" />
+    <path
+            android:name="background2"
+            android:fillColor="@color/fill_gradient_radial"
+            android:pathData="M 200,200 l 200,0 l 0, 200 l -200, 0 z" />
+    <path
+            android:name="background3"
+            android:fillColor="@color/fill_gradient_sweep"
+            android:pathData="M 400,400 l 200,0 l 0, 200 l -200, 0 z" />
+</group>
+<group
+        android:name="translateToCenterGroup"
+        android:translateX="50.0"
+        android:translateY="90.0" >
+    <path
+            android:name="twoLines"
+            android:pathData="@string/twoLinePathData"
+            android:strokeColor="@color/stroke_gradient"
+            android:strokeWidth="20" />
+
+    <group
+            android:name="rotationGroup"
+            android:pivotX="0.0"
+            android:pivotY="0.0"
+            android:rotation="-45.0">
+        <path
+                android:name="twoLines1"
+                android:pathData="@string/twoLinePathData"
+                android:strokeColor="@color/stroke_gradient"
+                android:strokeWidth="20" />
+
+        <group
+                android:name="translateGroup"
+                android:translateX="130.0"
+                android:translateY="160.0">
+            <group android:name="scaleGroup" >
+                <path
+                        android:name="twoLines3"
+                        android:pathData="@string/twoLinePathData"
+                        android:strokeColor="@color/stroke_gradient"
+                        android:strokeWidth="20" />
+            </group>
+        </group>
+
+        <group
+                android:name="translateGroupHalf"
+                android:translateX="65.0"
+                android:translateY="80.0">
+            <group android:name="scaleGroup" >
+                <path
+                        android:name="twoLines2"
+                        android:pathData="@string/twoLinePathData"
+                        android:fillColor="@color/fill_gradient_linear"
+                        android:strokeColor="@color/stroke_gradient"
+                        android:strokeWidth="20" />
+            </group>
+        </group>
+    </group>
+</group>
+
+</vector>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/drawable/vector_icon_gradient_1_clamp.xml b/tests/tests/graphics/res/drawable/vector_icon_gradient_1_clamp.xml
new file mode 100644
index 0000000..2fa440a
--- /dev/null
+++ b/tests/tests/graphics/res/drawable/vector_icon_gradient_1_clamp.xml
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:height="64dp"
+        android:width="64dp"
+        android:viewportHeight="400"
+        android:viewportWidth="400" >
+
+<group android:name="backgroundGroup"
+       android:scaleX="0.5"
+       android:scaleY="0.5">
+    <path
+            android:name="background1"
+            android:fillColor="@color/fill_gradient_linear_clamp"
+            android:pathData="M 0,0 l 200,0 l 0, 200 l -200, 0 z" />
+    <path
+            android:name="background2"
+            android:fillColor="@color/fill_gradient_radial_clamp"
+            android:pathData="M 200,200 l 200,0 l 0, 200 l -200, 0 z" />
+    <path
+            android:name="background3"
+            android:fillColor="@color/fill_gradient_sweep_clamp"
+            android:pathData="M 400,400 l 200,0 l 0, 200 l -200, 0 z" />
+</group>
+<group
+        android:name="translateToCenterGroup"
+        android:translateX="50.0"
+        android:translateY="90.0" >
+    <path
+            android:name="twoLines"
+            android:pathData="@string/twoLinePathData"
+            android:strokeColor="@color/stroke_gradient_clamp"
+            android:strokeWidth="20" />
+
+    <group
+            android:name="rotationGroup"
+            android:pivotX="0.0"
+            android:pivotY="0.0"
+            android:rotation="-45.0">
+        <path
+                android:name="twoLines1"
+                android:pathData="@string/twoLinePathData"
+                android:strokeColor="@color/stroke_gradient_clamp"
+                android:strokeWidth="20" />
+
+        <group
+                android:name="translateGroup"
+                android:translateX="130.0"
+                android:translateY="160.0">
+            <group android:name="scaleGroup" >
+                <path
+                        android:name="twoLines3"
+                        android:pathData="@string/twoLinePathData"
+                        android:strokeColor="@color/stroke_gradient_clamp"
+                        android:strokeWidth="20" />
+            </group>
+        </group>
+
+        <group
+                android:name="translateGroupHalf"
+                android:translateX="65.0"
+                android:translateY="80.0">
+            <group android:name="scaleGroup" >
+                <path
+                        android:name="twoLines2"
+                        android:pathData="@string/twoLinePathData"
+                        android:fillColor="@color/fill_gradient_linear_clamp"
+                        android:strokeColor="@color/stroke_gradient_clamp"
+                        android:strokeWidth="20" />
+            </group>
+        </group>
+    </group>
+</group>
+
+</vector>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/drawable/vector_icon_gradient_2.xml b/tests/tests/graphics/res/drawable/vector_icon_gradient_2.xml
new file mode 100644
index 0000000..abf3c7a
--- /dev/null
+++ b/tests/tests/graphics/res/drawable/vector_icon_gradient_2.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:height="64dp"
+        android:width="64dp"
+        android:viewportHeight="400"
+        android:viewportWidth="400" >
+
+<group android:name="backgroundGroup"
+       android:scaleX="0.5"
+       android:scaleY="0.5">
+    <path
+            android:name="background1"
+            android:fillColor="@color/fill_gradient_linear_item"
+            android:pathData="M 0,0 l 200,0 l 0, 200 l -200, 0 z" />
+    <path
+            android:name="background2"
+            android:fillColor="@color/fill_gradient_radial_item"
+            android:pathData="M 200,200 l 200,0 l 0, 200 l -200, 0 z" />
+    <path
+            android:name="background3"
+            android:fillColor="@color/fill_gradient_sweep_item"
+            android:pathData="M 400,400 l 200,0 l 0, 200 l -200, 0 z" />
+</group>
+<group
+        android:name="translateToCenterGroup"
+        android:translateX="50.0"
+        android:translateY="90.0" >
+    <path
+            android:name="twoLines"
+            android:pathData="@string/twoLinePathData"
+            android:strokeColor="@color/stroke_gradient_item"
+            android:strokeWidth="20" />
+
+    <group
+            android:name="rotationGroup"
+            android:pivotX="0.0"
+            android:pivotY="0.0"
+            android:rotation="-45.0">
+        <path
+                android:name="twoLines1"
+                android:pathData="@string/twoLinePathData"
+                android:strokeColor="@color/stroke_gradient_item"
+                android:strokeWidth="20" />
+
+        <group
+                android:name="translateGroup"
+                android:translateX="130.0"
+                android:translateY="160.0">
+            <group android:name="scaleGroup" >
+                <path
+                        android:name="twoLines3"
+                        android:pathData="@string/twoLinePathData"
+                        android:strokeColor="@color/stroke_gradient_item"
+                        android:strokeWidth="20" />
+            </group>
+        </group>
+
+        <group
+                android:name="translateGroupHalf"
+                android:translateX="65.0"
+                android:translateY="80.0">
+            <group android:name="scaleGroup" >
+                <path
+                        android:name="twoLines2"
+                        android:pathData="@string/twoLinePathData"
+                        android:strokeColor="@color/stroke_gradient_item"
+                        android:strokeWidth="20" />
+            </group>
+        </group>
+    </group>
+</group>
+
+</vector>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/drawable/vector_icon_gradient_2_repeat.xml b/tests/tests/graphics/res/drawable/vector_icon_gradient_2_repeat.xml
new file mode 100644
index 0000000..5a43f80
--- /dev/null
+++ b/tests/tests/graphics/res/drawable/vector_icon_gradient_2_repeat.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:height="64dp"
+        android:width="64dp"
+        android:viewportHeight="400"
+        android:viewportWidth="400" >
+
+<group android:name="backgroundGroup"
+       android:scaleX="0.5"
+       android:scaleY="0.5">
+    <path
+            android:name="background1"
+            android:fillColor="@color/fill_gradient_linear_item_repeat"
+            android:pathData="M 0,0 l 200,0 l 0, 200 l -200, 0 z" />
+    <path
+            android:name="background2"
+            android:fillColor="@color/fill_gradient_radial_item_repeat"
+            android:pathData="M 200,200 l 200,0 l 0, 200 l -200, 0 z" />
+    <path
+            android:name="background3"
+            android:fillColor="@color/fill_gradient_sweep_item_repeat"
+            android:pathData="M 400,400 l 200,0 l 0, 200 l -200, 0 z" />
+</group>
+<group
+        android:name="translateToCenterGroup"
+        android:translateX="50.0"
+        android:translateY="90.0" >
+    <path
+            android:name="twoLines"
+            android:pathData="@string/twoLinePathData"
+            android:strokeColor="@color/stroke_gradient_item_repeat"
+            android:strokeWidth="20" />
+
+    <group
+            android:name="rotationGroup"
+            android:pivotX="0.0"
+            android:pivotY="0.0"
+            android:rotation="-45.0">
+        <path
+                android:name="twoLines1"
+                android:pathData="@string/twoLinePathData"
+                android:strokeColor="@color/stroke_gradient_item_repeat"
+                android:strokeWidth="20" />
+
+        <group
+                android:name="translateGroup"
+                android:translateX="130.0"
+                android:translateY="160.0">
+            <group android:name="scaleGroup" >
+                <path
+                        android:name="twoLines3"
+                        android:pathData="@string/twoLinePathData"
+                        android:strokeColor="@color/stroke_gradient_item_repeat"
+                        android:strokeWidth="20" />
+            </group>
+        </group>
+
+        <group
+                android:name="translateGroupHalf"
+                android:translateX="65.0"
+                android:translateY="80.0">
+            <group android:name="scaleGroup" >
+                <path
+                        android:name="twoLines2"
+                        android:pathData="@string/twoLinePathData"
+                        android:strokeColor="@color/stroke_gradient_item_repeat"
+                        android:strokeWidth="20" />
+            </group>
+        </group>
+    </group>
+</group>
+
+</vector>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/drawable/vector_icon_gradient_3.xml b/tests/tests/graphics/res/drawable/vector_icon_gradient_3.xml
new file mode 100644
index 0000000..5f9726f
--- /dev/null
+++ b/tests/tests/graphics/res/drawable/vector_icon_gradient_3.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:height="64dp"
+        android:width="64dp"
+        android:viewportHeight="400"
+        android:viewportWidth="400" >
+
+<group android:name="backgroundGroup"
+       android:scaleX="0.5"
+       android:scaleY="0.5">
+    <path
+            android:name="background1"
+            android:fillColor="@color/fill_gradient_linear_item_overlap"
+            android:pathData="M 0,0 l 200,0 l 0, 200 l -200, 0 z" />
+    <path
+            android:name="background2"
+            android:fillColor="@color/fill_gradient_radial_item_short"
+            android:pathData="M 200,200 l 200,0 l 0, 200 l -200, 0 z" />
+    <path
+            android:name="background3"
+            android:fillColor="@color/fill_gradient_sweep_item_long"
+            android:pathData="M 400,400 l 200,0 l 0, 200 l -200, 0 z" />
+</group>
+<group
+        android:name="translateToCenterGroup"
+        android:translateX="50.0"
+        android:translateY="90.0" >
+    <path
+            android:name="twoLines"
+            android:pathData="@string/twoLinePathData"
+            android:strokeColor="@color/stroke_gradient_item_alpha"
+            android:strokeWidth="20" />
+
+    <group
+            android:name="rotationGroup"
+            android:pivotX="0.0"
+            android:pivotY="0.0"
+            android:rotation="-45.0">
+        <path
+                android:name="twoLines1"
+                android:pathData="@string/twoLinePathData"
+                android:strokeColor="@color/stroke_gradient_item_alpha"
+                android:strokeWidth="20" />
+
+        <group
+                android:name="translateGroup"
+                android:translateX="130.0"
+                android:translateY="160.0">
+            <group android:name="scaleGroup" >
+                <path
+                        android:name="twoLines3"
+                        android:pathData="@string/twoLinePathData"
+                        android:strokeColor="@color/stroke_gradient_item_alpha"
+                        android:strokeWidth="20" />
+            </group>
+        </group>
+
+        <group
+                android:name="translateGroupHalf"
+                android:translateX="65.0"
+                android:translateY="80.0">
+            <group android:name="scaleGroup" >
+                <path
+                        android:name="twoLines2"
+                        android:pathData="@string/twoLinePathData"
+                        android:strokeColor="@color/stroke_gradient_item_alpha"
+                        android:strokeWidth="20" />
+            </group>
+        </group>
+    </group>
+</group>
+
+</vector>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/drawable/vector_icon_gradient_3_mirror.xml b/tests/tests/graphics/res/drawable/vector_icon_gradient_3_mirror.xml
new file mode 100644
index 0000000..e8de7c2
--- /dev/null
+++ b/tests/tests/graphics/res/drawable/vector_icon_gradient_3_mirror.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:height="64dp"
+        android:width="64dp"
+        android:viewportHeight="400"
+        android:viewportWidth="400" >
+
+<group android:name="backgroundGroup"
+       android:scaleX="0.5"
+       android:scaleY="0.5">
+    <path
+            android:name="background1"
+            android:fillColor="@color/fill_gradient_linear_item_overlap_mirror"
+            android:pathData="M 0,0 l 200,0 l 0, 200 l -200, 0 z" />
+    <path
+            android:name="background2"
+            android:fillColor="@color/fill_gradient_radial_item_short_mirror"
+            android:pathData="M 200,200 l 200,0 l 0, 200 l -200, 0 z" />
+    <path
+            android:name="background3"
+            android:fillColor="@color/fill_gradient_sweep_item_long_mirror"
+            android:pathData="M 400,400 l 200,0 l 0, 200 l -200, 0 z" />
+</group>
+<group
+        android:name="translateToCenterGroup"
+        android:translateX="50.0"
+        android:translateY="90.0" >
+    <path
+            android:name="twoLines"
+            android:pathData="@string/twoLinePathData"
+            android:strokeColor="@color/stroke_gradient_item_alpha_mirror"
+            android:strokeWidth="20" />
+
+    <group
+            android:name="rotationGroup"
+            android:pivotX="0.0"
+            android:pivotY="0.0"
+            android:rotation="-45.0">
+        <path
+                android:name="twoLines1"
+                android:pathData="@string/twoLinePathData"
+                android:strokeColor="@color/stroke_gradient_item_alpha_mirror"
+                android:strokeWidth="20" />
+
+        <group
+                android:name="translateGroup"
+                android:translateX="130.0"
+                android:translateY="160.0">
+            <group android:name="scaleGroup" >
+                <path
+                        android:name="twoLines3"
+                        android:pathData="@string/twoLinePathData"
+                        android:strokeColor="@color/stroke_gradient_item_alpha_mirror"
+                        android:strokeWidth="20" />
+            </group>
+        </group>
+
+        <group
+                android:name="translateGroupHalf"
+                android:translateX="65.0"
+                android:translateY="80.0">
+            <group android:name="scaleGroup" >
+                <path
+                        android:name="twoLines2"
+                        android:pathData="@string/twoLinePathData"
+                        android:strokeColor="@color/stroke_gradient_item_alpha"
+                        android:strokeWidth="20" />
+            </group>
+        </group>
+    </group>
+</group>
+
+</vector>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/drawable/vector_icon_implicit_lineto.xml b/tests/tests/graphics/res/drawable/vector_icon_implicit_lineto.xml
new file mode 100644
index 0000000..d7b133b
--- /dev/null
+++ b/tests/tests/graphics/res/drawable/vector_icon_implicit_lineto.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:height="64dp"
+        android:width="64dp"
+        android:viewportHeight="64"
+        android:viewportWidth="64" >
+
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="m0,0 32,0 0,32 -32,0 0,-32z" />
+
+</vector>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/drawable/vector_icon_state_list.xml b/tests/tests/graphics/res/drawable/vector_icon_state_list.xml
new file mode 100644
index 0000000..65aa967
--- /dev/null
+++ b/tests/tests/graphics/res/drawable/vector_icon_state_list.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:height="64dp"
+        android:width="64dp"
+        android:viewportHeight="24"
+        android:viewportWidth="24" >
+
+    <path
+        android:fillColor="@color/vector_icon_fill_state_list"
+        android:strokeColor="@color/vector_icon_stroke_state_list"
+        android:strokeWidth="3"
+        android:pathData="M16.0,5.0c-1.955.0 -3.83,1.268 -4.5,3.0c-0.67-1.732 -2.547-3.0 -4.5-3.0C4.4570007,5.0 2.5,6.931999 2.5,9.5c0.0,3.529 3.793,6.258 9.0,11.5c5.207-5.242 9.0-7.971 9.0-11.5C20.5,6.931999 18.543,5.0 16.0,5.0z"/>
+
+</vector>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/drawable/vector_icon_state_list_2.xml b/tests/tests/graphics/res/drawable/vector_icon_state_list_2.xml
new file mode 100644
index 0000000..65aa967
--- /dev/null
+++ b/tests/tests/graphics/res/drawable/vector_icon_state_list_2.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:height="64dp"
+        android:width="64dp"
+        android:viewportHeight="24"
+        android:viewportWidth="24" >
+
+    <path
+        android:fillColor="@color/vector_icon_fill_state_list"
+        android:strokeColor="@color/vector_icon_stroke_state_list"
+        android:strokeWidth="3"
+        android:pathData="M16.0,5.0c-1.955.0 -3.83,1.268 -4.5,3.0c-0.67-1.732 -2.547-3.0 -4.5-3.0C4.4570007,5.0 2.5,6.931999 2.5,9.5c0.0,3.529 3.793,6.258 9.0,11.5c5.207-5.242 9.0-7.971 9.0-11.5C20.5,6.931999 18.543,5.0 16.0,5.0z"/>
+
+</vector>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/interpolator/avd_single_frame_interpolator.xml b/tests/tests/graphics/res/interpolator/avd_single_frame_interpolator.xml
new file mode 100644
index 0000000..d3728c4
--- /dev/null
+++ b/tests/tests/graphics/res/interpolator/avd_single_frame_interpolator.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<pathInterpolator
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0.0,0.0 c 0.4,0.0 0.4,1.0 1.0,1.0" />
diff --git a/tests/tests/graphics/res/layout/animated_vector_drawable_source.xml b/tests/tests/graphics/res/layout/animated_vector_drawable_source.xml
new file mode 100644
index 0000000..57f268f
--- /dev/null
+++ b/tests/tests/graphics/res/layout/animated_vector_drawable_source.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Demonstrates a simple layout with AnimatedVectorDrawable in an ImageView. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content">
+
+    <ImageView
+        android:id = "@+id/avd_view"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:src="@drawable/animation_vector_drawable_grouping_1"/>
+
+</LinearLayout>
diff --git a/tests/tests/graphics/res/values/strings.xml b/tests/tests/graphics/res/values/strings.xml
index c167278..8208b19 100644
--- a/tests/tests/graphics/res/values/strings.xml
+++ b/tests/tests/graphics/res/values/strings.xml
@@ -176,4 +176,5 @@
 text, I would love to see the kind of devices you guys now use! Guys, maybe some devices need longer string!
 I think so, so how about double this string, like copy and paste! </string>
     <string name="rectangle200">"M 0,0 l 200,0 l 0, 200 l -200, 0 z"</string>
+    <string name="twoLinePathData">"M 0,0 v 100 M 0,0 h 100"</string>
 </resources>
diff --git a/tests/tests/graphics/res/xml/scaledrawable_level.xml b/tests/tests/graphics/res/xml/scaledrawable_level.xml
new file mode 100644
index 0000000..6a7ec74
--- /dev/null
+++ b/tests/tests/graphics/res/xml/scaledrawable_level.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<alias xmlns:android="http://schemas.android.com/apk/res/android">
+    <scale_allattrs>
+        <scale xmlns:android="http://schemas.android.com/apk/res/android"
+            android:fromXScale="1.0"
+            android:toXScale="1.4"
+            android:fromYScale="1.0"
+            android:toYScale="0.6"
+            android:drawable="@drawable/testimage"
+            android:level="5000" />
+    </scale_allattrs>
+</alias>
\ No newline at end of file
diff --git a/tests/tests/graphics/src/android/graphics/cts/AvoidXfermodeTest.java b/tests/tests/graphics/src/android/graphics/cts/AvoidXfermodeTest.java
deleted file mode 100644
index beb3621..0000000
--- a/tests/tests/graphics/src/android/graphics/cts/AvoidXfermodeTest.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.graphics.cts;
-
-import android.graphics.AvoidXfermode;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
-import android.graphics.Bitmap.Config;
-
-import junit.framework.TestCase;
-
-public class AvoidXfermodeTest extends TestCase {
-    /*
-     * ToBeFixed: This test ought to work with a TOLERANCE of 0. See bug 2034547.
-     */
-    private static final int TOLERANCE = 255;
-    private static final int BASE_SIZE = 50;
-    private static final int BITMAP_HEIGHT = BASE_SIZE * 2;
-    private static final int BITMAP_WIDTH = BASE_SIZE * 2;
-
-    public void testAvoidXfermode() {
-        Paint greenPaint;
-        Paint redAvoidingGreenPaint;
-        Paint blueTargetingGreenPaint;
-        greenPaint = new Paint();
-        greenPaint.setColor(Color.GREEN);
-        AvoidXfermode avoidMode =
-            new AvoidXfermode(greenPaint.getColor(), TOLERANCE, AvoidXfermode.Mode.AVOID);
-        redAvoidingGreenPaint = new Paint();
-        redAvoidingGreenPaint.setColor(Color.RED);
-        redAvoidingGreenPaint.setXfermode(avoidMode);
-        AvoidXfermode targetMode =
-            new AvoidXfermode(greenPaint.getColor(), TOLERANCE, AvoidXfermode.Mode.TARGET);
-        blueTargetingGreenPaint = new Paint();
-        blueTargetingGreenPaint.setColor(Color.BLUE);
-        blueTargetingGreenPaint.setXfermode(targetMode);
-
-        Bitmap b = Bitmap.createBitmap(BITMAP_WIDTH, BITMAP_HEIGHT, Config.ARGB_8888);
-        b.eraseColor(Color.BLACK);
-        Canvas canvas = new Canvas(b);
-        // vertical bar on the left
-        canvas.drawRect(0f, 0f, BASE_SIZE, 2 * BASE_SIZE, greenPaint);
-        // horizontal bar on top
-        canvas.drawRect(0f, 0f, 2 * BASE_SIZE, BASE_SIZE, redAvoidingGreenPaint);
-        // horizontal bar at bottom
-        canvas.drawRect(0f, BASE_SIZE, 2 * BASE_SIZE, 2 * BASE_SIZE, blueTargetingGreenPaint);
-
-        assertEquals(Color.GREEN, b.getPixel(BASE_SIZE / 2, BASE_SIZE / 2));
-        assertEquals(Color.RED, b.getPixel(BASE_SIZE + BASE_SIZE / 2, BASE_SIZE / 2));
-        assertEquals(Color.BLUE, b.getPixel(BASE_SIZE / 2, BASE_SIZE + BASE_SIZE / 2));
-        assertEquals(Color.BLACK, b.getPixel(BASE_SIZE + BASE_SIZE / 2, BASE_SIZE + BASE_SIZE / 2));
-    }
-}
diff --git a/tests/tests/graphics/src/android/graphics/cts/AvoidXfermode_ModeTest.java b/tests/tests/graphics/src/android/graphics/cts/AvoidXfermode_ModeTest.java
deleted file mode 100644
index 8704e6f..0000000
--- a/tests/tests/graphics/src/android/graphics/cts/AvoidXfermode_ModeTest.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.graphics.cts;
-
-import android.graphics.AvoidXfermode;
-import android.graphics.AvoidXfermode.Mode;
-import android.test.AndroidTestCase;
-
-public class AvoidXfermode_ModeTest extends AndroidTestCase{
-
-    public void testValueOf(){
-        assertEquals(Mode.AVOID, Mode.valueOf("AVOID"));
-        assertEquals(Mode.TARGET, Mode.valueOf("TARGET"));
-    }
-
-    public void testValues(){
-        Mode[] mode = Mode.values();
-
-        assertEquals(2, mode.length);
-        assertEquals(Mode.AVOID, mode[0]);
-        assertEquals(Mode.TARGET, mode[1]);
-
-        //Mode is used as a argument here for all the methods that use it
-        assertNotNull(new AvoidXfermode(10, 24, Mode.AVOID));
-        assertNotNull(new AvoidXfermode(10, 24, Mode.TARGET));
-    }
-}
diff --git a/tests/tests/graphics/src/android/graphics/cts/BitmapFactoryTest.java b/tests/tests/graphics/src/android/graphics/cts/BitmapFactoryTest.java
index 2314ffb..6e0f277 100644
--- a/tests/tests/graphics/src/android/graphics/cts/BitmapFactoryTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/BitmapFactoryTest.java
@@ -16,7 +16,7 @@
 
 package android.graphics.cts;
 
-import com.android.cts.graphics.R;
+import android.graphics.cts.R;
 
 
 import android.content.res.Resources;
@@ -27,6 +27,7 @@
 import android.graphics.Bitmap.CompressFormat;
 import android.graphics.Bitmap.Config;
 import android.graphics.BitmapFactory.Options;
+import android.os.Parcel;
 import android.os.ParcelFileDescriptor;
 import android.test.InstrumentationTestCase;
 import android.util.DisplayMetrics;
@@ -64,12 +65,10 @@
     private static int HEIGHTS[] = new int[] { 960, 480, 240, 240, 480 };
 
     // Configurations for BitmapFactory.Options
-    private static Config[] COLOR_CONFIGS = new Config[] {Config.ARGB_8888, Config.RGB_565,
-        Config.ARGB_4444};
+    private static Config[] COLOR_CONFIGS = new Config[] {Config.ARGB_8888, Config.RGB_565};
     private static int[] COLOR_TOLS = new int[] {16, 49, 576};
 
-    private static Config[] COLOR_CONFIGS_RGBA = new Config[] {Config.ARGB_8888,
-        Config.ARGB_4444};
+    private static Config[] COLOR_CONFIGS_RGBA = new Config[] {Config.ARGB_8888};
     private static int[] COLOR_TOLS_RGBA = new int[] {72, 124};
 
     private static int[] RAW_COLORS = new int[] {
@@ -573,6 +572,142 @@
         verifyScaled(BitmapFactory.decodeStream(obtainInputStream(), null, scaledOpt));
     }
 
+    // Test that writing an index8 bitmap to a Parcel succeeds.
+    public void testParcel() {
+        // Turn off scaling, which would convert to an 8888 bitmap, which does not expose
+        // the bug.
+        BitmapFactory.Options opts = new BitmapFactory.Options();
+        opts.inScaled = false;
+        Bitmap b = BitmapFactory.decodeResource(mRes, R.drawable.gif_test, opts);
+        assertNotNull(b);
+
+        // index8 has no Java equivalent, so the Config will be null.
+        assertNull(b.getConfig());
+
+        Parcel p = Parcel.obtain();
+        b.writeToParcel(p, 0);
+
+        p.setDataPosition(0);
+        Bitmap b2 = Bitmap.CREATOR.createFromParcel(p);
+        compareBitmaps(b, b2, 0, true, true);
+
+        // When this failed previously, the bitmap was missing a colortable, resulting in a crash
+        // attempting to compress by dereferencing a null pointer. Compress to verify that we do
+        // not crash, but succeed instead.
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        assertTrue(b2.compress(Bitmap.CompressFormat.JPEG, 50, baos));
+    }
+
+    public void testConfigs() {
+        // The output Config of a BitmapFactory decode depends on the request from the
+        // client and the properties of the image to be decoded.
+        //
+        // Options.inPreferredConfig = Config.ARGB_8888
+        //     This is the default value of inPreferredConfig.  In this case, the image
+        //     will always be decoded to Config.ARGB_8888.
+        // Options.inPreferredConfig = Config.RGB_565
+        //     If the encoded image is opaque, we will decode to Config.RGB_565,
+        //     otherwise we will decode to whichever color type is the most natural match
+        //     for the encoded data.
+        // Options.inPreferredConfig = Config.ARGB_4444
+        //     This is deprecated and will always decode to Config.ARGB_8888.
+        // Options.inPreferredConfig = Config.ALPHA_8
+        //     If the encoded image is gray, we will decode to 8-bit grayscale values
+        //     and indicate that the output bitmap is Config.ALPHA_8.  This is somewhat
+        //     misleading because the image is really opaque and grayscale, but we are
+        //     labeling each pixel as if it is a translucency (alpha) value.  If the
+        //     encoded image is not gray, we will decode to whichever color type is the
+        //     most natural match for the encoded data.
+        // Options.inPreferredConfig = null
+        //     We will decode to whichever Config is the most natural match with the
+        //     encoded data.  This could be 8-bit indices into a color table (call this
+        //     INDEX_8), ALPHA_8 (gray), or ARGB_8888.
+        //
+        // This test ensures that images are decoded to the intended Config and that the
+        // decodes match regardless of the Config.
+        decodeConfigs(R.drawable.alpha, 31, 31, true, false, false);
+        decodeConfigs(R.drawable.baseline_jpeg, 1280, 960, false, false, false);
+        decodeConfigs(R.drawable.bmp_test, 320, 240, false, false, false);
+        decodeConfigs(R.drawable.scaled2, 6, 8, false, false, true);
+        decodeConfigs(R.drawable.grayscale_jpg, 128, 128, false, true, false);
+        decodeConfigs(R.drawable.grayscale_png, 128, 128, false, true, false);
+    }
+
+    private void decodeConfigs(int id, int width, int height, boolean hasAlpha, boolean isGray,
+            boolean hasColorTable) {
+        Options opts = new BitmapFactory.Options();
+        opts.inScaled = false;
+        assertEquals(Config.ARGB_8888, opts.inPreferredConfig);
+        Bitmap reference = BitmapFactory.decodeResource(mRes, id, opts);
+        assertNotNull(reference);
+        assertEquals(width, reference.getWidth());
+        assertEquals(height, reference.getHeight());
+        assertEquals(Config.ARGB_8888, reference.getConfig());
+
+        opts.inPreferredConfig = Config.ARGB_4444;
+        Bitmap argb4444 = BitmapFactory.decodeResource(mRes, id, opts);
+        assertNotNull(argb4444);
+        assertEquals(width, argb4444.getWidth());
+        assertEquals(height, argb4444.getHeight());
+        // ARGB_4444 is deprecated and we should decode to ARGB_8888.
+        assertEquals(Config.ARGB_8888, argb4444.getConfig());
+        compareBitmaps(reference, argb4444, 0, true, true);
+
+        opts.inPreferredConfig = Config.RGB_565;
+        Bitmap rgb565 = BitmapFactory.decodeResource(mRes, id, opts);
+        assertNotNull(rgb565);
+        assertEquals(width, rgb565.getWidth());
+        assertEquals(height, rgb565.getHeight());
+        if (!hasAlpha) {
+            assertEquals(Config.RGB_565, rgb565.getConfig());
+            // Convert the RGB_565 bitmap to ARGB_8888 and test that it is similar to
+            // the reference.  We lose information when decoding to 565, so there must
+            // be some tolerance.  The tolerance is intentionally loose to allow us some
+            // flexibility regarding if we dither and how we color convert.
+            compareBitmaps(reference, rgb565.copy(Config.ARGB_8888, false), 30, true, true);
+        }
+
+        opts.inPreferredConfig = Config.ALPHA_8;
+        Bitmap alpha8 = BitmapFactory.decodeResource(mRes, id, opts);
+        assertNotNull(alpha8);
+        assertEquals(width, reference.getWidth());
+        assertEquals(height, reference.getHeight());
+        if (isGray) {
+            assertEquals(Config.ALPHA_8, alpha8.getConfig());
+            // Convert the ALPHA_8 bitmap to ARGB_8888 and test that it is identical to
+            // the reference.  We must do this manually because we are abusing ALPHA_8
+            // in order to represent grayscale.
+            compareBitmaps(reference, grayToARGB(alpha8), 0, true, true);
+        }
+
+        // Setting inPreferredConfig to null selects the most natural color type for
+        // the encoded data.  If the image has a color table, this should be INDEX_8.
+        // If we decode to INDEX_8, the output bitmap will report that the Config is
+        // null.
+        opts.inPreferredConfig = null;
+        Bitmap index8 = BitmapFactory.decodeResource(mRes, id, opts);
+        assertNotNull(index8);
+        assertEquals(width, index8.getWidth());
+        assertEquals(height, index8.getHeight());
+        if (hasColorTable) {
+            assertEquals(null, index8.getConfig());
+            // Convert the INDEX_8 bitmap to ARGB_8888 and test that it is identical to
+            // the reference.
+            compareBitmaps(reference, index8.copy(Config.ARGB_8888, false), 0, true, true);
+        }
+    }
+
+    private Bitmap grayToARGB(Bitmap gray) {
+        Bitmap argb = Bitmap.createBitmap(gray.getWidth(), gray.getHeight(), Config.ARGB_8888);
+        for (int y = 0; y < argb.getHeight(); y++) {
+            for (int x = 0; x < argb.getWidth(); x++) {
+                int grayByte = Color.alpha(gray.getPixel(x, y));
+                argb.setPixel(x, y, Color.rgb(grayByte, grayByte, grayByte));
+            }
+        }
+        return argb;
+    }
+
     private byte[] obtainArray() {
         ByteArrayOutputStream stm = new ByteArrayOutputStream();
         Options opt = new BitmapFactory.Options();
diff --git a/tests/tests/graphics/src/android/graphics/cts/BitmapRegionDecoderTest.java b/tests/tests/graphics/src/android/graphics/cts/BitmapRegionDecoderTest.java
index adce1c4..328d9ed 100644
--- a/tests/tests/graphics/src/android/graphics/cts/BitmapRegionDecoderTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/BitmapRegionDecoderTest.java
@@ -29,7 +29,7 @@
 import android.test.InstrumentationTestCase;
 import android.util.Log;
 
-import com.android.cts.graphics.R;
+import android.graphics.cts.R;
 
 
 import java.io.ByteArrayOutputStream;
@@ -304,6 +304,83 @@
         }
     }
 
+    // The documentation for BitmapRegionDecoder guarantees that, when reusing a
+    // bitmap, "the provided Bitmap's width, height, and Bitmap.Config will not
+    // be changed".  If the inBitmap is too small, decoded content will be
+    // clipped into inBitmap.  Here we test that:
+    //     (1) If inBitmap is specified, it is always used.
+    //     (2) The width, height, and Config of inBitmap are never changed.
+    //     (3) All of the pixels decoded into inBitmap exactly match the pixels
+    //         of a decode where inBitmap is NULL.
+    public void testInBitmapReuse() throws IOException {
+        Options defaultOpts = new BitmapFactory.Options();
+        Options reuseOpts = new BitmapFactory.Options();
+        Rect subset = new Rect(0, 0, TILE_SIZE, TILE_SIZE);
+
+        for (int i = 0; i < NUM_TEST_IMAGES; i++) {
+            InputStream is = obtainInputStream(RES_IDS[i]);
+            BitmapRegionDecoder decoder = BitmapRegionDecoder.newInstance(is, false);
+            for (int j = 0; j < SAMPLESIZES.length; j++) {
+                int sampleSize = SAMPLESIZES[j];
+                defaultOpts.inSampleSize = sampleSize;
+                reuseOpts.inSampleSize = sampleSize;
+
+                // We don't need to worry about rounding here because sampleSize
+                // divides evenly into TILE_SIZE.
+                assertEquals(0, TILE_SIZE % sampleSize);
+                int scaledDim = TILE_SIZE / sampleSize;
+                int chunkSize = scaledDim / 2;
+                for (int k = 0; k < COLOR_CONFIGS.length; k++) {
+                    Config config = COLOR_CONFIGS[k];
+                    defaultOpts.inPreferredConfig = config;
+                    reuseOpts.inPreferredConfig = config;
+
+                    // For both the width and the height of inBitmap, we test three
+                    // interesting cases:
+                    // (1) inBitmap dimension is smaller than scaledDim.  The decoded
+                    //     pixels that fit inside inBitmap should exactly match the
+                    //     corresponding decoded pixels from the same region decode,
+                    //     performed without an inBitmap.  The pixels that do not fit
+                    //     inside inBitmap should be clipped.
+                    // (2) inBitmap dimension matches scaledDim.  After the decode,
+                    //     the pixels and dimensions of inBitmap should exactly match
+                    //     those of the result bitmap of the same region decode,
+                    //     performed without an inBitmap.
+                    // (3) inBitmap dimension is larger than scaledDim.  After the
+                    //     decode, inBitmap should contain decoded pixels for the
+                    //     entire region, exactly matching the decoded pixels
+                    //     produced when inBitmap is not specified.  The additional
+                    //     pixels in inBitmap are left the same as before the decode.
+                    for (int w = chunkSize; w <= 3 * chunkSize; w += chunkSize) {
+                        for (int h = chunkSize; h <= 3 * chunkSize; h += chunkSize) {
+                            // Decode reusing inBitmap.
+                            reuseOpts.inBitmap = Bitmap.createBitmap(w, h, config);
+                            Bitmap reuseResult = decoder.decodeRegion(subset, reuseOpts);
+                            assertSame(reuseOpts.inBitmap, reuseResult);
+                            assertEquals(reuseResult.getWidth(), w);
+                            assertEquals(reuseResult.getHeight(), h);
+                            assertEquals(reuseResult.getConfig(), config);
+
+                            // Decode into a new bitmap.
+                            Bitmap defaultResult = decoder.decodeRegion(subset, defaultOpts);
+                            assertEquals(defaultResult.getWidth(), scaledDim);
+                            assertEquals(defaultResult.getHeight(), scaledDim);
+
+                            // Ensure that the decoded pixels of reuseResult and defaultResult
+                            // are identical.
+                            int cropWidth = Math.min(w, scaledDim);
+                            int cropHeight = Math.min(h, scaledDim);
+                            Rect crop = new Rect(0 ,0, cropWidth, cropHeight);
+                            Bitmap reuseCropped = cropBitmap(reuseResult, crop);
+                            Bitmap defaultCropped = cropBitmap(defaultResult, crop);
+                            compareBitmaps(reuseCropped, defaultCropped, 0, true);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
     private void compareRegionByRegion(BitmapRegionDecoder decoder,
             Options opts, int mseMargin, Bitmap wholeImage) {
         int width = decoder.getWidth();
diff --git a/tests/tests/graphics/src/android/graphics/cts/BitmapTest.java b/tests/tests/graphics/src/android/graphics/cts/BitmapTest.java
index 07e65d2..f820771 100644
--- a/tests/tests/graphics/src/android/graphics/cts/BitmapTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/BitmapTest.java
@@ -15,7 +15,7 @@
  */
 package android.graphics.cts;
 
-import com.android.cts.graphics.R;
+import android.graphics.cts.R;
 
 
 import android.content.res.Resources;
diff --git a/tests/tests/graphics/src/android/graphics/cts/CanvasTest.java b/tests/tests/graphics/src/android/graphics/cts/CanvasTest.java
index 1dd6777..dee217b 100644
--- a/tests/tests/graphics/src/android/graphics/cts/CanvasTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/CanvasTest.java
@@ -41,7 +41,7 @@
 import android.text.SpannableStringBuilder;
 import android.text.SpannedString;
 
-import com.android.cts.graphics.R;
+import android.graphics.cts.R;
 
 import java.util.Vector;
 
@@ -348,6 +348,117 @@
         verifySaveFlagsSequence(flags);
     }
 
+    // This test exercises the saveLayer flag that preserves the clip
+    // state across the matching restore call boundary. This is a vanilla
+    // test and doesn't exercise any interaction between the clip stack
+    // and SkCanvas' deferred save/restore system.
+    public void testSaveFlags9() {
+        Rect clip0 = new Rect();
+        assertTrue(mCanvas.getClipBounds(clip0));
+
+        mCanvas.save(Canvas.MATRIX_SAVE_FLAG);
+
+            // All clip elements should be preserved after restore
+            mCanvas.clipRect(0, 0, BITMAP_WIDTH / 2, BITMAP_HEIGHT);
+            Path path = new Path();
+            path.addOval(0.25f * BITMAP_WIDTH, 0.25f * BITMAP_HEIGHT,
+                         0.75f * BITMAP_WIDTH, 0.75f * BITMAP_HEIGHT,
+                         Path.Direction.CW);
+            mCanvas.clipPath(path);
+            mCanvas.clipRect(0, 0, BITMAP_WIDTH, BITMAP_HEIGHT / 2);
+
+            Rect clip1 = new Rect();
+            assertTrue(mCanvas.getClipBounds(clip1));
+            assertTrue(clip1 != clip0);
+            assertTrue(clip0.contains(clip1));
+
+        mCanvas.restore();
+
+        Rect clip2 = new Rect();
+        assertTrue(mCanvas.getClipBounds(clip2));
+        assertEquals(clip2, clip1);
+    }
+
+    // This test exercises the saveLayer MATRIX_SAVE_FLAG flag and its
+    // interaction with the clip stack and SkCanvas deferred save/restore
+    // system.
+    public void testSaveFlags10() {
+        RectF rect1 = new RectF(0, 0, BITMAP_WIDTH / 2, BITMAP_HEIGHT);
+        RectF rect2 = new RectF(0, 0, BITMAP_WIDTH, BITMAP_HEIGHT / 2);
+        Path path = new Path();
+        path.addOval(0.25f * BITMAP_WIDTH, 0.25f * BITMAP_HEIGHT,
+                     0.75f * BITMAP_WIDTH, 0.75f * BITMAP_HEIGHT,
+                     Path.Direction.CW);
+
+        Rect clip0 = new Rect();
+        assertTrue(mCanvas.getClipBounds(clip0));
+
+        // Exercise various Canvas lazy-save interactions.
+        mCanvas.save();
+            mCanvas.save();
+                mCanvas.clipRect(rect1);
+                mCanvas.clipPath(path);
+
+                Rect clip1 = new Rect();
+                assertTrue(mCanvas.getClipBounds(clip1));
+                assertTrue(clip1 != clip0);
+
+                mCanvas.save(Canvas.MATRIX_SAVE_FLAG);
+                    mCanvas.save(Canvas.MATRIX_SAVE_FLAG);
+                        mCanvas.clipRect(rect2);
+                        mCanvas.clipPath(path);
+
+                        Rect clip2 = new Rect();
+                        assertTrue(mCanvas.getClipBounds(clip2));
+                        assertTrue(clip2 != clip1);
+                        assertTrue(clip2 != clip0);
+
+                        mCanvas.save();
+                            mCanvas.translate(10, 5);
+                            mCanvas.save(Canvas.MATRIX_SAVE_FLAG);
+                                // An uncommitted save/restore frame: exercises
+                                // the partial save emulation, ensuring there
+                                // are no side effects.
+                                Rect clip3 = new Rect();
+                                assertTrue(mCanvas.getClipBounds(clip3));
+                                clip3.offset(10, 5); // adjust for local offset
+                                assertEquals(clip3, clip2);
+                            mCanvas.restore();
+
+                            Rect clip4 = new Rect();
+                            assertTrue(mCanvas.getClipBounds(clip4));
+                            clip4.offset(10, 5); // adjust for local offset
+                            assertEquals(clip4, clip2);
+                        mCanvas.restore();
+
+                        Rect clip5 = new Rect();
+                        assertTrue(mCanvas.getClipBounds(clip5));
+                        assertEquals(clip5, clip2);
+                    mCanvas.restore();
+
+                    // clip2 survives the preceding restore
+                    Rect clip6 = new Rect();
+                    assertTrue(mCanvas.getClipBounds(clip6));
+                    assertEquals(clip6, clip2);
+                mCanvas.restore();
+
+                // clip2 also survives the preceding restore
+                Rect clip7 = new Rect();
+                assertTrue(mCanvas.getClipBounds(clip7));
+                assertEquals(clip7, clip2);
+            mCanvas.restore();
+
+            // clip1 does _not_ survive the preceding restore
+            Rect clip8 = new Rect();
+            assertTrue(mCanvas.getClipBounds(clip8));
+            assertEquals(clip8, clip0);
+        mCanvas.restore();
+
+        Rect clip9 = new Rect();
+        assertTrue(mCanvas.getClipBounds(clip9));
+        assertEquals(clip9, clip0);
+    }
+
     public void testSaveLayer1() {
         final Paint p = new Paint();
         final RectF rF = new RectF(0, 10, 31, 0);
diff --git a/tests/tests/graphics/src/android/graphics/cts/ComposeShaderTest.java b/tests/tests/graphics/src/android/graphics/cts/ComposeShaderTest.java
index 1a2164a..b44faff 100644
--- a/tests/tests/graphics/src/android/graphics/cts/ComposeShaderTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/ComposeShaderTest.java
@@ -23,8 +23,8 @@
 import android.graphics.ComposeShader;
 import android.graphics.LinearGradient;
 import android.graphics.Paint;
-import android.graphics.PixelXorXfermode;
 import android.graphics.PorterDuff;
+import android.graphics.PorterDuffXfermode;
 import android.graphics.Shader;
 import android.graphics.Xfermode;
 import android.graphics.Bitmap.Config;
@@ -71,17 +71,17 @@
     }
 
     public void testXfermode() {
-        Bitmap greenBitmap = Bitmap.createBitmap(1, 1, Config.ARGB_8888);
-        greenBitmap.eraseColor(Color.GREEN);
+        Bitmap redBitmap = Bitmap.createBitmap(1, 1, Config.ARGB_8888);
+        redBitmap.eraseColor(Color.RED);
         Bitmap cyanBitmap = Bitmap.createBitmap(1, 1, Config.ARGB_8888);
         cyanBitmap.eraseColor(Color.CYAN);
 
-        BitmapShader blueShader = new BitmapShader(greenBitmap, TileMode.CLAMP, TileMode.CLAMP);
-        BitmapShader redShader = new BitmapShader(cyanBitmap, TileMode.CLAMP, TileMode.CLAMP);
+        BitmapShader redShader = new BitmapShader(redBitmap, TileMode.CLAMP, TileMode.CLAMP);
+        BitmapShader cyanShader = new BitmapShader(cyanBitmap, TileMode.CLAMP, TileMode.CLAMP);
 
-        PixelXorXfermode xferMode = new PixelXorXfermode(Color.WHITE);
+        PorterDuffXfermode xferMode = new PorterDuffXfermode(PorterDuff.Mode.ADD);
 
-        ComposeShader shader = new ComposeShader(blueShader, redShader, xferMode);
+        ComposeShader shader = new ComposeShader(redShader, cyanShader, xferMode);
 
         Bitmap bitmap = Bitmap.createBitmap(1, 1, Config.ARGB_8888);
         Canvas canvas = new Canvas(bitmap);
@@ -89,7 +89,7 @@
         paint.setShader(shader);
         canvas.drawPaint(paint);
 
-        // white ^ green ^ cyan = yellow
-        assertEquals(Color.YELLOW, bitmap.getPixel(0, 0));
+        // green + cyan = white
+        assertEquals(Color.WHITE, bitmap.getPixel(0, 0));
     }
 }
diff --git a/tests/tests/graphics/src/android/graphics/cts/ImageViewCtsActivity.java b/tests/tests/graphics/src/android/graphics/cts/ImageViewCtsActivity.java
index b9887b7..9d6de44 100644
--- a/tests/tests/graphics/src/android/graphics/cts/ImageViewCtsActivity.java
+++ b/tests/tests/graphics/src/android/graphics/cts/ImageViewCtsActivity.java
@@ -16,7 +16,7 @@
 
 package android.graphics.cts;
 
-import com.android.cts.graphics.R;
+import android.graphics.cts.R;
 
 import android.app.Activity;
 import android.os.Bundle;
diff --git a/tests/tests/graphics/src/android/graphics/cts/MovieTest.java b/tests/tests/graphics/src/android/graphics/cts/MovieTest.java
index b18b800..c1e7ead 100644
--- a/tests/tests/graphics/src/android/graphics/cts/MovieTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/MovieTest.java
@@ -32,10 +32,10 @@
 
 public class MovieTest extends ActivityInstrumentationTestCase2<MockActivity> {
     private Movie mMovie;
-    private final int MOVIE = com.android.cts.graphics.R.drawable.animated;
+    private final int MOVIE = android.graphics.cts.R.drawable.animated;
 
     public MovieTest() {
-        super("com.android.cts.graphics", MockActivity.class);
+        super("android.graphics.cts", MockActivity.class);
     }
 
     @Override
diff --git a/tests/tests/graphics/src/android/graphics/cts/NinePatchTest.java b/tests/tests/graphics/src/android/graphics/cts/NinePatchTest.java
index d37ec90..8b73380 100644
--- a/tests/tests/graphics/src/android/graphics/cts/NinePatchTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/NinePatchTest.java
@@ -16,7 +16,7 @@
 
 package android.graphics.cts;
 
-import com.android.cts.graphics.R;
+import android.graphics.cts.R;
 
 
 import android.content.res.Resources;
diff --git a/tests/tests/graphics/src/android/graphics/cts/OutlineTest.java b/tests/tests/graphics/src/android/graphics/cts/OutlineTest.java
new file mode 100644
index 0000000..4b01916
--- /dev/null
+++ b/tests/tests/graphics/src/android/graphics/cts/OutlineTest.java
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.graphics.cts;
+
+import android.graphics.Outline;
+import android.graphics.Path;
+import android.graphics.Rect;
+import android.test.suitebuilder.annotation.SmallTest;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+@SmallTest
+public class OutlineTest {
+    @Test
+    public void testDefaults() {
+        Outline outline = new Outline();
+
+        assertEquals(0.0f, outline.getAlpha(), 0.0f);
+        assertTrue(outline.isEmpty());
+        Rect outRect = new Rect();
+        assertFalse(outline.getRect(outRect));
+        assertTrue(outline.getRadius() < 0);
+    }
+
+    @Test
+    public void testGetSetAlpha() {
+        Outline outline = new Outline();
+
+        outline.setAlpha(1.0f);
+        assertEquals(1.0f, outline.getAlpha(), 0.0f);
+
+        outline.setAlpha(0.0f);
+        assertEquals(0.0f, outline.getAlpha(), 0.0f);
+
+        outline.setAlpha(0.45f);
+        assertEquals(0.45f, outline.getAlpha(), 0.0f);
+
+        // define out of range getter/setter behavior: (note will be clamped in native when consumed)
+        outline.setAlpha(4f);
+        assertEquals(4f, outline.getAlpha(), 0.0f);
+        outline.setAlpha(-30f);
+        assertEquals(-30f, outline.getAlpha(), 0.0f);
+    }
+
+    @Test
+    public void testSetRect() {
+        Outline outline = new Outline();
+        Rect outRect = new Rect();
+
+        outline.setRect(0, 0, 0, 0);
+        assertTrue(outline.isEmpty());
+
+        outline.setRect(10, 5, 4, 5);
+        assertTrue(outline.isEmpty());
+
+        outline.setRect(new Rect());
+        assertTrue(outline.isEmpty());
+
+        outline.setRect(10, 10, 20, 20);
+        assertFalse(outline.isEmpty());
+        assertTrue(outline.getRect(outRect));
+        assertEquals(new Rect(10, 10, 20, 20), outRect);
+        assertTrue(outline.canClip());
+
+        outline.setRect(new Rect(10, 10, 20, 20));
+        assertFalse(outline.isEmpty());
+        assertTrue(outline.getRect(outRect));
+        assertEquals(new Rect(10, 10, 20, 20), outRect);
+        assertTrue(outline.canClip());
+    }
+
+    @Test
+    public void testSetRoundRect() {
+        Outline outline = new Outline();
+        Rect outRect = new Rect();
+
+        outline.setRoundRect(0, 0, 0, 0, 1f);
+        assertTrue(outline.isEmpty());
+
+        outline.setRoundRect(10, 5, 4, 5, 1f);
+        assertTrue(outline.isEmpty());
+
+        outline.setRoundRect(new Rect(), 1f);
+        assertTrue(outline.isEmpty());
+
+        outline.setRoundRect(10, 10, 20, 20, 5f);
+        assertFalse(outline.isEmpty());
+        assertTrue(outline.getRect(outRect));
+        assertEquals(new Rect(10, 10, 20, 20), outRect);
+        assertEquals(5f, outline.getRadius(), 0.0f);
+        assertTrue(outline.canClip());
+
+        outline.setRoundRect(new Rect(10, 10, 20, 20), 4f);
+        assertFalse(outline.isEmpty());
+        assertTrue(outline.getRect(outRect));
+        assertEquals(new Rect(10, 10, 20, 20), outRect);
+        assertEquals(4f, outline.getRadius(), 0.0f);
+        assertTrue(outline.canClip());
+    }
+
+    @Test
+    public void testSetOval() {
+        Outline outline = new Outline();
+
+        outline.setOval(0, 0, 0, 0);
+        assertTrue(outline.isEmpty());
+
+        outline.setOval(10, 5, 4, 5);
+        assertTrue(outline.isEmpty());
+
+        Rect outRect = new Rect();
+        outline.setOval(0, 0, 50, 51); // different x & y radii, so not round rect
+        assertFalse(outline.getRect(outRect)); // not round rect, doesn't work
+        assertFalse(outline.canClip()); // not round rect, doesn't work
+        assertFalse(outline.isEmpty());
+
+        outline.setOval(0, 0, 50, 50); // same x & y radii, so round rect
+        assertTrue(outline.getRect(outRect)); // is round rect, so works
+        assertTrue(outline.canClip()); // is round rect, so works
+        assertFalse(outline.isEmpty());
+    }
+
+    @Test
+    public void testSetConvexPath() {
+        Outline outline = new Outline();
+        Path path = new Path();
+
+        assertTrue(path.isEmpty());
+        outline.setConvexPath(path);
+        assertTrue(outline.isEmpty());
+
+        path.addCircle(50, 50, 50, Path.Direction.CW);
+        outline.setConvexPath(path);
+        assertFalse(outline.isEmpty());
+    }
+
+    @Test
+    public void testGetRectRadius() {
+        Outline outline = new Outline();
+
+        Rect outRect = new Rect();
+        outline.setRoundRect(15, 10, 45, 40, 30.0f);
+        assertEquals(30.0f, outline.getRadius(), 0.0f);
+        assertTrue(outline.getRect(outRect));
+        assertEquals(new Rect(15, 10, 45, 40), outRect);
+
+        outline.setRect(5, 10, 15, 20);
+        assertEquals(0.0f, outline.getRadius(), 0.0f);
+        assertTrue(outline.getRect(outRect));
+        assertEquals(new Rect(5, 10, 15, 20), outRect);
+
+        outline.setOval(0, 0, 50, 60);
+        assertTrue(outline.getRadius() < 0);
+        assertFalse(outline.getRect(outRect));
+    }
+
+    @Test
+    public void testOffset() {
+        Outline outline = new Outline();
+
+        Rect outRect = new Rect();
+        outline.setRoundRect(15, 10, 45, 40, 30.0f);
+        outline.offset(-15, -10);
+        assertTrue(outline.getRect(outRect));
+        assertEquals(new Rect(0, 0, 30, 30), outRect);
+
+        outline.setRect(5, 10, 15, 20);
+        outline.offset(-5, -10);
+        assertTrue(outline.getRect(outRect));
+        assertEquals(new Rect(0, 0, 10, 10), outRect);
+    }
+}
diff --git a/tests/tests/graphics/src/android/graphics/cts/PaintTest.java b/tests/tests/graphics/src/android/graphics/cts/PaintTest.java
index 80e0253..aa8348a 100644
--- a/tests/tests/graphics/src/android/graphics/cts/PaintTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/PaintTest.java
@@ -28,6 +28,7 @@
 import android.graphics.Path;
 import android.graphics.PathEffect;
 import android.graphics.Rasterizer;
+import android.graphics.Rect;
 import android.graphics.Shader;
 import android.graphics.Bitmap;
 import android.graphics.BitmapShader;
@@ -36,6 +37,7 @@
 import android.os.Build;
 import android.test.AndroidTestCase;
 import android.text.SpannedString;
+import android.util.LocaleList;
 import android.util.Log;
 
 import java.util.Locale;
@@ -600,30 +602,73 @@
         // Check default
         assertEquals(defaultLocale, p.getTextLocale());
 
-        // Check setter / getter
+        // Check setter / getters
         p.setTextLocale(Locale.US);
         assertEquals(Locale.US, p.getTextLocale());
+        assertEquals(new LocaleList(Locale.US), p.getTextLocales());
 
         p.setTextLocale(Locale.CHINESE);
         assertEquals(Locale.CHINESE, p.getTextLocale());
+        assertEquals(new LocaleList(Locale.CHINESE), p.getTextLocales());
 
         p.setTextLocale(Locale.JAPANESE);
         assertEquals(Locale.JAPANESE, p.getTextLocale());
+        assertEquals(new LocaleList(Locale.JAPANESE), p.getTextLocales());
 
         p.setTextLocale(Locale.KOREAN);
         assertEquals(Locale.KOREAN, p.getTextLocale());
+        assertEquals(new LocaleList(Locale.KOREAN), p.getTextLocales());
 
         // Check reverting back to default
         p.setTextLocale(defaultLocale);
         assertEquals(defaultLocale, p.getTextLocale());
+        assertEquals(new LocaleList(defaultLocale), p.getTextLocales());
 
         // Check that we cannot pass a null locale
         try {
             p.setTextLocale(null);
-            assertFalse(true);
+            fail("Setting the text locale to null should throw");
+        } catch (Throwable e) {
+            assertEquals(IllegalArgumentException.class, e.getClass());
         }
-        catch (IllegalArgumentException iae) {
-            // OK !!
+    }
+
+    public void testAccessTextLocales() {
+        Paint p = new Paint();
+
+        final LocaleList defaultLocales = LocaleList.getDefault();
+
+        // Check default
+        assertEquals(defaultLocales, p.getTextLocales());
+
+        // Check setter / getters for a one-member locale list
+        p.setTextLocales(new LocaleList(Locale.CHINESE));
+        assertEquals(Locale.CHINESE, p.getTextLocale());
+        assertEquals(new LocaleList(Locale.CHINESE), p.getTextLocales());
+
+        // Check setter / getters for a two-member locale list
+        p.setTextLocales(LocaleList.forLanguageTags("fr,de"));
+        assertEquals(Locale.forLanguageTag("fr"), p.getTextLocale());
+        assertEquals(LocaleList.forLanguageTags("fr,de"), p.getTextLocales());
+
+        // Check reverting back to default
+        p.setTextLocales(defaultLocales);
+        assertEquals(defaultLocales, p.getTextLocales());
+
+        // Check that we cannot pass a null locale list
+        try {
+            p.setTextLocales(null);
+            fail("Setting the text locale list to null should throw");
+        } catch (Throwable e) {
+            assertEquals(IllegalArgumentException.class, e.getClass());
+        }
+
+        // Check that we cannot pass an empty locale list
+        try {
+            p.setTextLocales(new LocaleList());
+            fail("Setting the text locale list to an empty list should throw");
+        } catch (Throwable e) {
+            assertEquals(IllegalArgumentException.class, e.getClass());
         }
     }
 
@@ -808,6 +853,57 @@
         assertEquals(10.0f, p.getStrokeWidth());
     }
 
+    public void testSetFontFeatureSettings() {
+        Paint p = new Paint();
+        // Roboto font (system default) has "fi" ligature
+        String text = "fi";
+        float[] widths = new float[text.length()];
+        p.getTextWidths(text, widths);
+        assertTrue(widths[0] > 0.0f);
+        assertEquals(0.0f, widths[1]);
+
+        // Disable ligature using OpenType feature
+        p.setFontFeatureSettings("'liga' off");
+        p.getTextWidths(text, widths);
+        assertTrue(widths[0] > 0.0f);
+        assertTrue(widths[1] > 0.0f);
+
+        // Re-enable ligature
+        p.setFontFeatureSettings("'liga' on");
+        p.getTextWidths(text, widths);
+        assertTrue(widths[0] > 0.0f);
+        assertEquals(0.0f, widths[1]);
+    }
+
+    public void testGetTextBounds() {
+        Paint p = new Paint();
+        p.setTextSize(10);
+        String text1 = "hello";
+        Rect bounds1 = new Rect();
+        Rect bounds2 = new Rect();
+        p.getTextBounds(text1, 0, text1.length(), bounds1);
+        char[] textChars1 = text1.toCharArray();
+        p.getTextBounds(textChars1, 0, textChars1.length, bounds2);
+        // verify that string and char array methods produce consistent results
+        assertEquals(bounds1, bounds2);
+        String text2 = "hello world";
+
+        // verify substring produces consistent results
+        p.getTextBounds(text2, 0, text1.length(), bounds2);
+        assertEquals(bounds1, bounds2);
+
+        // longer string is expected to have same left edge but be wider
+        p.getTextBounds(text2, 0, text2.length(), bounds2);
+        assertEquals(bounds1.left, bounds2.left);
+        assertTrue(bounds2.right > bounds1.right);
+
+        // bigger size implies bigger bounding rect
+        p.setTextSize(20);
+        p.getTextBounds(text1, 0, text1.length(), bounds2);
+        assertTrue(bounds2.right > bounds1.right);
+        assertTrue(bounds2.bottom - bounds2.top > bounds1.bottom - bounds1.top);
+    }
+
     public void testReset() {
         Paint p  = new Paint();
         ColorFilter c = new ColorFilter();
@@ -1075,6 +1171,11 @@
         }
 
         // TODO: when we support variation selectors, add positive tests
+
+        // Unicode 7.0, 8.0, and 9.0 emoji should be supported.
+        assertTrue(p.hasGlyph("\uD83D\uDD75"));  // SLEUTH OR SPY is introduced in Unicode 7.0
+        assertTrue(p.hasGlyph("\uD83C\uDF2E"));  // TACO is introduced in Unicode 8.0
+        assertTrue(p.hasGlyph("\uD83E\uDD33"));  // SELFIE is introduced in Unicode 9.0
     }
 
     public void testGetRunAdvance() {
@@ -1088,6 +1189,13 @@
                 assertEquals(0.0f, width);
             }
             {
+                for (int i = 0; i < string.length(); i++) {
+                    final float width = p.getRunAdvance(string, i, i + 1, 0, string.length(),
+                            false, i);
+                    assertEquals(0.0f, width);
+                }
+            }
+            {
                 final float widthToMid = p.getRunAdvance(string, 0, string.length(), 0,
                         string.length(), false, string.length() / 2);
                 final float widthToTail = p.getRunAdvance(string, 0, string.length(), 0,
@@ -1102,11 +1210,32 @@
                         string.length(), false, string.length());
                 assertTrue(widthFromHead > widthFromSecond);
             }
+            {
+                float width = 0.0f;
+                for (int i = 0; i < string.length(); i++) {
+                    width += p.getRunAdvance(string, i, i + 1, 0, string.length(), false, i + 1);
+                }
+                final float totalWidth = p.getRunAdvance(string, 0, string.length(), 0,
+                        string.length(), false, string.length());
+                assertEquals(totalWidth, width, 1.0f);
+            }
         }
         {
             // RTL
             String string = "\u0644\u063A\u0629 \u0639\u0631\u0628\u064A\u0629"; // Arabic
             {
+                final float width = p.getRunAdvance(string, 0, string.length(), 0,
+                        string.length(), true, 0);
+                assertEquals(0.0f, width);
+            }
+            {
+                for (int i = 0; i < string.length(); i++) {
+                    final float width = p.getRunAdvance(string, i, i + 1, 0, string.length(),
+                            true, i);
+                    assertEquals(0.0f, width);
+                }
+            }
+            {
                 final float widthToMid = p.getRunAdvance(string, 0, string.length(), 0,
                         string.length(), true, string.length() / 2);
                 final float widthToTail = p.getRunAdvance(string, 0, string.length(), 0,
diff --git a/tests/tests/graphics/src/android/graphics/cts/PathTest.java b/tests/tests/graphics/src/android/graphics/cts/PathTest.java
index c15bc38..6e93400 100644
--- a/tests/tests/graphics/src/android/graphics/cts/PathTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/PathTest.java
@@ -17,7 +17,12 @@
 package android.graphics.cts;
 
 import junit.framework.TestCase;
+
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
 import android.graphics.Matrix;
+import android.graphics.Paint;
 import android.graphics.Path;
 import android.graphics.RectF;
 
@@ -71,7 +76,26 @@
         Path path1 = new Path();
         setPath(path1);
         path.set(path1);
-        assertFalse(path.isEmpty());
+        assertPathsAreEquivalent(path, path1);
+    }
+
+    public void testSetCleanOld() {
+        Path path = new Path();
+        setPath(path);
+        path.addRect(new RectF(0, 0, 10, 10), Path.Direction.CW);
+        Path path1 = new Path();
+        path1.addRect(new RectF(10, 10, 20, 20), Path.Direction.CW);
+        path.set(path1);
+        assertPathsAreEquivalent(path, path1);
+    }
+
+    public void testSetEmptyPath() {
+        // new the Path instance
+        Path path = new Path();
+        setPath(path);
+        Path path1 = new Path();
+        path.set(path1);
+        assertPathsAreEquivalent(path, path1);
     }
 
     public void testAccessFillType() {
@@ -380,6 +404,25 @@
         assertFalse(path.isEmpty());
     }
 
+    private static void assertPathsAreEquivalent(Path actual, Path expected) {
+        Bitmap actualBitmap = drawAndGetBitmap(actual);
+        Bitmap expectedBitmap = drawAndGetBitmap(expected);
+        assertTrue(actualBitmap.sameAs(expectedBitmap));
+    }
+
+    private static final int WIDTH = 100;
+    private static final int HEIGHT = 100;
+
+    private static Bitmap drawAndGetBitmap(Path path) {
+        Bitmap bitmap = Bitmap.createBitmap(WIDTH, HEIGHT, Bitmap.Config.ARGB_8888);
+        bitmap.eraseColor(Color.BLACK);
+        Paint paint = new Paint();
+        paint.setColor(Color.RED);
+        Canvas canvas = new Canvas(bitmap);
+        canvas.drawPath(path, paint);
+        return bitmap;
+    }
+
     private void setPath(Path path) {
         RectF rect = new RectF(LEFT, TOP, RIGHT, BOTTOM);
         path.addRect(rect, Path.Direction.CW);
diff --git a/tests/tests/graphics/src/android/graphics/cts/PixelXorXfermodeTest.java b/tests/tests/graphics/src/android/graphics/cts/PixelXorXfermodeTest.java
deleted file mode 100644
index e2d68da..0000000
--- a/tests/tests/graphics/src/android/graphics/cts/PixelXorXfermodeTest.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.graphics.cts;
-
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
-import android.graphics.PixelXorXfermode;
-import android.graphics.Bitmap.Config;
-import android.test.AndroidTestCase;
-
-public class PixelXorXfermodeTest extends AndroidTestCase {
-
-    public void testPixelXorXfermode() {
-        int width = 100;
-        int height = 100;
-        Bitmap b1 = Bitmap.createBitmap(width / 2, height, Config.ARGB_8888);
-        b1.eraseColor(Color.WHITE);
-        Bitmap b2 = Bitmap.createBitmap(width, height / 2, Config.ARGB_8888);
-        b2.eraseColor(Color.CYAN);
-
-        Bitmap target = Bitmap.createBitmap(width, height, Config.ARGB_8888);
-        target.eraseColor(Color.BLACK);
-        Canvas canvas = new Canvas(target);
-        Paint p = new Paint();
-        canvas.drawBitmap(b1, 0, 0, p);
-        p.setXfermode(new PixelXorXfermode(Color.GREEN));
-        canvas.drawBitmap(b2, 0, height / 2, p);
-        assertEquals(Color.WHITE, target.getPixel(width / 4, height / 4));
-        // white ^ green ^ cyan = yellow
-        assertEquals(Color.YELLOW, target.getPixel(width / 4, height * 3 / 4));
-        // black ^ green ^ cyan = blue
-        assertEquals(Color.BLUE, target.getPixel(width * 3 / 4, height * 3 / 4));
-
-        // XOR transfer always results in an opaque image
-        p.setXfermode(new PixelXorXfermode(alphaColor(Color.GREEN, 25)));
-        target.eraseColor(alphaColor(Color.BLACK, 42));
-        p.setColor(alphaColor(Color.CYAN, 5));
-        canvas.drawPaint(p);
-        // result is always opaque, even though all inputs have alpha
-        assertEquals(255, Color.alpha(target.getPixel(0, 0)));
-    }
-
-    private int alphaColor(int color, int alpha) {
-        int red = Color.red(color);
-        int green = Color.green(color);
-        int blue = Color.blue(color);
-        return Color.argb(alpha, red, green, blue);
-    }
-}
diff --git a/tests/tests/graphics/src/android/graphics/cts/RegionTest.java b/tests/tests/graphics/src/android/graphics/cts/RegionTest.java
index 803f3e9..10e277b 100644
--- a/tests/tests/graphics/src/android/graphics/cts/RegionTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/RegionTest.java
@@ -1497,21 +1497,42 @@
         Rect oriRect = new Rect(0, 0, 10, 10);
         mRegion = new Region();
 
+        // test reading/writing an empty parcel
         Parcel p = Parcel.obtain();
         mRegion.writeToParcel(p, flags);
-        assertEquals(8, p.dataSize());
-
-        p = Parcel.obtain();
-        mRegion.set(oriRect);
-        mRegion.writeToParcel(p, flags);
-        assertEquals(24, p.dataSize());
 
         p.setDataPosition(0);
         Region dst = Region.CREATOR.createFromParcel(p);
+        assertTrue(dst.isEmpty());
+
+        // test reading/writing a single rect parcel
+        p = Parcel.obtain();
+        mRegion.set(oriRect);
+        mRegion.writeToParcel(p, flags);
+
+        p.setDataPosition(0);
+        dst = Region.CREATOR.createFromParcel(p);
         assertEquals(oriRect.top, dst.getBounds().top);
         assertEquals(oriRect.left, dst.getBounds().left);
         assertEquals(oriRect.bottom, dst.getBounds().bottom);
         assertEquals(oriRect.right, dst.getBounds().right);
+
+        // test reading/writing a multiple rect parcel
+        p = Parcel.obtain();
+        mRegion.op(5, 5, 15, 15, Region.Op.UNION);
+        mRegion.writeToParcel(p, flags);
+
+        p.setDataPosition(0);
+        dst = Region.CREATOR.createFromParcel(p);
+        assertTrue(dst.contains(2,2));
+        assertTrue(dst.contains(7,7));
+        assertTrue(dst.contains(12,12));
+        assertFalse(dst.contains(2,12));
+        assertFalse(dst.contains(12,2));
+        assertEquals(0, dst.getBounds().top);
+        assertEquals(0, dst.getBounds().left);
+        assertEquals(15, dst.getBounds().bottom);
+        assertEquals(15, dst.getBounds().right);
     }
 
     public void testDescribeContents() {
diff --git a/tests/tests/graphics/src/android/graphics/cts/TypefaceTest.java b/tests/tests/graphics/src/android/graphics/cts/TypefaceTest.java
index 5528372..e5a610c 100644
--- a/tests/tests/graphics/src/android/graphics/cts/TypefaceTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/TypefaceTest.java
@@ -19,15 +19,10 @@
 
 import android.graphics.Paint;
 import android.graphics.Typeface;
-import android.content.res.AssetFileDescriptor;
-import android.content.res.AssetManager;
-import android.content.res.Resources;
-import android.graphics.Typeface;
-import android.os.ParcelFileDescriptor;
 import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
 
 import java.io.File;
-import java.io.FileDescriptor;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
@@ -203,4 +198,27 @@
         float widthCustomTypeface = p.measureText(testString);
         assertEquals(widthDefaultTypeface, widthCustomTypeface, 1.0f);
     }
+
+    @SmallTest
+    public void testCreateFromAsset_cachesTypeface() {
+        Typeface typeface1 = Typeface.createFromAsset(getContext().getAssets(), "bombfont2.ttf");
+        assertNotNull(typeface1);
+
+        Typeface typeface2 = Typeface.createFromAsset(getContext().getAssets(), "bombfont2.ttf");
+        assertNotNull(typeface2);
+        assertSame("Same font asset should return same Typeface object", typeface1, typeface2);
+
+        Typeface typeface3 = Typeface.createFromAsset(getContext().getAssets(), "bombfont.ttf");
+        assertNotNull(typeface3);
+        assertNotSame("Different font asset should return different Typeface object",
+                typeface2, typeface3);
+
+        Typeface typeface4 = Typeface.createFromAsset(getContext().getAssets(), "samplefont.ttf");
+        assertNotNull(typeface4);
+        assertNotSame("Different font asset should return different Typeface object",
+                typeface2, typeface4);
+        assertNotSame("Different font asset should return different Typeface object",
+                typeface3, typeface4);
+    }
+
 }
diff --git a/tests/tests/graphics/src/android/graphics/cts/VulkanReservedTest.java b/tests/tests/graphics/src/android/graphics/cts/VulkanReservedTest.java
deleted file mode 100644
index bfd520e..0000000
--- a/tests/tests/graphics/src/android/graphics/cts/VulkanReservedTest.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.graphics.cts;
-
-import android.cts.util.FileUtils;
-
-import junit.framework.TestCase;
-
-import java.io.File;
-
-public class VulkanReservedTest extends TestCase {
-
-    /**
-     * Assert that file with given path does not exist.
-     */
-    private static void assertNoFile(String filename) {
-        assertFalse(filename + " must not exist", new File(filename).exists());
-    }
-
-    /**
-     * Test that no vendor ships libvulkan.so before ratification and
-     * appropriate CTS coverage.
-     */
-    public void testNoVulkan() {
-        assertNoFile("/system/lib/libvulkan.so");
-        assertNoFile("/system/lib64/libvulkan.so");
-        assertNoFile("/vendor/lib/libvulkan.so");
-        assertNoFile("/vendor/lib64/libvulkan.so");
-    }
-}
diff --git a/tests/tests/graphics/src/android/graphics/cts/YuvImageTest.java b/tests/tests/graphics/src/android/graphics/cts/YuvImageTest.java
index 02b3afa..a2038b4 100644
--- a/tests/tests/graphics/src/android/graphics/cts/YuvImageTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/YuvImageTest.java
@@ -33,7 +33,7 @@
 import android.test.AndroidTestCase;
 import android.util.Log;
 
-import com.android.cts.graphics.R;
+import android.graphics.cts.R;
 
 
 public class YuvImageTest extends AndroidTestCase {
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/AnimatedStateListDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/AnimatedStateListDrawableTest.java
new file mode 100644
index 0000000..12f9828
--- /dev/null
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/AnimatedStateListDrawableTest.java
@@ -0,0 +1,272 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.graphics.drawable.cts;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import android.R.attr;
+import android.content.Context;
+import android.content.res.Resources;
+import android.content.res.XmlResourceParser;
+import android.graphics.Canvas;
+import android.graphics.ColorFilter;
+import android.graphics.cts.R;
+import android.graphics.drawable.Animatable;
+import android.graphics.drawable.Animatable2;
+import android.graphics.drawable.AnimatedStateListDrawable;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.DrawableContainer.DrawableContainerState;
+import android.graphics.drawable.StateListDrawable;
+import android.test.InstrumentationTestCase;
+import android.util.StateSet;
+import android.util.Xml;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashSet;
+
+import static org.mockito.Mockito.mock;
+
+public class AnimatedStateListDrawableTest extends InstrumentationTestCase {
+    private static final int[] STATE_EMPTY = new int[] { };
+    private static final int[] STATE_FOCUSED = new int[] { attr.state_focused };
+
+    private Context mContext;
+    private Resources mResources;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        mContext = getInstrumentation().getTargetContext();
+        mResources = mContext.getResources();
+    }
+
+    public void testStateListDrawable() {
+        new AnimatedStateListDrawable();
+
+        // Check the values set in the constructor
+        assertNotNull(new AnimatedStateListDrawable().getConstantState());
+    }
+
+    public void testAddState() {
+        AnimatedStateListDrawable asld = new AnimatedStateListDrawable();
+        DrawableContainerState cs = (DrawableContainerState) asld.getConstantState();
+        assertEquals(0, cs.getChildCount());
+
+        try {
+            asld.addState(StateSet.WILD_CARD, null, R.id.focused);
+            fail("Expected IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected.
+        }
+
+        Drawable unfocused = mock(Drawable.class);
+        asld.addState(StateSet.WILD_CARD, unfocused, R.id.focused);
+        assertEquals(1, cs.getChildCount());
+
+        Drawable focused = mock(Drawable.class);
+        asld.addState(STATE_FOCUSED, focused, R.id.unfocused);
+        assertEquals(2, cs.getChildCount());
+    }
+
+    public void testAddTransition() {
+        AnimatedStateListDrawable asld = new AnimatedStateListDrawable();
+        DrawableContainerState cs = (DrawableContainerState) asld.getConstantState();
+
+        Drawable focused = mock(Drawable.class);
+        Drawable unfocused = mock(Drawable.class);
+        asld.addState(STATE_FOCUSED, focused, R.id.focused);
+        asld.addState(StateSet.WILD_CARD, unfocused, R.id.unfocused);
+
+        try {
+            asld.addTransition(R.id.focused, R.id.focused, null, false);
+            fail("Expected IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected.
+        }
+
+        MockTransition focusedToUnfocused = mock(MockTransition.class);
+        asld.addTransition(R.id.focused, R.id.unfocused, focusedToUnfocused, false);
+        assertEquals(3, cs.getChildCount());
+
+        MockTransition unfocusedToFocused = mock(MockTransition.class);
+        asld.addTransition(R.id.unfocused, R.id.focused, unfocusedToFocused, false);
+        assertEquals(4, cs.getChildCount());
+
+        MockTransition reversible = mock(MockTransition.class);
+        asld.addTransition(R.id.focused, R.id.unfocused, reversible, true);
+        assertEquals(5, cs.getChildCount());
+    }
+
+    public void testIsStateful() {
+        assertTrue(new AnimatedStateListDrawable().isStateful());
+    }
+
+    public void testOnStateChange() {
+        AnimatedStateListDrawable asld = new AnimatedStateListDrawable();
+
+        Drawable focused = mock(Drawable.class);
+        Drawable unfocused = mock(Drawable.class);
+        asld.addState(STATE_FOCUSED, focused, R.id.focused);
+        asld.addState(StateSet.WILD_CARD, unfocused, R.id.unfocused);
+
+        MockTransition focusedToUnfocused = mock(MockTransition.class);
+        MockTransition unfocusedToFocused = mock(MockTransition.class);
+        asld.addTransition(R.id.focused, R.id.unfocused, focusedToUnfocused, false);
+        asld.addTransition(R.id.unfocused, R.id.focused, unfocusedToFocused, false);
+
+        asld.setState(STATE_EMPTY);
+        assertSame(unfocused, asld.getCurrent());
+
+        asld.setState(STATE_FOCUSED);
+        assertSame(unfocusedToFocused, asld.getCurrent());
+
+        asld.setState(STATE_FOCUSED);
+        assertSame(unfocusedToFocused, asld.getCurrent());
+    }
+
+    public void testPreloadDensity() throws XmlPullParserException, IOException {
+        runPreloadDensityTestForDrawable(
+                R.drawable.animated_state_list_density, false);
+    }
+
+    public void testPreloadDensityConstantSize() throws XmlPullParserException, IOException {
+        runPreloadDensityTestForDrawable(
+                R.drawable.animated_state_list_density_constant_size, true);
+    }
+
+    private void runPreloadDensityTestForDrawable(int drawableResId, boolean isConstantSize)
+            throws XmlPullParserException, IOException {
+        final Resources res = mResources;
+        final int densityDpi = res.getConfiguration().densityDpi;
+        try {
+            runPreloadDensityTestForDrawableInner(res, densityDpi, drawableResId, isConstantSize);
+        } finally {
+            DrawableTestUtils.setResourcesDensity(res, densityDpi);
+        }
+    }
+
+    private void runPreloadDensityTestForDrawableInner(Resources res, int densityDpi,
+            int drawableResId, boolean isConstantSize) throws XmlPullParserException, IOException {
+        // Capture initial state at default density.
+        final XmlResourceParser parser = getResourceParser(drawableResId);
+        final AnimatedStateListDrawable asld = new AnimatedStateListDrawable();
+        asld.inflate(res, parser, Xml.asAttributeSet(parser));
+
+        final DrawableContainerState cs = (DrawableContainerState) asld.getConstantState();
+        final int count = cs.getChildCount();
+        final int[] origWidth = new int[count];
+        int max = 0;
+        for (int i = 0; i < count; i++) {
+            final int width = cs.getChild(i).getIntrinsicWidth();
+            max = Math.max(max, width);
+            origWidth[i] = width;
+        }
+        if (isConstantSize) {
+            Arrays.fill(origWidth, max);
+        }
+
+        // Set density to half of original.
+        DrawableTestUtils.setResourcesDensity(res, densityDpi / 2);
+        final StateListDrawable halfDrawable =
+                (StateListDrawable) cs.newDrawable(res);
+        for (int i = 0; i < count; i++) {
+            halfDrawable.selectDrawable(i);
+            assertEquals(Math.round(origWidth[i] / 2f), halfDrawable.getIntrinsicWidth());
+        }
+
+        // Set density to double original.
+        DrawableTestUtils.setResourcesDensity(res, densityDpi * 2);
+        final StateListDrawable doubleDrawable =
+                (StateListDrawable) cs.newDrawable(res);
+        for (int i = 0; i < count; i++) {
+            doubleDrawable.selectDrawable(i);
+            assertEquals(origWidth[i] * 2, doubleDrawable.getIntrinsicWidth());
+        }
+
+        // Restore original configuration and metrics.
+        DrawableTestUtils.setResourcesDensity(res, densityDpi);
+        final StateListDrawable origDrawable =
+                (StateListDrawable) cs.newDrawable(res);
+        for (int i = 0; i < count; i++) {
+            origDrawable.selectDrawable(i);
+            assertEquals(origWidth[i], origDrawable.getIntrinsicWidth());
+        }
+    }
+
+    private XmlResourceParser getResourceParser(int resId) throws XmlPullParserException,
+            IOException {
+        XmlResourceParser parser = getInstrumentation().getTargetContext().getResources().getXml(
+                resId);
+        int type;
+        while ((type = parser.next()) != XmlPullParser.START_TAG
+                && type != XmlPullParser.END_DOCUMENT) {
+            // Empty loop
+        }
+        return parser;
+    }
+
+    public void testInflate() throws XmlPullParserException, IOException {
+        AnimatedStateListDrawable asld = (AnimatedStateListDrawable) mContext.getDrawable(
+                R.drawable.animated_state_list_density);
+        DrawableContainerState asldState = (DrawableContainerState) asld.getConstantState();
+        assertTrue(asld.isVisible());
+        assertFalse(asldState.isConstantSize());
+        assertNull(asldState.getConstantPadding());
+        assertEquals(4, asldState.getChildCount());
+    }
+
+    public abstract class MockTransition extends MockDrawable implements Animatable, Animatable2 {
+        private HashSet<AnimationCallback> mCallbacks = new HashSet<>();
+
+        @Override
+        public void registerAnimationCallback(AnimationCallback callback) {
+            mCallbacks.add(callback);
+        }
+
+        @Override
+        public boolean unregisterAnimationCallback(AnimationCallback callback) {
+            return mCallbacks.remove(callback);
+        }
+
+        @Override
+        public void clearAnimationCallbacks() {
+            mCallbacks.clear();
+        }
+    }
+
+    public class MockDrawable extends Drawable {
+        @Override
+        public void draw(Canvas canvas) {
+        }
+
+        @Override
+        public int getOpacity() {
+            return 0;
+        }
+
+        @Override
+        public void setAlpha(int alpha) {
+        }
+
+        @Override
+        public void setColorFilter(ColorFilter cf) {
+        }
+    }
+}
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/AnimatedVectorDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/AnimatedVectorDrawableTest.java
index 769e110..487eb3b 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/AnimatedVectorDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/AnimatedVectorDrawableTest.java
@@ -19,16 +19,22 @@
 import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.PixelFormat;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffColorFilter;
+import android.graphics.cts.R;
 import android.graphics.drawable.Animatable2;
 import android.graphics.drawable.AnimatedVectorDrawable;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.Drawable.ConstantState;
 import android.test.ActivityInstrumentationTestCase2;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.test.suitebuilder.annotation.SmallTest;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.util.Xml;
-
-import com.android.cts.graphics.R;
+import android.widget.ImageView;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
@@ -37,6 +43,8 @@
 import java.io.FileOutputStream;
 import java.io.IOException;
 
+import static java.lang.Thread.sleep;
+
 public class AnimatedVectorDrawableTest extends ActivityInstrumentationTestCase2<DrawableStubActivity> {
     private static final String LOGTAG = AnimatedVectorDrawableTest.class.getSimpleName();
 
@@ -45,11 +53,13 @@
 
     private DrawableStubActivity mActivity;
     private Resources mResources;
-    private AnimatedVectorDrawable mAnimatedVectorDrawable;
     private Bitmap mBitmap;
     private Canvas mCanvas;
     private static final boolean DBG_DUMP_PNG = false;
-    private int mResId = R.drawable.animation_vector_drawable_grouping_1;
+    private final int mResId = R.drawable.animation_vector_drawable_grouping_1;
+    private final int mLayoutId = R.layout.animated_vector_drawable_source;
+    private final int mImageViewId = R.id.avd_view;
+
 
     public AnimatedVectorDrawableTest() {
         super(DrawableStubActivity.class);
@@ -61,7 +71,6 @@
 
         mBitmap = Bitmap.createBitmap(IMAGE_WIDTH, IMAGE_HEIGHT, Bitmap.Config.ARGB_8888);
         mCanvas = new Canvas(mBitmap);
-        mAnimatedVectorDrawable = new AnimatedVectorDrawable();
 
         mActivity = getActivity();
         mResources = mActivity.getResources();
@@ -99,6 +108,7 @@
         }
     }
 
+    @MediumTest
     public void testInflate() throws Exception {
         // Setup AnimatedVectorDrawable from xml file
         XmlPullParser parser = mResources.getXml(mResId);
@@ -113,11 +123,11 @@
         if (type != XmlPullParser.START_TAG) {
             throw new XmlPullParserException("No start tag found");
         }
-
-        mAnimatedVectorDrawable.inflate(mResources, parser, attrs);
-        mAnimatedVectorDrawable.setBounds(0, 0, IMAGE_WIDTH, IMAGE_HEIGHT);
+        AnimatedVectorDrawable drawable = new AnimatedVectorDrawable();
+        drawable.inflate(mResources, parser, attrs);
+        drawable.setBounds(0, 0, IMAGE_WIDTH, IMAGE_HEIGHT);
         mBitmap.eraseColor(0);
-        mAnimatedVectorDrawable.draw(mCanvas);
+        drawable.draw(mCanvas);
         int sunColor = mBitmap.getPixel(IMAGE_WIDTH / 2, IMAGE_HEIGHT / 2);
         int earthColor = mBitmap.getPixel(IMAGE_WIDTH * 3 / 4 + 2, IMAGE_HEIGHT / 2);
         assertTrue(sunColor == 0xFFFF8000);
@@ -128,6 +138,36 @@
         }
     }
 
+    @MediumTest
+    public void testSingleFrameAnimation() throws Exception {
+        int resId = R.drawable.avd_single_frame;
+        final AnimatedVectorDrawable d1 =
+                (AnimatedVectorDrawable) mResources.getDrawable(resId);
+        // The AVD has a duration as 16ms.
+        mActivity.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                d1.start();
+                d1.stop();
+
+            }
+        });
+        getInstrumentation().waitForIdleSync();
+
+        d1.setBounds(0, 0, IMAGE_WIDTH, IMAGE_HEIGHT);
+        mBitmap.eraseColor(0);
+        d1.draw(mCanvas);
+
+        int endColor = mBitmap.getPixel(IMAGE_WIDTH / 2, IMAGE_HEIGHT / 2);
+
+        assertEquals("Center point's color must be green", 0xFF00FF00, endColor);
+
+        if (DBG_DUMP_PNG) {
+            saveVectorDrawableIntoPNG(mBitmap, resId);
+        }
+    }
+
+    @SmallTest
     public void testGetChangingConfigurations() {
         AnimatedVectorDrawable avd = new AnimatedVectorDrawable();
         ConstantState constantState = avd.getConstantState();
@@ -151,6 +191,7 @@
         assertEquals(0xffff,  avd.getChangingConfigurations());
     }
 
+    @SmallTest
     public void testGetConstantState() {
         AnimatedVectorDrawable AnimatedVectorDrawable = new AnimatedVectorDrawable();
         ConstantState constantState = AnimatedVectorDrawable.getConstantState();
@@ -163,6 +204,7 @@
         assertEquals(1, constantState.getChangingConfigurations());
     }
 
+    @SmallTest
     public void testMutate() {
         AnimatedVectorDrawable d1 = (AnimatedVectorDrawable) mResources.getDrawable(mResId);
         AnimatedVectorDrawable d2 = (AnimatedVectorDrawable) mResources.getDrawable(mResId);
@@ -190,73 +232,158 @@
         assertEquals(originalAlpha, d3.getAlpha());
     }
 
+    @SmallTest
+    public void testGetOpacity() {
+        AnimatedVectorDrawable d1 = (AnimatedVectorDrawable) mResources.getDrawable(mResId);
+        assertEquals("Default is translucent", PixelFormat.TRANSLUCENT, d1.getOpacity());
+        d1.setAlpha(0);
+        assertEquals("Still translucent", PixelFormat.TRANSLUCENT, d1.getOpacity());
+    }
+
+    @SmallTest
+    public void testColorFilter() {
+        PorterDuffColorFilter filter = new PorterDuffColorFilter(Color.RED, PorterDuff.Mode.SRC_IN);
+        AnimatedVectorDrawable d1 = (AnimatedVectorDrawable) mResources.getDrawable(mResId);
+        d1.setColorFilter(filter);
+
+        assertEquals(filter, d1.getColorFilter());
+    }
+
+    @MediumTest
     public void testReset() {
         final AnimatedVectorDrawable d1 = (AnimatedVectorDrawable) mResources.getDrawable(mResId);
         // The AVD has a duration as 100ms.
         mActivity.runOnUiThread(new Runnable() {
             @Override
             public void run() {
+                d1.start();
                 d1.reset();
-                assertFalse(d1.isRunning());
             }
         });
+        getInstrumentation().waitForIdleSync();
+        assertFalse(d1.isRunning());
 
     }
 
-    public void testAddCallback() throws InterruptedException {
-        MyCallback callback = new MyCallback();
+    @MediumTest
+    public void testStop() {
         final AnimatedVectorDrawable d1 = (AnimatedVectorDrawable) mResources.getDrawable(mResId);
-
-        d1.registerAnimationCallback(callback);
         // The AVD has a duration as 100ms.
         mActivity.runOnUiThread(new Runnable() {
             @Override
             public void run() {
                 d1.start();
+                d1.stop();
+
             }
         });
+        getInstrumentation().waitForIdleSync();
+        assertFalse(d1.isRunning());
+    }
 
-        Thread.sleep(200);
-
+    @MediumTest
+    public void testAddCallbackBeforeStart() throws InterruptedException {
+        final MyCallback callback = new MyCallback();
+        // The AVD has a duration as 100ms.
+        mActivity.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mActivity.setContentView(mLayoutId);
+                ImageView imageView = (ImageView) mActivity.findViewById(mImageViewId);
+                AnimatedVectorDrawable d1 = (AnimatedVectorDrawable) imageView.getDrawable();
+                d1.registerAnimationCallback(callback);
+                d1.start();
+            }
+        });
+        getInstrumentation().waitForIdleSync();
+        sleep(200);
         assertTrue(callback.mStart);
         assertTrue(callback.mEnd);
     }
 
-    public void testRemoveCallback() throws InterruptedException {
-        MyCallback callback = new MyCallback();
-        final AnimatedVectorDrawable d1 = (AnimatedVectorDrawable) mResources.getDrawable(mResId);
-
-        d1.registerAnimationCallback(callback);
-        assertTrue(d1.unregisterAnimationCallback(callback));
+    @MediumTest
+    public void testAddCallbackAfterTrigger() throws InterruptedException {
+        final MyCallback callback = new MyCallback();
         // The AVD has a duration as 100ms.
         mActivity.runOnUiThread(new Runnable() {
             @Override
             public void run() {
+                mActivity.setContentView(mLayoutId);
+                ImageView imageView = (ImageView) mActivity.findViewById(mImageViewId);
+                AnimatedVectorDrawable d1 = (AnimatedVectorDrawable) imageView.getDrawable();
+                // This reset call can enforce the AnimatorSet is setup properly in AVD, when
+                // running on UI thread.
+                d1.reset();
+                d1.registerAnimationCallback(callback);
                 d1.start();
             }
         });
+        getInstrumentation().waitForIdleSync();
+        sleep(200);
+        assertTrue(callback.mStart);
+        assertTrue(callback.mEnd);
+    }
 
-        Thread.sleep(200);
+    @MediumTest
+    public void testAddCallbackAfterStart() throws InterruptedException {
+        final MyCallback callback = new MyCallback();
+        // The AVD has a duration as 100ms.
+        mActivity.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mActivity.setContentView(mLayoutId);
+                ImageView imageView = (ImageView) mActivity.findViewById(mImageViewId);
+                AnimatedVectorDrawable d1 = (AnimatedVectorDrawable) imageView.getDrawable();
+                d1.start();
+                d1.registerAnimationCallback(callback);
+            }
+        });
+        getInstrumentation().waitForIdleSync();
+        sleep(200);
+        // Whether or not the callback.start is true could vary when running on Render Thread.
+        // Therefore, we don't make assertion here. The most useful flag is the callback.mEnd.
+        assertTrue(callback.mEnd);
+    }
+
+    @MediumTest
+    public void testRemoveCallback() {
+        final MyCallback callback = new MyCallback();
+        // The AVD has a duration as 100ms.
+        mActivity.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mActivity.setContentView(mLayoutId);
+                ImageView imageView = (ImageView) mActivity.findViewById(mImageViewId);
+                AnimatedVectorDrawable d1 = (AnimatedVectorDrawable) imageView.getDrawable();
+                d1.registerAnimationCallback(callback);
+                assertTrue(d1.unregisterAnimationCallback(callback));
+                d1.start();
+            }
+        });
+        getInstrumentation().waitForIdleSync();
 
         assertFalse(callback.mStart);
         assertFalse(callback.mEnd);
     }
 
-    public void testClearCallback() throws InterruptedException {
-        MyCallback callback = new MyCallback();
-        final AnimatedVectorDrawable d1 = (AnimatedVectorDrawable) mResources.getDrawable(mResId);
+    @MediumTest
+    public void testClearCallback() {
+        final MyCallback callback = new MyCallback();
 
-        d1.registerAnimationCallback(callback);
-        d1.clearAnimationCallbacks();
         // The AVD has a duration as 100ms.
         mActivity.runOnUiThread(new Runnable() {
             @Override
             public void run() {
+                mActivity.setContentView(mLayoutId);
+                ImageView imageView = (ImageView) mActivity.findViewById(mImageViewId);
+                AnimatedVectorDrawable d1 = (AnimatedVectorDrawable) imageView.getDrawable();
+                d1.registerAnimationCallback(callback);
+                d1.clearAnimationCallbacks();
                 d1.start();
             }
         });
 
-        Thread.sleep(200);
+        getInstrumentation().waitForIdleSync();
 
         assertFalse(callback.mStart);
         assertFalse(callback.mEnd);
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/AnimationDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/AnimationDrawableTest.java
index 28a3c6b..33b99a4 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/AnimationDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/AnimationDrawableTest.java
@@ -16,7 +16,7 @@
 
 package android.graphics.drawable.cts;
 
-import com.android.cts.graphics.R;
+import android.graphics.cts.R;
 
 
 import org.xmlpull.v1.XmlPullParser;
@@ -50,7 +50,7 @@
     private Resources mResources;
 
     public AnimationDrawableTest() {
-        super("com.android.cts.graphics", ImageViewCtsActivity.class);
+        super("android.graphics.cts", ImageViewCtsActivity.class);
     }
 
     @Override
@@ -153,8 +153,22 @@
         assertStoppedAnimation(THIRD_FRAME_INDEX, THIRD_FRAME_DURATION);
     }
 
-    public void testRun() {
-        // This method should not be called directly.
+    public void testRun() throws Throwable {
+        assertFalse(mAnimationDrawable.isRunning());
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                mAnimationDrawable.run();
+            }
+        });
+
+        assertTrue(mAnimationDrawable.isRunning());
+        pollingCheckDrawable(SECOND_FRAME_INDEX, FIRST_FRAME_DURATION);
+
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                mAnimationDrawable.unscheduleSelf(mAnimationDrawable);
+            }
+        });
     }
 
     public void testUnscheduleSelf() throws Throwable {
@@ -275,6 +289,23 @@
         pollingCheckDrawable(THIRD_FRAME_INDEX, SECOND_FRAME_DURATION);
         // do not repeat
         assertStoppedAnimation(THIRD_FRAME_INDEX, THIRD_FRAME_DURATION);
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                // Set visible to false and restart to false
+                mAnimationDrawable.setVisible(false, false);
+            }
+        });
+        // Check that animation drawable stays on the same frame
+        assertStoppedAnimation(THIRD_FRAME_INDEX, THIRD_FRAME_DURATION);
+
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                // Set visible to true and restart to false
+                mAnimationDrawable.setVisible(true, false);
+            }
+        });
+        // Check that animation drawable stays on the same frame
+        assertStoppedAnimation(THIRD_FRAME_INDEX, THIRD_FRAME_DURATION);
     }
 
     public void testInflateCorrect() throws XmlPullParserException, IOException {
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/BitmapDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/BitmapDrawableTest.java
index 88e7acb..ed31a94 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/BitmapDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/BitmapDrawableTest.java
@@ -16,7 +16,10 @@
 
 package android.graphics.drawable.cts;
 
-import com.android.cts.graphics.R;
+import android.content.res.Resources.Theme;
+import android.graphics.BitmapFactory;
+import android.graphics.Rect;
+import android.graphics.cts.R;
 
 import org.xmlpull.v1.XmlPullParserException;
 
@@ -34,17 +37,30 @@
 import android.graphics.PorterDuff.Mode;
 import android.graphics.Shader.TileMode;
 import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
 import android.graphics.drawable.Drawable.ConstantState;
 import android.test.InstrumentationTestCase;
 import android.util.AttributeSet;
-import android.util.DisplayMetrics;
+import android.util.Xml;
 import android.view.Gravity;
 
 import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 
 public class BitmapDrawableTest extends InstrumentationTestCase {
+    // A small value is actually making sure that the values are matching
+    // exactly with the golden image.
+    // We can increase the threshold if the Skia is drawing with some variance
+    // on different devices. So far, the tests show they are matching correctly.
+    private static final float PIXEL_ERROR_THRESHOLD = 0.03f;
+    private static final float PIXEL_ERROR_COUNT_THRESHOLD = 0.005f;
+
+    // Set true to generate golden images, false for normal tests.
+    private static final boolean DBG_DUMP_PNG = false;
+
     // The target context.
     private Context mContext;
 
@@ -108,6 +124,17 @@
         assertEquals(Integer.MAX_VALUE, bitmapDrawable.getGravity());
     }
 
+    public void testAccessMipMap() {
+        Bitmap source = BitmapFactory.decodeResource(mContext.getResources(), R.raw.testimage);
+        BitmapDrawable bitmapDrawable = new BitmapDrawable(source);
+
+        bitmapDrawable.setMipMap(true);
+        assertTrue(source.hasMipMap());
+
+        bitmapDrawable.setMipMap(false);
+        assertFalse(source.hasMipMap());
+    }
+
     public void testSetAntiAlias() {
         InputStream source = mContext.getResources().openRawResource(R.raw.testimage);
         BitmapDrawable bitmapDrawable = new BitmapDrawable(source);
@@ -263,7 +290,7 @@
 
         d.setTint(Color.BLACK);
         d.setTintMode(Mode.SRC_OVER);
-        assertEquals("Nine-patch is tinted", Color.BLACK, DrawableTestingUtils.getPixel(d, 0, 0));
+        assertEquals("Nine-patch is tinted", Color.BLACK, DrawableTestUtils.getPixel(d, 0, 0));
 
         d.setTintList(null);
         d.setTintMode(null);
@@ -316,29 +343,62 @@
 
         InputStream source = mContext.getResources().openRawResource(R.drawable.size_48x48);
         bitmapDrawable = new BitmapDrawable(source);
-        bitmapDrawable.setTargetDensity(mContext.getResources().getDisplayMetrics().densityDpi);
+        bitmapDrawable.setTargetDensity(bitmapDrawable.getBitmap().getDensity());
         assertEquals(48, bitmapDrawable.getIntrinsicWidth());
         assertEquals(48, bitmapDrawable.getIntrinsicHeight());
     }
 
     @SuppressWarnings("deprecation")
     public void testSetTargetDensity() {
-        BitmapDrawable bitmapDrawable = new BitmapDrawable();
+        int sourceWidth, targetWidth;
+        int sourceHeight, targetHeight;
+        int sourceDensity, targetDensity;
+        BitmapDrawable bitmapDrawable;
+        Bitmap bitmap;
 
-        Bitmap bitmap = Bitmap.createBitmap(200, 300, Config.RGB_565);
+        sourceWidth = 200;
+        sourceHeight = 300;
+        bitmap = Bitmap.createBitmap(sourceWidth, sourceHeight, Config.RGB_565);
         Canvas canvas = new Canvas(bitmap);
         bitmapDrawable = new BitmapDrawable(bitmap);
-        bitmapDrawable.setTargetDensity(canvas.getDensity());
-        assertEquals(200, bitmapDrawable.getIntrinsicWidth());
-        assertEquals(300, bitmapDrawable.getIntrinsicHeight());
+        sourceDensity = bitmap.getDensity();
+        targetDensity = canvas.getDensity();
+        bitmapDrawable.setTargetDensity(canvas);
+        targetWidth = DrawableTestUtils.scaleBitmapFromDensity(
+                sourceWidth, sourceDensity, targetDensity);
+        targetHeight = DrawableTestUtils.scaleBitmapFromDensity(
+                sourceHeight, sourceDensity, targetDensity);
+        assertEquals(targetWidth, bitmapDrawable.getIntrinsicWidth());
+        assertEquals(targetHeight, bitmapDrawable.getIntrinsicHeight());
 
-        DisplayMetrics disMetrics = new DisplayMetrics();
-        disMetrics = getInstrumentation().getTargetContext().getResources().getDisplayMetrics();
+        sourceWidth = 200;
+        sourceHeight = 300;
+        bitmap = Bitmap.createBitmap(sourceWidth, sourceHeight, Config.RGB_565);
+        bitmapDrawable = new BitmapDrawable(bitmap);
+        sourceDensity = bitmap.getDensity();
+        targetDensity = mContext.getResources().getDisplayMetrics().densityDpi;
+        bitmapDrawable.setTargetDensity(mContext.getResources().getDisplayMetrics());
+        targetWidth = DrawableTestUtils.scaleBitmapFromDensity(
+                sourceWidth, sourceDensity, targetDensity);
+        targetHeight = DrawableTestUtils.scaleBitmapFromDensity(
+                sourceHeight, sourceDensity, targetDensity);
+        assertEquals(targetWidth, bitmapDrawable.getIntrinsicWidth());
+        assertEquals(targetHeight, bitmapDrawable.getIntrinsicHeight());
+
+        sourceWidth = 48;
+        sourceHeight = 48;
         InputStream source = mContext.getResources().openRawResource(R.drawable.size_48x48);
         bitmapDrawable = new BitmapDrawable(source);
-        bitmapDrawable.setTargetDensity(disMetrics.densityDpi);
-        assertEquals(48, bitmapDrawable.getIntrinsicWidth());
-        assertEquals(48, bitmapDrawable.getIntrinsicHeight());
+        bitmap = bitmapDrawable.getBitmap();
+        sourceDensity = bitmap.getDensity();
+        targetDensity = sourceDensity * 2;
+        bitmapDrawable.setTargetDensity(targetDensity);
+        targetWidth = DrawableTestUtils.scaleBitmapFromDensity(
+                sourceWidth, sourceDensity, targetDensity);
+        targetHeight = DrawableTestUtils.scaleBitmapFromDensity(
+                sourceHeight, sourceDensity, targetDensity);
+        assertEquals(targetWidth, bitmapDrawable.getIntrinsicWidth());
+        assertEquals(targetHeight, bitmapDrawable.getIntrinsicHeight());
     }
 
     @SuppressWarnings("deprecation")
@@ -440,4 +500,135 @@
         assertEquals(50, d2.getPaint().getAlpha());
         assertEquals(50, d3.getPaint().getAlpha());
     }
+
+    private static final int[] DENSITY_VALUES = new int[] {
+            160, 80, 320
+    };
+
+    private static final int[] DENSITY_IMAGES = new int[] {
+            R.drawable.bitmap_density
+    };
+
+    private static final int[][] DENSITY_GOLDEN_IMAGES = new int[][] {
+            {
+                    R.drawable.bitmap_density_golden_160,
+                    R.drawable.bitmap_density_golden_80,
+                    R.drawable.bitmap_density_golden_320,
+            }
+    };
+
+    public void testPreloadDensity() throws XmlPullParserException, IOException {
+        final Resources res = mContext.getResources();
+        final int densityDpi = res.getConfiguration().densityDpi;
+        try {
+            testPreloadDensityInner(res, DENSITY_IMAGES[0], DENSITY_VALUES, DENSITY_GOLDEN_IMAGES[0]);
+        } finally {
+            DrawableTestUtils.setResourcesDensity(res, densityDpi);
+        }
+    }
+
+    private void testPreloadDensityInner(Resources res, int sourceResId, int[] densities,
+            int[] goldenResIds) throws XmlPullParserException, IOException {
+        final Rect tempPadding = new Rect();
+
+        // Capture initial state at preload density.
+        final int preloadDensityDpi = densities[0];
+        DrawableTestUtils.setResourcesDensity(res, preloadDensityDpi);
+
+        final XmlResourceParser parser = DrawableTestUtils.getResourceParser(res, sourceResId);
+        final BitmapDrawable preloadedDrawable = new BitmapDrawable();
+        preloadedDrawable.inflate(res, parser, Xml.asAttributeSet(parser));
+
+        final ConstantState preloadedConstantState = preloadedDrawable.getConstantState();
+        final int origWidth = preloadedDrawable.getIntrinsicWidth();
+        final int origHeight = preloadedDrawable.getIntrinsicHeight();
+        assertFalse(preloadedDrawable.getPadding(tempPadding));
+
+        compareOrSave(preloadedDrawable, preloadDensityDpi, sourceResId, goldenResIds[0]);
+
+        for (int i = 1; i < densities.length; i++) {
+            final int scaledDensityDpi = densities[i];
+            final float scale = scaledDensityDpi / (float) preloadDensityDpi;
+            DrawableTestUtils.setResourcesDensity(res, scaledDensityDpi);
+
+            final BitmapDrawable scaledDrawable =
+                    (BitmapDrawable) preloadedConstantState.newDrawable(res);
+
+            // Sizes are rounded.
+            assertEquals(Math.round(origWidth * scale), scaledDrawable.getIntrinsicWidth());
+            assertEquals(Math.round(origHeight * scale), scaledDrawable.getIntrinsicHeight());
+
+            // Bitmaps have no padding.
+            assertFalse(scaledDrawable.getPadding(tempPadding));
+
+            compareOrSave(scaledDrawable, scaledDensityDpi, sourceResId, goldenResIds[i]);
+
+            // Ensure theme density is applied correctly. Unlike most
+            // drawables, we don't have any loss of accuracy because density
+            // changes are re-computed from the source every time.
+            DrawableTestUtils.setResourcesDensity(res, preloadDensityDpi);
+
+            final Theme t = res.newTheme();
+            scaledDrawable.applyTheme(t);
+            assertEquals(origWidth, scaledDrawable.getIntrinsicWidth());
+            assertEquals(origHeight, scaledDrawable.getIntrinsicHeight());
+            assertFalse(scaledDrawable.getPadding(tempPadding));
+        }
+    }
+
+    private void compareOrSave(Drawable dr, int densityDpi, int sourceResId, int goldenResId) {
+        final int width = dr.getIntrinsicWidth();
+        final int height = dr.getIntrinsicHeight();
+        final Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+        bitmap.setDensity(0);
+
+        final Canvas canvas = new Canvas(bitmap);
+        dr.setBounds(0, 0, width, height);
+        dr.draw(canvas);
+
+        if (DBG_DUMP_PNG) {
+            saveGoldenImage(bitmap, sourceResId, densityDpi);
+        } else {
+            final Bitmap golden = BitmapFactory.decodeResource(
+                    mContext.getResources(), goldenResId);
+            DrawableTestUtils.compareImages(densityDpi + " dpi", golden, bitmap,
+                    PIXEL_ERROR_THRESHOLD, PIXEL_ERROR_COUNT_THRESHOLD);
+        }
+    }
+
+    private void saveGoldenImage(Bitmap bitmap, int sourceResId, int densityDpi) {
+        // Save the image to the disk.
+        FileOutputStream out = null;
+
+        try {
+            final String outputFolder = "/sdcard/temp/";
+            final File folder = new File(outputFolder);
+            if (!folder.exists()) {
+                folder.mkdir();
+            }
+
+            final String sourceFilename = new File(
+                    mContext.getResources().getString(sourceResId)).getName();
+            final String sourceTitle = sourceFilename.substring(0, sourceFilename.lastIndexOf("."));
+            final String outputTitle = sourceTitle + "_golden_" + densityDpi;
+            final String outputFilename = outputFolder + outputTitle + ".png";
+            final File outputFile = new File(outputFilename);
+            if (!outputFile.exists()) {
+                outputFile.createNewFile();
+            }
+
+            out = new FileOutputStream(outputFile, false);
+            bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            if (out != null) {
+                try {
+                    out.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
 }
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/ClipDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/ClipDrawableTest.java
index e727350..074cbd9 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/ClipDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/ClipDrawableTest.java
@@ -16,7 +16,7 @@
 
 package android.graphics.drawable.cts;
 
-import com.android.cts.graphics.R;
+import android.graphics.cts.R;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/ColorDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/ColorDrawableTest.java
index 465a476..4be0046 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/ColorDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/ColorDrawableTest.java
@@ -16,17 +16,20 @@
 
 package android.graphics.drawable.cts;
 
-import android.content.res.ColorStateList;
 import android.content.res.XmlResourceParser;
+import android.graphics.Bitmap;
+import android.graphics.Bitmap.Config;
+import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.PixelFormat;
 import android.graphics.PorterDuff.Mode;
+import android.graphics.PorterDuffColorFilter;
 import android.graphics.drawable.ColorDrawable;
 import android.test.AndroidTestCase;
 import android.util.AttributeSet;
 import android.util.Xml;
 
-import com.android.cts.graphics.R;
+import android.graphics.cts.R;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
@@ -40,9 +43,6 @@
         new ColorDrawable(1);
     }
 
-    public void testDraw() {
-    }
-
     public void testAccessAlpha() {
         ColorDrawable colorDrawable = new ColorDrawable();
         assertEquals(0, colorDrawable.getAlpha());
@@ -120,19 +120,32 @@
 
     public void testSetColorFilter() {
         final ColorDrawable d = new ColorDrawable(Color.WHITE);
-        assertEquals(Color.WHITE, DrawableTestingUtils.getPixel(d, 0, 0));
+        assertEquals(Color.WHITE, DrawableTestUtils.getPixel(d, 0, 0));
 
         d.setColorFilter(Color.BLACK, Mode.SRC_OVER);
-        assertEquals(Color.BLACK, DrawableTestingUtils.getPixel(d, 0, 0));
+        assertEquals(Color.BLACK, DrawableTestUtils.getPixel(d, 0, 0));
 
+        d.setColorFilter(new PorterDuffColorFilter(Color.BLACK, Mode.SRC_OVER));
+        assertEquals(Color.BLACK, DrawableTestUtils.getPixel(d, 0, 0));
     }
 
     public void testSetTint() {
         final ColorDrawable d = new ColorDrawable(Color.WHITE);
-        assertEquals(Color.WHITE, DrawableTestingUtils.getPixel(d, 0, 0));
+        assertEquals(Color.WHITE, DrawableTestUtils.getPixel(d, 0, 0));
 
         d.setTint(Color.BLACK);
         d.setTintMode(Mode.SRC_OVER);
-        assertEquals(Color.BLACK, DrawableTestingUtils.getPixel(d, 0, 0));
+        assertEquals(Color.BLACK, DrawableTestUtils.getPixel(d, 0, 0));
+    }
+
+    public void testDraw() {
+        final ColorDrawable d = new ColorDrawable(Color.WHITE);
+        final Bitmap b = Bitmap.createBitmap(1, 1, Config.ARGB_8888);
+        final Canvas c = new Canvas(b);
+        d.setBounds(0, 0, 1, 1);
+        d.draw(c);
+        final int pixel = b.getPixel(0, 0);
+        b.recycle();
+        assertEquals(Color.WHITE, pixel);
     }
 }
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/CustomDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/CustomDrawableTest.java
new file mode 100644
index 0000000..7dff729
--- /dev/null
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/CustomDrawableTest.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.graphics.drawable.cts;
+
+import android.graphics.cts.R;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import android.content.res.Resources;
+import android.content.res.Resources.Theme;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.ColorFilter;
+import android.graphics.PixelFormat;
+import android.graphics.drawable.Drawable;
+import android.test.AndroidTestCase;
+import android.util.AttributeSet;
+
+import java.io.IOException;
+
+public class CustomDrawableTest extends AndroidTestCase {
+
+    public void testInflation() {
+        Drawable dr = getContext().getDrawable(R.drawable.custom_drawable);
+        assertTrue(dr instanceof CustomDrawable);
+        assertEquals(Color.RED, ((CustomDrawable) dr).getColor());
+    }
+
+    public static class CustomDrawable extends Drawable {
+        private static final int[] ATTRS = new int[] { android.R.attr.color };
+
+        private int mColor;
+
+        @Override
+        public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs, Theme theme)
+                throws XmlPullParserException, IOException {
+            super.inflate(r, parser, attrs, theme);
+
+            final TypedArray ta;
+            if (theme != null) {
+                ta = theme.obtainStyledAttributes(attrs, ATTRS, 0, 0);
+            } else {
+                ta = r.obtainAttributes(attrs, ATTRS);
+            }
+
+            mColor = ta.getColor(0, Color.BLACK);
+        }
+
+        public int getColor() {
+            return mColor;
+        }
+
+        @Override
+        public void draw(Canvas canvas) {
+
+        }
+
+        @Override
+        public void setAlpha(int alpha) {
+
+        }
+
+        @Override
+        public void setColorFilter(ColorFilter colorFilter) {
+
+        }
+
+        @Override
+        public int getOpacity() {
+            return PixelFormat.OPAQUE;
+        }
+    }
+}
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/DrawableContainerStateTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/DrawableContainerStateTest.java
index 701071b..8cbecab 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/DrawableContainerStateTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/DrawableContainerStateTest.java
@@ -117,6 +117,22 @@
         assertTrue(mDrawableContainerState.isStateful());
     }
 
+    public void testAccessEnterFadeDuration() {
+        mDrawableContainerState.setEnterFadeDuration(1000);
+        assertEquals(1000, mDrawableContainerState.getEnterFadeDuration());
+
+        mDrawableContainerState.setEnterFadeDuration(-1000);
+        assertEquals(-1000, mDrawableContainerState.getEnterFadeDuration());
+    }
+
+    public void testAccessExitFadeDuration() {
+        mDrawableContainerState.setExitFadeDuration(1000);
+        assertEquals(1000, mDrawableContainerState.getExitFadeDuration());
+
+        mDrawableContainerState.setExitFadeDuration(-1000);
+        assertEquals(-1000, mDrawableContainerState.getExitFadeDuration());
+    }
+
     public void testAccessConstantSize() {
         mDrawableContainerState.setConstantSize(true);
         assertTrue(mDrawableContainerState.isConstantSize());
@@ -236,13 +252,30 @@
         assertEquals(PixelFormat.UNKNOWN, mDrawableContainerState.getOpacity());
     }
 
-    public void testCanConstantState(){
+    public void testCanConstantState() {
+        DrawableContainer dr = new LevelListDrawable();
+        DrawableContainerState cs = (DrawableContainerState) dr.getConstantState();
+        assertTrue(cs.canConstantState());
+
+        cs.addChild(new MockDrawable());
+        assertFalse(cs.canConstantState());
     }
 
-    public void testGetChangingConfigurations(){
-    }
+    public void testGrowArray() {
+        DrawableContainer dr = new LevelListDrawable();
+        DrawableContainerState cs = (DrawableContainerState) dr.getConstantState();
 
-    public void testGrowArray(){
+        // Default capacity is undefined, so pin it to 0.
+        cs.growArray(0, 0);
+        try {
+            cs.getChild(10);
+            fail("Expected IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // Yay!
+        }
+
+        cs.growArray(0, 10);
+        cs.getChild(9);
     }
 
     private class MockDrawable extends Drawable {
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/DrawableContainerTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/DrawableContainerTest.java
index 79d2a1d..e78b04c 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/DrawableContainerTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/DrawableContainerTest.java
@@ -34,18 +34,22 @@
 public class DrawableContainerTest extends TestCase {
     private DrawableContainerState mDrawableContainerState;
 
-    private MockDrawableContainer mDrawableContainer;
+    private MockDrawableContainer mMockDrawableContainer;
+    private DrawableContainer mDrawableContainer;
 
     @Override
     protected void setUp() throws Exception {
         super.setUp();
+
         // DrawableContainerState has no public constructor. Obtain an instance through
         // LevelListDrawable.getConstants(). This is fine for testing the final methods of
         // DrawableContainerState.
         mDrawableContainerState =
             (DrawableContainerState) new LevelListDrawable().getConstantState();
         assertNotNull(mDrawableContainerState);
-        mDrawableContainer = new MockDrawableContainer();
+
+        mMockDrawableContainer = new MockDrawableContainer();
+        mDrawableContainer = mMockDrawableContainer;
     }
 
     public void testDraw() {
@@ -55,7 +59,7 @@
         mDrawableContainer.draw(null);
         mDrawableContainer.draw(new Canvas());
 
-        mDrawableContainer.setConstantState(mDrawableContainerState);
+        mMockDrawableContainer.setConstantState(mDrawableContainerState);
         MockDrawable dr = new MockDrawable();
         addAndSelectDrawable(dr);
 
@@ -68,7 +72,34 @@
         assertTrue(dr.hasDrawCalled());
     }
 
+    public void testSetEnterFadeDuration() {
+        helpTestSetEnterFadeDuration(1000);
+        helpTestSetEnterFadeDuration(0);
+    }
+
+    private void helpTestSetEnterFadeDuration(int enterFadeDuration) {
+        DrawableContainer container = new LevelListDrawable();
+        DrawableContainerState cs = ((DrawableContainerState) container.getConstantState());
+        container.setEnterFadeDuration(enterFadeDuration);
+        assertEquals(enterFadeDuration, cs.getEnterFadeDuration());
+    }
+
+    public void testSetExitFadeDuration() {
+        helpTestSetExitFadeDuration(1000);
+        helpTestSetExitFadeDuration(0);
+    }
+
+    private void helpTestSetExitFadeDuration(int exitFadeDuration) {
+        DrawableContainer container = new LevelListDrawable();
+        DrawableContainerState cs = ((DrawableContainerState) container.getConstantState());
+        container.setExitFadeDuration(exitFadeDuration);
+        assertEquals(exitFadeDuration, cs.getExitFadeDuration());
+    }
+
     public void testGetChangingConfigurations() {
+        // Workaround for CTS coverage not recognizing calls on subclasses.
+        DrawableContainer dr = mDrawableContainer;
+
         assertConstantStateNotSet();
 
         try {
@@ -77,14 +108,14 @@
         } catch (NullPointerException e) {
         }
 
-        mDrawableContainer.setConstantState(mDrawableContainerState);
+        mMockDrawableContainer.setConstantState(mDrawableContainerState);
         MockDrawable dr0 = new MockDrawable();
         dr0.setChangingConfigurations(0x001);
         mDrawableContainerState.addChild(dr0);
         MockDrawable dr1 = new MockDrawable();
         dr1.setChangingConfigurations(0x010);
         mDrawableContainerState.addChild(dr1);
-        mDrawableContainer.selectDrawable(0);
+        dr.selectDrawable(0);
         assertSame(dr0, mDrawableContainer.getCurrent());
 
         // can not set mDrawableContainerState's ChangingConfigurations
@@ -94,6 +125,9 @@
     }
 
     public void testGetPadding() {
+        // Workaround for CTS coverage not recognizing calls on subclasses.
+        DrawableContainer dr = mDrawableContainer;
+
         assertConstantStateNotSet();
         assertNull(mDrawableContainer.getCurrent());
 
@@ -104,14 +138,14 @@
         } catch (NullPointerException e) {
         }
 
-        mDrawableContainer.setConstantState(mDrawableContainerState);
+        mMockDrawableContainer.setConstantState(mDrawableContainerState);
         MockDrawable dr0 = new MockDrawable();
         dr0.setPadding(new Rect(1, 2, 0, 0));
         mDrawableContainerState.addChild(dr0);
         MockDrawable dr1 = new MockDrawable();
         dr1.setPadding(new Rect(0, 0, 3, 4));
         mDrawableContainerState.addChild(dr1);
-        mDrawableContainer.selectDrawable(0);
+        dr.selectDrawable(0);
         assertSame(dr0, mDrawableContainer.getCurrent());
 
         // use the current drawable's padding
@@ -127,7 +161,7 @@
         assertEquals(mDrawableContainerState.getConstantPadding(), result);
 
         // use default padding
-        mDrawableContainer.selectDrawable(-1);
+        dr.selectDrawable(-1);
         assertNull(mDrawableContainer.getCurrent());
         mDrawableContainerState.setVariablePadding(true);
         assertNull(mDrawableContainerState.getConstantPadding());
@@ -142,31 +176,34 @@
     }
 
     public void testSetAlpha() {
+        // Workaround for CTS coverage not recognizing calls on subclasses.
+        DrawableContainer dr = mDrawableContainer;
+
         assertConstantStateNotSet();
         assertNull(mDrawableContainer.getCurrent());
 
-        mDrawableContainer.setAlpha(0);
+        dr.setAlpha(0);
 
-        mDrawableContainer.setConstantState(mDrawableContainerState);
-        MockDrawable dr = new MockDrawable();
-        addAndSelectDrawable(dr);
+        mMockDrawableContainer.setConstantState(mDrawableContainerState);
+        MockDrawable mockDrawable = new MockDrawable();
+        addAndSelectDrawable(mockDrawable);
 
         // call current drawable's setAlpha if alpha is changed.
-        dr.reset();
-        mDrawableContainer.setAlpha(1);
-        assertTrue(dr.hasSetAlphaCalled());
+        mockDrawable.reset();
+        dr.setAlpha(1);
+        assertTrue(mockDrawable.hasSetAlphaCalled());
 
         // does not call it if alpha is not changed.
-        dr.reset();
-        mDrawableContainer.setAlpha(1);
-        assertFalse(dr.hasSetAlphaCalled());
+        mockDrawable.reset();
+        dr.setAlpha(1);
+        assertFalse(mockDrawable.hasSetAlphaCalled());
     }
 
     public void testSetDither() {
         assertConstantStateNotSet();
         assertNull(mDrawableContainer.getCurrent());
 
-        mDrawableContainer.setConstantState(mDrawableContainerState);
+        mMockDrawableContainer.setConstantState(mDrawableContainerState);
         mDrawableContainer.setDither(false);
         mDrawableContainer.setDither(true);
 
@@ -189,7 +226,7 @@
         assertConstantStateNotSet();
         assertNull(mDrawableContainer.getCurrent());
 
-        mDrawableContainer.setConstantState(mDrawableContainerState);
+        mMockDrawableContainer.setConstantState(mDrawableContainerState);
 
         MockDrawable dr = new MockDrawable();
         addAndSelectDrawable(dr);
@@ -208,7 +245,7 @@
         assertConstantStateNotSet();
         assertNull(mDrawableContainer.getCurrent());
 
-        mDrawableContainer.setConstantState(mDrawableContainerState);
+        mMockDrawableContainer.setConstantState(mDrawableContainerState);
 
         MockDrawable dr = new MockDrawable();
         addAndSelectDrawable(dr);
@@ -223,32 +260,35 @@
     }
 
     public void testSetColorFilter() {
+        // Workaround for CTS coverage not recognizing calls on subclasses.
+        DrawableContainer dr = mDrawableContainer;
+
         assertConstantStateNotSet();
         assertNull(mDrawableContainer.getCurrent());
 
-        mDrawableContainer.setConstantState(mDrawableContainerState);
-        mDrawableContainer.setColorFilter(null);
-        mDrawableContainer.setColorFilter(new ColorFilter());
+        mMockDrawableContainer.setConstantState(mDrawableContainerState);
+        dr.setColorFilter(null);
+        dr.setColorFilter(new ColorFilter());
 
-        MockDrawable dr = new MockDrawable();
-        addAndSelectDrawable(dr);
+        MockDrawable mockDrawable = new MockDrawable();
+        addAndSelectDrawable(mockDrawable);
 
         // call current drawable's setColorFilter if filter is changed.
-        dr.reset();
-        mDrawableContainer.setColorFilter(null);
-        assertTrue(dr.hasSetColorFilterCalled());
+        mockDrawable.reset();
+        dr.setColorFilter(null);
+        assertTrue(mockDrawable.hasSetColorFilterCalled());
 
         // does not call it if filter is not changed.
-        dr.reset();
-        mDrawableContainer.setColorFilter(new ColorFilter());
-        assertTrue(dr.hasSetColorFilterCalled());
+        mockDrawable.reset();
+        dr.setColorFilter(new ColorFilter());
+        assertTrue(mockDrawable.hasSetColorFilterCalled());
     }
 
     public void testSetTint() {
         assertConstantStateNotSet();
         assertNull(mDrawableContainer.getCurrent());
 
-        mDrawableContainer.setConstantState(mDrawableContainerState);
+        mMockDrawableContainer.setConstantState(mDrawableContainerState);
         mDrawableContainer.setTint(Color.BLACK);
         mDrawableContainer.setTintMode(Mode.SRC_OVER);
 
@@ -267,10 +307,10 @@
         assertConstantStateNotSet();
         assertNull(mDrawableContainer.getCurrent());
 
-        mDrawableContainer.onBoundsChange(new Rect());
-        mDrawableContainer.onBoundsChange(null);
+        mMockDrawableContainer.onBoundsChange(new Rect());
+        mMockDrawableContainer.onBoundsChange(null);
 
-        mDrawableContainer.setConstantState(mDrawableContainerState);
+        mMockDrawableContainer.setConstantState(mDrawableContainerState);
         MockDrawable dr = new MockDrawable();
         dr.setBounds(new Rect());
         addAndSelectDrawable(dr);
@@ -278,17 +318,17 @@
         // set current drawable's bounds.
         dr.reset();
         assertEquals(new Rect(), dr.getBounds());
-        mDrawableContainer.onBoundsChange(new Rect(1, 1, 1, 1));
+        mMockDrawableContainer.onBoundsChange(new Rect(1, 1, 1, 1));
         assertTrue(dr.hasOnBoundsChangedCalled());
         assertEquals(new Rect(1, 1, 1, 1), dr.getBounds());
 
         dr.reset();
-        mDrawableContainer.onBoundsChange(new Rect(1, 1, 1, 1));
+        mMockDrawableContainer.onBoundsChange(new Rect(1, 1, 1, 1));
         assertFalse(dr.hasOnBoundsChangedCalled());
         assertEquals(new Rect(1, 1, 1, 1), dr.getBounds());
 
         try {
-            mDrawableContainer.onBoundsChange(null);
+            mMockDrawableContainer.onBoundsChange(null);
             fail("Should throw NullPointerException if the bounds is null.");
         } catch (NullPointerException e) {
         }
@@ -303,7 +343,7 @@
         } catch (NullPointerException e) {
         }
 
-        mDrawableContainer.setConstantState(mDrawableContainerState);
+        mMockDrawableContainer.setConstantState(mDrawableContainerState);
         MockDrawable dr0 = new MockDrawable();
         dr0.setStateful(true);
         mDrawableContainerState.addChild(dr0);
@@ -324,10 +364,10 @@
         assertConstantStateNotSet();
         assertNull(mDrawableContainer.getCurrent());
 
-        assertFalse(mDrawableContainer.onStateChange(new int[] { 0 }));
-        assertFalse(mDrawableContainer.onStateChange(null));
+        assertFalse(mMockDrawableContainer.onStateChange(new int[] { 0 }));
+        assertFalse(mMockDrawableContainer.onStateChange(null));
 
-        mDrawableContainer.setConstantState(mDrawableContainerState);
+        mMockDrawableContainer.setConstantState(mDrawableContainerState);
         MockDrawable dr = new MockDrawable();
         dr.setState(new int[] { 0 });
         addAndSelectDrawable(dr);
@@ -335,17 +375,17 @@
         // set current drawable's state.
         dr.reset();
         assertNotNull(dr.getState());
-        mDrawableContainer.onStateChange(null);
+        mMockDrawableContainer.onStateChange(null);
         assertTrue(dr.hasOnStateChangedCalled());
         assertNull(dr.getState());
 
         dr.reset();
-        mDrawableContainer.onStateChange(new int[] { 0 });
+        mMockDrawableContainer.onStateChange(new int[] { 0 });
         assertTrue(dr.hasOnStateChangedCalled());
         assertTrue(Arrays.equals(new int[] { 0 }, dr.getState()));
 
         dr.reset();
-        assertFalse(mDrawableContainer.onStateChange(new int[] { 0 }));
+        assertFalse(mMockDrawableContainer.onStateChange(new int[] { 0 }));
         assertFalse(dr.hasOnStateChangedCalled());
         assertTrue(Arrays.equals(new int[] { 0 }, dr.getState()));
     }
@@ -354,10 +394,10 @@
         assertConstantStateNotSet();
         assertNull(mDrawableContainer.getCurrent());
 
-        assertFalse(mDrawableContainer.onLevelChange(Integer.MAX_VALUE));
-        assertFalse(mDrawableContainer.onLevelChange(Integer.MIN_VALUE));
+        assertFalse(mMockDrawableContainer.onLevelChange(Integer.MAX_VALUE));
+        assertFalse(mMockDrawableContainer.onLevelChange(Integer.MIN_VALUE));
 
-        mDrawableContainer.setConstantState(mDrawableContainerState);
+        mMockDrawableContainer.setConstantState(mDrawableContainerState);
         MockDrawable dr = new MockDrawable();
         dr.setLevel(0);
         addAndSelectDrawable(dr);
@@ -365,19 +405,19 @@
         // set current drawable's level.
         dr.reset();
         assertEquals(0, dr.getLevel());
-        mDrawableContainer.onLevelChange(Integer.MAX_VALUE);
+        mMockDrawableContainer.onLevelChange(Integer.MAX_VALUE);
         assertEquals(Integer.MAX_VALUE, dr.getLevel());
         assertTrue(dr.hasOnLevelChangedCalled());
 
         dr.reset();
         assertEquals(Integer.MAX_VALUE, dr.getLevel());
-        mDrawableContainer.onLevelChange(Integer.MIN_VALUE);
+        mMockDrawableContainer.onLevelChange(Integer.MIN_VALUE);
         assertEquals(Integer.MIN_VALUE, dr.getLevel());
         assertTrue(dr.hasOnLevelChangedCalled());
 
         dr.reset();
         assertEquals(Integer.MIN_VALUE, dr.getLevel());
-        assertFalse(mDrawableContainer.onLevelChange(Integer.MIN_VALUE));
+        assertFalse(mMockDrawableContainer.onLevelChange(Integer.MIN_VALUE));
         assertEquals(Integer.MIN_VALUE, dr.getLevel());
         assertFalse(dr.hasOnLevelChangedCalled());
     }
@@ -391,7 +431,7 @@
         } catch (NullPointerException e) {
         }
 
-        mDrawableContainer.setConstantState(mDrawableContainerState);
+        mMockDrawableContainer.setConstantState(mDrawableContainerState);
         MockDrawable dr0 = new MockDrawable();
         dr0.setIntrinsicWidth(1);
         mDrawableContainerState.addChild(dr0);
@@ -425,7 +465,7 @@
         } catch (NullPointerException e) {
         }
 
-        mDrawableContainer.setConstantState(mDrawableContainerState);
+        mMockDrawableContainer.setConstantState(mDrawableContainerState);
         MockDrawable dr0 = new MockDrawable();
         dr0.setIntrinsicHeight(1);
         mDrawableContainerState.addChild(dr0);
@@ -459,7 +499,7 @@
         } catch (NullPointerException e) {
         }
 
-        mDrawableContainer.setConstantState(mDrawableContainerState);
+        mMockDrawableContainer.setConstantState(mDrawableContainerState);
         MockDrawable dr0 = new MockDrawable();
         dr0.setMinimumWidth(1);
         mDrawableContainerState.addChild(dr0);
@@ -493,7 +533,7 @@
         } catch (NullPointerException e) {
         }
 
-        mDrawableContainer.setConstantState(mDrawableContainerState);
+        mMockDrawableContainer.setConstantState(mDrawableContainerState);
         MockDrawable dr0 = new MockDrawable();
         dr0.setMinimumHeight(1);
         mDrawableContainerState.addChild(dr0);
@@ -519,51 +559,57 @@
     }
 
     public void testInvalidateDrawable() {
+        // Workaround for CTS coverage not recognizing calls on subclasses.
+        DrawableContainer dr = mDrawableContainer;
+
         assertConstantStateNotSet();
         assertNull(mDrawableContainer.getCurrent());
 
         mDrawableContainer.setCallback(null);
-        mDrawableContainer.invalidateDrawable(mDrawableContainer);
-        mDrawableContainer.invalidateDrawable(null);
+        dr.invalidateDrawable(mDrawableContainer);
+        dr.invalidateDrawable(null);
 
         MockCallBack callback = new MockCallBack();
         mDrawableContainer.setCallback(callback);
 
         callback.reset();
-        mDrawableContainer.invalidateDrawable(mDrawableContainer);
+        dr.invalidateDrawable(mDrawableContainer);
         assertFalse(callback.hasInvalidateDrawableCalled());
 
         // the callback method can be called if the drawable passed in and the
         // current drawble are both null
         callback.reset();
-        mDrawableContainer.invalidateDrawable(null);
+        dr.invalidateDrawable(null);
         assertTrue(callback.hasInvalidateDrawableCalled());
 
-        mDrawableContainer.setConstantState(mDrawableContainerState);
-        MockDrawable dr = new MockDrawable();
-        addAndSelectDrawable(dr);
+        mMockDrawableContainer.setConstantState(mDrawableContainerState);
+        MockDrawable mockDrawable = new MockDrawable();
+        addAndSelectDrawable(mockDrawable);
 
         callback.reset();
-        mDrawableContainer.invalidateDrawable(mDrawableContainer);
+        dr.invalidateDrawable(mDrawableContainer);
         assertFalse(callback.hasInvalidateDrawableCalled());
 
         callback.reset();
-        mDrawableContainer.invalidateDrawable(null);
+        dr.invalidateDrawable(null);
         assertFalse(callback.hasInvalidateDrawableCalled());
 
         // Call the callback method if the drawable is selected.
         callback.reset();
-        mDrawableContainer.invalidateDrawable(dr);
+        dr.invalidateDrawable(mockDrawable);
         assertTrue(callback.hasInvalidateDrawableCalled());
     }
 
     public void testScheduleDrawable() {
+        // Workaround for CTS coverage not recognizing calls on subclasses.
+        DrawableContainer dr = mDrawableContainer;
+
         assertConstantStateNotSet();
         assertNull(mDrawableContainer.getCurrent());
 
         mDrawableContainer.setCallback(null);
-        mDrawableContainer.scheduleDrawable(mDrawableContainer, null, 0);
-        mDrawableContainer.scheduleDrawable(null, new Runnable() {
+        dr.scheduleDrawable(mDrawableContainer, null, 0);
+        dr.scheduleDrawable(null, new Runnable() {
                 public void run() {
                 }
             }, 0);
@@ -572,28 +618,28 @@
         mDrawableContainer.setCallback(callback);
 
         callback.reset();
-        mDrawableContainer.scheduleDrawable(mDrawableContainer, null, 0);
+        dr.scheduleDrawable(mDrawableContainer, null, 0);
         assertFalse(callback.hasScheduleDrawableCalled());
 
         // the callback method can be called if the drawable passed in and the
         // current drawble are both null
         callback.reset();
-        mDrawableContainer.scheduleDrawable(null, new Runnable() {
+        dr.scheduleDrawable(null, new Runnable() {
                 public void run() {
                 }
             }, 0);
         assertTrue(callback.hasScheduleDrawableCalled());
 
-        mDrawableContainer.setConstantState(mDrawableContainerState);
-        MockDrawable dr = new MockDrawable();
-        addAndSelectDrawable(dr);
+        mMockDrawableContainer.setConstantState(mDrawableContainerState);
+        MockDrawable mockDrawable = new MockDrawable();
+        addAndSelectDrawable(mockDrawable);
 
         callback.reset();
-        mDrawableContainer.scheduleDrawable(mDrawableContainer, null, 0);
+        dr.scheduleDrawable(mDrawableContainer, null, 0);
         assertFalse(callback.hasScheduleDrawableCalled());
 
         callback.reset();
-        mDrawableContainer.scheduleDrawable(null, new Runnable() {
+        dr.scheduleDrawable(null, new Runnable() {
                 public void run() {
                 }
             }, 0);
@@ -601,17 +647,20 @@
 
         // Call the callback method if the drawable is selected.
         callback.reset();
-        mDrawableContainer.scheduleDrawable(dr, null, 0);
+        dr.scheduleDrawable(mockDrawable, null, 0);
         assertTrue(callback.hasScheduleDrawableCalled());
     }
 
     public void testUnscheduleDrawable() {
+        // Workaround for CTS coverage not recognizing calls on subclasses.
+        DrawableContainer dr = mDrawableContainer;
+
         assertConstantStateNotSet();
         assertNull(mDrawableContainer.getCurrent());
 
         mDrawableContainer.setCallback(null);
-        mDrawableContainer.unscheduleDrawable(mDrawableContainer, null);
-        mDrawableContainer.unscheduleDrawable(null, new Runnable() {
+        dr.unscheduleDrawable(mDrawableContainer, null);
+        dr.unscheduleDrawable(null, new Runnable() {
                 public void run() {
                 }
             });
@@ -620,28 +669,28 @@
         mDrawableContainer.setCallback(callback);
 
         callback.reset();
-        mDrawableContainer.unscheduleDrawable(mDrawableContainer, null);
+        dr.unscheduleDrawable(mDrawableContainer, null);
         assertFalse(callback.hasUnscheduleDrawableCalled());
 
         // the callback method can be called if the drawable passed in and the
         // current drawble are both null
         callback.reset();
-        mDrawableContainer.unscheduleDrawable(null, new Runnable() {
+        dr.unscheduleDrawable(null, new Runnable() {
                 public void run() {
                 }
             });
         assertTrue(callback.hasUnscheduleDrawableCalled());
 
-        mDrawableContainer.setConstantState(mDrawableContainerState);
-        MockDrawable dr = new MockDrawable();
-        addAndSelectDrawable(dr);
+        mMockDrawableContainer.setConstantState(mDrawableContainerState);
+        MockDrawable mockDrawable = new MockDrawable();
+        addAndSelectDrawable(mockDrawable);
 
         callback.reset();
-        mDrawableContainer.unscheduleDrawable(mDrawableContainer, null);
+        dr.unscheduleDrawable(mDrawableContainer, null);
         assertFalse(callback.hasUnscheduleDrawableCalled());
 
         callback.reset();
-        mDrawableContainer.unscheduleDrawable(null, new Runnable() {
+        dr.unscheduleDrawable(null, new Runnable() {
                 public void run() {
                 }
             });
@@ -649,7 +698,7 @@
 
         // Call the callback method if the drawable is selected.
         callback.reset();
-        mDrawableContainer.unscheduleDrawable(dr, null);
+        dr.unscheduleDrawable(mockDrawable, null);
         assertTrue(callback.hasUnscheduleDrawableCalled());
     }
 
@@ -663,7 +712,7 @@
         assertFalse(mDrawableContainer.setVisible(false, false));
         assertTrue(mDrawableContainer.setVisible(true, false));
 
-        mDrawableContainer.setConstantState(mDrawableContainerState);
+        mMockDrawableContainer.setConstantState(mDrawableContainerState);
         MockDrawable dr = new MockDrawable();
         addAndSelectDrawable(dr);
 
@@ -676,42 +725,48 @@
     }
 
     public void testGetOpacity() {
+        // Workaround for CTS coverage not recognizing calls on subclasses.
+        DrawableContainer dr = mDrawableContainer;
+
         assertConstantStateNotSet();
 
         // there is no child, so the container is transparent
-        assertEquals(PixelFormat.TRANSPARENT, mDrawableContainer.getOpacity());
+        assertEquals(PixelFormat.TRANSPARENT, dr.getOpacity());
 
-        mDrawableContainer.setConstantState(mDrawableContainerState);
+        mMockDrawableContainer.setConstantState(mDrawableContainerState);
         MockDrawable dr0 = new MockDrawable();
         dr0.setOpacity(PixelFormat.OPAQUE);
         mDrawableContainerState.addChild(dr0);
         // no child selected yet
-        assertEquals(PixelFormat.TRANSPARENT, mDrawableContainer.getOpacity());
+        assertEquals(PixelFormat.TRANSPARENT, dr.getOpacity());
 
-        mDrawableContainer.selectDrawable(0);
-        assertEquals(mDrawableContainerState.getOpacity(), mDrawableContainer.getOpacity());
+        dr.selectDrawable(0);
+        assertEquals(mDrawableContainerState.getOpacity(), dr.getOpacity());
         assertEquals(PixelFormat.OPAQUE, mDrawableContainer.getOpacity());
 
         MockDrawable dr1 = new MockDrawable();
         dr1.setOpacity(PixelFormat.TRANSLUCENT);
         mDrawableContainerState.addChild(dr1);
 
-        mDrawableContainer.selectDrawable(1);
-        assertEquals(mDrawableContainerState.getOpacity(), mDrawableContainer.getOpacity());
-        assertEquals(PixelFormat.TRANSLUCENT, mDrawableContainer.getOpacity());
+        dr.selectDrawable(1);
+        assertEquals(mDrawableContainerState.getOpacity(), dr.getOpacity());
+        assertEquals(PixelFormat.TRANSLUCENT, dr.getOpacity());
     }
 
     public void testAccessCurrentDrawable() {
+        // Workaround for CTS coverage not recognizing calls on subclasses.
+        DrawableContainer dr = mDrawableContainer;
+
         assertConstantStateNotSet();
 
         assertNull(mDrawableContainer.getCurrent());
         try {
-            mDrawableContainer.selectDrawable(0);
+            dr.selectDrawable(0);
             fail("Should throw NullPointerException if the constant state is not set.");
         } catch (NullPointerException e) {
         }
 
-        mDrawableContainer.setConstantState(mDrawableContainerState);
+        mMockDrawableContainer.setConstantState(mDrawableContainerState);
         MockDrawable dr0 = new MockDrawable();
         dr0.setVisible(false, false);
         assertFalse(dr0.isVisible());
@@ -721,25 +776,25 @@
         assertFalse(dr1.isVisible());
         mDrawableContainerState.addChild(dr1);
 
-        assertTrue(mDrawableContainer.selectDrawable(0));
+        assertTrue(dr.selectDrawable(0));
         assertSame(dr0, mDrawableContainer.getCurrent());
         assertTrue(dr0.isVisible());
 
-        assertFalse(mDrawableContainer.selectDrawable(0));
+        assertFalse(dr.selectDrawable(0));
 
-        assertTrue(mDrawableContainer.selectDrawable(1));
+        assertTrue(dr.selectDrawable(1));
         assertSame(dr1, mDrawableContainer.getCurrent());
         assertTrue(dr1.isVisible());
         assertFalse(dr0.isVisible());
 
-        assertFalse(mDrawableContainer.selectDrawable(1));
+        assertFalse(dr.selectDrawable(1));
 
-        assertTrue(mDrawableContainer.selectDrawable(-1));
+        assertTrue(dr.selectDrawable(-1));
         assertNull(mDrawableContainer.getCurrent());
         assertFalse(dr0.isVisible());
         assertFalse(dr1.isVisible());
 
-        assertTrue(mDrawableContainer.selectDrawable(2));
+        assertTrue(dr.selectDrawable(2));
         assertNull(mDrawableContainer.getCurrent());
         assertFalse(dr0.isVisible());
         assertFalse(dr1.isVisible());
@@ -752,10 +807,10 @@
         } catch (NullPointerException e) {
         }
 
-        mDrawableContainer.setConstantState(mDrawableContainerState);
+        mMockDrawableContainer.setConstantState(mDrawableContainerState);
         assertSame(mDrawableContainerState, mDrawableContainer.getConstantState());
 
-        mDrawableContainer.setConstantState(null);
+        mMockDrawableContainer.setConstantState(null);
         assertConstantStateNotSet();
     }
 
@@ -767,17 +822,20 @@
         } catch (NullPointerException e) {
         }
 
-        mDrawableContainer.setConstantState(mDrawableContainerState);
+        mMockDrawableContainer.setConstantState(mDrawableContainerState);
         MockDrawable dr0 = new MockDrawable();
         mDrawableContainerState.addChild(dr0);
         mDrawableContainer.mutate();
         assertTrue(dr0.hasMutateCalled());
     }
 
-    private void addAndSelectDrawable(MockDrawable dr) {
-        int pos = mDrawableContainerState.addChild(dr);
-        mDrawableContainer.selectDrawable(pos);
-        assertSame(dr, mDrawableContainer.getCurrent());
+    private void addAndSelectDrawable(MockDrawable mockDrawable) {
+        // Workaround for CTS coverage not recognizing calls on subclasses.
+        DrawableContainer dr = mDrawableContainer;
+
+        int pos = mDrawableContainerState.addChild(mockDrawable);
+        dr.selectDrawable(pos);
+        assertSame(mockDrawable, dr.getCurrent());
     }
 
     private void assertConstantStateNotSet() {
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/DrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/DrawableTest.java
index a91353f..bc452f3 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/DrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/DrawableTest.java
@@ -16,8 +16,10 @@
 
 package android.graphics.drawable.cts;
 
+import android.content.res.Resources.Theme;
+import android.graphics.drawable.Drawable.Callback;
 import android.view.View;
-import com.android.cts.graphics.R;
+import android.graphics.cts.R;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
@@ -46,6 +48,8 @@
 import android.util.TypedValue;
 import android.util.Xml;
 
+import static org.mockito.Mockito.mock;
+
 public class DrawableTest extends AndroidTestCase {
     Resources mResources;
 
@@ -57,7 +61,7 @@
     }
 
     public void testClearColorFilter() {
-        MockDrawable mockDrawable = new MockDrawable();
+        Drawable mockDrawable = new MockDrawable();
         mockDrawable.clearColorFilter();
         assertNull(mockDrawable.getColorFilter());
 
@@ -70,7 +74,7 @@
     }
 
     public void testCopyBounds() {
-        MockDrawable mockDrawable = new MockDrawable();
+        Drawable mockDrawable = new MockDrawable();
         Rect rect1 = mockDrawable.copyBounds();
         Rect r1 = new Rect();
         mockDrawable.copyBounds(r1);
@@ -301,9 +305,23 @@
     public void testCreateFromXml() throws XmlPullParserException, IOException {
         XmlPullParser parser = mResources.getXml(R.drawable.gradientdrawable);
         Drawable drawable = Drawable.createFromXml(mResources, parser);
-        // values from gradientdrawable.xml
-        assertEquals(42, drawable.getIntrinsicWidth());
-        assertEquals(63, drawable.getIntrinsicHeight());
+        assertNotNull(drawable);
+
+        Drawable expected = mResources.getDrawable(R.drawable.gradientdrawable, null);
+        assertEquals(expected.getIntrinsicWidth(), drawable.getIntrinsicWidth());
+        assertEquals(expected.getIntrinsicHeight(), drawable.getIntrinsicHeight());
+    }
+
+    public void testCreateFromXmlThemed() throws XmlPullParserException, IOException {
+        XmlPullParser parser = mResources.getXml(R.drawable.gradientdrawable_theme);
+        Theme theme = mResources.newTheme();
+        theme.applyStyle(R.style.Theme_ThemedDrawableTest, true);
+        Drawable drawable = Drawable.createFromXml(mResources, parser, theme);
+        assertNotNull(drawable);
+
+        Drawable expected = mResources.getDrawable(R.drawable.gradientdrawable_theme, theme);
+        assertEquals(expected.getIntrinsicWidth(), drawable.getIntrinsicWidth());
+        assertEquals(expected.getIntrinsicHeight(), drawable.getIntrinsicHeight());
     }
 
     public void testCreateFromXmlInner() throws XmlPullParserException, IOException {
@@ -315,14 +333,29 @@
         Drawable drawable = Drawable.createFromXmlInner(mResources, parser, attrs);
         assertNotNull(drawable);
 
-        Drawable expected = mResources.getDrawable(R.drawable.gradientdrawable);
+        Drawable expected = mResources.getDrawable(R.drawable.gradientdrawable, null);
+        assertEquals(expected.getIntrinsicWidth(), drawable.getIntrinsicWidth());
+        assertEquals(expected.getIntrinsicHeight(), drawable.getIntrinsicHeight());
+    }
 
+    public void testCreateFromXmlInnerThemed() throws XmlPullParserException, IOException {
+        XmlPullParser parser = mResources.getXml(R.drawable.gradientdrawable_theme);
+        while (parser.next() != XmlPullParser.START_TAG) {
+            // ignore event, just seek to first tag
+        }
+        AttributeSet attrs = Xml.asAttributeSet(parser);
+        Theme theme = mResources.newTheme();
+        theme.applyStyle(R.style.Theme_ThemedDrawableTest, true);
+        Drawable drawable = Drawable.createFromXmlInner(mResources, parser, attrs, theme);
+        assertNotNull(drawable);
+
+        Drawable expected = mResources.getDrawable(R.drawable.gradientdrawable_theme, theme);
         assertEquals(expected.getIntrinsicWidth(), drawable.getIntrinsicWidth());
         assertEquals(expected.getIntrinsicHeight(), drawable.getIntrinsicHeight());
     }
 
     public void testAccessBounds() {
-        MockDrawable mockDrawable = new MockDrawable();
+        Drawable mockDrawable = new MockDrawable();
         mockDrawable.setBounds(0, 0, 100, 100);
         Rect r = mockDrawable.getBounds();
         assertEquals(0, r.left);
@@ -345,7 +378,7 @@
     }
 
     public void testAccessChangingConfigurations() {
-        MockDrawable mockDrawable = new MockDrawable();
+        Drawable mockDrawable = new MockDrawable();
         assertEquals(0, mockDrawable.getChangingConfigurations());
 
         mockDrawable.setChangingConfigurations(1);
@@ -359,27 +392,27 @@
     }
 
     public void testGetConstantState() {
-        MockDrawable mockDrawable = new MockDrawable();
+        Drawable mockDrawable = new MockDrawable();
         assertNull(mockDrawable.getConstantState());
     }
 
     public void testGetCurrent() {
-        MockDrawable mockDrawable = new MockDrawable();
+        Drawable mockDrawable = new MockDrawable();
         assertSame(mockDrawable, mockDrawable.getCurrent());
     }
 
     public void testGetIntrinsicHeight() {
-        MockDrawable mockDrawable = new MockDrawable();
+        Drawable mockDrawable = new MockDrawable();
         assertEquals(-1, mockDrawable.getIntrinsicHeight());
     }
 
     public void testGetIntrinsicWidth() {
-        MockDrawable mockDrawable = new MockDrawable();
+        Drawable mockDrawable = new MockDrawable();
         assertEquals(-1, mockDrawable.getIntrinsicWidth());
     }
 
     public void testAccessLevel() {
-        MockDrawable mockDrawable = new MockDrawable();
+        Drawable mockDrawable = new MockDrawable();
         assertEquals(0, mockDrawable.getLevel());
 
         assertFalse(mockDrawable.setLevel(10));
@@ -396,17 +429,17 @@
     }
 
     public void testGetMinimumHeight() {
-        MockDrawable mockDrawable = new MockDrawable();
+        Drawable mockDrawable = new MockDrawable();
         assertEquals(0, mockDrawable.getMinimumHeight());
     }
 
     public void testGetMinimumWidth() {
-        MockDrawable mockDrawable = new MockDrawable();
+        Drawable mockDrawable = new MockDrawable();
         assertEquals(0, mockDrawable.getMinimumWidth());
     }
 
     public void testGetPadding() {
-        MockDrawable mockDrawable = new MockDrawable();
+        Drawable mockDrawable = new MockDrawable();
         Rect r = new Rect(10, 10, 20, 20);
         assertFalse(mockDrawable.getPadding(r));
         assertEquals(0, r.bottom);
@@ -422,7 +455,7 @@
     }
 
     public void testAccessState() {
-        MockDrawable mockDrawable = new MockDrawable();
+        Drawable mockDrawable = new MockDrawable();
         assertEquals(StateSet.WILD_CARD, mockDrawable.getState());
 
         int[] states = new int[] {1, 2, 3};
@@ -433,12 +466,12 @@
     }
 
     public void testGetTransparentRegion() {
-        MockDrawable mockDrawable = new MockDrawable();
+        Drawable mockDrawable = new MockDrawable();
         assertNull(mockDrawable.getTransparentRegion());
     }
 
     public void testInflate() throws XmlPullParserException, IOException {
-        MockDrawable mockDrawable = new MockDrawable();
+        Drawable mockDrawable = new MockDrawable();
 
         XmlPullParser parser = mResources.getXml(R.xml.drawable_test);
         while (parser.next() != XmlPullParser.START_TAG) {
@@ -452,7 +485,7 @@
     }
 
     public void testInvalidateSelf() {
-        MockDrawable mockDrawable = new MockDrawable();
+        Drawable mockDrawable = new MockDrawable();
         // if setCallback() is not called, invalidateSelf() would do nothing,
         // so just call it to check whether it throws exceptions.
         mockDrawable.invalidateSelf();
@@ -464,12 +497,12 @@
     }
 
     public void testIsStateful() {
-        MockDrawable mockDrawable = new MockDrawable();
+        Drawable mockDrawable = new MockDrawable();
         assertFalse(mockDrawable.isStateful());
     }
 
     public void testVisible() {
-        MockDrawable mockDrawable = new MockDrawable();
+        Drawable mockDrawable = new MockDrawable();
         assertTrue(mockDrawable.isVisible());
 
         assertTrue(mockDrawable.setVisible(false, false));
@@ -485,7 +518,7 @@
     public void testOnBoundsChange() {
         MockDrawable mockDrawable = new MockDrawable();
 
-        // onBoundsChange is a non-operation function.
+        // No-op in the Drawable superclass.
         mockDrawable.onBoundsChange(new Rect(0, 0, 10, 10));
     }
 
@@ -522,56 +555,45 @@
         assertEquals(1000L, mockCallback.getWhen());
     }
 
-    public void testSetCallback() {
-        MockDrawable mockDrawable = new MockDrawable();
+    public void testAccessCallback() {
+        Drawable mockDrawable = new MockDrawable();
+        Callback mockCallback = mock(Callback.class);
 
-        MockCallback mockCallback = new MockCallback();
         mockDrawable.setCallback(mockCallback);
-        mockDrawable.scheduleSelf(null, 1000L);
-        assertEquals(mockDrawable, mockCallback.getScheduleDrawable());
-        assertNull(mockCallback.getRunnable());
-        assertEquals(1000L, mockCallback.getWhen());
+        assertEquals(mockCallback, mockDrawable.getCallback());
+
+        mockDrawable.setCallback(null);
+        assertEquals(null, mockDrawable.getCallback());
     }
 
     public void testSetColorFilter() {
-        MockDrawable mockDrawable = new MockDrawable();
-
+        Drawable mockDrawable = new MockDrawable();
         mockDrawable.setColorFilter(5, PorterDuff.Mode.CLEAR);
     }
 
     public void testSetDither() {
-        MockDrawable mockDrawable = new MockDrawable();
+        Drawable mockDrawable = new MockDrawable();
 
-        // setDither is a non-operation function.
+        // No-op in the Drawable superclass.
         mockDrawable.setDither(false);
     }
 
     public void testSetHotspotBounds() {
-        MockDrawable mockDrawable = new MockDrawable();
+        Drawable mockDrawable = new MockDrawable();
 
-        // setHotspotBounds is a non-operation function.
+        // No-op in the Drawable superclass.
         mockDrawable.setHotspotBounds(10, 15, 100, 150);
     }
 
     public void testGetHotspotBounds() {
-        MockDrawable mockDrawable = new MockDrawable();
+        Drawable mockDrawable = new MockDrawable();
 
-        // getHotspotBounds doesn't do anything interesting in the Drawable superclass
+        // No-op in the Drawable superclass.
         mockDrawable.getHotspotBounds(new Rect());
     }
 
-    public void testSetLayoutDirection() {
-        MockDrawable mockDrawable = new MockDrawable();
-
-        mockDrawable.setLayoutDirection(View.LAYOUT_DIRECTION_LTR);
-        assertEquals(View.LAYOUT_DIRECTION_LTR, mockDrawable.getLayoutDirection());
-
-        mockDrawable.setLayoutDirection(View.LAYOUT_DIRECTION_RTL);
-        assertEquals(View.LAYOUT_DIRECTION_RTL, mockDrawable.getLayoutDirection());
-    }
-
-    public void testGetLayoutDirection() {
-        MockDrawable mockDrawable = new MockDrawable();
+    public void testAccessLayoutDirection() {
+        Drawable mockDrawable = new MockDrawable();
 
         mockDrawable.setLayoutDirection(View.LAYOUT_DIRECTION_LTR);
         assertEquals(View.LAYOUT_DIRECTION_LTR, mockDrawable.getLayoutDirection());
@@ -581,28 +603,28 @@
     }
 
     public void testOnLayoutDirectionChanged() {
-        MockDrawable mockDrawable = new MockDrawable();
+        Drawable mockDrawable = new MockDrawable();
 
-        // onLayoutDirectionChanged is a non-operation function.
+        // No-op in the Drawable superclass.
         mockDrawable.onLayoutDirectionChanged(View.LAYOUT_DIRECTION_LTR);
     }
 
     public void testSetFilterBitmap() {
-        MockDrawable mockDrawable = new MockDrawable();
+        Drawable mockDrawable = new MockDrawable();
 
-        // setFilterBitmap is a non-operation function.
+        // No-op in the Drawable superclass.
         mockDrawable.setFilterBitmap(false);
     }
 
     public void testIsFilterBitmap() {
-        MockDrawable mockDrawable = new MockDrawable();
+        Drawable mockDrawable = new MockDrawable();
 
-        // setFilterBitmap is a non-operation function.
+        // No-op in the Drawable superclass.
         mockDrawable.isFilterBitmap();
     }
 
     public void testUnscheduleSelf() {
-        MockDrawable mockDrawable = new MockDrawable();
+        Drawable mockDrawable = new MockDrawable();
         MockCallback mockCallback = new MockCallback();
         mockDrawable.setCallback(mockCallback);
         mockDrawable.unscheduleSelf(null);
@@ -611,8 +633,7 @@
     }
 
     public void testMutate() {
-        MockDrawable mockDrawable = new MockDrawable();
-
+        Drawable mockDrawable = new MockDrawable();
         assertSame(mockDrawable, mockDrawable.mutate());
     }
 
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/DrawableTestUtils.java b/tests/tests/graphics/src/android/graphics/drawable/cts/DrawableTestUtils.java
index a0fa634..ba8f289 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/DrawableTestUtils.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/DrawableTestUtils.java
@@ -16,15 +16,23 @@
 
 package android.graphics.drawable.cts;
 
+import android.graphics.Canvas;
+import android.graphics.drawable.Drawable;
+import junit.framework.Assert;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import android.content.res.Configuration;
+import android.content.res.Resources;
 import android.content.res.XmlResourceParser;
+import android.graphics.Bitmap;
+import android.graphics.Color;
 import android.util.AttributeSet;
 import android.util.Xml;
 
 import java.io.IOException;
 
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
 /**
  * The useful methods for graphics.drawable test.
  */
@@ -85,4 +93,101 @@
         }
         return attrs;
     }
+
+    public static XmlResourceParser getResourceParser(Resources res, int resId)
+            throws XmlPullParserException, IOException {
+        final XmlResourceParser parser = res.getXml(resId);
+        int type;
+        while ((type = parser.next()) != XmlPullParser.START_TAG
+                && type != XmlPullParser.END_DOCUMENT) {
+            // Empty loop
+        }
+        return parser;
+    }
+
+    public static void setResourcesDensity(Resources res, int densityDpi) {
+        final Configuration config = new Configuration();
+        config.setTo(res.getConfiguration());
+        config.densityDpi = densityDpi;
+        res.updateConfiguration(config, null);
+    }
+
+    /**
+     * Implements scaling as used by the Bitmap class. Resulting values are
+     * rounded up (as distinct from resource scaling, which truncates or rounds
+     * to the nearest pixel).
+     *
+     * @param size the pixel size to scale
+     * @param sdensity the source density that corresponds to the size
+     * @param tdensity the target density
+     * @return the pixel size scaled for the target density
+     */
+    public static int scaleBitmapFromDensity(int size, int sdensity, int tdensity) {
+        if (sdensity == 0 || tdensity == 0 || sdensity == tdensity) {
+            return size;
+        }
+
+        // Scale by tdensity / sdensity, rounding up.
+        return ((size * tdensity) + (sdensity >> 1)) / sdensity;
+    }
+
+    /**
+     * Asserts that two images are similar within the given thresholds.
+     *
+     * @param message
+     * @param expected
+     * @param actual
+     * @param pixelThreshold
+     * @param pixelCountThreshold
+     */
+    public static void compareImages(String message, Bitmap expected, Bitmap actual,
+            float pixelThreshold, float pixelCountThreshold) {
+        int idealWidth = expected.getWidth();
+        int idealHeight = expected.getHeight();
+
+        Assert.assertTrue(idealWidth == actual.getWidth());
+        Assert.assertTrue(idealHeight == actual.getHeight());
+
+        int totalDiffPixelCount = 0;
+        float totalPixelCount = idealWidth * idealHeight;
+        for (int x = 0; x < idealWidth; x++) {
+            for (int y = 0; y < idealHeight; y++) {
+                int idealColor = expected.getPixel(x, y);
+                int givenColor = actual.getPixel(x, y);
+                if (idealColor == givenColor)
+                    continue;
+
+                float totalError = 0;
+                totalError += Math.abs(Color.red(idealColor) - Color.red(givenColor));
+                totalError += Math.abs(Color.green(idealColor) - Color.green(givenColor));
+                totalError += Math.abs(Color.blue(idealColor) - Color.blue(givenColor));
+                totalError += Math.abs(Color.alpha(idealColor) - Color.alpha(givenColor));
+
+                if ((totalError / 1024.0f) >= pixelThreshold) {
+                    Assert.fail((message + ": totalError is " + totalError));
+                }
+
+                totalDiffPixelCount++;
+            }
+        }
+        if ((totalDiffPixelCount / totalPixelCount) >= pixelCountThreshold) {
+            Assert.fail((message +": totalDiffPixelCount is " + totalDiffPixelCount));
+        }
+    }
+
+    /**
+     * Returns the {@link Color} at the specified location in the {@link Drawable}.
+     */
+    public static int getPixel(Drawable d, int x, int y) {
+        final int w = Math.max(d.getIntrinsicWidth(), x + 1);
+        final int h = Math.max(d.getIntrinsicHeight(), y + 1);
+        final Bitmap b = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
+        final Canvas c = new Canvas(b);
+        d.setBounds(0, 0, w, h);
+        d.draw(c);
+
+        final int pixel = b.getPixel(x, y);
+        b.recycle();
+        return pixel;
+    }
 }
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/DrawableTestingUtils.java b/tests/tests/graphics/src/android/graphics/drawable/cts/DrawableTestingUtils.java
deleted file mode 100644
index d560906..0000000
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/DrawableTestingUtils.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.graphics.drawable.cts;
-
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Bitmap.Config;
-import android.graphics.drawable.Drawable;
-
-public class DrawableTestingUtils {
-    public static int getPixel(Drawable d, int x, int y) {
-        final int w = Math.max(d.getIntrinsicWidth(), x + 1);
-        final int h = Math.max(d.getIntrinsicHeight(), y + 1);
-        final Bitmap b = Bitmap.createBitmap(w, h, Config.ARGB_8888);
-        final Canvas c = new Canvas(b);
-        d.setBounds(0, 0, w, h);
-        d.draw(c);
-
-        final int pixel = b.getPixel(x, y);
-        b.recycle();
-        return pixel;
-    }
-}
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/DrawableWrapperTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/DrawableWrapperTest.java
index 40680c1..340f945 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/DrawableWrapperTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/DrawableWrapperTest.java
@@ -17,7 +17,7 @@
 package android.graphics.drawable.cts;
 
 import android.graphics.drawable.DrawableWrapper;
-import com.android.cts.graphics.R;
+import android.graphics.cts.R;
 
 
 import java.util.Arrays;
@@ -42,7 +42,7 @@
     @SuppressWarnings("deprecation")
     public void testConstructor() {
         Drawable d = new BitmapDrawable();
-        MyWrapper wrapper = new MyWrapper(d);
+        DrawableWrapper wrapper = new MyWrapper(d);
         assertSame(d, wrapper.getDrawable());
 
         new MyWrapper(null);
@@ -51,14 +51,14 @@
     @SuppressWarnings("deprecation")
     public void testGetDrawable() {
         Drawable d = new BitmapDrawable();
-        MyWrapper wrapper = new MyWrapper(d);
+        DrawableWrapper wrapper = new MyWrapper(d);
         assertSame(d, wrapper.getDrawable());
     }
 
     @SuppressWarnings("deprecation")
     public void testSetDrawable() {
         Drawable d = new BitmapDrawable();
-        MyWrapper wrapper = new MyWrapper(null);
+        DrawableWrapper wrapper = new MyWrapper(null);
         assertSame(null, wrapper.getDrawable());
 
         wrapper.setDrawable(d);
@@ -67,7 +67,7 @@
 
     @SuppressWarnings("deprecation")
     public void testInvalidateDrawable() {
-        MyWrapper wrapper = new MyWrapper(new BitmapDrawable());
+        DrawableWrapper wrapper = new MyWrapper(new BitmapDrawable());
 
         MockCallback cb = new MockCallback();
         wrapper.setCallback(cb);
@@ -86,7 +86,7 @@
 
     @SuppressWarnings("deprecation")
     public void testScheduleDrawable() {
-        MyWrapper wrapper = new MyWrapper(new BitmapDrawable());
+        DrawableWrapper wrapper = new MyWrapper(new BitmapDrawable());
 
         MockCallback cb = new MockCallback();
         wrapper.setCallback(cb);
@@ -108,7 +108,7 @@
 
     @SuppressWarnings("deprecation")
     public void testUnscheduleDrawable() {
-        MyWrapper wrapper = new MyWrapper(new BitmapDrawable());
+        DrawableWrapper wrapper = new MyWrapper(new BitmapDrawable());
 
         MockCallback cb = new MockCallback();
         wrapper.setCallback(cb);
@@ -170,7 +170,7 @@
 
     public void testDraw() {
         MockDrawable mockDrawable = new MockDrawable();
-        MyWrapper wrapper = new MyWrapper(mockDrawable);
+        DrawableWrapper wrapper = new MyWrapper(mockDrawable);
 
         wrapper.draw(new Canvas());
         assertTrue(mockDrawable.hasCalledDraw());
@@ -185,7 +185,7 @@
         final int CONTAINED_DRAWABLE_CONFIG = 2;
 
         MockDrawable mockDrawable = new MockDrawable();
-        MyWrapper wrapper = new MyWrapper(mockDrawable);
+        DrawableWrapper wrapper = new MyWrapper(mockDrawable);
 
         assertEquals(0, wrapper.getChangingConfigurations());
 
@@ -199,7 +199,7 @@
 
     public void testGetPadding() {
         MockDrawable mockDrawable = new MockDrawable();
-        MyWrapper wrapper = new MyWrapper(mockDrawable);
+        DrawableWrapper wrapper = new MyWrapper(mockDrawable);
 
         // this method will call contained drawable's getPadding method.
         wrapper.getPadding(new Rect());
@@ -215,7 +215,7 @@
 
     public void testSetVisible() {
         MockDrawable mockDrawable = new MockDrawable();
-        MyWrapper wrapper = new MyWrapper(mockDrawable);
+        DrawableWrapper wrapper = new MyWrapper(mockDrawable);
         assertTrue(wrapper.isVisible());
 
         assertTrue(wrapper.setVisible(false, false));
@@ -235,7 +235,7 @@
 
     public void testSetAlpha() {
         MockDrawable mockDrawable = new MockDrawable();
-        MyWrapper wrapper = new MyWrapper(mockDrawable);
+        DrawableWrapper wrapper = new MyWrapper(mockDrawable);
 
         // this method will call contained drawable's setAlpha method.
         wrapper.setAlpha(100);
@@ -252,7 +252,7 @@
 
     public void testSetColorFilter() {
         MockDrawable mockDrawable = new MockDrawable();
-        MyWrapper wrapper = new MyWrapper(mockDrawable);
+        DrawableWrapper wrapper = new MyWrapper(mockDrawable);
 
         // this method will call contained drawable's setColorFilter method.
         wrapper.setColorFilter(new ColorFilter());
@@ -265,7 +265,7 @@
 
     public void testGetOpacity() {
         MockDrawable mockDrawable = new MockDrawable();
-        MyWrapper wrapper = new MyWrapper(mockDrawable);
+        DrawableWrapper wrapper = new MyWrapper(mockDrawable);
 
         // This method will call contained drawable's getOpacity method.
         wrapper.setLevel(1);
@@ -275,7 +275,7 @@
 
     public void testIsStateful() {
         MockDrawable mockDrawable = new MockDrawable();
-        MyWrapper wrapper = new MyWrapper(mockDrawable);
+        DrawableWrapper wrapper = new MyWrapper(mockDrawable);
 
         // this method will call contained drawable's isStateful method.
         wrapper.isStateful();
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/Drawable_ConstantStateTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/Drawable_ConstantStateTest.java
index 0f33dd1..45e83dd 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/Drawable_ConstantStateTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/Drawable_ConstantStateTest.java
@@ -16,15 +16,53 @@
 
 package android.graphics.drawable.cts;
 
-import junit.framework.TestCase;
 import android.graphics.drawable.Drawable;
+import android.graphics.drawable.Drawable.ConstantState;
+import android.test.AndroidTestCase;
 
-public class Drawable_ConstantStateTest extends TestCase {
-    public void testGetChangingConfigurations() {
-        // getChangingConfigurations is an abstract function.
-    }
+public class Drawable_ConstantStateTest extends AndroidTestCase {
 
     public void testNewDrawable() {
-        // newDrawable is an abstract function.
+        MockConstantState mock = new MockConstantState();
+        ConstantState cs = mock;
+
+        assertEquals(null, cs.newDrawable());
+        assertTrue(mock.hasCalledNewDrawable());
+        mock.reset();
+
+        assertEquals(null, cs.newDrawable(mContext.getResources()));
+        assertTrue(mock.hasCalledNewDrawable());
+        mock.reset();
+
+        assertEquals(null, cs.newDrawable(mContext.getResources(), mContext.getTheme()));
+        assertTrue(mock.hasCalledNewDrawable());
+    }
+
+    public void testCanApplyTheme() {
+        ConstantState cs = new MockConstantState();
+        assertFalse(cs.canApplyTheme());
+    }
+
+    public static class MockConstantState extends ConstantState {
+        private boolean mCalledNewDrawable;
+
+        @Override
+        public Drawable newDrawable() {
+            mCalledNewDrawable = true;
+            return null;
+        }
+
+        @Override
+        public int getChangingConfigurations() {
+            return 0;
+        }
+
+        public boolean hasCalledNewDrawable() {
+            return mCalledNewDrawable;
+        }
+
+        public void reset() {
+            mCalledNewDrawable = false;
+        }
     }
 }
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/GradientDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/GradientDrawableTest.java
index eeda22c..713f61a 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/GradientDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/GradientDrawableTest.java
@@ -16,24 +16,35 @@
 
 package android.graphics.drawable.cts;
 
-import com.android.cts.graphics.R;
-
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
+import android.content.res.ColorStateList;
 import android.content.res.Resources;
+import android.content.res.Resources.Theme;
+import android.content.res.XmlResourceParser;
 import android.graphics.Canvas;
+import android.graphics.Color;
 import android.graphics.ColorFilter;
+import android.graphics.PixelFormat;
 import android.graphics.Rect;
-import android.graphics.drawable.GradientDrawable;
+import android.graphics.cts.R;
 import android.graphics.drawable.Drawable.ConstantState;
+import android.graphics.drawable.GradientDrawable;
+import android.graphics.drawable.GradientDrawable.Orientation;
 import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.test.suitebuilder.annotation.SmallTest;
 import android.util.AttributeSet;
 import android.util.Xml;
 
 import java.io.IOException;
+import java.util.Arrays;
+
+import static org.junit.Assert.assertArrayEquals;
 
 public class GradientDrawableTest extends AndroidTestCase {
+    @SmallTest
     public void testConstructor() {
         int[] color = new int[] {1, 2, 3};
 
@@ -42,12 +53,61 @@
         new GradientDrawable(null, null);
     }
 
+    @SmallTest
+    public void testGetOpacity() {
+        GradientDrawable gradientDrawable = new GradientDrawable();
+        assertEquals("Default opacity is TRANSLUCENT",
+                PixelFormat.TRANSLUCENT, gradientDrawable.getOpacity());
+
+        gradientDrawable.setColor(Color.TRANSPARENT);
+        assertEquals("Color.TRANSPARENT is TRANSLUCENT",
+                PixelFormat.TRANSLUCENT, gradientDrawable.getOpacity());
+
+        gradientDrawable.setColor(0x80FFFFFF);
+        assertEquals("0x80FFFFFF is TRANSLUCENT",
+                PixelFormat.TRANSLUCENT, gradientDrawable.getOpacity());
+
+        gradientDrawable.setColors(new int[] { Color.RED, Color.TRANSPARENT });
+        assertEquals("{ RED, TRANSPARENT } is TRANSLUCENT",
+                PixelFormat.TRANSLUCENT, gradientDrawable.getOpacity());
+
+        gradientDrawable.setColors(new int[] { Color.RED, Color.BLUE });
+        assertEquals("{ RED, BLUE } is OPAQUE",
+                PixelFormat.OPAQUE, gradientDrawable.getOpacity());
+
+        gradientDrawable.setColor(Color.RED);
+        assertEquals("RED is OPAQUE",
+                PixelFormat.OPAQUE, gradientDrawable.getOpacity());
+
+        gradientDrawable.setCornerRadius(10);
+        gradientDrawable.setColor(Color.RED);
+        assertEquals("RED with corner radius is TRANSLUCENT",
+                PixelFormat.TRANSLUCENT, gradientDrawable.getOpacity());
+
+    }
+
+    @SmallTest
+    public void testSetOrientation() {
+        GradientDrawable gradientDrawable = new GradientDrawable();
+        Orientation orientation;
+
+        orientation = Orientation.BL_TR;
+        gradientDrawable.setOrientation(orientation);
+        assertEquals("Orientation set/get are symmetric",
+                orientation, gradientDrawable.getOrientation());
+    }
+
+    @SmallTest
     public void testSetCornerRadii() {
         float[] radii = new float[] {1.0f, 2.0f, 3.0f};
 
         GradientDrawable gradientDrawable = new GradientDrawable();
         gradientDrawable.setCornerRadii(radii);
 
+        float[] radiiActual = gradientDrawable.getCornerRadii();
+        assertArrayEquals("Gradient radius set/get are symmetric",
+                radii, radiiActual, 0);
+
         ConstantState constantState = gradientDrawable.getConstantState();
         assertNotNull(constantState);
 
@@ -55,6 +115,7 @@
         gradientDrawable.setCornerRadii(null);
     }
 
+    @SmallTest
     public void testSetCornerRadius() {
         GradientDrawable gradientDrawable = new GradientDrawable();
 
@@ -62,75 +123,133 @@
         gradientDrawable.setCornerRadius(-2.5f);
     }
 
+    @SmallTest
     public void testSetStroke() {
-        GradientDrawable gradientDrawable = new GradientDrawable();
-
-        gradientDrawable.setStroke(2, 3);
-        gradientDrawable.setStroke(-2, -3);
+        helpTestSetStroke(2, Color.RED);
+        helpTestSetStroke(-2, Color.TRANSPARENT);
+        helpTestSetStroke(0, 0);
     }
 
-    public void testSetStroke1() {
-        int width = 2;
-        int color = 3;
-        float dashWidth = 3.4f;
-        float dashGap = 5.5f;
-
+    private void helpTestSetStroke(int width, int color) {
         GradientDrawable gradientDrawable = new GradientDrawable();
-        gradientDrawable.setStroke(width, color, dashWidth, dashGap);
-
-        width = -2;
-        color = -3;
-        dashWidth = -3.4f;
-        dashGap = -5.5f;
-        gradientDrawable.setStroke(width, color, dashWidth, dashGap);
+        gradientDrawable.setStroke(width, color);
+        // TODO: Verify stroke properties.
     }
 
+    @SmallTest
+    public void testSetStroke_WidthGap() {
+        helpTestSetStroke_WidthGap(2, Color.RED, 3.4f, 5.5f);
+        helpTestSetStroke_WidthGap(-2, Color.TRANSPARENT, -3.4f, -5.5f);
+        helpTestSetStroke_WidthGap(0, 0, 0, (float) 0.0f);
+    }
+
+    private void helpTestSetStroke_WidthGap(int width, int color,
+            float dashWidth, float dashGap) {
+        GradientDrawable gradientDrawable = new GradientDrawable();
+        gradientDrawable.setStroke(width, color, dashWidth, dashGap);
+        // TODO: Verify stroke properties.
+    }
+
+    @SmallTest
+    public void testSetStrokeList() {
+        helpTestSetStrokeList(2, ColorStateList.valueOf(Color.RED));
+        helpTestSetStrokeList(-2, ColorStateList.valueOf(Color.TRANSPARENT));
+        helpTestSetStrokeList(0, null);
+    }
+
+    private void helpTestSetStrokeList(int width,
+            ColorStateList colorList) {
+        GradientDrawable gradientDrawable = new GradientDrawable();
+        gradientDrawable.setStroke(width, colorList);
+        // TODO: Verify stroke properties.
+    }
+
+    @SmallTest
+    public void testSetStrokeList_WidthGap() {
+        helpTestSetStrokeList_WidthGap(2, ColorStateList.valueOf(Color.RED), 3.4f, 5.5f);
+        helpTestSetStrokeList_WidthGap(-2, ColorStateList.valueOf(Color.TRANSPARENT), -3.4f, -5.5f);
+        helpTestSetStrokeList_WidthGap(0, null, 0.0f, 0.0f);
+    }
+
+    private void helpTestSetStrokeList_WidthGap(int width, ColorStateList colorList,
+            float dashWidth, float dashGap) {
+        GradientDrawable gradientDrawable = new GradientDrawable();
+        gradientDrawable.setStroke(width, colorList, dashWidth, dashGap);
+        // TODO: Verify stroke properties.
+    }
+
+    @SmallTest
     public void testSetSize() {
-        GradientDrawable gradientDrawable = new GradientDrawable();
-        gradientDrawable.setSize(6, 4);
-        assertEquals(6, gradientDrawable.getIntrinsicWidth());
-        assertEquals(4, gradientDrawable.getIntrinsicHeight());
-
-        gradientDrawable.setSize(-30, -40);
-        assertEquals(-30, gradientDrawable.getIntrinsicWidth());
-        assertEquals(-40, gradientDrawable.getIntrinsicHeight());
-
-        gradientDrawable.setSize(0, 0);
-        assertEquals(0, gradientDrawable.getIntrinsicWidth());
-        assertEquals(0, gradientDrawable.getIntrinsicHeight());
-
-        gradientDrawable.setSize(Integer.MAX_VALUE, Integer.MIN_VALUE);
-        assertEquals(Integer.MAX_VALUE, gradientDrawable.getIntrinsicWidth());
-        assertEquals(Integer.MIN_VALUE, gradientDrawable.getIntrinsicHeight());
+        helpTestSetSize(6, 4);
+        helpTestSetSize(-30, -40);
+        helpTestSetSize(0, 0);
+        helpTestSetSize(Integer.MAX_VALUE, Integer.MIN_VALUE);
     }
 
+    private void helpTestSetSize(int width, int height) {
+        GradientDrawable gradientDrawable = new GradientDrawable();
+        gradientDrawable.setSize(width, height);
+        assertEquals(width, gradientDrawable.getIntrinsicWidth());
+        assertEquals(height, gradientDrawable.getIntrinsicHeight());
+    }
+
+    @SmallTest
     public void testSetShape() {
         GradientDrawable gradientDrawable = new GradientDrawable();
+        int shape;
 
-        gradientDrawable.setShape(6);
-        gradientDrawable.setShape(-6);
+        shape = GradientDrawable.OVAL;
+        gradientDrawable.setShape(shape);
+        assertEquals("Gradient shape set/get are symmetric",
+                shape, gradientDrawable.getShape());
 
-        gradientDrawable.setShape(Integer.MAX_VALUE);
-        gradientDrawable.setShape(Integer.MIN_VALUE);
+        shape = -1;
+        gradientDrawable.setShape(shape);
+        assertEquals("Invalid gradient shape set/get are symmetric",
+                shape, gradientDrawable.getShape());
     }
 
+    @SmallTest
     public void testSetGradientType() {
         GradientDrawable gradientDrawable = new GradientDrawable();
+        int gradientType;
 
-        gradientDrawable.setGradientType(7);
-        gradientDrawable.setGradientType(-7);
+        gradientType = GradientDrawable.LINEAR_GRADIENT;
+        gradientDrawable.setGradientType(gradientType);
+        assertEquals("Gradient type set/get are symmetric",
+                gradientType, gradientDrawable.getGradientType());
 
-        gradientDrawable.setGradientType(Integer.MAX_VALUE);
-        gradientDrawable.setGradientType(Integer.MIN_VALUE);
+        gradientType = -1;
+        gradientDrawable.setGradientType(gradientType);
+        assertEquals("Invalid gradient type set/get are symmetric",
+                gradientType, gradientDrawable.getGradientType());
     }
 
+    @SmallTest
     public void testSetGradientCenter() {
         GradientDrawable gradientDrawable = new GradientDrawable();
+        float centerX;
+        float centerY;
 
-        gradientDrawable.setGradientCenter(3.4f, 5.5f);
-        gradientDrawable.setGradientCenter(-3.4f, -5.5f);
+        centerX = 0.5f;
+        centerY = 0.5f;
+        assertEquals(centerX, gradientDrawable.getGradientCenterX(), 0.01f);
+        assertEquals(centerY, gradientDrawable.getGradientCenterY(), 0.01f);
+
+        centerX = -0.5f;
+        centerY = -0.5f;
+        gradientDrawable.setGradientCenter(centerX, centerY);
+        assertEquals(centerX, gradientDrawable.getGradientCenterX(), 0.01f);
+        assertEquals(centerY, gradientDrawable.getGradientCenterY(), 0.01f);
+
+        centerX = 0.0f;
+        centerY = 0.0f;
+        gradientDrawable.setGradientCenter(centerX, centerY);
+        assertEquals(centerX, gradientDrawable.getGradientCenterX());
+        assertEquals(centerY, gradientDrawable.getGradientCenterY());
     }
 
+    @SmallTest
     public void testSetGradientRadius() {
         GradientDrawable gradientDrawable = new GradientDrawable();
 
@@ -138,13 +257,25 @@
         gradientDrawable.setGradientRadius(-3.6f);
     }
 
+    @SmallTest
     public void testSetUseLevel() {
         GradientDrawable gradientDrawable = new GradientDrawable();
+        boolean useLevel;
 
-        gradientDrawable.setUseLevel(true);
-        gradientDrawable.setUseLevel(false);
+        assertFalse("Default useLevel is false", gradientDrawable.getUseLevel());
+
+        useLevel = true;
+        gradientDrawable.setUseLevel(useLevel);
+        assertEquals("Gradient set/get useLevel is symmetric",
+                useLevel, gradientDrawable.getUseLevel());
+
+        useLevel = false;
+        gradientDrawable.setUseLevel(useLevel);
+        assertEquals("Gradient set/get useLevel is symmetric",
+                useLevel, gradientDrawable.getUseLevel());
     }
 
+    @SmallTest
     public void testDraw() {
         GradientDrawable gradientDrawable = new GradientDrawable();
         Canvas c = new Canvas();
@@ -154,16 +285,53 @@
         gradientDrawable.draw(null);
     }
 
+    @SmallTest
     public void testSetColor() {
         GradientDrawable gradientDrawable = new GradientDrawable();
+        int color;
 
-        gradientDrawable.setColor(8);
-        gradientDrawable.setColor(-8);
+        color = Color.RED;
+        gradientDrawable.setColor(color);
+        assertEquals("Color was set to " + color, color,
+                gradientDrawable.getColor().getDefaultColor());
 
-        gradientDrawable.setColor(Integer.MAX_VALUE);
-        gradientDrawable.setColor(Integer.MIN_VALUE);
+        color = Color.TRANSPARENT;
+        gradientDrawable.setColor(color);
+        assertEquals("Color was set to " + color, color,
+                gradientDrawable.getColor().getDefaultColor());
     }
 
+    @SmallTest
+    public void testSetColors() {
+        GradientDrawable gradientDrawable = new GradientDrawable();
+        int[] colors;
+
+        colors = new int[] { Color.RED };
+        gradientDrawable.setColors(colors);
+        assertArrayEquals("Color was set to " + Arrays.toString(colors),
+                colors, gradientDrawable.getColors());
+
+        colors = null;
+        gradientDrawable.setColors(colors);
+        assertArrayEquals("Color was set to " + Arrays.toString(colors),
+                colors, gradientDrawable.getColors());
+    }
+
+    @SmallTest
+    public void testSetColorList() {
+        GradientDrawable gradientDrawable = new GradientDrawable();
+        ColorStateList color;
+
+        color = ColorStateList.valueOf(Color.RED);
+        gradientDrawable.setColor(color);
+        assertEquals("Color was set to RED", color, gradientDrawable.getColor());
+
+        color = null;
+        gradientDrawable.setColor(color);
+        assertEquals("Color was set to null (TRANSPARENT)", color, gradientDrawable.getColor());
+    }
+
+    @SmallTest
     public void testGetChangingConfigurations() {
         GradientDrawable gradientDrawable = new GradientDrawable();
         assertEquals(0, gradientDrawable.getChangingConfigurations());
@@ -175,6 +343,7 @@
         assertEquals(-20, gradientDrawable.getChangingConfigurations());
     }
 
+    @SmallTest
     public void testSetAlpha() {
         GradientDrawable gradientDrawable = new GradientDrawable();
 
@@ -182,6 +351,7 @@
         gradientDrawable.setAlpha(-1);
     }
 
+    @SmallTest
     public void testSetDither() {
         GradientDrawable gradientDrawable = new GradientDrawable();
 
@@ -189,6 +359,7 @@
         gradientDrawable.setDither(false);
     }
 
+    @SmallTest
     public void testSetColorFilter() {
         GradientDrawable gradientDrawable = new GradientDrawable();
         ColorFilter cf = new ColorFilter();
@@ -198,10 +369,7 @@
         gradientDrawable.setColorFilter(null);
     }
 
-    public void testMethods() {
-        // implementation details, do not test.
-    }
-
+    @SmallTest
     public void testInflate() throws XmlPullParserException, IOException {
         GradientDrawable gradientDrawable = new GradientDrawable();
         Rect rect = new Rect();
@@ -246,6 +414,7 @@
         }
     }
 
+    @SmallTest
     public void testInflateGradientRadius() throws XmlPullParserException, IOException {
         Rect parentBounds = new Rect(0, 0, 100, 100);
         Resources resources = mContext.getResources();
@@ -266,6 +435,7 @@
         assertEquals(50.0f, radius, 0.0f);
     }
 
+    @SmallTest
     public void testGetIntrinsicWidth() {
         GradientDrawable gradientDrawable = new GradientDrawable();
         gradientDrawable.setSize(6, 4);
@@ -275,6 +445,7 @@
         assertEquals(-10, gradientDrawable.getIntrinsicWidth());
     }
 
+    @SmallTest
     public void testGetIntrinsicHeight() {
         GradientDrawable gradientDrawable = new GradientDrawable();
         gradientDrawable.setSize(5, 3);
@@ -284,11 +455,13 @@
         assertEquals(-15, gradientDrawable.getIntrinsicHeight());
     }
 
+    @SmallTest
     public void testGetConstantState() {
         GradientDrawable gradientDrawable = new GradientDrawable();
         assertNotNull(gradientDrawable.getConstantState());
     }
 
+    @SmallTest
     public void testMutate() {
         Resources resources = mContext.getResources();
         GradientDrawable d1 = (GradientDrawable) resources.getDrawable(R.drawable.gradientdrawable);
@@ -320,4 +493,81 @@
         assertEquals(50, d3.getIntrinsicHeight());
         assertEquals(40, d3.getIntrinsicWidth());
     }
+
+    @MediumTest
+    public void testPreloadDensity() throws XmlPullParserException, IOException {
+        final Resources res = getContext().getResources();
+        final int densityDpi = res.getConfiguration().densityDpi;
+        try {
+            testPreloadDensityInner(res, densityDpi);
+        } finally {
+            DrawableTestUtils.setResourcesDensity(res, densityDpi);
+        }
+    }
+
+    private void testPreloadDensityInner(Resources res, int densityDpi)
+            throws XmlPullParserException, IOException {
+        final Rect tempPadding = new Rect();
+
+        // Capture initial state at default density.
+        final XmlResourceParser parser = DrawableTestUtils.getResourceParser(
+                res, R.drawable.gradient_drawable_density);
+        final GradientDrawable preloadedDrawable = new GradientDrawable();
+        preloadedDrawable.inflate(res, parser, Xml.asAttributeSet(parser));
+        final ConstantState preloadedConstantState = preloadedDrawable.getConstantState();
+        final int origWidth = preloadedDrawable.getIntrinsicWidth();
+        final int origHeight = preloadedDrawable.getIntrinsicHeight();
+        final Rect origPadding = new Rect();
+        preloadedDrawable.getPadding(origPadding);
+
+        // Set density to half of original. Unlike offsets, which are
+        // truncated, dimensions are rounded to the nearest pixel.
+        DrawableTestUtils.setResourcesDensity(res, densityDpi / 2);
+        final GradientDrawable halfDrawable =
+                (GradientDrawable) preloadedConstantState.newDrawable(res);
+        assertEquals(Math.round(origWidth / 2f), halfDrawable.getIntrinsicWidth());
+        assertEquals(Math.round(origHeight / 2f), halfDrawable.getIntrinsicHeight());
+        assertTrue(halfDrawable.getPadding(tempPadding));
+        assertEquals((int) (origPadding.left / 2f), tempPadding.left);
+
+        // Set density to double original.
+        DrawableTestUtils.setResourcesDensity(res, densityDpi * 2);
+        final GradientDrawable doubleDrawable =
+                (GradientDrawable) preloadedConstantState.newDrawable(res);
+        assertEquals(origWidth * 2, doubleDrawable.getIntrinsicWidth());
+        assertEquals(origHeight * 2, doubleDrawable.getIntrinsicHeight());
+        assertTrue(doubleDrawable.getPadding(tempPadding));
+        assertEquals(origPadding.left * 2, tempPadding.left);
+
+        // Restore original density.
+        DrawableTestUtils.setResourcesDensity(res, densityDpi);
+        final GradientDrawable origDrawable =
+                (GradientDrawable) preloadedConstantState.newDrawable();
+        assertEquals(origWidth, origDrawable.getIntrinsicWidth());
+        assertEquals(origHeight, origDrawable.getIntrinsicHeight());
+        assertTrue(origDrawable.getPadding(tempPadding));
+        assertEquals(origPadding, tempPadding);
+
+        // Some precision is lost when scaling the half-density
+        // drawable back up to the original density. Padding is
+        // always truncated, rather than rounded.
+        final Rect sloppyOrigPadding = new Rect();
+        sloppyOrigPadding.left = 2 * (origPadding.left / 2);
+        sloppyOrigPadding.top = 2 * (origPadding.top / 2);
+        sloppyOrigPadding.right = 2 * (origPadding.right / 2);
+        sloppyOrigPadding.bottom = 2 * (origPadding.bottom / 2);
+
+        // Ensure theme density is applied correctly.
+        final Theme t = res.newTheme();
+        halfDrawable.applyTheme(t);
+        assertEquals(2 * Math.round(origWidth / 2f), halfDrawable.getIntrinsicWidth());
+        assertEquals(2 * Math.round(origHeight / 2f), halfDrawable.getIntrinsicHeight());
+        assertTrue(halfDrawable.getPadding(tempPadding));
+        assertEquals(sloppyOrigPadding, tempPadding);
+        doubleDrawable.applyTheme(t);
+        assertEquals(origWidth, doubleDrawable.getIntrinsicWidth());
+        assertEquals(origHeight, doubleDrawable.getIntrinsicHeight());
+        assertTrue(doubleDrawable.getPadding(tempPadding));
+        assertEquals(origPadding, tempPadding);
+    }
 }
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/IconTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/IconTest.java
index d89ce7c..299eaf0 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/IconTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/IconTest.java
@@ -16,7 +16,7 @@
 
 package android.graphics.drawable.cts;
 
-import com.android.cts.graphics.R;
+import android.graphics.cts.R;
 
 import android.app.Activity;
 import android.app.Instrumentation;
@@ -50,7 +50,7 @@
     MockRunner mRunner;
 
     public IconTest() {
-        super("com.android.cts.graphics", ImageViewCtsActivity.class);
+        super("android.graphics.cts", ImageViewCtsActivity.class);
     }
 
     @Override
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/InsetDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/InsetDrawableTest.java
index 9c5f063..8f6eb63 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/InsetDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/InsetDrawableTest.java
@@ -16,23 +16,25 @@
 
 package android.graphics.drawable.cts;
 
-import com.android.cts.graphics.R;
-
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
 import android.content.res.Resources;
+import android.content.res.Resources.Theme;
+import android.content.res.XmlResourceParser;
 import android.graphics.Canvas;
 import android.graphics.ColorFilter;
 import android.graphics.PixelFormat;
 import android.graphics.Rect;
+import android.graphics.cts.R;
 import android.graphics.drawable.Drawable;
-import android.graphics.drawable.InsetDrawable;
 import android.graphics.drawable.Drawable.ConstantState;
+import android.graphics.drawable.InsetDrawable;
 import android.test.AndroidTestCase;
 import android.util.AttributeSet;
 import android.util.StateSet;
 import android.util.Xml;
+import android.view.InflateException;
 
 import java.io.IOException;
 import java.util.Arrays;
@@ -57,23 +59,25 @@
 
         try {
             insetDrawable.inflate(r, parser, attrs);
-            fail("There should be a XmlPullParserException thrown out.");
-        } catch (XmlPullParserException e) {
+            fail("There should be an InflateException thrown out.");
+        } catch (InflateException e) {
             // expected, test success
         } catch (IOException e) {
             fail("There should not be an IOException thrown out.");
+        } catch (XmlPullParserException e) {
+            fail("There should not be a XmlPullParserException thrown out.");
         }
 
         // input null as params
         try {
             insetDrawable.inflate(null, null, null);
             fail("There should be a NullPointerException thrown out.");
-        } catch (XmlPullParserException e) {
-            fail("There should not be a XmlPullParserException thrown out.");
-        } catch (IOException e) {
-            fail("There should not be an IOException thrown out.");
         } catch (NullPointerException e) {
             // expected, test success
+        } catch (IOException e) {
+            fail("There should not be an IOException thrown out.");
+        } catch (XmlPullParserException e) {
+            fail("There should not be a XmlPullParserException thrown out.");
         }
     }
 
@@ -283,28 +287,48 @@
         Drawable d = mContext.getDrawable(R.drawable.pass);
         InsetDrawable insetDrawable = new InsetDrawable(d, 0);
 
-        int expected = d.getIntrinsicWidth(); /* 31 */
+        int expected = d.getIntrinsicWidth();
         assertEquals(expected, insetDrawable.getIntrinsicWidth());
 
         d = mContext.getDrawable(R.drawable.scenery);
         insetDrawable = new InsetDrawable(d, 0);
 
-        expected = d.getIntrinsicWidth(); /* 170 */
+        expected = d.getIntrinsicWidth();
         assertEquals(expected, insetDrawable.getIntrinsicWidth());
+
+        d = mContext.getDrawable(R.drawable.scenery);
+        insetDrawable = new InsetDrawable(d, 20);
+
+        expected = d.getIntrinsicWidth() + 40;
+        assertEquals(expected, insetDrawable.getIntrinsicWidth());
+
+        d = mContext.getDrawable(R.drawable.inset_color);
+        expected = -1;
+        assertEquals(expected, d.getIntrinsicWidth());
     }
 
     public void testGetIntrinsicHeight() {
         Drawable d = mContext.getDrawable(R.drawable.pass);
         InsetDrawable insetDrawable = new InsetDrawable(d, 0);
 
-        int expected = d.getIntrinsicHeight(); /* 31 */
+        int expected = d.getIntrinsicHeight();
         assertEquals(expected, insetDrawable.getIntrinsicHeight());
 
         d = mContext.getDrawable(R.drawable.scenery);
         insetDrawable = new InsetDrawable(d, 0);
 
-        expected = d.getIntrinsicHeight(); /* 107 */
+        expected = d.getIntrinsicHeight();
         assertEquals(expected, insetDrawable.getIntrinsicHeight());
+
+        d = mContext.getDrawable(R.drawable.scenery);
+        insetDrawable = new InsetDrawable(d, 20);
+
+        expected = d.getIntrinsicHeight() + 40;
+        assertEquals(expected, insetDrawable.getIntrinsicHeight());
+
+        d = mContext.getDrawable(R.drawable.inset_color);
+        expected = -1;
+        assertEquals(expected, d.getIntrinsicHeight());
     }
 
     public void testGetConstantState() {
@@ -333,6 +357,60 @@
         assertEquals("Did not modify post-mutate() instance", 255, post.getDrawable().getAlpha());
     }
 
+
+    public void testPreloadDensity() throws XmlPullParserException, IOException {
+        final Resources res = getContext().getResources();
+        final int densityDpi = res.getConfiguration().densityDpi;
+        try {
+            testPreloadDensityInner(res, densityDpi);
+        } finally {
+            DrawableTestUtils.setResourcesDensity(res, densityDpi);
+        }
+    }
+
+    private void testPreloadDensityInner(Resources res, int densityDpi)
+            throws XmlPullParserException, IOException {
+        // Capture initial state at default density.
+        final XmlResourceParser parser = DrawableTestUtils.getResourceParser(
+                res, R.drawable.inset_density);
+        final InsetDrawable preloadedDrawable = new InsetDrawable(null, 0);
+        preloadedDrawable.inflate(res, parser, Xml.asAttributeSet(parser));
+        final ConstantState preloadedConstantState = preloadedDrawable.getConstantState();
+        final int origInsetHoriz = preloadedDrawable.getIntrinsicWidth()
+                - preloadedDrawable.getDrawable().getIntrinsicWidth();
+
+        // Set density to half of original. Unlike offsets, which are
+        // truncated, dimensions are rounded to the nearest pixel.
+        DrawableTestUtils.setResourcesDensity(res, densityDpi / 2);
+        final InsetDrawable halfDrawable =
+                (InsetDrawable) preloadedConstantState.newDrawable(res);
+        assertEquals(Math.round(origInsetHoriz / 2f), halfDrawable.getIntrinsicWidth()
+                - halfDrawable.getDrawable().getIntrinsicWidth());
+
+        // Set density to double original.
+        DrawableTestUtils.setResourcesDensity(res, densityDpi * 2);
+        final InsetDrawable doubleDrawable =
+                (InsetDrawable) preloadedConstantState.newDrawable(res);
+        assertEquals(origInsetHoriz * 2, doubleDrawable.getIntrinsicWidth()
+                - doubleDrawable.getDrawable().getIntrinsicWidth());
+
+        // Restore original density.
+        DrawableTestUtils.setResourcesDensity(res, densityDpi);
+        final InsetDrawable origDrawable =
+                (InsetDrawable) preloadedConstantState.newDrawable();
+        assertEquals(origInsetHoriz, origDrawable.getIntrinsicWidth()
+                - origDrawable.getDrawable().getIntrinsicWidth());
+
+        // Ensure theme density is applied correctly.
+        final Theme t = res.newTheme();
+        halfDrawable.applyTheme(t);
+        assertEquals(origInsetHoriz, halfDrawable.getIntrinsicWidth()
+                - halfDrawable.getDrawable().getIntrinsicWidth());
+        doubleDrawable.applyTheme(t);
+        assertEquals(origInsetHoriz, doubleDrawable.getIntrinsicWidth()
+                - doubleDrawable.getDrawable().getIntrinsicWidth());
+    }
+
     private class MockInsetDrawable extends InsetDrawable {
         public MockInsetDrawable(Drawable drawable, int inset) {
             super(drawable, inset);
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/LayerDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/LayerDrawableTest.java
index a2f9ddf..d180261 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/LayerDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/LayerDrawableTest.java
@@ -16,19 +16,17 @@
 
 package android.graphics.drawable.cts;
 
-import android.view.Gravity;
-import com.android.cts.graphics.R;
-
 import org.xmlpull.v1.XmlPullParserException;
 
-import java.io.IOException;
-
+import android.content.res.Resources;
+import android.content.res.Resources.Theme;
 import android.content.res.XmlResourceParser;
 import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.ColorFilter;
 import android.graphics.PixelFormat;
 import android.graphics.Rect;
+import android.graphics.cts.R;
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
@@ -41,8 +39,12 @@
 import android.test.AndroidTestCase;
 import android.util.AttributeSet;
 import android.util.StateSet;
+import android.util.Xml;
+import android.view.Gravity;
 import android.view.View;
 
+import java.io.IOException;
+
 public class LayerDrawableTest extends AndroidTestCase {
 
     @SuppressWarnings("deprecation")
@@ -258,7 +260,12 @@
 
     @SuppressWarnings("deprecation")
     public void testSetLayerInset() {
-        Drawable[] array = new Drawable[] { new BitmapDrawable(), new ColorDrawable(Color.BLUE) };
+        MockDrawable firstLayer = new MockDrawable();
+        firstLayer.setIntrinsicSize(10, 10);
+        MockDrawable secondLayer = new MockDrawable();
+        secondLayer.setIntrinsicSize(-1, -1);
+
+        Drawable[] array = new Drawable[] { firstLayer, secondLayer };
         LayerDrawable layerDrawable = new LayerDrawable(array);
 
         // set inset for layer 0
@@ -272,15 +279,12 @@
         assertEquals(layerDrawable.getDrawable(0).getIntrinsicHeight() + top + bottom,
                 layerDrawable.getIntrinsicHeight());
 
-        // set bigger inset for layer 1
-        left += 10;
-        top += 10;
-        right += 10;
-        bottom += 10;
-        layerDrawable.setLayerInset(1, left, top, right, bottom);
-        assertEquals(layerDrawable.getDrawable(1).getIntrinsicWidth() + left + right,
+        // The drawable at index 0 has no intrinsic width or height, so it
+        // won't be counted for the overall intrinsic width or height.
+        layerDrawable.setLayerInset(1, 10, 10, 10, 10);
+        assertEquals(layerDrawable.getDrawable(0).getIntrinsicWidth() + left + right,
                 layerDrawable.getIntrinsicWidth());
-        assertEquals(layerDrawable.getDrawable(1).getIntrinsicHeight() + top + bottom,
+        assertEquals(layerDrawable.getDrawable(0).getIntrinsicHeight() + top + bottom,
                 layerDrawable.getIntrinsicHeight());
 
         try {
@@ -439,7 +443,7 @@
         assertEquals(superConfig | childConfig, layerDrawable.getChangingConfigurations());
     }
 
-    public void testGetPadding() {
+    public void testAccessPadding() {
         Drawable[] array = new Drawable[] { new ShapeDrawable(), new ShapeDrawable() };
         LayerDrawable layerDrawable = new LayerDrawable(array);
 
@@ -467,6 +471,27 @@
         assertEquals(padding0.bottom + padding1.bottom, rc.bottom);
     }
 
+    public void testAccessPaddingMode() {
+        Rect padding = new Rect();
+        Drawable dr0 = new IntrinsicSizeDrawable(20, 30, new Rect(1, 2, 3, 4));
+        Drawable dr1 = new IntrinsicSizeDrawable(30, 40, new Rect(9, 8, 7, 6));
+        LayerDrawable layerDrawable = new LayerDrawable(new Drawable[] { dr0, dr1 });
+
+        assertEquals("Default padding mode is NEST",
+                LayerDrawable.PADDING_MODE_NEST, layerDrawable.getPaddingMode());
+        assertEquals(34, layerDrawable.getIntrinsicWidth());
+        assertEquals(46, layerDrawable.getIntrinsicHeight());
+        assertTrue(layerDrawable.getPadding(padding));
+        assertEquals(new Rect(10, 10, 10, 10), padding);
+
+        layerDrawable.setPaddingMode(LayerDrawable.PADDING_MODE_STACK);
+        assertEquals(LayerDrawable.PADDING_MODE_STACK, layerDrawable.getPaddingMode());
+        assertEquals(30, layerDrawable.getIntrinsicWidth());
+        assertEquals(40, layerDrawable.getIntrinsicHeight());
+        assertTrue(layerDrawable.getPadding(padding));
+        assertEquals(new Rect(9, 8, 7, 6), padding);
+    }
+
     @SuppressWarnings("deprecation")
     public void testSetVisible() {
         Drawable[] array = new Drawable[] { new BitmapDrawable(), new ColorDrawable(Color.BLUE) };
@@ -562,7 +587,7 @@
         assertTrue(mockDrawable2.hasCalledColorFilter());
     }
 
-    public void testGetOpacity() {
+    public void testAccessOpacity() {
         Drawable[] array = new Drawable[0];
         LayerDrawable layerDrawable = new LayerDrawable(array);
         assertEquals(PixelFormat.TRANSPARENT, layerDrawable.getOpacity());
@@ -586,6 +611,13 @@
         mockDrawable1.setOpacity(PixelFormat.TRANSLUCENT);
         mockDrawable2.setOpacity(PixelFormat.UNKNOWN);
         assertEquals(PixelFormat.UNKNOWN, layerDrawable.getOpacity());
+
+        layerDrawable = new LayerDrawable(array);
+        layerDrawable.setOpacity(PixelFormat.OPAQUE);
+        mockDrawable1.setOpacity(PixelFormat.TRANSLUCENT);
+        mockDrawable2.setOpacity(PixelFormat.UNKNOWN);
+        assertEquals(PixelFormat.OPAQUE, layerDrawable.getOpacity());
+
     }
 
     @SuppressWarnings("deprecation")
@@ -640,6 +672,21 @@
         assertTrue(mockDrawable2.hasCalledOnBoundsChange());
     }
 
+    public void testJumpToCurrentState() {
+        MockDrawable mockDrawable1 = new MockDrawable();
+        MockDrawable mockDrawable2 = new MockDrawable();
+        Drawable[] array = new Drawable[] { mockDrawable1, mockDrawable2 };
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+
+        assertFalse(mockDrawable1.hasCalledJumpToCurrentState());
+        assertFalse(mockDrawable2.hasCalledJumpToCurrentState());
+
+        layerDrawable.jumpToCurrentState();
+
+        assertTrue(mockDrawable1.hasCalledJumpToCurrentState());
+        assertTrue(mockDrawable2.hasCalledJumpToCurrentState());
+    }
+
     public void testSetLevel() {
         MockDrawable mockDrawable1 = new MockDrawable();
         MockDrawable mockDrawable2 = new MockDrawable();
@@ -720,11 +767,13 @@
     }
 
     public void testGetIntrinsicWidth() {
-        MockDrawable mockDrawable1 = new MockDrawable();
-        MockDrawable mockDrawable2 = new MockDrawable();
-        Drawable[] array = new Drawable[] { mockDrawable1, mockDrawable2 };
+        MockDrawable largeMockDrawable = new MockDrawable();
+        largeMockDrawable.setIntrinsicSize(10, 10);
+        MockDrawable smallMockDrawable = new MockDrawable();
+        smallMockDrawable.setIntrinsicSize(1, 1);
+        Drawable[] array = new Drawable[] { largeMockDrawable, smallMockDrawable };
         LayerDrawable layerDrawable = new LayerDrawable(array);
-        assertEquals(mockDrawable1.getIntrinsicWidth(), layerDrawable.getIntrinsicWidth());
+        assertEquals(largeMockDrawable.getIntrinsicWidth(), layerDrawable.getIntrinsicWidth());
 
         Rect inset1 = new Rect(1, 2, 3, 4);
         Rect inset2 = new Rect(2, 4, 6, 7);
@@ -732,26 +781,28 @@
         Rect padding2 = new Rect(21, 32, 43, 54);
         layerDrawable.setLayerInset(0, inset1.left, inset1.top, inset1.right, inset1.bottom);
         layerDrawable.setLayerInset(1, inset2.left, inset2.top, inset2.right, inset2.bottom);
-        mockDrawable1.setPadding(padding1);
-        mockDrawable2.setPadding(padding2);
+        largeMockDrawable.setPadding(padding1);
+        smallMockDrawable.setPadding(padding2);
         layerDrawable.getPadding(new Rect());
-        assertEquals(mockDrawable2.getIntrinsicWidth() + inset2.left
+        assertEquals(smallMockDrawable.getIntrinsicWidth() + inset2.left
                 + inset2.right + padding1.left + padding1.right,
                 layerDrawable.getIntrinsicWidth());
 
         inset1 = new Rect(inset2.left + padding1.left + 1, inset2.top + padding1.top + 1,
                 inset2.right + padding1.right + 1, inset2.bottom + padding1.bottom + 1);
         layerDrawable.setLayerInset(0, inset1.left, inset1.top, inset1.right, inset1.bottom);
-        assertEquals(mockDrawable1.getIntrinsicWidth() + inset1.left + inset1.right,
+        assertEquals(largeMockDrawable.getIntrinsicWidth() + inset1.left + inset1.right,
                 layerDrawable.getIntrinsicWidth());
     }
 
     public void testGetIntrinsicHeight() {
-        MockDrawable mockDrawable1 = new MockDrawable();
-        MockDrawable mockDrawable2 = new MockDrawable();
-        Drawable[] array = new Drawable[] { mockDrawable1, mockDrawable2 };
+        MockDrawable largeMockDrawable = new MockDrawable();
+        largeMockDrawable.setIntrinsicSize(10, 10);
+        MockDrawable smallMockDrawable = new MockDrawable();
+        smallMockDrawable.setIntrinsicSize(1, 1);
+        Drawable[] array = new Drawable[] { largeMockDrawable, smallMockDrawable };
         LayerDrawable layerDrawable = new LayerDrawable(array);
-        assertEquals(mockDrawable1.getIntrinsicHeight(), layerDrawable.getIntrinsicHeight());
+        assertEquals(largeMockDrawable.getIntrinsicHeight(), layerDrawable.getIntrinsicHeight());
 
         Rect inset1 = new Rect(1, 2, 3, 4);
         Rect inset2 = new Rect(2, 4, 6, 7);
@@ -759,17 +810,17 @@
         Rect padding2 = new Rect(21, 32, 43, 54);
         layerDrawable.setLayerInset(0, inset1.left, inset1.top, inset1.right, inset1.bottom);
         layerDrawable.setLayerInset(1, inset2.left, inset2.top, inset2.right, inset2.bottom);
-        mockDrawable1.setPadding(padding1);
-        mockDrawable2.setPadding(padding2);
+        largeMockDrawable.setPadding(padding1);
+        smallMockDrawable.setPadding(padding2);
         layerDrawable.getPadding(new Rect());
-        assertEquals(mockDrawable2.getIntrinsicHeight() + inset2.top
+        assertEquals(smallMockDrawable.getIntrinsicHeight() + inset2.top
                 + inset2.bottom + padding1.top + padding1.bottom,
                 layerDrawable.getIntrinsicHeight());
 
         inset1 = new Rect(inset2.left + padding1.left + 1, inset2.top + padding1.top + 1,
                 inset2.right + padding1.right + 1, inset2.bottom + padding1.bottom + 1);
         layerDrawable.setLayerInset(0, inset1.left, inset1.top, inset1.right, inset1.bottom);
-        assertEquals(mockDrawable1.getIntrinsicHeight() + inset1.top + inset1.bottom,
+        assertEquals(largeMockDrawable.getIntrinsicHeight() + inset1.top + inset1.bottom,
                 layerDrawable.getIntrinsicHeight());
     }
 
@@ -1056,10 +1107,14 @@
 
     @SuppressWarnings("deprecation")
     public void testSetLayerInsetRelative() {
-        Drawable[] array = new Drawable[] { new BitmapDrawable(), new ColorDrawable(Color.BLUE) };
+        MockDrawable firstLayer = new MockDrawable();
+        firstLayer.setIntrinsicSize(10, 10);
+        MockDrawable secondLayer = new MockDrawable();
+        secondLayer.setIntrinsicSize(-1, -1);
+
+        Drawable[] array = new Drawable[] { firstLayer, secondLayer };
         LayerDrawable layerDrawable = new LayerDrawable(array);
 
-        // set inset for layer 0
         int start = 10;
         int top = 20;
         int end = 30;
@@ -1069,25 +1124,21 @@
                 layerDrawable.getIntrinsicWidth());
         assertEquals(layerDrawable.getDrawable(0).getIntrinsicHeight() + top + bottom,
                 layerDrawable.getIntrinsicHeight());
-        assertEquals(10, layerDrawable.getLayerInsetStart(0));
-        assertEquals(20, layerDrawable.getLayerInsetTop(0));
-        assertEquals(30, layerDrawable.getLayerInsetEnd(0));
-        assertEquals(40, layerDrawable.getLayerInsetBottom(0));
+        assertEquals(start, layerDrawable.getLayerInsetStart(0));
+        assertEquals(top, layerDrawable.getLayerInsetTop(0));
+        assertEquals(end, layerDrawable.getLayerInsetEnd(0));
+        assertEquals(bottom, layerDrawable.getLayerInsetBottom(0));
         assertEquals(0, layerDrawable.getLayerInsetLeft(0));
         assertEquals(0, layerDrawable.getLayerInsetRight(0));
 
-        // set bigger inset for layer 1
-        start += 10;
-        top += 10;
-        end += 10;
-        bottom += 10;
-        layerDrawable.setLayerInsetRelative(1, start, top, end, bottom);
-        assertEquals(layerDrawable.getDrawable(1).getIntrinsicWidth() + start + end,
+        // The drawable at index 1 has no intrinsic width or height, so it
+        // won't be counted for the overall intrinsic width or height.
+        layerDrawable.setLayerInsetRelative(1, 10, 10, 10, 10);
+        assertEquals(layerDrawable.getDrawable(0).getIntrinsicWidth() + start + end,
                 layerDrawable.getIntrinsicWidth());
-        assertEquals(layerDrawable.getDrawable(1).getIntrinsicHeight() + top + bottom,
+        assertEquals(layerDrawable.getDrawable(0).getIntrinsicHeight() + top + bottom,
                 layerDrawable.getIntrinsicHeight());
 
-
         try {
             layerDrawable.setLayerInsetRelative(-1, start, top, end, bottom);
             fail("Should throw IndexOutOfBoundsException");
@@ -1390,7 +1441,29 @@
         }
     }
 
+    public void testChildIntrinsicSize() {
+        LayerDrawable dr;
 
+        // Ensure that a child with no intrinsic size correctly reports bounds.
+        dr = (LayerDrawable) getContext().getDrawable(R.drawable.layer_drawable_intrinsic);
+        assertEquals(-1, dr.getIntrinsicWidth());
+        assertEquals(-1, dr.getIntrinsicHeight());
+
+        // Check when creating the drawble from code.
+        dr = new LayerDrawable(new Drawable[] { new ColorDrawable(Color.RED) });
+        dr.setLayerInset(0, 10, 10, 10, 10);
+        assertEquals(-1, dr.getIntrinsicWidth());
+        assertEquals(-1, dr.getIntrinsicHeight());
+
+        // Ensure mixed children report bounds correctly as well.
+        dr = (LayerDrawable) getContext().getDrawable(R.drawable.layer_drawable_intrinsic_mixed);
+        int width = dr.getLayerInsetLeft(0) + dr.getLayerInsetRight(0)
+                + dr.getDrawable(0).getIntrinsicWidth();
+        int height = dr.getLayerInsetTop(0) + dr.getLayerInsetBottom(0)
+                + dr.getDrawable(0).getIntrinsicHeight();
+        assertEquals(width, dr.getIntrinsicWidth());
+        assertEquals(height, dr.getIntrinsicHeight());
+    }
 
     private static class MockDrawable extends Drawable {
         private boolean mCalledSetDither = false;
@@ -1400,7 +1473,7 @@
         private boolean mCalledSetState = false;
         private boolean mCalledOnLevelChange = false;
         private boolean mCalledOnBoundsChange = false;
-
+        private boolean mCalledJumpToCurrentState = false;
 
         private boolean mCalledDraw = false;
 
@@ -1408,6 +1481,9 @@
 
         private int mOpacity = PixelFormat.OPAQUE;
 
+        private int mIntrinsicWidth = -1;
+        private int mIntrinsicHeight = -1;
+
         private boolean mDither = false;
 
         Rect mPadding = null;
@@ -1454,6 +1530,21 @@
             mCalledSetDither = true;
         }
 
+        public void setIntrinsicSize(int width, int height) {
+            mIntrinsicWidth = width;
+            mIntrinsicHeight = height;
+        }
+
+        @Override
+        public int getIntrinsicWidth() {
+            return mIntrinsicWidth;
+        }
+
+        @Override
+        public int getIntrinsicHeight() {
+            return mIntrinsicHeight;
+        }
+
         public boolean hasCalledSetDither() {
             return mCalledSetDither;
         }
@@ -1474,11 +1565,23 @@
             mCalledSetState = false;
             mCalledOnLevelChange = false;
             mCalledOnBoundsChange = false;
+            mCalledJumpToCurrentState = false;
 
             mCalledDraw = false;
         }
 
         @Override
+        public void jumpToCurrentState() {
+            super.jumpToCurrentState();
+
+            mCalledJumpToCurrentState = true;
+        }
+
+        public boolean hasCalledJumpToCurrentState() {
+            return mCalledJumpToCurrentState;
+        }
+
+        @Override
         protected boolean onStateChange(int[] state) {
             increasePadding();
             return mIsStateful;
@@ -1583,4 +1686,189 @@
         assertEquals(50, ((BitmapDrawable) d3.getDrawable(0)).getPaint().getAlpha());
         assertEquals(50, ((BitmapDrawable) d3.getDrawable(0)).getPaint().getAlpha());
     }
+
+
+    public void testPreloadDensity() throws XmlPullParserException, IOException {
+        final Resources res = getContext().getResources();
+        final int densityDpi = res.getConfiguration().densityDpi;
+        try {
+            testPreloadDensityInner(res, densityDpi);
+        } finally {
+            DrawableTestUtils.setResourcesDensity(res, densityDpi);
+        }
+    }
+
+    private void testPreloadDensityInner(Resources res, int densityDpi)
+            throws XmlPullParserException, IOException {
+        // Capture initial state at default density.
+        final XmlResourceParser parser = DrawableTestUtils.getResourceParser(
+                res, R.drawable.layer_drawable_density);
+        final LayerDrawable preloadedDrawable = new LayerDrawable(new Drawable[0]);
+        preloadedDrawable.inflate(res, parser, Xml.asAttributeSet(parser));
+        final ConstantState preloadedConstantState = preloadedDrawable.getConstantState();
+        final int initialLeftPadding = preloadedDrawable.getLeftPadding();
+        final int initialRightPadding = preloadedDrawable.getRightPadding();
+        final int initialContentInsetL = preloadedDrawable.getLayerInsetLeft(0);
+        final int initialContentInsetR = preloadedDrawable.getLayerInsetRight(0);
+        final int initialContentWidth = preloadedDrawable.getLayerWidth(0);
+        final int initialIntrinsicWidth = preloadedDrawable.getIntrinsicWidth();
+        final int initialBottomPadding = preloadedDrawable.getBottomPadding();
+        final int initialTopPadding = preloadedDrawable.getTopPadding();
+        final int initialLayerInsetLeft = preloadedDrawable.getLayerInsetLeft(0);
+        final int initialLayerInsetRight = preloadedDrawable.getLayerInsetRight(0);
+        final int initialLayerInsetTop = preloadedDrawable.getLayerInsetTop(0);
+        final int initialLayerInsetBottom = preloadedDrawable.getLayerInsetBottom(0);
+        final int initialLayerWidth = preloadedDrawable.getLayerWidth(0);
+        final int initialLayerHeight = preloadedDrawable.getLayerHeight(0);
+
+        // Set density to half of original. Padding and insets are
+        // truncated, dimensions are rounded to the nearest pixel. Because
+        // LayerDrawable's intrinsic width is a combination of padding and
+        // dimensions, some computation is necessary.
+        DrawableTestUtils.setResourcesDensity(res, densityDpi / 2);
+        final LayerDrawable halfDrawable =
+                (LayerDrawable) preloadedConstantState.newDrawable(res);
+        final int halfContentWidth = Math.round(initialContentWidth / 2f);
+        final int halfLeftPadding = initialLeftPadding / 2;
+        final int halfRightPadding = initialRightPadding / 2;
+        final int halfContentInsetL = initialContentInsetL / 2;
+        final int halfContentInsetR = initialContentInsetR / 2;
+        final int halfIntrinsicWidth = halfContentWidth + halfContentInsetL + halfContentInsetR;
+        assertEquals(halfLeftPadding, halfDrawable.getLeftPadding());
+        assertEquals(halfRightPadding, halfDrawable.getRightPadding());
+        assertEquals(halfContentInsetL, halfDrawable.getLayerInsetRight(0));
+        assertEquals(halfContentInsetR, halfDrawable.getLayerInsetLeft(0));
+        assertEquals(halfContentWidth, halfDrawable.getLayerWidth(0));
+        assertEquals(halfIntrinsicWidth, halfDrawable.getIntrinsicWidth());
+        assertEquals(initialBottomPadding / 2, halfDrawable.getBottomPadding());
+        assertEquals(initialTopPadding / 2, halfDrawable.getTopPadding());
+        assertEquals(initialLayerInsetLeft / 2,halfDrawable.getLayerInsetLeft(0));
+        assertEquals(initialLayerInsetRight / 2, halfDrawable.getLayerInsetRight(0));
+        assertEquals(initialLayerInsetTop / 2, halfDrawable.getLayerInsetTop(0));
+        assertEquals(initialLayerInsetBottom / 2, halfDrawable.getLayerInsetBottom(0));
+        assertEquals(Math.round(initialLayerWidth / 2f), halfDrawable.getLayerWidth(0));
+        assertEquals(Math.round(initialLayerHeight / 2f), halfDrawable.getLayerHeight(0));
+
+        // Set density to double original.
+        DrawableTestUtils.setResourcesDensity(res, densityDpi * 2);
+        final LayerDrawable doubleDrawable =
+                (LayerDrawable) preloadedConstantState.newDrawable(res);
+        assertEquals(initialLeftPadding * 2, doubleDrawable.getLeftPadding());
+        assertEquals(initialRightPadding * 2, doubleDrawable.getRightPadding());
+        assertEquals(initialContentInsetL * 2, doubleDrawable.getLayerInsetRight(0));
+        assertEquals(initialContentInsetR * 2, doubleDrawable.getLayerInsetLeft(0));
+        assertEquals(initialContentWidth * 2, doubleDrawable.getLayerWidth(0));
+        assertEquals(initialIntrinsicWidth * 2, doubleDrawable.getIntrinsicWidth());
+        assertEquals(initialBottomPadding * 2, doubleDrawable.getBottomPadding());
+        assertEquals(initialTopPadding * 2, doubleDrawable.getTopPadding());
+        assertEquals(initialLayerInsetLeft * 2, doubleDrawable.getLayerInsetLeft(0));
+        assertEquals(initialLayerInsetRight * 2, doubleDrawable.getLayerInsetRight(0));
+        assertEquals(initialLayerInsetTop * 2, doubleDrawable.getLayerInsetTop(0));
+        assertEquals(initialLayerInsetBottom * 2, doubleDrawable.getLayerInsetBottom(0));
+        assertEquals(initialLayerWidth * 2, doubleDrawable.getLayerWidth(0));
+        assertEquals(initialLayerHeight * 2, doubleDrawable.getLayerHeight(0));
+
+        // Restore original configuration and metrics.
+        DrawableTestUtils.setResourcesDensity(res, densityDpi);
+        final LayerDrawable origDrawable =
+                (LayerDrawable) preloadedConstantState.newDrawable(res);
+        assertEquals(initialLeftPadding, origDrawable.getLeftPadding());
+        assertEquals(initialRightPadding, origDrawable.getRightPadding());
+        assertEquals(initialContentInsetL, origDrawable.getLayerInsetRight(0));
+        assertEquals(initialContentInsetR, origDrawable.getLayerInsetLeft(0));
+        assertEquals(initialContentWidth, origDrawable.getLayerWidth(0));
+        assertEquals(initialIntrinsicWidth, origDrawable.getIntrinsicWidth());
+        assertEquals(initialBottomPadding, origDrawable.getBottomPadding());
+        assertEquals(initialTopPadding, origDrawable.getTopPadding());
+        assertEquals(initialLayerInsetLeft, origDrawable.getLayerInsetLeft(0));
+        assertEquals(initialLayerInsetRight, origDrawable.getLayerInsetRight(0));
+        assertEquals(initialLayerInsetTop, origDrawable.getLayerInsetTop(0));
+        assertEquals(initialLayerInsetBottom, origDrawable.getLayerInsetBottom(0));
+        assertEquals(initialLayerWidth, origDrawable.getLayerWidth(0));
+        assertEquals(initialLayerHeight, origDrawable.getLayerHeight(0));
+
+        // Ensure theme density is applied correctly.
+        final Theme t = res.newTheme();
+
+        // The half-density drawable will scale-up all of the values that were
+        // previously scaled-down, so we need to capture the rounding errors.
+        halfDrawable.applyTheme(t);
+        assertEquals(halfLeftPadding * 2, halfDrawable.getLeftPadding());
+        assertEquals(halfRightPadding * 2, halfDrawable.getRightPadding());
+        assertEquals(halfContentInsetL * 2, halfDrawable.getLayerInsetRight(0));
+        assertEquals(halfContentInsetR * 2, halfDrawable.getLayerInsetLeft(0));
+        assertEquals(halfContentWidth * 2, halfDrawable.getLayerWidth(0));
+        assertEquals(halfIntrinsicWidth * 2, halfDrawable.getIntrinsicWidth());
+        assertEquals(2 * (initialBottomPadding / 2), halfDrawable.getBottomPadding());
+        assertEquals(2 * (initialTopPadding / 2), halfDrawable.getTopPadding());
+        assertEquals(2 * (initialLayerInsetLeft / 2), halfDrawable.getLayerInsetLeft(0));
+        assertEquals(2 * (initialLayerInsetRight / 2), halfDrawable.getLayerInsetRight(0));
+        assertEquals(2 * (initialLayerInsetTop / 2), halfDrawable.getLayerInsetTop(0));
+        assertEquals(2 * (initialLayerInsetBottom / 2), halfDrawable.getLayerInsetBottom(0));
+        assertEquals(2 * Math.round(initialLayerWidth / 2f), halfDrawable.getLayerWidth(0));
+        assertEquals(2 * Math.round(initialLayerHeight / 2f), halfDrawable.getLayerHeight(0));
+
+        // The double-density drawable will scale-down all of the values that
+        // were previously scaled-up, so we don't need to worry about rounding.
+        doubleDrawable.applyTheme(t);
+        assertEquals(initialLeftPadding, doubleDrawable.getLeftPadding());
+        assertEquals(initialRightPadding, doubleDrawable.getRightPadding());
+        assertEquals(initialContentInsetL, doubleDrawable.getLayerInsetRight(0));
+        assertEquals(initialContentInsetR, doubleDrawable.getLayerInsetLeft(0));
+        assertEquals(initialContentWidth, doubleDrawable.getLayerWidth(0));
+        assertEquals(initialIntrinsicWidth, doubleDrawable.getIntrinsicWidth());
+        assertEquals(initialBottomPadding, doubleDrawable.getBottomPadding());
+        assertEquals(initialTopPadding, doubleDrawable.getTopPadding());
+        assertEquals(initialLayerInsetLeft, doubleDrawable.getLayerInsetLeft(0));
+        assertEquals(initialLayerInsetRight, doubleDrawable.getLayerInsetRight(0));
+        assertEquals(initialLayerInsetTop, doubleDrawable.getLayerInsetTop(0));
+        assertEquals(initialLayerInsetBottom, doubleDrawable.getLayerInsetBottom(0));
+        assertEquals(initialLayerWidth, doubleDrawable.getLayerWidth(0));
+        assertEquals(initialLayerHeight, doubleDrawable.getLayerHeight(0));
+    }
+
+    private static class IntrinsicSizeDrawable extends Drawable {
+        private final int mIntrinsicWidth;
+        private final int mIntrinsicHeight;
+        private final Rect mPadding;
+
+        public IntrinsicSizeDrawable(int intrinsicWidth, int intrinsicHeight, Rect padding) {
+            mIntrinsicWidth = intrinsicWidth;
+            mIntrinsicHeight = intrinsicHeight;
+            mPadding = new Rect(padding);
+        }
+
+        @Override
+        public boolean getPadding(Rect padding) {
+            padding.set(mPadding);
+            return true;
+        }
+
+        @Override
+        public int getIntrinsicHeight() {
+            return mIntrinsicHeight;
+        }
+
+        @Override
+        public int getIntrinsicWidth() {
+            return mIntrinsicWidth;
+        }
+
+        @Override
+        public void draw(Canvas canvas) {
+        }
+
+        @Override
+        public void setAlpha(int alpha) {
+        }
+
+        @Override
+        public void setColorFilter(ColorFilter colorFilter) {
+        }
+
+        @Override
+        public int getOpacity() {
+            return 0;
+        }
+    }
 }
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/LevelListDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/LevelListDrawableTest.java
index 11186b0..4ef49c0 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/LevelListDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/LevelListDrawableTest.java
@@ -31,7 +31,7 @@
 import android.test.InstrumentationTestCase;
 import android.util.Xml;
 
-import com.android.cts.graphics.R;
+import android.graphics.cts.R;
 
 
 public class LevelListDrawableTest extends InstrumentationTestCase {
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/NinePatchDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/NinePatchDrawableTest.java
index 720397c..3f8b17f 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/NinePatchDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/NinePatchDrawableTest.java
@@ -16,7 +16,9 @@
 
 package android.graphics.drawable.cts;
 
-import com.android.cts.graphics.R;
+import android.content.res.Resources.Theme;
+import android.graphics.Outline;
+import android.graphics.cts.R;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
@@ -35,17 +37,31 @@
 import android.graphics.Region;
 import android.graphics.Bitmap.Config;
 import android.graphics.PorterDuff.Mode;
+import android.graphics.drawable.Drawable;
 import android.graphics.drawable.NinePatchDrawable;
 import android.graphics.drawable.Drawable.ConstantState;
 import android.test.InstrumentationTestCase;
 import android.util.AttributeSet;
+import android.util.DisplayMetrics;
 import android.util.Xml;
 
+import java.io.File;
+import java.io.FileOutputStream;
 import java.io.IOException;
 
 public class NinePatchDrawableTest extends InstrumentationTestCase {
+    // A small value is actually making sure that the values are matching
+    // exactly with the golden image.
+    // We can increase the threshold if the Skia is drawing with some variance
+    // on different devices. So far, the tests show they are matching correctly.
+    private static final float PIXEL_ERROR_THRESHOLD = 0.03f;
+    private static final float PIXEL_ERROR_COUNT_THRESHOLD = 0.005f;
+
     private static final int MIN_CHUNK_SIZE = 32;
 
+    // Set true to generate golden images, false for normal tests.
+    private static final boolean DBG_DUMP_PNG = false;
+
     private NinePatchDrawable mNinePatchDrawable;
 
     private Resources mResources;
@@ -183,7 +199,7 @@
         mNinePatchDrawable.setTint(Color.BLACK);
         mNinePatchDrawable.setTintMode(Mode.SRC_OVER);
         assertEquals("Nine-patch is tinted", Color.BLACK,
-                DrawableTestingUtils.getPixel(mNinePatchDrawable, 0, 0));
+                DrawableTestUtils.getPixel(mNinePatchDrawable, 0, 0));
 
         mNinePatchDrawable.setTintList(null);
         mNinePatchDrawable.setTintMode(null);
@@ -311,15 +327,23 @@
     }
 
     public void testInflate() throws XmlPullParserException, IOException {
-        final int width = 80;
-        final int height = 120;
-        final int[] COLOR = new int[width * height];
-        Bitmap bitmap = Bitmap.createBitmap(COLOR, width, height, Bitmap.Config.RGB_565);
-        NinePatchDrawable ninePatchDrawable =
-            new NinePatchDrawable(mResources, bitmap, new byte[1000], null, "TESTNAME");
+        int sourceWidth = 80;
+        int sourceHeight = 120;
+        int[] colors = new int[sourceWidth * sourceHeight];
+        Bitmap bitmap = Bitmap.createBitmap(
+                colors, sourceWidth, sourceHeight, Bitmap.Config.RGB_565);
+        NinePatchDrawable ninePatchDrawable = new NinePatchDrawable(
+                mResources, bitmap, new byte[1000], null, "TESTNAME");
 
-        assertEquals(height, ninePatchDrawable.getIntrinsicHeight());
-        assertEquals(width, ninePatchDrawable.getIntrinsicWidth());
+        int sourceDensity = bitmap.getDensity();
+        int targetDensity = mResources.getDisplayMetrics().densityDpi;
+        int targetWidth = DrawableTestUtils.scaleBitmapFromDensity(
+                sourceWidth, sourceDensity, targetDensity);
+        int targetHeight = DrawableTestUtils.scaleBitmapFromDensity(
+                sourceHeight, sourceDensity, targetDensity);
+        assertEquals(targetWidth, ninePatchDrawable.getIntrinsicWidth());
+        assertEquals(targetHeight, ninePatchDrawable.getIntrinsicHeight());
+
         XmlResourceParser parser = mResources.getXml(R.drawable.ninepatchdrawable);
         int type;
         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
@@ -329,8 +353,8 @@
         ninePatchDrawable.inflate(mResources, parser, attrs);
 
         assertTrue(ninePatchDrawable.getPaint().isDither());
-        assertTrue(height != ninePatchDrawable.getIntrinsicHeight());
-        assertTrue(width != ninePatchDrawable.getIntrinsicWidth());
+        assertTrue(sourceHeight != ninePatchDrawable.getIntrinsicHeight());
+        assertTrue(sourceWidth != ninePatchDrawable.getIntrinsicWidth());
     }
 
     public void testMutate() {
@@ -351,6 +375,243 @@
         d1.mutate();
     }
 
+    private static final int[] DENSITY_VALUES = new int[] {
+            160, 80, 320
+    };
+
+    private static final int[] DENSITY_IMAGES = new int[] {
+            R.drawable.nine_patch_density
+    };
+
+    private static final int[][] DENSITY_GOLDEN_IMAGES = new int[][] {
+            {
+                    R.drawable.nine_patch_density_golden_160,
+                    R.drawable.nine_patch_density_golden_80,
+                    R.drawable.nine_patch_density_golden_320,
+            }
+    };
+
+    private interface TargetDensitySetter {
+        void setTargetDensity(NinePatchDrawable dr, int density);
+    }
+
+    private void testSetTargetDensityOuter(TargetDensitySetter densitySetter) {
+        final Resources res = mResources;
+        final int densityDpi = res.getConfiguration().densityDpi;
+        try {
+            testSetTargetDensityInner(res, DENSITY_IMAGES[0], DENSITY_VALUES, densitySetter);
+        } catch (IOException | XmlPullParserException e) {
+            throw new RuntimeException(e);
+        } finally {
+            DrawableTestUtils.setResourcesDensity(res, densityDpi);
+        }
+    }
+
+    private void testSetTargetDensityInner(Resources res, int sourceResId, int[] densities,
+            TargetDensitySetter densitySetter) throws XmlPullParserException, IOException {
+        final Rect tempPadding = new Rect();
+
+        // Capture initial state at preload density.
+        final int preloadDensityDpi = densities[0];
+        DrawableTestUtils.setResourcesDensity(res, preloadDensityDpi);
+
+        final NinePatchDrawable preloadedDrawable =
+                (NinePatchDrawable) res.getDrawable(sourceResId).mutate();
+        final int origWidth = preloadedDrawable.getIntrinsicWidth();
+        final int origHeight = preloadedDrawable.getIntrinsicHeight();
+        final Rect origPadding = new Rect();
+        preloadedDrawable.getPadding(origPadding);
+
+        for (int i = 1; i < densities.length; i++) {
+            final int scaledDensityDpi = densities[i];
+            final float scale = scaledDensityDpi / (float) preloadDensityDpi;
+
+            final NinePatchDrawable scaledDrawable =
+                    (NinePatchDrawable) res.getDrawable(sourceResId).mutate();
+            densitySetter.setTargetDensity(scaledDrawable, scaledDensityDpi);
+
+            // Sizes are rounded.
+            assertEquals(Math.round(origWidth * scale), scaledDrawable.getIntrinsicWidth());
+            assertEquals(Math.round(origHeight * scale), scaledDrawable.getIntrinsicHeight());
+
+            // Padding is truncated.
+            assertTrue(scaledDrawable.getPadding(tempPadding));
+            assertEquals((int) (origPadding.left * scale), tempPadding.left);
+            assertEquals((int) (origPadding.top * scale), tempPadding.top);
+            assertEquals((int) (origPadding.right * scale), tempPadding.right);
+            assertEquals((int) (origPadding.bottom * scale), tempPadding.bottom);
+
+            // Ensure theme density is applied correctly. Unlike most
+            // drawables, we don't have any loss of accuracy because density
+            // changes are re-computed from the source every time.
+            DrawableTestUtils.setResourcesDensity(res, preloadDensityDpi);
+
+            final Theme t = res.newTheme();
+            scaledDrawable.applyTheme(t);
+            assertEquals(origWidth, scaledDrawable.getIntrinsicWidth());
+            assertEquals(origHeight, scaledDrawable.getIntrinsicHeight());
+            assertTrue(scaledDrawable.getPadding(tempPadding));
+            assertEquals(origPadding, tempPadding);
+        }
+    }
+
+    public void testSetTargetDensity() {
+        testSetTargetDensityOuter(new TargetDensitySetter() {
+            @Override
+            public void setTargetDensity(NinePatchDrawable dr, int density) {
+                dr.setTargetDensity(density);
+            }
+        });
+    }
+
+    public void testSetTargetDensity_Canvas() {
+        // This should be identical to calling setTargetDensity(int) with the
+        // value returned by Canvas.getDensity().
+        testSetTargetDensityOuter(new TargetDensitySetter() {
+            @Override
+            public void setTargetDensity(NinePatchDrawable dr, int density) {
+                Canvas c = new Canvas();
+                c.setDensity(density);
+                dr.setTargetDensity(c);
+            }
+        });
+    }
+
+    public void testSetTargetDensity_DisplayMetrics() {
+        // This should be identical to calling setTargetDensity(int) with the
+        // value of DisplayMetrics.densityDpi.
+        testSetTargetDensityOuter(new TargetDensitySetter() {
+            @Override
+            public void setTargetDensity(NinePatchDrawable dr, int density) {
+                DisplayMetrics dm = new DisplayMetrics();
+                dm.densityDpi = density;
+                dr.setTargetDensity(dm);
+            }
+        });
+    }
+
+    public void testPreloadDensity() throws XmlPullParserException, IOException {
+        final Resources res = mResources;
+        final int densityDpi = res.getConfiguration().densityDpi;
+        try {
+            testPreloadDensityInner(res, DENSITY_IMAGES[0], DENSITY_VALUES,
+                    DENSITY_GOLDEN_IMAGES[0]);
+        } finally {
+            DrawableTestUtils.setResourcesDensity(res, densityDpi);
+        }
+    }
+
+    private void testPreloadDensityInner(Resources res, int sourceResId, int[] densities,
+            int[] goldenResIds) throws XmlPullParserException, IOException {
+        // Capture initial state at preload density.
+        final int preloadDensityDpi = densities[0];
+        final NinePatchDrawable preloadedDrawable = preloadedDrawable(res,
+                densities[0], sourceResId);
+
+        final ConstantState preloadedConstantState = preloadedDrawable.getConstantState();
+        final int origWidth = preloadedDrawable.getIntrinsicWidth();
+        final int origHeight = preloadedDrawable.getIntrinsicHeight();
+        final Rect origPadding = new Rect();
+        preloadedDrawable.getPadding(origPadding);
+
+        compareOrSave(preloadedDrawable, preloadDensityDpi, sourceResId, goldenResIds[0]);
+
+        for (int i = 1; i < densities.length; i++) {
+            final int scaledDensityDpi = densities[i];
+            final float scale = scaledDensityDpi / (float) preloadDensityDpi;
+            DrawableTestUtils.setResourcesDensity(res, scaledDensityDpi);
+
+            final NinePatchDrawable scaledDrawable =
+                    (NinePatchDrawable) preloadedConstantState.newDrawable(res);
+
+            assertEquals(Math.round(origWidth * scale), scaledDrawable.getIntrinsicWidth());
+            assertEquals(Math.round(origHeight * scale), scaledDrawable.getIntrinsicHeight());
+
+            // Padding is truncated.
+            final Rect tempPadding = new Rect();
+            assertTrue(scaledDrawable.getPadding(tempPadding));
+            assertEquals((int) (origPadding.left * scale), tempPadding.left);
+            assertEquals((int) (origPadding.top * scale), tempPadding.top);
+            assertEquals((int) (origPadding.right * scale), tempPadding.right);
+            assertEquals((int) (origPadding.bottom * scale), tempPadding.bottom);
+
+            compareOrSave(scaledDrawable, scaledDensityDpi, sourceResId, goldenResIds[i]);
+
+            // Ensure theme density is applied correctly. Unlike most
+            // drawables, we don't have any loss of accuracy because density
+            // changes are re-computed from the source every time.
+            DrawableTestUtils.setResourcesDensity(res, preloadDensityDpi);
+
+            final Theme t = res.newTheme();
+            scaledDrawable.applyTheme(t);
+            assertEquals(origWidth, scaledDrawable.getIntrinsicWidth());
+            assertEquals(origHeight, scaledDrawable.getIntrinsicHeight());
+            assertTrue(scaledDrawable.getPadding(tempPadding));
+            assertEquals(origPadding, tempPadding);
+        }
+    }
+
+    private static NinePatchDrawable preloadedDrawable(Resources res, int densityDpi, int sourceResId)
+            throws XmlPullParserException, IOException {
+        DrawableTestUtils.setResourcesDensity(res, densityDpi);
+        final XmlResourceParser parser = DrawableTestUtils.getResourceParser(res, sourceResId);
+        final NinePatchDrawable preloadedDrawable = new NinePatchDrawable(null);
+        preloadedDrawable.inflate(res, parser, Xml.asAttributeSet(parser));
+        return preloadedDrawable;
+    }
+
+    public void testOutlinePreloadDensity() throws XmlPullParserException, IOException {
+        final Resources res = mResources;
+        final int densityDpi = res.getConfiguration().densityDpi;
+        try {
+            testOutlinePreloadDensityInner(res);
+        } finally {
+            DrawableTestUtils.setResourcesDensity(res, densityDpi);
+        }
+    }
+
+    private static void testOutlinePreloadDensityInner(Resources res)
+            throws XmlPullParserException, IOException {
+        // Capture initial state at preload density.
+        final int preloadDensityDpi = DENSITY_VALUES[0];
+        final NinePatchDrawable preloadedDrawable = preloadedDrawable(res, preloadDensityDpi,
+                R.drawable.nine_patch_odd_insets);
+
+        final ConstantState preloadedConstantState = preloadedDrawable.getConstantState();
+        final int bound = 40;
+        final int expectedInset = 5;
+        preloadedDrawable.setBounds(0, 0, bound, bound);
+        final Outline origOutline = new Outline();
+        preloadedDrawable.getOutline(origOutline);
+        final Rect origOutlineRect = new Rect();
+        origOutline.getRect(origOutlineRect);
+        assertEquals(new Rect(expectedInset, expectedInset, bound - expectedInset,
+                bound - expectedInset), origOutlineRect);
+        final float origOutlineRadius = origOutline.getRadius();
+        float expectedRadius = 6.8f;
+        assertEquals(expectedRadius, origOutlineRadius, 0.1f);
+        for (int i = 1; i < DENSITY_VALUES.length; i++) {
+            final int scaledDensityDpi = DENSITY_VALUES[i];
+            final float scale = scaledDensityDpi / (float) preloadDensityDpi;
+            DrawableTestUtils.setResourcesDensity(res, scaledDensityDpi);
+            final NinePatchDrawable scaledDrawable =
+                    (NinePatchDrawable) preloadedConstantState.newDrawable(res);
+
+            int scaledBound = (int) (bound * scale);
+            scaledDrawable.setBounds(0, 0, scaledBound, scaledBound);
+
+            final Outline tempOutline = new Outline();
+            scaledDrawable.getOutline(tempOutline);
+            final Rect tempOutlineRect = new Rect();
+            assertTrue(tempOutline.getRect(tempOutlineRect));
+            assertEquals((int) Math.ceil(origOutlineRect.left * scale), tempOutlineRect.left);
+            assertEquals((int) Math.ceil(origOutlineRect.top * scale), tempOutlineRect.top);
+            assertEquals((int) Math.floor(origOutlineRect.right * scale), tempOutlineRect.right);
+            assertEquals((int) Math.floor(origOutlineRect.bottom * scale), tempOutlineRect.bottom);
+            assertEquals(origOutlineRadius * scale, tempOutline.getRadius(), 0.1f);
+        }
+    }
+
     private void assertColorFillRect(Bitmap bmp, int x, int y, int w, int h, int color) {
         for (int i = x; i < x + w; i++) {
             for (int j = y; j < y + h; j++) {
@@ -374,6 +635,60 @@
         return bitmap;
     }
 
+    private void compareOrSave(Drawable dr, int densityDpi, int sourceResId, int goldenResId) {
+        final int width = dr.getIntrinsicWidth();
+        final int height = dr.getIntrinsicHeight();
+        final Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+        bitmap.setDensity(0);
+
+        final Canvas canvas = new Canvas(bitmap);
+        dr.setBounds(0, 0, width, height);
+        dr.draw(canvas);
+
+        if (DBG_DUMP_PNG) {
+            saveGoldenImage(bitmap, sourceResId, densityDpi);
+        } else {
+            final Bitmap golden = BitmapFactory.decodeResource(mResources, goldenResId);
+            DrawableTestUtils.compareImages(densityDpi + " dpi", golden, bitmap,
+                    PIXEL_ERROR_THRESHOLD, PIXEL_ERROR_COUNT_THRESHOLD);
+        }
+    }
+
+    private void saveGoldenImage(Bitmap bitmap, int sourceResId, int densityDpi) {
+        // Save the image to the disk.
+        FileOutputStream out = null;
+
+        try {
+            final String outputFolder = "/sdcard/temp/";
+            final File folder = new File(outputFolder);
+            if (!folder.exists()) {
+                folder.mkdir();
+            }
+
+            final String sourceFilename = new File(mResources.getString(sourceResId)).getName();
+            final String sourceTitle = sourceFilename.substring(0, sourceFilename.lastIndexOf("."));
+            final String outputTitle = sourceTitle + "_golden_" + densityDpi;
+            final String outputFilename = outputFolder + outputTitle + ".png";
+            final File outputFile = new File(outputFilename);
+            if (!outputFile.exists()) {
+                outputFile.createNewFile();
+            }
+
+            out = new FileOutputStream(outputFile, false);
+            bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            if (out != null) {
+                try {
+                    out.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+
     private class MockColorFilter extends ColorFilter {
     }
 }
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/PaintDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/PaintDrawableTest.java
index a440dab..fdb8f2f 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/PaintDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/PaintDrawableTest.java
@@ -16,7 +16,7 @@
 
 package android.graphics.drawable.cts;
 
-import com.android.cts.graphics.R;
+import android.graphics.cts.R;
 
 
 import org.xmlpull.v1.XmlPullParser;
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/RippleDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/RippleDrawableTest.java
index b04433c..2e46a09 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/RippleDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/RippleDrawableTest.java
@@ -16,12 +16,23 @@
 
 package android.graphics.drawable.cts;
 
-import com.android.cts.graphics.R;
+import static org.mockito.Mockito.*;
+
+import org.xmlpull.v1.XmlPullParserException;
 
 import android.content.res.ColorStateList;
-import android.graphics.drawable.RippleDrawable;
+import android.content.res.Resources;
+import android.content.res.Resources.Theme;
+import android.content.res.XmlResourceParser;
 import android.graphics.Color;
+import android.graphics.cts.R;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.Drawable.ConstantState;
+import android.graphics.drawable.RippleDrawable;
 import android.test.AndroidTestCase;
+import android.util.Xml;
+
+import java.io.IOException;
 
 public class RippleDrawableTest extends AndroidTestCase {
     public void testConstructor() {
@@ -41,4 +52,61 @@
                 (RippleDrawable) getContext().getDrawable(R.drawable.rippledrawable_radius);
         assertEquals(10, drawable.getRadius());
     }
+
+    public void testPreloadDensity() throws XmlPullParserException, IOException {
+        final Resources res = getContext().getResources();
+        final int densityDpi = res.getConfiguration().densityDpi;
+        try {
+            testPreloadDensityInner(res, densityDpi);
+        } finally {
+            DrawableTestUtils.setResourcesDensity(res, densityDpi);
+        }
+    }
+
+    private void testPreloadDensityInner(Resources res, int densityDpi)
+            throws XmlPullParserException, IOException {
+        // Capture initial state at default density.
+        final XmlResourceParser parser = DrawableTestUtils.getResourceParser(
+                res, R.drawable.rippledrawable_radius);
+        final RippleDrawable preloadedDrawable = new RippleDrawable(
+                ColorStateList.valueOf(Color.BLACK), null, null);
+        preloadedDrawable.inflate(res, parser, Xml.asAttributeSet(parser));
+        final ConstantState preloadedConstantState = preloadedDrawable.getConstantState();
+        final int initialRadius = preloadedDrawable.getRadius();
+
+        // Set density to half of original. Unlike offsets, which are
+        // truncated, dimensions are rounded to the nearest pixel.
+        DrawableTestUtils.setResourcesDensity(res, densityDpi / 2);
+        final RippleDrawable halfDrawable =
+                (RippleDrawable) preloadedConstantState.newDrawable(res);
+        assertEquals(Math.round(initialRadius / 2f), halfDrawable.getRadius());
+
+        // Set density to double original.
+        DrawableTestUtils.setResourcesDensity(res, densityDpi * 2);
+        final RippleDrawable doubleDrawable =
+                (RippleDrawable) preloadedConstantState.newDrawable(res);
+        assertEquals(initialRadius * 2, doubleDrawable.getRadius());
+
+        // Restore original density.
+        DrawableTestUtils.setResourcesDensity(res, densityDpi);
+        final RippleDrawable origDrawable =
+                (RippleDrawable) preloadedConstantState.newDrawable(res);
+        assertEquals(initialRadius, origDrawable.getRadius());
+
+        // Ensure theme density is applied correctly.
+        final Theme t = res.newTheme();
+        halfDrawable.applyTheme(t);
+        assertEquals(initialRadius, halfDrawable.getRadius());
+        doubleDrawable.applyTheme(t);
+        assertEquals(initialRadius, doubleDrawable.getRadius());
+    }
+
+    public void testSetColor() {
+        Drawable.Callback cb = mock(Drawable.Callback.class);
+        RippleDrawable dr = new RippleDrawable(ColorStateList.valueOf(Color.RED), null, null);
+        dr.setCallback(cb);
+
+        dr.setColor(ColorStateList.valueOf(Color.BLACK));
+        verify(cb, times(1)).invalidateDrawable(dr);
+    }
 }
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/RotateDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/RotateDrawableTest.java
index cf25857..e51edc12 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/RotateDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/RotateDrawableTest.java
@@ -16,7 +16,7 @@
 
 package android.graphics.drawable.cts;
 
-import com.android.cts.graphics.R;
+import android.graphics.cts.R;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
@@ -57,6 +57,60 @@
         mRotateDrawable.draw(canvas);
     }
 
+    public void testInflate() {
+        RotateDrawable d;
+
+        d = (RotateDrawable) mContext.getResources().getDrawable(R.drawable.rotatedrawable_rel);
+        assertEquals(0.1f, d.getPivotX(), 0.01f);
+        assertEquals(0.2f, d.getPivotY(), 0.01f);
+        assertEquals(360.0f, d.getFromDegrees(), 0.01f);
+        assertEquals(360.0f, d.getToDegrees(), 0.01f);
+        assertEquals(true, d.isPivotXRelative());
+        assertEquals(true, d.isPivotYRelative());
+
+        d = (RotateDrawable) mContext.getResources().getDrawable(R.drawable.rotatedrawable_abs);
+        assertEquals(0.3f, d.getPivotX(), 0.01f);
+        assertEquals(0.3f, d.getPivotY(), 0.01f);
+        assertEquals(180.0f, d.getFromDegrees(), 0.01f);
+        assertEquals(-180.0f, d.getToDegrees(), 0.01f);
+        assertEquals(false, d.isPivotXRelative());
+        assertEquals(false, d.isPivotYRelative());
+    }
+
+    public void testSetPivot() {
+        RotateDrawable d = new RotateDrawable();
+        assertEquals(0.5f, d.getPivotX(), 0.01f);
+        assertEquals(0.5f, d.getPivotY(), 0.01f);
+        assertEquals(true, d.isPivotXRelative());
+        assertEquals(true, d.isPivotYRelative());
+
+        d.setPivotX(10.0f);
+        assertEquals(10.0f, d.getPivotX(), 0.01f);
+
+        d.setPivotY(10.0f);
+        assertEquals(10.0f, d.getPivotY(), 0.01f);
+
+        d.setPivotXRelative(false);
+        assertEquals(false, d.isPivotXRelative());
+
+        d.setPivotYRelative(false);
+        assertEquals(false, d.isPivotYRelative());
+    }
+
+    public void testSetDegrees() {
+        RotateDrawable d = new RotateDrawable();
+        assertEquals(0.0f, d.getFromDegrees(), 0.01f);
+        assertEquals(360.0f, d.getToDegrees(), 0.01f);
+
+        d.setFromDegrees(-10.0f);
+        assertEquals(-10.0f, d.getFromDegrees(), 0.01f);
+        assertEquals(360.0f, d.getToDegrees(), 0.01f);
+
+        d.setToDegrees(10.0f);
+        assertEquals(10.0f, d.getToDegrees(), 0.01f);
+        assertEquals(-10.0f, d.getFromDegrees(), 0.01f);
+    }
+
     public void testGetChangingConfigurations() {
         assertEquals(0, mRotateDrawable.getChangingConfigurations());
 
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/ScaleDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/ScaleDrawableTest.java
index b58e40f..e1f37b3 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/ScaleDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/ScaleDrawableTest.java
@@ -16,7 +16,7 @@
 
 package android.graphics.drawable.cts;
 
-import com.android.cts.graphics.R;
+import android.graphics.cts.R;
 
 import org.xmlpull.v1.XmlPullParserException;
 
@@ -33,6 +33,7 @@
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.Drawable.ConstantState;
 import android.graphics.drawable.ScaleDrawable;
+import android.os.Debug;
 import android.test.AndroidTestCase;
 import android.util.AttributeSet;
 import android.util.DisplayMetrics;
@@ -296,6 +297,29 @@
         // expected, no Exception thrown out, test success
     }
 
+    public void testInitialLevel() throws XmlPullParserException, IOException {
+        ScaleDrawable dr = new ScaleDrawable(null, Gravity.CENTER, 1, 1);
+        Resources res = mContext.getResources();
+        XmlResourceParser parser = res.getXml(R.xml.scaledrawable_level);
+        AttributeSet attrs = DrawableTestUtils.getAttributeSet(parser, "scale_allattrs");
+
+        // Ensure that initial level is loaded from XML.
+        dr.inflate(res, parser, attrs);
+        assertEquals(5000, dr.getLevel());
+
+        dr.setLevel(0);
+        assertEquals(0, dr.getLevel());
+
+        // Ensure that initial level is propagated to constant state clones.
+        ScaleDrawable clone = (ScaleDrawable) dr.getConstantState().newDrawable(res);
+        assertEquals(5000, clone.getLevel());
+
+        // Ensure that current level is not tied to constant state.
+        dr.setLevel(1000);
+        assertEquals(1000, dr.getLevel());
+        assertEquals(5000, clone.getLevel());
+    }
+
     public void testOnLevelChange() {
         MockDrawable mockDrawable = new MockDrawable();
         MockScaleDrawable mockScaleDrawable = new MockScaleDrawable(
@@ -411,8 +435,7 @@
         XmlResourceParser parser = res.getXml(R.xml.scaledrawable);
         AttributeSet attrs = DrawableTestUtils.getAttributeSet(parser, "scale_allattrs");
         scaleDrawable.inflate(res, parser, attrs);
-        int bitmapSize = (int) Math.ceil(48.0 *
-                res.getDisplayMetrics().densityDpi / DisplayMetrics.DENSITY_DEFAULT);
+        final int bitmapSize = Math.round(48f * res.getDisplayMetrics().density);
         assertEquals(bitmapSize, scaleDrawable.getIntrinsicWidth());
         assertEquals(bitmapSize, scaleDrawable.getIntrinsicHeight());
 
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/ShapeDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/ShapeDrawableTest.java
index 5b3234e..1449bad 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/ShapeDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/ShapeDrawableTest.java
@@ -34,7 +34,7 @@
 import android.util.AttributeSet;
 import android.util.Xml;
 
-import com.android.cts.graphics.R;
+import android.graphics.cts.R;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
@@ -319,7 +319,7 @@
         final ShapeDrawable d = new ShapeDrawable(new RectShape());
         d.setTint(Color.BLACK);
         d.setTintMode(Mode.SRC_OVER);
-        assertEquals("Shape is tinted", Color.BLACK, DrawableTestingUtils.getPixel(d, 0, 0));
+        assertEquals("Shape is tinted", Color.BLACK, DrawableTestUtils.getPixel(d, 0, 0));
     }
 
     public void testSetDither() {
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/StateListDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/StateListDrawableTest.java
index d55b91d..2194a00 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/StateListDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/StateListDrawableTest.java
@@ -22,23 +22,27 @@
 import org.xmlpull.v1.XmlPullParserException;
 
 import android.R.attr;
+import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.content.res.XmlResourceParser;
 import android.graphics.Canvas;
 import android.graphics.ColorFilter;
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
+import android.graphics.drawable.Drawable.ConstantState;
 import android.graphics.drawable.StateListDrawable;
 import android.graphics.drawable.DrawableContainer.DrawableContainerState;
 import android.test.InstrumentationTestCase;
+import android.util.DisplayMetrics;
 import android.util.StateSet;
 import android.util.Xml;
 
-import com.android.cts.graphics.R;
+import android.graphics.cts.R;
 
 
 public class StateListDrawableTest extends InstrumentationTestCase {
-    private MockStateListDrawable mStateListDrawable;
+    private MockStateListDrawable mMockDrawable;
+    private StateListDrawable mDrawable;
 
     private Resources mResources;
 
@@ -47,8 +51,8 @@
     @Override
     protected void setUp() throws Exception {
         super.setUp();
-        mStateListDrawable = new MockStateListDrawable();
-        mDrawableContainerState = (DrawableContainerState) mStateListDrawable.getConstantState();
+        mDrawable = mMockDrawable = new MockStateListDrawable();
+        mDrawableContainerState = (DrawableContainerState) mMockDrawable.getConstantState();
         mResources = getInstrumentation().getTargetContext().getResources();
     }
 
@@ -60,32 +64,34 @@
     }
 
     public void testAddState() {
+        // Workaround for CTS coverage not recognizing calls on subclasses.
+        StateListDrawable dr = mMockDrawable;
+
         assertEquals(0, mDrawableContainerState.getChildCount());
 
         // nothing happens if drawable is null
-        mStateListDrawable.reset();
-        mStateListDrawable.addState(StateSet.WILD_CARD, null);
+        mMockDrawable.reset();
+        dr.addState(StateSet.WILD_CARD, null);
         assertEquals(0, mDrawableContainerState.getChildCount());
-        assertFalse(mStateListDrawable.hasCalledOnStateChanged());
+        assertFalse(mMockDrawable.hasCalledOnStateChanged());
 
         // call onLevelChanged to assure that the correct drawable is selected.
-        mStateListDrawable.reset();
-        mStateListDrawable.addState(StateSet.WILD_CARD, new MockDrawable());
+        mMockDrawable.reset();
+        dr.addState(StateSet.WILD_CARD, new MockDrawable());
         assertEquals(1, mDrawableContainerState.getChildCount());
-        assertTrue(mStateListDrawable.hasCalledOnStateChanged());
+        assertTrue(mMockDrawable.hasCalledOnStateChanged());
 
-        mStateListDrawable.reset();
-        mStateListDrawable.addState(new int[] { attr.state_focused, - attr.state_selected },
-                new MockDrawable());
+        mMockDrawable.reset();
+        dr.addState(new int[] { attr.state_focused, - attr.state_selected }, new MockDrawable());
         assertEquals(2, mDrawableContainerState.getChildCount());
-        assertTrue(mStateListDrawable.hasCalledOnStateChanged());
+        assertTrue(mMockDrawable.hasCalledOnStateChanged());
 
         // call onLevelChanged will not throw NPE here because the first drawable with wild card
         // state is matched first. There is no chance that other drawables will be matched.
-        mStateListDrawable.reset();
-        mStateListDrawable.addState(null, new MockDrawable());
+        mMockDrawable.reset();
+        dr.addState(null, new MockDrawable());
         assertEquals(3, mDrawableContainerState.getChildCount());
-        assertTrue(mStateListDrawable.hasCalledOnStateChanged());
+        assertTrue(mMockDrawable.hasCalledOnStateChanged());
     }
 
     public void testIsStateful() {
@@ -93,110 +99,180 @@
     }
 
     public void testOnStateChange() {
-        mStateListDrawable.addState(new int[] { attr.state_focused, - attr.state_selected },
+        mMockDrawable.addState(new int[] { attr.state_focused, - attr.state_selected },
                 new MockDrawable());
-        mStateListDrawable.addState(StateSet.WILD_CARD, new MockDrawable());
-        mStateListDrawable.addState(StateSet.WILD_CARD, new MockDrawable());
+        mMockDrawable.addState(StateSet.WILD_CARD, new MockDrawable());
+        mMockDrawable.addState(StateSet.WILD_CARD, new MockDrawable());
 
         // the method is not called if same state is set
-        mStateListDrawable.reset();
-        mStateListDrawable.setState(mStateListDrawable.getState());
-        assertFalse(mStateListDrawable.hasCalledOnStateChanged());
+        mMockDrawable.reset();
+        mMockDrawable.setState(mMockDrawable.getState());
+        assertFalse(mMockDrawable.hasCalledOnStateChanged());
 
         // the method is called if different state is set
-        mStateListDrawable.reset();
-        mStateListDrawable.setState(new int[] { attr.state_focused, - attr.state_selected });
-        assertTrue(mStateListDrawable.hasCalledOnStateChanged());
+        mMockDrawable.reset();
+        mMockDrawable.setState(new int[] { attr.state_focused, - attr.state_selected });
+        assertTrue(mMockDrawable.hasCalledOnStateChanged());
 
-        mStateListDrawable.reset();
-        mStateListDrawable.setState(null);
-        assertTrue(mStateListDrawable.hasCalledOnStateChanged());
+        mMockDrawable.reset();
+        mMockDrawable.setState(null);
+        assertTrue(mMockDrawable.hasCalledOnStateChanged());
 
         // check that correct drawable is selected.
-        mStateListDrawable.onStateChange(new int[] { attr.state_focused, - attr.state_selected });
-        assertSame(mStateListDrawable.getCurrent(), mDrawableContainerState.getChildren()[0]);
+        mMockDrawable.onStateChange(new int[] { attr.state_focused, - attr.state_selected });
+        assertSame(mMockDrawable.getCurrent(), mDrawableContainerState.getChildren()[0]);
 
-        assertFalse(mStateListDrawable.onStateChange(new int[] { attr.state_focused }));
-        assertSame(mStateListDrawable.getCurrent(), mDrawableContainerState.getChildren()[0]);
+        assertFalse(mMockDrawable.onStateChange(new int[] { attr.state_focused }));
+        assertSame(mMockDrawable.getCurrent(), mDrawableContainerState.getChildren()[0]);
 
-        assertTrue(mStateListDrawable.onStateChange(StateSet.WILD_CARD));
-        assertSame(mStateListDrawable.getCurrent(), mDrawableContainerState.getChildren()[1]);
+        assertTrue(mMockDrawable.onStateChange(StateSet.WILD_CARD));
+        assertSame(mMockDrawable.getCurrent(), mDrawableContainerState.getChildren()[1]);
 
         // null state will match the wild card
-        assertFalse(mStateListDrawable.onStateChange(null));
-        assertSame(mStateListDrawable.getCurrent(), mDrawableContainerState.getChildren()[1]);
+        assertFalse(mMockDrawable.onStateChange(null));
+        assertSame(mMockDrawable.getCurrent(), mDrawableContainerState.getChildren()[1]);
     }
 
     public void testOnStateChangeWithWildCardAtFirst() {
-        mStateListDrawable.addState(StateSet.WILD_CARD, new MockDrawable());
-        mStateListDrawable.addState(new int[] { attr.state_focused, - attr.state_selected },
+        mMockDrawable.addState(StateSet.WILD_CARD, new MockDrawable());
+        mMockDrawable.addState(new int[] { attr.state_focused, - attr.state_selected },
                 new MockDrawable());
 
         // matches the first wild card although the second one is more accurate
-        mStateListDrawable.onStateChange(new int[] { attr.state_focused, - attr.state_selected });
-        assertSame(mStateListDrawable.getCurrent(), mDrawableContainerState.getChildren()[0]);
+        mMockDrawable.onStateChange(new int[] { attr.state_focused, - attr.state_selected });
+        assertSame(mMockDrawable.getCurrent(), mDrawableContainerState.getChildren()[0]);
     }
 
     public void testOnStateChangeWithNullStateSet() {
         assertEquals(0, mDrawableContainerState.getChildCount());
         try {
-            mStateListDrawable.addState(null, new MockDrawable());
+            mMockDrawable.addState(null, new MockDrawable());
             fail("Should throw NullPointerException.");
         } catch (NullPointerException e) {
         }
         assertEquals(1, mDrawableContainerState.getChildCount());
 
         try {
-            mStateListDrawable.onStateChange(StateSet.WILD_CARD);
+            mMockDrawable.onStateChange(StateSet.WILD_CARD);
             fail("Should throw NullPointerException.");
         } catch (NullPointerException e) {
         }
     }
 
+    public void testPreloadDensity() throws XmlPullParserException, IOException {
+        runPreloadDensityTestForDrawable(R.drawable.state_list_density, false);
+    }
+
+    public void testPreloadDensityConstantSize() throws XmlPullParserException, IOException {
+        runPreloadDensityTestForDrawable(R.drawable.state_list_density_constant_size, true);
+    }
+
+    private void runPreloadDensityTestForDrawable(int drawableResId, boolean isConstantSize)
+            throws XmlPullParserException, IOException {
+        final Resources res = mResources;
+        final int densityDpi = res.getConfiguration().densityDpi;
+        try {
+            runPreloadDensityTestForDrawableInner(res, densityDpi, drawableResId, isConstantSize);
+        } finally {
+            DrawableTestUtils.setResourcesDensity(res, densityDpi);
+        }
+    }
+
+    private void runPreloadDensityTestForDrawableInner(Resources res, int densityDpi,
+            int drawableResId, boolean isConstantSize) throws XmlPullParserException, IOException {
+        // Capture initial state at default density.
+        final XmlResourceParser parser = getResourceParser(drawableResId);
+        final StateListDrawable preloadedDrawable = new StateListDrawable();
+        preloadedDrawable.inflate(res, parser, Xml.asAttributeSet(parser));
+        final ConstantState preloadedConstantState = preloadedDrawable.getConstantState();
+        preloadedDrawable.selectDrawable(0);
+        final int tempWidth0 = preloadedDrawable.getIntrinsicWidth();
+        preloadedDrawable.selectDrawable(1);
+        final int tempWidth1 = preloadedDrawable.getIntrinsicWidth();
+
+        // Pick comparison widths based on constant size.
+        final int origWidth0;
+        final int origWidth1;
+        if (isConstantSize) {
+            origWidth0 = Math.max(tempWidth0, tempWidth1);
+            origWidth1 = origWidth0;
+        } else {
+            origWidth0 = tempWidth0;
+            origWidth1 = tempWidth1;
+        }
+
+        // Set density to half of original.
+        DrawableTestUtils.setResourcesDensity(res, densityDpi / 2);
+        final StateListDrawable halfDrawable =
+                (StateListDrawable) preloadedConstantState.newDrawable(res);
+        halfDrawable.selectDrawable(0);
+        assertEquals(Math.round(origWidth0 / 2f), halfDrawable.getIntrinsicWidth());
+        halfDrawable.selectDrawable(1);
+        assertEquals(Math.round(origWidth1 / 2f), halfDrawable.getIntrinsicWidth());
+
+        // Set density to double original.
+        DrawableTestUtils.setResourcesDensity(res, densityDpi * 2);
+        final StateListDrawable doubleDrawable =
+                (StateListDrawable) preloadedConstantState.newDrawable(res);
+        doubleDrawable.selectDrawable(0);
+        assertEquals(origWidth0 * 2, doubleDrawable.getIntrinsicWidth());
+        doubleDrawable.selectDrawable(1);
+        assertEquals(origWidth1 * 2, doubleDrawable.getIntrinsicWidth());
+
+        // Restore original configuration and metrics.
+        DrawableTestUtils.setResourcesDensity(res, densityDpi);
+        final StateListDrawable origDrawable =
+                (StateListDrawable) preloadedConstantState.newDrawable(res);
+        origDrawable.selectDrawable(0);
+        assertEquals(origWidth0, origDrawable.getIntrinsicWidth());
+        origDrawable.selectDrawable(1);
+        assertEquals(origWidth1, origDrawable.getIntrinsicWidth());
+    }
+
     public void testInflate() throws XmlPullParserException, IOException {
         XmlResourceParser parser = getResourceParser(R.xml.selector_correct);
 
-        mStateListDrawable.reset();
-        mStateListDrawable.inflate(mResources, parser, Xml.asAttributeSet(parser));
+        mMockDrawable.reset();
+        mMockDrawable.inflate(mResources, parser, Xml.asAttributeSet(parser));
         // android:visible="false"
-        assertFalse(mStateListDrawable.isVisible());
+        assertFalse(mMockDrawable.isVisible());
         // android:constantSize="true"
         assertTrue(mDrawableContainerState.isConstantSize());
         // android:variablePadding="true"
         assertNull(mDrawableContainerState.getConstantPadding());
-        assertTrue(mStateListDrawable.hasCalledOnStateChanged());
+        assertTrue(mMockDrawable.hasCalledOnStateChanged());
         assertEquals(2, mDrawableContainerState.getChildCount());
         // check the android:state_* by calling setState
-        mStateListDrawable.setState(new int[]{ attr.state_focused, - attr.state_pressed });
-        assertSame(mStateListDrawable.getCurrent(), mDrawableContainerState.getChildren()[0]);
-        mStateListDrawable.setState(StateSet.WILD_CARD);
-        assertSame(mStateListDrawable.getCurrent(), mDrawableContainerState.getChildren()[1]);
+        mMockDrawable.setState(new int[]{ attr.state_focused, - attr.state_pressed });
+        assertSame(mMockDrawable.getCurrent(), mDrawableContainerState.getChildren()[0]);
+        mMockDrawable.setState(StateSet.WILD_CARD);
+        assertSame(mMockDrawable.getCurrent(), mDrawableContainerState.getChildren()[1]);
 
-        mStateListDrawable = new MockStateListDrawable();
-        mDrawableContainerState = (DrawableContainerState) mStateListDrawable.getConstantState();
-        assertNull(mStateListDrawable.getCurrent());
-        mStateListDrawable.reset();
-        assertTrue(mStateListDrawable.isVisible());
+        mMockDrawable = new MockStateListDrawable();
+        mDrawableContainerState = (DrawableContainerState) mMockDrawable.getConstantState();
+        assertNull(mMockDrawable.getCurrent());
+        mMockDrawable.reset();
+        assertTrue(mMockDrawable.isVisible());
         parser = getResourceParser(R.xml.selector_missing_selector_attrs);
-        mStateListDrawable.inflate(mResources, parser, Xml.asAttributeSet(parser));
+        mMockDrawable.inflate(mResources, parser, Xml.asAttributeSet(parser));
         // use current the visibility
-        assertTrue(mStateListDrawable.isVisible());
+        assertTrue(mMockDrawable.isVisible());
         // default value of android:constantSize is false
         assertFalse(mDrawableContainerState.isConstantSize());
         // default value of android:variablePadding is false
         // TODO: behavior of mDrawableContainerState.getConstantPadding() when variablePadding is
         // false is undefined
         //assertNotNull(mDrawableContainerState.getConstantPadding());
-        assertTrue(mStateListDrawable.hasCalledOnStateChanged());
+        assertTrue(mMockDrawable.hasCalledOnStateChanged());
         assertEquals(1, mDrawableContainerState.getChildCount());
-        mStateListDrawable.setState(new int[]{ - attr.state_pressed, attr.state_focused });
-        assertSame(mStateListDrawable.getCurrent(), mDrawableContainerState.getChildren()[0]);
-        mStateListDrawable.setState(StateSet.WILD_CARD);
-        assertNull(mStateListDrawable.getCurrent());
+        mMockDrawable.setState(new int[]{ - attr.state_pressed, attr.state_focused });
+        assertSame(mMockDrawable.getCurrent(), mDrawableContainerState.getChildren()[0]);
+        mMockDrawable.setState(StateSet.WILD_CARD);
+        assertNull(mMockDrawable.getCurrent());
 
         parser = getResourceParser(R.xml.selector_missing_item_drawable);
         try {
-            mStateListDrawable.inflate(mResources, parser, Xml.asAttributeSet(parser));
+            mMockDrawable.inflate(mResources, parser, Xml.asAttributeSet(parser));
             fail("Should throw XmlPullParserException if drawable of item is missing");
         } catch (XmlPullParserException e) {
         }
@@ -205,19 +281,19 @@
     public void testInflateWithNullParameters() throws XmlPullParserException, IOException{
         XmlResourceParser parser = getResourceParser(R.xml.level_list_correct);
         try {
-            mStateListDrawable.inflate(null, parser, Xml.asAttributeSet(parser));
+            mMockDrawable.inflate(null, parser, Xml.asAttributeSet(parser));
             fail("Should throw XmlPullParserException if resource is null");
         } catch (NullPointerException e) {
         }
 
         try {
-            mStateListDrawable.inflate(mResources, null, Xml.asAttributeSet(parser));
+            mMockDrawable.inflate(mResources, null, Xml.asAttributeSet(parser));
             fail("Should throw XmlPullParserException if parser is null");
         } catch (NullPointerException e) {
         }
 
         try {
-            mStateListDrawable.inflate(mResources, parser, null);
+            mMockDrawable.inflate(mResources, parser, null);
             fail("Should throw XmlPullParserException if AttributeSet is null");
         } catch (NullPointerException e) {
         }
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/ThemedDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/ThemedDrawableTest.java
index d7becc6..52bef55 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/ThemedDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/ThemedDrawableTest.java
@@ -32,7 +32,7 @@
 import android.test.AndroidTestCase;
 import android.view.Gravity;
 
-import com.android.cts.graphics.R;
+import android.graphics.cts.R;
 
 @TargetApi(21)
 public class ThemedDrawableTest extends AndroidTestCase {
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/TransitionDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/TransitionDrawableTest.java
index f2a22a2..c0ef1be 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/TransitionDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/TransitionDrawableTest.java
@@ -16,7 +16,7 @@
 
 package android.graphics.drawable.cts;
 
-import com.android.cts.graphics.R;
+import android.graphics.cts.R;
 
 import android.content.res.Resources;
 import android.graphics.Bitmap;
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/VectorDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/VectorDrawableTest.java
index fdc7b7a..3845ba5 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/VectorDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/VectorDrawableTest.java
@@ -16,33 +16,40 @@
 
 package android.graphics.drawable.cts;
 
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
 import android.content.res.Resources;
+import android.content.res.Resources.Theme;
+import android.content.res.XmlResourceParser;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.graphics.Canvas;
 import android.graphics.Color;
-import android.graphics.ColorFilter;
+import android.graphics.PixelFormat;
 import android.graphics.PorterDuff.Mode;
 import android.graphics.PorterDuffColorFilter;
-import android.graphics.drawable.VectorDrawable;
+import android.graphics.cts.R;
 import android.graphics.drawable.Drawable.ConstantState;
+import android.graphics.drawable.VectorDrawable;
 import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.test.suitebuilder.annotation.SmallTest;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.util.Xml;
 
-import com.android.cts.graphics.R;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
 
 public class VectorDrawableTest extends AndroidTestCase {
-    private static final String LOGTAG = VectorDrawableTest.class.getSimpleName();
-    private int[] mIconResIds = new int[] {
+    private static final String LOGTAG = "VectorDrawableTest";
+
+    // Separate the test assets into different groups such that we could isolate the issue faster.
+    // Some new APIs or bug fixes only exist in particular os version, such that we name the tests
+    // and associated assets with OS code name L, M, N etc...
+    private static final int[] BASIC_ICON_RES_IDS = new int[]{
             R.drawable.vector_icon_create,
             R.drawable.vector_icon_delete,
             R.drawable.vector_icon_heart,
@@ -55,6 +62,24 @@
             R.drawable.vector_icon_repeated_a_1,
             R.drawable.vector_icon_repeated_a_2,
             R.drawable.vector_icon_clip_path_1,
+    };
+
+    private static final int[] BASIC_GOLDEN_IMAGES = new int[] {
+            R.drawable.vector_icon_create_golden,
+            R.drawable.vector_icon_delete_golden,
+            R.drawable.vector_icon_heart_golden,
+            R.drawable.vector_icon_schedule_golden,
+            R.drawable.vector_icon_settings_golden,
+            R.drawable.vector_icon_random_path_1_golden,
+            R.drawable.vector_icon_random_path_2_golden,
+            R.drawable.vector_icon_repeated_cq_golden,
+            R.drawable.vector_icon_repeated_st_golden,
+            R.drawable.vector_icon_repeated_a_1_golden,
+            R.drawable.vector_icon_repeated_a_2_golden,
+            R.drawable.vector_icon_clip_path_1_golden,
+    };
+
+    private static final int[] L_M_ICON_RES_IDS = new int[] {
             R.drawable.vector_icon_transformation_1,
             R.drawable.vector_icon_transformation_2,
             R.drawable.vector_icon_transformation_3,
@@ -70,19 +95,7 @@
             R.drawable.vector_icon_scale_2,
     };
 
-    private int[] mGoldenImages = new int[] {
-            R.drawable.vector_icon_create_golden,
-            R.drawable.vector_icon_delete_golden,
-            R.drawable.vector_icon_heart_golden,
-            R.drawable.vector_icon_schedule_golden,
-            R.drawable.vector_icon_settings_golden,
-            R.drawable.vector_icon_random_path_1_golden,
-            R.drawable.vector_icon_random_path_2_golden,
-            R.drawable.vector_icon_repeated_cq_golden,
-            R.drawable.vector_icon_repeated_st_golden,
-            R.drawable.vector_icon_repeated_a_1_golden,
-            R.drawable.vector_icon_repeated_a_2_golden,
-            R.drawable.vector_icon_clip_path_1_golden,
+    private static final int[] L_M_GOLDEN_IMAGES = new int[] {
             R.drawable.vector_icon_transformation_1_golden,
             R.drawable.vector_icon_transformation_2_golden,
             R.drawable.vector_icon_transformation_3_golden,
@@ -98,19 +111,76 @@
             R.drawable.vector_icon_scale_2_golden,
     };
 
+    private static final int[] N_ICON_RES_IDS = new int[] {
+            R.drawable.vector_icon_implicit_lineto,
+            R.drawable.vector_icon_arcto,
+            R.drawable.vector_icon_filltype_nonzero,
+            R.drawable.vector_icon_filltype_evenodd,
+    };
+
+    private static final int[] N_GOLDEN_IMAGES = new int[] {
+            R.drawable.vector_icon_implicit_lineto_golden,
+            R.drawable.vector_icon_arcto_golden,
+            R.drawable.vector_icon_filltype_nonzero_golden,
+            R.drawable.vector_icon_filltype_evenodd_golden,
+    };
+
+    private static final int[] GRADIENT_ICON_RES_IDS = new int[] {
+            R.drawable.vector_icon_gradient_1,
+            R.drawable.vector_icon_gradient_2,
+            R.drawable.vector_icon_gradient_3,
+            R.drawable.vector_icon_gradient_1_clamp,
+            R.drawable.vector_icon_gradient_2_repeat,
+            R.drawable.vector_icon_gradient_3_mirror,
+    };
+
+    private static final int[] GRADIENT_GOLDEN_IMAGES = new int[] {
+            R.drawable.vector_icon_gradient_1_golden,
+            R.drawable.vector_icon_gradient_2_golden,
+            R.drawable.vector_icon_gradient_3_golden,
+            R.drawable.vector_icon_gradient_1_clamp_golden,
+            R.drawable.vector_icon_gradient_2_repeat_golden,
+            R.drawable.vector_icon_gradient_3_mirror_golden,
+    };
+
+    private static final int[] STATEFUL_RES_IDS = new int[] {
+            // All these icons are using the same color state list, make sure it works for either
+            // the same drawable ID or different ID but same content.
+            R.drawable.vector_icon_state_list,
+            R.drawable.vector_icon_state_list,
+            R.drawable.vector_icon_state_list_2,
+    };
+
+    private static final int[][] STATEFUL_GOLDEN_IMAGES = new int[][] {
+            {
+                    R.drawable.vector_icon_state_list_golden,
+                    R.drawable.vector_icon_state_list_golden,
+                    R.drawable.vector_icon_state_list_2_golden
+            },
+            {
+                    R.drawable.vector_icon_state_list_golden_pressed,
+                    R.drawable.vector_icon_state_list_golden_pressed,
+                    R.drawable.vector_icon_state_list_2_golden_pressed
+            }
+    };
+
+    private static final int[][] STATEFUL_STATE_SETS = new int[][] {
+            {},
+            { android.R.attr.state_pressed }
+    };
+
     private static final int IMAGE_WIDTH = 64;
     private static final int IMAGE_HEIGHT = 64;
     // A small value is actually making sure that the values are matching
     // exactly with the golden image.
     // We can increase the threshold if the Skia is drawing with some variance
     // on different devices. So far, the tests show they are matching correctly.
-    private static final float PIXEL_ERROR_THRESHOLD = 0.02f;
+    private static final float PIXEL_ERROR_THRESHOLD = 0.03f;
     private static final float PIXEL_ERROR_COUNT_THRESHOLD = 0.005f;
 
     private static final boolean DBG_DUMP_PNG = false;
 
     private Resources mResources;
-    private VectorDrawable mVectorDrawable;
     private Bitmap mBitmap;
     private Canvas mCanvas;
 
@@ -122,25 +192,51 @@
 
         mBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
         mCanvas = new Canvas(mBitmap);
-        mVectorDrawable = new VectorDrawable();
-        mVectorDrawable.setBounds(0, 0, width, height);
-
         mResources = mContext.getResources();
     }
 
-    public void testSimpleVectorDrawables() throws Exception {
-        verifyVectorDrawables(mIconResIds, mGoldenImages, 0);
+    @MediumTest
+    public void testBasicVectorDrawables() throws XmlPullParserException, IOException {
+        verifyVectorDrawables(BASIC_ICON_RES_IDS, BASIC_GOLDEN_IMAGES, null);
     }
 
-    private void verifyVectorDrawables(int[] resIds, int[] goldenImages, float fraction) throws Exception {
+    @MediumTest
+    public void testLMVectorDrawables() throws XmlPullParserException, IOException {
+        verifyVectorDrawables(L_M_ICON_RES_IDS, L_M_GOLDEN_IMAGES, null);
+    }
+
+    @MediumTest
+    public void testNVectorDrawables() throws XmlPullParserException, IOException {
+        verifyVectorDrawables(N_ICON_RES_IDS, N_GOLDEN_IMAGES, null);
+    }
+
+    @MediumTest
+    public void testVectorDrawableGradient() throws XmlPullParserException, IOException {
+        verifyVectorDrawables(GRADIENT_ICON_RES_IDS, GRADIENT_GOLDEN_IMAGES, null);
+    }
+
+    @MediumTest
+    public void testColorStateList() throws XmlPullParserException, IOException {
+        for (int i = 0; i < STATEFUL_STATE_SETS.length; i++) {
+            verifyVectorDrawables(
+                    STATEFUL_RES_IDS, STATEFUL_GOLDEN_IMAGES[i], STATEFUL_STATE_SETS[i]);
+        }
+    }
+
+    private void verifyVectorDrawables(int[] resIds, int[] goldenImages, int[] stateSet)
+            throws XmlPullParserException, IOException {
         for (int i = 0; i < resIds.length; i++) {
+            VectorDrawable vectorDrawable = new VectorDrawable();
+            vectorDrawable.setBounds(0, 0, IMAGE_WIDTH, IMAGE_HEIGHT);
+
+
             // Setup VectorDrawable from xml file and draw into the bitmap.
             XmlPullParser parser = mResources.getXml(resIds[i]);
             AttributeSet attrs = Xml.asAttributeSet(parser);
 
             int type;
-            while ((type=parser.next()) != XmlPullParser.START_TAG &&
-                    type != XmlPullParser.END_DOCUMENT) {
+            while ((type=parser.next()) != XmlPullParser.START_TAG
+                    && type != XmlPullParser.END_DOCUMENT) {
                 // Empty loop
             }
 
@@ -148,23 +244,32 @@
                 throw new XmlPullParserException("No start tag found");
             }
 
-            mVectorDrawable.inflate(mResources, parser, attrs);
+            Theme theme = mResources.newTheme();
+            theme.applyStyle(R.style.Theme_ThemedDrawableTest, true);
+            vectorDrawable.inflate(mResources, parser, attrs, theme);
+
+            if (stateSet != null) {
+                vectorDrawable.setState(stateSet);
+            }
 
             mBitmap.eraseColor(0);
-            mVectorDrawable.draw(mCanvas);
+            vectorDrawable.draw(mCanvas);
 
             if (DBG_DUMP_PNG) {
-                saveVectorDrawableIntoPNG(mBitmap, resIds, i);
+                saveVectorDrawableIntoPNG(mBitmap, resIds, i, stateSet);
             } else {
                 // Start to compare
                 Bitmap golden = BitmapFactory.decodeResource(mResources, goldenImages[i]);
-                compareImages(mBitmap, golden, mResources.getString(resIds[i]));
+                DrawableTestUtils.compareImages(mResources.getString(resIds[i]), mBitmap, golden,
+                        VectorDrawableTest.PIXEL_ERROR_THRESHOLD,
+                        VectorDrawableTest.PIXEL_ERROR_COUNT_THRESHOLD);
             }
         }
     }
 
     // This is only for debugging or golden image (re)generation purpose.
-    private void saveVectorDrawableIntoPNG(Bitmap bitmap, int[] resIds, int index) throws IOException {
+    private void saveVectorDrawableIntoPNG(Bitmap bitmap, int[] resIds, int index, int[] stateSet)
+            throws IOException {
         // Save the image to the disk.
         FileOutputStream out = null;
         try {
@@ -177,7 +282,8 @@
             File originalFile = new File(originalFilePath);
             String fileFullName = originalFile.getName();
             String fileTitle = fileFullName.substring(0, fileFullName.lastIndexOf("."));
-            String outputFilename = outputFolder + fileTitle + "_golden.png";
+            String stateSetTitle = getTitleForStateSet(stateSet);
+            String outputFilename = outputFolder + fileTitle + "_golden" + stateSetTitle + ".png";
             File outputFile = new File(outputFilename);
             if (!outputFile.exists()) {
                 outputFile.createNewFile();
@@ -195,41 +301,39 @@
         }
     }
 
-    private void compareImages(Bitmap ideal, Bitmap given, String filename) {
-        int idealWidth = ideal.getWidth();
-        int idealHeight = ideal.getHeight();
+    /**
+     * Generates an underline-delimited list of states in a given state set.
+     * <p>
+     * For example, the array {@code {R.attr.state_pressed}} would return
+     * {@code "_pressed"}.
+     *
+     * @param stateSet a state set
+     * @return a string representing the state set, or the empty string if the
+     *         state set is empty or {@code null}
+     */
+    private String getTitleForStateSet(int[] stateSet) {
+        if (stateSet == null || stateSet.length == 0) {
+            return "";
+        }
 
-        assertTrue(idealWidth == given.getWidth());
-        assertTrue(idealHeight == given.getHeight());
+        final Resources res = getContext().getResources();
+        final StringBuilder builder = new StringBuilder();
+        for (int i = 0; i < stateSet.length; i++) {
+            builder.append('_');
 
-        int totalDiffPixelCount = 0;
-        float totalPixelCount = idealWidth * idealHeight;
-        for (int x = 0; x < idealWidth; x++) {
-            for (int y = 0; y < idealHeight; y++) {
-                int idealColor = ideal.getPixel(x, y);
-                int givenColor = given.getPixel(x, y);
-                if (idealColor == givenColor)
-                    continue;
-
-                float totalError = 0;
-                totalError += Math.abs(Color.red(idealColor) - Color.red(givenColor));
-                totalError += Math.abs(Color.green(idealColor) - Color.green(givenColor));
-                totalError += Math.abs(Color.blue(idealColor) - Color.blue(givenColor));
-                totalError += Math.abs(Color.alpha(idealColor) - Color.alpha(givenColor));
-
-                if ((totalError / 1024.0f) >= PIXEL_ERROR_THRESHOLD) {
-                    fail((filename + ": totalError is " + totalError));
-                }
-
-                totalDiffPixelCount++;
+            final String state = res.getResourceName(stateSet[i]);
+            final int stateIndex = state.indexOf("state_");
+            if (stateIndex >= 0) {
+                builder.append(state.substring(stateIndex + 6));
+            } else {
+                builder.append(stateSet[i]);
             }
         }
-        if ((totalDiffPixelCount / totalPixelCount) >= PIXEL_ERROR_COUNT_THRESHOLD) {
-            fail((filename +": totalDiffPixelCount is " + totalDiffPixelCount));
-        }
 
+        return builder.toString();
     }
 
+    @SmallTest
     public void testGetChangingConfigurations() {
         VectorDrawable vectorDrawable = new VectorDrawable();
         ConstantState constantState = vectorDrawable.getConstantState();
@@ -253,6 +357,7 @@
         assertEquals(0xffff,  vectorDrawable.getChangingConfigurations());
     }
 
+    @SmallTest
     public void testGetConstantState() {
         VectorDrawable vectorDrawable = new VectorDrawable();
         ConstantState constantState = vectorDrawable.getConstantState();
@@ -265,6 +370,7 @@
         assertEquals(1, constantState.getChangingConfigurations());
     }
 
+    @SmallTest
     public void testMutate() {
         Resources resources = mContext.getResources();
         // d1 will be mutated, while d2 / d3 will not.
@@ -292,6 +398,7 @@
         d2.setAlpha(originalAlpha);
     }
 
+    @SmallTest
     public void testColorFilter() {
         PorterDuffColorFilter filter = new PorterDuffColorFilter(Color.RED, Mode.SRC_IN);
         VectorDrawable vectorDrawable = new VectorDrawable();
@@ -299,4 +406,66 @@
 
         assertEquals(filter, vectorDrawable.getColorFilter());
     }
+
+    @SmallTest
+    public void testPreloadDensity() throws XmlPullParserException, IOException {
+        final Resources res = getContext().getResources();
+        final int densityDpi = res.getConfiguration().densityDpi;
+        try {
+            testPreloadDensityInner(res, densityDpi);
+        } finally {
+            DrawableTestUtils.setResourcesDensity(res, densityDpi);
+        }
+    }
+
+    @SmallTest
+    public void testGetOpacity () throws XmlPullParserException, IOException {
+        VectorDrawable vectorDrawable = new VectorDrawable();
+
+        assertEquals("Default alpha should be 255", 255, vectorDrawable.getAlpha());
+        assertEquals("Default opacity should be TRANSLUCENT", PixelFormat.TRANSLUCENT,
+                vectorDrawable.getOpacity());
+
+        vectorDrawable.setAlpha(0);
+        assertEquals("Alpha should be 0 now", 0, vectorDrawable.getAlpha());
+        assertEquals("Opacity should be TRANSPARENT now", PixelFormat.TRANSPARENT,
+                vectorDrawable.getOpacity());
+    }
+
+    private void testPreloadDensityInner(Resources res, int densityDpi)
+            throws XmlPullParserException, IOException {
+        // Capture initial state at default density.
+        final XmlResourceParser parser = DrawableTestUtils.getResourceParser(
+                res, R.drawable.vector_density);
+        final VectorDrawable preloadedDrawable = new VectorDrawable();
+        preloadedDrawable.inflate(mResources, parser, Xml.asAttributeSet(parser));
+        final ConstantState preloadedConstantState = preloadedDrawable.getConstantState();
+        final int origWidth = preloadedDrawable.getIntrinsicWidth();
+
+        // Set density to half of original. Unlike offsets, which are
+        // truncated, dimensions are rounded to the nearest pixel.
+        DrawableTestUtils.setResourcesDensity(res, densityDpi / 2);
+        final VectorDrawable halfDrawable =
+                (VectorDrawable) preloadedConstantState.newDrawable(res);
+        assertEquals(Math.round(origWidth / 2f), halfDrawable.getIntrinsicWidth());
+
+        // Set density to double original.
+        DrawableTestUtils.setResourcesDensity(res, densityDpi * 2);
+        final VectorDrawable doubleDrawable =
+                (VectorDrawable) preloadedConstantState.newDrawable(res);
+        assertEquals(origWidth * 2, doubleDrawable.getIntrinsicWidth());
+
+        // Restore original density.
+        DrawableTestUtils.setResourcesDensity(res, densityDpi);
+        final VectorDrawable origDrawable =
+                (VectorDrawable) preloadedConstantState.newDrawable();
+        assertEquals(origWidth, origDrawable.getIntrinsicWidth());
+
+        // Ensure theme density is applied correctly.
+        final Theme t = res.newTheme();
+        halfDrawable.applyTheme(t);
+        assertEquals(origWidth, halfDrawable.getIntrinsicWidth());
+        doubleDrawable.applyTheme(t);
+        assertEquals(origWidth, doubleDrawable.getIntrinsicWidth());
+    }
 }
diff --git a/tests/tests/graphics/src/android/graphics/drawable/shapes/cts/ArcShapeTest.java b/tests/tests/graphics/src/android/graphics/drawable/shapes/cts/ArcShapeTest.java
index 514d9d9..78db7a9 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/shapes/cts/ArcShapeTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/shapes/cts/ArcShapeTest.java
@@ -16,15 +16,16 @@
 
 package android.graphics.drawable.shapes.cts;
 
+import junit.framework.TestCase;
 
 import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Paint;
 import android.graphics.Bitmap.Config;
+import android.graphics.Canvas;
+import android.graphics.Outline;
+import android.graphics.Paint;
 import android.graphics.Paint.Style;
 import android.graphics.drawable.shapes.ArcShape;
-
-import junit.framework.TestCase;
+import android.test.suitebuilder.annotation.SmallTest;
 
 public class ArcShapeTest extends TestCase {
     private static final int TEST_WIDTH  = 100;
@@ -35,6 +36,7 @@
 
     private static final int TOLERANCE = 4; // tolerance in pixels
 
+    @SmallTest
     public void testConstructor() {
         new ArcShape(1f, 5f);
 
@@ -43,6 +45,7 @@
         new ArcShape(-1f, -1f);
     }
 
+    @SmallTest
     public void testDraw() {
         // draw completely.
         ArcShape arcShape = new ArcShape(0.0f, 360.0f);
@@ -71,4 +74,16 @@
         }
         assertEquals((double)SQUARE / 2 / Math.sqrt(2), count, TOLERANCE);
     }
+
+    @SmallTest
+    public void testGetOutline() {
+        Outline outline = new Outline();
+        ArcShape shape;
+
+        // This is a no-op. Just make sure it doesn't crash.
+        outline.setEmpty();
+        shape = new ArcShape(0.0f, 360.0f);
+        shape.getOutline(outline);
+        assertTrue(outline.isEmpty());
+    }
 }
diff --git a/tests/tests/graphics/src/android/graphics/drawable/shapes/cts/OvalShapeTest.java b/tests/tests/graphics/src/android/graphics/drawable/shapes/cts/OvalShapeTest.java
index dd440df..6ecf37a 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/shapes/cts/OvalShapeTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/shapes/cts/OvalShapeTest.java
@@ -16,15 +16,17 @@
 
 package android.graphics.drawable.shapes.cts;
 
+import junit.framework.TestCase;
 
 import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Paint;
 import android.graphics.Bitmap.Config;
+import android.graphics.Canvas;
+import android.graphics.Outline;
+import android.graphics.Paint;
 import android.graphics.Paint.Style;
+import android.graphics.Rect;
 import android.graphics.drawable.shapes.OvalShape;
-
-import junit.framework.TestCase;
+import android.test.suitebuilder.annotation.SmallTest;
 
 public class OvalShapeTest extends TestCase {
     private static final int TEST_WIDTH  = 100;
@@ -65,4 +67,36 @@
         }
         assertEquals((double)SQUARE / Math.sqrt(2), count, TOLERANCE);
     }
+
+    @SmallTest
+    public void testGetOutline() {
+        Outline outline = new Outline();
+        Rect rect = new Rect();
+        OvalShape shape;
+
+        // Zero-sized oval yields an empty outline.
+        shape = new OvalShape();
+        shape.getOutline(outline);
+        assertTrue(outline.isEmpty());
+        assertTrue(outline.getRadius() < 0);
+        assertFalse(outline.getRect(rect));
+
+        // Non-zero oval yields a rounded rect.
+        shape.resize(100, 100);
+        shape.getOutline(outline);
+        assertFalse(outline.isEmpty());
+        assertEquals(50.0f, outline.getRadius(), 0.01f);
+        assertTrue(outline.getRect(rect));
+        assertEquals(0, rect.left);
+        assertEquals(0, rect.top);
+        assertEquals(100, rect.right);
+        assertEquals(100, rect.bottom);
+
+        // Non-circular oval yields a path.
+        shape.resize(100, 200);
+        shape.getOutline(outline);
+        assertFalse(outline.isEmpty());
+        assertTrue(outline.getRadius() < 0);
+        assertFalse(outline.getRect(rect));
+    }
 }
diff --git a/tests/tests/graphics/src/android/graphics/drawable/shapes/cts/PathShapeTest.java b/tests/tests/graphics/src/android/graphics/drawable/shapes/cts/PathShapeTest.java
index 6da90a6..b833d61 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/shapes/cts/PathShapeTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/shapes/cts/PathShapeTest.java
@@ -16,16 +16,17 @@
 
 package android.graphics.drawable.shapes.cts;
 
+import junit.framework.TestCase;
 
 import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.Path;
 import android.graphics.Bitmap.Config;
+import android.graphics.Canvas;
+import android.graphics.Outline;
+import android.graphics.Paint;
 import android.graphics.Paint.Style;
+import android.graphics.Path;
 import android.graphics.drawable.shapes.PathShape;
-
-import junit.framework.TestCase;
+import android.test.suitebuilder.annotation.SmallTest;
 
 public class PathShapeTest extends TestCase {
     private static final int TEST_COLOR_1 = 0xFF00FF00;
@@ -33,6 +34,7 @@
 
     private static final int TOLERANCE = 4;
 
+    @SmallTest
     public void testConstructor() {
         new PathShape(new Path(), 1f, 5f);
 
@@ -41,6 +43,7 @@
         new PathShape(null, 0f, 0f);
     }
 
+    @SmallTest
     public void testDraw() {
         final int SHAPE_SIZE = 200;
 
@@ -87,6 +90,7 @@
         assertEquals(25, diagonal, TOLERANCE);
     }
 
+    @SmallTest
     public void testClone() throws CloneNotSupportedException {
         PathShape pathShape = new PathShape(new Path(), 1f, 5f);
         pathShape.resize(100f, 200f);
@@ -98,4 +102,16 @@
         assertEquals(pathShape.getWidth(), clonedShape.getWidth());
         assertEquals(pathShape.getHeight(), clonedShape.getHeight());
     }
+
+    @SmallTest
+    public void testGetOutline() {
+        Outline outline = new Outline();
+        PathShape shape;
+
+        // This is a no-op. Just make sure it doesn't crash.
+        outline.setEmpty();
+        shape = new PathShape(new Path(), 0, 0);
+        shape.getOutline(outline);
+        assertTrue(outline.isEmpty());
+    }
 }
diff --git a/tests/tests/graphics/src/android/graphics/drawable/shapes/cts/RectShapeTest.java b/tests/tests/graphics/src/android/graphics/drawable/shapes/cts/RectShapeTest.java
index e76274d..136770b 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/shapes/cts/RectShapeTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/shapes/cts/RectShapeTest.java
@@ -16,16 +16,18 @@
 
 package android.graphics.drawable.shapes.cts;
 
+import junit.framework.TestCase;
 
 import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.RectF;
 import android.graphics.Bitmap.Config;
+import android.graphics.Canvas;
+import android.graphics.Outline;
+import android.graphics.Paint;
 import android.graphics.Paint.Style;
+import android.graphics.Rect;
+import android.graphics.RectF;
 import android.graphics.drawable.shapes.RectShape;
-
-import junit.framework.TestCase;
+import android.test.suitebuilder.annotation.SmallTest;
 
 public class RectShapeTest extends TestCase {
     private static final int TEST_WIDTH  = 100;
@@ -46,6 +48,7 @@
         }
     }
 
+    @SmallTest
     public void testDraw() {
         RectShape rectShape = new RectShape();
         Bitmap bitmap = Bitmap.createBitmap(TEST_WIDTH, TEST_HEIGHT, Config.ARGB_8888);
@@ -63,6 +66,7 @@
         assertDrawSuccessfully(bitmap, TEST_WIDTH, TEST_HEIGHT, TEST_COLOR_2);
     }
 
+    @SmallTest
     public void testClone() throws CloneNotSupportedException {
         RectShape rectShape = new RectShape();
         rectShape.resize(100f, 200f);
@@ -75,22 +79,48 @@
         assertEquals(rectShape.getHeight(), clonedShape.getHeight());
     }
 
+    @SmallTest
     public void testRect() {
-        MyRectShape rectShape = new MyRectShape();
-        RectF rect = rectShape.myRect();
+        MyRectShape mockRectShape = new MyRectShape();
+        RectShape rectShape = mockRectShape;
+        RectF rect = mockRectShape.myRect();
         assertEquals(0.0f, rect.left);
         assertEquals(0.0f, rect.top);
         assertEquals(0.0f, rect.right);
         assertEquals(0.0f, rect.bottom);
 
         rectShape.resize(TEST_WIDTH, TEST_HEIGHT);
-        rect = rectShape.myRect();
+        rect = mockRectShape.myRect();
         assertEquals(0.0f, rect.left);
         assertEquals(0.0f, rect.top);
         assertEquals((float) TEST_WIDTH, rect.right);
         assertEquals((float) TEST_HEIGHT, rect.bottom);
     }
 
+    @SmallTest
+    public void testGetOutline() {
+        Outline outline = new Outline();
+        Rect rect = new Rect();
+        RectShape shape = new RectShape();
+
+        // Zero-size rect is empty.
+        shape.getOutline(outline);
+        assertTrue(outline.isEmpty());
+        assertTrue(outline.getRadius() < 0);
+        assertFalse(outline.getRect(rect));
+
+        // Non-zero rect is a rect.
+        shape.resize(100, 100);
+        shape.getOutline(outline);
+        assertFalse(outline.isEmpty());
+        assertEquals(0.0f, outline.getRadius());
+        assertTrue(outline.getRect(rect));
+        assertEquals(0, rect.left);
+        assertEquals(0, rect.top);
+        assertEquals(100, rect.right);
+        assertEquals(100, rect.bottom);
+    }
+
     private static class MyRectShape extends RectShape {
         public RectF myRect() {
             return super.rect();
diff --git a/tests/tests/graphics/src/android/graphics/drawable/shapes/cts/RoundRectShapeTest.java b/tests/tests/graphics/src/android/graphics/drawable/shapes/cts/RoundRectShapeTest.java
index 7b5ac3a..5209535 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/shapes/cts/RoundRectShapeTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/shapes/cts/RoundRectShapeTest.java
@@ -16,16 +16,18 @@
 
 package android.graphics.drawable.shapes.cts;
 
+import junit.framework.TestCase;
 
 import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.RectF;
 import android.graphics.Bitmap.Config;
+import android.graphics.Canvas;
+import android.graphics.Outline;
+import android.graphics.Paint;
 import android.graphics.Paint.Style;
+import android.graphics.Rect;
+import android.graphics.RectF;
 import android.graphics.drawable.shapes.RoundRectShape;
-
-import junit.framework.TestCase;
+import android.test.suitebuilder.annotation.SmallTest;
 
 public class RoundRectShapeTest extends TestCase {
     private static final int TEST_WIDTH  = 100;
@@ -91,4 +93,64 @@
         assertEquals(roundRectShape.getWidth(), clonedShape.getWidth());
         assertEquals(roundRectShape.getHeight(), clonedShape.getHeight());
     }
+
+    @SmallTest
+    public void testGetOutline() {
+        Outline outline = new Outline();
+        Rect rect = new Rect();
+        RoundRectShape shape;
+
+        // All null.
+        shape = new RoundRectShape(null, null, null);
+        shape.getOutline(outline);
+        assertTrue(outline.isEmpty());
+        assertTrue(outline.getRadius() < 0);
+        assertFalse(outline.getRect(rect));
+
+        shape.resize(100, 100);
+        shape.getOutline(outline);
+        assertFalse(outline.isEmpty());
+        assertEquals(0.0f, outline.getRadius());
+        assertTrue(outline.getRect(rect));
+        assertEquals(0, rect.left);
+        assertEquals(0, rect.top);
+        assertEquals(100, rect.right);
+        assertEquals(100, rect.bottom);
+
+        // Consistent outer radius gives a rounded rect outline.
+        shape = new RoundRectShape(new float[] { 10, 10, 10, 10, 10, 10, 10, 10 }, null, null);
+        shape.getOutline(outline);
+        assertTrue(outline.isEmpty());
+        assertTrue(outline.getRadius() < 0);
+        assertFalse(outline.getRect(rect));
+
+        shape.resize(100, 100);
+        shape.getOutline(outline);
+        assertFalse(outline.isEmpty());
+        assertEquals(10.0f, outline.getRadius(), 0.01f);
+        assertTrue(outline.getRect(rect));
+        assertEquals(0, rect.left);
+        assertEquals(0, rect.top);
+        assertEquals(100, rect.right);
+        assertEquals(100, rect.bottom);
+
+        // Inconsistent outer radius gives a path outline.
+        shape = new RoundRectShape(new float[] { 10, 10, 0, 0, 0, 0, 0, 0 }, null, null);
+        shape.getOutline(outline);
+        assertTrue(outline.isEmpty());
+        assertTrue(outline.getRadius() < 0);
+        assertFalse(outline.getRect(rect));
+
+        shape.resize(100, 100);
+        shape.getOutline(outline);
+        assertFalse(outline.isEmpty());
+        assertTrue(outline.getRadius() < 0);
+        assertFalse(outline.getRect(rect));
+
+        // Inset can't produce a valid outline, so the resulting behavior is
+        // undefined. Just verify that it doesn't crash.
+        shape = new RoundRectShape(new float[] { 10, 10, 0, 0, 0, 0, 0, 0 },
+                new RectF(100, 100, 100, 100), new float[] { 10, 10, 0, 0, 0, 0, 0, 0 });
+        shape.getOutline(outline);
+    }
 }
diff --git a/tests/tests/graphics/src/android/graphics/drawable/shapes/cts/ShapeTest.java b/tests/tests/graphics/src/android/graphics/drawable/shapes/cts/ShapeTest.java
index d54a698..7f0e1e0 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/shapes/cts/ShapeTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/shapes/cts/ShapeTest.java
@@ -16,17 +16,16 @@
 
 package android.graphics.drawable.shapes.cts;
 
+import junit.framework.TestCase;
 
 import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.RectF;
 import android.graphics.Bitmap.Config;
+import android.graphics.Canvas;
+import android.graphics.Outline;
+import android.graphics.Paint;
 import android.graphics.Paint.Style;
-import android.graphics.drawable.shapes.RoundRectShape;
 import android.graphics.drawable.shapes.Shape;
-
-import junit.framework.TestCase;
+import android.test.suitebuilder.annotation.SmallTest;
 
 public class ShapeTest extends TestCase {
     private static final int TEST_WIDTH  = 100;
@@ -35,6 +34,7 @@
     private static final int TEST_COLOR_1 = 0xFF00FF00;
     private static final int TEST_COLOR_2 = 0xFFFF0000;
 
+    @SmallTest
     public void testSize() {
         MockShape mockShape = new MockShape();
         assertFalse(mockShape.hasCalledOnResize());
@@ -57,6 +57,7 @@
         assertEquals(0f, mockShape.getHeight());
     }
 
+    @SmallTest
     public void testOnResize() {
         MockShape mockShape = new MockShape();
         assertFalse(mockShape.hasCalledOnResize());
@@ -75,6 +76,7 @@
         assertTrue(mockShape.hasCalledOnResize());
     }
 
+    @SmallTest
     public void testClone() throws CloneNotSupportedException {
         Shape shape = new MockShape();
         shape.resize(100f, 200f);
@@ -87,11 +89,13 @@
         assertEquals(shape.getHeight(), clonedShape.getHeight());
     }
 
+    @SmallTest
     public void testHasAlpha() {
         Shape shape = new MockShape();
         assertTrue(shape.hasAlpha());
     }
 
+    @SmallTest
     public void testDraw() {
         Shape shape = new MockShape();
         Bitmap bitmap = Bitmap.createBitmap(TEST_WIDTH, TEST_HEIGHT, Config.ARGB_8888);
@@ -109,6 +113,15 @@
         assertEquals(0, bitmap.getPixel(0, 0));
     }
 
+    @SmallTest
+    public void testGetOutline() {
+        Shape shape = new MockShape();
+        Outline outline = new Outline();
+
+        // This is a no-op. Just make sure it doesn't crash.
+        shape.getOutline(outline);
+    }
+
     private static class MockShape extends Shape {
         private boolean mCalledOnResize = false;
 
diff --git a/tests/tests/graphics/src/android/opengl/cts/CompressedTextureCtsActivity.java b/tests/tests/graphics/src/android/opengl/cts/CompressedTextureCtsActivity.java
index 533508a..bade5a8 100644
--- a/tests/tests/graphics/src/android/opengl/cts/CompressedTextureCtsActivity.java
+++ b/tests/tests/graphics/src/android/opengl/cts/CompressedTextureCtsActivity.java
@@ -15,7 +15,7 @@
  */
 package android.opengl.cts;
 
-import com.android.cts.graphics.R;
+import android.graphics.cts.R;
 
 import android.app.Activity;
 import android.content.Intent;
diff --git a/tests/tests/graphics/src/android/opengl/cts/CompressedTextureLoader.java b/tests/tests/graphics/src/android/opengl/cts/CompressedTextureLoader.java
index 1524f99..3a2e00f 100644
--- a/tests/tests/graphics/src/android/opengl/cts/CompressedTextureLoader.java
+++ b/tests/tests/graphics/src/android/opengl/cts/CompressedTextureLoader.java
@@ -21,7 +21,7 @@
 import java.nio.ByteOrder;
 import java.util.HashMap;
 
-import com.android.cts.graphics.R;
+import android.graphics.cts.R;
 
 import android.app.Activity;
 import android.content.res.AssetFileDescriptor;
diff --git a/tests/tests/graphics/src/android/opengl/cts/CompressedTextureSurfaceView.java b/tests/tests/graphics/src/android/opengl/cts/CompressedTextureSurfaceView.java
index 84aae10..9437c58 100644
--- a/tests/tests/graphics/src/android/opengl/cts/CompressedTextureSurfaceView.java
+++ b/tests/tests/graphics/src/android/opengl/cts/CompressedTextureSurfaceView.java
@@ -27,7 +27,7 @@
 import javax.microedition.khronos.egl.EGLConfig;
 import javax.microedition.khronos.opengles.GL10;
 
-import com.android.cts.graphics.R;
+import android.graphics.cts.R;
 
 import android.content.Context;
 import android.content.res.Resources;
diff --git a/tests/tests/graphics/src/android/opengl/cts/CompressedTextureTest.java b/tests/tests/graphics/src/android/opengl/cts/CompressedTextureTest.java
index c153712..09902df 100644
--- a/tests/tests/graphics/src/android/opengl/cts/CompressedTextureTest.java
+++ b/tests/tests/graphics/src/android/opengl/cts/CompressedTextureTest.java
@@ -24,13 +24,13 @@
 public class CompressedTextureTest extends ActivityInstrumentationTestCase2<CompressedTextureCtsActivity> {
 
     public CompressedTextureTest() {
-        super("com.android.cts.graphics", CompressedTextureCtsActivity.class);
+        super("android.graphics.cts", CompressedTextureCtsActivity.class);
     }
 
     private void launchTest(String format) throws Exception {
         Bundle extras = new Bundle();
         extras.putString("TextureFormat", format);
-        CompressedTextureCtsActivity activity = launchActivity("com.android.cts.graphics",
+        CompressedTextureCtsActivity activity = launchActivity("android.graphics.cts",
                 CompressedTextureCtsActivity.class, extras);
         activity.finish();
         assertTrue(activity.getPassed());
diff --git a/tests/tests/graphics/src/android/opengl/cts/EglConfigTest.java b/tests/tests/graphics/src/android/opengl/cts/EglConfigTest.java
index 14c8e10..33e82043 100644
--- a/tests/tests/graphics/src/android/opengl/cts/EglConfigTest.java
+++ b/tests/tests/graphics/src/android/opengl/cts/EglConfigTest.java
@@ -37,7 +37,7 @@
     private Instrumentation mInstrumentation;
 
     public EglConfigTest() {
-        super("com.android.cts.graphics", EglConfigCtsActivity.class);
+        super("android.graphics.cts", EglConfigCtsActivity.class);
     }
 
     @Override
@@ -60,7 +60,7 @@
             Bundle extras = new Bundle();
             extras.putInt(EglConfigCtsActivity.CONFIG_ID_EXTRA, configId);
             extras.putInt(EglConfigCtsActivity.CONTEXT_CLIENT_VERSION_EXTRA, contextClientVersion);
-            EglConfigCtsActivity activity = launchActivity("com.android.cts.graphics",
+            EglConfigCtsActivity activity = launchActivity("android.graphics.cts",
                     EglConfigCtsActivity.class, extras);
             activity.waitToFinishDrawing();
             activity.finish();
diff --git a/tests/tests/graphics/src/android/opengl/cts/GLSurfaceViewTest.java b/tests/tests/graphics/src/android/opengl/cts/GLSurfaceViewTest.java
index 87995fb..f603419 100644
--- a/tests/tests/graphics/src/android/opengl/cts/GLSurfaceViewTest.java
+++ b/tests/tests/graphics/src/android/opengl/cts/GLSurfaceViewTest.java
@@ -41,7 +41,7 @@
     private GLSurfaceViewCtsActivity mActivity;
 
     public GLSurfaceViewTest() {
-        super("com.android.cts.graphics", GLSurfaceViewCtsActivity.class);
+        super("android.graphics.cts", GLSurfaceViewCtsActivity.class);
     }
 
     @Override
diff --git a/tests/tests/graphics/src/android/opengl/cts/OpenGlEsVersionTest.java b/tests/tests/graphics/src/android/opengl/cts/OpenGlEsVersionTest.java
index 28ac5c0..dd3b787 100644
--- a/tests/tests/graphics/src/android/opengl/cts/OpenGlEsVersionTest.java
+++ b/tests/tests/graphics/src/android/opengl/cts/OpenGlEsVersionTest.java
@@ -48,7 +48,7 @@
     private OpenGlEsVersionCtsActivity mActivity;
 
     public OpenGlEsVersionTest() {
-        super("com.android.cts.graphics", OpenGlEsVersionCtsActivity.class);
+        super("android.graphics.cts", OpenGlEsVersionCtsActivity.class);
     }
 
     @Override
@@ -135,6 +135,57 @@
                 mActivity.getAepEs31Support());
     }
 
+    public void testOpenGlEsVersionForVrHighPerformance() throws InterruptedException {
+        if (!supportsVrHighPerformance())
+            return;
+        restartActivityWithClientVersion(3);
+
+        int reportedVersion = getVersionFromActivityManager(mActivity);
+        int major = getMajorVersion(reportedVersion);
+        int minor = getMinorVersion(reportedVersion);
+
+        assertTrue("OpenGL ES version 3.2 or higher is required for VR high-performance devices " +
+            " but this device supports only version " + major + "." + minor,
+            (major == 3 && minor >= 2) || major > 3);
+    }
+
+    public void testRequiredExtensionsForVrHighPerformance() throws InterruptedException {
+        if (!supportsVrHighPerformance())
+            return;
+        restartActivityWithClientVersion(3);
+
+        String extensions = mActivity.getExtensionsString();
+        final String requiredList[] = {
+            "EXT_protected_textures",
+            "EXT_multisampled_render_to_texture",
+            "OVR_multiview",
+            "OVR_multiview_multisampled_render_to_texture",
+            "OVR_multiview2",
+        };
+
+        for (int i = 0; i < requiredList.length; ++i) {
+            assertTrue("Required extension for VR high-performance is missing: " + requiredList[i],
+                    hasExtension(extensions, requiredList[i]));
+        }
+
+        EGL10 egl = (EGL10) EGLContext.getEGL();
+        EGLDisplay display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
+        extensions = egl.eglQueryString(display, EGL10.EGL_EXTENSIONS);
+        final String requiredEglList[] = {
+            "EGL_ANDROID_create_native_client_buffer",
+            "EGL_ANDROID_front_buffer_auto_refresh",
+            "EGL_EXT_protected_content",
+            "EGL_KHR_mutable_render_buffer",
+            "EGL_KHR_reusable_sync",
+            "EGL_KHR_wait_sync",
+        };
+
+        for (int i = 0; i < requiredList.length; ++i) {
+            assertTrue("Required EGL extension for VR high-performance is missing: " +
+                requiredEglList[i], hasExtension(extensions, requiredEglList[i]));
+        }
+    }
+
     private static boolean hasExtension(String extensions, String name) {
         return OpenGlEsVersionCtsActivity.hasExtension(extensions, name);
     }
@@ -264,4 +315,13 @@
             setActivityIntent(null);
         }
     }
+
+    /**
+     * Return whether the system supports FEATURE_VR_MODE and
+     * FEATURE_VR_MODE_HIGH_PERFORMANCE. This is used to skip some tests.
+     */
+    private boolean supportsVrHighPerformance() {
+        PackageManager pm = mActivity.getPackageManager();
+        return pm.hasSystemFeature(PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE);
+    }
 }
diff --git a/tests/tests/graphics2/Android.mk b/tests/tests/graphics2/Android.mk
index a3cdafa..daf3713 100644
--- a/tests/tests/graphics2/Android.mk
+++ b/tests/tests/graphics2/Android.mk
@@ -27,6 +27,9 @@
 
 LOCAL_PACKAGE_NAME := CtsGraphics2TestCases
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_INSTRUMENTATION_FOR :=
 
 LOCAL_SDK_VERSION := current
diff --git a/tests/tests/graphics2/AndroidManifest.xml b/tests/tests/graphics2/AndroidManifest.xml
index 67557ad..be7a985 100644
--- a/tests/tests/graphics2/AndroidManifest.xml
+++ b/tests/tests/graphics2/AndroidManifest.xml
@@ -14,7 +14,7 @@
      limitations under the License.
 -->
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.graphics2"
+    package="android.graphics2.cts"
     android:versionCode="1"
     android:versionName="1.0" >
 
@@ -23,7 +23,7 @@
     <uses-feature android:name="android.hardware.camera" />
 
     <instrumentation
-        android:targetPackage="com.android.cts.graphics2"
+        android:targetPackage="android.graphics2.cts"
         android:name="android.support.test.runner.AndroidJUnitRunner" >
         <meta-data android:name="listener"
             android:value="com.android.cts.runner.CtsTestRunListener" />
diff --git a/tests/tests/graphics2/AndroidTest.xml b/tests/tests/graphics2/AndroidTest.xml
new file mode 100644
index 0000000..2f9961b
--- /dev/null
+++ b/tests/tests/graphics2/AndroidTest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS Graphics test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsGraphics2TestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.graphics2.cts" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/tests/hardware/Android.mk b/tests/tests/hardware/Android.mk
index 07d5de9..a59c5f4 100644
--- a/tests/tests/hardware/Android.mk
+++ b/tests/tests/hardware/Android.mk
@@ -22,7 +22,10 @@
 
 LOCAL_MODULE_TAGS := tests
 
-LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
+    ctsdeviceutil compatibility-device-util platform-test-annotations
 
 LOCAL_SDK_VERSION := current
 
@@ -36,8 +39,6 @@
     src/android/hardware/cts/SensorTest.java \
     src/android/hardware/cts/SensorManagerStaticTest.java
 
-LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil
-
 include $(BUILD_STATIC_JAVA_LIBRARY)
 
 
@@ -47,16 +48,27 @@
 
 LOCAL_MODULE_TAGS := tests
 
-LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctstestrunner mockito-target android-ex-camera2
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
+    ctsdeviceutil \
+    compatibility-device-util \
+    ctstestrunner \
+    mockito-target \
+    android-ex-camera2 \
+    platform-test-annotations
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-renderscript-files-under, src)
 
 LOCAL_PACKAGE_NAME := CtsHardwareTestCases
 
+LOCAL_CTS_MODULE_CONFIG := $(LOCAL_PATH)/Old$(CTS_MODULE_TEST_CONFIG)
+
 LOCAL_SDK_VERSION := current
 
 LOCAL_JAVA_LIBRARIES := android.test.runner
 
-cts_runtime_hint := 120
-
 include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/hardware/AndroidManifest.xml b/tests/tests/hardware/AndroidManifest.xml
index 031b19e..1e4cedf 100644
--- a/tests/tests/hardware/AndroidManifest.xml
+++ b/tests/tests/hardware/AndroidManifest.xml
@@ -16,7 +16,7 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.hardware">
+    package="android.hardware.cts">
 
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <uses-permission android:name="android.permission.CAMERA" />
@@ -72,6 +72,9 @@
             android:process=":camera2ActivityProcess">
         </activity>
 
+        <activity android:name="android.hardware.input.cts.InputCtsActivity"
+            android:label="InputCtsActivity" />
+
         <activity android:name="android.hardware.cts.FingerprintTestActivity"
             android:label="FingerprintTestActivity">
         </activity>
@@ -79,8 +82,8 @@
     </application>
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.cts.hardware"
-                     android:label="CTS tests of android.hardware">
+                     android:targetPackage="android.hardware.cts"
+                     android:label="CTS hardware tests">
         <meta-data android:name="listener"
             android:value="com.android.cts.runner.CtsTestRunListener" />
     </instrumentation>
diff --git a/tests/tests/hardware/AndroidTest.xml b/tests/tests/hardware/AndroidTest.xml
index 4ddf28c..68131d1 100644
--- a/tests/tests/hardware/AndroidTest.xml
+++ b/tests/tests/hardware/AndroidTest.xml
@@ -1,4 +1,3 @@
-<?xml version="1.0" encoding="utf-8"?>
 <!-- Copyright (C) 2015 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
@@ -13,10 +12,21 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<configuration description="Base config for Sensor CTS tests. Put SensorService in restricted mode">
-    <include name="common-config" />
+<configuration description="Config for CTS Hardware test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.LocationCheck" />
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsHardwareTestCases.apk" />
+    </target_preparer>
     <!-- Put SensorService in restricted mode so that only CTS tests will be able to get access to
     sensors -->
-    <option name="run-command:run-command" value="dumpsys sensorservice restrict .cts." />
-    <option name="run-command:teardown-command" value="dumpsys sensorservice enable" />
+    <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+        <option name="run-command" value="dumpsys sensorservice restrict .cts." />
+        <option name="teardown-command" value="dumpsys sensorservice enable" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.hardware.cts" />
+        <option name="runtime-hint" value="47m28s" />
+    </test>
+
 </configuration>
diff --git a/tests/tests/hardware/OldAndroidTest.xml b/tests/tests/hardware/OldAndroidTest.xml
new file mode 100644
index 0000000..4ddf28c
--- /dev/null
+++ b/tests/tests/hardware/OldAndroidTest.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Base config for Sensor CTS tests. Put SensorService in restricted mode">
+    <include name="common-config" />
+    <!-- Put SensorService in restricted mode so that only CTS tests will be able to get access to
+    sensors -->
+    <option name="run-command:run-command" value="dumpsys sensorservice restrict .cts." />
+    <option name="run-command:teardown-command" value="dumpsys sensorservice enable" />
+</configuration>
diff --git a/tests/tests/hardware/res/raw/gamepad_press_a.json b/tests/tests/hardware/res/raw/gamepad_press_a.json
new file mode 100644
index 0000000..ff3ca4f
--- /dev/null
+++ b/tests/tests/hardware/res/raw/gamepad_press_a.json
@@ -0,0 +1,39 @@
+{
+    "id": 1,
+    "command": "register",
+    "name": "Odie (Test)",
+    "vid": 0x18d1,
+    "pid": 0x2c40,
+    "descriptor": [0x05, 0x01, 0x09, 0x05, 0xa1, 0x01, 0x85, 0x01, 0x05, 0x09, 0x0a, 0x01, 0x00,
+        0x0a, 0x02, 0x00, 0x0a, 0x04, 0x00, 0x0a, 0x05, 0x00, 0x0a, 0x07, 0x00, 0x0a, 0x08, 0x00,
+        0x0a, 0x0e, 0x00, 0x0a, 0x0f, 0x00, 0x0a, 0x0d, 0x00, 0x05, 0x0c, 0x0a, 0x24, 0x02, 0x0a,
+        0x23, 0x02, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x0b, 0x81, 0x02, 0x75, 0x01, 0x95,
+        0x01, 0x81, 0x03, 0x05, 0x01, 0x75, 0x04, 0x95, 0x01, 0x25, 0x07, 0x46, 0x3b, 0x01, 0x66,
+        0x14, 0x00, 0x09, 0x39, 0x81, 0x42, 0x66, 0x00, 0x00, 0x09, 0x01, 0xa1, 0x00, 0x09, 0x30,
+        0x09, 0x31, 0x09, 0x32, 0x09, 0x35, 0x05, 0x02, 0x09, 0xc5, 0x09, 0xc4, 0x15, 0x00, 0x26,
+        0xff, 0x00, 0x35, 0x00, 0x46, 0xff, 0x00, 0x75, 0x08, 0x95, 0x06, 0x81, 0x02, 0xc0, 0x85,
+        0x02, 0x05, 0x08, 0x0a, 0x01, 0x00, 0x0a, 0x02, 0x00, 0x0a, 0x03, 0x00, 0x0a, 0x04, 0x00,
+        0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x04, 0x91, 0x02, 0x75, 0x04, 0x95, 0x01, 0x91,
+        0x03, 0xc0, 0x05, 0x0c, 0x09, 0x01, 0xa1, 0x01, 0x85, 0x03, 0x05, 0x01, 0x09, 0x06, 0xa1,
+        0x02, 0x05, 0x06, 0x09, 0x20, 0x15, 0x00, 0x26, 0xff, 0x00, 0x75, 0x08, 0x95, 0x01, 0x81,
+        0x02, 0x06, 0xbc, 0xff, 0x0a, 0xad, 0xbd, 0x75, 0x08, 0x95, 0x06, 0x81, 0x02, 0xc0, 0xc0],
+    "report": [0x01, 0x00, 0x80, 0x90, 0x80, 0x7f, 0x73, 0x00, 0x00]
+}
+
+{
+    "id": 1,
+    "command": "report",
+    "report": [0x01, 0x01, 0x80, 0x90, 0x80, 0x7f, 0x73, 0x00, 0x00]
+}
+
+{
+    "id": 1,
+    "command": "delay",
+    "duration": 10
+}
+
+{
+    "id": 1,
+    "command": "report",
+    "report": [0x01, 0x00, 0x80, 0x90, 0x80, 0x7f, 0x73, 0x00, 0x00]
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/GeomagneticFieldTest.java b/tests/tests/hardware/src/android/hardware/cts/GeomagneticFieldTest.java
index dc927b6..75d7b7c 100644
--- a/tests/tests/hardware/src/android/hardware/cts/GeomagneticFieldTest.java
+++ b/tests/tests/hardware/src/android/hardware/cts/GeomagneticFieldTest.java
@@ -16,8 +16,8 @@
 
 package android.hardware.cts;
 
-
 import android.hardware.GeomagneticField;
+import android.platform.test.annotations.Presubmit;
 import android.test.AndroidTestCase;
 
 import java.util.GregorianCalendar;
@@ -29,6 +29,7 @@
     private static final float ALTITUDE_OF_CHENGDU = 500f;
     private static final long TEST_TIME = new GregorianCalendar(2010, 5, 1).getTimeInMillis();
 
+    @Presubmit
     public void testGeomagneticField() {
         GeomagneticField geomagneticField = new GeomagneticField(LATITUDE_OF_CHENGDU,
                 LONGITUDE_OF_CHENGDU, ALTITUDE_OF_CHENGDU, TEST_TIME);
diff --git a/tests/tests/hardware/src/android/hardware/cts/SensorBatchingFifoTest.java b/tests/tests/hardware/src/android/hardware/cts/SensorBatchingFifoTest.java
index c5607a0..1db2d51 100644
--- a/tests/tests/hardware/src/android/hardware/cts/SensorBatchingFifoTest.java
+++ b/tests/tests/hardware/src/android/hardware/cts/SensorBatchingFifoTest.java
@@ -24,6 +24,7 @@
 import android.hardware.cts.helpers.TestSensorEnvironment;
 import android.hardware.cts.helpers.sensoroperations.TestSensorOperation;
 import android.hardware.cts.helpers.sensorverification.FifoLengthVerification;
+import android.platform.test.annotations.Presubmit;
 
 import java.util.concurrent.TimeUnit;
 
@@ -34,13 +35,6 @@
  *
  */
 public class SensorBatchingFifoTest extends SensorTestCase {
-    private static final int ACCELEROMETER_MIN_FIFO_LENGTH = 3000;
-    private static final int UNCAL_MAGNETOMETER_MIN_FIFO_LENGTH = 600;
-    private static final int PRESSURE_MIN_FIFO_LENGTH = 300;
-    private static final int GAME_ROTATION_VECTOR_MIN_FIFO_LENGTH = 300;
-    private static final int PROXIMITY_SENSOR_MIN_FIFO_LENGTH = 300;
-    private static final int STEP_DETECTOR_MIN_FIFO_LENGTH = 100;
-
     private static final int SAMPLING_INTERVAL = 1000; /* every 1ms */
     private static final String TAG = "batching_fifo_test";
 
@@ -53,58 +47,39 @@
                 PackageManager.FEATURE_HIFI_SENSORS);
     }
 
+    @Presubmit
     public void testAccelerometerFifoLength() throws Throwable {
         if (!mHasHifiSensors) return;
         runBatchingSensorFifoTest(
                 Sensor.TYPE_ACCELEROMETER,
-                checkMinFifoLength(Sensor.TYPE_ACCELEROMETER, ACCELEROMETER_MIN_FIFO_LENGTH));
+                getReservedFifoLength(Sensor.TYPE_ACCELEROMETER));
     }
 
     public void testUncalMagnetometerFifoLength() throws Throwable {
         if (!mHasHifiSensors) return;
         runBatchingSensorFifoTest(
                 Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED,
-                checkMinFifoLength(
-                        Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED,
-                        UNCAL_MAGNETOMETER_MIN_FIFO_LENGTH));
+                getReservedFifoLength(Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED));
     }
 
     public void testPressureFifoLength() throws Throwable {
         if (!mHasHifiSensors) return;
         runBatchingSensorFifoTest(
                 Sensor.TYPE_PRESSURE,
-                checkMinFifoLength(Sensor.TYPE_PRESSURE, PRESSURE_MIN_FIFO_LENGTH));
+                getReservedFifoLength(Sensor.TYPE_PRESSURE));
     }
 
     public void testGameRotationVectorFifoLength() throws Throwable {
         if (!mHasHifiSensors) return;
         runBatchingSensorFifoTest(
                 Sensor.TYPE_GAME_ROTATION_VECTOR,
-                checkMinFifoLength(
-                        Sensor.TYPE_GAME_ROTATION_VECTOR, GAME_ROTATION_VECTOR_MIN_FIFO_LENGTH));
+                getReservedFifoLength(Sensor.TYPE_GAME_ROTATION_VECTOR));
     }
 
-    public void testProximityFifoLength() throws Throwable {
-        if (!mHasHifiSensors) return;
-        Sensor sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
-        if (sensor != null) {
-            assertTrue(sensor.getFifoReservedEventCount() <= PROXIMITY_SENSOR_MIN_FIFO_LENGTH);
-        }
-    }
-
-    public void testStepDetectorFifoLength() throws Throwable {
-        if (!mHasHifiSensors) return;
-        checkMinFifoLength(Sensor.TYPE_STEP_DETECTOR, STEP_DETECTOR_MIN_FIFO_LENGTH);
-    }
-
-    private int checkMinFifoLength(int sensorType, int minRequiredLength) {
+    private int getReservedFifoLength(int sensorType) {
         Sensor sensor = mSensorManager.getDefaultSensor(sensorType);
         assertTrue(String.format("sensor of type=%d (null)", sensorType), sensor != null);
-        int maxFifoLength = sensor.getFifoReservedEventCount();
-        assertTrue(String.format("Sensor=%s, min required fifo length=%d actual=%d",
-                    sensor.getName(), minRequiredLength, maxFifoLength),
-                    maxFifoLength >= minRequiredLength);
-        return maxFifoLength;
+        return sensor.getFifoReservedEventCount();
     }
 
     private void runBatchingSensorFifoTest(int sensorType, int fifoLength) throws Throwable {
diff --git a/tests/tests/hardware/src/android/hardware/cts/SensorBatchingTests.java b/tests/tests/hardware/src/android/hardware/cts/SensorBatchingTests.java
index 4d4f3d3..2a4c720 100644
--- a/tests/tests/hardware/src/android/hardware/cts/SensorBatchingTests.java
+++ b/tests/tests/hardware/src/android/hardware/cts/SensorBatchingTests.java
@@ -39,7 +39,7 @@
  * <p>To execute these test cases, the following command can be used:</p>
  * <pre>
  * adb shell am instrument -e class android.hardware.cts.SensorBatchingTests \
- *     -w com.android.cts.hardware/android.test.AndroidJUnitRunner
+ *     -w android.hardware.cts/android.test.AndroidJUnitRunner
  * </pre>
  */
 public class SensorBatchingTests extends SensorTestCase {
diff --git a/tests/tests/hardware/src/android/hardware/cts/SensorIntegrationTests.java b/tests/tests/hardware/src/android/hardware/cts/SensorIntegrationTests.java
index 1399cee..bcd1734 100644
--- a/tests/tests/hardware/src/android/hardware/cts/SensorIntegrationTests.java
+++ b/tests/tests/hardware/src/android/hardware/cts/SensorIntegrationTests.java
@@ -34,7 +34,7 @@
  *
  * To execute these test cases, the following command can be used:
  *      $ adb shell am instrument -e class android.hardware.cts.SensorIntegrationTests \
- *          -w com.android.cts.hardware/android.test.InstrumentationCtsTestRunner
+ *          -w android.hardware.cts/android.test.InstrumentationCtsTestRunner
  */
 public class SensorIntegrationTests extends SensorTestCase {
     private static final String TAG = "SensorIntegrationTests";
diff --git a/tests/tests/hardware/src/android/hardware/cts/SensorParameterRangeTest.java b/tests/tests/hardware/src/android/hardware/cts/SensorParameterRangeTest.java
index 22f092a..49b2926 100644
--- a/tests/tests/hardware/src/android/hardware/cts/SensorParameterRangeTest.java
+++ b/tests/tests/hardware/src/android/hardware/cts/SensorParameterRangeTest.java
@@ -30,7 +30,7 @@
  * <p>To execute these test cases, the following command can be used:</p>
  * <pre>
  * adb shell am instrument -e class android.hardware.cts.SensorParameterRangeTest \
- *     -w com.android.cts.hardware/android.test.AndroidJUnitRunner
+ *     -w android.hardware.cts/android.test.AndroidJUnitRunner
  * </pre>
  */
 public class SensorParameterRangeTest extends SensorTestCase {
@@ -51,6 +51,15 @@
     private static final double PRESSURE_MIN_FREQUENCY = 1.0;
     private static final double PRESSURE_MAX_FREQUENCY = 10.0;
 
+    // Note these FIFO minimum constants come from the CCD.  In version
+    // 6.0 of the CCD, these are in section 7.3.9.
+    private static final int ACCELEROMETER_MIN_FIFO_LENGTH = 3000;
+    private static final int UNCAL_MAGNETOMETER_MIN_FIFO_LENGTH = 600;
+    private static final int PRESSURE_MIN_FIFO_LENGTH = 300;
+    private static final int GAME_ROTATION_VECTOR_MIN_FIFO_LENGTH = 300;
+    private static final int PROXIMITY_SENSOR_MIN_FIFO_LENGTH = 100;
+    private static final int STEP_DETECTOR_MIN_FIFO_LENGTH = 100;
+
     private boolean mHasHifiSensors;
     private SensorManager mSensorManager;
 
@@ -112,4 +121,45 @@
                     sensor.getName(), actualMaxFrequency, maxFrequency), actualMaxFrequency >=
                 maxFrequency - 0.1);
     }
+
+    public void testAccelerometerFifoLength() throws Throwable {
+        if (!mHasHifiSensors) return;
+        checkMinFifoLength(Sensor.TYPE_ACCELEROMETER, ACCELEROMETER_MIN_FIFO_LENGTH);
+    }
+
+    public void testUncalMagnetometerFifoLength() throws Throwable {
+        if (!mHasHifiSensors) return;
+        checkMinFifoLength(
+                Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED,
+                UNCAL_MAGNETOMETER_MIN_FIFO_LENGTH);
+    }
+
+    public void testPressureFifoLength() throws Throwable {
+        if (!mHasHifiSensors) return;
+        checkMinFifoLength(Sensor.TYPE_PRESSURE, PRESSURE_MIN_FIFO_LENGTH);
+    }
+
+    public void testGameRotationVectorFifoLength() throws Throwable {
+        if (!mHasHifiSensors) return;
+        checkMinFifoLength(Sensor.TYPE_GAME_ROTATION_VECTOR, GAME_ROTATION_VECTOR_MIN_FIFO_LENGTH);
+    }
+
+    public void testProximityFifoLength() throws Throwable {
+        if (!mHasHifiSensors) return;
+        checkMinFifoLength(Sensor.TYPE_PROXIMITY, PROXIMITY_SENSOR_MIN_FIFO_LENGTH);
+    }
+
+    public void testStepDetectorFifoLength() throws Throwable {
+        if (!mHasHifiSensors) return;
+        checkMinFifoLength(Sensor.TYPE_STEP_DETECTOR, STEP_DETECTOR_MIN_FIFO_LENGTH);
+    }
+
+    private void checkMinFifoLength(int sensorType, int minRequiredLength) {
+        Sensor sensor = mSensorManager.getDefaultSensor(sensorType);
+        assertTrue(String.format("sensor of type=%d (null)", sensorType), sensor != null);
+        int reservedLength = sensor.getFifoReservedEventCount();
+        assertTrue(String.format("Sensor=%s, min required fifo length=%d actual=%d",
+                    sensor.getName(), minRequiredLength, reservedLength),
+                    reservedLength >= minRequiredLength);
+    }
 }
diff --git a/tests/tests/hardware/src/android/hardware/cts/SensorSupportTest.java b/tests/tests/hardware/src/android/hardware/cts/SensorSupportTest.java
index 2f25c8d..185eb07 100644
--- a/tests/tests/hardware/src/android/hardware/cts/SensorSupportTest.java
+++ b/tests/tests/hardware/src/android/hardware/cts/SensorSupportTest.java
@@ -30,7 +30,7 @@
  * <p>To execute these test cases, the following command can be used:</p>
  * <pre>
  * adb shell am instrument -e class android.hardware.cts.SensorSupportTest \
- *     -w com.android.cts.hardware/android.test.AndroidJUnitRunner
+ *     -w android.hardware.cts/android.test.AndroidJUnitRunner
  * </pre>
  */
 public class SensorSupportTest extends AndroidTestCase {
diff --git a/tests/tests/hardware/src/android/hardware/cts/SensorTest.java b/tests/tests/hardware/src/android/hardware/cts/SensorTest.java
index 171bef4..95a76b8 100644
--- a/tests/tests/hardware/src/android/hardware/cts/SensorTest.java
+++ b/tests/tests/hardware/src/android/hardware/cts/SensorTest.java
@@ -44,6 +44,7 @@
 import android.os.HandlerThread;
 import android.os.PowerManager;
 import android.os.SystemClock;
+import android.platform.test.annotations.Presubmit;
 import android.util.Log;
 
 import java.util.ArrayList;
@@ -200,6 +201,7 @@
 
     // Some sensors like proximity, significant motion etc. are defined as wake-up sensors by
     // default. Check if the wake-up flag is set correctly.
+    @Presubmit
     public void testWakeUpFlags() {
         final int TYPE_WAKE_GESTURE = 23;
         final int TYPE_GLANCE_GESTURE = 24;
@@ -241,6 +243,7 @@
         }
     }
 
+    @Presubmit
     public void testSensorStringTypes() {
         for (Sensor sensor : mSensorList) {
             if (sensor.getType() < MAX_OFFICIAL_ANDROID_SENSOR_TYPE &&
diff --git a/tests/tests/hardware/src/android/hardware/cts/SingleSensorTests.java b/tests/tests/hardware/src/android/hardware/cts/SingleSensorTests.java
index 73d61a5..e2a69e9d 100644
--- a/tests/tests/hardware/src/android/hardware/cts/SingleSensorTests.java
+++ b/tests/tests/hardware/src/android/hardware/cts/SingleSensorTests.java
@@ -36,7 +36,7 @@
  * To execute these test cases, the following command can be used:
  * </p><pre>
  * adb shell am instrument -e class android.hardware.cts.SingleSensorTests \
- *     -w com.android.cts.hardware/android.test.AndroidJUnitRunner
+ *     -w android.hardware.cts/android.test.AndroidJUnitRunner
  * </pre><p>
  * For each sensor that reports continuously, it takes a set of samples. The test suite verifies
  * that the event ordering, frequency, and jitter pass for the collected sensor events. It
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/JitterVerification.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/JitterVerification.java
index 9d36f37..694c61f 100644
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/JitterVerification.java
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/JitterVerification.java
@@ -27,8 +27,6 @@
 import android.hardware.cts.helpers.TestSensorEvent;
 import android.util.SparseIntArray;
 
-import com.android.cts.util.StatisticsUtils;
-
 import java.util.ArrayList;
 import java.util.LinkedList;
 import java.util.List;
diff --git a/tests/tests/hardware/src/android/hardware/fingerprint/cts/FingerprintManagerTest.java b/tests/tests/hardware/src/android/hardware/fingerprint/cts/FingerprintManagerTest.java
index 95704b9..f11b6bc 100644
--- a/tests/tests/hardware/src/android/hardware/fingerprint/cts/FingerprintManagerTest.java
+++ b/tests/tests/hardware/src/android/hardware/fingerprint/cts/FingerprintManagerTest.java
@@ -21,6 +21,7 @@
 import android.hardware.fingerprint.FingerprintManager;
 import android.hardware.fingerprint.FingerprintManager.AuthenticationCallback;
 import android.os.CancellationSignal;
+import android.platform.test.annotations.Presubmit;
 import android.test.AndroidTestCase;
 
 /**
@@ -65,6 +66,7 @@
         }
     }
 
+    @Presubmit
     public void test_hasFingerprintHardware() {
         if (!mHasFingerprintManager) {
             return; // skip test if no fingerprint feature
diff --git a/tests/tests/hardware/src/android/hardware/input/cts/InputCallback.java b/tests/tests/hardware/src/android/hardware/input/cts/InputCallback.java
new file mode 100644
index 0000000..accdcaf
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/input/cts/InputCallback.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.hardware.input.cts;
+
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+
+public interface InputCallback {
+    public void onKeyEvent(KeyEvent ev);
+    public void onMotionEvent(MotionEvent ev);
+}
diff --git a/tests/tests/hardware/src/android/hardware/input/cts/InputCtsActivity.java b/tests/tests/hardware/src/android/hardware/input/cts/InputCtsActivity.java
new file mode 100644
index 0000000..b16cadb
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/input/cts/InputCtsActivity.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.hardware.input.cts;
+
+import android.app.Activity;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class InputCtsActivity extends Activity {
+    private InputCallback mInputCallback;
+
+    @Override
+    public boolean dispatchGenericMotionEvent(MotionEvent ev) {
+        if (mInputCallback != null) {
+            mInputCallback.onMotionEvent(ev);
+        }
+        return true;
+    }
+
+    @Override
+    public boolean dispatchTouchEvent(MotionEvent ev) {
+        if (mInputCallback != null) {
+            mInputCallback.onMotionEvent(ev);
+        }
+        return true;
+    }
+
+    @Override
+    public boolean dispatchTrackballEvent(MotionEvent ev) {
+        if (mInputCallback != null) {
+            mInputCallback.onMotionEvent(ev);
+        }
+        return true;
+    }
+
+    @Override
+    public boolean dispatchKeyEvent(KeyEvent ev) {
+        if (mInputCallback != null) {
+            mInputCallback.onKeyEvent(ev);
+        }
+        return true;
+    }
+
+    public void setInputCallback(InputCallback callback) {
+        mInputCallback = callback;
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/input/cts/tests/GamepadTestCase.java b/tests/tests/hardware/src/android/hardware/input/cts/tests/GamepadTestCase.java
new file mode 100644
index 0000000..2a772ae
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/input/cts/tests/GamepadTestCase.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.hardware.input.cts.tests;
+
+import android.util.Log;
+import android.view.KeyEvent;
+
+import java.io.Writer;
+import java.util.List;
+
+import android.hardware.cts.R;
+
+public class GamepadTestCase extends InputTestCase {
+    private static final String TAG = "GamepadTests";
+
+    public void testButtonA() throws Exception {
+        sendHidCommands(R.raw.gamepad_press_a);
+        assertReceivedKeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BUTTON_A);
+        assertReceivedKeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_BUTTON_A);
+        assertNoMoreEvents();
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/input/cts/tests/InputTestCase.java b/tests/tests/hardware/src/android/hardware/input/cts/tests/InputTestCase.java
new file mode 100644
index 0000000..fba5f51
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/input/cts/tests/InputTestCase.java
@@ -0,0 +1,221 @@
+/*
+ * Copyright 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.hardware.input.cts.tests;
+
+import android.app.UiAutomation;
+import android.hardware.input.cts.InputCtsActivity;
+import android.hardware.input.cts.InputCallback;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.test.ActivityInstrumentationTestCase2;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+import java.util.List;
+import java.util.UUID;
+
+public class InputTestCase extends ActivityInstrumentationTestCase2<InputCtsActivity> {
+    private static final String TAG = "InputTestCase";
+    private static final String HID_EXECUTABLE = "hid";
+    private static final int SHELL_UID = 2000;
+    private static final String[] KEY_ACTIONS = {"DOWN", "UP", "MULTIPLE"};
+
+    private File mFifo;
+    private Writer mWriter;
+
+    private BlockingQueue<KeyEvent> mKeys;
+    private BlockingQueue<MotionEvent> mMotions;
+    private InputListener mInputListener;
+
+    public InputTestCase() {
+        super(InputCtsActivity.class);
+        mKeys = new LinkedBlockingQueue<KeyEvent>();
+        mMotions = new LinkedBlockingQueue<MotionEvent>();
+        mInputListener = new InputListener();
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mFifo = setupFifo();
+        clearKeys();
+        clearMotions();
+        getActivity().setInputCallback(mInputListener);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        if (mFifo != null) {
+            mFifo.delete();
+            mFifo = null;
+        }
+        closeQuietly(mWriter);
+        mWriter = null;
+        super.tearDown();
+    }
+
+    /**
+     * Sends the HID commands designated by the given resource id.
+     * The commands must be in the format expected by the `hid` shell command.
+     *
+     * @param id The resource id from which to load the HID commands. This must be a "raw"
+     * resource.
+     */
+    public void sendHidCommands(int id) {
+        try {
+            Writer w = getWriter();
+            w.write(getEvents(id));
+            w.flush();
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Asserts that the application received a {@link android.view.KeyEvent} with the given action
+     * and keycode.
+     *
+     * If other KeyEvents are received by the application prior to the expected KeyEvent, or no
+     * KeyEvents are received within a reasonable amount of time, then this will throw an
+     * AssertionFailedError.
+     *
+     * @param action The action to expect on the next KeyEvent
+     * (e.g. {@link android.view.KeyEvent#ACTION_DOWN}).
+     * @param keyCode The expected key code of the next KeyEvent.
+     */
+    public void assertReceivedKeyEvent(int action, int keyCode) {
+        KeyEvent k = waitForKey();
+        if (k == null) {
+            fail("Timed out waiting for " + KeyEvent.keyCodeToString(keyCode)
+                    + " with action " + KEY_ACTIONS[action]);
+            return;
+        }
+        assertEquals(action, k.getAction());
+        assertEquals(keyCode, k.getKeyCode());
+    }
+
+    /**
+     * Asserts that no more events have been received by the application.
+     *
+     * If any more events have been received by the application, this throws an
+     * AssertionFailedError.
+     */
+    public void assertNoMoreEvents() {
+        KeyEvent key;
+        MotionEvent motion;
+        if ((key = mKeys.poll()) != null) {
+            fail("Extraneous key events generated: " + key);
+        }
+        if ((motion = mMotions.poll()) != null) {
+            fail("Extraneous motion events generated: " + motion);
+        }
+    }
+
+    private KeyEvent waitForKey() {
+        try {
+            return mKeys.poll(1, TimeUnit.SECONDS);
+        } catch (InterruptedException e) {
+            return null;
+        }
+    }
+
+    private void clearKeys() {
+        mKeys.clear();
+    }
+
+    private void clearMotions() {
+        mMotions.clear();
+    }
+
+    private File setupFifo() throws ErrnoException {
+        File dir = getActivity().getCacheDir();
+        String filename = dir.getAbsolutePath() + File.separator +  UUID.randomUUID().toString();
+        Os.mkfifo(filename, 0666);
+        File f = new File(filename);
+        return f;
+    }
+
+    private Writer getWriter() throws IOException {
+        if (mWriter == null) {
+            UiAutomation ui = getInstrumentation().getUiAutomation();
+            ui.executeShellCommand("hid " + mFifo.getAbsolutePath());
+            mWriter = new FileWriter(mFifo);
+        }
+        return mWriter;
+    }
+
+    private String getEvents(int id) throws IOException {
+        InputStream is =
+            getInstrumentation().getTargetContext().getResources().openRawResource(id);
+        return readFully(is);
+    }
+
+
+    private static void closeQuietly(AutoCloseable closeable) {
+        if (closeable != null) {
+            try {
+                closeable.close();
+            } catch (RuntimeException rethrown) {
+                throw rethrown;
+            } catch (Exception ignored) { }
+        }
+    }
+
+    private static String readFully(InputStream is) throws IOException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        int read = 0;
+        byte[] buffer = new byte[1024];
+        while ((read = is.read(buffer)) >= 0) {
+            baos.write(buffer, 0, read);
+        }
+        return baos.toString();
+    }
+
+    private class InputListener implements InputCallback {
+        public void onKeyEvent(KeyEvent ev) {
+            boolean done = false;
+            do {
+                try {
+                    mKeys.put(new KeyEvent(ev));
+                    done = true;
+                } catch (InterruptedException ignore) { }
+            } while (!done);
+        }
+
+        public void onMotionEvent(MotionEvent ev) {
+            boolean done = false;
+            do {
+                try {
+                    mMotions.put(MotionEvent.obtain(ev));
+                    done = true;
+                } catch (InterruptedException ignore) { }
+            } while (!done);
+        }
+    }
+}
diff --git a/tests/tests/icu/Android.mk b/tests/tests/icu/Android.mk
new file mode 100644
index 0000000..6f183d5
--- /dev/null
+++ b/tests/tests/icu/Android.mk
@@ -0,0 +1,80 @@
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+# Don't include this package in any target
+LOCAL_MODULE_TAGS := tests
+# When built explicitly put it in the data partition
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_DEX_PREOPT := false
+
+LOCAL_PROGUARD_ENABLED := disabled
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_JAVA_RESOURCE_DIRS := resources
+
+# The aim of this package is to run tests against the implementation in use by
+# the current android system.
+LOCAL_STATIC_JAVA_LIBRARIES := \
+	cts-core-test-runner \
+	android-icu4j-tests
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_PACKAGE_NAME := CtsIcuTestCases
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_SUPPORT_PACKAGE)
+
+# Version 1 of the CTS framework has it's own logic for generating XML files based on scanning the
+# source for test methods and classes written using JUnit 3 (doesn't work for JUnit 4 @RunWith
+# tests). Since the ICU tests are not written using JUnit (although they are run with a custom JUnit
+# RunnerBuilder) this provides an alternative. This generates an XML representation based off a
+# list of the tests that are run by version 2 of the CTS framework (which doesn't require the list
+# in advance). The tools/update-test-list.sh script will take a host_log_[0-9]+.zip created by
+# CTSv1 and extract the list of tests run and update the test-list.txt file.
+
+CTS_ICU_TEST_LIST_PATH := $(LOCAL_PATH)/test-list.txt
+cts_package_xml := $(CTS_TESTCASES_OUT)/CtsIcuTestCases.xml
+$(cts_package_xml): $(HOST_OUT_JAVA_LIBRARIES)/cts-icu-tools.jar $(CTS_ICU_TEST_LIST_PATH) \
+	$(call intermediates-dir-for,APPS,$(LOCAL_PACKAGE_NAME))/package.apk
+	java -Xmx256M -classpath $(HOST_OUT_JAVA_LIBRARIES)/cts-icu-tools.jar \
+		android.icu.cts.tools.GenerateTestCaseXML \
+		$(CTS_ICU_TEST_LIST_PATH) \
+		$(TARGET_ARCH) \
+		$@
+
+# build cts-icu-tools tool
+# ============================================================
+include $(CLEAR_VARS)
+
+# Don't include this package in any target
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := $(call all-java-files-under, tools)
+LOCAL_JAVA_RESOURCE_DIRS := resources
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
+	descGen \
+	jsr305lib
+
+LOCAL_MODULE := cts-icu-tools
+
+include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/tests/tests/icu/AndroidManifest.xml b/tests/tests/icu/AndroidManifest.xml
new file mode 100644
index 0000000..d80c8e7
--- /dev/null
+++ b/tests/tests/icu/AndroidManifest.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="android.icu.cts">
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="android.icu.cts.IcuTestRunnerForCtsV1"
+                     android:targetPackage="android.icu.cts"
+                     android:label="CTS Repackaged ICU4J library tests."/>
+</manifest>
diff --git a/tests/tests/icu/AndroidTest.xml b/tests/tests/icu/AndroidTest.xml
new file mode 100644
index 0000000..769b789
--- /dev/null
+++ b/tests/tests/icu/AndroidTest.xml
@@ -0,0 +1,30 @@
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS ICU test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsIcuTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <!-- override AJUR -->
+        <option name="runner" value="com.android.cts.core.runner.CoreTestRunner" />
+        <option name="package" value="android.icu.cts" />
+        <option name="instrumentation-arg" key="core-root-classes"
+                value="android.icu.cts.coverage.TestAll,android.icu.dev.test.TestAll" />
+        <option name="instrumentation-arg" key="core-expectations"
+                value="/android/icu/cts/expectations/icu-known-failures.txt" />
+        <option name="runtime-hint" value="30m19s" />
+    </test>
+</configuration>
diff --git a/tests/tests/icu/resources/android/icu/cts/expectations/icu-known-failures.txt b/tests/tests/icu/resources/android/icu/cts/expectations/icu-known-failures.txt
new file mode 100644
index 0000000..9ca52c5
--- /dev/null
+++ b/tests/tests/icu/resources/android/icu/cts/expectations/icu-known-failures.txt
@@ -0,0 +1,69 @@
+/*
+ * This file contains expectations for tests that are known to fail.
+ */
+[
+// Uncomment this to exclude all tests and then add result: "SUCCESS" to any specific tests that
+// need to be run.
+/*
+{
+  description: "Exclude all tests",
+  name: "android.icu.dev.test"
+},
+*/
+{
+  description: "Class cannot be instantiated, cannot find resources android/icu/dev/test/serializable/data",
+  name: "android.icu.dev.test.serializable.CompatibilityTest",
+  bug: "27310873"
+},
+{
+  description: "Cannot find any classes to test because .class files are not treated as resources in APK",
+  name: "android.icu.dev.test.serializable.CoverageTest",
+  bug: "27666677"
+},
+{
+  description: "Serialized forms have not been converted to use repackaged classes",
+  name: "android.icu.dev.test.format.NumberFormatRegressionTest#TestSerialization",
+  bug: "27374606"
+},
+{
+  description: "android.icu.charset package not available in repackaged Android library",
+  name: "android.icu.dev.test.charset.TestAll",
+  bug: "27373370"
+},
+{
+  description: "A completely empty test case",
+  name: "android.icu.dev.test.duration.PeriodBuilderTest"
+},
+{
+  description: "Fails on host and on device in same way before and after packaging",
+  name: "android.icu.dev.test.bidi.TestCompatibility#testCompatibility",
+  bug: "23995372"
+},
+{
+  description: "Problem with negative multiplier, not a regression",
+  name: "android.icu.dev.test.format.NumberFormatTest#TestNonpositiveMultiplier",
+  bug: "19185440"
+},
+{
+  description: "Wrong case for exponent separator",
+  name: "android.icu.dev.test.format.PluralRulesTest#testOverUnderflow",
+  bug: "27566754"
+},
+{
+  description: "Checks differences in DecimalFormat classes from ICU4J and JDK but on Android java.text.DecimalFormat is implemented in terms of ICU4J",
+  name: "android.icu.dev.test.format.NumberFormatTest#TestDataDrivenJDK",
+  bug: "27711713"
+},
+{
+  description: "Collation rules data has been removed from ICU4J data on Android",
+  names: [
+    "android.icu.dev.test.collator.CollationCreationMethodTest#TestRuleVsLocaleCreationMonkey",
+    "android.icu.dev.test.collator.CollationMiscTest#TestImport",
+    "android.icu.dev.test.collator.CollationMiscTest#TestImportWithType",
+    "android.icu.dev.test.collator.CollationMiscTest#TestUCARules",
+    "android.icu.dev.test.collator.CollationTest#TestDataDriven",
+    "android.icu.dev.test.collator.G7CollationTest#TestG7Data"
+  ],
+  bug: "27552651"
+}
+]
diff --git a/tests/tests/icu/src/android/icu/cts/IcuTestRunnerForCtsV1.java b/tests/tests/icu/src/android/icu/cts/IcuTestRunnerForCtsV1.java
new file mode 100644
index 0000000..2a8d7b3
--- /dev/null
+++ b/tests/tests/icu/src/android/icu/cts/IcuTestRunnerForCtsV1.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.icu.cts;
+
+import android.os.Bundle;
+import com.android.cts.core.runner.CoreTestRunner;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Customize {@link CoreTestRunner} to hard code information in the runner.
+ *
+ * <p>CTSv2 allows parameters to be specified in the AndroidTest.xml file but CTSv1 does not so
+ * they have to be hard coded into the runner itself.
+ */
+public final class IcuTestRunnerForCtsV1 extends CoreTestRunner {
+
+    private static final List<String> EXPECTATIONS_PATHS =
+            Collections.singletonList("expectations/icu-known-failures.txt");
+
+    @Override
+    protected List<String> getExpectationResourcePaths(Bundle args) {
+        return EXPECTATIONS_PATHS;
+    }
+
+    @Override
+    protected List<String> getRootClassNames(Bundle args) {
+        return Arrays.asList(
+                "android.icu.cts.coverage.TestAll",
+                "android.icu.dev.test.TestAll");
+    }
+}
diff --git a/tests/tests/icu/test-list.txt b/tests/tests/icu/test-list.txt
new file mode 100644
index 0000000..cd47a76
--- /dev/null
+++ b/tests/tests/icu/test-list.txt
@@ -0,0 +1,2253 @@
+android.icu.cts.coverage.lang.UCharacterTest#testNameAliasing
+android.icu.cts.coverage.lang.UCharacterTest#testToTitleCase_Locale_String_BreakIterator_I
+android.icu.cts.coverage.lang.UCharacterTest#testToTitleCase_String_BreakIterator_en
+android.icu.cts.coverage.lang.UCharacterTest#testToTitleCase_String_BreakIterator_nl
+android.icu.cts.coverage.text.AlphabeticIndexTest#testAddLabels_Locale
+android.icu.cts.coverage.text.AlphabeticIndexTest#testFlowLabels
+android.icu.cts.coverage.text.AlphabeticIndexTest#testGetRecordCount_empty
+android.icu.cts.coverage.text.AlphabeticIndexTest#testGetRecordCount_withRecords
+android.icu.cts.coverage.text.DateFormatSymbolsTest#testSetEraNames_defensivelyCopies
+android.icu.cts.coverage.text.DateFormatSymbolsTest#testYearNames_defensivelyCopies
+android.icu.cts.coverage.text.DateIntervalFormatTest#testGetInstance_String_DateIntervalInfo
+android.icu.cts.coverage.text.DateIntervalFormatTest#testGetInstance_String_Locale_DateIntervalInfo
+android.icu.cts.coverage.text.DateIntervalFormatTest#testParseObject_notSupported
+android.icu.cts.coverage.text.LocaleDisplayNamesTest#testGetInstance
+android.icu.cts.coverage.text.LocaleDisplayNamesTest#testGetLocale
+android.icu.cts.coverage.text.LocaleDisplayNamesTest#testKeyDisplayName
+android.icu.cts.coverage.text.LocaleDisplayNamesTest#testKeyValueDisplayName
+android.icu.cts.coverage.text.LocaleDisplayNamesTest#testLocaleDisplayName
+android.icu.cts.coverage.text.LocaleDisplayNamesTest#testScriptDisplayName_Int
+android.icu.cts.coverage.text.LocaleDisplayNamesTest#testScriptDisplayName_String
+android.icu.cts.coverage.text.LocaleDisplayNamesTest#testVariantDisplayName
+android.icu.cts.coverage.text.RelativeDateTimeFormatterTest#testGetInstance
+android.icu.cts.coverage.text.TimeZoneNamesTest#testGetAvailableMetaZoneIDs
+android.icu.cts.coverage.text.TimeZoneNamesTest#testGetAvailableMetaZoneIDs_String
+android.icu.cts.coverage.text.TimeZoneNamesTest#testGetInstance_Locale
+android.icu.cts.coverage.text.TimeZoneNamesTest#testGetMetaZoneDisplayName
+android.icu.cts.coverage.text.TimeZoneNamesTest#testGetMetaZoneID
+android.icu.cts.coverage.text.TimeZoneNamesTest#testGetTimeZoneDisplayName
+android.icu.cts.coverage.text.UnicodeSetTest#testAddAll_CharacterSequences
+android.icu.cts.coverage.text.UnicodeSetTest#testCompareTo
+android.icu.cts.coverage.util.CurrencyTest#testGetDefaultFractionDigits_CurrencyUsage
+android.icu.cts.coverage.util.CurrencyTest#testGetName_Locale_Int_String_BooleanArray
+android.icu.cts.coverage.util.CurrencyTest#testGetRoundingIncrement
+android.icu.cts.coverage.util.CurrencyTest#testGetRoundingIncrement_CurrencyUsage
+android.icu.dev.test.bidi.BiDiConformanceTest#TestBidiCharacterTest
+android.icu.dev.test.bidi.BiDiConformanceTest#TestBidiTest
+android.icu.dev.test.bidi.TestBidi#testBidi
+android.icu.dev.test.bidi.TestCharFromDirProp#testCharFromDirProp
+android.icu.dev.test.bidi.TestClassOverride#testClassOverride
+android.icu.dev.test.bidi.TestContext#testContext
+android.icu.dev.test.bidi.TestFailureRecovery#testFailureRecovery
+android.icu.dev.test.bidi.TestInverse#testInverse
+android.icu.dev.test.bidi.TestMultipleParagraphs#testMultipleParagraphs
+android.icu.dev.test.bidi.TestReorderArabicMathSymbols#testReorderArabicMathSymbols
+android.icu.dev.test.bidi.TestReorderingMode#testReorderingMode
+android.icu.dev.test.bidi.TestReorderRunsOnly#testReorderRunsOnly
+android.icu.dev.test.bidi.TestReorder#testReorder
+android.icu.dev.test.bidi.TestStreaming#testStreaming
+android.icu.dev.test.bigdec.DiagBigDecimal#TestBigDecimal
+android.icu.dev.test.calendar.AstroTest#TestBasics
+android.icu.dev.test.calendar.AstroTest#TestCoordinates
+android.icu.dev.test.calendar.AstroTest#TestCoverage
+android.icu.dev.test.calendar.AstroTest#TestLunarPosition
+android.icu.dev.test.calendar.AstroTest#TestMoonAge
+android.icu.dev.test.calendar.AstroTest#TestSolarLongitude
+android.icu.dev.test.calendar.AstroTest#TestSunriseTimes
+android.icu.dev.test.calendar.CalendarRegression#Test4031502
+android.icu.dev.test.calendar.CalendarRegression#Test4035301
+android.icu.dev.test.calendar.CalendarRegression#Test4040996
+android.icu.dev.test.calendar.CalendarRegression#Test4051765
+android.icu.dev.test.calendar.CalendarRegression#Test4059654
+android.icu.dev.test.calendar.CalendarRegression#Test4061476
+android.icu.dev.test.calendar.CalendarRegression#Test4070502
+android.icu.dev.test.calendar.CalendarRegression#Test4071197
+android.icu.dev.test.calendar.CalendarRegression#Test4071385
+android.icu.dev.test.calendar.CalendarRegression#Test4073929
+android.icu.dev.test.calendar.CalendarRegression#Test4083167
+android.icu.dev.test.calendar.CalendarRegression#Test4086724
+android.icu.dev.test.calendar.CalendarRegression#Test4092362
+android.icu.dev.test.calendar.CalendarRegression#Test4095407
+android.icu.dev.test.calendar.CalendarRegression#Test4096231
+android.icu.dev.test.calendar.CalendarRegression#Test4096539
+android.icu.dev.test.calendar.CalendarRegression#Test4100311
+android.icu.dev.test.calendar.CalendarRegression#Test4103271
+android.icu.dev.test.calendar.CalendarRegression#Test4106136
+android.icu.dev.test.calendar.CalendarRegression#Test4108764
+android.icu.dev.test.calendar.CalendarRegression#Test4114578
+android.icu.dev.test.calendar.CalendarRegression#Test4118384
+android.icu.dev.test.calendar.CalendarRegression#Test4125881
+android.icu.dev.test.calendar.CalendarRegression#Test4125892
+android.icu.dev.test.calendar.CalendarRegression#Test4136399
+android.icu.dev.test.calendar.CalendarRegression#Test4141665
+android.icu.dev.test.calendar.CalendarRegression#Test4142933
+android.icu.dev.test.calendar.CalendarRegression#Test4145158
+android.icu.dev.test.calendar.CalendarRegression#Test4145983
+android.icu.dev.test.calendar.CalendarRegression#Test4147269
+android.icu.dev.test.calendar.CalendarRegression#Test4149677
+android.icu.dev.test.calendar.CalendarRegression#Test4162587
+android.icu.dev.test.calendar.CalendarRegression#Test4165343
+android.icu.dev.test.calendar.CalendarRegression#Test4166109
+android.icu.dev.test.calendar.CalendarRegression#Test4167060
+android.icu.dev.test.calendar.CalendarRegression#Test4173516
+android.icu.dev.test.calendar.CalendarRegression#Test4174361
+android.icu.dev.test.calendar.CalendarRegression#Test4177484
+android.icu.dev.test.calendar.CalendarRegression#Test4197699
+android.icu.dev.test.calendar.CalendarRegression#Test4209071
+android.icu.dev.test.calendar.CalendarRegression#Test4288792
+android.icu.dev.test.calendar.CalendarRegression#Test9019
+android.icu.dev.test.calendar.CalendarRegression#TestCalendarType6816
+android.icu.dev.test.calendar.CalendarRegression#TestDateFormatFactoryJ26
+android.icu.dev.test.calendar.CalendarRegression#TestGetKeywordValuesForLocale
+android.icu.dev.test.calendar.CalendarRegression#TestJ438
+android.icu.dev.test.calendar.CalendarRegression#TestJ9
+android.icu.dev.test.calendar.CalendarRegression#TestRegistration
+android.icu.dev.test.calendar.CalendarRegression#TestSerialization3474
+android.icu.dev.test.calendar.CalendarRegression#TestT5555
+android.icu.dev.test.calendar.CalendarRegression#TestT8057
+android.icu.dev.test.calendar.CalendarRegression#TestT8596
+android.icu.dev.test.calendar.CalendarRegression#TestT9403
+android.icu.dev.test.calendar.CalendarRegression#TestT9452
+android.icu.dev.test.calendar.CalendarRegression#TestT9968
+android.icu.dev.test.calendar.CalendarRegression#TestTimeStamp
+android.icu.dev.test.calendar.CalendarRegression#TestWeekendData_10560
+android.icu.dev.test.calendar.CalendarRegression#TestYearJump3279
+android.icu.dev.test.calendar.ChineseTest#Test6510
+android.icu.dev.test.calendar.ChineseTest#TestAdd
+android.icu.dev.test.calendar.ChineseTest#TestCoverage
+android.icu.dev.test.calendar.ChineseTest#TestFormat
+android.icu.dev.test.calendar.ChineseTest#TestInitWithCurrentTime
+android.icu.dev.test.calendar.ChineseTest#TestJulianDayMapping
+android.icu.dev.test.calendar.ChineseTest#TestLimits
+android.icu.dev.test.calendar.ChineseTest#TestMapping
+android.icu.dev.test.calendar.ChineseTest#TestOutOfRange
+android.icu.dev.test.calendar.ChineseTest#TestResolution
+android.icu.dev.test.calendar.ChineseTest#TestRoll
+android.icu.dev.test.calendar.ChineseTest#TestScratch
+android.icu.dev.test.calendar.ChineseTest#TestZeroDOM
+android.icu.dev.test.calendar.CompatibilityTest#TestActualMinMax
+android.icu.dev.test.calendar.CompatibilityTest#TestAdd520
+android.icu.dev.test.calendar.CompatibilityTest#TestAddAcrossOffsetTransitions
+android.icu.dev.test.calendar.CompatibilityTest#TestAddSetGet0610
+android.icu.dev.test.calendar.CompatibilityTest#TestAddSetOrder621
+android.icu.dev.test.calendar.CompatibilityTest#TestClonesUnique908
+android.icu.dev.test.calendar.CompatibilityTest#TestComputeJulianDay4406
+android.icu.dev.test.calendar.CompatibilityTest#TestDisambiguation765
+android.icu.dev.test.calendar.CompatibilityTest#TestDOW943
+android.icu.dev.test.calendar.CompatibilityTest#TestDOWProgression
+android.icu.dev.test.calendar.CompatibilityTest#TestEpochStartFields
+android.icu.dev.test.calendar.CompatibilityTest#TestFields060
+android.icu.dev.test.calendar.CompatibilityTest#TestFieldSet4781
+android.icu.dev.test.calendar.CompatibilityTest#TestGenericAPI
+android.icu.dev.test.calendar.CompatibilityTest#TestGMTvsLocal4064654
+android.icu.dev.test.calendar.CompatibilityTest#TestGregorianChange768
+android.icu.dev.test.calendar.CompatibilityTest#TestGregorianChangeover
+android.icu.dev.test.calendar.CompatibilityTest#TestMapping
+android.icu.dev.test.calendar.CompatibilityTest#TestRog
+android.icu.dev.test.calendar.CompatibilityTest#TestRoll
+android.icu.dev.test.calendar.CompatibilityTest#TestSecondsZero121
+android.icu.dev.test.calendar.CompatibilityTest#TestSerialize337
+android.icu.dev.test.calendar.CopticTest#Test6379
+android.icu.dev.test.calendar.CopticTest#TestAddSet
+android.icu.dev.test.calendar.CopticTest#TestBasic
+android.icu.dev.test.calendar.CopticTest#TestCases
+android.icu.dev.test.calendar.CopticTest#TestCopticToJD
+android.icu.dev.test.calendar.CopticTest#TestCoverage
+android.icu.dev.test.calendar.CopticTest#TestEraStart
+android.icu.dev.test.calendar.CopticTest#TestLimits
+android.icu.dev.test.calendar.CopticTest#TestYear
+android.icu.dev.test.calendar.DataDrivenCalendarTest#TestCalendarConversion
+android.icu.dev.test.calendar.DataDrivenCalendarTest#TestCalendarOperations
+android.icu.dev.test.calendar.EthiopicTest#TestAddSet
+android.icu.dev.test.calendar.EthiopicTest#TestBasic
+android.icu.dev.test.calendar.EthiopicTest#TestCases
+android.icu.dev.test.calendar.EthiopicTest#TestCoverage
+android.icu.dev.test.calendar.EthiopicTest#TestEraStart
+android.icu.dev.test.calendar.EthiopicTest#TestJD
+android.icu.dev.test.calendar.EthiopicTest#TestLimits
+android.icu.dev.test.calendar.HebrewTest#Test1624
+android.icu.dev.test.calendar.HebrewTest#TestAdd
+android.icu.dev.test.calendar.HebrewTest#TestCases
+android.icu.dev.test.calendar.HebrewTest#TestCoverage
+android.icu.dev.test.calendar.HebrewTest#TestDefaultFieldValues
+android.icu.dev.test.calendar.HebrewTest#TestElulMonth
+android.icu.dev.test.calendar.HebrewTest#TestLimits
+android.icu.dev.test.calendar.HebrewTest#TestMonthMovement
+android.icu.dev.test.calendar.HebrewTest#TestMonthValidation
+android.icu.dev.test.calendar.HebrewTest#TestRoll
+android.icu.dev.test.calendar.HebrewTest#TestTimeFields
+android.icu.dev.test.calendar.HolidayTest#TestAPI
+android.icu.dev.test.calendar.HolidayTest#TestCoverage
+android.icu.dev.test.calendar.HolidayTest#TestDisplayName
+android.icu.dev.test.calendar.HolidayTest#TestEaster
+android.icu.dev.test.calendar.HolidayTest#TestIsOn
+android.icu.dev.test.calendar.IBMCalendarTest#TestAddAcrossZoneTransition
+android.icu.dev.test.calendar.IBMCalendarTest#TestAddRollEra0AndEraBounds
+android.icu.dev.test.calendar.IBMCalendarTest#TestAmbiguousWallTimeAPIs
+android.icu.dev.test.calendar.IBMCalendarTest#TestBuddhist
+android.icu.dev.test.calendar.IBMCalendarTest#TestBuddhistCoverage
+android.icu.dev.test.calendar.IBMCalendarTest#TestBuddhistLimits
+android.icu.dev.test.calendar.IBMCalendarTest#TestComparable
+android.icu.dev.test.calendar.IBMCalendarTest#TestCoverage
+android.icu.dev.test.calendar.IBMCalendarTest#TestFieldDifference
+android.icu.dev.test.calendar.IBMCalendarTest#TestGregorianLimits
+android.icu.dev.test.calendar.IBMCalendarTest#TestISO8601
+android.icu.dev.test.calendar.IBMCalendarTest#TestJapanese
+android.icu.dev.test.calendar.IBMCalendarTest#TestJB1684
+android.icu.dev.test.calendar.IBMCalendarTest#TestJB4541
+android.icu.dev.test.calendar.IBMCalendarTest#TestLeapFieldDifference
+android.icu.dev.test.calendar.IBMCalendarTest#TestMalaysianInstance
+android.icu.dev.test.calendar.IBMCalendarTest#TestRepeatedWallTime
+android.icu.dev.test.calendar.IBMCalendarTest#TestSimpleDateFormatCoverage
+android.icu.dev.test.calendar.IBMCalendarTest#TestSkippedWallTime
+android.icu.dev.test.calendar.IBMCalendarTest#TestTaiwan
+android.icu.dev.test.calendar.IBMCalendarTest#TestTaiwanCoverage
+android.icu.dev.test.calendar.IBMCalendarTest#TestTaiwanLimits
+android.icu.dev.test.calendar.IBMCalendarTest#TestThaiDefault
+android.icu.dev.test.calendar.IBMCalendarTest#TestTimeZoneTransitionAdd
+android.icu.dev.test.calendar.IBMCalendarTest#TestTypes
+android.icu.dev.test.calendar.IBMCalendarTest#TestWeekData
+android.icu.dev.test.calendar.IBMCalendarTest#TestWeekend
+android.icu.dev.test.calendar.IBMCalendarTest#TestWeekShift
+android.icu.dev.test.calendar.IBMCalendarTest#TestZoneMeta
+android.icu.dev.test.calendar.IndianTest#TestBasic
+android.icu.dev.test.calendar.IndianTest#TestCases
+android.icu.dev.test.calendar.IndianTest#TestCoverage
+android.icu.dev.test.calendar.IndianTest#TestCoverage12424
+android.icu.dev.test.calendar.IndianTest#TestLimits
+android.icu.dev.test.calendar.IndianTest#TestYear
+android.icu.dev.test.calendar.IndianTest#TestYearEdge
+android.icu.dev.test.calendar.IslamicTest#Test7427
+android.icu.dev.test.calendar.IslamicTest#Test8822
+android.icu.dev.test.calendar.IslamicTest#TestBasic
+android.icu.dev.test.calendar.IslamicTest#TestCivilCases
+android.icu.dev.test.calendar.IslamicTest#TestCoverage
+android.icu.dev.test.calendar.IslamicTest#TestCreationByLocale
+android.icu.dev.test.calendar.IslamicTest#TestIslamicTabularDates
+android.icu.dev.test.calendar.IslamicTest#TestIslamicUmAlQura
+android.icu.dev.test.calendar.IslamicTest#TestLimits
+android.icu.dev.test.calendar.IslamicTest#TestRoll
+android.icu.dev.test.calendar.IslamicTest#TestSerialization8449
+android.icu.dev.test.calendar.JapaneseTest#Test3860
+android.icu.dev.test.calendar.JapaneseTest#Test5345calendar
+android.icu.dev.test.calendar.JapaneseTest#Test5345parse
+android.icu.dev.test.calendar.JapaneseTest#TestCoverage
+android.icu.dev.test.calendar.JapaneseTest#TestJapaneseYear3282
+android.icu.dev.test.calendar.JapaneseTest#TestLimits
+android.icu.dev.test.calendar.PersianTest#TestCoverage12424
+android.icu.dev.test.calendar.PersianTest#TestMapping
+android.icu.dev.test.charsetdet.TestCharsetDetector#TestArabic
+android.icu.dev.test.charsetdet.TestCharsetDetector#TestBufferOverflow
+android.icu.dev.test.charsetdet.TestCharsetDetector#TestBug6889
+android.icu.dev.test.charsetdet.TestCharsetDetector#TestBug6954
+android.icu.dev.test.charsetdet.TestCharsetDetector#TestBug9267
+android.icu.dev.test.charsetdet.TestCharsetDetector#TestC1Bytes
+android.icu.dev.test.charsetdet.TestCharsetDetector#TestCharsetRecog_UTF_16_LE_Match
+android.icu.dev.test.charsetdet.TestCharsetDetector#TestConstruction
+android.icu.dev.test.charsetdet.TestCharsetDetector#TestDetection
+android.icu.dev.test.charsetdet.TestCharsetDetector#TestFreshDetectorEachTime
+android.icu.dev.test.charsetdet.TestCharsetDetector#TestHebrew
+android.icu.dev.test.charsetdet.TestCharsetDetector#TestInputFilter
+android.icu.dev.test.charsetdet.TestCharsetDetector#TestJapanese
+android.icu.dev.test.charsetdet.TestCharsetDetector#TestMultithreaded
+android.icu.dev.test.charsetdet.TestCharsetDetector#TestReusingDetector
+android.icu.dev.test.charsetdet.TestCharsetDetector#TestShortInput
+android.icu.dev.test.charsetdet.TestCharsetDetector#TestUTF16
+android.icu.dev.test.charsetdet.TestCharsetDetector#TestUTF8
+android.icu.dev.test.collator.AlphabeticIndexTest#TestA
+android.icu.dev.test.collator.AlphabeticIndexTest#TestBasics
+android.icu.dev.test.collator.AlphabeticIndexTest#TestBuckets
+android.icu.dev.test.collator.AlphabeticIndexTest#TestChineseUnihan
+android.icu.dev.test.collator.AlphabeticIndexTest#TestChineseZhuyin
+android.icu.dev.test.collator.AlphabeticIndexTest#TestClientSupport
+android.icu.dev.test.collator.AlphabeticIndexTest#TestEmpty
+android.icu.dev.test.collator.AlphabeticIndexTest#TestFirstCharacters
+android.icu.dev.test.collator.AlphabeticIndexTest#TestFirstScriptCharacters
+android.icu.dev.test.collator.AlphabeticIndexTest#TestFrozenCollator
+android.icu.dev.test.collator.AlphabeticIndexTest#TestHaniFirst
+android.icu.dev.test.collator.AlphabeticIndexTest#TestIndexCharactersList
+android.icu.dev.test.collator.AlphabeticIndexTest#TestInflow
+android.icu.dev.test.collator.AlphabeticIndexTest#TestJapaneseKanji
+android.icu.dev.test.collator.AlphabeticIndexTest#TestNoLabels
+android.icu.dev.test.collator.AlphabeticIndexTest#TestPinyinFirst
+android.icu.dev.test.collator.AlphabeticIndexTest#TestSchSt
+android.icu.dev.test.collator.AlphabeticIndexTest#TestSimplified
+android.icu.dev.test.collator.AlphabeticIndexTest#TestTraditional
+android.icu.dev.test.collator.AlphabeticIndexTest#TestZZZ
+android.icu.dev.test.collator.CollationAPITest#TestBadKeywords
+android.icu.dev.test.collator.CollationAPITest#TestBounds
+android.icu.dev.test.collator.CollationAPITest#TestClone
+android.icu.dev.test.collator.CollationAPITest#TestCollationKey
+android.icu.dev.test.collator.CollationAPITest#TestCompare
+android.icu.dev.test.collator.CollationAPITest#TestCreateCollator
+android.icu.dev.test.collator.CollationAPITest#TestDecomposition
+android.icu.dev.test.collator.CollationAPITest#TestDuplicate
+android.icu.dev.test.collator.CollationAPITest#TestElemIter
+android.icu.dev.test.collator.CollationAPITest#TestGetAll
+android.icu.dev.test.collator.CollationAPITest#TestGetContractions
+android.icu.dev.test.collator.CollationAPITest#TestGetKeywordValues
+android.icu.dev.test.collator.CollationAPITest#TestGetLocale
+android.icu.dev.test.collator.CollationAPITest#TestGetTailoredSet
+android.icu.dev.test.collator.CollationAPITest#TestHashCode
+android.icu.dev.test.collator.CollationAPITest#TestIterNumeric
+android.icu.dev.test.collator.CollationAPITest#TestJunkCollator
+android.icu.dev.test.collator.CollationAPITest#TestMaxVariable
+android.icu.dev.test.collator.CollationAPITest#TestProperty
+android.icu.dev.test.collator.CollationAPITest#TestRawCollationKey
+android.icu.dev.test.collator.CollationAPITest#TestRuleBasedColl
+android.icu.dev.test.collator.CollationAPITest#TestRules
+android.icu.dev.test.collator.CollationAPITest#TestSafeClone
+android.icu.dev.test.collator.CollationAPITest#TestSetDecomposition
+android.icu.dev.test.collator.CollationAPITest#TestSetGet
+android.icu.dev.test.collator.CollationAPITest#TestSetStrength
+android.icu.dev.test.collator.CollationAPITest#TestSubClass
+android.icu.dev.test.collator.CollationAPITest#TestVariableTopSetting
+android.icu.dev.test.collator.CollationChineseTest#TestPinYin
+android.icu.dev.test.collator.CollationCurrencyTest#TestCurrency
+android.icu.dev.test.collator.CollationDummyTest#TestExtra
+android.icu.dev.test.collator.CollationDummyTest#TestIdentical
+android.icu.dev.test.collator.CollationDummyTest#TestJB1401
+android.icu.dev.test.collator.CollationDummyTest#TestJB581
+android.icu.dev.test.collator.CollationDummyTest#TestPrimary
+android.icu.dev.test.collator.CollationDummyTest#TestSecondary
+android.icu.dev.test.collator.CollationDummyTest#TestSurrogates
+android.icu.dev.test.collator.CollationDummyTest#TestTertiary
+android.icu.dev.test.collator.CollationDummyTest#TestVariableTop
+android.icu.dev.test.collator.CollationEnglishTest#TestPrimary
+android.icu.dev.test.collator.CollationEnglishTest#TestSecondary
+android.icu.dev.test.collator.CollationEnglishTest#TestTertiary
+android.icu.dev.test.collator.CollationFinnishTest#TestPrimary
+android.icu.dev.test.collator.CollationFinnishTest#TestTertiary
+android.icu.dev.test.collator.CollationFrenchTest#TestContinuationReordering
+android.icu.dev.test.collator.CollationFrenchTest#TestExtra
+android.icu.dev.test.collator.CollationFrenchTest#TestSecondary
+android.icu.dev.test.collator.CollationFrenchTest#TestTertiary
+android.icu.dev.test.collator.CollationGermanTest#TestPrimary
+android.icu.dev.test.collator.CollationGermanTest#TestSecondary
+android.icu.dev.test.collator.CollationGermanTest#TestTertiary
+android.icu.dev.test.collator.CollationIteratorTest#TestClearBuffers
+android.icu.dev.test.collator.CollationIteratorTest#TestDiscontiguous
+android.icu.dev.test.collator.CollationIteratorTest#TestMaxExpansion
+android.icu.dev.test.collator.CollationIteratorTest#TestNormalization
+android.icu.dev.test.collator.CollationIteratorTest#TestNormalizedUnicodeChar
+android.icu.dev.test.collator.CollationIteratorTest#TestOffset
+android.icu.dev.test.collator.CollationIteratorTest#TestPrevious
+android.icu.dev.test.collator.CollationIteratorTest#TestSearchCollatorElements
+android.icu.dev.test.collator.CollationIteratorTest#TestSetText
+android.icu.dev.test.collator.CollationIteratorTest#TestUnicodeChar
+android.icu.dev.test.collator.CollationKanaTest#TestBase
+android.icu.dev.test.collator.CollationKanaTest#TestChooonKigoo
+android.icu.dev.test.collator.CollationKanaTest#TestCommonCharacters
+android.icu.dev.test.collator.CollationKanaTest#TestKatakanaHiragana
+android.icu.dev.test.collator.CollationKanaTest#TestPlainDakutenHandakuten
+android.icu.dev.test.collator.CollationKanaTest#TestSmallLarge
+android.icu.dev.test.collator.CollationKanaTest#TestTertiary
+android.icu.dev.test.collator.CollationMiscTest#Test3249
+android.icu.dev.test.collator.CollationMiscTest#Test6179
+android.icu.dev.test.collator.CollationMiscTest#TestBefore
+android.icu.dev.test.collator.CollationMiscTest#TestBeforePinyin
+android.icu.dev.test.collator.CollationMiscTest#TestBeforePrefixFailure
+android.icu.dev.test.collator.CollationMiscTest#TestBeforeRuleWithScriptReordering
+android.icu.dev.test.collator.CollationMiscTest#TestBlackBird
+android.icu.dev.test.collator.CollationMiscTest#TestBocsuCoverage
+android.icu.dev.test.collator.CollationMiscTest#TestCase
+android.icu.dev.test.collator.CollationMiscTest#TestChMove
+android.icu.dev.test.collator.CollationMiscTest#TestCollationKeyEquals
+android.icu.dev.test.collator.CollationMiscTest#TestCollationKeyHashCode
+android.icu.dev.test.collator.CollationMiscTest#TestComposeDecompose
+android.icu.dev.test.collator.CollationMiscTest#TestContraction
+android.icu.dev.test.collator.CollationMiscTest#TestContractionClosure
+android.icu.dev.test.collator.CollationMiscTest#TestContractionEndCompare
+android.icu.dev.test.collator.CollationMiscTest#TestCyrillicTailoring
+android.icu.dev.test.collator.CollationMiscTest#TestEmptyRule
+android.icu.dev.test.collator.CollationMiscTest#TestEquivalentReorderingScripts
+android.icu.dev.test.collator.CollationMiscTest#TestExpansion
+android.icu.dev.test.collator.CollationMiscTest#TestExtremeCompression
+android.icu.dev.test.collator.CollationMiscTest#TestFCDProblem
+android.icu.dev.test.collator.CollationMiscTest#TestFrozeness
+android.icu.dev.test.collator.CollationMiscTest#TestFunkyA
+android.icu.dev.test.collator.CollationMiscTest#TestGetBound
+android.icu.dev.test.collator.CollationMiscTest#TestGreekFirstReorder
+android.icu.dev.test.collator.CollationMiscTest#TestGreekFirstReorderCloning
+android.icu.dev.test.collator.CollationMiscTest#TestGreekLastReorder
+android.icu.dev.test.collator.CollationMiscTest#TestHangulTailoring
+android.icu.dev.test.collator.CollationMiscTest#TestHaniReorder
+android.icu.dev.test.collator.CollationMiscTest#TestHaniReorderWithOtherRules
+android.icu.dev.test.collator.CollationMiscTest#TestHungarianTailoring
+android.icu.dev.test.collator.CollationMiscTest#TestIdenticalCompare
+android.icu.dev.test.collator.CollationMiscTest#TestImplicitTailoring
+android.icu.dev.test.collator.CollationMiscTest#TestIncompleteCnt
+android.icu.dev.test.collator.CollationMiscTest#TestIncrementalNormalize
+android.icu.dev.test.collator.CollationMiscTest#TestInvalidListsAndRanges
+android.icu.dev.test.collator.CollationMiscTest#TestJ3087
+android.icu.dev.test.collator.CollationMiscTest#TestJ3347
+android.icu.dev.test.collator.CollationMiscTest#TestJ4960
+android.icu.dev.test.collator.CollationMiscTest#TestJ5367
+android.icu.dev.test.collator.CollationMiscTest#TestJ815
+android.icu.dev.test.collator.CollationMiscTest#TestJB5298
+android.icu.dev.test.collator.CollationMiscTest#TestLocaleRuleBasedCollators
+android.icu.dev.test.collator.CollationMiscTest#TestMaxVariable
+android.icu.dev.test.collator.CollationMiscTest#TestMerge
+android.icu.dev.test.collator.CollationMiscTest#TestMergeSortKeys
+android.icu.dev.test.collator.CollationMiscTest#TestMultipleReorder
+android.icu.dev.test.collator.CollationMiscTest#TestNewJapanese
+android.icu.dev.test.collator.CollationMiscTest#TestNonChars
+android.icu.dev.test.collator.CollationMiscTest#TestNonLeadBytesDuringCollationReordering
+android.icu.dev.test.collator.CollationMiscTest#TestNonScriptReorder
+android.icu.dev.test.collator.CollationMiscTest#TestNumericCollation
+android.icu.dev.test.collator.CollationMiscTest#TestOptimize
+android.icu.dev.test.collator.CollationMiscTest#TestPinyinProblem
+android.icu.dev.test.collator.CollationMiscTest#TestPrefix
+android.icu.dev.test.collator.CollationMiscTest#TestPrefixCompose
+android.icu.dev.test.collator.CollationMiscTest#TestQuoteAndSpace
+android.icu.dev.test.collator.CollationMiscTest#TestRawCollationKeyCompareTo
+android.icu.dev.test.collator.CollationMiscTest#TestReorderingAPI
+android.icu.dev.test.collator.CollationMiscTest#TestReorderingAPIWithRuleCreatedCollator
+android.icu.dev.test.collator.CollationMiscTest#TestRuleOptions
+android.icu.dev.test.collator.CollationMiscTest#TestSameStrengthList
+android.icu.dev.test.collator.CollationMiscTest#TestSameStrengthListQuoted
+android.icu.dev.test.collator.CollationMiscTest#TestSameStrengthListQwerty
+android.icu.dev.test.collator.CollationMiscTest#TestSameStrengthListRanges
+android.icu.dev.test.collator.CollationMiscTest#TestSameStrengthListRangesWithSupplementalCharacters
+android.icu.dev.test.collator.CollationMiscTest#TestSameStrengthListWithSupplementalCharacters
+android.icu.dev.test.collator.CollationMiscTest#TestShifted
+android.icu.dev.test.collator.CollationMiscTest#TestSpecialCharacters
+android.icu.dev.test.collator.CollationMiscTest#TestStrCollIdenticalPrefix
+android.icu.dev.test.collator.CollationMiscTest#TestSuppressContractions
+android.icu.dev.test.collator.CollationMiscTest#TestSurrogates
+android.icu.dev.test.collator.CollationMiscTest#TestTibetanConformance
+android.icu.dev.test.collator.CollationMiscTest#TestUCAPrecontext
+android.icu.dev.test.collator.CollationMiscTest#TestUnknownCollationKeyword
+android.icu.dev.test.collator.CollationMiscTest#TestUpperFirstQuaternary
+android.icu.dev.test.collator.CollationMiscTest#TestVariableTop
+android.icu.dev.test.collator.CollationMiscTest#TestVariableTopSetting
+android.icu.dev.test.collator.CollationMiscTest#TestVI5913
+android.icu.dev.test.collator.CollationMonkeyTest#TestCollationKey
+android.icu.dev.test.collator.CollationMonkeyTest#TestCompare
+android.icu.dev.test.collator.CollationMonkeyTest#TestRules
+android.icu.dev.test.collator.CollationRegressionTest#Test4048446
+android.icu.dev.test.collator.CollationRegressionTest#Test4051866
+android.icu.dev.test.collator.CollationRegressionTest#Test4053636
+android.icu.dev.test.collator.CollationRegressionTest#Test4054238
+android.icu.dev.test.collator.CollationRegressionTest#Test4054734
+android.icu.dev.test.collator.CollationRegressionTest#Test4054736
+android.icu.dev.test.collator.CollationRegressionTest#Test4058613
+android.icu.dev.test.collator.CollationRegressionTest#Test4059820
+android.icu.dev.test.collator.CollationRegressionTest#Test4060154
+android.icu.dev.test.collator.CollationRegressionTest#Test4062418
+android.icu.dev.test.collator.CollationRegressionTest#Test4065540
+android.icu.dev.test.collator.CollationRegressionTest#Test4066189
+android.icu.dev.test.collator.CollationRegressionTest#Test4066696
+android.icu.dev.test.collator.CollationRegressionTest#Test4076676
+android.icu.dev.test.collator.CollationRegressionTest#Test4078588
+android.icu.dev.test.collator.CollationRegressionTest#Test4079231
+android.icu.dev.test.collator.CollationRegressionTest#Test4081866
+android.icu.dev.test.collator.CollationRegressionTest#Test4087241
+android.icu.dev.test.collator.CollationRegressionTest#Test4087243
+android.icu.dev.test.collator.CollationRegressionTest#Test4092260
+android.icu.dev.test.collator.CollationRegressionTest#Test4095316
+android.icu.dev.test.collator.CollationRegressionTest#Test4101940
+android.icu.dev.test.collator.CollationRegressionTest#Test4103436
+android.icu.dev.test.collator.CollationRegressionTest#Test4114076
+android.icu.dev.test.collator.CollationRegressionTest#Test4114077
+android.icu.dev.test.collator.CollationRegressionTest#Test4124632
+android.icu.dev.test.collator.CollationRegressionTest#Test4132736
+android.icu.dev.test.collator.CollationRegressionTest#Test4133509
+android.icu.dev.test.collator.CollationRegressionTest#Test4139572
+android.icu.dev.test.collator.CollationRegressionTest#Test4141640
+android.icu.dev.test.collator.CollationRegressionTest#Test4171974
+android.icu.dev.test.collator.CollationRegressionTest#Test4179216
+android.icu.dev.test.collator.CollationRegressionTest#Test4179686
+android.icu.dev.test.collator.CollationRegressionTest#Test4216006
+android.icu.dev.test.collator.CollationRegressionTest#Test4244884
+android.icu.dev.test.collator.CollationRegressionTest#Test4663220
+android.icu.dev.test.collator.CollationRegressionTest#Test8484
+android.icu.dev.test.collator.CollationRegressionTest#TestBeforeWithTooStrongAfter
+android.icu.dev.test.collator.CollationRegressionTest#TestBengaliSortKey
+android.icu.dev.test.collator.CollationRegressionTest#TestCaseFirstCompression
+android.icu.dev.test.collator.CollationRegressionTest#TestTrailingComment
+android.icu.dev.test.collator.CollationServiceTest#TestGetFunctionalEquivalent
+android.icu.dev.test.collator.CollationServiceTest#TestGetKeywordValues
+android.icu.dev.test.collator.CollationServiceTest#TestRegister
+android.icu.dev.test.collator.CollationServiceTest#TestRegisterFactory
+android.icu.dev.test.collator.CollationServiceTest#TestSeparateTrees
+android.icu.dev.test.collator.CollationSpanishTest#TestPrimary
+android.icu.dev.test.collator.CollationSpanishTest#TestTertiary
+android.icu.dev.test.collator.CollationTest#TestCollationWeights
+android.icu.dev.test.collator.CollationTest#TestFCD
+android.icu.dev.test.collator.CollationTest#TestImplicits
+android.icu.dev.test.collator.CollationTest#TestMinMax
+android.icu.dev.test.collator.CollationTest#TestRootElements
+android.icu.dev.test.collator.CollationTest#TestShortFCDData
+android.icu.dev.test.collator.CollationTest#TestSubSequence
+android.icu.dev.test.collator.CollationTest#TestTailoredElements
+android.icu.dev.test.collator.CollationThaiTest#TestCornerCases
+android.icu.dev.test.collator.CollationThaiTest#TestDictionary
+android.icu.dev.test.collator.CollationThaiTest#TestInvalidThai
+android.icu.dev.test.collator.CollationThaiTest#TestReordering
+android.icu.dev.test.collator.CollationThreadTest#testFrozen
+android.icu.dev.test.collator.CollationThreadTest#testThreads
+android.icu.dev.test.collator.CollationTurkishTest#TestPrimary
+android.icu.dev.test.collator.CollationTurkishTest#TestTertiary
+android.icu.dev.test.collator.G7CollationTest#TestDemo1
+android.icu.dev.test.collator.G7CollationTest#TestDemo2
+android.icu.dev.test.collator.G7CollationTest#TestDemo3
+android.icu.dev.test.collator.G7CollationTest#TestDemo4
+android.icu.dev.test.collator.LotusCollationKoreanTest#TestTertiary
+android.icu.dev.test.collator.UCAConformanceTest#TestRulesNonIgnorable
+android.icu.dev.test.collator.UCAConformanceTest#TestRulesShifted
+android.icu.dev.test.collator.UCAConformanceTest#TestTableNonIgnorable
+android.icu.dev.test.collator.UCAConformanceTest#TestTableShifted
+android.icu.dev.test.compression.DecompressionTest#TestDecompress
+android.icu.dev.test.compression.DecompressionTest#TestDecompression
+android.icu.dev.test.compression.ExhaustiveTest#testIterative
+android.icu.dev.test.compression.ExhaustiveTest#testMultipass
+android.icu.dev.test.compression.ExhaustiveTest#testSimple
+android.icu.dev.test.duration.DataReadWriteTest#testBool
+android.icu.dev.test.duration.DataReadWriteTest#testBoolArray
+android.icu.dev.test.duration.DataReadWriteTest#testCharacter
+android.icu.dev.test.duration.DataReadWriteTest#testCharacterArray
+android.icu.dev.test.duration.DataReadWriteTest#testNamedIndex
+android.icu.dev.test.duration.DataReadWriteTest#testNamedIndexArray
+android.icu.dev.test.duration.DataReadWriteTest#testOmittedFields
+android.icu.dev.test.duration.DataReadWriteTest#testOpenClose
+android.icu.dev.test.duration.DataReadWriteTest#testString
+android.icu.dev.test.duration.DataReadWriteTest#testStringArray
+android.icu.dev.test.duration.DataReadWriteTest#testStringTable
+android.icu.dev.test.duration.ICUDurationTest#TestBadLocaleError
+android.icu.dev.test.duration.ICUDurationTest#TestBadObjectError
+android.icu.dev.test.duration.ICUDurationTest#TestBasics
+android.icu.dev.test.duration.ICUDurationTest#TestDurationFormat
+android.icu.dev.test.duration.ICUDurationTest#TestFromNowTo
+android.icu.dev.test.duration.ICUDurationTest#TestResourceWithCalendar
+android.icu.dev.test.duration.ICUDurationTest#TestSimpleXMLDuration
+android.icu.dev.test.duration.ICUDurationTest#TestXMLDuration
+android.icu.dev.test.duration.languages.Test_en#testCustomMinutes
+android.icu.dev.test.duration.languages.Test_en#testFractionalUnits
+android.icu.dev.test.duration.languages.Test_en#testFullPluralizedForms
+android.icu.dev.test.duration.languages.Test_en#testHalfUnits
+android.icu.dev.test.duration.languages.Test_en#testLimitedUnits
+android.icu.dev.test.duration.languages.Test_en#testMediumForms
+android.icu.dev.test.duration.languages.Test_en#testMultipleUnits
+android.icu.dev.test.duration.languages.Test_en#testShortForms
+android.icu.dev.test.duration.languages.Test_es#testCustomMinutes
+android.icu.dev.test.duration.languages.Test_es#testFractionalUnits
+android.icu.dev.test.duration.languages.Test_es#testFullPluralizedForms
+android.icu.dev.test.duration.languages.Test_es#testHalfUnits
+android.icu.dev.test.duration.languages.Test_es#testLimitedUnits
+android.icu.dev.test.duration.languages.Test_es#testMediumForms
+android.icu.dev.test.duration.languages.Test_es#testMultipleUnits
+android.icu.dev.test.duration.languages.Test_es#testShortForms
+android.icu.dev.test.duration.languages.Test_fr#testCustomMinutes
+android.icu.dev.test.duration.languages.Test_fr#testFractionalUnits
+android.icu.dev.test.duration.languages.Test_fr#testFullPluralizedForms
+android.icu.dev.test.duration.languages.Test_fr#testHalfUnits
+android.icu.dev.test.duration.languages.Test_fr#testLimitedUnits
+android.icu.dev.test.duration.languages.Test_fr#testMediumForms
+android.icu.dev.test.duration.languages.Test_fr#testMultipleUnits
+android.icu.dev.test.duration.languages.Test_fr#testShortForms
+android.icu.dev.test.duration.languages.Test_he_IL#testCustomMinutes
+android.icu.dev.test.duration.languages.Test_he_IL#testFractionalUnits
+android.icu.dev.test.duration.languages.Test_he_IL#testFullPluralizedForms
+android.icu.dev.test.duration.languages.Test_he_IL#testHalfUnits
+android.icu.dev.test.duration.languages.Test_he_IL#testLimitedUnits
+android.icu.dev.test.duration.languages.Test_he_IL#testMediumForms
+android.icu.dev.test.duration.languages.Test_he_IL#testMultipleUnits
+android.icu.dev.test.duration.languages.Test_he_IL#testShortForms
+android.icu.dev.test.duration.languages.Test_hi#testCustomMinutes
+android.icu.dev.test.duration.languages.Test_hi#testFractionalUnits
+android.icu.dev.test.duration.languages.Test_hi#testFullPluralizedForms
+android.icu.dev.test.duration.languages.Test_hi#testHalfUnits
+android.icu.dev.test.duration.languages.Test_hi#testLimitedUnits
+android.icu.dev.test.duration.languages.Test_hi#testMediumForms
+android.icu.dev.test.duration.languages.Test_hi#testMonthNames
+android.icu.dev.test.duration.languages.Test_hi#testMultipleUnits
+android.icu.dev.test.duration.languages.Test_hi#testShortForms
+android.icu.dev.test.duration.languages.Test_it#testCustomMinutes
+android.icu.dev.test.duration.languages.Test_it#testFractionalUnits
+android.icu.dev.test.duration.languages.Test_it#testFullPluralizedForms
+android.icu.dev.test.duration.languages.Test_it#testHalfUnits
+android.icu.dev.test.duration.languages.Test_it#testLimitedUnits
+android.icu.dev.test.duration.languages.Test_it#testMediumForms
+android.icu.dev.test.duration.languages.Test_it#testMultipleUnits
+android.icu.dev.test.duration.languages.Test_it#testShortForms
+android.icu.dev.test.duration.languages.Test_ja#testCustomMinutes
+android.icu.dev.test.duration.languages.Test_ja#testFractionalUnits
+android.icu.dev.test.duration.languages.Test_ja#testFullPluralizedForms
+android.icu.dev.test.duration.languages.Test_ja#testHalfUnits
+android.icu.dev.test.duration.languages.Test_ja#testLimitedUnits
+android.icu.dev.test.duration.languages.Test_ja#testMediumForms
+android.icu.dev.test.duration.languages.Test_ja#testMultipleUnits
+android.icu.dev.test.duration.languages.Test_ja#testNoMillis
+android.icu.dev.test.duration.languages.Test_ja#testOmitZeros
+android.icu.dev.test.duration.languages.Test_ja#testShortForms
+android.icu.dev.test.duration.languages.Test_ko#testCustomMinutes
+android.icu.dev.test.duration.languages.Test_ko#testFractionalUnits
+android.icu.dev.test.duration.languages.Test_ko#testFullPluralizedForms
+android.icu.dev.test.duration.languages.Test_ko#testHalfUnits
+android.icu.dev.test.duration.languages.Test_ko#testLimitedUnits
+android.icu.dev.test.duration.languages.Test_ko#testMediumForms
+android.icu.dev.test.duration.languages.Test_ko#testMultipleUnits
+android.icu.dev.test.duration.languages.Test_ko#testShortForms
+android.icu.dev.test.duration.languages.Test_zh_Hans_SG#testCustomMinutes
+android.icu.dev.test.duration.languages.Test_zh_Hans_SG#testFractionalUnits
+android.icu.dev.test.duration.languages.Test_zh_Hans_SG#testFullPluralizedForms
+android.icu.dev.test.duration.languages.Test_zh_Hans_SG#testHalfUnits
+android.icu.dev.test.duration.languages.Test_zh_Hans_SG#testLimitedUnits
+android.icu.dev.test.duration.languages.Test_zh_Hans_SG#testMediumForms
+android.icu.dev.test.duration.languages.Test_zh_Hans_SG#testMultipleUnits
+android.icu.dev.test.duration.languages.Test_zh_Hans_SG#testShortForms
+android.icu.dev.test.duration.languages.Test_zh_Hans#testCustomMinutes
+android.icu.dev.test.duration.languages.Test_zh_Hans#testFractionalUnits
+android.icu.dev.test.duration.languages.Test_zh_Hans#testFullPluralizedForms
+android.icu.dev.test.duration.languages.Test_zh_Hans#testHalfUnits
+android.icu.dev.test.duration.languages.Test_zh_Hans#testLimitedUnits
+android.icu.dev.test.duration.languages.Test_zh_Hans#testMediumForms
+android.icu.dev.test.duration.languages.Test_zh_Hans#testMultipleUnits
+android.icu.dev.test.duration.languages.Test_zh_Hans#testShortForms
+android.icu.dev.test.duration.languages.Test_zh_Hant_HK#testCustomMinutes
+android.icu.dev.test.duration.languages.Test_zh_Hant_HK#testFractionalUnits
+android.icu.dev.test.duration.languages.Test_zh_Hant_HK#testFullPluralizedForms
+android.icu.dev.test.duration.languages.Test_zh_Hant_HK#testHalfUnits
+android.icu.dev.test.duration.languages.Test_zh_Hant_HK#testLimitedUnits
+android.icu.dev.test.duration.languages.Test_zh_Hant_HK#testMediumForms
+android.icu.dev.test.duration.languages.Test_zh_Hant_HK#testMultipleUnits
+android.icu.dev.test.duration.languages.Test_zh_Hant_HK#testShortForms
+android.icu.dev.test.duration.languages.Test_zh_Hant#testCustomMinutes
+android.icu.dev.test.duration.languages.Test_zh_Hant#testFractionalUnits
+android.icu.dev.test.duration.languages.Test_zh_Hant#testFullPluralizedForms
+android.icu.dev.test.duration.languages.Test_zh_Hant#testHalfUnits
+android.icu.dev.test.duration.languages.Test_zh_Hant#testLimitedUnits
+android.icu.dev.test.duration.languages.Test_zh_Hant#testMediumForms
+android.icu.dev.test.duration.languages.Test_zh_Hant#testMultipleUnits
+android.icu.dev.test.duration.languages.Test_zh_Hant#testShortForms
+android.icu.dev.test.duration.PeriodBuilderFactoryTest#testBuilderFactoryPeriodConstruction
+android.icu.dev.test.duration.PeriodBuilderFactoryTest#testSetAvailableUnitRange
+android.icu.dev.test.duration.PeriodBuilderFactoryTest#testSetUnitIsAvailable
+android.icu.dev.test.duration.PeriodTest#testAnd
+android.icu.dev.test.duration.PeriodTest#testFuturePast
+android.icu.dev.test.duration.PeriodTest#testInvalidCount
+android.icu.dev.test.duration.PeriodTest#testIsSet
+android.icu.dev.test.duration.PeriodTest#testMoreLessThan
+android.icu.dev.test.duration.ResourceBasedPeriodFormatterDataServiceTest#testAvailable
+android.icu.dev.test.format.BigNumberFormatTest#Test4161100
+android.icu.dev.test.format.BigNumberFormatTest#TestAlphaBigDecimal
+android.icu.dev.test.format.BigNumberFormatTest#TestBigDecimalJ28
+android.icu.dev.test.format.BigNumberFormatTest#TestBigDecimalRounding
+android.icu.dev.test.format.BigNumberFormatTest#TestExponent
+android.icu.dev.test.format.BigNumberFormatTest#TestPad
+android.icu.dev.test.format.BigNumberFormatTest#TestPatterns
+android.icu.dev.test.format.BigNumberFormatTest#TestScientific
+android.icu.dev.test.format.BigNumberFormatTest#TestSecondaryGrouping
+android.icu.dev.test.format.CompactDecimalFormatTest#TestACoreCompactFormat
+android.icu.dev.test.format.CompactDecimalFormatTest#TestArabicLongStyle
+android.icu.dev.test.format.CompactDecimalFormatTest#TestCharacterIterator
+android.icu.dev.test.format.CompactDecimalFormatTest#TestCsShort
+android.icu.dev.test.format.CompactDecimalFormatTest#TestDefaultSignificantDigits
+android.icu.dev.test.format.CompactDecimalFormatTest#TestEnglishShort
+android.icu.dev.test.format.CompactDecimalFormatTest#TestEquals
+android.icu.dev.test.format.CompactDecimalFormatTest#TestFieldPosition
+android.icu.dev.test.format.CompactDecimalFormatTest#TestJapaneseShort
+android.icu.dev.test.format.CompactDecimalFormatTest#TestSerbianLong
+android.icu.dev.test.format.CompactDecimalFormatTest#TestSerbianLongNegative
+android.icu.dev.test.format.CompactDecimalFormatTest#TestSerbianShort
+android.icu.dev.test.format.CompactDecimalFormatTest#TestSkLong
+android.icu.dev.test.format.CompactDecimalFormatTest#TestSwahiliShort
+android.icu.dev.test.format.CompactDecimalFormatTest#TestSwahiliShortNegative
+android.icu.dev.test.format.DataDrivenFormatTest#TestConsistentPivot
+android.icu.dev.test.format.DataDrivenFormatTest#TestDateFormatBasic
+android.icu.dev.test.format.DataDrivenFormatTest#TestFormatRelative
+android.icu.dev.test.format.DataDrivenFormatTest#TestHebrew
+android.icu.dev.test.format.DataDrivenFormatTest#TestMoreDateParse
+android.icu.dev.test.format.DataDrivenFormatTest#TestYearLengths
+android.icu.dev.test.format.DateFormatMiscTests#Test4097450
+android.icu.dev.test.format.DateFormatMiscTests#Test4099975new
+android.icu.dev.test.format.DateFormatMiscTests#Test4117335
+android.icu.dev.test.format.DateFormatRegressionTestJ#Test4103926
+android.icu.dev.test.format.DateFormatRegressionTestJ#Test4148168
+android.icu.dev.test.format.DateFormatRegressionTestJ#Test4213086
+android.icu.dev.test.format.DateFormatRegressionTestJ#Test4250359
+android.icu.dev.test.format.DateFormatRegressionTestJ#Test4253490
+android.icu.dev.test.format.DateFormatRegressionTestJ#Test4266432
+android.icu.dev.test.format.DateFormatRegressionTestJ#Test4358730
+android.icu.dev.test.format.DateFormatRegressionTestJ#Test4375399
+android.icu.dev.test.format.DateFormatRegressionTestJ#Test4468663
+android.icu.dev.test.format.DateFormatRegressionTest#Test4029195
+android.icu.dev.test.format.DateFormatRegressionTest#Test4052408
+android.icu.dev.test.format.DateFormatRegressionTest#Test4056591
+android.icu.dev.test.format.DateFormatRegressionTest#Test4059917
+android.icu.dev.test.format.DateFormatRegressionTest#Test4060212
+android.icu.dev.test.format.DateFormatRegressionTest#Test4061287
+android.icu.dev.test.format.DateFormatRegressionTest#Test4065240
+android.icu.dev.test.format.DateFormatRegressionTest#Test4071441
+android.icu.dev.test.format.DateFormatRegressionTest#Test4073003
+android.icu.dev.test.format.DateFormatRegressionTest#Test4089106
+android.icu.dev.test.format.DateFormatRegressionTest#Test4100302
+android.icu.dev.test.format.DateFormatRegressionTest#Test4101483
+android.icu.dev.test.format.DateFormatRegressionTest#Test4103340
+android.icu.dev.test.format.DateFormatRegressionTest#Test4103341
+android.icu.dev.test.format.DateFormatRegressionTest#Test4104136
+android.icu.dev.test.format.DateFormatRegressionTest#Test4104522
+android.icu.dev.test.format.DateFormatRegressionTest#Test4106807
+android.icu.dev.test.format.DateFormatRegressionTest#Test4108407
+android.icu.dev.test.format.DateFormatRegressionTest#Test4134203
+android.icu.dev.test.format.DateFormatRegressionTest#Test4151631
+android.icu.dev.test.format.DateFormatRegressionTest#Test4151706
+android.icu.dev.test.format.DateFormatRegressionTest#Test4162071
+android.icu.dev.test.format.DateFormatRegressionTest#Test4182066
+android.icu.dev.test.format.DateFormatRegressionTest#Test4210209
+android.icu.dev.test.format.DateFormatRegressionTest#Test5006GetShortMonths
+android.icu.dev.test.format.DateFormatRegressionTest#Test714
+android.icu.dev.test.format.DateFormatRegressionTest#TestDangiFormat
+android.icu.dev.test.format.DateFormatRegressionTest#Test_GEec
+android.icu.dev.test.format.DateFormatRegressionTest#TestHindiArabicDigits
+android.icu.dev.test.format.DateFormatRegressionTest#TestParsing
+android.icu.dev.test.format.DateFormatRegressionTest#TestT10110
+android.icu.dev.test.format.DateFormatRegressionTest#TestT10239
+android.icu.dev.test.format.DateFormatRegressionTest#TestT10334
+android.icu.dev.test.format.DateFormatRegressionTest#TestT10619
+android.icu.dev.test.format.DateFormatRegressionTest#TestT10906
+android.icu.dev.test.format.DateFormatRegressionTest#TestT11363
+android.icu.dev.test.format.DateFormatRegressionTest#TestT5683
+android.icu.dev.test.format.DateFormatRoundTripTest#TestDateFormatRoundTrip
+android.icu.dev.test.format.DateFormatTest#Test10632
+android.icu.dev.test.format.DateFormatTest#Test6880
+android.icu.dev.test.format.DateFormatTest#TestBadInput135
+android.icu.dev.test.format.DateFormatTest#TestBadInput135a
+android.icu.dev.test.format.DateFormatTest#TestCalendarType
+android.icu.dev.test.format.DateFormatTest#TestChineseDateFormatLocalizedPatternChars
+android.icu.dev.test.format.DateFormatTest#TestChineseDateFormatSymbols
+android.icu.dev.test.format.DateFormatTest#TestContext
+android.icu.dev.test.format.DateFormatTest#TestCoverage
+android.icu.dev.test.format.DateFormatTest#TestCzechMonths459
+android.icu.dev.test.format.DateFormatTest#TestDateFormatCalendar
+android.icu.dev.test.format.DateFormatTest#TestDateFormatLeniency
+android.icu.dev.test.format.DateFormatTest#TestDateFormatNone
+android.icu.dev.test.format.DateFormatTest#TestDateFormatZone061
+android.icu.dev.test.format.DateFormatTest#TestDateFormatZone146
+android.icu.dev.test.format.DateFormatTest#TestDayOfYearPattern195
+android.icu.dev.test.format.DateFormatTest#TestDotAndAtLeniency
+android.icu.dev.test.format.DateFormatTest#TestEquals
+android.icu.dev.test.format.DateFormatTest#TestEras
+android.icu.dev.test.format.DateFormatTest#TestErrorChecking
+android.icu.dev.test.format.DateFormatTest#TestExactCountFormat
+android.icu.dev.test.format.DateFormatTest#TestFieldPosition
+android.icu.dev.test.format.DateFormatTest#TestFormalChineseDate
+android.icu.dev.test.format.DateFormatTest#TestFormattingLocaleTimeSeparator
+android.icu.dev.test.format.DateFormatTest#TestFormatToCharacterIterator
+android.icu.dev.test.format.DateFormatTest#TestFormatToCharacterIteratorCoverage
+android.icu.dev.test.format.DateFormatTest#TestGeneral
+android.icu.dev.test.format.DateFormatTest#TestGenericTime
+android.icu.dev.test.format.DateFormatTest#TestGenericTimeZoneOrder
+android.icu.dev.test.format.DateFormatTest#TestGetPatternInstance
+android.icu.dev.test.format.DateFormatTest#TestGMTParsing
+android.icu.dev.test.format.DateFormatTest#TestGreekMay
+android.icu.dev.test.format.DateFormatTest#TestInvalidPattern
+android.icu.dev.test.format.DateFormatTest#TestISOEra
+android.icu.dev.test.format.DateFormatTest#TestLetterDPattern212
+android.icu.dev.test.format.DateFormatTest#TestLocaleDateFormat
+android.icu.dev.test.format.DateFormatTest#TestLongContiguousNumericPattern
+android.icu.dev.test.format.DateFormatTest#TestLongNumericPattern
+android.icu.dev.test.format.DateFormatTest#TestMonthPatterns
+android.icu.dev.test.format.DateFormatTest#TestNarrowNames
+android.icu.dev.test.format.DateFormatTest#TestNonGregoFmtParse
+android.icu.dev.test.format.DateFormatTest#TestOfCalendarField
+android.icu.dev.test.format.DateFormatTest#TestOverrideNumberForamt
+android.icu.dev.test.format.DateFormatTest#TestParseLeniencyAPIs
+android.icu.dev.test.format.DateFormatTest#TestParseMultiPatternMatch
+android.icu.dev.test.format.DateFormatTest#TestParsePosition
+android.icu.dev.test.format.DateFormatTest#TestPartialParse994
+android.icu.dev.test.format.DateFormatTest#TestPatterns
+android.icu.dev.test.format.DateFormatTest#TestQuarters
+android.icu.dev.test.format.DateFormatTest#TestQuotePattern161
+android.icu.dev.test.format.DateFormatTest#TestRelativeDateFormat
+android.icu.dev.test.format.DateFormatTest#TestRoundtripWithCalendar
+android.icu.dev.test.format.DateFormatTest#TestRunTogetherPattern917
+android.icu.dev.test.format.DateFormatTest#TestRunTogetherPattern985
+android.icu.dev.test.format.DateFormatTest#TestShortDays
+android.icu.dev.test.format.DateFormatTest#TestSimpleDateFormatConstructor_String_String_ULocale
+android.icu.dev.test.format.DateFormatTest#TestSpaceParsing
+android.icu.dev.test.format.DateFormatTest#TestStandAloneDays
+android.icu.dev.test.format.DateFormatTest#TestStandAloneMonths
+android.icu.dev.test.format.DateFormatTest#TestTimeZoneDisplayName
+android.icu.dev.test.format.DateFormatTest#TestTwoDigitWOY
+android.icu.dev.test.format.DateFormatTest#TestTwoDigitYear
+android.icu.dev.test.format.DateFormatTest#TestTwoDigitYearDSTParse
+android.icu.dev.test.format.DateFormatTest#TestWallyWedel
+android.icu.dev.test.format.DateFormatTest#TestWhiteSpaceParsing
+android.icu.dev.test.format.DateIntervalFormatTest#TestClone
+android.icu.dev.test.format.DateIntervalFormatTest#TestCloseAsThawed
+android.icu.dev.test.format.DateIntervalFormatTest#TestConstructor
+android.icu.dev.test.format.DateIntervalFormatTest#TestDateIntervalCoverage
+android.icu.dev.test.format.DateIntervalFormatTest#TestDateIntervalInfoEquals
+android.icu.dev.test.format.DateIntervalFormatTest#TestFormat
+android.icu.dev.test.format.DateIntervalFormatTest#TestFormatCLDR
+android.icu.dev.test.format.DateIntervalFormatTest#TestFormatUserDII
+android.icu.dev.test.format.DateIntervalFormatTest#TestFPos_SkelWithSeconds
+android.icu.dev.test.format.DateIntervalFormatTest#TestGetIntervalPattern
+android.icu.dev.test.format.DateIntervalFormatTest#TestGetSetTimeZone
+android.icu.dev.test.format.DateIntervalFormatTest#TestHashCode
+android.icu.dev.test.format.DateIntervalFormatTest#TestIsFrozen
+android.icu.dev.test.format.DateIntervalFormatTest#TestPattternInfoEquals
+android.icu.dev.test.format.DateIntervalFormatTest#TestSetFallbackIntervalPattern
+android.icu.dev.test.format.DateIntervalFormatTest#TestSetIntervalPattern
+android.icu.dev.test.format.DateIntervalFormatTest#TestSetIntervalPatternNoSideEffect
+android.icu.dev.test.format.DateIntervalFormatTest#TestStress
+android.icu.dev.test.format.DateIntervalFormatTest#TestT6396
+android.icu.dev.test.format.DateIntervalFormatTest#TestTicket11583
+android.icu.dev.test.format.DateIntervalFormatTest#TestTicket9914
+android.icu.dev.test.format.DateIntervalFormatTest#TestTicket9919GetInstance
+android.icu.dev.test.format.DateIntervalFormatTest#TestTicket9919Setter
+android.icu.dev.test.format.DateTimeGeneratorTest#TestAllFieldPatterns
+android.icu.dev.test.format.DateTimeGeneratorTest#TestBasic
+android.icu.dev.test.format.DateTimeGeneratorTest#TestCheckFrozen
+android.icu.dev.test.format.DateTimeGeneratorTest#TestClone
+android.icu.dev.test.format.DateTimeGeneratorTest#TestEmpty
+android.icu.dev.test.format.DateTimeGeneratorTest#TestFreezeAndCloneAsThawed
+android.icu.dev.test.format.DateTimeGeneratorTest#TestGetAppendItemFormat
+android.icu.dev.test.format.DateTimeGeneratorTest#TestGetAppendItemName
+android.icu.dev.test.format.DateTimeGeneratorTest#TestGetBaseSkeleton
+android.icu.dev.test.format.DateTimeGeneratorTest#TestGetBaseSkeletons
+android.icu.dev.test.format.DateTimeGeneratorTest#TestGetDecimal
+android.icu.dev.test.format.DateTimeGeneratorTest#TestGetFields
+android.icu.dev.test.format.DateTimeGeneratorTest#TestGetInstance
+android.icu.dev.test.format.DateTimeGeneratorTest#TestGetRedundants
+android.icu.dev.test.format.DateTimeGeneratorTest#TestGetSkeleton
+android.icu.dev.test.format.DateTimeGeneratorTest#TestGetSkeletons
+android.icu.dev.test.format.DateTimeGeneratorTest#TestHasDateAndTimeFields
+android.icu.dev.test.format.DateTimeGeneratorTest#TestIsSingleField
+android.icu.dev.test.format.DateTimeGeneratorTest#TestJavaLocale
+android.icu.dev.test.format.DateTimeGeneratorTest#TestOptions
+android.icu.dev.test.format.DateTimeGeneratorTest#TestOrdering
+android.icu.dev.test.format.DateTimeGeneratorTest#TestPatternParser
+android.icu.dev.test.format.DateTimeGeneratorTest#TestReplacingZoneString
+android.icu.dev.test.format.DateTimeGeneratorTest#TestRoot
+android.icu.dev.test.format.DateTimeGeneratorTest#TestSet
+android.icu.dev.test.format.DateTimeGeneratorTest#TestSimple
+android.icu.dev.test.format.DateTimeGeneratorTest#TestT7169
+android.icu.dev.test.format.DateTimeGeneratorTest#TestToString
+android.icu.dev.test.format.DateTimeGeneratorTest#TestVariableCharacters
+android.icu.dev.test.format.DateTimeGeneratorTest#TestVariableField_String
+android.icu.dev.test.format.GlobalizationPreferencesTest#TestBreakIterator
+android.icu.dev.test.format.GlobalizationPreferencesTest#TestCalendar
+android.icu.dev.test.format.GlobalizationPreferencesTest#TestCollator
+android.icu.dev.test.format.GlobalizationPreferencesTest#TestCurrency
+android.icu.dev.test.format.GlobalizationPreferencesTest#TestDateFormat
+android.icu.dev.test.format.GlobalizationPreferencesTest#TestDefault
+android.icu.dev.test.format.GlobalizationPreferencesTest#TestDisplayName
+android.icu.dev.test.format.GlobalizationPreferencesTest#TestFreezable
+android.icu.dev.test.format.GlobalizationPreferencesTest#TestJB5380
+android.icu.dev.test.format.GlobalizationPreferencesTest#TestNumberFormat
+android.icu.dev.test.format.GlobalizationPreferencesTest#TestResourceBundle
+android.icu.dev.test.format.GlobalizationPreferencesTest#TestSetLocales
+android.icu.dev.test.format.GlobalizationPreferencesTest#TestTerritory
+android.icu.dev.test.format.GlobalizationPreferencesTest#TestTimeZone
+android.icu.dev.test.format.IntlTestDateFormatAPIC#TestNameHiding
+android.icu.dev.test.format.IntlTestDateFormatAPI#TestAPI
+android.icu.dev.test.format.IntlTestDateFormatAPI#TestEquals
+android.icu.dev.test.format.IntlTestDateFormatSymbols#TestConstructorWithCalendar
+android.icu.dev.test.format.IntlTestDateFormatSymbols#TestGetEraNames
+android.icu.dev.test.format.IntlTestDateFormatSymbols#TestGetMonths
+android.icu.dev.test.format.IntlTestDateFormatSymbols#TestGetMonths2
+android.icu.dev.test.format.IntlTestDateFormatSymbols#TestGetWeekdays2
+android.icu.dev.test.format.IntlTestDateFormatSymbols#TestSymbols
+android.icu.dev.test.format.IntlTestDateFormat#TestAvailableLocales
+android.icu.dev.test.format.IntlTestDateFormat#TestFormat
+android.icu.dev.test.format.IntlTestDateFormat#TestRoundtrip
+android.icu.dev.test.format.IntlTestDateFormat#TestULocale
+android.icu.dev.test.format.IntlTestDecimalFormatAPIC#TestAPI
+android.icu.dev.test.format.IntlTestDecimalFormatAPIC#testFormatToCharacterIterator
+android.icu.dev.test.format.IntlTestDecimalFormatAPIC#TestRounding
+android.icu.dev.test.format.IntlTestDecimalFormatAPI#TestAPI
+android.icu.dev.test.format.IntlTestDecimalFormatAPI#testJB1871
+android.icu.dev.test.format.IntlTestDecimalFormatAPI#testJB4971
+android.icu.dev.test.format.IntlTestDecimalFormatAPI#testJB6134
+android.icu.dev.test.format.IntlTestDecimalFormatAPI#testJB6354
+android.icu.dev.test.format.IntlTestDecimalFormatAPI#testJB6648
+android.icu.dev.test.format.IntlTestDecimalFormatSymbolsC#TestSymbols
+android.icu.dev.test.format.IntlTestDecimalFormatSymbols#testCoverage
+android.icu.dev.test.format.IntlTestDecimalFormatSymbols#TestSymbols
+android.icu.dev.test.format.IntlTestNumberFormatAPI#TestAPI
+android.icu.dev.test.format.IntlTestNumberFormatAPI#TestCoverage
+android.icu.dev.test.format.IntlTestNumberFormat#TestAvailableLocales
+android.icu.dev.test.format.IntlTestNumberFormat#TestLocale
+android.icu.dev.test.format.IntlTestNumberFormat#TestMonster
+android.icu.dev.test.format.IntlTestSimpleDateFormatAPI#TestAPI
+android.icu.dev.test.format.IntlTestSimpleDateFormatAPI#TestCoverage
+android.icu.dev.test.format.ListFormatterTest#Test9946
+android.icu.dev.test.format.ListFormatterTest#TestBasic
+android.icu.dev.test.format.ListFormatterTest#TestCreatePatternForNumItems
+android.icu.dev.test.format.ListFormatterTest#TestEnglish
+android.icu.dev.test.format.ListFormatterTest#TestFromList
+android.icu.dev.test.format.ListFormatterTest#TestGetLocale
+android.icu.dev.test.format.ListFormatterTest#TestGetPatternForNumItemsException
+android.icu.dev.test.format.ListFormatterTest#TestJapanese
+android.icu.dev.test.format.ListFormatterTest#TestPatternOutOfOrder
+android.icu.dev.test.format.ListFormatterTest#TestSpecial
+android.icu.dev.test.format.MeasureUnitTest#Test10219FractionalPlurals
+android.icu.dev.test.format.MeasureUnitTest#testAUnit
+android.icu.dev.test.format.MeasureUnitTest#TestCompatible53_1
+android.icu.dev.test.format.MeasureUnitTest#TestCompatible54_1
+android.icu.dev.test.format.MeasureUnitTest#TestCompatible55_1
+android.icu.dev.test.format.MeasureUnitTest#TestCompatible56_1
+android.icu.dev.test.format.MeasureUnitTest#testCurrencies
+android.icu.dev.test.format.MeasureUnitTest#testCurrencyFormatLocale
+android.icu.dev.test.format.MeasureUnitTest#testCurrencyFormatStandInForMeasureFormat
+android.icu.dev.test.format.MeasureUnitTest#testDoubleZero
+android.icu.dev.test.format.MeasureUnitTest#testEqHashCode
+android.icu.dev.test.format.MeasureUnitTest#testEqHashCodeOfMeasure
+android.icu.dev.test.format.MeasureUnitTest#TestExamplesInDocs
+android.icu.dev.test.format.MeasureUnitTest#testFieldPosition
+android.icu.dev.test.format.MeasureUnitTest#testFieldPositionMultiple
+android.icu.dev.test.format.MeasureUnitTest#testFormatMeasuresOneArg
+android.icu.dev.test.format.MeasureUnitTest#testFormatMeasuresZeroArg
+android.icu.dev.test.format.MeasureUnitTest#TestFormatPeriodEn
+android.icu.dev.test.format.MeasureUnitTest#testFormatSingleArg
+android.icu.dev.test.format.MeasureUnitTest#testGetLocale
+android.icu.dev.test.format.MeasureUnitTest#testGram
+android.icu.dev.test.format.MeasureUnitTest#TestGreek
+android.icu.dev.test.format.MeasureUnitTest#testIndividualPluralFallback
+android.icu.dev.test.format.MeasureUnitTest#testMultiples
+android.icu.dev.test.format.MeasureUnitTest#testNumeratorPlurals
+android.icu.dev.test.format.MeasureUnitTest#testOldFormatBadArg
+android.icu.dev.test.format.MeasureUnitTest#testOldFormatWithArray
+android.icu.dev.test.format.MeasureUnitTest#testOldFormatWithList
+android.icu.dev.test.format.MeasureUnitTest#testParseObject
+android.icu.dev.test.format.MeasureUnitTest#TestSerial
+android.icu.dev.test.format.MeasureUnitTest#TestSerialFormatWidthEnum
+android.icu.dev.test.format.MeasureUnitTest#testSimplePer
+android.icu.dev.test.format.MeasureUnitTest#testUnitPerUnitResolution
+android.icu.dev.test.format.MessagePatternUtilTest#TestChoiceArg
+android.icu.dev.test.format.MessagePatternUtilTest#TestComplexArgs
+android.icu.dev.test.format.MessagePatternUtilTest#TestHello
+android.icu.dev.test.format.MessagePatternUtilTest#TestHelloWithApos
+android.icu.dev.test.format.MessagePatternUtilTest#TestHelloWithQuote
+android.icu.dev.test.format.MessagePatternUtilTest#TestNoneArg
+android.icu.dev.test.format.MessagePatternUtilTest#TestPluralArg
+android.icu.dev.test.format.MessagePatternUtilTest#TestPluralVariantsByType
+android.icu.dev.test.format.MessagePatternUtilTest#TestSelectArg
+android.icu.dev.test.format.MessagePatternUtilTest#TestSelectOrdinalArg
+android.icu.dev.test.format.MessagePatternUtilTest#TestSelectVariantsByType
+android.icu.dev.test.format.MessagePatternUtilTest#TestSimpleArg
+android.icu.dev.test.format.MessageRegression#Test4031438
+android.icu.dev.test.format.MessageRegression#Test4052223
+android.icu.dev.test.format.MessageRegression#Test4074764
+android.icu.dev.test.format.MessageRegression#Test4094906
+android.icu.dev.test.format.MessageRegression#Test4104976
+android.icu.dev.test.format.MessageRegression#Test4105380
+android.icu.dev.test.format.MessageRegression#Test4106659
+android.icu.dev.test.format.MessageRegression#Test4106660
+android.icu.dev.test.format.MessageRegression#Test4106661
+android.icu.dev.test.format.MessageRegression#Test4111739
+android.icu.dev.test.format.MessageRegression#Test4112104
+android.icu.dev.test.format.MessageRegression#Test4113018
+android.icu.dev.test.format.MessageRegression#Test4114739
+android.icu.dev.test.format.MessageRegression#Test4114743
+android.icu.dev.test.format.MessageRegression#Test4116444
+android.icu.dev.test.format.MessageRegression#Test4118592
+android.icu.dev.test.format.MessageRegression#Test4118594
+android.icu.dev.test.format.MessageRegression#Test4120552
+android.icu.dev.test.format.MessageRegression#Test4142938
+android.icu.dev.test.format.MessageRegression#Test4169959
+android.icu.dev.test.format.MessageRegression#test4232154
+android.icu.dev.test.format.MessageRegression#test4293229
+android.icu.dev.test.format.MessageRegression#testBugTestsWithNamesArguments
+android.icu.dev.test.format.MessageRegression#TestChoicePatternQuote
+android.icu.dev.test.format.MessageRegression#TestSerialization
+android.icu.dev.test.format.NumberFormatRegistrationTest#TestRegistration
+android.icu.dev.test.format.NumberFormatRegressionTest#Test4161100
+android.icu.dev.test.format.NumberFormatRegressionTest#Test4408066
+android.icu.dev.test.format.NumberFormatRegressionTest#TestJ691
+android.icu.dev.test.format.NumberFormatRegressionTest#TestJB5509
+android.icu.dev.test.format.NumberFormatRegressionTest#TestNBSPInPattern
+android.icu.dev.test.format.NumberFormatRegressionTest#TestSurrogatesParsing
+android.icu.dev.test.format.NumberFormatRegressionTest#TestT5698
+android.icu.dev.test.format.NumberFormatRegressionTest#TestT9293
+android.icu.dev.test.format.NumberFormatRoundTripTest#TestNumberFormatRoundTrip
+android.icu.dev.test.format.NumberFormatSpecificationTest#TestBasicPatterns
+android.icu.dev.test.format.NumberFormatSpecificationTest#TestNfSetters
+android.icu.dev.test.format.NumberFormatSpecificationTest#TestPadding
+android.icu.dev.test.format.NumberFormatSpecificationTest#TestPercent
+android.icu.dev.test.format.NumberFormatSpecificationTest#TestPerMilli
+android.icu.dev.test.format.NumberFormatSpecificationTest#TestRounding
+android.icu.dev.test.format.NumberFormatSpecificationTest#TestScientificNotation
+android.icu.dev.test.format.NumberFormatSpecificationTest#TestSignificantDigits
+android.icu.dev.test.format.NumberFormatTest#Test10419RoundingWith0FractionDigits
+android.icu.dev.test.format.NumberFormatTest#Test6816
+android.icu.dev.test.format.NumberFormatTest#TestAccountingCurrency
+android.icu.dev.test.format.NumberFormatTest#TestBigDecimalRounding
+android.icu.dev.test.format.NumberFormatTest#TestBug9936
+android.icu.dev.test.format.NumberFormatTest#TestCases
+android.icu.dev.test.format.NumberFormatTest#TestCompatibleCurrencies
+android.icu.dev.test.format.NumberFormatTest#TestComplexCurrency
+android.icu.dev.test.format.NumberFormatTest#TestContext
+android.icu.dev.test.format.NumberFormatTest#TestCoverage
+android.icu.dev.test.format.NumberFormatTest#TestCurrency
+android.icu.dev.test.format.NumberFormatTest#TestCurrencyAmountCoverage
+android.icu.dev.test.format.NumberFormatTest#TestCurrencyFormatForMixParsing
+android.icu.dev.test.format.NumberFormatTest#TestCurrencyFractionDigits
+android.icu.dev.test.format.NumberFormatTest#TestCurrencyIsoPluralFormat
+android.icu.dev.test.format.NumberFormatTest#TestCurrencyKeyword
+android.icu.dev.test.format.NumberFormatTest#TestCurrencyObject
+android.icu.dev.test.format.NumberFormatTest#TestCurrencyPatterns
+android.icu.dev.test.format.NumberFormatTest#TestCurrencyPlurals
+android.icu.dev.test.format.NumberFormatTest#TestCurrencySign
+android.icu.dev.test.format.NumberFormatTest#TestCurrencyUsage
+android.icu.dev.test.format.NumberFormatTest#TestCurrFmtNegSameAsPositive
+android.icu.dev.test.format.NumberFormatTest#TestCustomCurrencySignAndSeparator
+android.icu.dev.test.format.NumberFormatTest#TestDataDrivenICU
+android.icu.dev.test.format.NumberFormatTest#TestDecimalFormatCurrencyParse
+android.icu.dev.test.format.NumberFormatTest#TestExplicitParents
+android.icu.dev.test.format.NumberFormatTest#TestExponent
+android.icu.dev.test.format.NumberFormatTest#TestExponential
+android.icu.dev.test.format.NumberFormatTest#TestExponentParse
+android.icu.dev.test.format.NumberFormatTest#TestFieldPositionCurrency
+android.icu.dev.test.format.NumberFormatTest#TestFieldPositionDecimal
+android.icu.dev.test.format.NumberFormatTest#TestFieldPositionFraction
+android.icu.dev.test.format.NumberFormatTest#TestFieldPositionFractionButInteger
+android.icu.dev.test.format.NumberFormatTest#TestFieldPositionInteger
+android.icu.dev.test.format.NumberFormatTest#TestFormat
+android.icu.dev.test.format.NumberFormatTest#TestFormatAbstractImplCoverage
+android.icu.dev.test.format.NumberFormatTest#TestFormatToCharacterIteratorIssue11805
+android.icu.dev.test.format.NumberFormatTest#TestFormatToCharacterIteratorThread
+android.icu.dev.test.format.NumberFormatTest#TestGetAvailableLocales
+android.icu.dev.test.format.NumberFormatTest#TestGetInstance
+android.icu.dev.test.format.NumberFormatTest#TestIllegalPatterns
+android.icu.dev.test.format.NumberFormatTest#TestJB3832
+android.icu.dev.test.format.NumberFormatTest#TestJB5251
+android.icu.dev.test.format.NumberFormatTest#TestJB5358
+android.icu.dev.test.format.NumberFormatTest#TestLenientSymbolParsing
+android.icu.dev.test.format.NumberFormatTest#TestMiscCurrencyParsing
+android.icu.dev.test.format.NumberFormatTest#TestMultiCurrencySign
+android.icu.dev.test.format.NumberFormatTest#TestNegZeroRounding
+android.icu.dev.test.format.NumberFormatTest#TestNumberFormatFactory
+android.icu.dev.test.format.NumberFormatTest#TestNumberFormatTestTupleToString
+android.icu.dev.test.format.NumberFormatTest#TestNumberingSystemCoverage
+android.icu.dev.test.format.NumberFormatTest#TestNumberingSystems
+android.icu.dev.test.format.NumberFormatTest#TestPad
+android.icu.dev.test.format.NumberFormatTest#TestParse
+android.icu.dev.test.format.NumberFormatTest#TestParseCurrency
+android.icu.dev.test.format.NumberFormatTest#TestParseCurrencyTrailingSymbol
+android.icu.dev.test.format.NumberFormatTest#TestParseMaxDigits
+android.icu.dev.test.format.NumberFormatTest#TestParseNegativeWithAlternativeMinusSign
+android.icu.dev.test.format.NumberFormatTest#TestParseNegativeWithFaLocale
+android.icu.dev.test.format.NumberFormatTest#TestParseRequiredDecimalPoint
+android.icu.dev.test.format.NumberFormatTest#TestParseReturnType
+android.icu.dev.test.format.NumberFormatTest#TestParseSignsAndMarks
+android.icu.dev.test.format.NumberFormatTest#TestPatterns
+android.icu.dev.test.format.NumberFormatTest#TestPatterns2
+android.icu.dev.test.format.NumberFormatTest#TestPerMill
+android.icu.dev.test.format.NumberFormatTest#TestQuotes
+android.icu.dev.test.format.NumberFormatTest#TestRegistration
+android.icu.dev.test.format.NumberFormatTest#TestRounding
+android.icu.dev.test.format.NumberFormatTest#TestRounding487
+android.icu.dev.test.format.NumberFormatTest#TestRoundingBehavior
+android.icu.dev.test.format.NumberFormatTest#TestRoundingMode
+android.icu.dev.test.format.NumberFormatTest#TestRoundingPattern
+android.icu.dev.test.format.NumberFormatTest#TestRoundingScientific10542
+android.icu.dev.test.format.NumberFormatTest#TestRoundUnnecessarytIssue11808
+android.icu.dev.test.format.NumberFormatTest#TestScientific
+android.icu.dev.test.format.NumberFormatTest#TestScientific2
+android.icu.dev.test.format.NumberFormatTest#TestScientificGrouping
+android.icu.dev.test.format.NumberFormatTest#TestSecondaryGrouping
+android.icu.dev.test.format.NumberFormatTest#TestSetCurrency
+android.icu.dev.test.format.NumberFormatTest#TestSetMinimumIntegerDigits
+android.icu.dev.test.format.NumberFormatTest#TestShowZero
+android.icu.dev.test.format.NumberFormatTest#TestSignificantDigits
+android.icu.dev.test.format.NumberFormatTest#TestSimpleNumberFormatFactory
+android.icu.dev.test.format.NumberFormatTest#TestSpaceParsing
+android.icu.dev.test.format.NumberFormatTest#TestStrictParse
+android.icu.dev.test.format.NumberFormatTest#TestThreadedFormat
+android.icu.dev.test.format.NumberFormatTest#TestWhiteSpaceParsing
+android.icu.dev.test.format.NumberRegression#Test4052223
+android.icu.dev.test.format.NumberRegression#Test4059870
+android.icu.dev.test.format.NumberRegression#Test4061302
+android.icu.dev.test.format.NumberRegression#Test4062486
+android.icu.dev.test.format.NumberRegression#Test4066646
+android.icu.dev.test.format.NumberRegression#Test4068693
+android.icu.dev.test.format.NumberRegression#Test4069754
+android.icu.dev.test.format.NumberRegression#Test4070798
+android.icu.dev.test.format.NumberRegression#Test4071005
+android.icu.dev.test.format.NumberRegression#Test4071014
+android.icu.dev.test.format.NumberRegression#Test4071492
+android.icu.dev.test.format.NumberRegression#Test4071859
+android.icu.dev.test.format.NumberRegression#Test4074454
+android.icu.dev.test.format.NumberRegression#Test4074620
+android.icu.dev.test.format.NumberRegression#Test4075713
+android.icu.dev.test.format.NumberRegression#Test4083018
+android.icu.dev.test.format.NumberRegression#Test4086575
+android.icu.dev.test.format.NumberRegression#Test4087244
+android.icu.dev.test.format.NumberRegression#Test4087245
+android.icu.dev.test.format.NumberRegression#Test4087251
+android.icu.dev.test.format.NumberRegression#Test4087535
+android.icu.dev.test.format.NumberRegression#Test4088161
+android.icu.dev.test.format.NumberRegression#Test4088503
+android.icu.dev.test.format.NumberRegression#Test4090489
+android.icu.dev.test.format.NumberRegression#Test4090504
+android.icu.dev.test.format.NumberRegression#Test4092480
+android.icu.dev.test.format.NumberRegression#Test4092561
+android.icu.dev.test.format.NumberRegression#Test4093610
+android.icu.dev.test.format.NumberRegression#Test4095713
+android.icu.dev.test.format.NumberRegression#Test4098741
+android.icu.dev.test.format.NumberRegression#Test4099404
+android.icu.dev.test.format.NumberRegression#Test4101481
+android.icu.dev.test.format.NumberRegression#Test4106658
+android.icu.dev.test.format.NumberRegression#Test4106662
+android.icu.dev.test.format.NumberRegression#Test4106664
+android.icu.dev.test.format.NumberRegression#Test4106667
+android.icu.dev.test.format.NumberRegression#Test4108738
+android.icu.dev.test.format.NumberRegression#Test4110936
+android.icu.dev.test.format.NumberRegression#Test4114639
+android.icu.dev.test.format.NumberRegression#Test4122840
+android.icu.dev.test.format.NumberRegression#Test4125885
+android.icu.dev.test.format.NumberRegression#Test4134034
+android.icu.dev.test.format.NumberRegression#Test4134300
+android.icu.dev.test.format.NumberRegression#Test4140009
+android.icu.dev.test.format.NumberRegression#Test4141750
+android.icu.dev.test.format.NumberRegression#Test4145457
+android.icu.dev.test.format.NumberRegression#Test4147295
+android.icu.dev.test.format.NumberRegression#Test4147706
+android.icu.dev.test.format.NumberRegression#Test4162198
+android.icu.dev.test.format.NumberRegression#Test4162852
+android.icu.dev.test.format.NumberRegression#Test4167494
+android.icu.dev.test.format.NumberRegression#Test4170798
+android.icu.dev.test.format.NumberRegression#Test4176114
+android.icu.dev.test.format.NumberRegression#Test4179818
+android.icu.dev.test.format.NumberRegression#Test4185761
+android.icu.dev.test.format.NumberRegression#Test4212072
+android.icu.dev.test.format.NumberRegression#Test4216742
+android.icu.dev.test.format.NumberRegression#Test4217661
+android.icu.dev.test.format.NumberRegression#test4233840
+android.icu.dev.test.format.NumberRegression#test4241880
+android.icu.dev.test.format.NumberRegression#Test4243011
+android.icu.dev.test.format.NumberRegression#Test4243108
+android.icu.dev.test.format.NumberRegression#test4330377
+android.icu.dev.test.format.PluralFormatTest#TestEquals
+android.icu.dev.test.format.PluralFormatTest#TestGetLocale
+android.icu.dev.test.format.PluralFormatTest#TestGetPluralRules
+android.icu.dev.test.format.PluralFormatTest#TestOneFormLocales
+android.icu.dev.test.format.PluralFormatTest#TestPaucal1_234
+android.icu.dev.test.format.PluralFormatTest#TestPaucal1_2_34
+android.icu.dev.test.format.PluralFormatTest#TestPaucalExcept11_14
+android.icu.dev.test.format.PluralFormatTest#TestPaucalRu
+android.icu.dev.test.format.PluralFormatTest#TestSetLocale
+android.icu.dev.test.format.PluralFormatTest#TestSingular01Locales
+android.icu.dev.test.format.PluralFormatTest#TestSingular1Locales
+android.icu.dev.test.format.PluralFormatTest#TestSingularDual
+android.icu.dev.test.format.PluralFormatTest#TestSingularPaucal
+android.icu.dev.test.format.PluralFormatTest#TestSingularZeroSome
+android.icu.dev.test.format.PluralFormatTest#TestSpecial12_19
+android.icu.dev.test.format.PluralFormatTest#TestZeroSingularLocales
+android.icu.dev.test.format.PluralFormatUnitTest#TestApplyPatternAndFormat
+android.icu.dev.test.format.PluralFormatUnitTest#TestConstructor
+android.icu.dev.test.format.PluralFormatUnitTest#TestDecimals
+android.icu.dev.test.format.PluralFormatUnitTest#TestEquals
+android.icu.dev.test.format.PluralFormatUnitTest#TestExtendedPluralFormat
+android.icu.dev.test.format.PluralFormatUnitTest#TestExtendedPluralFormatParsing
+android.icu.dev.test.format.PluralFormatUnitTest#TestNegative
+android.icu.dev.test.format.PluralFormatUnitTest#TestOrdinalFormat
+android.icu.dev.test.format.PluralFormatUnitTest#TestParse
+android.icu.dev.test.format.PluralFormatUnitTest#TestPattern
+android.icu.dev.test.format.PluralFormatUnitTest#TestSamples
+android.icu.dev.test.format.PluralFormatUnitTest#TestSetLocale
+android.icu.dev.test.format.PluralRangesTest#TestBasic
+android.icu.dev.test.format.PluralRangesTest#TestFormatting
+android.icu.dev.test.format.PluralRangesTest#TestLocaleData
+android.icu.dev.test.format.PluralRangesTest#TestRangePattern
+android.icu.dev.test.format.PluralRulesTest#testAvailableULocales
+android.icu.dev.test.format.PluralRulesTest#TestBasicFraction
+android.icu.dev.test.format.PluralRulesTest#testBuiltInRules
+android.icu.dev.test.format.PluralRulesTest#TestCreateRules
+android.icu.dev.test.format.PluralRulesTest#testEquality
+android.icu.dev.test.format.PluralRulesTest#TestEquals
+android.icu.dev.test.format.PluralRulesTest#testFunctionalEquivalent
+android.icu.dev.test.format.PluralRulesTest#TestGetAllKeywordValues
+android.icu.dev.test.format.PluralRulesTest#TestGetSamples
+android.icu.dev.test.format.PluralRulesTest#TestGetUniqueKeywordValue
+android.icu.dev.test.format.PluralRulesTest#TestHashCode
+android.icu.dev.test.format.PluralRulesTest#testInequality
+android.icu.dev.test.format.PluralRulesTest#testJavaLocaleFactory
+android.icu.dev.test.format.PluralRulesTest#TestKeywords
+android.icu.dev.test.format.PluralRulesTest#TestLimitedAndSamplesConsistency
+android.icu.dev.test.format.PluralRulesTest#TestLocales
+android.icu.dev.test.format.PluralRulesTest#testOperands
+android.icu.dev.test.format.PluralRulesTest#TestOrdinal
+android.icu.dev.test.format.PluralRulesTest#TestParseDescription
+android.icu.dev.test.format.PluralRulesTest#testParseEmpty
+android.icu.dev.test.format.PluralRulesTest#testParsing
+android.icu.dev.test.format.PluralRulesTest#testSamples
+android.icu.dev.test.format.PluralRulesTest#TestSerial
+android.icu.dev.test.format.PluralRulesTest#TestSerialization
+android.icu.dev.test.format.PluralRulesTest#testSyntaxRestrictions
+android.icu.dev.test.format.PluralRulesTest#testUniqueRules
+android.icu.dev.test.format.RbnfLenientScannerTest#TestAllLocales
+android.icu.dev.test.format.RbnfLenientScannerTest#TestDefaultProvider
+android.icu.dev.test.format.RbnfLenientScannerTest#TestDurations
+android.icu.dev.test.format.RbnfLenientScannerTest#TestEnglishSpellout
+android.icu.dev.test.format.RbnfLenientScannerTest#TestFrenchSpellout
+android.icu.dev.test.format.RbnfLenientScannerTest#TestGermanSpellout
+android.icu.dev.test.format.RBNFParseTest#TestLenientParse
+android.icu.dev.test.format.RBNFParseTest#TestParse
+android.icu.dev.test.format.RbnfRoundTripTest#TestDurationsRT
+android.icu.dev.test.format.RbnfRoundTripTest#TestDutchSpelloutRT
+android.icu.dev.test.format.RbnfRoundTripTest#TestEnglishSpelloutRT
+android.icu.dev.test.format.RbnfRoundTripTest#TestFrenchSpelloutRT
+android.icu.dev.test.format.RbnfRoundTripTest#TestGermanSpelloutRT
+android.icu.dev.test.format.RbnfRoundTripTest#TestGreekSpelloutRT
+android.icu.dev.test.format.RbnfRoundTripTest#TestHebrewNumberingRT
+android.icu.dev.test.format.RbnfRoundTripTest#TestItalianSpelloutRT
+android.icu.dev.test.format.RbnfRoundTripTest#TestJapaneseSpelloutRT
+android.icu.dev.test.format.RbnfRoundTripTest#TestRussianSpelloutRT
+android.icu.dev.test.format.RbnfRoundTripTest#TestSpanishSpelloutRT
+android.icu.dev.test.format.RbnfRoundTripTest#TestSwedishSpelloutRT
+android.icu.dev.test.format.RbnfRoundTripTest#TestSwissFrenchSpelloutRT
+android.icu.dev.test.format.RbnfTest#TestAllLocales
+android.icu.dev.test.format.RbnfTest#TestBigNumbers
+android.icu.dev.test.format.RbnfTest#TestChineseProcess
+android.icu.dev.test.format.RbnfTest#TestContext
+android.icu.dev.test.format.RbnfTest#TestCoverage
+android.icu.dev.test.format.RbnfTest#TestDurations
+android.icu.dev.test.format.RbnfTest#TestEnglishSpellout
+android.icu.dev.test.format.RbnfTest#TestEquals
+android.icu.dev.test.format.RbnfTest#TestFractionalRuleSet
+android.icu.dev.test.format.RbnfTest#TestFrenchSpellout
+android.icu.dev.test.format.RbnfTest#TestGermanSpellout
+android.icu.dev.test.format.RbnfTest#TestGetNameListForLocale
+android.icu.dev.test.format.RbnfTest#TestGetRuleDisplayNameLocales
+android.icu.dev.test.format.RbnfTest#TestGetRulesSetDisplayName
+android.icu.dev.test.format.RbnfTest#TestInfinityNaN
+android.icu.dev.test.format.RbnfTest#TestItalianSpellout
+android.icu.dev.test.format.RbnfTest#TestMultiplePluralRules
+android.icu.dev.test.format.RbnfTest#TestOrdinalAbbreviations
+android.icu.dev.test.format.RbnfTest#TestPluralRules
+android.icu.dev.test.format.RbnfTest#TestRounding
+android.icu.dev.test.format.RbnfTest#TestRuleSetDisplayName
+android.icu.dev.test.format.RbnfTest#TestSetDecimalFormatSymbols
+android.icu.dev.test.format.RbnfTest#TestSmallValues
+android.icu.dev.test.format.RbnfTest#TestSpanishSpellout
+android.icu.dev.test.format.RbnfTest#TestSwedishSpellout
+android.icu.dev.test.format.RbnfTest#TestSwissFrenchSpellout
+android.icu.dev.test.format.RbnfTest#TestThaiSpellout
+android.icu.dev.test.format.RbnfTest#TestTrailingSemicolon
+android.icu.dev.test.format.RbnfTest#TestUndefinedSpellout
+android.icu.dev.test.format.RbnfTest#TestVariableDecimalPoint
+android.icu.dev.test.format.RelativeDateTimeFormatterTest#TestBadDisplayContext
+android.icu.dev.test.format.RelativeDateTimeFormatterTest#TestCombineDateAndTime
+android.icu.dev.test.format.RelativeDateTimeFormatterTest#TestCustomNumberFormat
+android.icu.dev.test.format.RelativeDateTimeFormatterTest#TestFormatWithoutQuantityIllegalArgument
+android.icu.dev.test.format.RelativeDateTimeFormatterTest#TestFormatWithQuantityIllegalArgument
+android.icu.dev.test.format.RelativeDateTimeFormatterTest#TestGetters
+android.icu.dev.test.format.RelativeDateTimeFormatterTest#TestJavaLocale
+android.icu.dev.test.format.RelativeDateTimeFormatterTest#TestRelativeDateWithoutQuantity
+android.icu.dev.test.format.RelativeDateTimeFormatterTest#TestRelativeDateWithoutQuantityCaps
+android.icu.dev.test.format.RelativeDateTimeFormatterTest#TestRelativeDateWithoutQuantityNarrow
+android.icu.dev.test.format.RelativeDateTimeFormatterTest#TestRelativeDateWithoutQuantityShort
+android.icu.dev.test.format.RelativeDateTimeFormatterTest#TestRelativeDateWithQuantity
+android.icu.dev.test.format.RelativeDateTimeFormatterTest#TestRelativeDateWithQuantityCaps
+android.icu.dev.test.format.RelativeDateTimeFormatterTest#TestRelativeDateWithQuantityNarrow
+android.icu.dev.test.format.RelativeDateTimeFormatterTest#TestRelativeDateWithQuantityShort
+android.icu.dev.test.format.RelativeDateTimeFormatterTest#TestRelativeDateWithQuantitySr
+android.icu.dev.test.format.RelativeDateTimeFormatterTest#TestRelativeDateWithQuantitySrFallback
+android.icu.dev.test.format.RelativeDateTimeFormatterTest#TestSidewaysDataLoading
+android.icu.dev.test.format.RelativeDateTimeFormatterTest#TestTwoBeforeTwoAfter
+android.icu.dev.test.format.ScientificNumberFormatterTest#TestBasic
+android.icu.dev.test.format.ScientificNumberFormatterTest#TestFarsi
+android.icu.dev.test.format.ScientificNumberFormatterTest#TestFixedDecimalMarkup
+android.icu.dev.test.format.ScientificNumberFormatterTest#TestFixedDecimalSuperscript
+android.icu.dev.test.format.ScientificNumberFormatterTest#TestPlusSignInExponentMarkup
+android.icu.dev.test.format.ScientificNumberFormatterTest#TestPlusSignInExponentSuperscript
+android.icu.dev.test.format.SelectFormatAPITest#TestApplyPatternToPattern
+android.icu.dev.test.format.SelectFormatAPITest#TestConstructors
+android.icu.dev.test.format.SelectFormatAPITest#TestEquals
+android.icu.dev.test.format.SelectFormatAPITest#TestFormat
+android.icu.dev.test.format.SelectFormatAPITest#TestHashCode
+android.icu.dev.test.format.SelectFormatAPITest#TestParseObject
+android.icu.dev.test.format.SelectFormatAPITest#TestToPattern
+android.icu.dev.test.format.SelectFormatAPITest#TestToString
+android.icu.dev.test.format.SelectFormatUnitTest#TestApplyFormat
+android.icu.dev.test.format.SelectFormatUnitTest#TestInvalidKeyword
+android.icu.dev.test.format.SelectFormatUnitTest#TestPatternSyntax
+android.icu.dev.test.format.TestMessageFormat#TestAdopt
+android.icu.dev.test.format.TestMessageFormat#testApostropheInPluralAndSelect
+android.icu.dev.test.format.TestMessageFormat#TestApostropheMode
+android.icu.dev.test.format.TestMessageFormat#TestAutoQuoteApostrophe
+android.icu.dev.test.format.TestMessageFormat#TestBug1
+android.icu.dev.test.format.TestMessageFormat#TestBug2
+android.icu.dev.test.format.TestMessageFormat#TestBug3
+android.icu.dev.test.format.TestMessageFormat#TestClone
+android.icu.dev.test.format.TestMessageFormat#TestCompatibleApostrophe
+android.icu.dev.test.format.TestMessageFormat#TestDecimals
+android.icu.dev.test.format.TestMessageFormat#TestEquals
+android.icu.dev.test.format.TestMessageFormat#TestFormat
+android.icu.dev.test.format.TestMessageFormat#testFormatNamedArguments
+android.icu.dev.test.format.TestMessageFormat#TestFormatToCharacterIterator
+android.icu.dev.test.format.TestMessageFormat#TestGetFormatByArgumentName
+android.icu.dev.test.format.TestMessageFormat#TestHashCode
+android.icu.dev.test.format.TestMessageFormat#TestMessagePatternAutoQuoteApostropheDeep
+android.icu.dev.test.format.TestMessageFormat#TestMessagePatternFreezable
+android.icu.dev.test.format.TestMessageFormat#TestMessagePatternNamedAndNumberedArguments
+android.icu.dev.test.format.TestMessageFormat#TestMessagePatternParseChoiceStyle
+android.icu.dev.test.format.TestMessageFormat#TestMessagePatternPartCoverage
+android.icu.dev.test.format.TestMessageFormat#TestMsgFormatChoice
+android.icu.dev.test.format.TestMessageFormat#testNamedArguments
+android.icu.dev.test.format.TestMessageFormat#testNestedFormatsInPluralFormat
+android.icu.dev.test.format.TestMessageFormat#TestNotEquals
+android.icu.dev.test.format.TestMessageFormat#TestNullArgs
+android.icu.dev.test.format.TestMessageFormat#testNumericFormatWithMap
+android.icu.dev.test.format.TestMessageFormat#testNumericOnlyMethods
+android.icu.dev.test.format.TestMessageFormat#TestParse
+android.icu.dev.test.format.TestMessageFormat#testParseNamedArguments
+android.icu.dev.test.format.TestMessageFormat#TestPattern
+android.icu.dev.test.format.TestMessageFormat#testPluralFormat
+android.icu.dev.test.format.TestMessageFormat#testPluralFormatToPattern
+android.icu.dev.test.format.TestMessageFormat#TestRBNF
+android.icu.dev.test.format.TestMessageFormat#TestSample
+android.icu.dev.test.format.TestMessageFormat#testSelectFormat
+android.icu.dev.test.format.TestMessageFormat#testSelectFormatToPattern
+android.icu.dev.test.format.TestMessageFormat#TestSelectOrdinal
+android.icu.dev.test.format.TestMessageFormat#TestSetFormat
+android.icu.dev.test.format.TestMessageFormat#TestSetGetFormats
+android.icu.dev.test.format.TestMessageFormat#TestSetLocale
+android.icu.dev.test.format.TestMessageFormat#TestSimpleFormat
+android.icu.dev.test.format.TestMessageFormat#TestStaticFormat
+android.icu.dev.test.format.TestMessageFormat#TestTrimArgumentName
+android.icu.dev.test.format.TestMessageFormat#TestUnlimitedArgsAndSubformats
+android.icu.dev.test.format.TimeUnitTest#Test10219FactionalPluralsParse
+android.icu.dev.test.format.TimeUnitTest#Test10219FractionalPlurals
+android.icu.dev.test.format.TimeUnitTest#TestAPI
+android.icu.dev.test.format.TimeUnitTest#TestBasic
+android.icu.dev.test.format.TimeUnitTest#TestBritishShortHourFallback
+android.icu.dev.test.format.TimeUnitTest#TestClone
+android.icu.dev.test.format.TimeUnitTest#TestEqHashCode
+android.icu.dev.test.format.TimeUnitTest#TestFormat
+android.icu.dev.test.format.TimeUnitTest#TestGetLocale
+android.icu.dev.test.format.TimeUnitTest#TestGreek
+android.icu.dev.test.format.TimeUnitTest#TestGreekWithSanitization
+android.icu.dev.test.format.TimeUnitTest#TestSetLocale
+android.icu.dev.test.format.TimeUnitTest#TestSetNumberFormat
+android.icu.dev.test.format.TimeUnitTest#TestSetup
+android.icu.dev.test.format.TimeUnitTest#TestStandInForMeasureFormat
+android.icu.dev.test.format.TimeUnitTest#TestTimeUnitFormat
+android.icu.dev.test.format.TimeZoneFormatTest#TestAPI
+android.icu.dev.test.format.TimeZoneFormatTest#TestFormat
+android.icu.dev.test.format.TimeZoneFormatTest#TestFormatTZDBNames
+android.icu.dev.test.format.TimeZoneFormatTest#TestInheritedFormat
+android.icu.dev.test.format.TimeZoneFormatTest#TestISOFormat
+android.icu.dev.test.format.TimeZoneFormatTest#TestParse
+android.icu.dev.test.format.TimeZoneFormatTest#TestParseCoverage
+android.icu.dev.test.format.TimeZoneFormatTest#TestTimeRoundTrip
+android.icu.dev.test.format.TimeZoneFormatTest#TestTimeZoneRoundTrip
+android.icu.dev.test.format.TimeZoneFormatTest#TestTZDBNamesThreading
+android.icu.dev.test.iterator.TestUCharacterIterator#TestClone
+android.icu.dev.test.iterator.TestUCharacterIterator#TestIteration
+android.icu.dev.test.iterator.TestUCharacterIterator#TestIterationUChar32
+android.icu.dev.test.iterator.TestUCharacterIterator#TestJitterbug1952
+android.icu.dev.test.iterator.TestUCharacterIterator#TestPreviousNext
+android.icu.dev.test.iterator.TestUCharacterIterator#TestUCharacterIteratorWrapper
+android.icu.dev.test.lang.TestUScriptRun#TestContstruction
+android.icu.dev.test.lang.TestUScriptRun#TestReset
+android.icu.dev.test.lang.TestUScriptRun#TestRuns
+android.icu.dev.test.lang.TestUScript#TestAllCodepoints
+android.icu.dev.test.lang.TestUScript#TestGetCode
+android.icu.dev.test.lang.TestUScript#TestGetName
+android.icu.dev.test.lang.TestUScript#TestGetScript
+android.icu.dev.test.lang.TestUScript#TestGetScriptExtensions
+android.icu.dev.test.lang.TestUScript#TestGetScriptOfCharsWithScriptExtensions
+android.icu.dev.test.lang.TestUScript#TestGetShortName
+android.icu.dev.test.lang.TestUScript#TestHasScript
+android.icu.dev.test.lang.TestUScript#TestLocaleGetCode
+android.icu.dev.test.lang.TestUScript#TestMultipleCode
+android.icu.dev.test.lang.TestUScript#TestNewCode
+android.icu.dev.test.lang.TestUScript#TestScriptMetadata
+android.icu.dev.test.lang.TestUScript#TestScriptMetadataAPI
+android.icu.dev.test.lang.TestUScript#TestScriptNames
+android.icu.dev.test.lang.UCharacterCaseTest#TestCharacter
+android.icu.dev.test.lang.UCharacterCaseTest#TestDutchTitle
+android.icu.dev.test.lang.UCharacterCaseTest#TestFolding
+android.icu.dev.test.lang.UCharacterCaseTest#TestLower
+android.icu.dev.test.lang.UCharacterCaseTest#TestSpecial
+android.icu.dev.test.lang.UCharacterCaseTest#TestSpecialCasingTxt
+android.icu.dev.test.lang.UCharacterCaseTest#TestTitle
+android.icu.dev.test.lang.UCharacterCaseTest#TestTitleRegression
+android.icu.dev.test.lang.UCharacterCaseTest#TestUpper
+android.icu.dev.test.lang.UCharacterCaseTest#TestUpperLower
+android.icu.dev.test.lang.UCharacterCategoryTest#TestToString
+android.icu.dev.test.lang.UCharacterDirectionTest#TestToString
+android.icu.dev.test.lang.UCharacterSurrogateTest#TestCharCount
+android.icu.dev.test.lang.UCharacterSurrogateTest#TestCodePointAtBefore
+android.icu.dev.test.lang.UCharacterSurrogateTest#TestCodePointCount
+android.icu.dev.test.lang.UCharacterSurrogateTest#TestIsHighSurrogate
+android.icu.dev.test.lang.UCharacterSurrogateTest#TestIsLowSurrogate
+android.icu.dev.test.lang.UCharacterSurrogateTest#TestIsSupplementaryCodePoint
+android.icu.dev.test.lang.UCharacterSurrogateTest#TestIsSurrogatePair
+android.icu.dev.test.lang.UCharacterSurrogateTest#TestIsValidCodePoint
+android.icu.dev.test.lang.UCharacterSurrogateTest#TestOffsetByCodePoints
+android.icu.dev.test.lang.UCharacterSurrogateTest#TestToChars
+android.icu.dev.test.lang.UCharacterSurrogateTest#TestToCodePoint
+android.icu.dev.test.lang.UCharacterSurrogateTest#TestUnicodeBlockForName
+android.icu.dev.test.lang.UCharacterTest#TestAdditionalProperties
+android.icu.dev.test.lang.UCharacterTest#TestBase
+android.icu.dev.test.lang.UCharacterTest#TestBidiPairedBracketType
+android.icu.dev.test.lang.UCharacterTest#TestBlockData
+android.icu.dev.test.lang.UCharacterTest#TestCodePoint
+android.icu.dev.test.lang.UCharacterTest#TestCodePointAt
+android.icu.dev.test.lang.UCharacterTest#TestCodePointBefore
+android.icu.dev.test.lang.UCharacterTest#TestCodePointCount
+android.icu.dev.test.lang.UCharacterTest#TestConsistency
+android.icu.dev.test.lang.UCharacterTest#TestCoverage
+android.icu.dev.test.lang.UCharacterTest#TestDefined
+android.icu.dev.test.lang.UCharacterTest#TestDigits
+android.icu.dev.test.lang.UCharacterTest#TestForName
+android.icu.dev.test.lang.UCharacterTest#TestGetAge
+android.icu.dev.test.lang.UCharacterTest#TestGetCombiningClass
+android.icu.dev.test.lang.UCharacterTest#TestGetEuropeanDigit
+android.icu.dev.test.lang.UCharacterTest#TestGetHanNumericValue
+android.icu.dev.test.lang.UCharacterTest#TestGetInstance
+android.icu.dev.test.lang.UCharacterTest#TestGetIntPropertyMaxValue
+android.icu.dev.test.lang.UCharacterTest#TestGetIntPropertyValue
+android.icu.dev.test.lang.UCharacterTest#TestGetISOComment
+android.icu.dev.test.lang.UCharacterTest#TestGetName
+android.icu.dev.test.lang.UCharacterTest#TestGetNumericValue
+android.icu.dev.test.lang.UCharacterTest#TestGetProperty
+android.icu.dev.test.lang.UCharacterTest#TestGetUnicodeNumericValue
+android.icu.dev.test.lang.UCharacterTest#TestHasBinaryProperty
+android.icu.dev.test.lang.UCharacterTest#TestIdentifier
+android.icu.dev.test.lang.UCharacterTest#TestIsBMP
+android.icu.dev.test.lang.UCharacterTest#TestIsFrozen
+android.icu.dev.test.lang.UCharacterTest#TestIsLegal
+android.icu.dev.test.lang.UCharacterTest#TestISOControl
+android.icu.dev.test.lang.UCharacterTest#TestIteration
+android.icu.dev.test.lang.UCharacterTest#TestLetterNumber
+android.icu.dev.test.lang.UCharacterTest#TestMirror
+android.icu.dev.test.lang.UCharacterTest#TestNameIteration
+android.icu.dev.test.lang.UCharacterTest#TestNames
+android.icu.dev.test.lang.UCharacterTest#TestNextCaseMapCP
+android.icu.dev.test.lang.UCharacterTest#TestNumeric
+android.icu.dev.test.lang.UCharacterTest#TestNumericProperties
+android.icu.dev.test.lang.UCharacterTest#TestOf
+android.icu.dev.test.lang.UCharacterTest#TestPatternProperties
+android.icu.dev.test.lang.UCharacterTest#TestPrint
+android.icu.dev.test.lang.UCharacterTest#TestPropertyValues
+android.icu.dev.test.lang.UCharacterTest#TestReset
+android.icu.dev.test.lang.UCharacterTest#TestSetLimit
+android.icu.dev.test.lang.UCharacterTest#TestSpaces
+android.icu.dev.test.lang.UCharacterTest#TestSupplementary
+android.icu.dev.test.lang.UCharacterTest#TestToChars
+android.icu.dev.test.lang.UCharacterTest#TestToLowerCase
+android.icu.dev.test.lang.UCharacterTest#TestToString
+android.icu.dev.test.lang.UCharacterTest#TestToTitleCaseCoverage
+android.icu.dev.test.lang.UCharacterTest#TestToUpperCase
+android.icu.dev.test.lang.UCharacterTest#TestUCharFromNameUnderflow
+android.icu.dev.test.lang.UCharacterTest#TestUnicodeData
+android.icu.dev.test.lang.UCharacterTest#TestVersion
+android.icu.dev.test.lang.UCharacterTest#TestXSymbolTable
+android.icu.dev.test.lang.UCharacterThreadTest#TestUCharactersGetName
+android.icu.dev.test.lang.UnicodeSetStringSpanTest#TestInterestingStringSpan
+android.icu.dev.test.lang.UnicodeSetStringSpanTest#TestSimpleStringSpan
+android.icu.dev.test.lang.UnicodeSetStringSpanTest#TestSimpleStringSpanAndFreeze
+android.icu.dev.test.lang.UnicodeSetStringSpanTest#TestSimpleStringSpanSlow
+android.icu.dev.test.lang.UnicodeSetStringSpanTest#TestSpan
+android.icu.dev.test.lang.UnicodeSetStringSpanTest#TestSpanAndCount
+android.icu.dev.test.lang.UnicodeSetStringSpanTest#TestStringWithUnpairedSurrogateSpan
+android.icu.dev.test.lang.UnicodeSetTest#TestAddCollection
+android.icu.dev.test.lang.UnicodeSetTest#TestAddRemove
+android.icu.dev.test.lang.UnicodeSetTest#TestAPI
+android.icu.dev.test.lang.UnicodeSetTest#TestAStringRange
+android.icu.dev.test.lang.UnicodeSetTest#TestCategories
+android.icu.dev.test.lang.UnicodeSetTest#TestCharSequenceArgs
+android.icu.dev.test.lang.UnicodeSetTest#TestClone
+android.icu.dev.test.lang.UnicodeSetTest#TestCloseOver
+android.icu.dev.test.lang.UnicodeSetTest#TestCodePoints
+android.icu.dev.test.lang.UnicodeSetTest#TestComparison
+android.icu.dev.test.lang.UnicodeSetTest#TestConstants
+android.icu.dev.test.lang.UnicodeSetTest#TestContains
+android.icu.dev.test.lang.UnicodeSetTest#TestContainsString
+android.icu.dev.test.lang.UnicodeSetTest#TestCountIn
+android.icu.dev.test.lang.UnicodeSetTest#TestEscapePattern
+android.icu.dev.test.lang.UnicodeSetTest#TestExhaustive
+android.icu.dev.test.lang.UnicodeSetTest#testForSpanGaps
+android.icu.dev.test.lang.UnicodeSetTest#TestFrozen
+android.icu.dev.test.lang.UnicodeSetTest#TestGenerics
+android.icu.dev.test.lang.UnicodeSetTest#TestGetSet
+android.icu.dev.test.lang.UnicodeSetTest#TestHangulSyllable
+android.icu.dev.test.lang.UnicodeSetTest#TestIndexOf
+android.icu.dev.test.lang.UnicodeSetTest#TestIteration
+android.icu.dev.test.lang.UnicodeSetTest#TestMinimalRep
+android.icu.dev.test.lang.UnicodeSetTest#TestPatterns
+android.icu.dev.test.lang.UnicodeSetTest#TestPosixClasses
+android.icu.dev.test.lang.UnicodeSetTest#TestPropertyAccess
+android.icu.dev.test.lang.UnicodeSetTest#TestPropertySet
+android.icu.dev.test.lang.UnicodeSetTest#TestRangeConstructor
+android.icu.dev.test.lang.UnicodeSetTest#TestReplaceAndDelete
+android.icu.dev.test.lang.UnicodeSetTest#TestScriptNames
+android.icu.dev.test.lang.UnicodeSetTest#TestScriptSet
+android.icu.dev.test.lang.UnicodeSetTest#TestSetRelation
+android.icu.dev.test.lang.UnicodeSetTest#TestSetSpeed
+android.icu.dev.test.lang.UnicodeSetTest#TestStrings
+android.icu.dev.test.lang.UnicodeSetTest#TestSurrogate
+android.icu.dev.test.lang.UnicodeSetTest#TestSymbolTable
+android.icu.dev.test.lang.UnicodeSetTest#TestToPattern
+android.icu.dev.test.lang.UnicodeSetTest#TestUnicodeSetStrings
+android.icu.dev.test.lang.UPropertyAliasesTest#TestPropertyNames
+android.icu.dev.test.lang.UPropertyAliasesTest#TestUnknownPropertyNames
+android.icu.dev.test.lang.UTF16Test#TestAppend
+android.icu.dev.test.lang.UTF16Test#TestBounds
+android.icu.dev.test.lang.UTF16Test#TestCaseCompare
+android.icu.dev.test.lang.UTF16Test#TestCharAt
+android.icu.dev.test.lang.UTF16Test#TestCodePointCompare
+android.icu.dev.test.lang.UTF16Test#TestCountCodePoint
+android.icu.dev.test.lang.UTF16Test#TestDelete
+android.icu.dev.test.lang.UTF16Test#TestfindOffset
+android.icu.dev.test.lang.UTF16Test#TestGetCharCountSurrogate
+android.icu.dev.test.lang.UTF16Test#TestHasMoreCodePointsThan
+android.icu.dev.test.lang.UTF16Test#TestIndexOf
+android.icu.dev.test.lang.UTF16Test#TestInsert
+android.icu.dev.test.lang.UTF16Test#TestMoveCodePointOffset
+android.icu.dev.test.lang.UTF16Test#TestNewString
+android.icu.dev.test.lang.UTF16Test#TestReplace
+android.icu.dev.test.lang.UTF16Test#TestReverse
+android.icu.dev.test.lang.UTF16Test#TestSetCharAt
+android.icu.dev.test.lang.UTF16Test#TestStringComparator
+android.icu.dev.test.lang.UTF16Test#TestUtilities
+android.icu.dev.test.lang.UTF16Test#TestValueOf
+android.icu.dev.test.normalizer.BasicTest#TestBengali
+android.icu.dev.test.normalizer.BasicTest#TestBugJ2068
+android.icu.dev.test.normalizer.BasicTest#TestBugJ2324
+android.icu.dev.test.normalizer.BasicTest#TestCanonCompose
+android.icu.dev.test.normalizer.BasicTest#TestCanonIterData
+android.icu.dev.test.normalizer.BasicTest#TestCheckFCD
+android.icu.dev.test.normalizer.BasicTest#TestCombiningMarks
+android.icu.dev.test.normalizer.BasicTest#TestCompare
+android.icu.dev.test.normalizer.BasicTest#TestCompareDebug
+android.icu.dev.test.normalizer.BasicTest#TestCompatCompose
+android.icu.dev.test.normalizer.BasicTest#TestCompatDecomp
+android.icu.dev.test.normalizer.BasicTest#TestComposition
+android.icu.dev.test.normalizer.BasicTest#TestCompositionExclusion
+android.icu.dev.test.normalizer.BasicTest#TestConcatenate
+android.icu.dev.test.normalizer.BasicTest#TestCustomComp
+android.icu.dev.test.normalizer.BasicTest#TestCustomFCC
+android.icu.dev.test.normalizer.BasicTest#TestDebugIter
+android.icu.dev.test.normalizer.BasicTest#TestDebugIterOld
+android.icu.dev.test.normalizer.BasicTest#TestDebugStatic
+android.icu.dev.test.normalizer.BasicTest#TestDecomp
+android.icu.dev.test.normalizer.BasicTest#TestExplodingBase
+android.icu.dev.test.normalizer.BasicTest#TestFCD
+android.icu.dev.test.normalizer.BasicTest#TestFCNFKCClosure
+android.icu.dev.test.normalizer.BasicTest#TestFilteredAppend
+android.icu.dev.test.normalizer.BasicTest#TestFilteredNormalizer2
+android.icu.dev.test.normalizer.BasicTest#TestFindFoldFCDExceptions
+android.icu.dev.test.normalizer.BasicTest#TestGetCombiningClass
+android.icu.dev.test.normalizer.BasicTest#TestGetDecomposition
+android.icu.dev.test.normalizer.BasicTest#TestGetEasyToUseInstance
+android.icu.dev.test.normalizer.BasicTest#TestGetRawDecomposition
+android.icu.dev.test.normalizer.BasicTest#TestHangulCompose
+android.icu.dev.test.normalizer.BasicTest#TestHangulDecomp
+android.icu.dev.test.normalizer.BasicTest#TestNFC
+android.icu.dev.test.normalizer.BasicTest#TestNFD
+android.icu.dev.test.normalizer.BasicTest#TestNone
+android.icu.dev.test.normalizer.BasicTest#TestNoneNormalizer
+android.icu.dev.test.normalizer.BasicTest#TestNoopNormalizer2
+android.icu.dev.test.normalizer.BasicTest#TestNormalizerAPI
+android.icu.dev.test.normalizer.BasicTest#TestPreviousNext
+android.icu.dev.test.normalizer.BasicTest#TestPreviousNextJCI
+android.icu.dev.test.normalizer.BasicTest#TestQuickCheckPerCP
+android.icu.dev.test.normalizer.BasicTest#TestQuickCheckResultMAYBE
+android.icu.dev.test.normalizer.BasicTest#TestQuickCheckResultNO
+android.icu.dev.test.normalizer.BasicTest#TestQuickCheckResultYES
+android.icu.dev.test.normalizer.BasicTest#TestQuickCheckStringResult
+android.icu.dev.test.normalizer.BasicTest#TestReturnFailure
+android.icu.dev.test.normalizer.BasicTest#TestSerializedSet
+android.icu.dev.test.normalizer.BasicTest#TestSkippable
+android.icu.dev.test.normalizer.BasicTest#TestTibetan
+android.icu.dev.test.normalizer.BasicTest#TestVerisign
+android.icu.dev.test.normalizer.BasicTest#TestZeroIndex
+android.icu.dev.test.normalizer.ConformanceTest#TestConformance
+android.icu.dev.test.normalizer.ConformanceTest#TestConformance_3_2
+android.icu.dev.test.normalizer.NormalizationMonkeyTest#TestNormalize
+android.icu.dev.test.normalizer.NormalizerRegressionTests#TestJB4472
+android.icu.dev.test.normalizer.TestCanonicalIterator#TestBasic
+android.icu.dev.test.normalizer.TestCanonicalIterator#TestExhaustive
+android.icu.dev.test.normalizer.TestCanonicalIterator#TestSpeed
+android.icu.dev.test.normalizer.TestDeprecatedNormalizerAPI#TestComposedCharIter
+android.icu.dev.test.normalizer.TestDeprecatedNormalizerAPI#TestNormalizerAPI
+android.icu.dev.test.normalizer.TestDeprecatedNormalizerAPI#TestRoundTrip
+android.icu.dev.test.normalizer.UTS46Test#TestAPI
+android.icu.dev.test.normalizer.UTS46Test#TestNotSTD3
+android.icu.dev.test.normalizer.UTS46Test#TestSomeCases
+android.icu.dev.test.rbbi.BreakIteratorRegTest#TestRegUnreg
+android.icu.dev.test.rbbi.BreakIteratorTest#TestBug4068133
+android.icu.dev.test.rbbi.BreakIteratorTest#TestBug4086052
+android.icu.dev.test.rbbi.BreakIteratorTest#TestBug4097779
+android.icu.dev.test.rbbi.BreakIteratorTest#TestBug4097920
+android.icu.dev.test.rbbi.BreakIteratorTest#TestBug4098467Characters
+android.icu.dev.test.rbbi.BreakIteratorTest#TestBug4098467Words
+android.icu.dev.test.rbbi.BreakIteratorTest#TestBug4111338
+android.icu.dev.test.rbbi.BreakIteratorTest#TestBug4117554Lines
+android.icu.dev.test.rbbi.BreakIteratorTest#TestBug4143071
+android.icu.dev.test.rbbi.BreakIteratorTest#TestBug4146175Lines
+android.icu.dev.test.rbbi.BreakIteratorTest#TestBug4152117
+android.icu.dev.test.rbbi.BreakIteratorTest#TestBug4152416
+android.icu.dev.test.rbbi.BreakIteratorTest#TestBug4153072
+android.icu.dev.test.rbbi.BreakIteratorTest#TestCharacterBreak
+android.icu.dev.test.rbbi.BreakIteratorTest#TestEmptyString
+android.icu.dev.test.rbbi.BreakIteratorTest#TestEndBehavior
+android.icu.dev.test.rbbi.BreakIteratorTest#TestFilteredBreakIteratorBuilder
+android.icu.dev.test.rbbi.BreakIteratorTest#TestGetAvailableLocales
+android.icu.dev.test.rbbi.BreakIteratorTest#TestLettersAndDigits
+android.icu.dev.test.rbbi.BreakIteratorTest#TestLineBreak
+android.icu.dev.test.rbbi.BreakIteratorTest#TestLineBreakContractions
+android.icu.dev.test.rbbi.BreakIteratorTest#TestNullLocale
+android.icu.dev.test.rbbi.BreakIteratorTest#TestPreceding
+android.icu.dev.test.rbbi.BreakIteratorTest#TestSentenceInvariants
+android.icu.dev.test.rbbi.BreakIteratorTest#TestT5615
+android.icu.dev.test.rbbi.BreakIteratorTest#TestTitleBreak
+android.icu.dev.test.rbbi.RBBIAPITest#TestCloneEquals
+android.icu.dev.test.rbbi.RBBIAPITest#TestFirstNextFollowing
+android.icu.dev.test.rbbi.RBBIAPITest#TestGetSetText
+android.icu.dev.test.rbbi.RBBIAPITest#TestHashCode
+android.icu.dev.test.rbbi.RBBIAPITest#TestIsBoundary
+android.icu.dev.test.rbbi.RBBIAPITest#TestLastPreviousPreceding
+android.icu.dev.test.rbbi.RBBIAPITest#TestRuleStatus
+android.icu.dev.test.rbbi.RBBIAPITest#TestToString
+android.icu.dev.test.rbbi.RBBITestExtended#TestExtended
+android.icu.dev.test.rbbi.RBBITestMonkey#TestCharMonkey
+android.icu.dev.test.rbbi.RBBITestMonkey#TestLineMonkey
+android.icu.dev.test.rbbi.RBBITestMonkey#TestRTCharMonkey
+android.icu.dev.test.rbbi.RBBITestMonkey#TestRTLineMonkey
+android.icu.dev.test.rbbi.RBBITestMonkey#TestRTSentMonkey
+android.icu.dev.test.rbbi.RBBITestMonkey#TestRTWordMonkey
+android.icu.dev.test.rbbi.RBBITestMonkey#TestSentMonkey
+android.icu.dev.test.rbbi.RBBITestMonkey#TestWordMonkey
+android.icu.dev.test.rbbi.RBBITest#TestClone
+android.icu.dev.test.rbbi.RBBITest#TestCurrent
+android.icu.dev.test.rbbi.RBBITest#TestDefaultRuleBasedCharacterIteration
+android.icu.dev.test.rbbi.RBBITest#TestDefaultRuleBasedLineIteration
+android.icu.dev.test.rbbi.RBBITest#TestDefaultRuleBasedSentenceIteration
+android.icu.dev.test.rbbi.RBBITest#TestDefaultRuleBasedWordIteration
+android.icu.dev.test.rbbi.RBBITest#TestDump
+android.icu.dev.test.rbbi.RBBITest#TestEquals
+android.icu.dev.test.rbbi.RBBITest#TestFirst
+android.icu.dev.test.rbbi.RBBITest#TestFollowing
+android.icu.dev.test.rbbi.RBBITest#TestLast
+android.icu.dev.test.rbbi.RBBITest#TestPreceding
+android.icu.dev.test.rbbi.RBBITest#TestTailoredBreaks
+android.icu.dev.test.rbbi.RBBITest#TestThaiDictionaryBreakIterator
+android.icu.dev.test.search.SearchTest#TestBasic
+android.icu.dev.test.search.SearchTest#TestBreakIterator
+android.icu.dev.test.search.SearchTest#TestBreakIteratorCanonical
+android.icu.dev.test.search.SearchTest#TestCanonical
+android.icu.dev.test.search.SearchTest#TestCollator
+android.icu.dev.test.search.SearchTest#TestCollatorCanonical
+android.icu.dev.test.search.SearchTest#TestCompositeBoundaries
+android.icu.dev.test.search.SearchTest#TestCompositeBoundariesCanonical
+android.icu.dev.test.search.SearchTest#TestConstructor
+android.icu.dev.test.search.SearchTest#TestContraction
+android.icu.dev.test.search.SearchTest#TestContractionCanonical
+android.icu.dev.test.search.SearchTest#TestDiactricMatch
+android.icu.dev.test.search.SearchTest#TestGetMatch
+android.icu.dev.test.search.SearchTest#TestGetSetAttribute
+android.icu.dev.test.search.SearchTest#TestGetSetOffset
+android.icu.dev.test.search.SearchTest#TestGetSetOffsetCanonical
+android.icu.dev.test.search.SearchTest#TestIgnorable
+android.icu.dev.test.search.SearchTest#TestIndicPrefixMatch
+android.icu.dev.test.search.SearchTest#TestInitialization
+android.icu.dev.test.search.SearchTest#TestNormCanonical
+android.icu.dev.test.search.SearchTest#TestNormExact
+android.icu.dev.test.search.SearchTest#TestOpenClose
+android.icu.dev.test.search.SearchTest#TestOverlap
+android.icu.dev.test.search.SearchTest#TestOverlapCanonical
+android.icu.dev.test.search.SearchTest#TestPattern
+android.icu.dev.test.search.SearchTest#TestPatternCanonical
+android.icu.dev.test.search.SearchTest#TestReset
+android.icu.dev.test.search.SearchTest#TestSetMatch
+android.icu.dev.test.search.SearchTest#TestStrength
+android.icu.dev.test.search.SearchTest#TestStrengthCanonical
+android.icu.dev.test.search.SearchTest#TestSubClass
+android.icu.dev.test.search.SearchTest#TestSupplementary
+android.icu.dev.test.search.SearchTest#TestSupplementaryCanonical
+android.icu.dev.test.search.SearchTest#TestText
+android.icu.dev.test.search.SearchTest#TestTextCanonical
+android.icu.dev.test.search.SearchTest#TestUsingSearchCollator
+android.icu.dev.test.search.SearchTest#TestVariable
+android.icu.dev.test.search.SearchTest#TestVariableCanonical
+android.icu.dev.test.shaping.ArabicShapingRegTest#TestEquals
+android.icu.dev.test.shaping.ArabicShapingRegTest#TestError
+android.icu.dev.test.shaping.ArabicShapingRegTest#TestPreflight
+android.icu.dev.test.shaping.ArabicShapingRegTest#TestShape
+android.icu.dev.test.shaping.ArabicShapingRegTest#TestStandard
+android.icu.dev.test.stringprep.IDNAConformanceTest#TestConformance
+android.icu.dev.test.stringprep.TestIDNARef#TestChaining
+android.icu.dev.test.stringprep.TestIDNARef#TestCompare
+android.icu.dev.test.stringprep.TestIDNARef#TestConformance
+android.icu.dev.test.stringprep.TestIDNARef#TestErrorCases
+android.icu.dev.test.stringprep.TestIDNARef#TestIDNToASCII
+android.icu.dev.test.stringprep.TestIDNARef#TestIDNToUnicode
+android.icu.dev.test.stringprep.TestIDNARef#TestNamePrepConformance
+android.icu.dev.test.stringprep.TestIDNARef#TestRootLabelSeparator
+android.icu.dev.test.stringprep.TestIDNARef#TestToASCII
+android.icu.dev.test.stringprep.TestIDNARef#TestToUnicode
+android.icu.dev.test.stringprep.TestIDNA#TestChaining
+android.icu.dev.test.stringprep.TestIDNA#TestCompare
+android.icu.dev.test.stringprep.TestIDNA#TestCompareRefImpl
+android.icu.dev.test.stringprep.TestIDNA#TestConformance
+android.icu.dev.test.stringprep.TestIDNA#TestConvertIDNToASCII
+android.icu.dev.test.stringprep.TestIDNA#TestConvertIDNToUnicode
+android.icu.dev.test.stringprep.TestIDNA#TestConvertToASCII
+android.icu.dev.test.stringprep.TestIDNA#TestConvertToUnicode
+android.icu.dev.test.stringprep.TestIDNA#TestDebug
+android.icu.dev.test.stringprep.TestIDNA#TestErrorCases
+android.icu.dev.test.stringprep.TestIDNA#TestIDNACompare
+android.icu.dev.test.stringprep.TestIDNA#TestIDNToASCII
+android.icu.dev.test.stringprep.TestIDNA#TestIDNToUnicode
+android.icu.dev.test.stringprep.TestIDNA#TestJB4475
+android.icu.dev.test.stringprep.TestIDNA#TestJB4490
+android.icu.dev.test.stringprep.TestIDNA#TestJB5273
+android.icu.dev.test.stringprep.TestIDNA#TestLength
+android.icu.dev.test.stringprep.TestIDNA#TestNamePrepConformance
+android.icu.dev.test.stringprep.TestIDNA#TestRootLabelSeparator
+android.icu.dev.test.stringprep.TestIDNA#TestToASCII
+android.icu.dev.test.stringprep.TestIDNA#TestToUnicode
+android.icu.dev.test.stringprep.TestStringPrepProfiles#TestProfiles
+android.icu.dev.test.stringprep.TestStringPrep#TestCISPrep
+android.icu.dev.test.stringprep.TestStringPrep#TestCoverage
+android.icu.dev.test.stringprep.TestStringPrep#TestCSPrep
+android.icu.dev.test.stringprep.TestStringPrep#TestGetError
+android.icu.dev.test.stringprep.TestStringPrep#TestGetInstance
+android.icu.dev.test.stringprep.TestStringPrep#TestNFS4MixedPrep
+android.icu.dev.test.stringprep.TestStringPrep#TestPrepare
+android.icu.dev.test.stringprep.TestStringPrep#TestSetPreContext
+android.icu.dev.test.stringprep.TestStringPrep#TestStringPrepParseException
+android.icu.dev.test.stringprep.TestStringPrep#TestStringPrepParseExceptionEquals
+android.icu.dev.test.text.SpoofCheckerTest#TestAllowedChars
+android.icu.dev.test.text.SpoofCheckerTest#TestAllowedLocales
+android.icu.dev.test.text.SpoofCheckerTest#TestAreConfusable
+android.icu.dev.test.text.SpoofCheckerTest#TestAreConfusable1
+android.icu.dev.test.text.SpoofCheckerTest#TestBug11635
+android.icu.dev.test.text.SpoofCheckerTest#TestCheck
+android.icu.dev.test.text.SpoofCheckerTest#TestCheckResultToString11447
+android.icu.dev.test.text.SpoofCheckerTest#TestComparator
+android.icu.dev.test.text.SpoofCheckerTest#testConfData
+android.icu.dev.test.text.SpoofCheckerTest#TestGetSetAllowedChars
+android.icu.dev.test.text.SpoofCheckerTest#TestGetSetChecks
+android.icu.dev.test.text.SpoofCheckerTest#TestGetSetChecks1
+android.icu.dev.test.text.SpoofCheckerTest#TestGetSkeleton
+android.icu.dev.test.text.SpoofCheckerTest#TestIdentifierInfo
+android.icu.dev.test.text.SpoofCheckerTest#TestInvisible
+android.icu.dev.test.text.SpoofCheckerTest#TestMixedNumbers
+android.icu.dev.test.text.SpoofCheckerTest#TestOpenFromSourceRules
+android.icu.dev.test.text.SpoofCheckerTest#TestRestrictionLevel
+android.icu.dev.test.text.SpoofCheckerTest#TestSkeleton
+android.icu.dev.test.text.SpoofCheckerTest#TestSpoofAPI
+android.icu.dev.test.text.SpoofCheckerTest#TestUSpoof
+android.icu.dev.test.timescale.TimeScaleAPITest#TestBigDecimalFromBigDecimal
+android.icu.dev.test.timescale.TimeScaleAPITest#TestBigDecimalFromDouble
+android.icu.dev.test.timescale.TimeScaleAPITest#TestBigDecimalFromLong
+android.icu.dev.test.timescale.TimeScaleAPITest#TestFromLong
+android.icu.dev.test.timescale.TimeScaleAPITest#TestGetTimeScale
+android.icu.dev.test.timescale.TimeScaleAPITest#TestToBigDecimalFromBigDecimal
+android.icu.dev.test.timescale.TimeScaleAPITest#TestToBigDecimalFromLong
+android.icu.dev.test.timescale.TimeScaleAPITest#TestToBigDecimalTrunc
+android.icu.dev.test.timescale.TimeScaleAPITest#TestToLong
+android.icu.dev.test.timescale.TimeScaleDataTest#TestDotNet
+android.icu.dev.test.timescale.TimeScaleDataTest#TestEpochOffsets
+android.icu.dev.test.timescale.TimeScaleDataTest#TestFromLimits
+android.icu.dev.test.timescale.TimeScaleDataTest#TestToLimits
+android.icu.dev.test.timescale.TimeScaleMonkeyTest#TestRoundTrip
+android.icu.dev.test.timezone.TimeZoneBoundaryTest#TestBoundaries
+android.icu.dev.test.timezone.TimeZoneBoundaryTest#TestNewRules
+android.icu.dev.test.timezone.TimeZoneBoundaryTest#TestStepwise
+android.icu.dev.test.timezone.TimeZoneOffsetLocalTest#TestGetOffsetAroundTransition
+android.icu.dev.test.timezone.TimeZoneRegression#Test4052967
+android.icu.dev.test.timezone.TimeZoneRegression#Test4073209
+android.icu.dev.test.timezone.TimeZoneRegression#Test4073215
+android.icu.dev.test.timezone.TimeZoneRegression#Test4084933
+android.icu.dev.test.timezone.TimeZoneRegression#Test4096952
+android.icu.dev.test.timezone.TimeZoneRegression#Test4109314
+android.icu.dev.test.timezone.TimeZoneRegression#Test4126678
+android.icu.dev.test.timezone.TimeZoneRegression#Test4151406
+android.icu.dev.test.timezone.TimeZoneRegression#Test4151429
+android.icu.dev.test.timezone.TimeZoneRegression#Test4154525
+android.icu.dev.test.timezone.TimeZoneRegression#Test4154537
+android.icu.dev.test.timezone.TimeZoneRegression#Test4154542
+android.icu.dev.test.timezone.TimeZoneRegression#Test4154650
+android.icu.dev.test.timezone.TimeZoneRegression#Test4159922
+android.icu.dev.test.timezone.TimeZoneRegression#Test4162593
+android.icu.dev.test.timezone.TimeZoneRegression#Test4173604
+android.icu.dev.test.timezone.TimeZoneRegression#Test4176686
+android.icu.dev.test.timezone.TimeZoneRegression#Test4184229
+android.icu.dev.test.timezone.TimeZoneRegression#Test4208960
+android.icu.dev.test.timezone.TimeZoneRegression#TestJ449
+android.icu.dev.test.timezone.TimeZoneRegression#TestJ5134
+android.icu.dev.test.timezone.TimeZoneRegression#TestJohannesburg
+android.icu.dev.test.timezone.TimeZoneRegression#TestT5280
+android.icu.dev.test.timezone.TimeZoneRegression#TestT5432
+android.icu.dev.test.timezone.TimeZoneRegression#TestT7107
+android.icu.dev.test.timezone.TimeZoneRuleTest#TestBasicTimeZoneCoverage
+android.icu.dev.test.timezone.TimeZoneRuleTest#TestGetSimpleRules
+android.icu.dev.test.timezone.TimeZoneRuleTest#TestHasEquivalentTransitions
+android.icu.dev.test.timezone.TimeZoneRuleTest#TestHistoricalRuleBasedTimeZone
+android.icu.dev.test.timezone.TimeZoneRuleTest#TestOlsonTransition
+android.icu.dev.test.timezone.TimeZoneRuleTest#TestRBTZTransition
+android.icu.dev.test.timezone.TimeZoneRuleTest#TestSimpleRuleBasedTimeZone
+android.icu.dev.test.timezone.TimeZoneRuleTest#TestSimpleTimeZoneCoverage
+android.icu.dev.test.timezone.TimeZoneRuleTest#TestT6216
+android.icu.dev.test.timezone.TimeZoneRuleTest#TestT6669
+android.icu.dev.test.timezone.TimeZoneRuleTest#TestT8943
+android.icu.dev.test.timezone.TimeZoneRuleTest#TestTimeZoneRuleCoverage
+android.icu.dev.test.timezone.TimeZoneRuleTest#TestVTimeZoneCoverage
+android.icu.dev.test.timezone.TimeZoneRuleTest#TestVTimeZoneHeaderProps
+android.icu.dev.test.timezone.TimeZoneRuleTest#TestVTimeZoneParse
+android.icu.dev.test.timezone.TimeZoneRuleTest#TestVTimeZoneRoundTrip
+android.icu.dev.test.timezone.TimeZoneRuleTest#TestVTimeZoneRoundTripPartial
+android.icu.dev.test.timezone.TimeZoneRuleTest#TestVTimeZoneSimpleWrite
+android.icu.dev.test.timezone.TimeZoneTest#TestAlternateRules
+android.icu.dev.test.timezone.TimeZoneTest#TestCanonicalID
+android.icu.dev.test.timezone.TimeZoneTest#TestCountries
+android.icu.dev.test.timezone.TimeZoneTest#TestCoverage
+android.icu.dev.test.timezone.TimeZoneTest#TestCustomParse
+android.icu.dev.test.timezone.TimeZoneTest#TestDisplayName
+android.icu.dev.test.timezone.TimeZoneTest#TestDisplayName2
+android.icu.dev.test.timezone.TimeZoneTest#TestDisplayNamesMeta
+android.icu.dev.test.timezone.TimeZoneTest#TestDSTSavings
+android.icu.dev.test.timezone.TimeZoneTest#TestEquivalencyGroups
+android.icu.dev.test.timezone.TimeZoneTest#TestFebruary
+android.icu.dev.test.timezone.TimeZoneTest#TestFractionalDST
+android.icu.dev.test.timezone.TimeZoneTest#TestFreezable
+android.icu.dev.test.timezone.TimeZoneTest#TestGenericAPI
+android.icu.dev.test.timezone.TimeZoneTest#TestGetAvailableIDs913
+android.icu.dev.test.timezone.TimeZoneTest#TestGetAvailableIDsNew
+android.icu.dev.test.timezone.TimeZoneTest#TestGetIDForWindowsID
+android.icu.dev.test.timezone.TimeZoneTest#TestGetOffsetDate
+android.icu.dev.test.timezone.TimeZoneTest#TestGetRegion
+android.icu.dev.test.timezone.TimeZoneTest#TestGetWindowsID
+android.icu.dev.test.timezone.TimeZoneTest#TestHashCode
+android.icu.dev.test.timezone.TimeZoneTest#TestMark
+android.icu.dev.test.timezone.TimeZoneTest#TestObservesDaylightTime
+android.icu.dev.test.timezone.TimeZoneTest#TestOddTimeZoneNames
+android.icu.dev.test.timezone.TimeZoneTest#TestPRTOffset
+android.icu.dev.test.timezone.TimeZoneTest#TestRuleAPI
+android.icu.dev.test.timezone.TimeZoneTest#TestSetDefault
+android.icu.dev.test.timezone.TimeZoneTest#TestShortZoneIDs
+android.icu.dev.test.timezone.TimeZoneTest#TestSimpleTimeZoneSerialization
+android.icu.dev.test.timezone.TimeZoneTest#TestVariousAPI518
+android.icu.dev.test.timezone.TimeZoneTest#TestZoneFields
+android.icu.dev.test.timezone.TimeZoneTest#TestZoneMeta
+android.icu.dev.test.translit.AnyScriptTest#TestCommonDigits
+android.icu.dev.test.translit.AnyScriptTest#TestContext
+android.icu.dev.test.translit.AnyScriptTest#TestForWidth
+android.icu.dev.test.translit.AnyScriptTest#TestScripts
+android.icu.dev.test.translit.CompoundTransliteratorTest#TestConstruction
+android.icu.dev.test.translit.CompoundTransliteratorTest#TestGetTransliterator
+android.icu.dev.test.translit.CompoundTransliteratorTest#TestTransliterate
+android.icu.dev.test.translit.ErrorTest#TestRBTErrors
+android.icu.dev.test.translit.ErrorTest#TestTransliteratorErrors
+android.icu.dev.test.translit.ErrorTest#TestUnicodeSetErrors
+android.icu.dev.test.translit.JamoTest#TestJamo
+android.icu.dev.test.translit.JamoTest#TestPiecemeal
+android.icu.dev.test.translit.JamoTest#TestRealText
+android.icu.dev.test.translit.JamoTest#TestRoundTrip
+android.icu.dev.test.translit.RegexUtilitiesTest#TestBnf
+android.icu.dev.test.translit.RegexUtilitiesTest#TestCharacters
+android.icu.dev.test.translit.RegexUtilitiesTest#TestConstruction
+android.icu.dev.test.translit.RegexUtilitiesTest#TestUnicodeProperties
+android.icu.dev.test.translit.ReplaceableTest#Test
+android.icu.dev.test.translit.ReplaceableTest#Test5789
+android.icu.dev.test.translit.RoundTripTest#TestArabic
+android.icu.dev.test.translit.RoundTripTest#TestCyrillic
+android.icu.dev.test.translit.RoundTripTest#TestDevanagariLatin
+android.icu.dev.test.translit.RoundTripTest#Testel
+android.icu.dev.test.translit.RoundTripTest#TestGreek
+android.icu.dev.test.translit.RoundTripTest#TestGreekUNGEGN
+android.icu.dev.test.translit.RoundTripTest#TestHan
+android.icu.dev.test.translit.RoundTripTest#TestHangul
+android.icu.dev.test.translit.RoundTripTest#TestHangul2
+android.icu.dev.test.translit.RoundTripTest#TestHebrew
+android.icu.dev.test.translit.RoundTripTest#TestHiragana
+android.icu.dev.test.translit.RoundTripTest#TestInterIndic
+android.icu.dev.test.translit.RoundTripTest#TestJamo
+android.icu.dev.test.translit.RoundTripTest#TestKana
+android.icu.dev.test.translit.RoundTripTest#TestKatakana
+android.icu.dev.test.translit.RoundTripTest#TestSingle
+android.icu.dev.test.translit.RoundTripTest#TestThai
+android.icu.dev.test.translit.TestUnicodeProperty#TestBasic
+android.icu.dev.test.translit.TestUnicodeProperty#TestSymbolTable
+android.icu.dev.test.translit.TestUnicodeProperty#TestSymbolTable2
+android.icu.dev.test.translit.ThreadTest#TestAnyTranslit
+android.icu.dev.test.translit.ThreadTest#TestThreads
+android.icu.dev.test.translit.TransliteratorTest#TestAliasInverseID
+android.icu.dev.test.translit.TransliteratorTest#TestAlternateSyntax
+android.icu.dev.test.translit.TransliteratorTest#TestAnchorMasking
+android.icu.dev.test.translit.TransliteratorTest#TestAnchors
+android.icu.dev.test.translit.TransliteratorTest#TestAny
+android.icu.dev.test.translit.TransliteratorTest#TestAnyX
+android.icu.dev.test.translit.TransliteratorTest#TestArbitraryVariableValues
+android.icu.dev.test.translit.TransliteratorTest#TestBeginEnd
+android.icu.dev.test.translit.TransliteratorTest#TestBeginEndToRules
+android.icu.dev.test.translit.TransliteratorTest#TestCaseMap
+android.icu.dev.test.translit.TransliteratorTest#TestCasing
+android.icu.dev.test.translit.TransliteratorTest#TestCharUtils
+android.icu.dev.test.translit.TransliteratorTest#TestChinese
+android.icu.dev.test.translit.TransliteratorTest#TestCompoundFilter
+android.icu.dev.test.translit.TransliteratorTest#TestCompoundFilterID
+android.icu.dev.test.translit.TransliteratorTest#TestCompoundHex
+android.icu.dev.test.translit.TransliteratorTest#TestCompoundInverse
+android.icu.dev.test.translit.TransliteratorTest#TestCompoundInverseID
+android.icu.dev.test.translit.TransliteratorTest#TestCompoundKana
+android.icu.dev.test.translit.TransliteratorTest#TestCompoundLatinRT
+android.icu.dev.test.translit.TransliteratorTest#TestCompoundRBT
+android.icu.dev.test.translit.TransliteratorTest#TestContext
+android.icu.dev.test.translit.TransliteratorTest#TestCopyJ476
+android.icu.dev.test.translit.TransliteratorTest#TestCoverage
+android.icu.dev.test.translit.TransliteratorTest#TestCreateInstance
+android.icu.dev.test.translit.TransliteratorTest#TestCursorOffset
+android.icu.dev.test.translit.TransliteratorTest#TestDevanagariLatinRT
+android.icu.dev.test.translit.TransliteratorTest#TestDisplayName
+android.icu.dev.test.translit.TransliteratorTest#TestEmptyContext
+android.icu.dev.test.translit.TransliteratorTest#TestEscape
+android.icu.dev.test.translit.TransliteratorTest#TestFilterIDs
+android.icu.dev.test.translit.TransliteratorTest#TestFiltering
+android.icu.dev.test.translit.TransliteratorTest#TestFunction
+android.icu.dev.test.translit.TransliteratorTest#TestGetAvailableTargets
+android.icu.dev.test.translit.TransliteratorTest#TestGetAvailableVariants
+android.icu.dev.test.translit.TransliteratorTest#TestGurmukhiDevanagari
+android.icu.dev.test.translit.TransliteratorTest#TestHalfwidthFullwidth
+android.icu.dev.test.translit.TransliteratorTest#TestHangul
+android.icu.dev.test.translit.TransliteratorTest#TestHiraganaKatakana
+android.icu.dev.test.translit.TransliteratorTest#TestIDForms
+android.icu.dev.test.translit.TransliteratorTest#TestIncrementalProgress
+android.icu.dev.test.translit.TransliteratorTest#TestInlineSet
+android.icu.dev.test.translit.TransliteratorTest#TestInstantiation
+android.icu.dev.test.translit.TransliteratorTest#TestInterIndic
+android.icu.dev.test.translit.TransliteratorTest#TestInvalidBackRef
+android.icu.dev.test.translit.TransliteratorTest#TestInvalidPostContext
+android.icu.dev.test.translit.TransliteratorTest#TestJ277
+android.icu.dev.test.translit.TransliteratorTest#TestJ329
+android.icu.dev.test.translit.TransliteratorTest#TestKeyboard
+android.icu.dev.test.translit.TransliteratorTest#TestKeyboard2
+android.icu.dev.test.translit.TransliteratorTest#TestKeyboard3
+android.icu.dev.test.translit.TransliteratorTest#TestLiberalizedID
+android.icu.dev.test.translit.TransliteratorTest#TestLocaleInstantiation
+android.icu.dev.test.translit.TransliteratorTest#TestLocaleResource
+android.icu.dev.test.translit.TransliteratorTest#TestMulticharStringSet
+android.icu.dev.test.translit.TransliteratorTest#TestNameMap
+android.icu.dev.test.translit.TransliteratorTest#TestNewEngine
+android.icu.dev.test.translit.TransliteratorTest#TestNextLine
+android.icu.dev.test.translit.TransliteratorTest#TestNFDChainRBT
+android.icu.dev.test.translit.TransliteratorTest#TestNormalizationTransliterator
+android.icu.dev.test.translit.TransliteratorTest#TestNullInverse
+android.icu.dev.test.translit.TransliteratorTest#TestOutputSet
+android.icu.dev.test.translit.TransliteratorTest#TestParseError
+android.icu.dev.test.translit.TransliteratorTest#TestPatternQuoting
+android.icu.dev.test.translit.TransliteratorTest#TestPatternWhitespace
+android.icu.dev.test.translit.TransliteratorTest#TestPositionAPI
+android.icu.dev.test.translit.TransliteratorTest#TestPositionHandling
+android.icu.dev.test.translit.TransliteratorTest#TestPropertySet
+android.icu.dev.test.translit.TransliteratorTest#TestQuantifiedSegment
+android.icu.dev.test.translit.TransliteratorTest#TestQuantifier
+android.icu.dev.test.translit.TransliteratorTest#TestRegisterAlias
+android.icu.dev.test.translit.TransliteratorTest#TestRegistry
+android.icu.dev.test.translit.TransliteratorTest#TestRemove
+android.icu.dev.test.translit.TransliteratorTest#TestRuleBasedInverse
+android.icu.dev.test.translit.TransliteratorTest#TestSanskritLatinRT
+android.icu.dev.test.translit.TransliteratorTest#TestScriptAllCodepoints
+android.icu.dev.test.translit.TransliteratorTest#TestSegments
+android.icu.dev.test.translit.TransliteratorTest#TestSimpleRules
+android.icu.dev.test.translit.TransliteratorTest#TestSourceTargetSet
+android.icu.dev.test.translit.TransliteratorTest#TestSourceTargetSet2
+android.icu.dev.test.translit.TransliteratorTest#TestSourceTargetSetFilter
+android.icu.dev.test.translit.TransliteratorTest#TestSpecialCases
+android.icu.dev.test.translit.TransliteratorTest#TestSTV
+android.icu.dev.test.translit.TransliteratorTest#TestSupplemental
+android.icu.dev.test.translit.TransliteratorTest#TestSurrogateCasing
+android.icu.dev.test.translit.TransliteratorTest#TestT5160
+android.icu.dev.test.translit.TransliteratorTest#TestTeluguLatinRT
+android.icu.dev.test.translit.TransliteratorTest#TestThai
+android.icu.dev.test.translit.TransliteratorTest#TestTitleAccents
+android.icu.dev.test.translit.TransliteratorTest#TestToRules
+android.icu.dev.test.translit.TransliteratorTest#TestToRulesMark
+android.icu.dev.test.translit.TransliteratorTest#TestUndefinedVariable
+android.icu.dev.test.translit.TransliteratorTest#TestUserFunction
+android.icu.dev.test.translit.TransliteratorTest#TestVariableNames
+android.icu.dev.test.translit.TransliteratorTest#TestVariableRange
+android.icu.dev.test.translit.UnicodeMapTest#TestAMonkey
+android.icu.dev.test.translit.UnicodeMapTest#TestCloneAsThawed11721
+android.icu.dev.test.translit.UnicodeMapTest#TestIterations
+android.icu.dev.test.translit.UnicodeMapTest#TestModify
+android.icu.dev.test.translit.UnicodeMapTest#TestRemove
+android.icu.dev.test.util.BytesTrieTest#Test00Builder
+android.icu.dev.test.util.BytesTrieTest#Test10Empty
+android.icu.dev.test.util.BytesTrieTest#Test11_a
+android.icu.dev.test.util.BytesTrieTest#Test12_a_ab
+android.icu.dev.test.util.BytesTrieTest#Test20ShortestBranch
+android.icu.dev.test.util.BytesTrieTest#Test21Branches
+android.icu.dev.test.util.BytesTrieTest#Test22LongSequence
+android.icu.dev.test.util.BytesTrieTest#Test23LongBranch
+android.icu.dev.test.util.BytesTrieTest#Test24ValuesForState
+android.icu.dev.test.util.BytesTrieTest#Test30Compact
+android.icu.dev.test.util.BytesTrieTest#Test40GetUniqueValue
+android.icu.dev.test.util.BytesTrieTest#Test41GetNextBytes
+android.icu.dev.test.util.BytesTrieTest#Test50IteratorFromBranch
+android.icu.dev.test.util.BytesTrieTest#Test51IteratorFromLinearMatch
+android.icu.dev.test.util.BytesTrieTest#Test52TruncatingIteratorFromRoot
+android.icu.dev.test.util.BytesTrieTest#Test53TruncatingIteratorFromLinearMatchShort
+android.icu.dev.test.util.BytesTrieTest#Test54TruncatingIteratorFromLinearMatchLong
+android.icu.dev.test.util.BytesTrieTest#Test59IteratorFromBytes
+android.icu.dev.test.util.CharsTrieTest#Test00Builder
+android.icu.dev.test.util.CharsTrieTest#Test10Empty
+android.icu.dev.test.util.CharsTrieTest#Test11_a
+android.icu.dev.test.util.CharsTrieTest#Test12_a_ab
+android.icu.dev.test.util.CharsTrieTest#Test20ShortestBranch
+android.icu.dev.test.util.CharsTrieTest#Test21Branches
+android.icu.dev.test.util.CharsTrieTest#Test22LongSequence
+android.icu.dev.test.util.CharsTrieTest#Test23LongBranch
+android.icu.dev.test.util.CharsTrieTest#Test24ValuesForState
+android.icu.dev.test.util.CharsTrieTest#Test30Compact
+android.icu.dev.test.util.CharsTrieTest#Test31FirstForCodePoint
+android.icu.dev.test.util.CharsTrieTest#Test32NextForCodePoint
+android.icu.dev.test.util.CharsTrieTest#Test37LargeTrie
+android.icu.dev.test.util.CharsTrieTest#Test40GetUniqueValue
+android.icu.dev.test.util.CharsTrieTest#Test41GetNextChars
+android.icu.dev.test.util.CharsTrieTest#Test50IteratorFromBranch
+android.icu.dev.test.util.CharsTrieTest#Test51IteratorFromLinearMatch
+android.icu.dev.test.util.CharsTrieTest#Test52TruncatingIteratorFromRoot
+android.icu.dev.test.util.CharsTrieTest#Test53TruncatingIteratorFromLinearMatchShort
+android.icu.dev.test.util.CharsTrieTest#Test54TruncatingIteratorFromLinearMatchLong
+android.icu.dev.test.util.CharsTrieTest#Test59IteratorFromChars
+android.icu.dev.test.util.CompactArrayTest#TestByteArrayCoverage
+android.icu.dev.test.util.CompactArrayTest#TestCharArrayCoverage
+android.icu.dev.test.util.CurrencyTest#TestAPI
+android.icu.dev.test.util.CurrencyTest#TestAvailableCurrencyCodes
+android.icu.dev.test.util.CurrencyTest#TestCoverage
+android.icu.dev.test.util.CurrencyTest#TestCurrencyData
+android.icu.dev.test.util.CurrencyTest#TestCurrencyDisplayNames
+android.icu.dev.test.util.CurrencyTest#TestCurrencyInfoCtor
+android.icu.dev.test.util.CurrencyTest#TestCurrencyKeyword
+android.icu.dev.test.util.CurrencyTest#TestCurrencyMetaInfo
+android.icu.dev.test.util.CurrencyTest#testCurrencyMetaInfoRanges
+android.icu.dev.test.util.CurrencyTest#testCurrencyMetaInfoRangesWithLongs
+android.icu.dev.test.util.CurrencyTest#TestDeprecatedCurrencyFormat
+android.icu.dev.test.util.CurrencyTest#TestGetAvailableCurrencies
+android.icu.dev.test.util.CurrencyTest#TestGetDisplayName
+android.icu.dev.test.util.CurrencyTest#TestGetKeywordValues
+android.icu.dev.test.util.CurrencyTest#TestGetNumericCode
+android.icu.dev.test.util.CurrencyTest#TestIsAvailable
+android.icu.dev.test.util.CurrencyTest#TestNames
+android.icu.dev.test.util.CurrencyTest#TestRegistration
+android.icu.dev.test.util.CurrencyTest#TestWithTender
+android.icu.dev.test.util.DebugUtilitiesTest#TestStrings
+android.icu.dev.test.util.GenderInfoTest#TestEmpty
+android.icu.dev.test.util.GenderInfoTest#TestFallback
+android.icu.dev.test.util.GenderInfoTest#TestOne
+android.icu.dev.test.util.GenderInfoTest#TestOther
+android.icu.dev.test.util.ICUBinaryTest#TestReadHeader
+android.icu.dev.test.util.ICUResourceBundleCollationTest#TestFunctionalEquivalent
+android.icu.dev.test.util.ICUResourceBundleCollationTest#TestGetWithFallback
+android.icu.dev.test.util.ICUResourceBundleCollationTest#TestKeywordValues
+android.icu.dev.test.util.ICUResourceBundleCollationTest#TestOpen
+android.icu.dev.test.util.ICUResourceBundleTest#TestAlias
+android.icu.dev.test.util.ICUResourceBundleTest#TestAliases
+android.icu.dev.test.util.ICUResourceBundleTest#TestAliasFallback
+android.icu.dev.test.util.ICUResourceBundleTest#TestBasicTypes
+android.icu.dev.test.util.ICUResourceBundleTest#TestCircularAliases
+android.icu.dev.test.util.ICUResourceBundleTest#TestCLDRStyleAliases
+android.icu.dev.test.util.ICUResourceBundleTest#TestCoverage
+android.icu.dev.test.util.ICUResourceBundleTest#TestFunctionalEquivalent
+android.icu.dev.test.util.ICUResourceBundleTest#TestGetResources
+android.icu.dev.test.util.ICUResourceBundleTest#TestGetWithFallback
+android.icu.dev.test.util.ICUResourceBundleTest#TestICUGetKeysAtTopLevel
+android.icu.dev.test.util.ICUResourceBundleTest#TestICUGetKeysForResourceItem
+android.icu.dev.test.util.ICUResourceBundleTest#TestJavaULocaleBundleLoading
+android.icu.dev.test.util.ICUResourceBundleTest#TestJB3879
+android.icu.dev.test.util.ICUResourceBundleTest#TestJB4102
+android.icu.dev.test.util.ICUResourceBundleTest#TestLoadingStatus
+android.icu.dev.test.util.ICUResourceBundleTest#TestLocaleDisplayNames
+android.icu.dev.test.util.ICUResourceBundleTest#TestNorwegian
+android.icu.dev.test.util.ICUResourceBundleTest#TestOpen
+android.icu.dev.test.util.ICUResourceBundleTest#TestPreventFallback
+android.icu.dev.test.util.ICUResourceBundleTest#TestResourceBundleWrapper
+android.icu.dev.test.util.ICUResourceBundleTest#TestT6844
+android.icu.dev.test.util.ICUResourceBundleTest#TestTable32
+android.icu.dev.test.util.ICUResourceBundleTest#TestUResourceBundleCoverage
+android.icu.dev.test.util.ICUResourceBundleTest#TestXPathAlias
+android.icu.dev.test.util.ICUServiceTest#TestAPI
+android.icu.dev.test.util.ICUServiceTest#TestCoverage
+android.icu.dev.test.util.ICUServiceTest#TestLocale
+android.icu.dev.test.util.ICUServiceTest#TestWrapFactory
+android.icu.dev.test.util.ICUServiceThreadTest#Test00_ConcurrentGet
+android.icu.dev.test.util.ICUServiceThreadTest#Test01_ConcurrentGetVisible
+android.icu.dev.test.util.ICUServiceThreadTest#Test02_ConcurrentGetDisplay
+android.icu.dev.test.util.ICUServiceThreadTest#Test03_ConcurrentRegUnreg
+android.icu.dev.test.util.ICUServiceThreadTest#Test04_WitheringService
+android.icu.dev.test.util.ICUServiceThreadTest#Test05_ConcurrentEverything
+android.icu.dev.test.util.LocaleAliasCollationTest#TestCollation
+android.icu.dev.test.util.LocaleAliasTest#TestCalendar
+android.icu.dev.test.util.LocaleAliasTest#TestDateFormat
+android.icu.dev.test.util.LocaleAliasTest#TestDisplayName
+android.icu.dev.test.util.LocaleAliasTest#TestULocale
+android.icu.dev.test.util.LocaleAliasTest#TestUResourceBundle
+android.icu.dev.test.util.LocaleBuilderTest#TestLocaleBuilder
+android.icu.dev.test.util.LocaleBuilderTest#TestSetLocale
+android.icu.dev.test.util.LocaleDataTest#TestCoverage
+android.icu.dev.test.util.LocaleDataTest#TestEnglishExemplarCharacters
+android.icu.dev.test.util.LocaleDataTest#TestExemplarSet
+android.icu.dev.test.util.LocaleDataTest#TestExemplarSet2
+android.icu.dev.test.util.LocaleDataTest#TestExemplarSetTypes
+android.icu.dev.test.util.LocaleDataTest#TestFallback
+android.icu.dev.test.util.LocaleDataTest#TestLocaleDisplayPattern
+android.icu.dev.test.util.LocaleDataTest#TestMeasurementSystem
+android.icu.dev.test.util.LocaleDataTest#TestPaperSize
+android.icu.dev.test.util.LocaleMatcherTest#Test8288
+android.icu.dev.test.util.LocaleMatcherTest#testAsymmetry
+android.icu.dev.test.util.LocaleMatcherTest#testBasics
+android.icu.dev.test.util.LocaleMatcherTest#testBestMatchForTraditionalChinese
+android.icu.dev.test.util.LocaleMatcherTest#testChinese
+android.icu.dev.test.util.LocaleMatcherTest#testEmpty
+android.icu.dev.test.util.LocaleMatcherTest#testenGB
+android.icu.dev.test.util.LocaleMatcherTest#testExactMatches
+android.icu.dev.test.util.LocaleMatcherTest#testFallback
+android.icu.dev.test.util.LocaleMatcherTest#testFallbacks
+android.icu.dev.test.util.LocaleMatcherTest#testGetBestMatchForList_closeEnoughMatchOnMaximized
+android.icu.dev.test.util.LocaleMatcherTest#testGetBestMatchForList_exactMatch
+android.icu.dev.test.util.LocaleMatcherTest#testGetBestMatchForList_matchOnMaximized
+android.icu.dev.test.util.LocaleMatcherTest#testGetBestMatchForList_matchOnMaximized2
+android.icu.dev.test.util.LocaleMatcherTest#testGetBestMatchForList_noMatchOnMaximized
+android.icu.dev.test.util.LocaleMatcherTest#testGetBestMatchForList_simpleVariantMatch
+android.icu.dev.test.util.LocaleMatcherTest#testGetBestMatchForPortuguese
+android.icu.dev.test.util.LocaleMatcherTest#testGetBestMatch_googlePseudoLocales
+android.icu.dev.test.util.LocaleMatcherTest#testGetBestMatch_regionDistance
+android.icu.dev.test.util.LocaleMatcherTest#testHK
+android.icu.dev.test.util.LocaleMatcherTest#TestLocaleMatcherCoverage
+android.icu.dev.test.util.LocaleMatcherTest#testMatch_exact
+android.icu.dev.test.util.LocaleMatcherTest#testMatchGrandfatheredCode
+android.icu.dev.test.util.LocaleMatcherTest#testMatch_matchOnMazimized
+android.icu.dev.test.util.LocaleMatcherTest#testMatch_none
+android.icu.dev.test.util.LocaleMatcherTest#testOverrideData
+android.icu.dev.test.util.LocaleMatcherTest#testParentLocales
+android.icu.dev.test.util.LocaleMatcherTest#testPerf
+android.icu.dev.test.util.LocaleMatcherTest#testRegionalSpecials
+android.icu.dev.test.util.LocaleMatcherTest#testSpecials
+android.icu.dev.test.util.LocaleMatcherTest#testUndefined
+android.icu.dev.test.util.LocaleMatcherTest#testVariantWithScriptMatch
+android.icu.dev.test.util.LocaleMatcherTest#testVariantWithScriptMatch2
+android.icu.dev.test.util.LocalePriorityListTest#testLanguagePriorityList
+android.icu.dev.test.util.RegionTest#TestAvailableTerritories
+android.icu.dev.test.util.RegionTest#TestContains
+android.icu.dev.test.util.RegionTest#TestGetContainedRegions
+android.icu.dev.test.util.RegionTest#TestGetContainedRegionsWithType
+android.icu.dev.test.util.RegionTest#TestGetContainingRegion
+android.icu.dev.test.util.RegionTest#TestGetContainingRegionWithType
+android.icu.dev.test.util.RegionTest#TestGetInstanceInt
+android.icu.dev.test.util.RegionTest#TestGetInstanceString
+android.icu.dev.test.util.RegionTest#TestGetPreferredValues
+android.icu.dev.test.util.RegionTest#TestKnownRegions
+android.icu.dev.test.util.SimplePatternFormatterTest#TestBigPlaceholder
+android.icu.dev.test.util.SimplePatternFormatterTest#TestFormatReplaceNoOptimization
+android.icu.dev.test.util.SimplePatternFormatterTest#TestFormatReplaceNoOptimizationLeadingPlaceholderUsedTwice
+android.icu.dev.test.util.SimplePatternFormatterTest#TestFormatReplaceNoOptimizationLeadingText
+android.icu.dev.test.util.SimplePatternFormatterTest#TestFormatReplaceNoOptimizationNoOffsets
+android.icu.dev.test.util.SimplePatternFormatterTest#TestFormatReplaceOptimization
+android.icu.dev.test.util.SimplePatternFormatterTest#TestFormatReplaceOptimizationNoOffsets
+android.icu.dev.test.util.SimplePatternFormatterTest#TestFormatUseAppendToAsPlaceholder
+android.icu.dev.test.util.SimplePatternFormatterTest#TestGetTextWithNoPlaceholders
+android.icu.dev.test.util.SimplePatternFormatterTest#TestOnePlaceholder
+android.icu.dev.test.util.SimplePatternFormatterTest#TestQuotingLikeMessageFormat
+android.icu.dev.test.util.SimplePatternFormatterTest#TestSyntaxErrors
+android.icu.dev.test.util.SimplePatternFormatterTest#TestTooFewPlaceholderValues
+android.icu.dev.test.util.SimplePatternFormatterTest#TestWithNoPlaceholders
+android.icu.dev.test.util.SimplePatternFormatterTest#TestWithPlaceholders
+android.icu.dev.test.util.StringTokenizerTest#TestAdd_int
+android.icu.dev.test.util.StringTokenizerTest#TestAdd_int_int
+android.icu.dev.test.util.StringTokenizerTest#TestBug4423
+android.icu.dev.test.util.StringTokenizerTest#TestCharAt
+android.icu.dev.test.util.StringTokenizerTest#TestComplement_int_int
+android.icu.dev.test.util.StringTokenizerTest#TestComplement_String
+android.icu.dev.test.util.StringTokenizerTest#TestConstructors
+android.icu.dev.test.util.StringTokenizerTest#TestContains_int
+android.icu.dev.test.util.StringTokenizerTest#TestContains_int_int
+android.icu.dev.test.util.StringTokenizerTest#TestContainsNone
+android.icu.dev.test.util.StringTokenizerTest#TestCountTokens
+android.icu.dev.test.util.StringTokenizerTest#TestCountTokensNoCoalesce
+android.icu.dev.test.util.StringTokenizerTest#Test_GeneratePattern
+android.icu.dev.test.util.StringTokenizerTest#TestGetRegexEquivalent
+android.icu.dev.test.util.StringTokenizerTest#TestGetSingleCP
+android.icu.dev.test.util.StringTokenizerTest#TestIndexOf
+android.icu.dev.test.util.StringTokenizerTest#TestMatches
+android.icu.dev.test.util.StringTokenizerTest#TestMatchesAt
+android.icu.dev.test.util.StringTokenizerTest#TestMatchRest
+android.icu.dev.test.util.StringTokenizerTest#TestNextDelimiterToken
+android.icu.dev.test.util.StringTokenizerTest#TestNextNewDelimiters
+android.icu.dev.test.util.StringTokenizerTest#TestNextNonDelimiterToken
+android.icu.dev.test.util.StringTokenizerTest#TestNoCoalesce
+android.icu.dev.test.util.StringTokenizerTest#TestRemove
+android.icu.dev.test.util.StringTokenizerTest#TestRemoveAllString
+android.icu.dev.test.util.StringTokenizerTest#TestRetain_int_int
+android.icu.dev.test.util.StringTokenizerTest#TestRetain_String
+android.icu.dev.test.util.StringTokenizerTest#TestSupplementary
+android.icu.dev.test.util.TextTrieMapTest#TestCaseInsensitive
+android.icu.dev.test.util.TextTrieMapTest#TestCaseSensitive
+android.icu.dev.test.util.Trie2Test#TestCharSequenceIterator
+android.icu.dev.test.util.Trie2Test#TestRanges
+android.icu.dev.test.util.Trie2Test#TestTrie2API
+android.icu.dev.test.util.Trie2Test#TestTrie2WritableAPI
+android.icu.dev.test.util.TrieTest#TestDummyCharTrie
+android.icu.dev.test.util.TrieTest#TestDummyIntTrie
+android.icu.dev.test.util.TrieTest#TestIntTrie
+android.icu.dev.test.util.ULocaleCollationTest#TestCollator
+android.icu.dev.test.util.ULocaleCollationTest#TestIllformedLocale
+android.icu.dev.test.util.ULocaleCollationTest#TestNameList
+android.icu.dev.test.util.ULocaleTest#Test4735
+android.icu.dev.test.util.ULocaleTest#TestAcceptLanguage
+android.icu.dev.test.util.ULocaleTest#TestAcceptLanguage2
+android.icu.dev.test.util.ULocaleTest#TestAddLikelySubtags
+android.icu.dev.test.util.ULocaleTest#TestBamBm
+android.icu.dev.test.util.ULocaleTest#TestBasicGetters
+android.icu.dev.test.util.ULocaleTest#TestCalendar
+android.icu.dev.test.util.ULocaleTest#TestCanonicalization
+android.icu.dev.test.util.ULocaleTest#TestCategoryDefault
+android.icu.dev.test.util.ULocaleTest#TestChineseToLocale
+android.icu.dev.test.util.ULocaleTest#TestCLDRVersion
+android.icu.dev.test.util.ULocaleTest#TestComparable
+android.icu.dev.test.util.ULocaleTest#TestCoverage
+android.icu.dev.test.util.ULocaleTest#TestDateFormat
+android.icu.dev.test.util.ULocaleTest#TestDisplayKeyword
+android.icu.dev.test.util.ULocaleTest#TestDisplayLanguageWithDialectCoverage
+android.icu.dev.test.util.ULocaleTest#TestDisplayNames
+android.icu.dev.test.util.ULocaleTest#TestDisplayNameWithDialectCoverage
+android.icu.dev.test.util.ULocaleTest#TestDisplayScriptCoverage
+android.icu.dev.test.util.ULocaleTest#TestDisplayWithKeyword
+android.icu.dev.test.util.ULocaleTest#TestExtension
+android.icu.dev.test.util.ULocaleTest#TestForLanguageTag
+android.icu.dev.test.util.ULocaleTest#TestForLocale
+android.icu.dev.test.util.ULocaleTest#TestGetAvailable
+android.icu.dev.test.util.ULocaleTest#TestGetFallback
+android.icu.dev.test.util.ULocaleTest#TestIsRightToLeft
+android.icu.dev.test.util.ULocaleTest#TestJavaLocaleCompatibility
+android.icu.dev.test.util.ULocaleTest#TestJB3962
+android.icu.dev.test.util.ULocaleTest#TestMinimize
+android.icu.dev.test.util.ULocaleTest#TestNumberFormat
+android.icu.dev.test.util.ULocaleTest#TestObsoleteNames
+android.icu.dev.test.util.ULocaleTest#TestOrientation
+android.icu.dev.test.util.ULocaleTest#TestPrefixes
+android.icu.dev.test.util.ULocaleTest#TestSetULocaleKeywords
+android.icu.dev.test.util.ULocaleTest#TestToLanguageTag
+android.icu.dev.test.util.ULocaleTest#TestToLegacyKey
+android.icu.dev.test.util.ULocaleTest#TestToLegacyType
+android.icu.dev.test.util.ULocaleTest#TestToLocale
+android.icu.dev.test.util.ULocaleTest#TestToUnicodeLocaleKey
+android.icu.dev.test.util.ULocaleTest#TestToUnicodeLocaleType
+android.icu.dev.test.util.ULocaleTest#TestUnicodeLocaleExtension
+android.icu.dev.test.util.UtilityTest#TestAssert
+android.icu.dev.test.util.UtilityTest#TestByteArrayWrapper
+android.icu.dev.test.util.UtilityTest#TestCaseInsensitiveString
+android.icu.dev.test.util.UtilityTest#TestCompareUnsigned
+android.icu.dev.test.util.UtilityTest#TestFormat
+android.icu.dev.test.util.UtilityTest#TestHighBit
+android.icu.dev.test.util.UtilityTest#TestSourceLocation
+android.icu.dev.test.util.UtilityTest#TestUnescape
+android.icu.dev.test.util.UtilityTest#TestUnicodeSet
+android.icu.dev.test.util.VersionInfoTest#TestComparable
+android.icu.dev.test.util.VersionInfoTest#TestCompare
+android.icu.dev.test.util.VersionInfoTest#TestGetter
+android.icu.dev.test.util.VersionInfoTest#TestInstance
+android.icu.dev.test.util.VersionInfoTest#TestMultiThread
+android.icu.dev.test.util.VersionInfoTest#TesttoString
diff --git a/tests/tests/icu/tools/android/icu/cts/tools/GenerateTestCaseXML.java b/tests/tests/icu/tools/android/icu/cts/tools/GenerateTestCaseXML.java
new file mode 100644
index 0000000..4cd0068
--- /dev/null
+++ b/tests/tests/icu/tools/android/icu/cts/tools/GenerateTestCaseXML.java
@@ -0,0 +1,245 @@
+package android.icu.cts.tools;
+
+import com.google.common.base.Joiner;
+import com.android.compatibility.common.util.AbiUtils;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+/**
+ * Generates an XML file suitable for CTS version 1.
+ *
+ * <p>A lot of this code is copied from {@code tools/utils/DescriptionGenerator.java} and
+ * {@code tools/utils/CollectAllTests.java}. Ideally, that code should have been refactored to make
+ * it usable in this case but that would have taken quite a lot of time and given that CTS version 1
+ * is going away anyway and CTS version 2 doesn't need an XML file this seemed like the best
+ * approach.
+ */
+public class GenerateTestCaseXML {
+
+  private static final String ATTRIBUTE_RUNNER = "runner";
+
+  private static final String ATTRIBUTE_PACKAGE = "appPackageName";
+
+  private static final String ATTRIBUTE_NS = "appNameSpace";
+
+  static final String TAG_PACKAGE = "TestPackage";
+
+  static final String TAG_SUITE = "TestSuite";
+
+  static final String TAG_CASE = "TestCase";
+
+  static final String TAG_TEST = "Test";
+
+  static final String ATTRIBUTE_NAME_VERSION = "version";
+
+  static final String ATTRIBUTE_VALUE_VERSION = "1.0";
+
+  static final String ATTRIBUTE_NAME_FRAMEWORK = "AndroidFramework";
+
+  static final String ATTRIBUTE_VALUE_FRAMEWORK = "Android 1.0";
+
+  static final String ATTRIBUTE_NAME = "name";
+
+  static final String ATTRIBUTE_ABIS = "abis";
+
+  public static void main(String[] args) throws Exception {
+    if (args.length != 3) {
+      throw new IllegalStateException(
+          "... <test-list-path> <architecture> <output-file-path");
+    }
+
+    String testListPath = args[0];
+    String architecture = args[1];
+    String outputFilePath = args[2];
+
+    File testListFile = new File(testListPath);
+    String abis = Joiner.on(" ").join(AbiUtils.getAbisForArch(architecture));
+    File testCaseXML = new File(outputFilePath);
+
+    TestSuite root = new TestSuite("");
+    try (FileReader fileReader = new FileReader(testListFile);
+         BufferedReader reader = new BufferedReader(fileReader)) {
+
+      String line;
+      while ((line = reader.readLine()) != null) {
+        int index = line.indexOf('#');
+        String className = line.substring(0, index);
+        String methodName = line.substring(index + 1);
+
+        root.addTest(className, methodName);
+      }
+    }
+
+    Document mDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
+
+    Element testPackageElem = mDoc.createElement(TAG_PACKAGE);
+    mDoc.appendChild(testPackageElem);
+
+    setAttribute(testPackageElem, ATTRIBUTE_NAME_VERSION, ATTRIBUTE_VALUE_VERSION);
+    setAttribute(testPackageElem, ATTRIBUTE_NAME_FRAMEWORK, ATTRIBUTE_VALUE_FRAMEWORK);
+    setAttribute(testPackageElem, ATTRIBUTE_NAME, "CtsIcuTestCases");
+    setAttribute(testPackageElem, ATTRIBUTE_RUNNER, "android.icu.cts.IcuTestRunnerForCtsV1");
+    setAttribute(testPackageElem, ATTRIBUTE_PACKAGE, "android.icu.dev.test");
+    setAttribute(testPackageElem, ATTRIBUTE_NS, "android.icu.cts");
+
+    root.addChildInformation(testPackageElem, abis);
+
+    Transformer t = TransformerFactory.newInstance().newTransformer();
+
+    // enable indent in result file
+    t.setOutputProperty("indent", "yes");
+    t.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
+
+    File directory = testCaseXML.getParentFile();
+    if (!directory.exists() && !directory.mkdirs()) {
+      throw new IOException("Could not create directory: " + directory);
+    }
+
+    t.transform(new DOMSource(mDoc), new StreamResult(new FileOutputStream(testCaseXML)));
+  }
+
+  /**
+   * Set the attribute of element.
+   *
+   * @param elem The element to be set attribute.
+   * @param name The attribute name.
+   * @param value The attribute value.
+   */
+  protected static void setAttribute(Node elem, String name, String value) {
+    Attr attr = elem.getOwnerDocument().createAttribute(name);
+    attr.setNodeValue(value);
+
+    elem.getAttributes().setNamedItem(attr);
+  }
+
+
+  /**
+   * The contents of a {@link TestSuite}, may be a {@link TestSuite} or a {@link TestCase}.
+   */
+  private static abstract class SuiteContent {
+
+    private final String name;
+
+    private SuiteContent(String name) {
+      this.name = name;
+    }
+
+    public String getName() {
+      return name;
+    }
+
+    public abstract void addInformation(Element parent, String abis);
+  }
+
+  public static class TestSuite extends SuiteContent {
+
+    private Map<String, SuiteContent> name2Content = new TreeMap<>();
+
+    public TestSuite(String name) {
+      super(name);
+    }
+
+    public TestSuite getSuite(String name) {
+      return getSuiteContent(TestSuite.class, name);
+    }
+
+    public TestCase getTestCase(String name) {
+      return getSuiteContent(TestCase.class, name);
+    }
+
+    private <S extends SuiteContent> S getSuiteContent(Class<? extends S> contentClass,
+        String name) {
+      SuiteContent content = name2Content.get(name);
+      S s;
+      if (content == null) {
+        try {
+          s = contentClass.getConstructor(String.class).newInstance(name);
+        } catch (Exception e) {
+          throw new RuntimeException("Could not create instance of " + contentClass, e);
+        }
+        name2Content.put(name, s);
+      } else if (contentClass.isInstance(content)) {
+        s = contentClass.cast(content);
+      } else {
+        throw new IllegalStateException("Expected " + this
+            + " to have a TestSuite called '" + name + "' but has "
+            + content + " instead");
+      }
+      return s;
+    }
+
+    public void addTest(String className, String methodName) {
+      int index = className.indexOf('.');
+      if (index == -1) {
+        TestCase testCase = getTestCase(className);
+        testCase.addMethod(methodName);
+      } else {
+        String suiteName = className.substring(0, index);
+        TestSuite childSuite = getSuite(suiteName);
+        childSuite.addTest(className.substring(index + 1), methodName);
+      }
+    }
+
+    @Override
+    public void addInformation(Element parent, String abis) {
+      Element suiteElement = appendElement(parent, TAG_SUITE);
+
+      setAttribute(suiteElement, ATTRIBUTE_NAME, getName());
+
+      addChildInformation(suiteElement, abis);
+    }
+
+    public void addChildInformation(Element parent, String abis) {
+      for (SuiteContent suiteContent : name2Content.values()) {
+        suiteContent.addInformation(parent, abis);
+      }
+    }
+  }
+
+  public static class TestCase extends SuiteContent {
+
+    private final Set<String> methods = new TreeSet<>();
+
+    public TestCase(String name) {
+      super(name);
+    }
+
+    @Override
+    public void addInformation(Element parent, String abis) {
+      Element testCaseElement = appendElement(parent, TAG_CASE);
+      setAttribute(testCaseElement, ATTRIBUTE_NAME, getName());
+      setAttribute(testCaseElement, ATTRIBUTE_ABIS, abis);
+
+      for (String method : methods) {
+        Element testElement = appendElement(testCaseElement, TAG_TEST);
+        setAttribute(testElement, ATTRIBUTE_NAME, method);
+      }
+    }
+
+    public void addMethod(String methodName) {
+      methods.add(methodName);
+    }
+  }
+
+  private static Element appendElement(Element parent, String tagName) {
+    Element testCaseElement = parent.getOwnerDocument().createElement(tagName);
+    parent.appendChild(testCaseElement);
+    return testCaseElement;
+  }
+}
diff --git a/tests/tests/icu/tools/update-test-list.sh b/tests/tests/icu/tools/update-test-list.sh
new file mode 100755
index 0000000..e73cbfb
--- /dev/null
+++ b/tests/tests/icu/tools/update-test-list.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+
+# Extract a flat list of tests from a CTSv2 generated host log for use when generating the CTSv1
+# required list of tests.
+ZIP=$1
+
+TMP_DIR=/tmp/update-test-list-$$
+mkdir -p $TMP_DIR
+
+unzip $ZIP host_log.txt -d $TMP_DIR
+
+HOST_LOG=$TMP_DIR/host_log.txt
+
+ICU_DIR=$(dirname $0)/../
+
+grep "ModuleListener.testStarted" $HOST_LOG \
+    | sed 's%.*(\([^#]\+\)#\([^)]\+\))%\1#\2%' | sort > $ICU_DIR/test-list.txt
diff --git a/tests/tests/jni/Android.mk b/tests/tests/jni/Android.mk
index 1aeb8b7..7a9504d 100644
--- a/tests/tests/jni/Android.mk
+++ b/tests/tests/jni/Android.mk
@@ -27,9 +27,12 @@
 # When built, explicitly put it in the data partition.
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
 
-LOCAL_JNI_SHARED_LIBRARIES := libjnitest
+LOCAL_JNI_SHARED_LIBRARIES := libjnitest libnativehelper_compat_libc++
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
diff --git a/tests/tests/jni/AndroidManifest.xml b/tests/tests/jni/AndroidManifest.xml
index 843b322..2724573 100644
--- a/tests/tests/jni/AndroidManifest.xml
+++ b/tests/tests/jni/AndroidManifest.xml
@@ -15,7 +15,7 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.jni">
+    package="android.jni.cts">
 
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <application>
@@ -24,7 +24,7 @@
 
     <!-- This is a self-instrumenting test package. -->
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.cts.jni"
+                     android:targetPackage="android.jni.cts"
                      android:label="CTS tests of calling native code via JNI">
         <meta-data android:name="listener"
             android:value="com.android.cts.runner.CtsTestRunListener" />
diff --git a/tests/tests/jni/AndroidTest.xml b/tests/tests/jni/AndroidTest.xml
new file mode 100644
index 0000000..8ec1df6
--- /dev/null
+++ b/tests/tests/jni/AndroidTest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS JNI test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsJniTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.jni.cts" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/tests/jni/libjnitest/Android.mk b/tests/tests/jni/libjnitest/Android.mk
index 396e161..7140de4 100644
--- a/tests/tests/jni/libjnitest/Android.mk
+++ b/tests/tests/jni/libjnitest/Android.mk
@@ -30,12 +30,16 @@
 	android_jni_cts_JniCTest.c \
 	android_jni_cts_JniCppTest.cpp \
 	android_jni_cts_JniStaticTest.cpp \
+	android_jni_cts_LinkerNamespacesTest.cpp \
 	android_jni_cts_StaticNonce.c \
 	helper.c \
 	register.c
 
 LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
 
-LOCAL_SHARED_LIBRARIES := libnativehelper liblog
+LOCAL_SHARED_LIBRARIES := libdl liblog libnativehelper_compat_libc++
+
+LOCAL_SDK_VERSION := 23
+LOCAL_NDK_STL_VARIANT := c++_static
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/tests/tests/jni/libjnitest/android_jni_cts_LinkerNamespacesTest.cpp b/tests/tests/jni/libjnitest/android_jni_cts_LinkerNamespacesTest.cpp
new file mode 100644
index 0000000..f4edcb1
--- /dev/null
+++ b/tests/tests/jni/libjnitest/android_jni_cts_LinkerNamespacesTest.cpp
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Tests accessibility of platform native libraries
+ */
+
+#include <dirent.h>
+#include <dlfcn.h>
+#include <fcntl.h>
+#include <jni.h>
+#include <JNIHelp.h>
+#include <libgen.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <list>
+#include <string>
+#include <unordered_set>
+#include <vector>
+
+#include "ScopedLocalRef.h"
+#include "ScopedUtfChars.h"
+
+#if defined(__LP64__)
+static const std::string kSystemLibraryPath = "/system/lib64";
+static const std::string kVendorLibraryPath = "/vendor/lib64";
+#else
+static const std::string kSystemLibraryPath = "/system/lib";
+static const std::string kVendorLibraryPath = "/vendor/lib";
+#endif
+
+static std::unordered_set<std::string> kSystemPublicLibraries = {
+    "libandroid.so",
+    "libcamera2ndk.so",
+    "libc.so",
+    "libdl.so",
+    "libEGL.so",
+    "libGLESv1_CM.so",
+    "libGLESv2.so",
+    "libGLESv3.so",
+    "libicui18n.so",
+    "libicuuc.so",
+    "libjnigraphics.so",
+    "liblog.so",
+    "libmediandk.so",
+    "libm.so",
+    "libOpenMAXAL.so",
+    "libOpenSLES.so",
+    "libRS.so",
+    "libstdc++.so",
+    "libvulkan.so",
+    "libwebviewchromium_plat_support.so",
+    "libz.so"
+  };
+
+// This is not complete list - just a small subset
+// of the libraries that should reside in /system/lib
+// (in addition to kSystemPublicLibraries)
+static std::unordered_set<std::string> kSystemLibraries = {
+    "libart.so",
+    "libandroid_runtime.so",
+    "libbinder.so",
+    "libcutils.so",
+    "libgui.so",
+    "libmedia.so",
+    "libnativehelper.so",
+    "libstagefright.so",
+    "libui.so",
+    "libutils.so",
+  };
+
+template <typename F>
+static bool for_each_file(const std::string& dir, F functor, std::string* error_msg) {
+  auto dir_deleter = [](DIR* handle) { closedir(handle); };
+  std::unique_ptr<DIR, decltype(dir_deleter)> dirp(opendir(dir.c_str()), dir_deleter);
+  if (dirp == nullptr) {
+    *error_msg = strerror(errno);
+    return false;
+  }
+
+  dirent* dp;
+  while ((dp = readdir(dirp.get())) != nullptr) {
+    // skip "." and ".."
+    if (strcmp(".", dp->d_name) == 0 ||
+        strcmp("..", dp->d_name) == 0) {
+      continue;
+    }
+
+    if (!functor(dp->d_name, error_msg)) {
+      return false;
+    }
+  }
+
+  return true;
+}
+
+static bool should_be_accessible(const std::string& public_library_path,
+                                 const std::unordered_set<std::string>& public_libraries,
+                                 const std::string& path) {
+  std::string name = basename(path.c_str());
+  return (public_libraries.find(name) != public_libraries.end()) &&
+         (public_library_path + "/" + name == path);
+}
+
+static bool is_directory(const std::string path) {
+  struct stat sb;
+  if (stat(path.c_str(), &sb) != -1) {
+    return S_ISDIR(sb.st_mode);
+  }
+
+  return false;
+}
+
+static bool is_libdl(const std::string path) {
+  return kSystemLibraryPath + "/libdl.so" == path;
+}
+
+static bool check_lib(const std::string& public_library_path,
+                      const std::unordered_set<std::string>& public_libraries,
+                      const std::string& path,
+                      std::string* error_msg) {
+  if (is_libdl(path)) {
+    // TODO (dimitry): we skip check for libdl.so because
+    // 1. Linker will fail to check accessibility because it imposes as libdl.so (see http://b/27106625)
+    // 2. It is impractical to dlopen libdl.so because this library already depends
+    //    on it in order to have dlopen()
+    return true;
+  }
+
+  auto dlcloser = [](void* handle) { dlclose(handle); };
+  std::unique_ptr<void, decltype(dlcloser)> handle(dlopen(path.c_str(), RTLD_NOW), dlcloser);
+  if (should_be_accessible(public_library_path, public_libraries, path)) {
+    if (handle.get() == nullptr) {
+      *error_msg = "The library \"" + path + "\" should be accessible but isn't: " + dlerror();
+      return false;
+    }
+  } else if (handle != nullptr) {
+    *error_msg = "The library \"" + path + "\" should not be accessible";
+    return false;
+  } else { // (handle == nullptr && !shouldBeAccessible(path))
+    // Check the error message
+    std::string err = dlerror();
+
+    if (err.find("dlopen failed: library \"" + path + "\"") != 0 ||
+        err.find("is not accessible for the namespace \"classloader-namespace\"") == std::string::npos) {
+      *error_msg = "unexpected dlerror: " + err;
+      return false;
+    }
+  }
+  return true;
+}
+
+static bool check_libs(const std::string& public_library_path,
+                       const std::unordered_set<std::string>& public_libraries,
+                       const std::unordered_set<std::string>& mandatory_files,
+                       std::string* error) {
+  std::list<std::string> dirs;
+  dirs.push_back(public_library_path);
+
+  while (!dirs.empty()) {
+    const auto dir = dirs.front();
+    dirs.pop_front();
+    bool success = for_each_file(dir, [&](const char* name, std::string* error_msg) {
+      std::string path = dir + "/" + name;
+      if (is_directory(path)) {
+        dirs.push_back(path);
+        return true;
+      }
+
+      return check_lib(public_library_path, public_libraries, path, error_msg);
+    }, error);
+
+    if (!success) {
+      return false;
+    }
+
+    // Check mandatory files - the grey list
+    for (const auto& name : mandatory_files) {
+      std::string path = public_library_path + "/" + name;
+      if (!check_lib(public_library_path, public_libraries, path, error)) {
+        return false;
+      }
+    }
+  }
+
+  return true;
+}
+
+static void load_vendor_libraries(JNIEnv* env,
+                                  jobjectArray java_vendor_public_libraries,
+                                  std::unordered_set<std::string>* libraries) {
+  size_t size = env->GetArrayLength(java_vendor_public_libraries);
+  for (size_t i = 0; i<size; ++i) {
+    ScopedLocalRef<jstring> java_soname(
+        env, (jstring) env->GetObjectArrayElement(java_vendor_public_libraries, i));
+
+    ScopedUtfChars soname(env, java_soname.get());
+    libraries->insert(soname.c_str());
+  }
+}
+
+extern "C" JNIEXPORT jstring JNICALL
+    Java_android_jni_cts_LinkerNamespacesHelper_runAccessibilityTestImpl(
+        JNIEnv* env,
+        jclass clazz __attribute__((unused)),
+        jobjectArray java_vendor_public_libraries) {
+  std::string error;
+
+  std::unordered_set<std::string> vendor_public_libraries;
+  std::unordered_set<std::string> empty_set;
+  load_vendor_libraries(env, java_vendor_public_libraries, &vendor_public_libraries);
+
+  if (!check_libs(kSystemLibraryPath, kSystemPublicLibraries, kSystemLibraries, &error) ||
+      !check_libs(kVendorLibraryPath, vendor_public_libraries, empty_set, &error)) {
+    return env->NewStringUTF(error.c_str());
+  }
+
+  return nullptr;
+}
+
diff --git a/tests/tests/jni/libjnitest/helper.c b/tests/tests/jni/libjnitest/helper.c
index 831d5b5..8f7f2f8 100644
--- a/tests/tests/jni/libjnitest/helper.c
+++ b/tests/tests/jni/libjnitest/helper.c
@@ -16,9 +16,10 @@
 
 #include "helper.h"
 
-#include <cutils/log.h>
+#include <android/log.h>
 
 #include <stdarg.h>
+#include <stdio.h>
 #include <stdlib.h>
 
 #define LOG_TAG "cts"
@@ -29,7 +30,7 @@
     char *result;
 
     va_start(args, format);
-    LOG_PRI_VA(ANDROID_LOG_ERROR, LOG_TAG, format, args);
+    __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, format, args);
     va_end(args);
 
     va_start(args, format);
@@ -58,7 +59,7 @@
 
         JniTestFunction *function = va_arg(args, JniTestFunction *);
 
-        ALOGI("running %s", name);
+        __android_log_print(ANDROID_LOG_INFO, LOG_TAG, "running %s", name);
 
         char *oneResult = function(env);
         if (oneResult != NULL) {
diff --git a/tests/tests/jni/libjnitest/register.c b/tests/tests/jni/libjnitest/register.c
index 66eb265..b371b8b 100644
--- a/tests/tests/jni/libjnitest/register.c
+++ b/tests/tests/jni/libjnitest/register.c
@@ -14,10 +14,12 @@
  * limitations under the License.
  */
 
-#include <cutils/log.h>
+#include <android/log.h>
 #include <jni.h>
 #include <stdlib.h>
 
+#define LOG_TAG "Cts-JniTest"
+
 /*
  * This function is called automatically by the system when this
  * library is loaded. We use it to register all our native functions,
@@ -32,25 +34,25 @@
 
     extern int register_InstanceNonce(JNIEnv *);
     if (register_InstanceNonce(env)) {
-        ALOGE("failed to register InstanceNonce");
+        __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "failed to register InstanceNonce");
         return JNI_ERR;
     }
 
     extern int register_StaticNonce(JNIEnv *);
     if (register_StaticNonce(env)) {
-        ALOGE("failed to register StaticNonce");
+        __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "failed to register StaticNonce");
         return JNI_ERR;
     }
 
     extern int register_JniCTest(JNIEnv *);
     if (register_JniCTest(env)) {
-        ALOGE("failed to register JniCTest");
+        __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "failed to register JniCTest");
         return JNI_ERR;
     }
 
     extern int register_JniCppTest(JNIEnv *);
     if (register_JniCppTest(env)) {
-        ALOGE("failed to register JniCppTest");
+        __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "failed to register JniCppTest");
         return JNI_ERR;
     }
 
diff --git a/tests/tests/jni/src/android/jni/cts/JniStaticTest.java b/tests/tests/jni/src/android/jni/cts/JniStaticTest.java
index d4b51b9..91ebe73 100644
--- a/tests/tests/jni/src/android/jni/cts/JniStaticTest.java
+++ b/tests/tests/jni/src/android/jni/cts/JniStaticTest.java
@@ -16,6 +16,7 @@
 
 package android.jni.cts;
 
+import java.io.IOException;
 
 /**
  * Basic static method tests. The "nonce" class being tested by this
@@ -31,6 +32,17 @@
     }
 
     /**
+     * Test library accessibility. Internal platform libraries should not
+     * be accessible from the jni code.
+     */
+    public void test_linker_namespaces() throws IOException {
+        String error = LinkerNamespacesHelper.runAccessibilityTest();
+        if (error != null) {
+            fail(error);
+        }
+    }
+
+    /**
      * Test that accessing classes true JNI works as expected. b/19382130
      */
     public void test_classload() {
diff --git a/tests/tests/jni/src/android/jni/cts/LinkerNamespacesHelper.java b/tests/tests/jni/src/android/jni/cts/LinkerNamespacesHelper.java
new file mode 100644
index 0000000..21bd71a
--- /dev/null
+++ b/tests/tests/jni/src/android/jni/cts/LinkerNamespacesHelper.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.jni.cts;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.File;
+import java.io.FileReader;
+import java.util.ArrayList;
+import java.util.List;
+
+class LinkerNamespacesHelper {
+    private final static String VENDOR_CONFIG_FILE = "/vendor/etc/public.libraries.txt";
+    public static String runAccessibilityTest() throws IOException {
+        List<String> libs = new ArrayList<>();
+        File file = new File(VENDOR_CONFIG_FILE);
+        if (file.exists()) {
+            try (BufferedReader br = new BufferedReader(new FileReader(file))) {
+                String line;
+                while ((line = br.readLine()) != null) {
+                    line = line.trim();
+                    if (line.isEmpty() || line.startsWith("#")) {
+                        continue;
+                    }
+                    libs.add(line);
+                }
+            }
+        }
+        return runAccessibilityTestImpl(libs.toArray(new String[libs.size()]));
+    }
+    private static native String runAccessibilityTestImpl(String[] publicVendorLibs);
+}
diff --git a/tests/tests/keystore/Android.mk b/tests/tests/keystore/Android.mk
index e51bc04..66d3ebc 100644
--- a/tests/tests/keystore/Android.mk
+++ b/tests/tests/keystore/Android.mk
@@ -18,7 +18,13 @@
 
 LOCAL_MODULE_TAGS := tests
 
-LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner core-tests-support
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
+    ctstestrunner core-tests-support platform-test-annotations ctsdeviceutil
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
@@ -26,8 +32,6 @@
 
 LOCAL_SDK_VERSION := current
 
-cts_runtime_hint := 28
-
 include $(BUILD_CTS_PACKAGE)
 
 include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/tests/keystore/AndroidManifest.xml b/tests/tests/keystore/AndroidManifest.xml
index 106a0dc..3678f63 100644
--- a/tests/tests/keystore/AndroidManifest.xml
+++ b/tests/tests/keystore/AndroidManifest.xml
@@ -16,7 +16,7 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.keystore">
+    package="android.keystore.cts">
 
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <uses-permission android:name="android.permission.INTERNET" />
@@ -25,8 +25,8 @@
     </application>
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.cts.keystore"
-                     android:label="CTS tests of com.android.cts.keystore">
+                     android:targetPackage="android.keystore.cts"
+                     android:label="CTS tests of android.keystore.cts">
         <meta-data android:name="listener"
             android:value="com.android.cts.runner.CtsTestRunListener" />
     </instrumentation>
diff --git a/tests/tests/keystore/AndroidTest.xml b/tests/tests/keystore/AndroidTest.xml
new file mode 100644
index 0000000..844cd2a
--- /dev/null
+++ b/tests/tests/keystore/AndroidTest.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS Keystore test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsKeystoreTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.keystore.cts" />
+        <option name="runtime-hint" value="16m39s" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/tests/keystore/src/android/keystore/cts/AndroidKeyStoreTest.java b/tests/tests/keystore/src/android/keystore/cts/AndroidKeyStoreTest.java
index 5fe3505..1efcb7f 100644
--- a/tests/tests/keystore/src/android/keystore/cts/AndroidKeyStoreTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/AndroidKeyStoreTest.java
@@ -16,6 +16,8 @@
 
 package android.keystore.cts;
 
+import android.app.KeyguardManager;
+import android.content.Context;
 import android.security.KeyPairGeneratorSpec;
 import android.security.KeyStoreParameter;
 import android.security.keystore.KeyProperties;
@@ -25,7 +27,7 @@
 import android.test.suitebuilder.annotation.LargeTest;
 import android.util.Log;
 
-import com.android.cts.keystore.R;
+import android.keystore.cts.R;
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
@@ -1334,6 +1336,14 @@
     }
 
     public void testKeyStore_SetEntry_PrivateKeyEntry_Params_Unencrypted_Failure() throws Exception {
+        // This test asserts that Android Keystore refuses to create/import keys encrypted at rest
+        // using the secure lock screen credential. The test assumes that the secure lock screen is
+        // not set up.
+        KeyguardManager keyguardManager =
+                (KeyguardManager) getContext().getSystemService(Context.KEYGUARD_SERVICE);
+        assertNotNull(keyguardManager);
+        assertFalse("Secure lock screen must not be configured", keyguardManager.isDeviceSecure());
+
         mKeyStore.load(null, null);
 
         KeyFactory keyFact = KeyFactory.getInstance("RSA");
diff --git a/tests/tests/keystore/src/android/keystore/cts/CipherTest.java b/tests/tests/keystore/src/android/keystore/cts/CipherTest.java
index e2c1d69..57a7648 100644
--- a/tests/tests/keystore/src/android/keystore/cts/CipherTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/CipherTest.java
@@ -16,12 +16,13 @@
 
 package android.keystore.cts;
 
+import android.platform.test.annotations.Presubmit;
 import android.security.keystore.KeyProperties;
 import android.security.keystore.KeyProtection;
 import android.test.AndroidTestCase;
 import android.test.MoreAsserts;
 
-import com.android.cts.keystore.R;
+import android.keystore.cts.R;
 
 import java.security.AlgorithmParameters;
 import java.security.InvalidKeyException;
@@ -221,6 +222,7 @@
     private static final byte[] AES256_KAT_KEY_BYTES =
             HexEncoding.decode("cf601cc10aaf434d1f01747136aff222af7fb426d101901712214c3fea18125f");
 
+    @Presubmit
     public void testAlgorithmList() {
         // Assert that Android Keystore Provider exposes exactly the expected Cipher
         // transformations. We don't care whether the transformations are exposed via aliases, as
@@ -441,12 +443,24 @@
                         if (!"SHA-1".equalsIgnoreCase(
                                 ((MGF1ParameterSpec) spec.getMGFParameters())
                                         .getDigestAlgorithm())) {
+                            // Create a new instance of Cipher because Bouncy Castle's RSA Cipher
+                            // caches AlgorithmParameters returned by Cipher.getParameters and does
+                            // not invalidate the cache when reinitialized with different
+                            // parameters.
+                            cipher = Cipher.getInstance(algorithm, encryptionProvider);
                             cipher.init(Cipher.ENCRYPT_MODE, encryptionKey, new OAEPParameterSpec(
                                     spec.getDigestAlgorithm(),
                                     "MGF1",
                                     MGF1ParameterSpec.SHA1,
                                     PSource.PSpecified.DEFAULT));
                             params = cipher.getParameters();
+                            OAEPParameterSpec newSpec =
+                                    params.getParameterSpec(OAEPParameterSpec.class);
+                            assertEquals(spec.getDigestAlgorithm(), newSpec.getDigestAlgorithm());
+                            assertEquals(
+                                    "SHA-1",
+                                    ((MGF1ParameterSpec) newSpec.getMGFParameters())
+                                            .getDigestAlgorithm());
                         }
                     }
 
diff --git a/tests/tests/keystore/src/android/keystore/cts/ECDSASignatureTest.java b/tests/tests/keystore/src/android/keystore/cts/ECDSASignatureTest.java
index ea3940d..de60e37 100644
--- a/tests/tests/keystore/src/android/keystore/cts/ECDSASignatureTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/ECDSASignatureTest.java
@@ -20,7 +20,7 @@
 import android.security.keystore.KeyProtection;
 import android.test.AndroidTestCase;
 
-import com.android.cts.keystore.R;
+import android.keystore.cts.R;
 
 import java.security.KeyPair;
 import java.security.Security;
diff --git a/tests/tests/keystore/src/android/keystore/cts/KeyFactoryTest.java b/tests/tests/keystore/src/android/keystore/cts/KeyFactoryTest.java
index d552631..fb853c9 100644
--- a/tests/tests/keystore/src/android/keystore/cts/KeyFactoryTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/KeyFactoryTest.java
@@ -22,7 +22,7 @@
 import android.test.AndroidTestCase;
 import android.test.MoreAsserts;
 
-import com.android.cts.keystore.R;
+import android.keystore.cts.R;
 
 import java.io.InputStream;
 import java.security.InvalidKeyException;
diff --git a/tests/tests/keystore/src/android/keystore/cts/KeyStoreTest.java b/tests/tests/keystore/src/android/keystore/cts/KeyStoreTest.java
new file mode 100644
index 0000000..988f75a
--- /dev/null
+++ b/tests/tests/keystore/src/android/keystore/cts/KeyStoreTest.java
@@ -0,0 +1,2546 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.keystore.cts;
+
+import com.android.cts.util.TimeoutReq;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.security.Key;
+import java.security.KeyStore;
+import java.security.KeyStore.Builder;
+import java.security.KeyStore.Entry;
+import java.security.KeyStore.LoadStoreParameter;
+import java.security.KeyStore.PasswordProtection;
+import java.security.KeyStore.PrivateKeyEntry;
+import java.security.KeyStore.ProtectionParameter;
+import java.security.KeyStore.SecretKeyEntry;
+import java.security.KeyStore.TrustedCertificateEntry;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.Provider;
+import java.security.Security;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
+import junit.framework.TestCase;
+
+import libcore.java.security.StandardNames;
+import libcore.java.security.TestKeyStore;
+
+public class KeyStoreTest extends TestCase {
+
+    private static final HashMap<String, PrivateKeyEntry> sPrivateKeys
+            = new HashMap<String, PrivateKeyEntry>();
+
+    private static TestKeyStore sTestKeyStore;
+
+    private static final String[] KEY_TYPES = new String[] { "DH", "DSA", "RSA", "EC" };
+
+    private static PrivateKeyEntry sPrivateKey2;
+
+    private static SecretKey sSecretKey;
+    private static SecretKey sSecretKey2;
+
+    private static final String ALIAS_PRIVATE = "private";
+    private static final String ALIAS_CERTIFICATE = "certificate";
+    private static final String ALIAS_SECRET = "secret";
+
+    private static final String ALIAS_ALT_CASE_PRIVATE = "pRiVaTe";
+    private static final String ALIAS_ALT_CASE_NO_PASSWORD_PRIVATE = "PrIvAtE-no-password";
+    private static final String ALIAS_ALT_CASE_CERTIFICATE = "cErTiFiCaTe";
+    private static final String ALIAS_ALT_CASE_SECRET = "sEcRet";
+
+    private static final String ALIAS_UNICODE_PRIVATE = "\u6400\u7902\u3101\u8c02\u5002\u8702\udd01";
+    private static final String ALIAS_UNICODE_NO_PASSWORD_PRIVATE = "\u926c\u0967\uc65b\ubc78";
+    private static final String ALIAS_UNICODE_CERTIFICATE = "\u5402\udd01\u7902\u8702\u3101\u5f02\u3101\u5402\u5002\u8702\udd01";
+    private static final String ALIAS_UNICODE_SECRET = "\ue224\ud424\ud224\ue124\ud424\ue324";
+
+    private static final String ALIAS_NO_PASSWORD_PRIVATE = "private-no-password";
+    private static final String ALIAS_NO_PASSWORD_SECRET = "secret-no-password";
+
+    private static final char[] PASSWORD_STORE = "store password".toCharArray();
+    private static final char[] PASSWORD_KEY = "key password".toCharArray();
+    private static final char[] PASSWORD_BAD = "dummy".toCharArray();
+
+    private static final ProtectionParameter PARAM_STORE = new PasswordProtection(PASSWORD_STORE);
+    private static final ProtectionParameter PARAM_KEY = new PasswordProtection(PASSWORD_KEY);
+    private static final ProtectionParameter PARAM_BAD = new PasswordProtection(PASSWORD_BAD);
+
+    private static PrivateKeyEntry getPrivateKey() {
+        return getPrivateKey("RSA");
+    }
+
+    private static PrivateKeyEntry getPrivateKey(String keyType) {
+        // Avoiding initialization of TestKeyStore in the static initializer: it breaks CTS tests
+        // by causing a NetworkOnMainThreadException.
+        if (sTestKeyStore == null) {
+            sTestKeyStore = new TestKeyStore.Builder()
+                .keyAlgorithms("RSA", "DH_RSA", "DSA", "EC")
+                .aliasPrefix("rsa-dsa-ec-dh")
+                .build();
+        }
+
+        PrivateKeyEntry entry = sPrivateKeys.get(keyType);
+        if (entry == null) {
+            if ("RSA".equals(keyType)) {
+                entry = sTestKeyStore.getPrivateKey("RSA", "RSA");
+            } else if ("DH".equals(keyType)) {
+                entry = sTestKeyStore.getPrivateKey("DH", "RSA");
+            } else if ("DSA".equals(keyType)) {
+                entry = sTestKeyStore.getPrivateKey("DSA", "DSA");
+            } else if ("EC".equals(keyType)) {
+                entry = sTestKeyStore.getPrivateKey("EC", "EC");
+            } else {
+                throw new IllegalArgumentException("Unexpected key type " + keyType);
+            }
+            sPrivateKeys.put(keyType, entry);
+        }
+        return entry;
+    }
+
+    private static PrivateKeyEntry getPrivateKey2() {
+        if (sPrivateKey2 == null) {
+            sPrivateKey2 = TestKeyStore.getClientCertificate().getPrivateKey("RSA", "RSA");
+        }
+        return sPrivateKey2;
+    }
+
+    private static SecretKey getSecretKey() {
+        if (sSecretKey == null) {
+            sSecretKey = generateSecretKey();
+        }
+        return sSecretKey;
+    }
+
+    private static SecretKey getSecretKey2() {
+        if (sSecretKey2 == null) {
+            sSecretKey2 = generateSecretKey();
+        }
+        return sSecretKey2;
+    }
+
+    private static SecretKey generateSecretKey() {
+        try {
+            KeyGenerator kg = KeyGenerator.getInstance("DES");
+            return kg.generateKey();
+        } catch (NoSuchAlgorithmException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public static List<KeyStore> keyStores() throws Exception {
+        List<KeyStore> keyStores = new ArrayList<KeyStore>();
+        Provider[] providers = Security.getProviders();
+        for (Provider provider : providers) {
+            Set<Provider.Service> services = provider.getServices();
+            for (Provider.Service service : services) {
+                String type = service.getType();
+                if (!type.equals("KeyStore")) {
+                    continue;
+                }
+                String algorithm = service.getAlgorithm();
+                KeyStore ks = KeyStore.getInstance(algorithm, provider);
+                assertEquals(provider, ks.getProvider());
+                assertEquals(algorithm, ks.getType());
+                if (!isUnsupported(ks)) {
+                    keyStores.add(ks);
+                }
+            }
+        }
+        return keyStores;
+    }
+
+    private static boolean isSecretKeyEnabled(KeyStore ks) {
+        // JKS key stores cannot store secret keys, neither can the RI's PKCS12
+        return (!(ks.getType().equals("JKS")
+                  || ks.getType().equals("CaseExactJKS")
+                  || (ks.getType().equals("PKCS12"))
+                  || (ks.getType().equals("AndroidKeyStore"))));
+    }
+
+    private static boolean isCertificateEnabled(KeyStore ks) {
+        // RI can't handle certificate in PKCS12, but BC can
+        return (!(ks.getType().equals("PKCS12") && ks.getProvider().getName().equals("SunJSSE")));
+    }
+
+    private static boolean isCaseSensitive(KeyStore ks) {
+        return (ks.getType().equals("CaseExactJKS")
+                || ks.getType().equals("BKS")
+                || ks.getType().equals("BouncyCastle")
+                || ks.getType().equals("AndroidKeyStore"));
+
+    }
+
+    private static boolean isUnsupported(KeyStore ks) {
+        // Don't bother testing BC on RI
+        // TODO enable AndroidKeyStore when CTS can set up the keystore
+        return (StandardNames.IS_RI && ks.getProvider().getName().equals("BC"))
+                || "AndroidKeyStore".equalsIgnoreCase(ks.getType())
+                || "TimaKeyStore".equalsIgnoreCase(ks.getType());
+    }
+
+    private static boolean isNullPasswordAllowed(KeyStore ks) {
+        return (!(ks.getType().equals("JKS")
+                  || ks.getType().equals("CaseExactJKS")
+                  || ks.getType().equals("JCEKS")
+                  || ks.getType().equals("PKCS12")));
+    }
+    private static boolean isKeyPasswordSupported(KeyStore ks) {
+        return !ks.getType().equals("AndroidKeyStore");
+    }
+    private static boolean isKeyPasswordIgnored(KeyStore ks) {
+        // BouncyCastle's PKCS12 ignores the key password unlike the RI which requires it
+        return (ks.getType().equals("PKCS12") && ks.getProvider().getName().equals("BC"));
+    }
+
+    private static boolean isLoadStoreParameterSupported(KeyStore ks) {
+        // BouncyCastle's PKCS12 allows a JDKPKCS12StoreParameter
+        return (ks.getType().equals("PKCS12") && ks.getProvider().getName().equals("BC"));
+    }
+
+    private static boolean isPersistentStorage(KeyStore ks) {
+        return ks.getType().equalsIgnoreCase("AndroidKeyStore");
+    }
+
+    private static boolean isLoadStoreUnsupported(KeyStore ks) {
+        return ks.getType().equalsIgnoreCase("AndroidKeyStore");
+    }
+
+    private static boolean isSetKeyByteArrayUnimplemented(KeyStore ks) {
+        // All of BouncyCastle's
+        // KeyStore.setKeyEntry(String,byte[],char[]) implementations
+        // throw RuntimeException
+        return (ks.getProvider().getName().equals("BC"));
+    }
+
+    private static boolean hasDefaultContents(KeyStore ks) {
+        // AndroidCAStore exposes CA cert files via the KeyStore
+        // interface, so it does start out empty like other KeyStores
+        return (ks.getType().equals("AndroidCAStore"));
+    }
+
+    private static boolean isReadOnly(KeyStore ks) {
+        // AndroidCAStore is read only, throwing
+        // UnsupportedOperationException on write operations
+        return (ks.getType().equals("AndroidCAStore"));
+    }
+
+    public static void populate(KeyStore ks) throws Exception {
+        boolean readOnly = clearKeyStore(ks);
+        if (readOnly) {
+            return;
+        }
+        if (isKeyPasswordSupported(ks)) {
+            setPrivateKey(ks);
+        }
+        if (isNullPasswordAllowed(ks)) {
+            ks.setKeyEntry(ALIAS_NO_PASSWORD_PRIVATE,
+                           getPrivateKey().getPrivateKey(),
+                           null,
+                           getPrivateKey().getCertificateChain());
+        }
+        if (isCertificateEnabled(ks)) {
+            ks.setCertificateEntry(ALIAS_CERTIFICATE,
+                                   getPrivateKey().getCertificate());
+        }
+        if (isSecretKeyEnabled(ks)) {
+            setSecretKey(ks);
+            if (isNullPasswordAllowed(ks)) {
+                ks.setKeyEntry(ALIAS_NO_PASSWORD_SECRET,
+                               getSecretKey(),
+                               null,
+                               null);
+            }
+        }
+    }
+
+    private static boolean clearKeyStore(KeyStore ks) throws Exception {
+        ks.load(null, null);
+        if (isReadOnly(ks)) {
+            try {
+                setPrivateKey(ks);
+                fail(ks.toString());
+            } catch (UnsupportedOperationException e) {
+            }
+            return true;
+        }
+        if (isPersistentStorage(ks)) {
+            Enumeration<String> aliases = ks.aliases();
+            while (aliases.hasMoreElements()) {
+                String alias = aliases.nextElement();
+                ks.deleteEntry(alias);
+            }
+        }
+        return false;
+    }
+
+    public static void setPrivateKeyNoPassword(KeyStore ks, String alias, PrivateKeyEntry privateKey)
+            throws Exception {
+        ks.setKeyEntry(alias, privateKey.getPrivateKey(), null, privateKey.getCertificateChain());
+    }
+    public static void setPrivateKey(KeyStore ks) throws Exception {
+        setPrivateKey(ks, ALIAS_PRIVATE);
+    }
+    public static void setPrivateKey(KeyStore ks, String alias) throws Exception {
+        setPrivateKey(ks, alias, getPrivateKey());
+    }
+    public static void setPrivateKey(KeyStore ks,
+                                     String alias,
+                                     PrivateKeyEntry privateKey)
+            throws Exception {
+        ks.setKeyEntry(alias,
+                       privateKey.getPrivateKey(),
+                       PASSWORD_KEY,
+                       privateKey.getCertificateChain());
+    }
+
+    public static void setPrivateKeyBytes(KeyStore ks) throws Exception {
+        setPrivateKeyBytes(ks, ALIAS_PRIVATE);
+    }
+    public static void setPrivateKeyBytes(KeyStore ks, String alias) throws Exception {
+        setPrivateKeyBytes(ks, alias, getPrivateKey());
+    }
+    public static void setPrivateKeyBytes(KeyStore ks,
+                                     String alias,
+                                     PrivateKeyEntry privateKey)
+            throws Exception {
+        ks.setKeyEntry(alias,
+                       privateKey.getPrivateKey().getEncoded(),
+                       privateKey.getCertificateChain());
+    }
+
+    public static void setSecretKey(KeyStore ks) throws Exception {
+        setSecretKey(ks, ALIAS_SECRET);
+    }
+    public static void setSecretKey(KeyStore ks, String alias) throws Exception {
+        setSecretKey(ks, alias, getSecretKey());
+    }
+    public static void setSecretKey(KeyStore ks, String alias, SecretKey key) throws Exception {
+        ks.setKeyEntry(alias,
+                       key,
+                       PASSWORD_KEY,
+                       null);
+    }
+
+    public static void setSecretKeyBytes(KeyStore ks) throws Exception {
+        setSecretKeyBytes(ks, ALIAS_SECRET);
+    }
+    public static void setSecretKeyBytes(KeyStore ks, String alias) throws Exception {
+        setSecretKeyBytes(ks, alias, getSecretKey());
+    }
+    public static void setSecretKeyBytes(KeyStore ks, String alias, SecretKey key)
+            throws Exception {
+        ks.setKeyEntry(alias,
+                       key.getEncoded(),
+                       null);
+    }
+
+    public static void setCertificate(KeyStore ks) throws Exception {
+        setCertificate(ks, ALIAS_CERTIFICATE);
+    }
+    public static void setCertificate(KeyStore ks, String alias) throws Exception {
+        setCertificate(ks, alias, getPrivateKey().getCertificate());
+    }
+    public static void setCertificate(KeyStore ks, String alias, Certificate certificate)
+            throws Exception {
+        ks.setCertificateEntry(alias, certificate);
+    }
+
+
+    public static void assertPrivateKey(Key actual)
+            throws Exception {
+        assertEquals(getPrivateKey().getPrivateKey(), actual);
+    }
+    public static void assertPrivateKey(String keyType, Key actual)
+            throws Exception {
+        assertEquals(getPrivateKey(keyType).getPrivateKey(), actual);
+    }
+    public static void assertPrivateKey2(Key actual)
+            throws Exception {
+        assertEquals(getPrivateKey2().getPrivateKey(), actual);
+    }
+    public static void assertPrivateKey(Entry actual)
+            throws Exception {
+        assertNotNull(actual);
+        assertSame(PrivateKeyEntry.class, actual.getClass());
+        PrivateKeyEntry privateKey = (PrivateKeyEntry) actual;
+        assertEquals(getPrivateKey().getPrivateKey(), privateKey.getPrivateKey());
+        assertEquals(getPrivateKey().getCertificate(), privateKey.getCertificate());
+        assertEquals(Arrays.asList(getPrivateKey().getCertificateChain()),
+                     Arrays.asList(privateKey.getCertificateChain()));
+    }
+
+    public static void assertSecretKey(Key actual)
+            throws Exception {
+        assertEquals(getSecretKey(), actual);
+    }
+    public static void assertSecretKey2(Key actual)
+            throws Exception {
+        assertEquals(getSecretKey2(), actual);
+    }
+    public static void assertSecretKey(Entry actual)
+            throws Exception {
+        assertSame(SecretKeyEntry.class, actual.getClass());
+        assertEquals(getSecretKey(), ((SecretKeyEntry) actual).getSecretKey());
+    }
+
+    public static void assertCertificate(Certificate actual)
+            throws Exception {
+        assertEquals(getPrivateKey().getCertificate(), actual);
+    }
+    public static void assertCertificate2(Certificate actual)
+            throws Exception {
+        assertEquals(getPrivateKey2().getCertificate(), actual);
+    }
+    public static void assertCertificate(Entry actual)
+            throws Exception {
+        assertSame(TrustedCertificateEntry.class, actual.getClass());
+        assertEquals(getPrivateKey().getCertificate(),
+                     ((TrustedCertificateEntry) actual).getTrustedCertificate());
+    }
+
+    public static void assertCertificateChain(Certificate[] actual)
+            throws Exception {
+        assertEquals(Arrays.asList(getPrivateKey().getCertificateChain()),
+                     Arrays.asList(actual));
+    }
+
+    public void test_KeyStore_create() throws Exception {
+        Provider[] providers = Security.getProviders();
+        for (Provider provider : providers) {
+            Set<Provider.Service> services = provider.getServices();
+            for (Provider.Service service : services) {
+                String type = service.getType();
+                if (!type.equals("KeyStore")) {
+                    continue;
+                }
+                String algorithm = service.getAlgorithm();
+                KeyStore ks = KeyStore.getInstance(algorithm, provider);
+                assertEquals(provider, ks.getProvider());
+                assertEquals(algorithm, ks.getType());
+            }
+        }
+    }
+
+    public void test_KeyStore_getInstance() throws Exception {
+        String type = KeyStore.getDefaultType();
+        try {
+            KeyStore.getInstance(null);
+            fail(type);
+        } catch (NullPointerException expected) {
+        }
+
+        assertNotNull(KeyStore.getInstance(type));
+
+        String providerName = StandardNames.SECURITY_PROVIDER_NAME;
+        try {
+            KeyStore.getInstance(null, (String)null);
+            fail(type);
+        } catch (IllegalArgumentException expected) {
+        }
+        try {
+            KeyStore.getInstance(null, providerName);
+            fail(type);
+        } catch (Exception e) {
+            if (e.getClass() != NullPointerException.class
+                && e.getClass() != KeyStoreException.class) {
+                throw e;
+            }
+        }
+        try {
+            KeyStore.getInstance(type, (String)null);
+            fail(type);
+        } catch (IllegalArgumentException expected) {
+        }
+        assertNotNull(KeyStore.getInstance(type, providerName));
+
+        Provider provider = Security.getProvider(providerName);
+        try {
+            KeyStore.getInstance(null, (Provider)null);
+            fail(type);
+        } catch (IllegalArgumentException expected) {
+        }
+        try {
+            KeyStore.getInstance(null, provider);
+            fail(type);
+        } catch (NullPointerException expected) {
+        }
+        try {
+            KeyStore.getInstance(type, (Provider)null);
+            fail(type);
+        } catch (IllegalArgumentException expected) {
+        }
+        assertNotNull(KeyStore.getInstance(type, provider));
+    }
+
+    public void test_KeyStore_getDefaultType() throws Exception {
+        String type = KeyStore.getDefaultType();
+        assertNotNull(type);
+        KeyStore ks = KeyStore.getInstance(type);
+        assertNotNull(ks);
+        assertEquals(type, ks.getType());
+    }
+
+    public void test_KeyStore_getProvider() throws Exception {
+        KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
+        assertNotNull(ks.getProvider());
+        assertNotNull(StandardNames.SECURITY_PROVIDER_NAME, ks.getProvider().getName());
+
+        for (KeyStore keyStore : keyStores()) {
+            assertNotNull(keyStore.getProvider());
+        }
+    }
+
+    public void test_KeyStore_getType() throws Exception {
+        String type = KeyStore.getDefaultType();
+        KeyStore ks = KeyStore.getInstance(type);
+        assertNotNull(ks.getType());
+        assertNotNull(type, ks.getType());
+
+        for (KeyStore keyStore : keyStores()) {
+            assertNotNull(keyStore.getType());
+        }
+    }
+
+    public void test_KeyStore_getKey() throws Exception {
+        for (KeyStore keyStore : keyStores()) {
+            try {
+                keyStore.getKey(null, null);
+                fail(keyStore.getType());
+            } catch (KeyStoreException expected) {
+            }
+        }
+
+        for (KeyStore keyStore : keyStores()) {
+            populate(keyStore);
+
+            // test odd inputs
+            try {
+                keyStore.getKey(null, null);
+                fail(keyStore.getType());
+            } catch (Exception e) {
+                if (e.getClass() != NullPointerException.class
+                    && e.getClass() != IllegalArgumentException.class) {
+                    throw e;
+                }
+            }
+            try {
+                keyStore.getKey(null, PASSWORD_KEY);
+                fail(keyStore.getType());
+            } catch (Exception e) {
+                if (e.getClass() != NullPointerException.class
+                    && e.getClass() != IllegalArgumentException.class
+                    && e.getClass() != KeyStoreException.class) {
+                    throw e;
+                }
+            }
+            assertNull(keyStore.getKey("", null));
+            assertNull(keyStore.getKey("", PASSWORD_KEY));
+
+            // test case sensitive
+            if (isReadOnly(keyStore)) {
+                assertNull(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
+            } else {
+                if (isKeyPasswordSupported(keyStore)) {
+                    assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
+                }
+                if (isNullPasswordAllowed(keyStore)) {
+                    assertPrivateKey(keyStore.getKey(ALIAS_NO_PASSWORD_PRIVATE, null));
+                }
+                if (isSecretKeyEnabled(keyStore)) {
+                    assertSecretKey(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
+                } else {
+                    assertNull(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
+                }
+            }
+
+            // test case insensitive
+            if (isCaseSensitive(keyStore) || isReadOnly(keyStore)) {
+                assertNull(keyStore.getKey(ALIAS_ALT_CASE_PRIVATE, PASSWORD_KEY));
+                assertNull(keyStore.getKey(ALIAS_ALT_CASE_NO_PASSWORD_PRIVATE, PASSWORD_KEY));
+                assertNull(keyStore.getKey(ALIAS_ALT_CASE_SECRET, PASSWORD_KEY));
+            } else {
+                if (isKeyPasswordSupported(keyStore)) {
+                    assertPrivateKey(keyStore.getKey(ALIAS_ALT_CASE_PRIVATE, PASSWORD_KEY));
+                }
+                if (isNullPasswordAllowed(keyStore)) {
+                    assertPrivateKey(keyStore.getKey(ALIAS_ALT_CASE_NO_PASSWORD_PRIVATE, null));
+                }
+                if (isSecretKeyEnabled(keyStore)) {
+                    assertSecretKey(keyStore.getKey(ALIAS_ALT_CASE_SECRET, PASSWORD_KEY));
+                }
+            }
+
+            // test with null passwords
+            if (isKeyPasswordSupported(keyStore) && isKeyPasswordIgnored(keyStore)) {
+                assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, null));
+            } else {
+                if (isReadOnly(keyStore)) {
+                    assertNull(keyStore.getKey(ALIAS_PRIVATE, null));
+                } else if (isKeyPasswordSupported(keyStore)) {
+                    try {
+                        keyStore.getKey(ALIAS_PRIVATE, null);
+                        fail(keyStore.getType());
+                    } catch (Exception e) {
+                        if (e.getClass() != UnrecoverableKeyException.class
+                            && e.getClass() != IllegalArgumentException.class) {
+                            throw e;
+                        }
+                    }
+                }
+            }
+            if (isReadOnly(keyStore)) {
+                assertNull(keyStore.getKey(ALIAS_SECRET, null));
+            } else if (isSecretKeyEnabled(keyStore)) {
+                try {
+                    keyStore.getKey(ALIAS_SECRET, null);
+                    fail(keyStore.getType());
+                } catch (Exception e) {
+                    if (e.getClass() != UnrecoverableKeyException.class
+                        && e.getClass() != IllegalArgumentException.class) {
+                        throw e;
+                    }
+                }
+            }
+
+            // test with bad passwords
+            if (isReadOnly(keyStore)) {
+                assertNull(keyStore.getKey(ALIAS_PRIVATE, null));
+            } else if (isKeyPasswordSupported(keyStore) && isKeyPasswordIgnored(keyStore)) {
+                assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, null));
+            } else if (isKeyPasswordSupported(keyStore)) {
+                try {
+                    keyStore.getKey(ALIAS_PRIVATE, PASSWORD_BAD);
+                    fail(keyStore.getType());
+                } catch (UnrecoverableKeyException expected) {
+                }
+            }
+            if (isReadOnly(keyStore)) {
+                assertNull(keyStore.getKey(ALIAS_SECRET, PASSWORD_BAD));
+            } else if (isSecretKeyEnabled(keyStore)) {
+                try {
+                    keyStore.getKey(ALIAS_SECRET, PASSWORD_BAD);
+                    fail(keyStore.getType());
+                } catch (UnrecoverableKeyException expected) {
+                }
+            }
+        }
+    }
+
+    public void test_KeyStore_getCertificateChain() throws Exception {
+        for (KeyStore keyStore : keyStores()) {
+            try {
+                keyStore.getCertificateChain(null);
+                fail(keyStore.getType());
+            } catch (KeyStoreException expected) {
+            }
+        }
+        for (KeyStore keyStore : keyStores()) {
+            populate(keyStore);
+
+            // test odd inputs
+            try {
+                keyStore.getCertificateChain(null);
+                fail(keyStore.getType());
+            } catch (Exception e) {
+                if (e.getClass() != NullPointerException.class
+                    && e.getClass() != IllegalArgumentException.class) {
+                    throw e;
+                }
+            }
+            assertNull(keyStore.getCertificateChain(""));
+
+            // test case sensitive
+            if (isReadOnly(keyStore)) {
+                assertNull(keyStore.getCertificateChain(ALIAS_PRIVATE));
+            } else if (isKeyPasswordSupported(keyStore)) {
+                assertCertificateChain(keyStore.getCertificateChain(ALIAS_PRIVATE));
+            } else if (isNullPasswordAllowed(keyStore)) {
+                assertCertificateChain(keyStore.getCertificateChain(ALIAS_NO_PASSWORD_PRIVATE));
+            }
+
+            // test case insensitive
+            if (isReadOnly(keyStore) || isCaseSensitive(keyStore)) {
+                assertNull(keyStore.getCertificateChain(ALIAS_ALT_CASE_PRIVATE));
+            } else {
+                assertCertificateChain(keyStore.getCertificateChain(ALIAS_ALT_CASE_PRIVATE));
+            }
+        }
+    }
+
+    public void test_KeyStore_getCertificate() throws Exception {
+        for (KeyStore keyStore : keyStores()) {
+            try {
+                keyStore.getCertificate(null);
+                fail(keyStore.getType());
+            } catch (KeyStoreException expected) {
+            }
+        }
+        for (KeyStore keyStore : keyStores()) {
+            populate(keyStore);
+
+            // test odd inputs
+            try {
+                keyStore.getCertificate(null);
+                fail(keyStore.getType());
+            } catch (Exception e) {
+                if (e.getClass() != NullPointerException.class
+                    && e.getClass() != IllegalArgumentException.class) {
+                    throw e;
+                }
+            }
+            assertNull(keyStore.getCertificate(""));
+
+            // test case sensitive
+            if (!isReadOnly(keyStore) && isCertificateEnabled(keyStore)) {
+                assertCertificate(keyStore.getCertificate(ALIAS_CERTIFICATE));
+            } else {
+                assertNull(keyStore.getCertificate(ALIAS_CERTIFICATE));
+            }
+
+            // test case insensitive
+            if (isReadOnly(keyStore) || isCaseSensitive(keyStore)) {
+                assertNull(keyStore.getCertificate(ALIAS_ALT_CASE_CERTIFICATE));
+            } else {
+                if (isCertificateEnabled(keyStore)) {
+                    assertCertificate(keyStore.getCertificate(ALIAS_ALT_CASE_CERTIFICATE));
+                }
+            }
+        }
+    }
+
+    public void test_KeyStore_getCreationDate() throws Exception {
+        for (KeyStore keyStore : keyStores()) {
+            try {
+                keyStore.getCreationDate(null);
+                fail(keyStore.getType());
+            } catch (KeyStoreException expected) {
+            }
+        }
+        long before = System.currentTimeMillis();
+        for (KeyStore keyStore : keyStores()) {
+            populate(keyStore);
+
+            // add 1000 since some key stores round of time to nearest second
+            long after = System.currentTimeMillis() + 1000;
+
+            // test odd inputs
+            try {
+                keyStore.getCreationDate(null);
+                fail(keyStore.getType());
+            } catch (NullPointerException expected) {
+            }
+            assertNull(keyStore.getCreationDate(""));
+
+            // test case sensitive
+            if (!isReadOnly(keyStore) && isCertificateEnabled(keyStore)) {
+                Date date = keyStore.getCreationDate(ALIAS_CERTIFICATE);
+                assertNotNull(date);
+                assertTrue("date should be after start time: " + date.getTime() + " >= " + before,
+                        before <= date.getTime());
+                assertTrue("date should be before expiry time: " + date.getTime() + " <= " + after,
+                        date.getTime() <= after);
+            } else {
+                assertNull(keyStore.getCreationDate(ALIAS_CERTIFICATE));
+            }
+
+            // test case insensitive
+            if (isReadOnly(keyStore) || isCaseSensitive(keyStore)) {
+                assertNull(keyStore.getCreationDate(ALIAS_ALT_CASE_CERTIFICATE));
+            } else {
+                if (isCertificateEnabled(keyStore)) {
+                    Date date = keyStore.getCreationDate(ALIAS_ALT_CASE_CERTIFICATE);
+                    assertTrue(before <= date.getTime());
+                    assertTrue(date.getTime() <= after);
+                }
+            }
+        }
+    }
+
+    public void test_KeyStore_setKeyEntry_Key() throws Exception {
+        for (KeyStore keyStore : keyStores()) {
+            try {
+                keyStore.setKeyEntry(null, null, null, null);
+                fail(keyStore.getType());
+            } catch (KeyStoreException expected) {
+            }
+        }
+
+        for (KeyStore keyStore : keyStores()) {
+            keyStore.load(null, null);
+            if (isReadOnly(keyStore)) {
+                try {
+                    keyStore.setKeyEntry(null, null, null, null);
+                    fail(keyStore.getType());
+                } catch (UnsupportedOperationException expected) {
+                }
+                continue;
+            }
+
+            // test odd inputs
+            try {
+                keyStore.setKeyEntry(null, null, null, null);
+                fail(keyStore.getType());
+            } catch (Exception e) {
+                if (e.getClass() != NullPointerException.class
+                    && e.getClass() != KeyStoreException.class) {
+                    throw e;
+                }
+            }
+            try {
+                keyStore.setKeyEntry(null, null, PASSWORD_KEY, null);
+                fail(keyStore.getType());
+            } catch (Exception e) {
+                if (e.getClass() != NullPointerException.class
+                    && e.getClass() != KeyStoreException.class) {
+                    throw e;
+                }
+            }
+            try {
+                keyStore.setKeyEntry(ALIAS_PRIVATE,
+                                     getPrivateKey().getPrivateKey(),
+                                     PASSWORD_KEY,
+                                     null);
+                fail(keyStore.getType());
+            } catch (Exception e) {
+                if (e.getClass() != IllegalArgumentException.class
+                        && e.getClass() != KeyStoreException.class) {
+                    throw e;
+                }
+            }
+        }
+
+        for (KeyStore keyStore : keyStores()) {
+            clearKeyStore(keyStore);
+
+            // test case sensitive
+            if (isKeyPasswordSupported(keyStore)) {
+                assertNull(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
+            }
+            if (isNullPasswordAllowed(keyStore)) {
+                assertNull(keyStore.getKey(ALIAS_NO_PASSWORD_PRIVATE, null));
+            }
+            if (isReadOnly(keyStore)) {
+                try {
+                    keyStore.setKeyEntry(ALIAS_SECRET, getSecretKey(), PASSWORD_KEY, null);
+                    fail(keyStore.getType());
+                } catch (UnsupportedOperationException expected) {
+                }
+                continue;
+            }
+            if (isKeyPasswordSupported(keyStore)) {
+                setPrivateKey(keyStore);
+                assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
+                assertCertificateChain(keyStore.getCertificateChain(ALIAS_PRIVATE));
+            }
+            if (isNullPasswordAllowed(keyStore)) {
+                setPrivateKeyNoPassword(keyStore, ALIAS_NO_PASSWORD_PRIVATE, getPrivateKey());
+                assertPrivateKey(keyStore.getKey(ALIAS_NO_PASSWORD_PRIVATE, null));
+                assertCertificateChain(keyStore.getCertificateChain(ALIAS_NO_PASSWORD_PRIVATE));
+            }
+            if (isSecretKeyEnabled(keyStore)) {
+                assertNull(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
+                setSecretKey(keyStore);
+                assertSecretKey(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
+            } else {
+                try {
+                    keyStore.setKeyEntry(ALIAS_SECRET, getSecretKey(), PASSWORD_KEY, null);
+                    fail(keyStore.getType());
+                } catch (Exception e) {
+                    if (e.getClass() != KeyStoreException.class
+                        && e.getClass() != NullPointerException.class) {
+                        throw e;
+                    }
+                }
+            }
+        }
+
+        for (KeyStore keyStore : keyStores()) {
+            populate(keyStore);
+
+            if (isReadOnly(keyStore)) {
+                assertNull(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
+                assertNull(keyStore.getKey(ALIAS_ALT_CASE_PRIVATE, PASSWORD_KEY));
+                assertNull(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
+                assertNull(keyStore.getKey(ALIAS_ALT_CASE_SECRET, PASSWORD_KEY));
+            } else if (isCaseSensitive(keyStore)) {
+                if (isKeyPasswordSupported(keyStore)) {
+                    assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
+                    assertNull(keyStore.getKey(ALIAS_ALT_CASE_PRIVATE, PASSWORD_KEY));
+                    setPrivateKey(keyStore, ALIAS_ALT_CASE_PRIVATE, getPrivateKey2());
+                    assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
+                    assertPrivateKey2(keyStore.getKey(ALIAS_ALT_CASE_PRIVATE, PASSWORD_KEY));
+                }
+
+                if (isNullPasswordAllowed(keyStore)) {
+                    assertPrivateKey(keyStore.getKey(ALIAS_NO_PASSWORD_PRIVATE, null));
+                    assertNull(keyStore.getKey(ALIAS_ALT_CASE_NO_PASSWORD_PRIVATE, null));
+                    setPrivateKeyNoPassword(keyStore, ALIAS_ALT_CASE_NO_PASSWORD_PRIVATE,
+                            getPrivateKey2());
+                    assertPrivateKey(keyStore.getKey(ALIAS_NO_PASSWORD_PRIVATE, null));
+                    assertPrivateKey2(keyStore.getKey(ALIAS_ALT_CASE_NO_PASSWORD_PRIVATE, null));
+                }
+
+                if (isSecretKeyEnabled(keyStore)) {
+                    assertSecretKey(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
+                    assertNull(keyStore.getKey(ALIAS_ALT_CASE_SECRET, PASSWORD_KEY));
+                    setSecretKey(keyStore, ALIAS_ALT_CASE_SECRET, getSecretKey2());
+                    assertSecretKey(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
+                    assertSecretKey2(keyStore.getKey(ALIAS_ALT_CASE_SECRET, PASSWORD_KEY));
+                }
+            } else {
+                if (isKeyPasswordSupported(keyStore)) {
+                    assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
+                    assertPrivateKey(keyStore.getKey(ALIAS_ALT_CASE_PRIVATE, PASSWORD_KEY));
+                    setPrivateKey(keyStore, ALIAS_ALT_CASE_PRIVATE, getPrivateKey2());
+                    assertPrivateKey2(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
+                    assertPrivateKey2(keyStore.getKey(ALIAS_ALT_CASE_PRIVATE, PASSWORD_KEY));
+                }
+
+                if (isNullPasswordAllowed(keyStore)) {
+                    assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, null));
+                    assertPrivateKey(keyStore.getKey(ALIAS_ALT_CASE_NO_PASSWORD_PRIVATE, null));
+                    setPrivateKey(keyStore, ALIAS_ALT_CASE_NO_PASSWORD_PRIVATE, getPrivateKey2());
+                    assertPrivateKey2(keyStore.getKey(ALIAS_PRIVATE, null));
+                    assertPrivateKey2(keyStore.getKey(ALIAS_ALT_CASE_NO_PASSWORD_PRIVATE, null));
+                }
+
+                if (isSecretKeyEnabled(keyStore)) {
+                    assertSecretKey(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
+                    assertSecretKey(keyStore.getKey(ALIAS_ALT_CASE_SECRET, PASSWORD_KEY));
+                    setSecretKey(keyStore, ALIAS_ALT_CASE_PRIVATE, getSecretKey2());
+                    assertSecretKey(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
+                    assertSecretKey(keyStore.getKey(ALIAS_ALT_CASE_SECRET, PASSWORD_KEY));
+                }
+            }
+        }
+
+        for (KeyStore keyStore : keyStores()) {
+            keyStore.load(null, null);
+            if (isReadOnly(keyStore)) {
+                try {
+                    keyStore.setKeyEntry(ALIAS_PRIVATE,
+                                         getPrivateKey().getPrivateKey(),
+                                         null,
+                                         getPrivateKey().getCertificateChain());
+                    fail(keyStore.getType());
+                } catch (UnsupportedOperationException expected) {
+                }
+                continue;
+            }
+
+            // test with null passwords
+            if (isNullPasswordAllowed(keyStore) || isKeyPasswordIgnored(keyStore)) {
+                keyStore.setKeyEntry(ALIAS_PRIVATE,
+                                     getPrivateKey().getPrivateKey(),
+                                     null,
+                                     getPrivateKey().getCertificateChain());
+                assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, null));
+            } else {
+                try {
+                    keyStore.setKeyEntry(ALIAS_PRIVATE,
+                                         getPrivateKey().getPrivateKey(),
+                                         null,
+                                         getPrivateKey().getCertificateChain());
+                    fail(keyStore.getType());
+                } catch (Exception e) {
+                    if (e.getClass() != UnrecoverableKeyException.class
+                        && e.getClass() != IllegalArgumentException.class
+                        && e.getClass() != KeyStoreException.class) {
+                        throw e;
+                    }
+                }
+            }
+            if (isSecretKeyEnabled(keyStore)) {
+                if (isNullPasswordAllowed(keyStore) || isKeyPasswordIgnored(keyStore)) {
+                    keyStore.setKeyEntry(ALIAS_SECRET, getSecretKey(), null, null);
+                    assertSecretKey(keyStore.getKey(ALIAS_SECRET, null));
+                } else {
+                    try {
+                        keyStore.setKeyEntry(ALIAS_SECRET, getSecretKey(), null, null);
+                        fail(keyStore.getType());
+                    } catch (Exception e) {
+                        if (e.getClass() != UnrecoverableKeyException.class
+                            && e.getClass() != IllegalArgumentException.class
+                            && e.getClass() != KeyStoreException.class) {
+                            throw e;
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    public void test_KeyStore_setKeyEntry_array() throws Exception {
+        for (KeyStore keyStore : keyStores()) {
+            try {
+                keyStore.setKeyEntry(null, null, null);
+                fail(keyStore.getType());
+            } catch (KeyStoreException expected) {
+            }
+        }
+
+        for (KeyStore keyStore : keyStores()) {
+            keyStore.load(null, null);
+
+            if (isReadOnly(keyStore)) {
+                try {
+                    keyStore.setKeyEntry(null, null, null);
+                    fail(keyStore.getType());
+                } catch (UnsupportedOperationException expected) {
+                }
+                continue;
+            }
+
+            // test odd inputs
+            try {
+                keyStore.setKeyEntry(null, null, null);
+                fail(keyStore.getType());
+            } catch (Exception e) {
+                if (e.getClass() != NullPointerException.class
+                    && e.getClass() != IllegalArgumentException.class
+                    && e.getClass() != KeyStoreException.class
+                    && e.getClass() != RuntimeException.class) {
+                    throw e;
+                }
+            }
+        }
+
+        for (KeyStore keyStore : keyStores()) {
+            if (!isNullPasswordAllowed(keyStore)) {
+                // TODO Use EncryptedPrivateKeyInfo to protect keys if
+                // password is required.
+                continue;
+            }
+            if (isSetKeyByteArrayUnimplemented(keyStore)) {
+                continue;
+            }
+
+            clearKeyStore(keyStore);
+
+            // test case sensitive
+            if (isKeyPasswordSupported(keyStore)) {
+                assertNull(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
+            }
+            if (isNullPasswordAllowed(keyStore)) {
+                assertNull(keyStore.getKey(ALIAS_NO_PASSWORD_PRIVATE, null));
+            }
+            if (isReadOnly(keyStore)) {
+                try {
+                    setPrivateKeyBytes(keyStore);
+                    fail(keyStore.getType());
+                } catch (UnsupportedOperationException expected) {
+                }
+                continue;
+            }
+            if (isKeyPasswordSupported(keyStore)) {
+                setPrivateKeyBytes(keyStore);
+                assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
+                assertCertificateChain(keyStore.getCertificateChain(ALIAS_PRIVATE));
+            }
+            if (isNullPasswordAllowed(keyStore)) {
+                setPrivateKeyNoPassword(keyStore, ALIAS_NO_PASSWORD_PRIVATE, getPrivateKey());
+                assertPrivateKey(keyStore.getKey(ALIAS_NO_PASSWORD_PRIVATE, null));
+                assertCertificateChain(keyStore.getCertificateChain(ALIAS_NO_PASSWORD_PRIVATE));
+            }
+            if (isSecretKeyEnabled(keyStore)) {
+                assertNull(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
+                setSecretKeyBytes(keyStore);
+                assertSecretKey(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
+            } else {
+                try {
+                    keyStore.setKeyEntry(ALIAS_SECRET, getSecretKey().getEncoded(), null);
+                    fail(keyStore.getType());
+                } catch (KeyStoreException expected) {
+                }
+            }
+        }
+
+        for (KeyStore keyStore : keyStores()) {
+            if (!isNullPasswordAllowed(keyStore)) {
+                // TODO Use EncryptedPrivateKeyInfo to protect keys if
+                // password is required.
+                continue;
+            }
+            if (isSetKeyByteArrayUnimplemented(keyStore)) {
+                continue;
+            }
+
+            populate(keyStore);
+
+            if (isReadOnly(keyStore)) {
+                assertNull(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
+                assertNull(keyStore.getKey(ALIAS_ALT_CASE_PRIVATE, PASSWORD_KEY));
+                assertNull(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
+                assertNull(keyStore.getKey(ALIAS_ALT_CASE_SECRET, PASSWORD_KEY));
+            } else if (isCaseSensitive(keyStore)) {
+                if (isKeyPasswordSupported(keyStore)) {
+                    assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
+                    assertNull(keyStore.getKey(ALIAS_ALT_CASE_PRIVATE, PASSWORD_KEY));
+                    setPrivateKeyBytes(keyStore, ALIAS_ALT_CASE_PRIVATE, getPrivateKey2());
+                    assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
+                    assertPrivateKey2(keyStore.getKey(ALIAS_ALT_CASE_PRIVATE, PASSWORD_KEY));
+                }
+                if (isNullPasswordAllowed(keyStore)) {
+                    assertPrivateKey(keyStore.getKey(ALIAS_NO_PASSWORD_PRIVATE, null));
+                    assertNull(keyStore.getKey(ALIAS_ALT_CASE_NO_PASSWORD_PRIVATE, null));
+                    setPrivateKeyNoPassword(keyStore, ALIAS_ALT_CASE_NO_PASSWORD_PRIVATE,
+                            getPrivateKey2());
+                    assertPrivateKey(keyStore.getKey(ALIAS_NO_PASSWORD_PRIVATE, null));
+                    assertPrivateKey2(keyStore.getKey(ALIAS_ALT_CASE_NO_PASSWORD_PRIVATE, null));
+                }
+
+                if (isSecretKeyEnabled(keyStore)) {
+                    assertSecretKey(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
+                    assertNull(keyStore.getKey(ALIAS_ALT_CASE_SECRET, PASSWORD_KEY));
+                    setSecretKeyBytes(keyStore, ALIAS_ALT_CASE_PRIVATE, getSecretKey2());
+                    assertSecretKey(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
+                    assertSecretKey2(keyStore.getKey(ALIAS_ALT_CASE_SECRET, PASSWORD_KEY));
+                }
+            } else {
+                if (isKeyPasswordSupported(keyStore)) {
+                    assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
+                    assertPrivateKey(keyStore.getKey(ALIAS_ALT_CASE_PRIVATE, PASSWORD_KEY));
+                    setPrivateKeyBytes(keyStore, ALIAS_ALT_CASE_PRIVATE, getPrivateKey2());
+                    assertPrivateKey2(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
+                    assertPrivateKey2(keyStore.getKey(ALIAS_ALT_CASE_PRIVATE, PASSWORD_KEY));
+                }
+                if (isNullPasswordAllowed(keyStore)) {
+                    assertPrivateKey(keyStore.getKey(ALIAS_NO_PASSWORD_PRIVATE, null));
+                    assertPrivateKey(keyStore.getKey(ALIAS_ALT_CASE_NO_PASSWORD_PRIVATE, null));
+                    setPrivateKeyNoPassword(keyStore, ALIAS_ALT_CASE_NO_PASSWORD_PRIVATE,
+                            getPrivateKey2());
+                    assertPrivateKey2(keyStore.getKey(ALIAS_NO_PASSWORD_PRIVATE, null));
+                    assertPrivateKey2(keyStore.getKey(ALIAS_ALT_CASE_NO_PASSWORD_PRIVATE, null));
+                }
+
+                if (isSecretKeyEnabled(keyStore)) {
+                    assertSecretKey(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
+                    assertSecretKey(keyStore.getKey(ALIAS_ALT_CASE_SECRET, PASSWORD_KEY));
+                    setSecretKeyBytes(keyStore, ALIAS_ALT_CASE_PRIVATE, getSecretKey2());
+                    assertSecretKey2(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
+                    assertSecretKey2(keyStore.getKey(ALIAS_ALT_CASE_SECRET, PASSWORD_KEY));
+                }
+            }
+        }
+    }
+
+    public void test_KeyStore_setCertificateEntry() throws Exception {
+        for (KeyStore keyStore : keyStores()) {
+            try {
+                keyStore.setCertificateEntry(null, null);
+                fail(keyStore.getType());
+            } catch (KeyStoreException expected) {
+            }
+        }
+
+        for (KeyStore keyStore : keyStores()) {
+            populate(keyStore);
+
+            // test odd inputs
+            try {
+                keyStore.setCertificateEntry(null, null);
+                fail(keyStore.getType());
+            } catch (Exception e) {
+                if (e.getClass() != NullPointerException.class
+                    && e.getClass() != KeyStoreException.class) {
+                    throw e;
+                }
+            }
+
+            if (isReadOnly(keyStore)) {
+                try {
+                    assertNull(keyStore.getCertificate(ALIAS_CERTIFICATE));
+                    keyStore.setCertificateEntry(ALIAS_CERTIFICATE, null);
+                    fail(keyStore.getType());
+                } catch (UnsupportedOperationException expected) {
+                }
+                continue;
+            }
+
+            // Sort of delete by setting null.  Note that even though
+            // certificate is null, size doesn't change,
+            // isCertificateEntry returns true, and it is still listed in aliases.
+            if (isCertificateEnabled(keyStore)) {
+                assertCertificate(keyStore.getCertificate(ALIAS_CERTIFICATE));
+                try {
+                    int size = keyStore.size();
+                    keyStore.setCertificateEntry(ALIAS_CERTIFICATE, null);
+                    assertNull(keyStore.getType(), keyStore.getCertificate(ALIAS_CERTIFICATE));
+                    assertEquals(keyStore.getType(), size, keyStore.size());
+                    assertTrue(keyStore.getType(), keyStore.isCertificateEntry(ALIAS_CERTIFICATE));
+                    assertTrue(keyStore.getType(),
+                            Collections.list(keyStore.aliases()).contains(ALIAS_CERTIFICATE));
+                } catch (NullPointerException expectedSometimes) {
+                    if (!("PKCS12".equalsIgnoreCase(keyStore.getType()) &&
+                                "BC".equalsIgnoreCase(keyStore.getProvider().getName()))
+                            && !"AndroidKeyStore".equalsIgnoreCase(keyStore.getType())) {
+                        throw expectedSometimes;
+                    }
+                }
+            } else {
+                try {
+                    keyStore.setCertificateEntry(ALIAS_CERTIFICATE, null);
+                    fail(keyStore.getType());
+                } catch (KeyStoreException expected) {
+                }
+            }
+        }
+
+        for (KeyStore keyStore : keyStores()) {
+            if (!isCertificateEnabled(keyStore)) {
+                continue;
+            }
+
+            clearKeyStore(keyStore);
+
+            assertNull(keyStore.getCertificate(ALIAS_CERTIFICATE));
+            if (isReadOnly(keyStore)) {
+                try {
+                    setCertificate(keyStore);
+                    fail(keyStore.getType());
+                } catch (UnsupportedOperationException expected) {
+                }
+                continue;
+            }
+            setCertificate(keyStore);
+            assertCertificate(keyStore.getCertificate(ALIAS_CERTIFICATE));
+        }
+
+        for (KeyStore keyStore : keyStores()) {
+            if (!isCertificateEnabled(keyStore)) {
+                continue;
+            }
+
+            populate(keyStore);
+
+            if (isReadOnly(keyStore)) {
+                assertNull(keyStore.getCertificate(ALIAS_CERTIFICATE));
+                assertNull(keyStore.getCertificate(ALIAS_ALT_CASE_CERTIFICATE));
+            } else if (isCaseSensitive(keyStore)) {
+                assertCertificate(keyStore.getCertificate(ALIAS_CERTIFICATE));
+                assertNull(keyStore.getCertificate(ALIAS_ALT_CASE_CERTIFICATE));
+                setCertificate(keyStore,
+                               ALIAS_ALT_CASE_CERTIFICATE,
+                               getPrivateKey2().getCertificate());
+                assertCertificate(keyStore.getCertificate(ALIAS_CERTIFICATE));
+                assertCertificate2(keyStore.getCertificate(ALIAS_ALT_CASE_CERTIFICATE));
+            } else {
+                assertCertificate(keyStore.getCertificate(ALIAS_CERTIFICATE));
+                assertCertificate(keyStore.getCertificate(ALIAS_ALT_CASE_CERTIFICATE));
+                setCertificate(keyStore,
+                               ALIAS_ALT_CASE_CERTIFICATE,
+                               getPrivateKey2().getCertificate());
+                assertCertificate2(keyStore.getCertificate(ALIAS_CERTIFICATE));
+                assertCertificate2(keyStore.getCertificate(ALIAS_ALT_CASE_CERTIFICATE));
+            }
+        }
+    }
+    public void test_KeyStore_deleteEntry() throws Exception {
+        for (KeyStore keyStore : keyStores()) {
+            try {
+                keyStore.deleteEntry(null);
+                fail(keyStore.getType());
+            } catch (KeyStoreException expected) {
+            }
+        }
+
+        for (KeyStore keyStore : keyStores()) {
+            keyStore.load(null, null);
+
+            if (isReadOnly(keyStore)) {
+                try {
+                    keyStore.deleteEntry(null);
+                    fail(keyStore.getType());
+                } catch (UnsupportedOperationException expected) {
+                }
+                continue;
+            }
+
+            // test odd inputs
+            try {
+                keyStore.deleteEntry(null);
+                fail(keyStore.getType());
+            } catch (Exception e) {
+                if (e.getClass() != NullPointerException.class
+                    && e.getClass() != KeyStoreException.class) {
+                    throw e;
+                }
+            }
+            keyStore.deleteEntry("");
+        }
+
+        for (KeyStore keyStore : keyStores()) {
+            populate(keyStore);
+
+            if (isReadOnly(keyStore)) {
+                try {
+                    keyStore.deleteEntry(ALIAS_PRIVATE);
+                } catch (UnsupportedOperationException e) {
+                }
+                continue;
+            }
+
+            // test case sensitive
+            if (isKeyPasswordSupported(keyStore)) {
+                assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
+                assertCertificateChain(keyStore.getCertificateChain(ALIAS_PRIVATE));
+                keyStore.deleteEntry(ALIAS_PRIVATE);
+                assertNull(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
+            }
+            if (isNullPasswordAllowed(keyStore)) {
+                assertPrivateKey(keyStore.getKey(ALIAS_NO_PASSWORD_PRIVATE, null));
+                assertCertificateChain(keyStore.getCertificateChain(ALIAS_NO_PASSWORD_PRIVATE));
+                keyStore.deleteEntry(ALIAS_NO_PASSWORD_PRIVATE);
+                assertNull(keyStore.getKey(ALIAS_NO_PASSWORD_PRIVATE, null));
+            }
+
+            if (isSecretKeyEnabled(keyStore)) {
+                assertSecretKey(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
+                keyStore.deleteEntry(ALIAS_SECRET);
+                assertNull(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
+            } else {
+                keyStore.deleteEntry(ALIAS_SECRET);
+            }
+
+            if (isCertificateEnabled(keyStore)) {
+                assertCertificate(keyStore.getCertificate(ALIAS_CERTIFICATE));
+                keyStore.deleteEntry(ALIAS_CERTIFICATE);
+                assertNull(keyStore.getCertificate(ALIAS_CERTIFICATE));
+            } else {
+                keyStore.deleteEntry(ALIAS_CERTIFICATE);
+            }
+        }
+
+        for (KeyStore keyStore : keyStores()) {
+            populate(keyStore);
+
+            // test case insensitive
+
+            if (isCaseSensitive(keyStore)) {
+                if (isKeyPasswordSupported(keyStore)) {
+                    assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
+                    keyStore.deleteEntry(ALIAS_ALT_CASE_PRIVATE);
+                    assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
+                }
+                if (isNullPasswordAllowed(keyStore)) {
+                    assertPrivateKey(keyStore.getKey(ALIAS_NO_PASSWORD_PRIVATE, null));
+                    keyStore.deleteEntry(ALIAS_ALT_CASE_NO_PASSWORD_PRIVATE);
+                    assertPrivateKey(keyStore.getKey(ALIAS_NO_PASSWORD_PRIVATE, null));
+                }
+
+                if (isSecretKeyEnabled(keyStore)) {
+                    assertSecretKey(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
+                    keyStore.deleteEntry(ALIAS_ALT_CASE_SECRET);
+                    assertSecretKey(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
+                } else {
+                    keyStore.deleteEntry(ALIAS_SECRET);
+                }
+
+                if (isCertificateEnabled(keyStore)) {
+                    assertCertificate(keyStore.getCertificate(ALIAS_CERTIFICATE));
+                    keyStore.deleteEntry(ALIAS_ALT_CASE_CERTIFICATE);
+                    assertCertificate(keyStore.getCertificate(ALIAS_CERTIFICATE));
+                } else {
+                    keyStore.deleteEntry(ALIAS_CERTIFICATE);
+                }
+            }
+        }
+    }
+
+    public void test_KeyStore_aliases() throws Exception {
+        for (KeyStore keyStore : keyStores()) {
+            try {
+                keyStore.aliases();
+                fail(keyStore.getType());
+            } catch (KeyStoreException expected) {
+            }
+        }
+
+        for (KeyStore keyStore : keyStores()) {
+            keyStore.load(null, null);
+            if (isPersistentStorage(keyStore)) {
+                assertNotNull("Should be able to query size: " + keyStore.getType(),
+                        keyStore.aliases());
+            } else if (hasDefaultContents(keyStore)) {
+                assertTrue("Should have more than one alias already: " + keyStore.getType(),
+                        keyStore.aliases().hasMoreElements());
+            } else {
+                assertEquals("Should have no aliases:" + keyStore.getType(), Collections.EMPTY_SET,
+                        new HashSet(Collections.list(keyStore.aliases())));
+            }
+        }
+
+        for (KeyStore keyStore : keyStores()) {
+            populate(keyStore);
+
+            Set<String> expected = new HashSet<String>();
+            if (isKeyPasswordSupported(keyStore)) {
+                expected.add(ALIAS_PRIVATE);
+            }
+            if (isNullPasswordAllowed(keyStore)) {
+                expected.add(ALIAS_NO_PASSWORD_PRIVATE);
+            }
+            if (isSecretKeyEnabled(keyStore)) {
+                expected.add(ALIAS_SECRET);
+                if (isNullPasswordAllowed(keyStore)) {
+                    expected.add(ALIAS_NO_PASSWORD_SECRET);
+                }
+            }
+            if (isCertificateEnabled(keyStore)) {
+                expected.add(ALIAS_CERTIFICATE);
+            }
+            if (isPersistentStorage(keyStore)) {
+                assertNotNull("Should be able to query size: " + keyStore.getType(),
+                        keyStore.aliases());
+            } else if (hasDefaultContents(keyStore)) {
+                assertTrue(keyStore.aliases().hasMoreElements());
+            } else {
+                assertEquals(expected, new HashSet<String>(Collections.list(keyStore.aliases())));
+            }
+        }
+    }
+
+    public void test_KeyStore_containsAlias() throws Exception {
+        for (KeyStore keyStore : keyStores()) {
+            try {
+                keyStore.containsAlias(null);
+                fail(keyStore.getType());
+            } catch (KeyStoreException expected) {
+            }
+        }
+
+        for (KeyStore keyStore : keyStores()) {
+            keyStore.load(null, null);
+
+            try {
+                keyStore.containsAlias(null);
+                fail(keyStore.getType());
+            } catch (NullPointerException expected) {
+            }
+
+            assertFalse(keyStore.containsAlias(""));
+        }
+
+        for (KeyStore keyStore : keyStores()) {
+            populate(keyStore);
+
+            assertFalse(keyStore.containsAlias(""));
+
+            if (isReadOnly(keyStore)) {
+                assertFalse(keyStore.containsAlias(ALIAS_PRIVATE));
+                continue;
+            }
+            if (isKeyPasswordSupported(keyStore)) {
+                assertTrue(keyStore.containsAlias(ALIAS_PRIVATE));
+            } else if (isNullPasswordAllowed(keyStore)) {
+                assertTrue(keyStore.containsAlias(ALIAS_NO_PASSWORD_PRIVATE));
+            }
+            assertEquals(isSecretKeyEnabled(keyStore), keyStore.containsAlias(ALIAS_SECRET));
+            assertEquals(isCertificateEnabled(keyStore), keyStore.containsAlias(ALIAS_CERTIFICATE));
+
+            assertEquals(!isCaseSensitive(keyStore),
+                         keyStore.containsAlias(ALIAS_ALT_CASE_PRIVATE));
+            assertEquals(!isCaseSensitive(keyStore) && isSecretKeyEnabled(keyStore),
+                         keyStore.containsAlias(ALIAS_ALT_CASE_SECRET));
+            assertEquals(!isCaseSensitive(keyStore) && isCertificateEnabled(keyStore),
+                         keyStore.containsAlias(ALIAS_ALT_CASE_CERTIFICATE));
+        }
+    }
+
+    public void test_KeyStore_size() throws Exception {
+        for (KeyStore keyStore : keyStores()) {
+            try {
+                keyStore.aliases();
+                fail(keyStore.getType());
+            } catch (KeyStoreException expected) {
+            }
+        }
+
+        for (KeyStore keyStore : keyStores()) {
+            keyStore.load(null, null);
+            if (isPersistentStorage(keyStore)) {
+                assertTrue("Should successfully query size: " + keyStore.getType(),
+                        keyStore.size() >= 0);
+            } else if (hasDefaultContents(keyStore)) {
+                assertTrue("Should have non-empty store: " + keyStore.getType(),
+                        keyStore.size() > 0);
+            } else {
+                assertEquals("Should have empty store: " + keyStore.getType(), 0, keyStore.size());
+            }
+        }
+
+        for (KeyStore keyStore : keyStores()) {
+            populate(keyStore);
+            if (hasDefaultContents(keyStore)) {
+                assertTrue("Should have non-empty store: " + keyStore.getType(),
+                        keyStore.size() > 0);
+                continue;
+            }
+
+            int expected = 0;
+            if (isKeyPasswordSupported(keyStore)) {
+                expected++;
+            }
+            if (isNullPasswordAllowed(keyStore)) {
+                expected++;
+            }
+            if (isSecretKeyEnabled(keyStore)) {
+                expected++;
+                if (isNullPasswordAllowed(keyStore)) {
+                    expected++;
+                }
+            }
+            if (isCertificateEnabled(keyStore)) {
+                expected++;
+            }
+            assertEquals(expected, keyStore.size());
+        }
+    }
+
+    public void test_KeyStore_isKeyEntry() throws Exception {
+        for (KeyStore keyStore : keyStores()) {
+            try {
+                keyStore.isKeyEntry(null);
+                fail(keyStore.getType());
+            } catch (KeyStoreException expected) {
+            }
+        }
+
+        for (KeyStore keyStore : keyStores()) {
+            keyStore.load(null, null);
+
+            try {
+                keyStore.isKeyEntry(null);
+                fail(keyStore.getType());
+            } catch (NullPointerException expected) {
+            }
+
+            assertFalse(keyStore.isKeyEntry(""));
+        }
+
+        for (KeyStore keyStore : keyStores()) {
+            populate(keyStore);
+
+            assertFalse(keyStore.isKeyEntry(""));
+            if (isReadOnly(keyStore)) {
+                assertFalse(keyStore.isKeyEntry(ALIAS_PRIVATE));
+                continue;
+            }
+            if (isKeyPasswordSupported(keyStore)) {
+                assertTrue(keyStore.isKeyEntry(ALIAS_PRIVATE));
+            }
+            if (isNullPasswordAllowed(keyStore)) {
+                assertTrue(keyStore.isKeyEntry(ALIAS_NO_PASSWORD_PRIVATE));
+            }
+            assertEquals(isSecretKeyEnabled(keyStore), keyStore.isKeyEntry(ALIAS_SECRET));
+            assertFalse(keyStore.isKeyEntry(ALIAS_CERTIFICATE));
+
+            assertEquals(!isCaseSensitive(keyStore),
+                         keyStore.isKeyEntry(ALIAS_ALT_CASE_PRIVATE));
+            assertEquals(!isCaseSensitive(keyStore) && isSecretKeyEnabled(keyStore),
+                         keyStore.isKeyEntry(ALIAS_ALT_CASE_SECRET));
+            assertFalse(keyStore.isKeyEntry(ALIAS_ALT_CASE_CERTIFICATE));
+        }
+    }
+
+    public void test_KeyStore_isCertificateEntry() throws Exception {
+        for (KeyStore keyStore : keyStores()) {
+            try {
+                keyStore.isCertificateEntry(null);
+                fail(keyStore.getType());
+            } catch (KeyStoreException expected) {
+            }
+        }
+
+        for (KeyStore keyStore : keyStores()) {
+            keyStore.load(null, null);
+
+            if (isCertificateEnabled(keyStore)) {
+                try {
+                    keyStore.isCertificateEntry(null);
+                    fail(keyStore.getType());
+                } catch (NullPointerException expected) {
+                }
+            } else {
+                assertFalse(keyStore.isCertificateEntry(null));
+            }
+
+            assertFalse(keyStore.isCertificateEntry(""));
+        }
+
+        for (KeyStore keyStore : keyStores()) {
+            populate(keyStore);
+
+            assertFalse(keyStore.isCertificateEntry(""));
+
+            if (isKeyPasswordSupported(keyStore)) {
+                assertFalse(keyStore.isCertificateEntry(ALIAS_PRIVATE));
+            }
+            if (isNullPasswordAllowed(keyStore)) {
+                assertFalse(keyStore.isCertificateEntry(ALIAS_NO_PASSWORD_PRIVATE));
+            }
+            assertFalse(keyStore.isCertificateEntry(ALIAS_SECRET));
+            assertEquals(isCertificateEnabled(keyStore) && !isReadOnly(keyStore),
+                    keyStore.isCertificateEntry(ALIAS_CERTIFICATE));
+
+            assertFalse(keyStore.isCertificateEntry(ALIAS_ALT_CASE_PRIVATE));
+            assertFalse(keyStore.isCertificateEntry(ALIAS_ALT_CASE_SECRET));
+            assertEquals(!isCaseSensitive(keyStore)
+                    && isCertificateEnabled(keyStore)
+                    && !isReadOnly(keyStore),
+                    keyStore.isCertificateEntry(ALIAS_ALT_CASE_CERTIFICATE));
+        }
+    }
+
+    public void test_KeyStore_getCertificateAlias() throws Exception {
+        for (KeyStore keyStore : keyStores()) {
+            try {
+                keyStore.getCertificateAlias(null);
+                fail(keyStore.getType());
+            } catch (KeyStoreException expected) {
+            }
+        }
+
+        for (KeyStore keyStore : keyStores()) {
+            keyStore.load(null, null);
+            assertNull(keyStore.getCertificateAlias(null));
+        }
+
+        for (KeyStore keyStore : keyStores()) {
+            populate(keyStore);
+
+            Set<String> expected = new HashSet<String>();
+            if (isKeyPasswordSupported(keyStore)) {
+                expected.add(ALIAS_PRIVATE);
+            }
+            if (isNullPasswordAllowed(keyStore)) {
+                expected.add(ALIAS_NO_PASSWORD_PRIVATE);
+            }
+            if (isCertificateEnabled(keyStore)) {
+                expected.add(ALIAS_CERTIFICATE);
+            }
+            String actual = keyStore.getCertificateAlias(getPrivateKey().getCertificate());
+            assertEquals(!isReadOnly(keyStore), expected.contains(actual));
+            assertNull(keyStore.getCertificateAlias(getPrivateKey2().getCertificate()));
+        }
+    }
+
+    public void assertEqualsKeyStores(File expected, char[] storePassword, KeyStore actual)
+            throws Exception{
+        KeyStore ks = KeyStore.getInstance(actual.getType(), actual.getProvider());
+        InputStream is = new FileInputStream(expected);
+        ks.load(is, storePassword);
+        is.close();
+        assertEqualsKeyStores(ks, actual);
+    }
+
+    public void assertEqualsKeyStores(KeyStore expected,
+                                      ByteArrayOutputStream actual, char[] storePassword)
+            throws Exception{
+        KeyStore ks = KeyStore.getInstance(expected.getType(), expected.getProvider());
+        ks.load(new ByteArrayInputStream(actual.toByteArray()), storePassword);
+        assertEqualsKeyStores(expected, ks);
+    }
+
+    public void assertEqualsKeyStores(KeyStore expected, KeyStore actual)
+            throws Exception{
+        assertEquals(expected.size(), actual.size());
+        for (String alias : Collections.list(actual.aliases())) {
+            if (alias.equals(ALIAS_NO_PASSWORD_PRIVATE)
+                    || alias.equals(ALIAS_NO_PASSWORD_SECRET)) {
+                assertEquals(expected.getKey(alias, null),
+                             actual.getKey(alias, null));
+            } else {
+                assertEquals(expected.getKey(alias, PASSWORD_KEY),
+                             actual.getKey(alias, PASSWORD_KEY));
+            }
+            assertEquals(expected.getCertificate(alias), actual.getCertificate(alias));
+        }
+    }
+
+    public void test_KeyStore_store_OutputStream() throws Exception {
+        for (KeyStore keyStore : keyStores()) {
+            try {
+                keyStore.store(null, null);
+                fail(keyStore.getType());
+            } catch (KeyStoreException expected) {
+            }
+        }
+
+        for (KeyStore keyStore : keyStores()) {
+            keyStore.load(null, null);
+            ByteArrayOutputStream out = new ByteArrayOutputStream();
+            if (isLoadStoreUnsupported(keyStore) || isReadOnly(keyStore)) {
+                try {
+                    keyStore.store(out, null);
+                    fail(keyStore.getType());
+                } catch (UnsupportedOperationException expected) {
+                }
+                continue;
+            }
+
+            if (isNullPasswordAllowed(keyStore)) {
+                keyStore.store(out, null);
+                assertEqualsKeyStores(keyStore, out, null);
+                continue;
+            }
+
+            try {
+                keyStore.store(out, null);
+                fail(keyStore.getType());
+            } catch (Exception e) {
+                if (e.getClass() != IllegalArgumentException.class
+                    && e.getClass() != NullPointerException.class) {
+                    throw e;
+                }
+            }
+        }
+
+        for (KeyStore keyStore : keyStores()) {
+            populate(keyStore);
+
+            ByteArrayOutputStream out = new ByteArrayOutputStream();
+            if (isLoadStoreUnsupported(keyStore) || isReadOnly(keyStore)) {
+                try {
+                    keyStore.store(out, null);
+                    fail(keyStore.getType());
+                } catch (UnsupportedOperationException expected) {
+                }
+            } else if (isNullPasswordAllowed(keyStore)) {
+                keyStore.store(out, null);
+                assertEqualsKeyStores(keyStore, out, null);
+            } else {
+                try {
+                    keyStore.store(out, null);
+                    fail(keyStore.getType());
+                } catch (Exception e) {
+                    if (e.getClass() != IllegalArgumentException.class
+                        && e.getClass() != NullPointerException.class) {
+                        throw e;
+                    }
+                }
+            }
+        }
+
+        for (KeyStore keyStore : keyStores()) {
+            keyStore.load(null, null);
+            ByteArrayOutputStream out = new ByteArrayOutputStream();
+            if (isLoadStoreUnsupported(keyStore) || isReadOnly(keyStore)) {
+                try {
+                    keyStore.store(out, PASSWORD_STORE);
+                    fail(keyStore.getType());
+                } catch (UnsupportedOperationException e) {
+                }
+                continue;
+            }
+            keyStore.store(out, PASSWORD_STORE);
+            assertEqualsKeyStores(keyStore, out, PASSWORD_STORE);
+        }
+
+        for (KeyStore keyStore : keyStores()) {
+            populate(keyStore);
+            ByteArrayOutputStream out = new ByteArrayOutputStream();
+            if (isLoadStoreUnsupported(keyStore) || isReadOnly(keyStore)) {
+                try {
+                    keyStore.store(out, PASSWORD_STORE);
+                    fail(keyStore.getType());
+                } catch (UnsupportedOperationException e) {
+                }
+                continue;
+            }
+            keyStore.store(out, PASSWORD_STORE);
+            assertEqualsKeyStores(keyStore, out, PASSWORD_STORE);
+        }
+    }
+
+    public void test_KeyStore_store_LoadStoreParameter() throws Exception {
+        for (KeyStore keyStore : keyStores()) {
+            try {
+                keyStore.store(null);
+                fail(keyStore.getType());
+            } catch (KeyStoreException expected) {
+            }
+        }
+
+        for (KeyStore keyStore : keyStores()) {
+            keyStore.load(null, null);
+            try {
+                keyStore.store(null);
+                fail(keyStore.getType());
+            } catch (UnsupportedOperationException expected) {
+                assertFalse(isLoadStoreParameterSupported(keyStore));
+            } catch (IllegalArgumentException expected) {
+                // its supported, but null causes an exception
+                assertTrue(isLoadStoreParameterSupported(keyStore));
+            }
+        }
+    }
+
+    public void test_KeyStore_load_InputStream() throws Exception {
+        for (KeyStore keyStore : keyStores()) {
+            keyStore.load(null, null);
+            if (isPersistentStorage(keyStore)) {
+                assertTrue("Should be able to query size: " + keyStore.getType(),
+                        keyStore.size() >= 0);
+            } else if (hasDefaultContents(keyStore)) {
+                assertTrue("Should have non-empty store: " + keyStore.getType(),
+                        keyStore.size() > 0);
+            } else {
+                assertEquals("Should have empty store: " + keyStore.getType(), 0, keyStore.size());
+            }
+        }
+
+        for (KeyStore keyStore : keyStores()) {
+            if (isLoadStoreUnsupported(keyStore)) {
+                continue;
+            }
+            keyStore.load(null, PASSWORD_STORE);
+            if (isPersistentStorage(keyStore)) {
+                assertTrue("Should be able to query size: " + keyStore.getType(),
+                        keyStore.size() >= 0);
+            } else if (hasDefaultContents(keyStore)) {
+                assertTrue("Should have non-empty store: " + keyStore.getType(),
+                        keyStore.size() > 0);
+            } else {
+                assertEquals("Should have empty store: " + keyStore.getType(), 0, keyStore.size());
+            }
+        }
+
+        // test_KeyStore_store_OutputStream effectively tests load as well as store
+    }
+
+    public void test_KeyStore_load_LoadStoreParameter() throws Exception {
+        for (KeyStore keyStore : keyStores()) {
+            keyStore.load(null);
+            if (isPersistentStorage(keyStore)) {
+                assertTrue("Should be able to query size: " + keyStore.getType(),
+                        keyStore.size() >= 0);
+            } else if (hasDefaultContents(keyStore)) {
+                assertTrue("Should have non-empty store: " + keyStore.getType(),
+                        keyStore.size() > 0);
+            } else {
+                assertEquals("Should have empty store: " + keyStore.getType(), 0, keyStore.size());
+            }
+        }
+
+        for (KeyStore keyStore : keyStores()) {
+            try {
+                keyStore.load(new LoadStoreParameter() {
+                        public ProtectionParameter getProtectionParameter() {
+                            return null;
+                        }
+                    });
+                fail(keyStore.getType());
+            } catch (UnsupportedOperationException expected) {
+            }
+        }
+    }
+
+    public void test_KeyStore_getEntry() throws Exception {
+        for (KeyStore keyStore : keyStores()) {
+            try {
+                keyStore.getEntry(null, null);
+                fail(keyStore.getType());
+            } catch (NullPointerException expected) {
+            }
+        }
+
+        for (KeyStore keyStore : keyStores()) {
+            populate(keyStore);
+
+            // test odd inputs
+            try {
+                keyStore.getEntry(null, null);
+                fail(keyStore.getType());
+            } catch (NullPointerException expected) {
+            }
+            try {
+                keyStore.getEntry(null, PARAM_KEY);
+                fail(keyStore.getType());
+            } catch (NullPointerException expected) {
+            }
+            assertNull(keyStore.getEntry("", null));
+            assertNull(keyStore.getEntry("", PARAM_KEY));
+
+            // test case sensitive
+            if (isReadOnly(keyStore)) {
+                assertNull(keyStore.getEntry(ALIAS_PRIVATE, PARAM_KEY));
+            } else {
+                if (isKeyPasswordSupported(keyStore)) {
+                    assertPrivateKey(keyStore.getEntry(ALIAS_PRIVATE, PARAM_KEY));
+                } else if (isNullPasswordAllowed(keyStore)) {
+                    assertPrivateKey(keyStore.getEntry(ALIAS_NO_PASSWORD_PRIVATE, null));
+                }
+                if (isSecretKeyEnabled(keyStore)) {
+                    assertSecretKey(keyStore.getEntry(ALIAS_SECRET, PARAM_KEY));
+                } else {
+                    assertNull(keyStore.getEntry(ALIAS_SECRET, PARAM_KEY));
+                }
+                if (isCertificateEnabled(keyStore)) {
+                    assertCertificate(keyStore.getEntry(ALIAS_CERTIFICATE, null));
+                } else {
+                    assertNull(keyStore.getEntry(ALIAS_CERTIFICATE, null));
+                }
+            }
+
+            // test case insensitive
+            if (isCaseSensitive(keyStore) || isReadOnly(keyStore)) {
+                assertNull(keyStore.getEntry(ALIAS_ALT_CASE_PRIVATE, PARAM_KEY));
+                assertNull(keyStore.getEntry(ALIAS_ALT_CASE_SECRET, PARAM_KEY));
+            } else {
+                assertPrivateKey(keyStore.getEntry(ALIAS_ALT_CASE_PRIVATE, PARAM_KEY));
+                if (isSecretKeyEnabled(keyStore)) {
+                    assertSecretKey(keyStore.getEntry(ALIAS_ALT_CASE_SECRET, PARAM_KEY));
+                }
+            }
+            if (isCaseSensitive(keyStore) || isReadOnly(keyStore)) {
+                assertNull(keyStore.getEntry(ALIAS_ALT_CASE_CERTIFICATE, null));
+            } else {
+                if (isCertificateEnabled(keyStore)) {
+                    assertCertificate(keyStore.getEntry(ALIAS_ALT_CASE_CERTIFICATE, null));
+                }
+            }
+
+            // test with null passwords
+            if (isReadOnly(keyStore)) {
+                assertNull(keyStore.getEntry(ALIAS_NO_PASSWORD_PRIVATE, null));
+            } else if (isNullPasswordAllowed(keyStore)) {
+                assertPrivateKey(keyStore.getEntry(ALIAS_NO_PASSWORD_PRIVATE, null));
+            } else if (isKeyPasswordSupported(keyStore) && isKeyPasswordIgnored(keyStore)) {
+                assertPrivateKey(keyStore.getEntry(ALIAS_PRIVATE, null));
+            } else if (isKeyPasswordIgnored(keyStore)) {
+                try {
+                    keyStore.getEntry(ALIAS_PRIVATE, null);
+                    fail(keyStore.getType());
+                } catch (Exception e) {
+                    if (e.getClass() != UnrecoverableKeyException.class
+                        && e.getClass() != IllegalArgumentException.class) {
+                        throw e;
+                    }
+                }
+            }
+            if (isReadOnly(keyStore)) {
+                assertNull(keyStore.getEntry(ALIAS_SECRET, null));
+            } else if (isSecretKeyEnabled(keyStore)) {
+                try {
+                    keyStore.getEntry(ALIAS_SECRET, null);
+                    fail(keyStore.getType());
+                } catch (Exception e) {
+                    if (e.getClass() != UnrecoverableKeyException.class
+                        && e.getClass() != IllegalArgumentException.class) {
+                        throw e;
+                    }
+                }
+            }
+
+            // test with bad passwords
+            if (isReadOnly(keyStore)) {
+                assertNull(keyStore.getEntry(ALIAS_PRIVATE, PARAM_BAD));
+            } else if (isKeyPasswordSupported(keyStore) && isKeyPasswordIgnored(keyStore)) {
+                assertPrivateKey(keyStore.getEntry(ALIAS_PRIVATE, PARAM_BAD));
+            } else if (isKeyPasswordSupported(keyStore)) {
+                try {
+                    keyStore.getEntry(ALIAS_PRIVATE, PARAM_BAD);
+                    fail(keyStore.getType());
+                } catch (UnrecoverableKeyException expected) {
+                }
+            }
+            if (isReadOnly(keyStore)) {
+                assertNull(keyStore.getEntry(ALIAS_SECRET, PARAM_BAD));
+            } else if (isSecretKeyEnabled(keyStore)) {
+                try {
+                    keyStore.getEntry(ALIAS_SECRET, PARAM_BAD);
+                    fail(keyStore.getType());
+                } catch (UnrecoverableKeyException expected) {
+                }
+            }
+        }
+    }
+
+    public static class FakeProtectionParameter implements ProtectionParameter {
+    }
+
+    public void test_KeyStore_setEntry() throws Exception {
+        for (KeyStore keyStore : keyStores()) {
+            keyStore.load(null, null);
+            try {
+                keyStore.setEntry(null, null, null);
+                fail(keyStore.getType());
+            } catch (NullPointerException expected) {
+            }
+        }
+
+        for (KeyStore keyStore : keyStores()) {
+            keyStore.load(null, null);
+
+            try {
+                keyStore.setEntry(ALIAS_PRIVATE, getPrivateKey(), new FakeProtectionParameter());
+                fail("Should not accept unknown ProtectionParameter: " + keyStore.getProvider());
+            } catch (KeyStoreException expected) {
+            }
+        }
+
+        for (KeyStore keyStore : keyStores()) {
+            keyStore.load(null, null);
+
+            // test odd inputs
+            try {
+                keyStore.setEntry(null, null, null);
+                fail(keyStore.getType());
+            } catch (Exception e) {
+                if (e.getClass() != NullPointerException.class
+                    && e.getClass() != KeyStoreException.class) {
+                    throw e;
+                }
+            }
+            try {
+                keyStore.setEntry(null, null, PARAM_KEY);
+                fail(keyStore.getType());
+            } catch (Exception e) {
+                if (e.getClass() != NullPointerException.class
+                    && e.getClass() != KeyStoreException.class) {
+                    throw e;
+                }
+            }
+            try {
+                keyStore.setEntry("", null, PARAM_KEY);
+                fail(keyStore.getType());
+            } catch (NullPointerException expected) {
+            }
+        }
+
+        for (KeyStore keyStore : keyStores()) {
+            clearKeyStore(keyStore);
+
+            // test case sensitive
+            assertNull(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
+            if (isReadOnly(keyStore)) {
+                try {
+                    keyStore.setEntry(ALIAS_PRIVATE, getPrivateKey(), PARAM_KEY);
+                    fail(keyStore.getType());
+                } catch (UnsupportedOperationException expected) {
+                }
+                continue;
+            }
+            if (isKeyPasswordSupported(keyStore)) {
+                keyStore.setEntry(ALIAS_PRIVATE, getPrivateKey(), PARAM_KEY);
+                assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
+                assertCertificateChain(keyStore.getCertificateChain(ALIAS_PRIVATE));
+            }
+            if (isNullPasswordAllowed(keyStore)) {
+                keyStore.setEntry(ALIAS_NO_PASSWORD_PRIVATE, getPrivateKey(), null);
+                assertPrivateKey(keyStore.getKey(ALIAS_NO_PASSWORD_PRIVATE, null));
+                assertCertificateChain(keyStore.getCertificateChain(ALIAS_NO_PASSWORD_PRIVATE));
+            }
+            if (isSecretKeyEnabled(keyStore)) {
+                assertNull(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
+                keyStore.setEntry(ALIAS_SECRET, new SecretKeyEntry(getSecretKey()), PARAM_KEY);
+                assertSecretKey(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
+            } else {
+                try {
+                    keyStore.setKeyEntry(ALIAS_SECRET, getSecretKey(), PASSWORD_KEY, null);
+                    fail(keyStore.getType());
+                } catch (KeyStoreException expected) {
+                }
+            }
+            if (isCertificateEnabled(keyStore)) {
+                assertNull(keyStore.getCertificate(ALIAS_CERTIFICATE));
+                keyStore.setEntry(ALIAS_CERTIFICATE,
+                                  new TrustedCertificateEntry(getPrivateKey().getCertificate()),
+                                  null);
+                assertCertificate(keyStore.getCertificate(ALIAS_CERTIFICATE));
+            } else {
+                try {
+                    keyStore.setEntry(ALIAS_CERTIFICATE,
+                                      new TrustedCertificateEntry(getPrivateKey().getCertificate()),
+                                      null);
+                    fail(keyStore.getType());
+                } catch (KeyStoreException expected) {
+                }
+            }
+            if (isKeyPasswordSupported(keyStore)) {
+                keyStore.setEntry(ALIAS_UNICODE_PRIVATE, getPrivateKey(), PARAM_KEY);
+                assertPrivateKey(keyStore.getKey(ALIAS_UNICODE_PRIVATE, PASSWORD_KEY));
+                assertCertificateChain(keyStore.getCertificateChain(ALIAS_UNICODE_PRIVATE));
+            }
+            if (isNullPasswordAllowed(keyStore)) {
+                keyStore.setEntry(ALIAS_UNICODE_NO_PASSWORD_PRIVATE, getPrivateKey(), null);
+                assertPrivateKey(keyStore.getKey(ALIAS_UNICODE_NO_PASSWORD_PRIVATE, null));
+                assertCertificateChain(keyStore
+                        .getCertificateChain(ALIAS_UNICODE_NO_PASSWORD_PRIVATE));
+            }
+            if (isSecretKeyEnabled(keyStore)) {
+                assertNull(keyStore.getKey(ALIAS_UNICODE_SECRET, PASSWORD_KEY));
+                keyStore.setEntry(ALIAS_UNICODE_SECRET, new SecretKeyEntry(getSecretKey()), PARAM_KEY);
+                assertSecretKey(keyStore.getKey(ALIAS_UNICODE_SECRET, PASSWORD_KEY));
+            } else {
+                try {
+                    keyStore.setKeyEntry(ALIAS_UNICODE_SECRET, getSecretKey(), PASSWORD_KEY, null);
+                    fail(keyStore.getType());
+                } catch (KeyStoreException expected) {
+                }
+            }
+        }
+
+        for (KeyStore keyStore : keyStores()) {
+            populate(keyStore);
+
+            if (isReadOnly(keyStore)) {
+                assertNull(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
+                assertNull(keyStore.getKey(ALIAS_ALT_CASE_PRIVATE, PASSWORD_KEY));
+                assertNull(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
+                assertNull(keyStore.getKey(ALIAS_ALT_CASE_SECRET, PASSWORD_KEY));
+            } else if (isCaseSensitive(keyStore)) {
+                if (isKeyPasswordSupported(keyStore)) {
+                    assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
+                    assertNull(keyStore.getKey(ALIAS_ALT_CASE_PRIVATE, PASSWORD_KEY));
+                    keyStore.setEntry(ALIAS_ALT_CASE_PRIVATE, getPrivateKey2(), PARAM_KEY);
+                    assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
+                    assertPrivateKey2(keyStore.getKey(ALIAS_ALT_CASE_PRIVATE, PASSWORD_KEY));
+                }
+
+                if (isNullPasswordAllowed(keyStore)) {
+                    assertPrivateKey(keyStore.getKey(ALIAS_NO_PASSWORD_PRIVATE, null));
+                    assertNull(keyStore.getKey(ALIAS_ALT_CASE_NO_PASSWORD_PRIVATE, null));
+                    keyStore.setEntry(ALIAS_ALT_CASE_NO_PASSWORD_PRIVATE, getPrivateKey2(), null);
+                    assertPrivateKey(keyStore.getKey(ALIAS_NO_PASSWORD_PRIVATE, null));
+                    assertPrivateKey2(keyStore.getKey(ALIAS_ALT_CASE_NO_PASSWORD_PRIVATE, null));
+                }
+
+                if (isSecretKeyEnabled(keyStore)) {
+                    assertSecretKey(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
+                    assertNull(keyStore.getKey(ALIAS_ALT_CASE_SECRET, PASSWORD_KEY));
+                    keyStore.setEntry(ALIAS_ALT_CASE_SECRET,
+                                      new SecretKeyEntry(getSecretKey2()),
+                                      PARAM_KEY);
+                    assertSecretKey(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
+                    assertSecretKey2(keyStore.getKey(ALIAS_ALT_CASE_SECRET, PASSWORD_KEY));
+                }
+
+                if (isCertificateEnabled(keyStore)) {
+                    assertCertificate(keyStore.getCertificate(ALIAS_CERTIFICATE));
+                    assertNull(keyStore.getCertificate(ALIAS_ALT_CASE_CERTIFICATE));
+                    keyStore.setEntry(ALIAS_ALT_CASE_CERTIFICATE,
+                                      new TrustedCertificateEntry(
+                                              getPrivateKey2().getCertificate()),
+                                      null);
+                    assertCertificate(keyStore.getCertificate(ALIAS_CERTIFICATE));
+                    assertCertificate2(keyStore.getCertificate(ALIAS_ALT_CASE_CERTIFICATE));
+                    keyStore.setEntry(ALIAS_UNICODE_CERTIFICATE,
+                                      new TrustedCertificateEntry(
+                                              getPrivateKey().getCertificate()),
+                                      null);
+                    assertCertificate(keyStore.getCertificate(ALIAS_UNICODE_CERTIFICATE));
+                }
+            } else {
+                assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
+                assertPrivateKey(keyStore.getKey(ALIAS_ALT_CASE_PRIVATE, PASSWORD_KEY));
+                keyStore.setEntry(ALIAS_ALT_CASE_PRIVATE, getPrivateKey2(), PARAM_KEY);
+                assertPrivateKey2(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
+                assertPrivateKey2(keyStore.getKey(ALIAS_ALT_CASE_PRIVATE, PASSWORD_KEY));
+
+                if (isSecretKeyEnabled(keyStore)) {
+                    assertSecretKey(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
+                    assertSecretKey(keyStore.getKey(ALIAS_ALT_CASE_SECRET, PASSWORD_KEY));
+                    keyStore.setEntry(ALIAS_ALT_CASE_SECRET,
+                                      new SecretKeyEntry(getSecretKey2()),
+                                      PARAM_KEY);
+                    assertSecretKey2(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
+                    assertSecretKey2(keyStore.getKey(ALIAS_ALT_CASE_SECRET, PASSWORD_KEY));
+                }
+
+                if (isCertificateEnabled(keyStore)) {
+                    assertCertificate(keyStore.getCertificate(ALIAS_CERTIFICATE));
+                    assertCertificate(keyStore.getCertificate(ALIAS_ALT_CASE_CERTIFICATE));
+                    keyStore.setEntry(ALIAS_ALT_CASE_CERTIFICATE,
+                                      new TrustedCertificateEntry(
+                                              getPrivateKey2().getCertificate()),
+                                      null);
+                    assertCertificate2(keyStore.getCertificate(ALIAS_CERTIFICATE));
+                    assertCertificate2(keyStore.getCertificate(ALIAS_ALT_CASE_CERTIFICATE));
+                    keyStore.setEntry(ALIAS_UNICODE_CERTIFICATE,
+                                      new TrustedCertificateEntry(
+                                              getPrivateKey().getCertificate()),
+                                      null);
+                    assertCertificate(keyStore.getCertificate(ALIAS_UNICODE_CERTIFICATE));
+                }
+            }
+        }
+
+        for (KeyStore keyStore : keyStores()) {
+            keyStore.load(null, null);
+
+            // test with null/non-null passwords
+            if (isReadOnly(keyStore)) {
+                try {
+                    keyStore.setEntry(ALIAS_PRIVATE, getPrivateKey(), null);
+                    fail(keyStore.getType());
+                } catch (UnsupportedOperationException expected) {
+                }
+                try {
+                    keyStore.setEntry(ALIAS_SECRET, new SecretKeyEntry(getSecretKey()), null);
+                    fail(keyStore.getType());
+                } catch (UnsupportedOperationException expected) {
+                }
+                try {
+                    keyStore.setEntry(ALIAS_CERTIFICATE,
+                                      new TrustedCertificateEntry(getPrivateKey().getCertificate()),
+                                      null);
+                    fail(keyStore.getType());
+                } catch (UnsupportedOperationException expected) {
+                }
+                continue;
+            }
+            if (isNullPasswordAllowed(keyStore) || isKeyPasswordIgnored(keyStore)) {
+                for (String keyType : KEY_TYPES) {
+                    keyStore.setEntry(ALIAS_PRIVATE, getPrivateKey(keyType), null);
+                    assertPrivateKey(keyType, keyStore.getKey(ALIAS_PRIVATE, null));
+                }
+            } else {
+                try {
+                    keyStore.setEntry(ALIAS_PRIVATE, getPrivateKey(), null);
+                    fail(keyStore.getType());
+                } catch (Exception e) {
+                    if (e.getClass() != UnrecoverableKeyException.class
+                        && e.getClass() != IllegalArgumentException.class
+                        && e.getClass() != KeyStoreException.class) {
+                        throw e;
+                    }
+                }
+            }
+            if (isSecretKeyEnabled(keyStore)) {
+                if (isNullPasswordAllowed(keyStore) || isKeyPasswordIgnored(keyStore)) {
+                    keyStore.setEntry(ALIAS_SECRET, new SecretKeyEntry(getSecretKey()), null);
+                    assertSecretKey(keyStore.getKey(ALIAS_SECRET, null));
+                } else {                    
+                    try {
+                        keyStore.setEntry(ALIAS_SECRET, new SecretKeyEntry(getSecretKey()), null);
+                        fail(keyStore.getType());
+                    } catch (Exception e) {
+                        if (e.getClass() != UnrecoverableKeyException.class
+                            && e.getClass() != IllegalArgumentException.class
+                            && e.getClass() != KeyStoreException.class) {
+                            throw e;
+                        }
+                    }
+                }
+            }
+            if (isCertificateEnabled(keyStore)) {
+                if (isNullPasswordAllowed(keyStore) || isKeyPasswordIgnored(keyStore)) {
+                    keyStore.setEntry(ALIAS_CERTIFICATE,
+                                      new TrustedCertificateEntry(getPrivateKey().getCertificate()),
+                                      PARAM_KEY);
+                    assertCertificate(keyStore.getCertificate(ALIAS_CERTIFICATE));
+                } else {
+                    try {
+                        keyStore.setEntry(ALIAS_CERTIFICATE,
+                                          new TrustedCertificateEntry(
+                                                  getPrivateKey().getCertificate()),
+                                          PARAM_KEY);
+                        fail(keyStore.getType());
+                    } catch (KeyStoreException expected) {
+                    }
+                }
+            }
+        }
+    }
+
+    public void test_KeyStore_entryInstanceOf() throws Exception {
+        for (KeyStore keyStore : keyStores()) {
+            try {
+                keyStore.entryInstanceOf(null, null);
+                fail(keyStore.getType());
+            } catch (NullPointerException expected) {
+            }
+        }
+
+        for (KeyStore keyStore : keyStores()) {
+            keyStore.load(null, null);
+
+            try {
+                keyStore.entryInstanceOf(null, null);
+                fail(keyStore.getType());
+            } catch (NullPointerException expected) {
+            }
+            try {
+                keyStore.entryInstanceOf(null, Entry.class);
+                fail(keyStore.getType());
+            } catch (NullPointerException expected) {
+            }
+            try {
+                keyStore.entryInstanceOf("", null);
+                fail(keyStore.getType());
+            } catch (NullPointerException expected) {
+            }
+
+            assertFalse(keyStore.entryInstanceOf("", Entry.class));
+        }
+
+        for (KeyStore keyStore : keyStores()) {
+            populate(keyStore);
+
+            // test odd inputs
+            assertFalse(keyStore.entryInstanceOf("", Entry.class));
+            assertFalse(keyStore.entryInstanceOf("", PrivateKeyEntry.class));
+            assertFalse(keyStore.entryInstanceOf("", SecretKeyEntry.class));
+            assertFalse(keyStore.entryInstanceOf("", TrustedCertificateEntry.class));
+
+            if (isReadOnly(keyStore)) {
+                assertFalse(keyStore.entryInstanceOf(ALIAS_PRIVATE, PrivateKeyEntry.class));
+                assertFalse(keyStore.entryInstanceOf(ALIAS_PRIVATE, SecretKeyEntry.class));
+                assertFalse(keyStore.entryInstanceOf(ALIAS_PRIVATE, TrustedCertificateEntry.class));
+
+                assertFalse(keyStore.entryInstanceOf(ALIAS_SECRET, SecretKeyEntry.class));
+                assertFalse(keyStore.entryInstanceOf(ALIAS_SECRET, PrivateKeyEntry.class));
+                assertFalse(keyStore.entryInstanceOf(ALIAS_SECRET, TrustedCertificateEntry.class));
+
+                assertFalse(keyStore.entryInstanceOf(ALIAS_CERTIFICATE,
+                                                     TrustedCertificateEntry.class));
+                assertFalse(keyStore.entryInstanceOf(ALIAS_CERTIFICATE, PrivateKeyEntry.class));
+                assertFalse(keyStore.entryInstanceOf(ALIAS_CERTIFICATE, SecretKeyEntry.class));
+                continue;
+            }
+
+            // test case sensitive
+            assertEquals(isKeyPasswordSupported(keyStore),
+                    keyStore.entryInstanceOf(ALIAS_PRIVATE, PrivateKeyEntry.class));
+            assertFalse(keyStore.entryInstanceOf(ALIAS_PRIVATE, SecretKeyEntry.class));
+            assertFalse(keyStore.entryInstanceOf(ALIAS_PRIVATE, TrustedCertificateEntry.class));
+
+            assertEquals(isNullPasswordAllowed(keyStore),
+                    keyStore.entryInstanceOf(ALIAS_NO_PASSWORD_PRIVATE, PrivateKeyEntry.class));
+            assertFalse(keyStore.entryInstanceOf(ALIAS_NO_PASSWORD_PRIVATE, SecretKeyEntry.class));
+            assertFalse(keyStore.entryInstanceOf(ALIAS_NO_PASSWORD_PRIVATE,
+                    TrustedCertificateEntry.class));
+
+            assertEquals(isSecretKeyEnabled(keyStore),
+                         keyStore.entryInstanceOf(ALIAS_SECRET, SecretKeyEntry.class));
+            assertFalse(keyStore.entryInstanceOf(ALIAS_SECRET, PrivateKeyEntry.class));
+            assertFalse(keyStore.entryInstanceOf(ALIAS_SECRET, TrustedCertificateEntry.class));
+
+            assertEquals(isCertificateEnabled(keyStore),
+                         keyStore.entryInstanceOf(ALIAS_CERTIFICATE,
+                                                  TrustedCertificateEntry.class));
+            assertFalse(keyStore.entryInstanceOf(ALIAS_CERTIFICATE, PrivateKeyEntry.class));
+            assertFalse(keyStore.entryInstanceOf(ALIAS_CERTIFICATE, SecretKeyEntry.class));
+
+            // test case insensitive
+            assertEquals(!isCaseSensitive(keyStore),
+                         keyStore.entryInstanceOf(ALIAS_ALT_CASE_PRIVATE, PrivateKeyEntry.class));
+            assertFalse(keyStore.entryInstanceOf(ALIAS_ALT_CASE_PRIVATE, SecretKeyEntry.class));
+            assertFalse(keyStore.entryInstanceOf(ALIAS_ALT_CASE_PRIVATE,
+                                                 TrustedCertificateEntry.class));
+
+            assertEquals(!isCaseSensitive(keyStore) && isSecretKeyEnabled(keyStore),
+                         keyStore.entryInstanceOf(ALIAS_ALT_CASE_SECRET, SecretKeyEntry.class));
+            assertFalse(keyStore.entryInstanceOf(ALIAS_ALT_CASE_SECRET, PrivateKeyEntry.class));
+            assertFalse(keyStore.entryInstanceOf(ALIAS_ALT_CASE_SECRET,
+                                                 TrustedCertificateEntry.class));
+
+            assertEquals(!isCaseSensitive(keyStore) && isCertificateEnabled(keyStore),
+                         keyStore.entryInstanceOf(ALIAS_ALT_CASE_CERTIFICATE,
+                                                  TrustedCertificateEntry.class));
+            assertFalse(keyStore.entryInstanceOf(ALIAS_ALT_CASE_CERTIFICATE,
+                                                 PrivateKeyEntry.class));
+            assertFalse(keyStore.entryInstanceOf(ALIAS_ALT_CASE_CERTIFICATE, SecretKeyEntry.class));
+        }
+    }
+
+    // TODO(27810271): investigate why this is taking too long for armeabi-v7a
+    @TimeoutReq(minutes=10)
+    public void test_KeyStore_Builder() throws Exception {
+        for (KeyStore keyStore : keyStores()) {
+            keyStore.load(null, null);
+            try {
+                Builder.newInstance(keyStore, null);
+                fail(keyStore.getType());
+            } catch (NullPointerException expected) {
+            }
+        }
+
+        for (KeyStore keyStore : keyStores()) {
+            try {
+                Builder.newInstance(keyStore.getType(),
+                                    keyStore.getProvider(),
+                                    null);
+                fail(keyStore.getType());
+            } catch (NullPointerException expected) {
+            }
+        }
+
+        for (KeyStore keyStore : keyStores()) {
+            try {
+                Builder.newInstance(null,
+                                    null,
+                                    null,
+                                    null);
+                fail(keyStore.getType());
+            } catch (NullPointerException expected) {
+            }
+            try {
+                Builder.newInstance(keyStore.getType(),
+                                    keyStore.getProvider(),
+                                    null,
+                                    null);
+                fail(keyStore.getType());
+            } catch (NullPointerException expected) {
+            }
+        }
+
+        for (KeyStore keyStore : keyStores()) {
+            keyStore.load(null, null);
+            Builder builder = Builder.newInstance(keyStore, PARAM_STORE);
+            try {
+                builder.getProtectionParameter(null);
+                fail(keyStore.getType());
+            } catch (NullPointerException expected) {
+            }
+            assertEquals(keyStore, builder.getKeyStore());
+            try {
+                builder.getProtectionParameter(null);
+                fail(keyStore.getType());
+            } catch (NullPointerException expected) {
+            }
+            assertEquals(PARAM_STORE, builder.getProtectionParameter(""));
+        }
+
+        for (KeyStore keyStore : keyStores()) {
+            populate(keyStore);
+
+            File file = File.createTempFile("keystore", keyStore.getProvider().getName());
+            OutputStream os = null;
+            try {
+                os = new FileOutputStream(file);
+                if (isLoadStoreUnsupported(keyStore) || isReadOnly(keyStore)) {
+                    try {
+                        keyStore.store(os, PASSWORD_STORE);
+                        fail(keyStore.getType());
+                    } catch (UnsupportedOperationException expected) {
+                    }
+                    continue;
+                }
+
+                keyStore.store(os, PASSWORD_STORE);
+                os.close();
+                Builder builder = Builder.newInstance(keyStore.getType(),
+                                                      keyStore.getProvider(),
+                                                      file,
+                                                      PARAM_STORE);
+                assertEquals(keyStore.getType(), builder.getKeyStore().getType());
+                assertEquals(keyStore.getProvider(), builder.getKeyStore().getProvider());
+                assertEquals(PARAM_STORE, builder.getProtectionParameter(""));
+                assertEqualsKeyStores(file, PASSWORD_STORE, keyStore);
+            } finally {
+                try {
+                    if (os != null) {
+                        os.close();
+                    }
+                } catch (IOException ignored) {
+                }
+                file.delete();
+            }
+        }
+
+        for (KeyStore keyStore : keyStores()) {
+            if (isLoadStoreUnsupported(keyStore)) {
+                continue;
+            }
+            Builder builder = Builder.newInstance(keyStore.getType(),
+                                                  keyStore.getProvider(),
+                                                  PARAM_STORE);
+            assertEquals(keyStore.getType(), builder.getKeyStore().getType());
+            assertEquals(keyStore.getProvider(), builder.getKeyStore().getProvider());
+            assertEquals(PARAM_STORE, builder.getProtectionParameter(""));
+        }
+    }
+
+    public void test_KeyStore_cacerts() throws Exception {
+        if (StandardNames.IS_RI) {
+            return;
+        }
+        KeyStore ks = KeyStore.getInstance("AndroidCAStore");
+        assertEquals("AndroidCAStore", ks.getType());
+        assertEquals("HarmonyJSSE", ks.getProvider().getName());
+
+        ks.load(null, null);
+        for (String alias : Collections.list(ks.aliases())) {
+            Certificate c = null;
+            try {
+                c = ks.getCertificate(alias);
+                assertNotNull(c);
+                assertTrue(ks.isCertificateEntry(alias));
+                assertTrue(ks.entryInstanceOf(alias, TrustedCertificateEntry.class));
+                assertEquals(alias, ks.getCertificateAlias(c));
+
+                assertTrue(c instanceof X509Certificate);
+                X509Certificate cert = (X509Certificate) c;
+                assertEquals(cert.getSubjectUniqueID(), cert.getIssuerUniqueID());
+                assertNotNull(cert.getPublicKey());
+
+                assertTrue(ks.containsAlias(alias));
+                assertNotNull(ks.getCreationDate(alias));
+                assertNotNull(ks.getEntry(alias, null));
+
+                assertFalse(ks.isKeyEntry(alias));
+                assertNull(ks.getKey(alias, null));
+                assertNull(ks.getCertificateChain(alias));
+
+            } catch (Throwable t) {
+                throw new Exception("alias=" + alias + " cert=" + c, t);
+            }
+        }
+    }
+
+    // http://b/857840: want JKS key store
+    public void testDefaultKeystore() {
+        String type = KeyStore.getDefaultType();
+        assertEquals(StandardNames.KEY_STORE_ALGORITHM, type);
+
+        try {
+            KeyStore store = KeyStore.getInstance(KeyStore.getDefaultType());
+            assertNotNull("Keystore must not be null", store);
+        } catch (Exception ex) {
+            throw new RuntimeException(ex);
+        }
+
+        try {
+            KeyStore store = KeyStore.getInstance(StandardNames.KEY_STORE_ALGORITHM);
+            assertNotNull("Keystore must not be null", store);
+        } catch (Exception ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+}
diff --git a/tests/tests/keystore/src/android/keystore/cts/RSASignatureTest.java b/tests/tests/keystore/src/android/keystore/cts/RSASignatureTest.java
index 9ae3043..d31f2e4 100644
--- a/tests/tests/keystore/src/android/keystore/cts/RSASignatureTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/RSASignatureTest.java
@@ -28,7 +28,7 @@
 import java.util.Collection;
 import java.util.List;
 
-import com.android.cts.keystore.R;
+import android.keystore.cts.R;
 
 import android.content.Context;
 import android.security.keystore.KeyProperties;
@@ -163,7 +163,7 @@
                         R.raw.rsa_key6_768_pkcs8, R.raw.rsa_key6_768_cert, importParams),
                 TestUtils.importIntoAndroidKeyStore("testRSA1024", context,
                         R.raw.rsa_key3_1024_pkcs8, R.raw.rsa_key3_1024_cert, importParams),
-                TestUtils.importIntoAndroidKeyStore("testRSA2024", context,
+                TestUtils.importIntoAndroidKeyStore("testRSA2048", context,
                         R.raw.rsa_key8_2048_pkcs8, R.raw.rsa_key8_2048_cert, importParams),
                 TestUtils.importIntoAndroidKeyStore("testRSA3072", context,
                         R.raw.rsa_key7_3072_pksc8, R.raw.rsa_key7_3072_cert, importParams),
diff --git a/tests/tests/keystore/src/android/keystore/cts/SignatureTest.java b/tests/tests/keystore/src/android/keystore/cts/SignatureTest.java
index 8451eb8..4fa8899 100644
--- a/tests/tests/keystore/src/android/keystore/cts/SignatureTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/SignatureTest.java
@@ -16,7 +16,7 @@
 
 package android.keystore.cts;
 
-import com.android.cts.keystore.R;
+import android.keystore.cts.R;
 
 import java.security.InvalidKeyException;
 import java.security.KeyPair;
@@ -562,8 +562,7 @@
         }
     }
 
-    // TODO: Re-enable this test once Signature.initSign passes SecureRandom to SPI (Bug 22485587).
-    public void DISABLED_testEntropyConsumption() throws Exception {
+    public void testEntropyConsumption() throws Exception {
         // Assert that signature generation consumes the correct amount of entropy from the provided
         // SecureRandom. There is no need to check that Signature.verify does not consume entropy
         // because Signature.initVerify does not take a SecureRandom.
diff --git a/tests/tests/keystore/src/android/keystore/cts/TestUtils.java b/tests/tests/keystore/src/android/keystore/cts/TestUtils.java
index 85b8869..2c87005 100644
--- a/tests/tests/keystore/src/android/keystore/cts/TestUtils.java
+++ b/tests/tests/keystore/src/android/keystore/cts/TestUtils.java
@@ -744,7 +744,8 @@
             if (KeyProperties.SIGNATURE_PADDING_RSA_PKCS1.equalsIgnoreCase(paddingScheme)) {
                 paddingOverheadBytes = 30;
             } else if (KeyProperties.SIGNATURE_PADDING_RSA_PSS.equalsIgnoreCase(paddingScheme)) {
-                paddingOverheadBytes = 22;
+                int saltSizeBytes = (digestOutputSizeBits + 7) / 8;
+                paddingOverheadBytes = saltSizeBytes + 1;
             } else {
                 throw new IllegalArgumentException(
                         "Unsupported signature padding scheme: " + paddingScheme);
diff --git a/tests/tests/libcorelegacy22/Android.mk b/tests/tests/libcorelegacy22/Android.mk
index fb3c503..408fd3b 100644
--- a/tests/tests/libcorelegacy22/Android.mk
+++ b/tests/tests/libcorelegacy22/Android.mk
@@ -29,4 +29,7 @@
 
 LOCAL_SDK_VERSION := 22
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/libcorelegacy22/AndroidManifest.xml b/tests/tests/libcorelegacy22/AndroidManifest.xml
index 4ff9ec2..131613e 100644
--- a/tests/tests/libcorelegacy22/AndroidManifest.xml
+++ b/tests/tests/libcorelegacy22/AndroidManifest.xml
@@ -16,7 +16,7 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.libcorelegacy22">
+    package="android.libcorelegacy22.cts">
 
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <uses-permission android:name="android.permission.READ_LOGS" />
@@ -25,7 +25,7 @@
     </application>
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.cts.libcorelegacy22"
+                     android:targetPackage="android.libcorelegacy22.cts"
                      android:label="CTS tests of android APIs last available in API 22">
         <meta-data android:name="listener"
             android:value="com.android.cts.runner.CtsTestRunListener" />
diff --git a/tests/tests/libcorelegacy22/AndroidTest.xml b/tests/tests/libcorelegacy22/AndroidTest.xml
new file mode 100644
index 0000000..cdc6611
--- /dev/null
+++ b/tests/tests/libcorelegacy22/AndroidTest.xml
@@ -0,0 +1,23 @@
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS Legacy Libcore test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsLibcoreLegacy22TestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.libcorelegacy22.cts" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/tests/location/Android.mk b/tests/tests/location/Android.mk
index 62d0d5d..6a8b9d3 100644
--- a/tests/tests/location/Android.mk
+++ b/tests/tests/location/Android.mk
@@ -16,17 +16,43 @@
 
 include $(CLEAR_VARS)
 
+# Reusable Location test classes and helpers
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := cts-location-tests
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
+    ctsdeviceutil ctstestrunner
+
+LOCAL_SDK_VERSION := test_current
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src/android/location/cts)
+
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
+# CtsLocationTestCases package
+
+include $(CLEAR_VARS)
+
 # don't include this package in any target
 LOCAL_MODULE_TAGS := optional
 # and when built explicitly put it in the data partition
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctstestrunner
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
 LOCAL_PACKAGE_NAME := CtsLocationTestCases
 
-LOCAL_SDK_VERSION := current
+LOCAL_SDK_VERSION := test_current
 
 include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/location/AndroidManifest.xml b/tests/tests/location/AndroidManifest.xml
index 5016f49..f9985ba 100644
--- a/tests/tests/location/AndroidManifest.xml
+++ b/tests/tests/location/AndroidManifest.xml
@@ -16,7 +16,7 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.location">
+    package="android.location.cts">
 
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <application>
@@ -28,7 +28,7 @@
     <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"/>
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.cts.location"
+                     android:targetPackage="android.location.cts"
                      android:label="CTS tests of android.location">
         <meta-data android:name="listener"
             android:value="com.android.cts.runner.CtsTestRunListener" />
diff --git a/tests/tests/location/AndroidTest.xml b/tests/tests/location/AndroidTest.xml
new file mode 100644
index 0000000..4ac850e
--- /dev/null
+++ b/tests/tests/location/AndroidTest.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS Location test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.LocationCheck" />
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsLocationTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.location.cts" />
+        <option name="runtime-hint" value="18m8s" />
+    </test>
+
+</configuration>
diff --git a/tests/tests/location/src/android/location/cts/AddressTest.java b/tests/tests/location/src/android/location/cts/AddressTest.java
index 66e4fad..411a687 100644
--- a/tests/tests/location/src/android/location/cts/AddressTest.java
+++ b/tests/tests/location/src/android/location/cts/AddressTest.java
@@ -270,6 +270,39 @@
         assertNull(address.getLocality());
     }
 
+    public void testAccessPremises() {
+        Address address = new Address(Locale.PRC);
+
+        String premises = "Appartment";
+        address.setPremises(premises);
+        assertEquals(premises, address.getPremises());
+
+        address.setPremises(null);
+        assertNull(address.getPremises());
+    }
+
+    public void testAccessSubLocality() {
+        Address address = new Address(Locale.PRC);
+
+        String subLocality = "Sarchnar";
+        address.setSubLocality(subLocality);
+        assertEquals(subLocality, address.getSubLocality());
+
+        address.setSubLocality(null);
+        assertNull(address.getSubLocality());
+    }
+
+    public void testAccessSubThoroughfare() {
+        Address address = new Address(Locale.PRC);
+
+        String subThoroughfare = "1600";
+        address.setSubThoroughfare(subThoroughfare);
+        assertEquals(subThoroughfare, address.getSubThoroughfare());
+
+        address.setSubThoroughfare(null);
+        assertNull(address.getSubThoroughfare());
+    }
+
     public void testWriteToParcel() {
         Locale locale = Locale.KOREA;
         Address address = new Address(locale);
diff --git a/tests/tests/location/src/android/location/cts/GeocoderTest.java b/tests/tests/location/src/android/location/cts/GeocoderTest.java
index a073284..d96b73f 100644
--- a/tests/tests/location/src/android/location/cts/GeocoderTest.java
+++ b/tests/tests/location/src/android/location/cts/GeocoderTest.java
@@ -41,6 +41,11 @@
         }
     }
 
+    public void testIsPresent() {
+        Geocoder geocoder = new Geocoder(getContext());
+        assertTrue(geocoder.isPresent());
+    }
+
     public void testGetFromLocation() throws IOException, InterruptedException {
         Geocoder geocoder = new Geocoder(getContext());
 
diff --git a/tests/tests/location/src/android/location/cts/GnssClockTest.java b/tests/tests/location/src/android/location/cts/GnssClockTest.java
new file mode 100644
index 0000000..b883f74
--- /dev/null
+++ b/tests/tests/location/src/android/location/cts/GnssClockTest.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.location.cts;
+
+import android.location.GnssClock;
+import android.os.Parcel;
+
+public class GnssClockTest extends GnssTestCase {
+    public void testDescribeContents() {
+        GnssClock clock = new GnssClock();
+        clock.describeContents();
+    }
+
+    public void testReset() {
+        GnssClock clock = new GnssClock();
+        clock.reset();
+    }
+
+    private static void setTestValues(GnssClock clock) {
+        clock.setBiasNanos(1.0);
+        clock.setBiasUncertaintyNanos(2.0);
+        clock.setDriftNanosPerSecond(3.0);
+        clock.setDriftUncertaintyNanosPerSecond(4.0);
+        clock.setFullBiasNanos(5);
+        clock.setHardwareClockDiscontinuityCount(6);
+        clock.setLeapSecond(7);
+        clock.setTimeNanos(8);
+        clock.setTimeUncertaintyNanos(9.0);
+    }
+
+    private static void verifyTestValues(GnssClock clock) {
+        assertEquals(1.0, clock.getBiasNanos());
+        assertEquals(2.0, clock.getBiasUncertaintyNanos());
+        assertEquals(3.0, clock.getDriftNanosPerSecond());
+        assertEquals(4.0, clock.getDriftUncertaintyNanosPerSecond());
+        assertEquals(5, clock.getFullBiasNanos());
+        assertEquals(6, clock.getHardwareClockDiscontinuityCount());
+        assertEquals(7, clock.getLeapSecond());
+        assertEquals(8, clock.getTimeNanos());
+        assertEquals(9.0, clock.getTimeUncertaintyNanos());
+    }
+
+    public void testWriteToParcel() {
+        GnssClock clock = new GnssClock();
+        setTestValues(clock);
+        Parcel parcel = Parcel.obtain();
+        clock.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        GnssClock newClock = GnssClock.CREATOR.createFromParcel(parcel);
+        verifyTestValues(newClock);
+    }
+
+    public void testSet() {
+        GnssClock clock = new GnssClock();
+        setTestValues(clock);
+        GnssClock newClock = new GnssClock();
+        newClock.set(clock);
+        verifyTestValues(newClock);
+    }
+
+    public void testHasAndReset() {
+        GnssClock clock = new GnssClock();
+        setTestValues(clock);
+
+        assertTrue(clock.hasBiasNanos());
+        clock.resetBiasNanos();
+        assertFalse(clock.hasBiasNanos());
+
+        assertTrue(clock.hasBiasUncertaintyNanos());
+        clock.resetBiasUncertaintyNanos();
+        assertFalse(clock.hasBiasUncertaintyNanos());
+
+        assertTrue(clock.hasDriftNanosPerSecond());
+        clock.resetDriftNanosPerSecond();
+        assertFalse(clock.hasDriftNanosPerSecond());
+
+        assertTrue(clock.hasDriftUncertaintyNanosPerSecond());
+        clock.resetDriftUncertaintyNanosPerSecond();
+        assertFalse(clock.hasDriftUncertaintyNanosPerSecond());
+
+        assertTrue(clock.hasFullBiasNanos());
+        clock.resetFullBiasNanos();
+        assertFalse(clock.hasFullBiasNanos());
+
+        assertTrue(clock.hasLeapSecond());
+        clock.resetLeapSecond();
+        assertFalse(clock.hasLeapSecond());
+
+        assertTrue(clock.hasTimeUncertaintyNanos());
+        clock.resetTimeUncertaintyNanos();
+        assertFalse(clock.hasTimeUncertaintyNanos());
+    }
+}
diff --git a/tests/tests/location/src/android/location/cts/GnssMeasurementRegistrationTest.java b/tests/tests/location/src/android/location/cts/GnssMeasurementRegistrationTest.java
new file mode 100644
index 0000000..d3a310e
--- /dev/null
+++ b/tests/tests/location/src/android/location/cts/GnssMeasurementRegistrationTest.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2015 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.location.cts;
+
+import android.location.GnssMeasurement;
+import android.location.GnssMeasurementsEvent;
+import android.location.GpsStatus;
+import android.util.Log;
+
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Test for {@link GnssMeasurement}s without location registration.
+ *
+ * Test steps:
+ * 1. Register a listener for {@link GnssMeasurementsEvent}s.
+ * 2. Check {@link GnssMeasurementsEvent} status: if the status is not
+ *    {@link GnssMeasurementsEvent#STATUS_READY}, the test will be skipped because one of the
+ *    following reasons:
+ *          2.1 the device does not support the feature,
+ *          2.2 GPS is disabled in the device,
+ *          2.3 Location is disabled in the device.
+ * 3. If at least one {@link GnssMeasurementsEvent} is received, the test will pass.
+ * 2. If no {@link GnssMeasurementsEvent} are received, then check whether the device is deep indoor.
+ *    This is done by performing the following steps:
+ *          2.1 Register for location updates, and {@link GpsStatus} events.
+ *          2.2 Wait for {@link TestGpsStatusListener#TIMEOUT_IN_SEC}.
+ *          2.3 If no {@link GpsStatus} is received this will mean that the device is located
+ *              indoor. Test will be skipped.
+ *          2.4 If we receive a {@link GpsStatus}, it mean that {@link GnssMeasurementsEvent}s are
+ *              provided only if the application registers for location updates as well:
+ *                  2.4.1 The test will pass with a warning for the M release.
+ *                  2.4.2 The test might fail in a future Android release, when this requirement
+ *                        becomes mandatory.
+ */
+public class GnssMeasurementRegistrationTest extends GnssTestCase {
+
+    private static final String TAG = "GnssMeasRegTest";
+    private TestLocationManager mTestLocationManager;
+    private static final int EVENTS_COUNT = 5;
+    private static final int GPS_EVENTS_COUNT = 1;
+    private TestLocationListener mLocationListener;
+    private TestGnssMeasurementListener mMeasurementListener;
+    private TestGpsStatusListener mGpsStatusListener;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        mTestLocationManager = new TestLocationManager(getContext());
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        // Unregister listeners
+        if (mLocationListener != null) {
+            mTestLocationManager.removeLocationUpdates(mLocationListener);
+        }
+        if (mMeasurementListener != null) {
+            mTestLocationManager.unregisterGnssMeasurementCallback(mMeasurementListener);
+        }
+        if (mGpsStatusListener != null) {
+            mTestLocationManager.removeGpsStatusListener(mGpsStatusListener);
+        }
+        super.tearDown();
+    }
+
+    /**
+     * Test GPS measurements registration.
+     */
+    public void testGnssMeasurementRegistration() throws Exception {
+        if (!TestMeasurementUtil.canTestRunOnCurrentDevice(mTestLocationManager)) {
+            return;
+        }
+
+        // Register for GPS measurements.
+        mMeasurementListener = new TestGnssMeasurementListener(TAG, GPS_EVENTS_COUNT);
+        mTestLocationManager.registerGnssMeasurementCallback(mMeasurementListener);
+
+        mMeasurementListener.await();
+        if (!mMeasurementListener.verifyState()) {
+            return;
+        }
+
+        List<GnssMeasurementsEvent> events = mMeasurementListener.getEvents();
+        Log.i(TAG, "Number of GnssMeasurement events received = " + events.size());
+        if (!events.isEmpty()) {
+            // Test passes if we get at least 1 pseudorange.
+            Log.i(TAG, "Received GPS measurements. Test Pass.");
+            return;
+        }
+
+        // Test if device is deep indoor.
+        Log.i(TAG, "Did not receive any GPS measurements. Test if device is deep indoor.");
+
+        // Register for location updates.
+        mLocationListener = new TestLocationListener(EVENTS_COUNT);
+        mTestLocationManager.requestLocationUpdates(mLocationListener);
+
+        // Wait for location updates
+        mLocationListener.await();
+        Log.i(TAG, "Location received = " + mLocationListener.isLocationReceived());
+
+        // Register for Gps Status updates
+        mGpsStatusListener = new TestGpsStatusListener(EVENTS_COUNT, mTestLocationManager);
+        mTestLocationManager.addGpsStatusListener(mGpsStatusListener);
+
+        // wait for Gps Status updates
+        mGpsStatusListener.await();
+        if (!mGpsStatusListener.isGpsStatusReceived()) {
+            // Skip the Test. No Satellites are visible. Device may be Indoor
+            Log.i(TAG, "No Satellites are visible. Device may be Indoor. Skipping Test.");
+            return;
+        }
+
+        SoftAssert.failAsWarning(
+                TAG,
+                "GPS measurements were not received without registering for location updates.");
+    }
+}
diff --git a/tests/tests/location/src/android/location/cts/GnssMeasurementTest.java b/tests/tests/location/src/android/location/cts/GnssMeasurementTest.java
new file mode 100644
index 0000000..2fc63a8
--- /dev/null
+++ b/tests/tests/location/src/android/location/cts/GnssMeasurementTest.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.location.cts;
+
+import android.location.GnssMeasurement;
+import android.location.GnssStatus;
+import android.os.Parcel;
+
+public class GnssMeasurementTest extends GnssTestCase {
+    public void testDescribeContents() {
+        GnssMeasurement measurement = new GnssMeasurement();
+        measurement.describeContents();
+    }
+
+    public void testReset() {
+        GnssMeasurement measurement = new GnssMeasurement();
+        measurement.reset();
+    }
+
+    private static void setTestValues(GnssMeasurement measurement) {
+        measurement.setAccumulatedDeltaRangeMeters(1.0);
+        measurement.setAccumulatedDeltaRangeState(2);
+        measurement.setAccumulatedDeltaRangeUncertaintyMeters(3.0);
+        measurement.setCarrierCycles(4);
+        measurement.setCarrierFrequencyHz(5.0f);
+        measurement.setCarrierPhase(6.0);
+        measurement.setCarrierPhaseUncertainty(7.0);
+        measurement.setCn0DbHz(8.0);
+        measurement.setConstellationType(GnssStatus.CONSTELLATION_GALILEO);
+        measurement.setMultipathIndicator(GnssMeasurement.MULTIPATH_INDICATOR_DETECTED);
+        measurement.setPseudorangeRateMetersPerSecond(9.0);
+        measurement.setPseudorangeRateUncertaintyMetersPerSecond(10.0);
+        measurement.setReceivedSvTimeNanos(11);
+        measurement.setReceivedSvTimeUncertaintyNanos(12);
+        measurement.setSnrInDb(13.0);
+        measurement.setState(14);
+        measurement.setSvid(15);
+        measurement.setTimeOffsetNanos(16.0);
+    }
+
+    private static void verifyTestValues(GnssMeasurement measurement) {
+        assertEquals(1.0, measurement.getAccumulatedDeltaRangeMeters());
+        assertEquals(2, measurement.getAccumulatedDeltaRangeState());
+        assertEquals(3.0, measurement.getAccumulatedDeltaRangeUncertaintyMeters());
+        assertEquals(4, measurement.getCarrierCycles());
+        assertEquals(5.0f, measurement.getCarrierFrequencyHz());
+        assertEquals(6.0, measurement.getCarrierPhase());
+        assertEquals(7.0, measurement.getCarrierPhaseUncertainty());
+        assertEquals(8.0, measurement.getCn0DbHz());
+        assertEquals(GnssStatus.CONSTELLATION_GALILEO, measurement.getConstellationType());
+        assertEquals(GnssMeasurement.MULTIPATH_INDICATOR_DETECTED,
+                measurement.getMultipathIndicator());
+        assertEquals(9.0, measurement.getPseudorangeRateMetersPerSecond());
+        assertEquals(10.0, measurement.getPseudorangeRateUncertaintyMetersPerSecond());
+        assertEquals(11, measurement.getReceivedSvTimeNanos());
+        assertEquals(12, measurement.getReceivedSvTimeUncertaintyNanos());
+        assertEquals(13.0, measurement.getSnrInDb());
+        assertEquals(14, measurement.getState());
+        assertEquals(15, measurement.getSvid());
+        assertEquals(16.0, measurement.getTimeOffsetNanos());
+    }
+
+    public void testWriteToParcel() {
+        GnssMeasurement measurement = new GnssMeasurement();
+        setTestValues(measurement);
+        Parcel parcel = Parcel.obtain();
+        measurement.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        GnssMeasurement newMeasurement = GnssMeasurement.CREATOR.createFromParcel(parcel);
+        verifyTestValues(newMeasurement);
+    }
+
+    public void testSet() {
+        GnssMeasurement measurement = new GnssMeasurement();
+        setTestValues(measurement);
+        GnssMeasurement newMeasurement = new GnssMeasurement();
+        newMeasurement.set(measurement);
+        verifyTestValues(newMeasurement);
+    }
+
+    public void testSetReset() {
+        GnssMeasurement measurement = new GnssMeasurement();
+        setTestValues(measurement);
+
+        assertTrue(measurement.hasCarrierCycles());
+        measurement.resetCarrierCycles();
+        assertFalse(measurement.hasCarrierCycles());
+
+        assertTrue(measurement.hasCarrierFrequencyHz());
+        measurement.resetCarrierFrequencyHz();
+        assertFalse(measurement.hasCarrierFrequencyHz());
+
+        assertTrue(measurement.hasCarrierPhase());
+        measurement.resetCarrierPhase();
+        assertFalse(measurement.hasCarrierPhase());
+
+        assertTrue(measurement.hasCarrierPhaseUncertainty());
+        measurement.resetCarrierPhaseUncertainty();
+        assertFalse(measurement.hasCarrierPhaseUncertainty());
+
+        assertTrue(measurement.hasSnrInDb());
+        measurement.resetSnrInDb();
+        assertFalse(measurement.hasSnrInDb());
+    }
+}
diff --git a/tests/tests/location/src/android/location/cts/GnssMeasurementValuesTest.java b/tests/tests/location/src/android/location/cts/GnssMeasurementValuesTest.java
new file mode 100644
index 0000000..ba6311f
--- /dev/null
+++ b/tests/tests/location/src/android/location/cts/GnssMeasurementValuesTest.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2015 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.location.cts;
+
+import android.location.GnssMeasurement;
+import android.location.GnssMeasurementsEvent;
+import android.util.Log;
+
+import java.util.List;
+
+/**
+ * Test the {@link GnssMeasurement} values.
+ *
+ * Test steps:
+ * 1. Register for location updates.
+ * 2. Register a listener for {@link GnssMeasurementsEvent}s.
+ * 3. Wait for {@link #LOCATION_TO_COLLECT_COUNT} locations.
+ * 4. Check {@link GnssMeasurementsEvent} status: if the status is not
+ *    {@link GnssMeasurementsEvent#STATUS_READY}, the test will be skipped because one of the
+ *    following reasons:
+ *          4.1 the device does not support the feature,
+ *          4.2 GPS is disabled in the device,
+ *          4.3 Location is disabled in the device.
+ *  5. Verify {@link GnssMeasurement}s (all mandatory fields), the test will fail if any of the
+ *     mandatory fields is not populated or in the expected range.
+ */
+public class GnssMeasurementValuesTest extends GnssTestCase {
+
+    private static final String TAG = "GnssMeasValuesTest";
+    private static final int LOCATION_TO_COLLECT_COUNT = 5;
+
+    private TestLocationManager mTestLocationManager;
+    private TestGnssMeasurementListener mMeasurementListener;
+    private TestLocationListener mLocationListener;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        mTestLocationManager = new TestLocationManager(getContext());
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        // Unregister listeners
+        if (mLocationListener != null) {
+            mTestLocationManager.removeLocationUpdates(mLocationListener);
+        }
+        if (mMeasurementListener != null) {
+            mTestLocationManager.unregisterGnssMeasurementCallback(mMeasurementListener);
+        }
+        super.tearDown();
+    }
+
+    /**
+     * Tests that one can listen for {@link GnssMeasurementsEvent} for collection purposes.
+     * It only performs sanity checks for the measurements received.
+     * This tests uses actual data retrieved from GPS HAL.
+     */
+    public void testListenForGnssMeasurements() throws Exception {
+        if (!TestMeasurementUtil.canTestRunOnCurrentDevice(mTestLocationManager)) {
+            return;
+        }
+
+        mLocationListener = new TestLocationListener(LOCATION_TO_COLLECT_COUNT);
+        mTestLocationManager.requestLocationUpdates(mLocationListener);
+
+        mMeasurementListener = new TestGnssMeasurementListener(TAG);
+        mTestLocationManager.registerGnssMeasurementCallback(mMeasurementListener);
+
+        boolean success = mLocationListener.await();
+        if (!success) {
+            Log.i(TAG, "Time elapsed without getting enough location fixes. Possibly, the test is"
+                    + " ran deep indoor. Skipping Test.");
+            return;
+        }
+
+        Log.i(TAG, "Location status received = " + mLocationListener.isLocationReceived());
+        if (!mMeasurementListener.verifyState()) {
+            return;
+        }
+
+        List<GnssMeasurementsEvent> events = mMeasurementListener.getEvents();
+        int eventCount = events.size();
+        Log.i(TAG, "Number of Gps Event received = " + eventCount);
+        assertTrue(
+                "GnssMeasurementEvent count: expected >= 0, received = " + eventCount,
+                eventCount > 0);
+
+        SoftAssert softAssert = new SoftAssert(TAG);
+        // we received events, so perform a quick sanity check on mandatory fields
+        for (GnssMeasurementsEvent event : events) {
+            // Verify Gps Event mandatory fields are in required ranges
+            assertNotNull("GnssMeasurementEvent cannot be null.", event);
+            // TODO(sumitk): To validate the timestamp if we receive GPS clock.
+            long timeInNs = event.getClock().getTimeNanos();
+            softAssert.assertTrue("time_ns: clock value",
+                    timeInNs,
+                    "X >= 0",
+                    String.valueOf(timeInNs),
+                    timeInNs >= 0L);
+
+            for (GnssMeasurement measurement : event.getMeasurements()) {
+                TestMeasurementUtil.assertAllGnssMeasurementMandatoryFields(measurement,
+                        softAssert, timeInNs);
+            }
+        }
+        softAssert.assertAll();
+    }
+}
diff --git a/tests/tests/location/src/android/location/cts/GnssMeasurementWhenNoLocationTest.java b/tests/tests/location/src/android/location/cts/GnssMeasurementWhenNoLocationTest.java
new file mode 100644
index 0000000..6752a34
--- /dev/null
+++ b/tests/tests/location/src/android/location/cts/GnssMeasurementWhenNoLocationTest.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2015 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.location.cts;
+
+import android.location.GnssMeasurement;
+import android.location.GnssMeasurementsEvent;
+import android.location.GpsStatus;
+import android.util.Log;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * Test for {@link GnssMeasurement} without a location fix.
+ *
+ * Test steps:
+ * 1. Clear A-GPS: this ensures that the device is not in a warm mode and it has 4+ satellites
+ *    acquired already.
+ * 2. Register a listener for:
+ *      - {@link GnssMeasurementsEvent}s,
+ *      - location updates and
+ *      - {@link GpsStatus} events.
+ * 3. Wait for {@link TestGpsStatusListener#TIMEOUT_IN_SEC}.
+ * 4. Check {@link GnssMeasurementsEvent} status: if the status is not
+ *    {@link GnssMeasurementsEvent#STATUS_READY}, the test will be skipped because one of the
+ *    following reasons:
+ *          4.1 the device does not support the feature,
+ *          4.2 GPS is disabled in the device,
+ *          4.3 Location is disabled in the device.
+ * 4. Check whether the device is deep indoor. This is done by performing the following steps:
+ *          4.1 If no {@link GpsStatus} is received this will mean that the device is located
+ *              indoor. The test will be skipped.
+ * 5. When the device is not indoor, verify that we receive {@link GnssMeasurementsEvent}s before
+ *    a GPS location is calculated, and reported by GPS HAL. If {@link GnssMeasurementsEvent}s are
+ *    only received after a location update is received:
+ *          4.1.1 The test will pass with a warning for the M release.
+ *          4.1.2 The test might fail in a future Android release, when this requirement becomes
+ *                mandatory.
+ 5. If {@link GnssMeasurementsEvent}s are received: verify all mandatory fields, the test will fail
+    if any of the mandatory fields is not populated or in the expected range.
+ */
+public class GnssMeasurementWhenNoLocationTest extends GnssTestCase {
+
+    private static final String TAG = "GnssMeasWhenNoFixTest";
+    private TestGnssMeasurementListener mMeasurementListener;
+    private TestLocationManager mTestLocationManager;
+    private TestGpsStatusListener mGpsStatusListener;
+    private TestLocationListener mLocationListener;
+    private static final int EVENTS_COUNT = 5;
+    private static final int GPS_RAW_EVENTS_COUNT = 1;
+    // Command to delete cached A-GPS data to get a truer GPS fix.
+    private static final String AGPS_DELETE_COMMAND = "delete_aiding_data";
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        mTestLocationManager = new TestLocationManager(getContext());
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        // Unregister listeners
+        if (mLocationListener != null) {
+            mTestLocationManager.removeLocationUpdates(mLocationListener);
+        }
+        if (mMeasurementListener != null) {
+            mTestLocationManager.unregisterGnssMeasurementCallback(mMeasurementListener);
+        }
+        if (mGpsStatusListener != null) {
+            mTestLocationManager.removeGpsStatusListener(mGpsStatusListener);
+        }
+        super.tearDown();
+    }
+
+    /**
+     * Test GPS measurements without a location fix.
+     */
+    public void testGnssMeasurementWhenNoLocation() throws Exception {
+        if (!TestMeasurementUtil.canTestRunOnCurrentDevice(mTestLocationManager)) {
+            return;
+        }
+
+        // Clear A-GPS and skip the test if the operation fails.
+        if (!mTestLocationManager.sendExtraCommand(AGPS_DELETE_COMMAND)) {
+            Log.i(TAG, "A-GPS failed to clear. Skip test.");
+            return;
+        }
+
+        // Register for GPS measurements.
+        mMeasurementListener = new TestGnssMeasurementListener(TAG, GPS_RAW_EVENTS_COUNT);
+        mTestLocationManager.registerGnssMeasurementCallback(mMeasurementListener);
+
+        // Register for Gps Status updates.
+        mGpsStatusListener = new TestGpsStatusListener(EVENTS_COUNT, mTestLocationManager);
+        mTestLocationManager.addGpsStatusListener(mGpsStatusListener);
+
+        // Register for location updates.
+        mLocationListener = new TestLocationListener(EVENTS_COUNT);
+        mTestLocationManager.requestLocationUpdates(mLocationListener);
+
+        // Wait for Gps Status updates.
+        mGpsStatusListener.await();
+        if (!mMeasurementListener.verifyState()) {
+            return;
+        }
+        if (!mGpsStatusListener.isGpsStatusReceived()) {
+            Log.i(TAG, "No Satellites are visible. Device may be indoors. Skip test.");
+            return;
+        }
+
+        List<GnssMeasurementsEvent> events = mMeasurementListener.getEvents();
+        Log.i(TAG, "Number of GPS measurement events received = " + events.size());
+
+        if (events.isEmpty()) {
+            Log.i(TAG, "No GPS measurement events received. Device may be indoors. Skip test.");
+            return;
+        }
+
+        // If device is not indoor, verify that we receive GPS measurements before being able to
+        // calculate the position solution and verify that mandatory fields of GnssMeasurement are
+        // in expected ranges.
+        GnssMeasurementsEvent firstEvent = events.get(0);
+        Collection<GnssMeasurement> gpsMeasurements = firstEvent.getMeasurements();
+        int satelliteCount = gpsMeasurements.size();
+        int[] gpsPrns = new int[satelliteCount];
+        int i = 0;
+        for (GnssMeasurement measurement : gpsMeasurements) {
+            gpsPrns[i] = measurement.getSvid();
+            ++i;
+        }
+
+        Log.i(TAG, "Gps Measurements 1st Event PRNs=" + Arrays.toString(gpsPrns));
+        SoftAssert softAssert = new SoftAssert(TAG);
+        long timeInNs = firstEvent.getClock().getTimeNanos();
+        softAssert.assertTrue("GPS measurement satellite count not in expected range. ",
+                timeInNs, // event time in ns
+                "satelliteCount > 0", // expected value
+                Integer.toString(satelliteCount), // actual value
+                satelliteCount > 0); // condition
+
+        // TODO: this verification should be enforced for all types of GPS clocks
+        softAssert.assertTrueAsWarning("timeInNs:",
+                timeInNs, // event time in ns
+                "timeInNs > 0", // expected value
+                Long.toString(timeInNs), // actual value
+                timeInNs > 0L); // condition
+
+        // Verify mandatory fields of GnssMeasurement
+        for (GnssMeasurement measurement : gpsMeasurements) {
+            TestMeasurementUtil.assertAllGnssMeasurementMandatoryFields(measurement,
+                    softAssert, timeInNs);
+        }
+        softAssert.assertAll();
+    }
+}
diff --git a/tests/tests/location/src/android/location/cts/GnssMeasurementsEventCallbackTest.java b/tests/tests/location/src/android/location/cts/GnssMeasurementsEventCallbackTest.java
new file mode 100644
index 0000000..b670efb
--- /dev/null
+++ b/tests/tests/location/src/android/location/cts/GnssMeasurementsEventCallbackTest.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.location.cts;
+
+import android.location.GnssClock;
+import android.location.GnssMeasurement;
+import android.location.GnssMeasurementsEvent;
+
+public class GnssMeasurementsEventCallbackTest extends GnssTestCase {
+    private static class MockCallback extends GnssMeasurementsEvent.Callback {
+    }
+
+    public void testAllMethodsExist() {
+        GnssMeasurementsEvent.Callback callback = new MockCallback();
+        GnssClock clock = new GnssClock();
+        GnssMeasurement m1 = new GnssMeasurement();
+        GnssMeasurement m2 = new GnssMeasurement();
+        GnssMeasurementsEvent event = new GnssMeasurementsEvent(
+                clock, new GnssMeasurement[] {m1, m2});
+        callback.onGnssMeasurementsReceived(event);
+        callback.onStatusChanged(GnssMeasurementsEvent.Callback.STATUS_READY);
+    }
+}
diff --git a/tests/tests/location/src/android/location/cts/GnssMeasurementsEventTest.java b/tests/tests/location/src/android/location/cts/GnssMeasurementsEventTest.java
new file mode 100644
index 0000000..06f4e5f
--- /dev/null
+++ b/tests/tests/location/src/android/location/cts/GnssMeasurementsEventTest.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.location.cts;
+
+import android.location.GnssClock;
+import android.location.GnssMeasurement;
+import android.location.GnssMeasurementsEvent;
+import android.location.GnssStatus;
+import android.os.Parcel;
+
+import java.util.Collection;
+import java.util.Iterator;
+
+public class GnssMeasurementsEventTest extends GnssTestCase {
+    public void testDescribeContents() {
+        GnssClock clock = new GnssClock();
+        GnssMeasurement m1 = new GnssMeasurement();
+        GnssMeasurement m2 = new GnssMeasurement();
+        GnssMeasurementsEvent event = new GnssMeasurementsEvent(
+                clock, new GnssMeasurement[] {m1, m2});
+        event.describeContents();
+    }
+
+    public void testWriteToParcel() {
+        GnssClock clock = new GnssClock();
+        clock.setLeapSecond(100);
+        GnssMeasurement m1 = new GnssMeasurement();
+        m1.setConstellationType(GnssStatus.CONSTELLATION_GLONASS);
+        GnssMeasurement m2 = new GnssMeasurement();
+        m2.setReceivedSvTimeNanos(43999);
+        GnssMeasurementsEvent event = new GnssMeasurementsEvent(
+                clock, new GnssMeasurement[] {m1, m2});
+        Parcel parcel = Parcel.obtain();
+        event.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        GnssMeasurementsEvent newEvent = GnssMeasurementsEvent.CREATOR.createFromParcel(parcel);
+        assertEquals(100, newEvent.getClock().getLeapSecond());
+        Collection<GnssMeasurement> measurements = newEvent.getMeasurements();
+        assertEquals(2, measurements.size());
+        Iterator<GnssMeasurement> iterator = measurements.iterator();
+        GnssMeasurement newM1 = iterator.next();
+        assertEquals(GnssStatus.CONSTELLATION_GLONASS, newM1.getConstellationType());
+        GnssMeasurement newM2 = iterator.next();
+        assertEquals(43999, newM2.getReceivedSvTimeNanos());
+    }
+}
diff --git a/tests/tests/location/src/android/location/cts/GnssNavigationMessageCallbackTest.java b/tests/tests/location/src/android/location/cts/GnssNavigationMessageCallbackTest.java
new file mode 100644
index 0000000..842561d
--- /dev/null
+++ b/tests/tests/location/src/android/location/cts/GnssNavigationMessageCallbackTest.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.location.cts;
+
+import android.location.GnssNavigationMessage;
+
+public class GnssNavigationMessageCallbackTest extends GnssTestCase {
+    private static class MockCallback extends GnssNavigationMessage.Callback {
+    }
+
+    public void testAllMethodsExist() {
+        GnssNavigationMessage.Callback callback = new MockCallback();
+        GnssNavigationMessage message = new GnssNavigationMessage();
+        GnssNavigationMessage event = message;
+        callback.onGnssNavigationMessageReceived(event);
+        callback.onStatusChanged(GnssNavigationMessage.Callback.STATUS_READY);
+    }
+}
diff --git a/tests/tests/location/src/android/location/cts/GnssNavigationMessageRegistrationTest.java b/tests/tests/location/src/android/location/cts/GnssNavigationMessageRegistrationTest.java
new file mode 100644
index 0000000..f23f885
--- /dev/null
+++ b/tests/tests/location/src/android/location/cts/GnssNavigationMessageRegistrationTest.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2015 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.location.cts;
+
+import android.location.GnssNavigationMessage;
+import android.util.Log;
+
+import java.util.List;
+
+/**
+ * Test the {@link GnssNavigationMessage} without location registration.
+ *
+ * Test steps:
+ * 1. Register for {@link GnssNavigationMessage}s.
+ * 2. Wait for {@link #EVENTS_COUNT} events to arrive.
+ * 3. Check {@link GnssNavigationMessage} status: if the status is not
+ *    {@link GnssNavigationMessage#Callback#STATUS_READY}, the test will be skipped because one of the
+ *    following reasons:
+ *          3.1 the device does not support the feature,
+ *          3.2 GPS is disabled in the device,
+ *          3.3 Location is disabled in the device.
+ * 4. If at least one {@link GnssNavigationMessage} is received, the test will pass.
+ * 5. If no {@link GnssNavigationMessage}s are received, then check whether the device is
+ *    deep indoor. This is done by performing the following steps:
+ *          2.1 Register for location updates, and {@link GpsStatus} events.
+ *          2.2 Wait for {@link TestGpsStatusListener#TIMEOUT_IN_SEC}.
+ *          2.3 If no {@link GpsStatus} is received this will mean that the device is located
+ *              indoor. Test will be skipped.
+ *          2.4 If we receive a {@link GpsStatus}, it mean that {@link GnssNavigationMessage}s
+ *              are provided only if the application registers for location updates as well:
+ *                  2.4.1 The test will pass with a warning for the M release.
+ *                  2.4.2 The test might fail in a future Android release, when this requirement
+ *                        becomes mandatory.
+ */
+public class GnssNavigationMessageRegistrationTest extends GnssTestCase {
+
+    private static final String TAG = "GpsNavMsgRegTest";
+    private TestLocationManager mTestLocationManager;
+    private static final int EVENTS_COUNT = 5;
+    private TestGnssNavigationMessageListener mTestGnssNavigationMessageListener;
+    private TestLocationListener mLocationListener;
+    private TestGpsStatusListener mGpsStatusListener;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mTestLocationManager = new TestLocationManager(getContext());
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        // Unregister GnssNavigationMessageListener
+        if (mTestGnssNavigationMessageListener != null) {
+            mTestLocationManager
+                    .unregisterGnssNavigationMessageCallback(mTestGnssNavigationMessageListener);
+            mTestGnssNavigationMessageListener = null;
+        }
+        if (mLocationListener != null) {
+            mTestLocationManager.removeLocationUpdates(mLocationListener);
+        }
+        if (mGpsStatusListener != null) {
+            mTestLocationManager.removeGpsStatusListener(mGpsStatusListener);
+        }
+        super.tearDown();
+    }
+
+    /**
+     * Tests that one can listen for {@link GnssNavigationMessage}s for collection purposes.
+     * It only performs sanity checks for the Navigation messages received.
+     */
+    public void testGnssNavigationMessageRegistration() throws Exception {
+        if (!TestMeasurementUtil.canTestRunOnCurrentDevice(mTestLocationManager)) {
+            return;
+        }
+
+        // Register Gps Navigation Message Listener.
+        mTestGnssNavigationMessageListener =
+                new TestGnssNavigationMessageListener(TAG, EVENTS_COUNT);
+        mTestLocationManager.registerGnssNavigationMessageCallback(mTestGnssNavigationMessageListener);
+
+        mTestGnssNavigationMessageListener.await();
+        if (!mTestGnssNavigationMessageListener.verifyState()) {
+            return;
+        }
+
+        List<GnssNavigationMessage> events = mTestGnssNavigationMessageListener.getEvents();
+        if (!events.isEmpty()) {
+            // Verify mandatory GnssNavigationMessage field values.
+            TestMeasurementUtil.verifyGnssNavMessageMandatoryField(events);
+            // Test passes if we get at least 1 GPS Navigation Message event.
+            Log.i(TAG, "Received GPS Navigation Message. Test Pass.");
+            return;
+        }
+
+        // If no {@link GnssNavigationMessage}s are received, then check whether the device is
+        // deep indoor.
+        Log.i(TAG, "Did not receive any GPS Navigation Message. Test if device is deep indoor.");
+
+        // Register for location updates.
+        mLocationListener = new TestLocationListener(EVENTS_COUNT);
+        mTestLocationManager.requestLocationUpdates(mLocationListener);
+
+        // Wait for location updates
+        mLocationListener.await();
+        Log.i(TAG, "Location received = " + mLocationListener.isLocationReceived());
+
+        // Register for Gps Status updates
+        mGpsStatusListener = new TestGpsStatusListener(EVENTS_COUNT, mTestLocationManager);
+        mTestLocationManager.addGpsStatusListener(mGpsStatusListener);
+
+        // Wait for Gps Status updates
+        mGpsStatusListener.await();
+        if (!mGpsStatusListener.isGpsStatusReceived()) {
+            // Skip the Test. No Satellites are visible. Device may be Indoor
+            Log.i(TAG, "No Satellites are visible. Device may be Indoor. Skipping Test.");
+            return;
+        }
+
+        SoftAssert.failAsWarning(
+                TAG,
+                "GPS Navigation Messages were not received without registering for location" +
+                        " updates.");
+    }
+}
diff --git a/tests/tests/location/src/android/location/cts/GnssNavigationMessageTest.java b/tests/tests/location/src/android/location/cts/GnssNavigationMessageTest.java
new file mode 100644
index 0000000..9082dc8
--- /dev/null
+++ b/tests/tests/location/src/android/location/cts/GnssNavigationMessageTest.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2015 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.location.cts;
+
+import android.location.GnssNavigationMessage;
+import android.os.Parcel;
+import android.util.Log;
+
+import java.util.List;
+
+/**
+ * Test the {@link GnssNavigationMessage} values.
+ *
+ * Test steps:
+ * 1. Register for {@link GnssNavigationMessage}s.
+ * 2. Wait for {@link #EVENTS_COUNT} events to arrive.
+ * 3. Check {@link GnssNavigationMessage} status: if the status is not
+ *    {@link GnssNavigationMessage.Callback#STATUS_READY}, the test will be skipped because one of the
+ *    following reasons:
+ *          3.1 the device does not support the feature,
+ *          3.2 GPS is disabled in the device,
+ *          3.3 Location is disabled in the device.
+ * 4. Verify {@link GnssNavigationMessage}s (all mandatory fields), the test will fail if any of the
+ *    mandatory fields is not populated or in the expected range.
+ */
+public class GnssNavigationMessageTest extends GnssTestCase {
+
+    private static final String TAG = "GpsNavMsgTest";
+    private TestLocationManager mTestLocationManager;
+    private static final int EVENTS_COUNT = 5;
+    private TestGnssNavigationMessageListener mTestGnssNavigationMessageListener;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mTestLocationManager = new TestLocationManager(getContext());
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        // Unregister GnssNavigationMessageListener
+        if (mTestGnssNavigationMessageListener != null) {
+            mTestLocationManager
+                    .unregisterGnssNavigationMessageCallback(mTestGnssNavigationMessageListener);
+            mTestGnssNavigationMessageListener = null;
+        }
+        super.tearDown();
+    }
+
+    /**
+     * Tests that one can listen for {@link GnssNavigationMessage}s for collection purposes.
+     * It only performs sanity checks for the Navigation messages received.
+     * This tests uses actual data retrieved from GPS HAL.
+     */
+    public void testGnssNavigationMessageMandatoryFieldRanges() throws Exception {
+        if (!TestMeasurementUtil.canTestRunOnCurrentDevice(mTestLocationManager)) {
+            return;
+        }
+
+        // Register Gps Navigation Message Listener.
+        mTestGnssNavigationMessageListener =
+                new TestGnssNavigationMessageListener(TAG, EVENTS_COUNT);
+        mTestLocationManager.registerGnssNavigationMessageCallback(mTestGnssNavigationMessageListener);
+
+        mTestGnssNavigationMessageListener.await();
+        if (!mTestGnssNavigationMessageListener.verifyState()) {
+            return;
+        }
+
+        List<GnssNavigationMessage> events = mTestGnssNavigationMessageListener.getEvents();
+        assertTrue("No Gps Navigation Message received.", !events.isEmpty());
+
+        // Verify mandatory GnssNavigationMessage field values.
+        TestMeasurementUtil.verifyGnssNavMessageMandatoryField(events);
+    }
+
+    private static void setTestValues(GnssNavigationMessage message) {
+        message.setData(new byte[] {1, 2, 3, 4});
+        message.setMessageId(5);
+        message.setStatus(GnssNavigationMessage.STATUS_PARITY_REBUILT);
+        message.setSubmessageId(6);
+        message.setSvid(7);
+        message.setType(GnssNavigationMessage.TYPE_GPS_L2CNAV);
+    }
+
+    private static void verifyTestValues(GnssNavigationMessage message) {
+        byte[] data = message.getData();
+        assertEquals(4, data.length);
+        assertEquals(1, data[0]);
+        assertEquals(2, data[1]);
+        assertEquals(3, data[2]);
+        assertEquals(4, data[3]);
+        assertEquals(5, message.getMessageId());
+        assertEquals(GnssNavigationMessage.STATUS_PARITY_REBUILT, message.getStatus());
+        assertEquals(6, message.getSubmessageId());
+        assertEquals(7, message.getSvid());
+        assertEquals(GnssNavigationMessage.TYPE_GPS_L2CNAV, message.getType());
+    }
+
+    public void testDescribeContents() {
+        GnssNavigationMessage message = new GnssNavigationMessage();
+        message.describeContents();
+    }
+
+    public void testWriteToParcel() {
+        GnssNavigationMessage message = new GnssNavigationMessage();
+        setTestValues(message);
+        Parcel parcel = Parcel.obtain();
+        message.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        GnssNavigationMessage newMessage =
+                GnssNavigationMessage.CREATOR.createFromParcel(parcel);
+        verifyTestValues(newMessage);
+    }
+
+    public void testReset() {
+        GnssNavigationMessage message = new GnssNavigationMessage();
+        message.reset();
+    }
+
+    public void testSet() {
+        GnssNavigationMessage message = new GnssNavigationMessage();
+        setTestValues(message);
+        GnssNavigationMessage newMessage = new GnssNavigationMessage();
+        newMessage.set(message);
+        verifyTestValues(newMessage);
+    }
+}
diff --git a/tests/tests/location/src/android/location/cts/GnssStatusCallbackTest.java b/tests/tests/location/src/android/location/cts/GnssStatusCallbackTest.java
new file mode 100644
index 0000000..b785e1a
--- /dev/null
+++ b/tests/tests/location/src/android/location/cts/GnssStatusCallbackTest.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.location.cts;
+
+import android.location.GnssStatus;
+
+public class GnssStatusCallbackTest extends GnssTestCase {
+    private static class MockCallback extends GnssStatus.Callback {
+    }
+
+    public void testAllMethodsExist() {
+        GnssStatus.Callback callback = new MockCallback();
+        callback.onStarted();
+        callback.onFirstFix(10);
+        callback.onSatelliteStatusChanged(null);
+        callback.onStopped();
+    }
+}
diff --git a/tests/tests/location/src/android/location/cts/GnssTestCase.java b/tests/tests/location/src/android/location/cts/GnssTestCase.java
new file mode 100644
index 0000000..35d8226
--- /dev/null
+++ b/tests/tests/location/src/android/location/cts/GnssTestCase.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.location.cts;
+
+import android.test.AndroidTestCase;
+
+/**
+ * Base Test Case class for all Gnss Tests.
+ */
+public abstract class GnssTestCase extends AndroidTestCase {
+    protected GnssTestCase() {}
+}
\ No newline at end of file
diff --git a/tests/tests/location/src/android/location/cts/LocationManagerTest.java b/tests/tests/location/src/android/location/cts/LocationManagerTest.java
index 8ac56ae..7fcc2aa 100644
--- a/tests/tests/location/src/android/location/cts/LocationManagerTest.java
+++ b/tests/tests/location/src/android/location/cts/LocationManagerTest.java
@@ -24,6 +24,7 @@
 import android.content.IntentFilter;
 import android.content.pm.PackageManager;
 import android.location.Criteria;
+import android.location.GnssStatus;
 import android.location.GpsStatus;
 import android.location.GpsStatus.Listener;
 import android.location.GpsStatus.NmeaListener;
@@ -31,7 +32,9 @@
 import android.location.LocationListener;
 import android.location.LocationManager;
 import android.location.LocationProvider;
+import android.location.OnNmeaMessageListener;
 import android.os.Bundle;
+import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.Looper;
 import android.os.SystemClock;
@@ -473,7 +476,7 @@
         }
 
         try {
-            mManager.removeUpdates( (LocationListener) null );
+            mManager.removeUpdates((LocationListener) null );
             fail("Should throw IllegalArgumentException if listener is null!");
         } catch (IllegalArgumentException e) {
             // expected
@@ -563,6 +566,13 @@
         assertFalse(listener.hasCalledOnLocationChanged(TEST_TIME_OUT));
 
         try {
+            mManager.requestSingleUpdate(LocationManager.GPS_PROVIDER, mPendingIntent);
+            fail("Should throw IllegalArgumentException if PendingIntent is null!");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+
+        try {
             mManager.requestSingleUpdate(LocationManager.GPS_PROVIDER, (LocationListener) null,
                     Looper.myLooper());
             fail("Should throw IllegalArgumentException if param listener is null!");
@@ -578,7 +588,7 @@
         }
 
         try {
-            mManager.removeUpdates( (LocationListener) null );
+            mManager.removeUpdates((LocationListener) null );
             fail("Should throw IllegalArgumentException if listener is null!");
         } catch (IllegalArgumentException e) {
             // expected
@@ -897,8 +907,20 @@
         mManager.addNmeaListener(listener);
         mManager.removeNmeaListener(listener);
 
-        mManager.addNmeaListener(null);
-        mManager.removeNmeaListener(null);
+        mManager.addNmeaListener((NmeaListener) null);
+        mManager.removeNmeaListener((NmeaListener) null);
+
+        MockGnssNmeaListener gnssListener = new MockGnssNmeaListener();
+        mManager.addNmeaListener(gnssListener);
+        mManager.removeNmeaListener(gnssListener);
+
+        HandlerThread handlerThread = new HandlerThread("testNmeaListener");
+        handlerThread.start();
+        mManager.addNmeaListener(gnssListener, new Handler(handlerThread.getLooper()));
+        mManager.removeNmeaListener(gnssListener);
+
+        mManager.addNmeaListener((OnNmeaMessageListener) null);
+        mManager.removeNmeaListener((OnNmeaMessageListener) null);
     }
 
     public void testIsProviderEnabled() {
@@ -987,6 +1009,22 @@
         assertSame(status, mManager.getGpsStatus(status));
     }
 
+    @UiThreadTest
+    public void testGnssStatusListener() {
+        MockGnssStatusCallback callback = new MockGnssStatusCallback();
+        mManager.registerGnssStatusCallback(callback);
+        mManager.unregisterGnssStatusCallback(callback);
+
+        mManager.registerGnssStatusCallback(null);
+        mManager.unregisterGnssStatusCallback(null);
+
+        HandlerThread handlerThread = new HandlerThread("testStatusUpdates");
+        handlerThread.start();
+
+        mManager.registerGnssStatusCallback(callback, new Handler(handlerThread.getLooper()));
+        mManager.unregisterGnssStatusCallback(callback);
+    }
+
     public void testSendExtraCommand() {
         // this test assumes TEST_MOCK_PROVIDER_NAME was created in setUp.
         assertNotNull(mManager.getProvider(TEST_MOCK_PROVIDER_NAME));
@@ -1390,6 +1428,23 @@
         }
     }
 
+    private static class MockGnssNmeaListener implements OnNmeaMessageListener {
+        private boolean mIsNmeaReceived;
+
+        @Override
+        public void onNmeaMessage(String name, long timestamp) {
+            mIsNmeaReceived = true;
+        }
+
+        public boolean isNmeaRecevied() {
+            return mIsNmeaReceived;
+        }
+
+        public void reset() {
+            mIsNmeaReceived = false;
+        }
+    }
+
     private static class MockGpsStatusListener implements Listener {
         private boolean mHasCallOnGpsStatusChanged;
 
@@ -1405,4 +1460,20 @@
             mHasCallOnGpsStatusChanged = true;
         }
     }
+
+    private static class MockGnssStatusCallback extends GnssStatus.Callback {
+        @Override
+        public void onSatelliteStatusChanged(GnssStatus status) {
+            for (int i = 0; i < status.getSatelliteCount(); ++i) {
+                status.getAzimuthDegrees(i);
+                status.getCn0DbHz(i);
+                status.getConstellationType(i);
+                status.getElevationDegrees(i);
+                status.getSvid(i);
+                status.hasAlmanacData(i);
+                status.hasEphemerisData(i);
+                status.usedInFix(i);
+            }
+        }
+    }
 }
diff --git a/tests/tests/location/src/android/location/cts/LocationTest.java b/tests/tests/location/src/android/location/cts/LocationTest.java
index db2820c..18faaee 100644
--- a/tests/tests/location/src/android/location/cts/LocationTest.java
+++ b/tests/tests/location/src/android/location/cts/LocationTest.java
@@ -377,6 +377,19 @@
         assertEquals(12000, location.getTime());
     }
 
+    public void testAccessElapsedRealtime() {
+        Location location = new Location("");
+
+        location.setElapsedRealtimeNanos(0);
+        assertEquals(0, location.getElapsedRealtimeNanos());
+
+        location.setElapsedRealtimeNanos(Long.MAX_VALUE);
+        assertEquals(Long.MAX_VALUE, location.getElapsedRealtimeNanos());
+
+        location.setElapsedRealtimeNanos(12000);
+        assertEquals(12000, location.getElapsedRealtimeNanos());
+    }
+
     public void testSet() {
         Location location = new Location("");
 
@@ -453,6 +466,8 @@
 
         // enabled == true case
         service.setEnabled(true);
+        assertTrue(service.onGetEnabled());
+        assertEquals("Summary", service.onGetSummary());
         resultHandler.expectEnabled(true);
         resultHandler.expectMessage(true);
         ret = service.callOnStartCommand(intent, SettingInjectorService.START_NOT_STICKY, 0);
@@ -563,7 +578,7 @@
         @Override
         // Deprecated API
         protected String onGetSummary() {
-            return "";
+            return "Summary";
         }
 
         @Override
@@ -575,7 +590,7 @@
             mEnabled = enabled;
         }
 
-        // API coverage dashboard will not cound method call from derived class.
+        // API coverage dashboard will not count method call from derived class.
         // Thus, it is necessary to make explicit call to SettingInjectorService public methods.
         public IBinder callOnBind(Intent intent) {
             return super.onBind(intent);
diff --git a/tests/tests/location/src/android/location/cts/SoftAssert.java b/tests/tests/location/src/android/location/cts/SoftAssert.java
new file mode 100644
index 0000000..0867bcae
--- /dev/null
+++ b/tests/tests/location/src/android/location/cts/SoftAssert.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2015 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.location.cts;
+
+import junit.framework.Assert;
+
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Custom Assertion class. This is useful for doing multiple validations together
+ * without failing the test. Tests don’t stop running even if an assertion condition fails,
+ * but the test itself is marked as a failed test to indicate the right result
+ * at the end of the test.
+ */
+public class SoftAssert {
+
+    List<String> mErrorList;
+    private String mTag;
+
+    SoftAssert(String source) {
+        mErrorList = new ArrayList<>();
+        mTag = source;
+    }
+
+    /**
+     * Check if condition is true
+     *
+     * @param message test message
+     * @param eventTimeInNs the time at which the condition occurred
+     * @param expectedResult expected value
+     * @param actualResult actual value
+     * @param condition condition for test
+     */
+    public void assertTrue(String message, long eventTimeInNs, String expectedResult,
+                           String actualResult, boolean condition) {
+        if (condition) {
+            Log.i(mTag, message + ", (Test: PASS, actual : " +
+                    actualResult + ", expected: " + expectedResult + ")");
+        } else {
+            String errorMessage = "At time = " + eventTimeInNs + " ns, " + message +
+                    " (Test: FAIL, actual :" + actualResult + ", " +
+                    "expected: " + expectedResult + ")";
+            Log.e(mTag, errorMessage);
+            mErrorList.add(errorMessage);
+        }
+    }
+
+    /**
+     * Check if a condition is true.
+     * NOTE: A failure is downgraded to a warning.
+     *
+     * @param message the message associated with the condition
+     * @param eventTimeInNs the time at which the condition occurred
+     * @param expectedResult the expected result of the condition
+     * @param actualResult the actual result of the condition
+     * @param condition the condition status
+     */
+    public void assertTrueAsWarning(
+            String message,
+            long eventTimeInNs,
+            String expectedResult,
+            String actualResult,
+            boolean condition) {
+        if (condition) {
+            String formattedMessage = String.format(
+                    "%s, (Test: PASS, actual : %s, expected : %s)",
+                    message,
+                    actualResult,
+                    expectedResult);
+            Log.i(mTag, formattedMessage);
+        } else {
+            String formattedMessage = String.format(
+                    "At time = %d ns, %s (Test: WARNING, actual : %s, expected : %s).",
+                    eventTimeInNs,
+                    message,
+                    actualResult,
+                    expectedResult);
+            failAsWarning(mTag, formattedMessage);
+        }
+    }
+
+    /**
+     * Check if condition is true
+     *
+     * @param message    test message
+     * @param condition  condition for test
+     */
+    public void assertTrue(String message, boolean condition) {
+        if (condition) {
+            Log.i(mTag, "(Test: PASS) " + message);
+        } else {
+            String errorMessage = "(Test: FAIL) " + message;
+            Log.i(mTag, errorMessage);
+            mErrorList.add(errorMessage);
+        }
+    }
+
+    /**
+     * Assert all conditions together. This method collates all the failures and decides
+     * whether to fail the test or not at the end. This must be called at the end of the test.
+     */
+    public void assertAll() {
+        if (mErrorList.isEmpty()) {
+            Log.i(mTag, "All test pass.");
+            // Test pass if there are no error message in errorMessageSet
+            Assert.assertTrue(true);
+        } else {
+            StringBuilder message = new StringBuilder();
+            for (String msg : mErrorList) {
+                message.append(msg + "\n");
+            }
+            Log.e(mTag, "Failing tests are: \n" + message);
+            Assert.fail("Failing tests are: \n" + message);
+        }
+    }
+
+    /**
+     * A soft failure. In the current state of the tests, it will only log a warning and let the
+     * test be reported as 'pass'.
+     */
+    public static void failAsWarning(String tag, String message) {
+        Log.w(tag, message + " [NOTE: in a future release this feature might become mandatory, and"
+                + " this warning will fail the test].");
+    }
+}
diff --git a/tests/tests/location/src/android/location/cts/TestGnssMeasurementListener.java b/tests/tests/location/src/android/location/cts/TestGnssMeasurementListener.java
new file mode 100644
index 0000000..154cff6
--- /dev/null
+++ b/tests/tests/location/src/android/location/cts/TestGnssMeasurementListener.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2015 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.location.cts;
+
+import junit.framework.Assert;
+
+import android.location.GnssMeasurementsEvent;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Used for receiving GPS satellite measurements from the GPS engine.
+ * Each measurement contains raw and computed data identifying a satellite.
+ */
+class TestGnssMeasurementListener extends GnssMeasurementsEvent.Callback {
+    // Timeout in sec for count down latch wait
+    private static final int TIMEOUT_IN_SEC = 90;
+
+    private volatile int mStatus = -1;
+
+    private final String mTag;
+    private final int mEventsToCollect;
+    private final List<GnssMeasurementsEvent> mMeasurementsEvents;
+    private final CountDownLatch mCountDownLatch;
+
+    TestGnssMeasurementListener(String tag) {
+        this(tag, 0);
+    }
+
+    TestGnssMeasurementListener(String tag, int eventsToCollect) {
+        mTag = tag;
+        mCountDownLatch = new CountDownLatch(eventsToCollect);
+        mEventsToCollect = eventsToCollect;
+        mMeasurementsEvents = new ArrayList<>(eventsToCollect);
+    }
+
+    @Override
+    public void onGnssMeasurementsReceived(GnssMeasurementsEvent event) {
+        mMeasurementsEvents.add(event);
+        if (mMeasurementsEvents.size() >= mEventsToCollect) {
+            mCountDownLatch.countDown();
+        }
+    }
+
+    @Override
+    public void onStatusChanged(int status) {
+        mStatus = status;
+        if (mStatus != GnssMeasurementsEvent.Callback.STATUS_READY) {
+            mCountDownLatch.countDown();
+        }
+    }
+
+    public boolean await() throws InterruptedException {
+        return TestUtils.waitFor(mCountDownLatch);
+    }
+
+    /**
+     * @return {@code true} if the state of the test ensures that data is expected to be collected,
+     *         {@code false} otherwise.
+     */
+    public boolean verifyState() {
+        switch (getStatus()) {
+            case GnssMeasurementsEvent.Callback.STATUS_NOT_SUPPORTED:
+                SoftAssert.failAsWarning(mTag, "GnssMeasurements is not supported in the device:"
+                        + " verifications performed by this test will be skipped.");
+                return false;
+            case GnssMeasurementsEvent.Callback.STATUS_READY:
+                return true;
+            case GnssMeasurementsEvent.Callback.STATUS_LOCATION_DISABLED:
+                Log.i(mTag, "Location or GPS is disabled on the device: skipping the test.");
+                return false;
+            default:
+                Assert.fail("GnssMeasurementsEvent status callback was not received.");
+        }
+        return false;
+    }
+
+    /**
+     * Get GPS Measurements Status.
+     *
+     * @return mStatus Gps Measurements Status
+     */
+    public int getStatus() {
+        return mStatus;
+    }
+
+    /**
+     * Get list of GPS Measurements Events.
+     *
+     * @return mMeasurementsEvents list of GPS Measurements Events
+     */
+    public List<GnssMeasurementsEvent> getEvents() {
+        return mMeasurementsEvents;
+    }
+}
diff --git a/tests/tests/location/src/android/location/cts/TestGnssNavigationMessageListener.java b/tests/tests/location/src/android/location/cts/TestGnssNavigationMessageListener.java
new file mode 100644
index 0000000..3765f3c
--- /dev/null
+++ b/tests/tests/location/src/android/location/cts/TestGnssNavigationMessageListener.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2015 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.location.cts;
+
+import junit.framework.Assert;
+
+import android.location.GnssNavigationMessage;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Used for receiving GPS satellite Navigation Messages from the GPS engine.
+ */
+class TestGnssNavigationMessageListener extends GnssNavigationMessage.Callback {
+
+    // Timeout in sec for count down latch wait
+    private static final long TIMEOUT_IN_SEC = 90L;
+
+    private volatile int mStatus = -1;
+
+    private final String mTag;
+    private final int mEventsToCollect;
+    private final List<GnssNavigationMessage> mEvents;
+    private final CountDownLatch mCountDownLatch;
+
+    TestGnssNavigationMessageListener(String tag, int eventsToCollect) {
+        mTag = tag;
+        mCountDownLatch = new CountDownLatch(1);
+        mEventsToCollect = eventsToCollect;
+        mEvents = new ArrayList<>(eventsToCollect);
+    }
+
+    @Override
+    public void onGnssNavigationMessageReceived(GnssNavigationMessage event) {
+        mEvents.add(event);
+        if (mEvents.size() > mEventsToCollect) {
+            mCountDownLatch.countDown();
+        }
+    }
+
+    @Override
+    public void onStatusChanged(int status) {
+        mStatus = status;
+        if (mStatus != GnssNavigationMessage.Callback.STATUS_READY) {
+            mCountDownLatch.countDown();
+        }
+    }
+
+    public boolean await() throws InterruptedException {
+        Log.i(mTag, "Number of GPS Navigation Message received = " + getEvents().size());
+        return TestUtils.waitFor(mCountDownLatch);
+    }
+
+    /**
+     * Get GPS Navigation Message Status.
+     *
+     * @return mStatus Gps Navigation Message Status
+     */
+    public int getStatus() {
+        return mStatus;
+    }
+
+    /**
+     * @return {@code true} if the state of the test ensures that data is expected to be collected,
+     *         {@code false} otherwise.
+     */
+    public boolean verifyState() {
+        switch (getStatus()) {
+            case GnssNavigationMessage.Callback.STATUS_NOT_SUPPORTED:
+                SoftAssert.failAsWarning(mTag, "GnssNavigationMessage is not supported in the"
+                        + " device: verifications performed by this test will be skipped.");
+                return false;
+            case GnssNavigationMessage.Callback.STATUS_READY:
+                return true;
+            case GnssNavigationMessage.Callback.STATUS_LOCATION_DISABLED:
+                Log.i(mTag, "Location or GPS is disabled on the device: skipping the test.");
+                return false;
+            default:
+                Assert.fail("GnssNavigationMessage status callback was not received.");
+        }
+        return false;
+    }
+
+    /**
+     * Get list of GPS Navigation Message Events.
+     *
+     * @return mEvents list of GPS Navigation Message Events
+     */
+    public List<GnssNavigationMessage> getEvents() {
+        return mEvents;
+    }
+}
diff --git a/tests/tests/location/src/android/location/cts/TestGnssStatusCallback.java b/tests/tests/location/src/android/location/cts/TestGnssStatusCallback.java
new file mode 100644
index 0000000..b5e102e
--- /dev/null
+++ b/tests/tests/location/src/android/location/cts/TestGnssStatusCallback.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2016 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.location.cts;
+
+import android.location.GnssStatus;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Used for receiving notifications when GNSS status has changed.
+ */
+class TestGnssStatusCallback extends GnssStatus.Callback {
+
+    private volatile boolean mGpsStatusReceived;
+    private GnssStatus mGnssStatus = null;
+    // Timeout in sec for count down latch wait
+    private static final int TIMEOUT_IN_SEC = 90;
+    private final CountDownLatch mCountDownLatch;
+    // Store list of Prn for Satellites.
+    private List<List<Integer>> mGpsSatellitePrns;
+
+    TestGnssStatusCallback(int gpsStatusCountToCollect) {
+        mCountDownLatch = new CountDownLatch(gpsStatusCountToCollect);
+        mGpsSatellitePrns = new ArrayList<List<Integer>>();
+    }
+
+    @Override
+    public void onStarted() {
+    }
+
+    @Override
+    public void onStopped() {
+    }
+
+    @Override
+    public void onFirstFix(int ttffMillis) {
+    }
+
+    @Override
+    public void onSatelliteStatusChanged(GnssStatus status) {
+        mCountDownLatch.countDown();
+    }
+
+    /**
+     * Returns the list of PRNs (pseudo-random number) for the satellite.
+     *
+     * @return list of PRNs number
+     */
+    public List<List<Integer>> getGpsSatellitePrns() {
+        return mGpsSatellitePrns;
+    }
+
+    /**
+     * Check if GPS Status is received.
+     *
+     * @return {@code true} if the GPS Status is received and {@code false}
+     *         if GPS Status is not received.
+     */
+    public boolean isGpsStatusReceived() {
+        return mGpsStatusReceived;
+    }
+
+    /**
+     * Get GPS Status.
+     *
+     * @return mGpsStatus GPS Status
+     */
+    public GnssStatus getGnssStatus() {
+        return mGnssStatus;
+    }
+
+    public boolean await() throws InterruptedException {
+        return TestUtils.waitFor(mCountDownLatch);
+    }
+}
diff --git a/tests/tests/location/src/android/location/cts/TestGpsStatusListener.java b/tests/tests/location/src/android/location/cts/TestGpsStatusListener.java
new file mode 100644
index 0000000..7f2b6d3c
--- /dev/null
+++ b/tests/tests/location/src/android/location/cts/TestGpsStatusListener.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2015 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.location.cts;
+
+import android.location.GpsSatellite;
+import android.location.GpsStatus;
+import android.location.LocationManager;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Used for receiving notifications when GPS status has changed.
+ */
+class TestGpsStatusListener implements GpsStatus.Listener {
+
+    private volatile boolean mGpsStatusReceived;
+    private GpsStatus mGpsStatus = null;
+    // Timeout in sec for count down latch wait
+    private static final int TIMEOUT_IN_SEC = 90;
+    private final CountDownLatch mCountDownLatch;
+    private final LocationManager mLocationManager;
+    // Store list of Prn for Satellites.
+    private List<List<Integer>> mGpsSatellitePrns;
+
+    TestGpsStatusListener(int gpsStatusCountToCollect, TestLocationManager testLocationManager) {
+        mCountDownLatch = new CountDownLatch(gpsStatusCountToCollect);
+        mLocationManager = testLocationManager.getLocationManager();
+        mGpsSatellitePrns = new ArrayList<List<Integer>>();
+    }
+
+    @Override
+    public void onGpsStatusChanged(int event) {
+        if (event == GpsStatus.GPS_EVENT_SATELLITE_STATUS) {
+            mGpsStatus = mLocationManager.getGpsStatus(mGpsStatus);
+            Iterable<GpsSatellite> satellites = mGpsStatus.getSatellites();
+            List<Integer> prns = new ArrayList<Integer>();
+            for (GpsSatellite gpsSatellite : satellites) {
+                prns.add(gpsSatellite.getPrn());
+            }
+            mGpsSatellitePrns.add(prns);
+            if (!mGpsSatellitePrns.isEmpty()) {
+                mGpsStatusReceived = true;
+                mCountDownLatch.countDown();
+            }
+        }
+    }
+
+    /**
+     * Returns the list of PRNs (pseudo-random number) for the satellite.
+     *
+     * @return list of PRNs number
+     */
+    public List<List<Integer>> getGpsSatellitePrns() {
+        return mGpsSatellitePrns;
+    }
+
+    /**
+     * Check if GPS Status is received.
+     *
+     * @return {@code true} if the GPS Status is received and {@code false}
+     *         if GPS Status is not received.
+     */
+    public boolean isGpsStatusReceived() {
+        return mGpsStatusReceived;
+    }
+
+    /**
+     * Get GPS Status.
+     *
+     * @return mGpsStatus GPS Status
+     */
+    public GpsStatus getGpsStatus() {
+        return mGpsStatus;
+    }
+
+    public boolean await() throws InterruptedException {
+        return TestUtils.waitFor(mCountDownLatch);
+    }
+}
diff --git a/tests/tests/location/src/android/location/cts/TestLocationListener.java b/tests/tests/location/src/android/location/cts/TestLocationListener.java
new file mode 100644
index 0000000..7681ec4
--- /dev/null
+++ b/tests/tests/location/src/android/location/cts/TestLocationListener.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2015 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.location.cts;
+
+import android.location.Location;
+import android.location.LocationListener;
+import android.location.LocationManager;
+import android.os.Bundle;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Used for receiving notifications from the LocationManager when the location has changed.
+ */
+class TestLocationListener implements LocationListener {
+    private volatile boolean mProviderEnabled;
+    private volatile boolean mLocationReceived;
+    // Timeout in sec for count down latch wait
+    private static final int TIMEOUT_IN_SEC = 300;
+    private final CountDownLatch mCountDownLatch;
+
+    TestLocationListener(int locationToCollect) {
+        mCountDownLatch = new CountDownLatch(locationToCollect);
+    }
+
+    @Override
+    public void onLocationChanged(Location location) {
+        mLocationReceived = true;
+        mCountDownLatch.countDown();
+    }
+
+    @Override
+    public void onStatusChanged(String s, int i, Bundle bundle) {
+    }
+
+    @Override
+    public void onProviderEnabled(String s) {
+        if (LocationManager.GPS_PROVIDER.equals(s)) {
+            mProviderEnabled = true;
+        }
+    }
+
+    @Override
+    public void onProviderDisabled(String s) {
+        if (LocationManager.GPS_PROVIDER.equals(s)) {
+            mProviderEnabled = false;
+        }
+    }
+
+    public boolean await() throws InterruptedException {
+        return TestUtils.waitFor(mCountDownLatch);
+    }
+
+    /**
+     * Check if location provider is enabled.
+     *
+     * @return {@code true} if the location provider is enabled and {@code false}
+     *         if location provider is disabled.
+     */
+    public boolean isProviderEnabled() {
+        return mProviderEnabled;
+    }
+
+    /**
+     * Check if the location is received.
+     *
+     * @return {@code true} if the location is received and {@code false}
+     *         if location is not received.
+     */
+    public boolean isLocationReceived() {
+        return mLocationReceived;
+    }
+}
diff --git a/tests/tests/location/src/android/location/cts/TestLocationManager.java b/tests/tests/location/src/android/location/cts/TestLocationManager.java
new file mode 100644
index 0000000..28068a0
--- /dev/null
+++ b/tests/tests/location/src/android/location/cts/TestLocationManager.java
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2015 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.location.cts;
+
+import android.content.Context;
+import android.location.GnssMeasurementsEvent;
+import android.location.GnssNavigationMessage;
+import android.location.GpsStatus;
+import android.location.LocationListener;
+import android.location.LocationManager;
+import android.os.Handler;
+import android.os.Looper;
+import android.util.Log;
+
+import junit.framework.Assert;
+
+/**
+ * A {@code LocationManager} wrapper that logs GNSS turn-on and turn-off.
+ */
+public class TestLocationManager {
+
+    private static final String TAG = "TestLocationManager";
+    private LocationManager mLocationManager;
+
+    public TestLocationManager(Context mContext) {
+        mLocationManager =
+                (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
+    }
+
+    /**
+     * See {@code LocationManager#removeUpdates(LocationListener)}.
+     *
+     * @param listener the listener to remove
+     */
+    public void removeLocationUpdates(LocationListener listener) {
+        Log.i(TAG, "Remove Location updates.");
+        mLocationManager.removeUpdates(listener);
+    }
+
+    /**
+     * See {@link android.location.LocationManager#registerGnssMeasurementsCallback
+     * (GnssMeasurementsEvent.Callback callback)}
+     *
+     * @param callback the listener to add
+     */
+    public void registerGnssMeasurementCallback(GnssMeasurementsEvent.Callback callback) {
+        Log.i(TAG, "Add Gnss Measurement Callback.");
+        boolean measurementListenerAdded =
+                mLocationManager.registerGnssMeasurementsCallback(callback);
+        if (!measurementListenerAdded) {
+            // Registration of GnssMeasurements listener has failed, this indicates a platform bug.
+            Log.i(TAG, TestMeasurementUtil.REGISTRATION_ERROR_MESSAGE);
+            Assert.fail(TestMeasurementUtil.REGISTRATION_ERROR_MESSAGE);
+        }
+    }
+
+    /**
+     * See {@link android.location.LocationManager#registerGnssMeasurementsCallback(GnssMeasurementsEvent.Callback callback)}
+     *
+     * @param callback the listener to add
+     * @param handler the handler that the callback runs at.
+     */
+    public void registerGnssMeasurementCallback(GnssMeasurementsEvent.Callback callback,
+            Handler handler) {
+        Log.i(TAG, "Add Gnss Measurement Callback.");
+        boolean measurementListenerAdded =
+                mLocationManager.registerGnssMeasurementsCallback(callback, handler);
+        if (!measurementListenerAdded) {
+            // Registration of GnssMeasurements listener has failed, this indicates a platform bug.
+            Log.i(TAG, TestMeasurementUtil.REGISTRATION_ERROR_MESSAGE);
+            Assert.fail(TestMeasurementUtil.REGISTRATION_ERROR_MESSAGE);
+        }
+    }
+
+    /**
+     * See {@link android.location.LocationManager#unregisterGnssMeasurementsCallback
+     * (GnssMeasurementsEvent.Callback)}.
+     *
+     * @param callback the listener to remove
+     */
+    public void unregisterGnssMeasurementCallback(GnssMeasurementsEvent.Callback callback) {
+        Log.i(TAG, "Remove Gnss Measurement Callback.");
+        mLocationManager.unregisterGnssMeasurementsCallback(callback);
+    }
+
+    /**
+     * See {@code LocationManager#requestLocationUpdates}.
+     *
+     * @param locationListener location listener for request
+     */
+    public void requestLocationUpdates(LocationListener locationListener) {
+        if (mLocationManager.getProvider(LocationManager.GPS_PROVIDER) != null) {
+            Log.i(TAG, "Request Location updates.");
+            mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
+                    0 /* minTime*/,
+                    0 /* minDistance */,
+                    locationListener,
+                    Looper.getMainLooper());
+        }
+    }
+
+    /**
+     * See {@link android.location.LocationManager#addGpsStatusListener (GpsStatus.Listener)}.
+     * @param listener the GpsStatus.Listener to add
+     */
+    public void addGpsStatusListener(final GpsStatus.Listener listener) {
+        Log.i(TAG, "Add Gps Status Listener.");
+        Handler mainThreadHandler = new Handler(Looper.getMainLooper());
+        // Add Gps status listener to the main thread, since the Gps Status updates will go to
+        // the main thread while the test thread is blocked by mGpsStatusListener.await()
+        mainThreadHandler.post(new Runnable() {
+            @Override
+            public void run() {
+                mLocationManager.addGpsStatusListener(listener);
+            }
+        });
+    }
+
+    /**
+     * See {@link android.location.LocationManager#removeGpsStatusListener (GpsStatus.Listener)}.
+     *
+     * @param listener the listener to remove
+     */
+    public void removeGpsStatusListener(GpsStatus.Listener listener) {
+        Log.i(TAG, "Remove Gps Status Listener.");
+        mLocationManager.removeGpsStatusListener(listener);
+    }
+
+    /**
+     * See {@link android.location.LocationManager#sendExtraCommand}.
+     *
+     * @param command name of the command to send to the provider.
+     *
+     * @return true if the command succeeds.
+     */
+    public boolean sendExtraCommand(String command) {
+        Log.i(TAG, "Send Extra Command = " + command);
+        boolean extraCommandStatus = mLocationManager.sendExtraCommand(LocationManager.GPS_PROVIDER,
+                command, null);
+        Log.i(TAG, "Sent extra command (" + command + ") status = " + extraCommandStatus);
+        return extraCommandStatus;
+    }
+
+    /**
+     * Add a GNSS Navigation Message callback.
+     *
+     * @param callback a {@link GnssNavigationMessage.Callback} object to register.
+     * @return {@code true} if the listener was added successfully, {@code false} otherwise.
+     */
+    public boolean registerGnssNavigationMessageCallback(
+            GnssNavigationMessage.Callback callback) {
+        Log.i(TAG, "Add Gnss Navigation Message Callback.");
+        return mLocationManager.registerGnssNavigationMessageCallback(callback);
+    }
+
+    /**
+     * Add a GNSS Navigation Message callback.
+     *
+     * @param callback a {@link GnssNavigationMessage.Callback} object to register.
+     * @param handler the handler that the callback runs at.
+     * @return {@code true} if the listener was added successfully, {@code false} otherwise.
+     */
+    public boolean registerGnssNavigationMessageCallback(
+            GnssNavigationMessage.Callback callback, Handler handler) {
+        Log.i(TAG, "Add Gnss Navigation Message Callback.");
+        return mLocationManager.registerGnssNavigationMessageCallback(callback, handler);
+    }
+
+    /**
+     * Removes a GNSS Navigation Message callback.
+     *
+     * @param callback a {@link GnssNavigationMessage.Callback} object to remove.
+     */
+    public void unregisterGnssNavigationMessageCallback(GnssNavigationMessage.Callback callback) {
+        Log.i(TAG, "Remove Gnss Navigation Message Callback.");
+        mLocationManager.unregisterGnssNavigationMessageCallback(callback);
+    }
+
+    /**
+     * Get LocationManager
+     *
+     * @return locationManager
+     */
+    public LocationManager getLocationManager() {
+        return mLocationManager;
+    }
+}
diff --git a/tests/tests/location/src/android/location/cts/TestMeasurementUtil.java b/tests/tests/location/src/android/location/cts/TestMeasurementUtil.java
new file mode 100644
index 0000000..f812f62
--- /dev/null
+++ b/tests/tests/location/src/android/location/cts/TestMeasurementUtil.java
@@ -0,0 +1,609 @@
+/*
+ * Copyright (C) 2015 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.location.cts;
+
+import android.location.GnssMeasurement;
+import android.location.GnssNavigationMessage;
+import android.location.GnssStatus;
+import android.location.LocationManager;
+import android.os.Build;
+import android.util.Log;
+
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Helper class for GnssMeasurement Tests.
+ */
+public final class TestMeasurementUtil {
+
+    private static final String TAG = "TestMeasurementUtil";
+    // Error message for GnssMeasurements Registration.
+    public static final String REGISTRATION_ERROR_MESSAGE = "Registration of GnssMeasurements" +
+            " listener has failed, this indicates a platform bug. Please report the issue with" +
+            " a full bugreport.";
+
+    /**
+     * Check if test can be run on the current device.
+     *
+     * @param  testLocationManager TestLocationManager
+     * @return true if Build.VERSION &gt;=  Build.VERSION_CODES.N and location enabled in device.
+     */
+    public static boolean canTestRunOnCurrentDevice(TestLocationManager testLocationManager) {
+       // TODO(sumitk): Enable this check once api 24 for N is avaiable.
+       /*
+       if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
+            Log.i(TAG, "This test is designed to work on N or newer. " +
+                    "Test is being skipped because the platform version is being run in " +
+                    Build.VERSION.SDK_INT);
+            return false;
+        }
+        */
+
+        if (!testLocationManager.getLocationManager()
+                .isProviderEnabled(LocationManager.GPS_PROVIDER)) {
+            Log.i(TAG, "GPS disabled or location disabled on the device. Skipping Test.");
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Assert all mandatory fields in Gnss Measurement are in expected range.
+     * See mandatory fields in {@code gps.h}.
+     *
+     * @param measurement GnssMeasurement
+     * @param softAssert  custom SoftAssert
+     * @param timeInNs    event time in ns
+     */
+    public static void assertAllGnssMeasurementMandatoryFields(GnssMeasurement measurement,
+        SoftAssert softAssert, long timeInNs) {
+
+        verifySvid(measurement, softAssert, timeInNs);
+        verifyReceivedSatelliteVehicleTimeInNs(measurement, softAssert, timeInNs);
+        verifyAccumulatedDeltaRanges(measurement, softAssert, timeInNs);
+
+        int state = measurement.getState();
+        softAssert.assertTrue("state: Satellite code sync state",
+                timeInNs,
+                "X > 0",
+                String.valueOf(state),
+                state > 0);
+
+        // Check received_gps_tow_uncertainty_ns
+        softAssert.assertTrueAsWarning("received_gps_tow_uncertainty_ns:" +
+                        " Uncertainty of received GPS Time-of-Week in ns",
+                timeInNs,
+                "X > 0",
+                String.valueOf(measurement.getReceivedSvTimeUncertaintyNanos()),
+                measurement.getReceivedSvTimeUncertaintyNanos() > 0L);
+
+        long timeOffsetInSec = TimeUnit.NANOSECONDS.toSeconds(
+                (long) measurement.getTimeOffsetNanos());
+        softAssert.assertTrue("time_offset_ns: Time offset",
+                timeInNs,
+                "-100 seconds < X < +10 seconds",
+                String.valueOf(measurement.getTimeOffsetNanos()),
+                (-100 < timeOffsetInSec) && (timeOffsetInSec < 10));
+
+        softAssert.assertTrue("c_n0_dbhz: Carrier-to-noise density",
+                timeInNs,
+                "0.0 >= X <=63",
+                String.valueOf(measurement.getCn0DbHz()),
+                measurement.getCn0DbHz() >= 0.0 &&
+                        measurement.getCn0DbHz() <= 63.0);
+
+        softAssert.assertTrue("pseudorange_rate_mps: Pseudorange rate in m/s",
+                timeInNs,
+                "X != 0.0",
+                String.valueOf(measurement.getPseudorangeRateMetersPerSecond()),
+                measurement.getPseudorangeRateMetersPerSecond() != 0.0);
+
+        softAssert.assertTrue("pseudorange_rate_uncertainty_mps: " +
+                        "Pseudorange Rate Uncertainty in m/s",
+                timeInNs,
+                "X > 0.0",
+                String.valueOf(
+                        measurement.getPseudorangeRateUncertaintyMetersPerSecond()),
+                measurement.getPseudorangeRateUncertaintyMetersPerSecond() > 0.0);
+
+        // Check carrier_frequency_hz.
+        if (measurement.hasCarrierFrequencyHz()) {
+            softAssert.assertTrue("carrier_frequency_hz: Carrier frequency in hz",
+                    timeInNs,
+                    "X > 0.0",
+                    String.valueOf(measurement.getCarrierFrequencyHz()),
+                    measurement.getCarrierFrequencyHz() > 0.0);
+        }
+
+        // Check carrier_phase.
+        if (measurement.hasCarrierPhase()) {
+            softAssert.assertTrue("carrier_phase: Carrier phase",
+                    timeInNs,
+                    "0.0 >= X <= 1.0",
+                    String.valueOf(measurement.getCarrierPhase()),
+                    measurement.getCarrierPhase() >= 0.0 && measurement.getCarrierPhase() <= 1.0);
+        }
+
+        // Check carrier_phase_uncertainty..
+        if (measurement.hasCarrierPhaseUncertainty()) {
+            softAssert.assertTrue("carrier_phase_uncertainty: 1-Sigma uncertainty of the " +
+                            "carrier-phase",
+                    timeInNs,
+                    "X > 0.0",
+                    String.valueOf(measurement.getCarrierPhaseUncertainty()),
+                    measurement.getCarrierPhaseUncertainty() > 0.0);
+        }
+
+        // Check GNSS Measurement's multipath_indicator.
+        softAssert.assertTrue("multipath_indicator: GNSS Measurement's multipath indicator",
+                timeInNs,
+                "0 >= X <= 2",
+                String.valueOf(measurement.getMultipathIndicator()),
+                measurement.getMultipathIndicator() >= 0
+                        && measurement.getMultipathIndicator() <= 2);
+
+
+        // Check Signal-to-Noise ratio (SNR).
+        if (measurement.hasSnrInDb()) {
+            softAssert.assertTrue("snr: Signal-to-Noise ratio (SNR) in dB",
+                    timeInNs,
+                    "0.0 >= X <= 63",
+                    String.valueOf(measurement.getSnrInDb()),
+                    measurement.getSnrInDb() >= 0.0 && measurement.getSnrInDb() <= 63);
+        }
+    }
+
+    /**
+     * Verify accumulated delta ranges are in expected range.
+     *
+     * @param measurement GnssMeasurement
+     * @param softAssert  custom SoftAssert
+     * @param timeInNs    event time in ns
+     */
+    private static void verifyAccumulatedDeltaRanges(GnssMeasurement measurement,
+        SoftAssert softAssert, long timeInNs) {
+
+        int accumulatedDeltaRangeState = measurement.getAccumulatedDeltaRangeState();
+        softAssert.assertTrue("accumulated_delta_range_state: " +
+                        "Accumulated delta range state",
+                timeInNs,
+                "0 <= X <= 7",
+                String.valueOf(accumulatedDeltaRangeState),
+                accumulatedDeltaRangeState >= 0 && accumulatedDeltaRangeState <= 7);
+        if (accumulatedDeltaRangeState > 0) {
+            double accumulatedDeltaRangeInMeters =
+                    measurement.getAccumulatedDeltaRangeMeters();
+            softAssert.assertTrue("accumulated_delta_range_m: " +
+                            "Accumulated delta range in meter",
+                    timeInNs,
+                    "X != 0.0",
+                    String.valueOf(accumulatedDeltaRangeInMeters),
+                    accumulatedDeltaRangeInMeters != 0.0);
+            double accumulatedDeltaRangeUncertainty =
+                    measurement.getAccumulatedDeltaRangeUncertaintyMeters();
+            softAssert.assertTrue("accumulated_delta_range_uncertainty_m: " +
+                            "Accumulated delta range uncertainty in meter",
+                    timeInNs,
+                    "X > 0.0",
+                    String.valueOf(accumulatedDeltaRangeUncertainty),
+                    accumulatedDeltaRangeUncertainty > 0.0);
+        }
+    }
+
+    /**
+     * Verify svid's are in expected range.
+     *
+     * @param measurement GnssMeasurement
+     * @param softAssert  custom SoftAssert
+     * @param timeInNs    event time in ns
+     */
+    private static void verifySvid(GnssMeasurement measurement, SoftAssert softAssert,
+        long timeInNs) {
+
+        String svidLogMessageFormat = "svid: Space Vehicle ID. Constellation type = %s";
+        int constellationType = measurement.getConstellationType();
+        int svid = measurement.getSvid();
+        String svidValue = String.valueOf(svid);
+
+        switch (constellationType) {
+            case GnssStatus.CONSTELLATION_GPS:
+                softAssert.assertTrue("svid: Space Vehicle ID. Constellation type " +
+                                "= CONSTELLATION_GPS",
+                        timeInNs,
+                        "[1, 32]",
+                        svidValue,
+                        svid > 0 && svid <= 32);
+                break;
+            case GnssStatus.CONSTELLATION_SBAS:
+                softAssert.assertTrue("svid: Space Vehicle ID. Constellation type " +
+                                "= CONSTELLATION_SBAS",
+                        timeInNs,
+                        "120 <= X <= 192",
+                        svidValue,
+                        svid >= 120 && svid <= 192);
+                break;
+            case GnssStatus.CONSTELLATION_GLONASS:
+                // Check Upper 8 bit, signed
+                int freq = (svid >> 8);
+                softAssert.assertTrue("svid: upper 8 bits, frequency number. Constellation type " +
+                                "= CONSTELLATION_GLONASS",
+                        timeInNs,
+                        "freq == -127 || -7 <= freq <= 6",
+                        svidValue,
+                        (freq == -127) || (freq >= -7 && freq <= 6));
+                // Check lower 8 bits, signed
+                byte slot = (byte) svid;
+                softAssert.assertTrue("svid: lower 8 bits, slot. Constellation type " +
+                                "= CONSTELLATION_GLONASS",
+                        timeInNs,
+                        "slot == -127 || 1 <= slot <= 24",
+                        svidValue,
+                        (slot == -127) || (slot >= 1 && slot <= 24));
+                softAssert.assertTrue("svid: one of slot or freq is set (not -127). " +
+                                "ConstellationType = CONSTELLATION_GLONASS,",
+                        timeInNs,
+                        "slot != -127 || freq != -127",
+                        svidValue,
+                        (slot != -127) || (freq != -127));
+                break;
+            case GnssStatus.CONSTELLATION_QZSS:
+                softAssert.assertTrue("svid: Space Vehicle ID. Constellation type " +
+                                "= CONSTELLATION_QZSS",
+                        timeInNs,
+                        "193 <= X <= 200",
+                        svidValue,
+                        svid >= 193 && svid <= 200);
+                break;
+            case GnssStatus.CONSTELLATION_BEIDOU:
+                softAssert.assertTrue("svid: Space Vehicle ID. Constellation type " +
+                                "= CONSTELLATION_BEIDOU",
+                        timeInNs,
+                        "1 <= X <= 36",
+                        svidValue,
+                        svid >= 1 && svid <= 36);
+                break;
+            case GnssStatus.CONSTELLATION_GALILEO:
+                softAssert.assertTrue("svid: Space Vehicle ID. Constellation type " +
+                                "= CONSTELLATION_GALILEO",
+                        timeInNs,
+                        "1 <= X <= 37",
+                        String.valueOf(svid),
+                        svid >= 1 && svid <= 37);
+                break;
+            default:
+                // Explicit fail if did not receive valid constellation type.
+                softAssert.assertTrue("svid: Space Vehicle ID. Did not receive any valid " +
+                                "constellation type.",
+                        timeInNs,
+                        "Valid constellation type.",
+                        svidValue,
+                        false);
+                break;
+        }
+    }
+
+    /**
+     * Verify sv times are in expected range.
+     *
+     * @param measurement GnssMeasurement
+     * @param softAssert  custom SoftAssert
+     * @param timeInNs    event time in ns
+     * */
+    private static void verifyReceivedSatelliteVehicleTimeInNs(GnssMeasurement measurement,
+        SoftAssert softAssert, long timeInNs) {
+
+        int constellationType = measurement.getConstellationType();
+        int state = measurement.getState();
+        long received_sv_time_ns = measurement.getReceivedSvTimeNanos();
+        double sv_time_ms = TimeUnit.NANOSECONDS.toMillis(received_sv_time_ns);
+        double sv_time_sec = TimeUnit.NANOSECONDS.toSeconds(received_sv_time_ns);
+        double sv_time_days = TimeUnit.NANOSECONDS.toDays(received_sv_time_ns);
+
+        // Check ranges for received_sv_time_ns for given Gps State
+        if (state == 0) {
+            softAssert.assertTrue("received_sv_time_ns:" +
+                            " Received SV Time-of-Week in ns." +
+                            " GNSS_MEASUREMENT_STATE_UNKNOWN.",
+                    timeInNs,
+                    "X == 0",
+                    String.valueOf(received_sv_time_ns),
+                    sv_time_ms == 0);
+        }
+
+        switch (constellationType) {
+            case GnssStatus.CONSTELLATION_GPS:
+                verifyGpsQzssSvTimes(measurement, softAssert, timeInNs, state, "CONSTELLATION_GPS");
+                break;
+            case GnssStatus.CONSTELLATION_QZSS:
+                verifyGpsQzssSvTimes(measurement, softAssert, timeInNs, state,
+                        "CONSTELLATION_QZSS");
+                break;
+            case GnssStatus.CONSTELLATION_SBAS:
+                if ((state | GnssMeasurement.STATE_SBAS_SYNC)
+                        == GnssMeasurement.STATE_SBAS_SYNC) {
+                    softAssert.assertTrue(getReceivedSvTimeNsLogMessage(
+                                    "GNSS_MEASUREMENT_STATE_SBAS_SYNC",
+                                    "GnssStatus.CONSTELLATION_SBAS"),
+                            timeInNs,
+                            "0s >= X <= 1s",
+                            String.valueOf(sv_time_sec),
+                            sv_time_sec >= 0 && sv_time_sec <= 1);
+                } else if ((state | GnssMeasurement.STATE_SYMBOL_SYNC)
+                        == GnssMeasurement.STATE_SYMBOL_SYNC) {
+                    softAssert.assertTrue(getReceivedSvTimeNsLogMessage(
+                                    "GNSS_MEASUREMENT_STATE_SYMBOL_SYNC",
+                                    "GnssStatus.CONSTELLATION_SBAS"),
+                            timeInNs,
+                            "0ms >= X <= 2ms",
+                            String.valueOf(sv_time_ms),
+                            sv_time_ms >= 0 && sv_time_ms <= 2);
+                } else if ((state | GnssMeasurement.STATE_CODE_LOCK)
+                        == GnssMeasurement.STATE_CODE_LOCK) {
+                    softAssert.assertTrue(getReceivedSvTimeNsLogMessage(
+                                    "GNSS_MEASUREMENT_STATE_CODE_LOCK",
+                                    "GnssStatus.CONSTELLATION_SBAS"),
+                            timeInNs,
+                            "0ms >= X <= 1ms",
+                            String.valueOf(sv_time_ms),
+                            sv_time_ms >= 0 && sv_time_ms <= 1);
+                }
+                break;
+            case GnssStatus.CONSTELLATION_GLONASS:
+                if ((state | GnssMeasurement.STATE_GLO_TOD_DECODED)
+                        == GnssMeasurement.STATE_GLO_TOD_DECODED) {
+                    softAssert.assertTrue(getReceivedSvTimeNsLogMessage(
+                                    "GNSS_MEASUREMENT_STATE_GLO_TOD_DECODED",
+                                    "GnssStatus.CONSTELLATION_GLONASS"),
+                            timeInNs,
+                            "0 day >= X <= 1 day",
+                            String.valueOf(sv_time_days),
+                            sv_time_days >= 0 && sv_time_days <= 1);
+                } else if ((state | GnssMeasurement.STATE_GLO_STRING_SYNC)
+                        == GnssMeasurement.STATE_GLO_STRING_SYNC) {
+                    softAssert.assertTrue(getReceivedSvTimeNsLogMessage(
+                                    "GNSS_MEASUREMENT_STATE_GLO_STRING_SYNC",
+                                    "GnssStatus.CONSTELLATION_GLONASS"),
+                            timeInNs,
+                            "0s >= X <= 2s",
+                            String.valueOf(sv_time_sec),
+                            sv_time_sec >= 0 && sv_time_sec <= 2);
+                } else if ((state | GnssMeasurement.STATE_BIT_SYNC)
+                        == GnssMeasurement.STATE_BIT_SYNC) {
+                    softAssert.assertTrue(getReceivedSvTimeNsLogMessage(
+                                    "GNSS_MEASUREMENT_STATE_BIT_SYNC",
+                                    "GnssStatus.CONSTELLATION_GLONASS"),
+                            timeInNs,
+                            "0ms >= X <= 20ms",
+                            String.valueOf(sv_time_ms),
+                            sv_time_ms >= 0 && sv_time_ms <= 20);
+                } else if ((state | GnssMeasurement.STATE_SYMBOL_SYNC)
+                        == GnssMeasurement.STATE_SYMBOL_SYNC) {
+                    softAssert.assertTrue(getReceivedSvTimeNsLogMessage(
+                                    "GNSS_MEASUREMENT_STATE_SYMBOL_SYNC",
+                                    "GnssStatus.CONSTELLATION_GLONASS"),
+                            timeInNs,
+                            "0ms >= X <= 10ms",
+                            String.valueOf(sv_time_ms),
+                            sv_time_ms >= 0 && sv_time_ms <= 10);
+                } else if ((state | GnssMeasurement.STATE_CODE_LOCK)
+                        == GnssMeasurement.STATE_CODE_LOCK) {
+                    softAssert.assertTrue(getReceivedSvTimeNsLogMessage(
+                                    "GNSS_MEASUREMENT_STATE_CODE_LOCK",
+                                    "GnssStatus.CONSTELLATION_GLONASS"),
+                            timeInNs,
+                            "0ms >= X <= 1ms",
+                            String.valueOf(sv_time_ms),
+                            sv_time_ms >= 0 && sv_time_ms <= 1);
+                }
+                break;
+            case GnssStatus.CONSTELLATION_GALILEO:
+                if ((state | GnssMeasurement.STATE_TOW_DECODED)
+                        == GnssMeasurement.STATE_TOW_DECODED) {
+                    softAssert.assertTrue(getReceivedSvTimeNsLogMessage(
+                                    "GNSS_MEASUREMENT_STATE_TOW_DECODED",
+                                    "GnssStatus.CONSTELLATION_GALILEO"),
+                            timeInNs,
+                            "0 >= X <= 7 days",
+                            String.valueOf(sv_time_days),
+                            sv_time_days >= 0 && sv_time_days <= 7);
+                } else if ((state | GnssMeasurement.STATE_GAL_E1B_PAGE_SYNC)
+                        == GnssMeasurement.STATE_GAL_E1B_PAGE_SYNC) {
+                    softAssert.assertTrue(getReceivedSvTimeNsLogMessage(
+                                    "GNSS_MEASUREMENT_STATE_GAL_E1B_PAGE_SYNC",
+                                    "GnssStatus.CONSTELLATION_GALILEO"),
+                            timeInNs,
+                            "0s >= X <= 2s",
+                            String.valueOf(sv_time_sec),
+                            sv_time_sec >= 0 && sv_time_sec <= 2);
+                } else if ((state | GnssMeasurement.STATE_GAL_E1C_2ND_CODE_LOCK)
+                        == GnssMeasurement.STATE_GAL_E1C_2ND_CODE_LOCK) {
+                    softAssert.assertTrue(getReceivedSvTimeNsLogMessage(
+                                    "GNSS_MEASUREMENT_STATE_GAL_E1C_2ND_CODE_LOCK",
+                                    "GnssStatus.CONSTELLATION_GALILEO"),
+                            timeInNs,
+                            "0ms >= X <= 100ms",
+                            String.valueOf(sv_time_ms),
+                            sv_time_ms >= 0 && sv_time_ms <= 100);
+                } else if ((state | GnssMeasurement.STATE_GAL_E1BC_CODE_LOCK)
+                        == GnssMeasurement.STATE_GAL_E1BC_CODE_LOCK) {
+                    softAssert.assertTrue(getReceivedSvTimeNsLogMessage(
+                                    "GNSS_MEASUREMENT_STATE_GAL_E1BC_CODE_LOCK",
+                                    "GnssStatus.CONSTELLATION_GALILEO"),
+                            timeInNs,
+                            "0ms >= X <= 4ms",
+                            String.valueOf(sv_time_ms),
+                            sv_time_ms >= 0 && sv_time_ms <= 4);
+                }
+                break;
+            case GnssStatus.CONSTELLATION_BEIDOU:
+                if ((state | GnssMeasurement.STATE_TOW_DECODED)
+                        == GnssMeasurement.STATE_TOW_DECODED) {
+                    softAssert.assertTrue(getReceivedSvTimeNsLogMessage(
+                                    "GNSS_MEASUREMENT_STATE_TOW_DECODED",
+                                    "GnssStatus.CONSTELLATION_BEIDOU"),
+                            timeInNs,
+                            "0 >= X <= 7 days",
+                            String.valueOf(sv_time_days),
+                            sv_time_days >= 0 && sv_time_days <= 7);
+                } else if ((state | GnssMeasurement.STATE_SUBFRAME_SYNC)
+                        == GnssMeasurement.STATE_SUBFRAME_SYNC) {
+                    softAssert.assertTrue(getReceivedSvTimeNsLogMessage(
+                                    "GNSS_MEASUREMENT_STATE_SUBFRAME_SYNC",
+                                    "GnssStatus.CONSTELLATION_BEIDOU"),
+                            timeInNs,
+                            "0s >= X <= 6s",
+                            String.valueOf(sv_time_sec),
+                            sv_time_sec >= 0 && sv_time_sec <= 6);
+                } else if ((state | GnssMeasurement.STATE_BDS_D2_SUBFRAME_SYNC)
+                        == GnssMeasurement.STATE_BDS_D2_SUBFRAME_SYNC) {
+                    softAssert.assertTrue(getReceivedSvTimeNsLogMessage(
+                                    "GNSS_MEASUREMENT_STATE_BDS_D2_SUBFRAME_SYNC",
+                                    "GnssStatus.CONSTELLATION_BEIDOU"),
+                            timeInNs,
+                            "0ms >= X <= 600ms (0.6sec)",
+                            String.valueOf(sv_time_ms),
+                            sv_time_ms >= 0 && sv_time_ms <= 600);
+                } else if ((state | GnssMeasurement.STATE_BIT_SYNC)
+                        == GnssMeasurement.STATE_BIT_SYNC) {
+                    softAssert.assertTrue(getReceivedSvTimeNsLogMessage(
+                                    "GNSS_MEASUREMENT_STATE_BIT_SYNC",
+                                    "GnssStatus.CONSTELLATION_BEIDOU"),
+                            timeInNs,
+                            "0ms >= X <= 20ms",
+                            String.valueOf(sv_time_ms),
+                            sv_time_ms >= 0 && sv_time_ms <= 20);
+                } else if ((state | GnssMeasurement.STATE_BDS_D2_BIT_SYNC)
+                        == GnssMeasurement.STATE_BDS_D2_BIT_SYNC) {
+                    softAssert.assertTrue(getReceivedSvTimeNsLogMessage(
+                                    "GNSS_MEASUREMENT_STATE_BDS_D2_BIT_SYNC",
+                                    "GnssStatus.CONSTELLATION_BEIDOU"),
+                            timeInNs,
+                            "0ms >= X <= 2ms",
+                            String.valueOf(sv_time_ms),
+                            sv_time_ms >= 0 && sv_time_ms <= 2);
+                } else if ((state | GnssMeasurement.STATE_CODE_LOCK)
+                        == GnssMeasurement.STATE_CODE_LOCK) {
+                    softAssert.assertTrue(getReceivedSvTimeNsLogMessage(
+                                    "GNSS_MEASUREMENT_STATE_CODE_LOCK",
+                                    "GnssStatus.CONSTELLATION_BEIDOU"),
+                            timeInNs,
+                            "0ms >= X <= 1ms",
+                            String.valueOf(sv_time_ms),
+                            sv_time_ms >= 0 && sv_time_ms <= 1);
+                }
+                break;
+        }
+    }
+
+    private static String getReceivedSvTimeNsLogMessage(String constellationType, String state) {
+        return "received_sv_time_ns: Received SV Time-of-Week in ns. Constellation type = "
+                + constellationType + ". State = " + state;
+    }
+
+    /**
+     * Verify sv times are in expected range for given constellation type.
+     * This is common check for CONSTELLATION_GPS & CONSTELLATION_QZSS.
+     *
+     * @param measurement GnssMeasurement
+     * @param softAssert  custom SoftAssert
+     * @param timeInNs    event time in ns
+     * @param state       GnssMeasurement State
+     * @param constellationType Gnss Constellation type
+     */
+    private static void verifyGpsQzssSvTimes(GnssMeasurement measurement,
+        SoftAssert softAssert, long timeInNs, int state, String constellationType) {
+
+        long received_sv_time_ns = measurement.getReceivedSvTimeNanos();
+        double sv_time_ms = TimeUnit.NANOSECONDS.toMillis(received_sv_time_ns);
+        double sv_time_sec = TimeUnit.NANOSECONDS.toSeconds(received_sv_time_ns);
+        double sv_time_days = TimeUnit.NANOSECONDS.toDays(received_sv_time_ns);
+
+        if ((state | GnssMeasurement.STATE_TOW_DECODED)
+                == GnssMeasurement.STATE_TOW_DECODED) {
+            softAssert.assertTrue(getReceivedSvTimeNsLogMessage(
+                            "GNSS_MEASUREMENT_STATE_TOW_DECODED",
+                            constellationType),
+                    timeInNs,
+                    "0 >= X <= 7 days",
+                    String.valueOf(sv_time_days),
+                    sv_time_days >= 0 && sv_time_days <= 7);
+        } else if ((state | GnssMeasurement.STATE_SUBFRAME_SYNC)
+                == GnssMeasurement.STATE_SUBFRAME_SYNC) {
+            softAssert.assertTrue(getReceivedSvTimeNsLogMessage(
+                            "GNSS_MEASUREMENT_STATE_SUBFRAME_SYNC",
+                            constellationType),
+                    timeInNs,
+                    "0s >= X <= 6s",
+                    String.valueOf(sv_time_sec),
+                    sv_time_sec >= 0 && sv_time_sec <= 6);
+        } else if ((state | GnssMeasurement.STATE_BIT_SYNC)
+                == GnssMeasurement.STATE_BIT_SYNC) {
+            softAssert.assertTrue(getReceivedSvTimeNsLogMessage(
+                            "GNSS_MEASUREMENT_STATE_BIT_SYNC",
+                            constellationType),
+                    timeInNs,
+                    "0ms >= X <= 20ms",
+                    String.valueOf(sv_time_ms),
+                    sv_time_ms >= 0 && sv_time_ms <= 20);
+
+        } else if ((state | GnssMeasurement.STATE_CODE_LOCK)
+                == GnssMeasurement.STATE_CODE_LOCK) {
+            softAssert.assertTrue(getReceivedSvTimeNsLogMessage(
+                            "GNSS_MEASUREMENT_STATE_CODE_LOCK",
+                            constellationType),
+                    timeInNs,
+                    "0ms >= X <= 1ms",
+                    String.valueOf(sv_time_ms),
+                    sv_time_ms >= 0 && sv_time_ms <= 1);
+        }
+    }
+
+    /**
+     * Assert all mandatory fields in Gnss Navigation Message are in expected range.
+     * See mandatory fields in {@code gps.h}.
+     *
+     * @param events GnssNavigationMessageEvents
+     */
+    public static void verifyGnssNavMessageMandatoryField(List<GnssNavigationMessage> events) {
+        // Verify mandatory GnssNavigationMessage field values.
+        SoftAssert softAssert = new SoftAssert(TAG);
+        for (GnssNavigationMessage message : events) {
+            int type = message.getType();
+            softAssert.assertTrue("Gnss Navigation Message Type:expected [0x0101 - 0x0104]," +
+                            " actual = " + type,
+                    type >= 0x0101 && type <= 0x0104);
+
+            // if message type == TYPE_L1CA, verify PRN & Data Size.
+            int messageType = message.getType();
+            if (messageType == GnssNavigationMessage.TYPE_GPS_L1CA) {
+                int svid = message.getSvid();
+                softAssert.assertTrue("Space Vehicle ID : expected = [1, 32], actual = " +
+                                svid,
+                        svid >= 1 && svid <= 32);
+                int dataSize = message.getData().length;
+                softAssert.assertTrue("Data size: expected = 40, actual = " + dataSize,
+                        dataSize == 40);
+            } else {
+                Log.i(TAG, "GnssNavigationMessage (type = " + messageType
+                        + ") skipped for verification.");
+            }
+        }
+        softAssert.assertAll();
+    }
+}
diff --git a/tests/tests/location/src/android/location/cts/TestUtils.java b/tests/tests/location/src/android/location/cts/TestUtils.java
new file mode 100644
index 0000000..82d644e
--- /dev/null
+++ b/tests/tests/location/src/android/location/cts/TestUtils.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2016 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.location.cts;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+public class TestUtils {
+    private static final long STANDARD_WAIT_TIME_MS = 50;
+    private static final long STANDARD_SLEEP_TIME_MS = 50;
+    private static final long STANDARD_WAIT_TIME_ROUNDS = 1200;
+
+    public static boolean waitFor(CountDownLatch latch) throws InterruptedException {
+        // Since late 2014, if the main thread has been occupied for long enough, Android will
+        // increase its priority. Such new behavior can causes starvation to the background thread -
+        // even if the main thread has called await() to yield its execution, the background thread
+        // still can't get scheduled.
+        //
+        // Here we're trying to wait on the main thread for a PendingIntent from a background
+        // thread. Because of the starvation problem, the background thread may take up to 5 minutes
+        // to deliver the PendingIntent if we simply call await() on the main thread. In order to
+        // give the background thread a chance to run, we call Thread.sleep() in a loop. Such dirty
+        // hack isn't ideal, but at least it can work.
+        //
+        // See also: b/17423027
+        for (int i = 0; i < STANDARD_WAIT_TIME_ROUNDS; ++i) {
+            Thread.sleep(STANDARD_SLEEP_TIME_MS);
+            if (latch.await(STANDARD_WAIT_TIME_MS, TimeUnit.MILLISECONDS)) {
+                return true;
+            }
+        }
+        return false;
+    }
+}
diff --git a/tests/tests/location2/Android.mk b/tests/tests/location2/Android.mk
index 5b227b2..4273444 100644
--- a/tests/tests/location2/Android.mk
+++ b/tests/tests/location2/Android.mk
@@ -21,6 +21,9 @@
 # and when built explicitly put it in the data partition
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
diff --git a/tests/tests/location2/AndroidManifest.xml b/tests/tests/location2/AndroidManifest.xml
index b2e0802..766aab4 100644
--- a/tests/tests/location2/AndroidManifest.xml
+++ b/tests/tests/location2/AndroidManifest.xml
@@ -16,7 +16,7 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.location2">
+    package="android.location2.cts">
 
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <application>
@@ -27,7 +27,7 @@
     <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"/>
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.cts.location2"
+                     android:targetPackage="android.location2.cts"
                      android:label="CTS tests of android.location">
         <meta-data android:name="listener"
             android:value="com.android.cts.runner.CtsTestRunListener" />
diff --git a/tests/tests/location2/AndroidTest.xml b/tests/tests/location2/AndroidTest.xml
new file mode 100644
index 0000000..5829249
--- /dev/null
+++ b/tests/tests/location2/AndroidTest.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS Location test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.LocationCheck" />
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsLocation2TestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.location2.cts" />
+    </test>
+
+</configuration>
diff --git a/tests/tests/location2/src/android/location2/cts/LocationManagerTest.java b/tests/tests/location2/src/android/location2/cts/LocationManagerTest.java
index 6764223..2e84264 100644
--- a/tests/tests/location2/src/android/location2/cts/LocationManagerTest.java
+++ b/tests/tests/location2/src/android/location2/cts/LocationManagerTest.java
@@ -253,7 +253,7 @@
         }
 
         try {
-            mManager.addNmeaListener(null);
+            mManager.addNmeaListener((NmeaListener) null);
             fail("Should have failed to add null as a gps status nmea listener");
         } catch (SecurityException e) {
             // expected
diff --git a/tests/tests/media/Android.mk b/tests/tests/media/Android.mk
index ea7256d..879c72b 100644
--- a/tests/tests/media/Android.mk
+++ b/tests/tests/media/Android.mk
@@ -17,8 +17,9 @@
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES := \
-	src/android/media/cts/CodecImage.java \
-	src/android/media/cts/CodecUtils.java
+  src/android/media/cts/CodecImage.java \
+  src/android/media/cts/YUVImage.java \
+  src/android/media/cts/CodecUtils.java
 
 LOCAL_MODULE_TAGS := optional
 
@@ -32,16 +33,20 @@
 
 # don't include this package in any target
 LOCAL_MODULE_TAGS := optional
+
 # and when built explicitly put it in the data partition
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
 
+LOCAL_DEX_PREOPT := false
+
+LOCAL_PROGUARD_ENABLED := disabled
+
 # include both the 32 and 64 bit versions
 LOCAL_MULTILIB := both
 
-LOCAL_STATIC_JAVA_LIBRARIES := \
-    ctsmediautil ctsdeviceutil ctstestserver ctstestrunner
+LOCAL_STATIC_JAVA_LIBRARIES := ctsmediautil ctsdeviceutil compatibility-device-util ctstestserver ctstestrunner ndkaudio
 
-LOCAL_JNI_SHARED_LIBRARIES := libctsmediacodec_jni libaudio_jni
+LOCAL_JNI_SHARED_LIBRARIES := libctsmediacodec_jni libaudio_jni libnativehelper_compat_libc++ libndkaudioLib
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
@@ -49,9 +54,11 @@
 
 # uncomment when b/13249737 is fixed
 #LOCAL_SDK_VERSION := current
+
 LOCAL_JAVA_LIBRARIES += android.test.runner org.apache.http.legacy
 
-cts_runtime_hint := 265
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
 
 include $(BUILD_CTS_PACKAGE)
 
diff --git a/tests/tests/media/AndroidManifest.xml b/tests/tests/media/AndroidManifest.xml
index cdc0e60..9064ade 100644
--- a/tests/tests/media/AndroidManifest.xml
+++ b/tests/tests/media/AndroidManifest.xml
@@ -15,8 +15,10 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.media">
+    package="android.media.cts">
 
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
     <uses-permission android:name="android.permission.CAMERA" />
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <uses-permission android:name="android.permission.INTERNET" />
@@ -34,6 +36,13 @@
             android:label="AudioManagerStub"/>
         <activity android:name="android.media.cts.AudioManagerStubHelper"
             android:label="AudioManagerStubHelper"/>
+        <activity android:name="android.media.cts.DecodeAccuracyTestActivity"
+            android:label="DecodeAccuracyTestActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+            </intent-filter>
+        </activity>
         <activity android:name="android.media.cts.MediaStubActivity"
             android:label="MediaStubActivity"
             android:screenOrientation="nosensor"
@@ -88,7 +97,7 @@
     </application>
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.cts.media"
+                     android:targetPackage="android.media.cts"
                      android:label="CTS tests of android.media">
         <meta-data android:name="listener"
             android:value="com.android.cts.runner.CtsTestRunListener" />
diff --git a/tests/tests/media/AndroidTest.xml b/tests/tests/media/AndroidTest.xml
new file mode 100644
index 0000000..5131fe4
--- /dev/null
+++ b/tests/tests/media/AndroidTest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS Media test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsMediaTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.media.cts" />
+    </test>
+</configuration>
diff --git a/tests/tests/media/DynamicConfig.xml b/tests/tests/media/DynamicConfig.xml
new file mode 100644
index 0000000..1299440
--- /dev/null
+++ b/tests/tests/media/DynamicConfig.xml
@@ -0,0 +1,53 @@
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<dynamicConfig>
+    <entry key="DecoderTest-VIDEO_URL">
+        <value>http://redirector.gvt1.com/videoplayback?id=c80658495af60617&amp;itag=18&amp;source=youtube&amp;ip=0.0.0.0&amp;ipbits=0&amp;expire=19000000000&amp;sparams=ip,ipbits,expire,id,itag,source&amp;signature=46A04ED550CA83B79B60060BA80C79FDA5853D26.49582D382B4A9AFAA163DED38D2AE531D85603C0&amp;key=ik0&amp;user=android-device-test</value>
+    </entry>
+    <entry key="StreamingMediaPlayerTest-testHTTP_H264Base_AAC_Video1">
+        <value>http://redirector.gvt1.com/videoplayback?id=271de9756065677e&amp;itag=18&amp;source=youtube&amp;ip=0.0.0.0&amp;ipbits=0&amp;expire=19000000000&amp;sparams=ip,ipbits,expire,id,itag,source&amp;signature=667AEEF54639926662CE62361400B8F8C1753B3F.15F46C382C68A9F121BA17BF1F56BEDEB4B06091&amp;key=ik0&amp;user=android-device-test</value>
+    </entry>
+    <entry key="StreamingMediaPlayerTest-testHTTP_H264Base_AAC_Video2">
+        <value>http://www.youtube.com/api/manifest/hls_variant/id/0168724d02bd9945/itag/5/source/youtube/playlist_type/DVR/ip/0.0.0.0/ipbits/0/expire/19000000000/sparams/ip,ipbits,expire,id,itag,source,playlist_type/signature/773AB8ACC68A96E5AA481996AD6A1BBCB70DCB87.95733B544ACC5F01A1223A837D2CF04DF85A3360/key/ik0/file/m3u8</value>
+    </entry>
+    <entry key="MediaCodecCapabilitiesTest-testAvcHigh31">
+        <value>http://redirector.gvt1.com/videoplayback?id=271de9756065677e&amp;itag=22&amp;source=youtube&amp;user=android-device-test&amp;sparams=ip,ipbits,expire,id,itag,source,user&amp;ip=0.0.0.0&amp;ipbits=0&amp;expire=19000000000&amp;signature=179525311196616BD8E1381759B0E5F81A9E91B5.C4A50E44059FEBCC6BBC78E3B3A4E0E0065777&amp;key=ik0</value>
+    </entry>
+    <entry key="StreamingMediaPlayerTest-testHTTP_MPEG4SP_AAC_Video2">
+        <value>http://redirector.gvt1.com/videoplayback?id=c80658495af60617&amp;itag=17&amp;source=youtube&amp;ip=0.0.0.0&amp;ipbits=0&amp;expire=19000000000&amp;sparams=ip,ipbits,expire,id,itag,source&amp;signature=70E979A621001201BC18622BDBF914FA870BDA40.6E78890B80F4A33A18835F775B1FF64F0A4D0003&amp;key=ik0&amp;user=android-device-test</value>
+    </entry>
+    <entry key="StreamingMediaPlayerTest-testHTTP_MPEG4SP_AAC_Video1">
+        <value>http://redirector.gvt1.com/videoplayback?id=271de9756065677e&amp;itag=17&amp;source=youtube&amp;ip=0.0.0.0&amp;ipbits=0&amp;expire=19000000000&amp;sparams=ip,ipbits,expire,id,itag,source&amp;signature=837198AAADF6F36BA6B2D324F690A7C5B7AFE3FF.7138CE5E36D718220726C1FC305497FF2D082249&amp;key=ik0&amp;user=android-device-test</value>
+    </entry>
+    <entry key="MediaCodecCapabilitiesTest-testAvcBaseline12">
+        <value>http://redirector.gvt1.com/videoplayback?id=271de9756065677e&amp;itag=160&amp;source=youtube&amp;user=android-device-test&amp;sparams=ip,ipbits,expire,id,itag,source,user&amp;ip=0.0.0.0&amp;ipbits=0&amp;expire=19000000000&amp;signature=9EDCA0B395B8A949C511FD5E59B9F805CFF797FD.702DE9BA7AF96785FD6930AD2DD693A0486C880E&amp;key=ik0</value>
+    </entry>
+    <entry key="DecoderTest-AUDIO_URL">
+        <value>http://redirector.gvt1.com/videoplayback?id=c80658495af60617&amp;itag=18&amp;source=youtube&amp;ip=0.0.0.0&amp;ipbits=0&amp;expire=19000000000&amp;sparams=ip,ipbits,expire,id,itag,source&amp;signature=46A04ED550CA83B79B60060BA80C79FDA5853D26.49582D382B4A9AFAA163DED38D2AE531D85603C0&amp;key=ik0&amp;user=android-device-test</value>
+    </entry>
+    <entry key="MediaCodecCapabilitiesTest-testAvcBaseline30">
+        <value>http://redirector.gvt1.com/videoplayback?id=271de9756065677e&amp;itag=18&amp;source=youtube&amp;user=android-device-test&amp;sparams=ip,ipbits,expire,id,itag,source,user&amp;ip=0.0.0.0&amp;ipbits=0&amp;expire=19000000000&amp;signature=7DCDE3A6594D0B91A27676A3CDC3A87B149F82EA.7A83031734CB1EDCE06766B6228842F954927960&amp;key=ik0</value>
+    </entry>
+    <entry key="MediaCodecCapabilitiesTest-testAvcHigh40">
+        <value>http://redirector.gvt1.com/videoplayback?id=271de9756065677e&amp;itag=137&amp;source=youtube&amp;user=android-device-test&amp;sparams=ip,ipbits,expire,id,itag,source,user&amp;ip=0.0.0.0&amp;ipbits=0&amp;expire=19000000000&amp;signature=B0976085596DD42DEA3F08307F76587241CB132B.043B719C039E8B92F45391ADC0BE3665E2332930&amp;key=ik0</value>
+    </entry>
+    <entry key="StreamingMediaPlayerTest-testHTTP_H263_AMR_Video2">
+        <value>http://redirector.gvt1.com/videoplayback?id=c80658495af60617&amp;itag=13&amp;source=youtube&amp;ip=0.0.0.0&amp;ipbits=0&amp;expire=19000000000&amp;sparams=ip,ipbits,expire,id,itag,source&amp;signature=508D82AB36939345BF6B8D0623CB6CABDD9C64C3.9B3336A96846DF38E5343C46AA57F6CF2956E427&amp;key=ik0&amp;user=android-device-test</value>
+    </entry>
+    <entry key="StreamingMediaPlayerTest-testHTTP_H263_AMR_Video1">
+        <value>http://redirector.gvt1.com/videoplayback?id=271de9756065677e&amp;itag=13&amp;source=youtube&amp;ip=0.0.0.0&amp;ipbits=0&amp;expire=19000000000&amp;sparams=ip,ipbits,expire,id,itag,source&amp;signature=5729247E22691EBB3E804DDD523EC42DC17DD8CE.443B81C1E8E6D64E4E1555F568BA46C206507D78&amp;key=ik0&amp;user=android-device-test</value>
+    </entry>
+</dynamicConfig>
diff --git a/tests/tests/media/assets/360pvp9decodertest.webm b/tests/tests/media/assets/360pvp9decodertest.webm
new file mode 100644
index 0000000..e35e7a8
--- /dev/null
+++ b/tests/tests/media/assets/360pvp9decodertest.webm
Binary files differ
diff --git a/tests/tests/media/assets/480ph264decodertest.mp4 b/tests/tests/media/assets/480ph264decodertest.mp4
new file mode 100644
index 0000000..9b7e894
--- /dev/null
+++ b/tests/tests/media/assets/480ph264decodertest.mp4
Binary files differ
diff --git a/tests/tests/media/assets/image_exif_byte_order_ii.jpg b/tests/tests/media/assets/image_exif_byte_order_ii.jpg
new file mode 100644
index 0000000..477cd3a
--- /dev/null
+++ b/tests/tests/media/assets/image_exif_byte_order_ii.jpg
Binary files differ
diff --git a/tests/tests/media/assets/image_exif_byte_order_mm.jpg b/tests/tests/media/assets/image_exif_byte_order_mm.jpg
new file mode 100644
index 0000000..78ac703
--- /dev/null
+++ b/tests/tests/media/assets/image_exif_byte_order_mm.jpg
Binary files differ
diff --git a/tests/tests/media/assets/lg_g4_iso_800.dng b/tests/tests/media/assets/lg_g4_iso_800.dng
new file mode 100644
index 0000000..5fcc720
--- /dev/null
+++ b/tests/tests/media/assets/lg_g4_iso_800.dng
Binary files differ
diff --git a/tests/tests/media/libaudiojni/Android.mk b/tests/tests/media/libaudiojni/Android.mk
index a6c1bfc..d1b1ced 100644
--- a/tests/tests/media/libaudiojni/Android.mk
+++ b/tests/tests/media/libaudiojni/Android.mk
@@ -34,6 +34,9 @@
 LOCAL_C_INCLUDES += $(call include-path-for, libaudiojni) \
 	$(call include-path-for, wilhelm)
 
-LOCAL_SHARED_LIBRARIES := libandroid liblog libnativehelper libOpenSLES libutils
+LOCAL_SHARED_LIBRARIES := libandroid liblog libnativehelper_compat_libc++ libOpenSLES
+LOCAL_CXX_STL := libc++_static
+
+LOCAL_CFLAGS := -Werror -Wall
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/tests/tests/media/libaudiojni/appendix-b-1-2-recording.cpp b/tests/tests/media/libaudiojni/appendix-b-1-2-recording.cpp
index 5f6f3aa..e628c6f 100644
--- a/tests/tests/media/libaudiojni/appendix-b-1-2-recording.cpp
+++ b/tests/tests/media/libaudiojni/appendix-b-1-2-recording.cpp
@@ -56,8 +56,6 @@
     SLDataLocator_IODevice locator_mic;
     SLDeviceVolumeItf devicevolumeItf;
     SLDataSink audioSink;
-    SLDataLocator_URI uri;
-    SLDataFormat_MIME mime;
 
     int i;
     SLboolean required[MAX_NUMBER_INTERFACES];
diff --git a/tests/tests/media/libaudiojni/audio-record-native.cpp b/tests/tests/media/libaudiojni/audio-record-native.cpp
index 9103cdc..f771d9b 100644
--- a/tests/tests/media/libaudiojni/audio-record-native.cpp
+++ b/tests/tests/media/libaudiojni/audio-record-native.cpp
@@ -75,7 +75,11 @@
 
     typedef std::lock_guard<std::recursive_mutex> auto_lock;
 
-    status_t open(uint32_t numChannels, uint32_t sampleRate, bool useFloat, uint32_t numBuffers) {
+    status_t open(uint32_t numChannels,
+                  uint32_t channelMask,
+                  uint32_t sampleRate,
+                  bool useFloat,
+                  uint32_t numBuffers) {
         close();
         auto_lock l(mLock);
         mEngineObj = OpenSLEngine();
@@ -120,7 +124,7 @@
             pcm.bitsPerSample = useFloat ?
                     SL_PCMSAMPLEFORMAT_FIXED_32 : SL_PCMSAMPLEFORMAT_FIXED_16;
             pcm.containerSize = pcm.bitsPerSample;
-            pcm.channelMask = channelCountToMask(numChannels);
+            pcm.channelMask = channelMask;
             pcm.endianness = SL_BYTEORDER_LITTLEENDIAN;
             // additional
             pcm.representation = useFloat ? SL_ANDROID_PCM_REPRESENTATION_FLOAT
@@ -401,7 +405,6 @@
     }
 
     static void BufferQueueCallback(SLBufferQueueItf queueItf, void *pContext) {
-        SLresult res;
         // naked native record
         AudioRecordNative *record = (AudioRecordNative *)pContext;
         record->bufferQueueCallback(queueItf);
@@ -434,10 +437,9 @@
  */
 
 extern "C" jint Java_android_media_cts_AudioRecordNative_nativeTest(
-    JNIEnv * /* env */, jclass /* clazz */,
-    jint numChannels, jint sampleRate, jboolean useFloat,
-    jint msecPerBuffer, jint numBuffers)
-{
+        JNIEnv * /* env */, jclass /* clazz */,
+        jint numChannels, jint channelMask, jint sampleRate,
+        jboolean useFloat, jint msecPerBuffer, jint numBuffers) {
     AudioRecordNative record;
     const size_t frameSize = numChannels * (useFloat ? sizeof(float) : sizeof(int16_t));
     const size_t framesPerBuffer = msecPerBuffer * sampleRate / 1000;
@@ -445,7 +447,7 @@
     status_t res;
     void *buffer = calloc(framesPerBuffer * numBuffers, frameSize);
     for (;;) {
-        res = record.open(numChannels, sampleRate, useFloat, numBuffers);
+        res = record.open(numChannels, channelMask, sampleRate, useFloat, numBuffers);
         if (res != OK) break;
 
         record.logBufferState();
@@ -482,14 +484,14 @@
 }
 
 extern "C" jint Java_android_media_cts_AudioRecordNative_nativeOpen(
-    JNIEnv * /* env */, jclass /* clazz */, jlong jrecord,
-    jint numChannels, jint sampleRate, jboolean useFloat, jint numBuffers)
+        JNIEnv * /* env */, jclass /* clazz */, jlong jrecord,
+        jint numChannels, jint channelMask, jint sampleRate, jboolean useFloat, jint numBuffers)
 {
     auto record = *(shared_pointer<AudioRecordNative> *)jrecord;
     if (record.get() == NULL) {
         return (jint)INVALID_OPERATION;
     }
-    return (jint)record->open(numChannels, sampleRate, useFloat == JNI_TRUE,
+    return (jint) record->open(numChannels, channelMask, sampleRate, useFloat == JNI_TRUE,
             numBuffers);
 }
 
diff --git a/tests/tests/media/libaudiojni/audio-track-native.cpp b/tests/tests/media/libaudiojni/audio-track-native.cpp
index d51a751..ce8bf91 100644
--- a/tests/tests/media/libaudiojni/audio-track-native.cpp
+++ b/tests/tests/media/libaudiojni/audio-track-native.cpp
@@ -70,8 +70,8 @@
 
     typedef std::lock_guard<std::recursive_mutex> auto_lock;
 
-    status_t open(uint32_t numChannels, uint32_t sampleRate, bool useFloat,
-            uint32_t numBuffers) {
+    status_t open(jint numChannels, jint channelMask,
+                  jint sampleRate, jboolean useFloat, jint numBuffers) {
         close();
         auto_lock l(mLock);
         mEngineObj = OpenSLEngine();
@@ -111,7 +111,7 @@
             pcm.bitsPerSample = useFloat ?
                     SL_PCMSAMPLEFORMAT_FIXED_32 : SL_PCMSAMPLEFORMAT_FIXED_16;
             pcm.containerSize = pcm.bitsPerSample;
-            pcm.channelMask = channelCountToMask(numChannels);
+            pcm.channelMask = channelMask;
             pcm.endianness = SL_BYTEORDER_LITTLEENDIAN;
             // additional
             pcm.representation = useFloat ? SL_ANDROID_PCM_REPRESENTATION_FLOAT
@@ -345,7 +345,6 @@
     }
 
     static void BufferQueueCallback(SLBufferQueueItf queueItf, void *pContext) {
-        SLresult res;
         // naked native track
         AudioTrackNative *track = (AudioTrackNative *)pContext;
         track->bufferQueueCallback(queueItf);
@@ -377,7 +376,7 @@
 
 extern "C" jint Java_android_media_cts_AudioTrackNative_nativeTest(
     JNIEnv * /* env */, jclass /* clazz */,
-    jint numChannels, jint sampleRate, jboolean useFloat,
+    jint numChannels, jint channelMask, jint sampleRate, jboolean useFloat,
     jint msecPerBuffer, jint numBuffers)
 {
     AudioTrackNative track;
@@ -387,7 +386,7 @@
     status_t res;
     void *buffer = calloc(framesPerBuffer * numBuffers, frameSize);
     for (;;) {
-        res = track.open(numChannels, sampleRate, useFloat, numBuffers);
+        res = track.open(numChannels, channelMask, sampleRate, useFloat, numBuffers);
         if (res != OK) break;
 
         for (int i = 0; i < numBuffers; ++i) {
@@ -426,14 +425,18 @@
 
 extern "C" jint Java_android_media_cts_AudioTrackNative_nativeOpen(
     JNIEnv * /* env */, jclass /* clazz */, jlong jtrack,
-    jint numChannels, jint sampleRate, jboolean useFloat, jint numBuffers)
+    jint numChannels, jint channelMask, jint sampleRate,
+    jboolean useFloat, jint numBuffers)
 {
     auto track = *(shared_pointer<AudioTrackNative> *)jtrack;
     if (track.get() == NULL) {
         return (jint)INVALID_OPERATION;
     }
-    return (jint)track->open(numChannels, sampleRate, useFloat == JNI_TRUE,
-            numBuffers);
+    return (jint) track->open(numChannels,
+                              channelMask,
+                              sampleRate,
+                              useFloat == JNI_TRUE,
+                              numBuffers);
 }
 
 extern "C" void Java_android_media_cts_AudioTrackNative_nativeClose(
diff --git a/tests/tests/media/libaudiojni/sl-utils.cpp b/tests/tests/media/libaudiojni/sl-utils.cpp
index 1aa89ba..4dbb08d 100644
--- a/tests/tests/media/libaudiojni/sl-utils.cpp
+++ b/tests/tests/media/libaudiojni/sl-utils.cpp
@@ -91,8 +91,10 @@
 
 static SLObjectItf createEngine() {
     static SLEngineOption EngineOption[] = {
+        {
             (SLuint32) SL_ENGINEOPTION_THREADSAFE,
             (SLuint32) SL_BOOLEAN_TRUE
+        },
     };
     // create engine in thread-safe mode
     SLObjectItf engine;
diff --git a/tests/tests/media/libmediandkjni/Android.mk b/tests/tests/media/libmediandkjni/Android.mk
index 23f9f5c..259c95e 100644
--- a/tests/tests/media/libmediandkjni/Android.mk
+++ b/tests/tests/media/libmediandkjni/Android.mk
@@ -22,7 +22,8 @@
 
 LOCAL_SRC_FILES := \
 	native-media-jni.cpp \
-	codec-utils-jni.cpp
+	codec-utils-jni.cpp  \
+	md5_utils.cpp
 
 LOCAL_C_INCLUDES := \
 	$(JNI_H_INCLUDE) \
@@ -30,6 +31,10 @@
 
 LOCAL_C_INCLUDES += $(call include-path-for, mediandk)
 
-LOCAL_SHARED_LIBRARIES := libandroid libnativehelper liblog libmediandk
+LOCAL_SHARED_LIBRARIES := libandroid libnativehelper_compat_libc++ liblog libmediandk
+
+LOCAL_SDK_VERSION := 23
+
+LOCAL_CFLAGS := -Werror -Wall
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/tests/tests/media/libmediandkjni/codec-utils-jni.cpp b/tests/tests/media/libmediandkjni/codec-utils-jni.cpp
index 4f87bb4..cb4363e 100644
--- a/tests/tests/media/libmediandkjni/codec-utils-jni.cpp
+++ b/tests/tests/media/libmediandkjni/codec-utils-jni.cpp
@@ -29,6 +29,8 @@
 
 #include <math.h>
 
+#include "md5_utils.h"
+
 typedef ssize_t offs_t;
 
 struct NativeImage {
@@ -241,7 +243,7 @@
     return img;
 }
 
-extern "C" jint Java_android_media_cts_CodecUtils_getImageChecksum(JNIEnv *env,
+extern "C" jint Java_android_media_cts_CodecUtils_getImageChecksumAlder32(JNIEnv *env,
         jclass /*clazz*/, jobject image)
 {
     NativeImage *img = getNativeImage(env, image);
@@ -266,6 +268,47 @@
     return adler.checksum();
 }
 
+extern "C" jstring Java_android_media_cts_CodecUtils_getImageChecksumMD5(JNIEnv *env,
+        jclass /*clazz*/, jobject image)
+{
+    NativeImage *img = getNativeImage(env, image);
+    if (img == NULL) {
+        return 0;
+    }
+
+    MD5Context md5;
+    char res[33];
+    MD5Init(&md5);
+
+    for (size_t ix = 0; ix < img->numPlanes; ++ix) {
+        const uint8_t *row = img->plane[ix].buffer + img->plane[ix].cropOffs;
+        for (size_t y = img->plane[ix].cropHeight; y > 0; --y) {
+            const uint8_t *col = row;
+            ssize_t colInc = img->plane[ix].colInc;
+            for (size_t x = img->plane[ix].cropWidth; x > 0; --x) {
+                MD5Update(&md5, col, 1);
+                col += colInc;
+            }
+            row += img->plane[ix].rowInc;
+        }
+    }
+
+    static const char hex[16] = {
+        '0', '1', '2', '3', '4', '5', '6', '7',
+        '8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
+    };
+    uint8_t tmp[16];
+
+    MD5Final(tmp, &md5);
+    for (int i = 0; i < 16; i++) {
+        res[i * 2 + 0] = hex[tmp[i] >> 4];
+        res[i * 2 + 1] = hex[tmp[i] & 0xf];
+    }
+    res[32] = 0;
+
+    return env->NewStringUTF(res);
+}
+
 /* tiled copy that loops around source image boundary */
 extern "C" void Java_android_media_cts_CodecUtils_copyFlexYUVImage(JNIEnv *env,
         jclass /*clazz*/, jobject target, jobject source)
diff --git a/tests/tests/media/libmediandkjni/md5_utils.cpp b/tests/tests/media/libmediandkjni/md5_utils.cpp
new file mode 100644
index 0000000..f4f893a
--- /dev/null
+++ b/tests/tests/media/libmediandkjni/md5_utils.cpp
@@ -0,0 +1,241 @@
+/*
+ * This code implements the MD5 message-digest algorithm.
+ * The algorithm is due to Ron Rivest.  This code was
+ * written by Colin Plumb in 1993, no copyright is claimed.
+ * This code is in the public domain; do with it what you wish.
+ *
+ * Equivalent code is available from RSA Data Security, Inc.
+ * This code has been tested against that, and is equivalent,
+ * except that you don't need to include two pages of legalese
+ * with every copy.
+ *
+ * To compute the message digest of a chunk of bytes, declare an
+ * MD5Context structure, pass it to MD5Init, call MD5Update as
+ * needed on buffers full of bytes, and then call MD5Final, which
+ * will fill a supplied 16-byte array with the digest.
+ *
+ * Changed so as no longer to depend on Colin Plumb's `usual.h' header
+ * definitions
+ *  - Ian Jackson <ian@chiark.greenend.org.uk>.
+ * Still in the public domain.
+ */
+
+#include <string.h>   /* for memcpy() */
+
+#include "md5_utils.h"
+
+static void
+byteSwap(UWORD32 *buf, unsigned words) {
+  md5byte *p;
+
+  /* Only swap bytes for big endian machines */
+  int i = 1;
+
+  if (*(char *)&i == 1)
+    return;
+
+  p = (md5byte *)buf;
+
+  do {
+    *buf++ = (UWORD32)((unsigned)p[3] << 8 | p[2]) << 16 |
+             ((unsigned)p[1] << 8 | p[0]);
+    p += 4;
+  } while (--words);
+}
+
+/*
+ * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious
+ * initialization constants.
+ */
+void
+MD5Init(struct MD5Context *ctx) {
+  ctx->buf[0] = 0x67452301;
+  ctx->buf[1] = 0xefcdab89;
+  ctx->buf[2] = 0x98badcfe;
+  ctx->buf[3] = 0x10325476;
+
+  ctx->bytes[0] = 0;
+  ctx->bytes[1] = 0;
+}
+
+/*
+ * Update context to reflect the concatenation of another buffer full
+ * of bytes.
+ */
+void
+MD5Update(struct MD5Context *ctx, md5byte const *buf, unsigned len) {
+  UWORD32 t;
+
+  /* Update byte count */
+
+  t = ctx->bytes[0];
+
+  if ((ctx->bytes[0] = t + len) < t)
+    ctx->bytes[1]++;  /* Carry from low to high */
+
+  t = 64 - (t & 0x3f);  /* Space available in ctx->in (at least 1) */
+
+  if (t > len) {
+    memcpy((md5byte *)ctx->in + 64 - t, buf, len);
+    return;
+  }
+
+  /* First chunk is an odd size */
+  memcpy((md5byte *)ctx->in + 64 - t, buf, t);
+  byteSwap(ctx->in, 16);
+  MD5Transform(ctx->buf, ctx->in);
+  buf += t;
+  len -= t;
+
+  /* Process data in 64-byte chunks */
+  while (len >= 64) {
+    memcpy(ctx->in, buf, 64);
+    byteSwap(ctx->in, 16);
+    MD5Transform(ctx->buf, ctx->in);
+    buf += 64;
+    len -= 64;
+  }
+
+  /* Handle any remaining bytes of data. */
+  memcpy(ctx->in, buf, len);
+}
+
+/*
+ * Final wrapup - pad to 64-byte boundary with the bit pattern
+ * 1 0* (64-bit count of bits processed, MSB-first)
+ */
+void
+MD5Final(md5byte digest[16], struct MD5Context *ctx) {
+  int count = ctx->bytes[0] & 0x3f; /* Number of bytes in ctx->in */
+  md5byte *p = (md5byte *)ctx->in + count;
+
+  /* Set the first char of padding to 0x80.  There is always room. */
+  *p++ = 0x80;
+
+  /* Bytes of padding needed to make 56 bytes (-8..55) */
+  count = 56 - 1 - count;
+
+  if (count < 0) {  /* Padding forces an extra block */
+    memset(p, 0, count + 8);
+    byteSwap(ctx->in, 16);
+    MD5Transform(ctx->buf, ctx->in);
+    p = (md5byte *)ctx->in;
+    count = 56;
+  }
+
+  memset(p, 0, count);
+  byteSwap(ctx->in, 14);
+
+  /* Append length in bits and transform */
+  ctx->in[14] = ctx->bytes[0] << 3;
+  ctx->in[15] = ctx->bytes[1] << 3 | ctx->bytes[0] >> 29;
+  MD5Transform(ctx->buf, ctx->in);
+
+  byteSwap(ctx->buf, 4);
+  memcpy(digest, ctx->buf, 16);
+  memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */
+}
+
+#ifndef ASM_MD5
+
+/* The four core functions - F1 is optimized somewhat */
+
+/* #define F1(x, y, z) (x & y | ~x & z) */
+#define F1(x, y, z) (z ^ (x & (y ^ z)))
+#define F2(x, y, z) F1(z, x, y)
+#define F3(x, y, z) (x ^ y ^ z)
+#define F4(x, y, z) (y ^ (x | ~z))
+
+/* This is the central step in the MD5 algorithm. */
+#define MD5STEP(f,w,x,y,z,in,s) \
+  (w += f(x,y,z) + in, w = (w<<s | w>>(32-s)) + x)
+
+/*
+ * The core of the MD5 algorithm, this alters an existing MD5 hash to
+ * reflect the addition of 16 longwords of new data.  MD5Update blocks
+ * the data and converts bytes into longwords for this routine.
+ */
+void
+MD5Transform(UWORD32 buf[4], UWORD32 const in[16]) {
+  register UWORD32 a, b, c, d;
+
+  a = buf[0];
+  b = buf[1];
+  c = buf[2];
+  d = buf[3];
+
+  MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
+  MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
+  MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
+  MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
+  MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
+  MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
+  MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
+  MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
+  MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
+  MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
+  MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
+  MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
+  MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
+  MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
+  MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
+  MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
+
+  MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
+  MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
+  MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
+  MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
+  MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
+  MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
+  MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
+  MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
+  MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
+  MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
+  MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
+  MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
+  MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
+  MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
+  MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
+  MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
+
+  MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
+  MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
+  MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
+  MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
+  MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
+  MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
+  MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
+  MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
+  MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
+  MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
+  MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
+  MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
+  MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
+  MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
+  MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
+  MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
+
+  MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
+  MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
+  MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
+  MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
+  MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
+  MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
+  MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
+  MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
+  MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
+  MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
+  MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
+  MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
+  MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
+  MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
+  MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
+  MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
+
+  buf[0] += a;
+  buf[1] += b;
+  buf[2] += c;
+  buf[3] += d;
+}
+
+#endif
diff --git a/tests/tests/media/libmediandkjni/md5_utils.h b/tests/tests/media/libmediandkjni/md5_utils.h
new file mode 100644
index 0000000..bd4991b
--- /dev/null
+++ b/tests/tests/media/libmediandkjni/md5_utils.h
@@ -0,0 +1,49 @@
+/*
+ * This is the header file for the MD5 message-digest algorithm.
+ * The algorithm is due to Ron Rivest.  This code was
+ * written by Colin Plumb in 1993, no copyright is claimed.
+ * This code is in the public domain; do with it what you wish.
+ *
+ * Equivalent code is available from RSA Data Security, Inc.
+ * This code has been tested against that, and is equivalent,
+ * except that you don't need to include two pages of legalese
+ * with every copy.
+ *
+ * To compute the message digest of a chunk of bytes, declare an
+ * MD5Context structure, pass it to MD5Init, call MD5Update as
+ * needed on buffers full of bytes, and then call MD5Final, which
+ * will fill a supplied 16-byte array with the digest.
+ *
+ * Changed so as no longer to depend on Colin Plumb's `usual.h'
+ * header definitions
+ *  - Ian Jackson <ian@chiark.greenend.org.uk>.
+ * Still in the public domain.
+ */
+
+#ifndef MD5_UTILS_H_
+#define MD5_UTILS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define md5byte unsigned char
+#define UWORD32 unsigned int
+
+typedef struct MD5Context MD5Context;
+struct MD5Context {
+  UWORD32 buf[4];
+  UWORD32 bytes[2];
+  UWORD32 in[16];
+};
+
+void MD5Init(struct MD5Context *context);
+void MD5Update(struct MD5Context *context, md5byte const *buf, unsigned len);
+void MD5Final(unsigned char digest[16], struct MD5Context *context);
+void MD5Transform(UWORD32 buf[4], UWORD32 const in[16]);
+
+#ifdef __cplusplus
+}  // extern "C"
+#endif
+
+#endif  // MD5_UTILS_H_
diff --git a/tests/tests/media/libmediandkjni/native-media-jni.cpp b/tests/tests/media/libmediandkjni/native-media-jni.cpp
index 2624c25..546ef2b 100644
--- a/tests/tests/media/libmediandkjni/native-media-jni.cpp
+++ b/tests/tests/media/libmediandkjni/native-media-jni.cpp
@@ -30,11 +30,11 @@
 
 #include <android/native_window_jni.h>
 
-#include "ndk/NdkMediaExtractor.h"
-#include "ndk/NdkMediaCodec.h"
-#include "ndk/NdkMediaCrypto.h"
-#include "ndk/NdkMediaFormat.h"
-#include "ndk/NdkMediaMuxer.h"
+#include "media/NdkMediaExtractor.h"
+#include "media/NdkMediaCodec.h"
+#include "media/NdkMediaCrypto.h"
+#include "media/NdkMediaFormat.h"
+#include "media/NdkMediaMuxer.h"
 
 template <class T>
 class simplevector {
@@ -263,7 +263,7 @@
         int t = AMediaExtractor_getSampleTrackIndex(ex);
         if (t >=0) {
             ssize_t bufidx = AMediaCodec_dequeueInputBuffer(codec[t], 5000);
-            ALOGV("track %d, input buffer %d", t, bufidx);
+            ALOGV("track %d, input buffer %zd", t, bufidx);
             if (bufidx >= 0) {
                 size_t bufsize;
                 uint8_t *buf = AMediaCodec_getInputBuffer(codec[t], bufidx, &bufsize);
@@ -408,7 +408,7 @@
 
     while (!sawOutputEOS) {
         ssize_t bufidx = AMediaCodec_dequeueInputBuffer(codec, 5000);
-        ALOGV("input buffer %d", bufidx);
+        ALOGV("input buffer %zd", bufidx);
         if (bufidx >= 0) {
             size_t bufsize;
             uint8_t *buf = AMediaCodec_getInputBuffer(codec, bufidx, &bufsize);
@@ -481,7 +481,7 @@
             return false;
         } else if (!strncmp(mime, "audio/", 6) || !strncmp(mime, "video/", 6)) {
             ssize_t tidx = AMediaMuxer_addTrack(muxer, format);
-            ALOGI("track %d -> %d format %s", i, tidx, s);
+            ALOGI("track %d -> %zd format %s", i, tidx, s);
             AMediaExtractor_selectTrack(ex, i);
         } else {
             ALOGE("expected audio or video mime type, got %s", mime);
@@ -536,7 +536,7 @@
     int64_t duration = 0;
     if (!AMediaFormat_getInt64(format, AMEDIAFORMAT_KEY_DURATION, &duration)
             || duration != 123456789123456789ll) {
-        ALOGE("AMediaFormat_getInt64 fail: %lld", duration);
+        ALOGE("AMediaFormat_getInt64 fail: %lld", (long long) duration);
         return false;
     }
 
diff --git a/tests/tests/media/libndkaudio/Android.mk b/tests/tests/media/libndkaudio/Android.mk
new file mode 100644
index 0000000..29e2118
--- /dev/null
+++ b/tests/tests/media/libndkaudio/Android.mk
@@ -0,0 +1,59 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE    := libndkaudioLib
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_C_INCLUDES := \
+  frameworks/wilhelm/include \
+  frameworks/wilhelm/src/android \
+  $(call include-path-for, wilhelm)
+
+LOCAL_SRC_FILES := \
+  OpenSLESUtils.cpp \
+  AudioPlayer.cpp \
+  AudioSource.cpp \
+  PeriodicAudioSource.cpp \
+  SystemParams.cpp \
+  WaveTableGenerator.cpp \
+  WaveTableOscillator.cpp \
+  com_android_ndkaudio_AudioPlayer.cpp \
+  AudioRecorder.cpp \
+  com_android_ndkaudio_AudioRecorder.cpp
+
+LOCAL_CXX_STL := libc++_static
+
+LOCAL_SHARED_LIBRARIES := liblog libOpenSLES
+
+LOCAL_CFLAGS := -Werror -Wall
+
+include $(BUILD_SHARED_LIBRARY)
+
+#
+# ndkaudio - java
+#
+include $(CLEAR_VARS)
+
+LOCAL_MODULE  := ndkaudio
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_CERTIFICATE := platform
+
+include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/tests/tests/media/libndkaudio/AndroidManifest.xml b/tests/tests/media/libndkaudio/AndroidManifest.xml
new file mode 100644
index 0000000..3fbb9ad
--- /dev/null
+++ b/tests/tests/media/libndkaudio/AndroidManifest.xml
@@ -0,0 +1,10 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.ndkaudio"
+    android:versionCode="1"
+    android:versionName="1.0" >
+
+    <uses-sdk
+        android:minSdkVersion="23"
+        android:targetSdkVersion="23" />
+
+</manifest>
diff --git a/tests/tests/media/libndkaudio/AudioPlayer.cpp b/tests/tests/media/libndkaudio/AudioPlayer.cpp
new file mode 100644
index 0000000..9eb9b54
--- /dev/null
+++ b/tests/tests/media/libndkaudio/AudioPlayer.cpp
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 <assert.h>
+
+#include <android/log.h>
+
+#include <SLES/OpenSLES.h>
+#include <SLES/OpenSLES_Android.h>
+
+#include "AudioPlayer.h"
+
+#include "AudioSource.h"
+#include "SystemParams.h"
+#include "OpenSLESUtils.h"
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+/*
+ * OpenSL ES Stuff
+ */
+static const char* TAG = "AudioPlayer";
+
+// engine interfaces
+static SLObjectItf engineObject = 0;
+static SLEngineItf engineItf;
+
+// output mix interfaces
+static SLObjectItf outputMixObject = 0;
+
+// this callback handler is called every time a buffer finishes playing
+static void bqPlayerCallback(SLAndroidSimpleBufferQueueItf /*bq*/, void *context)
+{
+    // __android_log_print(ANDROID_LOG_INFO, TAG, "bqPlayerCallback()");
+    ((ndkaudio::AudioPlayer*)context)->enqueBuffer();
+}
+
+static void OpenSLEngine() {
+    SLresult result;
+
+    // create engine
+    result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL);
+    assert(SL_RESULT_SUCCESS == result);
+    // __android_log_print(ANDROID_LOG_INFO, TAG, "OpenSLEngine() - engineObject:%p", engineObject);
+
+    // realize the engine
+    result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE);
+    // __android_log_print(ANDROID_LOG_INFO, TAG, "Realize() engine result:%s", getSLErrStr(result));
+   assert(SL_RESULT_SUCCESS == result);
+
+    // get the engine interface, which is needed in order to create other objects
+    result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineItf);
+    // __android_log_print(ANDROID_LOG_INFO, TAG, "GetInterface() engine:%p result:%s", engineItf, getSLErrStr(result));
+    assert(SL_RESULT_SUCCESS == result);
+
+    // get the output mixer
+    result = (*engineItf)->CreateOutputMix(engineItf, &outputMixObject, 0, 0, 0);
+    // __android_log_print(ANDROID_LOG_INFO, TAG, "CreateOutputMix() mix:%p result:%s", outputMixObject, getSLErrStr(result));
+    assert(SL_RESULT_SUCCESS == result);
+
+    // realize the output mix
+    result = (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE);
+    // __android_log_print(ANDROID_LOG_INFO, TAG, "Realize() result:%s", getSLErrStr(result));
+    assert(SL_RESULT_SUCCESS == result);
+}
+
+static void CloseSLEngine() {
+    __android_log_print(ANDROID_LOG_INFO, TAG, "CloseSLEngine()");
+
+    // destroy output mix object, and invalidate all associated interfaces
+    if (outputMixObject != NULL) {
+        (*outputMixObject)->Destroy(outputMixObject);
+        outputMixObject = NULL;
+    }
+
+    if (engineObject != NULL) {
+        (*engineObject)->Destroy(engineObject);
+        engineObject = NULL;
+        engineItf = NULL;
+    }
+}
+
+/*
+ * AudioPlayer
+ */
+namespace ndkaudio {
+
+AudioPlayer::AudioPlayer() {
+    source_ = NULL;
+
+    sampleRate_ = SystemParams::getSampleRate();
+    numChannels_ = 1;
+
+    numPlayBuffFrames_ = SystemParams::getNumBufferFrames();
+
+    playing_ = false;
+
+    time_ = 0;
+
+    bqPlayerObject_ = NULL;
+    bq_ = NULL;
+    bqPlayerPlay_ = NULL;
+    configItf_ = NULL;
+
+    OpenSLEngine();
+}
+
+AudioPlayer::~AudioPlayer() {
+    CloseSLEngine();
+
+    delete[] playBuff_;
+    playBuff_ = 0;
+}
+
+SLresult AudioPlayer::Open(int numChannels, AudioSource* source) {
+    source_ = source;
+
+    SLresult result;
+
+    numChannels_ = numChannels;
+
+    int internalBuffFactor = 1;
+
+    playBuff_ =
+            new float[numPlayBuffFrames_ * numChannels_ * internalBuffFactor];
+    playBuffSizeInBytes_ = numPlayBuffFrames_ * numChannels_ * sizeof(float)
+            * internalBuffFactor;
+
+    sampleRate_ = SystemParams::getSampleRate();
+
+//    __android_log_print(ANDROID_LOG_INFO, TAG,
+//                        "AudioPlayer::Open(chans:%d, rate:%d)", numChannels,
+//                        sampleRate_);
+
+    // configure audio source
+    SLDataLocator_AndroidSimpleBufferQueue loc_bufq = {
+            SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE,    // locatorType
+            1}; // numBuffers
+
+    // SLuint32 chanMask = SL_SPEAKER_FRONT_LEFT|SL_SPEAKER_FRONT_RIGHT;
+    SLAndroidDataFormat_PCM_EX format_pcm = {SL_ANDROID_DATAFORMAT_PCM_EX,	// formatType
+            (SLuint32) numChannels_,			// numChannels
+            (SLuint32)(sampleRate_ * 1000),			// milliSamplesPerSec
+            32,								// bitsPerSample
+            32,								// containerSize;
+            (SLuint32) chanCountToChanMask(numChannels_),  // channelMask
+            SL_BYTEORDER_LITTLEENDIAN,  // endianness
+            SL_ANDROID_PCM_REPRESENTATION_FLOAT};  // representation
+    SLDataSource audioSrc = {&loc_bufq, &format_pcm};
+
+    // configure audio sink
+    SLDataLocator_OutputMix loc_outmix = {SL_DATALOCATOR_OUTPUTMIX,
+            outputMixObject};
+    SLDataSink audioSnk = {&loc_outmix, NULL};
+
+    const SLInterfaceID ids[] =
+            {SL_IID_BUFFERQUEUE, SL_IID_ANDROIDCONFIGURATION};
+    const SLboolean req[] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
+
+    // The Player
+    result = (*engineItf)->CreateAudioPlayer(engineItf, &bqPlayerObject_,
+                                             &audioSrc, &audioSnk,
+                                             sizeof(ids) / sizeof(ids[0]), ids,
+                                             req);
+//    __android_log_print(ANDROID_LOG_INFO, TAG,
+//                        "CreateAudioPlayer() result:%s, bqPlayerObject_:%p",
+//                        getSLErrStr(result), bqPlayerObject_);
+    assert(SL_RESULT_SUCCESS == result);
+
+    return result;
+}
+
+void AudioPlayer::Close() {
+    __android_log_write(ANDROID_LOG_INFO, TAG, "CloseSLPlayer()");
+
+    if (bqPlayerObject_ != NULL) {
+        (*bqPlayerObject_)->Destroy(bqPlayerObject_);
+        bqPlayerObject_ = NULL;
+
+        // invalidate any interfaces
+        bqPlayerPlay_ = NULL;
+        bq_ = NULL;
+    }
+}
+
+SLresult AudioPlayer::RealizePlayer() {
+    SLresult result;
+
+//    __android_log_print(ANDROID_LOG_INFO, TAG, "AudioPlayer::RealizePlayer()");
+
+    result = (*bqPlayerObject_)->Realize(bqPlayerObject_, SL_BOOLEAN_FALSE);
+//    __android_log_print(ANDROID_LOG_INFO, TAG,
+//                        "Realize player object result:%s", getSLErrStr(result));
+    assert(SL_RESULT_SUCCESS == result);
+
+    result = (*bqPlayerObject_)->GetInterface(bqPlayerObject_, SL_IID_PLAY,
+                                              &bqPlayerPlay_);
+//    __android_log_print(ANDROID_LOG_INFO, TAG,
+//                        "get player interface result:%s, bqPlayerPlay_:%p",
+//                        getSLErrStr(result), bqPlayerPlay_);
+    assert(SL_RESULT_SUCCESS == result);
+
+    // The BufferQueue
+    result = (*bqPlayerObject_)->GetInterface(bqPlayerObject_,
+                                              SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
+                                              &bq_);
+//    __android_log_print(ANDROID_LOG_INFO, TAG,
+//                        "get bufferqueue interface:%p result:%s", bq_,
+//                        getSLErrStr(result));
+    assert(SL_RESULT_SUCCESS == result);
+
+    // The register BufferQueue callback
+    result = (*bq_)->RegisterCallback(bq_, bqPlayerCallback, this);
+//    __android_log_print(ANDROID_LOG_INFO, TAG, "register callback result:%s",
+//                        getSLErrStr(result));
+    assert(SL_RESULT_SUCCESS == result);
+
+    return result;
+}
+
+SLresult AudioPlayer::RealizeRoutingProxy() {
+    SLresult result;
+
+    // The Config interface (for routing)
+    result = (*bqPlayerObject_)->GetInterface(bqPlayerObject_,
+                                              SL_IID_ANDROIDCONFIGURATION,
+                                              (void*) &configItf_);
+//    __android_log_print(ANDROID_LOG_INFO, TAG, "get Config result:%s",
+//                        getSLErrStr(result));
+    assert(SL_RESULT_SUCCESS == result);
+
+    return result;
+}
+
+SLresult AudioPlayer::Start() {
+    // __android_log_print(ANDROID_LOG_INFO, TAG, "Start()");
+    playing_ = true;
+
+    // set the player's state to playing
+    SLresult result = (*bqPlayerPlay_)->SetPlayState(bqPlayerPlay_,
+                                                     SL_PLAYSTATE_PLAYING);
+    // __android_log_print(ANDROID_LOG_INFO, TAG, "SetPlayState() result:%s", getSLErrStr(result));
+    assert(SL_RESULT_SUCCESS == result);
+
+    enqueBuffer();
+
+    return result;
+}
+
+void AudioPlayer::Stop() {
+    // __android_log_print(ANDROID_LOG_INFO, TAG, "Stop()");
+    playing_ = false;
+}
+
+SLresult AudioPlayer::enqueBuffer() {
+    // __android_log_print(ANDROID_LOG_INFO, TAG, "AudioPlayer::enqueBuffer()");
+    if (playing_) {
+        //long dataSizeInSamples = source_->getData(time_++, playBuff_,
+        //                                          numPlayBuffFrames_,
+        //                                          source_->getNumChannels());
+        return (*bq_)->Enqueue(bq_, playBuff_, playBuffSizeInBytes_);
+    } else {
+        (*bqPlayerPlay_)->SetPlayState(bqPlayerPlay_, SL_PLAYSTATE_STOPPED);
+        return 0;
+    }
+}
+
+} // namespace ndkaudio
+
diff --git a/tests/tests/media/libndkaudio/AudioPlayer.h b/tests/tests/media/libndkaudio/AudioPlayer.h
new file mode 100644
index 0000000..57d48c7
--- /dev/null
+++ b/tests/tests/media/libndkaudio/AudioPlayer.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 AUDIOPLAYER_H_
+#define AUDIOPLAYER_H_
+
+#include <SLES/OpenSLES.h>
+#include <SLES/OpenSLES_Android.h>
+
+namespace ndkaudio {
+
+class AudioSource;
+
+class AudioPlayer {
+ public:
+    AudioPlayer();
+    ~AudioPlayer();
+
+    SLresult Open(int numChannels, AudioSource* filler);
+    void Close();
+
+    SLresult RealizePlayer();
+    SLresult RealizeRoutingProxy();
+
+    SLresult Start();
+    void Stop();
+
+    inline bool isPlaying() {
+        return playing_;
+    }
+    inline AudioSource* getSource() {
+        return source_;
+    }
+
+    // This is public because it needs to be called by the OpenSL ES callback, but it should not
+    // be called by anyone else.
+    SLresult enqueBuffer();
+
+    SLPlayItf getPlayerObject() {
+        return bqPlayerPlay_;
+    }
+
+    SLAndroidConfigurationItf getConfigItf() {
+        return configItf_;
+    }
+
+ private:
+    // void fill();
+
+    AudioSource* source_;
+    int sampleRate_;
+    int numChannels_;
+
+    float* playBuff_;
+    long numPlayBuffFrames_;
+    long playBuffSizeInBytes_;
+
+    bool playing_;
+
+    long time_;
+
+    // OpenSLES stuff
+    SLObjectItf bqPlayerObject_;
+    SLPlayItf bqPlayerPlay_;
+    SLAndroidSimpleBufferQueueItf bq_;
+    SLAndroidConfigurationItf configItf_;
+};
+
+} // namespace ndkaudio
+
+#endif /* AUDIOPLAYER_H_ */
diff --git a/tests/tests/media/libndkaudio/AudioRecorder.cpp b/tests/tests/media/libndkaudio/AudioRecorder.cpp
new file mode 100644
index 0000000..050c29d
--- /dev/null
+++ b/tests/tests/media/libndkaudio/AudioRecorder.cpp
@@ -0,0 +1,245 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 <assert.h>
+
+#include <android/log.h>
+
+#include <SLES/OpenSLES.h>
+#include <SLES/OpenSLES_Android.h>
+
+#include "AudioRecorder.h"
+
+#include "AudioSink.h"
+#include "SystemParams.h"
+#include "OpenSLESUtils.h"
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+#define ARRAYSIZE(a) sizeof((a))/sizeof((a)[0])
+
+using namespace ndkaudio;
+
+//static const char* const TAG = "AudioRecorder";
+
+#define NB_BUFFERS_IN_QUEUE 1
+
+static void RecCallback(SLRecordItf /*recorderItf_*/, void * /*context*/, SLuint32 event)
+{
+    if (SL_RECORDEVENT_HEADATNEWPOS & event) {
+        // __android_log_print(ANDROID_LOG_INFO, TAG, "SL_RECORDEVENT_HEADATNEWPOS");
+    }
+
+    if (SL_RECORDEVENT_HEADATMARKER & event) {
+        // __android_log_print(ANDROID_LOG_INFO, TAG, "SL_RECORDEVENT_HEADATMARKER");
+    }
+
+    if (SL_RECORDEVENT_BUFFER_FULL & event) {
+        // __android_log_print(ANDROID_LOG_INFO, TAG, "SL_RECORDEVENT_BUFFER_FULL");
+    }
+}
+
+#define BUFFER_SIZE_IN_FRAMES	8192
+
+static float* recBuffer = NULL;
+
+static void RecBufferQueueCallback(SLAndroidSimpleBufferQueueItf /*queueItf*/, void * context)
+{
+    AudioRecorder* recorder = (AudioRecorder*)context;
+    // __android_log_print(ANDROID_LOG_INFO, TAG, "RecBufferQueueCallback()");
+    recorder->enqueBuffer();
+}
+
+/*
+ * The OpenSL ES code was derived from:
+ *   frameworks/wilhelm/tests/examples/slesTestRecBuffQueue.cpp
+ */
+AudioRecorder::AudioRecorder()
+ : sink_(NULL),
+   recording_(false),
+   sampleRate_(48000),
+   numChannels_(0),
+   numBufferSamples_(0),
+   engineObj_(NULL),
+   engineItf_(NULL),
+   recorderObj_(NULL),
+   recorderItf_(NULL),
+   recBuffQueueItf_(NULL),
+   configItf_(NULL)
+{}
+
+AudioRecorder::~AudioRecorder() {}
+
+void AudioRecorder::Open(int numChannels, AudioSink* sink) {
+    sink_ = sink;
+    numChannels_ = numChannels;
+    // __android_log_print(ANDROID_LOG_INFO, TAG, "AudioRecorder::Open() - numChannels:%d", numChannels);
+
+    SLresult result;
+
+    numBufferSamples_ = BUFFER_SIZE_IN_FRAMES * numChannels_;
+    recBuffer = new float[numBufferSamples_];
+
+    SLEngineOption EngineOption[] = {
+            {(SLuint32) SL_ENGINEOPTION_THREADSAFE, (SLuint32) SL_BOOLEAN_TRUE}
+    };
+
+    /* Create the OpenSL ES Engine object */
+    result = slCreateEngine(&engineObj_, 1, EngineOption, 0, NULL, NULL);
+    assert(SL_RESULT_SUCCESS == result);
+    // __android_log_print(ANDROID_LOG_INFO, TAG, "slCreateEngine() - engineObj_:%p", engineObj_);
+
+    /* Realizing the SL Engine in synchronous mode. */
+    result = (*engineObj_)->Realize(engineObj_, SL_BOOLEAN_FALSE);
+    assert(SL_RESULT_SUCCESS == result);
+    // __android_log_print(ANDROID_LOG_INFO, TAG, "(*engineObj_)->Realize()");
+
+    result = (*engineObj_)->GetInterface(engineObj_, SL_IID_ENGINE, (void*)&engineItf_);
+    assert(SL_RESULT_SUCCESS == result);
+    // __android_log_print(ANDROID_LOG_INFO, TAG, "GetInterface() - engineItf_:%p", engineItf_);
+
+    // Configuration of the recorder
+    SLboolean required[] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
+    SLInterfaceID iidArray[] = {SL_IID_ANDROIDSIMPLEBUFFERQUEUE, SL_IID_ANDROIDCONFIGURATION};
+
+    SLDataLocator_IODevice ioDevice;
+    ioDevice.locatorType = SL_DATALOCATOR_IODEVICE;
+    ioDevice.deviceType = SL_IODEVICE_AUDIOINPUT;
+    ioDevice.deviceID = SL_DEFAULTDEVICEID_AUDIOINPUT;
+    ioDevice.device = NULL;
+
+    SLDataSource recSource;
+    recSource.pLocator = (void *) &ioDevice;
+    recSource.pFormat = NULL;
+
+    /* Setup the (OpenSL ES) data sink */
+    SLDataLocator_AndroidSimpleBufferQueue recBuffQueue;
+    recBuffQueue.locatorType = SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE;
+    recBuffQueue.numBuffers = NB_BUFFERS_IN_QUEUE;
+
+    SLAndroidDataFormat_PCM_EX pcm;
+    pcm.formatType = SL_ANDROID_DATAFORMAT_PCM_EX;
+    pcm.numChannels = numChannels_;
+    pcm.sampleRate = sampleRate_ * 1000; // milliHz
+    pcm.bitsPerSample = 32;
+    pcm.containerSize = 32;
+    pcm.channelMask = chanCountToChanMask(numChannels_);
+    pcm.endianness = SL_BYTEORDER_LITTLEENDIAN;
+    pcm.representation = SL_ANDROID_PCM_REPRESENTATION_FLOAT;
+
+    SLDataSink recDest;
+    recDest.pLocator = (void *) &recBuffQueue;
+    recDest.pFormat = (void * ) &pcm;
+
+    /* Create the audio recorder */
+    result = (*engineItf_)->CreateAudioRecorder(engineItf_, &recorderObj_, &recSource, &recDest,
+            ARRAYSIZE(iidArray), iidArray, required);
+    assert(SL_RESULT_SUCCESS == result);
+    // __android_log_print(ANDROID_LOG_INFO, TAG, "CreateAudioRecorder() - recorderObj_:%p", recorderObj_);
+}
+
+void AudioRecorder::Close() {
+    /* Shutdown OpenSL ES */
+    (*engineObj_)->Destroy(engineObj_);
+    engineObj_ = 0;
+}
+
+void AudioRecorder::RealizeRecorder() {
+    SLresult result;
+
+    /* Realize the recorder in synchronous mode. */
+    result = (*recorderObj_)->Realize(recorderObj_, SL_BOOLEAN_FALSE);
+    assert(SL_RESULT_SUCCESS == result);
+    // __android_log_print(ANDROID_LOG_INFO, TAG, "Recorder realized");
+
+    /* Get the record interface which is implicit */
+    result = (*recorderObj_)->GetInterface(recorderObj_, SL_IID_RECORD, (void*)&recorderItf_);
+    assert(SL_RESULT_SUCCESS == result);
+    // __android_log_print(ANDROID_LOG_INFO, TAG, "GetInterface() recorderItf_:%p", recorderItf_);
+
+    /* Set up the recorder callback to get events during the recording */
+    // __android_log_print(ANDROID_LOG_INFO, TAG, "SetMarkerPosition()");
+    result = (*recorderItf_)->SetMarkerPosition(recorderItf_, 2000);
+    assert(SL_RESULT_SUCCESS == result);
+
+    // __android_log_print(ANDROID_LOG_INFO, TAG, "SetPositionUpdatePeriod()");
+    result = (*recorderItf_)->SetPositionUpdatePeriod(recorderItf_, 500);
+    assert(SL_RESULT_SUCCESS == result);
+
+    // __android_log_print(ANDROID_LOG_INFO, TAG, "SetCallbackEventsMask()");
+    result = (*recorderItf_)->SetCallbackEventsMask(recorderItf_, SL_RECORDEVENT_HEADATMARKER | SL_RECORDEVENT_HEADATNEWPOS);
+    assert(SL_RESULT_SUCCESS == result);
+
+    // __android_log_print(ANDROID_LOG_INFO, TAG, "RegisterCallback() - Events");
+    result = (*recorderItf_)->RegisterCallback(recorderItf_, RecCallback, NULL);
+    assert(SL_RESULT_SUCCESS == result);
+
+    /* Get the buffer queue interface which was explicitly requested */
+    result = (*recorderObj_)->GetInterface(recorderObj_, SL_IID_ANDROIDSIMPLEBUFFERQUEUE, (void*)&recBuffQueueItf_);
+    assert(SL_RESULT_SUCCESS == result);
+    // __android_log_print(ANDROID_LOG_INFO, TAG, "GetInterface() recBuffQueueItf_:%p", recBuffQueueItf_);
+
+    result = (*recBuffQueueItf_)->RegisterCallback(recBuffQueueItf_, RecBufferQueueCallback, (void*)this);
+    assert(SL_RESULT_SUCCESS == result);
+    // __android_log_print(ANDROID_LOG_INFO, TAG, "RegisterCallback() - Buffers");
+}
+
+void AudioRecorder::RealizeRoutingProxy() {
+    SLresult result;
+    // The Config interface (for routing)
+    result = (*recorderObj_)->GetInterface(recorderObj_, SL_IID_ANDROIDCONFIGURATION, (void*)&configItf_);
+    // __android_log_print(ANDROID_LOG_INFO, TAG, "get Config result:%s", getSLErrStr(result));
+    assert(SL_RESULT_SUCCESS == result);
+}
+
+void AudioRecorder::Start() {
+    SLresult result;
+
+    /* Enqueue buffers to map the region of memory allocated to store the recorded data */
+    // __android_log_print(ANDROID_LOG_INFO, TAG, "Enqueueing buffer");
+    //int bufferSizeInBytes = BUFFER_SIZE_IN_FRAMES * numChannels_ * sizeof(float);
+
+    enqueBuffer();
+
+    /* ------------------------------------------------------ */
+    /* Start recording */
+    // __android_log_print(ANDROID_LOG_INFO, TAG, "Start Recording");
+    recording_ = true;
+    result = (*recorderItf_)->SetRecordState(recorderItf_, SL_RECORDSTATE_RECORDING);
+    assert(SL_RESULT_SUCCESS == result);
+}
+
+void AudioRecorder::Stop() {
+    recording_ = false;
+
+    SLresult result;
+    result = (*recorderItf_)->SetRecordState(recorderItf_, SL_RECORDSTATE_STOPPED);
+}
+
+SLresult AudioRecorder::enqueBuffer() {
+    SLresult result;
+    int bufferSizeInBytes = numBufferSamples_ * sizeof(float);
+    // __android_log_print(ANDROID_LOG_INFO, TAG, "Enque %d bytes", bufferSizeInBytes);
+    result = (*recBuffQueueItf_)->Enqueue(recBuffQueueItf_, recBuffer, bufferSizeInBytes);
+    assert(SL_RESULT_SUCCESS == result);
+
+    return result;
+}
+
+float* AudioRecorder::GetRecordBuffer() {
+    return recBuffer;
+}
diff --git a/tests/tests/media/libndkaudio/AudioRecorder.h b/tests/tests/media/libndkaudio/AudioRecorder.h
new file mode 100644
index 0000000..93a03c3
--- /dev/null
+++ b/tests/tests/media/libndkaudio/AudioRecorder.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 _AUDIORECORDER_H_
+#define _AUDIORECORDER_H_
+
+#include <SLES/OpenSLES.h>
+#include <SLES/OpenSLES_Android.h>
+
+namespace ndkaudio {
+
+class AudioSink;
+
+class AudioRecorder {
+ public:
+    AudioRecorder();
+    ~AudioRecorder();
+
+    void Open(int numChannels, AudioSink* sink);
+    void Close();
+
+    void RealizeRecorder();
+    void RealizeRoutingProxy();
+
+    void Start();
+    void Stop();
+
+    inline bool isRecording() {
+        return recording_;
+    }
+    inline AudioSink* getSink() {
+        return sink_;
+    }
+
+    SLAndroidConfigurationItf getConfigItf() {
+        return configItf_;
+    }
+
+    // public, but don't call directly (called by the OSLES callback)
+    SLresult enqueBuffer();
+
+    int GetNumBufferSamples() {
+        return numBufferSamples_;
+    }
+    float* GetRecordBuffer();
+
+ private:
+    AudioSink* sink_;
+    bool recording_;
+
+    int sampleRate_;
+    int numChannels_;
+
+    int numBufferSamples_;
+
+    // OpenSL ES stuff
+    // - Engine
+    SLObjectItf engineObj_;
+    SLEngineItf engineItf_;
+
+    // - Recorder
+    SLObjectItf recorderObj_;
+    SLRecordItf recorderItf_;
+    SLAndroidSimpleBufferQueueItf recBuffQueueItf_;
+    SLAndroidConfigurationItf configItf_;
+};
+
+} // namespace ndkaudio
+
+#endif // _AUDIORECORDER_H_
diff --git a/tests/tests/media/libndkaudio/AudioSink.h b/tests/tests/media/libndkaudio/AudioSink.h
new file mode 100644
index 0000000..933abc9
--- /dev/null
+++ b/tests/tests/media/libndkaudio/AudioSink.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 _AUDIOSINK_H_
+#define _AUDIOSINK_H_
+
+namespace ndkaudio {
+
+class AudioSink {
+ public:
+    AudioSink();
+    virtual ~AudioSink();
+
+    virtual bool put(float * buff, int numFrames, int numChannels) =0;
+};
+
+}  // namespace ndkaudio
+
+#endif // _AUDIOSINK_H_
+
diff --git a/tests/tests/media/libndkaudio/AudioSource.cpp b/tests/tests/media/libndkaudio/AudioSource.cpp
new file mode 100644
index 0000000..6e4fbbc
--- /dev/null
+++ b/tests/tests/media/libndkaudio/AudioSource.cpp
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 "AudioSource.h"
+
+#include "SystemParams.h"
+
+namespace ndkaudio {
+
+//static const char* const TAG = "AudioSource";
+
+AudioSource::AudioSource(int numChannels)
+ : numChannels_(numChannels),
+   lastReadSize_(0),
+   numBuffFrames_(SystemParams::getNumBufferFrames())
+{}
+
+AudioSource::~AudioSource()
+{}
+
+} // namespace ndkaudio
diff --git a/tests/tests/media/libndkaudio/AudioSource.h b/tests/tests/media/libndkaudio/AudioSource.h
new file mode 100644
index 0000000..1d192b4
--- /dev/null
+++ b/tests/tests/media/libndkaudio/AudioSource.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 AUDIOSOURCE_H_
+#define AUDIOSOURCE_H_
+
+namespace ndkaudio {
+
+class AudioSource {
+ public:
+    AudioSource(int numChannels);
+    virtual ~AudioSource();
+
+    int getLastReadSize() {
+        return lastReadSize_;
+    }
+    int getNumChannels() {
+        return numChannels_;
+    }
+    int getNumBufferFrames() {
+        return numBuffFrames_;
+    }
+
+    virtual int getData(long time, float * buff, int numFrames,
+                        int numChannels) =0;
+
+ protected:
+    int numChannels_;
+    int lastReadSize_;
+    int numBuffFrames_;
+};
+
+} //namespace ndkaudio
+
+#endif /* AUDIOSOURCE_H_ */
diff --git a/tests/tests/media/libndkaudio/OpenSLESUtils.cpp b/tests/tests/media/libndkaudio/OpenSLESUtils.cpp
new file mode 100644
index 0000000..7302ef5
--- /dev/null
+++ b/tests/tests/media/libndkaudio/OpenSLESUtils.cpp
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 "OpenSLESUtils.h"
+
+#include <SLES/OpenSLES.h>
+#include <SLES/OpenSLES_Android.h>
+
+/*
+ * OSLES Helpers
+ */
+static const char* errStrings[] = {
+        "SL_RESULT_SUCCESS",	// 0)
+        "SL_RESULT_PRECONDITIONS_VIOLATE",  // 1
+        "SL_RESULT_PARAMETER_INVALID",      // 2
+        "SL_RESULT_MEMORY_FAILURE",         // 3
+        "SL_RESULT_RESOURCE_ERROR",         // 4
+        "SL_RESULT_RESOURCE_LOST",          // 5
+        "SL_RESULT_IO_ERROR",               // 6
+        "SL_RESULT_BUFFER_INSUFFICIENT",    // 7
+        "SL_RESULT_CONTENT_CORRUPTED",      // 8
+        "SL_RESULT_CONTENT_UNSUPPORTED",    // 9
+        "SL_RESULT_CONTENT_NOT_FOUND",      // 10
+        "SL_RESULT_PERMISSION_DENIED",      // 11
+        "SL_RESULT_FEATURE_UNSUPPORTED",    // 12
+        "SL_RESULT_INTERNAL_ERROR",         // 13
+        "SL_RESULT_UNKNOWN_ERROR",          // 14
+        "SL_RESULT_OPERATION_ABORTED",      // 15
+        "SL_RESULT_CONTROL_LOST"            // 16
+};
+
+const char * getSLErrStr(int code) {
+    return errStrings[code];
+}
+
+// These will wind up in <SLES/OpenSLES_Android.h>
+#define SL_ANDROID_SPEAKER_QUAD (SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT \
+ | SL_SPEAKER_BACK_LEFT | SL_SPEAKER_BACK_RIGHT)
+
+#define SL_ANDROID_SPEAKER_5DOT1 (SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT \
+ | SL_SPEAKER_FRONT_CENTER  | SL_SPEAKER_LOW_FREQUENCY| SL_SPEAKER_BACK_LEFT \
+ | SL_SPEAKER_BACK_RIGHT)
+
+#define SL_ANDROID_SPEAKER_7DOT1 (SL_ANDROID_SPEAKER_5DOT1 | SL_SPEAKER_SIDE_LEFT \
+ |SL_SPEAKER_SIDE_RIGHT)
+
+int chanCountToChanMask(int chanCount) {
+    int channelMask = 0;
+
+    switch (chanCount) {
+        case 1:
+            channelMask = SL_SPEAKER_FRONT_CENTER;
+            break;
+
+        case 2:
+            channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
+            break;
+
+        case 4:  // Quad
+            channelMask = SL_ANDROID_SPEAKER_QUAD;
+            break;
+
+        case 6:  // 5.1
+            channelMask = SL_ANDROID_SPEAKER_5DOT1;
+            break;
+
+        case 8:  // 7.1
+            channelMask = SL_ANDROID_SPEAKER_7DOT1;
+            break;
+    }
+    return channelMask;
+}
diff --git a/tests/tests/media/libndkaudio/OpenSLESUtils.h b/tests/tests/media/libndkaudio/OpenSLESUtils.h
new file mode 100644
index 0000000..89dde3d
--- /dev/null
+++ b/tests/tests/media/libndkaudio/OpenSLESUtils.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 _OPENSLESUTILS_H_
+#define _OPENSLESUTILS_H_
+
+const char * getSLErrStr(int code);
+int chanCountToChanMask(int chanCount);
+
+#endif // _OPENSLESUTILS_H_
diff --git a/tests/tests/media/libndkaudio/PeriodicAudioSource.cpp b/tests/tests/media/libndkaudio/PeriodicAudioSource.cpp
new file mode 100644
index 0000000..a861bb8
--- /dev/null
+++ b/tests/tests/media/libndkaudio/PeriodicAudioSource.cpp
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 "PeriodicAudioSource.h"
+
+namespace ndkaudio {
+
+PeriodicAudioSource::PeriodicAudioSource(int numChannels)
+ : AudioSource(numChannels), targetFreq_(1000.0f) {
+}
+
+} // namespace ndkaudio
diff --git a/tests/tests/media/libndkaudio/PeriodicAudioSource.h b/tests/tests/media/libndkaudio/PeriodicAudioSource.h
new file mode 100644
index 0000000..ebb4a02
--- /dev/null
+++ b/tests/tests/media/libndkaudio/PeriodicAudioSource.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 PERIODICAUDIOSOURCE_H_
+#define PERIODICAUDIOSOURCE_H_
+
+#include "AudioSource.h"
+
+namespace ndkaudio {
+
+class PeriodicAudioSource : public AudioSource {
+ public:
+    PeriodicAudioSource(int numChannels);
+
+    void setAudioFrequency(float freq) {
+        targetFreq_ = freq;
+    }
+
+    float calcCurrentFreq(long time);
+
+ protected:
+    float targetFreq_;
+};
+
+} // namespace ndkaudio
+
+#endif /* PERIODICAUDIOSOURCE_H_ */
diff --git a/tests/tests/media/libndkaudio/SystemParams.cpp b/tests/tests/media/libndkaudio/SystemParams.cpp
new file mode 100644
index 0000000..c7f58f4
--- /dev/null
+++ b/tests/tests/media/libndkaudio/SystemParams.cpp
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 "SystemParams.h"
+
+namespace ndkaudio {
+
+int SystemParams::sysSampleRate_ = 48000;
+int SystemParams::sysBuffFrames_ = 480;
+
+void SystemParams::init(int sysSampleRate, int sysBuffFrames) {
+    sysSampleRate_ = sysSampleRate;
+    sysBuffFrames_ = sysBuffFrames;
+}
+
+} // namespace ndkaudio
diff --git a/tests/tests/media/libndkaudio/SystemParams.h b/tests/tests/media/libndkaudio/SystemParams.h
new file mode 100644
index 0000000..96e9af0
--- /dev/null
+++ b/tests/tests/media/libndkaudio/SystemParams.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 SYSTEMPARAMS_H_
+#define SYSTEMPARAMS_H_
+
+namespace ndkaudio {
+
+class SystemParams {
+ public:
+    static void init(int sysSampleRate, int sysBuffFrames);
+
+    static int getSampleRate() {
+        return sysSampleRate_;
+    }
+    static int getNumBufferFrames() {
+        return sysBuffFrames_;
+    }
+
+ private:
+    static int sysSampleRate_;
+    static int sysBuffFrames_;
+};
+
+} // namespace ndkaudio
+
+#endif /* SYSTEMPARAMS_H_ */
diff --git a/tests/tests/media/libndkaudio/WaveTableGenerator.cpp b/tests/tests/media/libndkaudio/WaveTableGenerator.cpp
new file mode 100644
index 0000000..5df87e7
--- /dev/null
+++ b/tests/tests/media/libndkaudio/WaveTableGenerator.cpp
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 <math.h>
+
+#include <android/log.h>
+
+#include "WaveTableGenerator.h"
+
+static const float kPI = 3.14159265359;	// close enough
+
+//static const char* const TAG = "WaveTableGenerator";
+
+namespace ndkaudio {
+
+float* WaveTableGenerator::genSinWave(int size, float maxValue) {
+    return genSinWave(size, maxValue, new float[size]);
+}
+
+float* WaveTableGenerator::genSinWave(int size, float maxValue, float* tbl) {
+    float incr = (kPI * 2.0f) / (float) size;
+    float val = 0.0f;
+    for (int index = 0; index < size; index++) {
+        tbl[index] = (float) sin(val) * maxValue;
+        val += incr;
+    }
+
+    return tbl;
+}
+
+} // namespace ndkaudio
diff --git a/tests/tests/media/libndkaudio/WaveTableGenerator.h b/tests/tests/media/libndkaudio/WaveTableGenerator.h
new file mode 100644
index 0000000..fbe188a
--- /dev/null
+++ b/tests/tests/media/libndkaudio/WaveTableGenerator.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 WAVETABLEGENERATOR_H_
+#define WAVETABLEGENERATOR_H_
+
+namespace ndkaudio {
+
+class WaveTableGenerator {
+ public:
+    // SINE
+    static float* genSinWave(int size, float maxValue);
+    static float* genSinWave(int size, float maxValue, float* tbl);
+};
+
+}  // namespace ndkaudio
+
+#endif /* WAVETABLEGENERATOR_H_ */
diff --git a/tests/tests/media/libndkaudio/WaveTableOscillator.cpp b/tests/tests/media/libndkaudio/WaveTableOscillator.cpp
new file mode 100644
index 0000000..2b7f850
--- /dev/null
+++ b/tests/tests/media/libndkaudio/WaveTableOscillator.cpp
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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/log.h>
+
+//static const char * const TAG = "WaveTableOscillator";
+
+#include "WaveTableOscillator.h"
+#include "SystemParams.h"
+
+namespace ndkaudio {
+
+WaveTableOscillator::WaveTableOscillator(int numChannels, float* waveTable,
+                                         int waveTableSize)
+ : PeriodicAudioSource(numChannels),
+   waveTable_(waveTable),
+   waveTableSize_(waveTableSize),
+   fN_(0.0f),
+   srcPhase_(0.0f),
+   prevFillTime_(0)
+{
+    setWaveTable(waveTable, waveTableSize);
+}
+
+void WaveTableOscillator::setWaveTable(float* waveTable, int waveTableSize) {
+    waveTable_ = waveTable;
+    waveTableSize_ = waveTableSize - 1;
+
+    // The frequency that would be played if we took every sample from the table and
+    // played it at the system sample-rate. The "Nominal" frequency
+    fN_ = SystemParams::getSampleRate() / (float) waveTableSize_;
+}
+
+int WaveTableOscillator::getData(long time, float* outBuff, int numFrames,
+                                 int /*outChans*/) {
+    prevFillTime_ = time;
+
+    // Frequency - main
+    float currentFreq = targetFreq_;
+
+    float phaseIncr = currentFreq / fN_;
+
+//	__android_log_print(ANDROID_LOG_INFO, TAG, "getData() freq:%f, fN_:%f, phs:%f incr:%f", currentFreq, fN_, srcPhase_, phaseIncr);
+
+    if (numChannels_ == 1) {
+        // calculate wave values
+        for (int dstIndex = 0; dstIndex < numFrames; ++dstIndex) {
+            // 'mod' back into the waveTable
+            if (srcPhase_ >= (float) waveTableSize_) {
+                srcPhase_ -= (float) waveTableSize_;
+            }
+
+            // linear-interpolate
+            int srcIndex = (int) srcPhase_;
+            float delta0 = srcPhase_ - srcIndex;
+            float delta1 = 1.0f - delta0;
+            outBuff[dstIndex] = ((waveTable_[srcIndex] * delta1)
+                    + (waveTable_[srcIndex + 1] * delta0)) / 2.0f;
+
+            srcPhase_ += phaseIncr;
+        }
+    } else if (numChannels_ == 2) {
+        // calculate wave values
+        int dstIndex = 0;
+        for (int frameIndex = 0; frameIndex < numFrames; frameIndex++) {
+            // 'mod' back into the waveTable
+            if (srcPhase_ >= (float) waveTableSize_) {
+                srcPhase_ -= (float) waveTableSize_;
+            }
+
+            // linear-interpolate
+            int srcIndex = (int) srcPhase_;
+            float delta0 = srcPhase_ - srcIndex;
+            float delta1 = 1.0f - delta0;
+            float out = ((waveTable_[srcIndex] * delta1)
+                    + (waveTable_[srcIndex + 1] * delta0)) / 2.0f;
+
+            outBuff[dstIndex++] = out;
+            outBuff[dstIndex++] = out;
+
+            srcPhase_ += phaseIncr;
+        }
+    }
+
+//	__android_log_print(ANDROID_LOG_INFO, TAG, "    %d samples", numSamples);
+    return numFrames;
+}
+
+} // namespace ndkaudio
diff --git a/tests/tests/media/libndkaudio/WaveTableOscillator.h b/tests/tests/media/libndkaudio/WaveTableOscillator.h
new file mode 100644
index 0000000..aaccaf3
--- /dev/null
+++ b/tests/tests/media/libndkaudio/WaveTableOscillator.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 WAVETABLEOSCILLATOR_H_
+#define WAVETABLEOSCILLATOR_H_
+
+#include "PeriodicAudioSource.h"
+
+namespace ndkaudio {
+
+/*
+ * The assumption here is that the provided wave table contains 1 cycle of the wave
+ * and that the first and last samples are the same.
+ */
+class WaveTableOscillator : public PeriodicAudioSource {
+ public:
+    WaveTableOscillator(int numChannels, float* waveTable, int waveTableSize);
+
+    void setWaveTable(float* waveTable, int waveTableSize);
+
+    int getData(long time, float* outBuff, int numFrames, int outChans);
+
+ private:
+    float* waveTable_;
+    int waveTableSize_;
+
+    // 'nominal' frequency (i.e. how many times we step through the
+    // 1-cycle wave table in a second
+    float fN_;
+
+    // current pointer into the wave table
+    float srcPhase_;
+
+    // profiling
+    long prevFillTime_;
+};
+
+} // namespace ndkaudio
+
+#endif /* WAVETABLEOSCILLATOR_H_ */
diff --git a/tests/tests/media/libndkaudio/com_android_ndkaudio_AudioPlayer.cpp b/tests/tests/media/libndkaudio/com_android_ndkaudio_AudioPlayer.cpp
new file mode 100644
index 0000000..ade0e34
--- /dev/null
+++ b/tests/tests/media/libndkaudio/com_android_ndkaudio_AudioPlayer.cpp
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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/log.h>
+
+#include "com_android_ndkaudio_AudioPlayer.h"
+
+#include "AudioPlayer.h"
+#include "WaveTableGenerator.h"
+#include "WaveTableOscillator.h"
+#include "SystemParams.h"
+
+static const char* TAG = "_com_android_ndkaudio_AudioPlayer_";
+
+using namespace ndkaudio;
+
+static int numChannels = 2;
+static int waveTableSize = 0;
+static float * waveTable = 0;
+
+static WaveTableOscillator* waveTableSource;
+static AudioPlayer* nativePlayer;
+
+static SLresult lastSLResult = 0;
+
+extern "C" {
+
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioPlayer_Create(JNIEnv*, jobject) {
+  __android_log_print(ANDROID_LOG_INFO, TAG, "AudioPlayer_Create() ...");
+
+  if (nativePlayer == 0) {
+      waveTableSize = SystemParams::getNumBufferFrames();
+      waveTable = WaveTableGenerator::genSinWave(waveTableSize, 1.0f);
+      waveTableSource = new WaveTableOscillator(numChannels, waveTable, waveTableSize);
+
+      nativePlayer = new AudioPlayer();
+      nativePlayer->Open(numChannels, waveTableSource);
+  }
+}
+
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioPlayer_Destroy(JNIEnv*, jobject) {
+  __android_log_print(ANDROID_LOG_INFO, TAG, "AudioPlayer_Destroy() ...");
+  nativePlayer->Close();
+}
+
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioPlayer_RealizePlayer(JNIEnv*, jobject) {
+    __android_log_print(ANDROID_LOG_INFO, TAG, "AudioPlayer_RealizePlayer() ...");
+    nativePlayer->RealizePlayer();
+  }
+
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioPlayer_RealizeRoutingProxy(JNIEnv*, jobject) {
+    __android_log_print(ANDROID_LOG_INFO, TAG, "AudioPlayer_RealizeRoutingProxy() ...");
+    nativePlayer->RealizeRoutingProxy();
+  }
+
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioPlayer_Start(JNIEnv*, jobject) {
+  __android_log_print(ANDROID_LOG_INFO, TAG, "AudioPlayer_Start() ...");
+  nativePlayer->Start();
+}
+
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioPlayer_Stop(JNIEnv*, jobject) {
+  __android_log_print(ANDROID_LOG_INFO, TAG, "AudioPlayer_Stop() ...");
+  nativePlayer->Stop();
+}
+
+JNIEXPORT jobject JNICALL Java_com_android_ndkaudio_AudioPlayer_GetRoutingInterface(JNIEnv*, jobject) {
+  __android_log_print(ANDROID_LOG_INFO, TAG, "AudioPlayer_GetRoutingInterface() ...");
+
+  SLAndroidConfigurationItf configItf = nativePlayer->getConfigItf();
+  __android_log_print(ANDROID_LOG_INFO, TAG, "  configItf:%p", configItf);
+  jobject routingObj = 0;
+  lastSLResult = (*configItf)->AcquireJavaProxy(configItf, SL_ANDROID_JAVA_PROXY_ROUTING, &routingObj);
+  __android_log_print(ANDROID_LOG_INFO, TAG, "  routingObj:%p", routingObj);
+  return routingObj;
+}
+
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioPlayer_ReleaseRoutingInterface(JNIEnv*, jobject, jobject /*proxyObj*/) {
+  __android_log_print(ANDROID_LOG_INFO, TAG, "AudioPlayer_ReleaseRoutingInterface() ...");
+
+  SLAndroidConfigurationItf configItf = nativePlayer->getConfigItf();
+  lastSLResult = (*configItf)->ReleaseJavaProxy(configItf, SL_ANDROID_JAVA_PROXY_ROUTING/*, proxyObj*/);
+}
+
+JNIEXPORT jlong JNICALL Java_com_android_ndkaudio_AudioPlayer_GetLastSLResult(JNIEnv*, jobject) {
+    return lastSLResult;
+}
+
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioPlayer_ClearLastSLResult(JNIEnv*, jobject) {
+    lastSLResult = 0;
+}
+
+} // extern "C"
diff --git a/tests/tests/media/libndkaudio/com_android_ndkaudio_AudioPlayer.h b/tests/tests/media/libndkaudio/com_android_ndkaudio_AudioPlayer.h
new file mode 100644
index 0000000..551349c
--- /dev/null
+++ b/tests/tests/media/libndkaudio/com_android_ndkaudio_AudioPlayer.h
@@ -0,0 +1,99 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class com_android_ndkaudio_AudioPlayer */
+
+#ifndef _Included_com_android_ndkaudio_AudioPlayer
+#define _Included_com_android_ndkaudio_AudioPlayer
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class:     com_android_ndkaudio_AudioPlayer
+ * Method:    InitN
+ * Signature: ()V
+ */
+
+/*
+ * Class:     com_android_ndkaudio_AudioPlayer
+ * Method:    Create
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioPlayer_Create
+  (JNIEnv *, jobject);
+
+/*
+ * Class:     com_android_ndkaudio_AudioPlayer
+ * Method:    Destroy
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioPlayer_Destroy
+  (JNIEnv*, jobject);
+
+/*
+ * Class:     com_android_ndkaudio_AudioPlayer
+ * Method:    RealizePlayer
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioPlayer_RealizePlayer
+  (JNIEnv*, jobject);
+
+/*
+ * Class:     com_android_ndkaudio_AudioPlayer
+ * Method:    RealizeRoutingProxy
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioPlayer_RealizeRoutingProxy
+  (JNIEnv*, jobject);
+
+/*
+ * Class:     com_android_ndkaudio_AudioPlayer
+ * Method:    Start
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioPlayer_Start
+  (JNIEnv *, jobject);
+
+/*
+ * Class:     com_android_ndkaudio_AudioPlayer
+ * Method:    Stop
+ * Signature: ()android/
+ */
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioPlayer_Stop
+  (JNIEnv *, jobject);
+
+/*
+ * Class:     com_android_ndkaudio_AudioPlayer
+ * Method:    GetRoutingInterface
+ * Signature: ()Landroid/media/AudioRouting;
+ */
+JNIEXPORT jobject JNICALL Java_com_android_ndkaudio_AudioPlayer_GetRoutingInterface
+  (JNIEnv*, jobject);
+
+/*
+ * Class:     com_android_ndkaudio_AudioPlayer
+ * Method:    GetRoutingInterface
+ * Signature: (Landroid/media/AudioRouting;)V
+ */
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioPlayer_ReleaseRoutingInterface
+  (JNIEnv*, jobject, jobject);
+
+/*
+ * Class:     com_android_ndkaudio_AudioPlayer
+ * Method:    GetLastSLResult
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_com_android_ndkaudio_AudioPlayer_GetLastSLResult
+  (JNIEnv*, jobject);
+
+/*
+ * Class:     com_android_ndkaudio_AudioPlayer
+ * Method:    ClearLastSLResult
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioPlayer_ClearLastSLResult
+  (JNIEnv*, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/tests/tests/media/libndkaudio/com_android_ndkaudio_AudioRecorder.cpp b/tests/tests/media/libndkaudio/com_android_ndkaudio_AudioRecorder.cpp
new file mode 100644
index 0000000..f4dcc20
--- /dev/null
+++ b/tests/tests/media/libndkaudio/com_android_ndkaudio_AudioRecorder.cpp
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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/log.h>
+
+#include "com_android_ndkaudio_AudioRecorder.h"
+
+#include "AudioRecorder.h"
+
+using namespace ndkaudio;
+
+static const char* TAG = "_com_android_ndkaudio_AudioRecorder_";
+
+static int numChannels = 2;
+
+static AudioRecorder* nativeRecorder;
+
+static SLresult lastSLResult = 0;
+extern "C" {
+
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioRecorder_Create(JNIEnv*, jobject) {
+  __android_log_print(ANDROID_LOG_INFO, TAG, "AudioRecorder_Create() ...");
+  if (nativeRecorder == 0) {
+      nativeRecorder = new AudioRecorder();
+  }
+  nativeRecorder->Open(numChannels, 0);
+}
+
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioRecorder_Destroy(JNIEnv*, jobject) {
+  __android_log_print(ANDROID_LOG_INFO, TAG, "AudioRecorder_Destroy() ...");
+  nativeRecorder->Close();
+  delete nativeRecorder;
+  nativeRecorder = 0;
+}
+
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioRecorder_RealizeRecorder(JNIEnv*, jobject) {
+    __android_log_print(ANDROID_LOG_INFO, TAG, "AudioRecorder_RealizePlayer() ...");
+    nativeRecorder->RealizeRecorder();
+  }
+
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioRecorder_RealizeRoutingProxy(JNIEnv*, jobject) {
+    __android_log_print(ANDROID_LOG_INFO, TAG, "RealizeRoutingProxy ...");
+    nativeRecorder->RealizeRoutingProxy();
+  }
+
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioRecorder_Start(JNIEnv *, jobject) {
+  __android_log_print(ANDROID_LOG_INFO, TAG, "AudioRecorder_Start() ...");
+  nativeRecorder->Start();
+}
+
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioRecorder_Stop(JNIEnv *, jobject) {
+  __android_log_print(ANDROID_LOG_INFO, TAG, "AudioRecorder_Stop() ...");
+  nativeRecorder->Stop();
+}
+
+JNIEXPORT jobject JNICALL Java_com_android_ndkaudio_AudioRecorder_GetRoutingInterface(JNIEnv*, jobject) {
+  __android_log_print(ANDROID_LOG_INFO, TAG, "AudioPlayer_GetRoutingObj() ...");
+
+  SLAndroidConfigurationItf configItf = nativeRecorder->getConfigItf();
+  jobject routingObj = 0;
+  lastSLResult = (*configItf)->AcquireJavaProxy(configItf, SL_ANDROID_JAVA_PROXY_ROUTING, &routingObj);
+  __android_log_print(ANDROID_LOG_INFO, TAG, "  routingObj:%p", routingObj);
+  return routingObj;
+}
+
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioRecorder_ReleaseRoutingInterface(JNIEnv*, jobject, jobject /*proxyObj*/) {
+  __android_log_print(ANDROID_LOG_INFO, TAG, "AudioPlayer_ReleaseRoutingInterface() ...");
+
+  SLAndroidConfigurationItf configItf = nativeRecorder->getConfigItf();
+  lastSLResult = (*configItf)->ReleaseJavaProxy(configItf, SL_ANDROID_JAVA_PROXY_ROUTING/*, proxyObj*/);
+}
+
+JNIEXPORT jint JNICALL Java_com_android_ndkaudio_AudioRecorder_GetNumBufferSamples(JNIEnv*, jobject) {
+    return nativeRecorder->GetNumBufferSamples();
+}
+
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioRecorder_GetBufferData(JNIEnv* jEnv, jobject, jfloatArray j_data) {
+    float* dataBuffer = nativeRecorder->GetRecordBuffer();
+    if (dataBuffer != 0) {
+        jEnv->SetFloatArrayRegion(j_data, 0, nativeRecorder->GetNumBufferSamples(), dataBuffer);
+    }
+}
+
+JNIEXPORT jlong JNICALL Java_com_android_ndkaudio_AudioRecorder_GetLastSLResult(JNIEnv*, jobject) {
+    return lastSLResult;
+}
+
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioRecorder_ClearLastSLResult(JNIEnv*, jobject) {
+    lastSLResult = 0;
+}
+
+} // extern "C"
diff --git a/tests/tests/media/libndkaudio/com_android_ndkaudio_AudioRecorder.h b/tests/tests/media/libndkaudio/com_android_ndkaudio_AudioRecorder.h
new file mode 100644
index 0000000..98a2932
--- /dev/null
+++ b/tests/tests/media/libndkaudio/com_android_ndkaudio_AudioRecorder.h
@@ -0,0 +1,109 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class com_android_ndkaudio_AudioRecorder */
+
+#ifndef _Included_com_android_ndkaudio_AudioRecorder
+#define _Included_com_android_ndkaudio_AudioRecorder
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class:     com_android_ndkaudio_AudioRecorder
+ * Method:    Create
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioRecorder_Create
+  (JNIEnv *, jobject);
+
+/*
+ * Class:     com_android_ndkaudio_AudioRecorder
+ * Method:    Destroy
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioRecorder_Destroy
+  (JNIEnv *, jobject);
+
+/*
+ * Class:     com_android_ndkaudio_AudioRecorder
+ * Method:    RealizeRecorder
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioRecorder_RealizeRecorder
+  (JNIEnv*, jobject);
+
+/*
+ * Class:     com_android_ndkaudio_AudioRecorder
+ * Method:    RealizeRoutingProxy
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioRecorder_RealizeRoutingProxy
+  (JNIEnv*, jobject);
+
+/*
+ * Class:     com_android_ndkaudio_AudioRecorder
+ * Method:    Start
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioRecorder_Start
+  (JNIEnv *, jobject);
+
+/*
+ * Class:     com_android_ndkaudio_AudioRecorder
+ * Method:    Stop
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioRecorder_Stop
+  (JNIEnv *, jobject);
+
+/*
+ * Class:     com_android_ndkaudio_AudioRecorder
+ * Method:    GetRoutingInterface
+ * Signature: ()Landroid/media/AudioRouting;
+ */
+JNIEXPORT jobject JNICALL Java_com_android_ndkaudio_AudioRecorder_GetRoutingInterface
+  (JNIEnv*, jobject);
+
+/*
+ * Class:     com_android_ndkaudio_AudioRecorder
+ * Method:    ReleaseRoutingInterface
+ * Signature: (Landroid/media/AudioRouting;)V
+ */
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioRecorder_ReleaseRoutingInterface
+  (JNIEnv*, jobject, jobject);
+
+/*
+ * Class:     com_android_ndkaudio_AudioRecorder
+ * Method:    GetNumBufferFrames
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_com_android_ndkaudio_AudioRecorder_GetNumBufferFrames
+  (JNIEnv *, jobject);
+
+/*
+ * Class:     com_android_ndkaudio_AudioRecorder
+ * Method:    GetBufferData
+ * Signature: ([F)V
+ */
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioRecorder_GetBufferData
+  (JNIEnv *, jobject, jfloatArray);
+
+/*
+ * Class:     com_android_ndkaudio_AudioRecorder
+ * Method:    GetLastSLResult
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_com_android_ndkaudio_AudioRecorder_GetLastSLResult
+  (JNIEnv*, jobject);
+
+/*
+ * Class:     com_android_ndkaudio_AudioRecorder
+ * Method:    ClearLastSLResult
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioRecorder_ClearLastSLResult
+  (JNIEnv*, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/tests/tests/media/libndkaudio/src/com/android/ndkaudio/AudioPlayer.java b/tests/tests/media/libndkaudio/src/com/android/ndkaudio/AudioPlayer.java
new file mode 100644
index 0000000..f9cd109
--- /dev/null
+++ b/tests/tests/media/libndkaudio/src/com/android/ndkaudio/AudioPlayer.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.ndkaudio;
+
+import android.media.AudioRouting;
+
+public class AudioPlayer {
+    public AudioPlayer() {
+        Create();
+    }
+
+    public native void Create();
+    public native void Destroy();
+
+    public native void RealizePlayer();
+    public native void RealizeRoutingProxy();
+
+    public native void Start();
+    public native void Stop();
+
+    public native AudioRouting GetRoutingInterface();
+
+    public native void ReleaseRoutingInterface(AudioRouting proxyObj);
+
+    public native long GetLastSLResult();
+    public native void ClearLastSLResult();
+}
diff --git a/tests/tests/media/libndkaudio/src/com/android/ndkaudio/AudioRecorder.java b/tests/tests/media/libndkaudio/src/com/android/ndkaudio/AudioRecorder.java
new file mode 100644
index 0000000..52d20c4
--- /dev/null
+++ b/tests/tests/media/libndkaudio/src/com/android/ndkaudio/AudioRecorder.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.ndkaudio;
+
+import android.media.AudioRouting;
+
+public class AudioRecorder {
+    public AudioRecorder() {
+        Create();
+    }
+
+    public native void Create();
+    public native void Destroy();
+
+    public native void RealizeRecorder();
+    public native void RealizeRoutingProxy();
+
+    public native void Start();
+    public native void Stop();
+
+    public native AudioRouting GetRoutingInterface();
+    public native void ReleaseRoutingInterface(AudioRouting proxyObj);
+
+    public native int GetNumBufferSamples();
+    public native void GetBufferData(float[] dstBuff);
+
+    public native long GetLastSLResult();
+    public native void ClearLastSLResult();
+}
diff --git a/tests/tests/media/res/layout/test_runner_activity.xml b/tests/tests/media/res/layout/test_runner_activity.xml
new file mode 100644
index 0000000..8cc88ea
--- /dev/null
+++ b/tests/tests/media/res/layout/test_runner_activity.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:orientation="vertical">
+        <HorizontalScrollView
+            android:layout_width="fill_parent"
+            android:layout_height="250dp">
+                <ScrollView
+                    android:layout_width="wrap_content"
+                    android:layout_height="fill_parent">
+                        <RelativeLayout
+                            android:id="@+id/attach_view"
+                            android:layout_width="fill_parent"
+                            android:layout_height="wrap_content"
+                            android:layout_gravity="start"/>
+                </ScrollView>
+        </HorizontalScrollView>
+        <ListView
+            android:id="@+id/test_case_list"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"/>
+</LinearLayout>
diff --git a/tests/tests/media/res/raw/h264decodertestgolden.png b/tests/tests/media/res/raw/h264decodertestgolden.png
new file mode 100644
index 0000000..bfaea26
--- /dev/null
+++ b/tests/tests/media/res/raw/h264decodertestgolden.png
Binary files differ
diff --git a/tests/tests/media/res/raw/image_exif_byte_order_ii.jpg b/tests/tests/media/res/raw/image_exif_byte_order_ii.jpg
new file mode 100644
index 0000000..477cd3a
--- /dev/null
+++ b/tests/tests/media/res/raw/image_exif_byte_order_ii.jpg
Binary files differ
diff --git a/tests/tests/media/res/raw/image_exif_byte_order_mm.jpg b/tests/tests/media/res/raw/image_exif_byte_order_mm.jpg
new file mode 100644
index 0000000..78ac703
--- /dev/null
+++ b/tests/tests/media/res/raw/image_exif_byte_order_mm.jpg
Binary files differ
diff --git a/tests/tests/media/res/raw/lg_g4_iso_800.dng b/tests/tests/media/res/raw/lg_g4_iso_800.dng
new file mode 100644
index 0000000..5fcc720
--- /dev/null
+++ b/tests/tests/media/res/raw/lg_g4_iso_800.dng
Binary files differ
diff --git a/tests/tests/media/res/raw/noise_1ch_16khz_aot39_ds_sbr_fl512_mp4.m4a b/tests/tests/media/res/raw/noise_1ch_16khz_aot39_ds_sbr_fl512_mp4.m4a
new file mode 100755
index 0000000..bd2e329
--- /dev/null
+++ b/tests/tests/media/res/raw/noise_1ch_16khz_aot39_ds_sbr_fl512_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/noise_1ch_24khz_aot39_ds_sbr_fl512_mp4.m4a b/tests/tests/media/res/raw/noise_1ch_24khz_aot39_ds_sbr_fl512_mp4.m4a
new file mode 100755
index 0000000..f917a0e
--- /dev/null
+++ b/tests/tests/media/res/raw/noise_1ch_24khz_aot39_ds_sbr_fl512_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/noise_1ch_24khz_aot5_dr_sbr_sig1_mp4.m4a b/tests/tests/media/res/raw/noise_1ch_24khz_aot5_dr_sbr_sig1_mp4.m4a
new file mode 100755
index 0000000..ea0f4cb
--- /dev/null
+++ b/tests/tests/media/res/raw/noise_1ch_24khz_aot5_dr_sbr_sig1_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/noise_1ch_24khz_aot5_ds_sbr_sig1_mp4.m4a b/tests/tests/media/res/raw/noise_1ch_24khz_aot5_ds_sbr_sig1_mp4.m4a
new file mode 100755
index 0000000..ff09a7b
--- /dev/null
+++ b/tests/tests/media/res/raw/noise_1ch_24khz_aot5_ds_sbr_sig1_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/noise_1ch_32khz_aot39_dr_sbr_fl480_mp4.m4a b/tests/tests/media/res/raw/noise_1ch_32khz_aot39_dr_sbr_fl480_mp4.m4a
new file mode 100755
index 0000000..24f4405
--- /dev/null
+++ b/tests/tests/media/res/raw/noise_1ch_32khz_aot39_dr_sbr_fl480_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/noise_1ch_32khz_aot5_dr_sbr_sig2_mp4.m4a b/tests/tests/media/res/raw/noise_1ch_32khz_aot5_dr_sbr_sig2_mp4.m4a
new file mode 100755
index 0000000..b9b061b
--- /dev/null
+++ b/tests/tests/media/res/raw/noise_1ch_32khz_aot5_dr_sbr_sig2_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/noise_1ch_44khz_aot39_ds_sbr_fl512_mp4.m4a b/tests/tests/media/res/raw/noise_1ch_44khz_aot39_ds_sbr_fl512_mp4.m4a
new file mode 100755
index 0000000..ae85392
--- /dev/null
+++ b/tests/tests/media/res/raw/noise_1ch_44khz_aot39_ds_sbr_fl512_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/noise_1ch_44khz_aot5_dr_sbr_sig0_mp4.m4a b/tests/tests/media/res/raw/noise_1ch_44khz_aot5_dr_sbr_sig0_mp4.m4a
new file mode 100755
index 0000000..a2f3dce
--- /dev/null
+++ b/tests/tests/media/res/raw/noise_1ch_44khz_aot5_dr_sbr_sig0_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/noise_1ch_44khz_aot5_ds_sbr_sig2_mp4.m4a b/tests/tests/media/res/raw/noise_1ch_44khz_aot5_ds_sbr_sig2_mp4.m4a
new file mode 100755
index 0000000..bf56de8
--- /dev/null
+++ b/tests/tests/media/res/raw/noise_1ch_44khz_aot5_ds_sbr_sig2_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/noise_1ch_48khz_aot39_dr_sbr_fl480_mp4.m4a b/tests/tests/media/res/raw/noise_1ch_48khz_aot39_dr_sbr_fl480_mp4.m4a
new file mode 100755
index 0000000..675a84b
--- /dev/null
+++ b/tests/tests/media/res/raw/noise_1ch_48khz_aot39_dr_sbr_fl480_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/noise_2ch_22khz_aot39_ds_sbr_fl512_mp4.m4a b/tests/tests/media/res/raw/noise_2ch_22khz_aot39_ds_sbr_fl512_mp4.m4a
new file mode 100755
index 0000000..1187f3b
--- /dev/null
+++ b/tests/tests/media/res/raw/noise_2ch_22khz_aot39_ds_sbr_fl512_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/noise_2ch_24khz_aot29_dr_sbr_sig0_mp4.m4a b/tests/tests/media/res/raw/noise_2ch_24khz_aot29_dr_sbr_sig0_mp4.m4a
new file mode 100755
index 0000000..eb4bc59
--- /dev/null
+++ b/tests/tests/media/res/raw/noise_2ch_24khz_aot29_dr_sbr_sig0_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/noise_2ch_24khz_aot5_dr_sbr_sig2_mp4.m4a b/tests/tests/media/res/raw/noise_2ch_24khz_aot5_dr_sbr_sig2_mp4.m4a
new file mode 100755
index 0000000..4675af3
--- /dev/null
+++ b/tests/tests/media/res/raw/noise_2ch_24khz_aot5_dr_sbr_sig2_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/noise_2ch_32khz_aot39_ds_sbr_fl512_mp4.m4a b/tests/tests/media/res/raw/noise_2ch_32khz_aot39_ds_sbr_fl512_mp4.m4a
new file mode 100755
index 0000000..4a795f2
--- /dev/null
+++ b/tests/tests/media/res/raw/noise_2ch_32khz_aot39_ds_sbr_fl512_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/noise_2ch_32khz_aot5_ds_sbr_sig2_mp4.m4a b/tests/tests/media/res/raw/noise_2ch_32khz_aot5_ds_sbr_sig2_mp4.m4a
new file mode 100755
index 0000000..95e3bf2
--- /dev/null
+++ b/tests/tests/media/res/raw/noise_2ch_32khz_aot5_ds_sbr_sig2_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/noise_2ch_44khz_aot29_dr_sbr_sig1_mp4.m4a b/tests/tests/media/res/raw/noise_2ch_44khz_aot29_dr_sbr_sig1_mp4.m4a
new file mode 100755
index 0000000..688cd73
--- /dev/null
+++ b/tests/tests/media/res/raw/noise_2ch_44khz_aot29_dr_sbr_sig1_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/noise_2ch_44khz_aot39_dr_sbr_fl480_mp4.m4a b/tests/tests/media/res/raw/noise_2ch_44khz_aot39_dr_sbr_fl480_mp4.m4a
new file mode 100755
index 0000000..54c32b5
--- /dev/null
+++ b/tests/tests/media/res/raw/noise_2ch_44khz_aot39_dr_sbr_fl480_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/noise_2ch_48khz_aot29_dr_sbr_sig2_mp4.m4a b/tests/tests/media/res/raw/noise_2ch_48khz_aot29_dr_sbr_sig2_mp4.m4a
new file mode 100755
index 0000000..2f8bba1
--- /dev/null
+++ b/tests/tests/media/res/raw/noise_2ch_48khz_aot29_dr_sbr_sig2_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/noise_2ch_48khz_aot39_ds_sbr_fl512_mp4.m4a b/tests/tests/media/res/raw/noise_2ch_48khz_aot39_ds_sbr_fl512_mp4.m4a
new file mode 100755
index 0000000..6798aec
--- /dev/null
+++ b/tests/tests/media/res/raw/noise_2ch_48khz_aot39_ds_sbr_fl512_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/noise_2ch_48khz_aot5_dr_sbr_sig1_mp4.m4a b/tests/tests/media/res/raw/noise_2ch_48khz_aot5_dr_sbr_sig1_mp4.m4a
new file mode 100755
index 0000000..d8f1ffc
--- /dev/null
+++ b/tests/tests/media/res/raw/noise_2ch_48khz_aot5_dr_sbr_sig1_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/noise_2ch_48khz_aot5_ds_sbr_sig1_mp4.m4a b/tests/tests/media/res/raw/noise_2ch_48khz_aot5_ds_sbr_sig1_mp4.m4a
new file mode 100755
index 0000000..fc94c20
--- /dev/null
+++ b/tests/tests/media/res/raw/noise_2ch_48khz_aot5_ds_sbr_sig1_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/noise_5ch_44khz_aot2_mp4.m4a b/tests/tests/media/res/raw/noise_5ch_44khz_aot2_mp4.m4a
new file mode 100755
index 0000000..cc9ad73
--- /dev/null
+++ b/tests/tests/media/res/raw/noise_5ch_44khz_aot2_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/noise_5ch_48khz_aot5_dr_sbr_sig1_mp4.m4a b/tests/tests/media/res/raw/noise_5ch_48khz_aot5_dr_sbr_sig1_mp4.m4a
new file mode 100755
index 0000000..a1266bf
--- /dev/null
+++ b/tests/tests/media/res/raw/noise_5ch_48khz_aot5_dr_sbr_sig1_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/noise_6ch_44khz_aot5_dr_sbr_sig2_mp4.m4a b/tests/tests/media/res/raw/noise_6ch_44khz_aot5_dr_sbr_sig2_mp4.m4a
new file mode 100755
index 0000000..ef1332c
--- /dev/null
+++ b/tests/tests/media/res/raw/noise_6ch_44khz_aot5_dr_sbr_sig2_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/noise_6ch_48khz_aot2_mp4.m4a b/tests/tests/media/res/raw/noise_6ch_48khz_aot2_mp4.m4a
new file mode 100755
index 0000000..7eeb5e8
--- /dev/null
+++ b/tests/tests/media/res/raw/noise_6ch_48khz_aot2_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/okgoogle123_good.wav b/tests/tests/media/res/raw/okgoogle123_good.wav
new file mode 100644
index 0000000..ffd5a7f8
--- /dev/null
+++ b/tests/tests/media/res/raw/okgoogle123_good.wav
Binary files differ
diff --git a/tests/tests/media/res/raw/sine1khzm40db.wav b/tests/tests/media/res/raw/sine1khzm40db.wav
index ba541c4..b653a77 100644
--- a/tests/tests/media/res/raw/sine1khzm40db.wav
+++ b/tests/tests/media/res/raw/sine1khzm40db.wav
Binary files differ
diff --git a/tests/tests/media/res/raw/sinesweep1_1ch_11khz_aot2_mp4.m4a b/tests/tests/media/res/raw/sinesweep1_1ch_11khz_aot2_mp4.m4a
new file mode 100755
index 0000000..019dbae
--- /dev/null
+++ b/tests/tests/media/res/raw/sinesweep1_1ch_11khz_aot2_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/sinesweep1_1ch_12khz_aot2_mp4.m4a b/tests/tests/media/res/raw/sinesweep1_1ch_12khz_aot2_mp4.m4a
new file mode 100755
index 0000000..0aae458
--- /dev/null
+++ b/tests/tests/media/res/raw/sinesweep1_1ch_12khz_aot2_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/sinesweep1_1ch_16khz_aot2_mp4.m4a b/tests/tests/media/res/raw/sinesweep1_1ch_16khz_aot2_mp4.m4a
new file mode 100755
index 0000000..b8e767b
--- /dev/null
+++ b/tests/tests/media/res/raw/sinesweep1_1ch_16khz_aot2_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/sinesweep1_1ch_16khz_aot39_fl480_mp4.m4a b/tests/tests/media/res/raw/sinesweep1_1ch_16khz_aot39_fl480_mp4.m4a
new file mode 100755
index 0000000..86ff942
--- /dev/null
+++ b/tests/tests/media/res/raw/sinesweep1_1ch_16khz_aot39_fl480_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/sinesweep1_1ch_22khz_aot2_mp4.m4a b/tests/tests/media/res/raw/sinesweep1_1ch_22khz_aot2_mp4.m4a
new file mode 100755
index 0000000..ce240bb
--- /dev/null
+++ b/tests/tests/media/res/raw/sinesweep1_1ch_22khz_aot2_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/sinesweep1_1ch_22khz_aot39_fl512_mp4.m4a b/tests/tests/media/res/raw/sinesweep1_1ch_22khz_aot39_fl512_mp4.m4a
new file mode 100755
index 0000000..b07b036
--- /dev/null
+++ b/tests/tests/media/res/raw/sinesweep1_1ch_22khz_aot39_fl512_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/sinesweep1_1ch_24khz_aot2_mp4.m4a b/tests/tests/media/res/raw/sinesweep1_1ch_24khz_aot2_mp4.m4a
new file mode 100755
index 0000000..7245bbb
--- /dev/null
+++ b/tests/tests/media/res/raw/sinesweep1_1ch_24khz_aot2_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/sinesweep1_1ch_24khz_aot39_fl480_mp4.m4a b/tests/tests/media/res/raw/sinesweep1_1ch_24khz_aot39_fl480_mp4.m4a
new file mode 100755
index 0000000..252366b
--- /dev/null
+++ b/tests/tests/media/res/raw/sinesweep1_1ch_24khz_aot39_fl480_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/sinesweep1_1ch_32khz_aot2_mp4.m4a b/tests/tests/media/res/raw/sinesweep1_1ch_32khz_aot2_mp4.m4a
new file mode 100755
index 0000000..e4216da
--- /dev/null
+++ b/tests/tests/media/res/raw/sinesweep1_1ch_32khz_aot2_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/sinesweep1_1ch_32khz_aot39_fl512_mp4.m4a b/tests/tests/media/res/raw/sinesweep1_1ch_32khz_aot39_fl512_mp4.m4a
new file mode 100755
index 0000000..a0c6a46
--- /dev/null
+++ b/tests/tests/media/res/raw/sinesweep1_1ch_32khz_aot39_fl512_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/sinesweep1_1ch_44khz_aot2_mp4.m4a b/tests/tests/media/res/raw/sinesweep1_1ch_44khz_aot2_mp4.m4a
new file mode 100755
index 0000000..d44a956
--- /dev/null
+++ b/tests/tests/media/res/raw/sinesweep1_1ch_44khz_aot2_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/sinesweep1_1ch_44khz_aot39_fl480_mp4.m4a b/tests/tests/media/res/raw/sinesweep1_1ch_44khz_aot39_fl480_mp4.m4a
new file mode 100755
index 0000000..4b3a860
--- /dev/null
+++ b/tests/tests/media/res/raw/sinesweep1_1ch_44khz_aot39_fl480_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/sinesweep1_1ch_48khz_aot2_mp4.m4a b/tests/tests/media/res/raw/sinesweep1_1ch_48khz_aot2_mp4.m4a
new file mode 100755
index 0000000..438b066
--- /dev/null
+++ b/tests/tests/media/res/raw/sinesweep1_1ch_48khz_aot2_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/sinesweep1_1ch_48khz_aot39_fl512_mp4.m4a b/tests/tests/media/res/raw/sinesweep1_1ch_48khz_aot39_fl512_mp4.m4a
new file mode 100755
index 0000000..b6a2e69
--- /dev/null
+++ b/tests/tests/media/res/raw/sinesweep1_1ch_48khz_aot39_fl512_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/sinesweep1_1ch_8khz_aot2_mp4.m4a b/tests/tests/media/res/raw/sinesweep1_1ch_8khz_aot2_mp4.m4a
new file mode 100755
index 0000000..4b690e2
--- /dev/null
+++ b/tests/tests/media/res/raw/sinesweep1_1ch_8khz_aot2_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/sinesweep_2ch_11khz_aot2_mp4.m4a b/tests/tests/media/res/raw/sinesweep_2ch_11khz_aot2_mp4.m4a
new file mode 100755
index 0000000..bd83ec8
--- /dev/null
+++ b/tests/tests/media/res/raw/sinesweep_2ch_11khz_aot2_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/sinesweep_2ch_12khz_aot2_mp4.m4a b/tests/tests/media/res/raw/sinesweep_2ch_12khz_aot2_mp4.m4a
new file mode 100755
index 0000000..054d6d8
--- /dev/null
+++ b/tests/tests/media/res/raw/sinesweep_2ch_12khz_aot2_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/sinesweep_2ch_16khz_aot2_mp4.m4a b/tests/tests/media/res/raw/sinesweep_2ch_16khz_aot2_mp4.m4a
new file mode 100755
index 0000000..321a3b5
--- /dev/null
+++ b/tests/tests/media/res/raw/sinesweep_2ch_16khz_aot2_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/sinesweep_2ch_16khz_aot39_fl512_mp4.m4a b/tests/tests/media/res/raw/sinesweep_2ch_16khz_aot39_fl512_mp4.m4a
new file mode 100755
index 0000000..f04f29f
--- /dev/null
+++ b/tests/tests/media/res/raw/sinesweep_2ch_16khz_aot39_fl512_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/sinesweep_2ch_22khz_aot2_mp4.m4a b/tests/tests/media/res/raw/sinesweep_2ch_22khz_aot2_mp4.m4a
new file mode 100755
index 0000000..432b379
--- /dev/null
+++ b/tests/tests/media/res/raw/sinesweep_2ch_22khz_aot2_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/sinesweep_2ch_22khz_aot39_fl480_mp4.m4a b/tests/tests/media/res/raw/sinesweep_2ch_22khz_aot39_fl480_mp4.m4a
new file mode 100755
index 0000000..0a300f8
--- /dev/null
+++ b/tests/tests/media/res/raw/sinesweep_2ch_22khz_aot39_fl480_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/sinesweep_2ch_24khz_aot2_mp4.m4a b/tests/tests/media/res/raw/sinesweep_2ch_24khz_aot2_mp4.m4a
new file mode 100755
index 0000000..c859c9a
--- /dev/null
+++ b/tests/tests/media/res/raw/sinesweep_2ch_24khz_aot2_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/sinesweep_2ch_24khz_aot39_fl512_mp4.m4a b/tests/tests/media/res/raw/sinesweep_2ch_24khz_aot39_fl512_mp4.m4a
new file mode 100755
index 0000000..cdc8928
--- /dev/null
+++ b/tests/tests/media/res/raw/sinesweep_2ch_24khz_aot39_fl512_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/sinesweep_2ch_32khz_aot2_mp4.m4a b/tests/tests/media/res/raw/sinesweep_2ch_32khz_aot2_mp4.m4a
new file mode 100755
index 0000000..48c7b02
--- /dev/null
+++ b/tests/tests/media/res/raw/sinesweep_2ch_32khz_aot2_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/sinesweep_2ch_32khz_aot39_fl480_mp4.m4a b/tests/tests/media/res/raw/sinesweep_2ch_32khz_aot39_fl480_mp4.m4a
new file mode 100755
index 0000000..76c9d47
--- /dev/null
+++ b/tests/tests/media/res/raw/sinesweep_2ch_32khz_aot39_fl480_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/sinesweep_2ch_44khz_aot2_mp4.m4a b/tests/tests/media/res/raw/sinesweep_2ch_44khz_aot2_mp4.m4a
new file mode 100755
index 0000000..dd752b0
--- /dev/null
+++ b/tests/tests/media/res/raw/sinesweep_2ch_44khz_aot2_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/sinesweep_2ch_44khz_aot39_fl512_mp4.m4a b/tests/tests/media/res/raw/sinesweep_2ch_44khz_aot39_fl512_mp4.m4a
new file mode 100755
index 0000000..76fba31
--- /dev/null
+++ b/tests/tests/media/res/raw/sinesweep_2ch_44khz_aot39_fl512_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/sinesweep_2ch_48khz_aot2_mp4.m4a b/tests/tests/media/res/raw/sinesweep_2ch_48khz_aot2_mp4.m4a
new file mode 100755
index 0000000..2960b54
--- /dev/null
+++ b/tests/tests/media/res/raw/sinesweep_2ch_48khz_aot2_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/sinesweep_2ch_48khz_aot39_fl480_mp4.m4a b/tests/tests/media/res/raw/sinesweep_2ch_48khz_aot39_fl480_mp4.m4a
new file mode 100755
index 0000000..baea42e
--- /dev/null
+++ b/tests/tests/media/res/raw/sinesweep_2ch_48khz_aot39_fl480_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/sinesweep_2ch_8khz_aot2_mp4.m4a b/tests/tests/media/res/raw/sinesweep_2ch_8khz_aot2_mp4.m4a
new file mode 100755
index 0000000..0863187
--- /dev/null
+++ b/tests/tests/media/res/raw/sinesweep_2ch_8khz_aot2_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/sinesweepopus.mkv b/tests/tests/media/res/raw/sinesweepopus.mkv
new file mode 100644
index 0000000..230dd36
--- /dev/null
+++ b/tests/tests/media/res/raw/sinesweepopus.mkv
Binary files differ
diff --git a/tests/tests/media/res/raw/sinesweepvorbis.mkv b/tests/tests/media/res/raw/sinesweepvorbis.mkv
new file mode 100644
index 0000000..613ab71
--- /dev/null
+++ b/tests/tests/media/res/raw/sinesweepvorbis.mkv
Binary files differ
diff --git a/tests/tests/media/res/raw/testvideo_with_2_subtitle_tracks.mp4 b/tests/tests/media/res/raw/testvideo_with_2_subtitle_tracks.mp4
new file mode 100755
index 0000000..b8dce17
--- /dev/null
+++ b/tests/tests/media/res/raw/testvideo_with_2_subtitle_tracks.mp4
Binary files differ
diff --git a/tests/tests/media/res/raw/testvideo_with_2_subtitles.3gp b/tests/tests/media/res/raw/testvideo_with_2_timedtext_tracks.3gp
similarity index 100%
rename from tests/tests/media/res/raw/testvideo_with_2_subtitles.3gp
rename to tests/tests/media/res/raw/testvideo_with_2_timedtext_tracks.3gp
Binary files differ
diff --git a/tests/tests/media/res/raw/tones.wav b/tests/tests/media/res/raw/tones.wav
new file mode 100644
index 0000000..ec54c96
--- /dev/null
+++ b/tests/tests/media/res/raw/tones.wav
Binary files differ
diff --git a/tests/tests/media/res/raw/video_320x240_webm_vp8_800kbps_30fps_vorbis_stereo_128kbps_44100hz_crypt.webm b/tests/tests/media/res/raw/video_320x240_webm_vp8_800kbps_30fps_vorbis_stereo_128kbps_44100hz_crypt.webm
new file mode 100644
index 0000000..978b3aa
--- /dev/null
+++ b/tests/tests/media/res/raw/video_320x240_webm_vp8_800kbps_30fps_vorbis_stereo_128kbps_44100hz_crypt.webm
Binary files differ
diff --git a/tests/tests/media/res/raw/video_720x480_mp4_hevc_1638kbps_30fps_aac_stereo_128kbps_44100hz.mp4 b/tests/tests/media/res/raw/video_640x360_mp4_hevc_1638kbps_30fps_aac_stereo_128kbps_44100hz
similarity index 100%
rename from tests/tests/media/res/raw/video_720x480_mp4_hevc_1638kbps_30fps_aac_stereo_128kbps_44100hz.mp4
rename to tests/tests/media/res/raw/video_640x360_mp4_hevc_1638kbps_30fps_aac_stereo_128kbps_44100hz
Binary files differ
diff --git a/tests/tests/media/res/raw/voice12_48k_128kbps_15s_ac3.raw b/tests/tests/media/res/raw/voice12_48k_128kbps_15s_ac3.raw
new file mode 100644
index 0000000..e8b46af
--- /dev/null
+++ b/tests/tests/media/res/raw/voice12_48k_128kbps_15s_ac3.raw
Binary files differ
diff --git a/tests/tests/media/res/raw/voice12_48k_128kbps_15s_ac3_readme.txt b/tests/tests/media/res/raw/voice12_48k_128kbps_15s_ac3_readme.txt
new file mode 100644
index 0000000..3073d48
--- /dev/null
+++ b/tests/tests/media/res/raw/voice12_48k_128kbps_15s_ac3_readme.txt
@@ -0,0 +1,7 @@
+file=voice12_48k_128kbps_15s.raw
+author=Phil Burk
+copyright=2016 Google Inc
+license=Apache Open Source V2
+channels=2
+encoding=AC3
+rate=48000
diff --git a/tests/tests/media/res/raw/vp9decodertestgolden.png b/tests/tests/media/res/raw/vp9decodertestgolden.png
new file mode 100644
index 0000000..cad6778
--- /dev/null
+++ b/tests/tests/media/res/raw/vp9decodertestgolden.png
Binary files differ
diff --git a/tests/tests/media/res/values/exifinterface.xml b/tests/tests/media/res/values/exifinterface.xml
new file mode 100644
index 0000000..bc34177
--- /dev/null
+++ b/tests/tests/media/res/values/exifinterface.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+    <array name="exifbyteorderii_jpg">
+        <item>true</item>
+        <item>512</item>
+        <item>288</item>
+        <item>false</item>
+        <item>0.0</item>
+        <item>0.0</item>
+        <item>0.0</item>
+        <item>SAMSUNG</item>
+        <item>SM-N900S</item>
+        <item>2.200</item>
+        <item>2016:01:29 18:32:27</item>
+        <item>0.033</item>
+        <item>0</item>
+        <item>413/100</item>
+        <item />
+        <item />
+        <item />
+        <item />
+        <item />
+        <item />
+        <item />
+        <item />
+        <item />
+        <item>480</item>
+        <item>640</item>
+        <item>50</item>
+        <item>6</item>
+        <item>0</item>
+    </array>
+    <array name="exifbyteordermm_jpg">
+        <item>false</item>
+        <item>0</item>
+        <item>0</item>
+        <item>true</item>
+        <item>0.0</item>
+        <item>0.0</item>
+        <item>0.0</item>
+        <item>LGE</item>
+        <item>Nexus 5</item>
+        <item>2.400</item>
+        <item>2016:01:29 15:44:58</item>
+        <item>0.017</item>
+        <item>0</item>
+        <item>3970/1000</item>
+        <item>0/1000</item>
+        <item>0</item>
+        <item>1970:01:01</item>
+        <item>0/1,0/1,0/10000</item>
+        <item>N</item>
+        <item>0/1,0/1,0/10000</item>
+        <item>E</item>
+        <item>GPS</item>
+        <item>00:00:00</item>
+        <item>176</item>
+        <item>144</item>
+        <item>146</item>
+        <item>0</item>
+        <item>0</item>
+    </array>
+    <array name="lg_g4_iso_800_dng">
+        <item>true</item>
+        <item>256</item>
+        <item>144</item>
+        <item>true</item>
+        <item>53.834507</item>
+        <item>10.69585</item>
+        <item>0.0</item>
+        <item>LGE</item>
+        <item>LG-H815</item>
+        <item>1.800</item>
+        <item>2015:11:12 16:46:18</item>
+        <item>0.0040</item>
+        <item>0.0</item>
+        <item>442/100</item>
+        <item>0/1</item>
+        <item>0</item>
+        <item>1970:01:17</item>
+        <item>53/1,50/1,423/100</item>
+        <item>N</item>
+        <item>10/1,41/1,4506/100</item>
+        <item>E</item>
+        <item />
+        <item>18:08:10</item>
+        <item>337</item>
+        <item>600</item>
+        <item>800</item>
+        <item>1</item>
+        <item>0</item>
+    </array>
+</resources>
diff --git a/tests/tests/media/src/android/media/cts/AdaptivePlaybackTest.java b/tests/tests/media/src/android/media/cts/AdaptivePlaybackTest.java
index ee5635c..e112b7e 100644
--- a/tests/tests/media/src/android/media/cts/AdaptivePlaybackTest.java
+++ b/tests/tests/media/src/android/media/cts/AdaptivePlaybackTest.java
@@ -16,7 +16,7 @@
 
 package android.media.cts;
 
-import com.android.cts.media.R;
+import android.media.cts.R;
 
 import android.content.Context;
 import android.content.pm.PackageManager;
diff --git a/tests/tests/media/src/android/media/cts/AudioAttributesTest.java b/tests/tests/media/src/android/media/cts/AudioAttributesTest.java
index 3e42b7e..99ab1ab 100644
--- a/tests/tests/media/src/android/media/cts/AudioAttributesTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioAttributesTest.java
@@ -34,8 +34,8 @@
     public void testParcelableDescribeContents() throws Exception {
         final AudioAttributes aa = new AudioAttributes.Builder()
                 .setUsage(AudioAttributes.USAGE_MEDIA).build();
-        final int c = aa.describeContents();
         assertNotNull("Failure to create the AudioAttributes", aa);
+        assertEquals(0, aa.describeContents());
     }
 
     // Test case 2: create an instance, marshall it and create a new instance,
diff --git a/tests/tests/media/src/android/media/cts/AudioEffectTest.java b/tests/tests/media/src/android/media/cts/AudioEffectTest.java
index dce7680..baa926e 100644
--- a/tests/tests/media/src/android/media/cts/AudioEffectTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioEffectTest.java
@@ -16,7 +16,7 @@
 
 package android.media.cts;
 
-import com.android.cts.media.R;
+import android.media.cts.R;
 
 import android.content.res.AssetFileDescriptor;
 import android.media.audiofx.AudioEffect;
@@ -59,6 +59,13 @@
     // AUDIOEFFECT TESTS:
     //----------------------------------
 
+    @Override
+    protected void tearDown() throws Exception {
+        releaseEffect();
+        terminateMediaPlayerLooper();
+        terminateListenerLooper();
+    }
+
     //-----------------------------------------------------------------
     // 0 - static methods
     //----------------------------------
diff --git a/tests/tests/media/src/android/media/cts/AudioFormatTest.java b/tests/tests/media/src/android/media/cts/AudioFormatTest.java
index 3c6a312..100e3b4 100644
--- a/tests/tests/media/src/android/media/cts/AudioFormatTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioFormatTest.java
@@ -18,6 +18,7 @@
 
 import android.cts.util.CtsAndroidTestCase;
 import android.media.AudioFormat;
+import android.os.Parcel;
 
 public class AudioFormatTest extends CtsAndroidTestCase {
 
@@ -138,4 +139,33 @@
         assertEquals("New AudioFormat doesn't report expected channel mask",
                 AudioFormat.CHANNEL_INVALID, copiedFormat.getChannelMask());
     }
+
+    // Test case 6: create an instance, marshall it and create a new instance,
+    //      check for equality
+    public void testParcel() throws Exception {
+        final int TEST_ENCODING = AudioFormat.ENCODING_PCM_16BIT;
+        final int TEST_SR = 48000;
+        final int TEST_CONF_POS = AudioFormat.CHANNEL_OUT_5POINT1;
+        // 6ch, like in 5.1 above offset by a randomly chosen number
+        final int TEST_CONF_IDX = 0x3F << 3;
+
+        final AudioFormat formatToMarshall = new AudioFormat.Builder()
+                .setEncoding(TEST_ENCODING).setSampleRate(TEST_SR)
+                .setChannelMask(TEST_CONF_POS).setChannelIndexMask(TEST_CONF_IDX).build();
+        assertNotNull("Failure to create the AudioFormat to marshall", formatToMarshall);
+        assertEquals(0, formatToMarshall.describeContents());
+
+        final Parcel srcParcel = Parcel.obtain();
+        final Parcel dstParcel = Parcel.obtain();
+
+        formatToMarshall.writeToParcel(srcParcel, 0 /*no public flags for marshalling*/);
+        final byte[] mbytes = srcParcel.marshall();
+        dstParcel.unmarshall(mbytes, 0, mbytes.length);
+        dstParcel.setDataPosition(0);
+        final AudioFormat unmarshalledFormat = AudioFormat.CREATOR.createFromParcel(dstParcel);
+
+        assertNotNull("Failure to unmarshall AudioFormat", unmarshalledFormat);
+        assertEquals("Source and destination AudioFormat not equal",
+                formatToMarshall, unmarshalledFormat);
+    }
 }
diff --git a/tests/tests/media/src/android/media/cts/AudioHelper.java b/tests/tests/media/src/android/media/cts/AudioHelper.java
index 6707ea6..dbe837d 100644
--- a/tests/tests/media/src/android/media/cts/AudioHelper.java
+++ b/tests/tests/media/src/android/media/cts/AudioHelper.java
@@ -67,6 +67,23 @@
         return vaf;
     }
 
+    /**
+     * Create and fill a short array with complete sine waves so we can
+     * hear buffer underruns more easily.
+     */
+    public static short[] createSineWavesShort(int numFrames, int samplesPerFrame,
+            int numCycles, double amplitude) {
+        final short[] data = new short[numFrames * samplesPerFrame];
+        final double rad = numCycles * 2.0 * Math.PI / numFrames;
+        for (int j = 0; j < data.length;) {
+            short sample = (short)(amplitude * Math.sin(j * rad) * Short.MAX_VALUE);
+            for (int sampleIndex = 0; sampleIndex < samplesPerFrame; sampleIndex++) {
+                data[j++] = sample;
+            }
+        }
+        return data;
+    }
+
     public static int frameSizeFromFormat(AudioFormat format) {
         return format.getChannelCount()
                 * format.getBytesPerSample(format.getEncoding());
diff --git a/tests/tests/media/src/android/media/cts/AudioManagerStub.java b/tests/tests/media/src/android/media/cts/AudioManagerStub.java
index 290b866..947acec 100644
--- a/tests/tests/media/src/android/media/cts/AudioManagerStub.java
+++ b/tests/tests/media/src/android/media/cts/AudioManagerStub.java
@@ -16,7 +16,7 @@
 
 package android.media.cts;
 
-import com.android.cts.media.R;
+import android.media.cts.R;
 
 import android.app.Activity;
 import android.cts.util.CTSResult;
diff --git a/tests/tests/media/src/android/media/cts/AudioManagerTest.java b/tests/tests/media/src/android/media/cts/AudioManagerTest.java
index a0163e5..d7ec5f1 100644
--- a/tests/tests/media/src/android/media/cts/AudioManagerTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioManagerTest.java
@@ -35,8 +35,6 @@
 import static android.media.AudioManager.VIBRATE_TYPE_RINGER;
 import static android.provider.Settings.System.SOUND_EFFECTS_ENABLED;
 
-import com.android.cts.media.R;
-
 import android.content.Context;
 import android.content.res.Resources;
 import android.media.AudioManager;
@@ -48,8 +46,6 @@
 import android.test.InstrumentationTestCase;
 import android.view.SoundEffectConstants;
 
-import java.util.TreeMap;
-
 public class AudioManagerTest extends InstrumentationTestCase {
 
     private final static int MP3_TO_PLAY = R.raw.testmp3;
@@ -85,8 +81,15 @@
     }
 
     public void testSoundEffects() throws Exception {
-        // set relative setting
-        mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
+        try {
+            Utils.toggleNotificationPolicyAccess(
+                    mContext.getPackageName(), getInstrumentation(), true);
+            // set relative setting
+            mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
+        } finally {
+            Utils.toggleNotificationPolicyAccess(
+                mContext.getPackageName(), getInstrumentation(), false);
+        }
         Settings.System.putInt(mContext.getContentResolver(), SOUND_EFFECTS_ENABLED, 1);
 
         // should hear sound after loadSoundEffects() called.
@@ -184,294 +187,420 @@
         if (mUseFixedVolume || !mHasVibrator) {
             return;
         }
-        // VIBRATE_SETTING_ON
-        mAudioManager.setVibrateSetting(VIBRATE_TYPE_NOTIFICATION, VIBRATE_SETTING_ON);
-        assertEquals(mHasVibrator ? VIBRATE_SETTING_ON : VIBRATE_SETTING_OFF,
-                mAudioManager.getVibrateSetting(VIBRATE_TYPE_NOTIFICATION));
-        mAudioManager.setRingerMode(RINGER_MODE_NORMAL);
-        assertEquals(mHasVibrator, mAudioManager.shouldVibrate(VIBRATE_TYPE_NOTIFICATION));
+        try {
+            Utils.toggleNotificationPolicyAccess(
+                    mContext.getPackageName(), getInstrumentation(), true);
+            // VIBRATE_SETTING_ON
+            mAudioManager.setVibrateSetting(VIBRATE_TYPE_NOTIFICATION, VIBRATE_SETTING_ON);
+            assertEquals(mHasVibrator ? VIBRATE_SETTING_ON : VIBRATE_SETTING_OFF,
+                    mAudioManager.getVibrateSetting(VIBRATE_TYPE_NOTIFICATION));
+            mAudioManager.setRingerMode(RINGER_MODE_NORMAL);
+            assertEquals(mHasVibrator, mAudioManager.shouldVibrate(VIBRATE_TYPE_NOTIFICATION));
 
-        mAudioManager.setRingerMode(RINGER_MODE_SILENT);
-        assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_NOTIFICATION));
+            mAudioManager.setRingerMode(RINGER_MODE_SILENT);
+            assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_NOTIFICATION));
 
-        mAudioManager.setRingerMode(RINGER_MODE_VIBRATE);
-        assertEquals(mHasVibrator ? RINGER_MODE_VIBRATE : RINGER_MODE_SILENT,
-                mAudioManager.getRingerMode());
-        assertEquals(mHasVibrator, mAudioManager.shouldVibrate(VIBRATE_TYPE_NOTIFICATION));
+            mAudioManager.setRingerMode(RINGER_MODE_VIBRATE);
+            assertEquals(mHasVibrator ? RINGER_MODE_VIBRATE : RINGER_MODE_SILENT,
+                    mAudioManager.getRingerMode());
+            assertEquals(mHasVibrator, mAudioManager.shouldVibrate(VIBRATE_TYPE_NOTIFICATION));
 
-        // VIBRATE_SETTING_OFF
-        mAudioManager.setVibrateSetting(VIBRATE_TYPE_NOTIFICATION, VIBRATE_SETTING_OFF);
-        assertEquals(VIBRATE_SETTING_OFF,
-                mAudioManager.getVibrateSetting(VIBRATE_TYPE_NOTIFICATION));
-        mAudioManager.setRingerMode(RINGER_MODE_NORMAL);
-        assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_NOTIFICATION));
+            // VIBRATE_SETTING_OFF
+            mAudioManager.setVibrateSetting(VIBRATE_TYPE_NOTIFICATION, VIBRATE_SETTING_OFF);
+            assertEquals(VIBRATE_SETTING_OFF,
+                    mAudioManager.getVibrateSetting(VIBRATE_TYPE_NOTIFICATION));
+            mAudioManager.setRingerMode(RINGER_MODE_NORMAL);
+            assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_NOTIFICATION));
 
-        mAudioManager.setRingerMode(RINGER_MODE_SILENT);
-        assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_NOTIFICATION));
+            mAudioManager.setRingerMode(RINGER_MODE_SILENT);
+            assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_NOTIFICATION));
 
-        mAudioManager.setRingerMode(RINGER_MODE_VIBRATE);
-        assertEquals(mHasVibrator ? RINGER_MODE_VIBRATE : RINGER_MODE_SILENT,
-                mAudioManager.getRingerMode());
-        assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_NOTIFICATION));
+            mAudioManager.setRingerMode(RINGER_MODE_VIBRATE);
+            assertEquals(mHasVibrator ? RINGER_MODE_VIBRATE : RINGER_MODE_SILENT,
+                    mAudioManager.getRingerMode());
+            assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_NOTIFICATION));
 
-        // VIBRATE_SETTING_ONLY_SILENT
-        mAudioManager.setVibrateSetting(VIBRATE_TYPE_NOTIFICATION, VIBRATE_SETTING_ONLY_SILENT);
-        assertEquals(mHasVibrator ? VIBRATE_SETTING_ONLY_SILENT : VIBRATE_SETTING_OFF,
-                mAudioManager.getVibrateSetting(VIBRATE_TYPE_NOTIFICATION));
-        mAudioManager.setRingerMode(RINGER_MODE_NORMAL);
-        assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_NOTIFICATION));
+            // VIBRATE_SETTING_ONLY_SILENT
+            mAudioManager.setVibrateSetting(VIBRATE_TYPE_NOTIFICATION, VIBRATE_SETTING_ONLY_SILENT);
+            assertEquals(mHasVibrator ? VIBRATE_SETTING_ONLY_SILENT : VIBRATE_SETTING_OFF,
+                    mAudioManager.getVibrateSetting(VIBRATE_TYPE_NOTIFICATION));
+            mAudioManager.setRingerMode(RINGER_MODE_NORMAL);
+            assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_NOTIFICATION));
 
-        mAudioManager.setRingerMode(RINGER_MODE_SILENT);
-        assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_NOTIFICATION));
+            mAudioManager.setRingerMode(RINGER_MODE_SILENT);
+            assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_NOTIFICATION));
 
-        mAudioManager.setRingerMode(RINGER_MODE_VIBRATE);
-        assertEquals(mHasVibrator ? RINGER_MODE_VIBRATE : RINGER_MODE_SILENT,
-                mAudioManager.getRingerMode());
-        assertEquals(mHasVibrator, mAudioManager.shouldVibrate(VIBRATE_TYPE_NOTIFICATION));
+            mAudioManager.setRingerMode(RINGER_MODE_VIBRATE);
+            assertEquals(mHasVibrator ? RINGER_MODE_VIBRATE : RINGER_MODE_SILENT,
+                    mAudioManager.getRingerMode());
+            assertEquals(mHasVibrator, mAudioManager.shouldVibrate(VIBRATE_TYPE_NOTIFICATION));
 
-        // VIBRATE_TYPE_NOTIFICATION
-        mAudioManager.setVibrateSetting(VIBRATE_TYPE_NOTIFICATION, VIBRATE_SETTING_ON);
-        assertEquals(mHasVibrator ? VIBRATE_SETTING_ON : VIBRATE_SETTING_OFF,
-                mAudioManager.getVibrateSetting(VIBRATE_TYPE_NOTIFICATION));
-        mAudioManager.setVibrateSetting(VIBRATE_TYPE_NOTIFICATION, VIBRATE_SETTING_OFF);
-        assertEquals(VIBRATE_SETTING_OFF, mAudioManager
-                .getVibrateSetting(VIBRATE_TYPE_NOTIFICATION));
-        mAudioManager.setVibrateSetting(VIBRATE_TYPE_NOTIFICATION, VIBRATE_SETTING_ONLY_SILENT);
-        assertEquals(mHasVibrator ? VIBRATE_SETTING_ONLY_SILENT : VIBRATE_SETTING_OFF,
-                mAudioManager.getVibrateSetting(VIBRATE_TYPE_NOTIFICATION));
+            // VIBRATE_TYPE_NOTIFICATION
+            mAudioManager.setVibrateSetting(VIBRATE_TYPE_NOTIFICATION, VIBRATE_SETTING_ON);
+            assertEquals(mHasVibrator ? VIBRATE_SETTING_ON : VIBRATE_SETTING_OFF,
+                    mAudioManager.getVibrateSetting(VIBRATE_TYPE_NOTIFICATION));
+            mAudioManager.setVibrateSetting(VIBRATE_TYPE_NOTIFICATION, VIBRATE_SETTING_OFF);
+            assertEquals(VIBRATE_SETTING_OFF, mAudioManager
+                    .getVibrateSetting(VIBRATE_TYPE_NOTIFICATION));
+            mAudioManager.setVibrateSetting(VIBRATE_TYPE_NOTIFICATION, VIBRATE_SETTING_ONLY_SILENT);
+            assertEquals(mHasVibrator ? VIBRATE_SETTING_ONLY_SILENT : VIBRATE_SETTING_OFF,
+                    mAudioManager.getVibrateSetting(VIBRATE_TYPE_NOTIFICATION));
+        } finally {
+            Utils.toggleNotificationPolicyAccess(
+                    mContext.getPackageName(), getInstrumentation(), false);
+        }
     }
 
     public void testVibrateRinger() throws Exception {
         if (mUseFixedVolume || !mHasVibrator) {
             return;
         }
-        // VIBRATE_TYPE_RINGER
-        mAudioManager.setVibrateSetting(VIBRATE_TYPE_RINGER, VIBRATE_SETTING_ON);
-        assertEquals(mHasVibrator ? VIBRATE_SETTING_ON : VIBRATE_SETTING_OFF,
-                mAudioManager.getVibrateSetting(VIBRATE_TYPE_RINGER));
-        mAudioManager.setRingerMode(RINGER_MODE_NORMAL);
-        assertEquals(mHasVibrator, mAudioManager.shouldVibrate(VIBRATE_TYPE_RINGER));
+        try {
+            Utils.toggleNotificationPolicyAccess(
+                    mContext.getPackageName(), getInstrumentation(), true);
+            // VIBRATE_TYPE_RINGER
+            mAudioManager.setVibrateSetting(VIBRATE_TYPE_RINGER, VIBRATE_SETTING_ON);
+            assertEquals(mHasVibrator ? VIBRATE_SETTING_ON : VIBRATE_SETTING_OFF,
+                    mAudioManager.getVibrateSetting(VIBRATE_TYPE_RINGER));
+            mAudioManager.setRingerMode(RINGER_MODE_NORMAL);
+            assertEquals(mHasVibrator, mAudioManager.shouldVibrate(VIBRATE_TYPE_RINGER));
 
-        mAudioManager.setRingerMode(RINGER_MODE_SILENT);
-        assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_RINGER));
+            mAudioManager.setRingerMode(RINGER_MODE_SILENT);
+            assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_RINGER));
 
-        mAudioManager.setRingerMode(RINGER_MODE_VIBRATE);
-        assertEquals(mHasVibrator ? RINGER_MODE_VIBRATE : RINGER_MODE_SILENT,
-                mAudioManager.getRingerMode());
-        assertEquals(mHasVibrator, mAudioManager.shouldVibrate(VIBRATE_TYPE_RINGER));
+            mAudioManager.setRingerMode(RINGER_MODE_VIBRATE);
+            assertEquals(mHasVibrator ? RINGER_MODE_VIBRATE : RINGER_MODE_SILENT,
+                    mAudioManager.getRingerMode());
+            assertEquals(mHasVibrator, mAudioManager.shouldVibrate(VIBRATE_TYPE_RINGER));
 
-        // VIBRATE_SETTING_OFF
-        mAudioManager.setVibrateSetting(VIBRATE_TYPE_RINGER, VIBRATE_SETTING_OFF);
-        assertEquals(VIBRATE_SETTING_OFF, mAudioManager.getVibrateSetting(VIBRATE_TYPE_RINGER));
-        mAudioManager.setRingerMode(RINGER_MODE_NORMAL);
-        assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_RINGER));
+            // VIBRATE_SETTING_OFF
+            mAudioManager.setVibrateSetting(VIBRATE_TYPE_RINGER, VIBRATE_SETTING_OFF);
+            assertEquals(VIBRATE_SETTING_OFF, mAudioManager.getVibrateSetting(VIBRATE_TYPE_RINGER));
+            mAudioManager.setRingerMode(RINGER_MODE_NORMAL);
+            assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_RINGER));
 
-        mAudioManager.setRingerMode(RINGER_MODE_SILENT);
-        assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_RINGER));
+            mAudioManager.setRingerMode(RINGER_MODE_SILENT);
+            assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_RINGER));
 
-        mAudioManager.setRingerMode(RINGER_MODE_VIBRATE);
-        assertEquals(mHasVibrator ? RINGER_MODE_VIBRATE : RINGER_MODE_SILENT,
-                mAudioManager.getRingerMode());
-        // Note: as of Froyo, if VIBRATE_TYPE_RINGER is set to OFF, it will
-        // not vibrate, even in RINGER_MODE_VIBRATE. This allows users to
-        // disable the vibration for incoming calls only.
-        assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_RINGER));
+            mAudioManager.setRingerMode(RINGER_MODE_VIBRATE);
+            assertEquals(mHasVibrator ? RINGER_MODE_VIBRATE : RINGER_MODE_SILENT,
+                    mAudioManager.getRingerMode());
+            // Note: as of Froyo, if VIBRATE_TYPE_RINGER is set to OFF, it will
+            // not vibrate, even in RINGER_MODE_VIBRATE. This allows users to
+            // disable the vibration for incoming calls only.
+            assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_RINGER));
 
-        // VIBRATE_SETTING_ONLY_SILENT
-        mAudioManager.setVibrateSetting(VIBRATE_TYPE_RINGER, VIBRATE_SETTING_ONLY_SILENT);
-        assertEquals(mHasVibrator ? VIBRATE_SETTING_ONLY_SILENT : VIBRATE_SETTING_OFF,
-                mAudioManager.getVibrateSetting(VIBRATE_TYPE_RINGER));
-        mAudioManager.setRingerMode(RINGER_MODE_NORMAL);
-        assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_RINGER));
+            // VIBRATE_SETTING_ONLY_SILENT
+            mAudioManager.setVibrateSetting(VIBRATE_TYPE_RINGER, VIBRATE_SETTING_ONLY_SILENT);
+            assertEquals(mHasVibrator ? VIBRATE_SETTING_ONLY_SILENT : VIBRATE_SETTING_OFF,
+                    mAudioManager.getVibrateSetting(VIBRATE_TYPE_RINGER));
+            mAudioManager.setRingerMode(RINGER_MODE_NORMAL);
+            assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_RINGER));
 
-        mAudioManager.setRingerMode(RINGER_MODE_SILENT);
-        assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_RINGER));
+            mAudioManager.setRingerMode(RINGER_MODE_SILENT);
+            assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_RINGER));
 
-        mAudioManager.setRingerMode(RINGER_MODE_VIBRATE);
-        assertEquals(mHasVibrator ? RINGER_MODE_VIBRATE : RINGER_MODE_SILENT,
-                mAudioManager.getRingerMode());
-        assertEquals(mHasVibrator, mAudioManager.shouldVibrate(VIBRATE_TYPE_RINGER));
+            mAudioManager.setRingerMode(RINGER_MODE_VIBRATE);
+            assertEquals(mHasVibrator ? RINGER_MODE_VIBRATE : RINGER_MODE_SILENT,
+                    mAudioManager.getRingerMode());
+            assertEquals(mHasVibrator, mAudioManager.shouldVibrate(VIBRATE_TYPE_RINGER));
 
-        // VIBRATE_TYPE_NOTIFICATION
-        mAudioManager.setVibrateSetting(VIBRATE_TYPE_RINGER, VIBRATE_SETTING_ON);
-        assertEquals(mHasVibrator ? VIBRATE_SETTING_ON : VIBRATE_SETTING_OFF,
-                mAudioManager.getVibrateSetting(VIBRATE_TYPE_RINGER));
-        mAudioManager.setVibrateSetting(VIBRATE_TYPE_RINGER, VIBRATE_SETTING_OFF);
-        assertEquals(VIBRATE_SETTING_OFF, mAudioManager.getVibrateSetting(VIBRATE_TYPE_RINGER));
-        mAudioManager.setVibrateSetting(VIBRATE_TYPE_RINGER, VIBRATE_SETTING_ONLY_SILENT);
-        assertEquals(mHasVibrator ? VIBRATE_SETTING_ONLY_SILENT : VIBRATE_SETTING_OFF,
-                mAudioManager.getVibrateSetting(VIBRATE_TYPE_RINGER));
+            // VIBRATE_TYPE_NOTIFICATION
+            mAudioManager.setVibrateSetting(VIBRATE_TYPE_RINGER, VIBRATE_SETTING_ON);
+            assertEquals(mHasVibrator ? VIBRATE_SETTING_ON : VIBRATE_SETTING_OFF,
+                    mAudioManager.getVibrateSetting(VIBRATE_TYPE_RINGER));
+            mAudioManager.setVibrateSetting(VIBRATE_TYPE_RINGER, VIBRATE_SETTING_OFF);
+            assertEquals(VIBRATE_SETTING_OFF, mAudioManager.getVibrateSetting(VIBRATE_TYPE_RINGER));
+            mAudioManager.setVibrateSetting(VIBRATE_TYPE_RINGER, VIBRATE_SETTING_ONLY_SILENT);
+            assertEquals(mHasVibrator ? VIBRATE_SETTING_ONLY_SILENT : VIBRATE_SETTING_OFF,
+                    mAudioManager.getVibrateSetting(VIBRATE_TYPE_RINGER));
+        } finally {
+            Utils.toggleNotificationPolicyAccess(
+                    mContext.getPackageName(), getInstrumentation(), false);
+        }
     }
 
     public void testAccessRingMode() throws Exception {
-        mAudioManager.setRingerMode(RINGER_MODE_NORMAL);
-        assertEquals(RINGER_MODE_NORMAL, mAudioManager.getRingerMode());
-
-        mAudioManager.setRingerMode(RINGER_MODE_SILENT);
-        // AudioService#setRingerMode() has:
-        // if (isTelevision) return;
-        if (mUseFixedVolume || mIsTelevision) {
+        try {
+            Utils.toggleNotificationPolicyAccess(
+                    mContext.getPackageName(), getInstrumentation(), true);
+            mAudioManager.setRingerMode(RINGER_MODE_NORMAL);
             assertEquals(RINGER_MODE_NORMAL, mAudioManager.getRingerMode());
-        } else {
+
+            mAudioManager.setRingerMode(RINGER_MODE_SILENT);
+            // AudioService#setRingerMode() has:
+            // if (isTelevision) return;
+            if (mUseFixedVolume || mIsTelevision) {
+                assertEquals(RINGER_MODE_NORMAL, mAudioManager.getRingerMode());
+            } else {
+                assertEquals(RINGER_MODE_SILENT, mAudioManager.getRingerMode());
+            }
+
+            mAudioManager.setRingerMode(RINGER_MODE_VIBRATE);
+            if (mUseFixedVolume || mIsTelevision) {
+                assertEquals(RINGER_MODE_NORMAL, mAudioManager.getRingerMode());
+            } else {
+                assertEquals(mHasVibrator ? RINGER_MODE_VIBRATE : RINGER_MODE_SILENT,
+                        mAudioManager.getRingerMode());
+            }
+        } finally {
+            Utils.toggleNotificationPolicyAccess(
+                    mContext.getPackageName(), getInstrumentation(), false);
+        }
+    }
+
+    public void testSetRingerModePolicyAccess() throws Exception {
+        if (mUseFixedVolume || mIsTelevision) {
+            return;
+        }
+        try {
+            // Apps without policy access cannot change silent -> normal or silent -> vibrate.
+            Utils.toggleNotificationPolicyAccess(
+                    mContext.getPackageName(), getInstrumentation(), true);
+            mAudioManager.setRingerMode(RINGER_MODE_SILENT);
             assertEquals(RINGER_MODE_SILENT, mAudioManager.getRingerMode());
-        }
+            Utils.toggleNotificationPolicyAccess(
+                    mContext.getPackageName(), getInstrumentation(), false);
 
-        mAudioManager.setRingerMode(RINGER_MODE_VIBRATE);
-        if (mUseFixedVolume || mIsTelevision) {
+            try {
+                mAudioManager.setRingerMode(RINGER_MODE_NORMAL);
+                fail("Apps without notification policy access cannot change ringer mode");
+            } catch (SecurityException e) {
+            }
+
+            try {
+                mAudioManager.setRingerMode(RINGER_MODE_VIBRATE);
+                fail("Apps without notification policy access cannot change ringer mode");
+            } catch (SecurityException e) {
+            }
+
+            // Apps without policy access cannot change normal -> silent.
+            Utils.toggleNotificationPolicyAccess(
+                    mContext.getPackageName(), getInstrumentation(), true);
+            mAudioManager.setRingerMode(RINGER_MODE_NORMAL);
             assertEquals(RINGER_MODE_NORMAL, mAudioManager.getRingerMode());
-        } else {
-            assertEquals(mHasVibrator ? RINGER_MODE_VIBRATE : RINGER_MODE_SILENT,
-                    mAudioManager.getRingerMode());
+            Utils.toggleNotificationPolicyAccess(
+                    mContext.getPackageName(), getInstrumentation(), false);
+
+            try {
+                mAudioManager.setRingerMode(RINGER_MODE_SILENT);
+                fail("Apps without notification policy access cannot change ringer mode");
+            } catch (SecurityException e) {
+            }
+            assertEquals(RINGER_MODE_NORMAL, mAudioManager.getRingerMode());
+
+            // Apps without policy access cannot change vibrate -> silent.
+            Utils.toggleNotificationPolicyAccess(
+                    mContext.getPackageName(), getInstrumentation(), true);
+            mAudioManager.setRingerMode(RINGER_MODE_VIBRATE);
+            assertEquals(RINGER_MODE_VIBRATE, mAudioManager.getRingerMode());
+            Utils.toggleNotificationPolicyAccess(
+                    mContext.getPackageName(), getInstrumentation(), false);
+
+            try {
+                mAudioManager.setRingerMode(RINGER_MODE_SILENT);
+                fail("Apps without notification policy access cannot change ringer mode");
+            } catch (SecurityException e) {
+            }
+
+            // Apps without policy access can change vibrate -> normal and vice versa.
+            assertEquals(RINGER_MODE_VIBRATE, mAudioManager.getRingerMode());
+            mAudioManager.setRingerMode(RINGER_MODE_NORMAL);
+            assertEquals(RINGER_MODE_NORMAL, mAudioManager.getRingerMode());
+            mAudioManager.setRingerMode(RINGER_MODE_VIBRATE);
+            assertEquals(RINGER_MODE_VIBRATE, mAudioManager.getRingerMode());
+        } finally {
+            Utils.toggleNotificationPolicyAccess(
+                    mContext.getPackageName(), getInstrumentation(), false);
         }
     }
 
+    public void testVolumeDndAffectedStream() throws Exception {
+        if (mUseFixedVolume || mHasVibrator) {
+            return;
+        }
+        Utils.toggleNotificationPolicyAccess(
+                mContext.getPackageName(), getInstrumentation(), true);
+        mAudioManager.setStreamVolume(
+                AudioManager.STREAM_SYSTEM, 7, AudioManager.FLAG_ALLOW_RINGER_MODES);
+        mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
+        Utils.toggleNotificationPolicyAccess(
+                mContext.getPackageName(), getInstrumentation(), false);
+        // 7 to 0, fail.
+        try {
+            mAudioManager.setStreamVolume(
+                    AudioManager.STREAM_SYSTEM, 0, AudioManager.FLAG_ALLOW_RINGER_MODES);
+            fail("Apps without notification policy access cannot change ringer mode");
+        } catch (SecurityException e) {}
+
+        // 7 to 1: success
+        mAudioManager.setStreamVolume(
+                AudioManager.STREAM_SYSTEM, 1, AudioManager.FLAG_ALLOW_RINGER_MODES);
+        assertEquals("setStreamVolume did not change volume",
+                1, mAudioManager.getStreamVolume(AudioManager.STREAM_SYSTEM));
+
+        // 0 to non-zero: fail.
+        Utils.toggleNotificationPolicyAccess(
+                mContext.getPackageName(), getInstrumentation(), true);
+        mAudioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
+        mAudioManager.setStreamVolume(
+                AudioManager.STREAM_SYSTEM, 0, AudioManager.FLAG_ALLOW_RINGER_MODES);
+        Utils.toggleNotificationPolicyAccess(
+                mContext.getPackageName(), getInstrumentation(), false);
+
+        try {
+            mAudioManager.setStreamVolume(
+                    AudioManager.STREAM_SYSTEM, 6, AudioManager.FLAG_ALLOW_RINGER_MODES);
+            fail("Apps without notification policy access cannot change ringer mode");
+        } catch (SecurityException e) {}
+    }
+
     public void testVolume() throws Exception {
-        int volume, volumeDelta;
-        int[] streams = { AudioManager.STREAM_ALARM,
-                          AudioManager.STREAM_MUSIC,
-                          AudioManager.STREAM_VOICE_CALL,
-                          AudioManager.STREAM_RING };
+        try {
+            Utils.toggleNotificationPolicyAccess(
+                    mContext.getPackageName(), getInstrumentation(), true);
+            int volume, volumeDelta;
+            int[] streams = {AudioManager.STREAM_ALARM,
+                    AudioManager.STREAM_MUSIC,
+                    AudioManager.STREAM_VOICE_CALL,
+                    AudioManager.STREAM_RING};
 
-        mAudioManager.adjustVolume(ADJUST_RAISE, 0);
-        mAudioManager.adjustSuggestedStreamVolume(
-                ADJUST_LOWER, USE_DEFAULT_STREAM_TYPE, 0);
-        int maxMusicVolume = mAudioManager.getStreamMaxVolume(STREAM_MUSIC);
+            mAudioManager.adjustVolume(ADJUST_RAISE, 0);
+            mAudioManager.adjustSuggestedStreamVolume(
+                    ADJUST_LOWER, USE_DEFAULT_STREAM_TYPE, 0);
+            int maxMusicVolume = mAudioManager.getStreamMaxVolume(STREAM_MUSIC);
 
-        for (int i = 0; i < streams.length; i++) {
-            // set ringer mode to back normal to not interfere with volume tests
-            mAudioManager.setRingerMode(RINGER_MODE_NORMAL);
+            for (int i = 0; i < streams.length; i++) {
+                // set ringer mode to back normal to not interfere with volume tests
+                mAudioManager.setRingerMode(RINGER_MODE_NORMAL);
 
-            int maxVolume = mAudioManager.getStreamMaxVolume(streams[i]);
-            int minVolume = mAudioManager.getStreamMinVolume(streams[i]);
+                int maxVolume = mAudioManager.getStreamMaxVolume(streams[i]);
+                int minVolume = mAudioManager.getStreamMinVolume(streams[i]);
 
-            // validate min
-            assertTrue(String.format("minVolume(%d) must be >= 0", minVolume), minVolume >= 0);
-            assertTrue(String.format("minVolume(%d) must be < maxVolume(%d)", minVolume, maxVolume),
-                    minVolume < maxVolume);
+                // validate min
+                assertTrue(String.format("minVolume(%d) must be >= 0", minVolume), minVolume >= 0);
+                assertTrue(String.format("minVolume(%d) must be < maxVolume(%d)", minVolume,
+                        maxVolume),
+                        minVolume < maxVolume);
 
-            mAudioManager.setStreamVolume(streams[i], 1, 0);
-            if (mUseFixedVolume) {
-                assertEquals(maxVolume, mAudioManager.getStreamVolume(streams[i]));
-                continue;
-            }
-            assertEquals(1, mAudioManager.getStreamVolume(streams[i]));
+                mAudioManager.setStreamVolume(streams[i], 1, 0);
+                if (mUseFixedVolume) {
+                    assertEquals(maxVolume, mAudioManager.getStreamVolume(streams[i]));
+                    continue;
+                }
+                assertEquals(1, mAudioManager.getStreamVolume(streams[i]));
 
-            if (streams[i] == AudioManager.STREAM_MUSIC && mAudioManager.isWiredHeadsetOn()) {
-                // due to new regulations, music sent over a wired headset may be volume limited
-                // until the user explicitly increases the limit, so we can't rely on being able
-                // to set the volume to getStreamMaxVolume(). Instead, determine the current limit
-                // by increasing the volume until it won't go any higher, then use that volume as
-                // the maximum for the purposes of this test
-                int curvol = 0;
-                int prevvol = 0;
-                do {
-                    prevvol = curvol;
-                    mAudioManager.adjustStreamVolume(streams[i], ADJUST_RAISE, 0);
-                    curvol = mAudioManager.getStreamVolume(streams[i]);
-                } while (curvol != prevvol);
-                maxVolume = maxMusicVolume = curvol;
-            }
-            mAudioManager.setStreamVolume(streams[i], maxVolume, 0);
-            mAudioManager.adjustStreamVolume(streams[i], ADJUST_RAISE, 0);
-            assertEquals(maxVolume, mAudioManager.getStreamVolume(streams[i]));
-
-            volumeDelta = getVolumeDelta(mAudioManager.getStreamVolume(streams[i]));
-            mAudioManager.adjustSuggestedStreamVolume(ADJUST_LOWER, streams[i], 0);
-            assertEquals(maxVolume - volumeDelta, mAudioManager.getStreamVolume(streams[i]));
-
-            // volume lower
-            mAudioManager.setStreamVolume(streams[i], maxVolume, 0);
-            volume = mAudioManager.getStreamVolume(streams[i]);
-            while (volume > minVolume) {
-                volumeDelta = getVolumeDelta(mAudioManager.getStreamVolume(streams[i]));
-                mAudioManager.adjustStreamVolume(streams[i], ADJUST_LOWER, 0);
-                assertEquals(Math.max(0, volume - volumeDelta),
-                             mAudioManager.getStreamVolume(streams[i]));
-                volume = mAudioManager.getStreamVolume(streams[i]);
-            }
-
-            mAudioManager.adjustStreamVolume(streams[i], ADJUST_SAME, 0);
-
-            // volume raise
-            mAudioManager.setStreamVolume(streams[i], 1, 0);
-            volume = mAudioManager.getStreamVolume(streams[i]);
-            while (volume < maxVolume) {
-                volumeDelta = getVolumeDelta(mAudioManager.getStreamVolume(streams[i]));
+                if (streams[i] == AudioManager.STREAM_MUSIC && mAudioManager.isWiredHeadsetOn()) {
+                    // due to new regulations, music sent over a wired headset may be volume limited
+                    // until the user explicitly increases the limit, so we can't rely on being able
+                    // to set the volume to getStreamMaxVolume(). Instead, determine the current limit
+                    // by increasing the volume until it won't go any higher, then use that volume as
+                    // the maximum for the purposes of this test
+                    int curvol = 0;
+                    int prevvol = 0;
+                    do {
+                        prevvol = curvol;
+                        mAudioManager.adjustStreamVolume(streams[i], ADJUST_RAISE, 0);
+                        curvol = mAudioManager.getStreamVolume(streams[i]);
+                    } while (curvol != prevvol);
+                    maxVolume = maxMusicVolume = curvol;
+                }
+                mAudioManager.setStreamVolume(streams[i], maxVolume, 0);
                 mAudioManager.adjustStreamVolume(streams[i], ADJUST_RAISE, 0);
-                assertEquals(Math.min(volume + volumeDelta, maxVolume),
-                             mAudioManager.getStreamVolume(streams[i]));
-                volume = mAudioManager.getStreamVolume(streams[i]);
-            }
-
-            // volume same
-            mAudioManager.setStreamVolume(streams[i], maxVolume, 0);
-            for (int k = 0; k < maxVolume; k++) {
-                mAudioManager.adjustStreamVolume(streams[i], ADJUST_SAME, 0);
                 assertEquals(maxVolume, mAudioManager.getStreamVolume(streams[i]));
+
+                volumeDelta = getVolumeDelta(mAudioManager.getStreamVolume(streams[i]));
+                mAudioManager.adjustSuggestedStreamVolume(ADJUST_LOWER, streams[i], 0);
+                assertEquals(maxVolume - volumeDelta, mAudioManager.getStreamVolume(streams[i]));
+
+                // volume lower
+                mAudioManager.setStreamVolume(streams[i], maxVolume, 0);
+                volume = mAudioManager.getStreamVolume(streams[i]);
+                while (volume > minVolume) {
+                    volumeDelta = getVolumeDelta(mAudioManager.getStreamVolume(streams[i]));
+                    mAudioManager.adjustStreamVolume(streams[i], ADJUST_LOWER, 0);
+                    assertEquals(Math.max(0, volume - volumeDelta),
+                            mAudioManager.getStreamVolume(streams[i]));
+                    volume = mAudioManager.getStreamVolume(streams[i]);
+                }
+
+                mAudioManager.adjustStreamVolume(streams[i], ADJUST_SAME, 0);
+
+                // volume raise
+                mAudioManager.setStreamVolume(streams[i], 1, 0);
+                volume = mAudioManager.getStreamVolume(streams[i]);
+                while (volume < maxVolume) {
+                    volumeDelta = getVolumeDelta(mAudioManager.getStreamVolume(streams[i]));
+                    mAudioManager.adjustStreamVolume(streams[i], ADJUST_RAISE, 0);
+                    assertEquals(Math.min(volume + volumeDelta, maxVolume),
+                            mAudioManager.getStreamVolume(streams[i]));
+                    volume = mAudioManager.getStreamVolume(streams[i]);
+                }
+
+                // volume same
+                mAudioManager.setStreamVolume(streams[i], maxVolume, 0);
+                for (int k = 0; k < maxVolume; k++) {
+                    mAudioManager.adjustStreamVolume(streams[i], ADJUST_SAME, 0);
+                    assertEquals(maxVolume, mAudioManager.getStreamVolume(streams[i]));
+                }
+
+                mAudioManager.setStreamVolume(streams[i], maxVolume, 0);
             }
 
-            mAudioManager.setStreamVolume(streams[i], maxVolume, 0);
+            if (mUseFixedVolume) {
+                return;
+            }
+
+            // adjust volume
+            mAudioManager.adjustVolume(ADJUST_RAISE, 0);
+
+            MediaPlayer mp = MediaPlayer.create(mContext, MP3_TO_PLAY);
+            assertNotNull(mp);
+            mp.setAudioStreamType(STREAM_MUSIC);
+            mp.setLooping(true);
+            mp.start();
+            Thread.sleep(TIME_TO_PLAY);
+            assertTrue(mAudioManager.isMusicActive());
+
+            // adjust volume as ADJUST_SAME
+            for (int k = 0; k < maxMusicVolume; k++) {
+                mAudioManager.adjustVolume(ADJUST_SAME, 0);
+                assertEquals(maxMusicVolume, mAudioManager.getStreamVolume(STREAM_MUSIC));
+            }
+
+            // adjust volume as ADJUST_RAISE
+            mAudioManager.setStreamVolume(STREAM_MUSIC, 0, 0);
+            volumeDelta = getVolumeDelta(mAudioManager.getStreamVolume(STREAM_MUSIC));
+            mAudioManager.adjustVolume(ADJUST_RAISE, 0);
+            assertEquals(Math.min(volumeDelta, maxMusicVolume),
+                    mAudioManager.getStreamVolume(STREAM_MUSIC));
+
+            // adjust volume as ADJUST_LOWER
+            mAudioManager.setStreamVolume(STREAM_MUSIC, maxMusicVolume, 0);
+            maxMusicVolume = mAudioManager.getStreamVolume(STREAM_MUSIC);
+            volumeDelta = getVolumeDelta(mAudioManager.getStreamVolume(STREAM_MUSIC));
+            mAudioManager.adjustVolume(ADJUST_LOWER, 0);
+            assertEquals(Math.max(0, maxMusicVolume - volumeDelta),
+                    mAudioManager.getStreamVolume(STREAM_MUSIC));
+
+            mp.stop();
+            mp.release();
+            Thread.sleep(TIME_TO_PLAY);
+            assertFalse(mAudioManager.isMusicActive());
+        } finally {
+            Utils.toggleNotificationPolicyAccess(
+                    mContext.getPackageName(), getInstrumentation(), false);
         }
-
-        if (mUseFixedVolume) {
-            return;
-        }
-
-        // adjust volume
-        mAudioManager.adjustVolume(ADJUST_RAISE, 0);
-
-        MediaPlayer mp = MediaPlayer.create(mContext, MP3_TO_PLAY);
-        assertNotNull(mp);
-        mp.setAudioStreamType(STREAM_MUSIC);
-        mp.setLooping(true);
-        mp.start();
-        Thread.sleep(TIME_TO_PLAY);
-        assertTrue(mAudioManager.isMusicActive());
-
-        // adjust volume as ADJUST_SAME
-        for (int k = 0; k < maxMusicVolume; k++) {
-            mAudioManager.adjustVolume(ADJUST_SAME, 0);
-            assertEquals(maxMusicVolume, mAudioManager.getStreamVolume(STREAM_MUSIC));
-        }
-
-        // adjust volume as ADJUST_RAISE
-        mAudioManager.setStreamVolume(STREAM_MUSIC, 0, 0);
-        volumeDelta = getVolumeDelta(mAudioManager.getStreamVolume(STREAM_MUSIC));
-        mAudioManager.adjustVolume(ADJUST_RAISE, 0);
-        assertEquals(Math.min(volumeDelta, maxMusicVolume),
-                     mAudioManager.getStreamVolume(STREAM_MUSIC));
-
-        // adjust volume as ADJUST_LOWER
-        mAudioManager.setStreamVolume(STREAM_MUSIC, maxMusicVolume, 0);
-        maxMusicVolume = mAudioManager.getStreamVolume(STREAM_MUSIC);
-        volumeDelta = getVolumeDelta(mAudioManager.getStreamVolume(STREAM_MUSIC));
-        mAudioManager.adjustVolume(ADJUST_LOWER, 0);
-        assertEquals(Math.max(0, maxMusicVolume - volumeDelta),
-                     mAudioManager.getStreamVolume(STREAM_MUSIC));
-
-        mp.stop();
-        mp.release();
-        Thread.sleep(TIME_TO_PLAY);
-        assertFalse(mAudioManager.isMusicActive());
     }
 
-    public void testMute() {
+    public void testMuteFixedVolume() throws Exception {
         int[] streams = {
                 AudioManager.STREAM_VOICE_CALL,
                 AudioManager.STREAM_MUSIC,
                 AudioManager.STREAM_RING,
                 AudioManager.STREAM_ALARM,
                 AudioManager.STREAM_NOTIFICATION,
-                AudioManager.STREAM_SYSTEM };
-
-        int muteAffectedStreams = System.getInt(mContext.getContentResolver(),
-                System.MUTE_STREAMS_AFFECTED,
-                        // Same defaults as in AudioService. Should be kept in
-                        // sync.
-                        ((1 << AudioManager.STREAM_MUSIC) |
-                                (1 << AudioManager.STREAM_RING) |
-                                (1 << AudioManager.STREAM_NOTIFICATION) |
-                                (1 << AudioManager.STREAM_SYSTEM)));
+                AudioManager.STREAM_SYSTEM};
         if (mUseFixedVolume) {
             for (int i = 0; i < streams.length; i++) {
                 mAudioManager.adjustStreamVolume(streams[i], AudioManager.ADJUST_MUTE, 0);
@@ -486,54 +615,87 @@
                 assertFalse("Muting should not affect a fixed volume device.",
                         mAudioManager.isStreamMute(streams[i]));
             }
+        }
+    }
+
+    public void testMute() throws Exception {
+        if (mUseFixedVolume) {
             return;
         }
-        // This ensures we're out of vibrate or silent modes.
-        mAudioManager.setRingerMode(RINGER_MODE_NORMAL);
-        for (int i = 0; i < streams.length; i++) {
-            // ensure each stream is on and turned up.
-            mAudioManager.setStreamVolume(streams[i], mAudioManager.getStreamMaxVolume(streams[i]),
-                    0);
-            if (((1 << streams[i]) & muteAffectedStreams) == 0) {
+
+        int[] streams = {
+                AudioManager.STREAM_VOICE_CALL,
+                AudioManager.STREAM_MUSIC,
+                AudioManager.STREAM_RING,
+                AudioManager.STREAM_ALARM,
+                AudioManager.STREAM_NOTIFICATION,
+                AudioManager.STREAM_SYSTEM };
+
+        try {
+            int muteAffectedStreams = System.getInt(mContext.getContentResolver(),
+                    System.MUTE_STREAMS_AFFECTED,
+                    // Same defaults as in AudioService. Should be kept in
+                    // sync.
+                    ((1 << AudioManager.STREAM_MUSIC) |
+                            (1 << AudioManager.STREAM_RING) |
+                            (1 << AudioManager.STREAM_NOTIFICATION) |
+                            (1 << AudioManager.STREAM_SYSTEM)));
+            Utils.toggleNotificationPolicyAccess(
+                    mContext.getPackageName(), getInstrumentation(), true);
+            // This ensures we're out of vibrate or silent modes.
+            mAudioManager.setRingerMode(RINGER_MODE_NORMAL);
+            Utils.toggleNotificationPolicyAccess(
+                    mContext.getPackageName(), getInstrumentation(), false);
+            for (int i = 0; i < streams.length; i++) {
+                // ensure each stream is on and turned up.
+                mAudioManager.setStreamVolume(streams[i],
+                        mAudioManager.getStreamMaxVolume(streams[i]),
+                        0);
+                if (((1 << streams[i]) & muteAffectedStreams) == 0) {
+                    mAudioManager.adjustStreamVolume(streams[i], AudioManager.ADJUST_MUTE, 0);
+                    assertFalse("Stream " + streams[i] + " should not be affected by mute.",
+                            mAudioManager.isStreamMute(streams[i]));
+                    mAudioManager.setStreamMute(streams[i], true);
+                    assertFalse("Stream " + streams[i] + " should not be affected by mute.",
+                            mAudioManager.isStreamMute(streams[i]));
+                    mAudioManager.adjustStreamVolume(streams[i], AudioManager.ADJUST_TOGGLE_MUTE,
+                            0);
+                    assertFalse("Stream " + streams[i] + " should not be affected by mute.",
+                            mAudioManager.isStreamMute(streams[i]));
+                    continue;
+                }
                 mAudioManager.adjustStreamVolume(streams[i], AudioManager.ADJUST_MUTE, 0);
-                assertFalse("Stream " + streams[i] + " should not be affected by mute.",
+                assertTrue("Muting stream " + streams[i] + " failed.",
                         mAudioManager.isStreamMute(streams[i]));
-                mAudioManager.setStreamMute(streams[i], true);
-                assertFalse("Stream " + streams[i] + " should not be affected by mute.",
+
+                mAudioManager.adjustStreamVolume(streams[i], AudioManager.ADJUST_UNMUTE, 0);
+                assertFalse("Unmuting stream " + streams[i] + " failed.",
                         mAudioManager.isStreamMute(streams[i]));
+
                 mAudioManager.adjustStreamVolume(streams[i], AudioManager.ADJUST_TOGGLE_MUTE, 0);
-                assertFalse("Stream " + streams[i] + " should not be affected by mute.",
+                assertTrue("Toggling mute on stream " + streams[i] + " failed.",
                         mAudioManager.isStreamMute(streams[i]));
-                continue;
+
+                mAudioManager.adjustStreamVolume(streams[i], AudioManager.ADJUST_TOGGLE_MUTE, 0);
+                assertFalse("Toggling mute on stream " + streams[i] + " failed.",
+                        mAudioManager.isStreamMute(streams[i]));
+
+                mAudioManager.setStreamMute(streams[i], true);
+                assertTrue("Muting stream " + streams[i] + " using setStreamMute failed",
+                        mAudioManager.isStreamMute(streams[i]));
+
+                // mute it three more times to verify the ref counting is gone.
+                mAudioManager.setStreamMute(streams[i], true);
+                mAudioManager.setStreamMute(streams[i], true);
+                mAudioManager.setStreamMute(streams[i], true);
+
+                mAudioManager.setStreamMute(streams[i], false);
+                assertFalse("Unmuting stream " + streams[i] + " using setStreamMute failed.",
+                        mAudioManager.isStreamMute(streams[i]));
             }
-            mAudioManager.adjustStreamVolume(streams[i], AudioManager.ADJUST_MUTE, 0);
-            assertTrue("Muting stream " + streams[i] + " failed.",
-                    mAudioManager.isStreamMute(streams[i]));
-
-            mAudioManager.adjustStreamVolume(streams[i], AudioManager.ADJUST_UNMUTE, 0);
-            assertFalse("Unmuting stream " + streams[i] + " failed.",
-                    mAudioManager.isStreamMute(streams[i]));
-
-            mAudioManager.adjustStreamVolume(streams[i], AudioManager.ADJUST_TOGGLE_MUTE, 0);
-            assertTrue("Toggling mute on stream " + streams[i] + " failed.",
-                    mAudioManager.isStreamMute(streams[i]));
-
-            mAudioManager.adjustStreamVolume(streams[i], AudioManager.ADJUST_TOGGLE_MUTE, 0);
-            assertFalse("Toggling mute on stream " + streams[i] + " failed.",
-                    mAudioManager.isStreamMute(streams[i]));
-
-            mAudioManager.setStreamMute(streams[i], true);
-            assertTrue("Muting stream " + streams[i] + " using setStreamMute failed",
-                    mAudioManager.isStreamMute(streams[i]));
-
-            // mute it three more times to verify the ref counting is gone.
-            mAudioManager.setStreamMute(streams[i], true);
-            mAudioManager.setStreamMute(streams[i], true);
-            mAudioManager.setStreamMute(streams[i], true);
-
-            mAudioManager.setStreamMute(streams[i], false);
-            assertFalse("Unmuting stream " + streams[i] + " using setStreamMute failed.",
-                    mAudioManager.isStreamMute(streams[i]));
+        } finally {
+            Utils.toggleNotificationPolicyAccess(
+                    mContext.getPackageName(), getInstrumentation(), false);
         }
     }
 
@@ -549,4 +711,5 @@
     private int getVolumeDelta(int volume) {
         return 1;
     }
+
 }
diff --git a/tests/tests/media/src/android/media/cts/AudioNativeTest.java b/tests/tests/media/src/android/media/cts/AudioNativeTest.java
index f52232f..9ec60bf 100644
--- a/tests/tests/media/src/android/media/cts/AudioNativeTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioNativeTest.java
@@ -16,11 +16,19 @@
 
 package android.media.cts;
 
+import android.content.Context;
 import android.content.pm.PackageManager;
 import android.cts.util.CtsAndroidTestCase;
-import android.util.Log;
+import android.media.AudioDeviceInfo;
+import android.media.AudioManager;
 
 public class AudioNativeTest extends CtsAndroidTestCase {
+    // Assume stereo here until b/23899814 is fixed.
+    public static final int MAX_CHANNEL_COUNT = 2;
+    public static final int MAX_INDEX_MASK = (1 << MAX_CHANNEL_COUNT) - 1;
+
+    private static final int CHANNEL_INDEX_MASK_MAGIC = 0x80000000;
+
     public void testAppendixBBufferQueue() {
         nativeAppendixBBufferQueue();
     }
@@ -189,6 +197,56 @@
                 1000 /* segmentDurationMs */, 10 /* numSegments */);
     }
 
+    public void testOutputChannelMasks() {
+        AudioTrackNative track = new AudioTrackNative();
+
+        // TODO: when b/23899814 is fixed, use AudioManager.getDevices() to enumerate
+        // actual devices and their channel counts instead of assuming stereo.
+        //
+        int maxOutputChannels = 2;
+
+        int validIndexMask = (1 << maxOutputChannels) - 1;
+
+        for (int mask = 0; mask <= MAX_INDEX_MASK; ++mask) {
+            int channelCount = Long.bitCount(mask);
+            boolean expectSuccess = (channelCount > 0)
+                && ((mask & validIndexMask) != 0);
+
+            // TODO: uncomment this line when b/27484181 is fixed.
+            // expectSuccess &&= ((mask & ~validIndexMask) == 0);
+
+            boolean ok = track.open(channelCount,
+                mask | CHANNEL_INDEX_MASK_MAGIC, 48000, false, 2);
+            track.close();
+            assertEquals(expectSuccess, ok);
+        }
+    }
+
+    public void testInputChannelMasks() {
+        AudioRecordNative recorder = new AudioRecordNative();
+
+        // TODO: when b/23899814 is fixed, use AudioManager.getDevices() to enumerate
+        // actual devices and their channel counts instead of assuming stereo.
+        //
+        int maxInputChannels = 2;
+
+        int validIndexMask = (1 << maxInputChannels) -1;
+
+        for (int mask = 0; mask <= MAX_INDEX_MASK; ++mask) {
+            int channelCount = Long.bitCount(mask);
+            boolean expectSuccess = (channelCount > 0)
+                && ((mask & validIndexMask) != 0);
+
+            // TODO: uncomment this line when b/27484181 is fixed.
+            // expectSuccess &&= ((mask & ~validIndexMask) == 0);
+
+            boolean ok = recorder.open(channelCount,
+                mask | CHANNEL_INDEX_MASK_MAGIC, 48000, false, 2);
+            recorder.close();
+            assertEquals(expectSuccess, ok);
+        }
+    }
+
     static {
         System.loadLibrary("audio_jni");
     }
diff --git a/tests/tests/media/src/android/media/cts/AudioPlayRoutingNative.java b/tests/tests/media/src/android/media/cts/AudioPlayRoutingNative.java
new file mode 100644
index 0000000..6156095
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/AudioPlayRoutingNative.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.media.cts;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.content.Context;
+import android.cts.util.CtsAndroidTestCase;
+import android.media.AudioDeviceInfo;
+import android.media.AudioManager;
+import android.media.AudioRouting;
+import android.test.AndroidTestCase;
+import android.util.Log;
+
+import com.android.ndkaudio.AudioPlayer;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+public class AudioPlayRoutingNative extends AndroidTestCase {
+    private static final String TAG = "AudioPlayRoutingNative";
+
+    private AudioManager mAudioManager;
+
+    static {
+        System.loadLibrary("ndkaudioLib");
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        // get the AudioManager
+        mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
+        assertNotNull(mAudioManager);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    //
+    // Tests
+    //
+
+    // Test a basic Aquire/Release cycle on the default player.
+    public void testAquireDefaultProxy() throws Exception {
+        AudioPlayer player = new AudioPlayer();
+        player.ClearLastSLResult();
+        player.RealizePlayer();
+        player.RealizeRoutingProxy();
+
+        AudioRouting routingObj = player.GetRoutingInterface();
+        assertNotNull(routingObj);
+
+        // Not allowed to acquire twice
+        routingObj = player.GetRoutingInterface();
+        assertNull(routingObj);
+        assertTrue(player.GetLastSLResult() != 0);
+
+        player.ReleaseRoutingInterface(routingObj);
+        assertTrue(player.GetLastSLResult() == 0);
+    }
+
+    // Test an Aquire before the OpenSL ES player is Realized.
+    public void testAquirePreRealizeDefaultProxy() throws Exception {
+        AudioPlayer player = new AudioPlayer();
+        player.ClearLastSLResult();
+        player.RealizeRoutingProxy();
+        assertTrue(player.GetLastSLResult() == 0);
+
+        AudioRouting routingObj = player.GetRoutingInterface();
+        assertTrue(player.GetLastSLResult() == 0);
+        assertNotNull(routingObj);
+
+        player.RealizePlayer();
+        assertTrue(player.GetLastSLResult() == 0);
+
+        player.ReleaseRoutingInterface(routingObj);
+        assertTrue(player.GetLastSLResult() == 0);
+    }
+
+    // Test actually setting the routing through the enumerated devices.
+    public void testRouting() {
+        AudioPlayer player = new AudioPlayer();
+        player.ClearLastSLResult();
+        player.RealizePlayer();
+        player.RealizeRoutingProxy();
+
+        AudioRouting routingObj = player.GetRoutingInterface();
+        assertNotNull(routingObj);
+
+        AudioDeviceInfo[] deviceList;
+        deviceList = mAudioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS);
+        assertTrue(deviceList != null);
+        for (AudioDeviceInfo devInfo : deviceList) {
+            assertTrue(routingObj.setPreferredDevice(devInfo));
+        }
+
+        player.ReleaseRoutingInterface(routingObj);
+        assertTrue(player.GetLastSLResult() == 0);
+    }
+}
diff --git a/tests/tests/media/src/android/media/cts/AudioPreProcessingTest.java b/tests/tests/media/src/android/media/cts/AudioPreProcessingTest.java
index de5b698..27aa866 100644
--- a/tests/tests/media/src/android/media/cts/AudioPreProcessingTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioPreProcessingTest.java
@@ -16,7 +16,7 @@
 
 package android.media.cts;
 
-import com.android.cts.media.R;
+import android.media.cts.R;
 
 import android.content.pm.PackageManager;
 import android.media.AudioFormat;
diff --git a/tests/tests/media/src/android/media/cts/AudioRecordNative.java b/tests/tests/media/src/android/media/cts/AudioRecordNative.java
index 18df8ee..3c7632e 100644
--- a/tests/tests/media/src/android/media/cts/AudioRecordNative.java
+++ b/tests/tests/media/src/android/media/cts/AudioRecordNative.java
@@ -40,8 +40,13 @@
     }
 
     public boolean open(int numChannels, int sampleRate, boolean useFloat, int numBuffers) {
-        if (nativeOpen(mNativeRecordInJavaObj, numChannels, sampleRate, useFloat, numBuffers)
-                == STATUS_OK) {
+        return open(numChannels, 0, sampleRate, useFloat,numBuffers);
+    }
+
+    public boolean open(int numChannels, int channelMask, int sampleRate,
+            boolean useFloat, int numBuffers) {
+        if (nativeOpen(mNativeRecordInJavaObj, numChannels, channelMask,
+                sampleRate, useFloat, numBuffers) == STATUS_OK) {
             mChannelCount = numChannels;
             return true;
         }
@@ -104,7 +109,12 @@
 
     public static boolean test(int numChannels, int sampleRate, boolean useFloat,
             int msecPerBuffer, int numBuffers) {
-        return nativeTest(numChannels, sampleRate, useFloat, msecPerBuffer, numBuffers)
+        return test(numChannels, 0, sampleRate, useFloat, msecPerBuffer, numBuffers);
+    }
+
+    public static boolean test(int numChannels, int channelMask, int sampleRate, boolean useFloat,
+            int msecPerBuffer, int numBuffers) {
+        return nativeTest(numChannels, channelMask, sampleRate, useFloat, msecPerBuffer, numBuffers)
                 == STATUS_OK;
     }
 
@@ -132,7 +142,8 @@
     private static native long nativeCreateRecord();
     private static native void nativeDestroyRecord(long record);
     private static native int nativeOpen(
-            long record, int numChannels, int sampleRate, boolean useFloat, int numBuffers);
+            long record, int numChannels, int channelMask,
+            int sampleRate, boolean useFloat, int numBuffers);
     private static native void nativeClose(long record);
     private static native int nativeStart(long record);
     private static native int nativeStop(long record);
@@ -149,5 +160,6 @@
 
     // native interface for all-in-one testing, no record handle required.
     private static native int nativeTest(
-            int numChannels, int sampleRate, boolean useFloat, int msecPerBuffer, int numBuffers);
+            int numChannels, int channelMask, int sampleRate,
+            boolean useFloat, int msecPerBuffer, int numBuffers);
 }
diff --git a/tests/tests/media/src/android/media/cts/AudioRecordRoutingNative.java b/tests/tests/media/src/android/media/cts/AudioRecordRoutingNative.java
new file mode 100644
index 0000000..c965e14
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/AudioRecordRoutingNative.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.media.cts;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.content.Context;
+import android.media.AudioDeviceInfo;
+import android.media.AudioManager;
+import android.media.AudioRouting;
+import android.test.AndroidTestCase;
+import android.util.Log;
+
+import com.android.ndkaudio.AudioRecorder;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+public class AudioRecordRoutingNative extends AndroidTestCase {
+    private static final String TAG = "AudioRecordRoutingNative";
+
+    private AudioManager mAudioManager;
+
+    static {
+        System.loadLibrary("ndkaudioLib");
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        // get the AudioManager
+        mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
+        assertNotNull(mAudioManager);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    //
+    // Tests
+    //
+
+    // Test a basic Aquire/Release cycle on the default recorder.
+    public void testAquireDefaultProxy() throws Exception {
+        AudioRecorder recorder = new AudioRecorder();
+        recorder.ClearLastSLResult();
+        recorder.RealizeRecorder();
+        recorder.RealizeRoutingProxy();
+
+        AudioRouting routingObj = recorder.GetRoutingInterface();
+        assertNotNull(routingObj);
+
+        // Not allowed to acquire twice
+        routingObj = recorder.GetRoutingInterface();
+        assertNull(routingObj);
+        assertTrue(recorder.GetLastSLResult() != 0);
+
+        recorder.ReleaseRoutingInterface(routingObj);
+        assertTrue(recorder.GetLastSLResult() == 0);
+    }
+
+    // Test an Aquire before the OpenSL ES recorder is Realized.
+    public void testAquirePreRealizeDefaultProxy() throws Exception {
+        AudioRecorder recorder = new AudioRecorder();
+        recorder.ClearLastSLResult();
+        recorder.RealizeRecorder();
+        recorder.RealizeRoutingProxy();
+        assertTrue(recorder.GetLastSLResult() == 0);
+
+        AudioRouting routingObj = recorder.GetRoutingInterface();
+        assertTrue(recorder.GetLastSLResult() == 0);
+        assertNotNull(routingObj);
+
+        recorder.RealizeRecorder();
+        assertTrue(recorder.GetLastSLResult() == 0);
+
+        recorder.ReleaseRoutingInterface(routingObj);
+        assertTrue(recorder.GetLastSLResult() == 0);
+    }
+
+    // Test actually setting the routing through the enumerated devices.
+    public void testRouting() {
+        AudioRecorder recorder = new AudioRecorder();
+        recorder.ClearLastSLResult();
+        recorder.RealizeRecorder();
+        recorder.RealizeRoutingProxy();
+
+        AudioRouting routingObj = recorder.GetRoutingInterface();
+        assertNotNull(routingObj);
+
+        AudioDeviceInfo[] deviceList;
+        deviceList = mAudioManager.getDevices(AudioManager.GET_DEVICES_INPUTS);
+        assertTrue(deviceList != null);
+        for (AudioDeviceInfo devInfo : deviceList) {
+            assertTrue(routingObj.setPreferredDevice(devInfo));
+        }
+
+        recorder.ReleaseRoutingInterface(routingObj);
+        assertTrue(recorder.GetLastSLResult() == 0);
+    }
+}
diff --git a/tests/tests/media/src/android/media/cts/AudioRecordTest.java b/tests/tests/media/src/android/media/cts/AudioRecordTest.java
index 41afab4..afd6997 100644
--- a/tests/tests/media/src/android/media/cts/AudioRecordTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioRecordTest.java
@@ -16,9 +16,6 @@
 
 package android.media.cts;
 
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-
 import android.app.ActivityManager;
 import android.content.Context;
 import android.content.pm.PackageManager;
@@ -27,17 +24,22 @@
 import android.media.AudioManager;
 import android.media.AudioRecord;
 import android.media.AudioRecord.OnRecordPositionUpdateListener;
+import android.media.AudioTimestamp;
 import android.media.AudioTrack;
 import android.media.MediaRecorder;
 import android.media.MediaSyncEvent;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
+import android.os.SystemClock;
 import android.util.Log;
 
-import com.android.cts.util.ReportLog;
-import com.android.cts.util.ResultType;
-import com.android.cts.util.ResultUnit;
+import com.android.compatibility.common.util.DeviceReportLog;
+import com.android.compatibility.common.util.ResultType;
+import com.android.compatibility.common.util.ResultUnit;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
 
 public class AudioRecordTest extends CtsAndroidTestCase {
     private final static String TAG = "AudioRecordTest";
@@ -469,6 +471,101 @@
         assertTrue(TEST_NAME + ": buffer frame count", observedBufferSize2 > 0);
     }
 
+    public void testTimestamp() throws Exception {
+        if (!hasMicrophone()) {
+            return;
+        }
+        final String TEST_NAME = "testTimestamp";
+        AudioRecord record = null;
+
+        try {
+            final int NANOS_PER_MILLIS = 1000000;
+            final long RECORD_TIME_IN_MS = 2000;
+            final long RECORD_TIME_IN_NANOS = RECORD_TIME_IN_MS * NANOS_PER_MILLIS;
+            final int RECORD_ENCODING = AudioFormat.ENCODING_PCM_16BIT; // fixed at this time.
+            final int RECORD_CHANNEL_MASK = AudioFormat.CHANNEL_IN_STEREO;
+            final int RECORD_SAMPLE_RATE = 23456;  // requires resampling
+            record = new AudioRecord.Builder()
+                    .setAudioFormat(new AudioFormat.Builder()
+                            .setSampleRate(RECORD_SAMPLE_RATE)
+                            .setChannelMask(RECORD_CHANNEL_MASK)
+                            .setEncoding(RECORD_ENCODING)
+                            .build())
+                    .build();
+
+            // For our tests, we could set test duration by timed sleep or by # frames received.
+            // Since we don't know *exactly* when AudioRecord actually begins recording,
+            // we end the test by # frames read.
+            final int numChannels =
+                    AudioFormat.channelCountFromInChannelMask(RECORD_CHANNEL_MASK);
+            final int bytesPerSample = AudioFormat.getBytesPerSample(RECORD_ENCODING);
+            final int bytesPerFrame = numChannels * bytesPerSample;
+            // careful about integer overflow in the formula below:
+            final int targetFrames =
+                    (int)((long)RECORD_TIME_IN_MS * RECORD_SAMPLE_RATE / 1000);
+            final int targetSamples = targetFrames * numChannels;
+            final int BUFFER_FRAMES = 512;
+            final int BUFFER_SAMPLES = BUFFER_FRAMES * numChannels;
+
+            final int tries = 2;
+            for (int i = 0; i < tries; ++i) {
+                long startTime = System.nanoTime();
+                long startTimeBoot = android.os.SystemClock.elapsedRealtimeNanos();
+
+                record.startRecording();
+
+                AudioTimestamp startTs = new AudioTimestamp();
+                int samplesRead = 0;
+                boolean timestampRead = false;
+                // For 16 bit data, use shorts
+                short[] shortData = new short[BUFFER_SAMPLES];
+                while (samplesRead < targetSamples) {
+                    int amount = samplesRead == 0 ? numChannels :
+                        Math.min(BUFFER_SAMPLES, targetSamples - samplesRead);
+                    int ret = record.read(shortData, 0, amount);
+                    assertEquals(TEST_NAME, amount, ret);
+                    // timestamps follow a different path than data, so it is conceivable
+                    // that first data arrives before the first timestamp is ready.
+                    if (!timestampRead) {
+                        timestampRead =
+                                record.getTimestamp(startTs, AudioTimestamp.TIMEBASE_MONOTONIC)
+                                    == AudioRecord.SUCCESS;
+                    }
+                    samplesRead += ret;
+                }
+                record.stop();
+
+                // stop is synchronous, but need not be in the future.
+                final long SLEEP_AFTER_STOP_FOR_INACTIVITY_MS = 1000;
+                Thread.sleep(SLEEP_AFTER_STOP_FOR_INACTIVITY_MS);
+
+                AudioTimestamp stopTs = new AudioTimestamp();
+                AudioTimestamp stopTsBoot = new AudioTimestamp();
+
+                assertEquals(AudioRecord.SUCCESS,
+                        record.getTimestamp(stopTs, AudioTimestamp.TIMEBASE_MONOTONIC));
+                assertEquals(AudioRecord.SUCCESS,
+                        record.getTimestamp(stopTsBoot, AudioTimestamp.TIMEBASE_BOOTTIME));
+
+                // printTimestamp("timestamp Monotonic", ts);
+                // printTimestamp("timestamp Boottime", tsBoot);
+                // Log.d(TEST_NAME, "startTime Monotonic " + startTime);
+                // Log.d(TEST_NAME, "startTime Boottime " + startTimeBoot);
+
+                assertEquals(stopTs.framePosition, stopTsBoot.framePosition);
+                assertTrue(stopTs.framePosition >= targetFrames);
+                assertTrue(stopTs.nanoTime - startTime > RECORD_TIME_IN_NANOS);
+                assertTrue(stopTsBoot.nanoTime - startTimeBoot > RECORD_TIME_IN_NANOS);
+                verifyContinuousTimestamps(startTs, stopTs, RECORD_SAMPLE_RATE);
+            }
+        } finally {
+            if (record != null) {
+                record.release();
+                record = null;
+            }
+        }
+    }
+
     public void testSynchronizedRecord() throws Exception {
         if (!hasMicrophone()) {
             return;
@@ -652,7 +749,7 @@
             return;
         }
         // audit recording plays back recorded audio, so use longer test timing
-        final int TEST_TIME_MS = auditRecording ? 10000 : 2000;
+        final int TEST_TIME_MS = auditRecording ? 60000 : 2000;
         final int TEST_SOURCE = MediaRecorder.AudioSource.DEFAULT;
         mIsHandleMessageCalled = false;
 
@@ -724,6 +821,11 @@
             assertEquals(AudioRecord.SUCCESS,
                     record.setPositionNotificationPeriod(updatePeriodInFrames));
 
+            // at the start, there is no timestamp.
+            AudioTimestamp startTs = new AudioTimestamp();
+            assertEquals(AudioRecord.ERROR_INVALID_OPERATION,
+                    record.getTimestamp(startTs, AudioTimestamp.TIMEBASE_MONOTONIC));
+
             listener.start(TEST_SR);
             record.startRecording();
             assertEquals(AudioRecord.RECORDSTATE_RECORDING, record.getRecordingState());
@@ -736,11 +838,13 @@
             final int bytesPerSample = AudioFormat.getBytesPerSample(TEST_FORMAT);
             final int bytesPerFrame = numChannels * bytesPerSample;
             // careful about integer overflow in the formula below:
-            final int targetSamples = (int)((long)TEST_TIME_MS * TEST_SR * numChannels / 1000);
+            final int targetFrames = (int)((long)TEST_TIME_MS * TEST_SR / 1000);
+            final int targetSamples = targetFrames * numChannels;
             final int BUFFER_FRAMES = 512;
             final int BUFFER_SAMPLES = BUFFER_FRAMES * numChannels;
             // TODO: verify behavior when buffer size is not a multiple of frame size.
 
+            int startTimeAtFrame = 0;
             int samplesRead = 0;
             if (useByteBuffer) {
                 ByteBuffer byteBuffer =
@@ -776,6 +880,11 @@
                         firstSampleTime = System.currentTimeMillis();
                     }
                     samplesRead += ret / bytesPerSample;
+                    if (startTimeAtFrame == 0 && ret > 0 &&
+                            record.getTimestamp(startTs, AudioTimestamp.TIMEBASE_MONOTONIC) ==
+                            AudioRecord.SUCCESS) {
+                        startTimeAtFrame = samplesRead / numChannels;
+                    }
                 }
             } else {
                 switch (TEST_FORMAT) {
@@ -799,6 +908,11 @@
                             firstSampleTime = System.currentTimeMillis();
                         }
                         samplesRead += ret;
+                        if (startTimeAtFrame == 0 && ret > 0 &&
+                                record.getTimestamp(startTs, AudioTimestamp.TIMEBASE_MONOTONIC) ==
+                                AudioRecord.SUCCESS) {
+                            startTimeAtFrame = samplesRead / numChannels;
+                        }
                     }
                 } break;
                 case AudioFormat.ENCODING_PCM_16BIT: {
@@ -821,6 +935,11 @@
                             firstSampleTime = System.currentTimeMillis();
                         }
                         samplesRead += ret;
+                        if (startTimeAtFrame == 0 && ret > 0 &&
+                                record.getTimestamp(startTs, AudioTimestamp.TIMEBASE_MONOTONIC) ==
+                                AudioRecord.SUCCESS) {
+                            startTimeAtFrame = samplesRead / numChannels;
+                        }
                     }
                 } break;
                 case AudioFormat.ENCODING_PCM_FLOAT: {
@@ -842,6 +961,11 @@
                             firstSampleTime = System.currentTimeMillis();
                         }
                         samplesRead += ret;
+                        if (startTimeAtFrame == 0 && ret > 0 &&
+                                record.getTimestamp(startTs, AudioTimestamp.TIMEBASE_MONOTONIC) ==
+                                AudioRecord.SUCCESS) {
+                            startTimeAtFrame = samplesRead / numChannels;
+                        }
                     }
                 } break;
                 }
@@ -889,6 +1013,31 @@
             Thread.sleep(SLEEP_AFTER_STOP_FOR_EVENTS_MS);
             listener.stop();
 
+            // get stop timestamp
+            AudioTimestamp stopTs = new AudioTimestamp();
+            assertEquals(AudioRecord.SUCCESS,
+                    record.getTimestamp(stopTs, AudioTimestamp.TIMEBASE_MONOTONIC));
+            AudioTimestamp stopTsBoot = new AudioTimestamp();
+            assertEquals(AudioRecord.SUCCESS,
+                    record.getTimestamp(stopTsBoot, AudioTimestamp.TIMEBASE_BOOTTIME));
+
+            // printTimestamp("startTs", startTs);
+            // printTimestamp("stopTs", stopTs);
+            // printTimestamp("stopTsBoot", stopTsBoot);
+            // Log.d(TAG, "time Monotonic " + System.nanoTime());
+            // Log.d(TAG, "time Boottime " + SystemClock.elapsedRealtimeNanos());
+
+            // stop should not reset timestamps
+            assertTrue(stopTs.framePosition >= targetFrames);
+            assertEquals(stopTs.framePosition, stopTsBoot.framePosition);
+            assertTrue(stopTs.nanoTime > 0);
+
+            // timestamps follow a different path than data, so it is conceivable
+            // that first data arrives before the first timestamp is ready.
+            assertTrue(startTimeAtFrame > 0); // we read a start timestamp
+
+            verifyContinuousTimestamps(startTs, stopTs, TEST_SR);
+
             // clean up
             if (makeSomething != null) {
                 makeSomething.join();
@@ -966,38 +1115,39 @@
         }
 
         // report this
-        ReportLog log = getReportLog();
-        log.printValue(reportName + ": startRecording lag", coldInputStartTime,
+        DeviceReportLog log = new DeviceReportLog();
+        log.addValue(reportName + ": startRecording lag", coldInputStartTime,
                 ResultType.LOWER_BETTER, ResultUnit.MS);
-        log.printValue(reportName + ": stop execution time", stopTime - stopRequestTime,
+        log.addValue(reportName + ": stop execution time", stopTime - stopRequestTime,
                 ResultType.LOWER_BETTER, ResultUnit.MS);
-        log.printValue(reportName + ": Total record time expected", TEST_TIME_MS,
+        log.addValue(reportName + ": Total record time expected", TEST_TIME_MS,
                 ResultType.NEUTRAL, ResultUnit.MS);
-        log.printValue(reportName + ": Total record time actual", endTime - firstSampleTime,
+        log.addValue(reportName + ": Total record time actual", endTime - firstSampleTime,
                 ResultType.NEUTRAL, ResultUnit.MS);
-        log.printValue(reportName + ": Total markers expected", markerPeriods,
+        log.addValue(reportName + ": Total markers expected", markerPeriods,
                 ResultType.NEUTRAL, ResultUnit.COUNT);
-        log.printValue(reportName + ": Total markers actual", markerList.size(),
+        log.addValue(reportName + ": Total markers actual", markerList.size(),
                 ResultType.NEUTRAL, ResultUnit.COUNT);
-        log.printValue(reportName + ": Total periods expected", updatePeriods,
+        log.addValue(reportName + ": Total periods expected", updatePeriods,
                 ResultType.NEUTRAL, ResultUnit.COUNT);
-        log.printValue(reportName + ": Total periods actual", periodicList.size(),
+        log.addValue(reportName + ": Total periods actual", periodicList.size(),
                 ResultType.NEUTRAL, ResultUnit.COUNT);
-        log.printValue(reportName + ": Average Marker diff", markerStat.getAvg(),
+        log.addValue(reportName + ": Average Marker diff", markerStat.getAvg(),
                 ResultType.LOWER_BETTER, ResultUnit.MS);
-        log.printValue(reportName + ": Maximum Marker abs diff", markerStat.getMaxAbs(),
+        log.addValue(reportName + ": Maximum Marker abs diff", markerStat.getMaxAbs(),
                 ResultType.LOWER_BETTER, ResultUnit.MS);
-        log.printValue(reportName + ": Average Marker abs diff", markerStat.getAvgAbs(),
+        log.addValue(reportName + ": Average Marker abs diff", markerStat.getAvgAbs(),
                 ResultType.LOWER_BETTER, ResultUnit.MS);
-        log.printValue(reportName + ": Average Periodic diff", periodicStat.getAvg(),
+        log.addValue(reportName + ": Average Periodic diff", periodicStat.getAvg(),
                 ResultType.LOWER_BETTER, ResultUnit.MS);
-        log.printValue(reportName + ": Maximum Periodic abs diff", periodicStat.getMaxAbs(),
+        log.addValue(reportName + ": Maximum Periodic abs diff", periodicStat.getMaxAbs(),
                 ResultType.LOWER_BETTER, ResultUnit.MS);
-        log.printValue(reportName + ": Average Periodic abs diff", periodicStat.getAvgAbs(),
+        log.addValue(reportName + ": Average Periodic abs diff", periodicStat.getAvgAbs(),
                 ResultType.LOWER_BETTER, ResultUnit.MS);
-        log.printSummary(reportName + ": Unified abs diff",
+        log.setSummary(reportName + ": Unified abs diff",
                 (periodicStat.getAvgAbs() + markerStat.getAvgAbs()) / 2,
                 ResultType.LOWER_BETTER, ResultUnit.MS);
+        log.submit(getInstrumentation());
     }
 
     private class MockOnRecordPositionUpdateListener
@@ -1091,4 +1241,24 @@
         return ((ActivityManager) getContext().getSystemService(Context.ACTIVITY_SERVICE))
                 .isLowRamDevice();
     }
+
+    private void verifyContinuousTimestamps(
+            AudioTimestamp startTs, AudioTimestamp stopTs, int sampleRate)
+            throws Exception {
+        final long timeDiff = stopTs.nanoTime - startTs.nanoTime;
+        final long frameDiff = stopTs.framePosition - startTs.framePosition;
+        final long NANOS_PER_SECOND = 1000000000;
+        final long timeByFrames = frameDiff * NANOS_PER_SECOND / sampleRate;
+        final double ratio = (double)timeDiff / timeByFrames;
+
+        // Usually the ratio is accurate to one part per thousand or better.
+        // Log.d(TAG, "ratio=" + ratio + ", timeDiff=" + timeDiff + ", frameDiff=" + frameDiff +
+        //        ", timeByFrames=" + timeByFrames + ", sampleRate=" + sampleRate);
+        assertEquals(1.0 /* expected */, ratio, 0.01 /* delta */);
+    }
+
+    // remove if AudioTimestamp has a better toString().
+    private void printTimestamp(String s, AudioTimestamp ats) {
+        Log.d(TAG, s + ":  pos: " + ats.framePosition + "  time: " + ats.nanoTime);
+    }
 }
diff --git a/tests/tests/media/src/android/media/cts/AudioRecordingConfigurationTest.java b/tests/tests/media/src/android/media/cts/AudioRecordingConfigurationTest.java
new file mode 100644
index 0000000..a8fb8fc
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/AudioRecordingConfigurationTest.java
@@ -0,0 +1,261 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.media.cts;
+
+import android.content.pm.PackageManager;
+import android.cts.util.CtsAndroidTestCase;
+import android.media.AudioDeviceInfo;
+import android.media.AudioFormat;
+import android.media.AudioManager;
+import android.media.AudioRecord;
+import android.media.AudioRecordingConfiguration;
+import android.media.MediaRecorder;
+import android.os.Looper;
+import android.os.Parcel;
+import android.util.Log;
+
+public class AudioRecordingConfigurationTest extends CtsAndroidTestCase {
+    private final static String TAG = "AudioRecordingConfigurationTest";
+
+    private final static int TEST_SAMPLE_RATE = 16000;
+    private final static int TEST_AUDIO_SOURCE = MediaRecorder.AudioSource.VOICE_RECOGNITION;
+
+    private final static int TEST_TIMING_TOLERANCE_MS = 70;
+
+    private AudioRecord mAudioRecord;
+    private Looper mLooper;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        if (!hasMicrophone()) {
+            return;
+        }
+
+        /*
+         * InstrumentationTestRunner.onStart() calls Looper.prepare(), which creates a looper
+         * for the current thread. However, since we don't actually call loop() in the test,
+         * any messages queued with that looper will never be consumed. Therefore, we must
+         * create the instance in another thread, either without a looper, so the main looper is
+         * used, or with an active looper.
+         */
+        Thread t = new Thread() {
+            @Override
+            public void run() {
+                Looper.prepare();
+                mLooper = Looper.myLooper();
+                synchronized(this) {
+                    mAudioRecord = new AudioRecord.Builder()
+                                     .setAudioSource(TEST_AUDIO_SOURCE)
+                                     .setAudioFormat(new AudioFormat.Builder()
+                                             .setEncoding(AudioFormat.ENCODING_PCM_16BIT)
+                                             .setSampleRate(TEST_SAMPLE_RATE)
+                                             .setChannelMask(AudioFormat.CHANNEL_IN_MONO)
+                                             .build())
+                                     .build();
+                    this.notify();
+                }
+                Looper.loop();
+            }
+        };
+        synchronized(t) {
+            t.start(); // will block until we wait
+            t.wait();
+        }
+        assertNotNull(mAudioRecord);
+        assertNotNull(mLooper);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        if (hasMicrophone()) {
+            mAudioRecord.stop();
+            mAudioRecord.release();
+            mLooper.quit();
+        }
+        super.tearDown();
+    }
+
+    // start a recording and verify it is seen as an active recording
+    public void testAudioManagerGetActiveRecordConfigurations() throws Exception {
+        if (!hasMicrophone()) {
+            return;
+        }
+        AudioManager am = new AudioManager(getContext());
+        assertNotNull("Could not create AudioManager", am);
+
+        AudioRecordingConfiguration[] configs = am.getActiveRecordingConfigurations();
+        assertNotNull("Invalid null array of record configurations before recording", configs);
+
+        assertEquals(AudioRecord.STATE_INITIALIZED, mAudioRecord.getState());
+        mAudioRecord.startRecording();
+        assertEquals(AudioRecord.RECORDSTATE_RECORDING, mAudioRecord.getRecordingState());
+        Thread.sleep(TEST_TIMING_TOLERANCE_MS);
+
+        // recording is active, verify there is an active record configuration
+        configs = am.getActiveRecordingConfigurations();
+        assertNotNull("Invalid null array of record configurations during recording", configs);
+        assertTrue("no active record configurations (empty array) during recording",
+                configs.length > 0);
+        final int nbConfigsDuringRecording = configs.length;
+
+        // verify our recording shows as one of the recording configs
+        assertTrue("Test source/session not amongst active record configurations",
+                verifyAudioConfig(TEST_AUDIO_SOURCE, mAudioRecord.getAudioSessionId(),
+                        mAudioRecord.getFormat(), mAudioRecord.getRoutedDevice(), configs));
+
+        // stopping recording: verify there are less active record configurations
+        mAudioRecord.stop();
+        Thread.sleep(TEST_TIMING_TOLERANCE_MS);
+        configs = am.getActiveRecordingConfigurations();
+        assertTrue("end of recording not reported in record configs",
+                configs.length < nbConfigsDuringRecording);
+    }
+
+    public void testCallback() throws Exception {
+        if (!hasMicrophone()) {
+            return;
+        }
+        AudioManager am = new AudioManager(getContext());
+        assertNotNull("Could not create AudioManager", am);
+
+        MyAudioRecordingCallback callback = new MyAudioRecordingCallback(
+                mAudioRecord.getAudioSessionId(), TEST_AUDIO_SOURCE);
+        am.registerAudioRecordingCallback(callback, null /*handler*/);
+
+        assertEquals(AudioRecord.STATE_INITIALIZED, mAudioRecord.getState());
+        mAudioRecord.startRecording();
+        assertEquals(AudioRecord.RECORDSTATE_RECORDING, mAudioRecord.getRecordingState());
+        Thread.sleep(TEST_TIMING_TOLERANCE_MS);
+
+        assertTrue("AudioRecordingCallback not called", callback.mCalled);
+        assertTrue("Expected record configuration was not found", callback.mParamMatch);
+
+        // stopping recording: callback is called with no match
+        callback.reset();
+        mAudioRecord.stop();
+        Thread.sleep(TEST_TIMING_TOLERANCE_MS);
+        assertTrue("AudioRecordingCallback not called", callback.mCalled);
+        assertFalse("Should not have found test record configuration", callback.mParamMatch);
+
+        // unregister callback and start recording again
+        am.unregisterAudioRecordingCallback(callback);
+        callback.reset();
+        mAudioRecord.startRecording();
+        Thread.sleep(TEST_TIMING_TOLERANCE_MS);
+        assertFalse("Unregistered callback was called", callback.mCalled);
+
+        // just call the callback once directly so it's marked as tested
+        final AudioManager.AudioRecordingCallback arc =
+                (AudioManager.AudioRecordingCallback) callback;
+        arc.onRecordingConfigChanged(new AudioRecordingConfiguration[0]);
+    }
+
+    public void testParcel() throws Exception {
+        if (!hasMicrophone()) {
+            return;
+        }
+        AudioManager am = new AudioManager(getContext());
+        assertNotNull("Could not create AudioManager", am);
+
+        assertEquals(AudioRecord.STATE_INITIALIZED, mAudioRecord.getState());
+        mAudioRecord.startRecording();
+        assertEquals(AudioRecord.RECORDSTATE_RECORDING, mAudioRecord.getRecordingState());
+        Thread.sleep(TEST_TIMING_TOLERANCE_MS);
+
+        AudioRecordingConfiguration[] configs = am.getActiveRecordingConfigurations();
+        assertTrue("Empty array of record configs during recording", configs.length > 0);
+        assertEquals(0, configs[0].describeContents());
+
+        // marshall a AudioRecordingConfiguration and compare to unmarshalled
+        final Parcel srcParcel = Parcel.obtain();
+        final Parcel dstParcel = Parcel.obtain();
+
+        configs[0].writeToParcel(srcParcel, 0 /*no public flags for marshalling*/);
+        final byte[] mbytes = srcParcel.marshall();
+        dstParcel.unmarshall(mbytes, 0, mbytes.length);
+        dstParcel.setDataPosition(0);
+        final AudioRecordingConfiguration unmarshalledConf =
+                AudioRecordingConfiguration.CREATOR.createFromParcel(dstParcel);
+
+        assertNotNull("Failure to unmarshall AudioRecordingConfiguration", unmarshalledConf);
+        assertEquals("Source and destination AudioRecordingConfiguration not equal",
+                configs[0], unmarshalledConf);
+    }
+
+    class MyAudioRecordingCallback extends AudioManager.AudioRecordingCallback {
+        boolean mCalled = false;
+        boolean mParamMatch = false;
+        final AudioManager mAM;
+        final int mTestSource;
+        final int mTestSession;
+
+        void reset() {
+            mCalled = false;
+            mParamMatch = false;
+        }
+
+        MyAudioRecordingCallback(int session, int source) {
+            mAM = new AudioManager(getContext());
+            mTestSource = source;
+            mTestSession = session;
+        }
+
+        @Override
+        public void onRecordingConfigChanged(AudioRecordingConfiguration[] configs) {
+            mCalled = true;
+            mParamMatch = verifyAudioConfig(mTestSource, mTestSession, mAudioRecord.getFormat(),
+                    mAudioRecord.getRoutedDevice(), configs);
+        }
+    }
+
+    private static boolean deviceMatch(AudioDeviceInfo devJoe, AudioDeviceInfo devJeff) {
+        return ((devJoe.getId() == devJeff.getId()
+                && (devJoe.getAddress() == devJeff.getAddress())
+                && (devJoe.getType() == devJeff.getType())));
+    }
+
+    private static boolean verifyAudioConfig(int source, int session, AudioFormat format,
+            AudioDeviceInfo device, AudioRecordingConfiguration[] configs) {
+        for (int i = 0 ; i < configs.length ; i++) {
+            if ((configs[i].getClientAudioSource() == source)
+                    && (configs[i].getClientAudioSessionId() == session)
+                    // test the client format matches that requested (same as the AudioRecord's)
+                    && (configs[i].getClientFormat().getEncoding() == format.getEncoding())
+                    && (configs[i].getClientFormat().getSampleRate() == format.getSampleRate())
+                    && (configs[i].getClientFormat().getChannelMask() == format.getChannelMask())
+                    && (configs[i].getClientFormat().getChannelIndexMask() ==
+                            format.getChannelIndexMask())
+                    // test the device format is configured
+                    && (configs[i].getFormat().getEncoding() != AudioFormat.ENCODING_INVALID)
+                    && (configs[i].getFormat().getSampleRate() > 0)
+                    //  for the channel mask, either the position or index-based value must be valid
+                    && ((configs[i].getFormat().getChannelMask() != AudioFormat.CHANNEL_INVALID)
+                            || (configs[i].getFormat().getChannelIndexMask() !=
+                                    AudioFormat.CHANNEL_INVALID))
+                    && deviceMatch(device, configs[i].getAudioDevice())) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean hasMicrophone() {
+        return getContext().getPackageManager().hasSystemFeature(
+                PackageManager.FEATURE_MICROPHONE);
+    }
+}
diff --git a/tests/tests/media/src/android/media/cts/AudioTrackLatencyTest.java b/tests/tests/media/src/android/media/cts/AudioTrackLatencyTest.java
new file mode 100644
index 0000000..0851a0a
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/AudioTrackLatencyTest.java
@@ -0,0 +1,577 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.media.cts;
+
+import android.app.ActivityManager;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.cts.util.CtsAndroidTestCase;
+import android.media.AudioAttributes;
+import android.media.AudioFormat;
+import android.media.AudioManager;
+import android.media.AudioTimestamp;
+import android.media.AudioTrack;
+import android.media.PlaybackParams;
+import android.util.Log;
+
+import com.android.compatibility.common.util.DeviceReportLog;
+import com.android.compatibility.common.util.ResultType;
+import com.android.compatibility.common.util.ResultUnit;
+
+import java.nio.ByteBuffer;
+import java.nio.FloatBuffer;
+import java.nio.ShortBuffer;
+
+// Test the Java AudioTrack low latency related features:
+//
+// setBufferSizeInFrames()
+// getBufferCapacityInFrames()
+// ASSUME getMinBufferSize in frames is significantly lower than getBufferCapacityInFrames.
+// This gives us room to adjust the sizes.
+//
+// getUnderrunCount()
+// ASSUME normal track will underrun with setBufferSizeInFrames(0).
+//
+// AudioAttributes.FLAG_LOW_LATENCY
+// ASSUME FLAG_LOW_LATENCY reduces output latency by more than 10 msec.
+// Warns if not. This can happen if there is no Fast Mixer or if a FastTrack
+// is not available.
+
+public class AudioTrackLatencyTest extends CtsAndroidTestCase {
+    private String TAG = "AudioTrackLatencyTest";
+    private final static long NANOS_PER_MILLISECOND = 1000000L;
+    private final static int MILLIS_PER_SECOND = 1000;
+    private final static long NANOS_PER_SECOND = NANOS_PER_MILLISECOND * MILLIS_PER_SECOND;
+
+    private void log(String testName, String message) {
+        Log.i(TAG, "[" + testName + "] " + message);
+    }
+
+    private void logw(String testName, String message) {
+        Log.w(TAG, "[" + testName + "] " + message);
+    }
+
+    private void loge(String testName, String message) {
+        Log.e(TAG, "[" + testName + "] " + message);
+    }
+
+    public void testSetBufferSize() throws Exception {
+        // constants for test
+        final String TEST_NAME = "testSetBufferSize";
+        final int TEST_SR = 44100;
+        final int TEST_CONF = AudioFormat.CHANNEL_OUT_STEREO;
+        final int TEST_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
+        final int TEST_MODE = AudioTrack.MODE_STREAM;
+        final int TEST_STREAM_TYPE = AudioManager.STREAM_MUSIC;
+
+        // -------- initialization --------------
+        int minBuffSize = AudioTrack.getMinBufferSize(TEST_SR, TEST_CONF, TEST_FORMAT);
+        AudioTrack track = new AudioTrack(TEST_STREAM_TYPE, TEST_SR, TEST_CONF, TEST_FORMAT,
+                minBuffSize, TEST_MODE);
+
+        // -------- test --------------
+        // Initial values
+        int bufferCapacity = track.getBufferCapacityInFrames();
+        int initialBufferSize = track.getBufferSizeInFrames();
+        assertTrue(TEST_NAME, bufferCapacity > 0);
+        assertTrue(TEST_NAME, initialBufferSize > 0);
+        assertTrue(TEST_NAME, initialBufferSize <= bufferCapacity);
+
+        // set to various values
+        int resultNegative = track.setBufferSizeInFrames(-1);
+        assertEquals(TEST_NAME + ": negative size", AudioTrack.ERROR_BAD_VALUE, resultNegative);
+        assertEquals(TEST_NAME + ": should be unchanged",
+                initialBufferSize, track.getBufferSizeInFrames());
+
+        int resultZero = track.setBufferSizeInFrames(0);
+        assertTrue(TEST_NAME + ": should be >0, but got " + resultZero, resultZero > 0);
+        assertTrue(TEST_NAME + ": zero size < original, but got " + resultZero,
+                resultZero < initialBufferSize);
+        assertEquals(TEST_NAME + ": should match resultZero",
+                resultZero, track.getBufferSizeInFrames());
+
+        int resultMax = track.setBufferSizeInFrames(Integer.MAX_VALUE);
+        assertTrue(TEST_NAME + ": set MAX_VALUE, >", resultMax > resultZero);
+        assertTrue(TEST_NAME + ": set MAX_VALUE, <=", resultMax <= bufferCapacity);
+        assertEquals(TEST_NAME + ": should match resultMax",
+                resultMax, track.getBufferSizeInFrames());
+
+        int resultMiddle = track.setBufferSizeInFrames(bufferCapacity / 2);
+        assertTrue(TEST_NAME + ": set middle, >", resultMiddle > resultZero);
+        assertTrue(TEST_NAME + ": set middle, <=", resultMiddle < resultMax);
+        assertEquals(TEST_NAME + ": should match resultMiddle",
+                resultMiddle, track.getBufferSizeInFrames());
+
+        // -------- tear down --------------
+        track.release();
+    }
+
+    // Helper class for tests
+    private static class TestSetup {
+        public int sampleRate = 48000;
+        public int samplesPerFrame = 2;
+        public int bytesPerSample = 2;
+        public int config = AudioFormat.CHANNEL_OUT_STEREO;
+        public int format = AudioFormat.ENCODING_PCM_16BIT;
+        public int mode = AudioTrack.MODE_STREAM;
+        public int streamType = AudioManager.STREAM_MUSIC;
+        public int framesPerBuffer = 256;
+        public double amplitude = 0.5;
+
+        private AudioTrack mTrack;
+        private short[] mData;
+        private int mActualSizeInFrames;
+
+        AudioTrack createTrack() {
+            mData = AudioHelper.createSineWavesShort(framesPerBuffer,
+                    samplesPerFrame, 1, amplitude);
+            int minBufferSize = AudioTrack.getMinBufferSize(sampleRate, config, format);
+            // Create a buffer that is 3/2 times bigger than the minimum.
+            // This gives me room to cut it in half and play without glitching.
+            // This is an arbitrary scaling factor.
+            int bufferSize = (minBufferSize * 3) / 2;
+            mTrack = new AudioTrack(streamType, sampleRate, config, format,
+                    bufferSize, mode);
+
+            // Calculate and use a smaller buffer size
+            int smallBufferSize = bufferSize / 2; // arbitrary, smaller might underflow
+            int smallBuffSizeInFrames = smallBufferSize / (samplesPerFrame * bytesPerSample);
+            mActualSizeInFrames = mTrack.setBufferSizeInFrames(smallBuffSizeInFrames);
+            return mTrack;
+
+        }
+
+        int primeAudioTrack(String testName) {
+            // Prime the buffer.
+            int samplesWrittenTotal = 0;
+            int samplesWritten;
+            do{
+                samplesWritten = mTrack.write(mData, 0, mData.length);
+                if (samplesWritten > 0) {
+                    samplesWrittenTotal += samplesWritten;
+                }
+            } while (samplesWritten == mData.length);
+            int framesWrittenTotal = samplesWrittenTotal / samplesPerFrame;
+            assertTrue(testName + ": framesWrittenTotal = " + framesWrittenTotal
+                    + ", size = " + mActualSizeInFrames,
+                    framesWrittenTotal >= mActualSizeInFrames);
+            return framesWrittenTotal;
+        }
+
+        /**
+         * @param seconds
+         */
+        public void writeSeconds(double seconds) throws InterruptedException {
+            long msecEnd = System.currentTimeMillis() + (long)(seconds * 1000);
+            while (System.currentTimeMillis() < msecEnd) {
+                // Use non-blocking mode in case the track is hung.
+                int samplesWritten = mTrack.write(mData, 0, mData.length, AudioTrack.WRITE_NON_BLOCKING);
+                if (samplesWritten < mData.length) {
+                    int samplesRemaining = mData.length - samplesWritten;
+                    int framesRemaining = samplesRemaining / samplesPerFrame;
+                    int millis = (framesRemaining * 1000) / sampleRate;
+                    Thread.sleep(millis);
+                }
+            }
+        }
+    }
+
+    // Try to play an AudioTrack when the initial size is less than capacity.
+    // We want to make sure the track starts properly and is not stuck.
+    public void testPlaySmallBuffer() throws Exception {
+        final String TEST_NAME = "testPlaySmallBuffer";
+        TestSetup setup = new TestSetup();
+        AudioTrack track = setup.createTrack();
+
+        // Prime the buffer.
+        int framesWrittenTotal = setup.primeAudioTrack(TEST_NAME);
+
+        // Start playing and let it drain.
+        int position1 = track.getPlaybackHeadPosition();
+        assertEquals(TEST_NAME + ": initial position", 0, position1);
+        track.play();
+
+        // Make sure it starts within a reasonably short time.
+        final long MAX_TIME_TO_START_MSEC =  500; // arbitrary
+        long giveUpAt = System.currentTimeMillis() + MAX_TIME_TO_START_MSEC;
+        int position2 = track.getPlaybackHeadPosition();
+        while ((position1 == position2)
+                && (System.currentTimeMillis() < giveUpAt)) {
+            Thread.sleep(20); // arbitrary interval
+            position2 = track.getPlaybackHeadPosition();
+        }
+        assertTrue(TEST_NAME + ": did it start?, position after start = " + position2,
+                position2 > position1);
+
+        // Make sure it finishes playing the data.
+        // Wait several times longer than it should take to play the data.
+        final int several = 3; // arbitrary
+        Thread.sleep(several * framesWrittenTotal * MILLIS_PER_SECOND / setup.sampleRate);
+        position2 = track.getPlaybackHeadPosition();
+        assertEquals(TEST_NAME + ": did it play all the data?",
+                framesWrittenTotal, position2);
+
+        track.release();
+    }
+
+    // Try to play and pause an AudioTrack when the initial size is less than capacity.
+    // We want to make sure the track starts properly and is not stuck.
+    public void testPlayPauseSmallBuffer() throws Exception {
+        final String TEST_NAME = "testPlayPauseSmallBuffer";
+        TestSetup setup = new TestSetup();
+        AudioTrack track = setup.createTrack();
+
+        // Prime the buffer.
+        setup.primeAudioTrack(TEST_NAME);
+
+        // Start playing then pause and play in a loop.
+        int position1 = track.getPlaybackHeadPosition();
+        assertEquals(TEST_NAME + ": initial position", 0, position1);
+        track.play();
+        // try pausing several times to see it if it fails
+        final int several = 4; // arbitrary
+        for (int i = 0; i < several; i++) {
+            // write data in non-blocking mode for a few seconds
+            setup.writeSeconds(2.0); // arbitrary, long enough for audio to get to the device
+            // Did position advance as we were playing? Or was the track stuck?
+            int position2 = track.getPlaybackHeadPosition();
+            int delta = position2 - position1; // safe from wrapping
+            assertTrue(TEST_NAME + ": [" + i + "] did it advance? p1 = " + position1
+                    + ", p2 = " + position2, delta > 0);
+            position1 = position2;
+            // pause for a second
+            track.pause();
+            Thread.sleep(MILLIS_PER_SECOND);
+            track.play();
+        }
+
+        track.release();
+    }
+
+    // Create a track with or without FLAG_LOW_LATENCY
+    private AudioTrack createCustomAudioTrack(boolean lowLatency) {
+        final String TEST_NAME = "createCustomAudioTrack";
+        final int TEST_SR = 48000;
+        final int TEST_CONF = AudioFormat.CHANNEL_OUT_STEREO;
+        final int TEST_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
+        final int TEST_CONTENT_TYPE = AudioAttributes.CONTENT_TYPE_MUSIC;
+
+        // Start with buffer twice as large as needed.
+        int bufferSizeBytes = 2 * AudioTrack.getMinBufferSize(TEST_SR, TEST_CONF, TEST_FORMAT);
+        AudioAttributes.Builder attributesBuilder = new AudioAttributes.Builder()
+                .setContentType(TEST_CONTENT_TYPE);
+        if (lowLatency) {
+            attributesBuilder.setFlags(AudioAttributes.FLAG_LOW_LATENCY);
+        }
+        AudioAttributes attributes = attributesBuilder.build();
+
+        // Do not specify the sample rate so we get the optimal rate.
+        AudioFormat format = new AudioFormat.Builder()
+                .setEncoding(TEST_FORMAT)
+                .setChannelMask(TEST_CONF)
+                .build();
+        AudioTrack track = new AudioTrack.Builder()
+                .setAudioAttributes(attributes)
+                .setAudioFormat(format)
+                .setBufferSizeInBytes(bufferSizeBytes)
+                .build();
+
+        assertTrue(track != null);
+        log(TEST_NAME, "Track sample rate = " + track.getSampleRate() + " Hz");
+        return track;
+    }
+
+
+    private int checkOutputLowLatency(boolean lowLatency) throws Exception {
+        // constants for test
+        final String TEST_NAME = "checkOutputLowLatency";
+        final int TEST_SAMPLES_PER_FRAME = 2;
+        final int TEST_BYTES_PER_SAMPLE = 2;
+        final int TEST_NUM_SECONDS = 4;
+        final int TEST_FRAMES_PER_BUFFER = 128;
+        final double TEST_AMPLITUDE = 0.5;
+
+        final short[] data = AudioHelper.createSineWavesShort(TEST_FRAMES_PER_BUFFER,
+                TEST_SAMPLES_PER_FRAME, 1, TEST_AMPLITUDE);
+
+        // -------- initialization --------------
+        AudioTrack track = createCustomAudioTrack(lowLatency);
+        assertTrue(TEST_NAME + " actual SR", track.getSampleRate() > 0);
+
+        // -------- test --------------
+        // Play some audio for a few seconds.
+        int numSeconds = TEST_NUM_SECONDS;
+        int numBuffers = numSeconds * track.getSampleRate() / TEST_FRAMES_PER_BUFFER;
+        long framesWritten = 0;
+        boolean isPlaying = false;
+        for (int i = 0; i < numBuffers; i++) {
+            track.write(data, 0, data.length);
+            framesWritten += TEST_FRAMES_PER_BUFFER;
+            // prime the buffer a bit before playing
+            if (!isPlaying) {
+                track.play();
+                isPlaying = true;
+            }
+        }
+
+        // Estimate the latency from the timestamp.
+        long timeWritten = System.nanoTime();
+        AudioTimestamp timestamp = new AudioTimestamp();
+        boolean result = track.getTimestamp(timestamp);
+        // FIXME failing LOW_LATENCY case! b/26413951
+        assertTrue(TEST_NAME + " did not get a timestamp, lowLatency = "
+                + lowLatency, result);
+
+        // Calculate when the last frame written is going to be rendered.
+        long framesPending = framesWritten - timestamp.framePosition;
+        long timeDelta = framesPending * NANOS_PER_SECOND / track.getSampleRate();
+        long timePresented = timestamp.nanoTime + timeDelta;
+        long latencyNanos = timePresented - timeWritten;
+        int latencyMillis = (int) (latencyNanos / NANOS_PER_MILLISECOND);
+        assertTrue(TEST_NAME + " got latencyMillis <= 0 == "
+                + latencyMillis, latencyMillis > 0);
+
+        // -------- cleanup --------------
+        track.release();
+
+        return latencyMillis;
+    }
+
+    // Compare output latency with and without FLAG_LOW_LATENCY.
+    public void testOutputLowLatency() throws Exception {
+        final String TEST_NAME = "testOutputLowLatency";
+
+        int highLatencyMillis = checkOutputLowLatency(false);
+        log(TEST_NAME, "High latency = " + highLatencyMillis + " msec");
+
+        int lowLatencyMillis = checkOutputLowLatency(true);
+        log(TEST_NAME, "Low latency = " + lowLatencyMillis + " msec");
+
+        // We are not guaranteed to get a FAST track. Some platforms
+        // do not even have a FastMixer. So just warn and not fail.
+        if (highLatencyMillis <= (lowLatencyMillis + 10)) {
+            logw(TEST_NAME, "high latency should be much higher, "
+                    + highLatencyMillis
+                    + " vs " + lowLatencyMillis);
+        }
+    }
+
+    // Verify that no underruns when buffer is >= getMinBufferSize().
+    // Verify that we get underruns with buffer at smallest possible size.
+    public void testGetUnderrunCount() throws Exception {
+        // constants for test
+        final String TEST_NAME = "testGetUnderrunCount";
+        final int TEST_SR = 44100;
+        final int TEST_SAMPLES_PER_FRAME = 2;
+        final int TEST_BYTES_PER_SAMPLE = 2;
+        final int TEST_NUM_SECONDS = 2;
+        final int TEST_CONF = AudioFormat.CHANNEL_OUT_STEREO;
+        final int TEST_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
+        final int TEST_MODE = AudioTrack.MODE_STREAM;
+        final int TEST_STREAM_TYPE = AudioManager.STREAM_MUSIC;
+        final int TEST_FRAMES_PER_BUFFER = 256;
+        final int TEST_FRAMES_PER_BLIP = TEST_SR / 8;
+        final int TEST_CYCLES_PER_BLIP = 700 * TEST_FRAMES_PER_BLIP / TEST_SR;
+        final double TEST_AMPLITUDE = 0.5;
+
+        final short[] data = AudioHelper.createSineWavesShort(TEST_FRAMES_PER_BUFFER,
+                TEST_SAMPLES_PER_FRAME, 1, TEST_AMPLITUDE);
+        final short[] blip = AudioHelper.createSineWavesShort(TEST_FRAMES_PER_BLIP,
+                TEST_SAMPLES_PER_FRAME, TEST_CYCLES_PER_BLIP, TEST_AMPLITUDE);
+
+        // -------- initialization --------------
+        int minBuffSize = AudioTrack.getMinBufferSize(TEST_SR, TEST_CONF, TEST_FORMAT);
+        // Start with buffer twice as large as needed.
+        AudioTrack track = new AudioTrack(TEST_STREAM_TYPE, TEST_SR, TEST_CONF, TEST_FORMAT,
+                minBuffSize * 2, TEST_MODE);
+
+        // -------- test --------------
+        // Initial values
+        int bufferCapacity = track.getBufferCapacityInFrames();
+        int initialBufferSize = track.getBufferSizeInFrames();
+        int minBuffSizeInFrames = minBuffSize / (TEST_SAMPLES_PER_FRAME * TEST_BYTES_PER_SAMPLE);
+        assertTrue(TEST_NAME, bufferCapacity > 0);
+        assertTrue(TEST_NAME, initialBufferSize > 0);
+        assertTrue(TEST_NAME, initialBufferSize <= bufferCapacity);
+
+        // Play with initial size.
+        int underrunCount1 = track.getUnderrunCount();
+        assertEquals(TEST_NAME + ": initially no underruns", 0, underrunCount1);
+
+        // Prime the buffer.
+        while (track.write(data, 0, data.length) == data.length);
+
+        // Start playing
+        track.play();
+        int numBuffers = TEST_SR / TEST_FRAMES_PER_BUFFER;
+        for (int i = 0; i < numBuffers; i++) {
+            track.write(data, 0, data.length);
+        }
+        int underrunCountBase = track.getUnderrunCount();
+        int numSeconds = TEST_NUM_SECONDS;
+        numBuffers = numSeconds * TEST_SR / TEST_FRAMES_PER_BUFFER;
+        track.write(blip, 0, blip.length);
+        for (int i = 0; i < numBuffers; i++) {
+            track.write(data, 0, data.length);
+        }
+        underrunCount1 = track.getUnderrunCount();
+        assertEquals(TEST_NAME + ": no more underruns after initial",
+                underrunCountBase, underrunCount1);
+
+        // Play with getMinBufferSize() size.
+        int resultMin = track.setBufferSizeInFrames(minBuffSizeInFrames);
+        assertTrue(TEST_NAME + ": set minBuff, >", resultMin > 0);
+        assertTrue(TEST_NAME + ": set minBuff, <=", resultMin <= initialBufferSize);
+        track.write(blip, 0, blip.length);
+        for (int i = 0; i < numBuffers; i++) {
+            track.write(data, 0, data.length);
+        }
+        track.write(blip, 0, blip.length);
+        underrunCount1 = track.getUnderrunCount();
+        assertEquals(TEST_NAME + ": no more underruns at min", underrunCountBase, underrunCount1);
+
+        // Play with ridiculously small size. We want to get underruns so we know that an app
+        // can get to the edge of underrunning.
+        int resultZero = track.setBufferSizeInFrames(0);
+        assertTrue(TEST_NAME + ": should return > 0, got " + resultZero, resultZero > 0);
+        assertTrue(TEST_NAME + ": zero size < original", resultZero < initialBufferSize);
+        numSeconds = TEST_NUM_SECONDS / 2; // cuz test takes longer when underflowing
+        numBuffers = numSeconds * TEST_SR / TEST_FRAMES_PER_BUFFER;
+        // Play for a few seconds or until we get some new underruns.
+        for (int i = 0; (i < numBuffers) && ((underrunCount1 - underrunCountBase) < 10); i++) {
+            track.write(data, 0, data.length);
+            underrunCount1 = track.getUnderrunCount();
+        }
+        assertTrue(TEST_NAME + ": underruns at zero", underrunCount1 > underrunCountBase);
+        int underrunCount2 = underrunCount1;
+        // Play for a few seconds or until we get some new underruns.
+        for (int i = 0; (i < numBuffers) && ((underrunCount2 - underrunCount1) < 10); i++) {
+            track.write(data, 0, data.length);
+            underrunCount2 = track.getUnderrunCount();
+        }
+        assertTrue(TEST_NAME + ": underruns still accumulating", underrunCount2 > underrunCount1);
+
+        // Restore buffer to good size
+        numSeconds = TEST_NUM_SECONDS;
+        numBuffers = numSeconds * TEST_SR / TEST_FRAMES_PER_BUFFER;
+        int resultMax = track.setBufferSizeInFrames(bufferCapacity);
+        track.write(blip, 0, blip.length);
+        for (int i = 0; i < numBuffers; i++) {
+            track.write(data, 0, data.length);
+        }
+        // Should have stopped by now.
+        underrunCount1 = track.getUnderrunCount();
+        track.write(blip, 0, blip.length);
+        for (int i = 0; i < numBuffers; i++) {
+            track.write(data, 0, data.length);
+        }
+        // Counts should match.
+        underrunCount2 = track.getUnderrunCount();
+        assertEquals(TEST_NAME + ": underruns should stop happening",
+                underrunCount1, underrunCount2);
+
+        // -------- tear down --------------
+        track.release();
+    }
+
+    // Verify that we get underruns if we stop writing to the buffer.
+    public void testGetUnderrunCountSleep() throws Exception {
+        // constants for test
+        final String TEST_NAME = "testGetUnderrunCountSleep";
+        final int TEST_SR = 48000;
+        final int TEST_SAMPLES_PER_FRAME = 2;
+        final int TEST_BYTES_PER_SAMPLE = 2;
+        final int TEST_NUM_SECONDS = 2;
+        final int TEST_CONF = AudioFormat.CHANNEL_OUT_STEREO;
+        final int TEST_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
+        final int TEST_MODE = AudioTrack.MODE_STREAM;
+        final int TEST_STREAM_TYPE = AudioManager.STREAM_MUSIC;
+        final int TEST_FRAMES_PER_BUFFER = 256;
+        final int TEST_FRAMES_PER_BLIP = TEST_SR / 8;
+        final int TEST_CYCLES_PER_BLIP = 700 * TEST_FRAMES_PER_BLIP / TEST_SR;
+        final double TEST_AMPLITUDE = 0.5;
+
+        final short[] data = AudioHelper.createSineWavesShort(TEST_FRAMES_PER_BUFFER,
+                TEST_SAMPLES_PER_FRAME, 1, TEST_AMPLITUDE);
+        final short[] blip = AudioHelper.createSineWavesShort(TEST_FRAMES_PER_BLIP,
+                TEST_SAMPLES_PER_FRAME, TEST_CYCLES_PER_BLIP, TEST_AMPLITUDE);
+
+        // -------- initialization --------------
+        int minBuffSize = AudioTrack.getMinBufferSize(TEST_SR, TEST_CONF, TEST_FORMAT);
+        // Start with buffer twice as large as needed.
+        AudioTrack track = new AudioTrack(TEST_STREAM_TYPE, TEST_SR, TEST_CONF, TEST_FORMAT,
+                minBuffSize * 2, TEST_MODE);
+
+        // -------- test --------------
+        // Initial values
+        int minBuffSizeInFrames = minBuffSize / (TEST_SAMPLES_PER_FRAME * TEST_BYTES_PER_SAMPLE);
+
+        int underrunCount1 = track.getUnderrunCount();
+        assertEquals(TEST_NAME + ": initially no underruns", 0, underrunCount1);
+
+        // Prime the buffer.
+        while (track.write(data, 0, data.length) == data.length);
+
+        // Start playing
+        track.play();
+        int numBuffers = TEST_SR / TEST_FRAMES_PER_BUFFER;
+        for (int i = 0; i < numBuffers; i++) {
+            track.write(data, 0, data.length);
+        }
+        int underrunCountBase = track.getUnderrunCount();
+        int numSeconds = TEST_NUM_SECONDS;
+        numBuffers = numSeconds * TEST_SR / TEST_FRAMES_PER_BUFFER;
+        track.write(blip, 0, blip.length);
+        for (int i = 0; i < numBuffers; i++) {
+            track.write(data, 0, data.length);
+        }
+        underrunCount1 = track.getUnderrunCount();
+        assertEquals(TEST_NAME + ": no more underruns after initial",
+                underrunCountBase, underrunCount1);
+
+        // Sleep and force underruns.
+        track.write(blip, 0, blip.length);
+        for (int i = 0; i < 10; i++) {
+            track.write(data, 0, data.length);
+            Thread.sleep(500);  // ========================= SLEEP! ===========
+        }
+        track.write(blip, 0, blip.length);
+        underrunCount1 = track.getUnderrunCount();
+        assertTrue(TEST_NAME + ": expect underruns after sleep, #ur="
+                + underrunCount1,
+                underrunCountBase < underrunCount1);
+
+        track.write(blip, 0, blip.length);
+        for (int i = 0; i < numBuffers; i++) {
+            track.write(data, 0, data.length);
+        }
+
+        // Should have stopped by now.
+        underrunCount1 = track.getUnderrunCount();
+        track.write(blip, 0, blip.length);
+        for (int i = 0; i < numBuffers; i++) {
+            track.write(data, 0, data.length);
+        }
+        // Counts should match.
+        int underrunCount2 = track.getUnderrunCount();
+        assertEquals(TEST_NAME + ": underruns should stop happening",
+                underrunCount1, underrunCount2);
+
+        // -------- tear down --------------
+        track.release();
+    }
+}
diff --git a/tests/tests/media/src/android/media/cts/AudioTrackNative.java b/tests/tests/media/src/android/media/cts/AudioTrackNative.java
index 1ce44ef..54746ae 100644
--- a/tests/tests/media/src/android/media/cts/AudioTrackNative.java
+++ b/tests/tests/media/src/android/media/cts/AudioTrackNative.java
@@ -43,8 +43,13 @@
     // numBuffers is the number of internal buffers before hitting the OpenSL ES.
     // A value of 0 means that all writes are blocking.
     public boolean open(int numChannels, int sampleRate, boolean useFloat, int numBuffers) {
-        if (nativeOpen(mNativeTrackInJavaObj, numChannels, sampleRate, useFloat, numBuffers)
-                == STATUS_OK) {
+        return open(numChannels, 0, sampleRate, useFloat, numBuffers);
+    }
+
+    public boolean open(int numChannels, int channelMask, int sampleRate,
+            boolean useFloat, int numBuffers) {
+        if (nativeOpen(mNativeTrackInJavaObj, numChannels, channelMask,
+                sampleRate, useFloat, numBuffers) == STATUS_OK) {
             mChannelCount = numChannels;
             return true;
         }
@@ -111,7 +116,12 @@
 
     public static boolean test(int numChannels, int sampleRate, boolean useFloat,
             int msecPerBuffer, int numBuffers) {
-        return nativeTest(numChannels, sampleRate, useFloat, msecPerBuffer, numBuffers)
+        return test(numChannels, 0, sampleRate, useFloat, msecPerBuffer, numBuffers);
+    }
+
+    public static boolean test(int numChannels, int channelMask, int sampleRate, boolean useFloat,
+            int msecPerBuffer, int numBuffers) {
+        return nativeTest(numChannels, channelMask, sampleRate, useFloat, msecPerBuffer, numBuffers)
                 == STATUS_OK;
     }
 
@@ -139,7 +149,8 @@
     private static native long nativeCreateTrack();
     private static native void nativeDestroyTrack(long track);
     private static native int nativeOpen(
-            long track, int numChannels, int sampleRate, boolean useFloat, int numBuffers);
+            long track, int numChannels, int channelMask,
+            int sampleRate, boolean useFloat, int numBuffers);
     private static native void nativeClose(long track);
     private static native int nativeStart(long track);
     private static native int nativeStop(long track);
@@ -156,5 +167,6 @@
 
     // native interface for all-in-one testing, no track handle required.
     private static native int nativeTest(
-            int numChannels, int sampleRate, boolean useFloat, int msecPerBuffer, int numBuffers);
+            int numChannels, int channelMask, int sampleRate,
+            boolean useFloat, int msecPerBuffer, int numBuffers);
 }
diff --git a/tests/tests/media/src/android/media/cts/AudioTrackSurroundTest.java b/tests/tests/media/src/android/media/cts/AudioTrackSurroundTest.java
new file mode 100644
index 0000000..2ab030a
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/AudioTrackSurroundTest.java
@@ -0,0 +1,537 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.media.cts;
+
+import android.annotation.RawRes;
+import android.app.ActivityManager;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.res.AssetFileDescriptor;
+import android.content.res.Resources;
+import android.cts.util.CtsAndroidTestCase;
+import android.media.AudioAttributes;
+import android.media.AudioDeviceInfo;
+import android.media.AudioFormat;
+import android.media.AudioManager;
+import android.media.AudioTimestamp;
+import android.media.AudioTrack;
+import android.util.Log;
+
+import java.io.BufferedInputStream;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Random;
+
+// Test the Java AudioTrack surround sound and HDMI passthrough.
+// Most tests involve creating a track with a given format and then playing
+// a few seconds of audio. The playback is verified by measuring the output
+// sample rate based on the AudioTimestamps.
+
+public class AudioTrackSurroundTest extends CtsAndroidTestCase {
+    private static final String TAG = "AudioTrackSurroundTest";
+
+    private static final double MAX_RATE_TOLERANCE_HZ = 100.0;
+    private static final double MAX_INSTANTANEOUS_RATE_TOLERANCE_HZ = 5000.0;
+    private static final boolean LOG_TIMESTAMPS = false; // set true for debugging
+
+    // Set this true to prefer the device that supports the particular encoding.
+    // But note that as of 3/25/2016, a bug causes Direct tracks to fail.
+    // So only set true when debugging that problem.
+    private static final boolean USE_PREFERRED_DEVICE = false;
+
+    private final static long NANOS_PER_MILLISECOND = 1000000L;
+    private final static int MILLIS_PER_SECOND = 1000;
+    private final static long NANOS_PER_SECOND = NANOS_PER_MILLISECOND * MILLIS_PER_SECOND;
+
+    private final static int RES_AC3_VOICE_48000 = R.raw.voice12_48k_128kbps_15s_ac3;
+
+    // Devices that support various encodings.
+    private static boolean mDeviceScanComplete = false;
+    private static AudioDeviceInfo mInfoPCM16 = null;
+    private static AudioDeviceInfo mInfoAC3 = null;
+    private static AudioDeviceInfo mInfoE_AC3 = null;
+    private static AudioDeviceInfo mInfoDTS = null;
+    private static AudioDeviceInfo mInfoDTS_HD = null;
+    private static AudioDeviceInfo mInfoIEC61937 = null;
+
+    private static void log(String testName, String message) {
+        Log.i(TAG, "[" + testName + "] " + message);
+    }
+
+    private static void logw(String testName, String message) {
+        Log.w(TAG, "[" + testName + "] " + message);
+    }
+
+    private static void loge(String testName, String message) {
+        Log.e(TAG, "[" + testName + "] " + message);
+    }
+
+    // This is a special method that is called automatically before each test.
+    @Override
+    protected void setUp() throws Exception {
+        // Note that I tried to only scan for encodings once but the static
+        // data did not persist properly. That may be a bug.
+        // For now, just scan before every test.
+        scanDevicesForEncodings();
+    }
+
+    private void scanDevicesForEncodings() throws Exception {
+        // Scan devices to see which encodings are supported.
+        AudioManager audioManager = (AudioManager) getContext()
+                .getSystemService(Context.AUDIO_SERVICE);
+        AudioDeviceInfo[] infos = audioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS);
+        for (AudioDeviceInfo info : infos) {
+            log("scanDevicesForEncodings", "scanning devices, info = " + info
+                    + ", id = " + info.getId() + "---------------");
+            if (info.isSink()) {
+                for (int encoding : info.getEncodings()) {
+                    switch (encoding) {
+                        case AudioFormat.ENCODING_PCM_16BIT:
+                            mInfoPCM16 = info;
+                            log(TAG, "mInfoPCM16 set to " + info);
+                            break;
+                        case AudioFormat.ENCODING_AC3:
+                            mInfoAC3 = info;
+                            log(TAG, "mInfoAC3 set to " + info);
+                            break;
+                        case AudioFormat.ENCODING_E_AC3:
+                            mInfoE_AC3 = info;
+                            log(TAG, "mInfoE_AC3 set to " + info);
+                            break;
+                        case AudioFormat.ENCODING_DTS:
+                            mInfoDTS = info;
+                            log(TAG, "mInfoDTS set to " + info);
+                            break;
+                        case AudioFormat.ENCODING_DTS_HD:
+                            mInfoDTS_HD = info;
+                            log(TAG, "mInfoDTS_HD set to " + info);
+                            break;
+                        case AudioFormat.ENCODING_IEC61937:
+                            mInfoIEC61937 = info;
+                            log(TAG, "mInfoIEC61937 set to " + info);
+                            break;
+                        default:
+                            // This is OK. It is just an encoding that we don't care about.
+                            break;
+                    }
+                }
+            }
+        }
+    }
+
+    // Load a resource into a byte[]
+    private byte[] loadRawResourceBytes(@RawRes int id) throws Exception {
+        AssetFileDescriptor masterFd = getContext().getResources().openRawResourceFd(id);
+        long masterLength = masterFd.getLength();
+        byte[] masterBuffer = new byte[(int) masterLength];
+        InputStream is = masterFd.createInputStream();
+        BufferedInputStream bis = new BufferedInputStream(is);
+        int result = bis.read(masterBuffer);
+        bis.close();
+        masterFd.close();
+        return masterBuffer;
+    }
+
+    // Load a resource into a short[]
+    private short[] loadRawResourceShorts(@RawRes int id) throws Exception {
+        AssetFileDescriptor masterFd = getContext().getResources().openRawResourceFd(id);
+        long masterLength = masterFd.getLength();
+        short[] masterBuffer = new short[(int) (masterLength / 2)];
+        InputStream is = masterFd.createInputStream();
+        BufferedInputStream bis = new BufferedInputStream(is);
+        for (int i = 0; i < masterBuffer.length; i++) {
+            int lo = bis.read(); // assume Little Endian
+            int hi = bis.read();
+            masterBuffer[i] = (short) (hi * 256 + lo);
+        }
+        bis.close();
+        masterFd.close();
+        return masterBuffer;
+    }
+
+    public void testLoadSineSweep() throws Exception {
+        final String TEST_NAME = "testLoadSineSweep";
+        short[] shortData = loadRawResourceShorts(R.raw.sinesweepraw);
+        assertTrue(TEST_NAME + ": load sinesweepraw as shorts", shortData.length > 100);
+        byte[] byteData = loadRawResourceBytes(R.raw.sinesweepraw);
+        assertTrue(TEST_NAME + ": load sinesweepraw as bytes", byteData.length > shortData.length);
+    }
+
+    private static AudioTrack createAudioTrack(int sampleRate, int encoding, int channelConfig) {
+        final String TEST_NAME = "createAudioTrack";
+        int minBufferSize = AudioTrack.getMinBufferSize(
+                sampleRate, channelConfig,
+                encoding);
+        assertTrue(TEST_NAME + ": getMinBufferSize", minBufferSize > 0);
+        int bufferSize = minBufferSize * 3; // plenty big
+        AudioTrack track = new AudioTrack(AudioManager.STREAM_MUSIC,
+                sampleRate, channelConfig,
+                encoding, bufferSize,
+                AudioTrack.MODE_STREAM);
+        return track;
+    }
+
+    static class TimestampAnalyzer {
+        ArrayList<AudioTimestamp> mTimestamps = new ArrayList<AudioTimestamp>();
+        AudioTimestamp mPreviousTimestamp = null;
+
+        static String timestampToString(AudioTimestamp timestamp) {
+            if (timestamp == null)
+                return "null";
+            return "(pos = " + timestamp.framePosition + ", nanos = " + timestamp.nanoTime + ")";
+        }
+
+        // Add timestamp if unique and valid.
+        void addTimestamp(AudioTrack track) {
+            AudioTimestamp timestamp = new AudioTimestamp();
+            boolean gotTimestamp = track.getTimestamp(timestamp);
+            if (gotTimestamp) {
+                // Only save timestamps after the data is flowing.
+                if (mPreviousTimestamp != null) {
+                    if ((timestamp.framePosition > 0)
+                            && (timestamp.nanoTime != mPreviousTimestamp.nanoTime)) {
+                        mTimestamps.add(timestamp);
+                    }
+                }
+                mPreviousTimestamp = timestamp;
+            }
+        }
+
+        // Use collected timestamps to estimate a sample rate.
+        double estimateSampleRate() {
+            assertTrue("expect many timestamps, got " + mTimestamps.size(),
+                    mTimestamps.size() > 10);
+            // Use first and last timestamp to get the most accurate rate.
+            AudioTimestamp first = mTimestamps.get(0);
+            AudioTimestamp last = mTimestamps.get(mTimestamps.size() - 1);
+            double measuredRate = calculateSampleRate(first, last);
+
+            AudioTimestamp previous = null;
+            // Make sure the timestamps are smooth and don't go retrograde.
+            for (AudioTimestamp timestamp : mTimestamps) {
+                if (previous != null) {
+                    double instantaneousRate = calculateSampleRate(previous, timestamp);
+                    assertEquals("instantaneous sample rate should match long term rate",
+                            measuredRate, instantaneousRate, MAX_INSTANTANEOUS_RATE_TOLERANCE_HZ);
+                    assertTrue("framePosition should be monotonic",
+                            timestamp.framePosition > previous.framePosition);
+                    assertTrue("nanoTime should be monotonic",
+                            timestamp.nanoTime > previous.nanoTime);
+                }
+                previous = timestamp;
+            }
+            return measuredRate;
+        }
+
+        /**
+         * @param timestamp1
+         * @param timestamp2
+         */
+        private double calculateSampleRate(AudioTimestamp timestamp1, AudioTimestamp timestamp2) {
+            long elapsedFrames = timestamp2.framePosition - timestamp1.framePosition;
+            long elapsedNanos = timestamp2.nanoTime - timestamp1.nanoTime;
+            double measuredRate = elapsedFrames * (double) NANOS_PER_SECOND / elapsedNanos;
+            if (LOG_TIMESTAMPS) {
+                Log.i(TAG, "calculateSampleRate(), elapsedFrames =, " + elapsedFrames
+                        + ", measuredRate =, "
+                        + (int) measuredRate);
+            }
+            return measuredRate;
+        }
+    }
+
+    // Class for looping a recording for several seconds and measuring the sample rate.
+    // This is not static because it needs to call getContext().
+    abstract class SamplePlayerBase {
+        private final int mSampleRate;
+        private final int mEncoding;
+        private final int mChannelConfig;
+        private int mBlockSize = 512;
+        protected int mOffset = 0;
+        protected AudioTrack mTrack;
+        private final TimestampAnalyzer mTimestampAnalyzer = new TimestampAnalyzer();
+
+        SamplePlayerBase(int sampleRate, int encoding, int channelConfig) {
+            mSampleRate = sampleRate;
+            mEncoding = encoding;
+            mChannelConfig = channelConfig;
+        }
+
+        // Use abstract write to handle byte[] or short[] data.
+        protected abstract int writeBlock(int numSamples);
+
+        private int primeBuffer() {
+            // Will not block when track is stopped.
+            return writeBlock(Integer.MAX_VALUE);
+        }
+
+        /**
+         * Use a device that we know supports the current encoding.
+         */
+        private void usePreferredDevice() {
+            AudioDeviceInfo info = null;
+            switch (mEncoding) {
+                case AudioFormat.ENCODING_PCM_16BIT:
+                    info = mInfoPCM16;
+                    break;
+                case AudioFormat.ENCODING_AC3:
+                    info = mInfoAC3;
+                    break;
+                case AudioFormat.ENCODING_E_AC3:
+                    info = mInfoE_AC3;
+                    break;
+                case AudioFormat.ENCODING_DTS:
+                    info = mInfoDTS;
+                    break;
+                case AudioFormat.ENCODING_DTS_HD:
+                    info = mInfoDTS_HD;
+                    break;
+                case AudioFormat.ENCODING_IEC61937:
+                    info = mInfoIEC61937;
+                    break;
+                default:
+                    break;
+            }
+
+            if (info != null) {
+                log(TAG, "track.setPreferredDevice(" + info + ")");
+                mTrack.setPreferredDevice(info);
+            }
+        }
+
+        public void playAndMeasureRate() throws Exception {
+            final String TEST_NAME = "playAndMeasureRate";
+            final long TEST_DURATION_MILLIS = 5000; // just long enough to measure the rate
+            log(TEST_NAME, String.format("test using rate = %d, encoding = 0x%08x",
+                    mSampleRate, mEncoding));
+            // Create a track and prime it.
+            mTrack = createAudioTrack(mSampleRate, mEncoding, mChannelConfig);
+            try {
+                assertEquals(TEST_NAME + ": track created", AudioTrack.STATE_INITIALIZED,
+                        mTrack.getState());
+
+                if (USE_PREFERRED_DEVICE) {
+                    usePreferredDevice();
+                }
+
+                int bytesWritten = 0;
+                mOffset = primeBuffer(); // prime the buffer
+                assertTrue(TEST_NAME + ": priming offset = " + mOffset, mOffset > 0);
+                bytesWritten += mOffset;
+
+                // Play for a while.
+                mTrack.play();
+                long elapsedMillis = 0;
+                long startTime = System.currentTimeMillis();
+                while (elapsedMillis < TEST_DURATION_MILLIS) {
+                    writeBlock(mBlockSize);
+                    elapsedMillis = System.currentTimeMillis() - startTime;
+                    mTimestampAnalyzer.addTimestamp(mTrack);
+                }
+
+                // Did we underrun? Allow 0 or 1 because there is sometimes
+                // an underrun on startup.
+                int underrunCount1 = mTrack.getUnderrunCount();
+                assertTrue(TEST_NAME + ": too many underruns, got underrunCount1",
+                        underrunCount1 < 2);
+
+                // Estimate the sample rate and compare it with expected.
+                double estimatedRate = mTimestampAnalyzer.estimateSampleRate();
+                assertEquals(TEST_NAME + ": measured sample rate",
+                        mSampleRate, estimatedRate, MAX_RATE_TOLERANCE_HZ);
+            } finally {
+                mTrack.release();
+            }
+        }
+    }
+
+    // Create player for short[]
+    class SamplePlayerShorts extends SamplePlayerBase {
+        private final short[] mData;
+
+        SamplePlayerShorts(int sampleRate, int encoding, int channelConfig) {
+            super(sampleRate, encoding, channelConfig);
+            mData = new short[64 * 1024];
+            // Fill with noise. We should not hear the noise for IEC61937.
+            int amplitude = 8000;
+            Random random = new Random();
+            for (int i = 0; i < mData.length; i++) {
+                mData[i] = (short)(random.nextInt(amplitude) - (amplitude / 2));
+            }
+        }
+
+        SamplePlayerShorts(int sampleRate, int encoding, int channelConfig, @RawRes int resourceId)
+                throws Exception {
+            super(sampleRate, encoding, channelConfig);
+            mData = loadRawResourceShorts(resourceId);
+            assertTrue("SamplePlayerShorts: load resource file as shorts", mData.length > 0);
+        }
+
+        @Override
+        protected int writeBlock(int numShorts) {
+            int result = 0;
+            int shortsToWrite = numShorts;
+            int shortsLeft = mData.length - mOffset;
+            if (shortsToWrite > shortsLeft) {
+                shortsToWrite = shortsLeft;
+            }
+            if (shortsToWrite > 0) {
+                result = mTrack.write(mData, mOffset, shortsToWrite);
+                mOffset += result;
+            } else {
+                mOffset = 0; // rewind
+            }
+            return result;
+        }
+    }
+
+    // Create player for byte[]
+    class SamplePlayerBytes extends SamplePlayerBase {
+        private final byte[] mData;
+
+        SamplePlayerBytes(int sampleRate, int encoding, int channelConfig) {
+            super(sampleRate, encoding, channelConfig);
+            mData = new byte[128 * 1024];
+        }
+
+        SamplePlayerBytes(int sampleRate, int encoding, int channelConfig, @RawRes int resourceId)
+                throws Exception {
+            super(sampleRate, encoding, channelConfig);
+            mData = loadRawResourceBytes(resourceId);
+            assertTrue("SamplePlayerBytes: load resource file as bytes", mData.length > 0);
+        }
+
+        @Override
+        protected int writeBlock(int numBytes) {
+            int result = 0;
+            int bytesToWrite = numBytes;
+            int bytesLeft = mData.length - mOffset;
+            if (bytesToWrite > bytesLeft) {
+                bytesToWrite = bytesLeft;
+            }
+            if (bytesToWrite > 0) {
+                result = mTrack.write(mData, mOffset, bytesToWrite);
+                mOffset += result;
+            } else {
+                mOffset = 0; // rewind
+            }
+            return result;
+        }
+    }
+
+    public void testPlayAC3Bytes() throws Exception {
+        if (mInfoAC3 != null) {
+            SamplePlayerBytes player = new SamplePlayerBytes(
+                    48000, AudioFormat.ENCODING_AC3, AudioFormat.CHANNEL_OUT_STEREO,
+                    RES_AC3_VOICE_48000);
+            player.playAndMeasureRate();
+        }
+    }
+
+    public void testPlayAC3Shorts() throws Exception {
+        if (mInfoAC3 != null) {
+            SamplePlayerShorts player = new SamplePlayerShorts(
+                    48000, AudioFormat.ENCODING_AC3, AudioFormat.CHANNEL_OUT_STEREO,
+                    RES_AC3_VOICE_48000);
+            player.playAndMeasureRate();
+        }
+    }
+
+    // Note that for testing IEC61937, the Audio framework does not look at the
+    // wrapped data. It just passes it through over HDMI. See we can just use
+    // zeros instead of real data.
+    public void testPlayIEC61937_32000() throws Exception {
+        if (mInfoIEC61937 != null) {
+            SamplePlayerShorts player = new SamplePlayerShorts(
+                    32000, AudioFormat.ENCODING_IEC61937, AudioFormat.CHANNEL_OUT_STEREO);
+            player.playAndMeasureRate();
+        }
+    }
+
+    public void testPlayIEC61937_44100() throws Exception {
+        if (mInfoIEC61937 != null) {
+            SamplePlayerShorts player = new SamplePlayerShorts(
+                    44100, AudioFormat.ENCODING_IEC61937, AudioFormat.CHANNEL_OUT_STEREO);
+            player.playAndMeasureRate();
+        }
+    }
+
+    public void testPlayIEC61937_48000() throws Exception {
+        if (mInfoIEC61937 != null) {
+            SamplePlayerShorts player = new SamplePlayerShorts(
+                    48000, AudioFormat.ENCODING_IEC61937, AudioFormat.CHANNEL_OUT_STEREO);
+            player.playAndMeasureRate();
+        }
+    }
+
+    public void testIEC61937_Errors() throws Exception {
+        if (mInfoIEC61937 != null) {
+            final String TEST_NAME = "testIEC61937_Errors";
+            try {
+                AudioTrack track = createAudioTrack(48000, AudioFormat.ENCODING_IEC61937,
+                        AudioFormat.CHANNEL_OUT_MONO);
+                assertTrue(TEST_NAME + ": IEC61937 track creation should fail for mono", false);
+            } catch (IllegalArgumentException e) {
+                // This is expected behavior.
+            }
+
+            try {
+                AudioTrack track = createAudioTrack(48000, AudioFormat.ENCODING_IEC61937,
+                        AudioFormat.CHANNEL_OUT_5POINT1);
+                assertTrue(TEST_NAME + ": IEC61937 track creation should fail for 5.1", false);
+            } catch (IllegalArgumentException e) {
+                // This is expected behavior.
+            }
+        }
+    }
+
+    public void testPlaySineSweepShorts() throws Exception {
+        SamplePlayerShorts player = new SamplePlayerShorts(
+                44100, AudioFormat.ENCODING_PCM_16BIT, AudioFormat.CHANNEL_OUT_STEREO,
+                R.raw.sinesweepraw);
+        player.playAndMeasureRate();
+    }
+
+    public void testPlaySineSweepBytes() throws Exception {
+        SamplePlayerBytes player = new SamplePlayerBytes(
+                44100, AudioFormat.ENCODING_PCM_16BIT, AudioFormat.CHANNEL_OUT_STEREO,
+                R.raw.sinesweepraw);
+        player.playAndMeasureRate();
+    }
+
+    public void testPlaySineSweepBytes48000() throws Exception {
+        SamplePlayerBytes player = new SamplePlayerBytes(
+                48000, AudioFormat.ENCODING_PCM_16BIT, AudioFormat.CHANNEL_OUT_STEREO,
+                R.raw.sinesweepraw);
+        player.playAndMeasureRate();
+    }
+
+    public void testPlaySineSweepShortsMono() throws Exception {
+        SamplePlayerShorts player = new SamplePlayerShorts(44100, AudioFormat.ENCODING_PCM_16BIT,
+                AudioFormat.CHANNEL_OUT_MONO,
+                R.raw.sinesweepraw);
+        player.playAndMeasureRate();
+    }
+
+    public void testPlaySineSweepBytesMono()
+            throws Exception {
+        SamplePlayerBytes player = new SamplePlayerBytes(44100,
+                AudioFormat.ENCODING_PCM_16BIT, AudioFormat.CHANNEL_OUT_MONO, R.raw.sinesweepraw);
+        player.playAndMeasureRate();
+    }
+
+}
diff --git a/tests/tests/media/src/android/media/cts/AudioTrackTest.java b/tests/tests/media/src/android/media/cts/AudioTrackTest.java
index 1884493..d81c11c 100644
--- a/tests/tests/media/src/android/media/cts/AudioTrackTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioTrackTest.java
@@ -28,14 +28,13 @@
 import android.media.PlaybackParams;
 import android.util.Log;
 
-import com.android.cts.util.ReportLog;
-import com.android.cts.util.ResultType;
-import com.android.cts.util.ResultUnit;
+import com.android.compatibility.common.util.DeviceReportLog;
+import com.android.compatibility.common.util.ResultType;
+import com.android.compatibility.common.util.ResultUnit;
 
-import java.nio.ByteOrder;
 import java.nio.ByteBuffer;
-import java.nio.ShortBuffer;
 import java.nio.FloatBuffer;
+import java.nio.ShortBuffer;
 
 public class AudioTrackTest extends CtsAndroidTestCase {
     private String TAG = "AudioTrackTest";
@@ -1908,56 +1907,85 @@
 
     public void testGetTimestamp() throws Exception {
         if (!hasAudioOutput()) {
-            Log.w(TAG,"AUDIO_OUTPUT feature not found. This system might not have a valid "
+            Log.w(TAG, "AUDIO_OUTPUT feature not found. This system might not have a valid "
                     + "audio output HAL");
             return;
         }
+        doTestTimestamp(
+                22050 /* sampleRate */,
+                AudioFormat.CHANNEL_OUT_MONO ,
+                AudioFormat.ENCODING_PCM_16BIT,
+                AudioTrack.MODE_STREAM);
+    }
+
+    public void testFastTimestamp() throws Exception {
+        if (!hasAudioOutput()) {
+            Log.w(TAG, "AUDIO_OUTPUT feature not found. This system might not have a valid "
+                    + "audio output HAL");
+            return;
+        }
+        doTestTimestamp(
+                AudioTrack.getNativeOutputSampleRate(AudioManager.STREAM_MUSIC),
+                AudioFormat.CHANNEL_OUT_MONO,
+                AudioFormat.ENCODING_PCM_16BIT,
+                AudioTrack.MODE_STREAM);
+    }
+
+    private void doTestTimestamp(
+            int sampleRate, int channelMask, int encoding, int transferMode) throws Exception {
         // constants for test
         final String TEST_NAME = "testGetTimestamp";
-        final int TEST_SR = 22050;
-        final int TEST_CONF = AudioFormat.CHANNEL_OUT_MONO;
-        final int TEST_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
-        final int TEST_MODE = AudioTrack.MODE_STREAM;
-        final int TEST_STREAM_TYPE = AudioManager.STREAM_MUSIC;
         final int TEST_LOOP_CNT = 10;
+        final int TEST_BUFFER_MS = 100;
+        final int TEST_USAGE = AudioAttributes.USAGE_MEDIA;
         // For jitter we allow 30 msec in frames.  This is a large margin.
         // Often this is just 0 or 1 frames, but that can depend on hardware.
-        final int TEST_JITTER_FRAMES_ALLOWED = TEST_SR * 30 / 1000;
+        final int TEST_JITTER_FRAMES_ALLOWED = sampleRate * 30 / 1000;
 
         // -------- initialization --------------
-        final int bytesPerFrame =
-                AudioFormat.getBytesPerSample(TEST_FORMAT)
-                * AudioFormat.channelCountFromOutChannelMask(TEST_CONF);
-        final int minBufferSizeInBytes =
-                AudioTrack.getMinBufferSize(TEST_SR, TEST_CONF, TEST_FORMAT);
-        final int bufferSizeInBytes = minBufferSizeInBytes * 3;
-        byte[] data = new byte[bufferSizeInBytes];
-        AudioTrack track = new AudioTrack(TEST_STREAM_TYPE, TEST_SR, TEST_CONF, TEST_FORMAT,
-                minBufferSizeInBytes, TEST_MODE);
-        // -------- test --------------
-        assertTrue(TEST_NAME, track.getState() == AudioTrack.STATE_INITIALIZED);
+        final int frameSize =
+                AudioFormat.getBytesPerSample(encoding)
+                * AudioFormat.channelCountFromOutChannelMask(channelMask);
+        final int frameCount = sampleRate * TEST_BUFFER_MS / 1000;
+        // see whether we can use fast mode
+        final boolean fast =
+                sampleRate == AudioTrack.getNativeOutputSampleRate(AudioManager.STREAM_MUSIC);
 
+        AudioAttributes attributes = (fast ? new AudioAttributes.Builder()
+                .setFlags(AudioAttributes.FLAG_LOW_LATENCY) : new AudioAttributes.Builder())
+                .setUsage(TEST_USAGE)
+                .build();
+        AudioFormat format = new AudioFormat.Builder()
+                //.setChannelIndexMask((1 << AudioFormat.channelCountFromOutChannelMask(channelMask)) - 1)
+                .setChannelMask(channelMask)
+                .setEncoding(encoding)
+                .setSampleRate(sampleRate)
+                .build();
+        // not specifying the buffer size in the builder should get us the minimum buffer size.
+        AudioTrack track = new AudioTrack.Builder()
+                .setAudioAttributes(attributes)
+                .setAudioFormat(format)
+                .setTransferMode(transferMode)
+                .build();
+        assertEquals(AudioTrack.STATE_INITIALIZED, track.getState());
+        track.play();
+
+        ByteBuffer data = ByteBuffer.allocate(frameCount * frameSize);
+        data.order(java.nio.ByteOrder.nativeOrder()).limit(frameCount * frameSize);
         AudioTimestamp timestamp = new AudioTimestamp();
-        boolean hasPlayed = false;
-
         long framesWritten = 0, lastFramesPresented = 0, lastFramesPresentedAt = 0;
         int cumulativeJitterCount = 0;
+        int differentials = 0;
         float cumulativeJitter = 0;
         float maxJitter = 0;
         for (int i = 0; i < TEST_LOOP_CNT; i++) {
             final long writeTime = System.nanoTime();
 
-            for (int written = 0; written < data.length;) {
-                int ret = track.write(data, written,
-                        Math.min(data.length - written, minBufferSizeInBytes));
-                assertTrue(TEST_NAME, ret >= 0);
-                written += ret;
-                if (!hasPlayed) {
-                    track.play();
-                    hasPlayed = true;
-                }
-            }
-            framesWritten += data.length / bytesPerFrame;
+            data.position(0);
+            assertEquals(data.limit(),
+                    track.write(data, data.limit(), AudioTrack.WRITE_BLOCKING));
+            assertEquals(data.position(), data.limit());
+            framesWritten += data.limit() / frameSize;
 
             // track.getTimestamp may return false if there are no physical HAL outputs.
             // This may occur on TV devices without connecting an HDMI monitor.
@@ -1967,7 +1995,7 @@
             // Nevertheless, we don't want to have unnecessary failures, so we ignore the
             // first iteration if we don't get a timestamp.
             final boolean result = track.getTimestamp(timestamp);
-            assertTrue(TEST_NAME, result || i == 0);
+            assertTrue("timestamp could not be read", result || i == 0);
             if (!result) {
                 continue;
             }
@@ -1979,62 +2007,78 @@
             // This is an "on-the-fly" read without pausing because pausing may cause the
             // timestamp to become stale and affect our jitter measurements.
             final int framesSeen = track.getPlaybackHeadPosition();
-            assertTrue(TEST_NAME, framesWritten >= framesSeen);
-            assertTrue(TEST_NAME, framesSeen >= framesPresented);
+            assertTrue("server frames ahead of client frames", framesWritten >= framesSeen);
+            assertTrue("presented frames ahead of server frames", framesSeen >= framesPresented);
 
-            if (i > 1) { // need delta info from previous iteration (skipping first)
+            if (i > 0) { // need delta info from previous iteration (skipping first)
                 final long deltaFrames = framesPresented - lastFramesPresented;
                 final long deltaTime = framesPresentedAt - lastFramesPresentedAt;
                 final long NANOSECONDS_PER_SECOND = 1000000000;
-                final long expectedFrames = deltaTime * TEST_SR / NANOSECONDS_PER_SECOND;
+                final long expectedFrames = deltaTime * sampleRate / NANOSECONDS_PER_SECOND;
                 final long jitterFrames = Math.abs(deltaFrames - expectedFrames);
 
-                //Log.d(TAG, "framesWritten(" + framesWritten
-                //        + ") framesSeen(" + framesSeen
-                //        + ") framesPresented(" + framesPresented
-                //        + ") jitter(" + jitterFrames + ")");
+                Log.d(TAG, "framesWritten(" + framesWritten
+                        + ") framesSeen(" + framesSeen
+                        + ") framesPresented(" + framesPresented
+                        + ") framesPresentedAt(" + framesPresentedAt
+                        + ") lastframesPresented(" + lastFramesPresented
+                        + ") lastFramesPresentedAt(" + lastFramesPresentedAt
+                        + ") deltaFrames(" + deltaFrames
+                        + ") deltaTime(" + deltaTime
+                        + ") expectedFrames(" + expectedFrames
+                        + ") writeTime(" + writeTime
+                        + ") jitter(" + jitterFrames + ")");
+                assertTrue("timestamp time should be increasing", deltaTime >= 0);
+                assertTrue("timestamp frames should be increasing", deltaFrames >= 0);
 
-                // We check that the timestamp position is reasonably accurate.
-                assertTrue(TEST_NAME, deltaTime >= 0);
-                assertTrue(TEST_NAME, deltaFrames >= 0);
-                if (i > 2) {
-                    // The first two periods may have inherent jitter as the audio pipe
-                    // is filling up. We check jitter only after that.
-                    assertTrue(TEST_NAME, jitterFrames < TEST_JITTER_FRAMES_ALLOWED);
-                    cumulativeJitter += jitterFrames;
-                    cumulativeJitterCount++;
-                    if (jitterFrames > maxJitter) {
-                        maxJitter = jitterFrames;
+                // the first nonzero value may have a jump, wait for the second.
+                if (lastFramesPresented != 0) {
+                    if (differentials++ > 1) {
+                        // We check that the timestamp position is reasonably accurate.
+                        assertTrue("jitterFrames(" + jitterFrames + ") < "
+                                + TEST_JITTER_FRAMES_ALLOWED,
+                                jitterFrames < TEST_JITTER_FRAMES_ALLOWED);
+                        cumulativeJitter += jitterFrames;
+                        cumulativeJitterCount++;
+                        if (jitterFrames > maxJitter) {
+                            maxJitter = jitterFrames;
+                        }
                     }
+                    final long NANOS_PER_MILLIS = 1000000;
+                    final long closeTimeNs = TEST_BUFFER_MS * 2 * NANOS_PER_MILLIS;
+                    // We check that the timestamp time is reasonably current.
+                    assertTrue("framesPresentedAt(" + framesPresentedAt
+                            + ") close to writeTime(" + writeTime
+                            + ")", Math.abs(framesPresentedAt - writeTime) <= closeTimeNs);
+                    assertTrue("timestamps must have causal time",
+                            writeTime >= lastFramesPresentedAt);
                 }
-
-                //Log.d(TAG, "lastFramesPresentedAt(" + lastFramesPresentedAt
-                //        + ") writeTime(" + writeTime
-                //        + ") framesPresentedAt(" + framesPresentedAt + ")");
-
-                // We check that the timestamp time is reasonably current.
-                assertTrue(TEST_NAME, framesPresentedAt >= writeTime);
-                assertTrue(TEST_NAME, writeTime >= lastFramesPresentedAt);
             }
             lastFramesPresented = framesPresented;
             lastFramesPresentedAt = framesPresentedAt;
         }
         // Full drain.
-        Thread.sleep(WAIT_MSEC);
-        track.stop();
-        Thread.sleep(WAIT_MSEC);
+        Thread.sleep(1000 /* millis */);
+        // check that we are really at the end of playback.
+        assertTrue("timestamp should be valid while draining", track.getTimestamp(timestamp));
+        if (!fast) {  // fast tracks may not fully drain
+            assertEquals("timestamp should fully drain", framesWritten, timestamp.framePosition);
+        }
+        assertTrue("sufficient nonzero timestamps", differentials > 2);
+
         track.release();
         // Log the average jitter
         if (cumulativeJitterCount > 0) {
-            ReportLog log = getReportLog();
+            DeviceReportLog log = new DeviceReportLog();
             final float averageJitterInFrames = cumulativeJitter / cumulativeJitterCount;
-            final float averageJitterInMs = averageJitterInFrames * 1000 / TEST_SR;
-            final float maxJitterInMs = maxJitter * 1000 / TEST_SR;
+            final float averageJitterInMs = averageJitterInFrames * 1000 / sampleRate;
+            final float maxJitterInMs = maxJitter * 1000 / sampleRate;
             // ReportLog needs at least one Value and Summary.
-            log.printValue("Maximum Jitter", maxJitterInMs,
+            log.addValue("Maximum Jitter", maxJitterInMs,
                     ResultType.LOWER_BETTER, ResultUnit.MS);
-            log.printSummary("Average Jitter", averageJitterInMs,
+            log.setSummary("Average Jitter", averageJitterInMs,
                     ResultType.LOWER_BETTER, ResultUnit.MS);
+            log.submit(getInstrumentation());
         }
     }
 
diff --git a/tests/tests/media/src/android/media/cts/AudioTrack_ListenerTest.java b/tests/tests/media/src/android/media/cts/AudioTrack_ListenerTest.java
index e059e36..37affd0 100644
--- a/tests/tests/media/src/android/media/cts/AudioTrack_ListenerTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioTrack_ListenerTest.java
@@ -16,21 +16,20 @@
 
 package android.media.cts;
 
-import java.util.ArrayList;
-
 import android.cts.util.CtsAndroidTestCase;
 import android.media.AudioFormat;
 import android.media.AudioManager;
 import android.media.AudioTrack;
 import android.media.AudioTrack.OnPlaybackPositionUpdateListener;
-import android.media.cts.AudioHelper;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
-import android.util.Log;
-import com.android.cts.util.ReportLog;
-import com.android.cts.util.ResultType;
-import com.android.cts.util.ResultUnit;
+
+import com.android.compatibility.common.util.DeviceReportLog;
+import com.android.compatibility.common.util.ResultType;
+import com.android.compatibility.common.util.ResultUnit;
+
+import java.util.ArrayList;
 
 public class AudioTrack_ListenerTest extends CtsAndroidTestCase {
     private final static String TAG = "AudioTrack_ListenerTest";
@@ -206,22 +205,23 @@
         }
 
         // report this
-        ReportLog log = getReportLog();
-        log.printValue(reportName + ": Average Marker diff", markerStat.getAvg(),
+        DeviceReportLog log = new DeviceReportLog();
+        log.addValue(reportName + ": Average Marker diff", markerStat.getAvg(),
                 ResultType.LOWER_BETTER, ResultUnit.MS);
-        log.printValue(reportName + ": Maximum Marker abs diff", markerStat.getMaxAbs(),
+        log.addValue(reportName + ": Maximum Marker abs diff", markerStat.getMaxAbs(),
                 ResultType.LOWER_BETTER, ResultUnit.MS);
-        log.printValue(reportName + ": Average Marker abs diff", markerStat.getAvgAbs(),
+        log.addValue(reportName + ": Average Marker abs diff", markerStat.getAvgAbs(),
                 ResultType.LOWER_BETTER, ResultUnit.MS);
-        log.printValue(reportName + ": Average Periodic diff", periodicStat.getAvg(),
+        log.addValue(reportName + ": Average Periodic diff", periodicStat.getAvg(),
                 ResultType.LOWER_BETTER, ResultUnit.MS);
-        log.printValue(reportName + ": Maximum Periodic abs diff", periodicStat.getMaxAbs(),
+        log.addValue(reportName + ": Maximum Periodic abs diff", periodicStat.getMaxAbs(),
                 ResultType.LOWER_BETTER, ResultUnit.MS);
-        log.printValue(reportName + ": Average Periodic abs diff", periodicStat.getAvgAbs(),
+        log.addValue(reportName + ": Average Periodic abs diff", periodicStat.getAvgAbs(),
                 ResultType.LOWER_BETTER, ResultUnit.MS);
-        log.printSummary(reportName + ": Unified abs diff",
+        log.setSummary(reportName + ": Unified abs diff",
                 (periodicStat.getAvgAbs() + markerStat.getAvgAbs()) / 2,
                 ResultType.LOWER_BETTER, ResultUnit.MS);
+        log.submit(getInstrumentation());
     }
 
     private class MockOnPlaybackPositionUpdateListener
diff --git a/tests/tests/media/src/android/media/cts/ClearKeySystemTest.java b/tests/tests/media/src/android/media/cts/ClearKeySystemTest.java
index 02276bc..7d5742e 100644
--- a/tests/tests/media/src/android/media/cts/ClearKeySystemTest.java
+++ b/tests/tests/media/src/android/media/cts/ClearKeySystemTest.java
@@ -56,35 +56,36 @@
     private static final String TAG = ClearKeySystemTest.class.getSimpleName();
 
     // Add additional keys here if the content has more keys.
-    private static final byte[] CLEAR_KEY =
+    private static final byte[] CLEAR_KEY_CENC =
         { 0x1a, (byte)0x8a, 0x20, (byte)0x95, (byte)0xe4, (byte)0xde, (byte)0xb2, (byte)0xd2,
           (byte)0x9e, (byte)0xc8, 0x16, (byte)0xac, 0x7b, (byte)0xae, 0x20, (byte)0x82 };
 
-    private static final int SLEEP_TIME_MS = 1000;
-    private static final int VIDEO_WIDTH = 1280;
-    private static final int VIDEO_HEIGHT = 720;
-    private static final long PLAY_TIME_MS = TimeUnit.MILLISECONDS.convert(1, TimeUnit.MINUTES);
-    private static final String MIME_VIDEO_AVC = MediaFormat.MIMETYPE_VIDEO_AVC;
+    private static final byte[] CLEAR_KEY_WEBM = "_CLEAR_KEY_WEBM_".getBytes();
 
-    private static final Uri AUDIO_URL = Uri.parse(
+    private static final int CONNECTION_RETRIES = 10;
+    private static final int SLEEP_TIME_MS = 1000;
+    private static final int VIDEO_WIDTH_CENC = 1280;
+    private static final int VIDEO_HEIGHT_CENC = 720;
+    private static final int VIDEO_WIDTH_WEBM = 320;
+    private static final int VIDEO_HEIGHT_WEBM = 180;
+    private static final long PLAY_TIME_MS = TimeUnit.MILLISECONDS.convert(25, TimeUnit.SECONDS);
+    private static final String MIME_VIDEO_AVC = MediaFormat.MIMETYPE_VIDEO_AVC;
+    private static final String MIME_VIDEO_VP8 = MediaFormat.MIMETYPE_VIDEO_VP8;
+
+    private static final Uri CENC_AUDIO_URL = Uri.parse(
             "http://yt-dash-mse-test.commondatastorage.googleapis.com/media/car_cenc-20120827-8c.mp4");
-    private static final Uri VIDEO_URL = Uri.parse(
+    private static final Uri CENC_VIDEO_URL = Uri.parse(
             "http://yt-dash-mse-test.commondatastorage.googleapis.com/media/car_cenc-20120827-88.mp4");
+    private static final Uri WEBM_URL = Uri.parse(
+            "android.resource://android.media.cts/" + R.raw.video_320x240_webm_vp8_800kbps_30fps_vorbis_stereo_128kbps_44100hz_crypt);
 
     private static final UUID CLEARKEY_SCHEME_UUID =
             new UUID(0x1077efecc0b24d02L, 0xace33c1e52e2fb4bL);
 
     private byte[] mDrmInitData;
     private byte[] mSessionId;
-    private Context mContext;
-    private final List<byte[]> mClearKeys = new ArrayList<byte[]>() {
-        {
-            add(CLEAR_KEY);
-            // add additional keys here
-        }
-    };
     private Looper mLooper;
-    private MediaCodecCencPlayer mMediaCodecPlayer;
+    private MediaCodecClearKeyPlayer mMediaCodecPlayer;
     private MediaDrm mDrm;
     private Object mLock = new Object();
     private SurfaceHolder mSurfaceHolder;
@@ -161,10 +162,11 @@
      * Retrieves clear key ids from getKeyRequest(), create JSON Web Key
      * set and send it to the CDM via provideKeyResponse().
      */
-    private void getKeys(MediaDrm drm, byte[] sessionId, byte[] drmInitData) {
+    private void getKeys(MediaDrm drm, String initDataType,
+            byte[] sessionId, byte[] drmInitData, byte[][] clearKeys) {
         MediaDrm.KeyRequest drmRequest = null;;
         try {
-            drmRequest = drm.getKeyRequest(sessionId, drmInitData, "cenc",
+            drmRequest = drm.getKeyRequest(sessionId, drmInitData, initDataType,
                     MediaDrm.KEY_TYPE_STREAMING, null);
         } catch (Exception e) {
             e.printStackTrace();
@@ -181,16 +183,16 @@
             return;
         }
 
-        if (mClearKeys.size() != keyIds.size()) {
+        if (clearKeys.length != keyIds.size()) {
             Log.e(TAG, "Mismatch number of key ids and keys: ids=" +
-                    keyIds.size() + ", keys=" + mClearKeys.size());
+                    keyIds.size() + ", keys=" + clearKeys.length);
             return;
         }
 
         // Base64 encodes clearkeys. Keys are known to the application.
         Vector<String> keys = new Vector<String>();
-        for (int i = 0; i < mClearKeys.size(); ++i) {
-            String clearKey = Base64.encodeToString(mClearKeys.get(i),
+        for (int i = 0; i < clearKeys.length; ++i) {
+            String clearKey = Base64.encodeToString(clearKeys[i],
                     Base64.NO_PADDING | Base64.NO_WRAP);
             keys.add(clearKey);
         }
@@ -210,7 +212,7 @@
         }
     }
 
-    private MediaDrm startDrm() {
+    private MediaDrm startDrm(final byte[][] clearKeys, final String initDataType) {
         new Thread() {
             @Override
             public void run() {
@@ -235,10 +237,10 @@
                                     int extra, byte[] data) {
                                 if (event == MediaDrm.EVENT_KEY_REQUIRED) {
                                     Log.i(TAG, "MediaDrm event: Key required");
-                                    getKeys(mDrm, mSessionId, mDrmInitData);
+                                    getKeys(mDrm, initDataType, mSessionId, mDrmInitData, clearKeys);
                                 } else if (event == MediaDrm.EVENT_KEY_EXPIRED) {
                                     Log.i(TAG, "MediaDrm event: Key expired");
-                                    getKeys(mDrm, mSessionId, mDrmInitData);
+                                    getKeys(mDrm, initDataType, mSessionId, mDrmInitData, clearKeys);
                                 } else {
                                     Log.e(TAG, "Events not supported" + event);
                                 }
@@ -285,7 +287,8 @@
         drm.closeSession(sessionId);
     }
 
-    public boolean isResolutionSupported(int videoWidth, int videoHeight) {
+    public boolean isResolutionSupported(String mime, String[] features,
+            int videoWidth, int videoHeight) {
         if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN) {
             if  (videoHeight <= 144) {
                 return CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_QCIF);
@@ -304,10 +307,10 @@
             }
         }
 
-        MediaFormat format = MediaFormat.createVideoFormat(
-                MIME_VIDEO_AVC, videoWidth, videoHeight);
-        // using secure codec even though it is clear key DRM
-        format.setFeatureEnabled(CodecCapabilities.FEATURE_SecurePlayback, true);
+        MediaFormat format = MediaFormat.createVideoFormat(mime, videoWidth, videoHeight);
+        for (String feature: features) {
+            format.setFeatureEnabled(feature, true);
+        }
         MediaCodecList mcl = new MediaCodecList(MediaCodecList.ALL_CODECS);
         if (mcl.findDecoderForFormat(format) == null) {
             Log.i(TAG, "could not find codec for " + format);
@@ -319,9 +322,13 @@
     /**
      * Tests clear key system playback.
      */
-    public void testClearKeyPlayback() throws Exception {
-
-        MediaDrm drm = startDrm();
+    private void testClearKeyPlayback(
+            String videoMime, String[] videoFeatures,
+            String initDataType, byte[][] clearKeys,
+            Uri audioUrl, boolean audioEncrypted,
+            Uri videoUrl, boolean videoEncrypted,
+            int videoWidth, int videoHeight) throws Exception {
+        MediaDrm drm = startDrm(clearKeys, initDataType);
         if (null == drm) {
             throw new Error("Failed to create drm.");
         }
@@ -331,27 +338,48 @@
             throw new Error("Crypto scheme is not supported.");
         }
 
-        if (!isResolutionSupported(VIDEO_WIDTH, VIDEO_HEIGHT)) {
+        if (!isResolutionSupported(videoMime, videoFeatures, videoWidth, videoHeight)) {
             Log.i(TAG, "Device does not support " +
-                    VIDEO_WIDTH + "x" + VIDEO_HEIGHT + "resolution.");
+                    videoWidth + "x" + videoHeight + " resolution for " + videoMime);
             return;
         }
 
-        mSessionId = openSession(drm);
-        mMediaCodecPlayer = new MediaCodecCencPlayer(
-                getActivity().getSurfaceHolder(), mSessionId);
+        IConnectionStatus wifiStatus = new WifiStatus(mContext);
+        if (!wifiStatus.isEnabled()) {
+            throw new Error("Wifi is not enabled, please enable Wifi to run tests.");
+        }
+        // If Wifi is not connected, recheck the status a few times.
+        int retries = 0;
+        while (!wifiStatus.isConnected()) {
+            if (retries++ >= CONNECTION_RETRIES) {
+                wifiStatus.printConnectionInfo();
+                throw new Error("Wifi is not connected, reason: " +
+                        wifiStatus.getNotConnectedReason());
+            }
+            try {
+                Thread.sleep(100);
+            } catch (InterruptedException e) {
+            }
+        }
+        wifiStatus.testConnection(videoUrl);
 
-        mMediaCodecPlayer.setAudioDataSource(AUDIO_URL, null, false);
-        mMediaCodecPlayer.setVideoDataSource(VIDEO_URL, null, true);
+        mSessionId = openSession(drm);
+        mMediaCodecPlayer = new MediaCodecClearKeyPlayer(
+                getActivity().getSurfaceHolder(),
+                mSessionId,
+                mContext.getResources());
+
+        mMediaCodecPlayer.setAudioDataSource(audioUrl, null, audioEncrypted);
+        mMediaCodecPlayer.setVideoDataSource(videoUrl, null, videoEncrypted);
         mMediaCodecPlayer.start();
         mMediaCodecPlayer.prepare();
-        mDrmInitData = mMediaCodecPlayer.getPsshInfo().get(CLEARKEY_SCHEME_UUID);
+        mDrmInitData = mMediaCodecPlayer.getDrmInitData();
 
-        getKeys(mDrm, mSessionId, mDrmInitData);
+        getKeys(mDrm, initDataType, mSessionId, mDrmInitData, clearKeys);
         // starts video playback
         mMediaCodecPlayer.startThread();
 
-        long timeOut = System.currentTimeMillis() + PLAY_TIME_MS * 4;
+        long timeOut = System.currentTimeMillis() + PLAY_TIME_MS;
         while (timeOut > System.currentTimeMillis() && !mMediaCodecPlayer.isEnded()) {
             Thread.sleep(SLEEP_TIME_MS);
             if (mMediaCodecPlayer.getCurrentPosition() >= mMediaCodecPlayer.getDuration() ) {
@@ -366,4 +394,23 @@
         closeSession(drm, mSessionId);
         stopDrm(drm);
     }
+
+    public void testClearKeyPlaybackCenc() throws Exception {
+        testClearKeyPlayback(
+            // using secure codec even though it is clear key DRM
+            MIME_VIDEO_AVC, new String[] { CodecCapabilities.FEATURE_SecurePlayback },
+            "cenc", new byte[][] { CLEAR_KEY_CENC },
+            CENC_AUDIO_URL, false,
+            CENC_VIDEO_URL, true,
+            VIDEO_WIDTH_CENC, VIDEO_HEIGHT_CENC);
+    }
+
+    public void testClearKeyPlaybackWebm() throws Exception {
+        testClearKeyPlayback(
+            MIME_VIDEO_VP8, new String[0],
+            "webm", new byte[][] { CLEAR_KEY_WEBM },
+            WEBM_URL, true,
+            WEBM_URL, true,
+            VIDEO_WIDTH_WEBM, VIDEO_WIDTH_WEBM);
+    }
 }
diff --git a/tests/tests/media/src/android/media/cts/CodecUtils.java b/tests/tests/media/src/android/media/cts/CodecUtils.java
index ef20e67..b7ebb88 100644
--- a/tests/tests/media/src/android/media/cts/CodecUtils.java
+++ b/tests/tests/media/src/android/media/cts/CodecUtils.java
@@ -105,8 +105,10 @@
         }
     }
 
+    /* two native image checksum functions */
+    public native static int getImageChecksumAdler32(CodecImage image);
+    public native static String getImageChecksumMD5(CodecImage image);
 
-    public native static int getImageChecksum(CodecImage image);
     public native static void copyFlexYUVImage(CodecImage target, CodecImage source);
 
     public static void copyFlexYUVImage(Image target, CodecImage source) {
diff --git a/tests/tests/media/src/android/media/cts/DecodeAccuracyTest.java b/tests/tests/media/src/android/media/cts/DecodeAccuracyTest.java
new file mode 100644
index 0000000..319df5a
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/DecodeAccuracyTest.java
@@ -0,0 +1,257 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.media.cts;
+
+import android.media.cts.R;
+
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.cts.util.MediaUtils;
+import android.graphics.Bitmap;
+import android.os.Build;
+import android.util.DisplayMetrics;
+import android.util.Log;
+import android.view.View;
+import android.view.WindowManager;
+
+import com.android.cts.util.TimeoutReq;
+
+@TargetApi(16)
+public class DecodeAccuracyTest extends DecodeAccuracyTestBase {
+
+    private static final String TAG = DecodeAccuracyTest.class.getSimpleName();
+    private static final String H264_VIDEO_FILE_NAME = "480ph264decodertest.mp4";
+    private static final String VP9_VIDEO_FILE_NAME = "360pvp9decodertest.webm";
+    private static final int ALLOWED_GREATEST_PIXEL_DIFFERENCE = 90;
+    private static final int TESTCASE_WAITTIME_MIN = 1;
+    private static final int OFFSET = 10;
+
+    /* <------------- Tests Using H264 -------------> */
+    @TimeoutReq(minutes = TESTCASE_WAITTIME_MIN)
+    public void testH264TextureViewVideoDecode() throws Exception {
+        runDecodeAccuracyTest(
+                new TextureViewFactory(),
+                new VideoFormat(H264_VIDEO_FILE_NAME));
+    }
+
+    @TimeoutReq(minutes = TESTCASE_WAITTIME_MIN)
+    public void testH264TextureViewLargerHeightVideoDecode() throws Exception {
+        runDecodeAccuracyTest(
+                new TextureViewFactory(),
+                getLargerHeightVideoFormat(new VideoFormat(H264_VIDEO_FILE_NAME)));
+    }
+
+    @TimeoutReq(minutes = TESTCASE_WAITTIME_MIN)
+    public void testH264TextureViewLargerWidthVideoDecode() throws Exception {
+        runDecodeAccuracyTest(
+                new TextureViewFactory(),
+                getLargerWidthVideoFormat(new VideoFormat(H264_VIDEO_FILE_NAME)));
+    }
+
+    @TimeoutReq(minutes = TESTCASE_WAITTIME_MIN)
+    public void testH264GLViewVideoDecode() throws Exception {
+        runDecodeAccuracyTest(
+                new GLSurfaceViewFactory(),
+                new VideoFormat(H264_VIDEO_FILE_NAME));
+    }
+
+    @TimeoutReq(minutes = TESTCASE_WAITTIME_MIN)
+    public void testH264GLViewLargerHeightVideoDecode() throws Exception {
+        runDecodeAccuracyTest(
+                new GLSurfaceViewFactory(),
+                getLargerHeightVideoFormat(new VideoFormat(H264_VIDEO_FILE_NAME)));
+    }
+
+    @TimeoutReq(minutes = TESTCASE_WAITTIME_MIN)
+    public void testH264GLViewLargerWidthVideoDecode() throws Exception {
+        runDecodeAccuracyTest(
+                new GLSurfaceViewFactory(),
+                getLargerWidthVideoFormat(new VideoFormat(H264_VIDEO_FILE_NAME)));
+    }
+
+    /* <------------- Tests Using VP9 -------------> */
+    @TimeoutReq(minutes = TESTCASE_WAITTIME_MIN)
+    public void testVP9TextureViewVideoDecode() throws Exception {
+        runDecodeAccuracyTest(
+                new TextureViewFactory(),
+                new VideoFormat(VP9_VIDEO_FILE_NAME));
+    }
+
+    @TimeoutReq(minutes = TESTCASE_WAITTIME_MIN)
+    public void testVP9TextureViewLargerHeightVideoDecode() throws Exception {
+        runDecodeAccuracyTest(
+                new TextureViewFactory(),
+                getLargerHeightVideoFormat(new VideoFormat(VP9_VIDEO_FILE_NAME)));
+    }
+
+    @TimeoutReq(minutes = TESTCASE_WAITTIME_MIN)
+    public void testVP9TextureViewLargerWidthVideoDecode() throws Exception {
+        runDecodeAccuracyTest(
+                new TextureViewFactory(),
+                getLargerWidthVideoFormat(new VideoFormat(VP9_VIDEO_FILE_NAME)));
+    }
+
+    @TimeoutReq(minutes = TESTCASE_WAITTIME_MIN)
+    public void testVP9GLViewVideoDecode() throws Exception {
+        runDecodeAccuracyTest(
+                new GLSurfaceViewFactory(),
+                new VideoFormat(VP9_VIDEO_FILE_NAME));
+    }
+
+    @TimeoutReq(minutes = TESTCASE_WAITTIME_MIN)
+    public void testVP9GLViewLargerHeightVideoDecode() throws Exception {
+        runDecodeAccuracyTest(
+                new GLSurfaceViewFactory(),
+                getLargerHeightVideoFormat(new VideoFormat(VP9_VIDEO_FILE_NAME)));
+    }
+
+    @TimeoutReq(minutes = TESTCASE_WAITTIME_MIN)
+    public void testVP9GLViewLargerWidthVideoDecode() throws Exception {
+        runDecodeAccuracyTest(
+                new GLSurfaceViewFactory(),
+                getLargerWidthVideoFormat(new VideoFormat(VP9_VIDEO_FILE_NAME)));
+    }
+
+    private void runDecodeAccuracyTest(VideoViewFactory videoViewFactory, VideoFormat videoFormat) {
+        checkNotNull(videoViewFactory);
+        checkNotNull(videoFormat);
+        if (!DisplayUtil.canPlay360p(getHelper().getContext())) {
+            MediaUtils.skipTest("Display does not support 360p.");
+            return;
+        }
+        if (!DisplayUtil.currentOrientationCanPlay360p(getHelper().getContext())) {
+            Log.w(TAG, "Current screen orientation does not support 360p.");
+            Log.i(TAG, "Rotate screen orientation and continue.");
+            getHelper().rotateOrientation();
+        }
+        View videoView = videoViewFactory.createView(getHelper().getContext());
+        // If view is intended and available to display.
+        if (videoView != null) {
+            getHelper().generateView(videoView);
+        }
+        videoViewFactory.waitForViewIsAvailable();
+
+        decodeVideo(videoFormat, videoViewFactory);
+        validateResult(videoFormat, videoViewFactory);
+
+        if (videoView != null) {
+            getHelper().cleanUpView(videoView);
+        }
+        videoViewFactory.release();
+        getHelper().unsetOrientation();
+    }
+
+    private void decodeVideo(VideoFormat videoFormat, VideoViewFactory videoViewFactory) {
+        final SimplePlayer player = new SimplePlayer(getHelper().getContext());
+        final SimplePlayer.PlayerResult playerResult = player.decodeVideoFrames(
+                videoViewFactory.getSurface(), videoFormat, 10);
+        assertTrue("Failed to configure video decoder.", playerResult.isConfigureSuccess());
+        assertTrue("Failed to start video decoder.", playerResult.isStartSuccess());
+        assertTrue("Failed to decode the video.", playerResult.isSuccess());
+    }
+
+    private void validateResult(VideoFormat videoFormat, VideoViewFactory videoViewFactory) {
+        final Bitmap result = getHelper().generateBitmapFromVideoViewSnapshot(
+                videoViewFactory.getVideoViewSnapshot());
+        final Bitmap golden;
+        final String mime = videoFormat.getMimeType();
+        if (mime.equals(MimeTypes.VIDEO_H264)) {
+            golden = getHelper().generateBitmapFromImageResourceId(R.raw.h264decodertestgolden);
+        } else if (mime.equals(MimeTypes.VIDEO_VP9)) {
+            golden = getHelper().generateBitmapFromImageResourceId(R.raw.vp9decodertestgolden);
+        } else {
+            fail("Unsupported MIME type " + mime);
+            return;
+        }
+        final BitmapCompare.Difference difference = BitmapCompare.computeDifference(golden, result);
+        assertTrue("Greatest pixel difference is "
+                    + difference.greatestPixelDifference
+                    + (difference.greatestPixelDifferenceCoordinates != null
+                    ? " at (" + difference.greatestPixelDifferenceCoordinates.first + ", "
+                    + difference.greatestPixelDifferenceCoordinates.second + ")" : "")
+                    + " which is over the allowed difference " + ALLOWED_GREATEST_PIXEL_DIFFERENCE,
+                    difference.greatestPixelDifference <= ALLOWED_GREATEST_PIXEL_DIFFERENCE);
+    }
+
+    private static VideoFormat getLargerHeightVideoFormat(VideoFormat videoFormat) {
+        return new VideoFormat(videoFormat) {
+            @Override
+            public int getHeight() {
+                return super.getHeight() + OFFSET;
+            }
+            @Override
+            public int getMaxHeight() {
+                return super.getHeight() * 2 + OFFSET;
+            }
+            @Override
+            public int getMaxWidth() {
+                return super.getWidth() * 2 + OFFSET;
+            }
+        };
+    }
+
+    private static VideoFormat getLargerWidthVideoFormat(VideoFormat videoFormat) {
+        return new VideoFormat(videoFormat) {
+            @Override
+            public int getWidth() {
+                return super.getWidth() + OFFSET;
+            }
+            @Override
+            public int getMaxHeight() {
+                return super.getHeight() * 2 + OFFSET;
+            }
+            @Override
+            public int getMaxWidth() {
+                return super.getWidth() * 2 + OFFSET;
+            }
+        };
+    }
+
+    private static final class DisplayUtil {
+
+        public static boolean canPlay360p(Context context) {
+            return displayMetricsHasMinPixelSize(context, 360);
+        }
+
+        public static boolean currentOrientationCanPlay360p(Context context) {
+            DisplayMetrics metrics = getDisplayMetrics(context);
+            return metrics.widthPixels >= 480 && metrics.heightPixels >= 360;
+        }
+
+        private static boolean displayMetricsHasMinPixelSize(Context context, int minPixelSize) {
+            return getDisplayMetricsMinPixelSize(context) >= minPixelSize;
+        }
+
+        private static int getDisplayMetricsMinPixelSize(Context context) {
+            DisplayMetrics metrics = getDisplayMetrics(context);
+            return Math.min(metrics.widthPixels, metrics.heightPixels);
+        }
+
+        private static DisplayMetrics getDisplayMetrics(Context context) {
+            checkNotNull(context);
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
+                DisplayMetrics metrics = new DisplayMetrics();
+                ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE))
+                        .getDefaultDisplay().getRealMetrics(metrics);
+                return metrics;
+            } else {
+                return context.getResources().getDisplayMetrics();
+            }
+        }
+
+    }
+
+}
diff --git a/tests/tests/media/src/android/media/cts/DecodeAccuracyTestActivity.java b/tests/tests/media/src/android/media/cts/DecodeAccuracyTestActivity.java
new file mode 100644
index 0000000..da06844
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/DecodeAccuracyTestActivity.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.media.cts;
+
+import android.media.cts.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.WindowManager;
+
+public class DecodeAccuracyTestActivity extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.test_runner_activity);
+        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+    }
+
+}
diff --git a/tests/tests/media/src/android/media/cts/DecodeAccuracyTestBase.java b/tests/tests/media/src/android/media/cts/DecodeAccuracyTestBase.java
new file mode 100644
index 0000000..8caf495
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/DecodeAccuracyTestBase.java
@@ -0,0 +1,1379 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.media.cts;
+
+import android.media.cts.R;
+
+import android.annotation.TargetApi;
+import android.app.Activity;
+import android.content.Context;
+import android.content.pm.ActivityInfo;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Color;
+import android.graphics.SurfaceTexture;
+import android.media.MediaCodec;
+import android.media.MediaCodec.BufferInfo;
+import android.media.MediaCodec.CodecException;
+import android.media.MediaExtractor;
+import android.media.MediaFormat;
+import android.net.Uri;
+import android.opengl.EGL14;
+import android.opengl.GLES11Ext;
+import android.opengl.GLES20;
+import android.opengl.GLSurfaceView;
+import android.os.Build;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.SystemClock;
+import android.test.ActivityInstrumentationTestCase2;
+import android.util.Log;
+import android.util.Pair;
+import android.util.SparseArray;
+import android.view.Surface;
+import android.view.TextureView;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.RelativeLayout;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.FloatBuffer;
+import java.util.concurrent.TimeUnit;
+
+import javax.microedition.khronos.egl.EGL10;
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.egl.EGLContext;
+import javax.microedition.khronos.egl.EGLDisplay;
+import javax.microedition.khronos.egl.EGLSurface;
+
+@TargetApi(16)
+public class DecodeAccuracyTestBase
+    extends ActivityInstrumentationTestCase2<DecodeAccuracyTestActivity> {
+
+    protected Context mContext;
+    protected Resources mResources;
+    protected DecodeAccuracyTestActivity mActivity;
+    protected TestHelper testHelper;
+
+    public DecodeAccuracyTestBase() {
+        super(DecodeAccuracyTestActivity.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mActivity = getActivity();
+        getInstrumentation().waitForIdleSync();
+        mContext = getInstrumentation().getTargetContext();
+        mResources = mContext.getResources();
+        testHelper = new TestHelper(mContext, mActivity);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        mActivity = null;
+        super.tearDown();
+    }
+
+    protected TestHelper getHelper() {
+        return testHelper;
+    }
+
+    public static <T> T checkNotNull(T reference) {
+        assertNotNull(reference);
+        return reference;
+    }
+
+    public static class SimplePlayer {
+
+        public static final long DECODE_TIMEOUT_MS = TimeUnit.SECONDS.toMillis(1) / 2;
+
+        private static final int NO_TRACK_INDEX = -3;
+        private static final long DEQUEUE_TIMEOUT_US = 20;
+        private static final String TAG = SimplePlayer.class.getSimpleName();
+
+        private final Context context;
+        private final MediaExtractor extractor;
+        private MediaCodec decoder;
+
+        public SimplePlayer(Context context) {
+            this(context, new MediaExtractor());
+        }
+
+        public SimplePlayer(Context context, MediaExtractor extractor) {
+            this.context = checkNotNull(context);
+            this.extractor = checkNotNull(extractor);
+        }
+
+        /*
+         * The function play the corresponding file for certain number of frames,
+         *
+         * @param surface is the surface view of decoder output.
+         * @param videoFormat is the format of the video to extract and decode.
+         * @param numOfTotalFrame is the number of Frame wish to play.
+         * @return a PlayerResult object indicating success or failure.
+         */
+        public PlayerResult decodeVideoFrames(
+                Surface surface, VideoFormat videoFormat, int numOfTotalFrames) {
+            PlayerResult playerResult;
+            if (prepare(surface, videoFormat)) {
+                if (startDecoder()) {
+                    playerResult = decodeFramesAndDisplay(
+                            surface, numOfTotalFrames, numOfTotalFrames * DECODE_TIMEOUT_MS);
+                } else {
+                    playerResult = PlayerResult.failToStart();
+                }
+            } else {
+                playerResult = new PlayerResult();
+            }
+            release();
+            return new PlayerResult(playerResult);
+        }
+
+        public PlayerResult decodeVideoFrames(VideoFormat videoFormat, int numOfTotalFrames) {
+            return decodeVideoFrames(null, videoFormat, numOfTotalFrames);
+        }
+
+        /*
+         * The function set up the extractor and decoder with proper format.
+         * This must be called before decodeFramesAndDisplay.
+         */
+        private boolean prepare(Surface surface, VideoFormat videoFormat) {
+            if (!setExtractorDataSource(videoFormat)) {
+                return false;
+            }
+            int trackNum = getFirstVideoTrackIndex(extractor);
+            if (trackNum == NO_TRACK_INDEX) {
+                return false;
+            }
+            extractor.selectTrack(trackNum);
+            MediaFormat mediaFormat = extractor.getTrackFormat(trackNum);
+            configureFormat(mediaFormat, videoFormat);
+            return configureDecoder(surface, mediaFormat);
+        }
+
+        /* The function decode video frames and display in a surface. */
+        private PlayerResult decodeFramesAndDisplay(
+                Surface surface, int numOfTotalFrames, long timeOutMs) {
+            checkNotNull(decoder);
+            int numOfDecodedFrames = 0;
+            long decodeStart = 0;
+            boolean renderToSurface = surface != null ? true : false;
+            BufferInfo info = new BufferInfo();
+            ByteBuffer inputBuffer;
+            ByteBuffer[] inputBufferArray = decoder.getInputBuffers();
+            long loopStart = SystemClock.elapsedRealtime();
+
+            while (numOfDecodedFrames < numOfTotalFrames
+                    && (SystemClock.elapsedRealtime() - loopStart < timeOutMs)) {
+                try {
+                    int inputBufferIndex = decoder.dequeueInputBuffer(DEQUEUE_TIMEOUT_US);
+                    if (inputBufferIndex >= 0) {
+                        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
+                            inputBuffer = inputBufferArray[inputBufferIndex];
+                        } else {
+                            inputBuffer = decoder.getInputBuffer(inputBufferIndex);
+                        }
+                        if (decodeStart == 0) {
+                            decodeStart = SystemClock.elapsedRealtime();
+                        }
+                        int sampleSize = extractor.readSampleData(inputBuffer, 0);
+                        if (sampleSize > 0) {
+                            decoder.queueInputBuffer(
+                                    inputBufferIndex, 0, sampleSize, extractor.getSampleTime(), 0);
+                            extractor.advance();
+                        }
+                    }
+                    int decoderStatus = decoder.dequeueOutputBuffer(info, DEQUEUE_TIMEOUT_US);
+                    if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
+                        break;
+                    }
+                    if (decoderStatus >= 0 && info.size > 0) {
+                        decoder.releaseOutputBuffer(decoderStatus, renderToSurface);
+                        numOfDecodedFrames++;
+                    }
+                } catch (IllegalStateException exception) {
+                    Log.e(TAG, "IllegalStateException in decodeFramesAndDisplay " + exception);
+                    break;
+                }
+            }
+            long totalTime = SystemClock.elapsedRealtime() - decodeStart;
+            return new PlayerResult(true, true, numOfTotalFrames == numOfDecodedFrames, totalTime);
+        }
+
+        private void release() {
+            decoderRelease();
+            extractorRelease();
+        }
+
+        private boolean setExtractorDataSource(VideoFormat videoFormat) {
+            try {
+                extractor.setDataSource(context, videoFormat.loadUri(context), null);
+            } catch (IOException exception) {
+                Log.e(TAG, "IOException in setDataSource", exception);
+                return false;
+            }
+            return true;
+        }
+
+        private boolean configureDecoder(Surface surface, MediaFormat mediaFormat) {
+            try {
+                decoder = MediaCodec.createDecoderByType(
+                        mediaFormat.getString(MediaFormat.KEY_MIME));
+                decoder.configure(mediaFormat, surface, null, 0);
+            } catch (Exception exception) {
+                if (exception instanceof IOException) {
+                    Log.e(TAG, "IOException in createDecoderByType", exception);
+                } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP
+                        && exception instanceof CodecException) {
+                    Log.e(TAG, "CodecException in createDecoderByType", exception);
+                    decoder.reset();
+                } else {
+                    Log.e(TAG, "Unknown exception in createDecoderByType", exception);
+                }
+                decoderRelease();
+                return false;
+            }
+            return true;
+        }
+
+        private boolean startDecoder() {
+            try {
+                decoder.start();
+            } catch (Exception exception) {
+                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP
+                        && exception instanceof CodecException) {
+                    Log.e(TAG, "CodecException in startDecoder", exception);
+                    decoder.reset();
+                } else if (exception instanceof IllegalStateException) {
+                    Log.e(TAG, "IllegalStateException in startDecoder", exception);
+                } else {
+                    Log.e(TAG, "Unknown exception in startDecoder", exception);
+                }
+                decoderRelease();
+                return false;
+            }
+            return true;
+        }
+
+        private void decoderRelease() {
+            if (decoder == null) {
+                return;
+            }
+            try {
+                decoder.stop();
+            } catch (IllegalStateException exception) {
+                // IllegalStateException happens when decoder fail to start.
+                Log.e(TAG, "IllegalStateException in decoder stop" + exception);
+            } finally {
+                try {
+                    decoder.release();
+                } catch (IllegalStateException exception) {
+                    Log.e(TAG, "IllegalStateException in decoder release" + exception);
+                }
+            }
+            decoder = null;
+        }
+
+        private void extractorRelease() {
+            if (extractor == null) {
+                return;
+            }
+            try {
+                extractor.release();
+            } catch (IllegalStateException exception) {
+                Log.e(TAG, "IllegalStateException in extractor release" + exception);
+            }
+        }
+
+        private static void configureFormat(MediaFormat mediaFormat, VideoFormat videoFormat) {
+            checkNotNull(mediaFormat);
+            checkNotNull(videoFormat);
+            videoFormat.setMimeType(mediaFormat.getString(MediaFormat.KEY_MIME));
+            videoFormat.setWidth(mediaFormat.getInteger(MediaFormat.KEY_WIDTH));
+            videoFormat.setHeight(mediaFormat.getInteger(MediaFormat.KEY_HEIGHT));
+            mediaFormat.setInteger(MediaFormat.KEY_WIDTH, videoFormat.getWidth());
+            mediaFormat.setInteger(MediaFormat.KEY_HEIGHT, videoFormat.getHeight());
+
+            if (videoFormat.getMaxWidth() != VideoFormat.UNSET
+                    && videoFormat.getMaxHeight() != VideoFormat.UNSET) {
+                mediaFormat.setInteger(MediaFormat.KEY_MAX_WIDTH, videoFormat.getMaxWidth());
+                mediaFormat.setInteger(MediaFormat.KEY_MAX_HEIGHT, videoFormat.getMaxHeight());
+            }
+        }
+
+        /*
+         * The function returns the first video track found.
+         *
+         * @param extractor is the media extractor instantiated with a video uri.
+         * @return the index of the first video track if found, NO_TRACK_INDEX otherwise.
+         */
+        private static int getFirstVideoTrackIndex(MediaExtractor extractor) {
+            for (int i = 0; i < extractor.getTrackCount(); i++) {
+                MediaFormat trackMediaFormat = extractor.getTrackFormat(i);
+                if (trackMediaFormat.getString(MediaFormat.KEY_MIME).startsWith("video/")) {
+                    return i;
+                }
+            }
+            Log.e(TAG, "couldn't get a video track");
+            return NO_TRACK_INDEX;
+        }
+
+        /* Stores the result from SimplePlayer. */
+        public static final class PlayerResult {
+
+            public static final int UNSET = -1;
+            private final boolean configureSuccess;
+            private final boolean startSuccess;
+            private final boolean decodeSuccess;
+            private final long totalTime;
+
+            public PlayerResult(
+                    boolean configureSuccess, boolean startSuccess,
+                    boolean decodeSuccess, long totalTime) {
+                this.configureSuccess = configureSuccess;
+                this.startSuccess = startSuccess;
+                this.decodeSuccess = decodeSuccess;
+                this.totalTime = totalTime;
+            }
+
+            public PlayerResult(PlayerResult playerResult) {
+                this(playerResult.configureSuccess, playerResult.startSuccess,
+                        playerResult.decodeSuccess, playerResult.totalTime);
+            }
+
+            public PlayerResult() {
+                // Dummy PlayerResult.
+                this(false, false, false, UNSET);
+            }
+
+            public static PlayerResult failToStart() {
+                return new PlayerResult(true, false, false, UNSET);
+            }
+
+            public boolean isConfigureSuccess() {
+                return configureSuccess;
+            }
+
+            public boolean isStartSuccess() {
+                return startSuccess;
+            }
+
+            public boolean isDecodeSuccess() {
+                return decodeSuccess;
+            }
+
+            public boolean isSuccess() {
+                return isConfigureSuccess() && isStartSuccess()
+                        && isDecodeSuccess() && getTotalTime() != UNSET;
+            }
+
+            public long getTotalTime() {
+                return totalTime;
+            }
+
+            public boolean isFailureForAll() {
+                return (!isConfigureSuccess() && !isStartSuccess()
+                        && !isDecodeSuccess() && getTotalTime() == UNSET);
+            }
+        }
+
+    }
+
+    /* Utility class for collecting common test case functionality. */
+    class TestHelper {
+
+        private final Context context;
+        private final Handler handler;
+        private final Activity activity;
+
+        public TestHelper(Context context, Activity activity) {
+            this.context = checkNotNull(context);
+            this.handler = new Handler(Looper.getMainLooper());
+            this.activity = activity;
+        }
+
+        public Bitmap generateBitmapFromImageResourceId(int resourceId) {
+            return BitmapFactory.decodeStream(context.getResources().openRawResource(resourceId));
+        }
+
+        public Context getContext() {
+            return context;
+        }
+
+        public void rotateOrientation() {
+            handler.post(new Runnable() {
+                @Override
+                public void run() {
+                    final int orientation = context.getResources().getConfiguration().orientation;
+                    if (orientation == Configuration.ORIENTATION_PORTRAIT) {
+                        activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
+                    } else {
+                        activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
+                    }
+                }
+            });
+        }
+
+        public void unsetOrientation() {
+            handler.post(new Runnable() {
+                @Override
+                public void run() {
+                    activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
+                }
+            });
+        }
+
+        public void generateView(View view) {
+            RelativeLayout relativeLayout =
+                    (RelativeLayout) activity.findViewById(R.id.attach_view);
+            ViewGenerator viewGenerator = new ViewGenerator(relativeLayout, view);
+            handler.post(viewGenerator);
+        }
+
+        public void cleanUpView(View view) {
+            ViewCleaner viewCleaner = new ViewCleaner(view);
+            handler.post(viewCleaner);
+        }
+
+        public synchronized Bitmap generateBitmapFromVideoViewSnapshot(VideoViewSnapshot snapshot) {
+            handler.post(snapshot);
+            try {
+                while (!snapshot.isBitmapReady()) {
+                    Thread.sleep(100);
+                }
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+            return snapshot.getBitmap();
+        }
+
+        private class ViewGenerator implements Runnable {
+
+            private final View view;
+            private final RelativeLayout relativeLayout;
+
+            public ViewGenerator(RelativeLayout relativeLayout, View view) {
+                this.view = checkNotNull(view);
+                this.relativeLayout = checkNotNull(relativeLayout);
+            }
+
+            @Override
+            public void run() {
+                if (view.getParent() != null) {
+                    ((ViewGroup) view.getParent()).removeView(view);
+                }
+                RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
+                        VideoViewFactory.VIEW_WIDTH, VideoViewFactory.VIEW_HEIGHT);
+                view.setLayoutParams(params);
+                relativeLayout.addView(view);
+            }
+
+        }
+
+        private class ViewCleaner implements Runnable {
+
+            private final View view;
+
+            public ViewCleaner(View view) {
+                this.view = checkNotNull(view);
+            }
+
+            @Override
+            public void run() {
+                if (view.getParent() != null) {
+                    ((ViewGroup) view.getParent()).removeView(view);
+                }
+            }
+
+        }
+
+    }
+
+}
+
+/* Factory for manipulating a {@link View}. */
+abstract class VideoViewFactory {
+
+    public final long VIEW_AVAILABLE_TIMEOUT_MS = TimeUnit.SECONDS.toMillis(1);
+    public static final int VIEW_WIDTH = 480;
+    public static final int VIEW_HEIGHT = 360;
+
+    public VideoViewFactory() {}
+
+    public abstract void release();
+
+    public abstract String getName();
+
+    public abstract View createView(Context context);
+
+    public abstract void waitForViewIsAvailable();
+
+    public abstract Surface getSurface();
+
+    public abstract VideoViewSnapshot getVideoViewSnapshot();
+
+}
+
+/* Factory for building a {@link TextureView}. */
+@TargetApi(16)
+class TextureViewFactory extends VideoViewFactory implements TextureView.SurfaceTextureListener {
+
+    private final String TAG = TextureViewFactory.class.getSimpleName();
+    private final Object syncToken = new Object();
+    private TextureView textureView;
+
+    public TextureViewFactory() {}
+
+    @Override
+    public TextureView createView(Context context) {
+        textureView = DecodeAccuracyTestBase.checkNotNull(new TextureView(context));
+        textureView.setSurfaceTextureListener(this);
+        return textureView;
+    }
+
+    @Override
+    public void release() {
+        textureView = null;
+    }
+
+    @Override
+    public String getName() {
+        return "TextureView";
+    }
+
+    @Override
+    public Surface getSurface() {
+        return new Surface(textureView.getSurfaceTexture());
+    }
+
+    @Override
+    public TextureViewSnapshot getVideoViewSnapshot() {
+        return new TextureViewSnapshot(textureView);
+    }
+
+    @Override
+    public void waitForViewIsAvailable() {
+        while (!textureView.isAvailable()) {
+            synchronized (syncToken) {
+                try {
+                    syncToken.wait(VIEW_AVAILABLE_TIMEOUT_MS);
+                } catch (InterruptedException exception) {
+                    Log.e(TAG, "InterruptedException in waitForViewIsAvailable", exception);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, int height) {
+        synchronized (syncToken) {
+            syncToken.notify();
+        }
+    }
+
+    @Override
+    public void onSurfaceTextureSizeChanged(
+            SurfaceTexture surfaceTexture, int width, int height) {}
+
+    @Override
+    public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
+        return false;
+    }
+
+    @Override
+    public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {}
+
+}
+
+/**
+ * Factory for building EGL and GLES that could render to GLSurfaceView.
+ * {@link GLSurfaceView} {@link EGL10} {@link GLES20}.
+ */
+@TargetApi(16)
+class GLSurfaceViewFactory extends VideoViewFactory {
+
+    private final String TAG = GLSurfaceViewFactory.class.getSimpleName();
+    private final Object surfaceSyncToken = new Object();
+    private final Object snapshotSyncToken = new Object();
+
+    private GLSurfaceViewThread glSurfaceViewThread;
+    private boolean snapshotIsReady = false;
+
+    public GLSurfaceViewFactory() {}
+
+    @Override
+    public void release() {
+        glSurfaceViewThread.release();
+        glSurfaceViewThread = null;
+    }
+
+    @Override
+    public String getName() {
+        return "GLSurfaceView";
+    }
+
+    @Override
+    public View createView(Context context) {
+        // Do all GL rendering in the GL thread.
+        glSurfaceViewThread = new GLSurfaceViewThread();
+        glSurfaceViewThread.start();
+        // No necessary view to display, return null.
+        return null;
+    }
+
+    @Override
+    public void waitForViewIsAvailable() {
+        while (glSurfaceViewThread.getSurface() == null) {
+            synchronized (surfaceSyncToken) {
+                try {
+                    surfaceSyncToken.wait(VIEW_AVAILABLE_TIMEOUT_MS);
+                } catch (InterruptedException exception) {
+                    Log.e(TAG, "InterruptedException in waitForViewIsAvailable", exception);
+                }
+            }
+        }
+    }
+
+    @Override
+    public Surface getSurface() {
+        return glSurfaceViewThread.getSurface();
+    }
+
+    @Override
+    public VideoViewSnapshot getVideoViewSnapshot() {
+        while (!snapshotIsReady) {
+            synchronized (snapshotSyncToken) {
+                try {
+                    snapshotSyncToken.wait(VIEW_AVAILABLE_TIMEOUT_MS);
+                } catch (InterruptedException exception) {
+                    Log.e(TAG, "InterruptedException in getVideoViewSnapshot", exception);
+                }
+            }
+        }
+        return new GLSurfaceViewSnapshot(
+                glSurfaceViewThread.getByteBuffer(), VIEW_WIDTH, VIEW_HEIGHT);
+    }
+
+    /* Does all GL operations. */
+    private class GLSurfaceViewThread extends Thread
+            implements SurfaceTexture.OnFrameAvailableListener {
+
+        private static final int FLOAT_SIZE_BYTES = 4;
+        private static final int TRIANGLE_VERTICES_DATA_STRIDE_BYTES = 5 * FLOAT_SIZE_BYTES;
+        private static final int TRIANGLE_VERTICES_DATA_POS_OFFSET = 0;
+        private static final int TRIANGLE_VERTICES_DATA_UV_OFFSET = 3;
+        private FloatBuffer triangleVertices;
+
+        private final float[] triangleVerticesData = {
+                // X, Y, Z, U, V
+                -1.0f, -1.0f, 0, 0.f, 0.f,
+                1.0f, -1.0f, 0, 1.f, 0.f,
+                -1.0f,  1.0f, 0, 0.f, 1.f,
+                1.0f,  1.0f, 0, 1.f, 1.f,
+        };
+
+        private static final String VERTEX_SHADER =
+                "attribute vec4 aPosition;\n"
+                + "attribute vec4 aTextureCoord;\n"
+                + "varying vec2 vTextureCoord;\n"
+                + "void main() {\n"
+                + "    gl_Position = aPosition;\n"
+                + "    vTextureCoord = aTextureCoord.xy;\n"
+                + "}\n";
+
+        private static final String FRAGMENT_SHADER =
+                "#extension GL_OES_EGL_image_external : require\n"
+                + "precision mediump float;\n"      // highp here doesn't seem to matter
+                + "varying vec2 vTextureCoord;\n"
+                + "uniform samplerExternalOES sTexture;\n"
+                + "void main() {\n"
+                + "    gl_FragColor = texture2D(sTexture, vTextureCoord);\n"
+                + "}\n";
+
+        private int glProgram;
+        private int textureID = -1;
+        private int aPositionHandle;
+        private int aTextureHandle;
+        private EGLDisplay eglDisplay = null;
+        private EGLContext eglContext = null;
+        private EGLSurface eglSurface = null;
+        private EGL10 egl10;
+        private Surface surface = null;
+        private SurfaceTexture surfaceTexture;
+        private ByteBuffer byteBuffer;
+
+        public GLSurfaceViewThread() {}
+
+        @Override
+        public void run() {
+            Looper.prepare();
+            triangleVertices = ByteBuffer
+                    .allocateDirect(triangleVerticesData.length * FLOAT_SIZE_BYTES)
+                            .order(ByteOrder.nativeOrder()).asFloatBuffer();
+            triangleVertices.put(triangleVerticesData).position(0);
+
+            eglSetup();
+            makeCurrent();
+            eglSurfaceCreated();
+
+            surfaceTexture = new SurfaceTexture(getTextureId());
+            surfaceTexture.setOnFrameAvailableListener(this);
+            surface = new Surface(surfaceTexture);
+            synchronized (surfaceSyncToken) {
+                surfaceSyncToken.notify();
+            }
+
+            // Store pixels from surface
+            byteBuffer = ByteBuffer.allocateDirect(VIEW_WIDTH * VIEW_HEIGHT * 4);
+            byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
+            Looper.loop();
+        }
+
+        @Override
+        public void onFrameAvailable(SurfaceTexture st) {
+            checkGlError("before updateTexImage");
+            surfaceTexture.updateTexImage();
+            drawFrame();
+            saveFrame();
+            snapshotIsReady = true;
+            synchronized(snapshotSyncToken) {
+                snapshotSyncToken.notify();
+            }
+        }
+
+        /* Prepares EGL to use GLES 2.0 context and a surface that supports pbuffer. */
+        public void eglSetup() {
+            egl10 = (EGL10) EGLContext.getEGL();
+            eglDisplay = egl10.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
+            if (eglDisplay == EGL10.EGL_NO_DISPLAY) {
+                throw new RuntimeException("unable to get egl10 display");
+            }
+            int[] version = new int[2];
+            if (!egl10.eglInitialize(eglDisplay, version)) {
+                eglDisplay = null;
+                throw new RuntimeException("unable to initialize egl10");
+            }
+            // Configure EGL for pbuffer and OpenGL ES 2.0, 24-bit RGB.
+            int[] configAttribs = {
+                    EGL10.EGL_RED_SIZE, 8,
+                    EGL10.EGL_GREEN_SIZE, 8,
+                    EGL10.EGL_BLUE_SIZE, 8,
+                    EGL10.EGL_ALPHA_SIZE, 8,
+                    EGL10.EGL_RENDERABLE_TYPE, EGL14.EGL_OPENGL_ES2_BIT,
+                    EGL10.EGL_SURFACE_TYPE, EGL10.EGL_PBUFFER_BIT,
+                    EGL10.EGL_NONE
+            };
+            EGLConfig[] configs = new EGLConfig[1];
+            int[] numConfigs = new int[1];
+            if (!egl10.eglChooseConfig(
+                    eglDisplay, configAttribs, configs, configs.length, numConfigs)) {
+                throw new RuntimeException("unable to find RGB888+recordable ES2 EGL config");
+            }
+            // Configure EGL context for OpenGL ES 2.0.
+            int[] contextAttribs = {
+                    EGL14.EGL_CONTEXT_CLIENT_VERSION, 2,
+                    EGL10.EGL_NONE
+            };
+            eglContext = egl10.eglCreateContext(
+                    eglDisplay, configs[0], EGL10.EGL_NO_CONTEXT, contextAttribs);
+            checkEglError("eglCreateContext");
+            if (eglContext == null) {
+                throw new RuntimeException("null context");
+            }
+            // Create a pbuffer surface.
+            int[] surfaceAttribs = {
+                    EGL10.EGL_WIDTH, VIEW_WIDTH,
+                    EGL10.EGL_HEIGHT, VIEW_HEIGHT,
+                    EGL10.EGL_NONE
+            };
+            eglSurface = egl10.eglCreatePbufferSurface(eglDisplay, configs[0], surfaceAttribs);
+            checkEglError("eglCreatePbufferSurface");
+            if (eglSurface == null) {
+                throw new RuntimeException("surface was null");
+            }
+        }
+
+        public void release() {
+            if (eglDisplay != EGL10.EGL_NO_DISPLAY) {
+                egl10.eglMakeCurrent(eglDisplay,
+                        EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT);
+                egl10.eglDestroySurface(eglDisplay, eglSurface);
+                egl10.eglDestroyContext(eglDisplay, eglContext);
+                egl10.eglTerminate(eglDisplay);
+            }
+            eglDisplay = EGL10.EGL_NO_DISPLAY;
+            eglContext = EGL10.EGL_NO_CONTEXT;
+            eglSurface = EGL10.EGL_NO_SURFACE;
+            surface.release();
+            surfaceTexture.release();
+        }
+
+        /* Makes our EGL context and surface current. */
+        public void makeCurrent() {
+            if (!egl10.eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext)) {
+                throw new RuntimeException("eglMakeCurrent failed");
+            }
+            checkEglError("eglMakeCurrent");
+        }
+
+        /* Call this after the EGL Surface is created and made current. */
+        public void eglSurfaceCreated() {
+            glProgram = createProgram(VERTEX_SHADER, FRAGMENT_SHADER);
+            if (glProgram == 0) {
+                throw new RuntimeException("failed creating program");
+            }
+            aPositionHandle = GLES20.glGetAttribLocation(glProgram, "aPosition");
+            checkLocation(aPositionHandle, "aPosition");
+            aTextureHandle = GLES20.glGetAttribLocation(glProgram, "aTextureCoord");
+            checkLocation(aTextureHandle, "aTextureCoord");
+
+            int[] textures = new int[1];
+            GLES20.glGenTextures(1, textures, 0);
+            checkGlError("glGenTextures");
+            textureID = textures[0];
+            GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, textureID);
+            checkGlError("glBindTexture");
+
+            GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MIN_FILTER,
+                    GLES20.GL_LINEAR);
+            GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MAG_FILTER,
+                    GLES20.GL_LINEAR);
+            GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_S,
+                    GLES20.GL_CLAMP_TO_EDGE);
+            GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_T,
+                    GLES20.GL_CLAMP_TO_EDGE);
+            checkGlError("glTexParameter");
+        }
+
+        public void drawFrame() {
+            GLES20.glUseProgram(glProgram);
+            checkGlError("glUseProgram");
+            GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
+            checkGlError("glActiveTexture");
+            GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, textureID);
+            checkGlError("glBindTexture");
+
+            triangleVertices.position(TRIANGLE_VERTICES_DATA_POS_OFFSET);
+            GLES20.glVertexAttribPointer(aPositionHandle, 3, GLES20.GL_FLOAT, false,
+                    TRIANGLE_VERTICES_DATA_STRIDE_BYTES, triangleVertices);
+            checkGlError("glVertexAttribPointer aPositionHandle");
+            GLES20.glEnableVertexAttribArray(aPositionHandle);
+            checkGlError("glEnableVertexAttribArray aPositionHandle");
+
+            triangleVertices.position(TRIANGLE_VERTICES_DATA_UV_OFFSET);
+            GLES20.glVertexAttribPointer(aTextureHandle, 2, GLES20.GL_FLOAT, false,
+                    TRIANGLE_VERTICES_DATA_STRIDE_BYTES, triangleVertices);
+            checkGlError("glVertexAttribPointer aTextureHandle");
+            GLES20.glEnableVertexAttribArray(aTextureHandle);
+            checkGlError("glEnableVertexAttribArray aTextureHandle");
+
+            GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
+            checkGlError("glDrawArrays");
+            GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, 0);
+        }
+
+        /* Reads the pixels to a ByteBuffer. */
+        public void saveFrame() {
+            byteBuffer.clear();
+            GLES20.glReadPixels(0, 0, VIEW_WIDTH, VIEW_HEIGHT, GLES20.GL_RGBA,
+                    GLES20.GL_UNSIGNED_BYTE, byteBuffer);
+        }
+
+        public int getTextureId() {
+            return textureID;
+        }
+
+        public Surface getSurface() {
+            return surface;
+        }
+
+        public ByteBuffer getByteBuffer() {
+            return byteBuffer;
+        }
+
+        private int loadShader(int shaderType, String source) {
+            int shader = GLES20.glCreateShader(shaderType);
+            checkGlError("glCreateShader type=" + shaderType);
+            GLES20.glShaderSource(shader, source);
+            GLES20.glCompileShader(shader);
+            int[] compiled = new int[1];
+            GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0);
+
+            if (compiled[0] == 0) {
+                Log.e(TAG, "Could not compile shader " + shaderType + ":");
+                Log.e(TAG, " " + GLES20.glGetShaderInfoLog(shader));
+                GLES20.glDeleteShader(shader);
+                shader = 0;
+            }
+            return shader;
+        }
+
+        private int createProgram(String vertexSource, String fragmentSource) {
+            int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexSource);
+            if (vertexShader == 0) {
+                return 0;
+            }
+            int pixelShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentSource);
+            if (pixelShader == 0) {
+                return 0;
+            }
+            int program = GLES20.glCreateProgram();
+            if (program == 0) {
+                Log.e(TAG, "Could not create program");
+            }
+            GLES20.glAttachShader(program, vertexShader);
+            checkGlError("glAttachShader");
+            GLES20.glAttachShader(program, pixelShader);
+            checkGlError("glAttachShader");
+            GLES20.glLinkProgram(program);
+            int[] linkStatus = new int[1];
+            GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0);
+
+            if (linkStatus[0] != GLES20.GL_TRUE) {
+                Log.e(TAG, "Could not link program: ");
+                Log.e(TAG, GLES20.glGetProgramInfoLog(program));
+                GLES20.glDeleteProgram(program);
+                program = 0;
+            }
+            return program;
+        }
+
+        private void checkEglError(String msg) {
+            int error;
+            if ((error = egl10.eglGetError()) != EGL10.EGL_SUCCESS) {
+                throw new RuntimeException(msg + ": EGL error: 0x" + Integer.toHexString(error));
+            }
+        }
+
+        public void checkGlError(String op) {
+            int error;
+            if ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
+                Log.e(TAG, op + ": glError " + error);
+                throw new RuntimeException(op + ": glError " + error);
+            }
+        }
+
+        public void checkLocation(int location, String label) {
+            if (location < 0) {
+                throw new RuntimeException("Unable to locate '" + label + "' in program");
+            }
+        }
+    }
+
+}
+
+/* Definition of a VideoViewSnapshot and a runnable to get a bitmap from a view. */
+abstract class VideoViewSnapshot implements Runnable {
+
+    public abstract Bitmap getBitmap();
+
+    public abstract boolean isBitmapReady();
+
+}
+
+/* Runnable to get a bitmap from a texture view on the UI thread via a handler. */
+class TextureViewSnapshot extends VideoViewSnapshot {
+
+    private final TextureView tv;
+    private Bitmap bitmap = null;
+
+    public TextureViewSnapshot(TextureView tv) {
+        this.tv = DecodeAccuracyTestBase.checkNotNull(tv);
+    }
+
+    @Override
+    public synchronized void run() {
+        bitmap = tv.getBitmap();
+    }
+
+    @Override
+    public Bitmap getBitmap() {
+        return bitmap;
+    }
+
+    @Override
+    public boolean isBitmapReady() {
+        return bitmap != null;
+    }
+
+}
+
+/**
+ * Runnable to get a bitmap from a GLSurfaceView on the UI thread via a handler.
+ * Note, because of how the bitmap is captured in GLSurfaceView,
+ * this method does not have to be a runnable.
+ */
+class GLSurfaceViewSnapshot extends VideoViewSnapshot {
+
+    private Bitmap bitmap = null;
+    private ByteBuffer byteBuffer;
+    private final int width;
+    private final int height;
+    private boolean bitmapIsReady = false;
+
+    public GLSurfaceViewSnapshot(ByteBuffer byteBuffer, int width, int height) {
+        this.byteBuffer = DecodeAccuracyTestBase.checkNotNull(byteBuffer);
+        this.width = width;
+        this.height = height;
+    }
+
+    @Override
+    public synchronized void run() {
+        bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+        byteBuffer.rewind();
+        bitmap.copyPixelsFromBuffer(byteBuffer);
+        bitmapIsReady = true;
+    }
+
+    @Override
+    public Bitmap getBitmap() {
+        return bitmap;
+    }
+
+    @Override
+    public boolean isBitmapReady() {
+        return bitmapIsReady;
+    }
+
+}
+
+/* Stores information of a video. */
+class VideoFormat {
+
+    public static final int UNSET = -1;
+    public static final String MIMETYPE_UNSET = "UNSET";
+    public static final String MIMETYPE_KEY = "mimeType";
+    public static final String WIDTH_KEY = "width";
+    public static final String HEIGHT_KEY = "height";
+    public static final String FRAMERATE_KEY = "frameRate";
+
+    private final String filename;
+    private Uri uri;
+    private String mimeType = MIMETYPE_UNSET;
+    private int width = UNSET;
+    private int height = UNSET;
+    private int maxWidth = UNSET;
+    private int maxHeight = UNSET;
+
+    public VideoFormat(String filename, Uri uri) {
+        this.filename = filename;
+        this.uri = uri;
+    }
+
+    public VideoFormat(String filename) {
+        this(filename, null);
+    }
+
+    public VideoFormat(VideoFormat videoFormat) {
+        this(videoFormat.filename, videoFormat.uri);
+    }
+
+    public Uri loadUri(Context context) {
+        uri = createCacheFile(context);
+        return uri;
+    }
+
+    public Uri getUri() {
+        return uri;
+    }
+
+    public String getFilename() {
+        return filename;
+    }
+
+    public void setMimeType(String mimeType) {
+        this.mimeType = mimeType;
+    }
+
+    public String getMimeType() {
+        return mimeType;
+    }
+
+    public void setWidth(int width) {
+        this.width = width;
+    }
+
+    public void setMaxWidth(int maxWidth) {
+        this.maxWidth = maxWidth;
+    }
+
+    public int getWidth() {
+        return width;
+    }
+
+    public int getMaxWidth() {
+        return maxWidth;
+    }
+
+    public void setHeight(int height) {
+        this.height = height;
+    }
+
+    public void setMaxHeight(int maxHeight) {
+        this.maxHeight = maxHeight;
+    }
+
+    public int getHeight() {
+        return height;
+    }
+
+    public int getMaxHeight() {
+        return maxHeight;
+    }
+
+    private Uri createCacheFile(Context context) {
+        try {
+            File cacheFile = new File(context.getCacheDir(), filename);
+            if (cacheFile.createNewFile() == false) {
+                cacheFile.delete();
+                cacheFile.createNewFile();
+            }
+            InputStream inputStream = context.getAssets().open(filename);
+            FileOutputStream fileOutputStream = new FileOutputStream(cacheFile);
+            final int bufferSize = 1024 * 512;
+            byte[] buffer = new byte[bufferSize];
+
+            while (inputStream.read(buffer) != -1) {
+                fileOutputStream.write(buffer, 0, bufferSize);
+            }
+            fileOutputStream.close();
+            inputStream.close();
+            return Uri.fromFile(cacheFile);
+        } catch (IOException e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+}
+
+/**
+ * Compares bitmaps to determine if they are similar.
+ *
+ * <p>To determine greatest pixel difference we transform each pixel into the
+ * CIE L*a*b* color space. The euclidean distance formula is used to determine pixel differences.
+ */
+class BitmapCompare {
+
+    private static final int RED = 0;
+    private static final int GREEN = 1;
+    private static final int BLUE = 2;
+    private static final int X = 0;
+    private static final int Y = 1;
+    private static final int Z = 2;
+
+    private static SparseArray<double[]> pixelTransformCache = new SparseArray<>();
+
+    private BitmapCompare() {}
+
+    /**
+     * Produces greatest pixel between two bitmaps. Used to determine bitmap similarity.
+     *
+     * @param bitmap1 A bitmap to compare to bitmap2.
+     * @param bitmap2 A bitmap to compare to bitmap1.
+     * @return A {@link Difference} with an integer describing the greatest pixel difference,
+     *     using {@link Integer#MAX_VALUE} for completely different bitmaps, and an optional
+     *     {@link Pair<Integer, Integer>} of the (col, row) pixel coordinate
+     *     where it was first found.
+     */
+    @TargetApi(12)
+    public static Difference computeDifference(Bitmap bitmap1, Bitmap bitmap2) {
+        if ((bitmap1 == null || bitmap2 == null) && bitmap1 != bitmap2) {
+            return new Difference(Integer.MAX_VALUE);
+        }
+        if (bitmap1 == bitmap2 || bitmap1.sameAs(bitmap2)) {
+            return new Difference(0);
+        }
+        if (bitmap1.getHeight() != bitmap2.getHeight() || bitmap1.getWidth() != bitmap2.getWidth()) {
+            return new Difference(Integer.MAX_VALUE);
+        }
+        // Convert all pixels to CIE L*a*b* color space so we can do a direct color comparison using
+        // euclidean distance formula.
+        final double[][] pixels1 = convertRgbToCieLab(bitmap1);
+        final double[][] pixels2 = convertRgbToCieLab(bitmap2);
+        int greatestDifference = 0;
+        int greatestDifferenceIndex = -1;
+        for (int i = 0; i < pixels1.length; i++) {
+            final int difference = euclideanDistance(pixels1[i], pixels2[i]);
+            if (difference > greatestDifference) {
+                greatestDifference = difference;
+                greatestDifferenceIndex = i;
+            }
+        }
+        return new Difference(greatestDifference, Pair.create(
+            greatestDifferenceIndex % bitmap1.getWidth(),
+            greatestDifferenceIndex / bitmap1.getHeight()));
+    }
+
+    private static double[][] convertRgbToCieLab(Bitmap bitmap) {
+        final double[][] result = new double[bitmap.getHeight() * bitmap.getWidth()][3];
+        final int pixels[] = new int[bitmap.getHeight() * bitmap.getWidth()];
+        bitmap.getPixels(pixels, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight());
+        for (int i = 0; i < pixels.length; i++) {
+            final double[] transformedColor = pixelTransformCache.get(pixels[i]);
+            if (transformedColor != null) {
+                result[i] = transformedColor;
+            } else {
+                result[i] = convertXyzToCieLab(convertRgbToXyz(pixels[i]));
+                pixelTransformCache.put(pixels[i], result[i]);
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Conversion from RGB to XYZ based algorithm as defined by:
+     * http://www.easyrgb.com/index.php?X=MATH&H=02#text2
+     *
+     * <p><pre>{@code
+     *   var_R = ( R / 255 )        //R from 0 to 255
+     *   var_G = ( G / 255 )        //G from 0 to 255
+     *   var_B = ( B / 255 )        //B from 0 to 255
+     *
+     *   if ( var_R > 0.04045 ) var_R = ( ( var_R + 0.055 ) / 1.055 ) ^ 2.4
+     *   else                   var_R = var_R / 12.92
+     *   if ( var_G > 0.04045 ) var_G = ( ( var_G + 0.055 ) / 1.055 ) ^ 2.4
+     *   else                   var_G = var_G / 12.92
+     *   if ( var_B > 0.04045 ) var_B = ( ( var_B + 0.055 ) / 1.055 ) ^ 2.4
+     *   else                   var_B = var_B / 12.92
+     *
+     *   var_R = var_R * 100
+     *   var_G = var_G * 100
+     *   var_B = var_B * 100
+     *
+     *   // Observer. = 2°, Illuminant = D65
+     *   X = var_R * 0.4124 + var_G * 0.3576 + var_B * 0.1805
+     *   Y = var_R * 0.2126 + var_G * 0.7152 + var_B * 0.0722
+     *   Z = var_R * 0.0193 + var_G * 0.1192 + var_B * 0.9505
+     * }</pre>
+     *
+     * @param rgbColor A packed int made up of 4 bytes: alpha, red, green, blue.
+     * @return An array of doubles where each value is a component of the XYZ color space.
+     */
+    private static double[] convertRgbToXyz(int rgbColor) {
+        final double[] comp = {Color.red(rgbColor), Color.green(rgbColor), Color.blue(rgbColor)};
+
+        for (int i = 0; i < comp.length; i++) {
+            comp[i] /= 255.0;
+            if (comp[i] > 0.04045) {
+                comp[i] = Math.pow((comp[i] + 0.055) / 1.055, 2.4);
+            } else {
+                comp[i] /= 12.92;
+            }
+            comp[i] *= 100;
+        }
+        final double x = (comp[RED] * 0.4124) + (comp[GREEN] * 0.3576) + (comp[BLUE] * 0.1805);
+        final double y = (comp[RED] * 0.2126) + (comp[GREEN] * 0.7152) + (comp[BLUE] * 0.0722);
+        final double z = (comp[RED] * 0.0193) + (comp[GREEN] * 0.1192) + (comp[BLUE] * 0.9505);
+        return new double[] {x, y, z};
+    }
+
+    /**
+     * Conversion from XYZ to CIE-L*a*b* based algorithm as defined by:
+     * http://www.easyrgb.com/index.php?X=MATH&H=07#text7
+     *
+     * <p><pre>
+     * {@code
+     *   var_X = X / ref_X          //ref_X =  95.047   Observer= 2°, Illuminant= D65
+     *   var_Y = Y / ref_Y          //ref_Y = 100.000
+     *   var_Z = Z / ref_Z          //ref_Z = 108.883
+     *
+     *   if ( var_X > 0.008856 ) var_X = var_X ^ ( 1/3 )
+     *   else                    var_X = ( 7.787 * var_X ) + ( 16 / 116 )
+     *   if ( var_Y > 0.008856 ) var_Y = var_Y ^ ( 1/3 )
+     *   else                    var_Y = ( 7.787 * var_Y ) + ( 16 / 116 )
+     *   if ( var_Z > 0.008856 ) var_Z = var_Z ^ ( 1/3 )
+     *   else                    var_Z = ( 7.787 * var_Z ) + ( 16 / 116 )
+     *
+     *   CIE-L* = ( 116 * var_Y ) - 16
+     *   CIE-a* = 500 * ( var_X - var_Y )
+     *   CIE-b* = 200 * ( var_Y - var_Z )
+     * }
+     * </pre>
+     *
+     * @param comp An array of doubles where each value is a component of the XYZ color space.
+     * @return An array of doubles where each value is a component of the CIE-L*a*b* color space.
+     */
+    private static double[] convertXyzToCieLab(double[] comp) {
+        comp[X] /= 95.047;
+        comp[Y] /= 100.0;
+        comp[Z] /= 108.883;
+
+        for (int i = 0; i < comp.length; i++) {
+            if (comp[i] > 0.008856) {
+                comp[i] = Math.pow(comp[i], (1.0 / 3.0));
+            } else {
+                comp[i] = (7.787 * comp[i]) + (16.0 / 116.0);
+            }
+        }
+        final double l = (116 * comp[Y]) - 16;
+        final double a = 500 * (comp[X] - comp[Y]);
+        final double b = 200 * (comp[Y] - comp[Z]);
+        return new double[] {l, a, b};
+    }
+
+    private static int euclideanDistance(double[] p1, double[] p2) {
+        if (p1.length != p2.length) {
+            return Integer.MAX_VALUE;
+        }
+        double result = 0;
+        for (int i = 0; i < p1.length; i++) {
+            result += Math.pow(p1[i] - p2[i], 2);
+        }
+        return (int) Math.round(Math.sqrt(result));
+    }
+
+    /* Describes the difference between two {@link Bitmap} instances. */
+    public static final class Difference {
+
+        public final int greatestPixelDifference;
+        public final Pair<Integer, Integer> greatestPixelDifferenceCoordinates;
+
+        private Difference(int greatestPixelDifference) {
+            this(greatestPixelDifference, null);
+        }
+
+        private Difference(
+                int greatestPixelDifference,
+                Pair<Integer, Integer> greatestPixelDifferenceCoordinates) {
+            this.greatestPixelDifference = greatestPixelDifference;
+            this.greatestPixelDifferenceCoordinates = greatestPixelDifferenceCoordinates;
+        }
+    }
+
+}
+
+/* Wrapper for MIME types. */
+final class MimeTypes {
+
+    private MimeTypes() {}
+
+    public static final String VIDEO_VP9 = "video/x-vnd.on2.vp9";
+    public static final String VIDEO_H264 = "video/avc";
+
+    public static boolean isVideo(String mimeType) {
+        return mimeType.startsWith("video");
+    }
+
+}
diff --git a/tests/tests/media/src/android/media/cts/DecoderTest.java b/tests/tests/media/src/android/media/cts/DecoderTest.java
index 2f369a5..79bf8c7 100755
--- a/tests/tests/media/src/android/media/cts/DecoderTest.java
+++ b/tests/tests/media/src/android/media/cts/DecoderTest.java
@@ -16,7 +16,7 @@
 
 package android.media.cts;
 
-import com.android.cts.media.R;
+import android.media.cts.R;
 
 import android.content.Context;
 import android.content.pm.PackageManager;
@@ -185,6 +185,14 @@
         testTimeStampOrdering(R.raw.sinesweeptsaac);
     }
 
+    public void testDecodeVorbis() throws Exception {
+        testTimeStampOrdering(R.raw.sinesweepvorbis);
+    }
+
+    public void testDecodeOpus() throws Exception {
+        testTimeStampOrdering(R.raw.sinesweepopus);
+    }
+
     public void testDecode51M4a() throws Exception {
         decodeToMemory(R.raw.sinesweep51m4a, RESET_MODE_NONE, CONFIG_MODE_NONE, -1, null);
     }
@@ -515,6 +523,443 @@
         }
     }
 
+    /**
+     * Verify correct decoding of MPEG-4 AAC-LC mono and stereo streams
+     */
+    public void testDecodeAacLcM4a() throws Exception {
+        // mono
+        decodeNtest(R.raw.sinesweep1_1ch_8khz_aot2_mp4, 40.f);
+        decodeNtest(R.raw.sinesweep1_1ch_11khz_aot2_mp4, 40.f);
+        decodeNtest(R.raw.sinesweep1_1ch_12khz_aot2_mp4, 40.f);
+        decodeNtest(R.raw.sinesweep1_1ch_16khz_aot2_mp4, 40.f);
+        decodeNtest(R.raw.sinesweep1_1ch_22khz_aot2_mp4, 40.f);
+        decodeNtest(R.raw.sinesweep1_1ch_24khz_aot2_mp4, 40.f);
+        decodeNtest(R.raw.sinesweep1_1ch_32khz_aot2_mp4, 40.f);
+        decodeNtest(R.raw.sinesweep1_1ch_44khz_aot2_mp4, 40.f);
+        decodeNtest(R.raw.sinesweep1_1ch_48khz_aot2_mp4, 40.f);
+        // stereo
+        decodeNtest(R.raw.sinesweep_2ch_8khz_aot2_mp4, 40.f);
+        decodeNtest(R.raw.sinesweep_2ch_11khz_aot2_mp4, 40.f);
+        decodeNtest(R.raw.sinesweep_2ch_12khz_aot2_mp4, 40.f);
+        decodeNtest(R.raw.sinesweep_2ch_16khz_aot2_mp4, 40.f);
+        decodeNtest(R.raw.sinesweep_2ch_22khz_aot2_mp4, 40.f);
+        decodeNtest(R.raw.sinesweep_2ch_24khz_aot2_mp4, 40.f);
+        decodeNtest(R.raw.sinesweep_2ch_32khz_aot2_mp4, 40.f);
+        decodeNtest(R.raw.sinesweep_2ch_44khz_aot2_mp4, 40.f);
+        decodeNtest(R.raw.sinesweep_2ch_48khz_aot2_mp4, 40.f);
+    }
+
+    /**
+     * Verify correct decoding of MPEG-4 AAC-LC 5.0 and 5.1 channel streams
+     */
+    public void testDecodeAacLcMcM4a() throws Exception {
+        AudioParameter decParams = new AudioParameter();
+        short[] decSamples = decodeToMemory(decParams, R.raw.noise_6ch_48khz_aot2_mp4,
+                RESET_MODE_NONE, CONFIG_MODE_NONE, -1, null);
+        checkEnergy(decSamples, decParams, 6);
+        decParams.reset();
+
+        decSamples = decodeToMemory(decParams, R.raw.noise_5ch_44khz_aot2_mp4,
+                RESET_MODE_NONE, CONFIG_MODE_NONE, -1, null);
+        checkEnergy(decSamples, decParams, 5);
+        decParams.reset();
+    }
+
+    /**
+     * Verify correct decoding of MPEG-4 HE-AAC mono and stereo streams
+     */
+    public void testDecodeHeAacM4a() throws Exception {
+        AudioParameter decParams = new AudioParameter();
+        // mono
+        short[] decSamples = decodeToMemory(decParams, R.raw.noise_1ch_24khz_aot5_dr_sbr_sig1_mp4,
+                RESET_MODE_NONE, CONFIG_MODE_NONE, -1, null);
+        checkEnergy(decSamples, decParams, 1);
+        decParams.reset();
+
+        decSamples = decodeToMemory(decParams, R.raw.noise_1ch_24khz_aot5_ds_sbr_sig1_mp4,
+                RESET_MODE_NONE, CONFIG_MODE_NONE, -1, null);
+        checkEnergy(decSamples, decParams, 1);
+        decParams.reset();
+
+        decSamples = decodeToMemory(decParams, R.raw.noise_1ch_32khz_aot5_dr_sbr_sig2_mp4,
+                RESET_MODE_NONE, CONFIG_MODE_NONE, -1, null);
+        checkEnergy(decSamples, decParams, 1);
+        decParams.reset();
+
+        decSamples = decodeToMemory(decParams, R.raw.noise_1ch_44khz_aot5_dr_sbr_sig0_mp4,
+                RESET_MODE_NONE, CONFIG_MODE_NONE, -1, null);
+        checkEnergy(decSamples, decParams, 1);
+        decParams.reset();
+
+        decSamples = decodeToMemory(decParams, R.raw.noise_1ch_44khz_aot5_ds_sbr_sig2_mp4,
+                RESET_MODE_NONE, CONFIG_MODE_NONE, -1, null);
+        checkEnergy(decSamples, decParams, 1);
+        decParams.reset();
+
+        // stereo
+        decSamples = decodeToMemory(decParams, R.raw.noise_2ch_24khz_aot5_dr_sbr_sig2_mp4,
+                RESET_MODE_NONE, CONFIG_MODE_NONE, -1, null);
+        checkEnergy(decSamples, decParams, 2);
+        decParams.reset();
+
+        decSamples = decodeToMemory(decParams, R.raw.noise_2ch_32khz_aot5_ds_sbr_sig2_mp4,
+                RESET_MODE_NONE, CONFIG_MODE_NONE, -1, null);
+        checkEnergy(decSamples, decParams, 2);
+        decParams.reset();
+
+        decSamples = decodeToMemory(decParams, R.raw.noise_2ch_48khz_aot5_dr_sbr_sig1_mp4,
+                RESET_MODE_NONE, CONFIG_MODE_NONE, -1, null);
+        checkEnergy(decSamples, decParams, 2);
+        decParams.reset();
+
+        decSamples = decodeToMemory(decParams, R.raw.noise_2ch_48khz_aot5_ds_sbr_sig1_mp4,
+                RESET_MODE_NONE, CONFIG_MODE_NONE, -1, null);
+        checkEnergy(decSamples, decParams, 2);
+        decParams.reset();
+    }
+
+    /**
+     * Verify correct decoding of MPEG-4 HE-AAC 5.0 and 5.1 channel streams
+     */
+    public void testDecodeHeAacMcM4a() throws Exception {
+        AudioParameter decParams = new AudioParameter();
+        short[] decSamples = decodeToMemory(decParams, R.raw.noise_5ch_48khz_aot5_dr_sbr_sig1_mp4,
+                RESET_MODE_NONE, CONFIG_MODE_NONE, -1, null);
+        checkEnergy(decSamples, decParams, 5);
+        decParams.reset();
+
+        decSamples = decodeToMemory(decParams, R.raw.noise_6ch_44khz_aot5_dr_sbr_sig2_mp4,
+                RESET_MODE_NONE, CONFIG_MODE_NONE, -1, null);
+        checkEnergy(decSamples, decParams, 6);
+        decParams.reset();
+    }
+
+    /**
+     * Verify correct decoding of MPEG-4 HE-AAC v2 stereo streams
+     */
+    public void testDecodeHeAacV2M4a() throws Exception {
+        AudioParameter decParams = new AudioParameter();
+        short[] decSamples = decodeToMemory(decParams, R.raw.noise_2ch_24khz_aot29_dr_sbr_sig0_mp4,
+                RESET_MODE_NONE, CONFIG_MODE_NONE, -1, null);
+        checkEnergy(decSamples, decParams, 2);
+
+        decSamples = decodeToMemory(decParams, R.raw.noise_2ch_44khz_aot29_dr_sbr_sig1_mp4,
+                RESET_MODE_NONE, CONFIG_MODE_NONE, -1, null);
+        checkEnergy(decSamples, decParams, 2);
+
+        decSamples = decodeToMemory(decParams, R.raw.noise_2ch_48khz_aot29_dr_sbr_sig2_mp4,
+                RESET_MODE_NONE, CONFIG_MODE_NONE, -1, null);
+        checkEnergy(decSamples, decParams, 2);
+    }
+
+    /**
+     * Verify correct decoding of MPEG-4 AAC-ELD mono and stereo streams
+     */
+    public void testDecodeAacEldM4a() throws Exception {
+        // mono
+        decodeNtest(R.raw.sinesweep1_1ch_16khz_aot39_fl480_mp4, 40.f);
+        decodeNtest(R.raw.sinesweep1_1ch_22khz_aot39_fl512_mp4, 40.f);
+        decodeNtest(R.raw.sinesweep1_1ch_24khz_aot39_fl480_mp4, 40.f);
+        decodeNtest(R.raw.sinesweep1_1ch_32khz_aot39_fl512_mp4, 40.f);
+        decodeNtest(R.raw.sinesweep1_1ch_44khz_aot39_fl480_mp4, 40.f);
+        decodeNtest(R.raw.sinesweep1_1ch_48khz_aot39_fl512_mp4, 40.f);
+
+        // stereo
+        decodeNtest(R.raw.sinesweep_2ch_16khz_aot39_fl512_mp4, 40.f);
+        decodeNtest(R.raw.sinesweep_2ch_22khz_aot39_fl480_mp4, 40.f);
+        decodeNtest(R.raw.sinesweep_2ch_24khz_aot39_fl512_mp4, 40.f);
+        decodeNtest(R.raw.sinesweep_2ch_32khz_aot39_fl480_mp4, 40.f);
+        decodeNtest(R.raw.sinesweep_2ch_44khz_aot39_fl512_mp4, 40.f);
+        decodeNtest(R.raw.sinesweep_2ch_48khz_aot39_fl480_mp4, 40.f);
+
+        AudioParameter decParams = new AudioParameter();
+        // mono
+        short[] decSamples = decodeToMemory(decParams, R.raw.noise_1ch_16khz_aot39_ds_sbr_fl512_mp4,
+                RESET_MODE_NONE, CONFIG_MODE_NONE, -1, null);
+        checkEnergy(decSamples, decParams, 1);
+        decParams.reset();
+
+        decSamples = decodeToMemory(decParams, R.raw.noise_1ch_24khz_aot39_ds_sbr_fl512_mp4,
+                RESET_MODE_NONE, CONFIG_MODE_NONE, -1, null);
+        checkEnergy(decSamples, decParams, 1);
+        decParams.reset();
+
+        decSamples = decodeToMemory(decParams, R.raw.noise_1ch_32khz_aot39_dr_sbr_fl480_mp4,
+                RESET_MODE_NONE, CONFIG_MODE_NONE, -1, null);
+        checkEnergy(decSamples, decParams, 1);
+        decParams.reset();
+
+        decSamples = decodeToMemory(decParams, R.raw.noise_1ch_44khz_aot39_ds_sbr_fl512_mp4,
+                RESET_MODE_NONE, CONFIG_MODE_NONE, -1, null);
+        checkEnergy(decSamples, decParams, 1);
+        decParams.reset();
+
+        decSamples = decodeToMemory(decParams, R.raw.noise_1ch_48khz_aot39_dr_sbr_fl480_mp4,
+                RESET_MODE_NONE, CONFIG_MODE_NONE, -1, null);
+        checkEnergy(decSamples, decParams, 1);
+        decParams.reset();
+
+        // stereo
+        decSamples = decodeToMemory(decParams, R.raw.noise_2ch_22khz_aot39_ds_sbr_fl512_mp4,
+                RESET_MODE_NONE, CONFIG_MODE_NONE, -1, null);
+        checkEnergy(decSamples, decParams, 2);
+        decParams.reset();
+
+        decSamples = decodeToMemory(decParams, R.raw.noise_2ch_32khz_aot39_ds_sbr_fl512_mp4,
+                RESET_MODE_NONE, CONFIG_MODE_NONE, -1, null);
+        checkEnergy(decSamples, decParams, 2);
+        decParams.reset();
+
+        decSamples = decodeToMemory(decParams, R.raw.noise_2ch_44khz_aot39_dr_sbr_fl480_mp4,
+                RESET_MODE_NONE, CONFIG_MODE_NONE, -1, null);
+        checkEnergy(decSamples, decParams, 2);
+        decParams.reset();
+
+        decSamples = decodeToMemory(decParams, R.raw.noise_2ch_48khz_aot39_ds_sbr_fl512_mp4,
+                RESET_MODE_NONE, CONFIG_MODE_NONE, -1, null);
+        checkEnergy(decSamples, decParams, 2);
+        decParams.reset();
+    }
+
+    /**
+     * Perform a segmented energy analysis on given audio signal samples and run several tests on
+     * the energy values.
+     *
+     * The main purpose is to verify whether an AAC decoder implementation applies Spectral Band
+     * Replication (SBR) and Parametric Stereo (PS) correctly. Both tools are inherent parts to the
+     * MPEG-4 HE-AAC and HE-AAC v2 audio codecs.
+     *
+     * In addition, this test can verify the correct decoding of multi-channel (e.g. 5.1 channel)
+     * streams or the creation of a mixdown signal.
+     *
+     * Note: This test procedure is not an MPEG Conformance Test and can not serve as a replacement.
+     *
+     * @param decSamples the decoded audio samples to be tested
+     * @param decParams the audio parameters of the given audio samples (decSamples)
+     * @param encNch the encoded number of audio channels (number of channels of the original
+     *               input)
+     * @throws RuntimeException
+     */
+    private void checkEnergy(short[] decSamples, AudioParameter decParams, int encNch)
+            throws RuntimeException
+    {
+        String localTag = TAG + "#checkEnergy";
+
+        final int nSegPerBlk = 4;                          // the number of segments per block
+        final int nCh = decParams.getNumChannels();        // the number of input channels
+        final int nBlkSmp = decParams.getSamplingRate();   // length of one (LB/HB) block [samples]
+        final int nSegSmp = nBlkSmp / nSegPerBlk;          // length of one segment [samples]
+        final int smplPerChan = decSamples.length / nCh;   // actual # samples per channel (total)
+
+        final int nSegSmpTot = nSegSmp * nCh;              // actual # samples per segment (all ch)
+        final int nSegChOffst = 2 * nSegPerBlk;            // signal offset between chans [segments]
+        final int procNch = Math.min(nCh, encNch);         // the number of channels to be analyzed
+        if (encNch > 4) {
+            assertTrue(String.format("multichannel content (%dch) was downmixed (%dch)",
+                    encNch, nCh), procNch > 4);
+        }
+        assertTrue(String.format("got less channels(%d) than encoded (%d)", nCh, encNch),
+                nCh >= encNch);
+
+        final int encEffNch = (encNch > 5) ? encNch-1 : encNch;  // all original configs with more
+                                                           // ... than five channel have an LFE */
+        final int expSmplPerChan = Math.max(encEffNch, 2) * nSegChOffst * nSegSmp;
+        final boolean isDmx = nCh < encNch;                // flag telling that input is dmx signal
+        int effProcNch = procNch;                          // the num analyzed channels with signal
+
+        assertTrue("got less input samples than expected", smplPerChan >= expSmplPerChan);
+
+        // get the signal offset by counting zero samples at the very beginning (over all channels)
+        final int zeroSigThresh = 1;                     // sample value threshold for signal search
+        int signalStart = smplPerChan;                   // receives the number of samples that
+                                                         // ... are in front of the actual signal
+        int noiseStart = signalStart;                    // receives the number of null samples
+                                                         // ... (per chan) at the very beginning
+        for (int smpl = 0; smpl < decSamples.length; smpl++) {
+            int value = Math.abs(decSamples[smpl]);
+            if (value > 0 && noiseStart == signalStart) {
+                noiseStart = smpl / nCh;                   // store start of prepended noise
+            }                                              // ... (can be same as signalStart)
+            if (value > zeroSigThresh) {
+                signalStart = smpl / nCh;                  // store signal start offset [samples]
+                break;
+            }
+        }
+        signalStart = (signalStart > noiseStart+1) ? signalStart : noiseStart;
+        assertTrue ("no signal found in any channel!", signalStart < smplPerChan);
+        final int totSeg = (smplPerChan-signalStart) / nSegSmp; // max num seg that fit into signal
+        final int totSmp = nSegSmp * totSeg;               // max num relevant samples (per channel)
+        assertTrue("no segments left to test after signal search", totSeg > 0);
+
+        // get the energies and the channel offsets by searching for the first segment above the
+        //  energy threshold
+        final double zeroMaxNrgRatio = 0.001f;             // ratio of zeroNrgThresh to the max nrg
+        double zeroNrgThresh = nSegSmp * nSegSmp;          // threshold to classify segment energies
+        double totMaxNrg = 0.0f;                           // will store the max seg nrg over all ch
+        double[][] nrg = new double[procNch][totSeg];      // array receiving the segment energies
+        int[] offset = new int[procNch];                   // array for channel offsets
+        boolean[] sigSeg = new boolean[totSeg];            // array receiving the segment ...
+                                                           // ... energy status over all channels
+        for (int ch = 0; ch < procNch; ch++) {
+            offset[ch] = -1;
+            for (int seg = 0; seg < totSeg; seg++) {
+                final int smpStart = (signalStart * nCh) + (seg * nSegSmpTot) + ch;
+                final int smpStop = smpStart + nSegSmpTot;
+                for (int smpl = smpStart; smpl < smpStop; smpl += nCh) {
+                    nrg[ch][seg] += decSamples[smpl] * decSamples[smpl];  // accumulate segment nrg
+                }
+                if (nrg[ch][seg] > zeroNrgThresh && offset[ch] < 0) { // store 1st segment (index)
+                    offset[ch] = seg / nSegChOffst;        // ... per ch which has energy above the
+                }                                          // ... threshold to get the ch offsets
+                if (nrg[ch][seg] > totMaxNrg) {
+                    totMaxNrg = nrg[ch][seg];              // store the max segment nrg over all ch
+                }
+                sigSeg[seg] |= nrg[ch][seg] > zeroNrgThresh;  // store whether the channel has
+                                                           // ... energy in this segment
+            }
+            if (offset[ch] < 0) {                          // if one channel has no signal it is
+                effProcNch -= 1;                           // ... most probably the LFE
+                offset[ch] = effProcNch;                   // the LFE is no effective channel
+            }
+            if (ch == 0) {                                 // recalculate the zero signal threshold
+                zeroNrgThresh = zeroMaxNrgRatio * totMaxNrg; // ... based on the 1st channels max
+            }                                              // ... energy for all subsequent checks
+        }
+        // check the channel mapping
+        assertTrue("more than one LFE detected", effProcNch >= procNch - 1);
+        assertTrue(String.format("less samples decoded than expected: %d < %d",
+                decSamples.length-(signalStart * nCh), totSmp * effProcNch),
+                decSamples.length-(signalStart * nCh) >= totSmp * effProcNch);
+        if (procNch >= 5) {                                // for multi-channel signals the only
+            final int[] frontChMap1 = {2, 0, 1};           // valid front channel orders are L, R, C
+            final int[] frontChMap2 = {0, 1, 2};           // or C, L, R (L=left, R=right, C=center)
+            if ( !(Arrays.equals(Arrays.copyOfRange(offset, 0, 3), frontChMap1)
+                    || Arrays.equals(Arrays.copyOfRange(offset, 0, 3), frontChMap2)) ) {
+                fail("wrong front channel mapping");
+            }
+        }
+        // check whether every channel occurs exactly once
+        int[] chMap = new int[nCh];                        // mapping array to sort channels
+        for (int ch = 0; ch < effProcNch; ch++) {
+            int occurred = 0;
+            for (int idx = 0; idx < procNch; idx++) {
+                if (offset[idx] == ch) {
+                    occurred += 1;
+                    chMap[ch] = idx;                       // create mapping table to address chans
+                }                                          // ... from front to back
+            }                                              // the LFE must be last
+            assertTrue(String.format("channel %d occurs %d times in the mapping", ch, occurred),
+                    occurred == 1);
+        }
+
+        // go over all segment energies in all channels and check them
+        final double nrgRatioThresh = 0.50f;               // threshold to classify energy ratios
+        double refMinNrg = zeroNrgThresh;                  // reference min energy for the 1st ch;
+                                                           // others will be compared against 1st
+        for (int ch = 0; ch < procNch; ch++) {
+            int idx = chMap[ch];                           // resolve channel mapping
+            final int ofst = offset[idx] * nSegChOffst;    // signal offset [segments]
+            if (ch < effProcNch && ofst < totSeg) {
+                int nrgSegEnd;                             // the last segment that has energy
+                int nrgSeg;                                // the number of segments with energy
+                if ((encNch <= 2) && (ch == 0)) {          // the first channel of a mono or ...
+                    nrgSeg = totSeg;                       // stereo signal has full signal ...
+                } else {                                   // all others have one LB + one HB block
+                    nrgSeg = Math.min(totSeg, (2 * nSegPerBlk) + ofst) - ofst;
+                }
+                nrgSegEnd = ofst + nrgSeg;
+                // find min and max energy of all segments that should have signal
+                double minNrg = nrg[idx][ofst];            // channels minimum segment energy
+                double maxNrg = nrg[idx][ofst];            // channels maximum segment energy
+                for (int seg = ofst+1; seg < nrgSegEnd; seg++) {          // values of 1st segment
+                    if (nrg[idx][seg] < minNrg) minNrg = nrg[idx][seg];   // ... already assigned
+                    if (nrg[idx][seg] > maxNrg) maxNrg = nrg[idx][seg];
+                }
+                assertTrue(String.format("max energy of channel %d is zero", ch),
+                        maxNrg > 0.0f);
+                assertTrue(String.format("channel %d has not enough energy", ch),
+                        minNrg >= refMinNrg);              // check the channels minimum energy
+                if (ch == 0) {                             // use 85% of 1st channels min energy as
+                    refMinNrg = minNrg * 0.85f;            // ... reference the other chs must meet
+                } else if (isDmx && (ch == 1)) {           // in case of mixdown signal the energy
+                    refMinNrg *= 0.50f;                    // ... can be lower depending on the
+                }                                          // ... downmix equation
+                // calculate and check the energy ratio
+                final double nrgRatio = minNrg / maxNrg;
+                assertTrue(String.format("energy ratio of channel %d below threshold", ch),
+                        nrgRatio >= nrgRatioThresh);
+                if (!isDmx) {
+                    if (nrgSegEnd < totSeg) {
+                        // consider that some noise can extend into the subsequent segment
+                        // allow this to be at max 20% of the channels minimum energy
+                        assertTrue(String.format("min energy after noise above threshold (%.2f)",
+                                nrg[idx][nrgSegEnd]),
+                                nrg[idx][nrgSegEnd] < minNrg * 0.20f);
+                        nrgSegEnd += 1;
+                    }
+                } else {                                   // ignore all subsequent segments
+                    nrgSegEnd = totSeg;                    // ... in case of a mixdown signal
+                }
+                // zero-out the verified energies to simplify the subsequent check
+                for (int seg = ofst; seg < nrgSegEnd; seg++) nrg[idx][seg] = 0.0f;
+            }
+            // check zero signal parts
+            for (int seg = 0; seg < totSeg; seg++) {
+                assertTrue(String.format("segment %d in channel %d has signal where should " +
+                        "be none (%.2f)", seg, ch, nrg[idx][seg]), nrg[idx][seg] < zeroNrgThresh);
+            }
+        }
+        // test whether each segment has energy in at least one channel
+        for (int seg = 0; seg < totSeg; seg++) {
+            assertTrue(String.format("no channel has energy in segment %d", seg), sigSeg[seg]);
+        }
+    }
+
+    /**
+     * Calculate the RMS of the difference signal between a given signal and the reference samples
+     * located in mMasterBuffer.
+     * @param signal the decoded samples to test
+     * @return RMS of error signal
+     * @throws RuntimeException
+     */
+    private double getRmsError(short[] signal) throws RuntimeException {
+        long totalErrorSquared = 0;
+        int stride = mMasterBuffer.length / signal.length;
+        assertEquals("wrong data size", mMasterBuffer.length, signal.length * stride);
+
+        for (int i = 0; i < signal.length; i++) {
+            short sample = signal[i];
+            short mastersample = mMasterBuffer[i * stride];
+            int d = sample - mastersample;
+            totalErrorSquared += d * d;
+        }
+        long avgErrorSquared = (totalErrorSquared / signal.length);
+        return Math.sqrt(avgErrorSquared);
+    }
+
+    /**
+     * Decode a given input stream and compare the output against the reference signal. The RMS of
+     * the error signal must be below the given threshold (maxerror).
+     * Important note about the test signals: this method expects test signals to have been
+     *   "stretched" relative to the reference signal. The reference, sinesweepraw, is 3s long at
+     *   44100Hz. For instance for comparing this reference to a test signal at 8000Hz, the test
+     *   signal needs to be 44100/8000 = 5.5125 times longer, containing frequencies 5.5125
+     *   times lower than the reference.
+     * @param testinput the file to decode
+     * @param maxerror  the maximum allowed root mean squared error
+     * @throws Exception
+     */
+    private void decodeNtest(int testinput, float maxerror) throws Exception {
+        String localTag = TAG + "#decodeNtest";
+
+        AudioParameter decParams = new AudioParameter();
+        short[] decoded = decodeToMemory(decParams, testinput, RESET_MODE_NONE, CONFIG_MODE_NONE,
+                -1, null);
+        double rmse = getRmsError(decoded);
+
+        assertTrue("decoding error too big: " + rmse, rmse <= maxerror);
+        Log.v(localTag, String.format("rms = %f (max = %f)", rmse, maxerror));
+    }
 
     private void monoTest(int res, int expectedLength) throws Exception {
         short [] mono = decodeToMemory(res, RESET_MODE_NONE, CONFIG_MODE_NONE, -1, null);
@@ -556,17 +1001,8 @@
 
         assertEquals("wrong data size", mMasterBuffer.length, decoded.length);
 
-        long totalErrorSquared = 0;
+        double rmse = getRmsError(decoded);
 
-        for (int i = 0; i < decoded.length; i++) {
-            short sample = decoded[i];
-            short mastersample = mMasterBuffer[i];
-            int d = sample - mastersample;
-            totalErrorSquared += d * d;
-        }
-
-        long avgErrorSquared = (totalErrorSquared / decoded.length);
-        double rmse = Math.sqrt(avgErrorSquared);
         assertTrue("decoding error too big: " + rmse, rmse <= maxerror);
 
         int[] resetModes = new int[] { RESET_MODE_NONE, RESET_MODE_RECONFIGURE,
@@ -612,9 +1048,49 @@
         }
     }
 
+    // Class handling all audio parameters relevant for testing
+    private class AudioParameter {
+
+        public AudioParameter() {
+            this.reset();
+        }
+
+        public void reset() {
+            this.numChannels = 0;
+            this.samplingRate = 0;
+        }
+
+        public int getNumChannels() {
+            return this.numChannels;
+        }
+
+        public int getSamplingRate() {
+            return this.samplingRate;
+        }
+
+        public void setNumChannels(int numChannels) {
+            this.numChannels = numChannels;
+        }
+
+        public void setSamplingRate(int samplingRate) {
+            this.samplingRate = samplingRate;
+        }
+
+        private int numChannels;
+        private int samplingRate;
+    }
+
     private short[] decodeToMemory(int testinput, int resetMode, int configMode,
             int eossample, List<Long> timestamps) throws IOException {
 
+        AudioParameter audioParams = new AudioParameter();
+        return decodeToMemory(audioParams, testinput, resetMode, configMode, eossample, timestamps);
+    }
+
+    private short[] decodeToMemory(AudioParameter audioParams, int testinput, int resetMode,
+            int configMode, int eossample, List<Long> timestamps)
+            throws IOException
+    {
         String localTag = TAG + "#decodeToMemory";
         Log.v(localTag, String.format("reset = %d; config: %s", resetMode, configMode));
         short [] decoded = new short[0];
@@ -797,7 +1273,8 @@
                 Log.d(TAG, "output buffers have changed.");
             } else if (res == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
                 MediaFormat oformat = codec.getOutputFormat();
-
+                audioParams.setNumChannels(oformat.getInteger(MediaFormat.KEY_CHANNEL_COUNT));
+                audioParams.setSamplingRate(oformat.getInteger(MediaFormat.KEY_SAMPLE_RATE));
                 Log.d(TAG, "output format has changed to " + oformat);
             } else {
                 Log.d(TAG, "dequeueOutputBuffer returned " + res);
@@ -1096,8 +1573,8 @@
         testDecode(R.raw.video_352x288_mp4_hevc_600kbps_30fps_aac_stereo_128kbps_44100hz, 299);
     }
 
-    public void testHEVCDecode720x480() throws Exception {
-        testDecode(R.raw.video_720x480_mp4_hevc_1638kbps_30fps_aac_stereo_128kbps_44100hz, 299);
+    public void testHEVCDecode640x360() throws Exception {
+        testDecode(R.raw.video_640x360_mp4_hevc_1638kbps_30fps_aac_stereo_128kbps_44100hz, 299);
     }
 
     public void testHEVCDecode30fps1280x720Tv() throws Exception {
diff --git a/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayWithCompositionTest.java b/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayWithCompositionTest.java
index a999135..b49f07e 100644
--- a/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayWithCompositionTest.java
+++ b/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayWithCompositionTest.java
@@ -58,7 +58,7 @@
 import android.widget.ImageView;
 import android.widget.TextView;
 
-import com.android.cts.media.R;
+import android.media.cts.R;
 
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
@@ -1292,7 +1292,7 @@
 
         void connect() throws Exception {
             Intent intent = new Intent();
-            intent.setClassName("com.android.cts.media",
+            intent.setClassName("android.media.cts",
                     "android.media.cts.RemoteVirtualDisplayService");
             mContext.bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
             if (!mConnectionWait.tryAcquire(DEFAULT_WAIT_TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
diff --git a/tests/tests/media/src/android/media/cts/EncoderTest.java b/tests/tests/media/src/android/media/cts/EncoderTest.java
index 4b2a168..e48af7e 100644
--- a/tests/tests/media/src/android/media/cts/EncoderTest.java
+++ b/tests/tests/media/src/android/media/cts/EncoderTest.java
@@ -16,26 +16,48 @@
 
 package android.media.cts;
 
-import com.android.cts.media.R;
+import android.media.cts.R;
 
 import android.content.Context;
 import android.media.MediaCodec;
 import android.media.MediaCodecInfo;
 import android.media.MediaCodecList;
 import android.media.MediaFormat;
+import android.media.MediaMuxer;
 import android.test.AndroidTestCase;
 import android.util.Log;
 
+import java.io.File;
+import java.io.InputStream;
+import java.nio.BufferOverflowException;
 import java.nio.ByteBuffer;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Random;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
 
 public class EncoderTest extends AndroidTestCase {
     private static final String TAG = "EncoderTest";
     private static final boolean VERBOSE = false;
 
-    private static final int kNumInputBytes = 256 * 1024;
-    private static final long kTimeoutUs = 10000;
+    private static final int kNumInputBytes = 512 * 1024;
+    private static final long kTimeoutUs = 100;
+
+    // not all combinations are valid
+    private static final int MODE_SILENT = 0;
+    private static final int MODE_RANDOM = 1;
+    private static final int MODE_RESOURCE = 2;
+    private static final int MODE_QUIET = 4;
+    private static final int MODE_SILENTLEAD = 8;
+
+    /*
+     * Set this to true to save the encoding results to /data/local/tmp
+     * You will need to make /data/local/tmp writeable, run "setenforce 0",
+     * and remove files left from a previous run.
+     */
+    private static boolean sSaveResults = false;
 
     @Override
     public void setContext(Context context) {
@@ -121,15 +143,21 @@
     private void testEncoderWithFormats(
             String mime, List<MediaFormat> formats) {
         List<String> componentNames = getEncoderNamesForType(mime);
+        ExecutorService pool = Executors.newFixedThreadPool(3);
 
         for (String componentName : componentNames) {
-            Log.d(TAG, "testing component '" + componentName + "'");
             for (MediaFormat format : formats) {
-                Log.d(TAG, "  testing format '" + format + "'");
                 assertEquals(mime, format.getString(MediaFormat.KEY_MIME));
-                testEncoder(componentName, format);
+                pool.execute(new EncoderRun(componentName, format));
             }
         }
+        try {
+            pool.shutdown();
+            assertTrue("timed out waiting for encoder threads",
+                    pool.awaitTermination(5, TimeUnit.MINUTES));
+        } catch (InterruptedException e) {
+            fail("interrupted while waiting for encoder threads");
+        }
     }
 
     private List<String> getEncoderNamesForType(String mime) {
@@ -151,17 +179,66 @@
         return names;
     }
 
-    private int queueInputBuffer(
-            MediaCodec codec, ByteBuffer[] inputBuffers, int index) {
-        ByteBuffer buffer = inputBuffers[index];
-        buffer.clear();
+    // See bug 25843966
+    private long[] mBadSeeds = {
+            101833462733980l, // fail @ 23680 in all-random mode
+            273262699095706l, // fail @ 58880 in all-random mode
+            137295510492957l, // fail @ 35840 in zero-lead mode
+            57821391502855l,  // fail @ 32000 in zero-lead mode
+    };
 
+    private Random mRandom = new Random(1);
+
+    private int queueInputBuffer(
+            MediaCodec codec, ByteBuffer[] inputBuffers, int index,
+            InputStream istream, int mode, long timeUs) {
+        ByteBuffer buffer = inputBuffers[index];
+        buffer.rewind();
         int size = buffer.limit();
 
-        byte[] zeroes = new byte[size];
-        buffer.put(zeroes);
+        if ((mode & MODE_RESOURCE) != 0 && istream != null) {
+            while (buffer.hasRemaining()) {
+                try {
+                    int next = istream.read();
+                    if (next < 0) {
+                        break;
+                    }
+                    buffer.put((byte) next);
+                } catch (Exception ex) {
+                    Log.i(TAG, "caught exception writing: " + ex);
+                    break;
+                }
+            }
+        } else if ((mode & MODE_RANDOM) != 0) {
+            if ((mode & MODE_SILENTLEAD) != 0) {
+                buffer.putInt(0);
+                buffer.putInt(0);
+                buffer.putInt(0);
+                buffer.putInt(0);
+            }
+            while (true) {
+                try {
+                    int next = mRandom.nextInt();
+                    buffer.putInt(mRandom.nextInt());
+                } catch (BufferOverflowException ex) {
+                    break;
+                }
+            }
+        } else {
+            byte[] zeroes = new byte[size];
+            buffer.put(zeroes);
+        }
 
-        codec.queueInputBuffer(index, 0 /* offset */, size, 0 /* timeUs */, 0);
+        if ((mode & MODE_QUIET) != 0) {
+            int n = buffer.limit();
+            for (int i = 0; i < n; i += 2) {
+                short s = buffer.getShort(i);
+                s /= 8;
+                buffer.putShort(i, s);
+            }
+        }
+
+        codec.queueInputBuffer(index, 0 /* offset */, size, timeUs, 0 /* flags */);
 
         return size;
     }
@@ -172,7 +249,68 @@
         codec.releaseOutputBuffer(index, false /* render */);
     }
 
+    class EncoderRun implements Runnable {
+        String mComponentName;
+        MediaFormat mFormat;
+
+        EncoderRun(String componentName, MediaFormat format) {
+            mComponentName = componentName;
+            mFormat = format;
+        }
+        @Override
+        public void run() {
+            testEncoder(mComponentName, mFormat);
+        }
+    }
+
     private void testEncoder(String componentName, MediaFormat format) {
+        Log.i(TAG, "testEncoder " + componentName + "/" + format);
+        // test with all zeroes/silence
+        testEncoder(componentName, format, 0, -1, MODE_SILENT);
+
+        // test with pcm input file
+        testEncoder(componentName, format, 0, R.raw.okgoogle123_good, MODE_RESOURCE);
+        testEncoder(componentName, format, 0, R.raw.okgoogle123_good, MODE_RESOURCE | MODE_QUIET);
+        testEncoder(componentName, format, 0, R.raw.tones, MODE_RESOURCE);
+        testEncoder(componentName, format, 0, R.raw.tones, MODE_RESOURCE | MODE_QUIET);
+
+        // test with random data, with and without a few leading zeroes
+        for (int i = 0; i < mBadSeeds.length; i++) {
+            testEncoder(componentName, format, mBadSeeds[i], -1, MODE_RANDOM);
+            testEncoder(componentName, format, mBadSeeds[i], -1, MODE_RANDOM | MODE_SILENTLEAD);
+        }
+    }
+
+    private void testEncoder(String componentName, MediaFormat format,
+            long startSeed, int resid, int mode) {
+
+        Log.i(TAG, "testEncoder " + componentName + "/" + mode + "/" + format);
+        int sampleRate = format.getInteger(MediaFormat.KEY_SAMPLE_RATE);
+        int channelCount = format.getInteger(MediaFormat.KEY_CHANNEL_COUNT);
+        int inBitrate = sampleRate * channelCount * 16;  // bit/sec
+        int outBitrate = format.getInteger(MediaFormat.KEY_BIT_RATE);
+
+        MediaMuxer muxer = null;
+        int muxidx = -1;
+        if (sSaveResults) {
+            try {
+                String outFile = "/data/local/tmp/transcoded-" + componentName +
+                        "-" + sampleRate + "-" + channelCount + "-" + outBitrate +
+                        "-" + mode + "-" + startSeed + ".mp4";
+                new File("outFile").delete();
+                muxer = new MediaMuxer(outFile, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
+                // The track can't be added until we have the codec specific data
+            } catch (Exception e) {
+                Log.i(TAG, "couldn't create muxer: " + e);
+            }
+        }
+
+        InputStream istream = null;
+        if ((mode & MODE_RESOURCE) != 0) {
+            istream = mContext.getResources().openRawResource(resid);
+        }
+
+        mRandom.setSeed(startSeed);
         MediaCodec codec;
         try {
             codec = MediaCodec.createByCodecName(componentName);
@@ -205,12 +343,14 @@
                 index = codec.dequeueInputBuffer(kTimeoutUs /* timeoutUs */);
 
                 if (index != MediaCodec.INFO_TRY_AGAIN_LATER) {
+                    long timeUs =
+                            (long)numBytesSubmitted * 1000000 / (2 * channelCount * sampleRate);
                     if (numBytesSubmitted >= kNumInputBytes) {
                         codec.queueInputBuffer(
                                 index,
                                 0 /* offset */,
                                 0 /* size */,
-                                0 /* timeUs */,
+                                timeUs,
                                 MediaCodec.BUFFER_FLAG_END_OF_STREAM);
 
                         if (VERBOSE) {
@@ -220,7 +360,7 @@
                         doneSubmittingInput = true;
                     } else {
                         int size = queueInputBuffer(
-                                codec, codecInputBuffers, index);
+                                codec, codecInputBuffers, index, istream, mode, timeUs);
 
                         numBytesSubmitted += size;
 
@@ -239,6 +379,16 @@
             } else if (index == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
                 codecOutputBuffers = codec.getOutputBuffers();
             } else {
+                if (muxer != null) {
+                    ByteBuffer buffer = codec.getOutputBuffer(index);
+                    if (muxidx < 0) {
+                        MediaFormat trackFormat = codec.getOutputFormat();
+                        muxidx = muxer.addTrack(trackFormat);
+                        muxer.start();
+                    }
+                    muxer.writeSampleData(muxidx, buffer, info);
+                }
+
                 dequeueOutputBuffer(codec, codecOutputBuffers, index, info);
 
                 numBytesDequeued += info.size;
@@ -261,11 +411,6 @@
                     + "dequeued " + numBytesDequeued + " bytes.");
         }
 
-        int sampleRate = format.getInteger(MediaFormat.KEY_SAMPLE_RATE);
-        int channelCount = format.getInteger(MediaFormat.KEY_CHANNEL_COUNT);
-        int inBitrate = sampleRate * channelCount * 16;  // bit/sec
-        int outBitrate = format.getInteger(MediaFormat.KEY_BIT_RATE);
-
         float desiredRatio = (float)outBitrate / (float)inBitrate;
         float actualRatio = (float)numBytesDequeued / (float)numBytesSubmitted;
 
@@ -276,6 +421,11 @@
 
         codec.release();
         codec = null;
+        if (muxer != null) {
+            muxer.stop();
+            muxer.release();
+            muxer = null;
+        }
     }
 }
 
diff --git a/tests/tests/media/src/android/media/cts/ExifInterfaceTest.java b/tests/tests/media/src/android/media/cts/ExifInterfaceTest.java
new file mode 100644
index 0000000..dff6b1c
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/ExifInterfaceTest.java
@@ -0,0 +1,464 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.media.cts;
+
+import android.content.res.TypedArray;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.media.ExifInterface;
+import android.os.Environment;
+import android.test.AndroidTestCase;
+import android.util.Log;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.system.OsConstants;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.IOException;
+import java.lang.reflect.Type;
+
+import libcore.io.IoUtils;
+import libcore.io.Streams;
+
+public class ExifInterfaceTest extends AndroidTestCase {
+    private static final String TAG = ExifInterface.class.getSimpleName();
+    private static final boolean VERBOSE = false;  // lots of logging
+
+    private static final double DIFFERENCE_TOLERANCE = .001;
+
+    // List of files.
+    private static final String EXIF_BYTE_ORDER_II_JPEG = "image_exif_byte_order_ii.jpg";
+    private static final String EXIF_BYTE_ORDER_MM_JPEG = "image_exif_byte_order_mm.jpg";
+    private static final String LG_G4_ISO_800_DNG = "lg_g4_iso_800.dng";
+    private static final int[] IMAGE_RESOURCES = new int[] {
+            R.raw.image_exif_byte_order_ii,  R.raw.image_exif_byte_order_mm, R.raw.lg_g4_iso_800 };
+    private static final String[] IMAGE_FILENAMES = new String[] {
+            EXIF_BYTE_ORDER_II_JPEG, EXIF_BYTE_ORDER_MM_JPEG, LG_G4_ISO_800_DNG };
+
+    private static final String[] EXIF_TAGS = {
+            ExifInterface.TAG_MAKE,
+            ExifInterface.TAG_MODEL,
+            ExifInterface.TAG_F_NUMBER,
+            ExifInterface.TAG_DATETIME,
+            ExifInterface.TAG_EXPOSURE_TIME,
+            ExifInterface.TAG_FLASH,
+            ExifInterface.TAG_FOCAL_LENGTH,
+            ExifInterface.TAG_GPS_ALTITUDE,
+            ExifInterface.TAG_GPS_ALTITUDE_REF,
+            ExifInterface.TAG_GPS_DATESTAMP,
+            ExifInterface.TAG_GPS_LATITUDE,
+            ExifInterface.TAG_GPS_LATITUDE_REF,
+            ExifInterface.TAG_GPS_LONGITUDE,
+            ExifInterface.TAG_GPS_LONGITUDE_REF,
+            ExifInterface.TAG_GPS_PROCESSING_METHOD,
+            ExifInterface.TAG_GPS_TIMESTAMP,
+            ExifInterface.TAG_IMAGE_LENGTH,
+            ExifInterface.TAG_IMAGE_WIDTH,
+            ExifInterface.TAG_ISO_SPEED_RATINGS,
+            ExifInterface.TAG_ORIENTATION,
+            ExifInterface.TAG_WHITE_BALANCE
+    };
+
+    private static class ExpectedValue {
+        // Thumbnail information.
+        public final boolean hasThumbnail;
+        public final int thumbnailWidth;
+        public final int thumbnailHeight;
+
+        // GPS information.
+        public final boolean hasLatLong;
+        public final float latitude;
+        public final float longitude;
+        public final float altitude;
+
+        // Values.
+        public final String make;
+        public final String model;
+        public final float aperture;
+        public final String datetime;
+        public final float exposureTime;
+        public final float flash;
+        public final String focalLength;
+        public final String gpsAltitude;
+        public final String gpsAltitudeRef;
+        public final String gpsDatestamp;
+        public final String gpsLatitude;
+        public final String gpsLatitudeRef;
+        public final String gpsLongitude;
+        public final String gpsLongitudeRef;
+        public final String gpsProcessingMethod;
+        public final String gpsTimestamp;
+        public final int imageLength;
+        public final int imageWidth;
+        public final String iso;
+        public final int orientation;
+        public final int whiteBalance;
+
+        private static String getString(TypedArray typedArray, int index) {
+            String stringValue = typedArray.getString(index);
+            if (stringValue == null || stringValue.equals("")) {
+                return null;
+            }
+            return stringValue.trim();
+        }
+
+        public ExpectedValue(TypedArray typedArray) {
+            // Reads thumbnail information.
+            hasThumbnail = typedArray.getBoolean(0, false);
+            thumbnailWidth = typedArray.getInt(1, 0);
+            thumbnailHeight = typedArray.getInt(2, 0);
+
+            // Reads GPS information.
+            hasLatLong = typedArray.getBoolean(3, false);
+            latitude = typedArray.getFloat(4, 0f);
+            longitude = typedArray.getFloat(5, 0f);
+            altitude = typedArray.getFloat(6, 0f);
+
+            // Reads values.
+            make = getString(typedArray, 7);
+            model = getString(typedArray, 8);
+            aperture = typedArray.getFloat(9, 0f);
+            datetime = getString(typedArray, 10);
+            exposureTime = typedArray.getFloat(11, 0f);
+            flash = typedArray.getFloat(12, 0f);
+            focalLength = getString(typedArray, 13);
+            gpsAltitude = getString(typedArray, 14);
+            gpsAltitudeRef = getString(typedArray, 15);
+            gpsDatestamp = getString(typedArray, 16);
+            gpsLatitude = getString(typedArray, 17);
+            gpsLatitudeRef = getString(typedArray, 18);
+            gpsLongitude = getString(typedArray, 19);
+            gpsLongitudeRef = getString(typedArray, 20);
+            gpsProcessingMethod = getString(typedArray, 21);
+            gpsTimestamp = getString(typedArray, 22);
+            imageLength = typedArray.getInt(23, 0);
+            imageWidth = typedArray.getInt(24, 0);
+            iso = getString(typedArray, 25);
+            orientation = typedArray.getInt(26, 0);
+            whiteBalance = typedArray.getInt(27, 0);
+
+            typedArray.recycle();
+        }
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        for (int i = 0; i < IMAGE_RESOURCES.length; ++i) {
+            String outputPath = new File(Environment.getExternalStorageDirectory(),
+                    IMAGE_FILENAMES[i]).getAbsolutePath();
+            try (InputStream inputStream = getContext().getResources().openRawResource(
+                    IMAGE_RESOURCES[i])) {
+                try (FileOutputStream outputStream = new FileOutputStream(outputPath)) {
+                    Streams.copy(inputStream, outputStream);
+                }
+            }
+        }
+        super.setUp();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        for (int i = 0; i < IMAGE_RESOURCES.length; ++i) {
+            String imageFilePath = new File(Environment.getExternalStorageDirectory(),
+                    IMAGE_FILENAMES[i]).getAbsolutePath();
+            File imageFile = new File(imageFilePath);
+            if (imageFile.exists()) {
+                imageFile.delete();
+            }
+        }
+
+        super.tearDown();
+    }
+
+    public void testReadExifDataFromExifByteOrderIIJpeg() throws Throwable {
+        testExifInterfaceForJpeg(EXIF_BYTE_ORDER_II_JPEG, R.array.exifbyteorderii_jpg);
+    }
+
+    public void testReadExifDataFromExifByteOrderMMJpeg() throws Throwable {
+        testExifInterfaceForJpeg(EXIF_BYTE_ORDER_MM_JPEG, R.array.exifbyteordermm_jpg);
+    }
+
+    public void testReadExifDataFromLgG4Iso800Dng() throws Throwable {
+        testExifInterfaceForRaw(LG_G4_ISO_800_DNG, R.array.lg_g4_iso_800_dng);
+    }
+
+    private void printExifTagsAndValues(String fileName, ExifInterface exifInterface) {
+        // Prints thumbnail information.
+        if (exifInterface.hasThumbnail()) {
+            byte[] thumbnailBytes = exifInterface.getThumbnail();
+            if (thumbnailBytes != null) {
+                Log.v(TAG, fileName + " Thumbnail size = " + thumbnailBytes.length);
+                Bitmap bitmap = BitmapFactory.decodeByteArray(
+                        thumbnailBytes, 0, thumbnailBytes.length);
+                if (bitmap == null) {
+                    Log.e(TAG, fileName + " Corrupted thumbnail!");
+                } else {
+                    Log.v(TAG, fileName + " Thumbnail size: " + bitmap.getWidth() + ", "
+                            + bitmap.getHeight());
+                }
+            } else {
+                Log.e(TAG, fileName + " Unexpected result: No thumbnails were found. "
+                        + "A thumbnail is expected.");
+            }
+        } else {
+            if (exifInterface.getThumbnail() != null) {
+                Log.e(TAG, fileName + " Unexpected result: A thumbnail was found. "
+                        + "No thumbnail is expected.");
+            } else {
+                Log.v(TAG, fileName + " No thumbnail");
+            }
+        }
+
+        // Prints GPS information.
+        Log.v(TAG, fileName + " Altitude = " + exifInterface.getAltitude(.0));
+
+        float[] latLong = new float[2];
+        if (exifInterface.getLatLong(latLong)) {
+            Log.v(TAG, fileName + " Latitude = " + latLong[0]);
+            Log.v(TAG, fileName + " Longitude = " + latLong[1]);
+        } else {
+            Log.v(TAG, fileName + " No latlong data");
+        }
+
+        // Prints values.
+        for (String tagKey : EXIF_TAGS) {
+            String tagValue = exifInterface.getAttribute(tagKey);
+            Log.v(TAG, fileName + " Key{" + tagKey + "} = '" + tagValue + "'");
+        }
+    }
+
+    private void assertIntTag(ExifInterface exifInterface, String tag, int expectedValue) {
+        int intValue = exifInterface.getAttributeInt(tag, 0);
+        assertEquals(expectedValue, intValue);
+    }
+
+    private void assertFloatTag(ExifInterface exifInterface, String tag, float expectedValue) {
+        double doubleValue = exifInterface.getAttributeDouble(tag, 0.0);
+        assertEquals(expectedValue, doubleValue, DIFFERENCE_TOLERANCE);
+    }
+
+    private void assertStringTag(ExifInterface exifInterface, String tag, String expectedValue) {
+        String stringValue = exifInterface.getAttribute(tag);
+        if (stringValue != null) {
+            stringValue = stringValue.trim();
+        }
+        assertEquals(expectedValue, stringValue);
+    }
+
+    private void compareWithExpectedValue(ExifInterface exifInterface,
+            ExpectedValue expectedValue, String verboseTag) {
+        if (VERBOSE) {
+            printExifTagsAndValues(verboseTag, exifInterface);
+        }
+        // Checks a thumbnail image.
+        assertEquals(expectedValue.hasThumbnail, exifInterface.hasThumbnail());
+        if (expectedValue.hasThumbnail) {
+            byte[] thumbnailBytes = exifInterface.getThumbnail();
+            assertNotNull(thumbnailBytes);
+            Bitmap thumbnailBitmap =
+                    BitmapFactory.decodeByteArray(thumbnailBytes, 0, thumbnailBytes.length);
+            assertNotNull(thumbnailBitmap);
+            assertEquals(expectedValue.thumbnailWidth, thumbnailBitmap.getWidth());
+            assertEquals(expectedValue.thumbnailHeight, thumbnailBitmap.getHeight());
+        } else {
+            assertNull(exifInterface.getThumbnail());
+        }
+
+        // Checks GPS information.
+        float[] latLong = new float[2];
+        assertEquals(expectedValue.hasLatLong, exifInterface.getLatLong(latLong));
+        if (expectedValue.hasLatLong) {
+            assertEquals(expectedValue.latitude, latLong[0], DIFFERENCE_TOLERANCE);
+            assertEquals(expectedValue.longitude, latLong[1], DIFFERENCE_TOLERANCE);
+        }
+        assertEquals(expectedValue.altitude, exifInterface.getAltitude(.0), DIFFERENCE_TOLERANCE);
+
+        // Checks values.
+        assertStringTag(exifInterface, ExifInterface.TAG_MAKE, expectedValue.make);
+        assertStringTag(exifInterface, ExifInterface.TAG_MODEL, expectedValue.model);
+        assertFloatTag(exifInterface, ExifInterface.TAG_F_NUMBER, expectedValue.aperture);
+        assertStringTag(exifInterface, ExifInterface.TAG_DATETIME, expectedValue.datetime);
+        assertFloatTag(exifInterface, ExifInterface.TAG_EXPOSURE_TIME, expectedValue.exposureTime);
+        assertFloatTag(exifInterface, ExifInterface.TAG_FLASH, expectedValue.flash);
+        assertStringTag(exifInterface, ExifInterface.TAG_FOCAL_LENGTH, expectedValue.focalLength);
+        assertStringTag(exifInterface, ExifInterface.TAG_GPS_ALTITUDE, expectedValue.gpsAltitude);
+        assertStringTag(exifInterface, ExifInterface.TAG_GPS_ALTITUDE_REF,
+                expectedValue.gpsAltitudeRef);
+        assertStringTag(exifInterface, ExifInterface.TAG_GPS_DATESTAMP, expectedValue.gpsDatestamp);
+        assertStringTag(exifInterface, ExifInterface.TAG_GPS_LATITUDE, expectedValue.gpsLatitude);
+        assertStringTag(exifInterface, ExifInterface.TAG_GPS_LATITUDE_REF,
+                expectedValue.gpsLatitudeRef);
+        assertStringTag(exifInterface, ExifInterface.TAG_GPS_LONGITUDE, expectedValue.gpsLongitude);
+        assertStringTag(exifInterface, ExifInterface.TAG_GPS_LONGITUDE_REF,
+                expectedValue.gpsLongitudeRef);
+        assertStringTag(exifInterface, ExifInterface.TAG_GPS_PROCESSING_METHOD,
+                expectedValue.gpsProcessingMethod);
+        assertStringTag(exifInterface, ExifInterface.TAG_GPS_TIMESTAMP, expectedValue.gpsTimestamp);
+        assertIntTag(exifInterface, ExifInterface.TAG_IMAGE_LENGTH, expectedValue.imageLength);
+        assertIntTag(exifInterface, ExifInterface.TAG_IMAGE_WIDTH, expectedValue.imageWidth);
+        assertStringTag(exifInterface, ExifInterface.TAG_ISO_SPEED_RATINGS, expectedValue.iso);
+        assertIntTag(exifInterface, ExifInterface.TAG_ORIENTATION, expectedValue.orientation);
+        assertIntTag(exifInterface, ExifInterface.TAG_WHITE_BALANCE, expectedValue.whiteBalance);
+    }
+
+    private void testExifInterfaceCommon(File imageFile, ExpectedValue expectedValue)
+            throws IOException {
+        String verboseTag = imageFile.getName();
+
+        // Creates via path.
+        ExifInterface exifInterface = new ExifInterface(imageFile.getAbsolutePath());
+        assertNotNull(exifInterface);
+        compareWithExpectedValue(exifInterface, expectedValue, verboseTag);
+
+        // Creates from an asset file.
+        InputStream in = null;
+        try {
+            in = getContext().getAssets().open(imageFile.getName());
+            exifInterface = new ExifInterface(in);
+            compareWithExpectedValue(exifInterface, expectedValue, verboseTag);
+        } finally {
+            IoUtils.closeQuietly(in);
+        }
+
+        // Creates via InputStream.
+        in = null;
+        try {
+            in = new BufferedInputStream(new FileInputStream(imageFile.getAbsolutePath()));
+            exifInterface = new ExifInterface(in);
+            compareWithExpectedValue(exifInterface, expectedValue, verboseTag);
+        } finally {
+            IoUtils.closeQuietly(in);
+        }
+
+        // Creates via FileDescriptor.
+        FileDescriptor fd = null;
+        try {
+            fd = Os.open(imageFile.getAbsolutePath(), OsConstants.O_RDONLY, 0600);
+            exifInterface = new ExifInterface(fd);
+            compareWithExpectedValue(exifInterface, expectedValue, verboseTag);
+        } catch (ErrnoException e) {
+            throw e.rethrowAsIOException();
+        } finally {
+            IoUtils.closeQuietly(fd);
+        }
+    }
+
+    private void testSaveAttributes_withFileName(File imageFile, ExpectedValue expectedValue)
+            throws IOException {
+        String verboseTag = imageFile.getName();
+
+        ExifInterface exifInterface = new ExifInterface(imageFile.getAbsolutePath());
+        exifInterface.saveAttributes();
+        exifInterface = new ExifInterface(imageFile.getAbsolutePath());
+        compareWithExpectedValue(exifInterface, expectedValue, verboseTag);
+
+        // Test for modifying one attribute.
+        String backupValue = exifInterface.getAttribute(ExifInterface.TAG_MAKE);
+        exifInterface.setAttribute(ExifInterface.TAG_MAKE, "abc");
+        exifInterface.saveAttributes();
+        exifInterface = new ExifInterface(imageFile.getAbsolutePath());
+        assertEquals("abc", exifInterface.getAttribute(ExifInterface.TAG_MAKE));
+        // Restore the backup value.
+        exifInterface.setAttribute(ExifInterface.TAG_MAKE, backupValue);
+        exifInterface.saveAttributes();
+        exifInterface = new ExifInterface(imageFile.getAbsolutePath());
+        compareWithExpectedValue(exifInterface, expectedValue, verboseTag);
+    }
+
+    private void testSaveAttributes_withFileDescriptor(File imageFile, ExpectedValue expectedValue)
+            throws IOException {
+        String verboseTag = imageFile.getName();
+
+        FileDescriptor fd = null;
+        try {
+            fd = Os.open(imageFile.getAbsolutePath(), OsConstants.O_RDWR, 0600);
+            ExifInterface exifInterface = new ExifInterface(fd);
+            exifInterface.saveAttributes();
+            Os.lseek(fd, 0, OsConstants.SEEK_SET);
+            exifInterface = new ExifInterface(fd);
+            compareWithExpectedValue(exifInterface, expectedValue, verboseTag);
+
+            // Test for modifying one attribute.
+            String backupValue = exifInterface.getAttribute(ExifInterface.TAG_MAKE);
+            exifInterface.setAttribute(ExifInterface.TAG_MAKE, "abc");
+            exifInterface.saveAttributes();
+            Os.lseek(fd, 0, OsConstants.SEEK_SET);
+            exifInterface = new ExifInterface(fd);
+            assertEquals("abc", exifInterface.getAttribute(ExifInterface.TAG_MAKE));
+            // Restore the backup value.
+            exifInterface.setAttribute(ExifInterface.TAG_MAKE, backupValue);
+            exifInterface.saveAttributes();
+            Os.lseek(fd, 0, OsConstants.SEEK_SET);
+            exifInterface = new ExifInterface(fd);
+            compareWithExpectedValue(exifInterface, expectedValue, verboseTag);
+        } catch (ErrnoException e) {
+            throw e.rethrowAsIOException();
+        } finally {
+            IoUtils.closeQuietly(fd);
+        }
+    }
+
+    private void testSaveAttributes_withInputStream(File imageFile, ExpectedValue expectedValue)
+            throws IOException {
+        InputStream in = null;
+        try {
+            in = getContext().getAssets().open(imageFile.getName());
+            ExifInterface exifInterface = new ExifInterface(in);
+            exifInterface.saveAttributes();
+        } catch (UnsupportedOperationException e) {
+            // Expected. saveAttributes is not supported with an ExifInterface object which was
+            // created with InputStream.
+            return;
+        } finally {
+            IoUtils.closeQuietly(in);
+        }
+        fail("Should not reach here!");
+    }
+
+    private void testExifInterfaceForJpeg(String fileName, int typedArrayResourceId)
+            throws IOException {
+        ExpectedValue expectedValue = new ExpectedValue(
+                getContext().getResources().obtainTypedArray(typedArrayResourceId));
+        File imageFile = new File(Environment.getExternalStorageDirectory(), fileName);
+
+        // Test for reading from various inputs.
+        testExifInterfaceCommon(imageFile, expectedValue);
+
+        // Test for saving attributes.
+        testSaveAttributes_withFileName(imageFile, expectedValue);
+        testSaveAttributes_withFileDescriptor(imageFile, expectedValue);
+        testSaveAttributes_withInputStream(imageFile, expectedValue);
+    }
+
+    private void testExifInterfaceForRaw(String fileName, int typedArrayResourceId)
+            throws IOException {
+        ExpectedValue expectedValue = new ExpectedValue(
+                getContext().getResources().obtainTypedArray(typedArrayResourceId));
+        File imageFile = new File(Environment.getExternalStorageDirectory(), fileName);
+
+        // Test for reading from various inputs.
+        testExifInterfaceCommon(imageFile, expectedValue);
+
+        // Since ExifInterface does not support for saving attributes for RAW files, do not test
+        // about writing back in here.
+    }
+}
diff --git a/tests/tests/media/src/android/media/cts/ExtractDecodeEditEncodeMuxTest.java b/tests/tests/media/src/android/media/cts/ExtractDecodeEditEncodeMuxTest.java
index 8650d20..72a74c1 100644
--- a/tests/tests/media/src/android/media/cts/ExtractDecodeEditEncodeMuxTest.java
+++ b/tests/tests/media/src/android/media/cts/ExtractDecodeEditEncodeMuxTest.java
@@ -18,6 +18,7 @@
 
 import android.annotation.TargetApi;
 import android.content.res.AssetFileDescriptor;
+import android.content.Context;
 import android.media.MediaCodec;
 import android.media.MediaCodecInfo;
 import android.media.MediaCodecInfo.CodecCapabilities;
@@ -26,8 +27,9 @@
 import android.media.MediaExtractor;
 import android.media.MediaFormat;
 import android.media.MediaMuxer;
+import android.media.MediaPlayer;
 import android.os.Environment;
-import android.test.AndroidTestCase;
+import android.test.ActivityInstrumentationTestCase2;
 import android.util.Log;
 import android.view.Surface;
 
@@ -35,12 +37,13 @@
 import android.media.MediaCodecInfo.CodecCapabilities;
 import android.media.MediaCodecInfo.CodecProfileLevel;
 
-import com.android.cts.media.R;
+import android.media.cts.R;
 
 import java.io.File;
 import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.util.concurrent.atomic.AtomicReference;
+import java.util.concurrent.CountDownLatch;
 
 /**
  * Test for the integration of MediaMuxer and MediaCodec's encoder.
@@ -56,7 +59,8 @@
  * MediaMuxer.
  */
 @TargetApi(18)
-public class ExtractDecodeEditEncodeMuxTest extends AndroidTestCase {
+public class ExtractDecodeEditEncodeMuxTest
+        extends ActivityInstrumentationTestCase2<MediaStubActivity> {
 
     private static final String TAG = ExtractDecodeEditEncodeMuxTest.class.getSimpleName();
     private static final boolean VERBOSE = false; // lots of logging
@@ -68,8 +72,6 @@
     private static final File OUTPUT_FILENAME_DIR = Environment.getExternalStorageDirectory();
 
     // parameters for the video encoder
-                                                                // H.264 Advanced Video Coding
-    private static final String OUTPUT_VIDEO_MIME_TYPE = MediaFormat.MIMETYPE_VIDEO_AVC;
     private static final int OUTPUT_VIDEO_BIT_RATE = 2000000;   // 2Mbps
     private static final int OUTPUT_VIDEO_FRAME_RATE = 15;      // 15fps
     private static final int OUTPUT_VIDEO_IFRAME_INTERVAL = 10; // 10 seconds between I-frames
@@ -116,10 +118,17 @@
     /** The destination file for the encoded output. */
     private String mOutputFile;
 
+    private String mOutputVideoMimeType;
+
+    public ExtractDecodeEditEncodeMuxTest() {
+        super(MediaStubActivity.class);
+    }
+
     public void testExtractDecodeEditEncodeMuxQCIF() throws Throwable {
         if(!setSize(176, 144)) return;
         setSource(R.raw.video_480x360_mp4_h264_500kbps_30fps_aac_stereo_128kbps_44100hz);
         setCopyVideo();
+        setVideoMimeType(MediaFormat.MIMETYPE_VIDEO_AVC);
         TestWrapper.runTest(this);
     }
 
@@ -127,6 +136,7 @@
         if(!setSize(320, 240)) return;
         setSource(R.raw.video_480x360_mp4_h264_500kbps_30fps_aac_stereo_128kbps_44100hz);
         setCopyVideo();
+        setVideoMimeType(MediaFormat.MIMETYPE_VIDEO_AVC);
         TestWrapper.runTest(this);
     }
 
@@ -134,6 +144,15 @@
         if(!setSize(1280, 720)) return;
         setSource(R.raw.video_480x360_mp4_h264_500kbps_30fps_aac_stereo_128kbps_44100hz);
         setCopyVideo();
+        setVideoMimeType(MediaFormat.MIMETYPE_VIDEO_AVC);
+        TestWrapper.runTest(this);
+    }
+
+    public void testExtractDecodeEditEncodeMux2160pHevc() throws Throwable {
+        if(!setSize(3840, 2160)) return;
+        setSource(R.raw.video_480x360_mp4_h264_500kbps_30fps_aac_stereo_128kbps_44100hz);
+        setCopyVideo();
+        setVideoMimeType(MediaFormat.MIMETYPE_VIDEO_HEVC);
         TestWrapper.runTest(this);
     }
 
@@ -222,7 +241,7 @@
         mWidth = width;
         mHeight = height;
 
-	// TODO: remove this logic in setSize as it is now handled when configuring codecs
+        // TODO: remove this logic in setSize as it is now handled when configuring codecs
         return true;
     }
 
@@ -264,6 +283,10 @@
         mOutputFile = sb.toString();
     }
 
+    private void setVideoMimeType(String mimeType) {
+        mOutputVideoMimeType = mimeType;
+    }
+
     /**
      * Tests encoding and subsequently decoding video from frames generated into a buffer.
      * <p>
@@ -279,7 +302,7 @@
         // We avoid the device-specific limitations on width and height by using values
         // that are multiples of 16, which all tested devices seem to be able to handle.
         MediaFormat outputVideoFormat =
-                MediaFormat.createVideoFormat(OUTPUT_VIDEO_MIME_TYPE, mWidth, mHeight);
+                MediaFormat.createVideoFormat(mOutputVideoMimeType, mWidth, mHeight);
 
         // Set some properties. Failing to specify some of these can cause the MediaCodec
         // configure() call to throw an unhelpful exception.
@@ -304,7 +327,8 @@
                         OUTPUT_AUDIO_MIME_TYPE, OUTPUT_AUDIO_SAMPLE_RATE_HZ,
                         OUTPUT_AUDIO_CHANNEL_COUNT);
         outputAudioFormat.setInteger(MediaFormat.KEY_BIT_RATE, OUTPUT_AUDIO_BIT_RATE);
-        outputAudioFormat.setInteger(MediaFormat.KEY_AAC_PROFILE, OUTPUT_AUDIO_AAC_PROFILE);
+        // TODO: Bug workaround --- uncomment once fixed.
+        // outputAudioFormat.setInteger(MediaFormat.KEY_AAC_PROFILE, OUTPUT_AUDIO_AAC_PROFILE);
 
         String audioEncoderName = mcl.findEncoderForFormat(outputAudioFormat);
         if (audioEncoderName == null) {
@@ -514,6 +538,42 @@
         }
 
         // TODO: Check the generated output file's video format and sample data.
+
+        MediaStubActivity activity = getActivity();
+        final MediaPlayer mp = new MediaPlayer();
+        final Exception[] exceptionHolder = { null };
+        final CountDownLatch playbackEndSignal = new CountDownLatch(1);
+        mp.setOnErrorListener(new MediaPlayer.OnErrorListener() {
+            @Override
+            public boolean onError(MediaPlayer origin, int what, int extra) {
+                exceptionHolder[0] = new RuntimeException("error playing output file: what=" + what
+                        + " extra=" + extra);
+                // Returning false would trigger onCompletion() so that
+                // playbackEndSignal.await() can stop waiting.
+                return false;
+            }
+        });
+        mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
+            @Override
+            public void onCompletion(MediaPlayer origin) {
+                playbackEndSignal.countDown();
+            }
+        });
+        try {
+            mp.setDataSource(mOutputFile);
+            mp.setDisplay(activity.getSurfaceHolder());
+            mp.prepare();
+            mp.start();
+            playbackEndSignal.await();
+        } catch (Exception e) {
+            exceptionHolder[0] = e;
+        } finally {
+            mp.release();
+        }
+
+        if (exceptionHolder[0] != null) {
+            throw exceptionHolder[0];
+        }
     }
 
     /**
@@ -521,7 +581,8 @@
      */
     private MediaExtractor createExtractor() throws IOException {
         MediaExtractor extractor;
-        AssetFileDescriptor srcFd = getContext().getResources().openRawResourceFd(mSourceResId);
+        Context context = getInstrumentation().getTargetContext();
+        AssetFileDescriptor srcFd = context.getResources().openRawResourceFd(mSourceResId);
         extractor = new MediaExtractor();
         extractor.setDataSource(srcFd.getFileDescriptor(), srcFd.getStartOffset(),
                 srcFd.getLength());
@@ -1166,64 +1227,4 @@
         }
         return null;
     }
-
-  /**
-   * Checks whether the given resolution is supported by the AVC codec.
-   */
-    private static boolean isAvcSupportedSize(int width, int height) {
-        MediaCodecInfo mediaCodecInfo = selectCodec(OUTPUT_VIDEO_MIME_TYPE);
-        CodecCapabilities cap = mediaCodecInfo.getCapabilitiesForType(OUTPUT_VIDEO_MIME_TYPE);
-        if (cap == null) { // not supported
-            return false;
-        }
-        int highestLevel = 0;
-        for (CodecProfileLevel lvl : cap.profileLevels) {
-            if (lvl.level > highestLevel) {
-                highestLevel = lvl.level;
-            }
-        }
-        int maxW = 0;
-        int maxH = 0;
-        int bitRate = 0;
-        int fps = 0; // frame rate for the max resolution
-        switch(highestLevel) {
-            // Do not support Level 1 to 2.
-            case CodecProfileLevel.AVCLevel1:
-            case CodecProfileLevel.AVCLevel11:
-            case CodecProfileLevel.AVCLevel12:
-            case CodecProfileLevel.AVCLevel13:
-            case CodecProfileLevel.AVCLevel1b:
-            case CodecProfileLevel.AVCLevel2:
-                return false;
-            case CodecProfileLevel.AVCLevel21:
-                maxW = 352;
-                maxH = 576;
-                break;
-            case CodecProfileLevel.AVCLevel22:
-                maxW = 720;
-                maxH = 480;
-                break;
-            case CodecProfileLevel.AVCLevel3:
-                maxW = 720;
-                maxH = 480;
-                break;
-            case CodecProfileLevel.AVCLevel31:
-                maxW = 1280;
-                maxH = 720;
-                break;
-            case CodecProfileLevel.AVCLevel32:
-                maxW = 1280;
-                maxH = 720;
-                break;
-            case CodecProfileLevel.AVCLevel4: // only try up to 1080p
-            default:
-                maxW = 1920;
-                maxH = 1080;
-                break;
-        }
-        if(maxW*maxH < width*height)
-            return false;
-        else
-            return true;
-    }
 }
diff --git a/tests/tests/media/src/android/media/cts/FaceDetectorStub.java b/tests/tests/media/src/android/media/cts/FaceDetectorStub.java
index b1cb82d..6635fda 100644
--- a/tests/tests/media/src/android/media/cts/FaceDetectorStub.java
+++ b/tests/tests/media/src/android/media/cts/FaceDetectorStub.java
@@ -16,7 +16,7 @@
 
 package android.media.cts;
 
-import com.android.cts.media.R;
+import android.media.cts.R;
 
 import android.app.Activity;
 import android.media.FaceDetector.Face;
diff --git a/tests/tests/media/src/android/media/cts/FaceDetectorTest.java b/tests/tests/media/src/android/media/cts/FaceDetectorTest.java
index 4eebd52..4df0475 100644
--- a/tests/tests/media/src/android/media/cts/FaceDetectorTest.java
+++ b/tests/tests/media/src/android/media/cts/FaceDetectorTest.java
@@ -16,7 +16,7 @@
 
 package android.media.cts;
 
-import com.android.cts.media.R;
+import android.media.cts.R;
 
 
 import android.content.Intent;
diff --git a/tests/tests/media/src/android/media/cts/FaceDetector_FaceTest.java b/tests/tests/media/src/android/media/cts/FaceDetector_FaceTest.java
index 32c68fb..9dc06ec2 100644
--- a/tests/tests/media/src/android/media/cts/FaceDetector_FaceTest.java
+++ b/tests/tests/media/src/android/media/cts/FaceDetector_FaceTest.java
@@ -16,7 +16,7 @@
 
 package android.media.cts;
 
-import com.android.cts.media.R;
+import android.media.cts.R;
 
 
 import android.content.Intent;
diff --git a/tests/tests/media/src/android/media/cts/IConnectionStatus.java b/tests/tests/media/src/android/media/cts/IConnectionStatus.java
new file mode 100644
index 0000000..39e2781
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/IConnectionStatus.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.media.cts;
+
+import android.net.Uri;
+
+/**
+ * An interface to report and test connection status.
+ */
+public interface IConnectionStatus {
+
+    public String getNotConnectedReason();
+
+    public boolean isAvailable();
+
+    public boolean isConnected();
+
+    public boolean isEnabled();
+
+    public void printConnectionInfo();
+
+    public void testConnection(Uri uri);
+}
+
diff --git a/tests/tests/media/src/android/media/cts/ImageReaderDecoderTest.java b/tests/tests/media/src/android/media/cts/ImageReaderDecoderTest.java
index cc28b86..f1b2972 100644
--- a/tests/tests/media/src/android/media/cts/ImageReaderDecoderTest.java
+++ b/tests/tests/media/src/android/media/cts/ImageReaderDecoderTest.java
@@ -16,7 +16,7 @@
 
 package android.media.cts;
 
-import com.android.cts.media.R;
+import android.media.cts.R;
 
 import android.content.Context;
 import android.content.res.AssetFileDescriptor;
diff --git a/tests/tests/media/src/android/media/cts/JetPlayerTest.java b/tests/tests/media/src/android/media/cts/JetPlayerTest.java
index 4df3555..dce792a 100644
--- a/tests/tests/media/src/android/media/cts/JetPlayerTest.java
+++ b/tests/tests/media/src/android/media/cts/JetPlayerTest.java
@@ -16,7 +16,7 @@
 
 package android.media.cts;
 
-import com.android.cts.media.R;
+import android.media.cts.R;
 
 
 import android.content.res.AssetFileDescriptor;
diff --git a/tests/tests/media/src/android/media/cts/LoudnessEnhancerTest.java b/tests/tests/media/src/android/media/cts/LoudnessEnhancerTest.java
index 5b4d1aa..8923445 100644
--- a/tests/tests/media/src/android/media/cts/LoudnessEnhancerTest.java
+++ b/tests/tests/media/src/android/media/cts/LoudnessEnhancerTest.java
@@ -16,7 +16,7 @@
 
 package android.media.cts;
 
-import com.android.cts.media.R;
+import android.media.cts.R;
 
 import android.content.Context;
 import android.media.audiofx.AudioEffect;
@@ -91,7 +91,7 @@
         try {
             // this test will play a 1kHz sine wave with peaks at -40dB, and apply 6 db gain
             // using loudness enhancement
-            mp = MediaPlayer.create(getContext(), R.raw.sine1khzm40db);
+            mp = MediaPlayer.create(getContext(), R.raw.sine1khzs40dblong);
             final int LOUDNESS_GAIN = 600;
             final int MAX_MEASUREMENT_ERROR_MB = 200;
             assertNotNull("null MediaPlayer", mp);
@@ -122,6 +122,7 @@
             assertTrue("visualizer not enabled", visualizer.getEnabled());
             Thread.sleep(100);
             int status = visualizer.setMeasurementMode(Visualizer.MEASUREMENT_MODE_PEAK_RMS);
+            Thread.sleep(500);
             assertEquals("setMeasurementMode() for PEAK_RMS doesn't report success",
                     Visualizer.SUCCESS, status);
             // make sure we're playing long enough so the measurement is valid
@@ -147,7 +148,7 @@
 
             visualizer.setMeasurementMode(Visualizer.MEASUREMENT_MODE_PEAK_RMS);
             currentPosition = mp.getCurrentPosition();
-            maxTry = 5;
+            maxTry = 10;
             tryCount = 0;
             while (tryCount < maxTry) {
                 Thread.sleep(50);
diff --git a/tests/tests/media/src/android/media/cts/MediaBrowserServiceTest.java b/tests/tests/media/src/android/media/cts/MediaBrowserServiceTest.java
index 02bdd7f..d9e6816 100644
--- a/tests/tests/media/src/android/media/cts/MediaBrowserServiceTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaBrowserServiceTest.java
@@ -33,7 +33,7 @@
     private static final long TIME_OUT_MS = 3000L;
     private static final long WAIT_TIME_FOR_NO_RESPONSE_MS = 500L;
     private static final ComponentName TEST_BROWSER_SERVICE = new ComponentName(
-            "com.android.cts.media", "android.media.cts.StubMediaBrowserService");
+            "android.media.cts", "android.media.cts.StubMediaBrowserService");
     private final Object mWaitLock = new Object();
 
     private final MediaBrowser.ConnectionCallback mConnectionCallback =
@@ -47,7 +47,7 @@
         }
     };
 
-    private final MediaBrowser.SubscriptionCallback mSubscriptionCallback  =
+    private final MediaBrowser.SubscriptionCallback mSubscriptionCallback =
             new MediaBrowser.SubscriptionCallback() {
             @Override
             public void onChildrenLoaded(String parentId, List<MediaItem> children) {
@@ -56,10 +56,18 @@
                     mWaitLock.notify();
                 }
             }
+
+            @Override
+            public void onChildrenLoaded(String parentId, List<MediaItem> children,
+                    Bundle options) {
+                synchronized (mWaitLock) {
+                    mOnChildrenLoadedWithOptions = true;
+                    mWaitLock.notify();
+                }
+            }
         };
 
-    private final MediaBrowser.ItemCallback mItemCallback  =
-            new MediaBrowser.ItemCallback() {
+    private final MediaBrowser.ItemCallback mItemCallback = new MediaBrowser.ItemCallback() {
         @Override
         public void onItemLoaded(MediaItem item) {
             synchronized (mWaitLock) {
@@ -72,6 +80,7 @@
     private MediaBrowser mMediaBrowser;
     private StubMediaBrowserService mMediaBrowserService;
     private boolean mOnChildrenLoaded;
+    private boolean mOnChildrenLoadedWithOptions;
     private boolean mOnItemLoaded;
 
     @Override
@@ -108,6 +117,26 @@
         }
     }
 
+    public void testNotifyChildrenChangedWithPagination() throws Exception {
+        synchronized (mWaitLock) {
+            final int pageSize = 5;
+            final int page = 2;
+            Bundle options = new Bundle();
+            options.putInt(MediaBrowser.EXTRA_PAGE_SIZE, pageSize);
+            options.putInt(MediaBrowser.EXTRA_PAGE, page);
+
+            mMediaBrowser.subscribe(StubMediaBrowserService.MEDIA_ID_ROOT, options,
+                    mSubscriptionCallback);
+            mWaitLock.wait(TIME_OUT_MS);
+            assertTrue(mOnChildrenLoadedWithOptions);
+
+            mOnChildrenLoadedWithOptions = false;
+            mMediaBrowserService.notifyChildrenChanged(StubMediaBrowserService.MEDIA_ID_ROOT);
+            mWaitLock.wait(TIME_OUT_MS);
+            assertTrue(mOnChildrenLoadedWithOptions);
+        }
+    }
+
     public void testDelayedNotifyChildrenChanged() throws Exception {
         synchronized (mWaitLock) {
             mOnChildrenLoaded = false;
diff --git a/tests/tests/media/src/android/media/cts/MediaBrowserTest.java b/tests/tests/media/src/android/media/cts/MediaBrowserTest.java
index 7dd978f..23f464e 100644
--- a/tests/tests/media/src/android/media/cts/MediaBrowserTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaBrowserTest.java
@@ -19,6 +19,7 @@
 import android.cts.util.PollingCheck;
 import android.media.browse.MediaBrowser;
 import android.media.browse.MediaBrowser.MediaItem;
+import android.os.Bundle;
 import android.test.InstrumentationTestCase;
 
 import java.util.List;
@@ -30,7 +31,7 @@
     // The maximum time to wait for an operation.
     private static final long TIME_OUT_MS = 3000L;
     private static final ComponentName TEST_BROWSER_SERVICE = new ComponentName(
-            "com.android.cts.media", "android.media.cts.StubMediaBrowserService");
+            "android.media.cts", "android.media.cts.StubMediaBrowserService");
     private static final ComponentName TEST_INVALID_BROWSER_SERVICE = new ComponentName(
             "invalid.package", "invalid.ServiceClassName");
     private final StubConnectionCallback mConnectionCallback = new StubConnectionCallback();
@@ -111,12 +112,86 @@
         assertEquals(StubMediaBrowserService.MEDIA_ID_ROOT, mSubscriptionCallback.mLastParentId);
         assertEquals(StubMediaBrowserService.MEDIA_ID_CHILDREN.length,
                 mSubscriptionCallback.mLastChildMediaItems.size());
-        for (int i = 0; i < StubMediaBrowserService.MEDIA_ID_CHILDREN.length; i++) {
+        for (int i = 0; i < StubMediaBrowserService.MEDIA_ID_CHILDREN.length; ++i) {
             assertEquals(StubMediaBrowserService.MEDIA_ID_CHILDREN[i],
                     mSubscriptionCallback.mLastChildMediaItems.get(i).getMediaId());
         }
     }
 
+    public void testSubscribeWithOptions() {
+        createMediaBrowser(TEST_BROWSER_SERVICE);
+        connectMediaBrowserService();
+        final int pageSize = 3;
+        final int lastPage = (StubMediaBrowserService.MEDIA_ID_CHILDREN.length - 1) / pageSize;
+        Bundle options = new Bundle();
+        options.putInt(MediaBrowser.EXTRA_PAGE_SIZE, pageSize);
+        for (int page = 0; page <= lastPage; ++page) {
+            resetCallbacks();
+            options.putInt(MediaBrowser.EXTRA_PAGE, page);
+            mMediaBrowser.subscribe(StubMediaBrowserService.MEDIA_ID_ROOT, options,
+                    mSubscriptionCallback);
+            new PollingCheck(TIME_OUT_MS) {
+                @Override
+                protected boolean check() {
+                    return mSubscriptionCallback.mChildrenLoadedWithOptionCount > 0;
+                }
+            }.run();
+            assertEquals(StubMediaBrowserService.MEDIA_ID_ROOT,
+                    mSubscriptionCallback.mLastParentId);
+            if (page != lastPage) {
+                assertEquals(pageSize, mSubscriptionCallback.mLastChildMediaItems.size());
+            } else {
+                assertEquals((StubMediaBrowserService.MEDIA_ID_CHILDREN.length - 1) % pageSize + 1,
+                        mSubscriptionCallback.mLastChildMediaItems.size());
+            }
+            // Check whether all the items in the current page are loaded.
+            for (int i = 0; i < mSubscriptionCallback.mLastChildMediaItems.size(); ++i) {
+                assertEquals(StubMediaBrowserService.MEDIA_ID_CHILDREN[page * pageSize + i],
+                        mSubscriptionCallback.mLastChildMediaItems.get(i).getMediaId());
+            }
+        }
+    }
+
+    public void testSubscribeInvalidItem() {
+        resetCallbacks();
+        createMediaBrowser(TEST_BROWSER_SERVICE);
+        connectMediaBrowserService();
+        mMediaBrowser.subscribe(StubMediaBrowserService.MEDIA_ID_INVALID, mSubscriptionCallback);
+        new PollingCheck(TIME_OUT_MS) {
+            @Override
+            protected boolean check() {
+                return mSubscriptionCallback.mLastErrorId != null;
+            }
+        }.run();
+
+        assertEquals(StubMediaBrowserService.MEDIA_ID_INVALID, mSubscriptionCallback.mLastErrorId);
+    }
+
+    public void testSubscribeInvalidItemWithOptions() {
+        resetCallbacks();
+        createMediaBrowser(TEST_BROWSER_SERVICE);
+        connectMediaBrowserService();
+
+        final int pageSize = 5;
+        final int page = 2;
+        Bundle options = new Bundle();
+        options.putInt(MediaBrowser.EXTRA_PAGE_SIZE, pageSize);
+        options.putInt(MediaBrowser.EXTRA_PAGE, page);
+        mMediaBrowser.subscribe(StubMediaBrowserService.MEDIA_ID_INVALID, options,
+                mSubscriptionCallback);
+        new PollingCheck(TIME_OUT_MS) {
+            @Override
+            protected boolean check() {
+                return mSubscriptionCallback.mLastErrorId != null;
+            }
+        }.run();
+
+        assertEquals(StubMediaBrowserService.MEDIA_ID_INVALID, mSubscriptionCallback.mLastErrorId);
+        assertEquals(page, mSubscriptionCallback.mLastOptions.getInt(MediaBrowser.EXTRA_PAGE));
+        assertEquals(pageSize,
+                mSubscriptionCallback.mLastOptions.getInt(MediaBrowser.EXTRA_PAGE_SIZE));
+    }
+
     public void testGetItem() {
         resetCallbacks();
         createMediaBrowser(TEST_BROWSER_SERVICE);
@@ -137,7 +212,7 @@
         resetCallbacks();
         createMediaBrowser(TEST_BROWSER_SERVICE);
         connectMediaBrowserService();
-        mMediaBrowser.getItem("does-not-exist", mItemCallback);
+        mMediaBrowser.getItem(StubMediaBrowserService.MEDIA_ID_INVALID, mItemCallback);
         new PollingCheck(TIME_OUT_MS) {
             @Override
             protected boolean check() {
@@ -145,7 +220,7 @@
             }
         }.run();
 
-        assertEquals("does-not-exist", mItemCallback.mLastErrorId);
+        assertEquals(StubMediaBrowserService.MEDIA_ID_INVALID, mItemCallback.mLastErrorId);
     }
 
     private void createMediaBrowser(final ComponentName component) {
@@ -203,14 +278,18 @@
 
     private static class StubSubscriptionCallback extends MediaBrowser.SubscriptionCallback {
         private volatile int mChildrenLoadedCount;
+        private volatile int mChildrenLoadedWithOptionCount;
         private volatile String mLastErrorId;
         private volatile String mLastParentId;
+        private volatile Bundle mLastOptions;
         private volatile List<MediaBrowser.MediaItem> mLastChildMediaItems;
 
         public void reset() {
             mChildrenLoadedCount = 0;
+            mChildrenLoadedWithOptionCount = 0;
             mLastErrorId = null;
             mLastParentId = null;
+            mLastOptions = null;
             mLastChildMediaItems = null;
         }
 
@@ -222,10 +301,25 @@
         }
 
         @Override
+        public void onChildrenLoaded(String parentId, List<MediaBrowser.MediaItem> children,
+                Bundle options) {
+            mChildrenLoadedWithOptionCount++;
+            mLastParentId = parentId;
+            mLastOptions = options;
+            mLastChildMediaItems = children;
+        }
+
+        @Override
         public void onError(String id) {
             mLastErrorId = id;
         }
-    }
+
+        @Override
+        public void onError(String id, Bundle options) {
+            mLastErrorId = id;
+            mLastOptions = options;
+        }
+}
 
     private static class StubItemCallback extends MediaBrowser.ItemCallback {
         private volatile MediaBrowser.MediaItem mLastMediaItem;
diff --git a/tests/tests/media/src/android/media/cts/MediaCodecCapabilitiesTest.java b/tests/tests/media/src/android/media/cts/MediaCodecCapabilitiesTest.java
index 71cbd61..5b2936b 100644
--- a/tests/tests/media/src/android/media/cts/MediaCodecCapabilitiesTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaCodecCapabilitiesTest.java
@@ -185,6 +185,7 @@
         if (!checkDecoder(MIMETYPE_VIDEO_AVC, AVCProfileBaseline, AVCLevel3)) {
             return; // skip
         }
+
         playVideoWithRetries("http://redirector.c.youtube.com/videoplayback?id=271de9756065677e"
                 + "&itag=18&source=youtube&user=android-device-test"
                 + "&sparams=ip,ipbits,expire,id,itag,source,user"
@@ -198,6 +199,7 @@
         if (!checkDecoder(MIMETYPE_VIDEO_AVC, AVCProfileHigh, AVCLevel31)) {
             return; // skip
         }
+
         playVideoWithRetries("http://redirector.c.youtube.com/videoplayback?id=271de9756065677e"
                 + "&itag=22&source=youtube&user=android-device-test"
                 + "&sparams=ip,ipbits,expire,id,itag,source,user"
@@ -215,6 +217,7 @@
             MediaUtils.skipTest(TAG, "fragmented mp4 not supported");
             return;
         }
+
         playVideoWithRetries("http://redirector.c.youtube.com/videoplayback?id=271de9756065677e"
                 + "&itag=137&source=youtube&user=android-device-test"
                 + "&sparams=ip,ipbits,expire,id,itag,source,user"
diff --git a/tests/tests/media/src/android/media/cts/MediaCodecCencPlayer.java b/tests/tests/media/src/android/media/cts/MediaCodecCencPlayer.java
deleted file mode 100644
index f5856ed..0000000
--- a/tests/tests/media/src/android/media/cts/MediaCodecCencPlayer.java
+++ /dev/null
@@ -1,539 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.media.cts;
-
-import android.media.AudioManager;
-import android.media.MediaCodec;
-import android.media.MediaCodecInfo;
-import android.media.MediaCodecList;
-import android.media.MediaCrypto;
-import android.media.MediaCryptoException;
-import android.media.MediaExtractor;
-import android.media.MediaFormat;
-import android.net.Uri;
-import android.util.Log;
-import android.view.SurfaceHolder;
-
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.UUID;
-
-/**
- * JB(API 16) introduces {@link MediaCodec} API.  It allows apps have more control over
- * media playback, pushes individual frames to decoder and supports decryption via
- * {@link MediaCrypto} API.
- *
- * {@link MediaDrm} can be used to obtain keys for decrypting protected media streams,
- * in conjunction with MediaCrypto.
- */
-public class MediaCodecCencPlayer implements MediaTimeProvider {
-    private static final String TAG = MediaCodecCencPlayer.class.getSimpleName();
-
-    private static final int STATE_IDLE = 1;
-    private static final int STATE_PREPARING = 2;
-    private static final int STATE_PLAYING = 3;
-    private static final int STATE_PAUSED = 4;
-
-    private static final UUID CLEARKEY_SCHEME_UUID =
-            new UUID(0x1077efecc0b24d02L, 0xace33c1e52e2fb4bL);
-
-    private boolean mEncryptedAudio;
-    private boolean mEncryptedVideo;
-    private volatile boolean mThreadStarted = false;
-    private byte[] mSessionId;
-    private CodecState mAudioTrackState;
-    private int mMediaFormatHeight;
-    private int mMediaFormatWidth;
-    private int mState;
-    private long mDeltaTimeUs;
-    private long mDurationUs;
-    private Map<Integer, CodecState> mAudioCodecStates;
-    private Map<Integer, CodecState> mVideoCodecStates;
-    private Map<String, String> mAudioHeaders;
-    private Map<String, String> mVideoHeaders;
-    private Map<UUID, byte[]> mPsshInitData;
-    private MediaCrypto mCrypto;
-    private MediaExtractor mAudioExtractor;
-    private MediaExtractor mVideoExtractor;
-    private SurfaceHolder mSurfaceHolder;
-    private Thread mThread;
-    private Uri mAudioUri;
-    private Uri mVideoUri;
-
-    private static final byte[] PSSH = hexStringToByteArray(
-            "0000003470737368" +  // BMFF box header (4 bytes size + 'pssh')
-            "01000000" +          // Full box header (version = 1 flags = 0)
-            "1077efecc0b24d02" +  // SystemID
-            "ace33c1e52e2fb4b" +
-            "00000001" +          // Number of key ids
-            "60061e017e477e87" +  // Key id
-            "7e57d00d1ed00d1e" +
-            "00000000"            // Size of Data, must be zero
-            );
-
-    /**
-     * Convert a hex string into byte array.
-     */
-    private static byte[] hexStringToByteArray(String s) {
-        int len = s.length();
-        byte[] data = new byte[len / 2];
-        for (int i = 0; i < len; i += 2) {
-            data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
-                    + Character.digit(s.charAt(i + 1), 16));
-        }
-        return data;
-    }
-
-    /*
-     * Media player class to stream CENC content using MediaCodec class.
-     */
-    public MediaCodecCencPlayer(SurfaceHolder holder, byte[] sessionId) {
-        mSessionId = sessionId;
-        mSurfaceHolder = holder;
-        mState = STATE_IDLE;
-        mThread = new Thread(new Runnable() {
-            @Override
-            public void run() {
-                while (mThreadStarted == true) {
-                    doSomeWork();
-                    if (mAudioTrackState != null) {
-                        mAudioTrackState.process();
-                    }
-                    try {
-                        Thread.sleep(5);
-                    } catch (InterruptedException ex) {
-                        Log.d(TAG, "Thread interrupted");
-                    }
-                }
-            }
-        });
-    }
-
-    public void setAudioDataSource(Uri uri, Map<String, String> headers, boolean encrypted) {
-        mAudioUri = uri;
-        mAudioHeaders = headers;
-        mEncryptedAudio = encrypted;
-    }
-
-    public void setVideoDataSource(Uri uri, Map<String, String> headers, boolean encrypted) {
-        mVideoUri = uri;
-        mVideoHeaders = headers;
-        mEncryptedVideo = encrypted;
-    }
-
-    public final int getMediaFormatHeight() {
-        return mMediaFormatHeight;
-    }
-
-    public final int getMediaFormatWidth() {
-        return mMediaFormatWidth;
-    }
-
-    public final Map<UUID, byte[]> getPsshInfo() {
-        // TODO (edwinwong@)
-        // Remove the if statement when we get content that has the clear key system id.
-        if (mPsshInitData == null ||
-                (mPsshInitData != null && !mPsshInitData.containsKey(CLEARKEY_SCHEME_UUID))) {
-            mPsshInitData = new HashMap<UUID, byte[]>();
-            mPsshInitData.put(CLEARKEY_SCHEME_UUID, PSSH);
-        }
-        return mPsshInitData;
-    }
-
-    private void prepareAudio() throws IOException {
-        boolean hasAudio = false;
-        for (int i = mAudioExtractor.getTrackCount(); i-- > 0;) {
-            MediaFormat format = mAudioExtractor.getTrackFormat(i);
-            String mime = format.getString(MediaFormat.KEY_MIME);
-
-            Log.d(TAG, "audio track #" + i + " " + format + " " + mime +
-                  " Is ADTS:" + getMediaFormatInteger(format, MediaFormat.KEY_IS_ADTS) +
-                  " Sample rate:" + getMediaFormatInteger(format, MediaFormat.KEY_SAMPLE_RATE) +
-                  " Channel count:" +
-                  getMediaFormatInteger(format, MediaFormat.KEY_CHANNEL_COUNT));
-
-            if (!hasAudio) {
-                mAudioExtractor.selectTrack(i);
-                addTrack(i, format, mEncryptedAudio);
-                hasAudio = true;
-
-                if (format.containsKey(MediaFormat.KEY_DURATION)) {
-                    long durationUs = format.getLong(MediaFormat.KEY_DURATION);
-
-                    if (durationUs > mDurationUs) {
-                        mDurationUs = durationUs;
-                    }
-                    Log.d(TAG, "audio track format #" + i +
-                            " Duration:" + mDurationUs + " microseconds");
-                }
-
-                if (hasAudio) {
-                    break;
-                }
-            }
-        }
-    }
-
-    private void prepareVideo() throws IOException {
-        boolean hasVideo = false;
-
-        for (int i = mVideoExtractor.getTrackCount(); i-- > 0;) {
-            MediaFormat format = mVideoExtractor.getTrackFormat(i);
-            String mime = format.getString(MediaFormat.KEY_MIME);
-
-            mMediaFormatHeight = getMediaFormatInteger(format, MediaFormat.KEY_HEIGHT);
-            mMediaFormatWidth = getMediaFormatInteger(format, MediaFormat.KEY_WIDTH);
-            Log.d(TAG, "video track #" + i + " " + format + " " + mime +
-                  " Width:" + mMediaFormatWidth + ", Height:" + mMediaFormatHeight);
-
-            if (!hasVideo) {
-                mVideoExtractor.selectTrack(i);
-                addTrack(i, format, mEncryptedVideo);
-
-                hasVideo = true;
-
-                if (format.containsKey(MediaFormat.KEY_DURATION)) {
-                    long durationUs = format.getLong(MediaFormat.KEY_DURATION);
-
-                    if (durationUs > mDurationUs) {
-                        mDurationUs = durationUs;
-                    }
-                    Log.d(TAG, "track format #" + i + " Duration:" +
-                            mDurationUs + " microseconds");
-                }
-
-                if (hasVideo) {
-                    break;
-                }
-            }
-        }
-        return;
-    }
-
-    public void prepare() throws IOException, MediaCryptoException {
-        if (null == mAudioExtractor) {
-            mAudioExtractor = new MediaExtractor();
-            if (null == mAudioExtractor) {
-                Log.e(TAG, "Cannot create Audio extractor.");
-                return;
-            }
-        }
-
-        if (null == mVideoExtractor){
-            mVideoExtractor = new MediaExtractor();
-            if (null == mVideoExtractor) {
-                Log.e(TAG, "Cannot create Video extractor.");
-                return;
-            }
-        }
-
-        mAudioExtractor.setDataSource(mAudioUri.toString(), mAudioHeaders);
-        mVideoExtractor.setDataSource(mVideoUri.toString(), mVideoHeaders);
-        mPsshInitData = mVideoExtractor.getPsshInfo();
-
-        if (null == mCrypto && (mEncryptedVideo || mEncryptedAudio)) {
-            try {
-                byte[] initData = new byte[0];
-                mCrypto = new MediaCrypto(CLEARKEY_SCHEME_UUID, initData);
-            } catch (MediaCryptoException e) {
-                reset();
-                Log.e(TAG, "Failed to create MediaCrypto instance.");
-                throw e;
-            }
-            mCrypto.setMediaDrmSession(mSessionId);
-        } else {
-            reset();
-            mCrypto.release();
-            mCrypto = null;
-        }
-
-        if (null == mVideoCodecStates) {
-            mVideoCodecStates = new HashMap<Integer, CodecState>();
-        } else {
-            mVideoCodecStates.clear();
-        }
-
-        if (null == mAudioCodecStates) {
-            mAudioCodecStates = new HashMap<Integer, CodecState>();
-        } else {
-            mAudioCodecStates.clear();
-        }
-
-        prepareVideo();
-        prepareAudio();
-
-        mState = STATE_PAUSED;
-    }
-
-    private void addTrack(int trackIndex, MediaFormat format,
-            boolean encrypted) throws IOException {
-        String mime = format.getString(MediaFormat.KEY_MIME);
-        boolean isVideo = mime.startsWith("video/");
-        boolean isAudio = mime.startsWith("audio/");
-
-        MediaCodec codec;
-
-        if (encrypted && mCrypto.requiresSecureDecoderComponent(mime)) {
-            codec = MediaCodec.createByCodecName(
-                    getSecureDecoderNameForMime(mime));
-        } else {
-            codec = MediaCodec.createDecoderByType(mime);
-        }
-
-        codec.configure(
-                format,
-                isVideo ? mSurfaceHolder.getSurface() : null,
-                mCrypto,
-                0);
-
-        CodecState state;
-        if (isVideo) {
-            state = new CodecState((MediaTimeProvider)this, mVideoExtractor,
-                            trackIndex, format, codec, true, false,
-                            AudioManager.AUDIO_SESSION_ID_GENERATE);
-            mVideoCodecStates.put(Integer.valueOf(trackIndex), state);
-        } else {
-            state = new CodecState((MediaTimeProvider)this, mAudioExtractor,
-                            trackIndex, format, codec, true, false,
-                            AudioManager.AUDIO_SESSION_ID_GENERATE);
-            mAudioCodecStates.put(Integer.valueOf(trackIndex), state);
-        }
-
-        if (isAudio) {
-            mAudioTrackState = state;
-        }
-    }
-
-    protected int getMediaFormatInteger(MediaFormat format, String key) {
-        return format.containsKey(key) ? format.getInteger(key) : 0;
-    }
-
-    protected String getSecureDecoderNameForMime(String mime) {
-        int n = MediaCodecList.getCodecCount();
-        for (int i = 0; i < n; ++i) {
-            MediaCodecInfo info = MediaCodecList.getCodecInfoAt(i);
-
-            if (info.isEncoder()) {
-                continue;
-            }
-
-            String[] supportedTypes = info.getSupportedTypes();
-
-            for (int j = 0; j < supportedTypes.length; ++j) {
-                if (supportedTypes[j].equalsIgnoreCase(mime)) {
-                    return info.getName() + ".secure";
-                }
-            }
-        }
-        return null;
-    }
-
-    public void start() {
-        Log.d(TAG, "start");
-
-        if (mState == STATE_PLAYING || mState == STATE_PREPARING) {
-            return;
-        } else if (mState == STATE_IDLE) {
-            mState = STATE_PREPARING;
-            return;
-        } else if (mState != STATE_PAUSED) {
-            throw new IllegalStateException();
-        }
-
-        for (CodecState state : mVideoCodecStates.values()) {
-            state.start();
-        }
-
-        for (CodecState state : mAudioCodecStates.values()) {
-            state.start();
-        }
-
-        mDeltaTimeUs = -1;
-        mState = STATE_PLAYING;
-    }
-
-    public void startWork() throws IOException, MediaCryptoException, Exception {
-        try {
-            // Just change state from STATE_IDLE to STATE_PREPARING.
-            start();
-            // Extract media information from uri asset, and change state to STATE_PAUSED.
-            prepare();
-            // Start CodecState, and change from STATE_PAUSED to STATE_PLAYING.
-            start();
-        } catch (IOException e) {
-            throw e;
-        } catch (MediaCryptoException e) {
-            throw e;
-        }
-
-        mThreadStarted = true;
-        mThread.start();
-    }
-
-    public void startThread() {
-        start();
-        mThreadStarted = true;
-        mThread.start();
-    }
-
-    public void pause() {
-        Log.d(TAG, "pause");
-
-        if (mState == STATE_PAUSED) {
-            return;
-        } else if (mState != STATE_PLAYING) {
-            throw new IllegalStateException();
-        }
-
-        for (CodecState state : mVideoCodecStates.values()) {
-            state.pause();
-        }
-
-        for (CodecState state : mAudioCodecStates.values()) {
-            state.pause();
-        }
-
-        mState = STATE_PAUSED;
-    }
-
-    public void reset() {
-        if (mState == STATE_PLAYING) {
-            mThreadStarted = false;
-
-            try {
-                mThread.join();
-            } catch (InterruptedException ex) {
-                Log.d(TAG, "mThread.join " + ex);
-            }
-
-            pause();
-        }
-
-        if (mVideoCodecStates != null) {
-            for (CodecState state : mVideoCodecStates.values()) {
-                state.release();
-            }
-            mVideoCodecStates = null;
-        }
-
-        if (mAudioCodecStates != null) {
-            for (CodecState state : mAudioCodecStates.values()) {
-                state.release();
-            }
-            mAudioCodecStates = null;
-        }
-
-        if (mAudioExtractor != null) {
-            mAudioExtractor.release();
-            mAudioExtractor = null;
-        }
-
-        if (mVideoExtractor != null) {
-            mVideoExtractor.release();
-            mVideoExtractor = null;
-        }
-
-        if (mCrypto != null) {
-            mCrypto.release();
-            mCrypto = null;
-        }
-
-        mDurationUs = -1;
-        mState = STATE_IDLE;
-    }
-
-    public boolean isEnded() {
-        for (CodecState state : mVideoCodecStates.values()) {
-          if (!state.isEnded()) {
-            return false;
-          }
-        }
-
-        for (CodecState state : mAudioCodecStates.values()) {
-            if (!state.isEnded()) {
-              return false;
-            }
-        }
-
-        return true;
-    }
-
-    private void doSomeWork() {
-        try {
-            for (CodecState state : mVideoCodecStates.values()) {
-                state.doSomeWork();
-            }
-        } catch (MediaCodec.CryptoException e) {
-            throw new Error("Video CryptoException w/ errorCode "
-                    + e.getErrorCode() + ", '" + e.getMessage() + "'");
-        } catch (IllegalStateException e) {
-            throw new Error("Video CodecState.feedInputBuffer IllegalStateException " + e);
-        }
-
-        try {
-            for (CodecState state : mAudioCodecStates.values()) {
-                state.doSomeWork();
-            }
-        } catch (MediaCodec.CryptoException e) {
-            throw new Error("Audio CryptoException w/ errorCode "
-                    + e.getErrorCode() + ", '" + e.getMessage() + "'");
-        } catch (IllegalStateException e) {
-            throw new Error("Aduio CodecState.feedInputBuffer IllegalStateException " + e);
-        }
-
-    }
-
-    public long getNowUs() {
-        if (mAudioTrackState == null) {
-            return System.currentTimeMillis() * 1000;
-        }
-
-        return mAudioTrackState.getAudioTimeUs();
-    }
-
-    public long getRealTimeUsForMediaTime(long mediaTimeUs) {
-        if (mDeltaTimeUs == -1) {
-            long nowUs = getNowUs();
-            mDeltaTimeUs = nowUs - mediaTimeUs;
-        }
-
-        return mDeltaTimeUs + mediaTimeUs;
-    }
-
-    public int getDuration() {
-        return (int)((mDurationUs + 500) / 1000);
-    }
-
-    public int getCurrentPosition() {
-        if (mVideoCodecStates == null) {
-                return 0;
-        }
-
-        long positionUs = 0;
-
-        for (CodecState state : mVideoCodecStates.values()) {
-            long trackPositionUs = state.getCurrentPositionUs();
-
-            if (trackPositionUs > positionUs) {
-                positionUs = trackPositionUs;
-            }
-        }
-        return (int)((positionUs + 500) / 1000);
-    }
-
-}
diff --git a/tests/tests/media/src/android/media/cts/MediaCodecClearKeyPlayer.java b/tests/tests/media/src/android/media/cts/MediaCodecClearKeyPlayer.java
new file mode 100644
index 0000000..1d95463
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/MediaCodecClearKeyPlayer.java
@@ -0,0 +1,569 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.media.cts;
+
+import android.content.res.Resources;
+import android.content.res.AssetFileDescriptor;
+import android.media.AudioManager;
+import android.media.DrmInitData;
+import android.media.MediaCodec;
+import android.media.MediaCodecInfo;
+import android.media.MediaCodecList;
+import android.media.MediaCrypto;
+import android.media.MediaCryptoException;
+import android.media.MediaExtractor;
+import android.media.MediaFormat;
+import android.net.Uri;
+import android.util.Log;
+import android.view.SurfaceHolder;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+/**
+ * JB(API 16) introduces {@link MediaCodec} API.  It allows apps have more control over
+ * media playback, pushes individual frames to decoder and supports decryption via
+ * {@link MediaCrypto} API.
+ *
+ * {@link MediaDrm} can be used to obtain keys for decrypting protected media streams,
+ * in conjunction with MediaCrypto.
+ */
+public class MediaCodecClearKeyPlayer implements MediaTimeProvider {
+    private static final String TAG = MediaCodecClearKeyPlayer.class.getSimpleName();
+
+    private static final int STATE_IDLE = 1;
+    private static final int STATE_PREPARING = 2;
+    private static final int STATE_PLAYING = 3;
+    private static final int STATE_PAUSED = 4;
+
+    private static final UUID CLEARKEY_SCHEME_UUID =
+            new UUID(0x1077efecc0b24d02L, 0xace33c1e52e2fb4bL);
+
+    private boolean mEncryptedAudio;
+    private boolean mEncryptedVideo;
+    private volatile boolean mThreadStarted = false;
+    private byte[] mSessionId;
+    private CodecState mAudioTrackState;
+    private int mMediaFormatHeight;
+    private int mMediaFormatWidth;
+    private int mState;
+    private long mDeltaTimeUs;
+    private long mDurationUs;
+    private Map<Integer, CodecState> mAudioCodecStates;
+    private Map<Integer, CodecState> mVideoCodecStates;
+    private Map<String, String> mAudioHeaders;
+    private Map<String, String> mVideoHeaders;
+    private Map<UUID, byte[]> mPsshInitData;
+    private MediaCrypto mCrypto;
+    private MediaExtractor mAudioExtractor;
+    private MediaExtractor mVideoExtractor;
+    private SurfaceHolder mSurfaceHolder;
+    private Thread mThread;
+    private Uri mAudioUri;
+    private Uri mVideoUri;
+    private Resources mResources;
+
+    private static final byte[] PSSH = hexStringToByteArray(
+            "0000003470737368" +  // BMFF box header (4 bytes size + 'pssh')
+            "01000000" +          // Full box header (version = 1 flags = 0)
+            "1077efecc0b24d02" +  // SystemID
+            "ace33c1e52e2fb4b" +
+            "00000001" +          // Number of key ids
+            "60061e017e477e87" +  // Key id
+            "7e57d00d1ed00d1e" +
+            "00000000"            // Size of Data, must be zero
+            );
+
+    /**
+     * Convert a hex string into byte array.
+     */
+    private static byte[] hexStringToByteArray(String s) {
+        int len = s.length();
+        byte[] data = new byte[len / 2];
+        for (int i = 0; i < len; i += 2) {
+            data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+                    + Character.digit(s.charAt(i + 1), 16));
+        }
+        return data;
+    }
+
+    /*
+     * Media player class to stream CENC content using MediaCodec class.
+     */
+    public MediaCodecClearKeyPlayer(
+            SurfaceHolder holder, byte[] sessionId, Resources resources) {
+        mSessionId = sessionId;
+        mSurfaceHolder = holder;
+        mResources = resources;
+        mState = STATE_IDLE;
+        mThread = new Thread(new Runnable() {
+            @Override
+            public void run() {
+                while (mThreadStarted == true) {
+                    doSomeWork();
+                    if (mAudioTrackState != null) {
+                        mAudioTrackState.process();
+                    }
+                    try {
+                        Thread.sleep(5);
+                    } catch (InterruptedException ex) {
+                        Log.d(TAG, "Thread interrupted");
+                    }
+                }
+            }
+        });
+    }
+
+    public void setAudioDataSource(Uri uri, Map<String, String> headers, boolean encrypted) {
+        mAudioUri = uri;
+        mAudioHeaders = headers;
+        mEncryptedAudio = encrypted;
+    }
+
+    public void setVideoDataSource(Uri uri, Map<String, String> headers, boolean encrypted) {
+        mVideoUri = uri;
+        mVideoHeaders = headers;
+        mEncryptedVideo = encrypted;
+    }
+
+    public final int getMediaFormatHeight() {
+        return mMediaFormatHeight;
+    }
+
+    public final int getMediaFormatWidth() {
+        return mMediaFormatWidth;
+    }
+
+    public final byte[] getDrmInitData() {
+        for (MediaExtractor ex: new MediaExtractor[] {mVideoExtractor, mAudioExtractor}) {
+            DrmInitData drmInitData = ex.getDrmInitData();
+            if (drmInitData != null) {
+                DrmInitData.SchemeInitData schemeInitData = drmInitData.get(CLEARKEY_SCHEME_UUID);
+                if (schemeInitData != null && schemeInitData.data != null) {
+                    return schemeInitData.data;
+                }
+            }
+        }
+        // TODO
+        // Should not happen after we get content that has the clear key system id.
+        return PSSH;
+    }
+
+    private void prepareAudio() throws IOException {
+        boolean hasAudio = false;
+        for (int i = mAudioExtractor.getTrackCount(); i-- > 0;) {
+            MediaFormat format = mAudioExtractor.getTrackFormat(i);
+            String mime = format.getString(MediaFormat.KEY_MIME);
+            if (!mime.startsWith("audio/")) {
+                continue;
+            }
+
+            Log.d(TAG, "audio track #" + i + " " + format + " " + mime +
+                  " Is ADTS:" + getMediaFormatInteger(format, MediaFormat.KEY_IS_ADTS) +
+                  " Sample rate:" + getMediaFormatInteger(format, MediaFormat.KEY_SAMPLE_RATE) +
+                  " Channel count:" +
+                  getMediaFormatInteger(format, MediaFormat.KEY_CHANNEL_COUNT));
+
+            if (!hasAudio) {
+                mAudioExtractor.selectTrack(i);
+                addTrack(i, format, mEncryptedAudio);
+                hasAudio = true;
+
+                if (format.containsKey(MediaFormat.KEY_DURATION)) {
+                    long durationUs = format.getLong(MediaFormat.KEY_DURATION);
+
+                    if (durationUs > mDurationUs) {
+                        mDurationUs = durationUs;
+                    }
+                    Log.d(TAG, "audio track format #" + i +
+                            " Duration:" + mDurationUs + " microseconds");
+                }
+
+                if (hasAudio) {
+                    break;
+                }
+            }
+        }
+    }
+
+    private void prepareVideo() throws IOException {
+        boolean hasVideo = false;
+
+        for (int i = mVideoExtractor.getTrackCount(); i-- > 0;) {
+            MediaFormat format = mVideoExtractor.getTrackFormat(i);
+            String mime = format.getString(MediaFormat.KEY_MIME);
+            if (!mime.startsWith("video/")) {
+                continue;
+            }
+
+            mMediaFormatHeight = getMediaFormatInteger(format, MediaFormat.KEY_HEIGHT);
+            mMediaFormatWidth = getMediaFormatInteger(format, MediaFormat.KEY_WIDTH);
+            Log.d(TAG, "video track #" + i + " " + format + " " + mime +
+                  " Width:" + mMediaFormatWidth + ", Height:" + mMediaFormatHeight);
+
+            if (!hasVideo) {
+                mVideoExtractor.selectTrack(i);
+                addTrack(i, format, mEncryptedVideo);
+
+                hasVideo = true;
+
+                if (format.containsKey(MediaFormat.KEY_DURATION)) {
+                    long durationUs = format.getLong(MediaFormat.KEY_DURATION);
+
+                    if (durationUs > mDurationUs) {
+                        mDurationUs = durationUs;
+                    }
+                    Log.d(TAG, "track format #" + i + " Duration:" +
+                            mDurationUs + " microseconds");
+                }
+
+                if (hasVideo) {
+                    break;
+                }
+            }
+        }
+        return;
+    }
+
+    private void setDataSource(MediaExtractor extractor, Uri uri, Map<String, String> headers)
+            throws IOException {
+        String scheme = uri.getScheme();
+        if (scheme.startsWith("http")) {
+            extractor.setDataSource(uri.toString(), headers);
+        } else if (scheme.equals("android.resource")) {
+            int res = Integer.parseInt(uri.getLastPathSegment());
+            AssetFileDescriptor fd = mResources.openRawResourceFd(res);
+            extractor.setDataSource(fd.getFileDescriptor(), fd.getStartOffset(), fd.getLength());
+        } else {
+            throw new IllegalArgumentException(uri.toString());
+        }
+    }
+
+    public void prepare() throws IOException, MediaCryptoException {
+        if (null == mAudioExtractor) {
+            mAudioExtractor = new MediaExtractor();
+            if (null == mAudioExtractor) {
+                Log.e(TAG, "Cannot create Audio extractor.");
+                return;
+            }
+        }
+
+        if (null == mVideoExtractor){
+            mVideoExtractor = new MediaExtractor();
+            if (null == mVideoExtractor) {
+                Log.e(TAG, "Cannot create Video extractor.");
+                return;
+            }
+        }
+
+        setDataSource(mAudioExtractor, mAudioUri, mAudioHeaders);
+        setDataSource(mVideoExtractor, mVideoUri, mVideoHeaders);
+
+        if (null == mCrypto && (mEncryptedVideo || mEncryptedAudio)) {
+            try {
+                byte[] initData = new byte[0];
+                mCrypto = new MediaCrypto(CLEARKEY_SCHEME_UUID, initData);
+            } catch (MediaCryptoException e) {
+                reset();
+                Log.e(TAG, "Failed to create MediaCrypto instance.");
+                throw e;
+            }
+            mCrypto.setMediaDrmSession(mSessionId);
+        } else {
+            reset();
+            mCrypto.release();
+            mCrypto = null;
+        }
+
+        if (null == mVideoCodecStates) {
+            mVideoCodecStates = new HashMap<Integer, CodecState>();
+        } else {
+            mVideoCodecStates.clear();
+        }
+
+        if (null == mAudioCodecStates) {
+            mAudioCodecStates = new HashMap<Integer, CodecState>();
+        } else {
+            mAudioCodecStates.clear();
+        }
+
+        prepareVideo();
+        prepareAudio();
+
+        mState = STATE_PAUSED;
+    }
+
+    private void addTrack(int trackIndex, MediaFormat format,
+            boolean encrypted) throws IOException {
+        String mime = format.getString(MediaFormat.KEY_MIME);
+        boolean isVideo = mime.startsWith("video/");
+        boolean isAudio = mime.startsWith("audio/");
+
+        MediaCodec codec;
+
+        if (encrypted && mCrypto.requiresSecureDecoderComponent(mime)) {
+            codec = MediaCodec.createByCodecName(
+                    getSecureDecoderNameForMime(mime));
+        } else {
+            codec = MediaCodec.createDecoderByType(mime);
+        }
+
+        codec.configure(
+                format,
+                isVideo ? mSurfaceHolder.getSurface() : null,
+                mCrypto,
+                0);
+
+        CodecState state;
+        if (isVideo) {
+            state = new CodecState((MediaTimeProvider)this, mVideoExtractor,
+                            trackIndex, format, codec, true, false,
+                            AudioManager.AUDIO_SESSION_ID_GENERATE);
+            mVideoCodecStates.put(Integer.valueOf(trackIndex), state);
+        } else {
+            state = new CodecState((MediaTimeProvider)this, mAudioExtractor,
+                            trackIndex, format, codec, true, false,
+                            AudioManager.AUDIO_SESSION_ID_GENERATE);
+            mAudioCodecStates.put(Integer.valueOf(trackIndex), state);
+        }
+
+        if (isAudio) {
+            mAudioTrackState = state;
+        }
+    }
+
+    protected int getMediaFormatInteger(MediaFormat format, String key) {
+        return format.containsKey(key) ? format.getInteger(key) : 0;
+    }
+
+    protected String getSecureDecoderNameForMime(String mime) {
+        int n = MediaCodecList.getCodecCount();
+        for (int i = 0; i < n; ++i) {
+            MediaCodecInfo info = MediaCodecList.getCodecInfoAt(i);
+
+            if (info.isEncoder()) {
+                continue;
+            }
+
+            String[] supportedTypes = info.getSupportedTypes();
+
+            for (int j = 0; j < supportedTypes.length; ++j) {
+                if (supportedTypes[j].equalsIgnoreCase(mime)) {
+                    return info.getName() + ".secure";
+                }
+            }
+        }
+        return null;
+    }
+
+    public void start() {
+        Log.d(TAG, "start");
+
+        if (mState == STATE_PLAYING || mState == STATE_PREPARING) {
+            return;
+        } else if (mState == STATE_IDLE) {
+            mState = STATE_PREPARING;
+            return;
+        } else if (mState != STATE_PAUSED) {
+            throw new IllegalStateException();
+        }
+
+        for (CodecState state : mVideoCodecStates.values()) {
+            state.start();
+        }
+
+        for (CodecState state : mAudioCodecStates.values()) {
+            state.start();
+        }
+
+        mDeltaTimeUs = -1;
+        mState = STATE_PLAYING;
+    }
+
+    public void startWork() throws IOException, MediaCryptoException, Exception {
+        try {
+            // Just change state from STATE_IDLE to STATE_PREPARING.
+            start();
+            // Extract media information from uri asset, and change state to STATE_PAUSED.
+            prepare();
+            // Start CodecState, and change from STATE_PAUSED to STATE_PLAYING.
+            start();
+        } catch (IOException e) {
+            throw e;
+        } catch (MediaCryptoException e) {
+            throw e;
+        }
+
+        mThreadStarted = true;
+        mThread.start();
+    }
+
+    public void startThread() {
+        start();
+        mThreadStarted = true;
+        mThread.start();
+    }
+
+    public void pause() {
+        Log.d(TAG, "pause");
+
+        if (mState == STATE_PAUSED) {
+            return;
+        } else if (mState != STATE_PLAYING) {
+            throw new IllegalStateException();
+        }
+
+        for (CodecState state : mVideoCodecStates.values()) {
+            state.pause();
+        }
+
+        for (CodecState state : mAudioCodecStates.values()) {
+            state.pause();
+        }
+
+        mState = STATE_PAUSED;
+    }
+
+    public void reset() {
+        if (mState == STATE_PLAYING) {
+            mThreadStarted = false;
+
+            try {
+                mThread.join();
+            } catch (InterruptedException ex) {
+                Log.d(TAG, "mThread.join " + ex);
+            }
+
+            pause();
+        }
+
+        if (mVideoCodecStates != null) {
+            for (CodecState state : mVideoCodecStates.values()) {
+                state.release();
+            }
+            mVideoCodecStates = null;
+        }
+
+        if (mAudioCodecStates != null) {
+            for (CodecState state : mAudioCodecStates.values()) {
+                state.release();
+            }
+            mAudioCodecStates = null;
+        }
+
+        if (mAudioExtractor != null) {
+            mAudioExtractor.release();
+            mAudioExtractor = null;
+        }
+
+        if (mVideoExtractor != null) {
+            mVideoExtractor.release();
+            mVideoExtractor = null;
+        }
+
+        if (mCrypto != null) {
+            mCrypto.release();
+            mCrypto = null;
+        }
+
+        mDurationUs = -1;
+        mState = STATE_IDLE;
+    }
+
+    public boolean isEnded() {
+        for (CodecState state : mVideoCodecStates.values()) {
+          if (!state.isEnded()) {
+            return false;
+          }
+        }
+
+        for (CodecState state : mAudioCodecStates.values()) {
+            if (!state.isEnded()) {
+              return false;
+            }
+        }
+
+        return true;
+    }
+
+    private void doSomeWork() {
+        try {
+            for (CodecState state : mVideoCodecStates.values()) {
+                state.doSomeWork();
+            }
+        } catch (MediaCodec.CryptoException e) {
+            throw new Error("Video CryptoException w/ errorCode "
+                    + e.getErrorCode() + ", '" + e.getMessage() + "'");
+        } catch (IllegalStateException e) {
+            throw new Error("Video CodecState.feedInputBuffer IllegalStateException " + e);
+        }
+
+        try {
+            for (CodecState state : mAudioCodecStates.values()) {
+                state.doSomeWork();
+            }
+        } catch (MediaCodec.CryptoException e) {
+            throw new Error("Audio CryptoException w/ errorCode "
+                    + e.getErrorCode() + ", '" + e.getMessage() + "'");
+        } catch (IllegalStateException e) {
+            throw new Error("Aduio CodecState.feedInputBuffer IllegalStateException " + e);
+        }
+
+    }
+
+    public long getNowUs() {
+        if (mAudioTrackState == null) {
+            return System.currentTimeMillis() * 1000;
+        }
+
+        return mAudioTrackState.getAudioTimeUs();
+    }
+
+    public long getRealTimeUsForMediaTime(long mediaTimeUs) {
+        if (mDeltaTimeUs == -1) {
+            long nowUs = getNowUs();
+            mDeltaTimeUs = nowUs - mediaTimeUs;
+        }
+
+        return mDeltaTimeUs + mediaTimeUs;
+    }
+
+    public int getDuration() {
+        return (int)((mDurationUs + 500) / 1000);
+    }
+
+    public int getCurrentPosition() {
+        if (mVideoCodecStates == null) {
+                return 0;
+        }
+
+        long positionUs = 0;
+
+        for (CodecState state : mVideoCodecStates.values()) {
+            long trackPositionUs = state.getCurrentPositionUs();
+
+            if (trackPositionUs > positionUs) {
+                positionUs = trackPositionUs;
+            }
+        }
+        return (int)((positionUs + 500) / 1000);
+    }
+
+}
diff --git a/tests/tests/media/src/android/media/cts/MediaCodecListTest.java b/tests/tests/media/src/android/media/cts/MediaCodecListTest.java
index 9442d09..a88f133 100644
--- a/tests/tests/media/src/android/media/cts/MediaCodecListTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaCodecListTest.java
@@ -400,4 +400,39 @@
 
         return list;
     }
+
+    public void testFindDecoderWithAacProfile() throws Exception {
+        Log.d(TAG, "testFindDecoderWithAacProfile");
+        MediaFormat format = MediaFormat.createAudioFormat(
+                MediaFormat.MIMETYPE_AUDIO_AAC, 8000, 1);
+        List<Integer> profiles = new ArrayList<>();
+        profiles.add(MediaCodecInfo.CodecProfileLevel.AACObjectLC);
+        profiles.add(MediaCodecInfo.CodecProfileLevel.AACObjectHE);
+        profiles.add(MediaCodecInfo.CodecProfileLevel.AACObjectHE_PS);
+        // The API is added at 5.0, so the profile below must be supported.
+        profiles.add(MediaCodecInfo.CodecProfileLevel.AACObjectELD);
+        for (int profile : profiles) {
+            format.setInteger(MediaFormat.KEY_AAC_PROFILE, profile);
+            String codecName = mRegularCodecs.findDecoderForFormat(format);
+            assertNotNull("Profile " + profile + " must be supported.", codecName);
+        }
+    }
+
+    public void testFindEncoderWithAacProfile() throws Exception {
+        Log.d(TAG, "testFindEncoderWithAacProfile");
+        MediaFormat format = MediaFormat.createAudioFormat(
+                MediaFormat.MIMETYPE_AUDIO_AAC, 8000, 1);
+        List<Integer> profiles = new ArrayList<>();
+        if (hasMicrophone() && !isWatch()) {
+            profiles.add(MediaCodecInfo.CodecProfileLevel.AACObjectLC);
+            // The API is added at 5.0, so the profiles below must be supported.
+            profiles.add(MediaCodecInfo.CodecProfileLevel.AACObjectHE);
+            profiles.add(MediaCodecInfo.CodecProfileLevel.AACObjectELD);
+        }
+        for (int profile : profiles) {
+            format.setInteger(MediaFormat.KEY_AAC_PROFILE, profile);
+            String codecName = mRegularCodecs.findEncoderForFormat(format);
+            assertNotNull("Profile " + profile + " must be supported.", codecName);
+        }
+    }
 }
diff --git a/tests/tests/media/src/android/media/cts/MediaCodecTest.java b/tests/tests/media/src/android/media/cts/MediaCodecTest.java
index d3ab54f..e3c258b 100644
--- a/tests/tests/media/src/android/media/cts/MediaCodecTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaCodecTest.java
@@ -16,13 +16,15 @@
 
 package android.media.cts;
 
-import com.android.cts.media.R;
+import android.media.cts.R;
 
 import android.content.res.AssetFileDescriptor;
 import android.cts.util.MediaUtils;
 import android.media.MediaCodec;
 import android.media.MediaCodec.BufferInfo;
 import android.media.MediaCodec.CodecException;
+import android.media.MediaCodec.CryptoInfo;
+import android.media.MediaCodec.CryptoInfo.Pattern;
 import android.media.MediaCodecInfo;
 import android.media.MediaCodecList;
 import android.media.MediaExtractor;
@@ -1245,6 +1247,25 @@
         public int mBitRate;
     };
 
+    public void testCryptoInfoPattern() {
+        CryptoInfo info = new CryptoInfo();
+        Pattern pattern = new Pattern(1 /*blocksToEncrypt*/, 2 /*blocksToSkip*/);
+        if (pattern.getEncryptBlocks() != 1) {
+            fail("Incorrect number of encrypt blocks in pattern");
+        }
+        if (pattern.getSkipBlocks() != 2) {
+            fail("Incorrect number of skip blocks in pattern");
+        }
+        pattern.set(3 /*blocksToEncrypt*/, 4 /*blocksToSkip*/);
+        if (pattern.getEncryptBlocks() != 3) {
+            fail("Incorrect number of encrypt blocks in pattern");
+        }
+        if (pattern.getSkipBlocks() != 4) {
+            fail("Incorrect number of skip blocks in pattern");
+        }
+        info.setPattern(pattern);
+    }
+
     private static CodecInfo getAvcSupportedFormatInfo() {
         MediaCodecInfo mediaCodecInfo = selectCodec(MIME_TYPE);
         CodecCapabilities cap = mediaCodecInfo.getCapabilitiesForType(MIME_TYPE);
diff --git a/tests/tests/media/src/android/media/cts/MediaControllerTest.java b/tests/tests/media/src/android/media/cts/MediaControllerTest.java
index caf2a94..b8ec617 100644
--- a/tests/tests/media/src/android/media/cts/MediaControllerTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaControllerTest.java
@@ -214,6 +214,32 @@
             mWaitLock.wait(TIME_OUT_MS);
             assertTrue(mCallback.mOnSkipToQueueItemCalled);
             assertEquals(queueItemId, mCallback.mQueueItemId);
+
+            mCallback.reset();
+            controls.prepare();
+            mWaitLock.wait(TIME_OUT_MS);
+            assertTrue(mCallback.mOnPrepareCalled);
+
+            mCallback.reset();
+            controls.prepareFromMediaId(mediaId, extras);
+            mWaitLock.wait(TIME_OUT_MS);
+            assertTrue(mCallback.mOnPrepareFromMediaIdCalled);
+            assertEquals(mediaId, mCallback.mMediaId);
+            assertEquals(EXTRAS_VALUE, mCallback.mExtras.getString(EXTRAS_KEY));
+
+            mCallback.reset();
+            controls.prepareFromSearch(query, extras);
+            mWaitLock.wait(TIME_OUT_MS);
+            assertTrue(mCallback.mOnPrepareFromSearchCalled);
+            assertEquals(query, mCallback.mQuery);
+            assertEquals(EXTRAS_VALUE, mCallback.mExtras.getString(EXTRAS_KEY));
+
+            mCallback.reset();
+            controls.prepareFromUri(uri, extras);
+            mWaitLock.wait(TIME_OUT_MS);
+            assertTrue(mCallback.mOnPrepareFromUriCalled);
+            assertEquals(uri, mCallback.mUri);
+            assertEquals(EXTRAS_VALUE, mCallback.mExtras.getString(EXTRAS_KEY));
         }
     }
 
@@ -244,6 +270,10 @@
         private boolean mOnPlayFromUriCalled;
         private boolean mOnCustomActionCalled;
         private boolean mOnCommandCalled;
+        private boolean mOnPrepareCalled;
+        private boolean mOnPrepareFromMediaIdCalled;
+        private boolean mOnPrepareFromSearchCalled;
+        private boolean mOnPrepareFromUriCalled;
 
         public void reset() {
             mSeekPosition = -1;
@@ -272,6 +302,10 @@
             mOnPlayFromUriCalled = false;
             mOnCustomActionCalled = false;
             mOnCommandCalled = false;
+            mOnPrepareCalled = false;
+            mOnPrepareFromMediaIdCalled = false;
+            mOnPrepareFromSearchCalled = false;
+            mOnPrepareFromUriCalled = false;
         }
 
         @Override
@@ -407,5 +441,43 @@
                 mWaitLock.notify();
             }
         }
+
+        @Override
+        public void onPrepare() {
+            synchronized (mWaitLock) {
+                mOnPrepareCalled = true;
+                mWaitLock.notify();
+            }
+        }
+
+        @Override
+        public void onPrepareFromMediaId(String mediaId, Bundle extras) {
+            synchronized (mWaitLock) {
+                mOnPrepareFromMediaIdCalled = true;
+                mMediaId = mediaId;
+                mExtras = extras;
+                mWaitLock.notify();
+            }
+        }
+
+        @Override
+        public void onPrepareFromSearch(String query, Bundle extras) {
+            synchronized (mWaitLock) {
+                mOnPrepareFromSearchCalled = true;
+                mQuery = query;
+                mExtras = extras;
+                mWaitLock.notify();
+            }
+        }
+
+        @Override
+        public void onPrepareFromUri(Uri uri, Bundle extras) {
+            synchronized (mWaitLock) {
+                mOnPrepareFromUriCalled = true;
+                mUri = uri;
+                mExtras = extras;
+                mWaitLock.notify();
+            }
+        }
     }
 }
diff --git a/tests/tests/media/src/android/media/cts/MediaExtractorTest.java b/tests/tests/media/src/android/media/cts/MediaExtractorTest.java
index 9db54ff..9958e26 100644
--- a/tests/tests/media/src/android/media/cts/MediaExtractorTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaExtractorTest.java
@@ -16,7 +16,7 @@
 
 package android.media.cts;
 
-import com.android.cts.media.R;
+import android.media.cts.R;
 
 import android.content.res.AssetFileDescriptor;
 import android.content.res.Resources;
diff --git a/tests/tests/media/src/android/media/cts/MediaMetadataRetrieverTest.java b/tests/tests/media/src/android/media/cts/MediaMetadataRetrieverTest.java
index 54e6ef1..751e3d8 100644
--- a/tests/tests/media/src/android/media/cts/MediaMetadataRetrieverTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaMetadataRetrieverTest.java
@@ -16,7 +16,7 @@
 
 package android.media.cts;
 
-import com.android.cts.media.R;
+import android.media.cts.R;
 
 import android.content.res.AssetFileDescriptor;
 import android.content.res.Resources;
diff --git a/tests/tests/media/src/android/media/cts/MediaMuxerTest.java b/tests/tests/media/src/android/media/cts/MediaMuxerTest.java
index 0f664a5..562feba 100644
--- a/tests/tests/media/src/android/media/cts/MediaMuxerTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaMuxerTest.java
@@ -27,7 +27,7 @@
 import android.test.AndroidTestCase;
 import android.util.Log;
 
-import com.android.cts.media.R;
+import android.media.cts.R;
 
 import java.io.File;
 import java.io.IOException;
diff --git a/tests/tests/media/src/android/media/cts/MediaPlayerFlakyNetworkTest.java b/tests/tests/media/src/android/media/cts/MediaPlayerFlakyNetworkTest.java
index 640083f..147bce4 100644
--- a/tests/tests/media/src/android/media/cts/MediaPlayerFlakyNetworkTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaPlayerFlakyNetworkTest.java
@@ -46,7 +46,7 @@
  * from an HTTP server over a simulated "flaky" network.
  */
 public class MediaPlayerFlakyNetworkTest extends MediaPlayerTestBase {
-    private static final String PKG = "com.android.cts.media";
+    private static final String PKG = "android.media.cts";
 
     private static final String[] TEST_VIDEOS = {
         "raw/video_480x360_mp4_h264_1350kbps_30fps_aac_stereo_192kbps_44100hz",
diff --git a/tests/tests/media/src/android/media/cts/MediaPlayerSurfaceStubActivity.java b/tests/tests/media/src/android/media/cts/MediaPlayerSurfaceStubActivity.java
index c47995c..779a808 100644
--- a/tests/tests/media/src/android/media/cts/MediaPlayerSurfaceStubActivity.java
+++ b/tests/tests/media/src/android/media/cts/MediaPlayerSurfaceStubActivity.java
@@ -15,7 +15,7 @@
  */
 package android.media.cts;
 
-import com.android.cts.media.R;
+import android.media.cts.R;
 
 import android.app.Activity;
 import android.content.res.AssetFileDescriptor;
diff --git a/tests/tests/media/src/android/media/cts/MediaPlayerSurfaceTest.java b/tests/tests/media/src/android/media/cts/MediaPlayerSurfaceTest.java
index fc81cac..ae314d2 100644
--- a/tests/tests/media/src/android/media/cts/MediaPlayerSurfaceTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaPlayerSurfaceTest.java
@@ -24,12 +24,12 @@
 public class MediaPlayerSurfaceTest extends ActivityInstrumentationTestCase2<MediaPlayerSurfaceStubActivity> {
 
     public MediaPlayerSurfaceTest() {
-        super("com.android.cts.media", MediaPlayerSurfaceStubActivity.class);
+        super("android.media.cts", MediaPlayerSurfaceStubActivity.class);
     }
 
     public void testSetSurface() throws Exception {
         Bundle extras = new Bundle();
-        MediaPlayerSurfaceStubActivity activity = launchActivity("com.android.cts.media",
+        MediaPlayerSurfaceStubActivity activity = launchActivity("android.media.cts",
                 MediaPlayerSurfaceStubActivity.class, extras);
         activity.playVideo();
         activity.finish();
diff --git a/tests/tests/media/src/android/media/cts/MediaPlayerTest.java b/tests/tests/media/src/android/media/cts/MediaPlayerTest.java
old mode 100755
new mode 100644
index 21b9775..4eaefc3
--- a/tests/tests/media/src/android/media/cts/MediaPlayerTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaPlayerTest.java
@@ -15,13 +15,13 @@
  */
 package android.media.cts;
 
-import com.android.cts.media.R;
+import android.media.cts.R;
 
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.content.res.AssetFileDescriptor;
 import android.cts.util.MediaUtils;
-import android.hardware.Camera;
+import android.graphics.Rect;
 import android.media.AudioManager;
 import android.media.MediaCodec;
 import android.media.MediaDataSource;
@@ -33,11 +33,11 @@
 import android.media.MediaRecorder;
 import android.media.MediaTimestamp;
 import android.media.PlaybackParams;
+import android.media.SubtitleData;
 import android.media.SyncParams;
 import android.media.TimedText;
 import android.media.audiofx.AudioEffect;
 import android.media.audiofx.Visualizer;
-import android.media.cts.MediaPlayerTestBase.Monitor;
 import android.net.Uri;
 import android.os.Environment;
 import android.os.IBinder;
@@ -50,7 +50,6 @@
 import java.io.File;
 import java.io.InputStream;
 import java.io.InputStreamReader;
-import java.util.List;
 import java.util.StringTokenizer;
 import java.util.UUID;
 import java.util.Vector;
@@ -75,12 +74,18 @@
     private static final long RECORDED_DURATION_MS  = 3000;
     private static final float FLOAT_TOLERANCE = .0001f;
 
-    private Vector<Integer> mTimedTextTrackIndex = new Vector<Integer>();
+    private final Vector<Integer> mTimedTextTrackIndex = new Vector<>();
+    private final Monitor mOnTimedTextCalled = new Monitor();
     private int mSelectedTimedTextIndex;
-    private Monitor mOnTimedTextCalled = new Monitor();
+
+    private final Vector<Integer> mSubtitleTrackIndex = new Vector<>();
+    private final Monitor mOnSubtitleDataCalled = new Monitor();
+    private int mSelectedSubtitleIndex;
 
     private File mOutFile;
 
+    private int mBoundsCount;
+
     @Override
     protected void setUp() throws Exception {
         super.setUp();
@@ -294,6 +299,43 @@
         }
     }
 
+    public void testPlayAudioLooping() throws Exception {
+        final int resid = R.raw.testmp3;
+
+        MediaPlayer mp = MediaPlayer.create(mContext, resid);
+        try {
+            mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
+            mp.setWakeMode(mContext, PowerManager.PARTIAL_WAKE_LOCK);
+            mp.setLooping(true);
+            mOnCompletionCalled.reset();
+            mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
+                @Override
+                public void onCompletion(MediaPlayer mp) {
+                    Log.i("@@@", "got oncompletion");
+                    mOnCompletionCalled.signal();
+                }
+            });
+
+            assertFalse(mp.isPlaying());
+            mp.start();
+            assertTrue(mp.isPlaying());
+
+            int duration = mp.getDuration();
+            Thread.sleep(duration * 4); // allow for several loops
+            assertTrue(mp.isPlaying());
+            assertEquals("wrong number of completion signals", 0, mOnCompletionCalled.getNumSignal());
+            mp.setLooping(false);
+
+            // wait for playback to finish
+            while(mp.isPlaying()) {
+                Thread.sleep(SLEEP_TIME);
+            }
+            assertEquals("wrong number of completion signals", 1, mOnCompletionCalled.getNumSignal());
+        } finally {
+            mp.release();
+        }
+    }
+
     public void testPlayMidi() throws Exception {
         final int resid = R.raw.midi8sec;
         final int midiDuration = 8000;
@@ -646,55 +688,63 @@
     }
 
     private void testGapless(int resid1, int resid2) throws Exception {
-
-        MediaPlayer mp1 = new MediaPlayer();
-        mp1.setAudioStreamType(AudioManager.STREAM_MUSIC);
+        MediaPlayer mp1 = null;
+        MediaPlayer mp2 = null;
+        AudioEffect vc = null;
+        Visualizer vis = null;
+        AudioManager am = null;
+        int oldRingerMode = Integer.MIN_VALUE;
+        int oldVolume = Integer.MIN_VALUE;
         try {
+            Utils.toggleNotificationPolicyAccess(
+                    mContext.getPackageName(), getInstrumentation(), true /* on */);
+
+            mp1 = new MediaPlayer();
+            mp1.setAudioStreamType(AudioManager.STREAM_MUSIC);
+
             AssetFileDescriptor afd = mContext.getResources().openRawResourceFd(resid1);
             mp1.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
             afd.close();
             mp1.prepare();
-        } catch (Exception e) {
-            assertTrue(false);
-        }
-        int session = mp1.getAudioSessionId();
 
-        MediaPlayer mp2 = new MediaPlayer();
-        mp2.setAudioSessionId(session);
-        mp2.setAudioStreamType(AudioManager.STREAM_MUSIC);
-        try {
-            AssetFileDescriptor afd = mContext.getResources().openRawResourceFd(resid2);
+            int session = mp1.getAudioSessionId();
+
+            mp2 = new MediaPlayer();
+            mp2.setAudioSessionId(session);
+            mp2.setAudioStreamType(AudioManager.STREAM_MUSIC);
+
+            afd = mContext.getResources().openRawResourceFd(resid2);
             mp2.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
             afd.close();
             mp2.prepare();
-        } catch (Exception e) {
-            assertTrue(false);
-        }
-        // creating a volume controller on output mix ensures that ro.audio.silent mutes
-        // audio after the effects and not before
-        AudioEffect vc = new AudioEffect(
+
+            // creating a volume controller on output mix ensures that ro.audio.silent mutes
+            // audio after the effects and not before
+            vc = new AudioEffect(
                             AudioEffect.EFFECT_TYPE_NULL,
                             UUID.fromString("119341a0-8469-11df-81f9-0002a5d5c51b"),
                             0,
                             session);
-        vc.setEnabled(true);
-        int captureintervalms = mp1.getDuration() + mp2.getDuration() - 2000;
-        int size = 256;
-        int[] range = Visualizer.getCaptureSizeRange();
-        if (size < range[0]) {
-            size = range[0];
-        }
-        if (size > range[1]) {
-            size = range[1];
-        }
-        byte [] vizdata = new byte[size];
-        Visualizer vis = new Visualizer(session);
-        AudioManager am = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
-        int oldRingerMode = am.getRingerMode();
-        am.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
-        int oldvolume = am.getStreamVolume(AudioManager.STREAM_MUSIC);
-        am.setStreamVolume(AudioManager.STREAM_MUSIC, 1, 0);
-        try {
+            vc.setEnabled(true);
+            int captureintervalms = mp1.getDuration() + mp2.getDuration() - 2000;
+            int size = 256;
+            int[] range = Visualizer.getCaptureSizeRange();
+            if (size < range[0]) {
+                size = range[0];
+            }
+            if (size > range[1]) {
+                size = range[1];
+            }
+            byte[] vizdata = new byte[size];
+
+            vis = new Visualizer(session);
+            am = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
+            oldRingerMode = am.getRingerMode();
+            // make sure we aren't in silent mode
+            am.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
+            oldVolume = am.getStreamVolume(AudioManager.STREAM_MUSIC);
+            am.setStreamVolume(AudioManager.STREAM_MUSIC, 1, 0);
+
             assertEquals("setCaptureSize failed",
                     Visualizer.SUCCESS, vis.setCaptureSize(vizdata.length));
             assertEquals("setEnabled failed", Visualizer.SUCCESS, vis.setEnabled(true));
@@ -728,12 +778,26 @@
                 first = false;
             }
         } finally {
-            mp1.release();
-            mp2.release();
-            vis.release();
-            vc.release();
-            am.setRingerMode(oldRingerMode);
-            am.setStreamVolume(AudioManager.STREAM_MUSIC, oldvolume, 0);
+            if (mp1 != null) {
+                mp1.release();
+            }
+            if (mp2 != null) {
+                mp2.release();
+            }
+            if (vis != null) {
+                vis.release();
+            }
+            if (vc != null) {
+                vc.release();
+            }
+            if (oldRingerMode != Integer.MIN_VALUE) {
+                am.setRingerMode(oldRingerMode);
+            }
+            if (oldVolume != Integer.MIN_VALUE) {
+                am.setStreamVolume(AudioManager.STREAM_MUSIC, oldVolume, 0);
+            }
+            Utils.toggleNotificationPolicyAccess(
+                    mContext.getPackageName(), getInstrumentation(), false  /* on == false */);
         }
     }
 
@@ -823,34 +887,15 @@
         return getActivity().getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA);
     }
 
-    private Camera mCamera;
     private void testRecordedVideoPlaybackWithAngle(int angle) throws Exception {
-        int width = RECORDED_VIDEO_WIDTH;
-        int height = RECORDED_VIDEO_HEIGHT;
+        final int width = RECORDED_VIDEO_WIDTH;
+        final int height = RECORDED_VIDEO_HEIGHT;
         final String file = RECORDED_FILE;
         final long durationMs = RECORDED_DURATION_MS;
 
         if (!hasCamera()) {
             return;
         }
-
-        boolean isSupported = false;
-        mCamera = Camera.open(0);
-        Camera.Parameters parameters = mCamera.getParameters();
-        List<Camera.Size> videoSizes = parameters.getSupportedVideoSizes();
-        for (Camera.Size size : videoSizes)
-        {
-            if (size.width == width && size.height == height) {
-                isSupported = true;
-                break;
-            }
-        }
-        mCamera.release();
-        mCamera = null;
-        if (!isSupported) {
-            width = videoSizes.get(0).width;
-            height = videoSizes.get(0).height;
-        }
         checkOrientation(angle);
         recordVideo(width, height, angle, file, durationMs);
         checkDisplayedVideoSize(width, height, angle, file);
@@ -900,7 +945,7 @@
         MediaMetadataRetriever retriever = new MediaMetadataRetriever();
         retriever.setDataSource(file);
         String rotation = retriever.extractMetadata(
-                    MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION);
+                MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION);
         retriever.release();
         retriever = null;
         assertNotNull(rotation);
@@ -1187,6 +1232,194 @@
                 R.raw.video_176x144_3gp_h263_300kbps_25fps_aac_stereo_128kbps_22050hz, 176, 144);
     }
 
+    private void readSubtitleTracks() throws Exception {
+        mSubtitleTrackIndex.clear();
+        MediaPlayer.TrackInfo[] trackInfos = mMediaPlayer.getTrackInfo();
+        if (trackInfos == null || trackInfos.length == 0) {
+            return;
+        }
+
+        Vector<Integer> subtitleTrackIndex = new Vector<>();
+        for (int i = 0; i < trackInfos.length; ++i) {
+            assertTrue(trackInfos[i] != null);
+            if (trackInfos[i].getTrackType() == MediaPlayer.TrackInfo.MEDIA_TRACK_TYPE_SUBTITLE) {
+                subtitleTrackIndex.add(i);
+            }
+        }
+
+        mSubtitleTrackIndex.addAll(subtitleTrackIndex);
+    }
+
+    private void selectSubtitleTrack(int index) throws Exception {
+        int trackIndex = mSubtitleTrackIndex.get(index);
+        mMediaPlayer.selectTrack(trackIndex);
+        mSelectedSubtitleIndex = index;
+    }
+
+    private void deselectSubtitleTrack(int index) throws Exception {
+        int trackIndex = mSubtitleTrackIndex.get(index);
+        mMediaPlayer.deselectTrack(trackIndex);
+        if (mSelectedSubtitleIndex == index) {
+            mSelectedSubtitleIndex = -1;
+        }
+    }
+
+    public void testDeselectTrackForSubtitleTracks() throws Throwable {
+        if (!checkLoadResource(R.raw.testvideo_with_2_subtitle_tracks)) {
+            return; // skip;
+        }
+
+        getInstrumentation().waitForIdleSync();
+
+        mMediaPlayer.setOnSubtitleDataListener(new MediaPlayer.OnSubtitleDataListener() {
+            @Override
+            public void onSubtitleData(MediaPlayer mp, SubtitleData data) {
+                if (data != null && data.getData() != null) {
+                    mOnSubtitleDataCalled.signal();
+                }
+            }
+        });
+        mMediaPlayer.setOnInfoListener(new MediaPlayer.OnInfoListener() {
+            @Override
+            public boolean onInfo(MediaPlayer mp, int what, int extra) {
+                if (what == MediaPlayer.MEDIA_INFO_METADATA_UPDATE) {
+                    mOnInfoCalled.signal();
+                }
+                return false;
+            }
+        });
+
+        mMediaPlayer.setDisplay(getActivity().getSurfaceHolder());
+        mMediaPlayer.setScreenOnWhilePlaying(true);
+        mMediaPlayer.setWakeMode(mContext, PowerManager.PARTIAL_WAKE_LOCK);
+
+        mMediaPlayer.prepare();
+        mMediaPlayer.start();
+        assertTrue(mMediaPlayer.isPlaying());
+
+        // Closed caption tracks are in-band.
+        // So, those tracks will be found after processing a number of frames.
+        mOnInfoCalled.waitForSignal(1500);
+
+        mOnInfoCalled.reset();
+        mOnInfoCalled.waitForSignal(1500);
+
+        readSubtitleTracks();
+
+        // Run twice to check if repeated selection-deselection on the same track works well.
+        for (int i = 0; i < 2; i++) {
+            // Waits until at least one subtitle is fired. Timeout is 1.5 sec.
+            selectSubtitleTrack(i);
+            mOnSubtitleDataCalled.reset();
+            assertTrue(mOnSubtitleDataCalled.waitForSignal(1500));
+
+            // Try deselecting track.
+            deselectSubtitleTrack(i);
+            mOnSubtitleDataCalled.reset();
+            assertFalse(mOnSubtitleDataCalled.waitForSignal(1500));
+        }
+
+        try {
+            deselectSubtitleTrack(0);
+            fail("Deselecting unselected track: expected RuntimeException, " +
+                 "but no exception has been triggered.");
+        } catch (RuntimeException e) {
+            // expected
+        }
+
+        mMediaPlayer.stop();
+    }
+
+    public void testChangeSubtitleTrack() throws Throwable {
+        if (!checkLoadResource(R.raw.testvideo_with_2_subtitle_tracks)) {
+            return; // skip;
+        }
+
+        mMediaPlayer.setOnSubtitleDataListener(new MediaPlayer.OnSubtitleDataListener() {
+            @Override
+            public void onSubtitleData(MediaPlayer mp, SubtitleData data) {
+                if (data != null && data.getData() != null) {
+                    mOnSubtitleDataCalled.signal();
+                }
+            }
+        });
+        mMediaPlayer.setOnInfoListener(new MediaPlayer.OnInfoListener() {
+            @Override
+            public boolean onInfo(MediaPlayer mp, int what, int extra) {
+                if (what == MediaPlayer.MEDIA_INFO_METADATA_UPDATE) {
+                    mOnInfoCalled.signal();
+                }
+                return false;
+            }
+        });
+
+        mMediaPlayer.setDisplay(getActivity().getSurfaceHolder());
+        mMediaPlayer.setScreenOnWhilePlaying(true);
+        mMediaPlayer.setWakeMode(mContext, PowerManager.PARTIAL_WAKE_LOCK);
+
+        mMediaPlayer.prepare();
+        mMediaPlayer.start();
+        assertTrue(mMediaPlayer.isPlaying());
+
+        // Closed caption tracks are in-band.
+        // So, those tracks will be found after processing a number of frames.
+        mOnInfoCalled.waitForSignal(1500);
+
+        mOnInfoCalled.reset();
+        mOnInfoCalled.waitForSignal(1500);
+
+        readSubtitleTracks();
+
+        // Waits until at least two captions are fired. Timeout is 2.5 sec.
+        selectSubtitleTrack(0);
+        assertTrue(mOnSubtitleDataCalled.waitForCountedSignals(2, 2500) >= 2);
+
+        mOnSubtitleDataCalled.reset();
+        selectSubtitleTrack(1);
+        assertTrue(mOnSubtitleDataCalled.waitForCountedSignals(2, 2500) >= 2);
+
+        mMediaPlayer.stop();
+    }
+
+    public void testGetTrackInfoForVideoWithSubtitleTracks() throws Throwable {
+        if (!checkLoadResource(R.raw.testvideo_with_2_subtitle_tracks)) {
+            return; // skip;
+        }
+
+        getInstrumentation().waitForIdleSync();
+
+        mMediaPlayer.setOnInfoListener(new MediaPlayer.OnInfoListener() {
+            @Override
+            public boolean onInfo(MediaPlayer mp, int what, int extra) {
+                if (what == MediaPlayer.MEDIA_INFO_METADATA_UPDATE) {
+                    mOnInfoCalled.signal();
+                }
+                return false;
+            }
+        });
+
+        mMediaPlayer.setDisplay(getActivity().getSurfaceHolder());
+        mMediaPlayer.setScreenOnWhilePlaying(true);
+        mMediaPlayer.setWakeMode(mContext, PowerManager.PARTIAL_WAKE_LOCK);
+
+        mMediaPlayer.prepare();
+        mMediaPlayer.start();
+        assertTrue(mMediaPlayer.isPlaying());
+
+        // The media metadata will be changed while playing since closed caption tracks are in-band
+        // and those tracks will be found after processing a number of frames. These tracks will be
+        // found within one second.
+        mOnInfoCalled.waitForSignal(1500);
+
+        mOnInfoCalled.reset();
+        mOnInfoCalled.waitForSignal(1500);
+
+        readSubtitleTracks();
+        assertEquals(2, mSubtitleTrackIndex.size());
+
+        mMediaPlayer.stop();
+    }
+
     private void readTimedTextTracks() throws Exception {
         mTimedTextTrackIndex.clear();
         MediaPlayer.TrackInfo[] trackInfos = mMediaPlayer.getTrackInfo();
@@ -1215,13 +1448,13 @@
         return mTimedTextTrackIndex.size();
     }
 
-    private void selectSubtitleTrack(int index) throws Exception {
+    private void selectTimedTextTrack(int index) throws Exception {
         int trackIndex = mTimedTextTrackIndex.get(index);
         mMediaPlayer.selectTrack(trackIndex);
         mSelectedTimedTextIndex = index;
     }
 
-    private void deselectSubtitleTrack(int index) throws Exception {
+    private void deselectTimedTextTrack(int index) throws Exception {
         int trackIndex = mTimedTextTrackIndex.get(index);
         mMediaPlayer.deselectTrack(trackIndex);
         if (mSelectedTimedTextIndex == index) {
@@ -1229,8 +1462,8 @@
         }
     }
 
-    public void testDeselectTrack() throws Throwable {
-        if (!checkLoadResource(R.raw.testvideo_with_2_subtitles)) {
+    public void testDeselectTrackForTimedTextTrack() throws Throwable {
+        if (!checkLoadResource(R.raw.testvideo_with_2_timedtext_tracks)) {
             return; // skip;
         }
         runTestOnUiThread(new Runnable() {
@@ -1268,31 +1501,31 @@
 
         // Run twice to check if repeated selection-deselection on the same track works well.
         for (int i = 0; i < 2; i++) {
-            // Waits until at least one subtitle is fired. Timeout is 1 sec.
-            selectSubtitleTrack(0);
+            // Waits until at least one subtitle is fired. Timeout is 1.5 sec.
+            selectTimedTextTrack(0);
             mOnTimedTextCalled.reset();
             assertTrue(mOnTimedTextCalled.waitForSignal(1500));
 
             // Try deselecting track.
-            deselectSubtitleTrack(0);
+            deselectTimedTextTrack(0);
             mOnTimedTextCalled.reset();
             assertFalse(mOnTimedTextCalled.waitForSignal(1500));
         }
 
         // Run the same test for external subtitle track.
         for (int i = 0; i < 2; i++) {
-            selectSubtitleTrack(2);
+            selectTimedTextTrack(2);
             mOnTimedTextCalled.reset();
             assertTrue(mOnTimedTextCalled.waitForSignal(1500));
 
             // Try deselecting track.
-            deselectSubtitleTrack(2);
+            deselectTimedTextTrack(2);
             mOnTimedTextCalled.reset();
             assertFalse(mOnTimedTextCalled.waitForSignal(1500));
         }
 
         try {
-            deselectSubtitleTrack(0);
+            deselectTimedTextTrack(0);
             fail("Deselecting unselected track: expected RuntimeException, " +
                  "but no exception has been triggered.");
         } catch (RuntimeException e) {
@@ -1302,14 +1535,15 @@
         mMediaPlayer.stop();
     }
 
-    public void testChangeSubtitleTrack() throws Throwable {
-        if (!checkLoadResource(R.raw.testvideo_with_2_subtitles)) {
+    public void testChangeTimedTextTrack() throws Throwable {
+        if (!checkLoadResource(R.raw.testvideo_with_2_timedtext_tracks)) {
             return; // skip;
         }
 
         mMediaPlayer.setDisplay(getActivity().getSurfaceHolder());
         mMediaPlayer.setScreenOnWhilePlaying(true);
         mMediaPlayer.setWakeMode(mContext, PowerManager.PARTIAL_WAKE_LOCK);
+        mBoundsCount = 0;
         mMediaPlayer.setOnTimedTextListener(new MediaPlayer.OnTimedTextListener() {
             @Override
             public void onTimedText(MediaPlayer mp, TimedText text) {
@@ -1334,6 +1568,13 @@
                                      mSelectedTimedTextIndex, subtitleTrackIndex);
                         mOnTimedTextCalled.signal();
                     }
+                    Rect bounds = text.getBounds();
+                    if (bounds != null) {
+                        Log.d(LOG_TAG, "bounds: " + bounds);
+                        mBoundsCount++;
+                        Rect expected = new Rect(0, 0, 352, 288);
+                        assertEquals("wrong bounds", expected, bounds);
+                    }
                 }
             }
         });
@@ -1367,33 +1608,35 @@
         getInstrumentation().waitForIdleSync();
         assertEquals(getTimedTextTrackCount(), 4);
 
-        selectSubtitleTrack(0);
+        selectTimedTextTrack(0);
         mOnTimedTextCalled.reset();
 
         mMediaPlayer.start();
         assertTrue(mMediaPlayer.isPlaying());
 
-        // Waits until at least two subtitles are fired. Timeout is 2 sec.
+        // Waits until at least two subtitles are fired. Timeout is 2.5 sec.
         // Please refer the test srt files:
         // test_subtitle1_srt.3gp and test_subtitle2_srt.3gp
         assertTrue(mOnTimedTextCalled.waitForCountedSignals(2, 2500) >= 2);
 
-        selectSubtitleTrack(1);
+        selectTimedTextTrack(1);
         mOnTimedTextCalled.reset();
         assertTrue(mOnTimedTextCalled.waitForCountedSignals(2, 2500) >= 2);
 
-        selectSubtitleTrack(2);
+        selectTimedTextTrack(2);
         mOnTimedTextCalled.reset();
         assertTrue(mOnTimedTextCalled.waitForCountedSignals(2, 2500) >= 2);
 
-        selectSubtitleTrack(3);
+        selectTimedTextTrack(3);
         mOnTimedTextCalled.reset();
         assertTrue(mOnTimedTextCalled.waitForCountedSignals(2, 2500) >= 2);
         mMediaPlayer.stop();
+
+        assertEquals("Wrong bounds count", 2, mBoundsCount);
     }
 
-    public void testGetTrackInfo() throws Throwable {
-        if (!checkLoadResource(R.raw.testvideo_with_2_subtitles)) {
+    public void testGetTrackInfoForVideoWithTimedText() throws Throwable {
+        if (!checkLoadResource(R.raw.testvideo_with_2_timedtext_tracks)) {
             return; // skip;
         }
         runTestOnUiThread(new Runnable() {
@@ -1411,7 +1654,7 @@
         mMediaPlayer.start();
 
         readTimedTextTracks();
-        selectSubtitleTrack(2);
+        selectTimedTextTrack(2);
 
         int count = 0;
         MediaPlayer.TrackInfo[] trackInfos = mMediaPlayer.getTrackInfo();
diff --git a/tests/tests/media/src/android/media/cts/MediaRandomTest.java b/tests/tests/media/src/android/media/cts/MediaRandomTest.java
index e928a8f..a8fc703 100644
--- a/tests/tests/media/src/android/media/cts/MediaRandomTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaRandomTest.java
@@ -16,7 +16,7 @@
 package android.media.cts;
 
 
-import com.android.cts.media.R;
+import android.media.cts.R;
 
 import android.media.MediaRecorder;
 import android.media.MediaPlayer;
@@ -158,7 +158,7 @@
     }
 
     public MediaRandomTest() {
-        super("com.android.cts.media", MediaStubActivity.class);
+        super("android.media.cts", MediaStubActivity.class);
     }
 
     private void loadSource(int resid) throws Exception {
diff --git a/tests/tests/media/src/android/media/cts/MediaRecorderTest.java b/tests/tests/media/src/android/media/cts/MediaRecorderTest.java
old mode 100755
new mode 100644
index 82bd4d6..d452856
--- a/tests/tests/media/src/android/media/cts/MediaRecorderTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaRecorderTest.java
@@ -15,7 +15,6 @@
  */
 package android.media.cts;
 
-
 import android.content.pm.PackageManager;
 import android.cts.util.MediaUtils;
 import android.graphics.Canvas;
@@ -55,9 +54,11 @@
     private final String OUTPUT_PATH2;
     private static final float TOLERANCE = 0.0002f;
     private static final int RECORD_TIME_MS = 3000;
-    private static final int RECORD_TIME_LAPSE_MS = 4000;
+    private static final int RECORD_TIME_LAPSE_MS = 6000;
     private static final int RECORD_TIME_LONG_MS = 20000;
     private static final int RECORDED_DUR_TOLERANCE_MS = 1000;
+    // Tolerate 4 frames off at maximum
+    private static final float RECORDED_DUR_TOLERANCE_FRAMES = 4f;
     private static final int VIDEO_WIDTH = 176;
     private static final int VIDEO_HEIGHT = 144;
     private static int mVideoWidth = VIDEO_WIDTH;
@@ -90,7 +91,7 @@
     private ConditionVariable mMaxFileSizeCond;
 
     public MediaRecorderTest() {
-        super("com.android.cts.media", MediaStubActivity.class);
+        super("android.media.cts", MediaStubActivity.class);
         OUTPUT_PATH = new File(Environment.getExternalStorageDirectory(),
                 "record.out").getAbsolutePath();
         OUTPUT_PATH2 = new File(Environment.getExternalStorageDirectory(),
@@ -209,20 +210,28 @@
 
     @UiThreadTest
     public void testSetCamera() throws Exception {
-        recordVideoUsingCamera(false);
+        recordVideoUsingCamera(false, false);
     }
 
     public void testRecorderTimelapsedVideo() throws Exception {
-        recordVideoUsingCamera(true);
+        recordVideoUsingCamera(true, false);
     }
 
-    private void recordVideoUsingCamera(boolean timelapse) throws Exception {
+    public void testRecorderPauseResume() throws Exception {
+        recordVideoUsingCamera(false, true);
+    }
+
+    public void testRecorderPauseResumeOnTimeLapse() throws Exception {
+        recordVideoUsingCamera(true, true);
+    }
+
+    private void recordVideoUsingCamera(boolean timelapse, boolean pause) throws Exception {
         int nCamera = Camera.getNumberOfCameras();
         int durMs = timelapse? RECORD_TIME_LAPSE_MS: RECORD_TIME_MS;
         for (int cameraId = 0; cameraId < nCamera; cameraId++) {
             mCamera = Camera.open(cameraId);
             setSupportedResolution(mCamera);
-            recordVideoUsingCamera(mCamera, OUTPUT_PATH, durMs, timelapse);
+            recordVideoUsingCamera(mCamera, OUTPUT_PATH, durMs, timelapse, pause);
             mCamera.release();
             mCamera = null;
             assertTrue(checkLocationInFile(OUTPUT_PATH));
@@ -231,8 +240,8 @@
 
     private void setSupportedResolution(Camera camera) {
         Camera.Parameters parameters = camera.getParameters();
-        List<Camera.Size> videoSizes = parameters.getSupportedVideoSizes();
-        for (Camera.Size size : videoSizes)
+        List<Camera.Size> previewSizes = parameters.getSupportedPreviewSizes();
+        for (Camera.Size size : previewSizes)
         {
             if (size.width == VIDEO_WIDTH && size.height == VIDEO_HEIGHT) {
                 mVideoWidth = VIDEO_WIDTH;
@@ -240,12 +249,13 @@
                 return;
             }
         }
-        mVideoWidth = videoSizes.get(0).width;
-        mVideoHeight = videoSizes.get(0).height;
+        mVideoWidth = previewSizes.get(0).width;
+        mVideoHeight = previewSizes.get(0).height;
     }
 
     private void recordVideoUsingCamera(
-            Camera camera, String fileName, int durMs, boolean timelapse) throws Exception {
+            Camera camera, String fileName, int durMs, boolean timelapse, boolean pause)
+        throws Exception {
         // FIXME:
         // We should add some test case to use Camera.Parameters.getPreviewFpsRange()
         // to get the supported video frame rate range.
@@ -271,18 +281,27 @@
 
         mMediaRecorder.prepare();
         mMediaRecorder.start();
-        Thread.sleep(durMs);
+        if (pause) {
+            Thread.sleep(durMs / 2);
+            mMediaRecorder.pause();
+            Thread.sleep(durMs / 2);
+            mMediaRecorder.resume();
+            Thread.sleep(durMs / 2);
+        } else {
+            Thread.sleep(durMs);
+        }
         mMediaRecorder.stop();
         assertTrue(mOutFile.exists());
 
         int targetDurMs = timelapse? ((int) (durMs * (captureRate / frameRate))): durMs;
         boolean hasVideo = true;
         boolean hasAudio = timelapse? false: true;
-        checkTracksAndDuration(targetDurMs, hasVideo, hasAudio, fileName);
+        checkTracksAndDuration(targetDurMs, hasVideo, hasAudio, fileName, frameRate);
     }
 
     private void checkTracksAndDuration(
-            int targetMs, boolean hasVideo, boolean hasAudio, String fileName) throws Exception {
+            int targetMs, boolean hasVideo, boolean hasAudio, String fileName,
+            float frameRate) throws Exception {
         MediaMetadataRetriever retriever = new MediaMetadataRetriever();
         retriever.setDataSource(fileName);
         String hasVideoStr = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_HAS_VIDEO);
@@ -294,7 +313,15 @@
         // check on the duration.
         String durStr = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
         assertTrue(durStr != null);
-        assertTrue(Integer.parseInt(durStr) > 0);
+        int duration = Integer.parseInt(durStr);
+        assertTrue("duration is non-positive: dur = " + duration, duration > 0);
+        if (targetMs != 0) {
+            float toleranceMs = RECORDED_DUR_TOLERANCE_FRAMES * (1000f / frameRate);
+            assertTrue(String.format("duration is too large: dur = %d, target = %d, tolerance = %f",
+                        duration, targetMs, toleranceMs),
+                    duration <= targetMs + toleranceMs);
+        }
+
         retriever.release();
         retriever = null;
     }
@@ -392,6 +419,17 @@
         return 1;
     }
 
+    public void testRecordAudioFromAudioSourceUnprocessed() throws Exception {
+        if (!hasMicrophone()) {
+            return; // skip
+        }
+        mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.UNPROCESSED);
+        mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
+        mMediaRecorder.setOutputFile(OUTPUT_PATH);
+        mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
+        recordMedia(MAX_FILE_SIZE, mOutFile);
+    }
+
     public void testGetAudioSourceMax() throws Exception {
         final int max = MediaRecorder.getAudioSourceMax();
         assertTrue(MediaRecorder.AudioSource.DEFAULT <= max);
@@ -402,6 +440,7 @@
         assertTrue(MediaRecorder.AudioSource.VOICE_DOWNLINK <= max);
         assertTrue(MediaRecorder.AudioSource.VOICE_RECOGNITION <= max);
         assertTrue(MediaRecorder.AudioSource.VOICE_UPLINK <= max);
+        assertTrue(MediaRecorder.AudioSource.UNPROCESSED <= max);
     }
 
     public void testRecorderAudio() throws Exception {
@@ -890,6 +929,7 @@
         boolean success = false;
         Surface surface = null;
         int noOfFailure = 0;
+        final float frameRate = getMaxFrameRateForCodec(MediaRecorder.VideoEncoder.H264);
 
         if (!hasH264()) {
             MediaUtils.skipTest("no codecs");
@@ -922,7 +962,7 @@
                 Log.v(TAG, "testRecordFromSurface - round " + k);
                 success = recordFromSurface(filename, captureRate, hasAudio, surface);
                 if (success) {
-                    checkTracksAndDuration(0, true /* hasVideo */, hasAudio, filename);
+                    checkTracksAndDuration(0, true /* hasVideo */, hasAudio, filename, frameRate);
 
                     // verify capture fps meta key
                     if (timelapse && !checkCaptureFps(filename, captureRate)) {
diff --git a/tests/tests/media/src/android/media/cts/MediaRouterTest.java b/tests/tests/media/src/android/media/cts/MediaRouterTest.java
new file mode 100644
index 0000000..33544b9
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/MediaRouterTest.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.media.cts;
+
+import android.content.Context;
+import android.media.MediaRouter;
+import android.media.MediaRouter.RouteCategory;
+import android.media.MediaRouter.RouteInfo;
+import android.media.MediaRouter.UserRouteInfo;
+import android.test.InstrumentationTestCase;
+
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * Test {@link android.media.MediaRouter}.
+ */
+public class MediaRouterTest extends InstrumentationTestCase {
+
+    private MediaRouter mMediaRouter;
+    private RouteCategory mTestCategory;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        final Context context = getInstrumentation().getContext();
+        mMediaRouter = (MediaRouter) context.getSystemService(Context.MEDIA_ROUTER_SERVICE);
+        mTestCategory = mMediaRouter.createRouteCategory("testCategory", false);
+    }
+
+    protected void tearDown() throws Exception {
+        mMediaRouter.clearUserRoutes();
+        super.tearDown();
+    }
+
+    public void testSelectRoute() throws Exception {
+        RouteInfo prevSelectedRoute = mMediaRouter.getSelectedRoute(
+                MediaRouter.ROUTE_TYPE_LIVE_AUDIO | MediaRouter.ROUTE_TYPE_LIVE_VIDEO
+                | MediaRouter.ROUTE_TYPE_REMOTE_DISPLAY);
+
+        final String newRouteName = "User route's name";
+        UserRouteInfo newRoute = mMediaRouter.createUserRoute(mTestCategory);
+        newRoute.setName(newRouteName);
+        mMediaRouter.addUserRoute(newRoute);
+        mMediaRouter.selectRoute(newRoute.getSupportedTypes(), newRoute);
+
+        RouteInfo nowSelectedRoute = mMediaRouter.getSelectedRoute(MediaRouter.ROUTE_TYPE_USER);
+        assertEquals(newRoute, nowSelectedRoute);
+        assertEquals(mTestCategory, nowSelectedRoute.getCategory());
+
+        mMediaRouter.selectRoute(prevSelectedRoute.getSupportedTypes(), prevSelectedRoute);
+    }
+
+    public void testGetRouteCount() throws Exception {
+        final int count = mMediaRouter.getRouteCount();
+        assertTrue("By default, a media router has at least one route.", count > 0);
+
+        UserRouteInfo userRoute1 = mMediaRouter.createUserRoute(mTestCategory);
+        mMediaRouter.addUserRoute(userRoute1);
+        assertEquals(count + 1, mMediaRouter.getRouteCount());
+
+        mMediaRouter.removeUserRoute(userRoute1);
+        assertEquals(count, mMediaRouter.getRouteCount());
+
+        UserRouteInfo userRoute2 = mMediaRouter.createUserRoute(mTestCategory);
+        mMediaRouter.addUserRoute(userRoute1);
+        mMediaRouter.addUserRoute(userRoute2);
+        assertEquals(count + 2, mMediaRouter.getRouteCount());
+
+        mMediaRouter.clearUserRoutes();
+        assertEquals(count, mMediaRouter.getRouteCount());
+    }
+
+    public void testRouteCategory() throws Exception {
+        final int count = mMediaRouter.getCategoryCount();
+        assertTrue("By default, a media router has at least one route category.", count > 0);
+
+        UserRouteInfo newRoute = mMediaRouter.createUserRoute(mTestCategory);
+        mMediaRouter.addUserRoute(newRoute);
+        assertEquals(count + 1, mMediaRouter.getCategoryCount());
+
+        for (int i = 0; i < mMediaRouter.getCategoryCount(); i++) {
+            if (mMediaRouter.getCategoryAt(i) == mTestCategory) {
+                List<RouteInfo> routesInCategory = new ArrayList<RouteInfo>();
+                mTestCategory.getRoutes(routesInCategory);
+                assertEquals(1, routesInCategory.size());
+
+                RouteInfo route = routesInCategory.get(0);
+                assertEquals(newRoute, route);
+                return;
+            }
+        }
+        assertTrue(false);
+    }
+
+    public void testRouteInfo_getDeviceType() throws Exception {
+        final RouteInfo defaultRoute = mMediaRouter.getDefaultRoute();
+        assertTrue(defaultRoute != null);
+
+        final int deviceType = defaultRoute.getDeviceType();
+        assertEquals(RouteInfo.DEVICE_TYPE_UNKNOWN, deviceType);
+    }
+}
diff --git a/tests/tests/media/src/android/media/cts/MediaScannerConnectionTest.java b/tests/tests/media/src/android/media/cts/MediaScannerConnectionTest.java
index ddf87b8..952e03f 100644
--- a/tests/tests/media/src/android/media/cts/MediaScannerConnectionTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaScannerConnectionTest.java
@@ -16,7 +16,7 @@
 
 package android.media.cts;
 
-import com.android.cts.media.R;
+import android.media.cts.R;
 
 
 import android.content.ComponentName;
@@ -48,10 +48,10 @@
 
         FileCopyHelper copier = new FileCopyHelper(mContext);
         String fileName = "test" + System.currentTimeMillis();
-        copier.copy(R.raw.testmp3, fileName);
-
-        File dir = getContext().getFilesDir();
+        File dir = getContext().getExternalFilesDir(null);
         mMediaFile = new File(dir, fileName);
+        copier.copyToExternalStorage(R.raw.testmp3, mMediaFile);
+
         assertTrue(mMediaFile.exists());
     }
 
diff --git a/tests/tests/media/src/android/media/cts/MediaScannerTest.java b/tests/tests/media/src/android/media/cts/MediaScannerTest.java
index af7cfaa..ce93cb1 100644
--- a/tests/tests/media/src/android/media/cts/MediaScannerTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaScannerTest.java
@@ -16,7 +16,7 @@
 
 package android.media.cts;
 
-import com.android.cts.media.R;
+import android.media.cts.R;
 
 import android.content.ComponentName;
 import android.content.ContentResolver;
diff --git a/tests/tests/media/src/android/media/cts/MediaStubActivity.java b/tests/tests/media/src/android/media/cts/MediaStubActivity.java
index df6d736..48dde25 100644
--- a/tests/tests/media/src/android/media/cts/MediaStubActivity.java
+++ b/tests/tests/media/src/android/media/cts/MediaStubActivity.java
@@ -15,7 +15,7 @@
  */
 package android.media.cts;
 
-import com.android.cts.media.R;
+import android.media.cts.R;
 
 import android.app.Activity;
 import android.os.Bundle;
diff --git a/tests/tests/media/src/android/media/cts/MediaSyncTest.java b/tests/tests/media/src/android/media/cts/MediaSyncTest.java
index de5a5f5..bdd190f 100644
--- a/tests/tests/media/src/android/media/cts/MediaSyncTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaSyncTest.java
@@ -15,7 +15,7 @@
  */
 package android.media.cts;
 
-import com.android.cts.media.R;
+import android.media.cts.R;
 
 import android.content.Context;
 import android.content.pm.PackageManager;
@@ -82,8 +82,10 @@
     private boolean mHasVideo = false;
     private boolean mEosAudio = false;
     private boolean mEosVideo = false;
+    private int mTaggedAudioBufferIndex = -1;
     private final Object mConditionEos = new Object();
     private final Object mConditionEosAudio = new Object();
+    private final Object mConditionTaggedAudioBufferIndex = new Object();
 
     private int mNumBuffersReturned = 0;
 
@@ -138,15 +140,23 @@
         return ((!mHasVideo || mEosVideo) && (!mHasAudio || mEosAudio));
     }
 
+    public void onTaggedAudioBufferIndex(Decoder decoder, int index) {
+        synchronized (mConditionTaggedAudioBufferIndex) {
+            if (decoder == mDecoderAudio) {
+                mTaggedAudioBufferIndex = index;
+            }
+        }
+    }
+
     public void onEos(Decoder decoder) {
-        synchronized(mConditionEosAudio) {
+        synchronized (mConditionEosAudio) {
             if (decoder == mDecoderAudio) {
                 mEosAudio = true;
                 mConditionEosAudio.notify();
             }
         }
 
-        synchronized(mConditionEos) {
+        synchronized (mConditionEos) {
             if (decoder == mDecoderVideo) {
                 mEosVideo = true;
             }
@@ -173,7 +183,7 @@
         }
 
         assertTrue("The stream in test file can not be decoded",
-                mDecoderAudio.setup(INPUT_RESOURCE_ID, null, Long.MAX_VALUE));
+                mDecoderAudio.setup(INPUT_RESOURCE_ID, null, Long.MAX_VALUE, NO_TIMESTAMP));
 
         // get audio track.
         mAudioTrack = mDecoderAudio.getAudioTrack();
@@ -222,7 +232,7 @@
         final Object condition = new Object();
 
         mHasAudio = true;
-        if (mDecoderAudio.setup(inputResourceId, null, Long.MAX_VALUE) == false) {
+        if (mDecoderAudio.setup(inputResourceId, null, Long.MAX_VALUE, NO_TIMESTAMP) == false) {
             return true;
         }
 
@@ -283,7 +293,7 @@
         returnedIndex[0] = -1;
 
         mHasAudio = true;
-        if (mDecoderAudio.setup(inputResourceId, null, Long.MAX_VALUE) == false) {
+        if (mDecoderAudio.setup(inputResourceId, null, Long.MAX_VALUE, NO_TIMESTAMP) == false) {
             return true;
         }
 
@@ -417,8 +427,8 @@
             boolean audio,
             boolean video,
             float playbackRate) {
-        // allow 250ms for playback to get to stable state.
-        final int PLAYBACK_RAMP_UP_TIME_MS = 250;
+        // allow 750ms for playback to get to stable state.
+        final int PLAYBACK_RAMP_UP_TIME_US = 750000;
 
         final Object conditionFirstAudioBuffer = new Object();
 
@@ -427,14 +437,16 @@
             mSurface = mMediaSync.createInputSurface();
 
             if (mDecoderVideo.setup(
-                    inputResourceId, mSurface, lastBufferTimestampUs) == false) {
+                    inputResourceId, mSurface, lastBufferTimestampUs, NO_TIMESTAMP) == false) {
                 return true;
             }
             mHasVideo = true;
         }
 
         if (audio) {
-            if (mDecoderAudio.setup(inputResourceId, null, lastBufferTimestampUs) == false) {
+            if (mDecoderAudio.setup(
+                    inputResourceId, null, lastBufferTimestampUs,
+                    PLAYBACK_RAMP_UP_TIME_US) == false) {
                 return true;
             }
 
@@ -452,7 +464,12 @@
                         decoderAudio.releaseOutputBuffer(bufferIndex, NO_TIMESTAMP);
                     }
                     synchronized (conditionFirstAudioBuffer) {
-                        conditionFirstAudioBuffer.notify();
+                        synchronized (mConditionTaggedAudioBufferIndex) {
+                            if (mTaggedAudioBufferIndex >= 0
+                                    && mTaggedAudioBufferIndex == bufferIndex) {
+                                conditionFirstAudioBuffer.notify();
+                            }
+                        }
                     }
                 }
             }, null);
@@ -484,13 +501,6 @@
         }
 
         if (audio) {
-            try {
-                Thread.sleep(PLAYBACK_RAMP_UP_TIME_MS);
-            } catch (InterruptedException e) {
-                Log.i(LOG_TAG, "worker thread is interrupted during sleeping.");
-                return true;
-            }
-
             MediaTimestamp mediaTimestamp = mMediaSync.getTimestamp();
             assertTrue("No timestamp available for starting", mediaTimestamp != null);
             long checkStartTimeRealUs = System.nanoTime() / 1000;
@@ -542,6 +552,7 @@
         private MediaSync mMediaSync = null;
         private boolean mIsAudio = false;
         private long mLastBufferTimestampUs = 0;
+        private long mStartingAudioTimestampUs = NO_TIMESTAMP;
 
         private Surface mSurface = null;
 
@@ -577,7 +588,9 @@
             mIsAudio = isAudio;
         }
 
-        public boolean setup(int inputResourceId, Surface surface, long lastBufferTimestampUs) {
+        public boolean setup(
+                int inputResourceId, Surface surface, long lastBufferTimestampUs,
+                long startingAudioTimestampUs) {
             if (!mIsAudio) {
                 mSurface = surface;
                 // handle video callback in a separate thread as releaseOutputBuffer is blocking
@@ -586,6 +599,7 @@
                 mHandler = new Handler(mHandlerThread.getLooper());
             }
             mLastBufferTimestampUs = lastBufferTimestampUs;
+            mStartingAudioTimestampUs = startingAudioTimestampUs;
             try {
                 // get extrator.
                 String type = mIsAudio ? "audio/" : "video/";
@@ -728,13 +742,18 @@
                 if (info.size > 0) {
                     if (mIsAudio) {
                         ByteBuffer outputByteBuffer = codec.getOutputBuffer(index);
-                        synchronized(mAudioBufferLock) {
+                        synchronized (mAudioBufferLock) {
                             mAudioBuffers.add(new AudioBuffer(outputByteBuffer, index));
                         }
                         mMediaSync.queueAudio(
                                 outputByteBuffer,
                                 index,
                                 info.presentationTimeUs);
+                        if (mStartingAudioTimestampUs >= 0
+                                && info.presentationTimeUs >= mStartingAudioTimestampUs) {
+                            mMediaSyncTest.onTaggedAudioBufferIndex(this, index);
+                            mStartingAudioTimestampUs = NO_TIMESTAMP;
+                        }
                     } else {
                         codec.releaseOutputBuffer(index, info.presentationTimeUs * 1000);
                     }
@@ -753,7 +772,7 @@
         }
 
         public void checkReturnedAudioBuffer(ByteBuffer byteBuffer, int bufferIndex) {
-            synchronized(mAudioBufferLock) {
+            synchronized (mAudioBufferLock) {
                 AudioBuffer audioBuffer = mAudioBuffers.get(0);
                 if (audioBuffer.mByteBuffer != byteBuffer
                         || audioBuffer.mBufferIndex != bufferIndex) {
diff --git a/tests/tests/media/src/android/media/cts/NativeDecoderTest.java b/tests/tests/media/src/android/media/cts/NativeDecoderTest.java
index e7b08e9..deb561b 100644
--- a/tests/tests/media/src/android/media/cts/NativeDecoderTest.java
+++ b/tests/tests/media/src/android/media/cts/NativeDecoderTest.java
@@ -16,7 +16,7 @@
 
 package android.media.cts;
 
-import com.android.cts.media.R;
+import android.media.cts.R;
 
 import android.content.res.AssetFileDescriptor;
 import android.content.res.Resources;
diff --git a/tests/tests/media/src/android/media/cts/ParamsTest.java b/tests/tests/media/src/android/media/cts/ParamsTest.java
index 5e32828..113be32 100644
--- a/tests/tests/media/src/android/media/cts/ParamsTest.java
+++ b/tests/tests/media/src/android/media/cts/ParamsTest.java
@@ -16,7 +16,7 @@
 
 package android.media.cts;
 
-import com.android.cts.media.R;
+import android.media.cts.R;
 
 import android.media.PlaybackParams;
 import android.media.SyncParams;
diff --git a/tests/tests/media/src/android/media/cts/ResourceManagerTest.java b/tests/tests/media/src/android/media/cts/ResourceManagerTest.java
index 7305651..5f16bc5 100644
--- a/tests/tests/media/src/android/media/cts/ResourceManagerTest.java
+++ b/tests/tests/media/src/android/media/cts/ResourceManagerTest.java
@@ -23,13 +23,13 @@
         extends ActivityInstrumentationTestCase2<ResourceManagerStubActivity> {
 
     public ResourceManagerTest() {
-        super("com.android.cts.media", ResourceManagerStubActivity.class);
+        super("android.media.cts", ResourceManagerStubActivity.class);
     }
 
     private void doTestReclaimResource(int type1, int type2) throws Exception {
         Bundle extras = new Bundle();
         ResourceManagerStubActivity activity = launchActivity(
-                "com.android.cts.media", ResourceManagerStubActivity.class, extras);
+                "android.media.cts", ResourceManagerStubActivity.class, extras);
         activity.testReclaimResource(type1, type2);
         activity.finish();
     }
diff --git a/tests/tests/media/src/android/media/cts/ResourceManagerTestActivityBase.java b/tests/tests/media/src/android/media/cts/ResourceManagerTestActivityBase.java
index 689babb..76c7b0f 100644
--- a/tests/tests/media/src/android/media/cts/ResourceManagerTestActivityBase.java
+++ b/tests/tests/media/src/android/media/cts/ResourceManagerTestActivityBase.java
@@ -210,6 +210,7 @@
             Log.d(TAG, "useCodecs got CodecException 0x" + Integer.toHexString(e.getErrorCode()));
             if (e.getErrorCode() == MediaCodec.CodecException.ERROR_RECLAIMED) {
                 Log.d(TAG, "Remove codec " + current + " from the list");
+                mCodecs.get(current).release();
                 mCodecs.remove(current);
                 mGotReclaimedException = true;
                 mUseCodecs = false;
diff --git a/tests/tests/media/src/android/media/cts/RingtoneManagerTest.java b/tests/tests/media/src/android/media/cts/RingtoneManagerTest.java
index 4693036..0045577 100644
--- a/tests/tests/media/src/android/media/cts/RingtoneManagerTest.java
+++ b/tests/tests/media/src/android/media/cts/RingtoneManagerTest.java
@@ -15,7 +15,7 @@
  */
 package android.media.cts;
 
-import com.android.cts.media.R;
+import android.media.cts.R;
 
 
 import android.app.Activity;
@@ -34,7 +34,7 @@
 public class RingtoneManagerTest
         extends ActivityInstrumentationTestCase2<RingtonePickerActivity> {
 
-    private static final String PKG = "com.android.cts.media";
+    private static final String PKG = "android.media.cts";
     private static final String TAG = "RingtoneManagerTest";
 
     private RingtonePickerActivity mActivity;
diff --git a/tests/tests/media/src/android/media/cts/RingtoneTest.java b/tests/tests/media/src/android/media/cts/RingtoneTest.java
index 3527b1a..de21bdd 100644
--- a/tests/tests/media/src/android/media/cts/RingtoneTest.java
+++ b/tests/tests/media/src/android/media/cts/RingtoneTest.java
@@ -54,7 +54,14 @@
         mAudioManager.setStreamVolume(AudioManager.STREAM_RING, maxVolume / 2,
                 AudioManager.FLAG_ALLOW_RINGER_MODES);
         // make sure that we are not in silent mode
-        mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
+        try {
+            Utils.toggleNotificationPolicyAccess(
+                    mContext.getPackageName(), getInstrumentation(), true);
+            mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
+        } finally {
+            Utils.toggleNotificationPolicyAccess(
+                    mContext.getPackageName(), getInstrumentation(), false);
+        }
 
         mDefaultRingUri = RingtoneManager.getActualDefaultRingtoneUri(mContext,
                 RingtoneManager.TYPE_RINGTONE);
@@ -80,7 +87,14 @@
             mRingtone.setStreamType(mOriginalStreamType);
         }
         if (mAudioManager != null) {
-            mAudioManager.setRingerMode(mOriginalRingerMode);
+            try {
+                Utils.toggleNotificationPolicyAccess(
+                        mContext.getPackageName(), getInstrumentation(), true);
+                mAudioManager.setRingerMode(mOriginalRingerMode);
+            } finally {
+                Utils.toggleNotificationPolicyAccess(
+                        mContext.getPackageName(), getInstrumentation(), false);
+            }
             mAudioManager.setStreamVolume(AudioManager.STREAM_RING, mOriginalVolume,
                     AudioManager.FLAG_ALLOW_RINGER_MODES);
         }
diff --git a/tests/tests/media/src/android/media/cts/SoundPoolAacTest.java b/tests/tests/media/src/android/media/cts/SoundPoolAacTest.java
index a5eaf6b..9e37e39 100644
--- a/tests/tests/media/src/android/media/cts/SoundPoolAacTest.java
+++ b/tests/tests/media/src/android/media/cts/SoundPoolAacTest.java
@@ -16,7 +16,7 @@
 
 package android.media.cts;
 
-import com.android.cts.media.R;
+import android.media.cts.R;
 
 public class SoundPoolAacTest extends SoundPoolTest {
 
diff --git a/tests/tests/media/src/android/media/cts/SoundPoolMidiTest.java b/tests/tests/media/src/android/media/cts/SoundPoolMidiTest.java
index a8c640e..d7900e1 100644
--- a/tests/tests/media/src/android/media/cts/SoundPoolMidiTest.java
+++ b/tests/tests/media/src/android/media/cts/SoundPoolMidiTest.java
@@ -16,7 +16,7 @@
 
 package android.media.cts;
 
-import com.android.cts.media.R;
+import android.media.cts.R;
 
 public class SoundPoolMidiTest extends SoundPoolTest {
 
diff --git a/tests/tests/media/src/android/media/cts/SoundPoolOggTest.java b/tests/tests/media/src/android/media/cts/SoundPoolOggTest.java
index d35a93e..70330be 100644
--- a/tests/tests/media/src/android/media/cts/SoundPoolOggTest.java
+++ b/tests/tests/media/src/android/media/cts/SoundPoolOggTest.java
@@ -16,7 +16,7 @@
 
 package android.media.cts;
 
-import com.android.cts.media.R;
+import android.media.cts.R;
 
 public class SoundPoolOggTest extends SoundPoolTest {
 
diff --git a/tests/tests/media/src/android/media/cts/SoundPoolTest.java b/tests/tests/media/src/android/media/cts/SoundPoolTest.java
index 23c4a7c..9022731 100644
--- a/tests/tests/media/src/android/media/cts/SoundPoolTest.java
+++ b/tests/tests/media/src/android/media/cts/SoundPoolTest.java
@@ -16,7 +16,7 @@
 
 package android.media.cts;
 
-import com.android.cts.media.R;
+import android.media.cts.R;
 
 
 import android.content.Context;
diff --git a/tests/tests/media/src/android/media/cts/StreamingMediaPlayerTest.java b/tests/tests/media/src/android/media/cts/StreamingMediaPlayerTest.java
index ce61d76..0464cb6 100644
--- a/tests/tests/media/src/android/media/cts/StreamingMediaPlayerTest.java
+++ b/tests/tests/media/src/android/media/cts/StreamingMediaPlayerTest.java
@@ -80,6 +80,7 @@
                 + ".443B81C1E8E6D64E4E1555F568BA46C206507D78"
                 + "&key=ik0&user=android-device-test", 176, 144);
     }
+
     public void testHTTP_H263_AMR_Video2() throws Exception {
         if (!MediaUtils.checkDecoder(MediaFormat.MIMETYPE_VIDEO_H263, MediaFormat.MIMETYPE_AUDIO_AMR_NB)) {
             return; // skip
@@ -105,6 +106,7 @@
                 + ".7138CE5E36D718220726C1FC305497FF2D082249"
                 + "&key=ik0&user=android-device-test", 176, 144);
     }
+
     public void testHTTP_MPEG4SP_AAC_Video2() throws Exception {
         if (!MediaUtils.checkDecoder(MediaFormat.MIMETYPE_VIDEO_MPEG4)) {
             return; // skip
@@ -130,6 +132,7 @@
                 + ".15F46C382C68A9F121BA17BF1F56BEDEB4B06091"
                 + "&key=ik0&user=android-device-test", 640, 360);
     }
+
     public void testHTTP_H264Base_AAC_Video2() throws Exception {
         if (!MediaUtils.checkDecoder(MediaFormat.MIMETYPE_VIDEO_AVC)) {
             return; // skip
diff --git a/tests/tests/media/src/android/media/cts/StubMediaBrowserService.java b/tests/tests/media/src/android/media/cts/StubMediaBrowserService.java
index b5ba715..abea3f7 100644
--- a/tests/tests/media/src/android/media/cts/StubMediaBrowserService.java
+++ b/tests/tests/media/src/android/media/cts/StubMediaBrowserService.java
@@ -32,10 +32,13 @@
  * Stub implementation of (@link android.service.media.MediaBrowserService}.
  */
 public class StubMediaBrowserService extends MediaBrowserService {
-    static final String MEDIA_ID_ROOT = "test_media_id_root";
     static final String EXTRAS_KEY = "test_extras_key";
     static final String EXTRAS_VALUE = "test_extras_value";
+
+    static final String MEDIA_ID_INVALID = "test_media_id_invalid";
+    static final String MEDIA_ID_ROOT = "test_media_id_root";
     static final String MEDIA_ID_CHILDREN_DELAYED = "test_media_id_children_delayed";
+
     static final String[] MEDIA_ID_CHILDREN = new String[] {
         "test_media_id_children_0", "test_media_id_children_1",
         "test_media_id_children_2", "test_media_id_children_3",
@@ -77,6 +80,8 @@
             Assert.assertNull(mPendingLoadChildrenResult);
             mPendingLoadChildrenResult = result;
             result.detach();
+        } else if (MEDIA_ID_INVALID.equals(parentMediaId)){
+            result.sendResult(null);
         }
     }
 
diff --git a/tests/tests/media/src/android/media/cts/Utils.java b/tests/tests/media/src/android/media/cts/Utils.java
index bb9cf78..914a0518 100644
--- a/tests/tests/media/src/android/media/cts/Utils.java
+++ b/tests/tests/media/src/android/media/cts/Utils.java
@@ -18,9 +18,13 @@
 
 import android.app.Instrumentation;
 import android.app.UiAutomation;
+import android.content.ContentResolver;
+import android.content.Context;
 import android.os.ParcelFileDescriptor;
+import android.provider.Settings;
 
 import java.io.FileInputStream;
+import java.io.IOException;
 import java.io.InputStream;
 import java.util.Scanner;
 
@@ -67,4 +71,39 @@
             result = convertStreamToString(inputStream);
         }
     }
+
+    protected static void toggleNotificationPolicyAccess(String packageName,
+            Instrumentation instrumentation, boolean on) throws IOException {
+        Context context = instrumentation.getContext();
+
+        // Get permission to enable accessibility
+        UiAutomation uiAutomation = instrumentation.getUiAutomation();
+
+        ContentResolver cr = context.getContentResolver();
+        String alreadyEnabledServices = Settings.Secure.getString(
+                cr, Settings.Secure.ENABLED_NOTIFICATION_POLICY_ACCESS_PACKAGES);
+        ParcelFileDescriptor fd = null;
+        if (on) {
+            // Change the settings to enable the media cts package
+            fd = uiAutomation.executeShellCommand(
+                    "settings --user cur put secure "
+                            + Settings.Secure.ENABLED_NOTIFICATION_POLICY_ACCESS_PACKAGES + " "
+                            + alreadyEnabledServices + ":"
+                            + packageName);
+        } else {
+            int index =  alreadyEnabledServices.indexOf(":" + packageName);
+            if (index >= 0) {
+                fd = uiAutomation.executeShellCommand(
+                        "settings --user cur put secure "
+                                + Settings.Secure.ENABLED_NOTIFICATION_POLICY_ACCESS_PACKAGES + " "
+                                + alreadyEnabledServices.substring(0, index));
+            }
+        }
+        if (fd != null) {
+            InputStream in = new FileInputStream(fd.getFileDescriptor());
+            byte[] buffer = new byte[4096];
+            while (in.read(buffer) > 0) ;
+        }
+        uiAutomation.destroy();
+    }
 }
diff --git a/tests/tests/media/src/android/media/cts/VideoDecoderPerfTest.java b/tests/tests/media/src/android/media/cts/VideoDecoderPerfTest.java
index b14ea50..a153f78 100644
--- a/tests/tests/media/src/android/media/cts/VideoDecoderPerfTest.java
+++ b/tests/tests/media/src/android/media/cts/VideoDecoderPerfTest.java
@@ -16,7 +16,7 @@
 
 package android.media.cts;
 
-import com.android.cts.media.R;
+import android.media.cts.R;
 
 import android.content.Context;
 import android.content.res.AssetFileDescriptor;
@@ -36,7 +36,7 @@
 
 import com.android.cts.util.ResultType;
 import com.android.cts.util.ResultUnit;
-import com.android.cts.util.Stat;
+import com.android.compatibility.common.util.Stat;
 
 import java.nio.ByteBuffer;
 import java.util.Arrays;
@@ -488,16 +488,16 @@
                352, 288, true /* isGoog */);
     }
 
-    public void testHEVC0720x0480Other() throws Exception {
+    public void testHEVC0640x0360Other() throws Exception {
         decode(VIDEO_HEVC,
-               R.raw.video_720x480_mp4_hevc_1638kbps_30fps_aac_stereo_128kbps_44100hz,
-               720, 480, false /* isGoog */);
+               R.raw.video_640x360_mp4_hevc_1638kbps_30fps_aac_stereo_128kbps_44100hz,
+               640, 360, false /* isGoog */);
     }
 
-    public void testHEVC0720x0480Goog() throws Exception {
+    public void testHEVC0640x0360Goog() throws Exception {
         decode(VIDEO_HEVC,
-               R.raw.video_720x480_mp4_hevc_1638kbps_30fps_aac_stereo_128kbps_44100hz,
-               720, 480, true /* isGoog */);
+               R.raw.video_640x360_mp4_hevc_1638kbps_30fps_aac_stereo_128kbps_44100hz,
+               640, 360, true /* isGoog */);
     }
 
     public void testHEVC1280x0720Other() throws Exception {
diff --git a/tests/tests/media/src/android/media/cts/VideoEditorTest.java b/tests/tests/media/src/android/media/cts/VideoEditorTest.java
index 37a8246..c1097f8 100644
--- a/tests/tests/media/src/android/media/cts/VideoEditorTest.java
+++ b/tests/tests/media/src/android/media/cts/VideoEditorTest.java
@@ -16,7 +16,7 @@
 
 package android.media.cts;
 
-import com.android.cts.media.R;
+import android.media.cts.R;
 
 import android.test.ActivityInstrumentationTestCase2;
 
diff --git a/tests/tests/media/src/android/media/cts/VideoEncoderTest.java b/tests/tests/media/src/android/media/cts/VideoEncoderTest.java
index fb1521d..5edee65 100644
--- a/tests/tests/media/src/android/media/cts/VideoEncoderTest.java
+++ b/tests/tests/media/src/android/media/cts/VideoEncoderTest.java
@@ -16,7 +16,7 @@
 
 package android.media.cts;
 
-import com.android.cts.media.R;
+import android.media.cts.R;
 
 import android.media.cts.CodecUtils;
 
@@ -32,6 +32,7 @@
 import android.media.MediaCodecList;
 import android.media.MediaExtractor;
 import android.media.MediaFormat;
+import android.media.MediaMuxer;
 import android.net.Uri;
 import android.util.Log;
 import android.util.Pair;
@@ -39,9 +40,12 @@
 import android.util.Size;
 import android.view.Surface;
 
+import java.io.File;
 import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
+import java.util.function.Consumer;
+import java.util.function.Function;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -57,7 +61,7 @@
     private static final long INIT_TIMEOUT_MS = 2000;
 
     private static final String SOURCE_URL =
-        "android.resource://com.android.cts.media/raw/video_480x360_mp4_h264_871kbps_30fps";
+        "android.resource://android.media.cts/raw/video_480x360_mp4_h264_871kbps_30fps";
 
     private final boolean DEBUG = false;
 
@@ -168,9 +172,20 @@
     abstract class VideoProcessorBase extends MediaCodec.Callback {
         private static final String TAG = "VideoProcessorBase";
 
+        /*
+         * Set this to true to save the encoding results to /data/local/tmp
+         * You will need to make /data/local/tmp writeable, run "setenforce 0",
+         * and remove files left from a previous run.
+         */
+        private boolean mSaveResults = false;
+        private static final String FILE_DIR = "/data/local/tmp";
+        protected int mMuxIndex = -1;
+
+        protected String mProcessorName = "VideoProcessor";
         private MediaExtractor mExtractor;
+        protected MediaMuxer mMuxer;
         private ByteBuffer mBuffer = ByteBuffer.allocate(MAX_SAMPLE_SIZE);
-        private int mTrackIndex = -1;
+        protected int mTrackIndex = -1;
         private boolean mSignaledDecoderEOS;
 
         protected boolean mCompleted;
@@ -185,6 +200,21 @@
         protected int mFrameRate = 0;
         protected int mBitRate = 0;
 
+        protected Function<MediaFormat, Boolean> mUpdateConfigFormatHook;
+        protected Function<MediaFormat, Boolean> mCheckOutputFormatHook;
+
+        public void setProcessorName(String name) {
+            mProcessorName = name;
+        }
+
+        public void setUpdateConfigHook(Function<MediaFormat, Boolean> hook) {
+            mUpdateConfigFormatHook = hook;
+        }
+
+        public void setCheckOutputFormatHook(Function<MediaFormat, Boolean> hook) {
+            mCheckOutputFormatHook = hook;
+        }
+
         protected void open(String path) throws IOException {
             mExtractor = new MediaExtractor();
             if (path.startsWith("android.resource://")) {
@@ -209,8 +239,8 @@
 
         // returns true if encoder supports the size
         protected boolean initCodecsAndConfigureEncoder(
-                String videoEncName, String outMime, int width, int height, int colorFormat)
-                        throws IOException {
+                String videoEncName, String outMime, int width, int height,
+                int colorFormat) throws IOException {
             mDecFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, colorFormat);
 
             MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
@@ -230,7 +260,7 @@
             }
 
             MediaFormat outFmt = MediaFormat.createVideoFormat(outMime, width, height);
-
+            int bitRate = 0;
             {
                 int maxWidth = encCaps.getSupportedWidths().getUpper();
                 int maxHeight = encCaps.getSupportedHeightsFor(maxWidth).getUpper();
@@ -243,7 +273,7 @@
                 }
                 outFmt.setInteger(MediaFormat.KEY_FRAME_RATE, frameRate);
 
-                int bitRate = mBitRate;
+                bitRate = mBitRate;
                 if (bitRate <= 0) {
                     bitRate = encCaps.getBitrateRange().clamp(
                         (int)(encCaps.getBitrateRange().getUpper() /
@@ -255,8 +285,31 @@
             }
             outFmt.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 1);
             outFmt.setInteger(MediaFormat.KEY_COLOR_FORMAT, colorFormat);
+            // Some extra configure before starting the encoder.
+            if (mUpdateConfigFormatHook != null) {
+                if (!mUpdateConfigFormatHook.apply(outFmt)) {
+                    return false;
+                }
+            }
             mEncoder.configure(outFmt, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
             Log.i(TAG, "encoder input format " + mEncoder.getInputFormat() + " from " + outFmt);
+            if (mSaveResults) {
+                try {
+                    String outFileName =
+                            FILE_DIR + mProcessorName + "_" + bitRate + "bps";
+                    if (outMime.equals(MediaFormat.MIMETYPE_VIDEO_VP8) ||
+                            outMime.equals(MediaFormat.MIMETYPE_VIDEO_VP9)) {
+                        mMuxer = new MediaMuxer(
+                                outFileName + ".webm", MediaMuxer.OutputFormat.MUXER_OUTPUT_WEBM);
+                    } else {
+                        mMuxer = new MediaMuxer(
+                                outFileName + ".mp4", MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
+                    }
+                    // The track can't be added until we have the codec specific data
+                } catch (Exception e) {
+                    Log.i(TAG, "couldn't create muxer: " + e);
+                }
+            }
             return true;
         }
 
@@ -273,6 +326,11 @@
                 mExtractor.release();
                 mExtractor = null;
             }
+            if (mMuxer != null) {
+                mMuxer.stop();
+                mMuxer.release();
+                mMuxer = null;
+            }
         }
 
         // returns true if filled buffer
@@ -314,7 +372,16 @@
             if (DEBUG) Log.v(TAG, "encoder received output #" + ix
                      + " (sz=" + info.size + ", f=" + info.flags
                      + ", ts=" + info.presentationTimeUs + ")");
-            mEncodedStream.addBuffer(mEncoder.getOutputBuffer(ix), info);
+            ByteBuffer outputBuffer = mEncoder.getOutputBuffer(ix);
+            mEncodedStream.addBuffer(outputBuffer, info);
+
+            if (mMuxer != null) {
+                // reset position as addBuffer() modifies it
+                outputBuffer.position(info.offset);
+                outputBuffer.limit(info.offset + info.size);
+                mMuxer.writeSampleData(mMuxIndex, outputBuffer, info);
+            }
+
             if (!mCompleted) {
                 mEncoder.releaseOutputBuffer(ix, false);
                 if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
@@ -333,6 +400,15 @@
 
         protected void saveEncoderFormat(MediaFormat format) {
             mEncodedStream.setFormat(format);
+            if (mCheckOutputFormatHook != null) {
+                mCheckOutputFormatHook.apply(format);
+            }
+            if (mMuxer != null) {
+                if (mMuxIndex < 0) {
+                    mMuxIndex = mMuxer.addTrack(format);
+                    mMuxer.start();
+                }
+            }
         }
 
         public void playBack(Surface surface) {
@@ -770,7 +846,8 @@
     class Encoder {
         final private String mName;
         final private String mMime;
-        final private VideoCapabilities mCaps;
+        final private CodecCapabilities mCaps;
+        final private VideoCapabilities mVideoCaps;
 
         final private Map<Size, Set<Size>> mMinMax;     // extreme sizes
         final private Map<Size, Set<Size>> mNearMinMax; // sizes near extreme
@@ -784,7 +861,8 @@
         Encoder(String name, String mime, CodecCapabilities caps) {
             mName = name;
             mMime = mime;
-            mCaps = caps.getVideoCapabilities();
+            mCaps = caps;
+            mVideoCaps = caps.getVideoCapabilities();
 
             /* calculate min/max sizes */
             mMinMax = new HashMap<Size, Set<Size>>();
@@ -793,8 +871,8 @@
             mArbitraryH = new HashSet<Size>();
             mSizes = new HashSet<Size>();
 
-            xAlign = mCaps.getWidthAlignment();
-            yAlign = mCaps.getHeightAlignment();
+            xAlign = mVideoCaps.getWidthAlignment();
+            yAlign = mVideoCaps.getHeightAlignment();
 
             initializeSizes();
         }
@@ -811,16 +889,16 @@
                 int j = ((7 * i) % 11) + 1;
                 int width, height;
                 try {
-                    width = alignedPointInRange(i * 0.125, xAlign, mCaps.getSupportedWidths());
+                    width = alignedPointInRange(i * 0.125, xAlign, mVideoCaps.getSupportedWidths());
                     height = alignedPointInRange(
-                            j * 0.077, yAlign, mCaps.getSupportedHeightsFor(width));
+                            j * 0.077, yAlign, mVideoCaps.getSupportedHeightsFor(width));
                     mArbitraryW.add(new Size(width, height));
                 } catch (IllegalArgumentException e) {
                 }
 
                 try {
-                    height = alignedPointInRange(i * 0.125, yAlign, mCaps.getSupportedHeights());
-                    width = alignedPointInRange(j * 0.077, xAlign, mCaps.getSupportedWidthsFor(height));
+                    height = alignedPointInRange(i * 0.125, yAlign, mVideoCaps.getSupportedHeights());
+                    width = alignedPointInRange(j * 0.077, xAlign, mVideoCaps.getSupportedWidthsFor(height));
                     mArbitraryH.add(new Size(width, height));
                 } catch (IllegalArgumentException e) {
                 }
@@ -841,34 +919,34 @@
                 for (int dy = 0; dy <= yAlign; dy += yAlign) {
                     Set<Size> bucket = (dx + dy == 0) ? minMax : nearMinMax;
                     try {
-                        int width = getExtreme(mCaps.getSupportedWidths(), x, dx);
-                        int height = getExtreme(mCaps.getSupportedHeightsFor(width), y, dy);
+                        int width = getExtreme(mVideoCaps.getSupportedWidths(), x, dx);
+                        int height = getExtreme(mVideoCaps.getSupportedHeightsFor(width), y, dy);
                         bucket.add(new Size(width, height));
 
                         // try max max with more reasonable ratio if too skewed
                         if (x + y == 2 && width >= 4 * height) {
                             Size wideScreen = getLargestSizeForRatio(16, 9);
                             width = getExtreme(
-                                    mCaps.getSupportedWidths()
+                                    mVideoCaps.getSupportedWidths()
                                             .intersect(0, wideScreen.getWidth()), x, dx);
-                            height = getExtreme(mCaps.getSupportedHeightsFor(width), y, 0);
+                            height = getExtreme(mVideoCaps.getSupportedHeightsFor(width), y, 0);
                             bucket.add(new Size(width, height));
                         }
                     } catch (IllegalArgumentException e) {
                     }
 
                     try {
-                        int height = getExtreme(mCaps.getSupportedHeights(), y, dy);
-                        int width = getExtreme(mCaps.getSupportedWidthsFor(height), x, dx);
+                        int height = getExtreme(mVideoCaps.getSupportedHeights(), y, dy);
+                        int width = getExtreme(mVideoCaps.getSupportedWidthsFor(height), x, dx);
                         bucket.add(new Size(width, height));
 
                         // try max max with more reasonable ratio if too skewed
                         if (x + y == 2 && height >= 4 * width) {
                             Size wideScreen = getLargestSizeForRatio(9, 16);
                             height = getExtreme(
-                                    mCaps.getSupportedHeights()
+                                    mVideoCaps.getSupportedHeights()
                                             .intersect(0, wideScreen.getHeight()), y, dy);
-                            width = getExtreme(mCaps.getSupportedWidthsFor(height), x, dx);
+                            width = getExtreme(mVideoCaps.getSupportedWidthsFor(height), x, dx);
                             bucket.add(new Size(width, height));
                         }
                     } catch (IllegalArgumentException e) {
@@ -907,17 +985,17 @@
         }
 
         private Size getLargestSizeForRatio(int x, int y) {
-            Range<Integer> widthRange = mCaps.getSupportedWidths();
-            Range<Integer> heightRange = mCaps.getSupportedHeightsFor(widthRange.getUpper());
-            final int xAlign = mCaps.getWidthAlignment();
-            final int yAlign = mCaps.getHeightAlignment();
+            Range<Integer> widthRange = mVideoCaps.getSupportedWidths();
+            Range<Integer> heightRange = mVideoCaps.getSupportedHeightsFor(widthRange.getUpper());
+            final int xAlign = mVideoCaps.getWidthAlignment();
+            final int yAlign = mVideoCaps.getHeightAlignment();
 
             // scale by alignment
             int width = alignInRange(
                     Math.sqrt(widthRange.getUpper() * heightRange.getUpper() * (double)x / y),
                     xAlign, widthRange);
             int height = alignInRange(
-                    width * (double)y / x, yAlign, mCaps.getSupportedHeightsFor(width));
+                    width * (double)y / x, yAlign, mVideoCaps.getSupportedHeightsFor(width));
             return new Size(width, height);
         }
 
@@ -950,22 +1028,87 @@
             return test(width, height, true /* optional */, flexYUV);
         }
 
+        public boolean testIntraRefresh(int width, int height) {
+            final int refreshPeriod = 10;
+            if (!mCaps.isFeatureSupported(CodecCapabilities.FEATURE_IntraRefresh)) {
+                return false;
+            }
+
+            Function<MediaFormat, Boolean> updateConfigFormatHook =
+                    new Function<MediaFormat, Boolean>() {
+                public Boolean apply(MediaFormat fmt) {
+                    // set i-frame-interval to 10000 so encoded video only has 1 i-frame.
+                    fmt.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 10000);
+                    fmt.setInteger(MediaFormat.KEY_INTRA_REFRESH_PERIOD, refreshPeriod);
+                    return true;
+                }
+            };
+
+            Function<MediaFormat, Boolean> checkOutputFormatHook =
+                    new Function<MediaFormat, Boolean>() {
+                public Boolean apply(MediaFormat fmt) {
+                    int intraPeriod = fmt.getInteger(MediaFormat.KEY_INTRA_REFRESH_PERIOD);
+                    // Make sure intra period is correct and carried in the output format.
+                    // intraPeriod must be larger than 0 and not larger than what has been set.
+                    if (intraPeriod > refreshPeriod) {
+                        throw new RuntimeException("Intra period mismatch");
+                    }
+                    return true;
+                }
+            };
+
+            String testName =
+                    mName + '_' + width + "x" + height + '_' + "flexYUV_intraRefresh";
+
+            Consumer<VideoProcessorBase> configureVideoProcessor =
+                    new Consumer<VideoProcessorBase>() {
+                public void accept(VideoProcessorBase processor) {
+                    processor.setProcessorName(testName);
+                    processor.setUpdateConfigHook(updateConfigFormatHook);
+                    processor.setCheckOutputFormatHook(checkOutputFormatHook);
+                }
+            };
+
+            return test(width, height, 0 /* frameRate */, 0 /* bitRate */, true /* optional */,
+                    true /* flex */, configureVideoProcessor);
+        }
+
         public boolean testDetailed(
                 int width, int height, int frameRate, int bitRate, boolean flexYUV) {
-            return test(width, height, frameRate, bitRate, true /* optional */, flexYUV);
+            String testName =
+                    mName + '_' + width + "x" + height + '_' + (flexYUV ? "flexYUV" : " surface");
+            Consumer<VideoProcessorBase> configureVideoProcessor =
+                    new Consumer<VideoProcessorBase>() {
+                public void accept(VideoProcessorBase processor) {
+                    processor.setProcessorName(testName);
+                }
+            };
+            return test(width, height, frameRate, bitRate, true /* optional */, flexYUV,
+                    configureVideoProcessor);
         }
 
         public boolean testSupport(int width, int height, int frameRate, int bitRate) {
-            return mCaps.areSizeAndRateSupported(width, height, frameRate) &&
-                    mCaps.getBitrateRange().contains(bitRate);
+            return mVideoCaps.areSizeAndRateSupported(width, height, frameRate) &&
+                    mVideoCaps.getBitrateRange().contains(bitRate);
         }
 
-        private boolean test(int width, int height, boolean optional, boolean flexYUV) {
-            return test(width, height, 0 /* frameRate */, 0 /* bitRate */, optional, flexYUV);
+        private boolean test(
+                int width, int height, boolean optional, boolean flexYUV) {
+            String testName =
+                    mName + '_' + width + "x" + height + '_' + (flexYUV ? "flexYUV" : " surface");
+            Consumer<VideoProcessorBase> configureVideoProcessor =
+                    new Consumer<VideoProcessorBase>() {
+                public void accept(VideoProcessorBase processor) {
+                    processor.setProcessorName(testName);
+                }
+            };
+            return test(width, height, 0 /* frameRate */, 0 /* bitRate */,
+                    optional, flexYUV, configureVideoProcessor);
         }
 
-        private boolean test(int width, int height, int frameRate, int bitRate,
-                boolean optional, boolean flexYUV) {
+        private boolean test(
+                int width, int height, int frameRate, int bitRate, boolean optional,
+                boolean flexYUV, Consumer<VideoProcessorBase> configureVideoProcessor) {
             Log.i(TAG, "testing " + mMime + " on " + mName + " for " + width + "x" + height
                     + (flexYUV ? " flexYUV" : " surface"));
 
@@ -973,6 +1116,7 @@
                 flexYUV ? new VideoProcessor() : new SurfaceVideoProcessor();
 
             processor.setFrameAndBitRates(frameRate, bitRate);
+            configureVideoProcessor.accept(processor);
 
             // We are using a resource URL as an example
             boolean success = processor.processLoop(
@@ -1409,6 +1553,46 @@
     public void testOtherVP9Flex1080p()   { specific(otherVP9(),   1920, 1080, true /* flex */); }
     public void testOtherVP9Surf1080p()   { specific(otherVP9(),   1920, 1080, false /* flex */); }
 
+    public void testGoogH265Flex360pWithIntraRefresh() {
+        intraRefresh(googH265(), 480, 360);
+    }
+
+    public void testGoogH264Flex360pWithIntraRefresh() {
+        intraRefresh(googH264(), 480, 360);
+    }
+
+    public void testGoogH263Flex360pWithIntraRefresh() {
+        intraRefresh(googH263(), 480, 360);
+    }
+
+    public void testGoogMpeg4Flex360pWithIntraRefresh() {
+        intraRefresh(googMpeg4(), 480, 360);
+    }
+
+    public void testGoogVP8Flex360pWithIntraRefresh() {
+        intraRefresh(googVP8(), 480, 360);
+    }
+
+    public void testOtherH265Flex360pWithIntraRefresh() {
+        intraRefresh(otherH265(), 480, 360);
+    }
+
+    public void testOtherH264Flex360pWithIntraRefresh() {
+        intraRefresh(otherH264(), 480, 360);
+    }
+
+    public void testOtherH263FlexQCIFWithIntraRefresh() {
+        intraRefresh(otherH263(), 176, 120);
+    }
+
+    public void testOtherMpeg4Flex360pWithIntraRefresh() {
+        intraRefresh(otherMpeg4(), 480, 360);
+    }
+
+    public void testOtherVP8Flex360pWithIntraRefresh() {
+        intraRefresh(otherVP8(), 480, 360);
+    }
+
     // Tests encoder profiles required by CDD.
     // H264
     public void testH264LowQualitySDSupport()   {
@@ -1581,6 +1765,23 @@
         }
     }
 
+    /* test intra refresh with flexYUV */
+    private void intraRefresh(Encoder[] encoders, int width, int height) {
+        boolean skipped = true;
+        if (encoders.length == 0) {
+            MediaUtils.skipTest("no such encoder present");
+            return;
+        }
+        for (Encoder encoder : encoders) {
+            if (encoder.testIntraRefresh(width, height)) {
+                skipped = false;
+            }
+        }
+        if (skipped) {
+            MediaUtils.skipTest("intra-refresh unsupported");
+        }
+    }
+
     /* test size, frame rate and bit rate */
     private void detailed(
             Encoder[] encoders, int width, int height, int frameRate, int bitRate,
diff --git a/tests/tests/media/src/android/media/cts/VideoSurfaceView.java b/tests/tests/media/src/android/media/cts/VideoSurfaceView.java
index 229c6f6..76c3015 100644
--- a/tests/tests/media/src/android/media/cts/VideoSurfaceView.java
+++ b/tests/tests/media/src/android/media/cts/VideoSurfaceView.java
@@ -16,7 +16,7 @@
 
 package android.media.cts;
 
-import com.android.cts.media.R;
+import android.media.cts.R;
 
 import java.io.IOException;
 
diff --git a/tests/tests/media/src/android/media/cts/VirtualizerTest.java b/tests/tests/media/src/android/media/cts/VirtualizerTest.java
index ac8eb84..0fc9f31 100644
--- a/tests/tests/media/src/android/media/cts/VirtualizerTest.java
+++ b/tests/tests/media/src/android/media/cts/VirtualizerTest.java
@@ -24,7 +24,7 @@
 import android.test.AndroidTestCase;
 import android.util.Log;
 
-import com.android.cts.media.R;
+import android.media.cts.R;
 
 import java.util.Arrays;
 
diff --git a/tests/tests/media/src/android/media/cts/VisualizerTest.java b/tests/tests/media/src/android/media/cts/VisualizerTest.java
index 0d46ca7..141e339 100644
--- a/tests/tests/media/src/android/media/cts/VisualizerTest.java
+++ b/tests/tests/media/src/android/media/cts/VisualizerTest.java
@@ -16,7 +16,7 @@
 
 package android.media.cts;
 
-import com.android.cts.media.R;
+import android.media.cts.R;
 
 import android.content.Context;
 import android.media.audiofx.AudioEffect;
diff --git a/tests/tests/media/src/android/media/cts/Vp8CodecTestBase.java b/tests/tests/media/src/android/media/cts/Vp8CodecTestBase.java
index 133b91d..0395ec7 100644
--- a/tests/tests/media/src/android/media/cts/Vp8CodecTestBase.java
+++ b/tests/tests/media/src/android/media/cts/Vp8CodecTestBase.java
@@ -30,7 +30,7 @@
 import android.os.Handler;
 import android.test.AndroidTestCase;
 import android.util.Log;
-import com.android.cts.media.R;
+import android.media.cts.R;
 
 import java.io.File;
 import java.io.FileInputStream;
diff --git a/tests/tests/media/src/android/media/cts/Vp8EncoderTest.java b/tests/tests/media/src/android/media/cts/Vp8EncoderTest.java
index be7e721..5552f6c 100644
--- a/tests/tests/media/src/android/media/cts/Vp8EncoderTest.java
+++ b/tests/tests/media/src/android/media/cts/Vp8EncoderTest.java
@@ -21,7 +21,7 @@
 import android.media.MediaCodecList;
 import android.media.MediaFormat;
 import android.util.Log;
-import com.android.cts.media.R;
+import android.media.cts.R;
 
 import java.io.File;
 import java.util.ArrayList;
diff --git a/tests/tests/media/src/android/media/cts/WifiStatus.java b/tests/tests/media/src/android/media/cts/WifiStatus.java
new file mode 100644
index 0000000..c2577f1
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/WifiStatus.java
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.media.cts;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.net.Uri;
+import android.net.wifi.WifiInfo;
+import android.net.wifi.WifiManager;
+import android.util.Log;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.io.IOException;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+
+/**
+ * A class that implements IConnectionStatus interface
+ * to report and test Wifi connection.
+ */
+public class WifiStatus implements IConnectionStatus {
+
+    private static final String TAG = "WifiStatus";
+
+    private ConnectivityManager mConnectivityManager;
+    private WifiManager mWifiManager;
+
+    public WifiStatus(Context context) {
+        mConnectivityManager =
+                (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
+        mWifiManager = (WifiManager)context.getSystemService(Context.WIFI_SERVICE);
+    }
+
+    public String getNotConnectedReason() {
+        NetworkInfo networkInfo = mConnectivityManager.getActiveNetworkInfo();
+        if (networkInfo != null) {
+            return networkInfo.getReason();
+        } else {
+            return "Cannot get network info";
+        }
+    }
+
+    public boolean isAvailable() {
+        NetworkInfo networkInfo = mConnectivityManager.getActiveNetworkInfo();
+        return (networkInfo != null) && networkInfo.isAvailable();
+    }
+
+    public boolean isConnected() {
+        NetworkInfo networkInfo = mConnectivityManager.getActiveNetworkInfo();
+        return (networkInfo != null) && networkInfo.isConnected();
+    }
+
+    public boolean isEnabled() {
+        return mWifiManager.isWifiEnabled();
+    }
+
+    public void printConnectionInfo() {
+        WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
+        if (wifiInfo == null) {
+          throw new Error("Fail to get Wifi connection info");
+        }
+
+        Log.d(TAG, "ssid=" + wifiInfo.getSSID());
+        Log.d(TAG, "frequency=" + wifiInfo.getFrequency() + " " + WifiInfo.FREQUENCY_UNITS);
+        Log.d(TAG, "rssi=" + wifiInfo.getRssi() + " dBm");
+        Log.d(TAG, "link speed=" + wifiInfo.getLinkSpeed() + " " + WifiInfo.LINK_SPEED_UNITS);
+    }
+
+    /**
+     * Print lines.
+     *
+     * Print lines in ArrayList<String>
+     *
+     * @param lines ArrayList<String>
+     */
+    private void printLines(final ArrayList<String> lines) {
+        for (String line : lines) {
+            Log.d(TAG, line);
+        }
+    }
+
+    /**
+     * Perform ping test.
+     *
+     * @param server Server to ping
+     * @return true for success, false for failure
+     */
+    private boolean pingTest(String server) {
+        final long PING_RETRIES = 10;
+        if (server == null || server.isEmpty()) {
+            Log.e(TAG, "Null or empty server name to ping.");
+            return false;
+        }
+
+        int retries = 0;
+        while (retries++ <= PING_RETRIES) {
+            try {
+                Log.d(TAG, "Try pinging " + server);
+                // -c: ping 5 times, -w: limit to 20 seconds
+                Process p = Runtime.getRuntime().exec("ping -c 5 -w 20 " + server);
+                ArrayList<String> lines = new ArrayList<String>();
+                String line;
+                BufferedReader reader = new BufferedReader(
+                        new InputStreamReader(p.getInputStream()));
+                while ((line = reader.readLine()) != null) {
+                    lines.add(line);
+                }
+                printLines(lines);
+                lines.clear();
+
+                // print error if any
+                reader = new BufferedReader(
+                        new InputStreamReader(p.getErrorStream()));
+                while ((line = reader.readLine()) != null) {
+                    lines.add(line);
+                }
+                printLines(lines);
+                if (p.waitFor() == 0) {
+                    return true;
+                }
+            } catch (UnknownHostException e) {
+                Log.e(TAG, "ping not run: Unknown Host");
+                break;
+            } catch (IOException e) {
+                // e.g. if ping is not on the device
+                Log.e(TAG, "ping not found: IOException");
+                break;
+            } catch (InterruptedException e) {
+                Log.e(TAG, "ping failed: InterruptedException");
+                break;
+            }
+        }
+
+        // ping test timeout
+        return false;
+    }
+
+    public void testConnection(Uri uri) {
+        final String GOOG = "www.google.com";
+
+        if (pingTest(GOOG)) {
+            Log.d(TAG, "Successfully pinged " + GOOG);
+        } else {
+            Log.e(TAG, "Failed to ping " + GOOG);
+        }
+
+        if (pingTest(uri.getHost())) {
+            Log.d(TAG, "Successfully pinged " + uri.getHost());
+        } else {
+            Log.e(TAG, "Failed to ping " + uri.getHost());
+        }
+    }
+}
+
diff --git a/tests/tests/media/src/android/media/cts/YUVImage.java b/tests/tests/media/src/android/media/cts/YUVImage.java
new file mode 100644
index 0000000..bf2c5e7
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/YUVImage.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.media.cts;
+
+import android.graphics.ImageFormat;
+import android.graphics.Point;
+
+import android.media.cts.CodecImage;
+import android.media.cts.CodecUtils;
+
+import java.nio.ByteBuffer;
+
+public class YUVImage extends CodecImage {
+    private final int mImageWidth;
+    private final int mImageHeight;
+    private final Plane[] mPlanes;
+
+    public YUVImage(
+            Point origin,
+            int imageWidth, int imageHeight,
+            int arrayWidth, int arrayHeight,
+            boolean semiPlanar,
+            ByteBuffer bufferY, ByteBuffer bufferUV) {
+        mImageWidth = imageWidth;
+        mImageHeight = imageHeight;
+        ByteBuffer dupY = bufferY.duplicate();
+        ByteBuffer dupUV = bufferUV.duplicate();
+        mPlanes = new Plane[3];
+
+        int srcOffsetY = origin.x + origin.y * arrayWidth;
+
+        mPlanes[0] = new YUVPlane(
+                mImageWidth, mImageHeight, arrayWidth, 1,
+                dupY, srcOffsetY);
+
+        if (semiPlanar) {
+            int srcOffsetUV = origin.y / 2 * arrayWidth + origin.x / 2 * 2;
+
+            mPlanes[1] = new YUVPlane(
+                    mImageWidth / 2, mImageHeight / 2, arrayWidth, 2,
+                    dupUV, srcOffsetUV);
+            mPlanes[2] = new YUVPlane(
+                    mImageWidth / 2, mImageHeight / 2, arrayWidth, 2,
+                    dupUV, srcOffsetUV + 1);
+        } else {
+            int srcOffsetU = origin.y / 2 * arrayWidth / 2 + origin.x / 2;
+            int srcOffsetV = srcOffsetU + arrayWidth / 2 * arrayHeight / 2;
+
+            mPlanes[1] = new YUVPlane(
+                    mImageWidth / 2, mImageHeight / 2, arrayWidth / 2, 1,
+                    dupUV, srcOffsetU);
+            mPlanes[2] = new YUVPlane(
+                    mImageWidth / 2, mImageHeight / 2, arrayWidth / 2, 1,
+                    dupUV, srcOffsetV);
+        }
+    }
+
+    @Override
+    public int getFormat() {
+        return ImageFormat.YUV_420_888;
+    }
+
+    @Override
+    public int getWidth() {
+        return mImageWidth;
+    }
+
+    @Override
+    public int getHeight() {
+        return mImageHeight;
+    }
+
+    @Override
+    public long getTimestamp() {
+        return 0;
+    }
+
+    @Override
+    public Plane[] getPlanes() {
+        return mPlanes;
+    }
+
+    @Override
+    public void close() {
+        mPlanes[0] = null;
+        mPlanes[1] = null;
+        mPlanes[2] = null;
+    }
+
+    class YUVPlane extends CodecImage.Plane {
+        private final int mRowStride;
+        private final int mPixelStride;
+        private final ByteBuffer mByteBuffer;
+
+        YUVPlane(int w, int h, int rowStride, int pixelStride,
+                ByteBuffer buffer, int offset) {
+            mRowStride = rowStride;
+            mPixelStride = pixelStride;
+
+            // only safe to access length bytes starting from buffer[offset]
+            int length = (h - 1) * rowStride + (w - 1) * pixelStride + 1;
+
+            buffer.position(offset);
+            mByteBuffer = buffer.slice();
+            mByteBuffer.limit(length);
+        }
+
+        @Override
+        public int getRowStride() {
+            return mRowStride;
+        }
+
+        @Override
+        public int getPixelStride() {
+            return mPixelStride;
+        }
+
+        @Override
+        public ByteBuffer getBuffer() {
+            return mByteBuffer;
+        }
+    }
+}
+
diff --git a/tests/tests/mediastress/Android.mk b/tests/tests/mediastress/Android.mk
index d78ddac..8667e68 100644
--- a/tests/tests/mediastress/Android.mk
+++ b/tests/tests/mediastress/Android.mk
@@ -20,12 +20,17 @@
 
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 # Include both the 32 and 64 bit versions
 LOCAL_MULTILIB := both
 
 LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner ctsdeviceutil
 
-LOCAL_JNI_SHARED_LIBRARIES := libctsmediastress_jni
+LOCAL_HOST_SHARED_LIBRARIES := compatibility-device-media-preconditions
+
+LOCAL_JNI_SHARED_LIBRARIES := libctsmediastress_jni libnativehelper_compat_libc++
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
@@ -33,8 +38,6 @@
 
 LOCAL_SDK_VERSION := current
 
-cts_runtime_hint := 170
-
 include $(BUILD_CTS_PACKAGE)
 
 include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/tests/mediastress/AndroidManifest.xml b/tests/tests/mediastress/AndroidManifest.xml
index 9d48c8c..e4ab36c 100644
--- a/tests/tests/mediastress/AndroidManifest.xml
+++ b/tests/tests/mediastress/AndroidManifest.xml
@@ -15,7 +15,7 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-        package="com.android.cts.mediastress">
+        package="android.mediastress.cts">
 
     <uses-permission android:name="android.permission.CAMERA" />
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
@@ -40,7 +40,7 @@
                   android:label="NativeMedia" />
     </application>
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-            android:targetPackage="com.android.cts.mediastress"
+            android:targetPackage="android.mediastress.cts"
             android:label="Media stress tests InstrumentationRunner" >
         <meta-data android:name="listener"
             android:value="com.android.cts.runner.CtsTestRunListener" />
diff --git a/tests/tests/mediastress/AndroidTest.xml b/tests/tests/mediastress/AndroidTest.xml
new file mode 100644
index 0000000..43eae94
--- /dev/null
+++ b/tests/tests/mediastress/AndroidTest.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS Media Stress test cases">
+    <target_preparer class="android.mediastress.cts.preconditions.MediaPreparer" />
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsMediaStressTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.mediastress.cts" />
+    </test>
+</configuration>
diff --git a/tests/tests/mediastress/jni/Android.mk b/tests/tests/mediastress/jni/Android.mk
index 26ff647..164e302 100644
--- a/tests/tests/mediastress/jni/Android.mk
+++ b/tests/tests/mediastress/jni/Android.mk
@@ -26,6 +26,7 @@
 
 LOCAL_C_INCLUDES += $(call include-path-for, wilhelm)
 
-LOCAL_SHARED_LIBRARIES := libandroid libnativehelper liblog libOpenMAXAL
+LOCAL_SHARED_LIBRARIES := libandroid libnativehelper_compat_libc++ liblog libOpenMAXAL
+LOCAL_CXX_STL := libc++_static
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/tests/tests/mediastress/preconditions/Android.mk b/tests/tests/mediastress/preconditions/Android.mk
new file mode 100644
index 0000000..139bf23
--- /dev/null
+++ b/tests/tests/mediastress/preconditions/Android.mk
@@ -0,0 +1,34 @@
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_JAVA_LIBRARIES := compatibility-host-util cts-tradefed tradefed-prebuilt
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE := compatibility-host-media-preconditions
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_HOST_JAVA_LIBRARY)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/tests/mediastress/preconditions/src/android/mediastress/cts/preconditions/MediaPreparer.java b/tests/tests/mediastress/preconditions/src/android/mediastress/cts/preconditions/MediaPreparer.java
new file mode 100644
index 0000000..7254045
--- /dev/null
+++ b/tests/tests/mediastress/preconditions/src/android/mediastress/cts/preconditions/MediaPreparer.java
@@ -0,0 +1,354 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.mediastress.cts.preconditions;
+
+import com.android.compatibility.common.tradefed.targetprep.PreconditionPreparer;
+import com.android.compatibility.common.util.DynamicConfigHostSide;
+import com.android.ddmlib.IDevice;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.config.Option;
+import com.android.tradefed.config.OptionClass;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.targetprep.BuildError;
+import com.android.tradefed.targetprep.TargetSetupError;
+import com.android.tradefed.util.FileUtil;
+import com.android.tradefed.util.ZipUtil;
+
+import java.awt.Dimension;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.zip.ZipFile;
+
+import org.xmlpull.v1.XmlPullParserException;
+
+/**
+ * Ensures that the appropriate media files exist on the device
+ */
+@OptionClass(alias="media-preparer")
+public class MediaPreparer extends PreconditionPreparer {
+
+    @Option(name = "local-media-path",
+            description = "Absolute path of the media files directory, containing" +
+            "'bbb_short' and 'bbb_full' directories")
+    protected String mLocalMediaPath = null;
+
+    @Option(name = "skip-media-download",
+            description = "Whether to skip the media files precondition")
+    protected boolean mSkipMediaDownload = false;
+
+    /*
+     * The default name of local directory into which media files will be downloaded, if option
+     * "local-media-path" is not provided. This directory will live inside the temp directory.
+     */
+    protected static final String MEDIA_FOLDER_NAME = "android-cts-media";
+
+    /* The key used to retrieve the media files URL from the dynamic configuration */
+    private static final String MEDIA_FILES_URL_KEY = "MediaFilesUrl";
+
+    /* For a target preparer, the "module" of the configuration is the test suite */
+    private static final String DYNAMIC_CONFIG_MODULE = "cts";
+
+    /*
+     * The message printed when the maximum video playback resolution cannot be found in the
+     * output of 'dumpsys'. When this is the case, media files of all resolutions must be pushed
+     * to the device.
+     */
+    private static final String MAX_PLAYBACK_RES_FAILURE_MSG =
+            "Unable to parse maximum video playback resolution, pushing all media files";
+
+    private static final String LOG_TAG = MediaPreparer.class.getSimpleName();
+
+    /* Constants identifying resolutions of the media files to be copied */
+    protected static final int RES_176_144 = 0; // 176x144 resolution
+    protected static final int RES_DEFAULT = 1; // default max video playback resolution, 480x360
+    protected static final int RES_720_480 = 2; // 720x480 resolution
+    protected static final int RES_1280_720 = 3; // 1280x720 resolution
+    protected static final int RES_1920_1080 = 4; // 1920x1080 resolution
+
+    protected static final Dimension[] resolutions = { // indices meant to align with constants above
+            new Dimension(176, 144),
+            new Dimension(480, 360),
+            new Dimension(720, 480),
+            new Dimension(1280, 720),
+            new Dimension(1920, 1080)
+    };
+
+    /*
+     * The pathnames of the device's directories that hold media files for the tests.
+     * These depend on the device's mount point, which is retrieved in the MediaPreparer's run
+     * method.
+     *
+     * These fields are exposed for unit testing
+     */
+    protected String baseDeviceShortDir;
+    protected String baseDeviceFullDir;
+
+    /*
+     * Returns a string representation of the dimension
+     * For dimension of width = 480 and height = 360, the resolution string is "480x360"
+     */
+    private static String resolutionString(Dimension resolution) {
+        return String.format("%dx%d", resolution.width, resolution.height);
+    }
+
+    /*
+     * Loops through the predefined maximum video playback resolutions from largest to smallest,
+     * And returns the greatest resolution that is strictly smaller than the width and height
+     * provided in the arguments
+     */
+    private Dimension getMaxVideoPlaybackResolution(int width, int height) {
+        for (int resIndex = resolutions.length - 1; resIndex >= RES_DEFAULT; resIndex--) {
+            Dimension resolution = resolutions[resIndex];
+            if (width >= resolution.width && height >= resolution.height) {
+                return resolution;
+            }
+        }
+        return resolutions[RES_DEFAULT];
+    }
+
+    /*
+     * Returns the maximum video playback resolution of the device, in the form of a Dimension
+     * object. This method parses dumpsys output to find resolutions listed under the
+     * 'mBaseDisplayInfo' field. The value for 'smallest app' is used as an estimate for
+     * maximum video playback resolution, and is rounded down to the nearest dimension in the
+     * resolutions array.
+     *
+     * This method is exposed for unit testing.
+     */
+    protected Dimension getMaxVideoPlaybackResolution(ITestDevice device)
+            throws DeviceNotAvailableException {
+        String dumpsysOutput =
+                device.executeShellCommand("dumpsys display | grep mBaseDisplayInfo");
+        Pattern pattern = Pattern.compile("smallest app (\\d+) x (\\d+)");
+        Matcher matcher = pattern.matcher(dumpsysOutput);
+        if(!matcher.find()) {
+            // could not find resolution in dumpsysOutput, return largest max playback resolution
+            // so that preparer copies all media files
+            logError(MAX_PLAYBACK_RES_FAILURE_MSG);
+            return resolutions[RES_1920_1080];
+        }
+
+        int first;
+        int second;
+        try {
+            first = Integer.parseInt(matcher.group(1));
+            second = Integer.parseInt(matcher.group(2));
+        } catch (NumberFormatException e) {
+            logError(MAX_PLAYBACK_RES_FAILURE_MSG);
+            return resolutions[RES_1920_1080];
+        }
+        // dimensions in dumpsys output seem consistently reversed
+        // here we make note of which dimension is the larger of the two
+        int height = Math.min(first, second);
+        int width = Math.max(first, second);
+        return getMaxVideoPlaybackResolution(width, height);
+    }
+
+    /*
+     * Returns true if all necessary media files exist on the device, and false otherwise.
+     *
+     * This method is exposed for unit testing.
+     */
+    protected boolean mediaFilesExistOnDevice(ITestDevice device, Dimension mvpr)
+            throws DeviceNotAvailableException{
+        int resIndex = RES_176_144;
+        while (resIndex <= RES_1920_1080) {
+            Dimension copiedResolution = resolutions[resIndex];
+            if (copiedResolution.width > mvpr.width || copiedResolution.height > mvpr.height) {
+                break; // we don't need to check for resolutions greater than or equal to this
+            }
+            String resString = resolutionString(copiedResolution);
+            String deviceShortFilePath = baseDeviceShortDir + resString;
+            String deviceFullFilePath = baseDeviceFullDir + resString;
+            if (!device.doesFileExist(deviceShortFilePath) ||
+                    !device.doesFileExist(deviceFullFilePath)) { // media files must be copied
+                return false;
+            }
+            resIndex++;
+        }
+        return true;
+    }
+
+    /*
+     * After downloading and unzipping the media files, mLocalMediaPath must be the path to the
+     * directory containing 'bbb_short' and 'bbb_full' directories, as it is defined in its
+     * description as an option.
+     * After extraction, this directory exists one level below the the directory 'mediaFolder'.
+     * If the 'mediaFolder' contains anything other than exactly one subdirectory, a
+     * TargetSetupError is thrown. Otherwise, the mLocalMediaPath variable is set to the path of
+     * this subdirectory.
+     */
+    private void updateLocalMediaPath(File mediaFolder) throws TargetSetupError {
+        String[] subDirs = mediaFolder.list();
+        if (subDirs.length != 1) {
+            throw new TargetSetupError(String.format(
+                    "Unexpected contents in directory %s", mLocalMediaPath));
+        }
+        File newMediaFolder = new File(mediaFolder, subDirs[0]);
+        mLocalMediaPath = newMediaFolder.toString();
+    }
+
+    /*
+     * Copies the media files to the host from a predefined URL
+     * Updates mLocalMediaPath to be the pathname of the directory containing bbb_short and
+     * bbb_full media directories.
+     */
+    private void downloadMediaToHost() throws TargetSetupError {
+
+        URL url;
+        try {
+            DynamicConfigHostSide config = new DynamicConfigHostSide(DYNAMIC_CONFIG_MODULE);
+            String mediaUrlString = config.getValue(MEDIA_FILES_URL_KEY);
+            url = new URL(mediaUrlString);
+        } catch (IOException | XmlPullParserException e) {
+            throw new TargetSetupError("Trouble finding media file download location with " +
+                    "dynamic configuration");
+        }
+
+        File mediaFolder = new File(mLocalMediaPath);
+        File mediaFolderZip = new File(mediaFolder.getName() + ".zip");
+        try {
+
+            mediaFolder.mkdirs();
+            mediaFolderZip.createNewFile();
+
+            URLConnection conn = url.openConnection();
+            InputStream in = conn.getInputStream();
+            BufferedOutputStream out =
+                    new BufferedOutputStream(new FileOutputStream(mediaFolderZip));
+            byte[] buffer = new byte[1024];
+            int count;
+            logInfo("Downloading media files to host");
+            while ((count = in.read(buffer)) >= 0) {
+                out.write(buffer, 0, count);
+            }
+            out.flush();
+            out.close();
+            in.close();
+
+            logInfo("Unzipping media files");
+            ZipUtil.extractZip(new ZipFile(mediaFolderZip), mediaFolder);
+
+        } catch (IOException e) {
+            FileUtil.recursiveDelete(mediaFolder);
+            FileUtil.recursiveDelete(mediaFolderZip);
+            throw new TargetSetupError("Failed to open media files on host");
+        }
+    }
+
+    /*
+     * Pushes directories containing media files to the device for all directories that:
+     * - are not already present on the device
+     * - contain video files of a resolution less than or equal to the device's
+     *       max video playback resolution
+     *
+     * This method is exposed for unit testing.
+     */
+    protected void copyMediaFiles(ITestDevice device, Dimension mvpr)
+            throws DeviceNotAvailableException {
+
+        int resIndex = RES_176_144;
+        while (resIndex <= RES_1920_1080) {
+            Dimension copiedResolution = resolutions[resIndex];
+            String resString = resolutionString(copiedResolution);
+            if (copiedResolution.width > mvpr.width || copiedResolution.height > mvpr.height) {
+                logInfo("Device cannot support resolutions %s and larger, media copying complete",
+                        resString);
+                return;
+            }
+            String deviceShortFilePath = baseDeviceShortDir + resString;
+            String deviceFullFilePath = baseDeviceFullDir + resString;
+            if (!device.doesFileExist(deviceShortFilePath) ||
+                    !device.doesFileExist(deviceFullFilePath)) {
+                logInfo("Copying files of resolution %s to device", resString);
+                String localShortDirName = "bbb_short/" + resString;
+                String localFullDirName = "bbb_full/" + resString;
+                File localShortDir = new File(mLocalMediaPath, localShortDirName);
+                File localFullDir = new File(mLocalMediaPath, localFullDirName);
+                // push short directory of given resolution, if not present on device
+                if(!device.doesFileExist(deviceShortFilePath)) {
+                    device.pushDir(localShortDir, deviceShortFilePath);
+                }
+                // push full directory of given resolution, if not present on device
+                if(!device.doesFileExist(deviceFullFilePath)) {
+                    device.pushDir(localFullDir, deviceFullFilePath);
+                }
+            }
+            resIndex++;
+        }
+    }
+
+    // Initialize directory strings where media files live on device
+    protected void setMountPoint(ITestDevice device) {
+        String mountPoint = device.getMountPoint(IDevice.MNT_EXTERNAL_STORAGE);
+        baseDeviceShortDir = String.format("%s/test/bbb_short/", mountPoint);
+        baseDeviceFullDir = String.format("%s/test/bbb_full/", mountPoint);
+    }
+
+    @Override
+    public void run(ITestDevice device, IBuildInfo buildInfo) throws TargetSetupError,
+            BuildError, DeviceNotAvailableException {
+
+        if (mSkipMediaDownload) {
+            // skip this precondition
+            return;
+        }
+
+        setMountPoint(device);
+        Dimension mvpr = getMaxVideoPlaybackResolution(device);
+        if (mediaFilesExistOnDevice(device, mvpr)) {
+            // if files already on device, do nothing
+            logInfo("Media files found on the device");
+            return;
+        }
+
+        File mediaFolder;
+        if (mLocalMediaPath == null) {
+            // Option 'local-media-path' has not been defined
+            try {
+                // find system's temp directory, create folder MEDIA_FOLDER_NAME inside
+                File tmpFile = File.createTempFile(MEDIA_FOLDER_NAME, null);
+                String tmpDir = tmpFile.getParent();
+                mediaFolder = new File(tmpDir, MEDIA_FOLDER_NAME);
+                // delete temp file used for locating temp directory
+                tmpFile.delete();
+            } catch (IOException e) {
+                throw new TargetSetupError("Unable to create host temp directory for media files");
+            }
+            mLocalMediaPath = mediaFolder.getAbsolutePath();
+            if(!mediaFolder.exists()){
+                // directory has not been created by previous runs of MediaPreparer
+                // download media into mLocalMediaPath
+                downloadMediaToHost();
+            }
+            updateLocalMediaPath(mediaFolder);
+        }
+
+        logInfo("Media files located on host at: %s", mLocalMediaPath);
+        copyMediaFiles(device, mvpr);
+    }
+
+}
diff --git a/tests/tests/mediastress/preconditions/tests/Android.mk b/tests/tests/mediastress/preconditions/tests/Android.mk
new file mode 100644
index 0000000..28549f5
--- /dev/null
+++ b/tests/tests/mediastress/preconditions/tests/Android.mk
@@ -0,0 +1,31 @@
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_STATIC_JAVA_LIBRARIES := easymock
+
+LOCAL_JAVA_LIBRARIES := compatibility-host-util cts-tradefed tradefed-prebuilt compatibility-host-media-preconditions
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE := compatibility-host-media-preconditions-tests
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/tests/tests/mediastress/preconditions/tests/run_tests.sh b/tests/tests/mediastress/preconditions/tests/run_tests.sh
new file mode 100755
index 0000000..b04bde8
--- /dev/null
+++ b/tests/tests/mediastress/preconditions/tests/run_tests.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Helper script for running unit tests for compatibility libraries
+
+CTS_DIR=$(dirname ${0})/../../../../..
+source ${CTS_DIR}/test_defs.sh
+
+JARS="
+    compatibility-host-util\
+    cts-tradefed\
+    compatibility-host-media-preconditions\
+    compatibility-host-media-preconditions-tests"
+
+run_tests "android.mediastress.cts.preconditions.MediaPreparerTest" "${JARS}" "${@}"
diff --git a/tests/tests/mediastress/preconditions/tests/src/android/mediastress/cts/preconditions/MediaPreparerTest.java b/tests/tests/mediastress/preconditions/tests/src/android/mediastress/cts/preconditions/MediaPreparerTest.java
new file mode 100644
index 0000000..54ab025
--- /dev/null
+++ b/tests/tests/mediastress/preconditions/tests/src/android/mediastress/cts/preconditions/MediaPreparerTest.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.mediastress.cts.preconditions;
+
+import com.android.ddmlib.IDevice;
+import com.android.tradefed.build.BuildInfo;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.config.OptionSetter;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.targetprep.TargetSetupError;
+
+import java.awt.Dimension;
+
+import junit.framework.TestCase;
+
+import org.easymock.EasyMock;
+
+public class MediaPreparerTest extends TestCase {
+
+    private MediaPreparer mMediaPreparer;
+    private IBuildInfo mMockBuildInfo;
+    private ITestDevice mMockDevice;
+    private OptionSetter mOptionSetter;
+
+    private final Dimension DEFAULT_DIMENSION =
+            MediaPreparer.resolutions[MediaPreparer.RES_DEFAULT];
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        mMediaPreparer = new MediaPreparer();
+        mMockDevice = EasyMock.createMock(ITestDevice.class);
+        mMockBuildInfo = new BuildInfo("0", "", "");
+        mOptionSetter = new OptionSetter(mMediaPreparer);
+    }
+
+    public void testSetMountPoint() throws Exception {
+        EasyMock.expect(mMockDevice.getMountPoint(IDevice.MNT_EXTERNAL_STORAGE)).andReturn(
+                "/sdcard").once();
+        EasyMock.replay(mMockDevice);
+        mMediaPreparer.setMountPoint(mMockDevice);
+        assertEquals(mMediaPreparer.baseDeviceShortDir, "/sdcard/test/bbb_short/");
+        assertEquals(mMediaPreparer.baseDeviceFullDir, "/sdcard/test/bbb_full/");
+    }
+
+    public void testCopyMediaFiles() throws Exception {
+        // by jumping directly into copyMediaFiles, the baseDeviceShortDir variable won't be set
+        // thus, the string "null" replaces the variable
+        EasyMock.expect(mMockDevice.doesFileExist("null176x144")).andReturn(true).anyTimes();
+        EasyMock.expect(mMockDevice.doesFileExist("null480x360")).andReturn(true).anyTimes();
+        EasyMock.replay(mMockDevice);
+        mMediaPreparer.copyMediaFiles(mMockDevice, DEFAULT_DIMENSION);
+    }
+
+    public void testMediaFilesExistOnDeviceTrue() throws Exception {
+        // by jumping directly into copyMediaFiles, the baseDeviceShortDir variable won't be set
+        // thus, the string "null" replaces the variable
+        EasyMock.expect(mMockDevice.doesFileExist("null176x144")).andReturn(true).anyTimes();
+        EasyMock.expect(mMockDevice.doesFileExist("null480x360")).andReturn(true).anyTimes();
+        EasyMock.replay(mMockDevice);
+        assertTrue(mMediaPreparer.mediaFilesExistOnDevice(mMockDevice, DEFAULT_DIMENSION));
+    }
+
+    public void testMediaFilesExistOnDeviceFalse() throws Exception {
+        // by jumping directly into copyMediaFiles, the baseDeviceShortDir variable won't be set
+        // thus, the string "null" replaces the variable
+        EasyMock.expect(mMockDevice.doesFileExist("null176x144")).andReturn(false).anyTimes();
+        EasyMock.expect(mMockDevice.doesFileExist("null480x360")).andReturn(true).anyTimes();
+        EasyMock.replay(mMockDevice);
+        assertFalse(mMediaPreparer.mediaFilesExistOnDevice(mMockDevice, DEFAULT_DIMENSION));
+    }
+
+    public void testGetMaxVideoPlaybackResolutionFound() throws Exception {
+        String mockDumpsysOutput = "mBaseDisplayInfo=DisplayInfo{\"Built-in Screen\", uniqueId " +
+                "\"local:0\", app 1440 x 2560, real 1440 x 2560, largest app 1440 x 2560, " +
+                "smallest app 360 x 480, mode 1, defaultMode 1, modes [{id=1, width=1440, " +
+                "height=2560, fps=60.0}], rotation 0, density 560 (494.27 x 492.606) dpi, " +
+                "layerStack 0, appVsyncOff 2500000, presDeadline 17666667, type BUILT_IN, state " +
+                "ON, FLAG_SECURE, FLAG_SUPPORTS_PROTECTED_BUFFERS}\n";
+        EasyMock.expect(mMockDevice.executeShellCommand(
+                "dumpsys display | grep mBaseDisplayInfo")).andReturn(mockDumpsysOutput).once();
+        EasyMock.replay(mMockDevice);
+        Dimension result = mMediaPreparer.getMaxVideoPlaybackResolution(mMockDevice);
+        assertEquals(result, DEFAULT_DIMENSION);
+    }
+
+    public void testGetMaxVideoPlaybackResolutionNotFound() throws Exception {
+        String mockDumpsysOutput = "incorrect output";
+        EasyMock.expect(mMockDevice.executeShellCommand(
+                "dumpsys display | grep mBaseDisplayInfo")).andReturn(mockDumpsysOutput).once();
+        EasyMock.replay(mMockDevice);
+        Dimension result = mMediaPreparer.getMaxVideoPlaybackResolution(mMockDevice);
+        assertEquals(result, MediaPreparer.resolutions[MediaPreparer.RES_1920_1080]);
+    }
+
+    public void testSkipMediaDownload() throws Exception {
+        mOptionSetter.setOptionValue("skip-media-download", "true");
+        EasyMock.replay();
+        mMediaPreparer.run(mMockDevice, mMockBuildInfo);
+    }
+
+}
diff --git a/tests/tests/mediastress/src/android/mediastress/cts/MediaFrameworkTest.java b/tests/tests/mediastress/src/android/mediastress/cts/MediaFrameworkTest.java
index d39bc16..68d1e51 100644
--- a/tests/tests/mediastress/src/android/mediastress/cts/MediaFrameworkTest.java
+++ b/tests/tests/mediastress/src/android/mediastress/cts/MediaFrameworkTest.java
@@ -27,7 +27,7 @@
 import android.view.SurfaceHolder;
 import android.view.SurfaceView;
 
-import com.android.cts.mediastress.R;
+import android.mediastress.cts.R;
 
 public class MediaFrameworkTest extends Activity implements SurfaceHolder.Callback {
     private static String TAG = "MediaFrameworkTest";
diff --git a/tests/tests/midi/Android.mk b/tests/tests/midi/Android.mk
index f202933..3dc0c8b 100755
--- a/tests/tests/midi/Android.mk
+++ b/tests/tests/midi/Android.mk
@@ -22,6 +22,9 @@
 # When built, explicitly put it in the data partition.
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctstestrunner
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
diff --git a/tests/tests/midi/AndroidTest.xml b/tests/tests/midi/AndroidTest.xml
new file mode 100644
index 0000000..c95ab89
--- /dev/null
+++ b/tests/tests/midi/AndroidTest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS MIDI test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsMidiTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.midi.cts" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/tests/multiuser/Android.mk b/tests/tests/multiuser/Android.mk
new file mode 100644
index 0000000..ae1be7e
--- /dev/null
+++ b/tests/tests/multiuser/Android.mk
@@ -0,0 +1,34 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := CtsMultiUserTestCases
+
+LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner ctsdeviceutil
+
+LOCAL_SDK_VERSION := test_current
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/multiuser/AndroidManifest.xml b/tests/tests/multiuser/AndroidManifest.xml
new file mode 100644
index 0000000..f983fad
--- /dev/null
+++ b/tests/tests/multiuser/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+  ~ Copyright (C) 2016 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="android.multiuser.cts">
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="android.multiuser.cts"
+                     android:label="Multiuser tests"/>
+</manifest>
\ No newline at end of file
diff --git a/tests/tests/multiuser/AndroidTest.xml b/tests/tests/multiuser/AndroidTest.xml
new file mode 100644
index 0000000..c05430e
--- /dev/null
+++ b/tests/tests/multiuser/AndroidTest.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2016 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<configuration description="Config for CTS Multiuser test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsMultiUserTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.multiuser.cts" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/tests/multiuser/src/android/multiuser/cts/SplitSystemUserTest.java b/tests/tests/multiuser/src/android/multiuser/cts/SplitSystemUserTest.java
new file mode 100644
index 0000000..206a613
--- /dev/null
+++ b/tests/tests/multiuser/src/android/multiuser/cts/SplitSystemUserTest.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.multiuser.cts;
+
+
+import android.cts.util.SystemUtil;
+import android.os.UserManager;
+import android.test.InstrumentationTestCase;
+import android.util.Log;
+
+public class SplitSystemUserTest extends InstrumentationTestCase {
+
+    private static final String TAG = SplitSystemUserTest.class.getSimpleName();
+
+    public void testSplitSystemUserIsDisabled() throws Exception {
+        // Verify that am get-current-user and UserManager.isSystemUser both return 0
+        String curUser = SystemUtil.runShellCommand(getInstrumentation(), "am get-current-user");
+        Log.i(TAG, "am get-current-user: " + curUser);
+        assertEquals("Test must be running under user 0", "0", trim(curUser));
+        UserManager um = getInstrumentation().getContext().getSystemService(UserManager.class);
+        assertTrue("Test must be running under system user", um.isSystemUser());
+
+        // Check that ro.fw.system_user_split property is not set
+        String splitEnabledStr = trim(SystemUtil.runShellCommand(getInstrumentation(),
+                "getprop ro.fw.system_user_split"));
+        boolean splitEnabled = "y".equals(splitEnabledStr) || "yes".equals(splitEnabledStr)
+                || "1".equals(splitEnabledStr) || "true".equals(splitEnabledStr)
+                || "on".equals(splitEnabledStr);
+        assertFalse("ro.fw.system_user_split must not be enabled", splitEnabled);
+    }
+
+    private static String trim(String s) {
+        return s == null ? null : s.trim();
+    }
+}
diff --git a/tests/tests/nativemedia/Android.mk b/tests/tests/nativemedia/Android.mk
index 5053e7d..ba2da56 100644
--- a/tests/tests/nativemedia/Android.mk
+++ b/tests/tests/nativemedia/Android.mk
@@ -1 +1,15 @@
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT 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 $(call all-subdir-makefiles)
diff --git a/tests/tests/nativemedia/sl/Android.mk b/tests/tests/nativemedia/sl/Android.mk
index 28dfeff..e782994 100644
--- a/tests/tests/nativemedia/sl/Android.mk
+++ b/tests/tests/nativemedia/sl/Android.mk
@@ -1,8 +1,22 @@
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
 # Build the unit tests.
 
 LOCAL_PATH:= $(call my-dir)
 
-test_executable := NativeMediaTest_SL
+test_executable := CtsNativeMediaSlTestCases
 list_executable := $(test_executable)_list
 
 include $(CLEAR_VARS)
@@ -33,6 +47,12 @@
     libgtest
 
 LOCAL_CTS_TEST_PACKAGE := android.nativemedia.sl
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_CFLAGS := -Werror -Wall
+
 include $(BUILD_CTS_EXECUTABLE)
 
 include $(CLEAR_VARS)
@@ -46,6 +66,7 @@
 
 LOCAL_CFLAGS := \
     -DBUILD_ONLY \
+    -Werror -Wall
 
 LOCAL_SHARED_LIBRARIES := \
     liblog \
diff --git a/tests/tests/nativemedia/sl/AndroidTest.xml b/tests/tests/nativemedia/sl/AndroidTest.xml
new file mode 100644
index 0000000..c73c1b4
--- /dev/null
+++ b/tests/tests/nativemedia/sl/AndroidTest.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS Native Media Open SL ES test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
+        <option name="cleanup" value="true" />
+        <option name="push" value="CtsNativeMediaSlTestCases->/data/local/tmp/CtsNativeMediaSlTestCases" />
+        <option name="append-bitness" value="true" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="CtsNativeMediaSlTestCases" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/tests/nativemedia/xa/Android.mk b/tests/tests/nativemedia/xa/Android.mk
index 52126c3..f71d853 100644
--- a/tests/tests/nativemedia/xa/Android.mk
+++ b/tests/tests/nativemedia/xa/Android.mk
@@ -1,8 +1,22 @@
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
 # Build the unit tests.
 
 LOCAL_PATH:= $(call my-dir)
 
-test_executable := NativeMediaTest_XA
+test_executable := CtsNativeMediaXaTestCases
 list_executable := $(test_executable)_list
 
 include $(CLEAR_VARS)
@@ -32,6 +46,10 @@
   libgtest \
 
 LOCAL_CTS_TEST_PACKAGE := android.nativemedia.xa
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_CTS_EXECUTABLE)
 
 include $(CLEAR_VARS)
diff --git a/tests/tests/nativemedia/xa/AndroidTest.xml b/tests/tests/nativemedia/xa/AndroidTest.xml
new file mode 100644
index 0000000..229d8aa
--- /dev/null
+++ b/tests/tests/nativemedia/xa/AndroidTest.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS Native Media OpenMax AL test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
+        <option name="cleanup" value="true" />
+        <option name="push" value="CtsNativeMediaXaTestCases->/data/local/tmp/CtsNativeMediaXaTestCases" />
+        <option name="append-bitness" value="true" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="CtsNativeMediaXaTestCases" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/tests/nativeopengl/Android.mk b/tests/tests/nativeopengl/Android.mk
deleted file mode 100644
index d2192ad..0000000
--- a/tests/tests/nativeopengl/Android.mk
+++ /dev/null
@@ -1,41 +0,0 @@
-# Copyright 2012 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_PACKAGE_NAME := CtsNativeOpenGLTestCases
-
-# Don't include this package in any target.
-LOCAL_MODULE_TAGS := optional
-
-# When built, explicitly put it in the data partition.
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-
-# Include both the 32 and 64 bit versions
-LOCAL_MULTILIB := both
-
-LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner ctswrappedgtest
-
-LOCAL_JNI_SHARED_LIBRARIES := libnativeopengltests
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_SDK_VERSION := current
-
-include $(BUILD_CTS_GTEST_PACKAGE)
-
-# Include the associated library's makefile.
-include $(LOCAL_PATH)/libnativeopengltests/Android.mk
diff --git a/tests/tests/nativeopengl/AndroidManifest.xml b/tests/tests/nativeopengl/AndroidManifest.xml
deleted file mode 100644
index 72d87ac..0000000
--- a/tests/tests/nativeopengl/AndroidManifest.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
- * Copyright 2013 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.opengl.cts">
-
-    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
-
-    <application>
-        <uses-library android:name="android.test.runner" />
-        <activity android:name="com.android.opengl.cts.GLTestActivity"/>
-    </application>
-
-    <!-- This is a self-instrumenting test package. -->
-    <instrumentation android:name="GLTestInstrumentation"
-                     android:targetPackage="com.android.opengl.cts"
-                     android:label="Native OpenGL tests">
-    </instrumentation>
-</manifest>
diff --git a/tests/tests/nativeopengl/CtsNativeOpenGLTestCases_list.txt b/tests/tests/nativeopengl/CtsNativeOpenGLTestCases_list.txt
deleted file mode 100644
index 8daf3b2..0000000
--- a/tests/tests/nativeopengl/CtsNativeOpenGLTestCases_list.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-EGLCleanupTest.
-  TestCorrect
-EGLCreateContextTest.
-  BadAttributeFails
-GLTest.
-  ClearColorTest
diff --git a/tests/tests/nativeopengl/libnativeopengltests/Android.mk b/tests/tests/nativeopengl/libnativeopengltests/Android.mk
deleted file mode 100644
index 62e28ec..0000000
--- a/tests/tests/nativeopengl/libnativeopengltests/Android.mk
+++ /dev/null
@@ -1,48 +0,0 @@
-# Copyright 2012 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-#
-# This is the shared library included by the JNI test app.
-#
-
-LOCAL_PATH := $(call my-dir)/../standalone/jni/
-REAL_LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_ADDITIONAL_DEPENDENCIES := $(REAL_LOCAL_PATH)/Android.mk
-
-LOCAL_MODULE := libnativeopengltests
-
-# Don't include this package in any configuration by default.
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_C_INCLUDES := $(JNI_H_INCLUDE) \
-    external/gtest/include \
-
-LOCAL_SRC_FILES := \
-        register.cpp \
-        GLTestHelper.cpp \
-        tests/GLTest_test.cpp \
-        tests/EGLCleanup_test.cpp \
-        tests/EGLCreateContext_test.cpp
-
-LOCAL_CXX_STL := libc++
-LOCAL_SHARED_LIBRARIES := libEGL \
-                          libGLESv2 \
-                          libandroid \
-                          liblog \
-
-LOCAL_STATIC_LIBRARIES := libgtest
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/tests/tests/nativeopengl/src/com/android/opengl/cts/GLTestActivity.java b/tests/tests/nativeopengl/src/com/android/opengl/cts/GLTestActivity.java
deleted file mode 100644
index 1633a93..0000000
--- a/tests/tests/nativeopengl/src/com/android/opengl/cts/GLTestActivity.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.opengl.cts;
-
-import android.app.Activity;
-import android.app.Instrumentation;
-import android.content.Intent;
-import android.os.Bundle;
-import android.test.wrappedgtest.WrappedGTestActivity;
-import android.view.SurfaceHolder;
-import android.view.SurfaceView;
-import android.view.Surface;
-
-public class GLTestActivity extends WrappedGTestActivity {
-
-    private SurfaceView mSurfaceView;
-    private SurfaceHolder.Callback mHolderCallback = new SurfaceHolder.Callback() {
-
-        @Override
-        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
-             setSurface(holder.getSurface());
-        }
-
-        @Override
-        public void surfaceCreated(SurfaceHolder holder) {
-             setSurface(holder.getSurface());
-        }
-
-        @Override
-        public void surfaceDestroyed(SurfaceHolder holder) {
-        }
-    };
-
-    public void onCreate(Bundle data) {
-        super.onCreate(data);
-        mSurfaceView = new SurfaceView(this);
-        mSurfaceView.getHolder().addCallback(mHolderCallback);
-        setContentView(mSurfaceView);
-        System.loadLibrary("nativeopengltests");
-    }
-
-    private static native void setSurface(Surface surface);
-}
diff --git a/tests/tests/nativeopengl/src/com/android/opengl/cts/GLTestInstrumentation.java b/tests/tests/nativeopengl/src/com/android/opengl/cts/GLTestInstrumentation.java
deleted file mode 100644
index 913f0eb..0000000
--- a/tests/tests/nativeopengl/src/com/android/opengl/cts/GLTestInstrumentation.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.opengl.cts;
-
-import android.test.wrappedgtest.WrappedGTestInstrumentation;
-
-/**
- * adb shell am instrument -w com.android.opengl.cts/.GLTestInstrumentation
- */
-public class GLTestInstrumentation extends WrappedGTestInstrumentation {
-    public GLTestInstrumentation() {
-        mActivityClass = GLTestActivity.class;
-    }
-}
diff --git a/tests/tests/nativeopengl/standalone/.gitignore b/tests/tests/nativeopengl/standalone/.gitignore
deleted file mode 100644
index 1d1cdd2..0000000
--- a/tests/tests/nativeopengl/standalone/.gitignore
+++ /dev/null
@@ -1,8 +0,0 @@
-bin/
-build.xml
-gen/
-libs/
-local.properties
-obj/
-proguard-project.txt
-project.properties
diff --git a/tests/tests/nativeopengl/standalone/AndroidManifest.xml b/tests/tests/nativeopengl/standalone/AndroidManifest.xml
deleted file mode 100644
index 9092f69..0000000
--- a/tests/tests/nativeopengl/standalone/AndroidManifest.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
- * Copyright 2013 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.gltest"
-    android:versionCode="1"
-    android:versionName="1.0"
-    android:debuggable="true" >
-
-    <uses-sdk
-        android:minSdkVersion="8"
-        android:targetSdkVersion="15" />
-
-    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
-
-    <application android:label="NativeGLTest">
-        <activity android:name=".GLTestActivity">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-    </application>
-
-</manifest>
diff --git a/tests/tests/nativeopengl/standalone/jni/Android.mk b/tests/tests/nativeopengl/standalone/jni/Android.mk
deleted file mode 100644
index 53d9bbf..0000000
--- a/tests/tests/nativeopengl/standalone/jni/Android.mk
+++ /dev/null
@@ -1,51 +0,0 @@
-# Copyright 2013 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-MY_LOCAL_PATH := $(call my-dir)
-MY_GTEST_PATH := $(MY_LOCAL_PATH)/../../../../../../external/gtest
-
-# gtest
-
-LOCAL_PATH := $(MY_GTEST_PATH)
-
-include $(CLEAR_VARS)
-
-LOCAL_CPP_EXTENSION := .cc
-LOCAL_MODULE := libgtest
-LOCAL_C_INCLUDES := $(MY_GTEST_PATH)/include
-LOCAL_SRC_FILES := src/gtest-all.cc
-
-include $(BUILD_STATIC_LIBRARY)
-
-# nativetests
-
-LOCAL_PATH := $(MY_LOCAL_PATH)
-
-include $(CLEAR_VARS)
-
-LIB_PATH := $(LOCAL_PATH)/../libs/$(TARGET_ARCH_ABI)/
-LOCAL_C_INCLUDES := $(MY_GTEST_PATH)/include
-LOCAL_LDLIBS    := -L$(LIB_PATH) -landroid -lEGL -lGLESv2 -llog
-LOCAL_STATIC_LIBRARIES := libgtest
-LOCAL_MODULE    := nativeopengltests
-LOCAL_SRC_FILES := GLTestHelper.cpp \
-                   register.cpp \
-                   tests/GLTest_test.cpp \
-                   tests/EGLCleanup_test.cpp \
-                   tests/EGLCreateContext_test.cpp
-
-LOCAL_SHARED_LIBRARIES := libgtest
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/tests/tests/nativeopengl/standalone/jni/Application.mk b/tests/tests/nativeopengl/standalone/jni/Application.mk
deleted file mode 100644
index 76d05a7..0000000
--- a/tests/tests/nativeopengl/standalone/jni/Application.mk
+++ /dev/null
@@ -1,16 +0,0 @@
-# Copyright 2013 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-APP_STL := stlport_shared
diff --git a/tests/tests/nativeopengl/standalone/jni/GLTestHelper.cpp b/tests/tests/nativeopengl/standalone/jni/GLTestHelper.cpp
deleted file mode 100644
index d1f29d5..0000000
--- a/tests/tests/nativeopengl/standalone/jni/GLTestHelper.cpp
+++ /dev/null
@@ -1,312 +0,0 @@
-/*
- * Copyright 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "GLTest"
-#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
-#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
-
-#include <android/log.h>
-#include <android/native_window.h>
-#include <GLTestHelper.h>
-
-// this listener is used to forward the subset of
-// gtest output needed to generate CTS results
-class CTSGTestListener : public EmptyTestEventListener {
-public:
-    CTSGTestListener(JNIEnv *env, jobject activity)
-        : mActivity(activity), mEnv(env) {
-
-        jclass clazz = env->FindClass(
-              "android/test/wrappedgtest/WrappedGTestActivity");
-        mSendStatusID = env->GetMethodID(clazz, "sendStatus",
-              "(Ljava/lang/String;)V");
-        mMessageBuffer = new char[2048];
-    }
-
-    ~CTSGTestListener() {
-        delete[] mMessageBuffer;
-    }
-
-private:
-    jobject   mActivity;
-    JNIEnv *  mEnv;
-    jmethodID mSendStatusID;
-    char *    mMessageBuffer;
-
-    virtual void OnTestIterationStart(const UnitTest& unit_test,
-            int iteration) {
-        snprintf(mMessageBuffer, sizeof(char) * 2048,
-                "[==========] Running %i tests from %i test cases.",
-                unit_test.test_to_run_count(),
-                unit_test.test_case_to_run_count());
-
-        mEnv->CallVoidMethod(mActivity, mSendStatusID,
-                mEnv->NewStringUTF(mMessageBuffer));
-    }
-
-    virtual void OnTestStart(const TestInfo& test_info) {
-        snprintf(mMessageBuffer, sizeof(char) * 2048, "[ RUN      ] %s.%s",
-                test_info.test_case_name(), test_info.name());
-
-        mEnv->CallVoidMethod(mActivity, mSendStatusID,
-                mEnv->NewStringUTF(mMessageBuffer));
-    }
-
-    virtual void OnTestPartResult(const TestPartResult& result) {
-        if (result.type() == TestPartResult::kSuccess) {
-            return;
-        }
-
-        snprintf(mMessageBuffer, sizeof(char) * 2048, "%s:%i: Failure\n%s",
-                result.file_name(), result.line_number(), result.message());
-
-        mEnv->CallVoidMethod(mActivity, mSendStatusID,
-                mEnv->NewStringUTF(mMessageBuffer));
-    }
-
-    virtual void OnTestEnd(const TestInfo& test_info) {
-        const char * result = test_info.result()->Passed() ?
-                "[       OK ] " : "[  FAILED  ] ";
-
-        snprintf(mMessageBuffer, sizeof(char) * 2048, "%s%s.%s (%lli ms)",
-                result, test_info.test_case_name(), test_info.name(),
-                test_info.result()->elapsed_time());
-
-        mEnv->CallVoidMethod(mActivity, mSendStatusID,
-                mEnv->NewStringUTF(mMessageBuffer));
-    }
-
-    virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration) {
-        snprintf(mMessageBuffer, sizeof(char) * 2048,
-                "[==========] %i tests from %i test cases ran. (%lli ms total)",
-                unit_test.test_to_run_count(),
-                unit_test.test_case_to_run_count(), unit_test.elapsed_time());
-
-        mEnv->CallVoidMethod(mActivity, mSendStatusID,
-                mEnv->NewStringUTF(mMessageBuffer));
-    }
-};
-
-// this listener is similar to the default gtest listener
-// but it outputs the results to the log instead of stdout
-class LogGTestListener : public EmptyTestEventListener {
-
-private:
-    virtual void OnTestIterationStart(const UnitTest& unit_test,
-            int iteration) {
-        LOGI("[==========] Running %i tests from %i test cases.\n",
-                unit_test.test_to_run_count(),
-                unit_test.test_case_to_run_count());
-    }
-
-    virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test) {
-        LOGI("[==========] Global test environment set-up.\n");
-    }
-
-    virtual void OnTestCaseStart(const TestCase& test_case) {
-        LOGI("[----------] %i tests from %s\n",
-                test_case.test_to_run_count(),
-                test_case.name());
-
-    }
-
-    virtual void OnTestStart(const TestInfo& test_info) {
-        LOGI("[ RUN      ] %s.%s\n", test_info.test_case_name(),
-                test_info.name());
-
-    }
-
-    virtual void OnTestPartResult(const TestPartResult& result) {
-        if (result.type() == TestPartResult::kSuccess) {
-            return;
-        }
-
-        LOGI("%s:%i: Failure\n%s\n", result.file_name(), result.line_number(),
-                result.message());
-    }
-
-    virtual void OnTestEnd(const TestInfo& test_info) {
-        const char * result = test_info.result()->Passed() ?
-                "[       OK ] " : "[  FAILED  ] ";
-
-        LOGI("%s%s.%s (%lli ms)\n", result, test_info.test_case_name(),
-                test_info.name(), test_info.result()->elapsed_time());
-    }
-
-
-    virtual void OnTestCaseEnd(const TestCase& test_case) {
-        LOGI("[----------] %i tests from %s (%lli ms total)\n",
-                test_case.test_to_run_count(), test_case.name(),
-                test_case.elapsed_time());
-
-    }
-
-    virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test) {
-        LOGI("[==========] Global test environment tear-down.\n");
-    }
-
-    void PrintFailedTests(const UnitTest& unit_test) {
-        const int failed_test_count = unit_test.failed_test_count();
-        if (failed_test_count == 0) {
-            return;
-        }
-
-        for (int i = 0; i < unit_test.total_test_case_count(); ++i) {
-            const TestCase& test_case = *unit_test.GetTestCase(i);
-
-            if (!test_case.should_run() || test_case.failed_test_count() == 0) {
-                continue;
-            }
-
-            for (int j = 0; j < test_case.total_test_count(); ++j) {
-                const TestInfo& test_info = *test_case.GetTestInfo(j);
-                if (!test_info.should_run() || test_info.result()->Passed()) {
-                    continue;
-                }
-                LOGI("[  FAILED  ] %s.%s\n", test_case.name(),
-                        test_info.name());
-            }
-        }
-    }
-    virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration) {
-        LOGI("[==========] %i tests from %i test cases ran. (%lli ms total)\n",
-                unit_test.test_to_run_count(),
-                unit_test.test_case_to_run_count(), unit_test.elapsed_time());
-
-        LOGI("[  PASSED  ] %i tests\n", unit_test.successful_test_count());
-
-        if(unit_test.Passed()) {
-            return;
-        }
-
-        LOGI("[  FAILED  ] %i tests, listed below:\n",
-                unit_test.failed_test_count());
-
-        PrintFailedTests(unit_test);
-
-        LOGI("\n%2d FAILED TESTS\n", unit_test.failed_test_count());
-    }
-};
-
-ANativeWindow* GLTestHelper::mWindow;
-
-ANativeWindow* GLTestHelper::getWindow() {
-    return mWindow;
-}
-
-void GLTestHelper::setWindow(JNIEnv *env, jobject obj, jobject surface) {
-    mWindow = ANativeWindow_fromSurface(env, surface);
-}
-
-int GLTestHelper::runGTests(TestEventListener * listener, char * filter) {
-
-    if (filter) {
-        ::testing::GTEST_FLAG(filter) = filter;
-    }
-
-    int argc = 0;
-    InitGoogleTest(&argc, (char**)NULL);
-
-    TestEventListeners& listeners = UnitTest::GetInstance()->listeners();
-    delete listeners.Release(listeners.default_result_printer());
-
-    listeners.Append(listener);
-    int result = RUN_ALL_TESTS();
-    return result;
-}
-
-int GLTestHelper::runTests(JNIEnv *env, jobject obj, jstring filter) {
-    LogGTestListener * listener = new LogGTestListener();
-
-    char * filter_cstr = NULL;
-
-    // set filter if there is one
-    if (filter) {
-       filter_cstr = new char[512];
-       const char * ptr = env->GetStringUTFChars(filter, NULL);
-       snprintf(filter_cstr, sizeof(char) * 512, "%s", ptr);
-       env->ReleaseStringUTFChars(filter, ptr);
-    }
-
-    int result = runGTests(listener, filter_cstr);
-
-    if (filter_cstr) {
-        delete[] filter_cstr;
-    }
-
-    delete listener;
-    return result;
-}
-
-int GLTestHelper::runTestsCTS(JNIEnv *env, jobject obj, jobject activity) {
-    CTSGTestListener * listener = new CTSGTestListener(env, activity);
-    int result = runGTests(listener, NULL);
-    delete listener;
-    return result;
-}
-
-int GLTestHelper::registerNative(JNIEnv * env) {
-
-    jclass clazz = env->FindClass("com/android/opengl/cts/GLTestActivity");
-
-    jthrowable exception = env->ExceptionOccurred();
-    // CTS class not found, assume stand-alone application
-    if (exception) {
-        env->ExceptionClear();
-
-        if (!env->IsInstanceOf(env->ExceptionOccurred(),
-                    env->FindClass("java/lang/NoClassDefFoundError"))) {
-            env->Throw(exception);
-        }
-
-        //
-        JNINativeMethod standaloneMethods[] = {
-            // name, signature, function
-            { "setSurface", "(Landroid/view/Surface;)V", (void*)(GLTestHelper::setWindow) },
-            { "runTests", "(Ljava/lang/String;)V", (void*)(GLTestHelper::runTests) },
-        };
-
-        return env->RegisterNatives(
-                env->FindClass("com/android/gltest/GLTestActivity"),
-                standaloneMethods,
-                sizeof(standaloneMethods) / sizeof(JNINativeMethod));
-    }
-
-    // GLTestActivity methods
-    JNINativeMethod glTestActMethods[] = {
-        // name, signature, function
-        { "setSurface", "(Landroid/view/Surface;)V", (void*)(GLTestHelper::setWindow) },
-    };
-
-    int result = env->RegisterNatives(clazz, glTestActMethods,
-                         sizeof(glTestActMethods) / sizeof(JNINativeMethod));
-
-    if (result) {
-        return result;
-    }
-
-    // WrappedGTestActivity methods
-    JNINativeMethod wrappedGTestActMethods[] = {
-        // name, signature, function
-        { "runTests", "(Landroid/test/wrappedgtest/WrappedGTestActivity;)I",
-            (void*)(GLTestHelper::runTestsCTS) },
-    };
-
-    return env->RegisterNatives(
-            env->FindClass("android/test/wrappedgtest/WrappedGTestActivity"),
-            wrappedGTestActMethods,
-            sizeof(wrappedGTestActMethods) / sizeof(JNINativeMethod));
-}
diff --git a/tests/tests/nativeopengl/standalone/jni/GLTestHelper.h b/tests/tests/nativeopengl/standalone/jni/GLTestHelper.h
deleted file mode 100644
index d09d2f1..0000000
--- a/tests/tests/nativeopengl/standalone/jni/GLTestHelper.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_GL_TEST_HELPER_H
-#define ANDROID_GL_TEST_HELPER_H
-
-#include <android/native_window_jni.h>
-#include <gtest/gtest.h>
-
-using namespace testing;
-
-class GLTestHelper
-{
-private:
-    static ANativeWindow* mWindow;
-    static int runGTests(TestEventListener* listener, char * filter);
-    static int runTests(JNIEnv* env, jobject obj, jstring filter);
-    static int runTestsCTS(JNIEnv* env, jobject obj, jobject activity);
-public:
-    static ANativeWindow* getWindow();
-    static void setWindow(JNIEnv* env, jobject obj, jobject surface);
-    static int registerNative(JNIEnv* env);
-};
-
-
-
-#endif // ANDROID_GL_TEST_HELPER_H
diff --git a/tests/tests/nativeopengl/standalone/jni/register.cpp b/tests/tests/nativeopengl/standalone/jni/register.cpp
deleted file mode 100644
index 8dd14ed..0000000
--- a/tests/tests/nativeopengl/standalone/jni/register.cpp
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <jni.h>
-#include <GLTestHelper.h>
-
-/*
- * This function is called automatically by the system when this
- * library is loaded. We use it to register all our native functions,
- * which is the recommended practice for Android.
- */
-jint JNI_OnLoad(JavaVM *vm, void *reserved) {
-    JNIEnv *env = NULL;
-
-    if (vm->GetEnv((void **) &env, JNI_VERSION_1_4) != JNI_OK) {
-        return JNI_ERR;
-    }
-
-    if (GLTestHelper::registerNative(env)) {
-        return JNI_ERR;
-    }
-
-    return JNI_VERSION_1_4;
-}
diff --git a/tests/tests/nativeopengl/standalone/jni/tests/EGLCleanup_test.cpp b/tests/tests/nativeopengl/standalone/jni/tests/EGLCleanup_test.cpp
deleted file mode 100644
index 2daa2fe..0000000
--- a/tests/tests/nativeopengl/standalone/jni/tests/EGLCleanup_test.cpp
+++ /dev/null
@@ -1,346 +0,0 @@
-/*
- * Copyright 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "EGLCleanup"
-#include <android/log.h>
-#include <jni.h>
-
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-
-#include <gtest/gtest.h>
-
-#include <GLTestHelper.h>
-
-#include <pthread.h>
-
-#define ALOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
-#define ALOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
-#define ALOGW(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)
-#define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
-
-namespace android {
-
-/**
- * Tests EGL cleanup edge cases.
- */
-class EGLCleanupTest : public ::testing::Test {
-protected:
-    EGLCleanupTest() {}
-
-    virtual void SetUp() {
-        // Termination of a terminated display is defined to be a no-op.
-        // Android uses a refcounted implementation, so terminate it a few
-        // times to make sure it's really dead.  Without this, we might not
-        // get all the way into the driver eglTerminate implementation
-        // when we call eglTerminate.
-        EGLDisplay disp = eglGetDisplay(EGL_DEFAULT_DISPLAY);
-        if (disp != EGL_NO_DISPLAY) {
-            ALOGD("speculative terminate");
-            eglTerminate(disp);
-            eglTerminate(disp);
-            eglTerminate(disp);
-        }
-    }
-    virtual void TearDown() {}
-};
-
-/**
- * Perform an operation and then start a new thread.
- *
- * The trick here is that some code may be helpfully releasing storage in
- * pthread_key destructors.  Those run after the thread returns out of the
- * initial function, but before the thread fully exits.  We want them to
- * run concurrently with the next thread's initialization so we can confirm
- * that the specified behavior of eglTerminate vs. eglInitialize holds.
- */
-class ChainedThread {
-public:
-    enum TestType {
-        TEST_CORRECT,
-        TEST_NO_RELEASE_CURRENT
-    };
-
-    ChainedThread(TestType testType) : mEglDisplay(EGL_NO_DISPLAY),
-            mEglSurface(EGL_NO_SURFACE), mEglContext(EGL_NO_CONTEXT),
-            mTestType(testType), mIteration(0), mResult(true) {
-        pthread_mutex_init(&mLock, NULL);
-        pthread_cond_init(&mCond, NULL);
-    }
-    ~ChainedThread() {
-        // could get fancy and clean up the mutex
-    }
-
-    /* start here */
-    bool start() {
-        lock();
-        bool result = startThread_l();
-        unlock();
-        return result;
-    }
-
-    /* waits until test is done; when finished, call getResult() */
-    bool waitForEnd() {
-        lock();
-        int err = pthread_cond_wait(&mCond, &mLock);
-        if (err != 0) {
-            ALOGW("pthread_cond_wait failed: %d", err);
-        }
-        unlock();
-        return err == 0;
-    }
-
-    /* returns the result; true means success */
-    bool getResult() {
-        return mResult;
-    }
-
-private:
-    enum { MAX_ITERATIONS = 450 };
-
-    EGLDisplay mEglDisplay;
-    EGLSurface mEglSurface;
-    EGLContext mEglContext;
-
-    TestType mTestType;
-    int mIteration;
-    bool mResult;
-    pthread_mutex_t mLock;
-    pthread_cond_t mCond;
-
-    // Assertions set a flag in Java and return from the current method (which
-    // must be declared to return void).  They do not throw a C++ exception.
-    //
-    // Because we're running in a separate thread, which is not attached to
-    // the VM, the assert macros don't help us much.  We could attach to the
-    // VM (by linking to libdvm.so and calling a global function), but the
-    // assertions won't cause the test to stop, which makes them less valuable.
-    //
-    // So instead we just return a boolean out of functions that can fail.
-
-    /* call this to start the test */
-    bool startThread_l() {
-        pthread_attr_t attr;
-        pthread_attr_init(&attr);
-        pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-
-        pthread_t newThread;
-        int err = pthread_create(&newThread, &attr, ChainedThread::func,
-                (void*) this);
-        return (err == 0);
-    }
-
-    /* thread entry point */
-    static void* func(void* arg) {
-        ChainedThread* obj = static_cast<ChainedThread*>(arg);
-        obj->doWork();
-        return NULL;
-    }
-
-    bool lock() {
-        int err = pthread_mutex_lock(&mLock);
-        if (err != 0) {
-            ALOGW("pthread_mutex_lock failed: %d", err);
-        }
-        return err == 0;
-    }
-
-    bool unlock() {
-        int err = pthread_mutex_unlock(&mLock);
-        if (err != 0) {
-            ALOGW("pthread_mutex_unlock failed: %d", err);
-        }
-        return err == 0;
-    }
-
-    /* main worker */
-    void doWork() {
-        lock();
-
-        if ((mIteration % 25) == 0) {
-            ALOGD("iteration %d\n", mIteration);
-        }
-
-        mIteration++;
-        bool result = runTest_l();
-        if (!result) {
-            ALOGW("failed at iteration %d, stopping test", mIteration);
-            mResult = false;
-            mIteration = MAX_ITERATIONS;
-        }
-
-        if (mIteration < MAX_ITERATIONS) {
-            // still going, try to start the next one
-            if (!startThread_l()) {
-                ALOGW("Unable to start thread at iter=%d", mIteration);
-                mResult = false;
-                mIteration = MAX_ITERATIONS;
-            }
-        }
-
-        if (mIteration >= MAX_ITERATIONS) {
-            ALOGD("Test ending, signaling main thread");
-            pthread_cond_signal(&mCond);
-        }
-
-        unlock();
-    }
-
-    /* setup, use, release EGL */
-    bool runTest_l() {
-        if (!eglSetup()) {
-            return false;
-        }
-        if (!eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
-                mEglContext))
-        {
-            ALOGW("eglMakeCurrent failed: 0x%x", eglGetError());
-            return false;
-        }
-        if (!eglRelease_l()) {
-            return false;
-        }
-
-        return true;
-    }
-
-    /*
-     * Sets up EGL.  Creates a 1280x720 pbuffer, which is large enough to
-     * cause a rapid and highly visible memory leak if we fail to discard it.
-     */
-    bool eglSetup() {
-        static const EGLint kConfigAttribs[] = {
-                EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
-                EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
-                EGL_RED_SIZE, 8,
-                EGL_GREEN_SIZE, 8,
-                EGL_BLUE_SIZE, 8,
-                EGL_NONE
-        };
-        static const EGLint kContextAttribs[] = {
-                EGL_CONTEXT_CLIENT_VERSION, 2,
-                EGL_NONE
-        };
-        static const EGLint kPbufferAttribs[] = {
-                EGL_WIDTH, 1280,
-                EGL_HEIGHT, 720,
-                EGL_NONE
-        };
-
-        //usleep(25000);
-
-        mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
-        if (mEglDisplay == EGL_NO_DISPLAY) {
-            ALOGW("eglGetDisplay failed: 0x%x", eglGetError());
-            return false;
-        }
-
-        EGLint majorVersion, minorVersion;
-        if (!eglInitialize(mEglDisplay, &majorVersion, &minorVersion)) {
-            ALOGW("eglInitialize failed: 0x%x", eglGetError());
-            return false;
-        }
-
-        EGLConfig eglConfig;
-        EGLint numConfigs = 0;
-        if (!eglChooseConfig(mEglDisplay, kConfigAttribs, &eglConfig,
-                1, &numConfigs)) {
-            ALOGW("eglChooseConfig failed: 0x%x", eglGetError());
-            return false;
-        }
-
-        mEglSurface = eglCreatePbufferSurface(mEglDisplay, eglConfig,
-                kPbufferAttribs);
-        if (mEglSurface == EGL_NO_SURFACE) {
-            ALOGW("eglCreatePbufferSurface failed: 0x%x", eglGetError());
-            return false;
-        }
-
-        mEglContext = eglCreateContext(mEglDisplay, eglConfig, EGL_NO_CONTEXT,
-                kContextAttribs);
-        if (mEglContext == EGL_NO_CONTEXT) {
-            ALOGW("eglCreateContext failed: 0x%x", eglGetError());
-            return false;
-        }
-
-        return true;
-    }
-
-    /*
-     * Releases EGL.  How we do that depends on the type of test we're
-     * running.
-     */
-    bool eglRelease_l() {
-        if (mEglDisplay == EGL_NO_DISPLAY) {
-            ALOGW("No display to release");
-            return false;
-        }
-
-        switch (mTestType) {
-        case TEST_CORRECT:
-            eglTerminate(mEglDisplay);
-            eglReleaseThread();
-            break;
-        case TEST_NO_RELEASE_CURRENT:
-            eglDestroyContext(mEglDisplay, mEglContext);
-            eglDestroySurface(mEglDisplay, mEglSurface);
-            eglTerminate(mEglDisplay);
-            break;
-        default:
-            ALOGE("Unknown test type %d", mTestType);
-            break;
-        }
-
-        int err = eglGetError();
-        if (err != EGL_SUCCESS) {
-            ALOGW("eglRelease failed: 0x%x", err);
-            return false;
-        }
-        return true;
-    }
-};
-
-
-/* do things correctly */
-TEST_F(EGLCleanupTest, TestCorrect) {
-    ALOGI("Starting TEST_CORRECT");
-    ChainedThread cht(ChainedThread::TEST_CORRECT);
-
-    // start initial thread
-    ASSERT_TRUE(cht.start());
-
-    // wait for the end
-    cht.waitForEnd();
-    bool result = cht.getResult();
-    ASSERT_TRUE(result);
-}
-
-/* try it without un-currenting the surfaces and context
-TEST _F(EGLCleanupTest, TestNoReleaseCurrent) {
-    ALOGI("Starting TEST_NO_RELEASE_CURRENT");
-    ChainedThread cht(ChainedThread::TEST_NO_RELEASE_CURRENT);
-
-    // start initial thread
-    ASSERT_TRUE(cht.start());
-
-    // wait for the end
-    cht.waitForEnd();
-    bool result = cht.getResult();
-    ASSERT_TRUE(result);
-}
-*/
-
-} // namespace android
diff --git a/tests/tests/nativeopengl/standalone/jni/tests/EGLCreateContext_test.cpp b/tests/tests/nativeopengl/standalone/jni/tests/EGLCreateContext_test.cpp
deleted file mode 100644
index b7e5f7c..0000000
--- a/tests/tests/nativeopengl/standalone/jni/tests/EGLCreateContext_test.cpp
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <android/native_window.h>
-
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-#include <GLES2/gl2.h>
-
-#include <gtest/gtest.h>
-
-#include <android/log.h>
-
-#include "GLTestHelper.h"
-
-#define LOG_TAG "EGLCreateContext_test"
-#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
-#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
-
-namespace android {
-
-static int getGlVersion() {
-    const char* s = (const char*)glGetString(GL_VERSION);
-    if (!s)
-        return 0;
-    int major, minor;
-    if (sscanf(s, "OpenGL ES %d.%d", &major, &minor) != 2)
-        return 0;
-    return major;
-}
-
-class EGLCreateContextTest : public ::testing::Test {
-
-protected:
-
-    EGLCreateContextTest()
-    :   mEglDisplay(EGL_NO_DISPLAY),
-        mEglConfig(0),
-        mEglWindowSurface(EGL_NO_SURFACE),
-        mEglContext(EGL_NO_CONTEXT)
-    {}
-
-    virtual void SetUp() {
-        // static const EGLint SURFACE_ATTRIBS[] = {
-        //     EGL_NONE
-        // };
-
-        mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
-        ASSERT_NE(EGL_NO_DISPLAY, mEglDisplay);
-
-        EGLint major, minor;
-        ASSERT_TRUE(eglInitialize(mEglDisplay, &major, &minor));
-
-        EGLint numConfigs = 0;
-        ASSERT_TRUE(eglChooseConfig(mEglDisplay, getConfigAttribs(),
-                &mEglConfig, 1, &numConfigs));
-        ASSERT_GE(1, numConfigs);
-        ASSERT_NE((EGLConfig)0, mEglConfig);
-
-        mEglWindowSurface = eglCreateWindowSurface(mEglDisplay, mEglConfig,
-                GLTestHelper::getWindow(), getWindowSurfaceAttribs());
-        ASSERT_EQ(EGL_SUCCESS, eglGetError());
-        ASSERT_NE(EGL_NO_SURFACE, mEglWindowSurface);
-    }
-
-    virtual void TearDown() {
-        if (mEglContext != EGL_NO_CONTEXT) {
-            eglDestroyContext(mEglDisplay, mEglContext);
-        }
-        if (mEglWindowSurface != EGL_NO_SURFACE) {
-            eglDestroySurface(mEglDisplay, mEglWindowSurface);
-        }
-        if (mEglDisplay != EGL_NO_DISPLAY) {
-            eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
-                    EGL_NO_CONTEXT);
-            eglTerminate(mEglDisplay);
-        }
-        ASSERT_EQ(EGL_SUCCESS, eglGetError());
-    }
-
-    virtual const EGLint* getConfigAttribs() {
-        static const EGLint ATTRIBS[] = {
-            EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
-            EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
-            EGL_RED_SIZE, 8,
-            EGL_GREEN_SIZE, 8,
-            EGL_BLUE_SIZE, 8,
-            EGL_ALPHA_SIZE, 8,
-            EGL_NONE
-        };
-        return ATTRIBS;
-    }
-
-    virtual const EGLint* getWindowSurfaceAttribs() {
-        return NULL;
-    }
-
-    EGLDisplay mEglDisplay;
-    EGLConfig  mEglConfig;
-    EGLSurface mEglWindowSurface;
-    EGLContext mEglContext;
-};
-
-TEST_F(EGLCreateContextTest, BadAttributeFails) {
-    // First check that we can successfully create a context
-    EGLint attribs[5] = {
-        EGL_CONTEXT_CLIENT_VERSION, 2,
-        EGL_NONE, EGL_NONE, EGL_NONE,
-    };
-    mEglContext = eglCreateContext(mEglDisplay, mEglConfig, EGL_NO_CONTEXT,
-            attribs);
-    ASSERT_NE(mEglContext, EGL_NO_CONTEXT);
-    ASSERT_EQ(eglGetError(), EGL_SUCCESS);
-    ASSERT_EQ(EGL_TRUE, eglDestroyContext(mEglDisplay, mEglContext));
-    mEglContext = EGL_NO_CONTEXT;
-
-    // Now add an invalid attribute and make sure eglCreateContext fails
-    attribs[2] = EGL_BAD_ATTRIBUTE; // error code, not a valid attribute
-    mEglContext = eglCreateContext(mEglDisplay, mEglConfig, EGL_NO_CONTEXT,
-            attribs);
-    ASSERT_EQ(mEglContext, EGL_NO_CONTEXT);
-    ASSERT_EQ(eglGetError(), EGL_BAD_ATTRIBUTE);
-}
-
-} // namespace android
diff --git a/tests/tests/nativeopengl/standalone/jni/tests/GLTest_test.cpp b/tests/tests/nativeopengl/standalone/jni/tests/GLTest_test.cpp
deleted file mode 100644
index 5df090d..0000000
--- a/tests/tests/nativeopengl/standalone/jni/tests/GLTest_test.cpp
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * Copyright 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-#include <android/native_window.h>
-
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-
-#include <gtest/gtest.h>
-
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-
-#include <GLTestHelper.h>
-
-
-namespace android {
-
-class GLTest : public ::testing::Test {
-
-protected:
-
-    GLTest():
-            mEglDisplay(EGL_NO_DISPLAY),
-            mEglSurface(EGL_NO_SURFACE),
-            mEglContext(EGL_NO_CONTEXT) {
-    }
-
-
-   virtual void SetUp() {
-        mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
-        ASSERT_EQ(EGL_SUCCESS, eglGetError());
-        ASSERT_NE(EGL_NO_DISPLAY, mEglDisplay);
-
-        EGLint majorVersion;
-        EGLint minorVersion;
-        EXPECT_TRUE(eglInitialize(mEglDisplay, &majorVersion, &minorVersion));
-        ASSERT_EQ(EGL_SUCCESS, eglGetError());
-
-        EGLint numConfigs = 0;
-        EXPECT_TRUE(eglChooseConfig(mEglDisplay, getConfigAttribs(), &mGlConfig,
-                1, &numConfigs));
-        ASSERT_EQ(EGL_SUCCESS, eglGetError());
-
-        char* displaySecsEnv = getenv("GLTEST_DISPLAY_SECS");
-        if (displaySecsEnv != NULL) {
-            mDisplaySecs = atoi(displaySecsEnv);
-            if (mDisplaySecs < 0) {
-                mDisplaySecs = 0;
-            }
-        } else {
-            mDisplaySecs = 0;
-        }
-
-        if (mDisplaySecs > 0) {
-            mEglSurface = eglCreateWindowSurface(mEglDisplay, mGlConfig,
-                    GLTestHelper::getWindow(), NULL);
-        } else {
-            EGLint pbufferAttribs[] = {
-                EGL_WIDTH, getSurfaceWidth(),
-                EGL_HEIGHT, getSurfaceHeight(),
-                EGL_NONE };
-
-            mEglSurface = eglCreatePbufferSurface(mEglDisplay, mGlConfig,
-                    pbufferAttribs);
-        }
-        ASSERT_EQ(EGL_SUCCESS, eglGetError());
-        ASSERT_NE(EGL_NO_SURFACE, mEglSurface);
-
-        mEglContext = eglCreateContext(mEglDisplay, mGlConfig, EGL_NO_CONTEXT,
-                getContextAttribs());
-        ASSERT_EQ(EGL_SUCCESS, eglGetError());
-        ASSERT_NE(EGL_NO_CONTEXT, mEglContext);
-
-        EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
-                mEglContext));
-        ASSERT_EQ(EGL_SUCCESS, eglGetError());
-
-        EGLint w, h;
-        EXPECT_TRUE(eglQuerySurface(mEglDisplay, mEglSurface, EGL_WIDTH, &w));
-        ASSERT_EQ(EGL_SUCCESS, eglGetError());
-        EXPECT_TRUE(eglQuerySurface(mEglDisplay, mEglSurface, EGL_HEIGHT, &h));
-        ASSERT_EQ(EGL_SUCCESS, eglGetError());
-
-        glViewport(0, 0, w, h);
-        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
-    }
-
-    virtual void TearDown() {
-        // Display the result
-        if (mDisplaySecs > 0 && mEglSurface != EGL_NO_SURFACE) {
-            eglSwapBuffers(mEglDisplay, mEglSurface);
-            sleep(mDisplaySecs);
-        }
-
-        if (mEglContext != EGL_NO_CONTEXT) {
-            eglDestroyContext(mEglDisplay, mEglContext);
-        }
-        if (mEglSurface != EGL_NO_SURFACE) {
-            eglDestroySurface(mEglDisplay, mEglSurface);
-        }
-        if (mEglDisplay != EGL_NO_DISPLAY) {
-            eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
-                    EGL_NO_CONTEXT);
-            eglTerminate(mEglDisplay);
-        }
-        ASSERT_EQ(EGL_SUCCESS, eglGetError());
-    }
-
-    virtual EGLint const* getConfigAttribs() {
-        static EGLint sDefaultConfigAttribs[] = {
-            EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
-            EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
-            EGL_RED_SIZE, 8,
-            EGL_GREEN_SIZE, 8,
-            EGL_BLUE_SIZE, 8,
-            EGL_ALPHA_SIZE, 8,
-            EGL_DEPTH_SIZE, 16,
-            EGL_STENCIL_SIZE, 8,
-            EGL_NONE };
-
-        return sDefaultConfigAttribs;
-    }
-
-    virtual EGLint const* getContextAttribs() {
-        static EGLint sDefaultContextAttribs[] = {
-            EGL_CONTEXT_CLIENT_VERSION, 2,
-            EGL_NONE };
-
-        return sDefaultContextAttribs;
-    }
-
-    virtual EGLint getSurfaceWidth() {
-        return 512;
-    }
-
-    virtual EGLint getSurfaceHeight() {
-        return 512;
-    }
-
-    bool checkPixel(GLubyte * actual, GLubyte * expected, int tolerance) {
-        for (int i = 0; i < 4; i++) {
-            if (abs(actual[i] - expected[i]) > tolerance) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    ::testing::AssertionResult AssertPixel(const char* a_expr,
-            const char* e_expr, const char* t_expr, GLubyte * actual,
-            GLubyte * expected, int tolerance) {
-
-        if (checkPixel(actual, expected, tolerance)) {
-            return ::testing::AssertionSuccess();
-        }
-
-        return ::testing::AssertionFailure()
-            << "Pixel comparison failed with tolerance " << tolerance << "\n"
-            << "Actual: r=" << (int)actual[0] << " g=" << (int)actual[1]
-            << " b=" << (int)actual[2] << " a=" << (int)actual[3] << "\n"
-            << "Expected: r=" << (int)expected[0] << " g=" << (int)expected[1]
-            << " b=" << (int)expected[2] << " a=" << (int)expected[3] << "\n";
-    }
-
-    int mDisplaySecs;
-
-    EGLDisplay mEglDisplay;
-    EGLSurface mEglSurface;
-    EGLContext mEglContext;
-    EGLConfig  mGlConfig;
-};
-
-TEST_F(GLTest, ClearColorTest) {
-    glClearColor(0.2, 0.2, 0.2, 0.2);
-    glClear(GL_COLOR_BUFFER_BIT);
-    GLubyte expected[4] = { 51, 51, 51, 51 };
-    GLubyte pixel[4];
-    glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
-    ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
-    ASSERT_PRED_FORMAT3(AssertPixel, pixel, expected, 2);
-}
-
-} // namespace android
diff --git a/tests/tests/nativeopengl/standalone/src/com/android/gltest/GLTestActivity.java b/tests/tests/nativeopengl/standalone/src/com/android/gltest/GLTestActivity.java
deleted file mode 100644
index f0c250b..0000000
--- a/tests/tests/nativeopengl/standalone/src/com/android/gltest/GLTestActivity.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.gltest;
-
-import android.app.Activity;
-import android.app.KeyguardManager;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.os.Bundle;
-import android.view.SurfaceHolder;
-import android.view.SurfaceView;
-import android.view.Surface;
-
-public class GLTestActivity extends Activity {
-
-    private class TestThread extends Thread {
-
-        public void run() {
-            // it is possible to set the GTest filter flag from here
-            // for example "GLTest.ClearColorTest" to run that specific test only
-            runTests(null);
-
-            try {
-                Thread.sleep(1000);
-            } catch (InterruptedException e) {
-            }
-
-            finish();
-            System.exit(0);
-        }
-    }
-
-    private SurfaceView mSurfaceView;
-
-    private SurfaceHolder.Callback mHolderCallback = new SurfaceHolder.Callback() {
-
-        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
-            setSurface(holder.getSurface());
-        }
-
-        public void surfaceCreated(SurfaceHolder holder) {
-            setSurface(holder.getSurface());
-            Thread t = new TestThread();
-            t.start();
-        }
-
-        public void surfaceDestroyed(SurfaceHolder holder) {
-        }
-    };
-
-    @SuppressWarnings("deprecation")
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        if (checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
-                == PackageManager.PERMISSION_GRANTED) {
-            KeyguardManager keyguardManager =
-                (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
-            keyguardManager.newKeyguardLock("gltest").disableKeyguard();
-        }
-
-        super.onCreate(savedInstanceState);
-
-        mSurfaceView = new SurfaceView(this);
-        mSurfaceView.getHolder().addCallback(mHolderCallback);
-        setContentView(mSurfaceView);
-        System.loadLibrary("stlport_shared");
-        System.loadLibrary("nativeopengltests");
-    }
-
-    private static native void setSurface(Surface surface);
-    private static native void runTests(String filter);
-}
diff --git a/tests/tests/ndef/Android.mk b/tests/tests/ndef/Android.mk
index ba78f29..bd60a1a 100644
--- a/tests/tests/ndef/Android.mk
+++ b/tests/tests/ndef/Android.mk
@@ -30,4 +30,7 @@
 
 LOCAL_SDK_VERSION := current
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/ndef/AndroidManifest.xml b/tests/tests/ndef/AndroidManifest.xml
index e0244e1..dcec27d 100644
--- a/tests/tests/ndef/AndroidManifest.xml
+++ b/tests/tests/ndef/AndroidManifest.xml
@@ -15,7 +15,7 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.ndef">
+    package="android.ndef.cts">
 
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <application>
@@ -24,7 +24,7 @@
 
     <!-- This is a self-instrumenting test package. -->
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.cts.ndef"
+                     android:targetPackage="android.ndef.cts"
                      android:label="CTS tests of NDEF data classes">
         <meta-data android:name="listener"
             android:value="com.android.cts.runner.CtsTestRunListener" />
diff --git a/tests/tests/ndef/AndroidTest.xml b/tests/tests/ndef/AndroidTest.xml
new file mode 100644
index 0000000..cfb40d3
--- /dev/null
+++ b/tests/tests/ndef/AndroidTest.xml
@@ -0,0 +1,23 @@
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS NDEF test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsNdefTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.ndef.cts" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/tests/net/Android.mk b/tests/tests/net/Android.mk
index 6524871..c553a9b 100644
--- a/tests/tests/net/Android.mk
+++ b/tests/tests/net/Android.mk
@@ -27,7 +27,7 @@
 LOCAL_JAVA_LIBRARIES := voip-common conscrypt org.apache.http.legacy
 
 LOCAL_JNI_SHARED_LIBRARIES := libcts_jni libnativedns_jni \
-                              libnativemultinetwork_jni
+                              libnativemultinetwork_jni libnativehelper_compat_libc++
 
 # include CtsTestServer as a temporary hack to free net.cts from cts.stub.
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
@@ -40,6 +40,9 @@
 # uncomment when b/13249961 is fixed
 #LOCAL_SDK_VERSION := current
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_CTS_PACKAGE)
 
 include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/tests/net/AndroidManifest.xml b/tests/tests/net/AndroidManifest.xml
index 848ed99..dd310a1 100644
--- a/tests/tests/net/AndroidManifest.xml
+++ b/tests/tests/net/AndroidManifest.xml
@@ -16,7 +16,7 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.net">
+    package="android.net.cts">
 
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
@@ -33,10 +33,16 @@
     <application>
         <uses-library android:name="android.test.runner" />
         <uses-library android:name="org.apache.http.legacy" android:required="false" />
+
+        <receiver android:name=".ConnectivityReceiver">
+            <intent-filter>
+                <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
+            </intent-filter>
+        </receiver>
     </application>
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.cts.net"
+                     android:targetPackage="android.net.cts"
                      android:label="CTS tests of android.net">
         <meta-data android:name="listener"
             android:value="com.android.cts.runner.CtsTestRunListener" />
diff --git a/tests/tests/net/AndroidTest.xml b/tests/tests/net/AndroidTest.xml
new file mode 100644
index 0000000..dc80339
--- /dev/null
+++ b/tests/tests/net/AndroidTest.xml
@@ -0,0 +1,25 @@
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS Net test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.WifiCheck" />
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsNetTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.net.cts" />
+        <option name="runtime-hint" value="9m4s" />
+    </test>
+</configuration>
diff --git a/tests/tests/net/jni/Android.mk b/tests/tests/net/jni/Android.mk
index ca82b30..0ec8d28 100644
--- a/tests/tests/net/jni/Android.mk
+++ b/tests/tests/net/jni/Android.mk
@@ -25,8 +25,8 @@
 
 LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
 
-LOCAL_SHARED_LIBRARIES := libnativehelper liblog
-
+LOCAL_SHARED_LIBRARIES := libnativehelper_compat_libc++ liblog
+LOCAL_CXX_STL := libc++_static
 include $(BUILD_SHARED_LIBRARY)
 
 include $(CLEAR_VARS)
@@ -35,5 +35,6 @@
 LOCAL_MODULE_TAGS := optional
 LOCAL_SRC_FILES := NativeMultinetworkJni.c
 LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
-LOCAL_SHARED_LIBRARIES := libandroid libnativehelper liblog
+LOCAL_SHARED_LIBRARIES := libandroid libnativehelper_compat_libc++ liblog
+LOCAL_CXX_STL := libc++_static
 include $(BUILD_SHARED_LIBRARY)
diff --git a/tests/tests/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/tests/net/src/android/net/cts/ConnectivityManagerTest.java
index 9a99c22..4112466 100644
--- a/tests/tests/net/src/android/net/cts/ConnectivityManagerTest.java
+++ b/tests/tests/net/src/android/net/cts/ConnectivityManagerTest.java
@@ -265,13 +265,16 @@
         }
 
         // We will register for a WIFI network being available or lost.
-        NetworkRequest request = new NetworkRequest.Builder()
+        final NetworkRequest request = new NetworkRequest.Builder()
                 .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
                 .build();
-        TestNetworkCallback callback = new TestNetworkCallback();
+        final TestNetworkCallback callback = new TestNetworkCallback();
         mCm.registerNetworkCallback(request, callback);
 
-        boolean previousWifiEnabledState = mWifiManager.isWifiEnabled();
+        final TestNetworkCallback defaultTrackingCallback = new TestNetworkCallback();
+        mCm.registerDefaultNetworkCallback(defaultTrackingCallback);
+
+        final boolean previousWifiEnabledState = mWifiManager.isWifiEnabled();
 
         try {
             // Make sure WiFi is connected to an access point to start with.
@@ -284,12 +287,16 @@
             // is registered.
             assertTrue("Did not receive NetworkCallback.onAvailable for TRANSPORT_WIFI",
                     callback.waitForAvailable());
+
+            assertTrue("Did not receive NetworkCallback.onAvailable for any default network",
+                    defaultTrackingCallback.waitForAvailable());
         } catch (InterruptedException e) {
             fail("Broadcast receiver or NetworkCallback wait was interrupted.");
         } finally {
             mCm.unregisterNetworkCallback(callback);
+            mCm.unregisterNetworkCallback(defaultTrackingCallback);
 
-            // Return WiFI to its original enabled/disabled state.
+            // Return WiFi to its original enabled/disabled state.
             if (!previousWifiEnabledState) {
                 disconnectFromWifi();
             }
@@ -327,7 +334,7 @@
                 .build();
         mCm.registerNetworkCallback(request, pendingIntent);
 
-        boolean previousWifiEnabledState = mWifiManager.isWifiEnabled();
+        final boolean previousWifiEnabledState = mWifiManager.isWifiEnabled();
 
         try {
             // Make sure WiFi is connected to an access point to start with.
@@ -347,13 +354,43 @@
             pendingIntent.cancel();
             mContext.unregisterReceiver(receiver);
 
-            // Return WiFI to its original enabled/disabled state.
+            // Return WiFi to its original enabled/disabled state.
             if (!previousWifiEnabledState) {
                 disconnectFromWifi();
             }
         }
     }
 
+    /**
+     * Tests reporting of connectivity changed.
+     */
+    public void testConnectivityChanged() {
+        // We are going to ensure that we *don't* see the connectivity in the manifest.
+        ConnectivityReceiver.prepare();
+
+        // We will toggle the state of wifi to generate a connectivity change.
+        final boolean previousWifiEnabledState = mWifiManager.isWifiEnabled();
+        if (previousWifiEnabledState) {
+            disconnectFromWifi();
+        } else {
+            connectToWifi();
+        }
+
+        // The connectivity broadcast has been sent; push through a terminal broadcast
+        // to wait for in the receive to confirm it didn't see the connectivity change.
+        Intent finalIntent = new Intent(ConnectivityReceiver.FINAL_ACTION);
+        finalIntent.setClass(mContext, ConnectivityReceiver.class);
+        mContext.sendBroadcast(finalIntent);
+        assertFalse(ConnectivityReceiver.waitForBroadcast());
+
+        // Now restore previous state.
+        if (previousWifiEnabledState) {
+            connectToWifi();
+        } else {
+            disconnectFromWifi();
+        }
+    }
+
     /** Enable WiFi and wait for it to become connected to a network. */
     private void connectToWifi() {
         ConnectivityActionReceiver receiver = new ConnectivityActionReceiver(
diff --git a/tests/tests/net/src/android/net/cts/ConnectivityReceiver.java b/tests/tests/net/src/android/net/cts/ConnectivityReceiver.java
new file mode 100644
index 0000000..6a7b4a0
--- /dev/null
+++ b/tests/tests/net/src/android/net/cts/ConnectivityReceiver.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.cts;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.net.ConnectivityManager;
+import android.util.Log;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+public class ConnectivityReceiver extends BroadcastReceiver {
+    static boolean sReceivedConnectivity;
+    static boolean sReceivedFinal;
+    static CountDownLatch sLatch;
+
+    static void prepare() {
+        synchronized (ConnectivityReceiver.class) {
+            sReceivedConnectivity = sReceivedFinal = false;
+            sLatch = new CountDownLatch(1);
+        }
+    }
+
+    static boolean waitForBroadcast() {
+        try {
+            sLatch.await(30, TimeUnit.SECONDS);
+        } catch (InterruptedException e) {
+            throw new IllegalStateException(e);
+        }
+        synchronized (ConnectivityReceiver.class) {
+            sLatch = null;
+            if (!sReceivedFinal) {
+                throw new IllegalStateException("Never received final broadcast");
+            }
+            return sReceivedConnectivity;
+        }
+    }
+
+    static final String FINAL_ACTION = "android.net.cts.action.FINAL";
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        Log.i("ConnectivityReceiver", "Received: " + intent.getAction());
+        if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) {
+            sReceivedConnectivity = true;
+        } else if (FINAL_ACTION.equals(intent.getAction())) {
+            sReceivedFinal = true;
+            if (sLatch != null) {
+                sLatch.countDown();
+            }
+        }
+    }
+}
diff --git a/tests/tests/net/src/android/net/cts/LocalServerSocketTest.java b/tests/tests/net/src/android/net/cts/LocalServerSocketTest.java
index dc7be1f..103d1da 100644
--- a/tests/tests/net/src/android/net/cts/LocalServerSocketTest.java
+++ b/tests/tests/net/src/android/net/cts/LocalServerSocketTest.java
@@ -15,28 +15,27 @@
  */
 package android.net.cts;
 
+import junit.framework.TestCase;
+
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import android.net.LocalServerSocket;
 import android.net.LocalSocket;
 import android.net.LocalSocketAddress;
-import android.test.AndroidTestCase;
 
-public class LocalServerSocketTest extends AndroidTestCase {
+public class LocalServerSocketTest extends TestCase {
 
     public void testLocalServerSocket() throws IOException {
-        LocalServerSocket localServerSocket = new LocalServerSocket(LocalSocketTest.mSockAddr);
+        String address = "com.android.net.LocalServerSocketTest_testLocalServerSocket";
+        LocalServerSocket localServerSocket = new LocalServerSocket(address);
         assertNotNull(localServerSocket.getLocalSocketAddress());
-        commonFunctions(localServerSocket);
-    }
 
-    public void commonFunctions(LocalServerSocket localServerSocket) throws IOException {
         // create client socket
         LocalSocket clientSocket = new LocalSocket();
 
         // establish connection between client and server
-        clientSocket.connect(new LocalSocketAddress(LocalSocketTest.mSockAddr));
+        clientSocket.connect(new LocalSocketAddress(address));
         LocalSocket serverSocket = localServerSocket.accept();
 
         // send data from client to server
diff --git a/tests/tests/net/src/android/net/cts/LocalSocketTest.java b/tests/tests/net/src/android/net/cts/LocalSocketTest.java
index 865ec21..77f0a44 100644
--- a/tests/tests/net/src/android/net/cts/LocalSocketTest.java
+++ b/tests/tests/net/src/android/net/cts/LocalSocketTest.java
@@ -16,26 +16,31 @@
 
 package android.net.cts;
 
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
+import junit.framework.TestCase;
+
 import android.net.Credentials;
 import android.net.LocalServerSocket;
 import android.net.LocalSocket;
 import android.net.LocalSocketAddress;
-import android.test.AndroidTestCase;
 
-public class LocalSocketTest extends AndroidTestCase{
-    public final static String mSockAddr = "com.android.net.LocalSocketTest";
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 
-    public void testLocalConnections() throws IOException{
+public class LocalSocketTest extends TestCase {
+    private final static String ADDRESS_PREFIX = "com.android.net.LocalSocketTest";
+
+    public void testLocalConnections() throws IOException {
+        String address = ADDRESS_PREFIX + "_testLocalConnections";
         // create client and server socket
-        LocalServerSocket localServerSocket = new LocalServerSocket(mSockAddr);
+        LocalServerSocket localServerSocket = new LocalServerSocket(address);
         LocalSocket clientSocket = new LocalSocket();
 
         // establish connection between client and server
-        LocalSocketAddress locSockAddr = new LocalSocketAddress(mSockAddr);
+        LocalSocketAddress locSockAddr = new LocalSocketAddress(address);
         assertFalse(clientSocket.isConnected());
         clientSocket.connect(locSockAddr);
         assertTrue(clientSocket.isConnected());
@@ -111,9 +116,10 @@
         }
     }
 
-    public void testAccessors() throws IOException{
+    public void testAccessors() throws IOException {
+        String address = ADDRESS_PREFIX + "_testAccessors";
         LocalSocket socket = new LocalSocket();
-        LocalSocketAddress addr = new LocalSocketAddress("secondary");
+        LocalSocketAddress addr = new LocalSocketAddress(address);
 
         assertFalse(socket.isBound());
         socket.bind(addr);
@@ -129,9 +135,9 @@
         socket.setSendBufferSize(3998);
         assertEquals(3998 << 1, socket.getSendBufferSize());
 
-        // Timeout is not support at present, so set is ignored
-        socket.setSoTimeout(1996);
         assertEquals(0, socket.getSoTimeout());
+        socket.setSoTimeout(1996);
+        assertTrue(socket.getSoTimeout() > 0);
 
         try {
             socket.getRemoteSocketAddress();
@@ -167,5 +173,127 @@
         } catch (UnsupportedOperationException e) {
             // expected
         }
+
+        socket.close();
+    }
+
+    public void testAvailable() throws Exception {
+        String address = ADDRESS_PREFIX + "_testAvailable";
+        LocalServerSocket localServerSocket = new LocalServerSocket(address);
+        LocalSocket clientSocket = new LocalSocket();
+
+        // establish connection between client and server
+        LocalSocketAddress locSockAddr = new LocalSocketAddress(address);
+        clientSocket.connect(locSockAddr);
+        assertTrue(clientSocket.isConnected());
+        LocalSocket serverSocket = localServerSocket.accept();
+
+        OutputStream clientOutputStream = clientSocket.getOutputStream();
+        InputStream serverInputStream = serverSocket.getInputStream();
+        assertEquals(0, serverInputStream.available());
+
+        byte[] buffer = new byte[50];
+        clientOutputStream.write(buffer);
+        assertEquals(50, serverInputStream.available());
+
+        InputStream clientInputStream = clientSocket.getInputStream();
+        OutputStream serverOutputStream = serverSocket.getOutputStream();
+        assertEquals(0, clientInputStream.available());
+        serverOutputStream.write(buffer);
+        assertEquals(50, serverInputStream.available());
+
+        clientSocket.close();
+        serverSocket.close();
+        localServerSocket.close();
+    }
+
+    public void testFlush() throws Exception {
+        String address = ADDRESS_PREFIX + "_testFlush";
+        LocalServerSocket localServerSocket = new LocalServerSocket(address);
+        LocalSocket clientSocket = new LocalSocket();
+
+        // establish connection between client and server
+        LocalSocketAddress locSockAddr = new LocalSocketAddress(address);
+        clientSocket.connect(locSockAddr);
+        assertTrue(clientSocket.isConnected());
+        LocalSocket serverSocket = localServerSocket.accept();
+
+        OutputStream clientOutputStream = clientSocket.getOutputStream();
+        InputStream serverInputStream = serverSocket.getInputStream();
+        testFlushWorks(clientOutputStream, serverInputStream);
+
+        OutputStream serverOutputStream = serverSocket.getOutputStream();
+        InputStream clientInputStream = clientSocket.getInputStream();
+        testFlushWorks(serverOutputStream, clientInputStream);
+
+        clientSocket.close();
+        serverSocket.close();
+        localServerSocket.close();
+    }
+
+    private void testFlushWorks(OutputStream outputStream, InputStream inputStream)
+            throws Exception {
+        final int bytesToTransfer = 50;
+        StreamReader inputStreamReader = new StreamReader(inputStream, bytesToTransfer);
+
+        byte[] buffer = new byte[bytesToTransfer];
+        outputStream.write(buffer);
+        assertEquals(bytesToTransfer, inputStream.available());
+
+        // Start consuming the data.
+        inputStreamReader.start();
+
+        // This doesn't actually flush any buffers, it just polls until the reader has read all the
+        // bytes.
+        outputStream.flush();
+
+        inputStreamReader.waitForCompletion(5000);
+        inputStreamReader.assertBytesRead(bytesToTransfer);
+        assertEquals(0, inputStream.available());
+    }
+
+    private static class StreamReader extends Thread {
+        private final InputStream is;
+        private final int expectedByteCount;
+        private final CountDownLatch completeLatch = new CountDownLatch(1);
+
+        private volatile Exception exception;
+        private int bytesRead;
+
+        private StreamReader(InputStream is, int expectedByteCount) {
+            this.is = is;
+            this.expectedByteCount = expectedByteCount;
+        }
+
+        @Override
+        public void run() {
+            try {
+                byte[] buffer = new byte[10];
+                int readCount;
+                while ((readCount = is.read(buffer)) >= 0) {
+                    bytesRead += readCount;
+                    if (bytesRead >= expectedByteCount) {
+                        break;
+                    }
+                }
+            } catch (IOException e) {
+                exception = e;
+            } finally {
+                completeLatch.countDown();
+            }
+        }
+
+        public void waitForCompletion(long waitMillis) throws Exception {
+            if (!completeLatch.await(waitMillis, TimeUnit.MILLISECONDS)) {
+                fail("Timeout waiting for completion");
+            }
+            if (exception != null) {
+                throw new Exception("Read failed", exception);
+            }
+        }
+
+        public void assertBytesRead(int expected) {
+            assertEquals(expected, bytesRead);
+        }
     }
 }
diff --git a/tests/tests/net/src/android/net/wifi/cts/ConcurrencyTest.java b/tests/tests/net/src/android/net/wifi/cts/ConcurrencyTest.java
index 5accd77..a066ba8 100644
--- a/tests/tests/net/src/android/net/wifi/cts/ConcurrencyTest.java
+++ b/tests/tests/net/src/android/net/wifi/cts/ConcurrencyTest.java
@@ -20,12 +20,20 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.net.ConnectivityManager;
+import android.net.ConnectivityManager.NetworkCallback;
+import android.net.Network;
+import android.net.NetworkCapabilities;
+import android.net.NetworkRequest;
 import android.net.wifi.WifiManager;
 import android.net.wifi.p2p.WifiP2pManager;
 import static android.net.wifi.p2p.WifiP2pManager.WIFI_P2P_STATE_DISABLED;
 import static android.net.wifi.p2p.WifiP2pManager.WIFI_P2P_STATE_ENABLED;
 import android.test.AndroidTestCase;
 
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
 public class ConcurrencyTest extends AndroidTestCase {
     private class MySync {
         int expectedWifiState;
@@ -94,10 +102,7 @@
         }
         mContext.unregisterReceiver(mReceiver);
 
-        if (mWifiManager.isWifiEnabled()) {
-            assertTrue(mWifiManager.setWifiEnabled(false));
-            Thread.sleep(DURATION);
-        }
+        enableWifi();
         super.tearDown();
     }
 
@@ -114,6 +119,33 @@
         }
     }
 
+    /*
+     * Enables Wifi and block until connection is established.
+     */
+    private void enableWifi() throws InterruptedException {
+        if (!mWifiManager.isWifiEnabled()) {
+            assertTrue(mWifiManager.setWifiEnabled(true));
+        }
+
+        ConnectivityManager cm =
+            (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
+        NetworkRequest request =
+            new NetworkRequest.Builder().addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
+                                        .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
+                                        .build();
+        final CountDownLatch latch = new CountDownLatch(1);
+        NetworkCallback networkCallback = new NetworkCallback() {
+            @Override
+            public void onAvailable(Network network) {
+                latch.countDown();
+            }
+        };
+        cm.registerNetworkCallback(request, networkCallback);
+        latch.await(DURATION, TimeUnit.MILLISECONDS);
+
+        cm.unregisterNetworkCallback(networkCallback);
+    }
+
     public void testConcurrency() {
         // Cannot support p2p alone
         if (!WifiFeature.isWifiSupported(getContext())) {
diff --git a/tests/tests/net/src/android/net/wifi/cts/NsdManagerTest.java b/tests/tests/net/src/android/net/wifi/cts/NsdManagerTest.java
index e132cce..2e2e75b 100644
--- a/tests/tests/net/src/android/net/wifi/cts/NsdManagerTest.java
+++ b/tests/tests/net/src/android/net/wifi/cts/NsdManagerTest.java
@@ -24,6 +24,7 @@
 
 import java.io.IOException;
 import java.net.ServerSocket;
+import java.util.Arrays;
 import java.util.Random;
 import java.util.List;
 import java.util.ArrayList;
@@ -41,6 +42,7 @@
     NsdManager.RegistrationListener mRegistrationListener;
     NsdManager.DiscoveryListener mDiscoveryListener;
     NsdManager.ResolveListener mResolveListener;
+    private NsdServiceInfo mResolvedService;
 
     public NsdManagerTest() {
         initRegistrationListener();
@@ -119,6 +121,7 @@
 
             @Override
             public void onServiceResolved(NsdServiceInfo serviceInfo) {
+                mResolvedService = serviceInfo;
                 setEvent("onServiceResolved", serviceInfo);
             }
         };
@@ -254,14 +257,87 @@
         if (DBG) Log.d(TAG, "Tear down test ...");
     }
 
-    public void runTest() throws Exception {
+    public void testNDSManager() throws Exception {
+        EventData lastEvent = null;
+
+        if (DBG) Log.d(TAG, "Starting test ...");
+
         NsdServiceInfo si = new NsdServiceInfo();
         si.setServiceType(SERVICE_TYPE);
         si.setServiceName(mServiceName);
 
-        EventData lastEvent = null;
+        byte testByteArray[] = new byte[] {-128, 127, 2, 1, 0, 1, 2};
+        String String256 = "1_________2_________3_________4_________5_________6_________" +
+                 "7_________8_________9_________10________11________12________13________" +
+                 "14________15________16________17________18________19________20________" +
+                 "21________22________23________24________25________123456";
 
-        if (DBG) Log.d(TAG, "Starting test ...");
+        // Illegal attributes
+        try {
+            si.setAttribute(null, (String) null);
+            fail("Could set null key");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+
+        try {
+            si.setAttribute("", (String) null);
+            fail("Could set empty key");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+
+        try {
+            si.setAttribute(String256, (String) null);
+            fail("Could set key with 255 characters");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+
+        try {
+            si.setAttribute("key", String256.substring(3));
+            fail("Could set key+value combination with more than 255 characters");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+
+        try {
+            si.setAttribute("key", String256.substring(4));
+            fail("Could set key+value combination with 255 characters");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+
+        try {
+            si.setAttribute(new String(new byte[]{0x19}), (String) null);
+            fail("Could set key with invalid character");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+
+        try {
+            si.setAttribute("=", (String) null);
+            fail("Could set key with invalid character");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+
+        try {
+            si.setAttribute(new String(new byte[]{0x7F}), (String) null);
+            fail("Could set key with invalid character");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+
+        // Allowed attributes
+        si.setAttribute("booleanAttr", (String) null);
+        si.setAttribute("keyValueAttr", "value");
+        si.setAttribute("keyEqualsAttr", "=");
+        si.setAttribute(" whiteSpaceKeyValueAttr ", " value ");
+        si.setAttribute("binaryDataAttr", testByteArray);
+        si.setAttribute("nullBinaryDataAttr", (byte[]) null);
+        si.setAttribute("emptyBinaryDataAttr", new byte[]{});
+        si.setAttribute("longkey", String256.substring(9));
 
         ServerSocket socket;
         int localPort;
@@ -347,6 +423,25 @@
         mNsdManager.resolveService(si, mResolveListener);
         lastEvent = waitForCallback("onServiceResolved");                   // id = 4
 
+        assertNotNull(mResolvedService);
+
+        // Check Txt attributes
+        assertEquals(8, mResolvedService.getAttributes().size());
+        assertTrue(mResolvedService.getAttributes().containsKey("booleanAttr"));
+        assertNull(mResolvedService.getAttributes().get("booleanAttr"));
+        assertEquals("value", new String(mResolvedService.getAttributes().get("keyValueAttr")));
+        assertEquals("=", new String(mResolvedService.getAttributes().get("keyEqualsAttr")));
+        assertEquals(" value ", new String(mResolvedService.getAttributes()
+                .get(" whiteSpaceKeyValueAttr ")));
+        assertEquals(String256.substring(9), new String(mResolvedService.getAttributes()
+                .get("longkey")));
+        assertTrue(Arrays.equals(testByteArray,
+                mResolvedService.getAttributes().get("binaryDataAttr")));
+        assertTrue(mResolvedService.getAttributes().containsKey("nullBinaryDataAttr"));
+        assertNull(mResolvedService.getAttributes().get("nullBinaryDataAttr"));
+        assertTrue(mResolvedService.getAttributes().containsKey("emptyBinaryDataAttr"));
+        assertNull(mResolvedService.getAttributes().get("emptyBinaryDataAttr"));
+
         assertTrue(lastEvent != null);
         assertTrue(lastEvent.mSucceeded);
 
@@ -394,7 +489,41 @@
         registeredName = lastEvent.mInfo.getServiceName();
 
         // Expect a record to be discovered
-        lastEvent = waitForCallback("onServiceFound");                      // id = 8
+        // Expect a service record to be discovered (and filter the ones
+        // that are unrelated to this test)
+        found = false;
+        for (int i = 0; i < 32; i++) {
+
+            lastEvent = waitForCallback("onServiceFound");                  // id = 8
+            if (lastEvent == null) {
+                // no more onServiceFound events are being reported!
+                break;
+            }
+
+            assertTrue(lastEvent.mSucceeded);
+
+            if (DBG) Log.d(TAG, "id = " + String.valueOf(mWaitId) + ": ServiceName = " +
+                    lastEvent.mInfo.getServiceName());
+
+            if (lastEvent.mInfo.getServiceName().equals(registeredName)) {
+                // Save it, as it will get overwritten with new serviceFound events
+                si = lastEvent.mInfo;
+                found = true;
+            }
+
+            // Remove this event from the event cache, so it won't be found by subsequent
+            // calls to waitForCallback
+            synchronized (mEventCache) {
+                mEventCache.remove(lastEvent);
+            }
+        }
+
+        assertTrue(found);
+
+        // Resolve the service
+        clearEventCache();
+        mNsdManager.resolveService(si, mResolveListener);
+        lastEvent = waitForCallback("onServiceResolved");                   // id = 9
 
         assertTrue(lastEvent != null);
         assertTrue(lastEvent.mSucceeded);
@@ -404,11 +533,16 @@
 
         assertTrue(lastEvent.mInfo.getServiceName().equals(registeredName));
 
+        assertNotNull(mResolvedService);
+
+        // Check that we don't have any TXT records
+        assertEquals(0, mResolvedService.getAttributes().size());
+
         checkForAdditionalEvents();
         clearEventCache();
 
         mNsdManager.stopServiceDiscovery(mDiscoveryListener);
-        lastEvent = waitForCallback("onDiscoveryStopped");                  // id = 9
+        lastEvent = waitForCallback("onDiscoveryStopped");                  // id = 10
         assertTrue(lastEvent != null);
         assertTrue(lastEvent.mSucceeded);
         assertTrue(checkCacheSize(1));
@@ -418,7 +552,7 @@
 
         mNsdManager.unregisterService(mRegistrationListener);
 
-        lastEvent =  waitForCallback("onServiceUnregistered");              // id = 10
+        lastEvent =  waitForCallback("onServiceUnregistered");              // id = 11
         assertTrue(lastEvent != null);
         assertTrue(lastEvent.mSucceeded);
         assertTrue(checkCacheSize(1));
diff --git a/tests/tests/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java b/tests/tests/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java
index 2cc5951..f3eb4e9 100644
--- a/tests/tests/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java
+++ b/tests/tests/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java
@@ -25,6 +25,10 @@
 import android.net.wifi.WifiManager;
 import android.test.AndroidTestCase;
 
+import java.io.ByteArrayInputStream;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+
 public class WifiEnterpriseConfigTest extends AndroidTestCase {
     private  WifiManager mWifiManager;
 
@@ -39,6 +43,396 @@
     private static final String ANON_IDENTITY = "anonidentity";
     private static final int ENABLE_DELAY = 10000;
 
+    /*
+     * The keys and certificates below are generated with:
+     *
+     * openssl req -new -x509 -days 3650 -extensions v3_ca -keyout cakey.pem -out cacert.pem
+     * openssl ecparam -name prime256v1 -out ecparam.pem
+     * openssl req -newkey ec:ecparam.pem -keyout userkey.pem -nodes -days 3650 -out userkey.req
+     * mkdir -p demoCA/newcerts
+     * touch demoCA/index.txt
+     * echo "01" > demoCA/serial
+     * openssl ca -out usercert.pem -in userkey.req -cert cacert.pem -keyfile cakey.pem -days 3650
+     */
+
+    /**
+     * Generated from above and converted with:
+     *
+     * openssl x509 -outform d -in cacert.pem | xxd -i | sed 's/0x/(byte) 0x/g'
+     */
+
+    private static final byte[] FAKE_EC_1 = {
+        (byte) 0x30, (byte) 0x82, (byte) 0x04, (byte) 0x2f, (byte) 0x30, (byte) 0x82,
+        (byte) 0x03, (byte) 0x17, (byte) 0xa0, (byte) 0x03, (byte) 0x02, (byte) 0x01,
+        (byte) 0x02, (byte) 0x02, (byte) 0x09, (byte) 0x00, (byte) 0xa7, (byte) 0xe4,
+        (byte) 0x70, (byte) 0x50, (byte) 0x9b, (byte) 0xd2, (byte) 0x68, (byte) 0x68,
+        (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86,
+        (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01,
+        (byte) 0x0b, (byte) 0x05, (byte) 0x00, (byte) 0x30, (byte) 0x81, (byte) 0xad,
+        (byte) 0x31, (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03,
+        (byte) 0x55, (byte) 0x04, (byte) 0x06, (byte) 0x13, (byte) 0x02, (byte) 0x41,
+        (byte) 0x55, (byte) 0x31, (byte) 0x13, (byte) 0x30, (byte) 0x11, (byte) 0x06,
+        (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x08, (byte) 0x0c, (byte) 0x0a,
+        (byte) 0x53, (byte) 0x6f, (byte) 0x6d, (byte) 0x65, (byte) 0x2d, (byte) 0x53,
+        (byte) 0x74, (byte) 0x61, (byte) 0x74, (byte) 0x65, (byte) 0x31, (byte) 0x12,
+        (byte) 0x30, (byte) 0x10, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
+        (byte) 0x07, (byte) 0x0c, (byte) 0x09, (byte) 0x53, (byte) 0x6f, (byte) 0x6d,
+        (byte) 0x65, (byte) 0x2d, (byte) 0x43, (byte) 0x69, (byte) 0x74, (byte) 0x79,
+        (byte) 0x31, (byte) 0x15, (byte) 0x30, (byte) 0x13, (byte) 0x06, (byte) 0x03,
+        (byte) 0x55, (byte) 0x04, (byte) 0x0a, (byte) 0x0c, (byte) 0x0c, (byte) 0x53,
+        (byte) 0x6f, (byte) 0x6d, (byte) 0x65, (byte) 0x2d, (byte) 0x43, (byte) 0x6f,
+        (byte) 0x6d, (byte) 0x70, (byte) 0x61, (byte) 0x6e, (byte) 0x79, (byte) 0x31,
+        (byte) 0x10, (byte) 0x30, (byte) 0x0e, (byte) 0x06, (byte) 0x03, (byte) 0x55,
+        (byte) 0x04, (byte) 0x0b, (byte) 0x0c, (byte) 0x07, (byte) 0x53, (byte) 0x65,
+        (byte) 0x63, (byte) 0x74, (byte) 0x69, (byte) 0x6f, (byte) 0x6e, (byte) 0x31,
+        (byte) 0x21, (byte) 0x30, (byte) 0x1f, (byte) 0x06, (byte) 0x03, (byte) 0x55,
+        (byte) 0x04, (byte) 0x03, (byte) 0x0c, (byte) 0x18, (byte) 0x57, (byte) 0x69,
+        (byte) 0x66, (byte) 0x69, (byte) 0x45, (byte) 0x6e, (byte) 0x74, (byte) 0x65,
+        (byte) 0x72, (byte) 0x70, (byte) 0x72, (byte) 0x69, (byte) 0x73, (byte) 0x65,
+        (byte) 0x43, (byte) 0x6f, (byte) 0x6e, (byte) 0x66, (byte) 0x69, (byte) 0x67,
+        (byte) 0x54, (byte) 0x65, (byte) 0x73, (byte) 0x74, (byte) 0x31, (byte) 0x29,
+        (byte) 0x30, (byte) 0x27, (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86,
+        (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x09,
+        (byte) 0x01, (byte) 0x16, (byte) 0x1a, (byte) 0x61, (byte) 0x6e, (byte) 0x2d,
+        (byte) 0x65, (byte) 0x6d, (byte) 0x61, (byte) 0x69, (byte) 0x6c, (byte) 0x2d,
+        (byte) 0x61, (byte) 0x64, (byte) 0x72, (byte) 0x65, (byte) 0x73, (byte) 0x73,
+        (byte) 0x40, (byte) 0x64, (byte) 0x6f, (byte) 0x6d, (byte) 0x61, (byte) 0x69,
+        (byte) 0x6e, (byte) 0x2e, (byte) 0x63, (byte) 0x6f, (byte) 0x6d, (byte) 0x30,
+        (byte) 0x1e, (byte) 0x17, (byte) 0x0d, (byte) 0x31, (byte) 0x36, (byte) 0x30,
+        (byte) 0x31, (byte) 0x31, (byte) 0x35, (byte) 0x31, (byte) 0x31, (byte) 0x31,
+        (byte) 0x38, (byte) 0x35, (byte) 0x31, (byte) 0x5a, (byte) 0x17, (byte) 0x0d,
+        (byte) 0x32, (byte) 0x36, (byte) 0x30, (byte) 0x31, (byte) 0x31, (byte) 0x32,
+        (byte) 0x31, (byte) 0x31, (byte) 0x31, (byte) 0x38, (byte) 0x35, (byte) 0x31,
+        (byte) 0x5a, (byte) 0x30, (byte) 0x81, (byte) 0xad, (byte) 0x31, (byte) 0x0b,
+        (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
+        (byte) 0x06, (byte) 0x13, (byte) 0x02, (byte) 0x41, (byte) 0x55, (byte) 0x31,
+        (byte) 0x13, (byte) 0x30, (byte) 0x11, (byte) 0x06, (byte) 0x03, (byte) 0x55,
+        (byte) 0x04, (byte) 0x08, (byte) 0x0c, (byte) 0x0a, (byte) 0x53, (byte) 0x6f,
+        (byte) 0x6d, (byte) 0x65, (byte) 0x2d, (byte) 0x53, (byte) 0x74, (byte) 0x61,
+        (byte) 0x74, (byte) 0x65, (byte) 0x31, (byte) 0x12, (byte) 0x30, (byte) 0x10,
+        (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x07, (byte) 0x0c,
+        (byte) 0x09, (byte) 0x53, (byte) 0x6f, (byte) 0x6d, (byte) 0x65, (byte) 0x2d,
+        (byte) 0x43, (byte) 0x69, (byte) 0x74, (byte) 0x79, (byte) 0x31, (byte) 0x15,
+        (byte) 0x30, (byte) 0x13, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
+        (byte) 0x0a, (byte) 0x0c, (byte) 0x0c, (byte) 0x53, (byte) 0x6f, (byte) 0x6d,
+        (byte) 0x65, (byte) 0x2d, (byte) 0x43, (byte) 0x6f, (byte) 0x6d, (byte) 0x70,
+        (byte) 0x61, (byte) 0x6e, (byte) 0x79, (byte) 0x31, (byte) 0x10, (byte) 0x30,
+        (byte) 0x0e, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x0b,
+        (byte) 0x0c, (byte) 0x07, (byte) 0x53, (byte) 0x65, (byte) 0x63, (byte) 0x74,
+        (byte) 0x69, (byte) 0x6f, (byte) 0x6e, (byte) 0x31, (byte) 0x21, (byte) 0x30,
+        (byte) 0x1f, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x03,
+        (byte) 0x0c, (byte) 0x18, (byte) 0x57, (byte) 0x69, (byte) 0x66, (byte) 0x69,
+        (byte) 0x45, (byte) 0x6e, (byte) 0x74, (byte) 0x65, (byte) 0x72, (byte) 0x70,
+        (byte) 0x72, (byte) 0x69, (byte) 0x73, (byte) 0x65, (byte) 0x43, (byte) 0x6f,
+        (byte) 0x6e, (byte) 0x66, (byte) 0x69, (byte) 0x67, (byte) 0x54, (byte) 0x65,
+        (byte) 0x73, (byte) 0x74, (byte) 0x31, (byte) 0x29, (byte) 0x30, (byte) 0x27,
+        (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86,
+        (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x09, (byte) 0x01, (byte) 0x16,
+        (byte) 0x1a, (byte) 0x61, (byte) 0x6e, (byte) 0x2d, (byte) 0x65, (byte) 0x6d,
+        (byte) 0x61, (byte) 0x69, (byte) 0x6c, (byte) 0x2d, (byte) 0x61, (byte) 0x64,
+        (byte) 0x72, (byte) 0x65, (byte) 0x73, (byte) 0x73, (byte) 0x40, (byte) 0x64,
+        (byte) 0x6f, (byte) 0x6d, (byte) 0x61, (byte) 0x69, (byte) 0x6e, (byte) 0x2e,
+        (byte) 0x63, (byte) 0x6f, (byte) 0x6d, (byte) 0x30, (byte) 0x82, (byte) 0x01,
+        (byte) 0x22, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a,
+        (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01,
+        (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x03, (byte) 0x82,
+        (byte) 0x01, (byte) 0x0f, (byte) 0x00, (byte) 0x30, (byte) 0x82, (byte) 0x01,
+        (byte) 0x0a, (byte) 0x02, (byte) 0x82, (byte) 0x01, (byte) 0x01, (byte) 0x00,
+        (byte) 0xb4, (byte) 0x6e, (byte) 0x66, (byte) 0x24, (byte) 0xe7, (byte) 0x5c,
+        (byte) 0xd8, (byte) 0x6f, (byte) 0x08, (byte) 0xd3, (byte) 0x80, (byte) 0xa3,
+        (byte) 0xb9, (byte) 0xaf, (byte) 0x90, (byte) 0xef, (byte) 0x1c, (byte) 0x2a,
+        (byte) 0x5f, (byte) 0x39, (byte) 0x0b, (byte) 0xbd, (byte) 0x75, (byte) 0x0d,
+        (byte) 0x3e, (byte) 0x19, (byte) 0x2e, (byte) 0x47, (byte) 0x1e, (byte) 0x14,
+        (byte) 0xc2, (byte) 0x1a, (byte) 0x59, (byte) 0xcc, (byte) 0x1b, (byte) 0xb6,
+        (byte) 0x9b, (byte) 0x46, (byte) 0x1f, (byte) 0x7f, (byte) 0x71, (byte) 0xdd,
+        (byte) 0x38, (byte) 0xbe, (byte) 0x89, (byte) 0x30, (byte) 0xba, (byte) 0x88,
+        (byte) 0xfb, (byte) 0x3f, (byte) 0x57, (byte) 0x35, (byte) 0xe7, (byte) 0xa7,
+        (byte) 0x2f, (byte) 0x2c, (byte) 0x8d, (byte) 0x7c, (byte) 0xe2, (byte) 0xd8,
+        (byte) 0x0c, (byte) 0x0a, (byte) 0xe6, (byte) 0x62, (byte) 0x46, (byte) 0x8c,
+        (byte) 0xf4, (byte) 0x51, (byte) 0xfc, (byte) 0x6a, (byte) 0x79, (byte) 0xdd,
+        (byte) 0x0a, (byte) 0x41, (byte) 0x23, (byte) 0xd3, (byte) 0xe9, (byte) 0x5e,
+        (byte) 0x91, (byte) 0xcd, (byte) 0xbd, (byte) 0x55, (byte) 0x28, (byte) 0x71,
+        (byte) 0xec, (byte) 0x52, (byte) 0x19, (byte) 0x85, (byte) 0x0c, (byte) 0x1b,
+        (byte) 0xfa, (byte) 0xbf, (byte) 0xfe, (byte) 0xae, (byte) 0x5c, (byte) 0x3b,
+        (byte) 0x99, (byte) 0x42, (byte) 0xd4, (byte) 0xe7, (byte) 0x17, (byte) 0xec,
+        (byte) 0x41, (byte) 0x22, (byte) 0x2c, (byte) 0x1e, (byte) 0x7b, (byte) 0x53,
+        (byte) 0xad, (byte) 0x02, (byte) 0xfd, (byte) 0xf6, (byte) 0x4a, (byte) 0xb1,
+        (byte) 0x6e, (byte) 0x6c, (byte) 0x87, (byte) 0xf5, (byte) 0x7d, (byte) 0x9b,
+        (byte) 0x34, (byte) 0x0e, (byte) 0x3b, (byte) 0x0e, (byte) 0xaa, (byte) 0xc5,
+        (byte) 0xc4, (byte) 0xef, (byte) 0xf2, (byte) 0x5a, (byte) 0xa9, (byte) 0xac,
+        (byte) 0x19, (byte) 0xce, (byte) 0x5f, (byte) 0xc5, (byte) 0xcc, (byte) 0x0d,
+        (byte) 0xee, (byte) 0x7f, (byte) 0x32, (byte) 0xb4, (byte) 0xfe, (byte) 0xc1,
+        (byte) 0xca, (byte) 0x9b, (byte) 0x3f, (byte) 0xad, (byte) 0x2c, (byte) 0x7a,
+        (byte) 0xc5, (byte) 0x8d, (byte) 0x48, (byte) 0xa1, (byte) 0xc9, (byte) 0x74,
+        (byte) 0xfe, (byte) 0x8a, (byte) 0xe3, (byte) 0xb0, (byte) 0x92, (byte) 0xee,
+        (byte) 0x73, (byte) 0x09, (byte) 0x0a, (byte) 0xbc, (byte) 0xc8, (byte) 0x63,
+        (byte) 0xba, (byte) 0x0e, (byte) 0x26, (byte) 0xab, (byte) 0x1e, (byte) 0xff,
+        (byte) 0xbc, (byte) 0x24, (byte) 0x12, (byte) 0x26, (byte) 0x11, (byte) 0xe0,
+        (byte) 0x04, (byte) 0xcb, (byte) 0x96, (byte) 0x7d, (byte) 0x41, (byte) 0xf7,
+        (byte) 0x79, (byte) 0x32, (byte) 0x05, (byte) 0x33, (byte) 0x19, (byte) 0x6e,
+        (byte) 0xb9, (byte) 0x75, (byte) 0xf3, (byte) 0x50, (byte) 0xa4, (byte) 0xc3,
+        (byte) 0x55, (byte) 0x9d, (byte) 0x8f, (byte) 0xb6, (byte) 0xab, (byte) 0x97,
+        (byte) 0xe7, (byte) 0xe2, (byte) 0xe8, (byte) 0x15, (byte) 0xfc, (byte) 0x35,
+        (byte) 0xbd, (byte) 0xce, (byte) 0x17, (byte) 0xbe, (byte) 0xe3, (byte) 0x73,
+        (byte) 0xd4, (byte) 0x88, (byte) 0x39, (byte) 0x27, (byte) 0x7e, (byte) 0x6d,
+        (byte) 0xa2, (byte) 0x27, (byte) 0xfa, (byte) 0x96, (byte) 0xe3, (byte) 0x38,
+        (byte) 0xc0, (byte) 0xa1, (byte) 0x55, (byte) 0xc6, (byte) 0xf3, (byte) 0x20,
+        (byte) 0xea, (byte) 0x50, (byte) 0x8d, (byte) 0x6c, (byte) 0x94, (byte) 0x9a,
+        (byte) 0x43, (byte) 0x74, (byte) 0xc0, (byte) 0xfa, (byte) 0xef, (byte) 0xe0,
+        (byte) 0xb1, (byte) 0x1c, (byte) 0x6d, (byte) 0x5e, (byte) 0x44, (byte) 0x08,
+        (byte) 0xef, (byte) 0xd5, (byte) 0x80, (byte) 0xad, (byte) 0x02, (byte) 0x03,
+        (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0xa3, (byte) 0x50, (byte) 0x30,
+        (byte) 0x4e, (byte) 0x30, (byte) 0x1d, (byte) 0x06, (byte) 0x03, (byte) 0x55,
+        (byte) 0x1d, (byte) 0x0e, (byte) 0x04, (byte) 0x16, (byte) 0x04, (byte) 0x14,
+        (byte) 0xe9, (byte) 0xd0, (byte) 0x9e, (byte) 0x0e, (byte) 0x62, (byte) 0x31,
+        (byte) 0x02, (byte) 0x9a, (byte) 0x33, (byte) 0xd7, (byte) 0x4a, (byte) 0x93,
+        (byte) 0x0d, (byte) 0xf3, (byte) 0xd6, (byte) 0x74, (byte) 0xce, (byte) 0x69,
+        (byte) 0xe1, (byte) 0xef, (byte) 0x30, (byte) 0x1f, (byte) 0x06, (byte) 0x03,
+        (byte) 0x55, (byte) 0x1d, (byte) 0x23, (byte) 0x04, (byte) 0x18, (byte) 0x30,
+        (byte) 0x16, (byte) 0x80, (byte) 0x14, (byte) 0xe9, (byte) 0xd0, (byte) 0x9e,
+        (byte) 0x0e, (byte) 0x62, (byte) 0x31, (byte) 0x02, (byte) 0x9a, (byte) 0x33,
+        (byte) 0xd7, (byte) 0x4a, (byte) 0x93, (byte) 0x0d, (byte) 0xf3, (byte) 0xd6,
+        (byte) 0x74, (byte) 0xce, (byte) 0x69, (byte) 0xe1, (byte) 0xef, (byte) 0x30,
+        (byte) 0x0c, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x13,
+        (byte) 0x04, (byte) 0x05, (byte) 0x30, (byte) 0x03, (byte) 0x01, (byte) 0x01,
+        (byte) 0xff, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a,
+        (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01,
+        (byte) 0x01, (byte) 0x0b, (byte) 0x05, (byte) 0x00, (byte) 0x03, (byte) 0x82,
+        (byte) 0x01, (byte) 0x01, (byte) 0x00, (byte) 0x52, (byte) 0x70, (byte) 0xb6,
+        (byte) 0x10, (byte) 0x7f, (byte) 0xaa, (byte) 0x86, (byte) 0x8f, (byte) 0x02,
+        (byte) 0xb0, (byte) 0x97, (byte) 0x89, (byte) 0xb9, (byte) 0x04, (byte) 0x1d,
+        (byte) 0x79, (byte) 0xa3, (byte) 0x74, (byte) 0x7c, (byte) 0xdf, (byte) 0xad,
+        (byte) 0x87, (byte) 0xe4, (byte) 0x00, (byte) 0xd3, (byte) 0x3a, (byte) 0x5c,
+        (byte) 0x48, (byte) 0x3b, (byte) 0xfe, (byte) 0x77, (byte) 0xfd, (byte) 0xbe,
+        (byte) 0xce, (byte) 0x5b, (byte) 0xd2, (byte) 0xea, (byte) 0x3e, (byte) 0x7f,
+        (byte) 0xef, (byte) 0x20, (byte) 0x0d, (byte) 0x0b, (byte) 0xc7, (byte) 0xc4,
+        (byte) 0x25, (byte) 0x20, (byte) 0xe1, (byte) 0x8f, (byte) 0xc5, (byte) 0x19,
+        (byte) 0x37, (byte) 0x9c, (byte) 0xa0, (byte) 0x9d, (byte) 0x02, (byte) 0x30,
+        (byte) 0x5f, (byte) 0x49, (byte) 0x4e, (byte) 0x56, (byte) 0xc4, (byte) 0xab,
+        (byte) 0xcb, (byte) 0x5c, (byte) 0xe6, (byte) 0x40, (byte) 0x93, (byte) 0x92,
+        (byte) 0xee, (byte) 0xa1, (byte) 0x69, (byte) 0x7d, (byte) 0x10, (byte) 0x6b,
+        (byte) 0xd4, (byte) 0xf7, (byte) 0xec, (byte) 0xd9, (byte) 0xa5, (byte) 0x29,
+        (byte) 0x63, (byte) 0x29, (byte) 0xd9, (byte) 0x27, (byte) 0x2d, (byte) 0x5e,
+        (byte) 0x34, (byte) 0x37, (byte) 0xa9, (byte) 0xba, (byte) 0x0a, (byte) 0x7b,
+        (byte) 0x99, (byte) 0x1a, (byte) 0x7d, (byte) 0xa7, (byte) 0xa7, (byte) 0xf0,
+        (byte) 0xbf, (byte) 0x40, (byte) 0x29, (byte) 0x5d, (byte) 0x2f, (byte) 0x2e,
+        (byte) 0x0f, (byte) 0x35, (byte) 0x90, (byte) 0xb5, (byte) 0xc3, (byte) 0xfd,
+        (byte) 0x1e, (byte) 0xe2, (byte) 0xb3, (byte) 0xae, (byte) 0xf9, (byte) 0xde,
+        (byte) 0x9d, (byte) 0x76, (byte) 0xe1, (byte) 0x20, (byte) 0xf5, (byte) 0x1c,
+        (byte) 0x30, (byte) 0x42, (byte) 0x80, (byte) 0x2a, (byte) 0x4f, (byte) 0x85,
+        (byte) 0x5c, (byte) 0xb4, (byte) 0x49, (byte) 0x68, (byte) 0x6c, (byte) 0x7c,
+        (byte) 0x2a, (byte) 0xc8, (byte) 0xbc, (byte) 0x15, (byte) 0xed, (byte) 0x88,
+        (byte) 0xfd, (byte) 0x8a, (byte) 0x63, (byte) 0xe0, (byte) 0x93, (byte) 0xfd,
+        (byte) 0x86, (byte) 0xab, (byte) 0xa9, (byte) 0xf6, (byte) 0x63, (byte) 0xa5,
+        (byte) 0x29, (byte) 0xaf, (byte) 0xdc, (byte) 0x8f, (byte) 0xca, (byte) 0xc2,
+        (byte) 0x28, (byte) 0xe7, (byte) 0x26, (byte) 0x89, (byte) 0x75, (byte) 0xf1,
+        (byte) 0x3e, (byte) 0x2e, (byte) 0x86, (byte) 0x11, (byte) 0x8b, (byte) 0xfa,
+        (byte) 0xf5, (byte) 0xb4, (byte) 0xb4, (byte) 0x04, (byte) 0x02, (byte) 0xa3,
+        (byte) 0x85, (byte) 0x81, (byte) 0xad, (byte) 0xb3, (byte) 0xec, (byte) 0x2d,
+        (byte) 0x4b, (byte) 0x40, (byte) 0x59, (byte) 0x61, (byte) 0x0d, (byte) 0x59,
+        (byte) 0x09, (byte) 0x09, (byte) 0xee, (byte) 0xc7, (byte) 0x51, (byte) 0xef,
+        (byte) 0x6f, (byte) 0xd6, (byte) 0x9a, (byte) 0xa5, (byte) 0x45, (byte) 0xa2,
+        (byte) 0x89, (byte) 0xc2, (byte) 0x97, (byte) 0x93, (byte) 0xbc, (byte) 0x5b,
+        (byte) 0x37, (byte) 0x55, (byte) 0x73, (byte) 0x55, (byte) 0x0c, (byte) 0x9c,
+        (byte) 0xcb, (byte) 0x10, (byte) 0xec, (byte) 0x76, (byte) 0xfe, (byte) 0xa7,
+        (byte) 0x70, (byte) 0x4e, (byte) 0x9a, (byte) 0xa2, (byte) 0xf9, (byte) 0x40,
+        (byte) 0xdd, (byte) 0x96, (byte) 0x7d, (byte) 0x67, (byte) 0x5c, (byte) 0x8e,
+        (byte) 0x43, (byte) 0x1a, (byte) 0x26, (byte) 0xaa, (byte) 0xee, (byte) 0x38,
+        (byte) 0x11, (byte) 0x26, (byte) 0x3d, (byte) 0x69, (byte) 0xc7, (byte) 0x6a,
+        (byte) 0xe7, (byte) 0xbd, (byte) 0x67, (byte) 0x70, (byte) 0x35, (byte) 0xff,
+        (byte) 0x72, (byte) 0x2c, (byte) 0x87, (byte) 0x82, (byte) 0x68, (byte) 0x3f,
+        (byte) 0x8d
+    };
+
+    private static final byte[] FAKE_EC_2 = {
+        (byte) 0x30, (byte) 0x82, (byte) 0x04, (byte) 0x4f, (byte) 0x30, (byte) 0x82,
+        (byte) 0x03, (byte) 0x37, (byte) 0xa0, (byte) 0x03, (byte) 0x02, (byte) 0x01,
+        (byte) 0x02, (byte) 0x02, (byte) 0x09, (byte) 0x00, (byte) 0xd9, (byte) 0xc4,
+        (byte) 0xe1, (byte) 0xfc, (byte) 0x3d, (byte) 0x02, (byte) 0x21, (byte) 0x1f,
+        (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86,
+        (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01,
+        (byte) 0x0b, (byte) 0x05, (byte) 0x00, (byte) 0x30, (byte) 0x81, (byte) 0xbd,
+        (byte) 0x31, (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03,
+        (byte) 0x55, (byte) 0x04, (byte) 0x06, (byte) 0x13, (byte) 0x02, (byte) 0x41,
+        (byte) 0x55, (byte) 0x31, (byte) 0x13, (byte) 0x30, (byte) 0x11, (byte) 0x06,
+        (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x08, (byte) 0x0c, (byte) 0x0a,
+        (byte) 0x53, (byte) 0x6f, (byte) 0x6d, (byte) 0x65, (byte) 0x2d, (byte) 0x53,
+        (byte) 0x74, (byte) 0x61, (byte) 0x74, (byte) 0x65, (byte) 0x31, (byte) 0x12,
+        (byte) 0x30, (byte) 0x10, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
+        (byte) 0x07, (byte) 0x0c, (byte) 0x09, (byte) 0x53, (byte) 0x6f, (byte) 0x6d,
+        (byte) 0x65, (byte) 0x2d, (byte) 0x43, (byte) 0x69, (byte) 0x74, (byte) 0x79,
+        (byte) 0x31, (byte) 0x1b, (byte) 0x30, (byte) 0x19, (byte) 0x06, (byte) 0x03,
+        (byte) 0x55, (byte) 0x04, (byte) 0x0a, (byte) 0x0c, (byte) 0x12, (byte) 0x53,
+        (byte) 0x6f, (byte) 0x6d, (byte) 0x65, (byte) 0x2d, (byte) 0x4f, (byte) 0x74,
+        (byte) 0x68, (byte) 0x65, (byte) 0x72, (byte) 0x2d, (byte) 0x43, (byte) 0x6f,
+        (byte) 0x6d, (byte) 0x70, (byte) 0x61, (byte) 0x6e, (byte) 0x79, (byte) 0x31,
+        (byte) 0x15, (byte) 0x30, (byte) 0x13, (byte) 0x06, (byte) 0x03, (byte) 0x55,
+        (byte) 0x04, (byte) 0x0b, (byte) 0x0c, (byte) 0x0c, (byte) 0x53, (byte) 0x6f,
+        (byte) 0x6d, (byte) 0x65, (byte) 0x2d, (byte) 0x53, (byte) 0x65, (byte) 0x63,
+        (byte) 0x74, (byte) 0x69, (byte) 0x6f, (byte) 0x6e, (byte) 0x31, (byte) 0x21,
+        (byte) 0x30, (byte) 0x1f, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
+        (byte) 0x03, (byte) 0x0c, (byte) 0x18, (byte) 0x57, (byte) 0x69, (byte) 0x66,
+        (byte) 0x69, (byte) 0x45, (byte) 0x6e, (byte) 0x74, (byte) 0x65, (byte) 0x72,
+        (byte) 0x70, (byte) 0x72, (byte) 0x69, (byte) 0x73, (byte) 0x65, (byte) 0x43,
+        (byte) 0x6f, (byte) 0x6e, (byte) 0x66, (byte) 0x69, (byte) 0x67, (byte) 0x54,
+        (byte) 0x65, (byte) 0x73, (byte) 0x74, (byte) 0x31, (byte) 0x2e, (byte) 0x30,
+        (byte) 0x2c, (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86, (byte) 0x48,
+        (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x09, (byte) 0x01,
+        (byte) 0x16, (byte) 0x1f, (byte) 0x61, (byte) 0x6e, (byte) 0x2d, (byte) 0x65,
+        (byte) 0x6d, (byte) 0x61, (byte) 0x69, (byte) 0x6c, (byte) 0x2d, (byte) 0x61,
+        (byte) 0x64, (byte) 0x72, (byte) 0x65, (byte) 0x73, (byte) 0x73, (byte) 0x40,
+        (byte) 0x73, (byte) 0x6f, (byte) 0x6d, (byte) 0x65, (byte) 0x2d, (byte) 0x64,
+        (byte) 0x6f, (byte) 0x6d, (byte) 0x61, (byte) 0x69, (byte) 0x6e, (byte) 0x2e,
+        (byte) 0x63, (byte) 0x6f, (byte) 0x6d, (byte) 0x30, (byte) 0x1e, (byte) 0x17,
+        (byte) 0x0d, (byte) 0x31, (byte) 0x36, (byte) 0x30, (byte) 0x31, (byte) 0x31,
+        (byte) 0x35, (byte) 0x31, (byte) 0x31, (byte) 0x33, (byte) 0x32, (byte) 0x34,
+        (byte) 0x36, (byte) 0x5a, (byte) 0x17, (byte) 0x0d, (byte) 0x32, (byte) 0x36,
+        (byte) 0x30, (byte) 0x31, (byte) 0x31, (byte) 0x32, (byte) 0x31, (byte) 0x31,
+        (byte) 0x33, (byte) 0x32, (byte) 0x34, (byte) 0x36, (byte) 0x5a, (byte) 0x30,
+        (byte) 0x81, (byte) 0xbd, (byte) 0x31, (byte) 0x0b, (byte) 0x30, (byte) 0x09,
+        (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x06, (byte) 0x13,
+        (byte) 0x02, (byte) 0x41, (byte) 0x55, (byte) 0x31, (byte) 0x13, (byte) 0x30,
+        (byte) 0x11, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x08,
+        (byte) 0x0c, (byte) 0x0a, (byte) 0x53, (byte) 0x6f, (byte) 0x6d, (byte) 0x65,
+        (byte) 0x2d, (byte) 0x53, (byte) 0x74, (byte) 0x61, (byte) 0x74, (byte) 0x65,
+        (byte) 0x31, (byte) 0x12, (byte) 0x30, (byte) 0x10, (byte) 0x06, (byte) 0x03,
+        (byte) 0x55, (byte) 0x04, (byte) 0x07, (byte) 0x0c, (byte) 0x09, (byte) 0x53,
+        (byte) 0x6f, (byte) 0x6d, (byte) 0x65, (byte) 0x2d, (byte) 0x43, (byte) 0x69,
+        (byte) 0x74, (byte) 0x79, (byte) 0x31, (byte) 0x1b, (byte) 0x30, (byte) 0x19,
+        (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x0a, (byte) 0x0c,
+        (byte) 0x12, (byte) 0x53, (byte) 0x6f, (byte) 0x6d, (byte) 0x65, (byte) 0x2d,
+        (byte) 0x4f, (byte) 0x74, (byte) 0x68, (byte) 0x65, (byte) 0x72, (byte) 0x2d,
+        (byte) 0x43, (byte) 0x6f, (byte) 0x6d, (byte) 0x70, (byte) 0x61, (byte) 0x6e,
+        (byte) 0x79, (byte) 0x31, (byte) 0x15, (byte) 0x30, (byte) 0x13, (byte) 0x06,
+        (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x0b, (byte) 0x0c, (byte) 0x0c,
+        (byte) 0x53, (byte) 0x6f, (byte) 0x6d, (byte) 0x65, (byte) 0x2d, (byte) 0x53,
+        (byte) 0x65, (byte) 0x63, (byte) 0x74, (byte) 0x69, (byte) 0x6f, (byte) 0x6e,
+        (byte) 0x31, (byte) 0x21, (byte) 0x30, (byte) 0x1f, (byte) 0x06, (byte) 0x03,
+        (byte) 0x55, (byte) 0x04, (byte) 0x03, (byte) 0x0c, (byte) 0x18, (byte) 0x57,
+        (byte) 0x69, (byte) 0x66, (byte) 0x69, (byte) 0x45, (byte) 0x6e, (byte) 0x74,
+        (byte) 0x65, (byte) 0x72, (byte) 0x70, (byte) 0x72, (byte) 0x69, (byte) 0x73,
+        (byte) 0x65, (byte) 0x43, (byte) 0x6f, (byte) 0x6e, (byte) 0x66, (byte) 0x69,
+        (byte) 0x67, (byte) 0x54, (byte) 0x65, (byte) 0x73, (byte) 0x74, (byte) 0x31,
+        (byte) 0x2e, (byte) 0x30, (byte) 0x2c, (byte) 0x06, (byte) 0x09, (byte) 0x2a,
+        (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01,
+        (byte) 0x09, (byte) 0x01, (byte) 0x16, (byte) 0x1f, (byte) 0x61, (byte) 0x6e,
+        (byte) 0x2d, (byte) 0x65, (byte) 0x6d, (byte) 0x61, (byte) 0x69, (byte) 0x6c,
+        (byte) 0x2d, (byte) 0x61, (byte) 0x64, (byte) 0x72, (byte) 0x65, (byte) 0x73,
+        (byte) 0x73, (byte) 0x40, (byte) 0x73, (byte) 0x6f, (byte) 0x6d, (byte) 0x65,
+        (byte) 0x2d, (byte) 0x64, (byte) 0x6f, (byte) 0x6d, (byte) 0x61, (byte) 0x69,
+        (byte) 0x6e, (byte) 0x2e, (byte) 0x63, (byte) 0x6f, (byte) 0x6d, (byte) 0x30,
+        (byte) 0x82, (byte) 0x01, (byte) 0x22, (byte) 0x30, (byte) 0x0d, (byte) 0x06,
+        (byte) 0x09, (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7,
+        (byte) 0x0d, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x00,
+        (byte) 0x03, (byte) 0x82, (byte) 0x01, (byte) 0x0f, (byte) 0x00, (byte) 0x30,
+        (byte) 0x82, (byte) 0x01, (byte) 0x0a, (byte) 0x02, (byte) 0x82, (byte) 0x01,
+        (byte) 0x01, (byte) 0x00, (byte) 0xa9, (byte) 0xa3, (byte) 0x21, (byte) 0xfd,
+        (byte) 0xa6, (byte) 0xc1, (byte) 0x04, (byte) 0x48, (byte) 0xc2, (byte) 0xc8,
+        (byte) 0x44, (byte) 0x50, (byte) 0xc4, (byte) 0x6d, (byte) 0x35, (byte) 0x24,
+        (byte) 0xf0, (byte) 0x6d, (byte) 0x69, (byte) 0xfb, (byte) 0xd1, (byte) 0xfc,
+        (byte) 0xde, (byte) 0xe9, (byte) 0xdb, (byte) 0xca, (byte) 0xee, (byte) 0x24,
+        (byte) 0x3d, (byte) 0x85, (byte) 0x8d, (byte) 0x84, (byte) 0xb4, (byte) 0x73,
+        (byte) 0xd1, (byte) 0x09, (byte) 0x37, (byte) 0x16, (byte) 0x80, (byte) 0x70,
+        (byte) 0x6b, (byte) 0x61, (byte) 0xcc, (byte) 0xf2, (byte) 0x98, (byte) 0xbd,
+        (byte) 0x53, (byte) 0x3a, (byte) 0x68, (byte) 0x60, (byte) 0x02, (byte) 0xba,
+        (byte) 0x0c, (byte) 0x53, (byte) 0x96, (byte) 0xfb, (byte) 0x80, (byte) 0xd1,
+        (byte) 0x5b, (byte) 0xc3, (byte) 0xcb, (byte) 0x7a, (byte) 0x81, (byte) 0x00,
+        (byte) 0x5d, (byte) 0x20, (byte) 0x72, (byte) 0xc0, (byte) 0xe4, (byte) 0x48,
+        (byte) 0x0e, (byte) 0xa2, (byte) 0xcd, (byte) 0xa2, (byte) 0x63, (byte) 0x8c,
+        (byte) 0x05, (byte) 0x7c, (byte) 0x63, (byte) 0x5b, (byte) 0xda, (byte) 0x0e,
+        (byte) 0xa7, (byte) 0x05, (byte) 0x09, (byte) 0x6d, (byte) 0xd5, (byte) 0xe4,
+        (byte) 0x3a, (byte) 0x4e, (byte) 0xa1, (byte) 0xf5, (byte) 0xfd, (byte) 0x47,
+        (byte) 0xee, (byte) 0x7b, (byte) 0xa3, (byte) 0x4c, (byte) 0x8c, (byte) 0xd3,
+        (byte) 0xbb, (byte) 0x58, (byte) 0x0f, (byte) 0x1c, (byte) 0x56, (byte) 0x80,
+        (byte) 0x80, (byte) 0xb5, (byte) 0xf9, (byte) 0x80, (byte) 0xc2, (byte) 0xd1,
+        (byte) 0x1d, (byte) 0x3f, (byte) 0xe8, (byte) 0x2a, (byte) 0x63, (byte) 0x0b,
+        (byte) 0x54, (byte) 0x5f, (byte) 0xd4, (byte) 0xcb, (byte) 0xb7, (byte) 0x94,
+        (byte) 0xe2, (byte) 0x35, (byte) 0x65, (byte) 0x59, (byte) 0xd1, (byte) 0x72,
+        (byte) 0xa4, (byte) 0xb8, (byte) 0xee, (byte) 0x82, (byte) 0x11, (byte) 0x7a,
+        (byte) 0x4c, (byte) 0x26, (byte) 0x66, (byte) 0x9b, (byte) 0x27, (byte) 0x3d,
+        (byte) 0x14, (byte) 0x4b, (byte) 0x4b, (byte) 0xc8, (byte) 0xf0, (byte) 0x6e,
+        (byte) 0x43, (byte) 0x8f, (byte) 0xee, (byte) 0x1f, (byte) 0xeb, (byte) 0x20,
+        (byte) 0xe2, (byte) 0x4c, (byte) 0x79, (byte) 0xbf, (byte) 0x21, (byte) 0x0d,
+        (byte) 0x36, (byte) 0xed, (byte) 0x5f, (byte) 0xcc, (byte) 0x70, (byte) 0x68,
+        (byte) 0x8a, (byte) 0x05, (byte) 0x7c, (byte) 0x2f, (byte) 0x1b, (byte) 0xe9,
+        (byte) 0xec, (byte) 0x83, (byte) 0x6e, (byte) 0x9a, (byte) 0x78, (byte) 0x31,
+        (byte) 0x3d, (byte) 0xf4, (byte) 0xde, (byte) 0x1b, (byte) 0xd2, (byte) 0x76,
+        (byte) 0x32, (byte) 0x6c, (byte) 0x1e, (byte) 0xc9, (byte) 0x90, (byte) 0x7f,
+        (byte) 0xc4, (byte) 0x30, (byte) 0xc0, (byte) 0xae, (byte) 0xab, (byte) 0x70,
+        (byte) 0x08, (byte) 0x78, (byte) 0xbf, (byte) 0x2e, (byte) 0x8b, (byte) 0x07,
+        (byte) 0xab, (byte) 0x8f, (byte) 0x03, (byte) 0xc5, (byte) 0xd3, (byte) 0xeb,
+        (byte) 0x98, (byte) 0x19, (byte) 0x50, (byte) 0x83, (byte) 0x52, (byte) 0xf7,
+        (byte) 0xff, (byte) 0xf5, (byte) 0x89, (byte) 0xe6, (byte) 0xe7, (byte) 0xa7,
+        (byte) 0xcb, (byte) 0xdf, (byte) 0x96, (byte) 0x9d, (byte) 0x14, (byte) 0x04,
+        (byte) 0x5e, (byte) 0x45, (byte) 0x82, (byte) 0xf7, (byte) 0x23, (byte) 0x1a,
+        (byte) 0xb6, (byte) 0x64, (byte) 0x57, (byte) 0xe8, (byte) 0x7e, (byte) 0xa1,
+        (byte) 0xaf, (byte) 0x58, (byte) 0x68, (byte) 0x70, (byte) 0xc5, (byte) 0x0f,
+        (byte) 0x8d, (byte) 0x54, (byte) 0xf3, (byte) 0x49, (byte) 0xa3, (byte) 0x97,
+        (byte) 0x32, (byte) 0xa7, (byte) 0x2a, (byte) 0x79, (byte) 0xbe, (byte) 0xcd,
+        (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0xa3,
+        (byte) 0x50, (byte) 0x30, (byte) 0x4e, (byte) 0x30, (byte) 0x1d, (byte) 0x06,
+        (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x0e, (byte) 0x04, (byte) 0x16,
+        (byte) 0x04, (byte) 0x14, (byte) 0xac, (byte) 0xf3, (byte) 0x73, (byte) 0x9a,
+        (byte) 0x25, (byte) 0x08, (byte) 0x01, (byte) 0x07, (byte) 0x86, (byte) 0x8b,
+        (byte) 0xc4, (byte) 0xed, (byte) 0xb1, (byte) 0x6b, (byte) 0x53, (byte) 0xa3,
+        (byte) 0x21, (byte) 0xb4, (byte) 0xb4, (byte) 0x46, (byte) 0x30, (byte) 0x1f,
+        (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x23, (byte) 0x04,
+        (byte) 0x18, (byte) 0x30, (byte) 0x16, (byte) 0x80, (byte) 0x14, (byte) 0xac,
+        (byte) 0xf3, (byte) 0x73, (byte) 0x9a, (byte) 0x25, (byte) 0x08, (byte) 0x01,
+        (byte) 0x07, (byte) 0x86, (byte) 0x8b, (byte) 0xc4, (byte) 0xed, (byte) 0xb1,
+        (byte) 0x6b, (byte) 0x53, (byte) 0xa3, (byte) 0x21, (byte) 0xb4, (byte) 0xb4,
+        (byte) 0x46, (byte) 0x30, (byte) 0x0c, (byte) 0x06, (byte) 0x03, (byte) 0x55,
+        (byte) 0x1d, (byte) 0x13, (byte) 0x04, (byte) 0x05, (byte) 0x30, (byte) 0x03,
+        (byte) 0x01, (byte) 0x01, (byte) 0xff, (byte) 0x30, (byte) 0x0d, (byte) 0x06,
+        (byte) 0x09, (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7,
+        (byte) 0x0d, (byte) 0x01, (byte) 0x01, (byte) 0x0b, (byte) 0x05, (byte) 0x00,
+        (byte) 0x03, (byte) 0x82, (byte) 0x01, (byte) 0x01, (byte) 0x00, (byte) 0x16,
+        (byte) 0xf6, (byte) 0xd0, (byte) 0xe1, (byte) 0x14, (byte) 0x2d, (byte) 0x52,
+        (byte) 0x47, (byte) 0xa2, (byte) 0x89, (byte) 0xe6, (byte) 0x7f, (byte) 0xac,
+        (byte) 0x88, (byte) 0x04, (byte) 0x15, (byte) 0x21, (byte) 0x00, (byte) 0x72,
+        (byte) 0xf9, (byte) 0xee, (byte) 0xb2, (byte) 0x1b, (byte) 0x8e, (byte) 0x46,
+        (byte) 0x8b, (byte) 0x90, (byte) 0x20, (byte) 0x4f, (byte) 0xa7, (byte) 0xae,
+        (byte) 0x30, (byte) 0xb6, (byte) 0x24, (byte) 0xc5, (byte) 0x54, (byte) 0xaf,
+        (byte) 0x6c, (byte) 0x1e, (byte) 0xd6, (byte) 0x73, (byte) 0x22, (byte) 0x48,
+        (byte) 0x07, (byte) 0xb5, (byte) 0x13, (byte) 0x35, (byte) 0xbb, (byte) 0x9e,
+        (byte) 0xd9, (byte) 0x19, (byte) 0x79, (byte) 0xda, (byte) 0x76, (byte) 0x7f,
+        (byte) 0xf7, (byte) 0x87, (byte) 0xc9, (byte) 0xc3, (byte) 0x0b, (byte) 0x38,
+        (byte) 0x20, (byte) 0x26, (byte) 0xfc, (byte) 0x7f, (byte) 0x32, (byte) 0x2a,
+        (byte) 0xd5, (byte) 0x09, (byte) 0x87, (byte) 0xda, (byte) 0x23, (byte) 0x1f,
+        (byte) 0x71, (byte) 0x83, (byte) 0x00, (byte) 0x17, (byte) 0xf6, (byte) 0xb9,
+        (byte) 0x57, (byte) 0x21, (byte) 0xdf, (byte) 0x29, (byte) 0xcc, (byte) 0xdb,
+        (byte) 0xe9, (byte) 0x2c, (byte) 0xba, (byte) 0x86, (byte) 0x34, (byte) 0x53,
+        (byte) 0x29, (byte) 0x09, (byte) 0xc7, (byte) 0x3c, (byte) 0x8e, (byte) 0xa3,
+        (byte) 0x86, (byte) 0x81, (byte) 0x26, (byte) 0x7b, (byte) 0xa1, (byte) 0xbe,
+        (byte) 0xbc, (byte) 0xc9, (byte) 0x83, (byte) 0xb5, (byte) 0x36, (byte) 0x65,
+        (byte) 0x51, (byte) 0xb4, (byte) 0x41, (byte) 0xf0, (byte) 0x05, (byte) 0x78,
+        (byte) 0x3a, (byte) 0xa6, (byte) 0xad, (byte) 0x4b, (byte) 0x08, (byte) 0xd1,
+        (byte) 0xe4, (byte) 0xf1, (byte) 0x2e, (byte) 0xc7, (byte) 0x23, (byte) 0x6d,
+        (byte) 0xf0, (byte) 0x9d, (byte) 0x60, (byte) 0x6d, (byte) 0xe7, (byte) 0x11,
+        (byte) 0xaf, (byte) 0x41, (byte) 0x68, (byte) 0xee, (byte) 0x06, (byte) 0x76,
+        (byte) 0x82, (byte) 0x48, (byte) 0xee, (byte) 0x41, (byte) 0xc4, (byte) 0xf8,
+        (byte) 0xe1, (byte) 0x83, (byte) 0xbc, (byte) 0xa8, (byte) 0xbd, (byte) 0x9c,
+        (byte) 0x17, (byte) 0x45, (byte) 0xf4, (byte) 0x36, (byte) 0x67, (byte) 0x47,
+        (byte) 0x0e, (byte) 0x32, (byte) 0x13, (byte) 0x6e, (byte) 0xc1, (byte) 0x1e,
+        (byte) 0x08, (byte) 0xef, (byte) 0x10, (byte) 0xdf, (byte) 0x45, (byte) 0xbf,
+        (byte) 0x5a, (byte) 0xc4, (byte) 0x44, (byte) 0x4c, (byte) 0xd0, (byte) 0xd5,
+        (byte) 0x23, (byte) 0xde, (byte) 0xd7, (byte) 0x83, (byte) 0x1e, (byte) 0xb0,
+        (byte) 0x27, (byte) 0x4d, (byte) 0x57, (byte) 0xa3, (byte) 0xe8, (byte) 0x36,
+        (byte) 0x52, (byte) 0x1c, (byte) 0x48, (byte) 0x0a, (byte) 0xc4, (byte) 0xd8,
+        (byte) 0x32, (byte) 0xfc, (byte) 0xd0, (byte) 0x26, (byte) 0x6f, (byte) 0xa4,
+        (byte) 0x61, (byte) 0x2c, (byte) 0x3a, (byte) 0xa9, (byte) 0xfe, (byte) 0xa4,
+        (byte) 0x7a, (byte) 0x58, (byte) 0x54, (byte) 0x58, (byte) 0x96, (byte) 0x2b,
+        (byte) 0x6e, (byte) 0x9c, (byte) 0xc9, (byte) 0x00, (byte) 0xda, (byte) 0xc6,
+        (byte) 0xbb, (byte) 0x97, (byte) 0xc4, (byte) 0x95, (byte) 0x32, (byte) 0x6b,
+        (byte) 0x03, (byte) 0x6f, (byte) 0x33, (byte) 0x59, (byte) 0xd4, (byte) 0xa4,
+        (byte) 0x4a, (byte) 0x29, (byte) 0x29, (byte) 0x9a, (byte) 0xf4, (byte) 0x87,
+        (byte) 0x26, (byte) 0xe6, (byte) 0xee, (byte) 0x5c, (byte) 0x0b, (byte) 0xe9,
+        (byte) 0x98, (byte) 0x5d, (byte) 0xab, (byte) 0x31, (byte) 0xa1, (byte) 0x63,
+        (byte) 0xaa, (byte) 0x1a, (byte) 0xea, (byte) 0x61, (byte) 0x27, (byte) 0x5e,
+        (byte) 0x9e, (byte) 0x34, (byte) 0x73
+    };
+
+
     private boolean hasWifi() {
         return getContext().getPackageManager().hasSystemFeature(
                 PackageManager.FEATURE_WIFI);
@@ -57,7 +451,7 @@
         }
     }
 
-    public void testSettersAndGetters() {
+    public void testSettersAndGetters() throws Exception {
         if (!hasWifi()) {
             return;
         }
@@ -87,7 +481,17 @@
         assertTrue(config.getAnonymousIdentity().equals(ANON_IDENTITY));
         config.setPassword(PASSWORD);
         assertTrue(config.getPassword().equals(PASSWORD));
-        config.setCaCertificate(null);
+        CertificateFactory factory = CertificateFactory.getInstance("X.509");
+        X509Certificate cert1 = (X509Certificate) factory.generateCertificate(
+                new ByteArrayInputStream(FAKE_EC_1));
+        X509Certificate cert2 = (X509Certificate) factory.generateCertificate(
+                new ByteArrayInputStream(FAKE_EC_2));
+        config.setCaCertificate(cert1);
+        assertTrue(config.getCaCertificate().getSerialNumber().equals(cert1.getSerialNumber()));
+        config.setCaCertificates(new X509Certificate[]{cert1, cert2});
+        X509Certificate[] certs = config.getCaCertificates();
+        assertTrue(cert1.getSerialNumber().equals(certs[0].getSerialNumber()));
+        assertTrue(cert2.getSerialNumber().equals(certs[1].getSerialNumber()));
         config.setClientKeyEntry(null, null);
         config.setSubjectMatch(SUBJECT_MATCH);
         assertTrue(config.getSubjectMatch().equals(SUBJECT_MATCH));
diff --git a/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java
index 4478bd4..897e5cf 100644
--- a/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java
+++ b/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java
@@ -296,6 +296,8 @@
         for (int i = 0; i < WIFI_SCAN_TEST_ITERATIONS; ++i) {
             startScan();
             // Make sure at least one AP is found.
+            assertTrue("mScanResult should not be null. This may be due to a scan timeout",
+                       mScanResults != null);
             assertFalse("empty scan results!", mScanResults.isEmpty());
             long nowMillis = SystemClock.elapsedRealtime();
             // Keep track of how many APs are fresh in one scan.
@@ -373,7 +375,7 @@
             assertTrue(notExist != pos);
 
             // Enable & disable network
-            boolean disableOthers = false;
+            boolean disableOthers = true;
             assertTrue(mWifiManager.enableNetwork(netId, disableOthers));
             wifiConfiguration = mWifiManager.getConfiguredNetworks().get(pos);
             assertDisableOthers(wifiConfiguration, disableOthers);
@@ -484,6 +486,9 @@
         }
         assertTrue(mWifiManager.isWifiEnabled());
 
+        // This will generate a distinct stack trace if the initial connection fails.
+        connectWifi();
+
         int i = 0;
         for (; i < 15; i++) {
             // Wait for a WiFi connection
diff --git a/tests/tests/net/src/org/apache/http/conn/ssl/cts/AbstractVerifierTest.java b/tests/tests/net/src/org/apache/http/conn/ssl/cts/AbstractVerifierTest.java
new file mode 100644
index 0000000..5e2a55e
--- /dev/null
+++ b/tests/tests/net/src/org/apache/http/conn/ssl/cts/AbstractVerifierTest.java
@@ -0,0 +1,306 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.http.conn.ssl.cts;
+
+import javax.security.auth.x500.X500Principal;
+import junit.framework.TestCase;
+
+import org.apache.http.conn.ssl.AbstractVerifier;
+
+import java.lang.Override;
+import java.math.BigInteger;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Principal;
+import java.security.PublicKey;
+import java.security.SignatureException;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateExpiredException;
+import java.security.cert.CertificateNotYetValidException;
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.Set;
+
+/**
+ * See also {@link libcore.javax.security.auth.x500.X500PrincipalTest} as it shows some cases
+ * we are not checking as they are not allowed by the X500 principal in the first place.
+ */
+public final class AbstractVerifierTest extends TestCase {
+
+    public void testGetCns() {
+        assertCns("");
+        assertCns("ou=xxx");
+        assertCns("ou=xxx,cn=xxx", "xxx");
+        assertCns("ou=xxx+cn=yyy,cn=zzz+cn=abc", "yyy", "zzz", "abc");
+        assertCns("cn=a,cn=b", "a", "b");
+        assertCns("cn=a   c,cn=b", "a   c", "b");
+        assertCns("cn=a   ,cn=b", "a", "b");
+        assertCns("cn=Cc,cn=Bb,cn=Aa", "Cc", "Bb", "Aa");
+        assertCns("cn=imap.gmail.com", "imap.gmail.com");
+        assertCns("l=\"abcn=a,b\", cn=c", "c");
+        assertCns("l=\"abcn=a,b\", cn=c", "c");
+        assertCns("l=\"abcn=a,b\", cn= c", "c");
+        assertCns("cn=<", "<");
+        assertCns("cn=>", ">");
+        assertCns("cn= >", ">");
+        assertCns("cn=a b", "a b");
+        assertCns("cn   =a b", "a b");
+        assertCns("Cn=a b", "a b");
+        assertCns("cN=a b", "a b");
+        assertCns("CN=a b", "a b");
+        assertCns("cn=a#b", "a#b");
+        assertCns("cn=#130161", "a");
+        assertCns("l=q\t+cn=p", "p");
+        assertCns("l=q\n+cn=p", "p");
+        assertCns("l=q\n,cn=p", "p");
+        assertCns("l=,cn=p", "p");
+        assertCns("l=\tq\n,cn=\tp", "\tp");
+    }
+
+    /** A cn=, generates an empty value, unless it's at the very end */
+    public void testEmptyValues() {
+        assertCns("l=,cn=+cn=q", "", "q");
+        assertCns("l=,cn=,cn=q", "", "q");
+        assertCns("l=,cn=");
+        assertCns("l=,cn=q,cn=   ", "q");
+        assertCns("l=,cn=q  ,cn=   ", "q");
+        assertCns("l=,cn=\"\"");
+        assertCns("l=,cn=\"  \",cn=\"  \"", "  ", "  ");
+        assertCns("l=,cn=  ,cn=  ","");
+        assertCns("l=,cn=,cn=  ,cn=  ", "", "");
+    }
+
+
+    public void testGetCns_escapedChars() {
+        assertCns("cn=\\,", ",");
+        assertCns("cn=\\#", "#");
+        assertCns("cn=\\+", "+");
+        assertCns("cn=\\\"", "\"");
+        assertCns("cn=\\\\", "\\");
+        assertCns("cn=\\<", "<");
+        assertCns("cn=\\>", ">");
+        assertCns("cn=\\;", ";");
+        assertCns("cn=\\+", "+");
+        assertCns("cn=\"\\+\"", "+");
+        assertCns("cn=\"\\,\"", ",");
+        assertCns("cn= a =", "a =");
+        assertCns("cn==", "=");
+    }
+
+    public void testGetCns_whitespace() {
+        assertCns("cn= p", "p");
+        assertCns("cn=\np", "p");
+        assertCns("cn=\tp", "\tp");
+    }
+
+    public void testGetCnsWithOid() {
+        assertCns("2.5.4.3=a,ou=xxx", "a");
+        assertCns("2.5.4.3=\" a \",ou=xxx", " a ");
+        assertCns("2.5.5.3=a,ou=xxx,cn=b", "b");
+    }
+
+    public void testGetCnsWithQuotedStrings() {
+        assertCns("cn=\"\\\" a ,=<>#;\"", "\" a ,=<>#;");
+        assertCns("cn=abc\\,def", "abc,def");
+        assertCns("cn=\"\\\" a ,\\=<>\\#;\"", "\" a ,=<>#;");
+    }
+
+    public void testGetCnsWithUtf8() {
+        assertCns("cn=\"Lu\\C4\\8Di\\C4\\87\"", "\u004c\u0075\u010d\u0069\u0107");
+        assertCns("cn=Lu\\C4\\8Di\\C4\\87", "\u004c\u0075\u010d\u0069\u0107");
+        assertCns("cn=Lu\\C4\\8di\\c4\\87", "\u004c\u0075\u010d\u0069\u0107");
+        assertCns("cn=\"Lu\\C4\\8di\\c4\\87\"", "\u004c\u0075\u010d\u0069\u0107");
+        assertCns("cn=\u004c\u0075\u010d\u0069\u0107", "\u004c\u0075\u010d\u0069\u0107");
+        // \63=c
+        assertExceptionInPrincipal("\\63n=ab");
+        assertExceptionInPrincipal("cn=\\a");
+    }
+
+    public void testGetCnsWithWhitespace() {
+        assertCns("ou=a, cn=  a  b  ,o=x", "a  b");
+        assertCns("cn=\"  a  b  \" ,o=x", "  a  b  ");
+    }
+
+    private static void assertCns(String dn, String... expected) {
+        String[] result = AbstractVerifier.getCNs(createStubCertificate(dn));
+        if (expected.length == 0) {
+            assertNull(result);
+        } else {
+            assertNotNull(dn, result);
+            assertEquals(dn, Arrays.asList(expected), Arrays.asList(result));
+        }
+    }
+
+    private static void assertExceptionInPrincipal(String dn) {
+        try {
+            X500Principal principal = new X500Principal(dn);
+            fail("Expected " + IllegalArgumentException.class.getName()
+                    + " because of incorrect input name");
+        } catch (IllegalArgumentException e) {
+            // Expected.
+        }
+    }
+
+    private static X509Certificate createStubCertificate(final String subjectName) {
+        return new X509Certificate() {
+            @Override
+            public X500Principal getSubjectX500Principal() {
+                return new X500Principal(subjectName);
+            }
+
+            @Override
+            public Set<String> getCriticalExtensionOIDs() {
+                return null;
+            }
+
+            @Override
+            public byte[] getExtensionValue(String oid) {
+                return new byte[0];
+            }
+
+            @Override
+            public Set<String> getNonCriticalExtensionOIDs() {
+                return null;
+            }
+
+            @Override
+            public boolean hasUnsupportedCriticalExtension() {
+                return false;
+            }
+
+            @Override
+            public byte[] getEncoded() throws CertificateEncodingException {
+                return new byte[0];
+            }
+
+            @Override
+            public void verify(PublicKey key)
+                    throws CertificateException, NoSuchAlgorithmException, InvalidKeyException,
+                    NoSuchProviderException, SignatureException {
+
+            }
+
+            @Override
+            public void verify(PublicKey key, String sigProvider)
+                    throws CertificateException, NoSuchAlgorithmException, InvalidKeyException,
+                    NoSuchProviderException, SignatureException {
+
+            }
+
+            @Override
+            public String toString() {
+                return null;
+            }
+
+            @Override
+            public PublicKey getPublicKey() {
+                return null;
+            }
+
+            @Override
+            public void checkValidity()
+                    throws CertificateExpiredException, CertificateNotYetValidException {
+
+            }
+
+            @Override
+            public void checkValidity(Date date)
+                    throws CertificateExpiredException, CertificateNotYetValidException {
+
+            }
+
+            @Override
+            public int getVersion() {
+                return 0;
+            }
+
+            @Override
+            public BigInteger getSerialNumber() {
+                return null;
+            }
+
+            @Override
+            public Principal getIssuerDN() {
+                return null;
+            }
+
+            @Override
+            public Principal getSubjectDN() {
+                return null;
+            }
+
+            @Override
+            public Date getNotBefore() {
+                return null;
+            }
+
+            @Override
+            public Date getNotAfter() {
+                return null;
+            }
+
+            @Override
+            public byte[] getTBSCertificate() throws CertificateEncodingException {
+                return new byte[0];
+            }
+
+            @Override
+            public byte[] getSignature() {
+                return new byte[0];
+            }
+
+            @Override
+            public String getSigAlgName() {
+                return null;
+            }
+
+            @Override
+            public String getSigAlgOID() {
+                return null;
+            }
+
+            @Override
+            public byte[] getSigAlgParams() {
+                return new byte[0];
+            }
+
+            @Override
+            public boolean[] getIssuerUniqueID() {
+                return new boolean[0];
+            }
+
+            @Override
+            public boolean[] getSubjectUniqueID() {
+                return new boolean[0];
+            }
+
+            @Override
+            public boolean[] getKeyUsage() {
+                return new boolean[0];
+            }
+
+            @Override
+            public int getBasicConstraints() {
+                return 0;
+            }
+        };
+    }
+}
+
diff --git a/tests/tests/netsecpolicy/src/android/security/NetworkSecurityPolicyTestBase.java b/tests/tests/netsecpolicy/src/android/security/NetworkSecurityPolicyTestBase.java
index 0ab07ae..f55af35 100644
--- a/tests/tests/netsecpolicy/src/android/security/NetworkSecurityPolicyTestBase.java
+++ b/tests/tests/netsecpolicy/src/android/security/NetworkSecurityPolicyTestBase.java
@@ -98,7 +98,7 @@
             conn.setReadTimeout(5000);
             conn.getResponseCode();
             fail();
-        } catch (UnknownServiceException e) {
+        } catch (IOException e) {
             if ((e.getMessage() == null) || (!e.getMessage().toLowerCase().contains("cleartext"))) {
                 fail("Exception with which request failed does not mention cleartext: " + e);
             }
diff --git a/tests/tests/netsecpolicy/usescleartexttraffic-false/Android.mk b/tests/tests/netsecpolicy/usescleartexttraffic-false/Android.mk
index 01ea6b7..6dec23f 100644
--- a/tests/tests/netsecpolicy/usescleartexttraffic-false/Android.mk
+++ b/tests/tests/netsecpolicy/usescleartexttraffic-false/Android.mk
@@ -30,6 +30,9 @@
 
 LOCAL_INSTRUMENTATION_FOR := CtsNetSecPolicyUsesCleartextTrafficFalse
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_SDK_VERSION := current
 
 include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/netsecpolicy/usescleartexttraffic-false/AndroidTest.xml b/tests/tests/netsecpolicy/usescleartexttraffic-false/AndroidTest.xml
new file mode 100644
index 0000000..cd9e969
--- /dev/null
+++ b/tests/tests/netsecpolicy/usescleartexttraffic-false/AndroidTest.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS CtsNetSecPolicyUsesCleartextTrafficFalse test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsNetSecPolicyUsesCleartextTrafficFalse.apk" />
+        <option name="test-file-name" value="CtsNetSecPolicyUsesCleartextTrafficFalseTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="com.android.cts.netsecpolicy.usescleartext.false" />
+    </test>
+</configuration>
diff --git a/tests/tests/netsecpolicy/usescleartexttraffic-true/Android.mk b/tests/tests/netsecpolicy/usescleartexttraffic-true/Android.mk
index 9f53f18..6df748d 100644
--- a/tests/tests/netsecpolicy/usescleartexttraffic-true/Android.mk
+++ b/tests/tests/netsecpolicy/usescleartexttraffic-true/Android.mk
@@ -30,6 +30,9 @@
 
 LOCAL_INSTRUMENTATION_FOR := CtsNetSecPolicyUsesCleartextTrafficTrue
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_SDK_VERSION := current
 
 include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/netsecpolicy/usescleartexttraffic-true/AndroidTest.xml b/tests/tests/netsecpolicy/usescleartexttraffic-true/AndroidTest.xml
new file mode 100644
index 0000000..de0baf0
--- /dev/null
+++ b/tests/tests/netsecpolicy/usescleartexttraffic-true/AndroidTest.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS CtsNetSecPolicyUsesCleartextTrafficTrue test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsNetSecPolicyUsesCleartextTrafficTrue.apk" />
+        <option name="test-file-name" value="CtsNetSecPolicyUsesCleartextTrafficTrueTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="com.android.cts.netsecpolicy.usescleartext.true" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/tests/netsecpolicy/usescleartexttraffic-unspecified/Android.mk b/tests/tests/netsecpolicy/usescleartexttraffic-unspecified/Android.mk
index fe7d36e..6f35027 100644
--- a/tests/tests/netsecpolicy/usescleartexttraffic-unspecified/Android.mk
+++ b/tests/tests/netsecpolicy/usescleartexttraffic-unspecified/Android.mk
@@ -30,6 +30,9 @@
 
 LOCAL_INSTRUMENTATION_FOR := CtsNetSecPolicyUsesCleartextTrafficUnspecified
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_SDK_VERSION := current
 
 include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/netsecpolicy/usescleartexttraffic-unspecified/AndroidTest.xml b/tests/tests/netsecpolicy/usescleartexttraffic-unspecified/AndroidTest.xml
new file mode 100644
index 0000000..bbe34d7
--- /dev/null
+++ b/tests/tests/netsecpolicy/usescleartexttraffic-unspecified/AndroidTest.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS CtsNetSecPolicyUsesCleartextTrafficUnspecified test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsNetSecPolicyUsesCleartextTrafficUnspecified.apk" />
+        <option name="test-file-name" value="CtsNetSecPolicyUsesCleartextTrafficUnspecifiedTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="com.android.cts.netsecpolicy.usescleartext.unspecified" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/tests/networksecurityconfig/Android.mk b/tests/tests/networksecurityconfig/Android.mk
new file mode 100644
index 0000000..4312beb
--- /dev/null
+++ b/tests/tests/networksecurityconfig/Android.mk
@@ -0,0 +1,15 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT 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 $(call all-subdir-makefiles)
diff --git a/tests/tests/networksecurityconfig/manifest.xml b/tests/tests/networksecurityconfig/manifest.xml
new file mode 100644
index 0000000..0c1e85d
--- /dev/null
+++ b/tests/tests/networksecurityconfig/manifest.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="android.security.net.config.cts">
+  <application>
+      <uses-library android:name="android.test.runner"/>
+      <meta-data android:name="android.security.net.config"
+                 android:resource="@xml/network_security_config" />
+  </application>
+
+  <uses-permission android:name="android.permission.INTERNET" />
+  <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                   android:targetPackage="android.security.net.config.cts"
+                   android:label="">
+        <meta-data android:name="listener"
+            android:value="com.android.cts.runner.CtsTestRunListener" />
+    </instrumentation>
+</manifest>
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-attributes/Android.mk b/tests/tests/networksecurityconfig/networksecurityconfig-attributes/Android.mk
new file mode 100644
index 0000000..56c5d25
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-attributes/Android.mk
@@ -0,0 +1,34 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_PACKAGE_NAME := CtsNetSecConfigAttributeTestCases
+
+LOCAL_MODULE_TAGS := tests
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner org.apache.http.legacy android-support-test
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_SRC_FILES += $(call all-java-files-under, ../src)
+
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res/
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_SDK_VERSION := current
+include $(BUILD_CTS_PACKAGE)
\ No newline at end of file
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-attributes/AndroidManifest.xml b/tests/tests/networksecurityconfig/networksecurityconfig-attributes/AndroidManifest.xml
new file mode 100644
index 0000000..c2018ba
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-attributes/AndroidManifest.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="android.security.net.config.cts.CtsNetSecConfigAttributeTestCases">
+  <application>
+      <uses-library android:name="android.test.runner"/>
+      <meta-data android:name="android.security.net.config"
+                 android:resource="@xml/network_security_config" />
+  </application>
+
+  <uses-permission android:name="android.permission.INTERNET" />
+  <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                   android:targetPackage="android.security.net.config.cts.CtsNetSecConfigAttributeTestCases"
+                   android:label="">
+        <meta-data android:name="listener"
+            android:value="com.android.cts.runner.CtsTestRunListener" />
+    </instrumentation>
+</manifest>
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-attributes/AndroidTest.xml b/tests/tests/networksecurityconfig/networksecurityconfig-attributes/AndroidTest.xml
new file mode 100644
index 0000000..db52e8a
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-attributes/AndroidTest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS CtsNetSecConfigAttributeTestCases test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsNetSecConfigAttributeTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.security.net.config.cts.CtsNetSecConfigAttributeTestCases" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-attributes/res/xml/network_security_config.xml b/tests/tests/networksecurityconfig/networksecurityconfig-attributes/res/xml/network_security_config.xml
new file mode 100644
index 0000000..1e68b7d
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-attributes/res/xml/network_security_config.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<network-security-config>
+  <base-config cleartextTrafficPermitted="true">
+  </base-config>
+  <!-- Cleartext traffic is not permitted for connections to foo.bar -->
+  <domain-config cleartextTrafficPermitted="false">
+        <domain includeSubdomains="false">foo.bar</domain>
+  </domain-config>
+  <!-- cleartextTrafficPermitted not set, should inherit from the base-config -->
+  <domain-config>
+      <domain includeSubdomains="true">android.com</domain>
+  </domain-config>
+  <!-- Cleartext traffic is explicitly permitted to google.com and all subdomains -->
+  <domain-config cleartextTrafficPermitted="true">
+      <domain includeSubdomains="true">google.com</domain>
+  </domain-config>
+</network-security-config>
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-attributes/src/android/security/net/config/cts/TestAttributes.java b/tests/tests/networksecurityconfig/networksecurityconfig-attributes/src/android/security/net/config/cts/TestAttributes.java
new file mode 100644
index 0000000..4d23e5b
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-attributes/src/android/security/net/config/cts/TestAttributes.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.net.config.cts;
+
+import android.security.NetworkSecurityPolicy;
+import junit.framework.TestCase;
+
+public class TestAttributes extends TestCase {
+    public void testCleartextTrafficPermitted() throws Exception {
+        NetworkSecurityPolicy instance = NetworkSecurityPolicy.getInstance();
+        // Since there are some configs that do not allow cleartext the non-hostname aware version
+        // should return False.
+        assertFalse(instance.isCleartextTrafficPermitted());
+        // Domain that explicitly does not allow cleartext traffic.
+        assertFalse(instance.isCleartextTrafficPermitted("foo.bar"));
+        // Subdomains are not included in the above rule, they should use the base-config's value.
+        assertTrue(instance.isCleartextTrafficPermitted("example.foo.bar"));
+        // Domains in a domain-config that do not specify the flag, should inherit from the
+        // base-config.
+        assertTrue(instance.isCleartextTrafficPermitted("android.com"));
+        assertTrue(instance.isCleartextTrafficPermitted("foo.android.com"));
+        // Domains in a domain-config that explicitly allow cleartext.
+        assertTrue(instance.isCleartextTrafficPermitted("google.com"));
+        assertTrue(instance.isCleartextTrafficPermitted("test.google.com"));
+        // Domain not specified in a domain-config, should use the base-config's value.
+        assertTrue(instance.isCleartextTrafficPermitted("example.com"));
+    }
+}
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-basic-domain/Android.mk b/tests/tests/networksecurityconfig/networksecurityconfig-basic-domain/Android.mk
new file mode 100644
index 0000000..2b91bc6
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-basic-domain/Android.mk
@@ -0,0 +1,34 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_PACKAGE_NAME := CtsNetSecConfigBasicDomainConfigTestCases
+
+LOCAL_MODULE_TAGS := tests
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner org.apache.http.legacy android-support-test
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_SRC_FILES += $(call all-java-files-under, ../src)
+
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res/
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_SDK_VERSION := current
+include $(BUILD_CTS_PACKAGE)
\ No newline at end of file
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-basic-domain/AndroidManifest.xml b/tests/tests/networksecurityconfig/networksecurityconfig-basic-domain/AndroidManifest.xml
new file mode 100644
index 0000000..0fd1a59
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-basic-domain/AndroidManifest.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="android.security.net.config.cts.CtsNetSecConfigBasicDomainConfigTestCases">
+  <application>
+      <uses-library android:name="android.test.runner"/>
+      <meta-data android:name="android.security.net.config"
+                 android:resource="@xml/network_security_config" />
+  </application>
+
+  <uses-permission android:name="android.permission.INTERNET" />
+  <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                   android:targetPackage="android.security.net.config.cts.CtsNetSecConfigBasicDomainConfigTestCases"
+                   android:label="">
+        <meta-data android:name="listener"
+            android:value="com.android.cts.runner.CtsTestRunListener" />
+    </instrumentation>
+</manifest>
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-basic-domain/AndroidTest.xml b/tests/tests/networksecurityconfig/networksecurityconfig-basic-domain/AndroidTest.xml
new file mode 100644
index 0000000..6633c55
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-basic-domain/AndroidTest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS CtsNetSecConfigBasicDomainConfigTestCases test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsNetSecConfigBasicDomainConfigTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.security.net.config.cts.CtsNetSecConfigBasicDomainConfigTestCases" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-basic-domain/res/xml/network_security_config.xml b/tests/tests/networksecurityconfig/networksecurityconfig-basic-domain/res/xml/network_security_config.xml
new file mode 100644
index 0000000..6d8565c
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-basic-domain/res/xml/network_security_config.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<network-security-config>
+  <base-config>
+    <trust-anchors>
+    </trust-anchors>
+  </base-config>
+  <domain-config>
+    <domain>android.com</domain>
+    <trust-anchors>
+      <certificates src="system" />
+      <certificates src="user" />
+    </trust-anchors>
+  </domain-config>
+</network-security-config>
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-basic-domain/src/android/security/net/config/cts/DomainConfigTest.java b/tests/tests/networksecurityconfig/networksecurityconfig-basic-domain/src/android/security/net/config/cts/DomainConfigTest.java
new file mode 100644
index 0000000..73ddd33
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-basic-domain/src/android/security/net/config/cts/DomainConfigTest.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.net.config.cts;
+
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import javax.net.ssl.X509TrustManager;
+import junit.framework.TestCase;
+
+public class DomainConfigTest extends TestCase {
+
+    public void testDomainConfig() throws Exception {
+        TestUtils.assertTlsConnectionSucceeds("android.com", 443);
+    }
+
+    public void testDefaultConfig() throws Exception {
+        // The default config in this case has no trusted CAs, so all connections should fail.
+        TestUtils.assertTlsConnectionFails("developer.android.com", 443);
+        TestUtils.assertTlsConnectionFails("google.com", 443);
+    }
+
+    public void testHostnameAwareCheckServerTrustedRequired() throws Exception {
+        X509TrustManager x509tm = TestUtils.getDefaultTrustManager();
+        try {
+            x509tm.checkServerTrusted(new X509Certificate[] {}, "RSA");
+            fail("checkServerTrusted passed");
+        } catch (CertificateException e) {
+            if (!e.getMessage().contains("hostname aware checkServerTrusted")) {
+                fail("Hostname aware checkServerTrusted not required with a domain config");
+            }
+        }
+    }
+}
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-cleartext/Android.mk b/tests/tests/networksecurityconfig/networksecurityconfig-cleartext/Android.mk
new file mode 100644
index 0000000..df29b5f
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-cleartext/Android.mk
@@ -0,0 +1,34 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_PACKAGE_NAME := CtsNetSecConfigCleartextTrafficTestCases
+
+LOCAL_MODULE_TAGS := tests
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner org.apache.http.legacy android-support-test
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_SRC_FILES += $(call all-java-files-under, ../src)
+
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res/
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_SDK_VERSION := current
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-cleartext/AndroidManifest.xml b/tests/tests/networksecurityconfig/networksecurityconfig-cleartext/AndroidManifest.xml
new file mode 100644
index 0000000..dbb4770
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-cleartext/AndroidManifest.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="android.security.net.config.cts.CtsNetSecConfigCleartextTrafficTestCases">
+  <application>
+      <uses-library android:name="android.test.runner"/>
+      <meta-data android:name="android.security.net.config"
+                 android:resource="@xml/network_security_config" />
+  </application>
+
+  <uses-permission android:name="android.permission.INTERNET" />
+  <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                   android:targetPackage="android.security.net.config.cts.CtsNetSecConfigCleartextTrafficTestCases"
+                   android:label="">
+        <meta-data android:name="listener"
+            android:value="com.android.cts.runner.CtsTestRunListener" />
+    </instrumentation>
+</manifest>
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-cleartext/AndroidTest.xml b/tests/tests/networksecurityconfig/networksecurityconfig-cleartext/AndroidTest.xml
new file mode 100644
index 0000000..9957342
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-cleartext/AndroidTest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS CtsNetSecConfigCleartextTraffic test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsNetSecConfigCleartextTrafficTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.security.net.config.cts.CtsNetSecConfigCleartextTrafficTestCases" />
+    </test>
+</configuration>
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-cleartext/res/xml/network_security_config.xml b/tests/tests/networksecurityconfig/networksecurityconfig-cleartext/res/xml/network_security_config.xml
new file mode 100644
index 0000000..987b178
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-cleartext/res/xml/network_security_config.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<network-security-config>
+  <domain-config cleartextTrafficPermitted="false">
+    <domain includeSubdomains="true">android.com</domain>
+    <domain-config cleartextTrafficPermitted="true">
+      <domain>developer.android.com</domain>
+    </domain-config>
+  </domain-config>
+</network-security-config>
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-cleartext/src/android/security/net/config/cts/CleartextPermittedTest.java b/tests/tests/networksecurityconfig/networksecurityconfig-cleartext/src/android/security/net/config/cts/CleartextPermittedTest.java
new file mode 100644
index 0000000..401b5ac
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-cleartext/src/android/security/net/config/cts/CleartextPermittedTest.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.net.config.cts;
+
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import javax.net.ssl.X509TrustManager;
+import junit.framework.TestCase;
+
+public class CleartextPermittedTest extends TestCase {
+    public void testDefaultAllowed() throws Exception {
+        TestUtils.assertCleartextConnectionSucceeds("google.com", 80);
+        TestUtils.assertTlsConnectionSucceeds("google.com", 443);
+    }
+
+    public void testCleartextBlocked() throws Exception {
+        TestUtils.assertCleartextConnectionFails("android.com", 80);
+        TestUtils.assertTlsConnectionSucceeds("android.com", 443);
+        // subdomains of android.com are also disallowed.
+        TestUtils.assertCleartextConnectionFails("www.android.com", 80);
+        TestUtils.assertTlsConnectionSucceeds("www.android.com", 443);
+    }
+
+    public void testNestedCleartextPermitted() throws Exception {
+        // developer.android.com is explicitly permitted.
+        TestUtils.assertCleartextConnectionSucceeds("developer.android.com", 80);
+        TestUtils.assertTlsConnectionSucceeds("developer.android.com", 443);
+    }
+}
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-disabled/Android.mk b/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-disabled/Android.mk
new file mode 100644
index 0000000..59e5625
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-disabled/Android.mk
@@ -0,0 +1,34 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_PACKAGE_NAME := CtsNetSecConfigBasicDebugDisabledTestCases
+
+LOCAL_MODULE_TAGS := tests
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner org.apache.http.legacy android-support-test
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_SRC_FILES += $(call all-java-files-under, ../src)
+
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res/
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_SDK_VERSION := current
+include $(BUILD_CTS_PACKAGE)
\ No newline at end of file
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-disabled/AndroidManifest.xml b/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-disabled/AndroidManifest.xml
new file mode 100644
index 0000000..9464950
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-disabled/AndroidManifest.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="android.security.net.config.cts.CtsNetSecConfigBasicDebugDisabledTestCases">
+  <application android:debuggable="false">
+      <uses-library android:name="android.test.runner"/>
+      <meta-data android:name="android.security.net.config"
+                 android:resource="@xml/network_security_config" />
+  </application>
+
+  <uses-permission android:name="android.permission.INTERNET" />
+  <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                   android:targetPackage="android.security.net.config.cts.CtsNetSecConfigBasicDebugDisabledTestCases"
+                   android:label="">
+        <meta-data android:name="listener"
+            android:value="com.android.cts.runner.CtsTestRunListener" />
+    </instrumentation>
+</manifest>
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-disabled/AndroidTest.xml b/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-disabled/AndroidTest.xml
new file mode 100644
index 0000000..de1cc1b
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-disabled/AndroidTest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS CtsNetSecConfigBasicDebugDisabledTestCases test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsNetSecConfigBasicDebugDisabledTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.security.net.config.cts.CtsNetSecConfigBasicDebugDisabledTestCases" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-disabled/res/xml/network_security_config.xml b/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-disabled/res/xml/network_security_config.xml
new file mode 100644
index 0000000..c44d9de
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-disabled/res/xml/network_security_config.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<network-security-config>
+  <!-- default config that trusts nothing. Will always cause TLS errors -->
+  <base-config>
+    <trust-anchors>
+    </trust-anchors>
+  </base-config>
+  <!-- debug overrides, should be ignored in this case since the app is not debuggable -->
+  <debug-overrides>
+    <trust-anchors>
+      <certificates src="system" />
+    </trust-anchors>
+  </debug-overrides>
+</network-security-config>
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-disabled/src/android/security/net/config/cts/BasicDebugOverrideDisabledTest.java b/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-disabled/src/android/security/net/config/cts/BasicDebugOverrideDisabledTest.java
new file mode 100644
index 0000000..862dd9b
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-disabled/src/android/security/net/config/cts/BasicDebugOverrideDisabledTest.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.net.config.cts;
+
+import junit.framework.TestCase;
+
+public class BasicDebugOverrideDisabledTest extends TestCase {
+
+    public void testDefaultConfig() throws Exception {
+        TestUtils.assertTlsConnectionFails("android.com", 443);
+    }
+}
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-enabled/Android.mk b/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-enabled/Android.mk
new file mode 100644
index 0000000..c935486
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-enabled/Android.mk
@@ -0,0 +1,34 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_PACKAGE_NAME := CtsNetSecConfigBasicDebugEnabledTestCases
+
+LOCAL_MODULE_TAGS := tests
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner org.apache.http.legacy android-support-test
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_SRC_FILES += $(call all-java-files-under, ../src)
+
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res/
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_SDK_VERSION := current
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-enabled/AndroidManifest.xml b/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-enabled/AndroidManifest.xml
new file mode 100644
index 0000000..2a46c8c
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-enabled/AndroidManifest.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="android.security.net.config.cts.CtsNetSecConfigBasicDebugEnabledTestCases">
+  <application android:debuggable="true">
+      <uses-library android:name="android.test.runner"/>
+      <meta-data android:name="android.security.net.config"
+                 android:resource="@xml/network_security_config" />
+  </application>
+
+  <uses-permission android:name="android.permission.INTERNET" />
+  <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                   android:targetPackage="android.security.net.config.cts.CtsNetSecConfigBasicDebugEnabledTestCases"
+                   android:label="">
+        <meta-data android:name="listener"
+            android:value="com.android.cts.runner.CtsTestRunListener" />
+    </instrumentation>
+</manifest>
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-enabled/AndroidTest.xml b/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-enabled/AndroidTest.xml
new file mode 100644
index 0000000..fe6e6dc
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-enabled/AndroidTest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS CtsNetSecConfigBasicDebugEnabledTestCases test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsNetSecConfigBasicDebugEnabledTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.security.net.config.cts.CtsNetSecConfigBasicDebugEnabledTestCases" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-enabled/res/xml/network_security_config.xml b/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-enabled/res/xml/network_security_config.xml
new file mode 100644
index 0000000..f2c800a
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-enabled/res/xml/network_security_config.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<network-security-config>
+  <!-- default config that trusts nothing. Will always cause TLS errors -->
+  <base-config>
+    <trust-anchors>
+    </trust-anchors>
+  </base-config>
+  <!-- debug override that trusts the system CA store. Connections will work as normal when the
+       application is debuggable. -->
+  <debug-overrides>
+    <trust-anchors>
+      <certificates src="system" />
+    </trust-anchors>
+  </debug-overrides>
+</network-security-config>
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-enabled/src/android/security/net/config/cts/BasicDebugOverrideEnabledTest.java b/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-enabled/src/android/security/net/config/cts/BasicDebugOverrideEnabledTest.java
new file mode 100644
index 0000000..c0d9814
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-enabled/src/android/security/net/config/cts/BasicDebugOverrideEnabledTest.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.net.config.cts;
+
+import junit.framework.TestCase;
+
+public class BasicDebugOverrideEnabledTest extends TestCase {
+
+    public void testDefaultConfig() throws Exception {
+        // Connections should work thanks to the debug overrides adding the system CA store.
+        TestUtils.assertTlsConnectionSucceeds("android.com", 443);
+    }
+}
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-invalid-pin/Android.mk b/tests/tests/networksecurityconfig/networksecurityconfig-invalid-pin/Android.mk
new file mode 100644
index 0000000..a89bad0
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-invalid-pin/Android.mk
@@ -0,0 +1,34 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_PACKAGE_NAME := CtsNetSecConfigInvalidPinTestCases
+
+LOCAL_MODULE_TAGS := tests
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner org.apache.http.legacy android-support-test
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_SRC_FILES += $(call all-java-files-under, ../src)
+
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res/
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_SDK_VERSION := current
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-invalid-pin/AndroidManifest.xml b/tests/tests/networksecurityconfig/networksecurityconfig-invalid-pin/AndroidManifest.xml
new file mode 100644
index 0000000..e01dc07
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-invalid-pin/AndroidManifest.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="android.security.net.config.cts.CtsNetSecConfigInvalidPinTestCases">
+  <application>
+      <uses-library android:name="android.test.runner"/>
+      <meta-data android:name="android.security.net.config"
+                 android:resource="@xml/network_security_config" />
+  </application>
+
+  <uses-permission android:name="android.permission.INTERNET" />
+  <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                   android:targetPackage="android.security.net.config.cts.CtsNetSecConfigInvalidPinTestCases"
+                   android:label="">
+        <meta-data android:name="listener"
+            android:value="com.android.cts.runner.CtsTestRunListener" />
+    </instrumentation>
+</manifest>
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-invalid-pin/AndroidTest.xml b/tests/tests/networksecurityconfig/networksecurityconfig-invalid-pin/AndroidTest.xml
new file mode 100644
index 0000000..4f9adbc
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-invalid-pin/AndroidTest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS CtsNetSecConfigInvalidPinTestCases test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsNetSecConfigInvalidPinTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.security.net.config.cts.CtsNetSecConfigInvalidPinTestCases" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-invalid-pin/res/xml/network_security_config.xml b/tests/tests/networksecurityconfig/networksecurityconfig-invalid-pin/res/xml/network_security_config.xml
new file mode 100644
index 0000000..163b238
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-invalid-pin/res/xml/network_security_config.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<network-security-config>
+  <domain-config>
+    <domain>android.com</domain>
+    <pin-set>
+      <!-- Invalid pin for android.com -->
+      <pin digest="SHA-256">1HIpactkIAq2Y49orFOOQKurWxmmSFZhBCoQYcRhJ3Y=</pin>
+    </pin-set>
+  </domain-config>
+</network-security-config>
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-invalid-pin/src/android/security/net/config/cts/InvalidPinTest.java b/tests/tests/networksecurityconfig/networksecurityconfig-invalid-pin/src/android/security/net/config/cts/InvalidPinTest.java
new file mode 100644
index 0000000..fb0444a
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-invalid-pin/src/android/security/net/config/cts/InvalidPinTest.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.net.config.cts;
+
+import junit.framework.TestCase;
+
+public class InvalidPinTest extends TestCase {
+
+    public void testPinFailure() throws Exception {
+        TestUtils.assertTlsConnectionFails("android.com", 443);
+    }
+
+    public void testDefaultDomainUnaffected() throws Exception {
+        TestUtils.assertTlsConnectionSucceeds("google.com", 443);
+        TestUtils.assertTlsConnectionSucceeds("developer.android.com", 443);
+    }
+}
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-nested-domains/Android.mk b/tests/tests/networksecurityconfig/networksecurityconfig-nested-domains/Android.mk
new file mode 100644
index 0000000..d68073d
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-nested-domains/Android.mk
@@ -0,0 +1,34 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_PACKAGE_NAME := CtsNetSecConfigNestedDomainConfigTestCases
+
+LOCAL_MODULE_TAGS := tests
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner org.apache.http.legacy android-support-test
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_SRC_FILES += $(call all-java-files-under, ../src)
+
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res/
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_SDK_VERSION := current
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-nested-domains/AndroidManifest.xml b/tests/tests/networksecurityconfig/networksecurityconfig-nested-domains/AndroidManifest.xml
new file mode 100644
index 0000000..358644e
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-nested-domains/AndroidManifest.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="android.security.net.config.cts.CtsNetSecConfigNestedDomainConfigTestCases">
+  <application>
+      <uses-library android:name="android.test.runner"/>
+      <meta-data android:name="android.security.net.config"
+                 android:resource="@xml/network_security_config" />
+  </application>
+
+  <uses-permission android:name="android.permission.INTERNET" />
+  <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                   android:targetPackage="android.security.net.config.cts.CtsNetSecConfigNestedDomainConfigTestCases"
+                   android:label="">
+        <meta-data android:name="listener"
+            android:value="com.android.cts.runner.CtsTestRunListener" />
+    </instrumentation>
+</manifest>
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-nested-domains/AndroidTest.xml b/tests/tests/networksecurityconfig/networksecurityconfig-nested-domains/AndroidTest.xml
new file mode 100644
index 0000000..c6a1dd1
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-nested-domains/AndroidTest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS CtsNetSecConfigNestedDomainConfigTestCases test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsNetSecConfigNestedDomainConfigTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.security.net.config.cts.CtsNetSecConfigNestedDomainConfigTestCases" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-nested-domains/res/xml/network_security_config.xml b/tests/tests/networksecurityconfig/networksecurityconfig-nested-domains/res/xml/network_security_config.xml
new file mode 100644
index 0000000..9e91dc7
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-nested-domains/res/xml/network_security_config.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<network-security-config>
+  <domain-config cleartextTrafficPermitted="true">
+    <domain includeSubdomains="true">android.com</domain>
+    <!-- Empty trust anchors, all TLS connections will fail -->
+    <trust-anchors>
+    </trust-anchors>
+    <!-- Nested config, should inherit all unset values from the parent domain -->
+    <domain-config cleartextTrafficPermitted="false">
+      <domain>developer.android.com</domain>
+    </domain-config>
+  </domain-config>
+  <base-config>
+  </base-config>
+</network-security-config>
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-nested-domains/src/android/security/net/config/cts/NestedDomainConfigTest.java b/tests/tests/networksecurityconfig/networksecurityconfig-nested-domains/src/android/security/net/config/cts/NestedDomainConfigTest.java
new file mode 100644
index 0000000..b77ad5a
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-nested-domains/src/android/security/net/config/cts/NestedDomainConfigTest.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.net.config.cts;
+
+import android.security.NetworkSecurityPolicy;
+
+import junit.framework.TestCase;
+
+public class NestedDomainConfigTest extends TestCase {
+
+    public void testRootDomainConfig() throws Exception {
+        TestUtils.assertTlsConnectionFails("android.com", 443);
+        NetworkSecurityPolicy instance = NetworkSecurityPolicy.getInstance();
+        assertTrue(instance.isCleartextTrafficPermitted("android.com"));
+    }
+
+    public void testNestedDomainConfig() throws Exception {
+        TestUtils.assertTlsConnectionFails("developer.android.com", 443);
+        NetworkSecurityPolicy instance = NetworkSecurityPolicy.getInstance();
+        assertFalse(instance.isCleartextTrafficPermitted("developer.android.com"));
+    }
+}
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-resourcesrc/Android.mk b/tests/tests/networksecurityconfig/networksecurityconfig-resourcesrc/Android.mk
new file mode 100644
index 0000000..cace6d0
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-resourcesrc/Android.mk
@@ -0,0 +1,34 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_PACKAGE_NAME := CtsNetSecConfigResourcesSrcTestCases
+
+LOCAL_MODULE_TAGS := tests
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner org.apache.http.legacy android-support-test
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_SRC_FILES += $(call all-java-files-under, ../src)
+
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res/
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_SDK_VERSION := current
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-resourcesrc/AndroidManifest.xml b/tests/tests/networksecurityconfig/networksecurityconfig-resourcesrc/AndroidManifest.xml
new file mode 100644
index 0000000..492a914
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-resourcesrc/AndroidManifest.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="android.security.net.config.cts.CtsNetSecConfigResourcesSrcTestCases">
+  <application>
+      <uses-library android:name="android.test.runner"/>
+      <meta-data android:name="android.security.net.config"
+                 android:resource="@xml/network_security_config" />
+  </application>
+
+  <uses-permission android:name="android.permission.INTERNET" />
+  <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                   android:targetPackage="android.security.net.config.cts.CtsNetSecConfigResourcesSrcTestCases"
+                   android:label="">
+        <meta-data android:name="listener"
+            android:value="com.android.cts.runner.CtsTestRunListener" />
+    </instrumentation>
+</manifest>
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-resourcesrc/AndroidTest.xml b/tests/tests/networksecurityconfig/networksecurityconfig-resourcesrc/AndroidTest.xml
new file mode 100644
index 0000000..aa6df4d
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-resourcesrc/AndroidTest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS CtsNetSecConfigInvalidPinTestCases test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsNetSecConfigResourcesSrcTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.security.net.config.cts.CtsNetSecConfigResourcesSrcTestCases" />
+    </test>
+</configuration>
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-resourcesrc/res/raw/der_multiple.der b/tests/tests/networksecurityconfig/networksecurityconfig-resourcesrc/res/raw/der_multiple.der
new file mode 100644
index 0000000..784263f
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-resourcesrc/res/raw/der_multiple.der
Binary files differ
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-resourcesrc/res/raw/der_single.der b/tests/tests/networksecurityconfig/networksecurityconfig-resourcesrc/res/raw/der_single.der
new file mode 100644
index 0000000..64a1359
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-resourcesrc/res/raw/der_single.der
Binary files differ
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-resourcesrc/res/raw/pem_multiple.pem b/tests/tests/networksecurityconfig/networksecurityconfig-resourcesrc/res/raw/pem_multiple.pem
new file mode 100644
index 0000000..f342f3a
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-resourcesrc/res/raw/pem_multiple.pem
@@ -0,0 +1,34 @@
+-----BEGIN CERTIFICATE-----
+MIICvDCCAaSgAwIBAgIDBwztMA0GCSqGSIb3DQEBCwUAMBAxDjAMBgNVBAMUBVBF
+TV8xMCoYEzIwMTUwMTAxMDAwMDAwKzAwMDAYEzIwMjAwMTAxMDAwMDAwKzAwMDAw
+EDEOMAwGA1UEAxQFUEVNXzEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
+AQCq2QLoIjhJW51CpfQcoiXmtCB6GltsM5HEYqA52AQZXOeO4HXzFwizycpwA1Sh
+EWkKnbvONQ7HO/rxb1gWcU4IWOPMY54BI2hOMiOmknTeobLW38WnCJzeD0mOxx7Z
+9dzRFoAcQdEPvWlB7MD5hK0+sS/CAZcx5Qc/DBE5RrWliKXXsYK5lAdtQiXB4L6H
+126SkH1ZmALer8wAMRhhUSeYoWwR4z7w5kRRntO9lAAA8lfS61K0ojSz170cyH41
+/jvkMFXP1MV8ljxVU5CgNdnRmAgogz834btJ9dbZGckt1Trxp0k7Y9CdRBrykaw/
+n2TQymCdeTGoxV0vWa++InVjAgMBAAGjEzARMA8GA1UdEwEB/wQFMAMBAf8wDQYJ
+KoZIhvcNAQELBQADggEBAJWI/rlbtVDsVI2w9Ylf+Agzx7n5xFytrz64d8YcqPlm
+MI/8/PlzA32MqWohe7D/DXbsx8lDctii8sI6L9zjYKxkXIhs6bBnXlbTjHgOhloq
+v3yL1VnJSNfXFjL46jvps8pPbTobjzFNCazS2xZTlIs1MQfpF8nG63+FoTcRGmK8
+q500bS2gQ2lEwh3FusrKAyRGiBJtfnw0pyhOsNpO63yi4HGMMtVpC/6rIkpAor/g
+vIaOWsCYa6yllaeSDGbWyu5GBkZJa9pewCjUQLSwktHuhI9RsUMe9CcBwto3y37I
+151kgX4xNlJYDoomE6ORGgEWqS5fB39GY2f7W9URfXE=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICvDCCAaSgAwIBAgIDC+NwMA0GCSqGSIb3DQEBCwUAMBAxDjAMBgNVBAMUBVBF
+TV8yMCoYEzIwMTUwMTAxMDAwMDAwKzAwMDAYEzIwMjAwMTAxMDAwMDAwKzAwMDAw
+EDEOMAwGA1UEAxQFUEVNXzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
+AQCnMte2oRePmLQB8h4+cBoI2ZAC5KWC0O0nPdEXO383IDoPB/V1dRXy/ZXFw2JU
+acPq+fT+tXw8aiiEH7Jq4wPvI1E1YgvcDnl39xmOvRgoHk2/V9SMJ2L1w2h9aK/4
+490ECRNB1MyydSwG9uE9zoYAHoOjMUfjvjPIjURrJoRx0EiVc+6E6qB92DvOloIW
+PZq60Nql19H8Jl6ISj/br8wKiNN0nkZ3M2/Ditbr/bgucEqHAy9p0J0gPQ4mmlRk
+QTk3gRsHZw2zAn4wyaWKgbB+sY1z77IZ0HeS4FbI2h/qfx4IfIEBOT8IVkJoHqN+
+j6+xI8fWOHRACLevj6Cf+WeZAgMBAAGjEzARMA8GA1UdEwEB/wQFMAMBAf8wDQYJ
+KoZIhvcNAQELBQADggEBAIofR+BsrnvRIr+vkABRKJ8shds4mfBCv3Uv0oyLPgoY
+M1X79NuPuT4TmlhX38yk242FTMXwUn1FsTQjA9NNc7BD6aJHZ3/ivdbAViMVs+ND
+1hjlSuzg9N2rDV/+QR2axUBgLNGN4g07IjZpkky4+LB/Havx8e1TQ52NGze1iCjk
+d/+1CjfLCBrIRM2KfQQtqL6Ee6Dy5OIlzk7N1SQ18ON1eVuc/JK7d4bh/vJgUwsq
+wWUOEBkLx1Bu4Na6u+u4pwuKz6XhHN1Sn4TUB7J5p1NS0KEfcuK+qBe0RJbAXhYE
+OF7PYii754/zZBTZYspK2I9WRk9jaXFdKhcA7ptkBfk=
+-----END CERTIFICATE-----
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-resourcesrc/res/raw/pem_single.pem b/tests/tests/networksecurityconfig/networksecurityconfig-resourcesrc/res/raw/pem_single.pem
new file mode 100644
index 0000000..b0ebd7b
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-resourcesrc/res/raw/pem_single.pem
@@ -0,0 +1,17 @@
+-----BEGIN CERTIFICATE-----
+MIICxjCCAa6gAwIBAgIDD0EmMA0GCSqGSIb3DQEBCwUAMBUxEzARBgNVBAMUClBF
+TV9zaW5nbGUwKhgTMjAxNTAxMDEwMDAwMDArMDAwMBgTMjAyMDAxMDEwMDAwMDAr
+MDAwMDAVMRMwEQYDVQQDFApQRU1fc2luZ2xlMIIBIjANBgkqhkiG9w0BAQEFAAOC
+AQ8AMIIBCgKCAQEAvvfUKgXYIKc2C3kqwvhtHatNjWU7sTSmAx5Fh3Ok4H41M6XF
+4sTAECkU3UZGIM2kwrb+IJcJBlwg0SG/9s0e5bk1qvvu2iUZjR3y/oOcj/VGNtOT
+DC3TqCkAe4pd6FbydeMIo4H8t1s1Zg0BoGa15o3YvcBS7QOusAMb+h2rj2lVH5+F
+bet+KydK02FUACXYUIL+Em0QcF9ylGLVnfuieGaEtOEwxUhWui1DuDHcJ4V+nG1y
+9jpL+X2EvN7/oXBGV03kEo+i/QnwwI2x8r7yh8ZfkHgUlz5WSWNLQZD+IXOw8DuY
+eAQSvQtqPgYFVi4Zq4dVnWmmmyiKwoLn8eYkZQIDAQABoxMwETAPBgNVHRMBAf8E
+BTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQALfm/CaKleAeAccKEY9wZ796ycfwJn
+H5WdX2LEbosKdr21pbjvna/IPxz6QueX9YAWGWAWNowZDlLRStZR7EAP23cEzWbW
+qQtTuQ+wu1v2M4Zuzw2UAi89ooaXK0VskeMK5AnqY4trAWKMeetOANSdj+J8WIdg
+30jmXuLKX9PLfpq6iNLMcGM3j8Q5cCZmnf6q3KYP/7D5iMeMb/rVGNapfTOyGNFe
+PPhOMFU20BZLpIKpdEAmbWhtX5gzGXADObU6VpBIlG7B2BiUUuQjz3FDKljK7L1r
+bsu+L7mWzAlW4yDt+VwgYmYf1m/RxrCxtLAqQYfJPekQeh3wycLfN9g3
+-----END CERTIFICATE-----
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-resourcesrc/res/xml/network_security_config.xml b/tests/tests/networksecurityconfig/networksecurityconfig-resourcesrc/res/xml/network_security_config.xml
new file mode 100644
index 0000000..49ebfcf
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-resourcesrc/res/xml/network_security_config.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<network-security-config>
+  <base-config>
+    <trust-anchors>
+      <certificates src="@raw/der_single" />
+      <certificates src="@raw/pem_single" />
+      <certificates src="@raw/der_multiple" />
+      <certificates src="@raw/pem_multiple" />
+    </trust-anchors>
+  </base-config>
+</network-security-config>
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-resourcesrc/src/android/security/net/config/cts/ResourceSourceTest.java b/tests/tests/networksecurityconfig/networksecurityconfig-resourcesrc/src/android/security/net/config/cts/ResourceSourceTest.java
new file mode 100644
index 0000000..a191f49
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-resourcesrc/src/android/security/net/config/cts/ResourceSourceTest.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.net.config.cts;
+
+import android.security.net.config.cts.CtsNetSecConfigResourcesSrcTestCases.R;
+
+import android.test.AndroidTestCase;
+import android.test.MoreAsserts;
+import java.io.InputStream;
+import java.security.KeyStore;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.util.HashSet;
+import java.util.Set;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.X509TrustManager;
+
+public class ResourceSourceTest extends AndroidTestCase {
+
+    public void testSingleDerPresent() throws Exception {
+        Set<X509Certificate> trusted = getTrustedCertificates();
+        Set<X509Certificate> singleDer = loadCertificates(R.raw.der_single);
+        assertContainsAll(trusted, singleDer);
+    }
+
+    public void testSinglePemPresent() throws Exception {
+        Set<X509Certificate> trusted = getTrustedCertificates();
+        Set<X509Certificate> singlePem = loadCertificates(R.raw.pem_single);
+        assertContainsAll(trusted, singlePem);
+    }
+
+    public void testMultipleDerPresent() throws Exception {
+        Set<X509Certificate> trusted = getTrustedCertificates();
+        Set<X509Certificate> multipleDer = loadCertificates(R.raw.der_multiple);
+        assertEquals(2, multipleDer.size());
+        assertContainsAll(trusted, multipleDer);
+    }
+
+    public void testMultiplePemPresent() throws Exception {
+        Set<X509Certificate> trusted = getTrustedCertificates();
+        Set<X509Certificate> multiplePem = loadCertificates(R.raw.pem_multiple);
+        assertEquals(2, multiplePem.size());
+        assertContainsAll(trusted, multiplePem);
+    }
+
+    public void testOnlyResourceCasPresent() throws Exception {
+        Set<X509Certificate> trusted = getTrustedCertificates();
+        Set<X509Certificate> certs = loadCertificates(R.raw.der_single);
+        certs.addAll(loadCertificates(R.raw.der_multiple));
+        certs.addAll(loadCertificates(R.raw.pem_single));
+        certs.addAll(loadCertificates(R.raw.pem_multiple));
+        MoreAsserts.assertEquals(certs, trusted);
+    }
+
+    private Set<X509Certificate> loadCertificates(int resId) throws Exception {
+        Set<X509Certificate> result = new HashSet<X509Certificate>();
+        CertificateFactory factory = CertificateFactory.getInstance("X.509");
+        InputStream is = null;
+        try {
+            is = getContext().getResources().openRawResource(resId);
+            for (Certificate cert : factory.generateCertificates(is)) {
+                result.add((X509Certificate)cert);
+            }
+            return result;
+        } finally {
+            if (is != null) {
+                is.close();
+            }
+        }
+    }
+
+    private static Set<X509Certificate> getTrustedCertificates() throws Exception {
+        TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX");
+        tmf.init((KeyStore)null);
+        for (TrustManager tm : tmf.getTrustManagers()) {
+            if (tm instanceof X509TrustManager) {
+                X509Certificate[] trustedCerts = ((X509TrustManager) tm).getAcceptedIssuers();
+                Set<X509Certificate> result = new HashSet<X509Certificate>(trustedCerts.length);
+                for (X509Certificate cert : trustedCerts) {
+                    result.add(cert);
+                }
+                return result;
+            }
+        }
+        fail("Unable to find X509TrustManager");
+        return null;
+    }
+
+    private static void assertContainsAll(Set<? extends Object> set,
+            Set<? extends Object> subset) throws Exception {
+        for (Object o : subset) {
+            if (!set.contains(o)) {
+                fail("Set does not contain element " + o);
+            }
+        }
+    }
+}
diff --git a/tests/tests/networksecurityconfig/src/android/security/net/config/cts/TestUtils.java b/tests/tests/networksecurityconfig/src/android/security/net/config/cts/TestUtils.java
new file mode 100644
index 0000000..d114ab5
--- /dev/null
+++ b/tests/tests/networksecurityconfig/src/android/security/net/config/cts/TestUtils.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.net.config.cts;
+
+import android.net.http.AndroidHttpClient;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.net.Socket;
+import java.net.URL;
+import java.security.KeyStore;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.util.List;
+import java.util.ArrayList;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLHandshakeException;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.X509TrustManager;
+
+import junit.framework.Assert;
+
+import org.apache.http.HttpResponse;
+import org.apache.http.client.methods.HttpGet;
+
+public final class TestUtils extends Assert {
+
+    private TestUtils() {
+    }
+
+    public static void assertTlsConnectionSucceeds(String host, int port) throws Exception {
+        assertSslSocketSucceeds(host, port);
+        assertHttpClientSucceeds(host, port, true /* https */);
+        assertUrlConnectionSucceeds(host, port, true /* https */);
+    }
+
+    public static void assertTlsConnectionFails(String host, int port) throws Exception {
+        assertSslSocketFails(host, port);
+        assertHttpClientFails(host, port, true /* https */);
+        assertUrlConnectionFails(host, port, true /* https */);
+    }
+
+    public static void assertCleartextConnectionSucceeds(String host, int port) throws Exception {
+        assertHttpClientSucceeds(host, port, false /* http */);
+        assertUrlConnectionSucceeds(host, port, false /* http */);
+    }
+
+    public static void assertCleartextConnectionFails(String host, int port) throws Exception {
+        assertHttpClientFails(host, port, false /* http */);
+        assertUrlConnectionFails(host, port, false /* http */);
+    }
+
+    public static X509TrustManager getDefaultTrustManager() throws Exception {
+        TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX");
+        tmf.init((KeyStore)null);
+        for (TrustManager tm : tmf.getTrustManagers()) {
+            if (tm instanceof X509TrustManager) {
+                return (X509TrustManager) tm;
+            }
+        }
+        fail("Unable to find X509TrustManager");
+        return null;
+    }
+
+    public static List<X509Certificate> loadCertificates(InputStream is) throws Exception {
+        CertificateFactory factory = CertificateFactory.getInstance("X.509");
+        ArrayList<X509Certificate> result = new ArrayList<>();
+        for (Certificate c : factory.generateCertificates(is)) {
+            result.add((X509Certificate) c);
+        }
+        return result;
+    }
+
+    private static void assertSslSocketFails(String host, int port)
+            throws Exception {
+        try {
+            Socket s = SSLContext.getDefault().getSocketFactory().createSocket(host, port);
+            s.getInputStream();
+            fail("Connection to " + host + ":" + port + " succeeded");
+        } catch (SSLHandshakeException expected) {
+        }
+    }
+
+    private static void assertSslSocketSucceeds(String host, int port)
+            throws Exception {
+        Socket s = SSLContext.getDefault().getSocketFactory().createSocket(host, port);
+        s.getInputStream();
+    }
+
+    private static void assertUrlConnectionFails(String host, int port, boolean https)
+            throws Exception {
+        URL url = new URL((https ? "https://" : "http://") + host + ":" + port);
+        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+        try {
+            connection.getInputStream();
+            fail("Connection to " + host + ":" + port + " succeeded");
+        } catch (IOException expected) {
+        }
+    }
+
+    private static void assertUrlConnectionSucceeds(String host, int port, boolean https)
+            throws Exception {
+        URL url = new URL((https ? "https://" : "http://") + host + ":" + port);
+        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+        connection.getInputStream();
+    }
+
+    private static void assertHttpClientSucceeds(String host, int port, boolean https)
+            throws Exception {
+        URL url = new URL((https ? "https://" : "http://") + host + ":" + port);
+        AndroidHttpClient httpClient = AndroidHttpClient.newInstance(null);
+        try {
+            HttpResponse response = httpClient.execute(new HttpGet(url.toString()));
+        } finally {
+            httpClient.close();
+        }
+    }
+
+    private static void assertHttpClientFails(String host, int port, boolean https)
+            throws Exception {
+        URL url = new URL((https ? "https://" : "http://") + host + ":" + port);
+        AndroidHttpClient httpClient = AndroidHttpClient.newInstance(null);
+        try {
+            HttpResponse response = httpClient.execute(new HttpGet(url.toString()));
+            fail("Connection to " + host + ":" + port + " succeeded");
+        } catch (IOException expected) {
+        } finally {
+            httpClient.close();
+        }
+    }
+}
diff --git a/tests/tests/opengl/Android.mk b/tests/tests/opengl/Android.mk
index 3844807..69090f5 100644
--- a/tests/tests/opengl/Android.mk
+++ b/tests/tests/opengl/Android.mk
@@ -35,10 +35,10 @@
 
 LOCAL_SDK_VERSION := current
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_CTS_PACKAGE)
 
 # Include the associated library's makefile.
 include $(LOCAL_PATH)/libopengltest/Android.mk
-
-
-
diff --git a/tests/tests/opengl/AndroidManifest.xml b/tests/tests/opengl/AndroidManifest.xml
index 363b9aa..cc0ab8f 100644
--- a/tests/tests/opengl/AndroidManifest.xml
+++ b/tests/tests/opengl/AndroidManifest.xml
@@ -14,7 +14,7 @@
      limitations under the License.
 -->
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.opengl"
+    package="android.opengl.cts"
     android:versionCode="1"
     android:versionName="1.0" >
 
@@ -23,7 +23,7 @@
     <uses-feature android:glEsVersion="0x00020000"/>
     <instrumentation
         android:name="android.support.test.runner.AndroidJUnitRunner"
-        android:targetPackage="com.android.cts.opengl" >
+        android:targetPackage="android.opengl.cts" >
         <meta-data android:name="listener"
             android:value="com.android.cts.runner.CtsTestRunListener" />
     </instrumentation>
diff --git a/tests/tests/opengl/AndroidTest.xml b/tests/tests/opengl/AndroidTest.xml
new file mode 100644
index 0000000..124d072
--- /dev/null
+++ b/tests/tests/opengl/AndroidTest.xml
@@ -0,0 +1,23 @@
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS OpenGL test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsOpenGLTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.opengl.cts" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/tests/opengl/libopengltest/Android.mk b/tests/tests/opengl/libopengltest/Android.mk
index a141550..afa94dc 100755
--- a/tests/tests/opengl/libopengltest/Android.mk
+++ b/tests/tests/opengl/libopengltest/Android.mk
@@ -36,6 +36,8 @@
 
 LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
 
+LOCAL_CXX_STL := libc++_static
+
 LOCAL_SHARED_LIBRARIES := libGLESv2 liblog
 include $(BUILD_SHARED_LIBRARY)
 
diff --git a/tests/tests/openglperf/Android.mk b/tests/tests/openglperf/Android.mk
index 6b42ed0..56fa568 100644
--- a/tests/tests/openglperf/Android.mk
+++ b/tests/tests/openglperf/Android.mk
@@ -26,7 +26,7 @@
 
 LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner ctsdeviceutil
 
-LOCAL_JNI_SHARED_LIBRARIES := libctsopenglperf_jni
+LOCAL_JNI_SHARED_LIBRARIES := libctsopenglperf_jni libnativehelper_compat_libc++
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
@@ -36,6 +36,9 @@
 
 LOCAL_SDK_VERSION := current
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_CTS_PACKAGE)
 
 # Make the replica island app and copy it to CTS out dir.
diff --git a/tests/tests/openglperf/AndroidManifest.xml b/tests/tests/openglperf/AndroidManifest.xml
index a213e51..9335a65 100644
--- a/tests/tests/openglperf/AndroidManifest.xml
+++ b/tests/tests/openglperf/AndroidManifest.xml
@@ -14,7 +14,7 @@
      limitations under the License.
 -->
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.openglperf"
+    package="android.openglperf.cts"
     android:versionCode="1"
     android:versionName="1.0" >
 
@@ -32,7 +32,7 @@
             android:value="com.android.cts.runner.CtsTestRunListener" />
     </instrumentation>
     <instrumentation
-        android:targetPackage="com.android.cts.openglperf"
+        android:targetPackage="android.openglperf.cts"
         android:name="android.support.test.runner.AndroidJUnitRunner">
         <meta-data android:name="listener"
             android:value="com.android.cts.runner.CtsTestRunListener" />
diff --git a/tests/tests/openglperf/AndroidTest.xml b/tests/tests/openglperf/AndroidTest.xml
new file mode 100644
index 0000000..630bd05
--- /dev/null
+++ b/tests/tests/openglperf/AndroidTest.xml
@@ -0,0 +1,23 @@
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS OpenGL Performance test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsOpenGlPerfTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.openglperf.cts" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/tests/openglperf/jni/Android.mk b/tests/tests/openglperf/jni/Android.mk
index 2cebaec..d6df59b 100644
--- a/tests/tests/openglperf/jni/Android.mk
+++ b/tests/tests/openglperf/jni/Android.mk
@@ -24,7 +24,7 @@
 
 LOCAL_C_INCLUDES := $(JNI_H_INCLUDE) $(call include-path-for, system-core) frameworks/native/opengl/include
 
-LOCAL_SHARED_LIBRARIES := libnativehelper libcutils liblog libGLES_trace libEGL
+LOCAL_SHARED_LIBRARIES := libnativehelper_compat_libc++ liblog libEGL
 
 LOCAL_SDK_VERSION := 14
 
diff --git a/tests/tests/os/Android.mk b/tests/tests/os/Android.mk
index f4b140e..bbee284 100644
--- a/tests/tests/os/Android.mk
+++ b/tests/tests/os/Android.mk
@@ -24,18 +24,23 @@
 # Include both the 32 and 64 bit versions
 LOCAL_MULTILIB := both
 
-LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctstestrunner guava
+LOCAL_STATIC_JAVA_LIBRARIES := \
+    ctsdeviceutil ctstestrunner guava platform-test-annotations
 
-LOCAL_JNI_SHARED_LIBRARIES := libcts_jni libctsos_jni
+LOCAL_JNI_SHARED_LIBRARIES := libcts_jni libctsos_jni libnativehelper_compat_libc++
 
-LOCAL_SRC_FILES := $(call all-java-files-under, src) \
-        src/android/os/cts/IParcelFileDescriptorPeer.aidl \
-        src/android/os/cts/IEmptyService.aidl \
-        src/android/os/cts/ISeccompIsolatedService.aidl \
-        src/android/os/cts/ISecondary.aidl
+LOCAL_SRC_FILES := \
+    $(call all-java-files-under, src) \
+    src/android/os/cts/IParcelFileDescriptorPeer.aidl \
+    src/android/os/cts/IEmptyService.aidl \
+    src/android/os/cts/ISeccompIsolatedService.aidl \
+    src/android/os/cts/ISecondary.aidl
 
 LOCAL_PACKAGE_NAME := CtsOsTestCases
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 # uncomment when b/13282254 is fixed
 #LOCAL_SDK_VERSION := current
 LOCAL_JAVA_LIBRARIES += android.test.runner
diff --git a/tests/tests/os/AndroidManifest.xml b/tests/tests/os/AndroidManifest.xml
index deb7045..bdb5230 100644
--- a/tests/tests/os/AndroidManifest.xml
+++ b/tests/tests/os/AndroidManifest.xml
@@ -16,7 +16,7 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.os">
+    package="android.os.cts">
 
     <permission android:name="android.os.cts.permission.TEST_GRANTED"
         android:protectionLevel="normal"
@@ -132,7 +132,7 @@
     </application>
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.cts.os"
+                     android:targetPackage="android.os.cts"
                      android:label="CTS tests of android.os">
         <meta-data android:name="listener"
             android:value="com.android.cts.runner.CtsTestRunListener" />
diff --git a/tests/tests/os/AndroidTest.xml b/tests/tests/os/AndroidTest.xml
new file mode 100644
index 0000000..fd446c2
--- /dev/null
+++ b/tests/tests/os/AndroidTest.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Configuration for OS Tests">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsOsTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.os.cts" />
+        <option name="runtime-hint" value="3m15s" />
+    </test>
+</configuration>
diff --git a/tests/tests/os/jni/Android.mk b/tests/tests/os/jni/Android.mk
index c125f5c..425b6c1 100644
--- a/tests/tests/os/jni/Android.mk
+++ b/tests/tests/os/jni/Android.mk
@@ -33,23 +33,12 @@
 # Select the architectures on which seccomp-bpf are supported. This is used to
 # include extra test files that will not compile on architectures where it is
 # not supported.
-ARCH_SUPPORTS_SECCOMP := 0
-ifeq ($(strip $(TARGET_ARCH)),arm)
-	ARCH_SUPPORTS_SECCOMP = 1
+ARCH_SUPPORTS_SECCOMP := 1
+ifeq ($(strip $(TARGET_ARCH)),mips)
+	ARCH_SUPPORTS_SECCOMP = 0
 endif
-
-ifeq ($(strip $(TARGET_ARCH)),arm64)
-	ARCH_SUPPORTS_SECCOMP = 1
-	# Required for __NR_poll definition.
-	LOCAL_CFLAGS += -D__ARCH_WANT_SYSCALL_DEPRECATED
-endif
-
-ifeq ($(strip $(TARGET_ARCH)),x86)
-	ARCH_SUPPORTS_SECCOMP = 1
-endif
-
-ifeq ($(strip $(TARGET_ARCH)),x86_64)
-	ARCH_SUPPORTS_SECCOMP = 1
+ifeq ($(strip $(TARGET_ARCH)),mips64)
+	ARCH_SUPPORTS_SECCOMP = 0
 endif
 
 ifeq ($(ARCH_SUPPORTS_SECCOMP),1)
@@ -62,10 +51,11 @@
 
 LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
 
-LOCAL_SHARED_LIBRARIES := libnativehelper liblog libdl libcutils
+LOCAL_SHARED_LIBRARIES := libnativehelper_compat_libc++ liblog libdl
+LOCAL_CXX_STL := none
 
 LOCAL_SRC_FILES += android_os_cts_CpuFeatures.cpp
 LOCAL_C_INCLUDES += ndk/sources/cpufeatures
-LOCAL_STATIC_LIBRARIES := cpufeatures
+LOCAL_STATIC_LIBRARIES := cpufeatures libc++_static
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/tests/tests/os/jni/android_os_cts_HardwareName.cpp b/tests/tests/os/jni/android_os_cts_HardwareName.cpp
index 6752aa3..74b630e 100644
--- a/tests/tests/os/jni/android_os_cts_HardwareName.cpp
+++ b/tests/tests/os/jni/android_os_cts_HardwareName.cpp
@@ -16,15 +16,13 @@
  */
 #include <jni.h>
 
-#include <cutils/properties.h>
+#include <sys/system_properties.h>
 
 jstring android_os_cts_HardwareName_getName(JNIEnv* env, jobject thiz)
 {
-    char name[PROPERTY_VALUE_MAX];
-    int ret;
+    char name[PROP_VALUE_MAX];
 
-    ret = property_get("ro.boot.hardware", name, NULL);
-    if (ret <= 0) {
+    if (__system_property_get("ro.boot.hardware", name) <= 0) {
         return NULL;
     }
 
diff --git a/tests/tests/os/jni/android_os_cts_OSFeatures.cpp b/tests/tests/os/jni/android_os_cts_OSFeatures.cpp
index 153fb27..b3ccc92 100644
--- a/tests/tests/os/jni/android_os_cts_OSFeatures.cpp
+++ b/tests/tests/os/jni/android_os_cts_OSFeatures.cpp
@@ -89,23 +89,6 @@
     // This define is controlled by the Android.mk.
     return false;
 #endif
-
-    int major;
-    int minor;
-    struct utsname uts;
-    if (uname(&uts) == -1) {
-        return false;
-    }
-
-    if (sscanf(uts.release, "%d.%d", &major, &minor) != 2) {
-        return false;
-    }
-
-    // Kernels before 3.8 don't have seccomp
-    if ((major < 3) || ((major == 3) && (minor < 8))) {
-        return false;
-    }
-
     return true;
 }
 
diff --git a/tests/tests/os/jni/seccomp-tests/README.android b/tests/tests/os/jni/seccomp-tests/README.android
index 8b1ac9a..a819ee5 100644
--- a/tests/tests/os/jni/seccomp-tests/README.android
+++ b/tests/tests/os/jni/seccomp-tests/README.android
@@ -9,8 +9,11 @@
 - Use __android_log_print() instead of fprintf()
 - Rename main() to seccomp_test_main()
 - Add get_seccomp_test_list()
+- Backport TEST(syscall_restart) from upstream
 
-The diff of modifications can be found in local-modifications-android.diff.
+The diff of modifications can be found in local-modifications-android.diff
+and local-modifications-android-2.diff. Note, the TEST(syscall_restart)
+backport is the only change in local-modifications-android-2.diff
 
 Additional modification is to backport fixes for Android Native Bridge:
 https://patchwork.kernel.org/patch/7537891/. This is not found in the above
diff --git a/tests/tests/os/jni/seccomp-tests/local-modifications-android-2.diff b/tests/tests/os/jni/seccomp-tests/local-modifications-android-2.diff
new file mode 100644
index 0000000..b56fc359
--- /dev/null
+++ b/tests/tests/os/jni/seccomp-tests/local-modifications-android-2.diff
@@ -0,0 +1,153 @@
+diff --git a/tests/tests/os/jni/seccomp-tests/tests/seccomp_bpf_tests.c b/tests/tests/os/jni/seccomp-tests/tests/seccomp_bpf_tests.c
+index 3c238e6..7481dd2 100644
+--- a/tests/tests/os/jni/seccomp-tests/tests/seccomp_bpf_tests.c
++++ b/tests/tests/os/jni/seccomp-tests/tests/seccomp_bpf_tests.c
+@@ -19,7 +19,6 @@
+ #include <linux/prctl.h>
+ #include <linux/ptrace.h>
+ #include <linux/seccomp.h>
+-#include <poll.h>
+ #include <pthread.h>
+ #include <semaphore.h>
+ #include <signal.h>
+@@ -28,6 +27,7 @@
+ #include <string.h>
+ #include <linux/elf.h>
+ #include <sys/uio.h>
++#include <sys/utsname.h>
+ #include <fcntl.h>  // ANDROID
+ #include <sys/mman.h>
+ #include <sys/times.h>
+@@ -1798,7 +1798,8 @@ TEST_F(TSYNC, two_siblings_not_under_filter) {
+ }
+ 
+ /* Make sure restarted syscalls are seen directly as "restart_syscall". */
+-TEST(syscall_restart) {
++TEST(syscall_restart)
++{
+ 	long ret;
+ 	unsigned long msg;
+ 	pid_t child_pid;
+@@ -1815,20 +1816,25 @@ TEST(syscall_restart) {
+ 		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_read, 5, 0),
+ 		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_exit, 4, 0),
+ 		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_rt_sigreturn, 3, 0),
+-		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_poll, 4, 0),
++		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_nanosleep, 4, 0),
+ 		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_restart_syscall, 4, 0),
+ 
+ 		/* Allow __NR_write for easy logging. */
+ 		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_write, 0, 1),
+ 		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
+ 		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_KILL),
+-		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_TRACE|0x100), /* poll */
+-		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_TRACE|0x200), /* restart */
++		/* The nanosleep jump target. */
++		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_TRACE|0x100),
++		/* The restart_syscall jump target. */
++		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_TRACE|0x200),
+ 	};
+ 	struct sock_fprog prog = {
+-		.len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
++		.len = (unsigned short) (sizeof(filter)/sizeof(filter[0])),
+ 		.filter = filter,
+ 	};
++#if defined(__arm__)
++	struct utsname utsbuf;
++#endif
+ 
+ 	ASSERT_EQ(0, pipe(pipefd));
+ 
+@@ -1837,10 +1843,7 @@ TEST(syscall_restart) {
+ 	if (child_pid == 0) {
+ 		/* Child uses EXPECT not ASSERT to deliver status correctly. */
+ 		char buf = ' ';
+-		struct pollfd fds = {
+-			.fd = pipefd[0],
+-			.events = POLLIN,
+-		};
++		struct timespec timeout = { };
+ 
+ 		/* Attach parent as tracer and stop. */
+ 		EXPECT_EQ(0, ptrace(PTRACE_TRACEME));
+@@ -1864,10 +1867,11 @@ TEST(syscall_restart) {
+ 			TH_LOG("Failed to get sync data from read()");
+ 		}
+ 
+-		/* Start poll to be interrupted. */
++		/* Start nanosleep to be interrupted. */
++		timeout.tv_sec = 1;
+ 		errno = 0;
+-		EXPECT_EQ(1, poll(&fds, 1, -1)) {
+-			TH_LOG("Call to poll() failed (errno %d)", errno);
++		EXPECT_EQ(0, nanosleep(&timeout, NULL)) {
++			TH_LOG("Call to nanosleep() failed (errno %d)", errno);
+ 		}
+ 
+ 		/* Read final sync from parent. */
+@@ -1892,14 +1896,14 @@ TEST(syscall_restart) {
+ 	ASSERT_EQ(0, ptrace(PTRACE_CONT, child_pid, NULL, 0));
+ 	ASSERT_EQ(1, write(pipefd[1], ".", 1));
+ 
+-	/* Wait for poll() to start. */
++	/* Wait for nanosleep() to start. */
+ 	ASSERT_EQ(child_pid, waitpid(child_pid, &status, 0));
+ 	ASSERT_EQ(true, WIFSTOPPED(status));
+ 	ASSERT_EQ(SIGTRAP, WSTOPSIG(status));
+ 	ASSERT_EQ(PTRACE_EVENT_SECCOMP, (status >> 16));
+ 	ASSERT_EQ(0, ptrace(PTRACE_GETEVENTMSG, child_pid, NULL, &msg));
+ 	ASSERT_EQ(0x100, msg);
+-	EXPECT_EQ(__NR_poll, get_syscall(_metadata, child_pid));
++	EXPECT_EQ(__NR_nanosleep, get_syscall(_metadata, child_pid));
+ 
+ 	/* Might as well check siginfo for sanity while we're here. */
+ 	ASSERT_EQ(0, ptrace(PTRACE_GETSIGINFO, child_pid, NULL, &info));
+@@ -1910,7 +1914,7 @@ TEST(syscall_restart) {
+ 	/* Verify signal delivery came from child (seccomp-triggered). */
+ 	EXPECT_EQ(child_pid, info.si_pid);
+ 
+-	/* Interrupt poll with SIGSTOP (which we'll need to handle). */
++	/* Interrupt nanosleep with SIGSTOP (which we'll need to handle). */
+ 	ASSERT_EQ(0, kill(child_pid, SIGSTOP));
+ 	ASSERT_EQ(0, ptrace(PTRACE_CONT, child_pid, NULL, 0));
+ 	ASSERT_EQ(child_pid, waitpid(child_pid, &status, 0));
+@@ -1920,7 +1924,7 @@ TEST(syscall_restart) {
+ 	ASSERT_EQ(0, ptrace(PTRACE_GETSIGINFO, child_pid, NULL, &info));
+ 	EXPECT_EQ(getpid(), info.si_pid);
+ 
+-	/* Restart poll with SIGCONT, which triggers restart_syscall. */
++	/* Restart nanosleep with SIGCONT, which triggers restart_syscall. */
+ 	ASSERT_EQ(0, kill(child_pid, SIGCONT));
+ 	ASSERT_EQ(0, ptrace(PTRACE_CONT, child_pid, NULL, 0));
+ 	ASSERT_EQ(child_pid, waitpid(child_pid, &status, 0));
+@@ -1934,16 +1938,25 @@ TEST(syscall_restart) {
+ 	ASSERT_EQ(SIGTRAP, WSTOPSIG(status));
+ 	ASSERT_EQ(PTRACE_EVENT_SECCOMP, (status >> 16));
+ 	ASSERT_EQ(0, ptrace(PTRACE_GETEVENTMSG, child_pid, NULL, &msg));
++
+ 	ASSERT_EQ(0x200, msg);
+ 	ret = get_syscall(_metadata, child_pid);
+ #if defined(__arm__)
+-	/* FIXME: ARM does not expose true syscall in registers. */
+-	EXPECT_EQ(__NR_poll, ret);
+-#else
+-	EXPECT_EQ(__NR_restart_syscall, ret);
++	/*
++	 * FIXME:
++	 * - native ARM registers do NOT expose true syscall.
++	 * - compat ARM registers on ARM64 DO expose true syscall.
++	 */
++	ASSERT_EQ(0, uname(&utsbuf));
++	if (strncmp(utsbuf.machine, "arm", 3) == 0) {
++		EXPECT_EQ(__NR_nanosleep, ret);
++	} else
+ #endif
++	{
++		EXPECT_EQ(__NR_restart_syscall, ret);
++	}
+ 
+-	/* Write again to end poll. */
++	/* Write again to end test. */
+ 	ASSERT_EQ(0, ptrace(PTRACE_CONT, child_pid, NULL, 0));
+ 	ASSERT_EQ(1, write(pipefd[1], "!", 1));
+ 	EXPECT_EQ(0, close(pipefd[1]));
diff --git a/tests/tests/os/jni/seccomp-tests/tests/seccomp_bpf_tests.c b/tests/tests/os/jni/seccomp-tests/tests/seccomp_bpf_tests.c
index 3c238e6..7481dd2 100644
--- a/tests/tests/os/jni/seccomp-tests/tests/seccomp_bpf_tests.c
+++ b/tests/tests/os/jni/seccomp-tests/tests/seccomp_bpf_tests.c
@@ -19,7 +19,6 @@
 #include <linux/prctl.h>
 #include <linux/ptrace.h>
 #include <linux/seccomp.h>
-#include <poll.h>
 #include <pthread.h>
 #include <semaphore.h>
 #include <signal.h>
@@ -28,6 +27,7 @@
 #include <string.h>
 #include <linux/elf.h>
 #include <sys/uio.h>
+#include <sys/utsname.h>
 #include <fcntl.h>  // ANDROID
 #include <sys/mman.h>
 #include <sys/times.h>
@@ -1798,7 +1798,8 @@
 }
 
 /* Make sure restarted syscalls are seen directly as "restart_syscall". */
-TEST(syscall_restart) {
+TEST(syscall_restart)
+{
 	long ret;
 	unsigned long msg;
 	pid_t child_pid;
@@ -1815,20 +1816,25 @@
 		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_read, 5, 0),
 		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_exit, 4, 0),
 		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_rt_sigreturn, 3, 0),
-		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_poll, 4, 0),
+		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_nanosleep, 4, 0),
 		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_restart_syscall, 4, 0),
 
 		/* Allow __NR_write for easy logging. */
 		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_write, 0, 1),
 		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
 		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_KILL),
-		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_TRACE|0x100), /* poll */
-		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_TRACE|0x200), /* restart */
+		/* The nanosleep jump target. */
+		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_TRACE|0x100),
+		/* The restart_syscall jump target. */
+		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_TRACE|0x200),
 	};
 	struct sock_fprog prog = {
-		.len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
+		.len = (unsigned short) (sizeof(filter)/sizeof(filter[0])),
 		.filter = filter,
 	};
+#if defined(__arm__)
+	struct utsname utsbuf;
+#endif
 
 	ASSERT_EQ(0, pipe(pipefd));
 
@@ -1837,10 +1843,7 @@
 	if (child_pid == 0) {
 		/* Child uses EXPECT not ASSERT to deliver status correctly. */
 		char buf = ' ';
-		struct pollfd fds = {
-			.fd = pipefd[0],
-			.events = POLLIN,
-		};
+		struct timespec timeout = { };
 
 		/* Attach parent as tracer and stop. */
 		EXPECT_EQ(0, ptrace(PTRACE_TRACEME));
@@ -1864,10 +1867,11 @@
 			TH_LOG("Failed to get sync data from read()");
 		}
 
-		/* Start poll to be interrupted. */
+		/* Start nanosleep to be interrupted. */
+		timeout.tv_sec = 1;
 		errno = 0;
-		EXPECT_EQ(1, poll(&fds, 1, -1)) {
-			TH_LOG("Call to poll() failed (errno %d)", errno);
+		EXPECT_EQ(0, nanosleep(&timeout, NULL)) {
+			TH_LOG("Call to nanosleep() failed (errno %d)", errno);
 		}
 
 		/* Read final sync from parent. */
@@ -1892,14 +1896,14 @@
 	ASSERT_EQ(0, ptrace(PTRACE_CONT, child_pid, NULL, 0));
 	ASSERT_EQ(1, write(pipefd[1], ".", 1));
 
-	/* Wait for poll() to start. */
+	/* Wait for nanosleep() to start. */
 	ASSERT_EQ(child_pid, waitpid(child_pid, &status, 0));
 	ASSERT_EQ(true, WIFSTOPPED(status));
 	ASSERT_EQ(SIGTRAP, WSTOPSIG(status));
 	ASSERT_EQ(PTRACE_EVENT_SECCOMP, (status >> 16));
 	ASSERT_EQ(0, ptrace(PTRACE_GETEVENTMSG, child_pid, NULL, &msg));
 	ASSERT_EQ(0x100, msg);
-	EXPECT_EQ(__NR_poll, get_syscall(_metadata, child_pid));
+	EXPECT_EQ(__NR_nanosleep, get_syscall(_metadata, child_pid));
 
 	/* Might as well check siginfo for sanity while we're here. */
 	ASSERT_EQ(0, ptrace(PTRACE_GETSIGINFO, child_pid, NULL, &info));
@@ -1910,7 +1914,7 @@
 	/* Verify signal delivery came from child (seccomp-triggered). */
 	EXPECT_EQ(child_pid, info.si_pid);
 
-	/* Interrupt poll with SIGSTOP (which we'll need to handle). */
+	/* Interrupt nanosleep with SIGSTOP (which we'll need to handle). */
 	ASSERT_EQ(0, kill(child_pid, SIGSTOP));
 	ASSERT_EQ(0, ptrace(PTRACE_CONT, child_pid, NULL, 0));
 	ASSERT_EQ(child_pid, waitpid(child_pid, &status, 0));
@@ -1920,7 +1924,7 @@
 	ASSERT_EQ(0, ptrace(PTRACE_GETSIGINFO, child_pid, NULL, &info));
 	EXPECT_EQ(getpid(), info.si_pid);
 
-	/* Restart poll with SIGCONT, which triggers restart_syscall. */
+	/* Restart nanosleep with SIGCONT, which triggers restart_syscall. */
 	ASSERT_EQ(0, kill(child_pid, SIGCONT));
 	ASSERT_EQ(0, ptrace(PTRACE_CONT, child_pid, NULL, 0));
 	ASSERT_EQ(child_pid, waitpid(child_pid, &status, 0));
@@ -1934,16 +1938,25 @@
 	ASSERT_EQ(SIGTRAP, WSTOPSIG(status));
 	ASSERT_EQ(PTRACE_EVENT_SECCOMP, (status >> 16));
 	ASSERT_EQ(0, ptrace(PTRACE_GETEVENTMSG, child_pid, NULL, &msg));
+
 	ASSERT_EQ(0x200, msg);
 	ret = get_syscall(_metadata, child_pid);
 #if defined(__arm__)
-	/* FIXME: ARM does not expose true syscall in registers. */
-	EXPECT_EQ(__NR_poll, ret);
-#else
-	EXPECT_EQ(__NR_restart_syscall, ret);
+	/*
+	 * FIXME:
+	 * - native ARM registers do NOT expose true syscall.
+	 * - compat ARM registers on ARM64 DO expose true syscall.
+	 */
+	ASSERT_EQ(0, uname(&utsbuf));
+	if (strncmp(utsbuf.machine, "arm", 3) == 0) {
+		EXPECT_EQ(__NR_nanosleep, ret);
+	} else
 #endif
+	{
+		EXPECT_EQ(__NR_restart_syscall, ret);
+	}
 
-	/* Write again to end poll. */
+	/* Write again to end test. */
 	ASSERT_EQ(0, ptrace(PTRACE_CONT, child_pid, NULL, 0));
 	ASSERT_EQ(1, write(pipefd[1], "!", 1));
 	EXPECT_EQ(0, close(pipefd[1]));
diff --git a/tests/tests/os/res/raw/test1_new.obb b/tests/tests/os/res/raw/test1_new.obb
new file mode 100644
index 0000000..450af90
--- /dev/null
+++ b/tests/tests/os/res/raw/test1_new.obb
Binary files differ
diff --git a/tests/tests/os/res/xml/alias.xml b/tests/tests/os/res/xml/alias.xml
index 1166669..98fb5b2 100644
--- a/tests/tests/os/res/xml/alias.xml
+++ b/tests/tests/os/res/xml/alias.xml
@@ -19,7 +19,7 @@
 
 <alias xmlns:android="http://schemas.android.com/apk/res/android">
     <intent android:action="android.intent.action.MAIN"
-        android:targetPackage="com.android.cts.os"
+        android:targetPackage="android.os.cts"
         android:targetClass="android.os.cts.ChildActivity"
         android:data="http://www.google.com/">
     </intent>
diff --git a/tests/tests/os/src/android/os/cts/AbiTest.java b/tests/tests/os/src/android/os/cts/AbiTest.java
index ee2c168..1d343e6 100644
--- a/tests/tests/os/src/android/os/cts/AbiTest.java
+++ b/tests/tests/os/src/android/os/cts/AbiTest.java
@@ -17,16 +17,35 @@
 package android.os.cts;
 
 import android.cts.util.ReadElf;
+import android.util.ArraySet;
 
 import java.io.File;
+import java.util.Arrays;
 
 import junit.framework.TestCase;
 
 public class AbiTest extends TestCase {
     public void testNo64() throws Exception {
-        for (String dir : new File("/").list()) {
-            if (!dir.equals("data") && !dir.equals("dev") && !dir.equals("proc") && !dir.equals("sys")) {
-                checkElfFilesInDirectory(new File("/" + dir));
+        ArraySet<String> abiDirs = new ArraySet(Arrays.asList(
+            "/sbin",
+            "/system",
+            "/vendor"));
+        String pathVar = System.getenv("PATH");
+        if (pathVar != null) {
+            abiDirs.addAll(Arrays.asList(pathVar.split(":")));
+        }
+        for (String dir : abiDirs) {
+            boolean skip_dir = false;
+            for (String dirOther : abiDirs) {
+                if (dir.equals(dirOther)) {
+                    continue;
+                } else if (dir.startsWith(dirOther + "/")) {
+                    skip_dir = true;
+                    break;
+                }
+            }
+            if (!skip_dir) {
+                checkElfFilesInDirectory(new File(dir));
             }
         }
     }
diff --git a/tests/tests/os/src/android/os/cts/BuildTest.java b/tests/tests/os/src/android/os/cts/BuildTest.java
index 26b07f1..a0446bf 100644
--- a/tests/tests/os/src/android/os/cts/BuildTest.java
+++ b/tests/tests/os/src/android/os/cts/BuildTest.java
@@ -38,15 +38,15 @@
 
     /** Tests that check the values of {@link Build#CPU_ABI} and {@link Build#CPU_ABI2}. */
     public void testCpuAbi() throws Exception {
-        testCpuAbiCommon();
+        runTestCpuAbiCommon();
         if (VMRuntime.getRuntime().is64Bit()) {
-            testCpuAbi64();
+            runTestCpuAbi64();
         } else {
-            testCpuAbi32();
+            runTestCpuAbi32();
         }
     }
 
-    private void testCpuAbiCommon() throws Exception {
+    private void runTestCpuAbiCommon() throws Exception {
         // The build property must match Build.SUPPORTED_ABIS exactly.
         final String[] abiListProperty = getStringList(RO_PRODUCT_CPU_ABILIST);
         assertEquals(Arrays.toString(abiListProperty), Arrays.toString(Build.SUPPORTED_ABIS));
@@ -75,7 +75,7 @@
         }
     }
 
-    private void testCpuAbi32() throws Exception {
+    private void runTestCpuAbi32() throws Exception {
         List<String> abi32 = Arrays.asList(Build.SUPPORTED_32_BIT_ABIS);
         assertTrue(abi32.contains(Build.CPU_ABI));
 
@@ -84,7 +84,7 @@
         }
     }
 
-    private void testCpuAbi64() {
+    private void runTestCpuAbi64() {
         List<String> abi64 = Arrays.asList(Build.SUPPORTED_64_BIT_ABIS);
         assertTrue(abi64.contains(Build.CPU_ABI));
 
diff --git a/tests/tests/os/src/android/os/cts/BundleTest.java b/tests/tests/os/src/android/os/cts/BundleTest.java
index 0db5fd0..36326b3 100644
--- a/tests/tests/os/src/android/os/cts/BundleTest.java
+++ b/tests/tests/os/src/android/os/cts/BundleTest.java
@@ -730,6 +730,26 @@
         assertTrue(mBundle.hasFileDescriptors());
     }
 
+    public void testHasFileDescriptorsOnNullValuedCollection() {
+        assertFalse(mBundle.hasFileDescriptors());
+
+        mBundle.putParcelableArray("foo", new Parcelable[1]);
+        assertFalse(mBundle.hasFileDescriptors());
+        mBundle.clear();
+
+        SparseArray<Parcelable> sparseArray = new SparseArray<Parcelable>();
+        sparseArray.put(0, null);
+        mBundle.putSparseParcelableArray("bar", sparseArray);
+        assertFalse(mBundle.hasFileDescriptors());
+        mBundle.clear();
+
+        ArrayList<Parcelable> arrayList = new ArrayList<Parcelable>();
+        arrayList.add(null);
+        mBundle.putParcelableArrayList("baz", arrayList);
+        assertFalse(mBundle.hasFileDescriptors());
+        mBundle.clear();
+    }
+
     public void testSetClassLoader() {
         mBundle.setClassLoader(new MockClassLoader());
     }
diff --git a/tests/tests/os/src/android/os/cts/CustomClassLoaderTest.java b/tests/tests/os/src/android/os/cts/CustomClassLoaderTest.java
index bd88073..4c4804e 100644
--- a/tests/tests/os/src/android/os/cts/CustomClassLoaderTest.java
+++ b/tests/tests/os/src/android/os/cts/CustomClassLoaderTest.java
@@ -19,6 +19,7 @@
 import java.io.*;
 import java.lang.reflect.*;
 
+import android.platform.test.annotations.Presubmit;
 import android.test.AndroidTestCase;
 
 public class CustomClassLoaderTest extends AndroidTestCase {
@@ -76,6 +77,7 @@
 
     /* Test a custom class loader based on the PathClassLoader.
      */
+    @Presubmit
     public void testCustomPathClassLoader() throws Exception {
         // Try to load the TestClass class by the CustomPathClassLoader.
         try {
diff --git a/tests/tests/os/src/android/os/cts/MessengerTest.java b/tests/tests/os/src/android/os/cts/MessengerTest.java
index 72bf247..5bf9428 100644
--- a/tests/tests/os/src/android/os/cts/MessengerTest.java
+++ b/tests/tests/os/src/android/os/cts/MessengerTest.java
@@ -30,6 +30,7 @@
 import android.os.Messenger;
 import android.os.Parcel;
 import android.os.RemoteException;
+import android.os.ResultReceiver;
 import android.test.AndroidTestCase;
 
 import java.io.FileDescriptor;
@@ -88,6 +89,11 @@
         public void dumpAsync(FileDescriptor fd, String[] args) throws RemoteException {
         }
 
+        @Override
+        public void shellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
+                String[] args, ResultReceiver resultReceiver) {
+        }
+
     };
 
     // Create another messenger to send msg.
diff --git a/tests/tests/os/src/android/os/cts/ParcelFileDescriptorProcessTest.java b/tests/tests/os/src/android/os/cts/ParcelFileDescriptorProcessTest.java
index 679a35c..a6a6b99 100644
--- a/tests/tests/os/src/android/os/cts/ParcelFileDescriptorProcessTest.java
+++ b/tests/tests/os/src/android/os/cts/ParcelFileDescriptorProcessTest.java
@@ -89,10 +89,10 @@
         // Bring up both remote processes and wire them to each other
         redIntent = new Intent();
         redIntent.setComponent(new ComponentName(
-                "com.android.cts.os", "android.os.cts.ParcelFileDescriptorPeer$Red"));
+                "android.os.cts", "android.os.cts.ParcelFileDescriptorPeer$Red"));
         blueIntent = new Intent();
         blueIntent.setComponent(new ComponentName(
-                "com.android.cts.os", "android.os.cts.ParcelFileDescriptorPeer$Blue"));
+                "android.os.cts", "android.os.cts.ParcelFileDescriptorPeer$Blue"));
         redConn = new PeerConnection();
         blueConn = new PeerConnection();
         context.startService(redIntent);
diff --git a/tests/tests/os/src/android/os/cts/ParcelFileDescriptorTest.java b/tests/tests/os/src/android/os/cts/ParcelFileDescriptorTest.java
index 3bcc4b9..f51af76 100644
--- a/tests/tests/os/src/android/os/cts/ParcelFileDescriptorTest.java
+++ b/tests/tests/os/src/android/os/cts/ParcelFileDescriptorTest.java
@@ -372,7 +372,7 @@
 
         FileOutputStream fout = null;
 
-        fout = con.openFileOutput(fileName, Context.MODE_WORLD_WRITEABLE);
+        fout = con.openFileOutput(fileName, Context.MODE_PRIVATE);
 
         try {
             fout.write(new byte[] { 0x0, 0x1, 0x2, 0x3 });
diff --git a/tests/tests/os/src/android/os/cts/StrictModeTest.java b/tests/tests/os/src/android/os/cts/StrictModeTest.java
index 2407309..a345256 100644
--- a/tests/tests/os/src/android/os/cts/StrictModeTest.java
+++ b/tests/tests/os/src/android/os/cts/StrictModeTest.java
@@ -108,9 +108,9 @@
     }
 
     private boolean hasInternetConnection() {
-        // TODO: expand this to include devices with ethernet
         final PackageManager pm = getContext().getPackageManager();
         return pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)
-                || pm.hasSystemFeature(PackageManager.FEATURE_WIFI);
+                || pm.hasSystemFeature(PackageManager.FEATURE_WIFI)
+                || pm.hasSystemFeature(PackageManager.FEATURE_ETHERNET);
     }
 }
diff --git a/tests/tests/os/src/android/os/health/cts/HealthStatsTest.java b/tests/tests/os/src/android/os/health/cts/HealthStatsTest.java
new file mode 100644
index 0000000..cc7201a
--- /dev/null
+++ b/tests/tests/os/src/android/os/health/cts/HealthStatsTest.java
@@ -0,0 +1,252 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.os.health.cts;
+
+import android.os.Parcel;
+import android.os.health.HealthKeys;
+import android.os.health.HealthStats;
+import android.os.health.HealthStatsParceler;
+import android.os.health.HealthStatsWriter;
+import android.os.health.TimerStat;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+import java.util.Map;
+
+/**
+ * Provides test cases for android.os.health.HealthStats and HealthStatsWriter.
+ */
+public class HealthStatsTest extends TestCase {
+    @HealthKeys.Constant(type=HealthKeys.TYPE_TIMER)
+    public static final int TIMER_0 = 10;
+
+    @HealthKeys.Constant(type=HealthKeys.TYPE_TIMER)
+    public static final int TIMER_1 = 11;
+
+    @HealthKeys.Constant(type=HealthKeys.TYPE_MEASUREMENT)
+    public static final int MEASUREMENT_0 = 20;
+
+    @HealthKeys.Constant(type=HealthKeys.TYPE_MEASUREMENT)
+    public static final int MEASUREMENT_1 = 21;
+
+    @HealthKeys.Constant(type=HealthKeys.TYPE_MEASUREMENT)
+    public static final int MEASUREMENT_2 = 21;
+
+    @HealthKeys.Constant(type=HealthKeys.TYPE_STATS)
+    public static final int STATS_0 = 30;
+
+    @HealthKeys.Constant(type=HealthKeys.TYPE_TIMERS)
+    public static final int TIMERS_0 = 30;
+
+    @HealthKeys.Constant(type=HealthKeys.TYPE_MEASUREMENTS)
+    public static final int MEASUREMENTS_0 = 40;
+
+    @HealthKeys.Constant(type=HealthKeys.TYPE_MEASUREMENTS)
+    public static final int MEASUREMENTS_1 = 41;
+
+
+    public static final HealthKeys.Constants CONSTANTS
+            = new HealthKeys.Constants(HealthStatsTest.class);
+
+    /**
+     * Check all the fields.
+     */
+    private void checkHealthStats(HealthStats readback) {
+        // Header fields
+        Assert.assertEquals("HealthStatsTest", readback.getDataType());
+
+
+        // TimerStat fields
+        Assert.assertEquals(2, readback.getTimerKeyCount());
+
+        Assert.assertEquals(TIMER_0, readback.getTimerKeyAt(0));
+        Assert.assertTrue(readback.hasTimer(TIMER_0));
+        Assert.assertEquals(1, readback.getTimerCount(TIMER_0));
+        Assert.assertEquals(100, readback.getTimerTime(TIMER_0));
+
+        Assert.assertEquals(TIMER_1, readback.getTimerKeyAt(1));
+        Assert.assertTrue(readback.hasTimer(TIMER_1));
+        Assert.assertEquals(Integer.MAX_VALUE, readback.getTimerCount(TIMER_1));
+        Assert.assertEquals(Long.MAX_VALUE, readback.getTimerTime(TIMER_1));
+
+        Assert.assertEquals(Integer.MAX_VALUE, readback.getTimer(TIMER_1).getCount());
+        Assert.assertEquals(Long.MAX_VALUE, readback.getTimer(TIMER_1).getTime());
+
+
+        // Measurement fields
+        Assert.assertEquals(2, readback.getMeasurementKeyCount());
+
+        Assert.assertEquals(MEASUREMENT_0, readback.getMeasurementKeyAt(0));
+        Assert.assertTrue(readback.hasMeasurement(MEASUREMENT_0));
+        Assert.assertEquals(300, readback.getMeasurement(MEASUREMENT_0));
+
+        Assert.assertEquals(MEASUREMENT_1, readback.getMeasurementKeyAt(1));
+        Assert.assertTrue(readback.hasMeasurement(MEASUREMENT_1));
+        Assert.assertEquals(Long.MAX_VALUE, readback.getMeasurement(MEASUREMENT_1));
+        
+
+        // Stats fields
+        Assert.assertEquals(1, readback.getStatsKeyCount());
+
+        Assert.assertEquals(STATS_0, readback.getStatsKeyAt(0));
+        Assert.assertTrue(readback.hasStats(STATS_0));
+
+        final Map<String,HealthStats> stats = readback.getStats(STATS_0);
+        Assert.assertEquals(1, stats.size());
+        final HealthStats child = stats.get("a");
+        Assert.assertEquals(0, child.getTimerKeyCount());
+        Assert.assertEquals(1, child.getMeasurementKeyCount());
+        Assert.assertEquals(Long.MIN_VALUE, child.getMeasurement(MEASUREMENT_2));
+        Assert.assertEquals(0, child.getStatsKeyCount());
+        Assert.assertEquals(0, child.getTimersKeyCount());
+
+
+        // Timers fields
+        Assert.assertEquals(1, readback.getTimersKeyCount());
+
+        Assert.assertEquals(TIMERS_0, readback.getTimersKeyAt(0));
+        Assert.assertTrue(readback.hasTimers(TIMERS_0));
+        final Map<String,TimerStat> timers = readback.getTimers(TIMERS_0);
+        Assert.assertEquals(1, timers.size());
+        Assert.assertEquals(200, timers.get("b").getCount());
+        Assert.assertEquals(400, timers.get("b").getTime());
+
+
+        // Measurements fields
+        Map<String,Long> measurements;
+        Assert.assertEquals(2, readback.getMeasurementsKeyCount());
+
+        Assert.assertEquals(MEASUREMENTS_0, readback.getMeasurementsKeyAt(0));
+        Assert.assertTrue(readback.hasMeasurements(MEASUREMENTS_0));
+        measurements = readback.getMeasurements(MEASUREMENTS_0);
+        Assert.assertEquals(1, measurements.size());
+        Assert.assertEquals(800L, measurements.get("Z").longValue());
+
+        Assert.assertEquals(MEASUREMENTS_1, readback.getMeasurementsKeyAt(1));
+        measurements = readback.getMeasurements(MEASUREMENTS_1);
+        Assert.assertTrue(readback.hasMeasurements(MEASUREMENTS_1));
+        Assert.assertEquals(2, measurements.size());
+        Assert.assertEquals(900L, measurements.get("Y").longValue());
+        Assert.assertEquals(901L, measurements.get("X").longValue());
+    }
+
+    /**
+     * Tests parceling empty HealthStats.
+     */
+    @SmallTest
+    public void testParcelEmpty() throws Exception {
+        final HealthStatsWriter writer = new HealthStatsWriter(CONSTANTS);
+
+        Parcel parcel = Parcel.obtain();
+        writer.flattenToParcel(parcel);
+
+        parcel.setDataPosition(0);
+
+        HealthStats readback = new HealthStats(parcel);
+
+        // Check that there is no more data in the parcel
+        Assert.assertEquals(0, parcel.dataAvail());
+        parcel.recycle();
+        
+        Assert.assertEquals(0, readback.getTimerKeyCount());
+        Assert.assertEquals(0, readback.getMeasurementKeyCount());
+        Assert.assertEquals(0, readback.getStatsKeyCount());
+        Assert.assertEquals(0, readback.getTimersKeyCount());
+        Assert.assertEquals(0, readback.getMeasurementsKeyCount());
+    }
+
+
+    /**
+     * Tests parceling HealthStats.
+     */
+    @SmallTest
+    public void testParcelling() throws Exception {
+        final HealthStatsWriter writer = new HealthStatsWriter(CONSTANTS);
+
+        // TimerStat
+        writer.addTimer(TIMER_0, 1, 100);
+        writer.addTimer(TIMER_1, Integer.MAX_VALUE, Long.MAX_VALUE);
+
+        // Measurement
+        writer.addMeasurement(MEASUREMENT_0, 300);
+        writer.addMeasurement(MEASUREMENT_1, Long.MAX_VALUE);
+
+        // Stats
+        HealthStatsWriter writer2 = new HealthStatsWriter(CONSTANTS);
+        writer2.addMeasurement(MEASUREMENT_2, Long.MIN_VALUE);
+        writer.addStats(STATS_0, "a", writer2);
+
+        // Timers
+        writer.addTimers(TIMERS_0, "b", new TimerStat(200, 400));
+
+        // Measurements
+        writer.addMeasurements(MEASUREMENTS_0, "Z", 800);
+        writer.addMeasurements(MEASUREMENTS_1, "Y", 900);
+        writer.addMeasurements(MEASUREMENTS_1, "X", 901);
+
+
+        // Parcel and unparcel it via HealthStatsWriter.writeToParcel.
+        Parcel parcel = Parcel.obtain();
+        writer.flattenToParcel(parcel);
+        parcel.setDataPosition(0);
+        HealthStats readback = new HealthStats(parcel);
+        
+        // Check that there is no more data in the parcel
+        Assert.assertEquals(0, parcel.dataAvail());
+        parcel.recycle();
+        
+        checkHealthStats(readback);
+    }
+
+    /**
+     * Tests the HealthStatsParceler.
+     */
+    @SmallTest
+    public void testParceler() throws Exception {
+        final HealthStatsWriter writer = new HealthStatsWriter(CONSTANTS);
+        writer.addMeasurement(MEASUREMENT_0, 300);
+
+        final HealthStatsParceler parceler = new HealthStatsParceler(writer);
+
+        final Parcel parcel = Parcel.obtain();
+        parceler.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+
+        final HealthStatsParceler parceler2 = new HealthStatsParceler(parcel);
+
+        // Check that there is no more data in the parcel
+        Assert.assertEquals(0, parcel.dataAvail());
+        parcel.recycle();
+
+        final HealthStats readback = parceler2.getHealthStats();
+        
+        Assert.assertEquals(300, readback.getMeasurement(MEASUREMENT_0));
+
+        // Should fail
+        try {
+            final Parcel parcel2 = Parcel.obtain();
+            parceler2.writeToParcel(parcel2, 0);
+            parcel2.recycle();
+            throw new Exception("Expected IndexOutOfBoundsException");
+        } catch (RuntimeException ex) {
+            // expected
+        }
+    }
+}
+
diff --git a/tests/tests/os/src/android/os/health/cts/SystemHealthManagerTest.java b/tests/tests/os/src/android/os/health/cts/SystemHealthManagerTest.java
new file mode 100644
index 0000000..1ce3086
--- /dev/null
+++ b/tests/tests/os/src/android/os/health/cts/SystemHealthManagerTest.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.os.health.cts;
+
+import android.content.Context;
+import android.os.Parcel;
+import android.os.Process;
+import android.os.health.SystemHealthManager;
+import android.os.health.HealthStats;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.test.InstrumentationTestCase;
+
+import junit.framework.Assert;
+
+/**
+ * Provides test cases for android.os.health.TimerStat.
+ */
+public class SystemHealthManagerTest extends InstrumentationTestCase {
+    /**
+     * Tests that takeMyUidSnapshot returns a HealthStats object.
+     */
+    @SmallTest
+    public void testTakeMyUidSnapshot() throws Exception {
+        final Context context = getInstrumentation().getTargetContext();
+        final SystemHealthManager healthy = SystemHealthManager.from(context);
+
+        Assert.assertNotNull(healthy.takeMyUidSnapshot());
+    }
+
+    /**
+     * Tests that takeUidSnapshot with this uid returns a HealthStats object.
+     */
+    @SmallTest
+    public void testTakeUidSnapshotWithMe() throws Exception {
+        final Context context = getInstrumentation().getTargetContext();
+        final SystemHealthManager healthy = SystemHealthManager.from(context);
+
+        Assert.assertNotNull(healthy.takeUidSnapshot(Process.myUid()));
+    }
+
+    /**
+     * Tests that takeUidSnapshot on the system process throws a SecurityException.
+     */
+    @SmallTest
+    public void testTakeMyUidSnapshotWithSystem() throws Exception {
+        final Context context = getInstrumentation().getTargetContext();
+        final SystemHealthManager healthy = SystemHealthManager.from(context);
+
+        boolean threw = false;
+        try {
+            healthy.takeUidSnapshot(Process.SYSTEM_UID);
+        } catch (SecurityException ex) {
+            threw = true;
+        }
+
+        Assert.assertTrue(threw);
+    }
+
+    /**
+     * Tests that takeUidSnapshots with an empty array returns an empty array.
+     */
+    @SmallTest
+    public void testTakeUidSnapshotsWithEmptyArray() throws Exception {
+        final Context context = getInstrumentation().getTargetContext();
+        final SystemHealthManager healthy = SystemHealthManager.from(context);
+
+        final HealthStats[] result = healthy.takeUidSnapshots(new int[0]);
+        Assert.assertEquals(0, result.length);
+    }
+
+    /**
+     * Tests that takeUidSnapshots with this uid returns a HealthStats object.
+     */
+    @SmallTest
+    public void testTakeUidSnapshotsWithMe() throws Exception {
+        final Context context = getInstrumentation().getTargetContext();
+        final SystemHealthManager healthy = SystemHealthManager.from(context);
+
+        final HealthStats[] result = healthy.takeUidSnapshots(new int[] {
+                    Process.myUid(),
+                    Process.myUid(),
+                });
+        Assert.assertEquals(2, result.length);
+        Assert.assertNotNull(result[0]);
+        Assert.assertNotNull(result[1]);
+    }
+
+    /**
+     * Tests that takeUidSnapshot on the system process throws a SecurityException.
+     */
+    @SmallTest
+    public void testTakeMyUidSnapshotsWithSystem() throws Exception {
+        final Context context = getInstrumentation().getTargetContext();
+        final SystemHealthManager healthy = SystemHealthManager.from(context);
+
+        boolean threw = false;
+        try {
+            healthy.takeUidSnapshots(new int[] {
+                        Process.myUid(),
+                        Process.SYSTEM_UID,
+                    });
+        } catch (SecurityException ex) {
+            threw = true;
+        }
+
+        Assert.assertTrue(threw);
+    }
+}
+
diff --git a/tests/tests/os/src/android/os/health/cts/TimerStatTest.java b/tests/tests/os/src/android/os/health/cts/TimerStatTest.java
new file mode 100644
index 0000000..f8e27fe
--- /dev/null
+++ b/tests/tests/os/src/android/os/health/cts/TimerStatTest.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.os.health.cts;
+
+import android.os.Parcel;
+import android.os.health.TimerStat;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+/**
+ * Provides test cases for android.os.health.TimerStat.
+ */
+public class TimerStatTest extends TestCase {
+    /**
+     * Tests empty constructor and get methods.
+     */
+    @SmallTest
+    public void testEmptyConstructor() throws Exception {
+        TimerStat timer = new TimerStat();
+
+        Assert.assertEquals(0, timer.getCount());
+        Assert.assertEquals(0, timer.getTime());
+    }
+
+    /**
+     * Tests setCount.
+     */
+    @SmallTest
+    public void testSetCount() throws Exception {
+        TimerStat timer = new TimerStat(Integer.MAX_VALUE, Long.MAX_VALUE);
+
+        Assert.assertEquals(Integer.MAX_VALUE, timer.getCount());
+
+        timer.setCount(12);
+
+        Assert.assertEquals(12, timer.getCount());
+        Assert.assertEquals(Long.MAX_VALUE, timer.getTime());
+    }
+
+    /**
+     * Tests setTime.
+     */
+    @SmallTest
+    public void testSetTime() throws Exception {
+        TimerStat timer = new TimerStat(Integer.MAX_VALUE, Long.MAX_VALUE);
+
+        Assert.assertEquals(Integer.MAX_VALUE, timer.getCount());
+
+        timer.setTime(5000);
+
+        Assert.assertEquals(Integer.MAX_VALUE, timer.getCount());
+        Assert.assertEquals(5000, timer.getTime());
+    }
+
+    /**
+     * Tests writeToParcel and reading a parcel.
+     */
+    @SmallTest
+    public void testParceling() throws Exception {
+        TimerStat timer = new TimerStat(Integer.MAX_VALUE, Long.MAX_VALUE);
+
+        Assert.assertEquals(Integer.MAX_VALUE, timer.getCount());
+        Assert.assertEquals(Long.MAX_VALUE, timer.getTime());
+        Assert.assertEquals(0, timer.describeContents());
+
+        Parcel parcel = Parcel.obtain();
+        timer.writeToParcel(parcel, 0);
+
+        parcel.setDataPosition(0);
+
+        TimerStat readback = new TimerStat(parcel);
+
+        Assert.assertEquals(Integer.MAX_VALUE, readback.getCount());
+        Assert.assertEquals(Long.MAX_VALUE, readback.getTime());
+    }
+}
+
diff --git a/tests/tests/os/src/android/os/storage/cts/StorageManagerTest.java b/tests/tests/os/src/android/os/storage/cts/StorageManagerTest.java
index a8e8e64..f9a58ad 100644
--- a/tests/tests/os/src/android/os/storage/cts/StorageManagerTest.java
+++ b/tests/tests/os/src/android/os/storage/cts/StorageManagerTest.java
@@ -16,15 +16,17 @@
 
 package android.os.storage.cts;
 
-import com.android.cts.os.R;
+import android.os.cts.R;
 
 import android.content.Context;
 import android.content.res.Resources;
 import android.content.res.Resources.NotFoundException;
 import android.os.Environment;
+import android.os.Parcel;
 import android.cts.util.FileUtils;
 import android.os.storage.OnObbStateChangeListener;
 import android.os.storage.StorageManager;
+import android.os.storage.StorageVolume;
 import android.test.AndroidTestCase;
 import android.test.ComparisonFailure;
 import android.util.Log;
@@ -35,6 +37,8 @@
 import java.io.FileInputStream;
 import java.io.InputStream;
 import java.io.IOException;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
@@ -47,7 +51,7 @@
     private static final long WAIT_TIME_INCR = 5*1000;
 
     private static final String OBB_MOUNT_PREFIX = "/mnt/obb/";
-    private static final String TEST1_CONTENTS = "1\n";
+    private static final String TEST1_NEW_CONTENTS = "1\n";
 
     private StorageManager mStorageManager;
 
@@ -59,16 +63,16 @@
 
     public void testMountAndUnmountObbNormal() throws IOException {
         for (File target : getTargetFiles()) {
-            target = new File(target, "test1.obb");
+            target = new File(target, "test1_new.obb");
             Log.d(TAG, "Testing path " + target);
             doMountAndUnmountObbNormal(target);
         }
     }
 
     private void doMountAndUnmountObbNormal(File outFile) throws IOException {
-        final String canonPath = mountObb(R.raw.test1, outFile, OnObbStateChangeListener.MOUNTED);
+        final String canonPath = mountObb(R.raw.test1_new, outFile, OnObbStateChangeListener.MOUNTED);
 
-        mountObb(R.raw.test1, outFile, OnObbStateChangeListener.ERROR_ALREADY_MOUNTED);
+        mountObb(R.raw.test1_new, outFile, OnObbStateChangeListener.ERROR_ALREADY_MOUNTED);
 
         try {
             final String mountPath = checkMountedPath(canonPath);
@@ -77,7 +81,7 @@
 
             assertTrue("OBB mounted path should be a directory", mountDir.isDirectory());
             assertTrue("test1.txt does not exist in OBB dir", testFile.exists());
-            assertFileContains(testFile, TEST1_CONTENTS);
+            assertFileContains(testFile, TEST1_NEW_CONTENTS);
         } finally {
             unmountObb(outFile, OnObbStateChangeListener.UNMOUNTED);
         }
@@ -130,8 +134,8 @@
     }
 
     private void doMountAndUnmountTwoObbs(File file1, File file2) throws IOException {
-        ObbObserver oo1 = mountObbWithoutWait(R.raw.test1, file1);
-        ObbObserver oo2 = mountObbWithoutWait(R.raw.test1, file2);
+        ObbObserver oo1 = mountObbWithoutWait(R.raw.test1_new, file1);
+        ObbObserver oo2 = mountObbWithoutWait(R.raw.test1_new, file2);
 
         Log.d(TAG, "Waiting for OBB #1 to complete mount");
         waitForObbActionCompletion(file1, oo1, OnObbStateChangeListener.MOUNTED);
@@ -144,20 +148,114 @@
             final File testFile1 = new File(mountDir1, "test1.txt");
             assertTrue("OBB mounted path should be a directory", mountDir1.isDirectory());
             assertTrue("test1.txt does not exist in OBB dir", testFile1.exists());
-            assertFileContains(testFile1, TEST1_CONTENTS);
+            assertFileContains(testFile1, TEST1_NEW_CONTENTS);
 
             final String mountPath2 = checkMountedPath(oo2.getPath());
             final File mountDir2 = new File(mountPath2);
             final File testFile2 = new File(mountDir2, "test1.txt");
             assertTrue("OBB mounted path should be a directory", mountDir2.isDirectory());
             assertTrue("test1.txt does not exist in OBB dir", testFile2.exists());
-            assertFileContains(testFile2, TEST1_CONTENTS);
+            assertFileContains(testFile2, TEST1_NEW_CONTENTS);
         } finally {
             unmountObb(file1, OnObbStateChangeListener.UNMOUNTED);
             unmountObb(file2, OnObbStateChangeListener.UNMOUNTED);
         }
     }
 
+    public void testGetPrimaryVolume() throws Exception {
+        final StorageVolume volume = mStorageManager.getPrimaryStorageVolume();
+        assertNotNull("Did not get primary storage", volume);
+
+        // Tests some basic Scoped Directory Access requests.
+        assertNull("Should not grant access for root directory", volume.createAccessIntent(null));
+        assertNull("Should not grant access for invalid directory",
+                volume.createAccessIntent("/system"));
+        assertNotNull("Should grant access for valid directory " + Environment.DIRECTORY_DOCUMENTS,
+                volume.createAccessIntent(Environment.DIRECTORY_DOCUMENTS));
+
+        // Tests basic properties.
+        assertNotNull("Should have description", volume.getDescription(mContext));
+        assertTrue("Should be primary", volume.isPrimary());
+        assertEquals("Wrong state", Environment.MEDIA_MOUNTED, volume.getState());
+
+        // Tests properties that depend on storage type (emulated or physical)
+        final String uuid = volume.getUuid();
+        final boolean removable = volume.isRemovable();
+        final boolean emulated = volume.isEmulated();
+        if (emulated) {
+            assertFalse("Should not be removable", removable);
+            assertNull("Should not have uuid", uuid);
+        } else {
+            assertTrue("Should be removable", removable);
+            assertNotNull("Should have uuid", uuid);
+        }
+
+        // Tests path - although it's not a public API, sm.getPrimaryStorageVolume()
+        // explicitly states it should match Environment#getExternalStorageDirectory
+        final String path = volume.getPath();
+        assertEquals("Path does not match Environment's",
+                Environment.getExternalStorageDirectory().getAbsolutePath(), path);
+
+        // Tests Parcelable contract.
+        assertEquals("Wrong describeContents", 0, volume.describeContents());
+        final Parcel parcel = Parcel.obtain();
+        try {
+            volume.writeToParcel(parcel, 0);
+            parcel.setDataPosition(0);
+            final StorageVolume clone = StorageVolume.CREATOR.createFromParcel(parcel);
+            assertStorageVolumesEquals(volume, clone);
+        } finally {
+            parcel.recycle();
+        }
+    }
+
+    public void testGetStorageVolumes() throws Exception {
+        final List<StorageVolume> volumes = mStorageManager.getStorageVolumes();
+        assertFalse("No volume return", volumes.isEmpty());
+        StorageVolume primary = null;
+        for (StorageVolume volume : volumes) {
+            if (volume.isPrimary()) {
+                assertNull("There can be only one primary volume: " + volumes, primary);
+                primary = volume;
+            }
+        }
+        assertNotNull("No primary volume on  " + volumes, primary);
+        assertStorageVolumesEquals(primary, mStorageManager.getPrimaryVolume());
+    }
+
+    public void testGetStorageVolume() throws Exception {
+        assertNull("Should not get volume for null path", mStorageManager.getStorageVolume(null));
+        assertNull("Should not get volume for invalid path",
+                mStorageManager.getStorageVolume(new File("/system")));
+        assertNull("Should not get volume for storage directory",
+                mStorageManager.getStorageVolume(Environment.getStorageDirectory()));
+
+        final File root = Environment.getExternalStorageDirectory();
+        final StorageVolume primary = mStorageManager.getPrimaryStorageVolume();
+        final StorageVolume rootVolume = mStorageManager.getStorageVolume(root);
+        assertNotNull("No volume for root (" + root + ")", rootVolume);
+        assertStorageVolumesEquals(primary, rootVolume);
+
+        final File child = new File(root, "child");
+        StorageVolume childVolume = mStorageManager.getStorageVolume(child);
+        assertNotNull("No volume for child (" + child + ")", childVolume);
+        assertStorageVolumesEquals(primary, childVolume);
+    }
+
+    private void assertStorageVolumesEquals(StorageVolume volume, StorageVolume clone)
+            throws Exception {
+        // Asserts equals() method.
+        assertEquals("StorageVolume.equals() mismatch", volume, clone);
+        // Make sure all fields match.
+        for (Field field : StorageVolume.class.getDeclaredFields()) {
+            if (Modifier.isStatic(field.getModifiers())) continue;
+            field.setAccessible(true);
+            final Object originalValue = field.get(volume);
+            final Object clonedValue = field.get(clone);
+            assertEquals("Mismatch for field " + field.getName(), originalValue, clonedValue);
+        }
+    }
+
     private static void assertStartsWith(String message, String prefix, String actual) {
         if (!actual.startsWith(prefix)) {
             throw new ComparisonFailure(message, prefix, actual);
@@ -241,11 +339,22 @@
         } catch (NotFoundException e) {
             fail("Failed to load resource with id: " + rawResId);
         }
-        FileUtils.setPermissions(outFile.getPath(), FileUtils.S_IRWXU | FileUtils.S_IRWXG
-                | FileUtils.S_IRWXO);
         assertTrue(FileUtils.copyToFile(is, outFile));
-        FileUtils.setPermissions(outFile.getPath(), FileUtils.S_IRWXU | FileUtils.S_IRWXG
-                | FileUtils.S_IRWXO);
+        exposeFile(outFile);
+    }
+
+    private File exposeFile(File file) {
+        file.setReadable(true, false);
+        file.setReadable(true, true);
+
+        File dir = file.getParentFile();
+        do {
+            dir.setExecutable(true, false);
+            dir.setExecutable(true, true);
+            dir = dir.getParentFile();
+        } while (dir != null);
+
+        return file;
     }
 
     private String mountObb(final int resource, final File file, int expectedState) {
@@ -297,7 +406,7 @@
     private void unmountObb(final File file, int expectedState) {
         final ObbObserver observer = new ObbObserver();
 
-        assertTrue("unmountObb call on test1.obb should succeed",
+        assertTrue("unmountObb call on test1_new.obb should succeed",
                 mStorageManager.unmountObb(file.getPath(), false, observer));
 
         assertTrue("Unmount should have completed",
diff --git a/tests/tests/permission/Android.mk b/tests/tests/permission/Android.mk
index 6a7da5f..c37ddfc 100644
--- a/tests/tests/permission/Android.mk
+++ b/tests/tests/permission/Android.mk
@@ -19,14 +19,20 @@
 
 LOCAL_MODULE_TAGS := tests
 
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 # Include both the 32 and 64 bit versions
 LOCAL_MULTILIB := both
 
 LOCAL_JAVA_LIBRARIES := telephony-common
 
-LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner guava android-ex-camera2
+LOCAL_STATIC_JAVA_LIBRARIES := \
+    ctstestrunner guava android-ex-camera2 platform-test-annotations
 
-LOCAL_JNI_SHARED_LIBRARIES := libctspermission_jni
+LOCAL_JNI_SHARED_LIBRARIES := libctspermission_jni libnativehelper_compat_libc++
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
diff --git a/tests/tests/permission/AndroidManifest.xml b/tests/tests/permission/AndroidManifest.xml
index fa03335..8b08009 100644
--- a/tests/tests/permission/AndroidManifest.xml
+++ b/tests/tests/permission/AndroidManifest.xml
@@ -16,7 +16,7 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.permission">
+    package="android.permission.cts">
 
     <uses-permission android:name="android.permission.INJECT_EVENTS" />
     <application>
@@ -41,8 +41,8 @@
         relies on hidden APIs.
     -->
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.cts.permission"
-                     android:label="CTS tests of com.android.cts.permission">
+                     android:targetPackage="android.permission.cts"
+                     android:label="CTS tests of android.permission">
         <meta-data android:name="listener"
             android:value="com.android.cts.runner.CtsTestRunListener" />
     </instrumentation>
diff --git a/tests/tests/permission/AndroidTest.xml b/tests/tests/permission/AndroidTest.xml
new file mode 100644
index 0000000..f64db70
--- /dev/null
+++ b/tests/tests/permission/AndroidTest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS Permission test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsPermissionTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.permission.cts" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/tests/permission/jni/Android.mk b/tests/tests/permission/jni/Android.mk
index 44e742e..ea45096 100644
--- a/tests/tests/permission/jni/Android.mk
+++ b/tests/tests/permission/jni/Android.mk
@@ -27,6 +27,7 @@
 
 LOCAL_C_INCLUDES := $(JNI_H_INCLUDE) 
 
-LOCAL_SHARED_LIBRARIES := libnativehelper liblog
+LOCAL_SHARED_LIBRARIES := libnativehelper_compat_libc++ liblog
+LOCAL_SDK_VERSION := 23
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/tests/tests/permission/jni/android_permission_cts_FileUtils.cpp b/tests/tests/permission/jni/android_permission_cts_FileUtils.cpp
index 8f32027..0547be4 100644
--- a/tests/tests/permission/jni/android_permission_cts_FileUtils.cpp
+++ b/tests/tests/permission/jni/android_permission_cts_FileUtils.cpp
@@ -14,9 +14,9 @@
  * limitations under the License.
  */
 
+#include <android/log.h>
 #include <jni.h>
 #include <stdio.h>
-#include <cutils/log.h>
 #include <linux/xattr.h>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -104,7 +104,8 @@
                               sizeof(capData));
     if (result <= 0)
     {
-          ALOGD("isPermittedCapBitSet(): getxattr(\"%s\") call failed: "
+          __android_log_print(ANDROID_LOG_DEBUG, NULL,
+                  "isPermittedCapBitSet(): getxattr(\"%s\") call failed: "
                   "return %d (error: %s (%d))\n",
                   cPath.c_str(), result, strerror(errno), errno);
           return false;
@@ -132,7 +133,8 @@
     ScopedLocalRef<jclass> eClazz(env, env->FindClass(className));
     if (eClazz.get() == NULL)
     {
-        ALOGE("throwNamedException(): failed to find class %s, cannot throw",
+        __android_log_print(ANDROID_LOG_ERROR, NULL,
+                "throwNamedException(): failed to find class %s, cannot throw",
                 className);
         return false;
     }
@@ -186,7 +188,8 @@
             sizeof(actualCapData));
     if (result <= 0)
     {
-        ALOGD("fileHasOnly(): getxattr(\"%s\") call failed: "
+        __android_log_print(ANDROID_LOG_DEBUG, NULL,
+                "fileHasOnly(): getxattr(\"%s\") call failed: "
                 "return %d (error: %s (%d))\n",
                 cPath.c_str(), result, strerror(errno), errno);
         return false;
diff --git a/tests/tests/permission/src/android/permission/cts/Camera2PermissionTest.java b/tests/tests/permission/src/android/permission/cts/Camera2PermissionTest.java
index 021a501..e40d7cb 100644
--- a/tests/tests/permission/src/android/permission/cts/Camera2PermissionTest.java
+++ b/tests/tests/permission/src/android/permission/cts/Camera2PermissionTest.java
@@ -23,6 +23,7 @@
 import android.hardware.camera2.CameraManager;
 import android.os.Handler;
 import android.os.HandlerThread;
+import android.platform.test.annotations.Presubmit;
 import android.test.AndroidTestCase;
 import android.util.Log;
 
@@ -96,6 +97,7 @@
     /**
      * Add and remove availability listeners should work without permission.
      */
+    @Presubmit
     public void testAvailabilityCallback() throws Exception {
         DummyCameraListener availabilityListener = new DummyCameraListener();
         // Remove a not-registered listener is a no-op.
diff --git a/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java b/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
index eda5c75..617f0ab 100644
--- a/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
+++ b/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
@@ -19,7 +19,6 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.os.Environment;
-import android.os.SystemProperties;
 import android.system.Os;
 import android.system.OsConstants;
 import android.system.StructStatVfs;
@@ -108,8 +107,8 @@
                 .getInstalledApplications(PackageManager.GET_UNINSTALLED_PACKAGES);
         String myAppDirectory = getContext().getApplicationInfo().dataDir;
         for (ApplicationInfo app : apps) {
-            if (!myAppDirectory.equals(app.dataDir)) {
-                writableDirs.addAll(getWritableDirectoryiesAndSubdirectoriesOf(new File(app.dataDir)));
+            if (app.dataDir != null && !myAppDirectory.equals(app.dataDir)) {
+                writableDirs.addAll(getWritableDirectoriesAndSubdirectoriesOf(new File(app.dataDir)));
             }
         }
 
@@ -263,6 +262,20 @@
     }
 
     @MediumTest
+    public void testProcSelfPagemapNotAccessible() {
+        // Note: can't use f.canRead() here, since the security check is done
+        // during the open() process. access(R_OK) return OK even through
+        // open() eventually fails.
+        try {
+            new FileInputStream("/proc/self/pagemap");
+            fail("Device is missing the following kernel security patch: "
+                 + "https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=ab676b7d6fbf4b294bf198fb27ade5b0e865c7ce");
+        } catch (FileNotFoundException e) {
+            // expected
+        }
+    }
+
+    @MediumTest
     public void testTcpDefaultRwndSane() throws Exception {
         File f = new File("/proc/sys/net/ipv4/tcp_default_init_rwnd");
         assertTrue(f.canRead());
@@ -277,7 +290,6 @@
     public void testIdletimerDirectoryExistsAndSane() throws Exception {
         File dir = new File("/sys/class/xt_idletimer");
         assertTrue(dir.isDirectory());
-        assertTrue(dir.canRead());
         assertFalse(dir.canWrite());
         assertTrue(dir.canExecute());
 
@@ -285,6 +297,40 @@
         assertFileOwnedByGroup(dir, "root");
     }
 
+
+    @MediumTest
+    public void testProcfsMmapRndBitsExistsAndSane() throws Exception {
+        String arch = System.getProperty("os.arch");
+        boolean supported = false;
+        boolean supported_64 = false;
+
+        if (arch.equals("aarch64") || arch.equals("x86_64"))
+            supported_64 = true;
+        else if (arch.startsWith("arm") || arch.endsWith("86"))
+            supported = true;
+
+        /* 64-bit OS should support running 32-bit applications */
+        if (supported_64) {
+            File f = new File("/proc/sys/vm/mmap_rnd_compat_bits");
+            assertTrue(f.exists());
+            assertFalse(f.canRead());
+            assertFalse(f.canWrite());
+            assertFalse(f.canExecute());
+            assertFileOwnedBy(f, "root");
+            assertFileOwnedByGroup(f, "root");
+        }
+
+        if (supported_64 || supported) {
+            File f = new File("/proc/sys/vm/mmap_rnd_bits");
+            assertTrue(f.exists());
+            assertFalse(f.canRead());
+            assertFalse(f.canWrite());
+            assertFalse(f.canExecute());
+            assertFileOwnedBy(f, "root");
+            assertFileOwnedByGroup(f, "root");
+        }
+    }
+
     /**
      * Assert that a file is owned by a specific owner. This is a noop if the
      * file does not exist.
@@ -360,7 +406,6 @@
     @MediumTest
     public void testDeviceTreeCpuCurrent() throws Exception {
         String arch = System.getProperty("os.arch");
-        String flavor = SystemProperties.get("ro.build.flavor");
         String[] osVersion = System.getProperty("os.version").split("\\.");
         /*
          * Perform the test for only arm-based architecture and
@@ -418,7 +463,7 @@
     @LargeTest
     public void testAllOtherDirectoriesNotWritable() throws Exception {
         File start = new File("/");
-        Set<File> writableDirs = getWritableDirectoryiesAndSubdirectoriesOf(start);
+        Set<File> writableDirs = getWritableDirectoriesAndSubdirectoriesOf(start);
 
         assertTrue("Found writable directories: " + writableDirs.toString(),
                 writableDirs.isEmpty());
@@ -579,7 +624,6 @@
                     "/mnt_ext/badablk3",
                     "/mnt_ext/cache",
                     "/mnt_ext/data",
-                    "/system/etc/dhcpcd/dhcpcd-run-hooks",
                     "/system/etc/security/drm",
                     "/synthesis/hades",
                     "/synthesis/chimaira",
@@ -610,7 +654,7 @@
         Set<File> writableDirs = new HashSet<File>();
         for (String dir : OTHER_RANDOM_DIRECTORIES) {
             File start = new File(dir);
-            writableDirs.addAll(getWritableDirectoryiesAndSubdirectoriesOf(start));
+            writableDirs.addAll(getWritableDirectoriesAndSubdirectoriesOf(start));
         }
 
         assertTrue("Found writable directories: " + writableDirs.toString(),
@@ -1031,7 +1075,7 @@
         return retval;
     }
 
-    private Set<File> getWritableDirectoryiesAndSubdirectoriesOf(File dir) throws Exception {
+    private Set<File> getWritableDirectoriesAndSubdirectoriesOf(File dir) throws Exception {
         Set<File> retval = new HashSet<File>();
         if (!dir.isDirectory()) {
             return retval;
@@ -1060,7 +1104,7 @@
         }
 
         for (File f : subFiles) {
-            retval.addAll(getWritableDirectoryiesAndSubdirectoriesOf(f));
+            retval.addAll(getWritableDirectoriesAndSubdirectoriesOf(f));
         }
 
         return retval;
diff --git a/tests/tests/permission/src/android/permission/cts/NoActivityRelatedPermissionTest.java b/tests/tests/permission/src/android/permission/cts/NoActivityRelatedPermissionTest.java
index 91ffdf4..72b5530 100644
--- a/tests/tests/permission/src/android/permission/cts/NoActivityRelatedPermissionTest.java
+++ b/tests/tests/permission/src/android/permission/cts/NoActivityRelatedPermissionTest.java
@@ -38,7 +38,7 @@
     private PermissionStubActivity mActivity;
 
     public NoActivityRelatedPermissionTest() {
-        super("com.android.cts.permission", PermissionStubActivity.class);
+        super("android.permission.cts", PermissionStubActivity.class);
     }
 
     @Override
diff --git a/tests/tests/permission/src/android/permission/cts/RebootPermissionTest.java b/tests/tests/permission/src/android/permission/cts/RebootPermissionTest.java
index 4d54098..2c6e08e 100644
--- a/tests/tests/permission/src/android/permission/cts/RebootPermissionTest.java
+++ b/tests/tests/permission/src/android/permission/cts/RebootPermissionTest.java
@@ -40,6 +40,7 @@
     public void testBroadcastReboot() {
         try {
             mContext.sendBroadcast(new Intent(Intent.ACTION_REBOOT));
+            fail("SecurityException expected!");
         } catch (SecurityException e) {
             // expected
         }
diff --git a/tests/tests/permission/src/android/permission/cts/TelephonyManagerPermissionTest.java b/tests/tests/permission/src/android/permission/cts/TelephonyManagerPermissionTest.java
index 607f301..cfafd9a 100644
--- a/tests/tests/permission/src/android/permission/cts/TelephonyManagerPermissionTest.java
+++ b/tests/tests/permission/src/android/permission/cts/TelephonyManagerPermissionTest.java
@@ -17,6 +17,7 @@
 package android.permission.cts;
 
 import android.content.Context;
+import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.media.AudioManager;
 import android.telephony.TelephonyManager;
@@ -61,6 +62,12 @@
         } catch (SecurityException e) {
             // expected
         }
+        try {
+            String id = mTelephonyManager.getDeviceId(0);
+            fail("Got device ID: " + id);
+        } catch (SecurityException e) {
+            // expected
+        }
     }
 
     /**
@@ -159,4 +166,50 @@
         mAudioManager.setMode(AudioManager.MODE_IN_CALL);
         assertEquals(audioMode, mAudioManager.getMode());
     }
+
+    /**
+     * Verify that Telephony related broadcasts are protected.
+     */
+    @SmallTest
+    public void testProtectedBroadcasts() {
+        try {
+            Intent intent = new Intent("android.intent.action.SIM_STATE_CHANGED");
+            getContext().sendBroadcast(intent);
+            fail("SecurityException expected!");
+        } catch (SecurityException e) {}
+        try {
+            Intent intent = new Intent("android.intent.action.SERVICE_STATE");
+            getContext().sendBroadcast(intent);
+            fail("SecurityException expected!");
+        } catch (SecurityException e) {}
+        try {
+            Intent intent = new Intent("android.intent.action.ACTION_DEFAULT_SUBSCRIPTION_CHANGED");
+            getContext().sendBroadcast(intent);
+            fail("SecurityException expected!");
+        } catch (SecurityException e) {}
+        try {
+            Intent intent = new Intent(
+                    "android.intent.action.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED");
+            getContext().sendBroadcast(intent);
+            fail("SecurityException expected!");
+        } catch (SecurityException e) {}
+        try {
+            Intent intent = new Intent(
+                    "android.intent.action.ACTION_DEFAULT_SMS_SUBSCRIPTION_CHANGED");
+            getContext().sendBroadcast(intent);
+            fail("SecurityException expected!");
+        } catch (SecurityException e) {}
+        try {
+            Intent intent = new Intent(
+                    "android.intent.action.ACTION_DEFAULT_VOICE_SUBSCRIPTION_CHANGED");
+            getContext().sendBroadcast(intent);
+            fail("SecurityException expected!");
+        } catch (SecurityException e) {}
+        try {
+            Intent intent = new Intent("android.intent.action.SIG_STR");
+            getContext().sendBroadcast(intent);
+            fail("SecurityException expected!");
+        } catch (SecurityException e) {}
+
+    }
 }
diff --git a/tests/tests/permission2/Android.mk b/tests/tests/permission2/Android.mk
index 29d5e03..1b4251a 100755
--- a/tests/tests/permission2/Android.mk
+++ b/tests/tests/permission2/Android.mk
@@ -19,6 +19,11 @@
 
 LOCAL_MODULE_TAGS := tests
 
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_JAVA_LIBRARIES := telephony-common
 
 LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
diff --git a/tests/tests/permission2/AndroidManifest.xml b/tests/tests/permission2/AndroidManifest.xml
index 984d124..6429dab 100755
--- a/tests/tests/permission2/AndroidManifest.xml
+++ b/tests/tests/permission2/AndroidManifest.xml
@@ -16,7 +16,7 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.permission2">
+    package="android.permission2.cts">
 
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <application>
@@ -63,7 +63,7 @@
             android:maxSdkVersion="9000" />
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.cts.permission2"
+                     android:targetPackage="android.permission2.cts"
                      android:label="More CTS tests for permissions">
         <meta-data android:name="listener"
             android:value="com.android.cts.runner.CtsTestRunListener" />
diff --git a/tests/tests/permission2/AndroidTest.xml b/tests/tests/permission2/AndroidTest.xml
new file mode 100644
index 0000000..b814aa7
--- /dev/null
+++ b/tests/tests/permission2/AndroidTest.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS Permission test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsPermission2TestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.permission2.cts" />
+        <option name="runtime-hint" value="2m" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/tests/permission2/res/raw/android_manifest.xml b/tests/tests/permission2/res/raw/android_manifest.xml
index 08bccc1..e2cc09f 100644
--- a/tests/tests/permission2/res/raw/android_manifest.xml
+++ b/tests/tests/permission2/res/raw/android_manifest.xml
@@ -18,8 +18,8 @@
 */
 -->
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android" coreApp="true" android:sharedUserId="android.uid.system"
-    android:sharedUserLabel="@string/android_system_label">
+          package="android" coreApp="true" android:sharedUserId="android.uid.system"
+          android:sharedUserLabel="@string/android_system_label">
 
     <!-- ================================================ -->
     <!-- Special broadcasts that only the system can send -->
@@ -33,6 +33,7 @@
     <protected-broadcast android:name="android.intent.action.TIME_TICK" />
     <protected-broadcast android:name="android.intent.action.TIMEZONE_CHANGED" />
     <protected-broadcast android:name="android.intent.action.DATE_CHANGED" />
+    <protected-broadcast android:name="android.intent.action.PRE_BOOT_COMPLETED" />
     <protected-broadcast android:name="android.intent.action.BOOT_COMPLETED" />
     <protected-broadcast android:name="android.intent.action.PACKAGE_INSTALL" />
     <protected-broadcast android:name="android.intent.action.PACKAGE_ADDED" />
@@ -46,6 +47,8 @@
     <protected-broadcast android:name="android.intent.action.PACKAGE_FIRST_LAUNCH" />
     <protected-broadcast android:name="android.intent.action.PACKAGE_NEEDS_VERIFICATION" />
     <protected-broadcast android:name="android.intent.action.PACKAGE_VERIFIED" />
+    <protected-broadcast android:name="android.intent.action.PACKAGES_SUSPENDED" />
+    <protected-broadcast android:name="android.intent.action.PACKAGES_UNSUSPENDED" />
     <protected-broadcast android:name="android.intent.action.UID_REMOVED" />
     <protected-broadcast android:name="android.intent.action.QUERY_PACKAGE_RESTART" />
     <protected-broadcast android:name="android.intent.action.CONFIGURATION_CHANGED" />
@@ -65,6 +68,7 @@
     <protected-broadcast android:name="android.intent.action.NEW_OUTGOING_CALL" />
     <protected-broadcast android:name="android.intent.action.REBOOT" />
     <protected-broadcast android:name="android.intent.action.DOCK_EVENT" />
+    <protected-broadcast android:name="android.intent.action.THERMAL_EVENT" />
     <protected-broadcast android:name="android.intent.action.MASTER_CLEAR_NOTIFICATION" />
     <protected-broadcast android:name="android.intent.action.USER_ADDED" />
     <protected-broadcast android:name="android.intent.action.USER_REMOVED" />
@@ -75,6 +79,7 @@
     <protected-broadcast android:name="android.intent.action.USER_BACKGROUND" />
     <protected-broadcast android:name="android.intent.action.USER_FOREGROUND" />
     <protected-broadcast android:name="android.intent.action.USER_SWITCHED" />
+    <protected-broadcast android:name="android.intent.action.USER_INITIALIZE" />
     <protected-broadcast android:name="android.intent.action.INTENT_FILTER_NEEDS_VERIFICATION" />
 
     <protected-broadcast android:name="android.os.action.POWER_SAVE_MODE_CHANGED" />
@@ -82,6 +87,7 @@
     <protected-broadcast android:name="android.os.action.DEVICE_IDLE_MODE_CHANGED" />
     <protected-broadcast android:name="android.os.action.POWER_SAVE_WHITELIST_CHANGED" />
     <protected-broadcast android:name="android.os.action.POWER_SAVE_TEMP_WHITELIST_CHANGED" />
+    <protected-broadcast android:name="android.os.action.POWER_SAVE_MODE_CHANGED_INTERNAL" />
 
     <protected-broadcast android:name="android.os.action.SCREEN_BRIGHTNESS_BOOST_CHANGED" />
 
@@ -91,6 +97,10 @@
     <protected-broadcast android:name="android.app.action.EXIT_DESK_MODE" />
     <protected-broadcast android:name="android.app.action.NEXT_ALARM_CLOCK_CHANGED" />
 
+    <protected-broadcast android:name="android.app.action.BUGREPORT_SHARING_DECLINED" />
+    <protected-broadcast android:name="android.app.action.BUGREPORT_FAILED" />
+    <protected-broadcast android:name="android.app.action.BUGREPORT_SHARE" />
+
     <protected-broadcast android:name="android.appwidget.action.APPWIDGET_UPDATE_OPTIONS" />
     <protected-broadcast android:name="android.appwidget.action.APPWIDGET_DELETED" />
     <protected-broadcast android:name="android.appwidget.action.APPWIDGET_DISABLED" />
@@ -100,10 +110,11 @@
 
     <protected-broadcast android:name="android.os.action.SETTING_RESTORED" />
 
-    <protected-broadcast android:name="android.backup.intent.RUN" />
-    <protected-broadcast android:name="android.backup.intent.CLEAR" />
-    <protected-broadcast android:name="android.backup.intent.INIT" />
+    <protected-broadcast android:name="android.app.backup.intent.RUN" />
+    <protected-broadcast android:name="android.app.backup.intent.CLEAR" />
+    <protected-broadcast android:name="android.app.backup.intent.INIT" />
 
+    <protected-broadcast android:name="android.bluetooth.intent.DISCOVERABLE_TIMEOUT" />
     <protected-broadcast android:name="android.bluetooth.adapter.action.STATE_CHANGED" />
     <protected-broadcast android:name="android.bluetooth.adapter.action.SCAN_MODE_CHANGED" />
     <protected-broadcast android:name="android.bluetooth.adapter.action.DISCOVERY_STARTED" />
@@ -130,43 +141,43 @@
     <protected-broadcast android:name="android.bluetooth.devicepicker.action.LAUNCH" />
     <protected-broadcast android:name="android.bluetooth.devicepicker.action.DEVICE_SELECTED" />
     <protected-broadcast
-        android:name="android.bluetooth.headset.profile.action.CONNECTION_STATE_CHANGED" />
+            android:name="android.bluetooth.headset.profile.action.CONNECTION_STATE_CHANGED" />
     <protected-broadcast
-        android:name="android.bluetooth.headset.profile.action.AUDIO_STATE_CHANGED" />
+            android:name="android.bluetooth.headset.profile.action.AUDIO_STATE_CHANGED" />
     <protected-broadcast
-        android:name="android.bluetooth.headset.action.VENDOR_SPECIFIC_HEADSET_EVENT" />
+            android:name="android.bluetooth.headset.action.VENDOR_SPECIFIC_HEADSET_EVENT" />
     <protected-broadcast
-        android:name="android.bluetooth.headsetclient.profile.action.CONNECTION_STATE_CHANGED" />
+            android:name="android.bluetooth.headsetclient.profile.action.CONNECTION_STATE_CHANGED" />
     <protected-broadcast
-        android:name="android.bluetooth.headsetclient.profile.action.AUDIO_STATE_CHANGED" />
+            android:name="android.bluetooth.headsetclient.profile.action.AUDIO_STATE_CHANGED" />
     <protected-broadcast
-        android:name="android.bluetooth.headsetclient.profile.action.AG_EVENT" />
+            android:name="android.bluetooth.headsetclient.profile.action.AG_EVENT" />
     <protected-broadcast
-        android:name="android.bluetooth.headsetclient.profile.action.AG_CALL_CHANGED" />
+            android:name="android.bluetooth.headsetclient.profile.action.AG_CALL_CHANGED" />
     <protected-broadcast
-        android:name="android.bluetooth.headsetclient.profile.action.RESULT" />
+            android:name="android.bluetooth.headsetclient.profile.action.RESULT" />
     <protected-broadcast
-        android:name="android.bluetooth.headsetclient.profile.action.LAST_VTAG" />
+            android:name="android.bluetooth.headsetclient.profile.action.LAST_VTAG" />
     <protected-broadcast
-        android:name="android.bluetooth.a2dp.profile.action.CONNECTION_STATE_CHANGED" />
+            android:name="android.bluetooth.a2dp.profile.action.CONNECTION_STATE_CHANGED" />
     <protected-broadcast
-        android:name="android.bluetooth.a2dp.profile.action.PLAYING_STATE_CHANGED" />
+            android:name="android.bluetooth.a2dp.profile.action.PLAYING_STATE_CHANGED" />
     <protected-broadcast
-        android:name="android.bluetooth.a2dp-sink.profile.action.CONNECTION_STATE_CHANGED" />
+            android:name="android.bluetooth.a2dp-sink.profile.action.CONNECTION_STATE_CHANGED" />
     <protected-broadcast
-        android:name="android.bluetooth.a2dp-sink.profile.action.PLAYING_STATE_CHANGED" />
+            android:name="android.bluetooth.a2dp-sink.profile.action.PLAYING_STATE_CHANGED" />
     <protected-broadcast
-        android:name="android.bluetooth.a2dp-sink.profile.action.AUDIO_CONFIG_CHANGED" />
-   <protected-broadcast
-        android:name="android.bluetooth.avrcp-controller.profile.action.CONNECTION_STATE_CHANGED" />
+            android:name="android.bluetooth.a2dp-sink.profile.action.AUDIO_CONFIG_CHANGED" />
     <protected-broadcast
-        android:name="android.bluetooth.input.profile.action.CONNECTION_STATE_CHANGED" />
+            android:name="android.bluetooth.avrcp-controller.profile.action.CONNECTION_STATE_CHANGED" />
     <protected-broadcast
-        android:name="android.bluetooth.input.profile.action.PROTOCOL_MODE_CHANGED" />
+            android:name="android.bluetooth.input.profile.action.CONNECTION_STATE_CHANGED" />
     <protected-broadcast
-        android:name="android.bluetooth.input.profile.action.VIRTUAL_UNPLUG_STATUS" />
+            android:name="android.bluetooth.input.profile.action.PROTOCOL_MODE_CHANGED" />
     <protected-broadcast
-        android:name="android.bluetooth.pan.profile.action.CONNECTION_STATE_CHANGED" />
+            android:name="android.bluetooth.input.profile.action.VIRTUAL_UNPLUG_STATUS" />
+    <protected-broadcast
+            android:name="android.bluetooth.pan.profile.action.CONNECTION_STATE_CHANGED" />
     <protected-broadcast android:name="android.bluetooth.pbap.intent.action.PBAP_STATE_CHANGED" />
     <protected-broadcast android:name="android.btopp.intent.action.INCOMING_FILE_NOTIFICATION" />
     <protected-broadcast android:name="android.btopp.intent.action.USER_CONFIRMATION_TIMEOUT" />
@@ -188,7 +199,7 @@
     <protected-broadcast android:name="android.hardware.usb.action.USB_STATE" />
     <protected-broadcast android:name="android.hardware.usb.action.USB_PORT_CHANGED" />
     <protected-broadcast android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" />
-    <protected-broadcast android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" />
+    <protected-broadcast android:name="android.hardware.usb.action.USB_ACCESSORY_DETACHED" />
     <protected-broadcast android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
     <protected-broadcast android:name="android.hardware.usb.action.USB_DEVICE_DETACHED" />
 
@@ -201,6 +212,7 @@
     <protected-broadcast android:name="android.media.VOLUME_CHANGED_ACTION" />
     <protected-broadcast android:name="android.media.MASTER_VOLUME_CHANGED_ACTION" />
     <protected-broadcast android:name="android.media.MASTER_MUTE_CHANGED_ACTION" />
+    <protected-broadcast android:name="android.media.MASTER_MONO_CHANGED_ACTION" />
     <protected-broadcast android:name="android.media.SCO_AUDIO_STATE_CHANGED" />
     <protected-broadcast android:name="android.media.ACTION_SCO_AUDIO_STATE_UPDATED" />
 
@@ -220,17 +232,27 @@
     <!-- @deprecated.  Only {@link android.net.ConnectivityManager.CONNECTIVITY_ACTION} is sent. -->
     <protected-broadcast android:name="android.net.conn.CONNECTIVITY_CHANGE_IMMEDIATE" />
     <protected-broadcast android:name="android.net.conn.DATA_ACTIVITY_CHANGE" />
+    <protected-broadcast android:name="android.net.conn.RESTRICT_BACKGROUND_CHANGED" />
     <protected-broadcast android:name="android.net.conn.BACKGROUND_DATA_SETTING_CHANGED" />
     <protected-broadcast android:name="android.net.conn.CAPTIVE_PORTAL_TEST_COMPLETED" />
 
     <protected-broadcast android:name="android.net.nsd.STATE_CHANGED" />
 
-    <protected-broadcast android:name="android.nfc.action.LLCP_LINK_STATE_CHANGED" />
+    <protected-broadcast android:name="android.nfc.action.ADAPTER_STATE_CHANGED" />
+    <protected-broadcast android:name="android.nfc.action.TRANSACTION_DETECTED" />
+    <protected-broadcast android:name="com.android.nfc.action.LLCP_UP" />
+    <protected-broadcast android:name="com.android.nfc.action.LLCP_DOWN" />
+    <protected-broadcast android:name="com.android.nfc.cardemulation.action.CLOSE_TAP_DIALOG" />
+    <protected-broadcast android:name="com.android.nfc.handover.action.ALLOW_CONNECT" />
+    <protected-broadcast android:name="com.android.nfc.handover.action.DENY_CONNECT" />
     <protected-broadcast android:name="com.android.nfc_extras.action.RF_FIELD_ON_DETECTED" />
     <protected-broadcast android:name="com.android.nfc_extras.action.RF_FIELD_OFF_DETECTED" />
     <protected-broadcast android:name="com.android.nfc_extras.action.AID_SELECTED" />
-
-    <protected-broadcast android:name="android.nfc.action.TRANSACTION_DETECTED" />
+    <!-- For NFC to BT handover -->
+    <protected-broadcast android:name="android.btopp.intent.action.WHITELIST_DEVICE" />
+    <protected-broadcast android:name="android.btopp.intent.action.STOP_HANDOVER_TRANSFER" />
+    <protected-broadcast android:name="android.nfc.handover.intent.action.HANDOVER_SEND" />
+    <protected-broadcast android:name="android.nfc.handover.intent.action.HANDOVER_SEND_MULTIPLE" />
 
     <protected-broadcast android:name="android.intent.action.CLEAR_DNS_CACHE" />
     <protected-broadcast android:name="android.intent.action.PROXY_CHANGE" />
@@ -240,11 +262,13 @@
     <protected-broadcast android:name="android.intent.action.DREAMING_STARTED" />
     <protected-broadcast android:name="android.intent.action.DREAMING_STOPPED" />
     <protected-broadcast android:name="android.intent.action.ANY_DATA_STATE" />
-    <protected-broadcast android:name="android.intent.action.DATA_CONNECTION_CONNECTED_TO_PROVISIONING_APN" />
 
     <protected-broadcast android:name="com.android.server.WifiManager.action.START_SCAN" />
     <protected-broadcast android:name="com.android.server.WifiManager.action.START_PNO" />
     <protected-broadcast android:name="com.android.server.WifiManager.action.DELAYED_DRIVER_STOP" />
+    <protected-broadcast android:name="com.android.server.WifiManager.action.DEVICE_IDLE" />
+    <protected-broadcast android:name="com.android.server.action.REMOTE_BUGREPORT_SHARING_ACCEPTED" />
+    <protected-broadcast android:name="com.android.server.action.REMOTE_BUGREPORT_SHARING_DECLINED" />
     <protected-broadcast android:name="android.net.wifi.WIFI_STATE_CHANGED" />
     <protected-broadcast android:name="android.net.wifi.WIFI_AP_STATE_CHANGED" />
     <protected-broadcast android:name="android.net.wifi.WIFI_CREDENTIAL_CHANGED" />
@@ -274,11 +298,13 @@
     <protected-broadcast android:name="android.intent.action.AIRPLANE_MODE" />
     <protected-broadcast android:name="android.intent.action.ADVANCED_SETTINGS" />
     <protected-broadcast android:name="android.intent.action.APPLICATION_RESTRICTIONS_CHANGED" />
-    <protected-broadcast android:name="android.intent.action.BUGREPORT_FINISHED" />
 
+    <!-- Legacy -->
     <protected-broadcast android:name="android.intent.action.ACTION_IDLE_MAINTENANCE_START" />
     <protected-broadcast android:name="android.intent.action.ACTION_IDLE_MAINTENANCE_END" />
 
+    <protected-broadcast android:name="com.android.server.task.controllers.IdleController.ACTION_TRIGGER_IDLE" />
+
     <protected-broadcast android:name="android.intent.action.HDMI_PLUGGED" />
 
     <protected-broadcast android:name="android.intent.action.PHONE_STATE" />
@@ -294,11 +320,11 @@
     <protected-broadcast android:name="android.telecom.action.DEFAULT_DIALER_CHANGED" />
 
     <protected-broadcast
-        android:name="com.android.server.connectivityservice.CONNECTED_TO_PROVISIONING_NETWORK_ACTION" />
+            android:name="com.android.server.connectivityservice.CONNECTED_TO_PROVISIONING_NETWORK_ACTION" />
 
     <!-- Defined in RestrictionsManager -->
     <protected-broadcast
-        android:name="android.intent.action.PERMISSION_RESPONSE_RECEIVED" />
+            android:name="android.intent.action.PERMISSION_RESPONSE_RECEIVED" />
     <!-- Defined in RestrictionsManager -->
 
     <protected-broadcast android:name="android.intent.action.REQUEST_PERMISSION" />
@@ -320,6 +346,131 @@
     <protected-broadcast android:name="android.internal.policy.action.BURN_IN_PROTECTION" />
     <protected-broadcast android:name="android.app.action.SYSTEM_UPDATE_POLICY_CHANGED" />
     <protected-broadcast android:name="android.app.action.DEVICE_OWNER_CHANGED" />
+
+    <protected-broadcast android:name="android.intent.action.MANAGED_PROFILE_AVAILABILITY_CHANGED" />
+    <protected-broadcast android:name="android.intent.action.MANAGED_PROFILE_AVAILABLE" />
+    <protected-broadcast android:name="android.intent.action.MANAGED_PROFILE_UNAVAILABLE" />
+
+    <!-- Added in N -->
+    <protected-broadcast android:name="android.intent.action.ANR" />
+    <protected-broadcast android:name="android.intent.action.CALL" />
+    <protected-broadcast android:name="android.intent.action.DROPBOX_ENTRY_ADDED" />
+    <protected-broadcast android:name="android.intent.action.INPUT_METHOD_CHANGED" />
+    <protected-broadcast android:name="android.intent.action.internal_sim_state_changed" />
+    <protected-broadcast android:name="android.intent.action.LOCKED_BOOT_COMPLETED" />
+    <protected-broadcast android:name="android.intent.action.PRECISE_CALL_STATE" />
+    <protected-broadcast android:name="android.intent.action.PRECISE_DATA_CONNECTION_STATE_CHANGED" />
+    <protected-broadcast android:name="android.intent.action.SUBSCRIPTION_PHONE_STATE" />
+    <protected-broadcast android:name="android.intent.action.USER_INFO_CHANGED" />
+    <protected-broadcast android:name="android.intent.action.USER_UNLOCKED" />
+    <protected-broadcast android:name="android.intent.action.WALLPAPER_CHANGED" />
+
+    <protected-broadcast android:name="android.app.action.DEVICE_POLICY_MANAGER_STATE_CHANGED" />
+    <protected-broadcast android:name="android.app.action.CHOOSE_PRIVATE_KEY_ALIAS" />
+    <protected-broadcast android:name="android.app.action.DEVICE_ADMIN_DISABLED" />
+    <protected-broadcast android:name="android.app.action.DEVICE_ADMIN_DISABLE_REQUESTED" />
+    <protected-broadcast android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
+    <protected-broadcast android:name="android.app.action.LOCK_TASK_ENTERING" />
+    <protected-broadcast android:name="android.app.action.LOCK_TASK_EXITING" />
+    <protected-broadcast android:name="android.app.action.NOTIFY_PENDING_SYSTEM_UPDATE" />
+    <protected-broadcast android:name="android.app.action.ACTION_PASSWORD_CHANGED" />
+    <protected-broadcast android:name="android.app.action.ACTION_PASSWORD_EXPIRING" />
+    <protected-broadcast android:name="android.app.action.ACTION_PASSWORD_FAILED" />
+    <protected-broadcast android:name="android.app.action.ACTION_PASSWORD_SUCCEEDED" />
+    <protected-broadcast android:name="com.android.server.ACTION_EXPIRED_PASSWORD_NOTIFICATION" />
+
+    <protected-broadcast android:name="android.intent.action.MANAGED_PROFILE_ADDED" />
+    <protected-broadcast android:name="android.intent.action.MANAGED_PROFILE_UNLOCKED" />
+    <protected-broadcast android:name="android.intent.action.MANAGED_PROFILE_REMOVED" />
+
+    <protected-broadcast android:name="android.bluetooth.adapter.action.BLE_STATE_CHANGED" />
+    <protected-broadcast android:name="android.content.jobscheduler.JOB_DELAY_EXPIRED" />
+    <protected-broadcast android:name="android.content.syncmanager.SYNC_ALARM" />
+    <protected-broadcast android:name="android.media.INTERNAL_RINGER_MODE_CHANGED_ACTION" />
+    <protected-broadcast android:name="android.media.STREAM_DEVICES_CHANGED_ACTION" />
+    <protected-broadcast android:name="android.media.STREAM_MUTE_CHANGED_ACTION" />
+    <protected-broadcast android:name="android.net.sip.SIP_SERVICE_UP" />
+    <protected-broadcast android:name="android.nfc.action.ADAPTER_STATE_CHANGED" />
+    <protected-broadcast android:name="android.os.action.CHARGING" />
+    <protected-broadcast android:name="android.os.action.DISCHARGING" />
+    <protected-broadcast android:name="android.search.action.SEARCHABLES_CHANGED" />
+    <protected-broadcast android:name="android.security.STORAGE_CHANGED" />
+    <protected-broadcast android:name="android.telecom.action.PHONE_ACCOUNT_REGISTERED" />
+    <protected-broadcast android:name="android.telecom.action.PHONE_ACCOUNT_UNREGISTERED" />
+    <protected-broadcast android:name="android.telecom.action.SHOW_MISSED_CALLS_NOTIFICATION" />
+    <protected-broadcast android:name="android.telephony.action.CARRIER_CONFIG_CHANGED" />
+
+    <protected-broadcast android:name="com.android.bluetooth.btservice.action.ALARM_WAKEUP" />
+    <protected-broadcast android:name="com.android.server.action.NETWORK_STATS_POLL" />
+    <protected-broadcast android:name="com.android.server.action.NETWORK_STATS_UPDATED" />
+    <protected-broadcast android:name="com.android.server.NetworkTimeUpdateService.action.POLL" />
+    <protected-broadcast android:name="com.android.server.telecom.intent.action.CALLS_ADD_ENTRY" />
+    <protected-broadcast android:name="com.android.settings.location.MODE_CHANGING" />
+
+    <protected-broadcast android:name="ScheduleConditionProvider.EVALUATE" />
+    <protected-broadcast android:name="EventConditionProvider.EVALUATE" />
+    <protected-broadcast android:name="wifi_scan_available" />
+
+    <protected-broadcast android:name="action.cne.started" />
+    <protected-broadcast android:name="android.content.jobscheduler.JOB_DEADLINE_EXPIRED" />
+    <protected-broadcast android:name="android.intent.action.ACTION_UNSOL_RESPONSE_OEM_HOOK_RAW" />
+    <protected-broadcast android:name="android.net.conn.CONNECTIVITY_CHANGE_SUPL" />
+    <protected-broadcast android:name="android.os.action.ACTION_EFFECTS_SUPPRESSOR_CHANGED" />
+    <protected-broadcast android:name="android.os.action.LIGHT_DEVICE_IDLE_MODE_CHANGED" />
+    <protected-broadcast android:name="android.os.storage.action.VOLUME_STATE_CHANGED" />
+    <protected-broadcast android:name="android.os.storage.action.DISK_SCANNED" />
+    <protected-broadcast android:name="com.android.server.action.UPDATE_TWILIGHT_STATE" />
+    <protected-broadcast android:name="com.android.server.action.RESET_TWILIGHT_AUTO" />
+    <protected-broadcast android:name="com.android.server.device_idle.STEP_IDLE_STATE" />
+    <protected-broadcast android:name="com.android.server.device_idle.STEP_LIGHT_IDLE_STATE" />
+    <protected-broadcast android:name="com.android.server.Wifi.action.TOGGLE_PNO" />
+    <protected-broadcast android:name="intent.action.ACTION_RF_BAND_INFO" />
+    <protected-broadcast android:name="android.intent.action.MEDIA_RESOURCE_GRANTED" />
+    <protected-broadcast android:name="android.app.action.SECURITY_LOGS_AVAILABLE" />
+
+    <protected-broadcast android:name="android.app.action.INTERRUPTION_FILTER_CHANGED" />
+    <protected-broadcast android:name="android.app.action.INTERRUPTION_FILTER_CHANGED_INTERNAL" />
+    <protected-broadcast android:name="android.app.action.NOTIFICATION_POLICY_CHANGED" />
+    <protected-broadcast android:name="android.app.action.NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED" />
+    <protected-broadcast android:name="android.os.action.ACTION_EFFECTS_SUPPRESSOR_CHANGED" />
+
+    <protected-broadcast android:name="android.permission.GET_APP_GRANTED_URI_PERMISSIONS" />
+    <protected-broadcast android:name="android.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS" />
+
+    <protected-broadcast android:name="android.intent.action.DYNAMIC_SENSOR_CHANGED" />
+
+    <protected-broadcast android:name="android.intent.action.ACTION_RADIO_OFF" />
+
+    <protected-broadcast android:name="android.accounts.LOGIN_ACCOUNTS_CHANGED" />
+    <protected-broadcast android:name="com.android.sync.SYNC_CONN_STATUS_CHANGED" />
+
+    <protected-broadcast android:name="com.android.phone.SIP_INCOMING_CALL" />
+    <protected-broadcast android:name="com.android.phone.SIP_ADD_PHONE" />
+    <protected-broadcast android:name="com.android.phone.SIP_REMOVE_PHONE" />
+    <protected-broadcast android:name="com.android.phone.SIP_CALL_OPTION_CHANGED" />
+
+    <protected-broadcast android:name="android.bluetooth.adapter.action.BLE_ACL_CONNECTED" />
+    <protected-broadcast android:name="android.bluetooth.adapter.action.BLE_ACL_DISCONNECTED" />
+
+    <protected-broadcast android:name="android.bluetooth.input.profile.action.HANDSHAKE" />
+    <protected-broadcast android:name="android.bluetooth.input.profile.action.REPORT" />
+
+    <protected-broadcast android:name="android.intent.action.TWILIGHT_CHANGED" />
+
+    <protected-broadcast android:name="com.android.server.fingerprint.ACTION_LOCKOUT_RESET" />
+    <protected-broadcast android:name="android.net.wifi.PASSPOINT_ICON_RECEIVED" />
+    <protected-broadcast android:name="com.android.server.notification.CountdownConditionProvider" />
+
+    <protected-broadcast android:name="com.android.ims.IMS_SERVICE_UP" />
+    <protected-broadcast android:name="com.android.ims.IMS_INCOMING_CALL" />
+    <protected-broadcast android:name="com.android.ims.internal.uce.UCE_SERVICE_UP" />
+    <protected-broadcast android:name="com.android.intent.action.IMS_FEATURE_CHANGED" />
+    <protected-broadcast android:name="com.android.intent.action.IMS_CONFIG_CHANGED" />
+
+    <protected-broadcast android:name="com.android.internal.location.ALARM_WAKEUP" />
+    <protected-broadcast android:name="com.android.internal.location.ALARM_TIMEOUT" />
+    <protected-broadcast android:name="android.intent.action.GLOBAL_BUTTON" />
+
     <!-- ====================================================================== -->
     <!--                          RUNTIME PERMISSIONS                           -->
     <!-- ====================================================================== -->
@@ -332,28 +483,28 @@
 
     <!-- Used for runtime permissions related to user's contacts and profile. -->
     <permission-group android:name="android.permission-group.CONTACTS"
-        android:icon="@drawable/perm_group_contacts"
-        android:label="@string/permgrouplab_contacts"
-        android:description="@string/permgroupdesc_contacts"
-        android:priority="100" />
+                      android:icon="@drawable/perm_group_contacts"
+                      android:label="@string/permgrouplab_contacts"
+                      android:description="@string/permgroupdesc_contacts"
+                      android:priority="100" />
 
     <!-- Allows an application to read the user's contacts data.
         <p>Protection level: dangerous
     -->
     <permission android:name="android.permission.READ_CONTACTS"
-        android:permissionGroup="android.permission-group.CONTACTS"
-        android:label="@string/permlab_readContacts"
-        android:description="@string/permdesc_readContacts"
-        android:protectionLevel="dangerous" />
+                android:permissionGroup="android.permission-group.CONTACTS"
+                android:label="@string/permlab_readContacts"
+                android:description="@string/permdesc_readContacts"
+                android:protectionLevel="dangerous" />
 
     <!-- Allows an application to write the user's contacts data.
          <p>Protection level: dangerous
     -->
     <permission android:name="android.permission.WRITE_CONTACTS"
-        android:permissionGroup="android.permission-group.CONTACTS"
-        android:label="@string/permlab_writeContacts"
-        android:description="@string/permdesc_writeContacts"
-        android:protectionLevel="dangerous" />
+                android:permissionGroup="android.permission-group.CONTACTS"
+                android:label="@string/permlab_writeContacts"
+                android:description="@string/permdesc_writeContacts"
+                android:protectionLevel="dangerous" />
 
     <!-- ====================================================================== -->
     <!-- Permissions for accessing user's calendar                              -->
@@ -362,28 +513,28 @@
 
     <!-- Used for runtime permissions related to user's calendar. -->
     <permission-group android:name="android.permission-group.CALENDAR"
-        android:icon="@drawable/perm_group_calendar"
-        android:label="@string/permgrouplab_calendar"
-        android:description="@string/permgroupdesc_calendar"
-        android:priority="200" />
+                      android:icon="@drawable/perm_group_calendar"
+                      android:label="@string/permgrouplab_calendar"
+                      android:description="@string/permgroupdesc_calendar"
+                      android:priority="200" />
 
     <!-- Allows an application to read the user's calendar data.
          <p>Protection level: dangerous
     -->
     <permission android:name="android.permission.READ_CALENDAR"
-        android:permissionGroup="android.permission-group.CALENDAR"
-        android:label="@string/permlab_readCalendar"
-        android:description="@string/permdesc_readCalendar"
-        android:protectionLevel="dangerous" />
+                android:permissionGroup="android.permission-group.CALENDAR"
+                android:label="@string/permlab_readCalendar"
+                android:description="@string/permdesc_readCalendar"
+                android:protectionLevel="dangerous" />
 
     <!-- Allows an application to write the user's calendar data.
          <p>Protection level: dangerous
     -->
     <permission android:name="android.permission.WRITE_CALENDAR"
-        android:permissionGroup="android.permission-group.CALENDAR"
-        android:label="@string/permlab_writeCalendar"
-        android:description="@string/permdesc_writeCalendar"
-        android:protectionLevel="dangerous" />
+                android:permissionGroup="android.permission-group.CALENDAR"
+                android:label="@string/permlab_writeCalendar"
+                android:description="@string/permdesc_writeCalendar"
+                android:protectionLevel="dangerous" />
 
     <!-- ====================================================================== -->
     <!-- Permissions for accessing and modifying user's SMS messages            -->
@@ -392,56 +543,56 @@
 
     <!-- Used for runtime permissions related to user's SMS messages. -->
     <permission-group android:name="android.permission-group.SMS"
-        android:icon="@drawable/perm_group_sms"
-        android:label="@string/permgrouplab_sms"
-        android:description="@string/permgroupdesc_sms"
-        android:priority="300" />
+                      android:icon="@drawable/perm_group_sms"
+                      android:label="@string/permgrouplab_sms"
+                      android:description="@string/permgroupdesc_sms"
+                      android:priority="300" />
 
     <!-- Allows an application to send SMS messages.
          <p>Protection level: dangerous
     -->
     <permission android:name="android.permission.SEND_SMS"
-        android:permissionGroup="android.permission-group.SMS"
-        android:label="@string/permlab_sendSms"
-        android:description="@string/permdesc_sendSms"
-        android:permissionFlags="costsMoney"
-        android:protectionLevel="dangerous" />
+                android:permissionGroup="android.permission-group.SMS"
+                android:label="@string/permlab_sendSms"
+                android:description="@string/permdesc_sendSms"
+                android:permissionFlags="costsMoney"
+                android:protectionLevel="dangerous" />
 
     <!-- Allows an application to receive SMS messages.
          <p>Protection level: dangerous
     -->
     <permission android:name="android.permission.RECEIVE_SMS"
-        android:permissionGroup="android.permission-group.SMS"
-        android:label="@string/permlab_receiveSms"
-        android:description="@string/permdesc_receiveSms"
-        android:protectionLevel="dangerous"/>
+                android:permissionGroup="android.permission-group.SMS"
+                android:label="@string/permlab_receiveSms"
+                android:description="@string/permdesc_receiveSms"
+                android:protectionLevel="dangerous"/>
 
     <!-- Allows an application to read SMS messages.
          <p>Protection level: dangerous
     -->
     <permission android:name="android.permission.READ_SMS"
-        android:permissionGroup="android.permission-group.SMS"
-        android:label="@string/permlab_readSms"
-        android:description="@string/permdesc_readSms"
-        android:protectionLevel="dangerous" />
+                android:permissionGroup="android.permission-group.SMS"
+                android:label="@string/permlab_readSms"
+                android:description="@string/permdesc_readSms"
+                android:protectionLevel="dangerous" />
 
     <!-- Allows an application to receive WAP push messages.
          <p>Protection level: dangerous
     -->
     <permission android:name="android.permission.RECEIVE_WAP_PUSH"
-        android:permissionGroup="android.permission-group.SMS"
-        android:label="@string/permlab_receiveWapPush"
-        android:description="@string/permdesc_receiveWapPush"
-        android:protectionLevel="dangerous" />
+                android:permissionGroup="android.permission-group.SMS"
+                android:label="@string/permlab_receiveWapPush"
+                android:description="@string/permdesc_receiveWapPush"
+                android:protectionLevel="dangerous" />
 
     <!-- Allows an application to monitor incoming MMS messages.
         <p>Protection level: dangerous
     -->
     <permission android:name="android.permission.RECEIVE_MMS"
-        android:permissionGroup="android.permission-group.SMS"
-        android:label="@string/permlab_receiveMms"
-        android:description="@string/permdesc_receiveMms"
-        android:protectionLevel="dangerous" />
+                android:permissionGroup="android.permission-group.SMS"
+                android:label="@string/permlab_receiveMms"
+                android:description="@string/permdesc_receiveMms"
+                android:protectionLevel="dangerous" />
 
     <!-- Allows an application to read previously received cell broadcast
          messages and to register a content observer to get notifications when
@@ -456,10 +607,10 @@
          <p>Protection level: dangerous
          @hide Pending API council approval -->
     <permission android:name="android.permission.READ_CELL_BROADCASTS"
-        android:permissionGroup="android.permission-group.SMS"
-        android:label="@string/permlab_readCellBroadcasts"
-        android:description="@string/permdesc_readCellBroadcasts"
-        android:protectionLevel="dangerous" />
+                android:permissionGroup="android.permission-group.SMS"
+                android:label="@string/permlab_readCellBroadcasts"
+                android:description="@string/permdesc_readCellBroadcasts"
+                android:protectionLevel="dangerous" />
 
     <!-- ====================================================================== -->
     <!-- Permissions for accessing external storage                             -->
@@ -468,10 +619,10 @@
 
     <!-- Used for runtime permissions related to the shared external storage. -->
     <permission-group android:name="android.permission-group.STORAGE"
-        android:icon="@drawable/perm_group_storage"
-        android:label="@string/permgrouplab_storage"
-        android:description="@string/permgroupdesc_storage"
-        android:priority="900" />
+                      android:icon="@drawable/perm_group_storage"
+                      android:label="@string/permgrouplab_storage"
+                      android:description="@string/permgroupdesc_storage"
+                      android:priority="900" />
 
     <!-- Allows an application to read from external storage.
      <p>Any app that declares the {@link #WRITE_EXTERNAL_STORAGE} permission is implicitly
@@ -496,10 +647,10 @@
      <p>Protection level: dangerous
      -->
     <permission android:name="android.permission.READ_EXTERNAL_STORAGE"
-        android:permissionGroup="android.permission-group.STORAGE"
-        android:label="@string/permlab_sdcardRead"
-        android:description="@string/permdesc_sdcardRead"
-        android:protectionLevel="dangerous" />
+                android:permissionGroup="android.permission-group.STORAGE"
+                android:label="@string/permlab_sdcardRead"
+                android:description="@string/permdesc_sdcardRead"
+                android:protectionLevel="dangerous" />
 
     <!-- Allows an application to write to external storage.
          <p class="note"><strong>Note:</strong> If <em>both</em> your <a
@@ -517,10 +668,10 @@
          <p>Protection level: dangerous
     -->
     <permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
-        android:permissionGroup="android.permission-group.STORAGE"
-        android:label="@string/permlab_sdcardWrite"
-        android:description="@string/permdesc_sdcardWrite"
-        android:protectionLevel="dangerous" />
+                android:permissionGroup="android.permission-group.STORAGE"
+                android:label="@string/permlab_sdcardWrite"
+                android:description="@string/permdesc_sdcardWrite"
+                android:protectionLevel="dangerous" />
 
     <!-- ====================================================================== -->
     <!-- Permissions for accessing the device location                          -->
@@ -529,28 +680,28 @@
 
     <!-- Used for permissions that allow accessing the device location. -->
     <permission-group android:name="android.permission-group.LOCATION"
-        android:icon="@drawable/perm_group_location"
-        android:label="@string/permgrouplab_location"
-        android:description="@string/permgroupdesc_location"
-        android:priority="400" />
+                      android:icon="@drawable/perm_group_location"
+                      android:label="@string/permgrouplab_location"
+                      android:description="@string/permgroupdesc_location"
+                      android:priority="400" />
 
     <!-- Allows an app to access precise location.
          <p>Protection level: dangerous
     -->
     <permission android:name="android.permission.ACCESS_FINE_LOCATION"
-        android:permissionGroup="android.permission-group.LOCATION"
-        android:label="@string/permlab_accessFineLocation"
-        android:description="@string/permdesc_accessFineLocation"
-        android:protectionLevel="dangerous" />
+                android:permissionGroup="android.permission-group.LOCATION"
+                android:label="@string/permlab_accessFineLocation"
+                android:description="@string/permdesc_accessFineLocation"
+                android:protectionLevel="dangerous" />
 
     <!-- Allows an app to access approximate location.
          <p>Protection level: dangerous
     -->
     <permission android:name="android.permission.ACCESS_COARSE_LOCATION"
-        android:permissionGroup="android.permission-group.LOCATION"
-        android:label="@string/permlab_accessCoarseLocation"
-        android:description="@string/permdesc_accessCoarseLocation"
-        android:protectionLevel="dangerous" />
+                android:permissionGroup="android.permission-group.LOCATION"
+                android:label="@string/permlab_accessCoarseLocation"
+                android:description="@string/permdesc_accessCoarseLocation"
+                android:protectionLevel="dangerous" />
 
     <!-- ====================================================================== -->
     <!-- Permissions for accessing the device telephony                         -->
@@ -559,12 +710,14 @@
 
     <!-- Used for permissions that are associated telephony features. -->
     <permission-group android:name="android.permission-group.PHONE"
-        android:icon="@drawable/perm_group_phone_calls"
-        android:label="@string/permgrouplab_phone"
-        android:description="@string/permgroupdesc_phone"
-        android:priority="500" />
+                      android:icon="@drawable/perm_group_phone_calls"
+                      android:label="@string/permgrouplab_phone"
+                      android:description="@string/permgroupdesc_phone"
+                      android:priority="500" />
 
-    <!-- Allows read only access to phone state.
+    <!-- Allows read only access to phone state, including the phone number of the device,
+         current cellular network information, the status of any ongoing calls, and a list of any
+         {@link android.telecom.PhoneAccount}s registered on the device.
          <p class="note"><strong>Note:</strong> If <em>both</em> your <a
          href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code
          minSdkVersion}</a> and <a
@@ -576,32 +729,32 @@
          <p>Protection level: dangerous
     -->
     <permission android:name="android.permission.READ_PHONE_STATE"
-        android:permissionGroup="android.permission-group.PHONE"
-        android:label="@string/permlab_readPhoneState"
-        android:description="@string/permdesc_readPhoneState"
-        android:protectionLevel="dangerous" />
+                android:permissionGroup="android.permission-group.PHONE"
+                android:label="@string/permlab_readPhoneState"
+                android:description="@string/permdesc_readPhoneState"
+                android:protectionLevel="dangerous" />
 
     <!-- Allows an application to initiate a phone call without going through
         the Dialer user interface for the user to confirm the call.
         <p>Protection level: dangerous
     -->
     <permission android:name="android.permission.CALL_PHONE"
-        android:permissionGroup="android.permission-group.PHONE"
-        android:permissionFlags="costsMoney"
-        android:label="@string/permlab_callPhone"
-        android:description="@string/permdesc_callPhone"
-        android:protectionLevel="dangerous" />
+                android:permissionGroup="android.permission-group.PHONE"
+                android:permissionFlags="costsMoney"
+                android:label="@string/permlab_callPhone"
+                android:description="@string/permdesc_callPhone"
+                android:protectionLevel="dangerous" />
 
     <!-- Allows an application to access the IMS call service: making and
          modifying a call
-        <p>Protection level: signature|system
+        <p>Protection level: signature|privileged
         @hide
     -->
     <permission android:name="android.permission.ACCESS_IMS_CALL_SERVICE"
-        android:permissionGroup="android.permission-group.PHONE"
-        android:label="@string/permlab_accessImsCallService"
-        android:description="@string/permdesc_accessImsCallService"
-        android:protectionLevel="signature|system" />
+                android:permissionGroup="android.permission-group.PHONE"
+                android:label="@string/permlab_accessImsCallService"
+                android:description="@string/permdesc_accessImsCallService"
+                android:protectionLevel="signature|privileged" />
 
     <!-- Allows an application to read the user's call log.
          <p class="note"><strong>Note:</strong> If your app uses the
@@ -616,13 +769,13 @@
          <p>Protection level: dangerous
     -->
     <permission android:name="android.permission.READ_CALL_LOG"
-        android:permissionGroup="android.permission-group.PHONE"
-        android:label="@string/permlab_readCallLog"
-        android:description="@string/permdesc_readCallLog"
-        android:protectionLevel="dangerous" />
+                android:permissionGroup="android.permission-group.PHONE"
+                android:label="@string/permlab_readCallLog"
+                android:description="@string/permdesc_readCallLog"
+                android:protectionLevel="dangerous" />
 
     <!-- Allows an application to write (but not read) the user's
-         contacts data.
+         call log data.
          <p class="note"><strong>Note:</strong> If your app uses the
          {@link #WRITE_CONTACTS} permission and <em>both</em> your <a
          href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code
@@ -635,28 +788,28 @@
          <p>Protection level: dangerous
     -->
     <permission android:name="android.permission.WRITE_CALL_LOG"
-        android:permissionGroup="android.permission-group.PHONE"
-        android:label="@string/permlab_writeCallLog"
-        android:description="@string/permdesc_writeCallLog"
-        android:protectionLevel="dangerous" />
+                android:permissionGroup="android.permission-group.PHONE"
+                android:label="@string/permlab_writeCallLog"
+                android:description="@string/permdesc_writeCallLog"
+                android:protectionLevel="dangerous" />
 
     <!-- Allows an application to add voicemails into the system.
          <p>Protection level: dangerous
     -->
     <permission android:name="com.android.voicemail.permission.ADD_VOICEMAIL"
-        android:permissionGroup="android.permission-group.PHONE"
-        android:label="@string/permlab_addVoicemail"
-        android:description="@string/permdesc_addVoicemail"
-        android:protectionLevel="dangerous" />
+                android:permissionGroup="android.permission-group.PHONE"
+                android:label="@string/permlab_addVoicemail"
+                android:description="@string/permdesc_addVoicemail"
+                android:protectionLevel="dangerous" />
 
     <!-- Allows an application to use SIP service.
          <p>Protection level: dangerous
     -->
     <permission android:name="android.permission.USE_SIP"
-        android:permissionGroup="android.permission-group.PHONE"
-        android:description="@string/permdesc_use_sip"
-        android:label="@string/permlab_use_sip"
-        android:protectionLevel="dangerous"/>
+                android:permissionGroup="android.permission-group.PHONE"
+                android:description="@string/permdesc_use_sip"
+                android:label="@string/permlab_use_sip"
+                android:protectionLevel="dangerous"/>
 
     <!-- Allows an application to see the number being dialed during an outgoing
          call with the option to redirect the call to a different number or
@@ -664,10 +817,10 @@
          <p>Protection level: dangerous
     -->
     <permission android:name="android.permission.PROCESS_OUTGOING_CALLS"
-        android:permissionGroup="android.permission-group.PHONE"
-        android:label="@string/permlab_processOutgoingCalls"
-        android:description="@string/permdesc_processOutgoingCalls"
-        android:protectionLevel="dangerous" />
+                android:permissionGroup="android.permission-group.PHONE"
+                android:label="@string/permlab_processOutgoingCalls"
+                android:description="@string/permdesc_processOutgoingCalls"
+                android:protectionLevel="dangerous" />
 
     <!-- ====================================================================== -->
     <!-- Permissions for accessing the device microphone                        -->
@@ -678,19 +831,39 @@
          microphone audio from the device. Note that phone calls also capture audio
          but are in a separate (more visible) permission group. -->
     <permission-group android:name="android.permission-group.MICROPHONE"
-        android:icon="@drawable/perm_group_microphone"
-        android:label="@string/permgrouplab_microphone"
-        android:description="@string/permgroupdesc_microphone"
-        android:priority="600" />
+                      android:icon="@drawable/perm_group_microphone"
+                      android:label="@string/permgrouplab_microphone"
+                      android:description="@string/permgroupdesc_microphone"
+                      android:priority="600" />
 
     <!-- Allows an application to record audio.
          <p>Protection level: dangerous
     -->
     <permission android:name="android.permission.RECORD_AUDIO"
-        android:permissionGroup="android.permission-group.MICROPHONE"
-        android:label="@string/permlab_recordAudio"
-        android:description="@string/permdesc_recordAudio"
-        android:protectionLevel="dangerous"/>
+                android:permissionGroup="android.permission-group.MICROPHONE"
+                android:label="@string/permlab_recordAudio"
+                android:description="@string/permdesc_recordAudio"
+                android:protectionLevel="dangerous"/>
+
+    <!-- ====================================================================== -->
+    <!-- Permissions for accessing the UCE Service                              -->
+    <!-- ====================================================================== -->
+
+    <!-- @hide Allows an application to Access UCE-Presence.
+         <p>Protection level: dangerous
+    -->
+    <permission android:name="android.permission.ACCESS_UCE_PRESENCE_SERVICE"
+                android:permissionGroup="android.permission-group.PHONE"
+                android:protectionLevel="signatureOrSystem"/>
+
+    <!-- @hide Allows an application to Access UCE-OPTIONS.
+         <p>Protection level: dangerous
+    -->
+    <permission android:name="android.permission.ACCESS_UCE_OPTIONS_SERVICE"
+                android:permissionGroup="android.permission-group.PHONE"
+                android:protectionLevel="signatureOrSystem"/>
+
+
 
     <!-- ====================================================================== -->
     <!-- Permissions for accessing the device camera                            -->
@@ -700,25 +873,25 @@
     <!-- Used for permissions that are associated with accessing
      camera or capturing images/video from the device. -->
     <permission-group android:name="android.permission-group.CAMERA"
-        android:icon="@drawable/perm_group_camera"
-        android:label="@string/permgrouplab_camera"
-        android:description="@string/permgroupdesc_camera"
-        android:priority="700" />
+                      android:icon="@drawable/perm_group_camera"
+                      android:label="@string/permgrouplab_camera"
+                      android:description="@string/permgroupdesc_camera"
+                      android:priority="700" />
 
     <!-- Required to be able to access the camera device.
          <p>This will automatically enforce the <a
-         href="{@docRoot}guide/topics/manifest/uses-feature-element.html">{@code
-         &lt;uses-feature&gt;}</a> manifest element for <em>all</em> camera features.
+         href="{@docRoot}guide/topics/manifest/uses-feature-element.html">
+         <uses-feature>}</a> manifest element for <em>all</em> camera features.
          If you do not require all camera features or can properly operate if a camera
          is not available, then you must modify your manifest as appropriate in order to
          install on devices that don't support all camera features.</p>
          <p>Protection level: dangerous
     -->
     <permission android:name="android.permission.CAMERA"
-        android:permissionGroup="android.permission-group.CAMERA"
-        android:label="@string/permlab_camera"
-        android:description="@string/permdesc_camera"
-        android:protectionLevel="dangerous" />
+                android:permissionGroup="android.permission-group.CAMERA"
+                android:label="@string/permlab_camera"
+                android:description="@string/permdesc_camera"
+                android:protectionLevel="dangerous" />
 
 
     <!-- ====================================================================== -->
@@ -729,28 +902,28 @@
     <!-- Used for permissions that are associated with accessing
          camera or capturing images/video from the device. -->
     <permission-group android:name="android.permission-group.SENSORS"
-        android:icon="@drawable/perm_group_sensors"
-        android:label="@string/permgrouplab_sensors"
-        android:description="@string/permgroupdesc_sensors"
-        android:priority="800" />
+                      android:icon="@drawable/perm_group_sensors"
+                      android:label="@string/permgrouplab_sensors"
+                      android:description="@string/permgroupdesc_sensors"
+                      android:priority="800" />
 
     <!-- Allows an application to access data from sensors that the user uses to
          measure what is happening inside his/her body, such as heart rate.
          <p>Protection level: dangerous -->
     <permission android:name="android.permission.BODY_SENSORS"
-        android:permissionGroup="android.permission-group.SENSORS"
-        android:label="@string/permlab_bodySensors"
-        android:description="@string/permdesc_bodySensors"
-        android:protectionLevel="dangerous" />
+                android:permissionGroup="android.permission-group.SENSORS"
+                android:label="@string/permlab_bodySensors"
+                android:description="@string/permdesc_bodySensors"
+                android:protectionLevel="dangerous" />
 
     <!-- Allows an app to use fingerprint hardware.
          <p>Protection level: normal
     -->
     <permission android:name="android.permission.USE_FINGERPRINT"
-        android:permissionGroup="android.permission-group.SENSORS"
-        android:label="@string/permlab_useFingerprint"
-        android:description="@string/permdesc_useFingerprint"
-        android:protectionLevel="normal" />
+                android:permissionGroup="android.permission-group.SENSORS"
+                android:label="@string/permlab_useFingerprint"
+                android:description="@string/permdesc_useFingerprint"
+                android:protectionLevel="normal" />
 
     <!-- ====================================================================== -->
     <!-- REMOVED PERMISSIONS                                                    -->
@@ -758,73 +931,78 @@
 
     <!-- @hide We need to keep this around for backwards compatibility -->
     <permission android:name="android.permission.READ_PROFILE"
-        android:protectionLevel="normal"
-        android:permissionFlags="hidden"/>
+                android:protectionLevel="normal"
+                android:permissionFlags="removed"/>
 
     <!-- @hide We need to keep this around for backwards compatibility -->
     <permission android:name="android.permission.WRITE_PROFILE"
-        android:protectionLevel="normal"
-        android:permissionFlags="hidden"/>
+                android:protectionLevel="normal"
+                android:permissionFlags="removed"/>
 
     <!-- @hide We need to keep this around for backwards compatibility -->
     <permission android:name="android.permission.READ_SOCIAL_STREAM"
-        android:protectionLevel="normal"
-        android:permissionFlags="hidden"/>
+                android:protectionLevel="normal"
+                android:permissionFlags="removed"/>
 
     <!-- @hide We need to keep this around for backwards compatibility -->
     <permission android:name="android.permission.WRITE_SOCIAL_STREAM"
-        android:protectionLevel="normal"
-        android:permissionFlags="hidden"/>
+                android:protectionLevel="normal"
+                android:permissionFlags="removed"/>
 
     <!-- @hide We need to keep this around for backwards compatibility -->
     <permission android:name="android.permission.READ_USER_DICTIONARY"
-        android:protectionLevel="normal"
-        android:permissionFlags="hidden"/>
+                android:protectionLevel="normal"
+                android:permissionFlags="removed"/>
 
     <!-- @hide We need to keep this around for backwards compatibility -->
     <permission android:name="android.permission.WRITE_USER_DICTIONARY"
-        android:protectionLevel="normal"
-        android:permissionFlags="hidden"/>
+                android:protectionLevel="normal"
+                android:permissionFlags="removed"/>
 
     <!-- @hide We need to keep this around for backwards compatibility -->
     <permission android:name="android.permission.WRITE_SMS"
-        android:protectionLevel="normal"
-        android:permissionFlags="hidden"/>
+                android:protectionLevel="normal"
+                android:permissionFlags="removed"/>
 
     <!-- @hide We need to keep this around for backwards compatibility -->
     <permission android:name="com.android.browser.permission.READ_HISTORY_BOOKMARKS"
-        android:protectionLevel="normal"
-        android:permissionFlags="hidden"/>
+                android:protectionLevel="normal"
+                android:permissionFlags="removed"/>
 
     <!-- @hide We need to keep this around for backwards compatibility -->
     <permission android:name="com.android.browser.permission.WRITE_HISTORY_BOOKMARKS"
-        android:protectionLevel="normal"
-        android:permissionFlags="hidden"/>
+                android:protectionLevel="normal"
+                android:permissionFlags="removed"/>
 
     <!-- @hide We need to keep this around for backwards compatibility -->
     <permission android:name="android.permission.AUTHENTICATE_ACCOUNTS"
-        android:protectionLevel="normal"
-        android:permissionFlags="hidden"/>
+                android:protectionLevel="normal"
+                android:permissionFlags="removed"/>
 
     <!-- @hide We need to keep this around for backwards compatibility -->
     <permission android:name="android.permission.MANAGE_ACCOUNTS"
-        android:protectionLevel="normal"
-        android:permissionFlags="hidden"/>
+                android:protectionLevel="normal"
+                android:permissionFlags="removed"/>
 
     <!-- @hide We need to keep this around for backwards compatibility -->
     <permission android:name="android.permission.USE_CREDENTIALS"
-        android:protectionLevel="normal"
-        android:permissionFlags="hidden"/>
+                android:protectionLevel="normal"
+                android:permissionFlags="removed"/>
 
     <!-- @hide We need to keep this around for backwards compatibility -->
     <permission android:name="android.permission.SUBSCRIBED_FEEDS_READ"
-        android:protectionLevel="normal"
-        android:permissionFlags="hidden"/>
+                android:protectionLevel="normal"
+                android:permissionFlags="removed"/>
 
     <!-- @hide We need to keep this around for backwards compatibility -->
     <permission android:name="android.permission.SUBSCRIBED_FEEDS_WRITE"
-        android:protectionLevel="normal"
-        android:permissionFlags="hidden"/>
+                android:protectionLevel="normal"
+                android:permissionFlags="removed"/>
+
+    <!-- @hide We need to keep this around for backwards compatibility -->
+    <permission android:name="android.permission.FLASHLIGHT"
+                android:protectionLevel="normal"
+                android:permissionFlags="removed"/>
 
     <!-- ====================================================================== -->
     <!-- INSTALL PERMISSIONS                                                    -->
@@ -839,31 +1017,40 @@
          to handle the respond-via-message action during incoming calls.
          <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.SEND_RESPOND_VIA_MESSAGE"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
+
+    <!-- @SystemApi Allows an application to send SMS to premium shortcodes without user permission.
+         <p>Not for use by third-party applications. -->
+    <permission android:name="android.permission.SEND_SMS_NO_CONFIRMATION"
+                android:protectionLevel="signature|privileged" />
 
     <!-- Allows an application to filter carrier specific sms.
          @hide -->
     <permission android:name="android.permission.CARRIER_FILTER_SMS"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to receive emergency cell broadcast messages,
          to record or display them to the user.
-         <p>Not for use by third-party applications.
-         @hide Pending API council approval -->
+         <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.RECEIVE_EMERGENCY_BROADCAST"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- Allows an application to monitor incoming Bluetooth MAP messages, to record
          or perform processing on them. -->
     <!-- @hide -->
     <permission android:name="android.permission.RECEIVE_BLUETOOTH_MAP"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi @hide Allows an application to execute contacts directory search.
          This should only be used by ContactsProvider.
          <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.BIND_DIRECTORY_SEARCH"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
+
+    <!-- @SystemApi @hide Allows an application to modify cell broadcasts through the content provider.
+         <p>Not for use by third-party applications. -->
+    <permission android:name="android.permission.MODIFY_CELL_BROADCASTS"
+                android:protectionLevel="signature|privileged" />
 
     <!-- =============================================================== -->
     <!-- Permissions for setting the device alarm                        -->
@@ -874,9 +1061,9 @@
          <p>Protection level: normal
     -->
     <permission android:name="com.android.alarm.permission.SET_ALARM"
-        android:label="@string/permlab_setAlarm"
-        android:description="@string/permdesc_setAlarm"
-        android:protectionLevel="normal" />
+                android:label="@string/permlab_setAlarm"
+                android:description="@string/permdesc_setAlarm"
+                android:protectionLevel="normal" />
 
     <!-- =============================================================== -->
     <!-- Permissions for accessing the user voicemail                    -->
@@ -884,16 +1071,16 @@
     <eat-comment />
 
     <!-- Allows an application to modify and remove existing voicemails in the system
-        <p>Protection level: system|signature
+        <p>Protection level: signature|privileged
     -->
     <permission android:name="com.android.voicemail.permission.WRITE_VOICEMAIL"
-        android:protectionLevel="system|signature" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- Allows an application to read voicemails in the system.
-         <p>Protection level: system|signature
+         <p>Protection level: signature|privileged
     -->
     <permission android:name="com.android.voicemail.permission.READ_VOICEMAIL"
-        android:protectionLevel="system|signature" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- ======================================= -->
     <!-- Permissions for accessing location info -->
@@ -904,26 +1091,26 @@
          <p>Protection level: normal
     -->
     <permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"
-        android:label="@string/permlab_accessLocationExtraCommands"
-        android:description="@string/permdesc_accessLocationExtraCommands"
-        android:protectionLevel="normal" />
+                android:label="@string/permlab_accessLocationExtraCommands"
+                android:description="@string/permdesc_accessLocationExtraCommands"
+                android:protectionLevel="normal" />
 
     <!-- @SystemApi Allows an application to install a location provider into the Location Manager.
     <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.INSTALL_LOCATION_PROVIDER"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi @hide Allows HDMI-CEC service to access device and configuration files.
          This should only be used by HDMI-CEC service.
     -->
     <permission android:name="android.permission.HDMI_CEC"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to use location features in hardware,
          such as the geofencing api.
          <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.LOCATION_HARDWARE"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
     <uses-permission android:name="android.permission.LOCATION_HARDWARE"/>
 
     <!-- @SystemApi Allows an application to create mock location providers for testing.
@@ -931,7 +1118,7 @@
          @hide
     -->
     <permission android:name="android.permission.ACCESS_MOCK_LOCATION"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- ======================================= -->
     <!-- Permissions for accessing networks -->
@@ -942,67 +1129,73 @@
          <p>Protection level: normal
     -->
     <permission android:name="android.permission.INTERNET"
-        android:description="@string/permdesc_createNetworkSockets"
-        android:label="@string/permlab_createNetworkSockets"
-        android:protectionLevel="normal" />
+                android:description="@string/permdesc_createNetworkSockets"
+                android:label="@string/permlab_createNetworkSockets"
+                android:protectionLevel="normal" />
 
     <!-- Allows applications to access information about networks
          <p>Protection level: normal
     -->
     <permission android:name="android.permission.ACCESS_NETWORK_STATE"
-        android:description="@string/permdesc_accessNetworkState"
-        android:label="@string/permlab_accessNetworkState"
-        android:protectionLevel="normal" />
+                android:description="@string/permdesc_accessNetworkState"
+                android:label="@string/permlab_accessNetworkState"
+                android:protectionLevel="normal" />
 
     <!-- Allows applications to access information about Wi-Fi networks.
          <p>Protection level: normal
     -->
     <permission android:name="android.permission.ACCESS_WIFI_STATE"
-        android:description="@string/permdesc_accessWifiState"
-        android:label="@string/permlab_accessWifiState"
-        android:protectionLevel="normal" />
+                android:description="@string/permdesc_accessWifiState"
+                android:label="@string/permlab_accessWifiState"
+                android:protectionLevel="normal" />
 
     <!-- Allows applications to change Wi-Fi connectivity state.
          <p>Protection level: normal
     -->
     <permission android:name="android.permission.CHANGE_WIFI_STATE"
-        android:description="@string/permdesc_changeWifiState"
-        android:label="@string/permlab_changeWifiState"
-        android:protectionLevel="normal" />
+                android:description="@string/permdesc_changeWifiState"
+                android:label="@string/permlab_changeWifiState"
+                android:protectionLevel="normal" />
 
     <!-- @SystemApi @hide Allows applications to read Wi-Fi credential.
          <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.READ_WIFI_CREDENTIAL"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
+
+    <!-- @SystemApi @hide Allows applications to change tether state and run
+         tether carrier provisioning.
+         <p>Not for use by third-party applications. -->
+    <permission android:name="android.permission.TETHER_PRIVILEGED"
+                android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi @hide Allow system apps to receive broadcast
          when a wifi network credential is changed.
          <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.RECEIVE_WIFI_CREDENTIAL_CHANGE"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi @hide Allows an application to modify any wifi configuration, even if created
      by another application. Once reconfigured the original creator cannot make any further
      modifications.
      <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.OVERRIDE_WIFI_CONFIG"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- @hide -->
     <permission android:name="android.permission.ACCESS_WIMAX_STATE"
-        android:description="@string/permdesc_accessWimaxState"
-        android:label="@string/permlab_accessWimaxState"
-        android:protectionLevel="normal" />
+                android:description="@string/permdesc_accessWimaxState"
+                android:label="@string/permlab_accessWimaxState"
+                android:protectionLevel="normal" />
 
     <!-- @hide -->
     <permission android:name="android.permission.CHANGE_WIMAX_STATE"
-        android:description="@string/permdesc_changeWimaxState"
-        android:label="@string/permlab_changeWimaxState"
-        android:protectionLevel="normal" />
+                android:description="@string/permdesc_changeWimaxState"
+                android:label="@string/permlab_changeWimaxState"
+                android:protectionLevel="normal" />
 
     <!-- Allows applications to act as network scorers. @hide @SystemApi-->
     <permission android:name="android.permission.SCORE_NETWORKS"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- ======================================= -->
     <!-- Permissions for short range, peripheral networks -->
@@ -1013,68 +1206,68 @@
          <p>Protection level: normal
     -->
     <permission android:name="android.permission.BLUETOOTH"
-        android:description="@string/permdesc_bluetooth"
-        android:label="@string/permlab_bluetooth"
-        android:protectionLevel="normal" />
+                android:description="@string/permdesc_bluetooth"
+                android:label="@string/permlab_bluetooth"
+                android:protectionLevel="normal" />
 
     <!-- Allows applications to discover and pair bluetooth devices.
          <p>Protection level: normal
     -->
     <permission android:name="android.permission.BLUETOOTH_ADMIN"
-        android:description="@string/permdesc_bluetoothAdmin"
-        android:label="@string/permlab_bluetoothAdmin"
-        android:protectionLevel="normal" />
+                android:description="@string/permdesc_bluetoothAdmin"
+                android:label="@string/permlab_bluetoothAdmin"
+                android:protectionLevel="normal" />
 
     <!-- @SystemApi Allows applications to pair bluetooth devices without user interaction, and to
          allow or disallow phonebook access or message access.
          This is not available to third party applications. -->
     <permission android:name="android.permission.BLUETOOTH_PRIVILEGED"
-        android:protectionLevel="system|signature" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- Control access to email providers exclusively for Bluetooth
          @hide
     -->
     <permission android:name="android.permission.BLUETOOTH_MAP"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- Allows bluetooth stack to access files
          @hide This should only be used by Bluetooth apk.
     -->
     <permission android:name="android.permission.BLUETOOTH_STACK"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- Allows applications to perform I/O operations over NFC.
          <p>Protection level: normal
     -->
     <permission android:name="android.permission.NFC"
-        android:description="@string/permdesc_nfc"
-        android:label="@string/permlab_nfc"
-        android:protectionLevel="normal" />
+                android:description="@string/permdesc_nfc"
+                android:label="@string/permlab_nfc"
+                android:protectionLevel="normal" />
 
     <!-- @SystemApi Allows an internal user to use privileged ConnectivityManager APIs.
          @hide -->
     <permission android:name="android.permission.CONNECTIVITY_INTERNAL"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- Allows a system application to access hardware packet offload capabilities.
          @hide -->
     <permission android:name="android.permission.PACKET_KEEPALIVE_OFFLOAD"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi
          @hide -->
     <permission android:name="android.permission.RECEIVE_DATA_ACTIVITY_CHANGE"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows access to the loop radio (Android@Home mesh network) device.
          @hide -->
     <permission android:name="android.permission.LOOP_RADIO"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- Allows sending and receiving handover transfer status from Wifi and Bluetooth
          @hide -->
     <permission android:name="android.permission.NFC_HANDOVER_STATUS"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- ================================== -->
     <!-- Permissions for accessing accounts -->
@@ -1085,15 +1278,15 @@
         <p>Protection level: normal
     -->
     <permission android:name="android.permission.GET_ACCOUNTS"
-        android:permissionGroup="android.permission-group.CONTACTS"
-        android:protectionLevel="dangerous"
-        android:description="@string/permdesc_getAccounts"
-        android:label="@string/permlab_getAccounts" />
+                android:permissionGroup="android.permission-group.CONTACTS"
+                android:protectionLevel="dangerous"
+                android:description="@string/permdesc_getAccounts"
+                android:label="@string/permlab_getAccounts" />
 
     <!-- @SystemApi Allows applications to call into AccountAuthenticators.
     <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.ACCOUNT_MANAGER"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- ================================== -->
     <!-- Permissions for accessing hardware that may effect battery life-->
@@ -1104,42 +1297,34 @@
          <p>Protection level: normal
     -->
     <permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"
-        android:description="@string/permdesc_changeWifiMulticastState"
-        android:label="@string/permlab_changeWifiMulticastState"
-        android:protectionLevel="normal" />
+                android:description="@string/permdesc_changeWifiMulticastState"
+                android:label="@string/permlab_changeWifiMulticastState"
+                android:protectionLevel="normal" />
 
     <!-- Allows access to the vibrator.
          <p>Protection level: normal
     -->
     <permission android:name="android.permission.VIBRATE"
-        android:label="@string/permlab_vibrate"
-        android:description="@string/permdesc_vibrate"
-        android:protectionLevel="normal" />
-
-    <!-- Allows access to the flashlight.
-         <p>Protection level: normal
-    -->
-    <permission android:name="android.permission.FLASHLIGHT"
-        android:label="@string/permlab_flashlight"
-        android:description="@string/permdesc_flashlight"
-        android:protectionLevel="normal" />
+                android:label="@string/permlab_vibrate"
+                android:description="@string/permdesc_vibrate"
+                android:protectionLevel="normal" />
 
     <!-- Allows using PowerManager WakeLocks to keep processor from sleeping or screen
          from dimming.
          <p>Protection level: normal
     -->
     <permission android:name="android.permission.WAKE_LOCK"
-        android:label="@string/permlab_wakeLock"
-        android:description="@string/permdesc_wakeLock"
-        android:protectionLevel="normal" />
+                android:label="@string/permlab_wakeLock"
+                android:description="@string/permdesc_wakeLock"
+                android:protectionLevel="normal" />
 
     <!-- Allows using the device's IR transmitter, if available.
          <p>Protection level: normal
     -->
     <permission android:name="android.permission.TRANSMIT_IR"
-        android:label="@string/permlab_transmitIr"
-        android:description="@string/permdesc_transmitIr"
-        android:protectionLevel="normal" />
+                android:label="@string/permlab_transmitIr"
+                android:description="@string/permdesc_transmitIr"
+                android:protectionLevel="normal" />
 
     <!-- ==================================================== -->
     <!-- Permissions related to changing audio settings   -->
@@ -1150,9 +1335,9 @@
          <p>Protection level: normal
     -->
     <permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"
-        android:label="@string/permlab_modifyAudioSettings"
-        android:description="@string/permdesc_modifyAudioSettings"
-        android:protectionLevel="normal" />
+                android:label="@string/permlab_modifyAudioSettings"
+                android:description="@string/permdesc_modifyAudioSettings"
+                android:protectionLevel="normal" />
 
     <!-- ================================== -->
     <!-- Permissions for accessing hardware -->
@@ -1162,68 +1347,68 @@
     <!-- @SystemApi Allows an application to manage preferences and permissions for USB devices
          @hide -->
     <permission android:name="android.permission.MANAGE_USB"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to access the MTP USB kernel driver.
          For use only by the device side MTP implementation.
          @hide -->
     <permission android:name="android.permission.ACCESS_MTP"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows access to hardware peripherals.  Intended only for hardware testing.
          <p>Not for use by third-party applications.
          @hide
     -->
     <permission android:name="android.permission.HARDWARE_TEST"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- @SystemApi Allows access to FM
          @hide This is not a third-party API (intended for system apps).-->
     <permission android:name="android.permission.ACCESS_FM_RADIO"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- Allows access to configure network interfaces, configure/use IPSec, etc.
          @hide -->
     <permission android:name="android.permission.NET_ADMIN"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- Allows registration for remote audio playback. @hide -->
     <permission android:name="android.permission.REMOTE_AUDIO_PLAYBACK"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- @SystemApi Allows TvInputService to access underlying TV input hardware such as
          built-in tuners and HDMI-in's.
          @hide This should only be used by OEM's TvInputService's.
     -->
     <permission android:name="android.permission.TV_INPUT_HARDWARE"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows to capture a frame of TV input hardware such as
          built-in tuners and HDMI-in's.
          @hide <p>Not for use by third-party applications.
     -->
     <permission android:name="android.permission.CAPTURE_TV_INPUT"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- @hide Allows TvInputService to access DVB device.
    <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.DVB_DEVICE"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- @hide Allows enabling/disabling OEM unlock
    <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.OEM_UNLOCK_STATE"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- @hide Allows querying state of PersistentDataBlock
    <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.ACCESS_PDB_STATE"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- @hide Allows system update service to notify device owner about pending updates.
    <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.NOTIFY_PENDING_SYSTEM_UPDATE"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- =========================================== -->
     <!-- Permissions associated with camera and image capture -->
@@ -1234,12 +1419,12 @@
          a camera is in use by an application.
          @hide -->
     <permission android:name="android.permission.CAMERA_DISABLE_TRANSMIT_LED"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- Allows sending the camera service notifications about system-wide events.
         @hide -->
     <permission android:name="android.permission.CAMERA_SEND_SYSTEM_EVENTS"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- =========================================== -->
     <!-- Permissions associated with telephony state -->
@@ -1250,43 +1435,50 @@
          Does not include placing calls.
          <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.MODIFY_PHONE_STATE"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- Allows read only access to precise phone state.
          @hide Pending API council approval -->
     <permission android:name="android.permission.READ_PRECISE_PHONE_STATE"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows read access to privileged phone state.
          @hide Used internally. -->
     <permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Protects the ability to register any PhoneAccount with
          PhoneAccount#CAPABILITY_SIM_SUBSCRIPTION. This capability indicates that the PhoneAccount
          corresponds to a device SIM.
          @hide -->
     <permission android:name="android.permission.REGISTER_SIM_SUBSCRIPTION"
-        android:protectionLevel="system|signature" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Protects the ability to register any PhoneAccount with
          PhoneAccount#CAPABILITY_CALL_PROVIDER.
          @hide -->
     <permission android:name="android.permission.REGISTER_CALL_PROVIDER"
-        android:protectionLevel="system|signature" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Protects the ability to register any PhoneAccount with
          PhoneAccount#CAPABILITY_CONNECTION_MANAGER
          @hide -->
     <permission android:name="android.permission.REGISTER_CONNECTION_MANAGER"
-        android:protectionLevel="system|signature" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- Must be required by a {@link android.telecom.InCallService},
          to ensure that only the system can bind to it.
-         <p>Protection level: system|signature
+         <p>Protection level: signature|privileged
     -->
     <permission android:name="android.permission.BIND_INCALL_SERVICE"
-        android:protectionLevel="system|signature" />
+                android:protectionLevel="signature|privileged" />
+
+    <!-- Must be required by a {@link android.telecom.CallScreeningService},
+         to ensure that only the system can bind to it.
+         <p>Protection level: signature|privileged
+    -->
+    <permission android:name="android.permission.BIND_SCREENING_SERVICE"
+                android:protectionLevel="signature|privileged" />
 
     <!-- Must be required by a {@link android.telecom.ConnectionService},
          to ensure that only the system can bind to it.
@@ -1295,24 +1487,24 @@
          @SystemApi
          @hide -->
     <permission android:name="android.permission.BIND_CONNECTION_SERVICE"
-        android:protectionLevel="system|signature" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- Must be required by a {@link android.telecom.ConnectionService},
          to ensure that only the system can bind to it.
-         <p>Protection level: system|signature
+         <p>Protection level: signature|privileged
     -->
     <permission android:name="android.permission.BIND_TELECOM_CONNECTION_SERVICE"
-        android:protectionLevel="system|signature" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to control the in-call experience.
          @hide -->
     <permission android:name="android.permission.CONTROL_INCALL_EXPERIENCE"
-        android:protectionLevel="system|signature" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- Allows an application to receive STK related commands.
          @hide -->
     <permission android:name="android.permission.RECEIVE_STK_COMMANDS"
-        android:protectionLevel="system|signature" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- ================================== -->
     <!-- Permissions for sdcard interaction -->
@@ -1322,14 +1514,24 @@
     <!-- @SystemApi Allows an application to write to internal media storage
          @hide  -->
     <permission android:name="android.permission.WRITE_MEDIA_STORAGE"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- Allows an application to manage access to documents, usually as part
          of a document picker.
+         <p>This permission should <em>only</em> be requested by the platform
+         document management app.  This permission cannot be granted to
+         third-party apps.
          <p>Protection level: signature
     -->
     <permission android:name="android.permission.MANAGE_DOCUMENTS"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
+
+    <!-- @hide Allows an application to cache content.
+         <p>Not for use by third-party applications.
+         <p>Protection level: signature
+    -->
+    <permission android:name="android.permission.CACHE_CONTENT"
+                android:protectionLevel="signature" />
 
     <!-- ================================== -->
     <!-- Permissions for screenlock         -->
@@ -1340,9 +1542,9 @@
          <p>Protection level: normal
     -->
     <permission android:name="android.permission.DISABLE_KEYGUARD"
-        android:description="@string/permdesc_disableKeyguard"
-        android:label="@string/permlab_disableKeyguard"
-        android:protectionLevel="normal" />
+                android:description="@string/permdesc_disableKeyguard"
+                android:label="@string/permlab_disableKeyguard"
+                android:protectionLevel="normal" />
 
     <!-- ================================== -->
     <!-- Permissions to access other installed applications  -->
@@ -1351,9 +1553,9 @@
 
     <!-- @deprecated No longer enforced. -->
     <permission android:name="android.permission.GET_TASKS"
-        android:label="@string/permlab_getTasks"
-        android:description="@string/permdesc_getTasks"
-        android:protectionLevel="normal" />
+                android:label="@string/permlab_getTasks"
+                android:description="@string/permdesc_getTasks"
+                android:protectionLevel="normal" />
 
     <!-- New version of GET_TASKS that apps can request, since GET_TASKS doesn't really
          give access to task information.  We need this new one because there are
@@ -1366,87 +1568,98 @@
          @hide
          @SystemApi -->
     <permission android:name="android.permission.REAL_GET_TASKS"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- Allows an application to start a task from a ActivityManager#RecentTaskInfo.
          @hide -->
     <permission android:name="android.permission.START_TASKS_FROM_RECENTS"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi @hide Allows an application to call APIs that allow it to do interactions
          across the users on the device, using singleton services and
          user-targeted broadcasts.  This permission is not available to
          third party applications. -->
     <permission android:name="android.permission.INTERACT_ACROSS_USERS"
-        android:protectionLevel="signature|privileged|development" />
+                android:protectionLevel="signature|privileged|development" />
 
     <!-- @hide Fuller form of {@link android.Manifest.permission#INTERACT_ACROSS_USERS}
          that removes restrictions on where broadcasts can be sent and allows other
          types of interactions. -->
     <permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL"
-        android:protectionLevel="signature|installer" />
+                android:protectionLevel="signature|installer" />
 
     <!-- @SystemApi @hide Allows an application to call APIs that allow it to query and manage
          users on the device. This permission is not available to
          third party applications. -->
     <permission android:name="android.permission.MANAGE_USERS"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- @hide Allows an application to set the profile owners and the device owner.
          This permission is not available to third party applications.-->
     <permission android:name="android.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS"
-        android:protectionLevel="signature"
-        android:label="@string/permlab_manageProfileAndDeviceOwners"
-        android:description="@string/permdesc_manageProfileAndDeviceOwners" />
+                android:protectionLevel="signature"
+                android:label="@string/permlab_manageProfileAndDeviceOwners"
+                android:description="@string/permdesc_manageProfileAndDeviceOwners" />
 
     <!-- Allows an application to get full detailed information about
          recently running tasks, with full fidelity to the real state.
          @hide -->
     <permission android:name="android.permission.GET_DETAILED_TASKS"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- Allows an application to change the Z-order of tasks.
          <p>Protection level: normal
     -->
     <permission android:name="android.permission.REORDER_TASKS"
-        android:label="@string/permlab_reorderTasks"
-        android:description="@string/permdesc_reorderTasks"
-        android:protectionLevel="normal" />
+                android:label="@string/permlab_reorderTasks"
+                android:description="@string/permdesc_reorderTasks"
+                android:protectionLevel="normal" />
 
     <!-- @hide Allows an application to change to remove/kill tasks -->
     <permission android:name="android.permission.REMOVE_TASKS"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- @SystemApi @hide Allows an application to create/manage/remove stacks -->
     <permission android:name="android.permission.MANAGE_ACTIVITY_STACKS"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- Allows an application to start any activity, regardless of permission
          protection or exported state.
          @hide -->
     <permission android:name="android.permission.START_ANY_ACTIVITY"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- @deprecated The {@link android.app.ActivityManager#restartPackage}
         API is no longer supported. -->
     <permission android:name="android.permission.RESTART_PACKAGES"
-        android:label="@string/permlab_killBackgroundProcesses"
-        android:description="@string/permdesc_killBackgroundProcesses"
-        android:protectionLevel="normal" />
+                android:label="@string/permlab_killBackgroundProcesses"
+                android:description="@string/permdesc_killBackgroundProcesses"
+                android:protectionLevel="normal" />
 
     <!-- Allows an application to call
         {@link android.app.ActivityManager#killBackgroundProcesses}.
          <p>Protection level: normal
     -->
     <permission android:name="android.permission.KILL_BACKGROUND_PROCESSES"
-        android:label="@string/permlab_killBackgroundProcesses"
-        android:description="@string/permdesc_killBackgroundProcesses"
-        android:protectionLevel="normal" />
+                android:label="@string/permlab_killBackgroundProcesses"
+                android:description="@string/permdesc_killBackgroundProcesses"
+                android:protectionLevel="normal" />
+
+    <!-- @SystemApi @hide Allows an application to query process states and current
+         OOM adjustment scores.
+         <p>Not for use by third-party applications. -->
+    <permission android:name="android.permission.GET_PROCESS_STATE_AND_OOM_SCORE"
+                android:protectionLevel="signature|privileged|development" />
 
     <!-- @SystemApi @hide Allows an application to retrieve a package's importance.
          This permission is not available to third party applications. -->
     <permission android:name="android.permission.GET_PACKAGE_IMPORTANCE"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
+
+    <!-- Allows use of PendingIntent.getIntent().
+         @hide -->
+    <permission android:name="android.permission.GET_INTENT_SENDER_INTENT"
+                android:protectionLevel="signature" />
 
     <!-- ================================== -->
     <!-- Permissions affecting the display of other applications  -->
@@ -1459,9 +1672,9 @@
          should use this permission; these windows are intended for
          system-level interaction with the user. -->
     <permission android:name="android.permission.SYSTEM_ALERT_WINDOW"
-        android:label="@string/permlab_systemAlertWindow"
-        android:description="@string/permdesc_systemAlertWindow"
-        android:protectionLevel="signature|preinstalled|appop|pre23|development" />
+                android:label="@string/permlab_systemAlertWindow"
+                android:description="@string/permdesc_systemAlertWindow"
+                android:protectionLevel="signature|preinstalled|appop|pre23|development" />
 
     <!-- ================================== -->
     <!-- Permissions affecting the system wallpaper -->
@@ -1472,17 +1685,17 @@
          <p>Protection level: normal
      -->
     <permission android:name="android.permission.SET_WALLPAPER"
-        android:label="@string/permlab_setWallpaper"
-        android:description="@string/permdesc_setWallpaper"
-        android:protectionLevel="normal" />
+                android:label="@string/permlab_setWallpaper"
+                android:description="@string/permdesc_setWallpaper"
+                android:protectionLevel="normal" />
 
     <!-- Allows applications to set the wallpaper hints.
          <p>Protection level: normal
     -->
     <permission android:name="android.permission.SET_WALLPAPER_HINTS"
-        android:label="@string/permlab_setWallpaperHints"
-        android:description="@string/permdesc_setWallpaperHints"
-        android:protectionLevel="normal" />
+                android:label="@string/permlab_setWallpaperHints"
+                android:description="@string/permdesc_setWallpaperHints"
+                android:protectionLevel="normal" />
 
     <!-- ============================================ -->
     <!-- Permissions for changing the system clock -->
@@ -1492,15 +1705,15 @@
     <!-- @SystemApi Allows applications to set the system time.
     <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.SET_TIME"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- Allows applications to set the system time zone.
          <p>Protection level: normal
     -->
     <permission android:name="android.permission.SET_TIME_ZONE"
-        android:label="@string/permlab_setTimeZone"
-        android:description="@string/permdesc_setTimeZone"
-        android:protectionLevel="normal" />
+                android:label="@string/permlab_setTimeZone"
+                android:description="@string/permdesc_setTimeZone"
+                android:protectionLevel="normal" />
 
     <!-- ==================================================== -->
     <!-- Permissions related to changing status bar   -->
@@ -1511,9 +1724,9 @@
          <p>Protection level: normal
     -->
     <permission android:name="android.permission.EXPAND_STATUS_BAR"
-        android:label="@string/permlab_expandStatusBar"
-        android:description="@string/permdesc_expandStatusBar"
-        android:protectionLevel="normal" />
+                android:label="@string/permlab_expandStatusBar"
+                android:description="@string/permdesc_expandStatusBar"
+                android:protectionLevel="normal" />
 
     <!-- ============================================================== -->
     <!-- Permissions related to adding/removing shortcuts from Launcher -->
@@ -1524,17 +1737,17 @@
          <p>Protection level: normal
     -->
     <permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT"
-        android:label="@string/permlab_install_shortcut"
-        android:description="@string/permdesc_install_shortcut"
-        android:protectionLevel="normal"/>
+                android:label="@string/permlab_install_shortcut"
+                android:description="@string/permdesc_install_shortcut"
+                android:protectionLevel="normal"/>
 
     <!-- Allows an application to uninstall a shortcut in Launcher.
          <p>Protection level: normal
     -->
     <permission android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT"
-        android:label="@string/permlab_uninstall_shortcut"
-        android:description="@string/permdesc_uninstall_shortcut"
-        android:protectionLevel="normal"/>
+                android:label="@string/permlab_uninstall_shortcut"
+                android:description="@string/permdesc_uninstall_shortcut"
+                android:protectionLevel="normal"/>
 
     <!-- ==================================================== -->
     <!-- Permissions related to accessing sync settings   -->
@@ -1545,25 +1758,25 @@
          <p>Protection level: normal
     -->
     <permission android:name="android.permission.READ_SYNC_SETTINGS"
-        android:description="@string/permdesc_readSyncSettings"
-        android:label="@string/permlab_readSyncSettings"
-        android:protectionLevel="normal" />
+                android:description="@string/permdesc_readSyncSettings"
+                android:label="@string/permlab_readSyncSettings"
+                android:protectionLevel="normal" />
 
     <!-- Allows applications to write the sync settings.
          <p>Protection level: normal
     -->
     <permission android:name="android.permission.WRITE_SYNC_SETTINGS"
-        android:description="@string/permdesc_writeSyncSettings"
-        android:label="@string/permlab_writeSyncSettings"
-        android:protectionLevel="normal" />
+                android:description="@string/permdesc_writeSyncSettings"
+                android:label="@string/permlab_writeSyncSettings"
+                android:protectionLevel="normal" />
 
     <!-- Allows applications to read the sync stats.
          <p>Protection level: normal
     -->
     <permission android:name="android.permission.READ_SYNC_STATS"
-        android:description="@string/permdesc_readSyncStats"
-        android:label="@string/permlab_readSyncStats"
-        android:protectionLevel="normal" />
+                android:description="@string/permdesc_readSyncStats"
+                android:label="@string/permlab_readSyncStats"
+                android:protectionLevel="normal" />
 
     <!-- ============================================ -->
     <!-- Permissions for low-level system interaction -->
@@ -1572,62 +1785,62 @@
 
     <!-- @SystemApi @hide Change the screen compatibility mode of applications -->
     <permission android:name="android.permission.SET_SCREEN_COMPATIBILITY"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- @SystemApi Allows an application to modify the current configuration, such
          as locale. -->
     <permission android:name="android.permission.CHANGE_CONFIGURATION"
-        android:protectionLevel="signature|privileged|development" />
+                android:protectionLevel="signature|privileged|development" />
 
     <!-- Allows an application to read or write the system settings.
          <p>Protection level: signature
     -->
     <permission android:name="android.permission.WRITE_SETTINGS"
-        android:label="@string/permlab_writeSettings"
-        android:description="@string/permdesc_writeSettings"
-        android:protectionLevel="signature|preinstalled|appop|pre23" />
+                android:label="@string/permlab_writeSettings"
+                android:description="@string/permdesc_writeSettings"
+                android:protectionLevel="signature|preinstalled|appop|pre23" />
 
     <!-- @SystemApi Allows an application to modify the Google service map.
     <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.WRITE_GSERVICES"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to call
         {@link android.app.ActivityManager#forceStopPackage}.
         @hide -->
     <permission android:name="android.permission.FORCE_STOP_PACKAGES"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi @hide Allows an application to retrieve the content of the active window
          An active window is the window that has fired an accessibility event. -->
     <permission android:name="android.permission.RETRIEVE_WINDOW_CONTENT"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Modify the global animation scaling factor.
     <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.SET_ANIMATION_SCALE"
-        android:protectionLevel="signature|privileged|development" />
+                android:protectionLevel="signature|privileged|development" />
 
     <!-- @deprecated This functionality will be removed in the future; please do
          not use. Allow an application to make its activities persistent. -->
     <permission android:name="android.permission.PERSISTENT_ACTIVITY"
-        android:label="@string/permlab_persistentActivity"
-        android:description="@string/permdesc_persistentActivity"
-        android:protectionLevel="normal" />
+                android:label="@string/permlab_persistentActivity"
+                android:description="@string/permdesc_persistentActivity"
+                android:protectionLevel="normal" />
 
     <!-- Allows an application to find out the space used by any package.
          <p>Protection level: normal
     -->
     <permission android:name="android.permission.GET_PACKAGE_SIZE"
-        android:label="@string/permlab_getPackageSize"
-        android:description="@string/permdesc_getPackageSize"
-        android:protectionLevel="normal" />
+                android:label="@string/permlab_getPackageSize"
+                android:description="@string/permdesc_getPackageSize"
+                android:protectionLevel="normal" />
 
     <!-- @deprecated No longer useful, see
          {@link android.content.pm.PackageManager#addPackageToPreferred}
          for details. -->
     <permission android:name="android.permission.SET_PREFERRED_APPLICATIONS"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- Allows an application to receive the
          {@link android.content.Intent#ACTION_BOOT_COMPLETED} that is
@@ -1643,9 +1856,9 @@
          <p>Protection level: normal
     -->
     <permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"
-        android:label="@string/permlab_receiveBootCompleted"
-        android:description="@string/permdesc_receiveBootCompleted"
-        android:protectionLevel="normal" />
+                android:label="@string/permlab_receiveBootCompleted"
+                android:description="@string/permdesc_receiveBootCompleted"
+                android:protectionLevel="normal" />
 
     <!-- Allows an application to broadcast sticky intents.  These are
          broadcasts whose data is held by the system after being finished,
@@ -1654,86 +1867,90 @@
          <p>Protection level: normal
     -->
     <permission android:name="android.permission.BROADCAST_STICKY"
-        android:label="@string/permlab_broadcastSticky"
-        android:description="@string/permdesc_broadcastSticky"
-        android:protectionLevel="normal" />
+                android:label="@string/permlab_broadcastSticky"
+                android:description="@string/permdesc_broadcastSticky"
+                android:protectionLevel="normal" />
 
     <!-- @SystemApi Allows mounting and unmounting file systems for removable storage.
     <p>Not for use by third-party applications.-->
     <permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"
-        android:protectionLevel="system|signature" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows formatting file systems for removable storage.
     <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.MOUNT_FORMAT_FILESYSTEMS"
-        android:protectionLevel="system|signature" />
+                android:protectionLevel="signature|privileged" />
+
+    <!-- @hide -->
+    <permission android:name="android.permission.STORAGE_INTERNAL"
+                android:protectionLevel="signature" />
 
     <!-- Allows access to ASEC non-destructive API calls
          @hide  -->
     <permission android:name="android.permission.ASEC_ACCESS"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- Allows creation of ASEC volumes
          @hide  -->
     <permission android:name="android.permission.ASEC_CREATE"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- Allows destruction of ASEC volumes
          @hide  -->
     <permission android:name="android.permission.ASEC_DESTROY"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- Allows mount / unmount of ASEC volumes
          @hide  -->
     <permission android:name="android.permission.ASEC_MOUNT_UNMOUNT"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- Allows rename of ASEC volumes
          @hide  -->
     <permission android:name="android.permission.ASEC_RENAME"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- @SystemApi Allows applications to write the apn settings.
     <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.WRITE_APN_SETTINGS"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- Allows applications to change network connectivity state.
          <p>Protection level: normal
     -->
     <permission android:name="android.permission.CHANGE_NETWORK_STATE"
-        android:description="@string/permdesc_changeNetworkState"
-        android:label="@string/permlab_changeNetworkState"
-        android:protectionLevel="normal" />
+                android:description="@string/permdesc_changeNetworkState"
+                android:label="@string/permlab_changeNetworkState"
+                android:protectionLevel="normal" />
 
     <!-- Allows an application to clear the caches of all installed
          applications on the device.
          <p>Protection level: system|signature
     -->
     <permission android:name="android.permission.CLEAR_APP_CACHE"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to use any media decoder when decoding for playback
          @hide -->
     <permission android:name="android.permission.ALLOW_ANY_CODEC_FOR_PLAYBACK"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to install and/or uninstall CA certificates on
          behalf of the user.
          @hide -->
     <permission android:name="android.permission.MANAGE_CA_CERTIFICATES"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to do certain operations needed for
          interacting with the recovery (system update) system.
          @hide -->
     <permission android:name="android.permission.RECOVERY"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- Allows the system to bind to an application's task services
          @hide -->
     <permission android:name="android.permission.BIND_JOB_SERVICE"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
     <uses-permission android:name="android.permission.BIND_JOB_SERVICE"/>
 
     <!-- Allows an application to initiate configuration updates
@@ -1742,7 +1959,7 @@
          it off to the various individual installer components
          @hide -->
     <permission android:name="android.permission.UPDATE_CONFIG"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- ========================================= -->
     <!-- Permissions for special development tools -->
@@ -1752,40 +1969,40 @@
     <!-- @SystemApi Allows an application to read or write the secure system settings.
     <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.WRITE_SECURE_SETTINGS"
-        android:protectionLevel="signature|privileged|development" />
+                android:protectionLevel="signature|privileged|development" />
 
     <!-- @SystemApi Allows an application to retrieve state dump information from system services.
     <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.DUMP"
-        android:protectionLevel="signature|privileged|development" />
+                android:protectionLevel="signature|privileged|development" />
 
     <!-- @SystemApi Allows an application to read the low-level system log files.
     <p>Not for use by third-party applications, because
     Log entries can contain the user's private information. -->
     <permission android:name="android.permission.READ_LOGS"
-        android:protectionLevel="signature|privileged|development" />
+                android:protectionLevel="signature|privileged|development" />
 
     <!-- @SystemApi Configure an application for debugging.
     <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.SET_DEBUG_APP"
-        android:protectionLevel="signature|privileged|development" />
+                android:protectionLevel="signature|privileged|development" />
 
     <!-- @SystemApi Allows an application to set the maximum number of (not needed)
          application processes that can be running.
          <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.SET_PROCESS_LIMIT"
-        android:protectionLevel="signature|privileged|development" />
+                android:protectionLevel="signature|privileged|development" />
 
     <!-- @SystemApi Allows an application to control whether activities are immediately
          finished when put in the background.
          <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.SET_ALWAYS_FINISH"
-        android:protectionLevel="signature|privileged|development" />
+                android:protectionLevel="signature|privileged|development" />
 
     <!-- @SystemApi Allow an application to request that a signal be sent to all persistent processes.
     <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.SIGNAL_PERSISTENT_PROCESSES"
-        android:protectionLevel="signature|privileged|development" />
+                android:protectionLevel="signature|privileged|development" />
 
     <!-- ==================================== -->
     <!-- Private permissions                  -->
@@ -1794,23 +2011,34 @@
 
     <!-- @SystemApi Allows access to the list of accounts in the Accounts Service. -->
     <permission android:name="android.permission.GET_ACCOUNTS_PRIVILEGED"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
+
+    <!-- @SystemApi Allows but does not guarantee access to user passwords at the conclusion of add
+         account -->
+    <permission android:name="android.permission.GET_PASSWORD_PRIVILEGED"
+                android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows applications to RW to diagnostic resources.
     <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.DIAGNOSTIC"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- @SystemApi Allows an application to open, close, or disable the status bar
          and its icons.
          <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.STATUS_BAR"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- Allows an application to be the status bar.  Currently used only by SystemUI.apk
     @hide -->
     <permission android:name="android.permission.STATUS_BAR_SERVICE"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
+
+    <!-- Allows an application to bind to third party quick settings tiles.
+         <p>Should only be requested by the System, should be required by
+         TileService declarations.-->
+    <permission android:name="android.permission.BIND_QUICK_SETTINGS_TILE"
+                android:protectionLevel="signature" />
 
     <!-- @SystemApi Allows an application to force a BACK operation on whatever is the
          top activity.
@@ -1818,21 +2046,27 @@
          @hide
     -->
     <permission android:name="android.permission.FORCE_BACK"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- @SystemApi Allows an application to update device statistics.
     <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.UPDATE_DEVICE_STATS"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi @hide Allows an application to collect battery statistics -->
     <permission android:name="android.permission.GET_APP_OPS_STATS"
-        android:protectionLevel="signature|privileged|development" />
+                android:protectionLevel="signature|privileged|development" />
 
     <!-- @SystemApi Allows an application to update application operation statistics. Not for
          use by third party apps. @hide -->
     <permission android:name="android.permission.UPDATE_APP_OPS_STATS"
-        android:protectionLevel="signature|privileged|installer" />
+                android:protectionLevel="signature|privileged|installer" />
+
+    <!-- Allows an application to update the user app op restrictions.
+         Not for use by third party apps.
+         @hide -->
+    <permission android:name="android.permission.MANAGE_APP_OPS_RESTRICTIONS"
+                android:protectionLevel="signature|installer" />
 
     <!-- @SystemApi Allows an application to open windows that are for use by parts
          of the system user interface.
@@ -1840,7 +2074,7 @@
          @hide
     -->
     <permission android:name="android.permission.INTERNAL_SYSTEM_WINDOW"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- @SystemApi Allows an application to manage (create, destroy,
          Z-order) application tokens in the window manager.
@@ -1848,12 +2082,17 @@
          @hide
     -->
     <permission android:name="android.permission.MANAGE_APP_TOKENS"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
+
+    <!-- Allows System UI to register listeners for events from Window Manager.
+         @hide -->
+    <permission android:name="android.permission.REGISTER_WINDOW_MANAGER_LISTENERS"
+                android:protectionLevel="signature" />
 
     <!-- @hide Allows the application to temporarily freeze the screen for a
          full-screen transition. -->
     <permission android:name="android.permission.FREEZE_SCREEN"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- @SystemApi Allows an application to inject user events (keys, touch, trackball)
          into the event stream and deliver them to ANY window.  Without this
@@ -1862,24 +2101,24 @@
          @hide
     -->
     <permission android:name="android.permission.INJECT_EVENTS"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- @hide Allows an application to register an input filter which filters the stream
          of user events (keys, touch, trackball) before they are dispatched to any window. -->
     <permission android:name="android.permission.FILTER_EVENTS"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- @hide Allows an application to retrieve the window token from the accessibility manager. -->
     <permission android:name="android.permission.RETRIEVE_WINDOW_TOKEN"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- @hide Allows an application to collect frame statistics -->
     <permission android:name="android.permission.FRAME_STATS"
-         android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- @hide Allows an application to temporary enable accessibility on the device. -->
     <permission android:name="android.permission.TEMPORARY_ENABLE_ACCESSIBILITY"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- @SystemApi Allows an application to watch and control how activities are
          started globally in the system.  Only for is in debugging
@@ -1888,13 +2127,13 @@
          @hide
     -->
     <permission android:name="android.permission.SET_ACTIVITY_WATCHER"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- @SystemApi Allows an application to call the activity manager shutdown() API
          to put the higher-level system there into a shutdown state.
          @hide -->
     <permission android:name="android.permission.SHUTDOWN"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to tell the activity manager to temporarily
          stop application switches, putting it into a special mode that
@@ -1902,7 +2141,7 @@
          critical UI such as the home screen.
          @hide -->
     <permission android:name="android.permission.STOP_APP_SWITCHES"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to retrieve private information about
          the current top activity, such as any assist context it can provide.
@@ -1910,42 +2149,51 @@
          @hide
     -->
     <permission android:name="android.permission.GET_TOP_ACTIVITY_INFO"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- Allows an application to retrieve the current state of keys and
          switches.
          <p>Not for use by third-party applications.
          @deprecated The API that used this permission has been removed. -->
     <permission android:name="android.permission.READ_INPUT_STATE"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- Must be required by an {@link android.inputmethodservice.InputMethodService},
          to ensure that only the system can bind to it.
          <p>Protection level: signature
     -->
     <permission android:name="android.permission.BIND_INPUT_METHOD"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- Must be required by an {@link android.media.midi.MidiDeviceService},
          to ensure that only the system can bind to it.
          <p>Protection level: signature
     -->
     <permission android:name="android.permission.BIND_MIDI_DEVICE_SERVICE"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- Must be required by an {@link android.accessibilityservice.AccessibilityService},
          to ensure that only the system can bind to it.
          <p>Protection level: signature
     -->
     <permission android:name="android.permission.BIND_ACCESSIBILITY_SERVICE"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- Must be required by a {@link android.printservice.PrintService},
          to ensure that only the system can bind to it.
          <p>Protection level: signature
     -->
     <permission android:name="android.permission.BIND_PRINT_SERVICE"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
+
+    <!-- Must be required by a {@link android.printservice.recommendation.RecommendationService},
+     to ensure that only the system can bind to it.
+     @hide
+     @SystemApi
+     <p>Protection level: signature
+    -->
+    <permission android:name="android.permission.BIND_PRINT_RECOMMENDATION_SERVICE"
+                android:protectionLevel="signature" />
 
     <!-- Must be required by a {@link android.nfc.cardemulation.HostApduService}
          or {@link android.nfc.cardemulation.OffHostApduService} to ensure that only
@@ -1953,84 +2201,84 @@
          <p>Protection level: signature
     -->
     <permission android:name="android.permission.BIND_NFC_SERVICE"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- Must be required by the PrintSpooler to ensure that only the system can bind to it.
          @hide -->
     <permission android:name="android.permission.BIND_PRINT_SPOOLER_SERVICE"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- Must be required by a TextService (e.g. SpellCheckerService)
          to ensure that only the system can bind to it.
          <p>Protection level: signature
     -->
     <permission android:name="android.permission.BIND_TEXT_SERVICE"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- Must be required by a {@link android.net.VpnService},
          to ensure that only the system can bind to it.
          <p>Protection level: signature
     -->
     <permission android:name="android.permission.BIND_VPN_SERVICE"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- Must be required by a {@link android.service.wallpaper.WallpaperService},
          to ensure that only the system can bind to it.
          <p>Protection level: system|signature
     -->
     <permission android:name="android.permission.BIND_WALLPAPER"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- Must be required by a {@link android.service.voice.VoiceInteractionService},
          to ensure that only the system can bind to it.
          <p>Protection level: signature
     -->
     <permission android:name="android.permission.BIND_VOICE_INTERACTION"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- Must be required by hotword enrollment application,
          to ensure that only the system can interact with it.
          @hide <p>Not for use by third-party applications.</p> -->
     <permission android:name="android.permission.MANAGE_VOICE_KEYPHRASES"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- Must be required by a {@link com.android.media.remotedisplay.RemoteDisplayProvider},
          to ensure that only the system can bind to it.
          @hide -->
     <permission android:name="android.permission.BIND_REMOTE_DISPLAY"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- Must be required by a {@link android.media.tv.TvInputService}
          to ensure that only the system can bind to it.
          <p>Protection level: signature
     -->
     <permission android:name="android.permission.BIND_TV_INPUT"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to modify parental controls
          <p>Not for use by third-party applications.
          @hide -->
     <permission android:name="android.permission.MODIFY_PARENTAL_CONTROLS"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- Must be required by a {@link android.media.routing.MediaRouteService}
          to ensure that only the system can interact with it.
          @hide -->
     <permission android:name="android.permission.BIND_ROUTE_PROVIDER"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- Must be required by device administration receiver, to ensure that only the
          system can interact with it.
          <p>Protection level: signature
     -->
     <permission android:name="android.permission.BIND_DEVICE_ADMIN"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- @SystemApi Required to add or remove another application as a device admin.
          <p>Not for use by third-party applications.
          @hide -->
     <permission android:name="android.permission.MANAGE_DEVICE_ADMINS"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows low-level access to setting the orientation (actually
          rotation) of the screen.
@@ -2038,33 +2286,33 @@
          @hide
     -->
     <permission android:name="android.permission.SET_ORIENTATION"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- @SystemApi Allows low-level access to setting the pointer speed.
          <p>Not for use by third-party applications.
          @hide
     -->
     <permission android:name="android.permission.SET_POINTER_SPEED"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- Allows low-level access to setting input device calibration.
          <p>Not for use by normal applications.
          @hide -->
     <permission android:name="android.permission.SET_INPUT_CALIBRATION"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- Allows low-level access to setting the keyboard layout.
          <p>Not for use by third-party applications.
          @hide -->
     <permission android:name="android.permission.SET_KEYBOARD_LAYOUT"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- Allows an application to query tablet mode state and monitor changes
          in it.
          <p>Not for use by third-party applications.
          @hide -->
     <permission android:name="android.permission.TABLET_MODE"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- Allows an application to request installing packages. Apps
          targeting APIs greater than 22 must hold this permission in
@@ -2072,277 +2320,292 @@
          <p>Protection level: normal
     -->
     <permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"
-        android:label="@string/permlab_requestInstallPackages"
-        android:description="@string/permdesc_requestInstallPackages"
-        android:protectionLevel="normal" />
+                android:label="@string/permlab_requestInstallPackages"
+                android:description="@string/permdesc_requestInstallPackages"
+                android:protectionLevel="normal" />
 
     <!-- @SystemApi Allows an application to install packages.
     <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.INSTALL_PACKAGES"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to clear user data.
          <p>Not for use by third-party applications
          @hide
     -->
     <permission android:name="android.permission.CLEAR_APP_USER_DATA"
-        android:protectionLevel="signature|installer" />
+                android:protectionLevel="signature|installer" />
+
+    <!-- @hide Allows an application to get the URI permissions
+         granted to another application.
+         <p>Not for use by third-party applications
+    -->
+    <permission android:name="android.permission.GET_APP_GRANTED_URI_PERMISSIONS"
+                android:protectionLevel="signature" />
+
+    <!-- @hide Allows an application to clear the URI permissions
+         granted to another application.
+         <p>Not for use by third-party applications
+    -->
+    <permission
+            android:name="android.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS"
+            android:protectionLevel="signature" />
 
     <!-- @SystemApi Allows an application to delete cache files.
     <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.DELETE_CACHE_FILES"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to delete packages.
     <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.DELETE_PACKAGES"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to move location of installed package.
          @hide -->
     <permission android:name="android.permission.MOVE_PACKAGE"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to change whether an application component (other than its own) is
          enabled or not.
          <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.CHANGE_COMPONENT_ENABLED_STATE"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- Allows an application to grant specific permissions.
          @hide -->
     <permission android:name="android.permission.GRANT_RUNTIME_PERMISSIONS"
-        android:protectionLevel="signature|installer|verifier" />
+                android:protectionLevel="signature|installer|verifier" />
 
     <!-- Allows an app that has this permission and the permissions to install packages
          to request certain runtime permissions to be granted at installation.
          @hide
          @SystemApi -->
     <permission android:name="android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS"
-        android:protectionLevel="signature|installer|verifier" />
+                android:protectionLevel="signature|installer|verifier" />
 
     <!-- Allows an application to revoke specific permissions.
         @hide
         @SystemApi -->
     <permission android:name="android.permission.REVOKE_RUNTIME_PERMISSIONS"
-         android:protectionLevel="signature|installer|verifier" />
+                android:protectionLevel="signature|installer|verifier" />
 
     <!-- @hide Allows an application to observe permission changes. -->
     <permission android:name="android.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to use SurfaceFlinger's low level features.
          <p>Not for use by third-party applications.
          @hide
     -->
     <permission android:name="android.permission.ACCESS_SURFACE_FLINGER"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- @SystemApi Allows an application to take screen shots and more generally
          get access to the frame buffer data.
          <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.READ_FRAME_BUFFER"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- Allows an application to use InputFlinger's low level features.
          @hide -->
     <permission android:name="android.permission.ACCESS_INPUT_FLINGER"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- Allows an application to configure and connect to Wifi displays
          @hide -->
     <permission android:name="android.permission.CONFIGURE_WIFI_DISPLAY"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- Allows an application to control low-level features of Wifi displays
          such as opening an RTSP socket.  This permission should only be used
          by the display manager.
          @hide -->
     <permission android:name="android.permission.CONTROL_WIFI_DISPLAY"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- Allows an application to control the color transforms applied to
          displays system-wide.
          <p>Not for use by third-party applications.</p>
          @hide -->
     <permission android:name="android.permission.CONFIGURE_DISPLAY_COLOR_TRANSFORM"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- @SystemApi Allows an application to control VPN.
          <p>Not for use by third-party applications.</p>
          @hide -->
     <permission android:name="android.permission.CONTROL_VPN"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
     <uses-permission android:name="android.permission.CONTROL_VPN" />
 
     <!-- @SystemApi Allows an application to capture audio output.
          <p>Not for use by third-party applications.</p> -->
     <permission android:name="android.permission.CAPTURE_AUDIO_OUTPUT"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to capture audio for hotword detection.
          <p>Not for use by third-party applications.</p>
          @hide -->
     <permission android:name="android.permission.CAPTURE_AUDIO_HOTWORD"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to modify audio routing and override policy decisions.
          <p>Not for use by third-party applications.</p>
          @hide -->
     <permission android:name="android.permission.MODIFY_AUDIO_ROUTING"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to capture video output.
          <p>Not for use by third-party applications.</p> -->
     <permission android:name="android.permission.CAPTURE_VIDEO_OUTPUT"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to capture secure video output.
          <p>Not for use by third-party applications.</p> -->
     <permission android:name="android.permission.CAPTURE_SECURE_VIDEO_OUTPUT"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to know what content is playing and control its playback.
          <p>Not for use by third-party applications due to privacy of media consumption</p>  -->
     <permission android:name="android.permission.MEDIA_CONTENT_CONTROL"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Required to be able to disable the device (very dangerous!).
          <p>Not for use by third-party applications.
          @hide
     -->
     <permission android:name="android.permission.BRICK"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- @SystemApi Required to be able to reboot the device.
     <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.REBOOT"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
-   <!-- @SystemApi Allows low-level access to power management.
-        <p>Not for use by third-party applications.
-        @hide
-    -->
-   <permission android:name="android.permission.DEVICE_POWER"
-        android:protectionLevel="signature" />
+    <!-- @SystemApi Allows low-level access to power management.
+         <p>Not for use by third-party applications.
+         @hide
+     -->
+    <permission android:name="android.permission.DEVICE_POWER"
+                android:protectionLevel="signature" />
 
-   <!-- Allows access to the PowerManager.userActivity function.
-   <p>Not for use by third-party applications. @hide @SystemApi -->
+    <!-- Allows access to the PowerManager.userActivity function.
+    <p>Not for use by third-party applications. @hide @SystemApi -->
     <permission android:name="android.permission.USER_ACTIVITY"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
-   <!-- @hide Allows low-level access to tun tap driver -->
+    <!-- @hide Allows low-level access to tun tap driver -->
     <permission android:name="android.permission.NET_TUNNELING"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- Run as a manufacturer test application, running as the root user.
          Only available when the device is running in manufacturer test mode.
          <p>Not for use by third-party applications.
     -->
     <permission android:name="android.permission.FACTORY_TEST"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- Allows an application to broadcast a notification that an application
          package has been removed.
          <p>Not for use by third-party applications.
     -->
     <permission android:name="android.permission.BROADCAST_PACKAGE_REMOVED"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- Allows an application to broadcast an SMS receipt notification.
          <p>Not for use by third-party applications.
     -->
     <permission android:name="android.permission.BROADCAST_SMS"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- Allows an application to broadcast a WAP PUSH receipt notification.
          <p>Not for use by third-party applications.
     -->
     <permission android:name="android.permission.BROADCAST_WAP_PUSH"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- @SystemApi Allows an application to broadcast privileged networking requests.
          <p>Not for use by third-party applications. @hide -->
     <permission android:name="android.permission.BROADCAST_NETWORK_PRIVILEGED"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Not for use by third-party applications. -->
     <permission android:name="android.permission.MASTER_CLEAR"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to call any phone number, including emergency
          numbers, without going through the Dialer user interface for the user
          to confirm the call being placed.
          <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.CALL_PRIVILEGED"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to perform CDMA OTA provisioning @hide -->
     <permission android:name="android.permission.PERFORM_CDMA_PROVISIONING"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to perform SIM Activation @hide -->
     <permission android:name="android.permission.PERFORM_SIM_ACTIVATION"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows enabling/disabling location update notifications from
          the radio.
          <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.CONTROL_LOCATION_UPDATES"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows read/write access to the "properties" table in the checkin
          database, to change values that get uploaded.
          <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.ACCESS_CHECKIN_PROPERTIES"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to collect component usage
          statistics
          <p>Declaring the permission implies intention to use the API and the user of the
          device can grant permission through the Settings application. -->
     <permission android:name="android.permission.PACKAGE_USAGE_STATS"
-        android:protectionLevel="signature|privileged|development|appop" />
+                android:protectionLevel="signature|privileged|development|appop" />
     <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" />
 
     <!-- @hide Allows an application to change the app idle state of an app.
          <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.CHANGE_APP_IDLE_STATE"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- @hide @SystemApi Allows an application to temporarily whitelist an inactive app to
          access the network and acquire wakelocks.
          <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST"
-        android:protectionLevel="system|signature" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- Permission an application must hold in order to use
          {@link android.provider.Settings#ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS}.
          This is a normal permission: an app requesting it will always be granted the
          permission, without the user needing to approve or see it. -->
     <permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"
-        android:protectionLevel="normal" />
+                android:protectionLevel="normal" />
 
     <!-- @SystemApi Allows an application to collect battery statistics -->
     <permission android:name="android.permission.BATTERY_STATS"
-        android:protectionLevel="signature|privileged|development" />
+                android:protectionLevel="signature|privileged|development" />
 
     <!-- @SystemApi Allows an application to control the backup and restore process.
     <p>Not for use by third-party applications.
          @hide pending API council -->
     <permission android:name="android.permission.BACKUP"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- Allows a package to launch the secure full-backup confirmation UI.
          ONLY the system process may hold this permission.
          @hide -->
     <permission android:name="android.permission.CONFIRM_FULL_BACKUP"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- @SystemApi Must be required by a {@link android.widget.RemoteViewsService},
          to ensure that only the system can bind to it. -->
     <permission android:name="android.permission.BIND_REMOTEVIEWS"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to tell the AppWidget service which application
          can access AppWidget's data.  The normal user flow is that a user
@@ -2351,25 +2614,25 @@
          An application that has this permission should honor that contract.
          <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.BIND_APPWIDGET"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Private permission, to restrict who can bring up a dialog to add a new
          keyguard widget
          @hide -->
     <permission android:name="android.permission.BIND_KEYGUARD_APPWIDGET"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Internal permission allowing an application to query/set which
          applications can bind AppWidgets.
          @hide -->
     <permission android:name="android.permission.MODIFY_APPWIDGET_BIND_PERMISSIONS"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- Allows applications to change the background data setting.
     <p>Not for use by third-party applications.
          @hide pending API council -->
     <permission android:name="android.permission.CHANGE_BACKGROUND_DATA_SETTING"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- @SystemApi This permission can be used on content providers to allow the global
          search system to access their data.  Typically it used when the
@@ -2380,7 +2643,7 @@
          it is used by applications to protect themselves from everyone else
          besides global search. -->
     <permission android:name="android.permission.GLOBAL_SEARCH"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- Internal permission protecting access to the global search
          system: ensures that only the system can access the provider
@@ -2390,33 +2653,33 @@
          ranking).
          @hide -->
     <permission android:name="android.permission.GLOBAL_SEARCH_CONTROL"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- @SystemApi Internal permission to allows an application to read indexable data.
         @hide -->
     <permission android:name="android.permission.READ_SEARCH_INDEXABLES"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows applications to set a live wallpaper.
          @hide XXX Change to signature once the picker is moved to its
          own apk as Ghod Intended. -->
     <permission android:name="android.permission.SET_WALLPAPER_COMPONENT"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows applications to read dream settings and dream state.
          @hide -->
     <permission android:name="android.permission.READ_DREAM_STATE"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows applications to write dream settings, and start or stop dreaming.
          @hide -->
     <permission android:name="android.permission.WRITE_DREAM_STATE"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allow an application to read and write the cache partition.
          @hide -->
     <permission android:name="android.permission.ACCESS_CACHE_FILESYSTEM"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- Must be required by default container service so that only
          the system can bind to it and use it to copy
@@ -2424,67 +2687,67 @@
          accessible to the system.
          @hide -->
     <permission android:name="android.permission.COPY_PROTECTED_DATA"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- @SystemApi Internal permission protecting access to the encryption methods
         @hide
     -->
     <permission android:name="android.permission.CRYPT_KEEPER"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to read historical network usage for
          specific networks and applications. @hide -->
     <permission android:name="android.permission.READ_NETWORK_USAGE_HISTORY"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- Allows an application to manage network policies (such as warning and disable
          limits) and to define application-specific rules. @hide -->
     <permission android:name="android.permission.MANAGE_NETWORK_POLICY"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- @SystemApi Allows an application to account its network traffic against other UIDs. Used
          by system services like download manager and media server. Not for use by
          third party apps. @hide -->
     <permission android:name="android.permission.MODIFY_NETWORK_ACCOUNTING"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- C2DM permission.
          @hide Used internally.
      -->
     <permission android:name="android.intent.category.MASTER_CLEAR.permission.C2D_MESSAGE"
-          android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
     <uses-permission android:name="android.intent.category.MASTER_CLEAR.permission.C2D_MESSAGE"/>
 
     <!-- @SystemApi @hide Package verifier needs to have this permission before the PackageManager will
          trust it to verify packages.
     -->
     <permission android:name="android.permission.PACKAGE_VERIFICATION_AGENT"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- Must be required by package verifier receiver, to ensure that only the
          system can interact with it.
          @hide
     -->
     <permission android:name="android.permission.BIND_PACKAGE_VERIFIER"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- @SystemApi @hide Intent filter verifier needs to have this permission before the
          PackageManager will trust it to verify intent filters.
     -->
     <permission android:name="android.permission.INTENT_FILTER_VERIFICATION_AGENT"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- Must be required by intent filter verifier receiver, to ensure that only the
          system can interact with it.
          @hide
     -->
     <permission android:name="android.permission.BIND_INTENT_FILTER_VERIFIER"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- @SystemApi Allows applications to access serial ports via the SerialManager.
          @hide -->
     <permission android:name="android.permission.SERIAL_PORT"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- Allows the holder to access content providers from outside an ApplicationThread.
          This permission is enforced by the ActivityManagerService on the corresponding APIs,
@@ -2493,67 +2756,73 @@
          @hide
     -->
     <permission android:name="android.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- @SystemApi Allows an application to hold an UpdateLock, recommending that a headless
          OTA reboot *not* occur while the lock is held.
          @hide -->
     <permission android:name="android.permission.UPDATE_LOCK"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to read the current set of notifications, including
          any metadata and intents attached.
          @hide -->
     <permission android:name="android.permission.ACCESS_NOTIFICATIONS"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- Marker permission for applications that wish to access notification policy.
          <p>Protection level: normal
     -->
     <permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY"
-        android:description="@string/permdesc_access_notification_policy"
-        android:label="@string/permlab_access_notification_policy"
-        android:protectionLevel="normal" />
+                android:description="@string/permdesc_access_notification_policy"
+                android:label="@string/permlab_access_notification_policy"
+                android:protectionLevel="normal" />
+
+    <!-- Allows modification of do not disturb rules and policies. Only allowed for system
+        processes.
+        @hide -->
+    <permission android:name="android.permission.MANAGE_NOTIFICATIONS"
+                android:protectionLevel="signature" />
 
     <!-- Allows access to keyguard secure storage.  Only allowed for system processes.
         @hide -->
     <permission android:name="android.permission.ACCESS_KEYGUARD_SECURE_STORAGE"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- Allows managing (adding, removing) fingerprint templates. Reserved for the system. @hide -->
     <permission android:name="android.permission.MANAGE_FINGERPRINT"
-        android:protectionLevel="system|signature" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- Allows an app to reset fingerprint attempt counter. Reserved for the system. @hide -->
     <permission android:name="android.permission.RESET_FINGERPRINT_LOCKOUT"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- Allows an application to control keyguard.  Only allowed for system processes.
         @hide -->
     <permission android:name="android.permission.CONTROL_KEYGUARD"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- Allows an application to listen to trust changes.  Only allowed for system processes.
         @hide -->
     <permission android:name="android.permission.TRUST_LISTENER"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- @SystemApi Allows an application to provide a trust agent.
          @hide For security reasons, this is a platform-only permission. -->
     <permission android:name="android.permission.PROVIDE_TRUST_AGENT"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- Allows an application to launch the trust agent settings activity.
         @hide -->
     <permission android:name="android.permission.LAUNCH_TRUST_AGENT_SETTINGS"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Must be required by an {@link
         android.service.trust.TrustAgentService},
         to ensure that only the system can bind to it.
         @hide -->
     <permission android:name="android.permission.BIND_TRUST_AGENT"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- Must be required by an {@link
          android.service.notification.NotificationListenerService},
@@ -2561,7 +2830,15 @@
          <p>Protection level: signature
     -->
     <permission android:name="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
+
+    <!-- Must be required by an {@link
+         android.service.notification.NotificationRankerService         to ensure that only the system can bind to it.
+         <p>Protection level: signature
+         @hide This is not a third-party API (intended for system apps). -->
+    -->
+    <permission android:name="android.permission.BIND_NOTIFICATION_RANKER_SERVICE"
+                android:protectionLevel="signature" />
 
     <!-- Must be required by a {@link
          android.service.chooser.ChooserTargetService}, to ensure that
@@ -2569,64 +2846,65 @@
          <p>Protection level: signature
     -->
     <permission android:name="android.permission.BIND_CHOOSER_TARGET_SERVICE"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
-    <!-- @SystemApi Must be required by a {@link
+    <!-- Must be required by a {@link
          android.service.notification.ConditionProviderService},
          to ensure that only the system can bind to it.
-         @hide -->
+         <p>Protection level: signature
+         -->
     <permission android:name="android.permission.BIND_CONDITION_PROVIDER_SERVICE"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- Must be required by an {@link android.service.dreams.DreamService},
          to ensure that only the system can bind to it.
          <p>Protection level: signature
     -->
     <permission android:name="android.permission.BIND_DREAM_SERVICE"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- @SystemApi Allows an application to call into a carrier setup flow. It is up to the
          carrier setup application to enforce that this permission is required
          @hide This is not a third-party API (intended for OEMs and system apps). -->
     <permission android:name="android.permission.INVOKE_CARRIER_SETUP"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to listen for network condition observations.
          @hide This is not a third-party API (intended for system apps). -->
     <permission android:name="android.permission.ACCESS_NETWORK_CONDITIONS"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to provision and access DRM certificates
          @hide This is not a third-party API (intended for system apps). -->
     <permission android:name="android.permission.ACCESS_DRM_CERTIFICATES"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- Api Allows an application to manage media projection sessions.
          @hide This is not a third-party API (intended for system apps). -->
     <permission android:name="android.permission.MANAGE_MEDIA_PROJECTION"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- @SystemApi Allows an application to read install sessions
          @hide This is not a third-party API (intended for system apps). -->
     <permission android:name="android.permission.READ_INSTALL_SESSIONS"
-        android:label="@string/permlab_readInstallSessions"
-        android:description="@string/permdesc_readInstallSessions"
-        android:protectionLevel="normal"/>
+                android:label="@string/permlab_readInstallSessions"
+                android:description="@string/permdesc_readInstallSessions"
+                android:protectionLevel="normal"/>
 
     <!-- @SystemApi Allows an application to remove DRM certificates
          @hide This is not a third-party API (intended for system apps). -->
     <permission android:name="android.permission.REMOVE_DRM_CERTIFICATES"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- @deprecated Use {@link android.Manifest.permission#BIND_CARRIER_SERVICES} instead -->
     <permission android:name="android.permission.BIND_CARRIER_MESSAGING_SERVICE"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- Allows an application to interact with the currently active
          {@link android.service.voice.VoiceInteractionService}.
          @hide -->
     <permission android:name="android.permission.ACCESS_VOICE_INTERACTION_SERVICE"
-        android:protectionLevel="signature" />
+                android:protectionLevel="signature" />
 
     <!-- The system process that is allowed to bind to services in carrier apps will
          have this permission. Carrier apps should use this permission to protect
@@ -2634,9 +2912,9 @@
          <p>Protection level: system|signature
     -->
     <permission android:name="android.permission.BIND_CARRIER_SERVICES"
-        android:label="@string/permlab_bindCarrierServices"
-        android:description="@string/permdesc_bindCarrierServices"
-        android:protectionLevel="signature|privileged" />
+                android:label="@string/permlab_bindCarrierServices"
+                android:description="@string/permdesc_bindCarrierServices"
+                android:protectionLevel="signature|privileged" />
 
     <!-- Allows an application to query whether DO_NOT_ASK_CREDENTIALS_ON_BOOT
          flag is set.
@@ -2667,10 +2945,75 @@
     <permission android:name="android.permission.DISPATCH_NFC_MESSAGE"
                 android:protectionLevel="signature|privileged" />
 
+    <!-- @SystemApi Allows changing day / night mode when system is configured with
+         config_lockDayNightMode set to true. If requesting app does not have permission,
+         it will be ignored.
+        @hide -->
+    <permission android:name="android.permission.MODIFY_DAY_NIGHT_MODE"
+                android:protectionLevel="signature|privileged" />
+
     <!-- The system process is explicitly the only one allowed to launch the
          confirmation UI for full backup/restore -->
     <uses-permission android:name="android.permission.CONFIRM_FULL_BACKUP"/>
 
+
+    <!-- Allows the holder to access the ephemeral applications on the device.
+    @hide -->
+    <permission android:name="android.permission.ACCESS_EPHEMERAL_APPS"
+                android:protectionLevel="signature" />
+
+    <!-- Allows receiving the usage of media resource e.g. video/audio codec and
+         graphic memory.
+         @hide -->
+    <permission android:name="android.permission.RECEIVE_MEDIA_RESOURCE_USAGE"
+                android:protectionLevel="signature|privileged" />
+
+    <!-- Must be required by system/priv apps when accessing the sound trigger
+         APIs given by {@link SoundTriggerManager}.
+         @hide <p>Not for use by third-party applications.</p> -->
+    <permission android:name="android.permission.MANAGE_SOUND_TRIGGER"
+                android:protectionLevel="signature|privileged" />
+
+    <!-- @SystemApi Allows trusted applications to dispatch managed provisioning message to Managed
+         Provisioning app. If requesting app does not have permission, it will be ignored.
+         @hide -->
+    <permission android:name="android.permission.DISPATCH_PROVISIONING_MESSAGE"
+                android:protectionLevel="signature|privileged" />
+
+    <!-- Allows the holder to read blocked numbers. See
+         {@link android.provider.BlockedNumberContract}.
+         @hide -->
+    <permission android:name="android.permission.READ_BLOCKED_NUMBERS"
+                android:protectionLevel="signature" />
+
+    <!-- Allows the holder to write blocked numbers. See
+         {@link android.provider.BlockedNumberContract}.
+         @hide -->
+    <permission android:name="android.permission.WRITE_BLOCKED_NUMBERS"
+                android:protectionLevel="signature" />
+
+    <!-- Must be required by an {@link android.service.vr.VrListenerService}, to ensure that only
+         the system can bind to it.
+         <p>Protection level: signature -->
+    <permission android:name="android.permission.BIND_VR_LISTENER_SERVICE"
+                android:protectionLevel="signature" />
+
+    <!-- Required to make calls to {@link android.service.vr.IVrManager}.
+         @hide -->
+    <permission android:name="android.permission.ACCESS_VR_MANAGER"
+                android:protectionLevel="signature" />
+
+    <!-- Allows an application to whitelist tasks during lock task mode
+         @hide <p>Not for use by third-party applications.</p> -->
+    <permission android:name="android.permission.UPDATE_LOCK_TASK_PACKAGES"
+                android:protectionLevel="signature|setup" />
+
+    <!-- @SystemApi Allows an application to replace the app name displayed alongside notifications
+         in the N-release and later.
+         @hide  <p>Not for use by third-party applications.</p> -->
+    <permission android:name="android.permission.SUBSTITUTE_NOTIFICATION_APP_NAME"
+                android:protectionLevel="signature|privileged" />
+
     <application android:process="system"
                  android:persistent="true"
                  android:hasCode="false"
@@ -2679,14 +3022,17 @@
                  android:backupAgent="com.android.server.backup.SystemBackupAgent"
                  android:killAfterRestore="false"
                  android:icon="@drawable/ic_launcher_android"
-                 android:supportsRtl="true">
+                 android:supportsRtl="true"
+                 android:theme="@style/Theme.Material.Light.DarkActionBar"
+                 android:defaultToDeviceProtectedStorage="true"
+                 android:directBootAware="true">
         <activity android:name="com.android.internal.app.ChooserActivity"
-                android:theme="@style/Theme.DeviceDefault.Resolver"
-                android:finishOnCloseSystemDialogs="true"
-                android:excludeFromRecents="true"
-                android:documentLaunchMode="never"
-                android:relinquishTaskIdentity="true"
-                android:process=":ui">
+                  android:theme="@style/Theme.DeviceDefault.Resolver"
+                  android:finishOnCloseSystemDialogs="true"
+                  android:excludeFromRecents="true"
+                  android:documentLaunchMode="never"
+                  android:relinquishTaskIdentity="true"
+                  android:process=":ui">
             <intent-filter>
                 <action android:name="android.intent.action.CHOOSER" />
                 <category android:name="android.intent.category.DEFAULT" />
@@ -2694,102 +3040,102 @@
             </intent-filter>
         </activity>
         <activity android:name="com.android.internal.app.IntentForwarderActivity"
-                android:finishOnCloseSystemDialogs="true"
-                android:theme="@style/Theme.NoDisplay"
-                android:excludeFromRecents="true"
-                android:label="@string/user_owner_label"
-                android:exported="true"
-                >
+                  android:finishOnCloseSystemDialogs="true"
+                  android:theme="@style/Theme.NoDisplay"
+                  android:excludeFromRecents="true"
+                  android:label="@string/user_owner_label"
+                  android:exported="true"
+        >
         </activity>
-        <activity-alias android:name="com.android.internal.app.ForwardIntentToUserOwner"
-                android:targetActivity="com.android.internal.app.IntentForwarderActivity"
-                android:exported="true"
-                android:label="@string/user_owner_label">
+        <activity-alias android:name="com.android.internal.app.ForwardIntentToParent"
+                        android:targetActivity="com.android.internal.app.IntentForwarderActivity"
+                        android:exported="true"
+                        android:label="@string/user_owner_label">
         </activity-alias>
         <activity-alias android:name="com.android.internal.app.ForwardIntentToManagedProfile"
-                android:targetActivity="com.android.internal.app.IntentForwarderActivity"
-                android:icon="@drawable/ic_corp_icon"
-                android:exported="true"
-                android:label="@string/managed_profile_label">
+                        android:targetActivity="com.android.internal.app.IntentForwarderActivity"
+                        android:icon="@drawable/ic_corp_icon"
+                        android:exported="true"
+                        android:label="@string/managed_profile_label">
         </activity-alias>
         <activity android:name="com.android.internal.app.HeavyWeightSwitcherActivity"
-                android:theme="@style/Theme.Material.Light.Dialog"
-                android:label="@string/heavy_weight_switcher_title"
-                android:finishOnCloseSystemDialogs="true"
-                android:excludeFromRecents="true"
-                android:process=":ui">
+                  android:theme="@style/Theme.Material.Light.Dialog"
+                  android:label="@string/heavy_weight_switcher_title"
+                  android:finishOnCloseSystemDialogs="true"
+                  android:excludeFromRecents="true"
+                  android:process=":ui">
         </activity>
         <activity android:name="com.android.internal.app.PlatLogoActivity"
-                android:theme="@style/Theme.Wallpaper.NoTitleBar.Fullscreen"
-                android:configChanges="orientation|keyboardHidden"
-                android:process=":ui">
+                  android:theme="@style/Theme.Wallpaper.NoTitleBar.Fullscreen"
+                  android:configChanges="orientation|keyboardHidden"
+                  android:process=":ui">
         </activity>
         <activity android:name="com.android.internal.app.DisableCarModeActivity"
-                android:theme="@style/Theme.NoDisplay"
-                android:excludeFromRecents="true"
-                android:process=":ui">
+                  android:theme="@style/Theme.NoDisplay"
+                  android:excludeFromRecents="true"
+                  android:process=":ui">
         </activity>
         <activity android:name="com.android.internal.app.DumpHeapActivity"
-                android:theme="@style/Theme.Translucent.NoTitleBar"
-                android:label="@string/dump_heap_title"
-                android:finishOnCloseSystemDialogs="true"
-                android:noHistory="true"
-                android:excludeFromRecents="true"
-                android:process=":ui">
+                  android:theme="@style/Theme.Translucent.NoTitleBar"
+                  android:label="@string/dump_heap_title"
+                  android:finishOnCloseSystemDialogs="true"
+                  android:noHistory="true"
+                  android:excludeFromRecents="true"
+                  android:process=":ui">
         </activity>
         <provider android:name="com.android.server.am.DumpHeapProvider"
-                android:authorities="com.android.server.heapdump"
-                android:grantUriPermissions="true"
-                android:multiprocess="false"
-                android:singleUser="true" />
+                  android:authorities="com.android.server.heapdump"
+                  android:grantUriPermissions="true"
+                  android:multiprocess="false"
+                  android:singleUser="true" />
 
         <activity android:name="android.accounts.ChooseAccountActivity"
-                android:excludeFromRecents="true"
-                android:exported="true"
-                android:theme="@style/Theme.Material.Light.Dialog"
-                android:label="@string/choose_account_label"
-                android:process=":ui">
+                  android:excludeFromRecents="true"
+                  android:exported="true"
+                  android:theme="@style/Theme.Material.Light.Dialog"
+                  android:label="@string/choose_account_label"
+                  android:process=":ui">
         </activity>
 
         <activity android:name="android.accounts.ChooseTypeAndAccountActivity"
-                android:excludeFromRecents="true"
-                android:exported="true"
-                android:theme="@style/Theme.Material.Light.Dialog"
-                android:label="@string/choose_account_label"
-                android:process=":ui">
+                  android:excludeFromRecents="true"
+                  android:exported="true"
+                  android:theme="@style/Theme.Material.Light.Dialog"
+                  android:label="@string/choose_account_label"
+                  android:process=":ui">
         </activity>
 
         <activity android:name="android.accounts.ChooseAccountTypeActivity"
-                android:excludeFromRecents="true"
-                android:theme="@style/Theme.Material.Light.Dialog"
-                android:label="@string/choose_account_label"
-                android:process=":ui">
+                  android:excludeFromRecents="true"
+                  android:theme="@style/Theme.Material.Light.Dialog"
+                  android:label="@string/choose_account_label"
+                  android:process=":ui">
         </activity>
 
         <activity android:name="android.accounts.CantAddAccountActivity"
-                android:excludeFromRecents="true"
-                android:exported="true"
-                android:theme="@style/Theme.Material.Light.Dialog.NoActionBar"
-                android:process=":ui">
+                  android:excludeFromRecents="true"
+                  android:exported="true"
+                  android:theme="@style/Theme.Material.Light.Dialog.NoActionBar"
+                  android:process=":ui">
         </activity>
 
         <activity android:name="android.accounts.GrantCredentialsPermissionActivity"
-                android:excludeFromRecents="true"
-                android:exported="true"
-                android:theme="@style/Theme.Material.Light.DialogWhenLarge"
-                android:process=":ui">
+                  android:excludeFromRecents="true"
+                  android:exported="true"
+                  android:theme="@style/Theme.Material.Light.DialogWhenLarge"
+                  android:process=":ui">
         </activity>
 
         <activity android:name="android.content.SyncActivityTooManyDeletes"
-               android:theme="@style/Theme.Material.Light.Dialog"
-               android:label="@string/sync_too_many_deletes"
-               android:process=":ui">
+                  android:theme="@style/Theme.Material.Light.Dialog"
+                  android:label="@string/sync_too_many_deletes"
+                  android:process=":ui">
         </activity>
 
         <activity android:name="com.android.internal.app.ShutdownActivity"
-            android:permission="android.permission.SHUTDOWN"
-            android:theme="@style/Theme.NoDisplay"
-            android:excludeFromRecents="true">
+                  android:permission="android.permission.SHUTDOWN"
+                  android:theme="@style/Theme.NoDisplay"
+                  android:excludeFromRecents="true">
             <intent-filter>
                 <action android:name="android.intent.action.ACTION_REQUEST_SHUTDOWN" />
                 <category android:name="android.intent.category.DEFAULT" />
@@ -2801,20 +3147,49 @@
         </activity>
 
         <activity android:name="com.android.internal.app.NetInitiatedActivity"
-                android:theme="@style/Theme.Material.Light.Dialog.Alert"
-                android:excludeFromRecents="true"
-                android:process=":ui">
+                  android:theme="@style/Theme.Material.Light.Dialog.Alert"
+                  android:excludeFromRecents="true"
+                  android:process=":ui">
+        </activity>
+
+        <activity android:name="com.android.internal.app.SystemUserHomeActivity"
+                  android:enabled="false"
+                  android:process=":ui"
+                  android:systemUserOnly="true"
+                  android:theme="@style/Theme.Translucent.NoTitleBar">
+            <intent-filter android:priority="-100">
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.HOME" />
+            </intent-filter>
+        </activity>
+
+        <!-- Activity to prompt user if it's ok to create a new user sandbox for a
+             specified account. -->
+        <activity android:name="com.android.internal.app.ConfirmUserCreationActivity"
+                  android:excludeFromRecents="true"
+                  android:process=":ui"
+                  android:theme="@style/Theme.Material.Light.Dialog.Alert">
+            <intent-filter android:priority="1000">
+                <action android:name="android.os.action.CREATE_USER" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name="com.android.internal.app.UnlaunchableAppActivity"
+                  android:theme="@style/Theme.Material.Light.Dialog.Alert"
+                  android:excludeFromRecents="true"
+                  android:process=":ui">
         </activity>
 
         <receiver android:name="com.android.server.BootReceiver"
-                android:primaryUserOnly="true">
+                  android:systemUserOnly="true">
             <intent-filter android:priority="1000">
                 <action android:name="android.intent.action.BOOT_COMPLETED" />
             </intent-filter>
         </receiver>
 
         <receiver android:name="com.android.server.updates.CertPinInstallReceiver"
-                android:permission="android.permission.UPDATE_CONFIG">
+                  android:permission="android.permission.UPDATE_CONFIG">
             <intent-filter>
                 <action android:name="android.intent.action.UPDATE_PINS" />
                 <data android:scheme="content" android:host="*" android:mimeType="*/*" />
@@ -2822,7 +3197,7 @@
         </receiver>
 
         <receiver android:name="com.android.server.updates.IntentFirewallInstallReceiver"
-                android:permission="android.permission.UPDATE_CONFIG">
+                  android:permission="android.permission.UPDATE_CONFIG">
             <intent-filter>
                 <action android:name="android.intent.action.UPDATE_INTENT_FIREWALL" />
                 <data android:scheme="content" android:host="*" android:mimeType="*/*" />
@@ -2830,15 +3205,23 @@
         </receiver>
 
         <receiver android:name="com.android.server.updates.SmsShortCodesInstallReceiver"
-                android:permission="android.permission.UPDATE_CONFIG">
+                  android:permission="android.permission.UPDATE_CONFIG">
             <intent-filter>
                 <action android:name="android.intent.action.UPDATE_SMS_SHORT_CODES" />
                 <data android:scheme="content" android:host="*" android:mimeType="*/*" />
             </intent-filter>
         </receiver>
 
+        <receiver android:name="com.android.server.updates.ApnDbInstallReceiver"
+                  android:permission="android.permission.UPDATE_CONFIG">
+            <intent-filter>
+                <action android:name="android.intent.action.UPDATE_APN_DB" />
+                <data android:scheme="content" android:host="*" android:mimeType="*/*" />
+            </intent-filter>
+        </receiver>
+
         <receiver android:name="com.android.server.updates.CarrierProvisioningUrlsInstallReceiver"
-                android:permission="android.permission.UPDATE_CONFIG">
+                  android:permission="android.permission.UPDATE_CONFIG">
             <intent-filter>
                 <action android:name="android.intent.action.UPDATE_CARRIER_PROVISIONING_URLS" />
                 <data android:scheme="content" android:host="*" android:mimeType="*/*" />
@@ -2846,7 +3229,7 @@
         </receiver>
 
         <receiver android:name="com.android.server.updates.TzDataInstallReceiver"
-                android:permission="android.permission.UPDATE_CONFIG">
+                  android:permission="android.permission.UPDATE_CONFIG">
             <intent-filter>
                 <action android:name="android.intent.action.UPDATE_TZDATA" />
                 <data android:scheme="content" android:host="*" android:mimeType="*/*" />
@@ -2854,7 +3237,7 @@
         </receiver>
 
         <receiver android:name="com.android.server.updates.SELinuxPolicyInstallReceiver"
-                android:permission="android.permission.UPDATE_CONFIG">
+                  android:permission="android.permission.UPDATE_CONFIG">
             <intent-filter>
                 <action android:name="android.intent.action.UPDATE_SEPOLICY" />
                 <data android:scheme="content" android:host="*" android:mimeType="*/*" />
@@ -2862,7 +3245,7 @@
         </receiver>
 
         <receiver android:name="com.android.server.MasterClearReceiver"
-            android:permission="android.permission.MASTER_CLEAR">
+                  android:permission="android.permission.MASTER_CLEAR">
             <intent-filter
                     android:priority="100" >
                 <!-- For Checkin, Settings, etc.: action=MASTER_CLEAR -->
@@ -2875,12 +3258,12 @@
         </receiver>
 
         <service android:name="android.hardware.location.GeofenceHardwareService"
-            android:permission="android.permission.LOCATION_HARDWARE"
-            android:exported="false" />
+                 android:permission="android.permission.LOCATION_HARDWARE"
+                 android:exported="false" />
 
         <service android:name="com.android.internal.backup.LocalTransportService"
-                android:permission="android.permission.CONFIRM_FULL_BACKUP"
-                android:exported="false">
+                 android:permission="android.permission.CONFIRM_FULL_BACKUP"
+                 android:exported="false">
             <intent-filter>
                 <action android:name="android.backup.TRANSPORT_HOST" />
             </intent-filter>
@@ -2900,10 +3283,14 @@
                  android:permission="android.permission.BIND_JOB_SERVICE" >
         </service>
 
+        <service android:name="com.android.server.content.SyncJobService"
+                 android:permission="android.permission.BIND_JOB_SERVICE" >
+        </service>
+
         <service
-            android:name="com.android.server.pm.BackgroundDexOptService"
-            android:exported="true"
-            android:permission="android.permission.BIND_JOB_SERVICE">
+                android:name="com.android.server.pm.BackgroundDexOptService"
+                android:exported="true"
+                android:permission="android.permission.BIND_JOB_SERVICE">
         </service>
 
     </application>
diff --git a/tests/tests/permission2/src/android/permission2/cts/PermissionPolicyTest.java b/tests/tests/permission2/src/android/permission2/cts/PermissionPolicyTest.java
index fb3ef64..0bee8b9 100644
--- a/tests/tests/permission2/src/android/permission2/cts/PermissionPolicyTest.java
+++ b/tests/tests/permission2/src/android/permission2/cts/PermissionPolicyTest.java
@@ -124,7 +124,7 @@
         List<PermissionInfo> permissions = new ArrayList<>();
         try (
                 InputStream in = getContext().getResources()
-                        .openRawResource(com.android.cts.permission2.R.raw.android_manifest)
+                        .openRawResource(android.permission2.cts.R.raw.android_manifest)
         ) {
             XmlPullParser parser = Xml.newPullParser();
             parser.setInput(in, null);
@@ -193,6 +193,9 @@
                 case "privileged": {
                     protectionLevel |= PermissionInfo.PROTECTION_FLAG_PRIVILEGED;
                 } break;
+                case "setup": {
+                    protectionLevel |= PermissionInfo.PROTECTION_FLAG_SETUP;
+                } break;
             }
         }
         return protectionLevel;
diff --git a/tests/tests/preference/Android.mk b/tests/tests/preference/Android.mk
index 7534641..fa6f9c9 100644
--- a/tests/tests/preference/Android.mk
+++ b/tests/tests/preference/Android.mk
@@ -20,6 +20,9 @@
 
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
diff --git a/tests/tests/preference/AndroidManifest.xml b/tests/tests/preference/AndroidManifest.xml
index 3cc3ef8..e5fd710 100644
--- a/tests/tests/preference/AndroidManifest.xml
+++ b/tests/tests/preference/AndroidManifest.xml
@@ -16,7 +16,7 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.preference">
+    package="android.preference.cts">
 
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <application>
@@ -28,8 +28,8 @@
     </application>
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.cts.preference"
-                     android:label="CTS tests of android.os">
+                     android:targetPackage="android.preference.cts"
+                     android:label="CTS tests of android.preference">
         <meta-data android:name="listener"
             android:value="com.android.cts.runner.CtsTestRunListener" />
     </instrumentation>
diff --git a/tests/tests/preference/AndroidTest.xml b/tests/tests/preference/AndroidTest.xml
new file mode 100644
index 0000000..f9074fe
--- /dev/null
+++ b/tests/tests/preference/AndroidTest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS Preference test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsPreferenceTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.preference.cts" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/tests/preference/src/android/preference/cts/PreferenceActivityTest.java b/tests/tests/preference/src/android/preference/cts/PreferenceActivityTest.java
index 51ebc7d..162f200 100644
--- a/tests/tests/preference/src/android/preference/cts/PreferenceActivityTest.java
+++ b/tests/tests/preference/src/android/preference/cts/PreferenceActivityTest.java
@@ -16,7 +16,7 @@
 
 package android.preference.cts;
 
-import com.android.cts.preference.R;
+import android.preference.cts.R;
 
 import android.content.Intent;
 import android.preference.PreferenceActivity;
@@ -69,4 +69,4 @@
 
         assertEquals(prefScreen, mActivity.getPreferenceScreen());
     }
-}
\ No newline at end of file
+}
diff --git a/tests/tests/preference2/Android.mk b/tests/tests/preference2/Android.mk
index 59fedc8..2fd94a6 100644
--- a/tests/tests/preference2/Android.mk
+++ b/tests/tests/preference2/Android.mk
@@ -22,6 +22,9 @@
 
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
diff --git a/tests/tests/preference2/AndroidManifest.xml b/tests/tests/preference2/AndroidManifest.xml
index 2dbd53a..8d2b823 100644
--- a/tests/tests/preference2/AndroidManifest.xml
+++ b/tests/tests/preference2/AndroidManifest.xml
@@ -15,7 +15,7 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.preference2">
+    package="android.preference2.cts">
 
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <application>
@@ -36,8 +36,8 @@
 
     <!-- This is a self-instrumenting test package. -->
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.cts.preference2"
-                     android:label="CTS Test Cases for android.preference">
+                     android:targetPackage="android.preference2.cts"
+                     android:label="CTS Test Cases for android.preference2">
         <meta-data android:name="listener"
             android:value="com.android.cts.runner.CtsTestRunListener" />
     </instrumentation>
diff --git a/tests/tests/preference2/AndroidTest.xml b/tests/tests/preference2/AndroidTest.xml
new file mode 100644
index 0000000..96dfe0e
--- /dev/null
+++ b/tests/tests/preference2/AndroidTest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS Preference test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsPreference2TestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.preference2.cts" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/tests/preference2/res/xml/pref_cb.xml b/tests/tests/preference2/res/xml/pref_cb.xml
index b5f77b9..73dc3d8 100755
--- a/tests/tests/preference2/res/xml/pref_cb.xml
+++ b/tests/tests/preference2/res/xml/pref_cb.xml
@@ -13,7 +13,7 @@
      limitations under the License.

 -->

 <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"

-    xmlns:in="http://schemas.android.com/apk/res/com.android.cts.preference2" >

+    xmlns:in="http://schemas.android.com/apk/res/android.preference2.cts" >

 

     <PreferenceCategory android:title="@string/inline_preferences" >

         <android.preference2.cts.CustomCheckBoxPreference

diff --git a/tests/tests/preference2/src/android/preference2/cts/CheckBoxPreferenceTest.java b/tests/tests/preference2/src/android/preference2/cts/CheckBoxPreferenceTest.java
index de129e0..cf8bfde 100644
--- a/tests/tests/preference2/src/android/preference2/cts/CheckBoxPreferenceTest.java
+++ b/tests/tests/preference2/src/android/preference2/cts/CheckBoxPreferenceTest.java
@@ -19,7 +19,7 @@
 import android.preference.CheckBoxPreference;
 import android.test.ActivityInstrumentationTestCase2;
 
-import com.android.cts.preference2.R;
+import android.preference2.cts.R;
 
 public class CheckBoxPreferenceTest
         extends ActivityInstrumentationTestCase2<PreferenceFromCodeActivity> {
diff --git a/tests/tests/preference2/src/android/preference2/cts/CustomCheckBoxPreference.java b/tests/tests/preference2/src/android/preference2/cts/CustomCheckBoxPreference.java
index d51eddd..64cc360 100644
--- a/tests/tests/preference2/src/android/preference2/cts/CustomCheckBoxPreference.java
+++ b/tests/tests/preference2/src/android/preference2/cts/CustomCheckBoxPreference.java
@@ -15,7 +15,7 @@
  */
 package android.preference2.cts;
 
-import com.android.cts.preference2.R;
+import android.preference2.cts.R;
 
 import android.content.Context;
 import android.content.res.TypedArray;
diff --git a/tests/tests/preference2/src/android/preference2/cts/CustomDialogPreference.java b/tests/tests/preference2/src/android/preference2/cts/CustomDialogPreference.java
index db584ac..20346b1 100644
--- a/tests/tests/preference2/src/android/preference2/cts/CustomDialogPreference.java
+++ b/tests/tests/preference2/src/android/preference2/cts/CustomDialogPreference.java
@@ -15,7 +15,7 @@
  */
 package android.preference2.cts;
 
-import com.android.cts.preference2.R;
+import android.preference2.cts.R;
 
 import android.content.Context;
 import android.content.res.TypedArray;
diff --git a/tests/tests/preference2/src/android/preference2/cts/CustomEditTextPreference.java b/tests/tests/preference2/src/android/preference2/cts/CustomEditTextPreference.java
index 51fdf13..007f475 100644
--- a/tests/tests/preference2/src/android/preference2/cts/CustomEditTextPreference.java
+++ b/tests/tests/preference2/src/android/preference2/cts/CustomEditTextPreference.java
@@ -15,7 +15,7 @@
  */
 package android.preference2.cts;
 
-import com.android.cts.preference2.R;
+import android.preference2.cts.R;
 
 import android.content.Context;
 import android.content.res.TypedArray;
diff --git a/tests/tests/preference2/src/android/preference2/cts/CustomPreference.java b/tests/tests/preference2/src/android/preference2/cts/CustomPreference.java
index 7506bd0..4875acc1 100644
--- a/tests/tests/preference2/src/android/preference2/cts/CustomPreference.java
+++ b/tests/tests/preference2/src/android/preference2/cts/CustomPreference.java
@@ -15,7 +15,7 @@
  */
 package android.preference2.cts;
 
-import com.android.cts.preference2.R;
+import android.preference2.cts.R;
 
 import android.content.Context;
 import android.content.res.TypedArray;
diff --git a/tests/tests/preference2/src/android/preference2/cts/CustomPreferenceGroup.java b/tests/tests/preference2/src/android/preference2/cts/CustomPreferenceGroup.java
index 26e1bcf..c4771d3 100644
--- a/tests/tests/preference2/src/android/preference2/cts/CustomPreferenceGroup.java
+++ b/tests/tests/preference2/src/android/preference2/cts/CustomPreferenceGroup.java
@@ -15,7 +15,7 @@
  */
 package android.preference2.cts;
 
-import com.android.cts.preference2.R;
+import android.preference2.cts.R;
 
 import android.content.Context;
 import android.content.res.TypedArray;
diff --git a/tests/tests/preference2/src/android/preference2/cts/CustomSwitchPreference.java b/tests/tests/preference2/src/android/preference2/cts/CustomSwitchPreference.java
index 54e7861..6793c50 100644
--- a/tests/tests/preference2/src/android/preference2/cts/CustomSwitchPreference.java
+++ b/tests/tests/preference2/src/android/preference2/cts/CustomSwitchPreference.java
@@ -16,7 +16,7 @@
 package android.preference2.cts;
 
 
-import com.android.cts.preference2.R;
+import android.preference2.cts.R;
 
 import android.content.Context;
 import android.content.res.TypedArray;
diff --git a/tests/tests/preference2/src/android/preference2/cts/DialogPreferenceTest.java b/tests/tests/preference2/src/android/preference2/cts/DialogPreferenceTest.java
index 1136cee..edcef0c 100644
--- a/tests/tests/preference2/src/android/preference2/cts/DialogPreferenceTest.java
+++ b/tests/tests/preference2/src/android/preference2/cts/DialogPreferenceTest.java
@@ -20,7 +20,7 @@
 import android.preference.DialogPreference;
 import android.test.ActivityInstrumentationTestCase2;
 
-import com.android.cts.preference2.R;
+import android.preference2.cts.R;
 
 public class DialogPreferenceTest
         extends ActivityInstrumentationTestCase2<PreferenceFromCodeActivity> {
diff --git a/tests/tests/preference2/src/android/preference2/cts/FragmentPreferences.java b/tests/tests/preference2/src/android/preference2/cts/FragmentPreferences.java
index dacc192..7efbe76 100644
--- a/tests/tests/preference2/src/android/preference2/cts/FragmentPreferences.java
+++ b/tests/tests/preference2/src/android/preference2/cts/FragmentPreferences.java
@@ -16,7 +16,7 @@
 
 package android.preference2.cts;
 
-import com.android.cts.preference2.R;
+import android.preference2.cts.R;
 
 import android.app.Activity;
 import android.os.Bundle;
diff --git a/tests/tests/preference2/src/android/preference2/cts/ListPreferenceTest.java b/tests/tests/preference2/src/android/preference2/cts/ListPreferenceTest.java
index 32596ff..743b51e 100644
--- a/tests/tests/preference2/src/android/preference2/cts/ListPreferenceTest.java
+++ b/tests/tests/preference2/src/android/preference2/cts/ListPreferenceTest.java
@@ -19,7 +19,7 @@
 import android.preference.ListPreference;
 import android.test.ActivityInstrumentationTestCase2;
 
-import com.android.cts.preference2.R;
+import android.preference2.cts.R;
 
 public class ListPreferenceTest
         extends ActivityInstrumentationTestCase2<PreferenceFromCodeActivity> {
diff --git a/tests/tests/preference2/src/android/preference2/cts/PreferenceFromCodeActivity.java b/tests/tests/preference2/src/android/preference2/cts/PreferenceFromCodeActivity.java
index e76c95a..7a67e3e 100644
--- a/tests/tests/preference2/src/android/preference2/cts/PreferenceFromCodeActivity.java
+++ b/tests/tests/preference2/src/android/preference2/cts/PreferenceFromCodeActivity.java
@@ -16,7 +16,7 @@
 
 package android.preference2.cts;
 
-import com.android.cts.preference2.R;
+import android.preference2.cts.R;
 
 import android.os.Bundle;
 import android.preference.CheckBoxPreference;
diff --git a/tests/tests/preference2/src/android/preference2/cts/PreferenceGroupTest.java b/tests/tests/preference2/src/android/preference2/cts/PreferenceGroupTest.java
index 109ea77..fe0b3b2 100644
--- a/tests/tests/preference2/src/android/preference2/cts/PreferenceGroupTest.java
+++ b/tests/tests/preference2/src/android/preference2/cts/PreferenceGroupTest.java
@@ -16,7 +16,7 @@
 
 package android.preference2.cts;
 
-import com.android.cts.preference2.R;
+import android.preference2.cts.R;
 
 import android.preference.CheckBoxPreference;
 import android.preference.EditTextPreference;
diff --git a/tests/tests/preference2/src/android/preference2/cts/PreferenceTest.java b/tests/tests/preference2/src/android/preference2/cts/PreferenceTest.java
index 328e074..b2907f3 100644
--- a/tests/tests/preference2/src/android/preference2/cts/PreferenceTest.java
+++ b/tests/tests/preference2/src/android/preference2/cts/PreferenceTest.java
@@ -22,7 +22,7 @@
 import android.preference.PreferenceGroup;
 import android.test.ActivityInstrumentationTestCase2;
 
-import com.android.cts.preference2.R;
+import android.preference2.cts.R;
 
 public class PreferenceTest
         extends ActivityInstrumentationTestCase2<PreferenceFromCodeActivity> {
diff --git a/tests/tests/preference2/src/android/preference2/cts/PreferenceWithHeaders.java b/tests/tests/preference2/src/android/preference2/cts/PreferenceWithHeaders.java
index 1bb5637..a44cb7e6 100644
--- a/tests/tests/preference2/src/android/preference2/cts/PreferenceWithHeaders.java
+++ b/tests/tests/preference2/src/android/preference2/cts/PreferenceWithHeaders.java
@@ -20,7 +20,7 @@
 import android.preference.PreferenceActivity;
 import android.preference.PreferenceFragment;
 import android.widget.Button;
-import com.android.cts.preference2.R;
+import android.preference2.cts.R;
 import java.util.List;
 
 /**
diff --git a/tests/tests/preference2/src/android/preference2/cts/PreferencesFromXml.java b/tests/tests/preference2/src/android/preference2/cts/PreferencesFromXml.java
index 0a61461..1aff9f5 100644
--- a/tests/tests/preference2/src/android/preference2/cts/PreferencesFromXml.java
+++ b/tests/tests/preference2/src/android/preference2/cts/PreferencesFromXml.java
@@ -16,7 +16,7 @@
 
 package android.preference2.cts;
 
-import com.android.cts.preference2.R;
+import android.preference2.cts.R;
 import android.os.Bundle;
 import android.preference.PreferenceActivity;
 
diff --git a/tests/tests/preference2/src/android/preference2/cts/SwitchPreferenceTest.java b/tests/tests/preference2/src/android/preference2/cts/SwitchPreferenceTest.java
index 3bd42d2..218c55a 100644
--- a/tests/tests/preference2/src/android/preference2/cts/SwitchPreferenceTest.java
+++ b/tests/tests/preference2/src/android/preference2/cts/SwitchPreferenceTest.java
@@ -20,7 +20,7 @@
 import android.preference.SwitchPreference;
 import android.test.ActivityInstrumentationTestCase2;
 
-import com.android.cts.preference2.R;
+import android.preference2.cts.R;
 
 public class SwitchPreferenceTest
         extends ActivityInstrumentationTestCase2<PreferenceFromCodeActivity> {
diff --git a/tests/tests/print/Android.mk b/tests/tests/print/Android.mk
index 2ece2cf..bceaacc 100644
--- a/tests/tests/print/Android.mk
+++ b/tests/tests/print/Android.mk
@@ -18,12 +18,17 @@
 
 LOCAL_MODULE_TAGS := optional
 
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
 LOCAL_PACKAGE_NAME := CtsPrintTestCases
 
 LOCAL_STATIC_JAVA_LIBRARIES := mockito-target ctstestrunner ub-uiautomator ctsdeviceutil
 
-LOCAL_SDK_VERSION := current
+LOCAL_SDK_VERSION := test_current
 
 include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/print/AndroidManifest.xml b/tests/tests/print/AndroidManifest.xml
index b4a2905..bd58d3b 100644
--- a/tests/tests/print/AndroidManifest.xml
+++ b/tests/tests/print/AndroidManifest.xml
@@ -17,7 +17,7 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-        package="com.android.cts.print">
+        package="android.print.cts">
 
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
 
@@ -53,13 +53,11 @@
 
         <activity
             android:name="android.print.cts.services.SettingsActivity"
-            android:permission="android.permission.START_PRINT_SERVICE_CONFIG_ACTIVITY"
             android:exported="true">
         </activity>
 
         <activity
             android:name="android.print.cts.services.AddPrintersActivity"
-            android:permission="android.permission.START_PRINT_SERVICE_CONFIG_ACTIVITY"
             android:exported="true">
         </activity>
 
@@ -71,8 +69,8 @@
 
   </application>
 
-  <instrumentation android:name="android.support.test.uiautomator.UiAutomatorInstrumentationTestRunner"
-          android:targetPackage="com.android.cts.print"
+  <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+          android:targetPackage="android.print.cts"
           android:label="Tests for the print APIs."/>
 
 </manifest>
diff --git a/tests/tests/print/AndroidTest.xml b/tests/tests/print/AndroidTest.xml
new file mode 100644
index 0000000..9e3e797
--- /dev/null
+++ b/tests/tests/print/AndroidTest.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS Print test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsPrintTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.print.cts" />
+        <option name="runtime-hint" value="33m00s" />
+    </test>
+</configuration>
diff --git a/tests/tests/print/res/drawable/red_printer.xml b/tests/tests/print/res/drawable/red_printer.xml
new file mode 100644
index 0000000..1bd7a4f
--- /dev/null
+++ b/tests/tests/print/res/drawable/red_printer.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+    Copyright (C) 2015 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="48dp"
+        android:height="48dp"
+        android:viewportWidth="48.0"
+        android:viewportHeight="48.0">
+    <path
+        android:pathData="M10,18h28v13h-28z"
+        android:fillAlpha="1"
+        android:fillColor="#cccccc"
+        android:strokeColor="#00000000"/>
+    <path
+        android:pathData="M13,7L13,10L9,10C7,10 4,13 4,15L4,35L13,35L13,40L35,40L35,35L44,35L44,15C44,13 41,10 39,10L35,10L35,7L13,7zM14,8L34,8L34,10L14,10L14,8zM10,18L38,18L38,31L35,31L35,23L13,23L13,31L10,31L10,18zM14,24L34,24L34,39L14,39L14,24z"
+        android:fillColor="#0000ff"
+        android:strokeColor="#00000000"/>
+    <path
+        android:pathData="M14,24h20v15h-20z"
+        android:fillAlpha="1"
+        android:fillColor="#ffffff"
+        android:strokeColor="#00000000"/>
+    <path
+        android:pathData="M14,8h20v2h-20z"
+        android:fillAlpha="1"
+        android:fillColor="#ffffff"
+        android:strokeColor="#00000000"/>
+</vector>
diff --git a/tests/tests/print/res/raw/yellow_printer.png b/tests/tests/print/res/raw/yellow_printer.png
new file mode 100644
index 0000000..2e1cc8d
--- /dev/null
+++ b/tests/tests/print/res/raw/yellow_printer.png
Binary files differ
diff --git a/tests/tests/print/res/values/strings.xml b/tests/tests/print/res/values/strings.xml
index 6d869e9..3cc1256 100644
--- a/tests/tests/print/res/values/strings.xml
+++ b/tests/tests/print/res/values/strings.xml
@@ -22,4 +22,7 @@
     <string name="resolution_300x300">300x300</string>
     <string name="resolution_600x600">600x600</string>
 
+    <string name="testStr1">testStr1</string>
+    <string name="testStr2">testStr2</string>
+
 </resources>
diff --git a/tests/tests/print/res/xml/printservice.xml b/tests/tests/print/res/xml/printservice.xml
index 5579b81..78c7504 100644
--- a/tests/tests/print/res/xml/printservice.xml
+++ b/tests/tests/print/res/xml/printservice.xml
@@ -16,7 +16,7 @@
     limitations under the License.
 -->
 
-<print-service  xmlns:android="http://schemas.android.com/apk/res/android"
-     android:settingsActivity="android.print.services.SettingsActivity"
-     android:addPrintersActivity="android.print.services.AddPrintersActivity"
-     android:advancedPrintOptionsActivity="android.print.services.CustomPrintOptionsActivity"/>
+<print-service xmlns:android="http://schemas.android.com/apk/res/android"
+     android:settingsActivity="android.print.cts.services.SettingsActivity"
+     android:addPrintersActivity="android.print.cts.services.AddPrintersActivity"
+     android:advancedPrintOptionsActivity="android.print.cts.services.CustomPrintOptionsActivity"/>
diff --git a/tests/tests/print/src/android/print/cts/BasePrintTest.java b/tests/tests/print/src/android/print/cts/BasePrintTest.java
old mode 100755
new mode 100644
index ea61806..60b8c5c
--- a/tests/tests/print/src/android/print/cts/BasePrintTest.java
+++ b/tests/tests/print/src/android/print/cts/BasePrintTest.java
@@ -41,20 +41,22 @@
 import android.print.PrintDocumentAdapter.WriteResultCallback;
 import android.print.PrintManager;
 import android.print.PrinterId;
-import android.print.cts.services.FirstPrintService;
 import android.print.cts.services.PrintServiceCallbacks;
 import android.print.cts.services.PrinterDiscoverySessionCallbacks;
-import android.print.cts.services.SecondPrintService;
 import android.print.cts.services.StubbablePrinterDiscoverySession;
 import android.print.pdf.PrintedPdfDocument;
+import android.printservice.CustomPrinterIconCallback;
 import android.printservice.PrintJob;
 import android.printservice.PrintService;
-import android.support.test.uiautomator.UiAutomatorTestCase;
+import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.UiDevice;
 import android.support.test.uiautomator.UiObject;
 import android.support.test.uiautomator.UiObjectNotFoundException;
-import android.support.test.uiautomator.UiScrollable;
 import android.support.test.uiautomator.UiSelector;
+import android.test.InstrumentationTestCase;
 import android.util.DisplayMetrics;
+import android.util.LocaleList;
+import android.util.Log;
 
 import org.hamcrest.BaseMatcher;
 import org.hamcrest.Description;
@@ -62,7 +64,7 @@
 import org.mockito.stubbing.Answer;
 
 import java.io.BufferedReader;
-import java.io.File;
+import java.io.ByteArrayOutputStream;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
@@ -71,36 +73,44 @@
 import java.util.List;
 import java.util.Locale;
 import java.util.concurrent.TimeoutException;
-
 /**
  * This is the base class for print tests.
  */
-public abstract class BasePrintTest extends UiAutomatorTestCase {
+public abstract class BasePrintTest extends InstrumentationTestCase {
+    private final static String LOG_TAG = "BasePrintTest";
 
-    private static final long OPERATION_TIMEOUT = 100000000;
-
+    protected static final long OPERATION_TIMEOUT_MILLIS = 60000;
     private static final String PRINT_SPOOLER_PACKAGE_NAME = "com.android.printspooler";
-
     protected static final String PRINT_JOB_NAME = "Test";
-
     private static final String PM_CLEAR_SUCCESS_OUTPUT = "Success";
-
     private static final String COMMAND_LIST_ENABLED_IME_COMPONENTS = "ime list -s";
-
     private static final String COMMAND_PREFIX_ENABLE_IME = "ime enable ";
-
     private static final String COMMAND_PREFIX_DISABLE_IME = "ime disable ";
+    private static final int CURRENT_USER_ID = -2; // Mirrors UserHandle.USER_CURRENT
 
     private PrintDocumentActivity mActivity;
+    private UiDevice mUiDevice;
 
-    private Locale mOldLocale;
+    /**
+     * Return the UI device
+     *
+     * @return the UI device
+     */
+    public UiDevice getUiDevice() {
+        return mUiDevice;
+    }
+
+    private LocaleList mOldLocale;
 
     private CallCounter mCancelOperationCounter;
     private CallCounter mLayoutCallCounter;
     private CallCounter mWriteCallCounter;
     private CallCounter mFinishCallCounter;
     private CallCounter mPrintJobQueuedCallCounter;
+    private CallCounter mCreateSessionCallCounter;
     private CallCounter mDestroySessionCallCounter;
+    private static CallCounter mDestroyActivityCallCounter = new CallCounter();
+    private static CallCounter mCreateActivityCallCounter = new CallCounter();
 
     private String[] mEnabledImes;
 
@@ -109,12 +119,13 @@
 
         ParcelFileDescriptor pfd = getInstrumentation().getUiAutomation()
                 .executeShellCommand(COMMAND_LIST_ENABLED_IME_COMPONENTS);
-        BufferedReader reader = new BufferedReader(
-                new InputStreamReader(new FileInputStream(pfd.getFileDescriptor())));
+        try (BufferedReader reader = new BufferedReader(
+                new InputStreamReader(new FileInputStream(pfd.getFileDescriptor())))) {
 
-        String line;
-        while ((line = reader.readLine()) != null) {
-            imeList.add(line);
+            String line;
+            while ((line = reader.readLine()) != null) {
+                imeList.add(line);
+            }
         }
 
         String[] imeArray = new String[imeList.size()];
@@ -154,9 +165,10 @@
             return;
         }
 
+        mUiDevice = UiDevice.getInstance(getInstrumentation());
+
         // Make sure we start with a clean slate.
         clearPrintSpoolerData();
-        enablePrintServices();
         disableImes();
 
         // Workaround for dexmaker bug: https://code.google.com/p/dexmaker/issues/detail?id=2
@@ -167,11 +179,11 @@
         // Set to US locale.
         Resources resources = getInstrumentation().getTargetContext().getResources();
         Configuration oldConfiguration = resources.getConfiguration();
-        if (!oldConfiguration.locale.equals(Locale.US)) {
-            mOldLocale = oldConfiguration.locale;
+        if (!oldConfiguration.getLocales().get(0).equals(Locale.US)) {
+            mOldLocale = oldConfiguration.getLocales();
             DisplayMetrics displayMetrics = resources.getDisplayMetrics();
             Configuration newConfiguration = new Configuration(oldConfiguration);
-            newConfiguration.locale = Locale.US;
+            newConfiguration.setLocale(Locale.US);
             resources.updateConfiguration(newConfiguration, displayMetrics);
         }
 
@@ -182,6 +194,7 @@
         mWriteCallCounter = new CallCounter();
         mFinishCallCounter = new CallCounter();
         mPrintJobQueuedCallCounter = new CallCounter();
+        mCreateSessionCallCounter = new CallCounter();
         mDestroySessionCallCounter = new CallCounter();
 
         // Create the activity for the right locale.
@@ -195,7 +208,10 @@
         }
 
         // Done with the activity.
-        getActivity().finish();
+        if (!getActivity().isFinishing()) {
+            getActivity().finish();
+        }
+
         enableImes();
 
         // Restore the locale if needed.
@@ -203,30 +219,33 @@
             Resources resources = getInstrumentation().getTargetContext().getResources();
             DisplayMetrics displayMetrics = resources.getDisplayMetrics();
             Configuration newConfiguration = new Configuration(resources.getConfiguration());
-            newConfiguration.locale = mOldLocale;
+            newConfiguration.setLocales(mOldLocale);
             mOldLocale = null;
             resources.updateConfiguration(newConfiguration, displayMetrics);
         }
 
-        disablePrintServices();
-        // Make sure the spooler is cleaned.
+        // Make sure the spooler is cleaned, this also un-approves all services
         clearPrintSpoolerData();
 
         super.tearDown();
     }
 
-    protected void print(final PrintDocumentAdapter adapter) {
+    protected void print(final PrintDocumentAdapter adapter, final PrintAttributes attributes) {
         // Initiate printing as if coming from the app.
         getInstrumentation().runOnMainSync(new Runnable() {
             @Override
             public void run() {
                 PrintManager printManager = (PrintManager) getActivity()
                         .getSystemService(Context.PRINT_SERVICE);
-                printManager.print("Print job", adapter, null);
+                printManager.print("Print job", adapter, attributes);
             }
         });
     }
 
+    protected void print(PrintDocumentAdapter adapter) {
+        print(adapter, null);
+    }
+
     protected void onCancelOperationCalled() {
         mCancelOperationCounter.call();
     }
@@ -251,6 +270,10 @@
         mPrintJobQueuedCallCounter.call();
     }
 
+    protected void onPrinterDiscoverySessionCreateCalled() {
+        mCreateSessionCallCounter.call();
+    }
+
     protected void onPrinterDiscoverySessionDestroyCalled() {
         mDestroySessionCallCounter.call();
     }
@@ -260,13 +283,18 @@
                 "Did not get expected call to onCancel for the current operation.");
     }
 
-    protected void waitForPrinterDiscoverySessionDestroyCallbackCalled() {
-        waitForCallbackCallCount(mDestroySessionCallCounter, 1,
+    protected void waitForPrinterDiscoverySessionCreateCallbackCalled() {
+        waitForCallbackCallCount(mCreateSessionCallCounter, 1,
+                "Did not get expected call to onCreatePrinterDiscoverySession.");
+    }
+
+    protected void waitForPrinterDiscoverySessionDestroyCallbackCalled(int count) {
+        waitForCallbackCallCount(mDestroySessionCallCounter, count,
                 "Did not get expected call to onDestroyPrinterDiscoverySession.");
     }
 
-    protected void waitForServiceOnPrintJobQueuedCallbackCalled() {
-        waitForCallbackCallCount(mPrintJobQueuedCallCounter, 1,
+    protected void waitForServiceOnPrintJobQueuedCallbackCalled(int count) {
+        waitForCallbackCallCount(mPrintJobQueuedCallCounter, count,
                 "Did not get expected call to onPrintJobQueued.");
     }
 
@@ -280,141 +308,287 @@
                 "Did not get expected call to layout.");
     }
 
-    protected void waitForWriteAdapterCallback() {
-        waitForCallbackCallCount(mWriteCallCounter, 1, "Did not get expected call to write.");
+    protected void waitForWriteAdapterCallback(int count) {
+        waitForCallbackCallCount(mWriteCallCounter, count, "Did not get expected call to write.");
     }
 
     private void waitForCallbackCallCount(CallCounter counter, int count, String message) {
         try {
-            counter.waitForCount(count, OPERATION_TIMEOUT);
+            counter.waitForCount(count, OPERATION_TIMEOUT_MILLIS);
         } catch (TimeoutException te) {
             fail(message);
         }
     }
 
-    protected void selectPrinter(String printerName) throws UiObjectNotFoundException {
+    /**
+     * Indicate the print activity was created.
+     */
+    static void onActivityCreateCalled() {
+        mCreateActivityCallCounter.call();
+    }
+
+    /**
+     * Indicate the print activity was destroyed.
+     */
+    static void onActivityDestroyCalled() {
+        mDestroyActivityCallCounter.call();
+    }
+
+    /**
+     * Get the number of ties the print activity was destroyed.
+     *
+     * @return The number of onDestroy calls on the print activity.
+     */
+    protected int getActivityDestroyCallbackCallCount() {
+        return mDestroyActivityCallCounter.getCallCount();
+    }
+
+    /**
+     * Get the number of ties the print activity was created.
+     *
+     * @return The number of onCreate calls on the print activity.
+     */
+    protected int getActivityCreateCallbackCallCount() {
+        return mCreateActivityCallCounter.getCallCount();
+    }
+
+    /**
+     * Wait until create was called {@code count} times.
+     *
+     * @param count The number of create calls to expect.
+     */
+    protected void waitForActivityCreateCallbackCalled(int count) {
+        waitForCallbackCallCount(mCreateActivityCallCounter, count,
+                "Did not get expected call to create.");
+    }
+
+    /**
+     * Reset all counters.
+     */
+    protected void resetCounters() {
+        mCancelOperationCounter.reset();
+        mLayoutCallCounter.reset();
+        mWriteCallCounter.reset();
+        mFinishCallCounter.reset();
+        mPrintJobQueuedCallCounter.reset();
+        mCreateSessionCallCounter.reset();
+        mDestroySessionCallCounter.reset();
+        mDestroyActivityCallCounter.reset();
+        mCreateActivityCallCounter.reset();
+    }
+
+    protected void selectPrinter(String printerName) throws UiObjectNotFoundException, IOException {
         try {
-            UiObject destinationSpinner = new UiObject(new UiSelector().resourceId(
-                    "com.android.printspooler:id/destination_spinner"));
-            destinationSpinner.click();
-            UiObject printerOption = new UiObject(new UiSelector().text(printerName));
-            if (!printerOption.exists()) {
-                // Scroll through the spinner
-                UiScrollable printerSpinner = new UiScrollable(new UiSelector().scrollable(true));
-                printerSpinner.setAsVerticalList();
-                printerOption = printerSpinner.getChildByText(new UiSelector().text(printerName), printerName);
+            long delay = 100;
+            while (true) {
+                try {
+                    UiObject destinationSpinner = mUiDevice.findObject(new UiSelector().resourceId(
+                            "com.android.printspooler:id/destination_spinner"));
+
+                    destinationSpinner.click();
+
+                    // Give spinner some time to expand
+                    try {
+                        Thread.sleep(delay);
+                    } catch (InterruptedException e) {
+                        // ignore
+                    }
+
+                    // try to select printer
+                    UiObject printerOption = mUiDevice
+                            .findObject(new UiSelector().text(printerName));
+                    printerOption.click();
+                } catch (UiObjectNotFoundException e) {
+                    Log.e(LOG_TAG, "Could not select printer " + printerName, e);
+                }
+
+                // Make sure printer is selected
+                if (getUiDevice().hasObject(By.text(printerName))) {
+                    break;
+                } else {
+                    if (delay <= OPERATION_TIMEOUT_MILLIS) {
+                        Log.w(LOG_TAG, "Cannot find printer " + printerName + ", retrying.");
+                        delay *= 2;
+                        continue;
+                    } else {
+                        throw new UiObjectNotFoundException("Could find printer " + printerName +
+                                " even though we retried");
+                    }
+                }
             }
-            printerOption.click();
         } catch (UiObjectNotFoundException e) {
             dumpWindowHierarchy();
-            throw new UiObjectNotFoundException(e);
+            throw e;
         }
     }
 
-    protected void changeOrientation(String orientation) throws UiObjectNotFoundException {
+    protected void answerPrintServicesWarning(boolean confirm) throws UiObjectNotFoundException {
+        UiDevice uiDevice = UiDevice.getInstance(getInstrumentation());
+        UiObject button;
+        if (confirm) {
+            button = uiDevice.findObject(new UiSelector().resourceId("android:id/button1"));
+        } else {
+            button = uiDevice.findObject(new UiSelector().resourceId("android:id/button2"));
+        }
+        button.click();
+    }
+
+    protected void changeOrientation(String orientation)
+            throws UiObjectNotFoundException, IOException {
         try {
-            UiObject orientationSpinner = new UiObject(new UiSelector().resourceId(
+            UiObject orientationSpinner = mUiDevice.findObject(new UiSelector().resourceId(
                     "com.android.printspooler:id/orientation_spinner"));
             orientationSpinner.click();
-            UiObject orientationOption = new UiObject(new UiSelector().text(orientation));
+            UiObject orientationOption = mUiDevice.findObject(new UiSelector().text(orientation));
             orientationOption.click();
         } catch (UiObjectNotFoundException e) {
             dumpWindowHierarchy();
-            throw new UiObjectNotFoundException(e);
+            throw e;
         }
     }
 
-    protected void changeMediaSize(String mediaSize) throws UiObjectNotFoundException {
+    protected String getOrientation() throws UiObjectNotFoundException, IOException {
         try {
-            UiObject mediaSizeSpinner = new UiObject(new UiSelector().resourceId(
+            UiObject orientationSpinner = mUiDevice.findObject(new UiSelector().resourceId(
+                    "com.android.printspooler:id/orientation_spinner"));
+            return orientationSpinner.getText();
+        } catch (UiObjectNotFoundException e) {
+            dumpWindowHierarchy();
+            throw e;
+        }
+    }
+
+    protected void changeMediaSize(String mediaSize) throws UiObjectNotFoundException, IOException {
+        try {
+            UiObject mediaSizeSpinner = mUiDevice.findObject(new UiSelector().resourceId(
                     "com.android.printspooler:id/paper_size_spinner"));
             mediaSizeSpinner.click();
-            UiObject mediaSizeOption = new UiObject(new UiSelector().text(mediaSize));
+            UiObject mediaSizeOption = mUiDevice.findObject(new UiSelector().text(mediaSize));
             mediaSizeOption.click();
         } catch (UiObjectNotFoundException e) {
             dumpWindowHierarchy();
-            throw new UiObjectNotFoundException(e);
+            throw e;
         }
     }
 
-    protected void changeColor(String color) throws UiObjectNotFoundException {
+    protected String getMediaSize() throws UiObjectNotFoundException, IOException {
         try {
-            UiObject colorSpinner = new UiObject(new UiSelector().resourceId(
+            UiObject mediaSizeSpinner = mUiDevice.findObject(new UiSelector().resourceId(
+                    "com.android.printspooler:id/paper_size_spinner"));
+            return mediaSizeSpinner.getText();
+        } catch (UiObjectNotFoundException e) {
+            dumpWindowHierarchy();
+            throw e;
+        }
+    }
+
+    protected void changeColor(String color) throws UiObjectNotFoundException, IOException {
+        try {
+            UiObject colorSpinner = mUiDevice.findObject(new UiSelector().resourceId(
                     "com.android.printspooler:id/color_spinner"));
             colorSpinner.click();
-            UiObject colorOption = new UiObject(new UiSelector().text(color));
+            UiObject colorOption = mUiDevice.findObject(new UiSelector().text(color));
             colorOption.click();
         } catch (UiObjectNotFoundException e) {
             dumpWindowHierarchy();
-            throw new UiObjectNotFoundException(e);
+            throw e;
         }
     }
 
-    protected void changeDuplex(String duplex) throws UiObjectNotFoundException {
+    protected String getColor() throws UiObjectNotFoundException, IOException {
         try {
-            UiObject duplexSpinner = new UiObject(new UiSelector().resourceId(
+            UiObject colorSpinner = mUiDevice.findObject(new UiSelector().resourceId(
+                    "com.android.printspooler:id/color_spinner"));
+            return colorSpinner.getText();
+        } catch (UiObjectNotFoundException e) {
+            dumpWindowHierarchy();
+            throw e;
+        }
+    }
+
+    protected void changeDuplex(String duplex) throws UiObjectNotFoundException, IOException {
+        try {
+            UiObject duplexSpinner = mUiDevice.findObject(new UiSelector().resourceId(
                     "com.android.printspooler:id/duplex_spinner"));
             duplexSpinner.click();
-            UiObject duplexOption = new UiObject(new UiSelector().text(duplex));
+            UiObject duplexOption = mUiDevice.findObject(new UiSelector().text(duplex));
             duplexOption.click();
         } catch (UiObjectNotFoundException e) {
             dumpWindowHierarchy();
-            throw new UiObjectNotFoundException(e);
+            throw e;
         }
     }
 
-    protected void clickPrintButton() throws UiObjectNotFoundException {
+    protected String getDuplex() throws UiObjectNotFoundException, IOException {
         try {
-            UiObject printButton = new UiObject(new UiSelector().resourceId(
+            UiObject duplexSpinner = mUiDevice.findObject(new UiSelector().resourceId(
+                    "com.android.printspooler:id/duplex_spinner"));
+            return duplexSpinner.getText();
+        } catch (UiObjectNotFoundException e) {
+            dumpWindowHierarchy();
+            throw e;
+        }
+    }
+
+    protected String getCopies() throws UiObjectNotFoundException, IOException {
+        try {
+            UiObject copies = mUiDevice.findObject(new UiSelector().resourceId(
+                    "com.android.printspooler:id/copies_edittext"));
+            return copies.getText();
+        } catch (UiObjectNotFoundException e) {
+            dumpWindowHierarchy();
+            throw e;
+        }
+    }
+
+    protected void clickPrintButton() throws UiObjectNotFoundException, IOException {
+        try {
+            UiObject printButton = mUiDevice.findObject(new UiSelector().resourceId(
                     "com.android.printspooler:id/print_button"));
             printButton.click();
         } catch (UiObjectNotFoundException e) {
             dumpWindowHierarchy();
-            throw new UiObjectNotFoundException(e);
+            throw e;
         }
     }
 
-    private void dumpWindowHierarchy() {
-        String name = "print-test-failure-" + System.currentTimeMillis() + ".xml";
-        File file = new File(getActivity().getFilesDir(), name);
-        getUiDevice().dumpWindowHierarchy(file.toString());
+    protected void dumpWindowHierarchy() throws IOException {
+        ByteArrayOutputStream os = new ByteArrayOutputStream();
+        mUiDevice.dumpWindowHierarchy(os);
+
+        Log.w(LOG_TAG, "Window hierarchy:");
+        for (String line : os.toString("UTF-8").split("\n")) {
+            Log.w(LOG_TAG, line);
+        }
     }
 
     protected PrintDocumentActivity getActivity() {
         return mActivity;
     }
 
-    private void createActivity() {
+    protected void createActivity() {
         mActivity = launchActivity(
                 getInstrumentation().getTargetContext().getPackageName(),
                 PrintDocumentActivity.class, null);
     }
 
     protected void openPrintOptions() throws UiObjectNotFoundException {
-        UiObject expandHandle = new UiObject(new UiSelector().resourceId(
+        UiObject expandHandle = mUiDevice.findObject(new UiSelector().resourceId(
                 "com.android.printspooler:id/expand_collapse_handle"));
         expandHandle.click();
     }
 
+    protected void openCustomPrintOptions() throws UiObjectNotFoundException {
+        UiObject expandHandle = mUiDevice.findObject(new UiSelector().resourceId(
+                "com.android.printspooler:id/more_options_button"));
+        expandHandle.click();
+    }
+
     protected void clearPrintSpoolerData() throws Exception {
         assertTrue("failed to clear print spooler data",
-                SystemUtil.runShellCommand(getInstrumentation(),
-                        String.format("pm clear %s", PRINT_SPOOLER_PACKAGE_NAME))
-                            .contains(PM_CLEAR_SUCCESS_OUTPUT));
-    }
-
-    private void enablePrintServices() throws Exception {
-        String pkgName = getInstrumentation().getContext().getPackageName();
-        String enabledServicesValue = String.format("%s/%s:%s/%s",
-                pkgName, FirstPrintService.class.getCanonicalName(),
-                pkgName, SecondPrintService.class.getCanonicalName());
-        SystemUtil.runShellCommand(getInstrumentation(),
-                "settings put secure enabled_print_services " + enabledServicesValue);
-    }
-
-    private void disablePrintServices() throws Exception {
-        SystemUtil.runShellCommand(getInstrumentation(),
-                "settings put secure enabled_print_services \"\"");
+                SystemUtil.runShellCommand(getInstrumentation(), String.format(
+                        "pm clear --user %d %s", CURRENT_USER_ID, PRINT_SPOOLER_PACKAGE_NAME))
+                        .contains(PM_CLEAR_SUCCESS_OUTPUT));
     }
 
     protected void verifyLayoutCall(InOrder inOrder, PrintDocumentAdapter mock,
@@ -461,7 +635,8 @@
     protected PrinterDiscoverySessionCallbacks createMockPrinterDiscoverySessionCallbacks(
             Answer<Void> onStartPrinterDiscovery, Answer<Void> onStopPrinterDiscovery,
             Answer<Void> onValidatePrinters, Answer<Void> onStartPrinterStateTracking,
-            Answer<Void> onStopPrinterStateTracking, Answer<Void> onDestroy) {
+            Answer<Void> onRequestCustomPrinterIcon, Answer<Void> onStopPrinterStateTracking,
+            Answer<Void> onDestroy) {
         PrinterDiscoverySessionCallbacks callbacks = mock(PrinterDiscoverySessionCallbacks.class);
 
         doCallRealMethod().when(callbacks).setSession(any(StubbablePrinterDiscoverySession.class));
@@ -482,6 +657,11 @@
             doAnswer(onStartPrinterStateTracking).when(callbacks).onStartPrinterStateTracking(
                     any(PrinterId.class));
         }
+        if (onRequestCustomPrinterIcon != null) {
+            doAnswer(onRequestCustomPrinterIcon).when(callbacks).onRequestCustomPrinterIcon(
+                    any(PrinterId.class), any(CancellationSignal.class),
+                    any(CustomPrinterIconCallback.class));
+        }
         if (onStopPrinterStateTracking != null) {
             doAnswer(onStopPrinterStateTracking).when(callbacks).onStopPrinterStateTracking(
                     any(PrinterId.class));
@@ -529,7 +709,7 @@
         document.close();
     }
 
-    protected final class CallCounter {
+    protected static final class CallCounter {
         private final Object mLock = new Object();
 
         private int mCallCount;
@@ -547,6 +727,12 @@
             }
         }
 
+        public void reset() {
+            synchronized (mLock) {
+                mCallCount = 0;
+            }
+        }
+
         public void waitForCount(int count, long timeoutMillis) throws TimeoutException {
             synchronized (mLock) {
                 final long startTimeMillis = SystemClock.uptimeMillis();
@@ -566,6 +752,34 @@
         }
     }
 
+
+    /**
+     * Make {@code printerName} the default printer by adding it to the history of printers by
+     * printing once.
+     *
+     * @param adapter The {@link PrintDocumentAdapter} used
+     * @throws Exception If the printer could not be made default
+     */
+    protected void makeDefaultPrinter(PrintDocumentAdapter adapter, String printerName)
+            throws Exception {
+        // Perform a full print operation on the printer
+        print(adapter);
+        waitForWriteAdapterCallback(1);
+        selectPrinter(printerName);
+        clickPrintButton();
+        answerPrintServicesWarning(true);
+        waitForPrinterDiscoverySessionDestroyCallbackCalled(1);
+
+        // Switch to new activity, which should now use the default printer
+        getActivity().finish();
+
+        int createBefore = getActivityCreateCallbackCallCount();
+        createActivity();
+
+        // Wait for activity to be up
+        waitForActivityCreateCallbackCalled(createBefore + 1);
+    }
+
     protected boolean supportsPrinting() {
         return getInstrumentation().getContext().getPackageManager()
                 .hasSystemFeature(PackageManager.FEATURE_PRINTING);
diff --git a/tests/tests/print/src/android/print/cts/ClassParametersTest.java b/tests/tests/print/src/android/print/cts/ClassParametersTest.java
new file mode 100644
index 0000000..bad47f8
--- /dev/null
+++ b/tests/tests/print/src/android/print/cts/ClassParametersTest.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.print.cts;
+
+import android.print.PrintAttributes;
+import android.print.PrintAttributes.MediaSize;
+import android.print.PrintAttributes.Resolution;
+import android.print.PrintDocumentInfo;
+import android.support.test.runner.AndroidJUnit4;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Test that the print attributes are correctly propagated through the print framework
+ */
+@RunWith(AndroidJUnit4.class)
+public class ClassParametersTest {
+    /**
+     * Run a runnable and expect and exception of a certain type.
+     *
+     * @param r The runnable to run
+     * @param expectedClass The expected exception type
+     */
+    private void assertException(Runnable r, Class<? extends RuntimeException> expectedClass) {
+        try {
+            r.run();
+        } catch (Exception e) {
+            if (e.getClass().isAssignableFrom(expectedClass)) {
+                return;
+            } else {
+                throw new AssertionError("Expected: " + expectedClass.getName() + ", got: "
+                        + e.getClass().getName());
+            }
+        }
+
+        throw new AssertionError("No exception thrown");
+    }
+
+    /**
+     * Test that we cannot create PrintAttributes with illegal parameters.
+     *
+     * @throws Exception If anything is unexpected
+     */
+    @Test
+    public void testIllegalPrintAttributes() throws Exception {
+        assertException(() -> (new PrintAttributes.Builder()).setColorMode(-1),
+                IllegalArgumentException.class);
+        assertException(() -> (new PrintAttributes.Builder()).setColorMode(0),
+                IllegalArgumentException.class);
+        assertException(() -> (new PrintAttributes.Builder()).setColorMode(
+                PrintAttributes.COLOR_MODE_COLOR | PrintAttributes.COLOR_MODE_MONOCHROME),
+                IllegalArgumentException.class);
+
+        assertException(() -> (new PrintAttributes.Builder()).setDuplexMode(-1),
+                IllegalArgumentException.class);
+        assertException(() -> (new PrintAttributes.Builder()).setDuplexMode(0),
+                IllegalArgumentException.class);
+        assertException(() -> (new PrintAttributes.Builder()).setDuplexMode(
+                PrintAttributes.DUPLEX_MODE_LONG_EDGE | PrintAttributes.DUPLEX_MODE_NONE),
+                IllegalArgumentException.class);
+
+        assertException(() -> new Resolution(null, "label", 10, 10),
+                IllegalArgumentException.class);
+        assertException(() -> new Resolution("", "label", 10, 10),
+                IllegalArgumentException.class);
+        assertException(() -> new Resolution("id", null, 10, 10),
+                IllegalArgumentException.class);
+        assertException(() -> new Resolution("id", "", 10, 10),
+                IllegalArgumentException.class);
+        assertException(() -> new Resolution("id", "label", -10, 10),
+                IllegalArgumentException.class);
+        assertException(() -> new Resolution("id", "label", 0, 10),
+                IllegalArgumentException.class);
+        assertException(() -> new Resolution("id", "label", 10, -10),
+                IllegalArgumentException.class);
+        assertException(() -> new Resolution("id", "label", 10, 0),
+                IllegalArgumentException.class);
+
+        assertException(() -> new MediaSize(null, "label", 10, 10),
+                IllegalArgumentException.class);
+        assertException(() -> new MediaSize("", "label", 10, 10),
+                IllegalArgumentException.class);
+        assertException(() -> new MediaSize("id", null, 10, 10),
+                IllegalArgumentException.class);
+        assertException(() -> new MediaSize("id", "", 10, 10),
+                IllegalArgumentException.class);
+        assertException(() -> new MediaSize("id", "label", -10, 10),
+                IllegalArgumentException.class);
+        assertException(() -> new MediaSize("id", "label", 0, 10),
+                IllegalArgumentException.class);
+        assertException(() -> new MediaSize("id", "label", 10, -10),
+                IllegalArgumentException.class);
+        assertException(() -> new MediaSize("id", "label", 10, 0),
+                IllegalArgumentException.class);
+
+        // There is no restrictions on what parameters to set for minMargins.
+    }
+
+    /**
+     * Test that we cannot create PrintDocumentInfo with illegal parameters.
+     *
+     * @throws Exception If anything is unexpected
+     */
+    @Test
+    public void testIllegalPrintDocumentInfo() throws Exception {
+        assertException(() -> new PrintDocumentInfo.Builder(null),
+                IllegalArgumentException.class);
+        assertException(() -> new PrintDocumentInfo.Builder(""),
+                IllegalArgumentException.class);
+
+        assertException(() -> new PrintDocumentInfo.Builder("doc").setPageCount(-2),
+                IllegalArgumentException.class);
+        // -1 == UNKNOWN and 0 are allowed
+
+        // Content type is not restricted
+    }
+}
diff --git a/tests/tests/print/src/android/print/cts/CustomPrintOptionsTest.java b/tests/tests/print/src/android/print/cts/CustomPrintOptionsTest.java
new file mode 100644
index 0000000..619a7c9
--- /dev/null
+++ b/tests/tests/print/src/android/print/cts/CustomPrintOptionsTest.java
@@ -0,0 +1,430 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.print.cts;
+
+import android.os.ParcelFileDescriptor;
+import android.print.PageRange;
+import android.print.PrintAttributes;
+import android.print.PrintAttributes.Margins;
+import android.print.PrintAttributes.MediaSize;
+import android.print.PrintAttributes.Resolution;
+import android.print.PrintDocumentAdapter;
+import android.print.PrintDocumentAdapter.LayoutResultCallback;
+import android.print.PrintDocumentAdapter.WriteResultCallback;
+import android.print.PrintDocumentInfo;
+import android.print.PrintJobInfo;
+import android.print.PrinterCapabilitiesInfo;
+import android.print.PrinterId;
+import android.print.PrinterInfo;
+import android.print.cts.services.CustomPrintOptionsActivity;
+import android.print.cts.services.FirstPrintService;
+import android.print.cts.services.PrintServiceCallbacks;
+import android.print.cts.services.PrinterDiscoverySessionCallbacks;
+import android.print.cts.services.SecondPrintService;
+import android.print.cts.services.StubbablePrinterDiscoverySession;
+import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.UiObject;
+import android.support.test.uiautomator.UiSelector;
+import android.support.test.uiautomator.UiObjectNotFoundException;
+import android.util.Log;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.TimeoutException;
+
+/**
+ * This test verifies changes to the printer capabilities are applied correctly.
+ */
+public class CustomPrintOptionsTest extends BasePrintTest {
+    private final static String LOG_TAG = "CustomPrintOptionsTest";
+    private static final String PRINTER_NAME = "Test printer";
+    private static final int MAX_TRIES = 10;
+
+    // Default settings
+    private final PageRange[] DEFAULT_PAGES = new PageRange[] { new PageRange(0, 0) };
+    private final MediaSize DEFAULT_MEDIA_SIZE = MediaSize.ISO_A0;
+    private final int DEFAULT_COLOR_MODE = PrintAttributes.COLOR_MODE_COLOR;
+    private final int DEFAULT_DUPLEX_MODE = PrintAttributes.DUPLEX_MODE_LONG_EDGE;
+    private final Resolution DEFAULT_RESOLUTION = new Resolution("300x300", "300x300", 300, 300);
+    private final Margins DEFAULT_MARGINS = new Margins(0, 0, 0, 0);
+
+    // All settings that are tested
+    private final PageRange[][] PAGESS = { DEFAULT_PAGES, new PageRange[] { new PageRange(1, 1) },
+            new PageRange[] { new PageRange(0, 2) }
+    };
+    private final MediaSize[] MEDIA_SIZES = { DEFAULT_MEDIA_SIZE, MediaSize.ISO_B0 };
+    private final Integer[] COLOR_MODES = { DEFAULT_COLOR_MODE,
+            PrintAttributes.COLOR_MODE_MONOCHROME
+    };
+    private final Integer[] DUPLEX_MODES = { DEFAULT_DUPLEX_MODE, PrintAttributes.DUPLEX_MODE_NONE
+    };
+    private final Resolution[] RESOLUTIONS = { DEFAULT_RESOLUTION,
+            new Resolution("600x600", "600x600", 600, 600)
+    };
+
+    /**
+     * Get the page ranges currently selected as described in the UI.
+     *
+     * @return Only page ranges from {@link #PAGESS} are detected correctly.
+     *
+     * @throws Exception If something was unexpected
+     */
+    private PageRange[] getPages() throws Exception {
+        if (getUiDevice().hasObject(By.text("All 3"))) {
+            return PAGESS[2];
+        }
+
+        try {
+            UiObject pagesEditText = getUiDevice().findObject(new UiSelector().resourceId(
+                    "com.android.printspooler:id/page_range_edittext"));
+
+            if (pagesEditText.getText().equals("2")) {
+                return PAGESS[1];
+            }
+
+            if (pagesEditText.getText().equals("1")) {
+                return PAGESS[0];
+            }
+
+            return null;
+        } catch (UiObjectNotFoundException e) {
+            dumpWindowHierarchy();
+            throw e;
+        }
+    }
+
+    /**
+     * Test that we can switch to a specific set of settings via the custom print options activity
+     *
+     * @param copyFromOriginal If the print job info should be copied from the original
+     * @param numCopies        The copies to print
+     * @param pages            The page ranges to print
+     * @param mediaSize        The media size to use
+     * @param isPortrait       If the mediaSize is portrait
+     * @param colorMode        The color mode to use
+     * @param duplexMode       The duplex mode to use
+     * @param resolution       The resolution to use
+     *
+     * @throws Exception If anything is unexpected
+     */
+    private void testCase(final boolean copyFromOriginal, final Integer numCopies,
+            final PageRange[] pages, final MediaSize mediaSize, final boolean isPortrait,
+            final Integer colorMode, final Integer duplexMode, final Resolution resolution)
+            throws Exception {
+        if (!supportsPrinting()) {
+            return;
+        }
+
+        final PrintAttributes[] layoutAttributes = new PrintAttributes[1];
+
+        final PrinterDiscoverySessionCallbacks firstSessionCallbacks =
+                createMockPrinterDiscoverySessionCallbacks(invocation -> {
+                    StubbablePrinterDiscoverySession session =
+                            ((PrinterDiscoverySessionCallbacks) invocation.getMock())
+                                    .getSession();
+                    PrinterId printerId = session.getService().generatePrinterId(PRINTER_NAME);
+                    List<PrinterInfo> printers = new ArrayList<>(1);
+                    PrinterCapabilitiesInfo.Builder builder =
+                            new PrinterCapabilitiesInfo.Builder(printerId);
+
+                    builder.setMinMargins(DEFAULT_MARGINS)
+                            .setColorModes(COLOR_MODES[0] | COLOR_MODES[1],
+                                    DEFAULT_COLOR_MODE)
+                            .setDuplexModes(DUPLEX_MODES[0] | DUPLEX_MODES[1],
+                                    DEFAULT_DUPLEX_MODE)
+                            .addMediaSize(DEFAULT_MEDIA_SIZE, true)
+                            .addMediaSize(MEDIA_SIZES[1], false)
+                            .addResolution(DEFAULT_RESOLUTION, true)
+                            .addResolution(RESOLUTIONS[1], false);
+
+                    printers.add(new PrinterInfo.Builder(printerId, PRINTER_NAME,
+                            PrinterInfo.STATUS_IDLE).setCapabilities(builder.build()).build());
+
+                    session.addPrinters(printers);
+                    return null;
+                }, null, null, null, null, null, invocation -> {
+                    onPrinterDiscoverySessionDestroyCalled();
+                    return null;
+                });
+
+        PrintDocumentAdapter adapter = createMockPrintDocumentAdapter(
+                invocation -> {
+                    LayoutResultCallback callback = (LayoutResultCallback) invocation
+                            .getArguments()[3];
+                    PrintDocumentInfo info = new PrintDocumentInfo.Builder(PRINT_JOB_NAME)
+                            .setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT)
+                            .setPageCount(3)
+                            .build();
+
+                    synchronized (CustomPrintOptionsTest.this) {
+                        layoutAttributes[0] = (PrintAttributes) invocation.getArguments()[1];
+
+                        CustomPrintOptionsTest.this.notifyAll();
+                    }
+
+                    callback.onLayoutFinished(info, true);
+                    return null;
+                },
+                invocation -> {
+                    Object[] args = invocation.getArguments();
+                    ParcelFileDescriptor fd = (ParcelFileDescriptor) args[1];
+                    WriteResultCallback callback = (WriteResultCallback) args[3];
+
+                    PageRange[] writtenPages = (PageRange[]) args[0];
+
+                    writeBlankPages(layoutAttributes[0], fd, writtenPages[0].getStart(),
+                            writtenPages[0].getEnd());
+                    fd.close();
+
+                    callback.onWriteFinished(writtenPages);
+
+                    onWriteCalled();
+
+                    return null;
+                }, null);
+
+        // Create the service callbacks for the first print service.
+        PrintServiceCallbacks firstServiceCallbacks = createMockPrintServiceCallbacks(
+                invocation -> firstSessionCallbacks, null, null);
+
+        // Configure the print services.
+        FirstPrintService.setCallbacks(firstServiceCallbacks);
+        SecondPrintService.setCallbacks(createMockPrintServiceCallbacks(null, null, null));
+
+        final PrintAttributes.Builder additionalAttributesBuilder = new PrintAttributes.Builder();
+        final PrintAttributes.Builder newAttributesBuilder = new PrintAttributes.Builder();
+
+        newAttributesBuilder.setMinMargins(DEFAULT_MARGINS);
+
+        if (mediaSize != null) {
+            if (isPortrait) {
+                additionalAttributesBuilder.setMediaSize(mediaSize.asPortrait());
+                newAttributesBuilder.setMediaSize(mediaSize.asPortrait());
+            } else {
+                additionalAttributesBuilder.setMediaSize(mediaSize.asLandscape());
+                newAttributesBuilder.setMediaSize(mediaSize.asLandscape());
+            }
+        } else {
+            newAttributesBuilder.setMediaSize(DEFAULT_MEDIA_SIZE);
+        }
+
+        if (colorMode != null) {
+            additionalAttributesBuilder.setColorMode(colorMode);
+            newAttributesBuilder.setColorMode(colorMode);
+        } else {
+            newAttributesBuilder.setColorMode(DEFAULT_COLOR_MODE);
+        }
+
+        if (duplexMode != null) {
+            additionalAttributesBuilder.setDuplexMode(duplexMode);
+            newAttributesBuilder.setDuplexMode(duplexMode);
+        } else {
+            newAttributesBuilder.setDuplexMode(DEFAULT_DUPLEX_MODE);
+        }
+
+        if (resolution != null) {
+            additionalAttributesBuilder.setResolution(resolution);
+            newAttributesBuilder.setResolution(resolution);
+        } else {
+            newAttributesBuilder.setResolution(DEFAULT_RESOLUTION);
+        }
+
+        CustomPrintOptionsActivity.setCallBack(
+                (printJob, printer) -> {
+                    PrintJobInfo.Builder printJobBuilder;
+
+                    if (copyFromOriginal) {
+                        printJobBuilder = new PrintJobInfo.Builder(printJob);
+                    } else {
+                        printJobBuilder = new PrintJobInfo.Builder(null);
+                    }
+
+                    if (numCopies != null) {
+                        printJobBuilder.setCopies(numCopies);
+                    }
+
+                    if (pages != null) {
+                        printJobBuilder.setPages(pages);
+                    }
+
+                    if (mediaSize != null || colorMode != null || duplexMode != null
+                            || resolution != null) {
+                        printJobBuilder.setAttributes(additionalAttributesBuilder.build());
+                    }
+
+                    return printJobBuilder.build();
+                });
+
+        // This is the first print test that runs. If this is run after other tests these other test
+        // can still cause memory pressure and make the printactivity to go through a destroy-create
+        // cycle. In this case we have to retry to operation.
+        int tries = 0;
+        while (true) {
+            try {
+                clearPrintSpoolerData();
+                resetCounters();
+                makeDefaultPrinter(adapter, PRINTER_NAME);
+                break;
+            } catch (Exception e) {
+                if (getActivityDestroyCallbackCallCount() > 0 && tries < MAX_TRIES) {
+                    Log.e(LOG_TAG, "Activity was destroyed during test, retrying", e);
+
+                    tries++;
+                    continue;
+                }
+
+                throw e;
+            }
+        }
+
+        // Check that the attributes were send to the print service
+        PrintAttributes newAttributes = newAttributesBuilder.build();
+        Log.i(LOG_TAG, "Change to attributes: " + newAttributes + ", copies: " + numCopies +
+                ", pages: " + Arrays.toString(pages) + ", copyFromOriginal: " + copyFromOriginal);
+
+        // This is the first print test that runs. If this is run after other tests these other test
+        // can still cause memory pressure and make the printactivity to go through a destroy-create
+        // cycle. In this case we have to retry to operation.
+        while (true) {
+            try {
+                resetCounters();
+
+                // Start printing
+                print(adapter);
+
+                // Wait for write.
+                waitForWriteAdapterCallback(1);
+
+                // Open the print options.
+                openPrintOptions();
+
+                // Apply options by executing callback above
+                Log.d(LOG_TAG, "Apply changes");
+                openCustomPrintOptions();
+
+                Log.d(LOG_TAG, "Check attributes");
+                long endTime = System.currentTimeMillis() + OPERATION_TIMEOUT_MILLIS;
+                synchronized (this) {
+                    while (layoutAttributes[0] == null ||
+                            !layoutAttributes[0].equals(newAttributes)) {
+                        wait(Math.max(1, endTime - System.currentTimeMillis()));
+
+                        if (endTime < System.currentTimeMillis()) {
+                            throw new TimeoutException(
+                                    "Print attributes did not change to " + newAttributes + " in " +
+                                            OPERATION_TIMEOUT_MILLIS + " ms. Current attributes"
+                                            + layoutAttributes[0]);
+                        }
+                    }
+                }
+
+                PageRange[] newPages;
+
+                if (pages == null) {
+                    newPages = new PageRange[] { new PageRange(0, 2) };
+                } else {
+                    newPages = pages;
+                }
+
+                Log.d(LOG_TAG, "Check pages");
+                while (true) {
+                    try {
+                        PageRange[] actualPages = getPages();
+                        if (!Arrays.equals(newPages, actualPages)) {
+                            new AssertionError(
+                                    "Expected " + Arrays.toString(newPages) + ", actual " +
+                                            Arrays.toString(actualPages));
+                        }
+
+                        break;
+                    } catch (Exception e) {
+                        if (endTime < System.currentTimeMillis()) {
+                            throw e;
+                        } else {
+                            Log.e(LOG_TAG, "Could not verify pages, retrying", e);
+                            Thread.sleep(100);
+                        }
+                    }
+                }
+
+                break;
+            } catch (Exception e) {
+                if (getActivityDestroyCallbackCallCount() > 0 && tries < MAX_TRIES) {
+                    Log.e(LOG_TAG, "Activity was destroyed during test, retrying", e);
+
+                    tries++;
+                    continue;
+                }
+
+                throw e;
+            }
+        }
+
+        // Abort printing
+        getActivity().finish();
+
+        waitForPrinterDiscoverySessionDestroyCallbackCalled(1);
+    }
+
+    public void testChangeToChangeEveryThing() throws Exception {
+        testCase(false, 2, PAGESS[1], MEDIA_SIZES[1], false, COLOR_MODES[1], DUPLEX_MODES[1],
+                RESOLUTIONS[1]);
+    }
+
+    public void testChangeToAttributes() throws Exception {
+        testCase(false, null, null, MEDIA_SIZES[1], false, COLOR_MODES[1], DUPLEX_MODES[1],
+                RESOLUTIONS[1]);
+    }
+
+    public void testChangeToNonAttributes() throws Exception {
+        testCase(false, 2, PAGESS[1], null, true, null, null, null);
+    }
+
+    public void testChangeToAttributesNoCopy() throws Exception {
+        testCase(true, null, null, MEDIA_SIZES[1], false, COLOR_MODES[1], DUPLEX_MODES[1],
+                RESOLUTIONS[1]);
+    }
+
+    public void testChangeToNonAttributesNoCopy() throws Exception {
+        testCase(true, 2, PAGESS[1], null, true, null, null, null);
+    }
+
+    public void testChangeToDefault() throws Exception {
+        testCase(false, 1, DEFAULT_PAGES, DEFAULT_MEDIA_SIZE, DEFAULT_MEDIA_SIZE.isPortrait(),
+                DEFAULT_COLOR_MODE, DEFAULT_DUPLEX_MODE, DEFAULT_RESOLUTION);
+    }
+
+    public void testChangeToDefaultNoCopy() throws Exception {
+        testCase(true, 1, DEFAULT_PAGES, DEFAULT_MEDIA_SIZE, DEFAULT_MEDIA_SIZE.isPortrait(),
+                DEFAULT_COLOR_MODE, DEFAULT_DUPLEX_MODE, DEFAULT_RESOLUTION);
+    }
+
+    public void testChangeToNothing() throws Exception {
+        testCase(false, null, null, null, true, null, null, null);
+    }
+
+    public void testChangeToNothingNoCopy() throws Exception {
+        testCase(true, null, null, null, true, null, null, null);
+    }
+
+    public void testChangeToAllPages() throws Exception {
+        testCase(false, null, PAGESS[2], null, true, null, null, null);
+    }
+}
diff --git a/tests/tests/print/src/android/print/cts/PageRangeAdjustmentTest.java b/tests/tests/print/src/android/print/cts/PageRangeAdjustmentTest.java
index b9fd50a..df142b9 100644
--- a/tests/tests/print/src/android/print/cts/PageRangeAdjustmentTest.java
+++ b/tests/tests/print/src/android/print/cts/PageRangeAdjustmentTest.java
@@ -59,6 +59,8 @@
  */
 public class PageRangeAdjustmentTest extends BasePrintTest {
 
+    private static final int MAX_PREVIEW_PAGES_BATCH = 50;
+    private static final int PAGE_COUNT = 60;
     private static final String FIRST_PRINTER = "First printer";
 
     public void testAllPagesWantedAndAllPagesWritten() throws Exception {
@@ -101,7 +103,7 @@
                 LayoutResultCallback callback = (LayoutResultCallback) invocation.getArguments()[3];
                 PrintDocumentInfo info = new PrintDocumentInfo.Builder(PRINT_JOB_NAME)
                         .setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT)
-                        .setPageCount(100)
+                        .setPageCount(PAGE_COUNT)
                         .build();
                 callback.onLayoutFinished(info, false);
                 // Mark layout was called.
@@ -115,7 +117,7 @@
                 PageRange[] pages = (PageRange[]) args[0];
                 ParcelFileDescriptor fd = (ParcelFileDescriptor) args[1];
                 WriteResultCallback callback = (WriteResultCallback) args[3];
-                writeBlankPages(printAttributes[0], fd, 0, 99);
+                writeBlankPages(printAttributes[0], fd, 0, PAGE_COUNT - 1);
                 fd.close();
                 callback.onWriteFinished(pages);
                 // Mark write was called.
@@ -135,7 +137,7 @@
         print(adapter);
 
         // Wait for write.
-        waitForWriteAdapterCallback();
+        waitForWriteAdapterCallback(1);
 
         // Select the first printer.
         selectPrinter(FIRST_PRINTER);
@@ -146,11 +148,14 @@
         // Click the print button.
         clickPrintButton();
 
+        // Answer the dialog for the print service cloud warning
+        answerPrintServicesWarning(true);
+
         // Wait for finish.
         waitForAdapterFinishCallbackCalled();
 
         // Wait for the print job.
-        waitForServiceOnPrintJobQueuedCallbackCalled();
+        waitForServiceOnPrintJobQueuedCallbackCalled(1);
 
         // Verify the expected calls.
         InOrder inOrder = inOrder(firstServiceCallbacks);
@@ -206,7 +211,7 @@
                 LayoutResultCallback callback = (LayoutResultCallback) invocation.getArguments()[3];
                 PrintDocumentInfo info = new PrintDocumentInfo.Builder(PRINT_JOB_NAME)
                         .setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT)
-                        .setPageCount(100)
+                        .setPageCount(PAGE_COUNT)
                         .build();
                 callback.onLayoutFinished(info, false);
                 // Mark layout was called.
@@ -218,10 +223,10 @@
             public Void answer(InvocationOnMock invocation) throws Throwable {
                 Object[] args = invocation.getArguments();
                 PageRange[] pages = (PageRange[]) args[0];
-                assertTrue(pages[pages.length - 1].getEnd() < 100);
+                assertTrue(pages[pages.length - 1].getEnd() < PAGE_COUNT);
                 ParcelFileDescriptor fd = (ParcelFileDescriptor) args[1];
                 WriteResultCallback callback = (WriteResultCallback) args[3];
-                writeBlankPages(printAttributes[0], fd, 0, 99);
+                writeBlankPages(printAttributes[0], fd, 0, PAGE_COUNT - 1);
                 fd.close();
                 callback.onWriteFinished(new PageRange[] {PageRange.ALL_PAGES});
                 // Mark write was called.
@@ -241,7 +246,7 @@
         print(adapter);
 
         // Wait for write.
-        waitForWriteAdapterCallback();
+        waitForWriteAdapterCallback(1);
 
         // Open the print options.
         openPrintOptions();
@@ -258,11 +263,14 @@
         // Click the print button.
         clickPrintButton();
 
+        // Answer the dialog for the print service cloud warning
+        answerPrintServicesWarning(true);
+
         // Wait for finish.
         waitForAdapterFinishCallbackCalled();
 
         // Wait for the print job.
-        waitForServiceOnPrintJobQueuedCallbackCalled();
+        waitForServiceOnPrintJobQueuedCallbackCalled(1);
 
         // Verify the expected calls.
         InOrder inOrder = inOrder(firstServiceCallbacks);
@@ -277,6 +285,8 @@
     }
 
     public void testSomePagesWantedAndSomeMorePagesWritten() throws Exception {
+        final int REQUESTED_PAGE = 55;
+
         if (!supportsPrinting()) {
             return;
         }
@@ -295,8 +305,8 @@
                 PrintJob printJob = (PrintJob) invocation.getArguments()[0];
                 PrintJobInfo printJobInfo = printJob.getInfo();
                 PageRange[] pages = printJobInfo.getPages();
-                // We asked only for page 60 (index 59) but got 60 and 61 (indices
-                // 59, 60), but the system pruned the extra page, hence we expect
+                // We asked only for page 55 (index 54) but got 55 and 56 (indices
+                // 54, 55), but the system pruned the extra page, hence we expect
                 // to print all pages.
                 assertTrue(pages.length == 1 && PageRange.ALL_PAGES.equals(pages[0]));
                 assertSame(printJob.getDocument().getInfo().getPageCount(), 1);
@@ -321,7 +331,7 @@
                 LayoutResultCallback callback = (LayoutResultCallback) invocation.getArguments()[3];
                 PrintDocumentInfo info = new PrintDocumentInfo.Builder(PRINT_JOB_NAME)
                         .setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT)
-                        .setPageCount(100)
+                        .setPageCount(PAGE_COUNT)
                         .build();
                 callback.onLayoutFinished(info, false);
                 // Mark layout was called.
@@ -346,8 +356,9 @@
                     callback.onWriteFinished(pages);
                 } else {
                     // Otherwise write a page more that the one we selected.
-                    writeBlankPages(printAttributes[0], fd, 59, 60);
-                    callback.onWriteFinished(new PageRange[] {new PageRange(59, 60)});
+                    writeBlankPages(printAttributes[0], fd, REQUESTED_PAGE - 1, REQUESTED_PAGE);
+                    callback.onWriteFinished(new PageRange[] {new PageRange(REQUESTED_PAGE - 1,
+                            REQUESTED_PAGE)});
                 }
 
                 fd.close();
@@ -369,7 +380,7 @@
         print(adapter);
 
         // Wait for write.
-        waitForWriteAdapterCallback();
+        waitForWriteAdapterCallback(1);
 
         // Open the print options.
         openPrintOptions();
@@ -381,16 +392,19 @@
         waitForLayoutAdapterCallbackCount(2);
 
         // Select a page not written for preview.
-        selectPages("60");
+        selectPages(Integer.valueOf(REQUESTED_PAGE).toString());
 
         // Click the print button.
         clickPrintButton();
 
+        // Answer the dialog for the print service cloud warning
+        answerPrintServicesWarning(true);
+
         // Wait for finish.
         waitForAdapterFinishCallbackCalled();
 
         // Wait for the print job.
-        waitForServiceOnPrintJobQueuedCallbackCalled();
+        waitForServiceOnPrintJobQueuedCallbackCalled(1);
 
         // Verify the expected calls.
         InOrder inOrder = inOrder(firstServiceCallbacks);
@@ -434,7 +448,7 @@
                 LayoutResultCallback callback = (LayoutResultCallback) invocation.getArguments()[3];
                 PrintDocumentInfo info = new PrintDocumentInfo.Builder(PRINT_JOB_NAME)
                         .setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT)
-                        .setPageCount(100)
+                        .setPageCount(PAGE_COUNT)
                         .build();
                 callback.onLayoutFinished(info, false);
                 // Mark layout was called.
@@ -452,7 +466,7 @@
 
                 // We should be asked for some pages...
                 assertSame(pages[0].getStart(), 0);
-                assertTrue(pages[0].getEnd() == 49);
+                assertTrue(pages[0].getEnd() == MAX_PREVIEW_PAGES_BATCH - 1);
 
                 writeBlankPages(printAttributes[0], fd, pages[0].getStart(), pages[0].getEnd());
                 fd.close();
@@ -475,7 +489,7 @@
         print(adapter);
 
         // Wait for write.
-        waitForWriteAdapterCallback();
+        waitForWriteAdapterCallback(1);
 
         // Cancel printing.
         getUiDevice().pressBack(); // wakes up the device.
@@ -541,7 +555,7 @@
                 LayoutResultCallback callback = (LayoutResultCallback) invocation.getArguments()[3];
                 PrintDocumentInfo info = new PrintDocumentInfo.Builder(PRINT_JOB_NAME)
                         .setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT)
-                        .setPageCount(100)
+                        .setPageCount(PAGE_COUNT)
                         .build();
                 callback.onLayoutFinished(info, false);
                 // Mark layout was called.
@@ -581,7 +595,7 @@
         print(adapter);
 
         // Wait for write.
-        waitForWriteAdapterCallback();
+        waitForWriteAdapterCallback(1);
 
         // Open the print options.
         openPrintOptions();
@@ -598,11 +612,14 @@
         // Click the print button.
         clickPrintButton();
 
+        // Answer the dialog for the print service cloud warning
+        answerPrintServicesWarning(true);
+
         // Wait for finish.
         waitForAdapterFinishCallbackCalled();
 
         // Wait for the print job.
-        waitForServiceOnPrintJobQueuedCallbackCalled();
+        waitForServiceOnPrintJobQueuedCallbackCalled(1);
 
         // Verify the expected calls.
         InOrder inOrder = inOrder(firstServiceCallbacks);
@@ -667,7 +684,7 @@
 
                 return null;
             }
-        }, null, null, null, null, null);
+        }, null, null, null, null, null, null);
     }
 
     private PrintServiceCallbacks createSecondMockPrintServiceCallbacks() {
diff --git a/tests/tests/print/src/android/print/cts/PrintAttributesTest.java b/tests/tests/print/src/android/print/cts/PrintAttributesTest.java
new file mode 100644
index 0000000..a489499
--- /dev/null
+++ b/tests/tests/print/src/android/print/cts/PrintAttributesTest.java
@@ -0,0 +1,642 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.print.cts;
+
+import android.os.ParcelFileDescriptor;
+import android.print.PageRange;
+import android.print.PrintAttributes;
+import android.print.PrintAttributes.Margins;
+import android.print.PrintAttributes.MediaSize;
+import android.print.PrintAttributes.Resolution;
+import android.print.PrintDocumentAdapter;
+import android.print.PrintDocumentAdapter.LayoutResultCallback;
+import android.print.PrintDocumentAdapter.WriteResultCallback;
+import android.print.PrintDocumentInfo;
+import android.print.PrinterCapabilitiesInfo;
+import android.print.PrinterId;
+import android.print.PrinterInfo;
+import android.print.cts.services.FirstPrintService;
+import android.print.cts.services.PrintServiceCallbacks;
+import android.print.cts.services.PrinterDiscoverySessionCallbacks;
+import android.print.cts.services.SecondPrintService;
+import android.print.cts.services.StubbablePrinterDiscoverySession;
+import android.printservice.PrintJob;
+
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Test that the print attributes are correctly propagated through the print framework
+ */
+public class PrintAttributesTest extends BasePrintTest {
+    private final String PRINTER_NAME = "Test printer";
+
+    private final Margins[] MIN_MARGINS = {
+            new Margins(0, 0, 0, 0), new Margins(10, 10, 10, 10), new Margins(20, 20, 20, 20),
+    };
+
+    private final MediaSize MEDIA_SIZES[] = {
+            MediaSize.ISO_A3, MediaSize.ISO_A4, MediaSize.ISO_A5
+    };
+
+    private final int COLOR_MODES[] = {
+            PrintAttributes.COLOR_MODE_MONOCHROME, PrintAttributes.COLOR_MODE_COLOR
+    };
+
+    private final int DUPLEX_MODES[] = {
+            PrintAttributes.DUPLEX_MODE_NONE, PrintAttributes.DUPLEX_MODE_LONG_EDGE,
+            PrintAttributes.DUPLEX_MODE_SHORT_EDGE
+    };
+
+    private final Resolution RESOLUTIONS[] = {
+            new Resolution("300x300", "300x300", 300, 300),
+            new Resolution("600x600", "600x600", 600, 600),
+            new Resolution("1200x1200", "1200x1200", 1200, 1200)
+    };
+
+    /**
+     * Stores the {@link PrintAttributes} passed to the layout method
+     */
+    private PrintAttributes mLayoutAttributes;
+
+    /**
+     * Create a new {@link PrintAttributes} object with the given properties.
+     *
+     * All properties can be null/0 to remain unset.
+     *
+     * @param mediaSize {@link MediaSize} to use
+     * @param colorMode Color mode to use
+     * @param duplexMode Duplex mode to use
+     * @param resolution {@link Resolution} to use
+     *
+     * @return The newly created object or null if no properties are set
+     */
+    private PrintAttributes createAttributes(MediaSize mediaSize, int colorMode, int duplexMode,
+            Resolution resolution) {
+        if (mediaSize == null && colorMode == 0 && duplexMode == 0 && resolution == null) {
+            return null;
+        }
+
+        PrintAttributes.Builder builder = new PrintAttributes.Builder();
+
+        if (mediaSize != null) {
+            builder.setMediaSize(mediaSize);
+        }
+
+        if (colorMode != 0) {
+            builder.setColorMode(colorMode);
+        }
+
+        if (duplexMode != 0) {
+            builder.setDuplexMode(duplexMode);
+        }
+
+        if (resolution != null) {
+            builder.setResolution(resolution);
+        }
+
+        return builder.build();
+    }
+
+    /**
+     * Create {@link PrinterDiscoverySessionCallbacks} with a single printer that has the given
+     * capabilities
+     *
+     * @param minMargins The minMargins of the printer
+     * @param mediaSizes The {@link MediaSize media sizes} supported by the printer
+     * @param defaultMediaSize The default {@link MediaSize}
+     * @param colorModes The color modes supported by the printer
+     * @param defaultColorMode The default color mode
+     * @param duplexModes The duplex modes supported by the printer
+     * @param defaultDuplexMode The default duplex mode
+     * @param resolutions The {@link Resolution resolutions} supported by the printer
+     * @param defaultResolution The default {@link Resolution} to use
+     *
+     * @return New {@link PrinterDiscoverySessionCallbacks} with a single printer that has the
+     *         given capabilities
+     */
+    private PrinterDiscoverySessionCallbacks createMockPrinterDiscoverySessionCallbacks(
+            final Margins minMargins, final MediaSize mediaSizes[],
+            final MediaSize defaultMediaSize, final int colorModes[], final int defaultColorMode,
+            final int duplexModes[], final int defaultDuplexMode, final Resolution resolutions[],
+            final Resolution defaultResolution) {
+        return createMockPrinterDiscoverySessionCallbacks(new Answer<Void>() {
+            @Override
+            public Void answer(InvocationOnMock invocation) {
+                StubbablePrinterDiscoverySession session =
+                        ((PrinterDiscoverySessionCallbacks) invocation.getMock()).getSession();
+
+                if (session.getPrinters().isEmpty()) {
+                    List<PrinterInfo> printers = new ArrayList<PrinterInfo>();
+                    PrinterId printerId = session.getService().generatePrinterId(PRINTER_NAME);
+
+                    PrinterCapabilitiesInfo.Builder builder =
+                            new PrinterCapabilitiesInfo.Builder(printerId);
+
+                    builder.setMinMargins(minMargins);
+
+                    int mediaSizesLength = mediaSizes.length;
+                    for (int i = 0; i < mediaSizesLength; i++) {
+                        if (mediaSizes[i].equals(defaultMediaSize)) {
+                            builder.addMediaSize(mediaSizes[i], true);
+                        } else {
+                            builder.addMediaSize(mediaSizes[i], false);
+                        }
+                    }
+
+                    int colorModesMask = 0;
+                    int colorModesLength = colorModes.length;
+                    for (int i = 0; i < colorModesLength; i++) {
+                        colorModesMask |= colorModes[i];
+                    }
+                    builder.setColorModes(colorModesMask, defaultColorMode);
+
+                    int duplexModesMask = 0;
+                    int duplexModeLength = duplexModes.length;
+                    for (int i = 0; i < duplexModeLength; i++) {
+                        duplexModesMask |= duplexModes[i];
+                    }
+                    builder.setDuplexModes(duplexModesMask, defaultDuplexMode);
+
+                    int resolutionsLength = resolutions.length;
+                    for (int i = 0; i < resolutionsLength; i++) {
+                        if (resolutions[i].equals(defaultResolution)) {
+                            builder.addResolution(resolutions[i], true);
+                        } else {
+                            builder.addResolution(resolutions[i], false);
+                        }
+                    }
+
+                    PrinterInfo printer = new PrinterInfo.Builder(printerId, PRINTER_NAME,
+                            PrinterInfo.STATUS_IDLE).setCapabilities(builder.build()).build();
+                    printers.add(printer);
+
+                    session.addPrinters(printers);
+                }
+                return null;
+            }
+        }, null, null, new Answer<Void>() {
+            @Override
+            public Void answer(InvocationOnMock invocation) throws Throwable {
+                return null;
+            }
+        }, null, null, new Answer<Void>() {
+            @Override
+            public Void answer(InvocationOnMock invocation) throws Throwable {
+                // Take a note onDestroy was called.
+                onPrinterDiscoverySessionDestroyCalled();
+                return null;
+            }
+        });
+    }
+
+    /**
+     * Create dummy {@link PrintServiceCallbacks}
+     *
+     * This is needed to as the print framework is trying to talk to any printer even if is not set
+     * up.
+     *
+     * @return Dummy {@link PrintServiceCallbacks}
+     */
+    private PrintServiceCallbacks createDummyMockPrintServiceCallbacks() {
+        return createMockPrintServiceCallbacks(null, null, null);
+    }
+
+    /**
+     * Create a {@link PrintDocumentAdapter} that serves empty pages
+     *
+     * @return A new {@link PrintDocumentAdapter}
+     */
+    private PrintDocumentAdapter createMockPrintDocumentAdapter() {
+        return createMockPrintDocumentAdapter(
+                new Answer<Void>() {
+                    @Override
+                    public Void answer(InvocationOnMock invocation) throws Throwable {
+                        mLayoutAttributes = (PrintAttributes) invocation.getArguments()[1];
+                        LayoutResultCallback callback =
+                                (LayoutResultCallback) invocation.getArguments()[3];
+                        PrintDocumentInfo info = new PrintDocumentInfo.Builder(PRINT_JOB_NAME)
+                                .setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT)
+                                .setPageCount(1)
+                                .build();
+                        callback.onLayoutFinished(info, false);
+                        // Mark layout was called.
+                        onLayoutCalled();
+                        return null;
+                    }
+                }, new Answer<Void>() {
+                    @Override
+                    public Void answer(InvocationOnMock invocation) throws Throwable {
+                        Object[] args = invocation.getArguments();
+                        PageRange[] pages = (PageRange[]) args[0];
+                        ParcelFileDescriptor fd = (ParcelFileDescriptor) args[1];
+                        WriteResultCallback callback = (WriteResultCallback) args[3];
+                        writeBlankPages(mLayoutAttributes, fd, pages[0].getStart(),
+                                pages[0].getEnd());
+                        fd.close();
+                        callback.onWriteFinished(pages);
+                        // Mark write was called.
+                        onWriteCalled();
+                        return null;
+                    }
+                }, new Answer<Void>() {
+                    @Override
+                    public Void answer(InvocationOnMock invocation) throws Throwable {
+                        // Mark finish was called.
+                        onFinishCalled();
+                        return null;
+                    }
+                });
+    }
+
+    /**
+     * Set up a single printer with the given capabilities
+     *
+     * @param minMargins The minMargins of the printer
+     * @param mediaSizes The {@link MediaSize media sizes} supported by the printer
+     * @param defaultMediaSize The default {@link MediaSize}
+     * @param colorModes The color modes supported by the printer
+     * @param defaultColorMode The default color mode
+     * @param duplexModes The duplex modes supported by the printer
+     * @param defaultDuplexMode The default duplex mode
+     * @param resolutions The {@link Resolution resolutions} supported by the printer
+     * @param defaultResolution The default {@link Resolution} to use
+     *
+     * @return A {@link PrintDocumentAdapter} that can be used for the new printer
+     */
+    private PrintDocumentAdapter setUpPrinter(Margins minMargins, MediaSize mediaSizes[],
+            MediaSize defaultMediaSize, int colorModes[], int defaultColorMode, int duplexModes[],
+            int defaultDuplexMode, Resolution resolutions[], Resolution defaultResolution) {
+        final PrinterDiscoverySessionCallbacks sessionCallbacks =
+                createMockPrinterDiscoverySessionCallbacks(minMargins, mediaSizes,
+                        defaultMediaSize, colorModes, defaultColorMode, duplexModes,
+                        defaultDuplexMode, resolutions, defaultResolution);
+
+        PrintServiceCallbacks serviceCallbacks = createMockPrintServiceCallbacks(
+                new Answer<PrinterDiscoverySessionCallbacks>() {
+                    @Override
+                    public PrinterDiscoverySessionCallbacks answer(InvocationOnMock invocation) {
+                        return sessionCallbacks;
+                    }
+                },
+                new Answer<Void>() {
+                    @Override
+                    public Void answer(InvocationOnMock invocation) {
+                        PrintJob printJob = (PrintJob) invocation.getArguments()[0];
+                        // We pretend the job is handled immediately.
+                        printJob.complete();
+                        return null;
+                    }
+                }, null);
+
+        // Configure the print services.
+        FirstPrintService.setCallbacks(serviceCallbacks);
+
+        // We need to set up the second print service too, otherwise we get a null pointer in the
+        // print framework
+        SecondPrintService.setCallbacks(createDummyMockPrintServiceCallbacks());
+
+        // Create a print adapter that respects the print contract.
+        return createMockPrintDocumentAdapter();
+    }
+
+    /**
+     * Check if a value is in an array.
+     *
+     * To be use instead of Arrays.asList(array).contains(value) for ints.
+     *
+     * @param array The array the value might be in
+     * @param value The value to search for
+     *
+     * @return true iff the value is in the array
+     */
+    private boolean isInArray(final int array[], int value) {
+        int arrayLength = array.length;
+        for (int i = 0; i < arrayLength; i++) {
+            if (array[i] == value) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Flexible base test for all print attribute tests.
+     *
+     * Asserts that the default and suggested attributes are properly honored by the print
+     * framework.
+     *
+     * @param minMargins The minMargins of the printer
+     * @param mediaSizes The {@link MediaSize media sizes} supported by the printer
+     * @param defaultMediaSize The default {@link MediaSize}
+     * @param colorModes The color modes supported by the printer
+     * @param defaultColorMode The default color mode
+     * @param duplexModes The duplex modes supported by the printer
+     * @param defaultDuplexMode The default duplex mode
+     * @param resolutions The {@link Resolution resolutions} supported by the printer
+     * @param defaultResolution The default {@link Resolution} to use
+     * @param suggestedMediaSize The suggested {@link MediaSize} for the print job
+     * @param suggestedColorMode The suggested color mode for the print job
+     * @param suggestedDuplexMode The suggested duplex mode for the print job
+     * @param suggestedResolution The suggested resolution for the print job
+     *
+     * @throws Exception If anything is unexpected
+     */
+    private void baseTest(Margins minMargins, MediaSize mediaSizes[],
+            MediaSize defaultMediaSize, MediaSize suggestedMediaSize, int colorModes[],
+            int defaultColorMode, int suggestedColorMode, int duplexModes[],
+            int defaultDuplexMode, int suggestedDuplexMode, Resolution resolutions[],
+            Resolution defaultResolution, Resolution suggestedResolution) throws Exception {
+        if (!supportsPrinting()) {
+            return;
+        }
+
+        // Set up printer with supported and default attributes
+        PrintDocumentAdapter adapter =
+                setUpPrinter(minMargins, mediaSizes, defaultMediaSize, colorModes, defaultColorMode,
+                        duplexModes, defaultDuplexMode, resolutions, defaultResolution);
+
+        // Make printer default. This is necessary as a different default printer might pre-select
+        // its default attributes and thereby overrides the defaults of the tested printer.
+        makeDefaultPrinter(adapter, PRINTER_NAME);
+
+        // Select suggested attributes
+        PrintAttributes suggestedAttributes = createAttributes(suggestedMediaSize,
+                suggestedColorMode, suggestedDuplexMode, suggestedResolution);
+
+        // Start print action and wait for layout, the result is stored in #layoutAttributes,
+        // @see createMockPrintDocumentAdapter
+        print(adapter, suggestedAttributes);
+        waitForWriteAdapterCallback(2);
+        clickPrintButton();
+        waitForPrinterDiscoverySessionDestroyCallbackCalled(2);
+
+        // It does not make sense to suggest minMargins, hence the print framework always picks
+        // the one set up for the printer.
+        assertEquals("Min margins not as expected", minMargins, mLayoutAttributes.getMinMargins());
+
+        // Verify that the attributes are honored properly
+        if (suggestedMediaSize != null && Arrays.asList(mediaSizes).contains(suggestedMediaSize)) {
+            assertEquals("Media size not as suggested", suggestedMediaSize,
+                    mLayoutAttributes.getMediaSize());
+        } else {
+            assertEquals("Media size not default", defaultMediaSize,
+                    mLayoutAttributes.getMediaSize());
+        }
+
+        if (suggestedColorMode != 0 && isInArray(colorModes, suggestedColorMode)) {
+            assertEquals("Color mode not as suggested", suggestedColorMode,
+                    mLayoutAttributes.getColorMode());
+        } else {
+            assertEquals("Color mode not default", defaultColorMode,
+                    mLayoutAttributes.getColorMode());
+        }
+
+        if (suggestedDuplexMode != 0 && isInArray(duplexModes, suggestedDuplexMode)) {
+            assertEquals("Duplex mode not as suggested", suggestedDuplexMode,
+                    mLayoutAttributes.getDuplexMode());
+        } else {
+            assertEquals("Duplex mode not default", defaultDuplexMode,
+                    mLayoutAttributes.getDuplexMode());
+        }
+
+        if (suggestedResolution != null
+                && Arrays.asList(resolutions).contains(suggestedResolution)) {
+            assertEquals("Resolution not as suggested", suggestedResolution,
+                    mLayoutAttributes.getResolution());
+        } else {
+            assertEquals("Resolution not default", defaultResolution,
+                    mLayoutAttributes.getResolution());
+        }
+    }
+
+    /**
+     * Test that attributes are as expected if the default attributes match the suggested ones.
+     *
+     * This test sets the default and suggested attributes to the first selection.
+     *
+     * @throws Exception If anything is unexpected
+     */
+    public void testDefaultMatchesSuggested0() throws Exception {
+        //       available     default          suggestion
+        baseTest(              MIN_MARGINS[0],
+                 MEDIA_SIZES,  MEDIA_SIZES[0],  MEDIA_SIZES[0],
+                 COLOR_MODES,  COLOR_MODES[0],  COLOR_MODES[0],
+                 DUPLEX_MODES, DUPLEX_MODES[0], DUPLEX_MODES[0],
+                 RESOLUTIONS,  RESOLUTIONS[0],  RESOLUTIONS[0]);
+    }
+
+    /**
+     * Test that attributes are as expected if the default attributes match the suggested ones.
+     *
+     * This test sets the default and suggested attributes to the second selection.
+     *
+     * @throws Exception If anything is unexpected
+     */
+    public void testDefaultMatchesSuggested1() throws Exception {
+        //       available     default          suggestion
+        baseTest(              MIN_MARGINS[1],
+                 MEDIA_SIZES,  MEDIA_SIZES[1],  MEDIA_SIZES[1],
+                 COLOR_MODES,  COLOR_MODES[1],  COLOR_MODES[1],
+                 DUPLEX_MODES, DUPLEX_MODES[1], DUPLEX_MODES[1],
+                 RESOLUTIONS,  RESOLUTIONS[1],  RESOLUTIONS[1]);
+    }
+
+    /**
+     * Test that attributes are as expected if the default attributes match the suggested ones.
+     *
+     * This test sets the default and suggested attributes to the third selection.
+     *
+     * @throws Exception If anything is unexpected
+     */
+    public void testDefaultMatchesSuggested2() throws Exception {
+        //       available     default          suggestion
+        baseTest(              MIN_MARGINS[2],
+                 MEDIA_SIZES,  MEDIA_SIZES[2],  MEDIA_SIZES[2],
+                 // There are only two color modes, hence pick [1]
+                 COLOR_MODES,  COLOR_MODES[1],  COLOR_MODES[1],
+                 DUPLEX_MODES, DUPLEX_MODES[2], DUPLEX_MODES[2],
+                 RESOLUTIONS,  RESOLUTIONS[2],  RESOLUTIONS[2]);
+    }
+
+    /**
+     * Test that attributes are as expected if the no suggestion is given.
+     *
+     * This test sets the default attributes to the first selection.
+     *
+     * @throws Exception If anything is unexpected
+     */
+    public void testNoSuggestion0() throws Exception {
+        //       available     default          suggestion
+        baseTest(              MIN_MARGINS[0],
+                 MEDIA_SIZES,  MEDIA_SIZES[0],  null,
+                 COLOR_MODES,  COLOR_MODES[0],  0,
+                 DUPLEX_MODES, DUPLEX_MODES[0], 0,
+                 RESOLUTIONS,  RESOLUTIONS[0],  null);
+    }
+
+    /**
+     * Test that attributes are as expected if the no suggestion is given.
+     *
+     * This test sets the default attributes to the second selection.
+     *
+     * @throws Exception If anything is unexpected
+     */
+    public void testNoSuggestion1() throws Exception {
+        //       available     default          suggestion
+        baseTest(              MIN_MARGINS[1],
+                 MEDIA_SIZES,  MEDIA_SIZES[1],  null,
+                 COLOR_MODES,  COLOR_MODES[1],  0,
+                 DUPLEX_MODES, DUPLEX_MODES[1], 0,
+                 RESOLUTIONS,  RESOLUTIONS[1],  null);
+    }
+
+    /**
+     * Test that attributes are as expected if the no suggestion is given.
+     *
+     * This test sets the default attributes to the third selection.
+     *
+     * @throws Exception If anything is unexpected
+     */
+    public void testNoSuggestion2() throws Exception {
+        //       available     default          suggestion
+        baseTest(              MIN_MARGINS[2],
+                 MEDIA_SIZES,  MEDIA_SIZES[2],  null,
+                 // There are only two color modes, hence pick [1]
+                 COLOR_MODES,  COLOR_MODES[1],  0,
+                 DUPLEX_MODES, DUPLEX_MODES[2], 0,
+                 RESOLUTIONS,  RESOLUTIONS[2],  null);
+    }
+
+    /**
+     * Test that attributes are as expected if only the {@link MediaSize} is suggested.
+     *
+     * This test sets the default attributes to the first selection, but the {@link MediaSize} is
+     * suggested to be the second selection.
+     *
+     * @throws Exception If anything is unexpected
+     */
+    public void testMediaSizeSuggestion0() throws Exception {
+        //       available     default          suggestion
+        baseTest(              MIN_MARGINS[0],
+                 MEDIA_SIZES,  MEDIA_SIZES[0],  MEDIA_SIZES[1],
+                 COLOR_MODES,  COLOR_MODES[0],  0,
+                 DUPLEX_MODES, DUPLEX_MODES[0], 0,
+                 RESOLUTIONS,  RESOLUTIONS[0],  null);
+    }
+
+    /**
+     * Test that attributes are as expected if only the {@link MediaSize} is suggested.
+     *
+     * This test sets the default attributes to the second selection, but the {@link MediaSize} is
+     * suggested to be the first selection.
+     *
+     * @throws Exception If anything is unexpected
+     */
+    public void testMediaSizeSuggestion1() throws Exception {
+        //       available     default          suggestion
+        baseTest(              MIN_MARGINS[1],
+                 MEDIA_SIZES,  MEDIA_SIZES[1],  MEDIA_SIZES[0],
+                 COLOR_MODES,  COLOR_MODES[1],  0,
+                 DUPLEX_MODES, DUPLEX_MODES[1], 0,
+                 RESOLUTIONS,  RESOLUTIONS[1],  null);
+    }
+
+    /**
+     * Test that attributes are as expected if only the duplex mode is suggested.
+     *
+     * This test sets the default attributes to the first selection, but the duplex mode is
+     * suggested to be the second selection.
+     *
+     * @throws Exception If anything is unexpected
+     */
+    public void testDuplexModeSuggestion0() throws Exception {
+        //       available     default          suggestion
+        baseTest(              MIN_MARGINS[0],
+                 MEDIA_SIZES,  MEDIA_SIZES[0],  null,
+                 COLOR_MODES,  COLOR_MODES[0],  0,
+                 DUPLEX_MODES, DUPLEX_MODES[0], DUPLEX_MODES[1],
+                 RESOLUTIONS,  RESOLUTIONS[0],  null);
+    }
+
+    /**
+     * Test that attributes are as expected if only the duplex mode is suggested.
+     *
+     * This test sets the default attributes to the second selection, but the duplex mode is
+     * suggested to be the first selection.
+     *
+     * @throws Exception If anything is unexpected
+     */
+    public void testDuplexModeSuggestion1() throws Exception {
+        //       available     default          suggestion
+        baseTest(              MIN_MARGINS[1],
+                 MEDIA_SIZES,  MEDIA_SIZES[1],  null,
+                 COLOR_MODES,  COLOR_MODES[1],  0,
+                 DUPLEX_MODES, DUPLEX_MODES[1], DUPLEX_MODES[0],
+                 RESOLUTIONS,  RESOLUTIONS[1],  null);
+    }
+
+    /**
+     * Test that attributes are as expected if all attributes are suggested and different from the
+     * default attributes.
+     *
+     * @throws Exception If anything is unexpected
+     */
+    public void testSuggestedDifferentFromDefault() throws Exception {
+        //       available     default          suggestion
+        baseTest(              MIN_MARGINS[0],
+                 MEDIA_SIZES,  MEDIA_SIZES[0],  MEDIA_SIZES[1],
+                 COLOR_MODES,  COLOR_MODES[0],  COLOR_MODES[1],
+                 DUPLEX_MODES, DUPLEX_MODES[0], DUPLEX_MODES[1],
+                 RESOLUTIONS,  RESOLUTIONS[0],  RESOLUTIONS[1]);
+    }
+
+    /**
+     * Test that attributes are as expected if all attributes are suggested but all of them are not
+     * supported by the printer.
+     *
+     * @throws Exception If anything is unexpected
+     */
+    public void testUnsupportedSuggested() throws Exception {
+        //       available                               default          suggestion
+        baseTest(                                        MIN_MARGINS[0],
+                 Arrays.copyOfRange(MEDIA_SIZES, 0, 1),  MEDIA_SIZES[0],  MEDIA_SIZES[1],
+                 Arrays.copyOfRange(COLOR_MODES, 0, 1),  COLOR_MODES[0],  COLOR_MODES[1],
+                 Arrays.copyOfRange(DUPLEX_MODES, 0, 1), DUPLEX_MODES[0], DUPLEX_MODES[1],
+                 Arrays.copyOfRange(RESOLUTIONS, 0, 1),  RESOLUTIONS[0],  RESOLUTIONS[1]);
+    }
+
+    /**
+     * Test that negative Margins do not cause issues in the print print spooler. Negative margins
+     * are allowed because of historical reasons.
+     *
+     * @throws Exception If anything is unexpected
+     */
+    public void testNegativeMargins() throws Exception {
+        //       available     default                          suggestion
+        baseTest(              new Margins(-10, -10, -10, -10),
+                 MEDIA_SIZES,  MEDIA_SIZES[1],                  null,
+                 COLOR_MODES,  COLOR_MODES[1],                  0,
+                 DUPLEX_MODES, DUPLEX_MODES[1],                 0,
+                 RESOLUTIONS,  RESOLUTIONS[1],                  null);
+    }
+}
diff --git a/tests/tests/print/src/android/print/cts/PrintDocumentActivity.java b/tests/tests/print/src/android/print/cts/PrintDocumentActivity.java
index 41e7a57..8ba4f8f 100644
--- a/tests/tests/print/src/android/print/cts/PrintDocumentActivity.java
+++ b/tests/tests/print/src/android/print/cts/PrintDocumentActivity.java
@@ -29,5 +29,13 @@
         getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
                 | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
                 | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
+
+        BasePrintTest.onActivityCreateCalled();
+    }
+
+    @Override
+    protected void onDestroy() {
+        BasePrintTest.onActivityDestroyCalled();
+        super.onDestroy();
     }
 }
diff --git a/tests/tests/print/src/android/print/cts/PrintDocumentAdapterContractTest.java b/tests/tests/print/src/android/print/cts/PrintDocumentAdapterContractTest.java
index 9f1e3a5..f171884 100644
--- a/tests/tests/print/src/android/print/cts/PrintDocumentAdapterContractTest.java
+++ b/tests/tests/print/src/android/print/cts/PrintDocumentAdapterContractTest.java
@@ -111,7 +111,7 @@
         print(adapter);
 
         // Wait for write.
-        waitForWriteAdapterCallback();
+        waitForWriteAdapterCallback(1);
 
         // Select the second printer.
         selectPrinter("Second printer");
@@ -122,11 +122,14 @@
         // Click the print button.
         clickPrintButton();
 
+        // Answer the dialog for the print service cloud warning
+        answerPrintServicesWarning(true);
+
         // Wait for finish.
         waitForAdapterFinishCallbackCalled();
 
         // Wait for the session to be destroyed to isolate tests.
-        waitForPrinterDiscoverySessionDestroyCallbackCalled();
+        waitForPrinterDiscoverySessionDestroyCallbackCalled(1);
 
         // Verify the expected calls.
         InOrder inOrder = inOrder(adapter);
@@ -142,6 +145,7 @@
                 .setResolution(new Resolution("PDF resolution", "PDF resolution", 300, 300))
                 .setMinMargins(Margins.NO_MARGINS)
                 .setColorMode(PrintAttributes.COLOR_MODE_COLOR)
+                .setDuplexMode(PrintAttributes.DUPLEX_MODE_NONE)
                 .build();
         verifyLayoutCall(inOrder, adapter, firstOldAttributes, firstNewAttributes, true);
 
@@ -230,7 +234,7 @@
         print(adapter);
 
         // Wait for write.
-        waitForWriteAdapterCallback();
+        waitForWriteAdapterCallback(1);
 
         // Cancel the printing.
         getUiDevice().pressBack(); // wakes up the device.
@@ -240,7 +244,7 @@
         waitForAdapterFinishCallbackCalled();
 
         // Wait for the session to be destroyed to isolate tests.
-        waitForPrinterDiscoverySessionDestroyCallbackCalled();
+        waitForPrinterDiscoverySessionDestroyCallbackCalled(1);
 
         // Verify the expected calls.
         InOrder inOrder = inOrder(adapter);
@@ -256,6 +260,7 @@
                 .setResolution(new Resolution("PDF resolution", "PDF resolution", 300, 300))
                 .setMinMargins(Margins.NO_MARGINS)
                 .setColorMode(PrintAttributes.COLOR_MODE_COLOR)
+                .setDuplexMode(PrintAttributes.DUPLEX_MODE_NONE)
                 .build();
         verifyLayoutCall(inOrder, adapter, firstOldAttributes, firstNewAttributes, true);
 
@@ -325,7 +330,7 @@
         print(adapter);
 
         // Wait for write.
-        waitForWriteAdapterCallback();
+        waitForWriteAdapterCallback(1);
 
         // Open the print options.
         openPrintOptions();
@@ -363,11 +368,14 @@
         // Click the print button.
         clickPrintButton();
 
+        // Answer the dialog for the print service cloud warning
+        answerPrintServicesWarning(true);
+
         // Wait for a finish.
         waitForAdapterFinishCallbackCalled();
 
         // Wait for the session to be destroyed to isolate tests.
-        waitForPrinterDiscoverySessionDestroyCallbackCalled();
+        waitForPrinterDiscoverySessionDestroyCallbackCalled(1);
 
         // Verify the expected calls.
         InOrder inOrder = inOrder(adapter);
@@ -383,6 +391,7 @@
                 .setResolution(new Resolution("PDF resolution", "PDF resolution", 300, 300))
                 .setMinMargins(Margins.NO_MARGINS)
                 .setColorMode(PrintAttributes.COLOR_MODE_COLOR)
+                .setDuplexMode(PrintAttributes.DUPLEX_MODE_NONE)
                 .build();
         verifyLayoutCall(inOrder, adapter, firstOldAttributes, firstNewAttributes, true);
 
@@ -525,7 +534,7 @@
         print(adapter);
 
         // Wait for write.
-        waitForWriteAdapterCallback();
+        waitForWriteAdapterCallback(1);
 
         // Open the print options.
         openPrintOptions();
@@ -552,11 +561,14 @@
         // Click the print button.
         clickPrintButton();
 
+        // Answer the dialog for the print service cloud warning
+        answerPrintServicesWarning(true);
+
         // Wait for a finish.
         waitForAdapterFinishCallbackCalled();
 
         // Wait for the session to be destroyed to isolate tests.
-        waitForPrinterDiscoverySessionDestroyCallbackCalled();
+        waitForPrinterDiscoverySessionDestroyCallbackCalled(1);
 
         // Verify the expected calls.
         InOrder inOrder = inOrder(adapter);
@@ -572,6 +584,7 @@
                 .setResolution(new Resolution("PDF resolution", "PDF resolution", 300, 300))
                 .setMinMargins(Margins.NO_MARGINS)
                 .setColorMode(PrintAttributes.COLOR_MODE_COLOR)
+                .setDuplexMode(PrintAttributes.DUPLEX_MODE_NONE)
                 .build();
         verifyLayoutCall(inOrder, adapter, firstOldAttributes, firstNewAttributes, true);
 
@@ -613,6 +626,7 @@
                 .setResolution(new Resolution("PDF resolution", "PDF resolution", 300, 300))
                 .setMinMargins(new Margins(200, 200, 200, 200))
                 .setColorMode(PrintAttributes.COLOR_MODE_COLOR)
+                .setDuplexMode(PrintAttributes.DUPLEX_MODE_NONE)
                 .build();
         verifyLayoutCall(inOrder, adapter, fourthOldAttributes, fourthNewAttributes, true);
 
@@ -685,7 +699,7 @@
         print(adapter);
 
         // Wait for write.
-        waitForWriteAdapterCallback();
+        waitForWriteAdapterCallback(1);
 
         // Open the print options.
         openPrintOptions();
@@ -699,11 +713,14 @@
         // Click the print button.
         clickPrintButton();
 
+        // Answer the dialog for the print service cloud warning
+        answerPrintServicesWarning(true);
+
         // Wait for a finish.
         waitForAdapterFinishCallbackCalled();
 
         // Wait for the session to be destroyed to isolate tests.
-        waitForPrinterDiscoverySessionDestroyCallbackCalled();
+        waitForPrinterDiscoverySessionDestroyCallbackCalled(1);
 
         // Verify the expected calls.
         InOrder inOrder = inOrder(adapter);
@@ -718,6 +735,7 @@
                 .setMediaSize(MediaSize.NA_LETTER)
                 .setResolution(new Resolution("PDF resolution", "PDF resolution", 300, 300))
                 .setMinMargins(Margins.NO_MARGINS).setColorMode(PrintAttributes.COLOR_MODE_COLOR)
+                .setDuplexMode(PrintAttributes.DUPLEX_MODE_NONE)
                 .build();
         verifyLayoutCall(inOrder, adapter, firstOldAttributes, firstNewAttributes, true);
 
@@ -812,7 +830,7 @@
         print(adapter);
 
         // Wait for write.
-        waitForWriteAdapterCallback();
+        waitForWriteAdapterCallback(1);
 
         // Open the print options.
         openPrintOptions();
@@ -823,11 +841,14 @@
         // Click the print button.
         clickPrintButton();
 
+        // Answer the dialog for the print service cloud warning
+        answerPrintServicesWarning(true);
+
         // Wait for a finish.
         waitForAdapterFinishCallbackCalled();
 
         // Wait for the session to be destroyed to isolate tests.
-        waitForPrinterDiscoverySessionDestroyCallbackCalled();
+        waitForPrinterDiscoverySessionDestroyCallbackCalled(1);
 
         // Verify the expected calls.
         InOrder inOrder = inOrder(adapter);
@@ -842,6 +863,7 @@
                 .setMediaSize(MediaSize.NA_LETTER)
                 .setResolution(new Resolution("PDF resolution", "PDF resolution", 300, 300))
                 .setMinMargins(Margins.NO_MARGINS).setColorMode(PrintAttributes.COLOR_MODE_COLOR)
+                .setDuplexMode(PrintAttributes.DUPLEX_MODE_NONE)
                 .build();
         verifyLayoutCall(inOrder, adapter, firstOldAttributes, firstNewAttributes, true);
 
@@ -918,7 +940,7 @@
         print(adapter);
 
         // Wait for write.
-        waitForWriteAdapterCallback();
+        waitForWriteAdapterCallback(1);
 
         // Open the print options.
         openPrintOptions();
@@ -932,11 +954,14 @@
         // Click the print button.
         clickPrintButton();
 
+        // Answer the dialog for the print service cloud warning
+        answerPrintServicesWarning(true);
+
         // Wait for a finish.
         waitForAdapterFinishCallbackCalled();
 
         // Wait for the session to be destroyed to isolate tests.
-        waitForPrinterDiscoverySessionDestroyCallbackCalled();
+        waitForPrinterDiscoverySessionDestroyCallbackCalled(1);
 
         // Verify the expected calls.
         InOrder inOrder = inOrder(adapter);
@@ -951,6 +976,7 @@
                 .setMediaSize(MediaSize.NA_LETTER)
                 .setResolution(new Resolution("PDF resolution", "PDF resolution", 300, 300))
                 .setMinMargins(Margins.NO_MARGINS).setColorMode(PrintAttributes.COLOR_MODE_COLOR)
+                .setDuplexMode(PrintAttributes.DUPLEX_MODE_NONE)
                 .build();
         verifyLayoutCall(inOrder, adapter, firstOldAttributes, firstNewAttributes, true);
 
@@ -1043,7 +1069,7 @@
         waitForAdapterFinishCallbackCalled();
 
         // Wait for the session to be destroyed to isolate tests.
-        waitForPrinterDiscoverySessionDestroyCallbackCalled();
+        waitForPrinterDiscoverySessionDestroyCallbackCalled(1);
 
         // Verify the expected calls.
         InOrder inOrder = inOrder(adapter);
@@ -1058,6 +1084,7 @@
                 .setMediaSize(MediaSize.NA_LETTER)
                 .setResolution(new Resolution("PDF resolution", "PDF resolution", 300, 300))
                 .setMinMargins(Margins.NO_MARGINS).setColorMode(PrintAttributes.COLOR_MODE_COLOR)
+                .setDuplexMode(PrintAttributes.DUPLEX_MODE_NONE)
                 .build();
         verifyLayoutCall(inOrder, adapter, firstOldAttributes, firstNewAttributes, true);
 
@@ -1124,7 +1151,7 @@
         print(adapter);
 
         // Wait for write.
-        waitForWriteAdapterCallback();
+        waitForWriteAdapterCallback(1);
 
         // Cancel printing.
         getUiDevice().pressBack(); // wakes up the device.
@@ -1137,7 +1164,7 @@
         waitForAdapterFinishCallbackCalled();
 
         // Wait for the session to be destroyed to isolate tests.
-        waitForPrinterDiscoverySessionDestroyCallbackCalled();
+        waitForPrinterDiscoverySessionDestroyCallbackCalled(1);
 
         // Verify the expected calls.
         InOrder inOrder = inOrder(adapter);
@@ -1152,6 +1179,7 @@
                 .setMediaSize(MediaSize.NA_LETTER)
                 .setResolution(new Resolution("PDF resolution", "PDF resolution", 300, 300))
                 .setMinMargins(Margins.NO_MARGINS).setColorMode(PrintAttributes.COLOR_MODE_COLOR)
+                .setDuplexMode(PrintAttributes.DUPLEX_MODE_NONE)
                 .build();
         verifyLayoutCall(inOrder, adapter, firstOldAttributes, firstNewAttributes, true);
 
@@ -1209,7 +1237,7 @@
         waitForAdapterFinishCallbackCalled();
 
         // Wait for the session to be destroyed to isolate tests.
-        waitForPrinterDiscoverySessionDestroyCallbackCalled();
+        waitForPrinterDiscoverySessionDestroyCallbackCalled(1);
 
         // Verify the expected calls.
         InOrder inOrder = inOrder(adapter);
@@ -1224,6 +1252,7 @@
                 .setMediaSize(MediaSize.NA_LETTER)
                 .setResolution(new Resolution("PDF resolution", "PDF resolution", 300, 300))
                 .setMinMargins(Margins.NO_MARGINS).setColorMode(PrintAttributes.COLOR_MODE_COLOR)
+                .setDuplexMode(PrintAttributes.DUPLEX_MODE_NONE)
                 .build();
         verifyLayoutCall(inOrder, adapter, firstOldAttributes, firstNewAttributes, true);
 
@@ -1281,7 +1310,7 @@
         print(adapter);
 
         // Wait for write.
-        waitForWriteAdapterCallback();
+        waitForWriteAdapterCallback(1);
 
         // Cancel printing.
         getUiDevice().pressBack(); // wakes up the device.
@@ -1291,7 +1320,7 @@
         waitForAdapterFinishCallbackCalled();
 
         // Wait for the session to be destroyed to isolate tests.
-        waitForPrinterDiscoverySessionDestroyCallbackCalled();
+        waitForPrinterDiscoverySessionDestroyCallbackCalled(1);
 
         // Verify the expected calls.
         InOrder inOrder = inOrder(adapter);
@@ -1306,6 +1335,7 @@
                 .setMediaSize(MediaSize.NA_LETTER)
                 .setResolution(new Resolution("PDF resolution", "PDF resolution", 300, 300))
                 .setMinMargins(Margins.NO_MARGINS).setColorMode(PrintAttributes.COLOR_MODE_COLOR)
+                .setDuplexMode(PrintAttributes.DUPLEX_MODE_NONE)
                 .build();
         verifyLayoutCall(inOrder, adapter, firstOldAttributes, firstNewAttributes, true);
 
@@ -1350,7 +1380,6 @@
                 Object[] args = invocation.getArguments();
                 ParcelFileDescriptor fd = (ParcelFileDescriptor) args[1];
                 WriteResultCallback callback = (WriteResultCallback) args[3];
-                PageRange[] pages = (PageRange[]) args[0];
                 writeBlankPages(printAttributes[0], fd, Integer.MAX_VALUE, Integer.MAX_VALUE);
                 fd.close();
                 // Write wrong pages.
@@ -1373,7 +1402,7 @@
         print(adapter);
 
         // Wait for write.
-        waitForWriteAdapterCallback();
+        waitForWriteAdapterCallback(1);
 
         // Cancel printing.
         getUiDevice().pressBack(); // wakes up the device.
@@ -1383,7 +1412,7 @@
         waitForAdapterFinishCallbackCalled();
 
         // Wait for the session to be destroyed to isolate tests.
-        waitForPrinterDiscoverySessionDestroyCallbackCalled();
+        waitForPrinterDiscoverySessionDestroyCallbackCalled(1);
 
         // Verify the expected calls.
         InOrder inOrder = inOrder(adapter);
@@ -1398,6 +1427,7 @@
                 .setMediaSize(MediaSize.NA_LETTER)
                 .setResolution(new Resolution("PDF resolution", "PDF resolution", 300, 300))
                 .setMinMargins(Margins.NO_MARGINS).setColorMode(PrintAttributes.COLOR_MODE_COLOR)
+                .setDuplexMode(PrintAttributes.DUPLEX_MODE_NONE)
                 .build();
         verifyLayoutCall(inOrder, adapter, firstOldAttributes, firstNewAttributes, true);
 
@@ -1454,7 +1484,7 @@
         waitForAdapterFinishCallbackCalled();
 
         // Wait for the session to be destroyed to isolate tests.
-        waitForPrinterDiscoverySessionDestroyCallbackCalled();
+        waitForPrinterDiscoverySessionDestroyCallbackCalled(1);
 
         // Verify the expected calls.
         InOrder inOrder = inOrder(adapter);
@@ -1469,6 +1499,7 @@
                 .setMediaSize(MediaSize.NA_LETTER)
                 .setResolution(new Resolution("PDF resolution", "PDF resolution", 300, 300))
                 .setMinMargins(Margins.NO_MARGINS).setColorMode(PrintAttributes.COLOR_MODE_COLOR)
+                .setDuplexMode(PrintAttributes.DUPLEX_MODE_NONE)
                 .build();
         verifyLayoutCall(inOrder, adapter, firstOldAttributes, firstNewAttributes, true);
 
@@ -1523,7 +1554,7 @@
         print(adapter);
 
         // Wait for write.
-        waitForWriteAdapterCallback();
+        waitForWriteAdapterCallback(1);
 
         // Cancel printing.
         getUiDevice().pressBack(); // wakes up the device.
@@ -1533,7 +1564,7 @@
         waitForAdapterFinishCallbackCalled();
 
         // Wait for the session to be destroyed to isolate tests.
-        waitForPrinterDiscoverySessionDestroyCallbackCalled();
+        waitForPrinterDiscoverySessionDestroyCallbackCalled(1);
 
         // Verify the expected calls.
         InOrder inOrder = inOrder(adapter);
@@ -1548,6 +1579,7 @@
                 .setMediaSize(MediaSize.NA_LETTER)
                 .setResolution(new Resolution("PDF resolution", "PDF resolution", 300, 300))
                 .setMinMargins(Margins.NO_MARGINS).setColorMode(PrintAttributes.COLOR_MODE_COLOR)
+                .setDuplexMode(PrintAttributes.DUPLEX_MODE_NONE)
                 .build();
         verifyLayoutCall(inOrder, adapter, firstOldAttributes, firstNewAttributes, true);
 
@@ -1563,6 +1595,224 @@
         verifyNoMoreInteractions(adapter);
     }
 
+    /**
+     * Pretend to have written two pages, but only actually write one page
+     *
+     * @throws Exception If anything is unexpected
+     */
+    public void testNotEnoughPages() throws Exception {
+        if (!supportsPrinting()) {
+            return;
+        }
+
+        FirstPrintService.setCallbacks(createFirstMockPrintServiceCallbacks());
+        SecondPrintService.setCallbacks(createSecondMockPrintServiceCallbacks());
+
+        final PrintAttributes[] printAttributes = new PrintAttributes[1];
+
+        final PrintDocumentAdapter adapter = createMockPrintDocumentAdapter(
+                new Answer<Void>() {
+                    @Override
+                    public Void answer(InvocationOnMock invocation) throws Throwable {
+                        printAttributes[0] = (PrintAttributes) invocation.getArguments()[1];
+                        LayoutResultCallback callback = (LayoutResultCallback) invocation
+                                .getArguments()[3];
+
+                        // Lay out two pages
+                        PrintDocumentInfo info = new PrintDocumentInfo.Builder(PRINT_JOB_NAME)
+                                .setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT)
+                                .setPageCount(2)
+                                .build();
+                        callback.onLayoutFinished(info, true);
+                        return null;
+                    }
+                }, new Answer<Void>() {
+                    @Override
+                    public Void answer(InvocationOnMock invocation) throws Throwable {
+                        Object[] args = invocation.getArguments();
+                        PageRange[] pages = (PageRange[]) args[0];
+                        ParcelFileDescriptor fd = (ParcelFileDescriptor) args[1];
+                        WriteResultCallback callback = (WriteResultCallback) args[3];
+
+                        // Write only one pages
+                        writeBlankPages(printAttributes[0], fd, 0, 0);
+                        fd.close();
+
+                        // Break the contract and report that two pages were written
+                        callback.onWriteFinished(pages);
+                        onWriteCalled();
+                        return null;
+                    }
+                }, new Answer<Void>() {
+                    @Override
+                    public Void answer(InvocationOnMock invocation) throws Throwable {
+                        onFinishCalled();
+                        return null;
+                    }
+                });
+
+        print(adapter);
+        waitForWriteAdapterCallback(1);
+        selectPrinter("First printer");
+        clickPrintButton();
+
+        // Answer the dialog for the print service cloud warning
+        answerPrintServicesWarning(true);
+
+        waitForAdapterFinishCallbackCalled();
+
+        // Wait for the session to be destroyed to isolate tests.
+        waitForPrinterDiscoverySessionDestroyCallbackCalled(1);
+    }
+
+    /**
+     * Executes a print process with a given print document info
+     *
+     * @param info The print document info to declare on layout
+     */
+    private void printDocumentInfoBaseTest(final PrintDocumentInfo info) throws Exception {
+        if (!supportsPrinting()) {
+            return;
+        }
+        // Configure the print services.
+        FirstPrintService.setCallbacks(createFirstMockPrintServiceCallbacks());
+        SecondPrintService.setCallbacks(createSecondMockPrintServiceCallbacks());
+
+        final PrintAttributes[] printAttributes = new PrintAttributes[1];
+
+        // Create a mock print adapter.
+        final PrintDocumentAdapter adapter = createMockPrintDocumentAdapter(
+                new Answer<Void>() {
+                    @Override
+                    public Void answer(InvocationOnMock invocation) throws Throwable {
+                        printAttributes[0] = (PrintAttributes) invocation.getArguments()[1];
+                        LayoutResultCallback callback = (LayoutResultCallback) invocation.getArguments()[3];
+                        callback.onLayoutFinished(info, false);
+                        // Mark layout was called.
+                        onLayoutCalled();
+                        return null;
+                    }
+                }, new Answer<Void>() {
+                    @Override
+                    public Void answer(InvocationOnMock invocation) throws Throwable {
+                        Object[] args = invocation.getArguments();
+                        PageRange[] pages = (PageRange[]) args[0];
+                        ParcelFileDescriptor fd = (ParcelFileDescriptor) args[1];
+                        WriteResultCallback callback = (WriteResultCallback) args[3];
+                        writeBlankPages(printAttributes[0], fd, 0, 1);
+                        fd.close();
+                        callback.onWriteFinished(pages);
+                        // Mark write was called.
+                        onWriteCalled();
+                        return null;
+                    }
+                }, new Answer<Void>() {
+                    @Override
+                    public Void answer(InvocationOnMock invocation) throws Throwable {
+                        // Mark finish was called.
+                        onFinishCalled();
+                        return null;
+                    }
+                });
+
+        // Start printing.
+        print(adapter);
+
+        // Select the second printer.
+        selectPrinter("Second printer");
+
+        // Wait for layout.
+        waitForLayoutAdapterCallbackCount(2);
+
+        // Click the print button.
+        clickPrintButton();
+
+        // Answer the dialog for the print service cloud warning
+        answerPrintServicesWarning(true);
+
+        // Wait for the session to be destroyed to isolate tests.
+        waitForPrinterDiscoverySessionDestroyCallbackCalled(1);
+    }
+
+    /**
+     * Test that the default values of the PrintDocumentInfo are fine.
+     *
+     * @throws Exception If anything unexpected happens
+     */
+    public void testDocumentInfoNothingSet() throws Exception {
+        printDocumentInfoBaseTest((new PrintDocumentInfo.Builder(PRINT_JOB_NAME)).build());
+    }
+
+    /**
+     * Test that a unknown page count is handled correctly.
+     *
+     * @throws Exception If anything unexpected happens
+     */
+    public void testDocumentInfoUnknownPageCount() throws Exception {
+        printDocumentInfoBaseTest((new PrintDocumentInfo.Builder(PRINT_JOB_NAME))
+                .setPageCount(PrintDocumentInfo.PAGE_COUNT_UNKNOWN).build());
+    }
+
+    /**
+     * Test that zero page count is handled correctly.
+     *
+     * @throws Exception If anything unexpected happens
+     */
+    public void testDocumentInfoZeroPageCount() throws Exception {
+        printDocumentInfoBaseTest((new PrintDocumentInfo.Builder(PRINT_JOB_NAME))
+                .setPageCount(0).build());
+    }
+
+    /**
+     * Test that page count one is handled correctly. (The document has two pages)
+     *
+     * @throws Exception If anything unexpected happens
+     */
+    public void testDocumentInfoOnePageCount() throws Exception {
+        printDocumentInfoBaseTest((new PrintDocumentInfo.Builder(PRINT_JOB_NAME))
+                .setPageCount(1).build());
+    }
+
+    /**
+     * Test that page count three is handled correctly. (The document has two pages)
+     *
+     * @throws Exception If anything unexpected happens
+     */
+    public void testDocumentInfoThreePageCount() throws Exception {
+        printDocumentInfoBaseTest((new PrintDocumentInfo.Builder(PRINT_JOB_NAME))
+                .setPageCount(3).build());
+    }
+
+    /**
+     * Test that a photo content type is handled correctly.
+     *
+     * @throws Exception If anything unexpected happens
+     */
+    public void testDocumentInfoContentTypePhoto() throws Exception {
+        printDocumentInfoBaseTest((new PrintDocumentInfo.Builder(PRINT_JOB_NAME))
+                .setContentType(PrintDocumentInfo.CONTENT_TYPE_PHOTO).build());
+    }
+
+    /**
+     * Test that a unknown content type is handled correctly.
+     *
+     * @throws Exception If anything unexpected happens
+     */
+    public void testDocumentInfoContentTypeUnknown() throws Exception {
+        printDocumentInfoBaseTest((new PrintDocumentInfo.Builder(PRINT_JOB_NAME))
+                .setContentType(PrintDocumentInfo.CONTENT_TYPE_UNKNOWN).build());
+    }
+
+    /**
+     * Test that a undefined content type is handled correctly.
+     *
+     * @throws Exception If anything unexpected happens
+     */
+    public void testDocumentInfoContentTypeNonDefined() throws Exception {
+        printDocumentInfoBaseTest((new PrintDocumentInfo.Builder(PRINT_JOB_NAME))
+                .setContentType(-23).build());
+    }
+
     private PrintServiceCallbacks createFirstMockPrintServiceCallbacks() {
         final PrinterDiscoverySessionCallbacks callbacks =
                 createMockPrinterDiscoverySessionCallbacks(new Answer<Void>() {
@@ -1636,7 +1886,7 @@
                 }
                 return null;
             }
-        }, null, null, null, null, new Answer<Void>() {
+        }, null, null, null, null, null, new Answer<Void>() {
                 @Override
                 public Void answer(InvocationOnMock invocation) throws Throwable {
                     // Take a note onDestroy was called.
diff --git a/tests/tests/print/src/android/print/cts/PrintJobTest.java b/tests/tests/print/src/android/print/cts/PrintJobTest.java
new file mode 100644
index 0000000..2dc3a9f
--- /dev/null
+++ b/tests/tests/print/src/android/print/cts/PrintJobTest.java
@@ -0,0 +1,679 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.print.cts;
+
+import android.os.ParcelFileDescriptor;
+import android.print.PageRange;
+import android.print.PrintAttributes;
+import android.print.PrintAttributes.Margins;
+import android.print.PrintAttributes.MediaSize;
+import android.print.PrintAttributes.Resolution;
+import android.print.PrintDocumentAdapter;
+import android.print.PrintDocumentAdapter.LayoutResultCallback;
+import android.print.PrintDocumentAdapter.WriteResultCallback;
+import android.print.PrintDocumentInfo;
+import android.print.PrintJobInfo;
+import android.print.PrinterCapabilitiesInfo;
+import android.print.PrinterId;
+import android.print.PrinterInfo;
+import android.print.cts.services.CustomPrintOptionsActivity;
+import android.print.cts.services.FirstPrintService;
+import android.print.cts.services.PrintServiceCallbacks;
+import android.print.cts.services.PrinterDiscoverySessionCallbacks;
+import android.print.cts.services.SecondPrintService;
+import android.print.cts.services.StubbablePrinterDiscoverySession;
+import android.printservice.PrintJob;
+import android.support.test.uiautomator.UiObject;
+import android.support.test.uiautomator.UiSelector;
+import android.util.Log;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+import java.util.ArrayList;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertNull;
+import static junit.framework.Assert.assertTrue;
+import static junit.framework.Assert.assertFalse;
+
+
+/**
+ * Tests all possible states of print jobs.
+ */
+public class PrintJobTest extends BasePrintTest {
+    private static final String LOG_TAG = "PrintJobTest";
+
+    private static final String PRINTER_NAME = "TestPrinter";
+
+    private final static String VALID_NULL_KEY = "validNullKey";
+    private final static String VALID_STRING_KEY = "validStringKey";
+    private final static String STRING_VALUE = "string value";
+    private final static String INVALID_STRING_KEY = "invalidStringKey";
+    private final static String VALID_INT_KEY = "validIntKey";
+    private final static int INT_VALUE = 23;
+    private final static String INVALID_INT_KEY = "invalidIntKey";
+
+    private final boolean testSuccess[] = new boolean[1];
+
+    /** The printer discovery session used in this test */
+    private static StubbablePrinterDiscoverySession mDiscoverySession;
+
+    /**
+     * Create a mock {@link PrintDocumentAdapter} that provides one empty page.
+     *
+     * @return The mock adapter
+     */
+    private PrintDocumentAdapter createMockPrintDocumentAdapter() {
+        final PrintAttributes[] printAttributes = new PrintAttributes[1];
+
+        return createMockPrintDocumentAdapter(
+                new Answer<Void>() {
+                    @Override
+                    public Void answer(InvocationOnMock invocation) throws Throwable {
+                        printAttributes[0] = (PrintAttributes) invocation.getArguments()[1];
+                        LayoutResultCallback callback = (LayoutResultCallback) invocation
+                                .getArguments()[3];
+
+                        PrintDocumentInfo info = new PrintDocumentInfo.Builder(PRINT_JOB_NAME)
+                                .setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT)
+                                .setPageCount(1)
+                                .build();
+
+                        callback.onLayoutFinished(info, false);
+                        return null;
+                    }
+                }, new Answer<Void>() {
+                    @Override
+                    public Void answer(InvocationOnMock invocation) throws Throwable {
+                        Object[] args = invocation.getArguments();
+                        PageRange[] pages = (PageRange[]) args[0];
+                        ParcelFileDescriptor fd = (ParcelFileDescriptor) args[1];
+                        WriteResultCallback callback = (WriteResultCallback) args[3];
+
+                        writeBlankPages(printAttributes[0], fd, pages[0].getStart(),
+                                pages[0].getEnd());
+                        fd.close();
+                        callback.onWriteFinished(pages);
+                        return null;
+                    }
+                }, new Answer<Void>() {
+                    @Override
+                    public Void answer(InvocationOnMock invocation) throws Throwable {
+                        return null;
+                    }
+                });
+    }
+
+    /**
+     * Create a mock {@link PrinterDiscoverySessionCallbacks} that discovers a simple test printer.
+     *
+     * @return The mock session callbacks
+     */
+    private PrinterDiscoverySessionCallbacks createFirstMockPrinterDiscoverySessionCallbacks() {
+        return createMockPrinterDiscoverySessionCallbacks(new Answer<Void>() {
+            @Override
+            public Void answer(InvocationOnMock invocation) {
+                // Get the session.
+                mDiscoverySession = ((PrinterDiscoverySessionCallbacks) invocation.getMock())
+                        .getSession();
+
+                if (mDiscoverySession.getPrinters().isEmpty()) {
+                    PrinterId printerId =
+                            mDiscoverySession.getService().generatePrinterId(PRINTER_NAME);
+                    PrinterInfo.Builder printer = new PrinterInfo.Builder(
+                            mDiscoverySession.getService().generatePrinterId(PRINTER_NAME),
+                            PRINTER_NAME, PrinterInfo.STATUS_IDLE);
+
+                    printer.setCapabilities(new PrinterCapabilitiesInfo.Builder(printerId)
+                            .addMediaSize(MediaSize.ISO_A4, true)
+                            .addResolution(new Resolution("300x300", "300dpi", 300, 300), true)
+                            .setColorModes(PrintAttributes.COLOR_MODE_COLOR,
+                                    PrintAttributes.COLOR_MODE_COLOR)
+                            .setMinMargins(new Margins(0, 0, 0, 0)).build());
+
+                    ArrayList<PrinterInfo> printers = new ArrayList<>(1);
+                    printers.add(printer.build());
+
+                    mDiscoverySession.addPrinters(printers);
+                }
+                return null;
+            }
+        }, null, null, new Answer<Void>() {
+            @Override
+            public Void answer(InvocationOnMock invocation) throws Throwable {
+                return null;
+            }
+        }, null, null, new Answer<Void>() {
+            @Override
+            public Void answer(InvocationOnMock invocation) throws Throwable {
+                // Take a note onDestroy was called.
+                onPrinterDiscoverySessionDestroyCalled();
+                return null;
+            }
+        });
+    }
+
+    private interface PrintJobTestFn {
+        void onPrintJobQueued(PrintJob printJob) throws Exception;
+    }
+
+    /**
+     * Create mock service callback for a session. Once the job is queued the test function is
+     * called.
+     *
+     * @param sessionCallbacks The callbacks of the session
+     * @param printJobTest test function to call
+     */
+    private PrintServiceCallbacks createFirstMockPrinterServiceCallbacks(
+            final PrinterDiscoverySessionCallbacks sessionCallbacks,
+            final PrintJobTestFn printJobTest) {
+        return createMockPrintServiceCallbacks(
+                new Answer<PrinterDiscoverySessionCallbacks>() {
+                    @Override
+                    public PrinterDiscoverySessionCallbacks answer(InvocationOnMock invocation) {
+                        return sessionCallbacks;
+                    }
+                }, new Answer<Void>() {
+                    @Override
+                    public Void answer(InvocationOnMock invocation) {
+                        PrintJob printJob = (PrintJob) invocation.getArguments()[0];
+
+                        try {
+                            printJobTest.onPrintJobQueued(printJob);
+                            testSuccess[0] = true;
+                        } catch (Exception e) {
+                            Log.e(LOG_TAG, "Test function failed", e);
+                        }
+
+                        onPrintJobQueuedCalled();
+
+                        return null;
+                    }
+                }, null);
+    }
+
+    /**
+     * Make sure that a runnable eventually finishes without throwing a exception.
+     *
+     * @param r The runnable to run.
+     */
+    private static void eventually(Runnable r) {
+        final long TIMEOUT_MILLS = 5000;
+        long start = System.currentTimeMillis();
+
+        while (true) {
+            try {
+                r.run();
+                break;
+            } catch (Exception e) {
+                if (System.currentTimeMillis() - start < TIMEOUT_MILLS) {
+                    Log.e(LOG_TAG, "Ignoring exception as we know that the print spooler does " +
+                            "not guarantee to process commands in order", e);
+                    try {
+                        Thread.sleep(100);
+                    } catch (InterruptedException e1) {
+                        Log.e(LOG_TAG, "Interrupted", e);
+                    }
+                } else {
+                    throw e;
+                }
+            }
+        }
+    }
+
+    /**
+     * Base test for the print job tests. Starts a print job and executes a testFn once the job is
+     * queued.
+     *
+     * @throws Exception If anything is unexpected.
+     */
+    private void baseTest(PrintJobTestFn testFn, int testCaseNum)
+            throws Exception {
+        if (!supportsPrinting()) {
+            return;
+        }
+
+        testSuccess[0] = false;
+
+        // Create the session of the printers that we will be checking.
+        PrinterDiscoverySessionCallbacks sessionCallbacks
+                = createFirstMockPrinterDiscoverySessionCallbacks();
+
+        // Create the service callbacks for the first print service.
+        PrintServiceCallbacks serviceCallbacks = createFirstMockPrinterServiceCallbacks(
+                sessionCallbacks, testFn);
+
+        // Configure the print services.
+        FirstPrintService.setCallbacks(serviceCallbacks);
+
+        // We don't use the second service, but we have to still configure it
+        SecondPrintService.setCallbacks(createMockPrintServiceCallbacks(null, null, null));
+
+        // Create a print adapter that respects the print contract.
+        PrintDocumentAdapter adapter = createMockPrintDocumentAdapter();
+
+        // Start printing.
+        print(adapter);
+
+        if (testCaseNum == 0) {
+            selectPrinter(PRINTER_NAME);
+        }
+
+        clickPrintButton();
+
+        if (testCaseNum == 0) {
+            answerPrintServicesWarning(true);
+        }
+
+        // Wait for print job to be queued
+        waitForServiceOnPrintJobQueuedCallbackCalled(testCaseNum + 1);
+
+        // Wait for discovery session to be destroyed to isolate tests from each other
+        waitForPrinterDiscoverySessionDestroyCallbackCalled(1);
+
+        if (!testSuccess[0]) {
+            throw new Exception("Did not succeed");
+        }
+    }
+
+    private static boolean setState(PrintJob job, int state) {
+        switch (state) {
+            case PrintJobInfo.STATE_QUEUED:
+                // queue cannot be set, but is set at the beginning
+                return job.isQueued();
+            case PrintJobInfo.STATE_STARTED:
+                return job.start();
+            case PrintJobInfo.STATE_BLOCKED:
+                return job.block(null);
+            case PrintJobInfo.STATE_COMPLETED:
+                return job.complete();
+            case PrintJobInfo.STATE_FAILED:
+                return job.fail(null);
+            case PrintJobInfo.STATE_CANCELED:
+                return job.cancel();
+            default:
+                // not reached
+                throw new IllegalArgumentException("Cannot switch to " + state);
+        }
+    }
+
+    private static boolean isStateTransitionAllowed(int before, int after) {
+        switch (before) {
+            case PrintJobInfo.STATE_QUEUED:
+                switch (after) {
+                    case PrintJobInfo.STATE_QUEUED:
+                        // queued is not actually set, see setState
+                    case PrintJobInfo.STATE_STARTED:
+                    case PrintJobInfo.STATE_FAILED:
+                    case PrintJobInfo.STATE_CANCELED:
+                        return true;
+                    default:
+                        return false;
+                }
+            case PrintJobInfo.STATE_STARTED:
+                switch (after) {
+                    case PrintJobInfo.STATE_QUEUED:
+                    case PrintJobInfo.STATE_STARTED:
+                        return false;
+                    default:
+                        return true;
+                }
+            case PrintJobInfo.STATE_BLOCKED:
+                switch (after) {
+                    case PrintJobInfo.STATE_STARTED:
+                        // blocked -> started == restart
+                    case PrintJobInfo.STATE_FAILED:
+                    case PrintJobInfo.STATE_CANCELED:
+                        return true;
+                    default:
+                        return false;
+                }
+            case PrintJobInfo.STATE_COMPLETED:
+                return false;
+            case PrintJobInfo.STATE_FAILED:
+                return false;
+            case PrintJobInfo.STATE_CANCELED:
+                return false;
+            default:
+                // not reached
+                throw new IllegalArgumentException("Cannot switch from " + before);
+        }
+    }
+
+    private static void checkState(PrintJob job, int state) {
+        eventually(() -> assertEquals(state, job.getInfo().getState()));
+        switch (state) {
+            case PrintJobInfo.STATE_QUEUED:
+                eventually(() -> assertTrue(job.isQueued()));
+                break;
+            case PrintJobInfo.STATE_STARTED:
+                eventually(() -> assertTrue(job.isStarted()));
+                break;
+            case PrintJobInfo.STATE_BLOCKED:
+                eventually(() -> assertTrue(job.isBlocked()));
+                break;
+            case PrintJobInfo.STATE_COMPLETED:
+                eventually(() -> assertTrue(job.isCompleted()));
+                break;
+            case PrintJobInfo.STATE_FAILED:
+                eventually(() -> assertTrue(job.isFailed()));
+                break;
+            case PrintJobInfo.STATE_CANCELED:
+                eventually(() -> assertTrue(job.isCancelled()));
+                break;
+            default:
+                // not reached
+                throw new IllegalArgumentException("Cannot check " + state);
+        }
+    }
+
+    public void testStateTransitions() throws Exception {
+        int states[] = new int[] { PrintJobInfo.STATE_QUEUED,
+                PrintJobInfo.STATE_STARTED,
+                PrintJobInfo.STATE_BLOCKED,
+                PrintJobInfo.STATE_COMPLETED,
+                PrintJobInfo.STATE_FAILED,
+                PrintJobInfo.STATE_CANCELED
+        };
+
+        final boolean knownFailures[][] = new boolean[8][8];
+
+        int testCaseNum = 0;
+
+        for (final int state1 : states) {
+            for (final int state2 : states) {
+                for (final int state3 : states) {
+                    // No need to test the same non-transitions twice
+                    if (state1 == state2 && state2 == state3) {
+                        continue;
+                    }
+
+                    // No need to repeat what previously failed
+                    if (knownFailures[state1][state2]
+                            || knownFailures[state2][state3]) {
+                        continue;
+                    }
+
+                    // QUEUED does not actually set a state, see setState
+                    if (state1 == PrintJobInfo.STATE_QUEUED) {
+                        continue;
+                    }
+
+                    Log.i(LOG_TAG, "Test " + state1 + " -> " + state2 + " -> " + state3);
+
+                    baseTest(new PrintJobTestFn() {
+                        @Override
+                        public void onPrintJobQueued(PrintJob printJob) throws Exception {
+                            knownFailures[PrintJobInfo.STATE_QUEUED][state1] = true;
+
+                            boolean success = setState(printJob, state1);
+                            assertEquals(isStateTransitionAllowed(PrintJobInfo.STATE_QUEUED,
+                                    state1), success);
+                            if (!success) {
+                                return;
+                            }
+                            checkState(printJob, state1);
+
+                            knownFailures[PrintJobInfo.STATE_QUEUED][state1] = false;
+
+                            knownFailures[state1][state2] = true;
+
+                            success = setState(printJob, state2);
+                            assertEquals(isStateTransitionAllowed(state1, state2), success);
+                            if (!success) {
+                                return;
+                            }
+                            checkState(printJob, state2);
+
+                            knownFailures[state1][state2] = false;
+
+                            knownFailures[state2][state3] = true;
+
+                            success = setState(printJob, state3);
+                            assertEquals(isStateTransitionAllowed(state2, state3), success);
+                            if (!success) {
+                                return;
+                            }
+                            checkState(printJob, state3);
+
+                            knownFailures[state2][state3] = false;
+                        }
+                    }, testCaseNum);
+
+                    testCaseNum++;
+                }
+            }
+        }
+    }
+
+    public void testBlockWithReason() throws Exception {
+        baseTest(new PrintJobTestFn() {
+            @Override
+            public void onPrintJobQueued(PrintJob printJob) throws Exception {
+                printJob.start();
+                checkState(printJob, PrintJobInfo.STATE_STARTED);
+
+                printJob.setStatus(R.string.testStr1);
+                eventually(() -> assertEquals(getActivity().getString(R.string.testStr1),
+                        printJob.getInfo().getStatus(getActivity().getPackageManager())));
+
+                boolean success = printJob.block("test reason");
+                assertTrue(success);
+                checkState(printJob, PrintJobInfo.STATE_BLOCKED);
+                eventually(() -> assertEquals("test reason",
+                        printJob.getInfo().getStatus(getActivity().getPackageManager())));
+
+                success = printJob.block("another reason");
+                assertFalse(success);
+                checkState(printJob, PrintJobInfo.STATE_BLOCKED);
+                eventually(() -> assertEquals("test reason",
+                        printJob.getInfo().getStatus(getActivity().getPackageManager())));
+
+                printJob.setStatus(R.string.testStr2);
+                eventually(() -> assertEquals(getActivity().getString(R.string.testStr2),
+                        printJob.getInfo().getStatus(getActivity().getPackageManager())));
+            }
+        }, 0);
+    }
+
+    public void testFailWithReason() throws Exception {
+        baseTest(new PrintJobTestFn() {
+            @Override
+            public void onPrintJobQueued(PrintJob printJob) throws Exception {
+                printJob.start();
+                checkState(printJob, PrintJobInfo.STATE_STARTED);
+
+                boolean success = printJob.fail("test reason");
+                assertTrue(success);
+                checkState(printJob, PrintJobInfo.STATE_FAILED);
+                eventually(() -> assertEquals("test reason",
+                        printJob.getInfo().getStatus(getActivity().getPackageManager())));
+
+                success = printJob.fail("another reason");
+                assertFalse(success);
+                checkState(printJob, PrintJobInfo.STATE_FAILED);
+                eventually(() -> assertEquals("test reason",
+                        printJob.getInfo().getStatus(getActivity().getPackageManager())));
+            }
+        }, 0);
+    }
+
+    public void testTag() throws Exception {
+        baseTest(new PrintJobTestFn() {
+            @Override
+            public void onPrintJobQueued(PrintJob printJob) throws Exception {
+                // Default value should be null
+                assertNull(printJob.getTag());
+
+                printJob.setTag("testTag");
+                eventually(() -> assertEquals("testTag", printJob.getTag()));
+
+                printJob.setTag(null);
+                eventually(() -> assertNull(printJob.getTag()));
+            }
+        }, 0);
+    }
+
+    public void testAdvancedOption() throws Exception {
+        if (!supportsPrinting()) {
+            return;
+        }
+
+        testSuccess[0] = false;
+
+        // Create the session of the printers that we will be checking.
+        PrinterDiscoverySessionCallbacks sessionCallbacks
+                = createFirstMockPrinterDiscoverySessionCallbacks();
+
+        // Create the service callbacks for the first print service.
+        PrintServiceCallbacks serviceCallbacks = createFirstMockPrinterServiceCallbacks(
+                sessionCallbacks, new PrintJobTestFn() {
+                    @Override
+                    public void onPrintJobQueued(PrintJob printJob) throws Exception {
+                        assertTrue(printJob.hasAdvancedOption(VALID_STRING_KEY));
+                        assertEquals(STRING_VALUE, printJob.getAdvancedStringOption(VALID_STRING_KEY));
+
+                        assertFalse(printJob.hasAdvancedOption(INVALID_STRING_KEY));
+                        assertNull(printJob.getAdvancedStringOption(INVALID_STRING_KEY));
+
+                        assertTrue(printJob.hasAdvancedOption(VALID_INT_KEY));
+                        assertEquals(INT_VALUE, printJob.getAdvancedIntOption(VALID_INT_KEY));
+
+                        assertTrue(printJob.hasAdvancedOption(VALID_NULL_KEY));
+                        assertNull(printJob.getAdvancedStringOption(VALID_NULL_KEY));
+
+                        assertFalse(printJob.hasAdvancedOption(INVALID_INT_KEY));
+                        assertEquals(0, printJob.getAdvancedIntOption(INVALID_INT_KEY));
+
+                        assertNull(printJob.getAdvancedStringOption(VALID_INT_KEY));
+                        assertEquals(0, printJob.getAdvancedIntOption(VALID_STRING_KEY));
+                    }
+                });
+
+        CustomPrintOptionsActivity.setCallBack(
+                new CustomPrintOptionsActivity.CustomPrintOptionsCallback() {
+                    @Override
+                    public PrintJobInfo executeCustomPrintOptionsActivity(
+                            PrintJobInfo printJob, PrinterInfo printer) {
+                        PrintJobInfo.Builder printJobBuilder = new PrintJobInfo.Builder(printJob);
+
+                        try {
+                            printJobBuilder.putAdvancedOption(null, STRING_VALUE);
+                            throw new RuntimeException("Should not be able to use a null key");
+                        } catch (NullPointerException e) {
+                            // expected
+                        }
+
+                        // Second put overrides the first
+                        printJobBuilder.putAdvancedOption(VALID_STRING_KEY, "something");
+                        printJobBuilder.putAdvancedOption(VALID_STRING_KEY, STRING_VALUE);
+
+                        printJobBuilder.putAdvancedOption(VALID_INT_KEY, "something");
+                        printJobBuilder.putAdvancedOption(VALID_INT_KEY, INT_VALUE);
+
+                        printJobBuilder.putAdvancedOption(VALID_NULL_KEY, null);
+
+                        return printJobBuilder.build();
+                    }
+                });
+
+        // Configure the print services.
+        FirstPrintService.setCallbacks(serviceCallbacks);
+
+        // We don't use the second service, but we have to still configure it
+        SecondPrintService.setCallbacks(createMockPrintServiceCallbacks(null, null, null));
+
+        // Create a print adapter that respects the print contract.
+        PrintDocumentAdapter adapter = createMockPrintDocumentAdapter();
+
+        // Start printing.
+        print(adapter);
+
+        selectPrinter(PRINTER_NAME);
+        openPrintOptions();
+        openCustomPrintOptions();
+        clickPrintButton();
+        answerPrintServicesWarning(true);
+
+        // Wait for print job to be queued
+        waitForServiceOnPrintJobQueuedCallbackCalled(1);
+
+        // Wait for discovery session to be destroyed to isolate tests from each other
+        waitForPrinterDiscoverySessionDestroyCallbackCalled(1);
+
+        if (!testSuccess[0]) {
+            throw new Exception("Did not succeed");
+        }
+    }
+
+    public void testOther() throws Exception {
+        baseTest(new PrintJobTestFn() {
+            @Override
+            public void onPrintJobQueued(PrintJob printJob) throws Exception {
+                assertNotNull(printJob.getDocument());
+                assertNotNull(printJob.getId());
+            }
+        }, 0);
+    }
+
+    public void testSetStatus() throws Exception {
+        baseTest(new PrintJobTestFn() {
+            @Override
+            public void onPrintJobQueued(PrintJob printJob) throws Exception {
+                printJob.start();
+
+                printJob.setStatus(R.string.testStr1);
+                eventually(() -> assertEquals(getActivity().getString(R.string.testStr1),
+                        printJob.getInfo().getStatus(getActivity().getPackageManager())));
+
+                printJob.setStatus("testStr3");
+                eventually(() -> assertEquals("testStr3",
+                        printJob.getInfo().getStatus(getActivity().getPackageManager())));
+
+                printJob.setStatus(R.string.testStr2);
+                eventually(() -> assertEquals(getActivity().getString(R.string.testStr2),
+                        printJob.getInfo().getStatus(getActivity().getPackageManager())));
+
+                printJob.setStatus(null);
+                eventually(() -> assertNull(
+                        printJob.getInfo().getStatus(getActivity().getPackageManager())));
+
+                printJob.block("testStr4");
+                eventually(() -> assertEquals("testStr4",
+                        printJob.getInfo().getStatus(getActivity().getPackageManager())));
+
+                printJob.setStatus(R.string.testStr2);
+                eventually(() -> assertEquals(getActivity().getString(R.string.testStr2),
+                        printJob.getInfo().getStatus(getActivity().getPackageManager())));
+
+                try {
+                    printJob.setStatus(0);
+                    throw new Exception("Should not be able to set 0 as status res id");
+                } catch (IllegalArgumentException e) {
+                    // expected, status should not be changed
+                    assertEquals(getActivity().getString(R.string.testStr2),
+                            printJob.getInfo().getStatus(getActivity().getPackageManager()));
+                }
+
+                printJob.setStatus(-1);
+                eventually(() -> assertNull(
+                        printJob.getInfo().getStatus(getActivity().getPackageManager())));
+            }
+        }, 0);
+    }
+}
diff --git a/tests/tests/print/src/android/print/cts/PrintServicesTest.java b/tests/tests/print/src/android/print/cts/PrintServicesTest.java
new file mode 100644
index 0000000..ccb1f07
--- /dev/null
+++ b/tests/tests/print/src/android/print/cts/PrintServicesTest.java
@@ -0,0 +1,577 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.print.cts;
+
+import android.app.Activity;
+import android.app.PendingIntent;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.Icon;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.ParcelFileDescriptor;
+import android.os.SystemClock;
+import android.print.PageRange;
+import android.print.PrintAttributes;
+import android.print.PrintAttributes.Margins;
+import android.print.PrintAttributes.MediaSize;
+import android.print.PrintAttributes.Resolution;
+import android.print.PrintDocumentAdapter;
+import android.print.PrintDocumentAdapter.LayoutResultCallback;
+import android.print.PrintDocumentAdapter.WriteResultCallback;
+import android.print.PrintDocumentInfo;
+import android.print.PrinterCapabilitiesInfo;
+import android.print.PrinterId;
+import android.print.PrinterInfo;
+import android.print.cts.services.FirstPrintService;
+import android.print.cts.services.PrintServiceCallbacks;
+import android.print.cts.services.PrinterDiscoverySessionCallbacks;
+import android.print.cts.services.SecondPrintService;
+import android.print.cts.services.StubbablePrinterDiscoverySession;
+import android.printservice.CustomPrinterIconCallback;
+import android.printservice.PrintJob;
+import android.support.test.uiautomator.UiDevice;
+import android.support.test.uiautomator.UiObject;
+import android.support.test.uiautomator.UiSelector;
+
+import junit.framework.AssertionFailedError;
+
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.concurrent.TimeoutException;
+
+/**
+ * Test the interface from a print service to the print manager
+ */
+public class PrintServicesTest extends BasePrintTest {
+    private static final String PRINTER_NAME = "Test printer";
+    private static final int NUM_PAGES = 2;
+
+    /** The print job processed in the test */
+    private static PrintJob mPrintJob;
+
+    /** The current progress of #mPrintJob once read from the system */
+    private static float mPrintProgress;
+
+    /** Printer under test */
+    private static PrinterInfo mPrinter;
+
+    /** The printer discovery session used in this test */
+    private static StubbablePrinterDiscoverySession mDiscoverySession;
+
+    /** The current status of #mPrintJob once read from the system */
+    private static CharSequence mPrintStatus;
+
+    /** The custom printer icon to use */
+    private Icon mIcon;
+
+    /**
+     * Create a mock {@link PrintDocumentAdapter} that provides {@link #NUM_PAGES} empty pages.
+     *
+     * @return The mock adapter
+     */
+    private PrintDocumentAdapter createMockPrintDocumentAdapter() {
+        final PrintAttributes[] printAttributes = new PrintAttributes[1];
+
+        return createMockPrintDocumentAdapter(
+                new Answer<Void>() {
+                    @Override
+                    public Void answer(InvocationOnMock invocation) throws Throwable {
+                        printAttributes[0] = (PrintAttributes) invocation.getArguments()[1];
+                        LayoutResultCallback callback = (LayoutResultCallback) invocation
+                                .getArguments()[3];
+
+                        PrintDocumentInfo info = new PrintDocumentInfo.Builder(PRINT_JOB_NAME)
+                                .setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT)
+                                .setPageCount(NUM_PAGES)
+                                .build();
+
+                        callback.onLayoutFinished(info, false);
+
+                        // Mark layout was called.
+                        onLayoutCalled();
+                        return null;
+                    }
+                }, new Answer<Void>() {
+                    @Override
+                    public Void answer(InvocationOnMock invocation) throws Throwable {
+                        Object[] args = invocation.getArguments();
+                        PageRange[] pages = (PageRange[]) args[0];
+                        ParcelFileDescriptor fd = (ParcelFileDescriptor) args[1];
+                        WriteResultCallback callback = (WriteResultCallback) args[3];
+
+                        writeBlankPages(printAttributes[0], fd, pages[0].getStart(),
+                                pages[0].getEnd());
+                        fd.close();
+                        callback.onWriteFinished(pages);
+
+                        // Mark write was called.
+                        onWriteCalled();
+                        return null;
+                    }
+                }, new Answer<Void>() {
+                    @Override
+                    public Void answer(InvocationOnMock invocation) throws Throwable {
+                        // Mark finish was called.
+                        onFinishCalled();
+                        return null;
+                    }
+                });
+    }
+
+    /**
+     * Create a mock {@link PrinterDiscoverySessionCallbacks} that discovers a single printer with
+     * minimal capabilities.
+     *
+     * @return The mock session callbacks
+     */
+    private PrinterDiscoverySessionCallbacks createFirstMockPrinterDiscoverySessionCallbacks() {
+        return createMockPrinterDiscoverySessionCallbacks(new Answer<Void>() {
+            @Override
+            public Void answer(InvocationOnMock invocation) {
+                // Get the session.
+                mDiscoverySession = ((PrinterDiscoverySessionCallbacks) invocation.getMock())
+                        .getSession();
+
+                if (mDiscoverySession.getPrinters().isEmpty()) {
+                    List<PrinterInfo> printers = new ArrayList<PrinterInfo>();
+
+                    // Add the printer.
+                    PrinterId printerId = mDiscoverySession.getService()
+                            .generatePrinterId(PRINTER_NAME);
+
+                    PrinterCapabilitiesInfo capabilities = new PrinterCapabilitiesInfo.Builder(
+                            printerId)
+                                    .setMinMargins(new Margins(200, 200, 200, 200))
+                                    .addMediaSize(MediaSize.ISO_A4, true)
+                                    .addResolution(new Resolution("300x300", "300x300", 300, 300),
+                                            true)
+                                    .setColorModes(PrintAttributes.COLOR_MODE_COLOR,
+                                            PrintAttributes.COLOR_MODE_COLOR)
+                                    .build();
+
+                    Intent infoIntent = new Intent(getActivity(), Activity.class);
+                    PendingIntent infoPendingIntent = PendingIntent.getActivity(getActivity(), 0,
+                            infoIntent, PendingIntent.FLAG_IMMUTABLE);
+
+                    mPrinter = new PrinterInfo.Builder(printerId, PRINTER_NAME,
+                            PrinterInfo.STATUS_IDLE)
+                                    .setCapabilities(capabilities)
+                                    .setDescription("Minimal capabilities")
+                                    .setInfoIntent(infoPendingIntent)
+                                    .build();
+                    printers.add(mPrinter);
+
+                    mDiscoverySession.addPrinters(printers);
+                }
+                return null;
+            }
+        }, null, null, new Answer<Void>() {
+            @Override
+            public Void answer(InvocationOnMock invocation) throws Throwable {
+                return null;
+            }
+        }, new Answer<Void>() {
+            @Override
+            public Void answer(InvocationOnMock invocation) throws Throwable {
+                CustomPrinterIconCallback callback = (CustomPrinterIconCallback) invocation
+                        .getArguments()[2];
+
+                if (mIcon != null) {
+                    callback.onCustomPrinterIconLoaded(mIcon);
+                }
+                return null;
+            }
+        }, null, new Answer<Void>() {
+            @Override
+            public Void answer(InvocationOnMock invocation) throws Throwable {
+                // Take a note onDestroy was called.
+                onPrinterDiscoverySessionDestroyCalled();
+                return null;
+            }
+        });
+    }
+
+    /**
+     * Get the current progress of #mPrintJob
+     *
+     * @return The current progress
+     * @throws InterruptedException If the thread was interrupted while setting the progress
+     */
+    private float getProgress() throws InterruptedException {
+        final PrintServicesTest synchronizer = PrintServicesTest.this;
+
+        synchronized (synchronizer) {
+            Runnable getter = new Runnable() {
+                @Override
+                public void run() {
+                    synchronized (synchronizer) {
+                        mPrintProgress = mPrintJob.getInfo().getProgress();
+
+                        synchronizer.notify();
+                    }
+                }
+            };
+
+            (new Handler(Looper.getMainLooper())).post(getter);
+
+            synchronizer.wait();
+        }
+
+        return mPrintProgress;
+    }
+
+    /**
+     * Get the current status of #mPrintJob
+     *
+     * @return The current status
+     * @throws InterruptedException If the thread was interrupted while getting the status
+     */
+    private CharSequence getStatus() throws InterruptedException {
+        final PrintServicesTest synchronizer = PrintServicesTest.this;
+
+        synchronized (synchronizer) {
+            Runnable getter = new Runnable() {
+                @Override
+                public void run() {
+                    synchronized (synchronizer) {
+                        mPrintStatus = mPrintJob.getInfo()
+                                .getStatus(getActivity().getPackageManager());
+
+                        synchronizer.notify();
+                    }
+                }
+            };
+
+            (new Handler(Looper.getMainLooper())).post(getter);
+
+            synchronizer.wait();
+        }
+
+        return mPrintStatus;
+    }
+
+    /**
+     * Check if a print progress is correct.
+     *
+     * @param desiredProgress The expected @{link PrintProgresses}
+     * @throws Exception If anything goes wrong or this takes more than 5 seconds
+     */
+    private void checkNotification(float desiredProgress,
+            CharSequence desiredStatus) throws Exception {
+        final long TIMEOUT = 5000;
+        final Date start = new Date();
+
+        while ((new Date()).getTime() - start.getTime() < TIMEOUT) {
+            if (desiredProgress == getProgress()
+                    && desiredStatus.toString().equals(getStatus().toString())) {
+                return;
+            }
+
+            Thread.sleep(200);
+        }
+
+        throw new TimeoutException("Progress or status not updated in " + TIMEOUT + " ms");
+    }
+
+    /**
+     * Set a new progress and status for #mPrintJob
+     *
+     * @param progress The new progress to set
+     * @param status The new status to set
+     * @throws InterruptedException If the thread was interrupted while setting
+     */
+    private void setProgressAndStatus(final float progress, final CharSequence status)
+            throws InterruptedException {
+        final PrintServicesTest synchronizer = PrintServicesTest.this;
+
+        synchronized (synchronizer) {
+            Runnable completer = new Runnable() {
+                @Override
+                public void run() {
+                    synchronized (synchronizer) {
+                        mPrintJob.setProgress(progress);
+                        mPrintJob.setStatus(status);
+
+                        synchronizer.notify();
+                    }
+                }
+            };
+
+            (new Handler(Looper.getMainLooper())).post(completer);
+
+            synchronizer.wait();
+        }
+    }
+
+    /**
+     * Progress print job and check the print job state.
+     *
+     * @param progress How much to progress
+     * @param status The status to set
+     * @throws Exception If anything goes wrong.
+     */
+    private void progress(float progress, CharSequence status) throws Exception {
+        setProgressAndStatus(progress, status);
+
+        // Check that progress of job is correct
+        checkNotification(progress, status);
+    }
+
+    /**
+     * Create mock service callback for a session.
+     *
+     * @param sessionCallbacks The callbacks of the sessopm
+     */
+    private PrintServiceCallbacks createFirstMockPrinterServiceCallbacks(
+            final PrinterDiscoverySessionCallbacks sessionCallbacks) {
+        return createMockPrintServiceCallbacks(
+                new Answer<PrinterDiscoverySessionCallbacks>() {
+                    @Override
+                    public PrinterDiscoverySessionCallbacks answer(InvocationOnMock invocation) {
+                        return sessionCallbacks;
+                    }
+                },
+                new Answer<Void>() {
+                    @Override
+                    public Void answer(InvocationOnMock invocation) {
+                        mPrintJob = (PrintJob) invocation.getArguments()[0];
+                        mPrintJob.start();
+                        onPrintJobQueuedCalled();
+
+                        return null;
+                    }
+                }, null);
+    }
+
+    /**
+     * Test that the progress and status is propagated correctly.
+     *
+     * @throws Exception If anything is unexpected.
+     */
+    public void testProgress()
+            throws Exception {
+        if (!supportsPrinting()) {
+            return;
+        }
+        // Create the session callbacks that we will be checking.
+        PrinterDiscoverySessionCallbacks sessionCallbacks
+                = createFirstMockPrinterDiscoverySessionCallbacks();
+
+        // Create the service callbacks for the first print service.
+        PrintServiceCallbacks serviceCallbacks = createFirstMockPrinterServiceCallbacks(
+                sessionCallbacks);
+
+        // Configure the print services.
+        FirstPrintService.setCallbacks(serviceCallbacks);
+
+        // We don't use the second service, but we have to still configure it
+        SecondPrintService.setCallbacks(createMockPrintServiceCallbacks(null, null, null));
+
+        // Create a print adapter that respects the print contract.
+        PrintDocumentAdapter adapter = createMockPrintDocumentAdapter();
+
+        // Start printing.
+        print(adapter);
+
+        // Wait for write of the first page.
+        waitForWriteAdapterCallback(1);
+
+        // Select the printer.
+        selectPrinter(PRINTER_NAME);
+
+        // Click the print button.
+        clickPrintButton();
+
+        // Answer the dialog for the print service cloud warning
+        answerPrintServicesWarning(true);
+
+        // Wait until the print job is queued and #mPrintJob is set
+        waitForServiceOnPrintJobQueuedCallbackCalled(1);
+
+        // Progress print job and check for appropriate notifications
+        progress(0, "printed 0");
+        progress(0.5f, "printed 50");
+        progress(1, "printed 100");
+
+        // Call complete from the main thread
+        Handler handler = new Handler(Looper.getMainLooper());
+
+        Runnable completer = new Runnable() {
+            @Override
+            public void run() {
+                mPrintJob.complete();
+            }
+        };
+
+        handler.post(completer);
+
+        // Wait for all print jobs to be handled after which the session destroyed.
+        waitForPrinterDiscoverySessionDestroyCallbackCalled(1);
+    }
+
+    /**
+     * Render a {@link Drawable} into a {@link Bitmap}.
+     *
+     * @param d the drawable to be rendered
+     * @return the rendered bitmap
+     */
+    private static Bitmap renderDrawable(Drawable d) {
+        Bitmap bitmap = Bitmap.createBitmap(d.getIntrinsicWidth(), d.getIntrinsicHeight(),
+                Bitmap.Config.ARGB_8888);
+
+        Canvas canvas = new Canvas(bitmap);
+        d.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
+        d.draw(canvas);
+
+        return bitmap;
+    }
+
+    /**
+     * Update the printer
+     *
+     * @param printer the new printer to use
+     * @throws InterruptedException If we were interrupted while the printer was updated.
+     */
+    private void updatePrinter(final PrinterInfo printer)
+            throws InterruptedException {
+        final PrintServicesTest synchronizer = PrintServicesTest.this;
+
+        synchronized (synchronizer) {
+            Runnable updated = new Runnable() {
+                @Override
+                public void run() {
+                    synchronized (synchronizer) {
+                        ArrayList<PrinterInfo> printers = new ArrayList<>(1);
+                        printers.add(printer);
+                        mDiscoverySession.addPrinters(printers);
+
+                        synchronizer.notifyAll();
+                    }
+                }
+            };
+
+            (new Handler(Looper.getMainLooper())).post(updated);
+
+            synchronizer.wait();
+        }
+
+        // Update local copy of printer
+        mPrinter = printer;
+    }
+
+    /**
+     * Assert is the printer icon does not match the bitmap. As the icon update might take some time
+     * we try up to 5 seconds.
+     *
+     * @param bitmap The bitmap to match
+     */
+    private void assertThatIconIs(Bitmap bitmap) {
+        final long TIMEOUT = 5000;
+
+        final long startMillis = SystemClock.uptimeMillis();
+        while (true) {
+            try {
+                if (bitmap.sameAs(renderDrawable(mPrinter.loadIcon(getActivity())))) {
+                    return;
+                }
+                final long elapsedMillis = SystemClock.uptimeMillis() - startMillis;
+                final long waitMillis = TIMEOUT - elapsedMillis;
+                if (waitMillis <= 0) {
+                    throw new AssertionFailedError("Icon does not match bitmap");
+                }
+
+                // We do not get notified about the icon update, hence wait and try again.
+                Thread.sleep(1000);
+            } catch (InterruptedException ie) {
+               /* ignore */
+            }
+        }
+    }
+
+    /**
+     * Test that the icon get be updated.
+     *
+     * @throws Exception If anything is unexpected.
+     */
+    public void testUpdateIcon()
+            throws Exception {
+        if (!supportsPrinting()) {
+            return;
+        }
+        // Create the session callbacks that we will be checking.
+        final PrinterDiscoverySessionCallbacks sessionCallbacks
+                = createFirstMockPrinterDiscoverySessionCallbacks();
+
+        // Create the service callbacks for the first print service.
+        PrintServiceCallbacks serviceCallbacks = createFirstMockPrinterServiceCallbacks(
+                sessionCallbacks);
+
+        // Configure the print services.
+        FirstPrintService.setCallbacks(serviceCallbacks);
+
+        // We don't use the second service, but we have to still configure it
+        SecondPrintService.setCallbacks(createMockPrintServiceCallbacks(null, null, null));
+
+        // Create a print adapter that respects the print contract.
+        PrintDocumentAdapter adapter = createMockPrintDocumentAdapter();
+
+        // Start printing.
+        print(adapter);
+
+        // Open printer selection dropdown list to display icon on screen
+        UiObject destinationSpinner = UiDevice.getInstance(getInstrumentation())
+                .findObject(new UiSelector().resourceId(
+                        "com.android.printspooler:id/destination_spinner"));
+        destinationSpinner.click();
+
+        // Get the print service's icon
+        PackageManager packageManager = getActivity().getPackageManager();
+        PackageInfo packageInfo = packageManager.getPackageInfo(
+                new ComponentName(getActivity(), FirstPrintService.class).getPackageName(), 0);
+        ApplicationInfo appInfo = packageInfo.applicationInfo;
+        Drawable printServiceIcon = appInfo.loadIcon(packageManager);
+
+        assertThatIconIs(renderDrawable(printServiceIcon));
+
+        // Update icon to resource
+        updatePrinter((new PrinterInfo.Builder(mPrinter)).setIconResourceId(R.drawable.red_printer)
+                .build());
+
+        assertThatIconIs(renderDrawable(getActivity().getDrawable(R.drawable.red_printer)));
+
+        // Update icon to bitmap
+        Bitmap bm = BitmapFactory.decodeResource(getActivity().getResources(),
+                R.raw.yellow_printer);
+        // Icon will be picked up from the discovery session once setHasCustomPrinterIcon is set
+        mIcon = Icon.createWithBitmap(bm);
+        updatePrinter((new PrinterInfo.Builder(mPrinter)).setHasCustomPrinterIcon(true).build());
+
+        assertThatIconIs(renderDrawable(mIcon.loadDrawable(getActivity())));
+    }
+}
diff --git a/tests/tests/print/src/android/print/cts/PrinterCapabilitiesTest.java b/tests/tests/print/src/android/print/cts/PrinterCapabilitiesTest.java
new file mode 100644
index 0000000..8e3f984
--- /dev/null
+++ b/tests/tests/print/src/android/print/cts/PrinterCapabilitiesTest.java
@@ -0,0 +1,741 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.print.cts;
+
+import android.os.ParcelFileDescriptor;
+import android.print.PageRange;
+import android.print.PrintAttributes;
+import android.print.PrintAttributes.Margins;
+import android.print.PrintAttributes.MediaSize;
+import android.print.PrintAttributes.Resolution;
+import android.print.PrintDocumentAdapter;
+import android.print.PrintDocumentAdapter.LayoutResultCallback;
+import android.print.PrintDocumentAdapter.WriteResultCallback;
+import android.print.PrintDocumentInfo;
+import android.print.PrinterCapabilitiesInfo;
+import android.print.PrinterId;
+import android.print.PrinterInfo;
+import android.print.cts.services.FirstPrintService;
+import android.print.cts.services.PrintServiceCallbacks;
+import android.print.cts.services.PrinterDiscoverySessionCallbacks;
+import android.print.cts.services.SecondPrintService;
+import android.print.cts.services.StubbablePrinterDiscoverySession;
+import android.util.Log;
+import android.support.test.uiautomator.UiObject;
+import android.support.test.uiautomator.UiSelector;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeoutException;
+import java.util.function.Consumer;
+import java.util.function.Function;
+
+/**
+ * This test verifies changes to the printer capabilities are applied correctly.
+ */
+public class PrinterCapabilitiesTest extends BasePrintTest {
+    private static final String LOG_TAG = "PrinterCapabilitiesTest";
+    private static final String PRINTER_NAME = "Test printer";
+
+    private static final Margins DEFAULT_MARGINS = new Margins(0, 0, 0, 0);
+    private static final PrintAttributes.Resolution RESOLUTION_300 =
+            new PrintAttributes.Resolution("300", "300", 300, 300);
+    private static final PrintAttributes.Resolution RESOLUTION_600 =
+            new PrintAttributes.Resolution("600", "600", 600, 600);
+
+    /**
+     * Generate a new list of printers containing a singer printer with the given media size and
+     * status. The other capabilities are default values.
+     *
+     * @param printerId The id of the printer
+     * @param mediaSize The media size to use
+     * @param status    The status of th printer
+     *
+     * @return The list of printers
+     */
+    private List<PrinterInfo> generatePrinters(PrinterId printerId, MediaSize mediaSize,
+            int status) {
+        List<PrinterInfo> printers = new ArrayList<>(1);
+
+        PrinterCapabilitiesInfo cap;
+
+        if (mediaSize != null) {
+            PrinterCapabilitiesInfo.Builder builder = new PrinterCapabilitiesInfo.Builder(
+                    printerId);
+            builder.setMinMargins(DEFAULT_MARGINS)
+                    .setColorModes(PrintAttributes.COLOR_MODE_COLOR,
+                            PrintAttributes.COLOR_MODE_COLOR)
+                    .setDuplexModes(PrintAttributes.DUPLEX_MODE_NONE,
+                            PrintAttributes.DUPLEX_MODE_NONE)
+                    .addMediaSize(mediaSize, true)
+                    .addResolution(RESOLUTION_300, true);
+            cap = builder.build();
+        } else {
+            cap = null;
+        }
+
+        printers.add(new PrinterInfo.Builder(printerId, PRINTER_NAME, status).setCapabilities(cap)
+                .build());
+
+        return printers;
+    }
+
+    /**
+     * Wait until the print activity requested an update with print attributes matching the media
+     * size.
+     *
+     * @param printAttributes The print attributes container
+     * @param mediaSize       The media size to match
+     *
+     * @throws Exception If anything unexpected happened, e.g. the attributes did not change.
+     */
+    private void waitForMediaSizeChange(PrintAttributes[] printAttributes, MediaSize mediaSize)
+            throws Exception {
+        synchronized (PrinterCapabilitiesTest.this) {
+            long endTime = System.currentTimeMillis() + OPERATION_TIMEOUT_MILLIS;
+            while (printAttributes[0] == null ||
+                    !printAttributes[0].getMediaSize().equals(mediaSize)) {
+                wait(Math.max(0, endTime - System.currentTimeMillis()));
+
+                if (endTime < System.currentTimeMillis()) {
+                    throw new TimeoutException(
+                            "Print attributes did not change to " + mediaSize + " in " +
+                                    OPERATION_TIMEOUT_MILLIS + " ms. Current attributes"
+                                    + printAttributes[0]);
+                }
+            }
+        }
+    }
+
+    /**
+     * Change the media size of the capabilities of the printer
+     *
+     * @param session     The session used in the test
+     * @param printerId   The printer to change
+     * @param mediaSize   The new mediaSize to apply
+     * @param isAvailable If the printer should be available or not
+     */
+    private void changeCapabilities(final StubbablePrinterDiscoverySession session,
+            final PrinterId printerId, final MediaSize mediaSize, final boolean isAvailable) {
+        getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                session.addPrinters(generatePrinters(printerId, mediaSize, isAvailable ?
+                        PrinterInfo.STATUS_IDLE :
+                        PrinterInfo.STATUS_UNAVAILABLE));
+            }
+        });
+    }
+
+    /**
+     * Wait until the message is shown that indicates that a printer is unavilable.
+     *
+     * @throws Exception If anything was unexpected.
+     */
+    private void waitForPrinterUnavailable() throws Exception {
+        final String PRINTER_UNAVAILABLE_MSG = "This printer isn't available right now.";
+
+        UiObject message = getUiDevice().findObject(new UiSelector().resourceId(
+                "com.android.printspooler:id/message"));
+        if (!message.getText().equals(PRINTER_UNAVAILABLE_MSG)) {
+            throw new Exception("Wrong message: " + message.getText() + " instead of " +
+                    PRINTER_UNAVAILABLE_MSG);
+        }
+    }
+
+    /**
+     * A single test case from {@link #testPrinterCapabilityChange}. Tests a single capability
+     * change.
+     *
+     * @param session     The session used in  the test
+     * @param printerId   The ID of the test printer
+     * @param availBefore If the printer should be available before the change
+     * @param msBefore    The media size of the printer before the change
+     * @param availAfter  If the printer should be available after the change
+     * @param msAfter     The media size of the printer after the change
+     *
+     * @throws Exception If anything is unexpected
+     */
+    private void testCase(final StubbablePrinterDiscoverySession[] session,
+            final PrinterId[] printerId, final boolean availBefore, final MediaSize msBefore,
+            final boolean availAfter, final MediaSize msAfter) throws Exception {
+        if (!supportsPrinting()) {
+            return;
+        }
+
+        Log.i(LOG_TAG, "Test case: " + availBefore + ", " + msBefore + " -> " + availAfter + ", "
+                + msAfter);
+
+        final PrintAttributes[] layoutAttributes = new PrintAttributes[1];
+        final PrintAttributes[] writeAttributes = new PrintAttributes[1];
+
+        PrintDocumentAdapter adapter = createMockPrintDocumentAdapter(
+                new Answer<Void>() {
+                    @Override
+                    public Void answer(InvocationOnMock invocation) throws Throwable {
+                        LayoutResultCallback callback = (LayoutResultCallback) invocation
+                                .getArguments()[3];
+                        PrintDocumentInfo info = new PrintDocumentInfo.Builder(PRINT_JOB_NAME)
+                                .setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT)
+                                .setPageCount(1)
+                                .build();
+
+                        synchronized (PrinterCapabilitiesTest.this) {
+                            layoutAttributes[0] = (PrintAttributes) invocation.getArguments()[1];
+
+                            PrinterCapabilitiesTest.this.notify();
+                        }
+
+                        callback.onLayoutFinished(info, true);
+                        return null;
+                    }
+                },
+                new Answer<Void>() {
+                    @Override
+                    public Void answer(InvocationOnMock invocation) throws Throwable {
+                        Object[] args = invocation.getArguments();
+                        PageRange[] pages = (PageRange[]) args[0];
+                        ParcelFileDescriptor fd = (ParcelFileDescriptor) args[1];
+                        WriteResultCallback callback = (WriteResultCallback) args[3];
+
+                        writeBlankPages(layoutAttributes[0], fd, pages[0].getStart(),
+                                pages[0].getEnd());
+                        fd.close();
+
+                        synchronized (PrinterCapabilitiesTest.this) {
+                            writeAttributes[0] = layoutAttributes[0];
+
+                            PrinterCapabilitiesTest.this.notify();
+                        }
+
+                        callback.onWriteFinished(pages);
+                        return null;
+                    }
+                }, null);
+
+        // Start printing.
+        print(adapter);
+
+        // Select the printer.
+        selectPrinter(PRINTER_NAME);
+
+        changeCapabilities(session[0], printerId[0], msBefore, availBefore);
+        if (availBefore && msBefore != null) {
+            waitForMediaSizeChange(layoutAttributes, msBefore);
+            waitForMediaSizeChange(writeAttributes, msBefore);
+        } else {
+            waitForPrinterUnavailable();
+        }
+
+        changeCapabilities(session[0], printerId[0], msAfter, availAfter);
+        if (availAfter && msAfter != null) {
+            waitForMediaSizeChange(layoutAttributes, msAfter);
+            waitForMediaSizeChange(writeAttributes, msAfter);
+        } else {
+            waitForPrinterUnavailable();
+        }
+
+        // Reset printer to default in case discovery session is reused
+        changeCapabilities(session[0], printerId[0], MediaSize.NA_LETTER, true);
+        waitForMediaSizeChange(layoutAttributes, MediaSize.NA_LETTER);
+        waitForMediaSizeChange(writeAttributes, MediaSize.NA_LETTER);
+
+        getUiDevice().pressBack();
+
+        // Wait until PrintActivity is gone
+        Thread.sleep(500);
+    }
+
+    /**
+     * Tests that the printActivity propertly requests (layout and write) updates when the printer
+     * capabilities change. This tests all combination of changes.
+     *
+     * @throws Exception If something is unexpected.
+     */
+    public void testPrinterCapabilityChange() throws Exception {
+        // The session might be reused between test cases, hence carry them from test case to case
+        final StubbablePrinterDiscoverySession[] session = new StubbablePrinterDiscoverySession[1];
+        final PrinterId[] printerId = new PrinterId[1];
+
+        // Create the session[0] callbacks that we will be checking.
+        final PrinterDiscoverySessionCallbacks firstSessionCallbacks =
+                createMockPrinterDiscoverySessionCallbacks(new Answer<Void>() {
+                    @Override
+                    public Void answer(InvocationOnMock invocation) {
+                        session[0] = ((PrinterDiscoverySessionCallbacks) invocation.getMock())
+                                .getSession();
+
+                        printerId[0] = session[0].getService().generatePrinterId(PRINTER_NAME);
+
+                        session[0].addPrinters(generatePrinters(printerId[0], MediaSize.NA_LETTER,
+                                PrinterInfo.STATUS_IDLE));
+                        return null;
+                    }
+                }, null, null, null, null, null, new Answer<Void>() {
+                    @Override
+                    public Void answer(InvocationOnMock invocation) {
+                        onPrinterDiscoverySessionDestroyCalled();
+                        return null;
+                    }
+                });
+
+        // Create the service callbacks for the first print service.
+        PrintServiceCallbacks firstServiceCallbacks = createMockPrintServiceCallbacks(
+                new Answer<PrinterDiscoverySessionCallbacks>() {
+                    @Override
+                    public PrinterDiscoverySessionCallbacks answer(InvocationOnMock invocation) {
+                        return firstSessionCallbacks;
+                    }
+                }, null, null);
+
+        // Configure the print services.
+        FirstPrintService.setCallbacks(firstServiceCallbacks);
+        SecondPrintService.setCallbacks(createMockPrintServiceCallbacks(null, null, null));
+
+        testCase(session, printerId, false, null, false, null);
+        testCase(session, printerId, false, null, false, MediaSize.ISO_A0);
+        testCase(session, printerId, false, null, false, MediaSize.ISO_B0);
+        testCase(session, printerId, false, null, true, null);
+        testCase(session, printerId, false, null, true, MediaSize.ISO_A0);
+        testCase(session, printerId, false, null, true, MediaSize.ISO_B0);
+        testCase(session, printerId, false, MediaSize.ISO_A0, false, null);
+        testCase(session, printerId, false, MediaSize.ISO_A0, false, MediaSize.ISO_A0);
+        testCase(session, printerId, false, MediaSize.ISO_A0, false, MediaSize.ISO_B0);
+        testCase(session, printerId, false, MediaSize.ISO_A0, true, null);
+        testCase(session, printerId, false, MediaSize.ISO_A0, true, MediaSize.ISO_A0);
+        testCase(session, printerId, false, MediaSize.ISO_A0, true, MediaSize.ISO_B0);
+        testCase(session, printerId, true, null, false, null);
+        testCase(session, printerId, true, null, false, MediaSize.ISO_B0);
+        testCase(session, printerId, true, null, true, null);
+        testCase(session, printerId, true, null, true, MediaSize.ISO_B0);
+        testCase(session, printerId, true, MediaSize.ISO_A0, false, null);
+        testCase(session, printerId, true, MediaSize.ISO_A0, false, MediaSize.ISO_A0);
+        testCase(session, printerId, true, MediaSize.ISO_A0, false, MediaSize.ISO_B0);
+        testCase(session, printerId, true, MediaSize.ISO_A0, true, null);
+        testCase(session, printerId, true, MediaSize.ISO_A0, true, MediaSize.ISO_A0);
+        testCase(session, printerId, true, MediaSize.ISO_A0, true, MediaSize.ISO_B0);
+
+        waitForPrinterDiscoverySessionDestroyCallbackCalled(1);
+    }
+
+    /**
+     * Run a runnable and expect and exception of a certain type.
+     *
+     * @param r The runnable to run
+     * @param expectedClass The expected exception type
+     */
+    private void assertException(Runnable r, Class<? extends RuntimeException> expectedClass) {
+        try {
+            r.run();
+        } catch (Exception e) {
+            if (e.getClass().isAssignableFrom(expectedClass)) {
+                return;
+            } else {
+                throw new AssertionError("Expected: " + expectedClass.getName() + ", got: "
+                        + e.getClass().getName());
+            }
+        }
+
+        throw new AssertionError("No exception thrown");
+    }
+
+    /**
+     * That that you cannot create illegal PrinterCapabilityInfos.
+     *
+     * @throws Exception If anything is unexpected
+     */
+    public void testIllegalPrinterCapabilityInfos() throws Exception {
+        if (!supportsPrinting()) {
+            return;
+        }
+
+        final PrinterDiscoverySessionCallbacks firstSessionCallbacks =
+                createMockPrinterDiscoverySessionCallbacks(new Answer<Void>() {
+                    @Override
+                    public Void answer(InvocationOnMock invocation) {
+                        StubbablePrinterDiscoverySession session =
+                                ((PrinterDiscoverySessionCallbacks)
+                                        invocation.getMock()).getSession();
+
+                        PrinterId printerId = session.getService().generatePrinterId(PRINTER_NAME);
+
+                        // printerId need to be set
+                        assertException(() -> new PrinterCapabilitiesInfo.Builder(null),
+                                IllegalArgumentException.class);
+
+                        // All capability fields (beside duplex) need to be initialized:
+                        // Test no color
+                        assertException(() ->
+                                        (new PrinterCapabilitiesInfo.Builder(printerId))
+                                                .setMinMargins(DEFAULT_MARGINS)
+                                                .addMediaSize(MediaSize.ISO_A4, true)
+                                                .addResolution(RESOLUTION_300, true).build(),
+                                IllegalStateException.class);
+                        // Test bad colors
+                        assertException(() ->
+                                        (new PrinterCapabilitiesInfo.Builder(printerId))
+                                                .setColorModes(0xffff,
+                                                        PrintAttributes.COLOR_MODE_MONOCHROME),
+                                IllegalArgumentException.class);
+                        // Test bad duplex mode
+                        assertException(() ->
+                                        (new PrinterCapabilitiesInfo.Builder(printerId))
+                                                .setDuplexModes(0xffff,
+                                                        PrintAttributes.DUPLEX_MODE_NONE),
+                                IllegalArgumentException.class);
+                        // Test no mediasize
+                        assertException(() ->
+                                        (new PrinterCapabilitiesInfo.Builder(printerId))
+                                                .setColorModes(PrintAttributes.COLOR_MODE_COLOR,
+                                                        PrintAttributes.COLOR_MODE_COLOR)
+                                                .setMinMargins(DEFAULT_MARGINS)
+                                                .addResolution(RESOLUTION_300, true).build(),
+                                IllegalStateException.class);
+                        // Test no default mediasize
+                        assertException(() ->
+                                        (new PrinterCapabilitiesInfo.Builder(printerId))
+                                                .setColorModes(PrintAttributes.COLOR_MODE_COLOR,
+                                                        PrintAttributes.COLOR_MODE_COLOR)
+                                                .setMinMargins(DEFAULT_MARGINS)
+                                                .addMediaSize(MediaSize.ISO_A4, false)
+                                                .addResolution(RESOLUTION_300, true).build(),
+                                IllegalStateException.class);
+                        // Test two default mediasizes
+                        assertException(() ->
+                                        (new PrinterCapabilitiesInfo.Builder(printerId))
+                                                .addMediaSize(MediaSize.ISO_A4, true)
+                                                .addMediaSize(MediaSize.ISO_A5, true),
+                                IllegalArgumentException.class);
+                        // Test no resolution
+                        assertException(() ->
+                                        (new PrinterCapabilitiesInfo.Builder(printerId))
+                                                .setColorModes(PrintAttributes.COLOR_MODE_COLOR,
+                                                        PrintAttributes.COLOR_MODE_COLOR)
+                                                .setMinMargins(DEFAULT_MARGINS)
+                                                .addMediaSize(MediaSize.ISO_A4, true).build(),
+                                IllegalStateException.class);
+                        // Test no default resolution
+                        assertException(() ->
+                                        (new PrinterCapabilitiesInfo.Builder(printerId))
+                                                .setColorModes(PrintAttributes.COLOR_MODE_COLOR,
+                                                        PrintAttributes.COLOR_MODE_COLOR)
+                                                .setMinMargins(DEFAULT_MARGINS)
+                                                .addMediaSize(MediaSize.ISO_A4, true)
+                                                .addResolution(RESOLUTION_300, false).build(),
+                                IllegalStateException.class);
+                        // Test two default resolutions
+                        assertException(() ->
+                                        (new PrinterCapabilitiesInfo.Builder(printerId))
+                                                .addResolution(RESOLUTION_300, true)
+                                                .addResolution(RESOLUTION_600, true),
+                                IllegalArgumentException.class);
+
+                        onPrinterDiscoverySessionCreateCalled();
+                        return null;
+                    }
+                }, null, null, null, null, null, new Answer<Void>() {
+                    @Override
+                    public Void answer(InvocationOnMock invocation) {
+                        onPrinterDiscoverySessionDestroyCalled();
+                        return null;
+                    }
+                });
+
+        // Create the service callbacks for the first print service.
+        PrintServiceCallbacks firstServiceCallbacks = createMockPrintServiceCallbacks(
+                new Answer<PrinterDiscoverySessionCallbacks>() {
+                    @Override
+                    public PrinterDiscoverySessionCallbacks answer(InvocationOnMock invocation) {
+                        return firstSessionCallbacks;
+                    }
+                }, null, null);
+
+        // Configure the print services.
+        FirstPrintService.setCallbacks(firstServiceCallbacks);
+        SecondPrintService.setCallbacks(createMockPrintServiceCallbacks(null, null, null));
+
+        PrintDocumentAdapter adapter = createMockPrintDocumentAdapter(null, null, null);
+
+        // Start printing.
+        print(adapter);
+
+        waitForPrinterDiscoverySessionCreateCallbackCalled();
+
+        getActivity().finish();
+
+        waitForPrinterDiscoverySessionDestroyCallbackCalled(1);
+    }
+
+    /**
+     * That that you can use all sane legal PrinterCapabilityInfos.
+     *
+     * @throws Exception If anything is unexpected
+     */
+    public void testSanePrinterCapabilityInfos() throws Exception {
+        if (!supportsPrinting()) {
+            return;
+        }
+
+        final PrinterDiscoverySessionCallbacks firstSessionCallbacks =
+                createMockPrinterDiscoverySessionCallbacks(new Answer<Void>() {
+                    @Override
+                    public Void answer(InvocationOnMock invocation) {
+                        StubbablePrinterDiscoverySession session =
+                                ((PrinterDiscoverySessionCallbacks)
+                                        invocation.getMock()).getSession();
+
+                        MediaSize[] mediaSizes = {MediaSize.ISO_A0, MediaSize.ISO_A0,
+                                MediaSize.ISO_A1};
+                        Resolution[] resolutions = {RESOLUTION_300, RESOLUTION_300,
+                                RESOLUTION_600};
+                        int[] colorModes = {PrintAttributes.COLOR_MODE_MONOCHROME,
+                                PrintAttributes.COLOR_MODE_COLOR};
+                        int[] duplexModes = {PrintAttributes.DUPLEX_MODE_NONE,
+                                PrintAttributes.DUPLEX_MODE_LONG_EDGE,
+                                PrintAttributes.DUPLEX_MODE_SHORT_EDGE};
+
+                        ArrayList<PrinterInfo> printers = new ArrayList<>();
+                        for (int mediaSizeIndex = 1; mediaSizeIndex < mediaSizes.length;
+                             mediaSizeIndex++) {
+                            for (int resolutionIndex = 1; resolutionIndex < mediaSizes.length;
+                                 resolutionIndex++) {
+                                for (int colorIndex = 1; colorIndex < colorModes.length;
+                                     colorIndex++) {
+                                    for (int duplexIndex = 1; duplexIndex < duplexModes.length;
+                                         duplexIndex++) {
+                                        PrinterId printerId = session.getService()
+                                                .generatePrinterId(Integer.valueOf(printers.size())
+                                                        .toString());
+
+                                        PrinterCapabilitiesInfo.Builder b =
+                                                new PrinterCapabilitiesInfo.Builder(printerId);
+
+                                        for (int i = 0; i < mediaSizeIndex; i++) {
+                                            b.addMediaSize(mediaSizes[i], i == mediaSizeIndex - 1);
+                                        }
+
+                                        for (int i = 0; i < resolutionIndex; i++) {
+                                            b.addResolution(resolutions[i],
+                                                    i == resolutionIndex - 1);
+                                        }
+
+                                        int allColors = 0;
+                                        for (int i = 0; i < colorIndex; i++) {
+                                            allColors |= colorModes[i];
+                                        }
+                                        b.setColorModes(allColors, colorModes[colorIndex - 1]);
+
+                                        int allDuplexModes = 0;
+                                        for (int i = 0; i < duplexIndex; i++) {
+                                            allDuplexModes |= duplexModes[i];
+                                        }
+                                        b.setDuplexModes(allDuplexModes,
+                                                duplexModes[duplexIndex - 1]);
+
+                                        printers.add((new PrinterInfo.Builder(printerId,
+                                                Integer.valueOf(printers.size()).toString(),
+                                                PrinterInfo.STATUS_IDLE)).setCapabilities(b.build())
+                                                .build());
+                                    }
+                                }
+                            }
+                        }
+
+                        session.addPrinters(printers);
+
+                        onPrinterDiscoverySessionCreateCalled();
+                        return null;
+                    }
+                }, null, null, null, null, null, new Answer<Void>() {
+                    @Override
+                    public Void answer(InvocationOnMock invocation) {
+                        onPrinterDiscoverySessionDestroyCalled();
+                        return null;
+                    }
+                });
+
+        // Create the service callbacks for the first print service.
+        PrintServiceCallbacks firstServiceCallbacks = createMockPrintServiceCallbacks(
+                new Answer<PrinterDiscoverySessionCallbacks>() {
+                    @Override
+                    public PrinterDiscoverySessionCallbacks answer(InvocationOnMock invocation) {
+                        return firstSessionCallbacks;
+                    }
+                }, null, null);
+
+        // Configure the print services.
+        FirstPrintService.setCallbacks(firstServiceCallbacks);
+        SecondPrintService.setCallbacks(createMockPrintServiceCallbacks(null, null, null));
+
+        PrintDocumentAdapter adapter = createMockPrintDocumentAdapter(null, null, null);
+
+        // Start printing.
+        print(adapter);
+
+        waitForPrinterDiscoverySessionCreateCallbackCalled();
+
+        getUiDevice().pressBack();
+
+        waitForPrinterDiscoverySessionDestroyCallbackCalled(1);
+    }
+
+    /**
+     * Base test that performs a print operation with a give PrinterCapabilityInfo and run a test
+     * function before finishing.
+     *
+     * @throws Exception
+     */
+    private void testPrinterCapabilityInfo(final Function<PrinterId, PrinterCapabilitiesInfo>
+            capBuilder, Consumer<PrintAttributes> test) throws Exception {
+        if (!supportsPrinting()) {
+            return;
+        }
+
+        final PrinterDiscoverySessionCallbacks firstSessionCallbacks =
+                createMockPrinterDiscoverySessionCallbacks(new Answer<Void>() {
+                    @Override
+                    public Void answer(InvocationOnMock invocation) {
+                        StubbablePrinterDiscoverySession session =
+                                ((PrinterDiscoverySessionCallbacks)
+                                        invocation.getMock()).getSession();
+
+                        PrinterId printerId = session.getService()
+                                .generatePrinterId(PRINTER_NAME);
+
+                        ArrayList<PrinterInfo> printers = new ArrayList<>();
+                        printers.add((new PrinterInfo.Builder(printerId, PRINTER_NAME,
+                                PrinterInfo.STATUS_IDLE))
+                                .setCapabilities(capBuilder.apply(printerId)).build());
+
+                        session.addPrinters(printers);
+
+                        onPrinterDiscoverySessionCreateCalled();
+                        return null;
+                    }
+                }, null, null, null, null, null, new Answer<Void>() {
+                    @Override
+                    public Void answer(InvocationOnMock invocation) {
+                        onPrinterDiscoverySessionDestroyCalled();
+                        return null;
+                    }
+                });
+
+        // Create the service callbacks for the first print service.
+        PrintServiceCallbacks firstServiceCallbacks = createMockPrintServiceCallbacks(
+                new Answer<PrinterDiscoverySessionCallbacks>() {
+                    @Override
+                    public PrinterDiscoverySessionCallbacks answer(InvocationOnMock invocation) {
+                        return firstSessionCallbacks;
+                    }
+                }, null, null);
+
+        // Configure the print services.
+        FirstPrintService.setCallbacks(firstServiceCallbacks);
+        SecondPrintService.setCallbacks(createMockPrintServiceCallbacks(null, null, null));
+
+        final PrintAttributes[] layoutAttributes = new PrintAttributes[1];
+
+        PrintDocumentAdapter adapter = createMockPrintDocumentAdapter(
+                new Answer<Void>() {
+                    @Override
+                    public Void answer(InvocationOnMock invocation) throws Throwable {
+                        LayoutResultCallback callback = (LayoutResultCallback) invocation
+                                .getArguments()[3];
+                        PrintDocumentInfo info = new PrintDocumentInfo.Builder(PRINT_JOB_NAME)
+                                .setPageCount(1)
+                                .build();
+                        layoutAttributes[0] = (PrintAttributes) invocation.getArguments()[1];
+
+                        callback.onLayoutFinished(info, true);
+                        return null;
+                    }
+                },
+                new Answer<Void>() {
+                    @Override
+                    public Void answer(InvocationOnMock invocation) throws Throwable {
+                        Object[] args = invocation.getArguments();
+                        PageRange[] pages = (PageRange[]) args[0];
+                        ParcelFileDescriptor fd = (ParcelFileDescriptor) args[1];
+                        WriteResultCallback callback = (WriteResultCallback) args[3];
+
+                        writeBlankPages(layoutAttributes[0], fd, pages[0].getStart(),
+                                pages[0].getEnd());
+                        fd.close();
+
+                        callback.onWriteFinished(pages);
+                        return null;
+                    }
+                }, null);
+
+        // Start printing.
+        print(adapter);
+
+        // make sure that options does not crash
+        openPrintOptions();
+
+        // Select printer under test
+        selectPrinter(PRINTER_NAME);
+
+        clickPrintButton();
+
+        answerPrintServicesWarning(true);
+
+        test.accept(layoutAttributes[0]);
+
+        waitForPrinterDiscoverySessionDestroyCallbackCalled(1);
+    }
+
+    /**
+     * That that you use a default color that is not in the allowed colors. This is allowed because
+     * of historical reasons.
+     *
+     * @throws Exception If anything is unexpected
+     */
+    public void testInvalidDefaultColor() throws Exception {
+        testPrinterCapabilityInfo(
+                (printerId) -> (new PrinterCapabilitiesInfo.Builder(printerId))
+                        .addMediaSize(MediaSize.ISO_A4, true)
+                        .addResolution(RESOLUTION_300, true)
+                        .setColorModes(PrintAttributes.COLOR_MODE_MONOCHROME,
+                                PrintAttributes.COLOR_MODE_COLOR).build(),
+                (layoutAttributes) -> assertEquals(layoutAttributes.getColorMode(),
+                        PrintAttributes.COLOR_MODE_MONOCHROME));
+    }
+
+    /**
+     * That that you use a default duplex mode that is not in the allowed duplex modes. This is
+     * allowed because of historical reasons.
+     *
+     * @throws Exception If anything is unexpected
+     */
+    public void testInvalidDefaultDuplexMode() throws Exception {
+        testPrinterCapabilityInfo(
+                (printerId) -> (new PrinterCapabilitiesInfo.Builder(printerId))
+                        .addMediaSize(MediaSize.ISO_A4, true)
+                        .addResolution(RESOLUTION_300, true)
+                        .setColorModes(PrintAttributes.COLOR_MODE_MONOCHROME,
+                                PrintAttributes.COLOR_MODE_MONOCHROME)
+                        .setDuplexModes(PrintAttributes.DUPLEX_MODE_LONG_EDGE
+                                | PrintAttributes.DUPLEX_MODE_NONE,
+                                PrintAttributes.DUPLEX_MODE_SHORT_EDGE).build(),
+                (layoutAttributes) -> assertTrue(layoutAttributes.getDuplexMode() ==
+                        PrintAttributes.DUPLEX_MODE_LONG_EDGE || layoutAttributes.getDuplexMode() ==
+                        PrintAttributes.DUPLEX_MODE_NONE));
+    }
+}
diff --git a/tests/tests/print/src/android/print/cts/PrinterDiscoverySessionLifecycleTest.java b/tests/tests/print/src/android/print/cts/PrinterDiscoverySessionLifecycleTest.java
index 7ea09e5..defbee3 100644
--- a/tests/tests/print/src/android/print/cts/PrinterDiscoverySessionLifecycleTest.java
+++ b/tests/tests/print/src/android/print/cts/PrinterDiscoverySessionLifecycleTest.java
@@ -39,7 +39,6 @@
 import android.printservice.PrintJob;
 import android.printservice.PrinterDiscoverySession;
 
-import junit.framework.AssertionFailedError;
 import org.mockito.InOrder;
 import org.mockito.exceptions.verification.VerificationInOrderFailure;
 import org.mockito.invocation.InvocationOnMock;
@@ -97,7 +96,7 @@
         print(adapter);
 
         // Wait for write of the first page.
-        waitForWriteAdapterCallback();
+        waitForWriteAdapterCallback(1);
 
         // Select the first printer.
         selectPrinter(FIRST_PRINTER_NAME);
@@ -123,8 +122,11 @@
         // Click the print button.
         clickPrintButton();
 
+        // Answer the dialog for the print service cloud warning
+        answerPrintServicesWarning(true);
+
         // Wait for all print jobs to be handled after which the session destroyed.
-        waitForPrinterDiscoverySessionDestroyCallbackCalled();
+        waitForPrinterDiscoverySessionDestroyCallbackCalled(1);
 
         // Verify the expected calls.
         InOrder inOrder = inOrder(firstSessionCallbacks);
@@ -157,6 +159,94 @@
         inOrder.verify(firstSessionCallbacks).onDestroy();
     }
 
+    public void testCancelPrintServicesAlertDialog() throws Exception {
+        if (!supportsPrinting()) {
+            return;
+        }
+        // Create the session callbacks that we will be checking.
+        final PrinterDiscoverySessionCallbacks firstSessionCallbacks =
+                createFirstMockPrinterDiscoverySessionCallbacks();
+
+        // Create the service callbacks for the first print service.
+        PrintServiceCallbacks firstServiceCallbacks = createMockPrintServiceCallbacks(
+                new Answer<PrinterDiscoverySessionCallbacks>() {
+                    @Override
+                    public PrinterDiscoverySessionCallbacks answer(InvocationOnMock invocation) {
+                        return firstSessionCallbacks;
+                    }
+                },
+                new Answer<Void>() {
+                    @Override
+                    public Void answer(InvocationOnMock invocation) {
+                        PrintJob printJob = (PrintJob) invocation.getArguments()[0];
+                        // We pretend the job is handled immediately.
+                        printJob.complete();
+                        return null;
+                    }
+                }, null);
+
+        // Configure the print services.
+        FirstPrintService.setCallbacks(firstServiceCallbacks);
+        SecondPrintService.setCallbacks(createSecondMockPrintServiceCallbacks());
+
+        // Create a print adapter that respects the print contract.
+        PrintDocumentAdapter adapter = createMockPrintDocumentAdapter();
+
+        // Start printing.
+        print(adapter);
+
+        // Wait for write of the first page.
+        waitForWriteAdapterCallback(1);
+
+        // Select the first printer.
+        selectPrinter(FIRST_PRINTER_NAME);
+
+        // While the printer discovery session is still alive store the
+        // ids of printers as we want to make some assertions about them
+        // but only the print service can create printer ids which means
+        // that we need to get the created ones.
+        PrinterId firstPrinterId = getAddedPrinterIdForLocalId(firstSessionCallbacks,
+                FIRST_PRINTER_LOCAL_ID);
+        assertNotNull("Coundn't find printer:" + FIRST_PRINTER_LOCAL_ID, firstPrinterId);
+
+        // Click the print button.
+        clickPrintButton();
+
+        // Cancel the dialog for the print service cloud warning
+        answerPrintServicesWarning(false);
+
+        // Click the print button again.
+        clickPrintButton();
+
+        // Answer the dialog for the print service cloud warning
+        answerPrintServicesWarning(true);
+
+        // Wait for all print jobs to be handled after which the session destroyed.
+        waitForPrinterDiscoverySessionDestroyCallbackCalled(1);
+
+        // Verify the expected calls.
+        InOrder inOrder = inOrder(firstSessionCallbacks);
+
+        // We start discovery as the print dialog was up.
+        List<PrinterId> emptyPrinterIdList = Collections.emptyList();
+        inOrder.verify(firstSessionCallbacks).onStartPrinterDiscovery(
+                emptyPrinterIdList);
+
+        // We selected the first printer and now it should be tracked.
+        inOrder.verify(firstSessionCallbacks).onStartPrinterStateTracking(
+                firstPrinterId);
+
+        // We selected the second printer so the first should not be tracked.
+        inOrder.verify(firstSessionCallbacks).onStopPrinterStateTracking(
+                firstPrinterId);
+
+        // ... next we stop printer discovery...
+        inOrder.verify(firstSessionCallbacks).onStopPrinterDiscovery();
+
+        // ... last the session is destroyed.
+        inOrder.verify(firstSessionCallbacks).onDestroy();
+    }
+
     public void testStartPrinterDiscoveryWithHistoricalPrinters() throws Exception {
         if (!supportsPrinting()) {
             return;
@@ -194,7 +284,7 @@
         print(adapter);
 
         // Wait for write of the first page.
-        waitForWriteAdapterCallback();
+        waitForWriteAdapterCallback(1);
 
         // Select the first printer.
         selectPrinter(FIRST_PRINTER_NAME);
@@ -213,6 +303,9 @@
         // Click the print button.
         clickPrintButton();
 
+        // Answer the dialog for the print service cloud warning
+        answerPrintServicesWarning(true);
+
         // Wait for the print to complete.
         waitForAdapterFinishCallbackCalled();
 
@@ -231,7 +324,7 @@
         getUiDevice().pressBack();
 
         // Wait for all print jobs to be handled after which the is session destroyed.
-        waitForPrinterDiscoverySessionDestroyCallbackCalled();
+        waitForPrinterDiscoverySessionDestroyCallbackCalled(1);
 
         // Verify the expected calls.
         InOrder inOrder = inOrder(firstSessionCallbacks);
@@ -385,7 +478,7 @@
 
                 return null;
             }
-        }, null, new Answer<Void>() {
+        }, null, null, new Answer<Void>() {
             @Override
             public Void answer(InvocationOnMock invocation) throws Throwable {
                 // Take a note onDestroy was called.
diff --git a/tests/tests/print/src/android/print/cts/PrinterInfoTest.java b/tests/tests/print/src/android/print/cts/PrinterInfoTest.java
new file mode 100644
index 0000000..72f2866
--- /dev/null
+++ b/tests/tests/print/src/android/print/cts/PrinterInfoTest.java
@@ -0,0 +1,442 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.print.cts;
+
+import android.app.Activity;
+import android.app.PendingIntent;
+import android.content.Intent;
+import android.graphics.drawable.Icon;
+import android.os.ParcelFileDescriptor;
+import android.print.PageRange;
+import android.print.PrintAttributes;
+import android.print.PrintAttributes.Margins;
+import android.print.PrintAttributes.MediaSize;
+import android.print.PrintAttributes.Resolution;
+import android.print.PrintDocumentAdapter;
+import android.print.PrintDocumentAdapter.LayoutResultCallback;
+import android.print.PrintDocumentAdapter.WriteResultCallback;
+import android.print.PrintDocumentInfo;
+import android.print.PrinterCapabilitiesInfo;
+import android.print.PrinterId;
+import android.print.PrinterInfo;
+import android.print.cts.services.FirstPrintService;
+import android.print.cts.services.PrintServiceCallbacks;
+import android.print.cts.services.PrinterDiscoverySessionCallbacks;
+import android.print.cts.services.SecondPrintService;
+import android.print.cts.services.StubbablePrinterDiscoverySession;
+import android.printservice.CustomPrinterIconCallback;
+import android.support.test.uiautomator.UiObject;
+import android.support.test.uiautomator.UiSelector;
+import android.text.TextUtils;
+
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Tests all allowed types of printerInfo
+ */
+public class PrinterInfoTest extends BasePrintTest {
+    private static final int NUM_PAGES = 2;
+
+    private static final String NAMED_PRINTERS_NAME_PREFIX = "Printer ";
+
+    /** The printer discovery session used in this test */
+    private static StubbablePrinterDiscoverySession mDiscoverySession;
+
+    /** The custom printer icon to use */
+    private Icon mIcon;
+
+    /**
+     * Create a mock {@link PrintDocumentAdapter} that provides {@link #NUM_PAGES} empty pages.
+     *
+     * @return The mock adapter
+     */
+    private PrintDocumentAdapter createMockPrintDocumentAdapter() {
+        final PrintAttributes[] printAttributes = new PrintAttributes[1];
+
+        return createMockPrintDocumentAdapter(
+                new Answer<Void>() {
+                    @Override
+                    public Void answer(InvocationOnMock invocation) throws Throwable {
+                        printAttributes[0] = (PrintAttributes) invocation.getArguments()[1];
+                        LayoutResultCallback callback = (LayoutResultCallback) invocation
+                                .getArguments()[3];
+
+                        PrintDocumentInfo info = new PrintDocumentInfo.Builder(PRINT_JOB_NAME)
+                                .setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT)
+                                .setPageCount(NUM_PAGES)
+                                .build();
+
+                        callback.onLayoutFinished(info, false);
+
+                        // Mark layout was called.
+                        onLayoutCalled();
+                        return null;
+                    }
+                }, new Answer<Void>() {
+                    @Override
+                    public Void answer(InvocationOnMock invocation) throws Throwable {
+                        Object[] args = invocation.getArguments();
+                        PageRange[] pages = (PageRange[]) args[0];
+                        ParcelFileDescriptor fd = (ParcelFileDescriptor) args[1];
+                        WriteResultCallback callback = (WriteResultCallback) args[3];
+
+                        writeBlankPages(printAttributes[0], fd, pages[0].getStart(),
+                                pages[0].getEnd());
+                        fd.close();
+                        callback.onWriteFinished(pages);
+
+                        // Mark write was called.
+                        onWriteCalled();
+                        return null;
+                    }
+                }, new Answer<Void>() {
+                    @Override
+                    public Void answer(InvocationOnMock invocation) throws Throwable {
+                        // Mark finish was called.
+                        onFinishCalled();
+                        return null;
+                    }
+                });
+    }
+
+    private boolean isValidStatus(int status) {
+        return status == PrinterInfo.STATUS_IDLE
+                || status == PrinterInfo.STATUS_BUSY
+                || status == PrinterInfo.STATUS_UNAVAILABLE;
+    }
+
+    /**
+     * Create a mock {@link PrinterDiscoverySessionCallbacks} that discovers a printers with all
+     * possible combinations of interesting printers.
+     *
+     * @return The mock session callbacks
+     */
+    private PrinterDiscoverySessionCallbacks createFirstMockPrinterDiscoverySessionCallbacks() {
+        return createMockPrinterDiscoverySessionCallbacks(new Answer<Void>() {
+            @Override
+            public Void answer(InvocationOnMock invocation) {
+                // Get the session.
+                mDiscoverySession = ((PrinterDiscoverySessionCallbacks) invocation.getMock())
+                        .getSession();
+
+                if (mDiscoverySession.getPrinters().isEmpty()) {
+                    final int INVALID_RES_ID = 0xffffffff;
+
+                    final PrinterInfo.Builder badPrinter = new PrinterInfo.Builder(
+                            mDiscoverySession.getService().generatePrinterId("bad printer"),
+                            "badPrinter", PrinterInfo.STATUS_UNAVAILABLE);
+
+                    String[] localPrinterIds = {
+                            "Printer", null
+                    };
+
+                    String[] names = {
+                            NAMED_PRINTERS_NAME_PREFIX, "", null
+                    };
+                    int[] statusList = {
+                            PrinterInfo.STATUS_IDLE, PrinterInfo.STATUS_BUSY,
+                            PrinterInfo.STATUS_UNAVAILABLE, 0, 42
+                    };
+                    int[] iconResourceIds = {
+                            R.drawable.red_printer, 0, INVALID_RES_ID, -1
+                    };
+
+                    boolean[] hasCustomPrinterIcons = {
+                            true, false
+                    };
+
+                    String[] descriptions = {
+                            "Description", "", null
+                    };
+
+                    PendingIntent[] infoIntents = {
+                            PendingIntent.getActivity(getActivity(), 0,
+                                    new Intent(getActivity(), Activity.class),
+                                    PendingIntent.FLAG_IMMUTABLE),
+                            null
+                    };
+
+                    PrinterCapabilitiesInfo[] capabilityList = {
+                            // The printerId not used in PrinterCapabilitiesInfo
+                            new PrinterCapabilitiesInfo.Builder(mDiscoverySession.getService()
+                                    .generatePrinterId("unused"))
+                                            .setMinMargins(new Margins(200, 200, 200, 200))
+                                            .addMediaSize(MediaSize.ISO_A4, true)
+                                            .addResolution(
+                                                    new Resolution("300x300", "300x300", 300, 300),
+                                                    true)
+                                            .setColorModes(PrintAttributes.COLOR_MODE_COLOR,
+                                                    PrintAttributes.COLOR_MODE_COLOR)
+                                            .build(),
+                            null
+                    };
+
+                    List<PrinterInfo> printers = new ArrayList<PrinterInfo>();
+                    for (String localPrinterId : localPrinterIds) {
+                        for (String name : names) {
+                            for (int status : statusList) {
+                                for (int iconResourceId : iconResourceIds) {
+                                    for (boolean hasCustomPrinterIcon : hasCustomPrinterIcons) {
+                                        for (String description : descriptions) {
+                                            for (PendingIntent infoIntent : infoIntents) {
+                                                for (PrinterCapabilitiesInfo capabilities
+                                                        : capabilityList) {
+                                                    // printerId
+                                                    RuntimeException e = null;
+                                                    PrinterId printerId = null;
+                                                    try {
+                                                        if (localPrinterId == null) {
+                                                            printerId = mDiscoverySession
+                                                                    .getService()
+                                                                    .generatePrinterId(
+                                                                            localPrinterId);
+                                                        } else {
+                                                            printerId = mDiscoverySession
+                                                                    .getService()
+                                                                    .generatePrinterId(
+                                                                            localPrinterId
+                                                                                    + printers
+                                                                                            .size());
+                                                        }
+                                                    } catch (RuntimeException ex) {
+                                                        e = ex;
+                                                    }
+
+                                                    // Expect exception if localId is null
+                                                    if (localPrinterId == null) {
+                                                        if (e == null) {
+                                                            throw new IllegalStateException();
+                                                        }
+                                                    } else if (e != null) {
+                                                        throw e;
+                                                    }
+
+                                                    // Constructor
+                                                    PrinterInfo.Builder b = null;
+                                                    e = null;
+                                                    try {
+                                                        b = new PrinterInfo.Builder(
+                                                                printerId, name, status);
+                                                    } catch (RuntimeException ex) {
+                                                        e = ex;
+                                                    }
+
+                                                    // Expect exception if any of the parameters was
+                                                    // bad
+                                                    if (printerId == null
+                                                            || TextUtils.isEmpty(name)
+                                                            || !isValidStatus(status)) {
+                                                        if (e == null) {
+                                                            throw new IllegalStateException();
+                                                        } else {
+                                                            b = badPrinter;
+                                                        }
+                                                    } else if (e != null) {
+                                                        throw e;
+                                                    }
+
+                                                    // IconResourceId
+                                                    e = null;
+                                                    try {
+                                                        b.setIconResourceId(iconResourceId);
+                                                    } catch (RuntimeException ex) {
+                                                        e = ex;
+                                                    }
+
+                                                    // Expect exception if iconResourceId was bad
+                                                    // We do allow invalid Ids as the printerInfo
+                                                    // might be created after the package of the
+                                                    // printer is already gone if the printer is a
+                                                    // historical printer.
+                                                    if (iconResourceId < 0) {
+                                                        if (e == null) {
+                                                            throw new IllegalStateException();
+                                                        } else {
+                                                            b = badPrinter;
+                                                        }
+                                                    } else if (e != null) {
+                                                        throw e;
+                                                    }
+
+                                                    // Status
+                                                    e = null;
+                                                    try {
+                                                        b.setStatus(status);
+                                                    } catch (RuntimeException ex) {
+                                                        e = ex;
+                                                    }
+
+                                                    // Expect exception is status is not valid
+                                                    if (!isValidStatus(status)) {
+                                                        if (e == null) {
+                                                            throw new IllegalStateException();
+                                                        } else {
+                                                            b = badPrinter;
+                                                        }
+                                                    } else if (e != null) {
+                                                        throw e;
+                                                    }
+
+                                                    // Name
+                                                    e = null;
+                                                    try {
+                                                        b.setName(name);
+                                                    } catch (RuntimeException ex) {
+                                                        e = ex;
+                                                    }
+
+                                                    // Expect exception if name is empty
+                                                    if (TextUtils.isEmpty(name)) {
+                                                        if (e == null) {
+                                                            throw new IllegalStateException();
+                                                        } else {
+                                                            b = badPrinter;
+                                                        }
+                                                    } else if (e != null) {
+                                                        throw e;
+                                                    }
+
+                                                    // hasCustomPrinterIcon
+                                                    b.setHasCustomPrinterIcon(hasCustomPrinterIcon);
+
+                                                    // Description
+                                                    b.setDescription(description);
+
+                                                    // InfoIntent
+                                                    b.setInfoIntent(infoIntent);
+
+                                                    // Capabilities
+                                                    b.setCapabilities(capabilities);
+
+                                                    PrinterInfo printer = b.build();
+
+                                                    // Don't create bad printers
+                                                    if (b == badPrinter) {
+                                                        continue;
+                                                    }
+
+                                                    // Verify get* methods
+                                                    if (printer.getId() != printerId
+                                                            || printer.getName() != name
+                                                            || printer.getStatus() != status
+                                                            || printer
+                                                                    .getDescription() != description
+                                                            || printer.getCapabilities()
+                                                                    != capabilities) {
+                                                        throw new IllegalStateException();
+                                                    }
+
+                                                    printers.add(printer);
+                                                }
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+
+                    mDiscoverySession.addPrinters(printers);
+                }
+                return null;
+            }
+        }, null, null, new Answer<Void>() {
+            @Override
+            public Void answer(InvocationOnMock invocation) throws Throwable {
+                return null;
+            }
+        }, new Answer<Void>() {
+            @Override
+            public Void answer(InvocationOnMock invocation) throws Throwable {
+                CustomPrinterIconCallback callback = (CustomPrinterIconCallback) invocation
+                        .getArguments()[2];
+
+                if (mIcon != null) {
+                    callback.onCustomPrinterIconLoaded(mIcon);
+                }
+                return null;
+            }
+        }, null, new Answer<Void>() {
+            @Override
+            public Void answer(InvocationOnMock invocation) throws Throwable {
+                // Take a note onDestroy was called.
+                onPrinterDiscoverySessionDestroyCalled();
+                return null;
+            }
+        });
+    }
+
+    /**
+     * Create mock service callback for a session.
+     *
+     * @param sessionCallbacks The callbacks of the session
+     */
+    private PrintServiceCallbacks createFirstMockPrinterServiceCallbacks(
+            final PrinterDiscoverySessionCallbacks sessionCallbacks) {
+        return createMockPrintServiceCallbacks(
+                new Answer<PrinterDiscoverySessionCallbacks>() {
+                    @Override
+                    public PrinterDiscoverySessionCallbacks answer(InvocationOnMock invocation) {
+                        return sessionCallbacks;
+                    }
+                },
+                null, null);
+    }
+
+    /**
+     * Test that all printInfos possible can be used and that invalid printInfos throw exceptions.
+     *
+     * @throws Exception If anything is unexpected.
+     */
+    public void testPrinterInfos()
+            throws Exception {
+        if (!supportsPrinting()) {
+            return;
+        }
+        // Create the session of the printers that we will be checking.
+        PrinterDiscoverySessionCallbacks sessionCallbacks
+                = createFirstMockPrinterDiscoverySessionCallbacks();
+
+        // Create the service callbacks for the first print service.
+        PrintServiceCallbacks serviceCallbacks = createFirstMockPrinterServiceCallbacks(
+                sessionCallbacks);
+
+        // Configure the print services.
+        FirstPrintService.setCallbacks(serviceCallbacks);
+
+        // We don't use the second service, but we have to still configure it
+        SecondPrintService.setCallbacks(createMockPrintServiceCallbacks(null, null, null));
+
+        // Create a print adapter that respects the print contract.
+        PrintDocumentAdapter adapter = createMockPrintDocumentAdapter();
+
+        // Start printing.
+        print(adapter);
+
+        // Wait for write of the first page.
+        waitForWriteAdapterCallback(1);
+
+        // Open destination spinner
+        UiObject destinationSpinner = getUiDevice().findObject(new UiSelector().resourceId(
+                "com.android.printspooler:id/destination_spinner"));
+        destinationSpinner.click();
+    }
+}
diff --git a/tests/tests/print/src/android/print/cts/services/CustomPrintOptionsActivity.java b/tests/tests/print/src/android/print/cts/services/CustomPrintOptionsActivity.java
index 9d26d81..dd5ac44 100644
--- a/tests/tests/print/src/android/print/cts/services/CustomPrintOptionsActivity.java
+++ b/tests/tests/print/src/android/print/cts/services/CustomPrintOptionsActivity.java
@@ -17,12 +17,60 @@
 package android.print.cts.services;
 
 import android.app.Activity;
+import android.content.Intent;
 import android.os.Bundle;
+import android.print.PrintJobInfo;
+import android.print.PrinterInfo;
+import android.printservice.PrintService;
 
+/**
+ * Custom print options activity for both print services
+ */
 public class CustomPrintOptionsActivity extends Activity {
+    /** Lock for {@link #sCallback} */
+    private static Object sLock = new Object();
+
+    /** Currently registered callback for _both_ first and second print service. */
+    private static CustomPrintOptionsCallback sCallback = null;
+
+    /**
+     * Set a new callback called when the custom options activity is launched.
+     *
+     * @param callback The new callback or null, if the callback should be unregistered.
+     */
+    public static void setCallBack(CustomPrintOptionsCallback callback) {
+        synchronized (sLock) {
+            sCallback = callback;
+        }
+    }
+
+    /**
+     * Callback executed for this activity. Set via {@link #setCallBack}.
+     */
+    public interface CustomPrintOptionsCallback {
+        PrintJobInfo executeCustomPrintOptionsActivity(PrintJobInfo printJob,
+                PrinterInfo printer);
+    }
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
+
+        Intent result = new Intent();
+
+        synchronized (sLock) {
+            if (sCallback != null) {
+                PrintJobInfo printJobInfo = getIntent().getParcelableExtra(
+                        PrintService.EXTRA_PRINT_JOB_INFO);
+                PrinterInfo printerInfo = getIntent().getParcelableExtra(
+                        "android.intent.extra.print.EXTRA_PRINTER_INFO");
+
+                result.putExtra(PrintService.EXTRA_PRINT_JOB_INFO,
+                        sCallback.executeCustomPrintOptionsActivity(printJobInfo, printerInfo));
+            }
+        }
+
+        setResult(Activity.RESULT_OK, result);
+        finish();
     }
 }
diff --git a/tests/tests/print/src/android/print/cts/services/PrinterDiscoverySessionCallbacks.java b/tests/tests/print/src/android/print/cts/services/PrinterDiscoverySessionCallbacks.java
index 6b2c3a9..ebddda1 100644
--- a/tests/tests/print/src/android/print/cts/services/PrinterDiscoverySessionCallbacks.java
+++ b/tests/tests/print/src/android/print/cts/services/PrinterDiscoverySessionCallbacks.java
@@ -16,7 +16,9 @@
 
 package android.print.cts.services;
 
+import android.os.CancellationSignal;
 import android.print.PrinterId;
+import android.printservice.CustomPrinterIconCallback;
 
 import java.util.List;
 
@@ -40,6 +42,9 @@
 
     public abstract void onStartPrinterStateTracking(PrinterId printerId);
 
+    public abstract void onRequestCustomPrinterIcon(PrinterId printerId,
+            CancellationSignal cancellationSignal, CustomPrinterIconCallback callback);
+
     public abstract void onStopPrinterStateTracking(PrinterId printerId);
 
     public abstract void onDestroy();
diff --git a/tests/tests/print/src/android/print/cts/services/StubbablePrinterDiscoverySession.java b/tests/tests/print/src/android/print/cts/services/StubbablePrinterDiscoverySession.java
index fdc2713..b7cccaa 100644
--- a/tests/tests/print/src/android/print/cts/services/StubbablePrinterDiscoverySession.java
+++ b/tests/tests/print/src/android/print/cts/services/StubbablePrinterDiscoverySession.java
@@ -16,7 +16,9 @@
 
 package android.print.cts.services;
 
+import android.os.CancellationSignal;
 import android.print.PrinterId;
+import android.printservice.CustomPrinterIconCallback;
 import android.printservice.PrintService;
 import android.printservice.PrinterDiscoverySession;
 
@@ -68,6 +70,14 @@
     }
 
     @Override
+    public void onRequestCustomPrinterIcon(PrinterId printerId,
+            CancellationSignal cancellationSignal, CustomPrinterIconCallback callback) {
+        if (mCallbacks != null) {
+            mCallbacks.onRequestCustomPrinterIcon(printerId, cancellationSignal, callback);
+        }
+    }
+
+    @Override
     public void onStopPrinterStateTracking(PrinterId printerId) {
         if (mCallbacks != null) {
             mCallbacks.onStopPrinterStateTracking(printerId);
diff --git a/tests/tests/provider/Android.mk b/tests/tests/provider/Android.mk
index 58a7516..59fb9f6 100644
--- a/tests/tests/provider/Android.mk
+++ b/tests/tests/provider/Android.mk
@@ -25,11 +25,17 @@
 # and when built explicitly put it in the data partition
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_CTS_MODULE_CONFIG := $(LOCAL_PATH)/Old$(CTS_MODULE_TEST_CONFIG)
+
 LOCAL_JAVA_LIBRARIES := android.test.runner telephony-common
 
-LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctstestrunner
+LOCAL_STATIC_JAVA_LIBRARIES := \
+    ctsdeviceutil ctstestrunner platform-test-annotations
 
-LOCAL_JNI_SHARED_LIBRARIES := libcts_jni
+LOCAL_JNI_SHARED_LIBRARIES := libcts_jni libnativehelper_compat_libc++
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
diff --git a/tests/tests/provider/AndroidManifest.xml b/tests/tests/provider/AndroidManifest.xml
index ed180f6..aadddb5 100644
--- a/tests/tests/provider/AndroidManifest.xml
+++ b/tests/tests/provider/AndroidManifest.xml
@@ -16,14 +16,13 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.cts.provider">
+          package="android.provider.cts">
 
     <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="21" />
 
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD"/>
     <uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
     <uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
-    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
     <uses-permission android:name="android.permission.USE_CREDENTIALS" />
     <uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
     <uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
@@ -37,6 +36,9 @@
     <uses-permission android:name="android.permission.WRITE_CONTACTS" />
     <uses-permission android:name="android.permission.READ_CALL_LOG" />
     <uses-permission android:name="android.permission.READ_CONTACTS" />
+    <uses-permission android:name="android.permission.READ_SMS" />
+    <uses-permission android:name="android.permission.WRITE_SMS" />
+
 
     <application>
         <uses-library android:name="android.test.runner"/>
@@ -50,7 +52,7 @@
         </activity>
 
         <service android:name="android.provider.cts.contacts.account.MockAccountService"
-                 process="com.android.cts.provider"
+                 process="android.provider.cts"
                  android:exported="true">
             <intent-filter>
                 <action android:name="android.accounts.AccountAuthenticator"/>
@@ -72,14 +74,14 @@
     </application>
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.cts.provider"
+                     android:targetPackage="android.provider.cts"
                      android:label="CTS tests of android.provider">
         <meta-data android:name="listener"
             android:value="com.android.cts.runner.CtsTestRunListener" />
     </instrumentation>
 
     <instrumentation android:name="android.provider.cts.CalendarTest$CalendarEmmaTestRunner"
-                     android:targetPackage="com.android.cts.provider"
+                     android:targetPackage="android.provider.cts"
                      android:label="Augmented CTS tests of Calendar provider"/>
 
 </manifest>
diff --git a/tests/tests/provider/AndroidTest.xml b/tests/tests/provider/AndroidTest.xml
index ae603a3..4c87f9c 100644
--- a/tests/tests/provider/AndroidTest.xml
+++ b/tests/tests/provider/AndroidTest.xml
@@ -1,22 +1,25 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2015 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-<configuration description="Test module config for provider">
-    <include name="common-config" />
-    <option name="cts-apk-installer:test-file-name" value="CtsProviderTestCases.apk" />
-    <option name="run-command:run-command"
-            value="ime enable com.android.cts.provider/.MockInputMethodService" />
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS Provider test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsProviderTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.provider.cts" />
+        <option name="runtime-hint" value="7m19s" />
+    </test>
 </configuration>
\ No newline at end of file
diff --git a/tests/tests/provider/OldAndroidTest.xml b/tests/tests/provider/OldAndroidTest.xml
new file mode 100644
index 0000000..bd22d8f
--- /dev/null
+++ b/tests/tests/provider/OldAndroidTest.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2015 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<configuration description="Test module config for provider">
+    <include name="common-config" />
+    <option name="run-command:run-command"
+            value="ime enable android.provider.cts/.MockInputMethodService" />
+</configuration>
diff --git a/tests/tests/provider/src/android/provider/cts/BlockedNumberBackupRestoreTest.java b/tests/tests/provider/src/android/provider/cts/BlockedNumberBackupRestoreTest.java
new file mode 100644
index 0000000..adf558b
--- /dev/null
+++ b/tests/tests/provider/src/android/provider/cts/BlockedNumberBackupRestoreTest.java
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.provider.cts;
+
+import android.app.UiAutomation;
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.provider.BlockedNumberContract;
+import android.telecom.Log;
+
+/**
+ * CTS tests for backup and restore of blocked numbers using local transport.
+ */
+// To run the tests in this file w/o running all the cts tests:
+// make cts
+// cts-tradefed
+// run cts -m CtsProviderTestCases --test android.provider.cts.BlockedNumberBackupRestoreTest
+public class BlockedNumberBackupRestoreTest extends TestCaseThatRunsIfTelephonyIsEnabled {
+    private static final String TAG = "BlockedNumberBackupRestoreTest";
+    private static final String LOCAL_BACKUP_COMPONENT =
+            "android/com.android.internal.backup.LocalTransport";
+    private static final String BLOCKED_NUMBERS_PROVIDER_PACKAGE =
+            "com.android.providers.blockednumber";
+
+    private ContentResolver mContentResolver;
+    private Context mContext;
+    private UiAutomation mUiAutomation;
+    private String mOldTransport;
+    private boolean mOldBackupEnabled;
+    private boolean mHasFeature;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        mContext = getInstrumentation().getContext();
+        mContentResolver = mContext.getContentResolver();
+        mUiAutomation = getInstrumentation().getUiAutomation();
+
+        mHasFeature = isFeatureSupported();
+
+        if (mHasFeature) {
+            ProviderTestUtils.setDefaultSmsApp(true, mContext.getPackageName(), mUiAutomation);
+
+            mOldTransport = ProviderTestUtils.setBackupTransport(
+                    LOCAL_BACKUP_COMPONENT, mUiAutomation);
+            mOldBackupEnabled = ProviderTestUtils.setBackupEnabled(true, mUiAutomation);
+            clearBlockedNumbers();
+            wipeBackup();
+        }
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        if (mHasFeature) {
+            wipeBackup();
+            clearBlockedNumbers();
+            ProviderTestUtils.setBackupEnabled(mOldBackupEnabled, mUiAutomation);
+            ProviderTestUtils.setBackupTransport(mOldTransport, mUiAutomation);
+            ProviderTestUtils.setDefaultSmsApp(false, mContext.getPackageName(), mUiAutomation);
+        }
+
+        super.tearDown();
+    }
+
+    public void testBackupAndRestoreForSingleNumber() throws Exception {
+        if (!mHasFeature) {
+            Log.i(TAG, "skipping BlockedNumberBackupRestoreTest");
+            return;
+        }
+
+        Log.i(TAG, "Adding blocked numbers.");
+        insertBlockedNumber("123456789");
+
+        Log.i(TAG, "Running backup.");
+        runBackup();
+
+        Log.i(TAG, "Clearing blocked numbers.");
+        clearBlockedNumbers();
+        verifyBlockedNumbers();
+
+        Log.i(TAG, "Restoring blocked numbers.");
+        runRestore();
+        verifyBlockedNumbers("123456789");
+    }
+
+    public void testBackupAndRestoreWithDeletion() throws Exception {
+        if (!mHasFeature) {
+            Log.i(TAG, "skipping BlockedNumberBackupRestoreTest");
+            return;
+        }
+
+        Log.i(TAG, "Adding blocked numbers.");
+        insertBlockedNumber("123456789");
+        insertBlockedNumber("223456789");
+        insertBlockedNumber("323456789");
+
+        Log.i(TAG, "Running backup.");
+        runBackup();
+
+        Log.i(TAG, "Deleting blocked number.");
+        deleteNumber("123456789");
+        verifyBlockedNumbers("223456789", "323456789");
+
+        Log.i(TAG, "Running backup.");
+        runBackup();
+
+        Log.i(TAG, "Clearing blocked numbers.");
+        clearBlockedNumbers();
+        verifyBlockedNumbers();
+
+        Log.i(TAG, "Restoring blocked numbers.");
+        runRestore();
+        verifyBlockedNumbers("223456789", "323456789");
+    }
+
+    private boolean isFeatureSupported() throws Exception {
+        return ProviderTestUtils.hasBackupTransport(LOCAL_BACKUP_COMPONENT, mUiAutomation)
+                && mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
+    }
+
+    private void insertBlockedNumber(String number) {
+        ContentValues cv = new ContentValues();
+        cv.put(BlockedNumberContract.BlockedNumbers.COLUMN_ORIGINAL_NUMBER, number);
+        mContentResolver.insert(BlockedNumberContract.BlockedNumbers.CONTENT_URI, cv);
+    }
+
+    private void deleteNumber(String number) {
+        assertEquals(1,
+                mContentResolver.delete(
+                        BlockedNumberContract.BlockedNumbers.CONTENT_URI,
+                        BlockedNumberContract.BlockedNumbers.COLUMN_ORIGINAL_NUMBER + "= ?",
+                        new String[] {number}));
+    }
+
+    private void verifyBlockedNumbers(String ... blockedNumbers) {
+        assertEquals(blockedNumbers.length,
+                mContentResolver.query(
+                        BlockedNumberContract.BlockedNumbers.CONTENT_URI, null, null, null, null)
+                        .getCount());
+        for (String blockedNumber : blockedNumbers) {
+            assertTrue(BlockedNumberContract.isBlocked(mContext, blockedNumber));
+        }
+    }
+
+    private void clearBlockedNumbers() {
+        mContentResolver.delete(BlockedNumberContract.BlockedNumbers.CONTENT_URI, null, null);
+    }
+
+    private void runBackup() throws Exception {
+        ProviderTestUtils.runBackup(BLOCKED_NUMBERS_PROVIDER_PACKAGE, mUiAutomation);
+    }
+
+    private void runRestore() throws Exception {
+        ProviderTestUtils.runRestore(BLOCKED_NUMBERS_PROVIDER_PACKAGE, mUiAutomation);
+    }
+
+    private void wipeBackup() throws Exception {
+        ProviderTestUtils.wipeBackup(LOCAL_BACKUP_COMPONENT, BLOCKED_NUMBERS_PROVIDER_PACKAGE,
+                mUiAutomation);
+    }
+}
diff --git a/tests/tests/provider/src/android/provider/cts/BlockedNumberContractTest.java b/tests/tests/provider/src/android/provider/cts/BlockedNumberContractTest.java
new file mode 100644
index 0000000..4ef28f4
--- /dev/null
+++ b/tests/tests/provider/src/android/provider/cts/BlockedNumberContractTest.java
@@ -0,0 +1,353 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.provider.cts;
+
+import android.annotation.Nullable;
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.ContentObserver;
+import android.database.Cursor;
+import android.net.Uri;
+import android.provider.BlockedNumberContract;
+import android.provider.BlockedNumberContract.BlockedNumbers;
+
+import junit.framework.Assert;
+
+import java.util.ArrayList;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * CTS tests for blockednumber provider accessed through {@link BlockedNumberContract}.
+ */
+// To run the tests in this file w/o running all the cts tests:
+// make cts
+// cts-tradefed
+// run cts -m CtsProviderTestCases --test android.provider.cts.BlockedNumberContractTest
+public class BlockedNumberContractTest extends TestCaseThatRunsIfTelephonyIsEnabled {
+    private ContentResolver mContentResolver;
+    private Context mContext;
+    private ArrayList<Uri> mAddedUris;
+
+    private static final String[] BLOCKED_NUMBERS_PROJECTION = new String[]{
+            BlockedNumbers.COLUMN_ORIGINAL_NUMBER,
+            BlockedNumbers.COLUMN_E164_NUMBER};
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mContext = getInstrumentation().getContext();
+        mContentResolver = mContext.getContentResolver();
+        mAddedUris = new ArrayList<>();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        for (Uri row : mAddedUris) {
+            mContentResolver.delete(row, null, null);
+        }
+        mAddedUris.clear();
+        setDefaultSmsApp(false);
+
+        super.tearDown();
+    }
+
+    public void testProviderInteractionsAsRegularApp_fails() {
+        try {
+            mAddedUris.add(mContentResolver.insert(
+                    BlockedNumbers.CONTENT_URI, getContentValues("1234567890")));
+            fail("Should throw SecurityException");
+        } catch (SecurityException expected) {
+        }
+
+        try {
+            mContentResolver.query(BlockedNumbers.CONTENT_URI, null, null, null, null);
+            fail("Should throw SecurityException");
+        } catch (SecurityException expected) {
+        }
+
+        try {
+            mContentResolver.update(
+                    BlockedNumbers.CONTENT_URI, getContentValues("123"), null, null);
+            fail("Should throw SecurityException");
+        } catch (SecurityException expected) {
+        }
+
+        try {
+            BlockedNumberContract.isBlocked(mContext, "123");
+            fail("Should throw SecurityException");
+        } catch (SecurityException expected) {
+        }
+
+        try {
+            BlockedNumberContract.unblock(mContext, "1234567890");
+            fail("Should throw SecurityException");
+        } catch (SecurityException expected) {
+        }
+
+        assertTrue(BlockedNumberContract.canCurrentUserBlockNumbers(mContext));
+    }
+
+    public void testGetType() throws Exception {
+        assertEquals(BlockedNumbers.CONTENT_TYPE,
+                mContentResolver.getType(BlockedNumbers.CONTENT_URI));
+        assertEquals(BlockedNumbers.CONTENT_ITEM_TYPE,
+                mContentResolver.getType(
+                        ContentUris.withAppendedId(BlockedNumbers.CONTENT_URI, 0)));
+
+        assertNull(mContentResolver.getType(BlockedNumberContract.AUTHORITY_URI));
+    }
+
+    public void testInsertAndBlockCheck_succeeds() throws Exception {
+        setDefaultSmsApp(true);
+
+        assertTrue(BlockedNumberContract.canCurrentUserBlockNumbers(mContext));
+
+        assertInsertBlockedNumberSucceeds("1234567890", null);
+        // Attempting to insert a duplicate replaces the existing entry.
+        assertInsertBlockedNumberSucceeds("1234567890", "+812345678901");
+        assertInsertBlockedNumberSucceeds("1234567890", null);
+
+        assertTrue(BlockedNumberContract.isBlocked(mContext, "1234567890"));
+        assertFalse(BlockedNumberContract.isBlocked(mContext, "2234567890"));
+
+        assertInsertBlockedNumberSucceeds("2345678901", "+12345678901");
+        assertTrue(BlockedNumberContract.isBlocked(mContext, "2345678901"));
+        assertTrue(BlockedNumberContract.isBlocked(mContext, "+12345678901"));
+
+        assertInsertBlockedNumberSucceeds("1234@abcd.com", null);
+        assertTrue(BlockedNumberContract.isBlocked(mContext, "1234@abcd.com"));
+
+        assertInsertBlockedNumberSucceeds("2345@abcd.com", null);
+        assertTrue(BlockedNumberContract.isBlocked(mContext, "2345@abcd.com"));
+
+        assertFalse(BlockedNumberContract.isBlocked(mContext, "9999@abcd.com"));
+        assertFalse(BlockedNumberContract.isBlocked(mContext, "random string"));
+    }
+
+    public void testUnblock_succeeds() throws Exception {
+        setDefaultSmsApp(true);
+
+        // Unblocking non-existent blocked number should return 0.
+        assertEquals(0, BlockedNumberContract.unblock(mContext, "6501004000"));
+
+        assertInsertBlockedNumberSucceeds("6501004000", null);
+        assertEquals(1, BlockedNumberContract.unblock(mContext, "6501004000"));
+        assertFalse(BlockedNumberContract.isBlocked(mContext, "(650)1004000"));
+
+        assertInsertBlockedNumberSucceeds("1234@abcd.com", null);
+        assertEquals(1, BlockedNumberContract.unblock(mContext, "1234@abcd.com"));
+        assertFalse(BlockedNumberContract.isBlocked(mContext, "1234@abcd.com"));
+    }
+
+    public void testInsert_failsWithInvalidInputs() throws Exception {
+        setDefaultSmsApp(true);
+
+        try {
+            ContentValues cv = new ContentValues();
+            cv.put(BlockedNumbers.COLUMN_ORIGINAL_NUMBER, "1234");
+            mAddedUris.add(mContentResolver.insert(
+                    ContentUris.withAppendedId(BlockedNumbers.CONTENT_URI, 1),
+                    new ContentValues()));
+            fail("Should throw IllegalArgumentException.");
+        } catch (IllegalArgumentException expected) {
+            assertTrue(expected.getMessage().contains("Unsupported URI"));
+        }
+
+        try {
+            mAddedUris.add(
+                    mContentResolver.insert(BlockedNumbers.CONTENT_URI, new ContentValues()));
+            fail("Should throw IllegalArgumentException.");
+        } catch (IllegalArgumentException expected) {
+            assertTrue(expected.getMessage().contains("Missing a required column"));
+        }
+
+        try {
+            ContentValues cv = new ContentValues();
+            cv.put(BlockedNumbers.COLUMN_E164_NUMBER, "+1234");
+            mAddedUris.add(mContentResolver.insert(BlockedNumbers.CONTENT_URI, cv));
+            fail("Should throw IllegalArgumentException.");
+        } catch (IllegalArgumentException expected) {
+            assertTrue(expected.getMessage().contains("Missing a required column"));
+        }
+
+        try {
+            ContentValues cv = new ContentValues();
+            cv.put(BlockedNumbers.COLUMN_ID, "1");
+            mAddedUris.add(mContentResolver.insert(BlockedNumbers.CONTENT_URI, cv));
+            fail("Should throw IllegalArgumentException.");
+        } catch (IllegalArgumentException expected) {
+            assertTrue(expected.getMessage().contains("must not be specified"));
+        }
+    }
+
+    public void testUpdate_isUnsupported() throws  Exception {
+        setDefaultSmsApp(true);
+        try {
+            mContentResolver.update(
+                    BlockedNumbers.CONTENT_URI, getContentValues("123"), null, null);
+            fail("Should throw UnsupportedOperationException");
+        } catch (UnsupportedOperationException expected) {
+        }
+    }
+
+    public void testIsBlocked_returnsFalseForNullAndEmpty() throws Exception {
+        setDefaultSmsApp(true);
+        assertFalse(BlockedNumberContract.isBlocked(mContext, null));
+        assertFalse(BlockedNumberContract.isBlocked(mContext, ""));
+    }
+
+    public void testDelete() throws Exception {
+        setDefaultSmsApp(true);
+
+        assertInsertBlockedNumberSucceeds("12345", "+112345");
+        assertInsertBlockedNumberSucceeds("012345", "+112345");
+        assertEquals(2,
+                mContentResolver.delete(
+                        BlockedNumbers.CONTENT_URI,
+                        BlockedNumbers.COLUMN_E164_NUMBER + "= ?",
+                        new String[] {"+112345"}));
+
+        assertInsertBlockedNumberSucceeds("12345", "");
+        assertEquals(1,
+                mContentResolver.delete(
+                        BlockedNumbers.CONTENT_URI,
+                        BlockedNumbers.COLUMN_ORIGINAL_NUMBER + "= ?",
+                        new String[] {"12345"}));
+
+        Uri insertedUri = assertInsertBlockedNumberSucceeds("12345", "");
+        assertEquals(1,
+                mContentResolver.delete(
+                        BlockedNumbers.CONTENT_URI,
+                        BlockedNumbers.COLUMN_ID + "= ?",
+                        new String[] {Long.toString(ContentUris.parseId(insertedUri))}));
+
+        insertedUri = assertInsertBlockedNumberSucceeds("12345", "");
+        assertEquals(1,
+                mContentResolver.delete(
+                        ContentUris.withAppendedId(
+                                BlockedNumbers.CONTENT_URI, ContentUris.parseId(insertedUri)),
+                        null, null));
+
+        insertedUri = assertInsertBlockedNumberSucceeds("12345", "");
+        assertEquals(1, mContentResolver.delete(insertedUri, null, null));
+
+        assertEquals(0,
+                mContentResolver.delete(
+                        BlockedNumbers.CONTENT_URI,
+                        BlockedNumbers.COLUMN_ORIGINAL_NUMBER + "= ?",
+                        new String[] {"12345"}));
+    }
+
+    public void testDelete_failsOnInvalidInputs() throws Exception {
+        setDefaultSmsApp(true);
+
+        try {
+            mContentResolver.delete(Uri.parse("foobar"), null, null);
+            fail("Should throw IllegalArgumentException");
+        } catch (IllegalArgumentException expected) {
+        }
+
+        Uri insertedUri = assertInsertBlockedNumberSucceeds("12345", "");
+        try {
+            mContentResolver.delete(
+                    insertedUri,
+                    BlockedNumbers.COLUMN_E164_NUMBER + "= ?",
+                    new String[] {"+112345"});
+            fail("Should throw IllegalArgumentException");
+        } catch (IllegalArgumentException expected) {
+            assertTrue(expected.getMessage().contains("selection must be null"));
+        }
+    }
+
+    public void testProviderNotifiesChangesUsingContentObserver() throws Exception {
+        setDefaultSmsApp(true);
+
+        Cursor cursor = mContentResolver.query(BlockedNumbers.CONTENT_URI, null, null, null, null);
+
+        final CountDownLatch latch = new CountDownLatch(2);
+        ContentObserver contentObserver = new ContentObserver(null) {
+            @Override
+            public void onChange(boolean selfChange) {
+                Assert.assertFalse(selfChange);
+                latch.notify();
+            }
+        };
+        cursor.registerContentObserver(contentObserver);
+
+        try {
+            Uri uri = assertInsertBlockedNumberSucceeds("12345", "");
+            mContentResolver.delete(uri, null, null);
+            latch.await(10, TimeUnit.SECONDS);
+        } catch (Exception e) {
+            fail(e.toString());
+        } finally {
+            cursor.unregisterContentObserver(contentObserver);
+        }
+    }
+
+    public void testAccessingNonExistentMethod_fails() throws Exception {
+        setDefaultSmsApp(true);
+
+        try {
+            mContext.getContentResolver()
+                    .call(BlockedNumberContract.AUTHORITY_URI, "nonExistentMethod", "1234", null);
+            fail("Should throw IllegalArgumentException");
+        } catch (IllegalArgumentException expected) {
+            assertTrue(expected.getMessage().contains("Unsupported method"));
+        }
+    }
+
+    private Uri assertInsertBlockedNumberSucceeds(
+            String originalNumber, @Nullable String e164Number) {
+        ContentValues cv = new ContentValues();
+        cv.put(BlockedNumbers.COLUMN_ORIGINAL_NUMBER, originalNumber);
+        if (e164Number != null) {
+            cv.put(BlockedNumbers.COLUMN_E164_NUMBER, e164Number);
+        }
+        Uri insertedUri = mContentResolver.insert(BlockedNumbers.CONTENT_URI, cv);
+        mAddedUris.add(insertedUri);
+
+        Cursor cursor = mContentResolver.query(
+                BlockedNumbers.CONTENT_URI,
+                BLOCKED_NUMBERS_PROJECTION,
+                BlockedNumbers.COLUMN_ORIGINAL_NUMBER + "= ?",
+                new String[]{originalNumber},
+                null);
+        assertTrue(cursor.moveToFirst());
+
+        assertEquals(originalNumber, cursor.getString(0));
+        if (e164Number != null) {
+            assertEquals(e164Number, cursor.getString(1));
+        }
+        cursor.close();
+        return insertedUri;
+    }
+
+    private ContentValues getContentValues(String originalNumber) {
+        ContentValues cv = new ContentValues();
+        cv.put(BlockedNumbers.COLUMN_ORIGINAL_NUMBER, originalNumber);
+        return cv;
+    }
+
+    private void setDefaultSmsApp(boolean setToSmsApp) throws Exception {
+        ProviderTestUtils.setDefaultSmsApp(
+                setToSmsApp, mContext.getPackageName(), getInstrumentation().getUiAutomation());
+    }
+}
diff --git a/tests/tests/provider/src/android/provider/cts/CalendarTest.java b/tests/tests/provider/src/android/provider/cts/CalendarTest.java
index c9e2213..df31a19 100644
--- a/tests/tests/provider/src/android/provider/cts/CalendarTest.java
+++ b/tests/tests/provider/src/android/provider/cts/CalendarTest.java
@@ -3279,7 +3279,7 @@
     @MediumTest
     public void testMutatorSetCorrectly() {
         String account = "ec_account";
-        String packageName = "com.android.cts.provider";
+        String packageName = "android.provider.cts";
         int seed = 0;
 
         // Clean up just in case
diff --git a/tests/tests/provider/src/android/provider/cts/ContactsContract_CommonDataKinds_OrganizationTest.java b/tests/tests/provider/src/android/provider/cts/ContactsContract_CommonDataKinds_OrganizationTest.java
index 2de3b05..fa83d4f 100644
--- a/tests/tests/provider/src/android/provider/cts/ContactsContract_CommonDataKinds_OrganizationTest.java
+++ b/tests/tests/provider/src/android/provider/cts/ContactsContract_CommonDataKinds_OrganizationTest.java
@@ -16,9 +16,12 @@
 
 package android.provider.cts;
 
+import junit.framework.Assert;
+
 import android.content.res.Resources;
 import android.provider.ContactsContract.CommonDataKinds.Im;
 import android.provider.ContactsContract.CommonDataKinds.Organization;
+import android.provider.ContactsContract.Data;
 import android.test.AndroidTestCase;
 
 public class ContactsContract_CommonDataKinds_OrganizationTest extends AndroidTestCase {
@@ -51,4 +54,10 @@
         assertTrue(res != 0);
         assertEquals(label, Organization.getTypeLabel(mResources, Im.TYPE_CUSTOM, label));
     }
+
+    public void testPhoneticNameStyleColumnName() throws Exception {
+        // Make sure the column name is data10 and not phonetic_name_style
+        // from the parent class.
+        assertEquals(Data.DATA10, Organization.PHONETIC_NAME_STYLE);
+    }
 }
diff --git a/tests/tests/provider/src/android/provider/cts/ContactsContract_PhoneLookup.java b/tests/tests/provider/src/android/provider/cts/ContactsContract_PhoneLookup.java
index 434ac201..556fb2d 100644
--- a/tests/tests/provider/src/android/provider/cts/ContactsContract_PhoneLookup.java
+++ b/tests/tests/provider/src/android/provider/cts/ContactsContract_PhoneLookup.java
@@ -23,6 +23,7 @@
 import android.provider.ContactsContract;
 import android.provider.ContactsContract.CommonDataKinds.Email;
 import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.provider.ContactsContract.CommonDataKinds.SipAddress;
 import android.provider.ContactsContract.CommonDataKinds.StructuredName;
 import android.provider.ContactsContract.Contacts;
 import android.provider.ContactsContract.PhoneLookup;
@@ -60,7 +61,17 @@
         mBuilder.cleanup();
     }
 
-    private long[] setupTestData() throws Exception {
+    static class Id {
+        public long contactId;
+        public long dataId;
+
+        public Id (long contactId, long dataId) {
+            this.contactId = contactId;
+            this.dataId = dataId;
+        }
+    }
+
+    private Id[] setupTestData() throws Exception {
         TestRawContact rawContact = mBuilder.newRawContact()
                 .with(RawContacts.ACCOUNT_TYPE, "test_account")
                 .with(RawContacts.ACCOUNT_NAME, "test_name")
@@ -68,7 +79,7 @@
         rawContact.newDataRow(StructuredName.CONTENT_ITEM_TYPE)
                 .with(StructuredName.DISPLAY_NAME, "Hot Tamale")
                 .insert();
-        rawContact.newDataRow(Phone.CONTENT_ITEM_TYPE)
+        long dataId = rawContact.newDataRow(Phone.CONTENT_ITEM_TYPE)
                 .with(Phone.DATA, "1111222333444")
                 .with(Email.TYPE, Phone.TYPE_HOME)
                 .insert().load().getId();
@@ -82,24 +93,41 @@
         rawContact2.newDataRow(StructuredName.CONTENT_ITEM_TYPE)
                 .with(StructuredName.DISPLAY_NAME, "Cold Tamago")
                 .insert();
-        rawContact2.newDataRow(Phone.CONTENT_ITEM_TYPE)
+       long dataId2 =  rawContact2.newDataRow(Phone.CONTENT_ITEM_TYPE)
                 .with(Phone.DATA, "2111222333444")
                 .with(Phone.TYPE, Phone.TYPE_OTHER)
-                .insert().load();
-
+                .insert().load().getId();
         rawContact2.load();
         TestContact contact2 = rawContact2.getContact().load();
 
-        return new long[] {
-                contact.getId(), contact2.getId()
+        // Contact with SIP address
+        TestRawContact rawContact3 = mBuilder.newRawContact()
+                .with(RawContacts.ACCOUNT_TYPE, "test_account")
+                .with(RawContacts.ACCOUNT_NAME, "test_name")
+                .insert();
+        rawContact3.newDataRow(StructuredName.CONTENT_ITEM_TYPE)
+                .with(StructuredName.DISPLAY_NAME, "Warm Tempura")
+                .insert();
+        long dataId3 = rawContact2.newDataRow(SipAddress.CONTENT_ITEM_TYPE)
+                .with(SipAddress.SIP_ADDRESS, "777@sip.org")
+                .with(SipAddress.TYPE, SipAddress.TYPE_WORK)
+                .insert().load().getId();
+        rawContact3.load();
+        TestContact contact3 = rawContact2.getContact().load();
+
+        return new Id[] {
+                new Id(contact.getId(), dataId),
+                new Id(contact2.getId(), dataId2),
+                new Id(contact3.getId(), dataId3)
         };
+
     }
 
     /**
      * Test for {@link android.provider.ContactsContract.PhoneLookup#CONTENT_FILTER_URI}.
      */
     public void testPhoneLookup_nomatch() throws Exception {
-        long[] ids = setupTestData();
+        Id[] ids = setupTestData();
         final Uri uri = PhoneLookup.CONTENT_FILTER_URI.buildUpon()
                 .appendPath("no-such-phone-number").build();
 
@@ -110,12 +138,14 @@
      * Test for {@link android.provider.ContactsContract.PhoneLookup#CONTENT_FILTER_URI}.
      */
     public void testPhoneLookup_found1() throws Exception {
-        long[] ids = setupTestData();
+        Id[] ids = setupTestData();
         final Uri uri = PhoneLookup.CONTENT_FILTER_URI.buildUpon()
                 .appendPath("1111222333444").build();
 
         final ContentValues expected = new ContentValues();
-        expected.put(PhoneLookup._ID, ids[0]);
+        expected.put(PhoneLookup._ID, ids[0].contactId);
+        expected.put(PhoneLookup.CONTACT_ID, ids[0].contactId);
+        expected.put(PhoneLookup.DATA_ID, ids[0].dataId);
         expected.put(PhoneLookup.NUMBER, "1111222333444");
 
         assertCursorStoredValuesWithContactsFilter(uri, ids, expected);
@@ -125,22 +155,39 @@
      * Test for {@link android.provider.ContactsContract.PhoneLookup#CONTENT_FILTER_URI}.
      */
     public void testPhoneLookup_found2() throws Exception {
-        long[] ids = setupTestData();
+        Id[] ids = setupTestData();
         final Uri uri = PhoneLookup.CONTENT_FILTER_URI.buildUpon()
                 .appendPath("2111222333444").build();
 
         final ContentValues expected = new ContentValues();
-        expected.put(PhoneLookup._ID, ids[1]);
+        expected.put(PhoneLookup._ID, ids[1].contactId);
+        expected.put(PhoneLookup.CONTACT_ID, ids[1].contactId);
+        expected.put(PhoneLookup.DATA_ID, ids[1].dataId);
         expected.put(PhoneLookup.NUMBER, "2111222333444");
 
         assertCursorStoredValuesWithContactsFilter(uri, ids, expected);
     }
 
+    public void testPhoneLookup_sip_found() throws Exception {
+        Id[] ids = setupTestData();
+        final Uri uri = PhoneLookup.CONTENT_FILTER_URI.buildUpon()
+                .appendPath("777@sip.org")
+                .appendQueryParameter(PhoneLookup.QUERY_PARAMETER_SIP_ADDRESS, "1")
+                .build();
+
+        final ContentValues expected = new ContentValues();
+        expected.put(PhoneLookup.CONTACT_ID, ids[2].contactId);
+        expected.put(PhoneLookup.DATA_ID, ids[2].dataId);
+        expected.put(SipAddress.SIP_ADDRESS, "777@sip.org");
+
+        assertCursorStoredValuesWithContactsFilter(uri, ids, expected);
+    }
+
     /**
      * Test for {@link android.provider.ContactsContract.PhoneLookup#ENTERPRISE_CONTENT_FILTER_URI}.
      */
     public void testPhoneLookupEnterprise_nomatch() throws Exception {
-        long[] ids = setupTestData();
+        Id[] ids = setupTestData();
         final Uri uri = PhoneLookup.ENTERPRISE_CONTENT_FILTER_URI.buildUpon()
                 .appendPath("no-such-phone-number").build();
 
@@ -151,12 +198,14 @@
      * Test for {@link android.provider.ContactsContract.PhoneLookup#ENTERPRISE_CONTENT_FILTER_URI}.
      */
     public void testPhoneLookupEnterprise_found1() throws Exception {
-        long[] ids = setupTestData();
+        Id[] ids = setupTestData();
         final Uri uri = PhoneLookup.ENTERPRISE_CONTENT_FILTER_URI.buildUpon()
                 .appendPath("1111222333444").build();
 
         final ContentValues expected = new ContentValues();
-        expected.put(PhoneLookup._ID, ids[0]);
+        expected.put(PhoneLookup._ID, ids[0].contactId);
+        expected.put(PhoneLookup.CONTACT_ID, ids[0].contactId);
+        expected.put(PhoneLookup.DATA_ID, ids[0].dataId);
         expected.put(PhoneLookup.NUMBER, "1111222333444");
 
         assertCursorStoredValuesWithContactsFilter(uri, ids, expected);
@@ -166,27 +215,45 @@
      * Test for {@link android.provider.ContactsContract.PhoneLookup#ENTERPRISE_CONTENT_FILTER_URI}.
      */
     public void testPhoneLookupEnterprise_found2() throws Exception {
-        long[] ids = setupTestData();
+        Id[] ids = setupTestData();
         final Uri uri = PhoneLookup.ENTERPRISE_CONTENT_FILTER_URI.buildUpon()
                 .appendPath("2111222333444").build();
 
         final ContentValues expected = new ContentValues();
-        expected.put(PhoneLookup._ID, ids[1]);
+        expected.put(PhoneLookup._ID, ids[1].contactId);
+        expected.put(PhoneLookup.CONTACT_ID, ids[1].contactId);
+        expected.put(PhoneLookup.DATA_ID, ids[1].dataId);
         expected.put(PhoneLookup.NUMBER, "2111222333444");
 
         assertCursorStoredValuesWithContactsFilter(uri, ids, expected);
     }
 
-    private void assertCursorStoredValuesWithContactsFilter(Uri uri, long[] contactsId,
+    public void testPhoneLookupEnterprise_sip_found() throws Exception {
+        Id[] ids = setupTestData();
+        final Uri uri = PhoneLookup.ENTERPRISE_CONTENT_FILTER_URI.buildUpon()
+                .appendPath("777@sip.org")
+                .appendQueryParameter(PhoneLookup.QUERY_PARAMETER_SIP_ADDRESS, "1")
+                .build();
+
+        final ContentValues expected = new ContentValues();
+        expected.put(PhoneLookup._ID, ids[2].dataId);
+        expected.put(PhoneLookup.CONTACT_ID, ids[2].contactId);
+        expected.put(PhoneLookup.DATA_ID, ids[2].dataId);
+        expected.put(SipAddress.SIP_ADDRESS, "777@sip.org");
+
+        assertCursorStoredValuesWithContactsFilter(uri, ids, expected);
+    }
+
+    private void assertCursorStoredValuesWithContactsFilter(Uri uri, Id[] ids,
             ContentValues... expected) {
         // We need this helper function to add a filter for specific contacts because
         // otherwise tests will fail if performed on a device with existing contacts data
         StringBuilder sb = new StringBuilder();
         sb.append(Contacts._ID + " in ");
         sb.append("(");
-        for (int i = 0; i < contactsId.length; i++) {
+        for (int i = 0; i < ids.length; i++) {
             if (i != 0) sb.append(",");
-            sb.append(contactsId[i]);
+            sb.append(ids[i].contactId);
         }
         sb.append(")");
         DatabaseAsserts.assertStoredValuesInUriMatchExactly(mResolver, uri, null,
diff --git a/tests/tests/provider/src/android/provider/cts/ContactsContract_StatusUpdatesTest.java b/tests/tests/provider/src/android/provider/cts/ContactsContract_StatusUpdatesTest.java
index 2f3cdeb..375d7b2 100644
--- a/tests/tests/provider/src/android/provider/cts/ContactsContract_StatusUpdatesTest.java
+++ b/tests/tests/provider/src/android/provider/cts/ContactsContract_StatusUpdatesTest.java
@@ -33,7 +33,7 @@
 
 public class ContactsContract_StatusUpdatesTest extends AndroidTestCase {
 
-    private static final String ACCOUNT_TYPE = "com.android.cts.provider";
+    private static final String ACCOUNT_TYPE = "android.provider.cts";
     private static final String ACCOUNT_NAME = "ContactsContract_StatusUpdatesTest";
 
     private ContentResolver mResolver;
diff --git a/tests/tests/provider/src/android/provider/cts/ContactsContract_StructuredPhoneticName.java b/tests/tests/provider/src/android/provider/cts/ContactsContract_StructuredPhoneticName.java
index 4efd9a7..42bc6d2 100644
--- a/tests/tests/provider/src/android/provider/cts/ContactsContract_StructuredPhoneticName.java
+++ b/tests/tests/provider/src/android/provider/cts/ContactsContract_StructuredPhoneticName.java
@@ -24,6 +24,7 @@
 import android.provider.ContactsContract.AggregationExceptions;
 import android.provider.ContactsContract.CommonDataKinds.StructuredName;
 import android.provider.ContactsContract.Contacts;
+import android.provider.ContactsContract.Data;
 import android.provider.ContactsContract.DisplayNameSources;
 import android.provider.ContactsContract.RawContacts;
 import android.provider.cts.ContactsContract_TestDataBuilder.TestContact;
@@ -72,6 +73,12 @@
                 DisplayNameSources.STRUCTURED_PHONETIC_NAME);
     }
 
+    public void testPhoneticNameStyleColumnName() throws Exception {
+        // Make sure the column name is data11 and not phonetic_name_style
+        // from the parent class.
+        assertEquals(Data.DATA11, StructuredName.PHONETIC_NAME_STYLE);
+    }
+
     public void testPhoneticStructuredName_phoneticPriority1() throws Exception {
         // Setup: one raw contact has a complex phonetic name and the other a simple given name
         TestRawContact rawContact1 = mBuilder.newRawContact()
diff --git a/tests/tests/provider/src/android/provider/cts/ContactsMetadataProviderTest.java b/tests/tests/provider/src/android/provider/cts/ContactsMetadataProviderTest.java
new file mode 100644
index 0000000..424b256
--- /dev/null
+++ b/tests/tests/provider/src/android/provider/cts/ContactsMetadataProviderTest.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.provider.cts;
+
+import android.content.ContentValues;
+import android.net.Uri;
+import android.test.AndroidTestCase;
+import android.test.MoreAsserts;
+
+/**
+ * Make sure the provider is protected.
+ *
+ * Run with:
+ * cts-tradefed run cts --class android.provider.cts.ContactsMetadataProviderTest < /dev/null
+ */
+public class ContactsMetadataProviderTest extends AndroidTestCase {
+
+    /** The authority for the contacts metadata */
+    public static final String METADATA_AUTHORITY = "com.android.contacts.metadata";
+
+    /** A content:// style uri to the authority for the contacts metadata */
+    public static final Uri METADATA_AUTHORITY_URI = Uri.parse(
+            "content://" + METADATA_AUTHORITY);
+
+    /**
+     * The content:// style URI for this table.
+     */
+    public static final Uri CONTENT_URI = Uri.withAppendedPath(METADATA_AUTHORITY_URI,
+            "metadata_sync");
+
+    public void testCallerCheck() {
+        try {
+            getContext().getContentResolver().query(CONTENT_URI, null, null, null, null);
+            fail();
+        } catch (SecurityException e) {
+            MoreAsserts.assertContainsRegex("can't access ContactMetadataProvider", e.getMessage());
+        }
+        try {
+            getContext().getContentResolver().insert(CONTENT_URI, new ContentValues());
+            fail();
+        } catch (SecurityException e) {
+            MoreAsserts.assertContainsRegex("can't access ContactMetadataProvider", e.getMessage());
+        }
+        try {
+            getContext().getContentResolver().update(CONTENT_URI, new ContentValues(), null, null);
+            fail();
+        } catch (SecurityException e) {
+            MoreAsserts.assertContainsRegex("can't access ContactMetadataProvider", e.getMessage());
+        }
+        try {
+            getContext().getContentResolver().delete(CONTENT_URI, null, null);
+            fail();
+        } catch (SecurityException e) {
+            MoreAsserts.assertContainsRegex("can't access ContactMetadataProvider", e.getMessage());
+        }
+    }
+}
diff --git a/tests/tests/provider/src/android/provider/cts/ContactsTest.java b/tests/tests/provider/src/android/provider/cts/ContactsTest.java
index 4d1cb86..3b71d49 100644
--- a/tests/tests/provider/src/android/provider/cts/ContactsTest.java
+++ b/tests/tests/provider/src/android/provider/cts/ContactsTest.java
@@ -220,12 +220,12 @@
         try {
             Context context = getInstrumentation().getTargetContext();
             InputStream inputStream = context.getResources().openRawResource(
-                    com.android.cts.provider.R.drawable.testimage);
+                    android.provider.cts.R.drawable.testimage);
             int size = inputStream.available();
             byte[] data =  new byte[size];
             inputStream.read(data);
             BitmapDrawable sourceDrawable = (BitmapDrawable) context.getResources().getDrawable(
-                    com.android.cts.provider.R.drawable.testimage);
+                    android.provider.cts.R.drawable.testimage);
             // Test: insert
             ContentValues value = new ContentValues();
             value.put(Photos.PERSON_ID, 1);
@@ -417,7 +417,7 @@
                 Calls.CACHED_NUMBER_LABEL, Calls.CACHED_FORMATTED_NUMBER,
                 Calls.CACHED_MATCHED_NUMBER, Calls.CACHED_NORMALIZED_NUMBER,
                 Calls.CACHED_LOOKUP_URI, Calls.CACHED_PHOTO_ID, Calls.COUNTRY_ISO,
-                Calls.GEOCODED_LOCATION, Calls.CACHED_PHOTO_URI};
+                Calls.GEOCODED_LOCATION, Calls.CACHED_PHOTO_URI, Calls.LAST_MODIFIED};
         final int ID_INDEX = 0;
         final int NUMBER_INDEX = 1;
         final int DATE_INDEX = 2;
@@ -435,6 +435,7 @@
         final int COUNTRY_ISO_INDEX = 14;
         final int GEOCODED_LOCATION_INDEX = 15;
         final int CACHED_PHOTO_URI_INDEX = 16;
+        final int LAST_MODIFIED_INDEX = 17;
 
         String insertCallsNumber = "0123456789";
         int insertCallsDuration = 120;
@@ -481,6 +482,7 @@
             assertEquals(insertCallsName, cursor.getString(CACHED_NAME_INDEX));
             assertEquals(Phones.TYPE_HOME, cursor.getInt(CACHED_NUMBER_TYPE_INDEX));
             assertEquals(insertCallsNumberLabel, cursor.getString(CACHED_NUMBER_LABEL_INDEX));
+            assertTrue(getElapsedDurationMillis(cursor.getLong(LAST_MODIFIED_INDEX)) < 1000);
             int id = cursor.getInt(ID_INDEX);
             cursor.close();
 
@@ -527,6 +529,7 @@
             assertEquals(updateCountryIso, cursor.getString(COUNTRY_ISO_INDEX));
             assertEquals(updateGeocodedLocation, cursor.getString(GEOCODED_LOCATION_INDEX));
             assertEquals(updateCachedLookupUri, cursor.getString(CACHED_LOOKUP_URI_INDEX));
+            assertTrue(getElapsedDurationMillis(cursor.getLong(LAST_MODIFIED_INDEX)) < 1000);
             cursor.close();
 
             // Test: delete
@@ -901,4 +904,8 @@
             fail("Unexpected RemoteException");
         }
     }
+
+    private long getElapsedDurationMillis(long timeStampMillis){
+        return (System.currentTimeMillis() - timeStampMillis);
+    }
 }
diff --git a/tests/tests/provider/src/android/provider/cts/Contacts_PeopleTest.java b/tests/tests/provider/src/android/provider/cts/Contacts_PeopleTest.java
index 6b5de96..d887aa7 100644
--- a/tests/tests/provider/src/android/provider/cts/Contacts_PeopleTest.java
+++ b/tests/tests/provider/src/android/provider/cts/Contacts_PeopleTest.java
@@ -257,7 +257,7 @@
         Context context = getInstrumentation().getTargetContext();
         try {
             InputStream inputStream = context.getResources().openRawResource(
-                    com.android.cts.provider.R.drawable.testimage);
+                    android.provider.cts.R.drawable.testimage);
             int size = inputStream.available();
             byte[] data =  new byte[size];
             inputStream.read(data);
@@ -275,12 +275,12 @@
             assertNull(photoStream);
 
             bitmap = People.loadContactPhoto(context, mPeopleRowsAdded.get(0),
-                    com.android.cts.provider.R.drawable.size_48x48, null);
+                    android.provider.cts.R.drawable.size_48x48, null);
             assertEquals(96, bitmap.getWidth());
             assertEquals(64, bitmap.getHeight());
 
             bitmap = People.loadContactPhoto(context, null,
-                    com.android.cts.provider.R.drawable.size_48x48, null);
+                    android.provider.cts.R.drawable.size_48x48, null);
             assertNotNull(bitmap);
         } catch (IOException e) {
             fail("Unexpected IOException");
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStoreAudioTestHelper.java b/tests/tests/provider/src/android/provider/cts/MediaStoreAudioTestHelper.java
index c9eb506..56d74f3 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStoreAudioTestHelper.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStoreAudioTestHelper.java
@@ -107,7 +107,7 @@
         public static final String DISPLAY_NAME = "Jam -Michael Jackson";
 
         public static final String INTERNAL_DATA =
-            "/data/data/com.android.cts.provider/files/Jam.mp3";
+            "/data/data/android.provider.cts/files/Jam.mp3";
 
         public static final String FILE_NAME = "Jam.mp3";
 
@@ -190,7 +190,7 @@
             Environment.getExternalStorageDirectory().getPath() + "/" + FILE_NAME;
 
         public static final String INTERNAL_DATA =
-            "/data/data/com.android.cts.provider/files/Jam_live.mp3";
+            "/data/data/android.provider.cts/files/Jam_live.mp3";
 
 
 
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStoreIntentsTest.java b/tests/tests/provider/src/android/provider/cts/MediaStoreIntentsTest.java
index a94e7f4..529b176 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStoreIntentsTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStoreIntentsTest.java
@@ -71,7 +71,10 @@
         final String[] schemes = new String[] {
                 "file", "http", "https", "content" };
         final String[] mimes = new String[] {
-                "image/bmp", "image/jpeg", "image/png", "image/gif", "image/webp" };
+                "image/bmp", "image/jpeg", "image/png", "image/gif", "image/webp",
+                "image/x-adobe-dng", "image/x-canon-cr2", "image/x-nikon-nef", "image/x-nikon-nrw",
+                "image/x-sony-arw", "image/x-panasonic-rw2", "image/x-olympus-orf",
+                "image/x-fuji-raf", "image/x-pentax-pef", "image/x-samsung-srw" };
 
         for (String scheme : schemes) {
             for (String mime : mimes) {
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_AlbumsTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_AlbumsTest.java
index 84da62a..3bd81ce 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_AlbumsTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_AlbumsTest.java
@@ -16,7 +16,7 @@
 
 package android.provider.cts;
 
-import com.android.cts.provider.R;
+import android.provider.cts.R;
 
 import android.content.ContentResolver;
 import android.content.ContentValues;
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_PlaylistsTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_PlaylistsTest.java
index 8dcb1a8..463dfcb 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_PlaylistsTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_PlaylistsTest.java
@@ -112,7 +112,7 @@
     public void testStoreAudioPlaylistsInternal() {
         ContentValues values = new ContentValues();
         values.put(Playlists.NAME, "My favourites");
-        values.put(Playlists.DATA, "/data/data/com.android.cts.provider/files/my_favorites.pl");
+        values.put(Playlists.DATA, "/data/data/android.provider.cts/files/my_favorites.pl");
         long dateAdded = System.currentTimeMillis();
         values.put(Playlists.DATE_ADDED, dateAdded);
         long dateModified = System.currentTimeMillis();
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_Playlists_MembersTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_Playlists_MembersTest.java
index 58c1cdf..cc69942 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_Playlists_MembersTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_Playlists_MembersTest.java
@@ -454,7 +454,7 @@
     public void testStoreAudioPlaylistsMembersInternal() {
         ContentValues values = new ContentValues();
         values.put(Playlists.NAME, "My favourites");
-        values.put(Playlists.DATA, "/data/data/com.android.cts.provider/files/my_favorites.pl");
+        values.put(Playlists.DATA, "/data/data/android.provider.cts/files/my_favorites.pl");
         long dateAdded = System.currentTimeMillis();
         values.put(Playlists.DATE_ADDED, dateAdded);
         long dateModified = System.currentTimeMillis();
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_FilesTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_FilesTest.java
index 8fc5df1..8fe95f5 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_FilesTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_FilesTest.java
@@ -16,7 +16,7 @@
 
 package android.provider.cts;
 
-import com.android.cts.provider.R;
+import android.provider.cts.R;
 
 import android.content.ContentResolver;
 import android.content.ContentUris;
@@ -278,16 +278,6 @@
         } catch (FileNotFoundException e) {
             // expected
         }
-        // now make the file world-readable
-        fos = mContext.openFileOutput("dummy.dat", Context.MODE_WORLD_READABLE);
-        fos.write(0);
-        fos.close();
-        try {
-            pfd = mResolver.openFileDescriptor(uri, "r");
-            pfd.close();
-        } catch (FileNotFoundException e) {
-            fail("failed to open file");
-        }
         path.delete();
 
         File sdfile = null;
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_Images_MediaTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_Images_MediaTest.java
index 7469f8e..1c00aac 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_Images_MediaTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_Images_MediaTest.java
@@ -16,7 +16,7 @@
 
 package android.provider.cts;
 
-import com.android.cts.provider.R;
+import android.provider.cts.R;
 
 import android.content.ContentResolver;
 import android.content.ContentValues;
@@ -28,9 +28,11 @@
 import android.graphics.BitmapFactory;
 import android.net.Uri;
 import android.os.Environment;
+import android.platform.test.annotations.Presubmit;
 import android.provider.MediaStore.Images.Media;
 import android.provider.MediaStore.Images.Thumbnails;
 import android.test.InstrumentationTestCase;
+import android.util.Log;
 
 import java.io.File;
 import java.io.FileNotFoundException;
@@ -52,6 +54,8 @@
 
     private static final String TEST_DESCRIPTION3 = "test description3";
 
+    private static final String LOG_TAG = "MediaStore_Images_MediaTest";
+    
     private ArrayList<Uri> mRowsAdded;
 
     private Context mContext;
@@ -79,6 +83,16 @@
 
         mHelper = new FileCopyHelper(mContext);
         mRowsAdded = new ArrayList<Uri>();
+
+        File pics = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
+        if (!pics.exists()) {
+            Log.i(LOG_TAG, "Nonstandard test-environment: Pictures directory does not exist!");
+            pics.mkdirs();
+            if (!pics.exists()) {
+                Log.i(LOG_TAG, "Couldn't create Pictures directory, some tests may fail!");
+            }
+        }
+
     }
 
     public void testInsertImageWithImagePath() throws Exception {
@@ -178,6 +192,7 @@
         assertEquals(src.getHeight(), result.getHeight());
     }
 
+    @Presubmit
     public void testGetContentUri() {
         Cursor c = null;
         assertNotNull(c = mContentResolver.query(Media.getContentUri("internal"), null, null, null,
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_Images_ThumbnailsTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_Images_ThumbnailsTest.java
index ec9db8b..db3db6b 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_Images_ThumbnailsTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_Images_ThumbnailsTest.java
@@ -16,7 +16,7 @@
 
 package android.provider.cts;
 
-import com.android.cts.provider.R;
+import android.provider.cts.R;
 
 import android.content.ContentResolver;
 import android.content.ContentUris;
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_VideoTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_VideoTest.java
index 89de9c6..e50f18a 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_VideoTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_VideoTest.java
@@ -16,7 +16,7 @@
 
 package android.provider.cts;
 
-import com.android.cts.provider.R;
+import android.provider.cts.R;
 
 import android.content.ContentResolver;
 import android.content.ContentValues;
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_Video_MediaTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_Video_MediaTest.java
index f84b75c..5ec765c 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_Video_MediaTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_Video_MediaTest.java
@@ -17,7 +17,7 @@
 package android.provider.cts;
 
 
-import com.android.cts.provider.R;
+import android.provider.cts.R;
 
 import android.content.ContentResolver;
 import android.content.ContentValues;
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_Video_ThumbnailsTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_Video_ThumbnailsTest.java
index 974eeb71..9c41274 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_Video_ThumbnailsTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_Video_ThumbnailsTest.java
@@ -16,7 +16,7 @@
 
 package android.provider.cts;
 
-import com.android.cts.provider.R;
+import android.provider.cts.R;
 
 import android.content.ContentResolver;
 import android.content.ContentUris;
diff --git a/tests/tests/provider/src/android/provider/cts/PhotoUtil.java b/tests/tests/provider/src/android/provider/cts/PhotoUtil.java
index ec4fdef..4debd8f 100644
--- a/tests/tests/provider/src/android/provider/cts/PhotoUtil.java
+++ b/tests/tests/provider/src/android/provider/cts/PhotoUtil.java
@@ -16,7 +16,7 @@
 
 package android.provider.cts;
 
-import com.android.cts.provider.R;
+import android.provider.cts.R;
 
 import android.content.Context;
 import android.cts.util.FileUtils;
diff --git a/tests/tests/provider/src/android/provider/cts/ProviderTestUtils.java b/tests/tests/provider/src/android/provider/cts/ProviderTestUtils.java
new file mode 100644
index 0000000..e2ed68d
--- /dev/null
+++ b/tests/tests/provider/src/android/provider/cts/ProviderTestUtils.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.provider.cts;
+
+import android.app.UiAutomation;
+import android.os.ParcelFileDescriptor;
+
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+import java.util.Objects;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Utility methods for provider cts tests.
+ */
+public class ProviderTestUtils {
+
+    private static final int BACKUP_TIMEOUT_MILLIS = 4000;
+    private static final Pattern BMGR_ENABLED_PATTERN = Pattern.compile(
+            "^Backup Manager currently (enabled|disabled)$");
+
+    static void setDefaultSmsApp(boolean setToSmsApp, String packageName, UiAutomation uiAutomation)
+            throws Exception {
+        String command = String.format(
+                "appops set %s WRITE_SMS %s", packageName, setToSmsApp ? "allow" : "default");
+        executeShellCommand(command, uiAutomation);
+    }
+
+    static String executeShellCommand(String command, UiAutomation uiAutomation)
+            throws IOException {
+        ParcelFileDescriptor pfd = uiAutomation.executeShellCommand(command.toString());
+        BufferedReader br = null;
+        try (InputStream in = new FileInputStream(pfd.getFileDescriptor());) {
+            br = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8));
+            String str = null;
+            StringBuilder out = new StringBuilder();
+            while ((str = br.readLine()) != null) {
+                out.append(str);
+            }
+            return out.toString();
+        } finally {
+            if (br != null) {
+                br.close();
+            }
+        }
+    }
+
+    static String setBackupTransport(String transport, UiAutomation uiAutomation) throws Exception {
+        String output = executeShellCommand("bmgr transport " + transport, uiAutomation);
+        Pattern pattern = Pattern.compile("\\(formerly (.*)\\)$");
+        Matcher matcher = pattern.matcher(output);
+        if (matcher.find()) {
+            return matcher.group(1);
+        } else {
+            throw new Exception("non-parsable output setting bmgr transport: " + output);
+        }
+    }
+
+    static boolean setBackupEnabled(boolean enable, UiAutomation uiAutomation) throws Exception {
+        // Check to see the previous state of the backup service
+        boolean previouslyEnabled = false;
+        String output = executeShellCommand("bmgr enabled", uiAutomation);
+        Matcher matcher = BMGR_ENABLED_PATTERN.matcher(output.trim());
+        if (matcher.find()) {
+            previouslyEnabled = "enabled".equals(matcher.group(1));
+        } else {
+            throw new RuntimeException("Backup output format changed.  No longer matches"
+                    + " expected regex: " + BMGR_ENABLED_PATTERN + "\nactual: '" + output + "'");
+        }
+
+        executeShellCommand("bmgr enable " + enable, uiAutomation);
+        return previouslyEnabled;
+    }
+
+    static boolean hasBackupTransport(String transport, UiAutomation uiAutomation)
+            throws Exception {
+        String output = executeShellCommand("bmgr list transports", uiAutomation);
+        for (String t : output.split(" ")) {
+            if ("*".equals(t)) {
+                // skip the current selection marker.
+                continue;
+            } else if (Objects.equals(transport, t)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    static void runBackup(String packageName, UiAutomation uiAutomation) throws Exception {
+        executeShellCommand("bmgr backupnow " + packageName, uiAutomation);
+        Thread.sleep(BACKUP_TIMEOUT_MILLIS);
+    }
+
+    static void runRestore(String packageName, UiAutomation uiAutomation) throws Exception {
+        executeShellCommand("bmgr restore 1 " + packageName, uiAutomation);
+        Thread.sleep(BACKUP_TIMEOUT_MILLIS);
+    }
+
+    static void wipeBackup(String backupTransport, String packageName, UiAutomation uiAutomation)
+            throws Exception {
+        executeShellCommand("bmgr wipe " + backupTransport + " " + packageName, uiAutomation);
+    }
+}
diff --git a/tests/tests/provider/src/android/provider/cts/SmsBackupRestoreTest.java b/tests/tests/provider/src/android/provider/cts/SmsBackupRestoreTest.java
new file mode 100644
index 0000000..fad1019
--- /dev/null
+++ b/tests/tests/provider/src/android/provider/cts/SmsBackupRestoreTest.java
@@ -0,0 +1,260 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.provider.cts;
+
+import com.google.android.mms.ContentType;
+import com.google.android.mms.pdu.CharacterSets;
+
+import android.app.UiAutomation;
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.database.Cursor;
+import android.net.Uri;
+import android.provider.BaseColumns;
+import android.provider.Telephony;
+import android.util.Log;
+
+/**
+ * CTS tests for backup and restore of blocked numbers using local transport.
+ */
+// To run the tests in this file w/o running all the cts tests:
+// make cts
+// cts-tradefed
+// run cts -m CtsProviderTestCases --test android.provider.cts.SmsBackupRestoreTest
+public class SmsBackupRestoreTest extends TestCaseThatRunsIfTelephonyIsEnabled {
+    private static final String TAG = "SmsBackupRestoreTest";
+    private static final String LOCAL_BACKUP_COMPONENT =
+            "android/com.android.internal.backup.LocalTransport";
+    private static final String TELEPHONY_PROVIDER_PACKAGE = "com.android.providers.telephony";
+
+    private static final String[] smsAddressBody1 = new String[] {"+123" , "sms CTS text"};
+    private static final String[] smsAddressBody2 = new String[] {"+456" , "sms CTS text 2"};
+    private static final String[] mmsAddresses = new String[] {"+1223", "+43234234"};
+    private static final String mmsSubject = "MMS Subject CTS";
+    private static final String mmsBody = "MMS body CTS";
+
+    private static final String[] ID_PROJECTION = new String[] { BaseColumns._ID };
+    private static final String SMS_SELECTION = Telephony.Sms.ADDRESS + " = ? and "
+            + Telephony.Sms.BODY + " = ?";
+
+    private static final String MMS_SELECTION = Telephony.Mms.SUBJECT + " = ?";
+
+    private static final String[] MMS_PART_TEXT_PROJECTION = new String[]{Telephony.Mms.Part.TEXT};
+    private static final String MMS_PART_SELECTION = Telephony.Mms.Part.MSG_ID + " = ?";
+    private static final String MMS_PART_TEXT_SELECTION = Telephony.Mms.Part.CONTENT_TYPE + " = ?";
+    private static final String[] MMS_ADDR_PROJECTION = new String[] { Telephony.Mms.Addr.ADDRESS };
+    private static final String MMS_ADDR_SELECTION = Telephony.Mms.Addr.MSG_ID + " = ?";
+
+    private Context mContext;
+    private ContentResolver mContentResolver;
+    private UiAutomation mUiAutomation;
+    private String mOldTransport;
+    private boolean mOldBackupEnabled;
+    private boolean mHasFeature;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        // Wait for the UI Thread to become idle.
+        getInstrumentation().waitForIdleSync();
+        mContext = getInstrumentation().getContext();
+        mContentResolver = mContext.getContentResolver();
+        mUiAutomation = getInstrumentation().getUiAutomation();
+        mHasFeature = isFeatureSupported();
+        if (mHasFeature) {
+            ProviderTestUtils.setDefaultSmsApp(true, mContext.getPackageName(), mUiAutomation);
+            mOldTransport =
+                    ProviderTestUtils.setBackupTransport(LOCAL_BACKUP_COMPONENT, mUiAutomation);
+            mOldBackupEnabled = ProviderTestUtils.setBackupEnabled(true, mUiAutomation);
+            clearMessages();
+            wipeBackup();
+        }
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        if (mHasFeature) {
+            wipeBackup();
+            clearMessages();
+            ProviderTestUtils.setBackupEnabled(mOldBackupEnabled, mUiAutomation);
+            ProviderTestUtils.setBackupTransport(mOldTransport, mUiAutomation);
+            ProviderTestUtils.setDefaultSmsApp(false, mContext.getPackageName(), mUiAutomation);
+        }
+
+        super.tearDown();
+    }
+
+    private boolean isFeatureSupported() throws Exception {
+        return (ProviderTestUtils.hasBackupTransport(LOCAL_BACKUP_COMPONENT, mUiAutomation)
+                && mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY));
+    }
+
+    private void clearMessages() {
+        mContentResolver.delete(Telephony.Sms.CONTENT_URI, SMS_SELECTION, smsAddressBody1);
+        mContentResolver.delete(Telephony.Sms.CONTENT_URI, SMS_SELECTION, smsAddressBody2);
+        try (Cursor mmsCursor =
+                     mContentResolver.query(Telephony.Mms.CONTENT_URI, ID_PROJECTION, MMS_SELECTION,
+                             new String[] {mmsSubject}, null)) {
+            if (mmsCursor != null && mmsCursor.moveToFirst()) {
+                final long mmsId = mmsCursor.getLong(0);
+                final Uri partUri = Telephony.Mms.CONTENT_URI.buildUpon()
+                        .appendPath(String.valueOf(mmsId)).appendPath("part").build();
+                mContentResolver.delete(partUri, MMS_PART_SELECTION,
+                        new String[]{String.valueOf(mmsId)});
+
+                final Uri addrUri = getMmsAddrUri(mmsId);
+                mContentResolver.delete(addrUri, MMS_ADDR_SELECTION,
+                        new String[]{String.valueOf(mmsId)});
+            }
+        }
+        mContentResolver.delete(Telephony.Mms.CONTENT_URI, MMS_SELECTION, new String[]{mmsSubject});
+    }
+
+    /**
+     * Test adds 2 SMS messages, 1 text-only MMS messages and 1 non-text-only, runs backup,
+     * deletes the messages from the provider, runs restore, check if the messages are in the
+     * provider (w/o non-text-only one).
+     * @throws Exception
+     */
+    public void testSmsBackupRestore() throws Exception {
+        if (!mHasFeature) {
+            Log.i(TAG, "skipping testSmsBackupRestore");
+            return;
+        }
+
+        ContentValues smsContentValues[] = new ContentValues[] {
+                createSmsValues(smsAddressBody1),
+                createSmsValues(smsAddressBody2)};
+        Log.i(TAG, "Put 2 SMS into the provider");
+        mContentResolver.bulkInsert(Telephony.Sms.CONTENT_URI, smsContentValues);
+
+        Log.i(TAG, "Put 1 text MMS into the provider");
+        addMms(true /*isTextOnly*/, mmsBody, mmsSubject, mmsAddresses);
+        Log.i(TAG, "Put 1 non-text MMS into the provider");
+        addMms(false /*isTextOnly*/, mmsBody, mmsSubject, mmsAddresses);
+
+        Log.i(TAG, "Run backup");
+        ProviderTestUtils.runBackup(TELEPHONY_PROVIDER_PACKAGE, mUiAutomation);
+        Log.i(TAG, "Delete the messages from the provider");
+        clearMessages();
+        Log.i(TAG, "Run restore");
+        ProviderTestUtils.runRestore(TELEPHONY_PROVIDER_PACKAGE, mUiAutomation);
+
+        Log.i(TAG, "Check the providers for the messages");
+        assertEquals(1,
+                mContentResolver.delete(Telephony.Sms.CONTENT_URI, SMS_SELECTION, smsAddressBody1));
+        assertEquals(1,
+                mContentResolver.delete(Telephony.Sms.CONTENT_URI, SMS_SELECTION, smsAddressBody2));
+
+        try (Cursor mmsCursor = mContentResolver.query(Telephony.Mms.CONTENT_URI, ID_PROJECTION,
+                MMS_SELECTION, new String[] {mmsSubject}, null)) {
+            assertNotNull(mmsCursor);
+            assertEquals(1, mmsCursor.getCount());
+            mmsCursor.moveToFirst();
+            final long mmsId = mmsCursor.getLong(0);
+            final Uri partUri = Telephony.Mms.CONTENT_URI.buildUpon()
+                    .appendPath(String.valueOf(mmsId)).appendPath("part").build();
+            // Check the body.
+            try (Cursor partCursor = mContentResolver.query(partUri, MMS_PART_TEXT_PROJECTION,
+                    MMS_PART_TEXT_SELECTION, new String[]{ ContentType.TEXT_PLAIN }, null)) {
+                assertNotNull(partCursor);
+                assertEquals(1, partCursor.getCount());
+                assertTrue(partCursor.moveToFirst());
+                assertEquals(mmsBody, partCursor.getString(0));
+            }
+
+            // Check if there are 2 parts (smil and body).
+            assertEquals(2, mContentResolver.delete(partUri, MMS_PART_SELECTION,
+                    new String[]{String.valueOf(mmsId)}));
+
+            // Check addresses.
+            final Uri addrUri = getMmsAddrUri(mmsId);
+            try (Cursor addrCursor = mContentResolver.query(addrUri, MMS_ADDR_PROJECTION,
+                    MMS_ADDR_SELECTION, new String[]{String.valueOf(mmsId)}, null)) {
+                assertNotNull(addrCursor);
+                for (String addr : mmsAddresses) {
+                    addrCursor.moveToNext();
+                    assertEquals(addr, addrCursor.getString(0));
+                }
+            }
+            assertEquals(mmsAddresses.length, mContentResolver.delete(addrUri, MMS_ADDR_SELECTION,
+                    new String[]{String.valueOf(mmsId)}));
+        }
+    }
+
+    private static Uri getMmsAddrUri(long mmsId) {
+        Uri.Builder builder = Telephony.Mms.CONTENT_URI.buildUpon();
+        builder.appendPath(String.valueOf(mmsId)).appendPath("addr");
+        return builder.build();
+    }
+
+    private void addMms(boolean isTextOnly, String body, String subject, String[] addresses) {
+        // Insert mms.
+        final ContentValues mmsValues = new ContentValues(2);
+        mmsValues.put(Telephony.Mms.TEXT_ONLY, isTextOnly ? 1 : 0);
+        mmsValues.put(Telephony.Mms.MESSAGE_TYPE, 128);
+        mmsValues.put(Telephony.Mms.SUBJECT, subject);
+        final Uri mmsUri = mContentResolver.insert(Telephony.Mms.CONTENT_URI, mmsValues);
+        assertNotNull(mmsUri);
+        final long mmsId = ContentUris.parseId(mmsUri);
+
+        final String srcName = String.format("text.%06d.txt", 0);
+        // Insert body part.
+        final Uri partUri = Telephony.Mms.CONTENT_URI.buildUpon()
+                .appendPath(String.valueOf(mmsId)).appendPath("part").build();
+
+        final ContentValues values = new ContentValues(8);
+        values.put(Telephony.Mms.Part.MSG_ID, mmsId);
+        values.put(Telephony.Mms.Part.SEQ, 0);
+        values.put(Telephony.Mms.Part.CONTENT_TYPE, ContentType.TEXT_PLAIN);
+        values.put(Telephony.Mms.Part.NAME, srcName);
+        values.put(Telephony.Mms.Part.CONTENT_ID, "<"+srcName+">");
+        values.put(Telephony.Mms.Part.CONTENT_LOCATION, srcName);
+        values.put(Telephony.Mms.Part.CHARSET, CharacterSets.DEFAULT_CHARSET);
+        if (!isTextOnly) {
+            body = body + " Non text-only";
+        }
+        values.put(Telephony.Mms.Part.TEXT, body);
+        mContentResolver.insert(partUri, values);
+
+        // Insert addresses.
+        final Uri addrUri = Uri.withAppendedPath(mmsUri, "addr");
+        for (int i = 0; i < addresses.length; ++i) {
+            ContentValues addrValues = new ContentValues(3);
+            addrValues.put(Telephony.Mms.Addr.TYPE, i);
+            addrValues.put(Telephony.Mms.Addr.CHARSET, CharacterSets.DEFAULT_CHARSET);
+            addrValues.put(Telephony.Mms.Addr.ADDRESS, addresses[i]);
+            addrValues.put(Telephony.Mms.Addr.MSG_ID, mmsId);
+            mContentResolver.insert(addrUri, addrValues);
+        }
+    }
+
+    private static ContentValues createSmsValues(String[] addressBody) {
+        ContentValues smsRow = new ContentValues();
+        smsRow.put(Telephony.Sms.ADDRESS, addressBody[0]);
+        smsRow.put(Telephony.Sms.BODY, addressBody[1]);
+        return smsRow;
+    }
+
+    private void wipeBackup() throws Exception {
+        ProviderTestUtils.wipeBackup(LOCAL_BACKUP_COMPONENT, TELEPHONY_PROVIDER_PACKAGE,
+                mUiAutomation);
+    }
+}
\ No newline at end of file
diff --git a/tests/tests/provider/src/android/provider/cts/TestCaseThatRunsIfTelephonyIsEnabled.java b/tests/tests/provider/src/android/provider/cts/TestCaseThatRunsIfTelephonyIsEnabled.java
new file mode 100644
index 0000000..9d2b093
--- /dev/null
+++ b/tests/tests/provider/src/android/provider/cts/TestCaseThatRunsIfTelephonyIsEnabled.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.provider.cts;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.test.InstrumentationTestCase;
+
+/**
+ * An {@link InstrumentationTestCase} that runs tests only if
+ * {@link android.content.pm.PackageManager#FEATURE_TELEPHONY} is enabled.
+ */
+public class TestCaseThatRunsIfTelephonyIsEnabled extends InstrumentationTestCase {
+    @Override
+    protected void runTest() throws Throwable {
+        if (isTelephonySupported(getInstrumentation().getContext())) {
+            super.runTest();
+        }
+    }
+
+    private static boolean isTelephonySupported(Context context) {
+        return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
+    }
+}
diff --git a/tests/tests/provider/src/android/provider/cts/UserDictionary_WordsTest.java b/tests/tests/provider/src/android/provider/cts/UserDictionary_WordsTest.java
index e226fef..27c48d3 100644
--- a/tests/tests/provider/src/android/provider/cts/UserDictionary_WordsTest.java
+++ b/tests/tests/provider/src/android/provider/cts/UserDictionary_WordsTest.java
@@ -26,6 +26,10 @@
 import java.util.ArrayList;
 import java.util.Locale;
 
+/**
+ * NOTE: user dictionary is now accessible only by the current spellchecker and keyboard, so this
+ * test make sure they are not accessible by apps.
+ */
 public class UserDictionary_WordsTest extends AndroidTestCase {
 
     private ContentResolver mContentResolver;
@@ -68,14 +72,8 @@
 
         Cursor cursor = mContentResolver.query(UserDictionary.Words.CONTENT_URI, WORDS_PROJECTION,
                 UserDictionary.Words.WORD + "='" + word + "'", null, null);
-        assertTrue(cursor.moveToFirst());
-        mAddedBackup.add(Uri.withAppendedPath(UserDictionary.Words.CONTENT_URI,
-                cursor.getString(ID_INDEX)));
+        assertFalse("cursor is not empty", cursor.moveToFirst());
 
-        assertEquals(1, cursor.getCount());
-        assertEquals(word, cursor.getString(WORD_INDEX));
-        assertEquals(frequency, cursor.getInt(FREQUENCY_INDEX));
-        assertNull(cursor.getString(LOCALE_INDEX));
         cursor.close();
     }
 
@@ -92,14 +90,8 @@
 
         Cursor cursor = mContentResolver.query(UserDictionary.Words.CONTENT_URI, WORDS_PROJECTION,
                 UserDictionary.Words.WORD + "='" + word + "'", null, null);
-        assertTrue(cursor.moveToFirst());
-        mAddedBackup.add(Uri.withAppendedPath(UserDictionary.Words.CONTENT_URI,
-                cursor.getString(ID_INDEX)));
+        assertFalse("cursor is not empty", cursor.moveToFirst());
 
-        assertEquals(1, cursor.getCount());
-        assertEquals(word, cursor.getString(WORD_INDEX));
-        assertEquals(expectedFrequency, cursor.getInt(FREQUENCY_INDEX));
-        assertEquals(locale.toString(), cursor.getString(LOCALE_INDEX));
         cursor.close();
     }
 }
diff --git a/tests/tests/provider/src/android/provider/cts/VoicemailContractTest.java b/tests/tests/provider/src/android/provider/cts/VoicemailContractTest.java
index 34a546e..8e0a6cc 100644
--- a/tests/tests/provider/src/android/provider/cts/VoicemailContractTest.java
+++ b/tests/tests/provider/src/android/provider/cts/VoicemailContractTest.java
@@ -205,7 +205,8 @@
         final String[] STATUS_PROJECTION = new String[] {
                 Status._ID, Status.SOURCE_PACKAGE, Status.CONFIGURATION_STATE,
                 Status.DATA_CHANNEL_STATE, Status.NOTIFICATION_CHANNEL_STATE,
-                Status.SETTINGS_URI, Status.VOICEMAIL_ACCESS_URI};
+                Status.SETTINGS_URI, Status.VOICEMAIL_ACCESS_URI,
+                Status.QUOTA_OCCUPIED, Status.QUOTA_TOTAL};
         final int ID_INDEX = 0;
         final int SOURCE_PACKAGE_INDEX = 1;
         final int CONFIGURATION_STATE_INDEX = 2;
@@ -213,16 +214,22 @@
         final int NOTIFICATION_CHANNEL_STATE_INDEX = 4;
         final int SETTINGS_URI_INDEX = 5;
         final int VOICEMAIL_ACCESS_URI_INDEX = 6;
+        final int QUOTA_OCCUPIED_INDEX = 7;
+        final int QUOTA_TOTAL_INDEX = 8;
 
         int insertConfigurationState = Status.CONFIGURATION_STATE_OK;
         int insertDataChannelState = Status.DATA_CHANNEL_STATE_OK;
         int insertNotificationChannelState = Status.NOTIFICATION_CHANNEL_STATE_OK;
         String insertSettingsUri = "settings_uri";
         String insertVoicemailAccessUri = "tel:901";
+        int quotaOccupied = 7;
+        int quotaTotal = 42;
 
         int updateDataChannelState = Status.DATA_CHANNEL_STATE_NO_CONNECTION;
         int updateNotificationChannelState = Status.NOTIFICATION_CHANNEL_STATE_MESSAGE_WAITING;
         String updateSettingsUri = "settings_uri_2";
+        int updateQuotaOccupied = 1337;
+        int updateQuotaTotal = 2187;
 
         // Test: insert
         ContentValues value = new ContentValues();
@@ -231,6 +238,8 @@
         value.put(Status.NOTIFICATION_CHANNEL_STATE, insertNotificationChannelState);
         value.put(Status.SETTINGS_URI, insertSettingsUri);
         value.put(Status.VOICEMAIL_ACCESS_URI, insertVoicemailAccessUri);
+        value.put(Status.QUOTA_OCCUPIED, quotaOccupied);
+        value.put(Status.QUOTA_TOTAL, quotaTotal);
 
         Uri uri = mStatusProvider.insert(mStatusContentUri, value);
         Cursor cursor = mStatusProvider.query(
@@ -243,6 +252,8 @@
                 cursor.getInt(NOTIFICATION_CHANNEL_STATE_INDEX));
         assertEquals(insertSettingsUri, cursor.getString(SETTINGS_URI_INDEX));
         assertEquals(insertVoicemailAccessUri, cursor.getString(VOICEMAIL_ACCESS_URI_INDEX));
+        assertEquals(quotaOccupied, cursor.getInt(QUOTA_OCCUPIED_INDEX));
+        assertEquals(quotaTotal, cursor.getInt(QUOTA_TOTAL_INDEX));
         int id = cursor.getInt(ID_INDEX);
         assertEquals(id, Integer.parseInt(uri.getLastPathSegment()));
         cursor.close();
@@ -252,6 +263,8 @@
         value.put(Status.DATA_CHANNEL_STATE, updateDataChannelState);
         value.put(Status.NOTIFICATION_CHANNEL_STATE, updateNotificationChannelState);
         value.put(Status.SETTINGS_URI, updateSettingsUri);
+        value.put(Status.QUOTA_OCCUPIED, updateQuotaOccupied);
+        value.put(Status.QUOTA_TOTAL, updateQuotaTotal);
 
         mStatusProvider.update(uri, value, null, null);
         cursor = mStatusProvider.query(mStatusContentUri, STATUS_PROJECTION,
@@ -263,6 +276,8 @@
         assertEquals(updateNotificationChannelState,
                 cursor.getInt(NOTIFICATION_CHANNEL_STATE_INDEX));
         assertEquals(updateSettingsUri, cursor.getString(SETTINGS_URI_INDEX));
+        assertEquals(updateQuotaOccupied, cursor.getInt(QUOTA_OCCUPIED_INDEX));
+        assertEquals(updateQuotaTotal, cursor.getInt(QUOTA_TOTAL_INDEX));
         cursor.close();
 
         // Test: delete
diff --git a/tests/tests/renderscript/Android.mk b/tests/tests/renderscript/Android.mk
index 7b30859..00e751a 100644
--- a/tests/tests/renderscript/Android.mk
+++ b/tests/tests/renderscript/Android.mk
@@ -28,8 +28,8 @@
 # When built, explicitly put it in the data partition.
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
 
-LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
-LOCAL_JNI_SHARED_LIBRARIES := libcoremathtestcpp_jni libbnnmdata_jni
+LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner xmp_toolkit
+LOCAL_JNI_SHARED_LIBRARIES := libcoremathtestcpp_jni
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-renderscript-files-under, src)
 
@@ -37,5 +37,8 @@
 
 LOCAL_SDK_VERSION := current
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_CTS_PACKAGE)
 include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/tests/renderscript/AndroidManifest.xml b/tests/tests/renderscript/AndroidManifest.xml
index b9405ca..7499899 100644
--- a/tests/tests/renderscript/AndroidManifest.xml
+++ b/tests/tests/renderscript/AndroidManifest.xml
@@ -19,16 +19,18 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.renderscript">
+    package="android.renderscript.cts">
 
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
-    <application>
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+    <application android:largeHeap="true">
         <uses-library android:name="android.test.runner" />
     </application>
 
     <!-- This is a self-instrumenting test package. -->
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.cts.renderscript"
+                     android:targetPackage="android.renderscript.cts"
                      android:label="CTS tests of Renderscript component">
         <meta-data android:name="listener"
             android:value="com.android.cts.runner.CtsTestRunListener" />
diff --git a/tests/tests/renderscript/AndroidTest.xml b/tests/tests/renderscript/AndroidTest.xml
new file mode 100644
index 0000000..2e69534
--- /dev/null
+++ b/tests/tests/renderscript/AndroidTest.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Configuration for Renderscript Tests">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsRenderscriptTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.renderscript.cts" />
+        <option name="runtime-hint" value="9m35s" />
+    </test>
+</configuration>
diff --git a/tests/tests/renderscript/libbnnmdata/Android.mk b/tests/tests/renderscript/libbnnmdata/Android.mk
deleted file mode 100644
index 471d74a..0000000
--- a/tests/tests/renderscript/libbnnmdata/Android.mk
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright (C) 2015 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-LOCAL_CLANG := true
-
-LOCAL_MODULE := libbnnmdata_jni
-LOCAL_MODULE_TAGS := optional
-LOCAL_SRC_FILES := test_data.cpp
-
-LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/tests/tests/renderscript/libbnnmdata/test_data.cpp b/tests/tests/renderscript/libbnnmdata/test_data.cpp
deleted file mode 100644
index 91222c2..0000000
--- a/tests/tests/renderscript/libbnnmdata/test_data.cpp
+++ /dev/null
@@ -1,56591 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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 <jni.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-const int m = 256;
-const int n = 192;
-const int k = 1152;
-const int a_offset = 0;
-const int b_offset = 84;
-const int c_mult_int = 3401;
-const int c_offset = 74980;
-
-const int a_count = (m * k);
-const int b_count = (n * k);
-const int c_count = (m * n);
-
-unsigned char a_data[a_count] = {
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 39, 14, 0, 0, 0, 63, 31,
-  0, 36, 15, 0, 0, 12, 10, 93, 23, 78,
-  37, 39, 52, 0, 44, 62, 9, 23, 34, 48,
-  251, 53, 0, 0, 103, 0, 11, 0, 0, 19,
-  12, 43, 34, 0, 10, 7, 84, 61, 0, 22,
-  0, 69, 0, 28, 41, 0, 20, 0, 7, 14,
-  0, 3, 6, 7, 15, 0, 0, 16, 25, 16,
-  0, 28, 0, 14, 83, 9, 21, 62, 7, 4,
-  7, 0, 53, 0, 16, 0, 0, 1, 0, 4,
-  66, 24, 50, 9, 0, 0, 69, 27, 15, 2,
-  14, 33, 3, 0, 1, 18, 73, 0, 43, 0,
-  0, 6, 26, 16, 10, 44, 0, 0, 22, 18,
-  0, 41, 77, 0, 0, 0, 0, 0, 27, 20,
-  27, 77, 56, 1, 0, 0, 53, 33, 0, 26,
-  0, 19, 15, 40, 3, 80, 27, 70, 9, 40,
-  13, 19, 51, 56, 1, 0, 62, 39, 168, 33,
-  0, 2, 112, 0, 35, 0, 0, 8, 0, 15,
-  15, 0, 16, 4, 70, 57, 0, 21, 0, 58,
-  0, 81, 74, 0, 31, 0, 4, 0, 0, 0,
-  31, 0, 5, 36, 0, 9, 25, 0, 0, 65,
-  0, 19, 22, 10, 17, 20, 19, 22, 19, 0,
-  39, 0, 23, 18, 0, 9, 5, 21, 68, 17,
-  39, 0, 0, 0, 34, 0, 67, 16, 7, 35,
-  9, 16, 42, 18, 111, 0, 19, 7, 30, 4,
-  45, 33, 26, 6, 0, 0, 14, 0, 1, 30,
-  86, 0, 9, 0, 3, 0, 26, 19, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 12, 21, 64, 6,
-  0, 0, 17, 8, 0, 10, 24, 0, 0, 65,
-  0, 74, 92, 76, 35, 40, 22, 3, 39, 33,
-  0, 0, 31, 58, 156, 6, 15, 0, 58, 0,
-  0, 0, 0, 18, 0, 18, 5, 27, 0, 0,
-  53, 31, 0, 18, 0, 0, 0, 47, 40, 0,
-  10, 0, 0, 9, 0, 6, 28, 0, 0, 0,
-  0, 7, 44, 0, 48, 45, 0, 16, 17, 16,
-  28, 6, 22, 3, 0, 16, 38, 0, 14, 0,
-  0, 13, 0, 23, 45, 25, 8, 25, 0, 0,
-  67, 0, 51, 0, 0, 39, 3, 0, 27, 11,
-  67, 0, 18, 0, 0, 0, 20, 21, 9, 43,
-  3, 0, 12, 0, 0, 0, 64, 0, 5, 0,
-  0, 0, 55, 0, 56, 59, 50, 27, 4, 0,
-  2, 0, 0, 0, 8, 0, 48, 60, 4, 28,
-  76, 49, 0, 0, 0, 6, 1, 61, 24, 0,
-  35, 40, 0, 0, 13, 0, 67, 0, 0, 0,
-  0, 0, 0, 1, 0, 66, 2, 0, 30, 28,
-  26, 42, 0, 12, 0, 69, 96, 0, 23, 0,
-  0, 0, 0, 0, 51, 0, 0, 65, 0, 8,
-  82, 0, 40, 45, 0, 20, 0, 33, 32, 0,
-  14, 3, 0, 16, 42, 0, 37, 0, 0, 30,
-  0, 27, 36, 9, 13, 0, 0, 22, 2, 0,
-  70, 5, 0, 64, 0, 23, 40, 0, 76, 0,
-  6, 0, 58, 8, 17, 40, 5, 0, 26, 0,
-  1, 0, 0, 0, 39, 0, 71, 0, 10, 9,
-  14, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 39, 14, 0,
-  0, 0, 63, 31, 0, 36, 15, 0, 0, 12,
-  10, 93, 23, 78, 37, 39, 52, 0, 44, 62,
-  9, 23, 34, 48, 251, 53, 0, 0, 103, 0,
-  11, 0, 0, 19, 12, 43, 34, 0, 10, 7,
-  84, 61, 0, 22, 0, 69, 0, 28, 41, 0,
-  20, 0, 7, 14, 0, 3, 6, 7, 15, 0,
-  0, 16, 25, 16, 0, 28, 0, 14, 83, 9,
-  21, 62, 7, 4, 7, 0, 53, 0, 16, 0,
-  0, 1, 0, 4, 66, 24, 50, 9, 0, 0,
-  69, 27, 15, 2, 14, 33, 3, 0, 1, 18,
-  73, 0, 43, 0, 0, 6, 26, 16, 10, 44,
-  0, 0, 22, 18, 0, 41, 77, 0, 0, 0,
-  0, 0, 27, 20, 27, 77, 56, 1, 0, 0,
-  53, 33, 0, 26, 0, 19, 15, 40, 3, 80,
-  27, 70, 9, 40, 13, 19, 51, 56, 1, 0,
-  62, 39, 168, 33, 0, 2, 112, 0, 35, 0,
-  0, 8, 0, 15, 15, 0, 16, 4, 70, 57,
-  0, 21, 0, 58, 0, 81, 74, 0, 31, 0,
-  4, 0, 0, 0, 31, 0, 5, 36, 0, 9,
-  25, 0, 0, 65, 0, 19, 22, 10, 17, 20,
-  19, 22, 19, 0, 39, 0, 23, 18, 0, 9,
-  5, 21, 68, 17, 39, 0, 0, 0, 34, 0,
-  67, 16, 7, 35, 9, 16, 42, 18, 111, 0,
-  19, 7, 30, 4, 45, 33, 26, 6, 0, 0,
-  14, 0, 1, 30, 86, 0, 9, 0, 3, 0,
-  26, 19, 51, 73, 59, 31, 0, 25, 25, 27,
-  1, 0, 0, 49, 62, 54, 0, 17, 9, 31,
-  5, 0, 0, 97, 24, 47, 40, 0, 67, 36,
-  173, 0, 0, 93, 100, 0, 16, 5, 0, 0,
-  0, 8, 0, 0, 58, 12, 35, 124, 53, 23,
-  0, 49, 0, 76, 26, 0, 69, 0, 16, 0,
-  0, 0, 74, 49, 11, 40, 2, 17, 33, 10,
-  4, 69, 21, 19, 13, 0, 5, 0, 39, 35,
-  1, 0, 24, 0, 46, 72, 0, 11, 18, 1,
-  41, 28, 0, 0, 0, 0, 0, 0, 56, 0,
-  0, 45, 33, 55, 30, 39, 114, 0, 28, 15,
-  40, 0, 15, 24, 15, 0, 0, 0, 36, 0,
-  25, 27, 59, 0, 0, 0, 16, 0, 11, 50,
-  12, 21, 64, 6, 0, 0, 17, 8, 0, 10,
-  24, 0, 0, 65, 0, 74, 92, 76, 35, 40,
-  22, 3, 39, 33, 0, 0, 31, 58, 156, 6,
-  15, 0, 58, 0, 0, 0, 0, 18, 0, 18,
-  5, 27, 0, 0, 53, 31, 0, 18, 0, 0,
-  0, 47, 40, 0, 10, 0, 0, 9, 0, 6,
-  28, 0, 0, 0, 0, 7, 44, 0, 48, 45,
-  0, 16, 17, 16, 28, 6, 22, 3, 0, 16,
-  38, 0, 14, 0, 0, 13, 0, 23, 45, 25,
-  8, 25, 0, 0, 67, 0, 51, 0, 0, 39,
-  3, 0, 27, 11, 67, 0, 18, 0, 0, 0,
-  20, 21, 9, 43, 3, 0, 12, 0, 0, 0,
-  64, 0, 5, 0, 0, 0, 55, 0, 56, 59,
-  50, 27, 4, 0, 2, 0, 0, 0, 8, 0,
-  48, 60, 4, 28, 76, 49, 0, 0, 0, 6,
-  1, 61, 24, 0, 35, 40, 0, 0, 13, 0,
-  67, 0, 0, 0, 0, 0, 0, 1, 0, 66,
-  2, 0, 30, 28, 26, 42, 0, 12, 0, 69,
-  96, 0, 23, 0, 0, 0, 0, 0, 51, 0,
-  0, 65, 0, 8, 82, 0, 40, 45, 0, 20,
-  0, 33, 32, 0, 14, 3, 0, 16, 42, 0,
-  37, 0, 0, 30, 0, 27, 36, 9, 13, 0,
-  0, 22, 2, 0, 70, 5, 0, 64, 0, 23,
-  40, 0, 76, 0, 6, 0, 58, 8, 17, 40,
-  5, 0, 26, 0, 1, 0, 0, 0, 39, 0,
-  71, 0, 10, 9, 14, 0, 2, 55, 59, 38,
-  4, 35, 16, 13, 17, 0, 0, 16, 84, 0,
-  0, 22, 51, 18, 0, 0, 0, 56, 0, 33,
-  67, 0, 5, 30, 0, 0, 0, 43, 70, 0,
-  18, 0, 0, 0, 0, 41, 0, 35, 57, 2,
-  29, 80, 44, 19, 0, 21, 0, 34, 36, 10,
-  35, 0, 10, 0, 0, 0, 30, 26, 0, 32,
-  0, 0, 35, 1, 27, 0, 0, 17, 9, 19,
-  26, 0, 10, 16, 0, 22, 23, 0, 61, 69,
-  0, 5, 0, 0, 0, 42, 5, 0, 0, 31,
-  0, 24, 35, 0, 0, 65, 2, 0, 10, 12,
-  63, 0, 37, 0, 27, 0, 0, 14, 0, 0,
-  0, 0, 0, 0, 0, 0, 4, 0, 41, 0,
-  35, 0, 8, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 27, 77,
-  56, 1, 0, 0, 53, 33, 0, 26, 0, 19,
-  15, 40, 3, 80, 27, 70, 9, 40, 13, 19,
-  51, 56, 1, 0, 62, 39, 168, 33, 0, 2,
-  112, 0, 35, 0, 0, 8, 0, 15, 15, 0,
-  16, 4, 70, 57, 0, 21, 0, 58, 0, 81,
-  74, 0, 31, 0, 4, 0, 0, 0, 31, 0,
-  5, 36, 0, 9, 25, 0, 0, 65, 0, 19,
-  22, 10, 17, 20, 19, 22, 19, 0, 39, 0,
-  23, 18, 0, 9, 5, 21, 68, 17, 39, 0,
-  0, 0, 34, 0, 67, 16, 7, 35, 9, 16,
-  42, 18, 111, 0, 19, 7, 30, 4, 45, 33,
-  26, 6, 0, 0, 14, 0, 1, 30, 86, 0,
-  9, 0, 3, 0, 26, 19, 51, 73, 59, 31,
-  0, 25, 25, 27, 1, 0, 0, 49, 62, 54,
-  0, 17, 9, 31, 5, 0, 0, 97, 24, 47,
-  40, 0, 67, 36, 173, 0, 0, 93, 100, 0,
-  16, 5, 0, 0, 0, 8, 0, 0, 58, 12,
-  35, 124, 53, 23, 0, 49, 0, 76, 26, 0,
-  69, 0, 16, 0, 0, 0, 74, 49, 11, 40,
-  2, 17, 33, 10, 4, 69, 21, 19, 13, 0,
-  5, 0, 39, 35, 1, 0, 24, 0, 46, 72,
-  0, 11, 18, 1, 41, 28, 0, 0, 0, 0,
-  0, 0, 56, 0, 0, 45, 33, 55, 30, 39,
-  114, 0, 28, 15, 40, 0, 15, 24, 15, 0,
-  0, 0, 36, 0, 25, 27, 59, 0, 0, 0,
-  16, 0, 11, 50, 1, 0, 0, 19, 11, 92,
-  28, 0, 0, 0, 0, 57, 41, 55, 0, 0,
-  0, 21, 17, 3, 0, 71, 14, 58, 40, 0,
-  38, 15, 173, 20, 0, 66, 63, 35, 0, 0,
-  0, 0, 0, 44, 0, 0, 10, 45, 6, 158,
-  67, 62, 0, 26, 0, 54, 50, 0, 21, 0,
-  34, 0, 34, 0, 70, 66, 0, 18, 13, 4,
-  36, 35, 62, 39, 52, 9, 43, 0, 28, 0,
-  37, 0, 0, 0, 49, 0, 22, 62, 0, 0,
-  39, 14, 21, 0, 0, 25, 16, 0, 24, 37,
-  0, 0, 11, 49, 15, 31, 12, 45, 82, 9,
-  31, 0, 0, 16, 0, 14, 0, 7, 0, 44,
-  106, 21, 47, 22, 46, 0, 0, 0, 16, 0,
-  13, 16, 56, 59, 50, 27, 4, 0, 2, 0,
-  0, 0, 8, 0, 48, 60, 4, 28, 76, 49,
-  0, 0, 0, 6, 1, 61, 24, 0, 35, 40,
-  0, 0, 13, 0, 67, 0, 0, 0, 0, 0,
-  0, 1, 0, 66, 2, 0, 30, 28, 26, 42,
-  0, 12, 0, 69, 96, 0, 23, 0, 0, 0,
-  0, 0, 51, 0, 0, 65, 0, 8, 82, 0,
-  40, 45, 0, 20, 0, 33, 32, 0, 14, 3,
-  0, 16, 42, 0, 37, 0, 0, 30, 0, 27,
-  36, 9, 13, 0, 0, 22, 2, 0, 70, 5,
-  0, 64, 0, 23, 40, 0, 76, 0, 6, 0,
-  58, 8, 17, 40, 5, 0, 26, 0, 1, 0,
-  0, 0, 39, 0, 71, 0, 10, 9, 14, 0,
-  2, 55, 59, 38, 4, 35, 16, 13, 17, 0,
-  0, 16, 84, 0, 0, 22, 51, 18, 0, 0,
-  0, 56, 0, 33, 67, 0, 5, 30, 0, 0,
-  0, 43, 70, 0, 18, 0, 0, 0, 0, 41,
-  0, 35, 57, 2, 29, 80, 44, 19, 0, 21,
-  0, 34, 36, 10, 35, 0, 10, 0, 0, 0,
-  30, 26, 0, 32, 0, 0, 35, 1, 27, 0,
-  0, 17, 9, 19, 26, 0, 10, 16, 0, 22,
-  23, 0, 61, 69, 0, 5, 0, 0, 0, 42,
-  5, 0, 0, 31, 0, 24, 35, 0, 0, 65,
-  2, 0, 10, 12, 63, 0, 37, 0, 27, 0,
-  0, 14, 0, 0, 0, 0, 0, 0, 0, 0,
-  4, 0, 41, 0, 35, 0, 8, 0, 0, 0,
-  0, 18, 14, 124, 8, 0, 7, 0, 0, 29,
-  52, 11, 0, 6, 15, 0, 0, 0, 0, 77,
-  2, 24, 40, 0, 0, 9, 0, 14, 0, 31,
-  15, 32, 0, 0, 0, 21, 0, 76, 0, 37,
-  0, 65, 12, 85, 61, 31, 0, 0, 0, 31,
-  31, 4, 2, 0, 40, 0, 18, 0, 23, 69,
-  0, 16, 12, 9, 0, 29, 58, 0, 39, 20,
-  11, 0, 25, 21, 19, 0, 0, 29, 42, 0,
-  16, 44, 15, 0, 11, 0, 0, 8, 0, 6,
-  0, 0, 4, 72, 0, 0, 0, 72, 0, 0,
-  4, 12, 57, 0, 27, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 77, 0, 47, 0, 6, 3,
-  0, 0, 55, 0, 22, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  51, 73, 59, 31, 0, 25, 25, 27, 1, 0,
-  0, 49, 62, 54, 0, 17, 9, 31, 5, 0,
-  0, 97, 24, 47, 40, 0, 67, 36, 173, 0,
-  0, 93, 100, 0, 16, 5, 0, 0, 0, 8,
-  0, 0, 58, 12, 35, 124, 53, 23, 0, 49,
-  0, 76, 26, 0, 69, 0, 16, 0, 0, 0,
-  74, 49, 11, 40, 2, 17, 33, 10, 4, 69,
-  21, 19, 13, 0, 5, 0, 39, 35, 1, 0,
-  24, 0, 46, 72, 0, 11, 18, 1, 41, 28,
-  0, 0, 0, 0, 0, 0, 56, 0, 0, 45,
-  33, 55, 30, 39, 114, 0, 28, 15, 40, 0,
-  15, 24, 15, 0, 0, 0, 36, 0, 25, 27,
-  59, 0, 0, 0, 16, 0, 11, 50, 1, 0,
-  0, 19, 11, 92, 28, 0, 0, 0, 0, 57,
-  41, 55, 0, 0, 0, 21, 17, 3, 0, 71,
-  14, 58, 40, 0, 38, 15, 173, 20, 0, 66,
-  63, 35, 0, 0, 0, 0, 0, 44, 0, 0,
-  10, 45, 6, 158, 67, 62, 0, 26, 0, 54,
-  50, 0, 21, 0, 34, 0, 34, 0, 70, 66,
-  0, 18, 13, 4, 36, 35, 62, 39, 52, 9,
-  43, 0, 28, 0, 37, 0, 0, 0, 49, 0,
-  22, 62, 0, 0, 39, 14, 21, 0, 0, 25,
-  16, 0, 24, 37, 0, 0, 11, 49, 15, 31,
-  12, 45, 82, 9, 31, 0, 0, 16, 0, 14,
-  0, 7, 0, 44, 106, 21, 47, 22, 46, 0,
-  0, 0, 16, 0, 13, 16, 0, 38, 0, 0,
-  45, 3, 47, 0, 0, 5, 2, 35, 43, 41,
-  0, 12, 6, 26, 23, 27, 41, 0, 0, 68,
-  18, 30, 36, 25, 149, 46, 0, 0, 61, 42,
-  0, 0, 0, 0, 0, 81, 0, 0, 0, 48,
-  15, 76, 31, 35, 0, 47, 0, 53, 104, 0,
-  0, 15, 21, 0, 0, 5, 36, 26, 0, 63,
-  0, 10, 50, 5, 36, 4, 6, 13, 12, 0,
-  42, 49, 0, 0, 30, 0, 84, 0, 8, 23,
-  8, 1, 28, 38, 67, 0, 15, 10, 39, 0,
-  22, 34, 0, 0, 46, 45, 0, 15, 23, 0,
-  43, 0, 19, 15, 9, 58, 9, 7, 0, 4,
-  0, 0, 41, 21, 33, 22, 54, 6, 20, 0,
-  41, 0, 6, 0, 2, 55, 59, 38, 4, 35,
-  16, 13, 17, 0, 0, 16, 84, 0, 0, 22,
-  51, 18, 0, 0, 0, 56, 0, 33, 67, 0,
-  5, 30, 0, 0, 0, 43, 70, 0, 18, 0,
-  0, 0, 0, 41, 0, 35, 57, 2, 29, 80,
-  44, 19, 0, 21, 0, 34, 36, 10, 35, 0,
-  10, 0, 0, 0, 30, 26, 0, 32, 0, 0,
-  35, 1, 27, 0, 0, 17, 9, 19, 26, 0,
-  10, 16, 0, 22, 23, 0, 61, 69, 0, 5,
-  0, 0, 0, 42, 5, 0, 0, 31, 0, 24,
-  35, 0, 0, 65, 2, 0, 10, 12, 63, 0,
-  37, 0, 27, 0, 0, 14, 0, 0, 0, 0,
-  0, 0, 0, 0, 4, 0, 41, 0, 35, 0,
-  8, 0, 0, 0, 0, 18, 14, 124, 8, 0,
-  7, 0, 0, 29, 52, 11, 0, 6, 15, 0,
-  0, 0, 0, 77, 2, 24, 40, 0, 0, 9,
-  0, 14, 0, 31, 15, 32, 0, 0, 0, 21,
-  0, 76, 0, 37, 0, 65, 12, 85, 61, 31,
-  0, 0, 0, 31, 31, 4, 2, 0, 40, 0,
-  18, 0, 23, 69, 0, 16, 12, 9, 0, 29,
-  58, 0, 39, 20, 11, 0, 25, 21, 19, 0,
-  0, 29, 42, 0, 16, 44, 15, 0, 11, 0,
-  0, 8, 0, 6, 0, 0, 4, 72, 0, 0,
-  0, 72, 0, 0, 4, 12, 57, 0, 27, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 77, 0,
-  47, 0, 6, 3, 0, 0, 55, 0, 22, 0,
-  0, 12, 0, 0, 34, 31, 37, 0, 16, 0,
-  1, 11, 52, 11, 10, 28, 23, 12, 0, 12,
-  51, 0, 0, 50, 24, 48, 0, 15, 0, 35,
-  0, 0, 38, 48, 0, 0, 0, 6, 0, 75,
-  0, 43, 0, 59, 29, 41, 15, 15, 0, 19,
-  0, 15, 107, 18, 0, 0, 17, 0, 0, 28,
-  25, 21, 0, 41, 0, 0, 45, 6, 26, 0,
-  0, 8, 0, 14, 33, 51, 4, 0, 0, 28,
-  84, 14, 0, 6, 19, 0, 12, 21, 18, 26,
-  0, 9, 9, 21, 0, 72, 0, 4, 31, 72,
-  0, 0, 2, 0, 39, 0, 26, 7, 9, 48,
-  0, 0, 0, 3, 0, 0, 39, 24, 41, 0,
-  37, 0, 84, 0, 64, 0, 13, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 1, 0, 0, 19, 11, 92, 28, 0,
-  0, 0, 0, 57, 41, 55, 0, 0, 0, 21,
-  17, 3, 0, 71, 14, 58, 40, 0, 38, 15,
-  173, 20, 0, 66, 63, 35, 0, 0, 0, 0,
-  0, 44, 0, 0, 10, 45, 6, 158, 67, 62,
-  0, 26, 0, 54, 50, 0, 21, 0, 34, 0,
-  34, 0, 70, 66, 0, 18, 13, 4, 36, 35,
-  62, 39, 52, 9, 43, 0, 28, 0, 37, 0,
-  0, 0, 49, 0, 22, 62, 0, 0, 39, 14,
-  21, 0, 0, 25, 16, 0, 24, 37, 0, 0,
-  11, 49, 15, 31, 12, 45, 82, 9, 31, 0,
-  0, 16, 0, 14, 0, 7, 0, 44, 106, 21,
-  47, 22, 46, 0, 0, 0, 16, 0, 13, 16,
-  0, 38, 0, 0, 45, 3, 47, 0, 0, 5,
-  2, 35, 43, 41, 0, 12, 6, 26, 23, 27,
-  41, 0, 0, 68, 18, 30, 36, 25, 149, 46,
-  0, 0, 61, 42, 0, 0, 0, 0, 0, 81,
-  0, 0, 0, 48, 15, 76, 31, 35, 0, 47,
-  0, 53, 104, 0, 0, 15, 21, 0, 0, 5,
-  36, 26, 0, 63, 0, 10, 50, 5, 36, 4,
-  6, 13, 12, 0, 42, 49, 0, 0, 30, 0,
-  84, 0, 8, 23, 8, 1, 28, 38, 67, 0,
-  15, 10, 39, 0, 22, 34, 0, 0, 46, 45,
-  0, 15, 23, 0, 43, 0, 19, 15, 9, 58,
-  9, 7, 0, 4, 0, 0, 41, 21, 33, 22,
-  54, 6, 20, 0, 41, 0, 6, 0, 0, 46,
-  0, 5, 8, 0, 87, 3, 13, 14, 0, 39,
-  38, 29, 17, 42, 21, 66, 26, 57, 83, 0,
-  35, 35, 10, 13, 59, 37, 156, 43, 0, 0,
-  97, 0, 28, 0, 0, 0, 0, 60, 0, 0,
-  0, 58, 6, 89, 17, 14, 0, 43, 0, 39,
-  81, 11, 0, 0, 23, 0, 0, 26, 0, 12,
-  14, 12, 0, 0, 12, 25, 19, 1, 23, 0,
-  31, 0, 56, 15, 12, 6, 36, 0, 63, 0,
-  17, 12, 2, 0, 24, 1, 58, 22, 24, 0,
-  0, 0, 11, 31, 0, 0, 72, 22, 0, 0,
-  23, 0, 40, 0, 15, 32, 13, 36, 18, 8,
-  0, 1, 0, 0, 17, 8, 16, 23, 55, 3,
-  28, 0, 23, 0, 16, 0, 0, 0, 0, 18,
-  14, 124, 8, 0, 7, 0, 0, 29, 52, 11,
-  0, 6, 15, 0, 0, 0, 0, 77, 2, 24,
-  40, 0, 0, 9, 0, 14, 0, 31, 15, 32,
-  0, 0, 0, 21, 0, 76, 0, 37, 0, 65,
-  12, 85, 61, 31, 0, 0, 0, 31, 31, 4,
-  2, 0, 40, 0, 18, 0, 23, 69, 0, 16,
-  12, 9, 0, 29, 58, 0, 39, 20, 11, 0,
-  25, 21, 19, 0, 0, 29, 42, 0, 16, 44,
-  15, 0, 11, 0, 0, 8, 0, 6, 0, 0,
-  4, 72, 0, 0, 0, 72, 0, 0, 4, 12,
-  57, 0, 27, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 77, 0, 47, 0, 6, 3, 0, 0,
-  55, 0, 22, 0, 0, 12, 0, 0, 34, 31,
-  37, 0, 16, 0, 1, 11, 52, 11, 10, 28,
-  23, 12, 0, 12, 51, 0, 0, 50, 24, 48,
-  0, 15, 0, 35, 0, 0, 38, 48, 0, 0,
-  0, 6, 0, 75, 0, 43, 0, 59, 29, 41,
-  15, 15, 0, 19, 0, 15, 107, 18, 0, 0,
-  17, 0, 0, 28, 25, 21, 0, 41, 0, 0,
-  45, 6, 26, 0, 0, 8, 0, 14, 33, 51,
-  4, 0, 0, 28, 84, 14, 0, 6, 19, 0,
-  12, 21, 18, 26, 0, 9, 9, 21, 0, 72,
-  0, 4, 31, 72, 0, 0, 2, 0, 39, 0,
-  26, 7, 9, 48, 0, 0, 0, 3, 0, 0,
-  39, 24, 41, 0, 37, 0, 84, 0, 64, 0,
-  13, 0, 0, 32, 0, 0, 20, 0, 56, 0,
-  35, 0, 0, 29, 28, 20, 52, 24, 39, 50,
-  3, 36, 95, 0, 10, 21, 21, 25, 9, 34,
-  0, 29, 0, 0, 63, 0, 10, 0, 0, 0,
-  0, 48, 0, 3, 0, 63, 16, 61, 5, 1,
-  0, 6, 0, 3, 79, 33, 0, 0, 18, 0,
-  0, 7, 0, 7, 0, 0, 0, 0, 32, 20,
-  20, 0, 0, 0, 0, 0, 62, 0, 13, 2,
-  0, 6, 67, 26, 0, 0, 6, 0, 7, 0,
-  11, 49, 18, 0, 0, 4, 0, 55, 0, 6,
-  64, 36, 0, 0, 3, 0, 34, 0, 22, 9,
-  31, 35, 0, 0, 0, 0, 0, 0, 14, 2,
-  12, 0, 45, 0, 77, 0, 41, 0, 26, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 38, 0, 0, 45, 3,
-  47, 0, 0, 5, 2, 35, 43, 41, 0, 12,
-  6, 26, 23, 27, 41, 0, 0, 68, 18, 30,
-  36, 25, 149, 46, 0, 0, 61, 42, 0, 0,
-  0, 0, 0, 81, 0, 0, 0, 48, 15, 76,
-  31, 35, 0, 47, 0, 53, 104, 0, 0, 15,
-  21, 0, 0, 5, 36, 26, 0, 63, 0, 10,
-  50, 5, 36, 4, 6, 13, 12, 0, 42, 49,
-  0, 0, 30, 0, 84, 0, 8, 23, 8, 1,
-  28, 38, 67, 0, 15, 10, 39, 0, 22, 34,
-  0, 0, 46, 45, 0, 15, 23, 0, 43, 0,
-  19, 15, 9, 58, 9, 7, 0, 4, 0, 0,
-  41, 21, 33, 22, 54, 6, 20, 0, 41, 0,
-  6, 0, 0, 46, 0, 5, 8, 0, 87, 3,
-  13, 14, 0, 39, 38, 29, 17, 42, 21, 66,
-  26, 57, 83, 0, 35, 35, 10, 13, 59, 37,
-  156, 43, 0, 0, 97, 0, 28, 0, 0, 0,
-  0, 60, 0, 0, 0, 58, 6, 89, 17, 14,
-  0, 43, 0, 39, 81, 11, 0, 0, 23, 0,
-  0, 26, 0, 12, 14, 12, 0, 0, 12, 25,
-  19, 1, 23, 0, 31, 0, 56, 15, 12, 6,
-  36, 0, 63, 0, 17, 12, 2, 0, 24, 1,
-  58, 22, 24, 0, 0, 0, 11, 31, 0, 0,
-  72, 22, 0, 0, 23, 0, 40, 0, 15, 32,
-  13, 36, 18, 8, 0, 1, 0, 0, 17, 8,
-  16, 23, 55, 3, 28, 0, 23, 0, 16, 0,
-  0, 26, 0, 19, 10, 0, 77, 11, 23, 31,
-  0, 35, 23, 57, 9, 52, 22, 74, 37, 27,
-  102, 0, 0, 31, 15, 13, 55, 46, 154, 59,
-  0, 4, 97, 0, 27, 0, 0, 0, 0, 55,
-  0, 0, 0, 52, 12, 66, 15, 9, 0, 41,
-  0, 76, 57, 46, 4, 14, 7, 0, 0, 16,
-  0, 0, 24, 8, 0, 8, 10, 17, 12, 30,
-  0, 0, 27, 0, 37, 13, 12, 0, 23, 0,
-  76, 0, 17, 2, 0, 0, 21, 18, 71, 15,
-  30, 0, 0, 0, 29, 12, 20, 0, 83, 41,
-  0, 0, 20, 0, 63, 0, 2, 35, 27, 25,
-  17, 5, 25, 0, 6, 0, 30, 0, 13, 13,
-  58, 0, 47, 0, 29, 0, 20, 0, 0, 12,
-  0, 0, 34, 31, 37, 0, 16, 0, 1, 11,
-  52, 11, 10, 28, 23, 12, 0, 12, 51, 0,
-  0, 50, 24, 48, 0, 15, 0, 35, 0, 0,
-  38, 48, 0, 0, 0, 6, 0, 75, 0, 43,
-  0, 59, 29, 41, 15, 15, 0, 19, 0, 15,
-  107, 18, 0, 0, 17, 0, 0, 28, 25, 21,
-  0, 41, 0, 0, 45, 6, 26, 0, 0, 8,
-  0, 14, 33, 51, 4, 0, 0, 28, 84, 14,
-  0, 6, 19, 0, 12, 21, 18, 26, 0, 9,
-  9, 21, 0, 72, 0, 4, 31, 72, 0, 0,
-  2, 0, 39, 0, 26, 7, 9, 48, 0, 0,
-  0, 3, 0, 0, 39, 24, 41, 0, 37, 0,
-  84, 0, 64, 0, 13, 0, 0, 32, 0, 0,
-  20, 0, 56, 0, 35, 0, 0, 29, 28, 20,
-  52, 24, 39, 50, 3, 36, 95, 0, 10, 21,
-  21, 25, 9, 34, 0, 29, 0, 0, 63, 0,
-  10, 0, 0, 0, 0, 48, 0, 3, 0, 63,
-  16, 61, 5, 1, 0, 6, 0, 3, 79, 33,
-  0, 0, 18, 0, 0, 7, 0, 7, 0, 0,
-  0, 0, 32, 20, 20, 0, 0, 0, 0, 0,
-  62, 0, 13, 2, 0, 6, 67, 26, 0, 0,
-  6, 0, 7, 0, 11, 49, 18, 0, 0, 4,
-  0, 55, 0, 6, 64, 36, 0, 0, 3, 0,
-  34, 0, 22, 9, 31, 35, 0, 0, 0, 0,
-  0, 0, 14, 2, 12, 0, 45, 0, 77, 0,
-  41, 0, 26, 0, 0, 27, 0, 15, 17, 0,
-  54, 0, 26, 19, 0, 24, 19, 41, 54, 36,
-  42, 53, 0, 29, 105, 0, 0, 24, 36, 35,
-  13, 47, 0, 36, 0, 0, 67, 9, 22, 0,
-  0, 0, 0, 30, 0, 0, 0, 58, 16, 44,
-  12, 18, 0, 3, 21, 11, 61, 51, 0, 0,
-  3, 0, 0, 16, 0, 0, 0, 0, 0, 0,
-  38, 18, 25, 0, 0, 0, 0, 0, 56, 0,
-  14, 7, 0, 10, 79, 42, 2, 0, 11, 0,
-  6, 6, 16, 33, 14, 0, 0, 12, 0, 42,
-  0, 6, 83, 38, 0, 0, 5, 0, 37, 0,
-  29, 9, 43, 27, 0, 0, 1, 0, 0, 0,
-  12, 0, 2, 0, 32, 0, 100, 0, 40, 0,
-  22, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 46, 0, 5,
-  8, 0, 87, 3, 13, 14, 0, 39, 38, 29,
-  17, 42, 21, 66, 26, 57, 83, 0, 35, 35,
-  10, 13, 59, 37, 156, 43, 0, 0, 97, 0,
-  28, 0, 0, 0, 0, 60, 0, 0, 0, 58,
-  6, 89, 17, 14, 0, 43, 0, 39, 81, 11,
-  0, 0, 23, 0, 0, 26, 0, 12, 14, 12,
-  0, 0, 12, 25, 19, 1, 23, 0, 31, 0,
-  56, 15, 12, 6, 36, 0, 63, 0, 17, 12,
-  2, 0, 24, 1, 58, 22, 24, 0, 0, 0,
-  11, 31, 0, 0, 72, 22, 0, 0, 23, 0,
-  40, 0, 15, 32, 13, 36, 18, 8, 0, 1,
-  0, 0, 17, 8, 16, 23, 55, 3, 28, 0,
-  23, 0, 16, 0, 0, 26, 0, 19, 10, 0,
-  77, 11, 23, 31, 0, 35, 23, 57, 9, 52,
-  22, 74, 37, 27, 102, 0, 0, 31, 15, 13,
-  55, 46, 154, 59, 0, 4, 97, 0, 27, 0,
-  0, 0, 0, 55, 0, 0, 0, 52, 12, 66,
-  15, 9, 0, 41, 0, 76, 57, 46, 4, 14,
-  7, 0, 0, 16, 0, 0, 24, 8, 0, 8,
-  10, 17, 12, 30, 0, 0, 27, 0, 37, 13,
-  12, 0, 23, 0, 76, 0, 17, 2, 0, 0,
-  21, 18, 71, 15, 30, 0, 0, 0, 29, 12,
-  20, 0, 83, 41, 0, 0, 20, 0, 63, 0,
-  2, 35, 27, 25, 17, 5, 25, 0, 6, 0,
-  30, 0, 13, 13, 58, 0, 47, 0, 29, 0,
-  20, 0, 0, 16, 0, 14, 1, 0, 63, 29,
-  23, 32, 0, 13, 0, 45, 0, 47, 19, 68,
-  39, 6, 67, 0, 0, 42, 12, 16, 57, 47,
-  121, 62, 0, 0, 87, 0, 30, 0, 0, 0,
-  0, 41, 0, 0, 0, 17, 8, 43, 25, 0,
-  0, 37, 11, 79, 44, 41, 28, 6, 2, 20,
-  0, 16, 0, 0, 13, 18, 0, 16, 25, 5,
-  1, 40, 0, 0, 44, 0, 27, 34, 0, 0,
-  27, 0, 77, 0, 17, 14, 0, 0, 18, 24,
-  76, 0, 60, 4, 0, 4, 30, 0, 46, 0,
-  60, 49, 0, 0, 9, 0, 57, 0, 0, 18,
-  38, 31, 23, 17, 38, 0, 21, 0, 27, 0,
-  7, 10, 58, 0, 64, 0, 40, 0, 0, 0,
-  0, 32, 0, 0, 20, 0, 56, 0, 35, 0,
-  0, 29, 28, 20, 52, 24, 39, 50, 3, 36,
-  95, 0, 10, 21, 21, 25, 9, 34, 0, 29,
-  0, 0, 63, 0, 10, 0, 0, 0, 0, 48,
-  0, 3, 0, 63, 16, 61, 5, 1, 0, 6,
-  0, 3, 79, 33, 0, 0, 18, 0, 0, 7,
-  0, 7, 0, 0, 0, 0, 32, 20, 20, 0,
-  0, 0, 0, 0, 62, 0, 13, 2, 0, 6,
-  67, 26, 0, 0, 6, 0, 7, 0, 11, 49,
-  18, 0, 0, 4, 0, 55, 0, 6, 64, 36,
-  0, 0, 3, 0, 34, 0, 22, 9, 31, 35,
-  0, 0, 0, 0, 0, 0, 14, 2, 12, 0,
-  45, 0, 77, 0, 41, 0, 26, 0, 0, 27,
-  0, 15, 17, 0, 54, 0, 26, 19, 0, 24,
-  19, 41, 54, 36, 42, 53, 0, 29, 105, 0,
-  0, 24, 36, 35, 13, 47, 0, 36, 0, 0,
-  67, 9, 22, 0, 0, 0, 0, 30, 0, 0,
-  0, 58, 16, 44, 12, 18, 0, 3, 21, 11,
-  61, 51, 0, 0, 3, 0, 0, 16, 0, 0,
-  0, 0, 0, 0, 38, 18, 25, 0, 0, 0,
-  0, 0, 56, 0, 14, 7, 0, 10, 79, 42,
-  2, 0, 11, 0, 6, 6, 16, 33, 14, 0,
-  0, 12, 0, 42, 0, 6, 83, 38, 0, 0,
-  5, 0, 37, 0, 29, 9, 43, 27, 0, 0,
-  1, 0, 0, 0, 12, 0, 2, 0, 32, 0,
-  100, 0, 40, 0, 22, 0, 0, 22, 0, 0,
-  8, 0, 32, 0, 33, 28, 0, 1, 0, 29,
-  40, 48, 56, 56, 12, 13, 56, 0, 0, 29,
-  28, 42, 16, 56, 0, 19, 0, 0, 57, 2,
-  6, 0, 0, 0, 0, 24, 0, 0, 0, 16,
-  1, 14, 21, 10, 0, 5, 37, 5, 41, 38,
-  0, 11, 0, 24, 0, 42, 0, 0, 0, 0,
-  0, 0, 70, 24, 23, 0, 0, 0, 11, 21,
-  44, 0, 8, 0, 0, 12, 70, 39, 7, 8,
-  19, 29, 0, 28, 16, 3, 38, 30, 0, 36,
-  4, 7, 0, 4, 60, 56, 0, 0, 5, 0,
-  33, 0, 12, 9, 35, 35, 0, 12, 2, 0,
-  10, 0, 0, 0, 0, 0, 6, 0, 111, 0,
-  30, 0, 9, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 26,
-  0, 19, 10, 0, 77, 11, 23, 31, 0, 35,
-  23, 57, 9, 52, 22, 74, 37, 27, 102, 0,
-  0, 31, 15, 13, 55, 46, 154, 59, 0, 4,
-  97, 0, 27, 0, 0, 0, 0, 55, 0, 0,
-  0, 52, 12, 66, 15, 9, 0, 41, 0, 76,
-  57, 46, 4, 14, 7, 0, 0, 16, 0, 0,
-  24, 8, 0, 8, 10, 17, 12, 30, 0, 0,
-  27, 0, 37, 13, 12, 0, 23, 0, 76, 0,
-  17, 2, 0, 0, 21, 18, 71, 15, 30, 0,
-  0, 0, 29, 12, 20, 0, 83, 41, 0, 0,
-  20, 0, 63, 0, 2, 35, 27, 25, 17, 5,
-  25, 0, 6, 0, 30, 0, 13, 13, 58, 0,
-  47, 0, 29, 0, 20, 0, 0, 16, 0, 14,
-  1, 0, 63, 29, 23, 32, 0, 13, 0, 45,
-  0, 47, 19, 68, 39, 6, 67, 0, 0, 42,
-  12, 16, 57, 47, 121, 62, 0, 0, 87, 0,
-  30, 0, 0, 0, 0, 41, 0, 0, 0, 17,
-  8, 43, 25, 0, 0, 37, 11, 79, 44, 41,
-  28, 6, 2, 20, 0, 16, 0, 0, 13, 18,
-  0, 16, 25, 5, 1, 40, 0, 0, 44, 0,
-  27, 34, 0, 0, 27, 0, 77, 0, 17, 14,
-  0, 0, 18, 24, 76, 0, 60, 4, 0, 4,
-  30, 0, 46, 0, 60, 49, 0, 0, 9, 0,
-  57, 0, 0, 18, 38, 31, 23, 17, 38, 0,
-  21, 0, 27, 0, 7, 10, 58, 0, 64, 0,
-  40, 0, 0, 0, 0, 26, 0, 7, 2, 0,
-  63, 38, 23, 37, 2, 6, 0, 40, 0, 45,
-  6, 67, 46, 14, 38, 0, 0, 48, 16, 24,
-  55, 58, 112, 45, 0, 0, 68, 0, 26, 0,
-  0, 0, 0, 44, 0, 0, 0, 2, 1, 25,
-  39, 0, 0, 36, 14, 72, 25, 35, 35, 0,
-  0, 49, 0, 21, 0, 0, 16, 34, 0, 26,
-  35, 0, 2, 44, 0, 0, 64, 0, 29, 35,
-  0, 1, 39, 0, 66, 5, 11, 30, 0, 6,
-  14, 27, 89, 0, 74, 5, 0, 3, 35, 0,
-  49, 0, 45, 48, 0, 0, 10, 0, 56, 0,
-  0, 23, 42, 24, 30, 23, 39, 0, 31, 0,
-  11, 0, 7, 13, 40, 0, 62, 0, 52, 0,
-  0, 2, 0, 27, 0, 15, 17, 0, 54, 0,
-  26, 19, 0, 24, 19, 41, 54, 36, 42, 53,
-  0, 29, 105, 0, 0, 24, 36, 35, 13, 47,
-  0, 36, 0, 0, 67, 9, 22, 0, 0, 0,
-  0, 30, 0, 0, 0, 58, 16, 44, 12, 18,
-  0, 3, 21, 11, 61, 51, 0, 0, 3, 0,
-  0, 16, 0, 0, 0, 0, 0, 0, 38, 18,
-  25, 0, 0, 0, 0, 0, 56, 0, 14, 7,
-  0, 10, 79, 42, 2, 0, 11, 0, 6, 6,
-  16, 33, 14, 0, 0, 12, 0, 42, 0, 6,
-  83, 38, 0, 0, 5, 0, 37, 0, 29, 9,
-  43, 27, 0, 0, 1, 0, 0, 0, 12, 0,
-  2, 0, 32, 0, 100, 0, 40, 0, 22, 0,
-  0, 22, 0, 0, 8, 0, 32, 0, 33, 28,
-  0, 1, 0, 29, 40, 48, 56, 56, 12, 13,
-  56, 0, 0, 29, 28, 42, 16, 56, 0, 19,
-  0, 0, 57, 2, 6, 0, 0, 0, 0, 24,
-  0, 0, 0, 16, 1, 14, 21, 10, 0, 5,
-  37, 5, 41, 38, 0, 11, 0, 24, 0, 42,
-  0, 0, 0, 0, 0, 0, 70, 24, 23, 0,
-  0, 0, 11, 21, 44, 0, 8, 0, 0, 12,
-  70, 39, 7, 8, 19, 29, 0, 28, 16, 3,
-  38, 30, 0, 36, 4, 7, 0, 4, 60, 56,
-  0, 0, 5, 0, 33, 0, 12, 9, 35, 35,
-  0, 12, 2, 0, 10, 0, 0, 0, 0, 0,
-  6, 0, 111, 0, 30, 0, 9, 0, 0, 40,
-  0, 0, 15, 0, 26, 0, 40, 45, 1, 0,
-  0, 24, 16, 54, 51, 59, 27, 8, 15, 0,
-  0, 41, 35, 63, 9, 78, 0, 0, 8, 0,
-  21, 0, 0, 0, 0, 0, 0, 35, 0, 0,
-  0, 0, 0, 0, 38, 0, 0, 5, 22, 8,
-  24, 27, 0, 0, 0, 65, 0, 36, 0, 0,
-  0, 33, 0, 2, 97, 14, 35, 0, 0, 0,
-  20, 36, 43, 5, 0, 0, 0, 9, 52, 53,
-  0, 20, 31, 37, 0, 46, 33, 0, 42, 41,
-  0, 48, 0, 0, 2, 16, 45, 62, 0, 0,
-  12, 0, 34, 0, 0, 17, 24, 34, 0, 27,
-  0, 0, 25, 0, 0, 14, 10, 0, 0, 8,
-  110, 0, 42, 0, 17, 9, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 16, 0, 14, 1, 0, 63, 29, 23, 32,
-  0, 13, 0, 45, 0, 47, 19, 68, 39, 6,
-  67, 0, 0, 42, 12, 16, 57, 47, 121, 62,
-  0, 0, 87, 0, 30, 0, 0, 0, 0, 41,
-  0, 0, 0, 17, 8, 43, 25, 0, 0, 37,
-  11, 79, 44, 41, 28, 6, 2, 20, 0, 16,
-  0, 0, 13, 18, 0, 16, 25, 5, 1, 40,
-  0, 0, 44, 0, 27, 34, 0, 0, 27, 0,
-  77, 0, 17, 14, 0, 0, 18, 24, 76, 0,
-  60, 4, 0, 4, 30, 0, 46, 0, 60, 49,
-  0, 0, 9, 0, 57, 0, 0, 18, 38, 31,
-  23, 17, 38, 0, 21, 0, 27, 0, 7, 10,
-  58, 0, 64, 0, 40, 0, 0, 0, 0, 26,
-  0, 7, 2, 0, 63, 38, 23, 37, 2, 6,
-  0, 40, 0, 45, 6, 67, 46, 14, 38, 0,
-  0, 48, 16, 24, 55, 58, 112, 45, 0, 0,
-  68, 0, 26, 0, 0, 0, 0, 44, 0, 0,
-  0, 2, 1, 25, 39, 0, 0, 36, 14, 72,
-  25, 35, 35, 0, 0, 49, 0, 21, 0, 0,
-  16, 34, 0, 26, 35, 0, 2, 44, 0, 0,
-  64, 0, 29, 35, 0, 1, 39, 0, 66, 5,
-  11, 30, 0, 6, 14, 27, 89, 0, 74, 5,
-  0, 3, 35, 0, 49, 0, 45, 48, 0, 0,
-  10, 0, 56, 0, 0, 23, 42, 24, 30, 23,
-  39, 0, 31, 0, 11, 0, 7, 13, 40, 0,
-  62, 0, 52, 0, 0, 2, 0, 45, 0, 0,
-  0, 0, 62, 43, 22, 57, 2, 15, 0, 41,
-  7, 47, 6, 61, 60, 24, 15, 0, 0, 43,
-  26, 39, 53, 69, 110, 31, 0, 0, 54, 0,
-  28, 0, 0, 0, 0, 53, 0, 0, 0, 0,
-  3, 7, 35, 0, 0, 41, 15, 67, 26, 42,
-  26, 0, 0, 57, 0, 32, 0, 0, 14, 45,
-  0, 35, 43, 0, 0, 32, 0, 1, 56, 0,
-  32, 31, 0, 8, 48, 0, 66, 25, 6, 25,
-  12, 12, 17, 31, 106, 0, 60, 5, 0, 7,
-  27, 0, 51, 1, 26, 50, 0, 0, 24, 0,
-  67, 0, 2, 18, 45, 33, 35, 9, 30, 0,
-  39, 0, 0, 6, 16, 9, 41, 0, 67, 0,
-  44, 0, 11, 14, 0, 22, 0, 0, 8, 0,
-  32, 0, 33, 28, 0, 1, 0, 29, 40, 48,
-  56, 56, 12, 13, 56, 0, 0, 29, 28, 42,
-  16, 56, 0, 19, 0, 0, 57, 2, 6, 0,
-  0, 0, 0, 24, 0, 0, 0, 16, 1, 14,
-  21, 10, 0, 5, 37, 5, 41, 38, 0, 11,
-  0, 24, 0, 42, 0, 0, 0, 0, 0, 0,
-  70, 24, 23, 0, 0, 0, 11, 21, 44, 0,
-  8, 0, 0, 12, 70, 39, 7, 8, 19, 29,
-  0, 28, 16, 3, 38, 30, 0, 36, 4, 7,
-  0, 4, 60, 56, 0, 0, 5, 0, 33, 0,
-  12, 9, 35, 35, 0, 12, 2, 0, 10, 0,
-  0, 0, 0, 0, 6, 0, 111, 0, 30, 0,
-  9, 0, 0, 40, 0, 0, 15, 0, 26, 0,
-  40, 45, 1, 0, 0, 24, 16, 54, 51, 59,
-  27, 8, 15, 0, 0, 41, 35, 63, 9, 78,
-  0, 0, 8, 0, 21, 0, 0, 0, 0, 0,
-  0, 35, 0, 0, 0, 0, 0, 0, 38, 0,
-  0, 5, 22, 8, 24, 27, 0, 0, 0, 65,
-  0, 36, 0, 0, 0, 33, 0, 2, 97, 14,
-  35, 0, 0, 0, 20, 36, 43, 5, 0, 0,
-  0, 9, 52, 53, 0, 20, 31, 37, 0, 46,
-  33, 0, 42, 41, 0, 48, 0, 0, 2, 16,
-  45, 62, 0, 0, 12, 0, 34, 0, 0, 17,
-  24, 34, 0, 27, 0, 0, 25, 0, 0, 14,
-  10, 0, 0, 8, 110, 0, 42, 0, 17, 9,
-  0, 44, 12, 0, 11, 0, 23, 0, 54, 79,
-  0, 0, 0, 0, 3, 53, 49, 60, 36, 23,
-  0, 0, 0, 42, 29, 49, 27, 93, 0, 0,
-  15, 0, 15, 0, 0, 0, 0, 32, 0, 20,
-  0, 0, 0, 0, 0, 7, 42, 0, 0, 5,
-  12, 12, 37, 19, 0, 0, 0, 60, 0, 25,
-  1, 12, 0, 29, 0, 0, 86, 0, 36, 9,
-  0, 0, 13, 38, 43, 13, 0, 16, 0, 0,
-  60, 35, 0, 10, 27, 23, 0, 45, 43, 0,
-  17, 49, 0, 42, 0, 0, 4, 7, 24, 57,
-  0, 0, 23, 0, 36, 0, 0, 1, 19, 59,
-  0, 22, 0, 0, 36, 0, 0, 24, 28, 0,
-  1, 18, 93, 0, 22, 0, 42, 20, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 26, 0, 7, 2, 0, 63, 38,
-  23, 37, 2, 6, 0, 40, 0, 45, 6, 67,
-  46, 14, 38, 0, 0, 48, 16, 24, 55, 58,
-  112, 45, 0, 0, 68, 0, 26, 0, 0, 0,
-  0, 44, 0, 0, 0, 2, 1, 25, 39, 0,
-  0, 36, 14, 72, 25, 35, 35, 0, 0, 49,
-  0, 21, 0, 0, 16, 34, 0, 26, 35, 0,
-  2, 44, 0, 0, 64, 0, 29, 35, 0, 1,
-  39, 0, 66, 5, 11, 30, 0, 6, 14, 27,
-  89, 0, 74, 5, 0, 3, 35, 0, 49, 0,
-  45, 48, 0, 0, 10, 0, 56, 0, 0, 23,
-  42, 24, 30, 23, 39, 0, 31, 0, 11, 0,
-  7, 13, 40, 0, 62, 0, 52, 0, 0, 2,
-  0, 45, 0, 0, 0, 0, 62, 43, 22, 57,
-  2, 15, 0, 41, 7, 47, 6, 61, 60, 24,
-  15, 0, 0, 43, 26, 39, 53, 69, 110, 31,
-  0, 0, 54, 0, 28, 0, 0, 0, 0, 53,
-  0, 0, 0, 0, 3, 7, 35, 0, 0, 41,
-  15, 67, 26, 42, 26, 0, 0, 57, 0, 32,
-  0, 0, 14, 45, 0, 35, 43, 0, 0, 32,
-  0, 1, 56, 0, 32, 31, 0, 8, 48, 0,
-  66, 25, 6, 25, 12, 12, 17, 31, 106, 0,
-  60, 5, 0, 7, 27, 0, 51, 1, 26, 50,
-  0, 0, 24, 0, 67, 0, 2, 18, 45, 33,
-  35, 9, 30, 0, 39, 0, 0, 6, 16, 9,
-  41, 0, 67, 0, 44, 0, 11, 14, 0, 50,
-  11, 0, 0, 0, 74, 36, 26, 54, 0, 25,
-  0, 0, 19, 41, 32, 80, 62, 25, 0, 0,
-  0, 42, 46, 46, 53, 65, 120, 31, 0, 0,
-  44, 0, 29, 0, 0, 0, 0, 45, 0, 0,
-  34, 0, 9, 14, 37, 0, 0, 29, 26, 40,
-  42, 29, 11, 0, 0, 42, 0, 48, 0, 0,
-  13, 56, 0, 27, 47, 0, 0, 21, 0, 6,
-  37, 0, 32, 21, 1, 6, 34, 0, 57, 25,
-  7, 31, 24, 9, 22, 28, 77, 0, 42, 0,
-  0, 21, 17, 0, 36, 22, 1, 31, 0, 0,
-  35, 0, 70, 0, 6, 12, 44, 44, 51, 12,
-  23, 0, 31, 0, 0, 14, 39, 0, 40, 13,
-  69, 0, 18, 0, 49, 15, 0, 40, 0, 0,
-  15, 0, 26, 0, 40, 45, 1, 0, 0, 24,
-  16, 54, 51, 59, 27, 8, 15, 0, 0, 41,
-  35, 63, 9, 78, 0, 0, 8, 0, 21, 0,
-  0, 0, 0, 0, 0, 35, 0, 0, 0, 0,
-  0, 0, 38, 0, 0, 5, 22, 8, 24, 27,
-  0, 0, 0, 65, 0, 36, 0, 0, 0, 33,
-  0, 2, 97, 14, 35, 0, 0, 0, 20, 36,
-  43, 5, 0, 0, 0, 9, 52, 53, 0, 20,
-  31, 37, 0, 46, 33, 0, 42, 41, 0, 48,
-  0, 0, 2, 16, 45, 62, 0, 0, 12, 0,
-  34, 0, 0, 17, 24, 34, 0, 27, 0, 0,
-  25, 0, 0, 14, 10, 0, 0, 8, 110, 0,
-  42, 0, 17, 9, 0, 44, 12, 0, 11, 0,
-  23, 0, 54, 79, 0, 0, 0, 0, 3, 53,
-  49, 60, 36, 23, 0, 0, 0, 42, 29, 49,
-  27, 93, 0, 0, 15, 0, 15, 0, 0, 0,
-  0, 32, 0, 20, 0, 0, 0, 0, 0, 7,
-  42, 0, 0, 5, 12, 12, 37, 19, 0, 0,
-  0, 60, 0, 25, 1, 12, 0, 29, 0, 0,
-  86, 0, 36, 9, 0, 0, 13, 38, 43, 13,
-  0, 16, 0, 0, 60, 35, 0, 10, 27, 23,
-  0, 45, 43, 0, 17, 49, 0, 42, 0, 0,
-  4, 7, 24, 57, 0, 0, 23, 0, 36, 0,
-  0, 1, 19, 59, 0, 22, 0, 0, 36, 0,
-  0, 24, 28, 0, 1, 18, 93, 0, 22, 0,
-  42, 20, 0, 38, 33, 0, 0, 0, 27, 0,
-  63, 89, 0, 12, 0, 0, 14, 41, 49, 72,
-  30, 11, 0, 0, 0, 57, 37, 23, 43, 98,
-  0, 0, 23, 0, 9, 0, 0, 0, 0, 70,
-  0, 0, 14, 15, 16, 0, 0, 17, 24, 0,
-  0, 0, 12, 0, 48, 0, 0, 0, 0, 33,
-  0, 3, 10, 18, 0, 50, 0, 0, 81, 0,
-  15, 42, 0, 0, 7, 44, 23, 12, 4, 28,
-  0, 0, 63, 33, 2, 27, 31, 25, 2, 25,
-  25, 0, 0, 46, 0, 33, 0, 0, 0, 14,
-  0, 51, 3, 0, 8, 0, 41, 0, 0, 18,
-  2, 64, 10, 19, 0, 0, 55, 0, 0, 23,
-  45, 0, 7, 3, 63, 0, 0, 0, 78, 18,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 45, 0, 0, 0, 0,
-  62, 43, 22, 57, 2, 15, 0, 41, 7, 47,
-  6, 61, 60, 24, 15, 0, 0, 43, 26, 39,
-  53, 69, 110, 31, 0, 0, 54, 0, 28, 0,
-  0, 0, 0, 53, 0, 0, 0, 0, 3, 7,
-  35, 0, 0, 41, 15, 67, 26, 42, 26, 0,
-  0, 57, 0, 32, 0, 0, 14, 45, 0, 35,
-  43, 0, 0, 32, 0, 1, 56, 0, 32, 31,
-  0, 8, 48, 0, 66, 25, 6, 25, 12, 12,
-  17, 31, 106, 0, 60, 5, 0, 7, 27, 0,
-  51, 1, 26, 50, 0, 0, 24, 0, 67, 0,
-  2, 18, 45, 33, 35, 9, 30, 0, 39, 0,
-  0, 6, 16, 9, 41, 0, 67, 0, 44, 0,
-  11, 14, 0, 50, 11, 0, 0, 0, 74, 36,
-  26, 54, 0, 25, 0, 0, 19, 41, 32, 80,
-  62, 25, 0, 0, 0, 42, 46, 46, 53, 65,
-  120, 31, 0, 0, 44, 0, 29, 0, 0, 0,
-  0, 45, 0, 0, 34, 0, 9, 14, 37, 0,
-  0, 29, 26, 40, 42, 29, 11, 0, 0, 42,
-  0, 48, 0, 0, 13, 56, 0, 27, 47, 0,
-  0, 21, 0, 6, 37, 0, 32, 21, 1, 6,
-  34, 0, 57, 25, 7, 31, 24, 9, 22, 28,
-  77, 0, 42, 0, 0, 21, 17, 0, 36, 22,
-  1, 31, 0, 0, 35, 0, 70, 0, 6, 12,
-  44, 44, 51, 12, 23, 0, 31, 0, 0, 14,
-  39, 0, 40, 13, 69, 0, 18, 0, 49, 15,
-  0, 53, 6, 0, 0, 0, 108, 18, 35, 62,
-  0, 10, 0, 0, 14, 70, 19, 66, 42, 16,
-  0, 0, 0, 59, 58, 43, 47, 64, 123, 32,
-  0, 0, 54, 0, 29, 0, 0, 0, 9, 45,
-  0, 0, 26, 16, 0, 23, 56, 0, 0, 30,
-  14, 43, 57, 13, 7, 3, 3, 60, 0, 52,
-  0, 9, 11, 62, 0, 31, 41, 10, 20, 3,
-  0, 13, 31, 0, 45, 36, 0, 0, 32, 0,
-  56, 38, 10, 21, 24, 0, 26, 22, 84, 1,
-  35, 0, 0, 34, 0, 0, 6, 15, 19, 40,
-  0, 0, 26, 0, 74, 0, 0, 29, 37, 36,
-  50, 12, 2, 0, 29, 0, 0, 35, 51, 0,
-  32, 0, 64, 0, 33, 0, 43, 1, 0, 44,
-  12, 0, 11, 0, 23, 0, 54, 79, 0, 0,
-  0, 0, 3, 53, 49, 60, 36, 23, 0, 0,
-  0, 42, 29, 49, 27, 93, 0, 0, 15, 0,
-  15, 0, 0, 0, 0, 32, 0, 20, 0, 0,
-  0, 0, 0, 7, 42, 0, 0, 5, 12, 12,
-  37, 19, 0, 0, 0, 60, 0, 25, 1, 12,
-  0, 29, 0, 0, 86, 0, 36, 9, 0, 0,
-  13, 38, 43, 13, 0, 16, 0, 0, 60, 35,
-  0, 10, 27, 23, 0, 45, 43, 0, 17, 49,
-  0, 42, 0, 0, 4, 7, 24, 57, 0, 0,
-  23, 0, 36, 0, 0, 1, 19, 59, 0, 22,
-  0, 0, 36, 0, 0, 24, 28, 0, 1, 18,
-  93, 0, 22, 0, 42, 20, 0, 38, 33, 0,
-  0, 0, 27, 0, 63, 89, 0, 12, 0, 0,
-  14, 41, 49, 72, 30, 11, 0, 0, 0, 57,
-  37, 23, 43, 98, 0, 0, 23, 0, 9, 0,
-  0, 0, 0, 70, 0, 0, 14, 15, 16, 0,
-  0, 17, 24, 0, 0, 0, 12, 0, 48, 0,
-  0, 0, 0, 33, 0, 3, 10, 18, 0, 50,
-  0, 0, 81, 0, 15, 42, 0, 0, 7, 44,
-  23, 12, 4, 28, 0, 0, 63, 33, 2, 27,
-  31, 25, 2, 25, 25, 0, 0, 46, 0, 33,
-  0, 0, 0, 14, 0, 51, 3, 0, 8, 0,
-  41, 0, 0, 18, 2, 64, 10, 19, 0, 0,
-  55, 0, 0, 23, 45, 0, 7, 3, 63, 0,
-  0, 0, 78, 18, 0, 39, 39, 0, 0, 0,
-  25, 0, 78, 78, 0, 0, 0, 3, 0, 17,
-  3, 41, 11, 0, 0, 0, 16, 61, 36, 0,
-  50, 80, 0, 0, 9, 0, 0, 0, 0, 0,
-  16, 73, 0, 0, 40, 8, 4, 0, 0, 14,
-  31, 0, 0, 0, 18, 0, 26, 0, 2, 0,
-  24, 52, 0, 0, 0, 48, 0, 57, 2, 2,
-  88, 0, 14, 69, 0, 0, 2, 41, 6, 46,
-  1, 15, 0, 0, 48, 46, 0, 40, 32, 26,
-  15, 28, 27, 0, 0, 65, 0, 8, 0, 0,
-  0, 0, 0, 52, 25, 0, 0, 0, 32, 0,
-  0, 39, 0, 43, 11, 0, 0, 0, 70, 0,
-  0, 25, 54, 0, 0, 0, 11, 0, 0, 0,
-  64, 2, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 50, 11, 0,
-  0, 0, 74, 36, 26, 54, 0, 25, 0, 0,
-  19, 41, 32, 80, 62, 25, 0, 0, 0, 42,
-  46, 46, 53, 65, 120, 31, 0, 0, 44, 0,
-  29, 0, 0, 0, 0, 45, 0, 0, 34, 0,
-  9, 14, 37, 0, 0, 29, 26, 40, 42, 29,
-  11, 0, 0, 42, 0, 48, 0, 0, 13, 56,
-  0, 27, 47, 0, 0, 21, 0, 6, 37, 0,
-  32, 21, 1, 6, 34, 0, 57, 25, 7, 31,
-  24, 9, 22, 28, 77, 0, 42, 0, 0, 21,
-  17, 0, 36, 22, 1, 31, 0, 0, 35, 0,
-  70, 0, 6, 12, 44, 44, 51, 12, 23, 0,
-  31, 0, 0, 14, 39, 0, 40, 13, 69, 0,
-  18, 0, 49, 15, 0, 53, 6, 0, 0, 0,
-  108, 18, 35, 62, 0, 10, 0, 0, 14, 70,
-  19, 66, 42, 16, 0, 0, 0, 59, 58, 43,
-  47, 64, 123, 32, 0, 0, 54, 0, 29, 0,
-  0, 0, 9, 45, 0, 0, 26, 16, 0, 23,
-  56, 0, 0, 30, 14, 43, 57, 13, 7, 3,
-  3, 60, 0, 52, 0, 9, 11, 62, 0, 31,
-  41, 10, 20, 3, 0, 13, 31, 0, 45, 36,
-  0, 0, 32, 0, 56, 38, 10, 21, 24, 0,
-  26, 22, 84, 1, 35, 0, 0, 34, 0, 0,
-  6, 15, 19, 40, 0, 0, 26, 0, 74, 0,
-  0, 29, 37, 36, 50, 12, 2, 0, 29, 0,
-  0, 35, 51, 0, 32, 0, 64, 0, 33, 0,
-  43, 1, 0, 47, 0, 0, 0, 0, 99, 35,
-  39, 50, 0, 17, 0, 0, 7, 70, 34, 67,
-  46, 6, 16, 0, 0, 47, 51, 51, 43, 68,
-  129, 40, 9, 0, 53, 0, 19, 0, 0, 3,
-  0, 46, 0, 0, 4, 18, 0, 21, 43, 0,
-  0, 29, 3, 44, 51, 16, 0, 0, 8, 61,
-  0, 57, 0, 8, 10, 70, 0, 30, 41, 15,
-  26, 0, 0, 5, 28, 0, 43, 38, 0, 0,
-  35, 0, 53, 27, 7, 21, 30, 0, 31, 28,
-  62, 0, 36, 0, 0, 42, 1, 0, 11, 10,
-  39, 35, 0, 0, 24, 0, 67, 0, 0, 27,
-  42, 50, 46, 18, 14, 0, 25, 0, 0, 33,
-  56, 0, 33, 24, 74, 0, 21, 0, 46, 9,
-  0, 38, 33, 0, 0, 0, 27, 0, 63, 89,
-  0, 12, 0, 0, 14, 41, 49, 72, 30, 11,
-  0, 0, 0, 57, 37, 23, 43, 98, 0, 0,
-  23, 0, 9, 0, 0, 0, 0, 70, 0, 0,
-  14, 15, 16, 0, 0, 17, 24, 0, 0, 0,
-  12, 0, 48, 0, 0, 0, 0, 33, 0, 3,
-  10, 18, 0, 50, 0, 0, 81, 0, 15, 42,
-  0, 0, 7, 44, 23, 12, 4, 28, 0, 0,
-  63, 33, 2, 27, 31, 25, 2, 25, 25, 0,
-  0, 46, 0, 33, 0, 0, 0, 14, 0, 51,
-  3, 0, 8, 0, 41, 0, 0, 18, 2, 64,
-  10, 19, 0, 0, 55, 0, 0, 23, 45, 0,
-  7, 3, 63, 0, 0, 0, 78, 18, 0, 39,
-  39, 0, 0, 0, 25, 0, 78, 78, 0, 0,
-  0, 3, 0, 17, 3, 41, 11, 0, 0, 0,
-  16, 61, 36, 0, 50, 80, 0, 0, 9, 0,
-  0, 0, 0, 0, 16, 73, 0, 0, 40, 8,
-  4, 0, 0, 14, 31, 0, 0, 0, 18, 0,
-  26, 0, 2, 0, 24, 52, 0, 0, 0, 48,
-  0, 57, 2, 2, 88, 0, 14, 69, 0, 0,
-  2, 41, 6, 46, 1, 15, 0, 0, 48, 46,
-  0, 40, 32, 26, 15, 28, 27, 0, 0, 65,
-  0, 8, 0, 0, 0, 0, 0, 52, 25, 0,
-  0, 0, 32, 0, 0, 39, 0, 43, 11, 0,
-  0, 0, 70, 0, 0, 25, 54, 0, 0, 0,
-  11, 0, 0, 0, 64, 2, 0, 29, 0, 0,
-  0, 0, 15, 0, 80, 38, 0, 0, 0, 0,
-  0, 0, 0, 35, 26, 0, 14, 0, 0, 45,
-  31, 0, 42, 64, 0, 0, 16, 0, 0, 5,
-  0, 0, 32, 60, 1, 0, 52, 0, 0, 0,
-  0, 15, 40, 0, 0, 0, 0, 2, 11, 0,
-  19, 50, 26, 49, 0, 0, 6, 43, 3, 66,
-  19, 0, 76, 0, 18, 84, 0, 0, 2, 19,
-  0, 39, 0, 5, 14, 0, 39, 27, 3, 12,
-  27, 17, 21, 31, 23, 0, 0, 98, 2, 0,
-  0, 0, 0, 0, 39, 39, 30, 37, 0, 0,
-  15, 0, 0, 33, 0, 44, 1, 9, 0, 0,
-  55, 0, 0, 24, 71, 0, 0, 0, 0, 0,
-  0, 0, 42, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 53,
-  6, 0, 0, 0, 108, 18, 35, 62, 0, 10,
-  0, 0, 14, 70, 19, 66, 42, 16, 0, 0,
-  0, 59, 58, 43, 47, 64, 123, 32, 0, 0,
-  54, 0, 29, 0, 0, 0, 9, 45, 0, 0,
-  26, 16, 0, 23, 56, 0, 0, 30, 14, 43,
-  57, 13, 7, 3, 3, 60, 0, 52, 0, 9,
-  11, 62, 0, 31, 41, 10, 20, 3, 0, 13,
-  31, 0, 45, 36, 0, 0, 32, 0, 56, 38,
-  10, 21, 24, 0, 26, 22, 84, 1, 35, 0,
-  0, 34, 0, 0, 6, 15, 19, 40, 0, 0,
-  26, 0, 74, 0, 0, 29, 37, 36, 50, 12,
-  2, 0, 29, 0, 0, 35, 51, 0, 32, 0,
-  64, 0, 33, 0, 43, 1, 0, 47, 0, 0,
-  0, 0, 99, 35, 39, 50, 0, 17, 0, 0,
-  7, 70, 34, 67, 46, 6, 16, 0, 0, 47,
-  51, 51, 43, 68, 129, 40, 9, 0, 53, 0,
-  19, 0, 0, 3, 0, 46, 0, 0, 4, 18,
-  0, 21, 43, 0, 0, 29, 3, 44, 51, 16,
-  0, 0, 8, 61, 0, 57, 0, 8, 10, 70,
-  0, 30, 41, 15, 26, 0, 0, 5, 28, 0,
-  43, 38, 0, 0, 35, 0, 53, 27, 7, 21,
-  30, 0, 31, 28, 62, 0, 36, 0, 0, 42,
-  1, 0, 11, 10, 39, 35, 0, 0, 24, 0,
-  67, 0, 0, 27, 42, 50, 46, 18, 14, 0,
-  25, 0, 0, 33, 56, 0, 33, 24, 74, 0,
-  21, 0, 46, 9, 0, 40, 0, 0, 5, 0,
-  79, 51, 29, 30, 0, 28, 9, 0, 6, 57,
-  44, 75, 60, 18, 9, 0, 0, 32, 53, 70,
-  33, 61, 135, 47, 36, 0, 45, 8, 29, 0,
-  0, 4, 0, 55, 0, 0, 25, 9, 0, 4,
-  34, 0, 0, 18, 21, 51, 44, 48, 0, 10,
-  3, 61, 0, 58, 0, 0, 12, 61, 0, 22,
-  46, 13, 15, 0, 0, 2, 14, 0, 34, 33,
-  0, 3, 31, 0, 57, 9, 0, 22, 46, 0,
-  23, 34, 53, 5, 53, 2, 0, 39, 29, 0,
-  36, 10, 25, 36, 0, 0, 19, 0, 58, 0,
-  0, 20, 53, 51, 44, 24, 38, 2, 31, 0,
-  0, 13, 50, 0, 40, 53, 98, 0, 37, 0,
-  54, 1, 0, 39, 39, 0, 0, 0, 25, 0,
-  78, 78, 0, 0, 0, 3, 0, 17, 3, 41,
-  11, 0, 0, 0, 16, 61, 36, 0, 50, 80,
-  0, 0, 9, 0, 0, 0, 0, 0, 16, 73,
-  0, 0, 40, 8, 4, 0, 0, 14, 31, 0,
-  0, 0, 18, 0, 26, 0, 2, 0, 24, 52,
-  0, 0, 0, 48, 0, 57, 2, 2, 88, 0,
-  14, 69, 0, 0, 2, 41, 6, 46, 1, 15,
-  0, 0, 48, 46, 0, 40, 32, 26, 15, 28,
-  27, 0, 0, 65, 0, 8, 0, 0, 0, 0,
-  0, 52, 25, 0, 0, 0, 32, 0, 0, 39,
-  0, 43, 11, 0, 0, 0, 70, 0, 0, 25,
-  54, 0, 0, 0, 11, 0, 0, 0, 64, 2,
-  0, 29, 0, 0, 0, 0, 15, 0, 80, 38,
-  0, 0, 0, 0, 0, 0, 0, 35, 26, 0,
-  14, 0, 0, 45, 31, 0, 42, 64, 0, 0,
-  16, 0, 0, 5, 0, 0, 32, 60, 1, 0,
-  52, 0, 0, 0, 0, 15, 40, 0, 0, 0,
-  0, 2, 11, 0, 19, 50, 26, 49, 0, 0,
-  6, 43, 3, 66, 19, 0, 76, 0, 18, 84,
-  0, 0, 2, 19, 0, 39, 0, 5, 14, 0,
-  39, 27, 3, 12, 27, 17, 21, 31, 23, 0,
-  0, 98, 2, 0, 0, 0, 0, 0, 39, 39,
-  30, 37, 0, 0, 15, 0, 0, 33, 0, 44,
-  1, 9, 0, 0, 55, 0, 0, 24, 71, 0,
-  0, 0, 0, 0, 0, 0, 42, 0, 0, 21,
-  0, 0, 2, 0, 15, 0, 74, 29, 0, 18,
-  0, 12, 0, 34, 16, 63, 31, 0, 0, 0,
-  0, 43, 15, 0, 18, 55, 0, 0, 44, 0,
-  0, 15, 0, 0, 19, 53, 0, 0, 37, 0,
-  0, 0, 0, 6, 28, 0, 0, 0, 0, 19,
-  26, 0, 3, 71, 33, 50, 0, 0, 10, 18,
-  0, 54, 2, 0, 62, 0, 20, 53, 0, 0,
-  0, 10, 0, 34, 0, 0, 19, 0, 50, 13,
-  6, 0, 30, 11, 7, 22, 34, 0, 0, 109,
-  0, 6, 0, 0, 0, 0, 36, 46, 17, 32,
-  7, 0, 17, 0, 0, 18, 0, 40, 0, 25,
-  0, 9, 51, 0, 0, 9, 68, 0, 0, 9,
-  34, 0, 14, 0, 50, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 47, 0, 0, 0, 0, 99, 35, 39, 50,
-  0, 17, 0, 0, 7, 70, 34, 67, 46, 6,
-  16, 0, 0, 47, 51, 51, 43, 68, 129, 40,
-  9, 0, 53, 0, 19, 0, 0, 3, 0, 46,
-  0, 0, 4, 18, 0, 21, 43, 0, 0, 29,
-  3, 44, 51, 16, 0, 0, 8, 61, 0, 57,
-  0, 8, 10, 70, 0, 30, 41, 15, 26, 0,
-  0, 5, 28, 0, 43, 38, 0, 0, 35, 0,
-  53, 27, 7, 21, 30, 0, 31, 28, 62, 0,
-  36, 0, 0, 42, 1, 0, 11, 10, 39, 35,
-  0, 0, 24, 0, 67, 0, 0, 27, 42, 50,
-  46, 18, 14, 0, 25, 0, 0, 33, 56, 0,
-  33, 24, 74, 0, 21, 0, 46, 9, 0, 40,
-  0, 0, 5, 0, 79, 51, 29, 30, 0, 28,
-  9, 0, 6, 57, 44, 75, 60, 18, 9, 0,
-  0, 32, 53, 70, 33, 61, 135, 47, 36, 0,
-  45, 8, 29, 0, 0, 4, 0, 55, 0, 0,
-  25, 9, 0, 4, 34, 0, 0, 18, 21, 51,
-  44, 48, 0, 10, 3, 61, 0, 58, 0, 0,
-  12, 61, 0, 22, 46, 13, 15, 0, 0, 2,
-  14, 0, 34, 33, 0, 3, 31, 0, 57, 9,
-  0, 22, 46, 0, 23, 34, 53, 5, 53, 2,
-  0, 39, 29, 0, 36, 10, 25, 36, 0, 0,
-  19, 0, 58, 0, 0, 20, 53, 51, 44, 24,
-  38, 2, 31, 0, 0, 13, 50, 0, 40, 53,
-  98, 0, 37, 0, 54, 1, 0, 57, 0, 0,
-  7, 0, 75, 49, 21, 35, 0, 26, 12, 9,
-  20, 56, 23, 65, 41, 43, 0, 0, 0, 51,
-  49, 70, 25, 60, 128, 38, 16, 1, 47, 0,
-  34, 0, 0, 0, 0, 68, 0, 0, 51, 15,
-  10, 0, 33, 0, 0, 22, 41, 66, 39, 66,
-  0, 5, 0, 59, 0, 43, 0, 0, 13, 40,
-  0, 20, 49, 2, 9, 0, 0, 5, 40, 0,
-  43, 31, 0, 19, 43, 2, 80, 35, 0, 14,
-  27, 0, 17, 32, 100, 3, 76, 2, 0, 16,
-  24, 9, 46, 5, 10, 44, 0, 0, 7, 0,
-  65, 0, 4, 31, 54, 32, 37, 0, 31, 0,
-  29, 0, 0, 0, 10, 17, 45, 22, 97, 0,
-  76, 0, 23, 0, 0, 29, 0, 0, 0, 0,
-  15, 0, 80, 38, 0, 0, 0, 0, 0, 0,
-  0, 35, 26, 0, 14, 0, 0, 45, 31, 0,
-  42, 64, 0, 0, 16, 0, 0, 5, 0, 0,
-  32, 60, 1, 0, 52, 0, 0, 0, 0, 15,
-  40, 0, 0, 0, 0, 2, 11, 0, 19, 50,
-  26, 49, 0, 0, 6, 43, 3, 66, 19, 0,
-  76, 0, 18, 84, 0, 0, 2, 19, 0, 39,
-  0, 5, 14, 0, 39, 27, 3, 12, 27, 17,
-  21, 31, 23, 0, 0, 98, 2, 0, 0, 0,
-  0, 0, 39, 39, 30, 37, 0, 0, 15, 0,
-  0, 33, 0, 44, 1, 9, 0, 0, 55, 0,
-  0, 24, 71, 0, 0, 0, 0, 0, 0, 0,
-  42, 0, 0, 21, 0, 0, 2, 0, 15, 0,
-  74, 29, 0, 18, 0, 12, 0, 34, 16, 63,
-  31, 0, 0, 0, 0, 43, 15, 0, 18, 55,
-  0, 0, 44, 0, 0, 15, 0, 0, 19, 53,
-  0, 0, 37, 0, 0, 0, 0, 6, 28, 0,
-  0, 0, 0, 19, 26, 0, 3, 71, 33, 50,
-  0, 0, 10, 18, 0, 54, 2, 0, 62, 0,
-  20, 53, 0, 0, 0, 10, 0, 34, 0, 0,
-  19, 0, 50, 13, 6, 0, 30, 11, 7, 22,
-  34, 0, 0, 109, 0, 6, 0, 0, 0, 0,
-  36, 46, 17, 32, 7, 0, 17, 0, 0, 18,
-  0, 40, 0, 25, 0, 9, 51, 0, 0, 9,
-  68, 0, 0, 9, 34, 0, 14, 0, 50, 0,
-  0, 44, 0, 0, 11, 0, 30, 0, 44, 53,
-  0, 11, 18, 12, 0, 82, 51, 71, 16, 19,
-  0, 0, 0, 63, 28, 37, 0, 67, 2, 0,
-  45, 0, 33, 25, 0, 0, 0, 52, 0, 0,
-  18, 0, 13, 17, 0, 3, 20, 20, 0, 7,
-  2, 12, 49, 14, 0, 32, 19, 44, 0, 21,
-  12, 0, 0, 24, 0, 0, 80, 1, 40, 3,
-  0, 0, 8, 26, 18, 45, 0, 0, 0, 0,
-  87, 25, 0, 0, 27, 11, 0, 26, 28, 6,
-  18, 90, 0, 29, 0, 0, 0, 0, 0, 71,
-  9, 2, 14, 0, 37, 0, 0, 24, 1, 42,
-  0, 27, 0, 6, 32, 0, 0, 6, 43, 0,
-  9, 0, 103, 0, 43, 0, 51, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 40, 0, 0, 5, 0, 79, 51,
-  29, 30, 0, 28, 9, 0, 6, 57, 44, 75,
-  60, 18, 9, 0, 0, 32, 53, 70, 33, 61,
-  135, 47, 36, 0, 45, 8, 29, 0, 0, 4,
-  0, 55, 0, 0, 25, 9, 0, 4, 34, 0,
-  0, 18, 21, 51, 44, 48, 0, 10, 3, 61,
-  0, 58, 0, 0, 12, 61, 0, 22, 46, 13,
-  15, 0, 0, 2, 14, 0, 34, 33, 0, 3,
-  31, 0, 57, 9, 0, 22, 46, 0, 23, 34,
-  53, 5, 53, 2, 0, 39, 29, 0, 36, 10,
-  25, 36, 0, 0, 19, 0, 58, 0, 0, 20,
-  53, 51, 44, 24, 38, 2, 31, 0, 0, 13,
-  50, 0, 40, 53, 98, 0, 37, 0, 54, 1,
-  0, 57, 0, 0, 7, 0, 75, 49, 21, 35,
-  0, 26, 12, 9, 20, 56, 23, 65, 41, 43,
-  0, 0, 0, 51, 49, 70, 25, 60, 128, 38,
-  16, 1, 47, 0, 34, 0, 0, 0, 0, 68,
-  0, 0, 51, 15, 10, 0, 33, 0, 0, 22,
-  41, 66, 39, 66, 0, 5, 0, 59, 0, 43,
-  0, 0, 13, 40, 0, 20, 49, 2, 9, 0,
-  0, 5, 40, 0, 43, 31, 0, 19, 43, 2,
-  80, 35, 0, 14, 27, 0, 17, 32, 100, 3,
-  76, 2, 0, 16, 24, 9, 46, 5, 10, 44,
-  0, 0, 7, 0, 65, 0, 4, 31, 54, 32,
-  37, 0, 31, 0, 29, 0, 0, 0, 10, 17,
-  45, 22, 97, 0, 76, 0, 23, 0, 0, 100,
-  25, 10, 0, 0, 70, 30, 19, 50, 0, 57,
-  14, 13, 11, 54, 10, 51, 32, 74, 0, 0,
-  0, 42, 41, 47, 55, 47, 140, 28, 0, 6,
-  69, 0, 51, 0, 0, 0, 0, 61, 0, 0,
-  55, 28, 10, 25, 39, 0, 0, 40, 29, 63,
-  62, 56, 3, 0, 0, 4, 0, 42, 0, 0,
-  18, 10, 0, 13, 27, 0, 4, 2, 3, 7,
-  57, 0, 55, 33, 0, 39, 43, 0, 86, 34,
-  0, 21, 5, 0, 34, 32, 104, 0, 59, 5,
-  0, 0, 22, 8, 33, 0, 3, 36, 0, 11,
-  27, 0, 66, 0, 37, 39, 34, 16, 38, 0,
-  27, 2, 5, 0, 0, 0, 0, 19, 44, 4,
-  64, 0, 73, 0, 11, 0, 0, 21, 0, 0,
-  2, 0, 15, 0, 74, 29, 0, 18, 0, 12,
-  0, 34, 16, 63, 31, 0, 0, 0, 0, 43,
-  15, 0, 18, 55, 0, 0, 44, 0, 0, 15,
-  0, 0, 19, 53, 0, 0, 37, 0, 0, 0,
-  0, 6, 28, 0, 0, 0, 0, 19, 26, 0,
-  3, 71, 33, 50, 0, 0, 10, 18, 0, 54,
-  2, 0, 62, 0, 20, 53, 0, 0, 0, 10,
-  0, 34, 0, 0, 19, 0, 50, 13, 6, 0,
-  30, 11, 7, 22, 34, 0, 0, 109, 0, 6,
-  0, 0, 0, 0, 36, 46, 17, 32, 7, 0,
-  17, 0, 0, 18, 0, 40, 0, 25, 0, 9,
-  51, 0, 0, 9, 68, 0, 0, 9, 34, 0,
-  14, 0, 50, 0, 0, 44, 0, 0, 11, 0,
-  30, 0, 44, 53, 0, 11, 18, 12, 0, 82,
-  51, 71, 16, 19, 0, 0, 0, 63, 28, 37,
-  0, 67, 2, 0, 45, 0, 33, 25, 0, 0,
-  0, 52, 0, 0, 18, 0, 13, 17, 0, 3,
-  20, 20, 0, 7, 2, 12, 49, 14, 0, 32,
-  19, 44, 0, 21, 12, 0, 0, 24, 0, 0,
-  80, 1, 40, 3, 0, 0, 8, 26, 18, 45,
-  0, 0, 0, 0, 87, 25, 0, 0, 27, 11,
-  0, 26, 28, 6, 18, 90, 0, 29, 0, 0,
-  0, 0, 0, 71, 9, 2, 14, 0, 37, 0,
-  0, 24, 1, 42, 0, 27, 0, 6, 32, 0,
-  0, 6, 43, 0, 9, 0, 103, 0, 43, 0,
-  51, 0, 0, 102, 14, 0, 4, 0, 39, 0,
-  27, 51, 8, 13, 23, 3, 26, 91, 67, 61,
-  21, 56, 0, 0, 0, 56, 53, 69, 6, 74,
-  0, 0, 14, 0, 81, 1, 0, 0, 0, 25,
-  0, 38, 0, 16, 42, 22, 1, 7, 22, 19,
-  0, 49, 2, 1, 68, 52, 0, 0, 0, 9,
-  0, 50, 0, 0, 0, 0, 0, 0, 91, 11,
-  34, 0, 0, 0, 15, 26, 42, 23, 0, 6,
-  0, 4, 107, 11, 0, 0, 11, 8, 10, 15,
-  30, 12, 42, 45, 0, 41, 0, 10, 0, 0,
-  0, 81, 0, 0, 14, 0, 46, 0, 23, 15,
-  32, 37, 0, 0, 0, 0, 0, 0, 0, 0,
-  12, 0, 30, 11, 149, 0, 76, 0, 46, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 57, 0, 0, 7, 0,
-  75, 49, 21, 35, 0, 26, 12, 9, 20, 56,
-  23, 65, 41, 43, 0, 0, 0, 51, 49, 70,
-  25, 60, 128, 38, 16, 1, 47, 0, 34, 0,
-  0, 0, 0, 68, 0, 0, 51, 15, 10, 0,
-  33, 0, 0, 22, 41, 66, 39, 66, 0, 5,
-  0, 59, 0, 43, 0, 0, 13, 40, 0, 20,
-  49, 2, 9, 0, 0, 5, 40, 0, 43, 31,
-  0, 19, 43, 2, 80, 35, 0, 14, 27, 0,
-  17, 32, 100, 3, 76, 2, 0, 16, 24, 9,
-  46, 5, 10, 44, 0, 0, 7, 0, 65, 0,
-  4, 31, 54, 32, 37, 0, 31, 0, 29, 0,
-  0, 0, 10, 17, 45, 22, 97, 0, 76, 0,
-  23, 0, 0, 100, 25, 10, 0, 0, 70, 30,
-  19, 50, 0, 57, 14, 13, 11, 54, 10, 51,
-  32, 74, 0, 0, 0, 42, 41, 47, 55, 47,
-  140, 28, 0, 6, 69, 0, 51, 0, 0, 0,
-  0, 61, 0, 0, 55, 28, 10, 25, 39, 0,
-  0, 40, 29, 63, 62, 56, 3, 0, 0, 4,
-  0, 42, 0, 0, 18, 10, 0, 13, 27, 0,
-  4, 2, 3, 7, 57, 0, 55, 33, 0, 39,
-  43, 0, 86, 34, 0, 21, 5, 0, 34, 32,
-  104, 0, 59, 5, 0, 0, 22, 8, 33, 0,
-  3, 36, 0, 11, 27, 0, 66, 0, 37, 39,
-  34, 16, 38, 0, 27, 2, 5, 0, 0, 0,
-  0, 19, 44, 4, 64, 0, 73, 0, 11, 0,
-  0, 123, 31, 8, 0, 0, 58, 2, 5, 19,
-  0, 61, 49, 0, 0, 22, 6, 34, 22, 59,
-  0, 0, 47, 46, 38, 9, 61, 16, 179, 16,
-  0, 0, 76, 0, 51, 37, 0, 0, 40, 47,
-  0, 0, 71, 33, 17, 78, 26, 17, 0, 47,
-  0, 63, 77, 0, 7, 0, 7, 0, 0, 10,
-  13, 30, 0, 26, 0, 3, 14, 0, 1, 0,
-  72, 10, 34, 0, 44, 21, 8, 54, 16, 0,
-  64, 0, 25, 21, 0, 5, 39, 21, 53, 0,
-  0, 0, 23, 0, 9, 12, 0, 0, 0, 25,
-  0, 51, 27, 5, 41, 0, 55, 0, 0, 34,
-  30, 0, 0, 7, 0, 0, 0, 10, 31, 34,
-  58, 5, 0, 0, 20, 0, 0, 0, 0, 44,
-  0, 0, 11, 0, 30, 0, 44, 53, 0, 11,
-  18, 12, 0, 82, 51, 71, 16, 19, 0, 0,
-  0, 63, 28, 37, 0, 67, 2, 0, 45, 0,
-  33, 25, 0, 0, 0, 52, 0, 0, 18, 0,
-  13, 17, 0, 3, 20, 20, 0, 7, 2, 12,
-  49, 14, 0, 32, 19, 44, 0, 21, 12, 0,
-  0, 24, 0, 0, 80, 1, 40, 3, 0, 0,
-  8, 26, 18, 45, 0, 0, 0, 0, 87, 25,
-  0, 0, 27, 11, 0, 26, 28, 6, 18, 90,
-  0, 29, 0, 0, 0, 0, 0, 71, 9, 2,
-  14, 0, 37, 0, 0, 24, 1, 42, 0, 27,
-  0, 6, 32, 0, 0, 6, 43, 0, 9, 0,
-  103, 0, 43, 0, 51, 0, 0, 102, 14, 0,
-  4, 0, 39, 0, 27, 51, 8, 13, 23, 3,
-  26, 91, 67, 61, 21, 56, 0, 0, 0, 56,
-  53, 69, 6, 74, 0, 0, 14, 0, 81, 1,
-  0, 0, 0, 25, 0, 38, 0, 16, 42, 22,
-  1, 7, 22, 19, 0, 49, 2, 1, 68, 52,
-  0, 0, 0, 9, 0, 50, 0, 0, 0, 0,
-  0, 0, 91, 11, 34, 0, 0, 0, 15, 26,
-  42, 23, 0, 6, 0, 4, 107, 11, 0, 0,
-  11, 8, 10, 15, 30, 12, 42, 45, 0, 41,
-  0, 10, 0, 0, 0, 81, 0, 0, 14, 0,
-  46, 0, 23, 15, 32, 37, 0, 0, 0, 0,
-  0, 0, 0, 0, 12, 0, 30, 11, 149, 0,
-  76, 0, 46, 0, 0, 131, 52, 5, 17, 0,
-  45, 0, 11, 44, 5, 23, 60, 0, 17, 55,
-  55, 49, 15, 72, 0, 0, 12, 32, 54, 53,
-  11, 54, 0, 20, 0, 0, 76, 0, 17, 0,
-  0, 0, 0, 41, 0, 25, 68, 41, 28, 22,
-  40, 0, 0, 52, 0, 3, 85, 24, 0, 0,
-  0, 0, 0, 44, 4, 0, 0, 5, 0, 0,
-  29, 13, 13, 0, 0, 0, 8, 16, 74, 5,
-  15, 32, 0, 0, 97, 0, 0, 0, 14, 0,
-  30, 16, 22, 9, 0, 0, 0, 20, 0, 26,
-  0, 0, 0, 38, 5, 16, 9, 0, 39, 0,
-  48, 8, 25, 53, 0, 0, 0, 5, 0, 0,
-  0, 24, 33, 0, 34, 5, 77, 0, 62, 0,
-  29, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 100, 25, 10,
-  0, 0, 70, 30, 19, 50, 0, 57, 14, 13,
-  11, 54, 10, 51, 32, 74, 0, 0, 0, 42,
-  41, 47, 55, 47, 140, 28, 0, 6, 69, 0,
-  51, 0, 0, 0, 0, 61, 0, 0, 55, 28,
-  10, 25, 39, 0, 0, 40, 29, 63, 62, 56,
-  3, 0, 0, 4, 0, 42, 0, 0, 18, 10,
-  0, 13, 27, 0, 4, 2, 3, 7, 57, 0,
-  55, 33, 0, 39, 43, 0, 86, 34, 0, 21,
-  5, 0, 34, 32, 104, 0, 59, 5, 0, 0,
-  22, 8, 33, 0, 3, 36, 0, 11, 27, 0,
-  66, 0, 37, 39, 34, 16, 38, 0, 27, 2,
-  5, 0, 0, 0, 0, 19, 44, 4, 64, 0,
-  73, 0, 11, 0, 0, 123, 31, 8, 0, 0,
-  58, 2, 5, 19, 0, 61, 49, 0, 0, 22,
-  6, 34, 22, 59, 0, 0, 47, 46, 38, 9,
-  61, 16, 179, 16, 0, 0, 76, 0, 51, 37,
-  0, 0, 40, 47, 0, 0, 71, 33, 17, 78,
-  26, 17, 0, 47, 0, 63, 77, 0, 7, 0,
-  7, 0, 0, 10, 13, 30, 0, 26, 0, 3,
-  14, 0, 1, 0, 72, 10, 34, 0, 44, 21,
-  8, 54, 16, 0, 64, 0, 25, 21, 0, 5,
-  39, 21, 53, 0, 0, 0, 23, 0, 9, 12,
-  0, 0, 0, 25, 0, 51, 27, 5, 41, 0,
-  55, 0, 0, 34, 30, 0, 0, 7, 0, 0,
-  0, 10, 31, 34, 58, 5, 0, 0, 20, 0,
-  0, 0, 5, 63, 0, 6, 0, 6, 70, 9,
-  0, 0, 0, 80, 68, 0, 0, 0, 4, 24,
-  17, 28, 10, 34, 89, 45, 45, 0, 53, 4,
-  206, 0, 0, 11, 57, 5, 17, 54, 0, 0,
-  60, 39, 0, 0, 1, 61, 12, 128, 21, 26,
-  0, 14, 0, 73, 56, 0, 20, 6, 28, 0,
-  28, 0, 56, 44, 0, 46, 15, 2, 13, 32,
-  46, 0, 134, 11, 24, 0, 54, 0, 56, 54,
-  12, 0, 36, 0, 34, 0, 0, 7, 35, 1,
-  23, 0, 0, 0, 35, 0, 0, 29, 0, 0,
-  59, 43, 6, 53, 7, 33, 53, 18, 22, 0,
-  0, 36, 0, 23, 0, 10, 0, 29, 0, 20,
-  61, 20, 68, 0, 0, 0, 0, 0, 0, 0,
-  0, 102, 14, 0, 4, 0, 39, 0, 27, 51,
-  8, 13, 23, 3, 26, 91, 67, 61, 21, 56,
-  0, 0, 0, 56, 53, 69, 6, 74, 0, 0,
-  14, 0, 81, 1, 0, 0, 0, 25, 0, 38,
-  0, 16, 42, 22, 1, 7, 22, 19, 0, 49,
-  2, 1, 68, 52, 0, 0, 0, 9, 0, 50,
-  0, 0, 0, 0, 0, 0, 91, 11, 34, 0,
-  0, 0, 15, 26, 42, 23, 0, 6, 0, 4,
-  107, 11, 0, 0, 11, 8, 10, 15, 30, 12,
-  42, 45, 0, 41, 0, 10, 0, 0, 0, 81,
-  0, 0, 14, 0, 46, 0, 23, 15, 32, 37,
-  0, 0, 0, 0, 0, 0, 0, 0, 12, 0,
-  30, 11, 149, 0, 76, 0, 46, 0, 0, 131,
-  52, 5, 17, 0, 45, 0, 11, 44, 5, 23,
-  60, 0, 17, 55, 55, 49, 15, 72, 0, 0,
-  12, 32, 54, 53, 11, 54, 0, 20, 0, 0,
-  76, 0, 17, 0, 0, 0, 0, 41, 0, 25,
-  68, 41, 28, 22, 40, 0, 0, 52, 0, 3,
-  85, 24, 0, 0, 0, 0, 0, 44, 4, 0,
-  0, 5, 0, 0, 29, 13, 13, 0, 0, 0,
-  8, 16, 74, 5, 15, 32, 0, 0, 97, 0,
-  0, 0, 14, 0, 30, 16, 22, 9, 0, 0,
-  0, 20, 0, 26, 0, 0, 0, 38, 5, 16,
-  9, 0, 39, 0, 48, 8, 25, 53, 0, 0,
-  0, 5, 0, 0, 0, 24, 33, 0, 34, 5,
-  77, 0, 62, 0, 29, 0, 0, 75, 0, 0,
-  5, 14, 48, 1, 0, 0, 0, 56, 51, 0,
-  0, 4, 32, 10, 13, 41, 0, 10, 71, 13,
-  29, 0, 10, 14, 0, 17, 0, 0, 42, 0,
-  5, 27, 0, 0, 9, 20, 0, 26, 0, 66,
-  11, 74, 35, 26, 0, 2, 0, 16, 68, 0,
-  0, 0, 30, 0, 1, 5, 28, 45, 0, 49,
-  0, 0, 0, 37, 29, 0, 51, 0, 22, 9,
-  83, 12, 47, 23, 0, 0, 69, 0, 4, 0,
-  38, 0, 23, 2, 0, 0, 0, 0, 0, 6,
-  0, 38, 0, 0, 22, 49, 15, 29, 19, 13,
-  22, 0, 31, 11, 0, 28, 0, 0, 0, 0,
-  0, 0, 0, 19, 71, 6, 22, 4, 0, 0,
-  22, 0, 10, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 123,
-  31, 8, 0, 0, 58, 2, 5, 19, 0, 61,
-  49, 0, 0, 22, 6, 34, 22, 59, 0, 0,
-  47, 46, 38, 9, 61, 16, 179, 16, 0, 0,
-  76, 0, 51, 37, 0, 0, 40, 47, 0, 0,
-  71, 33, 17, 78, 26, 17, 0, 47, 0, 63,
-  77, 0, 7, 0, 7, 0, 0, 10, 13, 30,
-  0, 26, 0, 3, 14, 0, 1, 0, 72, 10,
-  34, 0, 44, 21, 8, 54, 16, 0, 64, 0,
-  25, 21, 0, 5, 39, 21, 53, 0, 0, 0,
-  23, 0, 9, 12, 0, 0, 0, 25, 0, 51,
-  27, 5, 41, 0, 55, 0, 0, 34, 30, 0,
-  0, 7, 0, 0, 0, 10, 31, 34, 58, 5,
-  0, 0, 20, 0, 0, 0, 5, 63, 0, 6,
-  0, 6, 70, 9, 0, 0, 0, 80, 68, 0,
-  0, 0, 4, 24, 17, 28, 10, 34, 89, 45,
-  45, 0, 53, 4, 206, 0, 0, 11, 57, 5,
-  17, 54, 0, 0, 60, 39, 0, 0, 1, 61,
-  12, 128, 21, 26, 0, 14, 0, 73, 56, 0,
-  20, 6, 28, 0, 28, 0, 56, 44, 0, 46,
-  15, 2, 13, 32, 46, 0, 134, 11, 24, 0,
-  54, 0, 56, 54, 12, 0, 36, 0, 34, 0,
-  0, 7, 35, 1, 23, 0, 0, 0, 35, 0,
-  0, 29, 0, 0, 59, 43, 6, 53, 7, 33,
-  53, 18, 22, 0, 0, 36, 0, 23, 0, 10,
-  0, 29, 0, 20, 61, 20, 68, 0, 0, 0,
-  0, 0, 0, 0, 23, 19, 0, 34, 10, 9,
-  83, 40, 0, 0, 0, 24, 57, 8, 0, 49,
-  29, 55, 14, 27, 77, 6, 23, 33, 54, 0,
-  58, 20, 192, 4, 0, 22, 109, 15, 46, 0,
-  0, 37, 38, 5, 0, 0, 0, 70, 41, 137,
-  1, 46, 0, 13, 0, 79, 54, 2, 11, 54,
-  16, 0, 0, 0, 37, 0, 13, 6, 0, 0,
-  18, 17, 31, 11, 84, 0, 5, 0, 13, 0,
-  66, 45, 13, 0, 58, 0, 30, 0, 0, 0,
-  28, 0, 31, 38, 0, 18, 0, 18, 32, 25,
-  25, 0, 48, 37, 18, 2, 0, 55, 81, 0,
-  12, 13, 23, 14, 0, 32, 10, 37, 0, 0,
-  29, 0, 19, 21, 86, 0, 13, 0, 0, 0,
-  37, 12, 0, 131, 52, 5, 17, 0, 45, 0,
-  11, 44, 5, 23, 60, 0, 17, 55, 55, 49,
-  15, 72, 0, 0, 12, 32, 54, 53, 11, 54,
-  0, 20, 0, 0, 76, 0, 17, 0, 0, 0,
-  0, 41, 0, 25, 68, 41, 28, 22, 40, 0,
-  0, 52, 0, 3, 85, 24, 0, 0, 0, 0,
-  0, 44, 4, 0, 0, 5, 0, 0, 29, 13,
-  13, 0, 0, 0, 8, 16, 74, 5, 15, 32,
-  0, 0, 97, 0, 0, 0, 14, 0, 30, 16,
-  22, 9, 0, 0, 0, 20, 0, 26, 0, 0,
-  0, 38, 5, 16, 9, 0, 39, 0, 48, 8,
-  25, 53, 0, 0, 0, 5, 0, 0, 0, 24,
-  33, 0, 34, 5, 77, 0, 62, 0, 29, 0,
-  0, 75, 0, 0, 5, 14, 48, 1, 0, 0,
-  0, 56, 51, 0, 0, 4, 32, 10, 13, 41,
-  0, 10, 71, 13, 29, 0, 10, 14, 0, 17,
-  0, 0, 42, 0, 5, 27, 0, 0, 9, 20,
-  0, 26, 0, 66, 11, 74, 35, 26, 0, 2,
-  0, 16, 68, 0, 0, 0, 30, 0, 1, 5,
-  28, 45, 0, 49, 0, 0, 0, 37, 29, 0,
-  51, 0, 22, 9, 83, 12, 47, 23, 0, 0,
-  69, 0, 4, 0, 38, 0, 23, 2, 0, 0,
-  0, 0, 0, 6, 0, 38, 0, 0, 22, 49,
-  15, 29, 19, 13, 22, 0, 31, 11, 0, 28,
-  0, 0, 0, 0, 0, 0, 0, 19, 71, 6,
-  22, 4, 0, 0, 22, 0, 10, 0, 7, 18,
-  0, 16, 0, 21, 57, 17, 0, 0, 0, 41,
-  57, 2, 0, 6, 60, 44, 5, 5, 45, 0,
-  15, 0, 37, 0, 27, 0, 0, 35, 0, 0,
-  85, 0, 0, 0, 0, 5, 0, 0, 0, 23,
-  0, 64, 4, 113, 25, 79, 0, 0, 0, 41,
-  66, 0, 0, 22, 11, 0, 0, 0, 15, 0,
-  0, 2, 0, 0, 0, 36, 38, 0, 60, 0,
-  2, 0, 50, 0, 47, 0, 0, 0, 62, 0,
-  47, 0, 7, 0, 20, 0, 0, 8, 0, 4,
-  0, 8, 0, 7, 0, 0, 51, 44, 26, 26,
-  0, 37, 18, 0, 29, 6, 9, 13, 0, 18,
-  0, 17, 0, 0, 6, 0, 36, 0, 37, 0,
-  37, 0, 0, 0, 38, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  5, 63, 0, 6, 0, 6, 70, 9, 0, 0,
-  0, 80, 68, 0, 0, 0, 4, 24, 17, 28,
-  10, 34, 89, 45, 45, 0, 53, 4, 206, 0,
-  0, 11, 57, 5, 17, 54, 0, 0, 60, 39,
-  0, 0, 1, 61, 12, 128, 21, 26, 0, 14,
-  0, 73, 56, 0, 20, 6, 28, 0, 28, 0,
-  56, 44, 0, 46, 15, 2, 13, 32, 46, 0,
-  134, 11, 24, 0, 54, 0, 56, 54, 12, 0,
-  36, 0, 34, 0, 0, 7, 35, 1, 23, 0,
-  0, 0, 35, 0, 0, 29, 0, 0, 59, 43,
-  6, 53, 7, 33, 53, 18, 22, 0, 0, 36,
-  0, 23, 0, 10, 0, 29, 0, 20, 61, 20,
-  68, 0, 0, 0, 0, 0, 0, 0, 23, 19,
-  0, 34, 10, 9, 83, 40, 0, 0, 0, 24,
-  57, 8, 0, 49, 29, 55, 14, 27, 77, 6,
-  23, 33, 54, 0, 58, 20, 192, 4, 0, 22,
-  109, 15, 46, 0, 0, 37, 38, 5, 0, 0,
-  0, 70, 41, 137, 1, 46, 0, 13, 0, 79,
-  54, 2, 11, 54, 16, 0, 0, 0, 37, 0,
-  13, 6, 0, 0, 18, 17, 31, 11, 84, 0,
-  5, 0, 13, 0, 66, 45, 13, 0, 58, 0,
-  30, 0, 0, 0, 28, 0, 31, 38, 0, 18,
-  0, 18, 32, 25, 25, 0, 48, 37, 18, 2,
-  0, 55, 81, 0, 12, 13, 23, 14, 0, 32,
-  10, 37, 0, 0, 29, 0, 19, 21, 86, 0,
-  13, 0, 0, 0, 37, 12, 0, 33, 0, 8,
-  0, 0, 88, 51, 0, 25, 4, 29, 23, 1,
-  15, 91, 42, 50, 0, 22, 30, 0, 0, 49,
-  47, 30, 47, 45, 143, 63, 23, 6, 105, 25,
-  47, 0, 0, 39, 4, 30, 0, 3, 39, 25,
-  43, 65, 2, 47, 0, 56, 16, 77, 68, 39,
-  2, 24, 5, 0, 0, 43, 0, 0, 0, 26,
-  0, 4, 28, 0, 0, 0, 1, 21, 0, 0,
-  4, 46, 30, 14, 4, 0, 94, 0, 0, 19,
-  0, 0, 9, 3, 54, 33, 28, 12, 0, 25,
-  28, 16, 54, 0, 16, 44, 0, 0, 10, 24,
-  96, 0, 13, 21, 39, 36, 23, 10, 46, 34,
-  8, 0, 13, 0, 3, 31, 63, 19, 94, 0,
-  15, 0, 17, 0, 0, 75, 0, 0, 5, 14,
-  48, 1, 0, 0, 0, 56, 51, 0, 0, 4,
-  32, 10, 13, 41, 0, 10, 71, 13, 29, 0,
-  10, 14, 0, 17, 0, 0, 42, 0, 5, 27,
-  0, 0, 9, 20, 0, 26, 0, 66, 11, 74,
-  35, 26, 0, 2, 0, 16, 68, 0, 0, 0,
-  30, 0, 1, 5, 28, 45, 0, 49, 0, 0,
-  0, 37, 29, 0, 51, 0, 22, 9, 83, 12,
-  47, 23, 0, 0, 69, 0, 4, 0, 38, 0,
-  23, 2, 0, 0, 0, 0, 0, 6, 0, 38,
-  0, 0, 22, 49, 15, 29, 19, 13, 22, 0,
-  31, 11, 0, 28, 0, 0, 0, 0, 0, 0,
-  0, 19, 71, 6, 22, 4, 0, 0, 22, 0,
-  10, 0, 7, 18, 0, 16, 0, 21, 57, 17,
-  0, 0, 0, 41, 57, 2, 0, 6, 60, 44,
-  5, 5, 45, 0, 15, 0, 37, 0, 27, 0,
-  0, 35, 0, 0, 85, 0, 0, 0, 0, 5,
-  0, 0, 0, 23, 0, 64, 4, 113, 25, 79,
-  0, 0, 0, 41, 66, 0, 0, 22, 11, 0,
-  0, 0, 15, 0, 0, 2, 0, 0, 0, 36,
-  38, 0, 60, 0, 2, 0, 50, 0, 47, 0,
-  0, 0, 62, 0, 47, 0, 7, 0, 20, 0,
-  0, 8, 0, 4, 0, 8, 0, 7, 0, 0,
-  51, 44, 26, 26, 0, 37, 18, 0, 29, 6,
-  9, 13, 0, 18, 0, 17, 0, 0, 6, 0,
-  36, 0, 37, 0, 37, 0, 0, 0, 38, 0,
-  0, 12, 0, 42, 6, 15, 37, 28, 4, 4,
-  6, 14, 22, 0, 5, 59, 66, 39, 0, 24,
-  0, 0, 0, 20, 47, 15, 29, 33, 0, 35,
-  0, 0, 91, 34, 6, 0, 0, 11, 0, 10,
-  0, 18, 0, 22, 0, 58, 46, 78, 0, 43,
-  0, 62, 86, 46, 0, 56, 0, 0, 0, 20,
-  4, 0, 0, 0, 0, 0, 39, 0, 35, 6,
-  23, 0, 0, 0, 28, 23, 8, 0, 0, 0,
-  113, 0, 11, 9, 0, 0, 7, 22, 0, 0,
-  22, 29, 0, 8, 36, 0, 36, 0, 26, 59,
-  19, 7, 14, 19, 16, 0, 26, 17, 35, 32,
-  0, 9, 19, 42, 0, 0, 5, 0, 0, 0,
-  14, 11, 125, 0, 35, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 23, 19, 0, 34, 10, 9, 83, 40,
-  0, 0, 0, 24, 57, 8, 0, 49, 29, 55,
-  14, 27, 77, 6, 23, 33, 54, 0, 58, 20,
-  192, 4, 0, 22, 109, 15, 46, 0, 0, 37,
-  38, 5, 0, 0, 0, 70, 41, 137, 1, 46,
-  0, 13, 0, 79, 54, 2, 11, 54, 16, 0,
-  0, 0, 37, 0, 13, 6, 0, 0, 18, 17,
-  31, 11, 84, 0, 5, 0, 13, 0, 66, 45,
-  13, 0, 58, 0, 30, 0, 0, 0, 28, 0,
-  31, 38, 0, 18, 0, 18, 32, 25, 25, 0,
-  48, 37, 18, 2, 0, 55, 81, 0, 12, 13,
-  23, 14, 0, 32, 10, 37, 0, 0, 29, 0,
-  19, 21, 86, 0, 13, 0, 0, 0, 37, 12,
-  0, 33, 0, 8, 0, 0, 88, 51, 0, 25,
-  4, 29, 23, 1, 15, 91, 42, 50, 0, 22,
-  30, 0, 0, 49, 47, 30, 47, 45, 143, 63,
-  23, 6, 105, 25, 47, 0, 0, 39, 4, 30,
-  0, 3, 39, 25, 43, 65, 2, 47, 0, 56,
-  16, 77, 68, 39, 2, 24, 5, 0, 0, 43,
-  0, 0, 0, 26, 0, 4, 28, 0, 0, 0,
-  1, 21, 0, 0, 4, 46, 30, 14, 4, 0,
-  94, 0, 0, 19, 0, 0, 9, 3, 54, 33,
-  28, 12, 0, 25, 28, 16, 54, 0, 16, 44,
-  0, 0, 10, 24, 96, 0, 13, 21, 39, 36,
-  23, 10, 46, 34, 8, 0, 13, 0, 3, 31,
-  63, 19, 94, 0, 15, 0, 17, 0, 0, 98,
-  1, 0, 0, 0, 70, 26, 1, 40, 0, 18,
-  8, 0, 0, 55, 20, 56, 0, 28, 0, 0,
-  9, 77, 37, 43, 56, 51, 165, 33, 18, 0,
-  85, 0, 49, 0, 0, 7, 13, 31, 0, 0,
-  65, 0, 42, 42, 0, 0, 0, 51, 14, 68,
-  75, 5, 23, 0, 0, 0, 0, 38, 0, 3,
-  1, 24, 0, 20, 44, 0, 0, 18, 0, 29,
-  38, 5, 30, 64, 3, 48, 31, 0, 73, 0,
-  0, 22, 0, 9, 14, 16, 72, 24, 54, 0,
-  0, 3, 10, 1, 31, 0, 4, 29, 0, 13,
-  27, 0, 87, 0, 38, 9, 40, 53, 46, 4,
-  16, 15, 5, 0, 5, 0, 11, 52, 56, 10,
-  49, 0, 36, 0, 7, 0, 7, 18, 0, 16,
-  0, 21, 57, 17, 0, 0, 0, 41, 57, 2,
-  0, 6, 60, 44, 5, 5, 45, 0, 15, 0,
-  37, 0, 27, 0, 0, 35, 0, 0, 85, 0,
-  0, 0, 0, 5, 0, 0, 0, 23, 0, 64,
-  4, 113, 25, 79, 0, 0, 0, 41, 66, 0,
-  0, 22, 11, 0, 0, 0, 15, 0, 0, 2,
-  0, 0, 0, 36, 38, 0, 60, 0, 2, 0,
-  50, 0, 47, 0, 0, 0, 62, 0, 47, 0,
-  7, 0, 20, 0, 0, 8, 0, 4, 0, 8,
-  0, 7, 0, 0, 51, 44, 26, 26, 0, 37,
-  18, 0, 29, 6, 9, 13, 0, 18, 0, 17,
-  0, 0, 6, 0, 36, 0, 37, 0, 37, 0,
-  0, 0, 38, 0, 0, 12, 0, 42, 6, 15,
-  37, 28, 4, 4, 6, 14, 22, 0, 5, 59,
-  66, 39, 0, 24, 0, 0, 0, 20, 47, 15,
-  29, 33, 0, 35, 0, 0, 91, 34, 6, 0,
-  0, 11, 0, 10, 0, 18, 0, 22, 0, 58,
-  46, 78, 0, 43, 0, 62, 86, 46, 0, 56,
-  0, 0, 0, 20, 4, 0, 0, 0, 0, 0,
-  39, 0, 35, 6, 23, 0, 0, 0, 28, 23,
-  8, 0, 0, 0, 113, 0, 11, 9, 0, 0,
-  7, 22, 0, 0, 22, 29, 0, 8, 36, 0,
-  36, 0, 26, 59, 19, 7, 14, 19, 16, 0,
-  26, 17, 35, 32, 0, 9, 19, 42, 0, 0,
-  5, 0, 0, 0, 14, 11, 125, 0, 35, 0,
-  0, 0, 0, 93, 5, 24, 14, 0, 37, 16,
-  19, 24, 15, 1, 7, 0, 45, 74, 66, 43,
-  0, 20, 0, 0, 0, 49, 65, 69, 6, 62,
-  0, 1, 5, 0, 69, 27, 8, 0, 0, 8,
-  0, 34, 0, 35, 41, 0, 16, 0, 40, 0,
-  0, 56, 0, 37, 99, 45, 0, 4, 0, 17,
-  0, 45, 12, 0, 0, 33, 0, 12, 78, 0,
-  23, 0, 0, 0, 0, 6, 46, 35, 1, 18,
-  0, 2, 119, 0, 0, 1, 0, 16, 0, 27,
-  17, 29, 59, 0, 0, 26, 0, 8, 27, 0,
-  0, 42, 0, 0, 29, 0, 16, 0, 32, 10,
-  52, 56, 0, 0, 9, 11, 0, 0, 0, 0,
-  0, 0, 4, 23, 137, 0, 66, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 33, 0, 8, 0, 0,
-  88, 51, 0, 25, 4, 29, 23, 1, 15, 91,
-  42, 50, 0, 22, 30, 0, 0, 49, 47, 30,
-  47, 45, 143, 63, 23, 6, 105, 25, 47, 0,
-  0, 39, 4, 30, 0, 3, 39, 25, 43, 65,
-  2, 47, 0, 56, 16, 77, 68, 39, 2, 24,
-  5, 0, 0, 43, 0, 0, 0, 26, 0, 4,
-  28, 0, 0, 0, 1, 21, 0, 0, 4, 46,
-  30, 14, 4, 0, 94, 0, 0, 19, 0, 0,
-  9, 3, 54, 33, 28, 12, 0, 25, 28, 16,
-  54, 0, 16, 44, 0, 0, 10, 24, 96, 0,
-  13, 21, 39, 36, 23, 10, 46, 34, 8, 0,
-  13, 0, 3, 31, 63, 19, 94, 0, 15, 0,
-  17, 0, 0, 98, 1, 0, 0, 0, 70, 26,
-  1, 40, 0, 18, 8, 0, 0, 55, 20, 56,
-  0, 28, 0, 0, 9, 77, 37, 43, 56, 51,
-  165, 33, 18, 0, 85, 0, 49, 0, 0, 7,
-  13, 31, 0, 0, 65, 0, 42, 42, 0, 0,
-  0, 51, 14, 68, 75, 5, 23, 0, 0, 0,
-  0, 38, 0, 3, 1, 24, 0, 20, 44, 0,
-  0, 18, 0, 29, 38, 5, 30, 64, 3, 48,
-  31, 0, 73, 0, 0, 22, 0, 9, 14, 16,
-  72, 24, 54, 0, 0, 3, 10, 1, 31, 0,
-  4, 29, 0, 13, 27, 0, 87, 0, 38, 9,
-  40, 53, 46, 4, 16, 15, 5, 0, 5, 0,
-  11, 52, 56, 10, 49, 0, 36, 0, 7, 0,
-  21, 87, 0, 17, 0, 0, 7, 0, 27, 18,
-  0, 30, 39, 0, 0, 11, 9, 43, 15, 26,
-  0, 36, 93, 68, 12, 0, 68, 46, 209, 0,
-  0, 0, 54, 0, 48, 43, 0, 0, 65, 3,
-  0, 0, 39, 14, 18, 96, 0, 0, 0, 10,
-  0, 107, 61, 0, 69, 0, 19, 0, 17, 0,
-  20, 40, 0, 0, 35, 25, 0, 0, 0, 58,
-  134, 10, 46, 0, 8, 33, 3, 95, 34, 0,
-  24, 0, 8, 20, 0, 5, 21, 22, 59, 0,
-  30, 0, 0, 0, 54, 0, 27, 0, 10, 43,
-  26, 72, 29, 15, 69, 18, 47, 0, 13, 38,
-  8, 8, 0, 1, 0, 0, 3, 0, 8, 49,
-  53, 0, 0, 0, 36, 0, 0, 0, 0, 12,
-  0, 42, 6, 15, 37, 28, 4, 4, 6, 14,
-  22, 0, 5, 59, 66, 39, 0, 24, 0, 0,
-  0, 20, 47, 15, 29, 33, 0, 35, 0, 0,
-  91, 34, 6, 0, 0, 11, 0, 10, 0, 18,
-  0, 22, 0, 58, 46, 78, 0, 43, 0, 62,
-  86, 46, 0, 56, 0, 0, 0, 20, 4, 0,
-  0, 0, 0, 0, 39, 0, 35, 6, 23, 0,
-  0, 0, 28, 23, 8, 0, 0, 0, 113, 0,
-  11, 9, 0, 0, 7, 22, 0, 0, 22, 29,
-  0, 8, 36, 0, 36, 0, 26, 59, 19, 7,
-  14, 19, 16, 0, 26, 17, 35, 32, 0, 9,
-  19, 42, 0, 0, 5, 0, 0, 0, 14, 11,
-  125, 0, 35, 0, 0, 0, 0, 93, 5, 24,
-  14, 0, 37, 16, 19, 24, 15, 1, 7, 0,
-  45, 74, 66, 43, 0, 20, 0, 0, 0, 49,
-  65, 69, 6, 62, 0, 1, 5, 0, 69, 27,
-  8, 0, 0, 8, 0, 34, 0, 35, 41, 0,
-  16, 0, 40, 0, 0, 56, 0, 37, 99, 45,
-  0, 4, 0, 17, 0, 45, 12, 0, 0, 33,
-  0, 12, 78, 0, 23, 0, 0, 0, 0, 6,
-  46, 35, 1, 18, 0, 2, 119, 0, 0, 1,
-  0, 16, 0, 27, 17, 29, 59, 0, 0, 26,
-  0, 8, 27, 0, 0, 42, 0, 0, 29, 0,
-  16, 0, 32, 10, 52, 56, 0, 0, 9, 11,
-  0, 0, 0, 0, 0, 0, 4, 23, 137, 0,
-  66, 0, 0, 0, 0, 115, 36, 17, 6, 0,
-  3, 0, 44, 17, 0, 0, 3, 0, 0, 24,
-  36, 38, 6, 35, 0, 0, 67, 53, 19, 0,
-  40, 54, 0, 0, 0, 0, 68, 0, 53, 8,
-  0, 0, 28, 2, 0, 0, 37, 25, 0, 67,
-  27, 0, 0, 2, 0, 53, 88, 0, 20, 0,
-  26, 0, 0, 0, 0, 27, 0, 0, 0, 0,
-  0, 0, 0, 14, 53, 0, 37, 17, 61, 42,
-  0, 74, 24, 0, 64, 0, 4, 21, 0, 0,
-  6, 36, 25, 20, 74, 0, 0, 0, 24, 0,
-  0, 0, 0, 53, 38, 17, 0, 0, 21, 4,
-  62, 0, 41, 58, 0, 16, 0, 3, 0, 0,
-  0, 0, 0, 6, 0, 0, 35, 0, 53, 1,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 98, 1, 0,
-  0, 0, 70, 26, 1, 40, 0, 18, 8, 0,
-  0, 55, 20, 56, 0, 28, 0, 0, 9, 77,
-  37, 43, 56, 51, 165, 33, 18, 0, 85, 0,
-  49, 0, 0, 7, 13, 31, 0, 0, 65, 0,
-  42, 42, 0, 0, 0, 51, 14, 68, 75, 5,
-  23, 0, 0, 0, 0, 38, 0, 3, 1, 24,
-  0, 20, 44, 0, 0, 18, 0, 29, 38, 5,
-  30, 64, 3, 48, 31, 0, 73, 0, 0, 22,
-  0, 9, 14, 16, 72, 24, 54, 0, 0, 3,
-  10, 1, 31, 0, 4, 29, 0, 13, 27, 0,
-  87, 0, 38, 9, 40, 53, 46, 4, 16, 15,
-  5, 0, 5, 0, 11, 52, 56, 10, 49, 0,
-  36, 0, 7, 0, 21, 87, 0, 17, 0, 0,
-  7, 0, 27, 18, 0, 30, 39, 0, 0, 11,
-  9, 43, 15, 26, 0, 36, 93, 68, 12, 0,
-  68, 46, 209, 0, 0, 0, 54, 0, 48, 43,
-  0, 0, 65, 3, 0, 0, 39, 14, 18, 96,
-  0, 0, 0, 10, 0, 107, 61, 0, 69, 0,
-  19, 0, 17, 0, 20, 40, 0, 0, 35, 25,
-  0, 0, 0, 58, 134, 10, 46, 0, 8, 33,
-  3, 95, 34, 0, 24, 0, 8, 20, 0, 5,
-  21, 22, 59, 0, 30, 0, 0, 0, 54, 0,
-  27, 0, 10, 43, 26, 72, 29, 15, 69, 18,
-  47, 0, 13, 38, 8, 8, 0, 1, 0, 0,
-  3, 0, 8, 49, 53, 0, 0, 0, 36, 0,
-  0, 0, 121, 68, 0, 69, 37, 0, 10, 0,
-  13, 0, 0, 24, 109, 0, 0, 19, 14, 0,
-  23, 0, 0, 116, 51, 34, 64, 0, 36, 36,
-  222, 0, 6, 97, 40, 17, 23, 41, 0, 0,
-  124, 6, 0, 0, 30, 56, 59, 90, 15, 0,
-  0, 12, 0, 135, 15, 0, 103, 17, 27, 22,
-  53, 0, 58, 43, 30, 87, 0, 83, 14, 0,
-  21, 25, 137, 20, 29, 0, 0, 0, 51, 86,
-  41, 0, 7, 0, 17, 24, 0, 13, 21, 0,
-  55, 9, 0, 0, 0, 0, 22, 16, 63, 0,
-  40, 42, 4, 62, 32, 21, 74, 29, 0, 42,
-  54, 0, 12, 14, 0, 0, 0, 27, 4, 0,
-  11, 38, 71, 25, 0, 34, 62, 0, 9, 24,
-  0, 93, 5, 24, 14, 0, 37, 16, 19, 24,
-  15, 1, 7, 0, 45, 74, 66, 43, 0, 20,
-  0, 0, 0, 49, 65, 69, 6, 62, 0, 1,
-  5, 0, 69, 27, 8, 0, 0, 8, 0, 34,
-  0, 35, 41, 0, 16, 0, 40, 0, 0, 56,
-  0, 37, 99, 45, 0, 4, 0, 17, 0, 45,
-  12, 0, 0, 33, 0, 12, 78, 0, 23, 0,
-  0, 0, 0, 6, 46, 35, 1, 18, 0, 2,
-  119, 0, 0, 1, 0, 16, 0, 27, 17, 29,
-  59, 0, 0, 26, 0, 8, 27, 0, 0, 42,
-  0, 0, 29, 0, 16, 0, 32, 10, 52, 56,
-  0, 0, 9, 11, 0, 0, 0, 0, 0, 0,
-  4, 23, 137, 0, 66, 0, 0, 0, 0, 115,
-  36, 17, 6, 0, 3, 0, 44, 17, 0, 0,
-  3, 0, 0, 24, 36, 38, 6, 35, 0, 0,
-  67, 53, 19, 0, 40, 54, 0, 0, 0, 0,
-  68, 0, 53, 8, 0, 0, 28, 2, 0, 0,
-  37, 25, 0, 67, 27, 0, 0, 2, 0, 53,
-  88, 0, 20, 0, 26, 0, 0, 0, 0, 27,
-  0, 0, 0, 0, 0, 0, 0, 14, 53, 0,
-  37, 17, 61, 42, 0, 74, 24, 0, 64, 0,
-  4, 21, 0, 0, 6, 36, 25, 20, 74, 0,
-  0, 0, 24, 0, 0, 0, 0, 53, 38, 17,
-  0, 0, 21, 4, 62, 0, 41, 58, 0, 16,
-  0, 3, 0, 0, 0, 0, 0, 6, 0, 0,
-  35, 0, 53, 1, 0, 0, 55, 68, 5, 59,
-  7, 0, 0, 0, 39, 0, 0, 18, 78, 0,
-  0, 0, 25, 2, 0, 0, 0, 34, 65, 19,
-  34, 0, 18, 36, 0, 0, 0, 6, 13, 0,
-  31, 16, 0, 0, 71, 0, 0, 16, 19, 37,
-  0, 40, 14, 0, 0, 0, 0, 107, 29, 0,
-  61, 0, 36, 0, 0, 0, 0, 19, 0, 10,
-  41, 34, 0, 0, 22, 0, 133, 0, 33, 13,
-  17, 0, 9, 54, 28, 7, 16, 0, 14, 15,
-  15, 0, 15, 0, 48, 0, 1, 0, 0, 0,
-  0, 0, 10, 0, 0, 40, 0, 1, 9, 0,
-  35, 68, 7, 20, 38, 3, 0, 13, 0, 0,
-  0, 0, 0, 0, 0, 9, 0, 0, 0, 0,
-  53, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 21, 87,
-  0, 17, 0, 0, 7, 0, 27, 18, 0, 30,
-  39, 0, 0, 11, 9, 43, 15, 26, 0, 36,
-  93, 68, 12, 0, 68, 46, 209, 0, 0, 0,
-  54, 0, 48, 43, 0, 0, 65, 3, 0, 0,
-  39, 14, 18, 96, 0, 0, 0, 10, 0, 107,
-  61, 0, 69, 0, 19, 0, 17, 0, 20, 40,
-  0, 0, 35, 25, 0, 0, 0, 58, 134, 10,
-  46, 0, 8, 33, 3, 95, 34, 0, 24, 0,
-  8, 20, 0, 5, 21, 22, 59, 0, 30, 0,
-  0, 0, 54, 0, 27, 0, 10, 43, 26, 72,
-  29, 15, 69, 18, 47, 0, 13, 38, 8, 8,
-  0, 1, 0, 0, 3, 0, 8, 49, 53, 0,
-  0, 0, 36, 0, 0, 0, 121, 68, 0, 69,
-  37, 0, 10, 0, 13, 0, 0, 24, 109, 0,
-  0, 19, 14, 0, 23, 0, 0, 116, 51, 34,
-  64, 0, 36, 36, 222, 0, 6, 97, 40, 17,
-  23, 41, 0, 0, 124, 6, 0, 0, 30, 56,
-  59, 90, 15, 0, 0, 12, 0, 135, 15, 0,
-  103, 17, 27, 22, 53, 0, 58, 43, 30, 87,
-  0, 83, 14, 0, 21, 25, 137, 20, 29, 0,
-  0, 0, 51, 86, 41, 0, 7, 0, 17, 24,
-  0, 13, 21, 0, 55, 9, 0, 0, 0, 0,
-  22, 16, 63, 0, 40, 42, 4, 62, 32, 21,
-  74, 29, 0, 42, 54, 0, 12, 14, 0, 0,
-  0, 27, 4, 0, 11, 38, 71, 25, 0, 34,
-  62, 0, 9, 24, 66, 10, 0, 31, 29, 110,
-  12, 0, 20, 0, 0, 9, 85, 0, 0, 46,
-  16, 30, 0, 0, 33, 111, 0, 60, 48, 0,
-  3, 44, 255, 0, 0, 72, 42, 37, 17, 24,
-  0, 22, 96, 20, 32, 0, 17, 61, 85, 122,
-  14, 0, 0, 23, 0, 130, 26, 0, 91, 47,
-  26, 11, 67, 0, 34, 60, 32, 28, 0, 46,
-  0, 4, 12, 28, 143, 0, 41, 3, 0, 22,
-  11, 56, 20, 0, 23, 0, 1, 24, 0, 0,
-  19, 5, 50, 28, 0, 55, 8, 0, 61, 18,
-  20, 0, 39, 55, 9, 30, 21, 7, 86, 7,
-  1, 22, 0, 7, 0, 16, 0, 0, 0, 31,
-  20, 0, 35, 34, 69, 0, 0, 44, 59, 0,
-  6, 4, 0, 115, 36, 17, 6, 0, 3, 0,
-  44, 17, 0, 0, 3, 0, 0, 24, 36, 38,
-  6, 35, 0, 0, 67, 53, 19, 0, 40, 54,
-  0, 0, 0, 0, 68, 0, 53, 8, 0, 0,
-  28, 2, 0, 0, 37, 25, 0, 67, 27, 0,
-  0, 2, 0, 53, 88, 0, 20, 0, 26, 0,
-  0, 0, 0, 27, 0, 0, 0, 0, 0, 0,
-  0, 14, 53, 0, 37, 17, 61, 42, 0, 74,
-  24, 0, 64, 0, 4, 21, 0, 0, 6, 36,
-  25, 20, 74, 0, 0, 0, 24, 0, 0, 0,
-  0, 53, 38, 17, 0, 0, 21, 4, 62, 0,
-  41, 58, 0, 16, 0, 3, 0, 0, 0, 0,
-  0, 6, 0, 0, 35, 0, 53, 1, 0, 0,
-  55, 68, 5, 59, 7, 0, 0, 0, 39, 0,
-  0, 18, 78, 0, 0, 0, 25, 2, 0, 0,
-  0, 34, 65, 19, 34, 0, 18, 36, 0, 0,
-  0, 6, 13, 0, 31, 16, 0, 0, 71, 0,
-  0, 16, 19, 37, 0, 40, 14, 0, 0, 0,
-  0, 107, 29, 0, 61, 0, 36, 0, 0, 0,
-  0, 19, 0, 10, 41, 34, 0, 0, 22, 0,
-  133, 0, 33, 13, 17, 0, 9, 54, 28, 7,
-  16, 0, 14, 15, 15, 0, 15, 0, 48, 0,
-  1, 0, 0, 0, 0, 0, 10, 0, 0, 40,
-  0, 1, 9, 0, 35, 68, 7, 20, 38, 3,
-  0, 13, 0, 0, 0, 0, 0, 0, 0, 9,
-  0, 0, 0, 0, 53, 0, 0, 0, 104, 21,
-  0, 47, 20, 66, 0, 0, 53, 0, 0, 0,
-  116, 0, 0, 40, 62, 0, 2, 0, 11, 68,
-  0, 8, 23, 0, 0, 43, 3, 1, 13, 72,
-  0, 27, 24, 0, 0, 21, 96, 5, 13, 87,
-  14, 47, 59, 16, 0, 0, 0, 0, 0, 111,
-  0, 0, 107, 59, 25, 17, 19, 0, 0, 13,
-  9, 35, 0, 93, 0, 0, 13, 0, 155, 30,
-  22, 32, 0, 0, 34, 19, 0, 47, 0, 0,
-  15, 14, 42, 14, 8, 0, 73, 0, 0, 0,
-  0, 2, 0, 0, 31, 0, 21, 50, 0, 0,
-  5, 0, 30, 31, 0, 67, 22, 0, 17, 0,
-  0, 0, 0, 0, 0, 0, 0, 1, 0, 3,
-  0, 16, 53, 0, 3, 16, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  121, 68, 0, 69, 37, 0, 10, 0, 13, 0,
-  0, 24, 109, 0, 0, 19, 14, 0, 23, 0,
-  0, 116, 51, 34, 64, 0, 36, 36, 222, 0,
-  6, 97, 40, 17, 23, 41, 0, 0, 124, 6,
-  0, 0, 30, 56, 59, 90, 15, 0, 0, 12,
-  0, 135, 15, 0, 103, 17, 27, 22, 53, 0,
-  58, 43, 30, 87, 0, 83, 14, 0, 21, 25,
-  137, 20, 29, 0, 0, 0, 51, 86, 41, 0,
-  7, 0, 17, 24, 0, 13, 21, 0, 55, 9,
-  0, 0, 0, 0, 22, 16, 63, 0, 40, 42,
-  4, 62, 32, 21, 74, 29, 0, 42, 54, 0,
-  12, 14, 0, 0, 0, 27, 4, 0, 11, 38,
-  71, 25, 0, 34, 62, 0, 9, 24, 66, 10,
-  0, 31, 29, 110, 12, 0, 20, 0, 0, 9,
-  85, 0, 0, 46, 16, 30, 0, 0, 33, 111,
-  0, 60, 48, 0, 3, 44, 255, 0, 0, 72,
-  42, 37, 17, 24, 0, 22, 96, 20, 32, 0,
-  17, 61, 85, 122, 14, 0, 0, 23, 0, 130,
-  26, 0, 91, 47, 26, 11, 67, 0, 34, 60,
-  32, 28, 0, 46, 0, 4, 12, 28, 143, 0,
-  41, 3, 0, 22, 11, 56, 20, 0, 23, 0,
-  1, 24, 0, 0, 19, 5, 50, 28, 0, 55,
-  8, 0, 61, 18, 20, 0, 39, 55, 9, 30,
-  21, 7, 86, 7, 1, 22, 0, 7, 0, 16,
-  0, 0, 0, 31, 20, 0, 35, 34, 69, 0,
-  0, 44, 59, 0, 6, 4, 0, 38, 0, 0,
-  7, 72, 57, 6, 59, 17, 0, 6, 46, 16,
-  0, 163, 49, 58, 0, 0, 76, 0, 0, 90,
-  29, 28, 5, 40, 214, 33, 0, 0, 89, 29,
-  32, 0, 0, 53, 10, 75, 12, 0, 0, 45,
-  49, 87, 5, 9, 0, 73, 3, 65, 107, 1,
-  7, 49, 22, 23, 0, 54, 0, 5, 0, 32,
-  0, 1, 11, 0, 25, 0, 29, 0, 39, 11,
-  0, 97, 0, 37, 0, 1, 62, 0, 14, 26,
-  0, 4, 35, 12, 60, 53, 62, 78, 0, 3,
-  68, 5, 0, 0, 50, 64, 14, 0, 0, 0,
-  76, 0, 29, 16, 1, 58, 17, 0, 0, 22,
-  0, 0, 0, 12, 39, 12, 66, 4, 74, 0,
-  59, 0, 32, 0, 55, 68, 5, 59, 7, 0,
-  0, 0, 39, 0, 0, 18, 78, 0, 0, 0,
-  25, 2, 0, 0, 0, 34, 65, 19, 34, 0,
-  18, 36, 0, 0, 0, 6, 13, 0, 31, 16,
-  0, 0, 71, 0, 0, 16, 19, 37, 0, 40,
-  14, 0, 0, 0, 0, 107, 29, 0, 61, 0,
-  36, 0, 0, 0, 0, 19, 0, 10, 41, 34,
-  0, 0, 22, 0, 133, 0, 33, 13, 17, 0,
-  9, 54, 28, 7, 16, 0, 14, 15, 15, 0,
-  15, 0, 48, 0, 1, 0, 0, 0, 0, 0,
-  10, 0, 0, 40, 0, 1, 9, 0, 35, 68,
-  7, 20, 38, 3, 0, 13, 0, 0, 0, 0,
-  0, 0, 0, 9, 0, 0, 0, 0, 53, 0,
-  0, 0, 104, 21, 0, 47, 20, 66, 0, 0,
-  53, 0, 0, 0, 116, 0, 0, 40, 62, 0,
-  2, 0, 11, 68, 0, 8, 23, 0, 0, 43,
-  3, 1, 13, 72, 0, 27, 24, 0, 0, 21,
-  96, 5, 13, 87, 14, 47, 59, 16, 0, 0,
-  0, 0, 0, 111, 0, 0, 107, 59, 25, 17,
-  19, 0, 0, 13, 9, 35, 0, 93, 0, 0,
-  13, 0, 155, 30, 22, 32, 0, 0, 34, 19,
-  0, 47, 0, 0, 15, 14, 42, 14, 8, 0,
-  73, 0, 0, 0, 0, 2, 0, 0, 31, 0,
-  21, 50, 0, 0, 5, 0, 30, 31, 0, 67,
-  22, 0, 17, 0, 0, 0, 0, 0, 0, 0,
-  0, 1, 0, 3, 0, 16, 53, 0, 3, 16,
-  0, 0, 0, 0, 0, 145, 0, 0, 46, 0,
-  0, 0, 34, 21, 0, 109, 67, 48, 0, 0,
-  39, 1, 0, 58, 0, 0, 0, 56, 1, 0,
-  0, 0, 49, 0, 0, 0, 22, 71, 0, 0,
-  22, 0, 0, 3, 13, 87, 0, 0, 0, 14,
-  12, 53, 23, 0, 62, 19, 29, 0, 0, 0,
-  0, 48, 0, 0, 12, 0, 16, 0, 17, 13,
-  58, 0, 50, 76, 0, 66, 0, 52, 0, 0,
-  8, 0, 17, 64, 0, 25, 19, 0, 22, 2,
-  35, 128, 0, 0, 75, 0, 0, 0, 0, 93,
-  86, 0, 0, 0, 15, 0, 0, 38, 0, 19,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 13, 0, 4, 15, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 66, 10, 0, 31, 29, 110, 12, 0,
-  20, 0, 0, 9, 85, 0, 0, 46, 16, 30,
-  0, 0, 33, 111, 0, 60, 48, 0, 3, 44,
-  255, 0, 0, 72, 42, 37, 17, 24, 0, 22,
-  96, 20, 32, 0, 17, 61, 85, 122, 14, 0,
-  0, 23, 0, 130, 26, 0, 91, 47, 26, 11,
-  67, 0, 34, 60, 32, 28, 0, 46, 0, 4,
-  12, 28, 143, 0, 41, 3, 0, 22, 11, 56,
-  20, 0, 23, 0, 1, 24, 0, 0, 19, 5,
-  50, 28, 0, 55, 8, 0, 61, 18, 20, 0,
-  39, 55, 9, 30, 21, 7, 86, 7, 1, 22,
-  0, 7, 0, 16, 0, 0, 0, 31, 20, 0,
-  35, 34, 69, 0, 0, 44, 59, 0, 6, 4,
-  0, 38, 0, 0, 7, 72, 57, 6, 59, 17,
-  0, 6, 46, 16, 0, 163, 49, 58, 0, 0,
-  76, 0, 0, 90, 29, 28, 5, 40, 214, 33,
-  0, 0, 89, 29, 32, 0, 0, 53, 10, 75,
-  12, 0, 0, 45, 49, 87, 5, 9, 0, 73,
-  3, 65, 107, 1, 7, 49, 22, 23, 0, 54,
-  0, 5, 0, 32, 0, 1, 11, 0, 25, 0,
-  29, 0, 39, 11, 0, 97, 0, 37, 0, 1,
-  62, 0, 14, 26, 0, 4, 35, 12, 60, 53,
-  62, 78, 0, 3, 68, 5, 0, 0, 50, 64,
-  14, 0, 0, 0, 76, 0, 29, 16, 1, 58,
-  17, 0, 0, 22, 0, 0, 0, 12, 39, 12,
-  66, 4, 74, 0, 59, 0, 32, 0, 0, 58,
-  63, 0, 7, 0, 21, 41, 98, 32, 26, 34,
-  16, 64, 0, 150, 62, 63, 48, 14, 52, 0,
-  0, 72, 12, 0, 54, 79, 175, 35, 0, 0,
-  104, 0, 8, 0, 3, 53, 0, 34, 0, 0,
-  0, 32, 8, 71, 0, 0, 0, 50, 34, 80,
-  101, 18, 30, 0, 24, 14, 0, 49, 0, 0,
-  0, 16, 0, 0, 47, 0, 11, 29, 0, 0,
-  63, 28, 0, 75, 0, 60, 0, 1, 62, 4,
-  40, 45, 0, 23, 18, 40, 92, 24, 106, 1,
-  0, 0, 68, 0, 17, 0, 31, 98, 42, 0,
-  7, 0, 83, 0, 3, 51, 27, 30, 31, 0,
-  16, 5, 20, 0, 0, 18, 0, 32, 51, 0,
-  76, 0, 65, 0, 38, 22, 104, 21, 0, 47,
-  20, 66, 0, 0, 53, 0, 0, 0, 116, 0,
-  0, 40, 62, 0, 2, 0, 11, 68, 0, 8,
-  23, 0, 0, 43, 3, 1, 13, 72, 0, 27,
-  24, 0, 0, 21, 96, 5, 13, 87, 14, 47,
-  59, 16, 0, 0, 0, 0, 0, 111, 0, 0,
-  107, 59, 25, 17, 19, 0, 0, 13, 9, 35,
-  0, 93, 0, 0, 13, 0, 155, 30, 22, 32,
-  0, 0, 34, 19, 0, 47, 0, 0, 15, 14,
-  42, 14, 8, 0, 73, 0, 0, 0, 0, 2,
-  0, 0, 31, 0, 21, 50, 0, 0, 5, 0,
-  30, 31, 0, 67, 22, 0, 17, 0, 0, 0,
-  0, 0, 0, 0, 0, 1, 0, 3, 0, 16,
-  53, 0, 3, 16, 0, 0, 0, 0, 0, 145,
-  0, 0, 46, 0, 0, 0, 34, 21, 0, 109,
-  67, 48, 0, 0, 39, 1, 0, 58, 0, 0,
-  0, 56, 1, 0, 0, 0, 49, 0, 0, 0,
-  22, 71, 0, 0, 22, 0, 0, 3, 13, 87,
-  0, 0, 0, 14, 12, 53, 23, 0, 62, 19,
-  29, 0, 0, 0, 0, 48, 0, 0, 12, 0,
-  16, 0, 17, 13, 58, 0, 50, 76, 0, 66,
-  0, 52, 0, 0, 8, 0, 17, 64, 0, 25,
-  19, 0, 22, 2, 35, 128, 0, 0, 75, 0,
-  0, 0, 0, 93, 86, 0, 0, 0, 15, 0,
-  0, 38, 0, 19, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 13, 0,
-  4, 15, 0, 0, 92, 0, 0, 76, 0, 0,
-  44, 0, 0, 15, 13, 93, 0, 13, 41, 74,
-  27, 0, 22, 35, 4, 32, 0, 0, 0, 34,
-  0, 0, 18, 4, 5, 0, 0, 0, 14, 65,
-  0, 0, 0, 14, 0, 0, 0, 18, 0, 0,
-  0, 0, 19, 112, 26, 0, 66, 0, 49, 0,
-  1, 0, 0, 12, 0, 0, 37, 7, 27, 10,
-  26, 96, 0, 0, 36, 15, 0, 30, 0, 21,
-  0, 0, 0, 0, 33, 83, 0, 28, 14, 34,
-  42, 0, 16, 32, 0, 0, 39, 0, 0, 0,
-  13, 107, 45, 0, 0, 0, 3, 18, 0, 20,
-  0, 5, 17, 0, 0, 0, 49, 0, 46, 44,
-  22, 4, 0, 0, 0, 0, 20, 0, 0, 18,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 38, 0, 0, 7, 72,
-  57, 6, 59, 17, 0, 6, 46, 16, 0, 163,
-  49, 58, 0, 0, 76, 0, 0, 90, 29, 28,
-  5, 40, 214, 33, 0, 0, 89, 29, 32, 0,
-  0, 53, 10, 75, 12, 0, 0, 45, 49, 87,
-  5, 9, 0, 73, 3, 65, 107, 1, 7, 49,
-  22, 23, 0, 54, 0, 5, 0, 32, 0, 1,
-  11, 0, 25, 0, 29, 0, 39, 11, 0, 97,
-  0, 37, 0, 1, 62, 0, 14, 26, 0, 4,
-  35, 12, 60, 53, 62, 78, 0, 3, 68, 5,
-  0, 0, 50, 64, 14, 0, 0, 0, 76, 0,
-  29, 16, 1, 58, 17, 0, 0, 22, 0, 0,
-  0, 12, 39, 12, 66, 4, 74, 0, 59, 0,
-  32, 0, 0, 58, 63, 0, 7, 0, 21, 41,
-  98, 32, 26, 34, 16, 64, 0, 150, 62, 63,
-  48, 14, 52, 0, 0, 72, 12, 0, 54, 79,
-  175, 35, 0, 0, 104, 0, 8, 0, 3, 53,
-  0, 34, 0, 0, 0, 32, 8, 71, 0, 0,
-  0, 50, 34, 80, 101, 18, 30, 0, 24, 14,
-  0, 49, 0, 0, 0, 16, 0, 0, 47, 0,
-  11, 29, 0, 0, 63, 28, 0, 75, 0, 60,
-  0, 1, 62, 4, 40, 45, 0, 23, 18, 40,
-  92, 24, 106, 1, 0, 0, 68, 0, 17, 0,
-  31, 98, 42, 0, 7, 0, 83, 0, 3, 51,
-  27, 30, 31, 0, 16, 5, 20, 0, 0, 18,
-  0, 32, 51, 0, 76, 0, 65, 0, 38, 22,
-  50, 21, 117, 0, 0, 33, 0, 34, 48, 0,
-  0, 21, 0, 97, 0, 11, 24, 76, 56, 29,
-  7, 79, 14, 26, 0, 0, 21, 72, 178, 23,
-  2, 77, 15, 0, 0, 17, 0, 58, 0, 0,
-  0, 0, 23, 6, 0, 52, 0, 0, 0, 0,
-  17, 138, 16, 0, 76, 0, 43, 0, 26, 0,
-  0, 0, 10, 14, 41, 10, 2, 8, 11, 125,
-  0, 0, 81, 0, 0, 29, 11, 26, 12, 0,
-  0, 0, 1, 82, 0, 0, 46, 37, 66, 0,
-  39, 0, 0, 0, 91, 0, 6, 0, 15, 66,
-  24, 0, 23, 6, 85, 90, 0, 23, 0, 0,
-  42, 20, 11, 6, 52, 0, 44, 28, 0, 49,
-  48, 0, 0, 0, 21, 0, 24, 28, 0, 0,
-  0, 0, 0, 145, 0, 0, 46, 0, 0, 0,
-  34, 21, 0, 109, 67, 48, 0, 0, 39, 1,
-  0, 58, 0, 0, 0, 56, 1, 0, 0, 0,
-  49, 0, 0, 0, 22, 71, 0, 0, 22, 0,
-  0, 3, 13, 87, 0, 0, 0, 14, 12, 53,
-  23, 0, 62, 19, 29, 0, 0, 0, 0, 48,
-  0, 0, 12, 0, 16, 0, 17, 13, 58, 0,
-  50, 76, 0, 66, 0, 52, 0, 0, 8, 0,
-  17, 64, 0, 25, 19, 0, 22, 2, 35, 128,
-  0, 0, 75, 0, 0, 0, 0, 93, 86, 0,
-  0, 0, 15, 0, 0, 38, 0, 19, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 13, 0, 4, 15, 0, 0, 92, 0,
-  0, 76, 0, 0, 44, 0, 0, 15, 13, 93,
-  0, 13, 41, 74, 27, 0, 22, 35, 4, 32,
-  0, 0, 0, 34, 0, 0, 18, 4, 5, 0,
-  0, 0, 14, 65, 0, 0, 0, 14, 0, 0,
-  0, 18, 0, 0, 0, 0, 19, 112, 26, 0,
-  66, 0, 49, 0, 1, 0, 0, 12, 0, 0,
-  37, 7, 27, 10, 26, 96, 0, 0, 36, 15,
-  0, 30, 0, 21, 0, 0, 0, 0, 33, 83,
-  0, 28, 14, 34, 42, 0, 16, 32, 0, 0,
-  39, 0, 0, 0, 13, 107, 45, 0, 0, 0,
-  3, 18, 0, 20, 0, 5, 17, 0, 0, 0,
-  49, 0, 46, 44, 22, 4, 0, 0, 0, 0,
-  20, 0, 0, 18, 0, 0, 91, 0, 0, 56,
-  0, 0, 0, 0, 0, 21, 6, 68, 0, 0,
-  3, 66, 22, 26, 0, 44, 1, 12, 25, 0,
-  0, 0, 0, 0, 35, 19, 0, 0, 0, 0,
-  0, 41, 0, 0, 0, 9, 0, 13, 0, 4,
-  17, 0, 0, 0, 11, 90, 12, 0, 37, 0,
-  34, 0, 44, 0, 0, 20, 0, 0, 71, 0,
-  0, 58, 0, 66, 0, 22, 34, 0, 4, 12,
-  0, 0, 14, 0, 0, 0, 11, 67, 48, 0,
-  47, 25, 46, 0, 0, 0, 0, 0, 2, 0,
-  0, 5, 16, 47, 0, 0, 0, 1, 0, 93,
-  0, 9, 0, 23, 27, 12, 0, 4, 70, 6,
-  57, 62, 45, 37, 28, 1, 0, 0, 18, 8,
-  3, 27, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 58, 63, 0,
-  7, 0, 21, 41, 98, 32, 26, 34, 16, 64,
-  0, 150, 62, 63, 48, 14, 52, 0, 0, 72,
-  12, 0, 54, 79, 175, 35, 0, 0, 104, 0,
-  8, 0, 3, 53, 0, 34, 0, 0, 0, 32,
-  8, 71, 0, 0, 0, 50, 34, 80, 101, 18,
-  30, 0, 24, 14, 0, 49, 0, 0, 0, 16,
-  0, 0, 47, 0, 11, 29, 0, 0, 63, 28,
-  0, 75, 0, 60, 0, 1, 62, 4, 40, 45,
-  0, 23, 18, 40, 92, 24, 106, 1, 0, 0,
-  68, 0, 17, 0, 31, 98, 42, 0, 7, 0,
-  83, 0, 3, 51, 27, 30, 31, 0, 16, 5,
-  20, 0, 0, 18, 0, 32, 51, 0, 76, 0,
-  65, 0, 38, 22, 50, 21, 117, 0, 0, 33,
-  0, 34, 48, 0, 0, 21, 0, 97, 0, 11,
-  24, 76, 56, 29, 7, 79, 14, 26, 0, 0,
-  21, 72, 178, 23, 2, 77, 15, 0, 0, 17,
-  0, 58, 0, 0, 0, 0, 23, 6, 0, 52,
-  0, 0, 0, 0, 17, 138, 16, 0, 76, 0,
-  43, 0, 26, 0, 0, 0, 10, 14, 41, 10,
-  2, 8, 11, 125, 0, 0, 81, 0, 0, 29,
-  11, 26, 12, 0, 0, 0, 1, 82, 0, 0,
-  46, 37, 66, 0, 39, 0, 0, 0, 91, 0,
-  6, 0, 15, 66, 24, 0, 23, 6, 85, 90,
-  0, 23, 0, 0, 42, 20, 11, 6, 52, 0,
-  44, 28, 0, 49, 48, 0, 0, 0, 21, 0,
-  24, 28, 37, 2, 61, 0, 0, 73, 0, 0,
-  0, 0, 0, 0, 0, 114, 0, 0, 5, 58,
-  36, 11, 0, 72, 12, 49, 0, 0, 26, 41,
-  217, 0, 0, 48, 0, 41, 0, 0, 6, 3,
-  0, 0, 0, 0, 13, 0, 0, 63, 19, 55,
-  0, 0, 20, 92, 0, 0, 70, 0, 42, 0,
-  39, 0, 25, 1, 0, 0, 74, 12, 10, 4,
-  28, 139, 25, 13, 70, 0, 0, 6, 18, 0,
-  2, 4, 0, 0, 4, 80, 0, 0, 46, 48,
-  69, 0, 0, 0, 12, 0, 60, 0, 0, 0,
-  11, 29, 28, 90, 42, 8, 49, 129, 4, 0,
-  0, 1, 4, 23, 0, 0, 30, 66, 51, 23,
-  16, 39, 2, 0, 0, 0, 0, 0, 0, 44,
-  0, 0, 92, 0, 0, 76, 0, 0, 44, 0,
-  0, 15, 13, 93, 0, 13, 41, 74, 27, 0,
-  22, 35, 4, 32, 0, 0, 0, 34, 0, 0,
-  18, 4, 5, 0, 0, 0, 14, 65, 0, 0,
-  0, 14, 0, 0, 0, 18, 0, 0, 0, 0,
-  19, 112, 26, 0, 66, 0, 49, 0, 1, 0,
-  0, 12, 0, 0, 37, 7, 27, 10, 26, 96,
-  0, 0, 36, 15, 0, 30, 0, 21, 0, 0,
-  0, 0, 33, 83, 0, 28, 14, 34, 42, 0,
-  16, 32, 0, 0, 39, 0, 0, 0, 13, 107,
-  45, 0, 0, 0, 3, 18, 0, 20, 0, 5,
-  17, 0, 0, 0, 49, 0, 46, 44, 22, 4,
-  0, 0, 0, 0, 20, 0, 0, 18, 0, 0,
-  91, 0, 0, 56, 0, 0, 0, 0, 0, 21,
-  6, 68, 0, 0, 3, 66, 22, 26, 0, 44,
-  1, 12, 25, 0, 0, 0, 0, 0, 35, 19,
-  0, 0, 0, 0, 0, 41, 0, 0, 0, 9,
-  0, 13, 0, 4, 17, 0, 0, 0, 11, 90,
-  12, 0, 37, 0, 34, 0, 44, 0, 0, 20,
-  0, 0, 71, 0, 0, 58, 0, 66, 0, 22,
-  34, 0, 4, 12, 0, 0, 14, 0, 0, 0,
-  11, 67, 48, 0, 47, 25, 46, 0, 0, 0,
-  0, 0, 2, 0, 0, 5, 16, 47, 0, 0,
-  0, 1, 0, 93, 0, 9, 0, 23, 27, 12,
-  0, 4, 70, 6, 57, 62, 45, 37, 28, 1,
-  0, 0, 18, 8, 3, 27, 0, 16, 49, 0,
-  0, 5, 31, 0, 1, 0, 0, 6, 0, 41,
-  0, 0, 0, 25, 35, 4, 0, 0, 0, 52,
-  24, 0, 16, 5, 179, 11, 21, 0, 23, 0,
-  0, 0, 0, 11, 0, 43, 0, 24, 1, 8,
-  2, 65, 31, 0, 0, 0, 0, 37, 49, 0,
-  7, 0, 6, 0, 40, 14, 28, 28, 0, 0,
-  0, 18, 44, 18, 0, 7, 0, 39, 35, 0,
-  13, 18, 0, 0, 20, 0, 17, 2, 0, 51,
-  0, 0, 32, 30, 78, 35, 0, 0, 40, 0,
-  0, 22, 0, 0, 33, 23, 14, 18, 8, 0,
-  15, 74, 44, 16, 21, 36, 0, 12, 0, 0,
-  6, 34, 56, 40, 46, 34, 33, 8, 0, 0,
-  18, 0, 14, 30, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 50, 21,
-  117, 0, 0, 33, 0, 34, 48, 0, 0, 21,
-  0, 97, 0, 11, 24, 76, 56, 29, 7, 79,
-  14, 26, 0, 0, 21, 72, 178, 23, 2, 77,
-  15, 0, 0, 17, 0, 58, 0, 0, 0, 0,
-  23, 6, 0, 52, 0, 0, 0, 0, 17, 138,
-  16, 0, 76, 0, 43, 0, 26, 0, 0, 0,
-  10, 14, 41, 10, 2, 8, 11, 125, 0, 0,
-  81, 0, 0, 29, 11, 26, 12, 0, 0, 0,
-  1, 82, 0, 0, 46, 37, 66, 0, 39, 0,
-  0, 0, 91, 0, 6, 0, 15, 66, 24, 0,
-  23, 6, 85, 90, 0, 23, 0, 0, 42, 20,
-  11, 6, 52, 0, 44, 28, 0, 49, 48, 0,
-  0, 0, 21, 0, 24, 28, 37, 2, 61, 0,
-  0, 73, 0, 0, 0, 0, 0, 0, 0, 114,
-  0, 0, 5, 58, 36, 11, 0, 72, 12, 49,
-  0, 0, 26, 41, 217, 0, 0, 48, 0, 41,
-  0, 0, 6, 3, 0, 0, 0, 0, 13, 0,
-  0, 63, 19, 55, 0, 0, 20, 92, 0, 0,
-  70, 0, 42, 0, 39, 0, 25, 1, 0, 0,
-  74, 12, 10, 4, 28, 139, 25, 13, 70, 0,
-  0, 6, 18, 0, 2, 4, 0, 0, 4, 80,
-  0, 0, 46, 48, 69, 0, 0, 0, 12, 0,
-  60, 0, 0, 0, 11, 29, 28, 90, 42, 8,
-  49, 129, 4, 0, 0, 1, 4, 23, 0, 0,
-  30, 66, 51, 23, 16, 39, 2, 0, 0, 0,
-  0, 0, 0, 44, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 91, 0, 0, 56, 0, 0,
-  0, 0, 0, 21, 6, 68, 0, 0, 3, 66,
-  22, 26, 0, 44, 1, 12, 25, 0, 0, 0,
-  0, 0, 35, 19, 0, 0, 0, 0, 0, 41,
-  0, 0, 0, 9, 0, 13, 0, 4, 17, 0,
-  0, 0, 11, 90, 12, 0, 37, 0, 34, 0,
-  44, 0, 0, 20, 0, 0, 71, 0, 0, 58,
-  0, 66, 0, 22, 34, 0, 4, 12, 0, 0,
-  14, 0, 0, 0, 11, 67, 48, 0, 47, 25,
-  46, 0, 0, 0, 0, 0, 2, 0, 0, 5,
-  16, 47, 0, 0, 0, 1, 0, 93, 0, 9,
-  0, 23, 27, 12, 0, 4, 70, 6, 57, 62,
-  45, 37, 28, 1, 0, 0, 18, 8, 3, 27,
-  0, 16, 49, 0, 0, 5, 31, 0, 1, 0,
-  0, 6, 0, 41, 0, 0, 0, 25, 35, 4,
-  0, 0, 0, 52, 24, 0, 16, 5, 179, 11,
-  21, 0, 23, 0, 0, 0, 0, 11, 0, 43,
-  0, 24, 1, 8, 2, 65, 31, 0, 0, 0,
-  0, 37, 49, 0, 7, 0, 6, 0, 40, 14,
-  28, 28, 0, 0, 0, 18, 44, 18, 0, 7,
-  0, 39, 35, 0, 13, 18, 0, 0, 20, 0,
-  17, 2, 0, 51, 0, 0, 32, 30, 78, 35,
-  0, 0, 40, 0, 0, 22, 0, 0, 33, 23,
-  14, 18, 8, 0, 15, 74, 44, 16, 21, 36,
-  0, 12, 0, 0, 6, 34, 56, 40, 46, 34,
-  33, 8, 0, 0, 18, 0, 14, 30, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 39, 14, 0, 0, 0,
-  63, 31, 0, 36, 15, 0, 0, 12, 10, 93,
-  23, 78, 37, 39, 52, 0, 44, 62, 9, 23,
-  34, 48, 251, 53, 0, 0, 103, 0, 11, 0,
-  0, 19, 12, 43, 34, 0, 10, 7, 84, 61,
-  0, 22, 0, 69, 0, 28, 41, 0, 20, 0,
-  7, 14, 0, 3, 6, 7, 15, 0, 0, 16,
-  25, 16, 0, 28, 0, 14, 83, 9, 21, 62,
-  7, 4, 7, 0, 53, 0, 16, 0, 0, 1,
-  0, 4, 66, 24, 50, 9, 0, 0, 69, 27,
-  15, 2, 14, 33, 3, 0, 1, 18, 73, 0,
-  43, 0, 0, 6, 26, 16, 10, 44, 0, 0,
-  22, 18, 0, 41, 77, 0, 0, 0, 0, 0,
-  27, 20, 27, 77, 56, 1, 0, 0, 53, 33,
-  0, 26, 0, 19, 15, 40, 3, 80, 27, 70,
-  9, 40, 13, 19, 51, 56, 1, 0, 62, 39,
-  168, 33, 0, 2, 112, 0, 35, 0, 0, 8,
-  0, 15, 15, 0, 16, 4, 70, 57, 0, 21,
-  0, 58, 0, 81, 74, 0, 31, 0, 4, 0,
-  0, 0, 31, 0, 5, 36, 0, 9, 25, 0,
-  0, 65, 0, 19, 22, 10, 17, 20, 19, 22,
-  19, 0, 39, 0, 23, 18, 0, 9, 5, 21,
-  68, 17, 39, 0, 0, 0, 34, 0, 67, 16,
-  7, 35, 9, 16, 42, 18, 111, 0, 19, 7,
-  30, 4, 45, 33, 26, 6, 0, 0, 14, 0,
-  1, 30, 86, 0, 9, 0, 3, 0, 26, 19,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 12, 21,
-  64, 6, 0, 0, 17, 8, 0, 10, 24, 0,
-  0, 65, 0, 74, 92, 76, 35, 40, 22, 3,
-  39, 33, 0, 0, 31, 58, 156, 6, 15, 0,
-  58, 0, 0, 0, 0, 18, 0, 18, 5, 27,
-  0, 0, 53, 31, 0, 18, 0, 0, 0, 47,
-  40, 0, 10, 0, 0, 9, 0, 6, 28, 0,
-  0, 0, 0, 7, 44, 0, 48, 45, 0, 16,
-  17, 16, 28, 6, 22, 3, 0, 16, 38, 0,
-  14, 0, 0, 13, 0, 23, 45, 25, 8, 25,
-  0, 0, 67, 0, 51, 0, 0, 39, 3, 0,
-  27, 11, 67, 0, 18, 0, 0, 0, 20, 21,
-  9, 43, 3, 0, 12, 0, 0, 0, 64, 0,
-  5, 0, 0, 0, 55, 0, 56, 59, 50, 27,
-  4, 0, 2, 0, 0, 0, 8, 0, 48, 60,
-  4, 28, 76, 49, 0, 0, 0, 6, 1, 61,
-  24, 0, 35, 40, 0, 0, 13, 0, 67, 0,
-  0, 0, 0, 0, 0, 1, 0, 66, 2, 0,
-  30, 28, 26, 42, 0, 12, 0, 69, 96, 0,
-  23, 0, 0, 0, 0, 0, 51, 0, 0, 65,
-  0, 8, 82, 0, 40, 45, 0, 20, 0, 33,
-  32, 0, 14, 3, 0, 16, 42, 0, 37, 0,
-  0, 30, 0, 27, 36, 9, 13, 0, 0, 22,
-  2, 0, 70, 5, 0, 64, 0, 23, 40, 0,
-  76, 0, 6, 0, 58, 8, 17, 40, 5, 0,
-  26, 0, 1, 0, 0, 0, 39, 0, 71, 0,
-  10, 9, 14, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 47, 23, 86, 28, 0, 0, 29, 6,
-  18, 0, 12, 0, 0, 94, 0, 55, 94, 25,
-  14, 29, 7, 39, 13, 18, 25, 0, 29, 32,
-  164, 9, 5, 45, 79, 0, 0, 0, 0, 37,
-  0, 0, 0, 4, 0, 10, 7, 71, 53, 0,
-  0, 0, 0, 40, 22, 15, 17, 0, 13, 0,
-  0, 3, 39, 29, 0, 0, 0, 0, 72, 0,
-  119, 51, 0, 0, 21, 0, 24, 0, 65, 11,
-  0, 23, 14, 0, 42, 0, 0, 26, 0, 0,
-  59, 5, 0, 16, 0, 5, 15, 0, 38, 1,
-  14, 93, 25, 0, 14, 51, 54, 47, 12, 0,
-  25, 0, 4, 10, 0, 41, 10, 0, 18, 0,
-  17, 0, 59, 0, 0, 0, 0, 24, 48, 21,
-  43, 69, 0, 8, 5, 11, 0, 0, 0, 0,
-  0, 0, 16, 73, 0, 0, 82, 18, 0, 0,
-  0, 41, 0, 50, 15, 0, 5, 16, 0, 0,
-  0, 19, 83, 23, 0, 0, 0, 9, 0, 0,
-  0, 6, 0, 0, 9, 74, 35, 102, 0, 0,
-  0, 29, 56, 0, 22, 0, 18, 0, 0, 0,
-  78, 24, 0, 51, 0, 0, 97, 0, 107, 49,
-  0, 0, 4, 13, 45, 0, 27, 0, 0, 5,
-  25, 0, 35, 12, 0, 12, 0, 6, 0, 6,
-  0, 26, 0, 19, 1, 0, 34, 0, 12, 95,
-  20, 81, 35, 21, 44, 44, 10, 0, 51, 0,
-  0, 63, 0, 7, 0, 0, 0, 0, 11, 0,
-  22, 0, 33, 0, 0, 27, 27, 0, 0, 39,
-  14, 0, 0, 0, 63, 31, 0, 36, 15, 0,
-  0, 12, 10, 93, 23, 78, 37, 39, 52, 0,
-  44, 62, 9, 23, 34, 48, 251, 53, 0, 0,
-  103, 0, 11, 0, 0, 19, 12, 43, 34, 0,
-  10, 7, 84, 61, 0, 22, 0, 69, 0, 28,
-  41, 0, 20, 0, 7, 14, 0, 3, 6, 7,
-  15, 0, 0, 16, 25, 16, 0, 28, 0, 14,
-  83, 9, 21, 62, 7, 4, 7, 0, 53, 0,
-  16, 0, 0, 1, 0, 4, 66, 24, 50, 9,
-  0, 0, 69, 27, 15, 2, 14, 33, 3, 0,
-  1, 18, 73, 0, 43, 0, 0, 6, 26, 16,
-  10, 44, 0, 0, 22, 18, 0, 41, 77, 0,
-  0, 0, 0, 0, 27, 20, 27, 77, 56, 1,
-  0, 0, 53, 33, 0, 26, 0, 19, 15, 40,
-  3, 80, 27, 70, 9, 40, 13, 19, 51, 56,
-  1, 0, 62, 39, 168, 33, 0, 2, 112, 0,
-  35, 0, 0, 8, 0, 15, 15, 0, 16, 4,
-  70, 57, 0, 21, 0, 58, 0, 81, 74, 0,
-  31, 0, 4, 0, 0, 0, 31, 0, 5, 36,
-  0, 9, 25, 0, 0, 65, 0, 19, 22, 10,
-  17, 20, 19, 22, 19, 0, 39, 0, 23, 18,
-  0, 9, 5, 21, 68, 17, 39, 0, 0, 0,
-  34, 0, 67, 16, 7, 35, 9, 16, 42, 18,
-  111, 0, 19, 7, 30, 4, 45, 33, 26, 6,
-  0, 0, 14, 0, 1, 30, 86, 0, 9, 0,
-  3, 0, 26, 19, 51, 73, 59, 31, 0, 25,
-  25, 27, 1, 0, 0, 49, 62, 54, 0, 17,
-  9, 31, 5, 0, 0, 97, 24, 47, 40, 0,
-  67, 36, 173, 0, 0, 93, 100, 0, 16, 5,
-  0, 0, 0, 8, 0, 0, 58, 12, 35, 124,
-  53, 23, 0, 49, 0, 76, 26, 0, 69, 0,
-  16, 0, 0, 0, 74, 49, 11, 40, 2, 17,
-  33, 10, 4, 69, 21, 19, 13, 0, 5, 0,
-  39, 35, 1, 0, 24, 0, 46, 72, 0, 11,
-  18, 1, 41, 28, 0, 0, 0, 0, 0, 0,
-  56, 0, 0, 45, 33, 55, 30, 39, 114, 0,
-  28, 15, 40, 0, 15, 24, 15, 0, 0, 0,
-  36, 0, 25, 27, 59, 0, 0, 0, 16, 0,
-  11, 50, 12, 21, 64, 6, 0, 0, 17, 8,
-  0, 10, 24, 0, 0, 65, 0, 74, 92, 76,
-  35, 40, 22, 3, 39, 33, 0, 0, 31, 58,
-  156, 6, 15, 0, 58, 0, 0, 0, 0, 18,
-  0, 18, 5, 27, 0, 0, 53, 31, 0, 18,
-  0, 0, 0, 47, 40, 0, 10, 0, 0, 9,
-  0, 6, 28, 0, 0, 0, 0, 7, 44, 0,
-  48, 45, 0, 16, 17, 16, 28, 6, 22, 3,
-  0, 16, 38, 0, 14, 0, 0, 13, 0, 23,
-  45, 25, 8, 25, 0, 0, 67, 0, 51, 0,
-  0, 39, 3, 0, 27, 11, 67, 0, 18, 0,
-  0, 0, 20, 21, 9, 43, 3, 0, 12, 0,
-  0, 0, 64, 0, 5, 0, 0, 0, 55, 0,
-  56, 59, 50, 27, 4, 0, 2, 0, 0, 0,
-  8, 0, 48, 60, 4, 28, 76, 49, 0, 0,
-  0, 6, 1, 61, 24, 0, 35, 40, 0, 0,
-  13, 0, 67, 0, 0, 0, 0, 0, 0, 1,
-  0, 66, 2, 0, 30, 28, 26, 42, 0, 12,
-  0, 69, 96, 0, 23, 0, 0, 0, 0, 0,
-  51, 0, 0, 65, 0, 8, 82, 0, 40, 45,
-  0, 20, 0, 33, 32, 0, 14, 3, 0, 16,
-  42, 0, 37, 0, 0, 30, 0, 27, 36, 9,
-  13, 0, 0, 22, 2, 0, 70, 5, 0, 64,
-  0, 23, 40, 0, 76, 0, 6, 0, 58, 8,
-  17, 40, 5, 0, 26, 0, 1, 0, 0, 0,
-  39, 0, 71, 0, 10, 9, 14, 0, 2, 55,
-  59, 38, 4, 35, 16, 13, 17, 0, 0, 16,
-  84, 0, 0, 22, 51, 18, 0, 0, 0, 56,
-  0, 33, 67, 0, 5, 30, 0, 0, 0, 43,
-  70, 0, 18, 0, 0, 0, 0, 41, 0, 35,
-  57, 2, 29, 80, 44, 19, 0, 21, 0, 34,
-  36, 10, 35, 0, 10, 0, 0, 0, 30, 26,
-  0, 32, 0, 0, 35, 1, 27, 0, 0, 17,
-  9, 19, 26, 0, 10, 16, 0, 22, 23, 0,
-  61, 69, 0, 5, 0, 0, 0, 42, 5, 0,
-  0, 31, 0, 24, 35, 0, 0, 65, 2, 0,
-  10, 12, 63, 0, 37, 0, 27, 0, 0, 14,
-  0, 0, 0, 0, 0, 0, 0, 0, 4, 0,
-  41, 0, 35, 0, 8, 0, 47, 23, 86, 28,
-  0, 0, 29, 6, 18, 0, 12, 0, 0, 94,
-  0, 55, 94, 25, 14, 29, 7, 39, 13, 18,
-  25, 0, 29, 32, 164, 9, 5, 45, 79, 0,
-  0, 0, 0, 37, 0, 0, 0, 4, 0, 10,
-  7, 71, 53, 0, 0, 0, 0, 40, 22, 15,
-  17, 0, 13, 0, 0, 3, 39, 29, 0, 0,
-  0, 0, 72, 0, 119, 51, 0, 0, 21, 0,
-  24, 0, 65, 11, 0, 23, 14, 0, 42, 0,
-  0, 26, 0, 0, 59, 5, 0, 16, 0, 5,
-  15, 0, 38, 1, 14, 93, 25, 0, 14, 51,
-  54, 47, 12, 0, 25, 0, 4, 10, 0, 41,
-  10, 0, 18, 0, 17, 0, 59, 0, 0, 0,
-  0, 24, 48, 21, 43, 69, 0, 8, 5, 11,
-  0, 0, 0, 0, 0, 0, 16, 73, 0, 0,
-  82, 18, 0, 0, 0, 41, 0, 50, 15, 0,
-  5, 16, 0, 0, 0, 19, 83, 23, 0, 0,
-  0, 9, 0, 0, 0, 6, 0, 0, 9, 74,
-  35, 102, 0, 0, 0, 29, 56, 0, 22, 0,
-  18, 0, 0, 0, 78, 24, 0, 51, 0, 0,
-  97, 0, 107, 49, 0, 0, 4, 13, 45, 0,
-  27, 0, 0, 5, 25, 0, 35, 12, 0, 12,
-  0, 6, 0, 6, 0, 26, 0, 19, 1, 0,
-  34, 0, 12, 95, 20, 81, 35, 21, 44, 44,
-  10, 0, 51, 0, 0, 63, 0, 7, 0, 0,
-  0, 0, 11, 0, 22, 0, 33, 0, 0, 27,
-  27, 0, 0, 39, 39, 29, 0, 48, 7, 15,
-  23, 0, 0, 11, 81, 0, 0, 23, 58, 7,
-  0, 0, 0, 63, 0, 21, 41, 0, 0, 12,
-  0, 0, 0, 32, 67, 3, 1, 0, 0, 13,
-  0, 47, 0, 18, 41, 13, 22, 69, 25, 53,
-  0, 12, 0, 37, 21, 7, 22, 0, 22, 0,
-  0, 0, 16, 31, 0, 29, 0, 0, 7, 0,
-  37, 0, 18, 0, 9, 21, 4, 0, 5, 11,
-  0, 39, 27, 0, 62, 62, 0, 0, 0, 0,
-  0, 18, 1, 0, 0, 19, 0, 19, 32, 0,
-  0, 78, 11, 0, 0, 10, 15, 0, 33, 0,
-  0, 0, 0, 8, 0, 0, 0, 0, 7, 0,
-  0, 0, 0, 0, 38, 0, 39, 0, 9, 0,
-  27, 77, 56, 1, 0, 0, 53, 33, 0, 26,
-  0, 19, 15, 40, 3, 80, 27, 70, 9, 40,
-  13, 19, 51, 56, 1, 0, 62, 39, 168, 33,
-  0, 2, 112, 0, 35, 0, 0, 8, 0, 15,
-  15, 0, 16, 4, 70, 57, 0, 21, 0, 58,
-  0, 81, 74, 0, 31, 0, 4, 0, 0, 0,
-  31, 0, 5, 36, 0, 9, 25, 0, 0, 65,
-  0, 19, 22, 10, 17, 20, 19, 22, 19, 0,
-  39, 0, 23, 18, 0, 9, 5, 21, 68, 17,
-  39, 0, 0, 0, 34, 0, 67, 16, 7, 35,
-  9, 16, 42, 18, 111, 0, 19, 7, 30, 4,
-  45, 33, 26, 6, 0, 0, 14, 0, 1, 30,
-  86, 0, 9, 0, 3, 0, 26, 19, 51, 73,
-  59, 31, 0, 25, 25, 27, 1, 0, 0, 49,
-  62, 54, 0, 17, 9, 31, 5, 0, 0, 97,
-  24, 47, 40, 0, 67, 36, 173, 0, 0, 93,
-  100, 0, 16, 5, 0, 0, 0, 8, 0, 0,
-  58, 12, 35, 124, 53, 23, 0, 49, 0, 76,
-  26, 0, 69, 0, 16, 0, 0, 0, 74, 49,
-  11, 40, 2, 17, 33, 10, 4, 69, 21, 19,
-  13, 0, 5, 0, 39, 35, 1, 0, 24, 0,
-  46, 72, 0, 11, 18, 1, 41, 28, 0, 0,
-  0, 0, 0, 0, 56, 0, 0, 45, 33, 55,
-  30, 39, 114, 0, 28, 15, 40, 0, 15, 24,
-  15, 0, 0, 0, 36, 0, 25, 27, 59, 0,
-  0, 0, 16, 0, 11, 50, 1, 0, 0, 19,
-  11, 92, 28, 0, 0, 0, 0, 57, 41, 55,
-  0, 0, 0, 21, 17, 3, 0, 71, 14, 58,
-  40, 0, 38, 15, 173, 20, 0, 66, 63, 35,
-  0, 0, 0, 0, 0, 44, 0, 0, 10, 45,
-  6, 158, 67, 62, 0, 26, 0, 54, 50, 0,
-  21, 0, 34, 0, 34, 0, 70, 66, 0, 18,
-  13, 4, 36, 35, 62, 39, 52, 9, 43, 0,
-  28, 0, 37, 0, 0, 0, 49, 0, 22, 62,
-  0, 0, 39, 14, 21, 0, 0, 25, 16, 0,
-  24, 37, 0, 0, 11, 49, 15, 31, 12, 45,
-  82, 9, 31, 0, 0, 16, 0, 14, 0, 7,
-  0, 44, 106, 21, 47, 22, 46, 0, 0, 0,
-  16, 0, 13, 16, 56, 59, 50, 27, 4, 0,
-  2, 0, 0, 0, 8, 0, 48, 60, 4, 28,
-  76, 49, 0, 0, 0, 6, 1, 61, 24, 0,
-  35, 40, 0, 0, 13, 0, 67, 0, 0, 0,
-  0, 0, 0, 1, 0, 66, 2, 0, 30, 28,
-  26, 42, 0, 12, 0, 69, 96, 0, 23, 0,
-  0, 0, 0, 0, 51, 0, 0, 65, 0, 8,
-  82, 0, 40, 45, 0, 20, 0, 33, 32, 0,
-  14, 3, 0, 16, 42, 0, 37, 0, 0, 30,
-  0, 27, 36, 9, 13, 0, 0, 22, 2, 0,
-  70, 5, 0, 64, 0, 23, 40, 0, 76, 0,
-  6, 0, 58, 8, 17, 40, 5, 0, 26, 0,
-  1, 0, 0, 0, 39, 0, 71, 0, 10, 9,
-  14, 0, 2, 55, 59, 38, 4, 35, 16, 13,
-  17, 0, 0, 16, 84, 0, 0, 22, 51, 18,
-  0, 0, 0, 56, 0, 33, 67, 0, 5, 30,
-  0, 0, 0, 43, 70, 0, 18, 0, 0, 0,
-  0, 41, 0, 35, 57, 2, 29, 80, 44, 19,
-  0, 21, 0, 34, 36, 10, 35, 0, 10, 0,
-  0, 0, 30, 26, 0, 32, 0, 0, 35, 1,
-  27, 0, 0, 17, 9, 19, 26, 0, 10, 16,
-  0, 22, 23, 0, 61, 69, 0, 5, 0, 0,
-  0, 42, 5, 0, 0, 31, 0, 24, 35, 0,
-  0, 65, 2, 0, 10, 12, 63, 0, 37, 0,
-  27, 0, 0, 14, 0, 0, 0, 0, 0, 0,
-  0, 0, 4, 0, 41, 0, 35, 0, 8, 0,
-  0, 0, 0, 18, 14, 124, 8, 0, 7, 0,
-  0, 29, 52, 11, 0, 6, 15, 0, 0, 0,
-  0, 77, 2, 24, 40, 0, 0, 9, 0, 14,
-  0, 31, 15, 32, 0, 0, 0, 21, 0, 76,
-  0, 37, 0, 65, 12, 85, 61, 31, 0, 0,
-  0, 31, 31, 4, 2, 0, 40, 0, 18, 0,
-  23, 69, 0, 16, 12, 9, 0, 29, 58, 0,
-  39, 20, 11, 0, 25, 21, 19, 0, 0, 29,
-  42, 0, 16, 44, 15, 0, 11, 0, 0, 8,
-  0, 6, 0, 0, 4, 72, 0, 0, 0, 72,
-  0, 0, 4, 12, 57, 0, 27, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 77, 0, 47, 0,
-  6, 3, 0, 0, 55, 0, 22, 0, 43, 69,
-  0, 8, 5, 11, 0, 0, 0, 0, 0, 0,
-  16, 73, 0, 0, 82, 18, 0, 0, 0, 41,
-  0, 50, 15, 0, 5, 16, 0, 0, 0, 19,
-  83, 23, 0, 0, 0, 9, 0, 0, 0, 6,
-  0, 0, 9, 74, 35, 102, 0, 0, 0, 29,
-  56, 0, 22, 0, 18, 0, 0, 0, 78, 24,
-  0, 51, 0, 0, 97, 0, 107, 49, 0, 0,
-  4, 13, 45, 0, 27, 0, 0, 5, 25, 0,
-  35, 12, 0, 12, 0, 6, 0, 6, 0, 26,
-  0, 19, 1, 0, 34, 0, 12, 95, 20, 81,
-  35, 21, 44, 44, 10, 0, 51, 0, 0, 63,
-  0, 7, 0, 0, 0, 0, 11, 0, 22, 0,
-  33, 0, 0, 27, 27, 0, 0, 39, 39, 29,
-  0, 48, 7, 15, 23, 0, 0, 11, 81, 0,
-  0, 23, 58, 7, 0, 0, 0, 63, 0, 21,
-  41, 0, 0, 12, 0, 0, 0, 32, 67, 3,
-  1, 0, 0, 13, 0, 47, 0, 18, 41, 13,
-  22, 69, 25, 53, 0, 12, 0, 37, 21, 7,
-  22, 0, 22, 0, 0, 0, 16, 31, 0, 29,
-  0, 0, 7, 0, 37, 0, 18, 0, 9, 21,
-  4, 0, 5, 11, 0, 39, 27, 0, 62, 62,
-  0, 0, 0, 0, 0, 18, 1, 0, 0, 19,
-  0, 19, 32, 0, 0, 78, 11, 0, 0, 10,
-  15, 0, 33, 0, 0, 0, 0, 8, 0, 0,
-  0, 0, 7, 0, 0, 0, 0, 0, 38, 0,
-  39, 0, 9, 0, 0, 0, 0, 12, 0, 128,
-  4, 0, 24, 0, 0, 24, 44, 0, 0, 3,
-  15, 0, 0, 0, 17, 87, 14, 19, 11, 0,
-  0, 0, 0, 0, 0, 22, 19, 26, 0, 6,
-  0, 37, 0, 56, 0, 21, 0, 56, 0, 77,
-  54, 47, 0, 0, 0, 41, 15, 0, 2, 0,
-  67, 0, 29, 0, 3, 66, 0, 12, 54, 5,
-  0, 16, 73, 0, 77, 17, 14, 1, 0, 19,
-  20, 20, 0, 39, 27, 0, 45, 41, 10, 0,
-  5, 0, 0, 0, 0, 17, 0, 0, 0, 33,
-  0, 0, 7, 75, 14, 0, 0, 3, 5, 0,
-  19, 0, 0, 0, 0, 0, 0, 14, 0, 0,
-  93, 0, 37, 0, 0, 0, 0, 0, 36, 0,
-  0, 0, 51, 73, 59, 31, 0, 25, 25, 27,
-  1, 0, 0, 49, 62, 54, 0, 17, 9, 31,
-  5, 0, 0, 97, 24, 47, 40, 0, 67, 36,
-  173, 0, 0, 93, 100, 0, 16, 5, 0, 0,
-  0, 8, 0, 0, 58, 12, 35, 124, 53, 23,
-  0, 49, 0, 76, 26, 0, 69, 0, 16, 0,
-  0, 0, 74, 49, 11, 40, 2, 17, 33, 10,
-  4, 69, 21, 19, 13, 0, 5, 0, 39, 35,
-  1, 0, 24, 0, 46, 72, 0, 11, 18, 1,
-  41, 28, 0, 0, 0, 0, 0, 0, 56, 0,
-  0, 45, 33, 55, 30, 39, 114, 0, 28, 15,
-  40, 0, 15, 24, 15, 0, 0, 0, 36, 0,
-  25, 27, 59, 0, 0, 0, 16, 0, 11, 50,
-  1, 0, 0, 19, 11, 92, 28, 0, 0, 0,
-  0, 57, 41, 55, 0, 0, 0, 21, 17, 3,
-  0, 71, 14, 58, 40, 0, 38, 15, 173, 20,
-  0, 66, 63, 35, 0, 0, 0, 0, 0, 44,
-  0, 0, 10, 45, 6, 158, 67, 62, 0, 26,
-  0, 54, 50, 0, 21, 0, 34, 0, 34, 0,
-  70, 66, 0, 18, 13, 4, 36, 35, 62, 39,
-  52, 9, 43, 0, 28, 0, 37, 0, 0, 0,
-  49, 0, 22, 62, 0, 0, 39, 14, 21, 0,
-  0, 25, 16, 0, 24, 37, 0, 0, 11, 49,
-  15, 31, 12, 45, 82, 9, 31, 0, 0, 16,
-  0, 14, 0, 7, 0, 44, 106, 21, 47, 22,
-  46, 0, 0, 0, 16, 0, 13, 16, 0, 38,
-  0, 0, 45, 3, 47, 0, 0, 5, 2, 35,
-  43, 41, 0, 12, 6, 26, 23, 27, 41, 0,
-  0, 68, 18, 30, 36, 25, 149, 46, 0, 0,
-  61, 42, 0, 0, 0, 0, 0, 81, 0, 0,
-  0, 48, 15, 76, 31, 35, 0, 47, 0, 53,
-  104, 0, 0, 15, 21, 0, 0, 5, 36, 26,
-  0, 63, 0, 10, 50, 5, 36, 4, 6, 13,
-  12, 0, 42, 49, 0, 0, 30, 0, 84, 0,
-  8, 23, 8, 1, 28, 38, 67, 0, 15, 10,
-  39, 0, 22, 34, 0, 0, 46, 45, 0, 15,
-  23, 0, 43, 0, 19, 15, 9, 58, 9, 7,
-  0, 4, 0, 0, 41, 21, 33, 22, 54, 6,
-  20, 0, 41, 0, 6, 0, 2, 55, 59, 38,
-  4, 35, 16, 13, 17, 0, 0, 16, 84, 0,
-  0, 22, 51, 18, 0, 0, 0, 56, 0, 33,
-  67, 0, 5, 30, 0, 0, 0, 43, 70, 0,
-  18, 0, 0, 0, 0, 41, 0, 35, 57, 2,
-  29, 80, 44, 19, 0, 21, 0, 34, 36, 10,
-  35, 0, 10, 0, 0, 0, 30, 26, 0, 32,
-  0, 0, 35, 1, 27, 0, 0, 17, 9, 19,
-  26, 0, 10, 16, 0, 22, 23, 0, 61, 69,
-  0, 5, 0, 0, 0, 42, 5, 0, 0, 31,
-  0, 24, 35, 0, 0, 65, 2, 0, 10, 12,
-  63, 0, 37, 0, 27, 0, 0, 14, 0, 0,
-  0, 0, 0, 0, 0, 0, 4, 0, 41, 0,
-  35, 0, 8, 0, 0, 0, 0, 18, 14, 124,
-  8, 0, 7, 0, 0, 29, 52, 11, 0, 6,
-  15, 0, 0, 0, 0, 77, 2, 24, 40, 0,
-  0, 9, 0, 14, 0, 31, 15, 32, 0, 0,
-  0, 21, 0, 76, 0, 37, 0, 65, 12, 85,
-  61, 31, 0, 0, 0, 31, 31, 4, 2, 0,
-  40, 0, 18, 0, 23, 69, 0, 16, 12, 9,
-  0, 29, 58, 0, 39, 20, 11, 0, 25, 21,
-  19, 0, 0, 29, 42, 0, 16, 44, 15, 0,
-  11, 0, 0, 8, 0, 6, 0, 0, 4, 72,
-  0, 0, 0, 72, 0, 0, 4, 12, 57, 0,
-  27, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  77, 0, 47, 0, 6, 3, 0, 0, 55, 0,
-  22, 0, 0, 12, 0, 0, 34, 31, 37, 0,
-  16, 0, 1, 11, 52, 11, 10, 28, 23, 12,
-  0, 12, 51, 0, 0, 50, 24, 48, 0, 15,
-  0, 35, 0, 0, 38, 48, 0, 0, 0, 6,
-  0, 75, 0, 43, 0, 59, 29, 41, 15, 15,
-  0, 19, 0, 15, 107, 18, 0, 0, 17, 0,
-  0, 28, 25, 21, 0, 41, 0, 0, 45, 6,
-  26, 0, 0, 8, 0, 14, 33, 51, 4, 0,
-  0, 28, 84, 14, 0, 6, 19, 0, 12, 21,
-  18, 26, 0, 9, 9, 21, 0, 72, 0, 4,
-  31, 72, 0, 0, 2, 0, 39, 0, 26, 7,
-  9, 48, 0, 0, 0, 3, 0, 0, 39, 24,
-  41, 0, 37, 0, 84, 0, 64, 0, 13, 0,
-  0, 39, 39, 29, 0, 48, 7, 15, 23, 0,
-  0, 11, 81, 0, 0, 23, 58, 7, 0, 0,
-  0, 63, 0, 21, 41, 0, 0, 12, 0, 0,
-  0, 32, 67, 3, 1, 0, 0, 13, 0, 47,
-  0, 18, 41, 13, 22, 69, 25, 53, 0, 12,
-  0, 37, 21, 7, 22, 0, 22, 0, 0, 0,
-  16, 31, 0, 29, 0, 0, 7, 0, 37, 0,
-  18, 0, 9, 21, 4, 0, 5, 11, 0, 39,
-  27, 0, 62, 62, 0, 0, 0, 0, 0, 18,
-  1, 0, 0, 19, 0, 19, 32, 0, 0, 78,
-  11, 0, 0, 10, 15, 0, 33, 0, 0, 0,
-  0, 8, 0, 0, 0, 0, 7, 0, 0, 0,
-  0, 0, 38, 0, 39, 0, 9, 0, 0, 0,
-  0, 12, 0, 128, 4, 0, 24, 0, 0, 24,
-  44, 0, 0, 3, 15, 0, 0, 0, 17, 87,
-  14, 19, 11, 0, 0, 0, 0, 0, 0, 22,
-  19, 26, 0, 6, 0, 37, 0, 56, 0, 21,
-  0, 56, 0, 77, 54, 47, 0, 0, 0, 41,
-  15, 0, 2, 0, 67, 0, 29, 0, 3, 66,
-  0, 12, 54, 5, 0, 16, 73, 0, 77, 17,
-  14, 1, 0, 19, 20, 20, 0, 39, 27, 0,
-  45, 41, 10, 0, 5, 0, 0, 0, 0, 17,
-  0, 0, 0, 33, 0, 0, 7, 75, 14, 0,
-  0, 3, 5, 0, 19, 0, 0, 0, 0, 0,
-  0, 14, 0, 0, 93, 0, 37, 0, 0, 0,
-  0, 0, 36, 0, 0, 0, 0, 0, 0, 0,
-  0, 48, 47, 0, 22, 0, 0, 0, 38, 0,
-  10, 49, 31, 17, 0, 15, 62, 0, 0, 40,
-  0, 20, 12, 0, 0, 26, 0, 0, 64, 55,
-  8, 0, 0, 16, 0, 41, 0, 28, 0, 56,
-  0, 45, 21, 45, 0, 12, 2, 10, 93, 9,
-  0, 9, 48, 0, 0, 35, 16, 4, 0, 1,
-  0, 0, 17, 7, 42, 0, 2, 3, 0, 21,
-  13, 42, 3, 0, 0, 26, 69, 0, 18, 2,
-  18, 0, 12, 0, 9, 8, 0, 31, 0, 8,
-  5, 29, 0, 0, 36, 54, 18, 0, 0, 0,
-  1, 0, 24, 4, 0, 31, 0, 1, 0, 19,
-  0, 0, 51, 3, 32, 0, 21, 0, 83, 0,
-  35, 0, 4, 0, 1, 0, 0, 19, 11, 92,
-  28, 0, 0, 0, 0, 57, 41, 55, 0, 0,
-  0, 21, 17, 3, 0, 71, 14, 58, 40, 0,
-  38, 15, 173, 20, 0, 66, 63, 35, 0, 0,
-  0, 0, 0, 44, 0, 0, 10, 45, 6, 158,
-  67, 62, 0, 26, 0, 54, 50, 0, 21, 0,
-  34, 0, 34, 0, 70, 66, 0, 18, 13, 4,
-  36, 35, 62, 39, 52, 9, 43, 0, 28, 0,
-  37, 0, 0, 0, 49, 0, 22, 62, 0, 0,
-  39, 14, 21, 0, 0, 25, 16, 0, 24, 37,
-  0, 0, 11, 49, 15, 31, 12, 45, 82, 9,
-  31, 0, 0, 16, 0, 14, 0, 7, 0, 44,
-  106, 21, 47, 22, 46, 0, 0, 0, 16, 0,
-  13, 16, 0, 38, 0, 0, 45, 3, 47, 0,
-  0, 5, 2, 35, 43, 41, 0, 12, 6, 26,
-  23, 27, 41, 0, 0, 68, 18, 30, 36, 25,
-  149, 46, 0, 0, 61, 42, 0, 0, 0, 0,
-  0, 81, 0, 0, 0, 48, 15, 76, 31, 35,
-  0, 47, 0, 53, 104, 0, 0, 15, 21, 0,
-  0, 5, 36, 26, 0, 63, 0, 10, 50, 5,
-  36, 4, 6, 13, 12, 0, 42, 49, 0, 0,
-  30, 0, 84, 0, 8, 23, 8, 1, 28, 38,
-  67, 0, 15, 10, 39, 0, 22, 34, 0, 0,
-  46, 45, 0, 15, 23, 0, 43, 0, 19, 15,
-  9, 58, 9, 7, 0, 4, 0, 0, 41, 21,
-  33, 22, 54, 6, 20, 0, 41, 0, 6, 0,
-  0, 46, 0, 5, 8, 0, 87, 3, 13, 14,
-  0, 39, 38, 29, 17, 42, 21, 66, 26, 57,
-  83, 0, 35, 35, 10, 13, 59, 37, 156, 43,
-  0, 0, 97, 0, 28, 0, 0, 0, 0, 60,
-  0, 0, 0, 58, 6, 89, 17, 14, 0, 43,
-  0, 39, 81, 11, 0, 0, 23, 0, 0, 26,
-  0, 12, 14, 12, 0, 0, 12, 25, 19, 1,
-  23, 0, 31, 0, 56, 15, 12, 6, 36, 0,
-  63, 0, 17, 12, 2, 0, 24, 1, 58, 22,
-  24, 0, 0, 0, 11, 31, 0, 0, 72, 22,
-  0, 0, 23, 0, 40, 0, 15, 32, 13, 36,
-  18, 8, 0, 1, 0, 0, 17, 8, 16, 23,
-  55, 3, 28, 0, 23, 0, 16, 0, 0, 0,
-  0, 18, 14, 124, 8, 0, 7, 0, 0, 29,
-  52, 11, 0, 6, 15, 0, 0, 0, 0, 77,
-  2, 24, 40, 0, 0, 9, 0, 14, 0, 31,
-  15, 32, 0, 0, 0, 21, 0, 76, 0, 37,
-  0, 65, 12, 85, 61, 31, 0, 0, 0, 31,
-  31, 4, 2, 0, 40, 0, 18, 0, 23, 69,
-  0, 16, 12, 9, 0, 29, 58, 0, 39, 20,
-  11, 0, 25, 21, 19, 0, 0, 29, 42, 0,
-  16, 44, 15, 0, 11, 0, 0, 8, 0, 6,
-  0, 0, 4, 72, 0, 0, 0, 72, 0, 0,
-  4, 12, 57, 0, 27, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 77, 0, 47, 0, 6, 3,
-  0, 0, 55, 0, 22, 0, 0, 12, 0, 0,
-  34, 31, 37, 0, 16, 0, 1, 11, 52, 11,
-  10, 28, 23, 12, 0, 12, 51, 0, 0, 50,
-  24, 48, 0, 15, 0, 35, 0, 0, 38, 48,
-  0, 0, 0, 6, 0, 75, 0, 43, 0, 59,
-  29, 41, 15, 15, 0, 19, 0, 15, 107, 18,
-  0, 0, 17, 0, 0, 28, 25, 21, 0, 41,
-  0, 0, 45, 6, 26, 0, 0, 8, 0, 14,
-  33, 51, 4, 0, 0, 28, 84, 14, 0, 6,
-  19, 0, 12, 21, 18, 26, 0, 9, 9, 21,
-  0, 72, 0, 4, 31, 72, 0, 0, 2, 0,
-  39, 0, 26, 7, 9, 48, 0, 0, 0, 3,
-  0, 0, 39, 24, 41, 0, 37, 0, 84, 0,
-  64, 0, 13, 0, 0, 32, 0, 0, 20, 0,
-  56, 0, 35, 0, 0, 29, 28, 20, 52, 24,
-  39, 50, 3, 36, 95, 0, 10, 21, 21, 25,
-  9, 34, 0, 29, 0, 0, 63, 0, 10, 0,
-  0, 0, 0, 48, 0, 3, 0, 63, 16, 61,
-  5, 1, 0, 6, 0, 3, 79, 33, 0, 0,
-  18, 0, 0, 7, 0, 7, 0, 0, 0, 0,
-  32, 20, 20, 0, 0, 0, 0, 0, 62, 0,
-  13, 2, 0, 6, 67, 26, 0, 0, 6, 0,
-  7, 0, 11, 49, 18, 0, 0, 4, 0, 55,
-  0, 6, 64, 36, 0, 0, 3, 0, 34, 0,
-  22, 9, 31, 35, 0, 0, 0, 0, 0, 0,
-  14, 2, 12, 0, 45, 0, 77, 0, 41, 0,
-  26, 0, 0, 0, 0, 12, 0, 128, 4, 0,
-  24, 0, 0, 24, 44, 0, 0, 3, 15, 0,
-  0, 0, 17, 87, 14, 19, 11, 0, 0, 0,
-  0, 0, 0, 22, 19, 26, 0, 6, 0, 37,
-  0, 56, 0, 21, 0, 56, 0, 77, 54, 47,
-  0, 0, 0, 41, 15, 0, 2, 0, 67, 0,
-  29, 0, 3, 66, 0, 12, 54, 5, 0, 16,
-  73, 0, 77, 17, 14, 1, 0, 19, 20, 20,
-  0, 39, 27, 0, 45, 41, 10, 0, 5, 0,
-  0, 0, 0, 17, 0, 0, 0, 33, 0, 0,
-  7, 75, 14, 0, 0, 3, 5, 0, 19, 0,
-  0, 0, 0, 0, 0, 14, 0, 0, 93, 0,
-  37, 0, 0, 0, 0, 0, 36, 0, 0, 0,
-  0, 0, 0, 0, 0, 48, 47, 0, 22, 0,
-  0, 0, 38, 0, 10, 49, 31, 17, 0, 15,
-  62, 0, 0, 40, 0, 20, 12, 0, 0, 26,
-  0, 0, 64, 55, 8, 0, 0, 16, 0, 41,
-  0, 28, 0, 56, 0, 45, 21, 45, 0, 12,
-  2, 10, 93, 9, 0, 9, 48, 0, 0, 35,
-  16, 4, 0, 1, 0, 0, 17, 7, 42, 0,
-  2, 3, 0, 21, 13, 42, 3, 0, 0, 26,
-  69, 0, 18, 2, 18, 0, 12, 0, 9, 8,
-  0, 31, 0, 8, 5, 29, 0, 0, 36, 54,
-  18, 0, 0, 0, 1, 0, 24, 4, 0, 31,
-  0, 1, 0, 19, 0, 0, 51, 3, 32, 0,
-  21, 0, 83, 0, 35, 0, 4, 0, 0, 9,
-  0, 0, 15, 0, 57, 0, 37, 0, 0, 0,
-  30, 12, 51, 40, 45, 47, 0, 28, 101, 0,
-  0, 27, 0, 9, 25, 8, 0, 23, 0, 0,
-  52, 4, 22, 0, 0, 12, 0, 35, 0, 7,
-  0, 70, 5, 54, 4, 16, 0, 0, 13, 8,
-  68, 27, 0, 0, 28, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 23, 1, 27, 0, 0, 0,
-  0, 10, 48, 0, 7, 9, 0, 11, 57, 13,
-  9, 0, 13, 0, 0, 0, 22, 29, 9, 0,
-  0, 15, 0, 34, 0, 0, 59, 37, 0, 0,
-  0, 0, 12, 0, 17, 14, 11, 27, 0, 0,
-  0, 5, 0, 0, 24, 0, 14, 0, 27, 0,
-  77, 0, 21, 0, 13, 0, 0, 38, 0, 0,
-  45, 3, 47, 0, 0, 5, 2, 35, 43, 41,
-  0, 12, 6, 26, 23, 27, 41, 0, 0, 68,
-  18, 30, 36, 25, 149, 46, 0, 0, 61, 42,
-  0, 0, 0, 0, 0, 81, 0, 0, 0, 48,
-  15, 76, 31, 35, 0, 47, 0, 53, 104, 0,
-  0, 15, 21, 0, 0, 5, 36, 26, 0, 63,
-  0, 10, 50, 5, 36, 4, 6, 13, 12, 0,
-  42, 49, 0, 0, 30, 0, 84, 0, 8, 23,
-  8, 1, 28, 38, 67, 0, 15, 10, 39, 0,
-  22, 34, 0, 0, 46, 45, 0, 15, 23, 0,
-  43, 0, 19, 15, 9, 58, 9, 7, 0, 4,
-  0, 0, 41, 21, 33, 22, 54, 6, 20, 0,
-  41, 0, 6, 0, 0, 46, 0, 5, 8, 0,
-  87, 3, 13, 14, 0, 39, 38, 29, 17, 42,
-  21, 66, 26, 57, 83, 0, 35, 35, 10, 13,
-  59, 37, 156, 43, 0, 0, 97, 0, 28, 0,
-  0, 0, 0, 60, 0, 0, 0, 58, 6, 89,
-  17, 14, 0, 43, 0, 39, 81, 11, 0, 0,
-  23, 0, 0, 26, 0, 12, 14, 12, 0, 0,
-  12, 25, 19, 1, 23, 0, 31, 0, 56, 15,
-  12, 6, 36, 0, 63, 0, 17, 12, 2, 0,
-  24, 1, 58, 22, 24, 0, 0, 0, 11, 31,
-  0, 0, 72, 22, 0, 0, 23, 0, 40, 0,
-  15, 32, 13, 36, 18, 8, 0, 1, 0, 0,
-  17, 8, 16, 23, 55, 3, 28, 0, 23, 0,
-  16, 0, 0, 26, 0, 19, 10, 0, 77, 11,
-  23, 31, 0, 35, 23, 57, 9, 52, 22, 74,
-  37, 27, 102, 0, 0, 31, 15, 13, 55, 46,
-  154, 59, 0, 4, 97, 0, 27, 0, 0, 0,
-  0, 55, 0, 0, 0, 52, 12, 66, 15, 9,
-  0, 41, 0, 76, 57, 46, 4, 14, 7, 0,
-  0, 16, 0, 0, 24, 8, 0, 8, 10, 17,
-  12, 30, 0, 0, 27, 0, 37, 13, 12, 0,
-  23, 0, 76, 0, 17, 2, 0, 0, 21, 18,
-  71, 15, 30, 0, 0, 0, 29, 12, 20, 0,
-  83, 41, 0, 0, 20, 0, 63, 0, 2, 35,
-  27, 25, 17, 5, 25, 0, 6, 0, 30, 0,
-  13, 13, 58, 0, 47, 0, 29, 0, 20, 0,
-  0, 12, 0, 0, 34, 31, 37, 0, 16, 0,
-  1, 11, 52, 11, 10, 28, 23, 12, 0, 12,
-  51, 0, 0, 50, 24, 48, 0, 15, 0, 35,
-  0, 0, 38, 48, 0, 0, 0, 6, 0, 75,
-  0, 43, 0, 59, 29, 41, 15, 15, 0, 19,
-  0, 15, 107, 18, 0, 0, 17, 0, 0, 28,
-  25, 21, 0, 41, 0, 0, 45, 6, 26, 0,
-  0, 8, 0, 14, 33, 51, 4, 0, 0, 28,
-  84, 14, 0, 6, 19, 0, 12, 21, 18, 26,
-  0, 9, 9, 21, 0, 72, 0, 4, 31, 72,
-  0, 0, 2, 0, 39, 0, 26, 7, 9, 48,
-  0, 0, 0, 3, 0, 0, 39, 24, 41, 0,
-  37, 0, 84, 0, 64, 0, 13, 0, 0, 32,
-  0, 0, 20, 0, 56, 0, 35, 0, 0, 29,
-  28, 20, 52, 24, 39, 50, 3, 36, 95, 0,
-  10, 21, 21, 25, 9, 34, 0, 29, 0, 0,
-  63, 0, 10, 0, 0, 0, 0, 48, 0, 3,
-  0, 63, 16, 61, 5, 1, 0, 6, 0, 3,
-  79, 33, 0, 0, 18, 0, 0, 7, 0, 7,
-  0, 0, 0, 0, 32, 20, 20, 0, 0, 0,
-  0, 0, 62, 0, 13, 2, 0, 6, 67, 26,
-  0, 0, 6, 0, 7, 0, 11, 49, 18, 0,
-  0, 4, 0, 55, 0, 6, 64, 36, 0, 0,
-  3, 0, 34, 0, 22, 9, 31, 35, 0, 0,
-  0, 0, 0, 0, 14, 2, 12, 0, 45, 0,
-  77, 0, 41, 0, 26, 0, 0, 27, 0, 15,
-  17, 0, 54, 0, 26, 19, 0, 24, 19, 41,
-  54, 36, 42, 53, 0, 29, 105, 0, 0, 24,
-  36, 35, 13, 47, 0, 36, 0, 0, 67, 9,
-  22, 0, 0, 0, 0, 30, 0, 0, 0, 58,
-  16, 44, 12, 18, 0, 3, 21, 11, 61, 51,
-  0, 0, 3, 0, 0, 16, 0, 0, 0, 0,
-  0, 0, 38, 18, 25, 0, 0, 0, 0, 0,
-  56, 0, 14, 7, 0, 10, 79, 42, 2, 0,
-  11, 0, 6, 6, 16, 33, 14, 0, 0, 12,
-  0, 42, 0, 6, 83, 38, 0, 0, 5, 0,
-  37, 0, 29, 9, 43, 27, 0, 0, 1, 0,
-  0, 0, 12, 0, 2, 0, 32, 0, 100, 0,
-  40, 0, 22, 0, 0, 0, 0, 0, 0, 48,
-  47, 0, 22, 0, 0, 0, 38, 0, 10, 49,
-  31, 17, 0, 15, 62, 0, 0, 40, 0, 20,
-  12, 0, 0, 26, 0, 0, 64, 55, 8, 0,
-  0, 16, 0, 41, 0, 28, 0, 56, 0, 45,
-  21, 45, 0, 12, 2, 10, 93, 9, 0, 9,
-  48, 0, 0, 35, 16, 4, 0, 1, 0, 0,
-  17, 7, 42, 0, 2, 3, 0, 21, 13, 42,
-  3, 0, 0, 26, 69, 0, 18, 2, 18, 0,
-  12, 0, 9, 8, 0, 31, 0, 8, 5, 29,
-  0, 0, 36, 54, 18, 0, 0, 0, 1, 0,
-  24, 4, 0, 31, 0, 1, 0, 19, 0, 0,
-  51, 3, 32, 0, 21, 0, 83, 0, 35, 0,
-  4, 0, 0, 9, 0, 0, 15, 0, 57, 0,
-  37, 0, 0, 0, 30, 12, 51, 40, 45, 47,
-  0, 28, 101, 0, 0, 27, 0, 9, 25, 8,
-  0, 23, 0, 0, 52, 4, 22, 0, 0, 12,
-  0, 35, 0, 7, 0, 70, 5, 54, 4, 16,
-  0, 0, 13, 8, 68, 27, 0, 0, 28, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 23, 1,
-  27, 0, 0, 0, 0, 10, 48, 0, 7, 9,
-  0, 11, 57, 13, 9, 0, 13, 0, 0, 0,
-  22, 29, 9, 0, 0, 15, 0, 34, 0, 0,
-  59, 37, 0, 0, 0, 0, 12, 0, 17, 14,
-  11, 27, 0, 0, 0, 5, 0, 0, 24, 0,
-  14, 0, 27, 0, 77, 0, 21, 0, 13, 0,
-  0, 33, 0, 0, 27, 0, 41, 0, 45, 22,
-  0, 7, 22, 44, 69, 48, 60, 49, 0, 17,
-  100, 0, 0, 26, 19, 29, 19, 25, 0, 21,
-  0, 0, 29, 10, 19, 0, 0, 21, 0, 35,
-  0, 0, 0, 56, 7, 31, 16, 4, 0, 0,
-  48, 0, 33, 46, 0, 2, 16, 0, 0, 12,
-  0, 0, 0, 0, 0, 0, 48, 0, 33, 0,
-  0, 0, 0, 6, 51, 0, 15, 23, 0, 30,
-  42, 35, 0, 0, 24, 0, 0, 0, 26, 42,
-  0, 0, 0, 46, 0, 27, 0, 13, 75, 38,
-  0, 0, 0, 0, 17, 0, 16, 5, 28, 44,
-  0, 0, 0, 5, 8, 0, 2, 0, 24, 0,
-  4, 0, 105, 0, 27, 6, 32, 0, 0, 46,
-  0, 5, 8, 0, 87, 3, 13, 14, 0, 39,
-  38, 29, 17, 42, 21, 66, 26, 57, 83, 0,
-  35, 35, 10, 13, 59, 37, 156, 43, 0, 0,
-  97, 0, 28, 0, 0, 0, 0, 60, 0, 0,
-  0, 58, 6, 89, 17, 14, 0, 43, 0, 39,
-  81, 11, 0, 0, 23, 0, 0, 26, 0, 12,
-  14, 12, 0, 0, 12, 25, 19, 1, 23, 0,
-  31, 0, 56, 15, 12, 6, 36, 0, 63, 0,
-  17, 12, 2, 0, 24, 1, 58, 22, 24, 0,
-  0, 0, 11, 31, 0, 0, 72, 22, 0, 0,
-  23, 0, 40, 0, 15, 32, 13, 36, 18, 8,
-  0, 1, 0, 0, 17, 8, 16, 23, 55, 3,
-  28, 0, 23, 0, 16, 0, 0, 26, 0, 19,
-  10, 0, 77, 11, 23, 31, 0, 35, 23, 57,
-  9, 52, 22, 74, 37, 27, 102, 0, 0, 31,
-  15, 13, 55, 46, 154, 59, 0, 4, 97, 0,
-  27, 0, 0, 0, 0, 55, 0, 0, 0, 52,
-  12, 66, 15, 9, 0, 41, 0, 76, 57, 46,
-  4, 14, 7, 0, 0, 16, 0, 0, 24, 8,
-  0, 8, 10, 17, 12, 30, 0, 0, 27, 0,
-  37, 13, 12, 0, 23, 0, 76, 0, 17, 2,
-  0, 0, 21, 18, 71, 15, 30, 0, 0, 0,
-  29, 12, 20, 0, 83, 41, 0, 0, 20, 0,
-  63, 0, 2, 35, 27, 25, 17, 5, 25, 0,
-  6, 0, 30, 0, 13, 13, 58, 0, 47, 0,
-  29, 0, 20, 0, 0, 16, 0, 14, 1, 0,
-  63, 29, 23, 32, 0, 13, 0, 45, 0, 47,
-  19, 68, 39, 6, 67, 0, 0, 42, 12, 16,
-  57, 47, 121, 62, 0, 0, 87, 0, 30, 0,
-  0, 0, 0, 41, 0, 0, 0, 17, 8, 43,
-  25, 0, 0, 37, 11, 79, 44, 41, 28, 6,
-  2, 20, 0, 16, 0, 0, 13, 18, 0, 16,
-  25, 5, 1, 40, 0, 0, 44, 0, 27, 34,
-  0, 0, 27, 0, 77, 0, 17, 14, 0, 0,
-  18, 24, 76, 0, 60, 4, 0, 4, 30, 0,
-  46, 0, 60, 49, 0, 0, 9, 0, 57, 0,
-  0, 18, 38, 31, 23, 17, 38, 0, 21, 0,
-  27, 0, 7, 10, 58, 0, 64, 0, 40, 0,
-  0, 0, 0, 32, 0, 0, 20, 0, 56, 0,
-  35, 0, 0, 29, 28, 20, 52, 24, 39, 50,
-  3, 36, 95, 0, 10, 21, 21, 25, 9, 34,
-  0, 29, 0, 0, 63, 0, 10, 0, 0, 0,
-  0, 48, 0, 3, 0, 63, 16, 61, 5, 1,
-  0, 6, 0, 3, 79, 33, 0, 0, 18, 0,
-  0, 7, 0, 7, 0, 0, 0, 0, 32, 20,
-  20, 0, 0, 0, 0, 0, 62, 0, 13, 2,
-  0, 6, 67, 26, 0, 0, 6, 0, 7, 0,
-  11, 49, 18, 0, 0, 4, 0, 55, 0, 6,
-  64, 36, 0, 0, 3, 0, 34, 0, 22, 9,
-  31, 35, 0, 0, 0, 0, 0, 0, 14, 2,
-  12, 0, 45, 0, 77, 0, 41, 0, 26, 0,
-  0, 27, 0, 15, 17, 0, 54, 0, 26, 19,
-  0, 24, 19, 41, 54, 36, 42, 53, 0, 29,
-  105, 0, 0, 24, 36, 35, 13, 47, 0, 36,
-  0, 0, 67, 9, 22, 0, 0, 0, 0, 30,
-  0, 0, 0, 58, 16, 44, 12, 18, 0, 3,
-  21, 11, 61, 51, 0, 0, 3, 0, 0, 16,
-  0, 0, 0, 0, 0, 0, 38, 18, 25, 0,
-  0, 0, 0, 0, 56, 0, 14, 7, 0, 10,
-  79, 42, 2, 0, 11, 0, 6, 6, 16, 33,
-  14, 0, 0, 12, 0, 42, 0, 6, 83, 38,
-  0, 0, 5, 0, 37, 0, 29, 9, 43, 27,
-  0, 0, 1, 0, 0, 0, 12, 0, 2, 0,
-  32, 0, 100, 0, 40, 0, 22, 0, 0, 22,
-  0, 0, 8, 0, 32, 0, 33, 28, 0, 1,
-  0, 29, 40, 48, 56, 56, 12, 13, 56, 0,
-  0, 29, 28, 42, 16, 56, 0, 19, 0, 0,
-  57, 2, 6, 0, 0, 0, 0, 24, 0, 0,
-  0, 16, 1, 14, 21, 10, 0, 5, 37, 5,
-  41, 38, 0, 11, 0, 24, 0, 42, 0, 0,
-  0, 0, 0, 0, 70, 24, 23, 0, 0, 0,
-  11, 21, 44, 0, 8, 0, 0, 12, 70, 39,
-  7, 8, 19, 29, 0, 28, 16, 3, 38, 30,
-  0, 36, 4, 7, 0, 4, 60, 56, 0, 0,
-  5, 0, 33, 0, 12, 9, 35, 35, 0, 12,
-  2, 0, 10, 0, 0, 0, 0, 0, 6, 0,
-  111, 0, 30, 0, 9, 0, 0, 9, 0, 0,
-  15, 0, 57, 0, 37, 0, 0, 0, 30, 12,
-  51, 40, 45, 47, 0, 28, 101, 0, 0, 27,
-  0, 9, 25, 8, 0, 23, 0, 0, 52, 4,
-  22, 0, 0, 12, 0, 35, 0, 7, 0, 70,
-  5, 54, 4, 16, 0, 0, 13, 8, 68, 27,
-  0, 0, 28, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 23, 1, 27, 0, 0, 0, 0, 10,
-  48, 0, 7, 9, 0, 11, 57, 13, 9, 0,
-  13, 0, 0, 0, 22, 29, 9, 0, 0, 15,
-  0, 34, 0, 0, 59, 37, 0, 0, 0, 0,
-  12, 0, 17, 14, 11, 27, 0, 0, 0, 5,
-  0, 0, 24, 0, 14, 0, 27, 0, 77, 0,
-  21, 0, 13, 0, 0, 33, 0, 0, 27, 0,
-  41, 0, 45, 22, 0, 7, 22, 44, 69, 48,
-  60, 49, 0, 17, 100, 0, 0, 26, 19, 29,
-  19, 25, 0, 21, 0, 0, 29, 10, 19, 0,
-  0, 21, 0, 35, 0, 0, 0, 56, 7, 31,
-  16, 4, 0, 0, 48, 0, 33, 46, 0, 2,
-  16, 0, 0, 12, 0, 0, 0, 0, 0, 0,
-  48, 0, 33, 0, 0, 0, 0, 6, 51, 0,
-  15, 23, 0, 30, 42, 35, 0, 0, 24, 0,
-  0, 0, 26, 42, 0, 0, 0, 46, 0, 27,
-  0, 13, 75, 38, 0, 0, 0, 0, 17, 0,
-  16, 5, 28, 44, 0, 0, 0, 5, 8, 0,
-  2, 0, 24, 0, 4, 0, 105, 0, 27, 6,
-  32, 0, 0, 33, 0, 0, 36, 0, 0, 3,
-  48, 28, 0, 0, 10, 59, 39, 46, 67, 44,
-  12, 0, 51, 0, 0, 36, 0, 22, 41, 60,
-  0, 0, 0, 0, 19, 0, 7, 0, 0, 22,
-  0, 24, 0, 0, 0, 4, 0, 17, 23, 0,
-  0, 0, 55, 0, 1, 17, 0, 0, 18, 15,
-  0, 17, 0, 0, 0, 0, 0, 0, 102, 0,
-  17, 0, 0, 0, 5, 41, 35, 0, 3, 53,
-  0, 13, 18, 38, 12, 42, 10, 28, 0, 30,
-  22, 26, 21, 17, 0, 42, 0, 0, 0, 2,
-  49, 55, 1, 0, 0, 0, 16, 0, 14, 19,
-  32, 69, 0, 3, 0, 0, 21, 0, 0, 0,
-  17, 0, 0, 13, 100, 0, 0, 0, 30, 37,
-  0, 26, 0, 19, 10, 0, 77, 11, 23, 31,
-  0, 35, 23, 57, 9, 52, 22, 74, 37, 27,
-  102, 0, 0, 31, 15, 13, 55, 46, 154, 59,
-  0, 4, 97, 0, 27, 0, 0, 0, 0, 55,
-  0, 0, 0, 52, 12, 66, 15, 9, 0, 41,
-  0, 76, 57, 46, 4, 14, 7, 0, 0, 16,
-  0, 0, 24, 8, 0, 8, 10, 17, 12, 30,
-  0, 0, 27, 0, 37, 13, 12, 0, 23, 0,
-  76, 0, 17, 2, 0, 0, 21, 18, 71, 15,
-  30, 0, 0, 0, 29, 12, 20, 0, 83, 41,
-  0, 0, 20, 0, 63, 0, 2, 35, 27, 25,
-  17, 5, 25, 0, 6, 0, 30, 0, 13, 13,
-  58, 0, 47, 0, 29, 0, 20, 0, 0, 16,
-  0, 14, 1, 0, 63, 29, 23, 32, 0, 13,
-  0, 45, 0, 47, 19, 68, 39, 6, 67, 0,
-  0, 42, 12, 16, 57, 47, 121, 62, 0, 0,
-  87, 0, 30, 0, 0, 0, 0, 41, 0, 0,
-  0, 17, 8, 43, 25, 0, 0, 37, 11, 79,
-  44, 41, 28, 6, 2, 20, 0, 16, 0, 0,
-  13, 18, 0, 16, 25, 5, 1, 40, 0, 0,
-  44, 0, 27, 34, 0, 0, 27, 0, 77, 0,
-  17, 14, 0, 0, 18, 24, 76, 0, 60, 4,
-  0, 4, 30, 0, 46, 0, 60, 49, 0, 0,
-  9, 0, 57, 0, 0, 18, 38, 31, 23, 17,
-  38, 0, 21, 0, 27, 0, 7, 10, 58, 0,
-  64, 0, 40, 0, 0, 0, 0, 26, 0, 7,
-  2, 0, 63, 38, 23, 37, 2, 6, 0, 40,
-  0, 45, 6, 67, 46, 14, 38, 0, 0, 48,
-  16, 24, 55, 58, 112, 45, 0, 0, 68, 0,
-  26, 0, 0, 0, 0, 44, 0, 0, 0, 2,
-  1, 25, 39, 0, 0, 36, 14, 72, 25, 35,
-  35, 0, 0, 49, 0, 21, 0, 0, 16, 34,
-  0, 26, 35, 0, 2, 44, 0, 0, 64, 0,
-  29, 35, 0, 1, 39, 0, 66, 5, 11, 30,
-  0, 6, 14, 27, 89, 0, 74, 5, 0, 3,
-  35, 0, 49, 0, 45, 48, 0, 0, 10, 0,
-  56, 0, 0, 23, 42, 24, 30, 23, 39, 0,
-  31, 0, 11, 0, 7, 13, 40, 0, 62, 0,
-  52, 0, 0, 2, 0, 27, 0, 15, 17, 0,
-  54, 0, 26, 19, 0, 24, 19, 41, 54, 36,
-  42, 53, 0, 29, 105, 0, 0, 24, 36, 35,
-  13, 47, 0, 36, 0, 0, 67, 9, 22, 0,
-  0, 0, 0, 30, 0, 0, 0, 58, 16, 44,
-  12, 18, 0, 3, 21, 11, 61, 51, 0, 0,
-  3, 0, 0, 16, 0, 0, 0, 0, 0, 0,
-  38, 18, 25, 0, 0, 0, 0, 0, 56, 0,
-  14, 7, 0, 10, 79, 42, 2, 0, 11, 0,
-  6, 6, 16, 33, 14, 0, 0, 12, 0, 42,
-  0, 6, 83, 38, 0, 0, 5, 0, 37, 0,
-  29, 9, 43, 27, 0, 0, 1, 0, 0, 0,
-  12, 0, 2, 0, 32, 0, 100, 0, 40, 0,
-  22, 0, 0, 22, 0, 0, 8, 0, 32, 0,
-  33, 28, 0, 1, 0, 29, 40, 48, 56, 56,
-  12, 13, 56, 0, 0, 29, 28, 42, 16, 56,
-  0, 19, 0, 0, 57, 2, 6, 0, 0, 0,
-  0, 24, 0, 0, 0, 16, 1, 14, 21, 10,
-  0, 5, 37, 5, 41, 38, 0, 11, 0, 24,
-  0, 42, 0, 0, 0, 0, 0, 0, 70, 24,
-  23, 0, 0, 0, 11, 21, 44, 0, 8, 0,
-  0, 12, 70, 39, 7, 8, 19, 29, 0, 28,
-  16, 3, 38, 30, 0, 36, 4, 7, 0, 4,
-  60, 56, 0, 0, 5, 0, 33, 0, 12, 9,
-  35, 35, 0, 12, 2, 0, 10, 0, 0, 0,
-  0, 0, 6, 0, 111, 0, 30, 0, 9, 0,
-  0, 40, 0, 0, 15, 0, 26, 0, 40, 45,
-  1, 0, 0, 24, 16, 54, 51, 59, 27, 8,
-  15, 0, 0, 41, 35, 63, 9, 78, 0, 0,
-  8, 0, 21, 0, 0, 0, 0, 0, 0, 35,
-  0, 0, 0, 0, 0, 0, 38, 0, 0, 5,
-  22, 8, 24, 27, 0, 0, 0, 65, 0, 36,
-  0, 0, 0, 33, 0, 2, 97, 14, 35, 0,
-  0, 0, 20, 36, 43, 5, 0, 0, 0, 9,
-  52, 53, 0, 20, 31, 37, 0, 46, 33, 0,
-  42, 41, 0, 48, 0, 0, 2, 16, 45, 62,
-  0, 0, 12, 0, 34, 0, 0, 17, 24, 34,
-  0, 27, 0, 0, 25, 0, 0, 14, 10, 0,
-  0, 8, 110, 0, 42, 0, 17, 9, 0, 33,
-  0, 0, 27, 0, 41, 0, 45, 22, 0, 7,
-  22, 44, 69, 48, 60, 49, 0, 17, 100, 0,
-  0, 26, 19, 29, 19, 25, 0, 21, 0, 0,
-  29, 10, 19, 0, 0, 21, 0, 35, 0, 0,
-  0, 56, 7, 31, 16, 4, 0, 0, 48, 0,
-  33, 46, 0, 2, 16, 0, 0, 12, 0, 0,
-  0, 0, 0, 0, 48, 0, 33, 0, 0, 0,
-  0, 6, 51, 0, 15, 23, 0, 30, 42, 35,
-  0, 0, 24, 0, 0, 0, 26, 42, 0, 0,
-  0, 46, 0, 27, 0, 13, 75, 38, 0, 0,
-  0, 0, 17, 0, 16, 5, 28, 44, 0, 0,
-  0, 5, 8, 0, 2, 0, 24, 0, 4, 0,
-  105, 0, 27, 6, 32, 0, 0, 33, 0, 0,
-  36, 0, 0, 3, 48, 28, 0, 0, 10, 59,
-  39, 46, 67, 44, 12, 0, 51, 0, 0, 36,
-  0, 22, 41, 60, 0, 0, 0, 0, 19, 0,
-  7, 0, 0, 22, 0, 24, 0, 0, 0, 4,
-  0, 17, 23, 0, 0, 0, 55, 0, 1, 17,
-  0, 0, 18, 15, 0, 17, 0, 0, 0, 0,
-  0, 0, 102, 0, 17, 0, 0, 0, 5, 41,
-  35, 0, 3, 53, 0, 13, 18, 38, 12, 42,
-  10, 28, 0, 30, 22, 26, 21, 17, 0, 42,
-  0, 0, 0, 2, 49, 55, 1, 0, 0, 0,
-  16, 0, 14, 19, 32, 69, 0, 3, 0, 0,
-  21, 0, 0, 0, 17, 0, 0, 13, 100, 0,
-  0, 0, 30, 37, 12, 0, 30, 0, 18, 0,
-  0, 0, 37, 30, 0, 0, 4, 71, 11, 0,
-  44, 48, 26, 0, 25, 1, 22, 8, 0, 6,
-  34, 49, 0, 0, 16, 0, 0, 5, 0, 0,
-  40, 32, 0, 1, 1, 0, 0, 0, 0, 0,
-  9, 0, 0, 0, 31, 0, 0, 10, 0, 0,
-  0, 51, 0, 0, 2, 6, 23, 5, 0, 0,
-  106, 5, 12, 82, 0, 0, 6, 39, 0, 0,
-  0, 50, 1, 0, 0, 34, 0, 54, 42, 31,
-  0, 69, 0, 0, 0, 56, 0, 0, 20, 0,
-  0, 15, 19, 45, 10, 6, 0, 0, 0, 0,
-  0, 21, 1, 57, 6, 0, 0, 0, 53, 11,
-  0, 0, 15, 0, 0, 26, 8, 0, 0, 12,
-  42, 48, 0, 16, 0, 14, 1, 0, 63, 29,
-  23, 32, 0, 13, 0, 45, 0, 47, 19, 68,
-  39, 6, 67, 0, 0, 42, 12, 16, 57, 47,
-  121, 62, 0, 0, 87, 0, 30, 0, 0, 0,
-  0, 41, 0, 0, 0, 17, 8, 43, 25, 0,
-  0, 37, 11, 79, 44, 41, 28, 6, 2, 20,
-  0, 16, 0, 0, 13, 18, 0, 16, 25, 5,
-  1, 40, 0, 0, 44, 0, 27, 34, 0, 0,
-  27, 0, 77, 0, 17, 14, 0, 0, 18, 24,
-  76, 0, 60, 4, 0, 4, 30, 0, 46, 0,
-  60, 49, 0, 0, 9, 0, 57, 0, 0, 18,
-  38, 31, 23, 17, 38, 0, 21, 0, 27, 0,
-  7, 10, 58, 0, 64, 0, 40, 0, 0, 0,
-  0, 26, 0, 7, 2, 0, 63, 38, 23, 37,
-  2, 6, 0, 40, 0, 45, 6, 67, 46, 14,
-  38, 0, 0, 48, 16, 24, 55, 58, 112, 45,
-  0, 0, 68, 0, 26, 0, 0, 0, 0, 44,
-  0, 0, 0, 2, 1, 25, 39, 0, 0, 36,
-  14, 72, 25, 35, 35, 0, 0, 49, 0, 21,
-  0, 0, 16, 34, 0, 26, 35, 0, 2, 44,
-  0, 0, 64, 0, 29, 35, 0, 1, 39, 0,
-  66, 5, 11, 30, 0, 6, 14, 27, 89, 0,
-  74, 5, 0, 3, 35, 0, 49, 0, 45, 48,
-  0, 0, 10, 0, 56, 0, 0, 23, 42, 24,
-  30, 23, 39, 0, 31, 0, 11, 0, 7, 13,
-  40, 0, 62, 0, 52, 0, 0, 2, 0, 45,
-  0, 0, 0, 0, 62, 43, 22, 57, 2, 15,
-  0, 41, 7, 47, 6, 61, 60, 24, 15, 0,
-  0, 43, 26, 39, 53, 69, 110, 31, 0, 0,
-  54, 0, 28, 0, 0, 0, 0, 53, 0, 0,
-  0, 0, 3, 7, 35, 0, 0, 41, 15, 67,
-  26, 42, 26, 0, 0, 57, 0, 32, 0, 0,
-  14, 45, 0, 35, 43, 0, 0, 32, 0, 1,
-  56, 0, 32, 31, 0, 8, 48, 0, 66, 25,
-  6, 25, 12, 12, 17, 31, 106, 0, 60, 5,
-  0, 7, 27, 0, 51, 1, 26, 50, 0, 0,
-  24, 0, 67, 0, 2, 18, 45, 33, 35, 9,
-  30, 0, 39, 0, 0, 6, 16, 9, 41, 0,
-  67, 0, 44, 0, 11, 14, 0, 22, 0, 0,
-  8, 0, 32, 0, 33, 28, 0, 1, 0, 29,
-  40, 48, 56, 56, 12, 13, 56, 0, 0, 29,
-  28, 42, 16, 56, 0, 19, 0, 0, 57, 2,
-  6, 0, 0, 0, 0, 24, 0, 0, 0, 16,
-  1, 14, 21, 10, 0, 5, 37, 5, 41, 38,
-  0, 11, 0, 24, 0, 42, 0, 0, 0, 0,
-  0, 0, 70, 24, 23, 0, 0, 0, 11, 21,
-  44, 0, 8, 0, 0, 12, 70, 39, 7, 8,
-  19, 29, 0, 28, 16, 3, 38, 30, 0, 36,
-  4, 7, 0, 4, 60, 56, 0, 0, 5, 0,
-  33, 0, 12, 9, 35, 35, 0, 12, 2, 0,
-  10, 0, 0, 0, 0, 0, 6, 0, 111, 0,
-  30, 0, 9, 0, 0, 40, 0, 0, 15, 0,
-  26, 0, 40, 45, 1, 0, 0, 24, 16, 54,
-  51, 59, 27, 8, 15, 0, 0, 41, 35, 63,
-  9, 78, 0, 0, 8, 0, 21, 0, 0, 0,
-  0, 0, 0, 35, 0, 0, 0, 0, 0, 0,
-  38, 0, 0, 5, 22, 8, 24, 27, 0, 0,
-  0, 65, 0, 36, 0, 0, 0, 33, 0, 2,
-  97, 14, 35, 0, 0, 0, 20, 36, 43, 5,
-  0, 0, 0, 9, 52, 53, 0, 20, 31, 37,
-  0, 46, 33, 0, 42, 41, 0, 48, 0, 0,
-  2, 16, 45, 62, 0, 0, 12, 0, 34, 0,
-  0, 17, 24, 34, 0, 27, 0, 0, 25, 0,
-  0, 14, 10, 0, 0, 8, 110, 0, 42, 0,
-  17, 9, 0, 44, 12, 0, 11, 0, 23, 0,
-  54, 79, 0, 0, 0, 0, 3, 53, 49, 60,
-  36, 23, 0, 0, 0, 42, 29, 49, 27, 93,
-  0, 0, 15, 0, 15, 0, 0, 0, 0, 32,
-  0, 20, 0, 0, 0, 0, 0, 7, 42, 0,
-  0, 5, 12, 12, 37, 19, 0, 0, 0, 60,
-  0, 25, 1, 12, 0, 29, 0, 0, 86, 0,
-  36, 9, 0, 0, 13, 38, 43, 13, 0, 16,
-  0, 0, 60, 35, 0, 10, 27, 23, 0, 45,
-  43, 0, 17, 49, 0, 42, 0, 0, 4, 7,
-  24, 57, 0, 0, 23, 0, 36, 0, 0, 1,
-  19, 59, 0, 22, 0, 0, 36, 0, 0, 24,
-  28, 0, 1, 18, 93, 0, 22, 0, 42, 20,
-  0, 33, 0, 0, 36, 0, 0, 3, 48, 28,
-  0, 0, 10, 59, 39, 46, 67, 44, 12, 0,
-  51, 0, 0, 36, 0, 22, 41, 60, 0, 0,
-  0, 0, 19, 0, 7, 0, 0, 22, 0, 24,
-  0, 0, 0, 4, 0, 17, 23, 0, 0, 0,
-  55, 0, 1, 17, 0, 0, 18, 15, 0, 17,
-  0, 0, 0, 0, 0, 0, 102, 0, 17, 0,
-  0, 0, 5, 41, 35, 0, 3, 53, 0, 13,
-  18, 38, 12, 42, 10, 28, 0, 30, 22, 26,
-  21, 17, 0, 42, 0, 0, 0, 2, 49, 55,
-  1, 0, 0, 0, 16, 0, 14, 19, 32, 69,
-  0, 3, 0, 0, 21, 0, 0, 0, 17, 0,
-  0, 13, 100, 0, 0, 0, 30, 37, 12, 0,
-  30, 0, 18, 0, 0, 0, 37, 30, 0, 0,
-  4, 71, 11, 0, 44, 48, 26, 0, 25, 1,
-  22, 8, 0, 6, 34, 49, 0, 0, 16, 0,
-  0, 5, 0, 0, 40, 32, 0, 1, 1, 0,
-  0, 0, 0, 0, 9, 0, 0, 0, 31, 0,
-  0, 10, 0, 0, 0, 51, 0, 0, 2, 6,
-  23, 5, 0, 0, 106, 5, 12, 82, 0, 0,
-  6, 39, 0, 0, 0, 50, 1, 0, 0, 34,
-  0, 54, 42, 31, 0, 69, 0, 0, 0, 56,
-  0, 0, 20, 0, 0, 15, 19, 45, 10, 6,
-  0, 0, 0, 0, 0, 21, 1, 57, 6, 0,
-  0, 0, 53, 11, 0, 0, 15, 0, 0, 26,
-  8, 0, 0, 12, 42, 48, 16, 0, 43, 0,
-  0, 0, 0, 0, 40, 54, 0, 16, 0, 59,
-  14, 0, 21, 57, 23, 17, 21, 14, 54, 0,
-  0, 0, 42, 21, 0, 0, 0, 0, 0, 0,
-  0, 0, 54, 47, 0, 0, 9, 0, 0, 0,
-  0, 0, 9, 0, 0, 0, 23, 0, 0, 0,
-  10, 0, 8, 40, 0, 0, 0, 25, 50, 0,
-  59, 21, 36, 7, 0, 114, 0, 9, 8, 6,
-  0, 0, 4, 34, 0, 0, 0, 19, 0, 29,
-  42, 2, 22, 44, 6, 0, 0, 57, 0, 0,
-  19, 0, 0, 0, 14, 17, 24, 0, 0, 0,
-  0, 0, 0, 0, 0, 39, 0, 0, 0, 0,
-  81, 4, 14, 0, 20, 0, 0, 18, 0, 0,
-  0, 19, 37, 4, 0, 26, 0, 7, 2, 0,
-  63, 38, 23, 37, 2, 6, 0, 40, 0, 45,
-  6, 67, 46, 14, 38, 0, 0, 48, 16, 24,
-  55, 58, 112, 45, 0, 0, 68, 0, 26, 0,
-  0, 0, 0, 44, 0, 0, 0, 2, 1, 25,
-  39, 0, 0, 36, 14, 72, 25, 35, 35, 0,
-  0, 49, 0, 21, 0, 0, 16, 34, 0, 26,
-  35, 0, 2, 44, 0, 0, 64, 0, 29, 35,
-  0, 1, 39, 0, 66, 5, 11, 30, 0, 6,
-  14, 27, 89, 0, 74, 5, 0, 3, 35, 0,
-  49, 0, 45, 48, 0, 0, 10, 0, 56, 0,
-  0, 23, 42, 24, 30, 23, 39, 0, 31, 0,
-  11, 0, 7, 13, 40, 0, 62, 0, 52, 0,
-  0, 2, 0, 45, 0, 0, 0, 0, 62, 43,
-  22, 57, 2, 15, 0, 41, 7, 47, 6, 61,
-  60, 24, 15, 0, 0, 43, 26, 39, 53, 69,
-  110, 31, 0, 0, 54, 0, 28, 0, 0, 0,
-  0, 53, 0, 0, 0, 0, 3, 7, 35, 0,
-  0, 41, 15, 67, 26, 42, 26, 0, 0, 57,
-  0, 32, 0, 0, 14, 45, 0, 35, 43, 0,
-  0, 32, 0, 1, 56, 0, 32, 31, 0, 8,
-  48, 0, 66, 25, 6, 25, 12, 12, 17, 31,
-  106, 0, 60, 5, 0, 7, 27, 0, 51, 1,
-  26, 50, 0, 0, 24, 0, 67, 0, 2, 18,
-  45, 33, 35, 9, 30, 0, 39, 0, 0, 6,
-  16, 9, 41, 0, 67, 0, 44, 0, 11, 14,
-  0, 50, 11, 0, 0, 0, 74, 36, 26, 54,
-  0, 25, 0, 0, 19, 41, 32, 80, 62, 25,
-  0, 0, 0, 42, 46, 46, 53, 65, 120, 31,
-  0, 0, 44, 0, 29, 0, 0, 0, 0, 45,
-  0, 0, 34, 0, 9, 14, 37, 0, 0, 29,
-  26, 40, 42, 29, 11, 0, 0, 42, 0, 48,
-  0, 0, 13, 56, 0, 27, 47, 0, 0, 21,
-  0, 6, 37, 0, 32, 21, 1, 6, 34, 0,
-  57, 25, 7, 31, 24, 9, 22, 28, 77, 0,
-  42, 0, 0, 21, 17, 0, 36, 22, 1, 31,
-  0, 0, 35, 0, 70, 0, 6, 12, 44, 44,
-  51, 12, 23, 0, 31, 0, 0, 14, 39, 0,
-  40, 13, 69, 0, 18, 0, 49, 15, 0, 40,
-  0, 0, 15, 0, 26, 0, 40, 45, 1, 0,
-  0, 24, 16, 54, 51, 59, 27, 8, 15, 0,
-  0, 41, 35, 63, 9, 78, 0, 0, 8, 0,
-  21, 0, 0, 0, 0, 0, 0, 35, 0, 0,
-  0, 0, 0, 0, 38, 0, 0, 5, 22, 8,
-  24, 27, 0, 0, 0, 65, 0, 36, 0, 0,
-  0, 33, 0, 2, 97, 14, 35, 0, 0, 0,
-  20, 36, 43, 5, 0, 0, 0, 9, 52, 53,
-  0, 20, 31, 37, 0, 46, 33, 0, 42, 41,
-  0, 48, 0, 0, 2, 16, 45, 62, 0, 0,
-  12, 0, 34, 0, 0, 17, 24, 34, 0, 27,
-  0, 0, 25, 0, 0, 14, 10, 0, 0, 8,
-  110, 0, 42, 0, 17, 9, 0, 44, 12, 0,
-  11, 0, 23, 0, 54, 79, 0, 0, 0, 0,
-  3, 53, 49, 60, 36, 23, 0, 0, 0, 42,
-  29, 49, 27, 93, 0, 0, 15, 0, 15, 0,
-  0, 0, 0, 32, 0, 20, 0, 0, 0, 0,
-  0, 7, 42, 0, 0, 5, 12, 12, 37, 19,
-  0, 0, 0, 60, 0, 25, 1, 12, 0, 29,
-  0, 0, 86, 0, 36, 9, 0, 0, 13, 38,
-  43, 13, 0, 16, 0, 0, 60, 35, 0, 10,
-  27, 23, 0, 45, 43, 0, 17, 49, 0, 42,
-  0, 0, 4, 7, 24, 57, 0, 0, 23, 0,
-  36, 0, 0, 1, 19, 59, 0, 22, 0, 0,
-  36, 0, 0, 24, 28, 0, 1, 18, 93, 0,
-  22, 0, 42, 20, 0, 38, 33, 0, 0, 0,
-  27, 0, 63, 89, 0, 12, 0, 0, 14, 41,
-  49, 72, 30, 11, 0, 0, 0, 57, 37, 23,
-  43, 98, 0, 0, 23, 0, 9, 0, 0, 0,
-  0, 70, 0, 0, 14, 15, 16, 0, 0, 17,
-  24, 0, 0, 0, 12, 0, 48, 0, 0, 0,
-  0, 33, 0, 3, 10, 18, 0, 50, 0, 0,
-  81, 0, 15, 42, 0, 0, 7, 44, 23, 12,
-  4, 28, 0, 0, 63, 33, 2, 27, 31, 25,
-  2, 25, 25, 0, 0, 46, 0, 33, 0, 0,
-  0, 14, 0, 51, 3, 0, 8, 0, 41, 0,
-  0, 18, 2, 64, 10, 19, 0, 0, 55, 0,
-  0, 23, 45, 0, 7, 3, 63, 0, 0, 0,
-  78, 18, 12, 0, 30, 0, 18, 0, 0, 0,
-  37, 30, 0, 0, 4, 71, 11, 0, 44, 48,
-  26, 0, 25, 1, 22, 8, 0, 6, 34, 49,
-  0, 0, 16, 0, 0, 5, 0, 0, 40, 32,
-  0, 1, 1, 0, 0, 0, 0, 0, 9, 0,
-  0, 0, 31, 0, 0, 10, 0, 0, 0, 51,
-  0, 0, 2, 6, 23, 5, 0, 0, 106, 5,
-  12, 82, 0, 0, 6, 39, 0, 0, 0, 50,
-  1, 0, 0, 34, 0, 54, 42, 31, 0, 69,
-  0, 0, 0, 56, 0, 0, 20, 0, 0, 15,
-  19, 45, 10, 6, 0, 0, 0, 0, 0, 21,
-  1, 57, 6, 0, 0, 0, 53, 11, 0, 0,
-  15, 0, 0, 26, 8, 0, 0, 12, 42, 48,
-  16, 0, 43, 0, 0, 0, 0, 0, 40, 54,
-  0, 16, 0, 59, 14, 0, 21, 57, 23, 17,
-  21, 14, 54, 0, 0, 0, 42, 21, 0, 0,
-  0, 0, 0, 0, 0, 0, 54, 47, 0, 0,
-  9, 0, 0, 0, 0, 0, 9, 0, 0, 0,
-  23, 0, 0, 0, 10, 0, 8, 40, 0, 0,
-  0, 25, 50, 0, 59, 21, 36, 7, 0, 114,
-  0, 9, 8, 6, 0, 0, 4, 34, 0, 0,
-  0, 19, 0, 29, 42, 2, 22, 44, 6, 0,
-  0, 57, 0, 0, 19, 0, 0, 0, 14, 17,
-  24, 0, 0, 0, 0, 0, 0, 0, 0, 39,
-  0, 0, 0, 0, 81, 4, 14, 0, 20, 0,
-  0, 18, 0, 0, 0, 19, 37, 4, 30, 0,
-  21, 8, 18, 0, 0, 0, 23, 36, 0, 0,
-  0, 54, 7, 0, 0, 65, 15, 16, 55, 1,
-  62, 10, 0, 0, 52, 0, 0, 0, 14, 0,
-  0, 0, 0, 0, 9, 33, 0, 0, 29, 0,
-  0, 9, 0, 0, 15, 0, 0, 0, 30, 30,
-  0, 0, 29, 0, 20, 15, 0, 0, 0, 14,
-  64, 0, 89, 22, 8, 0, 0, 130, 0, 14,
-  8, 0, 2, 0, 14, 22, 0, 0, 24, 0,
-  8, 22, 41, 0, 39, 0, 26, 0, 0, 30,
-  15, 0, 0, 0, 0, 0, 23, 0, 15, 0,
-  0, 0, 0, 0, 0, 32, 0, 10, 0, 9,
-  0, 0, 99, 17, 35, 0, 24, 0, 6, 0,
-  0, 0, 0, 31, 25, 0, 0, 45, 0, 0,
-  0, 0, 62, 43, 22, 57, 2, 15, 0, 41,
-  7, 47, 6, 61, 60, 24, 15, 0, 0, 43,
-  26, 39, 53, 69, 110, 31, 0, 0, 54, 0,
-  28, 0, 0, 0, 0, 53, 0, 0, 0, 0,
-  3, 7, 35, 0, 0, 41, 15, 67, 26, 42,
-  26, 0, 0, 57, 0, 32, 0, 0, 14, 45,
-  0, 35, 43, 0, 0, 32, 0, 1, 56, 0,
-  32, 31, 0, 8, 48, 0, 66, 25, 6, 25,
-  12, 12, 17, 31, 106, 0, 60, 5, 0, 7,
-  27, 0, 51, 1, 26, 50, 0, 0, 24, 0,
-  67, 0, 2, 18, 45, 33, 35, 9, 30, 0,
-  39, 0, 0, 6, 16, 9, 41, 0, 67, 0,
-  44, 0, 11, 14, 0, 50, 11, 0, 0, 0,
-  74, 36, 26, 54, 0, 25, 0, 0, 19, 41,
-  32, 80, 62, 25, 0, 0, 0, 42, 46, 46,
-  53, 65, 120, 31, 0, 0, 44, 0, 29, 0,
-  0, 0, 0, 45, 0, 0, 34, 0, 9, 14,
-  37, 0, 0, 29, 26, 40, 42, 29, 11, 0,
-  0, 42, 0, 48, 0, 0, 13, 56, 0, 27,
-  47, 0, 0, 21, 0, 6, 37, 0, 32, 21,
-  1, 6, 34, 0, 57, 25, 7, 31, 24, 9,
-  22, 28, 77, 0, 42, 0, 0, 21, 17, 0,
-  36, 22, 1, 31, 0, 0, 35, 0, 70, 0,
-  6, 12, 44, 44, 51, 12, 23, 0, 31, 0,
-  0, 14, 39, 0, 40, 13, 69, 0, 18, 0,
-  49, 15, 0, 53, 6, 0, 0, 0, 108, 18,
-  35, 62, 0, 10, 0, 0, 14, 70, 19, 66,
-  42, 16, 0, 0, 0, 59, 58, 43, 47, 64,
-  123, 32, 0, 0, 54, 0, 29, 0, 0, 0,
-  9, 45, 0, 0, 26, 16, 0, 23, 56, 0,
-  0, 30, 14, 43, 57, 13, 7, 3, 3, 60,
-  0, 52, 0, 9, 11, 62, 0, 31, 41, 10,
-  20, 3, 0, 13, 31, 0, 45, 36, 0, 0,
-  32, 0, 56, 38, 10, 21, 24, 0, 26, 22,
-  84, 1, 35, 0, 0, 34, 0, 0, 6, 15,
-  19, 40, 0, 0, 26, 0, 74, 0, 0, 29,
-  37, 36, 50, 12, 2, 0, 29, 0, 0, 35,
-  51, 0, 32, 0, 64, 0, 33, 0, 43, 1,
-  0, 44, 12, 0, 11, 0, 23, 0, 54, 79,
-  0, 0, 0, 0, 3, 53, 49, 60, 36, 23,
-  0, 0, 0, 42, 29, 49, 27, 93, 0, 0,
-  15, 0, 15, 0, 0, 0, 0, 32, 0, 20,
-  0, 0, 0, 0, 0, 7, 42, 0, 0, 5,
-  12, 12, 37, 19, 0, 0, 0, 60, 0, 25,
-  1, 12, 0, 29, 0, 0, 86, 0, 36, 9,
-  0, 0, 13, 38, 43, 13, 0, 16, 0, 0,
-  60, 35, 0, 10, 27, 23, 0, 45, 43, 0,
-  17, 49, 0, 42, 0, 0, 4, 7, 24, 57,
-  0, 0, 23, 0, 36, 0, 0, 1, 19, 59,
-  0, 22, 0, 0, 36, 0, 0, 24, 28, 0,
-  1, 18, 93, 0, 22, 0, 42, 20, 0, 38,
-  33, 0, 0, 0, 27, 0, 63, 89, 0, 12,
-  0, 0, 14, 41, 49, 72, 30, 11, 0, 0,
-  0, 57, 37, 23, 43, 98, 0, 0, 23, 0,
-  9, 0, 0, 0, 0, 70, 0, 0, 14, 15,
-  16, 0, 0, 17, 24, 0, 0, 0, 12, 0,
-  48, 0, 0, 0, 0, 33, 0, 3, 10, 18,
-  0, 50, 0, 0, 81, 0, 15, 42, 0, 0,
-  7, 44, 23, 12, 4, 28, 0, 0, 63, 33,
-  2, 27, 31, 25, 2, 25, 25, 0, 0, 46,
-  0, 33, 0, 0, 0, 14, 0, 51, 3, 0,
-  8, 0, 41, 0, 0, 18, 2, 64, 10, 19,
-  0, 0, 55, 0, 0, 23, 45, 0, 7, 3,
-  63, 0, 0, 0, 78, 18, 0, 39, 39, 0,
-  0, 0, 25, 0, 78, 78, 0, 0, 0, 3,
-  0, 17, 3, 41, 11, 0, 0, 0, 16, 61,
-  36, 0, 50, 80, 0, 0, 9, 0, 0, 0,
-  0, 0, 16, 73, 0, 0, 40, 8, 4, 0,
-  0, 14, 31, 0, 0, 0, 18, 0, 26, 0,
-  2, 0, 24, 52, 0, 0, 0, 48, 0, 57,
-  2, 2, 88, 0, 14, 69, 0, 0, 2, 41,
-  6, 46, 1, 15, 0, 0, 48, 46, 0, 40,
-  32, 26, 15, 28, 27, 0, 0, 65, 0, 8,
-  0, 0, 0, 0, 0, 52, 25, 0, 0, 0,
-  32, 0, 0, 39, 0, 43, 11, 0, 0, 0,
-  70, 0, 0, 25, 54, 0, 0, 0, 11, 0,
-  0, 0, 64, 2, 16, 0, 43, 0, 0, 0,
-  0, 0, 40, 54, 0, 16, 0, 59, 14, 0,
-  21, 57, 23, 17, 21, 14, 54, 0, 0, 0,
-  42, 21, 0, 0, 0, 0, 0, 0, 0, 0,
-  54, 47, 0, 0, 9, 0, 0, 0, 0, 0,
-  9, 0, 0, 0, 23, 0, 0, 0, 10, 0,
-  8, 40, 0, 0, 0, 25, 50, 0, 59, 21,
-  36, 7, 0, 114, 0, 9, 8, 6, 0, 0,
-  4, 34, 0, 0, 0, 19, 0, 29, 42, 2,
-  22, 44, 6, 0, 0, 57, 0, 0, 19, 0,
-  0, 0, 14, 17, 24, 0, 0, 0, 0, 0,
-  0, 0, 0, 39, 0, 0, 0, 0, 81, 4,
-  14, 0, 20, 0, 0, 18, 0, 0, 0, 19,
-  37, 4, 30, 0, 21, 8, 18, 0, 0, 0,
-  23, 36, 0, 0, 0, 54, 7, 0, 0, 65,
-  15, 16, 55, 1, 62, 10, 0, 0, 52, 0,
-  0, 0, 14, 0, 0, 0, 0, 0, 9, 33,
-  0, 0, 29, 0, 0, 9, 0, 0, 15, 0,
-  0, 0, 30, 30, 0, 0, 29, 0, 20, 15,
-  0, 0, 0, 14, 64, 0, 89, 22, 8, 0,
-  0, 130, 0, 14, 8, 0, 2, 0, 14, 22,
-  0, 0, 24, 0, 8, 22, 41, 0, 39, 0,
-  26, 0, 0, 30, 15, 0, 0, 0, 0, 0,
-  23, 0, 15, 0, 0, 0, 0, 0, 0, 32,
-  0, 10, 0, 9, 0, 0, 99, 17, 35, 0,
-  24, 0, 6, 0, 0, 0, 0, 31, 25, 0,
-  5, 13, 0, 32, 19, 0, 8, 0, 42, 4,
-  0, 13, 0, 36, 0, 0, 0, 57, 0, 20,
-  78, 0, 62, 17, 0, 0, 48, 0, 0, 0,
-  23, 0, 0, 0, 0, 0, 0, 22, 0, 0,
-  41, 0, 0, 33, 9, 0, 6, 0, 0, 0,
-  32, 6, 0, 0, 33, 0, 37, 0, 4, 0,
-  0, 39, 62, 0, 84, 8, 32, 22, 0, 130,
-  0, 9, 16, 0, 0, 9, 33, 13, 0, 0,
-  29, 13, 0, 22, 32, 0, 33, 0, 24, 0,
-  0, 28, 10, 0, 0, 0, 8, 0, 32, 0,
-  10, 12, 0, 0, 0, 0, 0, 83, 0, 0,
-  2, 0, 0, 0, 98, 36, 46, 0, 18, 0,
-  8, 0, 0, 0, 0, 28, 8, 0, 0, 50,
-  11, 0, 0, 0, 74, 36, 26, 54, 0, 25,
-  0, 0, 19, 41, 32, 80, 62, 25, 0, 0,
-  0, 42, 46, 46, 53, 65, 120, 31, 0, 0,
-  44, 0, 29, 0, 0, 0, 0, 45, 0, 0,
-  34, 0, 9, 14, 37, 0, 0, 29, 26, 40,
-  42, 29, 11, 0, 0, 42, 0, 48, 0, 0,
-  13, 56, 0, 27, 47, 0, 0, 21, 0, 6,
-  37, 0, 32, 21, 1, 6, 34, 0, 57, 25,
-  7, 31, 24, 9, 22, 28, 77, 0, 42, 0,
-  0, 21, 17, 0, 36, 22, 1, 31, 0, 0,
-  35, 0, 70, 0, 6, 12, 44, 44, 51, 12,
-  23, 0, 31, 0, 0, 14, 39, 0, 40, 13,
-  69, 0, 18, 0, 49, 15, 0, 53, 6, 0,
-  0, 0, 108, 18, 35, 62, 0, 10, 0, 0,
-  14, 70, 19, 66, 42, 16, 0, 0, 0, 59,
-  58, 43, 47, 64, 123, 32, 0, 0, 54, 0,
-  29, 0, 0, 0, 9, 45, 0, 0, 26, 16,
-  0, 23, 56, 0, 0, 30, 14, 43, 57, 13,
-  7, 3, 3, 60, 0, 52, 0, 9, 11, 62,
-  0, 31, 41, 10, 20, 3, 0, 13, 31, 0,
-  45, 36, 0, 0, 32, 0, 56, 38, 10, 21,
-  24, 0, 26, 22, 84, 1, 35, 0, 0, 34,
-  0, 0, 6, 15, 19, 40, 0, 0, 26, 0,
-  74, 0, 0, 29, 37, 36, 50, 12, 2, 0,
-  29, 0, 0, 35, 51, 0, 32, 0, 64, 0,
-  33, 0, 43, 1, 0, 47, 0, 0, 0, 0,
-  99, 35, 39, 50, 0, 17, 0, 0, 7, 70,
-  34, 67, 46, 6, 16, 0, 0, 47, 51, 51,
-  43, 68, 129, 40, 9, 0, 53, 0, 19, 0,
-  0, 3, 0, 46, 0, 0, 4, 18, 0, 21,
-  43, 0, 0, 29, 3, 44, 51, 16, 0, 0,
-  8, 61, 0, 57, 0, 8, 10, 70, 0, 30,
-  41, 15, 26, 0, 0, 5, 28, 0, 43, 38,
-  0, 0, 35, 0, 53, 27, 7, 21, 30, 0,
-  31, 28, 62, 0, 36, 0, 0, 42, 1, 0,
-  11, 10, 39, 35, 0, 0, 24, 0, 67, 0,
-  0, 27, 42, 50, 46, 18, 14, 0, 25, 0,
-  0, 33, 56, 0, 33, 24, 74, 0, 21, 0,
-  46, 9, 0, 38, 33, 0, 0, 0, 27, 0,
-  63, 89, 0, 12, 0, 0, 14, 41, 49, 72,
-  30, 11, 0, 0, 0, 57, 37, 23, 43, 98,
-  0, 0, 23, 0, 9, 0, 0, 0, 0, 70,
-  0, 0, 14, 15, 16, 0, 0, 17, 24, 0,
-  0, 0, 12, 0, 48, 0, 0, 0, 0, 33,
-  0, 3, 10, 18, 0, 50, 0, 0, 81, 0,
-  15, 42, 0, 0, 7, 44, 23, 12, 4, 28,
-  0, 0, 63, 33, 2, 27, 31, 25, 2, 25,
-  25, 0, 0, 46, 0, 33, 0, 0, 0, 14,
-  0, 51, 3, 0, 8, 0, 41, 0, 0, 18,
-  2, 64, 10, 19, 0, 0, 55, 0, 0, 23,
-  45, 0, 7, 3, 63, 0, 0, 0, 78, 18,
-  0, 39, 39, 0, 0, 0, 25, 0, 78, 78,
-  0, 0, 0, 3, 0, 17, 3, 41, 11, 0,
-  0, 0, 16, 61, 36, 0, 50, 80, 0, 0,
-  9, 0, 0, 0, 0, 0, 16, 73, 0, 0,
-  40, 8, 4, 0, 0, 14, 31, 0, 0, 0,
-  18, 0, 26, 0, 2, 0, 24, 52, 0, 0,
-  0, 48, 0, 57, 2, 2, 88, 0, 14, 69,
-  0, 0, 2, 41, 6, 46, 1, 15, 0, 0,
-  48, 46, 0, 40, 32, 26, 15, 28, 27, 0,
-  0, 65, 0, 8, 0, 0, 0, 0, 0, 52,
-  25, 0, 0, 0, 32, 0, 0, 39, 0, 43,
-  11, 0, 0, 0, 70, 0, 0, 25, 54, 0,
-  0, 0, 11, 0, 0, 0, 64, 2, 0, 29,
-  0, 0, 0, 0, 15, 0, 80, 38, 0, 0,
-  0, 0, 0, 0, 0, 35, 26, 0, 14, 0,
-  0, 45, 31, 0, 42, 64, 0, 0, 16, 0,
-  0, 5, 0, 0, 32, 60, 1, 0, 52, 0,
-  0, 0, 0, 15, 40, 0, 0, 0, 0, 2,
-  11, 0, 19, 50, 26, 49, 0, 0, 6, 43,
-  3, 66, 19, 0, 76, 0, 18, 84, 0, 0,
-  2, 19, 0, 39, 0, 5, 14, 0, 39, 27,
-  3, 12, 27, 17, 21, 31, 23, 0, 0, 98,
-  2, 0, 0, 0, 0, 0, 39, 39, 30, 37,
-  0, 0, 15, 0, 0, 33, 0, 44, 1, 9,
-  0, 0, 55, 0, 0, 24, 71, 0, 0, 0,
-  0, 0, 0, 0, 42, 0, 30, 0, 21, 8,
-  18, 0, 0, 0, 23, 36, 0, 0, 0, 54,
-  7, 0, 0, 65, 15, 16, 55, 1, 62, 10,
-  0, 0, 52, 0, 0, 0, 14, 0, 0, 0,
-  0, 0, 9, 33, 0, 0, 29, 0, 0, 9,
-  0, 0, 15, 0, 0, 0, 30, 30, 0, 0,
-  29, 0, 20, 15, 0, 0, 0, 14, 64, 0,
-  89, 22, 8, 0, 0, 130, 0, 14, 8, 0,
-  2, 0, 14, 22, 0, 0, 24, 0, 8, 22,
-  41, 0, 39, 0, 26, 0, 0, 30, 15, 0,
-  0, 0, 0, 0, 23, 0, 15, 0, 0, 0,
-  0, 0, 0, 32, 0, 10, 0, 9, 0, 0,
-  99, 17, 35, 0, 24, 0, 6, 0, 0, 0,
-  0, 31, 25, 0, 5, 13, 0, 32, 19, 0,
-  8, 0, 42, 4, 0, 13, 0, 36, 0, 0,
-  0, 57, 0, 20, 78, 0, 62, 17, 0, 0,
-  48, 0, 0, 0, 23, 0, 0, 0, 0, 0,
-  0, 22, 0, 0, 41, 0, 0, 33, 9, 0,
-  6, 0, 0, 0, 32, 6, 0, 0, 33, 0,
-  37, 0, 4, 0, 0, 39, 62, 0, 84, 8,
-  32, 22, 0, 130, 0, 9, 16, 0, 0, 9,
-  33, 13, 0, 0, 29, 13, 0, 22, 32, 0,
-  33, 0, 24, 0, 0, 28, 10, 0, 0, 0,
-  8, 0, 32, 0, 10, 12, 0, 0, 0, 0,
-  0, 83, 0, 0, 2, 0, 0, 0, 98, 36,
-  46, 0, 18, 0, 8, 0, 0, 0, 0, 28,
-  8, 0, 11, 29, 0, 45, 2, 0, 17, 0,
-  59, 0, 0, 24, 0, 0, 0, 0, 0, 40,
-  1, 11, 70, 0, 8, 10, 0, 0, 32, 0,
-  0, 0, 26, 22, 0, 7, 0, 0, 17, 26,
-  2, 0, 47, 0, 0, 21, 13, 9, 8, 0,
-  0, 0, 39, 2, 0, 18, 67, 54, 46, 0,
-  21, 0, 0, 41, 60, 20, 72, 13, 27, 31,
-  0, 123, 0, 13, 17, 0, 0, 28, 28, 13,
-  17, 0, 23, 19, 0, 3, 26, 0, 27, 0,
-  23, 0, 0, 39, 0, 0, 0, 3, 33, 0,
-  52, 9, 4, 75, 0, 0, 0, 0, 0, 100,
-  0, 0, 2, 0, 0, 11, 51, 34, 23, 0,
-  31, 0, 14, 0, 0, 0, 3, 31, 7, 0,
-  0, 53, 6, 0, 0, 0, 108, 18, 35, 62,
-  0, 10, 0, 0, 14, 70, 19, 66, 42, 16,
-  0, 0, 0, 59, 58, 43, 47, 64, 123, 32,
-  0, 0, 54, 0, 29, 0, 0, 0, 9, 45,
-  0, 0, 26, 16, 0, 23, 56, 0, 0, 30,
-  14, 43, 57, 13, 7, 3, 3, 60, 0, 52,
-  0, 9, 11, 62, 0, 31, 41, 10, 20, 3,
-  0, 13, 31, 0, 45, 36, 0, 0, 32, 0,
-  56, 38, 10, 21, 24, 0, 26, 22, 84, 1,
-  35, 0, 0, 34, 0, 0, 6, 15, 19, 40,
-  0, 0, 26, 0, 74, 0, 0, 29, 37, 36,
-  50, 12, 2, 0, 29, 0, 0, 35, 51, 0,
-  32, 0, 64, 0, 33, 0, 43, 1, 0, 47,
-  0, 0, 0, 0, 99, 35, 39, 50, 0, 17,
-  0, 0, 7, 70, 34, 67, 46, 6, 16, 0,
-  0, 47, 51, 51, 43, 68, 129, 40, 9, 0,
-  53, 0, 19, 0, 0, 3, 0, 46, 0, 0,
-  4, 18, 0, 21, 43, 0, 0, 29, 3, 44,
-  51, 16, 0, 0, 8, 61, 0, 57, 0, 8,
-  10, 70, 0, 30, 41, 15, 26, 0, 0, 5,
-  28, 0, 43, 38, 0, 0, 35, 0, 53, 27,
-  7, 21, 30, 0, 31, 28, 62, 0, 36, 0,
-  0, 42, 1, 0, 11, 10, 39, 35, 0, 0,
-  24, 0, 67, 0, 0, 27, 42, 50, 46, 18,
-  14, 0, 25, 0, 0, 33, 56, 0, 33, 24,
-  74, 0, 21, 0, 46, 9, 0, 40, 0, 0,
-  5, 0, 79, 51, 29, 30, 0, 28, 9, 0,
-  6, 57, 44, 75, 60, 18, 9, 0, 0, 32,
-  53, 70, 33, 61, 135, 47, 36, 0, 45, 8,
-  29, 0, 0, 4, 0, 55, 0, 0, 25, 9,
-  0, 4, 34, 0, 0, 18, 21, 51, 44, 48,
-  0, 10, 3, 61, 0, 58, 0, 0, 12, 61,
-  0, 22, 46, 13, 15, 0, 0, 2, 14, 0,
-  34, 33, 0, 3, 31, 0, 57, 9, 0, 22,
-  46, 0, 23, 34, 53, 5, 53, 2, 0, 39,
-  29, 0, 36, 10, 25, 36, 0, 0, 19, 0,
-  58, 0, 0, 20, 53, 51, 44, 24, 38, 2,
-  31, 0, 0, 13, 50, 0, 40, 53, 98, 0,
-  37, 0, 54, 1, 0, 39, 39, 0, 0, 0,
-  25, 0, 78, 78, 0, 0, 0, 3, 0, 17,
-  3, 41, 11, 0, 0, 0, 16, 61, 36, 0,
-  50, 80, 0, 0, 9, 0, 0, 0, 0, 0,
-  16, 73, 0, 0, 40, 8, 4, 0, 0, 14,
-  31, 0, 0, 0, 18, 0, 26, 0, 2, 0,
-  24, 52, 0, 0, 0, 48, 0, 57, 2, 2,
-  88, 0, 14, 69, 0, 0, 2, 41, 6, 46,
-  1, 15, 0, 0, 48, 46, 0, 40, 32, 26,
-  15, 28, 27, 0, 0, 65, 0, 8, 0, 0,
-  0, 0, 0, 52, 25, 0, 0, 0, 32, 0,
-  0, 39, 0, 43, 11, 0, 0, 0, 70, 0,
-  0, 25, 54, 0, 0, 0, 11, 0, 0, 0,
-  64, 2, 0, 29, 0, 0, 0, 0, 15, 0,
-  80, 38, 0, 0, 0, 0, 0, 0, 0, 35,
-  26, 0, 14, 0, 0, 45, 31, 0, 42, 64,
-  0, 0, 16, 0, 0, 5, 0, 0, 32, 60,
-  1, 0, 52, 0, 0, 0, 0, 15, 40, 0,
-  0, 0, 0, 2, 11, 0, 19, 50, 26, 49,
-  0, 0, 6, 43, 3, 66, 19, 0, 76, 0,
-  18, 84, 0, 0, 2, 19, 0, 39, 0, 5,
-  14, 0, 39, 27, 3, 12, 27, 17, 21, 31,
-  23, 0, 0, 98, 2, 0, 0, 0, 0, 0,
-  39, 39, 30, 37, 0, 0, 15, 0, 0, 33,
-  0, 44, 1, 9, 0, 0, 55, 0, 0, 24,
-  71, 0, 0, 0, 0, 0, 0, 0, 42, 0,
-  0, 21, 0, 0, 2, 0, 15, 0, 74, 29,
-  0, 18, 0, 12, 0, 34, 16, 63, 31, 0,
-  0, 0, 0, 43, 15, 0, 18, 55, 0, 0,
-  44, 0, 0, 15, 0, 0, 19, 53, 0, 0,
-  37, 0, 0, 0, 0, 6, 28, 0, 0, 0,
-  0, 19, 26, 0, 3, 71, 33, 50, 0, 0,
-  10, 18, 0, 54, 2, 0, 62, 0, 20, 53,
-  0, 0, 0, 10, 0, 34, 0, 0, 19, 0,
-  50, 13, 6, 0, 30, 11, 7, 22, 34, 0,
-  0, 109, 0, 6, 0, 0, 0, 0, 36, 46,
-  17, 32, 7, 0, 17, 0, 0, 18, 0, 40,
-  0, 25, 0, 9, 51, 0, 0, 9, 68, 0,
-  0, 9, 34, 0, 14, 0, 50, 0, 5, 13,
-  0, 32, 19, 0, 8, 0, 42, 4, 0, 13,
-  0, 36, 0, 0, 0, 57, 0, 20, 78, 0,
-  62, 17, 0, 0, 48, 0, 0, 0, 23, 0,
-  0, 0, 0, 0, 0, 22, 0, 0, 41, 0,
-  0, 33, 9, 0, 6, 0, 0, 0, 32, 6,
-  0, 0, 33, 0, 37, 0, 4, 0, 0, 39,
-  62, 0, 84, 8, 32, 22, 0, 130, 0, 9,
-  16, 0, 0, 9, 33, 13, 0, 0, 29, 13,
-  0, 22, 32, 0, 33, 0, 24, 0, 0, 28,
-  10, 0, 0, 0, 8, 0, 32, 0, 10, 12,
-  0, 0, 0, 0, 0, 83, 0, 0, 2, 0,
-  0, 0, 98, 36, 46, 0, 18, 0, 8, 0,
-  0, 0, 0, 28, 8, 0, 11, 29, 0, 45,
-  2, 0, 17, 0, 59, 0, 0, 24, 0, 0,
-  0, 0, 0, 40, 1, 11, 70, 0, 8, 10,
-  0, 0, 32, 0, 0, 0, 26, 22, 0, 7,
-  0, 0, 17, 26, 2, 0, 47, 0, 0, 21,
-  13, 9, 8, 0, 0, 0, 39, 2, 0, 18,
-  67, 54, 46, 0, 21, 0, 0, 41, 60, 20,
-  72, 13, 27, 31, 0, 123, 0, 13, 17, 0,
-  0, 28, 28, 13, 17, 0, 23, 19, 0, 3,
-  26, 0, 27, 0, 23, 0, 0, 39, 0, 0,
-  0, 3, 33, 0, 52, 9, 4, 75, 0, 0,
-  0, 0, 0, 100, 0, 0, 2, 0, 0, 11,
-  51, 34, 23, 0, 31, 0, 14, 0, 0, 0,
-  3, 31, 7, 0, 11, 24, 0, 20, 0, 8,
-  0, 0, 72, 0, 0, 35, 0, 0, 0, 0,
-  0, 45, 6, 0, 35, 11, 0, 11, 0, 0,
-  13, 0, 0, 0, 2, 13, 0, 0, 0, 0,
-  29, 44, 34, 0, 50, 0, 0, 11, 0, 7,
-  0, 0, 0, 0, 8, 60, 0, 0, 108, 136,
-  34, 5, 37, 0, 0, 24, 71, 27, 134, 39,
-  0, 0, 0, 158, 66, 0, 9, 0, 0, 10,
-  0, 0, 39, 0, 9, 0, 13, 5, 9, 0,
-  4, 0, 70, 0, 0, 80, 0, 0, 27, 0,
-  26, 0, 39, 45, 33, 130, 0, 0, 0, 0,
-  0, 84, 0, 0, 0, 0, 0, 24, 23, 13,
-  0, 0, 36, 0, 0, 0, 0, 0, 23, 31,
-  12, 0, 0, 47, 0, 0, 0, 0, 99, 35,
-  39, 50, 0, 17, 0, 0, 7, 70, 34, 67,
-  46, 6, 16, 0, 0, 47, 51, 51, 43, 68,
-  129, 40, 9, 0, 53, 0, 19, 0, 0, 3,
-  0, 46, 0, 0, 4, 18, 0, 21, 43, 0,
-  0, 29, 3, 44, 51, 16, 0, 0, 8, 61,
-  0, 57, 0, 8, 10, 70, 0, 30, 41, 15,
-  26, 0, 0, 5, 28, 0, 43, 38, 0, 0,
-  35, 0, 53, 27, 7, 21, 30, 0, 31, 28,
-  62, 0, 36, 0, 0, 42, 1, 0, 11, 10,
-  39, 35, 0, 0, 24, 0, 67, 0, 0, 27,
-  42, 50, 46, 18, 14, 0, 25, 0, 0, 33,
-  56, 0, 33, 24, 74, 0, 21, 0, 46, 9,
-  0, 40, 0, 0, 5, 0, 79, 51, 29, 30,
-  0, 28, 9, 0, 6, 57, 44, 75, 60, 18,
-  9, 0, 0, 32, 53, 70, 33, 61, 135, 47,
-  36, 0, 45, 8, 29, 0, 0, 4, 0, 55,
-  0, 0, 25, 9, 0, 4, 34, 0, 0, 18,
-  21, 51, 44, 48, 0, 10, 3, 61, 0, 58,
-  0, 0, 12, 61, 0, 22, 46, 13, 15, 0,
-  0, 2, 14, 0, 34, 33, 0, 3, 31, 0,
-  57, 9, 0, 22, 46, 0, 23, 34, 53, 5,
-  53, 2, 0, 39, 29, 0, 36, 10, 25, 36,
-  0, 0, 19, 0, 58, 0, 0, 20, 53, 51,
-  44, 24, 38, 2, 31, 0, 0, 13, 50, 0,
-  40, 53, 98, 0, 37, 0, 54, 1, 0, 57,
-  0, 0, 7, 0, 75, 49, 21, 35, 0, 26,
-  12, 9, 20, 56, 23, 65, 41, 43, 0, 0,
-  0, 51, 49, 70, 25, 60, 128, 38, 16, 1,
-  47, 0, 34, 0, 0, 0, 0, 68, 0, 0,
-  51, 15, 10, 0, 33, 0, 0, 22, 41, 66,
-  39, 66, 0, 5, 0, 59, 0, 43, 0, 0,
-  13, 40, 0, 20, 49, 2, 9, 0, 0, 5,
-  40, 0, 43, 31, 0, 19, 43, 2, 80, 35,
-  0, 14, 27, 0, 17, 32, 100, 3, 76, 2,
-  0, 16, 24, 9, 46, 5, 10, 44, 0, 0,
-  7, 0, 65, 0, 4, 31, 54, 32, 37, 0,
-  31, 0, 29, 0, 0, 0, 10, 17, 45, 22,
-  97, 0, 76, 0, 23, 0, 0, 29, 0, 0,
-  0, 0, 15, 0, 80, 38, 0, 0, 0, 0,
-  0, 0, 0, 35, 26, 0, 14, 0, 0, 45,
-  31, 0, 42, 64, 0, 0, 16, 0, 0, 5,
-  0, 0, 32, 60, 1, 0, 52, 0, 0, 0,
-  0, 15, 40, 0, 0, 0, 0, 2, 11, 0,
-  19, 50, 26, 49, 0, 0, 6, 43, 3, 66,
-  19, 0, 76, 0, 18, 84, 0, 0, 2, 19,
-  0, 39, 0, 5, 14, 0, 39, 27, 3, 12,
-  27, 17, 21, 31, 23, 0, 0, 98, 2, 0,
-  0, 0, 0, 0, 39, 39, 30, 37, 0, 0,
-  15, 0, 0, 33, 0, 44, 1, 9, 0, 0,
-  55, 0, 0, 24, 71, 0, 0, 0, 0, 0,
-  0, 0, 42, 0, 0, 21, 0, 0, 2, 0,
-  15, 0, 74, 29, 0, 18, 0, 12, 0, 34,
-  16, 63, 31, 0, 0, 0, 0, 43, 15, 0,
-  18, 55, 0, 0, 44, 0, 0, 15, 0, 0,
-  19, 53, 0, 0, 37, 0, 0, 0, 0, 6,
-  28, 0, 0, 0, 0, 19, 26, 0, 3, 71,
-  33, 50, 0, 0, 10, 18, 0, 54, 2, 0,
-  62, 0, 20, 53, 0, 0, 0, 10, 0, 34,
-  0, 0, 19, 0, 50, 13, 6, 0, 30, 11,
-  7, 22, 34, 0, 0, 109, 0, 6, 0, 0,
-  0, 0, 36, 46, 17, 32, 7, 0, 17, 0,
-  0, 18, 0, 40, 0, 25, 0, 9, 51, 0,
-  0, 9, 68, 0, 0, 9, 34, 0, 14, 0,
-  50, 0, 0, 44, 0, 0, 11, 0, 30, 0,
-  44, 53, 0, 11, 18, 12, 0, 82, 51, 71,
-  16, 19, 0, 0, 0, 63, 28, 37, 0, 67,
-  2, 0, 45, 0, 33, 25, 0, 0, 0, 52,
-  0, 0, 18, 0, 13, 17, 0, 3, 20, 20,
-  0, 7, 2, 12, 49, 14, 0, 32, 19, 44,
-  0, 21, 12, 0, 0, 24, 0, 0, 80, 1,
-  40, 3, 0, 0, 8, 26, 18, 45, 0, 0,
-  0, 0, 87, 25, 0, 0, 27, 11, 0, 26,
-  28, 6, 18, 90, 0, 29, 0, 0, 0, 0,
-  0, 71, 9, 2, 14, 0, 37, 0, 0, 24,
-  1, 42, 0, 27, 0, 6, 32, 0, 0, 6,
-  43, 0, 9, 0, 103, 0, 43, 0, 51, 0,
-  11, 29, 0, 45, 2, 0, 17, 0, 59, 0,
-  0, 24, 0, 0, 0, 0, 0, 40, 1, 11,
-  70, 0, 8, 10, 0, 0, 32, 0, 0, 0,
-  26, 22, 0, 7, 0, 0, 17, 26, 2, 0,
-  47, 0, 0, 21, 13, 9, 8, 0, 0, 0,
-  39, 2, 0, 18, 67, 54, 46, 0, 21, 0,
-  0, 41, 60, 20, 72, 13, 27, 31, 0, 123,
-  0, 13, 17, 0, 0, 28, 28, 13, 17, 0,
-  23, 19, 0, 3, 26, 0, 27, 0, 23, 0,
-  0, 39, 0, 0, 0, 3, 33, 0, 52, 9,
-  4, 75, 0, 0, 0, 0, 0, 100, 0, 0,
-  2, 0, 0, 11, 51, 34, 23, 0, 31, 0,
-  14, 0, 0, 0, 3, 31, 7, 0, 11, 24,
-  0, 20, 0, 8, 0, 0, 72, 0, 0, 35,
-  0, 0, 0, 0, 0, 45, 6, 0, 35, 11,
-  0, 11, 0, 0, 13, 0, 0, 0, 2, 13,
-  0, 0, 0, 0, 29, 44, 34, 0, 50, 0,
-  0, 11, 0, 7, 0, 0, 0, 0, 8, 60,
-  0, 0, 108, 136, 34, 5, 37, 0, 0, 24,
-  71, 27, 134, 39, 0, 0, 0, 158, 66, 0,
-  9, 0, 0, 10, 0, 0, 39, 0, 9, 0,
-  13, 5, 9, 0, 4, 0, 70, 0, 0, 80,
-  0, 0, 27, 0, 26, 0, 39, 45, 33, 130,
-  0, 0, 0, 0, 0, 84, 0, 0, 0, 0,
-  0, 24, 23, 13, 0, 0, 36, 0, 0, 0,
-  0, 0, 23, 31, 12, 0, 0, 15, 0, 0,
-  0, 50, 0, 0, 53, 14, 0, 2, 0, 0,
-  0, 0, 0, 48, 12, 0, 0, 0, 0, 19,
-  0, 0, 0, 3, 0, 0, 3, 11, 0, 0,
-  0, 9, 43, 82, 35, 0, 70, 0, 5, 16,
-  0, 7, 7, 0, 0, 0, 0, 63, 0, 0,
-  57, 160, 47, 9, 35, 0, 0, 29, 57, 0,
-  153, 4, 0, 0, 0, 121, 122, 0, 14, 27,
-  0, 33, 0, 0, 46, 0, 6, 0, 5, 13,
-  16, 0, 0, 10, 64, 0, 0, 128, 0, 0,
-  35, 0, 0, 0, 10, 76, 58, 96, 0, 0,
-  0, 0, 0, 62, 0, 0, 0, 3, 0, 35,
-  0, 0, 0, 0, 53, 0, 0, 0, 0, 0,
-  18, 28, 29, 0, 0, 40, 0, 0, 5, 0,
-  79, 51, 29, 30, 0, 28, 9, 0, 6, 57,
-  44, 75, 60, 18, 9, 0, 0, 32, 53, 70,
-  33, 61, 135, 47, 36, 0, 45, 8, 29, 0,
-  0, 4, 0, 55, 0, 0, 25, 9, 0, 4,
-  34, 0, 0, 18, 21, 51, 44, 48, 0, 10,
-  3, 61, 0, 58, 0, 0, 12, 61, 0, 22,
-  46, 13, 15, 0, 0, 2, 14, 0, 34, 33,
-  0, 3, 31, 0, 57, 9, 0, 22, 46, 0,
-  23, 34, 53, 5, 53, 2, 0, 39, 29, 0,
-  36, 10, 25, 36, 0, 0, 19, 0, 58, 0,
-  0, 20, 53, 51, 44, 24, 38, 2, 31, 0,
-  0, 13, 50, 0, 40, 53, 98, 0, 37, 0,
-  54, 1, 0, 57, 0, 0, 7, 0, 75, 49,
-  21, 35, 0, 26, 12, 9, 20, 56, 23, 65,
-  41, 43, 0, 0, 0, 51, 49, 70, 25, 60,
-  128, 38, 16, 1, 47, 0, 34, 0, 0, 0,
-  0, 68, 0, 0, 51, 15, 10, 0, 33, 0,
-  0, 22, 41, 66, 39, 66, 0, 5, 0, 59,
-  0, 43, 0, 0, 13, 40, 0, 20, 49, 2,
-  9, 0, 0, 5, 40, 0, 43, 31, 0, 19,
-  43, 2, 80, 35, 0, 14, 27, 0, 17, 32,
-  100, 3, 76, 2, 0, 16, 24, 9, 46, 5,
-  10, 44, 0, 0, 7, 0, 65, 0, 4, 31,
-  54, 32, 37, 0, 31, 0, 29, 0, 0, 0,
-  10, 17, 45, 22, 97, 0, 76, 0, 23, 0,
-  0, 100, 25, 10, 0, 0, 70, 30, 19, 50,
-  0, 57, 14, 13, 11, 54, 10, 51, 32, 74,
-  0, 0, 0, 42, 41, 47, 55, 47, 140, 28,
-  0, 6, 69, 0, 51, 0, 0, 0, 0, 61,
-  0, 0, 55, 28, 10, 25, 39, 0, 0, 40,
-  29, 63, 62, 56, 3, 0, 0, 4, 0, 42,
-  0, 0, 18, 10, 0, 13, 27, 0, 4, 2,
-  3, 7, 57, 0, 55, 33, 0, 39, 43, 0,
-  86, 34, 0, 21, 5, 0, 34, 32, 104, 0,
-  59, 5, 0, 0, 22, 8, 33, 0, 3, 36,
-  0, 11, 27, 0, 66, 0, 37, 39, 34, 16,
-  38, 0, 27, 2, 5, 0, 0, 0, 0, 19,
-  44, 4, 64, 0, 73, 0, 11, 0, 0, 21,
-  0, 0, 2, 0, 15, 0, 74, 29, 0, 18,
-  0, 12, 0, 34, 16, 63, 31, 0, 0, 0,
-  0, 43, 15, 0, 18, 55, 0, 0, 44, 0,
-  0, 15, 0, 0, 19, 53, 0, 0, 37, 0,
-  0, 0, 0, 6, 28, 0, 0, 0, 0, 19,
-  26, 0, 3, 71, 33, 50, 0, 0, 10, 18,
-  0, 54, 2, 0, 62, 0, 20, 53, 0, 0,
-  0, 10, 0, 34, 0, 0, 19, 0, 50, 13,
-  6, 0, 30, 11, 7, 22, 34, 0, 0, 109,
-  0, 6, 0, 0, 0, 0, 36, 46, 17, 32,
-  7, 0, 17, 0, 0, 18, 0, 40, 0, 25,
-  0, 9, 51, 0, 0, 9, 68, 0, 0, 9,
-  34, 0, 14, 0, 50, 0, 0, 44, 0, 0,
-  11, 0, 30, 0, 44, 53, 0, 11, 18, 12,
-  0, 82, 51, 71, 16, 19, 0, 0, 0, 63,
-  28, 37, 0, 67, 2, 0, 45, 0, 33, 25,
-  0, 0, 0, 52, 0, 0, 18, 0, 13, 17,
-  0, 3, 20, 20, 0, 7, 2, 12, 49, 14,
-  0, 32, 19, 44, 0, 21, 12, 0, 0, 24,
-  0, 0, 80, 1, 40, 3, 0, 0, 8, 26,
-  18, 45, 0, 0, 0, 0, 87, 25, 0, 0,
-  27, 11, 0, 26, 28, 6, 18, 90, 0, 29,
-  0, 0, 0, 0, 0, 71, 9, 2, 14, 0,
-  37, 0, 0, 24, 1, 42, 0, 27, 0, 6,
-  32, 0, 0, 6, 43, 0, 9, 0, 103, 0,
-  43, 0, 51, 0, 0, 102, 14, 0, 4, 0,
-  39, 0, 27, 51, 8, 13, 23, 3, 26, 91,
-  67, 61, 21, 56, 0, 0, 0, 56, 53, 69,
-  6, 74, 0, 0, 14, 0, 81, 1, 0, 0,
-  0, 25, 0, 38, 0, 16, 42, 22, 1, 7,
-  22, 19, 0, 49, 2, 1, 68, 52, 0, 0,
-  0, 9, 0, 50, 0, 0, 0, 0, 0, 0,
-  91, 11, 34, 0, 0, 0, 15, 26, 42, 23,
-  0, 6, 0, 4, 107, 11, 0, 0, 11, 8,
-  10, 15, 30, 12, 42, 45, 0, 41, 0, 10,
-  0, 0, 0, 81, 0, 0, 14, 0, 46, 0,
-  23, 15, 32, 37, 0, 0, 0, 0, 0, 0,
-  0, 0, 12, 0, 30, 11, 149, 0, 76, 0,
-  46, 0, 11, 24, 0, 20, 0, 8, 0, 0,
-  72, 0, 0, 35, 0, 0, 0, 0, 0, 45,
-  6, 0, 35, 11, 0, 11, 0, 0, 13, 0,
-  0, 0, 2, 13, 0, 0, 0, 0, 29, 44,
-  34, 0, 50, 0, 0, 11, 0, 7, 0, 0,
-  0, 0, 8, 60, 0, 0, 108, 136, 34, 5,
-  37, 0, 0, 24, 71, 27, 134, 39, 0, 0,
-  0, 158, 66, 0, 9, 0, 0, 10, 0, 0,
-  39, 0, 9, 0, 13, 5, 9, 0, 4, 0,
-  70, 0, 0, 80, 0, 0, 27, 0, 26, 0,
-  39, 45, 33, 130, 0, 0, 0, 0, 0, 84,
-  0, 0, 0, 0, 0, 24, 23, 13, 0, 0,
-  36, 0, 0, 0, 0, 0, 23, 31, 12, 0,
-  0, 15, 0, 0, 0, 50, 0, 0, 53, 14,
-  0, 2, 0, 0, 0, 0, 0, 48, 12, 0,
-  0, 0, 0, 19, 0, 0, 0, 3, 0, 0,
-  3, 11, 0, 0, 0, 9, 43, 82, 35, 0,
-  70, 0, 5, 16, 0, 7, 7, 0, 0, 0,
-  0, 63, 0, 0, 57, 160, 47, 9, 35, 0,
-  0, 29, 57, 0, 153, 4, 0, 0, 0, 121,
-  122, 0, 14, 27, 0, 33, 0, 0, 46, 0,
-  6, 0, 5, 13, 16, 0, 0, 10, 64, 0,
-  0, 128, 0, 0, 35, 0, 0, 0, 10, 76,
-  58, 96, 0, 0, 0, 0, 0, 62, 0, 0,
-  0, 3, 0, 35, 0, 0, 0, 0, 53, 0,
-  0, 0, 0, 0, 18, 28, 29, 0, 0, 39,
-  0, 0, 0, 29, 0, 0, 78, 47, 0, 0,
-  30, 0, 0, 88, 39, 61, 6, 17, 0, 0,
-  0, 41, 0, 0, 7, 53, 6, 0, 17, 0,
-  36, 0, 0, 0, 35, 96, 0, 0, 48, 0,
-  9, 30, 0, 28, 42, 19, 0, 0, 0, 32,
-  2, 0, 4, 101, 46, 8, 0, 0, 0, 0,
-  0, 0, 66, 0, 6, 4, 24, 53, 52, 0,
-  17, 37, 0, 49, 0, 0, 5, 0, 39, 0,
-  0, 0, 0, 1, 0, 30, 51, 0, 0, 131,
-  0, 0, 11, 0, 0, 0, 0, 86, 87, 31,
-  0, 0, 0, 0, 0, 48, 0, 13, 0, 11,
-  0, 8, 2, 0, 0, 2, 51, 0, 25, 0,
-  41, 0, 28, 12, 43, 0, 0, 57, 0, 0,
-  7, 0, 75, 49, 21, 35, 0, 26, 12, 9,
-  20, 56, 23, 65, 41, 43, 0, 0, 0, 51,
-  49, 70, 25, 60, 128, 38, 16, 1, 47, 0,
-  34, 0, 0, 0, 0, 68, 0, 0, 51, 15,
-  10, 0, 33, 0, 0, 22, 41, 66, 39, 66,
-  0, 5, 0, 59, 0, 43, 0, 0, 13, 40,
-  0, 20, 49, 2, 9, 0, 0, 5, 40, 0,
-  43, 31, 0, 19, 43, 2, 80, 35, 0, 14,
-  27, 0, 17, 32, 100, 3, 76, 2, 0, 16,
-  24, 9, 46, 5, 10, 44, 0, 0, 7, 0,
-  65, 0, 4, 31, 54, 32, 37, 0, 31, 0,
-  29, 0, 0, 0, 10, 17, 45, 22, 97, 0,
-  76, 0, 23, 0, 0, 100, 25, 10, 0, 0,
-  70, 30, 19, 50, 0, 57, 14, 13, 11, 54,
-  10, 51, 32, 74, 0, 0, 0, 42, 41, 47,
-  55, 47, 140, 28, 0, 6, 69, 0, 51, 0,
-  0, 0, 0, 61, 0, 0, 55, 28, 10, 25,
-  39, 0, 0, 40, 29, 63, 62, 56, 3, 0,
-  0, 4, 0, 42, 0, 0, 18, 10, 0, 13,
-  27, 0, 4, 2, 3, 7, 57, 0, 55, 33,
-  0, 39, 43, 0, 86, 34, 0, 21, 5, 0,
-  34, 32, 104, 0, 59, 5, 0, 0, 22, 8,
-  33, 0, 3, 36, 0, 11, 27, 0, 66, 0,
-  37, 39, 34, 16, 38, 0, 27, 2, 5, 0,
-  0, 0, 0, 19, 44, 4, 64, 0, 73, 0,
-  11, 0, 0, 123, 31, 8, 0, 0, 58, 2,
-  5, 19, 0, 61, 49, 0, 0, 22, 6, 34,
-  22, 59, 0, 0, 47, 46, 38, 9, 61, 16,
-  179, 16, 0, 0, 76, 0, 51, 37, 0, 0,
-  40, 47, 0, 0, 71, 33, 17, 78, 26, 17,
-  0, 47, 0, 63, 77, 0, 7, 0, 7, 0,
-  0, 10, 13, 30, 0, 26, 0, 3, 14, 0,
-  1, 0, 72, 10, 34, 0, 44, 21, 8, 54,
-  16, 0, 64, 0, 25, 21, 0, 5, 39, 21,
-  53, 0, 0, 0, 23, 0, 9, 12, 0, 0,
-  0, 25, 0, 51, 27, 5, 41, 0, 55, 0,
-  0, 34, 30, 0, 0, 7, 0, 0, 0, 10,
-  31, 34, 58, 5, 0, 0, 20, 0, 0, 0,
-  0, 44, 0, 0, 11, 0, 30, 0, 44, 53,
-  0, 11, 18, 12, 0, 82, 51, 71, 16, 19,
-  0, 0, 0, 63, 28, 37, 0, 67, 2, 0,
-  45, 0, 33, 25, 0, 0, 0, 52, 0, 0,
-  18, 0, 13, 17, 0, 3, 20, 20, 0, 7,
-  2, 12, 49, 14, 0, 32, 19, 44, 0, 21,
-  12, 0, 0, 24, 0, 0, 80, 1, 40, 3,
-  0, 0, 8, 26, 18, 45, 0, 0, 0, 0,
-  87, 25, 0, 0, 27, 11, 0, 26, 28, 6,
-  18, 90, 0, 29, 0, 0, 0, 0, 0, 71,
-  9, 2, 14, 0, 37, 0, 0, 24, 1, 42,
-  0, 27, 0, 6, 32, 0, 0, 6, 43, 0,
-  9, 0, 103, 0, 43, 0, 51, 0, 0, 102,
-  14, 0, 4, 0, 39, 0, 27, 51, 8, 13,
-  23, 3, 26, 91, 67, 61, 21, 56, 0, 0,
-  0, 56, 53, 69, 6, 74, 0, 0, 14, 0,
-  81, 1, 0, 0, 0, 25, 0, 38, 0, 16,
-  42, 22, 1, 7, 22, 19, 0, 49, 2, 1,
-  68, 52, 0, 0, 0, 9, 0, 50, 0, 0,
-  0, 0, 0, 0, 91, 11, 34, 0, 0, 0,
-  15, 26, 42, 23, 0, 6, 0, 4, 107, 11,
-  0, 0, 11, 8, 10, 15, 30, 12, 42, 45,
-  0, 41, 0, 10, 0, 0, 0, 81, 0, 0,
-  14, 0, 46, 0, 23, 15, 32, 37, 0, 0,
-  0, 0, 0, 0, 0, 0, 12, 0, 30, 11,
-  149, 0, 76, 0, 46, 0, 0, 131, 52, 5,
-  17, 0, 45, 0, 11, 44, 5, 23, 60, 0,
-  17, 55, 55, 49, 15, 72, 0, 0, 12, 32,
-  54, 53, 11, 54, 0, 20, 0, 0, 76, 0,
-  17, 0, 0, 0, 0, 41, 0, 25, 68, 41,
-  28, 22, 40, 0, 0, 52, 0, 3, 85, 24,
-  0, 0, 0, 0, 0, 44, 4, 0, 0, 5,
-  0, 0, 29, 13, 13, 0, 0, 0, 8, 16,
-  74, 5, 15, 32, 0, 0, 97, 0, 0, 0,
-  14, 0, 30, 16, 22, 9, 0, 0, 0, 20,
-  0, 26, 0, 0, 0, 38, 5, 16, 9, 0,
-  39, 0, 48, 8, 25, 53, 0, 0, 0, 5,
-  0, 0, 0, 24, 33, 0, 34, 5, 77, 0,
-  62, 0, 29, 0, 0, 15, 0, 0, 0, 50,
-  0, 0, 53, 14, 0, 2, 0, 0, 0, 0,
-  0, 48, 12, 0, 0, 0, 0, 19, 0, 0,
-  0, 3, 0, 0, 3, 11, 0, 0, 0, 9,
-  43, 82, 35, 0, 70, 0, 5, 16, 0, 7,
-  7, 0, 0, 0, 0, 63, 0, 0, 57, 160,
-  47, 9, 35, 0, 0, 29, 57, 0, 153, 4,
-  0, 0, 0, 121, 122, 0, 14, 27, 0, 33,
-  0, 0, 46, 0, 6, 0, 5, 13, 16, 0,
-  0, 10, 64, 0, 0, 128, 0, 0, 35, 0,
-  0, 0, 10, 76, 58, 96, 0, 0, 0, 0,
-  0, 62, 0, 0, 0, 3, 0, 35, 0, 0,
-  0, 0, 53, 0, 0, 0, 0, 0, 18, 28,
-  29, 0, 0, 39, 0, 0, 0, 29, 0, 0,
-  78, 47, 0, 0, 30, 0, 0, 88, 39, 61,
-  6, 17, 0, 0, 0, 41, 0, 0, 7, 53,
-  6, 0, 17, 0, 36, 0, 0, 0, 35, 96,
-  0, 0, 48, 0, 9, 30, 0, 28, 42, 19,
-  0, 0, 0, 32, 2, 0, 4, 101, 46, 8,
-  0, 0, 0, 0, 0, 0, 66, 0, 6, 4,
-  24, 53, 52, 0, 17, 37, 0, 49, 0, 0,
-  5, 0, 39, 0, 0, 0, 0, 1, 0, 30,
-  51, 0, 0, 131, 0, 0, 11, 0, 0, 0,
-  0, 86, 87, 31, 0, 0, 0, 0, 0, 48,
-  0, 13, 0, 11, 0, 8, 2, 0, 0, 2,
-  51, 0, 25, 0, 41, 0, 28, 12, 43, 0,
-  0, 93, 41, 0, 7, 0, 52, 3, 86, 40,
-  12, 0, 76, 3, 0, 125, 70, 39, 2, 33,
-  0, 0, 0, 54, 36, 13, 16, 61, 3, 0,
-  21, 0, 90, 1, 0, 0, 0, 58, 0, 29,
-  9, 0, 26, 52, 0, 59, 72, 36, 0, 44,
-  0, 0, 84, 12, 0, 0, 22, 0, 0, 42,
-  0, 0, 0, 0, 0, 0, 47, 0, 62, 0,
-  0, 0, 2, 50, 38, 28, 0, 0, 0, 0,
-  77, 11, 8, 0, 0, 21, 0, 22, 43, 0,
-  0, 57, 0, 32, 0, 0, 0, 0, 0, 79,
-  66, 0, 0, 0, 15, 0, 10, 29, 0, 69,
-  0, 1, 0, 0, 0, 0, 0, 36, 65, 0,
-  62, 0, 139, 0, 57, 16, 25, 0, 0, 100,
-  25, 10, 0, 0, 70, 30, 19, 50, 0, 57,
-  14, 13, 11, 54, 10, 51, 32, 74, 0, 0,
-  0, 42, 41, 47, 55, 47, 140, 28, 0, 6,
-  69, 0, 51, 0, 0, 0, 0, 61, 0, 0,
-  55, 28, 10, 25, 39, 0, 0, 40, 29, 63,
-  62, 56, 3, 0, 0, 4, 0, 42, 0, 0,
-  18, 10, 0, 13, 27, 0, 4, 2, 3, 7,
-  57, 0, 55, 33, 0, 39, 43, 0, 86, 34,
-  0, 21, 5, 0, 34, 32, 104, 0, 59, 5,
-  0, 0, 22, 8, 33, 0, 3, 36, 0, 11,
-  27, 0, 66, 0, 37, 39, 34, 16, 38, 0,
-  27, 2, 5, 0, 0, 0, 0, 19, 44, 4,
-  64, 0, 73, 0, 11, 0, 0, 123, 31, 8,
-  0, 0, 58, 2, 5, 19, 0, 61, 49, 0,
-  0, 22, 6, 34, 22, 59, 0, 0, 47, 46,
-  38, 9, 61, 16, 179, 16, 0, 0, 76, 0,
-  51, 37, 0, 0, 40, 47, 0, 0, 71, 33,
-  17, 78, 26, 17, 0, 47, 0, 63, 77, 0,
-  7, 0, 7, 0, 0, 10, 13, 30, 0, 26,
-  0, 3, 14, 0, 1, 0, 72, 10, 34, 0,
-  44, 21, 8, 54, 16, 0, 64, 0, 25, 21,
-  0, 5, 39, 21, 53, 0, 0, 0, 23, 0,
-  9, 12, 0, 0, 0, 25, 0, 51, 27, 5,
-  41, 0, 55, 0, 0, 34, 30, 0, 0, 7,
-  0, 0, 0, 10, 31, 34, 58, 5, 0, 0,
-  20, 0, 0, 0, 5, 63, 0, 6, 0, 6,
-  70, 9, 0, 0, 0, 80, 68, 0, 0, 0,
-  4, 24, 17, 28, 10, 34, 89, 45, 45, 0,
-  53, 4, 206, 0, 0, 11, 57, 5, 17, 54,
-  0, 0, 60, 39, 0, 0, 1, 61, 12, 128,
-  21, 26, 0, 14, 0, 73, 56, 0, 20, 6,
-  28, 0, 28, 0, 56, 44, 0, 46, 15, 2,
-  13, 32, 46, 0, 134, 11, 24, 0, 54, 0,
-  56, 54, 12, 0, 36, 0, 34, 0, 0, 7,
-  35, 1, 23, 0, 0, 0, 35, 0, 0, 29,
-  0, 0, 59, 43, 6, 53, 7, 33, 53, 18,
-  22, 0, 0, 36, 0, 23, 0, 10, 0, 29,
-  0, 20, 61, 20, 68, 0, 0, 0, 0, 0,
-  0, 0, 0, 102, 14, 0, 4, 0, 39, 0,
-  27, 51, 8, 13, 23, 3, 26, 91, 67, 61,
-  21, 56, 0, 0, 0, 56, 53, 69, 6, 74,
-  0, 0, 14, 0, 81, 1, 0, 0, 0, 25,
-  0, 38, 0, 16, 42, 22, 1, 7, 22, 19,
-  0, 49, 2, 1, 68, 52, 0, 0, 0, 9,
-  0, 50, 0, 0, 0, 0, 0, 0, 91, 11,
-  34, 0, 0, 0, 15, 26, 42, 23, 0, 6,
-  0, 4, 107, 11, 0, 0, 11, 8, 10, 15,
-  30, 12, 42, 45, 0, 41, 0, 10, 0, 0,
-  0, 81, 0, 0, 14, 0, 46, 0, 23, 15,
-  32, 37, 0, 0, 0, 0, 0, 0, 0, 0,
-  12, 0, 30, 11, 149, 0, 76, 0, 46, 0,
-  0, 131, 52, 5, 17, 0, 45, 0, 11, 44,
-  5, 23, 60, 0, 17, 55, 55, 49, 15, 72,
-  0, 0, 12, 32, 54, 53, 11, 54, 0, 20,
-  0, 0, 76, 0, 17, 0, 0, 0, 0, 41,
-  0, 25, 68, 41, 28, 22, 40, 0, 0, 52,
-  0, 3, 85, 24, 0, 0, 0, 0, 0, 44,
-  4, 0, 0, 5, 0, 0, 29, 13, 13, 0,
-  0, 0, 8, 16, 74, 5, 15, 32, 0, 0,
-  97, 0, 0, 0, 14, 0, 30, 16, 22, 9,
-  0, 0, 0, 20, 0, 26, 0, 0, 0, 38,
-  5, 16, 9, 0, 39, 0, 48, 8, 25, 53,
-  0, 0, 0, 5, 0, 0, 0, 24, 33, 0,
-  34, 5, 77, 0, 62, 0, 29, 0, 0, 75,
-  0, 0, 5, 14, 48, 1, 0, 0, 0, 56,
-  51, 0, 0, 4, 32, 10, 13, 41, 0, 10,
-  71, 13, 29, 0, 10, 14, 0, 17, 0, 0,
-  42, 0, 5, 27, 0, 0, 9, 20, 0, 26,
-  0, 66, 11, 74, 35, 26, 0, 2, 0, 16,
-  68, 0, 0, 0, 30, 0, 1, 5, 28, 45,
-  0, 49, 0, 0, 0, 37, 29, 0, 51, 0,
-  22, 9, 83, 12, 47, 23, 0, 0, 69, 0,
-  4, 0, 38, 0, 23, 2, 0, 0, 0, 0,
-  0, 6, 0, 38, 0, 0, 22, 49, 15, 29,
-  19, 13, 22, 0, 31, 11, 0, 28, 0, 0,
-  0, 0, 0, 0, 0, 19, 71, 6, 22, 4,
-  0, 0, 22, 0, 10, 0, 0, 39, 0, 0,
-  0, 29, 0, 0, 78, 47, 0, 0, 30, 0,
-  0, 88, 39, 61, 6, 17, 0, 0, 0, 41,
-  0, 0, 7, 53, 6, 0, 17, 0, 36, 0,
-  0, 0, 35, 96, 0, 0, 48, 0, 9, 30,
-  0, 28, 42, 19, 0, 0, 0, 32, 2, 0,
-  4, 101, 46, 8, 0, 0, 0, 0, 0, 0,
-  66, 0, 6, 4, 24, 53, 52, 0, 17, 37,
-  0, 49, 0, 0, 5, 0, 39, 0, 0, 0,
-  0, 1, 0, 30, 51, 0, 0, 131, 0, 0,
-  11, 0, 0, 0, 0, 86, 87, 31, 0, 0,
-  0, 0, 0, 48, 0, 13, 0, 11, 0, 8,
-  2, 0, 0, 2, 51, 0, 25, 0, 41, 0,
-  28, 12, 43, 0, 0, 93, 41, 0, 7, 0,
-  52, 3, 86, 40, 12, 0, 76, 3, 0, 125,
-  70, 39, 2, 33, 0, 0, 0, 54, 36, 13,
-  16, 61, 3, 0, 21, 0, 90, 1, 0, 0,
-  0, 58, 0, 29, 9, 0, 26, 52, 0, 59,
-  72, 36, 0, 44, 0, 0, 84, 12, 0, 0,
-  22, 0, 0, 42, 0, 0, 0, 0, 0, 0,
-  47, 0, 62, 0, 0, 0, 2, 50, 38, 28,
-  0, 0, 0, 0, 77, 11, 8, 0, 0, 21,
-  0, 22, 43, 0, 0, 57, 0, 32, 0, 0,
-  0, 0, 0, 79, 66, 0, 0, 0, 15, 0,
-  10, 29, 0, 69, 0, 1, 0, 0, 0, 0,
-  0, 36, 65, 0, 62, 0, 139, 0, 57, 16,
-  25, 0, 0, 58, 49, 0, 14, 0, 50, 16,
-  63, 8, 3, 26, 61, 1, 7, 53, 52, 0,
-  0, 15, 0, 27, 43, 19, 23, 0, 0, 13,
-  0, 0, 0, 0, 41, 0, 0, 6, 0, 16,
-  0, 79, 0, 24, 0, 55, 1, 70, 61, 46,
-  0, 21, 0, 20, 72, 1, 0, 0, 29, 0,
-  0, 0, 15, 36, 0, 43, 0, 14, 0, 0,
-  79, 0, 0, 0, 7, 27, 66, 15, 34, 28,
-  0, 0, 79, 0, 29, 0, 25, 0, 16, 0,
-  0, 0, 0, 0, 0, 17, 0, 26, 0, 0,
-  5, 71, 31, 0, 0, 0, 26, 0, 28, 0,
-  0, 38, 0, 0, 0, 2, 0, 0, 2, 14,
-  69, 0, 27, 0, 63, 0, 43, 7, 17, 0,
-  0, 123, 31, 8, 0, 0, 58, 2, 5, 19,
-  0, 61, 49, 0, 0, 22, 6, 34, 22, 59,
-  0, 0, 47, 46, 38, 9, 61, 16, 179, 16,
-  0, 0, 76, 0, 51, 37, 0, 0, 40, 47,
-  0, 0, 71, 33, 17, 78, 26, 17, 0, 47,
-  0, 63, 77, 0, 7, 0, 7, 0, 0, 10,
-  13, 30, 0, 26, 0, 3, 14, 0, 1, 0,
-  72, 10, 34, 0, 44, 21, 8, 54, 16, 0,
-  64, 0, 25, 21, 0, 5, 39, 21, 53, 0,
-  0, 0, 23, 0, 9, 12, 0, 0, 0, 25,
-  0, 51, 27, 5, 41, 0, 55, 0, 0, 34,
-  30, 0, 0, 7, 0, 0, 0, 10, 31, 34,
-  58, 5, 0, 0, 20, 0, 0, 0, 5, 63,
-  0, 6, 0, 6, 70, 9, 0, 0, 0, 80,
-  68, 0, 0, 0, 4, 24, 17, 28, 10, 34,
-  89, 45, 45, 0, 53, 4, 206, 0, 0, 11,
-  57, 5, 17, 54, 0, 0, 60, 39, 0, 0,
-  1, 61, 12, 128, 21, 26, 0, 14, 0, 73,
-  56, 0, 20, 6, 28, 0, 28, 0, 56, 44,
-  0, 46, 15, 2, 13, 32, 46, 0, 134, 11,
-  24, 0, 54, 0, 56, 54, 12, 0, 36, 0,
-  34, 0, 0, 7, 35, 1, 23, 0, 0, 0,
-  35, 0, 0, 29, 0, 0, 59, 43, 6, 53,
-  7, 33, 53, 18, 22, 0, 0, 36, 0, 23,
-  0, 10, 0, 29, 0, 20, 61, 20, 68, 0,
-  0, 0, 0, 0, 0, 0, 23, 19, 0, 34,
-  10, 9, 83, 40, 0, 0, 0, 24, 57, 8,
-  0, 49, 29, 55, 14, 27, 77, 6, 23, 33,
-  54, 0, 58, 20, 192, 4, 0, 22, 109, 15,
-  46, 0, 0, 37, 38, 5, 0, 0, 0, 70,
-  41, 137, 1, 46, 0, 13, 0, 79, 54, 2,
-  11, 54, 16, 0, 0, 0, 37, 0, 13, 6,
-  0, 0, 18, 17, 31, 11, 84, 0, 5, 0,
-  13, 0, 66, 45, 13, 0, 58, 0, 30, 0,
-  0, 0, 28, 0, 31, 38, 0, 18, 0, 18,
-  32, 25, 25, 0, 48, 37, 18, 2, 0, 55,
-  81, 0, 12, 13, 23, 14, 0, 32, 10, 37,
-  0, 0, 29, 0, 19, 21, 86, 0, 13, 0,
-  0, 0, 37, 12, 0, 131, 52, 5, 17, 0,
-  45, 0, 11, 44, 5, 23, 60, 0, 17, 55,
-  55, 49, 15, 72, 0, 0, 12, 32, 54, 53,
-  11, 54, 0, 20, 0, 0, 76, 0, 17, 0,
-  0, 0, 0, 41, 0, 25, 68, 41, 28, 22,
-  40, 0, 0, 52, 0, 3, 85, 24, 0, 0,
-  0, 0, 0, 44, 4, 0, 0, 5, 0, 0,
-  29, 13, 13, 0, 0, 0, 8, 16, 74, 5,
-  15, 32, 0, 0, 97, 0, 0, 0, 14, 0,
-  30, 16, 22, 9, 0, 0, 0, 20, 0, 26,
-  0, 0, 0, 38, 5, 16, 9, 0, 39, 0,
-  48, 8, 25, 53, 0, 0, 0, 5, 0, 0,
-  0, 24, 33, 0, 34, 5, 77, 0, 62, 0,
-  29, 0, 0, 75, 0, 0, 5, 14, 48, 1,
-  0, 0, 0, 56, 51, 0, 0, 4, 32, 10,
-  13, 41, 0, 10, 71, 13, 29, 0, 10, 14,
-  0, 17, 0, 0, 42, 0, 5, 27, 0, 0,
-  9, 20, 0, 26, 0, 66, 11, 74, 35, 26,
-  0, 2, 0, 16, 68, 0, 0, 0, 30, 0,
-  1, 5, 28, 45, 0, 49, 0, 0, 0, 37,
-  29, 0, 51, 0, 22, 9, 83, 12, 47, 23,
-  0, 0, 69, 0, 4, 0, 38, 0, 23, 2,
-  0, 0, 0, 0, 0, 6, 0, 38, 0, 0,
-  22, 49, 15, 29, 19, 13, 22, 0, 31, 11,
-  0, 28, 0, 0, 0, 0, 0, 0, 0, 19,
-  71, 6, 22, 4, 0, 0, 22, 0, 10, 0,
-  7, 18, 0, 16, 0, 21, 57, 17, 0, 0,
-  0, 41, 57, 2, 0, 6, 60, 44, 5, 5,
-  45, 0, 15, 0, 37, 0, 27, 0, 0, 35,
-  0, 0, 85, 0, 0, 0, 0, 5, 0, 0,
-  0, 23, 0, 64, 4, 113, 25, 79, 0, 0,
-  0, 41, 66, 0, 0, 22, 11, 0, 0, 0,
-  15, 0, 0, 2, 0, 0, 0, 36, 38, 0,
-  60, 0, 2, 0, 50, 0, 47, 0, 0, 0,
-  62, 0, 47, 0, 7, 0, 20, 0, 0, 8,
-  0, 4, 0, 8, 0, 7, 0, 0, 51, 44,
-  26, 26, 0, 37, 18, 0, 29, 6, 9, 13,
-  0, 18, 0, 17, 0, 0, 6, 0, 36, 0,
-  37, 0, 37, 0, 0, 0, 38, 0, 0, 93,
-  41, 0, 7, 0, 52, 3, 86, 40, 12, 0,
-  76, 3, 0, 125, 70, 39, 2, 33, 0, 0,
-  0, 54, 36, 13, 16, 61, 3, 0, 21, 0,
-  90, 1, 0, 0, 0, 58, 0, 29, 9, 0,
-  26, 52, 0, 59, 72, 36, 0, 44, 0, 0,
-  84, 12, 0, 0, 22, 0, 0, 42, 0, 0,
-  0, 0, 0, 0, 47, 0, 62, 0, 0, 0,
-  2, 50, 38, 28, 0, 0, 0, 0, 77, 11,
-  8, 0, 0, 21, 0, 22, 43, 0, 0, 57,
-  0, 32, 0, 0, 0, 0, 0, 79, 66, 0,
-  0, 0, 15, 0, 10, 29, 0, 69, 0, 1,
-  0, 0, 0, 0, 0, 36, 65, 0, 62, 0,
-  139, 0, 57, 16, 25, 0, 0, 58, 49, 0,
-  14, 0, 50, 16, 63, 8, 3, 26, 61, 1,
-  7, 53, 52, 0, 0, 15, 0, 27, 43, 19,
-  23, 0, 0, 13, 0, 0, 0, 0, 41, 0,
-  0, 6, 0, 16, 0, 79, 0, 24, 0, 55,
-  1, 70, 61, 46, 0, 21, 0, 20, 72, 1,
-  0, 0, 29, 0, 0, 0, 15, 36, 0, 43,
-  0, 14, 0, 0, 79, 0, 0, 0, 7, 27,
-  66, 15, 34, 28, 0, 0, 79, 0, 29, 0,
-  25, 0, 16, 0, 0, 0, 0, 0, 0, 17,
-  0, 26, 0, 0, 5, 71, 31, 0, 0, 0,
-  26, 0, 28, 0, 0, 38, 0, 0, 0, 2,
-  0, 0, 2, 14, 69, 0, 27, 0, 63, 0,
-  43, 7, 17, 0, 0, 6, 0, 0, 0, 1,
-  30, 12, 26, 0, 0, 25, 43, 0, 8, 23,
-  56, 23, 0, 0, 32, 29, 18, 2, 25, 0,
-  0, 0, 0, 0, 0, 0, 36, 17, 0, 0,
-  0, 0, 0, 34, 0, 11, 0, 58, 21, 87,
-  29, 59, 0, 1, 0, 52, 63, 0, 3, 0,
-  12, 0, 0, 0, 25, 4, 0, 38, 0, 10,
-  4, 0, 42, 0, 34, 0, 0, 17, 34, 0,
-  45, 41, 0, 0, 77, 0, 55, 0, 5, 0,
-  14, 0, 0, 0, 0, 31, 0, 0, 0, 22,
-  0, 0, 32, 57, 30, 0, 0, 9, 8, 0,
-  15, 0, 0, 13, 0, 14, 0, 2, 0, 0,
-  29, 0, 33, 0, 14, 0, 33, 0, 13, 6,
-  20, 0, 5, 63, 0, 6, 0, 6, 70, 9,
-  0, 0, 0, 80, 68, 0, 0, 0, 4, 24,
-  17, 28, 10, 34, 89, 45, 45, 0, 53, 4,
-  206, 0, 0, 11, 57, 5, 17, 54, 0, 0,
-  60, 39, 0, 0, 1, 61, 12, 128, 21, 26,
-  0, 14, 0, 73, 56, 0, 20, 6, 28, 0,
-  28, 0, 56, 44, 0, 46, 15, 2, 13, 32,
-  46, 0, 134, 11, 24, 0, 54, 0, 56, 54,
-  12, 0, 36, 0, 34, 0, 0, 7, 35, 1,
-  23, 0, 0, 0, 35, 0, 0, 29, 0, 0,
-  59, 43, 6, 53, 7, 33, 53, 18, 22, 0,
-  0, 36, 0, 23, 0, 10, 0, 29, 0, 20,
-  61, 20, 68, 0, 0, 0, 0, 0, 0, 0,
-  23, 19, 0, 34, 10, 9, 83, 40, 0, 0,
-  0, 24, 57, 8, 0, 49, 29, 55, 14, 27,
-  77, 6, 23, 33, 54, 0, 58, 20, 192, 4,
-  0, 22, 109, 15, 46, 0, 0, 37, 38, 5,
-  0, 0, 0, 70, 41, 137, 1, 46, 0, 13,
-  0, 79, 54, 2, 11, 54, 16, 0, 0, 0,
-  37, 0, 13, 6, 0, 0, 18, 17, 31, 11,
-  84, 0, 5, 0, 13, 0, 66, 45, 13, 0,
-  58, 0, 30, 0, 0, 0, 28, 0, 31, 38,
-  0, 18, 0, 18, 32, 25, 25, 0, 48, 37,
-  18, 2, 0, 55, 81, 0, 12, 13, 23, 14,
-  0, 32, 10, 37, 0, 0, 29, 0, 19, 21,
-  86, 0, 13, 0, 0, 0, 37, 12, 0, 33,
-  0, 8, 0, 0, 88, 51, 0, 25, 4, 29,
-  23, 1, 15, 91, 42, 50, 0, 22, 30, 0,
-  0, 49, 47, 30, 47, 45, 143, 63, 23, 6,
-  105, 25, 47, 0, 0, 39, 4, 30, 0, 3,
-  39, 25, 43, 65, 2, 47, 0, 56, 16, 77,
-  68, 39, 2, 24, 5, 0, 0, 43, 0, 0,
-  0, 26, 0, 4, 28, 0, 0, 0, 1, 21,
-  0, 0, 4, 46, 30, 14, 4, 0, 94, 0,
-  0, 19, 0, 0, 9, 3, 54, 33, 28, 12,
-  0, 25, 28, 16, 54, 0, 16, 44, 0, 0,
-  10, 24, 96, 0, 13, 21, 39, 36, 23, 10,
-  46, 34, 8, 0, 13, 0, 3, 31, 63, 19,
-  94, 0, 15, 0, 17, 0, 0, 75, 0, 0,
-  5, 14, 48, 1, 0, 0, 0, 56, 51, 0,
-  0, 4, 32, 10, 13, 41, 0, 10, 71, 13,
-  29, 0, 10, 14, 0, 17, 0, 0, 42, 0,
-  5, 27, 0, 0, 9, 20, 0, 26, 0, 66,
-  11, 74, 35, 26, 0, 2, 0, 16, 68, 0,
-  0, 0, 30, 0, 1, 5, 28, 45, 0, 49,
-  0, 0, 0, 37, 29, 0, 51, 0, 22, 9,
-  83, 12, 47, 23, 0, 0, 69, 0, 4, 0,
-  38, 0, 23, 2, 0, 0, 0, 0, 0, 6,
-  0, 38, 0, 0, 22, 49, 15, 29, 19, 13,
-  22, 0, 31, 11, 0, 28, 0, 0, 0, 0,
-  0, 0, 0, 19, 71, 6, 22, 4, 0, 0,
-  22, 0, 10, 0, 7, 18, 0, 16, 0, 21,
-  57, 17, 0, 0, 0, 41, 57, 2, 0, 6,
-  60, 44, 5, 5, 45, 0, 15, 0, 37, 0,
-  27, 0, 0, 35, 0, 0, 85, 0, 0, 0,
-  0, 5, 0, 0, 0, 23, 0, 64, 4, 113,
-  25, 79, 0, 0, 0, 41, 66, 0, 0, 22,
-  11, 0, 0, 0, 15, 0, 0, 2, 0, 0,
-  0, 36, 38, 0, 60, 0, 2, 0, 50, 0,
-  47, 0, 0, 0, 62, 0, 47, 0, 7, 0,
-  20, 0, 0, 8, 0, 4, 0, 8, 0, 7,
-  0, 0, 51, 44, 26, 26, 0, 37, 18, 0,
-  29, 6, 9, 13, 0, 18, 0, 17, 0, 0,
-  6, 0, 36, 0, 37, 0, 37, 0, 0, 0,
-  38, 0, 0, 12, 0, 42, 6, 15, 37, 28,
-  4, 4, 6, 14, 22, 0, 5, 59, 66, 39,
-  0, 24, 0, 0, 0, 20, 47, 15, 29, 33,
-  0, 35, 0, 0, 91, 34, 6, 0, 0, 11,
-  0, 10, 0, 18, 0, 22, 0, 58, 46, 78,
-  0, 43, 0, 62, 86, 46, 0, 56, 0, 0,
-  0, 20, 4, 0, 0, 0, 0, 0, 39, 0,
-  35, 6, 23, 0, 0, 0, 28, 23, 8, 0,
-  0, 0, 113, 0, 11, 9, 0, 0, 7, 22,
-  0, 0, 22, 29, 0, 8, 36, 0, 36, 0,
-  26, 59, 19, 7, 14, 19, 16, 0, 26, 17,
-  35, 32, 0, 9, 19, 42, 0, 0, 5, 0,
-  0, 0, 14, 11, 125, 0, 35, 0, 0, 0,
-  0, 58, 49, 0, 14, 0, 50, 16, 63, 8,
-  3, 26, 61, 1, 7, 53, 52, 0, 0, 15,
-  0, 27, 43, 19, 23, 0, 0, 13, 0, 0,
-  0, 0, 41, 0, 0, 6, 0, 16, 0, 79,
-  0, 24, 0, 55, 1, 70, 61, 46, 0, 21,
-  0, 20, 72, 1, 0, 0, 29, 0, 0, 0,
-  15, 36, 0, 43, 0, 14, 0, 0, 79, 0,
-  0, 0, 7, 27, 66, 15, 34, 28, 0, 0,
-  79, 0, 29, 0, 25, 0, 16, 0, 0, 0,
-  0, 0, 0, 17, 0, 26, 0, 0, 5, 71,
-  31, 0, 0, 0, 26, 0, 28, 0, 0, 38,
-  0, 0, 0, 2, 0, 0, 2, 14, 69, 0,
-  27, 0, 63, 0, 43, 7, 17, 0, 0, 6,
-  0, 0, 0, 1, 30, 12, 26, 0, 0, 25,
-  43, 0, 8, 23, 56, 23, 0, 0, 32, 29,
-  18, 2, 25, 0, 0, 0, 0, 0, 0, 0,
-  36, 17, 0, 0, 0, 0, 0, 34, 0, 11,
-  0, 58, 21, 87, 29, 59, 0, 1, 0, 52,
-  63, 0, 3, 0, 12, 0, 0, 0, 25, 4,
-  0, 38, 0, 10, 4, 0, 42, 0, 34, 0,
-  0, 17, 34, 0, 45, 41, 0, 0, 77, 0,
-  55, 0, 5, 0, 14, 0, 0, 0, 0, 31,
-  0, 0, 0, 22, 0, 0, 32, 57, 30, 0,
-  0, 9, 8, 0, 15, 0, 0, 13, 0, 14,
-  0, 2, 0, 0, 29, 0, 33, 0, 14, 0,
-  33, 0, 13, 6, 20, 0, 0, 5, 0, 30,
-  11, 9, 0, 0, 16, 0, 14, 0, 28, 0,
-  0, 43, 62, 17, 0, 4, 0, 0, 0, 14,
-  39, 0, 19, 14, 0, 0, 0, 0, 39, 51,
-  0, 0, 0, 0, 8, 0, 0, 0, 0, 26,
-  0, 76, 41, 64, 0, 17, 0, 73, 78, 15,
-  1, 58, 0, 0, 0, 0, 35, 0, 0, 26,
-  0, 0, 54, 0, 52, 39, 59, 0, 0, 16,
-  4, 0, 13, 36, 0, 0, 89, 0, 49, 0,
-  0, 20, 1, 30, 0, 0, 0, 79, 0, 0,
-  39, 0, 21, 0, 17, 79, 53, 5, 0, 14,
-  0, 0, 0, 9, 0, 17, 0, 33, 0, 25,
-  0, 0, 3, 0, 0, 0, 0, 0, 77, 0,
-  14, 5, 4, 0, 23, 19, 0, 34, 10, 9,
-  83, 40, 0, 0, 0, 24, 57, 8, 0, 49,
-  29, 55, 14, 27, 77, 6, 23, 33, 54, 0,
-  58, 20, 192, 4, 0, 22, 109, 15, 46, 0,
-  0, 37, 38, 5, 0, 0, 0, 70, 41, 137,
-  1, 46, 0, 13, 0, 79, 54, 2, 11, 54,
-  16, 0, 0, 0, 37, 0, 13, 6, 0, 0,
-  18, 17, 31, 11, 84, 0, 5, 0, 13, 0,
-  66, 45, 13, 0, 58, 0, 30, 0, 0, 0,
-  28, 0, 31, 38, 0, 18, 0, 18, 32, 25,
-  25, 0, 48, 37, 18, 2, 0, 55, 81, 0,
-  12, 13, 23, 14, 0, 32, 10, 37, 0, 0,
-  29, 0, 19, 21, 86, 0, 13, 0, 0, 0,
-  37, 12, 0, 33, 0, 8, 0, 0, 88, 51,
-  0, 25, 4, 29, 23, 1, 15, 91, 42, 50,
-  0, 22, 30, 0, 0, 49, 47, 30, 47, 45,
-  143, 63, 23, 6, 105, 25, 47, 0, 0, 39,
-  4, 30, 0, 3, 39, 25, 43, 65, 2, 47,
-  0, 56, 16, 77, 68, 39, 2, 24, 5, 0,
-  0, 43, 0, 0, 0, 26, 0, 4, 28, 0,
-  0, 0, 1, 21, 0, 0, 4, 46, 30, 14,
-  4, 0, 94, 0, 0, 19, 0, 0, 9, 3,
-  54, 33, 28, 12, 0, 25, 28, 16, 54, 0,
-  16, 44, 0, 0, 10, 24, 96, 0, 13, 21,
-  39, 36, 23, 10, 46, 34, 8, 0, 13, 0,
-  3, 31, 63, 19, 94, 0, 15, 0, 17, 0,
-  0, 98, 1, 0, 0, 0, 70, 26, 1, 40,
-  0, 18, 8, 0, 0, 55, 20, 56, 0, 28,
-  0, 0, 9, 77, 37, 43, 56, 51, 165, 33,
-  18, 0, 85, 0, 49, 0, 0, 7, 13, 31,
-  0, 0, 65, 0, 42, 42, 0, 0, 0, 51,
-  14, 68, 75, 5, 23, 0, 0, 0, 0, 38,
-  0, 3, 1, 24, 0, 20, 44, 0, 0, 18,
-  0, 29, 38, 5, 30, 64, 3, 48, 31, 0,
-  73, 0, 0, 22, 0, 9, 14, 16, 72, 24,
-  54, 0, 0, 3, 10, 1, 31, 0, 4, 29,
-  0, 13, 27, 0, 87, 0, 38, 9, 40, 53,
-  46, 4, 16, 15, 5, 0, 5, 0, 11, 52,
-  56, 10, 49, 0, 36, 0, 7, 0, 7, 18,
-  0, 16, 0, 21, 57, 17, 0, 0, 0, 41,
-  57, 2, 0, 6, 60, 44, 5, 5, 45, 0,
-  15, 0, 37, 0, 27, 0, 0, 35, 0, 0,
-  85, 0, 0, 0, 0, 5, 0, 0, 0, 23,
-  0, 64, 4, 113, 25, 79, 0, 0, 0, 41,
-  66, 0, 0, 22, 11, 0, 0, 0, 15, 0,
-  0, 2, 0, 0, 0, 36, 38, 0, 60, 0,
-  2, 0, 50, 0, 47, 0, 0, 0, 62, 0,
-  47, 0, 7, 0, 20, 0, 0, 8, 0, 4,
-  0, 8, 0, 7, 0, 0, 51, 44, 26, 26,
-  0, 37, 18, 0, 29, 6, 9, 13, 0, 18,
-  0, 17, 0, 0, 6, 0, 36, 0, 37, 0,
-  37, 0, 0, 0, 38, 0, 0, 12, 0, 42,
-  6, 15, 37, 28, 4, 4, 6, 14, 22, 0,
-  5, 59, 66, 39, 0, 24, 0, 0, 0, 20,
-  47, 15, 29, 33, 0, 35, 0, 0, 91, 34,
-  6, 0, 0, 11, 0, 10, 0, 18, 0, 22,
-  0, 58, 46, 78, 0, 43, 0, 62, 86, 46,
-  0, 56, 0, 0, 0, 20, 4, 0, 0, 0,
-  0, 0, 39, 0, 35, 6, 23, 0, 0, 0,
-  28, 23, 8, 0, 0, 0, 113, 0, 11, 9,
-  0, 0, 7, 22, 0, 0, 22, 29, 0, 8,
-  36, 0, 36, 0, 26, 59, 19, 7, 14, 19,
-  16, 0, 26, 17, 35, 32, 0, 9, 19, 42,
-  0, 0, 5, 0, 0, 0, 14, 11, 125, 0,
-  35, 0, 0, 0, 0, 93, 5, 24, 14, 0,
-  37, 16, 19, 24, 15, 1, 7, 0, 45, 74,
-  66, 43, 0, 20, 0, 0, 0, 49, 65, 69,
-  6, 62, 0, 1, 5, 0, 69, 27, 8, 0,
-  0, 8, 0, 34, 0, 35, 41, 0, 16, 0,
-  40, 0, 0, 56, 0, 37, 99, 45, 0, 4,
-  0, 17, 0, 45, 12, 0, 0, 33, 0, 12,
-  78, 0, 23, 0, 0, 0, 0, 6, 46, 35,
-  1, 18, 0, 2, 119, 0, 0, 1, 0, 16,
-  0, 27, 17, 29, 59, 0, 0, 26, 0, 8,
-  27, 0, 0, 42, 0, 0, 29, 0, 16, 0,
-  32, 10, 52, 56, 0, 0, 9, 11, 0, 0,
-  0, 0, 0, 0, 4, 23, 137, 0, 66, 0,
-  0, 0, 0, 6, 0, 0, 0, 1, 30, 12,
-  26, 0, 0, 25, 43, 0, 8, 23, 56, 23,
-  0, 0, 32, 29, 18, 2, 25, 0, 0, 0,
-  0, 0, 0, 0, 36, 17, 0, 0, 0, 0,
-  0, 34, 0, 11, 0, 58, 21, 87, 29, 59,
-  0, 1, 0, 52, 63, 0, 3, 0, 12, 0,
-  0, 0, 25, 4, 0, 38, 0, 10, 4, 0,
-  42, 0, 34, 0, 0, 17, 34, 0, 45, 41,
-  0, 0, 77, 0, 55, 0, 5, 0, 14, 0,
-  0, 0, 0, 31, 0, 0, 0, 22, 0, 0,
-  32, 57, 30, 0, 0, 9, 8, 0, 15, 0,
-  0, 13, 0, 14, 0, 2, 0, 0, 29, 0,
-  33, 0, 14, 0, 33, 0, 13, 6, 20, 0,
-  0, 5, 0, 30, 11, 9, 0, 0, 16, 0,
-  14, 0, 28, 0, 0, 43, 62, 17, 0, 4,
-  0, 0, 0, 14, 39, 0, 19, 14, 0, 0,
-  0, 0, 39, 51, 0, 0, 0, 0, 8, 0,
-  0, 0, 0, 26, 0, 76, 41, 64, 0, 17,
-  0, 73, 78, 15, 1, 58, 0, 0, 0, 0,
-  35, 0, 0, 26, 0, 0, 54, 0, 52, 39,
-  59, 0, 0, 16, 4, 0, 13, 36, 0, 0,
-  89, 0, 49, 0, 0, 20, 1, 30, 0, 0,
-  0, 79, 0, 0, 39, 0, 21, 0, 17, 79,
-  53, 5, 0, 14, 0, 0, 0, 9, 0, 17,
-  0, 33, 0, 25, 0, 0, 3, 0, 0, 0,
-  0, 0, 77, 0, 14, 5, 4, 0, 0, 37,
-  0, 30, 19, 0, 8, 0, 29, 1, 5, 0,
-  23, 0, 24, 68, 78, 31, 0, 2, 0, 0,
-  0, 40, 45, 0, 20, 28, 0, 0, 7, 0,
-  46, 69, 0, 0, 0, 8, 7, 0, 0, 0,
-  0, 16, 0, 35, 63, 39, 0, 11, 0, 42,
-  72, 27, 0, 30, 0, 4, 0, 3, 38, 0,
-  0, 31, 0, 0, 79, 0, 75, 41, 0, 0,
-  0, 12, 16, 0, 14, 1, 0, 0, 85, 0,
-  26, 0, 0, 32, 0, 18, 6, 0, 14, 72,
-  0, 6, 28, 0, 15, 0, 0, 80, 18, 0,
-  0, 7, 0, 0, 0, 0, 2, 22, 0, 30,
-  8, 22, 3, 0, 0, 0, 0, 0, 0, 0,
-  101, 0, 9, 26, 7, 0, 0, 33, 0, 8,
-  0, 0, 88, 51, 0, 25, 4, 29, 23, 1,
-  15, 91, 42, 50, 0, 22, 30, 0, 0, 49,
-  47, 30, 47, 45, 143, 63, 23, 6, 105, 25,
-  47, 0, 0, 39, 4, 30, 0, 3, 39, 25,
-  43, 65, 2, 47, 0, 56, 16, 77, 68, 39,
-  2, 24, 5, 0, 0, 43, 0, 0, 0, 26,
-  0, 4, 28, 0, 0, 0, 1, 21, 0, 0,
-  4, 46, 30, 14, 4, 0, 94, 0, 0, 19,
-  0, 0, 9, 3, 54, 33, 28, 12, 0, 25,
-  28, 16, 54, 0, 16, 44, 0, 0, 10, 24,
-  96, 0, 13, 21, 39, 36, 23, 10, 46, 34,
-  8, 0, 13, 0, 3, 31, 63, 19, 94, 0,
-  15, 0, 17, 0, 0, 98, 1, 0, 0, 0,
-  70, 26, 1, 40, 0, 18, 8, 0, 0, 55,
-  20, 56, 0, 28, 0, 0, 9, 77, 37, 43,
-  56, 51, 165, 33, 18, 0, 85, 0, 49, 0,
-  0, 7, 13, 31, 0, 0, 65, 0, 42, 42,
-  0, 0, 0, 51, 14, 68, 75, 5, 23, 0,
-  0, 0, 0, 38, 0, 3, 1, 24, 0, 20,
-  44, 0, 0, 18, 0, 29, 38, 5, 30, 64,
-  3, 48, 31, 0, 73, 0, 0, 22, 0, 9,
-  14, 16, 72, 24, 54, 0, 0, 3, 10, 1,
-  31, 0, 4, 29, 0, 13, 27, 0, 87, 0,
-  38, 9, 40, 53, 46, 4, 16, 15, 5, 0,
-  5, 0, 11, 52, 56, 10, 49, 0, 36, 0,
-  7, 0, 21, 87, 0, 17, 0, 0, 7, 0,
-  27, 18, 0, 30, 39, 0, 0, 11, 9, 43,
-  15, 26, 0, 36, 93, 68, 12, 0, 68, 46,
-  209, 0, 0, 0, 54, 0, 48, 43, 0, 0,
-  65, 3, 0, 0, 39, 14, 18, 96, 0, 0,
-  0, 10, 0, 107, 61, 0, 69, 0, 19, 0,
-  17, 0, 20, 40, 0, 0, 35, 25, 0, 0,
-  0, 58, 134, 10, 46, 0, 8, 33, 3, 95,
-  34, 0, 24, 0, 8, 20, 0, 5, 21, 22,
-  59, 0, 30, 0, 0, 0, 54, 0, 27, 0,
-  10, 43, 26, 72, 29, 15, 69, 18, 47, 0,
-  13, 38, 8, 8, 0, 1, 0, 0, 3, 0,
-  8, 49, 53, 0, 0, 0, 36, 0, 0, 0,
-  0, 12, 0, 42, 6, 15, 37, 28, 4, 4,
-  6, 14, 22, 0, 5, 59, 66, 39, 0, 24,
-  0, 0, 0, 20, 47, 15, 29, 33, 0, 35,
-  0, 0, 91, 34, 6, 0, 0, 11, 0, 10,
-  0, 18, 0, 22, 0, 58, 46, 78, 0, 43,
-  0, 62, 86, 46, 0, 56, 0, 0, 0, 20,
-  4, 0, 0, 0, 0, 0, 39, 0, 35, 6,
-  23, 0, 0, 0, 28, 23, 8, 0, 0, 0,
-  113, 0, 11, 9, 0, 0, 7, 22, 0, 0,
-  22, 29, 0, 8, 36, 0, 36, 0, 26, 59,
-  19, 7, 14, 19, 16, 0, 26, 17, 35, 32,
-  0, 9, 19, 42, 0, 0, 5, 0, 0, 0,
-  14, 11, 125, 0, 35, 0, 0, 0, 0, 93,
-  5, 24, 14, 0, 37, 16, 19, 24, 15, 1,
-  7, 0, 45, 74, 66, 43, 0, 20, 0, 0,
-  0, 49, 65, 69, 6, 62, 0, 1, 5, 0,
-  69, 27, 8, 0, 0, 8, 0, 34, 0, 35,
-  41, 0, 16, 0, 40, 0, 0, 56, 0, 37,
-  99, 45, 0, 4, 0, 17, 0, 45, 12, 0,
-  0, 33, 0, 12, 78, 0, 23, 0, 0, 0,
-  0, 6, 46, 35, 1, 18, 0, 2, 119, 0,
-  0, 1, 0, 16, 0, 27, 17, 29, 59, 0,
-  0, 26, 0, 8, 27, 0, 0, 42, 0, 0,
-  29, 0, 16, 0, 32, 10, 52, 56, 0, 0,
-  9, 11, 0, 0, 0, 0, 0, 0, 4, 23,
-  137, 0, 66, 0, 0, 0, 0, 115, 36, 17,
-  6, 0, 3, 0, 44, 17, 0, 0, 3, 0,
-  0, 24, 36, 38, 6, 35, 0, 0, 67, 53,
-  19, 0, 40, 54, 0, 0, 0, 0, 68, 0,
-  53, 8, 0, 0, 28, 2, 0, 0, 37, 25,
-  0, 67, 27, 0, 0, 2, 0, 53, 88, 0,
-  20, 0, 26, 0, 0, 0, 0, 27, 0, 0,
-  0, 0, 0, 0, 0, 14, 53, 0, 37, 17,
-  61, 42, 0, 74, 24, 0, 64, 0, 4, 21,
-  0, 0, 6, 36, 25, 20, 74, 0, 0, 0,
-  24, 0, 0, 0, 0, 53, 38, 17, 0, 0,
-  21, 4, 62, 0, 41, 58, 0, 16, 0, 3,
-  0, 0, 0, 0, 0, 6, 0, 0, 35, 0,
-  53, 1, 0, 0, 0, 5, 0, 30, 11, 9,
-  0, 0, 16, 0, 14, 0, 28, 0, 0, 43,
-  62, 17, 0, 4, 0, 0, 0, 14, 39, 0,
-  19, 14, 0, 0, 0, 0, 39, 51, 0, 0,
-  0, 0, 8, 0, 0, 0, 0, 26, 0, 76,
-  41, 64, 0, 17, 0, 73, 78, 15, 1, 58,
-  0, 0, 0, 0, 35, 0, 0, 26, 0, 0,
-  54, 0, 52, 39, 59, 0, 0, 16, 4, 0,
-  13, 36, 0, 0, 89, 0, 49, 0, 0, 20,
-  1, 30, 0, 0, 0, 79, 0, 0, 39, 0,
-  21, 0, 17, 79, 53, 5, 0, 14, 0, 0,
-  0, 9, 0, 17, 0, 33, 0, 25, 0, 0,
-  3, 0, 0, 0, 0, 0, 77, 0, 14, 5,
-  4, 0, 0, 37, 0, 30, 19, 0, 8, 0,
-  29, 1, 5, 0, 23, 0, 24, 68, 78, 31,
-  0, 2, 0, 0, 0, 40, 45, 0, 20, 28,
-  0, 0, 7, 0, 46, 69, 0, 0, 0, 8,
-  7, 0, 0, 0, 0, 16, 0, 35, 63, 39,
-  0, 11, 0, 42, 72, 27, 0, 30, 0, 4,
-  0, 3, 38, 0, 0, 31, 0, 0, 79, 0,
-  75, 41, 0, 0, 0, 12, 16, 0, 14, 1,
-  0, 0, 85, 0, 26, 0, 0, 32, 0, 18,
-  6, 0, 14, 72, 0, 6, 28, 0, 15, 0,
-  0, 80, 18, 0, 0, 7, 0, 0, 0, 0,
-  2, 22, 0, 30, 8, 22, 3, 0, 0, 0,
-  0, 0, 0, 0, 101, 0, 9, 26, 7, 0,
-  0, 119, 31, 10, 0, 0, 55, 0, 33, 18,
-  0, 0, 0, 0, 46, 39, 65, 38, 5, 18,
-  0, 0, 0, 46, 49, 6, 24, 40, 0, 0,
-  0, 0, 84, 26, 0, 0, 0, 16, 0, 3,
-  0, 0, 24, 17, 0, 45, 64, 6, 0, 10,
-  0, 0, 73, 0, 0, 0, 32, 0, 0, 35,
-  7, 5, 0, 0, 0, 0, 63, 0, 26, 11,
-  0, 0, 0, 15, 64, 26, 8, 27, 5, 0,
-  67, 3, 18, 28, 0, 6, 0, 0, 1, 26,
-  36, 0, 0, 22, 0, 0, 0, 0, 0, 60,
-  6, 0, 0, 0, 2, 0, 43, 0, 35, 36,
-  0, 21, 0, 19, 0, 0, 0, 0, 13, 0,
-  0, 0, 95, 0, 24, 41, 20, 0, 0, 98,
-  1, 0, 0, 0, 70, 26, 1, 40, 0, 18,
-  8, 0, 0, 55, 20, 56, 0, 28, 0, 0,
-  9, 77, 37, 43, 56, 51, 165, 33, 18, 0,
-  85, 0, 49, 0, 0, 7, 13, 31, 0, 0,
-  65, 0, 42, 42, 0, 0, 0, 51, 14, 68,
-  75, 5, 23, 0, 0, 0, 0, 38, 0, 3,
-  1, 24, 0, 20, 44, 0, 0, 18, 0, 29,
-  38, 5, 30, 64, 3, 48, 31, 0, 73, 0,
-  0, 22, 0, 9, 14, 16, 72, 24, 54, 0,
-  0, 3, 10, 1, 31, 0, 4, 29, 0, 13,
-  27, 0, 87, 0, 38, 9, 40, 53, 46, 4,
-  16, 15, 5, 0, 5, 0, 11, 52, 56, 10,
-  49, 0, 36, 0, 7, 0, 21, 87, 0, 17,
-  0, 0, 7, 0, 27, 18, 0, 30, 39, 0,
-  0, 11, 9, 43, 15, 26, 0, 36, 93, 68,
-  12, 0, 68, 46, 209, 0, 0, 0, 54, 0,
-  48, 43, 0, 0, 65, 3, 0, 0, 39, 14,
-  18, 96, 0, 0, 0, 10, 0, 107, 61, 0,
-  69, 0, 19, 0, 17, 0, 20, 40, 0, 0,
-  35, 25, 0, 0, 0, 58, 134, 10, 46, 0,
-  8, 33, 3, 95, 34, 0, 24, 0, 8, 20,
-  0, 5, 21, 22, 59, 0, 30, 0, 0, 0,
-  54, 0, 27, 0, 10, 43, 26, 72, 29, 15,
-  69, 18, 47, 0, 13, 38, 8, 8, 0, 1,
-  0, 0, 3, 0, 8, 49, 53, 0, 0, 0,
-  36, 0, 0, 0, 121, 68, 0, 69, 37, 0,
-  10, 0, 13, 0, 0, 24, 109, 0, 0, 19,
-  14, 0, 23, 0, 0, 116, 51, 34, 64, 0,
-  36, 36, 222, 0, 6, 97, 40, 17, 23, 41,
-  0, 0, 124, 6, 0, 0, 30, 56, 59, 90,
-  15, 0, 0, 12, 0, 135, 15, 0, 103, 17,
-  27, 22, 53, 0, 58, 43, 30, 87, 0, 83,
-  14, 0, 21, 25, 137, 20, 29, 0, 0, 0,
-  51, 86, 41, 0, 7, 0, 17, 24, 0, 13,
-  21, 0, 55, 9, 0, 0, 0, 0, 22, 16,
-  63, 0, 40, 42, 4, 62, 32, 21, 74, 29,
-  0, 42, 54, 0, 12, 14, 0, 0, 0, 27,
-  4, 0, 11, 38, 71, 25, 0, 34, 62, 0,
-  9, 24, 0, 93, 5, 24, 14, 0, 37, 16,
-  19, 24, 15, 1, 7, 0, 45, 74, 66, 43,
-  0, 20, 0, 0, 0, 49, 65, 69, 6, 62,
-  0, 1, 5, 0, 69, 27, 8, 0, 0, 8,
-  0, 34, 0, 35, 41, 0, 16, 0, 40, 0,
-  0, 56, 0, 37, 99, 45, 0, 4, 0, 17,
-  0, 45, 12, 0, 0, 33, 0, 12, 78, 0,
-  23, 0, 0, 0, 0, 6, 46, 35, 1, 18,
-  0, 2, 119, 0, 0, 1, 0, 16, 0, 27,
-  17, 29, 59, 0, 0, 26, 0, 8, 27, 0,
-  0, 42, 0, 0, 29, 0, 16, 0, 32, 10,
-  52, 56, 0, 0, 9, 11, 0, 0, 0, 0,
-  0, 0, 4, 23, 137, 0, 66, 0, 0, 0,
-  0, 115, 36, 17, 6, 0, 3, 0, 44, 17,
-  0, 0, 3, 0, 0, 24, 36, 38, 6, 35,
-  0, 0, 67, 53, 19, 0, 40, 54, 0, 0,
-  0, 0, 68, 0, 53, 8, 0, 0, 28, 2,
-  0, 0, 37, 25, 0, 67, 27, 0, 0, 2,
-  0, 53, 88, 0, 20, 0, 26, 0, 0, 0,
-  0, 27, 0, 0, 0, 0, 0, 0, 0, 14,
-  53, 0, 37, 17, 61, 42, 0, 74, 24, 0,
-  64, 0, 4, 21, 0, 0, 6, 36, 25, 20,
-  74, 0, 0, 0, 24, 0, 0, 0, 0, 53,
-  38, 17, 0, 0, 21, 4, 62, 0, 41, 58,
-  0, 16, 0, 3, 0, 0, 0, 0, 0, 6,
-  0, 0, 35, 0, 53, 1, 0, 0, 55, 68,
-  5, 59, 7, 0, 0, 0, 39, 0, 0, 18,
-  78, 0, 0, 0, 25, 2, 0, 0, 0, 34,
-  65, 19, 34, 0, 18, 36, 0, 0, 0, 6,
-  13, 0, 31, 16, 0, 0, 71, 0, 0, 16,
-  19, 37, 0, 40, 14, 0, 0, 0, 0, 107,
-  29, 0, 61, 0, 36, 0, 0, 0, 0, 19,
-  0, 10, 41, 34, 0, 0, 22, 0, 133, 0,
-  33, 13, 17, 0, 9, 54, 28, 7, 16, 0,
-  14, 15, 15, 0, 15, 0, 48, 0, 1, 0,
-  0, 0, 0, 0, 10, 0, 0, 40, 0, 1,
-  9, 0, 35, 68, 7, 20, 38, 3, 0, 13,
-  0, 0, 0, 0, 0, 0, 0, 9, 0, 0,
-  0, 0, 53, 0, 0, 0, 0, 37, 0, 30,
-  19, 0, 8, 0, 29, 1, 5, 0, 23, 0,
-  24, 68, 78, 31, 0, 2, 0, 0, 0, 40,
-  45, 0, 20, 28, 0, 0, 7, 0, 46, 69,
-  0, 0, 0, 8, 7, 0, 0, 0, 0, 16,
-  0, 35, 63, 39, 0, 11, 0, 42, 72, 27,
-  0, 30, 0, 4, 0, 3, 38, 0, 0, 31,
-  0, 0, 79, 0, 75, 41, 0, 0, 0, 12,
-  16, 0, 14, 1, 0, 0, 85, 0, 26, 0,
-  0, 32, 0, 18, 6, 0, 14, 72, 0, 6,
-  28, 0, 15, 0, 0, 80, 18, 0, 0, 7,
-  0, 0, 0, 0, 2, 22, 0, 30, 8, 22,
-  3, 0, 0, 0, 0, 0, 0, 0, 101, 0,
-  9, 26, 7, 0, 0, 119, 31, 10, 0, 0,
-  55, 0, 33, 18, 0, 0, 0, 0, 46, 39,
-  65, 38, 5, 18, 0, 0, 0, 46, 49, 6,
-  24, 40, 0, 0, 0, 0, 84, 26, 0, 0,
-  0, 16, 0, 3, 0, 0, 24, 17, 0, 45,
-  64, 6, 0, 10, 0, 0, 73, 0, 0, 0,
-  32, 0, 0, 35, 7, 5, 0, 0, 0, 0,
-  63, 0, 26, 11, 0, 0, 0, 15, 64, 26,
-  8, 27, 5, 0, 67, 3, 18, 28, 0, 6,
-  0, 0, 1, 26, 36, 0, 0, 22, 0, 0,
-  0, 0, 0, 60, 6, 0, 0, 0, 2, 0,
-  43, 0, 35, 36, 0, 21, 0, 19, 0, 0,
-  0, 0, 13, 0, 0, 0, 95, 0, 24, 41,
-  20, 0, 0, 104, 16, 18, 0, 0, 0, 0,
-  47, 19, 0, 0, 6, 0, 7, 17, 36, 23,
-  0, 2, 0, 0, 72, 39, 0, 0, 14, 29,
-  0, 0, 0, 0, 40, 0, 36, 14, 0, 1,
-  11, 0, 0, 0, 22, 32, 0, 52, 25, 0,
-  0, 0, 0, 42, 40, 0, 22, 0, 44, 0,
-  3, 0, 0, 33, 0, 0, 52, 0, 0, 0,
-  0, 10, 106, 0, 39, 32, 46, 45, 0, 59,
-  28, 0, 21, 0, 1, 31, 0, 0, 5, 21,
-  26, 0, 31, 0, 0, 0, 5, 0, 0, 0,
-  0, 52, 28, 23, 1, 0, 7, 59, 48, 1,
-  0, 29, 0, 28, 0, 8, 0, 0, 0, 0,
-  0, 12, 0, 0, 0, 0, 49, 26, 5, 0,
-  21, 87, 0, 17, 0, 0, 7, 0, 27, 18,
-  0, 30, 39, 0, 0, 11, 9, 43, 15, 26,
-  0, 36, 93, 68, 12, 0, 68, 46, 209, 0,
-  0, 0, 54, 0, 48, 43, 0, 0, 65, 3,
-  0, 0, 39, 14, 18, 96, 0, 0, 0, 10,
-  0, 107, 61, 0, 69, 0, 19, 0, 17, 0,
-  20, 40, 0, 0, 35, 25, 0, 0, 0, 58,
-  134, 10, 46, 0, 8, 33, 3, 95, 34, 0,
-  24, 0, 8, 20, 0, 5, 21, 22, 59, 0,
-  30, 0, 0, 0, 54, 0, 27, 0, 10, 43,
-  26, 72, 29, 15, 69, 18, 47, 0, 13, 38,
-  8, 8, 0, 1, 0, 0, 3, 0, 8, 49,
-  53, 0, 0, 0, 36, 0, 0, 0, 121, 68,
-  0, 69, 37, 0, 10, 0, 13, 0, 0, 24,
-  109, 0, 0, 19, 14, 0, 23, 0, 0, 116,
-  51, 34, 64, 0, 36, 36, 222, 0, 6, 97,
-  40, 17, 23, 41, 0, 0, 124, 6, 0, 0,
-  30, 56, 59, 90, 15, 0, 0, 12, 0, 135,
-  15, 0, 103, 17, 27, 22, 53, 0, 58, 43,
-  30, 87, 0, 83, 14, 0, 21, 25, 137, 20,
-  29, 0, 0, 0, 51, 86, 41, 0, 7, 0,
-  17, 24, 0, 13, 21, 0, 55, 9, 0, 0,
-  0, 0, 22, 16, 63, 0, 40, 42, 4, 62,
-  32, 21, 74, 29, 0, 42, 54, 0, 12, 14,
-  0, 0, 0, 27, 4, 0, 11, 38, 71, 25,
-  0, 34, 62, 0, 9, 24, 66, 10, 0, 31,
-  29, 110, 12, 0, 20, 0, 0, 9, 85, 0,
-  0, 46, 16, 30, 0, 0, 33, 111, 0, 60,
-  48, 0, 3, 44, 255, 0, 0, 72, 42, 37,
-  17, 24, 0, 22, 96, 20, 32, 0, 17, 61,
-  85, 122, 14, 0, 0, 23, 0, 130, 26, 0,
-  91, 47, 26, 11, 67, 0, 34, 60, 32, 28,
-  0, 46, 0, 4, 12, 28, 143, 0, 41, 3,
-  0, 22, 11, 56, 20, 0, 23, 0, 1, 24,
-  0, 0, 19, 5, 50, 28, 0, 55, 8, 0,
-  61, 18, 20, 0, 39, 55, 9, 30, 21, 7,
-  86, 7, 1, 22, 0, 7, 0, 16, 0, 0,
-  0, 31, 20, 0, 35, 34, 69, 0, 0, 44,
-  59, 0, 6, 4, 0, 115, 36, 17, 6, 0,
-  3, 0, 44, 17, 0, 0, 3, 0, 0, 24,
-  36, 38, 6, 35, 0, 0, 67, 53, 19, 0,
-  40, 54, 0, 0, 0, 0, 68, 0, 53, 8,
-  0, 0, 28, 2, 0, 0, 37, 25, 0, 67,
-  27, 0, 0, 2, 0, 53, 88, 0, 20, 0,
-  26, 0, 0, 0, 0, 27, 0, 0, 0, 0,
-  0, 0, 0, 14, 53, 0, 37, 17, 61, 42,
-  0, 74, 24, 0, 64, 0, 4, 21, 0, 0,
-  6, 36, 25, 20, 74, 0, 0, 0, 24, 0,
-  0, 0, 0, 53, 38, 17, 0, 0, 21, 4,
-  62, 0, 41, 58, 0, 16, 0, 3, 0, 0,
-  0, 0, 0, 6, 0, 0, 35, 0, 53, 1,
-  0, 0, 55, 68, 5, 59, 7, 0, 0, 0,
-  39, 0, 0, 18, 78, 0, 0, 0, 25, 2,
-  0, 0, 0, 34, 65, 19, 34, 0, 18, 36,
-  0, 0, 0, 6, 13, 0, 31, 16, 0, 0,
-  71, 0, 0, 16, 19, 37, 0, 40, 14, 0,
-  0, 0, 0, 107, 29, 0, 61, 0, 36, 0,
-  0, 0, 0, 19, 0, 10, 41, 34, 0, 0,
-  22, 0, 133, 0, 33, 13, 17, 0, 9, 54,
-  28, 7, 16, 0, 14, 15, 15, 0, 15, 0,
-  48, 0, 1, 0, 0, 0, 0, 0, 10, 0,
-  0, 40, 0, 1, 9, 0, 35, 68, 7, 20,
-  38, 3, 0, 13, 0, 0, 0, 0, 0, 0,
-  0, 9, 0, 0, 0, 0, 53, 0, 0, 0,
-  104, 21, 0, 47, 20, 66, 0, 0, 53, 0,
-  0, 0, 116, 0, 0, 40, 62, 0, 2, 0,
-  11, 68, 0, 8, 23, 0, 0, 43, 3, 1,
-  13, 72, 0, 27, 24, 0, 0, 21, 96, 5,
-  13, 87, 14, 47, 59, 16, 0, 0, 0, 0,
-  0, 111, 0, 0, 107, 59, 25, 17, 19, 0,
-  0, 13, 9, 35, 0, 93, 0, 0, 13, 0,
-  155, 30, 22, 32, 0, 0, 34, 19, 0, 47,
-  0, 0, 15, 14, 42, 14, 8, 0, 73, 0,
-  0, 0, 0, 2, 0, 0, 31, 0, 21, 50,
-  0, 0, 5, 0, 30, 31, 0, 67, 22, 0,
-  17, 0, 0, 0, 0, 0, 0, 0, 0, 1,
-  0, 3, 0, 16, 53, 0, 3, 16, 0, 119,
-  31, 10, 0, 0, 55, 0, 33, 18, 0, 0,
-  0, 0, 46, 39, 65, 38, 5, 18, 0, 0,
-  0, 46, 49, 6, 24, 40, 0, 0, 0, 0,
-  84, 26, 0, 0, 0, 16, 0, 3, 0, 0,
-  24, 17, 0, 45, 64, 6, 0, 10, 0, 0,
-  73, 0, 0, 0, 32, 0, 0, 35, 7, 5,
-  0, 0, 0, 0, 63, 0, 26, 11, 0, 0,
-  0, 15, 64, 26, 8, 27, 5, 0, 67, 3,
-  18, 28, 0, 6, 0, 0, 1, 26, 36, 0,
-  0, 22, 0, 0, 0, 0, 0, 60, 6, 0,
-  0, 0, 2, 0, 43, 0, 35, 36, 0, 21,
-  0, 19, 0, 0, 0, 0, 13, 0, 0, 0,
-  95, 0, 24, 41, 20, 0, 0, 104, 16, 18,
-  0, 0, 0, 0, 47, 19, 0, 0, 6, 0,
-  7, 17, 36, 23, 0, 2, 0, 0, 72, 39,
-  0, 0, 14, 29, 0, 0, 0, 0, 40, 0,
-  36, 14, 0, 1, 11, 0, 0, 0, 22, 32,
-  0, 52, 25, 0, 0, 0, 0, 42, 40, 0,
-  22, 0, 44, 0, 3, 0, 0, 33, 0, 0,
-  52, 0, 0, 0, 0, 10, 106, 0, 39, 32,
-  46, 45, 0, 59, 28, 0, 21, 0, 1, 31,
-  0, 0, 5, 21, 26, 0, 31, 0, 0, 0,
-  5, 0, 0, 0, 0, 52, 28, 23, 1, 0,
-  7, 59, 48, 1, 0, 29, 0, 28, 0, 8,
-  0, 0, 0, 0, 0, 12, 0, 0, 0, 0,
-  49, 26, 5, 0, 107, 66, 16, 65, 30, 0,
-  0, 17, 71, 14, 28, 0, 85, 0, 0, 80,
-  60, 0, 13, 0, 0, 32, 32, 6, 0, 0,
-  0, 61, 0, 37, 19, 69, 10, 6, 18, 5,
-  0, 44, 103, 0, 0, 23, 0, 23, 18, 0,
-  0, 0, 0, 0, 0, 86, 0, 0, 83, 13,
-  32, 36, 9, 0, 0, 0, 0, 0, 15, 55,
-  0, 0, 11, 0, 91, 19, 43, 55, 0, 39,
-  28, 49, 0, 26, 0, 0, 19, 64, 28, 26,
-  14, 0, 86, 0, 32, 0, 0, 14, 0, 0,
-  66, 0, 5, 67, 43, 0, 9, 0, 0, 58,
-  0, 60, 9, 0, 6, 0, 0, 0, 0, 0,
-  0, 0, 0, 15, 0, 4, 0, 18, 46, 15,
-  12, 30, 121, 68, 0, 69, 37, 0, 10, 0,
-  13, 0, 0, 24, 109, 0, 0, 19, 14, 0,
-  23, 0, 0, 116, 51, 34, 64, 0, 36, 36,
-  222, 0, 6, 97, 40, 17, 23, 41, 0, 0,
-  124, 6, 0, 0, 30, 56, 59, 90, 15, 0,
-  0, 12, 0, 135, 15, 0, 103, 17, 27, 22,
-  53, 0, 58, 43, 30, 87, 0, 83, 14, 0,
-  21, 25, 137, 20, 29, 0, 0, 0, 51, 86,
-  41, 0, 7, 0, 17, 24, 0, 13, 21, 0,
-  55, 9, 0, 0, 0, 0, 22, 16, 63, 0,
-  40, 42, 4, 62, 32, 21, 74, 29, 0, 42,
-  54, 0, 12, 14, 0, 0, 0, 27, 4, 0,
-  11, 38, 71, 25, 0, 34, 62, 0, 9, 24,
-  66, 10, 0, 31, 29, 110, 12, 0, 20, 0,
-  0, 9, 85, 0, 0, 46, 16, 30, 0, 0,
-  33, 111, 0, 60, 48, 0, 3, 44, 255, 0,
-  0, 72, 42, 37, 17, 24, 0, 22, 96, 20,
-  32, 0, 17, 61, 85, 122, 14, 0, 0, 23,
-  0, 130, 26, 0, 91, 47, 26, 11, 67, 0,
-  34, 60, 32, 28, 0, 46, 0, 4, 12, 28,
-  143, 0, 41, 3, 0, 22, 11, 56, 20, 0,
-  23, 0, 1, 24, 0, 0, 19, 5, 50, 28,
-  0, 55, 8, 0, 61, 18, 20, 0, 39, 55,
-  9, 30, 21, 7, 86, 7, 1, 22, 0, 7,
-  0, 16, 0, 0, 0, 31, 20, 0, 35, 34,
-  69, 0, 0, 44, 59, 0, 6, 4, 0, 38,
-  0, 0, 7, 72, 57, 6, 59, 17, 0, 6,
-  46, 16, 0, 163, 49, 58, 0, 0, 76, 0,
-  0, 90, 29, 28, 5, 40, 214, 33, 0, 0,
-  89, 29, 32, 0, 0, 53, 10, 75, 12, 0,
-  0, 45, 49, 87, 5, 9, 0, 73, 3, 65,
-  107, 1, 7, 49, 22, 23, 0, 54, 0, 5,
-  0, 32, 0, 1, 11, 0, 25, 0, 29, 0,
-  39, 11, 0, 97, 0, 37, 0, 1, 62, 0,
-  14, 26, 0, 4, 35, 12, 60, 53, 62, 78,
-  0, 3, 68, 5, 0, 0, 50, 64, 14, 0,
-  0, 0, 76, 0, 29, 16, 1, 58, 17, 0,
-  0, 22, 0, 0, 0, 12, 39, 12, 66, 4,
-  74, 0, 59, 0, 32, 0, 55, 68, 5, 59,
-  7, 0, 0, 0, 39, 0, 0, 18, 78, 0,
-  0, 0, 25, 2, 0, 0, 0, 34, 65, 19,
-  34, 0, 18, 36, 0, 0, 0, 6, 13, 0,
-  31, 16, 0, 0, 71, 0, 0, 16, 19, 37,
-  0, 40, 14, 0, 0, 0, 0, 107, 29, 0,
-  61, 0, 36, 0, 0, 0, 0, 19, 0, 10,
-  41, 34, 0, 0, 22, 0, 133, 0, 33, 13,
-  17, 0, 9, 54, 28, 7, 16, 0, 14, 15,
-  15, 0, 15, 0, 48, 0, 1, 0, 0, 0,
-  0, 0, 10, 0, 0, 40, 0, 1, 9, 0,
-  35, 68, 7, 20, 38, 3, 0, 13, 0, 0,
-  0, 0, 0, 0, 0, 9, 0, 0, 0, 0,
-  53, 0, 0, 0, 104, 21, 0, 47, 20, 66,
-  0, 0, 53, 0, 0, 0, 116, 0, 0, 40,
-  62, 0, 2, 0, 11, 68, 0, 8, 23, 0,
-  0, 43, 3, 1, 13, 72, 0, 27, 24, 0,
-  0, 21, 96, 5, 13, 87, 14, 47, 59, 16,
-  0, 0, 0, 0, 0, 111, 0, 0, 107, 59,
-  25, 17, 19, 0, 0, 13, 9, 35, 0, 93,
-  0, 0, 13, 0, 155, 30, 22, 32, 0, 0,
-  34, 19, 0, 47, 0, 0, 15, 14, 42, 14,
-  8, 0, 73, 0, 0, 0, 0, 2, 0, 0,
-  31, 0, 21, 50, 0, 0, 5, 0, 30, 31,
-  0, 67, 22, 0, 17, 0, 0, 0, 0, 0,
-  0, 0, 0, 1, 0, 3, 0, 16, 53, 0,
-  3, 16, 0, 0, 0, 0, 0, 145, 0, 0,
-  46, 0, 0, 0, 34, 21, 0, 109, 67, 48,
-  0, 0, 39, 1, 0, 58, 0, 0, 0, 56,
-  1, 0, 0, 0, 49, 0, 0, 0, 22, 71,
-  0, 0, 22, 0, 0, 3, 13, 87, 0, 0,
-  0, 14, 12, 53, 23, 0, 62, 19, 29, 0,
-  0, 0, 0, 48, 0, 0, 12, 0, 16, 0,
-  17, 13, 58, 0, 50, 76, 0, 66, 0, 52,
-  0, 0, 8, 0, 17, 64, 0, 25, 19, 0,
-  22, 2, 35, 128, 0, 0, 75, 0, 0, 0,
-  0, 93, 86, 0, 0, 0, 15, 0, 0, 38,
-  0, 19, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 13, 0, 4, 15,
-  0, 104, 16, 18, 0, 0, 0, 0, 47, 19,
-  0, 0, 6, 0, 7, 17, 36, 23, 0, 2,
-  0, 0, 72, 39, 0, 0, 14, 29, 0, 0,
-  0, 0, 40, 0, 36, 14, 0, 1, 11, 0,
-  0, 0, 22, 32, 0, 52, 25, 0, 0, 0,
-  0, 42, 40, 0, 22, 0, 44, 0, 3, 0,
-  0, 33, 0, 0, 52, 0, 0, 0, 0, 10,
-  106, 0, 39, 32, 46, 45, 0, 59, 28, 0,
-  21, 0, 1, 31, 0, 0, 5, 21, 26, 0,
-  31, 0, 0, 0, 5, 0, 0, 0, 0, 52,
-  28, 23, 1, 0, 7, 59, 48, 1, 0, 29,
-  0, 28, 0, 8, 0, 0, 0, 0, 0, 12,
-  0, 0, 0, 0, 49, 26, 5, 0, 107, 66,
-  16, 65, 30, 0, 0, 17, 71, 14, 28, 0,
-  85, 0, 0, 80, 60, 0, 13, 0, 0, 32,
-  32, 6, 0, 0, 0, 61, 0, 37, 19, 69,
-  10, 6, 18, 5, 0, 44, 103, 0, 0, 23,
-  0, 23, 18, 0, 0, 0, 0, 0, 0, 86,
-  0, 0, 83, 13, 32, 36, 9, 0, 0, 0,
-  0, 0, 15, 55, 0, 0, 11, 0, 91, 19,
-  43, 55, 0, 39, 28, 49, 0, 26, 0, 0,
-  19, 64, 28, 26, 14, 0, 86, 0, 32, 0,
-  0, 14, 0, 0, 66, 0, 5, 67, 43, 0,
-  9, 0, 0, 58, 0, 60, 9, 0, 6, 0,
-  0, 0, 0, 0, 0, 0, 0, 15, 0, 4,
-  0, 18, 46, 15, 12, 30, 14, 0, 60, 29,
-  0, 164, 0, 0, 18, 0, 0, 0, 3, 20,
-  0, 48, 30, 38, 0, 0, 13, 76, 24, 1,
-  0, 0, 0, 35, 0, 48, 0, 88, 0, 0,
-  0, 20, 63, 58, 24, 0, 0, 0, 0, 0,
-  0, 11, 0, 0, 13, 0, 0, 83, 0, 0,
-  99, 0, 57, 0, 22, 0, 0, 57, 14, 0,
-  110, 0, 0, 29, 2, 76, 21, 14, 67, 27,
-  0, 44, 44, 26, 0, 0, 0, 0, 32, 108,
-  0, 10, 10, 0, 11, 0, 10, 13, 0, 0,
-  58, 0, 30, 0, 0, 71, 79, 0, 0, 0,
-  0, 18, 0, 26, 0, 0, 0, 0, 0, 0,
-  4, 4, 54, 0, 0, 35, 0, 18, 0, 0,
-  0, 17, 0, 23, 66, 10, 0, 31, 29, 110,
-  12, 0, 20, 0, 0, 9, 85, 0, 0, 46,
-  16, 30, 0, 0, 33, 111, 0, 60, 48, 0,
-  3, 44, 255, 0, 0, 72, 42, 37, 17, 24,
-  0, 22, 96, 20, 32, 0, 17, 61, 85, 122,
-  14, 0, 0, 23, 0, 130, 26, 0, 91, 47,
-  26, 11, 67, 0, 34, 60, 32, 28, 0, 46,
-  0, 4, 12, 28, 143, 0, 41, 3, 0, 22,
-  11, 56, 20, 0, 23, 0, 1, 24, 0, 0,
-  19, 5, 50, 28, 0, 55, 8, 0, 61, 18,
-  20, 0, 39, 55, 9, 30, 21, 7, 86, 7,
-  1, 22, 0, 7, 0, 16, 0, 0, 0, 31,
-  20, 0, 35, 34, 69, 0, 0, 44, 59, 0,
-  6, 4, 0, 38, 0, 0, 7, 72, 57, 6,
-  59, 17, 0, 6, 46, 16, 0, 163, 49, 58,
-  0, 0, 76, 0, 0, 90, 29, 28, 5, 40,
-  214, 33, 0, 0, 89, 29, 32, 0, 0, 53,
-  10, 75, 12, 0, 0, 45, 49, 87, 5, 9,
-  0, 73, 3, 65, 107, 1, 7, 49, 22, 23,
-  0, 54, 0, 5, 0, 32, 0, 1, 11, 0,
-  25, 0, 29, 0, 39, 11, 0, 97, 0, 37,
-  0, 1, 62, 0, 14, 26, 0, 4, 35, 12,
-  60, 53, 62, 78, 0, 3, 68, 5, 0, 0,
-  50, 64, 14, 0, 0, 0, 76, 0, 29, 16,
-  1, 58, 17, 0, 0, 22, 0, 0, 0, 12,
-  39, 12, 66, 4, 74, 0, 59, 0, 32, 0,
-  0, 58, 63, 0, 7, 0, 21, 41, 98, 32,
-  26, 34, 16, 64, 0, 150, 62, 63, 48, 14,
-  52, 0, 0, 72, 12, 0, 54, 79, 175, 35,
-  0, 0, 104, 0, 8, 0, 3, 53, 0, 34,
-  0, 0, 0, 32, 8, 71, 0, 0, 0, 50,
-  34, 80, 101, 18, 30, 0, 24, 14, 0, 49,
-  0, 0, 0, 16, 0, 0, 47, 0, 11, 29,
-  0, 0, 63, 28, 0, 75, 0, 60, 0, 1,
-  62, 4, 40, 45, 0, 23, 18, 40, 92, 24,
-  106, 1, 0, 0, 68, 0, 17, 0, 31, 98,
-  42, 0, 7, 0, 83, 0, 3, 51, 27, 30,
-  31, 0, 16, 5, 20, 0, 0, 18, 0, 32,
-  51, 0, 76, 0, 65, 0, 38, 22, 104, 21,
-  0, 47, 20, 66, 0, 0, 53, 0, 0, 0,
-  116, 0, 0, 40, 62, 0, 2, 0, 11, 68,
-  0, 8, 23, 0, 0, 43, 3, 1, 13, 72,
-  0, 27, 24, 0, 0, 21, 96, 5, 13, 87,
-  14, 47, 59, 16, 0, 0, 0, 0, 0, 111,
-  0, 0, 107, 59, 25, 17, 19, 0, 0, 13,
-  9, 35, 0, 93, 0, 0, 13, 0, 155, 30,
-  22, 32, 0, 0, 34, 19, 0, 47, 0, 0,
-  15, 14, 42, 14, 8, 0, 73, 0, 0, 0,
-  0, 2, 0, 0, 31, 0, 21, 50, 0, 0,
-  5, 0, 30, 31, 0, 67, 22, 0, 17, 0,
-  0, 0, 0, 0, 0, 0, 0, 1, 0, 3,
-  0, 16, 53, 0, 3, 16, 0, 0, 0, 0,
-  0, 145, 0, 0, 46, 0, 0, 0, 34, 21,
-  0, 109, 67, 48, 0, 0, 39, 1, 0, 58,
-  0, 0, 0, 56, 1, 0, 0, 0, 49, 0,
-  0, 0, 22, 71, 0, 0, 22, 0, 0, 3,
-  13, 87, 0, 0, 0, 14, 12, 53, 23, 0,
-  62, 19, 29, 0, 0, 0, 0, 48, 0, 0,
-  12, 0, 16, 0, 17, 13, 58, 0, 50, 76,
-  0, 66, 0, 52, 0, 0, 8, 0, 17, 64,
-  0, 25, 19, 0, 22, 2, 35, 128, 0, 0,
-  75, 0, 0, 0, 0, 93, 86, 0, 0, 0,
-  15, 0, 0, 38, 0, 19, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  13, 0, 4, 15, 0, 0, 92, 0, 0, 76,
-  0, 0, 44, 0, 0, 15, 13, 93, 0, 13,
-  41, 74, 27, 0, 22, 35, 4, 32, 0, 0,
-  0, 34, 0, 0, 18, 4, 5, 0, 0, 0,
-  14, 65, 0, 0, 0, 14, 0, 0, 0, 18,
-  0, 0, 0, 0, 19, 112, 26, 0, 66, 0,
-  49, 0, 1, 0, 0, 12, 0, 0, 37, 7,
-  27, 10, 26, 96, 0, 0, 36, 15, 0, 30,
-  0, 21, 0, 0, 0, 0, 33, 83, 0, 28,
-  14, 34, 42, 0, 16, 32, 0, 0, 39, 0,
-  0, 0, 13, 107, 45, 0, 0, 0, 3, 18,
-  0, 20, 0, 5, 17, 0, 0, 0, 49, 0,
-  46, 44, 22, 4, 0, 0, 0, 0, 20, 0,
-  0, 18, 107, 66, 16, 65, 30, 0, 0, 17,
-  71, 14, 28, 0, 85, 0, 0, 80, 60, 0,
-  13, 0, 0, 32, 32, 6, 0, 0, 0, 61,
-  0, 37, 19, 69, 10, 6, 18, 5, 0, 44,
-  103, 0, 0, 23, 0, 23, 18, 0, 0, 0,
-  0, 0, 0, 86, 0, 0, 83, 13, 32, 36,
-  9, 0, 0, 0, 0, 0, 15, 55, 0, 0,
-  11, 0, 91, 19, 43, 55, 0, 39, 28, 49,
-  0, 26, 0, 0, 19, 64, 28, 26, 14, 0,
-  86, 0, 32, 0, 0, 14, 0, 0, 66, 0,
-  5, 67, 43, 0, 9, 0, 0, 58, 0, 60,
-  9, 0, 6, 0, 0, 0, 0, 0, 0, 0,
-  0, 15, 0, 4, 0, 18, 46, 15, 12, 30,
-  14, 0, 60, 29, 0, 164, 0, 0, 18, 0,
-  0, 0, 3, 20, 0, 48, 30, 38, 0, 0,
-  13, 76, 24, 1, 0, 0, 0, 35, 0, 48,
-  0, 88, 0, 0, 0, 20, 63, 58, 24, 0,
-  0, 0, 0, 0, 0, 11, 0, 0, 13, 0,
-  0, 83, 0, 0, 99, 0, 57, 0, 22, 0,
-  0, 57, 14, 0, 110, 0, 0, 29, 2, 76,
-  21, 14, 67, 27, 0, 44, 44, 26, 0, 0,
-  0, 0, 32, 108, 0, 10, 10, 0, 11, 0,
-  10, 13, 0, 0, 58, 0, 30, 0, 0, 71,
-  79, 0, 0, 0, 0, 18, 0, 26, 0, 0,
-  0, 0, 0, 0, 4, 4, 54, 0, 0, 35,
-  0, 18, 0, 0, 0, 17, 0, 23, 0, 0,
-  70, 0, 4, 150, 0, 0, 0, 0, 0, 1,
-  23, 94, 0, 0, 0, 44, 0, 0, 21, 54,
-  0, 39, 0, 0, 0, 0, 0, 45, 16, 26,
-  0, 7, 0, 0, 0, 50, 0, 0, 0, 11,
-  0, 27, 0, 8, 1, 0, 0, 0, 12, 123,
-  0, 0, 39, 0, 39, 0, 42, 0, 0, 32,
-  0, 0, 97, 0, 0, 31, 0, 64, 0, 26,
-  51, 0, 0, 17, 0, 0, 0, 0, 0, 0,
-  27, 70, 21, 0, 16, 15, 54, 0, 0, 0,
-  24, 0, 2, 0, 0, 0, 0, 60, 12, 0,
-  0, 0, 0, 79, 0, 14, 0, 5, 25, 0,
-  0, 14, 51, 41, 105, 41, 29, 52, 23, 0,
-  0, 0, 17, 23, 0, 13, 0, 38, 0, 0,
-  7, 72, 57, 6, 59, 17, 0, 6, 46, 16,
-  0, 163, 49, 58, 0, 0, 76, 0, 0, 90,
-  29, 28, 5, 40, 214, 33, 0, 0, 89, 29,
-  32, 0, 0, 53, 10, 75, 12, 0, 0, 45,
-  49, 87, 5, 9, 0, 73, 3, 65, 107, 1,
-  7, 49, 22, 23, 0, 54, 0, 5, 0, 32,
-  0, 1, 11, 0, 25, 0, 29, 0, 39, 11,
-  0, 97, 0, 37, 0, 1, 62, 0, 14, 26,
-  0, 4, 35, 12, 60, 53, 62, 78, 0, 3,
-  68, 5, 0, 0, 50, 64, 14, 0, 0, 0,
-  76, 0, 29, 16, 1, 58, 17, 0, 0, 22,
-  0, 0, 0, 12, 39, 12, 66, 4, 74, 0,
-  59, 0, 32, 0, 0, 58, 63, 0, 7, 0,
-  21, 41, 98, 32, 26, 34, 16, 64, 0, 150,
-  62, 63, 48, 14, 52, 0, 0, 72, 12, 0,
-  54, 79, 175, 35, 0, 0, 104, 0, 8, 0,
-  3, 53, 0, 34, 0, 0, 0, 32, 8, 71,
-  0, 0, 0, 50, 34, 80, 101, 18, 30, 0,
-  24, 14, 0, 49, 0, 0, 0, 16, 0, 0,
-  47, 0, 11, 29, 0, 0, 63, 28, 0, 75,
-  0, 60, 0, 1, 62, 4, 40, 45, 0, 23,
-  18, 40, 92, 24, 106, 1, 0, 0, 68, 0,
-  17, 0, 31, 98, 42, 0, 7, 0, 83, 0,
-  3, 51, 27, 30, 31, 0, 16, 5, 20, 0,
-  0, 18, 0, 32, 51, 0, 76, 0, 65, 0,
-  38, 22, 50, 21, 117, 0, 0, 33, 0, 34,
-  48, 0, 0, 21, 0, 97, 0, 11, 24, 76,
-  56, 29, 7, 79, 14, 26, 0, 0, 21, 72,
-  178, 23, 2, 77, 15, 0, 0, 17, 0, 58,
-  0, 0, 0, 0, 23, 6, 0, 52, 0, 0,
-  0, 0, 17, 138, 16, 0, 76, 0, 43, 0,
-  26, 0, 0, 0, 10, 14, 41, 10, 2, 8,
-  11, 125, 0, 0, 81, 0, 0, 29, 11, 26,
-  12, 0, 0, 0, 1, 82, 0, 0, 46, 37,
-  66, 0, 39, 0, 0, 0, 91, 0, 6, 0,
-  15, 66, 24, 0, 23, 6, 85, 90, 0, 23,
-  0, 0, 42, 20, 11, 6, 52, 0, 44, 28,
-  0, 49, 48, 0, 0, 0, 21, 0, 24, 28,
-  0, 0, 0, 0, 0, 145, 0, 0, 46, 0,
-  0, 0, 34, 21, 0, 109, 67, 48, 0, 0,
-  39, 1, 0, 58, 0, 0, 0, 56, 1, 0,
-  0, 0, 49, 0, 0, 0, 22, 71, 0, 0,
-  22, 0, 0, 3, 13, 87, 0, 0, 0, 14,
-  12, 53, 23, 0, 62, 19, 29, 0, 0, 0,
-  0, 48, 0, 0, 12, 0, 16, 0, 17, 13,
-  58, 0, 50, 76, 0, 66, 0, 52, 0, 0,
-  8, 0, 17, 64, 0, 25, 19, 0, 22, 2,
-  35, 128, 0, 0, 75, 0, 0, 0, 0, 93,
-  86, 0, 0, 0, 15, 0, 0, 38, 0, 19,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 13, 0, 4, 15, 0, 0,
-  92, 0, 0, 76, 0, 0, 44, 0, 0, 15,
-  13, 93, 0, 13, 41, 74, 27, 0, 22, 35,
-  4, 32, 0, 0, 0, 34, 0, 0, 18, 4,
-  5, 0, 0, 0, 14, 65, 0, 0, 0, 14,
-  0, 0, 0, 18, 0, 0, 0, 0, 19, 112,
-  26, 0, 66, 0, 49, 0, 1, 0, 0, 12,
-  0, 0, 37, 7, 27, 10, 26, 96, 0, 0,
-  36, 15, 0, 30, 0, 21, 0, 0, 0, 0,
-  33, 83, 0, 28, 14, 34, 42, 0, 16, 32,
-  0, 0, 39, 0, 0, 0, 13, 107, 45, 0,
-  0, 0, 3, 18, 0, 20, 0, 5, 17, 0,
-  0, 0, 49, 0, 46, 44, 22, 4, 0, 0,
-  0, 0, 20, 0, 0, 18, 0, 0, 91, 0,
-  0, 56, 0, 0, 0, 0, 0, 21, 6, 68,
-  0, 0, 3, 66, 22, 26, 0, 44, 1, 12,
-  25, 0, 0, 0, 0, 0, 35, 19, 0, 0,
-  0, 0, 0, 41, 0, 0, 0, 9, 0, 13,
-  0, 4, 17, 0, 0, 0, 11, 90, 12, 0,
-  37, 0, 34, 0, 44, 0, 0, 20, 0, 0,
-  71, 0, 0, 58, 0, 66, 0, 22, 34, 0,
-  4, 12, 0, 0, 14, 0, 0, 0, 11, 67,
-  48, 0, 47, 25, 46, 0, 0, 0, 0, 0,
-  2, 0, 0, 5, 16, 47, 0, 0, 0, 1,
-  0, 93, 0, 9, 0, 23, 27, 12, 0, 4,
-  70, 6, 57, 62, 45, 37, 28, 1, 0, 0,
-  18, 8, 3, 27, 14, 0, 60, 29, 0, 164,
-  0, 0, 18, 0, 0, 0, 3, 20, 0, 48,
-  30, 38, 0, 0, 13, 76, 24, 1, 0, 0,
-  0, 35, 0, 48, 0, 88, 0, 0, 0, 20,
-  63, 58, 24, 0, 0, 0, 0, 0, 0, 11,
-  0, 0, 13, 0, 0, 83, 0, 0, 99, 0,
-  57, 0, 22, 0, 0, 57, 14, 0, 110, 0,
-  0, 29, 2, 76, 21, 14, 67, 27, 0, 44,
-  44, 26, 0, 0, 0, 0, 32, 108, 0, 10,
-  10, 0, 11, 0, 10, 13, 0, 0, 58, 0,
-  30, 0, 0, 71, 79, 0, 0, 0, 0, 18,
-  0, 26, 0, 0, 0, 0, 0, 0, 4, 4,
-  54, 0, 0, 35, 0, 18, 0, 0, 0, 17,
-  0, 23, 0, 0, 70, 0, 4, 150, 0, 0,
-  0, 0, 0, 1, 23, 94, 0, 0, 0, 44,
-  0, 0, 21, 54, 0, 39, 0, 0, 0, 0,
-  0, 45, 16, 26, 0, 7, 0, 0, 0, 50,
-  0, 0, 0, 11, 0, 27, 0, 8, 1, 0,
-  0, 0, 12, 123, 0, 0, 39, 0, 39, 0,
-  42, 0, 0, 32, 0, 0, 97, 0, 0, 31,
-  0, 64, 0, 26, 51, 0, 0, 17, 0, 0,
-  0, 0, 0, 0, 27, 70, 21, 0, 16, 15,
-  54, 0, 0, 0, 24, 0, 2, 0, 0, 0,
-  0, 60, 12, 0, 0, 0, 0, 79, 0, 14,
-  0, 5, 25, 0, 0, 14, 51, 41, 105, 41,
-  29, 52, 23, 0, 0, 0, 17, 23, 0, 13,
-  0, 43, 48, 0, 24, 32, 13, 0, 8, 0,
-  0, 0, 63, 49, 0, 0, 3, 17, 8, 10,
-  0, 0, 0, 37, 41, 35, 6, 0, 0, 48,
-  48, 0, 0, 14, 0, 0, 0, 2, 0, 39,
-  0, 40, 0, 41, 21, 0, 3, 0, 0, 0,
-  0, 40, 61, 0, 0, 0, 14, 6, 2, 35,
-  0, 6, 0, 21, 0, 0, 0, 27, 0, 0,
-  0, 32, 20, 0, 21, 28, 0, 0, 0, 25,
-  16, 25, 21, 40, 63, 0, 39, 18, 50, 13,
-  0, 0, 32, 28, 0, 22, 0, 38, 15, 31,
-  0, 0, 0, 0, 0, 28, 14, 0, 53, 57,
-  40, 0, 0, 20, 46, 0, 33, 38, 62, 29,
-  61, 16, 47, 0, 46, 37, 0, 1, 0, 58,
-  63, 0, 7, 0, 21, 41, 98, 32, 26, 34,
-  16, 64, 0, 150, 62, 63, 48, 14, 52, 0,
-  0, 72, 12, 0, 54, 79, 175, 35, 0, 0,
-  104, 0, 8, 0, 3, 53, 0, 34, 0, 0,
-  0, 32, 8, 71, 0, 0, 0, 50, 34, 80,
-  101, 18, 30, 0, 24, 14, 0, 49, 0, 0,
-  0, 16, 0, 0, 47, 0, 11, 29, 0, 0,
-  63, 28, 0, 75, 0, 60, 0, 1, 62, 4,
-  40, 45, 0, 23, 18, 40, 92, 24, 106, 1,
-  0, 0, 68, 0, 17, 0, 31, 98, 42, 0,
-  7, 0, 83, 0, 3, 51, 27, 30, 31, 0,
-  16, 5, 20, 0, 0, 18, 0, 32, 51, 0,
-  76, 0, 65, 0, 38, 22, 50, 21, 117, 0,
-  0, 33, 0, 34, 48, 0, 0, 21, 0, 97,
-  0, 11, 24, 76, 56, 29, 7, 79, 14, 26,
-  0, 0, 21, 72, 178, 23, 2, 77, 15, 0,
-  0, 17, 0, 58, 0, 0, 0, 0, 23, 6,
-  0, 52, 0, 0, 0, 0, 17, 138, 16, 0,
-  76, 0, 43, 0, 26, 0, 0, 0, 10, 14,
-  41, 10, 2, 8, 11, 125, 0, 0, 81, 0,
-  0, 29, 11, 26, 12, 0, 0, 0, 1, 82,
-  0, 0, 46, 37, 66, 0, 39, 0, 0, 0,
-  91, 0, 6, 0, 15, 66, 24, 0, 23, 6,
-  85, 90, 0, 23, 0, 0, 42, 20, 11, 6,
-  52, 0, 44, 28, 0, 49, 48, 0, 0, 0,
-  21, 0, 24, 28, 37, 2, 61, 0, 0, 73,
-  0, 0, 0, 0, 0, 0, 0, 114, 0, 0,
-  5, 58, 36, 11, 0, 72, 12, 49, 0, 0,
-  26, 41, 217, 0, 0, 48, 0, 41, 0, 0,
-  6, 3, 0, 0, 0, 0, 13, 0, 0, 63,
-  19, 55, 0, 0, 20, 92, 0, 0, 70, 0,
-  42, 0, 39, 0, 25, 1, 0, 0, 74, 12,
-  10, 4, 28, 139, 25, 13, 70, 0, 0, 6,
-  18, 0, 2, 4, 0, 0, 4, 80, 0, 0,
-  46, 48, 69, 0, 0, 0, 12, 0, 60, 0,
-  0, 0, 11, 29, 28, 90, 42, 8, 49, 129,
-  4, 0, 0, 1, 4, 23, 0, 0, 30, 66,
-  51, 23, 16, 39, 2, 0, 0, 0, 0, 0,
-  0, 44, 0, 0, 92, 0, 0, 76, 0, 0,
-  44, 0, 0, 15, 13, 93, 0, 13, 41, 74,
-  27, 0, 22, 35, 4, 32, 0, 0, 0, 34,
-  0, 0, 18, 4, 5, 0, 0, 0, 14, 65,
-  0, 0, 0, 14, 0, 0, 0, 18, 0, 0,
-  0, 0, 19, 112, 26, 0, 66, 0, 49, 0,
-  1, 0, 0, 12, 0, 0, 37, 7, 27, 10,
-  26, 96, 0, 0, 36, 15, 0, 30, 0, 21,
-  0, 0, 0, 0, 33, 83, 0, 28, 14, 34,
-  42, 0, 16, 32, 0, 0, 39, 0, 0, 0,
-  13, 107, 45, 0, 0, 0, 3, 18, 0, 20,
-  0, 5, 17, 0, 0, 0, 49, 0, 46, 44,
-  22, 4, 0, 0, 0, 0, 20, 0, 0, 18,
-  0, 0, 91, 0, 0, 56, 0, 0, 0, 0,
-  0, 21, 6, 68, 0, 0, 3, 66, 22, 26,
-  0, 44, 1, 12, 25, 0, 0, 0, 0, 0,
-  35, 19, 0, 0, 0, 0, 0, 41, 0, 0,
-  0, 9, 0, 13, 0, 4, 17, 0, 0, 0,
-  11, 90, 12, 0, 37, 0, 34, 0, 44, 0,
-  0, 20, 0, 0, 71, 0, 0, 58, 0, 66,
-  0, 22, 34, 0, 4, 12, 0, 0, 14, 0,
-  0, 0, 11, 67, 48, 0, 47, 25, 46, 0,
-  0, 0, 0, 0, 2, 0, 0, 5, 16, 47,
-  0, 0, 0, 1, 0, 93, 0, 9, 0, 23,
-  27, 12, 0, 4, 70, 6, 57, 62, 45, 37,
-  28, 1, 0, 0, 18, 8, 3, 27, 0, 16,
-  49, 0, 0, 5, 31, 0, 1, 0, 0, 6,
-  0, 41, 0, 0, 0, 25, 35, 4, 0, 0,
-  0, 52, 24, 0, 16, 5, 179, 11, 21, 0,
-  23, 0, 0, 0, 0, 11, 0, 43, 0, 24,
-  1, 8, 2, 65, 31, 0, 0, 0, 0, 37,
-  49, 0, 7, 0, 6, 0, 40, 14, 28, 28,
-  0, 0, 0, 18, 44, 18, 0, 7, 0, 39,
-  35, 0, 13, 18, 0, 0, 20, 0, 17, 2,
-  0, 51, 0, 0, 32, 30, 78, 35, 0, 0,
-  40, 0, 0, 22, 0, 0, 33, 23, 14, 18,
-  8, 0, 15, 74, 44, 16, 21, 36, 0, 12,
-  0, 0, 6, 34, 56, 40, 46, 34, 33, 8,
-  0, 0, 18, 0, 14, 30, 0, 0, 70, 0,
-  4, 150, 0, 0, 0, 0, 0, 1, 23, 94,
-  0, 0, 0, 44, 0, 0, 21, 54, 0, 39,
-  0, 0, 0, 0, 0, 45, 16, 26, 0, 7,
-  0, 0, 0, 50, 0, 0, 0, 11, 0, 27,
-  0, 8, 1, 0, 0, 0, 12, 123, 0, 0,
-  39, 0, 39, 0, 42, 0, 0, 32, 0, 0,
-  97, 0, 0, 31, 0, 64, 0, 26, 51, 0,
-  0, 17, 0, 0, 0, 0, 0, 0, 27, 70,
-  21, 0, 16, 15, 54, 0, 0, 0, 24, 0,
-  2, 0, 0, 0, 0, 60, 12, 0, 0, 0,
-  0, 79, 0, 14, 0, 5, 25, 0, 0, 14,
-  51, 41, 105, 41, 29, 52, 23, 0, 0, 0,
-  17, 23, 0, 13, 0, 43, 48, 0, 24, 32,
-  13, 0, 8, 0, 0, 0, 63, 49, 0, 0,
-  3, 17, 8, 10, 0, 0, 0, 37, 41, 35,
-  6, 0, 0, 48, 48, 0, 0, 14, 0, 0,
-  0, 2, 0, 39, 0, 40, 0, 41, 21, 0,
-  3, 0, 0, 0, 0, 40, 61, 0, 0, 0,
-  14, 6, 2, 35, 0, 6, 0, 21, 0, 0,
-  0, 27, 0, 0, 0, 32, 20, 0, 21, 28,
-  0, 0, 0, 25, 16, 25, 21, 40, 63, 0,
-  39, 18, 50, 13, 0, 0, 32, 28, 0, 22,
-  0, 38, 15, 31, 0, 0, 0, 0, 0, 28,
-  14, 0, 53, 57, 40, 0, 0, 20, 46, 0,
-  33, 38, 62, 29, 61, 16, 47, 0, 46, 37,
-  0, 1, 0, 41, 74, 0, 7, 0, 37, 0,
-  26, 0, 0, 0, 8, 45, 0, 15, 14, 0,
-  13, 0, 0, 0, 20, 55, 23, 53, 16, 0,
-  159, 1, 19, 0, 8, 19, 20, 0, 0, 0,
-  0, 81, 7, 52, 28, 35, 49, 21, 9, 3,
-  0, 0, 0, 24, 50, 0, 0, 0, 1, 33,
-  4, 24, 7, 14, 0, 0, 0, 27, 51, 0,
-  10, 0, 0, 31, 38, 26, 32, 14, 0, 0,
-  0, 32, 48, 29, 26, 13, 31, 0, 3, 25,
-  74, 17, 4, 0, 45, 17, 0, 32, 0, 0,
-  21, 15, 0, 0, 0, 0, 6, 22, 50, 8,
-  38, 32, 47, 0, 0, 0, 1, 0, 13, 0,
-  30, 2, 0, 0, 24, 0, 46, 24, 32, 0,
-  50, 21, 117, 0, 0, 33, 0, 34, 48, 0,
-  0, 21, 0, 97, 0, 11, 24, 76, 56, 29,
-  7, 79, 14, 26, 0, 0, 21, 72, 178, 23,
-  2, 77, 15, 0, 0, 17, 0, 58, 0, 0,
-  0, 0, 23, 6, 0, 52, 0, 0, 0, 0,
-  17, 138, 16, 0, 76, 0, 43, 0, 26, 0,
-  0, 0, 10, 14, 41, 10, 2, 8, 11, 125,
-  0, 0, 81, 0, 0, 29, 11, 26, 12, 0,
-  0, 0, 1, 82, 0, 0, 46, 37, 66, 0,
-  39, 0, 0, 0, 91, 0, 6, 0, 15, 66,
-  24, 0, 23, 6, 85, 90, 0, 23, 0, 0,
-  42, 20, 11, 6, 52, 0, 44, 28, 0, 49,
-  48, 0, 0, 0, 21, 0, 24, 28, 37, 2,
-  61, 0, 0, 73, 0, 0, 0, 0, 0, 0,
-  0, 114, 0, 0, 5, 58, 36, 11, 0, 72,
-  12, 49, 0, 0, 26, 41, 217, 0, 0, 48,
-  0, 41, 0, 0, 6, 3, 0, 0, 0, 0,
-  13, 0, 0, 63, 19, 55, 0, 0, 20, 92,
-  0, 0, 70, 0, 42, 0, 39, 0, 25, 1,
-  0, 0, 74, 12, 10, 4, 28, 139, 25, 13,
-  70, 0, 0, 6, 18, 0, 2, 4, 0, 0,
-  4, 80, 0, 0, 46, 48, 69, 0, 0, 0,
-  12, 0, 60, 0, 0, 0, 11, 29, 28, 90,
-  42, 8, 49, 129, 4, 0, 0, 1, 4, 23,
-  0, 0, 30, 66, 51, 23, 16, 39, 2, 0,
-  0, 0, 0, 0, 0, 44, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 91, 0, 0, 56,
-  0, 0, 0, 0, 0, 21, 6, 68, 0, 0,
-  3, 66, 22, 26, 0, 44, 1, 12, 25, 0,
-  0, 0, 0, 0, 35, 19, 0, 0, 0, 0,
-  0, 41, 0, 0, 0, 9, 0, 13, 0, 4,
-  17, 0, 0, 0, 11, 90, 12, 0, 37, 0,
-  34, 0, 44, 0, 0, 20, 0, 0, 71, 0,
-  0, 58, 0, 66, 0, 22, 34, 0, 4, 12,
-  0, 0, 14, 0, 0, 0, 11, 67, 48, 0,
-  47, 25, 46, 0, 0, 0, 0, 0, 2, 0,
-  0, 5, 16, 47, 0, 0, 0, 1, 0, 93,
-  0, 9, 0, 23, 27, 12, 0, 4, 70, 6,
-  57, 62, 45, 37, 28, 1, 0, 0, 18, 8,
-  3, 27, 0, 16, 49, 0, 0, 5, 31, 0,
-  1, 0, 0, 6, 0, 41, 0, 0, 0, 25,
-  35, 4, 0, 0, 0, 52, 24, 0, 16, 5,
-  179, 11, 21, 0, 23, 0, 0, 0, 0, 11,
-  0, 43, 0, 24, 1, 8, 2, 65, 31, 0,
-  0, 0, 0, 37, 49, 0, 7, 0, 6, 0,
-  40, 14, 28, 28, 0, 0, 0, 18, 44, 18,
-  0, 7, 0, 39, 35, 0, 13, 18, 0, 0,
-  20, 0, 17, 2, 0, 51, 0, 0, 32, 30,
-  78, 35, 0, 0, 40, 0, 0, 22, 0, 0,
-  33, 23, 14, 18, 8, 0, 15, 74, 44, 16,
-  21, 36, 0, 12, 0, 0, 6, 34, 56, 40,
-  46, 34, 33, 8, 0, 0, 18, 0, 14, 30,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 43,
-  48, 0, 24, 32, 13, 0, 8, 0, 0, 0,
-  63, 49, 0, 0, 3, 17, 8, 10, 0, 0,
-  0, 37, 41, 35, 6, 0, 0, 48, 48, 0,
-  0, 14, 0, 0, 0, 2, 0, 39, 0, 40,
-  0, 41, 21, 0, 3, 0, 0, 0, 0, 40,
-  61, 0, 0, 0, 14, 6, 2, 35, 0, 6,
-  0, 21, 0, 0, 0, 27, 0, 0, 0, 32,
-  20, 0, 21, 28, 0, 0, 0, 25, 16, 25,
-  21, 40, 63, 0, 39, 18, 50, 13, 0, 0,
-  32, 28, 0, 22, 0, 38, 15, 31, 0, 0,
-  0, 0, 0, 28, 14, 0, 53, 57, 40, 0,
-  0, 20, 46, 0, 33, 38, 62, 29, 61, 16,
-  47, 0, 46, 37, 0, 1, 0, 41, 74, 0,
-  7, 0, 37, 0, 26, 0, 0, 0, 8, 45,
-  0, 15, 14, 0, 13, 0, 0, 0, 20, 55,
-  23, 53, 16, 0, 159, 1, 19, 0, 8, 19,
-  20, 0, 0, 0, 0, 81, 7, 52, 28, 35,
-  49, 21, 9, 3, 0, 0, 0, 24, 50, 0,
-  0, 0, 1, 33, 4, 24, 7, 14, 0, 0,
-  0, 27, 51, 0, 10, 0, 0, 31, 38, 26,
-  32, 14, 0, 0, 0, 32, 48, 29, 26, 13,
-  31, 0, 3, 25, 74, 17, 4, 0, 45, 17,
-  0, 32, 0, 0, 21, 15, 0, 0, 0, 0,
-  6, 22, 50, 8, 38, 32, 47, 0, 0, 0,
-  1, 0, 13, 0, 30, 2, 0, 0, 24, 0,
-  46, 24, 32, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  12, 21, 64, 6, 0, 0, 17, 8, 0, 10,
-  24, 0, 0, 65, 0, 74, 92, 76, 35, 40,
-  22, 3, 39, 33, 0, 0, 31, 58, 156, 6,
-  15, 0, 58, 0, 0, 0, 0, 18, 0, 18,
-  5, 27, 0, 0, 53, 31, 0, 18, 0, 0,
-  0, 47, 40, 0, 10, 0, 0, 9, 0, 6,
-  28, 0, 0, 0, 0, 7, 44, 0, 48, 45,
-  0, 16, 17, 16, 28, 6, 22, 3, 0, 16,
-  38, 0, 14, 0, 0, 13, 0, 23, 45, 25,
-  8, 25, 0, 0, 67, 0, 51, 0, 0, 39,
-  3, 0, 27, 11, 67, 0, 18, 0, 0, 0,
-  20, 21, 9, 43, 3, 0, 12, 0, 0, 0,
-  64, 0, 5, 0, 0, 0, 55, 0, 56, 59,
-  50, 27, 4, 0, 2, 0, 0, 0, 8, 0,
-  48, 60, 4, 28, 76, 49, 0, 0, 0, 6,
-  1, 61, 24, 0, 35, 40, 0, 0, 13, 0,
-  67, 0, 0, 0, 0, 0, 0, 1, 0, 66,
-  2, 0, 30, 28, 26, 42, 0, 12, 0, 69,
-  96, 0, 23, 0, 0, 0, 0, 0, 51, 0,
-  0, 65, 0, 8, 82, 0, 40, 45, 0, 20,
-  0, 33, 32, 0, 14, 3, 0, 16, 42, 0,
-  37, 0, 0, 30, 0, 27, 36, 9, 13, 0,
-  0, 22, 2, 0, 70, 5, 0, 64, 0, 23,
-  40, 0, 76, 0, 6, 0, 58, 8, 17, 40,
-  5, 0, 26, 0, 1, 0, 0, 0, 39, 0,
-  71, 0, 10, 9, 14, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 47, 23, 86, 28, 0, 0,
-  29, 6, 18, 0, 12, 0, 0, 94, 0, 55,
-  94, 25, 14, 29, 7, 39, 13, 18, 25, 0,
-  29, 32, 164, 9, 5, 45, 79, 0, 0, 0,
-  0, 37, 0, 0, 0, 4, 0, 10, 7, 71,
-  53, 0, 0, 0, 0, 40, 22, 15, 17, 0,
-  13, 0, 0, 3, 39, 29, 0, 0, 0, 0,
-  72, 0, 119, 51, 0, 0, 21, 0, 24, 0,
-  65, 11, 0, 23, 14, 0, 42, 0, 0, 26,
-  0, 0, 59, 5, 0, 16, 0, 5, 15, 0,
-  38, 1, 14, 93, 25, 0, 14, 51, 54, 47,
-  12, 0, 25, 0, 4, 10, 0, 41, 10, 0,
-  18, 0, 17, 0, 59, 0, 0, 0, 0, 24,
-  48, 21, 43, 69, 0, 8, 5, 11, 0, 0,
-  0, 0, 0, 0, 16, 73, 0, 0, 82, 18,
-  0, 0, 0, 41, 0, 50, 15, 0, 5, 16,
-  0, 0, 0, 19, 83, 23, 0, 0, 0, 9,
-  0, 0, 0, 6, 0, 0, 9, 74, 35, 102,
-  0, 0, 0, 29, 56, 0, 22, 0, 18, 0,
-  0, 0, 78, 24, 0, 51, 0, 0, 97, 0,
-  107, 49, 0, 0, 4, 13, 45, 0, 27, 0,
-  0, 5, 25, 0, 35, 12, 0, 12, 0, 6,
-  0, 6, 0, 26, 0, 19, 1, 0, 34, 0,
-  12, 95, 20, 81, 35, 21, 44, 44, 10, 0,
-  51, 0, 0, 63, 0, 7, 0, 0, 0, 0,
-  11, 0, 22, 0, 33, 0, 0, 27, 27, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 23, 32,
-  93, 27, 1, 9, 26, 5, 18, 0, 0, 0,
-  0, 103, 0, 30, 67, 4, 0, 16, 13, 75,
-  10, 41, 20, 0, 6, 20, 201, 42, 3, 62,
-  71, 0, 24, 0, 0, 56, 0, 4, 5, 32,
-  0, 22, 9, 88, 48, 0, 0, 0, 0, 51,
-  21, 3, 55, 0, 44, 0, 32, 0, 31, 72,
-  0, 0, 0, 0, 48, 9, 120, 30, 0, 10,
-  58, 0, 32, 0, 53, 0, 0, 37, 0, 0,
-  36, 11, 0, 15, 0, 0, 58, 5, 0, 0,
-  0, 3, 0, 36, 0, 0, 40, 101, 17, 0,
-  0, 52, 55, 89, 20, 0, 9, 0, 2, 9,
-  0, 33, 6, 2, 40, 0, 19, 12, 51, 0,
-  0, 0, 3, 0, 39, 30, 0, 67, 0, 11,
-  0, 33, 2, 0, 0, 0, 0, 17, 28, 49,
-  0, 0, 52, 3, 0, 0, 28, 58, 0, 42,
-  19, 0, 0, 8, 0, 9, 0, 26, 82, 21,
-  0, 0, 0, 27, 0, 8, 0, 40, 0, 22,
-  24, 91, 9, 110, 0, 0, 0, 27, 50, 0,
-  37, 0, 28, 0, 14, 0, 55, 50, 0, 43,
-  0, 0, 49, 11, 81, 0, 4, 0, 22, 7,
-  42, 0, 12, 0, 0, 26, 21, 0, 21, 24,
-  0, 0, 0, 0, 0, 9, 0, 0, 0, 9,
-  0, 20, 0, 0, 47, 83, 0, 52, 17, 21,
-  41, 51, 25, 0, 40, 5, 0, 40, 0, 11,
-  0, 0, 21, 0, 13, 13, 31, 0, 15, 0,
-  35, 1, 15, 0, 12, 21, 64, 6, 0, 0,
-  17, 8, 0, 10, 24, 0, 0, 65, 0, 74,
-  92, 76, 35, 40, 22, 3, 39, 33, 0, 0,
-  31, 58, 156, 6, 15, 0, 58, 0, 0, 0,
-  0, 18, 0, 18, 5, 27, 0, 0, 53, 31,
-  0, 18, 0, 0, 0, 47, 40, 0, 10, 0,
-  0, 9, 0, 6, 28, 0, 0, 0, 0, 7,
-  44, 0, 48, 45, 0, 16, 17, 16, 28, 6,
-  22, 3, 0, 16, 38, 0, 14, 0, 0, 13,
-  0, 23, 45, 25, 8, 25, 0, 0, 67, 0,
-  51, 0, 0, 39, 3, 0, 27, 11, 67, 0,
-  18, 0, 0, 0, 20, 21, 9, 43, 3, 0,
-  12, 0, 0, 0, 64, 0, 5, 0, 0, 0,
-  55, 0, 56, 59, 50, 27, 4, 0, 2, 0,
-  0, 0, 8, 0, 48, 60, 4, 28, 76, 49,
-  0, 0, 0, 6, 1, 61, 24, 0, 35, 40,
-  0, 0, 13, 0, 67, 0, 0, 0, 0, 0,
-  0, 1, 0, 66, 2, 0, 30, 28, 26, 42,
-  0, 12, 0, 69, 96, 0, 23, 0, 0, 0,
-  0, 0, 51, 0, 0, 65, 0, 8, 82, 0,
-  40, 45, 0, 20, 0, 33, 32, 0, 14, 3,
-  0, 16, 42, 0, 37, 0, 0, 30, 0, 27,
-  36, 9, 13, 0, 0, 22, 2, 0, 70, 5,
-  0, 64, 0, 23, 40, 0, 76, 0, 6, 0,
-  58, 8, 17, 40, 5, 0, 26, 0, 1, 0,
-  0, 0, 39, 0, 71, 0, 10, 9, 14, 0,
-  2, 55, 59, 38, 4, 35, 16, 13, 17, 0,
-  0, 16, 84, 0, 0, 22, 51, 18, 0, 0,
-  0, 56, 0, 33, 67, 0, 5, 30, 0, 0,
-  0, 43, 70, 0, 18, 0, 0, 0, 0, 41,
-  0, 35, 57, 2, 29, 80, 44, 19, 0, 21,
-  0, 34, 36, 10, 35, 0, 10, 0, 0, 0,
-  30, 26, 0, 32, 0, 0, 35, 1, 27, 0,
-  0, 17, 9, 19, 26, 0, 10, 16, 0, 22,
-  23, 0, 61, 69, 0, 5, 0, 0, 0, 42,
-  5, 0, 0, 31, 0, 24, 35, 0, 0, 65,
-  2, 0, 10, 12, 63, 0, 37, 0, 27, 0,
-  0, 14, 0, 0, 0, 0, 0, 0, 0, 0,
-  4, 0, 41, 0, 35, 0, 8, 0, 47, 23,
-  86, 28, 0, 0, 29, 6, 18, 0, 12, 0,
-  0, 94, 0, 55, 94, 25, 14, 29, 7, 39,
-  13, 18, 25, 0, 29, 32, 164, 9, 5, 45,
-  79, 0, 0, 0, 0, 37, 0, 0, 0, 4,
-  0, 10, 7, 71, 53, 0, 0, 0, 0, 40,
-  22, 15, 17, 0, 13, 0, 0, 3, 39, 29,
-  0, 0, 0, 0, 72, 0, 119, 51, 0, 0,
-  21, 0, 24, 0, 65, 11, 0, 23, 14, 0,
-  42, 0, 0, 26, 0, 0, 59, 5, 0, 16,
-  0, 5, 15, 0, 38, 1, 14, 93, 25, 0,
-  14, 51, 54, 47, 12, 0, 25, 0, 4, 10,
-  0, 41, 10, 0, 18, 0, 17, 0, 59, 0,
-  0, 0, 0, 24, 48, 21, 43, 69, 0, 8,
-  5, 11, 0, 0, 0, 0, 0, 0, 16, 73,
-  0, 0, 82, 18, 0, 0, 0, 41, 0, 50,
-  15, 0, 5, 16, 0, 0, 0, 19, 83, 23,
-  0, 0, 0, 9, 0, 0, 0, 6, 0, 0,
-  9, 74, 35, 102, 0, 0, 0, 29, 56, 0,
-  22, 0, 18, 0, 0, 0, 78, 24, 0, 51,
-  0, 0, 97, 0, 107, 49, 0, 0, 4, 13,
-  45, 0, 27, 0, 0, 5, 25, 0, 35, 12,
-  0, 12, 0, 6, 0, 6, 0, 26, 0, 19,
-  1, 0, 34, 0, 12, 95, 20, 81, 35, 21,
-  44, 44, 10, 0, 51, 0, 0, 63, 0, 7,
-  0, 0, 0, 0, 11, 0, 22, 0, 33, 0,
-  0, 27, 27, 0, 0, 39, 39, 29, 0, 48,
-  7, 15, 23, 0, 0, 11, 81, 0, 0, 23,
-  58, 7, 0, 0, 0, 63, 0, 21, 41, 0,
-  0, 12, 0, 0, 0, 32, 67, 3, 1, 0,
-  0, 13, 0, 47, 0, 18, 41, 13, 22, 69,
-  25, 53, 0, 12, 0, 37, 21, 7, 22, 0,
-  22, 0, 0, 0, 16, 31, 0, 29, 0, 0,
-  7, 0, 37, 0, 18, 0, 9, 21, 4, 0,
-  5, 11, 0, 39, 27, 0, 62, 62, 0, 0,
-  0, 0, 0, 18, 1, 0, 0, 19, 0, 19,
-  32, 0, 0, 78, 11, 0, 0, 10, 15, 0,
-  33, 0, 0, 0, 0, 8, 0, 0, 0, 0,
-  7, 0, 0, 0, 0, 0, 38, 0, 39, 0,
-  9, 0, 23, 32, 93, 27, 1, 9, 26, 5,
-  18, 0, 0, 0, 0, 103, 0, 30, 67, 4,
-  0, 16, 13, 75, 10, 41, 20, 0, 6, 20,
-  201, 42, 3, 62, 71, 0, 24, 0, 0, 56,
-  0, 4, 5, 32, 0, 22, 9, 88, 48, 0,
-  0, 0, 0, 51, 21, 3, 55, 0, 44, 0,
-  32, 0, 31, 72, 0, 0, 0, 0, 48, 9,
-  120, 30, 0, 10, 58, 0, 32, 0, 53, 0,
-  0, 37, 0, 0, 36, 11, 0, 15, 0, 0,
-  58, 5, 0, 0, 0, 3, 0, 36, 0, 0,
-  40, 101, 17, 0, 0, 52, 55, 89, 20, 0,
-  9, 0, 2, 9, 0, 33, 6, 2, 40, 0,
-  19, 12, 51, 0, 0, 0, 3, 0, 39, 30,
-  0, 67, 0, 11, 0, 33, 2, 0, 0, 0,
-  0, 17, 28, 49, 0, 0, 52, 3, 0, 0,
-  28, 58, 0, 42, 19, 0, 0, 8, 0, 9,
-  0, 26, 82, 21, 0, 0, 0, 27, 0, 8,
-  0, 40, 0, 22, 24, 91, 9, 110, 0, 0,
-  0, 27, 50, 0, 37, 0, 28, 0, 14, 0,
-  55, 50, 0, 43, 0, 0, 49, 11, 81, 0,
-  4, 0, 22, 7, 42, 0, 12, 0, 0, 26,
-  21, 0, 21, 24, 0, 0, 0, 0, 0, 9,
-  0, 0, 0, 9, 0, 20, 0, 0, 47, 83,
-  0, 52, 17, 21, 41, 51, 25, 0, 40, 5,
-  0, 40, 0, 11, 0, 0, 21, 0, 13, 13,
-  31, 0, 15, 0, 35, 1, 15, 0, 0, 27,
-  36, 37, 0, 42, 17, 9, 15, 0, 0, 22,
-  97, 0, 7, 27, 55, 8, 0, 0, 0, 69,
-  0, 8, 46, 0, 0, 20, 0, 2, 0, 37,
-  78, 0, 3, 0, 0, 24, 0, 73, 0, 34,
-  30, 29, 29, 57, 25, 42, 0, 28, 0, 43,
-  34, 9, 17, 0, 10, 0, 0, 0, 6, 14,
-  0, 16, 0, 0, 0, 0, 28, 0, 23, 6,
-  0, 10, 7, 0, 0, 23, 0, 35, 38, 0,
-  52, 56, 0, 0, 11, 0, 0, 18, 0, 0,
-  0, 4, 0, 16, 29, 0, 0, 66, 6, 0,
-  0, 10, 18, 0, 38, 0, 0, 6, 0, 7,
-  0, 1, 0, 0, 17, 0, 0, 0, 5, 0,
-  43, 0, 63, 0, 11, 0, 56, 59, 50, 27,
-  4, 0, 2, 0, 0, 0, 8, 0, 48, 60,
-  4, 28, 76, 49, 0, 0, 0, 6, 1, 61,
-  24, 0, 35, 40, 0, 0, 13, 0, 67, 0,
-  0, 0, 0, 0, 0, 1, 0, 66, 2, 0,
-  30, 28, 26, 42, 0, 12, 0, 69, 96, 0,
-  23, 0, 0, 0, 0, 0, 51, 0, 0, 65,
-  0, 8, 82, 0, 40, 45, 0, 20, 0, 33,
-  32, 0, 14, 3, 0, 16, 42, 0, 37, 0,
-  0, 30, 0, 27, 36, 9, 13, 0, 0, 22,
-  2, 0, 70, 5, 0, 64, 0, 23, 40, 0,
-  76, 0, 6, 0, 58, 8, 17, 40, 5, 0,
-  26, 0, 1, 0, 0, 0, 39, 0, 71, 0,
-  10, 9, 14, 0, 2, 55, 59, 38, 4, 35,
-  16, 13, 17, 0, 0, 16, 84, 0, 0, 22,
-  51, 18, 0, 0, 0, 56, 0, 33, 67, 0,
-  5, 30, 0, 0, 0, 43, 70, 0, 18, 0,
-  0, 0, 0, 41, 0, 35, 57, 2, 29, 80,
-  44, 19, 0, 21, 0, 34, 36, 10, 35, 0,
-  10, 0, 0, 0, 30, 26, 0, 32, 0, 0,
-  35, 1, 27, 0, 0, 17, 9, 19, 26, 0,
-  10, 16, 0, 22, 23, 0, 61, 69, 0, 5,
-  0, 0, 0, 42, 5, 0, 0, 31, 0, 24,
-  35, 0, 0, 65, 2, 0, 10, 12, 63, 0,
-  37, 0, 27, 0, 0, 14, 0, 0, 0, 0,
-  0, 0, 0, 0, 4, 0, 41, 0, 35, 0,
-  8, 0, 0, 0, 0, 18, 14, 124, 8, 0,
-  7, 0, 0, 29, 52, 11, 0, 6, 15, 0,
-  0, 0, 0, 77, 2, 24, 40, 0, 0, 9,
-  0, 14, 0, 31, 15, 32, 0, 0, 0, 21,
-  0, 76, 0, 37, 0, 65, 12, 85, 61, 31,
-  0, 0, 0, 31, 31, 4, 2, 0, 40, 0,
-  18, 0, 23, 69, 0, 16, 12, 9, 0, 29,
-  58, 0, 39, 20, 11, 0, 25, 21, 19, 0,
-  0, 29, 42, 0, 16, 44, 15, 0, 11, 0,
-  0, 8, 0, 6, 0, 0, 4, 72, 0, 0,
-  0, 72, 0, 0, 4, 12, 57, 0, 27, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 77, 0,
-  47, 0, 6, 3, 0, 0, 55, 0, 22, 0,
-  43, 69, 0, 8, 5, 11, 0, 0, 0, 0,
-  0, 0, 16, 73, 0, 0, 82, 18, 0, 0,
-  0, 41, 0, 50, 15, 0, 5, 16, 0, 0,
-  0, 19, 83, 23, 0, 0, 0, 9, 0, 0,
-  0, 6, 0, 0, 9, 74, 35, 102, 0, 0,
-  0, 29, 56, 0, 22, 0, 18, 0, 0, 0,
-  78, 24, 0, 51, 0, 0, 97, 0, 107, 49,
-  0, 0, 4, 13, 45, 0, 27, 0, 0, 5,
-  25, 0, 35, 12, 0, 12, 0, 6, 0, 6,
-  0, 26, 0, 19, 1, 0, 34, 0, 12, 95,
-  20, 81, 35, 21, 44, 44, 10, 0, 51, 0,
-  0, 63, 0, 7, 0, 0, 0, 0, 11, 0,
-  22, 0, 33, 0, 0, 27, 27, 0, 0, 39,
-  39, 29, 0, 48, 7, 15, 23, 0, 0, 11,
-  81, 0, 0, 23, 58, 7, 0, 0, 0, 63,
-  0, 21, 41, 0, 0, 12, 0, 0, 0, 32,
-  67, 3, 1, 0, 0, 13, 0, 47, 0, 18,
-  41, 13, 22, 69, 25, 53, 0, 12, 0, 37,
-  21, 7, 22, 0, 22, 0, 0, 0, 16, 31,
-  0, 29, 0, 0, 7, 0, 37, 0, 18, 0,
-  9, 21, 4, 0, 5, 11, 0, 39, 27, 0,
-  62, 62, 0, 0, 0, 0, 0, 18, 1, 0,
-  0, 19, 0, 19, 32, 0, 0, 78, 11, 0,
-  0, 10, 15, 0, 33, 0, 0, 0, 0, 8,
-  0, 0, 0, 0, 7, 0, 0, 0, 0, 0,
-  38, 0, 39, 0, 9, 0, 0, 0, 0, 12,
-  0, 128, 4, 0, 24, 0, 0, 24, 44, 0,
-  0, 3, 15, 0, 0, 0, 17, 87, 14, 19,
-  11, 0, 0, 0, 0, 0, 0, 22, 19, 26,
-  0, 6, 0, 37, 0, 56, 0, 21, 0, 56,
-  0, 77, 54, 47, 0, 0, 0, 41, 15, 0,
-  2, 0, 67, 0, 29, 0, 3, 66, 0, 12,
-  54, 5, 0, 16, 73, 0, 77, 17, 14, 1,
-  0, 19, 20, 20, 0, 39, 27, 0, 45, 41,
-  10, 0, 5, 0, 0, 0, 0, 17, 0, 0,
-  0, 33, 0, 0, 7, 75, 14, 0, 0, 3,
-  5, 0, 19, 0, 0, 0, 0, 0, 0, 14,
-  0, 0, 93, 0, 37, 0, 0, 0, 0, 0,
-  36, 0, 0, 0, 0, 67, 0, 11, 0, 33,
-  2, 0, 0, 0, 0, 17, 28, 49, 0, 0,
-  52, 3, 0, 0, 28, 58, 0, 42, 19, 0,
-  0, 8, 0, 9, 0, 26, 82, 21, 0, 0,
-  0, 27, 0, 8, 0, 40, 0, 22, 24, 91,
-  9, 110, 0, 0, 0, 27, 50, 0, 37, 0,
-  28, 0, 14, 0, 55, 50, 0, 43, 0, 0,
-  49, 11, 81, 0, 4, 0, 22, 7, 42, 0,
-  12, 0, 0, 26, 21, 0, 21, 24, 0, 0,
-  0, 0, 0, 9, 0, 0, 0, 9, 0, 20,
-  0, 0, 47, 83, 0, 52, 17, 21, 41, 51,
-  25, 0, 40, 5, 0, 40, 0, 11, 0, 0,
-  21, 0, 13, 13, 31, 0, 15, 0, 35, 1,
-  15, 0, 0, 27, 36, 37, 0, 42, 17, 9,
-  15, 0, 0, 22, 97, 0, 7, 27, 55, 8,
-  0, 0, 0, 69, 0, 8, 46, 0, 0, 20,
-  0, 2, 0, 37, 78, 0, 3, 0, 0, 24,
-  0, 73, 0, 34, 30, 29, 29, 57, 25, 42,
-  0, 28, 0, 43, 34, 9, 17, 0, 10, 0,
-  0, 0, 6, 14, 0, 16, 0, 0, 0, 0,
-  28, 0, 23, 6, 0, 10, 7, 0, 0, 23,
-  0, 35, 38, 0, 52, 56, 0, 0, 11, 0,
-  0, 18, 0, 0, 0, 4, 0, 16, 29, 0,
-  0, 66, 6, 0, 0, 10, 18, 0, 38, 0,
-  0, 6, 0, 7, 0, 1, 0, 0, 17, 0,
-  0, 0, 5, 0, 43, 0, 63, 0, 11, 0,
-  0, 0, 0, 15, 0, 142, 5, 0, 3, 0,
-  0, 27, 43, 0, 0, 0, 6, 0, 0, 0,
-  37, 88, 23, 15, 8, 0, 0, 0, 0, 13,
-  0, 22, 26, 24, 0, 2, 0, 36, 0, 50,
-  0, 35, 0, 56, 1, 71, 43, 43, 0, 0,
-  0, 38, 8, 0, 4, 0, 67, 0, 33, 0,
-  0, 57, 0, 0, 64, 0, 0, 26, 62, 0,
-  74, 26, 27, 3, 4, 32, 9, 25, 0, 31,
-  35, 0, 37, 52, 8, 0, 19, 0, 0, 0,
-  0, 11, 7, 0, 1, 26, 0, 0, 10, 66,
-  18, 0, 0, 7, 8, 0, 31, 0, 0, 0,
-  0, 0, 0, 15, 0, 0, 111, 2, 35, 3,
-  0, 0, 0, 0, 41, 0, 0, 0, 2, 55,
-  59, 38, 4, 35, 16, 13, 17, 0, 0, 16,
-  84, 0, 0, 22, 51, 18, 0, 0, 0, 56,
-  0, 33, 67, 0, 5, 30, 0, 0, 0, 43,
-  70, 0, 18, 0, 0, 0, 0, 41, 0, 35,
-  57, 2, 29, 80, 44, 19, 0, 21, 0, 34,
-  36, 10, 35, 0, 10, 0, 0, 0, 30, 26,
-  0, 32, 0, 0, 35, 1, 27, 0, 0, 17,
-  9, 19, 26, 0, 10, 16, 0, 22, 23, 0,
-  61, 69, 0, 5, 0, 0, 0, 42, 5, 0,
-  0, 31, 0, 24, 35, 0, 0, 65, 2, 0,
-  10, 12, 63, 0, 37, 0, 27, 0, 0, 14,
-  0, 0, 0, 0, 0, 0, 0, 0, 4, 0,
-  41, 0, 35, 0, 8, 0, 0, 0, 0, 18,
-  14, 124, 8, 0, 7, 0, 0, 29, 52, 11,
-  0, 6, 15, 0, 0, 0, 0, 77, 2, 24,
-  40, 0, 0, 9, 0, 14, 0, 31, 15, 32,
-  0, 0, 0, 21, 0, 76, 0, 37, 0, 65,
-  12, 85, 61, 31, 0, 0, 0, 31, 31, 4,
-  2, 0, 40, 0, 18, 0, 23, 69, 0, 16,
-  12, 9, 0, 29, 58, 0, 39, 20, 11, 0,
-  25, 21, 19, 0, 0, 29, 42, 0, 16, 44,
-  15, 0, 11, 0, 0, 8, 0, 6, 0, 0,
-  4, 72, 0, 0, 0, 72, 0, 0, 4, 12,
-  57, 0, 27, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 77, 0, 47, 0, 6, 3, 0, 0,
-  55, 0, 22, 0, 0, 12, 0, 0, 34, 31,
-  37, 0, 16, 0, 1, 11, 52, 11, 10, 28,
-  23, 12, 0, 12, 51, 0, 0, 50, 24, 48,
-  0, 15, 0, 35, 0, 0, 38, 48, 0, 0,
-  0, 6, 0, 75, 0, 43, 0, 59, 29, 41,
-  15, 15, 0, 19, 0, 15, 107, 18, 0, 0,
-  17, 0, 0, 28, 25, 21, 0, 41, 0, 0,
-  45, 6, 26, 0, 0, 8, 0, 14, 33, 51,
-  4, 0, 0, 28, 84, 14, 0, 6, 19, 0,
-  12, 21, 18, 26, 0, 9, 9, 21, 0, 72,
-  0, 4, 31, 72, 0, 0, 2, 0, 39, 0,
-  26, 7, 9, 48, 0, 0, 0, 3, 0, 0,
-  39, 24, 41, 0, 37, 0, 84, 0, 64, 0,
-  13, 0, 0, 39, 39, 29, 0, 48, 7, 15,
-  23, 0, 0, 11, 81, 0, 0, 23, 58, 7,
-  0, 0, 0, 63, 0, 21, 41, 0, 0, 12,
-  0, 0, 0, 32, 67, 3, 1, 0, 0, 13,
-  0, 47, 0, 18, 41, 13, 22, 69, 25, 53,
-  0, 12, 0, 37, 21, 7, 22, 0, 22, 0,
-  0, 0, 16, 31, 0, 29, 0, 0, 7, 0,
-  37, 0, 18, 0, 9, 21, 4, 0, 5, 11,
-  0, 39, 27, 0, 62, 62, 0, 0, 0, 0,
-  0, 18, 1, 0, 0, 19, 0, 19, 32, 0,
-  0, 78, 11, 0, 0, 10, 15, 0, 33, 0,
-  0, 0, 0, 8, 0, 0, 0, 0, 7, 0,
-  0, 0, 0, 0, 38, 0, 39, 0, 9, 0,
-  0, 0, 0, 12, 0, 128, 4, 0, 24, 0,
-  0, 24, 44, 0, 0, 3, 15, 0, 0, 0,
-  17, 87, 14, 19, 11, 0, 0, 0, 0, 0,
-  0, 22, 19, 26, 0, 6, 0, 37, 0, 56,
-  0, 21, 0, 56, 0, 77, 54, 47, 0, 0,
-  0, 41, 15, 0, 2, 0, 67, 0, 29, 0,
-  3, 66, 0, 12, 54, 5, 0, 16, 73, 0,
-  77, 17, 14, 1, 0, 19, 20, 20, 0, 39,
-  27, 0, 45, 41, 10, 0, 5, 0, 0, 0,
-  0, 17, 0, 0, 0, 33, 0, 0, 7, 75,
-  14, 0, 0, 3, 5, 0, 19, 0, 0, 0,
-  0, 0, 0, 14, 0, 0, 93, 0, 37, 0,
-  0, 0, 0, 0, 36, 0, 0, 0, 0, 0,
-  0, 0, 0, 48, 47, 0, 22, 0, 0, 0,
-  38, 0, 10, 49, 31, 17, 0, 15, 62, 0,
-  0, 40, 0, 20, 12, 0, 0, 26, 0, 0,
-  64, 55, 8, 0, 0, 16, 0, 41, 0, 28,
-  0, 56, 0, 45, 21, 45, 0, 12, 2, 10,
-  93, 9, 0, 9, 48, 0, 0, 35, 16, 4,
-  0, 1, 0, 0, 17, 7, 42, 0, 2, 3,
-  0, 21, 13, 42, 3, 0, 0, 26, 69, 0,
-  18, 2, 18, 0, 12, 0, 9, 8, 0, 31,
-  0, 8, 5, 29, 0, 0, 36, 54, 18, 0,
-  0, 0, 1, 0, 24, 4, 0, 31, 0, 1,
-  0, 19, 0, 0, 51, 3, 32, 0, 21, 0,
-  83, 0, 35, 0, 4, 0, 0, 27, 36, 37,
-  0, 42, 17, 9, 15, 0, 0, 22, 97, 0,
-  7, 27, 55, 8, 0, 0, 0, 69, 0, 8,
-  46, 0, 0, 20, 0, 2, 0, 37, 78, 0,
-  3, 0, 0, 24, 0, 73, 0, 34, 30, 29,
-  29, 57, 25, 42, 0, 28, 0, 43, 34, 9,
-  17, 0, 10, 0, 0, 0, 6, 14, 0, 16,
-  0, 0, 0, 0, 28, 0, 23, 6, 0, 10,
-  7, 0, 0, 23, 0, 35, 38, 0, 52, 56,
-  0, 0, 11, 0, 0, 18, 0, 0, 0, 4,
-  0, 16, 29, 0, 0, 66, 6, 0, 0, 10,
-  18, 0, 38, 0, 0, 6, 0, 7, 0, 1,
-  0, 0, 17, 0, 0, 0, 5, 0, 43, 0,
-  63, 0, 11, 0, 0, 0, 0, 15, 0, 142,
-  5, 0, 3, 0, 0, 27, 43, 0, 0, 0,
-  6, 0, 0, 0, 37, 88, 23, 15, 8, 0,
-  0, 0, 0, 13, 0, 22, 26, 24, 0, 2,
-  0, 36, 0, 50, 0, 35, 0, 56, 1, 71,
-  43, 43, 0, 0, 0, 38, 8, 0, 4, 0,
-  67, 0, 33, 0, 0, 57, 0, 0, 64, 0,
-  0, 26, 62, 0, 74, 26, 27, 3, 4, 32,
-  9, 25, 0, 31, 35, 0, 37, 52, 8, 0,
-  19, 0, 0, 0, 0, 11, 7, 0, 1, 26,
-  0, 0, 10, 66, 18, 0, 0, 7, 8, 0,
-  31, 0, 0, 0, 0, 0, 0, 15, 0, 0,
-  111, 2, 35, 3, 0, 0, 0, 0, 41, 0,
-  0, 0, 0, 0, 0, 0, 0, 51, 48, 0,
-  17, 0, 0, 1, 56, 0, 12, 28, 33, 20,
-  5, 18, 77, 0, 0, 29, 0, 42, 17, 0,
-  0, 38, 0, 0, 71, 57, 0, 0, 0, 12,
-  0, 39, 0, 43, 0, 51, 0, 34, 20, 45,
-  0, 31, 15, 0, 71, 13, 0, 6, 44, 0,
-  0, 54, 15, 0, 0, 0, 0, 0, 23, 28,
-  33, 0, 0, 13, 0, 22, 15, 54, 0, 0,
-  0, 29, 69, 6, 16, 0, 25, 0, 11, 13,
-  3, 2, 0, 26, 5, 14, 0, 26, 0, 0,
-  43, 47, 11, 6, 0, 0, 0, 0, 43, 0,
-  0, 46, 1, 0, 0, 11, 0, 0, 48, 15,
-  46, 0, 23, 0, 104, 0, 47, 0, 0, 0,
-  0, 0, 0, 18, 14, 124, 8, 0, 7, 0,
-  0, 29, 52, 11, 0, 6, 15, 0, 0, 0,
-  0, 77, 2, 24, 40, 0, 0, 9, 0, 14,
-  0, 31, 15, 32, 0, 0, 0, 21, 0, 76,
-  0, 37, 0, 65, 12, 85, 61, 31, 0, 0,
-  0, 31, 31, 4, 2, 0, 40, 0, 18, 0,
-  23, 69, 0, 16, 12, 9, 0, 29, 58, 0,
-  39, 20, 11, 0, 25, 21, 19, 0, 0, 29,
-  42, 0, 16, 44, 15, 0, 11, 0, 0, 8,
-  0, 6, 0, 0, 4, 72, 0, 0, 0, 72,
-  0, 0, 4, 12, 57, 0, 27, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 77, 0, 47, 0,
-  6, 3, 0, 0, 55, 0, 22, 0, 0, 12,
-  0, 0, 34, 31, 37, 0, 16, 0, 1, 11,
-  52, 11, 10, 28, 23, 12, 0, 12, 51, 0,
-  0, 50, 24, 48, 0, 15, 0, 35, 0, 0,
-  38, 48, 0, 0, 0, 6, 0, 75, 0, 43,
-  0, 59, 29, 41, 15, 15, 0, 19, 0, 15,
-  107, 18, 0, 0, 17, 0, 0, 28, 25, 21,
-  0, 41, 0, 0, 45, 6, 26, 0, 0, 8,
-  0, 14, 33, 51, 4, 0, 0, 28, 84, 14,
-  0, 6, 19, 0, 12, 21, 18, 26, 0, 9,
-  9, 21, 0, 72, 0, 4, 31, 72, 0, 0,
-  2, 0, 39, 0, 26, 7, 9, 48, 0, 0,
-  0, 3, 0, 0, 39, 24, 41, 0, 37, 0,
-  84, 0, 64, 0, 13, 0, 0, 32, 0, 0,
-  20, 0, 56, 0, 35, 0, 0, 29, 28, 20,
-  52, 24, 39, 50, 3, 36, 95, 0, 10, 21,
-  21, 25, 9, 34, 0, 29, 0, 0, 63, 0,
-  10, 0, 0, 0, 0, 48, 0, 3, 0, 63,
-  16, 61, 5, 1, 0, 6, 0, 3, 79, 33,
-  0, 0, 18, 0, 0, 7, 0, 7, 0, 0,
-  0, 0, 32, 20, 20, 0, 0, 0, 0, 0,
-  62, 0, 13, 2, 0, 6, 67, 26, 0, 0,
-  6, 0, 7, 0, 11, 49, 18, 0, 0, 4,
-  0, 55, 0, 6, 64, 36, 0, 0, 3, 0,
-  34, 0, 22, 9, 31, 35, 0, 0, 0, 0,
-  0, 0, 14, 2, 12, 0, 45, 0, 77, 0,
-  41, 0, 26, 0, 0, 0, 0, 12, 0, 128,
-  4, 0, 24, 0, 0, 24, 44, 0, 0, 3,
-  15, 0, 0, 0, 17, 87, 14, 19, 11, 0,
-  0, 0, 0, 0, 0, 22, 19, 26, 0, 6,
-  0, 37, 0, 56, 0, 21, 0, 56, 0, 77,
-  54, 47, 0, 0, 0, 41, 15, 0, 2, 0,
-  67, 0, 29, 0, 3, 66, 0, 12, 54, 5,
-  0, 16, 73, 0, 77, 17, 14, 1, 0, 19,
-  20, 20, 0, 39, 27, 0, 45, 41, 10, 0,
-  5, 0, 0, 0, 0, 17, 0, 0, 0, 33,
-  0, 0, 7, 75, 14, 0, 0, 3, 5, 0,
-  19, 0, 0, 0, 0, 0, 0, 14, 0, 0,
-  93, 0, 37, 0, 0, 0, 0, 0, 36, 0,
-  0, 0, 0, 0, 0, 0, 0, 48, 47, 0,
-  22, 0, 0, 0, 38, 0, 10, 49, 31, 17,
-  0, 15, 62, 0, 0, 40, 0, 20, 12, 0,
-  0, 26, 0, 0, 64, 55, 8, 0, 0, 16,
-  0, 41, 0, 28, 0, 56, 0, 45, 21, 45,
-  0, 12, 2, 10, 93, 9, 0, 9, 48, 0,
-  0, 35, 16, 4, 0, 1, 0, 0, 17, 7,
-  42, 0, 2, 3, 0, 21, 13, 42, 3, 0,
-  0, 26, 69, 0, 18, 2, 18, 0, 12, 0,
-  9, 8, 0, 31, 0, 8, 5, 29, 0, 0,
-  36, 54, 18, 0, 0, 0, 1, 0, 24, 4,
-  0, 31, 0, 1, 0, 19, 0, 0, 51, 3,
-  32, 0, 21, 0, 83, 0, 35, 0, 4, 0,
-  0, 9, 0, 0, 15, 0, 57, 0, 37, 0,
-  0, 0, 30, 12, 51, 40, 45, 47, 0, 28,
-  101, 0, 0, 27, 0, 9, 25, 8, 0, 23,
-  0, 0, 52, 4, 22, 0, 0, 12, 0, 35,
-  0, 7, 0, 70, 5, 54, 4, 16, 0, 0,
-  13, 8, 68, 27, 0, 0, 28, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 23, 1, 27, 0,
-  0, 0, 0, 10, 48, 0, 7, 9, 0, 11,
-  57, 13, 9, 0, 13, 0, 0, 0, 22, 29,
-  9, 0, 0, 15, 0, 34, 0, 0, 59, 37,
-  0, 0, 0, 0, 12, 0, 17, 14, 11, 27,
-  0, 0, 0, 5, 0, 0, 24, 0, 14, 0,
-  27, 0, 77, 0, 21, 0, 13, 0, 0, 0,
-  0, 15, 0, 142, 5, 0, 3, 0, 0, 27,
-  43, 0, 0, 0, 6, 0, 0, 0, 37, 88,
-  23, 15, 8, 0, 0, 0, 0, 13, 0, 22,
-  26, 24, 0, 2, 0, 36, 0, 50, 0, 35,
-  0, 56, 1, 71, 43, 43, 0, 0, 0, 38,
-  8, 0, 4, 0, 67, 0, 33, 0, 0, 57,
-  0, 0, 64, 0, 0, 26, 62, 0, 74, 26,
-  27, 3, 4, 32, 9, 25, 0, 31, 35, 0,
-  37, 52, 8, 0, 19, 0, 0, 0, 0, 11,
-  7, 0, 1, 26, 0, 0, 10, 66, 18, 0,
-  0, 7, 8, 0, 31, 0, 0, 0, 0, 0,
-  0, 15, 0, 0, 111, 2, 35, 3, 0, 0,
-  0, 0, 41, 0, 0, 0, 0, 0, 0, 0,
-  0, 51, 48, 0, 17, 0, 0, 1, 56, 0,
-  12, 28, 33, 20, 5, 18, 77, 0, 0, 29,
-  0, 42, 17, 0, 0, 38, 0, 0, 71, 57,
-  0, 0, 0, 12, 0, 39, 0, 43, 0, 51,
-  0, 34, 20, 45, 0, 31, 15, 0, 71, 13,
-  0, 6, 44, 0, 0, 54, 15, 0, 0, 0,
-  0, 0, 23, 28, 33, 0, 0, 13, 0, 22,
-  15, 54, 0, 0, 0, 29, 69, 6, 16, 0,
-  25, 0, 11, 13, 3, 2, 0, 26, 5, 14,
-  0, 26, 0, 0, 43, 47, 11, 6, 0, 0,
-  0, 0, 43, 0, 0, 46, 1, 0, 0, 11,
-  0, 0, 48, 15, 46, 0, 23, 0, 104, 0,
-  47, 0, 0, 0, 0, 29, 0, 0, 20, 0,
-  45, 0, 38, 0, 0, 2, 26, 28, 73, 29,
-  52, 53, 0, 24, 91, 0, 0, 24, 16, 39,
-  26, 0, 0, 20, 0, 0, 40, 12, 3, 0,
-  0, 8, 0, 47, 0, 9, 0, 58, 0, 33,
-  12, 19, 0, 0, 17, 3, 66, 44, 0, 0,
-  7, 0, 0, 3, 7, 0, 0, 0, 0, 0,
-  42, 7, 32, 0, 0, 0, 0, 10, 51, 0,
-  4, 0, 0, 8, 61, 18, 25, 0, 32, 0,
-  8, 4, 12, 12, 2, 0, 0, 26, 0, 31,
-  0, 0, 56, 29, 0, 2, 0, 0, 0, 0,
-  30, 0, 7, 37, 0, 0, 0, 21, 0, 0,
-  7, 6, 14, 0, 16, 0, 90, 0, 25, 0,
-  12, 0, 0, 12, 0, 0, 34, 31, 37, 0,
-  16, 0, 1, 11, 52, 11, 10, 28, 23, 12,
-  0, 12, 51, 0, 0, 50, 24, 48, 0, 15,
-  0, 35, 0, 0, 38, 48, 0, 0, 0, 6,
-  0, 75, 0, 43, 0, 59, 29, 41, 15, 15,
-  0, 19, 0, 15, 107, 18, 0, 0, 17, 0,
-  0, 28, 25, 21, 0, 41, 0, 0, 45, 6,
-  26, 0, 0, 8, 0, 14, 33, 51, 4, 0,
-  0, 28, 84, 14, 0, 6, 19, 0, 12, 21,
-  18, 26, 0, 9, 9, 21, 0, 72, 0, 4,
-  31, 72, 0, 0, 2, 0, 39, 0, 26, 7,
-  9, 48, 0, 0, 0, 3, 0, 0, 39, 24,
-  41, 0, 37, 0, 84, 0, 64, 0, 13, 0,
-  0, 32, 0, 0, 20, 0, 56, 0, 35, 0,
-  0, 29, 28, 20, 52, 24, 39, 50, 3, 36,
-  95, 0, 10, 21, 21, 25, 9, 34, 0, 29,
-  0, 0, 63, 0, 10, 0, 0, 0, 0, 48,
-  0, 3, 0, 63, 16, 61, 5, 1, 0, 6,
-  0, 3, 79, 33, 0, 0, 18, 0, 0, 7,
-  0, 7, 0, 0, 0, 0, 32, 20, 20, 0,
-  0, 0, 0, 0, 62, 0, 13, 2, 0, 6,
-  67, 26, 0, 0, 6, 0, 7, 0, 11, 49,
-  18, 0, 0, 4, 0, 55, 0, 6, 64, 36,
-  0, 0, 3, 0, 34, 0, 22, 9, 31, 35,
-  0, 0, 0, 0, 0, 0, 14, 2, 12, 0,
-  45, 0, 77, 0, 41, 0, 26, 0, 0, 27,
-  0, 15, 17, 0, 54, 0, 26, 19, 0, 24,
-  19, 41, 54, 36, 42, 53, 0, 29, 105, 0,
-  0, 24, 36, 35, 13, 47, 0, 36, 0, 0,
-  67, 9, 22, 0, 0, 0, 0, 30, 0, 0,
-  0, 58, 16, 44, 12, 18, 0, 3, 21, 11,
-  61, 51, 0, 0, 3, 0, 0, 16, 0, 0,
-  0, 0, 0, 0, 38, 18, 25, 0, 0, 0,
-  0, 0, 56, 0, 14, 7, 0, 10, 79, 42,
-  2, 0, 11, 0, 6, 6, 16, 33, 14, 0,
-  0, 12, 0, 42, 0, 6, 83, 38, 0, 0,
-  5, 0, 37, 0, 29, 9, 43, 27, 0, 0,
-  1, 0, 0, 0, 12, 0, 2, 0, 32, 0,
-  100, 0, 40, 0, 22, 0, 0, 0, 0, 0,
-  0, 48, 47, 0, 22, 0, 0, 0, 38, 0,
-  10, 49, 31, 17, 0, 15, 62, 0, 0, 40,
-  0, 20, 12, 0, 0, 26, 0, 0, 64, 55,
-  8, 0, 0, 16, 0, 41, 0, 28, 0, 56,
-  0, 45, 21, 45, 0, 12, 2, 10, 93, 9,
-  0, 9, 48, 0, 0, 35, 16, 4, 0, 1,
-  0, 0, 17, 7, 42, 0, 2, 3, 0, 21,
-  13, 42, 3, 0, 0, 26, 69, 0, 18, 2,
-  18, 0, 12, 0, 9, 8, 0, 31, 0, 8,
-  5, 29, 0, 0, 36, 54, 18, 0, 0, 0,
-  1, 0, 24, 4, 0, 31, 0, 1, 0, 19,
-  0, 0, 51, 3, 32, 0, 21, 0, 83, 0,
-  35, 0, 4, 0, 0, 9, 0, 0, 15, 0,
-  57, 0, 37, 0, 0, 0, 30, 12, 51, 40,
-  45, 47, 0, 28, 101, 0, 0, 27, 0, 9,
-  25, 8, 0, 23, 0, 0, 52, 4, 22, 0,
-  0, 12, 0, 35, 0, 7, 0, 70, 5, 54,
-  4, 16, 0, 0, 13, 8, 68, 27, 0, 0,
-  28, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  23, 1, 27, 0, 0, 0, 0, 10, 48, 0,
-  7, 9, 0, 11, 57, 13, 9, 0, 13, 0,
-  0, 0, 22, 29, 9, 0, 0, 15, 0, 34,
-  0, 0, 59, 37, 0, 0, 0, 0, 12, 0,
-  17, 14, 11, 27, 0, 0, 0, 5, 0, 0,
-  24, 0, 14, 0, 27, 0, 77, 0, 21, 0,
-  13, 0, 0, 33, 0, 0, 27, 0, 41, 0,
-  45, 22, 0, 7, 22, 44, 69, 48, 60, 49,
-  0, 17, 100, 0, 0, 26, 19, 29, 19, 25,
-  0, 21, 0, 0, 29, 10, 19, 0, 0, 21,
-  0, 35, 0, 0, 0, 56, 7, 31, 16, 4,
-  0, 0, 48, 0, 33, 46, 0, 2, 16, 0,
-  0, 12, 0, 0, 0, 0, 0, 0, 48, 0,
-  33, 0, 0, 0, 0, 6, 51, 0, 15, 23,
-  0, 30, 42, 35, 0, 0, 24, 0, 0, 0,
-  26, 42, 0, 0, 0, 46, 0, 27, 0, 13,
-  75, 38, 0, 0, 0, 0, 17, 0, 16, 5,
-  28, 44, 0, 0, 0, 5, 8, 0, 2, 0,
-  24, 0, 4, 0, 105, 0, 27, 6, 32, 0,
-  0, 0, 0, 0, 0, 51, 48, 0, 17, 0,
-  0, 1, 56, 0, 12, 28, 33, 20, 5, 18,
-  77, 0, 0, 29, 0, 42, 17, 0, 0, 38,
-  0, 0, 71, 57, 0, 0, 0, 12, 0, 39,
-  0, 43, 0, 51, 0, 34, 20, 45, 0, 31,
-  15, 0, 71, 13, 0, 6, 44, 0, 0, 54,
-  15, 0, 0, 0, 0, 0, 23, 28, 33, 0,
-  0, 13, 0, 22, 15, 54, 0, 0, 0, 29,
-  69, 6, 16, 0, 25, 0, 11, 13, 3, 2,
-  0, 26, 5, 14, 0, 26, 0, 0, 43, 47,
-  11, 6, 0, 0, 0, 0, 43, 0, 0, 46,
-  1, 0, 0, 11, 0, 0, 48, 15, 46, 0,
-  23, 0, 104, 0, 47, 0, 0, 0, 0, 29,
-  0, 0, 20, 0, 45, 0, 38, 0, 0, 2,
-  26, 28, 73, 29, 52, 53, 0, 24, 91, 0,
-  0, 24, 16, 39, 26, 0, 0, 20, 0, 0,
-  40, 12, 3, 0, 0, 8, 0, 47, 0, 9,
-  0, 58, 0, 33, 12, 19, 0, 0, 17, 3,
-  66, 44, 0, 0, 7, 0, 0, 3, 7, 0,
-  0, 0, 0, 0, 42, 7, 32, 0, 0, 0,
-  0, 10, 51, 0, 4, 0, 0, 8, 61, 18,
-  25, 0, 32, 0, 8, 4, 12, 12, 2, 0,
-  0, 26, 0, 31, 0, 0, 56, 29, 0, 2,
-  0, 0, 0, 0, 30, 0, 7, 37, 0, 0,
-  0, 21, 0, 0, 7, 6, 14, 0, 16, 0,
-  90, 0, 25, 0, 12, 0, 0, 65, 0, 0,
-  34, 0, 36, 0, 61, 12, 0, 5, 44, 54,
-  61, 74, 64, 45, 0, 12, 72, 0, 0, 33,
-  31, 57, 17, 27, 0, 12, 0, 0, 29, 8,
-  17, 0, 0, 37, 0, 58, 0, 3, 0, 54,
-  0, 29, 24, 4, 0, 0, 35, 0, 43, 56,
-  0, 0, 7, 0, 0, 32, 0, 0, 0, 0,
-  0, 0, 70, 9, 41, 0, 0, 0, 0, 18,
-  51, 0, 0, 21, 0, 27, 40, 52, 13, 20,
-  40, 15, 0, 9, 25, 57, 3, 0, 0, 59,
-  0, 27, 0, 5, 69, 44, 0, 0, 0, 0,
-  2, 0, 12, 20, 36, 60, 0, 0, 0, 21,
-  0, 0, 0, 18, 24, 0, 0, 1, 134, 0,
-  38, 0, 44, 0, 0, 32, 0, 0, 20, 0,
-  56, 0, 35, 0, 0, 29, 28, 20, 52, 24,
-  39, 50, 3, 36, 95, 0, 10, 21, 21, 25,
-  9, 34, 0, 29, 0, 0, 63, 0, 10, 0,
-  0, 0, 0, 48, 0, 3, 0, 63, 16, 61,
-  5, 1, 0, 6, 0, 3, 79, 33, 0, 0,
-  18, 0, 0, 7, 0, 7, 0, 0, 0, 0,
-  32, 20, 20, 0, 0, 0, 0, 0, 62, 0,
-  13, 2, 0, 6, 67, 26, 0, 0, 6, 0,
-  7, 0, 11, 49, 18, 0, 0, 4, 0, 55,
-  0, 6, 64, 36, 0, 0, 3, 0, 34, 0,
-  22, 9, 31, 35, 0, 0, 0, 0, 0, 0,
-  14, 2, 12, 0, 45, 0, 77, 0, 41, 0,
-  26, 0, 0, 27, 0, 15, 17, 0, 54, 0,
-  26, 19, 0, 24, 19, 41, 54, 36, 42, 53,
-  0, 29, 105, 0, 0, 24, 36, 35, 13, 47,
-  0, 36, 0, 0, 67, 9, 22, 0, 0, 0,
-  0, 30, 0, 0, 0, 58, 16, 44, 12, 18,
-  0, 3, 21, 11, 61, 51, 0, 0, 3, 0,
-  0, 16, 0, 0, 0, 0, 0, 0, 38, 18,
-  25, 0, 0, 0, 0, 0, 56, 0, 14, 7,
-  0, 10, 79, 42, 2, 0, 11, 0, 6, 6,
-  16, 33, 14, 0, 0, 12, 0, 42, 0, 6,
-  83, 38, 0, 0, 5, 0, 37, 0, 29, 9,
-  43, 27, 0, 0, 1, 0, 0, 0, 12, 0,
-  2, 0, 32, 0, 100, 0, 40, 0, 22, 0,
-  0, 22, 0, 0, 8, 0, 32, 0, 33, 28,
-  0, 1, 0, 29, 40, 48, 56, 56, 12, 13,
-  56, 0, 0, 29, 28, 42, 16, 56, 0, 19,
-  0, 0, 57, 2, 6, 0, 0, 0, 0, 24,
-  0, 0, 0, 16, 1, 14, 21, 10, 0, 5,
-  37, 5, 41, 38, 0, 11, 0, 24, 0, 42,
-  0, 0, 0, 0, 0, 0, 70, 24, 23, 0,
-  0, 0, 11, 21, 44, 0, 8, 0, 0, 12,
-  70, 39, 7, 8, 19, 29, 0, 28, 16, 3,
-  38, 30, 0, 36, 4, 7, 0, 4, 60, 56,
-  0, 0, 5, 0, 33, 0, 12, 9, 35, 35,
-  0, 12, 2, 0, 10, 0, 0, 0, 0, 0,
-  6, 0, 111, 0, 30, 0, 9, 0, 0, 9,
-  0, 0, 15, 0, 57, 0, 37, 0, 0, 0,
-  30, 12, 51, 40, 45, 47, 0, 28, 101, 0,
-  0, 27, 0, 9, 25, 8, 0, 23, 0, 0,
-  52, 4, 22, 0, 0, 12, 0, 35, 0, 7,
-  0, 70, 5, 54, 4, 16, 0, 0, 13, 8,
-  68, 27, 0, 0, 28, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 23, 1, 27, 0, 0, 0,
-  0, 10, 48, 0, 7, 9, 0, 11, 57, 13,
-  9, 0, 13, 0, 0, 0, 22, 29, 9, 0,
-  0, 15, 0, 34, 0, 0, 59, 37, 0, 0,
-  0, 0, 12, 0, 17, 14, 11, 27, 0, 0,
-  0, 5, 0, 0, 24, 0, 14, 0, 27, 0,
-  77, 0, 21, 0, 13, 0, 0, 33, 0, 0,
-  27, 0, 41, 0, 45, 22, 0, 7, 22, 44,
-  69, 48, 60, 49, 0, 17, 100, 0, 0, 26,
-  19, 29, 19, 25, 0, 21, 0, 0, 29, 10,
-  19, 0, 0, 21, 0, 35, 0, 0, 0, 56,
-  7, 31, 16, 4, 0, 0, 48, 0, 33, 46,
-  0, 2, 16, 0, 0, 12, 0, 0, 0, 0,
-  0, 0, 48, 0, 33, 0, 0, 0, 0, 6,
-  51, 0, 15, 23, 0, 30, 42, 35, 0, 0,
-  24, 0, 0, 0, 26, 42, 0, 0, 0, 46,
-  0, 27, 0, 13, 75, 38, 0, 0, 0, 0,
-  17, 0, 16, 5, 28, 44, 0, 0, 0, 5,
-  8, 0, 2, 0, 24, 0, 4, 0, 105, 0,
-  27, 6, 32, 0, 0, 33, 0, 0, 36, 0,
-  0, 3, 48, 28, 0, 0, 10, 59, 39, 46,
-  67, 44, 12, 0, 51, 0, 0, 36, 0, 22,
-  41, 60, 0, 0, 0, 0, 19, 0, 7, 0,
-  0, 22, 0, 24, 0, 0, 0, 4, 0, 17,
-  23, 0, 0, 0, 55, 0, 1, 17, 0, 0,
-  18, 15, 0, 17, 0, 0, 0, 0, 0, 0,
-  102, 0, 17, 0, 0, 0, 5, 41, 35, 0,
-  3, 53, 0, 13, 18, 38, 12, 42, 10, 28,
-  0, 30, 22, 26, 21, 17, 0, 42, 0, 0,
-  0, 2, 49, 55, 1, 0, 0, 0, 16, 0,
-  14, 19, 32, 69, 0, 3, 0, 0, 21, 0,
-  0, 0, 17, 0, 0, 13, 100, 0, 0, 0,
-  30, 37, 0, 29, 0, 0, 20, 0, 45, 0,
-  38, 0, 0, 2, 26, 28, 73, 29, 52, 53,
-  0, 24, 91, 0, 0, 24, 16, 39, 26, 0,
-  0, 20, 0, 0, 40, 12, 3, 0, 0, 8,
-  0, 47, 0, 9, 0, 58, 0, 33, 12, 19,
-  0, 0, 17, 3, 66, 44, 0, 0, 7, 0,
-  0, 3, 7, 0, 0, 0, 0, 0, 42, 7,
-  32, 0, 0, 0, 0, 10, 51, 0, 4, 0,
-  0, 8, 61, 18, 25, 0, 32, 0, 8, 4,
-  12, 12, 2, 0, 0, 26, 0, 31, 0, 0,
-  56, 29, 0, 2, 0, 0, 0, 0, 30, 0,
-  7, 37, 0, 0, 0, 21, 0, 0, 7, 6,
-  14, 0, 16, 0, 90, 0, 25, 0, 12, 0,
-  0, 65, 0, 0, 34, 0, 36, 0, 61, 12,
-  0, 5, 44, 54, 61, 74, 64, 45, 0, 12,
-  72, 0, 0, 33, 31, 57, 17, 27, 0, 12,
-  0, 0, 29, 8, 17, 0, 0, 37, 0, 58,
-  0, 3, 0, 54, 0, 29, 24, 4, 0, 0,
-  35, 0, 43, 56, 0, 0, 7, 0, 0, 32,
-  0, 0, 0, 0, 0, 0, 70, 9, 41, 0,
-  0, 0, 0, 18, 51, 0, 0, 21, 0, 27,
-  40, 52, 13, 20, 40, 15, 0, 9, 25, 57,
-  3, 0, 0, 59, 0, 27, 0, 5, 69, 44,
-  0, 0, 0, 0, 2, 0, 12, 20, 36, 60,
-  0, 0, 0, 21, 0, 0, 0, 18, 24, 0,
-  0, 1, 134, 0, 38, 0, 44, 0, 0, 26,
-  42, 0, 40, 0, 0, 0, 68, 7, 0, 5,
-  43, 69, 21, 36, 59, 16, 3, 0, 30, 7,
-  16, 33, 0, 0, 32, 69, 0, 5, 0, 0,
-  0, 0, 0, 0, 0, 55, 0, 45, 0, 4,
-  0, 0, 0, 8, 12, 0, 0, 16, 23, 16,
-  0, 8, 0, 0, 24, 20, 0, 0, 0, 0,
-  0, 0, 0, 0, 70, 10, 16, 0, 0, 0,
-  0, 27, 24, 0, 0, 57, 0, 13, 0, 13,
-  15, 76, 12, 31, 0, 45, 9, 26, 24, 0,
-  0, 11, 0, 0, 0, 0, 52, 56, 16, 0,
-  0, 0, 1, 0, 7, 24, 39, 91, 4, 0,
-  0, 0, 0, 0, 11, 0, 10, 0, 0, 35,
-  51, 0, 0, 0, 24, 66, 0, 27, 0, 15,
-  17, 0, 54, 0, 26, 19, 0, 24, 19, 41,
-  54, 36, 42, 53, 0, 29, 105, 0, 0, 24,
-  36, 35, 13, 47, 0, 36, 0, 0, 67, 9,
-  22, 0, 0, 0, 0, 30, 0, 0, 0, 58,
-  16, 44, 12, 18, 0, 3, 21, 11, 61, 51,
-  0, 0, 3, 0, 0, 16, 0, 0, 0, 0,
-  0, 0, 38, 18, 25, 0, 0, 0, 0, 0,
-  56, 0, 14, 7, 0, 10, 79, 42, 2, 0,
-  11, 0, 6, 6, 16, 33, 14, 0, 0, 12,
-  0, 42, 0, 6, 83, 38, 0, 0, 5, 0,
-  37, 0, 29, 9, 43, 27, 0, 0, 1, 0,
-  0, 0, 12, 0, 2, 0, 32, 0, 100, 0,
-  40, 0, 22, 0, 0, 22, 0, 0, 8, 0,
-  32, 0, 33, 28, 0, 1, 0, 29, 40, 48,
-  56, 56, 12, 13, 56, 0, 0, 29, 28, 42,
-  16, 56, 0, 19, 0, 0, 57, 2, 6, 0,
-  0, 0, 0, 24, 0, 0, 0, 16, 1, 14,
-  21, 10, 0, 5, 37, 5, 41, 38, 0, 11,
-  0, 24, 0, 42, 0, 0, 0, 0, 0, 0,
-  70, 24, 23, 0, 0, 0, 11, 21, 44, 0,
-  8, 0, 0, 12, 70, 39, 7, 8, 19, 29,
-  0, 28, 16, 3, 38, 30, 0, 36, 4, 7,
-  0, 4, 60, 56, 0, 0, 5, 0, 33, 0,
-  12, 9, 35, 35, 0, 12, 2, 0, 10, 0,
-  0, 0, 0, 0, 6, 0, 111, 0, 30, 0,
-  9, 0, 0, 40, 0, 0, 15, 0, 26, 0,
-  40, 45, 1, 0, 0, 24, 16, 54, 51, 59,
-  27, 8, 15, 0, 0, 41, 35, 63, 9, 78,
-  0, 0, 8, 0, 21, 0, 0, 0, 0, 0,
-  0, 35, 0, 0, 0, 0, 0, 0, 38, 0,
-  0, 5, 22, 8, 24, 27, 0, 0, 0, 65,
-  0, 36, 0, 0, 0, 33, 0, 2, 97, 14,
-  35, 0, 0, 0, 20, 36, 43, 5, 0, 0,
-  0, 9, 52, 53, 0, 20, 31, 37, 0, 46,
-  33, 0, 42, 41, 0, 48, 0, 0, 2, 16,
-  45, 62, 0, 0, 12, 0, 34, 0, 0, 17,
-  24, 34, 0, 27, 0, 0, 25, 0, 0, 14,
-  10, 0, 0, 8, 110, 0, 42, 0, 17, 9,
-  0, 33, 0, 0, 27, 0, 41, 0, 45, 22,
-  0, 7, 22, 44, 69, 48, 60, 49, 0, 17,
-  100, 0, 0, 26, 19, 29, 19, 25, 0, 21,
-  0, 0, 29, 10, 19, 0, 0, 21, 0, 35,
-  0, 0, 0, 56, 7, 31, 16, 4, 0, 0,
-  48, 0, 33, 46, 0, 2, 16, 0, 0, 12,
-  0, 0, 0, 0, 0, 0, 48, 0, 33, 0,
-  0, 0, 0, 6, 51, 0, 15, 23, 0, 30,
-  42, 35, 0, 0, 24, 0, 0, 0, 26, 42,
-  0, 0, 0, 46, 0, 27, 0, 13, 75, 38,
-  0, 0, 0, 0, 17, 0, 16, 5, 28, 44,
-  0, 0, 0, 5, 8, 0, 2, 0, 24, 0,
-  4, 0, 105, 0, 27, 6, 32, 0, 0, 33,
-  0, 0, 36, 0, 0, 3, 48, 28, 0, 0,
-  10, 59, 39, 46, 67, 44, 12, 0, 51, 0,
-  0, 36, 0, 22, 41, 60, 0, 0, 0, 0,
-  19, 0, 7, 0, 0, 22, 0, 24, 0, 0,
-  0, 4, 0, 17, 23, 0, 0, 0, 55, 0,
-  1, 17, 0, 0, 18, 15, 0, 17, 0, 0,
-  0, 0, 0, 0, 102, 0, 17, 0, 0, 0,
-  5, 41, 35, 0, 3, 53, 0, 13, 18, 38,
-  12, 42, 10, 28, 0, 30, 22, 26, 21, 17,
-  0, 42, 0, 0, 0, 2, 49, 55, 1, 0,
-  0, 0, 16, 0, 14, 19, 32, 69, 0, 3,
-  0, 0, 21, 0, 0, 0, 17, 0, 0, 13,
-  100, 0, 0, 0, 30, 37, 12, 0, 30, 0,
-  18, 0, 0, 0, 37, 30, 0, 0, 4, 71,
-  11, 0, 44, 48, 26, 0, 25, 1, 22, 8,
-  0, 6, 34, 49, 0, 0, 16, 0, 0, 5,
-  0, 0, 40, 32, 0, 1, 1, 0, 0, 0,
-  0, 0, 9, 0, 0, 0, 31, 0, 0, 10,
-  0, 0, 0, 51, 0, 0, 2, 6, 23, 5,
-  0, 0, 106, 5, 12, 82, 0, 0, 6, 39,
-  0, 0, 0, 50, 1, 0, 0, 34, 0, 54,
-  42, 31, 0, 69, 0, 0, 0, 56, 0, 0,
-  20, 0, 0, 15, 19, 45, 10, 6, 0, 0,
-  0, 0, 0, 21, 1, 57, 6, 0, 0, 0,
-  53, 11, 0, 0, 15, 0, 0, 26, 8, 0,
-  0, 12, 42, 48, 0, 65, 0, 0, 34, 0,
-  36, 0, 61, 12, 0, 5, 44, 54, 61, 74,
-  64, 45, 0, 12, 72, 0, 0, 33, 31, 57,
-  17, 27, 0, 12, 0, 0, 29, 8, 17, 0,
-  0, 37, 0, 58, 0, 3, 0, 54, 0, 29,
-  24, 4, 0, 0, 35, 0, 43, 56, 0, 0,
-  7, 0, 0, 32, 0, 0, 0, 0, 0, 0,
-  70, 9, 41, 0, 0, 0, 0, 18, 51, 0,
-  0, 21, 0, 27, 40, 52, 13, 20, 40, 15,
-  0, 9, 25, 57, 3, 0, 0, 59, 0, 27,
-  0, 5, 69, 44, 0, 0, 0, 0, 2, 0,
-  12, 20, 36, 60, 0, 0, 0, 21, 0, 0,
-  0, 18, 24, 0, 0, 1, 134, 0, 38, 0,
-  44, 0, 0, 26, 42, 0, 40, 0, 0, 0,
-  68, 7, 0, 5, 43, 69, 21, 36, 59, 16,
-  3, 0, 30, 7, 16, 33, 0, 0, 32, 69,
-  0, 5, 0, 0, 0, 0, 0, 0, 0, 55,
-  0, 45, 0, 4, 0, 0, 0, 8, 12, 0,
-  0, 16, 23, 16, 0, 8, 0, 0, 24, 20,
-  0, 0, 0, 0, 0, 0, 0, 0, 70, 10,
-  16, 0, 0, 0, 0, 27, 24, 0, 0, 57,
-  0, 13, 0, 13, 15, 76, 12, 31, 0, 45,
-  9, 26, 24, 0, 0, 11, 0, 0, 0, 0,
-  52, 56, 16, 0, 0, 0, 1, 0, 7, 24,
-  39, 91, 4, 0, 0, 0, 0, 0, 11, 0,
-  10, 0, 0, 35, 51, 0, 0, 0, 24, 66,
-  70, 0, 17, 0, 20, 30, 0, 0, 12, 0,
-  0, 0, 2, 79, 18, 0, 26, 23, 6, 5,
-  29, 52, 17, 15, 0, 0, 8, 29, 0, 0,
-  0, 9, 0, 47, 0, 0, 7, 43, 0, 12,
-  0, 10, 0, 0, 5, 0, 16, 5, 10, 0,
-  24, 4, 0, 0, 15, 0, 23, 37, 5, 0,
-  30, 16, 31, 0, 0, 12, 69, 32, 32, 66,
-  0, 18, 10, 0, 25, 0, 0, 55, 11, 6,
-  0, 12, 0, 37, 48, 12, 31, 65, 0, 0,
-  0, 0, 0, 0, 29, 0, 0, 17, 57, 30,
-  0, 27, 0, 0, 0, 60, 0, 14, 29, 64,
-  0, 0, 0, 1, 7, 52, 58, 0, 0, 0,
-  0, 32, 0, 0, 0, 19, 23, 49, 0, 22,
-  0, 0, 8, 0, 32, 0, 33, 28, 0, 1,
-  0, 29, 40, 48, 56, 56, 12, 13, 56, 0,
-  0, 29, 28, 42, 16, 56, 0, 19, 0, 0,
-  57, 2, 6, 0, 0, 0, 0, 24, 0, 0,
-  0, 16, 1, 14, 21, 10, 0, 5, 37, 5,
-  41, 38, 0, 11, 0, 24, 0, 42, 0, 0,
-  0, 0, 0, 0, 70, 24, 23, 0, 0, 0,
-  11, 21, 44, 0, 8, 0, 0, 12, 70, 39,
-  7, 8, 19, 29, 0, 28, 16, 3, 38, 30,
-  0, 36, 4, 7, 0, 4, 60, 56, 0, 0,
-  5, 0, 33, 0, 12, 9, 35, 35, 0, 12,
-  2, 0, 10, 0, 0, 0, 0, 0, 6, 0,
-  111, 0, 30, 0, 9, 0, 0, 40, 0, 0,
-  15, 0, 26, 0, 40, 45, 1, 0, 0, 24,
-  16, 54, 51, 59, 27, 8, 15, 0, 0, 41,
-  35, 63, 9, 78, 0, 0, 8, 0, 21, 0,
-  0, 0, 0, 0, 0, 35, 0, 0, 0, 0,
-  0, 0, 38, 0, 0, 5, 22, 8, 24, 27,
-  0, 0, 0, 65, 0, 36, 0, 0, 0, 33,
-  0, 2, 97, 14, 35, 0, 0, 0, 20, 36,
-  43, 5, 0, 0, 0, 9, 52, 53, 0, 20,
-  31, 37, 0, 46, 33, 0, 42, 41, 0, 48,
-  0, 0, 2, 16, 45, 62, 0, 0, 12, 0,
-  34, 0, 0, 17, 24, 34, 0, 27, 0, 0,
-  25, 0, 0, 14, 10, 0, 0, 8, 110, 0,
-  42, 0, 17, 9, 0, 44, 12, 0, 11, 0,
-  23, 0, 54, 79, 0, 0, 0, 0, 3, 53,
-  49, 60, 36, 23, 0, 0, 0, 42, 29, 49,
-  27, 93, 0, 0, 15, 0, 15, 0, 0, 0,
-  0, 32, 0, 20, 0, 0, 0, 0, 0, 7,
-  42, 0, 0, 5, 12, 12, 37, 19, 0, 0,
-  0, 60, 0, 25, 1, 12, 0, 29, 0, 0,
-  86, 0, 36, 9, 0, 0, 13, 38, 43, 13,
-  0, 16, 0, 0, 60, 35, 0, 10, 27, 23,
-  0, 45, 43, 0, 17, 49, 0, 42, 0, 0,
-  4, 7, 24, 57, 0, 0, 23, 0, 36, 0,
-  0, 1, 19, 59, 0, 22, 0, 0, 36, 0,
-  0, 24, 28, 0, 1, 18, 93, 0, 22, 0,
-  42, 20, 0, 33, 0, 0, 36, 0, 0, 3,
-  48, 28, 0, 0, 10, 59, 39, 46, 67, 44,
-  12, 0, 51, 0, 0, 36, 0, 22, 41, 60,
-  0, 0, 0, 0, 19, 0, 7, 0, 0, 22,
-  0, 24, 0, 0, 0, 4, 0, 17, 23, 0,
-  0, 0, 55, 0, 1, 17, 0, 0, 18, 15,
-  0, 17, 0, 0, 0, 0, 0, 0, 102, 0,
-  17, 0, 0, 0, 5, 41, 35, 0, 3, 53,
-  0, 13, 18, 38, 12, 42, 10, 28, 0, 30,
-  22, 26, 21, 17, 0, 42, 0, 0, 0, 2,
-  49, 55, 1, 0, 0, 0, 16, 0, 14, 19,
-  32, 69, 0, 3, 0, 0, 21, 0, 0, 0,
-  17, 0, 0, 13, 100, 0, 0, 0, 30, 37,
-  12, 0, 30, 0, 18, 0, 0, 0, 37, 30,
-  0, 0, 4, 71, 11, 0, 44, 48, 26, 0,
-  25, 1, 22, 8, 0, 6, 34, 49, 0, 0,
-  16, 0, 0, 5, 0, 0, 40, 32, 0, 1,
-  1, 0, 0, 0, 0, 0, 9, 0, 0, 0,
-  31, 0, 0, 10, 0, 0, 0, 51, 0, 0,
-  2, 6, 23, 5, 0, 0, 106, 5, 12, 82,
-  0, 0, 6, 39, 0, 0, 0, 50, 1, 0,
-  0, 34, 0, 54, 42, 31, 0, 69, 0, 0,
-  0, 56, 0, 0, 20, 0, 0, 15, 19, 45,
-  10, 6, 0, 0, 0, 0, 0, 21, 1, 57,
-  6, 0, 0, 0, 53, 11, 0, 0, 15, 0,
-  0, 26, 8, 0, 0, 12, 42, 48, 16, 0,
-  43, 0, 0, 0, 0, 0, 40, 54, 0, 16,
-  0, 59, 14, 0, 21, 57, 23, 17, 21, 14,
-  54, 0, 0, 0, 42, 21, 0, 0, 0, 0,
-  0, 0, 0, 0, 54, 47, 0, 0, 9, 0,
-  0, 0, 0, 0, 9, 0, 0, 0, 23, 0,
-  0, 0, 10, 0, 8, 40, 0, 0, 0, 25,
-  50, 0, 59, 21, 36, 7, 0, 114, 0, 9,
-  8, 6, 0, 0, 4, 34, 0, 0, 0, 19,
-  0, 29, 42, 2, 22, 44, 6, 0, 0, 57,
-  0, 0, 19, 0, 0, 0, 14, 17, 24, 0,
-  0, 0, 0, 0, 0, 0, 0, 39, 0, 0,
-  0, 0, 81, 4, 14, 0, 20, 0, 0, 18,
-  0, 0, 0, 19, 37, 4, 0, 26, 42, 0,
-  40, 0, 0, 0, 68, 7, 0, 5, 43, 69,
-  21, 36, 59, 16, 3, 0, 30, 7, 16, 33,
-  0, 0, 32, 69, 0, 5, 0, 0, 0, 0,
-  0, 0, 0, 55, 0, 45, 0, 4, 0, 0,
-  0, 8, 12, 0, 0, 16, 23, 16, 0, 8,
-  0, 0, 24, 20, 0, 0, 0, 0, 0, 0,
-  0, 0, 70, 10, 16, 0, 0, 0, 0, 27,
-  24, 0, 0, 57, 0, 13, 0, 13, 15, 76,
-  12, 31, 0, 45, 9, 26, 24, 0, 0, 11,
-  0, 0, 0, 0, 52, 56, 16, 0, 0, 0,
-  1, 0, 7, 24, 39, 91, 4, 0, 0, 0,
-  0, 0, 11, 0, 10, 0, 0, 35, 51, 0,
-  0, 0, 24, 66, 70, 0, 17, 0, 20, 30,
-  0, 0, 12, 0, 0, 0, 2, 79, 18, 0,
-  26, 23, 6, 5, 29, 52, 17, 15, 0, 0,
-  8, 29, 0, 0, 0, 9, 0, 47, 0, 0,
-  7, 43, 0, 12, 0, 10, 0, 0, 5, 0,
-  16, 5, 10, 0, 24, 4, 0, 0, 15, 0,
-  23, 37, 5, 0, 30, 16, 31, 0, 0, 12,
-  69, 32, 32, 66, 0, 18, 10, 0, 25, 0,
-  0, 55, 11, 6, 0, 12, 0, 37, 48, 12,
-  31, 65, 0, 0, 0, 0, 0, 0, 29, 0,
-  0, 17, 57, 30, 0, 27, 0, 0, 0, 60,
-  0, 14, 29, 64, 0, 0, 0, 1, 7, 52,
-  58, 0, 0, 0, 0, 32, 0, 0, 0, 19,
-  23, 49, 22, 3, 0, 0, 24, 14, 0, 0,
-  31, 13, 0, 23, 0, 61, 30, 0, 16, 46,
-  7, 38, 53, 0, 0, 0, 7, 20, 37, 0,
-  0, 0, 0, 0, 0, 35, 0, 0, 9, 0,
-  0, 0, 0, 3, 0, 3, 12, 0, 13, 5,
-  0, 0, 57, 0, 3, 0, 0, 0, 27, 17,
-  0, 0, 5, 8, 37, 0, 0, 0, 19, 60,
-  0, 39, 0, 33, 30, 0, 37, 12, 0, 30,
-  0, 10, 5, 30, 0, 0, 41, 0, 71, 36,
-  0, 13, 0, 0, 4, 0, 18, 0, 0, 16,
-  44, 2, 0, 26, 0, 0, 0, 38, 5, 6,
-  19, 51, 0, 0, 0, 14, 43, 20, 37, 0,
-  0, 0, 39, 13, 0, 0, 0, 39, 17, 0,
-  0, 40, 0, 0, 15, 0, 26, 0, 40, 45,
-  1, 0, 0, 24, 16, 54, 51, 59, 27, 8,
-  15, 0, 0, 41, 35, 63, 9, 78, 0, 0,
-  8, 0, 21, 0, 0, 0, 0, 0, 0, 35,
-  0, 0, 0, 0, 0, 0, 38, 0, 0, 5,
-  22, 8, 24, 27, 0, 0, 0, 65, 0, 36,
-  0, 0, 0, 33, 0, 2, 97, 14, 35, 0,
-  0, 0, 20, 36, 43, 5, 0, 0, 0, 9,
-  52, 53, 0, 20, 31, 37, 0, 46, 33, 0,
-  42, 41, 0, 48, 0, 0, 2, 16, 45, 62,
-  0, 0, 12, 0, 34, 0, 0, 17, 24, 34,
-  0, 27, 0, 0, 25, 0, 0, 14, 10, 0,
-  0, 8, 110, 0, 42, 0, 17, 9, 0, 44,
-  12, 0, 11, 0, 23, 0, 54, 79, 0, 0,
-  0, 0, 3, 53, 49, 60, 36, 23, 0, 0,
-  0, 42, 29, 49, 27, 93, 0, 0, 15, 0,
-  15, 0, 0, 0, 0, 32, 0, 20, 0, 0,
-  0, 0, 0, 7, 42, 0, 0, 5, 12, 12,
-  37, 19, 0, 0, 0, 60, 0, 25, 1, 12,
-  0, 29, 0, 0, 86, 0, 36, 9, 0, 0,
-  13, 38, 43, 13, 0, 16, 0, 0, 60, 35,
-  0, 10, 27, 23, 0, 45, 43, 0, 17, 49,
-  0, 42, 0, 0, 4, 7, 24, 57, 0, 0,
-  23, 0, 36, 0, 0, 1, 19, 59, 0, 22,
-  0, 0, 36, 0, 0, 24, 28, 0, 1, 18,
-  93, 0, 22, 0, 42, 20, 0, 38, 33, 0,
-  0, 0, 27, 0, 63, 89, 0, 12, 0, 0,
-  14, 41, 49, 72, 30, 11, 0, 0, 0, 57,
-  37, 23, 43, 98, 0, 0, 23, 0, 9, 0,
-  0, 0, 0, 70, 0, 0, 14, 15, 16, 0,
-  0, 17, 24, 0, 0, 0, 12, 0, 48, 0,
-  0, 0, 0, 33, 0, 3, 10, 18, 0, 50,
-  0, 0, 81, 0, 15, 42, 0, 0, 7, 44,
-  23, 12, 4, 28, 0, 0, 63, 33, 2, 27,
-  31, 25, 2, 25, 25, 0, 0, 46, 0, 33,
-  0, 0, 0, 14, 0, 51, 3, 0, 8, 0,
-  41, 0, 0, 18, 2, 64, 10, 19, 0, 0,
-  55, 0, 0, 23, 45, 0, 7, 3, 63, 0,
-  0, 0, 78, 18, 12, 0, 30, 0, 18, 0,
-  0, 0, 37, 30, 0, 0, 4, 71, 11, 0,
-  44, 48, 26, 0, 25, 1, 22, 8, 0, 6,
-  34, 49, 0, 0, 16, 0, 0, 5, 0, 0,
-  40, 32, 0, 1, 1, 0, 0, 0, 0, 0,
-  9, 0, 0, 0, 31, 0, 0, 10, 0, 0,
-  0, 51, 0, 0, 2, 6, 23, 5, 0, 0,
-  106, 5, 12, 82, 0, 0, 6, 39, 0, 0,
-  0, 50, 1, 0, 0, 34, 0, 54, 42, 31,
-  0, 69, 0, 0, 0, 56, 0, 0, 20, 0,
-  0, 15, 19, 45, 10, 6, 0, 0, 0, 0,
-  0, 21, 1, 57, 6, 0, 0, 0, 53, 11,
-  0, 0, 15, 0, 0, 26, 8, 0, 0, 12,
-  42, 48, 16, 0, 43, 0, 0, 0, 0, 0,
-  40, 54, 0, 16, 0, 59, 14, 0, 21, 57,
-  23, 17, 21, 14, 54, 0, 0, 0, 42, 21,
-  0, 0, 0, 0, 0, 0, 0, 0, 54, 47,
-  0, 0, 9, 0, 0, 0, 0, 0, 9, 0,
-  0, 0, 23, 0, 0, 0, 10, 0, 8, 40,
-  0, 0, 0, 25, 50, 0, 59, 21, 36, 7,
-  0, 114, 0, 9, 8, 6, 0, 0, 4, 34,
-  0, 0, 0, 19, 0, 29, 42, 2, 22, 44,
-  6, 0, 0, 57, 0, 0, 19, 0, 0, 0,
-  14, 17, 24, 0, 0, 0, 0, 0, 0, 0,
-  0, 39, 0, 0, 0, 0, 81, 4, 14, 0,
-  20, 0, 0, 18, 0, 0, 0, 19, 37, 4,
-  30, 0, 21, 8, 18, 0, 0, 0, 23, 36,
-  0, 0, 0, 54, 7, 0, 0, 65, 15, 16,
-  55, 1, 62, 10, 0, 0, 52, 0, 0, 0,
-  14, 0, 0, 0, 0, 0, 9, 33, 0, 0,
-  29, 0, 0, 9, 0, 0, 15, 0, 0, 0,
-  30, 30, 0, 0, 29, 0, 20, 15, 0, 0,
-  0, 14, 64, 0, 89, 22, 8, 0, 0, 130,
-  0, 14, 8, 0, 2, 0, 14, 22, 0, 0,
-  24, 0, 8, 22, 41, 0, 39, 0, 26, 0,
-  0, 30, 15, 0, 0, 0, 0, 0, 23, 0,
-  15, 0, 0, 0, 0, 0, 0, 32, 0, 10,
-  0, 9, 0, 0, 99, 17, 35, 0, 24, 0,
-  6, 0, 0, 0, 0, 31, 25, 0, 70, 0,
-  17, 0, 20, 30, 0, 0, 12, 0, 0, 0,
-  2, 79, 18, 0, 26, 23, 6, 5, 29, 52,
-  17, 15, 0, 0, 8, 29, 0, 0, 0, 9,
-  0, 47, 0, 0, 7, 43, 0, 12, 0, 10,
-  0, 0, 5, 0, 16, 5, 10, 0, 24, 4,
-  0, 0, 15, 0, 23, 37, 5, 0, 30, 16,
-  31, 0, 0, 12, 69, 32, 32, 66, 0, 18,
-  10, 0, 25, 0, 0, 55, 11, 6, 0, 12,
-  0, 37, 48, 12, 31, 65, 0, 0, 0, 0,
-  0, 0, 29, 0, 0, 17, 57, 30, 0, 27,
-  0, 0, 0, 60, 0, 14, 29, 64, 0, 0,
-  0, 1, 7, 52, 58, 0, 0, 0, 0, 32,
-  0, 0, 0, 19, 23, 49, 22, 3, 0, 0,
-  24, 14, 0, 0, 31, 13, 0, 23, 0, 61,
-  30, 0, 16, 46, 7, 38, 53, 0, 0, 0,
-  7, 20, 37, 0, 0, 0, 0, 0, 0, 35,
-  0, 0, 9, 0, 0, 0, 0, 3, 0, 3,
-  12, 0, 13, 5, 0, 0, 57, 0, 3, 0,
-  0, 0, 27, 17, 0, 0, 5, 8, 37, 0,
-  0, 0, 19, 60, 0, 39, 0, 33, 30, 0,
-  37, 12, 0, 30, 0, 10, 5, 30, 0, 0,
-  41, 0, 71, 36, 0, 13, 0, 0, 4, 0,
-  18, 0, 0, 16, 44, 2, 0, 26, 0, 0,
-  0, 38, 5, 6, 19, 51, 0, 0, 0, 14,
-  43, 20, 37, 0, 0, 0, 39, 13, 0, 0,
-  0, 39, 17, 0, 19, 51, 0, 11, 63, 0,
-  36, 0, 33, 2, 0, 24, 2, 46, 28, 0,
-  6, 25, 11, 52, 60, 0, 0, 15, 21, 37,
-  39, 0, 0, 21, 42, 0, 0, 33, 0, 0,
-  0, 0, 0, 0, 0, 29, 0, 51, 23, 0,
-  7, 28, 0, 0, 51, 0, 37, 15, 0, 12,
-  5, 0, 0, 22, 16, 2, 15, 0, 0, 0,
-  4, 57, 0, 0, 0, 41, 5, 0, 60, 0,
-  19, 1, 4, 1, 52, 31, 4, 0, 58, 0,
-  51, 26, 21, 39, 0, 0, 0, 32, 0, 23,
-  0, 0, 55, 8, 0, 36, 1, 0, 0, 0,
-  14, 29, 63, 36, 0, 0, 0, 0, 46, 0,
-  12, 0, 4, 0, 35, 1, 40, 0, 0, 33,
-  0, 0, 0, 44, 12, 0, 11, 0, 23, 0,
-  54, 79, 0, 0, 0, 0, 3, 53, 49, 60,
-  36, 23, 0, 0, 0, 42, 29, 49, 27, 93,
-  0, 0, 15, 0, 15, 0, 0, 0, 0, 32,
-  0, 20, 0, 0, 0, 0, 0, 7, 42, 0,
-  0, 5, 12, 12, 37, 19, 0, 0, 0, 60,
-  0, 25, 1, 12, 0, 29, 0, 0, 86, 0,
-  36, 9, 0, 0, 13, 38, 43, 13, 0, 16,
-  0, 0, 60, 35, 0, 10, 27, 23, 0, 45,
-  43, 0, 17, 49, 0, 42, 0, 0, 4, 7,
-  24, 57, 0, 0, 23, 0, 36, 0, 0, 1,
-  19, 59, 0, 22, 0, 0, 36, 0, 0, 24,
-  28, 0, 1, 18, 93, 0, 22, 0, 42, 20,
-  0, 38, 33, 0, 0, 0, 27, 0, 63, 89,
-  0, 12, 0, 0, 14, 41, 49, 72, 30, 11,
-  0, 0, 0, 57, 37, 23, 43, 98, 0, 0,
-  23, 0, 9, 0, 0, 0, 0, 70, 0, 0,
-  14, 15, 16, 0, 0, 17, 24, 0, 0, 0,
-  12, 0, 48, 0, 0, 0, 0, 33, 0, 3,
-  10, 18, 0, 50, 0, 0, 81, 0, 15, 42,
-  0, 0, 7, 44, 23, 12, 4, 28, 0, 0,
-  63, 33, 2, 27, 31, 25, 2, 25, 25, 0,
-  0, 46, 0, 33, 0, 0, 0, 14, 0, 51,
-  3, 0, 8, 0, 41, 0, 0, 18, 2, 64,
-  10, 19, 0, 0, 55, 0, 0, 23, 45, 0,
-  7, 3, 63, 0, 0, 0, 78, 18, 0, 39,
-  39, 0, 0, 0, 25, 0, 78, 78, 0, 0,
-  0, 3, 0, 17, 3, 41, 11, 0, 0, 0,
-  16, 61, 36, 0, 50, 80, 0, 0, 9, 0,
-  0, 0, 0, 0, 16, 73, 0, 0, 40, 8,
-  4, 0, 0, 14, 31, 0, 0, 0, 18, 0,
-  26, 0, 2, 0, 24, 52, 0, 0, 0, 48,
-  0, 57, 2, 2, 88, 0, 14, 69, 0, 0,
-  2, 41, 6, 46, 1, 15, 0, 0, 48, 46,
-  0, 40, 32, 26, 15, 28, 27, 0, 0, 65,
-  0, 8, 0, 0, 0, 0, 0, 52, 25, 0,
-  0, 0, 32, 0, 0, 39, 0, 43, 11, 0,
-  0, 0, 70, 0, 0, 25, 54, 0, 0, 0,
-  11, 0, 0, 0, 64, 2, 16, 0, 43, 0,
-  0, 0, 0, 0, 40, 54, 0, 16, 0, 59,
-  14, 0, 21, 57, 23, 17, 21, 14, 54, 0,
-  0, 0, 42, 21, 0, 0, 0, 0, 0, 0,
-  0, 0, 54, 47, 0, 0, 9, 0, 0, 0,
-  0, 0, 9, 0, 0, 0, 23, 0, 0, 0,
-  10, 0, 8, 40, 0, 0, 0, 25, 50, 0,
-  59, 21, 36, 7, 0, 114, 0, 9, 8, 6,
-  0, 0, 4, 34, 0, 0, 0, 19, 0, 29,
-  42, 2, 22, 44, 6, 0, 0, 57, 0, 0,
-  19, 0, 0, 0, 14, 17, 24, 0, 0, 0,
-  0, 0, 0, 0, 0, 39, 0, 0, 0, 0,
-  81, 4, 14, 0, 20, 0, 0, 18, 0, 0,
-  0, 19, 37, 4, 30, 0, 21, 8, 18, 0,
-  0, 0, 23, 36, 0, 0, 0, 54, 7, 0,
-  0, 65, 15, 16, 55, 1, 62, 10, 0, 0,
-  52, 0, 0, 0, 14, 0, 0, 0, 0, 0,
-  9, 33, 0, 0, 29, 0, 0, 9, 0, 0,
-  15, 0, 0, 0, 30, 30, 0, 0, 29, 0,
-  20, 15, 0, 0, 0, 14, 64, 0, 89, 22,
-  8, 0, 0, 130, 0, 14, 8, 0, 2, 0,
-  14, 22, 0, 0, 24, 0, 8, 22, 41, 0,
-  39, 0, 26, 0, 0, 30, 15, 0, 0, 0,
-  0, 0, 23, 0, 15, 0, 0, 0, 0, 0,
-  0, 32, 0, 10, 0, 9, 0, 0, 99, 17,
-  35, 0, 24, 0, 6, 0, 0, 0, 0, 31,
-  25, 0, 5, 13, 0, 32, 19, 0, 8, 0,
-  42, 4, 0, 13, 0, 36, 0, 0, 0, 57,
-  0, 20, 78, 0, 62, 17, 0, 0, 48, 0,
-  0, 0, 23, 0, 0, 0, 0, 0, 0, 22,
-  0, 0, 41, 0, 0, 33, 9, 0, 6, 0,
-  0, 0, 32, 6, 0, 0, 33, 0, 37, 0,
-  4, 0, 0, 39, 62, 0, 84, 8, 32, 22,
-  0, 130, 0, 9, 16, 0, 0, 9, 33, 13,
-  0, 0, 29, 13, 0, 22, 32, 0, 33, 0,
-  24, 0, 0, 28, 10, 0, 0, 0, 8, 0,
-  32, 0, 10, 12, 0, 0, 0, 0, 0, 83,
-  0, 0, 2, 0, 0, 0, 98, 36, 46, 0,
-  18, 0, 8, 0, 0, 0, 0, 28, 8, 0,
-  22, 3, 0, 0, 24, 14, 0, 0, 31, 13,
-  0, 23, 0, 61, 30, 0, 16, 46, 7, 38,
-  53, 0, 0, 0, 7, 20, 37, 0, 0, 0,
-  0, 0, 0, 35, 0, 0, 9, 0, 0, 0,
-  0, 3, 0, 3, 12, 0, 13, 5, 0, 0,
-  57, 0, 3, 0, 0, 0, 27, 17, 0, 0,
-  5, 8, 37, 0, 0, 0, 19, 60, 0, 39,
-  0, 33, 30, 0, 37, 12, 0, 30, 0, 10,
-  5, 30, 0, 0, 41, 0, 71, 36, 0, 13,
-  0, 0, 4, 0, 18, 0, 0, 16, 44, 2,
-  0, 26, 0, 0, 0, 38, 5, 6, 19, 51,
-  0, 0, 0, 14, 43, 20, 37, 0, 0, 0,
-  39, 13, 0, 0, 0, 39, 17, 0, 19, 51,
-  0, 11, 63, 0, 36, 0, 33, 2, 0, 24,
-  2, 46, 28, 0, 6, 25, 11, 52, 60, 0,
-  0, 15, 21, 37, 39, 0, 0, 21, 42, 0,
-  0, 33, 0, 0, 0, 0, 0, 0, 0, 29,
-  0, 51, 23, 0, 7, 28, 0, 0, 51, 0,
-  37, 15, 0, 12, 5, 0, 0, 22, 16, 2,
-  15, 0, 0, 0, 4, 57, 0, 0, 0, 41,
-  5, 0, 60, 0, 19, 1, 4, 1, 52, 31,
-  4, 0, 58, 0, 51, 26, 21, 39, 0, 0,
-  0, 32, 0, 23, 0, 0, 55, 8, 0, 36,
-  1, 0, 0, 0, 14, 29, 63, 36, 0, 0,
-  0, 0, 46, 0, 12, 0, 4, 0, 35, 1,
-  40, 0, 0, 33, 0, 0, 0, 99, 0, 38,
-  55, 0, 74, 0, 47, 0, 0, 55, 43, 30,
-  27, 0, 3, 36, 0, 59, 80, 0, 0, 26,
-  36, 49, 32, 1, 0, 12, 51, 0, 22, 17,
-  3, 0, 0, 0, 0, 0, 0, 20, 0, 83,
-  20, 23, 0, 15, 0, 0, 26, 0, 67, 45,
-  0, 11, 23, 0, 0, 37, 22, 0, 0, 0,
-  0, 0, 14, 67, 0, 0, 0, 11, 0, 0,
-  67, 0, 16, 0, 7, 0, 80, 54, 0, 0,
-  42, 0, 37, 1, 24, 67, 6, 0, 0, 40,
-  0, 45, 0, 0, 77, 8, 0, 34, 3, 0,
-  0, 0, 25, 58, 103, 36, 0, 0, 0, 0,
-  32, 0, 0, 0, 0, 0, 21, 22, 80, 0,
-  38, 25, 8, 0, 0, 38, 33, 0, 0, 0,
-  27, 0, 63, 89, 0, 12, 0, 0, 14, 41,
-  49, 72, 30, 11, 0, 0, 0, 57, 37, 23,
-  43, 98, 0, 0, 23, 0, 9, 0, 0, 0,
-  0, 70, 0, 0, 14, 15, 16, 0, 0, 17,
-  24, 0, 0, 0, 12, 0, 48, 0, 0, 0,
-  0, 33, 0, 3, 10, 18, 0, 50, 0, 0,
-  81, 0, 15, 42, 0, 0, 7, 44, 23, 12,
-  4, 28, 0, 0, 63, 33, 2, 27, 31, 25,
-  2, 25, 25, 0, 0, 46, 0, 33, 0, 0,
-  0, 14, 0, 51, 3, 0, 8, 0, 41, 0,
-  0, 18, 2, 64, 10, 19, 0, 0, 55, 0,
-  0, 23, 45, 0, 7, 3, 63, 0, 0, 0,
-  78, 18, 0, 39, 39, 0, 0, 0, 25, 0,
-  78, 78, 0, 0, 0, 3, 0, 17, 3, 41,
-  11, 0, 0, 0, 16, 61, 36, 0, 50, 80,
-  0, 0, 9, 0, 0, 0, 0, 0, 16, 73,
-  0, 0, 40, 8, 4, 0, 0, 14, 31, 0,
-  0, 0, 18, 0, 26, 0, 2, 0, 24, 52,
-  0, 0, 0, 48, 0, 57, 2, 2, 88, 0,
-  14, 69, 0, 0, 2, 41, 6, 46, 1, 15,
-  0, 0, 48, 46, 0, 40, 32, 26, 15, 28,
-  27, 0, 0, 65, 0, 8, 0, 0, 0, 0,
-  0, 52, 25, 0, 0, 0, 32, 0, 0, 39,
-  0, 43, 11, 0, 0, 0, 70, 0, 0, 25,
-  54, 0, 0, 0, 11, 0, 0, 0, 64, 2,
-  0, 29, 0, 0, 0, 0, 15, 0, 80, 38,
-  0, 0, 0, 0, 0, 0, 0, 35, 26, 0,
-  14, 0, 0, 45, 31, 0, 42, 64, 0, 0,
-  16, 0, 0, 5, 0, 0, 32, 60, 1, 0,
-  52, 0, 0, 0, 0, 15, 40, 0, 0, 0,
-  0, 2, 11, 0, 19, 50, 26, 49, 0, 0,
-  6, 43, 3, 66, 19, 0, 76, 0, 18, 84,
-  0, 0, 2, 19, 0, 39, 0, 5, 14, 0,
-  39, 27, 3, 12, 27, 17, 21, 31, 23, 0,
-  0, 98, 2, 0, 0, 0, 0, 0, 39, 39,
-  30, 37, 0, 0, 15, 0, 0, 33, 0, 44,
-  1, 9, 0, 0, 55, 0, 0, 24, 71, 0,
-  0, 0, 0, 0, 0, 0, 42, 0, 30, 0,
-  21, 8, 18, 0, 0, 0, 23, 36, 0, 0,
-  0, 54, 7, 0, 0, 65, 15, 16, 55, 1,
-  62, 10, 0, 0, 52, 0, 0, 0, 14, 0,
-  0, 0, 0, 0, 9, 33, 0, 0, 29, 0,
-  0, 9, 0, 0, 15, 0, 0, 0, 30, 30,
-  0, 0, 29, 0, 20, 15, 0, 0, 0, 14,
-  64, 0, 89, 22, 8, 0, 0, 130, 0, 14,
-  8, 0, 2, 0, 14, 22, 0, 0, 24, 0,
-  8, 22, 41, 0, 39, 0, 26, 0, 0, 30,
-  15, 0, 0, 0, 0, 0, 23, 0, 15, 0,
-  0, 0, 0, 0, 0, 32, 0, 10, 0, 9,
-  0, 0, 99, 17, 35, 0, 24, 0, 6, 0,
-  0, 0, 0, 31, 25, 0, 5, 13, 0, 32,
-  19, 0, 8, 0, 42, 4, 0, 13, 0, 36,
-  0, 0, 0, 57, 0, 20, 78, 0, 62, 17,
-  0, 0, 48, 0, 0, 0, 23, 0, 0, 0,
-  0, 0, 0, 22, 0, 0, 41, 0, 0, 33,
-  9, 0, 6, 0, 0, 0, 32, 6, 0, 0,
-  33, 0, 37, 0, 4, 0, 0, 39, 62, 0,
-  84, 8, 32, 22, 0, 130, 0, 9, 16, 0,
-  0, 9, 33, 13, 0, 0, 29, 13, 0, 22,
-  32, 0, 33, 0, 24, 0, 0, 28, 10, 0,
-  0, 0, 8, 0, 32, 0, 10, 12, 0, 0,
-  0, 0, 0, 83, 0, 0, 2, 0, 0, 0,
-  98, 36, 46, 0, 18, 0, 8, 0, 0, 0,
-  0, 28, 8, 0, 11, 29, 0, 45, 2, 0,
-  17, 0, 59, 0, 0, 24, 0, 0, 0, 0,
-  0, 40, 1, 11, 70, 0, 8, 10, 0, 0,
-  32, 0, 0, 0, 26, 22, 0, 7, 0, 0,
-  17, 26, 2, 0, 47, 0, 0, 21, 13, 9,
-  8, 0, 0, 0, 39, 2, 0, 18, 67, 54,
-  46, 0, 21, 0, 0, 41, 60, 20, 72, 13,
-  27, 31, 0, 123, 0, 13, 17, 0, 0, 28,
-  28, 13, 17, 0, 23, 19, 0, 3, 26, 0,
-  27, 0, 23, 0, 0, 39, 0, 0, 0, 3,
-  33, 0, 52, 9, 4, 75, 0, 0, 0, 0,
-  0, 100, 0, 0, 2, 0, 0, 11, 51, 34,
-  23, 0, 31, 0, 14, 0, 0, 0, 3, 31,
-  7, 0, 19, 51, 0, 11, 63, 0, 36, 0,
-  33, 2, 0, 24, 2, 46, 28, 0, 6, 25,
-  11, 52, 60, 0, 0, 15, 21, 37, 39, 0,
-  0, 21, 42, 0, 0, 33, 0, 0, 0, 0,
-  0, 0, 0, 29, 0, 51, 23, 0, 7, 28,
-  0, 0, 51, 0, 37, 15, 0, 12, 5, 0,
-  0, 22, 16, 2, 15, 0, 0, 0, 4, 57,
-  0, 0, 0, 41, 5, 0, 60, 0, 19, 1,
-  4, 1, 52, 31, 4, 0, 58, 0, 51, 26,
-  21, 39, 0, 0, 0, 32, 0, 23, 0, 0,
-  55, 8, 0, 36, 1, 0, 0, 0, 14, 29,
-  63, 36, 0, 0, 0, 0, 46, 0, 12, 0,
-  4, 0, 35, 1, 40, 0, 0, 33, 0, 0,
-  0, 99, 0, 38, 55, 0, 74, 0, 47, 0,
-  0, 55, 43, 30, 27, 0, 3, 36, 0, 59,
-  80, 0, 0, 26, 36, 49, 32, 1, 0, 12,
-  51, 0, 22, 17, 3, 0, 0, 0, 0, 0,
-  0, 20, 0, 83, 20, 23, 0, 15, 0, 0,
-  26, 0, 67, 45, 0, 11, 23, 0, 0, 37,
-  22, 0, 0, 0, 0, 0, 14, 67, 0, 0,
-  0, 11, 0, 0, 67, 0, 16, 0, 7, 0,
-  80, 54, 0, 0, 42, 0, 37, 1, 24, 67,
-  6, 0, 0, 40, 0, 45, 0, 0, 77, 8,
-  0, 34, 3, 0, 0, 0, 25, 58, 103, 36,
-  0, 0, 0, 0, 32, 0, 0, 0, 0, 0,
-  21, 22, 80, 0, 38, 25, 8, 0, 0, 129,
-  0, 59, 30, 0, 80, 0, 63, 0, 2, 62,
-  41, 13, 24, 8, 0, 36, 0, 50, 73, 0,
-  0, 34, 40, 69, 39, 5, 0, 13, 44, 0,
-  63, 0, 17, 0, 0, 0, 0, 0, 0, 30,
-  0, 55, 31, 26, 0, 15, 0, 0, 34, 0,
-  63, 66, 0, 6, 53, 0, 0, 76, 13, 0,
-  0, 0, 0, 0, 32, 81, 0, 0, 0, 20,
-  0, 0, 48, 49, 0, 0, 0, 0, 65, 72,
-  1, 0, 21, 0, 34, 0, 17, 106, 73, 0,
-  0, 66, 0, 33, 16, 0, 73, 22, 0, 27,
-  0, 0, 0, 0, 17, 70, 123, 31, 8, 0,
-  18, 0, 19, 0, 0, 0, 0, 0, 16, 21,
-  113, 10, 49, 16, 11, 0, 0, 39, 39, 0,
-  0, 0, 25, 0, 78, 78, 0, 0, 0, 3,
-  0, 17, 3, 41, 11, 0, 0, 0, 16, 61,
-  36, 0, 50, 80, 0, 0, 9, 0, 0, 0,
-  0, 0, 16, 73, 0, 0, 40, 8, 4, 0,
-  0, 14, 31, 0, 0, 0, 18, 0, 26, 0,
-  2, 0, 24, 52, 0, 0, 0, 48, 0, 57,
-  2, 2, 88, 0, 14, 69, 0, 0, 2, 41,
-  6, 46, 1, 15, 0, 0, 48, 46, 0, 40,
-  32, 26, 15, 28, 27, 0, 0, 65, 0, 8,
-  0, 0, 0, 0, 0, 52, 25, 0, 0, 0,
-  32, 0, 0, 39, 0, 43, 11, 0, 0, 0,
-  70, 0, 0, 25, 54, 0, 0, 0, 11, 0,
-  0, 0, 64, 2, 0, 29, 0, 0, 0, 0,
-  15, 0, 80, 38, 0, 0, 0, 0, 0, 0,
-  0, 35, 26, 0, 14, 0, 0, 45, 31, 0,
-  42, 64, 0, 0, 16, 0, 0, 5, 0, 0,
-  32, 60, 1, 0, 52, 0, 0, 0, 0, 15,
-  40, 0, 0, 0, 0, 2, 11, 0, 19, 50,
-  26, 49, 0, 0, 6, 43, 3, 66, 19, 0,
-  76, 0, 18, 84, 0, 0, 2, 19, 0, 39,
-  0, 5, 14, 0, 39, 27, 3, 12, 27, 17,
-  21, 31, 23, 0, 0, 98, 2, 0, 0, 0,
-  0, 0, 39, 39, 30, 37, 0, 0, 15, 0,
-  0, 33, 0, 44, 1, 9, 0, 0, 55, 0,
-  0, 24, 71, 0, 0, 0, 0, 0, 0, 0,
-  42, 0, 0, 21, 0, 0, 2, 0, 15, 0,
-  74, 29, 0, 18, 0, 12, 0, 34, 16, 63,
-  31, 0, 0, 0, 0, 43, 15, 0, 18, 55,
-  0, 0, 44, 0, 0, 15, 0, 0, 19, 53,
-  0, 0, 37, 0, 0, 0, 0, 6, 28, 0,
-  0, 0, 0, 19, 26, 0, 3, 71, 33, 50,
-  0, 0, 10, 18, 0, 54, 2, 0, 62, 0,
-  20, 53, 0, 0, 0, 10, 0, 34, 0, 0,
-  19, 0, 50, 13, 6, 0, 30, 11, 7, 22,
-  34, 0, 0, 109, 0, 6, 0, 0, 0, 0,
-  36, 46, 17, 32, 7, 0, 17, 0, 0, 18,
-  0, 40, 0, 25, 0, 9, 51, 0, 0, 9,
-  68, 0, 0, 9, 34, 0, 14, 0, 50, 0,
-  5, 13, 0, 32, 19, 0, 8, 0, 42, 4,
-  0, 13, 0, 36, 0, 0, 0, 57, 0, 20,
-  78, 0, 62, 17, 0, 0, 48, 0, 0, 0,
-  23, 0, 0, 0, 0, 0, 0, 22, 0, 0,
-  41, 0, 0, 33, 9, 0, 6, 0, 0, 0,
-  32, 6, 0, 0, 33, 0, 37, 0, 4, 0,
-  0, 39, 62, 0, 84, 8, 32, 22, 0, 130,
-  0, 9, 16, 0, 0, 9, 33, 13, 0, 0,
-  29, 13, 0, 22, 32, 0, 33, 0, 24, 0,
-  0, 28, 10, 0, 0, 0, 8, 0, 32, 0,
-  10, 12, 0, 0, 0, 0, 0, 83, 0, 0,
-  2, 0, 0, 0, 98, 36, 46, 0, 18, 0,
-  8, 0, 0, 0, 0, 28, 8, 0, 11, 29,
-  0, 45, 2, 0, 17, 0, 59, 0, 0, 24,
-  0, 0, 0, 0, 0, 40, 1, 11, 70, 0,
-  8, 10, 0, 0, 32, 0, 0, 0, 26, 22,
-  0, 7, 0, 0, 17, 26, 2, 0, 47, 0,
-  0, 21, 13, 9, 8, 0, 0, 0, 39, 2,
-  0, 18, 67, 54, 46, 0, 21, 0, 0, 41,
-  60, 20, 72, 13, 27, 31, 0, 123, 0, 13,
-  17, 0, 0, 28, 28, 13, 17, 0, 23, 19,
-  0, 3, 26, 0, 27, 0, 23, 0, 0, 39,
-  0, 0, 0, 3, 33, 0, 52, 9, 4, 75,
-  0, 0, 0, 0, 0, 100, 0, 0, 2, 0,
-  0, 11, 51, 34, 23, 0, 31, 0, 14, 0,
-  0, 0, 3, 31, 7, 0, 11, 24, 0, 20,
-  0, 8, 0, 0, 72, 0, 0, 35, 0, 0,
-  0, 0, 0, 45, 6, 0, 35, 11, 0, 11,
-  0, 0, 13, 0, 0, 0, 2, 13, 0, 0,
-  0, 0, 29, 44, 34, 0, 50, 0, 0, 11,
-  0, 7, 0, 0, 0, 0, 8, 60, 0, 0,
-  108, 136, 34, 5, 37, 0, 0, 24, 71, 27,
-  134, 39, 0, 0, 0, 158, 66, 0, 9, 0,
-  0, 10, 0, 0, 39, 0, 9, 0, 13, 5,
-  9, 0, 4, 0, 70, 0, 0, 80, 0, 0,
-  27, 0, 26, 0, 39, 45, 33, 130, 0, 0,
-  0, 0, 0, 84, 0, 0, 0, 0, 0, 24,
-  23, 13, 0, 0, 36, 0, 0, 0, 0, 0,
-  23, 31, 12, 0, 0, 99, 0, 38, 55, 0,
-  74, 0, 47, 0, 0, 55, 43, 30, 27, 0,
-  3, 36, 0, 59, 80, 0, 0, 26, 36, 49,
-  32, 1, 0, 12, 51, 0, 22, 17, 3, 0,
-  0, 0, 0, 0, 0, 20, 0, 83, 20, 23,
-  0, 15, 0, 0, 26, 0, 67, 45, 0, 11,
-  23, 0, 0, 37, 22, 0, 0, 0, 0, 0,
-  14, 67, 0, 0, 0, 11, 0, 0, 67, 0,
-  16, 0, 7, 0, 80, 54, 0, 0, 42, 0,
-  37, 1, 24, 67, 6, 0, 0, 40, 0, 45,
-  0, 0, 77, 8, 0, 34, 3, 0, 0, 0,
-  25, 58, 103, 36, 0, 0, 0, 0, 32, 0,
-  0, 0, 0, 0, 21, 22, 80, 0, 38, 25,
-  8, 0, 0, 129, 0, 59, 30, 0, 80, 0,
-  63, 0, 2, 62, 41, 13, 24, 8, 0, 36,
-  0, 50, 73, 0, 0, 34, 40, 69, 39, 5,
-  0, 13, 44, 0, 63, 0, 17, 0, 0, 0,
-  0, 0, 0, 30, 0, 55, 31, 26, 0, 15,
-  0, 0, 34, 0, 63, 66, 0, 6, 53, 0,
-  0, 76, 13, 0, 0, 0, 0, 0, 32, 81,
-  0, 0, 0, 20, 0, 0, 48, 49, 0, 0,
-  0, 0, 65, 72, 1, 0, 21, 0, 34, 0,
-  17, 106, 73, 0, 0, 66, 0, 33, 16, 0,
-  73, 22, 0, 27, 0, 0, 0, 0, 17, 70,
-  123, 31, 8, 0, 18, 0, 19, 0, 0, 0,
-  0, 0, 16, 21, 113, 10, 49, 16, 11, 0,
-  4, 112, 0, 54, 23, 0, 15, 0, 85, 7,
-  0, 53, 5, 3, 0, 0, 0, 18, 0, 13,
-  49, 0, 0, 31, 10, 11, 45, 17, 0, 0,
-  0, 9, 32, 0, 23, 0, 0, 18, 0, 0,
-  0, 0, 0, 18, 25, 27, 0, 0, 0, 0,
-  33, 14, 7, 64, 44, 38, 45, 0, 0, 10,
-  0, 11, 7, 12, 0, 7, 17, 45, 0, 29,
-  0, 13, 26, 0, 1, 55, 0, 8, 5, 0,
-  20, 44, 16, 23, 0, 0, 15, 29, 38, 55,
-  93, 0, 0, 17, 0, 0, 52, 0, 35, 52,
-  0, 80, 0, 0, 0, 0, 0, 84, 112, 0,
-  31, 0, 15, 3, 1, 0, 0, 0, 0, 0,
-  3, 0, 28, 0, 45, 32, 0, 0, 0, 29,
-  0, 0, 0, 0, 15, 0, 80, 38, 0, 0,
-  0, 0, 0, 0, 0, 35, 26, 0, 14, 0,
-  0, 45, 31, 0, 42, 64, 0, 0, 16, 0,
-  0, 5, 0, 0, 32, 60, 1, 0, 52, 0,
-  0, 0, 0, 15, 40, 0, 0, 0, 0, 2,
-  11, 0, 19, 50, 26, 49, 0, 0, 6, 43,
-  3, 66, 19, 0, 76, 0, 18, 84, 0, 0,
-  2, 19, 0, 39, 0, 5, 14, 0, 39, 27,
-  3, 12, 27, 17, 21, 31, 23, 0, 0, 98,
-  2, 0, 0, 0, 0, 0, 39, 39, 30, 37,
-  0, 0, 15, 0, 0, 33, 0, 44, 1, 9,
-  0, 0, 55, 0, 0, 24, 71, 0, 0, 0,
-  0, 0, 0, 0, 42, 0, 0, 21, 0, 0,
-  2, 0, 15, 0, 74, 29, 0, 18, 0, 12,
-  0, 34, 16, 63, 31, 0, 0, 0, 0, 43,
-  15, 0, 18, 55, 0, 0, 44, 0, 0, 15,
-  0, 0, 19, 53, 0, 0, 37, 0, 0, 0,
-  0, 6, 28, 0, 0, 0, 0, 19, 26, 0,
-  3, 71, 33, 50, 0, 0, 10, 18, 0, 54,
-  2, 0, 62, 0, 20, 53, 0, 0, 0, 10,
-  0, 34, 0, 0, 19, 0, 50, 13, 6, 0,
-  30, 11, 7, 22, 34, 0, 0, 109, 0, 6,
-  0, 0, 0, 0, 36, 46, 17, 32, 7, 0,
-  17, 0, 0, 18, 0, 40, 0, 25, 0, 9,
-  51, 0, 0, 9, 68, 0, 0, 9, 34, 0,
-  14, 0, 50, 0, 0, 44, 0, 0, 11, 0,
-  30, 0, 44, 53, 0, 11, 18, 12, 0, 82,
-  51, 71, 16, 19, 0, 0, 0, 63, 28, 37,
-  0, 67, 2, 0, 45, 0, 33, 25, 0, 0,
-  0, 52, 0, 0, 18, 0, 13, 17, 0, 3,
-  20, 20, 0, 7, 2, 12, 49, 14, 0, 32,
-  19, 44, 0, 21, 12, 0, 0, 24, 0, 0,
-  80, 1, 40, 3, 0, 0, 8, 26, 18, 45,
-  0, 0, 0, 0, 87, 25, 0, 0, 27, 11,
-  0, 26, 28, 6, 18, 90, 0, 29, 0, 0,
-  0, 0, 0, 71, 9, 2, 14, 0, 37, 0,
-  0, 24, 1, 42, 0, 27, 0, 6, 32, 0,
-  0, 6, 43, 0, 9, 0, 103, 0, 43, 0,
-  51, 0, 11, 29, 0, 45, 2, 0, 17, 0,
-  59, 0, 0, 24, 0, 0, 0, 0, 0, 40,
-  1, 11, 70, 0, 8, 10, 0, 0, 32, 0,
-  0, 0, 26, 22, 0, 7, 0, 0, 17, 26,
-  2, 0, 47, 0, 0, 21, 13, 9, 8, 0,
-  0, 0, 39, 2, 0, 18, 67, 54, 46, 0,
-  21, 0, 0, 41, 60, 20, 72, 13, 27, 31,
-  0, 123, 0, 13, 17, 0, 0, 28, 28, 13,
-  17, 0, 23, 19, 0, 3, 26, 0, 27, 0,
-  23, 0, 0, 39, 0, 0, 0, 3, 33, 0,
-  52, 9, 4, 75, 0, 0, 0, 0, 0, 100,
-  0, 0, 2, 0, 0, 11, 51, 34, 23, 0,
-  31, 0, 14, 0, 0, 0, 3, 31, 7, 0,
-  11, 24, 0, 20, 0, 8, 0, 0, 72, 0,
-  0, 35, 0, 0, 0, 0, 0, 45, 6, 0,
-  35, 11, 0, 11, 0, 0, 13, 0, 0, 0,
-  2, 13, 0, 0, 0, 0, 29, 44, 34, 0,
-  50, 0, 0, 11, 0, 7, 0, 0, 0, 0,
-  8, 60, 0, 0, 108, 136, 34, 5, 37, 0,
-  0, 24, 71, 27, 134, 39, 0, 0, 0, 158,
-  66, 0, 9, 0, 0, 10, 0, 0, 39, 0,
-  9, 0, 13, 5, 9, 0, 4, 0, 70, 0,
-  0, 80, 0, 0, 27, 0, 26, 0, 39, 45,
-  33, 130, 0, 0, 0, 0, 0, 84, 0, 0,
-  0, 0, 0, 24, 23, 13, 0, 0, 36, 0,
-  0, 0, 0, 0, 23, 31, 12, 0, 0, 15,
-  0, 0, 0, 50, 0, 0, 53, 14, 0, 2,
-  0, 0, 0, 0, 0, 48, 12, 0, 0, 0,
-  0, 19, 0, 0, 0, 3, 0, 0, 3, 11,
-  0, 0, 0, 9, 43, 82, 35, 0, 70, 0,
-  5, 16, 0, 7, 7, 0, 0, 0, 0, 63,
-  0, 0, 57, 160, 47, 9, 35, 0, 0, 29,
-  57, 0, 153, 4, 0, 0, 0, 121, 122, 0,
-  14, 27, 0, 33, 0, 0, 46, 0, 6, 0,
-  5, 13, 16, 0, 0, 10, 64, 0, 0, 128,
-  0, 0, 35, 0, 0, 0, 10, 76, 58, 96,
-  0, 0, 0, 0, 0, 62, 0, 0, 0, 3,
-  0, 35, 0, 0, 0, 0, 53, 0, 0, 0,
-  0, 0, 18, 28, 29, 0, 0, 129, 0, 59,
-  30, 0, 80, 0, 63, 0, 2, 62, 41, 13,
-  24, 8, 0, 36, 0, 50, 73, 0, 0, 34,
-  40, 69, 39, 5, 0, 13, 44, 0, 63, 0,
-  17, 0, 0, 0, 0, 0, 0, 30, 0, 55,
-  31, 26, 0, 15, 0, 0, 34, 0, 63, 66,
-  0, 6, 53, 0, 0, 76, 13, 0, 0, 0,
-  0, 0, 32, 81, 0, 0, 0, 20, 0, 0,
-  48, 49, 0, 0, 0, 0, 65, 72, 1, 0,
-  21, 0, 34, 0, 17, 106, 73, 0, 0, 66,
-  0, 33, 16, 0, 73, 22, 0, 27, 0, 0,
-  0, 0, 17, 70, 123, 31, 8, 0, 18, 0,
-  19, 0, 0, 0, 0, 0, 16, 21, 113, 10,
-  49, 16, 11, 0, 4, 112, 0, 54, 23, 0,
-  15, 0, 85, 7, 0, 53, 5, 3, 0, 0,
-  0, 18, 0, 13, 49, 0, 0, 31, 10, 11,
-  45, 17, 0, 0, 0, 9, 32, 0, 23, 0,
-  0, 18, 0, 0, 0, 0, 0, 18, 25, 27,
-  0, 0, 0, 0, 33, 14, 7, 64, 44, 38,
-  45, 0, 0, 10, 0, 11, 7, 12, 0, 7,
-  17, 45, 0, 29, 0, 13, 26, 0, 1, 55,
-  0, 8, 5, 0, 20, 44, 16, 23, 0, 0,
-  15, 29, 38, 55, 93, 0, 0, 17, 0, 0,
-  52, 0, 35, 52, 0, 80, 0, 0, 0, 0,
-  0, 84, 112, 0, 31, 0, 15, 3, 1, 0,
-  0, 0, 0, 0, 3, 0, 28, 0, 45, 32,
-  0, 0, 29, 57, 0, 24, 0, 27, 0, 0,
-  42, 0, 0, 31, 0, 13, 0, 0, 0, 38,
-  15, 0, 3, 20, 0, 0, 0, 0, 2, 0,
-  0, 0, 0, 33, 0, 0, 0, 22, 12, 36,
-  5, 0, 22, 0, 25, 16, 5, 0, 6, 0,
-  0, 0, 0, 74, 0, 26, 125, 100, 30, 22,
-  18, 0, 0, 43, 75, 37, 102, 36, 0, 20,
-  0, 109, 123, 3, 27, 0, 0, 17, 0, 0,
-  34, 0, 0, 1, 35, 33, 3, 0, 0, 8,
-  62, 0, 21, 30, 0, 0, 38, 0, 43, 0,
-  9, 59, 0, 117, 0, 0, 0, 0, 0, 80,
-  21, 0, 14, 0, 0, 24, 0, 0, 0, 0,
-  10, 0, 0, 0, 0, 0, 32, 35, 0, 0,
-  0, 21, 0, 0, 2, 0, 15, 0, 74, 29,
-  0, 18, 0, 12, 0, 34, 16, 63, 31, 0,
-  0, 0, 0, 43, 15, 0, 18, 55, 0, 0,
-  44, 0, 0, 15, 0, 0, 19, 53, 0, 0,
-  37, 0, 0, 0, 0, 6, 28, 0, 0, 0,
-  0, 19, 26, 0, 3, 71, 33, 50, 0, 0,
-  10, 18, 0, 54, 2, 0, 62, 0, 20, 53,
-  0, 0, 0, 10, 0, 34, 0, 0, 19, 0,
-  50, 13, 6, 0, 30, 11, 7, 22, 34, 0,
-  0, 109, 0, 6, 0, 0, 0, 0, 36, 46,
-  17, 32, 7, 0, 17, 0, 0, 18, 0, 40,
-  0, 25, 0, 9, 51, 0, 0, 9, 68, 0,
-  0, 9, 34, 0, 14, 0, 50, 0, 0, 44,
-  0, 0, 11, 0, 30, 0, 44, 53, 0, 11,
-  18, 12, 0, 82, 51, 71, 16, 19, 0, 0,
-  0, 63, 28, 37, 0, 67, 2, 0, 45, 0,
-  33, 25, 0, 0, 0, 52, 0, 0, 18, 0,
-  13, 17, 0, 3, 20, 20, 0, 7, 2, 12,
-  49, 14, 0, 32, 19, 44, 0, 21, 12, 0,
-  0, 24, 0, 0, 80, 1, 40, 3, 0, 0,
-  8, 26, 18, 45, 0, 0, 0, 0, 87, 25,
-  0, 0, 27, 11, 0, 26, 28, 6, 18, 90,
-  0, 29, 0, 0, 0, 0, 0, 71, 9, 2,
-  14, 0, 37, 0, 0, 24, 1, 42, 0, 27,
-  0, 6, 32, 0, 0, 6, 43, 0, 9, 0,
-  103, 0, 43, 0, 51, 0, 0, 102, 14, 0,
-  4, 0, 39, 0, 27, 51, 8, 13, 23, 3,
-  26, 91, 67, 61, 21, 56, 0, 0, 0, 56,
-  53, 69, 6, 74, 0, 0, 14, 0, 81, 1,
-  0, 0, 0, 25, 0, 38, 0, 16, 42, 22,
-  1, 7, 22, 19, 0, 49, 2, 1, 68, 52,
-  0, 0, 0, 9, 0, 50, 0, 0, 0, 0,
-  0, 0, 91, 11, 34, 0, 0, 0, 15, 26,
-  42, 23, 0, 6, 0, 4, 107, 11, 0, 0,
-  11, 8, 10, 15, 30, 12, 42, 45, 0, 41,
-  0, 10, 0, 0, 0, 81, 0, 0, 14, 0,
-  46, 0, 23, 15, 32, 37, 0, 0, 0, 0,
-  0, 0, 0, 0, 12, 0, 30, 11, 149, 0,
-  76, 0, 46, 0, 11, 24, 0, 20, 0, 8,
-  0, 0, 72, 0, 0, 35, 0, 0, 0, 0,
-  0, 45, 6, 0, 35, 11, 0, 11, 0, 0,
-  13, 0, 0, 0, 2, 13, 0, 0, 0, 0,
-  29, 44, 34, 0, 50, 0, 0, 11, 0, 7,
-  0, 0, 0, 0, 8, 60, 0, 0, 108, 136,
-  34, 5, 37, 0, 0, 24, 71, 27, 134, 39,
-  0, 0, 0, 158, 66, 0, 9, 0, 0, 10,
-  0, 0, 39, 0, 9, 0, 13, 5, 9, 0,
-  4, 0, 70, 0, 0, 80, 0, 0, 27, 0,
-  26, 0, 39, 45, 33, 130, 0, 0, 0, 0,
-  0, 84, 0, 0, 0, 0, 0, 24, 23, 13,
-  0, 0, 36, 0, 0, 0, 0, 0, 23, 31,
-  12, 0, 0, 15, 0, 0, 0, 50, 0, 0,
-  53, 14, 0, 2, 0, 0, 0, 0, 0, 48,
-  12, 0, 0, 0, 0, 19, 0, 0, 0, 3,
-  0, 0, 3, 11, 0, 0, 0, 9, 43, 82,
-  35, 0, 70, 0, 5, 16, 0, 7, 7, 0,
-  0, 0, 0, 63, 0, 0, 57, 160, 47, 9,
-  35, 0, 0, 29, 57, 0, 153, 4, 0, 0,
-  0, 121, 122, 0, 14, 27, 0, 33, 0, 0,
-  46, 0, 6, 0, 5, 13, 16, 0, 0, 10,
-  64, 0, 0, 128, 0, 0, 35, 0, 0, 0,
-  10, 76, 58, 96, 0, 0, 0, 0, 0, 62,
-  0, 0, 0, 3, 0, 35, 0, 0, 0, 0,
-  53, 0, 0, 0, 0, 0, 18, 28, 29, 0,
-  0, 39, 0, 0, 0, 29, 0, 0, 78, 47,
-  0, 0, 30, 0, 0, 88, 39, 61, 6, 17,
-  0, 0, 0, 41, 0, 0, 7, 53, 6, 0,
-  17, 0, 36, 0, 0, 0, 35, 96, 0, 0,
-  48, 0, 9, 30, 0, 28, 42, 19, 0, 0,
-  0, 32, 2, 0, 4, 101, 46, 8, 0, 0,
-  0, 0, 0, 0, 66, 0, 6, 4, 24, 53,
-  52, 0, 17, 37, 0, 49, 0, 0, 5, 0,
-  39, 0, 0, 0, 0, 1, 0, 30, 51, 0,
-  0, 131, 0, 0, 11, 0, 0, 0, 0, 86,
-  87, 31, 0, 0, 0, 0, 0, 48, 0, 13,
-  0, 11, 0, 8, 2, 0, 0, 2, 51, 0,
-  25, 0, 41, 0, 28, 12, 43, 0, 4, 112,
-  0, 54, 23, 0, 15, 0, 85, 7, 0, 53,
-  5, 3, 0, 0, 0, 18, 0, 13, 49, 0,
-  0, 31, 10, 11, 45, 17, 0, 0, 0, 9,
-  32, 0, 23, 0, 0, 18, 0, 0, 0, 0,
-  0, 18, 25, 27, 0, 0, 0, 0, 33, 14,
-  7, 64, 44, 38, 45, 0, 0, 10, 0, 11,
-  7, 12, 0, 7, 17, 45, 0, 29, 0, 13,
-  26, 0, 1, 55, 0, 8, 5, 0, 20, 44,
-  16, 23, 0, 0, 15, 29, 38, 55, 93, 0,
-  0, 17, 0, 0, 52, 0, 35, 52, 0, 80,
-  0, 0, 0, 0, 0, 84, 112, 0, 31, 0,
-  15, 3, 1, 0, 0, 0, 0, 0, 3, 0,
-  28, 0, 45, 32, 0, 0, 29, 57, 0, 24,
-  0, 27, 0, 0, 42, 0, 0, 31, 0, 13,
-  0, 0, 0, 38, 15, 0, 3, 20, 0, 0,
-  0, 0, 2, 0, 0, 0, 0, 33, 0, 0,
-  0, 22, 12, 36, 5, 0, 22, 0, 25, 16,
-  5, 0, 6, 0, 0, 0, 0, 74, 0, 26,
-  125, 100, 30, 22, 18, 0, 0, 43, 75, 37,
-  102, 36, 0, 20, 0, 109, 123, 3, 27, 0,
-  0, 17, 0, 0, 34, 0, 0, 1, 35, 33,
-  3, 0, 0, 8, 62, 0, 21, 30, 0, 0,
-  38, 0, 43, 0, 9, 59, 0, 117, 0, 0,
-  0, 0, 0, 80, 21, 0, 14, 0, 0, 24,
-  0, 0, 0, 0, 10, 0, 0, 0, 0, 0,
-  32, 35, 0, 0, 10, 25, 0, 0, 0, 85,
-  0, 0, 22, 0, 0, 0, 0, 0, 0, 0,
-  0, 39, 3, 8, 0, 40, 0, 0, 0, 0,
-  8, 3, 0, 0, 0, 38, 0, 0, 0, 43,
-  47, 68, 23, 0, 46, 0, 22, 15, 0, 13,
-  59, 13, 0, 0, 0, 55, 0, 0, 112, 118,
-  34, 26, 48, 0, 0, 57, 67, 0, 179, 5,
-  0, 32, 0, 139, 175, 0, 10, 15, 0, 0,
-  0, 0, 42, 0, 0, 0, 28, 19, 31, 0,
-  0, 11, 42, 0, 0, 116, 13, 0, 34, 0,
-  0, 0, 6, 54, 43, 142, 0, 0, 0, 0,
-  0, 58, 0, 0, 0, 29, 0, 30, 0, 10,
-  0, 0, 53, 0, 0, 0, 0, 0, 1, 29,
-  1, 6, 0, 44, 0, 0, 11, 0, 30, 0,
-  44, 53, 0, 11, 18, 12, 0, 82, 51, 71,
-  16, 19, 0, 0, 0, 63, 28, 37, 0, 67,
-  2, 0, 45, 0, 33, 25, 0, 0, 0, 52,
-  0, 0, 18, 0, 13, 17, 0, 3, 20, 20,
-  0, 7, 2, 12, 49, 14, 0, 32, 19, 44,
-  0, 21, 12, 0, 0, 24, 0, 0, 80, 1,
-  40, 3, 0, 0, 8, 26, 18, 45, 0, 0,
-  0, 0, 87, 25, 0, 0, 27, 11, 0, 26,
-  28, 6, 18, 90, 0, 29, 0, 0, 0, 0,
-  0, 71, 9, 2, 14, 0, 37, 0, 0, 24,
-  1, 42, 0, 27, 0, 6, 32, 0, 0, 6,
-  43, 0, 9, 0, 103, 0, 43, 0, 51, 0,
-  0, 102, 14, 0, 4, 0, 39, 0, 27, 51,
-  8, 13, 23, 3, 26, 91, 67, 61, 21, 56,
-  0, 0, 0, 56, 53, 69, 6, 74, 0, 0,
-  14, 0, 81, 1, 0, 0, 0, 25, 0, 38,
-  0, 16, 42, 22, 1, 7, 22, 19, 0, 49,
-  2, 1, 68, 52, 0, 0, 0, 9, 0, 50,
-  0, 0, 0, 0, 0, 0, 91, 11, 34, 0,
-  0, 0, 15, 26, 42, 23, 0, 6, 0, 4,
-  107, 11, 0, 0, 11, 8, 10, 15, 30, 12,
-  42, 45, 0, 41, 0, 10, 0, 0, 0, 81,
-  0, 0, 14, 0, 46, 0, 23, 15, 32, 37,
-  0, 0, 0, 0, 0, 0, 0, 0, 12, 0,
-  30, 11, 149, 0, 76, 0, 46, 0, 0, 131,
-  52, 5, 17, 0, 45, 0, 11, 44, 5, 23,
-  60, 0, 17, 55, 55, 49, 15, 72, 0, 0,
-  12, 32, 54, 53, 11, 54, 0, 20, 0, 0,
-  76, 0, 17, 0, 0, 0, 0, 41, 0, 25,
-  68, 41, 28, 22, 40, 0, 0, 52, 0, 3,
-  85, 24, 0, 0, 0, 0, 0, 44, 4, 0,
-  0, 5, 0, 0, 29, 13, 13, 0, 0, 0,
-  8, 16, 74, 5, 15, 32, 0, 0, 97, 0,
-  0, 0, 14, 0, 30, 16, 22, 9, 0, 0,
-  0, 20, 0, 26, 0, 0, 0, 38, 5, 16,
-  9, 0, 39, 0, 48, 8, 25, 53, 0, 0,
-  0, 5, 0, 0, 0, 24, 33, 0, 34, 5,
-  77, 0, 62, 0, 29, 0, 0, 15, 0, 0,
-  0, 50, 0, 0, 53, 14, 0, 2, 0, 0,
-  0, 0, 0, 48, 12, 0, 0, 0, 0, 19,
-  0, 0, 0, 3, 0, 0, 3, 11, 0, 0,
-  0, 9, 43, 82, 35, 0, 70, 0, 5, 16,
-  0, 7, 7, 0, 0, 0, 0, 63, 0, 0,
-  57, 160, 47, 9, 35, 0, 0, 29, 57, 0,
-  153, 4, 0, 0, 0, 121, 122, 0, 14, 27,
-  0, 33, 0, 0, 46, 0, 6, 0, 5, 13,
-  16, 0, 0, 10, 64, 0, 0, 128, 0, 0,
-  35, 0, 0, 0, 10, 76, 58, 96, 0, 0,
-  0, 0, 0, 62, 0, 0, 0, 3, 0, 35,
-  0, 0, 0, 0, 53, 0, 0, 0, 0, 0,
-  18, 28, 29, 0, 0, 39, 0, 0, 0, 29,
-  0, 0, 78, 47, 0, 0, 30, 0, 0, 88,
-  39, 61, 6, 17, 0, 0, 0, 41, 0, 0,
-  7, 53, 6, 0, 17, 0, 36, 0, 0, 0,
-  35, 96, 0, 0, 48, 0, 9, 30, 0, 28,
-  42, 19, 0, 0, 0, 32, 2, 0, 4, 101,
-  46, 8, 0, 0, 0, 0, 0, 0, 66, 0,
-  6, 4, 24, 53, 52, 0, 17, 37, 0, 49,
-  0, 0, 5, 0, 39, 0, 0, 0, 0, 1,
-  0, 30, 51, 0, 0, 131, 0, 0, 11, 0,
-  0, 0, 0, 86, 87, 31, 0, 0, 0, 0,
-  0, 48, 0, 13, 0, 11, 0, 8, 2, 0,
-  0, 2, 51, 0, 25, 0, 41, 0, 28, 12,
-  43, 0, 0, 93, 41, 0, 7, 0, 52, 3,
-  86, 40, 12, 0, 76, 3, 0, 125, 70, 39,
-  2, 33, 0, 0, 0, 54, 36, 13, 16, 61,
-  3, 0, 21, 0, 90, 1, 0, 0, 0, 58,
-  0, 29, 9, 0, 26, 52, 0, 59, 72, 36,
-  0, 44, 0, 0, 84, 12, 0, 0, 22, 0,
-  0, 42, 0, 0, 0, 0, 0, 0, 47, 0,
-  62, 0, 0, 0, 2, 50, 38, 28, 0, 0,
-  0, 0, 77, 11, 8, 0, 0, 21, 0, 22,
-  43, 0, 0, 57, 0, 32, 0, 0, 0, 0,
-  0, 79, 66, 0, 0, 0, 15, 0, 10, 29,
-  0, 69, 0, 1, 0, 0, 0, 0, 0, 36,
-  65, 0, 62, 0, 139, 0, 57, 16, 25, 0,
-  29, 57, 0, 24, 0, 27, 0, 0, 42, 0,
-  0, 31, 0, 13, 0, 0, 0, 38, 15, 0,
-  3, 20, 0, 0, 0, 0, 2, 0, 0, 0,
-  0, 33, 0, 0, 0, 22, 12, 36, 5, 0,
-  22, 0, 25, 16, 5, 0, 6, 0, 0, 0,
-  0, 74, 0, 26, 125, 100, 30, 22, 18, 0,
-  0, 43, 75, 37, 102, 36, 0, 20, 0, 109,
-  123, 3, 27, 0, 0, 17, 0, 0, 34, 0,
-  0, 1, 35, 33, 3, 0, 0, 8, 62, 0,
-  21, 30, 0, 0, 38, 0, 43, 0, 9, 59,
-  0, 117, 0, 0, 0, 0, 0, 80, 21, 0,
-  14, 0, 0, 24, 0, 0, 0, 0, 10, 0,
-  0, 0, 0, 0, 32, 35, 0, 0, 10, 25,
-  0, 0, 0, 85, 0, 0, 22, 0, 0, 0,
-  0, 0, 0, 0, 0, 39, 3, 8, 0, 40,
-  0, 0, 0, 0, 8, 3, 0, 0, 0, 38,
-  0, 0, 0, 43, 47, 68, 23, 0, 46, 0,
-  22, 15, 0, 13, 59, 13, 0, 0, 0, 55,
-  0, 0, 112, 118, 34, 26, 48, 0, 0, 57,
-  67, 0, 179, 5, 0, 32, 0, 139, 175, 0,
-  10, 15, 0, 0, 0, 0, 42, 0, 0, 0,
-  28, 19, 31, 0, 0, 11, 42, 0, 0, 116,
-  13, 0, 34, 0, 0, 0, 6, 54, 43, 142,
-  0, 0, 0, 0, 0, 58, 0, 0, 0, 29,
-  0, 30, 0, 10, 0, 0, 53, 0, 0, 0,
-  0, 0, 1, 29, 1, 6, 0, 37, 0, 0,
-  0, 81, 0, 0, 83, 32, 0, 0, 0, 9,
-  0, 42, 6, 26, 0, 10, 0, 0, 0, 25,
-  0, 0, 22, 40, 7, 0, 0, 0, 67, 0,
-  0, 20, 33, 86, 0, 0, 32, 0, 0, 10,
-  0, 67, 54, 81, 0, 26, 0, 6, 0, 0,
-  25, 36, 58, 0, 32, 0, 0, 65, 0, 0,
-  102, 0, 0, 34, 25, 57, 85, 0, 33, 59,
-  0, 79, 0, 0, 3, 0, 3, 0, 2, 0,
-  0, 0, 0, 49, 15, 0, 0, 173, 0, 0,
-  0, 0, 0, 0, 0, 64, 113, 110, 0, 0,
-  0, 0, 0, 29, 0, 22, 0, 30, 0, 19,
-  0, 0, 0, 29, 61, 0, 40, 0, 0, 0,
-  0, 15, 1, 35, 0, 102, 14, 0, 4, 0,
-  39, 0, 27, 51, 8, 13, 23, 3, 26, 91,
-  67, 61, 21, 56, 0, 0, 0, 56, 53, 69,
-  6, 74, 0, 0, 14, 0, 81, 1, 0, 0,
-  0, 25, 0, 38, 0, 16, 42, 22, 1, 7,
-  22, 19, 0, 49, 2, 1, 68, 52, 0, 0,
-  0, 9, 0, 50, 0, 0, 0, 0, 0, 0,
-  91, 11, 34, 0, 0, 0, 15, 26, 42, 23,
-  0, 6, 0, 4, 107, 11, 0, 0, 11, 8,
-  10, 15, 30, 12, 42, 45, 0, 41, 0, 10,
-  0, 0, 0, 81, 0, 0, 14, 0, 46, 0,
-  23, 15, 32, 37, 0, 0, 0, 0, 0, 0,
-  0, 0, 12, 0, 30, 11, 149, 0, 76, 0,
-  46, 0, 0, 131, 52, 5, 17, 0, 45, 0,
-  11, 44, 5, 23, 60, 0, 17, 55, 55, 49,
-  15, 72, 0, 0, 12, 32, 54, 53, 11, 54,
-  0, 20, 0, 0, 76, 0, 17, 0, 0, 0,
-  0, 41, 0, 25, 68, 41, 28, 22, 40, 0,
-  0, 52, 0, 3, 85, 24, 0, 0, 0, 0,
-  0, 44, 4, 0, 0, 5, 0, 0, 29, 13,
-  13, 0, 0, 0, 8, 16, 74, 5, 15, 32,
-  0, 0, 97, 0, 0, 0, 14, 0, 30, 16,
-  22, 9, 0, 0, 0, 20, 0, 26, 0, 0,
-  0, 38, 5, 16, 9, 0, 39, 0, 48, 8,
-  25, 53, 0, 0, 0, 5, 0, 0, 0, 24,
-  33, 0, 34, 5, 77, 0, 62, 0, 29, 0,
-  0, 75, 0, 0, 5, 14, 48, 1, 0, 0,
-  0, 56, 51, 0, 0, 4, 32, 10, 13, 41,
-  0, 10, 71, 13, 29, 0, 10, 14, 0, 17,
-  0, 0, 42, 0, 5, 27, 0, 0, 9, 20,
-  0, 26, 0, 66, 11, 74, 35, 26, 0, 2,
-  0, 16, 68, 0, 0, 0, 30, 0, 1, 5,
-  28, 45, 0, 49, 0, 0, 0, 37, 29, 0,
-  51, 0, 22, 9, 83, 12, 47, 23, 0, 0,
-  69, 0, 4, 0, 38, 0, 23, 2, 0, 0,
-  0, 0, 0, 6, 0, 38, 0, 0, 22, 49,
-  15, 29, 19, 13, 22, 0, 31, 11, 0, 28,
-  0, 0, 0, 0, 0, 0, 0, 19, 71, 6,
-  22, 4, 0, 0, 22, 0, 10, 0, 0, 39,
-  0, 0, 0, 29, 0, 0, 78, 47, 0, 0,
-  30, 0, 0, 88, 39, 61, 6, 17, 0, 0,
-  0, 41, 0, 0, 7, 53, 6, 0, 17, 0,
-  36, 0, 0, 0, 35, 96, 0, 0, 48, 0,
-  9, 30, 0, 28, 42, 19, 0, 0, 0, 32,
-  2, 0, 4, 101, 46, 8, 0, 0, 0, 0,
-  0, 0, 66, 0, 6, 4, 24, 53, 52, 0,
-  17, 37, 0, 49, 0, 0, 5, 0, 39, 0,
-  0, 0, 0, 1, 0, 30, 51, 0, 0, 131,
-  0, 0, 11, 0, 0, 0, 0, 86, 87, 31,
-  0, 0, 0, 0, 0, 48, 0, 13, 0, 11,
-  0, 8, 2, 0, 0, 2, 51, 0, 25, 0,
-  41, 0, 28, 12, 43, 0, 0, 93, 41, 0,
-  7, 0, 52, 3, 86, 40, 12, 0, 76, 3,
-  0, 125, 70, 39, 2, 33, 0, 0, 0, 54,
-  36, 13, 16, 61, 3, 0, 21, 0, 90, 1,
-  0, 0, 0, 58, 0, 29, 9, 0, 26, 52,
-  0, 59, 72, 36, 0, 44, 0, 0, 84, 12,
-  0, 0, 22, 0, 0, 42, 0, 0, 0, 0,
-  0, 0, 47, 0, 62, 0, 0, 0, 2, 50,
-  38, 28, 0, 0, 0, 0, 77, 11, 8, 0,
-  0, 21, 0, 22, 43, 0, 0, 57, 0, 32,
-  0, 0, 0, 0, 0, 79, 66, 0, 0, 0,
-  15, 0, 10, 29, 0, 69, 0, 1, 0, 0,
-  0, 0, 0, 36, 65, 0, 62, 0, 139, 0,
-  57, 16, 25, 0, 0, 58, 49, 0, 14, 0,
-  50, 16, 63, 8, 3, 26, 61, 1, 7, 53,
-  52, 0, 0, 15, 0, 27, 43, 19, 23, 0,
-  0, 13, 0, 0, 0, 0, 41, 0, 0, 6,
-  0, 16, 0, 79, 0, 24, 0, 55, 1, 70,
-  61, 46, 0, 21, 0, 20, 72, 1, 0, 0,
-  29, 0, 0, 0, 15, 36, 0, 43, 0, 14,
-  0, 0, 79, 0, 0, 0, 7, 27, 66, 15,
-  34, 28, 0, 0, 79, 0, 29, 0, 25, 0,
-  16, 0, 0, 0, 0, 0, 0, 17, 0, 26,
-  0, 0, 5, 71, 31, 0, 0, 0, 26, 0,
-  28, 0, 0, 38, 0, 0, 0, 2, 0, 0,
-  2, 14, 69, 0, 27, 0, 63, 0, 43, 7,
-  17, 0, 10, 25, 0, 0, 0, 85, 0, 0,
-  22, 0, 0, 0, 0, 0, 0, 0, 0, 39,
-  3, 8, 0, 40, 0, 0, 0, 0, 8, 3,
-  0, 0, 0, 38, 0, 0, 0, 43, 47, 68,
-  23, 0, 46, 0, 22, 15, 0, 13, 59, 13,
-  0, 0, 0, 55, 0, 0, 112, 118, 34, 26,
-  48, 0, 0, 57, 67, 0, 179, 5, 0, 32,
-  0, 139, 175, 0, 10, 15, 0, 0, 0, 0,
-  42, 0, 0, 0, 28, 19, 31, 0, 0, 11,
-  42, 0, 0, 116, 13, 0, 34, 0, 0, 0,
-  6, 54, 43, 142, 0, 0, 0, 0, 0, 58,
-  0, 0, 0, 29, 0, 30, 0, 10, 0, 0,
-  53, 0, 0, 0, 0, 0, 1, 29, 1, 6,
-  0, 37, 0, 0, 0, 81, 0, 0, 83, 32,
-  0, 0, 0, 9, 0, 42, 6, 26, 0, 10,
-  0, 0, 0, 25, 0, 0, 22, 40, 7, 0,
-  0, 0, 67, 0, 0, 20, 33, 86, 0, 0,
-  32, 0, 0, 10, 0, 67, 54, 81, 0, 26,
-  0, 6, 0, 0, 25, 36, 58, 0, 32, 0,
-  0, 65, 0, 0, 102, 0, 0, 34, 25, 57,
-  85, 0, 33, 59, 0, 79, 0, 0, 3, 0,
-  3, 0, 2, 0, 0, 0, 0, 49, 15, 0,
-  0, 173, 0, 0, 0, 0, 0, 0, 0, 64,
-  113, 110, 0, 0, 0, 0, 0, 29, 0, 22,
-  0, 30, 0, 19, 0, 0, 0, 29, 61, 0,
-  40, 0, 0, 0, 0, 15, 1, 35, 0, 34,
-  21, 0, 0, 0, 48, 33, 91, 15, 14, 16,
-  57, 1, 0, 81, 49, 0, 0, 0, 6, 20,
-  26, 30, 1, 0, 0, 23, 0, 0, 0, 0,
-  60, 0, 3, 0, 0, 56, 0, 42, 4, 5,
-  0, 43, 0, 101, 57, 64, 0, 36, 0, 14,
-  67, 0, 0, 0, 60, 0, 18, 0, 6, 36,
-  0, 46, 0, 0, 0, 0, 80, 0, 0, 0,
-  27, 50, 26, 48, 16, 11, 0, 0, 59, 0,
-  25, 0, 0, 9, 9, 3, 5, 0, 0, 63,
-  0, 14, 0, 0, 0, 0, 4, 79, 88, 0,
-  0, 0, 17, 0, 30, 2, 0, 51, 0, 7,
-  0, 20, 0, 0, 0, 31, 77, 0, 50, 0,
-  85, 0, 42, 0, 14, 0, 0, 131, 52, 5,
-  17, 0, 45, 0, 11, 44, 5, 23, 60, 0,
-  17, 55, 55, 49, 15, 72, 0, 0, 12, 32,
-  54, 53, 11, 54, 0, 20, 0, 0, 76, 0,
-  17, 0, 0, 0, 0, 41, 0, 25, 68, 41,
-  28, 22, 40, 0, 0, 52, 0, 3, 85, 24,
-  0, 0, 0, 0, 0, 44, 4, 0, 0, 5,
-  0, 0, 29, 13, 13, 0, 0, 0, 8, 16,
-  74, 5, 15, 32, 0, 0, 97, 0, 0, 0,
-  14, 0, 30, 16, 22, 9, 0, 0, 0, 20,
-  0, 26, 0, 0, 0, 38, 5, 16, 9, 0,
-  39, 0, 48, 8, 25, 53, 0, 0, 0, 5,
-  0, 0, 0, 24, 33, 0, 34, 5, 77, 0,
-  62, 0, 29, 0, 0, 75, 0, 0, 5, 14,
-  48, 1, 0, 0, 0, 56, 51, 0, 0, 4,
-  32, 10, 13, 41, 0, 10, 71, 13, 29, 0,
-  10, 14, 0, 17, 0, 0, 42, 0, 5, 27,
-  0, 0, 9, 20, 0, 26, 0, 66, 11, 74,
-  35, 26, 0, 2, 0, 16, 68, 0, 0, 0,
-  30, 0, 1, 5, 28, 45, 0, 49, 0, 0,
-  0, 37, 29, 0, 51, 0, 22, 9, 83, 12,
-  47, 23, 0, 0, 69, 0, 4, 0, 38, 0,
-  23, 2, 0, 0, 0, 0, 0, 6, 0, 38,
-  0, 0, 22, 49, 15, 29, 19, 13, 22, 0,
-  31, 11, 0, 28, 0, 0, 0, 0, 0, 0,
-  0, 19, 71, 6, 22, 4, 0, 0, 22, 0,
-  10, 0, 7, 18, 0, 16, 0, 21, 57, 17,
-  0, 0, 0, 41, 57, 2, 0, 6, 60, 44,
-  5, 5, 45, 0, 15, 0, 37, 0, 27, 0,
-  0, 35, 0, 0, 85, 0, 0, 0, 0, 5,
-  0, 0, 0, 23, 0, 64, 4, 113, 25, 79,
-  0, 0, 0, 41, 66, 0, 0, 22, 11, 0,
-  0, 0, 15, 0, 0, 2, 0, 0, 0, 36,
-  38, 0, 60, 0, 2, 0, 50, 0, 47, 0,
-  0, 0, 62, 0, 47, 0, 7, 0, 20, 0,
-  0, 8, 0, 4, 0, 8, 0, 7, 0, 0,
-  51, 44, 26, 26, 0, 37, 18, 0, 29, 6,
-  9, 13, 0, 18, 0, 17, 0, 0, 6, 0,
-  36, 0, 37, 0, 37, 0, 0, 0, 38, 0,
-  0, 93, 41, 0, 7, 0, 52, 3, 86, 40,
-  12, 0, 76, 3, 0, 125, 70, 39, 2, 33,
-  0, 0, 0, 54, 36, 13, 16, 61, 3, 0,
-  21, 0, 90, 1, 0, 0, 0, 58, 0, 29,
-  9, 0, 26, 52, 0, 59, 72, 36, 0, 44,
-  0, 0, 84, 12, 0, 0, 22, 0, 0, 42,
-  0, 0, 0, 0, 0, 0, 47, 0, 62, 0,
-  0, 0, 2, 50, 38, 28, 0, 0, 0, 0,
-  77, 11, 8, 0, 0, 21, 0, 22, 43, 0,
-  0, 57, 0, 32, 0, 0, 0, 0, 0, 79,
-  66, 0, 0, 0, 15, 0, 10, 29, 0, 69,
-  0, 1, 0, 0, 0, 0, 0, 36, 65, 0,
-  62, 0, 139, 0, 57, 16, 25, 0, 0, 58,
-  49, 0, 14, 0, 50, 16, 63, 8, 3, 26,
-  61, 1, 7, 53, 52, 0, 0, 15, 0, 27,
-  43, 19, 23, 0, 0, 13, 0, 0, 0, 0,
-  41, 0, 0, 6, 0, 16, 0, 79, 0, 24,
-  0, 55, 1, 70, 61, 46, 0, 21, 0, 20,
-  72, 1, 0, 0, 29, 0, 0, 0, 15, 36,
-  0, 43, 0, 14, 0, 0, 79, 0, 0, 0,
-  7, 27, 66, 15, 34, 28, 0, 0, 79, 0,
-  29, 0, 25, 0, 16, 0, 0, 0, 0, 0,
-  0, 17, 0, 26, 0, 0, 5, 71, 31, 0,
-  0, 0, 26, 0, 28, 0, 0, 38, 0, 0,
-  0, 2, 0, 0, 2, 14, 69, 0, 27, 0,
-  63, 0, 43, 7, 17, 0, 0, 6, 0, 0,
-  0, 1, 30, 12, 26, 0, 0, 25, 43, 0,
-  8, 23, 56, 23, 0, 0, 32, 29, 18, 2,
-  25, 0, 0, 0, 0, 0, 0, 0, 36, 17,
-  0, 0, 0, 0, 0, 34, 0, 11, 0, 58,
-  21, 87, 29, 59, 0, 1, 0, 52, 63, 0,
-  3, 0, 12, 0, 0, 0, 25, 4, 0, 38,
-  0, 10, 4, 0, 42, 0, 34, 0, 0, 17,
-  34, 0, 45, 41, 0, 0, 77, 0, 55, 0,
-  5, 0, 14, 0, 0, 0, 0, 31, 0, 0,
-  0, 22, 0, 0, 32, 57, 30, 0, 0, 9,
-  8, 0, 15, 0, 0, 13, 0, 14, 0, 2,
-  0, 0, 29, 0, 33, 0, 14, 0, 33, 0,
-  13, 6, 20, 0, 0, 37, 0, 0, 0, 81,
-  0, 0, 83, 32, 0, 0, 0, 9, 0, 42,
-  6, 26, 0, 10, 0, 0, 0, 25, 0, 0,
-  22, 40, 7, 0, 0, 0, 67, 0, 0, 20,
-  33, 86, 0, 0, 32, 0, 0, 10, 0, 67,
-  54, 81, 0, 26, 0, 6, 0, 0, 25, 36,
-  58, 0, 32, 0, 0, 65, 0, 0, 102, 0,
-  0, 34, 25, 57, 85, 0, 33, 59, 0, 79,
-  0, 0, 3, 0, 3, 0, 2, 0, 0, 0,
-  0, 49, 15, 0, 0, 173, 0, 0, 0, 0,
-  0, 0, 0, 64, 113, 110, 0, 0, 0, 0,
-  0, 29, 0, 22, 0, 30, 0, 19, 0, 0,
-  0, 29, 61, 0, 40, 0, 0, 0, 0, 15,
-  1, 35, 0, 34, 21, 0, 0, 0, 48, 33,
-  91, 15, 14, 16, 57, 1, 0, 81, 49, 0,
-  0, 0, 6, 20, 26, 30, 1, 0, 0, 23,
-  0, 0, 0, 0, 60, 0, 3, 0, 0, 56,
-  0, 42, 4, 5, 0, 43, 0, 101, 57, 64,
-  0, 36, 0, 14, 67, 0, 0, 0, 60, 0,
-  18, 0, 6, 36, 0, 46, 0, 0, 0, 0,
-  80, 0, 0, 0, 27, 50, 26, 48, 16, 11,
-  0, 0, 59, 0, 25, 0, 0, 9, 9, 3,
-  5, 0, 0, 63, 0, 14, 0, 0, 0, 0,
-  4, 79, 88, 0, 0, 0, 17, 0, 30, 2,
-  0, 51, 0, 7, 0, 20, 0, 0, 0, 31,
-  77, 0, 50, 0, 85, 0, 42, 0, 14, 0,
-  0, 27, 0, 6, 0, 0, 33, 17, 40, 0,
-  12, 29, 62, 0, 14, 33, 65, 28, 0, 0,
-  26, 32, 26, 12, 42, 0, 0, 27, 0, 0,
-  0, 0, 69, 0, 0, 0, 0, 14, 0, 40,
-  0, 14, 0, 40, 23, 88, 0, 29, 0, 18,
-  0, 24, 66, 1, 4, 0, 0, 0, 0, 0,
-  30, 14, 0, 50, 0, 7, 42, 0, 37, 0,
-  0, 0, 0, 48, 16, 0, 58, 78, 0, 0,
-  60, 0, 43, 4, 0, 14, 12, 0, 0, 2,
-  0, 24, 0, 6, 0, 25, 4, 0, 5, 84,
-  38, 0, 0, 3, 48, 0, 12, 5, 0, 1,
-  0, 12, 0, 2, 0, 0, 15, 0, 12, 0,
-  16, 0, 60, 0, 26, 0, 25, 0, 0, 75,
-  0, 0, 5, 14, 48, 1, 0, 0, 0, 56,
-  51, 0, 0, 4, 32, 10, 13, 41, 0, 10,
-  71, 13, 29, 0, 10, 14, 0, 17, 0, 0,
-  42, 0, 5, 27, 0, 0, 9, 20, 0, 26,
-  0, 66, 11, 74, 35, 26, 0, 2, 0, 16,
-  68, 0, 0, 0, 30, 0, 1, 5, 28, 45,
-  0, 49, 0, 0, 0, 37, 29, 0, 51, 0,
-  22, 9, 83, 12, 47, 23, 0, 0, 69, 0,
-  4, 0, 38, 0, 23, 2, 0, 0, 0, 0,
-  0, 6, 0, 38, 0, 0, 22, 49, 15, 29,
-  19, 13, 22, 0, 31, 11, 0, 28, 0, 0,
-  0, 0, 0, 0, 0, 19, 71, 6, 22, 4,
-  0, 0, 22, 0, 10, 0, 7, 18, 0, 16,
-  0, 21, 57, 17, 0, 0, 0, 41, 57, 2,
-  0, 6, 60, 44, 5, 5, 45, 0, 15, 0,
-  37, 0, 27, 0, 0, 35, 0, 0, 85, 0,
-  0, 0, 0, 5, 0, 0, 0, 23, 0, 64,
-  4, 113, 25, 79, 0, 0, 0, 41, 66, 0,
-  0, 22, 11, 0, 0, 0, 15, 0, 0, 2,
-  0, 0, 0, 36, 38, 0, 60, 0, 2, 0,
-  50, 0, 47, 0, 0, 0, 62, 0, 47, 0,
-  7, 0, 20, 0, 0, 8, 0, 4, 0, 8,
-  0, 7, 0, 0, 51, 44, 26, 26, 0, 37,
-  18, 0, 29, 6, 9, 13, 0, 18, 0, 17,
-  0, 0, 6, 0, 36, 0, 37, 0, 37, 0,
-  0, 0, 38, 0, 0, 12, 0, 42, 6, 15,
-  37, 28, 4, 4, 6, 14, 22, 0, 5, 59,
-  66, 39, 0, 24, 0, 0, 0, 20, 47, 15,
-  29, 33, 0, 35, 0, 0, 91, 34, 6, 0,
-  0, 11, 0, 10, 0, 18, 0, 22, 0, 58,
-  46, 78, 0, 43, 0, 62, 86, 46, 0, 56,
-  0, 0, 0, 20, 4, 0, 0, 0, 0, 0,
-  39, 0, 35, 6, 23, 0, 0, 0, 28, 23,
-  8, 0, 0, 0, 113, 0, 11, 9, 0, 0,
-  7, 22, 0, 0, 22, 29, 0, 8, 36, 0,
-  36, 0, 26, 59, 19, 7, 14, 19, 16, 0,
-  26, 17, 35, 32, 0, 9, 19, 42, 0, 0,
-  5, 0, 0, 0, 14, 11, 125, 0, 35, 0,
-  0, 0, 0, 58, 49, 0, 14, 0, 50, 16,
-  63, 8, 3, 26, 61, 1, 7, 53, 52, 0,
-  0, 15, 0, 27, 43, 19, 23, 0, 0, 13,
-  0, 0, 0, 0, 41, 0, 0, 6, 0, 16,
-  0, 79, 0, 24, 0, 55, 1, 70, 61, 46,
-  0, 21, 0, 20, 72, 1, 0, 0, 29, 0,
-  0, 0, 15, 36, 0, 43, 0, 14, 0, 0,
-  79, 0, 0, 0, 7, 27, 66, 15, 34, 28,
-  0, 0, 79, 0, 29, 0, 25, 0, 16, 0,
-  0, 0, 0, 0, 0, 17, 0, 26, 0, 0,
-  5, 71, 31, 0, 0, 0, 26, 0, 28, 0,
-  0, 38, 0, 0, 0, 2, 0, 0, 2, 14,
-  69, 0, 27, 0, 63, 0, 43, 7, 17, 0,
-  0, 6, 0, 0, 0, 1, 30, 12, 26, 0,
-  0, 25, 43, 0, 8, 23, 56, 23, 0, 0,
-  32, 29, 18, 2, 25, 0, 0, 0, 0, 0,
-  0, 0, 36, 17, 0, 0, 0, 0, 0, 34,
-  0, 11, 0, 58, 21, 87, 29, 59, 0, 1,
-  0, 52, 63, 0, 3, 0, 12, 0, 0, 0,
-  25, 4, 0, 38, 0, 10, 4, 0, 42, 0,
-  34, 0, 0, 17, 34, 0, 45, 41, 0, 0,
-  77, 0, 55, 0, 5, 0, 14, 0, 0, 0,
-  0, 31, 0, 0, 0, 22, 0, 0, 32, 57,
-  30, 0, 0, 9, 8, 0, 15, 0, 0, 13,
-  0, 14, 0, 2, 0, 0, 29, 0, 33, 0,
-  14, 0, 33, 0, 13, 6, 20, 0, 0, 5,
-  0, 30, 11, 9, 0, 0, 16, 0, 14, 0,
-  28, 0, 0, 43, 62, 17, 0, 4, 0, 0,
-  0, 14, 39, 0, 19, 14, 0, 0, 0, 0,
-  39, 51, 0, 0, 0, 0, 8, 0, 0, 0,
-  0, 26, 0, 76, 41, 64, 0, 17, 0, 73,
-  78, 15, 1, 58, 0, 0, 0, 0, 35, 0,
-  0, 26, 0, 0, 54, 0, 52, 39, 59, 0,
-  0, 16, 4, 0, 13, 36, 0, 0, 89, 0,
-  49, 0, 0, 20, 1, 30, 0, 0, 0, 79,
-  0, 0, 39, 0, 21, 0, 17, 79, 53, 5,
-  0, 14, 0, 0, 0, 9, 0, 17, 0, 33,
-  0, 25, 0, 0, 3, 0, 0, 0, 0, 0,
-  77, 0, 14, 5, 4, 0, 0, 34, 21, 0,
-  0, 0, 48, 33, 91, 15, 14, 16, 57, 1,
-  0, 81, 49, 0, 0, 0, 6, 20, 26, 30,
-  1, 0, 0, 23, 0, 0, 0, 0, 60, 0,
-  3, 0, 0, 56, 0, 42, 4, 5, 0, 43,
-  0, 101, 57, 64, 0, 36, 0, 14, 67, 0,
-  0, 0, 60, 0, 18, 0, 6, 36, 0, 46,
-  0, 0, 0, 0, 80, 0, 0, 0, 27, 50,
-  26, 48, 16, 11, 0, 0, 59, 0, 25, 0,
-  0, 9, 9, 3, 5, 0, 0, 63, 0, 14,
-  0, 0, 0, 0, 4, 79, 88, 0, 0, 0,
-  17, 0, 30, 2, 0, 51, 0, 7, 0, 20,
-  0, 0, 0, 31, 77, 0, 50, 0, 85, 0,
-  42, 0, 14, 0, 0, 27, 0, 6, 0, 0,
-  33, 17, 40, 0, 12, 29, 62, 0, 14, 33,
-  65, 28, 0, 0, 26, 32, 26, 12, 42, 0,
-  0, 27, 0, 0, 0, 0, 69, 0, 0, 0,
-  0, 14, 0, 40, 0, 14, 0, 40, 23, 88,
-  0, 29, 0, 18, 0, 24, 66, 1, 4, 0,
-  0, 0, 0, 0, 30, 14, 0, 50, 0, 7,
-  42, 0, 37, 0, 0, 0, 0, 48, 16, 0,
-  58, 78, 0, 0, 60, 0, 43, 4, 0, 14,
-  12, 0, 0, 2, 0, 24, 0, 6, 0, 25,
-  4, 0, 5, 84, 38, 0, 0, 3, 48, 0,
-  12, 5, 0, 1, 0, 12, 0, 2, 0, 0,
-  15, 0, 12, 0, 16, 0, 60, 0, 26, 0,
-  25, 0, 32, 14, 0, 17, 0, 0, 0, 0,
-  0, 0, 1, 1, 16, 0, 0, 0, 49, 11,
-  3, 0, 0, 29, 0, 16, 72, 0, 37, 30,
-  0, 0, 0, 15, 79, 12, 0, 0, 0, 13,
-  41, 0, 0, 0, 0, 11, 0, 105, 32, 28,
-  0, 0, 0, 8, 36, 0, 22, 20, 3, 0,
-  0, 0, 87, 22, 0, 54, 0, 0, 130, 30,
-  67, 49, 31, 0, 0, 36, 0, 0, 48, 46,
-  0, 0, 36, 0, 58, 28, 0, 42, 0, 0,
-  0, 0, 0, 73, 0, 0, 0, 0, 0, 0,
-  0, 113, 49, 57, 10, 33, 35, 37, 0, 0,
-  24, 0, 0, 52, 0, 0, 0, 0, 4, 0,
-  10, 0, 8, 0, 23, 0, 0, 0, 31, 19,
-  7, 18, 0, 16, 0, 21, 57, 17, 0, 0,
-  0, 41, 57, 2, 0, 6, 60, 44, 5, 5,
-  45, 0, 15, 0, 37, 0, 27, 0, 0, 35,
-  0, 0, 85, 0, 0, 0, 0, 5, 0, 0,
-  0, 23, 0, 64, 4, 113, 25, 79, 0, 0,
-  0, 41, 66, 0, 0, 22, 11, 0, 0, 0,
-  15, 0, 0, 2, 0, 0, 0, 36, 38, 0,
-  60, 0, 2, 0, 50, 0, 47, 0, 0, 0,
-  62, 0, 47, 0, 7, 0, 20, 0, 0, 8,
-  0, 4, 0, 8, 0, 7, 0, 0, 51, 44,
-  26, 26, 0, 37, 18, 0, 29, 6, 9, 13,
-  0, 18, 0, 17, 0, 0, 6, 0, 36, 0,
-  37, 0, 37, 0, 0, 0, 38, 0, 0, 12,
-  0, 42, 6, 15, 37, 28, 4, 4, 6, 14,
-  22, 0, 5, 59, 66, 39, 0, 24, 0, 0,
-  0, 20, 47, 15, 29, 33, 0, 35, 0, 0,
-  91, 34, 6, 0, 0, 11, 0, 10, 0, 18,
-  0, 22, 0, 58, 46, 78, 0, 43, 0, 62,
-  86, 46, 0, 56, 0, 0, 0, 20, 4, 0,
-  0, 0, 0, 0, 39, 0, 35, 6, 23, 0,
-  0, 0, 28, 23, 8, 0, 0, 0, 113, 0,
-  11, 9, 0, 0, 7, 22, 0, 0, 22, 29,
-  0, 8, 36, 0, 36, 0, 26, 59, 19, 7,
-  14, 19, 16, 0, 26, 17, 35, 32, 0, 9,
-  19, 42, 0, 0, 5, 0, 0, 0, 14, 11,
-  125, 0, 35, 0, 0, 0, 0, 93, 5, 24,
-  14, 0, 37, 16, 19, 24, 15, 1, 7, 0,
-  45, 74, 66, 43, 0, 20, 0, 0, 0, 49,
-  65, 69, 6, 62, 0, 1, 5, 0, 69, 27,
-  8, 0, 0, 8, 0, 34, 0, 35, 41, 0,
-  16, 0, 40, 0, 0, 56, 0, 37, 99, 45,
-  0, 4, 0, 17, 0, 45, 12, 0, 0, 33,
-  0, 12, 78, 0, 23, 0, 0, 0, 0, 6,
-  46, 35, 1, 18, 0, 2, 119, 0, 0, 1,
-  0, 16, 0, 27, 17, 29, 59, 0, 0, 26,
-  0, 8, 27, 0, 0, 42, 0, 0, 29, 0,
-  16, 0, 32, 10, 52, 56, 0, 0, 9, 11,
-  0, 0, 0, 0, 0, 0, 4, 23, 137, 0,
-  66, 0, 0, 0, 0, 6, 0, 0, 0, 1,
-  30, 12, 26, 0, 0, 25, 43, 0, 8, 23,
-  56, 23, 0, 0, 32, 29, 18, 2, 25, 0,
-  0, 0, 0, 0, 0, 0, 36, 17, 0, 0,
-  0, 0, 0, 34, 0, 11, 0, 58, 21, 87,
-  29, 59, 0, 1, 0, 52, 63, 0, 3, 0,
-  12, 0, 0, 0, 25, 4, 0, 38, 0, 10,
-  4, 0, 42, 0, 34, 0, 0, 17, 34, 0,
-  45, 41, 0, 0, 77, 0, 55, 0, 5, 0,
-  14, 0, 0, 0, 0, 31, 0, 0, 0, 22,
-  0, 0, 32, 57, 30, 0, 0, 9, 8, 0,
-  15, 0, 0, 13, 0, 14, 0, 2, 0, 0,
-  29, 0, 33, 0, 14, 0, 33, 0, 13, 6,
-  20, 0, 0, 5, 0, 30, 11, 9, 0, 0,
-  16, 0, 14, 0, 28, 0, 0, 43, 62, 17,
-  0, 4, 0, 0, 0, 14, 39, 0, 19, 14,
-  0, 0, 0, 0, 39, 51, 0, 0, 0, 0,
-  8, 0, 0, 0, 0, 26, 0, 76, 41, 64,
-  0, 17, 0, 73, 78, 15, 1, 58, 0, 0,
-  0, 0, 35, 0, 0, 26, 0, 0, 54, 0,
-  52, 39, 59, 0, 0, 16, 4, 0, 13, 36,
-  0, 0, 89, 0, 49, 0, 0, 20, 1, 30,
-  0, 0, 0, 79, 0, 0, 39, 0, 21, 0,
-  17, 79, 53, 5, 0, 14, 0, 0, 0, 9,
-  0, 17, 0, 33, 0, 25, 0, 0, 3, 0,
-  0, 0, 0, 0, 77, 0, 14, 5, 4, 0,
-  0, 37, 0, 30, 19, 0, 8, 0, 29, 1,
-  5, 0, 23, 0, 24, 68, 78, 31, 0, 2,
-  0, 0, 0, 40, 45, 0, 20, 28, 0, 0,
-  7, 0, 46, 69, 0, 0, 0, 8, 7, 0,
-  0, 0, 0, 16, 0, 35, 63, 39, 0, 11,
-  0, 42, 72, 27, 0, 30, 0, 4, 0, 3,
-  38, 0, 0, 31, 0, 0, 79, 0, 75, 41,
-  0, 0, 0, 12, 16, 0, 14, 1, 0, 0,
-  85, 0, 26, 0, 0, 32, 0, 18, 6, 0,
-  14, 72, 0, 6, 28, 0, 15, 0, 0, 80,
-  18, 0, 0, 7, 0, 0, 0, 0, 2, 22,
-  0, 30, 8, 22, 3, 0, 0, 0, 0, 0,
-  0, 0, 101, 0, 9, 26, 7, 0, 0, 27,
-  0, 6, 0, 0, 33, 17, 40, 0, 12, 29,
-  62, 0, 14, 33, 65, 28, 0, 0, 26, 32,
-  26, 12, 42, 0, 0, 27, 0, 0, 0, 0,
-  69, 0, 0, 0, 0, 14, 0, 40, 0, 14,
-  0, 40, 23, 88, 0, 29, 0, 18, 0, 24,
-  66, 1, 4, 0, 0, 0, 0, 0, 30, 14,
-  0, 50, 0, 7, 42, 0, 37, 0, 0, 0,
-  0, 48, 16, 0, 58, 78, 0, 0, 60, 0,
-  43, 4, 0, 14, 12, 0, 0, 2, 0, 24,
-  0, 6, 0, 25, 4, 0, 5, 84, 38, 0,
-  0, 3, 48, 0, 12, 5, 0, 1, 0, 12,
-  0, 2, 0, 0, 15, 0, 12, 0, 16, 0,
-  60, 0, 26, 0, 25, 0, 32, 14, 0, 17,
-  0, 0, 0, 0, 0, 0, 1, 1, 16, 0,
-  0, 0, 49, 11, 3, 0, 0, 29, 0, 16,
-  72, 0, 37, 30, 0, 0, 0, 15, 79, 12,
-  0, 0, 0, 13, 41, 0, 0, 0, 0, 11,
-  0, 105, 32, 28, 0, 0, 0, 8, 36, 0,
-  22, 20, 3, 0, 0, 0, 87, 22, 0, 54,
-  0, 0, 130, 30, 67, 49, 31, 0, 0, 36,
-  0, 0, 48, 46, 0, 0, 36, 0, 58, 28,
-  0, 42, 0, 0, 0, 0, 0, 73, 0, 0,
-  0, 0, 0, 0, 0, 113, 49, 57, 10, 33,
-  35, 37, 0, 0, 24, 0, 0, 52, 0, 0,
-  0, 0, 4, 0, 10, 0, 8, 0, 23, 0,
-  0, 0, 31, 19, 12, 13, 0, 21, 6, 5,
-  0, 0, 11, 0, 0, 0, 48, 0, 0, 18,
-  58, 12, 0, 0, 0, 8, 0, 28, 33, 0,
-  31, 20, 0, 0, 0, 2, 67, 50, 0, 0,
-  0, 26, 49, 0, 0, 0, 0, 31, 0, 97,
-  52, 74, 0, 0, 0, 36, 26, 0, 0, 44,
-  0, 0, 0, 0, 64, 9, 0, 12, 0, 0,
-  87, 26, 88, 48, 67, 0, 0, 16, 0, 0,
-  28, 0, 0, 0, 33, 0, 46, 22, 0, 32,
-  0, 0, 2, 0, 0, 84, 0, 0, 12, 0,
-  0, 0, 1, 115, 49, 54, 0, 40, 17, 26,
-  0, 0, 9, 0, 0, 49, 0, 16, 0, 0,
-  0, 0, 29, 0, 1, 0, 46, 0, 0, 0,
-  33, 16, 0, 12, 0, 42, 6, 15, 37, 28,
-  4, 4, 6, 14, 22, 0, 5, 59, 66, 39,
-  0, 24, 0, 0, 0, 20, 47, 15, 29, 33,
-  0, 35, 0, 0, 91, 34, 6, 0, 0, 11,
-  0, 10, 0, 18, 0, 22, 0, 58, 46, 78,
-  0, 43, 0, 62, 86, 46, 0, 56, 0, 0,
-  0, 20, 4, 0, 0, 0, 0, 0, 39, 0,
-  35, 6, 23, 0, 0, 0, 28, 23, 8, 0,
-  0, 0, 113, 0, 11, 9, 0, 0, 7, 22,
-  0, 0, 22, 29, 0, 8, 36, 0, 36, 0,
-  26, 59, 19, 7, 14, 19, 16, 0, 26, 17,
-  35, 32, 0, 9, 19, 42, 0, 0, 5, 0,
-  0, 0, 14, 11, 125, 0, 35, 0, 0, 0,
-  0, 93, 5, 24, 14, 0, 37, 16, 19, 24,
-  15, 1, 7, 0, 45, 74, 66, 43, 0, 20,
-  0, 0, 0, 49, 65, 69, 6, 62, 0, 1,
-  5, 0, 69, 27, 8, 0, 0, 8, 0, 34,
-  0, 35, 41, 0, 16, 0, 40, 0, 0, 56,
-  0, 37, 99, 45, 0, 4, 0, 17, 0, 45,
-  12, 0, 0, 33, 0, 12, 78, 0, 23, 0,
-  0, 0, 0, 6, 46, 35, 1, 18, 0, 2,
-  119, 0, 0, 1, 0, 16, 0, 27, 17, 29,
-  59, 0, 0, 26, 0, 8, 27, 0, 0, 42,
-  0, 0, 29, 0, 16, 0, 32, 10, 52, 56,
-  0, 0, 9, 11, 0, 0, 0, 0, 0, 0,
-  4, 23, 137, 0, 66, 0, 0, 0, 0, 115,
-  36, 17, 6, 0, 3, 0, 44, 17, 0, 0,
-  3, 0, 0, 24, 36, 38, 6, 35, 0, 0,
-  67, 53, 19, 0, 40, 54, 0, 0, 0, 0,
-  68, 0, 53, 8, 0, 0, 28, 2, 0, 0,
-  37, 25, 0, 67, 27, 0, 0, 2, 0, 53,
-  88, 0, 20, 0, 26, 0, 0, 0, 0, 27,
-  0, 0, 0, 0, 0, 0, 0, 14, 53, 0,
-  37, 17, 61, 42, 0, 74, 24, 0, 64, 0,
-  4, 21, 0, 0, 6, 36, 25, 20, 74, 0,
-  0, 0, 24, 0, 0, 0, 0, 53, 38, 17,
-  0, 0, 21, 4, 62, 0, 41, 58, 0, 16,
-  0, 3, 0, 0, 0, 0, 0, 6, 0, 0,
-  35, 0, 53, 1, 0, 0, 0, 5, 0, 30,
-  11, 9, 0, 0, 16, 0, 14, 0, 28, 0,
-  0, 43, 62, 17, 0, 4, 0, 0, 0, 14,
-  39, 0, 19, 14, 0, 0, 0, 0, 39, 51,
-  0, 0, 0, 0, 8, 0, 0, 0, 0, 26,
-  0, 76, 41, 64, 0, 17, 0, 73, 78, 15,
-  1, 58, 0, 0, 0, 0, 35, 0, 0, 26,
-  0, 0, 54, 0, 52, 39, 59, 0, 0, 16,
-  4, 0, 13, 36, 0, 0, 89, 0, 49, 0,
-  0, 20, 1, 30, 0, 0, 0, 79, 0, 0,
-  39, 0, 21, 0, 17, 79, 53, 5, 0, 14,
-  0, 0, 0, 9, 0, 17, 0, 33, 0, 25,
-  0, 0, 3, 0, 0, 0, 0, 0, 77, 0,
-  14, 5, 4, 0, 0, 37, 0, 30, 19, 0,
-  8, 0, 29, 1, 5, 0, 23, 0, 24, 68,
-  78, 31, 0, 2, 0, 0, 0, 40, 45, 0,
-  20, 28, 0, 0, 7, 0, 46, 69, 0, 0,
-  0, 8, 7, 0, 0, 0, 0, 16, 0, 35,
-  63, 39, 0, 11, 0, 42, 72, 27, 0, 30,
-  0, 4, 0, 3, 38, 0, 0, 31, 0, 0,
-  79, 0, 75, 41, 0, 0, 0, 12, 16, 0,
-  14, 1, 0, 0, 85, 0, 26, 0, 0, 32,
-  0, 18, 6, 0, 14, 72, 0, 6, 28, 0,
-  15, 0, 0, 80, 18, 0, 0, 7, 0, 0,
-  0, 0, 2, 22, 0, 30, 8, 22, 3, 0,
-  0, 0, 0, 0, 0, 0, 101, 0, 9, 26,
-  7, 0, 0, 119, 31, 10, 0, 0, 55, 0,
-  33, 18, 0, 0, 0, 0, 46, 39, 65, 38,
-  5, 18, 0, 0, 0, 46, 49, 6, 24, 40,
-  0, 0, 0, 0, 84, 26, 0, 0, 0, 16,
-  0, 3, 0, 0, 24, 17, 0, 45, 64, 6,
-  0, 10, 0, 0, 73, 0, 0, 0, 32, 0,
-  0, 35, 7, 5, 0, 0, 0, 0, 63, 0,
-  26, 11, 0, 0, 0, 15, 64, 26, 8, 27,
-  5, 0, 67, 3, 18, 28, 0, 6, 0, 0,
-  1, 26, 36, 0, 0, 22, 0, 0, 0, 0,
-  0, 60, 6, 0, 0, 0, 2, 0, 43, 0,
-  35, 36, 0, 21, 0, 19, 0, 0, 0, 0,
-  13, 0, 0, 0, 95, 0, 24, 41, 20, 0,
-  32, 14, 0, 17, 0, 0, 0, 0, 0, 0,
-  1, 1, 16, 0, 0, 0, 49, 11, 3, 0,
-  0, 29, 0, 16, 72, 0, 37, 30, 0, 0,
-  0, 15, 79, 12, 0, 0, 0, 13, 41, 0,
-  0, 0, 0, 11, 0, 105, 32, 28, 0, 0,
-  0, 8, 36, 0, 22, 20, 3, 0, 0, 0,
-  87, 22, 0, 54, 0, 0, 130, 30, 67, 49,
-  31, 0, 0, 36, 0, 0, 48, 46, 0, 0,
-  36, 0, 58, 28, 0, 42, 0, 0, 0, 0,
-  0, 73, 0, 0, 0, 0, 0, 0, 0, 113,
-  49, 57, 10, 33, 35, 37, 0, 0, 24, 0,
-  0, 52, 0, 0, 0, 0, 4, 0, 10, 0,
-  8, 0, 23, 0, 0, 0, 31, 19, 12, 13,
-  0, 21, 6, 5, 0, 0, 11, 0, 0, 0,
-  48, 0, 0, 18, 58, 12, 0, 0, 0, 8,
-  0, 28, 33, 0, 31, 20, 0, 0, 0, 2,
-  67, 50, 0, 0, 0, 26, 49, 0, 0, 0,
-  0, 31, 0, 97, 52, 74, 0, 0, 0, 36,
-  26, 0, 0, 44, 0, 0, 0, 0, 64, 9,
-  0, 12, 0, 0, 87, 26, 88, 48, 67, 0,
-  0, 16, 0, 0, 28, 0, 0, 0, 33, 0,
-  46, 22, 0, 32, 0, 0, 2, 0, 0, 84,
-  0, 0, 12, 0, 0, 0, 1, 115, 49, 54,
-  0, 40, 17, 26, 0, 0, 9, 0, 0, 49,
-  0, 16, 0, 0, 0, 0, 29, 0, 1, 0,
-  46, 0, 0, 0, 33, 16, 0, 98, 0, 20,
-  14, 0, 60, 12, 44, 16, 32, 0, 54, 0,
-  44, 107, 104, 30, 6, 0, 0, 0, 0, 40,
-  41, 45, 0, 53, 0, 0, 0, 0, 87, 64,
-  0, 0, 0, 27, 0, 41, 0, 0, 16, 28,
-  30, 44, 24, 53, 0, 28, 0, 0, 87, 10,
-  0, 0, 0, 14, 0, 58, 10, 0, 0, 24,
-  0, 0, 75, 0, 41, 0, 0, 0, 0, 48,
-  17, 40, 0, 0, 0, 12, 73, 0, 9, 26,
-  0, 32, 2, 2, 0, 43, 49, 36, 0, 65,
-  0, 26, 0, 0, 0, 86, 27, 0, 0, 0,
-  9, 0, 28, 10, 24, 30, 0, 17, 0, 27,
-  0, 0, 0, 0, 2, 0, 8, 0, 164, 0,
-  52, 9, 40, 0, 0, 93, 5, 24, 14, 0,
-  37, 16, 19, 24, 15, 1, 7, 0, 45, 74,
-  66, 43, 0, 20, 0, 0, 0, 49, 65, 69,
-  6, 62, 0, 1, 5, 0, 69, 27, 8, 0,
-  0, 8, 0, 34, 0, 35, 41, 0, 16, 0,
-  40, 0, 0, 56, 0, 37, 99, 45, 0, 4,
-  0, 17, 0, 45, 12, 0, 0, 33, 0, 12,
-  78, 0, 23, 0, 0, 0, 0, 6, 46, 35,
-  1, 18, 0, 2, 119, 0, 0, 1, 0, 16,
-  0, 27, 17, 29, 59, 0, 0, 26, 0, 8,
-  27, 0, 0, 42, 0, 0, 29, 0, 16, 0,
-  32, 10, 52, 56, 0, 0, 9, 11, 0, 0,
-  0, 0, 0, 0, 4, 23, 137, 0, 66, 0,
-  0, 0, 0, 115, 36, 17, 6, 0, 3, 0,
-  44, 17, 0, 0, 3, 0, 0, 24, 36, 38,
-  6, 35, 0, 0, 67, 53, 19, 0, 40, 54,
-  0, 0, 0, 0, 68, 0, 53, 8, 0, 0,
-  28, 2, 0, 0, 37, 25, 0, 67, 27, 0,
-  0, 2, 0, 53, 88, 0, 20, 0, 26, 0,
-  0, 0, 0, 27, 0, 0, 0, 0, 0, 0,
-  0, 14, 53, 0, 37, 17, 61, 42, 0, 74,
-  24, 0, 64, 0, 4, 21, 0, 0, 6, 36,
-  25, 20, 74, 0, 0, 0, 24, 0, 0, 0,
-  0, 53, 38, 17, 0, 0, 21, 4, 62, 0,
-  41, 58, 0, 16, 0, 3, 0, 0, 0, 0,
-  0, 6, 0, 0, 35, 0, 53, 1, 0, 0,
-  55, 68, 5, 59, 7, 0, 0, 0, 39, 0,
-  0, 18, 78, 0, 0, 0, 25, 2, 0, 0,
-  0, 34, 65, 19, 34, 0, 18, 36, 0, 0,
-  0, 6, 13, 0, 31, 16, 0, 0, 71, 0,
-  0, 16, 19, 37, 0, 40, 14, 0, 0, 0,
-  0, 107, 29, 0, 61, 0, 36, 0, 0, 0,
-  0, 19, 0, 10, 41, 34, 0, 0, 22, 0,
-  133, 0, 33, 13, 17, 0, 9, 54, 28, 7,
-  16, 0, 14, 15, 15, 0, 15, 0, 48, 0,
-  1, 0, 0, 0, 0, 0, 10, 0, 0, 40,
-  0, 1, 9, 0, 35, 68, 7, 20, 38, 3,
-  0, 13, 0, 0, 0, 0, 0, 0, 0, 9,
-  0, 0, 0, 0, 53, 0, 0, 0, 0, 37,
-  0, 30, 19, 0, 8, 0, 29, 1, 5, 0,
-  23, 0, 24, 68, 78, 31, 0, 2, 0, 0,
-  0, 40, 45, 0, 20, 28, 0, 0, 7, 0,
-  46, 69, 0, 0, 0, 8, 7, 0, 0, 0,
-  0, 16, 0, 35, 63, 39, 0, 11, 0, 42,
-  72, 27, 0, 30, 0, 4, 0, 3, 38, 0,
-  0, 31, 0, 0, 79, 0, 75, 41, 0, 0,
-  0, 12, 16, 0, 14, 1, 0, 0, 85, 0,
-  26, 0, 0, 32, 0, 18, 6, 0, 14, 72,
-  0, 6, 28, 0, 15, 0, 0, 80, 18, 0,
-  0, 7, 0, 0, 0, 0, 2, 22, 0, 30,
-  8, 22, 3, 0, 0, 0, 0, 0, 0, 0,
-  101, 0, 9, 26, 7, 0, 0, 119, 31, 10,
-  0, 0, 55, 0, 33, 18, 0, 0, 0, 0,
-  46, 39, 65, 38, 5, 18, 0, 0, 0, 46,
-  49, 6, 24, 40, 0, 0, 0, 0, 84, 26,
-  0, 0, 0, 16, 0, 3, 0, 0, 24, 17,
-  0, 45, 64, 6, 0, 10, 0, 0, 73, 0,
-  0, 0, 32, 0, 0, 35, 7, 5, 0, 0,
-  0, 0, 63, 0, 26, 11, 0, 0, 0, 15,
-  64, 26, 8, 27, 5, 0, 67, 3, 18, 28,
-  0, 6, 0, 0, 1, 26, 36, 0, 0, 22,
-  0, 0, 0, 0, 0, 60, 6, 0, 0, 0,
-  2, 0, 43, 0, 35, 36, 0, 21, 0, 19,
-  0, 0, 0, 0, 13, 0, 0, 0, 95, 0,
-  24, 41, 20, 0, 0, 104, 16, 18, 0, 0,
-  0, 0, 47, 19, 0, 0, 6, 0, 7, 17,
-  36, 23, 0, 2, 0, 0, 72, 39, 0, 0,
-  14, 29, 0, 0, 0, 0, 40, 0, 36, 14,
-  0, 1, 11, 0, 0, 0, 22, 32, 0, 52,
-  25, 0, 0, 0, 0, 42, 40, 0, 22, 0,
-  44, 0, 3, 0, 0, 33, 0, 0, 52, 0,
-  0, 0, 0, 10, 106, 0, 39, 32, 46, 45,
-  0, 59, 28, 0, 21, 0, 1, 31, 0, 0,
-  5, 21, 26, 0, 31, 0, 0, 0, 5, 0,
-  0, 0, 0, 52, 28, 23, 1, 0, 7, 59,
-  48, 1, 0, 29, 0, 28, 0, 8, 0, 0,
-  0, 0, 0, 12, 0, 0, 0, 0, 49, 26,
-  5, 0, 12, 13, 0, 21, 6, 5, 0, 0,
-  11, 0, 0, 0, 48, 0, 0, 18, 58, 12,
-  0, 0, 0, 8, 0, 28, 33, 0, 31, 20,
-  0, 0, 0, 2, 67, 50, 0, 0, 0, 26,
-  49, 0, 0, 0, 0, 31, 0, 97, 52, 74,
-  0, 0, 0, 36, 26, 0, 0, 44, 0, 0,
-  0, 0, 64, 9, 0, 12, 0, 0, 87, 26,
-  88, 48, 67, 0, 0, 16, 0, 0, 28, 0,
-  0, 0, 33, 0, 46, 22, 0, 32, 0, 0,
-  2, 0, 0, 84, 0, 0, 12, 0, 0, 0,
-  1, 115, 49, 54, 0, 40, 17, 26, 0, 0,
-  9, 0, 0, 49, 0, 16, 0, 0, 0, 0,
-  29, 0, 1, 0, 46, 0, 0, 0, 33, 16,
-  0, 98, 0, 20, 14, 0, 60, 12, 44, 16,
-  32, 0, 54, 0, 44, 107, 104, 30, 6, 0,
-  0, 0, 0, 40, 41, 45, 0, 53, 0, 0,
-  0, 0, 87, 64, 0, 0, 0, 27, 0, 41,
-  0, 0, 16, 28, 30, 44, 24, 53, 0, 28,
-  0, 0, 87, 10, 0, 0, 0, 14, 0, 58,
-  10, 0, 0, 24, 0, 0, 75, 0, 41, 0,
-  0, 0, 0, 48, 17, 40, 0, 0, 0, 12,
-  73, 0, 9, 26, 0, 32, 2, 2, 0, 43,
-  49, 36, 0, 65, 0, 26, 0, 0, 0, 86,
-  27, 0, 0, 0, 9, 0, 28, 10, 24, 30,
-  0, 17, 0, 27, 0, 0, 0, 0, 2, 0,
-  8, 0, 164, 0, 52, 9, 40, 0, 0, 111,
-  49, 4, 4, 0, 0, 13, 78, 36, 24, 0,
-  20, 0, 0, 97, 83, 24, 24, 5, 0, 0,
-  48, 50, 0, 0, 1, 78, 1, 0, 0, 0,
-  68, 0, 12, 0, 0, 28, 0, 3, 0, 0,
-  11, 19, 11, 36, 0, 0, 0, 29, 0, 18,
-  44, 0, 0, 0, 1, 0, 0, 8, 0, 0,
-  0, 0, 0, 0, 29, 0, 0, 0, 0, 0,
-  32, 72, 9, 90, 0, 112, 2, 20, 35, 0,
-  0, 53, 0, 31, 6, 61, 21, 24, 117, 0,
-  0, 0, 26, 0, 0, 0, 0, 100, 90, 0,
-  0, 0, 7, 0, 54, 21, 0, 21, 0, 0,
-  0, 15, 0, 0, 0, 0, 0, 21, 0, 0,
-  73, 0, 76, 10, 35, 0, 0, 115, 36, 17,
-  6, 0, 3, 0, 44, 17, 0, 0, 3, 0,
-  0, 24, 36, 38, 6, 35, 0, 0, 67, 53,
-  19, 0, 40, 54, 0, 0, 0, 0, 68, 0,
-  53, 8, 0, 0, 28, 2, 0, 0, 37, 25,
-  0, 67, 27, 0, 0, 2, 0, 53, 88, 0,
-  20, 0, 26, 0, 0, 0, 0, 27, 0, 0,
-  0, 0, 0, 0, 0, 14, 53, 0, 37, 17,
-  61, 42, 0, 74, 24, 0, 64, 0, 4, 21,
-  0, 0, 6, 36, 25, 20, 74, 0, 0, 0,
-  24, 0, 0, 0, 0, 53, 38, 17, 0, 0,
-  21, 4, 62, 0, 41, 58, 0, 16, 0, 3,
-  0, 0, 0, 0, 0, 6, 0, 0, 35, 0,
-  53, 1, 0, 0, 55, 68, 5, 59, 7, 0,
-  0, 0, 39, 0, 0, 18, 78, 0, 0, 0,
-  25, 2, 0, 0, 0, 34, 65, 19, 34, 0,
-  18, 36, 0, 0, 0, 6, 13, 0, 31, 16,
-  0, 0, 71, 0, 0, 16, 19, 37, 0, 40,
-  14, 0, 0, 0, 0, 107, 29, 0, 61, 0,
-  36, 0, 0, 0, 0, 19, 0, 10, 41, 34,
-  0, 0, 22, 0, 133, 0, 33, 13, 17, 0,
-  9, 54, 28, 7, 16, 0, 14, 15, 15, 0,
-  15, 0, 48, 0, 1, 0, 0, 0, 0, 0,
-  10, 0, 0, 40, 0, 1, 9, 0, 35, 68,
-  7, 20, 38, 3, 0, 13, 0, 0, 0, 0,
-  0, 0, 0, 9, 0, 0, 0, 0, 53, 0,
-  0, 0, 104, 21, 0, 47, 20, 66, 0, 0,
-  53, 0, 0, 0, 116, 0, 0, 40, 62, 0,
-  2, 0, 11, 68, 0, 8, 23, 0, 0, 43,
-  3, 1, 13, 72, 0, 27, 24, 0, 0, 21,
-  96, 5, 13, 87, 14, 47, 59, 16, 0, 0,
-  0, 0, 0, 111, 0, 0, 107, 59, 25, 17,
-  19, 0, 0, 13, 9, 35, 0, 93, 0, 0,
-  13, 0, 155, 30, 22, 32, 0, 0, 34, 19,
-  0, 47, 0, 0, 15, 14, 42, 14, 8, 0,
-  73, 0, 0, 0, 0, 2, 0, 0, 31, 0,
-  21, 50, 0, 0, 5, 0, 30, 31, 0, 67,
-  22, 0, 17, 0, 0, 0, 0, 0, 0, 0,
-  0, 1, 0, 3, 0, 16, 53, 0, 3, 16,
-  0, 119, 31, 10, 0, 0, 55, 0, 33, 18,
-  0, 0, 0, 0, 46, 39, 65, 38, 5, 18,
-  0, 0, 0, 46, 49, 6, 24, 40, 0, 0,
-  0, 0, 84, 26, 0, 0, 0, 16, 0, 3,
-  0, 0, 24, 17, 0, 45, 64, 6, 0, 10,
-  0, 0, 73, 0, 0, 0, 32, 0, 0, 35,
-  7, 5, 0, 0, 0, 0, 63, 0, 26, 11,
-  0, 0, 0, 15, 64, 26, 8, 27, 5, 0,
-  67, 3, 18, 28, 0, 6, 0, 0, 1, 26,
-  36, 0, 0, 22, 0, 0, 0, 0, 0, 60,
-  6, 0, 0, 0, 2, 0, 43, 0, 35, 36,
-  0, 21, 0, 19, 0, 0, 0, 0, 13, 0,
-  0, 0, 95, 0, 24, 41, 20, 0, 0, 104,
-  16, 18, 0, 0, 0, 0, 47, 19, 0, 0,
-  6, 0, 7, 17, 36, 23, 0, 2, 0, 0,
-  72, 39, 0, 0, 14, 29, 0, 0, 0, 0,
-  40, 0, 36, 14, 0, 1, 11, 0, 0, 0,
-  22, 32, 0, 52, 25, 0, 0, 0, 0, 42,
-  40, 0, 22, 0, 44, 0, 3, 0, 0, 33,
-  0, 0, 52, 0, 0, 0, 0, 10, 106, 0,
-  39, 32, 46, 45, 0, 59, 28, 0, 21, 0,
-  1, 31, 0, 0, 5, 21, 26, 0, 31, 0,
-  0, 0, 5, 0, 0, 0, 0, 52, 28, 23,
-  1, 0, 7, 59, 48, 1, 0, 29, 0, 28,
-  0, 8, 0, 0, 0, 0, 0, 12, 0, 0,
-  0, 0, 49, 26, 5, 0, 107, 66, 16, 65,
-  30, 0, 0, 17, 71, 14, 28, 0, 85, 0,
-  0, 80, 60, 0, 13, 0, 0, 32, 32, 6,
-  0, 0, 0, 61, 0, 37, 19, 69, 10, 6,
-  18, 5, 0, 44, 103, 0, 0, 23, 0, 23,
-  18, 0, 0, 0, 0, 0, 0, 86, 0, 0,
-  83, 13, 32, 36, 9, 0, 0, 0, 0, 0,
-  15, 55, 0, 0, 11, 0, 91, 19, 43, 55,
-  0, 39, 28, 49, 0, 26, 0, 0, 19, 64,
-  28, 26, 14, 0, 86, 0, 32, 0, 0, 14,
-  0, 0, 66, 0, 5, 67, 43, 0, 9, 0,
-  0, 58, 0, 60, 9, 0, 6, 0, 0, 0,
-  0, 0, 0, 0, 0, 15, 0, 4, 0, 18,
-  46, 15, 12, 30, 0, 98, 0, 20, 14, 0,
-  60, 12, 44, 16, 32, 0, 54, 0, 44, 107,
-  104, 30, 6, 0, 0, 0, 0, 40, 41, 45,
-  0, 53, 0, 0, 0, 0, 87, 64, 0, 0,
-  0, 27, 0, 41, 0, 0, 16, 28, 30, 44,
-  24, 53, 0, 28, 0, 0, 87, 10, 0, 0,
-  0, 14, 0, 58, 10, 0, 0, 24, 0, 0,
-  75, 0, 41, 0, 0, 0, 0, 48, 17, 40,
-  0, 0, 0, 12, 73, 0, 9, 26, 0, 32,
-  2, 2, 0, 43, 49, 36, 0, 65, 0, 26,
-  0, 0, 0, 86, 27, 0, 0, 0, 9, 0,
-  28, 10, 24, 30, 0, 17, 0, 27, 0, 0,
-  0, 0, 2, 0, 8, 0, 164, 0, 52, 9,
-  40, 0, 0, 111, 49, 4, 4, 0, 0, 13,
-  78, 36, 24, 0, 20, 0, 0, 97, 83, 24,
-  24, 5, 0, 0, 48, 50, 0, 0, 1, 78,
-  1, 0, 0, 0, 68, 0, 12, 0, 0, 28,
-  0, 3, 0, 0, 11, 19, 11, 36, 0, 0,
-  0, 29, 0, 18, 44, 0, 0, 0, 1, 0,
-  0, 8, 0, 0, 0, 0, 0, 0, 29, 0,
-  0, 0, 0, 0, 32, 72, 9, 90, 0, 112,
-  2, 20, 35, 0, 0, 53, 0, 31, 6, 61,
-  21, 24, 117, 0, 0, 0, 26, 0, 0, 0,
-  0, 100, 90, 0, 0, 0, 7, 0, 54, 21,
-  0, 21, 0, 0, 0, 15, 0, 0, 0, 0,
-  0, 21, 0, 0, 73, 0, 76, 10, 35, 0,
-  59, 1, 72, 42, 0, 0, 0, 22, 38, 13,
-  13, 6, 0, 7, 0, 21, 38, 13, 14, 0,
-  0, 64, 43, 11, 0, 0, 1, 54, 0, 38,
-  0, 39, 17, 0, 12, 19, 36, 29, 3, 0,
-  0, 0, 0, 0, 0, 11, 0, 0, 0, 0,
-  0, 70, 0, 0, 91, 0, 38, 0, 8, 0,
-  0, 4, 0, 0, 64, 10, 0, 0, 0, 114,
-  20, 0, 74, 27, 0, 45, 12, 51, 27, 0,
-  0, 0, 15, 101, 0, 21, 22, 36, 22, 0,
-  57, 0, 0, 0, 62, 0, 29, 0, 0, 72,
-  95, 0, 0, 0, 0, 80, 0, 16, 0, 0,
-  0, 13, 0, 0, 0, 0, 0, 0, 0, 33,
-  0, 3, 0, 0, 0, 0, 4, 22, 55, 68,
-  5, 59, 7, 0, 0, 0, 39, 0, 0, 18,
-  78, 0, 0, 0, 25, 2, 0, 0, 0, 34,
-  65, 19, 34, 0, 18, 36, 0, 0, 0, 6,
-  13, 0, 31, 16, 0, 0, 71, 0, 0, 16,
-  19, 37, 0, 40, 14, 0, 0, 0, 0, 107,
-  29, 0, 61, 0, 36, 0, 0, 0, 0, 19,
-  0, 10, 41, 34, 0, 0, 22, 0, 133, 0,
-  33, 13, 17, 0, 9, 54, 28, 7, 16, 0,
-  14, 15, 15, 0, 15, 0, 48, 0, 1, 0,
-  0, 0, 0, 0, 10, 0, 0, 40, 0, 1,
-  9, 0, 35, 68, 7, 20, 38, 3, 0, 13,
-  0, 0, 0, 0, 0, 0, 0, 9, 0, 0,
-  0, 0, 53, 0, 0, 0, 104, 21, 0, 47,
-  20, 66, 0, 0, 53, 0, 0, 0, 116, 0,
-  0, 40, 62, 0, 2, 0, 11, 68, 0, 8,
-  23, 0, 0, 43, 3, 1, 13, 72, 0, 27,
-  24, 0, 0, 21, 96, 5, 13, 87, 14, 47,
-  59, 16, 0, 0, 0, 0, 0, 111, 0, 0,
-  107, 59, 25, 17, 19, 0, 0, 13, 9, 35,
-  0, 93, 0, 0, 13, 0, 155, 30, 22, 32,
-  0, 0, 34, 19, 0, 47, 0, 0, 15, 14,
-  42, 14, 8, 0, 73, 0, 0, 0, 0, 2,
-  0, 0, 31, 0, 21, 50, 0, 0, 5, 0,
-  30, 31, 0, 67, 22, 0, 17, 0, 0, 0,
-  0, 0, 0, 0, 0, 1, 0, 3, 0, 16,
-  53, 0, 3, 16, 0, 0, 0, 0, 0, 145,
-  0, 0, 46, 0, 0, 0, 34, 21, 0, 109,
-  67, 48, 0, 0, 39, 1, 0, 58, 0, 0,
-  0, 56, 1, 0, 0, 0, 49, 0, 0, 0,
-  22, 71, 0, 0, 22, 0, 0, 3, 13, 87,
-  0, 0, 0, 14, 12, 53, 23, 0, 62, 19,
-  29, 0, 0, 0, 0, 48, 0, 0, 12, 0,
-  16, 0, 17, 13, 58, 0, 50, 76, 0, 66,
-  0, 52, 0, 0, 8, 0, 17, 64, 0, 25,
-  19, 0, 22, 2, 35, 128, 0, 0, 75, 0,
-  0, 0, 0, 93, 86, 0, 0, 0, 15, 0,
-  0, 38, 0, 19, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 13, 0,
-  4, 15, 0, 104, 16, 18, 0, 0, 0, 0,
-  47, 19, 0, 0, 6, 0, 7, 17, 36, 23,
-  0, 2, 0, 0, 72, 39, 0, 0, 14, 29,
-  0, 0, 0, 0, 40, 0, 36, 14, 0, 1,
-  11, 0, 0, 0, 22, 32, 0, 52, 25, 0,
-  0, 0, 0, 42, 40, 0, 22, 0, 44, 0,
-  3, 0, 0, 33, 0, 0, 52, 0, 0, 0,
-  0, 10, 106, 0, 39, 32, 46, 45, 0, 59,
-  28, 0, 21, 0, 1, 31, 0, 0, 5, 21,
-  26, 0, 31, 0, 0, 0, 5, 0, 0, 0,
-  0, 52, 28, 23, 1, 0, 7, 59, 48, 1,
-  0, 29, 0, 28, 0, 8, 0, 0, 0, 0,
-  0, 12, 0, 0, 0, 0, 49, 26, 5, 0,
-  107, 66, 16, 65, 30, 0, 0, 17, 71, 14,
-  28, 0, 85, 0, 0, 80, 60, 0, 13, 0,
-  0, 32, 32, 6, 0, 0, 0, 61, 0, 37,
-  19, 69, 10, 6, 18, 5, 0, 44, 103, 0,
-  0, 23, 0, 23, 18, 0, 0, 0, 0, 0,
-  0, 86, 0, 0, 83, 13, 32, 36, 9, 0,
-  0, 0, 0, 0, 15, 55, 0, 0, 11, 0,
-  91, 19, 43, 55, 0, 39, 28, 49, 0, 26,
-  0, 0, 19, 64, 28, 26, 14, 0, 86, 0,
-  32, 0, 0, 14, 0, 0, 66, 0, 5, 67,
-  43, 0, 9, 0, 0, 58, 0, 60, 9, 0,
-  6, 0, 0, 0, 0, 0, 0, 0, 0, 15,
-  0, 4, 0, 18, 46, 15, 12, 30, 14, 0,
-  60, 29, 0, 164, 0, 0, 18, 0, 0, 0,
-  3, 20, 0, 48, 30, 38, 0, 0, 13, 76,
-  24, 1, 0, 0, 0, 35, 0, 48, 0, 88,
-  0, 0, 0, 20, 63, 58, 24, 0, 0, 0,
-  0, 0, 0, 11, 0, 0, 13, 0, 0, 83,
-  0, 0, 99, 0, 57, 0, 22, 0, 0, 57,
-  14, 0, 110, 0, 0, 29, 2, 76, 21, 14,
-  67, 27, 0, 44, 44, 26, 0, 0, 0, 0,
-  32, 108, 0, 10, 10, 0, 11, 0, 10, 13,
-  0, 0, 58, 0, 30, 0, 0, 71, 79, 0,
-  0, 0, 0, 18, 0, 26, 0, 0, 0, 0,
-  0, 0, 4, 4, 54, 0, 0, 35, 0, 18,
-  0, 0, 0, 17, 0, 23, 0, 111, 49, 4,
-  4, 0, 0, 13, 78, 36, 24, 0, 20, 0,
-  0, 97, 83, 24, 24, 5, 0, 0, 48, 50,
-  0, 0, 1, 78, 1, 0, 0, 0, 68, 0,
-  12, 0, 0, 28, 0, 3, 0, 0, 11, 19,
-  11, 36, 0, 0, 0, 29, 0, 18, 44, 0,
-  0, 0, 1, 0, 0, 8, 0, 0, 0, 0,
-  0, 0, 29, 0, 0, 0, 0, 0, 32, 72,
-  9, 90, 0, 112, 2, 20, 35, 0, 0, 53,
-  0, 31, 6, 61, 21, 24, 117, 0, 0, 0,
-  26, 0, 0, 0, 0, 100, 90, 0, 0, 0,
-  7, 0, 54, 21, 0, 21, 0, 0, 0, 15,
-  0, 0, 0, 0, 0, 21, 0, 0, 73, 0,
-  76, 10, 35, 0, 59, 1, 72, 42, 0, 0,
-  0, 22, 38, 13, 13, 6, 0, 7, 0, 21,
-  38, 13, 14, 0, 0, 64, 43, 11, 0, 0,
-  1, 54, 0, 38, 0, 39, 17, 0, 12, 19,
-  36, 29, 3, 0, 0, 0, 0, 0, 0, 11,
-  0, 0, 0, 0, 0, 70, 0, 0, 91, 0,
-  38, 0, 8, 0, 0, 4, 0, 0, 64, 10,
-  0, 0, 0, 114, 20, 0, 74, 27, 0, 45,
-  12, 51, 27, 0, 0, 0, 15, 101, 0, 21,
-  22, 36, 22, 0, 57, 0, 0, 0, 62, 0,
-  29, 0, 0, 72, 95, 0, 0, 0, 0, 80,
-  0, 16, 0, 0, 0, 13, 0, 0, 0, 0,
-  0, 0, 0, 33, 0, 3, 0, 0, 0, 0,
-  4, 22, 21, 0, 99, 34, 0, 157, 0, 0,
-  0, 0, 0, 17, 14, 49, 0, 0, 14, 40,
-  0, 1, 5, 82, 30, 0, 0, 0, 0, 0,
-  0, 147, 4, 78, 0, 24, 0, 23, 87, 19,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
-  42, 0, 0, 78, 0, 0, 59, 0, 56, 0,
-  27, 0, 0, 28, 13, 0, 118, 0, 0, 48,
-  0, 113, 0, 36, 68, 0, 0, 7, 28, 0,
-  17, 0, 0, 0, 10, 108, 35, 0, 27, 10,
-  7, 0, 0, 0, 13, 0, 52, 0, 0, 0,
-  0, 5, 41, 0, 0, 0, 0, 82, 0, 16,
-  0, 8, 18, 0, 0, 0, 39, 10, 84, 0,
-  0, 54, 5, 43, 0, 6, 0, 3, 0, 26,
-  104, 21, 0, 47, 20, 66, 0, 0, 53, 0,
-  0, 0, 116, 0, 0, 40, 62, 0, 2, 0,
-  11, 68, 0, 8, 23, 0, 0, 43, 3, 1,
-  13, 72, 0, 27, 24, 0, 0, 21, 96, 5,
-  13, 87, 14, 47, 59, 16, 0, 0, 0, 0,
-  0, 111, 0, 0, 107, 59, 25, 17, 19, 0,
-  0, 13, 9, 35, 0, 93, 0, 0, 13, 0,
-  155, 30, 22, 32, 0, 0, 34, 19, 0, 47,
-  0, 0, 15, 14, 42, 14, 8, 0, 73, 0,
-  0, 0, 0, 2, 0, 0, 31, 0, 21, 50,
-  0, 0, 5, 0, 30, 31, 0, 67, 22, 0,
-  17, 0, 0, 0, 0, 0, 0, 0, 0, 1,
-  0, 3, 0, 16, 53, 0, 3, 16, 0, 0,
-  0, 0, 0, 145, 0, 0, 46, 0, 0, 0,
-  34, 21, 0, 109, 67, 48, 0, 0, 39, 1,
-  0, 58, 0, 0, 0, 56, 1, 0, 0, 0,
-  49, 0, 0, 0, 22, 71, 0, 0, 22, 0,
-  0, 3, 13, 87, 0, 0, 0, 14, 12, 53,
-  23, 0, 62, 19, 29, 0, 0, 0, 0, 48,
-  0, 0, 12, 0, 16, 0, 17, 13, 58, 0,
-  50, 76, 0, 66, 0, 52, 0, 0, 8, 0,
-  17, 64, 0, 25, 19, 0, 22, 2, 35, 128,
-  0, 0, 75, 0, 0, 0, 0, 93, 86, 0,
-  0, 0, 15, 0, 0, 38, 0, 19, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 13, 0, 4, 15, 0, 0, 92, 0,
-  0, 76, 0, 0, 44, 0, 0, 15, 13, 93,
-  0, 13, 41, 74, 27, 0, 22, 35, 4, 32,
-  0, 0, 0, 34, 0, 0, 18, 4, 5, 0,
-  0, 0, 14, 65, 0, 0, 0, 14, 0, 0,
-  0, 18, 0, 0, 0, 0, 19, 112, 26, 0,
-  66, 0, 49, 0, 1, 0, 0, 12, 0, 0,
-  37, 7, 27, 10, 26, 96, 0, 0, 36, 15,
-  0, 30, 0, 21, 0, 0, 0, 0, 33, 83,
-  0, 28, 14, 34, 42, 0, 16, 32, 0, 0,
-  39, 0, 0, 0, 13, 107, 45, 0, 0, 0,
-  3, 18, 0, 20, 0, 5, 17, 0, 0, 0,
-  49, 0, 46, 44, 22, 4, 0, 0, 0, 0,
-  20, 0, 0, 18, 107, 66, 16, 65, 30, 0,
-  0, 17, 71, 14, 28, 0, 85, 0, 0, 80,
-  60, 0, 13, 0, 0, 32, 32, 6, 0, 0,
-  0, 61, 0, 37, 19, 69, 10, 6, 18, 5,
-  0, 44, 103, 0, 0, 23, 0, 23, 18, 0,
-  0, 0, 0, 0, 0, 86, 0, 0, 83, 13,
-  32, 36, 9, 0, 0, 0, 0, 0, 15, 55,
-  0, 0, 11, 0, 91, 19, 43, 55, 0, 39,
-  28, 49, 0, 26, 0, 0, 19, 64, 28, 26,
-  14, 0, 86, 0, 32, 0, 0, 14, 0, 0,
-  66, 0, 5, 67, 43, 0, 9, 0, 0, 58,
-  0, 60, 9, 0, 6, 0, 0, 0, 0, 0,
-  0, 0, 0, 15, 0, 4, 0, 18, 46, 15,
-  12, 30, 14, 0, 60, 29, 0, 164, 0, 0,
-  18, 0, 0, 0, 3, 20, 0, 48, 30, 38,
-  0, 0, 13, 76, 24, 1, 0, 0, 0, 35,
-  0, 48, 0, 88, 0, 0, 0, 20, 63, 58,
-  24, 0, 0, 0, 0, 0, 0, 11, 0, 0,
-  13, 0, 0, 83, 0, 0, 99, 0, 57, 0,
-  22, 0, 0, 57, 14, 0, 110, 0, 0, 29,
-  2, 76, 21, 14, 67, 27, 0, 44, 44, 26,
-  0, 0, 0, 0, 32, 108, 0, 10, 10, 0,
-  11, 0, 10, 13, 0, 0, 58, 0, 30, 0,
-  0, 71, 79, 0, 0, 0, 0, 18, 0, 26,
-  0, 0, 0, 0, 0, 0, 4, 4, 54, 0,
-  0, 35, 0, 18, 0, 0, 0, 17, 0, 23,
-  0, 0, 70, 0, 4, 150, 0, 0, 0, 0,
-  0, 1, 23, 94, 0, 0, 0, 44, 0, 0,
-  21, 54, 0, 39, 0, 0, 0, 0, 0, 45,
-  16, 26, 0, 7, 0, 0, 0, 50, 0, 0,
-  0, 11, 0, 27, 0, 8, 1, 0, 0, 0,
-  12, 123, 0, 0, 39, 0, 39, 0, 42, 0,
-  0, 32, 0, 0, 97, 0, 0, 31, 0, 64,
-  0, 26, 51, 0, 0, 17, 0, 0, 0, 0,
-  0, 0, 27, 70, 21, 0, 16, 15, 54, 0,
-  0, 0, 24, 0, 2, 0, 0, 0, 0, 60,
-  12, 0, 0, 0, 0, 79, 0, 14, 0, 5,
-  25, 0, 0, 14, 51, 41, 105, 41, 29, 52,
-  23, 0, 0, 0, 17, 23, 0, 13, 59, 1,
-  72, 42, 0, 0, 0, 22, 38, 13, 13, 6,
-  0, 7, 0, 21, 38, 13, 14, 0, 0, 64,
-  43, 11, 0, 0, 1, 54, 0, 38, 0, 39,
-  17, 0, 12, 19, 36, 29, 3, 0, 0, 0,
-  0, 0, 0, 11, 0, 0, 0, 0, 0, 70,
-  0, 0, 91, 0, 38, 0, 8, 0, 0, 4,
-  0, 0, 64, 10, 0, 0, 0, 114, 20, 0,
-  74, 27, 0, 45, 12, 51, 27, 0, 0, 0,
-  15, 101, 0, 21, 22, 36, 22, 0, 57, 0,
-  0, 0, 62, 0, 29, 0, 0, 72, 95, 0,
-  0, 0, 0, 80, 0, 16, 0, 0, 0, 13,
-  0, 0, 0, 0, 0, 0, 0, 33, 0, 3,
-  0, 0, 0, 0, 4, 22, 21, 0, 99, 34,
-  0, 157, 0, 0, 0, 0, 0, 17, 14, 49,
-  0, 0, 14, 40, 0, 1, 5, 82, 30, 0,
-  0, 0, 0, 0, 0, 147, 4, 78, 0, 24,
-  0, 23, 87, 19, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 3, 42, 0, 0, 78, 0, 0,
-  59, 0, 56, 0, 27, 0, 0, 28, 13, 0,
-  118, 0, 0, 48, 0, 113, 0, 36, 68, 0,
-  0, 7, 28, 0, 17, 0, 0, 0, 10, 108,
-  35, 0, 27, 10, 7, 0, 0, 0, 13, 0,
-  52, 0, 0, 0, 0, 5, 41, 0, 0, 0,
-  0, 82, 0, 16, 0, 8, 18, 0, 0, 0,
-  39, 10, 84, 0, 0, 54, 5, 43, 0, 6,
-  0, 3, 0, 26, 0, 9, 38, 0, 15, 120,
-  0, 0, 0, 0, 0, 3, 58, 72, 0, 0,
-  0, 18, 0, 18, 44, 0, 0, 51, 0, 3,
-  0, 0, 0, 91, 41, 0, 0, 22, 0, 0,
-  0, 22, 0, 25, 0, 45, 0, 53, 1, 0,
-  0, 32, 0, 0, 0, 70, 11, 0, 0, 0,
-  19, 0, 13, 14, 0, 9, 0, 0, 0, 0,
-  0, 11, 0, 0, 0, 58, 10, 0, 0, 20,
-  0, 0, 2, 19, 0, 27, 10, 28, 51, 0,
-  32, 5, 54, 4, 0, 0, 52, 5, 0, 37,
-  0, 0, 0, 30, 0, 0, 0, 0, 3, 4,
-  0, 16, 10, 25, 57, 0, 0, 17, 37, 0,
-  63, 43, 24, 47, 55, 1, 2, 0, 25, 2,
-  0, 0, 0, 0, 0, 0, 0, 145, 0, 0,
-  46, 0, 0, 0, 34, 21, 0, 109, 67, 48,
-  0, 0, 39, 1, 0, 58, 0, 0, 0, 56,
-  1, 0, 0, 0, 49, 0, 0, 0, 22, 71,
-  0, 0, 22, 0, 0, 3, 13, 87, 0, 0,
-  0, 14, 12, 53, 23, 0, 62, 19, 29, 0,
-  0, 0, 0, 48, 0, 0, 12, 0, 16, 0,
-  17, 13, 58, 0, 50, 76, 0, 66, 0, 52,
-  0, 0, 8, 0, 17, 64, 0, 25, 19, 0,
-  22, 2, 35, 128, 0, 0, 75, 0, 0, 0,
-  0, 93, 86, 0, 0, 0, 15, 0, 0, 38,
-  0, 19, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 13, 0, 4, 15,
-  0, 0, 92, 0, 0, 76, 0, 0, 44, 0,
-  0, 15, 13, 93, 0, 13, 41, 74, 27, 0,
-  22, 35, 4, 32, 0, 0, 0, 34, 0, 0,
-  18, 4, 5, 0, 0, 0, 14, 65, 0, 0,
-  0, 14, 0, 0, 0, 18, 0, 0, 0, 0,
-  19, 112, 26, 0, 66, 0, 49, 0, 1, 0,
-  0, 12, 0, 0, 37, 7, 27, 10, 26, 96,
-  0, 0, 36, 15, 0, 30, 0, 21, 0, 0,
-  0, 0, 33, 83, 0, 28, 14, 34, 42, 0,
-  16, 32, 0, 0, 39, 0, 0, 0, 13, 107,
-  45, 0, 0, 0, 3, 18, 0, 20, 0, 5,
-  17, 0, 0, 0, 49, 0, 46, 44, 22, 4,
-  0, 0, 0, 0, 20, 0, 0, 18, 0, 0,
-  91, 0, 0, 56, 0, 0, 0, 0, 0, 21,
-  6, 68, 0, 0, 3, 66, 22, 26, 0, 44,
-  1, 12, 25, 0, 0, 0, 0, 0, 35, 19,
-  0, 0, 0, 0, 0, 41, 0, 0, 0, 9,
-  0, 13, 0, 4, 17, 0, 0, 0, 11, 90,
-  12, 0, 37, 0, 34, 0, 44, 0, 0, 20,
-  0, 0, 71, 0, 0, 58, 0, 66, 0, 22,
-  34, 0, 4, 12, 0, 0, 14, 0, 0, 0,
-  11, 67, 48, 0, 47, 25, 46, 0, 0, 0,
-  0, 0, 2, 0, 0, 5, 16, 47, 0, 0,
-  0, 1, 0, 93, 0, 9, 0, 23, 27, 12,
-  0, 4, 70, 6, 57, 62, 45, 37, 28, 1,
-  0, 0, 18, 8, 3, 27, 14, 0, 60, 29,
-  0, 164, 0, 0, 18, 0, 0, 0, 3, 20,
-  0, 48, 30, 38, 0, 0, 13, 76, 24, 1,
-  0, 0, 0, 35, 0, 48, 0, 88, 0, 0,
-  0, 20, 63, 58, 24, 0, 0, 0, 0, 0,
-  0, 11, 0, 0, 13, 0, 0, 83, 0, 0,
-  99, 0, 57, 0, 22, 0, 0, 57, 14, 0,
-  110, 0, 0, 29, 2, 76, 21, 14, 67, 27,
-  0, 44, 44, 26, 0, 0, 0, 0, 32, 108,
-  0, 10, 10, 0, 11, 0, 10, 13, 0, 0,
-  58, 0, 30, 0, 0, 71, 79, 0, 0, 0,
-  0, 18, 0, 26, 0, 0, 0, 0, 0, 0,
-  4, 4, 54, 0, 0, 35, 0, 18, 0, 0,
-  0, 17, 0, 23, 0, 0, 70, 0, 4, 150,
-  0, 0, 0, 0, 0, 1, 23, 94, 0, 0,
-  0, 44, 0, 0, 21, 54, 0, 39, 0, 0,
-  0, 0, 0, 45, 16, 26, 0, 7, 0, 0,
-  0, 50, 0, 0, 0, 11, 0, 27, 0, 8,
-  1, 0, 0, 0, 12, 123, 0, 0, 39, 0,
-  39, 0, 42, 0, 0, 32, 0, 0, 97, 0,
-  0, 31, 0, 64, 0, 26, 51, 0, 0, 17,
-  0, 0, 0, 0, 0, 0, 27, 70, 21, 0,
-  16, 15, 54, 0, 0, 0, 24, 0, 2, 0,
-  0, 0, 0, 60, 12, 0, 0, 0, 0, 79,
-  0, 14, 0, 5, 25, 0, 0, 14, 51, 41,
-  105, 41, 29, 52, 23, 0, 0, 0, 17, 23,
-  0, 13, 0, 43, 48, 0, 24, 32, 13, 0,
-  8, 0, 0, 0, 63, 49, 0, 0, 3, 17,
-  8, 10, 0, 0, 0, 37, 41, 35, 6, 0,
-  0, 48, 48, 0, 0, 14, 0, 0, 0, 2,
-  0, 39, 0, 40, 0, 41, 21, 0, 3, 0,
-  0, 0, 0, 40, 61, 0, 0, 0, 14, 6,
-  2, 35, 0, 6, 0, 21, 0, 0, 0, 27,
-  0, 0, 0, 32, 20, 0, 21, 28, 0, 0,
-  0, 25, 16, 25, 21, 40, 63, 0, 39, 18,
-  50, 13, 0, 0, 32, 28, 0, 22, 0, 38,
-  15, 31, 0, 0, 0, 0, 0, 28, 14, 0,
-  53, 57, 40, 0, 0, 20, 46, 0, 33, 38,
-  62, 29, 61, 16, 47, 0, 46, 37, 0, 1,
-  21, 0, 99, 34, 0, 157, 0, 0, 0, 0,
-  0, 17, 14, 49, 0, 0, 14, 40, 0, 1,
-  5, 82, 30, 0, 0, 0, 0, 0, 0, 147,
-  4, 78, 0, 24, 0, 23, 87, 19, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 3, 42, 0,
-  0, 78, 0, 0, 59, 0, 56, 0, 27, 0,
-  0, 28, 13, 0, 118, 0, 0, 48, 0, 113,
-  0, 36, 68, 0, 0, 7, 28, 0, 17, 0,
-  0, 0, 10, 108, 35, 0, 27, 10, 7, 0,
-  0, 0, 13, 0, 52, 0, 0, 0, 0, 5,
-  41, 0, 0, 0, 0, 82, 0, 16, 0, 8,
-  18, 0, 0, 0, 39, 10, 84, 0, 0, 54,
-  5, 43, 0, 6, 0, 3, 0, 26, 0, 9,
-  38, 0, 15, 120, 0, 0, 0, 0, 0, 3,
-  58, 72, 0, 0, 0, 18, 0, 18, 44, 0,
-  0, 51, 0, 3, 0, 0, 0, 91, 41, 0,
-  0, 22, 0, 0, 0, 22, 0, 25, 0, 45,
-  0, 53, 1, 0, 0, 32, 0, 0, 0, 70,
-  11, 0, 0, 0, 19, 0, 13, 14, 0, 9,
-  0, 0, 0, 0, 0, 11, 0, 0, 0, 58,
-  10, 0, 0, 20, 0, 0, 2, 19, 0, 27,
-  10, 28, 51, 0, 32, 5, 54, 4, 0, 0,
-  52, 5, 0, 37, 0, 0, 0, 30, 0, 0,
-  0, 0, 3, 4, 0, 16, 10, 25, 57, 0,
-  0, 17, 37, 0, 63, 43, 24, 47, 55, 1,
-  2, 0, 25, 2, 0, 0, 0, 70, 65, 0,
-  63, 0, 15, 0, 1, 0, 14, 0, 64, 75,
-  0, 51, 17, 7, 26, 16, 9, 0, 0, 47,
-  38, 59, 0, 0, 0, 0, 53, 0, 0, 37,
-  12, 0, 0, 0, 0, 53, 50, 43, 24, 71,
-  73, 0, 0, 0, 0, 0, 0, 26, 50, 0,
-  0, 0, 0, 20, 1, 27, 24, 0, 0, 63,
-  0, 2, 29, 0, 0, 0, 0, 0, 7, 41,
-  16, 12, 0, 17, 0, 23, 46, 34, 33, 22,
-  87, 14, 32, 4, 49, 40, 0, 20, 24, 31,
-  0, 54, 0, 35, 3, 41, 0, 0, 0, 0,
-  0, 0, 7, 10, 34, 32, 82, 0, 0, 13,
-  31, 0, 0, 29, 54, 8, 7, 0, 55, 0,
-  75, 11, 2, 0, 0, 0, 92, 0, 0, 76,
-  0, 0, 44, 0, 0, 15, 13, 93, 0, 13,
-  41, 74, 27, 0, 22, 35, 4, 32, 0, 0,
-  0, 34, 0, 0, 18, 4, 5, 0, 0, 0,
-  14, 65, 0, 0, 0, 14, 0, 0, 0, 18,
-  0, 0, 0, 0, 19, 112, 26, 0, 66, 0,
-  49, 0, 1, 0, 0, 12, 0, 0, 37, 7,
-  27, 10, 26, 96, 0, 0, 36, 15, 0, 30,
-  0, 21, 0, 0, 0, 0, 33, 83, 0, 28,
-  14, 34, 42, 0, 16, 32, 0, 0, 39, 0,
-  0, 0, 13, 107, 45, 0, 0, 0, 3, 18,
-  0, 20, 0, 5, 17, 0, 0, 0, 49, 0,
-  46, 44, 22, 4, 0, 0, 0, 0, 20, 0,
-  0, 18, 0, 0, 91, 0, 0, 56, 0, 0,
-  0, 0, 0, 21, 6, 68, 0, 0, 3, 66,
-  22, 26, 0, 44, 1, 12, 25, 0, 0, 0,
-  0, 0, 35, 19, 0, 0, 0, 0, 0, 41,
-  0, 0, 0, 9, 0, 13, 0, 4, 17, 0,
-  0, 0, 11, 90, 12, 0, 37, 0, 34, 0,
-  44, 0, 0, 20, 0, 0, 71, 0, 0, 58,
-  0, 66, 0, 22, 34, 0, 4, 12, 0, 0,
-  14, 0, 0, 0, 11, 67, 48, 0, 47, 25,
-  46, 0, 0, 0, 0, 0, 2, 0, 0, 5,
-  16, 47, 0, 0, 0, 1, 0, 93, 0, 9,
-  0, 23, 27, 12, 0, 4, 70, 6, 57, 62,
-  45, 37, 28, 1, 0, 0, 18, 8, 3, 27,
-  0, 16, 49, 0, 0, 5, 31, 0, 1, 0,
-  0, 6, 0, 41, 0, 0, 0, 25, 35, 4,
-  0, 0, 0, 52, 24, 0, 16, 5, 179, 11,
-  21, 0, 23, 0, 0, 0, 0, 11, 0, 43,
-  0, 24, 1, 8, 2, 65, 31, 0, 0, 0,
-  0, 37, 49, 0, 7, 0, 6, 0, 40, 14,
-  28, 28, 0, 0, 0, 18, 44, 18, 0, 7,
-  0, 39, 35, 0, 13, 18, 0, 0, 20, 0,
-  17, 2, 0, 51, 0, 0, 32, 30, 78, 35,
-  0, 0, 40, 0, 0, 22, 0, 0, 33, 23,
-  14, 18, 8, 0, 15, 74, 44, 16, 21, 36,
-  0, 12, 0, 0, 6, 34, 56, 40, 46, 34,
-  33, 8, 0, 0, 18, 0, 14, 30, 0, 0,
-  70, 0, 4, 150, 0, 0, 0, 0, 0, 1,
-  23, 94, 0, 0, 0, 44, 0, 0, 21, 54,
-  0, 39, 0, 0, 0, 0, 0, 45, 16, 26,
-  0, 7, 0, 0, 0, 50, 0, 0, 0, 11,
-  0, 27, 0, 8, 1, 0, 0, 0, 12, 123,
-  0, 0, 39, 0, 39, 0, 42, 0, 0, 32,
-  0, 0, 97, 0, 0, 31, 0, 64, 0, 26,
-  51, 0, 0, 17, 0, 0, 0, 0, 0, 0,
-  27, 70, 21, 0, 16, 15, 54, 0, 0, 0,
-  24, 0, 2, 0, 0, 0, 0, 60, 12, 0,
-  0, 0, 0, 79, 0, 14, 0, 5, 25, 0,
-  0, 14, 51, 41, 105, 41, 29, 52, 23, 0,
-  0, 0, 17, 23, 0, 13, 0, 43, 48, 0,
-  24, 32, 13, 0, 8, 0, 0, 0, 63, 49,
-  0, 0, 3, 17, 8, 10, 0, 0, 0, 37,
-  41, 35, 6, 0, 0, 48, 48, 0, 0, 14,
-  0, 0, 0, 2, 0, 39, 0, 40, 0, 41,
-  21, 0, 3, 0, 0, 0, 0, 40, 61, 0,
-  0, 0, 14, 6, 2, 35, 0, 6, 0, 21,
-  0, 0, 0, 27, 0, 0, 0, 32, 20, 0,
-  21, 28, 0, 0, 0, 25, 16, 25, 21, 40,
-  63, 0, 39, 18, 50, 13, 0, 0, 32, 28,
-  0, 22, 0, 38, 15, 31, 0, 0, 0, 0,
-  0, 28, 14, 0, 53, 57, 40, 0, 0, 20,
-  46, 0, 33, 38, 62, 29, 61, 16, 47, 0,
-  46, 37, 0, 1, 0, 41, 74, 0, 7, 0,
-  37, 0, 26, 0, 0, 0, 8, 45, 0, 15,
-  14, 0, 13, 0, 0, 0, 20, 55, 23, 53,
-  16, 0, 159, 1, 19, 0, 8, 19, 20, 0,
-  0, 0, 0, 81, 7, 52, 28, 35, 49, 21,
-  9, 3, 0, 0, 0, 24, 50, 0, 0, 0,
-  1, 33, 4, 24, 7, 14, 0, 0, 0, 27,
-  51, 0, 10, 0, 0, 31, 38, 26, 32, 14,
-  0, 0, 0, 32, 48, 29, 26, 13, 31, 0,
-  3, 25, 74, 17, 4, 0, 45, 17, 0, 32,
-  0, 0, 21, 15, 0, 0, 0, 0, 6, 22,
-  50, 8, 38, 32, 47, 0, 0, 0, 1, 0,
-  13, 0, 30, 2, 0, 0, 24, 0, 46, 24,
-  32, 0, 0, 9, 38, 0, 15, 120, 0, 0,
-  0, 0, 0, 3, 58, 72, 0, 0, 0, 18,
-  0, 18, 44, 0, 0, 51, 0, 3, 0, 0,
-  0, 91, 41, 0, 0, 22, 0, 0, 0, 22,
-  0, 25, 0, 45, 0, 53, 1, 0, 0, 32,
-  0, 0, 0, 70, 11, 0, 0, 0, 19, 0,
-  13, 14, 0, 9, 0, 0, 0, 0, 0, 11,
-  0, 0, 0, 58, 10, 0, 0, 20, 0, 0,
-  2, 19, 0, 27, 10, 28, 51, 0, 32, 5,
-  54, 4, 0, 0, 52, 5, 0, 37, 0, 0,
-  0, 30, 0, 0, 0, 0, 3, 4, 0, 16,
-  10, 25, 57, 0, 0, 17, 37, 0, 63, 43,
-  24, 47, 55, 1, 2, 0, 25, 2, 0, 0,
-  0, 70, 65, 0, 63, 0, 15, 0, 1, 0,
-  14, 0, 64, 75, 0, 51, 17, 7, 26, 16,
-  9, 0, 0, 47, 38, 59, 0, 0, 0, 0,
-  53, 0, 0, 37, 12, 0, 0, 0, 0, 53,
-  50, 43, 24, 71, 73, 0, 0, 0, 0, 0,
-  0, 26, 50, 0, 0, 0, 0, 20, 1, 27,
-  24, 0, 0, 63, 0, 2, 29, 0, 0, 0,
-  0, 0, 7, 41, 16, 12, 0, 17, 0, 23,
-  46, 34, 33, 22, 87, 14, 32, 4, 49, 40,
-  0, 20, 24, 31, 0, 54, 0, 35, 3, 41,
-  0, 0, 0, 0, 0, 0, 7, 10, 34, 32,
-  82, 0, 0, 13, 31, 0, 0, 29, 54, 8,
-  7, 0, 55, 0, 75, 11, 2, 0, 0, 0,
-  119, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 103, 0, 9, 0, 6, 10, 5, 9, 50,
-  108, 24, 0, 0, 0, 8, 184, 0, 22, 0,
-  0, 31, 0, 0, 11, 12, 0, 10, 106, 0,
-  19, 21, 57, 33, 0, 2, 16, 0, 0, 65,
-  0, 0, 30, 0, 14, 26, 31, 0, 30, 40,
-  20, 0, 16, 5, 36, 0, 0, 70, 0, 0,
-  38, 61, 0, 0, 13, 0, 0, 0, 25, 10,
-  0, 19, 7, 11, 0, 47, 49, 0, 0, 54,
-  39, 0, 33, 24, 0, 0, 0, 22, 19, 7,
-  17, 0, 40, 27, 0, 5, 0, 0, 50, 3,
-  0, 0, 37, 20, 52, 0, 0, 30, 0, 0,
-  0, 0, 2, 25, 2, 0, 0, 0, 91, 0,
-  0, 56, 0, 0, 0, 0, 0, 21, 6, 68,
-  0, 0, 3, 66, 22, 26, 0, 44, 1, 12,
-  25, 0, 0, 0, 0, 0, 35, 19, 0, 0,
-  0, 0, 0, 41, 0, 0, 0, 9, 0, 13,
-  0, 4, 17, 0, 0, 0, 11, 90, 12, 0,
-  37, 0, 34, 0, 44, 0, 0, 20, 0, 0,
-  71, 0, 0, 58, 0, 66, 0, 22, 34, 0,
-  4, 12, 0, 0, 14, 0, 0, 0, 11, 67,
-  48, 0, 47, 25, 46, 0, 0, 0, 0, 0,
-  2, 0, 0, 5, 16, 47, 0, 0, 0, 1,
-  0, 93, 0, 9, 0, 23, 27, 12, 0, 4,
-  70, 6, 57, 62, 45, 37, 28, 1, 0, 0,
-  18, 8, 3, 27, 0, 16, 49, 0, 0, 5,
-  31, 0, 1, 0, 0, 6, 0, 41, 0, 0,
-  0, 25, 35, 4, 0, 0, 0, 52, 24, 0,
-  16, 5, 179, 11, 21, 0, 23, 0, 0, 0,
-  0, 11, 0, 43, 0, 24, 1, 8, 2, 65,
-  31, 0, 0, 0, 0, 37, 49, 0, 7, 0,
-  6, 0, 40, 14, 28, 28, 0, 0, 0, 18,
-  44, 18, 0, 7, 0, 39, 35, 0, 13, 18,
-  0, 0, 20, 0, 17, 2, 0, 51, 0, 0,
-  32, 30, 78, 35, 0, 0, 40, 0, 0, 22,
-  0, 0, 33, 23, 14, 18, 8, 0, 15, 74,
-  44, 16, 21, 36, 0, 12, 0, 0, 6, 34,
-  56, 40, 46, 34, 33, 8, 0, 0, 18, 0,
-  14, 30, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 43, 48, 0, 24, 32, 13, 0, 8, 0,
-  0, 0, 63, 49, 0, 0, 3, 17, 8, 10,
-  0, 0, 0, 37, 41, 35, 6, 0, 0, 48,
-  48, 0, 0, 14, 0, 0, 0, 2, 0, 39,
-  0, 40, 0, 41, 21, 0, 3, 0, 0, 0,
-  0, 40, 61, 0, 0, 0, 14, 6, 2, 35,
-  0, 6, 0, 21, 0, 0, 0, 27, 0, 0,
-  0, 32, 20, 0, 21, 28, 0, 0, 0, 25,
-  16, 25, 21, 40, 63, 0, 39, 18, 50, 13,
-  0, 0, 32, 28, 0, 22, 0, 38, 15, 31,
-  0, 0, 0, 0, 0, 28, 14, 0, 53, 57,
-  40, 0, 0, 20, 46, 0, 33, 38, 62, 29,
-  61, 16, 47, 0, 46, 37, 0, 1, 0, 41,
-  74, 0, 7, 0, 37, 0, 26, 0, 0, 0,
-  8, 45, 0, 15, 14, 0, 13, 0, 0, 0,
-  20, 55, 23, 53, 16, 0, 159, 1, 19, 0,
-  8, 19, 20, 0, 0, 0, 0, 81, 7, 52,
-  28, 35, 49, 21, 9, 3, 0, 0, 0, 24,
-  50, 0, 0, 0, 1, 33, 4, 24, 7, 14,
-  0, 0, 0, 27, 51, 0, 10, 0, 0, 31,
-  38, 26, 32, 14, 0, 0, 0, 32, 48, 29,
-  26, 13, 31, 0, 3, 25, 74, 17, 4, 0,
-  45, 17, 0, 32, 0, 0, 21, 15, 0, 0,
-  0, 0, 6, 22, 50, 8, 38, 32, 47, 0,
-  0, 0, 1, 0, 13, 0, 30, 2, 0, 0,
-  24, 0, 46, 24, 32, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 70, 65, 0, 63, 0,
-  15, 0, 1, 0, 14, 0, 64, 75, 0, 51,
-  17, 7, 26, 16, 9, 0, 0, 47, 38, 59,
-  0, 0, 0, 0, 53, 0, 0, 37, 12, 0,
-  0, 0, 0, 53, 50, 43, 24, 71, 73, 0,
-  0, 0, 0, 0, 0, 26, 50, 0, 0, 0,
-  0, 20, 1, 27, 24, 0, 0, 63, 0, 2,
-  29, 0, 0, 0, 0, 0, 7, 41, 16, 12,
-  0, 17, 0, 23, 46, 34, 33, 22, 87, 14,
-  32, 4, 49, 40, 0, 20, 24, 31, 0, 54,
-  0, 35, 3, 41, 0, 0, 0, 0, 0, 0,
-  7, 10, 34, 32, 82, 0, 0, 13, 31, 0,
-  0, 29, 54, 8, 7, 0, 55, 0, 75, 11,
-  2, 0, 0, 0, 119, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 103, 0, 9, 0, 6,
-  10, 5, 9, 50, 108, 24, 0, 0, 0, 8,
-  184, 0, 22, 0, 0, 31, 0, 0, 11, 12,
-  0, 10, 106, 0, 19, 21, 57, 33, 0, 2,
-  16, 0, 0, 65, 0, 0, 30, 0, 14, 26,
-  31, 0, 30, 40, 20, 0, 16, 5, 36, 0,
-  0, 70, 0, 0, 38, 61, 0, 0, 13, 0,
-  0, 0, 25, 10, 0, 19, 7, 11, 0, 47,
-  49, 0, 0, 54, 39, 0, 33, 24, 0, 0,
-  0, 22, 19, 7, 17, 0, 40, 27, 0, 5,
-  0, 0, 50, 3, 0, 0, 37, 20, 52, 0,
-  0, 30, 0, 0, 0, 0, 2, 25, 2, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 47, 23, 86, 28,
-  0, 0, 29, 6, 18, 0, 12, 0, 0, 94,
-  0, 55, 94, 25, 14, 29, 7, 39, 13, 18,
-  25, 0, 29, 32, 164, 9, 5, 45, 79, 0,
-  0, 0, 0, 37, 0, 0, 0, 4, 0, 10,
-  7, 71, 53, 0, 0, 0, 0, 40, 22, 15,
-  17, 0, 13, 0, 0, 3, 39, 29, 0, 0,
-  0, 0, 72, 0, 119, 51, 0, 0, 21, 0,
-  24, 0, 65, 11, 0, 23, 14, 0, 42, 0,
-  0, 26, 0, 0, 59, 5, 0, 16, 0, 5,
-  15, 0, 38, 1, 14, 93, 25, 0, 14, 51,
-  54, 47, 12, 0, 25, 0, 4, 10, 0, 41,
-  10, 0, 18, 0, 17, 0, 59, 0, 0, 0,
-  0, 24, 48, 21, 43, 69, 0, 8, 5, 11,
-  0, 0, 0, 0, 0, 0, 16, 73, 0, 0,
-  82, 18, 0, 0, 0, 41, 0, 50, 15, 0,
-  5, 16, 0, 0, 0, 19, 83, 23, 0, 0,
-  0, 9, 0, 0, 0, 6, 0, 0, 9, 74,
-  35, 102, 0, 0, 0, 29, 56, 0, 22, 0,
-  18, 0, 0, 0, 78, 24, 0, 51, 0, 0,
-  97, 0, 107, 49, 0, 0, 4, 13, 45, 0,
-  27, 0, 0, 5, 25, 0, 35, 12, 0, 12,
-  0, 6, 0, 6, 0, 26, 0, 19, 1, 0,
-  34, 0, 12, 95, 20, 81, 35, 21, 44, 44,
-  10, 0, 51, 0, 0, 63, 0, 7, 0, 0,
-  0, 0, 11, 0, 22, 0, 33, 0, 0, 27,
-  27, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  23, 32, 93, 27, 1, 9, 26, 5, 18, 0,
-  0, 0, 0, 103, 0, 30, 67, 4, 0, 16,
-  13, 75, 10, 41, 20, 0, 6, 20, 201, 42,
-  3, 62, 71, 0, 24, 0, 0, 56, 0, 4,
-  5, 32, 0, 22, 9, 88, 48, 0, 0, 0,
-  0, 51, 21, 3, 55, 0, 44, 0, 32, 0,
-  31, 72, 0, 0, 0, 0, 48, 9, 120, 30,
-  0, 10, 58, 0, 32, 0, 53, 0, 0, 37,
-  0, 0, 36, 11, 0, 15, 0, 0, 58, 5,
-  0, 0, 0, 3, 0, 36, 0, 0, 40, 101,
-  17, 0, 0, 52, 55, 89, 20, 0, 9, 0,
-  2, 9, 0, 33, 6, 2, 40, 0, 19, 12,
-  51, 0, 0, 0, 3, 0, 39, 30, 0, 67,
-  0, 11, 0, 33, 2, 0, 0, 0, 0, 17,
-  28, 49, 0, 0, 52, 3, 0, 0, 28, 58,
-  0, 42, 19, 0, 0, 8, 0, 9, 0, 26,
-  82, 21, 0, 0, 0, 27, 0, 8, 0, 40,
-  0, 22, 24, 91, 9, 110, 0, 0, 0, 27,
-  50, 0, 37, 0, 28, 0, 14, 0, 55, 50,
-  0, 43, 0, 0, 49, 11, 81, 0, 4, 0,
-  22, 7, 42, 0, 12, 0, 0, 26, 21, 0,
-  21, 24, 0, 0, 0, 0, 0, 9, 0, 0,
-  0, 9, 0, 20, 0, 0, 47, 83, 0, 52,
-  17, 21, 41, 51, 25, 0, 40, 5, 0, 40,
-  0, 11, 0, 0, 21, 0, 13, 13, 31, 0,
-  15, 0, 35, 1, 15, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 13, 24, 67, 6, 0, 18,
-  27, 22, 0, 0, 0, 0, 0, 97, 0, 0,
-  60, 4, 0, 5, 27, 86, 27, 52, 0, 0,
-  8, 9, 193, 55, 1, 28, 52, 0, 59, 1,
-  0, 58, 0, 17, 14, 39, 0, 14, 26, 83,
-  17, 0, 2, 0, 0, 64, 30, 0, 71, 0,
-  60, 0, 49, 0, 15, 71, 0, 0, 0, 0,
-  7, 6, 77, 33, 0, 22, 82, 11, 31, 27,
-  25, 0, 20, 13, 0, 0, 15, 5, 0, 0,
-  0, 0, 62, 3, 0, 0, 23, 0, 15, 37,
-  0, 0, 49, 67, 15, 0, 0, 37, 46, 75,
-  26, 0, 0, 6, 1, 16, 0, 37, 12, 0,
-  55, 0, 9, 28, 40, 0, 0, 0, 4, 0,
-  26, 26, 0, 60, 0, 15, 0, 5, 36, 23,
-  2, 0, 0, 31, 86, 8, 0, 0, 59, 11,
-  0, 0, 65, 56, 0, 25, 23, 0, 0, 13,
-  0, 13, 0, 11, 92, 0, 18, 0, 0, 32,
-  0, 53, 0, 28, 0, 44, 48, 94, 4, 86,
-  0, 7, 0, 38, 52, 0, 35, 0, 21, 0,
-  24, 0, 13, 27, 0, 40, 0, 11, 10, 0,
-  33, 0, 8, 0, 25, 13, 37, 0, 0, 0,
-  0, 15, 39, 0, 14, 13, 0, 0, 0, 0,
-  0, 24, 0, 0, 0, 13, 0, 47, 0, 0,
-  62, 50, 3, 0, 0, 13, 20, 1, 44, 0,
-  24, 28, 0, 29, 0, 15, 0, 0, 25, 0,
-  11, 10, 47, 0, 42, 0, 79, 0, 14, 0,
-  47, 23, 86, 28, 0, 0, 29, 6, 18, 0,
-  12, 0, 0, 94, 0, 55, 94, 25, 14, 29,
-  7, 39, 13, 18, 25, 0, 29, 32, 164, 9,
-  5, 45, 79, 0, 0, 0, 0, 37, 0, 0,
-  0, 4, 0, 10, 7, 71, 53, 0, 0, 0,
-  0, 40, 22, 15, 17, 0, 13, 0, 0, 3,
-  39, 29, 0, 0, 0, 0, 72, 0, 119, 51,
-  0, 0, 21, 0, 24, 0, 65, 11, 0, 23,
-  14, 0, 42, 0, 0, 26, 0, 0, 59, 5,
-  0, 16, 0, 5, 15, 0, 38, 1, 14, 93,
-  25, 0, 14, 51, 54, 47, 12, 0, 25, 0,
-  4, 10, 0, 41, 10, 0, 18, 0, 17, 0,
-  59, 0, 0, 0, 0, 24, 48, 21, 43, 69,
-  0, 8, 5, 11, 0, 0, 0, 0, 0, 0,
-  16, 73, 0, 0, 82, 18, 0, 0, 0, 41,
-  0, 50, 15, 0, 5, 16, 0, 0, 0, 19,
-  83, 23, 0, 0, 0, 9, 0, 0, 0, 6,
-  0, 0, 9, 74, 35, 102, 0, 0, 0, 29,
-  56, 0, 22, 0, 18, 0, 0, 0, 78, 24,
-  0, 51, 0, 0, 97, 0, 107, 49, 0, 0,
-  4, 13, 45, 0, 27, 0, 0, 5, 25, 0,
-  35, 12, 0, 12, 0, 6, 0, 6, 0, 26,
-  0, 19, 1, 0, 34, 0, 12, 95, 20, 81,
-  35, 21, 44, 44, 10, 0, 51, 0, 0, 63,
-  0, 7, 0, 0, 0, 0, 11, 0, 22, 0,
-  33, 0, 0, 27, 27, 0, 0, 39, 39, 29,
-  0, 48, 7, 15, 23, 0, 0, 11, 81, 0,
-  0, 23, 58, 7, 0, 0, 0, 63, 0, 21,
-  41, 0, 0, 12, 0, 0, 0, 32, 67, 3,
-  1, 0, 0, 13, 0, 47, 0, 18, 41, 13,
-  22, 69, 25, 53, 0, 12, 0, 37, 21, 7,
-  22, 0, 22, 0, 0, 0, 16, 31, 0, 29,
-  0, 0, 7, 0, 37, 0, 18, 0, 9, 21,
-  4, 0, 5, 11, 0, 39, 27, 0, 62, 62,
-  0, 0, 0, 0, 0, 18, 1, 0, 0, 19,
-  0, 19, 32, 0, 0, 78, 11, 0, 0, 10,
-  15, 0, 33, 0, 0, 0, 0, 8, 0, 0,
-  0, 0, 7, 0, 0, 0, 0, 0, 38, 0,
-  39, 0, 9, 0, 23, 32, 93, 27, 1, 9,
-  26, 5, 18, 0, 0, 0, 0, 103, 0, 30,
-  67, 4, 0, 16, 13, 75, 10, 41, 20, 0,
-  6, 20, 201, 42, 3, 62, 71, 0, 24, 0,
-  0, 56, 0, 4, 5, 32, 0, 22, 9, 88,
-  48, 0, 0, 0, 0, 51, 21, 3, 55, 0,
-  44, 0, 32, 0, 31, 72, 0, 0, 0, 0,
-  48, 9, 120, 30, 0, 10, 58, 0, 32, 0,
-  53, 0, 0, 37, 0, 0, 36, 11, 0, 15,
-  0, 0, 58, 5, 0, 0, 0, 3, 0, 36,
-  0, 0, 40, 101, 17, 0, 0, 52, 55, 89,
-  20, 0, 9, 0, 2, 9, 0, 33, 6, 2,
-  40, 0, 19, 12, 51, 0, 0, 0, 3, 0,
-  39, 30, 0, 67, 0, 11, 0, 33, 2, 0,
-  0, 0, 0, 17, 28, 49, 0, 0, 52, 3,
-  0, 0, 28, 58, 0, 42, 19, 0, 0, 8,
-  0, 9, 0, 26, 82, 21, 0, 0, 0, 27,
-  0, 8, 0, 40, 0, 22, 24, 91, 9, 110,
-  0, 0, 0, 27, 50, 0, 37, 0, 28, 0,
-  14, 0, 55, 50, 0, 43, 0, 0, 49, 11,
-  81, 0, 4, 0, 22, 7, 42, 0, 12, 0,
-  0, 26, 21, 0, 21, 24, 0, 0, 0, 0,
-  0, 9, 0, 0, 0, 9, 0, 20, 0, 0,
-  47, 83, 0, 52, 17, 21, 41, 51, 25, 0,
-  40, 5, 0, 40, 0, 11, 0, 0, 21, 0,
-  13, 13, 31, 0, 15, 0, 35, 1, 15, 0,
-  0, 27, 36, 37, 0, 42, 17, 9, 15, 0,
-  0, 22, 97, 0, 7, 27, 55, 8, 0, 0,
-  0, 69, 0, 8, 46, 0, 0, 20, 0, 2,
-  0, 37, 78, 0, 3, 0, 0, 24, 0, 73,
-  0, 34, 30, 29, 29, 57, 25, 42, 0, 28,
-  0, 43, 34, 9, 17, 0, 10, 0, 0, 0,
-  6, 14, 0, 16, 0, 0, 0, 0, 28, 0,
-  23, 6, 0, 10, 7, 0, 0, 23, 0, 35,
-  38, 0, 52, 56, 0, 0, 11, 0, 0, 18,
-  0, 0, 0, 4, 0, 16, 29, 0, 0, 66,
-  6, 0, 0, 10, 18, 0, 38, 0, 0, 6,
-  0, 7, 0, 1, 0, 0, 17, 0, 0, 0,
-  5, 0, 43, 0, 63, 0, 11, 0, 13, 24,
-  67, 6, 0, 18, 27, 22, 0, 0, 0, 0,
-  0, 97, 0, 0, 60, 4, 0, 5, 27, 86,
-  27, 52, 0, 0, 8, 9, 193, 55, 1, 28,
-  52, 0, 59, 1, 0, 58, 0, 17, 14, 39,
-  0, 14, 26, 83, 17, 0, 2, 0, 0, 64,
-  30, 0, 71, 0, 60, 0, 49, 0, 15, 71,
-  0, 0, 0, 0, 7, 6, 77, 33, 0, 22,
-  82, 11, 31, 27, 25, 0, 20, 13, 0, 0,
-  15, 5, 0, 0, 0, 0, 62, 3, 0, 0,
-  23, 0, 15, 37, 0, 0, 49, 67, 15, 0,
-  0, 37, 46, 75, 26, 0, 0, 6, 1, 16,
-  0, 37, 12, 0, 55, 0, 9, 28, 40, 0,
-  0, 0, 4, 0, 26, 26, 0, 60, 0, 15,
-  0, 5, 36, 23, 2, 0, 0, 31, 86, 8,
-  0, 0, 59, 11, 0, 0, 65, 56, 0, 25,
-  23, 0, 0, 13, 0, 13, 0, 11, 92, 0,
-  18, 0, 0, 32, 0, 53, 0, 28, 0, 44,
-  48, 94, 4, 86, 0, 7, 0, 38, 52, 0,
-  35, 0, 21, 0, 24, 0, 13, 27, 0, 40,
-  0, 11, 10, 0, 33, 0, 8, 0, 25, 13,
-  37, 0, 0, 0, 0, 15, 39, 0, 14, 13,
-  0, 0, 0, 0, 0, 24, 0, 0, 0, 13,
-  0, 47, 0, 0, 62, 50, 3, 0, 0, 13,
-  20, 1, 44, 0, 24, 28, 0, 29, 0, 15,
-  0, 0, 25, 0, 11, 10, 47, 0, 42, 0,
-  79, 0, 14, 0, 3, 28, 40, 34, 0, 19,
-  25, 3, 20, 0, 0, 31, 114, 0, 21, 37,
-  61, 3, 0, 0, 0, 74, 0, 5, 57, 0,
-  0, 30, 0, 1, 0, 41, 79, 0, 10, 0,
-  0, 27, 0, 80, 0, 41, 32, 32, 31, 55,
-  32, 23, 0, 44, 0, 50, 31, 17, 17, 0,
-  7, 0, 0, 0, 12, 0, 0, 36, 0, 0,
-  4, 0, 28, 0, 17, 10, 0, 3, 3, 0,
-  15, 36, 0, 33, 36, 0, 51, 45, 0, 0,
-  5, 0, 0, 36, 0, 0, 0, 5, 0, 25,
-  33, 0, 3, 68, 5, 0, 5, 7, 24, 0,
-  28, 0, 2, 10, 6, 14, 0, 1, 0, 0,
-  2, 0, 6, 0, 15, 4, 59, 0, 74, 0,
-  21, 0, 43, 69, 0, 8, 5, 11, 0, 0,
-  0, 0, 0, 0, 16, 73, 0, 0, 82, 18,
-  0, 0, 0, 41, 0, 50, 15, 0, 5, 16,
-  0, 0, 0, 19, 83, 23, 0, 0, 0, 9,
-  0, 0, 0, 6, 0, 0, 9, 74, 35, 102,
-  0, 0, 0, 29, 56, 0, 22, 0, 18, 0,
-  0, 0, 78, 24, 0, 51, 0, 0, 97, 0,
-  107, 49, 0, 0, 4, 13, 45, 0, 27, 0,
-  0, 5, 25, 0, 35, 12, 0, 12, 0, 6,
-  0, 6, 0, 26, 0, 19, 1, 0, 34, 0,
-  12, 95, 20, 81, 35, 21, 44, 44, 10, 0,
-  51, 0, 0, 63, 0, 7, 0, 0, 0, 0,
-  11, 0, 22, 0, 33, 0, 0, 27, 27, 0,
-  0, 39, 39, 29, 0, 48, 7, 15, 23, 0,
-  0, 11, 81, 0, 0, 23, 58, 7, 0, 0,
-  0, 63, 0, 21, 41, 0, 0, 12, 0, 0,
-  0, 32, 67, 3, 1, 0, 0, 13, 0, 47,
-  0, 18, 41, 13, 22, 69, 25, 53, 0, 12,
-  0, 37, 21, 7, 22, 0, 22, 0, 0, 0,
-  16, 31, 0, 29, 0, 0, 7, 0, 37, 0,
-  18, 0, 9, 21, 4, 0, 5, 11, 0, 39,
-  27, 0, 62, 62, 0, 0, 0, 0, 0, 18,
-  1, 0, 0, 19, 0, 19, 32, 0, 0, 78,
-  11, 0, 0, 10, 15, 0, 33, 0, 0, 0,
-  0, 8, 0, 0, 0, 0, 7, 0, 0, 0,
-  0, 0, 38, 0, 39, 0, 9, 0, 0, 0,
-  0, 12, 0, 128, 4, 0, 24, 0, 0, 24,
-  44, 0, 0, 3, 15, 0, 0, 0, 17, 87,
-  14, 19, 11, 0, 0, 0, 0, 0, 0, 22,
-  19, 26, 0, 6, 0, 37, 0, 56, 0, 21,
-  0, 56, 0, 77, 54, 47, 0, 0, 0, 41,
-  15, 0, 2, 0, 67, 0, 29, 0, 3, 66,
-  0, 12, 54, 5, 0, 16, 73, 0, 77, 17,
-  14, 1, 0, 19, 20, 20, 0, 39, 27, 0,
-  45, 41, 10, 0, 5, 0, 0, 0, 0, 17,
-  0, 0, 0, 33, 0, 0, 7, 75, 14, 0,
-  0, 3, 5, 0, 19, 0, 0, 0, 0, 0,
-  0, 14, 0, 0, 93, 0, 37, 0, 0, 0,
-  0, 0, 36, 0, 0, 0, 0, 67, 0, 11,
-  0, 33, 2, 0, 0, 0, 0, 17, 28, 49,
-  0, 0, 52, 3, 0, 0, 28, 58, 0, 42,
-  19, 0, 0, 8, 0, 9, 0, 26, 82, 21,
-  0, 0, 0, 27, 0, 8, 0, 40, 0, 22,
-  24, 91, 9, 110, 0, 0, 0, 27, 50, 0,
-  37, 0, 28, 0, 14, 0, 55, 50, 0, 43,
-  0, 0, 49, 11, 81, 0, 4, 0, 22, 7,
-  42, 0, 12, 0, 0, 26, 21, 0, 21, 24,
-  0, 0, 0, 0, 0, 9, 0, 0, 0, 9,
-  0, 20, 0, 0, 47, 83, 0, 52, 17, 21,
-  41, 51, 25, 0, 40, 5, 0, 40, 0, 11,
-  0, 0, 21, 0, 13, 13, 31, 0, 15, 0,
-  35, 1, 15, 0, 0, 27, 36, 37, 0, 42,
-  17, 9, 15, 0, 0, 22, 97, 0, 7, 27,
-  55, 8, 0, 0, 0, 69, 0, 8, 46, 0,
-  0, 20, 0, 2, 0, 37, 78, 0, 3, 0,
-  0, 24, 0, 73, 0, 34, 30, 29, 29, 57,
-  25, 42, 0, 28, 0, 43, 34, 9, 17, 0,
-  10, 0, 0, 0, 6, 14, 0, 16, 0, 0,
-  0, 0, 28, 0, 23, 6, 0, 10, 7, 0,
-  0, 23, 0, 35, 38, 0, 52, 56, 0, 0,
-  11, 0, 0, 18, 0, 0, 0, 4, 0, 16,
-  29, 0, 0, 66, 6, 0, 0, 10, 18, 0,
-  38, 0, 0, 6, 0, 7, 0, 1, 0, 0,
-  17, 0, 0, 0, 5, 0, 43, 0, 63, 0,
-  11, 0, 0, 0, 0, 15, 0, 142, 5, 0,
-  3, 0, 0, 27, 43, 0, 0, 0, 6, 0,
-  0, 0, 37, 88, 23, 15, 8, 0, 0, 0,
-  0, 13, 0, 22, 26, 24, 0, 2, 0, 36,
-  0, 50, 0, 35, 0, 56, 1, 71, 43, 43,
-  0, 0, 0, 38, 8, 0, 4, 0, 67, 0,
-  33, 0, 0, 57, 0, 0, 64, 0, 0, 26,
-  62, 0, 74, 26, 27, 3, 4, 32, 9, 25,
-  0, 31, 35, 0, 37, 52, 8, 0, 19, 0,
-  0, 0, 0, 11, 7, 0, 1, 26, 0, 0,
-  10, 66, 18, 0, 0, 7, 8, 0, 31, 0,
-  0, 0, 0, 0, 0, 15, 0, 0, 111, 2,
-  35, 3, 0, 0, 0, 0, 41, 0, 0, 0,
-  0, 60, 0, 15, 0, 5, 36, 23, 2, 0,
-  0, 31, 86, 8, 0, 0, 59, 11, 0, 0,
-  65, 56, 0, 25, 23, 0, 0, 13, 0, 13,
-  0, 11, 92, 0, 18, 0, 0, 32, 0, 53,
-  0, 28, 0, 44, 48, 94, 4, 86, 0, 7,
-  0, 38, 52, 0, 35, 0, 21, 0, 24, 0,
-  13, 27, 0, 40, 0, 11, 10, 0, 33, 0,
-  8, 0, 25, 13, 37, 0, 0, 0, 0, 15,
-  39, 0, 14, 13, 0, 0, 0, 0, 0, 24,
-  0, 0, 0, 13, 0, 47, 0, 0, 62, 50,
-  3, 0, 0, 13, 20, 1, 44, 0, 24, 28,
-  0, 29, 0, 15, 0, 0, 25, 0, 11, 10,
-  47, 0, 42, 0, 79, 0, 14, 0, 3, 28,
-  40, 34, 0, 19, 25, 3, 20, 0, 0, 31,
-  114, 0, 21, 37, 61, 3, 0, 0, 0, 74,
-  0, 5, 57, 0, 0, 30, 0, 1, 0, 41,
-  79, 0, 10, 0, 0, 27, 0, 80, 0, 41,
-  32, 32, 31, 55, 32, 23, 0, 44, 0, 50,
-  31, 17, 17, 0, 7, 0, 0, 0, 12, 0,
-  0, 36, 0, 0, 4, 0, 28, 0, 17, 10,
-  0, 3, 3, 0, 15, 36, 0, 33, 36, 0,
-  51, 45, 0, 0, 5, 0, 0, 36, 0, 0,
-  0, 5, 0, 25, 33, 0, 3, 68, 5, 0,
-  5, 7, 24, 0, 28, 0, 2, 10, 6, 14,
-  0, 1, 0, 0, 2, 0, 6, 0, 15, 4,
-  59, 0, 74, 0, 21, 0, 0, 0, 0, 16,
-  0, 145, 3, 0, 12, 0, 0, 27, 50, 0,
-  0, 22, 2, 0, 1, 0, 35, 91, 18, 9,
-  3, 0, 0, 0, 0, 4, 0, 27, 23, 43,
-  0, 0, 0, 30, 0, 60, 0, 29, 0, 69,
-  6, 72, 26, 52, 0, 0, 0, 48, 12, 0,
-  0, 0, 56, 0, 35, 0, 2, 55, 0, 0,
-  72, 0, 0, 20, 53, 0, 83, 22, 17, 0,
-  0, 33, 2, 22, 0, 37, 41, 0, 32, 49,
-  7, 0, 27, 0, 0, 0, 0, 13, 1, 0,
-  15, 38, 0, 0, 2, 68, 27, 0, 0, 7,
-  17, 0, 22, 0, 0, 0, 0, 0, 0, 29,
-  0, 0, 104, 4, 40, 7, 0, 0, 0, 0,
-  54, 0, 3, 0, 0, 39, 39, 29, 0, 48,
-  7, 15, 23, 0, 0, 11, 81, 0, 0, 23,
-  58, 7, 0, 0, 0, 63, 0, 21, 41, 0,
-  0, 12, 0, 0, 0, 32, 67, 3, 1, 0,
-  0, 13, 0, 47, 0, 18, 41, 13, 22, 69,
-  25, 53, 0, 12, 0, 37, 21, 7, 22, 0,
-  22, 0, 0, 0, 16, 31, 0, 29, 0, 0,
-  7, 0, 37, 0, 18, 0, 9, 21, 4, 0,
-  5, 11, 0, 39, 27, 0, 62, 62, 0, 0,
-  0, 0, 0, 18, 1, 0, 0, 19, 0, 19,
-  32, 0, 0, 78, 11, 0, 0, 10, 15, 0,
-  33, 0, 0, 0, 0, 8, 0, 0, 0, 0,
-  7, 0, 0, 0, 0, 0, 38, 0, 39, 0,
-  9, 0, 0, 0, 0, 12, 0, 128, 4, 0,
-  24, 0, 0, 24, 44, 0, 0, 3, 15, 0,
-  0, 0, 17, 87, 14, 19, 11, 0, 0, 0,
-  0, 0, 0, 22, 19, 26, 0, 6, 0, 37,
-  0, 56, 0, 21, 0, 56, 0, 77, 54, 47,
-  0, 0, 0, 41, 15, 0, 2, 0, 67, 0,
-  29, 0, 3, 66, 0, 12, 54, 5, 0, 16,
-  73, 0, 77, 17, 14, 1, 0, 19, 20, 20,
-  0, 39, 27, 0, 45, 41, 10, 0, 5, 0,
-  0, 0, 0, 17, 0, 0, 0, 33, 0, 0,
-  7, 75, 14, 0, 0, 3, 5, 0, 19, 0,
-  0, 0, 0, 0, 0, 14, 0, 0, 93, 0,
-  37, 0, 0, 0, 0, 0, 36, 0, 0, 0,
-  0, 0, 0, 0, 0, 48, 47, 0, 22, 0,
-  0, 0, 38, 0, 10, 49, 31, 17, 0, 15,
-  62, 0, 0, 40, 0, 20, 12, 0, 0, 26,
-  0, 0, 64, 55, 8, 0, 0, 16, 0, 41,
-  0, 28, 0, 56, 0, 45, 21, 45, 0, 12,
-  2, 10, 93, 9, 0, 9, 48, 0, 0, 35,
-  16, 4, 0, 1, 0, 0, 17, 7, 42, 0,
-  2, 3, 0, 21, 13, 42, 3, 0, 0, 26,
-  69, 0, 18, 2, 18, 0, 12, 0, 9, 8,
-  0, 31, 0, 8, 5, 29, 0, 0, 36, 54,
-  18, 0, 0, 0, 1, 0, 24, 4, 0, 31,
-  0, 1, 0, 19, 0, 0, 51, 3, 32, 0,
-  21, 0, 83, 0, 35, 0, 4, 0, 0, 27,
-  36, 37, 0, 42, 17, 9, 15, 0, 0, 22,
-  97, 0, 7, 27, 55, 8, 0, 0, 0, 69,
-  0, 8, 46, 0, 0, 20, 0, 2, 0, 37,
-  78, 0, 3, 0, 0, 24, 0, 73, 0, 34,
-  30, 29, 29, 57, 25, 42, 0, 28, 0, 43,
-  34, 9, 17, 0, 10, 0, 0, 0, 6, 14,
-  0, 16, 0, 0, 0, 0, 28, 0, 23, 6,
-  0, 10, 7, 0, 0, 23, 0, 35, 38, 0,
-  52, 56, 0, 0, 11, 0, 0, 18, 0, 0,
-  0, 4, 0, 16, 29, 0, 0, 66, 6, 0,
-  0, 10, 18, 0, 38, 0, 0, 6, 0, 7,
-  0, 1, 0, 0, 17, 0, 0, 0, 5, 0,
-  43, 0, 63, 0, 11, 0, 0, 0, 0, 15,
-  0, 142, 5, 0, 3, 0, 0, 27, 43, 0,
-  0, 0, 6, 0, 0, 0, 37, 88, 23, 15,
-  8, 0, 0, 0, 0, 13, 0, 22, 26, 24,
-  0, 2, 0, 36, 0, 50, 0, 35, 0, 56,
-  1, 71, 43, 43, 0, 0, 0, 38, 8, 0,
-  4, 0, 67, 0, 33, 0, 0, 57, 0, 0,
-  64, 0, 0, 26, 62, 0, 74, 26, 27, 3,
-  4, 32, 9, 25, 0, 31, 35, 0, 37, 52,
-  8, 0, 19, 0, 0, 0, 0, 11, 7, 0,
-  1, 26, 0, 0, 10, 66, 18, 0, 0, 7,
-  8, 0, 31, 0, 0, 0, 0, 0, 0, 15,
-  0, 0, 111, 2, 35, 3, 0, 0, 0, 0,
-  41, 0, 0, 0, 0, 0, 0, 0, 0, 51,
-  48, 0, 17, 0, 0, 1, 56, 0, 12, 28,
-  33, 20, 5, 18, 77, 0, 0, 29, 0, 42,
-  17, 0, 0, 38, 0, 0, 71, 57, 0, 0,
-  0, 12, 0, 39, 0, 43, 0, 51, 0, 34,
-  20, 45, 0, 31, 15, 0, 71, 13, 0, 6,
-  44, 0, 0, 54, 15, 0, 0, 0, 0, 0,
-  23, 28, 33, 0, 0, 13, 0, 22, 15, 54,
-  0, 0, 0, 29, 69, 6, 16, 0, 25, 0,
-  11, 13, 3, 2, 0, 26, 5, 14, 0, 26,
-  0, 0, 43, 47, 11, 6, 0, 0, 0, 0,
-  43, 0, 0, 46, 1, 0, 0, 11, 0, 0,
-  48, 15, 46, 0, 23, 0, 104, 0, 47, 0,
-  0, 0, 3, 28, 40, 34, 0, 19, 25, 3,
-  20, 0, 0, 31, 114, 0, 21, 37, 61, 3,
-  0, 0, 0, 74, 0, 5, 57, 0, 0, 30,
-  0, 1, 0, 41, 79, 0, 10, 0, 0, 27,
-  0, 80, 0, 41, 32, 32, 31, 55, 32, 23,
-  0, 44, 0, 50, 31, 17, 17, 0, 7, 0,
-  0, 0, 12, 0, 0, 36, 0, 0, 4, 0,
-  28, 0, 17, 10, 0, 3, 3, 0, 15, 36,
-  0, 33, 36, 0, 51, 45, 0, 0, 5, 0,
-  0, 36, 0, 0, 0, 5, 0, 25, 33, 0,
-  3, 68, 5, 0, 5, 7, 24, 0, 28, 0,
-  2, 10, 6, 14, 0, 1, 0, 0, 2, 0,
-  6, 0, 15, 4, 59, 0, 74, 0, 21, 0,
-  0, 0, 0, 16, 0, 145, 3, 0, 12, 0,
-  0, 27, 50, 0, 0, 22, 2, 0, 1, 0,
-  35, 91, 18, 9, 3, 0, 0, 0, 0, 4,
-  0, 27, 23, 43, 0, 0, 0, 30, 0, 60,
-  0, 29, 0, 69, 6, 72, 26, 52, 0, 0,
-  0, 48, 12, 0, 0, 0, 56, 0, 35, 0,
-  2, 55, 0, 0, 72, 0, 0, 20, 53, 0,
-  83, 22, 17, 0, 0, 33, 2, 22, 0, 37,
-  41, 0, 32, 49, 7, 0, 27, 0, 0, 0,
-  0, 13, 1, 0, 15, 38, 0, 0, 2, 68,
-  27, 0, 0, 7, 17, 0, 22, 0, 0, 0,
-  0, 0, 0, 29, 0, 0, 104, 4, 40, 7,
-  0, 0, 0, 0, 54, 0, 3, 0, 0, 0,
-  0, 0, 0, 45, 41, 0, 20, 0, 0, 0,
-  75, 11, 19, 55, 39, 21, 25, 2, 84, 0,
-  0, 27, 13, 52, 3, 2, 0, 52, 0, 0,
-  56, 63, 0, 0, 0, 0, 0, 59, 0, 43,
-  0, 45, 7, 20, 17, 36, 0, 46, 0, 0,
-  66, 22, 0, 0, 25, 0, 0, 76, 20, 0,
-  0, 2, 0, 0, 13, 21, 31, 0, 0, 26,
-  0, 14, 8, 55, 0, 0, 0, 54, 58, 17,
-  20, 5, 37, 0, 12, 14, 8, 14, 4, 15,
-  7, 17, 1, 41, 0, 0, 39, 55, 6, 0,
-  4, 0, 0, 0, 35, 0, 0, 42, 13, 0,
-  0, 5, 0, 0, 43, 15, 52, 0, 18, 3,
-  121, 0, 68, 0, 9, 0, 0, 0, 0, 12,
-  0, 128, 4, 0, 24, 0, 0, 24, 44, 0,
-  0, 3, 15, 0, 0, 0, 17, 87, 14, 19,
-  11, 0, 0, 0, 0, 0, 0, 22, 19, 26,
-  0, 6, 0, 37, 0, 56, 0, 21, 0, 56,
-  0, 77, 54, 47, 0, 0, 0, 41, 15, 0,
-  2, 0, 67, 0, 29, 0, 3, 66, 0, 12,
-  54, 5, 0, 16, 73, 0, 77, 17, 14, 1,
-  0, 19, 20, 20, 0, 39, 27, 0, 45, 41,
-  10, 0, 5, 0, 0, 0, 0, 17, 0, 0,
-  0, 33, 0, 0, 7, 75, 14, 0, 0, 3,
-  5, 0, 19, 0, 0, 0, 0, 0, 0, 14,
-  0, 0, 93, 0, 37, 0, 0, 0, 0, 0,
-  36, 0, 0, 0, 0, 0, 0, 0, 0, 48,
-  47, 0, 22, 0, 0, 0, 38, 0, 10, 49,
-  31, 17, 0, 15, 62, 0, 0, 40, 0, 20,
-  12, 0, 0, 26, 0, 0, 64, 55, 8, 0,
-  0, 16, 0, 41, 0, 28, 0, 56, 0, 45,
-  21, 45, 0, 12, 2, 10, 93, 9, 0, 9,
-  48, 0, 0, 35, 16, 4, 0, 1, 0, 0,
-  17, 7, 42, 0, 2, 3, 0, 21, 13, 42,
-  3, 0, 0, 26, 69, 0, 18, 2, 18, 0,
-  12, 0, 9, 8, 0, 31, 0, 8, 5, 29,
-  0, 0, 36, 54, 18, 0, 0, 0, 1, 0,
-  24, 4, 0, 31, 0, 1, 0, 19, 0, 0,
-  51, 3, 32, 0, 21, 0, 83, 0, 35, 0,
-  4, 0, 0, 9, 0, 0, 15, 0, 57, 0,
-  37, 0, 0, 0, 30, 12, 51, 40, 45, 47,
-  0, 28, 101, 0, 0, 27, 0, 9, 25, 8,
-  0, 23, 0, 0, 52, 4, 22, 0, 0, 12,
-  0, 35, 0, 7, 0, 70, 5, 54, 4, 16,
-  0, 0, 13, 8, 68, 27, 0, 0, 28, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 23, 1,
-  27, 0, 0, 0, 0, 10, 48, 0, 7, 9,
-  0, 11, 57, 13, 9, 0, 13, 0, 0, 0,
-  22, 29, 9, 0, 0, 15, 0, 34, 0, 0,
-  59, 37, 0, 0, 0, 0, 12, 0, 17, 14,
-  11, 27, 0, 0, 0, 5, 0, 0, 24, 0,
-  14, 0, 27, 0, 77, 0, 21, 0, 13, 0,
-  0, 0, 0, 15, 0, 142, 5, 0, 3, 0,
-  0, 27, 43, 0, 0, 0, 6, 0, 0, 0,
-  37, 88, 23, 15, 8, 0, 0, 0, 0, 13,
-  0, 22, 26, 24, 0, 2, 0, 36, 0, 50,
-  0, 35, 0, 56, 1, 71, 43, 43, 0, 0,
-  0, 38, 8, 0, 4, 0, 67, 0, 33, 0,
-  0, 57, 0, 0, 64, 0, 0, 26, 62, 0,
-  74, 26, 27, 3, 4, 32, 9, 25, 0, 31,
-  35, 0, 37, 52, 8, 0, 19, 0, 0, 0,
-  0, 11, 7, 0, 1, 26, 0, 0, 10, 66,
-  18, 0, 0, 7, 8, 0, 31, 0, 0, 0,
-  0, 0, 0, 15, 0, 0, 111, 2, 35, 3,
-  0, 0, 0, 0, 41, 0, 0, 0, 0, 0,
-  0, 0, 0, 51, 48, 0, 17, 0, 0, 1,
-  56, 0, 12, 28, 33, 20, 5, 18, 77, 0,
-  0, 29, 0, 42, 17, 0, 0, 38, 0, 0,
-  71, 57, 0, 0, 0, 12, 0, 39, 0, 43,
-  0, 51, 0, 34, 20, 45, 0, 31, 15, 0,
-  71, 13, 0, 6, 44, 0, 0, 54, 15, 0,
-  0, 0, 0, 0, 23, 28, 33, 0, 0, 13,
-  0, 22, 15, 54, 0, 0, 0, 29, 69, 6,
-  16, 0, 25, 0, 11, 13, 3, 2, 0, 26,
-  5, 14, 0, 26, 0, 0, 43, 47, 11, 6,
-  0, 0, 0, 0, 43, 0, 0, 46, 1, 0,
-  0, 11, 0, 0, 48, 15, 46, 0, 23, 0,
-  104, 0, 47, 0, 0, 0, 0, 29, 0, 0,
-  20, 0, 45, 0, 38, 0, 0, 2, 26, 28,
-  73, 29, 52, 53, 0, 24, 91, 0, 0, 24,
-  16, 39, 26, 0, 0, 20, 0, 0, 40, 12,
-  3, 0, 0, 8, 0, 47, 0, 9, 0, 58,
-  0, 33, 12, 19, 0, 0, 17, 3, 66, 44,
-  0, 0, 7, 0, 0, 3, 7, 0, 0, 0,
-  0, 0, 42, 7, 32, 0, 0, 0, 0, 10,
-  51, 0, 4, 0, 0, 8, 61, 18, 25, 0,
-  32, 0, 8, 4, 12, 12, 2, 0, 0, 26,
-  0, 31, 0, 0, 56, 29, 0, 2, 0, 0,
-  0, 0, 30, 0, 7, 37, 0, 0, 0, 21,
-  0, 0, 7, 6, 14, 0, 16, 0, 90, 0,
-  25, 0, 12, 0, 0, 0, 0, 16, 0, 145,
-  3, 0, 12, 0, 0, 27, 50, 0, 0, 22,
-  2, 0, 1, 0, 35, 91, 18, 9, 3, 0,
-  0, 0, 0, 4, 0, 27, 23, 43, 0, 0,
-  0, 30, 0, 60, 0, 29, 0, 69, 6, 72,
-  26, 52, 0, 0, 0, 48, 12, 0, 0, 0,
-  56, 0, 35, 0, 2, 55, 0, 0, 72, 0,
-  0, 20, 53, 0, 83, 22, 17, 0, 0, 33,
-  2, 22, 0, 37, 41, 0, 32, 49, 7, 0,
-  27, 0, 0, 0, 0, 13, 1, 0, 15, 38,
-  0, 0, 2, 68, 27, 0, 0, 7, 17, 0,
-  22, 0, 0, 0, 0, 0, 0, 29, 0, 0,
-  104, 4, 40, 7, 0, 0, 0, 0, 54, 0,
-  3, 0, 0, 0, 0, 0, 0, 45, 41, 0,
-  20, 0, 0, 0, 75, 11, 19, 55, 39, 21,
-  25, 2, 84, 0, 0, 27, 13, 52, 3, 2,
-  0, 52, 0, 0, 56, 63, 0, 0, 0, 0,
-  0, 59, 0, 43, 0, 45, 7, 20, 17, 36,
-  0, 46, 0, 0, 66, 22, 0, 0, 25, 0,
-  0, 76, 20, 0, 0, 2, 0, 0, 13, 21,
-  31, 0, 0, 26, 0, 14, 8, 55, 0, 0,
-  0, 54, 58, 17, 20, 5, 37, 0, 12, 14,
-  8, 14, 4, 15, 7, 17, 1, 41, 0, 0,
-  39, 55, 6, 0, 4, 0, 0, 0, 35, 0,
-  0, 42, 13, 0, 0, 5, 0, 0, 43, 15,
-  52, 0, 18, 3, 121, 0, 68, 0, 9, 0,
-  0, 49, 1, 0, 30, 0, 15, 0, 64, 0,
-  0, 7, 46, 41, 52, 60, 59, 47, 14, 4,
-  85, 0, 0, 29, 21, 32, 22, 9, 0, 19,
-  0, 0, 33, 0, 0, 0, 0, 0, 0, 62,
-  0, 0, 0, 54, 0, 32, 4, 0, 0, 16,
-  7, 12, 54, 37, 0, 0, 0, 0, 0, 0,
-  1, 0, 0, 0, 0, 0, 49, 0, 30, 0,
-  0, 0, 5, 29, 27, 0, 0, 9, 0, 21,
-  35, 23, 45, 0, 23, 22, 4, 26, 21, 30,
-  26, 0, 0, 24, 0, 19, 0, 0, 46, 43,
-  11, 0, 0, 0, 0, 0, 30, 1, 0, 44,
-  0, 0, 0, 16, 0, 0, 1, 3, 6, 0,
-  0, 0, 95, 0, 52, 0, 20, 0, 0, 0,
-  0, 0, 0, 48, 47, 0, 22, 0, 0, 0,
-  38, 0, 10, 49, 31, 17, 0, 15, 62, 0,
-  0, 40, 0, 20, 12, 0, 0, 26, 0, 0,
-  64, 55, 8, 0, 0, 16, 0, 41, 0, 28,
-  0, 56, 0, 45, 21, 45, 0, 12, 2, 10,
-  93, 9, 0, 9, 48, 0, 0, 35, 16, 4,
-  0, 1, 0, 0, 17, 7, 42, 0, 2, 3,
-  0, 21, 13, 42, 3, 0, 0, 26, 69, 0,
-  18, 2, 18, 0, 12, 0, 9, 8, 0, 31,
-  0, 8, 5, 29, 0, 0, 36, 54, 18, 0,
-  0, 0, 1, 0, 24, 4, 0, 31, 0, 1,
-  0, 19, 0, 0, 51, 3, 32, 0, 21, 0,
-  83, 0, 35, 0, 4, 0, 0, 9, 0, 0,
-  15, 0, 57, 0, 37, 0, 0, 0, 30, 12,
-  51, 40, 45, 47, 0, 28, 101, 0, 0, 27,
-  0, 9, 25, 8, 0, 23, 0, 0, 52, 4,
-  22, 0, 0, 12, 0, 35, 0, 7, 0, 70,
-  5, 54, 4, 16, 0, 0, 13, 8, 68, 27,
-  0, 0, 28, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 23, 1, 27, 0, 0, 0, 0, 10,
-  48, 0, 7, 9, 0, 11, 57, 13, 9, 0,
-  13, 0, 0, 0, 22, 29, 9, 0, 0, 15,
-  0, 34, 0, 0, 59, 37, 0, 0, 0, 0,
-  12, 0, 17, 14, 11, 27, 0, 0, 0, 5,
-  0, 0, 24, 0, 14, 0, 27, 0, 77, 0,
-  21, 0, 13, 0, 0, 33, 0, 0, 27, 0,
-  41, 0, 45, 22, 0, 7, 22, 44, 69, 48,
-  60, 49, 0, 17, 100, 0, 0, 26, 19, 29,
-  19, 25, 0, 21, 0, 0, 29, 10, 19, 0,
-  0, 21, 0, 35, 0, 0, 0, 56, 7, 31,
-  16, 4, 0, 0, 48, 0, 33, 46, 0, 2,
-  16, 0, 0, 12, 0, 0, 0, 0, 0, 0,
-  48, 0, 33, 0, 0, 0, 0, 6, 51, 0,
-  15, 23, 0, 30, 42, 35, 0, 0, 24, 0,
-  0, 0, 26, 42, 0, 0, 0, 46, 0, 27,
-  0, 13, 75, 38, 0, 0, 0, 0, 17, 0,
-  16, 5, 28, 44, 0, 0, 0, 5, 8, 0,
-  2, 0, 24, 0, 4, 0, 105, 0, 27, 6,
-  32, 0, 0, 0, 0, 0, 0, 51, 48, 0,
-  17, 0, 0, 1, 56, 0, 12, 28, 33, 20,
-  5, 18, 77, 0, 0, 29, 0, 42, 17, 0,
-  0, 38, 0, 0, 71, 57, 0, 0, 0, 12,
-  0, 39, 0, 43, 0, 51, 0, 34, 20, 45,
-  0, 31, 15, 0, 71, 13, 0, 6, 44, 0,
-  0, 54, 15, 0, 0, 0, 0, 0, 23, 28,
-  33, 0, 0, 13, 0, 22, 15, 54, 0, 0,
-  0, 29, 69, 6, 16, 0, 25, 0, 11, 13,
-  3, 2, 0, 26, 5, 14, 0, 26, 0, 0,
-  43, 47, 11, 6, 0, 0, 0, 0, 43, 0,
-  0, 46, 1, 0, 0, 11, 0, 0, 48, 15,
-  46, 0, 23, 0, 104, 0, 47, 0, 0, 0,
-  0, 29, 0, 0, 20, 0, 45, 0, 38, 0,
-  0, 2, 26, 28, 73, 29, 52, 53, 0, 24,
-  91, 0, 0, 24, 16, 39, 26, 0, 0, 20,
-  0, 0, 40, 12, 3, 0, 0, 8, 0, 47,
-  0, 9, 0, 58, 0, 33, 12, 19, 0, 0,
-  17, 3, 66, 44, 0, 0, 7, 0, 0, 3,
-  7, 0, 0, 0, 0, 0, 42, 7, 32, 0,
-  0, 0, 0, 10, 51, 0, 4, 0, 0, 8,
-  61, 18, 25, 0, 32, 0, 8, 4, 12, 12,
-  2, 0, 0, 26, 0, 31, 0, 0, 56, 29,
-  0, 2, 0, 0, 0, 0, 30, 0, 7, 37,
-  0, 0, 0, 21, 0, 0, 7, 6, 14, 0,
-  16, 0, 90, 0, 25, 0, 12, 0, 0, 65,
-  0, 0, 34, 0, 36, 0, 61, 12, 0, 5,
-  44, 54, 61, 74, 64, 45, 0, 12, 72, 0,
-  0, 33, 31, 57, 17, 27, 0, 12, 0, 0,
-  29, 8, 17, 0, 0, 37, 0, 58, 0, 3,
-  0, 54, 0, 29, 24, 4, 0, 0, 35, 0,
-  43, 56, 0, 0, 7, 0, 0, 32, 0, 0,
-  0, 0, 0, 0, 70, 9, 41, 0, 0, 0,
-  0, 18, 51, 0, 0, 21, 0, 27, 40, 52,
-  13, 20, 40, 15, 0, 9, 25, 57, 3, 0,
-  0, 59, 0, 27, 0, 5, 69, 44, 0, 0,
-  0, 0, 2, 0, 12, 20, 36, 60, 0, 0,
-  0, 21, 0, 0, 0, 18, 24, 0, 0, 1,
-  134, 0, 38, 0, 44, 0, 0, 0, 0, 0,
-  0, 45, 41, 0, 20, 0, 0, 0, 75, 11,
-  19, 55, 39, 21, 25, 2, 84, 0, 0, 27,
-  13, 52, 3, 2, 0, 52, 0, 0, 56, 63,
-  0, 0, 0, 0, 0, 59, 0, 43, 0, 45,
-  7, 20, 17, 36, 0, 46, 0, 0, 66, 22,
-  0, 0, 25, 0, 0, 76, 20, 0, 0, 2,
-  0, 0, 13, 21, 31, 0, 0, 26, 0, 14,
-  8, 55, 0, 0, 0, 54, 58, 17, 20, 5,
-  37, 0, 12, 14, 8, 14, 4, 15, 7, 17,
-  1, 41, 0, 0, 39, 55, 6, 0, 4, 0,
-  0, 0, 35, 0, 0, 42, 13, 0, 0, 5,
-  0, 0, 43, 15, 52, 0, 18, 3, 121, 0,
-  68, 0, 9, 0, 0, 49, 1, 0, 30, 0,
-  15, 0, 64, 0, 0, 7, 46, 41, 52, 60,
-  59, 47, 14, 4, 85, 0, 0, 29, 21, 32,
-  22, 9, 0, 19, 0, 0, 33, 0, 0, 0,
-  0, 0, 0, 62, 0, 0, 0, 54, 0, 32,
-  4, 0, 0, 16, 7, 12, 54, 37, 0, 0,
-  0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
-  49, 0, 30, 0, 0, 0, 5, 29, 27, 0,
-  0, 9, 0, 21, 35, 23, 45, 0, 23, 22,
-  4, 26, 21, 30, 26, 0, 0, 24, 0, 19,
-  0, 0, 46, 43, 11, 0, 0, 0, 0, 0,
-  30, 1, 0, 44, 0, 0, 0, 16, 0, 0,
-  1, 3, 6, 0, 0, 0, 95, 0, 52, 0,
-  20, 0, 0, 44, 27, 0, 33, 0, 0, 0,
-  76, 0, 0, 1, 67, 69, 11, 51, 63, 32,
-  6, 0, 66, 0, 0, 38, 0, 0, 28, 40,
-  0, 0, 0, 0, 7, 0, 0, 0, 0, 27,
-  0, 47, 0, 0, 0, 20, 0, 38, 0, 0,
-  0, 16, 0, 34, 21, 7, 0, 0, 0, 8,
-  0, 0, 0, 0, 0, 0, 0, 0, 98, 0,
-  25, 5, 0, 0, 0, 78, 9, 0, 0, 35,
-  0, 0, 12, 5, 38, 41, 20, 53, 0, 44,
-  32, 14, 27, 37, 0, 13, 0, 0, 0, 0,
-  28, 63, 38, 0, 0, 0, 0, 0, 3, 36,
-  0, 61, 0, 0, 0, 5, 3, 0, 4, 0,
-  0, 0, 0, 0, 77, 0, 26, 0, 18, 21,
-  0, 9, 0, 0, 15, 0, 57, 0, 37, 0,
-  0, 0, 30, 12, 51, 40, 45, 47, 0, 28,
-  101, 0, 0, 27, 0, 9, 25, 8, 0, 23,
-  0, 0, 52, 4, 22, 0, 0, 12, 0, 35,
-  0, 7, 0, 70, 5, 54, 4, 16, 0, 0,
-  13, 8, 68, 27, 0, 0, 28, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 23, 1, 27, 0,
-  0, 0, 0, 10, 48, 0, 7, 9, 0, 11,
-  57, 13, 9, 0, 13, 0, 0, 0, 22, 29,
-  9, 0, 0, 15, 0, 34, 0, 0, 59, 37,
-  0, 0, 0, 0, 12, 0, 17, 14, 11, 27,
-  0, 0, 0, 5, 0, 0, 24, 0, 14, 0,
-  27, 0, 77, 0, 21, 0, 13, 0, 0, 33,
-  0, 0, 27, 0, 41, 0, 45, 22, 0, 7,
-  22, 44, 69, 48, 60, 49, 0, 17, 100, 0,
-  0, 26, 19, 29, 19, 25, 0, 21, 0, 0,
-  29, 10, 19, 0, 0, 21, 0, 35, 0, 0,
-  0, 56, 7, 31, 16, 4, 0, 0, 48, 0,
-  33, 46, 0, 2, 16, 0, 0, 12, 0, 0,
-  0, 0, 0, 0, 48, 0, 33, 0, 0, 0,
-  0, 6, 51, 0, 15, 23, 0, 30, 42, 35,
-  0, 0, 24, 0, 0, 0, 26, 42, 0, 0,
-  0, 46, 0, 27, 0, 13, 75, 38, 0, 0,
-  0, 0, 17, 0, 16, 5, 28, 44, 0, 0,
-  0, 5, 8, 0, 2, 0, 24, 0, 4, 0,
-  105, 0, 27, 6, 32, 0, 0, 33, 0, 0,
-  36, 0, 0, 3, 48, 28, 0, 0, 10, 59,
-  39, 46, 67, 44, 12, 0, 51, 0, 0, 36,
-  0, 22, 41, 60, 0, 0, 0, 0, 19, 0,
-  7, 0, 0, 22, 0, 24, 0, 0, 0, 4,
-  0, 17, 23, 0, 0, 0, 55, 0, 1, 17,
-  0, 0, 18, 15, 0, 17, 0, 0, 0, 0,
-  0, 0, 102, 0, 17, 0, 0, 0, 5, 41,
-  35, 0, 3, 53, 0, 13, 18, 38, 12, 42,
-  10, 28, 0, 30, 22, 26, 21, 17, 0, 42,
-  0, 0, 0, 2, 49, 55, 1, 0, 0, 0,
-  16, 0, 14, 19, 32, 69, 0, 3, 0, 0,
-  21, 0, 0, 0, 17, 0, 0, 13, 100, 0,
-  0, 0, 30, 37, 0, 29, 0, 0, 20, 0,
-  45, 0, 38, 0, 0, 2, 26, 28, 73, 29,
-  52, 53, 0, 24, 91, 0, 0, 24, 16, 39,
-  26, 0, 0, 20, 0, 0, 40, 12, 3, 0,
-  0, 8, 0, 47, 0, 9, 0, 58, 0, 33,
-  12, 19, 0, 0, 17, 3, 66, 44, 0, 0,
-  7, 0, 0, 3, 7, 0, 0, 0, 0, 0,
-  42, 7, 32, 0, 0, 0, 0, 10, 51, 0,
-  4, 0, 0, 8, 61, 18, 25, 0, 32, 0,
-  8, 4, 12, 12, 2, 0, 0, 26, 0, 31,
-  0, 0, 56, 29, 0, 2, 0, 0, 0, 0,
-  30, 0, 7, 37, 0, 0, 0, 21, 0, 0,
-  7, 6, 14, 0, 16, 0, 90, 0, 25, 0,
-  12, 0, 0, 65, 0, 0, 34, 0, 36, 0,
-  61, 12, 0, 5, 44, 54, 61, 74, 64, 45,
-  0, 12, 72, 0, 0, 33, 31, 57, 17, 27,
-  0, 12, 0, 0, 29, 8, 17, 0, 0, 37,
-  0, 58, 0, 3, 0, 54, 0, 29, 24, 4,
-  0, 0, 35, 0, 43, 56, 0, 0, 7, 0,
-  0, 32, 0, 0, 0, 0, 0, 0, 70, 9,
-  41, 0, 0, 0, 0, 18, 51, 0, 0, 21,
-  0, 27, 40, 52, 13, 20, 40, 15, 0, 9,
-  25, 57, 3, 0, 0, 59, 0, 27, 0, 5,
-  69, 44, 0, 0, 0, 0, 2, 0, 12, 20,
-  36, 60, 0, 0, 0, 21, 0, 0, 0, 18,
-  24, 0, 0, 1, 134, 0, 38, 0, 44, 0,
-  0, 26, 42, 0, 40, 0, 0, 0, 68, 7,
-  0, 5, 43, 69, 21, 36, 59, 16, 3, 0,
-  30, 7, 16, 33, 0, 0, 32, 69, 0, 5,
-  0, 0, 0, 0, 0, 0, 0, 55, 0, 45,
-  0, 4, 0, 0, 0, 8, 12, 0, 0, 16,
-  23, 16, 0, 8, 0, 0, 24, 20, 0, 0,
-  0, 0, 0, 0, 0, 0, 70, 10, 16, 0,
-  0, 0, 0, 27, 24, 0, 0, 57, 0, 13,
-  0, 13, 15, 76, 12, 31, 0, 45, 9, 26,
-  24, 0, 0, 11, 0, 0, 0, 0, 52, 56,
-  16, 0, 0, 0, 1, 0, 7, 24, 39, 91,
-  4, 0, 0, 0, 0, 0, 11, 0, 10, 0,
-  0, 35, 51, 0, 0, 0, 24, 66, 0, 49,
-  1, 0, 30, 0, 15, 0, 64, 0, 0, 7,
-  46, 41, 52, 60, 59, 47, 14, 4, 85, 0,
-  0, 29, 21, 32, 22, 9, 0, 19, 0, 0,
-  33, 0, 0, 0, 0, 0, 0, 62, 0, 0,
-  0, 54, 0, 32, 4, 0, 0, 16, 7, 12,
-  54, 37, 0, 0, 0, 0, 0, 0, 1, 0,
-  0, 0, 0, 0, 49, 0, 30, 0, 0, 0,
-  5, 29, 27, 0, 0, 9, 0, 21, 35, 23,
-  45, 0, 23, 22, 4, 26, 21, 30, 26, 0,
-  0, 24, 0, 19, 0, 0, 46, 43, 11, 0,
-  0, 0, 0, 0, 30, 1, 0, 44, 0, 0,
-  0, 16, 0, 0, 1, 3, 6, 0, 0, 0,
-  95, 0, 52, 0, 20, 0, 0, 44, 27, 0,
-  33, 0, 0, 0, 76, 0, 0, 1, 67, 69,
-  11, 51, 63, 32, 6, 0, 66, 0, 0, 38,
-  0, 0, 28, 40, 0, 0, 0, 0, 7, 0,
-  0, 0, 0, 27, 0, 47, 0, 0, 0, 20,
-  0, 38, 0, 0, 0, 16, 0, 34, 21, 7,
-  0, 0, 0, 8, 0, 0, 0, 0, 0, 0,
-  0, 0, 98, 0, 25, 5, 0, 0, 0, 78,
-  9, 0, 0, 35, 0, 0, 12, 5, 38, 41,
-  20, 53, 0, 44, 32, 14, 27, 37, 0, 13,
-  0, 0, 0, 0, 28, 63, 38, 0, 0, 0,
-  0, 0, 3, 36, 0, 61, 0, 0, 0, 5,
-  3, 0, 4, 0, 0, 0, 0, 0, 77, 0,
-  26, 0, 18, 21, 29, 0, 57, 0, 12, 30,
-  0, 0, 52, 0, 0, 2, 43, 101, 14, 0,
-  40, 0, 0, 0, 32, 66, 0, 35, 0, 0,
-  0, 29, 0, 8, 0, 0, 0, 11, 0, 0,
-  0, 50, 0, 48, 0, 31, 0, 0, 0, 0,
-  0, 0, 6, 9, 0, 67, 0, 0, 11, 0,
-  13, 40, 0, 0, 5, 7, 0, 44, 0, 15,
-  58, 0, 30, 45, 0, 14, 0, 32, 0, 0,
-  0, 10, 0, 27, 0, 3, 29, 32, 45, 49,
-  0, 64, 21, 0, 0, 14, 0, 0, 0, 0,
-  0, 0, 30, 78, 0, 0, 0, 0, 0, 18,
-  0, 23, 14, 57, 17, 0, 0, 0, 29, 0,
-  59, 1, 9, 2, 0, 17, 0, 0, 0, 0,
-  0, 41, 0, 33, 0, 0, 27, 0, 41, 0,
-  45, 22, 0, 7, 22, 44, 69, 48, 60, 49,
-  0, 17, 100, 0, 0, 26, 19, 29, 19, 25,
-  0, 21, 0, 0, 29, 10, 19, 0, 0, 21,
-  0, 35, 0, 0, 0, 56, 7, 31, 16, 4,
-  0, 0, 48, 0, 33, 46, 0, 2, 16, 0,
-  0, 12, 0, 0, 0, 0, 0, 0, 48, 0,
-  33, 0, 0, 0, 0, 6, 51, 0, 15, 23,
-  0, 30, 42, 35, 0, 0, 24, 0, 0, 0,
-  26, 42, 0, 0, 0, 46, 0, 27, 0, 13,
-  75, 38, 0, 0, 0, 0, 17, 0, 16, 5,
-  28, 44, 0, 0, 0, 5, 8, 0, 2, 0,
-  24, 0, 4, 0, 105, 0, 27, 6, 32, 0,
-  0, 33, 0, 0, 36, 0, 0, 3, 48, 28,
-  0, 0, 10, 59, 39, 46, 67, 44, 12, 0,
-  51, 0, 0, 36, 0, 22, 41, 60, 0, 0,
-  0, 0, 19, 0, 7, 0, 0, 22, 0, 24,
-  0, 0, 0, 4, 0, 17, 23, 0, 0, 0,
-  55, 0, 1, 17, 0, 0, 18, 15, 0, 17,
-  0, 0, 0, 0, 0, 0, 102, 0, 17, 0,
-  0, 0, 5, 41, 35, 0, 3, 53, 0, 13,
-  18, 38, 12, 42, 10, 28, 0, 30, 22, 26,
-  21, 17, 0, 42, 0, 0, 0, 2, 49, 55,
-  1, 0, 0, 0, 16, 0, 14, 19, 32, 69,
-  0, 3, 0, 0, 21, 0, 0, 0, 17, 0,
-  0, 13, 100, 0, 0, 0, 30, 37, 12, 0,
-  30, 0, 18, 0, 0, 0, 37, 30, 0, 0,
-  4, 71, 11, 0, 44, 48, 26, 0, 25, 1,
-  22, 8, 0, 6, 34, 49, 0, 0, 16, 0,
-  0, 5, 0, 0, 40, 32, 0, 1, 1, 0,
-  0, 0, 0, 0, 9, 0, 0, 0, 31, 0,
-  0, 10, 0, 0, 0, 51, 0, 0, 2, 6,
-  23, 5, 0, 0, 106, 5, 12, 82, 0, 0,
-  6, 39, 0, 0, 0, 50, 1, 0, 0, 34,
-  0, 54, 42, 31, 0, 69, 0, 0, 0, 56,
-  0, 0, 20, 0, 0, 15, 19, 45, 10, 6,
-  0, 0, 0, 0, 0, 21, 1, 57, 6, 0,
-  0, 0, 53, 11, 0, 0, 15, 0, 0, 26,
-  8, 0, 0, 12, 42, 48, 0, 65, 0, 0,
-  34, 0, 36, 0, 61, 12, 0, 5, 44, 54,
-  61, 74, 64, 45, 0, 12, 72, 0, 0, 33,
-  31, 57, 17, 27, 0, 12, 0, 0, 29, 8,
-  17, 0, 0, 37, 0, 58, 0, 3, 0, 54,
-  0, 29, 24, 4, 0, 0, 35, 0, 43, 56,
-  0, 0, 7, 0, 0, 32, 0, 0, 0, 0,
-  0, 0, 70, 9, 41, 0, 0, 0, 0, 18,
-  51, 0, 0, 21, 0, 27, 40, 52, 13, 20,
-  40, 15, 0, 9, 25, 57, 3, 0, 0, 59,
-  0, 27, 0, 5, 69, 44, 0, 0, 0, 0,
-  2, 0, 12, 20, 36, 60, 0, 0, 0, 21,
-  0, 0, 0, 18, 24, 0, 0, 1, 134, 0,
-  38, 0, 44, 0, 0, 26, 42, 0, 40, 0,
-  0, 0, 68, 7, 0, 5, 43, 69, 21, 36,
-  59, 16, 3, 0, 30, 7, 16, 33, 0, 0,
-  32, 69, 0, 5, 0, 0, 0, 0, 0, 0,
-  0, 55, 0, 45, 0, 4, 0, 0, 0, 8,
-  12, 0, 0, 16, 23, 16, 0, 8, 0, 0,
-  24, 20, 0, 0, 0, 0, 0, 0, 0, 0,
-  70, 10, 16, 0, 0, 0, 0, 27, 24, 0,
-  0, 57, 0, 13, 0, 13, 15, 76, 12, 31,
-  0, 45, 9, 26, 24, 0, 0, 11, 0, 0,
-  0, 0, 52, 56, 16, 0, 0, 0, 1, 0,
-  7, 24, 39, 91, 4, 0, 0, 0, 0, 0,
-  11, 0, 10, 0, 0, 35, 51, 0, 0, 0,
-  24, 66, 70, 0, 17, 0, 20, 30, 0, 0,
-  12, 0, 0, 0, 2, 79, 18, 0, 26, 23,
-  6, 5, 29, 52, 17, 15, 0, 0, 8, 29,
-  0, 0, 0, 9, 0, 47, 0, 0, 7, 43,
-  0, 12, 0, 10, 0, 0, 5, 0, 16, 5,
-  10, 0, 24, 4, 0, 0, 15, 0, 23, 37,
-  5, 0, 30, 16, 31, 0, 0, 12, 69, 32,
-  32, 66, 0, 18, 10, 0, 25, 0, 0, 55,
-  11, 6, 0, 12, 0, 37, 48, 12, 31, 65,
-  0, 0, 0, 0, 0, 0, 29, 0, 0, 17,
-  57, 30, 0, 27, 0, 0, 0, 60, 0, 14,
-  29, 64, 0, 0, 0, 1, 7, 52, 58, 0,
-  0, 0, 0, 32, 0, 0, 0, 19, 23, 49,
-  0, 44, 27, 0, 33, 0, 0, 0, 76, 0,
-  0, 1, 67, 69, 11, 51, 63, 32, 6, 0,
-  66, 0, 0, 38, 0, 0, 28, 40, 0, 0,
-  0, 0, 7, 0, 0, 0, 0, 27, 0, 47,
-  0, 0, 0, 20, 0, 38, 0, 0, 0, 16,
-  0, 34, 21, 7, 0, 0, 0, 8, 0, 0,
-  0, 0, 0, 0, 0, 0, 98, 0, 25, 5,
-  0, 0, 0, 78, 9, 0, 0, 35, 0, 0,
-  12, 5, 38, 41, 20, 53, 0, 44, 32, 14,
-  27, 37, 0, 13, 0, 0, 0, 0, 28, 63,
-  38, 0, 0, 0, 0, 0, 3, 36, 0, 61,
-  0, 0, 0, 5, 3, 0, 4, 0, 0, 0,
-  0, 0, 77, 0, 26, 0, 18, 21, 29, 0,
-  57, 0, 12, 30, 0, 0, 52, 0, 0, 2,
-  43, 101, 14, 0, 40, 0, 0, 0, 32, 66,
-  0, 35, 0, 0, 0, 29, 0, 8, 0, 0,
-  0, 11, 0, 0, 0, 50, 0, 48, 0, 31,
-  0, 0, 0, 0, 0, 0, 6, 9, 0, 67,
-  0, 0, 11, 0, 13, 40, 0, 0, 5, 7,
-  0, 44, 0, 15, 58, 0, 30, 45, 0, 14,
-  0, 32, 0, 0, 0, 10, 0, 27, 0, 3,
-  29, 32, 45, 49, 0, 64, 21, 0, 0, 14,
-  0, 0, 0, 0, 0, 0, 30, 78, 0, 0,
-  0, 0, 0, 18, 0, 23, 14, 57, 17, 0,
-  0, 0, 29, 0, 59, 1, 9, 2, 0, 17,
-  0, 0, 0, 0, 0, 41, 0, 0, 0, 0,
-  31, 51, 0, 0, 37, 2, 0, 0, 4, 70,
-  43, 0, 24, 35, 0, 14, 56, 0, 0, 39,
-  0, 0, 9, 13, 0, 36, 0, 0, 0, 14,
-  0, 0, 0, 19, 0, 41, 0, 0, 0, 5,
-  3, 0, 4, 0, 0, 0, 23, 13, 20, 0,
-  0, 0, 18, 34, 0, 0, 4, 17, 0, 0,
-  0, 0, 21, 0, 0, 0, 0, 23, 10, 1,
-  39, 9, 0, 0, 1, 25, 3, 20, 0, 8,
-  17, 5, 38, 41, 32, 19, 10, 0, 6, 0,
-  0, 0, 0, 5, 45, 39, 4, 0, 0, 0,
-  0, 31, 0, 9, 12, 73, 0, 0, 0, 0,
-  2, 0, 65, 11, 0, 5, 37, 0, 20, 0,
-  0, 11, 0, 8, 0, 33, 0, 0, 36, 0,
-  0, 3, 48, 28, 0, 0, 10, 59, 39, 46,
-  67, 44, 12, 0, 51, 0, 0, 36, 0, 22,
-  41, 60, 0, 0, 0, 0, 19, 0, 7, 0,
-  0, 22, 0, 24, 0, 0, 0, 4, 0, 17,
-  23, 0, 0, 0, 55, 0, 1, 17, 0, 0,
-  18, 15, 0, 17, 0, 0, 0, 0, 0, 0,
-  102, 0, 17, 0, 0, 0, 5, 41, 35, 0,
-  3, 53, 0, 13, 18, 38, 12, 42, 10, 28,
-  0, 30, 22, 26, 21, 17, 0, 42, 0, 0,
-  0, 2, 49, 55, 1, 0, 0, 0, 16, 0,
-  14, 19, 32, 69, 0, 3, 0, 0, 21, 0,
-  0, 0, 17, 0, 0, 13, 100, 0, 0, 0,
-  30, 37, 12, 0, 30, 0, 18, 0, 0, 0,
-  37, 30, 0, 0, 4, 71, 11, 0, 44, 48,
-  26, 0, 25, 1, 22, 8, 0, 6, 34, 49,
-  0, 0, 16, 0, 0, 5, 0, 0, 40, 32,
-  0, 1, 1, 0, 0, 0, 0, 0, 9, 0,
-  0, 0, 31, 0, 0, 10, 0, 0, 0, 51,
-  0, 0, 2, 6, 23, 5, 0, 0, 106, 5,
-  12, 82, 0, 0, 6, 39, 0, 0, 0, 50,
-  1, 0, 0, 34, 0, 54, 42, 31, 0, 69,
-  0, 0, 0, 56, 0, 0, 20, 0, 0, 15,
-  19, 45, 10, 6, 0, 0, 0, 0, 0, 21,
-  1, 57, 6, 0, 0, 0, 53, 11, 0, 0,
-  15, 0, 0, 26, 8, 0, 0, 12, 42, 48,
-  16, 0, 43, 0, 0, 0, 0, 0, 40, 54,
-  0, 16, 0, 59, 14, 0, 21, 57, 23, 17,
-  21, 14, 54, 0, 0, 0, 42, 21, 0, 0,
-  0, 0, 0, 0, 0, 0, 54, 47, 0, 0,
-  9, 0, 0, 0, 0, 0, 9, 0, 0, 0,
-  23, 0, 0, 0, 10, 0, 8, 40, 0, 0,
-  0, 25, 50, 0, 59, 21, 36, 7, 0, 114,
-  0, 9, 8, 6, 0, 0, 4, 34, 0, 0,
-  0, 19, 0, 29, 42, 2, 22, 44, 6, 0,
-  0, 57, 0, 0, 19, 0, 0, 0, 14, 17,
-  24, 0, 0, 0, 0, 0, 0, 0, 0, 39,
-  0, 0, 0, 0, 81, 4, 14, 0, 20, 0,
-  0, 18, 0, 0, 0, 19, 37, 4, 0, 26,
-  42, 0, 40, 0, 0, 0, 68, 7, 0, 5,
-  43, 69, 21, 36, 59, 16, 3, 0, 30, 7,
-  16, 33, 0, 0, 32, 69, 0, 5, 0, 0,
-  0, 0, 0, 0, 0, 55, 0, 45, 0, 4,
-  0, 0, 0, 8, 12, 0, 0, 16, 23, 16,
-  0, 8, 0, 0, 24, 20, 0, 0, 0, 0,
-  0, 0, 0, 0, 70, 10, 16, 0, 0, 0,
-  0, 27, 24, 0, 0, 57, 0, 13, 0, 13,
-  15, 76, 12, 31, 0, 45, 9, 26, 24, 0,
-  0, 11, 0, 0, 0, 0, 52, 56, 16, 0,
-  0, 0, 1, 0, 7, 24, 39, 91, 4, 0,
-  0, 0, 0, 0, 11, 0, 10, 0, 0, 35,
-  51, 0, 0, 0, 24, 66, 70, 0, 17, 0,
-  20, 30, 0, 0, 12, 0, 0, 0, 2, 79,
-  18, 0, 26, 23, 6, 5, 29, 52, 17, 15,
-  0, 0, 8, 29, 0, 0, 0, 9, 0, 47,
-  0, 0, 7, 43, 0, 12, 0, 10, 0, 0,
-  5, 0, 16, 5, 10, 0, 24, 4, 0, 0,
-  15, 0, 23, 37, 5, 0, 30, 16, 31, 0,
-  0, 12, 69, 32, 32, 66, 0, 18, 10, 0,
-  25, 0, 0, 55, 11, 6, 0, 12, 0, 37,
-  48, 12, 31, 65, 0, 0, 0, 0, 0, 0,
-  29, 0, 0, 17, 57, 30, 0, 27, 0, 0,
-  0, 60, 0, 14, 29, 64, 0, 0, 0, 1,
-  7, 52, 58, 0, 0, 0, 0, 32, 0, 0,
-  0, 19, 23, 49, 22, 3, 0, 0, 24, 14,
-  0, 0, 31, 13, 0, 23, 0, 61, 30, 0,
-  16, 46, 7, 38, 53, 0, 0, 0, 7, 20,
-  37, 0, 0, 0, 0, 0, 0, 35, 0, 0,
-  9, 0, 0, 0, 0, 3, 0, 3, 12, 0,
-  13, 5, 0, 0, 57, 0, 3, 0, 0, 0,
-  27, 17, 0, 0, 5, 8, 37, 0, 0, 0,
-  19, 60, 0, 39, 0, 33, 30, 0, 37, 12,
-  0, 30, 0, 10, 5, 30, 0, 0, 41, 0,
-  71, 36, 0, 13, 0, 0, 4, 0, 18, 0,
-  0, 16, 44, 2, 0, 26, 0, 0, 0, 38,
-  5, 6, 19, 51, 0, 0, 0, 14, 43, 20,
-  37, 0, 0, 0, 39, 13, 0, 0, 0, 39,
-  17, 0, 29, 0, 57, 0, 12, 30, 0, 0,
-  52, 0, 0, 2, 43, 101, 14, 0, 40, 0,
-  0, 0, 32, 66, 0, 35, 0, 0, 0, 29,
-  0, 8, 0, 0, 0, 11, 0, 0, 0, 50,
-  0, 48, 0, 31, 0, 0, 0, 0, 0, 0,
-  6, 9, 0, 67, 0, 0, 11, 0, 13, 40,
-  0, 0, 5, 7, 0, 44, 0, 15, 58, 0,
-  30, 45, 0, 14, 0, 32, 0, 0, 0, 10,
-  0, 27, 0, 3, 29, 32, 45, 49, 0, 64,
-  21, 0, 0, 14, 0, 0, 0, 0, 0, 0,
-  30, 78, 0, 0, 0, 0, 0, 18, 0, 23,
-  14, 57, 17, 0, 0, 0, 29, 0, 59, 1,
-  9, 2, 0, 17, 0, 0, 0, 0, 0, 41,
-  0, 0, 0, 0, 31, 51, 0, 0, 37, 2,
-  0, 0, 4, 70, 43, 0, 24, 35, 0, 14,
-  56, 0, 0, 39, 0, 0, 9, 13, 0, 36,
-  0, 0, 0, 14, 0, 0, 0, 19, 0, 41,
-  0, 0, 0, 5, 3, 0, 4, 0, 0, 0,
-  23, 13, 20, 0, 0, 0, 18, 34, 0, 0,
-  4, 17, 0, 0, 0, 0, 21, 0, 0, 0,
-  0, 23, 10, 1, 39, 9, 0, 0, 1, 25,
-  3, 20, 0, 8, 17, 5, 38, 41, 32, 19,
-  10, 0, 6, 0, 0, 0, 0, 5, 45, 39,
-  4, 0, 0, 0, 0, 31, 0, 9, 12, 73,
-  0, 0, 0, 0, 2, 0, 65, 11, 0, 5,
-  37, 0, 20, 0, 0, 11, 0, 8, 0, 32,
-  0, 0, 31, 0, 19, 0, 50, 0, 0, 16,
-  7, 64, 58, 24, 16, 46, 0, 28, 76, 0,
-  0, 47, 16, 40, 25, 0, 0, 27, 0, 0,
-  0, 37, 5, 0, 0, 0, 0, 29, 0, 1,
-  0, 41, 21, 3, 4, 6, 0, 0, 60, 0,
-  56, 11, 0, 0, 8, 6, 0, 26, 13, 0,
-  0, 0, 0, 0, 17, 6, 0, 0, 0, 25,
-  0, 0, 41, 13, 0, 0, 0, 30, 48, 39,
-  12, 0, 31, 0, 58, 23, 37, 56, 3, 0,
-  8, 19, 0, 16, 0, 10, 57, 33, 0, 0,
-  0, 0, 0, 0, 23, 0, 31, 59, 0, 0,
-  0, 1, 24, 0, 21, 0, 8, 0, 47, 0,
-  77, 0, 1, 23, 9, 0, 12, 0, 30, 0,
-  18, 0, 0, 0, 37, 30, 0, 0, 4, 71,
-  11, 0, 44, 48, 26, 0, 25, 1, 22, 8,
-  0, 6, 34, 49, 0, 0, 16, 0, 0, 5,
-  0, 0, 40, 32, 0, 1, 1, 0, 0, 0,
-  0, 0, 9, 0, 0, 0, 31, 0, 0, 10,
-  0, 0, 0, 51, 0, 0, 2, 6, 23, 5,
-  0, 0, 106, 5, 12, 82, 0, 0, 6, 39,
-  0, 0, 0, 50, 1, 0, 0, 34, 0, 54,
-  42, 31, 0, 69, 0, 0, 0, 56, 0, 0,
-  20, 0, 0, 15, 19, 45, 10, 6, 0, 0,
-  0, 0, 0, 21, 1, 57, 6, 0, 0, 0,
-  53, 11, 0, 0, 15, 0, 0, 26, 8, 0,
-  0, 12, 42, 48, 16, 0, 43, 0, 0, 0,
-  0, 0, 40, 54, 0, 16, 0, 59, 14, 0,
-  21, 57, 23, 17, 21, 14, 54, 0, 0, 0,
-  42, 21, 0, 0, 0, 0, 0, 0, 0, 0,
-  54, 47, 0, 0, 9, 0, 0, 0, 0, 0,
-  9, 0, 0, 0, 23, 0, 0, 0, 10, 0,
-  8, 40, 0, 0, 0, 25, 50, 0, 59, 21,
-  36, 7, 0, 114, 0, 9, 8, 6, 0, 0,
-  4, 34, 0, 0, 0, 19, 0, 29, 42, 2,
-  22, 44, 6, 0, 0, 57, 0, 0, 19, 0,
-  0, 0, 14, 17, 24, 0, 0, 0, 0, 0,
-  0, 0, 0, 39, 0, 0, 0, 0, 81, 4,
-  14, 0, 20, 0, 0, 18, 0, 0, 0, 19,
-  37, 4, 30, 0, 21, 8, 18, 0, 0, 0,
-  23, 36, 0, 0, 0, 54, 7, 0, 0, 65,
-  15, 16, 55, 1, 62, 10, 0, 0, 52, 0,
-  0, 0, 14, 0, 0, 0, 0, 0, 9, 33,
-  0, 0, 29, 0, 0, 9, 0, 0, 15, 0,
-  0, 0, 30, 30, 0, 0, 29, 0, 20, 15,
-  0, 0, 0, 14, 64, 0, 89, 22, 8, 0,
-  0, 130, 0, 14, 8, 0, 2, 0, 14, 22,
-  0, 0, 24, 0, 8, 22, 41, 0, 39, 0,
-  26, 0, 0, 30, 15, 0, 0, 0, 0, 0,
-  23, 0, 15, 0, 0, 0, 0, 0, 0, 32,
-  0, 10, 0, 9, 0, 0, 99, 17, 35, 0,
-  24, 0, 6, 0, 0, 0, 0, 31, 25, 0,
-  70, 0, 17, 0, 20, 30, 0, 0, 12, 0,
-  0, 0, 2, 79, 18, 0, 26, 23, 6, 5,
-  29, 52, 17, 15, 0, 0, 8, 29, 0, 0,
-  0, 9, 0, 47, 0, 0, 7, 43, 0, 12,
-  0, 10, 0, 0, 5, 0, 16, 5, 10, 0,
-  24, 4, 0, 0, 15, 0, 23, 37, 5, 0,
-  30, 16, 31, 0, 0, 12, 69, 32, 32, 66,
-  0, 18, 10, 0, 25, 0, 0, 55, 11, 6,
-  0, 12, 0, 37, 48, 12, 31, 65, 0, 0,
-  0, 0, 0, 0, 29, 0, 0, 17, 57, 30,
-  0, 27, 0, 0, 0, 60, 0, 14, 29, 64,
-  0, 0, 0, 1, 7, 52, 58, 0, 0, 0,
-  0, 32, 0, 0, 0, 19, 23, 49, 22, 3,
-  0, 0, 24, 14, 0, 0, 31, 13, 0, 23,
-  0, 61, 30, 0, 16, 46, 7, 38, 53, 0,
-  0, 0, 7, 20, 37, 0, 0, 0, 0, 0,
-  0, 35, 0, 0, 9, 0, 0, 0, 0, 3,
-  0, 3, 12, 0, 13, 5, 0, 0, 57, 0,
-  3, 0, 0, 0, 27, 17, 0, 0, 5, 8,
-  37, 0, 0, 0, 19, 60, 0, 39, 0, 33,
-  30, 0, 37, 12, 0, 30, 0, 10, 5, 30,
-  0, 0, 41, 0, 71, 36, 0, 13, 0, 0,
-  4, 0, 18, 0, 0, 16, 44, 2, 0, 26,
-  0, 0, 0, 38, 5, 6, 19, 51, 0, 0,
-  0, 14, 43, 20, 37, 0, 0, 0, 39, 13,
-  0, 0, 0, 39, 17, 0, 19, 51, 0, 11,
-  63, 0, 36, 0, 33, 2, 0, 24, 2, 46,
-  28, 0, 6, 25, 11, 52, 60, 0, 0, 15,
-  21, 37, 39, 0, 0, 21, 42, 0, 0, 33,
-  0, 0, 0, 0, 0, 0, 0, 29, 0, 51,
-  23, 0, 7, 28, 0, 0, 51, 0, 37, 15,
-  0, 12, 5, 0, 0, 22, 16, 2, 15, 0,
-  0, 0, 4, 57, 0, 0, 0, 41, 5, 0,
-  60, 0, 19, 1, 4, 1, 52, 31, 4, 0,
-  58, 0, 51, 26, 21, 39, 0, 0, 0, 32,
-  0, 23, 0, 0, 55, 8, 0, 36, 1, 0,
-  0, 0, 14, 29, 63, 36, 0, 0, 0, 0,
-  46, 0, 12, 0, 4, 0, 35, 1, 40, 0,
-  0, 33, 0, 0, 0, 0, 0, 0, 31, 51,
-  0, 0, 37, 2, 0, 0, 4, 70, 43, 0,
-  24, 35, 0, 14, 56, 0, 0, 39, 0, 0,
-  9, 13, 0, 36, 0, 0, 0, 14, 0, 0,
-  0, 19, 0, 41, 0, 0, 0, 5, 3, 0,
-  4, 0, 0, 0, 23, 13, 20, 0, 0, 0,
-  18, 34, 0, 0, 4, 17, 0, 0, 0, 0,
-  21, 0, 0, 0, 0, 23, 10, 1, 39, 9,
-  0, 0, 1, 25, 3, 20, 0, 8, 17, 5,
-  38, 41, 32, 19, 10, 0, 6, 0, 0, 0,
-  0, 5, 45, 39, 4, 0, 0, 0, 0, 31,
-  0, 9, 12, 73, 0, 0, 0, 0, 2, 0,
-  65, 11, 0, 5, 37, 0, 20, 0, 0, 11,
-  0, 8, 0, 32, 0, 0, 31, 0, 19, 0,
-  50, 0, 0, 16, 7, 64, 58, 24, 16, 46,
-  0, 28, 76, 0, 0, 47, 16, 40, 25, 0,
-  0, 27, 0, 0, 0, 37, 5, 0, 0, 0,
-  0, 29, 0, 1, 0, 41, 21, 3, 4, 6,
-  0, 0, 60, 0, 56, 11, 0, 0, 8, 6,
-  0, 26, 13, 0, 0, 0, 0, 0, 17, 6,
-  0, 0, 0, 25, 0, 0, 41, 13, 0, 0,
-  0, 30, 48, 39, 12, 0, 31, 0, 58, 23,
-  37, 56, 3, 0, 8, 19, 0, 16, 0, 10,
-  57, 33, 0, 0, 0, 0, 0, 0, 23, 0,
-  31, 59, 0, 0, 0, 1, 24, 0, 21, 0,
-  8, 0, 47, 0, 77, 0, 1, 23, 9, 0,
-  0, 86, 6, 8, 42, 0, 32, 0, 64, 4,
-  0, 0, 6, 42, 74, 53, 38, 43, 0, 27,
-  68, 0, 0, 42, 0, 47, 25, 9, 0, 24,
-  6, 0, 0, 29, 9, 0, 0, 0, 0, 25,
-  0, 26, 0, 59, 9, 0, 0, 24, 0, 0,
-  45, 0, 88, 34, 0, 0, 0, 0, 0, 9,
-  6, 0, 0, 0, 0, 0, 36, 0, 0, 0,
-  0, 0, 0, 17, 64, 0, 2, 0, 1, 0,
-  91, 28, 8, 0, 51, 13, 35, 13, 47, 25,
-  0, 0, 0, 32, 0, 22, 0, 0, 48, 22,
-  0, 7, 0, 0, 23, 0, 25, 21, 43, 64,
-  10, 0, 0, 0, 29, 0, 0, 0, 18, 0,
-  4, 0, 74, 0, 0, 37, 25, 0, 16, 0,
-  43, 0, 0, 0, 0, 0, 40, 54, 0, 16,
-  0, 59, 14, 0, 21, 57, 23, 17, 21, 14,
-  54, 0, 0, 0, 42, 21, 0, 0, 0, 0,
-  0, 0, 0, 0, 54, 47, 0, 0, 9, 0,
-  0, 0, 0, 0, 9, 0, 0, 0, 23, 0,
-  0, 0, 10, 0, 8, 40, 0, 0, 0, 25,
-  50, 0, 59, 21, 36, 7, 0, 114, 0, 9,
-  8, 6, 0, 0, 4, 34, 0, 0, 0, 19,
-  0, 29, 42, 2, 22, 44, 6, 0, 0, 57,
-  0, 0, 19, 0, 0, 0, 14, 17, 24, 0,
-  0, 0, 0, 0, 0, 0, 0, 39, 0, 0,
-  0, 0, 81, 4, 14, 0, 20, 0, 0, 18,
-  0, 0, 0, 19, 37, 4, 30, 0, 21, 8,
-  18, 0, 0, 0, 23, 36, 0, 0, 0, 54,
-  7, 0, 0, 65, 15, 16, 55, 1, 62, 10,
-  0, 0, 52, 0, 0, 0, 14, 0, 0, 0,
-  0, 0, 9, 33, 0, 0, 29, 0, 0, 9,
-  0, 0, 15, 0, 0, 0, 30, 30, 0, 0,
-  29, 0, 20, 15, 0, 0, 0, 14, 64, 0,
-  89, 22, 8, 0, 0, 130, 0, 14, 8, 0,
-  2, 0, 14, 22, 0, 0, 24, 0, 8, 22,
-  41, 0, 39, 0, 26, 0, 0, 30, 15, 0,
-  0, 0, 0, 0, 23, 0, 15, 0, 0, 0,
-  0, 0, 0, 32, 0, 10, 0, 9, 0, 0,
-  99, 17, 35, 0, 24, 0, 6, 0, 0, 0,
-  0, 31, 25, 0, 5, 13, 0, 32, 19, 0,
-  8, 0, 42, 4, 0, 13, 0, 36, 0, 0,
-  0, 57, 0, 20, 78, 0, 62, 17, 0, 0,
-  48, 0, 0, 0, 23, 0, 0, 0, 0, 0,
-  0, 22, 0, 0, 41, 0, 0, 33, 9, 0,
-  6, 0, 0, 0, 32, 6, 0, 0, 33, 0,
-  37, 0, 4, 0, 0, 39, 62, 0, 84, 8,
-  32, 22, 0, 130, 0, 9, 16, 0, 0, 9,
-  33, 13, 0, 0, 29, 13, 0, 22, 32, 0,
-  33, 0, 24, 0, 0, 28, 10, 0, 0, 0,
-  8, 0, 32, 0, 10, 12, 0, 0, 0, 0,
-  0, 83, 0, 0, 2, 0, 0, 0, 98, 36,
-  46, 0, 18, 0, 8, 0, 0, 0, 0, 28,
-  8, 0, 22, 3, 0, 0, 24, 14, 0, 0,
-  31, 13, 0, 23, 0, 61, 30, 0, 16, 46,
-  7, 38, 53, 0, 0, 0, 7, 20, 37, 0,
-  0, 0, 0, 0, 0, 35, 0, 0, 9, 0,
-  0, 0, 0, 3, 0, 3, 12, 0, 13, 5,
-  0, 0, 57, 0, 3, 0, 0, 0, 27, 17,
-  0, 0, 5, 8, 37, 0, 0, 0, 19, 60,
-  0, 39, 0, 33, 30, 0, 37, 12, 0, 30,
-  0, 10, 5, 30, 0, 0, 41, 0, 71, 36,
-  0, 13, 0, 0, 4, 0, 18, 0, 0, 16,
-  44, 2, 0, 26, 0, 0, 0, 38, 5, 6,
-  19, 51, 0, 0, 0, 14, 43, 20, 37, 0,
-  0, 0, 39, 13, 0, 0, 0, 39, 17, 0,
-  19, 51, 0, 11, 63, 0, 36, 0, 33, 2,
-  0, 24, 2, 46, 28, 0, 6, 25, 11, 52,
-  60, 0, 0, 15, 21, 37, 39, 0, 0, 21,
-  42, 0, 0, 33, 0, 0, 0, 0, 0, 0,
-  0, 29, 0, 51, 23, 0, 7, 28, 0, 0,
-  51, 0, 37, 15, 0, 12, 5, 0, 0, 22,
-  16, 2, 15, 0, 0, 0, 4, 57, 0, 0,
-  0, 41, 5, 0, 60, 0, 19, 1, 4, 1,
-  52, 31, 4, 0, 58, 0, 51, 26, 21, 39,
-  0, 0, 0, 32, 0, 23, 0, 0, 55, 8,
-  0, 36, 1, 0, 0, 0, 14, 29, 63, 36,
-  0, 0, 0, 0, 46, 0, 12, 0, 4, 0,
-  35, 1, 40, 0, 0, 33, 0, 0, 0, 99,
-  0, 38, 55, 0, 74, 0, 47, 0, 0, 55,
-  43, 30, 27, 0, 3, 36, 0, 59, 80, 0,
-  0, 26, 36, 49, 32, 1, 0, 12, 51, 0,
-  22, 17, 3, 0, 0, 0, 0, 0, 0, 20,
-  0, 83, 20, 23, 0, 15, 0, 0, 26, 0,
-  67, 45, 0, 11, 23, 0, 0, 37, 22, 0,
-  0, 0, 0, 0, 14, 67, 0, 0, 0, 11,
-  0, 0, 67, 0, 16, 0, 7, 0, 80, 54,
-  0, 0, 42, 0, 37, 1, 24, 67, 6, 0,
-  0, 40, 0, 45, 0, 0, 77, 8, 0, 34,
-  3, 0, 0, 0, 25, 58, 103, 36, 0, 0,
-  0, 0, 32, 0, 0, 0, 0, 0, 21, 22,
-  80, 0, 38, 25, 8, 0, 0, 32, 0, 0,
-  31, 0, 19, 0, 50, 0, 0, 16, 7, 64,
-  58, 24, 16, 46, 0, 28, 76, 0, 0, 47,
-  16, 40, 25, 0, 0, 27, 0, 0, 0, 37,
-  5, 0, 0, 0, 0, 29, 0, 1, 0, 41,
-  21, 3, 4, 6, 0, 0, 60, 0, 56, 11,
-  0, 0, 8, 6, 0, 26, 13, 0, 0, 0,
-  0, 0, 17, 6, 0, 0, 0, 25, 0, 0,
-  41, 13, 0, 0, 0, 30, 48, 39, 12, 0,
-  31, 0, 58, 23, 37, 56, 3, 0, 8, 19,
-  0, 16, 0, 10, 57, 33, 0, 0, 0, 0,
-  0, 0, 23, 0, 31, 59, 0, 0, 0, 1,
-  24, 0, 21, 0, 8, 0, 47, 0, 77, 0,
-  1, 23, 9, 0, 0, 86, 6, 8, 42, 0,
-  32, 0, 64, 4, 0, 0, 6, 42, 74, 53,
-  38, 43, 0, 27, 68, 0, 0, 42, 0, 47,
-  25, 9, 0, 24, 6, 0, 0, 29, 9, 0,
-  0, 0, 0, 25, 0, 26, 0, 59, 9, 0,
-  0, 24, 0, 0, 45, 0, 88, 34, 0, 0,
-  0, 0, 0, 9, 6, 0, 0, 0, 0, 0,
-  36, 0, 0, 0, 0, 0, 0, 17, 64, 0,
-  2, 0, 1, 0, 91, 28, 8, 0, 51, 13,
-  35, 13, 47, 25, 0, 0, 0, 32, 0, 22,
-  0, 0, 48, 22, 0, 7, 0, 0, 23, 0,
-  25, 21, 43, 64, 10, 0, 0, 0, 29, 0,
-  0, 0, 18, 0, 4, 0, 74, 0, 0, 37,
-  25, 0, 0, 96, 8, 3, 33, 0, 35, 0,
-  85, 3, 0, 27, 4, 58, 40, 66, 33, 44,
-  0, 33, 67, 0, 11, 33, 0, 10, 35, 17,
-  0, 0, 0, 0, 16, 0, 0, 0, 0, 12,
-  0, 0, 0, 9, 0, 67, 0, 25, 0, 38,
-  0, 0, 28, 0, 77, 30, 0, 0, 25, 0,
-  0, 0, 0, 0, 0, 0, 2, 0, 21, 0,
-  17, 0, 0, 0, 18, 29, 78, 0, 11, 0,
-  0, 0, 78, 36, 3, 0, 35, 3, 44, 7,
-  36, 20, 0, 27, 0, 26, 0, 8, 0, 0,
-  61, 33, 8, 16, 0, 0, 58, 0, 22, 29,
-  12, 37, 7, 0, 0, 0, 41, 0, 0, 0,
-  20, 0, 0, 0, 52, 0, 0, 31, 46, 0,
-  30, 0, 21, 8, 18, 0, 0, 0, 23, 36,
-  0, 0, 0, 54, 7, 0, 0, 65, 15, 16,
-  55, 1, 62, 10, 0, 0, 52, 0, 0, 0,
-  14, 0, 0, 0, 0, 0, 9, 33, 0, 0,
-  29, 0, 0, 9, 0, 0, 15, 0, 0, 0,
-  30, 30, 0, 0, 29, 0, 20, 15, 0, 0,
-  0, 14, 64, 0, 89, 22, 8, 0, 0, 130,
-  0, 14, 8, 0, 2, 0, 14, 22, 0, 0,
-  24, 0, 8, 22, 41, 0, 39, 0, 26, 0,
-  0, 30, 15, 0, 0, 0, 0, 0, 23, 0,
-  15, 0, 0, 0, 0, 0, 0, 32, 0, 10,
-  0, 9, 0, 0, 99, 17, 35, 0, 24, 0,
-  6, 0, 0, 0, 0, 31, 25, 0, 5, 13,
-  0, 32, 19, 0, 8, 0, 42, 4, 0, 13,
-  0, 36, 0, 0, 0, 57, 0, 20, 78, 0,
-  62, 17, 0, 0, 48, 0, 0, 0, 23, 0,
-  0, 0, 0, 0, 0, 22, 0, 0, 41, 0,
-  0, 33, 9, 0, 6, 0, 0, 0, 32, 6,
-  0, 0, 33, 0, 37, 0, 4, 0, 0, 39,
-  62, 0, 84, 8, 32, 22, 0, 130, 0, 9,
-  16, 0, 0, 9, 33, 13, 0, 0, 29, 13,
-  0, 22, 32, 0, 33, 0, 24, 0, 0, 28,
-  10, 0, 0, 0, 8, 0, 32, 0, 10, 12,
-  0, 0, 0, 0, 0, 83, 0, 0, 2, 0,
-  0, 0, 98, 36, 46, 0, 18, 0, 8, 0,
-  0, 0, 0, 28, 8, 0, 11, 29, 0, 45,
-  2, 0, 17, 0, 59, 0, 0, 24, 0, 0,
-  0, 0, 0, 40, 1, 11, 70, 0, 8, 10,
-  0, 0, 32, 0, 0, 0, 26, 22, 0, 7,
-  0, 0, 17, 26, 2, 0, 47, 0, 0, 21,
-  13, 9, 8, 0, 0, 0, 39, 2, 0, 18,
-  67, 54, 46, 0, 21, 0, 0, 41, 60, 20,
-  72, 13, 27, 31, 0, 123, 0, 13, 17, 0,
-  0, 28, 28, 13, 17, 0, 23, 19, 0, 3,
-  26, 0, 27, 0, 23, 0, 0, 39, 0, 0,
-  0, 3, 33, 0, 52, 9, 4, 75, 0, 0,
-  0, 0, 0, 100, 0, 0, 2, 0, 0, 11,
-  51, 34, 23, 0, 31, 0, 14, 0, 0, 0,
-  3, 31, 7, 0, 19, 51, 0, 11, 63, 0,
-  36, 0, 33, 2, 0, 24, 2, 46, 28, 0,
-  6, 25, 11, 52, 60, 0, 0, 15, 21, 37,
-  39, 0, 0, 21, 42, 0, 0, 33, 0, 0,
-  0, 0, 0, 0, 0, 29, 0, 51, 23, 0,
-  7, 28, 0, 0, 51, 0, 37, 15, 0, 12,
-  5, 0, 0, 22, 16, 2, 15, 0, 0, 0,
-  4, 57, 0, 0, 0, 41, 5, 0, 60, 0,
-  19, 1, 4, 1, 52, 31, 4, 0, 58, 0,
-  51, 26, 21, 39, 0, 0, 0, 32, 0, 23,
-  0, 0, 55, 8, 0, 36, 1, 0, 0, 0,
-  14, 29, 63, 36, 0, 0, 0, 0, 46, 0,
-  12, 0, 4, 0, 35, 1, 40, 0, 0, 33,
-  0, 0, 0, 99, 0, 38, 55, 0, 74, 0,
-  47, 0, 0, 55, 43, 30, 27, 0, 3, 36,
-  0, 59, 80, 0, 0, 26, 36, 49, 32, 1,
-  0, 12, 51, 0, 22, 17, 3, 0, 0, 0,
-  0, 0, 0, 20, 0, 83, 20, 23, 0, 15,
-  0, 0, 26, 0, 67, 45, 0, 11, 23, 0,
-  0, 37, 22, 0, 0, 0, 0, 0, 14, 67,
-  0, 0, 0, 11, 0, 0, 67, 0, 16, 0,
-  7, 0, 80, 54, 0, 0, 42, 0, 37, 1,
-  24, 67, 6, 0, 0, 40, 0, 45, 0, 0,
-  77, 8, 0, 34, 3, 0, 0, 0, 25, 58,
-  103, 36, 0, 0, 0, 0, 32, 0, 0, 0,
-  0, 0, 21, 22, 80, 0, 38, 25, 8, 0,
-  0, 129, 0, 59, 30, 0, 80, 0, 63, 0,
-  2, 62, 41, 13, 24, 8, 0, 36, 0, 50,
-  73, 0, 0, 34, 40, 69, 39, 5, 0, 13,
-  44, 0, 63, 0, 17, 0, 0, 0, 0, 0,
-  0, 30, 0, 55, 31, 26, 0, 15, 0, 0,
-  34, 0, 63, 66, 0, 6, 53, 0, 0, 76,
-  13, 0, 0, 0, 0, 0, 32, 81, 0, 0,
-  0, 20, 0, 0, 48, 49, 0, 0, 0, 0,
-  65, 72, 1, 0, 21, 0, 34, 0, 17, 106,
-  73, 0, 0, 66, 0, 33, 16, 0, 73, 22,
-  0, 27, 0, 0, 0, 0, 17, 70, 123, 31,
-  8, 0, 18, 0, 19, 0, 0, 0, 0, 0,
-  16, 21, 113, 10, 49, 16, 11, 0, 0, 86,
-  6, 8, 42, 0, 32, 0, 64, 4, 0, 0,
-  6, 42, 74, 53, 38, 43, 0, 27, 68, 0,
-  0, 42, 0, 47, 25, 9, 0, 24, 6, 0,
-  0, 29, 9, 0, 0, 0, 0, 25, 0, 26,
-  0, 59, 9, 0, 0, 24, 0, 0, 45, 0,
-  88, 34, 0, 0, 0, 0, 0, 9, 6, 0,
-  0, 0, 0, 0, 36, 0, 0, 0, 0, 0,
-  0, 17, 64, 0, 2, 0, 1, 0, 91, 28,
-  8, 0, 51, 13, 35, 13, 47, 25, 0, 0,
-  0, 32, 0, 22, 0, 0, 48, 22, 0, 7,
-  0, 0, 23, 0, 25, 21, 43, 64, 10, 0,
-  0, 0, 29, 0, 0, 0, 18, 0, 4, 0,
-  74, 0, 0, 37, 25, 0, 0, 96, 8, 3,
-  33, 0, 35, 0, 85, 3, 0, 27, 4, 58,
-  40, 66, 33, 44, 0, 33, 67, 0, 11, 33,
-  0, 10, 35, 17, 0, 0, 0, 0, 16, 0,
-  0, 0, 0, 12, 0, 0, 0, 9, 0, 67,
-  0, 25, 0, 38, 0, 0, 28, 0, 77, 30,
-  0, 0, 25, 0, 0, 0, 0, 0, 0, 0,
-  2, 0, 21, 0, 17, 0, 0, 0, 18, 29,
-  78, 0, 11, 0, 0, 0, 78, 36, 3, 0,
-  35, 3, 44, 7, 36, 20, 0, 27, 0, 26,
-  0, 8, 0, 0, 61, 33, 8, 16, 0, 0,
-  58, 0, 22, 29, 12, 37, 7, 0, 0, 0,
-  41, 0, 0, 0, 20, 0, 0, 0, 52, 0,
-  0, 31, 46, 0, 0, 50, 11, 21, 17, 0,
-  0, 0, 67, 0, 0, 42, 4, 106, 9, 17,
-  15, 45, 0, 24, 71, 0, 40, 19, 0, 0,
-  0, 3, 0, 0, 0, 0, 0, 10, 0, 0,
-  0, 0, 0, 0, 4, 19, 0, 50, 0, 0,
-  0, 45, 0, 0, 34, 65, 36, 45, 0, 0,
-  44, 0, 0, 0, 0, 0, 7, 0, 60, 7,
-  0, 7, 12, 15, 0, 0, 10, 2, 40, 0,
-  0, 0, 0, 1, 42, 35, 2, 0, 21, 0,
-  58, 15, 51, 12, 0, 30, 0, 0, 0, 9,
-  0, 0, 58, 45, 6, 2, 0, 0, 16, 0,
-  0, 13, 0, 3, 7, 0, 0, 0, 80, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 4,
-  12, 0, 5, 13, 0, 32, 19, 0, 8, 0,
-  42, 4, 0, 13, 0, 36, 0, 0, 0, 57,
-  0, 20, 78, 0, 62, 17, 0, 0, 48, 0,
-  0, 0, 23, 0, 0, 0, 0, 0, 0, 22,
-  0, 0, 41, 0, 0, 33, 9, 0, 6, 0,
-  0, 0, 32, 6, 0, 0, 33, 0, 37, 0,
-  4, 0, 0, 39, 62, 0, 84, 8, 32, 22,
-  0, 130, 0, 9, 16, 0, 0, 9, 33, 13,
-  0, 0, 29, 13, 0, 22, 32, 0, 33, 0,
-  24, 0, 0, 28, 10, 0, 0, 0, 8, 0,
-  32, 0, 10, 12, 0, 0, 0, 0, 0, 83,
-  0, 0, 2, 0, 0, 0, 98, 36, 46, 0,
-  18, 0, 8, 0, 0, 0, 0, 28, 8, 0,
-  11, 29, 0, 45, 2, 0, 17, 0, 59, 0,
-  0, 24, 0, 0, 0, 0, 0, 40, 1, 11,
-  70, 0, 8, 10, 0, 0, 32, 0, 0, 0,
-  26, 22, 0, 7, 0, 0, 17, 26, 2, 0,
-  47, 0, 0, 21, 13, 9, 8, 0, 0, 0,
-  39, 2, 0, 18, 67, 54, 46, 0, 21, 0,
-  0, 41, 60, 20, 72, 13, 27, 31, 0, 123,
-  0, 13, 17, 0, 0, 28, 28, 13, 17, 0,
-  23, 19, 0, 3, 26, 0, 27, 0, 23, 0,
-  0, 39, 0, 0, 0, 3, 33, 0, 52, 9,
-  4, 75, 0, 0, 0, 0, 0, 100, 0, 0,
-  2, 0, 0, 11, 51, 34, 23, 0, 31, 0,
-  14, 0, 0, 0, 3, 31, 7, 0, 11, 24,
-  0, 20, 0, 8, 0, 0, 72, 0, 0, 35,
-  0, 0, 0, 0, 0, 45, 6, 0, 35, 11,
-  0, 11, 0, 0, 13, 0, 0, 0, 2, 13,
-  0, 0, 0, 0, 29, 44, 34, 0, 50, 0,
-  0, 11, 0, 7, 0, 0, 0, 0, 8, 60,
-  0, 0, 108, 136, 34, 5, 37, 0, 0, 24,
-  71, 27, 134, 39, 0, 0, 0, 158, 66, 0,
-  9, 0, 0, 10, 0, 0, 39, 0, 9, 0,
-  13, 5, 9, 0, 4, 0, 70, 0, 0, 80,
-  0, 0, 27, 0, 26, 0, 39, 45, 33, 130,
-  0, 0, 0, 0, 0, 84, 0, 0, 0, 0,
-  0, 24, 23, 13, 0, 0, 36, 0, 0, 0,
-  0, 0, 23, 31, 12, 0, 0, 99, 0, 38,
-  55, 0, 74, 0, 47, 0, 0, 55, 43, 30,
-  27, 0, 3, 36, 0, 59, 80, 0, 0, 26,
-  36, 49, 32, 1, 0, 12, 51, 0, 22, 17,
-  3, 0, 0, 0, 0, 0, 0, 20, 0, 83,
-  20, 23, 0, 15, 0, 0, 26, 0, 67, 45,
-  0, 11, 23, 0, 0, 37, 22, 0, 0, 0,
-  0, 0, 14, 67, 0, 0, 0, 11, 0, 0,
-  67, 0, 16, 0, 7, 0, 80, 54, 0, 0,
-  42, 0, 37, 1, 24, 67, 6, 0, 0, 40,
-  0, 45, 0, 0, 77, 8, 0, 34, 3, 0,
-  0, 0, 25, 58, 103, 36, 0, 0, 0, 0,
-  32, 0, 0, 0, 0, 0, 21, 22, 80, 0,
-  38, 25, 8, 0, 0, 129, 0, 59, 30, 0,
-  80, 0, 63, 0, 2, 62, 41, 13, 24, 8,
-  0, 36, 0, 50, 73, 0, 0, 34, 40, 69,
-  39, 5, 0, 13, 44, 0, 63, 0, 17, 0,
-  0, 0, 0, 0, 0, 30, 0, 55, 31, 26,
-  0, 15, 0, 0, 34, 0, 63, 66, 0, 6,
-  53, 0, 0, 76, 13, 0, 0, 0, 0, 0,
-  32, 81, 0, 0, 0, 20, 0, 0, 48, 49,
-  0, 0, 0, 0, 65, 72, 1, 0, 21, 0,
-  34, 0, 17, 106, 73, 0, 0, 66, 0, 33,
-  16, 0, 73, 22, 0, 27, 0, 0, 0, 0,
-  17, 70, 123, 31, 8, 0, 18, 0, 19, 0,
-  0, 0, 0, 0, 16, 21, 113, 10, 49, 16,
-  11, 0, 4, 112, 0, 54, 23, 0, 15, 0,
-  85, 7, 0, 53, 5, 3, 0, 0, 0, 18,
-  0, 13, 49, 0, 0, 31, 10, 11, 45, 17,
-  0, 0, 0, 9, 32, 0, 23, 0, 0, 18,
-  0, 0, 0, 0, 0, 18, 25, 27, 0, 0,
-  0, 0, 33, 14, 7, 64, 44, 38, 45, 0,
-  0, 10, 0, 11, 7, 12, 0, 7, 17, 45,
-  0, 29, 0, 13, 26, 0, 1, 55, 0, 8,
-  5, 0, 20, 44, 16, 23, 0, 0, 15, 29,
-  38, 55, 93, 0, 0, 17, 0, 0, 52, 0,
-  35, 52, 0, 80, 0, 0, 0, 0, 0, 84,
-  112, 0, 31, 0, 15, 3, 1, 0, 0, 0,
-  0, 0, 3, 0, 28, 0, 45, 32, 0, 0,
-  0, 96, 8, 3, 33, 0, 35, 0, 85, 3,
-  0, 27, 4, 58, 40, 66, 33, 44, 0, 33,
-  67, 0, 11, 33, 0, 10, 35, 17, 0, 0,
-  0, 0, 16, 0, 0, 0, 0, 12, 0, 0,
-  0, 9, 0, 67, 0, 25, 0, 38, 0, 0,
-  28, 0, 77, 30, 0, 0, 25, 0, 0, 0,
-  0, 0, 0, 0, 2, 0, 21, 0, 17, 0,
-  0, 0, 18, 29, 78, 0, 11, 0, 0, 0,
-  78, 36, 3, 0, 35, 3, 44, 7, 36, 20,
-  0, 27, 0, 26, 0, 8, 0, 0, 61, 33,
-  8, 16, 0, 0, 58, 0, 22, 29, 12, 37,
-  7, 0, 0, 0, 41, 0, 0, 0, 20, 0,
-  0, 0, 52, 0, 0, 31, 46, 0, 0, 50,
-  11, 21, 17, 0, 0, 0, 67, 0, 0, 42,
-  4, 106, 9, 17, 15, 45, 0, 24, 71, 0,
-  40, 19, 0, 0, 0, 3, 0, 0, 0, 0,
-  0, 10, 0, 0, 0, 0, 0, 0, 4, 19,
-  0, 50, 0, 0, 0, 45, 0, 0, 34, 65,
-  36, 45, 0, 0, 44, 0, 0, 0, 0, 0,
-  7, 0, 60, 7, 0, 7, 12, 15, 0, 0,
-  10, 2, 40, 0, 0, 0, 0, 1, 42, 35,
-  2, 0, 21, 0, 58, 15, 51, 12, 0, 30,
-  0, 0, 0, 9, 0, 0, 58, 45, 6, 2,
-  0, 0, 16, 0, 0, 13, 0, 3, 7, 0,
-  0, 0, 80, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 4, 12, 0, 20, 58, 19, 29,
-  24, 0, 0, 0, 79, 0, 0, 44, 19, 100,
-  0, 0, 0, 11, 0, 4, 57, 0, 28, 24,
-  0, 0, 2, 0, 0, 3, 5, 0, 0, 6,
-  0, 0, 0, 0, 0, 0, 0, 34, 0, 24,
-  0, 0, 6, 41, 0, 0, 50, 104, 10, 72,
-  18, 0, 43, 0, 5, 0, 0, 0, 14, 0,
-  25, 49, 0, 0, 0, 41, 0, 14, 1, 0,
-  14, 2, 0, 0, 0, 33, 14, 52, 21, 0,
-  21, 0, 41, 46, 70, 27, 15, 0, 0, 0,
-  0, 6, 30, 0, 57, 63, 0, 18, 0, 0,
-  0, 0, 0, 23, 55, 0, 32, 0, 0, 0,
-  90, 0, 14, 0, 0, 0, 5, 1, 0, 0,
-  20, 7, 0, 0, 11, 29, 0, 45, 2, 0,
-  17, 0, 59, 0, 0, 24, 0, 0, 0, 0,
-  0, 40, 1, 11, 70, 0, 8, 10, 0, 0,
-  32, 0, 0, 0, 26, 22, 0, 7, 0, 0,
-  17, 26, 2, 0, 47, 0, 0, 21, 13, 9,
-  8, 0, 0, 0, 39, 2, 0, 18, 67, 54,
-  46, 0, 21, 0, 0, 41, 60, 20, 72, 13,
-  27, 31, 0, 123, 0, 13, 17, 0, 0, 28,
-  28, 13, 17, 0, 23, 19, 0, 3, 26, 0,
-  27, 0, 23, 0, 0, 39, 0, 0, 0, 3,
-  33, 0, 52, 9, 4, 75, 0, 0, 0, 0,
-  0, 100, 0, 0, 2, 0, 0, 11, 51, 34,
-  23, 0, 31, 0, 14, 0, 0, 0, 3, 31,
-  7, 0, 11, 24, 0, 20, 0, 8, 0, 0,
-  72, 0, 0, 35, 0, 0, 0, 0, 0, 45,
-  6, 0, 35, 11, 0, 11, 0, 0, 13, 0,
-  0, 0, 2, 13, 0, 0, 0, 0, 29, 44,
-  34, 0, 50, 0, 0, 11, 0, 7, 0, 0,
-  0, 0, 8, 60, 0, 0, 108, 136, 34, 5,
-  37, 0, 0, 24, 71, 27, 134, 39, 0, 0,
-  0, 158, 66, 0, 9, 0, 0, 10, 0, 0,
-  39, 0, 9, 0, 13, 5, 9, 0, 4, 0,
-  70, 0, 0, 80, 0, 0, 27, 0, 26, 0,
-  39, 45, 33, 130, 0, 0, 0, 0, 0, 84,
-  0, 0, 0, 0, 0, 24, 23, 13, 0, 0,
-  36, 0, 0, 0, 0, 0, 23, 31, 12, 0,
-  0, 15, 0, 0, 0, 50, 0, 0, 53, 14,
-  0, 2, 0, 0, 0, 0, 0, 48, 12, 0,
-  0, 0, 0, 19, 0, 0, 0, 3, 0, 0,
-  3, 11, 0, 0, 0, 9, 43, 82, 35, 0,
-  70, 0, 5, 16, 0, 7, 7, 0, 0, 0,
-  0, 63, 0, 0, 57, 160, 47, 9, 35, 0,
-  0, 29, 57, 0, 153, 4, 0, 0, 0, 121,
-  122, 0, 14, 27, 0, 33, 0, 0, 46, 0,
-  6, 0, 5, 13, 16, 0, 0, 10, 64, 0,
-  0, 128, 0, 0, 35, 0, 0, 0, 10, 76,
-  58, 96, 0, 0, 0, 0, 0, 62, 0, 0,
-  0, 3, 0, 35, 0, 0, 0, 0, 53, 0,
-  0, 0, 0, 0, 18, 28, 29, 0, 0, 129,
-  0, 59, 30, 0, 80, 0, 63, 0, 2, 62,
-  41, 13, 24, 8, 0, 36, 0, 50, 73, 0,
-  0, 34, 40, 69, 39, 5, 0, 13, 44, 0,
-  63, 0, 17, 0, 0, 0, 0, 0, 0, 30,
-  0, 55, 31, 26, 0, 15, 0, 0, 34, 0,
-  63, 66, 0, 6, 53, 0, 0, 76, 13, 0,
-  0, 0, 0, 0, 32, 81, 0, 0, 0, 20,
-  0, 0, 48, 49, 0, 0, 0, 0, 65, 72,
-  1, 0, 21, 0, 34, 0, 17, 106, 73, 0,
-  0, 66, 0, 33, 16, 0, 73, 22, 0, 27,
-  0, 0, 0, 0, 17, 70, 123, 31, 8, 0,
-  18, 0, 19, 0, 0, 0, 0, 0, 16, 21,
-  113, 10, 49, 16, 11, 0, 4, 112, 0, 54,
-  23, 0, 15, 0, 85, 7, 0, 53, 5, 3,
-  0, 0, 0, 18, 0, 13, 49, 0, 0, 31,
-  10, 11, 45, 17, 0, 0, 0, 9, 32, 0,
-  23, 0, 0, 18, 0, 0, 0, 0, 0, 18,
-  25, 27, 0, 0, 0, 0, 33, 14, 7, 64,
-  44, 38, 45, 0, 0, 10, 0, 11, 7, 12,
-  0, 7, 17, 45, 0, 29, 0, 13, 26, 0,
-  1, 55, 0, 8, 5, 0, 20, 44, 16, 23,
-  0, 0, 15, 29, 38, 55, 93, 0, 0, 17,
-  0, 0, 52, 0, 35, 52, 0, 80, 0, 0,
-  0, 0, 0, 84, 112, 0, 31, 0, 15, 3,
-  1, 0, 0, 0, 0, 0, 3, 0, 28, 0,
-  45, 32, 0, 0, 29, 57, 0, 24, 0, 27,
-  0, 0, 42, 0, 0, 31, 0, 13, 0, 0,
-  0, 38, 15, 0, 3, 20, 0, 0, 0, 0,
-  2, 0, 0, 0, 0, 33, 0, 0, 0, 22,
-  12, 36, 5, 0, 22, 0, 25, 16, 5, 0,
-  6, 0, 0, 0, 0, 74, 0, 26, 125, 100,
-  30, 22, 18, 0, 0, 43, 75, 37, 102, 36,
-  0, 20, 0, 109, 123, 3, 27, 0, 0, 17,
-  0, 0, 34, 0, 0, 1, 35, 33, 3, 0,
-  0, 8, 62, 0, 21, 30, 0, 0, 38, 0,
-  43, 0, 9, 59, 0, 117, 0, 0, 0, 0,
-  0, 80, 21, 0, 14, 0, 0, 24, 0, 0,
-  0, 0, 10, 0, 0, 0, 0, 0, 32, 35,
-  0, 0, 0, 50, 11, 21, 17, 0, 0, 0,
-  67, 0, 0, 42, 4, 106, 9, 17, 15, 45,
-  0, 24, 71, 0, 40, 19, 0, 0, 0, 3,
-  0, 0, 0, 0, 0, 10, 0, 0, 0, 0,
-  0, 0, 4, 19, 0, 50, 0, 0, 0, 45,
-  0, 0, 34, 65, 36, 45, 0, 0, 44, 0,
-  0, 0, 0, 0, 7, 0, 60, 7, 0, 7,
-  12, 15, 0, 0, 10, 2, 40, 0, 0, 0,
-  0, 1, 42, 35, 2, 0, 21, 0, 58, 15,
-  51, 12, 0, 30, 0, 0, 0, 9, 0, 0,
-  58, 45, 6, 2, 0, 0, 16, 0, 0, 13,
-  0, 3, 7, 0, 0, 0, 80, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 4, 12, 0,
-  20, 58, 19, 29, 24, 0, 0, 0, 79, 0,
-  0, 44, 19, 100, 0, 0, 0, 11, 0, 4,
-  57, 0, 28, 24, 0, 0, 2, 0, 0, 3,
-  5, 0, 0, 6, 0, 0, 0, 0, 0, 0,
-  0, 34, 0, 24, 0, 0, 6, 41, 0, 0,
-  50, 104, 10, 72, 18, 0, 43, 0, 5, 0,
-  0, 0, 14, 0, 25, 49, 0, 0, 0, 41,
-  0, 14, 1, 0, 14, 2, 0, 0, 0, 33,
-  14, 52, 21, 0, 21, 0, 41, 46, 70, 27,
-  15, 0, 0, 0, 0, 6, 30, 0, 57, 63,
-  0, 18, 0, 0, 0, 0, 0, 23, 55, 0,
-  32, 0, 0, 0, 90, 0, 14, 0, 0, 0,
-  5, 1, 0, 0, 20, 7, 0, 0, 56, 103,
-  0, 45, 15, 0, 0, 0, 58, 0, 0, 52,
-  30, 60, 0, 0, 0, 11, 22, 8, 26, 0,
-  0, 48, 0, 0, 58, 0, 0, 0, 19, 13,
-  0, 0, 3, 0, 0, 0, 0, 0, 0, 0,
-  0, 14, 26, 11, 2, 0, 0, 0, 23, 83,
-  1, 41, 67, 0, 39, 3, 0, 0, 0, 31,
-  34, 12, 4, 15, 0, 13, 0, 63, 0, 12,
-  10, 0, 0, 36, 0, 0, 33, 0, 0, 39,
-  30, 13, 0, 0, 19, 60, 73, 69, 93, 0,
-  0, 0, 0, 0, 59, 0, 21, 68, 23, 82,
-  0, 0, 0, 0, 0, 52, 129, 3, 21, 0,
-  0, 7, 40, 0, 0, 0, 3, 0, 26, 0,
-  14, 0, 57, 39, 0, 0, 11, 24, 0, 20,
-  0, 8, 0, 0, 72, 0, 0, 35, 0, 0,
-  0, 0, 0, 45, 6, 0, 35, 11, 0, 11,
-  0, 0, 13, 0, 0, 0, 2, 13, 0, 0,
-  0, 0, 29, 44, 34, 0, 50, 0, 0, 11,
-  0, 7, 0, 0, 0, 0, 8, 60, 0, 0,
-  108, 136, 34, 5, 37, 0, 0, 24, 71, 27,
-  134, 39, 0, 0, 0, 158, 66, 0, 9, 0,
-  0, 10, 0, 0, 39, 0, 9, 0, 13, 5,
-  9, 0, 4, 0, 70, 0, 0, 80, 0, 0,
-  27, 0, 26, 0, 39, 45, 33, 130, 0, 0,
-  0, 0, 0, 84, 0, 0, 0, 0, 0, 24,
-  23, 13, 0, 0, 36, 0, 0, 0, 0, 0,
-  23, 31, 12, 0, 0, 15, 0, 0, 0, 50,
-  0, 0, 53, 14, 0, 2, 0, 0, 0, 0,
-  0, 48, 12, 0, 0, 0, 0, 19, 0, 0,
-  0, 3, 0, 0, 3, 11, 0, 0, 0, 9,
-  43, 82, 35, 0, 70, 0, 5, 16, 0, 7,
-  7, 0, 0, 0, 0, 63, 0, 0, 57, 160,
-  47, 9, 35, 0, 0, 29, 57, 0, 153, 4,
-  0, 0, 0, 121, 122, 0, 14, 27, 0, 33,
-  0, 0, 46, 0, 6, 0, 5, 13, 16, 0,
-  0, 10, 64, 0, 0, 128, 0, 0, 35, 0,
-  0, 0, 10, 76, 58, 96, 0, 0, 0, 0,
-  0, 62, 0, 0, 0, 3, 0, 35, 0, 0,
-  0, 0, 53, 0, 0, 0, 0, 0, 18, 28,
-  29, 0, 0, 39, 0, 0, 0, 29, 0, 0,
-  78, 47, 0, 0, 30, 0, 0, 88, 39, 61,
-  6, 17, 0, 0, 0, 41, 0, 0, 7, 53,
-  6, 0, 17, 0, 36, 0, 0, 0, 35, 96,
-  0, 0, 48, 0, 9, 30, 0, 28, 42, 19,
-  0, 0, 0, 32, 2, 0, 4, 101, 46, 8,
-  0, 0, 0, 0, 0, 0, 66, 0, 6, 4,
-  24, 53, 52, 0, 17, 37, 0, 49, 0, 0,
-  5, 0, 39, 0, 0, 0, 0, 1, 0, 30,
-  51, 0, 0, 131, 0, 0, 11, 0, 0, 0,
-  0, 86, 87, 31, 0, 0, 0, 0, 0, 48,
-  0, 13, 0, 11, 0, 8, 2, 0, 0, 2,
-  51, 0, 25, 0, 41, 0, 28, 12, 43, 0,
-  4, 112, 0, 54, 23, 0, 15, 0, 85, 7,
-  0, 53, 5, 3, 0, 0, 0, 18, 0, 13,
-  49, 0, 0, 31, 10, 11, 45, 17, 0, 0,
-  0, 9, 32, 0, 23, 0, 0, 18, 0, 0,
-  0, 0, 0, 18, 25, 27, 0, 0, 0, 0,
-  33, 14, 7, 64, 44, 38, 45, 0, 0, 10,
-  0, 11, 7, 12, 0, 7, 17, 45, 0, 29,
-  0, 13, 26, 0, 1, 55, 0, 8, 5, 0,
-  20, 44, 16, 23, 0, 0, 15, 29, 38, 55,
-  93, 0, 0, 17, 0, 0, 52, 0, 35, 52,
-  0, 80, 0, 0, 0, 0, 0, 84, 112, 0,
-  31, 0, 15, 3, 1, 0, 0, 0, 0, 0,
-  3, 0, 28, 0, 45, 32, 0, 0, 29, 57,
-  0, 24, 0, 27, 0, 0, 42, 0, 0, 31,
-  0, 13, 0, 0, 0, 38, 15, 0, 3, 20,
-  0, 0, 0, 0, 2, 0, 0, 0, 0, 33,
-  0, 0, 0, 22, 12, 36, 5, 0, 22, 0,
-  25, 16, 5, 0, 6, 0, 0, 0, 0, 74,
-  0, 26, 125, 100, 30, 22, 18, 0, 0, 43,
-  75, 37, 102, 36, 0, 20, 0, 109, 123, 3,
-  27, 0, 0, 17, 0, 0, 34, 0, 0, 1,
-  35, 33, 3, 0, 0, 8, 62, 0, 21, 30,
-  0, 0, 38, 0, 43, 0, 9, 59, 0, 117,
-  0, 0, 0, 0, 0, 80, 21, 0, 14, 0,
-  0, 24, 0, 0, 0, 0, 10, 0, 0, 0,
-  0, 0, 32, 35, 0, 0, 10, 25, 0, 0,
-  0, 85, 0, 0, 22, 0, 0, 0, 0, 0,
-  0, 0, 0, 39, 3, 8, 0, 40, 0, 0,
-  0, 0, 8, 3, 0, 0, 0, 38, 0, 0,
-  0, 43, 47, 68, 23, 0, 46, 0, 22, 15,
-  0, 13, 59, 13, 0, 0, 0, 55, 0, 0,
-  112, 118, 34, 26, 48, 0, 0, 57, 67, 0,
-  179, 5, 0, 32, 0, 139, 175, 0, 10, 15,
-  0, 0, 0, 0, 42, 0, 0, 0, 28, 19,
-  31, 0, 0, 11, 42, 0, 0, 116, 13, 0,
-  34, 0, 0, 0, 6, 54, 43, 142, 0, 0,
-  0, 0, 0, 58, 0, 0, 0, 29, 0, 30,
-  0, 10, 0, 0, 53, 0, 0, 0, 0, 0,
-  1, 29, 1, 6, 20, 58, 19, 29, 24, 0,
-  0, 0, 79, 0, 0, 44, 19, 100, 0, 0,
-  0, 11, 0, 4, 57, 0, 28, 24, 0, 0,
-  2, 0, 0, 3, 5, 0, 0, 6, 0, 0,
-  0, 0, 0, 0, 0, 34, 0, 24, 0, 0,
-  6, 41, 0, 0, 50, 104, 10, 72, 18, 0,
-  43, 0, 5, 0, 0, 0, 14, 0, 25, 49,
-  0, 0, 0, 41, 0, 14, 1, 0, 14, 2,
-  0, 0, 0, 33, 14, 52, 21, 0, 21, 0,
-  41, 46, 70, 27, 15, 0, 0, 0, 0, 6,
-  30, 0, 57, 63, 0, 18, 0, 0, 0, 0,
-  0, 23, 55, 0, 32, 0, 0, 0, 90, 0,
-  14, 0, 0, 0, 5, 1, 0, 0, 20, 7,
-  0, 0, 56, 103, 0, 45, 15, 0, 0, 0,
-  58, 0, 0, 52, 30, 60, 0, 0, 0, 11,
-  22, 8, 26, 0, 0, 48, 0, 0, 58, 0,
-  0, 0, 19, 13, 0, 0, 3, 0, 0, 0,
-  0, 0, 0, 0, 0, 14, 26, 11, 2, 0,
-  0, 0, 23, 83, 1, 41, 67, 0, 39, 3,
-  0, 0, 0, 31, 34, 12, 4, 15, 0, 13,
-  0, 63, 0, 12, 10, 0, 0, 36, 0, 0,
-  33, 0, 0, 39, 30, 13, 0, 0, 19, 60,
-  73, 69, 93, 0, 0, 0, 0, 0, 59, 0,
-  21, 68, 23, 82, 0, 0, 0, 0, 0, 52,
-  129, 3, 21, 0, 0, 7, 40, 0, 0, 0,
-  3, 0, 26, 0, 14, 0, 57, 39, 0, 0,
-  46, 82, 0, 50, 1, 35, 0, 0, 22, 0,
-  0, 15, 41, 6, 0, 0, 0, 19, 21, 11,
-  13, 31, 0, 0, 0, 0, 64, 0, 0, 0,
-  30, 54, 0, 0, 28, 29, 0, 17, 0, 0,
-  0, 0, 1, 18, 5, 11, 10, 0, 0, 0,
-  0, 57, 0, 22, 95, 48, 30, 4, 0, 0,
-  0, 73, 54, 11, 88, 0, 0, 66, 0, 94,
-  130, 13, 9, 0, 0, 4, 0, 2, 68, 0,
-  0, 0, 23, 16, 20, 0, 0, 28, 33, 13,
-  56, 0, 0, 0, 6, 0, 47, 0, 18, 68,
-  22, 150, 0, 0, 0, 0, 0, 82, 91, 0,
-  7, 26, 10, 31, 0, 0, 0, 0, 31, 0,
-  0, 0, 0, 0, 50, 35, 0, 2, 0, 15,
-  0, 0, 0, 50, 0, 0, 53, 14, 0, 2,
-  0, 0, 0, 0, 0, 48, 12, 0, 0, 0,
-  0, 19, 0, 0, 0, 3, 0, 0, 3, 11,
-  0, 0, 0, 9, 43, 82, 35, 0, 70, 0,
-  5, 16, 0, 7, 7, 0, 0, 0, 0, 63,
-  0, 0, 57, 160, 47, 9, 35, 0, 0, 29,
-  57, 0, 153, 4, 0, 0, 0, 121, 122, 0,
-  14, 27, 0, 33, 0, 0, 46, 0, 6, 0,
-  5, 13, 16, 0, 0, 10, 64, 0, 0, 128,
-  0, 0, 35, 0, 0, 0, 10, 76, 58, 96,
-  0, 0, 0, 0, 0, 62, 0, 0, 0, 3,
-  0, 35, 0, 0, 0, 0, 53, 0, 0, 0,
-  0, 0, 18, 28, 29, 0, 0, 39, 0, 0,
-  0, 29, 0, 0, 78, 47, 0, 0, 30, 0,
-  0, 88, 39, 61, 6, 17, 0, 0, 0, 41,
-  0, 0, 7, 53, 6, 0, 17, 0, 36, 0,
-  0, 0, 35, 96, 0, 0, 48, 0, 9, 30,
-  0, 28, 42, 19, 0, 0, 0, 32, 2, 0,
-  4, 101, 46, 8, 0, 0, 0, 0, 0, 0,
-  66, 0, 6, 4, 24, 53, 52, 0, 17, 37,
-  0, 49, 0, 0, 5, 0, 39, 0, 0, 0,
-  0, 1, 0, 30, 51, 0, 0, 131, 0, 0,
-  11, 0, 0, 0, 0, 86, 87, 31, 0, 0,
-  0, 0, 0, 48, 0, 13, 0, 11, 0, 8,
-  2, 0, 0, 2, 51, 0, 25, 0, 41, 0,
-  28, 12, 43, 0, 0, 93, 41, 0, 7, 0,
-  52, 3, 86, 40, 12, 0, 76, 3, 0, 125,
-  70, 39, 2, 33, 0, 0, 0, 54, 36, 13,
-  16, 61, 3, 0, 21, 0, 90, 1, 0, 0,
-  0, 58, 0, 29, 9, 0, 26, 52, 0, 59,
-  72, 36, 0, 44, 0, 0, 84, 12, 0, 0,
-  22, 0, 0, 42, 0, 0, 0, 0, 0, 0,
-  47, 0, 62, 0, 0, 0, 2, 50, 38, 28,
-  0, 0, 0, 0, 77, 11, 8, 0, 0, 21,
-  0, 22, 43, 0, 0, 57, 0, 32, 0, 0,
-  0, 0, 0, 79, 66, 0, 0, 0, 15, 0,
-  10, 29, 0, 69, 0, 1, 0, 0, 0, 0,
-  0, 36, 65, 0, 62, 0, 139, 0, 57, 16,
-  25, 0, 29, 57, 0, 24, 0, 27, 0, 0,
-  42, 0, 0, 31, 0, 13, 0, 0, 0, 38,
-  15, 0, 3, 20, 0, 0, 0, 0, 2, 0,
-  0, 0, 0, 33, 0, 0, 0, 22, 12, 36,
-  5, 0, 22, 0, 25, 16, 5, 0, 6, 0,
-  0, 0, 0, 74, 0, 26, 125, 100, 30, 22,
-  18, 0, 0, 43, 75, 37, 102, 36, 0, 20,
-  0, 109, 123, 3, 27, 0, 0, 17, 0, 0,
-  34, 0, 0, 1, 35, 33, 3, 0, 0, 8,
-  62, 0, 21, 30, 0, 0, 38, 0, 43, 0,
-  9, 59, 0, 117, 0, 0, 0, 0, 0, 80,
-  21, 0, 14, 0, 0, 24, 0, 0, 0, 0,
-  10, 0, 0, 0, 0, 0, 32, 35, 0, 0,
-  10, 25, 0, 0, 0, 85, 0, 0, 22, 0,
-  0, 0, 0, 0, 0, 0, 0, 39, 3, 8,
-  0, 40, 0, 0, 0, 0, 8, 3, 0, 0,
-  0, 38, 0, 0, 0, 43, 47, 68, 23, 0,
-  46, 0, 22, 15, 0, 13, 59, 13, 0, 0,
-  0, 55, 0, 0, 112, 118, 34, 26, 48, 0,
-  0, 57, 67, 0, 179, 5, 0, 32, 0, 139,
-  175, 0, 10, 15, 0, 0, 0, 0, 42, 0,
-  0, 0, 28, 19, 31, 0, 0, 11, 42, 0,
-  0, 116, 13, 0, 34, 0, 0, 0, 6, 54,
-  43, 142, 0, 0, 0, 0, 0, 58, 0, 0,
-  0, 29, 0, 30, 0, 10, 0, 0, 53, 0,
-  0, 0, 0, 0, 1, 29, 1, 6, 0, 37,
-  0, 0, 0, 81, 0, 0, 83, 32, 0, 0,
-  0, 9, 0, 42, 6, 26, 0, 10, 0, 0,
-  0, 25, 0, 0, 22, 40, 7, 0, 0, 0,
-  67, 0, 0, 20, 33, 86, 0, 0, 32, 0,
-  0, 10, 0, 67, 54, 81, 0, 26, 0, 6,
-  0, 0, 25, 36, 58, 0, 32, 0, 0, 65,
-  0, 0, 102, 0, 0, 34, 25, 57, 85, 0,
-  33, 59, 0, 79, 0, 0, 3, 0, 3, 0,
-  2, 0, 0, 0, 0, 49, 15, 0, 0, 173,
-  0, 0, 0, 0, 0, 0, 0, 64, 113, 110,
-  0, 0, 0, 0, 0, 29, 0, 22, 0, 30,
-  0, 19, 0, 0, 0, 29, 61, 0, 40, 0,
-  0, 0, 0, 15, 1, 35, 56, 103, 0, 45,
-  15, 0, 0, 0, 58, 0, 0, 52, 30, 60,
-  0, 0, 0, 11, 22, 8, 26, 0, 0, 48,
-  0, 0, 58, 0, 0, 0, 19, 13, 0, 0,
-  3, 0, 0, 0, 0, 0, 0, 0, 0, 14,
-  26, 11, 2, 0, 0, 0, 23, 83, 1, 41,
-  67, 0, 39, 3, 0, 0, 0, 31, 34, 12,
-  4, 15, 0, 13, 0, 63, 0, 12, 10, 0,
-  0, 36, 0, 0, 33, 0, 0, 39, 30, 13,
-  0, 0, 19, 60, 73, 69, 93, 0, 0, 0,
-  0, 0, 59, 0, 21, 68, 23, 82, 0, 0,
-  0, 0, 0, 52, 129, 3, 21, 0, 0, 7,
-  40, 0, 0, 0, 3, 0, 26, 0, 14, 0,
-  57, 39, 0, 0, 46, 82, 0, 50, 1, 35,
-  0, 0, 22, 0, 0, 15, 41, 6, 0, 0,
-  0, 19, 21, 11, 13, 31, 0, 0, 0, 0,
-  64, 0, 0, 0, 30, 54, 0, 0, 28, 29,
-  0, 17, 0, 0, 0, 0, 1, 18, 5, 11,
-  10, 0, 0, 0, 0, 57, 0, 22, 95, 48,
-  30, 4, 0, 0, 0, 73, 54, 11, 88, 0,
-  0, 66, 0, 94, 130, 13, 9, 0, 0, 4,
-  0, 2, 68, 0, 0, 0, 23, 16, 20, 0,
-  0, 28, 33, 13, 56, 0, 0, 0, 6, 0,
-  47, 0, 18, 68, 22, 150, 0, 0, 0, 0,
-  0, 82, 91, 0, 7, 26, 10, 31, 0, 0,
-  0, 0, 31, 0, 0, 0, 0, 0, 50, 35,
-  0, 2, 1, 12, 0, 19, 0, 115, 0, 0,
-  17, 0, 0, 0, 0, 1, 0, 0, 0, 28,
-  11, 16, 0, 65, 2, 0, 0, 0, 23, 0,
-  0, 0, 0, 17, 8, 0, 9, 65, 12, 45,
-  5, 0, 48, 0, 0, 18, 0, 33, 46, 0,
-  0, 7, 0, 29, 0, 0, 131, 59, 54, 5,
-  43, 0, 0, 107, 51, 0, 166, 0, 0, 46,
-  0, 112, 193, 0, 44, 0, 0, 35, 0, 0,
-  29, 0, 0, 0, 32, 0, 28, 0, 0, 1,
-  14, 0, 0, 79, 16, 0, 38, 0, 0, 0,
-  3, 61, 47, 127, 0, 0, 0, 0, 0, 36,
-  0, 0, 0, 55, 0, 53, 0, 0, 0, 0,
-  47, 0, 0, 0, 0, 0, 13, 18, 0, 12,
-  0, 39, 0, 0, 0, 29, 0, 0, 78, 47,
-  0, 0, 30, 0, 0, 88, 39, 61, 6, 17,
-  0, 0, 0, 41, 0, 0, 7, 53, 6, 0,
-  17, 0, 36, 0, 0, 0, 35, 96, 0, 0,
-  48, 0, 9, 30, 0, 28, 42, 19, 0, 0,
-  0, 32, 2, 0, 4, 101, 46, 8, 0, 0,
-  0, 0, 0, 0, 66, 0, 6, 4, 24, 53,
-  52, 0, 17, 37, 0, 49, 0, 0, 5, 0,
-  39, 0, 0, 0, 0, 1, 0, 30, 51, 0,
-  0, 131, 0, 0, 11, 0, 0, 0, 0, 86,
-  87, 31, 0, 0, 0, 0, 0, 48, 0, 13,
-  0, 11, 0, 8, 2, 0, 0, 2, 51, 0,
-  25, 0, 41, 0, 28, 12, 43, 0, 0, 93,
-  41, 0, 7, 0, 52, 3, 86, 40, 12, 0,
-  76, 3, 0, 125, 70, 39, 2, 33, 0, 0,
-  0, 54, 36, 13, 16, 61, 3, 0, 21, 0,
-  90, 1, 0, 0, 0, 58, 0, 29, 9, 0,
-  26, 52, 0, 59, 72, 36, 0, 44, 0, 0,
-  84, 12, 0, 0, 22, 0, 0, 42, 0, 0,
-  0, 0, 0, 0, 47, 0, 62, 0, 0, 0,
-  2, 50, 38, 28, 0, 0, 0, 0, 77, 11,
-  8, 0, 0, 21, 0, 22, 43, 0, 0, 57,
-  0, 32, 0, 0, 0, 0, 0, 79, 66, 0,
-  0, 0, 15, 0, 10, 29, 0, 69, 0, 1,
-  0, 0, 0, 0, 0, 36, 65, 0, 62, 0,
-  139, 0, 57, 16, 25, 0, 0, 58, 49, 0,
-  14, 0, 50, 16, 63, 8, 3, 26, 61, 1,
-  7, 53, 52, 0, 0, 15, 0, 27, 43, 19,
-  23, 0, 0, 13, 0, 0, 0, 0, 41, 0,
-  0, 6, 0, 16, 0, 79, 0, 24, 0, 55,
-  1, 70, 61, 46, 0, 21, 0, 20, 72, 1,
-  0, 0, 29, 0, 0, 0, 15, 36, 0, 43,
-  0, 14, 0, 0, 79, 0, 0, 0, 7, 27,
-  66, 15, 34, 28, 0, 0, 79, 0, 29, 0,
-  25, 0, 16, 0, 0, 0, 0, 0, 0, 17,
-  0, 26, 0, 0, 5, 71, 31, 0, 0, 0,
-  26, 0, 28, 0, 0, 38, 0, 0, 0, 2,
-  0, 0, 2, 14, 69, 0, 27, 0, 63, 0,
-  43, 7, 17, 0, 10, 25, 0, 0, 0, 85,
-  0, 0, 22, 0, 0, 0, 0, 0, 0, 0,
-  0, 39, 3, 8, 0, 40, 0, 0, 0, 0,
-  8, 3, 0, 0, 0, 38, 0, 0, 0, 43,
-  47, 68, 23, 0, 46, 0, 22, 15, 0, 13,
-  59, 13, 0, 0, 0, 55, 0, 0, 112, 118,
-  34, 26, 48, 0, 0, 57, 67, 0, 179, 5,
-  0, 32, 0, 139, 175, 0, 10, 15, 0, 0,
-  0, 0, 42, 0, 0, 0, 28, 19, 31, 0,
-  0, 11, 42, 0, 0, 116, 13, 0, 34, 0,
-  0, 0, 6, 54, 43, 142, 0, 0, 0, 0,
-  0, 58, 0, 0, 0, 29, 0, 30, 0, 10,
-  0, 0, 53, 0, 0, 0, 0, 0, 1, 29,
-  1, 6, 0, 37, 0, 0, 0, 81, 0, 0,
-  83, 32, 0, 0, 0, 9, 0, 42, 6, 26,
-  0, 10, 0, 0, 0, 25, 0, 0, 22, 40,
-  7, 0, 0, 0, 67, 0, 0, 20, 33, 86,
-  0, 0, 32, 0, 0, 10, 0, 67, 54, 81,
-  0, 26, 0, 6, 0, 0, 25, 36, 58, 0,
-  32, 0, 0, 65, 0, 0, 102, 0, 0, 34,
-  25, 57, 85, 0, 33, 59, 0, 79, 0, 0,
-  3, 0, 3, 0, 2, 0, 0, 0, 0, 49,
-  15, 0, 0, 173, 0, 0, 0, 0, 0, 0,
-  0, 64, 113, 110, 0, 0, 0, 0, 0, 29,
-  0, 22, 0, 30, 0, 19, 0, 0, 0, 29,
-  61, 0, 40, 0, 0, 0, 0, 15, 1, 35,
-  0, 34, 21, 0, 0, 0, 48, 33, 91, 15,
-  14, 16, 57, 1, 0, 81, 49, 0, 0, 0,
-  6, 20, 26, 30, 1, 0, 0, 23, 0, 0,
-  0, 0, 60, 0, 3, 0, 0, 56, 0, 42,
-  4, 5, 0, 43, 0, 101, 57, 64, 0, 36,
-  0, 14, 67, 0, 0, 0, 60, 0, 18, 0,
-  6, 36, 0, 46, 0, 0, 0, 0, 80, 0,
-  0, 0, 27, 50, 26, 48, 16, 11, 0, 0,
-  59, 0, 25, 0, 0, 9, 9, 3, 5, 0,
-  0, 63, 0, 14, 0, 0, 0, 0, 4, 79,
-  88, 0, 0, 0, 17, 0, 30, 2, 0, 51,
-  0, 7, 0, 20, 0, 0, 0, 31, 77, 0,
-  50, 0, 85, 0, 42, 0, 14, 0, 46, 82,
-  0, 50, 1, 35, 0, 0, 22, 0, 0, 15,
-  41, 6, 0, 0, 0, 19, 21, 11, 13, 31,
-  0, 0, 0, 0, 64, 0, 0, 0, 30, 54,
-  0, 0, 28, 29, 0, 17, 0, 0, 0, 0,
-  1, 18, 5, 11, 10, 0, 0, 0, 0, 57,
-  0, 22, 95, 48, 30, 4, 0, 0, 0, 73,
-  54, 11, 88, 0, 0, 66, 0, 94, 130, 13,
-  9, 0, 0, 4, 0, 2, 68, 0, 0, 0,
-  23, 16, 20, 0, 0, 28, 33, 13, 56, 0,
-  0, 0, 6, 0, 47, 0, 18, 68, 22, 150,
-  0, 0, 0, 0, 0, 82, 91, 0, 7, 26,
-  10, 31, 0, 0, 0, 0, 31, 0, 0, 0,
-  0, 0, 50, 35, 0, 2, 1, 12, 0, 19,
-  0, 115, 0, 0, 17, 0, 0, 0, 0, 1,
-  0, 0, 0, 28, 11, 16, 0, 65, 2, 0,
-  0, 0, 23, 0, 0, 0, 0, 17, 8, 0,
-  9, 65, 12, 45, 5, 0, 48, 0, 0, 18,
-  0, 33, 46, 0, 0, 7, 0, 29, 0, 0,
-  131, 59, 54, 5, 43, 0, 0, 107, 51, 0,
-  166, 0, 0, 46, 0, 112, 193, 0, 44, 0,
-  0, 35, 0, 0, 29, 0, 0, 0, 32, 0,
-  28, 0, 0, 1, 14, 0, 0, 79, 16, 0,
-  38, 0, 0, 0, 3, 61, 47, 127, 0, 0,
-  0, 0, 0, 36, 0, 0, 0, 55, 0, 53,
-  0, 0, 0, 0, 47, 0, 0, 0, 0, 0,
-  13, 18, 0, 12, 0, 1, 0, 0, 0, 57,
-  0, 18, 70, 15, 0, 4, 0, 0, 0, 50,
-  13, 20, 0, 0, 47, 47, 29, 12, 0, 0,
-  0, 10, 0, 0, 0, 0, 50, 0, 0, 44,
-  0, 64, 0, 0, 54, 0, 0, 47, 0, 99,
-  16, 46, 0, 15, 0, 37, 0, 0, 63, 0,
-  74, 0, 64, 0, 0, 62, 0, 0, 90, 0,
-  0, 12, 30, 23, 61, 0, 70, 60, 0, 76,
-  0, 1, 0, 0, 21, 0, 0, 0, 0, 0,
-  8, 0, 5, 0, 0, 121, 9, 0, 0, 0,
-  0, 0, 20, 54, 116, 17, 0, 0, 0, 0,
-  11, 9, 0, 21, 0, 19, 0, 73, 0, 0,
-  0, 0, 56, 0, 53, 0, 0, 0, 21, 0,
-  18, 0, 0, 93, 41, 0, 7, 0, 52, 3,
-  86, 40, 12, 0, 76, 3, 0, 125, 70, 39,
-  2, 33, 0, 0, 0, 54, 36, 13, 16, 61,
-  3, 0, 21, 0, 90, 1, 0, 0, 0, 58,
-  0, 29, 9, 0, 26, 52, 0, 59, 72, 36,
-  0, 44, 0, 0, 84, 12, 0, 0, 22, 0,
-  0, 42, 0, 0, 0, 0, 0, 0, 47, 0,
-  62, 0, 0, 0, 2, 50, 38, 28, 0, 0,
-  0, 0, 77, 11, 8, 0, 0, 21, 0, 22,
-  43, 0, 0, 57, 0, 32, 0, 0, 0, 0,
-  0, 79, 66, 0, 0, 0, 15, 0, 10, 29,
-  0, 69, 0, 1, 0, 0, 0, 0, 0, 36,
-  65, 0, 62, 0, 139, 0, 57, 16, 25, 0,
-  0, 58, 49, 0, 14, 0, 50, 16, 63, 8,
-  3, 26, 61, 1, 7, 53, 52, 0, 0, 15,
-  0, 27, 43, 19, 23, 0, 0, 13, 0, 0,
-  0, 0, 41, 0, 0, 6, 0, 16, 0, 79,
-  0, 24, 0, 55, 1, 70, 61, 46, 0, 21,
-  0, 20, 72, 1, 0, 0, 29, 0, 0, 0,
-  15, 36, 0, 43, 0, 14, 0, 0, 79, 0,
-  0, 0, 7, 27, 66, 15, 34, 28, 0, 0,
-  79, 0, 29, 0, 25, 0, 16, 0, 0, 0,
-  0, 0, 0, 17, 0, 26, 0, 0, 5, 71,
-  31, 0, 0, 0, 26, 0, 28, 0, 0, 38,
-  0, 0, 0, 2, 0, 0, 2, 14, 69, 0,
-  27, 0, 63, 0, 43, 7, 17, 0, 0, 6,
-  0, 0, 0, 1, 30, 12, 26, 0, 0, 25,
-  43, 0, 8, 23, 56, 23, 0, 0, 32, 29,
-  18, 2, 25, 0, 0, 0, 0, 0, 0, 0,
-  36, 17, 0, 0, 0, 0, 0, 34, 0, 11,
-  0, 58, 21, 87, 29, 59, 0, 1, 0, 52,
-  63, 0, 3, 0, 12, 0, 0, 0, 25, 4,
-  0, 38, 0, 10, 4, 0, 42, 0, 34, 0,
-  0, 17, 34, 0, 45, 41, 0, 0, 77, 0,
-  55, 0, 5, 0, 14, 0, 0, 0, 0, 31,
-  0, 0, 0, 22, 0, 0, 32, 57, 30, 0,
-  0, 9, 8, 0, 15, 0, 0, 13, 0, 14,
-  0, 2, 0, 0, 29, 0, 33, 0, 14, 0,
-  33, 0, 13, 6, 20, 0, 0, 37, 0, 0,
-  0, 81, 0, 0, 83, 32, 0, 0, 0, 9,
-  0, 42, 6, 26, 0, 10, 0, 0, 0, 25,
-  0, 0, 22, 40, 7, 0, 0, 0, 67, 0,
-  0, 20, 33, 86, 0, 0, 32, 0, 0, 10,
-  0, 67, 54, 81, 0, 26, 0, 6, 0, 0,
-  25, 36, 58, 0, 32, 0, 0, 65, 0, 0,
-  102, 0, 0, 34, 25, 57, 85, 0, 33, 59,
-  0, 79, 0, 0, 3, 0, 3, 0, 2, 0,
-  0, 0, 0, 49, 15, 0, 0, 173, 0, 0,
-  0, 0, 0, 0, 0, 64, 113, 110, 0, 0,
-  0, 0, 0, 29, 0, 22, 0, 30, 0, 19,
-  0, 0, 0, 29, 61, 0, 40, 0, 0, 0,
-  0, 15, 1, 35, 0, 34, 21, 0, 0, 0,
-  48, 33, 91, 15, 14, 16, 57, 1, 0, 81,
-  49, 0, 0, 0, 6, 20, 26, 30, 1, 0,
-  0, 23, 0, 0, 0, 0, 60, 0, 3, 0,
-  0, 56, 0, 42, 4, 5, 0, 43, 0, 101,
-  57, 64, 0, 36, 0, 14, 67, 0, 0, 0,
-  60, 0, 18, 0, 6, 36, 0, 46, 0, 0,
-  0, 0, 80, 0, 0, 0, 27, 50, 26, 48,
-  16, 11, 0, 0, 59, 0, 25, 0, 0, 9,
-  9, 3, 5, 0, 0, 63, 0, 14, 0, 0,
-  0, 0, 4, 79, 88, 0, 0, 0, 17, 0,
-  30, 2, 0, 51, 0, 7, 0, 20, 0, 0,
-  0, 31, 77, 0, 50, 0, 85, 0, 42, 0,
-  14, 0, 0, 27, 0, 6, 0, 0, 33, 17,
-  40, 0, 12, 29, 62, 0, 14, 33, 65, 28,
-  0, 0, 26, 32, 26, 12, 42, 0, 0, 27,
-  0, 0, 0, 0, 69, 0, 0, 0, 0, 14,
-  0, 40, 0, 14, 0, 40, 23, 88, 0, 29,
-  0, 18, 0, 24, 66, 1, 4, 0, 0, 0,
-  0, 0, 30, 14, 0, 50, 0, 7, 42, 0,
-  37, 0, 0, 0, 0, 48, 16, 0, 58, 78,
-  0, 0, 60, 0, 43, 4, 0, 14, 12, 0,
-  0, 2, 0, 24, 0, 6, 0, 25, 4, 0,
-  5, 84, 38, 0, 0, 3, 48, 0, 12, 5,
-  0, 1, 0, 12, 0, 2, 0, 0, 15, 0,
-  12, 0, 16, 0, 60, 0, 26, 0, 25, 0,
-  1, 12, 0, 19, 0, 115, 0, 0, 17, 0,
-  0, 0, 0, 1, 0, 0, 0, 28, 11, 16,
-  0, 65, 2, 0, 0, 0, 23, 0, 0, 0,
-  0, 17, 8, 0, 9, 65, 12, 45, 5, 0,
-  48, 0, 0, 18, 0, 33, 46, 0, 0, 7,
-  0, 29, 0, 0, 131, 59, 54, 5, 43, 0,
-  0, 107, 51, 0, 166, 0, 0, 46, 0, 112,
-  193, 0, 44, 0, 0, 35, 0, 0, 29, 0,
-  0, 0, 32, 0, 28, 0, 0, 1, 14, 0,
-  0, 79, 16, 0, 38, 0, 0, 0, 3, 61,
-  47, 127, 0, 0, 0, 0, 0, 36, 0, 0,
-  0, 55, 0, 53, 0, 0, 0, 0, 47, 0,
-  0, 0, 0, 0, 13, 18, 0, 12, 0, 1,
-  0, 0, 0, 57, 0, 18, 70, 15, 0, 4,
-  0, 0, 0, 50, 13, 20, 0, 0, 47, 47,
-  29, 12, 0, 0, 0, 10, 0, 0, 0, 0,
-  50, 0, 0, 44, 0, 64, 0, 0, 54, 0,
-  0, 47, 0, 99, 16, 46, 0, 15, 0, 37,
-  0, 0, 63, 0, 74, 0, 64, 0, 0, 62,
-  0, 0, 90, 0, 0, 12, 30, 23, 61, 0,
-  70, 60, 0, 76, 0, 1, 0, 0, 21, 0,
-  0, 0, 0, 0, 8, 0, 5, 0, 0, 121,
-  9, 0, 0, 0, 0, 0, 20, 54, 116, 17,
-  0, 0, 0, 0, 11, 9, 0, 21, 0, 19,
-  0, 73, 0, 0, 0, 0, 56, 0, 53, 0,
-  0, 0, 21, 0, 18, 0, 0, 48, 16, 0,
-  0, 0, 50, 44, 75, 3, 3, 42, 110, 0,
-  16, 61, 79, 13, 2, 0, 31, 54, 4, 6,
-  49, 0, 0, 45, 0, 0, 0, 0, 83, 0,
-  2, 0, 0, 62, 0, 80, 0, 35, 4, 49,
-  18, 97, 6, 35, 0, 42, 0, 40, 48, 0,
-  23, 0, 3, 0, 0, 0, 0, 5, 0, 59,
-  0, 17, 20, 0, 40, 0, 0, 0, 0, 48,
-  8, 0, 29, 54, 0, 0, 33, 0, 42, 5,
-  0, 9, 4, 0, 0, 8, 0, 4, 0, 44,
-  0, 13, 5, 8, 15, 84, 41, 0, 0, 0,
-  34, 0, 24, 13, 4, 22, 0, 21, 0, 22,
-  0, 0, 0, 0, 35, 0, 31, 0, 111, 0,
-  71, 0, 32, 0, 0, 58, 49, 0, 14, 0,
-  50, 16, 63, 8, 3, 26, 61, 1, 7, 53,
-  52, 0, 0, 15, 0, 27, 43, 19, 23, 0,
-  0, 13, 0, 0, 0, 0, 41, 0, 0, 6,
-  0, 16, 0, 79, 0, 24, 0, 55, 1, 70,
-  61, 46, 0, 21, 0, 20, 72, 1, 0, 0,
-  29, 0, 0, 0, 15, 36, 0, 43, 0, 14,
-  0, 0, 79, 0, 0, 0, 7, 27, 66, 15,
-  34, 28, 0, 0, 79, 0, 29, 0, 25, 0,
-  16, 0, 0, 0, 0, 0, 0, 17, 0, 26,
-  0, 0, 5, 71, 31, 0, 0, 0, 26, 0,
-  28, 0, 0, 38, 0, 0, 0, 2, 0, 0,
-  2, 14, 69, 0, 27, 0, 63, 0, 43, 7,
-  17, 0, 0, 6, 0, 0, 0, 1, 30, 12,
-  26, 0, 0, 25, 43, 0, 8, 23, 56, 23,
-  0, 0, 32, 29, 18, 2, 25, 0, 0, 0,
-  0, 0, 0, 0, 36, 17, 0, 0, 0, 0,
-  0, 34, 0, 11, 0, 58, 21, 87, 29, 59,
-  0, 1, 0, 52, 63, 0, 3, 0, 12, 0,
-  0, 0, 25, 4, 0, 38, 0, 10, 4, 0,
-  42, 0, 34, 0, 0, 17, 34, 0, 45, 41,
-  0, 0, 77, 0, 55, 0, 5, 0, 14, 0,
-  0, 0, 0, 31, 0, 0, 0, 22, 0, 0,
-  32, 57, 30, 0, 0, 9, 8, 0, 15, 0,
-  0, 13, 0, 14, 0, 2, 0, 0, 29, 0,
-  33, 0, 14, 0, 33, 0, 13, 6, 20, 0,
-  0, 5, 0, 30, 11, 9, 0, 0, 16, 0,
-  14, 0, 28, 0, 0, 43, 62, 17, 0, 4,
-  0, 0, 0, 14, 39, 0, 19, 14, 0, 0,
-  0, 0, 39, 51, 0, 0, 0, 0, 8, 0,
-  0, 0, 0, 26, 0, 76, 41, 64, 0, 17,
-  0, 73, 78, 15, 1, 58, 0, 0, 0, 0,
-  35, 0, 0, 26, 0, 0, 54, 0, 52, 39,
-  59, 0, 0, 16, 4, 0, 13, 36, 0, 0,
-  89, 0, 49, 0, 0, 20, 1, 30, 0, 0,
-  0, 79, 0, 0, 39, 0, 21, 0, 17, 79,
-  53, 5, 0, 14, 0, 0, 0, 9, 0, 17,
-  0, 33, 0, 25, 0, 0, 3, 0, 0, 0,
-  0, 0, 77, 0, 14, 5, 4, 0, 0, 34,
-  21, 0, 0, 0, 48, 33, 91, 15, 14, 16,
-  57, 1, 0, 81, 49, 0, 0, 0, 6, 20,
-  26, 30, 1, 0, 0, 23, 0, 0, 0, 0,
-  60, 0, 3, 0, 0, 56, 0, 42, 4, 5,
-  0, 43, 0, 101, 57, 64, 0, 36, 0, 14,
-  67, 0, 0, 0, 60, 0, 18, 0, 6, 36,
-  0, 46, 0, 0, 0, 0, 80, 0, 0, 0,
-  27, 50, 26, 48, 16, 11, 0, 0, 59, 0,
-  25, 0, 0, 9, 9, 3, 5, 0, 0, 63,
-  0, 14, 0, 0, 0, 0, 4, 79, 88, 0,
-  0, 0, 17, 0, 30, 2, 0, 51, 0, 7,
-  0, 20, 0, 0, 0, 31, 77, 0, 50, 0,
-  85, 0, 42, 0, 14, 0, 0, 27, 0, 6,
-  0, 0, 33, 17, 40, 0, 12, 29, 62, 0,
-  14, 33, 65, 28, 0, 0, 26, 32, 26, 12,
-  42, 0, 0, 27, 0, 0, 0, 0, 69, 0,
-  0, 0, 0, 14, 0, 40, 0, 14, 0, 40,
-  23, 88, 0, 29, 0, 18, 0, 24, 66, 1,
-  4, 0, 0, 0, 0, 0, 30, 14, 0, 50,
-  0, 7, 42, 0, 37, 0, 0, 0, 0, 48,
-  16, 0, 58, 78, 0, 0, 60, 0, 43, 4,
-  0, 14, 12, 0, 0, 2, 0, 24, 0, 6,
-  0, 25, 4, 0, 5, 84, 38, 0, 0, 3,
-  48, 0, 12, 5, 0, 1, 0, 12, 0, 2,
-  0, 0, 15, 0, 12, 0, 16, 0, 60, 0,
-  26, 0, 25, 0, 32, 14, 0, 17, 0, 0,
-  0, 0, 0, 0, 1, 1, 16, 0, 0, 0,
-  49, 11, 3, 0, 0, 29, 0, 16, 72, 0,
-  37, 30, 0, 0, 0, 15, 79, 12, 0, 0,
-  0, 13, 41, 0, 0, 0, 0, 11, 0, 105,
-  32, 28, 0, 0, 0, 8, 36, 0, 22, 20,
-  3, 0, 0, 0, 87, 22, 0, 54, 0, 0,
-  130, 30, 67, 49, 31, 0, 0, 36, 0, 0,
-  48, 46, 0, 0, 36, 0, 58, 28, 0, 42,
-  0, 0, 0, 0, 0, 73, 0, 0, 0, 0,
-  0, 0, 0, 113, 49, 57, 10, 33, 35, 37,
-  0, 0, 24, 0, 0, 52, 0, 0, 0, 0,
-  4, 0, 10, 0, 8, 0, 23, 0, 0, 0,
-  31, 19, 0, 1, 0, 0, 0, 57, 0, 18,
-  70, 15, 0, 4, 0, 0, 0, 50, 13, 20,
-  0, 0, 47, 47, 29, 12, 0, 0, 0, 10,
-  0, 0, 0, 0, 50, 0, 0, 44, 0, 64,
-  0, 0, 54, 0, 0, 47, 0, 99, 16, 46,
-  0, 15, 0, 37, 0, 0, 63, 0, 74, 0,
-  64, 0, 0, 62, 0, 0, 90, 0, 0, 12,
-  30, 23, 61, 0, 70, 60, 0, 76, 0, 1,
-  0, 0, 21, 0, 0, 0, 0, 0, 8, 0,
-  5, 0, 0, 121, 9, 0, 0, 0, 0, 0,
-  20, 54, 116, 17, 0, 0, 0, 0, 11, 9,
-  0, 21, 0, 19, 0, 73, 0, 0, 0, 0,
-  56, 0, 53, 0, 0, 0, 21, 0, 18, 0,
-  0, 48, 16, 0, 0, 0, 50, 44, 75, 3,
-  3, 42, 110, 0, 16, 61, 79, 13, 2, 0,
-  31, 54, 4, 6, 49, 0, 0, 45, 0, 0,
-  0, 0, 83, 0, 2, 0, 0, 62, 0, 80,
-  0, 35, 4, 49, 18, 97, 6, 35, 0, 42,
-  0, 40, 48, 0, 23, 0, 3, 0, 0, 0,
-  0, 5, 0, 59, 0, 17, 20, 0, 40, 0,
-  0, 0, 0, 48, 8, 0, 29, 54, 0, 0,
-  33, 0, 42, 5, 0, 9, 4, 0, 0, 8,
-  0, 4, 0, 44, 0, 13, 5, 8, 15, 84,
-  41, 0, 0, 0, 34, 0, 24, 13, 4, 22,
-  0, 21, 0, 22, 0, 0, 0, 0, 35, 0,
-  31, 0, 111, 0, 71, 0, 32, 0, 3, 37,
-  0, 0, 14, 0, 32, 0, 0, 0, 3, 23,
-  56, 0, 0, 4, 62, 15, 4, 0, 0, 72,
-  0, 17, 107, 0, 0, 48, 0, 0, 0, 48,
-  90, 0, 0, 0, 0, 51, 43, 7, 0, 46,
-  21, 29, 25, 100, 41, 0, 0, 5, 0, 0,
-  5, 0, 27, 0, 7, 0, 20, 2, 58, 63,
-  0, 50, 0, 0, 97, 52, 73, 0, 0, 0,
-  9, 20, 30, 0, 53, 59, 0, 0, 0, 0,
-  39, 57, 10, 31, 0, 0, 0, 14, 0, 0,
-  0, 54, 0, 21, 0, 18, 0, 113, 24, 11,
-  22, 20, 39, 43, 10, 0, 43, 0, 0, 50,
-  0, 0, 0, 0, 10, 1, 48, 0, 7, 0,
-  27, 0, 30, 0, 30, 47, 0, 6, 0, 0,
-  0, 1, 30, 12, 26, 0, 0, 25, 43, 0,
-  8, 23, 56, 23, 0, 0, 32, 29, 18, 2,
-  25, 0, 0, 0, 0, 0, 0, 0, 36, 17,
-  0, 0, 0, 0, 0, 34, 0, 11, 0, 58,
-  21, 87, 29, 59, 0, 1, 0, 52, 63, 0,
-  3, 0, 12, 0, 0, 0, 25, 4, 0, 38,
-  0, 10, 4, 0, 42, 0, 34, 0, 0, 17,
-  34, 0, 45, 41, 0, 0, 77, 0, 55, 0,
-  5, 0, 14, 0, 0, 0, 0, 31, 0, 0,
-  0, 22, 0, 0, 32, 57, 30, 0, 0, 9,
-  8, 0, 15, 0, 0, 13, 0, 14, 0, 2,
-  0, 0, 29, 0, 33, 0, 14, 0, 33, 0,
-  13, 6, 20, 0, 0, 5, 0, 30, 11, 9,
-  0, 0, 16, 0, 14, 0, 28, 0, 0, 43,
-  62, 17, 0, 4, 0, 0, 0, 14, 39, 0,
-  19, 14, 0, 0, 0, 0, 39, 51, 0, 0,
-  0, 0, 8, 0, 0, 0, 0, 26, 0, 76,
-  41, 64, 0, 17, 0, 73, 78, 15, 1, 58,
-  0, 0, 0, 0, 35, 0, 0, 26, 0, 0,
-  54, 0, 52, 39, 59, 0, 0, 16, 4, 0,
-  13, 36, 0, 0, 89, 0, 49, 0, 0, 20,
-  1, 30, 0, 0, 0, 79, 0, 0, 39, 0,
-  21, 0, 17, 79, 53, 5, 0, 14, 0, 0,
-  0, 9, 0, 17, 0, 33, 0, 25, 0, 0,
-  3, 0, 0, 0, 0, 0, 77, 0, 14, 5,
-  4, 0, 0, 37, 0, 30, 19, 0, 8, 0,
-  29, 1, 5, 0, 23, 0, 24, 68, 78, 31,
-  0, 2, 0, 0, 0, 40, 45, 0, 20, 28,
-  0, 0, 7, 0, 46, 69, 0, 0, 0, 8,
-  7, 0, 0, 0, 0, 16, 0, 35, 63, 39,
-  0, 11, 0, 42, 72, 27, 0, 30, 0, 4,
-  0, 3, 38, 0, 0, 31, 0, 0, 79, 0,
-  75, 41, 0, 0, 0, 12, 16, 0, 14, 1,
-  0, 0, 85, 0, 26, 0, 0, 32, 0, 18,
-  6, 0, 14, 72, 0, 6, 28, 0, 15, 0,
-  0, 80, 18, 0, 0, 7, 0, 0, 0, 0,
-  2, 22, 0, 30, 8, 22, 3, 0, 0, 0,
-  0, 0, 0, 0, 101, 0, 9, 26, 7, 0,
-  0, 27, 0, 6, 0, 0, 33, 17, 40, 0,
-  12, 29, 62, 0, 14, 33, 65, 28, 0, 0,
-  26, 32, 26, 12, 42, 0, 0, 27, 0, 0,
-  0, 0, 69, 0, 0, 0, 0, 14, 0, 40,
-  0, 14, 0, 40, 23, 88, 0, 29, 0, 18,
-  0, 24, 66, 1, 4, 0, 0, 0, 0, 0,
-  30, 14, 0, 50, 0, 7, 42, 0, 37, 0,
-  0, 0, 0, 48, 16, 0, 58, 78, 0, 0,
-  60, 0, 43, 4, 0, 14, 12, 0, 0, 2,
-  0, 24, 0, 6, 0, 25, 4, 0, 5, 84,
-  38, 0, 0, 3, 48, 0, 12, 5, 0, 1,
-  0, 12, 0, 2, 0, 0, 15, 0, 12, 0,
-  16, 0, 60, 0, 26, 0, 25, 0, 32, 14,
-  0, 17, 0, 0, 0, 0, 0, 0, 1, 1,
-  16, 0, 0, 0, 49, 11, 3, 0, 0, 29,
-  0, 16, 72, 0, 37, 30, 0, 0, 0, 15,
-  79, 12, 0, 0, 0, 13, 41, 0, 0, 0,
-  0, 11, 0, 105, 32, 28, 0, 0, 0, 8,
-  36, 0, 22, 20, 3, 0, 0, 0, 87, 22,
-  0, 54, 0, 0, 130, 30, 67, 49, 31, 0,
-  0, 36, 0, 0, 48, 46, 0, 0, 36, 0,
-  58, 28, 0, 42, 0, 0, 0, 0, 0, 73,
-  0, 0, 0, 0, 0, 0, 0, 113, 49, 57,
-  10, 33, 35, 37, 0, 0, 24, 0, 0, 52,
-  0, 0, 0, 0, 4, 0, 10, 0, 8, 0,
-  23, 0, 0, 0, 31, 19, 12, 13, 0, 21,
-  6, 5, 0, 0, 11, 0, 0, 0, 48, 0,
-  0, 18, 58, 12, 0, 0, 0, 8, 0, 28,
-  33, 0, 31, 20, 0, 0, 0, 2, 67, 50,
-  0, 0, 0, 26, 49, 0, 0, 0, 0, 31,
-  0, 97, 52, 74, 0, 0, 0, 36, 26, 0,
-  0, 44, 0, 0, 0, 0, 64, 9, 0, 12,
-  0, 0, 87, 26, 88, 48, 67, 0, 0, 16,
-  0, 0, 28, 0, 0, 0, 33, 0, 46, 22,
-  0, 32, 0, 0, 2, 0, 0, 84, 0, 0,
-  12, 0, 0, 0, 1, 115, 49, 54, 0, 40,
-  17, 26, 0, 0, 9, 0, 0, 49, 0, 16,
-  0, 0, 0, 0, 29, 0, 1, 0, 46, 0,
-  0, 0, 33, 16, 0, 48, 16, 0, 0, 0,
-  50, 44, 75, 3, 3, 42, 110, 0, 16, 61,
-  79, 13, 2, 0, 31, 54, 4, 6, 49, 0,
-  0, 45, 0, 0, 0, 0, 83, 0, 2, 0,
-  0, 62, 0, 80, 0, 35, 4, 49, 18, 97,
-  6, 35, 0, 42, 0, 40, 48, 0, 23, 0,
-  3, 0, 0, 0, 0, 5, 0, 59, 0, 17,
-  20, 0, 40, 0, 0, 0, 0, 48, 8, 0,
-  29, 54, 0, 0, 33, 0, 42, 5, 0, 9,
-  4, 0, 0, 8, 0, 4, 0, 44, 0, 13,
-  5, 8, 15, 84, 41, 0, 0, 0, 34, 0,
-  24, 13, 4, 22, 0, 21, 0, 22, 0, 0,
-  0, 0, 35, 0, 31, 0, 111, 0, 71, 0,
-  32, 0, 3, 37, 0, 0, 14, 0, 32, 0,
-  0, 0, 3, 23, 56, 0, 0, 4, 62, 15,
-  4, 0, 0, 72, 0, 17, 107, 0, 0, 48,
-  0, 0, 0, 48, 90, 0, 0, 0, 0, 51,
-  43, 7, 0, 46, 21, 29, 25, 100, 41, 0,
-  0, 5, 0, 0, 5, 0, 27, 0, 7, 0,
-  20, 2, 58, 63, 0, 50, 0, 0, 97, 52,
-  73, 0, 0, 0, 9, 20, 30, 0, 53, 59,
-  0, 0, 0, 0, 39, 57, 10, 31, 0, 0,
-  0, 14, 0, 0, 0, 54, 0, 21, 0, 18,
-  0, 113, 24, 11, 22, 20, 39, 43, 10, 0,
-  43, 0, 0, 50, 0, 0, 0, 0, 10, 1,
-  48, 0, 7, 0, 27, 0, 30, 0, 30, 47,
-  0, 22, 0, 0, 13, 12, 20, 0, 30, 0,
-  12, 20, 47, 4, 0, 16, 61, 0, 3, 0,
-  0, 56, 0, 10, 36, 0, 0, 41, 0, 0,
-  2, 0, 51, 24, 0, 0, 0, 75, 57, 0,
-  0, 1, 0, 46, 0, 115, 40, 68, 0, 0,
-  0, 16, 0, 0, 30, 32, 30, 0, 49, 0,
-  37, 54, 0, 31, 7, 0, 25, 63, 98, 0,
-  89, 0, 26, 32, 28, 22, 29, 0, 0, 0,
-  0, 0, 23, 34, 22, 43, 0, 13, 0, 0,
-  0, 67, 0, 29, 0, 0, 0, 0, 28, 122,
-  64, 34, 0, 28, 14, 55, 5, 5, 0, 0,
-  0, 59, 0, 9, 0, 5, 0, 38, 80, 0,
-  0, 0, 7, 0, 12, 0, 22, 22, 0, 5,
-  0, 30, 11, 9, 0, 0, 16, 0, 14, 0,
-  28, 0, 0, 43, 62, 17, 0, 4, 0, 0,
-  0, 14, 39, 0, 19, 14, 0, 0, 0, 0,
-  39, 51, 0, 0, 0, 0, 8, 0, 0, 0,
-  0, 26, 0, 76, 41, 64, 0, 17, 0, 73,
-  78, 15, 1, 58, 0, 0, 0, 0, 35, 0,
-  0, 26, 0, 0, 54, 0, 52, 39, 59, 0,
-  0, 16, 4, 0, 13, 36, 0, 0, 89, 0,
-  49, 0, 0, 20, 1, 30, 0, 0, 0, 79,
-  0, 0, 39, 0, 21, 0, 17, 79, 53, 5,
-  0, 14, 0, 0, 0, 9, 0, 17, 0, 33,
-  0, 25, 0, 0, 3, 0, 0, 0, 0, 0,
-  77, 0, 14, 5, 4, 0, 0, 37, 0, 30,
-  19, 0, 8, 0, 29, 1, 5, 0, 23, 0,
-  24, 68, 78, 31, 0, 2, 0, 0, 0, 40,
-  45, 0, 20, 28, 0, 0, 7, 0, 46, 69,
-  0, 0, 0, 8, 7, 0, 0, 0, 0, 16,
-  0, 35, 63, 39, 0, 11, 0, 42, 72, 27,
-  0, 30, 0, 4, 0, 3, 38, 0, 0, 31,
-  0, 0, 79, 0, 75, 41, 0, 0, 0, 12,
-  16, 0, 14, 1, 0, 0, 85, 0, 26, 0,
-  0, 32, 0, 18, 6, 0, 14, 72, 0, 6,
-  28, 0, 15, 0, 0, 80, 18, 0, 0, 7,
-  0, 0, 0, 0, 2, 22, 0, 30, 8, 22,
-  3, 0, 0, 0, 0, 0, 0, 0, 101, 0,
-  9, 26, 7, 0, 0, 119, 31, 10, 0, 0,
-  55, 0, 33, 18, 0, 0, 0, 0, 46, 39,
-  65, 38, 5, 18, 0, 0, 0, 46, 49, 6,
-  24, 40, 0, 0, 0, 0, 84, 26, 0, 0,
-  0, 16, 0, 3, 0, 0, 24, 17, 0, 45,
-  64, 6, 0, 10, 0, 0, 73, 0, 0, 0,
-  32, 0, 0, 35, 7, 5, 0, 0, 0, 0,
-  63, 0, 26, 11, 0, 0, 0, 15, 64, 26,
-  8, 27, 5, 0, 67, 3, 18, 28, 0, 6,
-  0, 0, 1, 26, 36, 0, 0, 22, 0, 0,
-  0, 0, 0, 60, 6, 0, 0, 0, 2, 0,
-  43, 0, 35, 36, 0, 21, 0, 19, 0, 0,
-  0, 0, 13, 0, 0, 0, 95, 0, 24, 41,
-  20, 0, 32, 14, 0, 17, 0, 0, 0, 0,
-  0, 0, 1, 1, 16, 0, 0, 0, 49, 11,
-  3, 0, 0, 29, 0, 16, 72, 0, 37, 30,
-  0, 0, 0, 15, 79, 12, 0, 0, 0, 13,
-  41, 0, 0, 0, 0, 11, 0, 105, 32, 28,
-  0, 0, 0, 8, 36, 0, 22, 20, 3, 0,
-  0, 0, 87, 22, 0, 54, 0, 0, 130, 30,
-  67, 49, 31, 0, 0, 36, 0, 0, 48, 46,
-  0, 0, 36, 0, 58, 28, 0, 42, 0, 0,
-  0, 0, 0, 73, 0, 0, 0, 0, 0, 0,
-  0, 113, 49, 57, 10, 33, 35, 37, 0, 0,
-  24, 0, 0, 52, 0, 0, 0, 0, 4, 0,
-  10, 0, 8, 0, 23, 0, 0, 0, 31, 19,
-  12, 13, 0, 21, 6, 5, 0, 0, 11, 0,
-  0, 0, 48, 0, 0, 18, 58, 12, 0, 0,
-  0, 8, 0, 28, 33, 0, 31, 20, 0, 0,
-  0, 2, 67, 50, 0, 0, 0, 26, 49, 0,
-  0, 0, 0, 31, 0, 97, 52, 74, 0, 0,
-  0, 36, 26, 0, 0, 44, 0, 0, 0, 0,
-  64, 9, 0, 12, 0, 0, 87, 26, 88, 48,
-  67, 0, 0, 16, 0, 0, 28, 0, 0, 0,
-  33, 0, 46, 22, 0, 32, 0, 0, 2, 0,
-  0, 84, 0, 0, 12, 0, 0, 0, 1, 115,
-  49, 54, 0, 40, 17, 26, 0, 0, 9, 0,
-  0, 49, 0, 16, 0, 0, 0, 0, 29, 0,
-  1, 0, 46, 0, 0, 0, 33, 16, 0, 98,
-  0, 20, 14, 0, 60, 12, 44, 16, 32, 0,
-  54, 0, 44, 107, 104, 30, 6, 0, 0, 0,
-  0, 40, 41, 45, 0, 53, 0, 0, 0, 0,
-  87, 64, 0, 0, 0, 27, 0, 41, 0, 0,
-  16, 28, 30, 44, 24, 53, 0, 28, 0, 0,
-  87, 10, 0, 0, 0, 14, 0, 58, 10, 0,
-  0, 24, 0, 0, 75, 0, 41, 0, 0, 0,
-  0, 48, 17, 40, 0, 0, 0, 12, 73, 0,
-  9, 26, 0, 32, 2, 2, 0, 43, 49, 36,
-  0, 65, 0, 26, 0, 0, 0, 86, 27, 0,
-  0, 0, 9, 0, 28, 10, 24, 30, 0, 17,
-  0, 27, 0, 0, 0, 0, 2, 0, 8, 0,
-  164, 0, 52, 9, 40, 0, 3, 37, 0, 0,
-  14, 0, 32, 0, 0, 0, 3, 23, 56, 0,
-  0, 4, 62, 15, 4, 0, 0, 72, 0, 17,
-  107, 0, 0, 48, 0, 0, 0, 48, 90, 0,
-  0, 0, 0, 51, 43, 7, 0, 46, 21, 29,
-  25, 100, 41, 0, 0, 5, 0, 0, 5, 0,
-  27, 0, 7, 0, 20, 2, 58, 63, 0, 50,
-  0, 0, 97, 52, 73, 0, 0, 0, 9, 20,
-  30, 0, 53, 59, 0, 0, 0, 0, 39, 57,
-  10, 31, 0, 0, 0, 14, 0, 0, 0, 54,
-  0, 21, 0, 18, 0, 113, 24, 11, 22, 20,
-  39, 43, 10, 0, 43, 0, 0, 50, 0, 0,
-  0, 0, 10, 1, 48, 0, 7, 0, 27, 0,
-  30, 0, 30, 47, 0, 22, 0, 0, 13, 12,
-  20, 0, 30, 0, 12, 20, 47, 4, 0, 16,
-  61, 0, 3, 0, 0, 56, 0, 10, 36, 0,
-  0, 41, 0, 0, 2, 0, 51, 24, 0, 0,
-  0, 75, 57, 0, 0, 1, 0, 46, 0, 115,
-  40, 68, 0, 0, 0, 16, 0, 0, 30, 32,
-  30, 0, 49, 0, 37, 54, 0, 31, 7, 0,
-  25, 63, 98, 0, 89, 0, 26, 32, 28, 22,
-  29, 0, 0, 0, 0, 0, 23, 34, 22, 43,
-  0, 13, 0, 0, 0, 67, 0, 29, 0, 0,
-  0, 0, 28, 122, 64, 34, 0, 28, 14, 55,
-  5, 5, 0, 0, 0, 59, 0, 9, 0, 5,
-  0, 38, 80, 0, 0, 0, 7, 0, 12, 0,
-  22, 22, 0, 49, 0, 0, 0, 0, 12, 0,
-  80, 43, 25, 0, 73, 2, 0, 149, 100, 43,
-  17, 0, 0, 0, 0, 25, 0, 0, 21, 90,
-  9, 0, 9, 0, 115, 13, 0, 0, 4, 73,
-  0, 0, 23, 0, 0, 26, 0, 80, 0, 54,
-  0, 37, 0, 15, 61, 0, 0, 23, 13, 7,
-  0, 32, 0, 0, 0, 0, 0, 0, 27, 12,
-  61, 0, 7, 0, 0, 98, 0, 66, 0, 13,
-  0, 0, 19, 3, 24, 48, 0, 47, 3, 23,
-  13, 19, 53, 124, 0, 32, 23, 0, 0, 0,
-  0, 90, 142, 0, 0, 0, 8, 0, 0, 33,
-  0, 34, 0, 47, 0, 22, 0, 0, 0, 0,
-  6, 0, 0, 0, 122, 0, 29, 0, 52, 16,
-  0, 37, 0, 30, 19, 0, 8, 0, 29, 1,
-  5, 0, 23, 0, 24, 68, 78, 31, 0, 2,
-  0, 0, 0, 40, 45, 0, 20, 28, 0, 0,
-  7, 0, 46, 69, 0, 0, 0, 8, 7, 0,
-  0, 0, 0, 16, 0, 35, 63, 39, 0, 11,
-  0, 42, 72, 27, 0, 30, 0, 4, 0, 3,
-  38, 0, 0, 31, 0, 0, 79, 0, 75, 41,
-  0, 0, 0, 12, 16, 0, 14, 1, 0, 0,
-  85, 0, 26, 0, 0, 32, 0, 18, 6, 0,
-  14, 72, 0, 6, 28, 0, 15, 0, 0, 80,
-  18, 0, 0, 7, 0, 0, 0, 0, 2, 22,
-  0, 30, 8, 22, 3, 0, 0, 0, 0, 0,
-  0, 0, 101, 0, 9, 26, 7, 0, 0, 119,
-  31, 10, 0, 0, 55, 0, 33, 18, 0, 0,
-  0, 0, 46, 39, 65, 38, 5, 18, 0, 0,
-  0, 46, 49, 6, 24, 40, 0, 0, 0, 0,
-  84, 26, 0, 0, 0, 16, 0, 3, 0, 0,
-  24, 17, 0, 45, 64, 6, 0, 10, 0, 0,
-  73, 0, 0, 0, 32, 0, 0, 35, 7, 5,
-  0, 0, 0, 0, 63, 0, 26, 11, 0, 0,
-  0, 15, 64, 26, 8, 27, 5, 0, 67, 3,
-  18, 28, 0, 6, 0, 0, 1, 26, 36, 0,
-  0, 22, 0, 0, 0, 0, 0, 60, 6, 0,
-  0, 0, 2, 0, 43, 0, 35, 36, 0, 21,
-  0, 19, 0, 0, 0, 0, 13, 0, 0, 0,
-  95, 0, 24, 41, 20, 0, 0, 104, 16, 18,
-  0, 0, 0, 0, 47, 19, 0, 0, 6, 0,
-  7, 17, 36, 23, 0, 2, 0, 0, 72, 39,
-  0, 0, 14, 29, 0, 0, 0, 0, 40, 0,
-  36, 14, 0, 1, 11, 0, 0, 0, 22, 32,
-  0, 52, 25, 0, 0, 0, 0, 42, 40, 0,
-  22, 0, 44, 0, 3, 0, 0, 33, 0, 0,
-  52, 0, 0, 0, 0, 10, 106, 0, 39, 32,
-  46, 45, 0, 59, 28, 0, 21, 0, 1, 31,
-  0, 0, 5, 21, 26, 0, 31, 0, 0, 0,
-  5, 0, 0, 0, 0, 52, 28, 23, 1, 0,
-  7, 59, 48, 1, 0, 29, 0, 28, 0, 8,
-  0, 0, 0, 0, 0, 12, 0, 0, 0, 0,
-  49, 26, 5, 0, 12, 13, 0, 21, 6, 5,
-  0, 0, 11, 0, 0, 0, 48, 0, 0, 18,
-  58, 12, 0, 0, 0, 8, 0, 28, 33, 0,
-  31, 20, 0, 0, 0, 2, 67, 50, 0, 0,
-  0, 26, 49, 0, 0, 0, 0, 31, 0, 97,
-  52, 74, 0, 0, 0, 36, 26, 0, 0, 44,
-  0, 0, 0, 0, 64, 9, 0, 12, 0, 0,
-  87, 26, 88, 48, 67, 0, 0, 16, 0, 0,
-  28, 0, 0, 0, 33, 0, 46, 22, 0, 32,
-  0, 0, 2, 0, 0, 84, 0, 0, 12, 0,
-  0, 0, 1, 115, 49, 54, 0, 40, 17, 26,
-  0, 0, 9, 0, 0, 49, 0, 16, 0, 0,
-  0, 0, 29, 0, 1, 0, 46, 0, 0, 0,
-  33, 16, 0, 98, 0, 20, 14, 0, 60, 12,
-  44, 16, 32, 0, 54, 0, 44, 107, 104, 30,
-  6, 0, 0, 0, 0, 40, 41, 45, 0, 53,
-  0, 0, 0, 0, 87, 64, 0, 0, 0, 27,
-  0, 41, 0, 0, 16, 28, 30, 44, 24, 53,
-  0, 28, 0, 0, 87, 10, 0, 0, 0, 14,
-  0, 58, 10, 0, 0, 24, 0, 0, 75, 0,
-  41, 0, 0, 0, 0, 48, 17, 40, 0, 0,
-  0, 12, 73, 0, 9, 26, 0, 32, 2, 2,
-  0, 43, 49, 36, 0, 65, 0, 26, 0, 0,
-  0, 86, 27, 0, 0, 0, 9, 0, 28, 10,
-  24, 30, 0, 17, 0, 27, 0, 0, 0, 0,
-  2, 0, 8, 0, 164, 0, 52, 9, 40, 0,
-  0, 111, 49, 4, 4, 0, 0, 13, 78, 36,
-  24, 0, 20, 0, 0, 97, 83, 24, 24, 5,
-  0, 0, 48, 50, 0, 0, 1, 78, 1, 0,
-  0, 0, 68, 0, 12, 0, 0, 28, 0, 3,
-  0, 0, 11, 19, 11, 36, 0, 0, 0, 29,
-  0, 18, 44, 0, 0, 0, 1, 0, 0, 8,
-  0, 0, 0, 0, 0, 0, 29, 0, 0, 0,
-  0, 0, 32, 72, 9, 90, 0, 112, 2, 20,
-  35, 0, 0, 53, 0, 31, 6, 61, 21, 24,
-  117, 0, 0, 0, 26, 0, 0, 0, 0, 100,
-  90, 0, 0, 0, 7, 0, 54, 21, 0, 21,
-  0, 0, 0, 15, 0, 0, 0, 0, 0, 21,
-  0, 0, 73, 0, 76, 10, 35, 0, 0, 22,
-  0, 0, 13, 12, 20, 0, 30, 0, 12, 20,
-  47, 4, 0, 16, 61, 0, 3, 0, 0, 56,
-  0, 10, 36, 0, 0, 41, 0, 0, 2, 0,
-  51, 24, 0, 0, 0, 75, 57, 0, 0, 1,
-  0, 46, 0, 115, 40, 68, 0, 0, 0, 16,
-  0, 0, 30, 32, 30, 0, 49, 0, 37, 54,
-  0, 31, 7, 0, 25, 63, 98, 0, 89, 0,
-  26, 32, 28, 22, 29, 0, 0, 0, 0, 0,
-  23, 34, 22, 43, 0, 13, 0, 0, 0, 67,
-  0, 29, 0, 0, 0, 0, 28, 122, 64, 34,
-  0, 28, 14, 55, 5, 5, 0, 0, 0, 59,
-  0, 9, 0, 5, 0, 38, 80, 0, 0, 0,
-  7, 0, 12, 0, 22, 22, 0, 49, 0, 0,
-  0, 0, 12, 0, 80, 43, 25, 0, 73, 2,
-  0, 149, 100, 43, 17, 0, 0, 0, 0, 25,
-  0, 0, 21, 90, 9, 0, 9, 0, 115, 13,
-  0, 0, 4, 73, 0, 0, 23, 0, 0, 26,
-  0, 80, 0, 54, 0, 37, 0, 15, 61, 0,
-  0, 23, 13, 7, 0, 32, 0, 0, 0, 0,
-  0, 0, 27, 12, 61, 0, 7, 0, 0, 98,
-  0, 66, 0, 13, 0, 0, 19, 3, 24, 48,
-  0, 47, 3, 23, 13, 19, 53, 124, 0, 32,
-  23, 0, 0, 0, 0, 90, 142, 0, 0, 0,
-  8, 0, 0, 33, 0, 34, 0, 47, 0, 22,
-  0, 0, 0, 0, 6, 0, 0, 0, 122, 0,
-  29, 0, 52, 16, 0, 27, 108, 0, 0, 0,
-  0, 0, 90, 42, 15, 0, 26, 53, 0, 84,
-  60, 35, 50, 0, 0, 15, 20, 31, 0, 0,
-  3, 111, 0, 0, 0, 0, 61, 0, 0, 0,
-  0, 79, 0, 0, 3, 0, 0, 0, 0, 28,
-  0, 0, 0, 35, 0, 82, 11, 0, 69, 0,
-  27, 18, 0, 0, 0, 0, 0, 0, 27, 0,
-  48, 0, 11, 70, 0, 0, 22, 90, 0, 69,
-  0, 68, 0, 0, 7, 0, 32, 92, 0, 47,
-  0, 58, 48, 0, 85, 34, 0, 0, 11, 0,
-  0, 0, 0, 133, 125, 0, 0, 0, 8, 0,
-  0, 61, 0, 16, 7, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 45, 0, 54, 0,
-  21, 46, 0, 119, 31, 10, 0, 0, 55, 0,
-  33, 18, 0, 0, 0, 0, 46, 39, 65, 38,
-  5, 18, 0, 0, 0, 46, 49, 6, 24, 40,
-  0, 0, 0, 0, 84, 26, 0, 0, 0, 16,
-  0, 3, 0, 0, 24, 17, 0, 45, 64, 6,
-  0, 10, 0, 0, 73, 0, 0, 0, 32, 0,
-  0, 35, 7, 5, 0, 0, 0, 0, 63, 0,
-  26, 11, 0, 0, 0, 15, 64, 26, 8, 27,
-  5, 0, 67, 3, 18, 28, 0, 6, 0, 0,
-  1, 26, 36, 0, 0, 22, 0, 0, 0, 0,
-  0, 60, 6, 0, 0, 0, 2, 0, 43, 0,
-  35, 36, 0, 21, 0, 19, 0, 0, 0, 0,
-  13, 0, 0, 0, 95, 0, 24, 41, 20, 0,
-  0, 104, 16, 18, 0, 0, 0, 0, 47, 19,
-  0, 0, 6, 0, 7, 17, 36, 23, 0, 2,
-  0, 0, 72, 39, 0, 0, 14, 29, 0, 0,
-  0, 0, 40, 0, 36, 14, 0, 1, 11, 0,
-  0, 0, 22, 32, 0, 52, 25, 0, 0, 0,
-  0, 42, 40, 0, 22, 0, 44, 0, 3, 0,
-  0, 33, 0, 0, 52, 0, 0, 0, 0, 10,
-  106, 0, 39, 32, 46, 45, 0, 59, 28, 0,
-  21, 0, 1, 31, 0, 0, 5, 21, 26, 0,
-  31, 0, 0, 0, 5, 0, 0, 0, 0, 52,
-  28, 23, 1, 0, 7, 59, 48, 1, 0, 29,
-  0, 28, 0, 8, 0, 0, 0, 0, 0, 12,
-  0, 0, 0, 0, 49, 26, 5, 0, 107, 66,
-  16, 65, 30, 0, 0, 17, 71, 14, 28, 0,
-  85, 0, 0, 80, 60, 0, 13, 0, 0, 32,
-  32, 6, 0, 0, 0, 61, 0, 37, 19, 69,
-  10, 6, 18, 5, 0, 44, 103, 0, 0, 23,
-  0, 23, 18, 0, 0, 0, 0, 0, 0, 86,
-  0, 0, 83, 13, 32, 36, 9, 0, 0, 0,
-  0, 0, 15, 55, 0, 0, 11, 0, 91, 19,
-  43, 55, 0, 39, 28, 49, 0, 26, 0, 0,
-  19, 64, 28, 26, 14, 0, 86, 0, 32, 0,
-  0, 14, 0, 0, 66, 0, 5, 67, 43, 0,
-  9, 0, 0, 58, 0, 60, 9, 0, 6, 0,
-  0, 0, 0, 0, 0, 0, 0, 15, 0, 4,
-  0, 18, 46, 15, 12, 30, 0, 98, 0, 20,
-  14, 0, 60, 12, 44, 16, 32, 0, 54, 0,
-  44, 107, 104, 30, 6, 0, 0, 0, 0, 40,
-  41, 45, 0, 53, 0, 0, 0, 0, 87, 64,
-  0, 0, 0, 27, 0, 41, 0, 0, 16, 28,
-  30, 44, 24, 53, 0, 28, 0, 0, 87, 10,
-  0, 0, 0, 14, 0, 58, 10, 0, 0, 24,
-  0, 0, 75, 0, 41, 0, 0, 0, 0, 48,
-  17, 40, 0, 0, 0, 12, 73, 0, 9, 26,
-  0, 32, 2, 2, 0, 43, 49, 36, 0, 65,
-  0, 26, 0, 0, 0, 86, 27, 0, 0, 0,
-  9, 0, 28, 10, 24, 30, 0, 17, 0, 27,
-  0, 0, 0, 0, 2, 0, 8, 0, 164, 0,
-  52, 9, 40, 0, 0, 111, 49, 4, 4, 0,
-  0, 13, 78, 36, 24, 0, 20, 0, 0, 97,
-  83, 24, 24, 5, 0, 0, 48, 50, 0, 0,
-  1, 78, 1, 0, 0, 0, 68, 0, 12, 0,
-  0, 28, 0, 3, 0, 0, 11, 19, 11, 36,
-  0, 0, 0, 29, 0, 18, 44, 0, 0, 0,
-  1, 0, 0, 8, 0, 0, 0, 0, 0, 0,
-  29, 0, 0, 0, 0, 0, 32, 72, 9, 90,
-  0, 112, 2, 20, 35, 0, 0, 53, 0, 31,
-  6, 61, 21, 24, 117, 0, 0, 0, 26, 0,
-  0, 0, 0, 100, 90, 0, 0, 0, 7, 0,
-  54, 21, 0, 21, 0, 0, 0, 15, 0, 0,
-  0, 0, 0, 21, 0, 0, 73, 0, 76, 10,
-  35, 0, 59, 1, 72, 42, 0, 0, 0, 22,
-  38, 13, 13, 6, 0, 7, 0, 21, 38, 13,
-  14, 0, 0, 64, 43, 11, 0, 0, 1, 54,
-  0, 38, 0, 39, 17, 0, 12, 19, 36, 29,
-  3, 0, 0, 0, 0, 0, 0, 11, 0, 0,
-  0, 0, 0, 70, 0, 0, 91, 0, 38, 0,
-  8, 0, 0, 4, 0, 0, 64, 10, 0, 0,
-  0, 114, 20, 0, 74, 27, 0, 45, 12, 51,
-  27, 0, 0, 0, 15, 101, 0, 21, 22, 36,
-  22, 0, 57, 0, 0, 0, 62, 0, 29, 0,
-  0, 72, 95, 0, 0, 0, 0, 80, 0, 16,
-  0, 0, 0, 13, 0, 0, 0, 0, 0, 0,
-  0, 33, 0, 3, 0, 0, 0, 0, 4, 22,
-  0, 49, 0, 0, 0, 0, 12, 0, 80, 43,
-  25, 0, 73, 2, 0, 149, 100, 43, 17, 0,
-  0, 0, 0, 25, 0, 0, 21, 90, 9, 0,
-  9, 0, 115, 13, 0, 0, 4, 73, 0, 0,
-  23, 0, 0, 26, 0, 80, 0, 54, 0, 37,
-  0, 15, 61, 0, 0, 23, 13, 7, 0, 32,
-  0, 0, 0, 0, 0, 0, 27, 12, 61, 0,
-  7, 0, 0, 98, 0, 66, 0, 13, 0, 0,
-  19, 3, 24, 48, 0, 47, 3, 23, 13, 19,
-  53, 124, 0, 32, 23, 0, 0, 0, 0, 90,
-  142, 0, 0, 0, 8, 0, 0, 33, 0, 34,
-  0, 47, 0, 22, 0, 0, 0, 0, 6, 0,
-  0, 0, 122, 0, 29, 0, 52, 16, 0, 27,
-  108, 0, 0, 0, 0, 0, 90, 42, 15, 0,
-  26, 53, 0, 84, 60, 35, 50, 0, 0, 15,
-  20, 31, 0, 0, 3, 111, 0, 0, 0, 0,
-  61, 0, 0, 0, 0, 79, 0, 0, 3, 0,
-  0, 0, 0, 28, 0, 0, 0, 35, 0, 82,
-  11, 0, 69, 0, 27, 18, 0, 0, 0, 0,
-  0, 0, 27, 0, 48, 0, 11, 70, 0, 0,
-  22, 90, 0, 69, 0, 68, 0, 0, 7, 0,
-  32, 92, 0, 47, 0, 58, 48, 0, 85, 34,
-  0, 0, 11, 0, 0, 0, 0, 133, 125, 0,
-  0, 0, 8, 0, 0, 61, 0, 16, 7, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  45, 0, 54, 0, 21, 46, 0, 0, 117, 0,
-  0, 75, 0, 0, 21, 0, 0, 1, 34, 80,
-  0, 0, 0, 31, 19, 0, 0, 94, 14, 24,
-  0, 0, 0, 29, 0, 0, 10, 39, 0, 0,
-  0, 0, 0, 56, 0, 0, 0, 0, 0, 7,
-  0, 0, 0, 0, 0, 0, 0, 155, 0, 0,
-  71, 0, 21, 0, 50, 0, 0, 5, 0, 0,
-  108, 0, 0, 0, 0, 98, 0, 0, 39, 7,
-  0, 0, 0, 22, 15, 0, 0, 0, 31, 74,
-  16, 3, 15, 30, 48, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 72, 30, 0, 0, 0,
-  0, 78, 0, 23, 0, 11, 40, 0, 0, 0,
-  17, 16, 68, 25, 10, 51, 0, 3, 0, 0,
-  33, 0, 0, 53, 0, 104, 16, 18, 0, 0,
-  0, 0, 47, 19, 0, 0, 6, 0, 7, 17,
-  36, 23, 0, 2, 0, 0, 72, 39, 0, 0,
-  14, 29, 0, 0, 0, 0, 40, 0, 36, 14,
-  0, 1, 11, 0, 0, 0, 22, 32, 0, 52,
-  25, 0, 0, 0, 0, 42, 40, 0, 22, 0,
-  44, 0, 3, 0, 0, 33, 0, 0, 52, 0,
-  0, 0, 0, 10, 106, 0, 39, 32, 46, 45,
-  0, 59, 28, 0, 21, 0, 1, 31, 0, 0,
-  5, 21, 26, 0, 31, 0, 0, 0, 5, 0,
-  0, 0, 0, 52, 28, 23, 1, 0, 7, 59,
-  48, 1, 0, 29, 0, 28, 0, 8, 0, 0,
-  0, 0, 0, 12, 0, 0, 0, 0, 49, 26,
-  5, 0, 107, 66, 16, 65, 30, 0, 0, 17,
-  71, 14, 28, 0, 85, 0, 0, 80, 60, 0,
-  13, 0, 0, 32, 32, 6, 0, 0, 0, 61,
-  0, 37, 19, 69, 10, 6, 18, 5, 0, 44,
-  103, 0, 0, 23, 0, 23, 18, 0, 0, 0,
-  0, 0, 0, 86, 0, 0, 83, 13, 32, 36,
-  9, 0, 0, 0, 0, 0, 15, 55, 0, 0,
-  11, 0, 91, 19, 43, 55, 0, 39, 28, 49,
-  0, 26, 0, 0, 19, 64, 28, 26, 14, 0,
-  86, 0, 32, 0, 0, 14, 0, 0, 66, 0,
-  5, 67, 43, 0, 9, 0, 0, 58, 0, 60,
-  9, 0, 6, 0, 0, 0, 0, 0, 0, 0,
-  0, 15, 0, 4, 0, 18, 46, 15, 12, 30,
-  14, 0, 60, 29, 0, 164, 0, 0, 18, 0,
-  0, 0, 3, 20, 0, 48, 30, 38, 0, 0,
-  13, 76, 24, 1, 0, 0, 0, 35, 0, 48,
-  0, 88, 0, 0, 0, 20, 63, 58, 24, 0,
-  0, 0, 0, 0, 0, 11, 0, 0, 13, 0,
-  0, 83, 0, 0, 99, 0, 57, 0, 22, 0,
-  0, 57, 14, 0, 110, 0, 0, 29, 2, 76,
-  21, 14, 67, 27, 0, 44, 44, 26, 0, 0,
-  0, 0, 32, 108, 0, 10, 10, 0, 11, 0,
-  10, 13, 0, 0, 58, 0, 30, 0, 0, 71,
-  79, 0, 0, 0, 0, 18, 0, 26, 0, 0,
-  0, 0, 0, 0, 4, 4, 54, 0, 0, 35,
-  0, 18, 0, 0, 0, 17, 0, 23, 0, 111,
-  49, 4, 4, 0, 0, 13, 78, 36, 24, 0,
-  20, 0, 0, 97, 83, 24, 24, 5, 0, 0,
-  48, 50, 0, 0, 1, 78, 1, 0, 0, 0,
-  68, 0, 12, 0, 0, 28, 0, 3, 0, 0,
-  11, 19, 11, 36, 0, 0, 0, 29, 0, 18,
-  44, 0, 0, 0, 1, 0, 0, 8, 0, 0,
-  0, 0, 0, 0, 29, 0, 0, 0, 0, 0,
-  32, 72, 9, 90, 0, 112, 2, 20, 35, 0,
-  0, 53, 0, 31, 6, 61, 21, 24, 117, 0,
-  0, 0, 26, 0, 0, 0, 0, 100, 90, 0,
-  0, 0, 7, 0, 54, 21, 0, 21, 0, 0,
-  0, 15, 0, 0, 0, 0, 0, 21, 0, 0,
-  73, 0, 76, 10, 35, 0, 59, 1, 72, 42,
-  0, 0, 0, 22, 38, 13, 13, 6, 0, 7,
-  0, 21, 38, 13, 14, 0, 0, 64, 43, 11,
-  0, 0, 1, 54, 0, 38, 0, 39, 17, 0,
-  12, 19, 36, 29, 3, 0, 0, 0, 0, 0,
-  0, 11, 0, 0, 0, 0, 0, 70, 0, 0,
-  91, 0, 38, 0, 8, 0, 0, 4, 0, 0,
-  64, 10, 0, 0, 0, 114, 20, 0, 74, 27,
-  0, 45, 12, 51, 27, 0, 0, 0, 15, 101,
-  0, 21, 22, 36, 22, 0, 57, 0, 0, 0,
-  62, 0, 29, 0, 0, 72, 95, 0, 0, 0,
-  0, 80, 0, 16, 0, 0, 0, 13, 0, 0,
-  0, 0, 0, 0, 0, 33, 0, 3, 0, 0,
-  0, 0, 4, 22, 21, 0, 99, 34, 0, 157,
-  0, 0, 0, 0, 0, 17, 14, 49, 0, 0,
-  14, 40, 0, 1, 5, 82, 30, 0, 0, 0,
-  0, 0, 0, 147, 4, 78, 0, 24, 0, 23,
-  87, 19, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 3, 42, 0, 0, 78, 0, 0, 59, 0,
-  56, 0, 27, 0, 0, 28, 13, 0, 118, 0,
-  0, 48, 0, 113, 0, 36, 68, 0, 0, 7,
-  28, 0, 17, 0, 0, 0, 10, 108, 35, 0,
-  27, 10, 7, 0, 0, 0, 13, 0, 52, 0,
-  0, 0, 0, 5, 41, 0, 0, 0, 0, 82,
-  0, 16, 0, 8, 18, 0, 0, 0, 39, 10,
-  84, 0, 0, 54, 5, 43, 0, 6, 0, 3,
-  0, 26, 0, 27, 108, 0, 0, 0, 0, 0,
-  90, 42, 15, 0, 26, 53, 0, 84, 60, 35,
-  50, 0, 0, 15, 20, 31, 0, 0, 3, 111,
-  0, 0, 0, 0, 61, 0, 0, 0, 0, 79,
-  0, 0, 3, 0, 0, 0, 0, 28, 0, 0,
-  0, 35, 0, 82, 11, 0, 69, 0, 27, 18,
-  0, 0, 0, 0, 0, 0, 27, 0, 48, 0,
-  11, 70, 0, 0, 22, 90, 0, 69, 0, 68,
-  0, 0, 7, 0, 32, 92, 0, 47, 0, 58,
-  48, 0, 85, 34, 0, 0, 11, 0, 0, 0,
-  0, 133, 125, 0, 0, 0, 8, 0, 0, 61,
-  0, 16, 7, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 45, 0, 54, 0, 21, 46,
-  0, 0, 117, 0, 0, 75, 0, 0, 21, 0,
-  0, 1, 34, 80, 0, 0, 0, 31, 19, 0,
-  0, 94, 14, 24, 0, 0, 0, 29, 0, 0,
-  10, 39, 0, 0, 0, 0, 0, 56, 0, 0,
-  0, 0, 0, 7, 0, 0, 0, 0, 0, 0,
-  0, 155, 0, 0, 71, 0, 21, 0, 50, 0,
-  0, 5, 0, 0, 108, 0, 0, 0, 0, 98,
-  0, 0, 39, 7, 0, 0, 0, 22, 15, 0,
-  0, 0, 31, 74, 16, 3, 15, 30, 48, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 72,
-  30, 0, 0, 0, 0, 78, 0, 23, 0, 11,
-  40, 0, 0, 0, 17, 16, 68, 25, 10, 51,
-  0, 3, 0, 0, 33, 0, 0, 53, 0, 0,
-  59, 0, 5, 69, 0, 0, 0, 0, 0, 19,
-  45, 76, 0, 0, 0, 17, 2, 8, 10, 22,
-  0, 35, 0, 0, 0, 0, 0, 77, 41, 11,
-  0, 18, 0, 0, 0, 17, 0, 13, 0, 0,
-  0, 39, 0, 0, 0, 0, 0, 0, 0, 110,
-  0, 0, 0, 0, 15, 4, 28, 0, 0, 0,
-  0, 0, 48, 0, 0, 6, 0, 9, 0, 40,
-  17, 0, 0, 0, 0, 0, 53, 0, 0, 17,
-  0, 52, 45, 0, 40, 9, 68, 0, 0, 0,
-  56, 0, 0, 5, 0, 0, 0, 21, 0, 0,
-  0, 0, 1, 53, 0, 16, 7, 45, 50, 0,
-  0, 13, 38, 10, 68, 48, 19, 52, 56, 0,
-  0, 0, 26, 9, 0, 10, 107, 66, 16, 65,
-  30, 0, 0, 17, 71, 14, 28, 0, 85, 0,
-  0, 80, 60, 0, 13, 0, 0, 32, 32, 6,
-  0, 0, 0, 61, 0, 37, 19, 69, 10, 6,
-  18, 5, 0, 44, 103, 0, 0, 23, 0, 23,
-  18, 0, 0, 0, 0, 0, 0, 86, 0, 0,
-  83, 13, 32, 36, 9, 0, 0, 0, 0, 0,
-  15, 55, 0, 0, 11, 0, 91, 19, 43, 55,
-  0, 39, 28, 49, 0, 26, 0, 0, 19, 64,
-  28, 26, 14, 0, 86, 0, 32, 0, 0, 14,
-  0, 0, 66, 0, 5, 67, 43, 0, 9, 0,
-  0, 58, 0, 60, 9, 0, 6, 0, 0, 0,
-  0, 0, 0, 0, 0, 15, 0, 4, 0, 18,
-  46, 15, 12, 30, 14, 0, 60, 29, 0, 164,
-  0, 0, 18, 0, 0, 0, 3, 20, 0, 48,
-  30, 38, 0, 0, 13, 76, 24, 1, 0, 0,
-  0, 35, 0, 48, 0, 88, 0, 0, 0, 20,
-  63, 58, 24, 0, 0, 0, 0, 0, 0, 11,
-  0, 0, 13, 0, 0, 83, 0, 0, 99, 0,
-  57, 0, 22, 0, 0, 57, 14, 0, 110, 0,
-  0, 29, 2, 76, 21, 14, 67, 27, 0, 44,
-  44, 26, 0, 0, 0, 0, 32, 108, 0, 10,
-  10, 0, 11, 0, 10, 13, 0, 0, 58, 0,
-  30, 0, 0, 71, 79, 0, 0, 0, 0, 18,
-  0, 26, 0, 0, 0, 0, 0, 0, 4, 4,
-  54, 0, 0, 35, 0, 18, 0, 0, 0, 17,
-  0, 23, 0, 0, 70, 0, 4, 150, 0, 0,
-  0, 0, 0, 1, 23, 94, 0, 0, 0, 44,
-  0, 0, 21, 54, 0, 39, 0, 0, 0, 0,
-  0, 45, 16, 26, 0, 7, 0, 0, 0, 50,
-  0, 0, 0, 11, 0, 27, 0, 8, 1, 0,
-  0, 0, 12, 123, 0, 0, 39, 0, 39, 0,
-  42, 0, 0, 32, 0, 0, 97, 0, 0, 31,
-  0, 64, 0, 26, 51, 0, 0, 17, 0, 0,
-  0, 0, 0, 0, 27, 70, 21, 0, 16, 15,
-  54, 0, 0, 0, 24, 0, 2, 0, 0, 0,
-  0, 60, 12, 0, 0, 0, 0, 79, 0, 14,
-  0, 5, 25, 0, 0, 14, 51, 41, 105, 41,
-  29, 52, 23, 0, 0, 0, 17, 23, 0, 13,
-  59, 1, 72, 42, 0, 0, 0, 22, 38, 13,
-  13, 6, 0, 7, 0, 21, 38, 13, 14, 0,
-  0, 64, 43, 11, 0, 0, 1, 54, 0, 38,
-  0, 39, 17, 0, 12, 19, 36, 29, 3, 0,
-  0, 0, 0, 0, 0, 11, 0, 0, 0, 0,
-  0, 70, 0, 0, 91, 0, 38, 0, 8, 0,
-  0, 4, 0, 0, 64, 10, 0, 0, 0, 114,
-  20, 0, 74, 27, 0, 45, 12, 51, 27, 0,
-  0, 0, 15, 101, 0, 21, 22, 36, 22, 0,
-  57, 0, 0, 0, 62, 0, 29, 0, 0, 72,
-  95, 0, 0, 0, 0, 80, 0, 16, 0, 0,
-  0, 13, 0, 0, 0, 0, 0, 0, 0, 33,
-  0, 3, 0, 0, 0, 0, 4, 22, 21, 0,
-  99, 34, 0, 157, 0, 0, 0, 0, 0, 17,
-  14, 49, 0, 0, 14, 40, 0, 1, 5, 82,
-  30, 0, 0, 0, 0, 0, 0, 147, 4, 78,
-  0, 24, 0, 23, 87, 19, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 3, 42, 0, 0, 78,
-  0, 0, 59, 0, 56, 0, 27, 0, 0, 28,
-  13, 0, 118, 0, 0, 48, 0, 113, 0, 36,
-  68, 0, 0, 7, 28, 0, 17, 0, 0, 0,
-  10, 108, 35, 0, 27, 10, 7, 0, 0, 0,
-  13, 0, 52, 0, 0, 0, 0, 5, 41, 0,
-  0, 0, 0, 82, 0, 16, 0, 8, 18, 0,
-  0, 0, 39, 10, 84, 0, 0, 54, 5, 43,
-  0, 6, 0, 3, 0, 26, 0, 9, 38, 0,
-  15, 120, 0, 0, 0, 0, 0, 3, 58, 72,
-  0, 0, 0, 18, 0, 18, 44, 0, 0, 51,
-  0, 3, 0, 0, 0, 91, 41, 0, 0, 22,
-  0, 0, 0, 22, 0, 25, 0, 45, 0, 53,
-  1, 0, 0, 32, 0, 0, 0, 70, 11, 0,
-  0, 0, 19, 0, 13, 14, 0, 9, 0, 0,
-  0, 0, 0, 11, 0, 0, 0, 58, 10, 0,
-  0, 20, 0, 0, 2, 19, 0, 27, 10, 28,
-  51, 0, 32, 5, 54, 4, 0, 0, 52, 5,
-  0, 37, 0, 0, 0, 30, 0, 0, 0, 0,
-  3, 4, 0, 16, 10, 25, 57, 0, 0, 17,
-  37, 0, 63, 43, 24, 47, 55, 1, 2, 0,
-  25, 2, 0, 0, 0, 0, 117, 0, 0, 75,
-  0, 0, 21, 0, 0, 1, 34, 80, 0, 0,
-  0, 31, 19, 0, 0, 94, 14, 24, 0, 0,
-  0, 29, 0, 0, 10, 39, 0, 0, 0, 0,
-  0, 56, 0, 0, 0, 0, 0, 7, 0, 0,
-  0, 0, 0, 0, 0, 155, 0, 0, 71, 0,
-  21, 0, 50, 0, 0, 5, 0, 0, 108, 0,
-  0, 0, 0, 98, 0, 0, 39, 7, 0, 0,
-  0, 22, 15, 0, 0, 0, 31, 74, 16, 3,
-  15, 30, 48, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 72, 30, 0, 0, 0, 0, 78,
-  0, 23, 0, 11, 40, 0, 0, 0, 17, 16,
-  68, 25, 10, 51, 0, 3, 0, 0, 33, 0,
-  0, 53, 0, 0, 59, 0, 5, 69, 0, 0,
-  0, 0, 0, 19, 45, 76, 0, 0, 0, 17,
-  2, 8, 10, 22, 0, 35, 0, 0, 0, 0,
-  0, 77, 41, 11, 0, 18, 0, 0, 0, 17,
-  0, 13, 0, 0, 0, 39, 0, 0, 0, 0,
-  0, 0, 0, 110, 0, 0, 0, 0, 15, 4,
-  28, 0, 0, 0, 0, 0, 48, 0, 0, 6,
-  0, 9, 0, 40, 17, 0, 0, 0, 0, 0,
-  53, 0, 0, 17, 0, 52, 45, 0, 40, 9,
-  68, 0, 0, 0, 56, 0, 0, 5, 0, 0,
-  0, 21, 0, 0, 0, 0, 1, 53, 0, 16,
-  7, 45, 50, 0, 0, 13, 38, 10, 68, 48,
-  19, 52, 56, 0, 0, 0, 26, 9, 0, 10,
-  0, 52, 52, 0, 44, 0, 21, 0, 7, 0,
-  0, 3, 68, 73, 3, 33, 10, 1, 18, 0,
-  44, 0, 0, 50, 14, 42, 0, 0, 0, 12,
-  60, 0, 0, 39, 0, 0, 0, 7, 0, 62,
-  39, 63, 0, 87, 51, 0, 0, 0, 0, 0,
-  0, 78, 42, 0, 0, 0, 18, 20, 19, 14,
-  11, 0, 3, 81, 0, 28, 0, 0, 0, 0,
-  0, 30, 0, 13, 8, 1, 0, 0, 0, 18,
-  37, 38, 21, 0, 88, 0, 16, 0, 65, 54,
-  0, 0, 46, 25, 0, 61, 0, 19, 5, 30,
-  0, 0, 0, 0, 0, 0, 0, 15, 38, 43,
-  88, 0, 0, 20, 22, 0, 0, 24, 58, 18,
-  39, 4, 45, 0, 79, 0, 1, 0, 14, 0,
-  60, 29, 0, 164, 0, 0, 18, 0, 0, 0,
-  3, 20, 0, 48, 30, 38, 0, 0, 13, 76,
-  24, 1, 0, 0, 0, 35, 0, 48, 0, 88,
-  0, 0, 0, 20, 63, 58, 24, 0, 0, 0,
-  0, 0, 0, 11, 0, 0, 13, 0, 0, 83,
-  0, 0, 99, 0, 57, 0, 22, 0, 0, 57,
-  14, 0, 110, 0, 0, 29, 2, 76, 21, 14,
-  67, 27, 0, 44, 44, 26, 0, 0, 0, 0,
-  32, 108, 0, 10, 10, 0, 11, 0, 10, 13,
-  0, 0, 58, 0, 30, 0, 0, 71, 79, 0,
-  0, 0, 0, 18, 0, 26, 0, 0, 0, 0,
-  0, 0, 4, 4, 54, 0, 0, 35, 0, 18,
-  0, 0, 0, 17, 0, 23, 0, 0, 70, 0,
-  4, 150, 0, 0, 0, 0, 0, 1, 23, 94,
-  0, 0, 0, 44, 0, 0, 21, 54, 0, 39,
-  0, 0, 0, 0, 0, 45, 16, 26, 0, 7,
-  0, 0, 0, 50, 0, 0, 0, 11, 0, 27,
-  0, 8, 1, 0, 0, 0, 12, 123, 0, 0,
-  39, 0, 39, 0, 42, 0, 0, 32, 0, 0,
-  97, 0, 0, 31, 0, 64, 0, 26, 51, 0,
-  0, 17, 0, 0, 0, 0, 0, 0, 27, 70,
-  21, 0, 16, 15, 54, 0, 0, 0, 24, 0,
-  2, 0, 0, 0, 0, 60, 12, 0, 0, 0,
-  0, 79, 0, 14, 0, 5, 25, 0, 0, 14,
-  51, 41, 105, 41, 29, 52, 23, 0, 0, 0,
-  17, 23, 0, 13, 0, 43, 48, 0, 24, 32,
-  13, 0, 8, 0, 0, 0, 63, 49, 0, 0,
-  3, 17, 8, 10, 0, 0, 0, 37, 41, 35,
-  6, 0, 0, 48, 48, 0, 0, 14, 0, 0,
-  0, 2, 0, 39, 0, 40, 0, 41, 21, 0,
-  3, 0, 0, 0, 0, 40, 61, 0, 0, 0,
-  14, 6, 2, 35, 0, 6, 0, 21, 0, 0,
-  0, 27, 0, 0, 0, 32, 20, 0, 21, 28,
-  0, 0, 0, 25, 16, 25, 21, 40, 63, 0,
-  39, 18, 50, 13, 0, 0, 32, 28, 0, 22,
-  0, 38, 15, 31, 0, 0, 0, 0, 0, 28,
-  14, 0, 53, 57, 40, 0, 0, 20, 46, 0,
-  33, 38, 62, 29, 61, 16, 47, 0, 46, 37,
-  0, 1, 21, 0, 99, 34, 0, 157, 0, 0,
-  0, 0, 0, 17, 14, 49, 0, 0, 14, 40,
-  0, 1, 5, 82, 30, 0, 0, 0, 0, 0,
-  0, 147, 4, 78, 0, 24, 0, 23, 87, 19,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
-  42, 0, 0, 78, 0, 0, 59, 0, 56, 0,
-  27, 0, 0, 28, 13, 0, 118, 0, 0, 48,
-  0, 113, 0, 36, 68, 0, 0, 7, 28, 0,
-  17, 0, 0, 0, 10, 108, 35, 0, 27, 10,
-  7, 0, 0, 0, 13, 0, 52, 0, 0, 0,
-  0, 5, 41, 0, 0, 0, 0, 82, 0, 16,
-  0, 8, 18, 0, 0, 0, 39, 10, 84, 0,
-  0, 54, 5, 43, 0, 6, 0, 3, 0, 26,
-  0, 9, 38, 0, 15, 120, 0, 0, 0, 0,
-  0, 3, 58, 72, 0, 0, 0, 18, 0, 18,
-  44, 0, 0, 51, 0, 3, 0, 0, 0, 91,
-  41, 0, 0, 22, 0, 0, 0, 22, 0, 25,
-  0, 45, 0, 53, 1, 0, 0, 32, 0, 0,
-  0, 70, 11, 0, 0, 0, 19, 0, 13, 14,
-  0, 9, 0, 0, 0, 0, 0, 11, 0, 0,
-  0, 58, 10, 0, 0, 20, 0, 0, 2, 19,
-  0, 27, 10, 28, 51, 0, 32, 5, 54, 4,
-  0, 0, 52, 5, 0, 37, 0, 0, 0, 30,
-  0, 0, 0, 0, 3, 4, 0, 16, 10, 25,
-  57, 0, 0, 17, 37, 0, 63, 43, 24, 47,
-  55, 1, 2, 0, 25, 2, 0, 0, 0, 70,
-  65, 0, 63, 0, 15, 0, 1, 0, 14, 0,
-  64, 75, 0, 51, 17, 7, 26, 16, 9, 0,
-  0, 47, 38, 59, 0, 0, 0, 0, 53, 0,
-  0, 37, 12, 0, 0, 0, 0, 53, 50, 43,
-  24, 71, 73, 0, 0, 0, 0, 0, 0, 26,
-  50, 0, 0, 0, 0, 20, 1, 27, 24, 0,
-  0, 63, 0, 2, 29, 0, 0, 0, 0, 0,
-  7, 41, 16, 12, 0, 17, 0, 23, 46, 34,
-  33, 22, 87, 14, 32, 4, 49, 40, 0, 20,
-  24, 31, 0, 54, 0, 35, 3, 41, 0, 0,
-  0, 0, 0, 0, 7, 10, 34, 32, 82, 0,
-  0, 13, 31, 0, 0, 29, 54, 8, 7, 0,
-  55, 0, 75, 11, 2, 0, 0, 0, 59, 0,
-  5, 69, 0, 0, 0, 0, 0, 19, 45, 76,
-  0, 0, 0, 17, 2, 8, 10, 22, 0, 35,
-  0, 0, 0, 0, 0, 77, 41, 11, 0, 18,
-  0, 0, 0, 17, 0, 13, 0, 0, 0, 39,
-  0, 0, 0, 0, 0, 0, 0, 110, 0, 0,
-  0, 0, 15, 4, 28, 0, 0, 0, 0, 0,
-  48, 0, 0, 6, 0, 9, 0, 40, 17, 0,
-  0, 0, 0, 0, 53, 0, 0, 17, 0, 52,
-  45, 0, 40, 9, 68, 0, 0, 0, 56, 0,
-  0, 5, 0, 0, 0, 21, 0, 0, 0, 0,
-  1, 53, 0, 16, 7, 45, 50, 0, 0, 13,
-  38, 10, 68, 48, 19, 52, 56, 0, 0, 0,
-  26, 9, 0, 10, 0, 52, 52, 0, 44, 0,
-  21, 0, 7, 0, 0, 3, 68, 73, 3, 33,
-  10, 1, 18, 0, 44, 0, 0, 50, 14, 42,
-  0, 0, 0, 12, 60, 0, 0, 39, 0, 0,
-  0, 7, 0, 62, 39, 63, 0, 87, 51, 0,
-  0, 0, 0, 0, 0, 78, 42, 0, 0, 0,
-  18, 20, 19, 14, 11, 0, 3, 81, 0, 28,
-  0, 0, 0, 0, 0, 30, 0, 13, 8, 1,
-  0, 0, 0, 18, 37, 38, 21, 0, 88, 0,
-  16, 0, 65, 54, 0, 0, 46, 25, 0, 61,
-  0, 19, 5, 30, 0, 0, 0, 0, 0, 0,
-  0, 15, 38, 43, 88, 0, 0, 20, 22, 0,
-  0, 24, 58, 18, 39, 4, 45, 0, 79, 0,
-  1, 0, 0, 16, 100, 0, 22, 0, 0, 0,
-  0, 0, 0, 11, 22, 94, 0, 49, 0, 51,
-  31, 35, 50, 27, 110, 9, 0, 0, 0, 0,
-  0, 0, 32, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 94, 0, 0, 96, 51, 18, 0, 0,
-  0, 0, 0, 79, 0, 0, 15, 0, 24, 0,
-  24, 0, 7, 8, 19, 6, 56, 0, 0, 10,
-  0, 51, 0, 0, 21, 34, 0, 0, 0, 16,
-  0, 0, 24, 0, 36, 0, 41, 12, 2, 0,
-  43, 21, 0, 36, 0, 0, 5, 39, 0, 0,
-  0, 27, 23, 0, 0, 0, 0, 0, 0, 11,
-  0, 6, 79, 9, 0, 5, 40, 0, 52, 15,
-  28, 31, 21, 0, 0, 0, 55, 12, 0, 0,
-  0, 0, 70, 0, 4, 150, 0, 0, 0, 0,
-  0, 1, 23, 94, 0, 0, 0, 44, 0, 0,
-  21, 54, 0, 39, 0, 0, 0, 0, 0, 45,
-  16, 26, 0, 7, 0, 0, 0, 50, 0, 0,
-  0, 11, 0, 27, 0, 8, 1, 0, 0, 0,
-  12, 123, 0, 0, 39, 0, 39, 0, 42, 0,
-  0, 32, 0, 0, 97, 0, 0, 31, 0, 64,
-  0, 26, 51, 0, 0, 17, 0, 0, 0, 0,
-  0, 0, 27, 70, 21, 0, 16, 15, 54, 0,
-  0, 0, 24, 0, 2, 0, 0, 0, 0, 60,
-  12, 0, 0, 0, 0, 79, 0, 14, 0, 5,
-  25, 0, 0, 14, 51, 41, 105, 41, 29, 52,
-  23, 0, 0, 0, 17, 23, 0, 13, 0, 43,
-  48, 0, 24, 32, 13, 0, 8, 0, 0, 0,
-  63, 49, 0, 0, 3, 17, 8, 10, 0, 0,
-  0, 37, 41, 35, 6, 0, 0, 48, 48, 0,
-  0, 14, 0, 0, 0, 2, 0, 39, 0, 40,
-  0, 41, 21, 0, 3, 0, 0, 0, 0, 40,
-  61, 0, 0, 0, 14, 6, 2, 35, 0, 6,
-  0, 21, 0, 0, 0, 27, 0, 0, 0, 32,
-  20, 0, 21, 28, 0, 0, 0, 25, 16, 25,
-  21, 40, 63, 0, 39, 18, 50, 13, 0, 0,
-  32, 28, 0, 22, 0, 38, 15, 31, 0, 0,
-  0, 0, 0, 28, 14, 0, 53, 57, 40, 0,
-  0, 20, 46, 0, 33, 38, 62, 29, 61, 16,
-  47, 0, 46, 37, 0, 1, 0, 41, 74, 0,
-  7, 0, 37, 0, 26, 0, 0, 0, 8, 45,
-  0, 15, 14, 0, 13, 0, 0, 0, 20, 55,
-  23, 53, 16, 0, 159, 1, 19, 0, 8, 19,
-  20, 0, 0, 0, 0, 81, 7, 52, 28, 35,
-  49, 21, 9, 3, 0, 0, 0, 24, 50, 0,
-  0, 0, 1, 33, 4, 24, 7, 14, 0, 0,
-  0, 27, 51, 0, 10, 0, 0, 31, 38, 26,
-  32, 14, 0, 0, 0, 32, 48, 29, 26, 13,
-  31, 0, 3, 25, 74, 17, 4, 0, 45, 17,
-  0, 32, 0, 0, 21, 15, 0, 0, 0, 0,
-  6, 22, 50, 8, 38, 32, 47, 0, 0, 0,
-  1, 0, 13, 0, 30, 2, 0, 0, 24, 0,
-  46, 24, 32, 0, 0, 9, 38, 0, 15, 120,
-  0, 0, 0, 0, 0, 3, 58, 72, 0, 0,
-  0, 18, 0, 18, 44, 0, 0, 51, 0, 3,
-  0, 0, 0, 91, 41, 0, 0, 22, 0, 0,
-  0, 22, 0, 25, 0, 45, 0, 53, 1, 0,
-  0, 32, 0, 0, 0, 70, 11, 0, 0, 0,
-  19, 0, 13, 14, 0, 9, 0, 0, 0, 0,
-  0, 11, 0, 0, 0, 58, 10, 0, 0, 20,
-  0, 0, 2, 19, 0, 27, 10, 28, 51, 0,
-  32, 5, 54, 4, 0, 0, 52, 5, 0, 37,
-  0, 0, 0, 30, 0, 0, 0, 0, 3, 4,
-  0, 16, 10, 25, 57, 0, 0, 17, 37, 0,
-  63, 43, 24, 47, 55, 1, 2, 0, 25, 2,
-  0, 0, 0, 70, 65, 0, 63, 0, 15, 0,
-  1, 0, 14, 0, 64, 75, 0, 51, 17, 7,
-  26, 16, 9, 0, 0, 47, 38, 59, 0, 0,
-  0, 0, 53, 0, 0, 37, 12, 0, 0, 0,
-  0, 53, 50, 43, 24, 71, 73, 0, 0, 0,
-  0, 0, 0, 26, 50, 0, 0, 0, 0, 20,
-  1, 27, 24, 0, 0, 63, 0, 2, 29, 0,
-  0, 0, 0, 0, 7, 41, 16, 12, 0, 17,
-  0, 23, 46, 34, 33, 22, 87, 14, 32, 4,
-  49, 40, 0, 20, 24, 31, 0, 54, 0, 35,
-  3, 41, 0, 0, 0, 0, 0, 0, 7, 10,
-  34, 32, 82, 0, 0, 13, 31, 0, 0, 29,
-  54, 8, 7, 0, 55, 0, 75, 11, 2, 0,
-  0, 0, 119, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 103, 0, 9, 0, 6, 10, 5,
-  9, 50, 108, 24, 0, 0, 0, 8, 184, 0,
-  22, 0, 0, 31, 0, 0, 11, 12, 0, 10,
-  106, 0, 19, 21, 57, 33, 0, 2, 16, 0,
-  0, 65, 0, 0, 30, 0, 14, 26, 31, 0,
-  30, 40, 20, 0, 16, 5, 36, 0, 0, 70,
-  0, 0, 38, 61, 0, 0, 13, 0, 0, 0,
-  25, 10, 0, 19, 7, 11, 0, 47, 49, 0,
-  0, 54, 39, 0, 33, 24, 0, 0, 0, 22,
-  19, 7, 17, 0, 40, 27, 0, 5, 0, 0,
-  50, 3, 0, 0, 37, 20, 52, 0, 0, 30,
-  0, 0, 0, 0, 2, 25, 2, 0, 0, 52,
-  52, 0, 44, 0, 21, 0, 7, 0, 0, 3,
-  68, 73, 3, 33, 10, 1, 18, 0, 44, 0,
-  0, 50, 14, 42, 0, 0, 0, 12, 60, 0,
-  0, 39, 0, 0, 0, 7, 0, 62, 39, 63,
-  0, 87, 51, 0, 0, 0, 0, 0, 0, 78,
-  42, 0, 0, 0, 18, 20, 19, 14, 11, 0,
-  3, 81, 0, 28, 0, 0, 0, 0, 0, 30,
-  0, 13, 8, 1, 0, 0, 0, 18, 37, 38,
-  21, 0, 88, 0, 16, 0, 65, 54, 0, 0,
-  46, 25, 0, 61, 0, 19, 5, 30, 0, 0,
-  0, 0, 0, 0, 0, 15, 38, 43, 88, 0,
-  0, 20, 22, 0, 0, 24, 58, 18, 39, 4,
-  45, 0, 79, 0, 1, 0, 0, 16, 100, 0,
-  22, 0, 0, 0, 0, 0, 0, 11, 22, 94,
-  0, 49, 0, 51, 31, 35, 50, 27, 110, 9,
-  0, 0, 0, 0, 0, 0, 32, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 94, 0, 0, 96,
-  51, 18, 0, 0, 0, 0, 0, 79, 0, 0,
-  15, 0, 24, 0, 24, 0, 7, 8, 19, 6,
-  56, 0, 0, 10, 0, 51, 0, 0, 21, 34,
-  0, 0, 0, 16, 0, 0, 24, 0, 36, 0,
-  41, 12, 2, 0, 43, 21, 0, 36, 0, 0,
-  5, 39, 0, 0, 0, 27, 23, 0, 0, 0,
-  0, 0, 0, 11, 0, 6, 79, 9, 0, 5,
-  40, 0, 52, 15, 28, 31, 21, 0, 0, 0,
-  55, 12, 0, 0, 20, 0, 91, 19, 0, 0,
-  0, 12, 20, 0, 0, 0, 0, 125, 0, 0,
-  0, 22, 28, 1, 36, 70, 81, 11, 0, 0,
-  7, 35, 205, 0, 23, 21, 0, 15, 0, 0,
-  0, 31, 0, 0, 65, 0, 0, 38, 53, 70,
-  0, 0, 0, 0, 0, 120, 0, 6, 74, 0,
-  21, 12, 39, 0, 24, 17, 49, 0, 50, 0,
-  10, 0, 0, 102, 0, 0, 27, 14, 0, 0,
-  25, 0, 0, 0, 12, 2, 2, 20, 0, 0,
-  0, 33, 96, 33, 0, 2, 0, 0, 53, 20,
-  39, 0, 2, 26, 35, 12, 15, 0, 81, 19,
-  3, 30, 19, 0, 74, 0, 14, 0, 19, 31,
-  105, 0, 0, 54, 0, 0, 0, 0, 40, 22,
-  0, 17, 0, 43, 48, 0, 24, 32, 13, 0,
-  8, 0, 0, 0, 63, 49, 0, 0, 3, 17,
-  8, 10, 0, 0, 0, 37, 41, 35, 6, 0,
-  0, 48, 48, 0, 0, 14, 0, 0, 0, 2,
-  0, 39, 0, 40, 0, 41, 21, 0, 3, 0,
-  0, 0, 0, 40, 61, 0, 0, 0, 14, 6,
-  2, 35, 0, 6, 0, 21, 0, 0, 0, 27,
-  0, 0, 0, 32, 20, 0, 21, 28, 0, 0,
-  0, 25, 16, 25, 21, 40, 63, 0, 39, 18,
-  50, 13, 0, 0, 32, 28, 0, 22, 0, 38,
-  15, 31, 0, 0, 0, 0, 0, 28, 14, 0,
-  53, 57, 40, 0, 0, 20, 46, 0, 33, 38,
-  62, 29, 61, 16, 47, 0, 46, 37, 0, 1,
-  0, 41, 74, 0, 7, 0, 37, 0, 26, 0,
-  0, 0, 8, 45, 0, 15, 14, 0, 13, 0,
-  0, 0, 20, 55, 23, 53, 16, 0, 159, 1,
-  19, 0, 8, 19, 20, 0, 0, 0, 0, 81,
-  7, 52, 28, 35, 49, 21, 9, 3, 0, 0,
-  0, 24, 50, 0, 0, 0, 1, 33, 4, 24,
-  7, 14, 0, 0, 0, 27, 51, 0, 10, 0,
-  0, 31, 38, 26, 32, 14, 0, 0, 0, 32,
-  48, 29, 26, 13, 31, 0, 3, 25, 74, 17,
-  4, 0, 45, 17, 0, 32, 0, 0, 21, 15,
-  0, 0, 0, 0, 6, 22, 50, 8, 38, 32,
-  47, 0, 0, 0, 1, 0, 13, 0, 30, 2,
-  0, 0, 24, 0, 46, 24, 32, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 70, 65, 0,
-  63, 0, 15, 0, 1, 0, 14, 0, 64, 75,
-  0, 51, 17, 7, 26, 16, 9, 0, 0, 47,
-  38, 59, 0, 0, 0, 0, 53, 0, 0, 37,
-  12, 0, 0, 0, 0, 53, 50, 43, 24, 71,
-  73, 0, 0, 0, 0, 0, 0, 26, 50, 0,
-  0, 0, 0, 20, 1, 27, 24, 0, 0, 63,
-  0, 2, 29, 0, 0, 0, 0, 0, 7, 41,
-  16, 12, 0, 17, 0, 23, 46, 34, 33, 22,
-  87, 14, 32, 4, 49, 40, 0, 20, 24, 31,
-  0, 54, 0, 35, 3, 41, 0, 0, 0, 0,
-  0, 0, 7, 10, 34, 32, 82, 0, 0, 13,
-  31, 0, 0, 29, 54, 8, 7, 0, 55, 0,
-  75, 11, 2, 0, 0, 0, 119, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 103, 0, 9,
-  0, 6, 10, 5, 9, 50, 108, 24, 0, 0,
-  0, 8, 184, 0, 22, 0, 0, 31, 0, 0,
-  11, 12, 0, 10, 106, 0, 19, 21, 57, 33,
-  0, 2, 16, 0, 0, 65, 0, 0, 30, 0,
-  14, 26, 31, 0, 30, 40, 20, 0, 16, 5,
-  36, 0, 0, 70, 0, 0, 38, 61, 0, 0,
-  13, 0, 0, 0, 25, 10, 0, 19, 7, 11,
-  0, 47, 49, 0, 0, 54, 39, 0, 33, 24,
-  0, 0, 0, 22, 19, 7, 17, 0, 40, 27,
-  0, 5, 0, 0, 50, 3, 0, 0, 37, 20,
-  52, 0, 0, 30, 0, 0, 0, 0, 2, 25,
-  2, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 16, 100, 0, 22, 0, 0, 0, 0, 0,
-  0, 11, 22, 94, 0, 49, 0, 51, 31, 35,
-  50, 27, 110, 9, 0, 0, 0, 0, 0, 0,
-  32, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  94, 0, 0, 96, 51, 18, 0, 0, 0, 0,
-  0, 79, 0, 0, 15, 0, 24, 0, 24, 0,
-  7, 8, 19, 6, 56, 0, 0, 10, 0, 51,
-  0, 0, 21, 34, 0, 0, 0, 16, 0, 0,
-  24, 0, 36, 0, 41, 12, 2, 0, 43, 21,
-  0, 36, 0, 0, 5, 39, 0, 0, 0, 27,
-  23, 0, 0, 0, 0, 0, 0, 11, 0, 6,
-  79, 9, 0, 5, 40, 0, 52, 15, 28, 31,
-  21, 0, 0, 0, 55, 12, 0, 0, 20, 0,
-  91, 19, 0, 0, 0, 12, 20, 0, 0, 0,
-  0, 125, 0, 0, 0, 22, 28, 1, 36, 70,
-  81, 11, 0, 0, 7, 35, 205, 0, 23, 21,
-  0, 15, 0, 0, 0, 31, 0, 0, 65, 0,
-  0, 38, 53, 70, 0, 0, 0, 0, 0, 120,
-  0, 6, 74, 0, 21, 12, 39, 0, 24, 17,
-  49, 0, 50, 0, 10, 0, 0, 102, 0, 0,
-  27, 14, 0, 0, 25, 0, 0, 0, 12, 2,
-  2, 20, 0, 0, 0, 33, 96, 33, 0, 2,
-  0, 0, 53, 20, 39, 0, 2, 26, 35, 12,
-  15, 0, 81, 19, 3, 30, 19, 0, 74, 0,
-  14, 0, 19, 31, 105, 0, 0, 54, 0, 0,
-  0, 0, 40, 22, 0, 17, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 23, 32, 93, 27, 1, 9, 26, 5,
-  18, 0, 0, 0, 0, 103, 0, 30, 67, 4,
-  0, 16, 13, 75, 10, 41, 20, 0, 6, 20,
-  201, 42, 3, 62, 71, 0, 24, 0, 0, 56,
-  0, 4, 5, 32, 0, 22, 9, 88, 48, 0,
-  0, 0, 0, 51, 21, 3, 55, 0, 44, 0,
-  32, 0, 31, 72, 0, 0, 0, 0, 48, 9,
-  120, 30, 0, 10, 58, 0, 32, 0, 53, 0,
-  0, 37, 0, 0, 36, 11, 0, 15, 0, 0,
-  58, 5, 0, 0, 0, 3, 0, 36, 0, 0,
-  40, 101, 17, 0, 0, 52, 55, 89, 20, 0,
-  9, 0, 2, 9, 0, 33, 6, 2, 40, 0,
-  19, 12, 51, 0, 0, 0, 3, 0, 39, 30,
-  0, 67, 0, 11, 0, 33, 2, 0, 0, 0,
-  0, 17, 28, 49, 0, 0, 52, 3, 0, 0,
-  28, 58, 0, 42, 19, 0, 0, 8, 0, 9,
-  0, 26, 82, 21, 0, 0, 0, 27, 0, 8,
-  0, 40, 0, 22, 24, 91, 9, 110, 0, 0,
-  0, 27, 50, 0, 37, 0, 28, 0, 14, 0,
-  55, 50, 0, 43, 0, 0, 49, 11, 81, 0,
-  4, 0, 22, 7, 42, 0, 12, 0, 0, 26,
-  21, 0, 21, 24, 0, 0, 0, 0, 0, 9,
-  0, 0, 0, 9, 0, 20, 0, 0, 47, 83,
-  0, 52, 17, 21, 41, 51, 25, 0, 40, 5,
-  0, 40, 0, 11, 0, 0, 21, 0, 13, 13,
-  31, 0, 15, 0, 35, 1, 15, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 13, 24, 67, 6,
-  0, 18, 27, 22, 0, 0, 0, 0, 0, 97,
-  0, 0, 60, 4, 0, 5, 27, 86, 27, 52,
-  0, 0, 8, 9, 193, 55, 1, 28, 52, 0,
-  59, 1, 0, 58, 0, 17, 14, 39, 0, 14,
-  26, 83, 17, 0, 2, 0, 0, 64, 30, 0,
-  71, 0, 60, 0, 49, 0, 15, 71, 0, 0,
-  0, 0, 7, 6, 77, 33, 0, 22, 82, 11,
-  31, 27, 25, 0, 20, 13, 0, 0, 15, 5,
-  0, 0, 0, 0, 62, 3, 0, 0, 23, 0,
-  15, 37, 0, 0, 49, 67, 15, 0, 0, 37,
-  46, 75, 26, 0, 0, 6, 1, 16, 0, 37,
-  12, 0, 55, 0, 9, 28, 40, 0, 0, 0,
-  4, 0, 26, 26, 0, 60, 0, 15, 0, 5,
-  36, 23, 2, 0, 0, 31, 86, 8, 0, 0,
-  59, 11, 0, 0, 65, 56, 0, 25, 23, 0,
-  0, 13, 0, 13, 0, 11, 92, 0, 18, 0,
-  0, 32, 0, 53, 0, 28, 0, 44, 48, 94,
-  4, 86, 0, 7, 0, 38, 52, 0, 35, 0,
-  21, 0, 24, 0, 13, 27, 0, 40, 0, 11,
-  10, 0, 33, 0, 8, 0, 25, 13, 37, 0,
-  0, 0, 0, 15, 39, 0, 14, 13, 0, 0,
-  0, 0, 0, 24, 0, 0, 0, 13, 0, 47,
-  0, 0, 62, 50, 3, 0, 0, 13, 20, 1,
-  44, 0, 24, 28, 0, 29, 0, 15, 0, 0,
-  25, 0, 11, 10, 47, 0, 42, 0, 79, 0,
-  14, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 30, 25, 0, 1, 3, 33, 18, 0, 0,
-  0, 0, 0, 38, 0, 18, 43, 15, 0, 40,
-  38, 17, 58, 51, 0, 9, 8, 5, 128, 38,
-  0, 0, 54, 0, 69, 16, 0, 30, 0, 38,
-  21, 38, 0, 22, 60, 37, 2, 0, 0, 0,
-  0, 13, 47, 0, 16, 0, 64, 0, 29, 0,
-  6, 33, 7, 0, 0, 0, 7, 19, 25, 0,
-  0, 36, 79, 26, 45, 46, 0, 7, 30, 1,
-  38, 2, 13, 0, 0, 0, 0, 0, 54, 6,
-  3, 0, 38, 1, 15, 56, 0, 0, 37, 35,
-  9, 0, 0, 19, 20, 19, 57, 1, 0, 26,
-  0, 8, 0, 33, 5, 0, 23, 13, 0, 22,
-  19, 0, 0, 0, 19, 0, 11, 9, 0, 48,
-  13, 14, 0, 0, 29, 34, 3, 0, 0, 37,
-  105, 0, 2, 11, 53, 15, 0, 14, 67, 51,
-  53, 17, 9, 0, 0, 9, 0, 0, 0, 0,
-  96, 0, 32, 9, 0, 24, 0, 75, 0, 32,
-  0, 38, 68, 64, 0, 61, 0, 41, 0, 28,
-  43, 1, 16, 0, 14, 0, 11, 0, 0, 0,
-  0, 18, 0, 0, 0, 0, 17, 0, 10, 2,
-  29, 20, 37, 0, 16, 39, 0, 22, 45, 0,
-  41, 0, 0, 0, 0, 0, 0, 7, 0, 0,
-  0, 7, 0, 48, 0, 0, 52, 46, 8, 0,
-  0, 12, 18, 0, 59, 0, 0, 16, 0, 17,
-  0, 17, 0, 0, 14, 0, 6, 8, 40, 0,
-  40, 0, 76, 0, 11, 0, 23, 32, 93, 27,
-  1, 9, 26, 5, 18, 0, 0, 0, 0, 103,
-  0, 30, 67, 4, 0, 16, 13, 75, 10, 41,
-  20, 0, 6, 20, 201, 42, 3, 62, 71, 0,
-  24, 0, 0, 56, 0, 4, 5, 32, 0, 22,
-  9, 88, 48, 0, 0, 0, 0, 51, 21, 3,
-  55, 0, 44, 0, 32, 0, 31, 72, 0, 0,
-  0, 0, 48, 9, 120, 30, 0, 10, 58, 0,
-  32, 0, 53, 0, 0, 37, 0, 0, 36, 11,
-  0, 15, 0, 0, 58, 5, 0, 0, 0, 3,
-  0, 36, 0, 0, 40, 101, 17, 0, 0, 52,
-  55, 89, 20, 0, 9, 0, 2, 9, 0, 33,
-  6, 2, 40, 0, 19, 12, 51, 0, 0, 0,
-  3, 0, 39, 30, 0, 67, 0, 11, 0, 33,
-  2, 0, 0, 0, 0, 17, 28, 49, 0, 0,
-  52, 3, 0, 0, 28, 58, 0, 42, 19, 0,
-  0, 8, 0, 9, 0, 26, 82, 21, 0, 0,
-  0, 27, 0, 8, 0, 40, 0, 22, 24, 91,
-  9, 110, 0, 0, 0, 27, 50, 0, 37, 0,
-  28, 0, 14, 0, 55, 50, 0, 43, 0, 0,
-  49, 11, 81, 0, 4, 0, 22, 7, 42, 0,
-  12, 0, 0, 26, 21, 0, 21, 24, 0, 0,
-  0, 0, 0, 9, 0, 0, 0, 9, 0, 20,
-  0, 0, 47, 83, 0, 52, 17, 21, 41, 51,
-  25, 0, 40, 5, 0, 40, 0, 11, 0, 0,
-  21, 0, 13, 13, 31, 0, 15, 0, 35, 1,
-  15, 0, 0, 27, 36, 37, 0, 42, 17, 9,
-  15, 0, 0, 22, 97, 0, 7, 27, 55, 8,
-  0, 0, 0, 69, 0, 8, 46, 0, 0, 20,
-  0, 2, 0, 37, 78, 0, 3, 0, 0, 24,
-  0, 73, 0, 34, 30, 29, 29, 57, 25, 42,
-  0, 28, 0, 43, 34, 9, 17, 0, 10, 0,
-  0, 0, 6, 14, 0, 16, 0, 0, 0, 0,
-  28, 0, 23, 6, 0, 10, 7, 0, 0, 23,
-  0, 35, 38, 0, 52, 56, 0, 0, 11, 0,
-  0, 18, 0, 0, 0, 4, 0, 16, 29, 0,
-  0, 66, 6, 0, 0, 10, 18, 0, 38, 0,
-  0, 6, 0, 7, 0, 1, 0, 0, 17, 0,
-  0, 0, 5, 0, 43, 0, 63, 0, 11, 0,
-  13, 24, 67, 6, 0, 18, 27, 22, 0, 0,
-  0, 0, 0, 97, 0, 0, 60, 4, 0, 5,
-  27, 86, 27, 52, 0, 0, 8, 9, 193, 55,
-  1, 28, 52, 0, 59, 1, 0, 58, 0, 17,
-  14, 39, 0, 14, 26, 83, 17, 0, 2, 0,
-  0, 64, 30, 0, 71, 0, 60, 0, 49, 0,
-  15, 71, 0, 0, 0, 0, 7, 6, 77, 33,
-  0, 22, 82, 11, 31, 27, 25, 0, 20, 13,
-  0, 0, 15, 5, 0, 0, 0, 0, 62, 3,
-  0, 0, 23, 0, 15, 37, 0, 0, 49, 67,
-  15, 0, 0, 37, 46, 75, 26, 0, 0, 6,
-  1, 16, 0, 37, 12, 0, 55, 0, 9, 28,
-  40, 0, 0, 0, 4, 0, 26, 26, 0, 60,
-  0, 15, 0, 5, 36, 23, 2, 0, 0, 31,
-  86, 8, 0, 0, 59, 11, 0, 0, 65, 56,
-  0, 25, 23, 0, 0, 13, 0, 13, 0, 11,
-  92, 0, 18, 0, 0, 32, 0, 53, 0, 28,
-  0, 44, 48, 94, 4, 86, 0, 7, 0, 38,
-  52, 0, 35, 0, 21, 0, 24, 0, 13, 27,
-  0, 40, 0, 11, 10, 0, 33, 0, 8, 0,
-  25, 13, 37, 0, 0, 0, 0, 15, 39, 0,
-  14, 13, 0, 0, 0, 0, 0, 24, 0, 0,
-  0, 13, 0, 47, 0, 0, 62, 50, 3, 0,
-  0, 13, 20, 1, 44, 0, 24, 28, 0, 29,
-  0, 15, 0, 0, 25, 0, 11, 10, 47, 0,
-  42, 0, 79, 0, 14, 0, 3, 28, 40, 34,
-  0, 19, 25, 3, 20, 0, 0, 31, 114, 0,
-  21, 37, 61, 3, 0, 0, 0, 74, 0, 5,
-  57, 0, 0, 30, 0, 1, 0, 41, 79, 0,
-  10, 0, 0, 27, 0, 80, 0, 41, 32, 32,
-  31, 55, 32, 23, 0, 44, 0, 50, 31, 17,
-  17, 0, 7, 0, 0, 0, 12, 0, 0, 36,
-  0, 0, 4, 0, 28, 0, 17, 10, 0, 3,
-  3, 0, 15, 36, 0, 33, 36, 0, 51, 45,
-  0, 0, 5, 0, 0, 36, 0, 0, 0, 5,
-  0, 25, 33, 0, 3, 68, 5, 0, 5, 7,
-  24, 0, 28, 0, 2, 10, 6, 14, 0, 1,
-  0, 0, 2, 0, 6, 0, 15, 4, 59, 0,
-  74, 0, 21, 0, 0, 30, 25, 0, 1, 3,
-  33, 18, 0, 0, 0, 0, 0, 38, 0, 18,
-  43, 15, 0, 40, 38, 17, 58, 51, 0, 9,
-  8, 5, 128, 38, 0, 0, 54, 0, 69, 16,
-  0, 30, 0, 38, 21, 38, 0, 22, 60, 37,
-  2, 0, 0, 0, 0, 13, 47, 0, 16, 0,
-  64, 0, 29, 0, 6, 33, 7, 0, 0, 0,
-  7, 19, 25, 0, 0, 36, 79, 26, 45, 46,
-  0, 7, 30, 1, 38, 2, 13, 0, 0, 0,
-  0, 0, 54, 6, 3, 0, 38, 1, 15, 56,
-  0, 0, 37, 35, 9, 0, 0, 19, 20, 19,
-  57, 1, 0, 26, 0, 8, 0, 33, 5, 0,
-  23, 13, 0, 22, 19, 0, 0, 0, 19, 0,
-  11, 9, 0, 48, 13, 14, 0, 0, 29, 34,
-  3, 0, 0, 37, 105, 0, 2, 11, 53, 15,
-  0, 14, 67, 51, 53, 17, 9, 0, 0, 9,
-  0, 0, 0, 0, 96, 0, 32, 9, 0, 24,
-  0, 75, 0, 32, 0, 38, 68, 64, 0, 61,
-  0, 41, 0, 28, 43, 1, 16, 0, 14, 0,
-  11, 0, 0, 0, 0, 18, 0, 0, 0, 0,
-  17, 0, 10, 2, 29, 20, 37, 0, 16, 39,
-  0, 22, 45, 0, 41, 0, 0, 0, 0, 0,
-  0, 7, 0, 0, 0, 7, 0, 48, 0, 0,
-  52, 46, 8, 0, 0, 12, 18, 0, 59, 0,
-  0, 16, 0, 17, 0, 17, 0, 0, 14, 0,
-  6, 8, 40, 0, 40, 0, 76, 0, 11, 0,
-  4, 29, 39, 21, 0, 5, 28, 2, 19, 0,
-  0, 34, 112, 0, 22, 39, 53, 0, 0, 0,
-  0, 83, 0, 10, 59, 0, 0, 23, 0, 0,
-  0, 41, 82, 0, 23, 0, 0, 23, 0, 78,
-  0, 55, 37, 22, 36, 48, 30, 16, 0, 54,
-  0, 60, 33, 24, 31, 0, 11, 0, 7, 0,
-  17, 0, 0, 63, 0, 10, 7, 0, 36, 0,
-  8, 20, 0, 4, 0, 0, 33, 43, 0, 29,
-  44, 0, 61, 29, 0, 0, 0, 0, 0, 31,
-  0, 0, 0, 4, 0, 29, 42, 0, 5, 76,
-  2, 0, 8, 14, 30, 0, 21, 0, 0, 0,
-  8, 15, 0, 0, 0, 0, 0, 0, 6, 2,
-  19, 0, 53, 0, 69, 0, 17, 0, 0, 67,
-  0, 11, 0, 33, 2, 0, 0, 0, 0, 17,
-  28, 49, 0, 0, 52, 3, 0, 0, 28, 58,
-  0, 42, 19, 0, 0, 8, 0, 9, 0, 26,
-  82, 21, 0, 0, 0, 27, 0, 8, 0, 40,
-  0, 22, 24, 91, 9, 110, 0, 0, 0, 27,
-  50, 0, 37, 0, 28, 0, 14, 0, 55, 50,
-  0, 43, 0, 0, 49, 11, 81, 0, 4, 0,
-  22, 7, 42, 0, 12, 0, 0, 26, 21, 0,
-  21, 24, 0, 0, 0, 0, 0, 9, 0, 0,
-  0, 9, 0, 20, 0, 0, 47, 83, 0, 52,
-  17, 21, 41, 51, 25, 0, 40, 5, 0, 40,
-  0, 11, 0, 0, 21, 0, 13, 13, 31, 0,
-  15, 0, 35, 1, 15, 0, 0, 27, 36, 37,
-  0, 42, 17, 9, 15, 0, 0, 22, 97, 0,
-  7, 27, 55, 8, 0, 0, 0, 69, 0, 8,
-  46, 0, 0, 20, 0, 2, 0, 37, 78, 0,
-  3, 0, 0, 24, 0, 73, 0, 34, 30, 29,
-  29, 57, 25, 42, 0, 28, 0, 43, 34, 9,
-  17, 0, 10, 0, 0, 0, 6, 14, 0, 16,
-  0, 0, 0, 0, 28, 0, 23, 6, 0, 10,
-  7, 0, 0, 23, 0, 35, 38, 0, 52, 56,
-  0, 0, 11, 0, 0, 18, 0, 0, 0, 4,
-  0, 16, 29, 0, 0, 66, 6, 0, 0, 10,
-  18, 0, 38, 0, 0, 6, 0, 7, 0, 1,
-  0, 0, 17, 0, 0, 0, 5, 0, 43, 0,
-  63, 0, 11, 0, 0, 0, 0, 15, 0, 142,
-  5, 0, 3, 0, 0, 27, 43, 0, 0, 0,
-  6, 0, 0, 0, 37, 88, 23, 15, 8, 0,
-  0, 0, 0, 13, 0, 22, 26, 24, 0, 2,
-  0, 36, 0, 50, 0, 35, 0, 56, 1, 71,
-  43, 43, 0, 0, 0, 38, 8, 0, 4, 0,
-  67, 0, 33, 0, 0, 57, 0, 0, 64, 0,
-  0, 26, 62, 0, 74, 26, 27, 3, 4, 32,
-  9, 25, 0, 31, 35, 0, 37, 52, 8, 0,
-  19, 0, 0, 0, 0, 11, 7, 0, 1, 26,
-  0, 0, 10, 66, 18, 0, 0, 7, 8, 0,
-  31, 0, 0, 0, 0, 0, 0, 15, 0, 0,
-  111, 2, 35, 3, 0, 0, 0, 0, 41, 0,
-  0, 0, 0, 60, 0, 15, 0, 5, 36, 23,
-  2, 0, 0, 31, 86, 8, 0, 0, 59, 11,
-  0, 0, 65, 56, 0, 25, 23, 0, 0, 13,
-  0, 13, 0, 11, 92, 0, 18, 0, 0, 32,
-  0, 53, 0, 28, 0, 44, 48, 94, 4, 86,
-  0, 7, 0, 38, 52, 0, 35, 0, 21, 0,
-  24, 0, 13, 27, 0, 40, 0, 11, 10, 0,
-  33, 0, 8, 0, 25, 13, 37, 0, 0, 0,
-  0, 15, 39, 0, 14, 13, 0, 0, 0, 0,
-  0, 24, 0, 0, 0, 13, 0, 47, 0, 0,
-  62, 50, 3, 0, 0, 13, 20, 1, 44, 0,
-  24, 28, 0, 29, 0, 15, 0, 0, 25, 0,
-  11, 10, 47, 0, 42, 0, 79, 0, 14, 0,
-  3, 28, 40, 34, 0, 19, 25, 3, 20, 0,
-  0, 31, 114, 0, 21, 37, 61, 3, 0, 0,
-  0, 74, 0, 5, 57, 0, 0, 30, 0, 1,
-  0, 41, 79, 0, 10, 0, 0, 27, 0, 80,
-  0, 41, 32, 32, 31, 55, 32, 23, 0, 44,
-  0, 50, 31, 17, 17, 0, 7, 0, 0, 0,
-  12, 0, 0, 36, 0, 0, 4, 0, 28, 0,
-  17, 10, 0, 3, 3, 0, 15, 36, 0, 33,
-  36, 0, 51, 45, 0, 0, 5, 0, 0, 36,
-  0, 0, 0, 5, 0, 25, 33, 0, 3, 68,
-  5, 0, 5, 7, 24, 0, 28, 0, 2, 10,
-  6, 14, 0, 1, 0, 0, 2, 0, 6, 0,
-  15, 4, 59, 0, 74, 0, 21, 0, 0, 0,
-  0, 16, 0, 145, 3, 0, 12, 0, 0, 27,
-  50, 0, 0, 22, 2, 0, 1, 0, 35, 91,
-  18, 9, 3, 0, 0, 0, 0, 4, 0, 27,
-  23, 43, 0, 0, 0, 30, 0, 60, 0, 29,
-  0, 69, 6, 72, 26, 52, 0, 0, 0, 48,
-  12, 0, 0, 0, 56, 0, 35, 0, 2, 55,
-  0, 0, 72, 0, 0, 20, 53, 0, 83, 22,
-  17, 0, 0, 33, 2, 22, 0, 37, 41, 0,
-  32, 49, 7, 0, 27, 0, 0, 0, 0, 13,
-  1, 0, 15, 38, 0, 0, 2, 68, 27, 0,
-  0, 7, 17, 0, 22, 0, 0, 0, 0, 0,
-  0, 29, 0, 0, 104, 4, 40, 7, 0, 0,
-  0, 0, 54, 0, 3, 0, 0, 48, 13, 14,
-  0, 0, 29, 34, 3, 0, 0, 37, 105, 0,
-  2, 11, 53, 15, 0, 14, 67, 51, 53, 17,
-  9, 0, 0, 9, 0, 0, 0, 0, 96, 0,
-  32, 9, 0, 24, 0, 75, 0, 32, 0, 38,
-  68, 64, 0, 61, 0, 41, 0, 28, 43, 1,
-  16, 0, 14, 0, 11, 0, 0, 0, 0, 18,
-  0, 0, 0, 0, 17, 0, 10, 2, 29, 20,
-  37, 0, 16, 39, 0, 22, 45, 0, 41, 0,
-  0, 0, 0, 0, 0, 7, 0, 0, 0, 7,
-  0, 48, 0, 0, 52, 46, 8, 0, 0, 12,
-  18, 0, 59, 0, 0, 16, 0, 17, 0, 17,
-  0, 0, 14, 0, 6, 8, 40, 0, 40, 0,
-  76, 0, 11, 0, 4, 29, 39, 21, 0, 5,
-  28, 2, 19, 0, 0, 34, 112, 0, 22, 39,
-  53, 0, 0, 0, 0, 83, 0, 10, 59, 0,
-  0, 23, 0, 0, 0, 41, 82, 0, 23, 0,
-  0, 23, 0, 78, 0, 55, 37, 22, 36, 48,
-  30, 16, 0, 54, 0, 60, 33, 24, 31, 0,
-  11, 0, 7, 0, 17, 0, 0, 63, 0, 10,
-  7, 0, 36, 0, 8, 20, 0, 4, 0, 0,
-  33, 43, 0, 29, 44, 0, 61, 29, 0, 0,
-  0, 0, 0, 31, 0, 0, 0, 4, 0, 29,
-  42, 0, 5, 76, 2, 0, 8, 14, 30, 0,
-  21, 0, 0, 0, 8, 15, 0, 0, 0, 0,
-  0, 0, 6, 2, 19, 0, 53, 0, 69, 0,
-  17, 0, 0, 0, 0, 10, 0, 139, 4, 0,
-  12, 0, 0, 18, 33, 0, 0, 25, 0, 0,
-  0, 0, 30, 95, 19, 11, 3, 0, 0, 0,
-  0, 0, 0, 27, 29, 38, 0, 0, 0, 23,
-  0, 54, 0, 22, 0, 53, 1, 90, 35, 56,
-  0, 0, 0, 51, 6, 0, 10, 0, 55, 0,
-  49, 0, 11, 61, 0, 0, 76, 3, 0, 3,
-  55, 0, 82, 11, 11, 0, 0, 21, 26, 25,
-  0, 32, 34, 0, 41, 44, 0, 0, 22, 0,
-  0, 7, 0, 21, 4, 0, 4, 31, 0, 0,
-  7, 66, 36, 0, 0, 23, 27, 0, 16, 0,
-  0, 0, 0, 0, 0, 35, 0, 0, 100, 2,
-  34, 1, 0, 0, 0, 0, 28, 0, 0, 0,
-  0, 27, 36, 37, 0, 42, 17, 9, 15, 0,
-  0, 22, 97, 0, 7, 27, 55, 8, 0, 0,
-  0, 69, 0, 8, 46, 0, 0, 20, 0, 2,
-  0, 37, 78, 0, 3, 0, 0, 24, 0, 73,
-  0, 34, 30, 29, 29, 57, 25, 42, 0, 28,
-  0, 43, 34, 9, 17, 0, 10, 0, 0, 0,
-  6, 14, 0, 16, 0, 0, 0, 0, 28, 0,
-  23, 6, 0, 10, 7, 0, 0, 23, 0, 35,
-  38, 0, 52, 56, 0, 0, 11, 0, 0, 18,
-  0, 0, 0, 4, 0, 16, 29, 0, 0, 66,
-  6, 0, 0, 10, 18, 0, 38, 0, 0, 6,
-  0, 7, 0, 1, 0, 0, 17, 0, 0, 0,
-  5, 0, 43, 0, 63, 0, 11, 0, 0, 0,
-  0, 15, 0, 142, 5, 0, 3, 0, 0, 27,
-  43, 0, 0, 0, 6, 0, 0, 0, 37, 88,
-  23, 15, 8, 0, 0, 0, 0, 13, 0, 22,
-  26, 24, 0, 2, 0, 36, 0, 50, 0, 35,
-  0, 56, 1, 71, 43, 43, 0, 0, 0, 38,
-  8, 0, 4, 0, 67, 0, 33, 0, 0, 57,
-  0, 0, 64, 0, 0, 26, 62, 0, 74, 26,
-  27, 3, 4, 32, 9, 25, 0, 31, 35, 0,
-  37, 52, 8, 0, 19, 0, 0, 0, 0, 11,
-  7, 0, 1, 26, 0, 0, 10, 66, 18, 0,
-  0, 7, 8, 0, 31, 0, 0, 0, 0, 0,
-  0, 15, 0, 0, 111, 2, 35, 3, 0, 0,
-  0, 0, 41, 0, 0, 0, 0, 0, 0, 0,
-  0, 51, 48, 0, 17, 0, 0, 1, 56, 0,
-  12, 28, 33, 20, 5, 18, 77, 0, 0, 29,
-  0, 42, 17, 0, 0, 38, 0, 0, 71, 57,
-  0, 0, 0, 12, 0, 39, 0, 43, 0, 51,
-  0, 34, 20, 45, 0, 31, 15, 0, 71, 13,
-  0, 6, 44, 0, 0, 54, 15, 0, 0, 0,
-  0, 0, 23, 28, 33, 0, 0, 13, 0, 22,
-  15, 54, 0, 0, 0, 29, 69, 6, 16, 0,
-  25, 0, 11, 13, 3, 2, 0, 26, 5, 14,
-  0, 26, 0, 0, 43, 47, 11, 6, 0, 0,
-  0, 0, 43, 0, 0, 46, 1, 0, 0, 11,
-  0, 0, 48, 15, 46, 0, 23, 0, 104, 0,
-  47, 0, 0, 0, 3, 28, 40, 34, 0, 19,
-  25, 3, 20, 0, 0, 31, 114, 0, 21, 37,
-  61, 3, 0, 0, 0, 74, 0, 5, 57, 0,
-  0, 30, 0, 1, 0, 41, 79, 0, 10, 0,
-  0, 27, 0, 80, 0, 41, 32, 32, 31, 55,
-  32, 23, 0, 44, 0, 50, 31, 17, 17, 0,
-  7, 0, 0, 0, 12, 0, 0, 36, 0, 0,
-  4, 0, 28, 0, 17, 10, 0, 3, 3, 0,
-  15, 36, 0, 33, 36, 0, 51, 45, 0, 0,
-  5, 0, 0, 36, 0, 0, 0, 5, 0, 25,
-  33, 0, 3, 68, 5, 0, 5, 7, 24, 0,
-  28, 0, 2, 10, 6, 14, 0, 1, 0, 0,
-  2, 0, 6, 0, 15, 4, 59, 0, 74, 0,
-  21, 0, 0, 0, 0, 16, 0, 145, 3, 0,
-  12, 0, 0, 27, 50, 0, 0, 22, 2, 0,
-  1, 0, 35, 91, 18, 9, 3, 0, 0, 0,
-  0, 4, 0, 27, 23, 43, 0, 0, 0, 30,
-  0, 60, 0, 29, 0, 69, 6, 72, 26, 52,
-  0, 0, 0, 48, 12, 0, 0, 0, 56, 0,
-  35, 0, 2, 55, 0, 0, 72, 0, 0, 20,
-  53, 0, 83, 22, 17, 0, 0, 33, 2, 22,
-  0, 37, 41, 0, 32, 49, 7, 0, 27, 0,
-  0, 0, 0, 13, 1, 0, 15, 38, 0, 0,
-  2, 68, 27, 0, 0, 7, 17, 0, 22, 0,
-  0, 0, 0, 0, 0, 29, 0, 0, 104, 4,
-  40, 7, 0, 0, 0, 0, 54, 0, 3, 0,
-  0, 0, 0, 0, 0, 45, 41, 0, 20, 0,
-  0, 0, 75, 11, 19, 55, 39, 21, 25, 2,
-  84, 0, 0, 27, 13, 52, 3, 2, 0, 52,
-  0, 0, 56, 63, 0, 0, 0, 0, 0, 59,
-  0, 43, 0, 45, 7, 20, 17, 36, 0, 46,
-  0, 0, 66, 22, 0, 0, 25, 0, 0, 76,
-  20, 0, 0, 2, 0, 0, 13, 21, 31, 0,
-  0, 26, 0, 14, 8, 55, 0, 0, 0, 54,
-  58, 17, 20, 5, 37, 0, 12, 14, 8, 14,
-  4, 15, 7, 17, 1, 41, 0, 0, 39, 55,
-  6, 0, 4, 0, 0, 0, 35, 0, 0, 42,
-  13, 0, 0, 5, 0, 0, 43, 15, 52, 0,
-  18, 3, 121, 0, 68, 0, 9, 0, 4, 29,
-  39, 21, 0, 5, 28, 2, 19, 0, 0, 34,
-  112, 0, 22, 39, 53, 0, 0, 0, 0, 83,
-  0, 10, 59, 0, 0, 23, 0, 0, 0, 41,
-  82, 0, 23, 0, 0, 23, 0, 78, 0, 55,
-  37, 22, 36, 48, 30, 16, 0, 54, 0, 60,
-  33, 24, 31, 0, 11, 0, 7, 0, 17, 0,
-  0, 63, 0, 10, 7, 0, 36, 0, 8, 20,
-  0, 4, 0, 0, 33, 43, 0, 29, 44, 0,
-  61, 29, 0, 0, 0, 0, 0, 31, 0, 0,
-  0, 4, 0, 29, 42, 0, 5, 76, 2, 0,
-  8, 14, 30, 0, 21, 0, 0, 0, 8, 15,
-  0, 0, 0, 0, 0, 0, 6, 2, 19, 0,
-  53, 0, 69, 0, 17, 0, 0, 0, 0, 10,
-  0, 139, 4, 0, 12, 0, 0, 18, 33, 0,
-  0, 25, 0, 0, 0, 0, 30, 95, 19, 11,
-  3, 0, 0, 0, 0, 0, 0, 27, 29, 38,
-  0, 0, 0, 23, 0, 54, 0, 22, 0, 53,
-  1, 90, 35, 56, 0, 0, 0, 51, 6, 0,
-  10, 0, 55, 0, 49, 0, 11, 61, 0, 0,
-  76, 3, 0, 3, 55, 0, 82, 11, 11, 0,
-  0, 21, 26, 25, 0, 32, 34, 0, 41, 44,
-  0, 0, 22, 0, 0, 7, 0, 21, 4, 0,
-  4, 31, 0, 0, 7, 66, 36, 0, 0, 23,
-  27, 0, 16, 0, 0, 0, 0, 0, 0, 35,
-  0, 0, 100, 2, 34, 1, 0, 0, 0, 0,
-  28, 0, 0, 0, 0, 0, 0, 0, 9, 38,
-  29, 0, 28, 0, 15, 0, 49, 21, 13, 59,
-  25, 11, 12, 5, 68, 0, 0, 42, 2, 24,
-  1, 0, 0, 35, 0, 0, 51, 61, 4, 0,
-  0, 0, 0, 42, 8, 38, 0, 45, 9, 26,
-  16, 31, 0, 20, 23, 0, 74, 24, 0, 0,
-  43, 0, 0, 56, 26, 7, 0, 0, 0, 0,
-  26, 8, 30, 0, 0, 7, 0, 8, 2, 45,
-  9, 0, 0, 52, 52, 14, 29, 21, 20, 0,
-  7, 19, 17, 28, 6, 32, 0, 6, 20, 41,
-  0, 0, 30, 59, 7, 0, 1, 0, 0, 0,
-  35, 0, 0, 25, 13, 0, 0, 13, 0, 0,
-  41, 20, 37, 0, 1, 0, 90, 0, 36, 0,
-  0, 0, 0, 0, 0, 15, 0, 142, 5, 0,
-  3, 0, 0, 27, 43, 0, 0, 0, 6, 0,
-  0, 0, 37, 88, 23, 15, 8, 0, 0, 0,
-  0, 13, 0, 22, 26, 24, 0, 2, 0, 36,
-  0, 50, 0, 35, 0, 56, 1, 71, 43, 43,
-  0, 0, 0, 38, 8, 0, 4, 0, 67, 0,
-  33, 0, 0, 57, 0, 0, 64, 0, 0, 26,
-  62, 0, 74, 26, 27, 3, 4, 32, 9, 25,
-  0, 31, 35, 0, 37, 52, 8, 0, 19, 0,
-  0, 0, 0, 11, 7, 0, 1, 26, 0, 0,
-  10, 66, 18, 0, 0, 7, 8, 0, 31, 0,
-  0, 0, 0, 0, 0, 15, 0, 0, 111, 2,
-  35, 3, 0, 0, 0, 0, 41, 0, 0, 0,
-  0, 0, 0, 0, 0, 51, 48, 0, 17, 0,
-  0, 1, 56, 0, 12, 28, 33, 20, 5, 18,
-  77, 0, 0, 29, 0, 42, 17, 0, 0, 38,
-  0, 0, 71, 57, 0, 0, 0, 12, 0, 39,
-  0, 43, 0, 51, 0, 34, 20, 45, 0, 31,
-  15, 0, 71, 13, 0, 6, 44, 0, 0, 54,
-  15, 0, 0, 0, 0, 0, 23, 28, 33, 0,
-  0, 13, 0, 22, 15, 54, 0, 0, 0, 29,
-  69, 6, 16, 0, 25, 0, 11, 13, 3, 2,
-  0, 26, 5, 14, 0, 26, 0, 0, 43, 47,
-  11, 6, 0, 0, 0, 0, 43, 0, 0, 46,
-  1, 0, 0, 11, 0, 0, 48, 15, 46, 0,
-  23, 0, 104, 0, 47, 0, 0, 0, 0, 29,
-  0, 0, 20, 0, 45, 0, 38, 0, 0, 2,
-  26, 28, 73, 29, 52, 53, 0, 24, 91, 0,
-  0, 24, 16, 39, 26, 0, 0, 20, 0, 0,
-  40, 12, 3, 0, 0, 8, 0, 47, 0, 9,
-  0, 58, 0, 33, 12, 19, 0, 0, 17, 3,
-  66, 44, 0, 0, 7, 0, 0, 3, 7, 0,
-  0, 0, 0, 0, 42, 7, 32, 0, 0, 0,
-  0, 10, 51, 0, 4, 0, 0, 8, 61, 18,
-  25, 0, 32, 0, 8, 4, 12, 12, 2, 0,
-  0, 26, 0, 31, 0, 0, 56, 29, 0, 2,
-  0, 0, 0, 0, 30, 0, 7, 37, 0, 0,
-  0, 21, 0, 0, 7, 6, 14, 0, 16, 0,
-  90, 0, 25, 0, 12, 0, 0, 0, 0, 16,
-  0, 145, 3, 0, 12, 0, 0, 27, 50, 0,
-  0, 22, 2, 0, 1, 0, 35, 91, 18, 9,
-  3, 0, 0, 0, 0, 4, 0, 27, 23, 43,
-  0, 0, 0, 30, 0, 60, 0, 29, 0, 69,
-  6, 72, 26, 52, 0, 0, 0, 48, 12, 0,
-  0, 0, 56, 0, 35, 0, 2, 55, 0, 0,
-  72, 0, 0, 20, 53, 0, 83, 22, 17, 0,
-  0, 33, 2, 22, 0, 37, 41, 0, 32, 49,
-  7, 0, 27, 0, 0, 0, 0, 13, 1, 0,
-  15, 38, 0, 0, 2, 68, 27, 0, 0, 7,
-  17, 0, 22, 0, 0, 0, 0, 0, 0, 29,
-  0, 0, 104, 4, 40, 7, 0, 0, 0, 0,
-  54, 0, 3, 0, 0, 0, 0, 0, 0, 45,
-  41, 0, 20, 0, 0, 0, 75, 11, 19, 55,
-  39, 21, 25, 2, 84, 0, 0, 27, 13, 52,
-  3, 2, 0, 52, 0, 0, 56, 63, 0, 0,
-  0, 0, 0, 59, 0, 43, 0, 45, 7, 20,
-  17, 36, 0, 46, 0, 0, 66, 22, 0, 0,
-  25, 0, 0, 76, 20, 0, 0, 2, 0, 0,
-  13, 21, 31, 0, 0, 26, 0, 14, 8, 55,
-  0, 0, 0, 54, 58, 17, 20, 5, 37, 0,
-  12, 14, 8, 14, 4, 15, 7, 17, 1, 41,
-  0, 0, 39, 55, 6, 0, 4, 0, 0, 0,
-  35, 0, 0, 42, 13, 0, 0, 5, 0, 0,
-  43, 15, 52, 0, 18, 3, 121, 0, 68, 0,
-  9, 0, 0, 49, 1, 0, 30, 0, 15, 0,
-  64, 0, 0, 7, 46, 41, 52, 60, 59, 47,
-  14, 4, 85, 0, 0, 29, 21, 32, 22, 9,
-  0, 19, 0, 0, 33, 0, 0, 0, 0, 0,
-  0, 62, 0, 0, 0, 54, 0, 32, 4, 0,
-  0, 16, 7, 12, 54, 37, 0, 0, 0, 0,
-  0, 0, 1, 0, 0, 0, 0, 0, 49, 0,
-  30, 0, 0, 0, 5, 29, 27, 0, 0, 9,
-  0, 21, 35, 23, 45, 0, 23, 22, 4, 26,
-  21, 30, 26, 0, 0, 24, 0, 19, 0, 0,
-  46, 43, 11, 0, 0, 0, 0, 0, 30, 1,
-  0, 44, 0, 0, 0, 16, 0, 0, 1, 3,
-  6, 0, 0, 0, 95, 0, 52, 0, 20, 0,
-  0, 0, 0, 10, 0, 139, 4, 0, 12, 0,
-  0, 18, 33, 0, 0, 25, 0, 0, 0, 0,
-  30, 95, 19, 11, 3, 0, 0, 0, 0, 0,
-  0, 27, 29, 38, 0, 0, 0, 23, 0, 54,
-  0, 22, 0, 53, 1, 90, 35, 56, 0, 0,
-  0, 51, 6, 0, 10, 0, 55, 0, 49, 0,
-  11, 61, 0, 0, 76, 3, 0, 3, 55, 0,
-  82, 11, 11, 0, 0, 21, 26, 25, 0, 32,
-  34, 0, 41, 44, 0, 0, 22, 0, 0, 7,
-  0, 21, 4, 0, 4, 31, 0, 0, 7, 66,
-  36, 0, 0, 23, 27, 0, 16, 0, 0, 0,
-  0, 0, 0, 35, 0, 0, 100, 2, 34, 1,
-  0, 0, 0, 0, 28, 0, 0, 0, 0, 0,
-  0, 0, 9, 38, 29, 0, 28, 0, 15, 0,
-  49, 21, 13, 59, 25, 11, 12, 5, 68, 0,
-  0, 42, 2, 24, 1, 0, 0, 35, 0, 0,
-  51, 61, 4, 0, 0, 0, 0, 42, 8, 38,
-  0, 45, 9, 26, 16, 31, 0, 20, 23, 0,
-  74, 24, 0, 0, 43, 0, 0, 56, 26, 7,
-  0, 0, 0, 0, 26, 8, 30, 0, 0, 7,
-  0, 8, 2, 45, 9, 0, 0, 52, 52, 14,
-  29, 21, 20, 0, 7, 19, 17, 28, 6, 32,
-  0, 6, 20, 41, 0, 0, 30, 59, 7, 0,
-  1, 0, 0, 0, 35, 0, 0, 25, 13, 0,
-  0, 13, 0, 0, 41, 20, 37, 0, 1, 0,
-  90, 0, 36, 0, 0, 0, 0, 41, 38, 0,
-  0, 0, 0, 0, 61, 6, 0, 16, 12, 19,
-  25, 54, 49, 37, 21, 5, 43, 0, 53, 32,
-  0, 0, 35, 21, 0, 0, 0, 0, 32, 0,
-  3, 0, 0, 0, 0, 35, 0, 0, 0, 27,
-  0, 26, 0, 0, 0, 15, 28, 3, 38, 9,
-  0, 0, 27, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 56, 0, 5, 0, 0, 0, 1, 44,
-  11, 11, 0, 62, 0, 23, 13, 12, 56, 44,
-  1, 24, 0, 29, 27, 31, 52, 10, 0, 0,
-  12, 0, 0, 0, 11, 51, 42, 0, 0, 0,
-  0, 0, 41, 0, 0, 48, 5, 0, 0, 10,
-  0, 0, 7, 0, 0, 0, 0, 0, 47, 0,
-  21, 0, 1, 20, 0, 0, 0, 0, 0, 51,
-  48, 0, 17, 0, 0, 1, 56, 0, 12, 28,
-  33, 20, 5, 18, 77, 0, 0, 29, 0, 42,
-  17, 0, 0, 38, 0, 0, 71, 57, 0, 0,
-  0, 12, 0, 39, 0, 43, 0, 51, 0, 34,
-  20, 45, 0, 31, 15, 0, 71, 13, 0, 6,
-  44, 0, 0, 54, 15, 0, 0, 0, 0, 0,
-  23, 28, 33, 0, 0, 13, 0, 22, 15, 54,
-  0, 0, 0, 29, 69, 6, 16, 0, 25, 0,
-  11, 13, 3, 2, 0, 26, 5, 14, 0, 26,
-  0, 0, 43, 47, 11, 6, 0, 0, 0, 0,
-  43, 0, 0, 46, 1, 0, 0, 11, 0, 0,
-  48, 15, 46, 0, 23, 0, 104, 0, 47, 0,
-  0, 0, 0, 29, 0, 0, 20, 0, 45, 0,
-  38, 0, 0, 2, 26, 28, 73, 29, 52, 53,
-  0, 24, 91, 0, 0, 24, 16, 39, 26, 0,
-  0, 20, 0, 0, 40, 12, 3, 0, 0, 8,
-  0, 47, 0, 9, 0, 58, 0, 33, 12, 19,
-  0, 0, 17, 3, 66, 44, 0, 0, 7, 0,
-  0, 3, 7, 0, 0, 0, 0, 0, 42, 7,
-  32, 0, 0, 0, 0, 10, 51, 0, 4, 0,
-  0, 8, 61, 18, 25, 0, 32, 0, 8, 4,
-  12, 12, 2, 0, 0, 26, 0, 31, 0, 0,
-  56, 29, 0, 2, 0, 0, 0, 0, 30, 0,
-  7, 37, 0, 0, 0, 21, 0, 0, 7, 6,
-  14, 0, 16, 0, 90, 0, 25, 0, 12, 0,
-  0, 65, 0, 0, 34, 0, 36, 0, 61, 12,
-  0, 5, 44, 54, 61, 74, 64, 45, 0, 12,
-  72, 0, 0, 33, 31, 57, 17, 27, 0, 12,
-  0, 0, 29, 8, 17, 0, 0, 37, 0, 58,
-  0, 3, 0, 54, 0, 29, 24, 4, 0, 0,
-  35, 0, 43, 56, 0, 0, 7, 0, 0, 32,
-  0, 0, 0, 0, 0, 0, 70, 9, 41, 0,
-  0, 0, 0, 18, 51, 0, 0, 21, 0, 27,
-  40, 52, 13, 20, 40, 15, 0, 9, 25, 57,
-  3, 0, 0, 59, 0, 27, 0, 5, 69, 44,
-  0, 0, 0, 0, 2, 0, 12, 20, 36, 60,
-  0, 0, 0, 21, 0, 0, 0, 18, 24, 0,
-  0, 1, 134, 0, 38, 0, 44, 0, 0, 0,
-  0, 0, 0, 45, 41, 0, 20, 0, 0, 0,
-  75, 11, 19, 55, 39, 21, 25, 2, 84, 0,
-  0, 27, 13, 52, 3, 2, 0, 52, 0, 0,
-  56, 63, 0, 0, 0, 0, 0, 59, 0, 43,
-  0, 45, 7, 20, 17, 36, 0, 46, 0, 0,
-  66, 22, 0, 0, 25, 0, 0, 76, 20, 0,
-  0, 2, 0, 0, 13, 21, 31, 0, 0, 26,
-  0, 14, 8, 55, 0, 0, 0, 54, 58, 17,
-  20, 5, 37, 0, 12, 14, 8, 14, 4, 15,
-  7, 17, 1, 41, 0, 0, 39, 55, 6, 0,
-  4, 0, 0, 0, 35, 0, 0, 42, 13, 0,
-  0, 5, 0, 0, 43, 15, 52, 0, 18, 3,
-  121, 0, 68, 0, 9, 0, 0, 49, 1, 0,
-  30, 0, 15, 0, 64, 0, 0, 7, 46, 41,
-  52, 60, 59, 47, 14, 4, 85, 0, 0, 29,
-  21, 32, 22, 9, 0, 19, 0, 0, 33, 0,
-  0, 0, 0, 0, 0, 62, 0, 0, 0, 54,
-  0, 32, 4, 0, 0, 16, 7, 12, 54, 37,
-  0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
-  0, 0, 49, 0, 30, 0, 0, 0, 5, 29,
-  27, 0, 0, 9, 0, 21, 35, 23, 45, 0,
-  23, 22, 4, 26, 21, 30, 26, 0, 0, 24,
-  0, 19, 0, 0, 46, 43, 11, 0, 0, 0,
-  0, 0, 30, 1, 0, 44, 0, 0, 0, 16,
-  0, 0, 1, 3, 6, 0, 0, 0, 95, 0,
-  52, 0, 20, 0, 0, 44, 27, 0, 33, 0,
-  0, 0, 76, 0, 0, 1, 67, 69, 11, 51,
-  63, 32, 6, 0, 66, 0, 0, 38, 0, 0,
-  28, 40, 0, 0, 0, 0, 7, 0, 0, 0,
-  0, 27, 0, 47, 0, 0, 0, 20, 0, 38,
-  0, 0, 0, 16, 0, 34, 21, 7, 0, 0,
-  0, 8, 0, 0, 0, 0, 0, 0, 0, 0,
-  98, 0, 25, 5, 0, 0, 0, 78, 9, 0,
-  0, 35, 0, 0, 12, 5, 38, 41, 20, 53,
-  0, 44, 32, 14, 27, 37, 0, 13, 0, 0,
-  0, 0, 28, 63, 38, 0, 0, 0, 0, 0,
-  3, 36, 0, 61, 0, 0, 0, 5, 3, 0,
-  4, 0, 0, 0, 0, 0, 77, 0, 26, 0,
-  18, 21, 0, 0, 0, 0, 9, 38, 29, 0,
-  28, 0, 15, 0, 49, 21, 13, 59, 25, 11,
-  12, 5, 68, 0, 0, 42, 2, 24, 1, 0,
-  0, 35, 0, 0, 51, 61, 4, 0, 0, 0,
-  0, 42, 8, 38, 0, 45, 9, 26, 16, 31,
-  0, 20, 23, 0, 74, 24, 0, 0, 43, 0,
-  0, 56, 26, 7, 0, 0, 0, 0, 26, 8,
-  30, 0, 0, 7, 0, 8, 2, 45, 9, 0,
-  0, 52, 52, 14, 29, 21, 20, 0, 7, 19,
-  17, 28, 6, 32, 0, 6, 20, 41, 0, 0,
-  30, 59, 7, 0, 1, 0, 0, 0, 35, 0,
-  0, 25, 13, 0, 0, 13, 0, 0, 41, 20,
-  37, 0, 1, 0, 90, 0, 36, 0, 0, 0,
-  0, 41, 38, 0, 0, 0, 0, 0, 61, 6,
-  0, 16, 12, 19, 25, 54, 49, 37, 21, 5,
-  43, 0, 53, 32, 0, 0, 35, 21, 0, 0,
-  0, 0, 32, 0, 3, 0, 0, 0, 0, 35,
-  0, 0, 0, 27, 0, 26, 0, 0, 0, 15,
-  28, 3, 38, 9, 0, 0, 27, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 56, 0, 5, 0,
-  0, 0, 1, 44, 11, 11, 0, 62, 0, 23,
-  13, 12, 56, 44, 1, 24, 0, 29, 27, 31,
-  52, 10, 0, 0, 12, 0, 0, 0, 11, 51,
-  42, 0, 0, 0, 0, 0, 41, 0, 0, 48,
-  5, 0, 0, 10, 0, 0, 7, 0, 0, 0,
-  0, 0, 47, 0, 21, 0, 1, 20, 52, 0,
-  43, 0, 22, 0, 0, 0, 29, 0, 0, 0,
-  38, 88, 0, 0, 38, 0, 13, 0, 33, 104,
-  68, 26, 0, 0, 8, 50, 0, 0, 0, 10,
-  0, 4, 0, 0, 0, 20, 0, 11, 1, 0,
-  0, 0, 0, 16, 0, 0, 0, 7, 0, 77,
-  0, 0, 52, 0, 26, 23, 6, 0, 25, 0,
-  0, 6, 24, 0, 92, 16, 18, 73, 0, 0,
-  0, 73, 0, 0, 0, 50, 0, 0, 0, 0,
-  11, 59, 10, 49, 0, 55, 10, 0, 0, 37,
-  0, 0, 5, 0, 13, 0, 23, 61, 29, 7,
-  1, 0, 19, 2, 0, 26, 0, 53, 0, 7,
-  0, 0, 0, 23, 69, 0, 1, 0, 0, 31,
-  0, 0, 4, 0, 0, 61, 0, 29, 0, 0,
-  20, 0, 45, 0, 38, 0, 0, 2, 26, 28,
-  73, 29, 52, 53, 0, 24, 91, 0, 0, 24,
-  16, 39, 26, 0, 0, 20, 0, 0, 40, 12,
-  3, 0, 0, 8, 0, 47, 0, 9, 0, 58,
-  0, 33, 12, 19, 0, 0, 17, 3, 66, 44,
-  0, 0, 7, 0, 0, 3, 7, 0, 0, 0,
-  0, 0, 42, 7, 32, 0, 0, 0, 0, 10,
-  51, 0, 4, 0, 0, 8, 61, 18, 25, 0,
-  32, 0, 8, 4, 12, 12, 2, 0, 0, 26,
-  0, 31, 0, 0, 56, 29, 0, 2, 0, 0,
-  0, 0, 30, 0, 7, 37, 0, 0, 0, 21,
-  0, 0, 7, 6, 14, 0, 16, 0, 90, 0,
-  25, 0, 12, 0, 0, 65, 0, 0, 34, 0,
-  36, 0, 61, 12, 0, 5, 44, 54, 61, 74,
-  64, 45, 0, 12, 72, 0, 0, 33, 31, 57,
-  17, 27, 0, 12, 0, 0, 29, 8, 17, 0,
-  0, 37, 0, 58, 0, 3, 0, 54, 0, 29,
-  24, 4, 0, 0, 35, 0, 43, 56, 0, 0,
-  7, 0, 0, 32, 0, 0, 0, 0, 0, 0,
-  70, 9, 41, 0, 0, 0, 0, 18, 51, 0,
-  0, 21, 0, 27, 40, 52, 13, 20, 40, 15,
-  0, 9, 25, 57, 3, 0, 0, 59, 0, 27,
-  0, 5, 69, 44, 0, 0, 0, 0, 2, 0,
-  12, 20, 36, 60, 0, 0, 0, 21, 0, 0,
-  0, 18, 24, 0, 0, 1, 134, 0, 38, 0,
-  44, 0, 0, 26, 42, 0, 40, 0, 0, 0,
-  68, 7, 0, 5, 43, 69, 21, 36, 59, 16,
-  3, 0, 30, 7, 16, 33, 0, 0, 32, 69,
-  0, 5, 0, 0, 0, 0, 0, 0, 0, 55,
-  0, 45, 0, 4, 0, 0, 0, 8, 12, 0,
-  0, 16, 23, 16, 0, 8, 0, 0, 24, 20,
-  0, 0, 0, 0, 0, 0, 0, 0, 70, 10,
-  16, 0, 0, 0, 0, 27, 24, 0, 0, 57,
-  0, 13, 0, 13, 15, 76, 12, 31, 0, 45,
-  9, 26, 24, 0, 0, 11, 0, 0, 0, 0,
-  52, 56, 16, 0, 0, 0, 1, 0, 7, 24,
-  39, 91, 4, 0, 0, 0, 0, 0, 11, 0,
-  10, 0, 0, 35, 51, 0, 0, 0, 24, 66,
-  0, 49, 1, 0, 30, 0, 15, 0, 64, 0,
-  0, 7, 46, 41, 52, 60, 59, 47, 14, 4,
-  85, 0, 0, 29, 21, 32, 22, 9, 0, 19,
-  0, 0, 33, 0, 0, 0, 0, 0, 0, 62,
-  0, 0, 0, 54, 0, 32, 4, 0, 0, 16,
-  7, 12, 54, 37, 0, 0, 0, 0, 0, 0,
-  1, 0, 0, 0, 0, 0, 49, 0, 30, 0,
-  0, 0, 5, 29, 27, 0, 0, 9, 0, 21,
-  35, 23, 45, 0, 23, 22, 4, 26, 21, 30,
-  26, 0, 0, 24, 0, 19, 0, 0, 46, 43,
-  11, 0, 0, 0, 0, 0, 30, 1, 0, 44,
-  0, 0, 0, 16, 0, 0, 1, 3, 6, 0,
-  0, 0, 95, 0, 52, 0, 20, 0, 0, 44,
-  27, 0, 33, 0, 0, 0, 76, 0, 0, 1,
-  67, 69, 11, 51, 63, 32, 6, 0, 66, 0,
-  0, 38, 0, 0, 28, 40, 0, 0, 0, 0,
-  7, 0, 0, 0, 0, 27, 0, 47, 0, 0,
-  0, 20, 0, 38, 0, 0, 0, 16, 0, 34,
-  21, 7, 0, 0, 0, 8, 0, 0, 0, 0,
-  0, 0, 0, 0, 98, 0, 25, 5, 0, 0,
-  0, 78, 9, 0, 0, 35, 0, 0, 12, 5,
-  38, 41, 20, 53, 0, 44, 32, 14, 27, 37,
-  0, 13, 0, 0, 0, 0, 28, 63, 38, 0,
-  0, 0, 0, 0, 3, 36, 0, 61, 0, 0,
-  0, 5, 3, 0, 4, 0, 0, 0, 0, 0,
-  77, 0, 26, 0, 18, 21, 29, 0, 57, 0,
-  12, 30, 0, 0, 52, 0, 0, 2, 43, 101,
-  14, 0, 40, 0, 0, 0, 32, 66, 0, 35,
-  0, 0, 0, 29, 0, 8, 0, 0, 0, 11,
-  0, 0, 0, 50, 0, 48, 0, 31, 0, 0,
-  0, 0, 0, 0, 6, 9, 0, 67, 0, 0,
-  11, 0, 13, 40, 0, 0, 5, 7, 0, 44,
-  0, 15, 58, 0, 30, 45, 0, 14, 0, 32,
-  0, 0, 0, 10, 0, 27, 0, 3, 29, 32,
-  45, 49, 0, 64, 21, 0, 0, 14, 0, 0,
-  0, 0, 0, 0, 30, 78, 0, 0, 0, 0,
-  0, 18, 0, 23, 14, 57, 17, 0, 0, 0,
-  29, 0, 59, 1, 9, 2, 0, 17, 0, 0,
-  0, 0, 0, 41, 0, 41, 38, 0, 0, 0,
-  0, 0, 61, 6, 0, 16, 12, 19, 25, 54,
-  49, 37, 21, 5, 43, 0, 53, 32, 0, 0,
-  35, 21, 0, 0, 0, 0, 32, 0, 3, 0,
-  0, 0, 0, 35, 0, 0, 0, 27, 0, 26,
-  0, 0, 0, 15, 28, 3, 38, 9, 0, 0,
-  27, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  56, 0, 5, 0, 0, 0, 1, 44, 11, 11,
-  0, 62, 0, 23, 13, 12, 56, 44, 1, 24,
-  0, 29, 27, 31, 52, 10, 0, 0, 12, 0,
-  0, 0, 11, 51, 42, 0, 0, 0, 0, 0,
-  41, 0, 0, 48, 5, 0, 0, 10, 0, 0,
-  7, 0, 0, 0, 0, 0, 47, 0, 21, 0,
-  1, 20, 52, 0, 43, 0, 22, 0, 0, 0,
-  29, 0, 0, 0, 38, 88, 0, 0, 38, 0,
-  13, 0, 33, 104, 68, 26, 0, 0, 8, 50,
-  0, 0, 0, 10, 0, 4, 0, 0, 0, 20,
-  0, 11, 1, 0, 0, 0, 0, 16, 0, 0,
-  0, 7, 0, 77, 0, 0, 52, 0, 26, 23,
-  6, 0, 25, 0, 0, 6, 24, 0, 92, 16,
-  18, 73, 0, 0, 0, 73, 0, 0, 0, 50,
-  0, 0, 0, 0, 11, 59, 10, 49, 0, 55,
-  10, 0, 0, 37, 0, 0, 5, 0, 13, 0,
-  23, 61, 29, 7, 1, 0, 19, 2, 0, 26,
-  0, 53, 0, 7, 0, 0, 0, 23, 69, 0,
-  1, 0, 0, 31, 0, 0, 4, 0, 0, 61,
-  44, 0, 0, 0, 25, 73, 0, 0, 7, 0,
-  0, 0, 26, 81, 0, 0, 48, 0, 0, 0,
-  40, 70, 0, 48, 0, 0, 0, 16, 0, 0,
-  0, 0, 0, 39, 0, 0, 0, 36, 0, 27,
-  0, 6, 0, 0, 20, 1, 0, 24, 22, 0,
-  0, 39, 0, 0, 0, 0, 10, 25, 0, 0,
-  31, 12, 0, 4, 0, 0, 87, 23, 22, 30,
-  0, 6, 0, 43, 7, 0, 0, 5, 0, 16,
-  0, 0, 0, 7, 9, 33, 0, 49, 1, 0,
-  0, 56, 0, 0, 0, 0, 0, 0, 17, 64,
-  6, 22, 16, 0, 10, 13, 0, 13, 8, 65,
-  0, 0, 0, 0, 0, 16, 82, 0, 8, 0,
-  12, 7, 0, 0, 0, 7, 4, 20, 0, 65,
-  0, 0, 34, 0, 36, 0, 61, 12, 0, 5,
-  44, 54, 61, 74, 64, 45, 0, 12, 72, 0,
-  0, 33, 31, 57, 17, 27, 0, 12, 0, 0,
-  29, 8, 17, 0, 0, 37, 0, 58, 0, 3,
-  0, 54, 0, 29, 24, 4, 0, 0, 35, 0,
-  43, 56, 0, 0, 7, 0, 0, 32, 0, 0,
-  0, 0, 0, 0, 70, 9, 41, 0, 0, 0,
-  0, 18, 51, 0, 0, 21, 0, 27, 40, 52,
-  13, 20, 40, 15, 0, 9, 25, 57, 3, 0,
-  0, 59, 0, 27, 0, 5, 69, 44, 0, 0,
-  0, 0, 2, 0, 12, 20, 36, 60, 0, 0,
-  0, 21, 0, 0, 0, 18, 24, 0, 0, 1,
-  134, 0, 38, 0, 44, 0, 0, 26, 42, 0,
-  40, 0, 0, 0, 68, 7, 0, 5, 43, 69,
-  21, 36, 59, 16, 3, 0, 30, 7, 16, 33,
-  0, 0, 32, 69, 0, 5, 0, 0, 0, 0,
-  0, 0, 0, 55, 0, 45, 0, 4, 0, 0,
-  0, 8, 12, 0, 0, 16, 23, 16, 0, 8,
-  0, 0, 24, 20, 0, 0, 0, 0, 0, 0,
-  0, 0, 70, 10, 16, 0, 0, 0, 0, 27,
-  24, 0, 0, 57, 0, 13, 0, 13, 15, 76,
-  12, 31, 0, 45, 9, 26, 24, 0, 0, 11,
-  0, 0, 0, 0, 52, 56, 16, 0, 0, 0,
-  1, 0, 7, 24, 39, 91, 4, 0, 0, 0,
-  0, 0, 11, 0, 10, 0, 0, 35, 51, 0,
-  0, 0, 24, 66, 70, 0, 17, 0, 20, 30,
-  0, 0, 12, 0, 0, 0, 2, 79, 18, 0,
-  26, 23, 6, 5, 29, 52, 17, 15, 0, 0,
-  8, 29, 0, 0, 0, 9, 0, 47, 0, 0,
-  7, 43, 0, 12, 0, 10, 0, 0, 5, 0,
-  16, 5, 10, 0, 24, 4, 0, 0, 15, 0,
-  23, 37, 5, 0, 30, 16, 31, 0, 0, 12,
-  69, 32, 32, 66, 0, 18, 10, 0, 25, 0,
-  0, 55, 11, 6, 0, 12, 0, 37, 48, 12,
-  31, 65, 0, 0, 0, 0, 0, 0, 29, 0,
-  0, 17, 57, 30, 0, 27, 0, 0, 0, 60,
-  0, 14, 29, 64, 0, 0, 0, 1, 7, 52,
-  58, 0, 0, 0, 0, 32, 0, 0, 0, 19,
-  23, 49, 0, 44, 27, 0, 33, 0, 0, 0,
-  76, 0, 0, 1, 67, 69, 11, 51, 63, 32,
-  6, 0, 66, 0, 0, 38, 0, 0, 28, 40,
-  0, 0, 0, 0, 7, 0, 0, 0, 0, 27,
-  0, 47, 0, 0, 0, 20, 0, 38, 0, 0,
-  0, 16, 0, 34, 21, 7, 0, 0, 0, 8,
-  0, 0, 0, 0, 0, 0, 0, 0, 98, 0,
-  25, 5, 0, 0, 0, 78, 9, 0, 0, 35,
-  0, 0, 12, 5, 38, 41, 20, 53, 0, 44,
-  32, 14, 27, 37, 0, 13, 0, 0, 0, 0,
-  28, 63, 38, 0, 0, 0, 0, 0, 3, 36,
-  0, 61, 0, 0, 0, 5, 3, 0, 4, 0,
-  0, 0, 0, 0, 77, 0, 26, 0, 18, 21,
-  29, 0, 57, 0, 12, 30, 0, 0, 52, 0,
-  0, 2, 43, 101, 14, 0, 40, 0, 0, 0,
-  32, 66, 0, 35, 0, 0, 0, 29, 0, 8,
-  0, 0, 0, 11, 0, 0, 0, 50, 0, 48,
-  0, 31, 0, 0, 0, 0, 0, 0, 6, 9,
-  0, 67, 0, 0, 11, 0, 13, 40, 0, 0,
-  5, 7, 0, 44, 0, 15, 58, 0, 30, 45,
-  0, 14, 0, 32, 0, 0, 0, 10, 0, 27,
-  0, 3, 29, 32, 45, 49, 0, 64, 21, 0,
-  0, 14, 0, 0, 0, 0, 0, 0, 30, 78,
-  0, 0, 0, 0, 0, 18, 0, 23, 14, 57,
-  17, 0, 0, 0, 29, 0, 59, 1, 9, 2,
-  0, 17, 0, 0, 0, 0, 0, 41, 0, 0,
-  0, 0, 31, 51, 0, 0, 37, 2, 0, 0,
-  4, 70, 43, 0, 24, 35, 0, 14, 56, 0,
-  0, 39, 0, 0, 9, 13, 0, 36, 0, 0,
-  0, 14, 0, 0, 0, 19, 0, 41, 0, 0,
-  0, 5, 3, 0, 4, 0, 0, 0, 23, 13,
-  20, 0, 0, 0, 18, 34, 0, 0, 4, 17,
-  0, 0, 0, 0, 21, 0, 0, 0, 0, 23,
-  10, 1, 39, 9, 0, 0, 1, 25, 3, 20,
-  0, 8, 17, 5, 38, 41, 32, 19, 10, 0,
-  6, 0, 0, 0, 0, 5, 45, 39, 4, 0,
-  0, 0, 0, 31, 0, 9, 12, 73, 0, 0,
-  0, 0, 2, 0, 65, 11, 0, 5, 37, 0,
-  20, 0, 0, 11, 0, 8, 52, 0, 43, 0,
-  22, 0, 0, 0, 29, 0, 0, 0, 38, 88,
-  0, 0, 38, 0, 13, 0, 33, 104, 68, 26,
-  0, 0, 8, 50, 0, 0, 0, 10, 0, 4,
-  0, 0, 0, 20, 0, 11, 1, 0, 0, 0,
-  0, 16, 0, 0, 0, 7, 0, 77, 0, 0,
-  52, 0, 26, 23, 6, 0, 25, 0, 0, 6,
-  24, 0, 92, 16, 18, 73, 0, 0, 0, 73,
-  0, 0, 0, 50, 0, 0, 0, 0, 11, 59,
-  10, 49, 0, 55, 10, 0, 0, 37, 0, 0,
-  5, 0, 13, 0, 23, 61, 29, 7, 1, 0,
-  19, 2, 0, 26, 0, 53, 0, 7, 0, 0,
-  0, 23, 69, 0, 1, 0, 0, 31, 0, 0,
-  4, 0, 0, 61, 44, 0, 0, 0, 25, 73,
-  0, 0, 7, 0, 0, 0, 26, 81, 0, 0,
-  48, 0, 0, 0, 40, 70, 0, 48, 0, 0,
-  0, 16, 0, 0, 0, 0, 0, 39, 0, 0,
-  0, 36, 0, 27, 0, 6, 0, 0, 20, 1,
-  0, 24, 22, 0, 0, 39, 0, 0, 0, 0,
-  10, 25, 0, 0, 31, 12, 0, 4, 0, 0,
-  87, 23, 22, 30, 0, 6, 0, 43, 7, 0,
-  0, 5, 0, 16, 0, 0, 0, 7, 9, 33,
-  0, 49, 1, 0, 0, 56, 0, 0, 0, 0,
-  0, 0, 17, 64, 6, 22, 16, 0, 10, 13,
-  0, 13, 8, 65, 0, 0, 0, 0, 0, 16,
-  82, 0, 8, 0, 12, 7, 0, 0, 0, 7,
-  4, 20, 0, 17, 0, 0, 21, 28, 30, 14,
-  58, 16, 0, 5, 32, 30, 51, 35, 42, 53,
-  0, 21, 81, 0, 0, 49, 7, 50, 21, 0,
-  0, 19, 0, 0, 2, 16, 18, 0, 0, 7,
-  0, 43, 0, 40, 0, 33, 27, 19, 0, 12,
-  0, 0, 23, 0, 84, 2, 0, 0, 0, 0,
-  0, 29, 0, 0, 0, 0, 0, 0, 33, 0,
-  0, 0, 0, 25, 18, 30, 44, 27, 0, 0,
-  0, 44, 47, 23, 14, 0, 26, 7, 56, 14,
-  51, 35, 8, 27, 0, 39, 0, 19, 0, 4,
-  43, 43, 0, 0, 0, 0, 0, 0, 8, 13,
-  9, 61, 0, 0, 0, 0, 12, 0, 28, 21,
-  21, 0, 50, 0, 111, 0, 14, 14, 3, 0,
-  0, 26, 42, 0, 40, 0, 0, 0, 68, 7,
-  0, 5, 43, 69, 21, 36, 59, 16, 3, 0,
-  30, 7, 16, 33, 0, 0, 32, 69, 0, 5,
-  0, 0, 0, 0, 0, 0, 0, 55, 0, 45,
-  0, 4, 0, 0, 0, 8, 12, 0, 0, 16,
-  23, 16, 0, 8, 0, 0, 24, 20, 0, 0,
-  0, 0, 0, 0, 0, 0, 70, 10, 16, 0,
-  0, 0, 0, 27, 24, 0, 0, 57, 0, 13,
-  0, 13, 15, 76, 12, 31, 0, 45, 9, 26,
-  24, 0, 0, 11, 0, 0, 0, 0, 52, 56,
-  16, 0, 0, 0, 1, 0, 7, 24, 39, 91,
-  4, 0, 0, 0, 0, 0, 11, 0, 10, 0,
-  0, 35, 51, 0, 0, 0, 24, 66, 70, 0,
-  17, 0, 20, 30, 0, 0, 12, 0, 0, 0,
-  2, 79, 18, 0, 26, 23, 6, 5, 29, 52,
-  17, 15, 0, 0, 8, 29, 0, 0, 0, 9,
-  0, 47, 0, 0, 7, 43, 0, 12, 0, 10,
-  0, 0, 5, 0, 16, 5, 10, 0, 24, 4,
-  0, 0, 15, 0, 23, 37, 5, 0, 30, 16,
-  31, 0, 0, 12, 69, 32, 32, 66, 0, 18,
-  10, 0, 25, 0, 0, 55, 11, 6, 0, 12,
-  0, 37, 48, 12, 31, 65, 0, 0, 0, 0,
-  0, 0, 29, 0, 0, 17, 57, 30, 0, 27,
-  0, 0, 0, 60, 0, 14, 29, 64, 0, 0,
-  0, 1, 7, 52, 58, 0, 0, 0, 0, 32,
-  0, 0, 0, 19, 23, 49, 22, 3, 0, 0,
-  24, 14, 0, 0, 31, 13, 0, 23, 0, 61,
-  30, 0, 16, 46, 7, 38, 53, 0, 0, 0,
-  7, 20, 37, 0, 0, 0, 0, 0, 0, 35,
-  0, 0, 9, 0, 0, 0, 0, 3, 0, 3,
-  12, 0, 13, 5, 0, 0, 57, 0, 3, 0,
-  0, 0, 27, 17, 0, 0, 5, 8, 37, 0,
-  0, 0, 19, 60, 0, 39, 0, 33, 30, 0,
-  37, 12, 0, 30, 0, 10, 5, 30, 0, 0,
-  41, 0, 71, 36, 0, 13, 0, 0, 4, 0,
-  18, 0, 0, 16, 44, 2, 0, 26, 0, 0,
-  0, 38, 5, 6, 19, 51, 0, 0, 0, 14,
-  43, 20, 37, 0, 0, 0, 39, 13, 0, 0,
-  0, 39, 17, 0, 29, 0, 57, 0, 12, 30,
-  0, 0, 52, 0, 0, 2, 43, 101, 14, 0,
-  40, 0, 0, 0, 32, 66, 0, 35, 0, 0,
-  0, 29, 0, 8, 0, 0, 0, 11, 0, 0,
-  0, 50, 0, 48, 0, 31, 0, 0, 0, 0,
-  0, 0, 6, 9, 0, 67, 0, 0, 11, 0,
-  13, 40, 0, 0, 5, 7, 0, 44, 0, 15,
-  58, 0, 30, 45, 0, 14, 0, 32, 0, 0,
-  0, 10, 0, 27, 0, 3, 29, 32, 45, 49,
-  0, 64, 21, 0, 0, 14, 0, 0, 0, 0,
-  0, 0, 30, 78, 0, 0, 0, 0, 0, 18,
-  0, 23, 14, 57, 17, 0, 0, 0, 29, 0,
-  59, 1, 9, 2, 0, 17, 0, 0, 0, 0,
-  0, 41, 0, 0, 0, 0, 31, 51, 0, 0,
-  37, 2, 0, 0, 4, 70, 43, 0, 24, 35,
-  0, 14, 56, 0, 0, 39, 0, 0, 9, 13,
-  0, 36, 0, 0, 0, 14, 0, 0, 0, 19,
-  0, 41, 0, 0, 0, 5, 3, 0, 4, 0,
-  0, 0, 23, 13, 20, 0, 0, 0, 18, 34,
-  0, 0, 4, 17, 0, 0, 0, 0, 21, 0,
-  0, 0, 0, 23, 10, 1, 39, 9, 0, 0,
-  1, 25, 3, 20, 0, 8, 17, 5, 38, 41,
-  32, 19, 10, 0, 6, 0, 0, 0, 0, 5,
-  45, 39, 4, 0, 0, 0, 0, 31, 0, 9,
-  12, 73, 0, 0, 0, 0, 2, 0, 65, 11,
-  0, 5, 37, 0, 20, 0, 0, 11, 0, 8,
-  0, 32, 0, 0, 31, 0, 19, 0, 50, 0,
-  0, 16, 7, 64, 58, 24, 16, 46, 0, 28,
-  76, 0, 0, 47, 16, 40, 25, 0, 0, 27,
-  0, 0, 0, 37, 5, 0, 0, 0, 0, 29,
-  0, 1, 0, 41, 21, 3, 4, 6, 0, 0,
-  60, 0, 56, 11, 0, 0, 8, 6, 0, 26,
-  13, 0, 0, 0, 0, 0, 17, 6, 0, 0,
-  0, 25, 0, 0, 41, 13, 0, 0, 0, 30,
-  48, 39, 12, 0, 31, 0, 58, 23, 37, 56,
-  3, 0, 8, 19, 0, 16, 0, 10, 57, 33,
-  0, 0, 0, 0, 0, 0, 23, 0, 31, 59,
-  0, 0, 0, 1, 24, 0, 21, 0, 8, 0,
-  47, 0, 77, 0, 1, 23, 9, 0, 44, 0,
-  0, 0, 25, 73, 0, 0, 7, 0, 0, 0,
-  26, 81, 0, 0, 48, 0, 0, 0, 40, 70,
-  0, 48, 0, 0, 0, 16, 0, 0, 0, 0,
-  0, 39, 0, 0, 0, 36, 0, 27, 0, 6,
-  0, 0, 20, 1, 0, 24, 22, 0, 0, 39,
-  0, 0, 0, 0, 10, 25, 0, 0, 31, 12,
-  0, 4, 0, 0, 87, 23, 22, 30, 0, 6,
-  0, 43, 7, 0, 0, 5, 0, 16, 0, 0,
-  0, 7, 9, 33, 0, 49, 1, 0, 0, 56,
-  0, 0, 0, 0, 0, 0, 17, 64, 6, 22,
-  16, 0, 10, 13, 0, 13, 8, 65, 0, 0,
-  0, 0, 0, 16, 82, 0, 8, 0, 12, 7,
-  0, 0, 0, 7, 4, 20, 0, 17, 0, 0,
-  21, 28, 30, 14, 58, 16, 0, 5, 32, 30,
-  51, 35, 42, 53, 0, 21, 81, 0, 0, 49,
-  7, 50, 21, 0, 0, 19, 0, 0, 2, 16,
-  18, 0, 0, 7, 0, 43, 0, 40, 0, 33,
-  27, 19, 0, 12, 0, 0, 23, 0, 84, 2,
-  0, 0, 0, 0, 0, 29, 0, 0, 0, 0,
-  0, 0, 33, 0, 0, 0, 0, 25, 18, 30,
-  44, 27, 0, 0, 0, 44, 47, 23, 14, 0,
-  26, 7, 56, 14, 51, 35, 8, 27, 0, 39,
-  0, 19, 0, 4, 43, 43, 0, 0, 0, 0,
-  0, 0, 8, 13, 9, 61, 0, 0, 0, 0,
-  12, 0, 28, 21, 21, 0, 50, 0, 111, 0,
-  14, 14, 3, 0, 0, 47, 23, 0, 8, 0,
-  33, 0, 55, 0, 0, 17, 28, 56, 45, 66,
-  49, 49, 0, 15, 78, 0, 0, 46, 13, 29,
-  27, 0, 0, 0, 14, 0, 11, 19, 4, 0,
-  0, 0, 0, 33, 12, 13, 0, 55, 6, 0,
-  0, 0, 0, 0, 63, 12, 64, 29, 0, 0,
-  0, 0, 0, 23, 0, 0, 0, 0, 0, 0,
-  42, 0, 0, 0, 0, 0, 0, 41, 36, 0,
-  0, 29, 0, 27, 65, 51, 36, 6, 50, 11,
-  55, 0, 58, 33, 0, 14, 0, 30, 0, 20,
-  0, 12, 43, 51, 0, 0, 0, 0, 0, 0,
-  5, 6, 14, 33, 30, 0, 0, 0, 41, 0,
-  0, 0, 5, 0, 0, 0, 81, 0, 6, 22,
-  17, 0, 70, 0, 17, 0, 20, 30, 0, 0,
-  12, 0, 0, 0, 2, 79, 18, 0, 26, 23,
-  6, 5, 29, 52, 17, 15, 0, 0, 8, 29,
-  0, 0, 0, 9, 0, 47, 0, 0, 7, 43,
-  0, 12, 0, 10, 0, 0, 5, 0, 16, 5,
-  10, 0, 24, 4, 0, 0, 15, 0, 23, 37,
-  5, 0, 30, 16, 31, 0, 0, 12, 69, 32,
-  32, 66, 0, 18, 10, 0, 25, 0, 0, 55,
-  11, 6, 0, 12, 0, 37, 48, 12, 31, 65,
-  0, 0, 0, 0, 0, 0, 29, 0, 0, 17,
-  57, 30, 0, 27, 0, 0, 0, 60, 0, 14,
-  29, 64, 0, 0, 0, 1, 7, 52, 58, 0,
-  0, 0, 0, 32, 0, 0, 0, 19, 23, 49,
-  22, 3, 0, 0, 24, 14, 0, 0, 31, 13,
-  0, 23, 0, 61, 30, 0, 16, 46, 7, 38,
-  53, 0, 0, 0, 7, 20, 37, 0, 0, 0,
-  0, 0, 0, 35, 0, 0, 9, 0, 0, 0,
-  0, 3, 0, 3, 12, 0, 13, 5, 0, 0,
-  57, 0, 3, 0, 0, 0, 27, 17, 0, 0,
-  5, 8, 37, 0, 0, 0, 19, 60, 0, 39,
-  0, 33, 30, 0, 37, 12, 0, 30, 0, 10,
-  5, 30, 0, 0, 41, 0, 71, 36, 0, 13,
-  0, 0, 4, 0, 18, 0, 0, 16, 44, 2,
-  0, 26, 0, 0, 0, 38, 5, 6, 19, 51,
-  0, 0, 0, 14, 43, 20, 37, 0, 0, 0,
-  39, 13, 0, 0, 0, 39, 17, 0, 19, 51,
-  0, 11, 63, 0, 36, 0, 33, 2, 0, 24,
-  2, 46, 28, 0, 6, 25, 11, 52, 60, 0,
-  0, 15, 21, 37, 39, 0, 0, 21, 42, 0,
-  0, 33, 0, 0, 0, 0, 0, 0, 0, 29,
-  0, 51, 23, 0, 7, 28, 0, 0, 51, 0,
-  37, 15, 0, 12, 5, 0, 0, 22, 16, 2,
-  15, 0, 0, 0, 4, 57, 0, 0, 0, 41,
-  5, 0, 60, 0, 19, 1, 4, 1, 52, 31,
-  4, 0, 58, 0, 51, 26, 21, 39, 0, 0,
-  0, 32, 0, 23, 0, 0, 55, 8, 0, 36,
-  1, 0, 0, 0, 14, 29, 63, 36, 0, 0,
-  0, 0, 46, 0, 12, 0, 4, 0, 35, 1,
-  40, 0, 0, 33, 0, 0, 0, 0, 0, 0,
-  31, 51, 0, 0, 37, 2, 0, 0, 4, 70,
-  43, 0, 24, 35, 0, 14, 56, 0, 0, 39,
-  0, 0, 9, 13, 0, 36, 0, 0, 0, 14,
-  0, 0, 0, 19, 0, 41, 0, 0, 0, 5,
-  3, 0, 4, 0, 0, 0, 23, 13, 20, 0,
-  0, 0, 18, 34, 0, 0, 4, 17, 0, 0,
-  0, 0, 21, 0, 0, 0, 0, 23, 10, 1,
-  39, 9, 0, 0, 1, 25, 3, 20, 0, 8,
-  17, 5, 38, 41, 32, 19, 10, 0, 6, 0,
-  0, 0, 0, 5, 45, 39, 4, 0, 0, 0,
-  0, 31, 0, 9, 12, 73, 0, 0, 0, 0,
-  2, 0, 65, 11, 0, 5, 37, 0, 20, 0,
-  0, 11, 0, 8, 0, 32, 0, 0, 31, 0,
-  19, 0, 50, 0, 0, 16, 7, 64, 58, 24,
-  16, 46, 0, 28, 76, 0, 0, 47, 16, 40,
-  25, 0, 0, 27, 0, 0, 0, 37, 5, 0,
-  0, 0, 0, 29, 0, 1, 0, 41, 21, 3,
-  4, 6, 0, 0, 60, 0, 56, 11, 0, 0,
-  8, 6, 0, 26, 13, 0, 0, 0, 0, 0,
-  17, 6, 0, 0, 0, 25, 0, 0, 41, 13,
-  0, 0, 0, 30, 48, 39, 12, 0, 31, 0,
-  58, 23, 37, 56, 3, 0, 8, 19, 0, 16,
-  0, 10, 57, 33, 0, 0, 0, 0, 0, 0,
-  23, 0, 31, 59, 0, 0, 0, 1, 24, 0,
-  21, 0, 8, 0, 47, 0, 77, 0, 1, 23,
-  9, 0, 0, 86, 6, 8, 42, 0, 32, 0,
-  64, 4, 0, 0, 6, 42, 74, 53, 38, 43,
-  0, 27, 68, 0, 0, 42, 0, 47, 25, 9,
-  0, 24, 6, 0, 0, 29, 9, 0, 0, 0,
-  0, 25, 0, 26, 0, 59, 9, 0, 0, 24,
-  0, 0, 45, 0, 88, 34, 0, 0, 0, 0,
-  0, 9, 6, 0, 0, 0, 0, 0, 36, 0,
-  0, 0, 0, 0, 0, 17, 64, 0, 2, 0,
-  1, 0, 91, 28, 8, 0, 51, 13, 35, 13,
-  47, 25, 0, 0, 0, 32, 0, 22, 0, 0,
-  48, 22, 0, 7, 0, 0, 23, 0, 25, 21,
-  43, 64, 10, 0, 0, 0, 29, 0, 0, 0,
-  18, 0, 4, 0, 74, 0, 0, 37, 25, 0,
-  0, 17, 0, 0, 21, 28, 30, 14, 58, 16,
-  0, 5, 32, 30, 51, 35, 42, 53, 0, 21,
-  81, 0, 0, 49, 7, 50, 21, 0, 0, 19,
-  0, 0, 2, 16, 18, 0, 0, 7, 0, 43,
-  0, 40, 0, 33, 27, 19, 0, 12, 0, 0,
-  23, 0, 84, 2, 0, 0, 0, 0, 0, 29,
-  0, 0, 0, 0, 0, 0, 33, 0, 0, 0,
-  0, 25, 18, 30, 44, 27, 0, 0, 0, 44,
-  47, 23, 14, 0, 26, 7, 56, 14, 51, 35,
-  8, 27, 0, 39, 0, 19, 0, 4, 43, 43,
-  0, 0, 0, 0, 0, 0, 8, 13, 9, 61,
-  0, 0, 0, 0, 12, 0, 28, 21, 21, 0,
-  50, 0, 111, 0, 14, 14, 3, 0, 0, 47,
-  23, 0, 8, 0, 33, 0, 55, 0, 0, 17,
-  28, 56, 45, 66, 49, 49, 0, 15, 78, 0,
-  0, 46, 13, 29, 27, 0, 0, 0, 14, 0,
-  11, 19, 4, 0, 0, 0, 0, 33, 12, 13,
-  0, 55, 6, 0, 0, 0, 0, 0, 63, 12,
-  64, 29, 0, 0, 0, 0, 0, 23, 0, 0,
-  0, 0, 0, 0, 42, 0, 0, 0, 0, 0,
-  0, 41, 36, 0, 0, 29, 0, 27, 65, 51,
-  36, 6, 50, 11, 55, 0, 58, 33, 0, 14,
-  0, 30, 0, 20, 0, 12, 43, 51, 0, 0,
-  0, 0, 0, 0, 5, 6, 14, 33, 30, 0,
-  0, 0, 41, 0, 0, 0, 5, 0, 0, 0,
-  81, 0, 6, 22, 17, 0, 0, 43, 70, 0,
-  11, 0, 9, 0, 57, 6, 0, 0, 0, 60,
-  23, 63, 30, 38, 0, 12, 39, 0, 33, 35,
-  0, 0, 9, 14, 0, 0, 27, 0, 0, 0,
-  0, 0, 0, 17, 0, 12, 27, 0, 0, 40,
-  0, 0, 0, 0, 0, 0, 48, 52, 41, 12,
-  0, 0, 19, 12, 0, 0, 0, 0, 0, 0,
-  24, 0, 45, 0, 11, 4, 0, 0, 0, 28,
-  32, 0, 0, 18, 0, 0, 58, 19, 0, 21,
-  59, 13, 23, 9, 64, 10, 0, 32, 0, 0,
-  0, 0, 0, 0, 40, 51, 0, 0, 0, 0,
-  36, 0, 0, 22, 4, 24, 40, 0, 0, 0,
-  86, 0, 2, 0, 26, 0, 0, 1, 21, 0,
-  0, 24, 22, 0, 22, 3, 0, 0, 24, 14,
-  0, 0, 31, 13, 0, 23, 0, 61, 30, 0,
-  16, 46, 7, 38, 53, 0, 0, 0, 7, 20,
-  37, 0, 0, 0, 0, 0, 0, 35, 0, 0,
-  9, 0, 0, 0, 0, 3, 0, 3, 12, 0,
-  13, 5, 0, 0, 57, 0, 3, 0, 0, 0,
-  27, 17, 0, 0, 5, 8, 37, 0, 0, 0,
-  19, 60, 0, 39, 0, 33, 30, 0, 37, 12,
-  0, 30, 0, 10, 5, 30, 0, 0, 41, 0,
-  71, 36, 0, 13, 0, 0, 4, 0, 18, 0,
-  0, 16, 44, 2, 0, 26, 0, 0, 0, 38,
-  5, 6, 19, 51, 0, 0, 0, 14, 43, 20,
-  37, 0, 0, 0, 39, 13, 0, 0, 0, 39,
-  17, 0, 19, 51, 0, 11, 63, 0, 36, 0,
-  33, 2, 0, 24, 2, 46, 28, 0, 6, 25,
-  11, 52, 60, 0, 0, 15, 21, 37, 39, 0,
-  0, 21, 42, 0, 0, 33, 0, 0, 0, 0,
-  0, 0, 0, 29, 0, 51, 23, 0, 7, 28,
-  0, 0, 51, 0, 37, 15, 0, 12, 5, 0,
-  0, 22, 16, 2, 15, 0, 0, 0, 4, 57,
-  0, 0, 0, 41, 5, 0, 60, 0, 19, 1,
-  4, 1, 52, 31, 4, 0, 58, 0, 51, 26,
-  21, 39, 0, 0, 0, 32, 0, 23, 0, 0,
-  55, 8, 0, 36, 1, 0, 0, 0, 14, 29,
-  63, 36, 0, 0, 0, 0, 46, 0, 12, 0,
-  4, 0, 35, 1, 40, 0, 0, 33, 0, 0,
-  0, 99, 0, 38, 55, 0, 74, 0, 47, 0,
-  0, 55, 43, 30, 27, 0, 3, 36, 0, 59,
-  80, 0, 0, 26, 36, 49, 32, 1, 0, 12,
-  51, 0, 22, 17, 3, 0, 0, 0, 0, 0,
-  0, 20, 0, 83, 20, 23, 0, 15, 0, 0,
-  26, 0, 67, 45, 0, 11, 23, 0, 0, 37,
-  22, 0, 0, 0, 0, 0, 14, 67, 0, 0,
-  0, 11, 0, 0, 67, 0, 16, 0, 7, 0,
-  80, 54, 0, 0, 42, 0, 37, 1, 24, 67,
-  6, 0, 0, 40, 0, 45, 0, 0, 77, 8,
-  0, 34, 3, 0, 0, 0, 25, 58, 103, 36,
-  0, 0, 0, 0, 32, 0, 0, 0, 0, 0,
-  21, 22, 80, 0, 38, 25, 8, 0, 0, 32,
-  0, 0, 31, 0, 19, 0, 50, 0, 0, 16,
-  7, 64, 58, 24, 16, 46, 0, 28, 76, 0,
-  0, 47, 16, 40, 25, 0, 0, 27, 0, 0,
-  0, 37, 5, 0, 0, 0, 0, 29, 0, 1,
-  0, 41, 21, 3, 4, 6, 0, 0, 60, 0,
-  56, 11, 0, 0, 8, 6, 0, 26, 13, 0,
-  0, 0, 0, 0, 17, 6, 0, 0, 0, 25,
-  0, 0, 41, 13, 0, 0, 0, 30, 48, 39,
-  12, 0, 31, 0, 58, 23, 37, 56, 3, 0,
-  8, 19, 0, 16, 0, 10, 57, 33, 0, 0,
-  0, 0, 0, 0, 23, 0, 31, 59, 0, 0,
-  0, 1, 24, 0, 21, 0, 8, 0, 47, 0,
-  77, 0, 1, 23, 9, 0, 0, 86, 6, 8,
-  42, 0, 32, 0, 64, 4, 0, 0, 6, 42,
-  74, 53, 38, 43, 0, 27, 68, 0, 0, 42,
-  0, 47, 25, 9, 0, 24, 6, 0, 0, 29,
-  9, 0, 0, 0, 0, 25, 0, 26, 0, 59,
-  9, 0, 0, 24, 0, 0, 45, 0, 88, 34,
-  0, 0, 0, 0, 0, 9, 6, 0, 0, 0,
-  0, 0, 36, 0, 0, 0, 0, 0, 0, 17,
-  64, 0, 2, 0, 1, 0, 91, 28, 8, 0,
-  51, 13, 35, 13, 47, 25, 0, 0, 0, 32,
-  0, 22, 0, 0, 48, 22, 0, 7, 0, 0,
-  23, 0, 25, 21, 43, 64, 10, 0, 0, 0,
-  29, 0, 0, 0, 18, 0, 4, 0, 74, 0,
-  0, 37, 25, 0, 0, 96, 8, 3, 33, 0,
-  35, 0, 85, 3, 0, 27, 4, 58, 40, 66,
-  33, 44, 0, 33, 67, 0, 11, 33, 0, 10,
-  35, 17, 0, 0, 0, 0, 16, 0, 0, 0,
-  0, 12, 0, 0, 0, 9, 0, 67, 0, 25,
-  0, 38, 0, 0, 28, 0, 77, 30, 0, 0,
-  25, 0, 0, 0, 0, 0, 0, 0, 2, 0,
-  21, 0, 17, 0, 0, 0, 18, 29, 78, 0,
-  11, 0, 0, 0, 78, 36, 3, 0, 35, 3,
-  44, 7, 36, 20, 0, 27, 0, 26, 0, 8,
-  0, 0, 61, 33, 8, 16, 0, 0, 58, 0,
-  22, 29, 12, 37, 7, 0, 0, 0, 41, 0,
-  0, 0, 20, 0, 0, 0, 52, 0, 0, 31,
-  46, 0, 0, 47, 23, 0, 8, 0, 33, 0,
-  55, 0, 0, 17, 28, 56, 45, 66, 49, 49,
-  0, 15, 78, 0, 0, 46, 13, 29, 27, 0,
-  0, 0, 14, 0, 11, 19, 4, 0, 0, 0,
-  0, 33, 12, 13, 0, 55, 6, 0, 0, 0,
-  0, 0, 63, 12, 64, 29, 0, 0, 0, 0,
-  0, 23, 0, 0, 0, 0, 0, 0, 42, 0,
-  0, 0, 0, 0, 0, 41, 36, 0, 0, 29,
-  0, 27, 65, 51, 36, 6, 50, 11, 55, 0,
-  58, 33, 0, 14, 0, 30, 0, 20, 0, 12,
-  43, 51, 0, 0, 0, 0, 0, 0, 5, 6,
-  14, 33, 30, 0, 0, 0, 41, 0, 0, 0,
-  5, 0, 0, 0, 81, 0, 6, 22, 17, 0,
-  0, 43, 70, 0, 11, 0, 9, 0, 57, 6,
-  0, 0, 0, 60, 23, 63, 30, 38, 0, 12,
-  39, 0, 33, 35, 0, 0, 9, 14, 0, 0,
-  27, 0, 0, 0, 0, 0, 0, 17, 0, 12,
-  27, 0, 0, 40, 0, 0, 0, 0, 0, 0,
-  48, 52, 41, 12, 0, 0, 19, 12, 0, 0,
-  0, 0, 0, 0, 24, 0, 45, 0, 11, 4,
-  0, 0, 0, 28, 32, 0, 0, 18, 0, 0,
-  58, 19, 0, 21, 59, 13, 23, 9, 64, 10,
-  0, 32, 0, 0, 0, 0, 0, 0, 40, 51,
-  0, 0, 0, 0, 36, 0, 0, 22, 4, 24,
-  40, 0, 0, 0, 86, 0, 2, 0, 26, 0,
-  0, 1, 21, 0, 0, 24, 22, 0, 0, 1,
-  54, 0, 0, 0, 0, 0, 42, 0, 0, 7,
-  0, 86, 0, 0, 1, 43, 0, 15, 50, 15,
-  93, 16, 0, 0, 0, 18, 0, 0, 16, 0,
-  0, 0, 0, 0, 0, 25, 0, 0, 34, 33,
-  0, 35, 0, 0, 0, 17, 0, 0, 34, 96,
-  0, 0, 21, 0, 40, 0, 14, 0, 0, 2,
-  21, 0, 100, 23, 1, 3, 2, 71, 0, 0,
-  0, 0, 18, 0, 0, 0, 0, 0, 25, 5,
-  0, 25, 63, 0, 32, 16, 62, 0, 0, 28,
-  0, 0, 0, 0, 0, 0, 67, 44, 0, 0,
-  0, 0, 26, 0, 0, 29, 0, 5, 41, 0,
-  0, 0, 99, 0, 45, 0, 46, 0, 0, 13,
-  0, 0, 0, 6, 19, 0, 19, 51, 0, 11,
-  63, 0, 36, 0, 33, 2, 0, 24, 2, 46,
-  28, 0, 6, 25, 11, 52, 60, 0, 0, 15,
-  21, 37, 39, 0, 0, 21, 42, 0, 0, 33,
-  0, 0, 0, 0, 0, 0, 0, 29, 0, 51,
-  23, 0, 7, 28, 0, 0, 51, 0, 37, 15,
-  0, 12, 5, 0, 0, 22, 16, 2, 15, 0,
-  0, 0, 4, 57, 0, 0, 0, 41, 5, 0,
-  60, 0, 19, 1, 4, 1, 52, 31, 4, 0,
-  58, 0, 51, 26, 21, 39, 0, 0, 0, 32,
-  0, 23, 0, 0, 55, 8, 0, 36, 1, 0,
-  0, 0, 14, 29, 63, 36, 0, 0, 0, 0,
-  46, 0, 12, 0, 4, 0, 35, 1, 40, 0,
-  0, 33, 0, 0, 0, 99, 0, 38, 55, 0,
-  74, 0, 47, 0, 0, 55, 43, 30, 27, 0,
-  3, 36, 0, 59, 80, 0, 0, 26, 36, 49,
-  32, 1, 0, 12, 51, 0, 22, 17, 3, 0,
-  0, 0, 0, 0, 0, 20, 0, 83, 20, 23,
-  0, 15, 0, 0, 26, 0, 67, 45, 0, 11,
-  23, 0, 0, 37, 22, 0, 0, 0, 0, 0,
-  14, 67, 0, 0, 0, 11, 0, 0, 67, 0,
-  16, 0, 7, 0, 80, 54, 0, 0, 42, 0,
-  37, 1, 24, 67, 6, 0, 0, 40, 0, 45,
-  0, 0, 77, 8, 0, 34, 3, 0, 0, 0,
-  25, 58, 103, 36, 0, 0, 0, 0, 32, 0,
-  0, 0, 0, 0, 21, 22, 80, 0, 38, 25,
-  8, 0, 0, 129, 0, 59, 30, 0, 80, 0,
-  63, 0, 2, 62, 41, 13, 24, 8, 0, 36,
-  0, 50, 73, 0, 0, 34, 40, 69, 39, 5,
-  0, 13, 44, 0, 63, 0, 17, 0, 0, 0,
-  0, 0, 0, 30, 0, 55, 31, 26, 0, 15,
-  0, 0, 34, 0, 63, 66, 0, 6, 53, 0,
-  0, 76, 13, 0, 0, 0, 0, 0, 32, 81,
-  0, 0, 0, 20, 0, 0, 48, 49, 0, 0,
-  0, 0, 65, 72, 1, 0, 21, 0, 34, 0,
-  17, 106, 73, 0, 0, 66, 0, 33, 16, 0,
-  73, 22, 0, 27, 0, 0, 0, 0, 17, 70,
-  123, 31, 8, 0, 18, 0, 19, 0, 0, 0,
-  0, 0, 16, 21, 113, 10, 49, 16, 11, 0,
-  0, 86, 6, 8, 42, 0, 32, 0, 64, 4,
-  0, 0, 6, 42, 74, 53, 38, 43, 0, 27,
-  68, 0, 0, 42, 0, 47, 25, 9, 0, 24,
-  6, 0, 0, 29, 9, 0, 0, 0, 0, 25,
-  0, 26, 0, 59, 9, 0, 0, 24, 0, 0,
-  45, 0, 88, 34, 0, 0, 0, 0, 0, 9,
-  6, 0, 0, 0, 0, 0, 36, 0, 0, 0,
-  0, 0, 0, 17, 64, 0, 2, 0, 1, 0,
-  91, 28, 8, 0, 51, 13, 35, 13, 47, 25,
-  0, 0, 0, 32, 0, 22, 0, 0, 48, 22,
-  0, 7, 0, 0, 23, 0, 25, 21, 43, 64,
-  10, 0, 0, 0, 29, 0, 0, 0, 18, 0,
-  4, 0, 74, 0, 0, 37, 25, 0, 0, 96,
-  8, 3, 33, 0, 35, 0, 85, 3, 0, 27,
-  4, 58, 40, 66, 33, 44, 0, 33, 67, 0,
-  11, 33, 0, 10, 35, 17, 0, 0, 0, 0,
-  16, 0, 0, 0, 0, 12, 0, 0, 0, 9,
-  0, 67, 0, 25, 0, 38, 0, 0, 28, 0,
-  77, 30, 0, 0, 25, 0, 0, 0, 0, 0,
-  0, 0, 2, 0, 21, 0, 17, 0, 0, 0,
-  18, 29, 78, 0, 11, 0, 0, 0, 78, 36,
-  3, 0, 35, 3, 44, 7, 36, 20, 0, 27,
-  0, 26, 0, 8, 0, 0, 61, 33, 8, 16,
-  0, 0, 58, 0, 22, 29, 12, 37, 7, 0,
-  0, 0, 41, 0, 0, 0, 20, 0, 0, 0,
-  52, 0, 0, 31, 46, 0, 0, 50, 11, 21,
-  17, 0, 0, 0, 67, 0, 0, 42, 4, 106,
-  9, 17, 15, 45, 0, 24, 71, 0, 40, 19,
-  0, 0, 0, 3, 0, 0, 0, 0, 0, 10,
-  0, 0, 0, 0, 0, 0, 4, 19, 0, 50,
-  0, 0, 0, 45, 0, 0, 34, 65, 36, 45,
-  0, 0, 44, 0, 0, 0, 0, 0, 7, 0,
-  60, 7, 0, 7, 12, 15, 0, 0, 10, 2,
-  40, 0, 0, 0, 0, 1, 42, 35, 2, 0,
-  21, 0, 58, 15, 51, 12, 0, 30, 0, 0,
-  0, 9, 0, 0, 58, 45, 6, 2, 0, 0,
-  16, 0, 0, 13, 0, 3, 7, 0, 0, 0,
-  80, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 4, 12, 0, 0, 43, 70, 0, 11, 0,
-  9, 0, 57, 6, 0, 0, 0, 60, 23, 63,
-  30, 38, 0, 12, 39, 0, 33, 35, 0, 0,
-  9, 14, 0, 0, 27, 0, 0, 0, 0, 0,
-  0, 17, 0, 12, 27, 0, 0, 40, 0, 0,
-  0, 0, 0, 0, 48, 52, 41, 12, 0, 0,
-  19, 12, 0, 0, 0, 0, 0, 0, 24, 0,
-  45, 0, 11, 4, 0, 0, 0, 28, 32, 0,
-  0, 18, 0, 0, 58, 19, 0, 21, 59, 13,
-  23, 9, 64, 10, 0, 32, 0, 0, 0, 0,
-  0, 0, 40, 51, 0, 0, 0, 0, 36, 0,
-  0, 22, 4, 24, 40, 0, 0, 0, 86, 0,
-  2, 0, 26, 0, 0, 1, 21, 0, 0, 24,
-  22, 0, 0, 1, 54, 0, 0, 0, 0, 0,
-  42, 0, 0, 7, 0, 86, 0, 0, 1, 43,
-  0, 15, 50, 15, 93, 16, 0, 0, 0, 18,
-  0, 0, 16, 0, 0, 0, 0, 0, 0, 25,
-  0, 0, 34, 33, 0, 35, 0, 0, 0, 17,
-  0, 0, 34, 96, 0, 0, 21, 0, 40, 0,
-  14, 0, 0, 2, 21, 0, 100, 23, 1, 3,
-  2, 71, 0, 0, 0, 0, 18, 0, 0, 0,
-  0, 0, 25, 5, 0, 25, 63, 0, 32, 16,
-  62, 0, 0, 28, 0, 0, 0, 0, 0, 0,
-  67, 44, 0, 0, 0, 0, 26, 0, 0, 29,
-  0, 5, 41, 0, 0, 0, 99, 0, 45, 0,
-  46, 0, 0, 13, 0, 0, 0, 6, 19, 0,
-  16, 0, 16, 11, 0, 0, 0, 0, 35, 0,
-  0, 25, 4, 106, 0, 0, 0, 36, 2, 10,
-  68, 10, 49, 2, 0, 0, 0, 0, 0, 0,
-  0, 2, 0, 9, 0, 0, 0, 0, 0, 0,
-  5, 41, 0, 45, 0, 0, 0, 31, 0, 0,
-  66, 127, 0, 42, 14, 0, 16, 0, 2, 0,
-  0, 0, 48, 0, 110, 32, 0, 9, 0, 60,
-  0, 11, 0, 0, 22, 0, 0, 0, 0, 41,
-  18, 32, 0, 0, 51, 0, 58, 18, 81, 0,
-  0, 0, 0, 0, 0, 12, 11, 0, 73, 49,
-  0, 0, 0, 0, 6, 0, 0, 8, 11, 0,
-  36, 0, 0, 0, 95, 0, 70, 0, 20, 0,
-  1, 0, 0, 0, 8, 0, 11, 0, 0, 99,
-  0, 38, 55, 0, 74, 0, 47, 0, 0, 55,
-  43, 30, 27, 0, 3, 36, 0, 59, 80, 0,
-  0, 26, 36, 49, 32, 1, 0, 12, 51, 0,
-  22, 17, 3, 0, 0, 0, 0, 0, 0, 20,
-  0, 83, 20, 23, 0, 15, 0, 0, 26, 0,
-  67, 45, 0, 11, 23, 0, 0, 37, 22, 0,
-  0, 0, 0, 0, 14, 67, 0, 0, 0, 11,
-  0, 0, 67, 0, 16, 0, 7, 0, 80, 54,
-  0, 0, 42, 0, 37, 1, 24, 67, 6, 0,
-  0, 40, 0, 45, 0, 0, 77, 8, 0, 34,
-  3, 0, 0, 0, 25, 58, 103, 36, 0, 0,
-  0, 0, 32, 0, 0, 0, 0, 0, 21, 22,
-  80, 0, 38, 25, 8, 0, 0, 129, 0, 59,
-  30, 0, 80, 0, 63, 0, 2, 62, 41, 13,
-  24, 8, 0, 36, 0, 50, 73, 0, 0, 34,
-  40, 69, 39, 5, 0, 13, 44, 0, 63, 0,
-  17, 0, 0, 0, 0, 0, 0, 30, 0, 55,
-  31, 26, 0, 15, 0, 0, 34, 0, 63, 66,
-  0, 6, 53, 0, 0, 76, 13, 0, 0, 0,
-  0, 0, 32, 81, 0, 0, 0, 20, 0, 0,
-  48, 49, 0, 0, 0, 0, 65, 72, 1, 0,
-  21, 0, 34, 0, 17, 106, 73, 0, 0, 66,
-  0, 33, 16, 0, 73, 22, 0, 27, 0, 0,
-  0, 0, 17, 70, 123, 31, 8, 0, 18, 0,
-  19, 0, 0, 0, 0, 0, 16, 21, 113, 10,
-  49, 16, 11, 0, 4, 112, 0, 54, 23, 0,
-  15, 0, 85, 7, 0, 53, 5, 3, 0, 0,
-  0, 18, 0, 13, 49, 0, 0, 31, 10, 11,
-  45, 17, 0, 0, 0, 9, 32, 0, 23, 0,
-  0, 18, 0, 0, 0, 0, 0, 18, 25, 27,
-  0, 0, 0, 0, 33, 14, 7, 64, 44, 38,
-  45, 0, 0, 10, 0, 11, 7, 12, 0, 7,
-  17, 45, 0, 29, 0, 13, 26, 0, 1, 55,
-  0, 8, 5, 0, 20, 44, 16, 23, 0, 0,
-  15, 29, 38, 55, 93, 0, 0, 17, 0, 0,
-  52, 0, 35, 52, 0, 80, 0, 0, 0, 0,
-  0, 84, 112, 0, 31, 0, 15, 3, 1, 0,
-  0, 0, 0, 0, 3, 0, 28, 0, 45, 32,
-  0, 0, 0, 96, 8, 3, 33, 0, 35, 0,
-  85, 3, 0, 27, 4, 58, 40, 66, 33, 44,
-  0, 33, 67, 0, 11, 33, 0, 10, 35, 17,
-  0, 0, 0, 0, 16, 0, 0, 0, 0, 12,
-  0, 0, 0, 9, 0, 67, 0, 25, 0, 38,
-  0, 0, 28, 0, 77, 30, 0, 0, 25, 0,
-  0, 0, 0, 0, 0, 0, 2, 0, 21, 0,
-  17, 0, 0, 0, 18, 29, 78, 0, 11, 0,
-  0, 0, 78, 36, 3, 0, 35, 3, 44, 7,
-  36, 20, 0, 27, 0, 26, 0, 8, 0, 0,
-  61, 33, 8, 16, 0, 0, 58, 0, 22, 29,
-  12, 37, 7, 0, 0, 0, 41, 0, 0, 0,
-  20, 0, 0, 0, 52, 0, 0, 31, 46, 0,
-  0, 50, 11, 21, 17, 0, 0, 0, 67, 0,
-  0, 42, 4, 106, 9, 17, 15, 45, 0, 24,
-  71, 0, 40, 19, 0, 0, 0, 3, 0, 0,
-  0, 0, 0, 10, 0, 0, 0, 0, 0, 0,
-  4, 19, 0, 50, 0, 0, 0, 45, 0, 0,
-  34, 65, 36, 45, 0, 0, 44, 0, 0, 0,
-  0, 0, 7, 0, 60, 7, 0, 7, 12, 15,
-  0, 0, 10, 2, 40, 0, 0, 0, 0, 1,
-  42, 35, 2, 0, 21, 0, 58, 15, 51, 12,
-  0, 30, 0, 0, 0, 9, 0, 0, 58, 45,
-  6, 2, 0, 0, 16, 0, 0, 13, 0, 3,
-  7, 0, 0, 0, 80, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 4, 12, 0, 20, 58,
-  19, 29, 24, 0, 0, 0, 79, 0, 0, 44,
-  19, 100, 0, 0, 0, 11, 0, 4, 57, 0,
-  28, 24, 0, 0, 2, 0, 0, 3, 5, 0,
-  0, 6, 0, 0, 0, 0, 0, 0, 0, 34,
-  0, 24, 0, 0, 6, 41, 0, 0, 50, 104,
-  10, 72, 18, 0, 43, 0, 5, 0, 0, 0,
-  14, 0, 25, 49, 0, 0, 0, 41, 0, 14,
-  1, 0, 14, 2, 0, 0, 0, 33, 14, 52,
-  21, 0, 21, 0, 41, 46, 70, 27, 15, 0,
-  0, 0, 0, 6, 30, 0, 57, 63, 0, 18,
-  0, 0, 0, 0, 0, 23, 55, 0, 32, 0,
-  0, 0, 90, 0, 14, 0, 0, 0, 5, 1,
-  0, 0, 20, 7, 0, 0, 0, 1, 54, 0,
-  0, 0, 0, 0, 42, 0, 0, 7, 0, 86,
-  0, 0, 1, 43, 0, 15, 50, 15, 93, 16,
-  0, 0, 0, 18, 0, 0, 16, 0, 0, 0,
-  0, 0, 0, 25, 0, 0, 34, 33, 0, 35,
-  0, 0, 0, 17, 0, 0, 34, 96, 0, 0,
-  21, 0, 40, 0, 14, 0, 0, 2, 21, 0,
-  100, 23, 1, 3, 2, 71, 0, 0, 0, 0,
-  18, 0, 0, 0, 0, 0, 25, 5, 0, 25,
-  63, 0, 32, 16, 62, 0, 0, 28, 0, 0,
-  0, 0, 0, 0, 67, 44, 0, 0, 0, 0,
-  26, 0, 0, 29, 0, 5, 41, 0, 0, 0,
-  99, 0, 45, 0, 46, 0, 0, 13, 0, 0,
-  0, 6, 19, 0, 16, 0, 16, 11, 0, 0,
-  0, 0, 35, 0, 0, 25, 4, 106, 0, 0,
-  0, 36, 2, 10, 68, 10, 49, 2, 0, 0,
-  0, 0, 0, 0, 0, 2, 0, 9, 0, 0,
-  0, 0, 0, 0, 5, 41, 0, 45, 0, 0,
-  0, 31, 0, 0, 66, 127, 0, 42, 14, 0,
-  16, 0, 2, 0, 0, 0, 48, 0, 110, 32,
-  0, 9, 0, 60, 0, 11, 0, 0, 22, 0,
-  0, 0, 0, 41, 18, 32, 0, 0, 51, 0,
-  58, 18, 81, 0, 0, 0, 0, 0, 0, 12,
-  11, 0, 73, 49, 0, 0, 0, 0, 6, 0,
-  0, 8, 11, 0, 36, 0, 0, 0, 95, 0,
-  70, 0, 20, 0, 1, 0, 0, 0, 8, 0,
-  11, 0, 7, 17, 0, 25, 21, 11, 0, 0,
-  61, 0, 0, 19, 7, 87, 0, 0, 0, 20,
-  13, 16, 69, 0, 0, 19, 0, 0, 0, 0,
-  0, 18, 0, 0, 0, 6, 0, 0, 0, 0,
-  0, 0, 0, 18, 0, 55, 0, 0, 10, 38,
-  0, 0, 71, 103, 0, 69, 0, 0, 31, 9,
-  0, 0, 0, 0, 4, 0, 42, 20, 0, 14,
-  0, 7, 0, 2, 0, 0, 39, 0, 0, 0,
-  0, 43, 31, 45, 9, 0, 36, 0, 50, 45,
-  79, 24, 11, 1, 0, 0, 0, 13, 32, 0,
-  65, 65, 1, 23, 0, 0, 0, 0, 0, 13,
-  64, 0, 7, 0, 0, 0, 59, 0, 45, 0,
-  6, 0, 45, 0, 40, 0, 47, 0, 8, 0,
-  0, 129, 0, 59, 30, 0, 80, 0, 63, 0,
-  2, 62, 41, 13, 24, 8, 0, 36, 0, 50,
-  73, 0, 0, 34, 40, 69, 39, 5, 0, 13,
-  44, 0, 63, 0, 17, 0, 0, 0, 0, 0,
-  0, 30, 0, 55, 31, 26, 0, 15, 0, 0,
-  34, 0, 63, 66, 0, 6, 53, 0, 0, 76,
-  13, 0, 0, 0, 0, 0, 32, 81, 0, 0,
-  0, 20, 0, 0, 48, 49, 0, 0, 0, 0,
-  65, 72, 1, 0, 21, 0, 34, 0, 17, 106,
-  73, 0, 0, 66, 0, 33, 16, 0, 73, 22,
-  0, 27, 0, 0, 0, 0, 17, 70, 123, 31,
-  8, 0, 18, 0, 19, 0, 0, 0, 0, 0,
-  16, 21, 113, 10, 49, 16, 11, 0, 4, 112,
-  0, 54, 23, 0, 15, 0, 85, 7, 0, 53,
-  5, 3, 0, 0, 0, 18, 0, 13, 49, 0,
-  0, 31, 10, 11, 45, 17, 0, 0, 0, 9,
-  32, 0, 23, 0, 0, 18, 0, 0, 0, 0,
-  0, 18, 25, 27, 0, 0, 0, 0, 33, 14,
-  7, 64, 44, 38, 45, 0, 0, 10, 0, 11,
-  7, 12, 0, 7, 17, 45, 0, 29, 0, 13,
-  26, 0, 1, 55, 0, 8, 5, 0, 20, 44,
-  16, 23, 0, 0, 15, 29, 38, 55, 93, 0,
-  0, 17, 0, 0, 52, 0, 35, 52, 0, 80,
-  0, 0, 0, 0, 0, 84, 112, 0, 31, 0,
-  15, 3, 1, 0, 0, 0, 0, 0, 3, 0,
-  28, 0, 45, 32, 0, 0, 29, 57, 0, 24,
-  0, 27, 0, 0, 42, 0, 0, 31, 0, 13,
-  0, 0, 0, 38, 15, 0, 3, 20, 0, 0,
-  0, 0, 2, 0, 0, 0, 0, 33, 0, 0,
-  0, 22, 12, 36, 5, 0, 22, 0, 25, 16,
-  5, 0, 6, 0, 0, 0, 0, 74, 0, 26,
-  125, 100, 30, 22, 18, 0, 0, 43, 75, 37,
-  102, 36, 0, 20, 0, 109, 123, 3, 27, 0,
-  0, 17, 0, 0, 34, 0, 0, 1, 35, 33,
-  3, 0, 0, 8, 62, 0, 21, 30, 0, 0,
-  38, 0, 43, 0, 9, 59, 0, 117, 0, 0,
-  0, 0, 0, 80, 21, 0, 14, 0, 0, 24,
-  0, 0, 0, 0, 10, 0, 0, 0, 0, 0,
-  32, 35, 0, 0, 0, 50, 11, 21, 17, 0,
-  0, 0, 67, 0, 0, 42, 4, 106, 9, 17,
-  15, 45, 0, 24, 71, 0, 40, 19, 0, 0,
-  0, 3, 0, 0, 0, 0, 0, 10, 0, 0,
-  0, 0, 0, 0, 4, 19, 0, 50, 0, 0,
-  0, 45, 0, 0, 34, 65, 36, 45, 0, 0,
-  44, 0, 0, 0, 0, 0, 7, 0, 60, 7,
-  0, 7, 12, 15, 0, 0, 10, 2, 40, 0,
-  0, 0, 0, 1, 42, 35, 2, 0, 21, 0,
-  58, 15, 51, 12, 0, 30, 0, 0, 0, 9,
-  0, 0, 58, 45, 6, 2, 0, 0, 16, 0,
-  0, 13, 0, 3, 7, 0, 0, 0, 80, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 4,
-  12, 0, 20, 58, 19, 29, 24, 0, 0, 0,
-  79, 0, 0, 44, 19, 100, 0, 0, 0, 11,
-  0, 4, 57, 0, 28, 24, 0, 0, 2, 0,
-  0, 3, 5, 0, 0, 6, 0, 0, 0, 0,
-  0, 0, 0, 34, 0, 24, 0, 0, 6, 41,
-  0, 0, 50, 104, 10, 72, 18, 0, 43, 0,
-  5, 0, 0, 0, 14, 0, 25, 49, 0, 0,
-  0, 41, 0, 14, 1, 0, 14, 2, 0, 0,
-  0, 33, 14, 52, 21, 0, 21, 0, 41, 46,
-  70, 27, 15, 0, 0, 0, 0, 6, 30, 0,
-  57, 63, 0, 18, 0, 0, 0, 0, 0, 23,
-  55, 0, 32, 0, 0, 0, 90, 0, 14, 0,
-  0, 0, 5, 1, 0, 0, 20, 7, 0, 0,
-  56, 103, 0, 45, 15, 0, 0, 0, 58, 0,
-  0, 52, 30, 60, 0, 0, 0, 11, 22, 8,
-  26, 0, 0, 48, 0, 0, 58, 0, 0, 0,
-  19, 13, 0, 0, 3, 0, 0, 0, 0, 0,
-  0, 0, 0, 14, 26, 11, 2, 0, 0, 0,
-  23, 83, 1, 41, 67, 0, 39, 3, 0, 0,
-  0, 31, 34, 12, 4, 15, 0, 13, 0, 63,
-  0, 12, 10, 0, 0, 36, 0, 0, 33, 0,
-  0, 39, 30, 13, 0, 0, 19, 60, 73, 69,
-  93, 0, 0, 0, 0, 0, 59, 0, 21, 68,
-  23, 82, 0, 0, 0, 0, 0, 52, 129, 3,
-  21, 0, 0, 7, 40, 0, 0, 0, 3, 0,
-  26, 0, 14, 0, 57, 39, 0, 0, 16, 0,
-  16, 11, 0, 0, 0, 0, 35, 0, 0, 25,
-  4, 106, 0, 0, 0, 36, 2, 10, 68, 10,
-  49, 2, 0, 0, 0, 0, 0, 0, 0, 2,
-  0, 9, 0, 0, 0, 0, 0, 0, 5, 41,
-  0, 45, 0, 0, 0, 31, 0, 0, 66, 127,
-  0, 42, 14, 0, 16, 0, 2, 0, 0, 0,
-  48, 0, 110, 32, 0, 9, 0, 60, 0, 11,
-  0, 0, 22, 0, 0, 0, 0, 41, 18, 32,
-  0, 0, 51, 0, 58, 18, 81, 0, 0, 0,
-  0, 0, 0, 12, 11, 0, 73, 49, 0, 0,
-  0, 0, 6, 0, 0, 8, 11, 0, 36, 0,
-  0, 0, 95, 0, 70, 0, 20, 0, 1, 0,
-  0, 0, 8, 0, 11, 0, 7, 17, 0, 25,
-  21, 11, 0, 0, 61, 0, 0, 19, 7, 87,
-  0, 0, 0, 20, 13, 16, 69, 0, 0, 19,
-  0, 0, 0, 0, 0, 18, 0, 0, 0, 6,
-  0, 0, 0, 0, 0, 0, 0, 18, 0, 55,
-  0, 0, 10, 38, 0, 0, 71, 103, 0, 69,
-  0, 0, 31, 9, 0, 0, 0, 0, 4, 0,
-  42, 20, 0, 14, 0, 7, 0, 2, 0, 0,
-  39, 0, 0, 0, 0, 43, 31, 45, 9, 0,
-  36, 0, 50, 45, 79, 24, 11, 1, 0, 0,
-  0, 13, 32, 0, 65, 65, 1, 23, 0, 0,
-  0, 0, 0, 13, 64, 0, 7, 0, 0, 0,
-  59, 0, 45, 0, 6, 0, 45, 0, 40, 0,
-  47, 0, 8, 0, 0, 108, 0, 50, 20, 0,
-  23, 0, 76, 0, 5, 27, 31, 30, 12, 0,
-  0, 17, 12, 30, 55, 0, 0, 56, 13, 61,
-  39, 0, 0, 26, 15, 0, 27, 4, 0, 0,
-  0, 0, 0, 5, 0, 21, 0, 47, 11, 0,
-  10, 19, 0, 0, 54, 49, 57, 86, 0, 0,
-  20, 0, 0, 49, 9, 0, 0, 0, 0, 0,
-  32, 13, 0, 0, 0, 12, 0, 0, 51, 32,
-  0, 0, 0, 19, 65, 67, 24, 0, 19, 0,
-  39, 50, 52, 88, 74, 0, 0, 18, 0, 13,
-  42, 0, 60, 63, 11, 32, 0, 0, 0, 0,
-  14, 25, 123, 40, 2, 0, 0, 0, 13, 0,
-  5, 0, 0, 0, 42, 3, 144, 0, 86, 0,
-  0, 0, 4, 112, 0, 54, 23, 0, 15, 0,
-  85, 7, 0, 53, 5, 3, 0, 0, 0, 18,
-  0, 13, 49, 0, 0, 31, 10, 11, 45, 17,
-  0, 0, 0, 9, 32, 0, 23, 0, 0, 18,
-  0, 0, 0, 0, 0, 18, 25, 27, 0, 0,
-  0, 0, 33, 14, 7, 64, 44, 38, 45, 0,
-  0, 10, 0, 11, 7, 12, 0, 7, 17, 45,
-  0, 29, 0, 13, 26, 0, 1, 55, 0, 8,
-  5, 0, 20, 44, 16, 23, 0, 0, 15, 29,
-  38, 55, 93, 0, 0, 17, 0, 0, 52, 0,
-  35, 52, 0, 80, 0, 0, 0, 0, 0, 84,
-  112, 0, 31, 0, 15, 3, 1, 0, 0, 0,
-  0, 0, 3, 0, 28, 0, 45, 32, 0, 0,
-  29, 57, 0, 24, 0, 27, 0, 0, 42, 0,
-  0, 31, 0, 13, 0, 0, 0, 38, 15, 0,
-  3, 20, 0, 0, 0, 0, 2, 0, 0, 0,
-  0, 33, 0, 0, 0, 22, 12, 36, 5, 0,
-  22, 0, 25, 16, 5, 0, 6, 0, 0, 0,
-  0, 74, 0, 26, 125, 100, 30, 22, 18, 0,
-  0, 43, 75, 37, 102, 36, 0, 20, 0, 109,
-  123, 3, 27, 0, 0, 17, 0, 0, 34, 0,
-  0, 1, 35, 33, 3, 0, 0, 8, 62, 0,
-  21, 30, 0, 0, 38, 0, 43, 0, 9, 59,
-  0, 117, 0, 0, 0, 0, 0, 80, 21, 0,
-  14, 0, 0, 24, 0, 0, 0, 0, 10, 0,
-  0, 0, 0, 0, 32, 35, 0, 0, 10, 25,
-  0, 0, 0, 85, 0, 0, 22, 0, 0, 0,
-  0, 0, 0, 0, 0, 39, 3, 8, 0, 40,
-  0, 0, 0, 0, 8, 3, 0, 0, 0, 38,
-  0, 0, 0, 43, 47, 68, 23, 0, 46, 0,
-  22, 15, 0, 13, 59, 13, 0, 0, 0, 55,
-  0, 0, 112, 118, 34, 26, 48, 0, 0, 57,
-  67, 0, 179, 5, 0, 32, 0, 139, 175, 0,
-  10, 15, 0, 0, 0, 0, 42, 0, 0, 0,
-  28, 19, 31, 0, 0, 11, 42, 0, 0, 116,
-  13, 0, 34, 0, 0, 0, 6, 54, 43, 142,
-  0, 0, 0, 0, 0, 58, 0, 0, 0, 29,
-  0, 30, 0, 10, 0, 0, 53, 0, 0, 0,
-  0, 0, 1, 29, 1, 6, 20, 58, 19, 29,
-  24, 0, 0, 0, 79, 0, 0, 44, 19, 100,
-  0, 0, 0, 11, 0, 4, 57, 0, 28, 24,
-  0, 0, 2, 0, 0, 3, 5, 0, 0, 6,
-  0, 0, 0, 0, 0, 0, 0, 34, 0, 24,
-  0, 0, 6, 41, 0, 0, 50, 104, 10, 72,
-  18, 0, 43, 0, 5, 0, 0, 0, 14, 0,
-  25, 49, 0, 0, 0, 41, 0, 14, 1, 0,
-  14, 2, 0, 0, 0, 33, 14, 52, 21, 0,
-  21, 0, 41, 46, 70, 27, 15, 0, 0, 0,
-  0, 6, 30, 0, 57, 63, 0, 18, 0, 0,
-  0, 0, 0, 23, 55, 0, 32, 0, 0, 0,
-  90, 0, 14, 0, 0, 0, 5, 1, 0, 0,
-  20, 7, 0, 0, 56, 103, 0, 45, 15, 0,
-  0, 0, 58, 0, 0, 52, 30, 60, 0, 0,
-  0, 11, 22, 8, 26, 0, 0, 48, 0, 0,
-  58, 0, 0, 0, 19, 13, 0, 0, 3, 0,
-  0, 0, 0, 0, 0, 0, 0, 14, 26, 11,
-  2, 0, 0, 0, 23, 83, 1, 41, 67, 0,
-  39, 3, 0, 0, 0, 31, 34, 12, 4, 15,
-  0, 13, 0, 63, 0, 12, 10, 0, 0, 36,
-  0, 0, 33, 0, 0, 39, 30, 13, 0, 0,
-  19, 60, 73, 69, 93, 0, 0, 0, 0, 0,
-  59, 0, 21, 68, 23, 82, 0, 0, 0, 0,
-  0, 52, 129, 3, 21, 0, 0, 7, 40, 0,
-  0, 0, 3, 0, 26, 0, 14, 0, 57, 39,
-  0, 0, 46, 82, 0, 50, 1, 35, 0, 0,
-  22, 0, 0, 15, 41, 6, 0, 0, 0, 19,
-  21, 11, 13, 31, 0, 0, 0, 0, 64, 0,
-  0, 0, 30, 54, 0, 0, 28, 29, 0, 17,
-  0, 0, 0, 0, 1, 18, 5, 11, 10, 0,
-  0, 0, 0, 57, 0, 22, 95, 48, 30, 4,
-  0, 0, 0, 73, 54, 11, 88, 0, 0, 66,
-  0, 94, 130, 13, 9, 0, 0, 4, 0, 2,
-  68, 0, 0, 0, 23, 16, 20, 0, 0, 28,
-  33, 13, 56, 0, 0, 0, 6, 0, 47, 0,
-  18, 68, 22, 150, 0, 0, 0, 0, 0, 82,
-  91, 0, 7, 26, 10, 31, 0, 0, 0, 0,
-  31, 0, 0, 0, 0, 0, 50, 35, 0, 2,
-  7, 17, 0, 25, 21, 11, 0, 0, 61, 0,
-  0, 19, 7, 87, 0, 0, 0, 20, 13, 16,
-  69, 0, 0, 19, 0, 0, 0, 0, 0, 18,
-  0, 0, 0, 6, 0, 0, 0, 0, 0, 0,
-  0, 18, 0, 55, 0, 0, 10, 38, 0, 0,
-  71, 103, 0, 69, 0, 0, 31, 9, 0, 0,
-  0, 0, 4, 0, 42, 20, 0, 14, 0, 7,
-  0, 2, 0, 0, 39, 0, 0, 0, 0, 43,
-  31, 45, 9, 0, 36, 0, 50, 45, 79, 24,
-  11, 1, 0, 0, 0, 13, 32, 0, 65, 65,
-  1, 23, 0, 0, 0, 0, 0, 13, 64, 0,
-  7, 0, 0, 0, 59, 0, 45, 0, 6, 0,
-  45, 0, 40, 0, 47, 0, 8, 0, 0, 108,
-  0, 50, 20, 0, 23, 0, 76, 0, 5, 27,
-  31, 30, 12, 0, 0, 17, 12, 30, 55, 0,
-  0, 56, 13, 61, 39, 0, 0, 26, 15, 0,
-  27, 4, 0, 0, 0, 0, 0, 5, 0, 21,
-  0, 47, 11, 0, 10, 19, 0, 0, 54, 49,
-  57, 86, 0, 0, 20, 0, 0, 49, 9, 0,
-  0, 0, 0, 0, 32, 13, 0, 0, 0, 12,
-  0, 0, 51, 32, 0, 0, 0, 19, 65, 67,
-  24, 0, 19, 0, 39, 50, 52, 88, 74, 0,
-  0, 18, 0, 13, 42, 0, 60, 63, 11, 32,
-  0, 0, 0, 0, 14, 25, 123, 40, 2, 0,
-  0, 0, 13, 0, 5, 0, 0, 0, 42, 3,
-  144, 0, 86, 0, 0, 0, 0, 155, 0, 57,
-  4, 0, 35, 0, 65, 0, 13, 22, 77, 0,
-  0, 0, 0, 12, 22, 43, 12, 0, 0, 61,
-  29, 33, 73, 13, 3, 0, 36, 0, 52, 0,
-  38, 0, 0, 0, 0, 0, 0, 22, 0, 53,
-  11, 0, 16, 0, 0, 0, 43, 52, 47, 51,
-  11, 17, 36, 0, 0, 49, 1, 0, 0, 0,
-  0, 0, 2, 16, 0, 0, 11, 34, 0, 0,
-  39, 55, 0, 69, 4, 0, 37, 56, 49, 10,
-  11, 0, 0, 58, 72, 93, 137, 0, 0, 11,
-  0, 0, 57, 0, 44, 81, 42, 39, 0, 0,
-  0, 0, 27, 70, 152, 18, 4, 0, 17, 10,
-  0, 0, 0, 0, 0, 0, 3, 0, 133, 2,
-  119, 5, 0, 0, 29, 57, 0, 24, 0, 27,
-  0, 0, 42, 0, 0, 31, 0, 13, 0, 0,
-  0, 38, 15, 0, 3, 20, 0, 0, 0, 0,
-  2, 0, 0, 0, 0, 33, 0, 0, 0, 22,
-  12, 36, 5, 0, 22, 0, 25, 16, 5, 0,
-  6, 0, 0, 0, 0, 74, 0, 26, 125, 100,
-  30, 22, 18, 0, 0, 43, 75, 37, 102, 36,
-  0, 20, 0, 109, 123, 3, 27, 0, 0, 17,
-  0, 0, 34, 0, 0, 1, 35, 33, 3, 0,
-  0, 8, 62, 0, 21, 30, 0, 0, 38, 0,
-  43, 0, 9, 59, 0, 117, 0, 0, 0, 0,
-  0, 80, 21, 0, 14, 0, 0, 24, 0, 0,
-  0, 0, 10, 0, 0, 0, 0, 0, 32, 35,
-  0, 0, 10, 25, 0, 0, 0, 85, 0, 0,
-  22, 0, 0, 0, 0, 0, 0, 0, 0, 39,
-  3, 8, 0, 40, 0, 0, 0, 0, 8, 3,
-  0, 0, 0, 38, 0, 0, 0, 43, 47, 68,
-  23, 0, 46, 0, 22, 15, 0, 13, 59, 13,
-  0, 0, 0, 55, 0, 0, 112, 118, 34, 26,
-  48, 0, 0, 57, 67, 0, 179, 5, 0, 32,
-  0, 139, 175, 0, 10, 15, 0, 0, 0, 0,
-  42, 0, 0, 0, 28, 19, 31, 0, 0, 11,
-  42, 0, 0, 116, 13, 0, 34, 0, 0, 0,
-  6, 54, 43, 142, 0, 0, 0, 0, 0, 58,
-  0, 0, 0, 29, 0, 30, 0, 10, 0, 0,
-  53, 0, 0, 0, 0, 0, 1, 29, 1, 6,
-  0, 37, 0, 0, 0, 81, 0, 0, 83, 32,
-  0, 0, 0, 9, 0, 42, 6, 26, 0, 10,
-  0, 0, 0, 25, 0, 0, 22, 40, 7, 0,
-  0, 0, 67, 0, 0, 20, 33, 86, 0, 0,
-  32, 0, 0, 10, 0, 67, 54, 81, 0, 26,
-  0, 6, 0, 0, 25, 36, 58, 0, 32, 0,
-  0, 65, 0, 0, 102, 0, 0, 34, 25, 57,
-  85, 0, 33, 59, 0, 79, 0, 0, 3, 0,
-  3, 0, 2, 0, 0, 0, 0, 49, 15, 0,
-  0, 173, 0, 0, 0, 0, 0, 0, 0, 64,
-  113, 110, 0, 0, 0, 0, 0, 29, 0, 22,
-  0, 30, 0, 19, 0, 0, 0, 29, 61, 0,
-  40, 0, 0, 0, 0, 15, 1, 35, 56, 103,
-  0, 45, 15, 0, 0, 0, 58, 0, 0, 52,
-  30, 60, 0, 0, 0, 11, 22, 8, 26, 0,
-  0, 48, 0, 0, 58, 0, 0, 0, 19, 13,
-  0, 0, 3, 0, 0, 0, 0, 0, 0, 0,
-  0, 14, 26, 11, 2, 0, 0, 0, 23, 83,
-  1, 41, 67, 0, 39, 3, 0, 0, 0, 31,
-  34, 12, 4, 15, 0, 13, 0, 63, 0, 12,
-  10, 0, 0, 36, 0, 0, 33, 0, 0, 39,
-  30, 13, 0, 0, 19, 60, 73, 69, 93, 0,
-  0, 0, 0, 0, 59, 0, 21, 68, 23, 82,
-  0, 0, 0, 0, 0, 52, 129, 3, 21, 0,
-  0, 7, 40, 0, 0, 0, 3, 0, 26, 0,
-  14, 0, 57, 39, 0, 0, 46, 82, 0, 50,
-  1, 35, 0, 0, 22, 0, 0, 15, 41, 6,
-  0, 0, 0, 19, 21, 11, 13, 31, 0, 0,
-  0, 0, 64, 0, 0, 0, 30, 54, 0, 0,
-  28, 29, 0, 17, 0, 0, 0, 0, 1, 18,
-  5, 11, 10, 0, 0, 0, 0, 57, 0, 22,
-  95, 48, 30, 4, 0, 0, 0, 73, 54, 11,
-  88, 0, 0, 66, 0, 94, 130, 13, 9, 0,
-  0, 4, 0, 2, 68, 0, 0, 0, 23, 16,
-  20, 0, 0, 28, 33, 13, 56, 0, 0, 0,
-  6, 0, 47, 0, 18, 68, 22, 150, 0, 0,
-  0, 0, 0, 82, 91, 0, 7, 26, 10, 31,
-  0, 0, 0, 0, 31, 0, 0, 0, 0, 0,
-  50, 35, 0, 2, 1, 12, 0, 19, 0, 115,
-  0, 0, 17, 0, 0, 0, 0, 1, 0, 0,
-  0, 28, 11, 16, 0, 65, 2, 0, 0, 0,
-  23, 0, 0, 0, 0, 17, 8, 0, 9, 65,
-  12, 45, 5, 0, 48, 0, 0, 18, 0, 33,
-  46, 0, 0, 7, 0, 29, 0, 0, 131, 59,
-  54, 5, 43, 0, 0, 107, 51, 0, 166, 0,
-  0, 46, 0, 112, 193, 0, 44, 0, 0, 35,
-  0, 0, 29, 0, 0, 0, 32, 0, 28, 0,
-  0, 1, 14, 0, 0, 79, 16, 0, 38, 0,
-  0, 0, 3, 61, 47, 127, 0, 0, 0, 0,
-  0, 36, 0, 0, 0, 55, 0, 53, 0, 0,
-  0, 0, 47, 0, 0, 0, 0, 0, 13, 18,
-  0, 12, 0, 108, 0, 50, 20, 0, 23, 0,
-  76, 0, 5, 27, 31, 30, 12, 0, 0, 17,
-  12, 30, 55, 0, 0, 56, 13, 61, 39, 0,
-  0, 26, 15, 0, 27, 4, 0, 0, 0, 0,
-  0, 5, 0, 21, 0, 47, 11, 0, 10, 19,
-  0, 0, 54, 49, 57, 86, 0, 0, 20, 0,
-  0, 49, 9, 0, 0, 0, 0, 0, 32, 13,
-  0, 0, 0, 12, 0, 0, 51, 32, 0, 0,
-  0, 19, 65, 67, 24, 0, 19, 0, 39, 50,
-  52, 88, 74, 0, 0, 18, 0, 13, 42, 0,
-  60, 63, 11, 32, 0, 0, 0, 0, 14, 25,
-  123, 40, 2, 0, 0, 0, 13, 0, 5, 0,
-  0, 0, 42, 3, 144, 0, 86, 0, 0, 0,
-  0, 155, 0, 57, 4, 0, 35, 0, 65, 0,
-  13, 22, 77, 0, 0, 0, 0, 12, 22, 43,
-  12, 0, 0, 61, 29, 33, 73, 13, 3, 0,
-  36, 0, 52, 0, 38, 0, 0, 0, 0, 0,
-  0, 22, 0, 53, 11, 0, 16, 0, 0, 0,
-  43, 52, 47, 51, 11, 17, 36, 0, 0, 49,
-  1, 0, 0, 0, 0, 0, 2, 16, 0, 0,
-  11, 34, 0, 0, 39, 55, 0, 69, 4, 0,
-  37, 56, 49, 10, 11, 0, 0, 58, 72, 93,
-  137, 0, 0, 11, 0, 0, 57, 0, 44, 81,
-  42, 39, 0, 0, 0, 0, 27, 70, 152, 18,
-  4, 0, 17, 10, 0, 0, 0, 0, 0, 0,
-  3, 0, 133, 2, 119, 5, 0, 0, 21, 77,
-  0, 54, 0, 57, 1, 0, 24, 0, 0, 9,
-  43, 0, 0, 0, 0, 20, 47, 27, 0, 27,
-  1, 0, 0, 0, 69, 0, 0, 0, 4, 19,
-  15, 0, 32, 49, 0, 0, 3, 0, 0, 7,
-  0, 34, 8, 10, 16, 0, 0, 0, 3, 45,
-  0, 0, 93, 35, 51, 0, 0, 0, 0, 53,
-  20, 0, 103, 0, 0, 43, 0, 68, 175, 29,
-  22, 0, 0, 35, 0, 61, 4, 6, 0, 0,
-  64, 5, 21, 0, 0, 19, 51, 0, 81, 0,
-  0, 0, 7, 0, 55, 0, 12, 95, 28, 106,
-  1, 0, 0, 0, 4, 67, 71, 0, 2, 16,
-  0, 39, 0, 0, 0, 0, 25, 0, 0, 0,
-  0, 18, 65, 17, 0, 0, 10, 25, 0, 0,
-  0, 85, 0, 0, 22, 0, 0, 0, 0, 0,
-  0, 0, 0, 39, 3, 8, 0, 40, 0, 0,
-  0, 0, 8, 3, 0, 0, 0, 38, 0, 0,
-  0, 43, 47, 68, 23, 0, 46, 0, 22, 15,
-  0, 13, 59, 13, 0, 0, 0, 55, 0, 0,
-  112, 118, 34, 26, 48, 0, 0, 57, 67, 0,
-  179, 5, 0, 32, 0, 139, 175, 0, 10, 15,
-  0, 0, 0, 0, 42, 0, 0, 0, 28, 19,
-  31, 0, 0, 11, 42, 0, 0, 116, 13, 0,
-  34, 0, 0, 0, 6, 54, 43, 142, 0, 0,
-  0, 0, 0, 58, 0, 0, 0, 29, 0, 30,
-  0, 10, 0, 0, 53, 0, 0, 0, 0, 0,
-  1, 29, 1, 6, 0, 37, 0, 0, 0, 81,
-  0, 0, 83, 32, 0, 0, 0, 9, 0, 42,
-  6, 26, 0, 10, 0, 0, 0, 25, 0, 0,
-  22, 40, 7, 0, 0, 0, 67, 0, 0, 20,
-  33, 86, 0, 0, 32, 0, 0, 10, 0, 67,
-  54, 81, 0, 26, 0, 6, 0, 0, 25, 36,
-  58, 0, 32, 0, 0, 65, 0, 0, 102, 0,
-  0, 34, 25, 57, 85, 0, 33, 59, 0, 79,
-  0, 0, 3, 0, 3, 0, 2, 0, 0, 0,
-  0, 49, 15, 0, 0, 173, 0, 0, 0, 0,
-  0, 0, 0, 64, 113, 110, 0, 0, 0, 0,
-  0, 29, 0, 22, 0, 30, 0, 19, 0, 0,
-  0, 29, 61, 0, 40, 0, 0, 0, 0, 15,
-  1, 35, 0, 34, 21, 0, 0, 0, 48, 33,
-  91, 15, 14, 16, 57, 1, 0, 81, 49, 0,
-  0, 0, 6, 20, 26, 30, 1, 0, 0, 23,
-  0, 0, 0, 0, 60, 0, 3, 0, 0, 56,
-  0, 42, 4, 5, 0, 43, 0, 101, 57, 64,
-  0, 36, 0, 14, 67, 0, 0, 0, 60, 0,
-  18, 0, 6, 36, 0, 46, 0, 0, 0, 0,
-  80, 0, 0, 0, 27, 50, 26, 48, 16, 11,
-  0, 0, 59, 0, 25, 0, 0, 9, 9, 3,
-  5, 0, 0, 63, 0, 14, 0, 0, 0, 0,
-  4, 79, 88, 0, 0, 0, 17, 0, 30, 2,
-  0, 51, 0, 7, 0, 20, 0, 0, 0, 31,
-  77, 0, 50, 0, 85, 0, 42, 0, 14, 0,
-  46, 82, 0, 50, 1, 35, 0, 0, 22, 0,
-  0, 15, 41, 6, 0, 0, 0, 19, 21, 11,
-  13, 31, 0, 0, 0, 0, 64, 0, 0, 0,
-  30, 54, 0, 0, 28, 29, 0, 17, 0, 0,
-  0, 0, 1, 18, 5, 11, 10, 0, 0, 0,
-  0, 57, 0, 22, 95, 48, 30, 4, 0, 0,
-  0, 73, 54, 11, 88, 0, 0, 66, 0, 94,
-  130, 13, 9, 0, 0, 4, 0, 2, 68, 0,
-  0, 0, 23, 16, 20, 0, 0, 28, 33, 13,
-  56, 0, 0, 0, 6, 0, 47, 0, 18, 68,
-  22, 150, 0, 0, 0, 0, 0, 82, 91, 0,
-  7, 26, 10, 31, 0, 0, 0, 0, 31, 0,
-  0, 0, 0, 0, 50, 35, 0, 2, 1, 12,
-  0, 19, 0, 115, 0, 0, 17, 0, 0, 0,
-  0, 1, 0, 0, 0, 28, 11, 16, 0, 65,
-  2, 0, 0, 0, 23, 0, 0, 0, 0, 17,
-  8, 0, 9, 65, 12, 45, 5, 0, 48, 0,
-  0, 18, 0, 33, 46, 0, 0, 7, 0, 29,
-  0, 0, 131, 59, 54, 5, 43, 0, 0, 107,
-  51, 0, 166, 0, 0, 46, 0, 112, 193, 0,
-  44, 0, 0, 35, 0, 0, 29, 0, 0, 0,
-  32, 0, 28, 0, 0, 1, 14, 0, 0, 79,
-  16, 0, 38, 0, 0, 0, 3, 61, 47, 127,
-  0, 0, 0, 0, 0, 36, 0, 0, 0, 55,
-  0, 53, 0, 0, 0, 0, 47, 0, 0, 0,
-  0, 0, 13, 18, 0, 12, 0, 1, 0, 0,
-  0, 57, 0, 18, 70, 15, 0, 4, 0, 0,
-  0, 50, 13, 20, 0, 0, 47, 47, 29, 12,
-  0, 0, 0, 10, 0, 0, 0, 0, 50, 0,
-  0, 44, 0, 64, 0, 0, 54, 0, 0, 47,
-  0, 99, 16, 46, 0, 15, 0, 37, 0, 0,
-  63, 0, 74, 0, 64, 0, 0, 62, 0, 0,
-  90, 0, 0, 12, 30, 23, 61, 0, 70, 60,
-  0, 76, 0, 1, 0, 0, 21, 0, 0, 0,
-  0, 0, 8, 0, 5, 0, 0, 121, 9, 0,
-  0, 0, 0, 0, 20, 54, 116, 17, 0, 0,
-  0, 0, 11, 9, 0, 21, 0, 19, 0, 73,
-  0, 0, 0, 0, 56, 0, 53, 0, 0, 0,
-  21, 0, 18, 0, 0, 155, 0, 57, 4, 0,
-  35, 0, 65, 0, 13, 22, 77, 0, 0, 0,
-  0, 12, 22, 43, 12, 0, 0, 61, 29, 33,
-  73, 13, 3, 0, 36, 0, 52, 0, 38, 0,
-  0, 0, 0, 0, 0, 22, 0, 53, 11, 0,
-  16, 0, 0, 0, 43, 52, 47, 51, 11, 17,
-  36, 0, 0, 49, 1, 0, 0, 0, 0, 0,
-  2, 16, 0, 0, 11, 34, 0, 0, 39, 55,
-  0, 69, 4, 0, 37, 56, 49, 10, 11, 0,
-  0, 58, 72, 93, 137, 0, 0, 11, 0, 0,
-  57, 0, 44, 81, 42, 39, 0, 0, 0, 0,
-  27, 70, 152, 18, 4, 0, 17, 10, 0, 0,
-  0, 0, 0, 0, 3, 0, 133, 2, 119, 5,
-  0, 0, 21, 77, 0, 54, 0, 57, 1, 0,
-  24, 0, 0, 9, 43, 0, 0, 0, 0, 20,
-  47, 27, 0, 27, 1, 0, 0, 0, 69, 0,
-  0, 0, 4, 19, 15, 0, 32, 49, 0, 0,
-  3, 0, 0, 7, 0, 34, 8, 10, 16, 0,
-  0, 0, 3, 45, 0, 0, 93, 35, 51, 0,
-  0, 0, 0, 53, 20, 0, 103, 0, 0, 43,
-  0, 68, 175, 29, 22, 0, 0, 35, 0, 61,
-  4, 6, 0, 0, 64, 5, 21, 0, 0, 19,
-  51, 0, 81, 0, 0, 0, 7, 0, 55, 0,
-  12, 95, 28, 106, 1, 0, 0, 0, 4, 67,
-  71, 0, 2, 16, 0, 39, 0, 0, 0, 0,
-  25, 0, 0, 0, 0, 18, 65, 17, 0, 0,
-  0, 0, 0, 25, 0, 135, 0, 7, 42, 0,
-  0, 4, 0, 6, 0, 0, 0, 25, 13, 0,
-  41, 106, 15, 0, 0, 0, 0, 1, 0, 0,
-  0, 1, 9, 0, 0, 82, 0, 40, 0, 0,
-  45, 0, 0, 46, 0, 80, 0, 4, 0, 0,
-  0, 52, 0, 0, 133, 36, 44, 0, 57, 0,
-  0, 92, 42, 0, 155, 0, 0, 30, 0, 77,
-  196, 0, 59, 34, 0, 31, 0, 16, 9, 0,
-  0, 0, 35, 0, 0, 0, 1, 0, 11, 0,
-  0, 92, 0, 0, 27, 0, 0, 0, 7, 76,
-  78, 108, 0, 0, 0, 0, 0, 30, 0, 0,
-  0, 38, 0, 95, 0, 0, 0, 0, 52, 0,
-  0, 0, 0, 0, 21, 0, 0, 6, 0, 37,
-  0, 0, 0, 81, 0, 0, 83, 32, 0, 0,
-  0, 9, 0, 42, 6, 26, 0, 10, 0, 0,
-  0, 25, 0, 0, 22, 40, 7, 0, 0, 0,
-  67, 0, 0, 20, 33, 86, 0, 0, 32, 0,
-  0, 10, 0, 67, 54, 81, 0, 26, 0, 6,
-  0, 0, 25, 36, 58, 0, 32, 0, 0, 65,
-  0, 0, 102, 0, 0, 34, 25, 57, 85, 0,
-  33, 59, 0, 79, 0, 0, 3, 0, 3, 0,
-  2, 0, 0, 0, 0, 49, 15, 0, 0, 173,
-  0, 0, 0, 0, 0, 0, 0, 64, 113, 110,
-  0, 0, 0, 0, 0, 29, 0, 22, 0, 30,
-  0, 19, 0, 0, 0, 29, 61, 0, 40, 0,
-  0, 0, 0, 15, 1, 35, 0, 34, 21, 0,
-  0, 0, 48, 33, 91, 15, 14, 16, 57, 1,
-  0, 81, 49, 0, 0, 0, 6, 20, 26, 30,
-  1, 0, 0, 23, 0, 0, 0, 0, 60, 0,
-  3, 0, 0, 56, 0, 42, 4, 5, 0, 43,
-  0, 101, 57, 64, 0, 36, 0, 14, 67, 0,
-  0, 0, 60, 0, 18, 0, 6, 36, 0, 46,
-  0, 0, 0, 0, 80, 0, 0, 0, 27, 50,
-  26, 48, 16, 11, 0, 0, 59, 0, 25, 0,
-  0, 9, 9, 3, 5, 0, 0, 63, 0, 14,
-  0, 0, 0, 0, 4, 79, 88, 0, 0, 0,
-  17, 0, 30, 2, 0, 51, 0, 7, 0, 20,
-  0, 0, 0, 31, 77, 0, 50, 0, 85, 0,
-  42, 0, 14, 0, 0, 27, 0, 6, 0, 0,
-  33, 17, 40, 0, 12, 29, 62, 0, 14, 33,
-  65, 28, 0, 0, 26, 32, 26, 12, 42, 0,
-  0, 27, 0, 0, 0, 0, 69, 0, 0, 0,
-  0, 14, 0, 40, 0, 14, 0, 40, 23, 88,
-  0, 29, 0, 18, 0, 24, 66, 1, 4, 0,
-  0, 0, 0, 0, 30, 14, 0, 50, 0, 7,
-  42, 0, 37, 0, 0, 0, 0, 48, 16, 0,
-  58, 78, 0, 0, 60, 0, 43, 4, 0, 14,
-  12, 0, 0, 2, 0, 24, 0, 6, 0, 25,
-  4, 0, 5, 84, 38, 0, 0, 3, 48, 0,
-  12, 5, 0, 1, 0, 12, 0, 2, 0, 0,
-  15, 0, 12, 0, 16, 0, 60, 0, 26, 0,
-  25, 0, 1, 12, 0, 19, 0, 115, 0, 0,
-  17, 0, 0, 0, 0, 1, 0, 0, 0, 28,
-  11, 16, 0, 65, 2, 0, 0, 0, 23, 0,
-  0, 0, 0, 17, 8, 0, 9, 65, 12, 45,
-  5, 0, 48, 0, 0, 18, 0, 33, 46, 0,
-  0, 7, 0, 29, 0, 0, 131, 59, 54, 5,
-  43, 0, 0, 107, 51, 0, 166, 0, 0, 46,
-  0, 112, 193, 0, 44, 0, 0, 35, 0, 0,
-  29, 0, 0, 0, 32, 0, 28, 0, 0, 1,
-  14, 0, 0, 79, 16, 0, 38, 0, 0, 0,
-  3, 61, 47, 127, 0, 0, 0, 0, 0, 36,
-  0, 0, 0, 55, 0, 53, 0, 0, 0, 0,
-  47, 0, 0, 0, 0, 0, 13, 18, 0, 12,
-  0, 1, 0, 0, 0, 57, 0, 18, 70, 15,
-  0, 4, 0, 0, 0, 50, 13, 20, 0, 0,
-  47, 47, 29, 12, 0, 0, 0, 10, 0, 0,
-  0, 0, 50, 0, 0, 44, 0, 64, 0, 0,
-  54, 0, 0, 47, 0, 99, 16, 46, 0, 15,
-  0, 37, 0, 0, 63, 0, 74, 0, 64, 0,
-  0, 62, 0, 0, 90, 0, 0, 12, 30, 23,
-  61, 0, 70, 60, 0, 76, 0, 1, 0, 0,
-  21, 0, 0, 0, 0, 0, 8, 0, 5, 0,
-  0, 121, 9, 0, 0, 0, 0, 0, 20, 54,
-  116, 17, 0, 0, 0, 0, 11, 9, 0, 21,
-  0, 19, 0, 73, 0, 0, 0, 0, 56, 0,
-  53, 0, 0, 0, 21, 0, 18, 0, 0, 48,
-  16, 0, 0, 0, 50, 44, 75, 3, 3, 42,
-  110, 0, 16, 61, 79, 13, 2, 0, 31, 54,
-  4, 6, 49, 0, 0, 45, 0, 0, 0, 0,
-  83, 0, 2, 0, 0, 62, 0, 80, 0, 35,
-  4, 49, 18, 97, 6, 35, 0, 42, 0, 40,
-  48, 0, 23, 0, 3, 0, 0, 0, 0, 5,
-  0, 59, 0, 17, 20, 0, 40, 0, 0, 0,
-  0, 48, 8, 0, 29, 54, 0, 0, 33, 0,
-  42, 5, 0, 9, 4, 0, 0, 8, 0, 4,
-  0, 44, 0, 13, 5, 8, 15, 84, 41, 0,
-  0, 0, 34, 0, 24, 13, 4, 22, 0, 21,
-  0, 22, 0, 0, 0, 0, 35, 0, 31, 0,
-  111, 0, 71, 0, 32, 0, 21, 77, 0, 54,
-  0, 57, 1, 0, 24, 0, 0, 9, 43, 0,
-  0, 0, 0, 20, 47, 27, 0, 27, 1, 0,
-  0, 0, 69, 0, 0, 0, 4, 19, 15, 0,
-  32, 49, 0, 0, 3, 0, 0, 7, 0, 34,
-  8, 10, 16, 0, 0, 0, 3, 45, 0, 0,
-  93, 35, 51, 0, 0, 0, 0, 53, 20, 0,
-  103, 0, 0, 43, 0, 68, 175, 29, 22, 0,
-  0, 35, 0, 61, 4, 6, 0, 0, 64, 5,
-  21, 0, 0, 19, 51, 0, 81, 0, 0, 0,
-  7, 0, 55, 0, 12, 95, 28, 106, 1, 0,
-  0, 0, 4, 67, 71, 0, 2, 16, 0, 39,
-  0, 0, 0, 0, 25, 0, 0, 0, 0, 18,
-  65, 17, 0, 0, 0, 0, 0, 25, 0, 135,
-  0, 7, 42, 0, 0, 4, 0, 6, 0, 0,
-  0, 25, 13, 0, 41, 106, 15, 0, 0, 0,
-  0, 1, 0, 0, 0, 1, 9, 0, 0, 82,
-  0, 40, 0, 0, 45, 0, 0, 46, 0, 80,
-  0, 4, 0, 0, 0, 52, 0, 0, 133, 36,
-  44, 0, 57, 0, 0, 92, 42, 0, 155, 0,
-  0, 30, 0, 77, 196, 0, 59, 34, 0, 31,
-  0, 16, 9, 0, 0, 0, 35, 0, 0, 0,
-  1, 0, 11, 0, 0, 92, 0, 0, 27, 0,
-  0, 0, 7, 76, 78, 108, 0, 0, 0, 0,
-  0, 30, 0, 0, 0, 38, 0, 95, 0, 0,
-  0, 0, 52, 0, 0, 0, 0, 0, 21, 0,
-  0, 6, 0, 28, 0, 8, 0, 24, 24, 29,
-  104, 12, 0, 37, 106, 0, 0, 105, 62, 22,
-  0, 0, 41, 62, 0, 12, 2, 0, 0, 43,
-  0, 0, 0, 0, 76, 0, 33, 0, 0, 91,
-  0, 53, 32, 0, 4, 39, 5, 115, 2, 34,
-  0, 36, 0, 56, 16, 0, 56, 0, 6, 0,
-  36, 0, 0, 14, 0, 21, 0, 0, 0, 0,
-  27, 0, 37, 0, 47, 52, 0, 14, 8, 31,
-  0, 0, 8, 0, 29, 0, 0, 10, 11, 0,
-  20, 0, 0, 68, 0, 34, 0, 0, 0, 0,
-  26, 84, 90, 0, 0, 0, 22, 0, 15, 31,
-  0, 34, 0, 30, 0, 52, 0, 0, 0, 0,
-  60, 0, 39, 0, 79, 0, 69, 0, 34, 16,
-  0, 34, 21, 0, 0, 0, 48, 33, 91, 15,
-  14, 16, 57, 1, 0, 81, 49, 0, 0, 0,
-  6, 20, 26, 30, 1, 0, 0, 23, 0, 0,
-  0, 0, 60, 0, 3, 0, 0, 56, 0, 42,
-  4, 5, 0, 43, 0, 101, 57, 64, 0, 36,
-  0, 14, 67, 0, 0, 0, 60, 0, 18, 0,
-  6, 36, 0, 46, 0, 0, 0, 0, 80, 0,
-  0, 0, 27, 50, 26, 48, 16, 11, 0, 0,
-  59, 0, 25, 0, 0, 9, 9, 3, 5, 0,
-  0, 63, 0, 14, 0, 0, 0, 0, 4, 79,
-  88, 0, 0, 0, 17, 0, 30, 2, 0, 51,
-  0, 7, 0, 20, 0, 0, 0, 31, 77, 0,
-  50, 0, 85, 0, 42, 0, 14, 0, 0, 27,
-  0, 6, 0, 0, 33, 17, 40, 0, 12, 29,
-  62, 0, 14, 33, 65, 28, 0, 0, 26, 32,
-  26, 12, 42, 0, 0, 27, 0, 0, 0, 0,
-  69, 0, 0, 0, 0, 14, 0, 40, 0, 14,
-  0, 40, 23, 88, 0, 29, 0, 18, 0, 24,
-  66, 1, 4, 0, 0, 0, 0, 0, 30, 14,
-  0, 50, 0, 7, 42, 0, 37, 0, 0, 0,
-  0, 48, 16, 0, 58, 78, 0, 0, 60, 0,
-  43, 4, 0, 14, 12, 0, 0, 2, 0, 24,
-  0, 6, 0, 25, 4, 0, 5, 84, 38, 0,
-  0, 3, 48, 0, 12, 5, 0, 1, 0, 12,
-  0, 2, 0, 0, 15, 0, 12, 0, 16, 0,
-  60, 0, 26, 0, 25, 0, 32, 14, 0, 17,
-  0, 0, 0, 0, 0, 0, 1, 1, 16, 0,
-  0, 0, 49, 11, 3, 0, 0, 29, 0, 16,
-  72, 0, 37, 30, 0, 0, 0, 15, 79, 12,
-  0, 0, 0, 13, 41, 0, 0, 0, 0, 11,
-  0, 105, 32, 28, 0, 0, 0, 8, 36, 0,
-  22, 20, 3, 0, 0, 0, 87, 22, 0, 54,
-  0, 0, 130, 30, 67, 49, 31, 0, 0, 36,
-  0, 0, 48, 46, 0, 0, 36, 0, 58, 28,
-  0, 42, 0, 0, 0, 0, 0, 73, 0, 0,
-  0, 0, 0, 0, 0, 113, 49, 57, 10, 33,
-  35, 37, 0, 0, 24, 0, 0, 52, 0, 0,
-  0, 0, 4, 0, 10, 0, 8, 0, 23, 0,
-  0, 0, 31, 19, 0, 1, 0, 0, 0, 57,
-  0, 18, 70, 15, 0, 4, 0, 0, 0, 50,
-  13, 20, 0, 0, 47, 47, 29, 12, 0, 0,
-  0, 10, 0, 0, 0, 0, 50, 0, 0, 44,
-  0, 64, 0, 0, 54, 0, 0, 47, 0, 99,
-  16, 46, 0, 15, 0, 37, 0, 0, 63, 0,
-  74, 0, 64, 0, 0, 62, 0, 0, 90, 0,
-  0, 12, 30, 23, 61, 0, 70, 60, 0, 76,
-  0, 1, 0, 0, 21, 0, 0, 0, 0, 0,
-  8, 0, 5, 0, 0, 121, 9, 0, 0, 0,
-  0, 0, 20, 54, 116, 17, 0, 0, 0, 0,
-  11, 9, 0, 21, 0, 19, 0, 73, 0, 0,
-  0, 0, 56, 0, 53, 0, 0, 0, 21, 0,
-  18, 0, 0, 48, 16, 0, 0, 0, 50, 44,
-  75, 3, 3, 42, 110, 0, 16, 61, 79, 13,
-  2, 0, 31, 54, 4, 6, 49, 0, 0, 45,
-  0, 0, 0, 0, 83, 0, 2, 0, 0, 62,
-  0, 80, 0, 35, 4, 49, 18, 97, 6, 35,
-  0, 42, 0, 40, 48, 0, 23, 0, 3, 0,
-  0, 0, 0, 5, 0, 59, 0, 17, 20, 0,
-  40, 0, 0, 0, 0, 48, 8, 0, 29, 54,
-  0, 0, 33, 0, 42, 5, 0, 9, 4, 0,
-  0, 8, 0, 4, 0, 44, 0, 13, 5, 8,
-  15, 84, 41, 0, 0, 0, 34, 0, 24, 13,
-  4, 22, 0, 21, 0, 22, 0, 0, 0, 0,
-  35, 0, 31, 0, 111, 0, 71, 0, 32, 0,
-  3, 37, 0, 0, 14, 0, 32, 0, 0, 0,
-  3, 23, 56, 0, 0, 4, 62, 15, 4, 0,
-  0, 72, 0, 17, 107, 0, 0, 48, 0, 0,
-  0, 48, 90, 0, 0, 0, 0, 51, 43, 7,
-  0, 46, 21, 29, 25, 100, 41, 0, 0, 5,
-  0, 0, 5, 0, 27, 0, 7, 0, 20, 2,
-  58, 63, 0, 50, 0, 0, 97, 52, 73, 0,
-  0, 0, 9, 20, 30, 0, 53, 59, 0, 0,
-  0, 0, 39, 57, 10, 31, 0, 0, 0, 14,
-  0, 0, 0, 54, 0, 21, 0, 18, 0, 113,
-  24, 11, 22, 20, 39, 43, 10, 0, 43, 0,
-  0, 50, 0, 0, 0, 0, 10, 1, 48, 0,
-  7, 0, 27, 0, 30, 0, 30, 47, 0, 0,
-  0, 25, 0, 135, 0, 7, 42, 0, 0, 4,
-  0, 6, 0, 0, 0, 25, 13, 0, 41, 106,
-  15, 0, 0, 0, 0, 1, 0, 0, 0, 1,
-  9, 0, 0, 82, 0, 40, 0, 0, 45, 0,
-  0, 46, 0, 80, 0, 4, 0, 0, 0, 52,
-  0, 0, 133, 36, 44, 0, 57, 0, 0, 92,
-  42, 0, 155, 0, 0, 30, 0, 77, 196, 0,
-  59, 34, 0, 31, 0, 16, 9, 0, 0, 0,
-  35, 0, 0, 0, 1, 0, 11, 0, 0, 92,
-  0, 0, 27, 0, 0, 0, 7, 76, 78, 108,
-  0, 0, 0, 0, 0, 30, 0, 0, 0, 38,
-  0, 95, 0, 0, 0, 0, 52, 0, 0, 0,
-  0, 0, 21, 0, 0, 6, 0, 28, 0, 8,
-  0, 24, 24, 29, 104, 12, 0, 37, 106, 0,
-  0, 105, 62, 22, 0, 0, 41, 62, 0, 12,
-  2, 0, 0, 43, 0, 0, 0, 0, 76, 0,
-  33, 0, 0, 91, 0, 53, 32, 0, 4, 39,
-  5, 115, 2, 34, 0, 36, 0, 56, 16, 0,
-  56, 0, 6, 0, 36, 0, 0, 14, 0, 21,
-  0, 0, 0, 0, 27, 0, 37, 0, 47, 52,
-  0, 14, 8, 31, 0, 0, 8, 0, 29, 0,
-  0, 10, 11, 0, 20, 0, 0, 68, 0, 34,
-  0, 0, 0, 0, 26, 84, 90, 0, 0, 0,
-  22, 0, 15, 31, 0, 34, 0, 30, 0, 52,
-  0, 0, 0, 0, 60, 0, 39, 0, 79, 0,
-  69, 0, 34, 16, 0, 39, 58, 0, 0, 0,
-  35, 20, 76, 0, 11, 39, 97, 0, 0, 94,
-  63, 17, 0, 0, 0, 47, 11, 21, 63, 0,
-  0, 58, 0, 0, 0, 24, 97, 0, 27, 0,
-  0, 89, 26, 22, 38, 4, 46, 33, 23, 117,
-  42, 0, 0, 22, 0, 0, 14, 0, 32, 0,
-  5, 0, 47, 0, 0, 49, 0, 19, 0, 0,
-  17, 1, 30, 0, 0, 0, 56, 43, 10, 31,
-  22, 65, 0, 0, 6, 0, 19, 88, 0, 42,
-  0, 0, 0, 23, 0, 11, 0, 31, 0, 0,
-  0, 0, 0, 85, 98, 0, 0, 0, 13, 0,
-  31, 29, 0, 24, 0, 19, 0, 5, 0, 0,
-  0, 12, 70, 0, 0, 0, 32, 0, 63, 0,
-  24, 34, 0, 27, 0, 6, 0, 0, 33, 17,
-  40, 0, 12, 29, 62, 0, 14, 33, 65, 28,
-  0, 0, 26, 32, 26, 12, 42, 0, 0, 27,
-  0, 0, 0, 0, 69, 0, 0, 0, 0, 14,
-  0, 40, 0, 14, 0, 40, 23, 88, 0, 29,
-  0, 18, 0, 24, 66, 1, 4, 0, 0, 0,
-  0, 0, 30, 14, 0, 50, 0, 7, 42, 0,
-  37, 0, 0, 0, 0, 48, 16, 0, 58, 78,
-  0, 0, 60, 0, 43, 4, 0, 14, 12, 0,
-  0, 2, 0, 24, 0, 6, 0, 25, 4, 0,
-  5, 84, 38, 0, 0, 3, 48, 0, 12, 5,
-  0, 1, 0, 12, 0, 2, 0, 0, 15, 0,
-  12, 0, 16, 0, 60, 0, 26, 0, 25, 0,
-  32, 14, 0, 17, 0, 0, 0, 0, 0, 0,
-  1, 1, 16, 0, 0, 0, 49, 11, 3, 0,
-  0, 29, 0, 16, 72, 0, 37, 30, 0, 0,
-  0, 15, 79, 12, 0, 0, 0, 13, 41, 0,
-  0, 0, 0, 11, 0, 105, 32, 28, 0, 0,
-  0, 8, 36, 0, 22, 20, 3, 0, 0, 0,
-  87, 22, 0, 54, 0, 0, 130, 30, 67, 49,
-  31, 0, 0, 36, 0, 0, 48, 46, 0, 0,
-  36, 0, 58, 28, 0, 42, 0, 0, 0, 0,
-  0, 73, 0, 0, 0, 0, 0, 0, 0, 113,
-  49, 57, 10, 33, 35, 37, 0, 0, 24, 0,
-  0, 52, 0, 0, 0, 0, 4, 0, 10, 0,
-  8, 0, 23, 0, 0, 0, 31, 19, 12, 13,
-  0, 21, 6, 5, 0, 0, 11, 0, 0, 0,
-  48, 0, 0, 18, 58, 12, 0, 0, 0, 8,
-  0, 28, 33, 0, 31, 20, 0, 0, 0, 2,
-  67, 50, 0, 0, 0, 26, 49, 0, 0, 0,
-  0, 31, 0, 97, 52, 74, 0, 0, 0, 36,
-  26, 0, 0, 44, 0, 0, 0, 0, 64, 9,
-  0, 12, 0, 0, 87, 26, 88, 48, 67, 0,
-  0, 16, 0, 0, 28, 0, 0, 0, 33, 0,
-  46, 22, 0, 32, 0, 0, 2, 0, 0, 84,
-  0, 0, 12, 0, 0, 0, 1, 115, 49, 54,
-  0, 40, 17, 26, 0, 0, 9, 0, 0, 49,
-  0, 16, 0, 0, 0, 0, 29, 0, 1, 0,
-  46, 0, 0, 0, 33, 16, 0, 48, 16, 0,
-  0, 0, 50, 44, 75, 3, 3, 42, 110, 0,
-  16, 61, 79, 13, 2, 0, 31, 54, 4, 6,
-  49, 0, 0, 45, 0, 0, 0, 0, 83, 0,
-  2, 0, 0, 62, 0, 80, 0, 35, 4, 49,
-  18, 97, 6, 35, 0, 42, 0, 40, 48, 0,
-  23, 0, 3, 0, 0, 0, 0, 5, 0, 59,
-  0, 17, 20, 0, 40, 0, 0, 0, 0, 48,
-  8, 0, 29, 54, 0, 0, 33, 0, 42, 5,
-  0, 9, 4, 0, 0, 8, 0, 4, 0, 44,
-  0, 13, 5, 8, 15, 84, 41, 0, 0, 0,
-  34, 0, 24, 13, 4, 22, 0, 21, 0, 22,
-  0, 0, 0, 0, 35, 0, 31, 0, 111, 0,
-  71, 0, 32, 0, 3, 37, 0, 0, 14, 0,
-  32, 0, 0, 0, 3, 23, 56, 0, 0, 4,
-  62, 15, 4, 0, 0, 72, 0, 17, 107, 0,
-  0, 48, 0, 0, 0, 48, 90, 0, 0, 0,
-  0, 51, 43, 7, 0, 46, 21, 29, 25, 100,
-  41, 0, 0, 5, 0, 0, 5, 0, 27, 0,
-  7, 0, 20, 2, 58, 63, 0, 50, 0, 0,
-  97, 52, 73, 0, 0, 0, 9, 20, 30, 0,
-  53, 59, 0, 0, 0, 0, 39, 57, 10, 31,
-  0, 0, 0, 14, 0, 0, 0, 54, 0, 21,
-  0, 18, 0, 113, 24, 11, 22, 20, 39, 43,
-  10, 0, 43, 0, 0, 50, 0, 0, 0, 0,
-  10, 1, 48, 0, 7, 0, 27, 0, 30, 0,
-  30, 47, 0, 22, 0, 0, 13, 12, 20, 0,
-  30, 0, 12, 20, 47, 4, 0, 16, 61, 0,
-  3, 0, 0, 56, 0, 10, 36, 0, 0, 41,
-  0, 0, 2, 0, 51, 24, 0, 0, 0, 75,
-  57, 0, 0, 1, 0, 46, 0, 115, 40, 68,
-  0, 0, 0, 16, 0, 0, 30, 32, 30, 0,
-  49, 0, 37, 54, 0, 31, 7, 0, 25, 63,
-  98, 0, 89, 0, 26, 32, 28, 22, 29, 0,
-  0, 0, 0, 0, 23, 34, 22, 43, 0, 13,
-  0, 0, 0, 67, 0, 29, 0, 0, 0, 0,
-  28, 122, 64, 34, 0, 28, 14, 55, 5, 5,
-  0, 0, 0, 59, 0, 9, 0, 5, 0, 38,
-  80, 0, 0, 0, 7, 0, 12, 0, 22, 22,
-  0, 28, 0, 8, 0, 24, 24, 29, 104, 12,
-  0, 37, 106, 0, 0, 105, 62, 22, 0, 0,
-  41, 62, 0, 12, 2, 0, 0, 43, 0, 0,
-  0, 0, 76, 0, 33, 0, 0, 91, 0, 53,
-  32, 0, 4, 39, 5, 115, 2, 34, 0, 36,
-  0, 56, 16, 0, 56, 0, 6, 0, 36, 0,
-  0, 14, 0, 21, 0, 0, 0, 0, 27, 0,
-  37, 0, 47, 52, 0, 14, 8, 31, 0, 0,
-  8, 0, 29, 0, 0, 10, 11, 0, 20, 0,
-  0, 68, 0, 34, 0, 0, 0, 0, 26, 84,
-  90, 0, 0, 0, 22, 0, 15, 31, 0, 34,
-  0, 30, 0, 52, 0, 0, 0, 0, 60, 0,
-  39, 0, 79, 0, 69, 0, 34, 16, 0, 39,
-  58, 0, 0, 0, 35, 20, 76, 0, 11, 39,
-  97, 0, 0, 94, 63, 17, 0, 0, 0, 47,
-  11, 21, 63, 0, 0, 58, 0, 0, 0, 24,
-  97, 0, 27, 0, 0, 89, 26, 22, 38, 4,
-  46, 33, 23, 117, 42, 0, 0, 22, 0, 0,
-  14, 0, 32, 0, 5, 0, 47, 0, 0, 49,
-  0, 19, 0, 0, 17, 1, 30, 0, 0, 0,
-  56, 43, 10, 31, 22, 65, 0, 0, 6, 0,
-  19, 88, 0, 42, 0, 0, 0, 23, 0, 11,
-  0, 31, 0, 0, 0, 0, 0, 85, 98, 0,
-  0, 0, 13, 0, 31, 29, 0, 24, 0, 19,
-  0, 5, 0, 0, 0, 12, 70, 0, 0, 0,
-  32, 0, 63, 0, 24, 34, 0, 10, 0, 0,
-  0, 0, 0, 1, 32, 2, 16, 56, 0, 30,
-  0, 9, 3, 0, 2, 0, 1, 27, 71, 20,
-  5, 0, 0, 23, 0, 18, 0, 0, 30, 0,
-  15, 0, 59, 84, 34, 0, 85, 0, 0, 5,
-  0, 98, 39, 10, 0, 0, 0, 0, 0, 0,
-  57, 0, 55, 0, 96, 0, 0, 81, 9, 12,
-  28, 9, 50, 46, 29, 21, 0, 0, 85, 58,
-  7, 94, 37, 18, 0, 0, 0, 22, 0, 74,
-  0, 50, 11, 36, 0, 0, 0, 84, 19, 16,
-  0, 0, 0, 0, 17, 49, 89, 0, 0, 0,
-  0, 27, 5, 0, 0, 3, 0, 9, 0, 9,
-  21, 75, 0, 33, 64, 0, 0, 0, 0, 0,
-  0, 0, 0, 41, 32, 14, 0, 17, 0, 0,
-  0, 0, 0, 0, 1, 1, 16, 0, 0, 0,
-  49, 11, 3, 0, 0, 29, 0, 16, 72, 0,
-  37, 30, 0, 0, 0, 15, 79, 12, 0, 0,
-  0, 13, 41, 0, 0, 0, 0, 11, 0, 105,
-  32, 28, 0, 0, 0, 8, 36, 0, 22, 20,
-  3, 0, 0, 0, 87, 22, 0, 54, 0, 0,
-  130, 30, 67, 49, 31, 0, 0, 36, 0, 0,
-  48, 46, 0, 0, 36, 0, 58, 28, 0, 42,
-  0, 0, 0, 0, 0, 73, 0, 0, 0, 0,
-  0, 0, 0, 113, 49, 57, 10, 33, 35, 37,
-  0, 0, 24, 0, 0, 52, 0, 0, 0, 0,
-  4, 0, 10, 0, 8, 0, 23, 0, 0, 0,
-  31, 19, 12, 13, 0, 21, 6, 5, 0, 0,
-  11, 0, 0, 0, 48, 0, 0, 18, 58, 12,
-  0, 0, 0, 8, 0, 28, 33, 0, 31, 20,
-  0, 0, 0, 2, 67, 50, 0, 0, 0, 26,
-  49, 0, 0, 0, 0, 31, 0, 97, 52, 74,
-  0, 0, 0, 36, 26, 0, 0, 44, 0, 0,
-  0, 0, 64, 9, 0, 12, 0, 0, 87, 26,
-  88, 48, 67, 0, 0, 16, 0, 0, 28, 0,
-  0, 0, 33, 0, 46, 22, 0, 32, 0, 0,
-  2, 0, 0, 84, 0, 0, 12, 0, 0, 0,
-  1, 115, 49, 54, 0, 40, 17, 26, 0, 0,
-  9, 0, 0, 49, 0, 16, 0, 0, 0, 0,
-  29, 0, 1, 0, 46, 0, 0, 0, 33, 16,
-  0, 98, 0, 20, 14, 0, 60, 12, 44, 16,
-  32, 0, 54, 0, 44, 107, 104, 30, 6, 0,
-  0, 0, 0, 40, 41, 45, 0, 53, 0, 0,
-  0, 0, 87, 64, 0, 0, 0, 27, 0, 41,
-  0, 0, 16, 28, 30, 44, 24, 53, 0, 28,
-  0, 0, 87, 10, 0, 0, 0, 14, 0, 58,
-  10, 0, 0, 24, 0, 0, 75, 0, 41, 0,
-  0, 0, 0, 48, 17, 40, 0, 0, 0, 12,
-  73, 0, 9, 26, 0, 32, 2, 2, 0, 43,
-  49, 36, 0, 65, 0, 26, 0, 0, 0, 86,
-  27, 0, 0, 0, 9, 0, 28, 10, 24, 30,
-  0, 17, 0, 27, 0, 0, 0, 0, 2, 0,
-  8, 0, 164, 0, 52, 9, 40, 0, 3, 37,
-  0, 0, 14, 0, 32, 0, 0, 0, 3, 23,
-  56, 0, 0, 4, 62, 15, 4, 0, 0, 72,
-  0, 17, 107, 0, 0, 48, 0, 0, 0, 48,
-  90, 0, 0, 0, 0, 51, 43, 7, 0, 46,
-  21, 29, 25, 100, 41, 0, 0, 5, 0, 0,
-  5, 0, 27, 0, 7, 0, 20, 2, 58, 63,
-  0, 50, 0, 0, 97, 52, 73, 0, 0, 0,
-  9, 20, 30, 0, 53, 59, 0, 0, 0, 0,
-  39, 57, 10, 31, 0, 0, 0, 14, 0, 0,
-  0, 54, 0, 21, 0, 18, 0, 113, 24, 11,
-  22, 20, 39, 43, 10, 0, 43, 0, 0, 50,
-  0, 0, 0, 0, 10, 1, 48, 0, 7, 0,
-  27, 0, 30, 0, 30, 47, 0, 22, 0, 0,
-  13, 12, 20, 0, 30, 0, 12, 20, 47, 4,
-  0, 16, 61, 0, 3, 0, 0, 56, 0, 10,
-  36, 0, 0, 41, 0, 0, 2, 0, 51, 24,
-  0, 0, 0, 75, 57, 0, 0, 1, 0, 46,
-  0, 115, 40, 68, 0, 0, 0, 16, 0, 0,
-  30, 32, 30, 0, 49, 0, 37, 54, 0, 31,
-  7, 0, 25, 63, 98, 0, 89, 0, 26, 32,
-  28, 22, 29, 0, 0, 0, 0, 0, 23, 34,
-  22, 43, 0, 13, 0, 0, 0, 67, 0, 29,
-  0, 0, 0, 0, 28, 122, 64, 34, 0, 28,
-  14, 55, 5, 5, 0, 0, 0, 59, 0, 9,
-  0, 5, 0, 38, 80, 0, 0, 0, 7, 0,
-  12, 0, 22, 22, 0, 49, 0, 0, 0, 0,
-  12, 0, 80, 43, 25, 0, 73, 2, 0, 149,
-  100, 43, 17, 0, 0, 0, 0, 25, 0, 0,
-  21, 90, 9, 0, 9, 0, 115, 13, 0, 0,
-  4, 73, 0, 0, 23, 0, 0, 26, 0, 80,
-  0, 54, 0, 37, 0, 15, 61, 0, 0, 23,
-  13, 7, 0, 32, 0, 0, 0, 0, 0, 0,
-  27, 12, 61, 0, 7, 0, 0, 98, 0, 66,
-  0, 13, 0, 0, 19, 3, 24, 48, 0, 47,
-  3, 23, 13, 19, 53, 124, 0, 32, 23, 0,
-  0, 0, 0, 90, 142, 0, 0, 0, 8, 0,
-  0, 33, 0, 34, 0, 47, 0, 22, 0, 0,
-  0, 0, 6, 0, 0, 0, 122, 0, 29, 0,
-  52, 16, 0, 39, 58, 0, 0, 0, 35, 20,
-  76, 0, 11, 39, 97, 0, 0, 94, 63, 17,
-  0, 0, 0, 47, 11, 21, 63, 0, 0, 58,
-  0, 0, 0, 24, 97, 0, 27, 0, 0, 89,
-  26, 22, 38, 4, 46, 33, 23, 117, 42, 0,
-  0, 22, 0, 0, 14, 0, 32, 0, 5, 0,
-  47, 0, 0, 49, 0, 19, 0, 0, 17, 1,
-  30, 0, 0, 0, 56, 43, 10, 31, 22, 65,
-  0, 0, 6, 0, 19, 88, 0, 42, 0, 0,
-  0, 23, 0, 11, 0, 31, 0, 0, 0, 0,
-  0, 85, 98, 0, 0, 0, 13, 0, 31, 29,
-  0, 24, 0, 19, 0, 5, 0, 0, 0, 12,
-  70, 0, 0, 0, 32, 0, 63, 0, 24, 34,
-  0, 10, 0, 0, 0, 0, 0, 1, 32, 2,
-  16, 56, 0, 30, 0, 9, 3, 0, 2, 0,
-  1, 27, 71, 20, 5, 0, 0, 23, 0, 18,
-  0, 0, 30, 0, 15, 0, 59, 84, 34, 0,
-  85, 0, 0, 5, 0, 98, 39, 10, 0, 0,
-  0, 0, 0, 0, 57, 0, 55, 0, 96, 0,
-  0, 81, 9, 12, 28, 9, 50, 46, 29, 21,
-  0, 0, 85, 58, 7, 94, 37, 18, 0, 0,
-  0, 22, 0, 74, 0, 50, 11, 36, 0, 0,
-  0, 84, 19, 16, 0, 0, 0, 0, 17, 49,
-  89, 0, 0, 0, 0, 27, 5, 0, 0, 3,
-  0, 9, 0, 9, 21, 75, 0, 33, 64, 0,
-  0, 0, 0, 0, 0, 0, 0, 41, 4, 18,
-  11, 6, 0, 0, 0, 0, 60, 44, 0, 0,
-  0, 54, 0, 0, 0, 29, 17, 0, 3, 11,
-  34, 17, 0, 0, 58, 48, 0, 0, 0, 0,
-  53, 0, 0, 0, 74, 109, 0, 0, 46, 0,
-  0, 0, 0, 59, 0, 51, 0, 23, 0, 0,
-  0, 0, 78, 7, 34, 8, 0, 0, 0, 52,
-  29, 14, 74, 2, 53, 17, 8, 144, 9, 0,
-  46, 89, 0, 57, 27, 0, 12, 0, 0, 0,
-  31, 87, 0, 30, 0, 43, 20, 0, 0, 171,
-  0, 0, 22, 0, 7, 0, 0, 57, 123, 33,
-  0, 0, 0, 0, 0, 2, 0, 0, 0, 24,
-  0, 10, 20, 24, 0, 0, 14, 0, 0, 0,
-  0, 0, 0, 4, 58, 62, 12, 13, 0, 21,
-  6, 5, 0, 0, 11, 0, 0, 0, 48, 0,
-  0, 18, 58, 12, 0, 0, 0, 8, 0, 28,
-  33, 0, 31, 20, 0, 0, 0, 2, 67, 50,
-  0, 0, 0, 26, 49, 0, 0, 0, 0, 31,
-  0, 97, 52, 74, 0, 0, 0, 36, 26, 0,
-  0, 44, 0, 0, 0, 0, 64, 9, 0, 12,
-  0, 0, 87, 26, 88, 48, 67, 0, 0, 16,
-  0, 0, 28, 0, 0, 0, 33, 0, 46, 22,
-  0, 32, 0, 0, 2, 0, 0, 84, 0, 0,
-  12, 0, 0, 0, 1, 115, 49, 54, 0, 40,
-  17, 26, 0, 0, 9, 0, 0, 49, 0, 16,
-  0, 0, 0, 0, 29, 0, 1, 0, 46, 0,
-  0, 0, 33, 16, 0, 98, 0, 20, 14, 0,
-  60, 12, 44, 16, 32, 0, 54, 0, 44, 107,
-  104, 30, 6, 0, 0, 0, 0, 40, 41, 45,
-  0, 53, 0, 0, 0, 0, 87, 64, 0, 0,
-  0, 27, 0, 41, 0, 0, 16, 28, 30, 44,
-  24, 53, 0, 28, 0, 0, 87, 10, 0, 0,
-  0, 14, 0, 58, 10, 0, 0, 24, 0, 0,
-  75, 0, 41, 0, 0, 0, 0, 48, 17, 40,
-  0, 0, 0, 12, 73, 0, 9, 26, 0, 32,
-  2, 2, 0, 43, 49, 36, 0, 65, 0, 26,
-  0, 0, 0, 86, 27, 0, 0, 0, 9, 0,
-  28, 10, 24, 30, 0, 17, 0, 27, 0, 0,
-  0, 0, 2, 0, 8, 0, 164, 0, 52, 9,
-  40, 0, 0, 111, 49, 4, 4, 0, 0, 13,
-  78, 36, 24, 0, 20, 0, 0, 97, 83, 24,
-  24, 5, 0, 0, 48, 50, 0, 0, 1, 78,
-  1, 0, 0, 0, 68, 0, 12, 0, 0, 28,
-  0, 3, 0, 0, 11, 19, 11, 36, 0, 0,
-  0, 29, 0, 18, 44, 0, 0, 0, 1, 0,
-  0, 8, 0, 0, 0, 0, 0, 0, 29, 0,
-  0, 0, 0, 0, 32, 72, 9, 90, 0, 112,
-  2, 20, 35, 0, 0, 53, 0, 31, 6, 61,
-  21, 24, 117, 0, 0, 0, 26, 0, 0, 0,
-  0, 100, 90, 0, 0, 0, 7, 0, 54, 21,
-  0, 21, 0, 0, 0, 15, 0, 0, 0, 0,
-  0, 21, 0, 0, 73, 0, 76, 10, 35, 0,
-  0, 22, 0, 0, 13, 12, 20, 0, 30, 0,
-  12, 20, 47, 4, 0, 16, 61, 0, 3, 0,
-  0, 56, 0, 10, 36, 0, 0, 41, 0, 0,
-  2, 0, 51, 24, 0, 0, 0, 75, 57, 0,
-  0, 1, 0, 46, 0, 115, 40, 68, 0, 0,
-  0, 16, 0, 0, 30, 32, 30, 0, 49, 0,
-  37, 54, 0, 31, 7, 0, 25, 63, 98, 0,
-  89, 0, 26, 32, 28, 22, 29, 0, 0, 0,
-  0, 0, 23, 34, 22, 43, 0, 13, 0, 0,
-  0, 67, 0, 29, 0, 0, 0, 0, 28, 122,
-  64, 34, 0, 28, 14, 55, 5, 5, 0, 0,
-  0, 59, 0, 9, 0, 5, 0, 38, 80, 0,
-  0, 0, 7, 0, 12, 0, 22, 22, 0, 49,
-  0, 0, 0, 0, 12, 0, 80, 43, 25, 0,
-  73, 2, 0, 149, 100, 43, 17, 0, 0, 0,
-  0, 25, 0, 0, 21, 90, 9, 0, 9, 0,
-  115, 13, 0, 0, 4, 73, 0, 0, 23, 0,
-  0, 26, 0, 80, 0, 54, 0, 37, 0, 15,
-  61, 0, 0, 23, 13, 7, 0, 32, 0, 0,
-  0, 0, 0, 0, 27, 12, 61, 0, 7, 0,
-  0, 98, 0, 66, 0, 13, 0, 0, 19, 3,
-  24, 48, 0, 47, 3, 23, 13, 19, 53, 124,
-  0, 32, 23, 0, 0, 0, 0, 90, 142, 0,
-  0, 0, 8, 0, 0, 33, 0, 34, 0, 47,
-  0, 22, 0, 0, 0, 0, 6, 0, 0, 0,
-  122, 0, 29, 0, 52, 16, 0, 27, 108, 0,
-  0, 0, 0, 0, 90, 42, 15, 0, 26, 53,
-  0, 84, 60, 35, 50, 0, 0, 15, 20, 31,
-  0, 0, 3, 111, 0, 0, 0, 0, 61, 0,
-  0, 0, 0, 79, 0, 0, 3, 0, 0, 0,
-  0, 28, 0, 0, 0, 35, 0, 82, 11, 0,
-  69, 0, 27, 18, 0, 0, 0, 0, 0, 0,
-  27, 0, 48, 0, 11, 70, 0, 0, 22, 90,
-  0, 69, 0, 68, 0, 0, 7, 0, 32, 92,
-  0, 47, 0, 58, 48, 0, 85, 34, 0, 0,
-  11, 0, 0, 0, 0, 133, 125, 0, 0, 0,
-  8, 0, 0, 61, 0, 16, 7, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 45, 0,
-  54, 0, 21, 46, 0, 10, 0, 0, 0, 0,
-  0, 1, 32, 2, 16, 56, 0, 30, 0, 9,
-  3, 0, 2, 0, 1, 27, 71, 20, 5, 0,
-  0, 23, 0, 18, 0, 0, 30, 0, 15, 0,
-  59, 84, 34, 0, 85, 0, 0, 5, 0, 98,
-  39, 10, 0, 0, 0, 0, 0, 0, 57, 0,
-  55, 0, 96, 0, 0, 81, 9, 12, 28, 9,
-  50, 46, 29, 21, 0, 0, 85, 58, 7, 94,
-  37, 18, 0, 0, 0, 22, 0, 74, 0, 50,
-  11, 36, 0, 0, 0, 84, 19, 16, 0, 0,
-  0, 0, 17, 49, 89, 0, 0, 0, 0, 27,
-  5, 0, 0, 3, 0, 9, 0, 9, 21, 75,
-  0, 33, 64, 0, 0, 0, 0, 0, 0, 0,
-  0, 41, 4, 18, 11, 6, 0, 0, 0, 0,
-  60, 44, 0, 0, 0, 54, 0, 0, 0, 29,
-  17, 0, 3, 11, 34, 17, 0, 0, 58, 48,
-  0, 0, 0, 0, 53, 0, 0, 0, 74, 109,
-  0, 0, 46, 0, 0, 0, 0, 59, 0, 51,
-  0, 23, 0, 0, 0, 0, 78, 7, 34, 8,
-  0, 0, 0, 52, 29, 14, 74, 2, 53, 17,
-  8, 144, 9, 0, 46, 89, 0, 57, 27, 0,
-  12, 0, 0, 0, 31, 87, 0, 30, 0, 43,
-  20, 0, 0, 171, 0, 0, 22, 0, 7, 0,
-  0, 57, 123, 33, 0, 0, 0, 0, 0, 2,
-  0, 0, 0, 24, 0, 10, 20, 24, 0, 0,
-  14, 0, 0, 0, 0, 0, 0, 4, 58, 62,
-  28, 0, 51, 0, 0, 127, 0, 0, 28, 13,
-  0, 0, 0, 82, 0, 0, 9, 29, 31, 0,
-  0, 85, 28, 32, 0, 0, 13, 55, 0, 0,
-  0, 43, 0, 0, 0, 17, 44, 93, 0, 0,
-  24, 0, 15, 0, 0, 32, 0, 29, 0, 35,
-  0, 77, 0, 0, 138, 0, 12, 0, 0, 0,
-  0, 64, 0, 0, 81, 0, 9, 6, 12, 125,
-  8, 0, 33, 55, 0, 39, 22, 0, 0, 0,
-  0, 0, 28, 82, 0, 10, 0, 46, 0, 0,
-  0, 123, 0, 0, 55, 0, 11, 0, 0, 88,
-  63, 49, 0, 0, 27, 0, 0, 10, 0, 6,
-  1, 11, 0, 0, 9, 35, 24, 0, 11, 0,
-  0, 0, 0, 0, 0, 3, 9, 79, 0, 98,
-  0, 20, 14, 0, 60, 12, 44, 16, 32, 0,
-  54, 0, 44, 107, 104, 30, 6, 0, 0, 0,
-  0, 40, 41, 45, 0, 53, 0, 0, 0, 0,
-  87, 64, 0, 0, 0, 27, 0, 41, 0, 0,
-  16, 28, 30, 44, 24, 53, 0, 28, 0, 0,
-  87, 10, 0, 0, 0, 14, 0, 58, 10, 0,
-  0, 24, 0, 0, 75, 0, 41, 0, 0, 0,
-  0, 48, 17, 40, 0, 0, 0, 12, 73, 0,
-  9, 26, 0, 32, 2, 2, 0, 43, 49, 36,
-  0, 65, 0, 26, 0, 0, 0, 86, 27, 0,
-  0, 0, 9, 0, 28, 10, 24, 30, 0, 17,
-  0, 27, 0, 0, 0, 0, 2, 0, 8, 0,
-  164, 0, 52, 9, 40, 0, 0, 111, 49, 4,
-  4, 0, 0, 13, 78, 36, 24, 0, 20, 0,
-  0, 97, 83, 24, 24, 5, 0, 0, 48, 50,
-  0, 0, 1, 78, 1, 0, 0, 0, 68, 0,
-  12, 0, 0, 28, 0, 3, 0, 0, 11, 19,
-  11, 36, 0, 0, 0, 29, 0, 18, 44, 0,
-  0, 0, 1, 0, 0, 8, 0, 0, 0, 0,
-  0, 0, 29, 0, 0, 0, 0, 0, 32, 72,
-  9, 90, 0, 112, 2, 20, 35, 0, 0, 53,
-  0, 31, 6, 61, 21, 24, 117, 0, 0, 0,
-  26, 0, 0, 0, 0, 100, 90, 0, 0, 0,
-  7, 0, 54, 21, 0, 21, 0, 0, 0, 15,
-  0, 0, 0, 0, 0, 21, 0, 0, 73, 0,
-  76, 10, 35, 0, 59, 1, 72, 42, 0, 0,
-  0, 22, 38, 13, 13, 6, 0, 7, 0, 21,
-  38, 13, 14, 0, 0, 64, 43, 11, 0, 0,
-  1, 54, 0, 38, 0, 39, 17, 0, 12, 19,
-  36, 29, 3, 0, 0, 0, 0, 0, 0, 11,
-  0, 0, 0, 0, 0, 70, 0, 0, 91, 0,
-  38, 0, 8, 0, 0, 4, 0, 0, 64, 10,
-  0, 0, 0, 114, 20, 0, 74, 27, 0, 45,
-  12, 51, 27, 0, 0, 0, 15, 101, 0, 21,
-  22, 36, 22, 0, 57, 0, 0, 0, 62, 0,
-  29, 0, 0, 72, 95, 0, 0, 0, 0, 80,
-  0, 16, 0, 0, 0, 13, 0, 0, 0, 0,
-  0, 0, 0, 33, 0, 3, 0, 0, 0, 0,
-  4, 22, 0, 49, 0, 0, 0, 0, 12, 0,
-  80, 43, 25, 0, 73, 2, 0, 149, 100, 43,
-  17, 0, 0, 0, 0, 25, 0, 0, 21, 90,
-  9, 0, 9, 0, 115, 13, 0, 0, 4, 73,
-  0, 0, 23, 0, 0, 26, 0, 80, 0, 54,
-  0, 37, 0, 15, 61, 0, 0, 23, 13, 7,
-  0, 32, 0, 0, 0, 0, 0, 0, 27, 12,
-  61, 0, 7, 0, 0, 98, 0, 66, 0, 13,
-  0, 0, 19, 3, 24, 48, 0, 47, 3, 23,
-  13, 19, 53, 124, 0, 32, 23, 0, 0, 0,
-  0, 90, 142, 0, 0, 0, 8, 0, 0, 33,
-  0, 34, 0, 47, 0, 22, 0, 0, 0, 0,
-  6, 0, 0, 0, 122, 0, 29, 0, 52, 16,
-  0, 27, 108, 0, 0, 0, 0, 0, 90, 42,
-  15, 0, 26, 53, 0, 84, 60, 35, 50, 0,
-  0, 15, 20, 31, 0, 0, 3, 111, 0, 0,
-  0, 0, 61, 0, 0, 0, 0, 79, 0, 0,
-  3, 0, 0, 0, 0, 28, 0, 0, 0, 35,
-  0, 82, 11, 0, 69, 0, 27, 18, 0, 0,
-  0, 0, 0, 0, 27, 0, 48, 0, 11, 70,
-  0, 0, 22, 90, 0, 69, 0, 68, 0, 0,
-  7, 0, 32, 92, 0, 47, 0, 58, 48, 0,
-  85, 34, 0, 0, 11, 0, 0, 0, 0, 133,
-  125, 0, 0, 0, 8, 0, 0, 61, 0, 16,
-  7, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 45, 0, 54, 0, 21, 46, 0, 0,
-  117, 0, 0, 75, 0, 0, 21, 0, 0, 1,
-  34, 80, 0, 0, 0, 31, 19, 0, 0, 94,
-  14, 24, 0, 0, 0, 29, 0, 0, 10, 39,
-  0, 0, 0, 0, 0, 56, 0, 0, 0, 0,
-  0, 7, 0, 0, 0, 0, 0, 0, 0, 155,
-  0, 0, 71, 0, 21, 0, 50, 0, 0, 5,
-  0, 0, 108, 0, 0, 0, 0, 98, 0, 0,
-  39, 7, 0, 0, 0, 22, 15, 0, 0, 0,
-  31, 74, 16, 3, 15, 30, 48, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 72, 30, 0,
-  0, 0, 0, 78, 0, 23, 0, 11, 40, 0,
-  0, 0, 17, 16, 68, 25, 10, 51, 0, 3,
-  0, 0, 33, 0, 0, 53, 4, 18, 11, 6,
-  0, 0, 0, 0, 60, 44, 0, 0, 0, 54,
-  0, 0, 0, 29, 17, 0, 3, 11, 34, 17,
-  0, 0, 58, 48, 0, 0, 0, 0, 53, 0,
-  0, 0, 74, 109, 0, 0, 46, 0, 0, 0,
-  0, 59, 0, 51, 0, 23, 0, 0, 0, 0,
-  78, 7, 34, 8, 0, 0, 0, 52, 29, 14,
-  74, 2, 53, 17, 8, 144, 9, 0, 46, 89,
-  0, 57, 27, 0, 12, 0, 0, 0, 31, 87,
-  0, 30, 0, 43, 20, 0, 0, 171, 0, 0,
-  22, 0, 7, 0, 0, 57, 123, 33, 0, 0,
-  0, 0, 0, 2, 0, 0, 0, 24, 0, 10,
-  20, 24, 0, 0, 14, 0, 0, 0, 0, 0,
-  0, 4, 58, 62, 28, 0, 51, 0, 0, 127,
-  0, 0, 28, 13, 0, 0, 0, 82, 0, 0,
-  9, 29, 31, 0, 0, 85, 28, 32, 0, 0,
-  13, 55, 0, 0, 0, 43, 0, 0, 0, 17,
-  44, 93, 0, 0, 24, 0, 15, 0, 0, 32,
-  0, 29, 0, 35, 0, 77, 0, 0, 138, 0,
-  12, 0, 0, 0, 0, 64, 0, 0, 81, 0,
-  9, 6, 12, 125, 8, 0, 33, 55, 0, 39,
-  22, 0, 0, 0, 0, 0, 28, 82, 0, 10,
-  0, 46, 0, 0, 0, 123, 0, 0, 55, 0,
-  11, 0, 0, 88, 63, 49, 0, 0, 27, 0,
-  0, 10, 0, 6, 1, 11, 0, 0, 9, 35,
-  24, 0, 11, 0, 0, 0, 0, 0, 0, 3,
-  9, 79, 0, 0, 30, 0, 26, 161, 0, 0,
-  0, 0, 0, 0, 49, 60, 0, 0, 11, 55,
-  0, 0, 7, 16, 0, 50, 0, 0, 0, 0,
-  0, 35, 21, 0, 0, 13, 0, 0, 0, 55,
-  0, 3, 0, 20, 0, 22, 0, 12, 34, 22,
-  0, 0, 13, 103, 4, 0, 17, 0, 10, 0,
-  46, 0, 0, 0, 0, 0, 54, 0, 0, 2,
-  0, 4, 0, 34, 24, 5, 0, 40, 0, 0,
-  0, 10, 0, 0, 18, 36, 19, 0, 31, 36,
-  38, 0, 0, 22, 13, 0, 4, 0, 0, 0,
-  1, 46, 1, 0, 0, 0, 0, 10, 0, 22,
-  0, 25, 23, 0, 0, 0, 5, 29, 102, 47,
-  32, 3, 54, 0, 0, 0, 37, 15, 0, 14,
-  0, 111, 49, 4, 4, 0, 0, 13, 78, 36,
-  24, 0, 20, 0, 0, 97, 83, 24, 24, 5,
-  0, 0, 48, 50, 0, 0, 1, 78, 1, 0,
-  0, 0, 68, 0, 12, 0, 0, 28, 0, 3,
-  0, 0, 11, 19, 11, 36, 0, 0, 0, 29,
-  0, 18, 44, 0, 0, 0, 1, 0, 0, 8,
-  0, 0, 0, 0, 0, 0, 29, 0, 0, 0,
-  0, 0, 32, 72, 9, 90, 0, 112, 2, 20,
-  35, 0, 0, 53, 0, 31, 6, 61, 21, 24,
-  117, 0, 0, 0, 26, 0, 0, 0, 0, 100,
-  90, 0, 0, 0, 7, 0, 54, 21, 0, 21,
-  0, 0, 0, 15, 0, 0, 0, 0, 0, 21,
-  0, 0, 73, 0, 76, 10, 35, 0, 59, 1,
-  72, 42, 0, 0, 0, 22, 38, 13, 13, 6,
-  0, 7, 0, 21, 38, 13, 14, 0, 0, 64,
-  43, 11, 0, 0, 1, 54, 0, 38, 0, 39,
-  17, 0, 12, 19, 36, 29, 3, 0, 0, 0,
-  0, 0, 0, 11, 0, 0, 0, 0, 0, 70,
-  0, 0, 91, 0, 38, 0, 8, 0, 0, 4,
-  0, 0, 64, 10, 0, 0, 0, 114, 20, 0,
-  74, 27, 0, 45, 12, 51, 27, 0, 0, 0,
-  15, 101, 0, 21, 22, 36, 22, 0, 57, 0,
-  0, 0, 62, 0, 29, 0, 0, 72, 95, 0,
-  0, 0, 0, 80, 0, 16, 0, 0, 0, 13,
-  0, 0, 0, 0, 0, 0, 0, 33, 0, 3,
-  0, 0, 0, 0, 4, 22, 21, 0, 99, 34,
-  0, 157, 0, 0, 0, 0, 0, 17, 14, 49,
-  0, 0, 14, 40, 0, 1, 5, 82, 30, 0,
-  0, 0, 0, 0, 0, 147, 4, 78, 0, 24,
-  0, 23, 87, 19, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 3, 42, 0, 0, 78, 0, 0,
-  59, 0, 56, 0, 27, 0, 0, 28, 13, 0,
-  118, 0, 0, 48, 0, 113, 0, 36, 68, 0,
-  0, 7, 28, 0, 17, 0, 0, 0, 10, 108,
-  35, 0, 27, 10, 7, 0, 0, 0, 13, 0,
-  52, 0, 0, 0, 0, 5, 41, 0, 0, 0,
-  0, 82, 0, 16, 0, 8, 18, 0, 0, 0,
-  39, 10, 84, 0, 0, 54, 5, 43, 0, 6,
-  0, 3, 0, 26, 0, 27, 108, 0, 0, 0,
-  0, 0, 90, 42, 15, 0, 26, 53, 0, 84,
-  60, 35, 50, 0, 0, 15, 20, 31, 0, 0,
-  3, 111, 0, 0, 0, 0, 61, 0, 0, 0,
-  0, 79, 0, 0, 3, 0, 0, 0, 0, 28,
-  0, 0, 0, 35, 0, 82, 11, 0, 69, 0,
-  27, 18, 0, 0, 0, 0, 0, 0, 27, 0,
-  48, 0, 11, 70, 0, 0, 22, 90, 0, 69,
-  0, 68, 0, 0, 7, 0, 32, 92, 0, 47,
-  0, 58, 48, 0, 85, 34, 0, 0, 11, 0,
-  0, 0, 0, 133, 125, 0, 0, 0, 8, 0,
-  0, 61, 0, 16, 7, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 45, 0, 54, 0,
-  21, 46, 0, 0, 117, 0, 0, 75, 0, 0,
-  21, 0, 0, 1, 34, 80, 0, 0, 0, 31,
-  19, 0, 0, 94, 14, 24, 0, 0, 0, 29,
-  0, 0, 10, 39, 0, 0, 0, 0, 0, 56,
-  0, 0, 0, 0, 0, 7, 0, 0, 0, 0,
-  0, 0, 0, 155, 0, 0, 71, 0, 21, 0,
-  50, 0, 0, 5, 0, 0, 108, 0, 0, 0,
-  0, 98, 0, 0, 39, 7, 0, 0, 0, 22,
-  15, 0, 0, 0, 31, 74, 16, 3, 15, 30,
-  48, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 72, 30, 0, 0, 0, 0, 78, 0, 23,
-  0, 11, 40, 0, 0, 0, 17, 16, 68, 25,
-  10, 51, 0, 3, 0, 0, 33, 0, 0, 53,
-  0, 0, 59, 0, 5, 69, 0, 0, 0, 0,
-  0, 19, 45, 76, 0, 0, 0, 17, 2, 8,
-  10, 22, 0, 35, 0, 0, 0, 0, 0, 77,
-  41, 11, 0, 18, 0, 0, 0, 17, 0, 13,
-  0, 0, 0, 39, 0, 0, 0, 0, 0, 0,
-  0, 110, 0, 0, 0, 0, 15, 4, 28, 0,
-  0, 0, 0, 0, 48, 0, 0, 6, 0, 9,
-  0, 40, 17, 0, 0, 0, 0, 0, 53, 0,
-  0, 17, 0, 52, 45, 0, 40, 9, 68, 0,
-  0, 0, 56, 0, 0, 5, 0, 0, 0, 21,
-  0, 0, 0, 0, 1, 53, 0, 16, 7, 45,
-  50, 0, 0, 13, 38, 10, 68, 48, 19, 52,
-  56, 0, 0, 0, 26, 9, 0, 10, 28, 0,
-  51, 0, 0, 127, 0, 0, 28, 13, 0, 0,
-  0, 82, 0, 0, 9, 29, 31, 0, 0, 85,
-  28, 32, 0, 0, 13, 55, 0, 0, 0, 43,
-  0, 0, 0, 17, 44, 93, 0, 0, 24, 0,
-  15, 0, 0, 32, 0, 29, 0, 35, 0, 77,
-  0, 0, 138, 0, 12, 0, 0, 0, 0, 64,
-  0, 0, 81, 0, 9, 6, 12, 125, 8, 0,
-  33, 55, 0, 39, 22, 0, 0, 0, 0, 0,
-  28, 82, 0, 10, 0, 46, 0, 0, 0, 123,
-  0, 0, 55, 0, 11, 0, 0, 88, 63, 49,
-  0, 0, 27, 0, 0, 10, 0, 6, 1, 11,
-  0, 0, 9, 35, 24, 0, 11, 0, 0, 0,
-  0, 0, 0, 3, 9, 79, 0, 0, 30, 0,
-  26, 161, 0, 0, 0, 0, 0, 0, 49, 60,
-  0, 0, 11, 55, 0, 0, 7, 16, 0, 50,
-  0, 0, 0, 0, 0, 35, 21, 0, 0, 13,
-  0, 0, 0, 55, 0, 3, 0, 20, 0, 22,
-  0, 12, 34, 22, 0, 0, 13, 103, 4, 0,
-  17, 0, 10, 0, 46, 0, 0, 0, 0, 0,
-  54, 0, 0, 2, 0, 4, 0, 34, 24, 5,
-  0, 40, 0, 0, 0, 10, 0, 0, 18, 36,
-  19, 0, 31, 36, 38, 0, 0, 22, 13, 0,
-  4, 0, 0, 0, 1, 46, 1, 0, 0, 0,
-  0, 10, 0, 22, 0, 25, 23, 0, 0, 0,
-  5, 29, 102, 47, 32, 3, 54, 0, 0, 0,
-  37, 15, 0, 14, 0, 49, 11, 0, 44, 0,
-  25, 0, 19, 0, 0, 0, 81, 51, 5, 17,
-  15, 0, 0, 0, 3, 0, 0, 60, 21, 63,
-  0, 0, 0, 12, 63, 0, 0, 27, 12, 0,
-  0, 6, 0, 70, 0, 97, 10, 75, 53, 0,
-  0, 0, 0, 6, 0, 65, 94, 0, 0, 3,
-  21, 23, 4, 21, 0, 0, 0, 70, 0, 12,
-  8, 0, 0, 0, 0, 33, 0, 19, 20, 29,
-  0, 0, 0, 27, 44, 20, 19, 0, 78, 0,
-  29, 0, 66, 38, 0, 0, 42, 37, 0, 32,
-  0, 38, 3, 45, 0, 0, 0, 0, 0, 0,
-  3, 5, 71, 72, 88, 0, 0, 7, 31, 0,
-  0, 31, 64, 18, 57, 10, 85, 0, 91, 2,
-  0, 0, 59, 1, 72, 42, 0, 0, 0, 22,
-  38, 13, 13, 6, 0, 7, 0, 21, 38, 13,
-  14, 0, 0, 64, 43, 11, 0, 0, 1, 54,
-  0, 38, 0, 39, 17, 0, 12, 19, 36, 29,
-  3, 0, 0, 0, 0, 0, 0, 11, 0, 0,
-  0, 0, 0, 70, 0, 0, 91, 0, 38, 0,
-  8, 0, 0, 4, 0, 0, 64, 10, 0, 0,
-  0, 114, 20, 0, 74, 27, 0, 45, 12, 51,
-  27, 0, 0, 0, 15, 101, 0, 21, 22, 36,
-  22, 0, 57, 0, 0, 0, 62, 0, 29, 0,
-  0, 72, 95, 0, 0, 0, 0, 80, 0, 16,
-  0, 0, 0, 13, 0, 0, 0, 0, 0, 0,
-  0, 33, 0, 3, 0, 0, 0, 0, 4, 22,
-  21, 0, 99, 34, 0, 157, 0, 0, 0, 0,
-  0, 17, 14, 49, 0, 0, 14, 40, 0, 1,
-  5, 82, 30, 0, 0, 0, 0, 0, 0, 147,
-  4, 78, 0, 24, 0, 23, 87, 19, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 3, 42, 0,
-  0, 78, 0, 0, 59, 0, 56, 0, 27, 0,
-  0, 28, 13, 0, 118, 0, 0, 48, 0, 113,
-  0, 36, 68, 0, 0, 7, 28, 0, 17, 0,
-  0, 0, 10, 108, 35, 0, 27, 10, 7, 0,
-  0, 0, 13, 0, 52, 0, 0, 0, 0, 5,
-  41, 0, 0, 0, 0, 82, 0, 16, 0, 8,
-  18, 0, 0, 0, 39, 10, 84, 0, 0, 54,
-  5, 43, 0, 6, 0, 3, 0, 26, 0, 9,
-  38, 0, 15, 120, 0, 0, 0, 0, 0, 3,
-  58, 72, 0, 0, 0, 18, 0, 18, 44, 0,
-  0, 51, 0, 3, 0, 0, 0, 91, 41, 0,
-  0, 22, 0, 0, 0, 22, 0, 25, 0, 45,
-  0, 53, 1, 0, 0, 32, 0, 0, 0, 70,
-  11, 0, 0, 0, 19, 0, 13, 14, 0, 9,
-  0, 0, 0, 0, 0, 11, 0, 0, 0, 58,
-  10, 0, 0, 20, 0, 0, 2, 19, 0, 27,
-  10, 28, 51, 0, 32, 5, 54, 4, 0, 0,
-  52, 5, 0, 37, 0, 0, 0, 30, 0, 0,
-  0, 0, 3, 4, 0, 16, 10, 25, 57, 0,
-  0, 17, 37, 0, 63, 43, 24, 47, 55, 1,
-  2, 0, 25, 2, 0, 0, 0, 0, 117, 0,
-  0, 75, 0, 0, 21, 0, 0, 1, 34, 80,
-  0, 0, 0, 31, 19, 0, 0, 94, 14, 24,
-  0, 0, 0, 29, 0, 0, 10, 39, 0, 0,
-  0, 0, 0, 56, 0, 0, 0, 0, 0, 7,
-  0, 0, 0, 0, 0, 0, 0, 155, 0, 0,
-  71, 0, 21, 0, 50, 0, 0, 5, 0, 0,
-  108, 0, 0, 0, 0, 98, 0, 0, 39, 7,
-  0, 0, 0, 22, 15, 0, 0, 0, 31, 74,
-  16, 3, 15, 30, 48, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 72, 30, 0, 0, 0,
-  0, 78, 0, 23, 0, 11, 40, 0, 0, 0,
-  17, 16, 68, 25, 10, 51, 0, 3, 0, 0,
-  33, 0, 0, 53, 0, 0, 59, 0, 5, 69,
-  0, 0, 0, 0, 0, 19, 45, 76, 0, 0,
-  0, 17, 2, 8, 10, 22, 0, 35, 0, 0,
-  0, 0, 0, 77, 41, 11, 0, 18, 0, 0,
-  0, 17, 0, 13, 0, 0, 0, 39, 0, 0,
-  0, 0, 0, 0, 0, 110, 0, 0, 0, 0,
-  15, 4, 28, 0, 0, 0, 0, 0, 48, 0,
-  0, 6, 0, 9, 0, 40, 17, 0, 0, 0,
-  0, 0, 53, 0, 0, 17, 0, 52, 45, 0,
-  40, 9, 68, 0, 0, 0, 56, 0, 0, 5,
-  0, 0, 0, 21, 0, 0, 0, 0, 1, 53,
-  0, 16, 7, 45, 50, 0, 0, 13, 38, 10,
-  68, 48, 19, 52, 56, 0, 0, 0, 26, 9,
-  0, 10, 0, 52, 52, 0, 44, 0, 21, 0,
-  7, 0, 0, 3, 68, 73, 3, 33, 10, 1,
-  18, 0, 44, 0, 0, 50, 14, 42, 0, 0,
-  0, 12, 60, 0, 0, 39, 0, 0, 0, 7,
-  0, 62, 39, 63, 0, 87, 51, 0, 0, 0,
-  0, 0, 0, 78, 42, 0, 0, 0, 18, 20,
-  19, 14, 11, 0, 3, 81, 0, 28, 0, 0,
-  0, 0, 0, 30, 0, 13, 8, 1, 0, 0,
-  0, 18, 37, 38, 21, 0, 88, 0, 16, 0,
-  65, 54, 0, 0, 46, 25, 0, 61, 0, 19,
-  5, 30, 0, 0, 0, 0, 0, 0, 0, 15,
-  38, 43, 88, 0, 0, 20, 22, 0, 0, 24,
-  58, 18, 39, 4, 45, 0, 79, 0, 1, 0,
-  0, 0, 30, 0, 26, 161, 0, 0, 0, 0,
-  0, 0, 49, 60, 0, 0, 11, 55, 0, 0,
-  7, 16, 0, 50, 0, 0, 0, 0, 0, 35,
-  21, 0, 0, 13, 0, 0, 0, 55, 0, 3,
-  0, 20, 0, 22, 0, 12, 34, 22, 0, 0,
-  13, 103, 4, 0, 17, 0, 10, 0, 46, 0,
-  0, 0, 0, 0, 54, 0, 0, 2, 0, 4,
-  0, 34, 24, 5, 0, 40, 0, 0, 0, 10,
-  0, 0, 18, 36, 19, 0, 31, 36, 38, 0,
-  0, 22, 13, 0, 4, 0, 0, 0, 1, 46,
-  1, 0, 0, 0, 0, 10, 0, 22, 0, 25,
-  23, 0, 0, 0, 5, 29, 102, 47, 32, 3,
-  54, 0, 0, 0, 37, 15, 0, 14, 0, 49,
-  11, 0, 44, 0, 25, 0, 19, 0, 0, 0,
-  81, 51, 5, 17, 15, 0, 0, 0, 3, 0,
-  0, 60, 21, 63, 0, 0, 0, 12, 63, 0,
-  0, 27, 12, 0, 0, 6, 0, 70, 0, 97,
-  10, 75, 53, 0, 0, 0, 0, 6, 0, 65,
-  94, 0, 0, 3, 21, 23, 4, 21, 0, 0,
-  0, 70, 0, 12, 8, 0, 0, 0, 0, 33,
-  0, 19, 20, 29, 0, 0, 0, 27, 44, 20,
-  19, 0, 78, 0, 29, 0, 66, 38, 0, 0,
-  42, 37, 0, 32, 0, 38, 3, 45, 0, 0,
-  0, 0, 0, 0, 3, 5, 71, 72, 88, 0,
-  0, 7, 31, 0, 0, 31, 64, 18, 57, 10,
-  85, 0, 91, 2, 0, 0, 0, 21, 76, 0,
-  26, 0, 1, 0, 0, 0, 0, 6, 28, 78,
-  0, 20, 4, 29, 21, 10, 35, 34, 113, 11,
-  0, 0, 0, 0, 0, 0, 18, 0, 0, 0,
-  0, 0, 0, 1, 0, 10, 66, 3, 0, 101,
-  57, 6, 0, 0, 0, 0, 0, 90, 1, 0,
-  17, 0, 40, 0, 25, 0, 0, 10, 7, 19,
-  34, 0, 0, 18, 0, 29, 0, 0, 0, 43,
-  3, 0, 0, 28, 0, 0, 37, 0, 22, 0,
-  65, 9, 0, 0, 20, 0, 0, 16, 13, 0,
-  0, 46, 0, 0, 0, 39, 0, 0, 0, 0,
-  1, 0, 0, 4, 0, 7, 72, 14, 0, 12,
-  20, 0, 52, 13, 51, 13, 13, 0, 0, 0,
-  64, 0, 0, 0, 21, 0, 99, 34, 0, 157,
-  0, 0, 0, 0, 0, 17, 14, 49, 0, 0,
-  14, 40, 0, 1, 5, 82, 30, 0, 0, 0,
-  0, 0, 0, 147, 4, 78, 0, 24, 0, 23,
-  87, 19, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 3, 42, 0, 0, 78, 0, 0, 59, 0,
-  56, 0, 27, 0, 0, 28, 13, 0, 118, 0,
-  0, 48, 0, 113, 0, 36, 68, 0, 0, 7,
-  28, 0, 17, 0, 0, 0, 10, 108, 35, 0,
-  27, 10, 7, 0, 0, 0, 13, 0, 52, 0,
-  0, 0, 0, 5, 41, 0, 0, 0, 0, 82,
-  0, 16, 0, 8, 18, 0, 0, 0, 39, 10,
-  84, 0, 0, 54, 5, 43, 0, 6, 0, 3,
-  0, 26, 0, 9, 38, 0, 15, 120, 0, 0,
-  0, 0, 0, 3, 58, 72, 0, 0, 0, 18,
-  0, 18, 44, 0, 0, 51, 0, 3, 0, 0,
-  0, 91, 41, 0, 0, 22, 0, 0, 0, 22,
-  0, 25, 0, 45, 0, 53, 1, 0, 0, 32,
-  0, 0, 0, 70, 11, 0, 0, 0, 19, 0,
-  13, 14, 0, 9, 0, 0, 0, 0, 0, 11,
-  0, 0, 0, 58, 10, 0, 0, 20, 0, 0,
-  2, 19, 0, 27, 10, 28, 51, 0, 32, 5,
-  54, 4, 0, 0, 52, 5, 0, 37, 0, 0,
-  0, 30, 0, 0, 0, 0, 3, 4, 0, 16,
-  10, 25, 57, 0, 0, 17, 37, 0, 63, 43,
-  24, 47, 55, 1, 2, 0, 25, 2, 0, 0,
-  0, 70, 65, 0, 63, 0, 15, 0, 1, 0,
-  14, 0, 64, 75, 0, 51, 17, 7, 26, 16,
-  9, 0, 0, 47, 38, 59, 0, 0, 0, 0,
-  53, 0, 0, 37, 12, 0, 0, 0, 0, 53,
-  50, 43, 24, 71, 73, 0, 0, 0, 0, 0,
-  0, 26, 50, 0, 0, 0, 0, 20, 1, 27,
-  24, 0, 0, 63, 0, 2, 29, 0, 0, 0,
-  0, 0, 7, 41, 16, 12, 0, 17, 0, 23,
-  46, 34, 33, 22, 87, 14, 32, 4, 49, 40,
-  0, 20, 24, 31, 0, 54, 0, 35, 3, 41,
-  0, 0, 0, 0, 0, 0, 7, 10, 34, 32,
-  82, 0, 0, 13, 31, 0, 0, 29, 54, 8,
-  7, 0, 55, 0, 75, 11, 2, 0, 0, 0,
-  59, 0, 5, 69, 0, 0, 0, 0, 0, 19,
-  45, 76, 0, 0, 0, 17, 2, 8, 10, 22,
-  0, 35, 0, 0, 0, 0, 0, 77, 41, 11,
-  0, 18, 0, 0, 0, 17, 0, 13, 0, 0,
-  0, 39, 0, 0, 0, 0, 0, 0, 0, 110,
-  0, 0, 0, 0, 15, 4, 28, 0, 0, 0,
-  0, 0, 48, 0, 0, 6, 0, 9, 0, 40,
-  17, 0, 0, 0, 0, 0, 53, 0, 0, 17,
-  0, 52, 45, 0, 40, 9, 68, 0, 0, 0,
-  56, 0, 0, 5, 0, 0, 0, 21, 0, 0,
-  0, 0, 1, 53, 0, 16, 7, 45, 50, 0,
-  0, 13, 38, 10, 68, 48, 19, 52, 56, 0,
-  0, 0, 26, 9, 0, 10, 0, 52, 52, 0,
-  44, 0, 21, 0, 7, 0, 0, 3, 68, 73,
-  3, 33, 10, 1, 18, 0, 44, 0, 0, 50,
-  14, 42, 0, 0, 0, 12, 60, 0, 0, 39,
-  0, 0, 0, 7, 0, 62, 39, 63, 0, 87,
-  51, 0, 0, 0, 0, 0, 0, 78, 42, 0,
-  0, 0, 18, 20, 19, 14, 11, 0, 3, 81,
-  0, 28, 0, 0, 0, 0, 0, 30, 0, 13,
-  8, 1, 0, 0, 0, 18, 37, 38, 21, 0,
-  88, 0, 16, 0, 65, 54, 0, 0, 46, 25,
-  0, 61, 0, 19, 5, 30, 0, 0, 0, 0,
-  0, 0, 0, 15, 38, 43, 88, 0, 0, 20,
-  22, 0, 0, 24, 58, 18, 39, 4, 45, 0,
-  79, 0, 1, 0, 0, 16, 100, 0, 22, 0,
-  0, 0, 0, 0, 0, 11, 22, 94, 0, 49,
-  0, 51, 31, 35, 50, 27, 110, 9, 0, 0,
-  0, 0, 0, 0, 32, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 94, 0, 0, 96, 51, 18,
-  0, 0, 0, 0, 0, 79, 0, 0, 15, 0,
-  24, 0, 24, 0, 7, 8, 19, 6, 56, 0,
-  0, 10, 0, 51, 0, 0, 21, 34, 0, 0,
-  0, 16, 0, 0, 24, 0, 36, 0, 41, 12,
-  2, 0, 43, 21, 0, 36, 0, 0, 5, 39,
-  0, 0, 0, 27, 23, 0, 0, 0, 0, 0,
-  0, 11, 0, 6, 79, 9, 0, 5, 40, 0,
-  52, 15, 28, 31, 21, 0, 0, 0, 55, 12,
-  0, 0, 0, 49, 11, 0, 44, 0, 25, 0,
-  19, 0, 0, 0, 81, 51, 5, 17, 15, 0,
-  0, 0, 3, 0, 0, 60, 21, 63, 0, 0,
-  0, 12, 63, 0, 0, 27, 12, 0, 0, 6,
-  0, 70, 0, 97, 10, 75, 53, 0, 0, 0,
-  0, 6, 0, 65, 94, 0, 0, 3, 21, 23,
-  4, 21, 0, 0, 0, 70, 0, 12, 8, 0,
-  0, 0, 0, 33, 0, 19, 20, 29, 0, 0,
-  0, 27, 44, 20, 19, 0, 78, 0, 29, 0,
-  66, 38, 0, 0, 42, 37, 0, 32, 0, 38,
-  3, 45, 0, 0, 0, 0, 0, 0, 3, 5,
-  71, 72, 88, 0, 0, 7, 31, 0, 0, 31,
-  64, 18, 57, 10, 85, 0, 91, 2, 0, 0,
-  0, 21, 76, 0, 26, 0, 1, 0, 0, 0,
-  0, 6, 28, 78, 0, 20, 4, 29, 21, 10,
-  35, 34, 113, 11, 0, 0, 0, 0, 0, 0,
-  18, 0, 0, 0, 0, 0, 0, 1, 0, 10,
-  66, 3, 0, 101, 57, 6, 0, 0, 0, 0,
-  0, 90, 1, 0, 17, 0, 40, 0, 25, 0,
-  0, 10, 7, 19, 34, 0, 0, 18, 0, 29,
-  0, 0, 0, 43, 3, 0, 0, 28, 0, 0,
-  37, 0, 22, 0, 65, 9, 0, 0, 20, 0,
-  0, 16, 13, 0, 0, 46, 0, 0, 0, 39,
-  0, 0, 0, 0, 1, 0, 0, 4, 0, 7,
-  72, 14, 0, 12, 20, 0, 52, 13, 51, 13,
-  13, 0, 0, 0, 64, 0, 0, 0, 4, 0,
-  79, 3, 6, 0, 0, 0, 14, 0, 0, 8,
-  0, 94, 0, 3, 0, 47, 45, 17, 53, 54,
-  102, 0, 0, 0, 0, 16, 0, 0, 0, 0,
-  0, 0, 0, 14, 0, 0, 0, 0, 37, 0,
-  0, 85, 38, 32, 0, 6, 0, 0, 0, 126,
-  0, 0, 66, 0, 24, 0, 20, 0, 0, 0,
-  29, 0, 99, 0, 0, 10, 0, 92, 0, 0,
-  18, 0, 0, 0, 4, 0, 0, 0, 11, 0,
-  20, 0, 18, 0, 0, 0, 39, 0, 0, 7,
-  0, 0, 22, 29, 2, 0, 4, 32, 23, 0,
-  0, 0, 28, 0, 0, 3, 17, 0, 84, 3,
-  0, 15, 21, 0, 112, 0, 10, 16, 55, 0,
-  0, 0, 57, 15, 0, 0, 0, 9, 38, 0,
-  15, 120, 0, 0, 0, 0, 0, 3, 58, 72,
-  0, 0, 0, 18, 0, 18, 44, 0, 0, 51,
-  0, 3, 0, 0, 0, 91, 41, 0, 0, 22,
-  0, 0, 0, 22, 0, 25, 0, 45, 0, 53,
-  1, 0, 0, 32, 0, 0, 0, 70, 11, 0,
-  0, 0, 19, 0, 13, 14, 0, 9, 0, 0,
-  0, 0, 0, 11, 0, 0, 0, 58, 10, 0,
-  0, 20, 0, 0, 2, 19, 0, 27, 10, 28,
-  51, 0, 32, 5, 54, 4, 0, 0, 52, 5,
-  0, 37, 0, 0, 0, 30, 0, 0, 0, 0,
-  3, 4, 0, 16, 10, 25, 57, 0, 0, 17,
-  37, 0, 63, 43, 24, 47, 55, 1, 2, 0,
-  25, 2, 0, 0, 0, 70, 65, 0, 63, 0,
-  15, 0, 1, 0, 14, 0, 64, 75, 0, 51,
-  17, 7, 26, 16, 9, 0, 0, 47, 38, 59,
-  0, 0, 0, 0, 53, 0, 0, 37, 12, 0,
-  0, 0, 0, 53, 50, 43, 24, 71, 73, 0,
-  0, 0, 0, 0, 0, 26, 50, 0, 0, 0,
-  0, 20, 1, 27, 24, 0, 0, 63, 0, 2,
-  29, 0, 0, 0, 0, 0, 7, 41, 16, 12,
-  0, 17, 0, 23, 46, 34, 33, 22, 87, 14,
-  32, 4, 49, 40, 0, 20, 24, 31, 0, 54,
-  0, 35, 3, 41, 0, 0, 0, 0, 0, 0,
-  7, 10, 34, 32, 82, 0, 0, 13, 31, 0,
-  0, 29, 54, 8, 7, 0, 55, 0, 75, 11,
-  2, 0, 0, 0, 119, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 103, 0, 9, 0, 6,
-  10, 5, 9, 50, 108, 24, 0, 0, 0, 8,
-  184, 0, 22, 0, 0, 31, 0, 0, 11, 12,
-  0, 10, 106, 0, 19, 21, 57, 33, 0, 2,
-  16, 0, 0, 65, 0, 0, 30, 0, 14, 26,
-  31, 0, 30, 40, 20, 0, 16, 5, 36, 0,
-  0, 70, 0, 0, 38, 61, 0, 0, 13, 0,
-  0, 0, 25, 10, 0, 19, 7, 11, 0, 47,
-  49, 0, 0, 54, 39, 0, 33, 24, 0, 0,
-  0, 22, 19, 7, 17, 0, 40, 27, 0, 5,
-  0, 0, 50, 3, 0, 0, 37, 20, 52, 0,
-  0, 30, 0, 0, 0, 0, 2, 25, 2, 0,
-  0, 52, 52, 0, 44, 0, 21, 0, 7, 0,
-  0, 3, 68, 73, 3, 33, 10, 1, 18, 0,
-  44, 0, 0, 50, 14, 42, 0, 0, 0, 12,
-  60, 0, 0, 39, 0, 0, 0, 7, 0, 62,
-  39, 63, 0, 87, 51, 0, 0, 0, 0, 0,
-  0, 78, 42, 0, 0, 0, 18, 20, 19, 14,
-  11, 0, 3, 81, 0, 28, 0, 0, 0, 0,
-  0, 30, 0, 13, 8, 1, 0, 0, 0, 18,
-  37, 38, 21, 0, 88, 0, 16, 0, 65, 54,
-  0, 0, 46, 25, 0, 61, 0, 19, 5, 30,
-  0, 0, 0, 0, 0, 0, 0, 15, 38, 43,
-  88, 0, 0, 20, 22, 0, 0, 24, 58, 18,
-  39, 4, 45, 0, 79, 0, 1, 0, 0, 16,
-  100, 0, 22, 0, 0, 0, 0, 0, 0, 11,
-  22, 94, 0, 49, 0, 51, 31, 35, 50, 27,
-  110, 9, 0, 0, 0, 0, 0, 0, 32, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 94, 0,
-  0, 96, 51, 18, 0, 0, 0, 0, 0, 79,
-  0, 0, 15, 0, 24, 0, 24, 0, 7, 8,
-  19, 6, 56, 0, 0, 10, 0, 51, 0, 0,
-  21, 34, 0, 0, 0, 16, 0, 0, 24, 0,
-  36, 0, 41, 12, 2, 0, 43, 21, 0, 36,
-  0, 0, 5, 39, 0, 0, 0, 27, 23, 0,
-  0, 0, 0, 0, 0, 11, 0, 6, 79, 9,
-  0, 5, 40, 0, 52, 15, 28, 31, 21, 0,
-  0, 0, 55, 12, 0, 0, 20, 0, 91, 19,
-  0, 0, 0, 12, 20, 0, 0, 0, 0, 125,
-  0, 0, 0, 22, 28, 1, 36, 70, 81, 11,
-  0, 0, 7, 35, 205, 0, 23, 21, 0, 15,
-  0, 0, 0, 31, 0, 0, 65, 0, 0, 38,
-  53, 70, 0, 0, 0, 0, 0, 120, 0, 6,
-  74, 0, 21, 12, 39, 0, 24, 17, 49, 0,
-  50, 0, 10, 0, 0, 102, 0, 0, 27, 14,
-  0, 0, 25, 0, 0, 0, 12, 2, 2, 20,
-  0, 0, 0, 33, 96, 33, 0, 2, 0, 0,
-  53, 20, 39, 0, 2, 26, 35, 12, 15, 0,
-  81, 19, 3, 30, 19, 0, 74, 0, 14, 0,
-  19, 31, 105, 0, 0, 54, 0, 0, 0, 0,
-  40, 22, 0, 17, 0, 21, 76, 0, 26, 0,
-  1, 0, 0, 0, 0, 6, 28, 78, 0, 20,
-  4, 29, 21, 10, 35, 34, 113, 11, 0, 0,
-  0, 0, 0, 0, 18, 0, 0, 0, 0, 0,
-  0, 1, 0, 10, 66, 3, 0, 101, 57, 6,
-  0, 0, 0, 0, 0, 90, 1, 0, 17, 0,
-  40, 0, 25, 0, 0, 10, 7, 19, 34, 0,
-  0, 18, 0, 29, 0, 0, 0, 43, 3, 0,
-  0, 28, 0, 0, 37, 0, 22, 0, 65, 9,
-  0, 0, 20, 0, 0, 16, 13, 0, 0, 46,
-  0, 0, 0, 39, 0, 0, 0, 0, 1, 0,
-  0, 4, 0, 7, 72, 14, 0, 12, 20, 0,
-  52, 13, 51, 13, 13, 0, 0, 0, 64, 0,
-  0, 0, 4, 0, 79, 3, 6, 0, 0, 0,
-  14, 0, 0, 8, 0, 94, 0, 3, 0, 47,
-  45, 17, 53, 54, 102, 0, 0, 0, 0, 16,
-  0, 0, 0, 0, 0, 0, 0, 14, 0, 0,
-  0, 0, 37, 0, 0, 85, 38, 32, 0, 6,
-  0, 0, 0, 126, 0, 0, 66, 0, 24, 0,
-  20, 0, 0, 0, 29, 0, 99, 0, 0, 10,
-  0, 92, 0, 0, 18, 0, 0, 0, 4, 0,
-  0, 0, 11, 0, 20, 0, 18, 0, 0, 0,
-  39, 0, 0, 7, 0, 0, 22, 29, 2, 0,
-  4, 32, 23, 0, 0, 0, 28, 0, 0, 3,
-  17, 0, 84, 3, 0, 15, 21, 0, 112, 0,
-  10, 16, 55, 0, 0, 0, 57, 15, 0, 0,
-  2, 0, 42, 31, 0, 0, 14, 24, 59, 0,
-  4, 0, 0, 82, 0, 0, 0, 8, 26, 0,
-  35, 19, 23, 27, 0, 0, 38, 57, 187, 16,
-  19, 10, 32, 0, 0, 0, 0, 25, 0, 0,
-  0, 0, 0, 32, 38, 93, 0, 17, 0, 0,
-  3, 110, 0, 32, 59, 0, 9, 0, 14, 0,
-  0, 22, 8, 0, 4, 0, 20, 0, 0, 39,
-  0, 6, 29, 4, 0, 9, 34, 0, 0, 0,
-  24, 0, 1, 24, 0, 0, 0, 30, 103, 45,
-  40, 0, 0, 0, 18, 12, 59, 0, 26, 51,
-  26, 6, 18, 0, 84, 0, 42, 12, 87, 0,
-  79, 0, 10, 0, 1, 0, 115, 0, 0, 34,
-  41, 0, 5, 0, 59, 9, 0, 24, 0, 70,
-  65, 0, 63, 0, 15, 0, 1, 0, 14, 0,
-  64, 75, 0, 51, 17, 7, 26, 16, 9, 0,
-  0, 47, 38, 59, 0, 0, 0, 0, 53, 0,
-  0, 37, 12, 0, 0, 0, 0, 53, 50, 43,
-  24, 71, 73, 0, 0, 0, 0, 0, 0, 26,
-  50, 0, 0, 0, 0, 20, 1, 27, 24, 0,
-  0, 63, 0, 2, 29, 0, 0, 0, 0, 0,
-  7, 41, 16, 12, 0, 17, 0, 23, 46, 34,
-  33, 22, 87, 14, 32, 4, 49, 40, 0, 20,
-  24, 31, 0, 54, 0, 35, 3, 41, 0, 0,
-  0, 0, 0, 0, 7, 10, 34, 32, 82, 0,
-  0, 13, 31, 0, 0, 29, 54, 8, 7, 0,
-  55, 0, 75, 11, 2, 0, 0, 0, 119, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 103,
-  0, 9, 0, 6, 10, 5, 9, 50, 108, 24,
-  0, 0, 0, 8, 184, 0, 22, 0, 0, 31,
-  0, 0, 11, 12, 0, 10, 106, 0, 19, 21,
-  57, 33, 0, 2, 16, 0, 0, 65, 0, 0,
-  30, 0, 14, 26, 31, 0, 30, 40, 20, 0,
-  16, 5, 36, 0, 0, 70, 0, 0, 38, 61,
-  0, 0, 13, 0, 0, 0, 25, 10, 0, 19,
-  7, 11, 0, 47, 49, 0, 0, 54, 39, 0,
-  33, 24, 0, 0, 0, 22, 19, 7, 17, 0,
-  40, 27, 0, 5, 0, 0, 50, 3, 0, 0,
-  37, 20, 52, 0, 0, 30, 0, 0, 0, 0,
-  2, 25, 2, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 16, 100, 0, 22, 0, 0, 0,
-  0, 0, 0, 11, 22, 94, 0, 49, 0, 51,
-  31, 35, 50, 27, 110, 9, 0, 0, 0, 0,
-  0, 0, 32, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 94, 0, 0, 96, 51, 18, 0, 0,
-  0, 0, 0, 79, 0, 0, 15, 0, 24, 0,
-  24, 0, 7, 8, 19, 6, 56, 0, 0, 10,
-  0, 51, 0, 0, 21, 34, 0, 0, 0, 16,
-  0, 0, 24, 0, 36, 0, 41, 12, 2, 0,
-  43, 21, 0, 36, 0, 0, 5, 39, 0, 0,
-  0, 27, 23, 0, 0, 0, 0, 0, 0, 11,
-  0, 6, 79, 9, 0, 5, 40, 0, 52, 15,
-  28, 31, 21, 0, 0, 0, 55, 12, 0, 0,
-  20, 0, 91, 19, 0, 0, 0, 12, 20, 0,
-  0, 0, 0, 125, 0, 0, 0, 22, 28, 1,
-  36, 70, 81, 11, 0, 0, 7, 35, 205, 0,
-  23, 21, 0, 15, 0, 0, 0, 31, 0, 0,
-  65, 0, 0, 38, 53, 70, 0, 0, 0, 0,
-  0, 120, 0, 6, 74, 0, 21, 12, 39, 0,
-  24, 17, 49, 0, 50, 0, 10, 0, 0, 102,
-  0, 0, 27, 14, 0, 0, 25, 0, 0, 0,
-  12, 2, 2, 20, 0, 0, 0, 33, 96, 33,
-  0, 2, 0, 0, 53, 20, 39, 0, 2, 26,
-  35, 12, 15, 0, 81, 19, 3, 30, 19, 0,
-  74, 0, 14, 0, 19, 31, 105, 0, 0, 54,
-  0, 0, 0, 0, 40, 22, 0, 17, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 4, 0, 79, 3,
-  6, 0, 0, 0, 14, 0, 0, 8, 0, 94,
-  0, 3, 0, 47, 45, 17, 53, 54, 102, 0,
-  0, 0, 0, 16, 0, 0, 0, 0, 0, 0,
-  0, 14, 0, 0, 0, 0, 37, 0, 0, 85,
-  38, 32, 0, 6, 0, 0, 0, 126, 0, 0,
-  66, 0, 24, 0, 20, 0, 0, 0, 29, 0,
-  99, 0, 0, 10, 0, 92, 0, 0, 18, 0,
-  0, 0, 4, 0, 0, 0, 11, 0, 20, 0,
-  18, 0, 0, 0, 39, 0, 0, 7, 0, 0,
-  22, 29, 2, 0, 4, 32, 23, 0, 0, 0,
-  28, 0, 0, 3, 17, 0, 84, 3, 0, 15,
-  21, 0, 112, 0, 10, 16, 55, 0, 0, 0,
-  57, 15, 0, 0, 2, 0, 42, 31, 0, 0,
-  14, 24, 59, 0, 4, 0, 0, 82, 0, 0,
-  0, 8, 26, 0, 35, 19, 23, 27, 0, 0,
-  38, 57, 187, 16, 19, 10, 32, 0, 0, 0,
-  0, 25, 0, 0, 0, 0, 0, 32, 38, 93,
-  0, 17, 0, 0, 3, 110, 0, 32, 59, 0,
-  9, 0, 14, 0, 0, 22, 8, 0, 4, 0,
-  20, 0, 0, 39, 0, 6, 29, 4, 0, 9,
-  34, 0, 0, 0, 24, 0, 1, 24, 0, 0,
-  0, 30, 103, 45, 40, 0, 0, 0, 18, 12,
-  59, 0, 26, 51, 26, 6, 18, 0, 84, 0,
-  42, 12, 87, 0, 79, 0, 10, 0, 1, 0,
-  115, 0, 0, 34, 41, 0, 5, 0, 59, 9,
-  0, 24, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 13, 24,
-  67, 6, 0, 18, 27, 22, 0, 0, 0, 0,
-  0, 97, 0, 0, 60, 4, 0, 5, 27, 86,
-  27, 52, 0, 0, 8, 9, 193, 55, 1, 28,
-  52, 0, 59, 1, 0, 58, 0, 17, 14, 39,
-  0, 14, 26, 83, 17, 0, 2, 0, 0, 64,
-  30, 0, 71, 0, 60, 0, 49, 0, 15, 71,
-  0, 0, 0, 0, 7, 6, 77, 33, 0, 22,
-  82, 11, 31, 27, 25, 0, 20, 13, 0, 0,
-  15, 5, 0, 0, 0, 0, 62, 3, 0, 0,
-  23, 0, 15, 37, 0, 0, 49, 67, 15, 0,
-  0, 37, 46, 75, 26, 0, 0, 6, 1, 16,
-  0, 37, 12, 0, 55, 0, 9, 28, 40, 0,
-  0, 0, 4, 0, 26, 26, 0, 60, 0, 15,
-  0, 5, 36, 23, 2, 0, 0, 31, 86, 8,
-  0, 0, 59, 11, 0, 0, 65, 56, 0, 25,
-  23, 0, 0, 13, 0, 13, 0, 11, 92, 0,
-  18, 0, 0, 32, 0, 53, 0, 28, 0, 44,
-  48, 94, 4, 86, 0, 7, 0, 38, 52, 0,
-  35, 0, 21, 0, 24, 0, 13, 27, 0, 40,
-  0, 11, 10, 0, 33, 0, 8, 0, 25, 13,
-  37, 0, 0, 0, 0, 15, 39, 0, 14, 13,
-  0, 0, 0, 0, 0, 24, 0, 0, 0, 13,
-  0, 47, 0, 0, 62, 50, 3, 0, 0, 13,
-  20, 1, 44, 0, 24, 28, 0, 29, 0, 15,
-  0, 0, 25, 0, 11, 10, 47, 0, 42, 0,
-  79, 0, 14, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 30, 25, 0, 1, 3, 33, 18,
-  0, 0, 0, 0, 0, 38, 0, 18, 43, 15,
-  0, 40, 38, 17, 58, 51, 0, 9, 8, 5,
-  128, 38, 0, 0, 54, 0, 69, 16, 0, 30,
-  0, 38, 21, 38, 0, 22, 60, 37, 2, 0,
-  0, 0, 0, 13, 47, 0, 16, 0, 64, 0,
-  29, 0, 6, 33, 7, 0, 0, 0, 7, 19,
-  25, 0, 0, 36, 79, 26, 45, 46, 0, 7,
-  30, 1, 38, 2, 13, 0, 0, 0, 0, 0,
-  54, 6, 3, 0, 38, 1, 15, 56, 0, 0,
-  37, 35, 9, 0, 0, 19, 20, 19, 57, 1,
-  0, 26, 0, 8, 0, 33, 5, 0, 23, 13,
-  0, 22, 19, 0, 0, 0, 19, 0, 11, 9,
-  0, 48, 13, 14, 0, 0, 29, 34, 3, 0,
-  0, 37, 105, 0, 2, 11, 53, 15, 0, 14,
-  67, 51, 53, 17, 9, 0, 0, 9, 0, 0,
-  0, 0, 96, 0, 32, 9, 0, 24, 0, 75,
-  0, 32, 0, 38, 68, 64, 0, 61, 0, 41,
-  0, 28, 43, 1, 16, 0, 14, 0, 11, 0,
-  0, 0, 0, 18, 0, 0, 0, 0, 17, 0,
-  10, 2, 29, 20, 37, 0, 16, 39, 0, 22,
-  45, 0, 41, 0, 0, 0, 0, 0, 0, 7,
-  0, 0, 0, 7, 0, 48, 0, 0, 52, 46,
-  8, 0, 0, 12, 18, 0, 59, 0, 0, 16,
-  0, 17, 0, 17, 0, 0, 14, 0, 6, 8,
-  40, 0, 40, 0, 76, 0, 11, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 62, 32, 0,
-  2, 1, 44, 3, 0, 0, 16, 4, 12, 0,
-  5, 53, 33, 30, 0, 74, 61, 0, 71, 46,
-  0, 36, 0, 3, 111, 34, 1, 0, 57, 0,
-  53, 22, 0, 16, 0, 48, 40, 30, 5, 36,
-  99, 16, 0, 12, 0, 8, 1, 0, 56, 0,
-  0, 0, 43, 0, 7, 33, 9, 0, 16, 0,
-  0, 0, 18, 21, 0, 0, 8, 32, 42, 43,
-  43, 31, 0, 15, 0, 0, 70, 13, 10, 0,
-  12, 12, 0, 0, 50, 9, 2, 0, 16, 0,
-  5, 73, 0, 0, 8, 21, 2, 0, 0, 16,
-  17, 0, 77, 9, 0, 22, 29, 1, 0, 33,
-  0, 0, 0, 15, 0, 33, 26, 0, 0, 0,
-  28, 0, 14, 0, 5, 45, 49, 8, 0, 13,
-  12, 23, 0, 0, 0, 49, 90, 0, 0, 29,
-  44, 13, 0, 25, 68, 58, 82, 13, 0, 0,
-  0, 11, 0, 0, 0, 0, 81, 0, 34, 31,
-  0, 20, 0, 59, 2, 29, 0, 28, 67, 52,
-  0, 60, 0, 43, 0, 42, 24, 0, 22, 0,
-  17, 0, 7, 0, 0, 0, 0, 9, 8, 0,
-  0, 0, 16, 0, 14, 13, 19, 19, 30, 0,
-  40, 53, 0, 19, 43, 0, 42, 0, 0, 11,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 33,
-  18, 0, 37, 45, 21, 0, 0, 23, 29, 0,
-  60, 0, 0, 7, 11, 13, 0, 17, 0, 0,
-  0, 0, 1, 9, 37, 0, 7, 0, 52, 0,
-  8, 2, 13, 24, 67, 6, 0, 18, 27, 22,
-  0, 0, 0, 0, 0, 97, 0, 0, 60, 4,
-  0, 5, 27, 86, 27, 52, 0, 0, 8, 9,
-  193, 55, 1, 28, 52, 0, 59, 1, 0, 58,
-  0, 17, 14, 39, 0, 14, 26, 83, 17, 0,
-  2, 0, 0, 64, 30, 0, 71, 0, 60, 0,
-  49, 0, 15, 71, 0, 0, 0, 0, 7, 6,
-  77, 33, 0, 22, 82, 11, 31, 27, 25, 0,
-  20, 13, 0, 0, 15, 5, 0, 0, 0, 0,
-  62, 3, 0, 0, 23, 0, 15, 37, 0, 0,
-  49, 67, 15, 0, 0, 37, 46, 75, 26, 0,
-  0, 6, 1, 16, 0, 37, 12, 0, 55, 0,
-  9, 28, 40, 0, 0, 0, 4, 0, 26, 26,
-  0, 60, 0, 15, 0, 5, 36, 23, 2, 0,
-  0, 31, 86, 8, 0, 0, 59, 11, 0, 0,
-  65, 56, 0, 25, 23, 0, 0, 13, 0, 13,
-  0, 11, 92, 0, 18, 0, 0, 32, 0, 53,
-  0, 28, 0, 44, 48, 94, 4, 86, 0, 7,
-  0, 38, 52, 0, 35, 0, 21, 0, 24, 0,
-  13, 27, 0, 40, 0, 11, 10, 0, 33, 0,
-  8, 0, 25, 13, 37, 0, 0, 0, 0, 15,
-  39, 0, 14, 13, 0, 0, 0, 0, 0, 24,
-  0, 0, 0, 13, 0, 47, 0, 0, 62, 50,
-  3, 0, 0, 13, 20, 1, 44, 0, 24, 28,
-  0, 29, 0, 15, 0, 0, 25, 0, 11, 10,
-  47, 0, 42, 0, 79, 0, 14, 0, 3, 28,
-  40, 34, 0, 19, 25, 3, 20, 0, 0, 31,
-  114, 0, 21, 37, 61, 3, 0, 0, 0, 74,
-  0, 5, 57, 0, 0, 30, 0, 1, 0, 41,
-  79, 0, 10, 0, 0, 27, 0, 80, 0, 41,
-  32, 32, 31, 55, 32, 23, 0, 44, 0, 50,
-  31, 17, 17, 0, 7, 0, 0, 0, 12, 0,
-  0, 36, 0, 0, 4, 0, 28, 0, 17, 10,
-  0, 3, 3, 0, 15, 36, 0, 33, 36, 0,
-  51, 45, 0, 0, 5, 0, 0, 36, 0, 0,
-  0, 5, 0, 25, 33, 0, 3, 68, 5, 0,
-  5, 7, 24, 0, 28, 0, 2, 10, 6, 14,
-  0, 1, 0, 0, 2, 0, 6, 0, 15, 4,
-  59, 0, 74, 0, 21, 0, 0, 30, 25, 0,
-  1, 3, 33, 18, 0, 0, 0, 0, 0, 38,
-  0, 18, 43, 15, 0, 40, 38, 17, 58, 51,
-  0, 9, 8, 5, 128, 38, 0, 0, 54, 0,
-  69, 16, 0, 30, 0, 38, 21, 38, 0, 22,
-  60, 37, 2, 0, 0, 0, 0, 13, 47, 0,
-  16, 0, 64, 0, 29, 0, 6, 33, 7, 0,
-  0, 0, 7, 19, 25, 0, 0, 36, 79, 26,
-  45, 46, 0, 7, 30, 1, 38, 2, 13, 0,
-  0, 0, 0, 0, 54, 6, 3, 0, 38, 1,
-  15, 56, 0, 0, 37, 35, 9, 0, 0, 19,
-  20, 19, 57, 1, 0, 26, 0, 8, 0, 33,
-  5, 0, 23, 13, 0, 22, 19, 0, 0, 0,
-  19, 0, 11, 9, 0, 48, 13, 14, 0, 0,
-  29, 34, 3, 0, 0, 37, 105, 0, 2, 11,
-  53, 15, 0, 14, 67, 51, 53, 17, 9, 0,
-  0, 9, 0, 0, 0, 0, 96, 0, 32, 9,
-  0, 24, 0, 75, 0, 32, 0, 38, 68, 64,
-  0, 61, 0, 41, 0, 28, 43, 1, 16, 0,
-  14, 0, 11, 0, 0, 0, 0, 18, 0, 0,
-  0, 0, 17, 0, 10, 2, 29, 20, 37, 0,
-  16, 39, 0, 22, 45, 0, 41, 0, 0, 0,
-  0, 0, 0, 7, 0, 0, 0, 7, 0, 48,
-  0, 0, 52, 46, 8, 0, 0, 12, 18, 0,
-  59, 0, 0, 16, 0, 17, 0, 17, 0, 0,
-  14, 0, 6, 8, 40, 0, 40, 0, 76, 0,
-  11, 0, 4, 29, 39, 21, 0, 5, 28, 2,
-  19, 0, 0, 34, 112, 0, 22, 39, 53, 0,
-  0, 0, 0, 83, 0, 10, 59, 0, 0, 23,
-  0, 0, 0, 41, 82, 0, 23, 0, 0, 23,
-  0, 78, 0, 55, 37, 22, 36, 48, 30, 16,
-  0, 54, 0, 60, 33, 24, 31, 0, 11, 0,
-  7, 0, 17, 0, 0, 63, 0, 10, 7, 0,
-  36, 0, 8, 20, 0, 4, 0, 0, 33, 43,
-  0, 29, 44, 0, 61, 29, 0, 0, 0, 0,
-  0, 31, 0, 0, 0, 4, 0, 29, 42, 0,
-  5, 76, 2, 0, 8, 14, 30, 0, 21, 0,
-  0, 0, 8, 15, 0, 0, 0, 0, 0, 0,
-  6, 2, 19, 0, 53, 0, 69, 0, 17, 0,
-  0, 62, 32, 0, 2, 1, 44, 3, 0, 0,
-  16, 4, 12, 0, 5, 53, 33, 30, 0, 74,
-  61, 0, 71, 46, 0, 36, 0, 3, 111, 34,
-  1, 0, 57, 0, 53, 22, 0, 16, 0, 48,
-  40, 30, 5, 36, 99, 16, 0, 12, 0, 8,
-  1, 0, 56, 0, 0, 0, 43, 0, 7, 33,
-  9, 0, 16, 0, 0, 0, 18, 21, 0, 0,
-  8, 32, 42, 43, 43, 31, 0, 15, 0, 0,
-  70, 13, 10, 0, 12, 12, 0, 0, 50, 9,
-  2, 0, 16, 0, 5, 73, 0, 0, 8, 21,
-  2, 0, 0, 16, 17, 0, 77, 9, 0, 22,
-  29, 1, 0, 33, 0, 0, 0, 15, 0, 33,
-  26, 0, 0, 0, 28, 0, 14, 0, 5, 45,
-  49, 8, 0, 13, 12, 23, 0, 0, 0, 49,
-  90, 0, 0, 29, 44, 13, 0, 25, 68, 58,
-  82, 13, 0, 0, 0, 11, 0, 0, 0, 0,
-  81, 0, 34, 31, 0, 20, 0, 59, 2, 29,
-  0, 28, 67, 52, 0, 60, 0, 43, 0, 42,
-  24, 0, 22, 0, 17, 0, 7, 0, 0, 0,
-  0, 9, 8, 0, 0, 0, 16, 0, 14, 13,
-  19, 19, 30, 0, 40, 53, 0, 19, 43, 0,
-  42, 0, 0, 11, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 33, 18, 0, 37, 45, 21, 0,
-  0, 23, 29, 0, 60, 0, 0, 7, 11, 13,
-  0, 17, 0, 0, 0, 0, 1, 9, 37, 0,
-  7, 0, 52, 0, 8, 2, 2, 29, 35, 14,
-  0, 2, 25, 15, 25, 0, 0, 41, 100, 0,
-  19, 33, 52, 0, 0, 0, 0, 93, 0, 8,
-  42, 0, 0, 23, 0, 0, 0, 43, 78, 0,
-  33, 0, 0, 18, 0, 68, 0, 56, 40, 13,
-  39, 47, 17, 12, 0, 48, 0, 63, 25, 25,
-  42, 0, 13, 0, 12, 0, 4, 7, 0, 68,
-  0, 15, 1, 0, 32, 0, 7, 15, 0, 11,
-  0, 0, 44, 48, 0, 33, 43, 0, 60, 25,
-  0, 0, 0, 0, 0, 17, 0, 0, 0, 3,
-  0, 32, 43, 0, 2, 82, 3, 0, 8, 22,
-  34, 0, 25, 0, 0, 0, 17, 10, 0, 0,
-  0, 0, 0, 0, 2, 15, 15, 5, 38, 0,
-  55, 0, 13, 0, 0, 60, 0, 15, 0, 5,
-  36, 23, 2, 0, 0, 31, 86, 8, 0, 0,
-  59, 11, 0, 0, 65, 56, 0, 25, 23, 0,
-  0, 13, 0, 13, 0, 11, 92, 0, 18, 0,
-  0, 32, 0, 53, 0, 28, 0, 44, 48, 94,
-  4, 86, 0, 7, 0, 38, 52, 0, 35, 0,
-  21, 0, 24, 0, 13, 27, 0, 40, 0, 11,
-  10, 0, 33, 0, 8, 0, 25, 13, 37, 0,
-  0, 0, 0, 15, 39, 0, 14, 13, 0, 0,
-  0, 0, 0, 24, 0, 0, 0, 13, 0, 47,
-  0, 0, 62, 50, 3, 0, 0, 13, 20, 1,
-  44, 0, 24, 28, 0, 29, 0, 15, 0, 0,
-  25, 0, 11, 10, 47, 0, 42, 0, 79, 0,
-  14, 0, 3, 28, 40, 34, 0, 19, 25, 3,
-  20, 0, 0, 31, 114, 0, 21, 37, 61, 3,
-  0, 0, 0, 74, 0, 5, 57, 0, 0, 30,
-  0, 1, 0, 41, 79, 0, 10, 0, 0, 27,
-  0, 80, 0, 41, 32, 32, 31, 55, 32, 23,
-  0, 44, 0, 50, 31, 17, 17, 0, 7, 0,
-  0, 0, 12, 0, 0, 36, 0, 0, 4, 0,
-  28, 0, 17, 10, 0, 3, 3, 0, 15, 36,
-  0, 33, 36, 0, 51, 45, 0, 0, 5, 0,
-  0, 36, 0, 0, 0, 5, 0, 25, 33, 0,
-  3, 68, 5, 0, 5, 7, 24, 0, 28, 0,
-  2, 10, 6, 14, 0, 1, 0, 0, 2, 0,
-  6, 0, 15, 4, 59, 0, 74, 0, 21, 0,
-  0, 0, 0, 16, 0, 145, 3, 0, 12, 0,
-  0, 27, 50, 0, 0, 22, 2, 0, 1, 0,
-  35, 91, 18, 9, 3, 0, 0, 0, 0, 4,
-  0, 27, 23, 43, 0, 0, 0, 30, 0, 60,
-  0, 29, 0, 69, 6, 72, 26, 52, 0, 0,
-  0, 48, 12, 0, 0, 0, 56, 0, 35, 0,
-  2, 55, 0, 0, 72, 0, 0, 20, 53, 0,
-  83, 22, 17, 0, 0, 33, 2, 22, 0, 37,
-  41, 0, 32, 49, 7, 0, 27, 0, 0, 0,
-  0, 13, 1, 0, 15, 38, 0, 0, 2, 68,
-  27, 0, 0, 7, 17, 0, 22, 0, 0, 0,
-  0, 0, 0, 29, 0, 0, 104, 4, 40, 7,
-  0, 0, 0, 0, 54, 0, 3, 0, 0, 48,
-  13, 14, 0, 0, 29, 34, 3, 0, 0, 37,
-  105, 0, 2, 11, 53, 15, 0, 14, 67, 51,
-  53, 17, 9, 0, 0, 9, 0, 0, 0, 0,
-  96, 0, 32, 9, 0, 24, 0, 75, 0, 32,
-  0, 38, 68, 64, 0, 61, 0, 41, 0, 28,
-  43, 1, 16, 0, 14, 0, 11, 0, 0, 0,
-  0, 18, 0, 0, 0, 0, 17, 0, 10, 2,
-  29, 20, 37, 0, 16, 39, 0, 22, 45, 0,
-  41, 0, 0, 0, 0, 0, 0, 7, 0, 0,
-  0, 7, 0, 48, 0, 0, 52, 46, 8, 0,
-  0, 12, 18, 0, 59, 0, 0, 16, 0, 17,
-  0, 17, 0, 0, 14, 0, 6, 8, 40, 0,
-  40, 0, 76, 0, 11, 0, 4, 29, 39, 21,
-  0, 5, 28, 2, 19, 0, 0, 34, 112, 0,
-  22, 39, 53, 0, 0, 0, 0, 83, 0, 10,
-  59, 0, 0, 23, 0, 0, 0, 41, 82, 0,
-  23, 0, 0, 23, 0, 78, 0, 55, 37, 22,
-  36, 48, 30, 16, 0, 54, 0, 60, 33, 24,
-  31, 0, 11, 0, 7, 0, 17, 0, 0, 63,
-  0, 10, 7, 0, 36, 0, 8, 20, 0, 4,
-  0, 0, 33, 43, 0, 29, 44, 0, 61, 29,
-  0, 0, 0, 0, 0, 31, 0, 0, 0, 4,
-  0, 29, 42, 0, 5, 76, 2, 0, 8, 14,
-  30, 0, 21, 0, 0, 0, 8, 15, 0, 0,
-  0, 0, 0, 0, 6, 2, 19, 0, 53, 0,
-  69, 0, 17, 0, 0, 0, 0, 10, 0, 139,
-  4, 0, 12, 0, 0, 18, 33, 0, 0, 25,
-  0, 0, 0, 0, 30, 95, 19, 11, 3, 0,
-  0, 0, 0, 0, 0, 27, 29, 38, 0, 0,
-  0, 23, 0, 54, 0, 22, 0, 53, 1, 90,
-  35, 56, 0, 0, 0, 51, 6, 0, 10, 0,
-  55, 0, 49, 0, 11, 61, 0, 0, 76, 3,
-  0, 3, 55, 0, 82, 11, 11, 0, 0, 21,
-  26, 25, 0, 32, 34, 0, 41, 44, 0, 0,
-  22, 0, 0, 7, 0, 21, 4, 0, 4, 31,
-  0, 0, 7, 66, 36, 0, 0, 23, 27, 0,
-  16, 0, 0, 0, 0, 0, 0, 35, 0, 0,
-  100, 2, 34, 1, 0, 0, 0, 0, 28, 0,
-  0, 0, 5, 45, 49, 8, 0, 13, 12, 23,
-  0, 0, 0, 49, 90, 0, 0, 29, 44, 13,
-  0, 25, 68, 58, 82, 13, 0, 0, 0, 11,
-  0, 0, 0, 0, 81, 0, 34, 31, 0, 20,
-  0, 59, 2, 29, 0, 28, 67, 52, 0, 60,
-  0, 43, 0, 42, 24, 0, 22, 0, 17, 0,
-  7, 0, 0, 0, 0, 9, 8, 0, 0, 0,
-  16, 0, 14, 13, 19, 19, 30, 0, 40, 53,
-  0, 19, 43, 0, 42, 0, 0, 11, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 33, 18, 0,
-  37, 45, 21, 0, 0, 23, 29, 0, 60, 0,
-  0, 7, 11, 13, 0, 17, 0, 0, 0, 0,
-  1, 9, 37, 0, 7, 0, 52, 0, 8, 2,
-  2, 29, 35, 14, 0, 2, 25, 15, 25, 0,
-  0, 41, 100, 0, 19, 33, 52, 0, 0, 0,
-  0, 93, 0, 8, 42, 0, 0, 23, 0, 0,
-  0, 43, 78, 0, 33, 0, 0, 18, 0, 68,
-  0, 56, 40, 13, 39, 47, 17, 12, 0, 48,
-  0, 63, 25, 25, 42, 0, 13, 0, 12, 0,
-  4, 7, 0, 68, 0, 15, 1, 0, 32, 0,
-  7, 15, 0, 11, 0, 0, 44, 48, 0, 33,
-  43, 0, 60, 25, 0, 0, 0, 0, 0, 17,
-  0, 0, 0, 3, 0, 32, 43, 0, 2, 82,
-  3, 0, 8, 22, 34, 0, 25, 0, 0, 0,
-  17, 10, 0, 0, 0, 0, 0, 0, 2, 15,
-  15, 5, 38, 0, 55, 0, 13, 0, 0, 0,
-  0, 2, 0, 130, 10, 0, 4, 0, 0, 17,
-  27, 0, 0, 13, 0, 0, 0, 0, 39, 101,
-  22, 12, 0, 0, 0, 0, 0, 3, 0, 24,
-  35, 28, 1, 0, 0, 22, 0, 43, 0, 20,
-  0, 45, 17, 92, 24, 56, 0, 1, 0, 50,
-  0, 0, 17, 0, 51, 0, 51, 0, 0, 57,
-  0, 0, 72, 8, 0, 8, 34, 0, 64, 5,
-  28, 6, 0, 15, 34, 35, 0, 21, 42, 0,
-  36, 58, 0, 0, 16, 0, 0, 0, 0, 14,
-  4, 0, 0, 35, 0, 0, 0, 63, 44, 0,
-  0, 33, 35, 0, 21, 0, 0, 0, 3, 0,
-  0, 32, 0, 0, 109, 11, 25, 17, 0, 0,
-  0, 0, 15, 0, 0, 0, 3, 28, 40, 34,
-  0, 19, 25, 3, 20, 0, 0, 31, 114, 0,
-  21, 37, 61, 3, 0, 0, 0, 74, 0, 5,
-  57, 0, 0, 30, 0, 1, 0, 41, 79, 0,
-  10, 0, 0, 27, 0, 80, 0, 41, 32, 32,
-  31, 55, 32, 23, 0, 44, 0, 50, 31, 17,
-  17, 0, 7, 0, 0, 0, 12, 0, 0, 36,
-  0, 0, 4, 0, 28, 0, 17, 10, 0, 3,
-  3, 0, 15, 36, 0, 33, 36, 0, 51, 45,
-  0, 0, 5, 0, 0, 36, 0, 0, 0, 5,
-  0, 25, 33, 0, 3, 68, 5, 0, 5, 7,
-  24, 0, 28, 0, 2, 10, 6, 14, 0, 1,
-  0, 0, 2, 0, 6, 0, 15, 4, 59, 0,
-  74, 0, 21, 0, 0, 0, 0, 16, 0, 145,
-  3, 0, 12, 0, 0, 27, 50, 0, 0, 22,
-  2, 0, 1, 0, 35, 91, 18, 9, 3, 0,
-  0, 0, 0, 4, 0, 27, 23, 43, 0, 0,
-  0, 30, 0, 60, 0, 29, 0, 69, 6, 72,
-  26, 52, 0, 0, 0, 48, 12, 0, 0, 0,
-  56, 0, 35, 0, 2, 55, 0, 0, 72, 0,
-  0, 20, 53, 0, 83, 22, 17, 0, 0, 33,
-  2, 22, 0, 37, 41, 0, 32, 49, 7, 0,
-  27, 0, 0, 0, 0, 13, 1, 0, 15, 38,
-  0, 0, 2, 68, 27, 0, 0, 7, 17, 0,
-  22, 0, 0, 0, 0, 0, 0, 29, 0, 0,
-  104, 4, 40, 7, 0, 0, 0, 0, 54, 0,
-  3, 0, 0, 0, 0, 0, 0, 45, 41, 0,
-  20, 0, 0, 0, 75, 11, 19, 55, 39, 21,
-  25, 2, 84, 0, 0, 27, 13, 52, 3, 2,
-  0, 52, 0, 0, 56, 63, 0, 0, 0, 0,
-  0, 59, 0, 43, 0, 45, 7, 20, 17, 36,
-  0, 46, 0, 0, 66, 22, 0, 0, 25, 0,
-  0, 76, 20, 0, 0, 2, 0, 0, 13, 21,
-  31, 0, 0, 26, 0, 14, 8, 55, 0, 0,
-  0, 54, 58, 17, 20, 5, 37, 0, 12, 14,
-  8, 14, 4, 15, 7, 17, 1, 41, 0, 0,
-  39, 55, 6, 0, 4, 0, 0, 0, 35, 0,
-  0, 42, 13, 0, 0, 5, 0, 0, 43, 15,
-  52, 0, 18, 3, 121, 0, 68, 0, 9, 0,
-  4, 29, 39, 21, 0, 5, 28, 2, 19, 0,
-  0, 34, 112, 0, 22, 39, 53, 0, 0, 0,
-  0, 83, 0, 10, 59, 0, 0, 23, 0, 0,
-  0, 41, 82, 0, 23, 0, 0, 23, 0, 78,
-  0, 55, 37, 22, 36, 48, 30, 16, 0, 54,
-  0, 60, 33, 24, 31, 0, 11, 0, 7, 0,
-  17, 0, 0, 63, 0, 10, 7, 0, 36, 0,
-  8, 20, 0, 4, 0, 0, 33, 43, 0, 29,
-  44, 0, 61, 29, 0, 0, 0, 0, 0, 31,
-  0, 0, 0, 4, 0, 29, 42, 0, 5, 76,
-  2, 0, 8, 14, 30, 0, 21, 0, 0, 0,
-  8, 15, 0, 0, 0, 0, 0, 0, 6, 2,
-  19, 0, 53, 0, 69, 0, 17, 0, 0, 0,
-  0, 10, 0, 139, 4, 0, 12, 0, 0, 18,
-  33, 0, 0, 25, 0, 0, 0, 0, 30, 95,
-  19, 11, 3, 0, 0, 0, 0, 0, 0, 27,
-  29, 38, 0, 0, 0, 23, 0, 54, 0, 22,
-  0, 53, 1, 90, 35, 56, 0, 0, 0, 51,
-  6, 0, 10, 0, 55, 0, 49, 0, 11, 61,
-  0, 0, 76, 3, 0, 3, 55, 0, 82, 11,
-  11, 0, 0, 21, 26, 25, 0, 32, 34, 0,
-  41, 44, 0, 0, 22, 0, 0, 7, 0, 21,
-  4, 0, 4, 31, 0, 0, 7, 66, 36, 0,
-  0, 23, 27, 0, 16, 0, 0, 0, 0, 0,
-  0, 35, 0, 0, 100, 2, 34, 1, 0, 0,
-  0, 0, 28, 0, 0, 0, 0, 0, 0, 0,
-  9, 38, 29, 0, 28, 0, 15, 0, 49, 21,
-  13, 59, 25, 11, 12, 5, 68, 0, 0, 42,
-  2, 24, 1, 0, 0, 35, 0, 0, 51, 61,
-  4, 0, 0, 0, 0, 42, 8, 38, 0, 45,
-  9, 26, 16, 31, 0, 20, 23, 0, 74, 24,
-  0, 0, 43, 0, 0, 56, 26, 7, 0, 0,
-  0, 0, 26, 8, 30, 0, 0, 7, 0, 8,
-  2, 45, 9, 0, 0, 52, 52, 14, 29, 21,
-  20, 0, 7, 19, 17, 28, 6, 32, 0, 6,
-  20, 41, 0, 0, 30, 59, 7, 0, 1, 0,
-  0, 0, 35, 0, 0, 25, 13, 0, 0, 13,
-  0, 0, 41, 20, 37, 0, 1, 0, 90, 0,
-  36, 0, 0, 0, 2, 29, 35, 14, 0, 2,
-  25, 15, 25, 0, 0, 41, 100, 0, 19, 33,
-  52, 0, 0, 0, 0, 93, 0, 8, 42, 0,
-  0, 23, 0, 0, 0, 43, 78, 0, 33, 0,
-  0, 18, 0, 68, 0, 56, 40, 13, 39, 47,
-  17, 12, 0, 48, 0, 63, 25, 25, 42, 0,
-  13, 0, 12, 0, 4, 7, 0, 68, 0, 15,
-  1, 0, 32, 0, 7, 15, 0, 11, 0, 0,
-  44, 48, 0, 33, 43, 0, 60, 25, 0, 0,
-  0, 0, 0, 17, 0, 0, 0, 3, 0, 32,
-  43, 0, 2, 82, 3, 0, 8, 22, 34, 0,
-  25, 0, 0, 0, 17, 10, 0, 0, 0, 0,
-  0, 0, 2, 15, 15, 5, 38, 0, 55, 0,
-  13, 0, 0, 0, 0, 2, 0, 130, 10, 0,
-  4, 0, 0, 17, 27, 0, 0, 13, 0, 0,
-  0, 0, 39, 101, 22, 12, 0, 0, 0, 0,
-  0, 3, 0, 24, 35, 28, 1, 0, 0, 22,
-  0, 43, 0, 20, 0, 45, 17, 92, 24, 56,
-  0, 1, 0, 50, 0, 0, 17, 0, 51, 0,
-  51, 0, 0, 57, 0, 0, 72, 8, 0, 8,
-  34, 0, 64, 5, 28, 6, 0, 15, 34, 35,
-  0, 21, 42, 0, 36, 58, 0, 0, 16, 0,
-  0, 0, 0, 14, 4, 0, 0, 35, 0, 0,
-  0, 63, 44, 0, 0, 33, 35, 0, 21, 0,
-  0, 0, 3, 0, 0, 32, 0, 0, 109, 11,
-  25, 17, 0, 0, 0, 0, 15, 0, 0, 0,
-  0, 0, 0, 0, 0, 30, 33, 0, 19, 0,
-  21, 0, 43, 0, 16, 54, 29, 19, 0, 10,
-  66, 0, 0, 44, 0, 21, 4, 0, 0, 41,
-  0, 0, 53, 56, 9, 0, 0, 0, 0, 18,
-  0, 34, 0, 47, 24, 21, 4, 29, 0, 18,
-  41, 0, 75, 14, 0, 0, 37, 0, 0, 75,
-  15, 0, 0, 0, 0, 0, 34, 16, 0, 0,
-  0, 2, 0, 21, 12, 35, 14, 9, 0, 42,
-  59, 0, 15, 48, 23, 0, 5, 24, 11, 27,
-  9, 21, 0, 6, 17, 45, 0, 0, 9, 43,
-  26, 0, 0, 0, 17, 0, 51, 8, 2, 21,
-  33, 2, 0, 20, 0, 0, 46, 39, 44, 11,
-  0, 0, 80, 0, 29, 15, 0, 0, 0, 0,
-  0, 16, 0, 145, 3, 0, 12, 0, 0, 27,
-  50, 0, 0, 22, 2, 0, 1, 0, 35, 91,
-  18, 9, 3, 0, 0, 0, 0, 4, 0, 27,
-  23, 43, 0, 0, 0, 30, 0, 60, 0, 29,
-  0, 69, 6, 72, 26, 52, 0, 0, 0, 48,
-  12, 0, 0, 0, 56, 0, 35, 0, 2, 55,
-  0, 0, 72, 0, 0, 20, 53, 0, 83, 22,
-  17, 0, 0, 33, 2, 22, 0, 37, 41, 0,
-  32, 49, 7, 0, 27, 0, 0, 0, 0, 13,
-  1, 0, 15, 38, 0, 0, 2, 68, 27, 0,
-  0, 7, 17, 0, 22, 0, 0, 0, 0, 0,
-  0, 29, 0, 0, 104, 4, 40, 7, 0, 0,
-  0, 0, 54, 0, 3, 0, 0, 0, 0, 0,
-  0, 45, 41, 0, 20, 0, 0, 0, 75, 11,
-  19, 55, 39, 21, 25, 2, 84, 0, 0, 27,
-  13, 52, 3, 2, 0, 52, 0, 0, 56, 63,
-  0, 0, 0, 0, 0, 59, 0, 43, 0, 45,
-  7, 20, 17, 36, 0, 46, 0, 0, 66, 22,
-  0, 0, 25, 0, 0, 76, 20, 0, 0, 2,
-  0, 0, 13, 21, 31, 0, 0, 26, 0, 14,
-  8, 55, 0, 0, 0, 54, 58, 17, 20, 5,
-  37, 0, 12, 14, 8, 14, 4, 15, 7, 17,
-  1, 41, 0, 0, 39, 55, 6, 0, 4, 0,
-  0, 0, 35, 0, 0, 42, 13, 0, 0, 5,
-  0, 0, 43, 15, 52, 0, 18, 3, 121, 0,
-  68, 0, 9, 0, 0, 49, 1, 0, 30, 0,
-  15, 0, 64, 0, 0, 7, 46, 41, 52, 60,
-  59, 47, 14, 4, 85, 0, 0, 29, 21, 32,
-  22, 9, 0, 19, 0, 0, 33, 0, 0, 0,
-  0, 0, 0, 62, 0, 0, 0, 54, 0, 32,
-  4, 0, 0, 16, 7, 12, 54, 37, 0, 0,
-  0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
-  49, 0, 30, 0, 0, 0, 5, 29, 27, 0,
-  0, 9, 0, 21, 35, 23, 45, 0, 23, 22,
-  4, 26, 21, 30, 26, 0, 0, 24, 0, 19,
-  0, 0, 46, 43, 11, 0, 0, 0, 0, 0,
-  30, 1, 0, 44, 0, 0, 0, 16, 0, 0,
-  1, 3, 6, 0, 0, 0, 95, 0, 52, 0,
-  20, 0, 0, 0, 0, 10, 0, 139, 4, 0,
-  12, 0, 0, 18, 33, 0, 0, 25, 0, 0,
-  0, 0, 30, 95, 19, 11, 3, 0, 0, 0,
-  0, 0, 0, 27, 29, 38, 0, 0, 0, 23,
-  0, 54, 0, 22, 0, 53, 1, 90, 35, 56,
-  0, 0, 0, 51, 6, 0, 10, 0, 55, 0,
-  49, 0, 11, 61, 0, 0, 76, 3, 0, 3,
-  55, 0, 82, 11, 11, 0, 0, 21, 26, 25,
-  0, 32, 34, 0, 41, 44, 0, 0, 22, 0,
-  0, 7, 0, 21, 4, 0, 4, 31, 0, 0,
-  7, 66, 36, 0, 0, 23, 27, 0, 16, 0,
-  0, 0, 0, 0, 0, 35, 0, 0, 100, 2,
-  34, 1, 0, 0, 0, 0, 28, 0, 0, 0,
-  0, 0, 0, 0, 9, 38, 29, 0, 28, 0,
-  15, 0, 49, 21, 13, 59, 25, 11, 12, 5,
-  68, 0, 0, 42, 2, 24, 1, 0, 0, 35,
-  0, 0, 51, 61, 4, 0, 0, 0, 0, 42,
-  8, 38, 0, 45, 9, 26, 16, 31, 0, 20,
-  23, 0, 74, 24, 0, 0, 43, 0, 0, 56,
-  26, 7, 0, 0, 0, 0, 26, 8, 30, 0,
-  0, 7, 0, 8, 2, 45, 9, 0, 0, 52,
-  52, 14, 29, 21, 20, 0, 7, 19, 17, 28,
-  6, 32, 0, 6, 20, 41, 0, 0, 30, 59,
-  7, 0, 1, 0, 0, 0, 35, 0, 0, 25,
-  13, 0, 0, 13, 0, 0, 41, 20, 37, 0,
-  1, 0, 90, 0, 36, 0, 0, 0, 0, 41,
-  38, 0, 0, 0, 0, 0, 61, 6, 0, 16,
-  12, 19, 25, 54, 49, 37, 21, 5, 43, 0,
-  53, 32, 0, 0, 35, 21, 0, 0, 0, 0,
-  32, 0, 3, 0, 0, 0, 0, 35, 0, 0,
-  0, 27, 0, 26, 0, 0, 0, 15, 28, 3,
-  38, 9, 0, 0, 27, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 56, 0, 5, 0, 0, 0,
-  1, 44, 11, 11, 0, 62, 0, 23, 13, 12,
-  56, 44, 1, 24, 0, 29, 27, 31, 52, 10,
-  0, 0, 12, 0, 0, 0, 11, 51, 42, 0,
-  0, 0, 0, 0, 41, 0, 0, 48, 5, 0,
-  0, 10, 0, 0, 7, 0, 0, 0, 0, 0,
-  47, 0, 21, 0, 1, 20, 0, 0, 0, 2,
-  0, 130, 10, 0, 4, 0, 0, 17, 27, 0,
-  0, 13, 0, 0, 0, 0, 39, 101, 22, 12,
-  0, 0, 0, 0, 0, 3, 0, 24, 35, 28,
-  1, 0, 0, 22, 0, 43, 0, 20, 0, 45,
-  17, 92, 24, 56, 0, 1, 0, 50, 0, 0,
-  17, 0, 51, 0, 51, 0, 0, 57, 0, 0,
-  72, 8, 0, 8, 34, 0, 64, 5, 28, 6,
-  0, 15, 34, 35, 0, 21, 42, 0, 36, 58,
-  0, 0, 16, 0, 0, 0, 0, 14, 4, 0,
-  0, 35, 0, 0, 0, 63, 44, 0, 0, 33,
-  35, 0, 21, 0, 0, 0, 3, 0, 0, 32,
-  0, 0, 109, 11, 25, 17, 0, 0, 0, 0,
-  15, 0, 0, 0, 0, 0, 0, 0, 0, 30,
-  33, 0, 19, 0, 21, 0, 43, 0, 16, 54,
-  29, 19, 0, 10, 66, 0, 0, 44, 0, 21,
-  4, 0, 0, 41, 0, 0, 53, 56, 9, 0,
-  0, 0, 0, 18, 0, 34, 0, 47, 24, 21,
-  4, 29, 0, 18, 41, 0, 75, 14, 0, 0,
-  37, 0, 0, 75, 15, 0, 0, 0, 0, 0,
-  34, 16, 0, 0, 0, 2, 0, 21, 12, 35,
-  14, 9, 0, 42, 59, 0, 15, 48, 23, 0,
-  5, 24, 11, 27, 9, 21, 0, 6, 17, 45,
-  0, 0, 9, 43, 26, 0, 0, 0, 17, 0,
-  51, 8, 2, 21, 33, 2, 0, 20, 0, 0,
-  46, 39, 44, 11, 0, 0, 80, 0, 29, 15,
-  0, 0, 0, 47, 63, 0, 0, 0, 0, 0,
-  44, 1, 0, 11, 10, 3, 0, 58, 41, 16,
-  11, 0, 10, 0, 65, 40, 0, 0, 36, 16,
-  0, 0, 0, 0, 20, 0, 20, 14, 0, 0,
-  0, 16, 0, 3, 0, 22, 0, 2, 0, 0,
-  0, 1, 57, 3, 31, 0, 0, 0, 29, 0,
-  0, 14, 3, 0, 0, 0, 16, 0, 39, 2,
-  0, 0, 0, 0, 0, 49, 17, 0, 0, 86,
-  0, 30, 13, 0, 52, 56, 3, 30, 0, 29,
-  23, 24, 50, 0, 0, 0, 17, 0, 0, 0,
-  0, 53, 48, 0, 0, 0, 13, 0, 61, 0,
-  0, 31, 25, 0, 0, 5, 0, 0, 7, 0,
-  0, 16, 0, 0, 30, 0, 18, 13, 0, 31,
-  0, 0, 0, 0, 0, 45, 41, 0, 20, 0,
-  0, 0, 75, 11, 19, 55, 39, 21, 25, 2,
-  84, 0, 0, 27, 13, 52, 3, 2, 0, 52,
-  0, 0, 56, 63, 0, 0, 0, 0, 0, 59,
-  0, 43, 0, 45, 7, 20, 17, 36, 0, 46,
-  0, 0, 66, 22, 0, 0, 25, 0, 0, 76,
-  20, 0, 0, 2, 0, 0, 13, 21, 31, 0,
-  0, 26, 0, 14, 8, 55, 0, 0, 0, 54,
-  58, 17, 20, 5, 37, 0, 12, 14, 8, 14,
-  4, 15, 7, 17, 1, 41, 0, 0, 39, 55,
-  6, 0, 4, 0, 0, 0, 35, 0, 0, 42,
-  13, 0, 0, 5, 0, 0, 43, 15, 52, 0,
-  18, 3, 121, 0, 68, 0, 9, 0, 0, 49,
-  1, 0, 30, 0, 15, 0, 64, 0, 0, 7,
-  46, 41, 52, 60, 59, 47, 14, 4, 85, 0,
-  0, 29, 21, 32, 22, 9, 0, 19, 0, 0,
-  33, 0, 0, 0, 0, 0, 0, 62, 0, 0,
-  0, 54, 0, 32, 4, 0, 0, 16, 7, 12,
-  54, 37, 0, 0, 0, 0, 0, 0, 1, 0,
-  0, 0, 0, 0, 49, 0, 30, 0, 0, 0,
-  5, 29, 27, 0, 0, 9, 0, 21, 35, 23,
-  45, 0, 23, 22, 4, 26, 21, 30, 26, 0,
-  0, 24, 0, 19, 0, 0, 46, 43, 11, 0,
-  0, 0, 0, 0, 30, 1, 0, 44, 0, 0,
-  0, 16, 0, 0, 1, 3, 6, 0, 0, 0,
-  95, 0, 52, 0, 20, 0, 0, 44, 27, 0,
-  33, 0, 0, 0, 76, 0, 0, 1, 67, 69,
-  11, 51, 63, 32, 6, 0, 66, 0, 0, 38,
-  0, 0, 28, 40, 0, 0, 0, 0, 7, 0,
-  0, 0, 0, 27, 0, 47, 0, 0, 0, 20,
-  0, 38, 0, 0, 0, 16, 0, 34, 21, 7,
-  0, 0, 0, 8, 0, 0, 0, 0, 0, 0,
-  0, 0, 98, 0, 25, 5, 0, 0, 0, 78,
-  9, 0, 0, 35, 0, 0, 12, 5, 38, 41,
-  20, 53, 0, 44, 32, 14, 27, 37, 0, 13,
-  0, 0, 0, 0, 28, 63, 38, 0, 0, 0,
-  0, 0, 3, 36, 0, 61, 0, 0, 0, 5,
-  3, 0, 4, 0, 0, 0, 0, 0, 77, 0,
-  26, 0, 18, 21, 0, 0, 0, 0, 9, 38,
-  29, 0, 28, 0, 15, 0, 49, 21, 13, 59,
-  25, 11, 12, 5, 68, 0, 0, 42, 2, 24,
-  1, 0, 0, 35, 0, 0, 51, 61, 4, 0,
-  0, 0, 0, 42, 8, 38, 0, 45, 9, 26,
-  16, 31, 0, 20, 23, 0, 74, 24, 0, 0,
-  43, 0, 0, 56, 26, 7, 0, 0, 0, 0,
-  26, 8, 30, 0, 0, 7, 0, 8, 2, 45,
-  9, 0, 0, 52, 52, 14, 29, 21, 20, 0,
-  7, 19, 17, 28, 6, 32, 0, 6, 20, 41,
-  0, 0, 30, 59, 7, 0, 1, 0, 0, 0,
-  35, 0, 0, 25, 13, 0, 0, 13, 0, 0,
-  41, 20, 37, 0, 1, 0, 90, 0, 36, 0,
-  0, 0, 0, 41, 38, 0, 0, 0, 0, 0,
-  61, 6, 0, 16, 12, 19, 25, 54, 49, 37,
-  21, 5, 43, 0, 53, 32, 0, 0, 35, 21,
-  0, 0, 0, 0, 32, 0, 3, 0, 0, 0,
-  0, 35, 0, 0, 0, 27, 0, 26, 0, 0,
-  0, 15, 28, 3, 38, 9, 0, 0, 27, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 56, 0,
-  5, 0, 0, 0, 1, 44, 11, 11, 0, 62,
-  0, 23, 13, 12, 56, 44, 1, 24, 0, 29,
-  27, 31, 52, 10, 0, 0, 12, 0, 0, 0,
-  11, 51, 42, 0, 0, 0, 0, 0, 41, 0,
-  0, 48, 5, 0, 0, 10, 0, 0, 7, 0,
-  0, 0, 0, 0, 47, 0, 21, 0, 1, 20,
-  52, 0, 43, 0, 22, 0, 0, 0, 29, 0,
-  0, 0, 38, 88, 0, 0, 38, 0, 13, 0,
-  33, 104, 68, 26, 0, 0, 8, 50, 0, 0,
-  0, 10, 0, 4, 0, 0, 0, 20, 0, 11,
-  1, 0, 0, 0, 0, 16, 0, 0, 0, 7,
-  0, 77, 0, 0, 52, 0, 26, 23, 6, 0,
-  25, 0, 0, 6, 24, 0, 92, 16, 18, 73,
-  0, 0, 0, 73, 0, 0, 0, 50, 0, 0,
-  0, 0, 11, 59, 10, 49, 0, 55, 10, 0,
-  0, 37, 0, 0, 5, 0, 13, 0, 23, 61,
-  29, 7, 1, 0, 19, 2, 0, 26, 0, 53,
-  0, 7, 0, 0, 0, 23, 69, 0, 1, 0,
-  0, 31, 0, 0, 4, 0, 0, 61, 0, 0,
-  0, 0, 0, 30, 33, 0, 19, 0, 21, 0,
-  43, 0, 16, 54, 29, 19, 0, 10, 66, 0,
-  0, 44, 0, 21, 4, 0, 0, 41, 0, 0,
-  53, 56, 9, 0, 0, 0, 0, 18, 0, 34,
-  0, 47, 24, 21, 4, 29, 0, 18, 41, 0,
-  75, 14, 0, 0, 37, 0, 0, 75, 15, 0,
-  0, 0, 0, 0, 34, 16, 0, 0, 0, 2,
-  0, 21, 12, 35, 14, 9, 0, 42, 59, 0,
-  15, 48, 23, 0, 5, 24, 11, 27, 9, 21,
-  0, 6, 17, 45, 0, 0, 9, 43, 26, 0,
-  0, 0, 17, 0, 51, 8, 2, 21, 33, 2,
-  0, 20, 0, 0, 46, 39, 44, 11, 0, 0,
-  80, 0, 29, 15, 0, 0, 0, 47, 63, 0,
-  0, 0, 0, 0, 44, 1, 0, 11, 10, 3,
-  0, 58, 41, 16, 11, 0, 10, 0, 65, 40,
-  0, 0, 36, 16, 0, 0, 0, 0, 20, 0,
-  20, 14, 0, 0, 0, 16, 0, 3, 0, 22,
-  0, 2, 0, 0, 0, 1, 57, 3, 31, 0,
-  0, 0, 29, 0, 0, 14, 3, 0, 0, 0,
-  16, 0, 39, 2, 0, 0, 0, 0, 0, 49,
-  17, 0, 0, 86, 0, 30, 13, 0, 52, 56,
-  3, 30, 0, 29, 23, 24, 50, 0, 0, 0,
-  17, 0, 0, 0, 0, 53, 48, 0, 0, 0,
-  13, 0, 61, 0, 0, 31, 25, 0, 0, 5,
-  0, 0, 7, 0, 0, 16, 0, 0, 30, 0,
-  18, 13, 0, 31, 103, 0, 37, 5, 6, 15,
-  0, 0, 15, 0, 0, 23, 47, 54, 0, 0,
-  22, 0, 6, 0, 0, 173, 80, 13, 0, 0,
-  0, 33, 0, 0, 2, 56, 0, 34, 0, 21,
-  0, 29, 0, 25, 0, 22, 0, 0, 27, 6,
-  10, 8, 0, 0, 0, 77, 0, 0, 89, 0,
-  43, 20, 45, 0, 35, 11, 0, 32, 30, 49,
-  7, 15, 23, 23, 7, 28, 0, 22, 0, 0,
-  3, 45, 0, 13, 0, 0, 4, 42, 8, 27,
-  0, 9, 0, 0, 0, 0, 8, 0, 7, 0,
-  24, 0, 27, 61, 2, 0, 25, 0, 40, 28,
-  4, 8, 10, 35, 4, 0, 0, 0, 0, 15,
-  78, 0, 23, 10, 0, 35, 0, 0, 20, 3,
-  3, 48, 0, 49, 1, 0, 30, 0, 15, 0,
-  64, 0, 0, 7, 46, 41, 52, 60, 59, 47,
-  14, 4, 85, 0, 0, 29, 21, 32, 22, 9,
-  0, 19, 0, 0, 33, 0, 0, 0, 0, 0,
-  0, 62, 0, 0, 0, 54, 0, 32, 4, 0,
-  0, 16, 7, 12, 54, 37, 0, 0, 0, 0,
-  0, 0, 1, 0, 0, 0, 0, 0, 49, 0,
-  30, 0, 0, 0, 5, 29, 27, 0, 0, 9,
-  0, 21, 35, 23, 45, 0, 23, 22, 4, 26,
-  21, 30, 26, 0, 0, 24, 0, 19, 0, 0,
-  46, 43, 11, 0, 0, 0, 0, 0, 30, 1,
-  0, 44, 0, 0, 0, 16, 0, 0, 1, 3,
-  6, 0, 0, 0, 95, 0, 52, 0, 20, 0,
-  0, 44, 27, 0, 33, 0, 0, 0, 76, 0,
-  0, 1, 67, 69, 11, 51, 63, 32, 6, 0,
-  66, 0, 0, 38, 0, 0, 28, 40, 0, 0,
-  0, 0, 7, 0, 0, 0, 0, 27, 0, 47,
-  0, 0, 0, 20, 0, 38, 0, 0, 0, 16,
-  0, 34, 21, 7, 0, 0, 0, 8, 0, 0,
-  0, 0, 0, 0, 0, 0, 98, 0, 25, 5,
-  0, 0, 0, 78, 9, 0, 0, 35, 0, 0,
-  12, 5, 38, 41, 20, 53, 0, 44, 32, 14,
-  27, 37, 0, 13, 0, 0, 0, 0, 28, 63,
-  38, 0, 0, 0, 0, 0, 3, 36, 0, 61,
-  0, 0, 0, 5, 3, 0, 4, 0, 0, 0,
-  0, 0, 77, 0, 26, 0, 18, 21, 29, 0,
-  57, 0, 12, 30, 0, 0, 52, 0, 0, 2,
-  43, 101, 14, 0, 40, 0, 0, 0, 32, 66,
-  0, 35, 0, 0, 0, 29, 0, 8, 0, 0,
-  0, 11, 0, 0, 0, 50, 0, 48, 0, 31,
-  0, 0, 0, 0, 0, 0, 6, 9, 0, 67,
-  0, 0, 11, 0, 13, 40, 0, 0, 5, 7,
-  0, 44, 0, 15, 58, 0, 30, 45, 0, 14,
-  0, 32, 0, 0, 0, 10, 0, 27, 0, 3,
-  29, 32, 45, 49, 0, 64, 21, 0, 0, 14,
-  0, 0, 0, 0, 0, 0, 30, 78, 0, 0,
-  0, 0, 0, 18, 0, 23, 14, 57, 17, 0,
-  0, 0, 29, 0, 59, 1, 9, 2, 0, 17,
-  0, 0, 0, 0, 0, 41, 0, 41, 38, 0,
-  0, 0, 0, 0, 61, 6, 0, 16, 12, 19,
-  25, 54, 49, 37, 21, 5, 43, 0, 53, 32,
-  0, 0, 35, 21, 0, 0, 0, 0, 32, 0,
-  3, 0, 0, 0, 0, 35, 0, 0, 0, 27,
-  0, 26, 0, 0, 0, 15, 28, 3, 38, 9,
-  0, 0, 27, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 56, 0, 5, 0, 0, 0, 1, 44,
-  11, 11, 0, 62, 0, 23, 13, 12, 56, 44,
-  1, 24, 0, 29, 27, 31, 52, 10, 0, 0,
-  12, 0, 0, 0, 11, 51, 42, 0, 0, 0,
-  0, 0, 41, 0, 0, 48, 5, 0, 0, 10,
-  0, 0, 7, 0, 0, 0, 0, 0, 47, 0,
-  21, 0, 1, 20, 52, 0, 43, 0, 22, 0,
-  0, 0, 29, 0, 0, 0, 38, 88, 0, 0,
-  38, 0, 13, 0, 33, 104, 68, 26, 0, 0,
-  8, 50, 0, 0, 0, 10, 0, 4, 0, 0,
-  0, 20, 0, 11, 1, 0, 0, 0, 0, 16,
-  0, 0, 0, 7, 0, 77, 0, 0, 52, 0,
-  26, 23, 6, 0, 25, 0, 0, 6, 24, 0,
-  92, 16, 18, 73, 0, 0, 0, 73, 0, 0,
-  0, 50, 0, 0, 0, 0, 11, 59, 10, 49,
-  0, 55, 10, 0, 0, 37, 0, 0, 5, 0,
-  13, 0, 23, 61, 29, 7, 1, 0, 19, 2,
-  0, 26, 0, 53, 0, 7, 0, 0, 0, 23,
-  69, 0, 1, 0, 0, 31, 0, 0, 4, 0,
-  0, 61, 44, 0, 0, 0, 25, 73, 0, 0,
-  7, 0, 0, 0, 26, 81, 0, 0, 48, 0,
-  0, 0, 40, 70, 0, 48, 0, 0, 0, 16,
-  0, 0, 0, 0, 0, 39, 0, 0, 0, 36,
-  0, 27, 0, 6, 0, 0, 20, 1, 0, 24,
-  22, 0, 0, 39, 0, 0, 0, 0, 10, 25,
-  0, 0, 31, 12, 0, 4, 0, 0, 87, 23,
-  22, 30, 0, 6, 0, 43, 7, 0, 0, 5,
-  0, 16, 0, 0, 0, 7, 9, 33, 0, 49,
-  1, 0, 0, 56, 0, 0, 0, 0, 0, 0,
-  17, 64, 6, 22, 16, 0, 10, 13, 0, 13,
-  8, 65, 0, 0, 0, 0, 0, 16, 82, 0,
-  8, 0, 12, 7, 0, 0, 0, 7, 4, 20,
-  0, 47, 63, 0, 0, 0, 0, 0, 44, 1,
-  0, 11, 10, 3, 0, 58, 41, 16, 11, 0,
-  10, 0, 65, 40, 0, 0, 36, 16, 0, 0,
-  0, 0, 20, 0, 20, 14, 0, 0, 0, 16,
-  0, 3, 0, 22, 0, 2, 0, 0, 0, 1,
-  57, 3, 31, 0, 0, 0, 29, 0, 0, 14,
-  3, 0, 0, 0, 16, 0, 39, 2, 0, 0,
-  0, 0, 0, 49, 17, 0, 0, 86, 0, 30,
-  13, 0, 52, 56, 3, 30, 0, 29, 23, 24,
-  50, 0, 0, 0, 17, 0, 0, 0, 0, 53,
-  48, 0, 0, 0, 13, 0, 61, 0, 0, 31,
-  25, 0, 0, 5, 0, 0, 7, 0, 0, 16,
-  0, 0, 30, 0, 18, 13, 0, 31, 103, 0,
-  37, 5, 6, 15, 0, 0, 15, 0, 0, 23,
-  47, 54, 0, 0, 22, 0, 6, 0, 0, 173,
-  80, 13, 0, 0, 0, 33, 0, 0, 2, 56,
-  0, 34, 0, 21, 0, 29, 0, 25, 0, 22,
-  0, 0, 27, 6, 10, 8, 0, 0, 0, 77,
-  0, 0, 89, 0, 43, 20, 45, 0, 35, 11,
-  0, 32, 30, 49, 7, 15, 23, 23, 7, 28,
-  0, 22, 0, 0, 3, 45, 0, 13, 0, 0,
-  4, 42, 8, 27, 0, 9, 0, 0, 0, 0,
-  8, 0, 7, 0, 24, 0, 27, 61, 2, 0,
-  25, 0, 40, 28, 4, 8, 10, 35, 4, 0,
-  0, 0, 0, 15, 78, 0, 23, 10, 0, 35,
-  0, 0, 20, 3, 3, 48, 45, 0, 0, 0,
-  22, 82, 0, 0, 8, 0, 0, 0, 29, 61,
-  0, 8, 48, 0, 0, 0, 21, 71, 5, 41,
-  10, 3, 0, 14, 0, 2, 0, 9, 0, 69,
-  34, 19, 0, 41, 0, 34, 7, 20, 0, 34,
-  59, 23, 26, 10, 5, 0, 0, 0, 0, 0,
-  0, 0, 18, 22, 10, 15, 30, 39, 10, 0,
-  0, 0, 16, 36, 52, 0, 27, 32, 3, 0,
-  12, 28, 0, 21, 0, 48, 0, 2, 0, 34,
-  13, 5, 17, 11, 0, 25, 0, 47, 10, 1,
-  26, 5, 0, 0, 0, 67, 13, 0, 12, 0,
-  16, 0, 0, 15, 0, 51, 0, 0, 0, 0,
-  0, 0, 69, 0, 19, 0, 19, 11, 0, 0,
-  29, 2, 31, 0, 0, 44, 27, 0, 33, 0,
-  0, 0, 76, 0, 0, 1, 67, 69, 11, 51,
-  63, 32, 6, 0, 66, 0, 0, 38, 0, 0,
-  28, 40, 0, 0, 0, 0, 7, 0, 0, 0,
-  0, 27, 0, 47, 0, 0, 0, 20, 0, 38,
-  0, 0, 0, 16, 0, 34, 21, 7, 0, 0,
-  0, 8, 0, 0, 0, 0, 0, 0, 0, 0,
-  98, 0, 25, 5, 0, 0, 0, 78, 9, 0,
-  0, 35, 0, 0, 12, 5, 38, 41, 20, 53,
-  0, 44, 32, 14, 27, 37, 0, 13, 0, 0,
-  0, 0, 28, 63, 38, 0, 0, 0, 0, 0,
-  3, 36, 0, 61, 0, 0, 0, 5, 3, 0,
-  4, 0, 0, 0, 0, 0, 77, 0, 26, 0,
-  18, 21, 29, 0, 57, 0, 12, 30, 0, 0,
-  52, 0, 0, 2, 43, 101, 14, 0, 40, 0,
-  0, 0, 32, 66, 0, 35, 0, 0, 0, 29,
-  0, 8, 0, 0, 0, 11, 0, 0, 0, 50,
-  0, 48, 0, 31, 0, 0, 0, 0, 0, 0,
-  6, 9, 0, 67, 0, 0, 11, 0, 13, 40,
-  0, 0, 5, 7, 0, 44, 0, 15, 58, 0,
-  30, 45, 0, 14, 0, 32, 0, 0, 0, 10,
-  0, 27, 0, 3, 29, 32, 45, 49, 0, 64,
-  21, 0, 0, 14, 0, 0, 0, 0, 0, 0,
-  30, 78, 0, 0, 0, 0, 0, 18, 0, 23,
-  14, 57, 17, 0, 0, 0, 29, 0, 59, 1,
-  9, 2, 0, 17, 0, 0, 0, 0, 0, 41,
-  0, 0, 0, 0, 31, 51, 0, 0, 37, 2,
-  0, 0, 4, 70, 43, 0, 24, 35, 0, 14,
-  56, 0, 0, 39, 0, 0, 9, 13, 0, 36,
-  0, 0, 0, 14, 0, 0, 0, 19, 0, 41,
-  0, 0, 0, 5, 3, 0, 4, 0, 0, 0,
-  23, 13, 20, 0, 0, 0, 18, 34, 0, 0,
-  4, 17, 0, 0, 0, 0, 21, 0, 0, 0,
-  0, 23, 10, 1, 39, 9, 0, 0, 1, 25,
-  3, 20, 0, 8, 17, 5, 38, 41, 32, 19,
-  10, 0, 6, 0, 0, 0, 0, 5, 45, 39,
-  4, 0, 0, 0, 0, 31, 0, 9, 12, 73,
-  0, 0, 0, 0, 2, 0, 65, 11, 0, 5,
-  37, 0, 20, 0, 0, 11, 0, 8, 52, 0,
-  43, 0, 22, 0, 0, 0, 29, 0, 0, 0,
-  38, 88, 0, 0, 38, 0, 13, 0, 33, 104,
-  68, 26, 0, 0, 8, 50, 0, 0, 0, 10,
-  0, 4, 0, 0, 0, 20, 0, 11, 1, 0,
-  0, 0, 0, 16, 0, 0, 0, 7, 0, 77,
-  0, 0, 52, 0, 26, 23, 6, 0, 25, 0,
-  0, 6, 24, 0, 92, 16, 18, 73, 0, 0,
-  0, 73, 0, 0, 0, 50, 0, 0, 0, 0,
-  11, 59, 10, 49, 0, 55, 10, 0, 0, 37,
-  0, 0, 5, 0, 13, 0, 23, 61, 29, 7,
-  1, 0, 19, 2, 0, 26, 0, 53, 0, 7,
-  0, 0, 0, 23, 69, 0, 1, 0, 0, 31,
-  0, 0, 4, 0, 0, 61, 44, 0, 0, 0,
-  25, 73, 0, 0, 7, 0, 0, 0, 26, 81,
-  0, 0, 48, 0, 0, 0, 40, 70, 0, 48,
-  0, 0, 0, 16, 0, 0, 0, 0, 0, 39,
-  0, 0, 0, 36, 0, 27, 0, 6, 0, 0,
-  20, 1, 0, 24, 22, 0, 0, 39, 0, 0,
-  0, 0, 10, 25, 0, 0, 31, 12, 0, 4,
-  0, 0, 87, 23, 22, 30, 0, 6, 0, 43,
-  7, 0, 0, 5, 0, 16, 0, 0, 0, 7,
-  9, 33, 0, 49, 1, 0, 0, 56, 0, 0,
-  0, 0, 0, 0, 17, 64, 6, 22, 16, 0,
-  10, 13, 0, 13, 8, 65, 0, 0, 0, 0,
-  0, 16, 82, 0, 8, 0, 12, 7, 0, 0,
-  0, 7, 4, 20, 0, 17, 0, 0, 21, 28,
-  30, 14, 58, 16, 0, 5, 32, 30, 51, 35,
-  42, 53, 0, 21, 81, 0, 0, 49, 7, 50,
-  21, 0, 0, 19, 0, 0, 2, 16, 18, 0,
-  0, 7, 0, 43, 0, 40, 0, 33, 27, 19,
-  0, 12, 0, 0, 23, 0, 84, 2, 0, 0,
-  0, 0, 0, 29, 0, 0, 0, 0, 0, 0,
-  33, 0, 0, 0, 0, 25, 18, 30, 44, 27,
-  0, 0, 0, 44, 47, 23, 14, 0, 26, 7,
-  56, 14, 51, 35, 8, 27, 0, 39, 0, 19,
-  0, 4, 43, 43, 0, 0, 0, 0, 0, 0,
-  8, 13, 9, 61, 0, 0, 0, 0, 12, 0,
-  28, 21, 21, 0, 50, 0, 111, 0, 14, 14,
-  3, 0, 103, 0, 37, 5, 6, 15, 0, 0,
-  15, 0, 0, 23, 47, 54, 0, 0, 22, 0,
-  6, 0, 0, 173, 80, 13, 0, 0, 0, 33,
-  0, 0, 2, 56, 0, 34, 0, 21, 0, 29,
-  0, 25, 0, 22, 0, 0, 27, 6, 10, 8,
-  0, 0, 0, 77, 0, 0, 89, 0, 43, 20,
-  45, 0, 35, 11, 0, 32, 30, 49, 7, 15,
-  23, 23, 7, 28, 0, 22, 0, 0, 3, 45,
-  0, 13, 0, 0, 4, 42, 8, 27, 0, 9,
-  0, 0, 0, 0, 8, 0, 7, 0, 24, 0,
-  27, 61, 2, 0, 25, 0, 40, 28, 4, 8,
-  10, 35, 4, 0, 0, 0, 0, 15, 78, 0,
-  23, 10, 0, 35, 0, 0, 20, 3, 3, 48,
-  45, 0, 0, 0, 22, 82, 0, 0, 8, 0,
-  0, 0, 29, 61, 0, 8, 48, 0, 0, 0,
-  21, 71, 5, 41, 10, 3, 0, 14, 0, 2,
-  0, 9, 0, 69, 34, 19, 0, 41, 0, 34,
-  7, 20, 0, 34, 59, 23, 26, 10, 5, 0,
-  0, 0, 0, 0, 0, 0, 18, 22, 10, 15,
-  30, 39, 10, 0, 0, 0, 16, 36, 52, 0,
-  27, 32, 3, 0, 12, 28, 0, 21, 0, 48,
-  0, 2, 0, 34, 13, 5, 17, 11, 0, 25,
-  0, 47, 10, 1, 26, 5, 0, 0, 0, 67,
-  13, 0, 12, 0, 16, 0, 0, 15, 0, 51,
-  0, 0, 0, 0, 0, 0, 69, 0, 19, 0,
-  19, 11, 0, 0, 29, 2, 31, 0, 0, 24,
-  0, 0, 40, 11, 0, 0, 61, 11, 0, 15,
-  51, 85, 31, 58, 61, 16, 0, 9, 60, 0,
-  0, 53, 11, 51, 1, 8, 0, 10, 0, 0,
-  0, 42, 35, 0, 15, 23, 0, 51, 12, 18,
-  0, 69, 33, 20, 9, 0, 0, 0, 24, 0,
-  57, 28, 0, 0, 0, 2, 0, 18, 0, 0,
-  0, 0, 0, 0, 31, 0, 42, 0, 0, 0,
-  4, 14, 36, 12, 0, 6, 0, 29, 44, 60,
-  4, 0, 34, 12, 53, 16, 53, 25, 0, 50,
-  0, 27, 0, 9, 0, 0, 31, 64, 0, 0,
-  0, 0, 0, 0, 0, 12, 10, 60, 0, 0,
-  0, 0, 0, 0, 10, 13, 32, 0, 25, 0,
-  76, 0, 51, 15, 31, 0, 29, 0, 57, 0,
-  12, 30, 0, 0, 52, 0, 0, 2, 43, 101,
-  14, 0, 40, 0, 0, 0, 32, 66, 0, 35,
-  0, 0, 0, 29, 0, 8, 0, 0, 0, 11,
-  0, 0, 0, 50, 0, 48, 0, 31, 0, 0,
-  0, 0, 0, 0, 6, 9, 0, 67, 0, 0,
-  11, 0, 13, 40, 0, 0, 5, 7, 0, 44,
-  0, 15, 58, 0, 30, 45, 0, 14, 0, 32,
-  0, 0, 0, 10, 0, 27, 0, 3, 29, 32,
-  45, 49, 0, 64, 21, 0, 0, 14, 0, 0,
-  0, 0, 0, 0, 30, 78, 0, 0, 0, 0,
-  0, 18, 0, 23, 14, 57, 17, 0, 0, 0,
-  29, 0, 59, 1, 9, 2, 0, 17, 0, 0,
-  0, 0, 0, 41, 0, 0, 0, 0, 31, 51,
-  0, 0, 37, 2, 0, 0, 4, 70, 43, 0,
-  24, 35, 0, 14, 56, 0, 0, 39, 0, 0,
-  9, 13, 0, 36, 0, 0, 0, 14, 0, 0,
-  0, 19, 0, 41, 0, 0, 0, 5, 3, 0,
-  4, 0, 0, 0, 23, 13, 20, 0, 0, 0,
-  18, 34, 0, 0, 4, 17, 0, 0, 0, 0,
-  21, 0, 0, 0, 0, 23, 10, 1, 39, 9,
-  0, 0, 1, 25, 3, 20, 0, 8, 17, 5,
-  38, 41, 32, 19, 10, 0, 6, 0, 0, 0,
-  0, 5, 45, 39, 4, 0, 0, 0, 0, 31,
-  0, 9, 12, 73, 0, 0, 0, 0, 2, 0,
-  65, 11, 0, 5, 37, 0, 20, 0, 0, 11,
-  0, 8, 0, 32, 0, 0, 31, 0, 19, 0,
-  50, 0, 0, 16, 7, 64, 58, 24, 16, 46,
-  0, 28, 76, 0, 0, 47, 16, 40, 25, 0,
-  0, 27, 0, 0, 0, 37, 5, 0, 0, 0,
-  0, 29, 0, 1, 0, 41, 21, 3, 4, 6,
-  0, 0, 60, 0, 56, 11, 0, 0, 8, 6,
-  0, 26, 13, 0, 0, 0, 0, 0, 17, 6,
-  0, 0, 0, 25, 0, 0, 41, 13, 0, 0,
-  0, 30, 48, 39, 12, 0, 31, 0, 58, 23,
-  37, 56, 3, 0, 8, 19, 0, 16, 0, 10,
-  57, 33, 0, 0, 0, 0, 0, 0, 23, 0,
-  31, 59, 0, 0, 0, 1, 24, 0, 21, 0,
-  8, 0, 47, 0, 77, 0, 1, 23, 9, 0,
-  44, 0, 0, 0, 25, 73, 0, 0, 7, 0,
-  0, 0, 26, 81, 0, 0, 48, 0, 0, 0,
-  40, 70, 0, 48, 0, 0, 0, 16, 0, 0,
-  0, 0, 0, 39, 0, 0, 0, 36, 0, 27,
-  0, 6, 0, 0, 20, 1, 0, 24, 22, 0,
-  0, 39, 0, 0, 0, 0, 10, 25, 0, 0,
-  31, 12, 0, 4, 0, 0, 87, 23, 22, 30,
-  0, 6, 0, 43, 7, 0, 0, 5, 0, 16,
-  0, 0, 0, 7, 9, 33, 0, 49, 1, 0,
-  0, 56, 0, 0, 0, 0, 0, 0, 17, 64,
-  6, 22, 16, 0, 10, 13, 0, 13, 8, 65,
-  0, 0, 0, 0, 0, 16, 82, 0, 8, 0,
-  12, 7, 0, 0, 0, 7, 4, 20, 0, 17,
-  0, 0, 21, 28, 30, 14, 58, 16, 0, 5,
-  32, 30, 51, 35, 42, 53, 0, 21, 81, 0,
-  0, 49, 7, 50, 21, 0, 0, 19, 0, 0,
-  2, 16, 18, 0, 0, 7, 0, 43, 0, 40,
-  0, 33, 27, 19, 0, 12, 0, 0, 23, 0,
-  84, 2, 0, 0, 0, 0, 0, 29, 0, 0,
-  0, 0, 0, 0, 33, 0, 0, 0, 0, 25,
-  18, 30, 44, 27, 0, 0, 0, 44, 47, 23,
-  14, 0, 26, 7, 56, 14, 51, 35, 8, 27,
-  0, 39, 0, 19, 0, 4, 43, 43, 0, 0,
-  0, 0, 0, 0, 8, 13, 9, 61, 0, 0,
-  0, 0, 12, 0, 28, 21, 21, 0, 50, 0,
-  111, 0, 14, 14, 3, 0, 0, 47, 23, 0,
-  8, 0, 33, 0, 55, 0, 0, 17, 28, 56,
-  45, 66, 49, 49, 0, 15, 78, 0, 0, 46,
-  13, 29, 27, 0, 0, 0, 14, 0, 11, 19,
-  4, 0, 0, 0, 0, 33, 12, 13, 0, 55,
-  6, 0, 0, 0, 0, 0, 63, 12, 64, 29,
-  0, 0, 0, 0, 0, 23, 0, 0, 0, 0,
-  0, 0, 42, 0, 0, 0, 0, 0, 0, 41,
-  36, 0, 0, 29, 0, 27, 65, 51, 36, 6,
-  50, 11, 55, 0, 58, 33, 0, 14, 0, 30,
-  0, 20, 0, 12, 43, 51, 0, 0, 0, 0,
-  0, 0, 5, 6, 14, 33, 30, 0, 0, 0,
-  41, 0, 0, 0, 5, 0, 0, 0, 81, 0,
-  6, 22, 17, 0, 45, 0, 0, 0, 22, 82,
-  0, 0, 8, 0, 0, 0, 29, 61, 0, 8,
-  48, 0, 0, 0, 21, 71, 5, 41, 10, 3,
-  0, 14, 0, 2, 0, 9, 0, 69, 34, 19,
-  0, 41, 0, 34, 7, 20, 0, 34, 59, 23,
-  26, 10, 5, 0, 0, 0, 0, 0, 0, 0,
-  18, 22, 10, 15, 30, 39, 10, 0, 0, 0,
-  16, 36, 52, 0, 27, 32, 3, 0, 12, 28,
-  0, 21, 0, 48, 0, 2, 0, 34, 13, 5,
-  17, 11, 0, 25, 0, 47, 10, 1, 26, 5,
-  0, 0, 0, 67, 13, 0, 12, 0, 16, 0,
-  0, 15, 0, 51, 0, 0, 0, 0, 0, 0,
-  69, 0, 19, 0, 19, 11, 0, 0, 29, 2,
-  31, 0, 0, 24, 0, 0, 40, 11, 0, 0,
-  61, 11, 0, 15, 51, 85, 31, 58, 61, 16,
-  0, 9, 60, 0, 0, 53, 11, 51, 1, 8,
-  0, 10, 0, 0, 0, 42, 35, 0, 15, 23,
-  0, 51, 12, 18, 0, 69, 33, 20, 9, 0,
-  0, 0, 24, 0, 57, 28, 0, 0, 0, 2,
-  0, 18, 0, 0, 0, 0, 0, 0, 31, 0,
-  42, 0, 0, 0, 4, 14, 36, 12, 0, 6,
-  0, 29, 44, 60, 4, 0, 34, 12, 53, 16,
-  53, 25, 0, 50, 0, 27, 0, 9, 0, 0,
-  31, 64, 0, 0, 0, 0, 0, 0, 0, 12,
-  10, 60, 0, 0, 0, 0, 0, 0, 10, 13,
-  32, 0, 25, 0, 76, 0, 51, 15, 31, 0,
-  0, 35, 50, 0, 10, 0, 0, 0, 51, 2,
-  0, 18, 8, 100, 10, 27, 39, 26, 2, 4,
-  44, 0, 34, 24, 0, 0, 0, 5, 0, 0,
-  0, 0, 0, 0, 0, 0, 5, 0, 0, 22,
-  18, 0, 0, 35, 0, 0, 0, 0, 0, 0,
-  52, 66, 0, 34, 0, 0, 6, 2, 0, 0,
-  0, 0, 13, 0, 38, 2, 22, 0, 23, 0,
-  0, 0, 3, 15, 29, 0, 0, 37, 0, 21,
-  32, 48, 11, 18, 40, 3, 53, 7, 75, 6,
-  0, 23, 0, 0, 0, 1, 0, 0, 40, 70,
-  1, 0, 0, 0, 7, 0, 0, 9, 0, 8,
-  32, 0, 0, 0, 57, 0, 10, 0, 12, 0,
-  0, 0, 8, 0, 9, 14, 37, 0, 0, 0,
-  0, 0, 31, 51, 0, 0, 37, 2, 0, 0,
-  4, 70, 43, 0, 24, 35, 0, 14, 56, 0,
-  0, 39, 0, 0, 9, 13, 0, 36, 0, 0,
-  0, 14, 0, 0, 0, 19, 0, 41, 0, 0,
-  0, 5, 3, 0, 4, 0, 0, 0, 23, 13,
-  20, 0, 0, 0, 18, 34, 0, 0, 4, 17,
-  0, 0, 0, 0, 21, 0, 0, 0, 0, 23,
-  10, 1, 39, 9, 0, 0, 1, 25, 3, 20,
-  0, 8, 17, 5, 38, 41, 32, 19, 10, 0,
-  6, 0, 0, 0, 0, 5, 45, 39, 4, 0,
-  0, 0, 0, 31, 0, 9, 12, 73, 0, 0,
-  0, 0, 2, 0, 65, 11, 0, 5, 37, 0,
-  20, 0, 0, 11, 0, 8, 0, 32, 0, 0,
-  31, 0, 19, 0, 50, 0, 0, 16, 7, 64,
-  58, 24, 16, 46, 0, 28, 76, 0, 0, 47,
-  16, 40, 25, 0, 0, 27, 0, 0, 0, 37,
-  5, 0, 0, 0, 0, 29, 0, 1, 0, 41,
-  21, 3, 4, 6, 0, 0, 60, 0, 56, 11,
-  0, 0, 8, 6, 0, 26, 13, 0, 0, 0,
-  0, 0, 17, 6, 0, 0, 0, 25, 0, 0,
-  41, 13, 0, 0, 0, 30, 48, 39, 12, 0,
-  31, 0, 58, 23, 37, 56, 3, 0, 8, 19,
-  0, 16, 0, 10, 57, 33, 0, 0, 0, 0,
-  0, 0, 23, 0, 31, 59, 0, 0, 0, 1,
-  24, 0, 21, 0, 8, 0, 47, 0, 77, 0,
-  1, 23, 9, 0, 0, 86, 6, 8, 42, 0,
-  32, 0, 64, 4, 0, 0, 6, 42, 74, 53,
-  38, 43, 0, 27, 68, 0, 0, 42, 0, 47,
-  25, 9, 0, 24, 6, 0, 0, 29, 9, 0,
-  0, 0, 0, 25, 0, 26, 0, 59, 9, 0,
-  0, 24, 0, 0, 45, 0, 88, 34, 0, 0,
-  0, 0, 0, 9, 6, 0, 0, 0, 0, 0,
-  36, 0, 0, 0, 0, 0, 0, 17, 64, 0,
-  2, 0, 1, 0, 91, 28, 8, 0, 51, 13,
-  35, 13, 47, 25, 0, 0, 0, 32, 0, 22,
-  0, 0, 48, 22, 0, 7, 0, 0, 23, 0,
-  25, 21, 43, 64, 10, 0, 0, 0, 29, 0,
-  0, 0, 18, 0, 4, 0, 74, 0, 0, 37,
-  25, 0, 0, 17, 0, 0, 21, 28, 30, 14,
-  58, 16, 0, 5, 32, 30, 51, 35, 42, 53,
-  0, 21, 81, 0, 0, 49, 7, 50, 21, 0,
-  0, 19, 0, 0, 2, 16, 18, 0, 0, 7,
-  0, 43, 0, 40, 0, 33, 27, 19, 0, 12,
-  0, 0, 23, 0, 84, 2, 0, 0, 0, 0,
-  0, 29, 0, 0, 0, 0, 0, 0, 33, 0,
-  0, 0, 0, 25, 18, 30, 44, 27, 0, 0,
-  0, 44, 47, 23, 14, 0, 26, 7, 56, 14,
-  51, 35, 8, 27, 0, 39, 0, 19, 0, 4,
-  43, 43, 0, 0, 0, 0, 0, 0, 8, 13,
-  9, 61, 0, 0, 0, 0, 12, 0, 28, 21,
-  21, 0, 50, 0, 111, 0, 14, 14, 3, 0,
-  0, 47, 23, 0, 8, 0, 33, 0, 55, 0,
-  0, 17, 28, 56, 45, 66, 49, 49, 0, 15,
-  78, 0, 0, 46, 13, 29, 27, 0, 0, 0,
-  14, 0, 11, 19, 4, 0, 0, 0, 0, 33,
-  12, 13, 0, 55, 6, 0, 0, 0, 0, 0,
-  63, 12, 64, 29, 0, 0, 0, 0, 0, 23,
-  0, 0, 0, 0, 0, 0, 42, 0, 0, 0,
-  0, 0, 0, 41, 36, 0, 0, 29, 0, 27,
-  65, 51, 36, 6, 50, 11, 55, 0, 58, 33,
-  0, 14, 0, 30, 0, 20, 0, 12, 43, 51,
-  0, 0, 0, 0, 0, 0, 5, 6, 14, 33,
-  30, 0, 0, 0, 41, 0, 0, 0, 5, 0,
-  0, 0, 81, 0, 6, 22, 17, 0, 0, 43,
-  70, 0, 11, 0, 9, 0, 57, 6, 0, 0,
-  0, 60, 23, 63, 30, 38, 0, 12, 39, 0,
-  33, 35, 0, 0, 9, 14, 0, 0, 27, 0,
-  0, 0, 0, 0, 0, 17, 0, 12, 27, 0,
-  0, 40, 0, 0, 0, 0, 0, 0, 48, 52,
-  41, 12, 0, 0, 19, 12, 0, 0, 0, 0,
-  0, 0, 24, 0, 45, 0, 11, 4, 0, 0,
-  0, 28, 32, 0, 0, 18, 0, 0, 58, 19,
-  0, 21, 59, 13, 23, 9, 64, 10, 0, 32,
-  0, 0, 0, 0, 0, 0, 40, 51, 0, 0,
-  0, 0, 36, 0, 0, 22, 4, 24, 40, 0,
-  0, 0, 86, 0, 2, 0, 26, 0, 0, 1,
-  21, 0, 0, 24, 22, 0, 0, 24, 0, 0,
-  40, 11, 0, 0, 61, 11, 0, 15, 51, 85,
-  31, 58, 61, 16, 0, 9, 60, 0, 0, 53,
-  11, 51, 1, 8, 0, 10, 0, 0, 0, 42,
-  35, 0, 15, 23, 0, 51, 12, 18, 0, 69,
-  33, 20, 9, 0, 0, 0, 24, 0, 57, 28,
-  0, 0, 0, 2, 0, 18, 0, 0, 0, 0,
-  0, 0, 31, 0, 42, 0, 0, 0, 4, 14,
-  36, 12, 0, 6, 0, 29, 44, 60, 4, 0,
-  34, 12, 53, 16, 53, 25, 0, 50, 0, 27,
-  0, 9, 0, 0, 31, 64, 0, 0, 0, 0,
-  0, 0, 0, 12, 10, 60, 0, 0, 0, 0,
-  0, 0, 10, 13, 32, 0, 25, 0, 76, 0,
-  51, 15, 31, 0, 0, 35, 50, 0, 10, 0,
-  0, 0, 51, 2, 0, 18, 8, 100, 10, 27,
-  39, 26, 2, 4, 44, 0, 34, 24, 0, 0,
-  0, 5, 0, 0, 0, 0, 0, 0, 0, 0,
-  5, 0, 0, 22, 18, 0, 0, 35, 0, 0,
-  0, 0, 0, 0, 52, 66, 0, 34, 0, 0,
-  6, 2, 0, 0, 0, 0, 13, 0, 38, 2,
-  22, 0, 23, 0, 0, 0, 3, 15, 29, 0,
-  0, 37, 0, 21, 32, 48, 11, 18, 40, 3,
-  53, 7, 75, 6, 0, 23, 0, 0, 0, 1,
-  0, 0, 40, 70, 1, 0, 0, 0, 7, 0,
-  0, 9, 0, 8, 32, 0, 0, 0, 57, 0,
-  10, 0, 12, 0, 0, 0, 8, 0, 9, 14,
-  37, 0, 22, 0, 59, 0, 0, 0, 0, 0,
-  23, 0, 0, 0, 0, 116, 1, 0, 6, 27,
-  1, 0, 38, 30, 84, 8, 0, 0, 0, 4,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 2,
-  0, 0, 28, 17, 0, 30, 0, 0, 0, 0,
-  0, 0, 35, 131, 0, 15, 36, 0, 30, 17,
-  14, 0, 0, 0, 34, 0, 88, 47, 7, 2,
-  16, 67, 0, 0, 0, 0, 11, 0, 0, 0,
-  0, 24, 16, 22, 0, 15, 41, 0, 31, 10,
-  71, 0, 0, 11, 2, 0, 0, 5, 0, 0,
-  62, 66, 0, 0, 0, 0, 12, 10, 0, 7,
-  0, 0, 50, 0, 0, 0, 91, 3, 77, 0,
-  19, 0, 0, 0, 0, 0, 21, 6, 10, 0,
-  0, 32, 0, 0, 31, 0, 19, 0, 50, 0,
-  0, 16, 7, 64, 58, 24, 16, 46, 0, 28,
-  76, 0, 0, 47, 16, 40, 25, 0, 0, 27,
-  0, 0, 0, 37, 5, 0, 0, 0, 0, 29,
-  0, 1, 0, 41, 21, 3, 4, 6, 0, 0,
-  60, 0, 56, 11, 0, 0, 8, 6, 0, 26,
-  13, 0, 0, 0, 0, 0, 17, 6, 0, 0,
-  0, 25, 0, 0, 41, 13, 0, 0, 0, 30,
-  48, 39, 12, 0, 31, 0, 58, 23, 37, 56,
-  3, 0, 8, 19, 0, 16, 0, 10, 57, 33,
-  0, 0, 0, 0, 0, 0, 23, 0, 31, 59,
-  0, 0, 0, 1, 24, 0, 21, 0, 8, 0,
-  47, 0, 77, 0, 1, 23, 9, 0, 0, 86,
-  6, 8, 42, 0, 32, 0, 64, 4, 0, 0,
-  6, 42, 74, 53, 38, 43, 0, 27, 68, 0,
-  0, 42, 0, 47, 25, 9, 0, 24, 6, 0,
-  0, 29, 9, 0, 0, 0, 0, 25, 0, 26,
-  0, 59, 9, 0, 0, 24, 0, 0, 45, 0,
-  88, 34, 0, 0, 0, 0, 0, 9, 6, 0,
-  0, 0, 0, 0, 36, 0, 0, 0, 0, 0,
-  0, 17, 64, 0, 2, 0, 1, 0, 91, 28,
-  8, 0, 51, 13, 35, 13, 47, 25, 0, 0,
-  0, 32, 0, 22, 0, 0, 48, 22, 0, 7,
-  0, 0, 23, 0, 25, 21, 43, 64, 10, 0,
-  0, 0, 29, 0, 0, 0, 18, 0, 4, 0,
-  74, 0, 0, 37, 25, 0, 0, 96, 8, 3,
-  33, 0, 35, 0, 85, 3, 0, 27, 4, 58,
-  40, 66, 33, 44, 0, 33, 67, 0, 11, 33,
-  0, 10, 35, 17, 0, 0, 0, 0, 16, 0,
-  0, 0, 0, 12, 0, 0, 0, 9, 0, 67,
-  0, 25, 0, 38, 0, 0, 28, 0, 77, 30,
-  0, 0, 25, 0, 0, 0, 0, 0, 0, 0,
-  2, 0, 21, 0, 17, 0, 0, 0, 18, 29,
-  78, 0, 11, 0, 0, 0, 78, 36, 3, 0,
-  35, 3, 44, 7, 36, 20, 0, 27, 0, 26,
-  0, 8, 0, 0, 61, 33, 8, 16, 0, 0,
-  58, 0, 22, 29, 12, 37, 7, 0, 0, 0,
-  41, 0, 0, 0, 20, 0, 0, 0, 52, 0,
-  0, 31, 46, 0, 0, 47, 23, 0, 8, 0,
-  33, 0, 55, 0, 0, 17, 28, 56, 45, 66,
-  49, 49, 0, 15, 78, 0, 0, 46, 13, 29,
-  27, 0, 0, 0, 14, 0, 11, 19, 4, 0,
-  0, 0, 0, 33, 12, 13, 0, 55, 6, 0,
-  0, 0, 0, 0, 63, 12, 64, 29, 0, 0,
-  0, 0, 0, 23, 0, 0, 0, 0, 0, 0,
-  42, 0, 0, 0, 0, 0, 0, 41, 36, 0,
-  0, 29, 0, 27, 65, 51, 36, 6, 50, 11,
-  55, 0, 58, 33, 0, 14, 0, 30, 0, 20,
-  0, 12, 43, 51, 0, 0, 0, 0, 0, 0,
-  5, 6, 14, 33, 30, 0, 0, 0, 41, 0,
-  0, 0, 5, 0, 0, 0, 81, 0, 6, 22,
-  17, 0, 0, 43, 70, 0, 11, 0, 9, 0,
-  57, 6, 0, 0, 0, 60, 23, 63, 30, 38,
-  0, 12, 39, 0, 33, 35, 0, 0, 9, 14,
-  0, 0, 27, 0, 0, 0, 0, 0, 0, 17,
-  0, 12, 27, 0, 0, 40, 0, 0, 0, 0,
-  0, 0, 48, 52, 41, 12, 0, 0, 19, 12,
-  0, 0, 0, 0, 0, 0, 24, 0, 45, 0,
-  11, 4, 0, 0, 0, 28, 32, 0, 0, 18,
-  0, 0, 58, 19, 0, 21, 59, 13, 23, 9,
-  64, 10, 0, 32, 0, 0, 0, 0, 0, 0,
-  40, 51, 0, 0, 0, 0, 36, 0, 0, 22,
-  4, 24, 40, 0, 0, 0, 86, 0, 2, 0,
-  26, 0, 0, 1, 21, 0, 0, 24, 22, 0,
-  0, 1, 54, 0, 0, 0, 0, 0, 42, 0,
-  0, 7, 0, 86, 0, 0, 1, 43, 0, 15,
-  50, 15, 93, 16, 0, 0, 0, 18, 0, 0,
-  16, 0, 0, 0, 0, 0, 0, 25, 0, 0,
-  34, 33, 0, 35, 0, 0, 0, 17, 0, 0,
-  34, 96, 0, 0, 21, 0, 40, 0, 14, 0,
-  0, 2, 21, 0, 100, 23, 1, 3, 2, 71,
-  0, 0, 0, 0, 18, 0, 0, 0, 0, 0,
-  25, 5, 0, 25, 63, 0, 32, 16, 62, 0,
-  0, 28, 0, 0, 0, 0, 0, 0, 67, 44,
-  0, 0, 0, 0, 26, 0, 0, 29, 0, 5,
-  41, 0, 0, 0, 99, 0, 45, 0, 46, 0,
-  0, 13, 0, 0, 0, 6, 19, 0, 0, 35,
-  50, 0, 10, 0, 0, 0, 51, 2, 0, 18,
-  8, 100, 10, 27, 39, 26, 2, 4, 44, 0,
-  34, 24, 0, 0, 0, 5, 0, 0, 0, 0,
-  0, 0, 0, 0, 5, 0, 0, 22, 18, 0,
-  0, 35, 0, 0, 0, 0, 0, 0, 52, 66,
-  0, 34, 0, 0, 6, 2, 0, 0, 0, 0,
-  13, 0, 38, 2, 22, 0, 23, 0, 0, 0,
-  3, 15, 29, 0, 0, 37, 0, 21, 32, 48,
-  11, 18, 40, 3, 53, 7, 75, 6, 0, 23,
-  0, 0, 0, 1, 0, 0, 40, 70, 1, 0,
-  0, 0, 7, 0, 0, 9, 0, 8, 32, 0,
-  0, 0, 57, 0, 10, 0, 12, 0, 0, 0,
-  8, 0, 9, 14, 37, 0, 22, 0, 59, 0,
-  0, 0, 0, 0, 23, 0, 0, 0, 0, 116,
-  1, 0, 6, 27, 1, 0, 38, 30, 84, 8,
-  0, 0, 0, 4, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 2, 0, 0, 28, 17, 0, 30,
-  0, 0, 0, 0, 0, 0, 35, 131, 0, 15,
-  36, 0, 30, 17, 14, 0, 0, 0, 34, 0,
-  88, 47, 7, 2, 16, 67, 0, 0, 0, 0,
-  11, 0, 0, 0, 0, 24, 16, 22, 0, 15,
-  41, 0, 31, 10, 71, 0, 0, 11, 2, 0,
-  0, 5, 0, 0, 62, 66, 0, 0, 0, 0,
-  12, 10, 0, 7, 0, 0, 50, 0, 0, 0,
-  91, 3, 77, 0, 19, 0, 0, 0, 0, 0,
-  21, 6, 10, 0, 20, 0, 19, 16, 0, 0,
-  0, 0, 29, 0, 0, 0, 2, 73, 0, 0,
-  0, 28, 8, 5, 49, 5, 52, 6, 0, 0,
-  0, 7, 0, 12, 6, 1, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 29, 0, 45, 0, 0,
-  0, 16, 0, 0, 39, 114, 0, 30, 15, 0,
-  35, 10, 0, 0, 0, 0, 31, 0, 77, 23,
-  0, 26, 0, 48, 0, 8, 0, 0, 25, 0,
-  0, 0, 0, 24, 31, 18, 0, 15, 42, 0,
-  28, 19, 61, 0, 0, 0, 0, 0, 0, 9,
-  24, 0, 72, 41, 0, 0, 3, 0, 0, 0,
-  0, 13, 37, 0, 43, 0, 0, 5, 84, 0,
-  93, 0, 17, 0, 7, 5, 0, 0, 42, 4,
-  0, 0, 0, 86, 6, 8, 42, 0, 32, 0,
-  64, 4, 0, 0, 6, 42, 74, 53, 38, 43,
-  0, 27, 68, 0, 0, 42, 0, 47, 25, 9,
-  0, 24, 6, 0, 0, 29, 9, 0, 0, 0,
-  0, 25, 0, 26, 0, 59, 9, 0, 0, 24,
-  0, 0, 45, 0, 88, 34, 0, 0, 0, 0,
-  0, 9, 6, 0, 0, 0, 0, 0, 36, 0,
-  0, 0, 0, 0, 0, 17, 64, 0, 2, 0,
-  1, 0, 91, 28, 8, 0, 51, 13, 35, 13,
-  47, 25, 0, 0, 0, 32, 0, 22, 0, 0,
-  48, 22, 0, 7, 0, 0, 23, 0, 25, 21,
-  43, 64, 10, 0, 0, 0, 29, 0, 0, 0,
-  18, 0, 4, 0, 74, 0, 0, 37, 25, 0,
-  0, 96, 8, 3, 33, 0, 35, 0, 85, 3,
-  0, 27, 4, 58, 40, 66, 33, 44, 0, 33,
-  67, 0, 11, 33, 0, 10, 35, 17, 0, 0,
-  0, 0, 16, 0, 0, 0, 0, 12, 0, 0,
-  0, 9, 0, 67, 0, 25, 0, 38, 0, 0,
-  28, 0, 77, 30, 0, 0, 25, 0, 0, 0,
-  0, 0, 0, 0, 2, 0, 21, 0, 17, 0,
-  0, 0, 18, 29, 78, 0, 11, 0, 0, 0,
-  78, 36, 3, 0, 35, 3, 44, 7, 36, 20,
-  0, 27, 0, 26, 0, 8, 0, 0, 61, 33,
-  8, 16, 0, 0, 58, 0, 22, 29, 12, 37,
-  7, 0, 0, 0, 41, 0, 0, 0, 20, 0,
-  0, 0, 52, 0, 0, 31, 46, 0, 0, 50,
-  11, 21, 17, 0, 0, 0, 67, 0, 0, 42,
-  4, 106, 9, 17, 15, 45, 0, 24, 71, 0,
-  40, 19, 0, 0, 0, 3, 0, 0, 0, 0,
-  0, 10, 0, 0, 0, 0, 0, 0, 4, 19,
-  0, 50, 0, 0, 0, 45, 0, 0, 34, 65,
-  36, 45, 0, 0, 44, 0, 0, 0, 0, 0,
-  7, 0, 60, 7, 0, 7, 12, 15, 0, 0,
-  10, 2, 40, 0, 0, 0, 0, 1, 42, 35,
-  2, 0, 21, 0, 58, 15, 51, 12, 0, 30,
-  0, 0, 0, 9, 0, 0, 58, 45, 6, 2,
-  0, 0, 16, 0, 0, 13, 0, 3, 7, 0,
-  0, 0, 80, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 4, 12, 0, 0, 43, 70, 0,
-  11, 0, 9, 0, 57, 6, 0, 0, 0, 60,
-  23, 63, 30, 38, 0, 12, 39, 0, 33, 35,
-  0, 0, 9, 14, 0, 0, 27, 0, 0, 0,
-  0, 0, 0, 17, 0, 12, 27, 0, 0, 40,
-  0, 0, 0, 0, 0, 0, 48, 52, 41, 12,
-  0, 0, 19, 12, 0, 0, 0, 0, 0, 0,
-  24, 0, 45, 0, 11, 4, 0, 0, 0, 28,
-  32, 0, 0, 18, 0, 0, 58, 19, 0, 21,
-  59, 13, 23, 9, 64, 10, 0, 32, 0, 0,
-  0, 0, 0, 0, 40, 51, 0, 0, 0, 0,
-  36, 0, 0, 22, 4, 24, 40, 0, 0, 0,
-  86, 0, 2, 0, 26, 0, 0, 1, 21, 0,
-  0, 24, 22, 0, 0, 1, 54, 0, 0, 0,
-  0, 0, 42, 0, 0, 7, 0, 86, 0, 0,
-  1, 43, 0, 15, 50, 15, 93, 16, 0, 0,
-  0, 18, 0, 0, 16, 0, 0, 0, 0, 0,
-  0, 25, 0, 0, 34, 33, 0, 35, 0, 0,
-  0, 17, 0, 0, 34, 96, 0, 0, 21, 0,
-  40, 0, 14, 0, 0, 2, 21, 0, 100, 23,
-  1, 3, 2, 71, 0, 0, 0, 0, 18, 0,
-  0, 0, 0, 0, 25, 5, 0, 25, 63, 0,
-  32, 16, 62, 0, 0, 28, 0, 0, 0, 0,
-  0, 0, 67, 44, 0, 0, 0, 0, 26, 0,
-  0, 29, 0, 5, 41, 0, 0, 0, 99, 0,
-  45, 0, 46, 0, 0, 13, 0, 0, 0, 6,
-  19, 0, 16, 0, 16, 11, 0, 0, 0, 0,
-  35, 0, 0, 25, 4, 106, 0, 0, 0, 36,
-  2, 10, 68, 10, 49, 2, 0, 0, 0, 0,
-  0, 0, 0, 2, 0, 9, 0, 0, 0, 0,
-  0, 0, 5, 41, 0, 45, 0, 0, 0, 31,
-  0, 0, 66, 127, 0, 42, 14, 0, 16, 0,
-  2, 0, 0, 0, 48, 0, 110, 32, 0, 9,
-  0, 60, 0, 11, 0, 0, 22, 0, 0, 0,
-  0, 41, 18, 32, 0, 0, 51, 0, 58, 18,
-  81, 0, 0, 0, 0, 0, 0, 12, 11, 0,
-  73, 49, 0, 0, 0, 0, 6, 0, 0, 8,
-  11, 0, 36, 0, 0, 0, 95, 0, 70, 0,
-  20, 0, 1, 0, 0, 0, 8, 0, 11, 0,
-  22, 0, 59, 0, 0, 0, 0, 0, 23, 0,
-  0, 0, 0, 116, 1, 0, 6, 27, 1, 0,
-  38, 30, 84, 8, 0, 0, 0, 4, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 2, 0, 0,
-  28, 17, 0, 30, 0, 0, 0, 0, 0, 0,
-  35, 131, 0, 15, 36, 0, 30, 17, 14, 0,
-  0, 0, 34, 0, 88, 47, 7, 2, 16, 67,
-  0, 0, 0, 0, 11, 0, 0, 0, 0, 24,
-  16, 22, 0, 15, 41, 0, 31, 10, 71, 0,
-  0, 11, 2, 0, 0, 5, 0, 0, 62, 66,
-  0, 0, 0, 0, 12, 10, 0, 7, 0, 0,
-  50, 0, 0, 0, 91, 3, 77, 0, 19, 0,
-  0, 0, 0, 0, 21, 6, 10, 0, 20, 0,
-  19, 16, 0, 0, 0, 0, 29, 0, 0, 0,
-  2, 73, 0, 0, 0, 28, 8, 5, 49, 5,
-  52, 6, 0, 0, 0, 7, 0, 12, 6, 1,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 29,
-  0, 45, 0, 0, 0, 16, 0, 0, 39, 114,
-  0, 30, 15, 0, 35, 10, 0, 0, 0, 0,
-  31, 0, 77, 23, 0, 26, 0, 48, 0, 8,
-  0, 0, 25, 0, 0, 0, 0, 24, 31, 18,
-  0, 15, 42, 0, 28, 19, 61, 0, 0, 0,
-  0, 0, 0, 9, 24, 0, 72, 41, 0, 0,
-  3, 0, 0, 0, 0, 13, 37, 0, 43, 0,
-  0, 5, 84, 0, 93, 0, 17, 0, 7, 5,
-  0, 0, 42, 4, 0, 0, 3, 16, 0, 41,
-  1, 0, 4, 6, 70, 0, 0, 11, 25, 55,
-  18, 0, 14, 4, 17, 0, 52, 0, 0, 17,
-  0, 16, 4, 14, 0, 32, 2, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 25, 0, 53,
-  0, 0, 5, 16, 0, 0, 58, 87, 18, 68,
-  0, 0, 15, 25, 0, 19, 0, 0, 0, 0,
-  0, 11, 7, 13, 8, 0, 0, 9, 0, 0,
-  44, 3, 0, 0, 0, 43, 57, 57, 0, 0,
-  32, 0, 31, 33, 74, 29, 25, 0, 0, 0,
-  0, 11, 45, 0, 71, 48, 0, 0, 7, 0,
-  2, 0, 0, 12, 74, 6, 34, 0, 0, 0,
-  67, 0, 49, 0, 0, 0, 48, 9, 63, 0,
-  76, 0, 5, 0, 0, 96, 8, 3, 33, 0,
-  35, 0, 85, 3, 0, 27, 4, 58, 40, 66,
-  33, 44, 0, 33, 67, 0, 11, 33, 0, 10,
-  35, 17, 0, 0, 0, 0, 16, 0, 0, 0,
-  0, 12, 0, 0, 0, 9, 0, 67, 0, 25,
-  0, 38, 0, 0, 28, 0, 77, 30, 0, 0,
-  25, 0, 0, 0, 0, 0, 0, 0, 2, 0,
-  21, 0, 17, 0, 0, 0, 18, 29, 78, 0,
-  11, 0, 0, 0, 78, 36, 3, 0, 35, 3,
-  44, 7, 36, 20, 0, 27, 0, 26, 0, 8,
-  0, 0, 61, 33, 8, 16, 0, 0, 58, 0,
-  22, 29, 12, 37, 7, 0, 0, 0, 41, 0,
-  0, 0, 20, 0, 0, 0, 52, 0, 0, 31,
-  46, 0, 0, 50, 11, 21, 17, 0, 0, 0,
-  67, 0, 0, 42, 4, 106, 9, 17, 15, 45,
-  0, 24, 71, 0, 40, 19, 0, 0, 0, 3,
-  0, 0, 0, 0, 0, 10, 0, 0, 0, 0,
-  0, 0, 4, 19, 0, 50, 0, 0, 0, 45,
-  0, 0, 34, 65, 36, 45, 0, 0, 44, 0,
-  0, 0, 0, 0, 7, 0, 60, 7, 0, 7,
-  12, 15, 0, 0, 10, 2, 40, 0, 0, 0,
-  0, 1, 42, 35, 2, 0, 21, 0, 58, 15,
-  51, 12, 0, 30, 0, 0, 0, 9, 0, 0,
-  58, 45, 6, 2, 0, 0, 16, 0, 0, 13,
-  0, 3, 7, 0, 0, 0, 80, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 4, 12, 0,
-  20, 58, 19, 29, 24, 0, 0, 0, 79, 0,
-  0, 44, 19, 100, 0, 0, 0, 11, 0, 4,
-  57, 0, 28, 24, 0, 0, 2, 0, 0, 3,
-  5, 0, 0, 6, 0, 0, 0, 0, 0, 0,
-  0, 34, 0, 24, 0, 0, 6, 41, 0, 0,
-  50, 104, 10, 72, 18, 0, 43, 0, 5, 0,
-  0, 0, 14, 0, 25, 49, 0, 0, 0, 41,
-  0, 14, 1, 0, 14, 2, 0, 0, 0, 33,
-  14, 52, 21, 0, 21, 0, 41, 46, 70, 27,
-  15, 0, 0, 0, 0, 6, 30, 0, 57, 63,
-  0, 18, 0, 0, 0, 0, 0, 23, 55, 0,
-  32, 0, 0, 0, 90, 0, 14, 0, 0, 0,
-  5, 1, 0, 0, 20, 7, 0, 0, 0, 1,
-  54, 0, 0, 0, 0, 0, 42, 0, 0, 7,
-  0, 86, 0, 0, 1, 43, 0, 15, 50, 15,
-  93, 16, 0, 0, 0, 18, 0, 0, 16, 0,
-  0, 0, 0, 0, 0, 25, 0, 0, 34, 33,
-  0, 35, 0, 0, 0, 17, 0, 0, 34, 96,
-  0, 0, 21, 0, 40, 0, 14, 0, 0, 2,
-  21, 0, 100, 23, 1, 3, 2, 71, 0, 0,
-  0, 0, 18, 0, 0, 0, 0, 0, 25, 5,
-  0, 25, 63, 0, 32, 16, 62, 0, 0, 28,
-  0, 0, 0, 0, 0, 0, 67, 44, 0, 0,
-  0, 0, 26, 0, 0, 29, 0, 5, 41, 0,
-  0, 0, 99, 0, 45, 0, 46, 0, 0, 13,
-  0, 0, 0, 6, 19, 0, 16, 0, 16, 11,
-  0, 0, 0, 0, 35, 0, 0, 25, 4, 106,
-  0, 0, 0, 36, 2, 10, 68, 10, 49, 2,
-  0, 0, 0, 0, 0, 0, 0, 2, 0, 9,
-  0, 0, 0, 0, 0, 0, 5, 41, 0, 45,
-  0, 0, 0, 31, 0, 0, 66, 127, 0, 42,
-  14, 0, 16, 0, 2, 0, 0, 0, 48, 0,
-  110, 32, 0, 9, 0, 60, 0, 11, 0, 0,
-  22, 0, 0, 0, 0, 41, 18, 32, 0, 0,
-  51, 0, 58, 18, 81, 0, 0, 0, 0, 0,
-  0, 12, 11, 0, 73, 49, 0, 0, 0, 0,
-  6, 0, 0, 8, 11, 0, 36, 0, 0, 0,
-  95, 0, 70, 0, 20, 0, 1, 0, 0, 0,
-  8, 0, 11, 0, 7, 17, 0, 25, 21, 11,
-  0, 0, 61, 0, 0, 19, 7, 87, 0, 0,
-  0, 20, 13, 16, 69, 0, 0, 19, 0, 0,
-  0, 0, 0, 18, 0, 0, 0, 6, 0, 0,
-  0, 0, 0, 0, 0, 18, 0, 55, 0, 0,
-  10, 38, 0, 0, 71, 103, 0, 69, 0, 0,
-  31, 9, 0, 0, 0, 0, 4, 0, 42, 20,
-  0, 14, 0, 7, 0, 2, 0, 0, 39, 0,
-  0, 0, 0, 43, 31, 45, 9, 0, 36, 0,
-  50, 45, 79, 24, 11, 1, 0, 0, 0, 13,
-  32, 0, 65, 65, 1, 23, 0, 0, 0, 0,
-  0, 13, 64, 0, 7, 0, 0, 0, 59, 0,
-  45, 0, 6, 0, 45, 0, 40, 0, 47, 0,
-  8, 0, 20, 0, 19, 16, 0, 0, 0, 0,
-  29, 0, 0, 0, 2, 73, 0, 0, 0, 28,
-  8, 5, 49, 5, 52, 6, 0, 0, 0, 7,
-  0, 12, 6, 1, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 29, 0, 45, 0, 0, 0, 16,
-  0, 0, 39, 114, 0, 30, 15, 0, 35, 10,
-  0, 0, 0, 0, 31, 0, 77, 23, 0, 26,
-  0, 48, 0, 8, 0, 0, 25, 0, 0, 0,
-  0, 24, 31, 18, 0, 15, 42, 0, 28, 19,
-  61, 0, 0, 0, 0, 0, 0, 9, 24, 0,
-  72, 41, 0, 0, 3, 0, 0, 0, 0, 13,
-  37, 0, 43, 0, 0, 5, 84, 0, 93, 0,
-  17, 0, 7, 5, 0, 0, 42, 4, 0, 0,
-  3, 16, 0, 41, 1, 0, 4, 6, 70, 0,
-  0, 11, 25, 55, 18, 0, 14, 4, 17, 0,
-  52, 0, 0, 17, 0, 16, 4, 14, 0, 32,
-  2, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 25, 0, 53, 0, 0, 5, 16, 0, 0,
-  58, 87, 18, 68, 0, 0, 15, 25, 0, 19,
-  0, 0, 0, 0, 0, 11, 7, 13, 8, 0,
-  0, 9, 0, 0, 44, 3, 0, 0, 0, 43,
-  57, 57, 0, 0, 32, 0, 31, 33, 74, 29,
-  25, 0, 0, 0, 0, 11, 45, 0, 71, 48,
-  0, 0, 7, 0, 2, 0, 0, 12, 74, 6,
-  34, 0, 0, 0, 67, 0, 49, 0, 0, 0,
-  48, 9, 63, 0, 76, 0, 5, 0, 0, 29,
-  0, 36, 17, 0, 0, 1, 82, 0, 0, 10,
-  14, 80, 41, 0, 22, 8, 10, 0, 47, 0,
-  0, 23, 0, 13, 0, 15, 0, 5, 0, 0,
-  0, 11, 0, 0, 0, 0, 0, 11, 0, 0,
-  0, 51, 0, 0, 23, 16, 0, 0, 35, 72,
-  21, 74, 0, 0, 3, 24, 0, 11, 0, 0,
-  0, 0, 0, 21, 29, 0, 30, 0, 0, 0,
-  0, 0, 58, 0, 0, 0, 0, 30, 56, 60,
-  4, 0, 25, 0, 29, 51, 61, 17, 7, 13,
-  0, 0, 0, 14, 29, 0, 67, 43, 0, 16,
-  0, 0, 10, 1, 0, 7, 54, 13, 18, 0,
-  0, 0, 34, 0, 15, 0, 0, 0, 35, 0,
-  63, 0, 64, 0, 8, 0, 0, 50, 11, 21,
-  17, 0, 0, 0, 67, 0, 0, 42, 4, 106,
-  9, 17, 15, 45, 0, 24, 71, 0, 40, 19,
-  0, 0, 0, 3, 0, 0, 0, 0, 0, 10,
-  0, 0, 0, 0, 0, 0, 4, 19, 0, 50,
-  0, 0, 0, 45, 0, 0, 34, 65, 36, 45,
-  0, 0, 44, 0, 0, 0, 0, 0, 7, 0,
-  60, 7, 0, 7, 12, 15, 0, 0, 10, 2,
-  40, 0, 0, 0, 0, 1, 42, 35, 2, 0,
-  21, 0, 58, 15, 51, 12, 0, 30, 0, 0,
-  0, 9, 0, 0, 58, 45, 6, 2, 0, 0,
-  16, 0, 0, 13, 0, 3, 7, 0, 0, 0,
-  80, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 4, 12, 0, 20, 58, 19, 29, 24, 0,
-  0, 0, 79, 0, 0, 44, 19, 100, 0, 0,
-  0, 11, 0, 4, 57, 0, 28, 24, 0, 0,
-  2, 0, 0, 3, 5, 0, 0, 6, 0, 0,
-  0, 0, 0, 0, 0, 34, 0, 24, 0, 0,
-  6, 41, 0, 0, 50, 104, 10, 72, 18, 0,
-  43, 0, 5, 0, 0, 0, 14, 0, 25, 49,
-  0, 0, 0, 41, 0, 14, 1, 0, 14, 2,
-  0, 0, 0, 33, 14, 52, 21, 0, 21, 0,
-  41, 46, 70, 27, 15, 0, 0, 0, 0, 6,
-  30, 0, 57, 63, 0, 18, 0, 0, 0, 0,
-  0, 23, 55, 0, 32, 0, 0, 0, 90, 0,
-  14, 0, 0, 0, 5, 1, 0, 0, 20, 7,
-  0, 0, 56, 103, 0, 45, 15, 0, 0, 0,
-  58, 0, 0, 52, 30, 60, 0, 0, 0, 11,
-  22, 8, 26, 0, 0, 48, 0, 0, 58, 0,
-  0, 0, 19, 13, 0, 0, 3, 0, 0, 0,
-  0, 0, 0, 0, 0, 14, 26, 11, 2, 0,
-  0, 0, 23, 83, 1, 41, 67, 0, 39, 3,
-  0, 0, 0, 31, 34, 12, 4, 15, 0, 13,
-  0, 63, 0, 12, 10, 0, 0, 36, 0, 0,
-  33, 0, 0, 39, 30, 13, 0, 0, 19, 60,
-  73, 69, 93, 0, 0, 0, 0, 0, 59, 0,
-  21, 68, 23, 82, 0, 0, 0, 0, 0, 52,
-  129, 3, 21, 0, 0, 7, 40, 0, 0, 0,
-  3, 0, 26, 0, 14, 0, 57, 39, 0, 0,
-  16, 0, 16, 11, 0, 0, 0, 0, 35, 0,
-  0, 25, 4, 106, 0, 0, 0, 36, 2, 10,
-  68, 10, 49, 2, 0, 0, 0, 0, 0, 0,
-  0, 2, 0, 9, 0, 0, 0, 0, 0, 0,
-  5, 41, 0, 45, 0, 0, 0, 31, 0, 0,
-  66, 127, 0, 42, 14, 0, 16, 0, 2, 0,
-  0, 0, 48, 0, 110, 32, 0, 9, 0, 60,
-  0, 11, 0, 0, 22, 0, 0, 0, 0, 41,
-  18, 32, 0, 0, 51, 0, 58, 18, 81, 0,
-  0, 0, 0, 0, 0, 12, 11, 0, 73, 49,
-  0, 0, 0, 0, 6, 0, 0, 8, 11, 0,
-  36, 0, 0, 0, 95, 0, 70, 0, 20, 0,
-  1, 0, 0, 0, 8, 0, 11, 0, 7, 17,
-  0, 25, 21, 11, 0, 0, 61, 0, 0, 19,
-  7, 87, 0, 0, 0, 20, 13, 16, 69, 0,
-  0, 19, 0, 0, 0, 0, 0, 18, 0, 0,
-  0, 6, 0, 0, 0, 0, 0, 0, 0, 18,
-  0, 55, 0, 0, 10, 38, 0, 0, 71, 103,
-  0, 69, 0, 0, 31, 9, 0, 0, 0, 0,
-  4, 0, 42, 20, 0, 14, 0, 7, 0, 2,
-  0, 0, 39, 0, 0, 0, 0, 43, 31, 45,
-  9, 0, 36, 0, 50, 45, 79, 24, 11, 1,
-  0, 0, 0, 13, 32, 0, 65, 65, 1, 23,
-  0, 0, 0, 0, 0, 13, 64, 0, 7, 0,
-  0, 0, 59, 0, 45, 0, 6, 0, 45, 0,
-  40, 0, 47, 0, 8, 0, 0, 108, 0, 50,
-  20, 0, 23, 0, 76, 0, 5, 27, 31, 30,
-  12, 0, 0, 17, 12, 30, 55, 0, 0, 56,
-  13, 61, 39, 0, 0, 26, 15, 0, 27, 4,
-  0, 0, 0, 0, 0, 5, 0, 21, 0, 47,
-  11, 0, 10, 19, 0, 0, 54, 49, 57, 86,
-  0, 0, 20, 0, 0, 49, 9, 0, 0, 0,
-  0, 0, 32, 13, 0, 0, 0, 12, 0, 0,
-  51, 32, 0, 0, 0, 19, 65, 67, 24, 0,
-  19, 0, 39, 50, 52, 88, 74, 0, 0, 18,
-  0, 13, 42, 0, 60, 63, 11, 32, 0, 0,
-  0, 0, 14, 25, 123, 40, 2, 0, 0, 0,
-  13, 0, 5, 0, 0, 0, 42, 3, 144, 0,
-  86, 0, 0, 0, 3, 16, 0, 41, 1, 0,
-  4, 6, 70, 0, 0, 11, 25, 55, 18, 0,
-  14, 4, 17, 0, 52, 0, 0, 17, 0, 16,
-  4, 14, 0, 32, 2, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 25, 0, 53, 0, 0,
-  5, 16, 0, 0, 58, 87, 18, 68, 0, 0,
-  15, 25, 0, 19, 0, 0, 0, 0, 0, 11,
-  7, 13, 8, 0, 0, 9, 0, 0, 44, 3,
-  0, 0, 0, 43, 57, 57, 0, 0, 32, 0,
-  31, 33, 74, 29, 25, 0, 0, 0, 0, 11,
-  45, 0, 71, 48, 0, 0, 7, 0, 2, 0,
-  0, 12, 74, 6, 34, 0, 0, 0, 67, 0,
-  49, 0, 0, 0, 48, 9, 63, 0, 76, 0,
-  5, 0, 0, 29, 0, 36, 17, 0, 0, 1,
-  82, 0, 0, 10, 14, 80, 41, 0, 22, 8,
-  10, 0, 47, 0, 0, 23, 0, 13, 0, 15,
-  0, 5, 0, 0, 0, 11, 0, 0, 0, 0,
-  0, 11, 0, 0, 0, 51, 0, 0, 23, 16,
-  0, 0, 35, 72, 21, 74, 0, 0, 3, 24,
-  0, 11, 0, 0, 0, 0, 0, 21, 29, 0,
-  30, 0, 0, 0, 0, 0, 58, 0, 0, 0,
-  0, 30, 56, 60, 4, 0, 25, 0, 29, 51,
-  61, 17, 7, 13, 0, 0, 0, 14, 29, 0,
-  67, 43, 0, 16, 0, 0, 10, 1, 0, 7,
-  54, 13, 18, 0, 0, 0, 34, 0, 15, 0,
-  0, 0, 35, 0, 63, 0, 64, 0, 8, 0,
-  0, 64, 0, 40, 20, 0, 10, 0, 63, 0,
-  7, 15, 12, 65, 48, 6, 31, 34, 0, 25,
-  58, 0, 0, 21, 0, 36, 3, 4, 0, 0,
-  0, 0, 0, 32, 0, 0, 0, 0, 0, 11,
-  0, 0, 0, 41, 0, 0, 21, 22, 0, 0,
-  26, 26, 28, 76, 0, 0, 10, 4, 0, 25,
-  19, 0, 0, 0, 0, 11, 55, 3, 50, 0,
-  0, 0, 0, 0, 62, 0, 0, 0, 0, 3,
-  57, 69, 4, 0, 25, 19, 41, 29, 30, 12,
-  0, 34, 0, 1, 0, 24, 19, 0, 63, 30,
-  0, 19, 0, 0, 12, 0, 3, 1, 34, 21,
-  0, 0, 0, 0, 15, 0, 0, 0, 0, 0,
-  0, 13, 75, 0, 41, 0, 17, 0, 20, 58,
-  19, 29, 24, 0, 0, 0, 79, 0, 0, 44,
-  19, 100, 0, 0, 0, 11, 0, 4, 57, 0,
-  28, 24, 0, 0, 2, 0, 0, 3, 5, 0,
-  0, 6, 0, 0, 0, 0, 0, 0, 0, 34,
-  0, 24, 0, 0, 6, 41, 0, 0, 50, 104,
-  10, 72, 18, 0, 43, 0, 5, 0, 0, 0,
-  14, 0, 25, 49, 0, 0, 0, 41, 0, 14,
-  1, 0, 14, 2, 0, 0, 0, 33, 14, 52,
-  21, 0, 21, 0, 41, 46, 70, 27, 15, 0,
-  0, 0, 0, 6, 30, 0, 57, 63, 0, 18,
-  0, 0, 0, 0, 0, 23, 55, 0, 32, 0,
-  0, 0, 90, 0, 14, 0, 0, 0, 5, 1,
-  0, 0, 20, 7, 0, 0, 56, 103, 0, 45,
-  15, 0, 0, 0, 58, 0, 0, 52, 30, 60,
-  0, 0, 0, 11, 22, 8, 26, 0, 0, 48,
-  0, 0, 58, 0, 0, 0, 19, 13, 0, 0,
-  3, 0, 0, 0, 0, 0, 0, 0, 0, 14,
-  26, 11, 2, 0, 0, 0, 23, 83, 1, 41,
-  67, 0, 39, 3, 0, 0, 0, 31, 34, 12,
-  4, 15, 0, 13, 0, 63, 0, 12, 10, 0,
-  0, 36, 0, 0, 33, 0, 0, 39, 30, 13,
-  0, 0, 19, 60, 73, 69, 93, 0, 0, 0,
-  0, 0, 59, 0, 21, 68, 23, 82, 0, 0,
-  0, 0, 0, 52, 129, 3, 21, 0, 0, 7,
-  40, 0, 0, 0, 3, 0, 26, 0, 14, 0,
-  57, 39, 0, 0, 46, 82, 0, 50, 1, 35,
-  0, 0, 22, 0, 0, 15, 41, 6, 0, 0,
-  0, 19, 21, 11, 13, 31, 0, 0, 0, 0,
-  64, 0, 0, 0, 30, 54, 0, 0, 28, 29,
-  0, 17, 0, 0, 0, 0, 1, 18, 5, 11,
-  10, 0, 0, 0, 0, 57, 0, 22, 95, 48,
-  30, 4, 0, 0, 0, 73, 54, 11, 88, 0,
-  0, 66, 0, 94, 130, 13, 9, 0, 0, 4,
-  0, 2, 68, 0, 0, 0, 23, 16, 20, 0,
-  0, 28, 33, 13, 56, 0, 0, 0, 6, 0,
-  47, 0, 18, 68, 22, 150, 0, 0, 0, 0,
-  0, 82, 91, 0, 7, 26, 10, 31, 0, 0,
-  0, 0, 31, 0, 0, 0, 0, 0, 50, 35,
-  0, 2, 7, 17, 0, 25, 21, 11, 0, 0,
-  61, 0, 0, 19, 7, 87, 0, 0, 0, 20,
-  13, 16, 69, 0, 0, 19, 0, 0, 0, 0,
-  0, 18, 0, 0, 0, 6, 0, 0, 0, 0,
-  0, 0, 0, 18, 0, 55, 0, 0, 10, 38,
-  0, 0, 71, 103, 0, 69, 0, 0, 31, 9,
-  0, 0, 0, 0, 4, 0, 42, 20, 0, 14,
-  0, 7, 0, 2, 0, 0, 39, 0, 0, 0,
-  0, 43, 31, 45, 9, 0, 36, 0, 50, 45,
-  79, 24, 11, 1, 0, 0, 0, 13, 32, 0,
-  65, 65, 1, 23, 0, 0, 0, 0, 0, 13,
-  64, 0, 7, 0, 0, 0, 59, 0, 45, 0,
-  6, 0, 45, 0, 40, 0, 47, 0, 8, 0,
-  0, 108, 0, 50, 20, 0, 23, 0, 76, 0,
-  5, 27, 31, 30, 12, 0, 0, 17, 12, 30,
-  55, 0, 0, 56, 13, 61, 39, 0, 0, 26,
-  15, 0, 27, 4, 0, 0, 0, 0, 0, 5,
-  0, 21, 0, 47, 11, 0, 10, 19, 0, 0,
-  54, 49, 57, 86, 0, 0, 20, 0, 0, 49,
-  9, 0, 0, 0, 0, 0, 32, 13, 0, 0,
-  0, 12, 0, 0, 51, 32, 0, 0, 0, 19,
-  65, 67, 24, 0, 19, 0, 39, 50, 52, 88,
-  74, 0, 0, 18, 0, 13, 42, 0, 60, 63,
-  11, 32, 0, 0, 0, 0, 14, 25, 123, 40,
-  2, 0, 0, 0, 13, 0, 5, 0, 0, 0,
-  42, 3, 144, 0, 86, 0, 0, 0, 0, 155,
-  0, 57, 4, 0, 35, 0, 65, 0, 13, 22,
-  77, 0, 0, 0, 0, 12, 22, 43, 12, 0,
-  0, 61, 29, 33, 73, 13, 3, 0, 36, 0,
-  52, 0, 38, 0, 0, 0, 0, 0, 0, 22,
-  0, 53, 11, 0, 16, 0, 0, 0, 43, 52,
-  47, 51, 11, 17, 36, 0, 0, 49, 1, 0,
-  0, 0, 0, 0, 2, 16, 0, 0, 11, 34,
-  0, 0, 39, 55, 0, 69, 4, 0, 37, 56,
-  49, 10, 11, 0, 0, 58, 72, 93, 137, 0,
-  0, 11, 0, 0, 57, 0, 44, 81, 42, 39,
-  0, 0, 0, 0, 27, 70, 152, 18, 4, 0,
-  17, 10, 0, 0, 0, 0, 0, 0, 3, 0,
-  133, 2, 119, 5, 0, 0, 0, 29, 0, 36,
-  17, 0, 0, 1, 82, 0, 0, 10, 14, 80,
-  41, 0, 22, 8, 10, 0, 47, 0, 0, 23,
-  0, 13, 0, 15, 0, 5, 0, 0, 0, 11,
-  0, 0, 0, 0, 0, 11, 0, 0, 0, 51,
-  0, 0, 23, 16, 0, 0, 35, 72, 21, 74,
-  0, 0, 3, 24, 0, 11, 0, 0, 0, 0,
-  0, 21, 29, 0, 30, 0, 0, 0, 0, 0,
-  58, 0, 0, 0, 0, 30, 56, 60, 4, 0,
-  25, 0, 29, 51, 61, 17, 7, 13, 0, 0,
-  0, 14, 29, 0, 67, 43, 0, 16, 0, 0,
-  10, 1, 0, 7, 54, 13, 18, 0, 0, 0,
-  34, 0, 15, 0, 0, 0, 35, 0, 63, 0,
-  64, 0, 8, 0, 0, 64, 0, 40, 20, 0,
-  10, 0, 63, 0, 7, 15, 12, 65, 48, 6,
-  31, 34, 0, 25, 58, 0, 0, 21, 0, 36,
-  3, 4, 0, 0, 0, 0, 0, 32, 0, 0,
-  0, 0, 0, 11, 0, 0, 0, 41, 0, 0,
-  21, 22, 0, 0, 26, 26, 28, 76, 0, 0,
-  10, 4, 0, 25, 19, 0, 0, 0, 0, 11,
-  55, 3, 50, 0, 0, 0, 0, 0, 62, 0,
-  0, 0, 0, 3, 57, 69, 4, 0, 25, 19,
-  41, 29, 30, 12, 0, 34, 0, 1, 0, 24,
-  19, 0, 63, 30, 0, 19, 0, 0, 12, 0,
-  3, 1, 34, 21, 0, 0, 0, 0, 15, 0,
-  0, 0, 0, 0, 0, 13, 75, 0, 41, 0,
-  17, 0, 0, 151, 1, 57, 8, 0, 17, 0,
-  42, 0, 26, 0, 19, 37, 38, 18, 29, 7,
-  6, 53, 10, 0, 0, 24, 1, 37, 15, 7,
-  0, 0, 0, 0, 46, 5, 0, 0, 0, 0,
-  0, 1, 0, 2, 0, 21, 0, 0, 21, 42,
-  0, 0, 40, 0, 12, 89, 0, 0, 18, 1,
-  0, 44, 24, 0, 0, 0, 0, 0, 73, 21,
-  53, 0, 0, 0, 0, 8, 68, 12, 0, 35,
-  0, 18, 49, 62, 21, 11, 30, 33, 16, 49,
-  19, 13, 53, 22, 0, 17, 0, 5, 44, 0,
-  24, 80, 3, 46, 0, 0, 12, 0, 22, 12,
-  52, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 89, 0, 51, 0, 16, 1,
-  56, 103, 0, 45, 15, 0, 0, 0, 58, 0,
-  0, 52, 30, 60, 0, 0, 0, 11, 22, 8,
-  26, 0, 0, 48, 0, 0, 58, 0, 0, 0,
-  19, 13, 0, 0, 3, 0, 0, 0, 0, 0,
-  0, 0, 0, 14, 26, 11, 2, 0, 0, 0,
-  23, 83, 1, 41, 67, 0, 39, 3, 0, 0,
-  0, 31, 34, 12, 4, 15, 0, 13, 0, 63,
-  0, 12, 10, 0, 0, 36, 0, 0, 33, 0,
-  0, 39, 30, 13, 0, 0, 19, 60, 73, 69,
-  93, 0, 0, 0, 0, 0, 59, 0, 21, 68,
-  23, 82, 0, 0, 0, 0, 0, 52, 129, 3,
-  21, 0, 0, 7, 40, 0, 0, 0, 3, 0,
-  26, 0, 14, 0, 57, 39, 0, 0, 46, 82,
-  0, 50, 1, 35, 0, 0, 22, 0, 0, 15,
-  41, 6, 0, 0, 0, 19, 21, 11, 13, 31,
-  0, 0, 0, 0, 64, 0, 0, 0, 30, 54,
-  0, 0, 28, 29, 0, 17, 0, 0, 0, 0,
-  1, 18, 5, 11, 10, 0, 0, 0, 0, 57,
-  0, 22, 95, 48, 30, 4, 0, 0, 0, 73,
-  54, 11, 88, 0, 0, 66, 0, 94, 130, 13,
-  9, 0, 0, 4, 0, 2, 68, 0, 0, 0,
-  23, 16, 20, 0, 0, 28, 33, 13, 56, 0,
-  0, 0, 6, 0, 47, 0, 18, 68, 22, 150,
-  0, 0, 0, 0, 0, 82, 91, 0, 7, 26,
-  10, 31, 0, 0, 0, 0, 31, 0, 0, 0,
-  0, 0, 50, 35, 0, 2, 1, 12, 0, 19,
-  0, 115, 0, 0, 17, 0, 0, 0, 0, 1,
-  0, 0, 0, 28, 11, 16, 0, 65, 2, 0,
-  0, 0, 23, 0, 0, 0, 0, 17, 8, 0,
-  9, 65, 12, 45, 5, 0, 48, 0, 0, 18,
-  0, 33, 46, 0, 0, 7, 0, 29, 0, 0,
-  131, 59, 54, 5, 43, 0, 0, 107, 51, 0,
-  166, 0, 0, 46, 0, 112, 193, 0, 44, 0,
-  0, 35, 0, 0, 29, 0, 0, 0, 32, 0,
-  28, 0, 0, 1, 14, 0, 0, 79, 16, 0,
-  38, 0, 0, 0, 3, 61, 47, 127, 0, 0,
-  0, 0, 0, 36, 0, 0, 0, 55, 0, 53,
-  0, 0, 0, 0, 47, 0, 0, 0, 0, 0,
-  13, 18, 0, 12, 0, 108, 0, 50, 20, 0,
-  23, 0, 76, 0, 5, 27, 31, 30, 12, 0,
-  0, 17, 12, 30, 55, 0, 0, 56, 13, 61,
-  39, 0, 0, 26, 15, 0, 27, 4, 0, 0,
-  0, 0, 0, 5, 0, 21, 0, 47, 11, 0,
-  10, 19, 0, 0, 54, 49, 57, 86, 0, 0,
-  20, 0, 0, 49, 9, 0, 0, 0, 0, 0,
-  32, 13, 0, 0, 0, 12, 0, 0, 51, 32,
-  0, 0, 0, 19, 65, 67, 24, 0, 19, 0,
-  39, 50, 52, 88, 74, 0, 0, 18, 0, 13,
-  42, 0, 60, 63, 11, 32, 0, 0, 0, 0,
-  14, 25, 123, 40, 2, 0, 0, 0, 13, 0,
-  5, 0, 0, 0, 42, 3, 144, 0, 86, 0,
-  0, 0, 0, 155, 0, 57, 4, 0, 35, 0,
-  65, 0, 13, 22, 77, 0, 0, 0, 0, 12,
-  22, 43, 12, 0, 0, 61, 29, 33, 73, 13,
-  3, 0, 36, 0, 52, 0, 38, 0, 0, 0,
-  0, 0, 0, 22, 0, 53, 11, 0, 16, 0,
-  0, 0, 43, 52, 47, 51, 11, 17, 36, 0,
-  0, 49, 1, 0, 0, 0, 0, 0, 2, 16,
-  0, 0, 11, 34, 0, 0, 39, 55, 0, 69,
-  4, 0, 37, 56, 49, 10, 11, 0, 0, 58,
-  72, 93, 137, 0, 0, 11, 0, 0, 57, 0,
-  44, 81, 42, 39, 0, 0, 0, 0, 27, 70,
-  152, 18, 4, 0, 17, 10, 0, 0, 0, 0,
-  0, 0, 3, 0, 133, 2, 119, 5, 0, 0,
-  21, 77, 0, 54, 0, 57, 1, 0, 24, 0,
-  0, 9, 43, 0, 0, 0, 0, 20, 47, 27,
-  0, 27, 1, 0, 0, 0, 69, 0, 0, 0,
-  4, 19, 15, 0, 32, 49, 0, 0, 3, 0,
-  0, 7, 0, 34, 8, 10, 16, 0, 0, 0,
-  3, 45, 0, 0, 93, 35, 51, 0, 0, 0,
-  0, 53, 20, 0, 103, 0, 0, 43, 0, 68,
-  175, 29, 22, 0, 0, 35, 0, 61, 4, 6,
-  0, 0, 64, 5, 21, 0, 0, 19, 51, 0,
-  81, 0, 0, 0, 7, 0, 55, 0, 12, 95,
-  28, 106, 1, 0, 0, 0, 4, 67, 71, 0,
-  2, 16, 0, 39, 0, 0, 0, 0, 25, 0,
-  0, 0, 0, 18, 65, 17, 0, 0, 0, 64,
-  0, 40, 20, 0, 10, 0, 63, 0, 7, 15,
-  12, 65, 48, 6, 31, 34, 0, 25, 58, 0,
-  0, 21, 0, 36, 3, 4, 0, 0, 0, 0,
-  0, 32, 0, 0, 0, 0, 0, 11, 0, 0,
-  0, 41, 0, 0, 21, 22, 0, 0, 26, 26,
-  28, 76, 0, 0, 10, 4, 0, 25, 19, 0,
-  0, 0, 0, 11, 55, 3, 50, 0, 0, 0,
-  0, 0, 62, 0, 0, 0, 0, 3, 57, 69,
-  4, 0, 25, 19, 41, 29, 30, 12, 0, 34,
-  0, 1, 0, 24, 19, 0, 63, 30, 0, 19,
-  0, 0, 12, 0, 3, 1, 34, 21, 0, 0,
-  0, 0, 15, 0, 0, 0, 0, 0, 0, 13,
-  75, 0, 41, 0, 17, 0, 0, 151, 1, 57,
-  8, 0, 17, 0, 42, 0, 26, 0, 19, 37,
-  38, 18, 29, 7, 6, 53, 10, 0, 0, 24,
-  1, 37, 15, 7, 0, 0, 0, 0, 46, 5,
-  0, 0, 0, 0, 0, 1, 0, 2, 0, 21,
-  0, 0, 21, 42, 0, 0, 40, 0, 12, 89,
-  0, 0, 18, 1, 0, 44, 24, 0, 0, 0,
-  0, 0, 73, 21, 53, 0, 0, 0, 0, 8,
-  68, 12, 0, 35, 0, 18, 49, 62, 21, 11,
-  30, 33, 16, 49, 19, 13, 53, 22, 0, 17,
-  0, 5, 44, 0, 24, 80, 3, 46, 0, 0,
-  12, 0, 22, 12, 52, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 89, 0,
-  51, 0, 16, 1, 6, 145, 0, 66, 0, 25,
-  0, 0, 52, 0, 6, 0, 69, 0, 0, 0,
-  0, 5, 33, 32, 0, 0, 14, 32, 3, 0,
-  70, 0, 0, 0, 0, 0, 77, 0, 13, 38,
-  0, 0, 0, 0, 0, 17, 0, 19, 0, 15,
-  48, 19, 0, 17, 5, 25, 0, 35, 17, 0,
-  54, 0, 0, 16, 0, 0, 0, 0, 16, 0,
-  16, 19, 0, 1, 65, 17, 3, 0, 34, 29,
-  0, 94, 0, 16, 0, 0, 90, 39, 0, 18,
-  0, 41, 51, 18, 99, 0, 0, 0, 0, 0,
-  61, 0, 18, 99, 42, 59, 0, 0, 0, 10,
-  57, 44, 87, 0, 0, 0, 0, 36, 0, 0,
-  0, 0, 5, 0, 3, 0, 48, 0, 39, 0,
-  0, 46, 46, 82, 0, 50, 1, 35, 0, 0,
-  22, 0, 0, 15, 41, 6, 0, 0, 0, 19,
-  21, 11, 13, 31, 0, 0, 0, 0, 64, 0,
-  0, 0, 30, 54, 0, 0, 28, 29, 0, 17,
-  0, 0, 0, 0, 1, 18, 5, 11, 10, 0,
-  0, 0, 0, 57, 0, 22, 95, 48, 30, 4,
-  0, 0, 0, 73, 54, 11, 88, 0, 0, 66,
-  0, 94, 130, 13, 9, 0, 0, 4, 0, 2,
-  68, 0, 0, 0, 23, 16, 20, 0, 0, 28,
-  33, 13, 56, 0, 0, 0, 6, 0, 47, 0,
-  18, 68, 22, 150, 0, 0, 0, 0, 0, 82,
-  91, 0, 7, 26, 10, 31, 0, 0, 0, 0,
-  31, 0, 0, 0, 0, 0, 50, 35, 0, 2,
-  1, 12, 0, 19, 0, 115, 0, 0, 17, 0,
-  0, 0, 0, 1, 0, 0, 0, 28, 11, 16,
-  0, 65, 2, 0, 0, 0, 23, 0, 0, 0,
-  0, 17, 8, 0, 9, 65, 12, 45, 5, 0,
-  48, 0, 0, 18, 0, 33, 46, 0, 0, 7,
-  0, 29, 0, 0, 131, 59, 54, 5, 43, 0,
-  0, 107, 51, 0, 166, 0, 0, 46, 0, 112,
-  193, 0, 44, 0, 0, 35, 0, 0, 29, 0,
-  0, 0, 32, 0, 28, 0, 0, 1, 14, 0,
-  0, 79, 16, 0, 38, 0, 0, 0, 3, 61,
-  47, 127, 0, 0, 0, 0, 0, 36, 0, 0,
-  0, 55, 0, 53, 0, 0, 0, 0, 47, 0,
-  0, 0, 0, 0, 13, 18, 0, 12, 0, 1,
-  0, 0, 0, 57, 0, 18, 70, 15, 0, 4,
-  0, 0, 0, 50, 13, 20, 0, 0, 47, 47,
-  29, 12, 0, 0, 0, 10, 0, 0, 0, 0,
-  50, 0, 0, 44, 0, 64, 0, 0, 54, 0,
-  0, 47, 0, 99, 16, 46, 0, 15, 0, 37,
-  0, 0, 63, 0, 74, 0, 64, 0, 0, 62,
-  0, 0, 90, 0, 0, 12, 30, 23, 61, 0,
-  70, 60, 0, 76, 0, 1, 0, 0, 21, 0,
-  0, 0, 0, 0, 8, 0, 5, 0, 0, 121,
-  9, 0, 0, 0, 0, 0, 20, 54, 116, 17,
-  0, 0, 0, 0, 11, 9, 0, 21, 0, 19,
-  0, 73, 0, 0, 0, 0, 56, 0, 53, 0,
-  0, 0, 21, 0, 18, 0, 0, 155, 0, 57,
-  4, 0, 35, 0, 65, 0, 13, 22, 77, 0,
-  0, 0, 0, 12, 22, 43, 12, 0, 0, 61,
-  29, 33, 73, 13, 3, 0, 36, 0, 52, 0,
-  38, 0, 0, 0, 0, 0, 0, 22, 0, 53,
-  11, 0, 16, 0, 0, 0, 43, 52, 47, 51,
-  11, 17, 36, 0, 0, 49, 1, 0, 0, 0,
-  0, 0, 2, 16, 0, 0, 11, 34, 0, 0,
-  39, 55, 0, 69, 4, 0, 37, 56, 49, 10,
-  11, 0, 0, 58, 72, 93, 137, 0, 0, 11,
-  0, 0, 57, 0, 44, 81, 42, 39, 0, 0,
-  0, 0, 27, 70, 152, 18, 4, 0, 17, 10,
-  0, 0, 0, 0, 0, 0, 3, 0, 133, 2,
-  119, 5, 0, 0, 21, 77, 0, 54, 0, 57,
-  1, 0, 24, 0, 0, 9, 43, 0, 0, 0,
-  0, 20, 47, 27, 0, 27, 1, 0, 0, 0,
-  69, 0, 0, 0, 4, 19, 15, 0, 32, 49,
-  0, 0, 3, 0, 0, 7, 0, 34, 8, 10,
-  16, 0, 0, 0, 3, 45, 0, 0, 93, 35,
-  51, 0, 0, 0, 0, 53, 20, 0, 103, 0,
-  0, 43, 0, 68, 175, 29, 22, 0, 0, 35,
-  0, 61, 4, 6, 0, 0, 64, 5, 21, 0,
-  0, 19, 51, 0, 81, 0, 0, 0, 7, 0,
-  55, 0, 12, 95, 28, 106, 1, 0, 0, 0,
-  4, 67, 71, 0, 2, 16, 0, 39, 0, 0,
-  0, 0, 25, 0, 0, 0, 0, 18, 65, 17,
-  0, 0, 0, 0, 0, 25, 0, 135, 0, 7,
-  42, 0, 0, 4, 0, 6, 0, 0, 0, 25,
-  13, 0, 41, 106, 15, 0, 0, 0, 0, 1,
-  0, 0, 0, 1, 9, 0, 0, 82, 0, 40,
-  0, 0, 45, 0, 0, 46, 0, 80, 0, 4,
-  0, 0, 0, 52, 0, 0, 133, 36, 44, 0,
-  57, 0, 0, 92, 42, 0, 155, 0, 0, 30,
-  0, 77, 196, 0, 59, 34, 0, 31, 0, 16,
-  9, 0, 0, 0, 35, 0, 0, 0, 1, 0,
-  11, 0, 0, 92, 0, 0, 27, 0, 0, 0,
-  7, 76, 78, 108, 0, 0, 0, 0, 0, 30,
-  0, 0, 0, 38, 0, 95, 0, 0, 0, 0,
-  52, 0, 0, 0, 0, 0, 21, 0, 0, 6,
-  0, 151, 1, 57, 8, 0, 17, 0, 42, 0,
-  26, 0, 19, 37, 38, 18, 29, 7, 6, 53,
-  10, 0, 0, 24, 1, 37, 15, 7, 0, 0,
-  0, 0, 46, 5, 0, 0, 0, 0, 0, 1,
-  0, 2, 0, 21, 0, 0, 21, 42, 0, 0,
-  40, 0, 12, 89, 0, 0, 18, 1, 0, 44,
-  24, 0, 0, 0, 0, 0, 73, 21, 53, 0,
-  0, 0, 0, 8, 68, 12, 0, 35, 0, 18,
-  49, 62, 21, 11, 30, 33, 16, 49, 19, 13,
-  53, 22, 0, 17, 0, 5, 44, 0, 24, 80,
-  3, 46, 0, 0, 12, 0, 22, 12, 52, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 89, 0, 51, 0, 16, 1, 6, 145,
-  0, 66, 0, 25, 0, 0, 52, 0, 6, 0,
-  69, 0, 0, 0, 0, 5, 33, 32, 0, 0,
-  14, 32, 3, 0, 70, 0, 0, 0, 0, 0,
-  77, 0, 13, 38, 0, 0, 0, 0, 0, 17,
-  0, 19, 0, 15, 48, 19, 0, 17, 5, 25,
-  0, 35, 17, 0, 54, 0, 0, 16, 0, 0,
-  0, 0, 16, 0, 16, 19, 0, 1, 65, 17,
-  3, 0, 34, 29, 0, 94, 0, 16, 0, 0,
-  90, 39, 0, 18, 0, 41, 51, 18, 99, 0,
-  0, 0, 0, 0, 61, 0, 18, 99, 42, 59,
-  0, 0, 0, 10, 57, 44, 87, 0, 0, 0,
-  0, 36, 0, 0, 0, 0, 5, 0, 3, 0,
-  48, 0, 39, 0, 0, 46, 58, 21, 0, 68,
-  2, 105, 0, 4, 38, 0, 0, 0, 40, 0,
-  0, 0, 2, 21, 35, 0, 0, 90, 13, 0,
-  0, 0, 31, 0, 9, 0, 0, 31, 3, 0,
-  67, 72, 9, 0, 27, 0, 20, 14, 0, 28,
-  22, 53, 41, 0, 0, 0, 0, 61, 0, 0,
-  135, 38, 37, 0, 7, 0, 0, 47, 34, 0,
-  96, 0, 0, 31, 0, 47, 198, 6, 55, 0,
-  0, 0, 0, 35, 0, 0, 0, 0, 77, 27,
-  31, 0, 1, 1, 38, 0, 0, 15, 0, 0,
-  17, 0, 39, 0, 26, 71, 33, 77, 0, 0,
-  0, 0, 6, 46, 5, 0, 19, 40, 0, 88,
-  0, 0, 0, 0, 55, 0, 0, 0, 0, 0,
-  28, 0, 0, 16, 1, 12, 0, 19, 0, 115,
-  0, 0, 17, 0, 0, 0, 0, 1, 0, 0,
-  0, 28, 11, 16, 0, 65, 2, 0, 0, 0,
-  23, 0, 0, 0, 0, 17, 8, 0, 9, 65,
-  12, 45, 5, 0, 48, 0, 0, 18, 0, 33,
-  46, 0, 0, 7, 0, 29, 0, 0, 131, 59,
-  54, 5, 43, 0, 0, 107, 51, 0, 166, 0,
-  0, 46, 0, 112, 193, 0, 44, 0, 0, 35,
-  0, 0, 29, 0, 0, 0, 32, 0, 28, 0,
-  0, 1, 14, 0, 0, 79, 16, 0, 38, 0,
-  0, 0, 3, 61, 47, 127, 0, 0, 0, 0,
-  0, 36, 0, 0, 0, 55, 0, 53, 0, 0,
-  0, 0, 47, 0, 0, 0, 0, 0, 13, 18,
-  0, 12, 0, 1, 0, 0, 0, 57, 0, 18,
-  70, 15, 0, 4, 0, 0, 0, 50, 13, 20,
-  0, 0, 47, 47, 29, 12, 0, 0, 0, 10,
-  0, 0, 0, 0, 50, 0, 0, 44, 0, 64,
-  0, 0, 54, 0, 0, 47, 0, 99, 16, 46,
-  0, 15, 0, 37, 0, 0, 63, 0, 74, 0,
-  64, 0, 0, 62, 0, 0, 90, 0, 0, 12,
-  30, 23, 61, 0, 70, 60, 0, 76, 0, 1,
-  0, 0, 21, 0, 0, 0, 0, 0, 8, 0,
-  5, 0, 0, 121, 9, 0, 0, 0, 0, 0,
-  20, 54, 116, 17, 0, 0, 0, 0, 11, 9,
-  0, 21, 0, 19, 0, 73, 0, 0, 0, 0,
-  56, 0, 53, 0, 0, 0, 21, 0, 18, 0,
-  0, 48, 16, 0, 0, 0, 50, 44, 75, 3,
-  3, 42, 110, 0, 16, 61, 79, 13, 2, 0,
-  31, 54, 4, 6, 49, 0, 0, 45, 0, 0,
-  0, 0, 83, 0, 2, 0, 0, 62, 0, 80,
-  0, 35, 4, 49, 18, 97, 6, 35, 0, 42,
-  0, 40, 48, 0, 23, 0, 3, 0, 0, 0,
-  0, 5, 0, 59, 0, 17, 20, 0, 40, 0,
-  0, 0, 0, 48, 8, 0, 29, 54, 0, 0,
-  33, 0, 42, 5, 0, 9, 4, 0, 0, 8,
-  0, 4, 0, 44, 0, 13, 5, 8, 15, 84,
-  41, 0, 0, 0, 34, 0, 24, 13, 4, 22,
-  0, 21, 0, 22, 0, 0, 0, 0, 35, 0,
-  31, 0, 111, 0, 71, 0, 32, 0, 21, 77,
-  0, 54, 0, 57, 1, 0, 24, 0, 0, 9,
-  43, 0, 0, 0, 0, 20, 47, 27, 0, 27,
-  1, 0, 0, 0, 69, 0, 0, 0, 4, 19,
-  15, 0, 32, 49, 0, 0, 3, 0, 0, 7,
-  0, 34, 8, 10, 16, 0, 0, 0, 3, 45,
-  0, 0, 93, 35, 51, 0, 0, 0, 0, 53,
-  20, 0, 103, 0, 0, 43, 0, 68, 175, 29,
-  22, 0, 0, 35, 0, 61, 4, 6, 0, 0,
-  64, 5, 21, 0, 0, 19, 51, 0, 81, 0,
-  0, 0, 7, 0, 55, 0, 12, 95, 28, 106,
-  1, 0, 0, 0, 4, 67, 71, 0, 2, 16,
-  0, 39, 0, 0, 0, 0, 25, 0, 0, 0,
-  0, 18, 65, 17, 0, 0, 0, 0, 0, 25,
-  0, 135, 0, 7, 42, 0, 0, 4, 0, 6,
-  0, 0, 0, 25, 13, 0, 41, 106, 15, 0,
-  0, 0, 0, 1, 0, 0, 0, 1, 9, 0,
-  0, 82, 0, 40, 0, 0, 45, 0, 0, 46,
-  0, 80, 0, 4, 0, 0, 0, 52, 0, 0,
-  133, 36, 44, 0, 57, 0, 0, 92, 42, 0,
-  155, 0, 0, 30, 0, 77, 196, 0, 59, 34,
-  0, 31, 0, 16, 9, 0, 0, 0, 35, 0,
-  0, 0, 1, 0, 11, 0, 0, 92, 0, 0,
-  27, 0, 0, 0, 7, 76, 78, 108, 0, 0,
-  0, 0, 0, 30, 0, 0, 0, 38, 0, 95,
-  0, 0, 0, 0, 52, 0, 0, 0, 0, 0,
-  21, 0, 0, 6, 0, 28, 0, 8, 0, 24,
-  24, 29, 104, 12, 0, 37, 106, 0, 0, 105,
-  62, 22, 0, 0, 41, 62, 0, 12, 2, 0,
-  0, 43, 0, 0, 0, 0, 76, 0, 33, 0,
-  0, 91, 0, 53, 32, 0, 4, 39, 5, 115,
-  2, 34, 0, 36, 0, 56, 16, 0, 56, 0,
-  6, 0, 36, 0, 0, 14, 0, 21, 0, 0,
-  0, 0, 27, 0, 37, 0, 47, 52, 0, 14,
-  8, 31, 0, 0, 8, 0, 29, 0, 0, 10,
-  11, 0, 20, 0, 0, 68, 0, 34, 0, 0,
-  0, 0, 26, 84, 90, 0, 0, 0, 22, 0,
-  15, 31, 0, 34, 0, 30, 0, 52, 0, 0,
-  0, 0, 60, 0, 39, 0, 79, 0, 69, 0,
-  34, 16, 6, 145, 0, 66, 0, 25, 0, 0,
-  52, 0, 6, 0, 69, 0, 0, 0, 0, 5,
-  33, 32, 0, 0, 14, 32, 3, 0, 70, 0,
-  0, 0, 0, 0, 77, 0, 13, 38, 0, 0,
-  0, 0, 0, 17, 0, 19, 0, 15, 48, 19,
-  0, 17, 5, 25, 0, 35, 17, 0, 54, 0,
-  0, 16, 0, 0, 0, 0, 16, 0, 16, 19,
-  0, 1, 65, 17, 3, 0, 34, 29, 0, 94,
-  0, 16, 0, 0, 90, 39, 0, 18, 0, 41,
-  51, 18, 99, 0, 0, 0, 0, 0, 61, 0,
-  18, 99, 42, 59, 0, 0, 0, 10, 57, 44,
-  87, 0, 0, 0, 0, 36, 0, 0, 0, 0,
-  5, 0, 3, 0, 48, 0, 39, 0, 0, 46,
-  58, 21, 0, 68, 2, 105, 0, 4, 38, 0,
-  0, 0, 40, 0, 0, 0, 2, 21, 35, 0,
-  0, 90, 13, 0, 0, 0, 31, 0, 9, 0,
-  0, 31, 3, 0, 67, 72, 9, 0, 27, 0,
-  20, 14, 0, 28, 22, 53, 41, 0, 0, 0,
-  0, 61, 0, 0, 135, 38, 37, 0, 7, 0,
-  0, 47, 34, 0, 96, 0, 0, 31, 0, 47,
-  198, 6, 55, 0, 0, 0, 0, 35, 0, 0,
-  0, 0, 77, 27, 31, 0, 1, 1, 38, 0,
-  0, 15, 0, 0, 17, 0, 39, 0, 26, 71,
-  33, 77, 0, 0, 0, 0, 6, 46, 5, 0,
-  19, 40, 0, 88, 0, 0, 0, 0, 55, 0,
-  0, 0, 0, 0, 28, 0, 0, 16, 0, 0,
-  0, 15, 0, 83, 0, 21, 90, 39, 0, 48,
-  26, 0, 0, 60, 13, 28, 16, 0, 25, 81,
-  1, 0, 0, 0, 1, 44, 17, 19, 0, 35,
-  60, 0, 78, 36, 79, 138, 7, 0, 76, 0,
-  2, 0, 0, 129, 0, 4, 0, 11, 0, 4,
-  0, 0, 138, 0, 2, 0, 27, 0, 0, 90,
-  14, 2, 90, 0, 0, 39, 0, 61, 111, 0,
-  118, 35, 0, 31, 35, 22, 25, 0, 0, 0,
-  0, 27, 0, 0, 12, 25, 0, 0, 0, 91,
-  0, 7, 15, 0, 6, 0, 0, 89, 131, 18,
-  0, 0, 39, 0, 0, 48, 0, 0, 1, 67,
-  0, 57, 0, 0, 0, 0, 75, 0, 0, 0,
-  0, 0, 0, 0, 75, 51, 0, 1, 0, 0,
-  0, 57, 0, 18, 70, 15, 0, 4, 0, 0,
-  0, 50, 13, 20, 0, 0, 47, 47, 29, 12,
-  0, 0, 0, 10, 0, 0, 0, 0, 50, 0,
-  0, 44, 0, 64, 0, 0, 54, 0, 0, 47,
-  0, 99, 16, 46, 0, 15, 0, 37, 0, 0,
-  63, 0, 74, 0, 64, 0, 0, 62, 0, 0,
-  90, 0, 0, 12, 30, 23, 61, 0, 70, 60,
-  0, 76, 0, 1, 0, 0, 21, 0, 0, 0,
-  0, 0, 8, 0, 5, 0, 0, 121, 9, 0,
-  0, 0, 0, 0, 20, 54, 116, 17, 0, 0,
-  0, 0, 11, 9, 0, 21, 0, 19, 0, 73,
-  0, 0, 0, 0, 56, 0, 53, 0, 0, 0,
-  21, 0, 18, 0, 0, 48, 16, 0, 0, 0,
-  50, 44, 75, 3, 3, 42, 110, 0, 16, 61,
-  79, 13, 2, 0, 31, 54, 4, 6, 49, 0,
-  0, 45, 0, 0, 0, 0, 83, 0, 2, 0,
-  0, 62, 0, 80, 0, 35, 4, 49, 18, 97,
-  6, 35, 0, 42, 0, 40, 48, 0, 23, 0,
-  3, 0, 0, 0, 0, 5, 0, 59, 0, 17,
-  20, 0, 40, 0, 0, 0, 0, 48, 8, 0,
-  29, 54, 0, 0, 33, 0, 42, 5, 0, 9,
-  4, 0, 0, 8, 0, 4, 0, 44, 0, 13,
-  5, 8, 15, 84, 41, 0, 0, 0, 34, 0,
-  24, 13, 4, 22, 0, 21, 0, 22, 0, 0,
-  0, 0, 35, 0, 31, 0, 111, 0, 71, 0,
-  32, 0, 3, 37, 0, 0, 14, 0, 32, 0,
-  0, 0, 3, 23, 56, 0, 0, 4, 62, 15,
-  4, 0, 0, 72, 0, 17, 107, 0, 0, 48,
-  0, 0, 0, 48, 90, 0, 0, 0, 0, 51,
-  43, 7, 0, 46, 21, 29, 25, 100, 41, 0,
-  0, 5, 0, 0, 5, 0, 27, 0, 7, 0,
-  20, 2, 58, 63, 0, 50, 0, 0, 97, 52,
-  73, 0, 0, 0, 9, 20, 30, 0, 53, 59,
-  0, 0, 0, 0, 39, 57, 10, 31, 0, 0,
-  0, 14, 0, 0, 0, 54, 0, 21, 0, 18,
-  0, 113, 24, 11, 22, 20, 39, 43, 10, 0,
-  43, 0, 0, 50, 0, 0, 0, 0, 10, 1,
-  48, 0, 7, 0, 27, 0, 30, 0, 30, 47,
-  0, 0, 0, 25, 0, 135, 0, 7, 42, 0,
-  0, 4, 0, 6, 0, 0, 0, 25, 13, 0,
-  41, 106, 15, 0, 0, 0, 0, 1, 0, 0,
-  0, 1, 9, 0, 0, 82, 0, 40, 0, 0,
-  45, 0, 0, 46, 0, 80, 0, 4, 0, 0,
-  0, 52, 0, 0, 133, 36, 44, 0, 57, 0,
-  0, 92, 42, 0, 155, 0, 0, 30, 0, 77,
-  196, 0, 59, 34, 0, 31, 0, 16, 9, 0,
-  0, 0, 35, 0, 0, 0, 1, 0, 11, 0,
-  0, 92, 0, 0, 27, 0, 0, 0, 7, 76,
-  78, 108, 0, 0, 0, 0, 0, 30, 0, 0,
-  0, 38, 0, 95, 0, 0, 0, 0, 52, 0,
-  0, 0, 0, 0, 21, 0, 0, 6, 0, 28,
-  0, 8, 0, 24, 24, 29, 104, 12, 0, 37,
-  106, 0, 0, 105, 62, 22, 0, 0, 41, 62,
-  0, 12, 2, 0, 0, 43, 0, 0, 0, 0,
-  76, 0, 33, 0, 0, 91, 0, 53, 32, 0,
-  4, 39, 5, 115, 2, 34, 0, 36, 0, 56,
-  16, 0, 56, 0, 6, 0, 36, 0, 0, 14,
-  0, 21, 0, 0, 0, 0, 27, 0, 37, 0,
-  47, 52, 0, 14, 8, 31, 0, 0, 8, 0,
-  29, 0, 0, 10, 11, 0, 20, 0, 0, 68,
-  0, 34, 0, 0, 0, 0, 26, 84, 90, 0,
-  0, 0, 22, 0, 15, 31, 0, 34, 0, 30,
-  0, 52, 0, 0, 0, 0, 60, 0, 39, 0,
-  79, 0, 69, 0, 34, 16, 0, 39, 58, 0,
-  0, 0, 35, 20, 76, 0, 11, 39, 97, 0,
-  0, 94, 63, 17, 0, 0, 0, 47, 11, 21,
-  63, 0, 0, 58, 0, 0, 0, 24, 97, 0,
-  27, 0, 0, 89, 26, 22, 38, 4, 46, 33,
-  23, 117, 42, 0, 0, 22, 0, 0, 14, 0,
-  32, 0, 5, 0, 47, 0, 0, 49, 0, 19,
-  0, 0, 17, 1, 30, 0, 0, 0, 56, 43,
-  10, 31, 22, 65, 0, 0, 6, 0, 19, 88,
-  0, 42, 0, 0, 0, 23, 0, 11, 0, 31,
-  0, 0, 0, 0, 0, 85, 98, 0, 0, 0,
-  13, 0, 31, 29, 0, 24, 0, 19, 0, 5,
-  0, 0, 0, 12, 70, 0, 0, 0, 32, 0,
-  63, 0, 24, 34, 58, 21, 0, 68, 2, 105,
-  0, 4, 38, 0, 0, 0, 40, 0, 0, 0,
-  2, 21, 35, 0, 0, 90, 13, 0, 0, 0,
-  31, 0, 9, 0, 0, 31, 3, 0, 67, 72,
-  9, 0, 27, 0, 20, 14, 0, 28, 22, 53,
-  41, 0, 0, 0, 0, 61, 0, 0, 135, 38,
-  37, 0, 7, 0, 0, 47, 34, 0, 96, 0,
-  0, 31, 0, 47, 198, 6, 55, 0, 0, 0,
-  0, 35, 0, 0, 0, 0, 77, 27, 31, 0,
-  1, 1, 38, 0, 0, 15, 0, 0, 17, 0,
-  39, 0, 26, 71, 33, 77, 0, 0, 0, 0,
-  6, 46, 5, 0, 19, 40, 0, 88, 0, 0,
-  0, 0, 55, 0, 0, 0, 0, 0, 28, 0,
-  0, 16, 0, 0, 0, 15, 0, 83, 0, 21,
-  90, 39, 0, 48, 26, 0, 0, 60, 13, 28,
-  16, 0, 25, 81, 1, 0, 0, 0, 1, 44,
-  17, 19, 0, 35, 60, 0, 78, 36, 79, 138,
-  7, 0, 76, 0, 2, 0, 0, 129, 0, 4,
-  0, 11, 0, 4, 0, 0, 138, 0, 2, 0,
-  27, 0, 0, 90, 14, 2, 90, 0, 0, 39,
-  0, 61, 111, 0, 118, 35, 0, 31, 35, 22,
-  25, 0, 0, 0, 0, 27, 0, 0, 12, 25,
-  0, 0, 0, 91, 0, 7, 15, 0, 6, 0,
-  0, 89, 131, 18, 0, 0, 39, 0, 0, 48,
-  0, 0, 1, 67, 0, 57, 0, 0, 0, 0,
-  75, 0, 0, 0, 0, 0, 0, 0, 75, 51,
-  0, 0, 95, 9, 0, 0, 0, 24, 67, 28,
-  0, 54, 35, 44, 0, 52, 0, 15, 0, 0,
-  0, 58, 28, 9, 0, 0, 21, 48, 6, 84,
-  0, 37, 76, 0, 22, 0, 105, 123, 0, 0,
-  100, 0, 38, 0, 0, 109, 0, 0, 0, 11,
-  0, 0, 0, 0, 96, 0, 19, 0, 47, 0,
-  0, 83, 53, 15, 66, 0, 7, 34, 0, 90,
-  0, 0, 122, 30, 0, 21, 7, 0, 14, 0,
-  0, 2, 0, 89, 0, 17, 21, 0, 35, 0,
-  0, 36, 0, 3, 0, 0, 0, 0, 0, 59,
-  137, 0, 0, 0, 0, 0, 0, 52, 0, 3,
-  30, 17, 0, 0, 80, 0, 22, 0, 52, 0,
-  0, 0, 0, 0, 0, 14, 61, 73, 0, 48,
-  16, 0, 0, 0, 50, 44, 75, 3, 3, 42,
-  110, 0, 16, 61, 79, 13, 2, 0, 31, 54,
-  4, 6, 49, 0, 0, 45, 0, 0, 0, 0,
-  83, 0, 2, 0, 0, 62, 0, 80, 0, 35,
-  4, 49, 18, 97, 6, 35, 0, 42, 0, 40,
-  48, 0, 23, 0, 3, 0, 0, 0, 0, 5,
-  0, 59, 0, 17, 20, 0, 40, 0, 0, 0,
-  0, 48, 8, 0, 29, 54, 0, 0, 33, 0,
-  42, 5, 0, 9, 4, 0, 0, 8, 0, 4,
-  0, 44, 0, 13, 5, 8, 15, 84, 41, 0,
-  0, 0, 34, 0, 24, 13, 4, 22, 0, 21,
-  0, 22, 0, 0, 0, 0, 35, 0, 31, 0,
-  111, 0, 71, 0, 32, 0, 3, 37, 0, 0,
-  14, 0, 32, 0, 0, 0, 3, 23, 56, 0,
-  0, 4, 62, 15, 4, 0, 0, 72, 0, 17,
-  107, 0, 0, 48, 0, 0, 0, 48, 90, 0,
-  0, 0, 0, 51, 43, 7, 0, 46, 21, 29,
-  25, 100, 41, 0, 0, 5, 0, 0, 5, 0,
-  27, 0, 7, 0, 20, 2, 58, 63, 0, 50,
-  0, 0, 97, 52, 73, 0, 0, 0, 9, 20,
-  30, 0, 53, 59, 0, 0, 0, 0, 39, 57,
-  10, 31, 0, 0, 0, 14, 0, 0, 0, 54,
-  0, 21, 0, 18, 0, 113, 24, 11, 22, 20,
-  39, 43, 10, 0, 43, 0, 0, 50, 0, 0,
-  0, 0, 10, 1, 48, 0, 7, 0, 27, 0,
-  30, 0, 30, 47, 0, 22, 0, 0, 13, 12,
-  20, 0, 30, 0, 12, 20, 47, 4, 0, 16,
-  61, 0, 3, 0, 0, 56, 0, 10, 36, 0,
-  0, 41, 0, 0, 2, 0, 51, 24, 0, 0,
-  0, 75, 57, 0, 0, 1, 0, 46, 0, 115,
-  40, 68, 0, 0, 0, 16, 0, 0, 30, 32,
-  30, 0, 49, 0, 37, 54, 0, 31, 7, 0,
-  25, 63, 98, 0, 89, 0, 26, 32, 28, 22,
-  29, 0, 0, 0, 0, 0, 23, 34, 22, 43,
-  0, 13, 0, 0, 0, 67, 0, 29, 0, 0,
-  0, 0, 28, 122, 64, 34, 0, 28, 14, 55,
-  5, 5, 0, 0, 0, 59, 0, 9, 0, 5,
-  0, 38, 80, 0, 0, 0, 7, 0, 12, 0,
-  22, 22, 0, 28, 0, 8, 0, 24, 24, 29,
-  104, 12, 0, 37, 106, 0, 0, 105, 62, 22,
-  0, 0, 41, 62, 0, 12, 2, 0, 0, 43,
-  0, 0, 0, 0, 76, 0, 33, 0, 0, 91,
-  0, 53, 32, 0, 4, 39, 5, 115, 2, 34,
-  0, 36, 0, 56, 16, 0, 56, 0, 6, 0,
-  36, 0, 0, 14, 0, 21, 0, 0, 0, 0,
-  27, 0, 37, 0, 47, 52, 0, 14, 8, 31,
-  0, 0, 8, 0, 29, 0, 0, 10, 11, 0,
-  20, 0, 0, 68, 0, 34, 0, 0, 0, 0,
-  26, 84, 90, 0, 0, 0, 22, 0, 15, 31,
-  0, 34, 0, 30, 0, 52, 0, 0, 0, 0,
-  60, 0, 39, 0, 79, 0, 69, 0, 34, 16,
-  0, 39, 58, 0, 0, 0, 35, 20, 76, 0,
-  11, 39, 97, 0, 0, 94, 63, 17, 0, 0,
-  0, 47, 11, 21, 63, 0, 0, 58, 0, 0,
-  0, 24, 97, 0, 27, 0, 0, 89, 26, 22,
-  38, 4, 46, 33, 23, 117, 42, 0, 0, 22,
-  0, 0, 14, 0, 32, 0, 5, 0, 47, 0,
-  0, 49, 0, 19, 0, 0, 17, 1, 30, 0,
-  0, 0, 56, 43, 10, 31, 22, 65, 0, 0,
-  6, 0, 19, 88, 0, 42, 0, 0, 0, 23,
-  0, 11, 0, 31, 0, 0, 0, 0, 0, 85,
-  98, 0, 0, 0, 13, 0, 31, 29, 0, 24,
-  0, 19, 0, 5, 0, 0, 0, 12, 70, 0,
-  0, 0, 32, 0, 63, 0, 24, 34, 0, 10,
-  0, 0, 0, 0, 0, 1, 32, 2, 16, 56,
-  0, 30, 0, 9, 3, 0, 2, 0, 1, 27,
-  71, 20, 5, 0, 0, 23, 0, 18, 0, 0,
-  30, 0, 15, 0, 59, 84, 34, 0, 85, 0,
-  0, 5, 0, 98, 39, 10, 0, 0, 0, 0,
-  0, 0, 57, 0, 55, 0, 96, 0, 0, 81,
-  9, 12, 28, 9, 50, 46, 29, 21, 0, 0,
-  85, 58, 7, 94, 37, 18, 0, 0, 0, 22,
-  0, 74, 0, 50, 11, 36, 0, 0, 0, 84,
-  19, 16, 0, 0, 0, 0, 17, 49, 89, 0,
-  0, 0, 0, 27, 5, 0, 0, 3, 0, 9,
-  0, 9, 21, 75, 0, 33, 64, 0, 0, 0,
-  0, 0, 0, 0, 0, 41, 0, 0, 0, 15,
-  0, 83, 0, 21, 90, 39, 0, 48, 26, 0,
-  0, 60, 13, 28, 16, 0, 25, 81, 1, 0,
-  0, 0, 1, 44, 17, 19, 0, 35, 60, 0,
-  78, 36, 79, 138, 7, 0, 76, 0, 2, 0,
-  0, 129, 0, 4, 0, 11, 0, 4, 0, 0,
-  138, 0, 2, 0, 27, 0, 0, 90, 14, 2,
-  90, 0, 0, 39, 0, 61, 111, 0, 118, 35,
-  0, 31, 35, 22, 25, 0, 0, 0, 0, 27,
-  0, 0, 12, 25, 0, 0, 0, 91, 0, 7,
-  15, 0, 6, 0, 0, 89, 131, 18, 0, 0,
-  39, 0, 0, 48, 0, 0, 1, 67, 0, 57,
-  0, 0, 0, 0, 75, 0, 0, 0, 0, 0,
-  0, 0, 75, 51, 0, 0, 95, 9, 0, 0,
-  0, 24, 67, 28, 0, 54, 35, 44, 0, 52,
-  0, 15, 0, 0, 0, 58, 28, 9, 0, 0,
-  21, 48, 6, 84, 0, 37, 76, 0, 22, 0,
-  105, 123, 0, 0, 100, 0, 38, 0, 0, 109,
-  0, 0, 0, 11, 0, 0, 0, 0, 96, 0,
-  19, 0, 47, 0, 0, 83, 53, 15, 66, 0,
-  7, 34, 0, 90, 0, 0, 122, 30, 0, 21,
-  7, 0, 14, 0, 0, 2, 0, 89, 0, 17,
-  21, 0, 35, 0, 0, 36, 0, 3, 0, 0,
-  0, 0, 0, 59, 137, 0, 0, 0, 0, 0,
-  0, 52, 0, 3, 30, 17, 0, 0, 80, 0,
-  22, 0, 52, 0, 0, 0, 0, 0, 0, 14,
-  61, 73, 19, 3, 82, 25, 7, 0, 0, 19,
-  0, 0, 0, 50, 24, 124, 0, 0, 0, 0,
-  0, 0, 16, 66, 70, 4, 0, 0, 12, 4,
-  0, 88, 7, 3, 0, 13, 0, 0, 74, 8,
-  0, 0, 84, 0, 0, 15, 17, 36, 17, 22,
-  4, 0, 9, 49, 0, 0, 86, 0, 46, 0,
-  71, 0, 0, 47, 100, 0, 96, 0, 0, 47,
-  0, 116, 0, 23, 90, 0, 0, 33, 0, 0,
-  23, 0, 0, 55, 0, 76, 0, 1, 45, 31,
-  68, 0, 0, 0, 10, 0, 0, 0, 0, 0,
-  0, 29, 67, 0, 0, 0, 0, 4, 0, 42,
-  0, 0, 54, 0, 0, 0, 124, 74, 44, 0,
-  25, 0, 0, 0, 0, 25, 0, 22, 0, 56,
-  3, 37, 0, 0, 14, 0, 32, 0, 0, 0,
-  3, 23, 56, 0, 0, 4, 62, 15, 4, 0,
-  0, 72, 0, 17, 107, 0, 0, 48, 0, 0,
-  0, 48, 90, 0, 0, 0, 0, 51, 43, 7,
-  0, 46, 21, 29, 25, 100, 41, 0, 0, 5,
-  0, 0, 5, 0, 27, 0, 7, 0, 20, 2,
-  58, 63, 0, 50, 0, 0, 97, 52, 73, 0,
-  0, 0, 9, 20, 30, 0, 53, 59, 0, 0,
-  0, 0, 39, 57, 10, 31, 0, 0, 0, 14,
-  0, 0, 0, 54, 0, 21, 0, 18, 0, 113,
-  24, 11, 22, 20, 39, 43, 10, 0, 43, 0,
-  0, 50, 0, 0, 0, 0, 10, 1, 48, 0,
-  7, 0, 27, 0, 30, 0, 30, 47, 0, 22,
-  0, 0, 13, 12, 20, 0, 30, 0, 12, 20,
-  47, 4, 0, 16, 61, 0, 3, 0, 0, 56,
-  0, 10, 36, 0, 0, 41, 0, 0, 2, 0,
-  51, 24, 0, 0, 0, 75, 57, 0, 0, 1,
-  0, 46, 0, 115, 40, 68, 0, 0, 0, 16,
-  0, 0, 30, 32, 30, 0, 49, 0, 37, 54,
-  0, 31, 7, 0, 25, 63, 98, 0, 89, 0,
-  26, 32, 28, 22, 29, 0, 0, 0, 0, 0,
-  23, 34, 22, 43, 0, 13, 0, 0, 0, 67,
-  0, 29, 0, 0, 0, 0, 28, 122, 64, 34,
-  0, 28, 14, 55, 5, 5, 0, 0, 0, 59,
-  0, 9, 0, 5, 0, 38, 80, 0, 0, 0,
-  7, 0, 12, 0, 22, 22, 0, 49, 0, 0,
-  0, 0, 12, 0, 80, 43, 25, 0, 73, 2,
-  0, 149, 100, 43, 17, 0, 0, 0, 0, 25,
-  0, 0, 21, 90, 9, 0, 9, 0, 115, 13,
-  0, 0, 4, 73, 0, 0, 23, 0, 0, 26,
-  0, 80, 0, 54, 0, 37, 0, 15, 61, 0,
-  0, 23, 13, 7, 0, 32, 0, 0, 0, 0,
-  0, 0, 27, 12, 61, 0, 7, 0, 0, 98,
-  0, 66, 0, 13, 0, 0, 19, 3, 24, 48,
-  0, 47, 3, 23, 13, 19, 53, 124, 0, 32,
-  23, 0, 0, 0, 0, 90, 142, 0, 0, 0,
-  8, 0, 0, 33, 0, 34, 0, 47, 0, 22,
-  0, 0, 0, 0, 6, 0, 0, 0, 122, 0,
-  29, 0, 52, 16, 0, 39, 58, 0, 0, 0,
-  35, 20, 76, 0, 11, 39, 97, 0, 0, 94,
-  63, 17, 0, 0, 0, 47, 11, 21, 63, 0,
-  0, 58, 0, 0, 0, 24, 97, 0, 27, 0,
-  0, 89, 26, 22, 38, 4, 46, 33, 23, 117,
-  42, 0, 0, 22, 0, 0, 14, 0, 32, 0,
-  5, 0, 47, 0, 0, 49, 0, 19, 0, 0,
-  17, 1, 30, 0, 0, 0, 56, 43, 10, 31,
-  22, 65, 0, 0, 6, 0, 19, 88, 0, 42,
-  0, 0, 0, 23, 0, 11, 0, 31, 0, 0,
-  0, 0, 0, 85, 98, 0, 0, 0, 13, 0,
-  31, 29, 0, 24, 0, 19, 0, 5, 0, 0,
-  0, 12, 70, 0, 0, 0, 32, 0, 63, 0,
-  24, 34, 0, 10, 0, 0, 0, 0, 0, 1,
-  32, 2, 16, 56, 0, 30, 0, 9, 3, 0,
-  2, 0, 1, 27, 71, 20, 5, 0, 0, 23,
-  0, 18, 0, 0, 30, 0, 15, 0, 59, 84,
-  34, 0, 85, 0, 0, 5, 0, 98, 39, 10,
-  0, 0, 0, 0, 0, 0, 57, 0, 55, 0,
-  96, 0, 0, 81, 9, 12, 28, 9, 50, 46,
-  29, 21, 0, 0, 85, 58, 7, 94, 37, 18,
-  0, 0, 0, 22, 0, 74, 0, 50, 11, 36,
-  0, 0, 0, 84, 19, 16, 0, 0, 0, 0,
-  17, 49, 89, 0, 0, 0, 0, 27, 5, 0,
-  0, 3, 0, 9, 0, 9, 21, 75, 0, 33,
-  64, 0, 0, 0, 0, 0, 0, 0, 0, 41,
-  4, 18, 11, 6, 0, 0, 0, 0, 60, 44,
-  0, 0, 0, 54, 0, 0, 0, 29, 17, 0,
-  3, 11, 34, 17, 0, 0, 58, 48, 0, 0,
-  0, 0, 53, 0, 0, 0, 74, 109, 0, 0,
-  46, 0, 0, 0, 0, 59, 0, 51, 0, 23,
-  0, 0, 0, 0, 78, 7, 34, 8, 0, 0,
-  0, 52, 29, 14, 74, 2, 53, 17, 8, 144,
-  9, 0, 46, 89, 0, 57, 27, 0, 12, 0,
-  0, 0, 31, 87, 0, 30, 0, 43, 20, 0,
-  0, 171, 0, 0, 22, 0, 7, 0, 0, 57,
-  123, 33, 0, 0, 0, 0, 0, 2, 0, 0,
-  0, 24, 0, 10, 20, 24, 0, 0, 14, 0,
-  0, 0, 0, 0, 0, 4, 58, 62, 0, 0,
-  95, 9, 0, 0, 0, 24, 67, 28, 0, 54,
-  35, 44, 0, 52, 0, 15, 0, 0, 0, 58,
-  28, 9, 0, 0, 21, 48, 6, 84, 0, 37,
-  76, 0, 22, 0, 105, 123, 0, 0, 100, 0,
-  38, 0, 0, 109, 0, 0, 0, 11, 0, 0,
-  0, 0, 96, 0, 19, 0, 47, 0, 0, 83,
-  53, 15, 66, 0, 7, 34, 0, 90, 0, 0,
-  122, 30, 0, 21, 7, 0, 14, 0, 0, 2,
-  0, 89, 0, 17, 21, 0, 35, 0, 0, 36,
-  0, 3, 0, 0, 0, 0, 0, 59, 137, 0,
-  0, 0, 0, 0, 0, 52, 0, 3, 30, 17,
-  0, 0, 80, 0, 22, 0, 52, 0, 0, 0,
-  0, 0, 0, 14, 61, 73, 19, 3, 82, 25,
-  7, 0, 0, 19, 0, 0, 0, 50, 24, 124,
-  0, 0, 0, 0, 0, 0, 16, 66, 70, 4,
-  0, 0, 12, 4, 0, 88, 7, 3, 0, 13,
-  0, 0, 74, 8, 0, 0, 84, 0, 0, 15,
-  17, 36, 17, 22, 4, 0, 9, 49, 0, 0,
-  86, 0, 46, 0, 71, 0, 0, 47, 100, 0,
-  96, 0, 0, 47, 0, 116, 0, 23, 90, 0,
-  0, 33, 0, 0, 23, 0, 0, 55, 0, 76,
-  0, 1, 45, 31, 68, 0, 0, 0, 10, 0,
-  0, 0, 0, 0, 0, 29, 67, 0, 0, 0,
-  0, 4, 0, 42, 0, 0, 54, 0, 0, 0,
-  124, 74, 44, 0, 25, 0, 0, 0, 0, 25,
-  0, 22, 0, 56, 83, 83, 12, 72, 44, 15,
-  0, 0, 20, 0, 22, 0, 23, 126, 0, 0,
-  0, 0, 39, 0, 24, 37, 34, 21, 0, 0,
-  35, 11, 0, 34, 52, 81, 0, 0, 0, 0,
-  0, 26, 0, 0, 0, 1, 0, 0, 1, 18,
-  42, 71, 0, 0, 11, 40, 0, 7, 106, 0,
-  38, 4, 10, 0, 0, 34, 61, 26, 20, 0,
-  27, 21, 0, 98, 0, 49, 51, 0, 0, 28,
-  54, 0, 44, 0, 0, 48, 15, 60, 0, 1,
-  2, 45, 68, 0, 14, 0, 0, 25, 0, 0,
-  81, 0, 11, 15, 12, 121, 4, 0, 0, 16,
-  0, 68, 74, 0, 26, 0, 17, 1, 24, 87,
-  0, 0, 20, 2, 10, 0, 0, 0, 0, 22,
-  0, 87, 0, 22, 0, 0, 13, 12, 20, 0,
-  30, 0, 12, 20, 47, 4, 0, 16, 61, 0,
-  3, 0, 0, 56, 0, 10, 36, 0, 0, 41,
-  0, 0, 2, 0, 51, 24, 0, 0, 0, 75,
-  57, 0, 0, 1, 0, 46, 0, 115, 40, 68,
-  0, 0, 0, 16, 0, 0, 30, 32, 30, 0,
-  49, 0, 37, 54, 0, 31, 7, 0, 25, 63,
-  98, 0, 89, 0, 26, 32, 28, 22, 29, 0,
-  0, 0, 0, 0, 23, 34, 22, 43, 0, 13,
-  0, 0, 0, 67, 0, 29, 0, 0, 0, 0,
-  28, 122, 64, 34, 0, 28, 14, 55, 5, 5,
-  0, 0, 0, 59, 0, 9, 0, 5, 0, 38,
-  80, 0, 0, 0, 7, 0, 12, 0, 22, 22,
-  0, 49, 0, 0, 0, 0, 12, 0, 80, 43,
-  25, 0, 73, 2, 0, 149, 100, 43, 17, 0,
-  0, 0, 0, 25, 0, 0, 21, 90, 9, 0,
-  9, 0, 115, 13, 0, 0, 4, 73, 0, 0,
-  23, 0, 0, 26, 0, 80, 0, 54, 0, 37,
-  0, 15, 61, 0, 0, 23, 13, 7, 0, 32,
-  0, 0, 0, 0, 0, 0, 27, 12, 61, 0,
-  7, 0, 0, 98, 0, 66, 0, 13, 0, 0,
-  19, 3, 24, 48, 0, 47, 3, 23, 13, 19,
-  53, 124, 0, 32, 23, 0, 0, 0, 0, 90,
-  142, 0, 0, 0, 8, 0, 0, 33, 0, 34,
-  0, 47, 0, 22, 0, 0, 0, 0, 6, 0,
-  0, 0, 122, 0, 29, 0, 52, 16, 0, 27,
-  108, 0, 0, 0, 0, 0, 90, 42, 15, 0,
-  26, 53, 0, 84, 60, 35, 50, 0, 0, 15,
-  20, 31, 0, 0, 3, 111, 0, 0, 0, 0,
-  61, 0, 0, 0, 0, 79, 0, 0, 3, 0,
-  0, 0, 0, 28, 0, 0, 0, 35, 0, 82,
-  11, 0, 69, 0, 27, 18, 0, 0, 0, 0,
-  0, 0, 27, 0, 48, 0, 11, 70, 0, 0,
-  22, 90, 0, 69, 0, 68, 0, 0, 7, 0,
-  32, 92, 0, 47, 0, 58, 48, 0, 85, 34,
-  0, 0, 11, 0, 0, 0, 0, 133, 125, 0,
-  0, 0, 8, 0, 0, 61, 0, 16, 7, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  45, 0, 54, 0, 21, 46, 0, 10, 0, 0,
-  0, 0, 0, 1, 32, 2, 16, 56, 0, 30,
-  0, 9, 3, 0, 2, 0, 1, 27, 71, 20,
-  5, 0, 0, 23, 0, 18, 0, 0, 30, 0,
-  15, 0, 59, 84, 34, 0, 85, 0, 0, 5,
-  0, 98, 39, 10, 0, 0, 0, 0, 0, 0,
-  57, 0, 55, 0, 96, 0, 0, 81, 9, 12,
-  28, 9, 50, 46, 29, 21, 0, 0, 85, 58,
-  7, 94, 37, 18, 0, 0, 0, 22, 0, 74,
-  0, 50, 11, 36, 0, 0, 0, 84, 19, 16,
-  0, 0, 0, 0, 17, 49, 89, 0, 0, 0,
-  0, 27, 5, 0, 0, 3, 0, 9, 0, 9,
-  21, 75, 0, 33, 64, 0, 0, 0, 0, 0,
-  0, 0, 0, 41, 4, 18, 11, 6, 0, 0,
-  0, 0, 60, 44, 0, 0, 0, 54, 0, 0,
-  0, 29, 17, 0, 3, 11, 34, 17, 0, 0,
-  58, 48, 0, 0, 0, 0, 53, 0, 0, 0,
-  74, 109, 0, 0, 46, 0, 0, 0, 0, 59,
-  0, 51, 0, 23, 0, 0, 0, 0, 78, 7,
-  34, 8, 0, 0, 0, 52, 29, 14, 74, 2,
-  53, 17, 8, 144, 9, 0, 46, 89, 0, 57,
-  27, 0, 12, 0, 0, 0, 31, 87, 0, 30,
-  0, 43, 20, 0, 0, 171, 0, 0, 22, 0,
-  7, 0, 0, 57, 123, 33, 0, 0, 0, 0,
-  0, 2, 0, 0, 0, 24, 0, 10, 20, 24,
-  0, 0, 14, 0, 0, 0, 0, 0, 0, 4,
-  58, 62, 28, 0, 51, 0, 0, 127, 0, 0,
-  28, 13, 0, 0, 0, 82, 0, 0, 9, 29,
-  31, 0, 0, 85, 28, 32, 0, 0, 13, 55,
-  0, 0, 0, 43, 0, 0, 0, 17, 44, 93,
-  0, 0, 24, 0, 15, 0, 0, 32, 0, 29,
-  0, 35, 0, 77, 0, 0, 138, 0, 12, 0,
-  0, 0, 0, 64, 0, 0, 81, 0, 9, 6,
-  12, 125, 8, 0, 33, 55, 0, 39, 22, 0,
-  0, 0, 0, 0, 28, 82, 0, 10, 0, 46,
-  0, 0, 0, 123, 0, 0, 55, 0, 11, 0,
-  0, 88, 63, 49, 0, 0, 27, 0, 0, 10,
-  0, 6, 1, 11, 0, 0, 9, 35, 24, 0,
-  11, 0, 0, 0, 0, 0, 0, 3, 9, 79,
-  19, 3, 82, 25, 7, 0, 0, 19, 0, 0,
-  0, 50, 24, 124, 0, 0, 0, 0, 0, 0,
-  16, 66, 70, 4, 0, 0, 12, 4, 0, 88,
-  7, 3, 0, 13, 0, 0, 74, 8, 0, 0,
-  84, 0, 0, 15, 17, 36, 17, 22, 4, 0,
-  9, 49, 0, 0, 86, 0, 46, 0, 71, 0,
-  0, 47, 100, 0, 96, 0, 0, 47, 0, 116,
-  0, 23, 90, 0, 0, 33, 0, 0, 23, 0,
-  0, 55, 0, 76, 0, 1, 45, 31, 68, 0,
-  0, 0, 10, 0, 0, 0, 0, 0, 0, 29,
-  67, 0, 0, 0, 0, 4, 0, 42, 0, 0,
-  54, 0, 0, 0, 124, 74, 44, 0, 25, 0,
-  0, 0, 0, 25, 0, 22, 0, 56, 83, 83,
-  12, 72, 44, 15, 0, 0, 20, 0, 22, 0,
-  23, 126, 0, 0, 0, 0, 39, 0, 24, 37,
-  34, 21, 0, 0, 35, 11, 0, 34, 52, 81,
-  0, 0, 0, 0, 0, 26, 0, 0, 0, 1,
-  0, 0, 1, 18, 42, 71, 0, 0, 11, 40,
-  0, 7, 106, 0, 38, 4, 10, 0, 0, 34,
-  61, 26, 20, 0, 27, 21, 0, 98, 0, 49,
-  51, 0, 0, 28, 54, 0, 44, 0, 0, 48,
-  15, 60, 0, 1, 2, 45, 68, 0, 14, 0,
-  0, 25, 0, 0, 81, 0, 11, 15, 12, 121,
-  4, 0, 0, 16, 0, 68, 74, 0, 26, 0,
-  17, 1, 24, 87, 0, 0, 20, 2, 10, 0,
-  0, 0, 0, 22, 0, 87, 35, 0, 20, 65,
-  14, 232, 0, 0, 1, 0, 0, 0, 0, 21,
-  0, 0, 0, 33, 62, 0, 0, 113, 15, 0,
-  0, 0, 0, 6, 0, 17, 8, 99, 0, 0,
-  0, 33, 0, 40, 0, 0, 0, 0, 0, 0,
-  0, 58, 44, 47, 7, 4, 0, 38, 0, 0,
-  142, 0, 48, 0, 21, 0, 27, 92, 17, 0,
-  115, 0, 0, 40, 0, 96, 83, 63, 62, 0,
-  0, 35, 43, 0, 0, 0, 0, 0, 46, 65,
-  0, 0, 0, 31, 0, 0, 7, 7, 0, 0,
-  70, 0, 52, 0, 0, 9, 17, 116, 2, 0,
-  0, 5, 18, 17, 0, 0, 0, 39, 0, 0,
-  0, 45, 36, 0, 13, 16, 0, 19, 0, 0,
-  0, 15, 0, 44, 0, 49, 0, 0, 0, 0,
-  12, 0, 80, 43, 25, 0, 73, 2, 0, 149,
-  100, 43, 17, 0, 0, 0, 0, 25, 0, 0,
-  21, 90, 9, 0, 9, 0, 115, 13, 0, 0,
-  4, 73, 0, 0, 23, 0, 0, 26, 0, 80,
-  0, 54, 0, 37, 0, 15, 61, 0, 0, 23,
-  13, 7, 0, 32, 0, 0, 0, 0, 0, 0,
-  27, 12, 61, 0, 7, 0, 0, 98, 0, 66,
-  0, 13, 0, 0, 19, 3, 24, 48, 0, 47,
-  3, 23, 13, 19, 53, 124, 0, 32, 23, 0,
-  0, 0, 0, 90, 142, 0, 0, 0, 8, 0,
-  0, 33, 0, 34, 0, 47, 0, 22, 0, 0,
-  0, 0, 6, 0, 0, 0, 122, 0, 29, 0,
-  52, 16, 0, 27, 108, 0, 0, 0, 0, 0,
-  90, 42, 15, 0, 26, 53, 0, 84, 60, 35,
-  50, 0, 0, 15, 20, 31, 0, 0, 3, 111,
-  0, 0, 0, 0, 61, 0, 0, 0, 0, 79,
-  0, 0, 3, 0, 0, 0, 0, 28, 0, 0,
-  0, 35, 0, 82, 11, 0, 69, 0, 27, 18,
-  0, 0, 0, 0, 0, 0, 27, 0, 48, 0,
-  11, 70, 0, 0, 22, 90, 0, 69, 0, 68,
-  0, 0, 7, 0, 32, 92, 0, 47, 0, 58,
-  48, 0, 85, 34, 0, 0, 11, 0, 0, 0,
-  0, 133, 125, 0, 0, 0, 8, 0, 0, 61,
-  0, 16, 7, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 45, 0, 54, 0, 21, 46,
-  0, 0, 117, 0, 0, 75, 0, 0, 21, 0,
-  0, 1, 34, 80, 0, 0, 0, 31, 19, 0,
-  0, 94, 14, 24, 0, 0, 0, 29, 0, 0,
-  10, 39, 0, 0, 0, 0, 0, 56, 0, 0,
-  0, 0, 0, 7, 0, 0, 0, 0, 0, 0,
-  0, 155, 0, 0, 71, 0, 21, 0, 50, 0,
-  0, 5, 0, 0, 108, 0, 0, 0, 0, 98,
-  0, 0, 39, 7, 0, 0, 0, 22, 15, 0,
-  0, 0, 31, 74, 16, 3, 15, 30, 48, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 72,
-  30, 0, 0, 0, 0, 78, 0, 23, 0, 11,
-  40, 0, 0, 0, 17, 16, 68, 25, 10, 51,
-  0, 3, 0, 0, 33, 0, 0, 53, 4, 18,
-  11, 6, 0, 0, 0, 0, 60, 44, 0, 0,
-  0, 54, 0, 0, 0, 29, 17, 0, 3, 11,
-  34, 17, 0, 0, 58, 48, 0, 0, 0, 0,
-  53, 0, 0, 0, 74, 109, 0, 0, 46, 0,
-  0, 0, 0, 59, 0, 51, 0, 23, 0, 0,
-  0, 0, 78, 7, 34, 8, 0, 0, 0, 52,
-  29, 14, 74, 2, 53, 17, 8, 144, 9, 0,
-  46, 89, 0, 57, 27, 0, 12, 0, 0, 0,
-  31, 87, 0, 30, 0, 43, 20, 0, 0, 171,
-  0, 0, 22, 0, 7, 0, 0, 57, 123, 33,
-  0, 0, 0, 0, 0, 2, 0, 0, 0, 24,
-  0, 10, 20, 24, 0, 0, 14, 0, 0, 0,
-  0, 0, 0, 4, 58, 62, 28, 0, 51, 0,
-  0, 127, 0, 0, 28, 13, 0, 0, 0, 82,
-  0, 0, 9, 29, 31, 0, 0, 85, 28, 32,
-  0, 0, 13, 55, 0, 0, 0, 43, 0, 0,
-  0, 17, 44, 93, 0, 0, 24, 0, 15, 0,
-  0, 32, 0, 29, 0, 35, 0, 77, 0, 0,
-  138, 0, 12, 0, 0, 0, 0, 64, 0, 0,
-  81, 0, 9, 6, 12, 125, 8, 0, 33, 55,
-  0, 39, 22, 0, 0, 0, 0, 0, 28, 82,
-  0, 10, 0, 46, 0, 0, 0, 123, 0, 0,
-  55, 0, 11, 0, 0, 88, 63, 49, 0, 0,
-  27, 0, 0, 10, 0, 6, 1, 11, 0, 0,
-  9, 35, 24, 0, 11, 0, 0, 0, 0, 0,
-  0, 3, 9, 79, 0, 0, 30, 0, 26, 161,
-  0, 0, 0, 0, 0, 0, 49, 60, 0, 0,
-  11, 55, 0, 0, 7, 16, 0, 50, 0, 0,
-  0, 0, 0, 35, 21, 0, 0, 13, 0, 0,
-  0, 55, 0, 3, 0, 20, 0, 22, 0, 12,
-  34, 22, 0, 0, 13, 103, 4, 0, 17, 0,
-  10, 0, 46, 0, 0, 0, 0, 0, 54, 0,
-  0, 2, 0, 4, 0, 34, 24, 5, 0, 40,
-  0, 0, 0, 10, 0, 0, 18, 36, 19, 0,
-  31, 36, 38, 0, 0, 22, 13, 0, 4, 0,
-  0, 0, 1, 46, 1, 0, 0, 0, 0, 10,
-  0, 22, 0, 25, 23, 0, 0, 0, 5, 29,
-  102, 47, 32, 3, 54, 0, 0, 0, 37, 15,
-  0, 14, 83, 83, 12, 72, 44, 15, 0, 0,
-  20, 0, 22, 0, 23, 126, 0, 0, 0, 0,
-  39, 0, 24, 37, 34, 21, 0, 0, 35, 11,
-  0, 34, 52, 81, 0, 0, 0, 0, 0, 26,
-  0, 0, 0, 1, 0, 0, 1, 18, 42, 71,
-  0, 0, 11, 40, 0, 7, 106, 0, 38, 4,
-  10, 0, 0, 34, 61, 26, 20, 0, 27, 21,
-  0, 98, 0, 49, 51, 0, 0, 28, 54, 0,
-  44, 0, 0, 48, 15, 60, 0, 1, 2, 45,
-  68, 0, 14, 0, 0, 25, 0, 0, 81, 0,
-  11, 15, 12, 121, 4, 0, 0, 16, 0, 68,
-  74, 0, 26, 0, 17, 1, 24, 87, 0, 0,
-  20, 2, 10, 0, 0, 0, 0, 22, 0, 87,
-  35, 0, 20, 65, 14, 232, 0, 0, 1, 0,
-  0, 0, 0, 21, 0, 0, 0, 33, 62, 0,
-  0, 113, 15, 0, 0, 0, 0, 6, 0, 17,
-  8, 99, 0, 0, 0, 33, 0, 40, 0, 0,
-  0, 0, 0, 0, 0, 58, 44, 47, 7, 4,
-  0, 38, 0, 0, 142, 0, 48, 0, 21, 0,
-  27, 92, 17, 0, 115, 0, 0, 40, 0, 96,
-  83, 63, 62, 0, 0, 35, 43, 0, 0, 0,
-  0, 0, 46, 65, 0, 0, 0, 31, 0, 0,
-  7, 7, 0, 0, 70, 0, 52, 0, 0, 9,
-  17, 116, 2, 0, 0, 5, 18, 17, 0, 0,
-  0, 39, 0, 0, 0, 45, 36, 0, 13, 16,
-  0, 19, 0, 0, 0, 15, 0, 44, 0, 0,
-  0, 5, 19, 184, 0, 0, 0, 0, 0, 0,
-  30, 14, 0, 24, 4, 50, 5, 0, 21, 0,
-  0, 62, 18, 19, 0, 0, 0, 10, 18, 0,
-  0, 34, 0, 4, 0, 24, 0, 24, 0, 55,
-  0, 16, 0, 17, 43, 43, 0, 20, 0, 38,
-  14, 0, 0, 0, 9, 0, 19, 12, 5, 26,
-  0, 0, 6, 0, 0, 22, 22, 0, 30, 56,
-  37, 1, 2, 80, 0, 0, 0, 42, 0, 0,
-  13, 12, 24, 0, 22, 14, 2, 28, 1, 67,
-  43, 9, 35, 30, 0, 0, 7, 25, 0, 0,
-  0, 0, 0, 0, 0, 6, 0, 17, 0, 1,
-  0, 13, 0, 7, 81, 29, 34, 0, 48, 9,
-  42, 0, 38, 19, 0, 0, 0, 27, 108, 0,
-  0, 0, 0, 0, 90, 42, 15, 0, 26, 53,
-  0, 84, 60, 35, 50, 0, 0, 15, 20, 31,
-  0, 0, 3, 111, 0, 0, 0, 0, 61, 0,
-  0, 0, 0, 79, 0, 0, 3, 0, 0, 0,
-  0, 28, 0, 0, 0, 35, 0, 82, 11, 0,
-  69, 0, 27, 18, 0, 0, 0, 0, 0, 0,
-  27, 0, 48, 0, 11, 70, 0, 0, 22, 90,
-  0, 69, 0, 68, 0, 0, 7, 0, 32, 92,
-  0, 47, 0, 58, 48, 0, 85, 34, 0, 0,
-  11, 0, 0, 0, 0, 133, 125, 0, 0, 0,
-  8, 0, 0, 61, 0, 16, 7, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 45, 0,
-  54, 0, 21, 46, 0, 0, 117, 0, 0, 75,
-  0, 0, 21, 0, 0, 1, 34, 80, 0, 0,
-  0, 31, 19, 0, 0, 94, 14, 24, 0, 0,
-  0, 29, 0, 0, 10, 39, 0, 0, 0, 0,
-  0, 56, 0, 0, 0, 0, 0, 7, 0, 0,
-  0, 0, 0, 0, 0, 155, 0, 0, 71, 0,
-  21, 0, 50, 0, 0, 5, 0, 0, 108, 0,
-  0, 0, 0, 98, 0, 0, 39, 7, 0, 0,
-  0, 22, 15, 0, 0, 0, 31, 74, 16, 3,
-  15, 30, 48, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 72, 30, 0, 0, 0, 0, 78,
-  0, 23, 0, 11, 40, 0, 0, 0, 17, 16,
-  68, 25, 10, 51, 0, 3, 0, 0, 33, 0,
-  0, 53, 0, 0, 59, 0, 5, 69, 0, 0,
-  0, 0, 0, 19, 45, 76, 0, 0, 0, 17,
-  2, 8, 10, 22, 0, 35, 0, 0, 0, 0,
-  0, 77, 41, 11, 0, 18, 0, 0, 0, 17,
-  0, 13, 0, 0, 0, 39, 0, 0, 0, 0,
-  0, 0, 0, 110, 0, 0, 0, 0, 15, 4,
-  28, 0, 0, 0, 0, 0, 48, 0, 0, 6,
-  0, 9, 0, 40, 17, 0, 0, 0, 0, 0,
-  53, 0, 0, 17, 0, 52, 45, 0, 40, 9,
-  68, 0, 0, 0, 56, 0, 0, 5, 0, 0,
-  0, 21, 0, 0, 0, 0, 1, 53, 0, 16,
-  7, 45, 50, 0, 0, 13, 38, 10, 68, 48,
-  19, 52, 56, 0, 0, 0, 26, 9, 0, 10,
-  28, 0, 51, 0, 0, 127, 0, 0, 28, 13,
-  0, 0, 0, 82, 0, 0, 9, 29, 31, 0,
-  0, 85, 28, 32, 0, 0, 13, 55, 0, 0,
-  0, 43, 0, 0, 0, 17, 44, 93, 0, 0,
-  24, 0, 15, 0, 0, 32, 0, 29, 0, 35,
-  0, 77, 0, 0, 138, 0, 12, 0, 0, 0,
-  0, 64, 0, 0, 81, 0, 9, 6, 12, 125,
-  8, 0, 33, 55, 0, 39, 22, 0, 0, 0,
-  0, 0, 28, 82, 0, 10, 0, 46, 0, 0,
-  0, 123, 0, 0, 55, 0, 11, 0, 0, 88,
-  63, 49, 0, 0, 27, 0, 0, 10, 0, 6,
-  1, 11, 0, 0, 9, 35, 24, 0, 11, 0,
-  0, 0, 0, 0, 0, 3, 9, 79, 0, 0,
-  30, 0, 26, 161, 0, 0, 0, 0, 0, 0,
-  49, 60, 0, 0, 11, 55, 0, 0, 7, 16,
-  0, 50, 0, 0, 0, 0, 0, 35, 21, 0,
-  0, 13, 0, 0, 0, 55, 0, 3, 0, 20,
-  0, 22, 0, 12, 34, 22, 0, 0, 13, 103,
-  4, 0, 17, 0, 10, 0, 46, 0, 0, 0,
-  0, 0, 54, 0, 0, 2, 0, 4, 0, 34,
-  24, 5, 0, 40, 0, 0, 0, 10, 0, 0,
-  18, 36, 19, 0, 31, 36, 38, 0, 0, 22,
-  13, 0, 4, 0, 0, 0, 1, 46, 1, 0,
-  0, 0, 0, 10, 0, 22, 0, 25, 23, 0,
-  0, 0, 5, 29, 102, 47, 32, 3, 54, 0,
-  0, 0, 37, 15, 0, 14, 0, 49, 11, 0,
-  44, 0, 25, 0, 19, 0, 0, 0, 81, 51,
-  5, 17, 15, 0, 0, 0, 3, 0, 0, 60,
-  21, 63, 0, 0, 0, 12, 63, 0, 0, 27,
-  12, 0, 0, 6, 0, 70, 0, 97, 10, 75,
-  53, 0, 0, 0, 0, 6, 0, 65, 94, 0,
-  0, 3, 21, 23, 4, 21, 0, 0, 0, 70,
-  0, 12, 8, 0, 0, 0, 0, 33, 0, 19,
-  20, 29, 0, 0, 0, 27, 44, 20, 19, 0,
-  78, 0, 29, 0, 66, 38, 0, 0, 42, 37,
-  0, 32, 0, 38, 3, 45, 0, 0, 0, 0,
-  0, 0, 3, 5, 71, 72, 88, 0, 0, 7,
-  31, 0, 0, 31, 64, 18, 57, 10, 85, 0,
-  91, 2, 0, 0, 35, 0, 20, 65, 14, 232,
-  0, 0, 1, 0, 0, 0, 0, 21, 0, 0,
-  0, 33, 62, 0, 0, 113, 15, 0, 0, 0,
-  0, 6, 0, 17, 8, 99, 0, 0, 0, 33,
-  0, 40, 0, 0, 0, 0, 0, 0, 0, 58,
-  44, 47, 7, 4, 0, 38, 0, 0, 142, 0,
-  48, 0, 21, 0, 27, 92, 17, 0, 115, 0,
-  0, 40, 0, 96, 83, 63, 62, 0, 0, 35,
-  43, 0, 0, 0, 0, 0, 46, 65, 0, 0,
-  0, 31, 0, 0, 7, 7, 0, 0, 70, 0,
-  52, 0, 0, 9, 17, 116, 2, 0, 0, 5,
-  18, 17, 0, 0, 0, 39, 0, 0, 0, 45,
-  36, 0, 13, 16, 0, 19, 0, 0, 0, 15,
-  0, 44, 0, 0, 0, 5, 19, 184, 0, 0,
-  0, 0, 0, 0, 30, 14, 0, 24, 4, 50,
-  5, 0, 21, 0, 0, 62, 18, 19, 0, 0,
-  0, 10, 18, 0, 0, 34, 0, 4, 0, 24,
-  0, 24, 0, 55, 0, 16, 0, 17, 43, 43,
-  0, 20, 0, 38, 14, 0, 0, 0, 9, 0,
-  19, 12, 5, 26, 0, 0, 6, 0, 0, 22,
-  22, 0, 30, 56, 37, 1, 2, 80, 0, 0,
-  0, 42, 0, 0, 13, 12, 24, 0, 22, 14,
-  2, 28, 1, 67, 43, 9, 35, 30, 0, 0,
-  7, 25, 0, 0, 0, 0, 0, 0, 0, 6,
-  0, 17, 0, 1, 0, 13, 0, 7, 81, 29,
-  34, 0, 48, 9, 42, 0, 38, 19, 0, 0,
-  0, 34, 49, 0, 25, 0, 17, 0, 0, 0,
-  0, 0, 29, 51, 2, 46, 15, 40, 0, 20,
-  33, 0, 79, 40, 0, 20, 0, 0, 0, 0,
-  25, 0, 0, 0, 0, 0, 0, 5, 0, 35,
-  63, 42, 0, 75, 56, 0, 0, 0, 0, 4,
-  0, 42, 63, 0, 1, 0, 44, 5, 9, 0,
-  0, 3, 0, 23, 0, 0, 26, 7, 0, 0,
-  0, 3, 4, 30, 12, 34, 0, 8, 0, 0,
-  40, 0, 0, 0, 68, 13, 0, 0, 40, 12,
-  0, 29, 32, 0, 0, 30, 0, 0, 0, 46,
-  0, 0, 0, 0, 5, 0, 0, 0, 0, 29,
-  58, 4, 0, 15, 30, 0, 26, 17, 54, 0,
-  15, 0, 9, 0, 76, 5, 0, 0, 0, 0,
-  117, 0, 0, 75, 0, 0, 21, 0, 0, 1,
-  34, 80, 0, 0, 0, 31, 19, 0, 0, 94,
-  14, 24, 0, 0, 0, 29, 0, 0, 10, 39,
-  0, 0, 0, 0, 0, 56, 0, 0, 0, 0,
-  0, 7, 0, 0, 0, 0, 0, 0, 0, 155,
-  0, 0, 71, 0, 21, 0, 50, 0, 0, 5,
-  0, 0, 108, 0, 0, 0, 0, 98, 0, 0,
-  39, 7, 0, 0, 0, 22, 15, 0, 0, 0,
-  31, 74, 16, 3, 15, 30, 48, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 72, 30, 0,
-  0, 0, 0, 78, 0, 23, 0, 11, 40, 0,
-  0, 0, 17, 16, 68, 25, 10, 51, 0, 3,
-  0, 0, 33, 0, 0, 53, 0, 0, 59, 0,
-  5, 69, 0, 0, 0, 0, 0, 19, 45, 76,
-  0, 0, 0, 17, 2, 8, 10, 22, 0, 35,
-  0, 0, 0, 0, 0, 77, 41, 11, 0, 18,
-  0, 0, 0, 17, 0, 13, 0, 0, 0, 39,
-  0, 0, 0, 0, 0, 0, 0, 110, 0, 0,
-  0, 0, 15, 4, 28, 0, 0, 0, 0, 0,
-  48, 0, 0, 6, 0, 9, 0, 40, 17, 0,
-  0, 0, 0, 0, 53, 0, 0, 17, 0, 52,
-  45, 0, 40, 9, 68, 0, 0, 0, 56, 0,
-  0, 5, 0, 0, 0, 21, 0, 0, 0, 0,
-  1, 53, 0, 16, 7, 45, 50, 0, 0, 13,
-  38, 10, 68, 48, 19, 52, 56, 0, 0, 0,
-  26, 9, 0, 10, 0, 52, 52, 0, 44, 0,
-  21, 0, 7, 0, 0, 3, 68, 73, 3, 33,
-  10, 1, 18, 0, 44, 0, 0, 50, 14, 42,
-  0, 0, 0, 12, 60, 0, 0, 39, 0, 0,
-  0, 7, 0, 62, 39, 63, 0, 87, 51, 0,
-  0, 0, 0, 0, 0, 78, 42, 0, 0, 0,
-  18, 20, 19, 14, 11, 0, 3, 81, 0, 28,
-  0, 0, 0, 0, 0, 30, 0, 13, 8, 1,
-  0, 0, 0, 18, 37, 38, 21, 0, 88, 0,
-  16, 0, 65, 54, 0, 0, 46, 25, 0, 61,
-  0, 19, 5, 30, 0, 0, 0, 0, 0, 0,
-  0, 15, 38, 43, 88, 0, 0, 20, 22, 0,
-  0, 24, 58, 18, 39, 4, 45, 0, 79, 0,
-  1, 0, 0, 0, 30, 0, 26, 161, 0, 0,
-  0, 0, 0, 0, 49, 60, 0, 0, 11, 55,
-  0, 0, 7, 16, 0, 50, 0, 0, 0, 0,
-  0, 35, 21, 0, 0, 13, 0, 0, 0, 55,
-  0, 3, 0, 20, 0, 22, 0, 12, 34, 22,
-  0, 0, 13, 103, 4, 0, 17, 0, 10, 0,
-  46, 0, 0, 0, 0, 0, 54, 0, 0, 2,
-  0, 4, 0, 34, 24, 5, 0, 40, 0, 0,
-  0, 10, 0, 0, 18, 36, 19, 0, 31, 36,
-  38, 0, 0, 22, 13, 0, 4, 0, 0, 0,
-  1, 46, 1, 0, 0, 0, 0, 10, 0, 22,
-  0, 25, 23, 0, 0, 0, 5, 29, 102, 47,
-  32, 3, 54, 0, 0, 0, 37, 15, 0, 14,
-  0, 49, 11, 0, 44, 0, 25, 0, 19, 0,
-  0, 0, 81, 51, 5, 17, 15, 0, 0, 0,
-  3, 0, 0, 60, 21, 63, 0, 0, 0, 12,
-  63, 0, 0, 27, 12, 0, 0, 6, 0, 70,
-  0, 97, 10, 75, 53, 0, 0, 0, 0, 6,
-  0, 65, 94, 0, 0, 3, 21, 23, 4, 21,
-  0, 0, 0, 70, 0, 12, 8, 0, 0, 0,
-  0, 33, 0, 19, 20, 29, 0, 0, 0, 27,
-  44, 20, 19, 0, 78, 0, 29, 0, 66, 38,
-  0, 0, 42, 37, 0, 32, 0, 38, 3, 45,
-  0, 0, 0, 0, 0, 0, 3, 5, 71, 72,
-  88, 0, 0, 7, 31, 0, 0, 31, 64, 18,
-  57, 10, 85, 0, 91, 2, 0, 0, 0, 21,
-  76, 0, 26, 0, 1, 0, 0, 0, 0, 6,
-  28, 78, 0, 20, 4, 29, 21, 10, 35, 34,
-  113, 11, 0, 0, 0, 0, 0, 0, 18, 0,
-  0, 0, 0, 0, 0, 1, 0, 10, 66, 3,
-  0, 101, 57, 6, 0, 0, 0, 0, 0, 90,
-  1, 0, 17, 0, 40, 0, 25, 0, 0, 10,
-  7, 19, 34, 0, 0, 18, 0, 29, 0, 0,
-  0, 43, 3, 0, 0, 28, 0, 0, 37, 0,
-  22, 0, 65, 9, 0, 0, 20, 0, 0, 16,
-  13, 0, 0, 46, 0, 0, 0, 39, 0, 0,
-  0, 0, 1, 0, 0, 4, 0, 7, 72, 14,
-  0, 12, 20, 0, 52, 13, 51, 13, 13, 0,
-  0, 0, 64, 0, 0, 0, 0, 0, 0, 5,
-  19, 184, 0, 0, 0, 0, 0, 0, 30, 14,
-  0, 24, 4, 50, 5, 0, 21, 0, 0, 62,
-  18, 19, 0, 0, 0, 10, 18, 0, 0, 34,
-  0, 4, 0, 24, 0, 24, 0, 55, 0, 16,
-  0, 17, 43, 43, 0, 20, 0, 38, 14, 0,
-  0, 0, 9, 0, 19, 12, 5, 26, 0, 0,
-  6, 0, 0, 22, 22, 0, 30, 56, 37, 1,
-  2, 80, 0, 0, 0, 42, 0, 0, 13, 12,
-  24, 0, 22, 14, 2, 28, 1, 67, 43, 9,
-  35, 30, 0, 0, 7, 25, 0, 0, 0, 0,
-  0, 0, 0, 6, 0, 17, 0, 1, 0, 13,
-  0, 7, 81, 29, 34, 0, 48, 9, 42, 0,
-  38, 19, 0, 0, 0, 34, 49, 0, 25, 0,
-  17, 0, 0, 0, 0, 0, 29, 51, 2, 46,
-  15, 40, 0, 20, 33, 0, 79, 40, 0, 20,
-  0, 0, 0, 0, 25, 0, 0, 0, 0, 0,
-  0, 5, 0, 35, 63, 42, 0, 75, 56, 0,
-  0, 0, 0, 4, 0, 42, 63, 0, 1, 0,
-  44, 5, 9, 0, 0, 3, 0, 23, 0, 0,
-  26, 7, 0, 0, 0, 3, 4, 30, 12, 34,
-  0, 8, 0, 0, 40, 0, 0, 0, 68, 13,
-  0, 0, 40, 12, 0, 29, 32, 0, 0, 30,
-  0, 0, 0, 46, 0, 0, 0, 0, 5, 0,
-  0, 0, 0, 29, 58, 4, 0, 15, 30, 0,
-  26, 17, 54, 0, 15, 0, 9, 0, 76, 5,
-  0, 0, 10, 0, 77, 0, 9, 10, 0, 0,
-  4, 0, 0, 8, 3, 82, 0, 0, 0, 46,
-  42, 0, 45, 68, 136, 0, 0, 0, 0, 0,
-  0, 0, 3, 0, 0, 0, 0, 9, 0, 0,
-  0, 0, 33, 0, 0, 90, 40, 14, 0, 21,
-  0, 0, 0, 136, 0, 0, 74, 0, 41, 0,
-  36, 0, 0, 0, 35, 0, 125, 0, 0, 23,
-  0, 91, 0, 0, 13, 4, 0, 0, 7, 0,
-  0, 0, 15, 0, 23, 0, 45, 6, 0, 0,
-  20, 0, 0, 0, 0, 0, 24, 27, 0, 0,
-  0, 52, 15, 0, 0, 0, 14, 0, 0, 2,
-  0, 0, 69, 4, 0, 37, 12, 0, 118, 0,
-  23, 19, 24, 0, 0, 0, 53, 0, 0, 0,
-  0, 0, 59, 0, 5, 69, 0, 0, 0, 0,
-  0, 19, 45, 76, 0, 0, 0, 17, 2, 8,
-  10, 22, 0, 35, 0, 0, 0, 0, 0, 77,
-  41, 11, 0, 18, 0, 0, 0, 17, 0, 13,
-  0, 0, 0, 39, 0, 0, 0, 0, 0, 0,
-  0, 110, 0, 0, 0, 0, 15, 4, 28, 0,
-  0, 0, 0, 0, 48, 0, 0, 6, 0, 9,
-  0, 40, 17, 0, 0, 0, 0, 0, 53, 0,
-  0, 17, 0, 52, 45, 0, 40, 9, 68, 0,
-  0, 0, 56, 0, 0, 5, 0, 0, 0, 21,
-  0, 0, 0, 0, 1, 53, 0, 16, 7, 45,
-  50, 0, 0, 13, 38, 10, 68, 48, 19, 52,
-  56, 0, 0, 0, 26, 9, 0, 10, 0, 52,
-  52, 0, 44, 0, 21, 0, 7, 0, 0, 3,
-  68, 73, 3, 33, 10, 1, 18, 0, 44, 0,
-  0, 50, 14, 42, 0, 0, 0, 12, 60, 0,
-  0, 39, 0, 0, 0, 7, 0, 62, 39, 63,
-  0, 87, 51, 0, 0, 0, 0, 0, 0, 78,
-  42, 0, 0, 0, 18, 20, 19, 14, 11, 0,
-  3, 81, 0, 28, 0, 0, 0, 0, 0, 30,
-  0, 13, 8, 1, 0, 0, 0, 18, 37, 38,
-  21, 0, 88, 0, 16, 0, 65, 54, 0, 0,
-  46, 25, 0, 61, 0, 19, 5, 30, 0, 0,
-  0, 0, 0, 0, 0, 15, 38, 43, 88, 0,
-  0, 20, 22, 0, 0, 24, 58, 18, 39, 4,
-  45, 0, 79, 0, 1, 0, 0, 16, 100, 0,
-  22, 0, 0, 0, 0, 0, 0, 11, 22, 94,
-  0, 49, 0, 51, 31, 35, 50, 27, 110, 9,
-  0, 0, 0, 0, 0, 0, 32, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 94, 0, 0, 96,
-  51, 18, 0, 0, 0, 0, 0, 79, 0, 0,
-  15, 0, 24, 0, 24, 0, 7, 8, 19, 6,
-  56, 0, 0, 10, 0, 51, 0, 0, 21, 34,
-  0, 0, 0, 16, 0, 0, 24, 0, 36, 0,
-  41, 12, 2, 0, 43, 21, 0, 36, 0, 0,
-  5, 39, 0, 0, 0, 27, 23, 0, 0, 0,
-  0, 0, 0, 11, 0, 6, 79, 9, 0, 5,
-  40, 0, 52, 15, 28, 31, 21, 0, 0, 0,
-  55, 12, 0, 0, 0, 49, 11, 0, 44, 0,
-  25, 0, 19, 0, 0, 0, 81, 51, 5, 17,
-  15, 0, 0, 0, 3, 0, 0, 60, 21, 63,
-  0, 0, 0, 12, 63, 0, 0, 27, 12, 0,
-  0, 6, 0, 70, 0, 97, 10, 75, 53, 0,
-  0, 0, 0, 6, 0, 65, 94, 0, 0, 3,
-  21, 23, 4, 21, 0, 0, 0, 70, 0, 12,
-  8, 0, 0, 0, 0, 33, 0, 19, 20, 29,
-  0, 0, 0, 27, 44, 20, 19, 0, 78, 0,
-  29, 0, 66, 38, 0, 0, 42, 37, 0, 32,
-  0, 38, 3, 45, 0, 0, 0, 0, 0, 0,
-  3, 5, 71, 72, 88, 0, 0, 7, 31, 0,
-  0, 31, 64, 18, 57, 10, 85, 0, 91, 2,
-  0, 0, 0, 21, 76, 0, 26, 0, 1, 0,
-  0, 0, 0, 6, 28, 78, 0, 20, 4, 29,
-  21, 10, 35, 34, 113, 11, 0, 0, 0, 0,
-  0, 0, 18, 0, 0, 0, 0, 0, 0, 1,
-  0, 10, 66, 3, 0, 101, 57, 6, 0, 0,
-  0, 0, 0, 90, 1, 0, 17, 0, 40, 0,
-  25, 0, 0, 10, 7, 19, 34, 0, 0, 18,
-  0, 29, 0, 0, 0, 43, 3, 0, 0, 28,
-  0, 0, 37, 0, 22, 0, 65, 9, 0, 0,
-  20, 0, 0, 16, 13, 0, 0, 46, 0, 0,
-  0, 39, 0, 0, 0, 0, 1, 0, 0, 4,
-  0, 7, 72, 14, 0, 12, 20, 0, 52, 13,
-  51, 13, 13, 0, 0, 0, 64, 0, 0, 0,
-  4, 0, 79, 3, 6, 0, 0, 0, 14, 0,
-  0, 8, 0, 94, 0, 3, 0, 47, 45, 17,
-  53, 54, 102, 0, 0, 0, 0, 16, 0, 0,
-  0, 0, 0, 0, 0, 14, 0, 0, 0, 0,
-  37, 0, 0, 85, 38, 32, 0, 6, 0, 0,
-  0, 126, 0, 0, 66, 0, 24, 0, 20, 0,
-  0, 0, 29, 0, 99, 0, 0, 10, 0, 92,
-  0, 0, 18, 0, 0, 0, 4, 0, 0, 0,
-  11, 0, 20, 0, 18, 0, 0, 0, 39, 0,
-  0, 7, 0, 0, 22, 29, 2, 0, 4, 32,
-  23, 0, 0, 0, 28, 0, 0, 3, 17, 0,
-  84, 3, 0, 15, 21, 0, 112, 0, 10, 16,
-  55, 0, 0, 0, 57, 15, 0, 0, 0, 34,
-  49, 0, 25, 0, 17, 0, 0, 0, 0, 0,
-  29, 51, 2, 46, 15, 40, 0, 20, 33, 0,
-  79, 40, 0, 20, 0, 0, 0, 0, 25, 0,
-  0, 0, 0, 0, 0, 5, 0, 35, 63, 42,
-  0, 75, 56, 0, 0, 0, 0, 4, 0, 42,
-  63, 0, 1, 0, 44, 5, 9, 0, 0, 3,
-  0, 23, 0, 0, 26, 7, 0, 0, 0, 3,
-  4, 30, 12, 34, 0, 8, 0, 0, 40, 0,
-  0, 0, 68, 13, 0, 0, 40, 12, 0, 29,
-  32, 0, 0, 30, 0, 0, 0, 46, 0, 0,
-  0, 0, 5, 0, 0, 0, 0, 29, 58, 4,
-  0, 15, 30, 0, 26, 17, 54, 0, 15, 0,
-  9, 0, 76, 5, 0, 0, 10, 0, 77, 0,
-  9, 10, 0, 0, 4, 0, 0, 8, 3, 82,
-  0, 0, 0, 46, 42, 0, 45, 68, 136, 0,
-  0, 0, 0, 0, 0, 0, 3, 0, 0, 0,
-  0, 9, 0, 0, 0, 0, 33, 0, 0, 90,
-  40, 14, 0, 21, 0, 0, 0, 136, 0, 0,
-  74, 0, 41, 0, 36, 0, 0, 0, 35, 0,
-  125, 0, 0, 23, 0, 91, 0, 0, 13, 4,
-  0, 0, 7, 0, 0, 0, 15, 0, 23, 0,
-  45, 6, 0, 0, 20, 0, 0, 0, 0, 0,
-  24, 27, 0, 0, 0, 52, 15, 0, 0, 0,
-  14, 0, 0, 2, 0, 0, 69, 4, 0, 37,
-  12, 0, 118, 0, 23, 19, 24, 0, 0, 0,
-  53, 0, 0, 0, 0, 0, 45, 1, 17, 0,
-  0, 0, 31, 0, 0, 0, 20, 82, 0, 0,
-  0, 11, 29, 0, 23, 30, 25, 5, 0, 0,
-  20, 43, 0, 53, 0, 0, 0, 0, 0, 0,
-  0, 4, 0, 0, 0, 0, 0, 45, 6, 26,
-  0, 49, 0, 0, 0, 152, 0, 16, 45, 0,
-  12, 0, 0, 0, 0, 0, 8, 0, 63, 0,
-  0, 6, 0, 72, 0, 0, 8, 0, 0, 0,
-  0, 0, 0, 0, 13, 0, 1, 0, 0, 0,
-  0, 44, 53, 0, 44, 0, 0, 0, 18, 0,
-  36, 0, 0, 72, 23, 0, 15, 0, 42, 0,
-  1, 20, 65, 0, 81, 0, 0, 14, 40, 0,
-  141, 0, 0, 33, 89, 0, 30, 0, 58, 0,
-  0, 0, 0, 52, 52, 0, 44, 0, 21, 0,
-  7, 0, 0, 3, 68, 73, 3, 33, 10, 1,
-  18, 0, 44, 0, 0, 50, 14, 42, 0, 0,
-  0, 12, 60, 0, 0, 39, 0, 0, 0, 7,
-  0, 62, 39, 63, 0, 87, 51, 0, 0, 0,
-  0, 0, 0, 78, 42, 0, 0, 0, 18, 20,
-  19, 14, 11, 0, 3, 81, 0, 28, 0, 0,
-  0, 0, 0, 30, 0, 13, 8, 1, 0, 0,
-  0, 18, 37, 38, 21, 0, 88, 0, 16, 0,
-  65, 54, 0, 0, 46, 25, 0, 61, 0, 19,
-  5, 30, 0, 0, 0, 0, 0, 0, 0, 15,
-  38, 43, 88, 0, 0, 20, 22, 0, 0, 24,
-  58, 18, 39, 4, 45, 0, 79, 0, 1, 0,
-  0, 16, 100, 0, 22, 0, 0, 0, 0, 0,
-  0, 11, 22, 94, 0, 49, 0, 51, 31, 35,
-  50, 27, 110, 9, 0, 0, 0, 0, 0, 0,
-  32, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  94, 0, 0, 96, 51, 18, 0, 0, 0, 0,
-  0, 79, 0, 0, 15, 0, 24, 0, 24, 0,
-  7, 8, 19, 6, 56, 0, 0, 10, 0, 51,
-  0, 0, 21, 34, 0, 0, 0, 16, 0, 0,
-  24, 0, 36, 0, 41, 12, 2, 0, 43, 21,
-  0, 36, 0, 0, 5, 39, 0, 0, 0, 27,
-  23, 0, 0, 0, 0, 0, 0, 11, 0, 6,
-  79, 9, 0, 5, 40, 0, 52, 15, 28, 31,
-  21, 0, 0, 0, 55, 12, 0, 0, 20, 0,
-  91, 19, 0, 0, 0, 12, 20, 0, 0, 0,
-  0, 125, 0, 0, 0, 22, 28, 1, 36, 70,
-  81, 11, 0, 0, 7, 35, 205, 0, 23, 21,
-  0, 15, 0, 0, 0, 31, 0, 0, 65, 0,
-  0, 38, 53, 70, 0, 0, 0, 0, 0, 120,
-  0, 6, 74, 0, 21, 12, 39, 0, 24, 17,
-  49, 0, 50, 0, 10, 0, 0, 102, 0, 0,
-  27, 14, 0, 0, 25, 0, 0, 0, 12, 2,
-  2, 20, 0, 0, 0, 33, 96, 33, 0, 2,
-  0, 0, 53, 20, 39, 0, 2, 26, 35, 12,
-  15, 0, 81, 19, 3, 30, 19, 0, 74, 0,
-  14, 0, 19, 31, 105, 0, 0, 54, 0, 0,
-  0, 0, 40, 22, 0, 17, 0, 21, 76, 0,
-  26, 0, 1, 0, 0, 0, 0, 6, 28, 78,
-  0, 20, 4, 29, 21, 10, 35, 34, 113, 11,
-  0, 0, 0, 0, 0, 0, 18, 0, 0, 0,
-  0, 0, 0, 1, 0, 10, 66, 3, 0, 101,
-  57, 6, 0, 0, 0, 0, 0, 90, 1, 0,
-  17, 0, 40, 0, 25, 0, 0, 10, 7, 19,
-  34, 0, 0, 18, 0, 29, 0, 0, 0, 43,
-  3, 0, 0, 28, 0, 0, 37, 0, 22, 0,
-  65, 9, 0, 0, 20, 0, 0, 16, 13, 0,
-  0, 46, 0, 0, 0, 39, 0, 0, 0, 0,
-  1, 0, 0, 4, 0, 7, 72, 14, 0, 12,
-  20, 0, 52, 13, 51, 13, 13, 0, 0, 0,
-  64, 0, 0, 0, 4, 0, 79, 3, 6, 0,
-  0, 0, 14, 0, 0, 8, 0, 94, 0, 3,
-  0, 47, 45, 17, 53, 54, 102, 0, 0, 0,
-  0, 16, 0, 0, 0, 0, 0, 0, 0, 14,
-  0, 0, 0, 0, 37, 0, 0, 85, 38, 32,
-  0, 6, 0, 0, 0, 126, 0, 0, 66, 0,
-  24, 0, 20, 0, 0, 0, 29, 0, 99, 0,
-  0, 10, 0, 92, 0, 0, 18, 0, 0, 0,
-  4, 0, 0, 0, 11, 0, 20, 0, 18, 0,
-  0, 0, 39, 0, 0, 7, 0, 0, 22, 29,
-  2, 0, 4, 32, 23, 0, 0, 0, 28, 0,
-  0, 3, 17, 0, 84, 3, 0, 15, 21, 0,
-  112, 0, 10, 16, 55, 0, 0, 0, 57, 15,
-  0, 0, 2, 0, 42, 31, 0, 0, 14, 24,
-  59, 0, 4, 0, 0, 82, 0, 0, 0, 8,
-  26, 0, 35, 19, 23, 27, 0, 0, 38, 57,
-  187, 16, 19, 10, 32, 0, 0, 0, 0, 25,
-  0, 0, 0, 0, 0, 32, 38, 93, 0, 17,
-  0, 0, 3, 110, 0, 32, 59, 0, 9, 0,
-  14, 0, 0, 22, 8, 0, 4, 0, 20, 0,
-  0, 39, 0, 6, 29, 4, 0, 9, 34, 0,
-  0, 0, 24, 0, 1, 24, 0, 0, 0, 30,
-  103, 45, 40, 0, 0, 0, 18, 12, 59, 0,
-  26, 51, 26, 6, 18, 0, 84, 0, 42, 12,
-  87, 0, 79, 0, 10, 0, 1, 0, 115, 0,
-  0, 34, 41, 0, 5, 0, 59, 9, 0, 24,
-  10, 0, 77, 0, 9, 10, 0, 0, 4, 0,
-  0, 8, 3, 82, 0, 0, 0, 46, 42, 0,
-  45, 68, 136, 0, 0, 0, 0, 0, 0, 0,
-  3, 0, 0, 0, 0, 9, 0, 0, 0, 0,
-  33, 0, 0, 90, 40, 14, 0, 21, 0, 0,
-  0, 136, 0, 0, 74, 0, 41, 0, 36, 0,
-  0, 0, 35, 0, 125, 0, 0, 23, 0, 91,
-  0, 0, 13, 4, 0, 0, 7, 0, 0, 0,
-  15, 0, 23, 0, 45, 6, 0, 0, 20, 0,
-  0, 0, 0, 0, 24, 27, 0, 0, 0, 52,
-  15, 0, 0, 0, 14, 0, 0, 2, 0, 0,
-  69, 4, 0, 37, 12, 0, 118, 0, 23, 19,
-  24, 0, 0, 0, 53, 0, 0, 0, 0, 0,
-  45, 1, 17, 0, 0, 0, 31, 0, 0, 0,
-  20, 82, 0, 0, 0, 11, 29, 0, 23, 30,
-  25, 5, 0, 0, 20, 43, 0, 53, 0, 0,
-  0, 0, 0, 0, 0, 4, 0, 0, 0, 0,
-  0, 45, 6, 26, 0, 49, 0, 0, 0, 152,
-  0, 16, 45, 0, 12, 0, 0, 0, 0, 0,
-  8, 0, 63, 0, 0, 6, 0, 72, 0, 0,
-  8, 0, 0, 0, 0, 0, 0, 0, 13, 0,
-  1, 0, 0, 0, 0, 44, 53, 0, 44, 0,
-  0, 0, 18, 0, 36, 0, 0, 72, 23, 0,
-  15, 0, 42, 0, 1, 20, 65, 0, 81, 0,
-  0, 14, 40, 0, 141, 0, 0, 33, 89, 0,
-  30, 0, 58, 0, 0, 0, 0, 0, 24, 23,
-  0, 0, 18, 24, 50, 29, 0, 0, 0, 30,
-  0, 5, 4, 7, 13, 0, 0, 0, 0, 53,
-  0, 0, 74, 59, 173, 47, 0, 0, 71, 0,
-  19, 0, 0, 20, 0, 24, 0, 0, 0, 0,
-  18, 88, 16, 0, 0, 16, 0, 67, 30, 34,
-  32, 0, 0, 4, 0, 6, 0, 39, 0, 0,
-  0, 0, 33, 0, 0, 14, 6, 12, 56, 3,
-  0, 51, 0, 0, 0, 3, 39, 0, 0, 33,
-  0, 0, 0, 48, 80, 41, 84, 0, 0, 0,
-  23, 0, 51, 0, 2, 59, 14, 2, 58, 0,
-  66, 2, 56, 3, 77, 5, 38, 0, 11, 0,
-  0, 0, 103, 0, 0, 17, 53, 0, 50, 0,
-  60, 0, 7, 11, 0, 16, 100, 0, 22, 0,
-  0, 0, 0, 0, 0, 11, 22, 94, 0, 49,
-  0, 51, 31, 35, 50, 27, 110, 9, 0, 0,
-  0, 0, 0, 0, 32, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 94, 0, 0, 96, 51, 18,
-  0, 0, 0, 0, 0, 79, 0, 0, 15, 0,
-  24, 0, 24, 0, 7, 8, 19, 6, 56, 0,
-  0, 10, 0, 51, 0, 0, 21, 34, 0, 0,
-  0, 16, 0, 0, 24, 0, 36, 0, 41, 12,
-  2, 0, 43, 21, 0, 36, 0, 0, 5, 39,
-  0, 0, 0, 27, 23, 0, 0, 0, 0, 0,
-  0, 11, 0, 6, 79, 9, 0, 5, 40, 0,
-  52, 15, 28, 31, 21, 0, 0, 0, 55, 12,
-  0, 0, 20, 0, 91, 19, 0, 0, 0, 12,
-  20, 0, 0, 0, 0, 125, 0, 0, 0, 22,
-  28, 1, 36, 70, 81, 11, 0, 0, 7, 35,
-  205, 0, 23, 21, 0, 15, 0, 0, 0, 31,
-  0, 0, 65, 0, 0, 38, 53, 70, 0, 0,
-  0, 0, 0, 120, 0, 6, 74, 0, 21, 12,
-  39, 0, 24, 17, 49, 0, 50, 0, 10, 0,
-  0, 102, 0, 0, 27, 14, 0, 0, 25, 0,
-  0, 0, 12, 2, 2, 20, 0, 0, 0, 33,
-  96, 33, 0, 2, 0, 0, 53, 20, 39, 0,
-  2, 26, 35, 12, 15, 0, 81, 19, 3, 30,
-  19, 0, 74, 0, 14, 0, 19, 31, 105, 0,
-  0, 54, 0, 0, 0, 0, 40, 22, 0, 17,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 4, 0,
-  79, 3, 6, 0, 0, 0, 14, 0, 0, 8,
-  0, 94, 0, 3, 0, 47, 45, 17, 53, 54,
-  102, 0, 0, 0, 0, 16, 0, 0, 0, 0,
-  0, 0, 0, 14, 0, 0, 0, 0, 37, 0,
-  0, 85, 38, 32, 0, 6, 0, 0, 0, 126,
-  0, 0, 66, 0, 24, 0, 20, 0, 0, 0,
-  29, 0, 99, 0, 0, 10, 0, 92, 0, 0,
-  18, 0, 0, 0, 4, 0, 0, 0, 11, 0,
-  20, 0, 18, 0, 0, 0, 39, 0, 0, 7,
-  0, 0, 22, 29, 2, 0, 4, 32, 23, 0,
-  0, 0, 28, 0, 0, 3, 17, 0, 84, 3,
-  0, 15, 21, 0, 112, 0, 10, 16, 55, 0,
-  0, 0, 57, 15, 0, 0, 2, 0, 42, 31,
-  0, 0, 14, 24, 59, 0, 4, 0, 0, 82,
-  0, 0, 0, 8, 26, 0, 35, 19, 23, 27,
-  0, 0, 38, 57, 187, 16, 19, 10, 32, 0,
-  0, 0, 0, 25, 0, 0, 0, 0, 0, 32,
-  38, 93, 0, 17, 0, 0, 3, 110, 0, 32,
-  59, 0, 9, 0, 14, 0, 0, 22, 8, 0,
-  4, 0, 20, 0, 0, 39, 0, 6, 29, 4,
-  0, 9, 34, 0, 0, 0, 24, 0, 1, 24,
-  0, 0, 0, 30, 103, 45, 40, 0, 0, 0,
-  18, 12, 59, 0, 26, 51, 26, 6, 18, 0,
-  84, 0, 42, 12, 87, 0, 79, 0, 10, 0,
-  1, 0, 115, 0, 0, 34, 41, 0, 5, 0,
-  59, 9, 0, 24, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 45, 1, 17, 0, 0, 0,
-  31, 0, 0, 0, 20, 82, 0, 0, 0, 11,
-  29, 0, 23, 30, 25, 5, 0, 0, 20, 43,
-  0, 53, 0, 0, 0, 0, 0, 0, 0, 4,
-  0, 0, 0, 0, 0, 45, 6, 26, 0, 49,
-  0, 0, 0, 152, 0, 16, 45, 0, 12, 0,
-  0, 0, 0, 0, 8, 0, 63, 0, 0, 6,
-  0, 72, 0, 0, 8, 0, 0, 0, 0, 0,
-  0, 0, 13, 0, 1, 0, 0, 0, 0, 44,
-  53, 0, 44, 0, 0, 0, 18, 0, 36, 0,
-  0, 72, 23, 0, 15, 0, 42, 0, 1, 20,
-  65, 0, 81, 0, 0, 14, 40, 0, 141, 0,
-  0, 33, 89, 0, 30, 0, 58, 0, 0, 0,
-  0, 0, 24, 23, 0, 0, 18, 24, 50, 29,
-  0, 0, 0, 30, 0, 5, 4, 7, 13, 0,
-  0, 0, 0, 53, 0, 0, 74, 59, 173, 47,
-  0, 0, 71, 0, 19, 0, 0, 20, 0, 24,
-  0, 0, 0, 0, 18, 88, 16, 0, 0, 16,
-  0, 67, 30, 34, 32, 0, 0, 4, 0, 6,
-  0, 39, 0, 0, 0, 0, 33, 0, 0, 14,
-  6, 12, 56, 3, 0, 51, 0, 0, 0, 3,
-  39, 0, 0, 33, 0, 0, 0, 48, 80, 41,
-  84, 0, 0, 0, 23, 0, 51, 0, 2, 59,
-  14, 2, 58, 0, 66, 2, 56, 3, 77, 5,
-  38, 0, 11, 0, 0, 0, 103, 0, 0, 17,
-  53, 0, 50, 0, 60, 0, 7, 11, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 30, 25, 0, 1, 3,
-  33, 18, 0, 0, 0, 0, 0, 38, 0, 18,
-  43, 15, 0, 40, 38, 17, 58, 51, 0, 9,
-  8, 5, 128, 38, 0, 0, 54, 0, 69, 16,
-  0, 30, 0, 38, 21, 38, 0, 22, 60, 37,
-  2, 0, 0, 0, 0, 13, 47, 0, 16, 0,
-  64, 0, 29, 0, 6, 33, 7, 0, 0, 0,
-  7, 19, 25, 0, 0, 36, 79, 26, 45, 46,
-  0, 7, 30, 1, 38, 2, 13, 0, 0, 0,
-  0, 0, 54, 6, 3, 0, 38, 1, 15, 56,
-  0, 0, 37, 35, 9, 0, 0, 19, 20, 19,
-  57, 1, 0, 26, 0, 8, 0, 33, 5, 0,
-  23, 13, 0, 22, 19, 0, 0, 0, 19, 0,
-  11, 9, 0, 48, 13, 14, 0, 0, 29, 34,
-  3, 0, 0, 37, 105, 0, 2, 11, 53, 15,
-  0, 14, 67, 51, 53, 17, 9, 0, 0, 9,
-  0, 0, 0, 0, 96, 0, 32, 9, 0, 24,
-  0, 75, 0, 32, 0, 38, 68, 64, 0, 61,
-  0, 41, 0, 28, 43, 1, 16, 0, 14, 0,
-  11, 0, 0, 0, 0, 18, 0, 0, 0, 0,
-  17, 0, 10, 2, 29, 20, 37, 0, 16, 39,
-  0, 22, 45, 0, 41, 0, 0, 0, 0, 0,
-  0, 7, 0, 0, 0, 7, 0, 48, 0, 0,
-  52, 46, 8, 0, 0, 12, 18, 0, 59, 0,
-  0, 16, 0, 17, 0, 17, 0, 0, 14, 0,
-  6, 8, 40, 0, 40, 0, 76, 0, 11, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 62,
-  32, 0, 2, 1, 44, 3, 0, 0, 16, 4,
-  12, 0, 5, 53, 33, 30, 0, 74, 61, 0,
-  71, 46, 0, 36, 0, 3, 111, 34, 1, 0,
-  57, 0, 53, 22, 0, 16, 0, 48, 40, 30,
-  5, 36, 99, 16, 0, 12, 0, 8, 1, 0,
-  56, 0, 0, 0, 43, 0, 7, 33, 9, 0,
-  16, 0, 0, 0, 18, 21, 0, 0, 8, 32,
-  42, 43, 43, 31, 0, 15, 0, 0, 70, 13,
-  10, 0, 12, 12, 0, 0, 50, 9, 2, 0,
-  16, 0, 5, 73, 0, 0, 8, 21, 2, 0,
-  0, 16, 17, 0, 77, 9, 0, 22, 29, 1,
-  0, 33, 0, 0, 0, 15, 0, 33, 26, 0,
-  0, 0, 28, 0, 14, 0, 5, 45, 49, 8,
-  0, 13, 12, 23, 0, 0, 0, 49, 90, 0,
-  0, 29, 44, 13, 0, 25, 68, 58, 82, 13,
-  0, 0, 0, 11, 0, 0, 0, 0, 81, 0,
-  34, 31, 0, 20, 0, 59, 2, 29, 0, 28,
-  67, 52, 0, 60, 0, 43, 0, 42, 24, 0,
-  22, 0, 17, 0, 7, 0, 0, 0, 0, 9,
-  8, 0, 0, 0, 16, 0, 14, 13, 19, 19,
-  30, 0, 40, 53, 0, 19, 43, 0, 42, 0,
-  0, 11, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 33, 18, 0, 37, 45, 21, 0, 0, 23,
-  29, 0, 60, 0, 0, 7, 11, 13, 0, 17,
-  0, 0, 0, 0, 1, 9, 37, 0, 7, 0,
-  52, 0, 8, 2, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 74, 43, 0, 0, 0, 41, 0,
-  0, 0, 0, 15, 3, 0, 14, 72, 38, 47,
-  0, 64, 66, 0, 81, 51, 0, 26, 10, 14,
-  118, 35, 2, 0, 62, 0, 42, 8, 0, 26,
-  7, 52, 32, 25, 0, 26, 85, 30, 0, 8,
-  0, 25, 0, 13, 61, 0, 0, 0, 25, 0,
-  4, 20, 16, 0, 7, 0, 0, 0, 21, 2,
-  0, 0, 14, 32, 32, 38, 42, 30, 5, 5,
-  0, 0, 76, 3, 4, 0, 0, 15, 0, 0,
-  64, 23, 0, 0, 7, 0, 8, 49, 0, 0,
-  22, 10, 3, 0, 1, 17, 39, 0, 77, 0,
-  0, 43, 30, 0, 0, 41, 0, 0, 0, 3,
-  0, 15, 30, 0, 0, 0, 22, 0, 36, 0,
-  4, 47, 62, 10, 0, 19, 11, 10, 1, 0,
-  0, 51, 73, 0, 0, 33, 47, 24, 0, 20,
-  69, 64, 93, 12, 0, 0, 0, 23, 0, 0,
-  0, 0, 74, 0, 23, 28, 0, 28, 0, 48,
-  1, 24, 0, 19, 53, 57, 0, 57, 0, 37,
-  0, 54, 25, 0, 42, 0, 29, 0, 2, 0,
-  1, 0, 0, 20, 15, 0, 0, 0, 26, 0,
-  13, 15, 11, 22, 32, 0, 46, 51, 0, 12,
-  44, 0, 35, 0, 0, 8, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 24, 31, 0, 40, 41,
-  11, 0, 10, 24, 51, 0, 57, 0, 0, 3,
-  17, 15, 0, 12, 0, 0, 7, 0, 0, 7,
-  15, 4, 0, 0, 47, 0, 18, 0, 0, 30,
-  25, 0, 1, 3, 33, 18, 0, 0, 0, 0,
-  0, 38, 0, 18, 43, 15, 0, 40, 38, 17,
-  58, 51, 0, 9, 8, 5, 128, 38, 0, 0,
-  54, 0, 69, 16, 0, 30, 0, 38, 21, 38,
-  0, 22, 60, 37, 2, 0, 0, 0, 0, 13,
-  47, 0, 16, 0, 64, 0, 29, 0, 6, 33,
-  7, 0, 0, 0, 7, 19, 25, 0, 0, 36,
-  79, 26, 45, 46, 0, 7, 30, 1, 38, 2,
-  13, 0, 0, 0, 0, 0, 54, 6, 3, 0,
-  38, 1, 15, 56, 0, 0, 37, 35, 9, 0,
-  0, 19, 20, 19, 57, 1, 0, 26, 0, 8,
-  0, 33, 5, 0, 23, 13, 0, 22, 19, 0,
-  0, 0, 19, 0, 11, 9, 0, 48, 13, 14,
-  0, 0, 29, 34, 3, 0, 0, 37, 105, 0,
-  2, 11, 53, 15, 0, 14, 67, 51, 53, 17,
-  9, 0, 0, 9, 0, 0, 0, 0, 96, 0,
-  32, 9, 0, 24, 0, 75, 0, 32, 0, 38,
-  68, 64, 0, 61, 0, 41, 0, 28, 43, 1,
-  16, 0, 14, 0, 11, 0, 0, 0, 0, 18,
-  0, 0, 0, 0, 17, 0, 10, 2, 29, 20,
-  37, 0, 16, 39, 0, 22, 45, 0, 41, 0,
-  0, 0, 0, 0, 0, 7, 0, 0, 0, 7,
-  0, 48, 0, 0, 52, 46, 8, 0, 0, 12,
-  18, 0, 59, 0, 0, 16, 0, 17, 0, 17,
-  0, 0, 14, 0, 6, 8, 40, 0, 40, 0,
-  76, 0, 11, 0, 4, 29, 39, 21, 0, 5,
-  28, 2, 19, 0, 0, 34, 112, 0, 22, 39,
-  53, 0, 0, 0, 0, 83, 0, 10, 59, 0,
-  0, 23, 0, 0, 0, 41, 82, 0, 23, 0,
-  0, 23, 0, 78, 0, 55, 37, 22, 36, 48,
-  30, 16, 0, 54, 0, 60, 33, 24, 31, 0,
-  11, 0, 7, 0, 17, 0, 0, 63, 0, 10,
-  7, 0, 36, 0, 8, 20, 0, 4, 0, 0,
-  33, 43, 0, 29, 44, 0, 61, 29, 0, 0,
-  0, 0, 0, 31, 0, 0, 0, 4, 0, 29,
-  42, 0, 5, 76, 2, 0, 8, 14, 30, 0,
-  21, 0, 0, 0, 8, 15, 0, 0, 0, 0,
-  0, 0, 6, 2, 19, 0, 53, 0, 69, 0,
-  17, 0, 0, 62, 32, 0, 2, 1, 44, 3,
-  0, 0, 16, 4, 12, 0, 5, 53, 33, 30,
-  0, 74, 61, 0, 71, 46, 0, 36, 0, 3,
-  111, 34, 1, 0, 57, 0, 53, 22, 0, 16,
-  0, 48, 40, 30, 5, 36, 99, 16, 0, 12,
-  0, 8, 1, 0, 56, 0, 0, 0, 43, 0,
-  7, 33, 9, 0, 16, 0, 0, 0, 18, 21,
-  0, 0, 8, 32, 42, 43, 43, 31, 0, 15,
-  0, 0, 70, 13, 10, 0, 12, 12, 0, 0,
-  50, 9, 2, 0, 16, 0, 5, 73, 0, 0,
-  8, 21, 2, 0, 0, 16, 17, 0, 77, 9,
-  0, 22, 29, 1, 0, 33, 0, 0, 0, 15,
-  0, 33, 26, 0, 0, 0, 28, 0, 14, 0,
-  5, 45, 49, 8, 0, 13, 12, 23, 0, 0,
-  0, 49, 90, 0, 0, 29, 44, 13, 0, 25,
-  68, 58, 82, 13, 0, 0, 0, 11, 0, 0,
-  0, 0, 81, 0, 34, 31, 0, 20, 0, 59,
-  2, 29, 0, 28, 67, 52, 0, 60, 0, 43,
-  0, 42, 24, 0, 22, 0, 17, 0, 7, 0,
-  0, 0, 0, 9, 8, 0, 0, 0, 16, 0,
-  14, 13, 19, 19, 30, 0, 40, 53, 0, 19,
-  43, 0, 42, 0, 0, 11, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 33, 18, 0, 37, 45,
-  21, 0, 0, 23, 29, 0, 60, 0, 0, 7,
-  11, 13, 0, 17, 0, 0, 0, 0, 1, 9,
-  37, 0, 7, 0, 52, 0, 8, 2, 2, 29,
-  35, 14, 0, 2, 25, 15, 25, 0, 0, 41,
-  100, 0, 19, 33, 52, 0, 0, 0, 0, 93,
-  0, 8, 42, 0, 0, 23, 0, 0, 0, 43,
-  78, 0, 33, 0, 0, 18, 0, 68, 0, 56,
-  40, 13, 39, 47, 17, 12, 0, 48, 0, 63,
-  25, 25, 42, 0, 13, 0, 12, 0, 4, 7,
-  0, 68, 0, 15, 1, 0, 32, 0, 7, 15,
-  0, 11, 0, 0, 44, 48, 0, 33, 43, 0,
-  60, 25, 0, 0, 0, 0, 0, 17, 0, 0,
-  0, 3, 0, 32, 43, 0, 2, 82, 3, 0,
-  8, 22, 34, 0, 25, 0, 0, 0, 17, 10,
-  0, 0, 0, 0, 0, 0, 2, 15, 15, 5,
-  38, 0, 55, 0, 13, 0, 0, 74, 43, 0,
-  0, 0, 41, 0, 0, 0, 0, 15, 3, 0,
-  14, 72, 38, 47, 0, 64, 66, 0, 81, 51,
-  0, 26, 10, 14, 118, 35, 2, 0, 62, 0,
-  42, 8, 0, 26, 7, 52, 32, 25, 0, 26,
-  85, 30, 0, 8, 0, 25, 0, 13, 61, 0,
-  0, 0, 25, 0, 4, 20, 16, 0, 7, 0,
-  0, 0, 21, 2, 0, 0, 14, 32, 32, 38,
-  42, 30, 5, 5, 0, 0, 76, 3, 4, 0,
-  0, 15, 0, 0, 64, 23, 0, 0, 7, 0,
-  8, 49, 0, 0, 22, 10, 3, 0, 1, 17,
-  39, 0, 77, 0, 0, 43, 30, 0, 0, 41,
-  0, 0, 0, 3, 0, 15, 30, 0, 0, 0,
-  22, 0, 36, 0, 4, 47, 62, 10, 0, 19,
-  11, 10, 1, 0, 0, 51, 73, 0, 0, 33,
-  47, 24, 0, 20, 69, 64, 93, 12, 0, 0,
-  0, 23, 0, 0, 0, 0, 74, 0, 23, 28,
-  0, 28, 0, 48, 1, 24, 0, 19, 53, 57,
-  0, 57, 0, 37, 0, 54, 25, 0, 42, 0,
-  29, 0, 2, 0, 1, 0, 0, 20, 15, 0,
-  0, 0, 26, 0, 13, 15, 11, 22, 32, 0,
-  46, 51, 0, 12, 44, 0, 35, 0, 0, 8,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 24,
-  31, 0, 40, 41, 11, 0, 10, 24, 51, 0,
-  57, 0, 0, 3, 17, 15, 0, 12, 0, 0,
-  7, 0, 0, 7, 15, 4, 0, 0, 47, 0,
-  18, 0, 3, 30, 27, 20, 0, 12, 23, 23,
-  27, 0, 0, 40, 83, 0, 11, 31, 57, 0,
-  0, 0, 0, 92, 0, 1, 37, 0, 0, 25,
-  0, 0, 0, 50, 77, 0, 34, 0, 0, 19,
-  0, 54, 0, 46, 24, 10, 34, 52, 12, 15,
-  0, 33, 0, 55, 12, 26, 53, 0, 30, 0,
-  10, 0, 0, 13, 0, 58, 0, 13, 0, 0,
-  32, 0, 13, 16, 12, 11, 0, 0, 49, 39,
-  0, 32, 30, 0, 50, 41, 0, 0, 7, 0,
-  0, 13, 0, 0, 0, 16, 0, 30, 52, 0,
-  6, 80, 2, 0, 18, 20, 43, 0, 29, 0,
-  4, 0, 21, 11, 0, 0, 0, 0, 0, 0,
-  0, 11, 4, 11, 36, 0, 51, 0, 18, 0,
-  0, 48, 13, 14, 0, 0, 29, 34, 3, 0,
-  0, 37, 105, 0, 2, 11, 53, 15, 0, 14,
-  67, 51, 53, 17, 9, 0, 0, 9, 0, 0,
-  0, 0, 96, 0, 32, 9, 0, 24, 0, 75,
-  0, 32, 0, 38, 68, 64, 0, 61, 0, 41,
-  0, 28, 43, 1, 16, 0, 14, 0, 11, 0,
-  0, 0, 0, 18, 0, 0, 0, 0, 17, 0,
-  10, 2, 29, 20, 37, 0, 16, 39, 0, 22,
-  45, 0, 41, 0, 0, 0, 0, 0, 0, 7,
-  0, 0, 0, 7, 0, 48, 0, 0, 52, 46,
-  8, 0, 0, 12, 18, 0, 59, 0, 0, 16,
-  0, 17, 0, 17, 0, 0, 14, 0, 6, 8,
-  40, 0, 40, 0, 76, 0, 11, 0, 4, 29,
-  39, 21, 0, 5, 28, 2, 19, 0, 0, 34,
-  112, 0, 22, 39, 53, 0, 0, 0, 0, 83,
-  0, 10, 59, 0, 0, 23, 0, 0, 0, 41,
-  82, 0, 23, 0, 0, 23, 0, 78, 0, 55,
-  37, 22, 36, 48, 30, 16, 0, 54, 0, 60,
-  33, 24, 31, 0, 11, 0, 7, 0, 17, 0,
-  0, 63, 0, 10, 7, 0, 36, 0, 8, 20,
-  0, 4, 0, 0, 33, 43, 0, 29, 44, 0,
-  61, 29, 0, 0, 0, 0, 0, 31, 0, 0,
-  0, 4, 0, 29, 42, 0, 5, 76, 2, 0,
-  8, 14, 30, 0, 21, 0, 0, 0, 8, 15,
-  0, 0, 0, 0, 0, 0, 6, 2, 19, 0,
-  53, 0, 69, 0, 17, 0, 0, 0, 0, 10,
-  0, 139, 4, 0, 12, 0, 0, 18, 33, 0,
-  0, 25, 0, 0, 0, 0, 30, 95, 19, 11,
-  3, 0, 0, 0, 0, 0, 0, 27, 29, 38,
-  0, 0, 0, 23, 0, 54, 0, 22, 0, 53,
-  1, 90, 35, 56, 0, 0, 0, 51, 6, 0,
-  10, 0, 55, 0, 49, 0, 11, 61, 0, 0,
-  76, 3, 0, 3, 55, 0, 82, 11, 11, 0,
-  0, 21, 26, 25, 0, 32, 34, 0, 41, 44,
-  0, 0, 22, 0, 0, 7, 0, 21, 4, 0,
-  4, 31, 0, 0, 7, 66, 36, 0, 0, 23,
-  27, 0, 16, 0, 0, 0, 0, 0, 0, 35,
-  0, 0, 100, 2, 34, 1, 0, 0, 0, 0,
-  28, 0, 0, 0, 5, 45, 49, 8, 0, 13,
-  12, 23, 0, 0, 0, 49, 90, 0, 0, 29,
-  44, 13, 0, 25, 68, 58, 82, 13, 0, 0,
-  0, 11, 0, 0, 0, 0, 81, 0, 34, 31,
-  0, 20, 0, 59, 2, 29, 0, 28, 67, 52,
-  0, 60, 0, 43, 0, 42, 24, 0, 22, 0,
-  17, 0, 7, 0, 0, 0, 0, 9, 8, 0,
-  0, 0, 16, 0, 14, 13, 19, 19, 30, 0,
-  40, 53, 0, 19, 43, 0, 42, 0, 0, 11,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 33,
-  18, 0, 37, 45, 21, 0, 0, 23, 29, 0,
-  60, 0, 0, 7, 11, 13, 0, 17, 0, 0,
-  0, 0, 1, 9, 37, 0, 7, 0, 52, 0,
-  8, 2, 2, 29, 35, 14, 0, 2, 25, 15,
-  25, 0, 0, 41, 100, 0, 19, 33, 52, 0,
-  0, 0, 0, 93, 0, 8, 42, 0, 0, 23,
-  0, 0, 0, 43, 78, 0, 33, 0, 0, 18,
-  0, 68, 0, 56, 40, 13, 39, 47, 17, 12,
-  0, 48, 0, 63, 25, 25, 42, 0, 13, 0,
-  12, 0, 4, 7, 0, 68, 0, 15, 1, 0,
-  32, 0, 7, 15, 0, 11, 0, 0, 44, 48,
-  0, 33, 43, 0, 60, 25, 0, 0, 0, 0,
-  0, 17, 0, 0, 0, 3, 0, 32, 43, 0,
-  2, 82, 3, 0, 8, 22, 34, 0, 25, 0,
-  0, 0, 17, 10, 0, 0, 0, 0, 0, 0,
-  2, 15, 15, 5, 38, 0, 55, 0, 13, 0,
-  0, 0, 0, 2, 0, 130, 10, 0, 4, 0,
-  0, 17, 27, 0, 0, 13, 0, 0, 0, 0,
-  39, 101, 22, 12, 0, 0, 0, 0, 0, 3,
-  0, 24, 35, 28, 1, 0, 0, 22, 0, 43,
-  0, 20, 0, 45, 17, 92, 24, 56, 0, 1,
-  0, 50, 0, 0, 17, 0, 51, 0, 51, 0,
-  0, 57, 0, 0, 72, 8, 0, 8, 34, 0,
-  64, 5, 28, 6, 0, 15, 34, 35, 0, 21,
-  42, 0, 36, 58, 0, 0, 16, 0, 0, 0,
-  0, 14, 4, 0, 0, 35, 0, 0, 0, 63,
-  44, 0, 0, 33, 35, 0, 21, 0, 0, 0,
-  3, 0, 0, 32, 0, 0, 109, 11, 25, 17,
-  0, 0, 0, 0, 15, 0, 0, 0, 4, 47,
-  62, 10, 0, 19, 11, 10, 1, 0, 0, 51,
-  73, 0, 0, 33, 47, 24, 0, 20, 69, 64,
-  93, 12, 0, 0, 0, 23, 0, 0, 0, 0,
-  74, 0, 23, 28, 0, 28, 0, 48, 1, 24,
-  0, 19, 53, 57, 0, 57, 0, 37, 0, 54,
-  25, 0, 42, 0, 29, 0, 2, 0, 1, 0,
-  0, 20, 15, 0, 0, 0, 26, 0, 13, 15,
-  11, 22, 32, 0, 46, 51, 0, 12, 44, 0,
-  35, 0, 0, 8, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 24, 31, 0, 40, 41, 11, 0,
-  10, 24, 51, 0, 57, 0, 0, 3, 17, 15,
-  0, 12, 0, 0, 7, 0, 0, 7, 15, 4,
-  0, 0, 47, 0, 18, 0, 3, 30, 27, 20,
-  0, 12, 23, 23, 27, 0, 0, 40, 83, 0,
-  11, 31, 57, 0, 0, 0, 0, 92, 0, 1,
-  37, 0, 0, 25, 0, 0, 0, 50, 77, 0,
-  34, 0, 0, 19, 0, 54, 0, 46, 24, 10,
-  34, 52, 12, 15, 0, 33, 0, 55, 12, 26,
-  53, 0, 30, 0, 10, 0, 0, 13, 0, 58,
-  0, 13, 0, 0, 32, 0, 13, 16, 12, 11,
-  0, 0, 49, 39, 0, 32, 30, 0, 50, 41,
-  0, 0, 7, 0, 0, 13, 0, 0, 0, 16,
-  0, 30, 52, 0, 6, 80, 2, 0, 18, 20,
-  43, 0, 29, 0, 4, 0, 21, 11, 0, 0,
-  0, 0, 0, 0, 0, 11, 4, 11, 36, 0,
-  51, 0, 18, 0, 0, 0, 0, 5, 0, 140,
-  8, 5, 3, 0, 0, 23, 36, 0, 0, 10,
-  2, 0, 0, 0, 35, 102, 17, 9, 0, 0,
-  0, 0, 0, 21, 0, 23, 35, 21, 4, 1,
-  0, 25, 0, 41, 0, 16, 0, 48, 13, 84,
-  13, 57, 0, 3, 0, 61, 0, 0, 24, 0,
-  45, 0, 39, 0, 0, 51, 0, 0, 78, 3,
-  0, 20, 24, 0, 67, 6, 31, 2, 0, 19,
-  16, 27, 0, 18, 39, 0, 33, 59, 0, 0,
-  10, 0, 0, 0, 0, 8, 0, 0, 12, 34,
-  0, 0, 0, 66, 43, 0, 0, 31, 31, 0,
-  26, 0, 0, 0, 14, 0, 0, 24, 0, 0,
-  117, 2, 21, 20, 0, 0, 0, 0, 24, 0,
-  0, 0, 4, 29, 39, 21, 0, 5, 28, 2,
-  19, 0, 0, 34, 112, 0, 22, 39, 53, 0,
-  0, 0, 0, 83, 0, 10, 59, 0, 0, 23,
-  0, 0, 0, 41, 82, 0, 23, 0, 0, 23,
-  0, 78, 0, 55, 37, 22, 36, 48, 30, 16,
-  0, 54, 0, 60, 33, 24, 31, 0, 11, 0,
-  7, 0, 17, 0, 0, 63, 0, 10, 7, 0,
-  36, 0, 8, 20, 0, 4, 0, 0, 33, 43,
-  0, 29, 44, 0, 61, 29, 0, 0, 0, 0,
-  0, 31, 0, 0, 0, 4, 0, 29, 42, 0,
-  5, 76, 2, 0, 8, 14, 30, 0, 21, 0,
-  0, 0, 8, 15, 0, 0, 0, 0, 0, 0,
-  6, 2, 19, 0, 53, 0, 69, 0, 17, 0,
-  0, 0, 0, 10, 0, 139, 4, 0, 12, 0,
-  0, 18, 33, 0, 0, 25, 0, 0, 0, 0,
-  30, 95, 19, 11, 3, 0, 0, 0, 0, 0,
-  0, 27, 29, 38, 0, 0, 0, 23, 0, 54,
-  0, 22, 0, 53, 1, 90, 35, 56, 0, 0,
-  0, 51, 6, 0, 10, 0, 55, 0, 49, 0,
-  11, 61, 0, 0, 76, 3, 0, 3, 55, 0,
-  82, 11, 11, 0, 0, 21, 26, 25, 0, 32,
-  34, 0, 41, 44, 0, 0, 22, 0, 0, 7,
-  0, 21, 4, 0, 4, 31, 0, 0, 7, 66,
-  36, 0, 0, 23, 27, 0, 16, 0, 0, 0,
-  0, 0, 0, 35, 0, 0, 100, 2, 34, 1,
-  0, 0, 0, 0, 28, 0, 0, 0, 0, 0,
-  0, 0, 9, 38, 29, 0, 28, 0, 15, 0,
-  49, 21, 13, 59, 25, 11, 12, 5, 68, 0,
-  0, 42, 2, 24, 1, 0, 0, 35, 0, 0,
-  51, 61, 4, 0, 0, 0, 0, 42, 8, 38,
-  0, 45, 9, 26, 16, 31, 0, 20, 23, 0,
-  74, 24, 0, 0, 43, 0, 0, 56, 26, 7,
-  0, 0, 0, 0, 26, 8, 30, 0, 0, 7,
-  0, 8, 2, 45, 9, 0, 0, 52, 52, 14,
-  29, 21, 20, 0, 7, 19, 17, 28, 6, 32,
-  0, 6, 20, 41, 0, 0, 30, 59, 7, 0,
-  1, 0, 0, 0, 35, 0, 0, 25, 13, 0,
-  0, 13, 0, 0, 41, 20, 37, 0, 1, 0,
-  90, 0, 36, 0, 0, 0, 2, 29, 35, 14,
-  0, 2, 25, 15, 25, 0, 0, 41, 100, 0,
-  19, 33, 52, 0, 0, 0, 0, 93, 0, 8,
-  42, 0, 0, 23, 0, 0, 0, 43, 78, 0,
-  33, 0, 0, 18, 0, 68, 0, 56, 40, 13,
-  39, 47, 17, 12, 0, 48, 0, 63, 25, 25,
-  42, 0, 13, 0, 12, 0, 4, 7, 0, 68,
-  0, 15, 1, 0, 32, 0, 7, 15, 0, 11,
-  0, 0, 44, 48, 0, 33, 43, 0, 60, 25,
-  0, 0, 0, 0, 0, 17, 0, 0, 0, 3,
-  0, 32, 43, 0, 2, 82, 3, 0, 8, 22,
-  34, 0, 25, 0, 0, 0, 17, 10, 0, 0,
-  0, 0, 0, 0, 2, 15, 15, 5, 38, 0,
-  55, 0, 13, 0, 0, 0, 0, 2, 0, 130,
-  10, 0, 4, 0, 0, 17, 27, 0, 0, 13,
-  0, 0, 0, 0, 39, 101, 22, 12, 0, 0,
-  0, 0, 0, 3, 0, 24, 35, 28, 1, 0,
-  0, 22, 0, 43, 0, 20, 0, 45, 17, 92,
-  24, 56, 0, 1, 0, 50, 0, 0, 17, 0,
-  51, 0, 51, 0, 0, 57, 0, 0, 72, 8,
-  0, 8, 34, 0, 64, 5, 28, 6, 0, 15,
-  34, 35, 0, 21, 42, 0, 36, 58, 0, 0,
-  16, 0, 0, 0, 0, 14, 4, 0, 0, 35,
-  0, 0, 0, 63, 44, 0, 0, 33, 35, 0,
-  21, 0, 0, 0, 3, 0, 0, 32, 0, 0,
-  109, 11, 25, 17, 0, 0, 0, 0, 15, 0,
-  0, 0, 0, 0, 0, 0, 0, 30, 33, 0,
-  19, 0, 21, 0, 43, 0, 16, 54, 29, 19,
-  0, 10, 66, 0, 0, 44, 0, 21, 4, 0,
-  0, 41, 0, 0, 53, 56, 9, 0, 0, 0,
-  0, 18, 0, 34, 0, 47, 24, 21, 4, 29,
-  0, 18, 41, 0, 75, 14, 0, 0, 37, 0,
-  0, 75, 15, 0, 0, 0, 0, 0, 34, 16,
-  0, 0, 0, 2, 0, 21, 12, 35, 14, 9,
-  0, 42, 59, 0, 15, 48, 23, 0, 5, 24,
-  11, 27, 9, 21, 0, 6, 17, 45, 0, 0,
-  9, 43, 26, 0, 0, 0, 17, 0, 51, 8,
-  2, 21, 33, 2, 0, 20, 0, 0, 46, 39,
-  44, 11, 0, 0, 80, 0, 29, 15, 0, 0,
-  3, 30, 27, 20, 0, 12, 23, 23, 27, 0,
-  0, 40, 83, 0, 11, 31, 57, 0, 0, 0,
-  0, 92, 0, 1, 37, 0, 0, 25, 0, 0,
-  0, 50, 77, 0, 34, 0, 0, 19, 0, 54,
-  0, 46, 24, 10, 34, 52, 12, 15, 0, 33,
-  0, 55, 12, 26, 53, 0, 30, 0, 10, 0,
-  0, 13, 0, 58, 0, 13, 0, 0, 32, 0,
-  13, 16, 12, 11, 0, 0, 49, 39, 0, 32,
-  30, 0, 50, 41, 0, 0, 7, 0, 0, 13,
-  0, 0, 0, 16, 0, 30, 52, 0, 6, 80,
-  2, 0, 18, 20, 43, 0, 29, 0, 4, 0,
-  21, 11, 0, 0, 0, 0, 0, 0, 0, 11,
-  4, 11, 36, 0, 51, 0, 18, 0, 0, 0,
-  0, 5, 0, 140, 8, 5, 3, 0, 0, 23,
-  36, 0, 0, 10, 2, 0, 0, 0, 35, 102,
-  17, 9, 0, 0, 0, 0, 0, 21, 0, 23,
-  35, 21, 4, 1, 0, 25, 0, 41, 0, 16,
-  0, 48, 13, 84, 13, 57, 0, 3, 0, 61,
-  0, 0, 24, 0, 45, 0, 39, 0, 0, 51,
-  0, 0, 78, 3, 0, 20, 24, 0, 67, 6,
-  31, 2, 0, 19, 16, 27, 0, 18, 39, 0,
-  33, 59, 0, 0, 10, 0, 0, 0, 0, 8,
-  0, 0, 12, 34, 0, 0, 0, 66, 43, 0,
-  0, 31, 31, 0, 26, 0, 0, 0, 14, 0,
-  0, 24, 0, 0, 117, 2, 21, 20, 0, 0,
-  0, 0, 24, 0, 0, 0, 0, 8, 0, 0,
-  0, 26, 43, 6, 20, 0, 13, 0, 59, 0,
-  10, 62, 36, 31, 3, 0, 46, 0, 0, 38,
-  0, 42, 6, 2, 0, 34, 0, 0, 63, 41,
-  15, 0, 0, 0, 0, 46, 0, 37, 0, 53,
-  25, 14, 17, 17, 0, 32, 15, 5, 91, 14,
-  0, 0, 28, 0, 0, 70, 0, 0, 0, 0,
-  0, 0, 24, 8, 0, 0, 0, 2, 0, 9,
-  17, 48, 0, 3, 0, 31, 71, 5, 13, 36,
-  17, 0, 4, 23, 26, 35, 36, 0, 0, 2,
-  17, 32, 0, 0, 2, 44, 36, 0, 0, 0,
-  12, 0, 55, 13, 24, 46, 43, 0, 0, 24,
-  0, 0, 42, 41, 44, 0, 0, 0, 108, 0,
-  71, 14, 0, 0, 0, 0, 0, 10, 0, 139,
-  4, 0, 12, 0, 0, 18, 33, 0, 0, 25,
-  0, 0, 0, 0, 30, 95, 19, 11, 3, 0,
-  0, 0, 0, 0, 0, 27, 29, 38, 0, 0,
-  0, 23, 0, 54, 0, 22, 0, 53, 1, 90,
-  35, 56, 0, 0, 0, 51, 6, 0, 10, 0,
-  55, 0, 49, 0, 11, 61, 0, 0, 76, 3,
-  0, 3, 55, 0, 82, 11, 11, 0, 0, 21,
-  26, 25, 0, 32, 34, 0, 41, 44, 0, 0,
-  22, 0, 0, 7, 0, 21, 4, 0, 4, 31,
-  0, 0, 7, 66, 36, 0, 0, 23, 27, 0,
-  16, 0, 0, 0, 0, 0, 0, 35, 0, 0,
-  100, 2, 34, 1, 0, 0, 0, 0, 28, 0,
-  0, 0, 0, 0, 0, 0, 9, 38, 29, 0,
-  28, 0, 15, 0, 49, 21, 13, 59, 25, 11,
-  12, 5, 68, 0, 0, 42, 2, 24, 1, 0,
-  0, 35, 0, 0, 51, 61, 4, 0, 0, 0,
-  0, 42, 8, 38, 0, 45, 9, 26, 16, 31,
-  0, 20, 23, 0, 74, 24, 0, 0, 43, 0,
-  0, 56, 26, 7, 0, 0, 0, 0, 26, 8,
-  30, 0, 0, 7, 0, 8, 2, 45, 9, 0,
-  0, 52, 52, 14, 29, 21, 20, 0, 7, 19,
-  17, 28, 6, 32, 0, 6, 20, 41, 0, 0,
-  30, 59, 7, 0, 1, 0, 0, 0, 35, 0,
-  0, 25, 13, 0, 0, 13, 0, 0, 41, 20,
-  37, 0, 1, 0, 90, 0, 36, 0, 0, 0,
-  0, 41, 38, 0, 0, 0, 0, 0, 61, 6,
-  0, 16, 12, 19, 25, 54, 49, 37, 21, 5,
-  43, 0, 53, 32, 0, 0, 35, 21, 0, 0,
-  0, 0, 32, 0, 3, 0, 0, 0, 0, 35,
-  0, 0, 0, 27, 0, 26, 0, 0, 0, 15,
-  28, 3, 38, 9, 0, 0, 27, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 56, 0, 5, 0,
-  0, 0, 1, 44, 11, 11, 0, 62, 0, 23,
-  13, 12, 56, 44, 1, 24, 0, 29, 27, 31,
-  52, 10, 0, 0, 12, 0, 0, 0, 11, 51,
-  42, 0, 0, 0, 0, 0, 41, 0, 0, 48,
-  5, 0, 0, 10, 0, 0, 7, 0, 0, 0,
-  0, 0, 47, 0, 21, 0, 1, 20, 0, 0,
-  0, 2, 0, 130, 10, 0, 4, 0, 0, 17,
-  27, 0, 0, 13, 0, 0, 0, 0, 39, 101,
-  22, 12, 0, 0, 0, 0, 0, 3, 0, 24,
-  35, 28, 1, 0, 0, 22, 0, 43, 0, 20,
-  0, 45, 17, 92, 24, 56, 0, 1, 0, 50,
-  0, 0, 17, 0, 51, 0, 51, 0, 0, 57,
-  0, 0, 72, 8, 0, 8, 34, 0, 64, 5,
-  28, 6, 0, 15, 34, 35, 0, 21, 42, 0,
-  36, 58, 0, 0, 16, 0, 0, 0, 0, 14,
-  4, 0, 0, 35, 0, 0, 0, 63, 44, 0,
-  0, 33, 35, 0, 21, 0, 0, 0, 3, 0,
-  0, 32, 0, 0, 109, 11, 25, 17, 0, 0,
-  0, 0, 15, 0, 0, 0, 0, 0, 0, 0,
-  0, 30, 33, 0, 19, 0, 21, 0, 43, 0,
-  16, 54, 29, 19, 0, 10, 66, 0, 0, 44,
-  0, 21, 4, 0, 0, 41, 0, 0, 53, 56,
-  9, 0, 0, 0, 0, 18, 0, 34, 0, 47,
-  24, 21, 4, 29, 0, 18, 41, 0, 75, 14,
-  0, 0, 37, 0, 0, 75, 15, 0, 0, 0,
-  0, 0, 34, 16, 0, 0, 0, 2, 0, 21,
-  12, 35, 14, 9, 0, 42, 59, 0, 15, 48,
-  23, 0, 5, 24, 11, 27, 9, 21, 0, 6,
-  17, 45, 0, 0, 9, 43, 26, 0, 0, 0,
-  17, 0, 51, 8, 2, 21, 33, 2, 0, 20,
-  0, 0, 46, 39, 44, 11, 0, 0, 80, 0,
-  29, 15, 0, 0, 0, 47, 63, 0, 0, 0,
-  0, 0, 44, 1, 0, 11, 10, 3, 0, 58,
-  41, 16, 11, 0, 10, 0, 65, 40, 0, 0,
-  36, 16, 0, 0, 0, 0, 20, 0, 20, 14,
-  0, 0, 0, 16, 0, 3, 0, 22, 0, 2,
-  0, 0, 0, 1, 57, 3, 31, 0, 0, 0,
-  29, 0, 0, 14, 3, 0, 0, 0, 16, 0,
-  39, 2, 0, 0, 0, 0, 0, 49, 17, 0,
-  0, 86, 0, 30, 13, 0, 52, 56, 3, 30,
-  0, 29, 23, 24, 50, 0, 0, 0, 17, 0,
-  0, 0, 0, 53, 48, 0, 0, 0, 13, 0,
-  61, 0, 0, 31, 25, 0, 0, 5, 0, 0,
-  7, 0, 0, 16, 0, 0, 30, 0, 18, 13,
-  0, 31, 0, 0, 0, 5, 0, 140, 8, 5,
-  3, 0, 0, 23, 36, 0, 0, 10, 2, 0,
-  0, 0, 35, 102, 17, 9, 0, 0, 0, 0,
-  0, 21, 0, 23, 35, 21, 4, 1, 0, 25,
-  0, 41, 0, 16, 0, 48, 13, 84, 13, 57,
-  0, 3, 0, 61, 0, 0, 24, 0, 45, 0,
-  39, 0, 0, 51, 0, 0, 78, 3, 0, 20,
-  24, 0, 67, 6, 31, 2, 0, 19, 16, 27,
-  0, 18, 39, 0, 33, 59, 0, 0, 10, 0,
-  0, 0, 0, 8, 0, 0, 12, 34, 0, 0,
-  0, 66, 43, 0, 0, 31, 31, 0, 26, 0,
-  0, 0, 14, 0, 0, 24, 0, 0, 117, 2,
-  21, 20, 0, 0, 0, 0, 24, 0, 0, 0,
-  0, 8, 0, 0, 0, 26, 43, 6, 20, 0,
-  13, 0, 59, 0, 10, 62, 36, 31, 3, 0,
-  46, 0, 0, 38, 0, 42, 6, 2, 0, 34,
-  0, 0, 63, 41, 15, 0, 0, 0, 0, 46,
-  0, 37, 0, 53, 25, 14, 17, 17, 0, 32,
-  15, 5, 91, 14, 0, 0, 28, 0, 0, 70,
-  0, 0, 0, 0, 0, 0, 24, 8, 0, 0,
-  0, 2, 0, 9, 17, 48, 0, 3, 0, 31,
-  71, 5, 13, 36, 17, 0, 4, 23, 26, 35,
-  36, 0, 0, 2, 17, 32, 0, 0, 2, 44,
-  36, 0, 0, 0, 12, 0, 55, 13, 24, 46,
-  43, 0, 0, 24, 0, 0, 42, 41, 44, 0,
-  0, 0, 108, 0, 71, 14, 0, 0, 0, 44,
-  70, 0, 0, 0, 0, 9, 53, 0, 0, 29,
-  11, 20, 0, 36, 26, 0, 0, 0, 0, 7,
-  73, 51, 0, 0, 16, 18, 0, 0, 0, 0,
-  0, 0, 29, 22, 0, 0, 0, 40, 0, 13,
-  0, 10, 0, 1, 22, 0, 0, 0, 35, 32,
-  22, 15, 0, 0, 28, 0, 0, 0, 0, 0,
-  0, 0, 20, 0, 30, 0, 2, 0, 0, 8,
-  3, 20, 33, 0, 0, 85, 0, 28, 19, 0,
-  42, 48, 0, 18, 0, 36, 33, 9, 46, 0,
-  0, 0, 8, 0, 0, 0, 0, 81, 37, 0,
-  0, 0, 25, 0, 70, 0, 22, 26, 14, 0,
-  0, 8, 0, 0, 28, 0, 0, 18, 0, 0,
-  19, 0, 44, 20, 0, 20, 0, 0, 0, 0,
-  9, 38, 29, 0, 28, 0, 15, 0, 49, 21,
-  13, 59, 25, 11, 12, 5, 68, 0, 0, 42,
-  2, 24, 1, 0, 0, 35, 0, 0, 51, 61,
-  4, 0, 0, 0, 0, 42, 8, 38, 0, 45,
-  9, 26, 16, 31, 0, 20, 23, 0, 74, 24,
-  0, 0, 43, 0, 0, 56, 26, 7, 0, 0,
-  0, 0, 26, 8, 30, 0, 0, 7, 0, 8,
-  2, 45, 9, 0, 0, 52, 52, 14, 29, 21,
-  20, 0, 7, 19, 17, 28, 6, 32, 0, 6,
-  20, 41, 0, 0, 30, 59, 7, 0, 1, 0,
-  0, 0, 35, 0, 0, 25, 13, 0, 0, 13,
-  0, 0, 41, 20, 37, 0, 1, 0, 90, 0,
-  36, 0, 0, 0, 0, 41, 38, 0, 0, 0,
-  0, 0, 61, 6, 0, 16, 12, 19, 25, 54,
-  49, 37, 21, 5, 43, 0, 53, 32, 0, 0,
-  35, 21, 0, 0, 0, 0, 32, 0, 3, 0,
-  0, 0, 0, 35, 0, 0, 0, 27, 0, 26,
-  0, 0, 0, 15, 28, 3, 38, 9, 0, 0,
-  27, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  56, 0, 5, 0, 0, 0, 1, 44, 11, 11,
-  0, 62, 0, 23, 13, 12, 56, 44, 1, 24,
-  0, 29, 27, 31, 52, 10, 0, 0, 12, 0,
-  0, 0, 11, 51, 42, 0, 0, 0, 0, 0,
-  41, 0, 0, 48, 5, 0, 0, 10, 0, 0,
-  7, 0, 0, 0, 0, 0, 47, 0, 21, 0,
-  1, 20, 52, 0, 43, 0, 22, 0, 0, 0,
-  29, 0, 0, 0, 38, 88, 0, 0, 38, 0,
-  13, 0, 33, 104, 68, 26, 0, 0, 8, 50,
-  0, 0, 0, 10, 0, 4, 0, 0, 0, 20,
-  0, 11, 1, 0, 0, 0, 0, 16, 0, 0,
-  0, 7, 0, 77, 0, 0, 52, 0, 26, 23,
-  6, 0, 25, 0, 0, 6, 24, 0, 92, 16,
-  18, 73, 0, 0, 0, 73, 0, 0, 0, 50,
-  0, 0, 0, 0, 11, 59, 10, 49, 0, 55,
-  10, 0, 0, 37, 0, 0, 5, 0, 13, 0,
-  23, 61, 29, 7, 1, 0, 19, 2, 0, 26,
-  0, 53, 0, 7, 0, 0, 0, 23, 69, 0,
-  1, 0, 0, 31, 0, 0, 4, 0, 0, 61,
-  0, 0, 0, 0, 0, 30, 33, 0, 19, 0,
-  21, 0, 43, 0, 16, 54, 29, 19, 0, 10,
-  66, 0, 0, 44, 0, 21, 4, 0, 0, 41,
-  0, 0, 53, 56, 9, 0, 0, 0, 0, 18,
-  0, 34, 0, 47, 24, 21, 4, 29, 0, 18,
-  41, 0, 75, 14, 0, 0, 37, 0, 0, 75,
-  15, 0, 0, 0, 0, 0, 34, 16, 0, 0,
-  0, 2, 0, 21, 12, 35, 14, 9, 0, 42,
-  59, 0, 15, 48, 23, 0, 5, 24, 11, 27,
-  9, 21, 0, 6, 17, 45, 0, 0, 9, 43,
-  26, 0, 0, 0, 17, 0, 51, 8, 2, 21,
-  33, 2, 0, 20, 0, 0, 46, 39, 44, 11,
-  0, 0, 80, 0, 29, 15, 0, 0, 0, 47,
-  63, 0, 0, 0, 0, 0, 44, 1, 0, 11,
-  10, 3, 0, 58, 41, 16, 11, 0, 10, 0,
-  65, 40, 0, 0, 36, 16, 0, 0, 0, 0,
-  20, 0, 20, 14, 0, 0, 0, 16, 0, 3,
-  0, 22, 0, 2, 0, 0, 0, 1, 57, 3,
-  31, 0, 0, 0, 29, 0, 0, 14, 3, 0,
-  0, 0, 16, 0, 39, 2, 0, 0, 0, 0,
-  0, 49, 17, 0, 0, 86, 0, 30, 13, 0,
-  52, 56, 3, 30, 0, 29, 23, 24, 50, 0,
-  0, 0, 17, 0, 0, 0, 0, 53, 48, 0,
-  0, 0, 13, 0, 61, 0, 0, 31, 25, 0,
-  0, 5, 0, 0, 7, 0, 0, 16, 0, 0,
-  30, 0, 18, 13, 0, 31, 103, 0, 37, 5,
-  6, 15, 0, 0, 15, 0, 0, 23, 47, 54,
-  0, 0, 22, 0, 6, 0, 0, 173, 80, 13,
-  0, 0, 0, 33, 0, 0, 2, 56, 0, 34,
-  0, 21, 0, 29, 0, 25, 0, 22, 0, 0,
-  27, 6, 10, 8, 0, 0, 0, 77, 0, 0,
-  89, 0, 43, 20, 45, 0, 35, 11, 0, 32,
-  30, 49, 7, 15, 23, 23, 7, 28, 0, 22,
-  0, 0, 3, 45, 0, 13, 0, 0, 4, 42,
-  8, 27, 0, 9, 0, 0, 0, 0, 8, 0,
-  7, 0, 24, 0, 27, 61, 2, 0, 25, 0,
-  40, 28, 4, 8, 10, 35, 4, 0, 0, 0,
-  0, 15, 78, 0, 23, 10, 0, 35, 0, 0,
-  20, 3, 3, 48, 0, 8, 0, 0, 0, 26,
-  43, 6, 20, 0, 13, 0, 59, 0, 10, 62,
-  36, 31, 3, 0, 46, 0, 0, 38, 0, 42,
-  6, 2, 0, 34, 0, 0, 63, 41, 15, 0,
-  0, 0, 0, 46, 0, 37, 0, 53, 25, 14,
-  17, 17, 0, 32, 15, 5, 91, 14, 0, 0,
-  28, 0, 0, 70, 0, 0, 0, 0, 0, 0,
-  24, 8, 0, 0, 0, 2, 0, 9, 17, 48,
-  0, 3, 0, 31, 71, 5, 13, 36, 17, 0,
-  4, 23, 26, 35, 36, 0, 0, 2, 17, 32,
-  0, 0, 2, 44, 36, 0, 0, 0, 12, 0,
-  55, 13, 24, 46, 43, 0, 0, 24, 0, 0,
-  42, 41, 44, 0, 0, 0, 108, 0, 71, 14,
-  0, 0, 0, 44, 70, 0, 0, 0, 0, 9,
-  53, 0, 0, 29, 11, 20, 0, 36, 26, 0,
-  0, 0, 0, 7, 73, 51, 0, 0, 16, 18,
-  0, 0, 0, 0, 0, 0, 29, 22, 0, 0,
-  0, 40, 0, 13, 0, 10, 0, 1, 22, 0,
-  0, 0, 35, 32, 22, 15, 0, 0, 28, 0,
-  0, 0, 0, 0, 0, 0, 20, 0, 30, 0,
-  2, 0, 0, 8, 3, 20, 33, 0, 0, 85,
-  0, 28, 19, 0, 42, 48, 0, 18, 0, 36,
-  33, 9, 46, 0, 0, 0, 8, 0, 0, 0,
-  0, 81, 37, 0, 0, 0, 25, 0, 70, 0,
-  22, 26, 14, 0, 0, 8, 0, 0, 28, 0,
-  0, 18, 0, 0, 19, 0, 44, 20, 0, 20,
-  102, 0, 40, 4, 0, 12, 0, 0, 45, 0,
-  0, 35, 56, 20, 0, 0, 9, 0, 0, 0,
-  0, 189, 80, 25, 0, 0, 0, 31, 0, 0,
-  16, 61, 0, 11, 0, 30, 0, 40, 0, 30,
-  0, 28, 48, 0, 38, 21, 24, 29, 0, 0,
-  0, 80, 0, 0, 100, 0, 63, 0, 47, 0,
-  14, 23, 0, 56, 27, 66, 0, 1, 0, 4,
-  12, 26, 10, 13, 0, 0, 0, 47, 0, 15,
-  0, 0, 7, 21, 0, 11, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 25, 0, 18, 61,
-  0, 0, 17, 0, 54, 23, 26, 12, 6, 14,
-  8, 6, 0, 0, 0, 2, 87, 0, 36, 39,
-  0, 9, 0, 0, 23, 15, 18, 29, 0, 41,
-  38, 0, 0, 0, 0, 0, 61, 6, 0, 16,
-  12, 19, 25, 54, 49, 37, 21, 5, 43, 0,
-  53, 32, 0, 0, 35, 21, 0, 0, 0, 0,
-  32, 0, 3, 0, 0, 0, 0, 35, 0, 0,
-  0, 27, 0, 26, 0, 0, 0, 15, 28, 3,
-  38, 9, 0, 0, 27, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 56, 0, 5, 0, 0, 0,
-  1, 44, 11, 11, 0, 62, 0, 23, 13, 12,
-  56, 44, 1, 24, 0, 29, 27, 31, 52, 10,
-  0, 0, 12, 0, 0, 0, 11, 51, 42, 0,
-  0, 0, 0, 0, 41, 0, 0, 48, 5, 0,
-  0, 10, 0, 0, 7, 0, 0, 0, 0, 0,
-  47, 0, 21, 0, 1, 20, 52, 0, 43, 0,
-  22, 0, 0, 0, 29, 0, 0, 0, 38, 88,
-  0, 0, 38, 0, 13, 0, 33, 104, 68, 26,
-  0, 0, 8, 50, 0, 0, 0, 10, 0, 4,
-  0, 0, 0, 20, 0, 11, 1, 0, 0, 0,
-  0, 16, 0, 0, 0, 7, 0, 77, 0, 0,
-  52, 0, 26, 23, 6, 0, 25, 0, 0, 6,
-  24, 0, 92, 16, 18, 73, 0, 0, 0, 73,
-  0, 0, 0, 50, 0, 0, 0, 0, 11, 59,
-  10, 49, 0, 55, 10, 0, 0, 37, 0, 0,
-  5, 0, 13, 0, 23, 61, 29, 7, 1, 0,
-  19, 2, 0, 26, 0, 53, 0, 7, 0, 0,
-  0, 23, 69, 0, 1, 0, 0, 31, 0, 0,
-  4, 0, 0, 61, 44, 0, 0, 0, 25, 73,
-  0, 0, 7, 0, 0, 0, 26, 81, 0, 0,
-  48, 0, 0, 0, 40, 70, 0, 48, 0, 0,
-  0, 16, 0, 0, 0, 0, 0, 39, 0, 0,
-  0, 36, 0, 27, 0, 6, 0, 0, 20, 1,
-  0, 24, 22, 0, 0, 39, 0, 0, 0, 0,
-  10, 25, 0, 0, 31, 12, 0, 4, 0, 0,
-  87, 23, 22, 30, 0, 6, 0, 43, 7, 0,
-  0, 5, 0, 16, 0, 0, 0, 7, 9, 33,
-  0, 49, 1, 0, 0, 56, 0, 0, 0, 0,
-  0, 0, 17, 64, 6, 22, 16, 0, 10, 13,
-  0, 13, 8, 65, 0, 0, 0, 0, 0, 16,
-  82, 0, 8, 0, 12, 7, 0, 0, 0, 7,
-  4, 20, 0, 47, 63, 0, 0, 0, 0, 0,
-  44, 1, 0, 11, 10, 3, 0, 58, 41, 16,
-  11, 0, 10, 0, 65, 40, 0, 0, 36, 16,
-  0, 0, 0, 0, 20, 0, 20, 14, 0, 0,
-  0, 16, 0, 3, 0, 22, 0, 2, 0, 0,
-  0, 1, 57, 3, 31, 0, 0, 0, 29, 0,
-  0, 14, 3, 0, 0, 0, 16, 0, 39, 2,
-  0, 0, 0, 0, 0, 49, 17, 0, 0, 86,
-  0, 30, 13, 0, 52, 56, 3, 30, 0, 29,
-  23, 24, 50, 0, 0, 0, 17, 0, 0, 0,
-  0, 53, 48, 0, 0, 0, 13, 0, 61, 0,
-  0, 31, 25, 0, 0, 5, 0, 0, 7, 0,
-  0, 16, 0, 0, 30, 0, 18, 13, 0, 31,
-  103, 0, 37, 5, 6, 15, 0, 0, 15, 0,
-  0, 23, 47, 54, 0, 0, 22, 0, 6, 0,
-  0, 173, 80, 13, 0, 0, 0, 33, 0, 0,
-  2, 56, 0, 34, 0, 21, 0, 29, 0, 25,
-  0, 22, 0, 0, 27, 6, 10, 8, 0, 0,
-  0, 77, 0, 0, 89, 0, 43, 20, 45, 0,
-  35, 11, 0, 32, 30, 49, 7, 15, 23, 23,
-  7, 28, 0, 22, 0, 0, 3, 45, 0, 13,
-  0, 0, 4, 42, 8, 27, 0, 9, 0, 0,
-  0, 0, 8, 0, 7, 0, 24, 0, 27, 61,
-  2, 0, 25, 0, 40, 28, 4, 8, 10, 35,
-  4, 0, 0, 0, 0, 15, 78, 0, 23, 10,
-  0, 35, 0, 0, 20, 3, 3, 48, 45, 0,
-  0, 0, 22, 82, 0, 0, 8, 0, 0, 0,
-  29, 61, 0, 8, 48, 0, 0, 0, 21, 71,
-  5, 41, 10, 3, 0, 14, 0, 2, 0, 9,
-  0, 69, 34, 19, 0, 41, 0, 34, 7, 20,
-  0, 34, 59, 23, 26, 10, 5, 0, 0, 0,
-  0, 0, 0, 0, 18, 22, 10, 15, 30, 39,
-  10, 0, 0, 0, 16, 36, 52, 0, 27, 32,
-  3, 0, 12, 28, 0, 21, 0, 48, 0, 2,
-  0, 34, 13, 5, 17, 11, 0, 25, 0, 47,
-  10, 1, 26, 5, 0, 0, 0, 67, 13, 0,
-  12, 0, 16, 0, 0, 15, 0, 51, 0, 0,
-  0, 0, 0, 0, 69, 0, 19, 0, 19, 11,
-  0, 0, 29, 2, 31, 0, 0, 44, 70, 0,
-  0, 0, 0, 9, 53, 0, 0, 29, 11, 20,
-  0, 36, 26, 0, 0, 0, 0, 7, 73, 51,
-  0, 0, 16, 18, 0, 0, 0, 0, 0, 0,
-  29, 22, 0, 0, 0, 40, 0, 13, 0, 10,
-  0, 1, 22, 0, 0, 0, 35, 32, 22, 15,
-  0, 0, 28, 0, 0, 0, 0, 0, 0, 0,
-  20, 0, 30, 0, 2, 0, 0, 8, 3, 20,
-  33, 0, 0, 85, 0, 28, 19, 0, 42, 48,
-  0, 18, 0, 36, 33, 9, 46, 0, 0, 0,
-  8, 0, 0, 0, 0, 81, 37, 0, 0, 0,
-  25, 0, 70, 0, 22, 26, 14, 0, 0, 8,
-  0, 0, 28, 0, 0, 18, 0, 0, 19, 0,
-  44, 20, 0, 20, 102, 0, 40, 4, 0, 12,
-  0, 0, 45, 0, 0, 35, 56, 20, 0, 0,
-  9, 0, 0, 0, 0, 189, 80, 25, 0, 0,
-  0, 31, 0, 0, 16, 61, 0, 11, 0, 30,
-  0, 40, 0, 30, 0, 28, 48, 0, 38, 21,
-  24, 29, 0, 0, 0, 80, 0, 0, 100, 0,
-  63, 0, 47, 0, 14, 23, 0, 56, 27, 66,
-  0, 1, 0, 4, 12, 26, 10, 13, 0, 0,
-  0, 47, 0, 15, 0, 0, 7, 21, 0, 11,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  25, 0, 18, 61, 0, 0, 17, 0, 54, 23,
-  26, 12, 6, 14, 8, 6, 0, 0, 0, 2,
-  87, 0, 36, 39, 0, 9, 0, 0, 23, 15,
-  18, 29, 9, 0, 0, 9, 0, 65, 0, 0,
-  41, 0, 0, 0, 45, 38, 0, 38, 32, 25,
-  0, 0, 8, 14, 5, 56, 28, 0, 0, 19,
-  0, 0, 0, 21, 10, 40, 27, 4, 0, 33,
-  0, 8, 9, 4, 50, 58, 50, 77, 14, 17,
-  0, 0, 0, 0, 0, 0, 0, 0, 54, 0,
-  0, 0, 4, 43, 0, 0, 0, 0, 0, 0,
-  12, 0, 54, 0, 14, 11, 0, 28, 0, 28,
-  0, 28, 0, 16, 0, 39, 0, 0, 31, 0,
-  14, 62, 0, 63, 0, 0, 13, 17, 0, 0,
-  0, 56, 19, 0, 0, 0, 17, 0, 0, 4,
-  0, 40, 0, 0, 0, 9, 0, 0, 61, 0,
-  8, 0, 37, 0, 3, 0, 29, 10, 44, 0,
-  52, 0, 43, 0, 22, 0, 0, 0, 29, 0,
-  0, 0, 38, 88, 0, 0, 38, 0, 13, 0,
-  33, 104, 68, 26, 0, 0, 8, 50, 0, 0,
-  0, 10, 0, 4, 0, 0, 0, 20, 0, 11,
-  1, 0, 0, 0, 0, 16, 0, 0, 0, 7,
-  0, 77, 0, 0, 52, 0, 26, 23, 6, 0,
-  25, 0, 0, 6, 24, 0, 92, 16, 18, 73,
-  0, 0, 0, 73, 0, 0, 0, 50, 0, 0,
-  0, 0, 11, 59, 10, 49, 0, 55, 10, 0,
-  0, 37, 0, 0, 5, 0, 13, 0, 23, 61,
-  29, 7, 1, 0, 19, 2, 0, 26, 0, 53,
-  0, 7, 0, 0, 0, 23, 69, 0, 1, 0,
-  0, 31, 0, 0, 4, 0, 0, 61, 44, 0,
-  0, 0, 25, 73, 0, 0, 7, 0, 0, 0,
-  26, 81, 0, 0, 48, 0, 0, 0, 40, 70,
-  0, 48, 0, 0, 0, 16, 0, 0, 0, 0,
-  0, 39, 0, 0, 0, 36, 0, 27, 0, 6,
-  0, 0, 20, 1, 0, 24, 22, 0, 0, 39,
-  0, 0, 0, 0, 10, 25, 0, 0, 31, 12,
-  0, 4, 0, 0, 87, 23, 22, 30, 0, 6,
-  0, 43, 7, 0, 0, 5, 0, 16, 0, 0,
-  0, 7, 9, 33, 0, 49, 1, 0, 0, 56,
-  0, 0, 0, 0, 0, 0, 17, 64, 6, 22,
-  16, 0, 10, 13, 0, 13, 8, 65, 0, 0,
-  0, 0, 0, 16, 82, 0, 8, 0, 12, 7,
-  0, 0, 0, 7, 4, 20, 0, 17, 0, 0,
-  21, 28, 30, 14, 58, 16, 0, 5, 32, 30,
-  51, 35, 42, 53, 0, 21, 81, 0, 0, 49,
-  7, 50, 21, 0, 0, 19, 0, 0, 2, 16,
-  18, 0, 0, 7, 0, 43, 0, 40, 0, 33,
-  27, 19, 0, 12, 0, 0, 23, 0, 84, 2,
-  0, 0, 0, 0, 0, 29, 0, 0, 0, 0,
-  0, 0, 33, 0, 0, 0, 0, 25, 18, 30,
-  44, 27, 0, 0, 0, 44, 47, 23, 14, 0,
-  26, 7, 56, 14, 51, 35, 8, 27, 0, 39,
-  0, 19, 0, 4, 43, 43, 0, 0, 0, 0,
-  0, 0, 8, 13, 9, 61, 0, 0, 0, 0,
-  12, 0, 28, 21, 21, 0, 50, 0, 111, 0,
-  14, 14, 3, 0, 103, 0, 37, 5, 6, 15,
-  0, 0, 15, 0, 0, 23, 47, 54, 0, 0,
-  22, 0, 6, 0, 0, 173, 80, 13, 0, 0,
-  0, 33, 0, 0, 2, 56, 0, 34, 0, 21,
-  0, 29, 0, 25, 0, 22, 0, 0, 27, 6,
-  10, 8, 0, 0, 0, 77, 0, 0, 89, 0,
-  43, 20, 45, 0, 35, 11, 0, 32, 30, 49,
-  7, 15, 23, 23, 7, 28, 0, 22, 0, 0,
-  3, 45, 0, 13, 0, 0, 4, 42, 8, 27,
-  0, 9, 0, 0, 0, 0, 8, 0, 7, 0,
-  24, 0, 27, 61, 2, 0, 25, 0, 40, 28,
-  4, 8, 10, 35, 4, 0, 0, 0, 0, 15,
-  78, 0, 23, 10, 0, 35, 0, 0, 20, 3,
-  3, 48, 45, 0, 0, 0, 22, 82, 0, 0,
-  8, 0, 0, 0, 29, 61, 0, 8, 48, 0,
-  0, 0, 21, 71, 5, 41, 10, 3, 0, 14,
-  0, 2, 0, 9, 0, 69, 34, 19, 0, 41,
-  0, 34, 7, 20, 0, 34, 59, 23, 26, 10,
-  5, 0, 0, 0, 0, 0, 0, 0, 18, 22,
-  10, 15, 30, 39, 10, 0, 0, 0, 16, 36,
-  52, 0, 27, 32, 3, 0, 12, 28, 0, 21,
-  0, 48, 0, 2, 0, 34, 13, 5, 17, 11,
-  0, 25, 0, 47, 10, 1, 26, 5, 0, 0,
-  0, 67, 13, 0, 12, 0, 16, 0, 0, 15,
-  0, 51, 0, 0, 0, 0, 0, 0, 69, 0,
-  19, 0, 19, 11, 0, 0, 29, 2, 31, 0,
-  0, 24, 0, 0, 40, 11, 0, 0, 61, 11,
-  0, 15, 51, 85, 31, 58, 61, 16, 0, 9,
-  60, 0, 0, 53, 11, 51, 1, 8, 0, 10,
-  0, 0, 0, 42, 35, 0, 15, 23, 0, 51,
-  12, 18, 0, 69, 33, 20, 9, 0, 0, 0,
-  24, 0, 57, 28, 0, 0, 0, 2, 0, 18,
-  0, 0, 0, 0, 0, 0, 31, 0, 42, 0,
-  0, 0, 4, 14, 36, 12, 0, 6, 0, 29,
-  44, 60, 4, 0, 34, 12, 53, 16, 53, 25,
-  0, 50, 0, 27, 0, 9, 0, 0, 31, 64,
-  0, 0, 0, 0, 0, 0, 0, 12, 10, 60,
-  0, 0, 0, 0, 0, 0, 10, 13, 32, 0,
-  25, 0, 76, 0, 51, 15, 31, 0, 102, 0,
-  40, 4, 0, 12, 0, 0, 45, 0, 0, 35,
-  56, 20, 0, 0, 9, 0, 0, 0, 0, 189,
-  80, 25, 0, 0, 0, 31, 0, 0, 16, 61,
-  0, 11, 0, 30, 0, 40, 0, 30, 0, 28,
-  48, 0, 38, 21, 24, 29, 0, 0, 0, 80,
-  0, 0, 100, 0, 63, 0, 47, 0, 14, 23,
-  0, 56, 27, 66, 0, 1, 0, 4, 12, 26,
-  10, 13, 0, 0, 0, 47, 0, 15, 0, 0,
-  7, 21, 0, 11, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 25, 0, 18, 61, 0, 0,
-  17, 0, 54, 23, 26, 12, 6, 14, 8, 6,
-  0, 0, 0, 2, 87, 0, 36, 39, 0, 9,
-  0, 0, 23, 15, 18, 29, 9, 0, 0, 9,
-  0, 65, 0, 0, 41, 0, 0, 0, 45, 38,
-  0, 38, 32, 25, 0, 0, 8, 14, 5, 56,
-  28, 0, 0, 19, 0, 0, 0, 21, 10, 40,
-  27, 4, 0, 33, 0, 8, 9, 4, 50, 58,
-  50, 77, 14, 17, 0, 0, 0, 0, 0, 0,
-  0, 0, 54, 0, 0, 0, 4, 43, 0, 0,
-  0, 0, 0, 0, 12, 0, 54, 0, 14, 11,
-  0, 28, 0, 28, 0, 28, 0, 16, 0, 39,
-  0, 0, 31, 0, 14, 62, 0, 63, 0, 0,
-  13, 17, 0, 0, 0, 56, 19, 0, 0, 0,
-  17, 0, 0, 4, 0, 40, 0, 0, 0, 9,
-  0, 0, 61, 0, 8, 0, 37, 0, 3, 0,
-  29, 10, 44, 0, 0, 14, 0, 0, 35, 12,
-  0, 0, 40, 0, 0, 15, 31, 88, 14, 51,
-  40, 12, 0, 18, 47, 0, 19, 50, 3, 20,
-  0, 2, 0, 0, 0, 0, 0, 38, 7, 0,
-  3, 31, 0, 29, 36, 1, 0, 74, 29, 39,
-  8, 0, 0, 0, 18, 2, 39, 14, 0, 6,
-  37, 0, 0, 0, 0, 4, 5, 0, 0, 0,
-  26, 0, 49, 0, 0, 0, 3, 3, 17, 22,
-  0, 17, 0, 21, 27, 60, 0, 26, 24, 3,
-  57, 0, 52, 33, 0, 62, 14, 8, 23, 27,
-  0, 0, 26, 70, 5, 0, 0, 0, 0, 0,
-  0, 16, 0, 35, 0, 0, 0, 12, 0, 0,
-  17, 3, 26, 0, 0, 0, 20, 0, 35, 8,
-  37, 0, 44, 0, 0, 0, 25, 73, 0, 0,
-  7, 0, 0, 0, 26, 81, 0, 0, 48, 0,
-  0, 0, 40, 70, 0, 48, 0, 0, 0, 16,
-  0, 0, 0, 0, 0, 39, 0, 0, 0, 36,
-  0, 27, 0, 6, 0, 0, 20, 1, 0, 24,
-  22, 0, 0, 39, 0, 0, 0, 0, 10, 25,
-  0, 0, 31, 12, 0, 4, 0, 0, 87, 23,
-  22, 30, 0, 6, 0, 43, 7, 0, 0, 5,
-  0, 16, 0, 0, 0, 7, 9, 33, 0, 49,
-  1, 0, 0, 56, 0, 0, 0, 0, 0, 0,
-  17, 64, 6, 22, 16, 0, 10, 13, 0, 13,
-  8, 65, 0, 0, 0, 0, 0, 16, 82, 0,
-  8, 0, 12, 7, 0, 0, 0, 7, 4, 20,
-  0, 17, 0, 0, 21, 28, 30, 14, 58, 16,
-  0, 5, 32, 30, 51, 35, 42, 53, 0, 21,
-  81, 0, 0, 49, 7, 50, 21, 0, 0, 19,
-  0, 0, 2, 16, 18, 0, 0, 7, 0, 43,
-  0, 40, 0, 33, 27, 19, 0, 12, 0, 0,
-  23, 0, 84, 2, 0, 0, 0, 0, 0, 29,
-  0, 0, 0, 0, 0, 0, 33, 0, 0, 0,
-  0, 25, 18, 30, 44, 27, 0, 0, 0, 44,
-  47, 23, 14, 0, 26, 7, 56, 14, 51, 35,
-  8, 27, 0, 39, 0, 19, 0, 4, 43, 43,
-  0, 0, 0, 0, 0, 0, 8, 13, 9, 61,
-  0, 0, 0, 0, 12, 0, 28, 21, 21, 0,
-  50, 0, 111, 0, 14, 14, 3, 0, 0, 47,
-  23, 0, 8, 0, 33, 0, 55, 0, 0, 17,
-  28, 56, 45, 66, 49, 49, 0, 15, 78, 0,
-  0, 46, 13, 29, 27, 0, 0, 0, 14, 0,
-  11, 19, 4, 0, 0, 0, 0, 33, 12, 13,
-  0, 55, 6, 0, 0, 0, 0, 0, 63, 12,
-  64, 29, 0, 0, 0, 0, 0, 23, 0, 0,
-  0, 0, 0, 0, 42, 0, 0, 0, 0, 0,
-  0, 41, 36, 0, 0, 29, 0, 27, 65, 51,
-  36, 6, 50, 11, 55, 0, 58, 33, 0, 14,
-  0, 30, 0, 20, 0, 12, 43, 51, 0, 0,
-  0, 0, 0, 0, 5, 6, 14, 33, 30, 0,
-  0, 0, 41, 0, 0, 0, 5, 0, 0, 0,
-  81, 0, 6, 22, 17, 0, 45, 0, 0, 0,
-  22, 82, 0, 0, 8, 0, 0, 0, 29, 61,
-  0, 8, 48, 0, 0, 0, 21, 71, 5, 41,
-  10, 3, 0, 14, 0, 2, 0, 9, 0, 69,
-  34, 19, 0, 41, 0, 34, 7, 20, 0, 34,
-  59, 23, 26, 10, 5, 0, 0, 0, 0, 0,
-  0, 0, 18, 22, 10, 15, 30, 39, 10, 0,
-  0, 0, 16, 36, 52, 0, 27, 32, 3, 0,
-  12, 28, 0, 21, 0, 48, 0, 2, 0, 34,
-  13, 5, 17, 11, 0, 25, 0, 47, 10, 1,
-  26, 5, 0, 0, 0, 67, 13, 0, 12, 0,
-  16, 0, 0, 15, 0, 51, 0, 0, 0, 0,
-  0, 0, 69, 0, 19, 0, 19, 11, 0, 0,
-  29, 2, 31, 0, 0, 24, 0, 0, 40, 11,
-  0, 0, 61, 11, 0, 15, 51, 85, 31, 58,
-  61, 16, 0, 9, 60, 0, 0, 53, 11, 51,
-  1, 8, 0, 10, 0, 0, 0, 42, 35, 0,
-  15, 23, 0, 51, 12, 18, 0, 69, 33, 20,
-  9, 0, 0, 0, 24, 0, 57, 28, 0, 0,
-  0, 2, 0, 18, 0, 0, 0, 0, 0, 0,
-  31, 0, 42, 0, 0, 0, 4, 14, 36, 12,
-  0, 6, 0, 29, 44, 60, 4, 0, 34, 12,
-  53, 16, 53, 25, 0, 50, 0, 27, 0, 9,
-  0, 0, 31, 64, 0, 0, 0, 0, 0, 0,
-  0, 12, 10, 60, 0, 0, 0, 0, 0, 0,
-  10, 13, 32, 0, 25, 0, 76, 0, 51, 15,
-  31, 0, 0, 35, 50, 0, 10, 0, 0, 0,
-  51, 2, 0, 18, 8, 100, 10, 27, 39, 26,
-  2, 4, 44, 0, 34, 24, 0, 0, 0, 5,
-  0, 0, 0, 0, 0, 0, 0, 0, 5, 0,
-  0, 22, 18, 0, 0, 35, 0, 0, 0, 0,
-  0, 0, 52, 66, 0, 34, 0, 0, 6, 2,
-  0, 0, 0, 0, 13, 0, 38, 2, 22, 0,
-  23, 0, 0, 0, 3, 15, 29, 0, 0, 37,
-  0, 21, 32, 48, 11, 18, 40, 3, 53, 7,
-  75, 6, 0, 23, 0, 0, 0, 1, 0, 0,
-  40, 70, 1, 0, 0, 0, 7, 0, 0, 9,
-  0, 8, 32, 0, 0, 0, 57, 0, 10, 0,
-  12, 0, 0, 0, 8, 0, 9, 14, 37, 0,
-  9, 0, 0, 9, 0, 65, 0, 0, 41, 0,
-  0, 0, 45, 38, 0, 38, 32, 25, 0, 0,
-  8, 14, 5, 56, 28, 0, 0, 19, 0, 0,
-  0, 21, 10, 40, 27, 4, 0, 33, 0, 8,
-  9, 4, 50, 58, 50, 77, 14, 17, 0, 0,
-  0, 0, 0, 0, 0, 0, 54, 0, 0, 0,
-  4, 43, 0, 0, 0, 0, 0, 0, 12, 0,
-  54, 0, 14, 11, 0, 28, 0, 28, 0, 28,
-  0, 16, 0, 39, 0, 0, 31, 0, 14, 62,
-  0, 63, 0, 0, 13, 17, 0, 0, 0, 56,
-  19, 0, 0, 0, 17, 0, 0, 4, 0, 40,
-  0, 0, 0, 9, 0, 0, 61, 0, 8, 0,
-  37, 0, 3, 0, 29, 10, 44, 0, 0, 14,
-  0, 0, 35, 12, 0, 0, 40, 0, 0, 15,
-  31, 88, 14, 51, 40, 12, 0, 18, 47, 0,
-  19, 50, 3, 20, 0, 2, 0, 0, 0, 0,
-  0, 38, 7, 0, 3, 31, 0, 29, 36, 1,
-  0, 74, 29, 39, 8, 0, 0, 0, 18, 2,
-  39, 14, 0, 6, 37, 0, 0, 0, 0, 4,
-  5, 0, 0, 0, 26, 0, 49, 0, 0, 0,
-  3, 3, 17, 22, 0, 17, 0, 21, 27, 60,
-  0, 26, 24, 3, 57, 0, 52, 33, 0, 62,
-  14, 8, 23, 27, 0, 0, 26, 70, 5, 0,
-  0, 0, 0, 0, 0, 16, 0, 35, 0, 0,
-  0, 12, 0, 0, 17, 3, 26, 0, 0, 0,
-  20, 0, 35, 8, 37, 0, 24, 0, 53, 0,
-  32, 0, 0, 0, 25, 0, 0, 1, 9, 122,
-  15, 0, 27, 21, 0, 8, 41, 13, 69, 7,
-  0, 0, 0, 4, 0, 0, 0, 0, 0, 5,
-  0, 0, 0, 4, 0, 26, 14, 10, 0, 48,
-  14, 0, 0, 0, 0, 0, 37, 104, 0, 37,
-  0, 0, 9, 6, 3, 0, 0, 0, 33, 0,
-  50, 22, 0, 0, 24, 22, 0, 1, 0, 0,
-  27, 0, 0, 13, 0, 41, 14, 36, 0, 5,
-  48, 0, 45, 11, 72, 0, 0, 2, 0, 0,
-  0, 25, 0, 0, 41, 57, 0, 0, 0, 0,
-  0, 0, 0, 10, 1, 0, 35, 0, 0, 0,
-  51, 0, 55, 0, 5, 0, 0, 0, 0, 0,
-  28, 1, 16, 0, 0, 17, 0, 0, 21, 28,
-  30, 14, 58, 16, 0, 5, 32, 30, 51, 35,
-  42, 53, 0, 21, 81, 0, 0, 49, 7, 50,
-  21, 0, 0, 19, 0, 0, 2, 16, 18, 0,
-  0, 7, 0, 43, 0, 40, 0, 33, 27, 19,
-  0, 12, 0, 0, 23, 0, 84, 2, 0, 0,
-  0, 0, 0, 29, 0, 0, 0, 0, 0, 0,
-  33, 0, 0, 0, 0, 25, 18, 30, 44, 27,
-  0, 0, 0, 44, 47, 23, 14, 0, 26, 7,
-  56, 14, 51, 35, 8, 27, 0, 39, 0, 19,
-  0, 4, 43, 43, 0, 0, 0, 0, 0, 0,
-  8, 13, 9, 61, 0, 0, 0, 0, 12, 0,
-  28, 21, 21, 0, 50, 0, 111, 0, 14, 14,
-  3, 0, 0, 47, 23, 0, 8, 0, 33, 0,
-  55, 0, 0, 17, 28, 56, 45, 66, 49, 49,
-  0, 15, 78, 0, 0, 46, 13, 29, 27, 0,
-  0, 0, 14, 0, 11, 19, 4, 0, 0, 0,
-  0, 33, 12, 13, 0, 55, 6, 0, 0, 0,
-  0, 0, 63, 12, 64, 29, 0, 0, 0, 0,
-  0, 23, 0, 0, 0, 0, 0, 0, 42, 0,
-  0, 0, 0, 0, 0, 41, 36, 0, 0, 29,
-  0, 27, 65, 51, 36, 6, 50, 11, 55, 0,
-  58, 33, 0, 14, 0, 30, 0, 20, 0, 12,
-  43, 51, 0, 0, 0, 0, 0, 0, 5, 6,
-  14, 33, 30, 0, 0, 0, 41, 0, 0, 0,
-  5, 0, 0, 0, 81, 0, 6, 22, 17, 0,
-  0, 43, 70, 0, 11, 0, 9, 0, 57, 6,
-  0, 0, 0, 60, 23, 63, 30, 38, 0, 12,
-  39, 0, 33, 35, 0, 0, 9, 14, 0, 0,
-  27, 0, 0, 0, 0, 0, 0, 17, 0, 12,
-  27, 0, 0, 40, 0, 0, 0, 0, 0, 0,
-  48, 52, 41, 12, 0, 0, 19, 12, 0, 0,
-  0, 0, 0, 0, 24, 0, 45, 0, 11, 4,
-  0, 0, 0, 28, 32, 0, 0, 18, 0, 0,
-  58, 19, 0, 21, 59, 13, 23, 9, 64, 10,
-  0, 32, 0, 0, 0, 0, 0, 0, 40, 51,
-  0, 0, 0, 0, 36, 0, 0, 22, 4, 24,
-  40, 0, 0, 0, 86, 0, 2, 0, 26, 0,
-  0, 1, 21, 0, 0, 24, 22, 0, 0, 24,
-  0, 0, 40, 11, 0, 0, 61, 11, 0, 15,
-  51, 85, 31, 58, 61, 16, 0, 9, 60, 0,
-  0, 53, 11, 51, 1, 8, 0, 10, 0, 0,
-  0, 42, 35, 0, 15, 23, 0, 51, 12, 18,
-  0, 69, 33, 20, 9, 0, 0, 0, 24, 0,
-  57, 28, 0, 0, 0, 2, 0, 18, 0, 0,
-  0, 0, 0, 0, 31, 0, 42, 0, 0, 0,
-  4, 14, 36, 12, 0, 6, 0, 29, 44, 60,
-  4, 0, 34, 12, 53, 16, 53, 25, 0, 50,
-  0, 27, 0, 9, 0, 0, 31, 64, 0, 0,
-  0, 0, 0, 0, 0, 12, 10, 60, 0, 0,
-  0, 0, 0, 0, 10, 13, 32, 0, 25, 0,
-  76, 0, 51, 15, 31, 0, 0, 35, 50, 0,
-  10, 0, 0, 0, 51, 2, 0, 18, 8, 100,
-  10, 27, 39, 26, 2, 4, 44, 0, 34, 24,
-  0, 0, 0, 5, 0, 0, 0, 0, 0, 0,
-  0, 0, 5, 0, 0, 22, 18, 0, 0, 35,
-  0, 0, 0, 0, 0, 0, 52, 66, 0, 34,
-  0, 0, 6, 2, 0, 0, 0, 0, 13, 0,
-  38, 2, 22, 0, 23, 0, 0, 0, 3, 15,
-  29, 0, 0, 37, 0, 21, 32, 48, 11, 18,
-  40, 3, 53, 7, 75, 6, 0, 23, 0, 0,
-  0, 1, 0, 0, 40, 70, 1, 0, 0, 0,
-  7, 0, 0, 9, 0, 8, 32, 0, 0, 0,
-  57, 0, 10, 0, 12, 0, 0, 0, 8, 0,
-  9, 14, 37, 0, 22, 0, 59, 0, 0, 0,
-  0, 0, 23, 0, 0, 0, 0, 116, 1, 0,
-  6, 27, 1, 0, 38, 30, 84, 8, 0, 0,
-  0, 4, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 2, 0, 0, 28, 17, 0, 30, 0, 0,
-  0, 0, 0, 0, 35, 131, 0, 15, 36, 0,
-  30, 17, 14, 0, 0, 0, 34, 0, 88, 47,
-  7, 2, 16, 67, 0, 0, 0, 0, 11, 0,
-  0, 0, 0, 24, 16, 22, 0, 15, 41, 0,
-  31, 10, 71, 0, 0, 11, 2, 0, 0, 5,
-  0, 0, 62, 66, 0, 0, 0, 0, 12, 10,
-  0, 7, 0, 0, 50, 0, 0, 0, 91, 3,
-  77, 0, 19, 0, 0, 0, 0, 0, 21, 6,
-  10, 0, 0, 14, 0, 0, 35, 12, 0, 0,
-  40, 0, 0, 15, 31, 88, 14, 51, 40, 12,
-  0, 18, 47, 0, 19, 50, 3, 20, 0, 2,
-  0, 0, 0, 0, 0, 38, 7, 0, 3, 31,
-  0, 29, 36, 1, 0, 74, 29, 39, 8, 0,
-  0, 0, 18, 2, 39, 14, 0, 6, 37, 0,
-  0, 0, 0, 4, 5, 0, 0, 0, 26, 0,
-  49, 0, 0, 0, 3, 3, 17, 22, 0, 17,
-  0, 21, 27, 60, 0, 26, 24, 3, 57, 0,
-  52, 33, 0, 62, 14, 8, 23, 27, 0, 0,
-  26, 70, 5, 0, 0, 0, 0, 0, 0, 16,
-  0, 35, 0, 0, 0, 12, 0, 0, 17, 3,
-  26, 0, 0, 0, 20, 0, 35, 8, 37, 0,
-  24, 0, 53, 0, 32, 0, 0, 0, 25, 0,
-  0, 1, 9, 122, 15, 0, 27, 21, 0, 8,
-  41, 13, 69, 7, 0, 0, 0, 4, 0, 0,
-  0, 0, 0, 5, 0, 0, 0, 4, 0, 26,
-  14, 10, 0, 48, 14, 0, 0, 0, 0, 0,
-  37, 104, 0, 37, 0, 0, 9, 6, 3, 0,
-  0, 0, 33, 0, 50, 22, 0, 0, 24, 22,
-  0, 1, 0, 0, 27, 0, 0, 13, 0, 41,
-  14, 36, 0, 5, 48, 0, 45, 11, 72, 0,
-  0, 2, 0, 0, 0, 25, 0, 0, 41, 57,
-  0, 0, 0, 0, 0, 0, 0, 10, 1, 0,
-  35, 0, 0, 0, 51, 0, 55, 0, 5, 0,
-  0, 0, 0, 0, 28, 1, 16, 0, 30, 0,
-  17, 10, 31, 0, 0, 0, 35, 0, 0, 3,
-  12, 104, 13, 0, 18, 16, 0, 5, 51, 0,
-  33, 3, 0, 0, 0, 16, 0, 15, 0, 9,
-  0, 7, 0, 0, 0, 0, 0, 7, 0, 12,
-  0, 50, 13, 0, 0, 0, 0, 0, 32, 102,
-  0, 61, 0, 0, 22, 15, 0, 0, 0, 0,
-  29, 0, 32, 22, 10, 15, 12, 12, 0, 0,
-  0, 0, 42, 0, 0, 0, 0, 33, 26, 38,
-  0, 3, 31, 0, 30, 10, 63, 12, 0, 0,
-  0, 0, 0, 25, 23, 0, 69, 64, 0, 0,
-  2, 0, 4, 5, 0, 9, 49, 0, 33, 0,
-  0, 3, 60, 0, 68, 0, 0, 0, 8, 0,
-  0, 0, 49, 3, 11, 0, 0, 47, 23, 0,
-  8, 0, 33, 0, 55, 0, 0, 17, 28, 56,
-  45, 66, 49, 49, 0, 15, 78, 0, 0, 46,
-  13, 29, 27, 0, 0, 0, 14, 0, 11, 19,
-  4, 0, 0, 0, 0, 33, 12, 13, 0, 55,
-  6, 0, 0, 0, 0, 0, 63, 12, 64, 29,
-  0, 0, 0, 0, 0, 23, 0, 0, 0, 0,
-  0, 0, 42, 0, 0, 0, 0, 0, 0, 41,
-  36, 0, 0, 29, 0, 27, 65, 51, 36, 6,
-  50, 11, 55, 0, 58, 33, 0, 14, 0, 30,
-  0, 20, 0, 12, 43, 51, 0, 0, 0, 0,
-  0, 0, 5, 6, 14, 33, 30, 0, 0, 0,
-  41, 0, 0, 0, 5, 0, 0, 0, 81, 0,
-  6, 22, 17, 0, 0, 43, 70, 0, 11, 0,
-  9, 0, 57, 6, 0, 0, 0, 60, 23, 63,
-  30, 38, 0, 12, 39, 0, 33, 35, 0, 0,
-  9, 14, 0, 0, 27, 0, 0, 0, 0, 0,
-  0, 17, 0, 12, 27, 0, 0, 40, 0, 0,
-  0, 0, 0, 0, 48, 52, 41, 12, 0, 0,
-  19, 12, 0, 0, 0, 0, 0, 0, 24, 0,
-  45, 0, 11, 4, 0, 0, 0, 28, 32, 0,
-  0, 18, 0, 0, 58, 19, 0, 21, 59, 13,
-  23, 9, 64, 10, 0, 32, 0, 0, 0, 0,
-  0, 0, 40, 51, 0, 0, 0, 0, 36, 0,
-  0, 22, 4, 24, 40, 0, 0, 0, 86, 0,
-  2, 0, 26, 0, 0, 1, 21, 0, 0, 24,
-  22, 0, 0, 1, 54, 0, 0, 0, 0, 0,
-  42, 0, 0, 7, 0, 86, 0, 0, 1, 43,
-  0, 15, 50, 15, 93, 16, 0, 0, 0, 18,
-  0, 0, 16, 0, 0, 0, 0, 0, 0, 25,
-  0, 0, 34, 33, 0, 35, 0, 0, 0, 17,
-  0, 0, 34, 96, 0, 0, 21, 0, 40, 0,
-  14, 0, 0, 2, 21, 0, 100, 23, 1, 3,
-  2, 71, 0, 0, 0, 0, 18, 0, 0, 0,
-  0, 0, 25, 5, 0, 25, 63, 0, 32, 16,
-  62, 0, 0, 28, 0, 0, 0, 0, 0, 0,
-  67, 44, 0, 0, 0, 0, 26, 0, 0, 29,
-  0, 5, 41, 0, 0, 0, 99, 0, 45, 0,
-  46, 0, 0, 13, 0, 0, 0, 6, 19, 0,
-  0, 35, 50, 0, 10, 0, 0, 0, 51, 2,
-  0, 18, 8, 100, 10, 27, 39, 26, 2, 4,
-  44, 0, 34, 24, 0, 0, 0, 5, 0, 0,
-  0, 0, 0, 0, 0, 0, 5, 0, 0, 22,
-  18, 0, 0, 35, 0, 0, 0, 0, 0, 0,
-  52, 66, 0, 34, 0, 0, 6, 2, 0, 0,
-  0, 0, 13, 0, 38, 2, 22, 0, 23, 0,
-  0, 0, 3, 15, 29, 0, 0, 37, 0, 21,
-  32, 48, 11, 18, 40, 3, 53, 7, 75, 6,
-  0, 23, 0, 0, 0, 1, 0, 0, 40, 70,
-  1, 0, 0, 0, 7, 0, 0, 9, 0, 8,
-  32, 0, 0, 0, 57, 0, 10, 0, 12, 0,
-  0, 0, 8, 0, 9, 14, 37, 0, 22, 0,
-  59, 0, 0, 0, 0, 0, 23, 0, 0, 0,
-  0, 116, 1, 0, 6, 27, 1, 0, 38, 30,
-  84, 8, 0, 0, 0, 4, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 2, 0, 0, 28, 17,
-  0, 30, 0, 0, 0, 0, 0, 0, 35, 131,
-  0, 15, 36, 0, 30, 17, 14, 0, 0, 0,
-  34, 0, 88, 47, 7, 2, 16, 67, 0, 0,
-  0, 0, 11, 0, 0, 0, 0, 24, 16, 22,
-  0, 15, 41, 0, 31, 10, 71, 0, 0, 11,
-  2, 0, 0, 5, 0, 0, 62, 66, 0, 0,
-  0, 0, 12, 10, 0, 7, 0, 0, 50, 0,
-  0, 0, 91, 3, 77, 0, 19, 0, 0, 0,
-  0, 0, 21, 6, 10, 0, 20, 0, 19, 16,
-  0, 0, 0, 0, 29, 0, 0, 0, 2, 73,
-  0, 0, 0, 28, 8, 5, 49, 5, 52, 6,
-  0, 0, 0, 7, 0, 12, 6, 1, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 29, 0, 45,
-  0, 0, 0, 16, 0, 0, 39, 114, 0, 30,
-  15, 0, 35, 10, 0, 0, 0, 0, 31, 0,
-  77, 23, 0, 26, 0, 48, 0, 8, 0, 0,
-  25, 0, 0, 0, 0, 24, 31, 18, 0, 15,
-  42, 0, 28, 19, 61, 0, 0, 0, 0, 0,
-  0, 9, 24, 0, 72, 41, 0, 0, 3, 0,
-  0, 0, 0, 13, 37, 0, 43, 0, 0, 5,
-  84, 0, 93, 0, 17, 0, 7, 5, 0, 0,
-  42, 4, 0, 0, 24, 0, 53, 0, 32, 0,
-  0, 0, 25, 0, 0, 1, 9, 122, 15, 0,
-  27, 21, 0, 8, 41, 13, 69, 7, 0, 0,
-  0, 4, 0, 0, 0, 0, 0, 5, 0, 0,
-  0, 4, 0, 26, 14, 10, 0, 48, 14, 0,
-  0, 0, 0, 0, 37, 104, 0, 37, 0, 0,
-  9, 6, 3, 0, 0, 0, 33, 0, 50, 22,
-  0, 0, 24, 22, 0, 1, 0, 0, 27, 0,
-  0, 13, 0, 41, 14, 36, 0, 5, 48, 0,
-  45, 11, 72, 0, 0, 2, 0, 0, 0, 25,
-  0, 0, 41, 57, 0, 0, 0, 0, 0, 0,
-  0, 10, 1, 0, 35, 0, 0, 0, 51, 0,
-  55, 0, 5, 0, 0, 0, 0, 0, 28, 1,
-  16, 0, 30, 0, 17, 10, 31, 0, 0, 0,
-  35, 0, 0, 3, 12, 104, 13, 0, 18, 16,
-  0, 5, 51, 0, 33, 3, 0, 0, 0, 16,
-  0, 15, 0, 9, 0, 7, 0, 0, 0, 0,
-  0, 7, 0, 12, 0, 50, 13, 0, 0, 0,
-  0, 0, 32, 102, 0, 61, 0, 0, 22, 15,
-  0, 0, 0, 0, 29, 0, 32, 22, 10, 15,
-  12, 12, 0, 0, 0, 0, 42, 0, 0, 0,
-  0, 33, 26, 38, 0, 3, 31, 0, 30, 10,
-  63, 12, 0, 0, 0, 0, 0, 25, 23, 0,
-  69, 64, 0, 0, 2, 0, 4, 5, 0, 9,
-  49, 0, 33, 0, 0, 3, 60, 0, 68, 0,
-  0, 0, 8, 0, 0, 0, 49, 3, 11, 0,
-  0, 22, 0, 46, 29, 0, 0, 10, 69, 0,
-  0, 23, 38, 83, 24, 20, 35, 2, 0, 9,
-  58, 0, 0, 0, 4, 48, 0, 23, 0, 8,
-  10, 0, 0, 43, 1, 0, 0, 4, 0, 24,
-  0, 21, 0, 69, 0, 0, 10, 17, 0, 0,
-  39, 72, 4, 92, 0, 0, 6, 27, 0, 37,
-  0, 0, 0, 0, 0, 8, 23, 24, 37, 0,
-  0, 3, 0, 0, 58, 0, 0, 14, 0, 39,
-  58, 70, 0, 0, 36, 5, 31, 21, 43, 20,
-  8, 4, 0, 16, 0, 28, 38, 0, 72, 48,
-  0, 0, 6, 0, 2, 0, 0, 22, 64, 11,
-  22, 0, 0, 9, 42, 0, 28, 0, 0, 0,
-  25, 29, 79, 0, 79, 5, 10, 0, 0, 43,
-  70, 0, 11, 0, 9, 0, 57, 6, 0, 0,
-  0, 60, 23, 63, 30, 38, 0, 12, 39, 0,
-  33, 35, 0, 0, 9, 14, 0, 0, 27, 0,
-  0, 0, 0, 0, 0, 17, 0, 12, 27, 0,
-  0, 40, 0, 0, 0, 0, 0, 0, 48, 52,
-  41, 12, 0, 0, 19, 12, 0, 0, 0, 0,
-  0, 0, 24, 0, 45, 0, 11, 4, 0, 0,
-  0, 28, 32, 0, 0, 18, 0, 0, 58, 19,
-  0, 21, 59, 13, 23, 9, 64, 10, 0, 32,
-  0, 0, 0, 0, 0, 0, 40, 51, 0, 0,
-  0, 0, 36, 0, 0, 22, 4, 24, 40, 0,
-  0, 0, 86, 0, 2, 0, 26, 0, 0, 1,
-  21, 0, 0, 24, 22, 0, 0, 1, 54, 0,
-  0, 0, 0, 0, 42, 0, 0, 7, 0, 86,
-  0, 0, 1, 43, 0, 15, 50, 15, 93, 16,
-  0, 0, 0, 18, 0, 0, 16, 0, 0, 0,
-  0, 0, 0, 25, 0, 0, 34, 33, 0, 35,
-  0, 0, 0, 17, 0, 0, 34, 96, 0, 0,
-  21, 0, 40, 0, 14, 0, 0, 2, 21, 0,
-  100, 23, 1, 3, 2, 71, 0, 0, 0, 0,
-  18, 0, 0, 0, 0, 0, 25, 5, 0, 25,
-  63, 0, 32, 16, 62, 0, 0, 28, 0, 0,
-  0, 0, 0, 0, 67, 44, 0, 0, 0, 0,
-  26, 0, 0, 29, 0, 5, 41, 0, 0, 0,
-  99, 0, 45, 0, 46, 0, 0, 13, 0, 0,
-  0, 6, 19, 0, 16, 0, 16, 11, 0, 0,
-  0, 0, 35, 0, 0, 25, 4, 106, 0, 0,
-  0, 36, 2, 10, 68, 10, 49, 2, 0, 0,
-  0, 0, 0, 0, 0, 2, 0, 9, 0, 0,
-  0, 0, 0, 0, 5, 41, 0, 45, 0, 0,
-  0, 31, 0, 0, 66, 127, 0, 42, 14, 0,
-  16, 0, 2, 0, 0, 0, 48, 0, 110, 32,
-  0, 9, 0, 60, 0, 11, 0, 0, 22, 0,
-  0, 0, 0, 41, 18, 32, 0, 0, 51, 0,
-  58, 18, 81, 0, 0, 0, 0, 0, 0, 12,
-  11, 0, 73, 49, 0, 0, 0, 0, 6, 0,
-  0, 8, 11, 0, 36, 0, 0, 0, 95, 0,
-  70, 0, 20, 0, 1, 0, 0, 0, 8, 0,
-  11, 0, 22, 0, 59, 0, 0, 0, 0, 0,
-  23, 0, 0, 0, 0, 116, 1, 0, 6, 27,
-  1, 0, 38, 30, 84, 8, 0, 0, 0, 4,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 2,
-  0, 0, 28, 17, 0, 30, 0, 0, 0, 0,
-  0, 0, 35, 131, 0, 15, 36, 0, 30, 17,
-  14, 0, 0, 0, 34, 0, 88, 47, 7, 2,
-  16, 67, 0, 0, 0, 0, 11, 0, 0, 0,
-  0, 24, 16, 22, 0, 15, 41, 0, 31, 10,
-  71, 0, 0, 11, 2, 0, 0, 5, 0, 0,
-  62, 66, 0, 0, 0, 0, 12, 10, 0, 7,
-  0, 0, 50, 0, 0, 0, 91, 3, 77, 0,
-  19, 0, 0, 0, 0, 0, 21, 6, 10, 0,
-  20, 0, 19, 16, 0, 0, 0, 0, 29, 0,
-  0, 0, 2, 73, 0, 0, 0, 28, 8, 5,
-  49, 5, 52, 6, 0, 0, 0, 7, 0, 12,
-  6, 1, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 29, 0, 45, 0, 0, 0, 16, 0, 0,
-  39, 114, 0, 30, 15, 0, 35, 10, 0, 0,
-  0, 0, 31, 0, 77, 23, 0, 26, 0, 48,
-  0, 8, 0, 0, 25, 0, 0, 0, 0, 24,
-  31, 18, 0, 15, 42, 0, 28, 19, 61, 0,
-  0, 0, 0, 0, 0, 9, 24, 0, 72, 41,
-  0, 0, 3, 0, 0, 0, 0, 13, 37, 0,
-  43, 0, 0, 5, 84, 0, 93, 0, 17, 0,
-  7, 5, 0, 0, 42, 4, 0, 0, 3, 16,
-  0, 41, 1, 0, 4, 6, 70, 0, 0, 11,
-  25, 55, 18, 0, 14, 4, 17, 0, 52, 0,
-  0, 17, 0, 16, 4, 14, 0, 32, 2, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 25,
-  0, 53, 0, 0, 5, 16, 0, 0, 58, 87,
-  18, 68, 0, 0, 15, 25, 0, 19, 0, 0,
-  0, 0, 0, 11, 7, 13, 8, 0, 0, 9,
-  0, 0, 44, 3, 0, 0, 0, 43, 57, 57,
-  0, 0, 32, 0, 31, 33, 74, 29, 25, 0,
-  0, 0, 0, 11, 45, 0, 71, 48, 0, 0,
-  7, 0, 2, 0, 0, 12, 74, 6, 34, 0,
-  0, 0, 67, 0, 49, 0, 0, 0, 48, 9,
-  63, 0, 76, 0, 5, 0, 30, 0, 17, 10,
-  31, 0, 0, 0, 35, 0, 0, 3, 12, 104,
-  13, 0, 18, 16, 0, 5, 51, 0, 33, 3,
-  0, 0, 0, 16, 0, 15, 0, 9, 0, 7,
-  0, 0, 0, 0, 0, 7, 0, 12, 0, 50,
-  13, 0, 0, 0, 0, 0, 32, 102, 0, 61,
-  0, 0, 22, 15, 0, 0, 0, 0, 29, 0,
-  32, 22, 10, 15, 12, 12, 0, 0, 0, 0,
-  42, 0, 0, 0, 0, 33, 26, 38, 0, 3,
-  31, 0, 30, 10, 63, 12, 0, 0, 0, 0,
-  0, 25, 23, 0, 69, 64, 0, 0, 2, 0,
-  4, 5, 0, 9, 49, 0, 33, 0, 0, 3,
-  60, 0, 68, 0, 0, 0, 8, 0, 0, 0,
-  49, 3, 11, 0, 0, 22, 0, 46, 29, 0,
-  0, 10, 69, 0, 0, 23, 38, 83, 24, 20,
-  35, 2, 0, 9, 58, 0, 0, 0, 4, 48,
-  0, 23, 0, 8, 10, 0, 0, 43, 1, 0,
-  0, 4, 0, 24, 0, 21, 0, 69, 0, 0,
-  10, 17, 0, 0, 39, 72, 4, 92, 0, 0,
-  6, 27, 0, 37, 0, 0, 0, 0, 0, 8,
-  23, 24, 37, 0, 0, 3, 0, 0, 58, 0,
-  0, 14, 0, 39, 58, 70, 0, 0, 36, 5,
-  31, 21, 43, 20, 8, 4, 0, 16, 0, 28,
-  38, 0, 72, 48, 0, 0, 6, 0, 2, 0,
-  0, 22, 64, 11, 22, 0, 0, 9, 42, 0,
-  28, 0, 0, 0, 25, 29, 79, 0, 79, 5,
-  10, 0, 0, 19, 0, 49, 12, 0, 0, 25,
-  85, 2, 1, 7, 23, 85, 32, 34, 52, 0,
-  5, 0, 23, 0, 0, 0, 0, 25, 0, 34,
-  0, 0, 0, 0, 0, 25, 0, 0, 0, 0,
-  0, 23, 0, 6, 0, 46, 0, 0, 22, 18,
-  0, 0, 24, 75, 20, 83, 0, 0, 0, 46,
-  0, 19, 0, 0, 0, 0, 0, 30, 41, 0,
-  59, 0, 0, 0, 0, 12, 50, 0, 0, 9,
-  0, 32, 59, 63, 9, 0, 17, 31, 16, 61,
-  46, 0, 20, 36, 0, 0, 0, 9, 42, 0,
-  48, 63, 0, 0, 0, 0, 9, 0, 0, 19,
-  28, 6, 15, 0, 0, 0, 28, 0, 22, 0,
-  0, 0, 15, 1, 73, 0, 78, 3, 7, 0,
-  0, 1, 54, 0, 0, 0, 0, 0, 42, 0,
-  0, 7, 0, 86, 0, 0, 1, 43, 0, 15,
-  50, 15, 93, 16, 0, 0, 0, 18, 0, 0,
-  16, 0, 0, 0, 0, 0, 0, 25, 0, 0,
-  34, 33, 0, 35, 0, 0, 0, 17, 0, 0,
-  34, 96, 0, 0, 21, 0, 40, 0, 14, 0,
-  0, 2, 21, 0, 100, 23, 1, 3, 2, 71,
-  0, 0, 0, 0, 18, 0, 0, 0, 0, 0,
-  25, 5, 0, 25, 63, 0, 32, 16, 62, 0,
-  0, 28, 0, 0, 0, 0, 0, 0, 67, 44,
-  0, 0, 0, 0, 26, 0, 0, 29, 0, 5,
-  41, 0, 0, 0, 99, 0, 45, 0, 46, 0,
-  0, 13, 0, 0, 0, 6, 19, 0, 16, 0,
-  16, 11, 0, 0, 0, 0, 35, 0, 0, 25,
-  4, 106, 0, 0, 0, 36, 2, 10, 68, 10,
-  49, 2, 0, 0, 0, 0, 0, 0, 0, 2,
-  0, 9, 0, 0, 0, 0, 0, 0, 5, 41,
-  0, 45, 0, 0, 0, 31, 0, 0, 66, 127,
-  0, 42, 14, 0, 16, 0, 2, 0, 0, 0,
-  48, 0, 110, 32, 0, 9, 0, 60, 0, 11,
-  0, 0, 22, 0, 0, 0, 0, 41, 18, 32,
-  0, 0, 51, 0, 58, 18, 81, 0, 0, 0,
-  0, 0, 0, 12, 11, 0, 73, 49, 0, 0,
-  0, 0, 6, 0, 0, 8, 11, 0, 36, 0,
-  0, 0, 95, 0, 70, 0, 20, 0, 1, 0,
-  0, 0, 8, 0, 11, 0, 7, 17, 0, 25,
-  21, 11, 0, 0, 61, 0, 0, 19, 7, 87,
-  0, 0, 0, 20, 13, 16, 69, 0, 0, 19,
-  0, 0, 0, 0, 0, 18, 0, 0, 0, 6,
-  0, 0, 0, 0, 0, 0, 0, 18, 0, 55,
-  0, 0, 10, 38, 0, 0, 71, 103, 0, 69,
-  0, 0, 31, 9, 0, 0, 0, 0, 4, 0,
-  42, 20, 0, 14, 0, 7, 0, 2, 0, 0,
-  39, 0, 0, 0, 0, 43, 31, 45, 9, 0,
-  36, 0, 50, 45, 79, 24, 11, 1, 0, 0,
-  0, 13, 32, 0, 65, 65, 1, 23, 0, 0,
-  0, 0, 0, 13, 64, 0, 7, 0, 0, 0,
-  59, 0, 45, 0, 6, 0, 45, 0, 40, 0,
-  47, 0, 8, 0, 20, 0, 19, 16, 0, 0,
-  0, 0, 29, 0, 0, 0, 2, 73, 0, 0,
-  0, 28, 8, 5, 49, 5, 52, 6, 0, 0,
-  0, 7, 0, 12, 6, 1, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 29, 0, 45, 0, 0,
-  0, 16, 0, 0, 39, 114, 0, 30, 15, 0,
-  35, 10, 0, 0, 0, 0, 31, 0, 77, 23,
-  0, 26, 0, 48, 0, 8, 0, 0, 25, 0,
-  0, 0, 0, 24, 31, 18, 0, 15, 42, 0,
-  28, 19, 61, 0, 0, 0, 0, 0, 0, 9,
-  24, 0, 72, 41, 0, 0, 3, 0, 0, 0,
-  0, 13, 37, 0, 43, 0, 0, 5, 84, 0,
-  93, 0, 17, 0, 7, 5, 0, 0, 42, 4,
-  0, 0, 3, 16, 0, 41, 1, 0, 4, 6,
-  70, 0, 0, 11, 25, 55, 18, 0, 14, 4,
-  17, 0, 52, 0, 0, 17, 0, 16, 4, 14,
-  0, 32, 2, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 25, 0, 53, 0, 0, 5, 16,
-  0, 0, 58, 87, 18, 68, 0, 0, 15, 25,
-  0, 19, 0, 0, 0, 0, 0, 11, 7, 13,
-  8, 0, 0, 9, 0, 0, 44, 3, 0, 0,
-  0, 43, 57, 57, 0, 0, 32, 0, 31, 33,
-  74, 29, 25, 0, 0, 0, 0, 11, 45, 0,
-  71, 48, 0, 0, 7, 0, 2, 0, 0, 12,
-  74, 6, 34, 0, 0, 0, 67, 0, 49, 0,
-  0, 0, 48, 9, 63, 0, 76, 0, 5, 0,
-  0, 29, 0, 36, 17, 0, 0, 1, 82, 0,
-  0, 10, 14, 80, 41, 0, 22, 8, 10, 0,
-  47, 0, 0, 23, 0, 13, 0, 15, 0, 5,
-  0, 0, 0, 11, 0, 0, 0, 0, 0, 11,
-  0, 0, 0, 51, 0, 0, 23, 16, 0, 0,
-  35, 72, 21, 74, 0, 0, 3, 24, 0, 11,
-  0, 0, 0, 0, 0, 21, 29, 0, 30, 0,
-  0, 0, 0, 0, 58, 0, 0, 0, 0, 30,
-  56, 60, 4, 0, 25, 0, 29, 51, 61, 17,
-  7, 13, 0, 0, 0, 14, 29, 0, 67, 43,
-  0, 16, 0, 0, 10, 1, 0, 7, 54, 13,
-  18, 0, 0, 0, 34, 0, 15, 0, 0, 0,
-  35, 0, 63, 0, 64, 0, 8, 0, 0, 22,
-  0, 46, 29, 0, 0, 10, 69, 0, 0, 23,
-  38, 83, 24, 20, 35, 2, 0, 9, 58, 0,
-  0, 0, 4, 48, 0, 23, 0, 8, 10, 0,
-  0, 43, 1, 0, 0, 4, 0, 24, 0, 21,
-  0, 69, 0, 0, 10, 17, 0, 0, 39, 72,
-  4, 92, 0, 0, 6, 27, 0, 37, 0, 0,
-  0, 0, 0, 8, 23, 24, 37, 0, 0, 3,
-  0, 0, 58, 0, 0, 14, 0, 39, 58, 70,
-  0, 0, 36, 5, 31, 21, 43, 20, 8, 4,
-  0, 16, 0, 28, 38, 0, 72, 48, 0, 0,
-  6, 0, 2, 0, 0, 22, 64, 11, 22, 0,
-  0, 9, 42, 0, 28, 0, 0, 0, 25, 29,
-  79, 0, 79, 5, 10, 0, 0, 19, 0, 49,
-  12, 0, 0, 25, 85, 2, 1, 7, 23, 85,
-  32, 34, 52, 0, 5, 0, 23, 0, 0, 0,
-  0, 25, 0, 34, 0, 0, 0, 0, 0, 25,
-  0, 0, 0, 0, 0, 23, 0, 6, 0, 46,
-  0, 0, 22, 18, 0, 0, 24, 75, 20, 83,
-  0, 0, 0, 46, 0, 19, 0, 0, 0, 0,
-  0, 30, 41, 0, 59, 0, 0, 0, 0, 12,
-  50, 0, 0, 9, 0, 32, 59, 63, 9, 0,
-  17, 31, 16, 61, 46, 0, 20, 36, 0, 0,
-  0, 9, 42, 0, 48, 63, 0, 0, 0, 0,
-  9, 0, 0, 19, 28, 6, 15, 0, 0, 0,
-  28, 0, 22, 0, 0, 0, 15, 1, 73, 0,
-  78, 3, 7, 0, 0, 4, 2, 46, 13, 0,
-  0, 32, 107, 4, 2, 0, 4, 83, 44, 32,
-  46, 4, 0, 0, 3, 0, 0, 10, 0, 0,
-  0, 35, 0, 0, 0, 0, 0, 15, 0, 0,
-  0, 0, 0, 24, 0, 0, 0, 32, 0, 0,
-  49, 17, 0, 0, 0, 80, 25, 73, 0, 0,
-  0, 50, 0, 3, 0, 0, 0, 0, 0, 35,
-  49, 0, 61, 9, 0, 0, 3, 17, 57, 9,
-  0, 0, 0, 10, 48, 46, 9, 0, 7, 32,
-  17, 79, 43, 0, 37, 35, 0, 0, 0, 5,
-  31, 0, 49, 67, 11, 1, 0, 0, 15, 0,
-  0, 19, 8, 3, 5, 0, 0, 0, 19, 0,
-  26, 0, 0, 0, 5, 0, 65, 0, 62, 0,
-  2, 0, 16, 0, 16, 11, 0, 0, 0, 0,
-  35, 0, 0, 25, 4, 106, 0, 0, 0, 36,
-  2, 10, 68, 10, 49, 2, 0, 0, 0, 0,
-  0, 0, 0, 2, 0, 9, 0, 0, 0, 0,
-  0, 0, 5, 41, 0, 45, 0, 0, 0, 31,
-  0, 0, 66, 127, 0, 42, 14, 0, 16, 0,
-  2, 0, 0, 0, 48, 0, 110, 32, 0, 9,
-  0, 60, 0, 11, 0, 0, 22, 0, 0, 0,
-  0, 41, 18, 32, 0, 0, 51, 0, 58, 18,
-  81, 0, 0, 0, 0, 0, 0, 12, 11, 0,
-  73, 49, 0, 0, 0, 0, 6, 0, 0, 8,
-  11, 0, 36, 0, 0, 0, 95, 0, 70, 0,
-  20, 0, 1, 0, 0, 0, 8, 0, 11, 0,
-  7, 17, 0, 25, 21, 11, 0, 0, 61, 0,
-  0, 19, 7, 87, 0, 0, 0, 20, 13, 16,
-  69, 0, 0, 19, 0, 0, 0, 0, 0, 18,
-  0, 0, 0, 6, 0, 0, 0, 0, 0, 0,
-  0, 18, 0, 55, 0, 0, 10, 38, 0, 0,
-  71, 103, 0, 69, 0, 0, 31, 9, 0, 0,
-  0, 0, 4, 0, 42, 20, 0, 14, 0, 7,
-  0, 2, 0, 0, 39, 0, 0, 0, 0, 43,
-  31, 45, 9, 0, 36, 0, 50, 45, 79, 24,
-  11, 1, 0, 0, 0, 13, 32, 0, 65, 65,
-  1, 23, 0, 0, 0, 0, 0, 13, 64, 0,
-  7, 0, 0, 0, 59, 0, 45, 0, 6, 0,
-  45, 0, 40, 0, 47, 0, 8, 0, 0, 108,
-  0, 50, 20, 0, 23, 0, 76, 0, 5, 27,
-  31, 30, 12, 0, 0, 17, 12, 30, 55, 0,
-  0, 56, 13, 61, 39, 0, 0, 26, 15, 0,
-  27, 4, 0, 0, 0, 0, 0, 5, 0, 21,
-  0, 47, 11, 0, 10, 19, 0, 0, 54, 49,
-  57, 86, 0, 0, 20, 0, 0, 49, 9, 0,
-  0, 0, 0, 0, 32, 13, 0, 0, 0, 12,
-  0, 0, 51, 32, 0, 0, 0, 19, 65, 67,
-  24, 0, 19, 0, 39, 50, 52, 88, 74, 0,
-  0, 18, 0, 13, 42, 0, 60, 63, 11, 32,
-  0, 0, 0, 0, 14, 25, 123, 40, 2, 0,
-  0, 0, 13, 0, 5, 0, 0, 0, 42, 3,
-  144, 0, 86, 0, 0, 0, 3, 16, 0, 41,
-  1, 0, 4, 6, 70, 0, 0, 11, 25, 55,
-  18, 0, 14, 4, 17, 0, 52, 0, 0, 17,
-  0, 16, 4, 14, 0, 32, 2, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 25, 0, 53,
-  0, 0, 5, 16, 0, 0, 58, 87, 18, 68,
-  0, 0, 15, 25, 0, 19, 0, 0, 0, 0,
-  0, 11, 7, 13, 8, 0, 0, 9, 0, 0,
-  44, 3, 0, 0, 0, 43, 57, 57, 0, 0,
-  32, 0, 31, 33, 74, 29, 25, 0, 0, 0,
-  0, 11, 45, 0, 71, 48, 0, 0, 7, 0,
-  2, 0, 0, 12, 74, 6, 34, 0, 0, 0,
-  67, 0, 49, 0, 0, 0, 48, 9, 63, 0,
-  76, 0, 5, 0, 0, 29, 0, 36, 17, 0,
-  0, 1, 82, 0, 0, 10, 14, 80, 41, 0,
-  22, 8, 10, 0, 47, 0, 0, 23, 0, 13,
-  0, 15, 0, 5, 0, 0, 0, 11, 0, 0,
-  0, 0, 0, 11, 0, 0, 0, 51, 0, 0,
-  23, 16, 0, 0, 35, 72, 21, 74, 0, 0,
-  3, 24, 0, 11, 0, 0, 0, 0, 0, 21,
-  29, 0, 30, 0, 0, 0, 0, 0, 58, 0,
-  0, 0, 0, 30, 56, 60, 4, 0, 25, 0,
-  29, 51, 61, 17, 7, 13, 0, 0, 0, 14,
-  29, 0, 67, 43, 0, 16, 0, 0, 10, 1,
-  0, 7, 54, 13, 18, 0, 0, 0, 34, 0,
-  15, 0, 0, 0, 35, 0, 63, 0, 64, 0,
-  8, 0, 0, 64, 0, 40, 20, 0, 10, 0,
-  63, 0, 7, 15, 12, 65, 48, 6, 31, 34,
-  0, 25, 58, 0, 0, 21, 0, 36, 3, 4,
-  0, 0, 0, 0, 0, 32, 0, 0, 0, 0,
-  0, 11, 0, 0, 0, 41, 0, 0, 21, 22,
-  0, 0, 26, 26, 28, 76, 0, 0, 10, 4,
-  0, 25, 19, 0, 0, 0, 0, 11, 55, 3,
-  50, 0, 0, 0, 0, 0, 62, 0, 0, 0,
-  0, 3, 57, 69, 4, 0, 25, 19, 41, 29,
-  30, 12, 0, 34, 0, 1, 0, 24, 19, 0,
-  63, 30, 0, 19, 0, 0, 12, 0, 3, 1,
-  34, 21, 0, 0, 0, 0, 15, 0, 0, 0,
-  0, 0, 0, 13, 75, 0, 41, 0, 17, 0,
-  0, 19, 0, 49, 12, 0, 0, 25, 85, 2,
-  1, 7, 23, 85, 32, 34, 52, 0, 5, 0,
-  23, 0, 0, 0, 0, 25, 0, 34, 0, 0,
-  0, 0, 0, 25, 0, 0, 0, 0, 0, 23,
-  0, 6, 0, 46, 0, 0, 22, 18, 0, 0,
-  24, 75, 20, 83, 0, 0, 0, 46, 0, 19,
-  0, 0, 0, 0, 0, 30, 41, 0, 59, 0,
-  0, 0, 0, 12, 50, 0, 0, 9, 0, 32,
-  59, 63, 9, 0, 17, 31, 16, 61, 46, 0,
-  20, 36, 0, 0, 0, 9, 42, 0, 48, 63,
-  0, 0, 0, 0, 9, 0, 0, 19, 28, 6,
-  15, 0, 0, 0, 28, 0, 22, 0, 0, 0,
-  15, 1, 73, 0, 78, 3, 7, 0, 0, 4,
-  2, 46, 13, 0, 0, 32, 107, 4, 2, 0,
-  4, 83, 44, 32, 46, 4, 0, 0, 3, 0,
-  0, 10, 0, 0, 0, 35, 0, 0, 0, 0,
-  0, 15, 0, 0, 0, 0, 0, 24, 0, 0,
-  0, 32, 0, 0, 49, 17, 0, 0, 0, 80,
-  25, 73, 0, 0, 0, 50, 0, 3, 0, 0,
-  0, 0, 0, 35, 49, 0, 61, 9, 0, 0,
-  3, 17, 57, 9, 0, 0, 0, 10, 48, 46,
-  9, 0, 7, 32, 17, 79, 43, 0, 37, 35,
-  0, 0, 0, 5, 31, 0, 49, 67, 11, 1,
-  0, 0, 15, 0, 0, 19, 8, 3, 5, 0,
-  0, 0, 19, 0, 26, 0, 0, 0, 5, 0,
-  65, 0, 62, 0, 2, 0, 0, 37, 0, 44,
-  22, 0, 8, 20, 82, 0, 25, 11, 12, 56,
-  55, 36, 59, 22, 0, 12, 31, 0, 0, 0,
-  1, 27, 0, 18, 0, 0, 0, 0, 0, 37,
-  0, 0, 0, 0, 0, 14, 0, 0, 0, 28,
-  0, 0, 38, 1, 0, 0, 0, 23, 0, 87,
-  0, 0, 4, 32, 0, 38, 0, 0, 0, 0,
-  0, 27, 62, 7, 79, 0, 0, 0, 0, 8,
-  73, 0, 0, 19, 6, 1, 28, 74, 0, 0,
-  22, 50, 31, 43, 10, 0, 10, 37, 0, 20,
-  0, 33, 31, 10, 59, 36, 0, 0, 0, 0,
-  17, 0, 0, 13, 9, 1, 0, 0, 0, 0,
-  9, 0, 0, 0, 0, 0, 0, 23, 74, 0,
-  31, 0, 36, 0, 7, 17, 0, 25, 21, 11,
-  0, 0, 61, 0, 0, 19, 7, 87, 0, 0,
-  0, 20, 13, 16, 69, 0, 0, 19, 0, 0,
-  0, 0, 0, 18, 0, 0, 0, 6, 0, 0,
-  0, 0, 0, 0, 0, 18, 0, 55, 0, 0,
-  10, 38, 0, 0, 71, 103, 0, 69, 0, 0,
-  31, 9, 0, 0, 0, 0, 4, 0, 42, 20,
-  0, 14, 0, 7, 0, 2, 0, 0, 39, 0,
-  0, 0, 0, 43, 31, 45, 9, 0, 36, 0,
-  50, 45, 79, 24, 11, 1, 0, 0, 0, 13,
-  32, 0, 65, 65, 1, 23, 0, 0, 0, 0,
-  0, 13, 64, 0, 7, 0, 0, 0, 59, 0,
-  45, 0, 6, 0, 45, 0, 40, 0, 47, 0,
-  8, 0, 0, 108, 0, 50, 20, 0, 23, 0,
-  76, 0, 5, 27, 31, 30, 12, 0, 0, 17,
-  12, 30, 55, 0, 0, 56, 13, 61, 39, 0,
-  0, 26, 15, 0, 27, 4, 0, 0, 0, 0,
-  0, 5, 0, 21, 0, 47, 11, 0, 10, 19,
-  0, 0, 54, 49, 57, 86, 0, 0, 20, 0,
-  0, 49, 9, 0, 0, 0, 0, 0, 32, 13,
-  0, 0, 0, 12, 0, 0, 51, 32, 0, 0,
-  0, 19, 65, 67, 24, 0, 19, 0, 39, 50,
-  52, 88, 74, 0, 0, 18, 0, 13, 42, 0,
-  60, 63, 11, 32, 0, 0, 0, 0, 14, 25,
-  123, 40, 2, 0, 0, 0, 13, 0, 5, 0,
-  0, 0, 42, 3, 144, 0, 86, 0, 0, 0,
-  0, 155, 0, 57, 4, 0, 35, 0, 65, 0,
-  13, 22, 77, 0, 0, 0, 0, 12, 22, 43,
-  12, 0, 0, 61, 29, 33, 73, 13, 3, 0,
-  36, 0, 52, 0, 38, 0, 0, 0, 0, 0,
-  0, 22, 0, 53, 11, 0, 16, 0, 0, 0,
-  43, 52, 47, 51, 11, 17, 36, 0, 0, 49,
-  1, 0, 0, 0, 0, 0, 2, 16, 0, 0,
-  11, 34, 0, 0, 39, 55, 0, 69, 4, 0,
-  37, 56, 49, 10, 11, 0, 0, 58, 72, 93,
-  137, 0, 0, 11, 0, 0, 57, 0, 44, 81,
-  42, 39, 0, 0, 0, 0, 27, 70, 152, 18,
-  4, 0, 17, 10, 0, 0, 0, 0, 0, 0,
-  3, 0, 133, 2, 119, 5, 0, 0, 0, 29,
-  0, 36, 17, 0, 0, 1, 82, 0, 0, 10,
-  14, 80, 41, 0, 22, 8, 10, 0, 47, 0,
-  0, 23, 0, 13, 0, 15, 0, 5, 0, 0,
-  0, 11, 0, 0, 0, 0, 0, 11, 0, 0,
-  0, 51, 0, 0, 23, 16, 0, 0, 35, 72,
-  21, 74, 0, 0, 3, 24, 0, 11, 0, 0,
-  0, 0, 0, 21, 29, 0, 30, 0, 0, 0,
-  0, 0, 58, 0, 0, 0, 0, 30, 56, 60,
-  4, 0, 25, 0, 29, 51, 61, 17, 7, 13,
-  0, 0, 0, 14, 29, 0, 67, 43, 0, 16,
-  0, 0, 10, 1, 0, 7, 54, 13, 18, 0,
-  0, 0, 34, 0, 15, 0, 0, 0, 35, 0,
-  63, 0, 64, 0, 8, 0, 0, 64, 0, 40,
-  20, 0, 10, 0, 63, 0, 7, 15, 12, 65,
-  48, 6, 31, 34, 0, 25, 58, 0, 0, 21,
-  0, 36, 3, 4, 0, 0, 0, 0, 0, 32,
-  0, 0, 0, 0, 0, 11, 0, 0, 0, 41,
-  0, 0, 21, 22, 0, 0, 26, 26, 28, 76,
-  0, 0, 10, 4, 0, 25, 19, 0, 0, 0,
-  0, 11, 55, 3, 50, 0, 0, 0, 0, 0,
-  62, 0, 0, 0, 0, 3, 57, 69, 4, 0,
-  25, 19, 41, 29, 30, 12, 0, 34, 0, 1,
-  0, 24, 19, 0, 63, 30, 0, 19, 0, 0,
-  12, 0, 3, 1, 34, 21, 0, 0, 0, 0,
-  15, 0, 0, 0, 0, 0, 0, 13, 75, 0,
-  41, 0, 17, 0, 0, 151, 1, 57, 8, 0,
-  17, 0, 42, 0, 26, 0, 19, 37, 38, 18,
-  29, 7, 6, 53, 10, 0, 0, 24, 1, 37,
-  15, 7, 0, 0, 0, 0, 46, 5, 0, 0,
-  0, 0, 0, 1, 0, 2, 0, 21, 0, 0,
-  21, 42, 0, 0, 40, 0, 12, 89, 0, 0,
-  18, 1, 0, 44, 24, 0, 0, 0, 0, 0,
-  73, 21, 53, 0, 0, 0, 0, 8, 68, 12,
-  0, 35, 0, 18, 49, 62, 21, 11, 30, 33,
-  16, 49, 19, 13, 53, 22, 0, 17, 0, 5,
-  44, 0, 24, 80, 3, 46, 0, 0, 12, 0,
-  22, 12, 52, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 89, 0, 51, 0,
-  16, 1, 0, 4, 2, 46, 13, 0, 0, 32,
-  107, 4, 2, 0, 4, 83, 44, 32, 46, 4,
-  0, 0, 3, 0, 0, 10, 0, 0, 0, 35,
-  0, 0, 0, 0, 0, 15, 0, 0, 0, 0,
-  0, 24, 0, 0, 0, 32, 0, 0, 49, 17,
-  0, 0, 0, 80, 25, 73, 0, 0, 0, 50,
-  0, 3, 0, 0, 0, 0, 0, 35, 49, 0,
-  61, 9, 0, 0, 3, 17, 57, 9, 0, 0,
-  0, 10, 48, 46, 9, 0, 7, 32, 17, 79,
-  43, 0, 37, 35, 0, 0, 0, 5, 31, 0,
-  49, 67, 11, 1, 0, 0, 15, 0, 0, 19,
-  8, 3, 5, 0, 0, 0, 19, 0, 26, 0,
-  0, 0, 5, 0, 65, 0, 62, 0, 2, 0,
-  0, 37, 0, 44, 22, 0, 8, 20, 82, 0,
-  25, 11, 12, 56, 55, 36, 59, 22, 0, 12,
-  31, 0, 0, 0, 1, 27, 0, 18, 0, 0,
-  0, 0, 0, 37, 0, 0, 0, 0, 0, 14,
-  0, 0, 0, 28, 0, 0, 38, 1, 0, 0,
-  0, 23, 0, 87, 0, 0, 4, 32, 0, 38,
-  0, 0, 0, 0, 0, 27, 62, 7, 79, 0,
-  0, 0, 0, 8, 73, 0, 0, 19, 6, 1,
-  28, 74, 0, 0, 22, 50, 31, 43, 10, 0,
-  10, 37, 0, 20, 0, 33, 31, 10, 59, 36,
-  0, 0, 0, 0, 17, 0, 0, 13, 9, 1,
-  0, 0, 0, 0, 9, 0, 0, 0, 0, 0,
-  0, 23, 74, 0, 31, 0, 36, 0, 0, 74,
-  18, 48, 36, 0, 9, 0, 60, 0, 36, 0,
-  0, 63, 66, 33, 53, 1, 1, 40, 5, 0,
-  0, 0, 0, 29, 0, 0, 0, 0, 0, 0,
-  0, 33, 0, 0, 0, 0, 0, 13, 0, 0,
-  0, 7, 0, 0, 40, 19, 0, 0, 0, 0,
-  0, 107, 0, 0, 12, 52, 0, 31, 0, 27,
-  0, 0, 0, 19, 66, 8, 85, 0, 0, 0,
-  0, 0, 65, 0, 0, 12, 15, 13, 23, 55,
-  0, 0, 38, 70, 22, 57, 6, 0, 10, 41,
-  0, 20, 0, 27, 34, 9, 25, 65, 0, 0,
-  0, 0, 11, 0, 0, 0, 15, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  46, 0, 22, 0, 42, 0, 0, 108, 0, 50,
-  20, 0, 23, 0, 76, 0, 5, 27, 31, 30,
-  12, 0, 0, 17, 12, 30, 55, 0, 0, 56,
-  13, 61, 39, 0, 0, 26, 15, 0, 27, 4,
-  0, 0, 0, 0, 0, 5, 0, 21, 0, 47,
-  11, 0, 10, 19, 0, 0, 54, 49, 57, 86,
-  0, 0, 20, 0, 0, 49, 9, 0, 0, 0,
-  0, 0, 32, 13, 0, 0, 0, 12, 0, 0,
-  51, 32, 0, 0, 0, 19, 65, 67, 24, 0,
-  19, 0, 39, 50, 52, 88, 74, 0, 0, 18,
-  0, 13, 42, 0, 60, 63, 11, 32, 0, 0,
-  0, 0, 14, 25, 123, 40, 2, 0, 0, 0,
-  13, 0, 5, 0, 0, 0, 42, 3, 144, 0,
-  86, 0, 0, 0, 0, 155, 0, 57, 4, 0,
-  35, 0, 65, 0, 13, 22, 77, 0, 0, 0,
-  0, 12, 22, 43, 12, 0, 0, 61, 29, 33,
-  73, 13, 3, 0, 36, 0, 52, 0, 38, 0,
-  0, 0, 0, 0, 0, 22, 0, 53, 11, 0,
-  16, 0, 0, 0, 43, 52, 47, 51, 11, 17,
-  36, 0, 0, 49, 1, 0, 0, 0, 0, 0,
-  2, 16, 0, 0, 11, 34, 0, 0, 39, 55,
-  0, 69, 4, 0, 37, 56, 49, 10, 11, 0,
-  0, 58, 72, 93, 137, 0, 0, 11, 0, 0,
-  57, 0, 44, 81, 42, 39, 0, 0, 0, 0,
-  27, 70, 152, 18, 4, 0, 17, 10, 0, 0,
-  0, 0, 0, 0, 3, 0, 133, 2, 119, 5,
-  0, 0, 21, 77, 0, 54, 0, 57, 1, 0,
-  24, 0, 0, 9, 43, 0, 0, 0, 0, 20,
-  47, 27, 0, 27, 1, 0, 0, 0, 69, 0,
-  0, 0, 4, 19, 15, 0, 32, 49, 0, 0,
-  3, 0, 0, 7, 0, 34, 8, 10, 16, 0,
-  0, 0, 3, 45, 0, 0, 93, 35, 51, 0,
-  0, 0, 0, 53, 20, 0, 103, 0, 0, 43,
-  0, 68, 175, 29, 22, 0, 0, 35, 0, 61,
-  4, 6, 0, 0, 64, 5, 21, 0, 0, 19,
-  51, 0, 81, 0, 0, 0, 7, 0, 55, 0,
-  12, 95, 28, 106, 1, 0, 0, 0, 4, 67,
-  71, 0, 2, 16, 0, 39, 0, 0, 0, 0,
-  25, 0, 0, 0, 0, 18, 65, 17, 0, 0,
-  0, 64, 0, 40, 20, 0, 10, 0, 63, 0,
-  7, 15, 12, 65, 48, 6, 31, 34, 0, 25,
-  58, 0, 0, 21, 0, 36, 3, 4, 0, 0,
-  0, 0, 0, 32, 0, 0, 0, 0, 0, 11,
-  0, 0, 0, 41, 0, 0, 21, 22, 0, 0,
-  26, 26, 28, 76, 0, 0, 10, 4, 0, 25,
-  19, 0, 0, 0, 0, 11, 55, 3, 50, 0,
-  0, 0, 0, 0, 62, 0, 0, 0, 0, 3,
-  57, 69, 4, 0, 25, 19, 41, 29, 30, 12,
-  0, 34, 0, 1, 0, 24, 19, 0, 63, 30,
-  0, 19, 0, 0, 12, 0, 3, 1, 34, 21,
-  0, 0, 0, 0, 15, 0, 0, 0, 0, 0,
-  0, 13, 75, 0, 41, 0, 17, 0, 0, 151,
-  1, 57, 8, 0, 17, 0, 42, 0, 26, 0,
-  19, 37, 38, 18, 29, 7, 6, 53, 10, 0,
-  0, 24, 1, 37, 15, 7, 0, 0, 0, 0,
-  46, 5, 0, 0, 0, 0, 0, 1, 0, 2,
-  0, 21, 0, 0, 21, 42, 0, 0, 40, 0,
-  12, 89, 0, 0, 18, 1, 0, 44, 24, 0,
-  0, 0, 0, 0, 73, 21, 53, 0, 0, 0,
-  0, 8, 68, 12, 0, 35, 0, 18, 49, 62,
-  21, 11, 30, 33, 16, 49, 19, 13, 53, 22,
-  0, 17, 0, 5, 44, 0, 24, 80, 3, 46,
-  0, 0, 12, 0, 22, 12, 52, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  89, 0, 51, 0, 16, 1, 6, 145, 0, 66,
-  0, 25, 0, 0, 52, 0, 6, 0, 69, 0,
-  0, 0, 0, 5, 33, 32, 0, 0, 14, 32,
-  3, 0, 70, 0, 0, 0, 0, 0, 77, 0,
-  13, 38, 0, 0, 0, 0, 0, 17, 0, 19,
-  0, 15, 48, 19, 0, 17, 5, 25, 0, 35,
-  17, 0, 54, 0, 0, 16, 0, 0, 0, 0,
-  16, 0, 16, 19, 0, 1, 65, 17, 3, 0,
-  34, 29, 0, 94, 0, 16, 0, 0, 90, 39,
-  0, 18, 0, 41, 51, 18, 99, 0, 0, 0,
-  0, 0, 61, 0, 18, 99, 42, 59, 0, 0,
-  0, 10, 57, 44, 87, 0, 0, 0, 0, 36,
-  0, 0, 0, 0, 5, 0, 3, 0, 48, 0,
-  39, 0, 0, 46, 0, 37, 0, 44, 22, 0,
-  8, 20, 82, 0, 25, 11, 12, 56, 55, 36,
-  59, 22, 0, 12, 31, 0, 0, 0, 1, 27,
-  0, 18, 0, 0, 0, 0, 0, 37, 0, 0,
-  0, 0, 0, 14, 0, 0, 0, 28, 0, 0,
-  38, 1, 0, 0, 0, 23, 0, 87, 0, 0,
-  4, 32, 0, 38, 0, 0, 0, 0, 0, 27,
-  62, 7, 79, 0, 0, 0, 0, 8, 73, 0,
-  0, 19, 6, 1, 28, 74, 0, 0, 22, 50,
-  31, 43, 10, 0, 10, 37, 0, 20, 0, 33,
-  31, 10, 59, 36, 0, 0, 0, 0, 17, 0,
-  0, 13, 9, 1, 0, 0, 0, 0, 9, 0,
-  0, 0, 0, 0, 0, 23, 74, 0, 31, 0,
-  36, 0, 0, 74, 18, 48, 36, 0, 9, 0,
-  60, 0, 36, 0, 0, 63, 66, 33, 53, 1,
-  1, 40, 5, 0, 0, 0, 0, 29, 0, 0,
-  0, 0, 0, 0, 0, 33, 0, 0, 0, 0,
-  0, 13, 0, 0, 0, 7, 0, 0, 40, 19,
-  0, 0, 0, 0, 0, 107, 0, 0, 12, 52,
-  0, 31, 0, 27, 0, 0, 0, 19, 66, 8,
-  85, 0, 0, 0, 0, 0, 65, 0, 0, 12,
-  15, 13, 23, 55, 0, 0, 38, 70, 22, 57,
-  6, 0, 10, 41, 0, 20, 0, 27, 34, 9,
-  25, 65, 0, 0, 0, 0, 11, 0, 0, 0,
-  15, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 46, 0, 22, 0, 42, 0,
-  0, 120, 19, 74, 27, 0, 31, 0, 61, 0,
-  8, 0, 21, 27, 26, 43, 32, 22, 11, 48,
-  0, 0, 11, 13, 20, 2, 39, 1, 0, 0,
-  0, 0, 45, 5, 15, 2, 0, 0, 0, 0,
-  0, 0, 0, 21, 0, 27, 87, 36, 0, 0,
-  16, 0, 0, 39, 0, 0, 30, 0, 0, 50,
-  0, 22, 0, 0, 0, 0, 32, 15, 38, 0,
-  0, 0, 27, 0, 82, 16, 0, 44, 0, 0,
-  23, 10, 32, 10, 15, 51, 24, 38, 8, 39,
-  22, 24, 0, 47, 0, 0, 15, 0, 42, 41,
-  18, 5, 0, 0, 5, 0, 39, 13, 35, 22,
-  0, 0, 0, 45, 0, 0, 0, 0, 9, 0,
-  0, 0, 49, 0, 6, 0, 21, 9, 0, 155,
-  0, 57, 4, 0, 35, 0, 65, 0, 13, 22,
-  77, 0, 0, 0, 0, 12, 22, 43, 12, 0,
-  0, 61, 29, 33, 73, 13, 3, 0, 36, 0,
-  52, 0, 38, 0, 0, 0, 0, 0, 0, 22,
-  0, 53, 11, 0, 16, 0, 0, 0, 43, 52,
-  47, 51, 11, 17, 36, 0, 0, 49, 1, 0,
-  0, 0, 0, 0, 2, 16, 0, 0, 11, 34,
-  0, 0, 39, 55, 0, 69, 4, 0, 37, 56,
-  49, 10, 11, 0, 0, 58, 72, 93, 137, 0,
-  0, 11, 0, 0, 57, 0, 44, 81, 42, 39,
-  0, 0, 0, 0, 27, 70, 152, 18, 4, 0,
-  17, 10, 0, 0, 0, 0, 0, 0, 3, 0,
-  133, 2, 119, 5, 0, 0, 21, 77, 0, 54,
-  0, 57, 1, 0, 24, 0, 0, 9, 43, 0,
-  0, 0, 0, 20, 47, 27, 0, 27, 1, 0,
-  0, 0, 69, 0, 0, 0, 4, 19, 15, 0,
-  32, 49, 0, 0, 3, 0, 0, 7, 0, 34,
-  8, 10, 16, 0, 0, 0, 3, 45, 0, 0,
-  93, 35, 51, 0, 0, 0, 0, 53, 20, 0,
-  103, 0, 0, 43, 0, 68, 175, 29, 22, 0,
-  0, 35, 0, 61, 4, 6, 0, 0, 64, 5,
-  21, 0, 0, 19, 51, 0, 81, 0, 0, 0,
-  7, 0, 55, 0, 12, 95, 28, 106, 1, 0,
-  0, 0, 4, 67, 71, 0, 2, 16, 0, 39,
-  0, 0, 0, 0, 25, 0, 0, 0, 0, 18,
-  65, 17, 0, 0, 0, 0, 0, 25, 0, 135,
-  0, 7, 42, 0, 0, 4, 0, 6, 0, 0,
-  0, 25, 13, 0, 41, 106, 15, 0, 0, 0,
-  0, 1, 0, 0, 0, 1, 9, 0, 0, 82,
-  0, 40, 0, 0, 45, 0, 0, 46, 0, 80,
-  0, 4, 0, 0, 0, 52, 0, 0, 133, 36,
-  44, 0, 57, 0, 0, 92, 42, 0, 155, 0,
-  0, 30, 0, 77, 196, 0, 59, 34, 0, 31,
-  0, 16, 9, 0, 0, 0, 35, 0, 0, 0,
-  1, 0, 11, 0, 0, 92, 0, 0, 27, 0,
-  0, 0, 7, 76, 78, 108, 0, 0, 0, 0,
-  0, 30, 0, 0, 0, 38, 0, 95, 0, 0,
-  0, 0, 52, 0, 0, 0, 0, 0, 21, 0,
-  0, 6, 0, 151, 1, 57, 8, 0, 17, 0,
-  42, 0, 26, 0, 19, 37, 38, 18, 29, 7,
-  6, 53, 10, 0, 0, 24, 1, 37, 15, 7,
-  0, 0, 0, 0, 46, 5, 0, 0, 0, 0,
-  0, 1, 0, 2, 0, 21, 0, 0, 21, 42,
-  0, 0, 40, 0, 12, 89, 0, 0, 18, 1,
-  0, 44, 24, 0, 0, 0, 0, 0, 73, 21,
-  53, 0, 0, 0, 0, 8, 68, 12, 0, 35,
-  0, 18, 49, 62, 21, 11, 30, 33, 16, 49,
-  19, 13, 53, 22, 0, 17, 0, 5, 44, 0,
-  24, 80, 3, 46, 0, 0, 12, 0, 22, 12,
-  52, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 89, 0, 51, 0, 16, 1,
-  6, 145, 0, 66, 0, 25, 0, 0, 52, 0,
-  6, 0, 69, 0, 0, 0, 0, 5, 33, 32,
-  0, 0, 14, 32, 3, 0, 70, 0, 0, 0,
-  0, 0, 77, 0, 13, 38, 0, 0, 0, 0,
-  0, 17, 0, 19, 0, 15, 48, 19, 0, 17,
-  5, 25, 0, 35, 17, 0, 54, 0, 0, 16,
-  0, 0, 0, 0, 16, 0, 16, 19, 0, 1,
-  65, 17, 3, 0, 34, 29, 0, 94, 0, 16,
-  0, 0, 90, 39, 0, 18, 0, 41, 51, 18,
-  99, 0, 0, 0, 0, 0, 61, 0, 18, 99,
-  42, 59, 0, 0, 0, 10, 57, 44, 87, 0,
-  0, 0, 0, 36, 0, 0, 0, 0, 5, 0,
-  3, 0, 48, 0, 39, 0, 0, 46, 58, 21,
-  0, 68, 2, 105, 0, 4, 38, 0, 0, 0,
-  40, 0, 0, 0, 2, 21, 35, 0, 0, 90,
-  13, 0, 0, 0, 31, 0, 9, 0, 0, 31,
-  3, 0, 67, 72, 9, 0, 27, 0, 20, 14,
-  0, 28, 22, 53, 41, 0, 0, 0, 0, 61,
-  0, 0, 135, 38, 37, 0, 7, 0, 0, 47,
-  34, 0, 96, 0, 0, 31, 0, 47, 198, 6,
-  55, 0, 0, 0, 0, 35, 0, 0, 0, 0,
-  77, 27, 31, 0, 1, 1, 38, 0, 0, 15,
-  0, 0, 17, 0, 39, 0, 26, 71, 33, 77,
-  0, 0, 0, 0, 6, 46, 5, 0, 19, 40,
-  0, 88, 0, 0, 0, 0, 55, 0, 0, 0,
-  0, 0, 28, 0, 0, 16, 0, 74, 18, 48,
-  36, 0, 9, 0, 60, 0, 36, 0, 0, 63,
-  66, 33, 53, 1, 1, 40, 5, 0, 0, 0,
-  0, 29, 0, 0, 0, 0, 0, 0, 0, 33,
-  0, 0, 0, 0, 0, 13, 0, 0, 0, 7,
-  0, 0, 40, 19, 0, 0, 0, 0, 0, 107,
-  0, 0, 12, 52, 0, 31, 0, 27, 0, 0,
-  0, 19, 66, 8, 85, 0, 0, 0, 0, 0,
-  65, 0, 0, 12, 15, 13, 23, 55, 0, 0,
-  38, 70, 22, 57, 6, 0, 10, 41, 0, 20,
-  0, 27, 34, 9, 25, 65, 0, 0, 0, 0,
-  11, 0, 0, 0, 15, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 46, 0,
-  22, 0, 42, 0, 0, 120, 19, 74, 27, 0,
-  31, 0, 61, 0, 8, 0, 21, 27, 26, 43,
-  32, 22, 11, 48, 0, 0, 11, 13, 20, 2,
-  39, 1, 0, 0, 0, 0, 45, 5, 15, 2,
-  0, 0, 0, 0, 0, 0, 0, 21, 0, 27,
-  87, 36, 0, 0, 16, 0, 0, 39, 0, 0,
-  30, 0, 0, 50, 0, 22, 0, 0, 0, 0,
-  32, 15, 38, 0, 0, 0, 27, 0, 82, 16,
-  0, 44, 0, 0, 23, 10, 32, 10, 15, 51,
-  24, 38, 8, 39, 22, 24, 0, 47, 0, 0,
-  15, 0, 42, 41, 18, 5, 0, 0, 5, 0,
-  39, 13, 35, 22, 0, 0, 0, 45, 0, 0,
-  0, 0, 9, 0, 0, 0, 49, 0, 6, 0,
-  21, 9, 64, 56, 7, 47, 47, 23, 0, 2,
-  27, 0, 0, 0, 42, 8, 0, 3, 0, 0,
-  56, 18, 0, 16, 26, 0, 2, 0, 57, 0,
-  1, 54, 0, 27, 23, 0, 74, 44, 54, 0,
-  12, 0, 0, 9, 0, 16, 14, 30, 64, 22,
-  0, 0, 0, 0, 0, 18, 39, 0, 31, 0,
-  0, 0, 0, 41, 29, 0, 11, 5, 0, 39,
-  0, 10, 75, 0, 74, 0, 24, 4, 0, 36,
-  30, 0, 0, 0, 49, 39, 40, 0, 0, 51,
-  36, 6, 0, 6, 0, 16, 0, 0, 38, 0,
-  41, 42, 30, 45, 15, 0, 0, 0, 5, 61,
-  41, 0, 5, 11, 0, 65, 38, 0, 0, 0,
-  29, 0, 0, 0, 0, 0, 0, 0, 8, 29,
-  21, 77, 0, 54, 0, 57, 1, 0, 24, 0,
-  0, 9, 43, 0, 0, 0, 0, 20, 47, 27,
-  0, 27, 1, 0, 0, 0, 69, 0, 0, 0,
-  4, 19, 15, 0, 32, 49, 0, 0, 3, 0,
-  0, 7, 0, 34, 8, 10, 16, 0, 0, 0,
-  3, 45, 0, 0, 93, 35, 51, 0, 0, 0,
-  0, 53, 20, 0, 103, 0, 0, 43, 0, 68,
-  175, 29, 22, 0, 0, 35, 0, 61, 4, 6,
-  0, 0, 64, 5, 21, 0, 0, 19, 51, 0,
-  81, 0, 0, 0, 7, 0, 55, 0, 12, 95,
-  28, 106, 1, 0, 0, 0, 4, 67, 71, 0,
-  2, 16, 0, 39, 0, 0, 0, 0, 25, 0,
-  0, 0, 0, 18, 65, 17, 0, 0, 0, 0,
-  0, 25, 0, 135, 0, 7, 42, 0, 0, 4,
-  0, 6, 0, 0, 0, 25, 13, 0, 41, 106,
-  15, 0, 0, 0, 0, 1, 0, 0, 0, 1,
-  9, 0, 0, 82, 0, 40, 0, 0, 45, 0,
-  0, 46, 0, 80, 0, 4, 0, 0, 0, 52,
-  0, 0, 133, 36, 44, 0, 57, 0, 0, 92,
-  42, 0, 155, 0, 0, 30, 0, 77, 196, 0,
-  59, 34, 0, 31, 0, 16, 9, 0, 0, 0,
-  35, 0, 0, 0, 1, 0, 11, 0, 0, 92,
-  0, 0, 27, 0, 0, 0, 7, 76, 78, 108,
-  0, 0, 0, 0, 0, 30, 0, 0, 0, 38,
-  0, 95, 0, 0, 0, 0, 52, 0, 0, 0,
-  0, 0, 21, 0, 0, 6, 0, 28, 0, 8,
-  0, 24, 24, 29, 104, 12, 0, 37, 106, 0,
-  0, 105, 62, 22, 0, 0, 41, 62, 0, 12,
-  2, 0, 0, 43, 0, 0, 0, 0, 76, 0,
-  33, 0, 0, 91, 0, 53, 32, 0, 4, 39,
-  5, 115, 2, 34, 0, 36, 0, 56, 16, 0,
-  56, 0, 6, 0, 36, 0, 0, 14, 0, 21,
-  0, 0, 0, 0, 27, 0, 37, 0, 47, 52,
-  0, 14, 8, 31, 0, 0, 8, 0, 29, 0,
-  0, 10, 11, 0, 20, 0, 0, 68, 0, 34,
-  0, 0, 0, 0, 26, 84, 90, 0, 0, 0,
-  22, 0, 15, 31, 0, 34, 0, 30, 0, 52,
-  0, 0, 0, 0, 60, 0, 39, 0, 79, 0,
-  69, 0, 34, 16, 6, 145, 0, 66, 0, 25,
-  0, 0, 52, 0, 6, 0, 69, 0, 0, 0,
-  0, 5, 33, 32, 0, 0, 14, 32, 3, 0,
-  70, 0, 0, 0, 0, 0, 77, 0, 13, 38,
-  0, 0, 0, 0, 0, 17, 0, 19, 0, 15,
-  48, 19, 0, 17, 5, 25, 0, 35, 17, 0,
-  54, 0, 0, 16, 0, 0, 0, 0, 16, 0,
-  16, 19, 0, 1, 65, 17, 3, 0, 34, 29,
-  0, 94, 0, 16, 0, 0, 90, 39, 0, 18,
-  0, 41, 51, 18, 99, 0, 0, 0, 0, 0,
-  61, 0, 18, 99, 42, 59, 0, 0, 0, 10,
-  57, 44, 87, 0, 0, 0, 0, 36, 0, 0,
-  0, 0, 5, 0, 3, 0, 48, 0, 39, 0,
-  0, 46, 58, 21, 0, 68, 2, 105, 0, 4,
-  38, 0, 0, 0, 40, 0, 0, 0, 2, 21,
-  35, 0, 0, 90, 13, 0, 0, 0, 31, 0,
-  9, 0, 0, 31, 3, 0, 67, 72, 9, 0,
-  27, 0, 20, 14, 0, 28, 22, 53, 41, 0,
-  0, 0, 0, 61, 0, 0, 135, 38, 37, 0,
-  7, 0, 0, 47, 34, 0, 96, 0, 0, 31,
-  0, 47, 198, 6, 55, 0, 0, 0, 0, 35,
-  0, 0, 0, 0, 77, 27, 31, 0, 1, 1,
-  38, 0, 0, 15, 0, 0, 17, 0, 39, 0,
-  26, 71, 33, 77, 0, 0, 0, 0, 6, 46,
-  5, 0, 19, 40, 0, 88, 0, 0, 0, 0,
-  55, 0, 0, 0, 0, 0, 28, 0, 0, 16,
-  0, 0, 0, 15, 0, 83, 0, 21, 90, 39,
-  0, 48, 26, 0, 0, 60, 13, 28, 16, 0,
-  25, 81, 1, 0, 0, 0, 1, 44, 17, 19,
-  0, 35, 60, 0, 78, 36, 79, 138, 7, 0,
-  76, 0, 2, 0, 0, 129, 0, 4, 0, 11,
-  0, 4, 0, 0, 138, 0, 2, 0, 27, 0,
-  0, 90, 14, 2, 90, 0, 0, 39, 0, 61,
-  111, 0, 118, 35, 0, 31, 35, 22, 25, 0,
-  0, 0, 0, 27, 0, 0, 12, 25, 0, 0,
-  0, 91, 0, 7, 15, 0, 6, 0, 0, 89,
-  131, 18, 0, 0, 39, 0, 0, 48, 0, 0,
-  1, 67, 0, 57, 0, 0, 0, 0, 75, 0,
-  0, 0, 0, 0, 0, 0, 75, 51, 0, 120,
-  19, 74, 27, 0, 31, 0, 61, 0, 8, 0,
-  21, 27, 26, 43, 32, 22, 11, 48, 0, 0,
-  11, 13, 20, 2, 39, 1, 0, 0, 0, 0,
-  45, 5, 15, 2, 0, 0, 0, 0, 0, 0,
-  0, 21, 0, 27, 87, 36, 0, 0, 16, 0,
-  0, 39, 0, 0, 30, 0, 0, 50, 0, 22,
-  0, 0, 0, 0, 32, 15, 38, 0, 0, 0,
-  27, 0, 82, 16, 0, 44, 0, 0, 23, 10,
-  32, 10, 15, 51, 24, 38, 8, 39, 22, 24,
-  0, 47, 0, 0, 15, 0, 42, 41, 18, 5,
-  0, 0, 5, 0, 39, 13, 35, 22, 0, 0,
-  0, 45, 0, 0, 0, 0, 9, 0, 0, 0,
-  49, 0, 6, 0, 21, 9, 64, 56, 7, 47,
-  47, 23, 0, 2, 27, 0, 0, 0, 42, 8,
-  0, 3, 0, 0, 56, 18, 0, 16, 26, 0,
-  2, 0, 57, 0, 1, 54, 0, 27, 23, 0,
-  74, 44, 54, 0, 12, 0, 0, 9, 0, 16,
-  14, 30, 64, 22, 0, 0, 0, 0, 0, 18,
-  39, 0, 31, 0, 0, 0, 0, 41, 29, 0,
-  11, 5, 0, 39, 0, 10, 75, 0, 74, 0,
-  24, 4, 0, 36, 30, 0, 0, 0, 49, 39,
-  40, 0, 0, 51, 36, 6, 0, 6, 0, 16,
-  0, 0, 38, 0, 41, 42, 30, 45, 15, 0,
-  0, 0, 5, 61, 41, 0, 5, 11, 0, 65,
-  38, 0, 0, 0, 29, 0, 0, 0, 0, 0,
-  0, 0, 8, 29, 59, 0, 21, 13, 0, 41,
-  0, 2, 0, 43, 0, 19, 0, 48, 0, 0,
-  0, 0, 56, 0, 3, 89, 5, 0, 0, 0,
-  21, 5, 0, 99, 0, 11, 0, 0, 67, 44,
-  117, 91, 15, 0, 39, 0, 3, 0, 0, 12,
-  0, 18, 5, 1, 0, 35, 0, 23, 119, 0,
-  0, 4, 0, 0, 0, 65, 91, 49, 82, 33,
-  0, 21, 0, 118, 80, 20, 83, 0, 0, 0,
-  0, 0, 100, 0, 0, 0, 15, 22, 26, 0,
-  0, 49, 63, 0, 0, 18, 0, 0, 55, 0,
-  41, 0, 0, 54, 58, 26, 28, 0, 0, 0,
-  0, 29, 0, 0, 19, 18, 0, 23, 56, 7,
-  0, 0, 19, 0, 0, 0, 0, 0, 0, 24,
-  61, 73, 0, 0, 0, 25, 0, 135, 0, 7,
-  42, 0, 0, 4, 0, 6, 0, 0, 0, 25,
-  13, 0, 41, 106, 15, 0, 0, 0, 0, 1,
-  0, 0, 0, 1, 9, 0, 0, 82, 0, 40,
-  0, 0, 45, 0, 0, 46, 0, 80, 0, 4,
-  0, 0, 0, 52, 0, 0, 133, 36, 44, 0,
-  57, 0, 0, 92, 42, 0, 155, 0, 0, 30,
-  0, 77, 196, 0, 59, 34, 0, 31, 0, 16,
-  9, 0, 0, 0, 35, 0, 0, 0, 1, 0,
-  11, 0, 0, 92, 0, 0, 27, 0, 0, 0,
-  7, 76, 78, 108, 0, 0, 0, 0, 0, 30,
-  0, 0, 0, 38, 0, 95, 0, 0, 0, 0,
-  52, 0, 0, 0, 0, 0, 21, 0, 0, 6,
-  0, 28, 0, 8, 0, 24, 24, 29, 104, 12,
-  0, 37, 106, 0, 0, 105, 62, 22, 0, 0,
-  41, 62, 0, 12, 2, 0, 0, 43, 0, 0,
-  0, 0, 76, 0, 33, 0, 0, 91, 0, 53,
-  32, 0, 4, 39, 5, 115, 2, 34, 0, 36,
-  0, 56, 16, 0, 56, 0, 6, 0, 36, 0,
-  0, 14, 0, 21, 0, 0, 0, 0, 27, 0,
-  37, 0, 47, 52, 0, 14, 8, 31, 0, 0,
-  8, 0, 29, 0, 0, 10, 11, 0, 20, 0,
-  0, 68, 0, 34, 0, 0, 0, 0, 26, 84,
-  90, 0, 0, 0, 22, 0, 15, 31, 0, 34,
-  0, 30, 0, 52, 0, 0, 0, 0, 60, 0,
-  39, 0, 79, 0, 69, 0, 34, 16, 0, 39,
-  58, 0, 0, 0, 35, 20, 76, 0, 11, 39,
-  97, 0, 0, 94, 63, 17, 0, 0, 0, 47,
-  11, 21, 63, 0, 0, 58, 0, 0, 0, 24,
-  97, 0, 27, 0, 0, 89, 26, 22, 38, 4,
-  46, 33, 23, 117, 42, 0, 0, 22, 0, 0,
-  14, 0, 32, 0, 5, 0, 47, 0, 0, 49,
-  0, 19, 0, 0, 17, 1, 30, 0, 0, 0,
-  56, 43, 10, 31, 22, 65, 0, 0, 6, 0,
-  19, 88, 0, 42, 0, 0, 0, 23, 0, 11,
-  0, 31, 0, 0, 0, 0, 0, 85, 98, 0,
-  0, 0, 13, 0, 31, 29, 0, 24, 0, 19,
-  0, 5, 0, 0, 0, 12, 70, 0, 0, 0,
-  32, 0, 63, 0, 24, 34, 58, 21, 0, 68,
-  2, 105, 0, 4, 38, 0, 0, 0, 40, 0,
-  0, 0, 2, 21, 35, 0, 0, 90, 13, 0,
-  0, 0, 31, 0, 9, 0, 0, 31, 3, 0,
-  67, 72, 9, 0, 27, 0, 20, 14, 0, 28,
-  22, 53, 41, 0, 0, 0, 0, 61, 0, 0,
-  135, 38, 37, 0, 7, 0, 0, 47, 34, 0,
-  96, 0, 0, 31, 0, 47, 198, 6, 55, 0,
-  0, 0, 0, 35, 0, 0, 0, 0, 77, 27,
-  31, 0, 1, 1, 38, 0, 0, 15, 0, 0,
-  17, 0, 39, 0, 26, 71, 33, 77, 0, 0,
-  0, 0, 6, 46, 5, 0, 19, 40, 0, 88,
-  0, 0, 0, 0, 55, 0, 0, 0, 0, 0,
-  28, 0, 0, 16, 0, 0, 0, 15, 0, 83,
-  0, 21, 90, 39, 0, 48, 26, 0, 0, 60,
-  13, 28, 16, 0, 25, 81, 1, 0, 0, 0,
-  1, 44, 17, 19, 0, 35, 60, 0, 78, 36,
-  79, 138, 7, 0, 76, 0, 2, 0, 0, 129,
-  0, 4, 0, 11, 0, 4, 0, 0, 138, 0,
-  2, 0, 27, 0, 0, 90, 14, 2, 90, 0,
-  0, 39, 0, 61, 111, 0, 118, 35, 0, 31,
-  35, 22, 25, 0, 0, 0, 0, 27, 0, 0,
-  12, 25, 0, 0, 0, 91, 0, 7, 15, 0,
-  6, 0, 0, 89, 131, 18, 0, 0, 39, 0,
-  0, 48, 0, 0, 1, 67, 0, 57, 0, 0,
-  0, 0, 75, 0, 0, 0, 0, 0, 0, 0,
-  75, 51, 0, 0, 95, 9, 0, 0, 0, 24,
-  67, 28, 0, 54, 35, 44, 0, 52, 0, 15,
-  0, 0, 0, 58, 28, 9, 0, 0, 21, 48,
-  6, 84, 0, 37, 76, 0, 22, 0, 105, 123,
-  0, 0, 100, 0, 38, 0, 0, 109, 0, 0,
-  0, 11, 0, 0, 0, 0, 96, 0, 19, 0,
-  47, 0, 0, 83, 53, 15, 66, 0, 7, 34,
-  0, 90, 0, 0, 122, 30, 0, 21, 7, 0,
-  14, 0, 0, 2, 0, 89, 0, 17, 21, 0,
-  35, 0, 0, 36, 0, 3, 0, 0, 0, 0,
-  0, 59, 137, 0, 0, 0, 0, 0, 0, 52,
-  0, 3, 30, 17, 0, 0, 80, 0, 22, 0,
-  52, 0, 0, 0, 0, 0, 0, 14, 61, 73,
-  64, 56, 7, 47, 47, 23, 0, 2, 27, 0,
-  0, 0, 42, 8, 0, 3, 0, 0, 56, 18,
-  0, 16, 26, 0, 2, 0, 57, 0, 1, 54,
-  0, 27, 23, 0, 74, 44, 54, 0, 12, 0,
-  0, 9, 0, 16, 14, 30, 64, 22, 0, 0,
-  0, 0, 0, 18, 39, 0, 31, 0, 0, 0,
-  0, 41, 29, 0, 11, 5, 0, 39, 0, 10,
-  75, 0, 74, 0, 24, 4, 0, 36, 30, 0,
-  0, 0, 49, 39, 40, 0, 0, 51, 36, 6,
-  0, 6, 0, 16, 0, 0, 38, 0, 41, 42,
-  30, 45, 15, 0, 0, 0, 5, 61, 41, 0,
-  5, 11, 0, 65, 38, 0, 0, 0, 29, 0,
-  0, 0, 0, 0, 0, 0, 8, 29, 59, 0,
-  21, 13, 0, 41, 0, 2, 0, 43, 0, 19,
-  0, 48, 0, 0, 0, 0, 56, 0, 3, 89,
-  5, 0, 0, 0, 21, 5, 0, 99, 0, 11,
-  0, 0, 67, 44, 117, 91, 15, 0, 39, 0,
-  3, 0, 0, 12, 0, 18, 5, 1, 0, 35,
-  0, 23, 119, 0, 0, 4, 0, 0, 0, 65,
-  91, 49, 82, 33, 0, 21, 0, 118, 80, 20,
-  83, 0, 0, 0, 0, 0, 100, 0, 0, 0,
-  15, 22, 26, 0, 0, 49, 63, 0, 0, 18,
-  0, 0, 55, 0, 41, 0, 0, 54, 58, 26,
-  28, 0, 0, 0, 0, 29, 0, 0, 19, 18,
-  0, 23, 56, 7, 0, 0, 19, 0, 0, 0,
-  0, 0, 0, 24, 61, 73, 32, 0, 66, 36,
-  9, 0, 0, 0, 5, 21, 0, 26, 30, 124,
-  0, 0, 0, 0, 23, 0, 28, 52, 0, 3,
-  0, 0, 50, 28, 0, 103, 0, 4, 0, 0,
-  39, 0, 82, 66, 0, 0, 35, 0, 2, 0,
-  0, 22, 7, 0, 0, 0, 0, 70, 0, 21,
-  74, 0, 0, 14, 10, 0, 0, 32, 91, 24,
-  64, 1, 0, 2, 0, 95, 0, 13, 72, 0,
-  0, 0, 0, 0, 86, 0, 0, 56, 11, 19,
-  0, 0, 12, 13, 141, 0, 0, 19, 0, 0,
-  4, 0, 38, 0, 0, 38, 31, 0, 0, 0,
-  0, 0, 0, 56, 51, 0, 69, 0, 0, 0,
-  107, 0, 36, 0, 0, 32, 38, 0, 0, 0,
-  0, 37, 0, 81, 0, 28, 0, 8, 0, 24,
-  24, 29, 104, 12, 0, 37, 106, 0, 0, 105,
-  62, 22, 0, 0, 41, 62, 0, 12, 2, 0,
-  0, 43, 0, 0, 0, 0, 76, 0, 33, 0,
-  0, 91, 0, 53, 32, 0, 4, 39, 5, 115,
-  2, 34, 0, 36, 0, 56, 16, 0, 56, 0,
-  6, 0, 36, 0, 0, 14, 0, 21, 0, 0,
-  0, 0, 27, 0, 37, 0, 47, 52, 0, 14,
-  8, 31, 0, 0, 8, 0, 29, 0, 0, 10,
-  11, 0, 20, 0, 0, 68, 0, 34, 0, 0,
-  0, 0, 26, 84, 90, 0, 0, 0, 22, 0,
-  15, 31, 0, 34, 0, 30, 0, 52, 0, 0,
-  0, 0, 60, 0, 39, 0, 79, 0, 69, 0,
-  34, 16, 0, 39, 58, 0, 0, 0, 35, 20,
-  76, 0, 11, 39, 97, 0, 0, 94, 63, 17,
-  0, 0, 0, 47, 11, 21, 63, 0, 0, 58,
-  0, 0, 0, 24, 97, 0, 27, 0, 0, 89,
-  26, 22, 38, 4, 46, 33, 23, 117, 42, 0,
-  0, 22, 0, 0, 14, 0, 32, 0, 5, 0,
-  47, 0, 0, 49, 0, 19, 0, 0, 17, 1,
-  30, 0, 0, 0, 56, 43, 10, 31, 22, 65,
-  0, 0, 6, 0, 19, 88, 0, 42, 0, 0,
-  0, 23, 0, 11, 0, 31, 0, 0, 0, 0,
-  0, 85, 98, 0, 0, 0, 13, 0, 31, 29,
-  0, 24, 0, 19, 0, 5, 0, 0, 0, 12,
-  70, 0, 0, 0, 32, 0, 63, 0, 24, 34,
-  0, 10, 0, 0, 0, 0, 0, 1, 32, 2,
-  16, 56, 0, 30, 0, 9, 3, 0, 2, 0,
-  1, 27, 71, 20, 5, 0, 0, 23, 0, 18,
-  0, 0, 30, 0, 15, 0, 59, 84, 34, 0,
-  85, 0, 0, 5, 0, 98, 39, 10, 0, 0,
-  0, 0, 0, 0, 57, 0, 55, 0, 96, 0,
-  0, 81, 9, 12, 28, 9, 50, 46, 29, 21,
-  0, 0, 85, 58, 7, 94, 37, 18, 0, 0,
-  0, 22, 0, 74, 0, 50, 11, 36, 0, 0,
-  0, 84, 19, 16, 0, 0, 0, 0, 17, 49,
-  89, 0, 0, 0, 0, 27, 5, 0, 0, 3,
-  0, 9, 0, 9, 21, 75, 0, 33, 64, 0,
-  0, 0, 0, 0, 0, 0, 0, 41, 0, 0,
-  0, 15, 0, 83, 0, 21, 90, 39, 0, 48,
-  26, 0, 0, 60, 13, 28, 16, 0, 25, 81,
-  1, 0, 0, 0, 1, 44, 17, 19, 0, 35,
-  60, 0, 78, 36, 79, 138, 7, 0, 76, 0,
-  2, 0, 0, 129, 0, 4, 0, 11, 0, 4,
-  0, 0, 138, 0, 2, 0, 27, 0, 0, 90,
-  14, 2, 90, 0, 0, 39, 0, 61, 111, 0,
-  118, 35, 0, 31, 35, 22, 25, 0, 0, 0,
-  0, 27, 0, 0, 12, 25, 0, 0, 0, 91,
-  0, 7, 15, 0, 6, 0, 0, 89, 131, 18,
-  0, 0, 39, 0, 0, 48, 0, 0, 1, 67,
-  0, 57, 0, 0, 0, 0, 75, 0, 0, 0,
-  0, 0, 0, 0, 75, 51, 0, 0, 95, 9,
-  0, 0, 0, 24, 67, 28, 0, 54, 35, 44,
-  0, 52, 0, 15, 0, 0, 0, 58, 28, 9,
-  0, 0, 21, 48, 6, 84, 0, 37, 76, 0,
-  22, 0, 105, 123, 0, 0, 100, 0, 38, 0,
-  0, 109, 0, 0, 0, 11, 0, 0, 0, 0,
-  96, 0, 19, 0, 47, 0, 0, 83, 53, 15,
-  66, 0, 7, 34, 0, 90, 0, 0, 122, 30,
-  0, 21, 7, 0, 14, 0, 0, 2, 0, 89,
-  0, 17, 21, 0, 35, 0, 0, 36, 0, 3,
-  0, 0, 0, 0, 0, 59, 137, 0, 0, 0,
-  0, 0, 0, 52, 0, 3, 30, 17, 0, 0,
-  80, 0, 22, 0, 52, 0, 0, 0, 0, 0,
-  0, 14, 61, 73, 19, 3, 82, 25, 7, 0,
-  0, 19, 0, 0, 0, 50, 24, 124, 0, 0,
-  0, 0, 0, 0, 16, 66, 70, 4, 0, 0,
-  12, 4, 0, 88, 7, 3, 0, 13, 0, 0,
-  74, 8, 0, 0, 84, 0, 0, 15, 17, 36,
-  17, 22, 4, 0, 9, 49, 0, 0, 86, 0,
-  46, 0, 71, 0, 0, 47, 100, 0, 96, 0,
-  0, 47, 0, 116, 0, 23, 90, 0, 0, 33,
-  0, 0, 23, 0, 0, 55, 0, 76, 0, 1,
-  45, 31, 68, 0, 0, 0, 10, 0, 0, 0,
-  0, 0, 0, 29, 67, 0, 0, 0, 0, 4,
-  0, 42, 0, 0, 54, 0, 0, 0, 124, 74,
-  44, 0, 25, 0, 0, 0, 0, 25, 0, 22,
-  0, 56, 59, 0, 21, 13, 0, 41, 0, 2,
-  0, 43, 0, 19, 0, 48, 0, 0, 0, 0,
-  56, 0, 3, 89, 5, 0, 0, 0, 21, 5,
-  0, 99, 0, 11, 0, 0, 67, 44, 117, 91,
-  15, 0, 39, 0, 3, 0, 0, 12, 0, 18,
-  5, 1, 0, 35, 0, 23, 119, 0, 0, 4,
-  0, 0, 0, 65, 91, 49, 82, 33, 0, 21,
-  0, 118, 80, 20, 83, 0, 0, 0, 0, 0,
-  100, 0, 0, 0, 15, 22, 26, 0, 0, 49,
-  63, 0, 0, 18, 0, 0, 55, 0, 41, 0,
-  0, 54, 58, 26, 28, 0, 0, 0, 0, 29,
-  0, 0, 19, 18, 0, 23, 56, 7, 0, 0,
-  19, 0, 0, 0, 0, 0, 0, 24, 61, 73,
-  32, 0, 66, 36, 9, 0, 0, 0, 5, 21,
-  0, 26, 30, 124, 0, 0, 0, 0, 23, 0,
-  28, 52, 0, 3, 0, 0, 50, 28, 0, 103,
-  0, 4, 0, 0, 39, 0, 82, 66, 0, 0,
-  35, 0, 2, 0, 0, 22, 7, 0, 0, 0,
-  0, 70, 0, 21, 74, 0, 0, 14, 10, 0,
-  0, 32, 91, 24, 64, 1, 0, 2, 0, 95,
-  0, 13, 72, 0, 0, 0, 0, 0, 86, 0,
-  0, 56, 11, 19, 0, 0, 12, 13, 141, 0,
-  0, 19, 0, 0, 4, 0, 38, 0, 0, 38,
-  31, 0, 0, 0, 0, 0, 0, 56, 51, 0,
-  69, 0, 0, 0, 107, 0, 36, 0, 0, 32,
-  38, 0, 0, 0, 0, 37, 0, 81, 51, 46,
-  25, 77, 65, 9, 0, 0, 20, 0, 19, 0,
-  51, 118, 0, 0, 0, 0, 16, 7, 12, 11,
-  0, 26, 0, 0, 55, 19, 0, 69, 20, 7,
-  22, 0, 56, 0, 0, 0, 0, 0, 0, 35,
-  0, 0, 31, 31, 30, 33, 0, 0, 23, 35,
-  0, 14, 38, 0, 27, 20, 0, 10, 0, 19,
-  19, 8, 0, 0, 0, 0, 2, 0, 0, 41,
-  51, 0, 0, 22, 0, 0, 35, 8, 0, 53,
-  41, 20, 0, 0, 35, 12, 95, 14, 26, 0,
-  0, 30, 0, 0, 70, 0, 0, 50, 0, 20,
-  0, 0, 0, 25, 0, 43, 127, 0, 82, 0,
-  12, 0, 31, 0, 14, 0, 0, 8, 49, 0,
-  2, 15, 10, 13, 0, 93, 0, 39, 58, 0,
-  0, 0, 35, 20, 76, 0, 11, 39, 97, 0,
-  0, 94, 63, 17, 0, 0, 0, 47, 11, 21,
-  63, 0, 0, 58, 0, 0, 0, 24, 97, 0,
-  27, 0, 0, 89, 26, 22, 38, 4, 46, 33,
-  23, 117, 42, 0, 0, 22, 0, 0, 14, 0,
-  32, 0, 5, 0, 47, 0, 0, 49, 0, 19,
-  0, 0, 17, 1, 30, 0, 0, 0, 56, 43,
-  10, 31, 22, 65, 0, 0, 6, 0, 19, 88,
-  0, 42, 0, 0, 0, 23, 0, 11, 0, 31,
-  0, 0, 0, 0, 0, 85, 98, 0, 0, 0,
-  13, 0, 31, 29, 0, 24, 0, 19, 0, 5,
-  0, 0, 0, 12, 70, 0, 0, 0, 32, 0,
-  63, 0, 24, 34, 0, 10, 0, 0, 0, 0,
-  0, 1, 32, 2, 16, 56, 0, 30, 0, 9,
-  3, 0, 2, 0, 1, 27, 71, 20, 5, 0,
-  0, 23, 0, 18, 0, 0, 30, 0, 15, 0,
-  59, 84, 34, 0, 85, 0, 0, 5, 0, 98,
-  39, 10, 0, 0, 0, 0, 0, 0, 57, 0,
-  55, 0, 96, 0, 0, 81, 9, 12, 28, 9,
-  50, 46, 29, 21, 0, 0, 85, 58, 7, 94,
-  37, 18, 0, 0, 0, 22, 0, 74, 0, 50,
-  11, 36, 0, 0, 0, 84, 19, 16, 0, 0,
-  0, 0, 17, 49, 89, 0, 0, 0, 0, 27,
-  5, 0, 0, 3, 0, 9, 0, 9, 21, 75,
-  0, 33, 64, 0, 0, 0, 0, 0, 0, 0,
-  0, 41, 4, 18, 11, 6, 0, 0, 0, 0,
-  60, 44, 0, 0, 0, 54, 0, 0, 0, 29,
-  17, 0, 3, 11, 34, 17, 0, 0, 58, 48,
-  0, 0, 0, 0, 53, 0, 0, 0, 74, 109,
-  0, 0, 46, 0, 0, 0, 0, 59, 0, 51,
-  0, 23, 0, 0, 0, 0, 78, 7, 34, 8,
-  0, 0, 0, 52, 29, 14, 74, 2, 53, 17,
-  8, 144, 9, 0, 46, 89, 0, 57, 27, 0,
-  12, 0, 0, 0, 31, 87, 0, 30, 0, 43,
-  20, 0, 0, 171, 0, 0, 22, 0, 7, 0,
-  0, 57, 123, 33, 0, 0, 0, 0, 0, 2,
-  0, 0, 0, 24, 0, 10, 20, 24, 0, 0,
-  14, 0, 0, 0, 0, 0, 0, 4, 58, 62,
-  0, 0, 95, 9, 0, 0, 0, 24, 67, 28,
-  0, 54, 35, 44, 0, 52, 0, 15, 0, 0,
-  0, 58, 28, 9, 0, 0, 21, 48, 6, 84,
-  0, 37, 76, 0, 22, 0, 105, 123, 0, 0,
-  100, 0, 38, 0, 0, 109, 0, 0, 0, 11,
-  0, 0, 0, 0, 96, 0, 19, 0, 47, 0,
-  0, 83, 53, 15, 66, 0, 7, 34, 0, 90,
-  0, 0, 122, 30, 0, 21, 7, 0, 14, 0,
-  0, 2, 0, 89, 0, 17, 21, 0, 35, 0,
-  0, 36, 0, 3, 0, 0, 0, 0, 0, 59,
-  137, 0, 0, 0, 0, 0, 0, 52, 0, 3,
-  30, 17, 0, 0, 80, 0, 22, 0, 52, 0,
-  0, 0, 0, 0, 0, 14, 61, 73, 19, 3,
-  82, 25, 7, 0, 0, 19, 0, 0, 0, 50,
-  24, 124, 0, 0, 0, 0, 0, 0, 16, 66,
-  70, 4, 0, 0, 12, 4, 0, 88, 7, 3,
-  0, 13, 0, 0, 74, 8, 0, 0, 84, 0,
-  0, 15, 17, 36, 17, 22, 4, 0, 9, 49,
-  0, 0, 86, 0, 46, 0, 71, 0, 0, 47,
-  100, 0, 96, 0, 0, 47, 0, 116, 0, 23,
-  90, 0, 0, 33, 0, 0, 23, 0, 0, 55,
-  0, 76, 0, 1, 45, 31, 68, 0, 0, 0,
-  10, 0, 0, 0, 0, 0, 0, 29, 67, 0,
-  0, 0, 0, 4, 0, 42, 0, 0, 54, 0,
-  0, 0, 124, 74, 44, 0, 25, 0, 0, 0,
-  0, 25, 0, 22, 0, 56, 83, 83, 12, 72,
-  44, 15, 0, 0, 20, 0, 22, 0, 23, 126,
-  0, 0, 0, 0, 39, 0, 24, 37, 34, 21,
-  0, 0, 35, 11, 0, 34, 52, 81, 0, 0,
-  0, 0, 0, 26, 0, 0, 0, 1, 0, 0,
-  1, 18, 42, 71, 0, 0, 11, 40, 0, 7,
-  106, 0, 38, 4, 10, 0, 0, 34, 61, 26,
-  20, 0, 27, 21, 0, 98, 0, 49, 51, 0,
-  0, 28, 54, 0, 44, 0, 0, 48, 15, 60,
-  0, 1, 2, 45, 68, 0, 14, 0, 0, 25,
-  0, 0, 81, 0, 11, 15, 12, 121, 4, 0,
-  0, 16, 0, 68, 74, 0, 26, 0, 17, 1,
-  24, 87, 0, 0, 20, 2, 10, 0, 0, 0,
-  0, 22, 0, 87, 32, 0, 66, 36, 9, 0,
-  0, 0, 5, 21, 0, 26, 30, 124, 0, 0,
-  0, 0, 23, 0, 28, 52, 0, 3, 0, 0,
-  50, 28, 0, 103, 0, 4, 0, 0, 39, 0,
-  82, 66, 0, 0, 35, 0, 2, 0, 0, 22,
-  7, 0, 0, 0, 0, 70, 0, 21, 74, 0,
-  0, 14, 10, 0, 0, 32, 91, 24, 64, 1,
-  0, 2, 0, 95, 0, 13, 72, 0, 0, 0,
-  0, 0, 86, 0, 0, 56, 11, 19, 0, 0,
-  12, 13, 141, 0, 0, 19, 0, 0, 4, 0,
-  38, 0, 0, 38, 31, 0, 0, 0, 0, 0,
-  0, 56, 51, 0, 69, 0, 0, 0, 107, 0,
-  36, 0, 0, 32, 38, 0, 0, 0, 0, 37,
-  0, 81, 51, 46, 25, 77, 65, 9, 0, 0,
-  20, 0, 19, 0, 51, 118, 0, 0, 0, 0,
-  16, 7, 12, 11, 0, 26, 0, 0, 55, 19,
-  0, 69, 20, 7, 22, 0, 56, 0, 0, 0,
-  0, 0, 0, 35, 0, 0, 31, 31, 30, 33,
-  0, 0, 23, 35, 0, 14, 38, 0, 27, 20,
-  0, 10, 0, 19, 19, 8, 0, 0, 0, 0,
-  2, 0, 0, 41, 51, 0, 0, 22, 0, 0,
-  35, 8, 0, 53, 41, 20, 0, 0, 35, 12,
-  95, 14, 26, 0, 0, 30, 0, 0, 70, 0,
-  0, 50, 0, 20, 0, 0, 0, 25, 0, 43,
-  127, 0, 82, 0, 12, 0, 31, 0, 14, 0,
-  0, 8, 49, 0, 2, 15, 10, 13, 0, 93,
-  42, 127, 15, 99, 80, 43, 0, 0, 43, 0,
-  32, 0, 35, 29, 0, 0, 11, 0, 41, 15,
-  0, 0, 0, 47, 24, 0, 52, 29, 0, 37,
-  5, 49, 69, 0, 20, 0, 0, 0, 0, 0,
-  0, 17, 0, 6, 19, 56, 44, 46, 0, 7,
-  4, 0, 0, 17, 32, 0, 50, 2, 0, 29,
-  21, 24, 0, 8, 0, 0, 52, 4, 27, 0,
-  0, 21, 45, 4, 6, 45, 10, 2, 0, 2,
-  0, 19, 40, 73, 0, 17, 5, 38, 21, 49,
-  107, 0, 0, 49, 0, 0, 90, 0, 23, 57,
-  7, 99, 1, 0, 25, 33, 41, 62, 122, 0,
-  7, 22, 36, 0, 0, 0, 0, 0, 0, 0,
-  13, 0, 43, 0, 45, 1, 13, 74, 0, 10,
-  0, 0, 0, 0, 0, 1, 32, 2, 16, 56,
-  0, 30, 0, 9, 3, 0, 2, 0, 1, 27,
-  71, 20, 5, 0, 0, 23, 0, 18, 0, 0,
-  30, 0, 15, 0, 59, 84, 34, 0, 85, 0,
-  0, 5, 0, 98, 39, 10, 0, 0, 0, 0,
-  0, 0, 57, 0, 55, 0, 96, 0, 0, 81,
-  9, 12, 28, 9, 50, 46, 29, 21, 0, 0,
-  85, 58, 7, 94, 37, 18, 0, 0, 0, 22,
-  0, 74, 0, 50, 11, 36, 0, 0, 0, 84,
-  19, 16, 0, 0, 0, 0, 17, 49, 89, 0,
-  0, 0, 0, 27, 5, 0, 0, 3, 0, 9,
-  0, 9, 21, 75, 0, 33, 64, 0, 0, 0,
-  0, 0, 0, 0, 0, 41, 4, 18, 11, 6,
-  0, 0, 0, 0, 60, 44, 0, 0, 0, 54,
-  0, 0, 0, 29, 17, 0, 3, 11, 34, 17,
-  0, 0, 58, 48, 0, 0, 0, 0, 53, 0,
-  0, 0, 74, 109, 0, 0, 46, 0, 0, 0,
-  0, 59, 0, 51, 0, 23, 0, 0, 0, 0,
-  78, 7, 34, 8, 0, 0, 0, 52, 29, 14,
-  74, 2, 53, 17, 8, 144, 9, 0, 46, 89,
-  0, 57, 27, 0, 12, 0, 0, 0, 31, 87,
-  0, 30, 0, 43, 20, 0, 0, 171, 0, 0,
-  22, 0, 7, 0, 0, 57, 123, 33, 0, 0,
-  0, 0, 0, 2, 0, 0, 0, 24, 0, 10,
-  20, 24, 0, 0, 14, 0, 0, 0, 0, 0,
-  0, 4, 58, 62, 28, 0, 51, 0, 0, 127,
-  0, 0, 28, 13, 0, 0, 0, 82, 0, 0,
-  9, 29, 31, 0, 0, 85, 28, 32, 0, 0,
-  13, 55, 0, 0, 0, 43, 0, 0, 0, 17,
-  44, 93, 0, 0, 24, 0, 15, 0, 0, 32,
-  0, 29, 0, 35, 0, 77, 0, 0, 138, 0,
-  12, 0, 0, 0, 0, 64, 0, 0, 81, 0,
-  9, 6, 12, 125, 8, 0, 33, 55, 0, 39,
-  22, 0, 0, 0, 0, 0, 28, 82, 0, 10,
-  0, 46, 0, 0, 0, 123, 0, 0, 55, 0,
-  11, 0, 0, 88, 63, 49, 0, 0, 27, 0,
-  0, 10, 0, 6, 1, 11, 0, 0, 9, 35,
-  24, 0, 11, 0, 0, 0, 0, 0, 0, 3,
-  9, 79, 19, 3, 82, 25, 7, 0, 0, 19,
-  0, 0, 0, 50, 24, 124, 0, 0, 0, 0,
-  0, 0, 16, 66, 70, 4, 0, 0, 12, 4,
-  0, 88, 7, 3, 0, 13, 0, 0, 74, 8,
-  0, 0, 84, 0, 0, 15, 17, 36, 17, 22,
-  4, 0, 9, 49, 0, 0, 86, 0, 46, 0,
-  71, 0, 0, 47, 100, 0, 96, 0, 0, 47,
-  0, 116, 0, 23, 90, 0, 0, 33, 0, 0,
-  23, 0, 0, 55, 0, 76, 0, 1, 45, 31,
-  68, 0, 0, 0, 10, 0, 0, 0, 0, 0,
-  0, 29, 67, 0, 0, 0, 0, 4, 0, 42,
-  0, 0, 54, 0, 0, 0, 124, 74, 44, 0,
-  25, 0, 0, 0, 0, 25, 0, 22, 0, 56,
-  83, 83, 12, 72, 44, 15, 0, 0, 20, 0,
-  22, 0, 23, 126, 0, 0, 0, 0, 39, 0,
-  24, 37, 34, 21, 0, 0, 35, 11, 0, 34,
-  52, 81, 0, 0, 0, 0, 0, 26, 0, 0,
-  0, 1, 0, 0, 1, 18, 42, 71, 0, 0,
-  11, 40, 0, 7, 106, 0, 38, 4, 10, 0,
-  0, 34, 61, 26, 20, 0, 27, 21, 0, 98,
-  0, 49, 51, 0, 0, 28, 54, 0, 44, 0,
-  0, 48, 15, 60, 0, 1, 2, 45, 68, 0,
-  14, 0, 0, 25, 0, 0, 81, 0, 11, 15,
-  12, 121, 4, 0, 0, 16, 0, 68, 74, 0,
-  26, 0, 17, 1, 24, 87, 0, 0, 20, 2,
-  10, 0, 0, 0, 0, 22, 0, 87, 35, 0,
-  20, 65, 14, 232, 0, 0, 1, 0, 0, 0,
-  0, 21, 0, 0, 0, 33, 62, 0, 0, 113,
-  15, 0, 0, 0, 0, 6, 0, 17, 8, 99,
-  0, 0, 0, 33, 0, 40, 0, 0, 0, 0,
-  0, 0, 0, 58, 44, 47, 7, 4, 0, 38,
-  0, 0, 142, 0, 48, 0, 21, 0, 27, 92,
-  17, 0, 115, 0, 0, 40, 0, 96, 83, 63,
-  62, 0, 0, 35, 43, 0, 0, 0, 0, 0,
-  46, 65, 0, 0, 0, 31, 0, 0, 7, 7,
-  0, 0, 70, 0, 52, 0, 0, 9, 17, 116,
-  2, 0, 0, 5, 18, 17, 0, 0, 0, 39,
-  0, 0, 0, 45, 36, 0, 13, 16, 0, 19,
-  0, 0, 0, 15, 0, 44, 51, 46, 25, 77,
-  65, 9, 0, 0, 20, 0, 19, 0, 51, 118,
-  0, 0, 0, 0, 16, 7, 12, 11, 0, 26,
-  0, 0, 55, 19, 0, 69, 20, 7, 22, 0,
-  56, 0, 0, 0, 0, 0, 0, 35, 0, 0,
-  31, 31, 30, 33, 0, 0, 23, 35, 0, 14,
-  38, 0, 27, 20, 0, 10, 0, 19, 19, 8,
-  0, 0, 0, 0, 2, 0, 0, 41, 51, 0,
-  0, 22, 0, 0, 35, 8, 0, 53, 41, 20,
-  0, 0, 35, 12, 95, 14, 26, 0, 0, 30,
-  0, 0, 70, 0, 0, 50, 0, 20, 0, 0,
-  0, 25, 0, 43, 127, 0, 82, 0, 12, 0,
-  31, 0, 14, 0, 0, 8, 49, 0, 2, 15,
-  10, 13, 0, 93, 42, 127, 15, 99, 80, 43,
-  0, 0, 43, 0, 32, 0, 35, 29, 0, 0,
-  11, 0, 41, 15, 0, 0, 0, 47, 24, 0,
-  52, 29, 0, 37, 5, 49, 69, 0, 20, 0,
-  0, 0, 0, 0, 0, 17, 0, 6, 19, 56,
-  44, 46, 0, 7, 4, 0, 0, 17, 32, 0,
-  50, 2, 0, 29, 21, 24, 0, 8, 0, 0,
-  52, 4, 27, 0, 0, 21, 45, 4, 6, 45,
-  10, 2, 0, 2, 0, 19, 40, 73, 0, 17,
-  5, 38, 21, 49, 107, 0, 0, 49, 0, 0,
-  90, 0, 23, 57, 7, 99, 1, 0, 25, 33,
-  41, 62, 122, 0, 7, 22, 36, 0, 0, 0,
-  0, 0, 0, 0, 13, 0, 43, 0, 45, 1,
-  13, 74, 17, 8, 86, 68, 23, 217, 0, 0,
-  29, 0, 0, 0, 32, 0, 0, 0, 31, 18,
-  66, 0, 0, 112, 15, 8, 7, 0, 0, 35,
-  0, 72, 0, 82, 0, 0, 0, 30, 0, 0,
-  1, 0, 0, 19, 0, 19, 0, 50, 59, 42,
-  0, 14, 0, 45, 0, 0, 97, 0, 62, 0,
-  33, 0, 0, 70, 0, 0, 53, 0, 0, 26,
-  12, 6, 27, 25, 76, 0, 0, 26, 25, 0,
-  0, 18, 0, 0, 77, 83, 0, 0, 0, 18,
-  0, 4, 54, 0, 0, 0, 24, 0, 25, 0,
-  15, 39, 25, 35, 17, 0, 0, 31, 47, 29,
-  0, 0, 0, 45, 0, 0, 0, 0, 38, 0,
-  3, 0, 0, 1, 0, 22, 25, 0, 0, 20,
-  4, 18, 11, 6, 0, 0, 0, 0, 60, 44,
-  0, 0, 0, 54, 0, 0, 0, 29, 17, 0,
-  3, 11, 34, 17, 0, 0, 58, 48, 0, 0,
-  0, 0, 53, 0, 0, 0, 74, 109, 0, 0,
-  46, 0, 0, 0, 0, 59, 0, 51, 0, 23,
-  0, 0, 0, 0, 78, 7, 34, 8, 0, 0,
-  0, 52, 29, 14, 74, 2, 53, 17, 8, 144,
-  9, 0, 46, 89, 0, 57, 27, 0, 12, 0,
-  0, 0, 31, 87, 0, 30, 0, 43, 20, 0,
-  0, 171, 0, 0, 22, 0, 7, 0, 0, 57,
-  123, 33, 0, 0, 0, 0, 0, 2, 0, 0,
-  0, 24, 0, 10, 20, 24, 0, 0, 14, 0,
-  0, 0, 0, 0, 0, 4, 58, 62, 28, 0,
-  51, 0, 0, 127, 0, 0, 28, 13, 0, 0,
-  0, 82, 0, 0, 9, 29, 31, 0, 0, 85,
-  28, 32, 0, 0, 13, 55, 0, 0, 0, 43,
-  0, 0, 0, 17, 44, 93, 0, 0, 24, 0,
-  15, 0, 0, 32, 0, 29, 0, 35, 0, 77,
-  0, 0, 138, 0, 12, 0, 0, 0, 0, 64,
-  0, 0, 81, 0, 9, 6, 12, 125, 8, 0,
-  33, 55, 0, 39, 22, 0, 0, 0, 0, 0,
-  28, 82, 0, 10, 0, 46, 0, 0, 0, 123,
-  0, 0, 55, 0, 11, 0, 0, 88, 63, 49,
-  0, 0, 27, 0, 0, 10, 0, 6, 1, 11,
-  0, 0, 9, 35, 24, 0, 11, 0, 0, 0,
-  0, 0, 0, 3, 9, 79, 0, 0, 30, 0,
-  26, 161, 0, 0, 0, 0, 0, 0, 49, 60,
-  0, 0, 11, 55, 0, 0, 7, 16, 0, 50,
-  0, 0, 0, 0, 0, 35, 21, 0, 0, 13,
-  0, 0, 0, 55, 0, 3, 0, 20, 0, 22,
-  0, 12, 34, 22, 0, 0, 13, 103, 4, 0,
-  17, 0, 10, 0, 46, 0, 0, 0, 0, 0,
-  54, 0, 0, 2, 0, 4, 0, 34, 24, 5,
-  0, 40, 0, 0, 0, 10, 0, 0, 18, 36,
-  19, 0, 31, 36, 38, 0, 0, 22, 13, 0,
-  4, 0, 0, 0, 1, 46, 1, 0, 0, 0,
-  0, 10, 0, 22, 0, 25, 23, 0, 0, 0,
-  5, 29, 102, 47, 32, 3, 54, 0, 0, 0,
-  37, 15, 0, 14, 83, 83, 12, 72, 44, 15,
-  0, 0, 20, 0, 22, 0, 23, 126, 0, 0,
-  0, 0, 39, 0, 24, 37, 34, 21, 0, 0,
-  35, 11, 0, 34, 52, 81, 0, 0, 0, 0,
-  0, 26, 0, 0, 0, 1, 0, 0, 1, 18,
-  42, 71, 0, 0, 11, 40, 0, 7, 106, 0,
-  38, 4, 10, 0, 0, 34, 61, 26, 20, 0,
-  27, 21, 0, 98, 0, 49, 51, 0, 0, 28,
-  54, 0, 44, 0, 0, 48, 15, 60, 0, 1,
-  2, 45, 68, 0, 14, 0, 0, 25, 0, 0,
-  81, 0, 11, 15, 12, 121, 4, 0, 0, 16,
-  0, 68, 74, 0, 26, 0, 17, 1, 24, 87,
-  0, 0, 20, 2, 10, 0, 0, 0, 0, 22,
-  0, 87, 35, 0, 20, 65, 14, 232, 0, 0,
-  1, 0, 0, 0, 0, 21, 0, 0, 0, 33,
-  62, 0, 0, 113, 15, 0, 0, 0, 0, 6,
-  0, 17, 8, 99, 0, 0, 0, 33, 0, 40,
-  0, 0, 0, 0, 0, 0, 0, 58, 44, 47,
-  7, 4, 0, 38, 0, 0, 142, 0, 48, 0,
-  21, 0, 27, 92, 17, 0, 115, 0, 0, 40,
-  0, 96, 83, 63, 62, 0, 0, 35, 43, 0,
-  0, 0, 0, 0, 46, 65, 0, 0, 0, 31,
-  0, 0, 7, 7, 0, 0, 70, 0, 52, 0,
-  0, 9, 17, 116, 2, 0, 0, 5, 18, 17,
-  0, 0, 0, 39, 0, 0, 0, 45, 36, 0,
-  13, 16, 0, 19, 0, 0, 0, 15, 0, 44,
-  0, 0, 0, 5, 19, 184, 0, 0, 0, 0,
-  0, 0, 30, 14, 0, 24, 4, 50, 5, 0,
-  21, 0, 0, 62, 18, 19, 0, 0, 0, 10,
-  18, 0, 0, 34, 0, 4, 0, 24, 0, 24,
-  0, 55, 0, 16, 0, 17, 43, 43, 0, 20,
-  0, 38, 14, 0, 0, 0, 9, 0, 19, 12,
-  5, 26, 0, 0, 6, 0, 0, 22, 22, 0,
-  30, 56, 37, 1, 2, 80, 0, 0, 0, 42,
-  0, 0, 13, 12, 24, 0, 22, 14, 2, 28,
-  1, 67, 43, 9, 35, 30, 0, 0, 7, 25,
-  0, 0, 0, 0, 0, 0, 0, 6, 0, 17,
-  0, 1, 0, 13, 0, 7, 81, 29, 34, 0,
-  48, 9, 42, 0, 38, 19, 0, 0, 42, 127,
-  15, 99, 80, 43, 0, 0, 43, 0, 32, 0,
-  35, 29, 0, 0, 11, 0, 41, 15, 0, 0,
-  0, 47, 24, 0, 52, 29, 0, 37, 5, 49,
-  69, 0, 20, 0, 0, 0, 0, 0, 0, 17,
-  0, 6, 19, 56, 44, 46, 0, 7, 4, 0,
-  0, 17, 32, 0, 50, 2, 0, 29, 21, 24,
-  0, 8, 0, 0, 52, 4, 27, 0, 0, 21,
-  45, 4, 6, 45, 10, 2, 0, 2, 0, 19,
-  40, 73, 0, 17, 5, 38, 21, 49, 107, 0,
-  0, 49, 0, 0, 90, 0, 23, 57, 7, 99,
-  1, 0, 25, 33, 41, 62, 122, 0, 7, 22,
-  36, 0, 0, 0, 0, 0, 0, 0, 13, 0,
-  43, 0, 45, 1, 13, 74, 17, 8, 86, 68,
-  23, 217, 0, 0, 29, 0, 0, 0, 32, 0,
-  0, 0, 31, 18, 66, 0, 0, 112, 15, 8,
-  7, 0, 0, 35, 0, 72, 0, 82, 0, 0,
-  0, 30, 0, 0, 1, 0, 0, 19, 0, 19,
-  0, 50, 59, 42, 0, 14, 0, 45, 0, 0,
-  97, 0, 62, 0, 33, 0, 0, 70, 0, 0,
-  53, 0, 0, 26, 12, 6, 27, 25, 76, 0,
-  0, 26, 25, 0, 0, 18, 0, 0, 77, 83,
-  0, 0, 0, 18, 0, 4, 54, 0, 0, 0,
-  24, 0, 25, 0, 15, 39, 25, 35, 17, 0,
-  0, 31, 47, 29, 0, 0, 0, 45, 0, 0,
-  0, 0, 38, 0, 3, 0, 0, 1, 0, 22,
-  25, 0, 0, 20, 0, 0, 0, 0, 1, 125,
-  0, 0, 0, 0, 0, 0, 59, 8, 0, 44,
-  12, 40, 18, 0, 40, 6, 0, 49, 0, 0,
-  0, 0, 0, 14, 40, 0, 0, 17, 0, 8,
-  0, 16, 0, 48, 35, 47, 0, 33, 1, 0,
-  7, 27, 0, 35, 0, 77, 28, 0, 14, 0,
-  38, 0, 36, 0, 0, 14, 0, 11, 0, 0,
-  0, 3, 8, 0, 16, 34, 27, 15, 0, 70,
-  0, 0, 0, 26, 7, 0, 14, 12, 42, 0,
-  12, 0, 8, 25, 0, 47, 52, 0, 15, 13,
-  0, 0, 17, 28, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 32, 29, 12, 0, 47, 0, 0,
-  66, 14, 50, 0, 35, 14, 18, 0, 67, 1,
-  0, 0, 28, 0, 51, 0, 0, 127, 0, 0,
-  28, 13, 0, 0, 0, 82, 0, 0, 9, 29,
-  31, 0, 0, 85, 28, 32, 0, 0, 13, 55,
-  0, 0, 0, 43, 0, 0, 0, 17, 44, 93,
-  0, 0, 24, 0, 15, 0, 0, 32, 0, 29,
-  0, 35, 0, 77, 0, 0, 138, 0, 12, 0,
-  0, 0, 0, 64, 0, 0, 81, 0, 9, 6,
-  12, 125, 8, 0, 33, 55, 0, 39, 22, 0,
-  0, 0, 0, 0, 28, 82, 0, 10, 0, 46,
-  0, 0, 0, 123, 0, 0, 55, 0, 11, 0,
-  0, 88, 63, 49, 0, 0, 27, 0, 0, 10,
-  0, 6, 1, 11, 0, 0, 9, 35, 24, 0,
-  11, 0, 0, 0, 0, 0, 0, 3, 9, 79,
-  0, 0, 30, 0, 26, 161, 0, 0, 0, 0,
-  0, 0, 49, 60, 0, 0, 11, 55, 0, 0,
-  7, 16, 0, 50, 0, 0, 0, 0, 0, 35,
-  21, 0, 0, 13, 0, 0, 0, 55, 0, 3,
-  0, 20, 0, 22, 0, 12, 34, 22, 0, 0,
-  13, 103, 4, 0, 17, 0, 10, 0, 46, 0,
-  0, 0, 0, 0, 54, 0, 0, 2, 0, 4,
-  0, 34, 24, 5, 0, 40, 0, 0, 0, 10,
-  0, 0, 18, 36, 19, 0, 31, 36, 38, 0,
-  0, 22, 13, 0, 4, 0, 0, 0, 1, 46,
-  1, 0, 0, 0, 0, 10, 0, 22, 0, 25,
-  23, 0, 0, 0, 5, 29, 102, 47, 32, 3,
-  54, 0, 0, 0, 37, 15, 0, 14, 0, 49,
-  11, 0, 44, 0, 25, 0, 19, 0, 0, 0,
-  81, 51, 5, 17, 15, 0, 0, 0, 3, 0,
-  0, 60, 21, 63, 0, 0, 0, 12, 63, 0,
-  0, 27, 12, 0, 0, 6, 0, 70, 0, 97,
-  10, 75, 53, 0, 0, 0, 0, 6, 0, 65,
-  94, 0, 0, 3, 21, 23, 4, 21, 0, 0,
-  0, 70, 0, 12, 8, 0, 0, 0, 0, 33,
-  0, 19, 20, 29, 0, 0, 0, 27, 44, 20,
-  19, 0, 78, 0, 29, 0, 66, 38, 0, 0,
-  42, 37, 0, 32, 0, 38, 3, 45, 0, 0,
-  0, 0, 0, 0, 3, 5, 71, 72, 88, 0,
-  0, 7, 31, 0, 0, 31, 64, 18, 57, 10,
-  85, 0, 91, 2, 0, 0, 35, 0, 20, 65,
-  14, 232, 0, 0, 1, 0, 0, 0, 0, 21,
-  0, 0, 0, 33, 62, 0, 0, 113, 15, 0,
-  0, 0, 0, 6, 0, 17, 8, 99, 0, 0,
-  0, 33, 0, 40, 0, 0, 0, 0, 0, 0,
-  0, 58, 44, 47, 7, 4, 0, 38, 0, 0,
-  142, 0, 48, 0, 21, 0, 27, 92, 17, 0,
-  115, 0, 0, 40, 0, 96, 83, 63, 62, 0,
-  0, 35, 43, 0, 0, 0, 0, 0, 46, 65,
-  0, 0, 0, 31, 0, 0, 7, 7, 0, 0,
-  70, 0, 52, 0, 0, 9, 17, 116, 2, 0,
-  0, 5, 18, 17, 0, 0, 0, 39, 0, 0,
-  0, 45, 36, 0, 13, 16, 0, 19, 0, 0,
-  0, 15, 0, 44, 0, 0, 0, 5, 19, 184,
-  0, 0, 0, 0, 0, 0, 30, 14, 0, 24,
-  4, 50, 5, 0, 21, 0, 0, 62, 18, 19,
-  0, 0, 0, 10, 18, 0, 0, 34, 0, 4,
-  0, 24, 0, 24, 0, 55, 0, 16, 0, 17,
-  43, 43, 0, 20, 0, 38, 14, 0, 0, 0,
-  9, 0, 19, 12, 5, 26, 0, 0, 6, 0,
-  0, 22, 22, 0, 30, 56, 37, 1, 2, 80,
-  0, 0, 0, 42, 0, 0, 13, 12, 24, 0,
-  22, 14, 2, 28, 1, 67, 43, 9, 35, 30,
-  0, 0, 7, 25, 0, 0, 0, 0, 0, 0,
-  0, 6, 0, 17, 0, 1, 0, 13, 0, 7,
-  81, 29, 34, 0, 48, 9, 42, 0, 38, 19,
-  0, 0, 0, 34, 49, 0, 25, 0, 17, 0,
-  0, 0, 0, 0, 29, 51, 2, 46, 15, 40,
-  0, 20, 33, 0, 79, 40, 0, 20, 0, 0,
-  0, 0, 25, 0, 0, 0, 0, 0, 0, 5,
-  0, 35, 63, 42, 0, 75, 56, 0, 0, 0,
-  0, 4, 0, 42, 63, 0, 1, 0, 44, 5,
-  9, 0, 0, 3, 0, 23, 0, 0, 26, 7,
-  0, 0, 0, 3, 4, 30, 12, 34, 0, 8,
-  0, 0, 40, 0, 0, 0, 68, 13, 0, 0,
-  40, 12, 0, 29, 32, 0, 0, 30, 0, 0,
-  0, 46, 0, 0, 0, 0, 5, 0, 0, 0,
-  0, 29, 58, 4, 0, 15, 30, 0, 26, 17,
-  54, 0, 15, 0, 9, 0, 76, 5, 0, 0,
-  17, 8, 86, 68, 23, 217, 0, 0, 29, 0,
-  0, 0, 32, 0, 0, 0, 31, 18, 66, 0,
-  0, 112, 15, 8, 7, 0, 0, 35, 0, 72,
-  0, 82, 0, 0, 0, 30, 0, 0, 1, 0,
-  0, 19, 0, 19, 0, 50, 59, 42, 0, 14,
-  0, 45, 0, 0, 97, 0, 62, 0, 33, 0,
-  0, 70, 0, 0, 53, 0, 0, 26, 12, 6,
-  27, 25, 76, 0, 0, 26, 25, 0, 0, 18,
-  0, 0, 77, 83, 0, 0, 0, 18, 0, 4,
-  54, 0, 0, 0, 24, 0, 25, 0, 15, 39,
-  25, 35, 17, 0, 0, 31, 47, 29, 0, 0,
-  0, 45, 0, 0, 0, 0, 38, 0, 3, 0,
-  0, 1, 0, 22, 25, 0, 0, 20, 0, 0,
-  0, 0, 1, 125, 0, 0, 0, 0, 0, 0,
-  59, 8, 0, 44, 12, 40, 18, 0, 40, 6,
-  0, 49, 0, 0, 0, 0, 0, 14, 40, 0,
-  0, 17, 0, 8, 0, 16, 0, 48, 35, 47,
-  0, 33, 1, 0, 7, 27, 0, 35, 0, 77,
-  28, 0, 14, 0, 38, 0, 36, 0, 0, 14,
-  0, 11, 0, 0, 0, 3, 8, 0, 16, 34,
-  27, 15, 0, 70, 0, 0, 0, 26, 7, 0,
-  14, 12, 42, 0, 12, 0, 8, 25, 0, 47,
-  52, 0, 15, 13, 0, 0, 17, 28, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 32, 29, 12,
-  0, 47, 0, 0, 66, 14, 50, 0, 35, 14,
-  18, 0, 67, 1, 0, 0, 0, 0, 77, 0,
-  0, 0, 2, 0, 0, 0, 0, 1, 29, 58,
-  0, 41, 0, 69, 29, 7, 59, 19, 117, 17,
-  0, 0, 0, 5, 0, 0, 15, 0, 0, 0,
-  0, 13, 0, 12, 0, 0, 66, 0, 0, 79,
-  32, 0, 0, 0, 0, 6, 0, 87, 7, 0,
-  39, 0, 49, 0, 7, 0, 0, 1, 10, 0,
-  77, 0, 0, 21, 0, 50, 0, 0, 2, 19,
-  0, 7, 0, 0, 0, 0, 19, 0, 2, 0,
-  62, 8, 0, 0, 25, 0, 0, 13, 0, 0,
-  16, 30, 0, 0, 0, 54, 3, 0, 0, 0,
-  20, 0, 0, 0, 0, 0, 62, 11, 0, 38,
-  13, 0, 89, 23, 44, 14, 34, 0, 0, 0,
-  57, 0, 15, 0, 0, 0, 30, 0, 26, 161,
-  0, 0, 0, 0, 0, 0, 49, 60, 0, 0,
-  11, 55, 0, 0, 7, 16, 0, 50, 0, 0,
-  0, 0, 0, 35, 21, 0, 0, 13, 0, 0,
-  0, 55, 0, 3, 0, 20, 0, 22, 0, 12,
-  34, 22, 0, 0, 13, 103, 4, 0, 17, 0,
-  10, 0, 46, 0, 0, 0, 0, 0, 54, 0,
-  0, 2, 0, 4, 0, 34, 24, 5, 0, 40,
-  0, 0, 0, 10, 0, 0, 18, 36, 19, 0,
-  31, 36, 38, 0, 0, 22, 13, 0, 4, 0,
-  0, 0, 1, 46, 1, 0, 0, 0, 0, 10,
-  0, 22, 0, 25, 23, 0, 0, 0, 5, 29,
-  102, 47, 32, 3, 54, 0, 0, 0, 37, 15,
-  0, 14, 0, 49, 11, 0, 44, 0, 25, 0,
-  19, 0, 0, 0, 81, 51, 5, 17, 15, 0,
-  0, 0, 3, 0, 0, 60, 21, 63, 0, 0,
-  0, 12, 63, 0, 0, 27, 12, 0, 0, 6,
-  0, 70, 0, 97, 10, 75, 53, 0, 0, 0,
-  0, 6, 0, 65, 94, 0, 0, 3, 21, 23,
-  4, 21, 0, 0, 0, 70, 0, 12, 8, 0,
-  0, 0, 0, 33, 0, 19, 20, 29, 0, 0,
-  0, 27, 44, 20, 19, 0, 78, 0, 29, 0,
-  66, 38, 0, 0, 42, 37, 0, 32, 0, 38,
-  3, 45, 0, 0, 0, 0, 0, 0, 3, 5,
-  71, 72, 88, 0, 0, 7, 31, 0, 0, 31,
-  64, 18, 57, 10, 85, 0, 91, 2, 0, 0,
-  0, 21, 76, 0, 26, 0, 1, 0, 0, 0,
-  0, 6, 28, 78, 0, 20, 4, 29, 21, 10,
-  35, 34, 113, 11, 0, 0, 0, 0, 0, 0,
-  18, 0, 0, 0, 0, 0, 0, 1, 0, 10,
-  66, 3, 0, 101, 57, 6, 0, 0, 0, 0,
-  0, 90, 1, 0, 17, 0, 40, 0, 25, 0,
-  0, 10, 7, 19, 34, 0, 0, 18, 0, 29,
-  0, 0, 0, 43, 3, 0, 0, 28, 0, 0,
-  37, 0, 22, 0, 65, 9, 0, 0, 20, 0,
-  0, 16, 13, 0, 0, 46, 0, 0, 0, 39,
-  0, 0, 0, 0, 1, 0, 0, 4, 0, 7,
-  72, 14, 0, 12, 20, 0, 52, 13, 51, 13,
-  13, 0, 0, 0, 64, 0, 0, 0, 0, 0,
-  0, 5, 19, 184, 0, 0, 0, 0, 0, 0,
-  30, 14, 0, 24, 4, 50, 5, 0, 21, 0,
-  0, 62, 18, 19, 0, 0, 0, 10, 18, 0,
-  0, 34, 0, 4, 0, 24, 0, 24, 0, 55,
-  0, 16, 0, 17, 43, 43, 0, 20, 0, 38,
-  14, 0, 0, 0, 9, 0, 19, 12, 5, 26,
-  0, 0, 6, 0, 0, 22, 22, 0, 30, 56,
-  37, 1, 2, 80, 0, 0, 0, 42, 0, 0,
-  13, 12, 24, 0, 22, 14, 2, 28, 1, 67,
-  43, 9, 35, 30, 0, 0, 7, 25, 0, 0,
-  0, 0, 0, 0, 0, 6, 0, 17, 0, 1,
-  0, 13, 0, 7, 81, 29, 34, 0, 48, 9,
-  42, 0, 38, 19, 0, 0, 0, 34, 49, 0,
-  25, 0, 17, 0, 0, 0, 0, 0, 29, 51,
-  2, 46, 15, 40, 0, 20, 33, 0, 79, 40,
-  0, 20, 0, 0, 0, 0, 25, 0, 0, 0,
-  0, 0, 0, 5, 0, 35, 63, 42, 0, 75,
-  56, 0, 0, 0, 0, 4, 0, 42, 63, 0,
-  1, 0, 44, 5, 9, 0, 0, 3, 0, 23,
-  0, 0, 26, 7, 0, 0, 0, 3, 4, 30,
-  12, 34, 0, 8, 0, 0, 40, 0, 0, 0,
-  68, 13, 0, 0, 40, 12, 0, 29, 32, 0,
-  0, 30, 0, 0, 0, 46, 0, 0, 0, 0,
-  5, 0, 0, 0, 0, 29, 58, 4, 0, 15,
-  30, 0, 26, 17, 54, 0, 15, 0, 9, 0,
-  76, 5, 0, 0, 10, 0, 77, 0, 9, 10,
-  0, 0, 4, 0, 0, 8, 3, 82, 0, 0,
-  0, 46, 42, 0, 45, 68, 136, 0, 0, 0,
-  0, 0, 0, 0, 3, 0, 0, 0, 0, 9,
-  0, 0, 0, 0, 33, 0, 0, 90, 40, 14,
-  0, 21, 0, 0, 0, 136, 0, 0, 74, 0,
-  41, 0, 36, 0, 0, 0, 35, 0, 125, 0,
-  0, 23, 0, 91, 0, 0, 13, 4, 0, 0,
-  7, 0, 0, 0, 15, 0, 23, 0, 45, 6,
-  0, 0, 20, 0, 0, 0, 0, 0, 24, 27,
-  0, 0, 0, 52, 15, 0, 0, 0, 14, 0,
-  0, 2, 0, 0, 69, 4, 0, 37, 12, 0,
-  118, 0, 23, 19, 24, 0, 0, 0, 53, 0,
-  0, 0, 0, 0, 0, 0, 1, 125, 0, 0,
-  0, 0, 0, 0, 59, 8, 0, 44, 12, 40,
-  18, 0, 40, 6, 0, 49, 0, 0, 0, 0,
-  0, 14, 40, 0, 0, 17, 0, 8, 0, 16,
-  0, 48, 35, 47, 0, 33, 1, 0, 7, 27,
-  0, 35, 0, 77, 28, 0, 14, 0, 38, 0,
-  36, 0, 0, 14, 0, 11, 0, 0, 0, 3,
-  8, 0, 16, 34, 27, 15, 0, 70, 0, 0,
-  0, 26, 7, 0, 14, 12, 42, 0, 12, 0,
-  8, 25, 0, 47, 52, 0, 15, 13, 0, 0,
-  17, 28, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 32, 29, 12, 0, 47, 0, 0, 66, 14,
-  50, 0, 35, 14, 18, 0, 67, 1, 0, 0,
-  0, 0, 77, 0, 0, 0, 2, 0, 0, 0,
-  0, 1, 29, 58, 0, 41, 0, 69, 29, 7,
-  59, 19, 117, 17, 0, 0, 0, 5, 0, 0,
-  15, 0, 0, 0, 0, 13, 0, 12, 0, 0,
-  66, 0, 0, 79, 32, 0, 0, 0, 0, 6,
-  0, 87, 7, 0, 39, 0, 49, 0, 7, 0,
-  0, 1, 10, 0, 77, 0, 0, 21, 0, 50,
-  0, 0, 2, 19, 0, 7, 0, 0, 0, 0,
-  19, 0, 2, 0, 62, 8, 0, 0, 25, 0,
-  0, 13, 0, 0, 16, 30, 0, 0, 0, 54,
-  3, 0, 0, 0, 20, 0, 0, 0, 0, 0,
-  62, 11, 0, 38, 13, 0, 89, 23, 44, 14,
-  34, 0, 0, 0, 57, 0, 15, 0, 25, 0,
-  64, 0, 17, 12, 0, 0, 23, 0, 0, 6,
-  16, 72, 0, 0, 0, 19, 42, 0, 48, 60,
-  61, 0, 0, 0, 0, 26, 0, 41, 0, 0,
-  0, 0, 0, 3, 0, 6, 0, 0, 0, 0,
-  0, 69, 18, 17, 0, 65, 0, 0, 0, 167,
-  0, 0, 66, 0, 29, 0, 4, 0, 0, 0,
-  24, 0, 113, 0, 0, 10, 0, 64, 0, 4,
-  0, 0, 0, 0, 0, 0, 0, 0, 12, 0,
-  12, 0, 32, 1, 0, 15, 43, 0, 26, 0,
-  0, 0, 27, 0, 11, 0, 0, 71, 39, 0,
-  0, 0, 13, 0, 0, 24, 30, 0, 73, 0,
-  0, 44, 14, 0, 155, 0, 5, 26, 74, 0,
-  0, 0, 54, 0, 0, 0, 0, 49, 11, 0,
-  44, 0, 25, 0, 19, 0, 0, 0, 81, 51,
-  5, 17, 15, 0, 0, 0, 3, 0, 0, 60,
-  21, 63, 0, 0, 0, 12, 63, 0, 0, 27,
-  12, 0, 0, 6, 0, 70, 0, 97, 10, 75,
-  53, 0, 0, 0, 0, 6, 0, 65, 94, 0,
-  0, 3, 21, 23, 4, 21, 0, 0, 0, 70,
-  0, 12, 8, 0, 0, 0, 0, 33, 0, 19,
-  20, 29, 0, 0, 0, 27, 44, 20, 19, 0,
-  78, 0, 29, 0, 66, 38, 0, 0, 42, 37,
-  0, 32, 0, 38, 3, 45, 0, 0, 0, 0,
-  0, 0, 3, 5, 71, 72, 88, 0, 0, 7,
-  31, 0, 0, 31, 64, 18, 57, 10, 85, 0,
-  91, 2, 0, 0, 0, 21, 76, 0, 26, 0,
-  1, 0, 0, 0, 0, 6, 28, 78, 0, 20,
-  4, 29, 21, 10, 35, 34, 113, 11, 0, 0,
-  0, 0, 0, 0, 18, 0, 0, 0, 0, 0,
-  0, 1, 0, 10, 66, 3, 0, 101, 57, 6,
-  0, 0, 0, 0, 0, 90, 1, 0, 17, 0,
-  40, 0, 25, 0, 0, 10, 7, 19, 34, 0,
-  0, 18, 0, 29, 0, 0, 0, 43, 3, 0,
-  0, 28, 0, 0, 37, 0, 22, 0, 65, 9,
-  0, 0, 20, 0, 0, 16, 13, 0, 0, 46,
-  0, 0, 0, 39, 0, 0, 0, 0, 1, 0,
-  0, 4, 0, 7, 72, 14, 0, 12, 20, 0,
-  52, 13, 51, 13, 13, 0, 0, 0, 64, 0,
-  0, 0, 4, 0, 79, 3, 6, 0, 0, 0,
-  14, 0, 0, 8, 0, 94, 0, 3, 0, 47,
-  45, 17, 53, 54, 102, 0, 0, 0, 0, 16,
-  0, 0, 0, 0, 0, 0, 0, 14, 0, 0,
-  0, 0, 37, 0, 0, 85, 38, 32, 0, 6,
-  0, 0, 0, 126, 0, 0, 66, 0, 24, 0,
-  20, 0, 0, 0, 29, 0, 99, 0, 0, 10,
-  0, 92, 0, 0, 18, 0, 0, 0, 4, 0,
-  0, 0, 11, 0, 20, 0, 18, 0, 0, 0,
-  39, 0, 0, 7, 0, 0, 22, 29, 2, 0,
-  4, 32, 23, 0, 0, 0, 28, 0, 0, 3,
-  17, 0, 84, 3, 0, 15, 21, 0, 112, 0,
-  10, 16, 55, 0, 0, 0, 57, 15, 0, 0,
-  0, 34, 49, 0, 25, 0, 17, 0, 0, 0,
-  0, 0, 29, 51, 2, 46, 15, 40, 0, 20,
-  33, 0, 79, 40, 0, 20, 0, 0, 0, 0,
-  25, 0, 0, 0, 0, 0, 0, 5, 0, 35,
-  63, 42, 0, 75, 56, 0, 0, 0, 0, 4,
-  0, 42, 63, 0, 1, 0, 44, 5, 9, 0,
-  0, 3, 0, 23, 0, 0, 26, 7, 0, 0,
-  0, 3, 4, 30, 12, 34, 0, 8, 0, 0,
-  40, 0, 0, 0, 68, 13, 0, 0, 40, 12,
-  0, 29, 32, 0, 0, 30, 0, 0, 0, 46,
-  0, 0, 0, 0, 5, 0, 0, 0, 0, 29,
-  58, 4, 0, 15, 30, 0, 26, 17, 54, 0,
-  15, 0, 9, 0, 76, 5, 0, 0, 10, 0,
-  77, 0, 9, 10, 0, 0, 4, 0, 0, 8,
-  3, 82, 0, 0, 0, 46, 42, 0, 45, 68,
-  136, 0, 0, 0, 0, 0, 0, 0, 3, 0,
-  0, 0, 0, 9, 0, 0, 0, 0, 33, 0,
-  0, 90, 40, 14, 0, 21, 0, 0, 0, 136,
-  0, 0, 74, 0, 41, 0, 36, 0, 0, 0,
-  35, 0, 125, 0, 0, 23, 0, 91, 0, 0,
-  13, 4, 0, 0, 7, 0, 0, 0, 15, 0,
-  23, 0, 45, 6, 0, 0, 20, 0, 0, 0,
-  0, 0, 24, 27, 0, 0, 0, 52, 15, 0,
-  0, 0, 14, 0, 0, 2, 0, 0, 69, 4,
-  0, 37, 12, 0, 118, 0, 23, 19, 24, 0,
-  0, 0, 53, 0, 0, 0, 0, 0, 45, 1,
-  17, 0, 0, 0, 31, 0, 0, 0, 20, 82,
-  0, 0, 0, 11, 29, 0, 23, 30, 25, 5,
-  0, 0, 20, 43, 0, 53, 0, 0, 0, 0,
-  0, 0, 0, 4, 0, 0, 0, 0, 0, 45,
-  6, 26, 0, 49, 0, 0, 0, 152, 0, 16,
-  45, 0, 12, 0, 0, 0, 0, 0, 8, 0,
-  63, 0, 0, 6, 0, 72, 0, 0, 8, 0,
-  0, 0, 0, 0, 0, 0, 13, 0, 1, 0,
-  0, 0, 0, 44, 53, 0, 44, 0, 0, 0,
-  18, 0, 36, 0, 0, 72, 23, 0, 15, 0,
-  42, 0, 1, 20, 65, 0, 81, 0, 0, 14,
-  40, 0, 141, 0, 0, 33, 89, 0, 30, 0,
-  58, 0, 0, 0, 0, 0, 77, 0, 0, 0,
-  2, 0, 0, 0, 0, 1, 29, 58, 0, 41,
-  0, 69, 29, 7, 59, 19, 117, 17, 0, 0,
-  0, 5, 0, 0, 15, 0, 0, 0, 0, 13,
-  0, 12, 0, 0, 66, 0, 0, 79, 32, 0,
-  0, 0, 0, 6, 0, 87, 7, 0, 39, 0,
-  49, 0, 7, 0, 0, 1, 10, 0, 77, 0,
-  0, 21, 0, 50, 0, 0, 2, 19, 0, 7,
-  0, 0, 0, 0, 19, 0, 2, 0, 62, 8,
-  0, 0, 25, 0, 0, 13, 0, 0, 16, 30,
-  0, 0, 0, 54, 3, 0, 0, 0, 20, 0,
-  0, 0, 0, 0, 62, 11, 0, 38, 13, 0,
-  89, 23, 44, 14, 34, 0, 0, 0, 57, 0,
-  15, 0, 25, 0, 64, 0, 17, 12, 0, 0,
-  23, 0, 0, 6, 16, 72, 0, 0, 0, 19,
-  42, 0, 48, 60, 61, 0, 0, 0, 0, 26,
-  0, 41, 0, 0, 0, 0, 0, 3, 0, 6,
-  0, 0, 0, 0, 0, 69, 18, 17, 0, 65,
-  0, 0, 0, 167, 0, 0, 66, 0, 29, 0,
-  4, 0, 0, 0, 24, 0, 113, 0, 0, 10,
-  0, 64, 0, 4, 0, 0, 0, 0, 0, 0,
-  0, 0, 12, 0, 12, 0, 32, 1, 0, 15,
-  43, 0, 26, 0, 0, 0, 27, 0, 11, 0,
-  0, 71, 39, 0, 0, 0, 13, 0, 0, 24,
-  30, 0, 73, 0, 0, 44, 14, 0, 155, 0,
-  5, 26, 74, 0, 0, 0, 54, 0, 0, 0,
-  0, 0, 0, 0, 12, 0, 0, 14, 34, 15,
-  0, 0, 26, 34, 0, 0, 0, 21, 29, 0,
-  8, 0, 0, 45, 0, 0, 48, 64, 6, 83,
-  0, 0, 55, 0, 0, 0, 0, 1, 0, 5,
-  0, 0, 0, 16, 10, 46, 0, 58, 0, 8,
-  7, 104, 37, 30, 33, 0, 15, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 6, 0, 0, 19,
-  0, 0, 21, 0, 0, 63, 0, 0, 0, 9,
-  39, 0, 0, 13, 0, 0, 0, 59, 43, 21,
-  114, 3, 0, 0, 28, 0, 36, 0, 0, 91,
-  40, 0, 32, 0, 7, 0, 28, 8, 75, 20,
-  37, 0, 0, 8, 5, 0, 131, 0, 0, 37,
-  103, 0, 101, 0, 70, 0, 0, 0, 0, 21,
-  76, 0, 26, 0, 1, 0, 0, 0, 0, 6,
-  28, 78, 0, 20, 4, 29, 21, 10, 35, 34,
-  113, 11, 0, 0, 0, 0, 0, 0, 18, 0,
-  0, 0, 0, 0, 0, 1, 0, 10, 66, 3,
-  0, 101, 57, 6, 0, 0, 0, 0, 0, 90,
-  1, 0, 17, 0, 40, 0, 25, 0, 0, 10,
-  7, 19, 34, 0, 0, 18, 0, 29, 0, 0,
-  0, 43, 3, 0, 0, 28, 0, 0, 37, 0,
-  22, 0, 65, 9, 0, 0, 20, 0, 0, 16,
-  13, 0, 0, 46, 0, 0, 0, 39, 0, 0,
-  0, 0, 1, 0, 0, 4, 0, 7, 72, 14,
-  0, 12, 20, 0, 52, 13, 51, 13, 13, 0,
-  0, 0, 64, 0, 0, 0, 4, 0, 79, 3,
-  6, 0, 0, 0, 14, 0, 0, 8, 0, 94,
-  0, 3, 0, 47, 45, 17, 53, 54, 102, 0,
-  0, 0, 0, 16, 0, 0, 0, 0, 0, 0,
-  0, 14, 0, 0, 0, 0, 37, 0, 0, 85,
-  38, 32, 0, 6, 0, 0, 0, 126, 0, 0,
-  66, 0, 24, 0, 20, 0, 0, 0, 29, 0,
-  99, 0, 0, 10, 0, 92, 0, 0, 18, 0,
-  0, 0, 4, 0, 0, 0, 11, 0, 20, 0,
-  18, 0, 0, 0, 39, 0, 0, 7, 0, 0,
-  22, 29, 2, 0, 4, 32, 23, 0, 0, 0,
-  28, 0, 0, 3, 17, 0, 84, 3, 0, 15,
-  21, 0, 112, 0, 10, 16, 55, 0, 0, 0,
-  57, 15, 0, 0, 2, 0, 42, 31, 0, 0,
-  14, 24, 59, 0, 4, 0, 0, 82, 0, 0,
-  0, 8, 26, 0, 35, 19, 23, 27, 0, 0,
-  38, 57, 187, 16, 19, 10, 32, 0, 0, 0,
-  0, 25, 0, 0, 0, 0, 0, 32, 38, 93,
-  0, 17, 0, 0, 3, 110, 0, 32, 59, 0,
-  9, 0, 14, 0, 0, 22, 8, 0, 4, 0,
-  20, 0, 0, 39, 0, 6, 29, 4, 0, 9,
-  34, 0, 0, 0, 24, 0, 1, 24, 0, 0,
-  0, 30, 103, 45, 40, 0, 0, 0, 18, 12,
-  59, 0, 26, 51, 26, 6, 18, 0, 84, 0,
-  42, 12, 87, 0, 79, 0, 10, 0, 1, 0,
-  115, 0, 0, 34, 41, 0, 5, 0, 59, 9,
-  0, 24, 10, 0, 77, 0, 9, 10, 0, 0,
-  4, 0, 0, 8, 3, 82, 0, 0, 0, 46,
-  42, 0, 45, 68, 136, 0, 0, 0, 0, 0,
-  0, 0, 3, 0, 0, 0, 0, 9, 0, 0,
-  0, 0, 33, 0, 0, 90, 40, 14, 0, 21,
-  0, 0, 0, 136, 0, 0, 74, 0, 41, 0,
-  36, 0, 0, 0, 35, 0, 125, 0, 0, 23,
-  0, 91, 0, 0, 13, 4, 0, 0, 7, 0,
-  0, 0, 15, 0, 23, 0, 45, 6, 0, 0,
-  20, 0, 0, 0, 0, 0, 24, 27, 0, 0,
-  0, 52, 15, 0, 0, 0, 14, 0, 0, 2,
-  0, 0, 69, 4, 0, 37, 12, 0, 118, 0,
-  23, 19, 24, 0, 0, 0, 53, 0, 0, 0,
-  0, 0, 45, 1, 17, 0, 0, 0, 31, 0,
-  0, 0, 20, 82, 0, 0, 0, 11, 29, 0,
-  23, 30, 25, 5, 0, 0, 20, 43, 0, 53,
-  0, 0, 0, 0, 0, 0, 0, 4, 0, 0,
-  0, 0, 0, 45, 6, 26, 0, 49, 0, 0,
-  0, 152, 0, 16, 45, 0, 12, 0, 0, 0,
-  0, 0, 8, 0, 63, 0, 0, 6, 0, 72,
-  0, 0, 8, 0, 0, 0, 0, 0, 0, 0,
-  13, 0, 1, 0, 0, 0, 0, 44, 53, 0,
-  44, 0, 0, 0, 18, 0, 36, 0, 0, 72,
-  23, 0, 15, 0, 42, 0, 1, 20, 65, 0,
-  81, 0, 0, 14, 40, 0, 141, 0, 0, 33,
-  89, 0, 30, 0, 58, 0, 0, 0, 0, 0,
-  24, 23, 0, 0, 18, 24, 50, 29, 0, 0,
-  0, 30, 0, 5, 4, 7, 13, 0, 0, 0,
-  0, 53, 0, 0, 74, 59, 173, 47, 0, 0,
-  71, 0, 19, 0, 0, 20, 0, 24, 0, 0,
-  0, 0, 18, 88, 16, 0, 0, 16, 0, 67,
-  30, 34, 32, 0, 0, 4, 0, 6, 0, 39,
-  0, 0, 0, 0, 33, 0, 0, 14, 6, 12,
-  56, 3, 0, 51, 0, 0, 0, 3, 39, 0,
-  0, 33, 0, 0, 0, 48, 80, 41, 84, 0,
-  0, 0, 23, 0, 51, 0, 2, 59, 14, 2,
-  58, 0, 66, 2, 56, 3, 77, 5, 38, 0,
-  11, 0, 0, 0, 103, 0, 0, 17, 53, 0,
-  50, 0, 60, 0, 7, 11, 25, 0, 64, 0,
-  17, 12, 0, 0, 23, 0, 0, 6, 16, 72,
-  0, 0, 0, 19, 42, 0, 48, 60, 61, 0,
-  0, 0, 0, 26, 0, 41, 0, 0, 0, 0,
-  0, 3, 0, 6, 0, 0, 0, 0, 0, 69,
-  18, 17, 0, 65, 0, 0, 0, 167, 0, 0,
-  66, 0, 29, 0, 4, 0, 0, 0, 24, 0,
-  113, 0, 0, 10, 0, 64, 0, 4, 0, 0,
-  0, 0, 0, 0, 0, 0, 12, 0, 12, 0,
-  32, 1, 0, 15, 43, 0, 26, 0, 0, 0,
-  27, 0, 11, 0, 0, 71, 39, 0, 0, 0,
-  13, 0, 0, 24, 30, 0, 73, 0, 0, 44,
-  14, 0, 155, 0, 5, 26, 74, 0, 0, 0,
-  54, 0, 0, 0, 0, 0, 0, 0, 12, 0,
-  0, 14, 34, 15, 0, 0, 26, 34, 0, 0,
-  0, 21, 29, 0, 8, 0, 0, 45, 0, 0,
-  48, 64, 6, 83, 0, 0, 55, 0, 0, 0,
-  0, 1, 0, 5, 0, 0, 0, 16, 10, 46,
-  0, 58, 0, 8, 7, 104, 37, 30, 33, 0,
-  15, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  6, 0, 0, 19, 0, 0, 21, 0, 0, 63,
-  0, 0, 0, 9, 39, 0, 0, 13, 0, 0,
-  0, 59, 43, 21, 114, 3, 0, 0, 28, 0,
-  36, 0, 0, 91, 40, 0, 32, 0, 7, 0,
-  28, 8, 75, 20, 37, 0, 0, 8, 5, 0,
-  131, 0, 0, 37, 103, 0, 101, 0, 70, 0,
-  0, 0, 0, 6, 23, 5, 0, 0, 44, 22,
-  34, 36, 0, 0, 1, 0, 0, 41, 20, 23,
-  3, 8, 0, 0, 0, 69, 18, 19, 51, 49,
-  164, 7, 0, 0, 85, 0, 15, 0, 0, 31,
-  6, 63, 0, 3, 29, 0, 23, 56, 20, 0,
-  0, 47, 0, 43, 48, 47, 7, 0, 0, 20,
-  0, 28, 0, 23, 0, 0, 0, 3, 58, 0,
-  2, 0, 18, 22, 54, 25, 23, 58, 0, 0,
-  0, 13, 76, 0, 7, 17, 0, 0, 4, 37,
-  62, 48, 83, 0, 0, 0, 8, 13, 24, 0,
-  0, 55, 0, 0, 26, 0, 38, 0, 56, 0,
-  44, 17, 29, 0, 10, 0, 0, 0, 37, 0,
-  0, 16, 21, 0, 77, 0, 71, 0, 5, 0,
-  4, 0, 79, 3, 6, 0, 0, 0, 14, 0,
-  0, 8, 0, 94, 0, 3, 0, 47, 45, 17,
-  53, 54, 102, 0, 0, 0, 0, 16, 0, 0,
-  0, 0, 0, 0, 0, 14, 0, 0, 0, 0,
-  37, 0, 0, 85, 38, 32, 0, 6, 0, 0,
-  0, 126, 0, 0, 66, 0, 24, 0, 20, 0,
-  0, 0, 29, 0, 99, 0, 0, 10, 0, 92,
-  0, 0, 18, 0, 0, 0, 4, 0, 0, 0,
-  11, 0, 20, 0, 18, 0, 0, 0, 39, 0,
-  0, 7, 0, 0, 22, 29, 2, 0, 4, 32,
-  23, 0, 0, 0, 28, 0, 0, 3, 17, 0,
-  84, 3, 0, 15, 21, 0, 112, 0, 10, 16,
-  55, 0, 0, 0, 57, 15, 0, 0, 2, 0,
-  42, 31, 0, 0, 14, 24, 59, 0, 4, 0,
-  0, 82, 0, 0, 0, 8, 26, 0, 35, 19,
-  23, 27, 0, 0, 38, 57, 187, 16, 19, 10,
-  32, 0, 0, 0, 0, 25, 0, 0, 0, 0,
-  0, 32, 38, 93, 0, 17, 0, 0, 3, 110,
-  0, 32, 59, 0, 9, 0, 14, 0, 0, 22,
-  8, 0, 4, 0, 20, 0, 0, 39, 0, 6,
-  29, 4, 0, 9, 34, 0, 0, 0, 24, 0,
-  1, 24, 0, 0, 0, 30, 103, 45, 40, 0,
-  0, 0, 18, 12, 59, 0, 26, 51, 26, 6,
-  18, 0, 84, 0, 42, 12, 87, 0, 79, 0,
-  10, 0, 1, 0, 115, 0, 0, 34, 41, 0,
-  5, 0, 59, 9, 0, 24, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 45, 1, 17, 0,
-  0, 0, 31, 0, 0, 0, 20, 82, 0, 0,
-  0, 11, 29, 0, 23, 30, 25, 5, 0, 0,
-  20, 43, 0, 53, 0, 0, 0, 0, 0, 0,
-  0, 4, 0, 0, 0, 0, 0, 45, 6, 26,
-  0, 49, 0, 0, 0, 152, 0, 16, 45, 0,
-  12, 0, 0, 0, 0, 0, 8, 0, 63, 0,
-  0, 6, 0, 72, 0, 0, 8, 0, 0, 0,
-  0, 0, 0, 0, 13, 0, 1, 0, 0, 0,
-  0, 44, 53, 0, 44, 0, 0, 0, 18, 0,
-  36, 0, 0, 72, 23, 0, 15, 0, 42, 0,
-  1, 20, 65, 0, 81, 0, 0, 14, 40, 0,
-  141, 0, 0, 33, 89, 0, 30, 0, 58, 0,
-  0, 0, 0, 0, 24, 23, 0, 0, 18, 24,
-  50, 29, 0, 0, 0, 30, 0, 5, 4, 7,
-  13, 0, 0, 0, 0, 53, 0, 0, 74, 59,
-  173, 47, 0, 0, 71, 0, 19, 0, 0, 20,
-  0, 24, 0, 0, 0, 0, 18, 88, 16, 0,
-  0, 16, 0, 67, 30, 34, 32, 0, 0, 4,
-  0, 6, 0, 39, 0, 0, 0, 0, 33, 0,
-  0, 14, 6, 12, 56, 3, 0, 51, 0, 0,
-  0, 3, 39, 0, 0, 33, 0, 0, 0, 48,
-  80, 41, 84, 0, 0, 0, 23, 0, 51, 0,
-  2, 59, 14, 2, 58, 0, 66, 2, 56, 3,
-  77, 5, 38, 0, 11, 0, 0, 0, 103, 0,
-  0, 17, 53, 0, 50, 0, 60, 0, 7, 11,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 12, 0, 0, 14, 34, 15, 0, 0,
-  26, 34, 0, 0, 0, 21, 29, 0, 8, 0,
-  0, 45, 0, 0, 48, 64, 6, 83, 0, 0,
-  55, 0, 0, 0, 0, 1, 0, 5, 0, 0,
-  0, 16, 10, 46, 0, 58, 0, 8, 7, 104,
-  37, 30, 33, 0, 15, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 6, 0, 0, 19, 0, 0,
-  21, 0, 0, 63, 0, 0, 0, 9, 39, 0,
-  0, 13, 0, 0, 0, 59, 43, 21, 114, 3,
-  0, 0, 28, 0, 36, 0, 0, 91, 40, 0,
-  32, 0, 7, 0, 28, 8, 75, 20, 37, 0,
-  0, 8, 5, 0, 131, 0, 0, 37, 103, 0,
-  101, 0, 70, 0, 0, 0, 0, 6, 23, 5,
-  0, 0, 44, 22, 34, 36, 0, 0, 1, 0,
-  0, 41, 20, 23, 3, 8, 0, 0, 0, 69,
-  18, 19, 51, 49, 164, 7, 0, 0, 85, 0,
-  15, 0, 0, 31, 6, 63, 0, 3, 29, 0,
-  23, 56, 20, 0, 0, 47, 0, 43, 48, 47,
-  7, 0, 0, 20, 0, 28, 0, 23, 0, 0,
-  0, 3, 58, 0, 2, 0, 18, 22, 54, 25,
-  23, 58, 0, 0, 0, 13, 76, 0, 7, 17,
-  0, 0, 4, 37, 62, 48, 83, 0, 0, 0,
-  8, 13, 24, 0, 0, 55, 0, 0, 26, 0,
-  38, 0, 56, 0, 44, 17, 29, 0, 10, 0,
-  0, 0, 37, 0, 0, 16, 21, 0, 77, 0,
-  71, 0, 5, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 62, 32, 0, 2, 1, 44, 3, 0, 0,
-  16, 4, 12, 0, 5, 53, 33, 30, 0, 74,
-  61, 0, 71, 46, 0, 36, 0, 3, 111, 34,
-  1, 0, 57, 0, 53, 22, 0, 16, 0, 48,
-  40, 30, 5, 36, 99, 16, 0, 12, 0, 8,
-  1, 0, 56, 0, 0, 0, 43, 0, 7, 33,
-  9, 0, 16, 0, 0, 0, 18, 21, 0, 0,
-  8, 32, 42, 43, 43, 31, 0, 15, 0, 0,
-  70, 13, 10, 0, 12, 12, 0, 0, 50, 9,
-  2, 0, 16, 0, 5, 73, 0, 0, 8, 21,
-  2, 0, 0, 16, 17, 0, 77, 9, 0, 22,
-  29, 1, 0, 33, 0, 0, 0, 15, 0, 33,
-  26, 0, 0, 0, 28, 0, 14, 0, 5, 45,
-  49, 8, 0, 13, 12, 23, 0, 0, 0, 49,
-  90, 0, 0, 29, 44, 13, 0, 25, 68, 58,
-  82, 13, 0, 0, 0, 11, 0, 0, 0, 0,
-  81, 0, 34, 31, 0, 20, 0, 59, 2, 29,
-  0, 28, 67, 52, 0, 60, 0, 43, 0, 42,
-  24, 0, 22, 0, 17, 0, 7, 0, 0, 0,
-  0, 9, 8, 0, 0, 0, 16, 0, 14, 13,
-  19, 19, 30, 0, 40, 53, 0, 19, 43, 0,
-  42, 0, 0, 11, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 33, 18, 0, 37, 45, 21, 0,
-  0, 23, 29, 0, 60, 0, 0, 7, 11, 13,
-  0, 17, 0, 0, 0, 0, 1, 9, 37, 0,
-  7, 0, 52, 0, 8, 2, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 74, 43, 0, 0, 0,
-  41, 0, 0, 0, 0, 15, 3, 0, 14, 72,
-  38, 47, 0, 64, 66, 0, 81, 51, 0, 26,
-  10, 14, 118, 35, 2, 0, 62, 0, 42, 8,
-  0, 26, 7, 52, 32, 25, 0, 26, 85, 30,
-  0, 8, 0, 25, 0, 13, 61, 0, 0, 0,
-  25, 0, 4, 20, 16, 0, 7, 0, 0, 0,
-  21, 2, 0, 0, 14, 32, 32, 38, 42, 30,
-  5, 5, 0, 0, 76, 3, 4, 0, 0, 15,
-  0, 0, 64, 23, 0, 0, 7, 0, 8, 49,
-  0, 0, 22, 10, 3, 0, 1, 17, 39, 0,
-  77, 0, 0, 43, 30, 0, 0, 41, 0, 0,
-  0, 3, 0, 15, 30, 0, 0, 0, 22, 0,
-  36, 0, 4, 47, 62, 10, 0, 19, 11, 10,
-  1, 0, 0, 51, 73, 0, 0, 33, 47, 24,
-  0, 20, 69, 64, 93, 12, 0, 0, 0, 23,
-  0, 0, 0, 0, 74, 0, 23, 28, 0, 28,
-  0, 48, 1, 24, 0, 19, 53, 57, 0, 57,
-  0, 37, 0, 54, 25, 0, 42, 0, 29, 0,
-  2, 0, 1, 0, 0, 20, 15, 0, 0, 0,
-  26, 0, 13, 15, 11, 22, 32, 0, 46, 51,
-  0, 12, 44, 0, 35, 0, 0, 8, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 24, 31, 0,
-  40, 41, 11, 0, 10, 24, 51, 0, 57, 0,
-  0, 3, 17, 15, 0, 12, 0, 0, 7, 0,
-  0, 7, 15, 4, 0, 0, 47, 0, 18, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 79,
-  42, 0, 0, 0, 53, 0, 5, 0, 0, 37,
-  2, 1, 18, 62, 41, 51, 0, 55, 86, 0,
-  87, 50, 0, 11, 5, 15, 128, 37, 1, 0,
-  72, 0, 36, 0, 0, 27, 0, 45, 39, 32,
-  0, 35, 80, 55, 0, 7, 0, 21, 12, 25,
-  62, 0, 16, 0, 27, 0, 29, 0, 13, 0,
-  11, 0, 0, 0, 25, 0, 9, 0, 3, 35,
-  41, 39, 37, 34, 23, 0, 0, 8, 79, 22,
-  1, 0, 0, 13, 0, 0, 82, 36, 0, 0,
-  20, 0, 0, 51, 0, 0, 48, 11, 5, 0,
-  0, 23, 29, 0, 77, 0, 0, 50, 18, 0,
-  0, 42, 0, 0, 0, 4, 5, 13, 24, 0,
-  0, 0, 28, 0, 34, 0, 7, 54, 57, 12,
-  0, 23, 17, 14, 2, 0, 0, 54, 68, 12,
-  2, 19, 58, 30, 0, 13, 72, 61, 94, 10,
-  0, 0, 0, 26, 0, 0, 0, 5, 68, 0,
-  20, 19, 0, 31, 0, 50, 4, 41, 0, 19,
-  53, 58, 0, 66, 0, 27, 0, 55, 24, 0,
-  51, 0, 26, 0, 10, 0, 0, 0, 0, 18,
-  3, 0, 0, 0, 34, 0, 14, 26, 9, 11,
-  35, 0, 48, 32, 0, 34, 37, 0, 35, 0,
-  0, 7, 0, 0, 0, 5, 0, 0, 0, 0,
-  0, 28, 25, 0, 59, 36, 0, 0, 14, 23,
-  43, 0, 49, 0, 0, 6, 11, 5, 0, 11,
-  0, 0, 8, 0, 8, 0, 0, 4, 5, 0,
-  45, 0, 20, 0, 0, 62, 32, 0, 2, 1,
-  44, 3, 0, 0, 16, 4, 12, 0, 5, 53,
-  33, 30, 0, 74, 61, 0, 71, 46, 0, 36,
-  0, 3, 111, 34, 1, 0, 57, 0, 53, 22,
-  0, 16, 0, 48, 40, 30, 5, 36, 99, 16,
-  0, 12, 0, 8, 1, 0, 56, 0, 0, 0,
-  43, 0, 7, 33, 9, 0, 16, 0, 0, 0,
-  18, 21, 0, 0, 8, 32, 42, 43, 43, 31,
-  0, 15, 0, 0, 70, 13, 10, 0, 12, 12,
-  0, 0, 50, 9, 2, 0, 16, 0, 5, 73,
-  0, 0, 8, 21, 2, 0, 0, 16, 17, 0,
-  77, 9, 0, 22, 29, 1, 0, 33, 0, 0,
-  0, 15, 0, 33, 26, 0, 0, 0, 28, 0,
-  14, 0, 5, 45, 49, 8, 0, 13, 12, 23,
-  0, 0, 0, 49, 90, 0, 0, 29, 44, 13,
-  0, 25, 68, 58, 82, 13, 0, 0, 0, 11,
-  0, 0, 0, 0, 81, 0, 34, 31, 0, 20,
-  0, 59, 2, 29, 0, 28, 67, 52, 0, 60,
-  0, 43, 0, 42, 24, 0, 22, 0, 17, 0,
-  7, 0, 0, 0, 0, 9, 8, 0, 0, 0,
-  16, 0, 14, 13, 19, 19, 30, 0, 40, 53,
-  0, 19, 43, 0, 42, 0, 0, 11, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 33, 18, 0,
-  37, 45, 21, 0, 0, 23, 29, 0, 60, 0,
-  0, 7, 11, 13, 0, 17, 0, 0, 0, 0,
-  1, 9, 37, 0, 7, 0, 52, 0, 8, 2,
-  2, 29, 35, 14, 0, 2, 25, 15, 25, 0,
-  0, 41, 100, 0, 19, 33, 52, 0, 0, 0,
-  0, 93, 0, 8, 42, 0, 0, 23, 0, 0,
-  0, 43, 78, 0, 33, 0, 0, 18, 0, 68,
-  0, 56, 40, 13, 39, 47, 17, 12, 0, 48,
-  0, 63, 25, 25, 42, 0, 13, 0, 12, 0,
-  4, 7, 0, 68, 0, 15, 1, 0, 32, 0,
-  7, 15, 0, 11, 0, 0, 44, 48, 0, 33,
-  43, 0, 60, 25, 0, 0, 0, 0, 0, 17,
-  0, 0, 0, 3, 0, 32, 43, 0, 2, 82,
-  3, 0, 8, 22, 34, 0, 25, 0, 0, 0,
-  17, 10, 0, 0, 0, 0, 0, 0, 2, 15,
-  15, 5, 38, 0, 55, 0, 13, 0, 0, 74,
-  43, 0, 0, 0, 41, 0, 0, 0, 0, 15,
-  3, 0, 14, 72, 38, 47, 0, 64, 66, 0,
-  81, 51, 0, 26, 10, 14, 118, 35, 2, 0,
-  62, 0, 42, 8, 0, 26, 7, 52, 32, 25,
-  0, 26, 85, 30, 0, 8, 0, 25, 0, 13,
-  61, 0, 0, 0, 25, 0, 4, 20, 16, 0,
-  7, 0, 0, 0, 21, 2, 0, 0, 14, 32,
-  32, 38, 42, 30, 5, 5, 0, 0, 76, 3,
-  4, 0, 0, 15, 0, 0, 64, 23, 0, 0,
-  7, 0, 8, 49, 0, 0, 22, 10, 3, 0,
-  1, 17, 39, 0, 77, 0, 0, 43, 30, 0,
-  0, 41, 0, 0, 0, 3, 0, 15, 30, 0,
-  0, 0, 22, 0, 36, 0, 4, 47, 62, 10,
-  0, 19, 11, 10, 1, 0, 0, 51, 73, 0,
-  0, 33, 47, 24, 0, 20, 69, 64, 93, 12,
-  0, 0, 0, 23, 0, 0, 0, 0, 74, 0,
-  23, 28, 0, 28, 0, 48, 1, 24, 0, 19,
-  53, 57, 0, 57, 0, 37, 0, 54, 25, 0,
-  42, 0, 29, 0, 2, 0, 1, 0, 0, 20,
-  15, 0, 0, 0, 26, 0, 13, 15, 11, 22,
-  32, 0, 46, 51, 0, 12, 44, 0, 35, 0,
-  0, 8, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 24, 31, 0, 40, 41, 11, 0, 10, 24,
-  51, 0, 57, 0, 0, 3, 17, 15, 0, 12,
-  0, 0, 7, 0, 0, 7, 15, 4, 0, 0,
-  47, 0, 18, 0, 3, 30, 27, 20, 0, 12,
-  23, 23, 27, 0, 0, 40, 83, 0, 11, 31,
-  57, 0, 0, 0, 0, 92, 0, 1, 37, 0,
-  0, 25, 0, 0, 0, 50, 77, 0, 34, 0,
-  0, 19, 0, 54, 0, 46, 24, 10, 34, 52,
-  12, 15, 0, 33, 0, 55, 12, 26, 53, 0,
-  30, 0, 10, 0, 0, 13, 0, 58, 0, 13,
-  0, 0, 32, 0, 13, 16, 12, 11, 0, 0,
-  49, 39, 0, 32, 30, 0, 50, 41, 0, 0,
-  7, 0, 0, 13, 0, 0, 0, 16, 0, 30,
-  52, 0, 6, 80, 2, 0, 18, 20, 43, 0,
-  29, 0, 4, 0, 21, 11, 0, 0, 0, 0,
-  0, 0, 0, 11, 4, 11, 36, 0, 51, 0,
-  18, 0, 0, 79, 42, 0, 0, 0, 53, 0,
-  5, 0, 0, 37, 2, 1, 18, 62, 41, 51,
-  0, 55, 86, 0, 87, 50, 0, 11, 5, 15,
-  128, 37, 1, 0, 72, 0, 36, 0, 0, 27,
-  0, 45, 39, 32, 0, 35, 80, 55, 0, 7,
-  0, 21, 12, 25, 62, 0, 16, 0, 27, 0,
-  29, 0, 13, 0, 11, 0, 0, 0, 25, 0,
-  9, 0, 3, 35, 41, 39, 37, 34, 23, 0,
-  0, 8, 79, 22, 1, 0, 0, 13, 0, 0,
-  82, 36, 0, 0, 20, 0, 0, 51, 0, 0,
-  48, 11, 5, 0, 0, 23, 29, 0, 77, 0,
-  0, 50, 18, 0, 0, 42, 0, 0, 0, 4,
-  5, 13, 24, 0, 0, 0, 28, 0, 34, 0,
-  7, 54, 57, 12, 0, 23, 17, 14, 2, 0,
-  0, 54, 68, 12, 2, 19, 58, 30, 0, 13,
-  72, 61, 94, 10, 0, 0, 0, 26, 0, 0,
-  0, 5, 68, 0, 20, 19, 0, 31, 0, 50,
-  4, 41, 0, 19, 53, 58, 0, 66, 0, 27,
-  0, 55, 24, 0, 51, 0, 26, 0, 10, 0,
-  0, 0, 0, 18, 3, 0, 0, 0, 34, 0,
-  14, 26, 9, 11, 35, 0, 48, 32, 0, 34,
-  37, 0, 35, 0, 0, 7, 0, 0, 0, 5,
-  0, 0, 0, 0, 0, 28, 25, 0, 59, 36,
-  0, 0, 14, 23, 43, 0, 49, 0, 0, 6,
-  11, 5, 0, 11, 0, 0, 8, 0, 8, 0,
-  0, 4, 5, 0, 45, 0, 20, 0, 10, 27,
-  29, 24, 0, 21, 22, 22, 24, 0, 0, 43,
-  79, 0, 6, 26, 56, 0, 0, 0, 0, 87,
-  1, 0, 41, 0, 0, 30, 0, 1, 0, 60,
-  72, 0, 24, 0, 0, 23, 0, 54, 0, 47,
-  13, 10, 23, 49, 26, 18, 0, 30, 0, 52,
-  4, 24, 54, 0, 32, 0, 10, 0, 1, 11,
-  0, 48, 0, 8, 0, 0, 39, 0, 18, 26,
-  11, 0, 0, 2, 47, 27, 0, 46, 24, 0,
-  46, 46, 0, 0, 13, 0, 0, 18, 0, 0,
-  0, 23, 0, 24, 55, 0, 15, 78, 0, 0,
-  25, 19, 40, 0, 26, 0, 5, 0, 17, 8,
-  0, 0, 0, 0, 7, 0, 0, 4, 0, 11,
-  36, 0, 55, 0, 17, 0, 5, 45, 49, 8,
-  0, 13, 12, 23, 0, 0, 0, 49, 90, 0,
-  0, 29, 44, 13, 0, 25, 68, 58, 82, 13,
-  0, 0, 0, 11, 0, 0, 0, 0, 81, 0,
-  34, 31, 0, 20, 0, 59, 2, 29, 0, 28,
-  67, 52, 0, 60, 0, 43, 0, 42, 24, 0,
-  22, 0, 17, 0, 7, 0, 0, 0, 0, 9,
-  8, 0, 0, 0, 16, 0, 14, 13, 19, 19,
-  30, 0, 40, 53, 0, 19, 43, 0, 42, 0,
-  0, 11, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 33, 18, 0, 37, 45, 21, 0, 0, 23,
-  29, 0, 60, 0, 0, 7, 11, 13, 0, 17,
-  0, 0, 0, 0, 1, 9, 37, 0, 7, 0,
-  52, 0, 8, 2, 2, 29, 35, 14, 0, 2,
-  25, 15, 25, 0, 0, 41, 100, 0, 19, 33,
-  52, 0, 0, 0, 0, 93, 0, 8, 42, 0,
-  0, 23, 0, 0, 0, 43, 78, 0, 33, 0,
-  0, 18, 0, 68, 0, 56, 40, 13, 39, 47,
-  17, 12, 0, 48, 0, 63, 25, 25, 42, 0,
-  13, 0, 12, 0, 4, 7, 0, 68, 0, 15,
-  1, 0, 32, 0, 7, 15, 0, 11, 0, 0,
-  44, 48, 0, 33, 43, 0, 60, 25, 0, 0,
-  0, 0, 0, 17, 0, 0, 0, 3, 0, 32,
-  43, 0, 2, 82, 3, 0, 8, 22, 34, 0,
-  25, 0, 0, 0, 17, 10, 0, 0, 0, 0,
-  0, 0, 2, 15, 15, 5, 38, 0, 55, 0,
-  13, 0, 0, 0, 0, 2, 0, 130, 10, 0,
-  4, 0, 0, 17, 27, 0, 0, 13, 0, 0,
-  0, 0, 39, 101, 22, 12, 0, 0, 0, 0,
-  0, 3, 0, 24, 35, 28, 1, 0, 0, 22,
-  0, 43, 0, 20, 0, 45, 17, 92, 24, 56,
-  0, 1, 0, 50, 0, 0, 17, 0, 51, 0,
-  51, 0, 0, 57, 0, 0, 72, 8, 0, 8,
-  34, 0, 64, 5, 28, 6, 0, 15, 34, 35,
-  0, 21, 42, 0, 36, 58, 0, 0, 16, 0,
-  0, 0, 0, 14, 4, 0, 0, 35, 0, 0,
-  0, 63, 44, 0, 0, 33, 35, 0, 21, 0,
-  0, 0, 3, 0, 0, 32, 0, 0, 109, 11,
-  25, 17, 0, 0, 0, 0, 15, 0, 0, 0,
-  4, 47, 62, 10, 0, 19, 11, 10, 1, 0,
-  0, 51, 73, 0, 0, 33, 47, 24, 0, 20,
-  69, 64, 93, 12, 0, 0, 0, 23, 0, 0,
-  0, 0, 74, 0, 23, 28, 0, 28, 0, 48,
-  1, 24, 0, 19, 53, 57, 0, 57, 0, 37,
-  0, 54, 25, 0, 42, 0, 29, 0, 2, 0,
-  1, 0, 0, 20, 15, 0, 0, 0, 26, 0,
-  13, 15, 11, 22, 32, 0, 46, 51, 0, 12,
-  44, 0, 35, 0, 0, 8, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 24, 31, 0, 40, 41,
-  11, 0, 10, 24, 51, 0, 57, 0, 0, 3,
-  17, 15, 0, 12, 0, 0, 7, 0, 0, 7,
-  15, 4, 0, 0, 47, 0, 18, 0, 3, 30,
-  27, 20, 0, 12, 23, 23, 27, 0, 0, 40,
-  83, 0, 11, 31, 57, 0, 0, 0, 0, 92,
-  0, 1, 37, 0, 0, 25, 0, 0, 0, 50,
-  77, 0, 34, 0, 0, 19, 0, 54, 0, 46,
-  24, 10, 34, 52, 12, 15, 0, 33, 0, 55,
-  12, 26, 53, 0, 30, 0, 10, 0, 0, 13,
-  0, 58, 0, 13, 0, 0, 32, 0, 13, 16,
-  12, 11, 0, 0, 49, 39, 0, 32, 30, 0,
-  50, 41, 0, 0, 7, 0, 0, 13, 0, 0,
-  0, 16, 0, 30, 52, 0, 6, 80, 2, 0,
-  18, 20, 43, 0, 29, 0, 4, 0, 21, 11,
-  0, 0, 0, 0, 0, 0, 0, 11, 4, 11,
-  36, 0, 51, 0, 18, 0, 0, 0, 0, 5,
-  0, 140, 8, 5, 3, 0, 0, 23, 36, 0,
-  0, 10, 2, 0, 0, 0, 35, 102, 17, 9,
-  0, 0, 0, 0, 0, 21, 0, 23, 35, 21,
-  4, 1, 0, 25, 0, 41, 0, 16, 0, 48,
-  13, 84, 13, 57, 0, 3, 0, 61, 0, 0,
-  24, 0, 45, 0, 39, 0, 0, 51, 0, 0,
-  78, 3, 0, 20, 24, 0, 67, 6, 31, 2,
-  0, 19, 16, 27, 0, 18, 39, 0, 33, 59,
-  0, 0, 10, 0, 0, 0, 0, 8, 0, 0,
-  12, 34, 0, 0, 0, 66, 43, 0, 0, 31,
-  31, 0, 26, 0, 0, 0, 14, 0, 0, 24,
-  0, 0, 117, 2, 21, 20, 0, 0, 0, 0,
-  24, 0, 0, 0, 7, 54, 57, 12, 0, 23,
-  17, 14, 2, 0, 0, 54, 68, 12, 2, 19,
-  58, 30, 0, 13, 72, 61, 94, 10, 0, 0,
-  0, 26, 0, 0, 0, 5, 68, 0, 20, 19,
-  0, 31, 0, 50, 4, 41, 0, 19, 53, 58,
-  0, 66, 0, 27, 0, 55, 24, 0, 51, 0,
-  26, 0, 10, 0, 0, 0, 0, 18, 3, 0,
-  0, 0, 34, 0, 14, 26, 9, 11, 35, 0,
-  48, 32, 0, 34, 37, 0, 35, 0, 0, 7,
-  0, 0, 0, 5, 0, 0, 0, 0, 0, 28,
-  25, 0, 59, 36, 0, 0, 14, 23, 43, 0,
-  49, 0, 0, 6, 11, 5, 0, 11, 0, 0,
-  8, 0, 8, 0, 0, 4, 5, 0, 45, 0,
-  20, 0, 10, 27, 29, 24, 0, 21, 22, 22,
-  24, 0, 0, 43, 79, 0, 6, 26, 56, 0,
-  0, 0, 0, 87, 1, 0, 41, 0, 0, 30,
-  0, 1, 0, 60, 72, 0, 24, 0, 0, 23,
-  0, 54, 0, 47, 13, 10, 23, 49, 26, 18,
-  0, 30, 0, 52, 4, 24, 54, 0, 32, 0,
-  10, 0, 1, 11, 0, 48, 0, 8, 0, 0,
-  39, 0, 18, 26, 11, 0, 0, 2, 47, 27,
-  0, 46, 24, 0, 46, 46, 0, 0, 13, 0,
-  0, 18, 0, 0, 0, 23, 0, 24, 55, 0,
-  15, 78, 0, 0, 25, 19, 40, 0, 26, 0,
-  5, 0, 17, 8, 0, 0, 0, 0, 7, 0,
-  0, 4, 0, 11, 36, 0, 55, 0, 17, 0,
-  0, 0, 0, 7, 0, 153, 0, 0, 0, 0,
-  0, 29, 38, 0, 0, 1, 3, 0, 0, 0,
-  24, 93, 13, 16, 0, 0, 0, 0, 0, 19,
-  0, 24, 31, 29, 0, 8, 0, 29, 0, 45,
-  0, 25, 0, 49, 3, 74, 23, 63, 0, 7,
-  0, 55, 0, 0, 19, 0, 43, 0, 36, 0,
-  0, 49, 0, 0, 76, 0, 0, 27, 37, 0,
-  74, 15, 23, 0, 0, 20, 11, 20, 0, 34,
-  35, 0, 40, 53, 0, 0, 16, 0, 0, 0,
-  0, 13, 0, 0, 26, 27, 0, 0, 0, 73,
-  26, 0, 0, 26, 12, 0, 22, 0, 0, 0,
-  6, 0, 0, 16, 0, 0, 114, 0, 19, 9,
-  0, 0, 0, 0, 29, 0, 0, 0, 2, 29,
-  35, 14, 0, 2, 25, 15, 25, 0, 0, 41,
-  100, 0, 19, 33, 52, 0, 0, 0, 0, 93,
-  0, 8, 42, 0, 0, 23, 0, 0, 0, 43,
-  78, 0, 33, 0, 0, 18, 0, 68, 0, 56,
-  40, 13, 39, 47, 17, 12, 0, 48, 0, 63,
-  25, 25, 42, 0, 13, 0, 12, 0, 4, 7,
-  0, 68, 0, 15, 1, 0, 32, 0, 7, 15,
-  0, 11, 0, 0, 44, 48, 0, 33, 43, 0,
-  60, 25, 0, 0, 0, 0, 0, 17, 0, 0,
-  0, 3, 0, 32, 43, 0, 2, 82, 3, 0,
-  8, 22, 34, 0, 25, 0, 0, 0, 17, 10,
-  0, 0, 0, 0, 0, 0, 2, 15, 15, 5,
-  38, 0, 55, 0, 13, 0, 0, 0, 0, 2,
-  0, 130, 10, 0, 4, 0, 0, 17, 27, 0,
-  0, 13, 0, 0, 0, 0, 39, 101, 22, 12,
-  0, 0, 0, 0, 0, 3, 0, 24, 35, 28,
-  1, 0, 0, 22, 0, 43, 0, 20, 0, 45,
-  17, 92, 24, 56, 0, 1, 0, 50, 0, 0,
-  17, 0, 51, 0, 51, 0, 0, 57, 0, 0,
-  72, 8, 0, 8, 34, 0, 64, 5, 28, 6,
-  0, 15, 34, 35, 0, 21, 42, 0, 36, 58,
-  0, 0, 16, 0, 0, 0, 0, 14, 4, 0,
-  0, 35, 0, 0, 0, 63, 44, 0, 0, 33,
-  35, 0, 21, 0, 0, 0, 3, 0, 0, 32,
-  0, 0, 109, 11, 25, 17, 0, 0, 0, 0,
-  15, 0, 0, 0, 0, 0, 0, 0, 0, 30,
-  33, 0, 19, 0, 21, 0, 43, 0, 16, 54,
-  29, 19, 0, 10, 66, 0, 0, 44, 0, 21,
-  4, 0, 0, 41, 0, 0, 53, 56, 9, 0,
-  0, 0, 0, 18, 0, 34, 0, 47, 24, 21,
-  4, 29, 0, 18, 41, 0, 75, 14, 0, 0,
-  37, 0, 0, 75, 15, 0, 0, 0, 0, 0,
-  34, 16, 0, 0, 0, 2, 0, 21, 12, 35,
-  14, 9, 0, 42, 59, 0, 15, 48, 23, 0,
-  5, 24, 11, 27, 9, 21, 0, 6, 17, 45,
-  0, 0, 9, 43, 26, 0, 0, 0, 17, 0,
-  51, 8, 2, 21, 33, 2, 0, 20, 0, 0,
-  46, 39, 44, 11, 0, 0, 80, 0, 29, 15,
-  0, 0, 3, 30, 27, 20, 0, 12, 23, 23,
-  27, 0, 0, 40, 83, 0, 11, 31, 57, 0,
-  0, 0, 0, 92, 0, 1, 37, 0, 0, 25,
-  0, 0, 0, 50, 77, 0, 34, 0, 0, 19,
-  0, 54, 0, 46, 24, 10, 34, 52, 12, 15,
-  0, 33, 0, 55, 12, 26, 53, 0, 30, 0,
-  10, 0, 0, 13, 0, 58, 0, 13, 0, 0,
-  32, 0, 13, 16, 12, 11, 0, 0, 49, 39,
-  0, 32, 30, 0, 50, 41, 0, 0, 7, 0,
-  0, 13, 0, 0, 0, 16, 0, 30, 52, 0,
-  6, 80, 2, 0, 18, 20, 43, 0, 29, 0,
-  4, 0, 21, 11, 0, 0, 0, 0, 0, 0,
-  0, 11, 4, 11, 36, 0, 51, 0, 18, 0,
-  0, 0, 0, 5, 0, 140, 8, 5, 3, 0,
-  0, 23, 36, 0, 0, 10, 2, 0, 0, 0,
-  35, 102, 17, 9, 0, 0, 0, 0, 0, 21,
-  0, 23, 35, 21, 4, 1, 0, 25, 0, 41,
-  0, 16, 0, 48, 13, 84, 13, 57, 0, 3,
-  0, 61, 0, 0, 24, 0, 45, 0, 39, 0,
-  0, 51, 0, 0, 78, 3, 0, 20, 24, 0,
-  67, 6, 31, 2, 0, 19, 16, 27, 0, 18,
-  39, 0, 33, 59, 0, 0, 10, 0, 0, 0,
-  0, 8, 0, 0, 12, 34, 0, 0, 0, 66,
-  43, 0, 0, 31, 31, 0, 26, 0, 0, 0,
-  14, 0, 0, 24, 0, 0, 117, 2, 21, 20,
-  0, 0, 0, 0, 24, 0, 0, 0, 0, 8,
-  0, 0, 0, 26, 43, 6, 20, 0, 13, 0,
-  59, 0, 10, 62, 36, 31, 3, 0, 46, 0,
-  0, 38, 0, 42, 6, 2, 0, 34, 0, 0,
-  63, 41, 15, 0, 0, 0, 0, 46, 0, 37,
-  0, 53, 25, 14, 17, 17, 0, 32, 15, 5,
-  91, 14, 0, 0, 28, 0, 0, 70, 0, 0,
-  0, 0, 0, 0, 24, 8, 0, 0, 0, 2,
-  0, 9, 17, 48, 0, 3, 0, 31, 71, 5,
-  13, 36, 17, 0, 4, 23, 26, 35, 36, 0,
-  0, 2, 17, 32, 0, 0, 2, 44, 36, 0,
-  0, 0, 12, 0, 55, 13, 24, 46, 43, 0,
-  0, 24, 0, 0, 42, 41, 44, 0, 0, 0,
-  108, 0, 71, 14, 0, 0, 10, 27, 29, 24,
-  0, 21, 22, 22, 24, 0, 0, 43, 79, 0,
-  6, 26, 56, 0, 0, 0, 0, 87, 1, 0,
-  41, 0, 0, 30, 0, 1, 0, 60, 72, 0,
-  24, 0, 0, 23, 0, 54, 0, 47, 13, 10,
-  23, 49, 26, 18, 0, 30, 0, 52, 4, 24,
-  54, 0, 32, 0, 10, 0, 1, 11, 0, 48,
-  0, 8, 0, 0, 39, 0, 18, 26, 11, 0,
-  0, 2, 47, 27, 0, 46, 24, 0, 46, 46,
-  0, 0, 13, 0, 0, 18, 0, 0, 0, 23,
-  0, 24, 55, 0, 15, 78, 0, 0, 25, 19,
-  40, 0, 26, 0, 5, 0, 17, 8, 0, 0,
-  0, 0, 7, 0, 0, 4, 0, 11, 36, 0,
-  55, 0, 17, 0, 0, 0, 0, 7, 0, 153,
-  0, 0, 0, 0, 0, 29, 38, 0, 0, 1,
-  3, 0, 0, 0, 24, 93, 13, 16, 0, 0,
-  0, 0, 0, 19, 0, 24, 31, 29, 0, 8,
-  0, 29, 0, 45, 0, 25, 0, 49, 3, 74,
-  23, 63, 0, 7, 0, 55, 0, 0, 19, 0,
-  43, 0, 36, 0, 0, 49, 0, 0, 76, 0,
-  0, 27, 37, 0, 74, 15, 23, 0, 0, 20,
-  11, 20, 0, 34, 35, 0, 40, 53, 0, 0,
-  16, 0, 0, 0, 0, 13, 0, 0, 26, 27,
-  0, 0, 0, 73, 26, 0, 0, 26, 12, 0,
-  22, 0, 0, 0, 6, 0, 0, 16, 0, 0,
-  114, 0, 19, 9, 0, 0, 0, 0, 29, 0,
-  0, 0, 0, 17, 0, 0, 0, 31, 35, 0,
-  13, 0, 8, 0, 56, 4, 16, 62, 36, 39,
-  10, 0, 30, 0, 0, 48, 4, 53, 0, 4,
-  0, 15, 0, 0, 72, 44, 0, 0, 0, 0,
-  0, 66, 0, 41, 0, 43, 20, 12, 12, 36,
-  0, 41, 0, 7, 95, 16, 0, 0, 21, 0,
-  0, 55, 9, 0, 0, 0, 0, 0, 32, 12,
-  11, 0, 0, 0, 0, 15, 10, 55, 0, 0,
-  0, 47, 64, 4, 32, 22, 15, 0, 7, 27,
-  13, 34, 54, 16, 0, 11, 39, 32, 0, 0,
-  0, 68, 22, 0, 0, 0, 0, 0, 48, 0,
-  0, 30, 26, 15, 0, 27, 0, 0, 25, 30,
-  24, 3, 1, 0, 121, 0, 65, 2, 0, 0,
-  0, 0, 0, 2, 0, 130, 10, 0, 4, 0,
-  0, 17, 27, 0, 0, 13, 0, 0, 0, 0,
-  39, 101, 22, 12, 0, 0, 0, 0, 0, 3,
-  0, 24, 35, 28, 1, 0, 0, 22, 0, 43,
-  0, 20, 0, 45, 17, 92, 24, 56, 0, 1,
-  0, 50, 0, 0, 17, 0, 51, 0, 51, 0,
-  0, 57, 0, 0, 72, 8, 0, 8, 34, 0,
-  64, 5, 28, 6, 0, 15, 34, 35, 0, 21,
-  42, 0, 36, 58, 0, 0, 16, 0, 0, 0,
-  0, 14, 4, 0, 0, 35, 0, 0, 0, 63,
-  44, 0, 0, 33, 35, 0, 21, 0, 0, 0,
-  3, 0, 0, 32, 0, 0, 109, 11, 25, 17,
-  0, 0, 0, 0, 15, 0, 0, 0, 0, 0,
-  0, 0, 0, 30, 33, 0, 19, 0, 21, 0,
-  43, 0, 16, 54, 29, 19, 0, 10, 66, 0,
-  0, 44, 0, 21, 4, 0, 0, 41, 0, 0,
-  53, 56, 9, 0, 0, 0, 0, 18, 0, 34,
-  0, 47, 24, 21, 4, 29, 0, 18, 41, 0,
-  75, 14, 0, 0, 37, 0, 0, 75, 15, 0,
-  0, 0, 0, 0, 34, 16, 0, 0, 0, 2,
-  0, 21, 12, 35, 14, 9, 0, 42, 59, 0,
-  15, 48, 23, 0, 5, 24, 11, 27, 9, 21,
-  0, 6, 17, 45, 0, 0, 9, 43, 26, 0,
-  0, 0, 17, 0, 51, 8, 2, 21, 33, 2,
-  0, 20, 0, 0, 46, 39, 44, 11, 0, 0,
-  80, 0, 29, 15, 0, 0, 0, 47, 63, 0,
-  0, 0, 0, 0, 44, 1, 0, 11, 10, 3,
-  0, 58, 41, 16, 11, 0, 10, 0, 65, 40,
-  0, 0, 36, 16, 0, 0, 0, 0, 20, 0,
-  20, 14, 0, 0, 0, 16, 0, 3, 0, 22,
-  0, 2, 0, 0, 0, 1, 57, 3, 31, 0,
-  0, 0, 29, 0, 0, 14, 3, 0, 0, 0,
-  16, 0, 39, 2, 0, 0, 0, 0, 0, 49,
-  17, 0, 0, 86, 0, 30, 13, 0, 52, 56,
-  3, 30, 0, 29, 23, 24, 50, 0, 0, 0,
-  17, 0, 0, 0, 0, 53, 48, 0, 0, 0,
-  13, 0, 61, 0, 0, 31, 25, 0, 0, 5,
-  0, 0, 7, 0, 0, 16, 0, 0, 30, 0,
-  18, 13, 0, 31, 0, 0, 0, 5, 0, 140,
-  8, 5, 3, 0, 0, 23, 36, 0, 0, 10,
-  2, 0, 0, 0, 35, 102, 17, 9, 0, 0,
-  0, 0, 0, 21, 0, 23, 35, 21, 4, 1,
-  0, 25, 0, 41, 0, 16, 0, 48, 13, 84,
-  13, 57, 0, 3, 0, 61, 0, 0, 24, 0,
-  45, 0, 39, 0, 0, 51, 0, 0, 78, 3,
-  0, 20, 24, 0, 67, 6, 31, 2, 0, 19,
-  16, 27, 0, 18, 39, 0, 33, 59, 0, 0,
-  10, 0, 0, 0, 0, 8, 0, 0, 12, 34,
-  0, 0, 0, 66, 43, 0, 0, 31, 31, 0,
-  26, 0, 0, 0, 14, 0, 0, 24, 0, 0,
-  117, 2, 21, 20, 0, 0, 0, 0, 24, 0,
-  0, 0, 0, 8, 0, 0, 0, 26, 43, 6,
-  20, 0, 13, 0, 59, 0, 10, 62, 36, 31,
-  3, 0, 46, 0, 0, 38, 0, 42, 6, 2,
-  0, 34, 0, 0, 63, 41, 15, 0, 0, 0,
-  0, 46, 0, 37, 0, 53, 25, 14, 17, 17,
-  0, 32, 15, 5, 91, 14, 0, 0, 28, 0,
-  0, 70, 0, 0, 0, 0, 0, 0, 24, 8,
-  0, 0, 0, 2, 0, 9, 17, 48, 0, 3,
-  0, 31, 71, 5, 13, 36, 17, 0, 4, 23,
-  26, 35, 36, 0, 0, 2, 17, 32, 0, 0,
-  2, 44, 36, 0, 0, 0, 12, 0, 55, 13,
-  24, 46, 43, 0, 0, 24, 0, 0, 42, 41,
-  44, 0, 0, 0, 108, 0, 71, 14, 0, 0,
-  0, 44, 70, 0, 0, 0, 0, 9, 53, 0,
-  0, 29, 11, 20, 0, 36, 26, 0, 0, 0,
-  0, 7, 73, 51, 0, 0, 16, 18, 0, 0,
-  0, 0, 0, 0, 29, 22, 0, 0, 0, 40,
-  0, 13, 0, 10, 0, 1, 22, 0, 0, 0,
-  35, 32, 22, 15, 0, 0, 28, 0, 0, 0,
-  0, 0, 0, 0, 20, 0, 30, 0, 2, 0,
-  0, 8, 3, 20, 33, 0, 0, 85, 0, 28,
-  19, 0, 42, 48, 0, 18, 0, 36, 33, 9,
-  46, 0, 0, 0, 8, 0, 0, 0, 0, 81,
-  37, 0, 0, 0, 25, 0, 70, 0, 22, 26,
-  14, 0, 0, 8, 0, 0, 28, 0, 0, 18,
-  0, 0, 19, 0, 44, 20, 0, 20, 0, 0,
-  0, 7, 0, 153, 0, 0, 0, 0, 0, 29,
-  38, 0, 0, 1, 3, 0, 0, 0, 24, 93,
-  13, 16, 0, 0, 0, 0, 0, 19, 0, 24,
-  31, 29, 0, 8, 0, 29, 0, 45, 0, 25,
-  0, 49, 3, 74, 23, 63, 0, 7, 0, 55,
-  0, 0, 19, 0, 43, 0, 36, 0, 0, 49,
-  0, 0, 76, 0, 0, 27, 37, 0, 74, 15,
-  23, 0, 0, 20, 11, 20, 0, 34, 35, 0,
-  40, 53, 0, 0, 16, 0, 0, 0, 0, 13,
-  0, 0, 26, 27, 0, 0, 0, 73, 26, 0,
-  0, 26, 12, 0, 22, 0, 0, 0, 6, 0,
-  0, 16, 0, 0, 114, 0, 19, 9, 0, 0,
-  0, 0, 29, 0, 0, 0, 0, 17, 0, 0,
-  0, 31, 35, 0, 13, 0, 8, 0, 56, 4,
-  16, 62, 36, 39, 10, 0, 30, 0, 0, 48,
-  4, 53, 0, 4, 0, 15, 0, 0, 72, 44,
-  0, 0, 0, 0, 0, 66, 0, 41, 0, 43,
-  20, 12, 12, 36, 0, 41, 0, 7, 95, 16,
-  0, 0, 21, 0, 0, 55, 9, 0, 0, 0,
-  0, 0, 32, 12, 11, 0, 0, 0, 0, 15,
-  10, 55, 0, 0, 0, 47, 64, 4, 32, 22,
-  15, 0, 7, 27, 13, 34, 54, 16, 0, 11,
-  39, 32, 0, 0, 0, 68, 22, 0, 0, 0,
-  0, 0, 48, 0, 0, 30, 26, 15, 0, 27,
-  0, 0, 25, 30, 24, 3, 1, 0, 121, 0,
-  65, 2, 0, 0, 0, 31, 59, 0, 8, 0,
-  0, 0, 53, 2, 0, 9, 30, 0, 0, 23,
-  15, 0, 8, 0, 0, 47, 79, 53, 0, 0,
-  0, 15, 0, 0, 0, 0, 0, 0, 52, 28,
-  0, 4, 0, 63, 0, 25, 0, 1, 0, 0,
-  25, 4, 0, 6, 0, 48, 20, 26, 0, 0,
-  19, 0, 8, 0, 0, 13, 0, 0, 18, 0,
-  16, 0, 9, 0, 10, 19, 20, 21, 21, 5,
-  0, 89, 0, 46, 12, 0, 50, 44, 4, 2,
-  0, 39, 7, 1, 49, 0, 0, 0, 4, 0,
-  0, 0, 6, 91, 22, 0, 0, 0, 9, 0,
-  71, 0, 0, 9, 0, 0, 0, 14, 0, 0,
-  23, 0, 0, 33, 0, 0, 26, 0, 73, 2,
-  0, 1, 0, 0, 0, 0, 0, 30, 33, 0,
-  19, 0, 21, 0, 43, 0, 16, 54, 29, 19,
-  0, 10, 66, 0, 0, 44, 0, 21, 4, 0,
-  0, 41, 0, 0, 53, 56, 9, 0, 0, 0,
-  0, 18, 0, 34, 0, 47, 24, 21, 4, 29,
-  0, 18, 41, 0, 75, 14, 0, 0, 37, 0,
-  0, 75, 15, 0, 0, 0, 0, 0, 34, 16,
-  0, 0, 0, 2, 0, 21, 12, 35, 14, 9,
-  0, 42, 59, 0, 15, 48, 23, 0, 5, 24,
-  11, 27, 9, 21, 0, 6, 17, 45, 0, 0,
-  9, 43, 26, 0, 0, 0, 17, 0, 51, 8,
-  2, 21, 33, 2, 0, 20, 0, 0, 46, 39,
-  44, 11, 0, 0, 80, 0, 29, 15, 0, 0,
-  0, 47, 63, 0, 0, 0, 0, 0, 44, 1,
-  0, 11, 10, 3, 0, 58, 41, 16, 11, 0,
-  10, 0, 65, 40, 0, 0, 36, 16, 0, 0,
-  0, 0, 20, 0, 20, 14, 0, 0, 0, 16,
-  0, 3, 0, 22, 0, 2, 0, 0, 0, 1,
-  57, 3, 31, 0, 0, 0, 29, 0, 0, 14,
-  3, 0, 0, 0, 16, 0, 39, 2, 0, 0,
-  0, 0, 0, 49, 17, 0, 0, 86, 0, 30,
-  13, 0, 52, 56, 3, 30, 0, 29, 23, 24,
-  50, 0, 0, 0, 17, 0, 0, 0, 0, 53,
-  48, 0, 0, 0, 13, 0, 61, 0, 0, 31,
-  25, 0, 0, 5, 0, 0, 7, 0, 0, 16,
-  0, 0, 30, 0, 18, 13, 0, 31, 103, 0,
-  37, 5, 6, 15, 0, 0, 15, 0, 0, 23,
-  47, 54, 0, 0, 22, 0, 6, 0, 0, 173,
-  80, 13, 0, 0, 0, 33, 0, 0, 2, 56,
-  0, 34, 0, 21, 0, 29, 0, 25, 0, 22,
-  0, 0, 27, 6, 10, 8, 0, 0, 0, 77,
-  0, 0, 89, 0, 43, 20, 45, 0, 35, 11,
-  0, 32, 30, 49, 7, 15, 23, 23, 7, 28,
-  0, 22, 0, 0, 3, 45, 0, 13, 0, 0,
-  4, 42, 8, 27, 0, 9, 0, 0, 0, 0,
-  8, 0, 7, 0, 24, 0, 27, 61, 2, 0,
-  25, 0, 40, 28, 4, 8, 10, 35, 4, 0,
-  0, 0, 0, 15, 78, 0, 23, 10, 0, 35,
-  0, 0, 20, 3, 3, 48, 0, 8, 0, 0,
-  0, 26, 43, 6, 20, 0, 13, 0, 59, 0,
-  10, 62, 36, 31, 3, 0, 46, 0, 0, 38,
-  0, 42, 6, 2, 0, 34, 0, 0, 63, 41,
-  15, 0, 0, 0, 0, 46, 0, 37, 0, 53,
-  25, 14, 17, 17, 0, 32, 15, 5, 91, 14,
-  0, 0, 28, 0, 0, 70, 0, 0, 0, 0,
-  0, 0, 24, 8, 0, 0, 0, 2, 0, 9,
-  17, 48, 0, 3, 0, 31, 71, 5, 13, 36,
-  17, 0, 4, 23, 26, 35, 36, 0, 0, 2,
-  17, 32, 0, 0, 2, 44, 36, 0, 0, 0,
-  12, 0, 55, 13, 24, 46, 43, 0, 0, 24,
-  0, 0, 42, 41, 44, 0, 0, 0, 108, 0,
-  71, 14, 0, 0, 0, 44, 70, 0, 0, 0,
-  0, 9, 53, 0, 0, 29, 11, 20, 0, 36,
-  26, 0, 0, 0, 0, 7, 73, 51, 0, 0,
-  16, 18, 0, 0, 0, 0, 0, 0, 29, 22,
-  0, 0, 0, 40, 0, 13, 0, 10, 0, 1,
-  22, 0, 0, 0, 35, 32, 22, 15, 0, 0,
-  28, 0, 0, 0, 0, 0, 0, 0, 20, 0,
-  30, 0, 2, 0, 0, 8, 3, 20, 33, 0,
-  0, 85, 0, 28, 19, 0, 42, 48, 0, 18,
-  0, 36, 33, 9, 46, 0, 0, 0, 8, 0,
-  0, 0, 0, 81, 37, 0, 0, 0, 25, 0,
-  70, 0, 22, 26, 14, 0, 0, 8, 0, 0,
-  28, 0, 0, 18, 0, 0, 19, 0, 44, 20,
-  0, 20, 102, 0, 40, 4, 0, 12, 0, 0,
-  45, 0, 0, 35, 56, 20, 0, 0, 9, 0,
-  0, 0, 0, 189, 80, 25, 0, 0, 0, 31,
-  0, 0, 16, 61, 0, 11, 0, 30, 0, 40,
-  0, 30, 0, 28, 48, 0, 38, 21, 24, 29,
-  0, 0, 0, 80, 0, 0, 100, 0, 63, 0,
-  47, 0, 14, 23, 0, 56, 27, 66, 0, 1,
-  0, 4, 12, 26, 10, 13, 0, 0, 0, 47,
-  0, 15, 0, 0, 7, 21, 0, 11, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 25, 0,
-  18, 61, 0, 0, 17, 0, 54, 23, 26, 12,
-  6, 14, 8, 6, 0, 0, 0, 2, 87, 0,
-  36, 39, 0, 9, 0, 0, 23, 15, 18, 29,
-  0, 17, 0, 0, 0, 31, 35, 0, 13, 0,
-  8, 0, 56, 4, 16, 62, 36, 39, 10, 0,
-  30, 0, 0, 48, 4, 53, 0, 4, 0, 15,
-  0, 0, 72, 44, 0, 0, 0, 0, 0, 66,
-  0, 41, 0, 43, 20, 12, 12, 36, 0, 41,
-  0, 7, 95, 16, 0, 0, 21, 0, 0, 55,
-  9, 0, 0, 0, 0, 0, 32, 12, 11, 0,
-  0, 0, 0, 15, 10, 55, 0, 0, 0, 47,
-  64, 4, 32, 22, 15, 0, 7, 27, 13, 34,
-  54, 16, 0, 11, 39, 32, 0, 0, 0, 68,
-  22, 0, 0, 0, 0, 0, 48, 0, 0, 30,
-  26, 15, 0, 27, 0, 0, 25, 30, 24, 3,
-  1, 0, 121, 0, 65, 2, 0, 0, 0, 31,
-  59, 0, 8, 0, 0, 0, 53, 2, 0, 9,
-  30, 0, 0, 23, 15, 0, 8, 0, 0, 47,
-  79, 53, 0, 0, 0, 15, 0, 0, 0, 0,
-  0, 0, 52, 28, 0, 4, 0, 63, 0, 25,
-  0, 1, 0, 0, 25, 4, 0, 6, 0, 48,
-  20, 26, 0, 0, 19, 0, 8, 0, 0, 13,
-  0, 0, 18, 0, 16, 0, 9, 0, 10, 19,
-  20, 21, 21, 5, 0, 89, 0, 46, 12, 0,
-  50, 44, 4, 2, 0, 39, 7, 1, 49, 0,
-  0, 0, 4, 0, 0, 0, 6, 91, 22, 0,
-  0, 0, 9, 0, 71, 0, 0, 9, 0, 0,
-  0, 14, 0, 0, 23, 0, 0, 33, 0, 0,
-  26, 0, 73, 2, 0, 1, 73, 0, 21, 29,
-  10, 2, 0, 11, 74, 0, 0, 18, 94, 0,
-  0, 0, 36, 0, 0, 0, 0, 148, 91, 19,
-  0, 0, 0, 47, 0, 0, 32, 47, 0, 0,
-  27, 32, 0, 52, 0, 43, 0, 24, 66, 17,
-  51, 51, 13, 28, 0, 0, 0, 63, 0, 0,
-  62, 0, 50, 0, 39, 0, 0, 6, 0, 30,
-  12, 20, 0, 4, 0, 0, 19, 4, 40, 42,
-  0, 0, 0, 87, 0, 19, 0, 0, 16, 26,
-  0, 11, 0, 0, 0, 0, 0, 0, 0, 8,
-  0, 0, 35, 0, 15, 55, 0, 0, 22, 0,
-  52, 8, 59, 31, 3, 19, 8, 16, 0, 0,
-  0, 0, 66, 0, 18, 40, 0, 4, 0, 0,
-  51, 0, 18, 14, 0, 47, 63, 0, 0, 0,
-  0, 0, 44, 1, 0, 11, 10, 3, 0, 58,
-  41, 16, 11, 0, 10, 0, 65, 40, 0, 0,
-  36, 16, 0, 0, 0, 0, 20, 0, 20, 14,
-  0, 0, 0, 16, 0, 3, 0, 22, 0, 2,
-  0, 0, 0, 1, 57, 3, 31, 0, 0, 0,
-  29, 0, 0, 14, 3, 0, 0, 0, 16, 0,
-  39, 2, 0, 0, 0, 0, 0, 49, 17, 0,
-  0, 86, 0, 30, 13, 0, 52, 56, 3, 30,
-  0, 29, 23, 24, 50, 0, 0, 0, 17, 0,
-  0, 0, 0, 53, 48, 0, 0, 0, 13, 0,
-  61, 0, 0, 31, 25, 0, 0, 5, 0, 0,
-  7, 0, 0, 16, 0, 0, 30, 0, 18, 13,
-  0, 31, 103, 0, 37, 5, 6, 15, 0, 0,
-  15, 0, 0, 23, 47, 54, 0, 0, 22, 0,
-  6, 0, 0, 173, 80, 13, 0, 0, 0, 33,
-  0, 0, 2, 56, 0, 34, 0, 21, 0, 29,
-  0, 25, 0, 22, 0, 0, 27, 6, 10, 8,
-  0, 0, 0, 77, 0, 0, 89, 0, 43, 20,
-  45, 0, 35, 11, 0, 32, 30, 49, 7, 15,
-  23, 23, 7, 28, 0, 22, 0, 0, 3, 45,
-  0, 13, 0, 0, 4, 42, 8, 27, 0, 9,
-  0, 0, 0, 0, 8, 0, 7, 0, 24, 0,
-  27, 61, 2, 0, 25, 0, 40, 28, 4, 8,
-  10, 35, 4, 0, 0, 0, 0, 15, 78, 0,
-  23, 10, 0, 35, 0, 0, 20, 3, 3, 48,
-  45, 0, 0, 0, 22, 82, 0, 0, 8, 0,
-  0, 0, 29, 61, 0, 8, 48, 0, 0, 0,
-  21, 71, 5, 41, 10, 3, 0, 14, 0, 2,
-  0, 9, 0, 69, 34, 19, 0, 41, 0, 34,
-  7, 20, 0, 34, 59, 23, 26, 10, 5, 0,
-  0, 0, 0, 0, 0, 0, 18, 22, 10, 15,
-  30, 39, 10, 0, 0, 0, 16, 36, 52, 0,
-  27, 32, 3, 0, 12, 28, 0, 21, 0, 48,
-  0, 2, 0, 34, 13, 5, 17, 11, 0, 25,
-  0, 47, 10, 1, 26, 5, 0, 0, 0, 67,
-  13, 0, 12, 0, 16, 0, 0, 15, 0, 51,
-  0, 0, 0, 0, 0, 0, 69, 0, 19, 0,
-  19, 11, 0, 0, 29, 2, 31, 0, 0, 44,
-  70, 0, 0, 0, 0, 9, 53, 0, 0, 29,
-  11, 20, 0, 36, 26, 0, 0, 0, 0, 7,
-  73, 51, 0, 0, 16, 18, 0, 0, 0, 0,
-  0, 0, 29, 22, 0, 0, 0, 40, 0, 13,
-  0, 10, 0, 1, 22, 0, 0, 0, 35, 32,
-  22, 15, 0, 0, 28, 0, 0, 0, 0, 0,
-  0, 0, 20, 0, 30, 0, 2, 0, 0, 8,
-  3, 20, 33, 0, 0, 85, 0, 28, 19, 0,
-  42, 48, 0, 18, 0, 36, 33, 9, 46, 0,
-  0, 0, 8, 0, 0, 0, 0, 81, 37, 0,
-  0, 0, 25, 0, 70, 0, 22, 26, 14, 0,
-  0, 8, 0, 0, 28, 0, 0, 18, 0, 0,
-  19, 0, 44, 20, 0, 20, 102, 0, 40, 4,
-  0, 12, 0, 0, 45, 0, 0, 35, 56, 20,
-  0, 0, 9, 0, 0, 0, 0, 189, 80, 25,
-  0, 0, 0, 31, 0, 0, 16, 61, 0, 11,
-  0, 30, 0, 40, 0, 30, 0, 28, 48, 0,
-  38, 21, 24, 29, 0, 0, 0, 80, 0, 0,
-  100, 0, 63, 0, 47, 0, 14, 23, 0, 56,
-  27, 66, 0, 1, 0, 4, 12, 26, 10, 13,
-  0, 0, 0, 47, 0, 15, 0, 0, 7, 21,
-  0, 11, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 25, 0, 18, 61, 0, 0, 17, 0,
-  54, 23, 26, 12, 6, 14, 8, 6, 0, 0,
-  0, 2, 87, 0, 36, 39, 0, 9, 0, 0,
-  23, 15, 18, 29, 9, 0, 0, 9, 0, 65,
-  0, 0, 41, 0, 0, 0, 45, 38, 0, 38,
-  32, 25, 0, 0, 8, 14, 5, 56, 28, 0,
-  0, 19, 0, 0, 0, 21, 10, 40, 27, 4,
-  0, 33, 0, 8, 9, 4, 50, 58, 50, 77,
-  14, 17, 0, 0, 0, 0, 0, 0, 0, 0,
-  54, 0, 0, 0, 4, 43, 0, 0, 0, 0,
-  0, 0, 12, 0, 54, 0, 14, 11, 0, 28,
-  0, 28, 0, 28, 0, 16, 0, 39, 0, 0,
-  31, 0, 14, 62, 0, 63, 0, 0, 13, 17,
-  0, 0, 0, 56, 19, 0, 0, 0, 17, 0,
-  0, 4, 0, 40, 0, 0, 0, 9, 0, 0,
-  61, 0, 8, 0, 37, 0, 3, 0, 29, 10,
-  44, 0, 0, 31, 59, 0, 8, 0, 0, 0,
-  53, 2, 0, 9, 30, 0, 0, 23, 15, 0,
-  8, 0, 0, 47, 79, 53, 0, 0, 0, 15,
-  0, 0, 0, 0, 0, 0, 52, 28, 0, 4,
-  0, 63, 0, 25, 0, 1, 0, 0, 25, 4,
-  0, 6, 0, 48, 20, 26, 0, 0, 19, 0,
-  8, 0, 0, 13, 0, 0, 18, 0, 16, 0,
-  9, 0, 10, 19, 20, 21, 21, 5, 0, 89,
-  0, 46, 12, 0, 50, 44, 4, 2, 0, 39,
-  7, 1, 49, 0, 0, 0, 4, 0, 0, 0,
-  6, 91, 22, 0, 0, 0, 9, 0, 71, 0,
-  0, 9, 0, 0, 0, 14, 0, 0, 23, 0,
-  0, 33, 0, 0, 26, 0, 73, 2, 0, 1,
-  73, 0, 21, 29, 10, 2, 0, 11, 74, 0,
-  0, 18, 94, 0, 0, 0, 36, 0, 0, 0,
-  0, 148, 91, 19, 0, 0, 0, 47, 0, 0,
-  32, 47, 0, 0, 27, 32, 0, 52, 0, 43,
-  0, 24, 66, 17, 51, 51, 13, 28, 0, 0,
-  0, 63, 0, 0, 62, 0, 50, 0, 39, 0,
-  0, 6, 0, 30, 12, 20, 0, 4, 0, 0,
-  19, 4, 40, 42, 0, 0, 0, 87, 0, 19,
-  0, 0, 16, 26, 0, 11, 0, 0, 0, 0,
-  0, 0, 0, 8, 0, 0, 35, 0, 15, 55,
-  0, 0, 22, 0, 52, 8, 59, 31, 3, 19,
-  8, 16, 0, 0, 0, 0, 66, 0, 18, 40,
-  0, 4, 0, 0, 51, 0, 18, 14, 0, 0,
-  0, 29, 1, 29, 8, 0, 54, 0, 0, 0,
-  67, 10, 9, 37, 50, 41, 0, 0, 0, 0,
-  0, 46, 33, 11, 2, 31, 0, 0, 8, 47,
-  45, 22, 0, 0, 0, 51, 0, 0, 0, 0,
-  95, 63, 29, 90, 0, 25, 0, 0, 0, 1,
-  11, 3, 0, 0, 29, 0, 0, 1, 0, 38,
-  0, 0, 3, 0, 26, 25, 4, 0, 48, 0,
-  30, 61, 0, 8, 0, 30, 0, 18, 0, 0,
-  0, 54, 0, 2, 33, 0, 0, 26, 0, 44,
-  0, 32, 0, 43, 0, 0, 0, 39, 13, 0,
-  8, 0, 38, 0, 3, 19, 0, 10, 9, 7,
-  0, 4, 0, 0, 50, 0, 0, 18, 13, 0,
-  27, 0, 42, 0, 53, 0, 103, 0, 37, 5,
-  6, 15, 0, 0, 15, 0, 0, 23, 47, 54,
-  0, 0, 22, 0, 6, 0, 0, 173, 80, 13,
-  0, 0, 0, 33, 0, 0, 2, 56, 0, 34,
-  0, 21, 0, 29, 0, 25, 0, 22, 0, 0,
-  27, 6, 10, 8, 0, 0, 0, 77, 0, 0,
-  89, 0, 43, 20, 45, 0, 35, 11, 0, 32,
-  30, 49, 7, 15, 23, 23, 7, 28, 0, 22,
-  0, 0, 3, 45, 0, 13, 0, 0, 4, 42,
-  8, 27, 0, 9, 0, 0, 0, 0, 8, 0,
-  7, 0, 24, 0, 27, 61, 2, 0, 25, 0,
-  40, 28, 4, 8, 10, 35, 4, 0, 0, 0,
-  0, 15, 78, 0, 23, 10, 0, 35, 0, 0,
-  20, 3, 3, 48, 45, 0, 0, 0, 22, 82,
-  0, 0, 8, 0, 0, 0, 29, 61, 0, 8,
-  48, 0, 0, 0, 21, 71, 5, 41, 10, 3,
-  0, 14, 0, 2, 0, 9, 0, 69, 34, 19,
-  0, 41, 0, 34, 7, 20, 0, 34, 59, 23,
-  26, 10, 5, 0, 0, 0, 0, 0, 0, 0,
-  18, 22, 10, 15, 30, 39, 10, 0, 0, 0,
-  16, 36, 52, 0, 27, 32, 3, 0, 12, 28,
-  0, 21, 0, 48, 0, 2, 0, 34, 13, 5,
-  17, 11, 0, 25, 0, 47, 10, 1, 26, 5,
-  0, 0, 0, 67, 13, 0, 12, 0, 16, 0,
-  0, 15, 0, 51, 0, 0, 0, 0, 0, 0,
-  69, 0, 19, 0, 19, 11, 0, 0, 29, 2,
-  31, 0, 0, 24, 0, 0, 40, 11, 0, 0,
-  61, 11, 0, 15, 51, 85, 31, 58, 61, 16,
-  0, 9, 60, 0, 0, 53, 11, 51, 1, 8,
-  0, 10, 0, 0, 0, 42, 35, 0, 15, 23,
-  0, 51, 12, 18, 0, 69, 33, 20, 9, 0,
-  0, 0, 24, 0, 57, 28, 0, 0, 0, 2,
-  0, 18, 0, 0, 0, 0, 0, 0, 31, 0,
-  42, 0, 0, 0, 4, 14, 36, 12, 0, 6,
-  0, 29, 44, 60, 4, 0, 34, 12, 53, 16,
-  53, 25, 0, 50, 0, 27, 0, 9, 0, 0,
-  31, 64, 0, 0, 0, 0, 0, 0, 0, 12,
-  10, 60, 0, 0, 0, 0, 0, 0, 10, 13,
-  32, 0, 25, 0, 76, 0, 51, 15, 31, 0,
-  102, 0, 40, 4, 0, 12, 0, 0, 45, 0,
-  0, 35, 56, 20, 0, 0, 9, 0, 0, 0,
-  0, 189, 80, 25, 0, 0, 0, 31, 0, 0,
-  16, 61, 0, 11, 0, 30, 0, 40, 0, 30,
-  0, 28, 48, 0, 38, 21, 24, 29, 0, 0,
-  0, 80, 0, 0, 100, 0, 63, 0, 47, 0,
-  14, 23, 0, 56, 27, 66, 0, 1, 0, 4,
-  12, 26, 10, 13, 0, 0, 0, 47, 0, 15,
-  0, 0, 7, 21, 0, 11, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 25, 0, 18, 61,
-  0, 0, 17, 0, 54, 23, 26, 12, 6, 14,
-  8, 6, 0, 0, 0, 2, 87, 0, 36, 39,
-  0, 9, 0, 0, 23, 15, 18, 29, 9, 0,
-  0, 9, 0, 65, 0, 0, 41, 0, 0, 0,
-  45, 38, 0, 38, 32, 25, 0, 0, 8, 14,
-  5, 56, 28, 0, 0, 19, 0, 0, 0, 21,
-  10, 40, 27, 4, 0, 33, 0, 8, 9, 4,
-  50, 58, 50, 77, 14, 17, 0, 0, 0, 0,
-  0, 0, 0, 0, 54, 0, 0, 0, 4, 43,
-  0, 0, 0, 0, 0, 0, 12, 0, 54, 0,
-  14, 11, 0, 28, 0, 28, 0, 28, 0, 16,
-  0, 39, 0, 0, 31, 0, 14, 62, 0, 63,
-  0, 0, 13, 17, 0, 0, 0, 56, 19, 0,
-  0, 0, 17, 0, 0, 4, 0, 40, 0, 0,
-  0, 9, 0, 0, 61, 0, 8, 0, 37, 0,
-  3, 0, 29, 10, 44, 0, 0, 14, 0, 0,
-  35, 12, 0, 0, 40, 0, 0, 15, 31, 88,
-  14, 51, 40, 12, 0, 18, 47, 0, 19, 50,
-  3, 20, 0, 2, 0, 0, 0, 0, 0, 38,
-  7, 0, 3, 31, 0, 29, 36, 1, 0, 74,
-  29, 39, 8, 0, 0, 0, 18, 2, 39, 14,
-  0, 6, 37, 0, 0, 0, 0, 4, 5, 0,
-  0, 0, 26, 0, 49, 0, 0, 0, 3, 3,
-  17, 22, 0, 17, 0, 21, 27, 60, 0, 26,
-  24, 3, 57, 0, 52, 33, 0, 62, 14, 8,
-  23, 27, 0, 0, 26, 70, 5, 0, 0, 0,
-  0, 0, 0, 16, 0, 35, 0, 0, 0, 12,
-  0, 0, 17, 3, 26, 0, 0, 0, 20, 0,
-  35, 8, 37, 0, 73, 0, 21, 29, 10, 2,
-  0, 11, 74, 0, 0, 18, 94, 0, 0, 0,
-  36, 0, 0, 0, 0, 148, 91, 19, 0, 0,
-  0, 47, 0, 0, 32, 47, 0, 0, 27, 32,
-  0, 52, 0, 43, 0, 24, 66, 17, 51, 51,
-  13, 28, 0, 0, 0, 63, 0, 0, 62, 0,
-  50, 0, 39, 0, 0, 6, 0, 30, 12, 20,
-  0, 4, 0, 0, 19, 4, 40, 42, 0, 0,
-  0, 87, 0, 19, 0, 0, 16, 26, 0, 11,
-  0, 0, 0, 0, 0, 0, 0, 8, 0, 0,
-  35, 0, 15, 55, 0, 0, 22, 0, 52, 8,
-  59, 31, 3, 19, 8, 16, 0, 0, 0, 0,
-  66, 0, 18, 40, 0, 4, 0, 0, 51, 0,
-  18, 14, 0, 0, 0, 29, 1, 29, 8, 0,
-  54, 0, 0, 0, 67, 10, 9, 37, 50, 41,
-  0, 0, 0, 0, 0, 46, 33, 11, 2, 31,
-  0, 0, 8, 47, 45, 22, 0, 0, 0, 51,
-  0, 0, 0, 0, 95, 63, 29, 90, 0, 25,
-  0, 0, 0, 1, 11, 3, 0, 0, 29, 0,
-  0, 1, 0, 38, 0, 0, 3, 0, 26, 25,
-  4, 0, 48, 0, 30, 61, 0, 8, 0, 30,
-  0, 18, 0, 0, 0, 54, 0, 2, 33, 0,
-  0, 26, 0, 44, 0, 32, 0, 43, 0, 0,
-  0, 39, 13, 0, 8, 0, 38, 0, 3, 19,
-  0, 10, 9, 7, 0, 4, 0, 0, 50, 0,
-  0, 18, 13, 0, 27, 0, 42, 0, 53, 0,
-  0, 0, 0, 5, 36, 43, 0, 0, 0, 0,
-  0, 1, 24, 87, 0, 16, 36, 0, 0, 9,
-  34, 0, 19, 29, 0, 11, 0, 0, 0, 24,
-  7, 0, 0, 36, 0, 0, 0, 26, 0, 8,
-  20, 9, 0, 66, 26, 13, 0, 36, 0, 0,
-  2, 42, 7, 10, 0, 0, 26, 0, 0, 0,
-  0, 31, 20, 0, 10, 0, 10, 15, 33, 0,
-  6, 11, 0, 7, 9, 11, 0, 16, 0, 29,
-  9, 31, 0, 20, 48, 0, 63, 19, 21, 0,
-  0, 52, 14, 4, 22, 50, 0, 0, 0, 71,
-  13, 0, 0, 0, 0, 0, 0, 1, 0, 0,
-  3, 0, 0, 16, 0, 8, 57, 0, 8, 0,
-  0, 0, 0, 0, 20, 1, 25, 0, 45, 0,
-  0, 0, 22, 82, 0, 0, 8, 0, 0, 0,
-  29, 61, 0, 8, 48, 0, 0, 0, 21, 71,
-  5, 41, 10, 3, 0, 14, 0, 2, 0, 9,
-  0, 69, 34, 19, 0, 41, 0, 34, 7, 20,
-  0, 34, 59, 23, 26, 10, 5, 0, 0, 0,
-  0, 0, 0, 0, 18, 22, 10, 15, 30, 39,
-  10, 0, 0, 0, 16, 36, 52, 0, 27, 32,
-  3, 0, 12, 28, 0, 21, 0, 48, 0, 2,
-  0, 34, 13, 5, 17, 11, 0, 25, 0, 47,
-  10, 1, 26, 5, 0, 0, 0, 67, 13, 0,
-  12, 0, 16, 0, 0, 15, 0, 51, 0, 0,
-  0, 0, 0, 0, 69, 0, 19, 0, 19, 11,
-  0, 0, 29, 2, 31, 0, 0, 24, 0, 0,
-  40, 11, 0, 0, 61, 11, 0, 15, 51, 85,
-  31, 58, 61, 16, 0, 9, 60, 0, 0, 53,
-  11, 51, 1, 8, 0, 10, 0, 0, 0, 42,
-  35, 0, 15, 23, 0, 51, 12, 18, 0, 69,
-  33, 20, 9, 0, 0, 0, 24, 0, 57, 28,
-  0, 0, 0, 2, 0, 18, 0, 0, 0, 0,
-  0, 0, 31, 0, 42, 0, 0, 0, 4, 14,
-  36, 12, 0, 6, 0, 29, 44, 60, 4, 0,
-  34, 12, 53, 16, 53, 25, 0, 50, 0, 27,
-  0, 9, 0, 0, 31, 64, 0, 0, 0, 0,
-  0, 0, 0, 12, 10, 60, 0, 0, 0, 0,
-  0, 0, 10, 13, 32, 0, 25, 0, 76, 0,
-  51, 15, 31, 0, 0, 35, 50, 0, 10, 0,
-  0, 0, 51, 2, 0, 18, 8, 100, 10, 27,
-  39, 26, 2, 4, 44, 0, 34, 24, 0, 0,
-  0, 5, 0, 0, 0, 0, 0, 0, 0, 0,
-  5, 0, 0, 22, 18, 0, 0, 35, 0, 0,
-  0, 0, 0, 0, 52, 66, 0, 34, 0, 0,
-  6, 2, 0, 0, 0, 0, 13, 0, 38, 2,
-  22, 0, 23, 0, 0, 0, 3, 15, 29, 0,
-  0, 37, 0, 21, 32, 48, 11, 18, 40, 3,
-  53, 7, 75, 6, 0, 23, 0, 0, 0, 1,
-  0, 0, 40, 70, 1, 0, 0, 0, 7, 0,
-  0, 9, 0, 8, 32, 0, 0, 0, 57, 0,
-  10, 0, 12, 0, 0, 0, 8, 0, 9, 14,
-  37, 0, 9, 0, 0, 9, 0, 65, 0, 0,
-  41, 0, 0, 0, 45, 38, 0, 38, 32, 25,
-  0, 0, 8, 14, 5, 56, 28, 0, 0, 19,
-  0, 0, 0, 21, 10, 40, 27, 4, 0, 33,
-  0, 8, 9, 4, 50, 58, 50, 77, 14, 17,
-  0, 0, 0, 0, 0, 0, 0, 0, 54, 0,
-  0, 0, 4, 43, 0, 0, 0, 0, 0, 0,
-  12, 0, 54, 0, 14, 11, 0, 28, 0, 28,
-  0, 28, 0, 16, 0, 39, 0, 0, 31, 0,
-  14, 62, 0, 63, 0, 0, 13, 17, 0, 0,
-  0, 56, 19, 0, 0, 0, 17, 0, 0, 4,
-  0, 40, 0, 0, 0, 9, 0, 0, 61, 0,
-  8, 0, 37, 0, 3, 0, 29, 10, 44, 0,
-  0, 14, 0, 0, 35, 12, 0, 0, 40, 0,
-  0, 15, 31, 88, 14, 51, 40, 12, 0, 18,
-  47, 0, 19, 50, 3, 20, 0, 2, 0, 0,
-  0, 0, 0, 38, 7, 0, 3, 31, 0, 29,
-  36, 1, 0, 74, 29, 39, 8, 0, 0, 0,
-  18, 2, 39, 14, 0, 6, 37, 0, 0, 0,
-  0, 4, 5, 0, 0, 0, 26, 0, 49, 0,
-  0, 0, 3, 3, 17, 22, 0, 17, 0, 21,
-  27, 60, 0, 26, 24, 3, 57, 0, 52, 33,
-  0, 62, 14, 8, 23, 27, 0, 0, 26, 70,
-  5, 0, 0, 0, 0, 0, 0, 16, 0, 35,
-  0, 0, 0, 12, 0, 0, 17, 3, 26, 0,
-  0, 0, 20, 0, 35, 8, 37, 0, 24, 0,
-  53, 0, 32, 0, 0, 0, 25, 0, 0, 1,
-  9, 122, 15, 0, 27, 21, 0, 8, 41, 13,
-  69, 7, 0, 0, 0, 4, 0, 0, 0, 0,
-  0, 5, 0, 0, 0, 4, 0, 26, 14, 10,
-  0, 48, 14, 0, 0, 0, 0, 0, 37, 104,
-  0, 37, 0, 0, 9, 6, 3, 0, 0, 0,
-  33, 0, 50, 22, 0, 0, 24, 22, 0, 1,
-  0, 0, 27, 0, 0, 13, 0, 41, 14, 36,
-  0, 5, 48, 0, 45, 11, 72, 0, 0, 2,
-  0, 0, 0, 25, 0, 0, 41, 57, 0, 0,
-  0, 0, 0, 0, 0, 10, 1, 0, 35, 0,
-  0, 0, 51, 0, 55, 0, 5, 0, 0, 0,
-  0, 0, 28, 1, 16, 0, 0, 0, 0, 29,
-  1, 29, 8, 0, 54, 0, 0, 0, 67, 10,
-  9, 37, 50, 41, 0, 0, 0, 0, 0, 46,
-  33, 11, 2, 31, 0, 0, 8, 47, 45, 22,
-  0, 0, 0, 51, 0, 0, 0, 0, 95, 63,
-  29, 90, 0, 25, 0, 0, 0, 1, 11, 3,
-  0, 0, 29, 0, 0, 1, 0, 38, 0, 0,
-  3, 0, 26, 25, 4, 0, 48, 0, 30, 61,
-  0, 8, 0, 30, 0, 18, 0, 0, 0, 54,
-  0, 2, 33, 0, 0, 26, 0, 44, 0, 32,
-  0, 43, 0, 0, 0, 39, 13, 0, 8, 0,
-  38, 0, 3, 19, 0, 10, 9, 7, 0, 4,
-  0, 0, 50, 0, 0, 18, 13, 0, 27, 0,
-  42, 0, 53, 0, 0, 0, 0, 5, 36, 43,
-  0, 0, 0, 0, 0, 1, 24, 87, 0, 16,
-  36, 0, 0, 9, 34, 0, 19, 29, 0, 11,
-  0, 0, 0, 24, 7, 0, 0, 36, 0, 0,
-  0, 26, 0, 8, 20, 9, 0, 66, 26, 13,
-  0, 36, 0, 0, 2, 42, 7, 10, 0, 0,
-  26, 0, 0, 0, 0, 31, 20, 0, 10, 0,
-  10, 15, 33, 0, 6, 11, 0, 7, 9, 11,
-  0, 16, 0, 29, 9, 31, 0, 20, 48, 0,
-  63, 19, 21, 0, 0, 52, 14, 4, 22, 50,
-  0, 0, 0, 71, 13, 0, 0, 0, 0, 0,
-  0, 1, 0, 0, 3, 0, 0, 16, 0, 8,
-  57, 0, 8, 0, 0, 0, 0, 0, 20, 1,
-  25, 0, 15, 8, 22, 22, 74, 0, 0, 1,
-  31, 0, 0, 0, 40, 118, 28, 13, 44, 0,
-  0, 9, 37, 0, 0, 12, 0, 12, 0, 24,
-  0, 17, 2, 0, 0, 38, 0, 0, 0, 6,
-  0, 44, 0, 22, 0, 57, 17, 0, 18, 21,
-  0, 0, 25, 88, 0, 60, 0, 0, 0, 21,
-  0, 0, 0, 0, 0, 0, 0, 3, 13, 0,
-  39, 0, 0, 18, 0, 0, 44, 0, 0, 3,
-  0, 44, 27, 45, 2, 0, 52, 4, 48, 24,
-  64, 0, 0, 0, 0, 16, 0, 45, 3, 2,
-  31, 57, 0, 0, 0, 0, 0, 0, 0, 10,
-  30, 7, 17, 0, 0, 0, 33, 0, 43, 0,
-  0, 0, 30, 0, 35, 0, 54, 0, 0, 0,
-  0, 24, 0, 0, 40, 11, 0, 0, 61, 11,
-  0, 15, 51, 85, 31, 58, 61, 16, 0, 9,
-  60, 0, 0, 53, 11, 51, 1, 8, 0, 10,
-  0, 0, 0, 42, 35, 0, 15, 23, 0, 51,
-  12, 18, 0, 69, 33, 20, 9, 0, 0, 0,
-  24, 0, 57, 28, 0, 0, 0, 2, 0, 18,
-  0, 0, 0, 0, 0, 0, 31, 0, 42, 0,
-  0, 0, 4, 14, 36, 12, 0, 6, 0, 29,
-  44, 60, 4, 0, 34, 12, 53, 16, 53, 25,
-  0, 50, 0, 27, 0, 9, 0, 0, 31, 64,
-  0, 0, 0, 0, 0, 0, 0, 12, 10, 60,
-  0, 0, 0, 0, 0, 0, 10, 13, 32, 0,
-  25, 0, 76, 0, 51, 15, 31, 0, 0, 35,
-  50, 0, 10, 0, 0, 0, 51, 2, 0, 18,
-  8, 100, 10, 27, 39, 26, 2, 4, 44, 0,
-  34, 24, 0, 0, 0, 5, 0, 0, 0, 0,
-  0, 0, 0, 0, 5, 0, 0, 22, 18, 0,
-  0, 35, 0, 0, 0, 0, 0, 0, 52, 66,
-  0, 34, 0, 0, 6, 2, 0, 0, 0, 0,
-  13, 0, 38, 2, 22, 0, 23, 0, 0, 0,
-  3, 15, 29, 0, 0, 37, 0, 21, 32, 48,
-  11, 18, 40, 3, 53, 7, 75, 6, 0, 23,
-  0, 0, 0, 1, 0, 0, 40, 70, 1, 0,
-  0, 0, 7, 0, 0, 9, 0, 8, 32, 0,
-  0, 0, 57, 0, 10, 0, 12, 0, 0, 0,
-  8, 0, 9, 14, 37, 0, 22, 0, 59, 0,
-  0, 0, 0, 0, 23, 0, 0, 0, 0, 116,
-  1, 0, 6, 27, 1, 0, 38, 30, 84, 8,
-  0, 0, 0, 4, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 2, 0, 0, 28, 17, 0, 30,
-  0, 0, 0, 0, 0, 0, 35, 131, 0, 15,
-  36, 0, 30, 17, 14, 0, 0, 0, 34, 0,
-  88, 47, 7, 2, 16, 67, 0, 0, 0, 0,
-  11, 0, 0, 0, 0, 24, 16, 22, 0, 15,
-  41, 0, 31, 10, 71, 0, 0, 11, 2, 0,
-  0, 5, 0, 0, 62, 66, 0, 0, 0, 0,
-  12, 10, 0, 7, 0, 0, 50, 0, 0, 0,
-  91, 3, 77, 0, 19, 0, 0, 0, 0, 0,
-  21, 6, 10, 0, 0, 14, 0, 0, 35, 12,
-  0, 0, 40, 0, 0, 15, 31, 88, 14, 51,
-  40, 12, 0, 18, 47, 0, 19, 50, 3, 20,
-  0, 2, 0, 0, 0, 0, 0, 38, 7, 0,
-  3, 31, 0, 29, 36, 1, 0, 74, 29, 39,
-  8, 0, 0, 0, 18, 2, 39, 14, 0, 6,
-  37, 0, 0, 0, 0, 4, 5, 0, 0, 0,
-  26, 0, 49, 0, 0, 0, 3, 3, 17, 22,
-  0, 17, 0, 21, 27, 60, 0, 26, 24, 3,
-  57, 0, 52, 33, 0, 62, 14, 8, 23, 27,
-  0, 0, 26, 70, 5, 0, 0, 0, 0, 0,
-  0, 16, 0, 35, 0, 0, 0, 12, 0, 0,
-  17, 3, 26, 0, 0, 0, 20, 0, 35, 8,
-  37, 0, 24, 0, 53, 0, 32, 0, 0, 0,
-  25, 0, 0, 1, 9, 122, 15, 0, 27, 21,
-  0, 8, 41, 13, 69, 7, 0, 0, 0, 4,
-  0, 0, 0, 0, 0, 5, 0, 0, 0, 4,
-  0, 26, 14, 10, 0, 48, 14, 0, 0, 0,
-  0, 0, 37, 104, 0, 37, 0, 0, 9, 6,
-  3, 0, 0, 0, 33, 0, 50, 22, 0, 0,
-  24, 22, 0, 1, 0, 0, 27, 0, 0, 13,
-  0, 41, 14, 36, 0, 5, 48, 0, 45, 11,
-  72, 0, 0, 2, 0, 0, 0, 25, 0, 0,
-  41, 57, 0, 0, 0, 0, 0, 0, 0, 10,
-  1, 0, 35, 0, 0, 0, 51, 0, 55, 0,
-  5, 0, 0, 0, 0, 0, 28, 1, 16, 0,
-  30, 0, 17, 10, 31, 0, 0, 0, 35, 0,
-  0, 3, 12, 104, 13, 0, 18, 16, 0, 5,
-  51, 0, 33, 3, 0, 0, 0, 16, 0, 15,
-  0, 9, 0, 7, 0, 0, 0, 0, 0, 7,
-  0, 12, 0, 50, 13, 0, 0, 0, 0, 0,
-  32, 102, 0, 61, 0, 0, 22, 15, 0, 0,
-  0, 0, 29, 0, 32, 22, 10, 15, 12, 12,
-  0, 0, 0, 0, 42, 0, 0, 0, 0, 33,
-  26, 38, 0, 3, 31, 0, 30, 10, 63, 12,
-  0, 0, 0, 0, 0, 25, 23, 0, 69, 64,
-  0, 0, 2, 0, 4, 5, 0, 9, 49, 0,
-  33, 0, 0, 3, 60, 0, 68, 0, 0, 0,
-  8, 0, 0, 0, 49, 3, 11, 0, 0, 0,
-  0, 5, 36, 43, 0, 0, 0, 0, 0, 1,
-  24, 87, 0, 16, 36, 0, 0, 9, 34, 0,
-  19, 29, 0, 11, 0, 0, 0, 24, 7, 0,
-  0, 36, 0, 0, 0, 26, 0, 8, 20, 9,
-  0, 66, 26, 13, 0, 36, 0, 0, 2, 42,
-  7, 10, 0, 0, 26, 0, 0, 0, 0, 31,
-  20, 0, 10, 0, 10, 15, 33, 0, 6, 11,
-  0, 7, 9, 11, 0, 16, 0, 29, 9, 31,
-  0, 20, 48, 0, 63, 19, 21, 0, 0, 52,
-  14, 4, 22, 50, 0, 0, 0, 71, 13, 0,
-  0, 0, 0, 0, 0, 1, 0, 0, 3, 0,
-  0, 16, 0, 8, 57, 0, 8, 0, 0, 0,
-  0, 0, 20, 1, 25, 0, 15, 8, 22, 22,
-  74, 0, 0, 1, 31, 0, 0, 0, 40, 118,
-  28, 13, 44, 0, 0, 9, 37, 0, 0, 12,
-  0, 12, 0, 24, 0, 17, 2, 0, 0, 38,
-  0, 0, 0, 6, 0, 44, 0, 22, 0, 57,
-  17, 0, 18, 21, 0, 0, 25, 88, 0, 60,
-  0, 0, 0, 21, 0, 0, 0, 0, 0, 0,
-  0, 3, 13, 0, 39, 0, 0, 18, 0, 0,
-  44, 0, 0, 3, 0, 44, 27, 45, 2, 0,
-  52, 4, 48, 24, 64, 0, 0, 0, 0, 16,
-  0, 45, 3, 2, 31, 57, 0, 0, 0, 0,
-  0, 0, 0, 10, 30, 7, 17, 0, 0, 0,
-  33, 0, 43, 0, 0, 0, 30, 0, 35, 0,
-  54, 0, 0, 0, 0, 42, 26, 36, 66, 0,
-  0, 14, 62, 8, 0, 3, 37, 89, 51, 42,
-  59, 7, 0, 10, 42, 0, 0, 21, 16, 33,
-  0, 45, 0, 0, 4, 0, 0, 27, 0, 0,
-  0, 13, 0, 62, 0, 3, 0, 70, 16, 0,
-  32, 0, 0, 0, 21, 64, 8, 79, 0, 0,
-  0, 31, 0, 20, 0, 0, 0, 0, 0, 0,
-  49, 0, 44, 0, 0, 0, 0, 2, 62, 0,
-  0, 25, 0, 37, 50, 81, 8, 1, 28, 19,
-  26, 9, 59, 14, 0, 0, 0, 31, 0, 46,
-  17, 31, 61, 56, 0, 0, 3, 0, 4, 0,
-  0, 6, 50, 28, 14, 0, 0, 0, 10, 0,
-  0, 0, 0, 0, 7, 1, 83, 0, 80, 2,
-  9, 0, 0, 35, 50, 0, 10, 0, 0, 0,
-  51, 2, 0, 18, 8, 100, 10, 27, 39, 26,
-  2, 4, 44, 0, 34, 24, 0, 0, 0, 5,
-  0, 0, 0, 0, 0, 0, 0, 0, 5, 0,
-  0, 22, 18, 0, 0, 35, 0, 0, 0, 0,
-  0, 0, 52, 66, 0, 34, 0, 0, 6, 2,
-  0, 0, 0, 0, 13, 0, 38, 2, 22, 0,
-  23, 0, 0, 0, 3, 15, 29, 0, 0, 37,
-  0, 21, 32, 48, 11, 18, 40, 3, 53, 7,
-  75, 6, 0, 23, 0, 0, 0, 1, 0, 0,
-  40, 70, 1, 0, 0, 0, 7, 0, 0, 9,
-  0, 8, 32, 0, 0, 0, 57, 0, 10, 0,
-  12, 0, 0, 0, 8, 0, 9, 14, 37, 0,
-  22, 0, 59, 0, 0, 0, 0, 0, 23, 0,
-  0, 0, 0, 116, 1, 0, 6, 27, 1, 0,
-  38, 30, 84, 8, 0, 0, 0, 4, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 2, 0, 0,
-  28, 17, 0, 30, 0, 0, 0, 0, 0, 0,
-  35, 131, 0, 15, 36, 0, 30, 17, 14, 0,
-  0, 0, 34, 0, 88, 47, 7, 2, 16, 67,
-  0, 0, 0, 0, 11, 0, 0, 0, 0, 24,
-  16, 22, 0, 15, 41, 0, 31, 10, 71, 0,
-  0, 11, 2, 0, 0, 5, 0, 0, 62, 66,
-  0, 0, 0, 0, 12, 10, 0, 7, 0, 0,
-  50, 0, 0, 0, 91, 3, 77, 0, 19, 0,
-  0, 0, 0, 0, 21, 6, 10, 0, 20, 0,
-  19, 16, 0, 0, 0, 0, 29, 0, 0, 0,
-  2, 73, 0, 0, 0, 28, 8, 5, 49, 5,
-  52, 6, 0, 0, 0, 7, 0, 12, 6, 1,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 29,
-  0, 45, 0, 0, 0, 16, 0, 0, 39, 114,
-  0, 30, 15, 0, 35, 10, 0, 0, 0, 0,
-  31, 0, 77, 23, 0, 26, 0, 48, 0, 8,
-  0, 0, 25, 0, 0, 0, 0, 24, 31, 18,
-  0, 15, 42, 0, 28, 19, 61, 0, 0, 0,
-  0, 0, 0, 9, 24, 0, 72, 41, 0, 0,
-  3, 0, 0, 0, 0, 13, 37, 0, 43, 0,
-  0, 5, 84, 0, 93, 0, 17, 0, 7, 5,
-  0, 0, 42, 4, 0, 0, 24, 0, 53, 0,
-  32, 0, 0, 0, 25, 0, 0, 1, 9, 122,
-  15, 0, 27, 21, 0, 8, 41, 13, 69, 7,
-  0, 0, 0, 4, 0, 0, 0, 0, 0, 5,
-  0, 0, 0, 4, 0, 26, 14, 10, 0, 48,
-  14, 0, 0, 0, 0, 0, 37, 104, 0, 37,
-  0, 0, 9, 6, 3, 0, 0, 0, 33, 0,
-  50, 22, 0, 0, 24, 22, 0, 1, 0, 0,
-  27, 0, 0, 13, 0, 41, 14, 36, 0, 5,
-  48, 0, 45, 11, 72, 0, 0, 2, 0, 0,
-  0, 25, 0, 0, 41, 57, 0, 0, 0, 0,
-  0, 0, 0, 10, 1, 0, 35, 0, 0, 0,
-  51, 0, 55, 0, 5, 0, 0, 0, 0, 0,
-  28, 1, 16, 0, 30, 0, 17, 10, 31, 0,
-  0, 0, 35, 0, 0, 3, 12, 104, 13, 0,
-  18, 16, 0, 5, 51, 0, 33, 3, 0, 0,
-  0, 16, 0, 15, 0, 9, 0, 7, 0, 0,
-  0, 0, 0, 7, 0, 12, 0, 50, 13, 0,
-  0, 0, 0, 0, 32, 102, 0, 61, 0, 0,
-  22, 15, 0, 0, 0, 0, 29, 0, 32, 22,
-  10, 15, 12, 12, 0, 0, 0, 0, 42, 0,
-  0, 0, 0, 33, 26, 38, 0, 3, 31, 0,
-  30, 10, 63, 12, 0, 0, 0, 0, 0, 25,
-  23, 0, 69, 64, 0, 0, 2, 0, 4, 5,
-  0, 9, 49, 0, 33, 0, 0, 3, 60, 0,
-  68, 0, 0, 0, 8, 0, 0, 0, 49, 3,
-  11, 0, 0, 22, 0, 46, 29, 0, 0, 10,
-  69, 0, 0, 23, 38, 83, 24, 20, 35, 2,
-  0, 9, 58, 0, 0, 0, 4, 48, 0, 23,
-  0, 8, 10, 0, 0, 43, 1, 0, 0, 4,
-  0, 24, 0, 21, 0, 69, 0, 0, 10, 17,
-  0, 0, 39, 72, 4, 92, 0, 0, 6, 27,
-  0, 37, 0, 0, 0, 0, 0, 8, 23, 24,
-  37, 0, 0, 3, 0, 0, 58, 0, 0, 14,
-  0, 39, 58, 70, 0, 0, 36, 5, 31, 21,
-  43, 20, 8, 4, 0, 16, 0, 28, 38, 0,
-  72, 48, 0, 0, 6, 0, 2, 0, 0, 22,
-  64, 11, 22, 0, 0, 9, 42, 0, 28, 0,
-  0, 0, 25, 29, 79, 0, 79, 5, 10, 0,
-  15, 8, 22, 22, 74, 0, 0, 1, 31, 0,
-  0, 0, 40, 118, 28, 13, 44, 0, 0, 9,
-  37, 0, 0, 12, 0, 12, 0, 24, 0, 17,
-  2, 0, 0, 38, 0, 0, 0, 6, 0, 44,
-  0, 22, 0, 57, 17, 0, 18, 21, 0, 0,
-  25, 88, 0, 60, 0, 0, 0, 21, 0, 0,
-  0, 0, 0, 0, 0, 3, 13, 0, 39, 0,
-  0, 18, 0, 0, 44, 0, 0, 3, 0, 44,
-  27, 45, 2, 0, 52, 4, 48, 24, 64, 0,
-  0, 0, 0, 16, 0, 45, 3, 2, 31, 57,
-  0, 0, 0, 0, 0, 0, 0, 10, 30, 7,
-  17, 0, 0, 0, 33, 0, 43, 0, 0, 0,
-  30, 0, 35, 0, 54, 0, 0, 0, 0, 42,
-  26, 36, 66, 0, 0, 14, 62, 8, 0, 3,
-  37, 89, 51, 42, 59, 7, 0, 10, 42, 0,
-  0, 21, 16, 33, 0, 45, 0, 0, 4, 0,
-  0, 27, 0, 0, 0, 13, 0, 62, 0, 3,
-  0, 70, 16, 0, 32, 0, 0, 0, 21, 64,
-  8, 79, 0, 0, 0, 31, 0, 20, 0, 0,
-  0, 0, 0, 0, 49, 0, 44, 0, 0, 0,
-  0, 2, 62, 0, 0, 25, 0, 37, 50, 81,
-  8, 1, 28, 19, 26, 9, 59, 14, 0, 0,
-  0, 31, 0, 46, 17, 31, 61, 56, 0, 0,
-  3, 0, 4, 0, 0, 6, 50, 28, 14, 0,
-  0, 0, 10, 0, 0, 0, 0, 0, 7, 1,
-  83, 0, 80, 2, 9, 0, 0, 25, 11, 47,
-  41, 0, 0, 5, 47, 1, 0, 16, 5, 75,
-  19, 28, 49, 26, 0, 33, 25, 0, 0, 0,
-  18, 25, 0, 34, 0, 0, 0, 0, 0, 42,
-  0, 0, 0, 16, 0, 27, 0, 0, 0, 56,
-  0, 7, 36, 0, 0, 0, 0, 20, 0, 61,
-  0, 0, 3, 18, 0, 21, 2, 0, 0, 0,
-  0, 0, 62, 6, 75, 21, 0, 0, 9, 9,
-  54, 0, 0, 53, 0, 0, 29, 74, 8, 11,
-  30, 30, 27, 34, 17, 0, 0, 29, 0, 0,
-  22, 13, 14, 0, 41, 57, 0, 6, 0, 0,
-  3, 28, 0, 7, 12, 5, 0, 0, 0, 6,
-  0, 0, 0, 0, 0, 0, 0, 0, 32, 0,
-  54, 11, 27, 0, 22, 0, 59, 0, 0, 0,
-  0, 0, 23, 0, 0, 0, 0, 116, 1, 0,
-  6, 27, 1, 0, 38, 30, 84, 8, 0, 0,
-  0, 4, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 2, 0, 0, 28, 17, 0, 30, 0, 0,
-  0, 0, 0, 0, 35, 131, 0, 15, 36, 0,
-  30, 17, 14, 0, 0, 0, 34, 0, 88, 47,
-  7, 2, 16, 67, 0, 0, 0, 0, 11, 0,
-  0, 0, 0, 24, 16, 22, 0, 15, 41, 0,
-  31, 10, 71, 0, 0, 11, 2, 0, 0, 5,
-  0, 0, 62, 66, 0, 0, 0, 0, 12, 10,
-  0, 7, 0, 0, 50, 0, 0, 0, 91, 3,
-  77, 0, 19, 0, 0, 0, 0, 0, 21, 6,
-  10, 0, 20, 0, 19, 16, 0, 0, 0, 0,
-  29, 0, 0, 0, 2, 73, 0, 0, 0, 28,
-  8, 5, 49, 5, 52, 6, 0, 0, 0, 7,
-  0, 12, 6, 1, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 29, 0, 45, 0, 0, 0, 16,
-  0, 0, 39, 114, 0, 30, 15, 0, 35, 10,
-  0, 0, 0, 0, 31, 0, 77, 23, 0, 26,
-  0, 48, 0, 8, 0, 0, 25, 0, 0, 0,
-  0, 24, 31, 18, 0, 15, 42, 0, 28, 19,
-  61, 0, 0, 0, 0, 0, 0, 9, 24, 0,
-  72, 41, 0, 0, 3, 0, 0, 0, 0, 13,
-  37, 0, 43, 0, 0, 5, 84, 0, 93, 0,
-  17, 0, 7, 5, 0, 0, 42, 4, 0, 0,
-  3, 16, 0, 41, 1, 0, 4, 6, 70, 0,
-  0, 11, 25, 55, 18, 0, 14, 4, 17, 0,
-  52, 0, 0, 17, 0, 16, 4, 14, 0, 32,
-  2, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 25, 0, 53, 0, 0, 5, 16, 0, 0,
-  58, 87, 18, 68, 0, 0, 15, 25, 0, 19,
-  0, 0, 0, 0, 0, 11, 7, 13, 8, 0,
-  0, 9, 0, 0, 44, 3, 0, 0, 0, 43,
-  57, 57, 0, 0, 32, 0, 31, 33, 74, 29,
-  25, 0, 0, 0, 0, 11, 45, 0, 71, 48,
-  0, 0, 7, 0, 2, 0, 0, 12, 74, 6,
-  34, 0, 0, 0, 67, 0, 49, 0, 0, 0,
-  48, 9, 63, 0, 76, 0, 5, 0, 30, 0,
-  17, 10, 31, 0, 0, 0, 35, 0, 0, 3,
-  12, 104, 13, 0, 18, 16, 0, 5, 51, 0,
-  33, 3, 0, 0, 0, 16, 0, 15, 0, 9,
-  0, 7, 0, 0, 0, 0, 0, 7, 0, 12,
-  0, 50, 13, 0, 0, 0, 0, 0, 32, 102,
-  0, 61, 0, 0, 22, 15, 0, 0, 0, 0,
-  29, 0, 32, 22, 10, 15, 12, 12, 0, 0,
-  0, 0, 42, 0, 0, 0, 0, 33, 26, 38,
-  0, 3, 31, 0, 30, 10, 63, 12, 0, 0,
-  0, 0, 0, 25, 23, 0, 69, 64, 0, 0,
-  2, 0, 4, 5, 0, 9, 49, 0, 33, 0,
-  0, 3, 60, 0, 68, 0, 0, 0, 8, 0,
-  0, 0, 49, 3, 11, 0, 0, 22, 0, 46,
-  29, 0, 0, 10, 69, 0, 0, 23, 38, 83,
-  24, 20, 35, 2, 0, 9, 58, 0, 0, 0,
-  4, 48, 0, 23, 0, 8, 10, 0, 0, 43,
-  1, 0, 0, 4, 0, 24, 0, 21, 0, 69,
-  0, 0, 10, 17, 0, 0, 39, 72, 4, 92,
-  0, 0, 6, 27, 0, 37, 0, 0, 0, 0,
-  0, 8, 23, 24, 37, 0, 0, 3, 0, 0,
-  58, 0, 0, 14, 0, 39, 58, 70, 0, 0,
-  36, 5, 31, 21, 43, 20, 8, 4, 0, 16,
-  0, 28, 38, 0, 72, 48, 0, 0, 6, 0,
-  2, 0, 0, 22, 64, 11, 22, 0, 0, 9,
-  42, 0, 28, 0, 0, 0, 25, 29, 79, 0,
-  79, 5, 10, 0, 0, 19, 0, 49, 12, 0,
-  0, 25, 85, 2, 1, 7, 23, 85, 32, 34,
-  52, 0, 5, 0, 23, 0, 0, 0, 0, 25,
-  0, 34, 0, 0, 0, 0, 0, 25, 0, 0,
-  0, 0, 0, 23, 0, 6, 0, 46, 0, 0,
-  22, 18, 0, 0, 24, 75, 20, 83, 0, 0,
-  0, 46, 0, 19, 0, 0, 0, 0, 0, 30,
-  41, 0, 59, 0, 0, 0, 0, 12, 50, 0,
-  0, 9, 0, 32, 59, 63, 9, 0, 17, 31,
-  16, 61, 46, 0, 20, 36, 0, 0, 0, 9,
-  42, 0, 48, 63, 0, 0, 0, 0, 9, 0,
-  0, 19, 28, 6, 15, 0, 0, 0, 28, 0,
-  22, 0, 0, 0, 15, 1, 73, 0, 78, 3,
-  7, 0, 0, 42, 26, 36, 66, 0, 0, 14,
-  62, 8, 0, 3, 37, 89, 51, 42, 59, 7,
-  0, 10, 42, 0, 0, 21, 16, 33, 0, 45,
-  0, 0, 4, 0, 0, 27, 0, 0, 0, 13,
-  0, 62, 0, 3, 0, 70, 16, 0, 32, 0,
-  0, 0, 21, 64, 8, 79, 0, 0, 0, 31,
-  0, 20, 0, 0, 0, 0, 0, 0, 49, 0,
-  44, 0, 0, 0, 0, 2, 62, 0, 0, 25,
-  0, 37, 50, 81, 8, 1, 28, 19, 26, 9,
-  59, 14, 0, 0, 0, 31, 0, 46, 17, 31,
-  61, 56, 0, 0, 3, 0, 4, 0, 0, 6,
-  50, 28, 14, 0, 0, 0, 10, 0, 0, 0,
-  0, 0, 7, 1, 83, 0, 80, 2, 9, 0,
-  0, 25, 11, 47, 41, 0, 0, 5, 47, 1,
-  0, 16, 5, 75, 19, 28, 49, 26, 0, 33,
-  25, 0, 0, 0, 18, 25, 0, 34, 0, 0,
-  0, 0, 0, 42, 0, 0, 0, 16, 0, 27,
-  0, 0, 0, 56, 0, 7, 36, 0, 0, 0,
-  0, 20, 0, 61, 0, 0, 3, 18, 0, 21,
-  2, 0, 0, 0, 0, 0, 62, 6, 75, 21,
-  0, 0, 9, 9, 54, 0, 0, 53, 0, 0,
-  29, 74, 8, 11, 30, 30, 27, 34, 17, 0,
-  0, 29, 0, 0, 22, 13, 14, 0, 41, 57,
-  0, 6, 0, 0, 3, 28, 0, 7, 12, 5,
-  0, 0, 0, 6, 0, 0, 0, 0, 0, 0,
-  0, 0, 32, 0, 54, 11, 27, 0, 0, 0,
-  0, 70, 0, 0, 0, 2, 33, 0, 0, 0,
-  0, 43, 0, 6, 22, 39, 0, 28, 7, 0,
-  9, 0, 0, 0, 28, 31, 0, 0, 0, 0,
-  0, 29, 0, 0, 2, 27, 0, 0, 0, 0,
-  0, 6, 0, 5, 36, 29, 18, 0, 0, 0,
-  0, 40, 0, 15, 23, 36, 0, 10, 8, 17,
-  0, 4, 56, 0, 56, 30, 68, 85, 5, 0,
-  19, 21, 32, 0, 0, 9, 20, 0, 0, 41,
-  10, 0, 11, 39, 17, 55, 0, 0, 0, 81,
-  0, 0, 54, 0, 6, 0, 21, 50, 24, 33,
-  0, 0, 0, 40, 0, 5, 0, 0, 0, 0,
-  0, 0, 7, 0, 7, 0, 0, 0, 0, 0,
-  0, 0, 0, 21, 20, 0, 20, 0, 19, 16,
-  0, 0, 0, 0, 29, 0, 0, 0, 2, 73,
-  0, 0, 0, 28, 8, 5, 49, 5, 52, 6,
-  0, 0, 0, 7, 0, 12, 6, 1, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 29, 0, 45,
-  0, 0, 0, 16, 0, 0, 39, 114, 0, 30,
-  15, 0, 35, 10, 0, 0, 0, 0, 31, 0,
-  77, 23, 0, 26, 0, 48, 0, 8, 0, 0,
-  25, 0, 0, 0, 0, 24, 31, 18, 0, 15,
-  42, 0, 28, 19, 61, 0, 0, 0, 0, 0,
-  0, 9, 24, 0, 72, 41, 0, 0, 3, 0,
-  0, 0, 0, 13, 37, 0, 43, 0, 0, 5,
-  84, 0, 93, 0, 17, 0, 7, 5, 0, 0,
-  42, 4, 0, 0, 3, 16, 0, 41, 1, 0,
-  4, 6, 70, 0, 0, 11, 25, 55, 18, 0,
-  14, 4, 17, 0, 52, 0, 0, 17, 0, 16,
-  4, 14, 0, 32, 2, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 25, 0, 53, 0, 0,
-  5, 16, 0, 0, 58, 87, 18, 68, 0, 0,
-  15, 25, 0, 19, 0, 0, 0, 0, 0, 11,
-  7, 13, 8, 0, 0, 9, 0, 0, 44, 3,
-  0, 0, 0, 43, 57, 57, 0, 0, 32, 0,
-  31, 33, 74, 29, 25, 0, 0, 0, 0, 11,
-  45, 0, 71, 48, 0, 0, 7, 0, 2, 0,
-  0, 12, 74, 6, 34, 0, 0, 0, 67, 0,
-  49, 0, 0, 0, 48, 9, 63, 0, 76, 0,
-  5, 0, 0, 29, 0, 36, 17, 0, 0, 1,
-  82, 0, 0, 10, 14, 80, 41, 0, 22, 8,
-  10, 0, 47, 0, 0, 23, 0, 13, 0, 15,
-  0, 5, 0, 0, 0, 11, 0, 0, 0, 0,
-  0, 11, 0, 0, 0, 51, 0, 0, 23, 16,
-  0, 0, 35, 72, 21, 74, 0, 0, 3, 24,
-  0, 11, 0, 0, 0, 0, 0, 21, 29, 0,
-  30, 0, 0, 0, 0, 0, 58, 0, 0, 0,
-  0, 30, 56, 60, 4, 0, 25, 0, 29, 51,
-  61, 17, 7, 13, 0, 0, 0, 14, 29, 0,
-  67, 43, 0, 16, 0, 0, 10, 1, 0, 7,
-  54, 13, 18, 0, 0, 0, 34, 0, 15, 0,
-  0, 0, 35, 0, 63, 0, 64, 0, 8, 0,
-  0, 22, 0, 46, 29, 0, 0, 10, 69, 0,
-  0, 23, 38, 83, 24, 20, 35, 2, 0, 9,
-  58, 0, 0, 0, 4, 48, 0, 23, 0, 8,
-  10, 0, 0, 43, 1, 0, 0, 4, 0, 24,
-  0, 21, 0, 69, 0, 0, 10, 17, 0, 0,
-  39, 72, 4, 92, 0, 0, 6, 27, 0, 37,
-  0, 0, 0, 0, 0, 8, 23, 24, 37, 0,
-  0, 3, 0, 0, 58, 0, 0, 14, 0, 39,
-  58, 70, 0, 0, 36, 5, 31, 21, 43, 20,
-  8, 4, 0, 16, 0, 28, 38, 0, 72, 48,
-  0, 0, 6, 0, 2, 0, 0, 22, 64, 11,
-  22, 0, 0, 9, 42, 0, 28, 0, 0, 0,
-  25, 29, 79, 0, 79, 5, 10, 0, 0, 19,
-  0, 49, 12, 0, 0, 25, 85, 2, 1, 7,
-  23, 85, 32, 34, 52, 0, 5, 0, 23, 0,
-  0, 0, 0, 25, 0, 34, 0, 0, 0, 0,
-  0, 25, 0, 0, 0, 0, 0, 23, 0, 6,
-  0, 46, 0, 0, 22, 18, 0, 0, 24, 75,
-  20, 83, 0, 0, 0, 46, 0, 19, 0, 0,
-  0, 0, 0, 30, 41, 0, 59, 0, 0, 0,
-  0, 12, 50, 0, 0, 9, 0, 32, 59, 63,
-  9, 0, 17, 31, 16, 61, 46, 0, 20, 36,
-  0, 0, 0, 9, 42, 0, 48, 63, 0, 0,
-  0, 0, 9, 0, 0, 19, 28, 6, 15, 0,
-  0, 0, 28, 0, 22, 0, 0, 0, 15, 1,
-  73, 0, 78, 3, 7, 0, 0, 4, 2, 46,
-  13, 0, 0, 32, 107, 4, 2, 0, 4, 83,
-  44, 32, 46, 4, 0, 0, 3, 0, 0, 10,
-  0, 0, 0, 35, 0, 0, 0, 0, 0, 15,
-  0, 0, 0, 0, 0, 24, 0, 0, 0, 32,
-  0, 0, 49, 17, 0, 0, 0, 80, 25, 73,
-  0, 0, 0, 50, 0, 3, 0, 0, 0, 0,
-  0, 35, 49, 0, 61, 9, 0, 0, 3, 17,
-  57, 9, 0, 0, 0, 10, 48, 46, 9, 0,
-  7, 32, 17, 79, 43, 0, 37, 35, 0, 0,
-  0, 5, 31, 0, 49, 67, 11, 1, 0, 0,
-  15, 0, 0, 19, 8, 3, 5, 0, 0, 0,
-  19, 0, 26, 0, 0, 0, 5, 0, 65, 0,
-  62, 0, 2, 0, 0, 25, 11, 47, 41, 0,
-  0, 5, 47, 1, 0, 16, 5, 75, 19, 28,
-  49, 26, 0, 33, 25, 0, 0, 0, 18, 25,
-  0, 34, 0, 0, 0, 0, 0, 42, 0, 0,
-  0, 16, 0, 27, 0, 0, 0, 56, 0, 7,
-  36, 0, 0, 0, 0, 20, 0, 61, 0, 0,
-  3, 18, 0, 21, 2, 0, 0, 0, 0, 0,
-  62, 6, 75, 21, 0, 0, 9, 9, 54, 0,
-  0, 53, 0, 0, 29, 74, 8, 11, 30, 30,
-  27, 34, 17, 0, 0, 29, 0, 0, 22, 13,
-  14, 0, 41, 57, 0, 6, 0, 0, 3, 28,
-  0, 7, 12, 5, 0, 0, 0, 6, 0, 0,
-  0, 0, 0, 0, 0, 0, 32, 0, 54, 11,
-  27, 0, 0, 0, 0, 70, 0, 0, 0, 2,
-  33, 0, 0, 0, 0, 43, 0, 6, 22, 39,
-  0, 28, 7, 0, 9, 0, 0, 0, 28, 31,
-  0, 0, 0, 0, 0, 29, 0, 0, 2, 27,
-  0, 0, 0, 0, 0, 6, 0, 5, 36, 29,
-  18, 0, 0, 0, 0, 40, 0, 15, 23, 36,
-  0, 10, 8, 17, 0, 4, 56, 0, 56, 30,
-  68, 85, 5, 0, 19, 21, 32, 0, 0, 9,
-  20, 0, 0, 41, 10, 0, 11, 39, 17, 55,
-  0, 0, 0, 81, 0, 0, 54, 0, 6, 0,
-  21, 50, 24, 33, 0, 0, 0, 40, 0, 5,
-  0, 0, 0, 0, 0, 0, 7, 0, 7, 0,
-  0, 0, 0, 0, 0, 0, 0, 21, 20, 0,
-  0, 8, 0, 102, 1, 0, 0, 14, 69, 27,
-  0, 0, 0, 1, 0, 66, 27, 37, 0, 17,
-  6, 0, 0, 0, 2, 0, 52, 58, 12, 0,
-  0, 0, 14, 27, 0, 0, 6, 45, 0, 0,
-  2, 0, 0, 11, 0, 17, 56, 34, 0, 0,
-  0, 0, 2, 38, 0, 25, 6, 68, 0, 37,
-  0, 16, 0, 2, 22, 0, 50, 18, 67, 47,
-  0, 0, 22, 50, 27, 21, 0, 3, 14, 0,
-  29, 40, 11, 0, 0, 47, 18, 59, 13, 0,
-  37, 101, 0, 22, 37, 0, 12, 0, 20, 34,
-  37, 0, 0, 0, 4, 0, 0, 14, 0, 6,
-  0, 13, 0, 0, 10, 0, 0, 0, 0, 0,
-  4, 0, 56, 0, 21, 28, 9, 0, 3, 16,
-  0, 41, 1, 0, 4, 6, 70, 0, 0, 11,
-  25, 55, 18, 0, 14, 4, 17, 0, 52, 0,
-  0, 17, 0, 16, 4, 14, 0, 32, 2, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 25,
-  0, 53, 0, 0, 5, 16, 0, 0, 58, 87,
-  18, 68, 0, 0, 15, 25, 0, 19, 0, 0,
-  0, 0, 0, 11, 7, 13, 8, 0, 0, 9,
-  0, 0, 44, 3, 0, 0, 0, 43, 57, 57,
-  0, 0, 32, 0, 31, 33, 74, 29, 25, 0,
-  0, 0, 0, 11, 45, 0, 71, 48, 0, 0,
-  7, 0, 2, 0, 0, 12, 74, 6, 34, 0,
-  0, 0, 67, 0, 49, 0, 0, 0, 48, 9,
-  63, 0, 76, 0, 5, 0, 0, 29, 0, 36,
-  17, 0, 0, 1, 82, 0, 0, 10, 14, 80,
-  41, 0, 22, 8, 10, 0, 47, 0, 0, 23,
-  0, 13, 0, 15, 0, 5, 0, 0, 0, 11,
-  0, 0, 0, 0, 0, 11, 0, 0, 0, 51,
-  0, 0, 23, 16, 0, 0, 35, 72, 21, 74,
-  0, 0, 3, 24, 0, 11, 0, 0, 0, 0,
-  0, 21, 29, 0, 30, 0, 0, 0, 0, 0,
-  58, 0, 0, 0, 0, 30, 56, 60, 4, 0,
-  25, 0, 29, 51, 61, 17, 7, 13, 0, 0,
-  0, 14, 29, 0, 67, 43, 0, 16, 0, 0,
-  10, 1, 0, 7, 54, 13, 18, 0, 0, 0,
-  34, 0, 15, 0, 0, 0, 35, 0, 63, 0,
-  64, 0, 8, 0, 0, 64, 0, 40, 20, 0,
-  10, 0, 63, 0, 7, 15, 12, 65, 48, 6,
-  31, 34, 0, 25, 58, 0, 0, 21, 0, 36,
-  3, 4, 0, 0, 0, 0, 0, 32, 0, 0,
-  0, 0, 0, 11, 0, 0, 0, 41, 0, 0,
-  21, 22, 0, 0, 26, 26, 28, 76, 0, 0,
-  10, 4, 0, 25, 19, 0, 0, 0, 0, 11,
-  55, 3, 50, 0, 0, 0, 0, 0, 62, 0,
-  0, 0, 0, 3, 57, 69, 4, 0, 25, 19,
-  41, 29, 30, 12, 0, 34, 0, 1, 0, 24,
-  19, 0, 63, 30, 0, 19, 0, 0, 12, 0,
-  3, 1, 34, 21, 0, 0, 0, 0, 15, 0,
-  0, 0, 0, 0, 0, 13, 75, 0, 41, 0,
-  17, 0, 0, 19, 0, 49, 12, 0, 0, 25,
-  85, 2, 1, 7, 23, 85, 32, 34, 52, 0,
-  5, 0, 23, 0, 0, 0, 0, 25, 0, 34,
-  0, 0, 0, 0, 0, 25, 0, 0, 0, 0,
-  0, 23, 0, 6, 0, 46, 0, 0, 22, 18,
-  0, 0, 24, 75, 20, 83, 0, 0, 0, 46,
-  0, 19, 0, 0, 0, 0, 0, 30, 41, 0,
-  59, 0, 0, 0, 0, 12, 50, 0, 0, 9,
-  0, 32, 59, 63, 9, 0, 17, 31, 16, 61,
-  46, 0, 20, 36, 0, 0, 0, 9, 42, 0,
-  48, 63, 0, 0, 0, 0, 9, 0, 0, 19,
-  28, 6, 15, 0, 0, 0, 28, 0, 22, 0,
-  0, 0, 15, 1, 73, 0, 78, 3, 7, 0,
-  0, 4, 2, 46, 13, 0, 0, 32, 107, 4,
-  2, 0, 4, 83, 44, 32, 46, 4, 0, 0,
-  3, 0, 0, 10, 0, 0, 0, 35, 0, 0,
-  0, 0, 0, 15, 0, 0, 0, 0, 0, 24,
-  0, 0, 0, 32, 0, 0, 49, 17, 0, 0,
-  0, 80, 25, 73, 0, 0, 0, 50, 0, 3,
-  0, 0, 0, 0, 0, 35, 49, 0, 61, 9,
-  0, 0, 3, 17, 57, 9, 0, 0, 0, 10,
-  48, 46, 9, 0, 7, 32, 17, 79, 43, 0,
-  37, 35, 0, 0, 0, 5, 31, 0, 49, 67,
-  11, 1, 0, 0, 15, 0, 0, 19, 8, 3,
-  5, 0, 0, 0, 19, 0, 26, 0, 0, 0,
-  5, 0, 65, 0, 62, 0, 2, 0, 0, 37,
-  0, 44, 22, 0, 8, 20, 82, 0, 25, 11,
-  12, 56, 55, 36, 59, 22, 0, 12, 31, 0,
-  0, 0, 1, 27, 0, 18, 0, 0, 0, 0,
-  0, 37, 0, 0, 0, 0, 0, 14, 0, 0,
-  0, 28, 0, 0, 38, 1, 0, 0, 0, 23,
-  0, 87, 0, 0, 4, 32, 0, 38, 0, 0,
-  0, 0, 0, 27, 62, 7, 79, 0, 0, 0,
-  0, 8, 73, 0, 0, 19, 6, 1, 28, 74,
-  0, 0, 22, 50, 31, 43, 10, 0, 10, 37,
-  0, 20, 0, 33, 31, 10, 59, 36, 0, 0,
-  0, 0, 17, 0, 0, 13, 9, 1, 0, 0,
-  0, 0, 9, 0, 0, 0, 0, 0, 0, 23,
-  74, 0, 31, 0, 36, 0, 0, 0, 0, 70,
-  0, 0, 0, 2, 33, 0, 0, 0, 0, 43,
-  0, 6, 22, 39, 0, 28, 7, 0, 9, 0,
-  0, 0, 28, 31, 0, 0, 0, 0, 0, 29,
-  0, 0, 2, 27, 0, 0, 0, 0, 0, 6,
-  0, 5, 36, 29, 18, 0, 0, 0, 0, 40,
-  0, 15, 23, 36, 0, 10, 8, 17, 0, 4,
-  56, 0, 56, 30, 68, 85, 5, 0, 19, 21,
-  32, 0, 0, 9, 20, 0, 0, 41, 10, 0,
-  11, 39, 17, 55, 0, 0, 0, 81, 0, 0,
-  54, 0, 6, 0, 21, 50, 24, 33, 0, 0,
-  0, 40, 0, 5, 0, 0, 0, 0, 0, 0,
-  7, 0, 7, 0, 0, 0, 0, 0, 0, 0,
-  0, 21, 20, 0, 0, 8, 0, 102, 1, 0,
-  0, 14, 69, 27, 0, 0, 0, 1, 0, 66,
-  27, 37, 0, 17, 6, 0, 0, 0, 2, 0,
-  52, 58, 12, 0, 0, 0, 14, 27, 0, 0,
-  6, 45, 0, 0, 2, 0, 0, 11, 0, 17,
-  56, 34, 0, 0, 0, 0, 2, 38, 0, 25,
-  6, 68, 0, 37, 0, 16, 0, 2, 22, 0,
-  50, 18, 67, 47, 0, 0, 22, 50, 27, 21,
-  0, 3, 14, 0, 29, 40, 11, 0, 0, 47,
-  18, 59, 13, 0, 37, 101, 0, 22, 37, 0,
-  12, 0, 20, 34, 37, 0, 0, 0, 4, 0,
-  0, 14, 0, 6, 0, 13, 0, 0, 10, 0,
-  0, 0, 0, 0, 4, 0, 56, 0, 21, 28,
-  9, 0, 0, 56, 17, 88, 0, 0, 31, 9,
-  81, 2, 5, 0, 0, 6, 2, 91, 38, 27,
-  0, 41, 0, 0, 0, 0, 13, 0, 37, 42,
-  0, 0, 0, 2, 9, 19, 0, 0, 16, 37,
-  0, 0, 16, 0, 0, 26, 0, 16, 70, 3,
-  0, 0, 0, 0, 0, 52, 0, 0, 15, 62,
-  0, 58, 0, 17, 0, 7, 22, 0, 63, 23,
-  93, 25, 0, 0, 31, 35, 54, 3, 0, 8,
-  19, 0, 32, 63, 17, 6, 25, 64, 9, 35,
-  25, 0, 32, 85, 0, 27, 5, 0, 11, 0,
-  41, 54, 31, 0, 0, 0, 12, 3, 0, 31,
-  0, 0, 0, 17, 0, 0, 32, 0, 0, 0,
-  0, 0, 0, 0, 65, 0, 25, 16, 30, 0,
-  0, 29, 0, 36, 17, 0, 0, 1, 82, 0,
-  0, 10, 14, 80, 41, 0, 22, 8, 10, 0,
-  47, 0, 0, 23, 0, 13, 0, 15, 0, 5,
-  0, 0, 0, 11, 0, 0, 0, 0, 0, 11,
-  0, 0, 0, 51, 0, 0, 23, 16, 0, 0,
-  35, 72, 21, 74, 0, 0, 3, 24, 0, 11,
-  0, 0, 0, 0, 0, 21, 29, 0, 30, 0,
-  0, 0, 0, 0, 58, 0, 0, 0, 0, 30,
-  56, 60, 4, 0, 25, 0, 29, 51, 61, 17,
-  7, 13, 0, 0, 0, 14, 29, 0, 67, 43,
-  0, 16, 0, 0, 10, 1, 0, 7, 54, 13,
-  18, 0, 0, 0, 34, 0, 15, 0, 0, 0,
-  35, 0, 63, 0, 64, 0, 8, 0, 0, 64,
-  0, 40, 20, 0, 10, 0, 63, 0, 7, 15,
-  12, 65, 48, 6, 31, 34, 0, 25, 58, 0,
-  0, 21, 0, 36, 3, 4, 0, 0, 0, 0,
-  0, 32, 0, 0, 0, 0, 0, 11, 0, 0,
-  0, 41, 0, 0, 21, 22, 0, 0, 26, 26,
-  28, 76, 0, 0, 10, 4, 0, 25, 19, 0,
-  0, 0, 0, 11, 55, 3, 50, 0, 0, 0,
-  0, 0, 62, 0, 0, 0, 0, 3, 57, 69,
-  4, 0, 25, 19, 41, 29, 30, 12, 0, 34,
-  0, 1, 0, 24, 19, 0, 63, 30, 0, 19,
-  0, 0, 12, 0, 3, 1, 34, 21, 0, 0,
-  0, 0, 15, 0, 0, 0, 0, 0, 0, 13,
-  75, 0, 41, 0, 17, 0, 0, 151, 1, 57,
-  8, 0, 17, 0, 42, 0, 26, 0, 19, 37,
-  38, 18, 29, 7, 6, 53, 10, 0, 0, 24,
-  1, 37, 15, 7, 0, 0, 0, 0, 46, 5,
-  0, 0, 0, 0, 0, 1, 0, 2, 0, 21,
-  0, 0, 21, 42, 0, 0, 40, 0, 12, 89,
-  0, 0, 18, 1, 0, 44, 24, 0, 0, 0,
-  0, 0, 73, 21, 53, 0, 0, 0, 0, 8,
-  68, 12, 0, 35, 0, 18, 49, 62, 21, 11,
-  30, 33, 16, 49, 19, 13, 53, 22, 0, 17,
-  0, 5, 44, 0, 24, 80, 3, 46, 0, 0,
-  12, 0, 22, 12, 52, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 89, 0,
-  51, 0, 16, 1, 0, 4, 2, 46, 13, 0,
-  0, 32, 107, 4, 2, 0, 4, 83, 44, 32,
-  46, 4, 0, 0, 3, 0, 0, 10, 0, 0,
-  0, 35, 0, 0, 0, 0, 0, 15, 0, 0,
-  0, 0, 0, 24, 0, 0, 0, 32, 0, 0,
-  49, 17, 0, 0, 0, 80, 25, 73, 0, 0,
-  0, 50, 0, 3, 0, 0, 0, 0, 0, 35,
-  49, 0, 61, 9, 0, 0, 3, 17, 57, 9,
-  0, 0, 0, 10, 48, 46, 9, 0, 7, 32,
-  17, 79, 43, 0, 37, 35, 0, 0, 0, 5,
-  31, 0, 49, 67, 11, 1, 0, 0, 15, 0,
-  0, 19, 8, 3, 5, 0, 0, 0, 19, 0,
-  26, 0, 0, 0, 5, 0, 65, 0, 62, 0,
-  2, 0, 0, 37, 0, 44, 22, 0, 8, 20,
-  82, 0, 25, 11, 12, 56, 55, 36, 59, 22,
-  0, 12, 31, 0, 0, 0, 1, 27, 0, 18,
-  0, 0, 0, 0, 0, 37, 0, 0, 0, 0,
-  0, 14, 0, 0, 0, 28, 0, 0, 38, 1,
-  0, 0, 0, 23, 0, 87, 0, 0, 4, 32,
-  0, 38, 0, 0, 0, 0, 0, 27, 62, 7,
-  79, 0, 0, 0, 0, 8, 73, 0, 0, 19,
-  6, 1, 28, 74, 0, 0, 22, 50, 31, 43,
-  10, 0, 10, 37, 0, 20, 0, 33, 31, 10,
-  59, 36, 0, 0, 0, 0, 17, 0, 0, 13,
-  9, 1, 0, 0, 0, 0, 9, 0, 0, 0,
-  0, 0, 0, 23, 74, 0, 31, 0, 36, 0,
-  0, 74, 18, 48, 36, 0, 9, 0, 60, 0,
-  36, 0, 0, 63, 66, 33, 53, 1, 1, 40,
-  5, 0, 0, 0, 0, 29, 0, 0, 0, 0,
-  0, 0, 0, 33, 0, 0, 0, 0, 0, 13,
-  0, 0, 0, 7, 0, 0, 40, 19, 0, 0,
-  0, 0, 0, 107, 0, 0, 12, 52, 0, 31,
-  0, 27, 0, 0, 0, 19, 66, 8, 85, 0,
-  0, 0, 0, 0, 65, 0, 0, 12, 15, 13,
-  23, 55, 0, 0, 38, 70, 22, 57, 6, 0,
-  10, 41, 0, 20, 0, 27, 34, 9, 25, 65,
-  0, 0, 0, 0, 11, 0, 0, 0, 15, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 46, 0, 22, 0, 42, 0, 0, 8,
-  0, 102, 1, 0, 0, 14, 69, 27, 0, 0,
-  0, 1, 0, 66, 27, 37, 0, 17, 6, 0,
-  0, 0, 2, 0, 52, 58, 12, 0, 0, 0,
-  14, 27, 0, 0, 6, 45, 0, 0, 2, 0,
-  0, 11, 0, 17, 56, 34, 0, 0, 0, 0,
-  2, 38, 0, 25, 6, 68, 0, 37, 0, 16,
-  0, 2, 22, 0, 50, 18, 67, 47, 0, 0,
-  22, 50, 27, 21, 0, 3, 14, 0, 29, 40,
-  11, 0, 0, 47, 18, 59, 13, 0, 37, 101,
-  0, 22, 37, 0, 12, 0, 20, 34, 37, 0,
-  0, 0, 4, 0, 0, 14, 0, 6, 0, 13,
-  0, 0, 10, 0, 0, 0, 0, 0, 4, 0,
-  56, 0, 21, 28, 9, 0, 0, 56, 17, 88,
-  0, 0, 31, 9, 81, 2, 5, 0, 0, 6,
-  2, 91, 38, 27, 0, 41, 0, 0, 0, 0,
-  13, 0, 37, 42, 0, 0, 0, 2, 9, 19,
-  0, 0, 16, 37, 0, 0, 16, 0, 0, 26,
-  0, 16, 70, 3, 0, 0, 0, 0, 0, 52,
-  0, 0, 15, 62, 0, 58, 0, 17, 0, 7,
-  22, 0, 63, 23, 93, 25, 0, 0, 31, 35,
-  54, 3, 0, 8, 19, 0, 32, 63, 17, 6,
-  25, 64, 9, 35, 25, 0, 32, 85, 0, 27,
-  5, 0, 11, 0, 41, 54, 31, 0, 0, 0,
-  12, 3, 0, 31, 0, 0, 0, 17, 0, 0,
-  32, 0, 0, 0, 0, 0, 0, 0, 65, 0,
-  25, 16, 30, 0, 0, 28, 8, 32, 27, 0,
-  2, 0, 68, 0, 19, 0, 0, 42, 7, 49,
-  43, 15, 20, 47, 0, 0, 0, 0, 0, 0,
-  3, 32, 0, 0, 0, 6, 4, 23, 0, 12,
-  7, 21, 0, 0, 2, 0, 0, 18, 0, 11,
-  54, 50, 0, 0, 0, 0, 0, 40, 0, 0,
-  45, 53, 0, 11, 0, 42, 0, 0, 22, 4,
-  38, 14, 110, 11, 16, 0, 30, 15, 57, 0,
-  0, 0, 2, 0, 0, 18, 21, 0, 59, 45,
-  0, 63, 2, 0, 3, 85, 0, 10, 16, 0,
-  9, 0, 31, 80, 7, 29, 0, 0, 22, 22,
-  0, 19, 0, 0, 0, 25, 0, 0, 16, 0,
-  0, 0, 0, 0, 0, 0, 11, 0, 0, 5,
-  46, 8, 0, 64, 0, 40, 20, 0, 10, 0,
-  63, 0, 7, 15, 12, 65, 48, 6, 31, 34,
-  0, 25, 58, 0, 0, 21, 0, 36, 3, 4,
-  0, 0, 0, 0, 0, 32, 0, 0, 0, 0,
-  0, 11, 0, 0, 0, 41, 0, 0, 21, 22,
-  0, 0, 26, 26, 28, 76, 0, 0, 10, 4,
-  0, 25, 19, 0, 0, 0, 0, 11, 55, 3,
-  50, 0, 0, 0, 0, 0, 62, 0, 0, 0,
-  0, 3, 57, 69, 4, 0, 25, 19, 41, 29,
-  30, 12, 0, 34, 0, 1, 0, 24, 19, 0,
-  63, 30, 0, 19, 0, 0, 12, 0, 3, 1,
-  34, 21, 0, 0, 0, 0, 15, 0, 0, 0,
-  0, 0, 0, 13, 75, 0, 41, 0, 17, 0,
-  0, 151, 1, 57, 8, 0, 17, 0, 42, 0,
-  26, 0, 19, 37, 38, 18, 29, 7, 6, 53,
-  10, 0, 0, 24, 1, 37, 15, 7, 0, 0,
-  0, 0, 46, 5, 0, 0, 0, 0, 0, 1,
-  0, 2, 0, 21, 0, 0, 21, 42, 0, 0,
-  40, 0, 12, 89, 0, 0, 18, 1, 0, 44,
-  24, 0, 0, 0, 0, 0, 73, 21, 53, 0,
-  0, 0, 0, 8, 68, 12, 0, 35, 0, 18,
-  49, 62, 21, 11, 30, 33, 16, 49, 19, 13,
-  53, 22, 0, 17, 0, 5, 44, 0, 24, 80,
-  3, 46, 0, 0, 12, 0, 22, 12, 52, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 89, 0, 51, 0, 16, 1, 6, 145,
-  0, 66, 0, 25, 0, 0, 52, 0, 6, 0,
-  69, 0, 0, 0, 0, 5, 33, 32, 0, 0,
-  14, 32, 3, 0, 70, 0, 0, 0, 0, 0,
-  77, 0, 13, 38, 0, 0, 0, 0, 0, 17,
-  0, 19, 0, 15, 48, 19, 0, 17, 5, 25,
-  0, 35, 17, 0, 54, 0, 0, 16, 0, 0,
-  0, 0, 16, 0, 16, 19, 0, 1, 65, 17,
-  3, 0, 34, 29, 0, 94, 0, 16, 0, 0,
-  90, 39, 0, 18, 0, 41, 51, 18, 99, 0,
-  0, 0, 0, 0, 61, 0, 18, 99, 42, 59,
-  0, 0, 0, 10, 57, 44, 87, 0, 0, 0,
-  0, 36, 0, 0, 0, 0, 5, 0, 3, 0,
-  48, 0, 39, 0, 0, 46, 0, 37, 0, 44,
-  22, 0, 8, 20, 82, 0, 25, 11, 12, 56,
-  55, 36, 59, 22, 0, 12, 31, 0, 0, 0,
-  1, 27, 0, 18, 0, 0, 0, 0, 0, 37,
-  0, 0, 0, 0, 0, 14, 0, 0, 0, 28,
-  0, 0, 38, 1, 0, 0, 0, 23, 0, 87,
-  0, 0, 4, 32, 0, 38, 0, 0, 0, 0,
-  0, 27, 62, 7, 79, 0, 0, 0, 0, 8,
-  73, 0, 0, 19, 6, 1, 28, 74, 0, 0,
-  22, 50, 31, 43, 10, 0, 10, 37, 0, 20,
-  0, 33, 31, 10, 59, 36, 0, 0, 0, 0,
-  17, 0, 0, 13, 9, 1, 0, 0, 0, 0,
-  9, 0, 0, 0, 0, 0, 0, 23, 74, 0,
-  31, 0, 36, 0, 0, 74, 18, 48, 36, 0,
-  9, 0, 60, 0, 36, 0, 0, 63, 66, 33,
-  53, 1, 1, 40, 5, 0, 0, 0, 0, 29,
-  0, 0, 0, 0, 0, 0, 0, 33, 0, 0,
-  0, 0, 0, 13, 0, 0, 0, 7, 0, 0,
-  40, 19, 0, 0, 0, 0, 0, 107, 0, 0,
-  12, 52, 0, 31, 0, 27, 0, 0, 0, 19,
-  66, 8, 85, 0, 0, 0, 0, 0, 65, 0,
-  0, 12, 15, 13, 23, 55, 0, 0, 38, 70,
-  22, 57, 6, 0, 10, 41, 0, 20, 0, 27,
-  34, 9, 25, 65, 0, 0, 0, 0, 11, 0,
-  0, 0, 15, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 46, 0, 22, 0,
-  42, 0, 0, 120, 19, 74, 27, 0, 31, 0,
-  61, 0, 8, 0, 21, 27, 26, 43, 32, 22,
-  11, 48, 0, 0, 11, 13, 20, 2, 39, 1,
-  0, 0, 0, 0, 45, 5, 15, 2, 0, 0,
-  0, 0, 0, 0, 0, 21, 0, 27, 87, 36,
-  0, 0, 16, 0, 0, 39, 0, 0, 30, 0,
-  0, 50, 0, 22, 0, 0, 0, 0, 32, 15,
-  38, 0, 0, 0, 27, 0, 82, 16, 0, 44,
-  0, 0, 23, 10, 32, 10, 15, 51, 24, 38,
-  8, 39, 22, 24, 0, 47, 0, 0, 15, 0,
-  42, 41, 18, 5, 0, 0, 5, 0, 39, 13,
-  35, 22, 0, 0, 0, 45, 0, 0, 0, 0,
-  9, 0, 0, 0, 49, 0, 6, 0, 21, 9,
-  0, 56, 17, 88, 0, 0, 31, 9, 81, 2,
-  5, 0, 0, 6, 2, 91, 38, 27, 0, 41,
-  0, 0, 0, 0, 13, 0, 37, 42, 0, 0,
-  0, 2, 9, 19, 0, 0, 16, 37, 0, 0,
-  16, 0, 0, 26, 0, 16, 70, 3, 0, 0,
-  0, 0, 0, 52, 0, 0, 15, 62, 0, 58,
-  0, 17, 0, 7, 22, 0, 63, 23, 93, 25,
-  0, 0, 31, 35, 54, 3, 0, 8, 19, 0,
-  32, 63, 17, 6, 25, 64, 9, 35, 25, 0,
-  32, 85, 0, 27, 5, 0, 11, 0, 41, 54,
-  31, 0, 0, 0, 12, 3, 0, 31, 0, 0,
-  0, 17, 0, 0, 32, 0, 0, 0, 0, 0,
-  0, 0, 65, 0, 25, 16, 30, 0, 0, 28,
-  8, 32, 27, 0, 2, 0, 68, 0, 19, 0,
-  0, 42, 7, 49, 43, 15, 20, 47, 0, 0,
-  0, 0, 0, 0, 3, 32, 0, 0, 0, 6,
-  4, 23, 0, 12, 7, 21, 0, 0, 2, 0,
-  0, 18, 0, 11, 54, 50, 0, 0, 0, 0,
-  0, 40, 0, 0, 45, 53, 0, 11, 0, 42,
-  0, 0, 22, 4, 38, 14, 110, 11, 16, 0,
-  30, 15, 57, 0, 0, 0, 2, 0, 0, 18,
-  21, 0, 59, 45, 0, 63, 2, 0, 3, 85,
-  0, 10, 16, 0, 9, 0, 31, 80, 7, 29,
-  0, 0, 22, 22, 0, 19, 0, 0, 0, 25,
-  0, 0, 16, 0, 0, 0, 0, 0, 0, 0,
-  11, 0, 0, 5, 46, 8, 7, 49, 61, 23,
-  56, 0, 23, 0, 71, 0, 0, 0, 14, 98,
-  16, 58, 20, 15, 28, 30, 7, 0, 10, 8,
-  0, 0, 0, 49, 0, 0, 0, 0, 0, 27,
-  0, 0, 0, 0, 0, 0, 17, 10, 0, 57,
-  0, 0, 54, 50, 0, 0, 31, 38, 0, 36,
-  0, 0, 23, 53, 0, 29, 0, 9, 0, 0,
-  24, 18, 14, 0, 53, 0, 0, 0, 18, 6,
-  59, 0, 0, 0, 0, 0, 21, 44, 0, 0,
-  68, 38, 3, 47, 64, 0, 0, 40, 0, 20,
-  0, 9, 7, 0, 28, 55, 0, 0, 1, 0,
-  35, 0, 0, 37, 14, 0, 22, 0, 0, 15,
-  86, 0, 0, 0, 20, 0, 12, 0, 13, 0,
-  9, 8, 46, 0, 0, 151, 1, 57, 8, 0,
-  17, 0, 42, 0, 26, 0, 19, 37, 38, 18,
-  29, 7, 6, 53, 10, 0, 0, 24, 1, 37,
-  15, 7, 0, 0, 0, 0, 46, 5, 0, 0,
-  0, 0, 0, 1, 0, 2, 0, 21, 0, 0,
-  21, 42, 0, 0, 40, 0, 12, 89, 0, 0,
-  18, 1, 0, 44, 24, 0, 0, 0, 0, 0,
-  73, 21, 53, 0, 0, 0, 0, 8, 68, 12,
-  0, 35, 0, 18, 49, 62, 21, 11, 30, 33,
-  16, 49, 19, 13, 53, 22, 0, 17, 0, 5,
-  44, 0, 24, 80, 3, 46, 0, 0, 12, 0,
-  22, 12, 52, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 89, 0, 51, 0,
-  16, 1, 6, 145, 0, 66, 0, 25, 0, 0,
-  52, 0, 6, 0, 69, 0, 0, 0, 0, 5,
-  33, 32, 0, 0, 14, 32, 3, 0, 70, 0,
-  0, 0, 0, 0, 77, 0, 13, 38, 0, 0,
-  0, 0, 0, 17, 0, 19, 0, 15, 48, 19,
-  0, 17, 5, 25, 0, 35, 17, 0, 54, 0,
-  0, 16, 0, 0, 0, 0, 16, 0, 16, 19,
-  0, 1, 65, 17, 3, 0, 34, 29, 0, 94,
-  0, 16, 0, 0, 90, 39, 0, 18, 0, 41,
-  51, 18, 99, 0, 0, 0, 0, 0, 61, 0,
-  18, 99, 42, 59, 0, 0, 0, 10, 57, 44,
-  87, 0, 0, 0, 0, 36, 0, 0, 0, 0,
-  5, 0, 3, 0, 48, 0, 39, 0, 0, 46,
-  58, 21, 0, 68, 2, 105, 0, 4, 38, 0,
-  0, 0, 40, 0, 0, 0, 2, 21, 35, 0,
-  0, 90, 13, 0, 0, 0, 31, 0, 9, 0,
-  0, 31, 3, 0, 67, 72, 9, 0, 27, 0,
-  20, 14, 0, 28, 22, 53, 41, 0, 0, 0,
-  0, 61, 0, 0, 135, 38, 37, 0, 7, 0,
-  0, 47, 34, 0, 96, 0, 0, 31, 0, 47,
-  198, 6, 55, 0, 0, 0, 0, 35, 0, 0,
-  0, 0, 77, 27, 31, 0, 1, 1, 38, 0,
-  0, 15, 0, 0, 17, 0, 39, 0, 26, 71,
-  33, 77, 0, 0, 0, 0, 6, 46, 5, 0,
-  19, 40, 0, 88, 0, 0, 0, 0, 55, 0,
-  0, 0, 0, 0, 28, 0, 0, 16, 0, 74,
-  18, 48, 36, 0, 9, 0, 60, 0, 36, 0,
-  0, 63, 66, 33, 53, 1, 1, 40, 5, 0,
-  0, 0, 0, 29, 0, 0, 0, 0, 0, 0,
-  0, 33, 0, 0, 0, 0, 0, 13, 0, 0,
-  0, 7, 0, 0, 40, 19, 0, 0, 0, 0,
-  0, 107, 0, 0, 12, 52, 0, 31, 0, 27,
-  0, 0, 0, 19, 66, 8, 85, 0, 0, 0,
-  0, 0, 65, 0, 0, 12, 15, 13, 23, 55,
-  0, 0, 38, 70, 22, 57, 6, 0, 10, 41,
-  0, 20, 0, 27, 34, 9, 25, 65, 0, 0,
-  0, 0, 11, 0, 0, 0, 15, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  46, 0, 22, 0, 42, 0, 0, 120, 19, 74,
-  27, 0, 31, 0, 61, 0, 8, 0, 21, 27,
-  26, 43, 32, 22, 11, 48, 0, 0, 11, 13,
-  20, 2, 39, 1, 0, 0, 0, 0, 45, 5,
-  15, 2, 0, 0, 0, 0, 0, 0, 0, 21,
-  0, 27, 87, 36, 0, 0, 16, 0, 0, 39,
-  0, 0, 30, 0, 0, 50, 0, 22, 0, 0,
-  0, 0, 32, 15, 38, 0, 0, 0, 27, 0,
-  82, 16, 0, 44, 0, 0, 23, 10, 32, 10,
-  15, 51, 24, 38, 8, 39, 22, 24, 0, 47,
-  0, 0, 15, 0, 42, 41, 18, 5, 0, 0,
-  5, 0, 39, 13, 35, 22, 0, 0, 0, 45,
-  0, 0, 0, 0, 9, 0, 0, 0, 49, 0,
-  6, 0, 21, 9, 64, 56, 7, 47, 47, 23,
-  0, 2, 27, 0, 0, 0, 42, 8, 0, 3,
-  0, 0, 56, 18, 0, 16, 26, 0, 2, 0,
-  57, 0, 1, 54, 0, 27, 23, 0, 74, 44,
-  54, 0, 12, 0, 0, 9, 0, 16, 14, 30,
-  64, 22, 0, 0, 0, 0, 0, 18, 39, 0,
-  31, 0, 0, 0, 0, 41, 29, 0, 11, 5,
-  0, 39, 0, 10, 75, 0, 74, 0, 24, 4,
-  0, 36, 30, 0, 0, 0, 49, 39, 40, 0,
-  0, 51, 36, 6, 0, 6, 0, 16, 0, 0,
-  38, 0, 41, 42, 30, 45, 15, 0, 0, 0,
-  5, 61, 41, 0, 5, 11, 0, 65, 38, 0,
-  0, 0, 29, 0, 0, 0, 0, 0, 0, 0,
-  8, 29, 0, 28, 8, 32, 27, 0, 2, 0,
-  68, 0, 19, 0, 0, 42, 7, 49, 43, 15,
-  20, 47, 0, 0, 0, 0, 0, 0, 3, 32,
-  0, 0, 0, 6, 4, 23, 0, 12, 7, 21,
-  0, 0, 2, 0, 0, 18, 0, 11, 54, 50,
-  0, 0, 0, 0, 0, 40, 0, 0, 45, 53,
-  0, 11, 0, 42, 0, 0, 22, 4, 38, 14,
-  110, 11, 16, 0, 30, 15, 57, 0, 0, 0,
-  2, 0, 0, 18, 21, 0, 59, 45, 0, 63,
-  2, 0, 3, 85, 0, 10, 16, 0, 9, 0,
-  31, 80, 7, 29, 0, 0, 22, 22, 0, 19,
-  0, 0, 0, 25, 0, 0, 16, 0, 0, 0,
-  0, 0, 0, 0, 11, 0, 0, 5, 46, 8,
-  7, 49, 61, 23, 56, 0, 23, 0, 71, 0,
-  0, 0, 14, 98, 16, 58, 20, 15, 28, 30,
-  7, 0, 10, 8, 0, 0, 0, 49, 0, 0,
-  0, 0, 0, 27, 0, 0, 0, 0, 0, 0,
-  17, 10, 0, 57, 0, 0, 54, 50, 0, 0,
-  31, 38, 0, 36, 0, 0, 23, 53, 0, 29,
-  0, 9, 0, 0, 24, 18, 14, 0, 53, 0,
-  0, 0, 18, 6, 59, 0, 0, 0, 0, 0,
-  21, 44, 0, 0, 68, 38, 3, 47, 64, 0,
-  0, 40, 0, 20, 0, 9, 7, 0, 28, 55,
-  0, 0, 1, 0, 35, 0, 0, 37, 14, 0,
-  22, 0, 0, 15, 86, 0, 0, 0, 20, 0,
-  12, 0, 13, 0, 9, 8, 46, 0, 51, 65,
-  87, 26, 42, 0, 0, 0, 24, 1, 1, 1,
-  40, 128, 0, 10, 0, 0, 20, 34, 11, 2,
-  7, 22, 0, 0, 0, 18, 0, 18, 19, 8,
-  0, 36, 8, 0, 36, 0, 0, 0, 19, 59,
-  0, 24, 0, 0, 22, 33, 0, 0, 46, 60,
-  0, 37, 0, 0, 0, 36, 0, 23, 0, 0,
-  20, 0, 14, 43, 0, 0, 6, 10, 0, 33,
-  9, 0, 41, 0, 0, 0, 32, 7, 0, 63,
-  13, 0, 60, 24, 16, 45, 93, 12, 0, 0,
-  0, 1, 0, 0, 27, 0, 35, 36, 0, 2,
-  17, 0, 23, 17, 0, 42, 39, 0, 25, 0,
-  0, 19, 110, 2, 0, 0, 0, 0, 14, 0,
-  0, 0, 0, 15, 6, 19, 6, 145, 0, 66,
-  0, 25, 0, 0, 52, 0, 6, 0, 69, 0,
-  0, 0, 0, 5, 33, 32, 0, 0, 14, 32,
-  3, 0, 70, 0, 0, 0, 0, 0, 77, 0,
-  13, 38, 0, 0, 0, 0, 0, 17, 0, 19,
-  0, 15, 48, 19, 0, 17, 5, 25, 0, 35,
-  17, 0, 54, 0, 0, 16, 0, 0, 0, 0,
-  16, 0, 16, 19, 0, 1, 65, 17, 3, 0,
-  34, 29, 0, 94, 0, 16, 0, 0, 90, 39,
-  0, 18, 0, 41, 51, 18, 99, 0, 0, 0,
-  0, 0, 61, 0, 18, 99, 42, 59, 0, 0,
-  0, 10, 57, 44, 87, 0, 0, 0, 0, 36,
-  0, 0, 0, 0, 5, 0, 3, 0, 48, 0,
-  39, 0, 0, 46, 58, 21, 0, 68, 2, 105,
-  0, 4, 38, 0, 0, 0, 40, 0, 0, 0,
-  2, 21, 35, 0, 0, 90, 13, 0, 0, 0,
-  31, 0, 9, 0, 0, 31, 3, 0, 67, 72,
-  9, 0, 27, 0, 20, 14, 0, 28, 22, 53,
-  41, 0, 0, 0, 0, 61, 0, 0, 135, 38,
-  37, 0, 7, 0, 0, 47, 34, 0, 96, 0,
-  0, 31, 0, 47, 198, 6, 55, 0, 0, 0,
-  0, 35, 0, 0, 0, 0, 77, 27, 31, 0,
-  1, 1, 38, 0, 0, 15, 0, 0, 17, 0,
-  39, 0, 26, 71, 33, 77, 0, 0, 0, 0,
-  6, 46, 5, 0, 19, 40, 0, 88, 0, 0,
-  0, 0, 55, 0, 0, 0, 0, 0, 28, 0,
-  0, 16, 0, 0, 0, 15, 0, 83, 0, 21,
-  90, 39, 0, 48, 26, 0, 0, 60, 13, 28,
-  16, 0, 25, 81, 1, 0, 0, 0, 1, 44,
-  17, 19, 0, 35, 60, 0, 78, 36, 79, 138,
-  7, 0, 76, 0, 2, 0, 0, 129, 0, 4,
-  0, 11, 0, 4, 0, 0, 138, 0, 2, 0,
-  27, 0, 0, 90, 14, 2, 90, 0, 0, 39,
-  0, 61, 111, 0, 118, 35, 0, 31, 35, 22,
-  25, 0, 0, 0, 0, 27, 0, 0, 12, 25,
-  0, 0, 0, 91, 0, 7, 15, 0, 6, 0,
-  0, 89, 131, 18, 0, 0, 39, 0, 0, 48,
-  0, 0, 1, 67, 0, 57, 0, 0, 0, 0,
-  75, 0, 0, 0, 0, 0, 0, 0, 75, 51,
-  0, 120, 19, 74, 27, 0, 31, 0, 61, 0,
-  8, 0, 21, 27, 26, 43, 32, 22, 11, 48,
-  0, 0, 11, 13, 20, 2, 39, 1, 0, 0,
-  0, 0, 45, 5, 15, 2, 0, 0, 0, 0,
-  0, 0, 0, 21, 0, 27, 87, 36, 0, 0,
-  16, 0, 0, 39, 0, 0, 30, 0, 0, 50,
-  0, 22, 0, 0, 0, 0, 32, 15, 38, 0,
-  0, 0, 27, 0, 82, 16, 0, 44, 0, 0,
-  23, 10, 32, 10, 15, 51, 24, 38, 8, 39,
-  22, 24, 0, 47, 0, 0, 15, 0, 42, 41,
-  18, 5, 0, 0, 5, 0, 39, 13, 35, 22,
-  0, 0, 0, 45, 0, 0, 0, 0, 9, 0,
-  0, 0, 49, 0, 6, 0, 21, 9, 64, 56,
-  7, 47, 47, 23, 0, 2, 27, 0, 0, 0,
-  42, 8, 0, 3, 0, 0, 56, 18, 0, 16,
-  26, 0, 2, 0, 57, 0, 1, 54, 0, 27,
-  23, 0, 74, 44, 54, 0, 12, 0, 0, 9,
-  0, 16, 14, 30, 64, 22, 0, 0, 0, 0,
-  0, 18, 39, 0, 31, 0, 0, 0, 0, 41,
-  29, 0, 11, 5, 0, 39, 0, 10, 75, 0,
-  74, 0, 24, 4, 0, 36, 30, 0, 0, 0,
-  49, 39, 40, 0, 0, 51, 36, 6, 0, 6,
-  0, 16, 0, 0, 38, 0, 41, 42, 30, 45,
-  15, 0, 0, 0, 5, 61, 41, 0, 5, 11,
-  0, 65, 38, 0, 0, 0, 29, 0, 0, 0,
-  0, 0, 0, 0, 8, 29, 59, 0, 21, 13,
-  0, 41, 0, 2, 0, 43, 0, 19, 0, 48,
-  0, 0, 0, 0, 56, 0, 3, 89, 5, 0,
-  0, 0, 21, 5, 0, 99, 0, 11, 0, 0,
-  67, 44, 117, 91, 15, 0, 39, 0, 3, 0,
-  0, 12, 0, 18, 5, 1, 0, 35, 0, 23,
-  119, 0, 0, 4, 0, 0, 0, 65, 91, 49,
-  82, 33, 0, 21, 0, 118, 80, 20, 83, 0,
-  0, 0, 0, 0, 100, 0, 0, 0, 15, 22,
-  26, 0, 0, 49, 63, 0, 0, 18, 0, 0,
-  55, 0, 41, 0, 0, 54, 58, 26, 28, 0,
-  0, 0, 0, 29, 0, 0, 19, 18, 0, 23,
-  56, 7, 0, 0, 19, 0, 0, 0, 0, 0,
-  0, 24, 61, 73, 7, 49, 61, 23, 56, 0,
-  23, 0, 71, 0, 0, 0, 14, 98, 16, 58,
-  20, 15, 28, 30, 7, 0, 10, 8, 0, 0,
-  0, 49, 0, 0, 0, 0, 0, 27, 0, 0,
-  0, 0, 0, 0, 17, 10, 0, 57, 0, 0,
-  54, 50, 0, 0, 31, 38, 0, 36, 0, 0,
-  23, 53, 0, 29, 0, 9, 0, 0, 24, 18,
-  14, 0, 53, 0, 0, 0, 18, 6, 59, 0,
-  0, 0, 0, 0, 21, 44, 0, 0, 68, 38,
-  3, 47, 64, 0, 0, 40, 0, 20, 0, 9,
-  7, 0, 28, 55, 0, 0, 1, 0, 35, 0,
-  0, 37, 14, 0, 22, 0, 0, 15, 86, 0,
-  0, 0, 20, 0, 12, 0, 13, 0, 9, 8,
-  46, 0, 51, 65, 87, 26, 42, 0, 0, 0,
-  24, 1, 1, 1, 40, 128, 0, 10, 0, 0,
-  20, 34, 11, 2, 7, 22, 0, 0, 0, 18,
-  0, 18, 19, 8, 0, 36, 8, 0, 36, 0,
-  0, 0, 19, 59, 0, 24, 0, 0, 22, 33,
-  0, 0, 46, 60, 0, 37, 0, 0, 0, 36,
-  0, 23, 0, 0, 20, 0, 14, 43, 0, 0,
-  6, 10, 0, 33, 9, 0, 41, 0, 0, 0,
-  32, 7, 0, 63, 13, 0, 60, 24, 16, 45,
-  93, 12, 0, 0, 0, 1, 0, 0, 27, 0,
-  35, 36, 0, 2, 17, 0, 23, 17, 0, 42,
-  39, 0, 25, 0, 0, 19, 110, 2, 0, 0,
-  0, 0, 14, 0, 0, 0, 0, 15, 6, 19,
-  58, 29, 70, 32, 22, 7, 0, 0, 38, 0,
-  7, 32, 60, 93, 0, 0, 0, 0, 38, 0,
-  64, 26, 0, 33, 0, 0, 30, 14, 0, 67,
-  47, 0, 0, 0, 6, 0, 43, 9, 0, 0,
-  0, 21, 0, 0, 0, 0, 0, 24, 0, 6,
-  13, 86, 0, 24, 27, 0, 0, 48, 0, 0,
-  0, 0, 12, 26, 3, 21, 0, 0, 0, 30,
-  0, 44, 10, 2, 0, 0, 0, 0, 48, 0,
-  0, 39, 61, 0, 1, 12, 0, 35, 123, 0,
-  0, 0, 0, 0, 0, 0, 63, 0, 17, 39,
-  26, 0, 0, 0, 0, 26, 0, 33, 42, 10,
-  39, 0, 4, 0, 83, 0, 0, 0, 0, 28,
-  67, 0, 0, 0, 0, 33, 0, 82, 58, 21,
-  0, 68, 2, 105, 0, 4, 38, 0, 0, 0,
-  40, 0, 0, 0, 2, 21, 35, 0, 0, 90,
-  13, 0, 0, 0, 31, 0, 9, 0, 0, 31,
-  3, 0, 67, 72, 9, 0, 27, 0, 20, 14,
-  0, 28, 22, 53, 41, 0, 0, 0, 0, 61,
-  0, 0, 135, 38, 37, 0, 7, 0, 0, 47,
-  34, 0, 96, 0, 0, 31, 0, 47, 198, 6,
-  55, 0, 0, 0, 0, 35, 0, 0, 0, 0,
-  77, 27, 31, 0, 1, 1, 38, 0, 0, 15,
-  0, 0, 17, 0, 39, 0, 26, 71, 33, 77,
-  0, 0, 0, 0, 6, 46, 5, 0, 19, 40,
-  0, 88, 0, 0, 0, 0, 55, 0, 0, 0,
-  0, 0, 28, 0, 0, 16, 0, 0, 0, 15,
-  0, 83, 0, 21, 90, 39, 0, 48, 26, 0,
-  0, 60, 13, 28, 16, 0, 25, 81, 1, 0,
-  0, 0, 1, 44, 17, 19, 0, 35, 60, 0,
-  78, 36, 79, 138, 7, 0, 76, 0, 2, 0,
-  0, 129, 0, 4, 0, 11, 0, 4, 0, 0,
-  138, 0, 2, 0, 27, 0, 0, 90, 14, 2,
-  90, 0, 0, 39, 0, 61, 111, 0, 118, 35,
-  0, 31, 35, 22, 25, 0, 0, 0, 0, 27,
-  0, 0, 12, 25, 0, 0, 0, 91, 0, 7,
-  15, 0, 6, 0, 0, 89, 131, 18, 0, 0,
-  39, 0, 0, 48, 0, 0, 1, 67, 0, 57,
-  0, 0, 0, 0, 75, 0, 0, 0, 0, 0,
-  0, 0, 75, 51, 0, 0, 95, 9, 0, 0,
-  0, 24, 67, 28, 0, 54, 35, 44, 0, 52,
-  0, 15, 0, 0, 0, 58, 28, 9, 0, 0,
-  21, 48, 6, 84, 0, 37, 76, 0, 22, 0,
-  105, 123, 0, 0, 100, 0, 38, 0, 0, 109,
-  0, 0, 0, 11, 0, 0, 0, 0, 96, 0,
-  19, 0, 47, 0, 0, 83, 53, 15, 66, 0,
-  7, 34, 0, 90, 0, 0, 122, 30, 0, 21,
-  7, 0, 14, 0, 0, 2, 0, 89, 0, 17,
-  21, 0, 35, 0, 0, 36, 0, 3, 0, 0,
-  0, 0, 0, 59, 137, 0, 0, 0, 0, 0,
-  0, 52, 0, 3, 30, 17, 0, 0, 80, 0,
-  22, 0, 52, 0, 0, 0, 0, 0, 0, 14,
-  61, 73, 64, 56, 7, 47, 47, 23, 0, 2,
-  27, 0, 0, 0, 42, 8, 0, 3, 0, 0,
-  56, 18, 0, 16, 26, 0, 2, 0, 57, 0,
-  1, 54, 0, 27, 23, 0, 74, 44, 54, 0,
-  12, 0, 0, 9, 0, 16, 14, 30, 64, 22,
-  0, 0, 0, 0, 0, 18, 39, 0, 31, 0,
-  0, 0, 0, 41, 29, 0, 11, 5, 0, 39,
-  0, 10, 75, 0, 74, 0, 24, 4, 0, 36,
-  30, 0, 0, 0, 49, 39, 40, 0, 0, 51,
-  36, 6, 0, 6, 0, 16, 0, 0, 38, 0,
-  41, 42, 30, 45, 15, 0, 0, 0, 5, 61,
-  41, 0, 5, 11, 0, 65, 38, 0, 0, 0,
-  29, 0, 0, 0, 0, 0, 0, 0, 8, 29,
-  59, 0, 21, 13, 0, 41, 0, 2, 0, 43,
-  0, 19, 0, 48, 0, 0, 0, 0, 56, 0,
-  3, 89, 5, 0, 0, 0, 21, 5, 0, 99,
-  0, 11, 0, 0, 67, 44, 117, 91, 15, 0,
-  39, 0, 3, 0, 0, 12, 0, 18, 5, 1,
-  0, 35, 0, 23, 119, 0, 0, 4, 0, 0,
-  0, 65, 91, 49, 82, 33, 0, 21, 0, 118,
-  80, 20, 83, 0, 0, 0, 0, 0, 100, 0,
-  0, 0, 15, 22, 26, 0, 0, 49, 63, 0,
-  0, 18, 0, 0, 55, 0, 41, 0, 0, 54,
-  58, 26, 28, 0, 0, 0, 0, 29, 0, 0,
-  19, 18, 0, 23, 56, 7, 0, 0, 19, 0,
-  0, 0, 0, 0, 0, 24, 61, 73, 32, 0,
-  66, 36, 9, 0, 0, 0, 5, 21, 0, 26,
-  30, 124, 0, 0, 0, 0, 23, 0, 28, 52,
-  0, 3, 0, 0, 50, 28, 0, 103, 0, 4,
-  0, 0, 39, 0, 82, 66, 0, 0, 35, 0,
-  2, 0, 0, 22, 7, 0, 0, 0, 0, 70,
-  0, 21, 74, 0, 0, 14, 10, 0, 0, 32,
-  91, 24, 64, 1, 0, 2, 0, 95, 0, 13,
-  72, 0, 0, 0, 0, 0, 86, 0, 0, 56,
-  11, 19, 0, 0, 12, 13, 141, 0, 0, 19,
-  0, 0, 4, 0, 38, 0, 0, 38, 31, 0,
-  0, 0, 0, 0, 0, 56, 51, 0, 69, 0,
-  0, 0, 107, 0, 36, 0, 0, 32, 38, 0,
-  0, 0, 0, 37, 0, 81, 51, 65, 87, 26,
-  42, 0, 0, 0, 24, 1, 1, 1, 40, 128,
-  0, 10, 0, 0, 20, 34, 11, 2, 7, 22,
-  0, 0, 0, 18, 0, 18, 19, 8, 0, 36,
-  8, 0, 36, 0, 0, 0, 19, 59, 0, 24,
-  0, 0, 22, 33, 0, 0, 46, 60, 0, 37,
-  0, 0, 0, 36, 0, 23, 0, 0, 20, 0,
-  14, 43, 0, 0, 6, 10, 0, 33, 9, 0,
-  41, 0, 0, 0, 32, 7, 0, 63, 13, 0,
-  60, 24, 16, 45, 93, 12, 0, 0, 0, 1,
-  0, 0, 27, 0, 35, 36, 0, 2, 17, 0,
-  23, 17, 0, 42, 39, 0, 25, 0, 0, 19,
-  110, 2, 0, 0, 0, 0, 14, 0, 0, 0,
-  0, 15, 6, 19, 58, 29, 70, 32, 22, 7,
-  0, 0, 38, 0, 7, 32, 60, 93, 0, 0,
-  0, 0, 38, 0, 64, 26, 0, 33, 0, 0,
-  30, 14, 0, 67, 47, 0, 0, 0, 6, 0,
-  43, 9, 0, 0, 0, 21, 0, 0, 0, 0,
-  0, 24, 0, 6, 13, 86, 0, 24, 27, 0,
-  0, 48, 0, 0, 0, 0, 12, 26, 3, 21,
-  0, 0, 0, 30, 0, 44, 10, 2, 0, 0,
-  0, 0, 48, 0, 0, 39, 61, 0, 1, 12,
-  0, 35, 123, 0, 0, 0, 0, 0, 0, 0,
-  63, 0, 17, 39, 26, 0, 0, 0, 0, 26,
-  0, 33, 42, 10, 39, 0, 4, 0, 83, 0,
-  0, 0, 0, 28, 67, 0, 0, 0, 0, 33,
-  0, 82, 37, 48, 54, 46, 22, 17, 0, 0,
-  75, 0, 31, 10, 55, 60, 0, 21, 0, 0,
-  43, 0, 38, 0, 0, 48, 0, 0, 41, 28,
-  0, 38, 57, 0, 0, 0, 24, 0, 32, 0,
-  0, 0, 0, 80, 0, 0, 0, 0, 14, 21,
-  0, 28, 36, 67, 0, 12, 53, 0, 1, 49,
-  0, 34, 0, 0, 0, 41, 0, 12, 9, 0,
-  0, 0, 0, 43, 25, 31, 0, 22, 14, 0,
-  16, 22, 0, 32, 73, 0, 0, 30, 3, 13,
-  122, 5, 40, 0, 0, 1, 0, 0, 93, 0,
-  14, 55, 0, 0, 0, 0, 0, 54, 0, 32,
-  56, 22, 48, 0, 15, 0, 63, 0, 0, 0,
-  0, 46, 59, 0, 14, 0, 6, 28, 0, 93,
-  0, 0, 0, 15, 0, 83, 0, 21, 90, 39,
-  0, 48, 26, 0, 0, 60, 13, 28, 16, 0,
-  25, 81, 1, 0, 0, 0, 1, 44, 17, 19,
-  0, 35, 60, 0, 78, 36, 79, 138, 7, 0,
-  76, 0, 2, 0, 0, 129, 0, 4, 0, 11,
-  0, 4, 0, 0, 138, 0, 2, 0, 27, 0,
-  0, 90, 14, 2, 90, 0, 0, 39, 0, 61,
-  111, 0, 118, 35, 0, 31, 35, 22, 25, 0,
-  0, 0, 0, 27, 0, 0, 12, 25, 0, 0,
-  0, 91, 0, 7, 15, 0, 6, 0, 0, 89,
-  131, 18, 0, 0, 39, 0, 0, 48, 0, 0,
-  1, 67, 0, 57, 0, 0, 0, 0, 75, 0,
-  0, 0, 0, 0, 0, 0, 75, 51, 0, 0,
-  95, 9, 0, 0, 0, 24, 67, 28, 0, 54,
-  35, 44, 0, 52, 0, 15, 0, 0, 0, 58,
-  28, 9, 0, 0, 21, 48, 6, 84, 0, 37,
-  76, 0, 22, 0, 105, 123, 0, 0, 100, 0,
-  38, 0, 0, 109, 0, 0, 0, 11, 0, 0,
-  0, 0, 96, 0, 19, 0, 47, 0, 0, 83,
-  53, 15, 66, 0, 7, 34, 0, 90, 0, 0,
-  122, 30, 0, 21, 7, 0, 14, 0, 0, 2,
-  0, 89, 0, 17, 21, 0, 35, 0, 0, 36,
-  0, 3, 0, 0, 0, 0, 0, 59, 137, 0,
-  0, 0, 0, 0, 0, 52, 0, 3, 30, 17,
-  0, 0, 80, 0, 22, 0, 52, 0, 0, 0,
-  0, 0, 0, 14, 61, 73, 19, 3, 82, 25,
-  7, 0, 0, 19, 0, 0, 0, 50, 24, 124,
-  0, 0, 0, 0, 0, 0, 16, 66, 70, 4,
-  0, 0, 12, 4, 0, 88, 7, 3, 0, 13,
-  0, 0, 74, 8, 0, 0, 84, 0, 0, 15,
-  17, 36, 17, 22, 4, 0, 9, 49, 0, 0,
-  86, 0, 46, 0, 71, 0, 0, 47, 100, 0,
-  96, 0, 0, 47, 0, 116, 0, 23, 90, 0,
-  0, 33, 0, 0, 23, 0, 0, 55, 0, 76,
-  0, 1, 45, 31, 68, 0, 0, 0, 10, 0,
-  0, 0, 0, 0, 0, 29, 67, 0, 0, 0,
-  0, 4, 0, 42, 0, 0, 54, 0, 0, 0,
-  124, 74, 44, 0, 25, 0, 0, 0, 0, 25,
-  0, 22, 0, 56, 59, 0, 21, 13, 0, 41,
-  0, 2, 0, 43, 0, 19, 0, 48, 0, 0,
-  0, 0, 56, 0, 3, 89, 5, 0, 0, 0,
-  21, 5, 0, 99, 0, 11, 0, 0, 67, 44,
-  117, 91, 15, 0, 39, 0, 3, 0, 0, 12,
-  0, 18, 5, 1, 0, 35, 0, 23, 119, 0,
-  0, 4, 0, 0, 0, 65, 91, 49, 82, 33,
-  0, 21, 0, 118, 80, 20, 83, 0, 0, 0,
-  0, 0, 100, 0, 0, 0, 15, 22, 26, 0,
-  0, 49, 63, 0, 0, 18, 0, 0, 55, 0,
-  41, 0, 0, 54, 58, 26, 28, 0, 0, 0,
-  0, 29, 0, 0, 19, 18, 0, 23, 56, 7,
-  0, 0, 19, 0, 0, 0, 0, 0, 0, 24,
-  61, 73, 32, 0, 66, 36, 9, 0, 0, 0,
-  5, 21, 0, 26, 30, 124, 0, 0, 0, 0,
-  23, 0, 28, 52, 0, 3, 0, 0, 50, 28,
-  0, 103, 0, 4, 0, 0, 39, 0, 82, 66,
-  0, 0, 35, 0, 2, 0, 0, 22, 7, 0,
-  0, 0, 0, 70, 0, 21, 74, 0, 0, 14,
-  10, 0, 0, 32, 91, 24, 64, 1, 0, 2,
-  0, 95, 0, 13, 72, 0, 0, 0, 0, 0,
-  86, 0, 0, 56, 11, 19, 0, 0, 12, 13,
-  141, 0, 0, 19, 0, 0, 4, 0, 38, 0,
-  0, 38, 31, 0, 0, 0, 0, 0, 0, 56,
-  51, 0, 69, 0, 0, 0, 107, 0, 36, 0,
-  0, 32, 38, 0, 0, 0, 0, 37, 0, 81,
-  51, 46, 25, 77, 65, 9, 0, 0, 20, 0,
-  19, 0, 51, 118, 0, 0, 0, 0, 16, 7,
-  12, 11, 0, 26, 0, 0, 55, 19, 0, 69,
-  20, 7, 22, 0, 56, 0, 0, 0, 0, 0,
-  0, 35, 0, 0, 31, 31, 30, 33, 0, 0,
-  23, 35, 0, 14, 38, 0, 27, 20, 0, 10,
-  0, 19, 19, 8, 0, 0, 0, 0, 2, 0,
-  0, 41, 51, 0, 0, 22, 0, 0, 35, 8,
-  0, 53, 41, 20, 0, 0, 35, 12, 95, 14,
-  26, 0, 0, 30, 0, 0, 70, 0, 0, 50,
-  0, 20, 0, 0, 0, 25, 0, 43, 127, 0,
-  82, 0, 12, 0, 31, 0, 14, 0, 0, 8,
-  49, 0, 2, 15, 10, 13, 0, 93, 58, 29,
-  70, 32, 22, 7, 0, 0, 38, 0, 7, 32,
-  60, 93, 0, 0, 0, 0, 38, 0, 64, 26,
-  0, 33, 0, 0, 30, 14, 0, 67, 47, 0,
-  0, 0, 6, 0, 43, 9, 0, 0, 0, 21,
-  0, 0, 0, 0, 0, 24, 0, 6, 13, 86,
-  0, 24, 27, 0, 0, 48, 0, 0, 0, 0,
-  12, 26, 3, 21, 0, 0, 0, 30, 0, 44,
-  10, 2, 0, 0, 0, 0, 48, 0, 0, 39,
-  61, 0, 1, 12, 0, 35, 123, 0, 0, 0,
-  0, 0, 0, 0, 63, 0, 17, 39, 26, 0,
-  0, 0, 0, 26, 0, 33, 42, 10, 39, 0,
-  4, 0, 83, 0, 0, 0, 0, 28, 67, 0,
-  0, 0, 0, 33, 0, 82, 37, 48, 54, 46,
-  22, 17, 0, 0, 75, 0, 31, 10, 55, 60,
-  0, 21, 0, 0, 43, 0, 38, 0, 0, 48,
-  0, 0, 41, 28, 0, 38, 57, 0, 0, 0,
-  24, 0, 32, 0, 0, 0, 0, 80, 0, 0,
-  0, 0, 14, 21, 0, 28, 36, 67, 0, 12,
-  53, 0, 1, 49, 0, 34, 0, 0, 0, 41,
-  0, 12, 9, 0, 0, 0, 0, 43, 25, 31,
-  0, 22, 14, 0, 16, 22, 0, 32, 73, 0,
-  0, 30, 3, 13, 122, 5, 40, 0, 0, 1,
-  0, 0, 93, 0, 14, 55, 0, 0, 0, 0,
-  0, 54, 0, 32, 56, 22, 48, 0, 15, 0,
-  63, 0, 0, 0, 0, 46, 59, 0, 14, 0,
-  6, 28, 0, 93, 18, 58, 66, 69, 39, 34,
-  0, 0, 61, 0, 24, 0, 24, 41, 11, 21,
-  49, 14, 29, 7, 0, 0, 0, 34, 1, 0,
-  22, 29, 0, 26, 0, 5, 31, 0, 36, 0,
-  13, 0, 0, 0, 0, 34, 0, 0, 10, 55,
-  10, 6, 0, 0, 30, 0, 0, 0, 35, 0,
-  20, 14, 0, 4, 0, 6, 0, 0, 0, 0,
-  31, 0, 49, 0, 0, 0, 64, 30, 0, 37,
-  0, 10, 0, 53, 0, 8, 43, 93, 0, 42,
-  5, 3, 30, 39, 93, 5, 0, 0, 11, 0,
-  68, 0, 0, 79, 5, 0, 0, 0, 30, 61,
-  0, 15, 39, 0, 23, 0, 0, 0, 0, 0,
-  12, 0, 0, 0, 11, 0, 7, 0, 19, 17,
-  24, 37, 0, 0, 95, 9, 0, 0, 0, 24,
-  67, 28, 0, 54, 35, 44, 0, 52, 0, 15,
-  0, 0, 0, 58, 28, 9, 0, 0, 21, 48,
-  6, 84, 0, 37, 76, 0, 22, 0, 105, 123,
-  0, 0, 100, 0, 38, 0, 0, 109, 0, 0,
-  0, 11, 0, 0, 0, 0, 96, 0, 19, 0,
-  47, 0, 0, 83, 53, 15, 66, 0, 7, 34,
-  0, 90, 0, 0, 122, 30, 0, 21, 7, 0,
-  14, 0, 0, 2, 0, 89, 0, 17, 21, 0,
-  35, 0, 0, 36, 0, 3, 0, 0, 0, 0,
-  0, 59, 137, 0, 0, 0, 0, 0, 0, 52,
-  0, 3, 30, 17, 0, 0, 80, 0, 22, 0,
-  52, 0, 0, 0, 0, 0, 0, 14, 61, 73,
-  19, 3, 82, 25, 7, 0, 0, 19, 0, 0,
-  0, 50, 24, 124, 0, 0, 0, 0, 0, 0,
-  16, 66, 70, 4, 0, 0, 12, 4, 0, 88,
-  7, 3, 0, 13, 0, 0, 74, 8, 0, 0,
-  84, 0, 0, 15, 17, 36, 17, 22, 4, 0,
-  9, 49, 0, 0, 86, 0, 46, 0, 71, 0,
-  0, 47, 100, 0, 96, 0, 0, 47, 0, 116,
-  0, 23, 90, 0, 0, 33, 0, 0, 23, 0,
-  0, 55, 0, 76, 0, 1, 45, 31, 68, 0,
-  0, 0, 10, 0, 0, 0, 0, 0, 0, 29,
-  67, 0, 0, 0, 0, 4, 0, 42, 0, 0,
-  54, 0, 0, 0, 124, 74, 44, 0, 25, 0,
-  0, 0, 0, 25, 0, 22, 0, 56, 83, 83,
-  12, 72, 44, 15, 0, 0, 20, 0, 22, 0,
-  23, 126, 0, 0, 0, 0, 39, 0, 24, 37,
-  34, 21, 0, 0, 35, 11, 0, 34, 52, 81,
-  0, 0, 0, 0, 0, 26, 0, 0, 0, 1,
-  0, 0, 1, 18, 42, 71, 0, 0, 11, 40,
-  0, 7, 106, 0, 38, 4, 10, 0, 0, 34,
-  61, 26, 20, 0, 27, 21, 0, 98, 0, 49,
-  51, 0, 0, 28, 54, 0, 44, 0, 0, 48,
-  15, 60, 0, 1, 2, 45, 68, 0, 14, 0,
-  0, 25, 0, 0, 81, 0, 11, 15, 12, 121,
-  4, 0, 0, 16, 0, 68, 74, 0, 26, 0,
-  17, 1, 24, 87, 0, 0, 20, 2, 10, 0,
-  0, 0, 0, 22, 0, 87, 32, 0, 66, 36,
-  9, 0, 0, 0, 5, 21, 0, 26, 30, 124,
-  0, 0, 0, 0, 23, 0, 28, 52, 0, 3,
-  0, 0, 50, 28, 0, 103, 0, 4, 0, 0,
-  39, 0, 82, 66, 0, 0, 35, 0, 2, 0,
-  0, 22, 7, 0, 0, 0, 0, 70, 0, 21,
-  74, 0, 0, 14, 10, 0, 0, 32, 91, 24,
-  64, 1, 0, 2, 0, 95, 0, 13, 72, 0,
-  0, 0, 0, 0, 86, 0, 0, 56, 11, 19,
-  0, 0, 12, 13, 141, 0, 0, 19, 0, 0,
-  4, 0, 38, 0, 0, 38, 31, 0, 0, 0,
-  0, 0, 0, 56, 51, 0, 69, 0, 0, 0,
-  107, 0, 36, 0, 0, 32, 38, 0, 0, 0,
-  0, 37, 0, 81, 51, 46, 25, 77, 65, 9,
-  0, 0, 20, 0, 19, 0, 51, 118, 0, 0,
-  0, 0, 16, 7, 12, 11, 0, 26, 0, 0,
-  55, 19, 0, 69, 20, 7, 22, 0, 56, 0,
-  0, 0, 0, 0, 0, 35, 0, 0, 31, 31,
-  30, 33, 0, 0, 23, 35, 0, 14, 38, 0,
-  27, 20, 0, 10, 0, 19, 19, 8, 0, 0,
-  0, 0, 2, 0, 0, 41, 51, 0, 0, 22,
-  0, 0, 35, 8, 0, 53, 41, 20, 0, 0,
-  35, 12, 95, 14, 26, 0, 0, 30, 0, 0,
-  70, 0, 0, 50, 0, 20, 0, 0, 0, 25,
-  0, 43, 127, 0, 82, 0, 12, 0, 31, 0,
-  14, 0, 0, 8, 49, 0, 2, 15, 10, 13,
-  0, 93, 42, 127, 15, 99, 80, 43, 0, 0,
-  43, 0, 32, 0, 35, 29, 0, 0, 11, 0,
-  41, 15, 0, 0, 0, 47, 24, 0, 52, 29,
-  0, 37, 5, 49, 69, 0, 20, 0, 0, 0,
-  0, 0, 0, 17, 0, 6, 19, 56, 44, 46,
-  0, 7, 4, 0, 0, 17, 32, 0, 50, 2,
-  0, 29, 21, 24, 0, 8, 0, 0, 52, 4,
-  27, 0, 0, 21, 45, 4, 6, 45, 10, 2,
-  0, 2, 0, 19, 40, 73, 0, 17, 5, 38,
-  21, 49, 107, 0, 0, 49, 0, 0, 90, 0,
-  23, 57, 7, 99, 1, 0, 25, 33, 41, 62,
-  122, 0, 7, 22, 36, 0, 0, 0, 0, 0,
-  0, 0, 13, 0, 43, 0, 45, 1, 13, 74,
-  37, 48, 54, 46, 22, 17, 0, 0, 75, 0,
-  31, 10, 55, 60, 0, 21, 0, 0, 43, 0,
-  38, 0, 0, 48, 0, 0, 41, 28, 0, 38,
-  57, 0, 0, 0, 24, 0, 32, 0, 0, 0,
-  0, 80, 0, 0, 0, 0, 14, 21, 0, 28,
-  36, 67, 0, 12, 53, 0, 1, 49, 0, 34,
-  0, 0, 0, 41, 0, 12, 9, 0, 0, 0,
-  0, 43, 25, 31, 0, 22, 14, 0, 16, 22,
-  0, 32, 73, 0, 0, 30, 3, 13, 122, 5,
-  40, 0, 0, 1, 0, 0, 93, 0, 14, 55,
-  0, 0, 0, 0, 0, 54, 0, 32, 56, 22,
-  48, 0, 15, 0, 63, 0, 0, 0, 0, 46,
-  59, 0, 14, 0, 6, 28, 0, 93, 18, 58,
-  66, 69, 39, 34, 0, 0, 61, 0, 24, 0,
-  24, 41, 11, 21, 49, 14, 29, 7, 0, 0,
-  0, 34, 1, 0, 22, 29, 0, 26, 0, 5,
-  31, 0, 36, 0, 13, 0, 0, 0, 0, 34,
-  0, 0, 10, 55, 10, 6, 0, 0, 30, 0,
-  0, 0, 35, 0, 20, 14, 0, 4, 0, 6,
-  0, 0, 0, 0, 31, 0, 49, 0, 0, 0,
-  64, 30, 0, 37, 0, 10, 0, 53, 0, 8,
-  43, 93, 0, 42, 5, 3, 30, 39, 93, 5,
-  0, 0, 11, 0, 68, 0, 0, 79, 5, 0,
-  0, 0, 30, 61, 0, 15, 39, 0, 23, 0,
-  0, 0, 0, 0, 12, 0, 0, 0, 11, 0,
-  7, 0, 19, 17, 24, 37, 19, 83, 100, 57,
-  60, 86, 0, 0, 16, 0, 0, 0, 1, 37,
-  9, 22, 45, 0, 3, 24, 0, 9, 0, 26,
-  12, 0, 0, 30, 0, 58, 0, 45, 5, 36,
-  29, 8, 0, 14, 0, 6, 0, 0, 0, 30,
-  1, 47, 31, 38, 0, 0, 15, 0, 0, 0,
-  7, 0, 28, 11, 0, 0, 0, 19, 0, 0,
-  0, 0, 25, 0, 71, 0, 0, 0, 48, 11,
-  37, 0, 0, 0, 0, 14, 0, 10, 19, 113,
-  22, 41, 0, 37, 0, 20, 39, 0, 0, 0,
-  11, 0, 10, 0, 0, 52, 9, 11, 0, 0,
-  76, 50, 5, 16, 33, 0, 25, 22, 0, 4,
-  0, 0, 10, 0, 0, 0, 0, 0, 0, 0,
-  34, 0, 47, 18, 19, 3, 82, 25, 7, 0,
-  0, 19, 0, 0, 0, 50, 24, 124, 0, 0,
-  0, 0, 0, 0, 16, 66, 70, 4, 0, 0,
-  12, 4, 0, 88, 7, 3, 0, 13, 0, 0,
-  74, 8, 0, 0, 84, 0, 0, 15, 17, 36,
-  17, 22, 4, 0, 9, 49, 0, 0, 86, 0,
-  46, 0, 71, 0, 0, 47, 100, 0, 96, 0,
-  0, 47, 0, 116, 0, 23, 90, 0, 0, 33,
-  0, 0, 23, 0, 0, 55, 0, 76, 0, 1,
-  45, 31, 68, 0, 0, 0, 10, 0, 0, 0,
-  0, 0, 0, 29, 67, 0, 0, 0, 0, 4,
-  0, 42, 0, 0, 54, 0, 0, 0, 124, 74,
-  44, 0, 25, 0, 0, 0, 0, 25, 0, 22,
-  0, 56, 83, 83, 12, 72, 44, 15, 0, 0,
-  20, 0, 22, 0, 23, 126, 0, 0, 0, 0,
-  39, 0, 24, 37, 34, 21, 0, 0, 35, 11,
-  0, 34, 52, 81, 0, 0, 0, 0, 0, 26,
-  0, 0, 0, 1, 0, 0, 1, 18, 42, 71,
-  0, 0, 11, 40, 0, 7, 106, 0, 38, 4,
-  10, 0, 0, 34, 61, 26, 20, 0, 27, 21,
-  0, 98, 0, 49, 51, 0, 0, 28, 54, 0,
-  44, 0, 0, 48, 15, 60, 0, 1, 2, 45,
-  68, 0, 14, 0, 0, 25, 0, 0, 81, 0,
-  11, 15, 12, 121, 4, 0, 0, 16, 0, 68,
-  74, 0, 26, 0, 17, 1, 24, 87, 0, 0,
-  20, 2, 10, 0, 0, 0, 0, 22, 0, 87,
-  35, 0, 20, 65, 14, 232, 0, 0, 1, 0,
-  0, 0, 0, 21, 0, 0, 0, 33, 62, 0,
-  0, 113, 15, 0, 0, 0, 0, 6, 0, 17,
-  8, 99, 0, 0, 0, 33, 0, 40, 0, 0,
-  0, 0, 0, 0, 0, 58, 44, 47, 7, 4,
-  0, 38, 0, 0, 142, 0, 48, 0, 21, 0,
-  27, 92, 17, 0, 115, 0, 0, 40, 0, 96,
-  83, 63, 62, 0, 0, 35, 43, 0, 0, 0,
-  0, 0, 46, 65, 0, 0, 0, 31, 0, 0,
-  7, 7, 0, 0, 70, 0, 52, 0, 0, 9,
-  17, 116, 2, 0, 0, 5, 18, 17, 0, 0,
-  0, 39, 0, 0, 0, 45, 36, 0, 13, 16,
-  0, 19, 0, 0, 0, 15, 0, 44, 51, 46,
-  25, 77, 65, 9, 0, 0, 20, 0, 19, 0,
-  51, 118, 0, 0, 0, 0, 16, 7, 12, 11,
-  0, 26, 0, 0, 55, 19, 0, 69, 20, 7,
-  22, 0, 56, 0, 0, 0, 0, 0, 0, 35,
-  0, 0, 31, 31, 30, 33, 0, 0, 23, 35,
-  0, 14, 38, 0, 27, 20, 0, 10, 0, 19,
-  19, 8, 0, 0, 0, 0, 2, 0, 0, 41,
-  51, 0, 0, 22, 0, 0, 35, 8, 0, 53,
-  41, 20, 0, 0, 35, 12, 95, 14, 26, 0,
-  0, 30, 0, 0, 70, 0, 0, 50, 0, 20,
-  0, 0, 0, 25, 0, 43, 127, 0, 82, 0,
-  12, 0, 31, 0, 14, 0, 0, 8, 49, 0,
-  2, 15, 10, 13, 0, 93, 42, 127, 15, 99,
-  80, 43, 0, 0, 43, 0, 32, 0, 35, 29,
-  0, 0, 11, 0, 41, 15, 0, 0, 0, 47,
-  24, 0, 52, 29, 0, 37, 5, 49, 69, 0,
-  20, 0, 0, 0, 0, 0, 0, 17, 0, 6,
-  19, 56, 44, 46, 0, 7, 4, 0, 0, 17,
-  32, 0, 50, 2, 0, 29, 21, 24, 0, 8,
-  0, 0, 52, 4, 27, 0, 0, 21, 45, 4,
-  6, 45, 10, 2, 0, 2, 0, 19, 40, 73,
-  0, 17, 5, 38, 21, 49, 107, 0, 0, 49,
-  0, 0, 90, 0, 23, 57, 7, 99, 1, 0,
-  25, 33, 41, 62, 122, 0, 7, 22, 36, 0,
-  0, 0, 0, 0, 0, 0, 13, 0, 43, 0,
-  45, 1, 13, 74, 17, 8, 86, 68, 23, 217,
-  0, 0, 29, 0, 0, 0, 32, 0, 0, 0,
-  31, 18, 66, 0, 0, 112, 15, 8, 7, 0,
-  0, 35, 0, 72, 0, 82, 0, 0, 0, 30,
-  0, 0, 1, 0, 0, 19, 0, 19, 0, 50,
-  59, 42, 0, 14, 0, 45, 0, 0, 97, 0,
-  62, 0, 33, 0, 0, 70, 0, 0, 53, 0,
-  0, 26, 12, 6, 27, 25, 76, 0, 0, 26,
-  25, 0, 0, 18, 0, 0, 77, 83, 0, 0,
-  0, 18, 0, 4, 54, 0, 0, 0, 24, 0,
-  25, 0, 15, 39, 25, 35, 17, 0, 0, 31,
-  47, 29, 0, 0, 0, 45, 0, 0, 0, 0,
-  38, 0, 3, 0, 0, 1, 0, 22, 25, 0,
-  0, 20, 18, 58, 66, 69, 39, 34, 0, 0,
-  61, 0, 24, 0, 24, 41, 11, 21, 49, 14,
-  29, 7, 0, 0, 0, 34, 1, 0, 22, 29,
-  0, 26, 0, 5, 31, 0, 36, 0, 13, 0,
-  0, 0, 0, 34, 0, 0, 10, 55, 10, 6,
-  0, 0, 30, 0, 0, 0, 35, 0, 20, 14,
-  0, 4, 0, 6, 0, 0, 0, 0, 31, 0,
-  49, 0, 0, 0, 64, 30, 0, 37, 0, 10,
-  0, 53, 0, 8, 43, 93, 0, 42, 5, 3,
-  30, 39, 93, 5, 0, 0, 11, 0, 68, 0,
-  0, 79, 5, 0, 0, 0, 30, 61, 0, 15,
-  39, 0, 23, 0, 0, 0, 0, 0, 12, 0,
-  0, 0, 11, 0, 7, 0, 19, 17, 24, 37,
-  19, 83, 100, 57, 60, 86, 0, 0, 16, 0,
-  0, 0, 1, 37, 9, 22, 45, 0, 3, 24,
-  0, 9, 0, 26, 12, 0, 0, 30, 0, 58,
-  0, 45, 5, 36, 29, 8, 0, 14, 0, 6,
-  0, 0, 0, 30, 1, 47, 31, 38, 0, 0,
-  15, 0, 0, 0, 7, 0, 28, 11, 0, 0,
-  0, 19, 0, 0, 0, 0, 25, 0, 71, 0,
-  0, 0, 48, 11, 37, 0, 0, 0, 0, 14,
-  0, 10, 19, 113, 22, 41, 0, 37, 0, 20,
-  39, 0, 0, 0, 11, 0, 10, 0, 0, 52,
-  9, 11, 0, 0, 76, 50, 5, 16, 33, 0,
-  25, 22, 0, 4, 0, 0, 10, 0, 0, 0,
-  0, 0, 0, 0, 34, 0, 47, 18, 11, 11,
-  105, 33, 25, 144, 0, 0, 0, 0, 0, 0,
-  17, 0, 0, 0, 17, 5, 23, 0, 0, 94,
-  8, 12, 0, 0, 0, 0, 0, 52, 0, 26,
-  0, 34, 0, 30, 0, 0, 0, 25, 0, 0,
-  0, 39, 0, 0, 23, 37, 0, 0, 0, 86,
-  0, 0, 64, 0, 59, 0, 41, 0, 0, 32,
-  0, 17, 51, 3, 0, 0, 41, 0, 4, 7,
-  56, 0, 27, 0, 0, 0, 0, 10, 0, 0,
-  45, 50, 55, 11, 0, 9, 2, 0, 0, 0,
-  20, 0, 18, 0, 0, 0, 20, 19, 0, 0,
-  0, 0, 22, 38, 4, 0, 0, 0, 37, 28,
-  0, 0, 0, 0, 63, 0, 8, 0, 0, 0,
-  0, 12, 39, 5, 0, 0, 83, 83, 12, 72,
-  44, 15, 0, 0, 20, 0, 22, 0, 23, 126,
-  0, 0, 0, 0, 39, 0, 24, 37, 34, 21,
-  0, 0, 35, 11, 0, 34, 52, 81, 0, 0,
-  0, 0, 0, 26, 0, 0, 0, 1, 0, 0,
-  1, 18, 42, 71, 0, 0, 11, 40, 0, 7,
-  106, 0, 38, 4, 10, 0, 0, 34, 61, 26,
-  20, 0, 27, 21, 0, 98, 0, 49, 51, 0,
-  0, 28, 54, 0, 44, 0, 0, 48, 15, 60,
-  0, 1, 2, 45, 68, 0, 14, 0, 0, 25,
-  0, 0, 81, 0, 11, 15, 12, 121, 4, 0,
-  0, 16, 0, 68, 74, 0, 26, 0, 17, 1,
-  24, 87, 0, 0, 20, 2, 10, 0, 0, 0,
-  0, 22, 0, 87, 35, 0, 20, 65, 14, 232,
-  0, 0, 1, 0, 0, 0, 0, 21, 0, 0,
-  0, 33, 62, 0, 0, 113, 15, 0, 0, 0,
-  0, 6, 0, 17, 8, 99, 0, 0, 0, 33,
-  0, 40, 0, 0, 0, 0, 0, 0, 0, 58,
-  44, 47, 7, 4, 0, 38, 0, 0, 142, 0,
-  48, 0, 21, 0, 27, 92, 17, 0, 115, 0,
-  0, 40, 0, 96, 83, 63, 62, 0, 0, 35,
-  43, 0, 0, 0, 0, 0, 46, 65, 0, 0,
-  0, 31, 0, 0, 7, 7, 0, 0, 70, 0,
-  52, 0, 0, 9, 17, 116, 2, 0, 0, 5,
-  18, 17, 0, 0, 0, 39, 0, 0, 0, 45,
-  36, 0, 13, 16, 0, 19, 0, 0, 0, 15,
-  0, 44, 0, 0, 0, 5, 19, 184, 0, 0,
-  0, 0, 0, 0, 30, 14, 0, 24, 4, 50,
-  5, 0, 21, 0, 0, 62, 18, 19, 0, 0,
-  0, 10, 18, 0, 0, 34, 0, 4, 0, 24,
-  0, 24, 0, 55, 0, 16, 0, 17, 43, 43,
-  0, 20, 0, 38, 14, 0, 0, 0, 9, 0,
-  19, 12, 5, 26, 0, 0, 6, 0, 0, 22,
-  22, 0, 30, 56, 37, 1, 2, 80, 0, 0,
-  0, 42, 0, 0, 13, 12, 24, 0, 22, 14,
-  2, 28, 1, 67, 43, 9, 35, 30, 0, 0,
-  7, 25, 0, 0, 0, 0, 0, 0, 0, 6,
-  0, 17, 0, 1, 0, 13, 0, 7, 81, 29,
-  34, 0, 48, 9, 42, 0, 38, 19, 0, 0,
-  42, 127, 15, 99, 80, 43, 0, 0, 43, 0,
-  32, 0, 35, 29, 0, 0, 11, 0, 41, 15,
-  0, 0, 0, 47, 24, 0, 52, 29, 0, 37,
-  5, 49, 69, 0, 20, 0, 0, 0, 0, 0,
-  0, 17, 0, 6, 19, 56, 44, 46, 0, 7,
-  4, 0, 0, 17, 32, 0, 50, 2, 0, 29,
-  21, 24, 0, 8, 0, 0, 52, 4, 27, 0,
-  0, 21, 45, 4, 6, 45, 10, 2, 0, 2,
-  0, 19, 40, 73, 0, 17, 5, 38, 21, 49,
-  107, 0, 0, 49, 0, 0, 90, 0, 23, 57,
-  7, 99, 1, 0, 25, 33, 41, 62, 122, 0,
-  7, 22, 36, 0, 0, 0, 0, 0, 0, 0,
-  13, 0, 43, 0, 45, 1, 13, 74, 17, 8,
-  86, 68, 23, 217, 0, 0, 29, 0, 0, 0,
-  32, 0, 0, 0, 31, 18, 66, 0, 0, 112,
-  15, 8, 7, 0, 0, 35, 0, 72, 0, 82,
-  0, 0, 0, 30, 0, 0, 1, 0, 0, 19,
-  0, 19, 0, 50, 59, 42, 0, 14, 0, 45,
-  0, 0, 97, 0, 62, 0, 33, 0, 0, 70,
-  0, 0, 53, 0, 0, 26, 12, 6, 27, 25,
-  76, 0, 0, 26, 25, 0, 0, 18, 0, 0,
-  77, 83, 0, 0, 0, 18, 0, 4, 54, 0,
-  0, 0, 24, 0, 25, 0, 15, 39, 25, 35,
-  17, 0, 0, 31, 47, 29, 0, 0, 0, 45,
-  0, 0, 0, 0, 38, 0, 3, 0, 0, 1,
-  0, 22, 25, 0, 0, 20, 0, 0, 0, 0,
-  1, 125, 0, 0, 0, 0, 0, 0, 59, 8,
-  0, 44, 12, 40, 18, 0, 40, 6, 0, 49,
-  0, 0, 0, 0, 0, 14, 40, 0, 0, 17,
-  0, 8, 0, 16, 0, 48, 35, 47, 0, 33,
-  1, 0, 7, 27, 0, 35, 0, 77, 28, 0,
-  14, 0, 38, 0, 36, 0, 0, 14, 0, 11,
-  0, 0, 0, 3, 8, 0, 16, 34, 27, 15,
-  0, 70, 0, 0, 0, 26, 7, 0, 14, 12,
-  42, 0, 12, 0, 8, 25, 0, 47, 52, 0,
-  15, 13, 0, 0, 17, 28, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 32, 29, 12, 0, 47,
-  0, 0, 66, 14, 50, 0, 35, 14, 18, 0,
-  67, 1, 0, 0, 19, 83, 100, 57, 60, 86,
-  0, 0, 16, 0, 0, 0, 1, 37, 9, 22,
-  45, 0, 3, 24, 0, 9, 0, 26, 12, 0,
-  0, 30, 0, 58, 0, 45, 5, 36, 29, 8,
-  0, 14, 0, 6, 0, 0, 0, 30, 1, 47,
-  31, 38, 0, 0, 15, 0, 0, 0, 7, 0,
-  28, 11, 0, 0, 0, 19, 0, 0, 0, 0,
-  25, 0, 71, 0, 0, 0, 48, 11, 37, 0,
-  0, 0, 0, 14, 0, 10, 19, 113, 22, 41,
-  0, 37, 0, 20, 39, 0, 0, 0, 11, 0,
-  10, 0, 0, 52, 9, 11, 0, 0, 76, 50,
-  5, 16, 33, 0, 25, 22, 0, 4, 0, 0,
-  10, 0, 0, 0, 0, 0, 0, 0, 34, 0,
-  47, 18, 11, 11, 105, 33, 25, 144, 0, 0,
-  0, 0, 0, 0, 17, 0, 0, 0, 17, 5,
-  23, 0, 0, 94, 8, 12, 0, 0, 0, 0,
-  0, 52, 0, 26, 0, 34, 0, 30, 0, 0,
-  0, 25, 0, 0, 0, 39, 0, 0, 23, 37,
-  0, 0, 0, 86, 0, 0, 64, 0, 59, 0,
-  41, 0, 0, 32, 0, 17, 51, 3, 0, 0,
-  41, 0, 4, 7, 56, 0, 27, 0, 0, 0,
-  0, 10, 0, 0, 45, 50, 55, 11, 0, 9,
-  2, 0, 0, 0, 20, 0, 18, 0, 0, 0,
-  20, 19, 0, 0, 0, 0, 22, 38, 4, 0,
-  0, 0, 37, 28, 0, 0, 0, 0, 63, 0,
-  8, 0, 0, 0, 0, 12, 39, 5, 0, 0,
-  0, 2, 46, 0, 14, 18, 11, 0, 12, 0,
-  0, 11, 59, 26, 0, 39, 3, 30, 27, 0,
-  68, 23, 33, 23, 0, 0, 0, 0, 0, 0,
-  61, 0, 0, 0, 0, 7, 0, 8, 0, 25,
-  64, 32, 0, 78, 13, 0, 0, 10, 0, 12,
-  0, 114, 19, 0, 44, 0, 53, 0, 52, 0,
-  0, 0, 0, 20, 19, 0, 0, 11, 0, 0,
-  0, 19, 15, 39, 5, 36, 0, 0, 0, 0,
-  27, 0, 8, 0, 65, 1, 0, 0, 39, 0,
-  0, 25, 36, 0, 0, 17, 0, 0, 33, 36,
-  0, 0, 0, 0, 22, 0, 0, 0, 0, 13,
-  66, 18, 0, 34, 0, 0, 63, 12, 74, 5,
-  47, 3, 0, 0, 82, 14, 12, 0, 35, 0,
-  20, 65, 14, 232, 0, 0, 1, 0, 0, 0,
-  0, 21, 0, 0, 0, 33, 62, 0, 0, 113,
-  15, 0, 0, 0, 0, 6, 0, 17, 8, 99,
-  0, 0, 0, 33, 0, 40, 0, 0, 0, 0,
-  0, 0, 0, 58, 44, 47, 7, 4, 0, 38,
-  0, 0, 142, 0, 48, 0, 21, 0, 27, 92,
-  17, 0, 115, 0, 0, 40, 0, 96, 83, 63,
-  62, 0, 0, 35, 43, 0, 0, 0, 0, 0,
-  46, 65, 0, 0, 0, 31, 0, 0, 7, 7,
-  0, 0, 70, 0, 52, 0, 0, 9, 17, 116,
-  2, 0, 0, 5, 18, 17, 0, 0, 0, 39,
-  0, 0, 0, 45, 36, 0, 13, 16, 0, 19,
-  0, 0, 0, 15, 0, 44, 0, 0, 0, 5,
-  19, 184, 0, 0, 0, 0, 0, 0, 30, 14,
-  0, 24, 4, 50, 5, 0, 21, 0, 0, 62,
-  18, 19, 0, 0, 0, 10, 18, 0, 0, 34,
-  0, 4, 0, 24, 0, 24, 0, 55, 0, 16,
-  0, 17, 43, 43, 0, 20, 0, 38, 14, 0,
-  0, 0, 9, 0, 19, 12, 5, 26, 0, 0,
-  6, 0, 0, 22, 22, 0, 30, 56, 37, 1,
-  2, 80, 0, 0, 0, 42, 0, 0, 13, 12,
-  24, 0, 22, 14, 2, 28, 1, 67, 43, 9,
-  35, 30, 0, 0, 7, 25, 0, 0, 0, 0,
-  0, 0, 0, 6, 0, 17, 0, 1, 0, 13,
-  0, 7, 81, 29, 34, 0, 48, 9, 42, 0,
-  38, 19, 0, 0, 0, 34, 49, 0, 25, 0,
-  17, 0, 0, 0, 0, 0, 29, 51, 2, 46,
-  15, 40, 0, 20, 33, 0, 79, 40, 0, 20,
-  0, 0, 0, 0, 25, 0, 0, 0, 0, 0,
-  0, 5, 0, 35, 63, 42, 0, 75, 56, 0,
-  0, 0, 0, 4, 0, 42, 63, 0, 1, 0,
-  44, 5, 9, 0, 0, 3, 0, 23, 0, 0,
-  26, 7, 0, 0, 0, 3, 4, 30, 12, 34,
-  0, 8, 0, 0, 40, 0, 0, 0, 68, 13,
-  0, 0, 40, 12, 0, 29, 32, 0, 0, 30,
-  0, 0, 0, 46, 0, 0, 0, 0, 5, 0,
-  0, 0, 0, 29, 58, 4, 0, 15, 30, 0,
-  26, 17, 54, 0, 15, 0, 9, 0, 76, 5,
-  0, 0, 17, 8, 86, 68, 23, 217, 0, 0,
-  29, 0, 0, 0, 32, 0, 0, 0, 31, 18,
-  66, 0, 0, 112, 15, 8, 7, 0, 0, 35,
-  0, 72, 0, 82, 0, 0, 0, 30, 0, 0,
-  1, 0, 0, 19, 0, 19, 0, 50, 59, 42,
-  0, 14, 0, 45, 0, 0, 97, 0, 62, 0,
-  33, 0, 0, 70, 0, 0, 53, 0, 0, 26,
-  12, 6, 27, 25, 76, 0, 0, 26, 25, 0,
-  0, 18, 0, 0, 77, 83, 0, 0, 0, 18,
-  0, 4, 54, 0, 0, 0, 24, 0, 25, 0,
-  15, 39, 25, 35, 17, 0, 0, 31, 47, 29,
-  0, 0, 0, 45, 0, 0, 0, 0, 38, 0,
-  3, 0, 0, 1, 0, 22, 25, 0, 0, 20,
-  0, 0, 0, 0, 1, 125, 0, 0, 0, 0,
-  0, 0, 59, 8, 0, 44, 12, 40, 18, 0,
-  40, 6, 0, 49, 0, 0, 0, 0, 0, 14,
-  40, 0, 0, 17, 0, 8, 0, 16, 0, 48,
-  35, 47, 0, 33, 1, 0, 7, 27, 0, 35,
-  0, 77, 28, 0, 14, 0, 38, 0, 36, 0,
-  0, 14, 0, 11, 0, 0, 0, 3, 8, 0,
-  16, 34, 27, 15, 0, 70, 0, 0, 0, 26,
-  7, 0, 14, 12, 42, 0, 12, 0, 8, 25,
-  0, 47, 52, 0, 15, 13, 0, 0, 17, 28,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 32,
-  29, 12, 0, 47, 0, 0, 66, 14, 50, 0,
-  35, 14, 18, 0, 67, 1, 0, 0, 0, 0,
-  77, 0, 0, 0, 2, 0, 0, 0, 0, 1,
-  29, 58, 0, 41, 0, 69, 29, 7, 59, 19,
-  117, 17, 0, 0, 0, 5, 0, 0, 15, 0,
-  0, 0, 0, 13, 0, 12, 0, 0, 66, 0,
-  0, 79, 32, 0, 0, 0, 0, 6, 0, 87,
-  7, 0, 39, 0, 49, 0, 7, 0, 0, 1,
-  10, 0, 77, 0, 0, 21, 0, 50, 0, 0,
-  2, 19, 0, 7, 0, 0, 0, 0, 19, 0,
-  2, 0, 62, 8, 0, 0, 25, 0, 0, 13,
-  0, 0, 16, 30, 0, 0, 0, 54, 3, 0,
-  0, 0, 20, 0, 0, 0, 0, 0, 62, 11,
-  0, 38, 13, 0, 89, 23, 44, 14, 34, 0,
-  0, 0, 57, 0, 15, 0, 11, 11, 105, 33,
-  25, 144, 0, 0, 0, 0, 0, 0, 17, 0,
-  0, 0, 17, 5, 23, 0, 0, 94, 8, 12,
-  0, 0, 0, 0, 0, 52, 0, 26, 0, 34,
-  0, 30, 0, 0, 0, 25, 0, 0, 0, 39,
-  0, 0, 23, 37, 0, 0, 0, 86, 0, 0,
-  64, 0, 59, 0, 41, 0, 0, 32, 0, 17,
-  51, 3, 0, 0, 41, 0, 4, 7, 56, 0,
-  27, 0, 0, 0, 0, 10, 0, 0, 45, 50,
-  55, 11, 0, 9, 2, 0, 0, 0, 20, 0,
-  18, 0, 0, 0, 20, 19, 0, 0, 0, 0,
-  22, 38, 4, 0, 0, 0, 37, 28, 0, 0,
-  0, 0, 63, 0, 8, 0, 0, 0, 0, 12,
-  39, 5, 0, 0, 0, 2, 46, 0, 14, 18,
-  11, 0, 12, 0, 0, 11, 59, 26, 0, 39,
-  3, 30, 27, 0, 68, 23, 33, 23, 0, 0,
-  0, 0, 0, 0, 61, 0, 0, 0, 0, 7,
-  0, 8, 0, 25, 64, 32, 0, 78, 13, 0,
-  0, 10, 0, 12, 0, 114, 19, 0, 44, 0,
-  53, 0, 52, 0, 0, 0, 0, 20, 19, 0,
-  0, 11, 0, 0, 0, 19, 15, 39, 5, 36,
-  0, 0, 0, 0, 27, 0, 8, 0, 65, 1,
-  0, 0, 39, 0, 0, 25, 36, 0, 0, 17,
-  0, 0, 33, 36, 0, 0, 0, 0, 22, 0,
-  0, 0, 0, 13, 66, 18, 0, 34, 0, 0,
-  63, 12, 74, 5, 47, 3, 0, 0, 82, 14,
-  12, 0, 5, 0, 69, 0, 12, 8, 0, 0,
-  19, 0, 0, 0, 40, 75, 0, 7, 0, 50,
-  40, 0, 68, 50, 83, 1, 0, 0, 0, 31,
-  0, 3, 20, 0, 0, 0, 0, 5, 0, 22,
-  0, 0, 22, 4, 0, 91, 26, 21, 0, 48,
-  0, 0, 1, 153, 0, 0, 66, 0, 33, 0,
-  18, 0, 0, 0, 11, 0, 112, 0, 0, 0,
-  0, 59, 0, 0, 0, 7, 0, 0, 0, 0,
-  0, 0, 9, 0, 15, 0, 36, 8, 0, 0,
-  45, 0, 0, 0, 0, 0, 6, 8, 0, 0,
-  1, 53, 30, 0, 0, 0, 16, 0, 0, 5,
-  5, 0, 72, 5, 0, 42, 10, 0, 150, 0,
-  30, 25, 71, 0, 0, 0, 50, 0, 12, 0,
-  0, 0, 0, 5, 19, 184, 0, 0, 0, 0,
-  0, 0, 30, 14, 0, 24, 4, 50, 5, 0,
-  21, 0, 0, 62, 18, 19, 0, 0, 0, 10,
-  18, 0, 0, 34, 0, 4, 0, 24, 0, 24,
-  0, 55, 0, 16, 0, 17, 43, 43, 0, 20,
-  0, 38, 14, 0, 0, 0, 9, 0, 19, 12,
-  5, 26, 0, 0, 6, 0, 0, 22, 22, 0,
-  30, 56, 37, 1, 2, 80, 0, 0, 0, 42,
-  0, 0, 13, 12, 24, 0, 22, 14, 2, 28,
-  1, 67, 43, 9, 35, 30, 0, 0, 7, 25,
-  0, 0, 0, 0, 0, 0, 0, 6, 0, 17,
-  0, 1, 0, 13, 0, 7, 81, 29, 34, 0,
-  48, 9, 42, 0, 38, 19, 0, 0, 0, 34,
-  49, 0, 25, 0, 17, 0, 0, 0, 0, 0,
-  29, 51, 2, 46, 15, 40, 0, 20, 33, 0,
-  79, 40, 0, 20, 0, 0, 0, 0, 25, 0,
-  0, 0, 0, 0, 0, 5, 0, 35, 63, 42,
-  0, 75, 56, 0, 0, 0, 0, 4, 0, 42,
-  63, 0, 1, 0, 44, 5, 9, 0, 0, 3,
-  0, 23, 0, 0, 26, 7, 0, 0, 0, 3,
-  4, 30, 12, 34, 0, 8, 0, 0, 40, 0,
-  0, 0, 68, 13, 0, 0, 40, 12, 0, 29,
-  32, 0, 0, 30, 0, 0, 0, 46, 0, 0,
-  0, 0, 5, 0, 0, 0, 0, 29, 58, 4,
-  0, 15, 30, 0, 26, 17, 54, 0, 15, 0,
-  9, 0, 76, 5, 0, 0, 10, 0, 77, 0,
-  9, 10, 0, 0, 4, 0, 0, 8, 3, 82,
-  0, 0, 0, 46, 42, 0, 45, 68, 136, 0,
-  0, 0, 0, 0, 0, 0, 3, 0, 0, 0,
-  0, 9, 0, 0, 0, 0, 33, 0, 0, 90,
-  40, 14, 0, 21, 0, 0, 0, 136, 0, 0,
-  74, 0, 41, 0, 36, 0, 0, 0, 35, 0,
-  125, 0, 0, 23, 0, 91, 0, 0, 13, 4,
-  0, 0, 7, 0, 0, 0, 15, 0, 23, 0,
-  45, 6, 0, 0, 20, 0, 0, 0, 0, 0,
-  24, 27, 0, 0, 0, 52, 15, 0, 0, 0,
-  14, 0, 0, 2, 0, 0, 69, 4, 0, 37,
-  12, 0, 118, 0, 23, 19, 24, 0, 0, 0,
-  53, 0, 0, 0, 0, 0, 0, 0, 1, 125,
-  0, 0, 0, 0, 0, 0, 59, 8, 0, 44,
-  12, 40, 18, 0, 40, 6, 0, 49, 0, 0,
-  0, 0, 0, 14, 40, 0, 0, 17, 0, 8,
-  0, 16, 0, 48, 35, 47, 0, 33, 1, 0,
-  7, 27, 0, 35, 0, 77, 28, 0, 14, 0,
-  38, 0, 36, 0, 0, 14, 0, 11, 0, 0,
-  0, 3, 8, 0, 16, 34, 27, 15, 0, 70,
-  0, 0, 0, 26, 7, 0, 14, 12, 42, 0,
-  12, 0, 8, 25, 0, 47, 52, 0, 15, 13,
-  0, 0, 17, 28, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 32, 29, 12, 0, 47, 0, 0,
-  66, 14, 50, 0, 35, 14, 18, 0, 67, 1,
-  0, 0, 0, 0, 77, 0, 0, 0, 2, 0,
-  0, 0, 0, 1, 29, 58, 0, 41, 0, 69,
-  29, 7, 59, 19, 117, 17, 0, 0, 0, 5,
-  0, 0, 15, 0, 0, 0, 0, 13, 0, 12,
-  0, 0, 66, 0, 0, 79, 32, 0, 0, 0,
-  0, 6, 0, 87, 7, 0, 39, 0, 49, 0,
-  7, 0, 0, 1, 10, 0, 77, 0, 0, 21,
-  0, 50, 0, 0, 2, 19, 0, 7, 0, 0,
-  0, 0, 19, 0, 2, 0, 62, 8, 0, 0,
-  25, 0, 0, 13, 0, 0, 16, 30, 0, 0,
-  0, 54, 3, 0, 0, 0, 20, 0, 0, 0,
-  0, 0, 62, 11, 0, 38, 13, 0, 89, 23,
-  44, 14, 34, 0, 0, 0, 57, 0, 15, 0,
-  25, 0, 64, 0, 17, 12, 0, 0, 23, 0,
-  0, 6, 16, 72, 0, 0, 0, 19, 42, 0,
-  48, 60, 61, 0, 0, 0, 0, 26, 0, 41,
-  0, 0, 0, 0, 0, 3, 0, 6, 0, 0,
-  0, 0, 0, 69, 18, 17, 0, 65, 0, 0,
-  0, 167, 0, 0, 66, 0, 29, 0, 4, 0,
-  0, 0, 24, 0, 113, 0, 0, 10, 0, 64,
-  0, 4, 0, 0, 0, 0, 0, 0, 0, 0,
-  12, 0, 12, 0, 32, 1, 0, 15, 43, 0,
-  26, 0, 0, 0, 27, 0, 11, 0, 0, 71,
-  39, 0, 0, 0, 13, 0, 0, 24, 30, 0,
-  73, 0, 0, 44, 14, 0, 155, 0, 5, 26,
-  74, 0, 0, 0, 54, 0, 0, 0, 0, 2,
-  46, 0, 14, 18, 11, 0, 12, 0, 0, 11,
-  59, 26, 0, 39, 3, 30, 27, 0, 68, 23,
-  33, 23, 0, 0, 0, 0, 0, 0, 61, 0,
-  0, 0, 0, 7, 0, 8, 0, 25, 64, 32,
-  0, 78, 13, 0, 0, 10, 0, 12, 0, 114,
-  19, 0, 44, 0, 53, 0, 52, 0, 0, 0,
-  0, 20, 19, 0, 0, 11, 0, 0, 0, 19,
-  15, 39, 5, 36, 0, 0, 0, 0, 27, 0,
-  8, 0, 65, 1, 0, 0, 39, 0, 0, 25,
-  36, 0, 0, 17, 0, 0, 33, 36, 0, 0,
-  0, 0, 22, 0, 0, 0, 0, 13, 66, 18,
-  0, 34, 0, 0, 63, 12, 74, 5, 47, 3,
-  0, 0, 82, 14, 12, 0, 5, 0, 69, 0,
-  12, 8, 0, 0, 19, 0, 0, 0, 40, 75,
-  0, 7, 0, 50, 40, 0, 68, 50, 83, 1,
-  0, 0, 0, 31, 0, 3, 20, 0, 0, 0,
-  0, 5, 0, 22, 0, 0, 22, 4, 0, 91,
-  26, 21, 0, 48, 0, 0, 1, 153, 0, 0,
-  66, 0, 33, 0, 18, 0, 0, 0, 11, 0,
-  112, 0, 0, 0, 0, 59, 0, 0, 0, 7,
-  0, 0, 0, 0, 0, 0, 9, 0, 15, 0,
-  36, 8, 0, 0, 45, 0, 0, 0, 0, 0,
-  6, 8, 0, 0, 1, 53, 30, 0, 0, 0,
-  16, 0, 0, 5, 5, 0, 72, 5, 0, 42,
-  10, 0, 150, 0, 30, 25, 71, 0, 0, 0,
-  50, 0, 12, 0, 0, 0, 9, 0, 23, 7,
-  0, 0, 42, 0, 0, 0, 8, 47, 0, 0,
-  0, 0, 32, 0, 34, 11, 0, 18, 0, 0,
-  19, 48, 0, 74, 0, 0, 9, 0, 0, 0,
-  0, 14, 0, 0, 0, 0, 0, 37, 0, 40,
-  0, 86, 0, 0, 8, 140, 13, 21, 34, 0,
-  22, 0, 0, 0, 0, 0, 0, 0, 51, 0,
-  0, 0, 0, 14, 0, 9, 0, 0, 0, 24,
-  0, 0, 0, 11, 28, 0, 0, 0, 0, 0,
-  0, 47, 50, 10, 57, 0, 0, 0, 10, 0,
-  28, 0, 0, 84, 46, 0, 26, 0, 7, 0,
-  21, 14, 59, 0, 50, 0, 0, 36, 7, 0,
-  152, 0, 0, 31, 100, 6, 74, 0, 41, 0,
-  0, 0, 0, 34, 49, 0, 25, 0, 17, 0,
-  0, 0, 0, 0, 29, 51, 2, 46, 15, 40,
-  0, 20, 33, 0, 79, 40, 0, 20, 0, 0,
-  0, 0, 25, 0, 0, 0, 0, 0, 0, 5,
-  0, 35, 63, 42, 0, 75, 56, 0, 0, 0,
-  0, 4, 0, 42, 63, 0, 1, 0, 44, 5,
-  9, 0, 0, 3, 0, 23, 0, 0, 26, 7,
-  0, 0, 0, 3, 4, 30, 12, 34, 0, 8,
-  0, 0, 40, 0, 0, 0, 68, 13, 0, 0,
-  40, 12, 0, 29, 32, 0, 0, 30, 0, 0,
-  0, 46, 0, 0, 0, 0, 5, 0, 0, 0,
-  0, 29, 58, 4, 0, 15, 30, 0, 26, 17,
-  54, 0, 15, 0, 9, 0, 76, 5, 0, 0,
-  10, 0, 77, 0, 9, 10, 0, 0, 4, 0,
-  0, 8, 3, 82, 0, 0, 0, 46, 42, 0,
-  45, 68, 136, 0, 0, 0, 0, 0, 0, 0,
-  3, 0, 0, 0, 0, 9, 0, 0, 0, 0,
-  33, 0, 0, 90, 40, 14, 0, 21, 0, 0,
-  0, 136, 0, 0, 74, 0, 41, 0, 36, 0,
-  0, 0, 35, 0, 125, 0, 0, 23, 0, 91,
-  0, 0, 13, 4, 0, 0, 7, 0, 0, 0,
-  15, 0, 23, 0, 45, 6, 0, 0, 20, 0,
-  0, 0, 0, 0, 24, 27, 0, 0, 0, 52,
-  15, 0, 0, 0, 14, 0, 0, 2, 0, 0,
-  69, 4, 0, 37, 12, 0, 118, 0, 23, 19,
-  24, 0, 0, 0, 53, 0, 0, 0, 0, 0,
-  45, 1, 17, 0, 0, 0, 31, 0, 0, 0,
-  20, 82, 0, 0, 0, 11, 29, 0, 23, 30,
-  25, 5, 0, 0, 20, 43, 0, 53, 0, 0,
-  0, 0, 0, 0, 0, 4, 0, 0, 0, 0,
-  0, 45, 6, 26, 0, 49, 0, 0, 0, 152,
-  0, 16, 45, 0, 12, 0, 0, 0, 0, 0,
-  8, 0, 63, 0, 0, 6, 0, 72, 0, 0,
-  8, 0, 0, 0, 0, 0, 0, 0, 13, 0,
-  1, 0, 0, 0, 0, 44, 53, 0, 44, 0,
-  0, 0, 18, 0, 36, 0, 0, 72, 23, 0,
-  15, 0, 42, 0, 1, 20, 65, 0, 81, 0,
-  0, 14, 40, 0, 141, 0, 0, 33, 89, 0,
-  30, 0, 58, 0, 0, 0, 0, 0, 77, 0,
-  0, 0, 2, 0, 0, 0, 0, 1, 29, 58,
-  0, 41, 0, 69, 29, 7, 59, 19, 117, 17,
-  0, 0, 0, 5, 0, 0, 15, 0, 0, 0,
-  0, 13, 0, 12, 0, 0, 66, 0, 0, 79,
-  32, 0, 0, 0, 0, 6, 0, 87, 7, 0,
-  39, 0, 49, 0, 7, 0, 0, 1, 10, 0,
-  77, 0, 0, 21, 0, 50, 0, 0, 2, 19,
-  0, 7, 0, 0, 0, 0, 19, 0, 2, 0,
-  62, 8, 0, 0, 25, 0, 0, 13, 0, 0,
-  16, 30, 0, 0, 0, 54, 3, 0, 0, 0,
-  20, 0, 0, 0, 0, 0, 62, 11, 0, 38,
-  13, 0, 89, 23, 44, 14, 34, 0, 0, 0,
-  57, 0, 15, 0, 25, 0, 64, 0, 17, 12,
-  0, 0, 23, 0, 0, 6, 16, 72, 0, 0,
-  0, 19, 42, 0, 48, 60, 61, 0, 0, 0,
-  0, 26, 0, 41, 0, 0, 0, 0, 0, 3,
-  0, 6, 0, 0, 0, 0, 0, 69, 18, 17,
-  0, 65, 0, 0, 0, 167, 0, 0, 66, 0,
-  29, 0, 4, 0, 0, 0, 24, 0, 113, 0,
-  0, 10, 0, 64, 0, 4, 0, 0, 0, 0,
-  0, 0, 0, 0, 12, 0, 12, 0, 32, 1,
-  0, 15, 43, 0, 26, 0, 0, 0, 27, 0,
-  11, 0, 0, 71, 39, 0, 0, 0, 13, 0,
-  0, 24, 30, 0, 73, 0, 0, 44, 14, 0,
-  155, 0, 5, 26, 74, 0, 0, 0, 54, 0,
-  0, 0, 0, 0, 0, 0, 12, 0, 0, 14,
-  34, 15, 0, 0, 26, 34, 0, 0, 0, 21,
-  29, 0, 8, 0, 0, 45, 0, 0, 48, 64,
-  6, 83, 0, 0, 55, 0, 0, 0, 0, 1,
-  0, 5, 0, 0, 0, 16, 10, 46, 0, 58,
-  0, 8, 7, 104, 37, 30, 33, 0, 15, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 6, 0,
-  0, 19, 0, 0, 21, 0, 0, 63, 0, 0,
-  0, 9, 39, 0, 0, 13, 0, 0, 0, 59,
-  43, 21, 114, 3, 0, 0, 28, 0, 36, 0,
-  0, 91, 40, 0, 32, 0, 7, 0, 28, 8,
-  75, 20, 37, 0, 0, 8, 5, 0, 131, 0,
-  0, 37, 103, 0, 101, 0, 70, 0, 0, 0,
-  5, 0, 69, 0, 12, 8, 0, 0, 19, 0,
-  0, 0, 40, 75, 0, 7, 0, 50, 40, 0,
-  68, 50, 83, 1, 0, 0, 0, 31, 0, 3,
-  20, 0, 0, 0, 0, 5, 0, 22, 0, 0,
-  22, 4, 0, 91, 26, 21, 0, 48, 0, 0,
-  1, 153, 0, 0, 66, 0, 33, 0, 18, 0,
-  0, 0, 11, 0, 112, 0, 0, 0, 0, 59,
-  0, 0, 0, 7, 0, 0, 0, 0, 0, 0,
-  9, 0, 15, 0, 36, 8, 0, 0, 45, 0,
-  0, 0, 0, 0, 6, 8, 0, 0, 1, 53,
-  30, 0, 0, 0, 16, 0, 0, 5, 5, 0,
-  72, 5, 0, 42, 10, 0, 150, 0, 30, 25,
-  71, 0, 0, 0, 50, 0, 12, 0, 0, 0,
-  9, 0, 23, 7, 0, 0, 42, 0, 0, 0,
-  8, 47, 0, 0, 0, 0, 32, 0, 34, 11,
-  0, 18, 0, 0, 19, 48, 0, 74, 0, 0,
-  9, 0, 0, 0, 0, 14, 0, 0, 0, 0,
-  0, 37, 0, 40, 0, 86, 0, 0, 8, 140,
-  13, 21, 34, 0, 22, 0, 0, 0, 0, 0,
-  0, 0, 51, 0, 0, 0, 0, 14, 0, 9,
-  0, 0, 0, 24, 0, 0, 0, 11, 28, 0,
-  0, 0, 0, 0, 0, 47, 50, 10, 57, 0,
-  0, 0, 10, 0, 28, 0, 0, 84, 46, 0,
-  26, 0, 7, 0, 21, 14, 59, 0, 50, 0,
-  0, 36, 7, 0, 152, 0, 0, 31, 100, 6,
-  74, 0, 41, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 24, 26, 15, 20, 0, 5, 0, 0,
-  4, 23, 15, 29, 19, 5, 0, 0, 0, 56,
-  21, 39, 37, 55, 0, 52, 0, 0, 82, 0,
-  11, 0, 0, 14, 0, 19, 0, 6, 0, 1,
-  10, 45, 30, 46, 0, 40, 24, 27, 55, 43,
-  0, 0, 9, 0, 0, 42, 0, 0, 0, 0,
-  0, 0, 32, 0, 0, 0, 0, 2, 11, 0,
-  20, 67, 0, 0, 0, 27, 69, 0, 0, 21,
-  0, 0, 2, 43, 16, 39, 82, 7, 0, 0,
-  15, 0, 21, 0, 0, 53, 8, 0, 42, 0,
-  0, 0, 48, 0, 67, 45, 15, 0, 2, 4,
-  0, 0, 73, 0, 0, 11, 69, 15, 131, 0,
-  65, 0, 0, 0, 10, 0, 77, 0, 9, 10,
-  0, 0, 4, 0, 0, 8, 3, 82, 0, 0,
-  0, 46, 42, 0, 45, 68, 136, 0, 0, 0,
-  0, 0, 0, 0, 3, 0, 0, 0, 0, 9,
-  0, 0, 0, 0, 33, 0, 0, 90, 40, 14,
-  0, 21, 0, 0, 0, 136, 0, 0, 74, 0,
-  41, 0, 36, 0, 0, 0, 35, 0, 125, 0,
-  0, 23, 0, 91, 0, 0, 13, 4, 0, 0,
-  7, 0, 0, 0, 15, 0, 23, 0, 45, 6,
-  0, 0, 20, 0, 0, 0, 0, 0, 24, 27,
-  0, 0, 0, 52, 15, 0, 0, 0, 14, 0,
-  0, 2, 0, 0, 69, 4, 0, 37, 12, 0,
-  118, 0, 23, 19, 24, 0, 0, 0, 53, 0,
-  0, 0, 0, 0, 45, 1, 17, 0, 0, 0,
-  31, 0, 0, 0, 20, 82, 0, 0, 0, 11,
-  29, 0, 23, 30, 25, 5, 0, 0, 20, 43,
-  0, 53, 0, 0, 0, 0, 0, 0, 0, 4,
-  0, 0, 0, 0, 0, 45, 6, 26, 0, 49,
-  0, 0, 0, 152, 0, 16, 45, 0, 12, 0,
-  0, 0, 0, 0, 8, 0, 63, 0, 0, 6,
-  0, 72, 0, 0, 8, 0, 0, 0, 0, 0,
-  0, 0, 13, 0, 1, 0, 0, 0, 0, 44,
-  53, 0, 44, 0, 0, 0, 18, 0, 36, 0,
-  0, 72, 23, 0, 15, 0, 42, 0, 1, 20,
-  65, 0, 81, 0, 0, 14, 40, 0, 141, 0,
-  0, 33, 89, 0, 30, 0, 58, 0, 0, 0,
-  0, 0, 24, 23, 0, 0, 18, 24, 50, 29,
-  0, 0, 0, 30, 0, 5, 4, 7, 13, 0,
-  0, 0, 0, 53, 0, 0, 74, 59, 173, 47,
-  0, 0, 71, 0, 19, 0, 0, 20, 0, 24,
-  0, 0, 0, 0, 18, 88, 16, 0, 0, 16,
-  0, 67, 30, 34, 32, 0, 0, 4, 0, 6,
-  0, 39, 0, 0, 0, 0, 33, 0, 0, 14,
-  6, 12, 56, 3, 0, 51, 0, 0, 0, 3,
-  39, 0, 0, 33, 0, 0, 0, 48, 80, 41,
-  84, 0, 0, 0, 23, 0, 51, 0, 2, 59,
-  14, 2, 58, 0, 66, 2, 56, 3, 77, 5,
-  38, 0, 11, 0, 0, 0, 103, 0, 0, 17,
-  53, 0, 50, 0, 60, 0, 7, 11, 25, 0,
-  64, 0, 17, 12, 0, 0, 23, 0, 0, 6,
-  16, 72, 0, 0, 0, 19, 42, 0, 48, 60,
-  61, 0, 0, 0, 0, 26, 0, 41, 0, 0,
-  0, 0, 0, 3, 0, 6, 0, 0, 0, 0,
-  0, 69, 18, 17, 0, 65, 0, 0, 0, 167,
-  0, 0, 66, 0, 29, 0, 4, 0, 0, 0,
-  24, 0, 113, 0, 0, 10, 0, 64, 0, 4,
-  0, 0, 0, 0, 0, 0, 0, 0, 12, 0,
-  12, 0, 32, 1, 0, 15, 43, 0, 26, 0,
-  0, 0, 27, 0, 11, 0, 0, 71, 39, 0,
-  0, 0, 13, 0, 0, 24, 30, 0, 73, 0,
-  0, 44, 14, 0, 155, 0, 5, 26, 74, 0,
-  0, 0, 54, 0, 0, 0, 0, 0, 0, 0,
-  12, 0, 0, 14, 34, 15, 0, 0, 26, 34,
-  0, 0, 0, 21, 29, 0, 8, 0, 0, 45,
-  0, 0, 48, 64, 6, 83, 0, 0, 55, 0,
-  0, 0, 0, 1, 0, 5, 0, 0, 0, 16,
-  10, 46, 0, 58, 0, 8, 7, 104, 37, 30,
-  33, 0, 15, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 6, 0, 0, 19, 0, 0, 21, 0,
-  0, 63, 0, 0, 0, 9, 39, 0, 0, 13,
-  0, 0, 0, 59, 43, 21, 114, 3, 0, 0,
-  28, 0, 36, 0, 0, 91, 40, 0, 32, 0,
-  7, 0, 28, 8, 75, 20, 37, 0, 0, 8,
-  5, 0, 131, 0, 0, 37, 103, 0, 101, 0,
-  70, 0, 0, 0, 0, 6, 23, 5, 0, 0,
-  44, 22, 34, 36, 0, 0, 1, 0, 0, 41,
-  20, 23, 3, 8, 0, 0, 0, 69, 18, 19,
-  51, 49, 164, 7, 0, 0, 85, 0, 15, 0,
-  0, 31, 6, 63, 0, 3, 29, 0, 23, 56,
-  20, 0, 0, 47, 0, 43, 48, 47, 7, 0,
-  0, 20, 0, 28, 0, 23, 0, 0, 0, 3,
-  58, 0, 2, 0, 18, 22, 54, 25, 23, 58,
-  0, 0, 0, 13, 76, 0, 7, 17, 0, 0,
-  4, 37, 62, 48, 83, 0, 0, 0, 8, 13,
-  24, 0, 0, 55, 0, 0, 26, 0, 38, 0,
-  56, 0, 44, 17, 29, 0, 10, 0, 0, 0,
-  37, 0, 0, 16, 21, 0, 77, 0, 71, 0,
-  5, 0, 0, 0, 9, 0, 23, 7, 0, 0,
-  42, 0, 0, 0, 8, 47, 0, 0, 0, 0,
-  32, 0, 34, 11, 0, 18, 0, 0, 19, 48,
-  0, 74, 0, 0, 9, 0, 0, 0, 0, 14,
-  0, 0, 0, 0, 0, 37, 0, 40, 0, 86,
-  0, 0, 8, 140, 13, 21, 34, 0, 22, 0,
-  0, 0, 0, 0, 0, 0, 51, 0, 0, 0,
-  0, 14, 0, 9, 0, 0, 0, 24, 0, 0,
-  0, 11, 28, 0, 0, 0, 0, 0, 0, 47,
-  50, 10, 57, 0, 0, 0, 10, 0, 28, 0,
-  0, 84, 46, 0, 26, 0, 7, 0, 21, 14,
-  59, 0, 50, 0, 0, 36, 7, 0, 152, 0,
-  0, 31, 100, 6, 74, 0, 41, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 24, 26, 15, 20,
-  0, 5, 0, 0, 4, 23, 15, 29, 19, 5,
-  0, 0, 0, 56, 21, 39, 37, 55, 0, 52,
-  0, 0, 82, 0, 11, 0, 0, 14, 0, 19,
-  0, 6, 0, 1, 10, 45, 30, 46, 0, 40,
-  24, 27, 55, 43, 0, 0, 9, 0, 0, 42,
-  0, 0, 0, 0, 0, 0, 32, 0, 0, 0,
-  0, 2, 11, 0, 20, 67, 0, 0, 0, 27,
-  69, 0, 0, 21, 0, 0, 2, 43, 16, 39,
-  82, 7, 0, 0, 15, 0, 21, 0, 0, 53,
-  8, 0, 42, 0, 0, 0, 48, 0, 67, 45,
-  15, 0, 2, 4, 0, 0, 73, 0, 0, 11,
-  69, 15, 131, 0, 65, 0, 0, 0, 0, 21,
-  39, 0, 0, 0, 39, 17, 22, 19, 5, 0,
-  0, 0, 20, 45, 30, 23, 5, 22, 0, 0,
-  0, 63, 27, 30, 38, 35, 115, 0, 0, 0,
-  74, 0, 11, 0, 0, 35, 3, 71, 0, 30,
-  31, 0, 4, 24, 50, 0, 0, 63, 18, 33,
-  32, 49, 0, 0, 0, 28, 0, 17, 6, 0,
-  0, 0, 0, 3, 73, 0, 42, 0, 0, 21,
-  39, 30, 32, 29, 0, 11, 0, 17, 87, 0,
-  23, 13, 0, 0, 7, 29, 62, 11, 41, 0,
-  0, 0, 0, 12, 26, 0, 0, 45, 0, 0,
-  5, 0, 19, 0, 45, 0, 16, 20, 23, 0,
-  12, 0, 0, 0, 0, 0, 0, 4, 0, 0,
-  66, 0, 50, 0, 0, 0, 0, 0, 45, 1,
-  17, 0, 0, 0, 31, 0, 0, 0, 20, 82,
-  0, 0, 0, 11, 29, 0, 23, 30, 25, 5,
-  0, 0, 20, 43, 0, 53, 0, 0, 0, 0,
-  0, 0, 0, 4, 0, 0, 0, 0, 0, 45,
-  6, 26, 0, 49, 0, 0, 0, 152, 0, 16,
-  45, 0, 12, 0, 0, 0, 0, 0, 8, 0,
-  63, 0, 0, 6, 0, 72, 0, 0, 8, 0,
-  0, 0, 0, 0, 0, 0, 13, 0, 1, 0,
-  0, 0, 0, 44, 53, 0, 44, 0, 0, 0,
-  18, 0, 36, 0, 0, 72, 23, 0, 15, 0,
-  42, 0, 1, 20, 65, 0, 81, 0, 0, 14,
-  40, 0, 141, 0, 0, 33, 89, 0, 30, 0,
-  58, 0, 0, 0, 0, 0, 24, 23, 0, 0,
-  18, 24, 50, 29, 0, 0, 0, 30, 0, 5,
-  4, 7, 13, 0, 0, 0, 0, 53, 0, 0,
-  74, 59, 173, 47, 0, 0, 71, 0, 19, 0,
-  0, 20, 0, 24, 0, 0, 0, 0, 18, 88,
-  16, 0, 0, 16, 0, 67, 30, 34, 32, 0,
-  0, 4, 0, 6, 0, 39, 0, 0, 0, 0,
-  33, 0, 0, 14, 6, 12, 56, 3, 0, 51,
-  0, 0, 0, 3, 39, 0, 0, 33, 0, 0,
-  0, 48, 80, 41, 84, 0, 0, 0, 23, 0,
-  51, 0, 2, 59, 14, 2, 58, 0, 66, 2,
-  56, 3, 77, 5, 38, 0, 11, 0, 0, 0,
-  103, 0, 0, 17, 53, 0, 50, 0, 60, 0,
-  7, 11, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 12, 0, 0, 14, 34, 15,
-  0, 0, 26, 34, 0, 0, 0, 21, 29, 0,
-  8, 0, 0, 45, 0, 0, 48, 64, 6, 83,
-  0, 0, 55, 0, 0, 0, 0, 1, 0, 5,
-  0, 0, 0, 16, 10, 46, 0, 58, 0, 8,
-  7, 104, 37, 30, 33, 0, 15, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 6, 0, 0, 19,
-  0, 0, 21, 0, 0, 63, 0, 0, 0, 9,
-  39, 0, 0, 13, 0, 0, 0, 59, 43, 21,
-  114, 3, 0, 0, 28, 0, 36, 0, 0, 91,
-  40, 0, 32, 0, 7, 0, 28, 8, 75, 20,
-  37, 0, 0, 8, 5, 0, 131, 0, 0, 37,
-  103, 0, 101, 0, 70, 0, 0, 0, 0, 6,
-  23, 5, 0, 0, 44, 22, 34, 36, 0, 0,
-  1, 0, 0, 41, 20, 23, 3, 8, 0, 0,
-  0, 69, 18, 19, 51, 49, 164, 7, 0, 0,
-  85, 0, 15, 0, 0, 31, 6, 63, 0, 3,
-  29, 0, 23, 56, 20, 0, 0, 47, 0, 43,
-  48, 47, 7, 0, 0, 20, 0, 28, 0, 23,
-  0, 0, 0, 3, 58, 0, 2, 0, 18, 22,
-  54, 25, 23, 58, 0, 0, 0, 13, 76, 0,
-  7, 17, 0, 0, 4, 37, 62, 48, 83, 0,
-  0, 0, 8, 13, 24, 0, 0, 55, 0, 0,
-  26, 0, 38, 0, 56, 0, 44, 17, 29, 0,
-  10, 0, 0, 0, 37, 0, 0, 16, 21, 0,
-  77, 0, 71, 0, 5, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  24, 26, 15, 20, 0, 5, 0, 0, 4, 23,
-  15, 29, 19, 5, 0, 0, 0, 56, 21, 39,
-  37, 55, 0, 52, 0, 0, 82, 0, 11, 0,
-  0, 14, 0, 19, 0, 6, 0, 1, 10, 45,
-  30, 46, 0, 40, 24, 27, 55, 43, 0, 0,
-  9, 0, 0, 42, 0, 0, 0, 0, 0, 0,
-  32, 0, 0, 0, 0, 2, 11, 0, 20, 67,
-  0, 0, 0, 27, 69, 0, 0, 21, 0, 0,
-  2, 43, 16, 39, 82, 7, 0, 0, 15, 0,
-  21, 0, 0, 53, 8, 0, 42, 0, 0, 0,
-  48, 0, 67, 45, 15, 0, 2, 4, 0, 0,
-  73, 0, 0, 11, 69, 15, 131, 0, 65, 0,
-  0, 0, 0, 21, 39, 0, 0, 0, 39, 17,
-  22, 19, 5, 0, 0, 0, 20, 45, 30, 23,
-  5, 22, 0, 0, 0, 63, 27, 30, 38, 35,
-  115, 0, 0, 0, 74, 0, 11, 0, 0, 35,
-  3, 71, 0, 30, 31, 0, 4, 24, 50, 0,
-  0, 63, 18, 33, 32, 49, 0, 0, 0, 28,
-  0, 17, 6, 0, 0, 0, 0, 3, 73, 0,
-  42, 0, 0, 21, 39, 30, 32, 29, 0, 11,
-  0, 17, 87, 0, 23, 13, 0, 0, 7, 29,
-  62, 11, 41, 0, 0, 0, 0, 12, 26, 0,
-  0, 45, 0, 0, 5, 0, 19, 0, 45, 0,
-  16, 20, 23, 0, 12, 0, 0, 0, 0, 0,
-  0, 4, 0, 0, 66, 0, 50, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 74, 43, 0,
-  0, 0, 41, 0, 0, 0, 0, 15, 3, 0,
-  14, 72, 38, 47, 0, 64, 66, 0, 81, 51,
-  0, 26, 10, 14, 118, 35, 2, 0, 62, 0,
-  42, 8, 0, 26, 7, 52, 32, 25, 0, 26,
-  85, 30, 0, 8, 0, 25, 0, 13, 61, 0,
-  0, 0, 25, 0, 4, 20, 16, 0, 7, 0,
-  0, 0, 21, 2, 0, 0, 14, 32, 32, 38,
-  42, 30, 5, 5, 0, 0, 76, 3, 4, 0,
-  0, 15, 0, 0, 64, 23, 0, 0, 7, 0,
-  8, 49, 0, 0, 22, 10, 3, 0, 1, 17,
-  39, 0, 77, 0, 0, 43, 30, 0, 0, 41,
-  0, 0, 0, 3, 0, 15, 30, 0, 0, 0,
-  22, 0, 36, 0, 4, 47, 62, 10, 0, 19,
-  11, 10, 1, 0, 0, 51, 73, 0, 0, 33,
-  47, 24, 0, 20, 69, 64, 93, 12, 0, 0,
-  0, 23, 0, 0, 0, 0, 74, 0, 23, 28,
-  0, 28, 0, 48, 1, 24, 0, 19, 53, 57,
-  0, 57, 0, 37, 0, 54, 25, 0, 42, 0,
-  29, 0, 2, 0, 1, 0, 0, 20, 15, 0,
-  0, 0, 26, 0, 13, 15, 11, 22, 32, 0,
-  46, 51, 0, 12, 44, 0, 35, 0, 0, 8,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 24,
-  31, 0, 40, 41, 11, 0, 10, 24, 51, 0,
-  57, 0, 0, 3, 17, 15, 0, 12, 0, 0,
-  7, 0, 0, 7, 15, 4, 0, 0, 47, 0,
-  18, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 79, 42, 0, 0, 0, 53, 0, 5, 0,
-  0, 37, 2, 1, 18, 62, 41, 51, 0, 55,
-  86, 0, 87, 50, 0, 11, 5, 15, 128, 37,
-  1, 0, 72, 0, 36, 0, 0, 27, 0, 45,
-  39, 32, 0, 35, 80, 55, 0, 7, 0, 21,
-  12, 25, 62, 0, 16, 0, 27, 0, 29, 0,
-  13, 0, 11, 0, 0, 0, 25, 0, 9, 0,
-  3, 35, 41, 39, 37, 34, 23, 0, 0, 8,
-  79, 22, 1, 0, 0, 13, 0, 0, 82, 36,
-  0, 0, 20, 0, 0, 51, 0, 0, 48, 11,
-  5, 0, 0, 23, 29, 0, 77, 0, 0, 50,
-  18, 0, 0, 42, 0, 0, 0, 4, 5, 13,
-  24, 0, 0, 0, 28, 0, 34, 0, 7, 54,
-  57, 12, 0, 23, 17, 14, 2, 0, 0, 54,
-  68, 12, 2, 19, 58, 30, 0, 13, 72, 61,
-  94, 10, 0, 0, 0, 26, 0, 0, 0, 5,
-  68, 0, 20, 19, 0, 31, 0, 50, 4, 41,
-  0, 19, 53, 58, 0, 66, 0, 27, 0, 55,
-  24, 0, 51, 0, 26, 0, 10, 0, 0, 0,
-  0, 18, 3, 0, 0, 0, 34, 0, 14, 26,
-  9, 11, 35, 0, 48, 32, 0, 34, 37, 0,
-  35, 0, 0, 7, 0, 0, 0, 5, 0, 0,
-  0, 0, 0, 28, 25, 0, 59, 36, 0, 0,
-  14, 23, 43, 0, 49, 0, 0, 6, 11, 5,
-  0, 11, 0, 0, 8, 0, 8, 0, 0, 4,
-  5, 0, 45, 0, 20, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 59, 38, 0, 0, 0,
-  51, 10, 0, 0, 0, 39, 16, 14, 0, 31,
-  37, 50, 8, 52, 96, 0, 89, 33, 0, 0,
-  10, 17, 130, 11, 0, 0, 60, 0, 23, 5,
-  0, 27, 0, 39, 18, 30, 0, 52, 72, 74,
-  0, 1, 0, 9, 3, 38, 49, 0, 21, 0,
-  26, 0, 35, 0, 7, 0, 20, 0, 0, 0,
-  28, 0, 11, 0, 19, 32, 48, 45, 30, 15,
-  29, 8, 0, 9, 64, 8, 4, 0, 0, 0,
-  0, 0, 71, 23, 0, 0, 12, 0, 0, 61,
-  0, 0, 46, 11, 0, 0, 7, 26, 31, 0,
-  76, 0, 0, 36, 15, 0, 0, 53, 0, 0,
-  0, 21, 21, 27, 13, 0, 0, 0, 35, 0,
-  35, 0, 5, 41, 42, 14, 0, 10, 22, 17,
-  7, 0, 0, 59, 79, 18, 12, 8, 57, 30,
-  0, 8, 80, 64, 78, 4, 4, 0, 0, 27,
-  0, 0, 0, 6, 69, 0, 21, 17, 0, 41,
-  0, 56, 0, 45, 0, 25, 49, 58, 0, 46,
-  0, 36, 0, 53, 24, 7, 45, 0, 22, 0,
-  8, 0, 0, 0, 0, 27, 0, 6, 0, 0,
-  31, 0, 5, 23, 14, 9, 30, 0, 48, 35,
-  0, 35, 39, 0, 24, 0, 2, 0, 0, 0,
-  0, 6, 0, 0, 0, 3, 0, 41, 26, 0,
-  61, 31, 0, 0, 30, 12, 49, 0, 50, 0,
-  0, 4, 7, 3, 0, 14, 0, 0, 14, 0,
-  21, 1, 1, 11, 20, 0, 59, 0, 36, 0,
-  0, 74, 43, 0, 0, 0, 41, 0, 0, 0,
-  0, 15, 3, 0, 14, 72, 38, 47, 0, 64,
-  66, 0, 81, 51, 0, 26, 10, 14, 118, 35,
-  2, 0, 62, 0, 42, 8, 0, 26, 7, 52,
-  32, 25, 0, 26, 85, 30, 0, 8, 0, 25,
-  0, 13, 61, 0, 0, 0, 25, 0, 4, 20,
-  16, 0, 7, 0, 0, 0, 21, 2, 0, 0,
-  14, 32, 32, 38, 42, 30, 5, 5, 0, 0,
-  76, 3, 4, 0, 0, 15, 0, 0, 64, 23,
-  0, 0, 7, 0, 8, 49, 0, 0, 22, 10,
-  3, 0, 1, 17, 39, 0, 77, 0, 0, 43,
-  30, 0, 0, 41, 0, 0, 0, 3, 0, 15,
-  30, 0, 0, 0, 22, 0, 36, 0, 4, 47,
-  62, 10, 0, 19, 11, 10, 1, 0, 0, 51,
-  73, 0, 0, 33, 47, 24, 0, 20, 69, 64,
-  93, 12, 0, 0, 0, 23, 0, 0, 0, 0,
-  74, 0, 23, 28, 0, 28, 0, 48, 1, 24,
-  0, 19, 53, 57, 0, 57, 0, 37, 0, 54,
-  25, 0, 42, 0, 29, 0, 2, 0, 1, 0,
-  0, 20, 15, 0, 0, 0, 26, 0, 13, 15,
-  11, 22, 32, 0, 46, 51, 0, 12, 44, 0,
-  35, 0, 0, 8, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 24, 31, 0, 40, 41, 11, 0,
-  10, 24, 51, 0, 57, 0, 0, 3, 17, 15,
-  0, 12, 0, 0, 7, 0, 0, 7, 15, 4,
-  0, 0, 47, 0, 18, 0, 3, 30, 27, 20,
-  0, 12, 23, 23, 27, 0, 0, 40, 83, 0,
-  11, 31, 57, 0, 0, 0, 0, 92, 0, 1,
-  37, 0, 0, 25, 0, 0, 0, 50, 77, 0,
-  34, 0, 0, 19, 0, 54, 0, 46, 24, 10,
-  34, 52, 12, 15, 0, 33, 0, 55, 12, 26,
-  53, 0, 30, 0, 10, 0, 0, 13, 0, 58,
-  0, 13, 0, 0, 32, 0, 13, 16, 12, 11,
-  0, 0, 49, 39, 0, 32, 30, 0, 50, 41,
-  0, 0, 7, 0, 0, 13, 0, 0, 0, 16,
-  0, 30, 52, 0, 6, 80, 2, 0, 18, 20,
-  43, 0, 29, 0, 4, 0, 21, 11, 0, 0,
-  0, 0, 0, 0, 0, 11, 4, 11, 36, 0,
-  51, 0, 18, 0, 0, 79, 42, 0, 0, 0,
-  53, 0, 5, 0, 0, 37, 2, 1, 18, 62,
-  41, 51, 0, 55, 86, 0, 87, 50, 0, 11,
-  5, 15, 128, 37, 1, 0, 72, 0, 36, 0,
-  0, 27, 0, 45, 39, 32, 0, 35, 80, 55,
-  0, 7, 0, 21, 12, 25, 62, 0, 16, 0,
-  27, 0, 29, 0, 13, 0, 11, 0, 0, 0,
-  25, 0, 9, 0, 3, 35, 41, 39, 37, 34,
-  23, 0, 0, 8, 79, 22, 1, 0, 0, 13,
-  0, 0, 82, 36, 0, 0, 20, 0, 0, 51,
-  0, 0, 48, 11, 5, 0, 0, 23, 29, 0,
-  77, 0, 0, 50, 18, 0, 0, 42, 0, 0,
-  0, 4, 5, 13, 24, 0, 0, 0, 28, 0,
-  34, 0, 7, 54, 57, 12, 0, 23, 17, 14,
-  2, 0, 0, 54, 68, 12, 2, 19, 58, 30,
-  0, 13, 72, 61, 94, 10, 0, 0, 0, 26,
-  0, 0, 0, 5, 68, 0, 20, 19, 0, 31,
-  0, 50, 4, 41, 0, 19, 53, 58, 0, 66,
-  0, 27, 0, 55, 24, 0, 51, 0, 26, 0,
-  10, 0, 0, 0, 0, 18, 3, 0, 0, 0,
-  34, 0, 14, 26, 9, 11, 35, 0, 48, 32,
-  0, 34, 37, 0, 35, 0, 0, 7, 0, 0,
-  0, 5, 0, 0, 0, 0, 0, 28, 25, 0,
-  59, 36, 0, 0, 14, 23, 43, 0, 49, 0,
-  0, 6, 11, 5, 0, 11, 0, 0, 8, 0,
-  8, 0, 0, 4, 5, 0, 45, 0, 20, 0,
-  10, 27, 29, 24, 0, 21, 22, 22, 24, 0,
-  0, 43, 79, 0, 6, 26, 56, 0, 0, 0,
-  0, 87, 1, 0, 41, 0, 0, 30, 0, 1,
-  0, 60, 72, 0, 24, 0, 0, 23, 0, 54,
-  0, 47, 13, 10, 23, 49, 26, 18, 0, 30,
-  0, 52, 4, 24, 54, 0, 32, 0, 10, 0,
-  1, 11, 0, 48, 0, 8, 0, 0, 39, 0,
-  18, 26, 11, 0, 0, 2, 47, 27, 0, 46,
-  24, 0, 46, 46, 0, 0, 13, 0, 0, 18,
-  0, 0, 0, 23, 0, 24, 55, 0, 15, 78,
-  0, 0, 25, 19, 40, 0, 26, 0, 5, 0,
-  17, 8, 0, 0, 0, 0, 7, 0, 0, 4,
-  0, 11, 36, 0, 55, 0, 17, 0, 0, 59,
-  38, 0, 0, 0, 51, 10, 0, 0, 0, 39,
-  16, 14, 0, 31, 37, 50, 8, 52, 96, 0,
-  89, 33, 0, 0, 10, 17, 130, 11, 0, 0,
-  60, 0, 23, 5, 0, 27, 0, 39, 18, 30,
-  0, 52, 72, 74, 0, 1, 0, 9, 3, 38,
-  49, 0, 21, 0, 26, 0, 35, 0, 7, 0,
-  20, 0, 0, 0, 28, 0, 11, 0, 19, 32,
-  48, 45, 30, 15, 29, 8, 0, 9, 64, 8,
-  4, 0, 0, 0, 0, 0, 71, 23, 0, 0,
-  12, 0, 0, 61, 0, 0, 46, 11, 0, 0,
-  7, 26, 31, 0, 76, 0, 0, 36, 15, 0,
-  0, 53, 0, 0, 0, 21, 21, 27, 13, 0,
-  0, 0, 35, 0, 35, 0, 5, 41, 42, 14,
-  0, 10, 22, 17, 7, 0, 0, 59, 79, 18,
-  12, 8, 57, 30, 0, 8, 80, 64, 78, 4,
-  4, 0, 0, 27, 0, 0, 0, 6, 69, 0,
-  21, 17, 0, 41, 0, 56, 0, 45, 0, 25,
-  49, 58, 0, 46, 0, 36, 0, 53, 24, 7,
-  45, 0, 22, 0, 8, 0, 0, 0, 0, 27,
-  0, 6, 0, 0, 31, 0, 5, 23, 14, 9,
-  30, 0, 48, 35, 0, 35, 39, 0, 24, 0,
-  2, 0, 0, 0, 0, 6, 0, 0, 0, 3,
-  0, 41, 26, 0, 61, 31, 0, 0, 30, 12,
-  49, 0, 50, 0, 0, 4, 7, 3, 0, 14,
-  0, 0, 14, 0, 21, 1, 1, 11, 20, 0,
-  59, 0, 36, 0, 7, 20, 30, 33, 0, 25,
-  20, 19, 31, 0, 0, 42, 85, 0, 9, 30,
-  51, 0, 0, 0, 0, 86, 1, 3, 48, 0,
-  0, 38, 0, 0, 0, 59, 74, 0, 25, 0,
-  0, 26, 0, 62, 0, 45, 16, 10, 25, 48,
-  31, 10, 0, 42, 0, 48, 3, 27, 52, 0,
-  29, 0, 9, 0, 0, 10, 0, 42, 0, 8,
-  0, 0, 37, 0, 14, 27, 13, 0, 0, 2,
-  45, 38, 0, 45, 25, 0, 49, 45, 0, 0,
-  20, 0, 0, 19, 0, 0, 0, 17, 0, 27,
-  57, 0, 16, 73, 0, 0, 26, 12, 40, 0,
-  28, 0, 0, 0, 14, 3, 0, 0, 0, 0,
-  11, 0, 0, 9, 2, 6, 37, 0, 65, 0,
-  15, 0, 4, 47, 62, 10, 0, 19, 11, 10,
-  1, 0, 0, 51, 73, 0, 0, 33, 47, 24,
-  0, 20, 69, 64, 93, 12, 0, 0, 0, 23,
-  0, 0, 0, 0, 74, 0, 23, 28, 0, 28,
-  0, 48, 1, 24, 0, 19, 53, 57, 0, 57,
-  0, 37, 0, 54, 25, 0, 42, 0, 29, 0,
-  2, 0, 1, 0, 0, 20, 15, 0, 0, 0,
-  26, 0, 13, 15, 11, 22, 32, 0, 46, 51,
-  0, 12, 44, 0, 35, 0, 0, 8, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 24, 31, 0,
-  40, 41, 11, 0, 10, 24, 51, 0, 57, 0,
-  0, 3, 17, 15, 0, 12, 0, 0, 7, 0,
-  0, 7, 15, 4, 0, 0, 47, 0, 18, 0,
-  3, 30, 27, 20, 0, 12, 23, 23, 27, 0,
-  0, 40, 83, 0, 11, 31, 57, 0, 0, 0,
-  0, 92, 0, 1, 37, 0, 0, 25, 0, 0,
-  0, 50, 77, 0, 34, 0, 0, 19, 0, 54,
-  0, 46, 24, 10, 34, 52, 12, 15, 0, 33,
-  0, 55, 12, 26, 53, 0, 30, 0, 10, 0,
-  0, 13, 0, 58, 0, 13, 0, 0, 32, 0,
-  13, 16, 12, 11, 0, 0, 49, 39, 0, 32,
-  30, 0, 50, 41, 0, 0, 7, 0, 0, 13,
-  0, 0, 0, 16, 0, 30, 52, 0, 6, 80,
-  2, 0, 18, 20, 43, 0, 29, 0, 4, 0,
-  21, 11, 0, 0, 0, 0, 0, 0, 0, 11,
-  4, 11, 36, 0, 51, 0, 18, 0, 0, 0,
-  0, 5, 0, 140, 8, 5, 3, 0, 0, 23,
-  36, 0, 0, 10, 2, 0, 0, 0, 35, 102,
-  17, 9, 0, 0, 0, 0, 0, 21, 0, 23,
-  35, 21, 4, 1, 0, 25, 0, 41, 0, 16,
-  0, 48, 13, 84, 13, 57, 0, 3, 0, 61,
-  0, 0, 24, 0, 45, 0, 39, 0, 0, 51,
-  0, 0, 78, 3, 0, 20, 24, 0, 67, 6,
-  31, 2, 0, 19, 16, 27, 0, 18, 39, 0,
-  33, 59, 0, 0, 10, 0, 0, 0, 0, 8,
-  0, 0, 12, 34, 0, 0, 0, 66, 43, 0,
-  0, 31, 31, 0, 26, 0, 0, 0, 14, 0,
-  0, 24, 0, 0, 117, 2, 21, 20, 0, 0,
-  0, 0, 24, 0, 0, 0, 7, 54, 57, 12,
-  0, 23, 17, 14, 2, 0, 0, 54, 68, 12,
-  2, 19, 58, 30, 0, 13, 72, 61, 94, 10,
-  0, 0, 0, 26, 0, 0, 0, 5, 68, 0,
-  20, 19, 0, 31, 0, 50, 4, 41, 0, 19,
-  53, 58, 0, 66, 0, 27, 0, 55, 24, 0,
-  51, 0, 26, 0, 10, 0, 0, 0, 0, 18,
-  3, 0, 0, 0, 34, 0, 14, 26, 9, 11,
-  35, 0, 48, 32, 0, 34, 37, 0, 35, 0,
-  0, 7, 0, 0, 0, 5, 0, 0, 0, 0,
-  0, 28, 25, 0, 59, 36, 0, 0, 14, 23,
-  43, 0, 49, 0, 0, 6, 11, 5, 0, 11,
-  0, 0, 8, 0, 8, 0, 0, 4, 5, 0,
-  45, 0, 20, 0, 10, 27, 29, 24, 0, 21,
-  22, 22, 24, 0, 0, 43, 79, 0, 6, 26,
-  56, 0, 0, 0, 0, 87, 1, 0, 41, 0,
-  0, 30, 0, 1, 0, 60, 72, 0, 24, 0,
-  0, 23, 0, 54, 0, 47, 13, 10, 23, 49,
-  26, 18, 0, 30, 0, 52, 4, 24, 54, 0,
-  32, 0, 10, 0, 1, 11, 0, 48, 0, 8,
-  0, 0, 39, 0, 18, 26, 11, 0, 0, 2,
-  47, 27, 0, 46, 24, 0, 46, 46, 0, 0,
-  13, 0, 0, 18, 0, 0, 0, 23, 0, 24,
-  55, 0, 15, 78, 0, 0, 25, 19, 40, 0,
-  26, 0, 5, 0, 17, 8, 0, 0, 0, 0,
-  7, 0, 0, 4, 0, 11, 36, 0, 55, 0,
-  17, 0, 0, 0, 0, 7, 0, 153, 0, 0,
-  0, 0, 0, 29, 38, 0, 0, 1, 3, 0,
-  0, 0, 24, 93, 13, 16, 0, 0, 0, 0,
-  0, 19, 0, 24, 31, 29, 0, 8, 0, 29,
-  0, 45, 0, 25, 0, 49, 3, 74, 23, 63,
-  0, 7, 0, 55, 0, 0, 19, 0, 43, 0,
-  36, 0, 0, 49, 0, 0, 76, 0, 0, 27,
-  37, 0, 74, 15, 23, 0, 0, 20, 11, 20,
-  0, 34, 35, 0, 40, 53, 0, 0, 16, 0,
-  0, 0, 0, 13, 0, 0, 26, 27, 0, 0,
-  0, 73, 26, 0, 0, 26, 12, 0, 22, 0,
-  0, 0, 6, 0, 0, 16, 0, 0, 114, 0,
-  19, 9, 0, 0, 0, 0, 29, 0, 0, 0,
-  5, 41, 42, 14, 0, 10, 22, 17, 7, 0,
-  0, 59, 79, 18, 12, 8, 57, 30, 0, 8,
-  80, 64, 78, 4, 4, 0, 0, 27, 0, 0,
-  0, 6, 69, 0, 21, 17, 0, 41, 0, 56,
-  0, 45, 0, 25, 49, 58, 0, 46, 0, 36,
-  0, 53, 24, 7, 45, 0, 22, 0, 8, 0,
-  0, 0, 0, 27, 0, 6, 0, 0, 31, 0,
-  5, 23, 14, 9, 30, 0, 48, 35, 0, 35,
-  39, 0, 24, 0, 2, 0, 0, 0, 0, 6,
-  0, 0, 0, 3, 0, 41, 26, 0, 61, 31,
-  0, 0, 30, 12, 49, 0, 50, 0, 0, 4,
-  7, 3, 0, 14, 0, 0, 14, 0, 21, 1,
-  1, 11, 20, 0, 59, 0, 36, 0, 7, 20,
-  30, 33, 0, 25, 20, 19, 31, 0, 0, 42,
-  85, 0, 9, 30, 51, 0, 0, 0, 0, 86,
-  1, 3, 48, 0, 0, 38, 0, 0, 0, 59,
-  74, 0, 25, 0, 0, 26, 0, 62, 0, 45,
-  16, 10, 25, 48, 31, 10, 0, 42, 0, 48,
-  3, 27, 52, 0, 29, 0, 9, 0, 0, 10,
-  0, 42, 0, 8, 0, 0, 37, 0, 14, 27,
-  13, 0, 0, 2, 45, 38, 0, 45, 25, 0,
-  49, 45, 0, 0, 20, 0, 0, 19, 0, 0,
-  0, 17, 0, 27, 57, 0, 16, 73, 0, 0,
-  26, 12, 40, 0, 28, 0, 0, 0, 14, 3,
-  0, 0, 0, 0, 11, 0, 0, 9, 2, 6,
-  37, 0, 65, 0, 15, 0, 0, 0, 0, 14,
-  0, 156, 0, 0, 5, 0, 0, 33, 46, 0,
-  0, 1, 2, 0, 0, 0, 35, 87, 15, 22,
-  9, 0, 0, 0, 0, 4, 0, 26, 27, 34,
-  0, 10, 0, 25, 0, 45, 0, 20, 0, 52,
-  5, 80, 36, 57, 0, 13, 0, 53, 0, 0,
-  18, 0, 38, 0, 42, 0, 0, 46, 0, 0,
-  78, 0, 0, 21, 42, 0, 77, 17, 26, 0,
-  0, 15, 17, 17, 0, 33, 33, 0, 40, 55,
-  0, 0, 30, 0, 0, 0, 0, 21, 0, 0,
-  19, 31, 0, 0, 3, 65, 28, 0, 0, 21,
-  9, 0, 22, 0, 0, 0, 0, 0, 0, 12,
-  0, 0, 106, 0, 25, 11, 0, 0, 0, 0,
-  36, 0, 0, 0, 3, 30, 27, 20, 0, 12,
-  23, 23, 27, 0, 0, 40, 83, 0, 11, 31,
-  57, 0, 0, 0, 0, 92, 0, 1, 37, 0,
-  0, 25, 0, 0, 0, 50, 77, 0, 34, 0,
-  0, 19, 0, 54, 0, 46, 24, 10, 34, 52,
-  12, 15, 0, 33, 0, 55, 12, 26, 53, 0,
-  30, 0, 10, 0, 0, 13, 0, 58, 0, 13,
-  0, 0, 32, 0, 13, 16, 12, 11, 0, 0,
-  49, 39, 0, 32, 30, 0, 50, 41, 0, 0,
-  7, 0, 0, 13, 0, 0, 0, 16, 0, 30,
-  52, 0, 6, 80, 2, 0, 18, 20, 43, 0,
-  29, 0, 4, 0, 21, 11, 0, 0, 0, 0,
-  0, 0, 0, 11, 4, 11, 36, 0, 51, 0,
-  18, 0, 0, 0, 0, 5, 0, 140, 8, 5,
-  3, 0, 0, 23, 36, 0, 0, 10, 2, 0,
-  0, 0, 35, 102, 17, 9, 0, 0, 0, 0,
-  0, 21, 0, 23, 35, 21, 4, 1, 0, 25,
-  0, 41, 0, 16, 0, 48, 13, 84, 13, 57,
-  0, 3, 0, 61, 0, 0, 24, 0, 45, 0,
-  39, 0, 0, 51, 0, 0, 78, 3, 0, 20,
-  24, 0, 67, 6, 31, 2, 0, 19, 16, 27,
-  0, 18, 39, 0, 33, 59, 0, 0, 10, 0,
-  0, 0, 0, 8, 0, 0, 12, 34, 0, 0,
-  0, 66, 43, 0, 0, 31, 31, 0, 26, 0,
-  0, 0, 14, 0, 0, 24, 0, 0, 117, 2,
-  21, 20, 0, 0, 0, 0, 24, 0, 0, 0,
-  0, 8, 0, 0, 0, 26, 43, 6, 20, 0,
-  13, 0, 59, 0, 10, 62, 36, 31, 3, 0,
-  46, 0, 0, 38, 0, 42, 6, 2, 0, 34,
-  0, 0, 63, 41, 15, 0, 0, 0, 0, 46,
-  0, 37, 0, 53, 25, 14, 17, 17, 0, 32,
-  15, 5, 91, 14, 0, 0, 28, 0, 0, 70,
-  0, 0, 0, 0, 0, 0, 24, 8, 0, 0,
-  0, 2, 0, 9, 17, 48, 0, 3, 0, 31,
-  71, 5, 13, 36, 17, 0, 4, 23, 26, 35,
-  36, 0, 0, 2, 17, 32, 0, 0, 2, 44,
-  36, 0, 0, 0, 12, 0, 55, 13, 24, 46,
-  43, 0, 0, 24, 0, 0, 42, 41, 44, 0,
-  0, 0, 108, 0, 71, 14, 0, 0, 10, 27,
-  29, 24, 0, 21, 22, 22, 24, 0, 0, 43,
-  79, 0, 6, 26, 56, 0, 0, 0, 0, 87,
-  1, 0, 41, 0, 0, 30, 0, 1, 0, 60,
-  72, 0, 24, 0, 0, 23, 0, 54, 0, 47,
-  13, 10, 23, 49, 26, 18, 0, 30, 0, 52,
-  4, 24, 54, 0, 32, 0, 10, 0, 1, 11,
-  0, 48, 0, 8, 0, 0, 39, 0, 18, 26,
-  11, 0, 0, 2, 47, 27, 0, 46, 24, 0,
-  46, 46, 0, 0, 13, 0, 0, 18, 0, 0,
-  0, 23, 0, 24, 55, 0, 15, 78, 0, 0,
-  25, 19, 40, 0, 26, 0, 5, 0, 17, 8,
-  0, 0, 0, 0, 7, 0, 0, 4, 0, 11,
-  36, 0, 55, 0, 17, 0, 0, 0, 0, 7,
-  0, 153, 0, 0, 0, 0, 0, 29, 38, 0,
-  0, 1, 3, 0, 0, 0, 24, 93, 13, 16,
-  0, 0, 0, 0, 0, 19, 0, 24, 31, 29,
-  0, 8, 0, 29, 0, 45, 0, 25, 0, 49,
-  3, 74, 23, 63, 0, 7, 0, 55, 0, 0,
-  19, 0, 43, 0, 36, 0, 0, 49, 0, 0,
-  76, 0, 0, 27, 37, 0, 74, 15, 23, 0,
-  0, 20, 11, 20, 0, 34, 35, 0, 40, 53,
-  0, 0, 16, 0, 0, 0, 0, 13, 0, 0,
-  26, 27, 0, 0, 0, 73, 26, 0, 0, 26,
-  12, 0, 22, 0, 0, 0, 6, 0, 0, 16,
-  0, 0, 114, 0, 19, 9, 0, 0, 0, 0,
-  29, 0, 0, 0, 0, 17, 0, 0, 0, 31,
-  35, 0, 13, 0, 8, 0, 56, 4, 16, 62,
-  36, 39, 10, 0, 30, 0, 0, 48, 4, 53,
-  0, 4, 0, 15, 0, 0, 72, 44, 0, 0,
-  0, 0, 0, 66, 0, 41, 0, 43, 20, 12,
-  12, 36, 0, 41, 0, 7, 95, 16, 0, 0,
-  21, 0, 0, 55, 9, 0, 0, 0, 0, 0,
-  32, 12, 11, 0, 0, 0, 0, 15, 10, 55,
-  0, 0, 0, 47, 64, 4, 32, 22, 15, 0,
-  7, 27, 13, 34, 54, 16, 0, 11, 39, 32,
-  0, 0, 0, 68, 22, 0, 0, 0, 0, 0,
-  48, 0, 0, 30, 26, 15, 0, 27, 0, 0,
-  25, 30, 24, 3, 1, 0, 121, 0, 65, 2,
-  0, 0, 7, 20, 30, 33, 0, 25, 20, 19,
-  31, 0, 0, 42, 85, 0, 9, 30, 51, 0,
-  0, 0, 0, 86, 1, 3, 48, 0, 0, 38,
-  0, 0, 0, 59, 74, 0, 25, 0, 0, 26,
-  0, 62, 0, 45, 16, 10, 25, 48, 31, 10,
-  0, 42, 0, 48, 3, 27, 52, 0, 29, 0,
-  9, 0, 0, 10, 0, 42, 0, 8, 0, 0,
-  37, 0, 14, 27, 13, 0, 0, 2, 45, 38,
-  0, 45, 25, 0, 49, 45, 0, 0, 20, 0,
-  0, 19, 0, 0, 0, 17, 0, 27, 57, 0,
-  16, 73, 0, 0, 26, 12, 40, 0, 28, 0,
-  0, 0, 14, 3, 0, 0, 0, 0, 11, 0,
-  0, 9, 2, 6, 37, 0, 65, 0, 15, 0,
-  0, 0, 0, 14, 0, 156, 0, 0, 5, 0,
-  0, 33, 46, 0, 0, 1, 2, 0, 0, 0,
-  35, 87, 15, 22, 9, 0, 0, 0, 0, 4,
-  0, 26, 27, 34, 0, 10, 0, 25, 0, 45,
-  0, 20, 0, 52, 5, 80, 36, 57, 0, 13,
-  0, 53, 0, 0, 18, 0, 38, 0, 42, 0,
-  0, 46, 0, 0, 78, 0, 0, 21, 42, 0,
-  77, 17, 26, 0, 0, 15, 17, 17, 0, 33,
-  33, 0, 40, 55, 0, 0, 30, 0, 0, 0,
-  0, 21, 0, 0, 19, 31, 0, 0, 3, 65,
-  28, 0, 0, 21, 9, 0, 22, 0, 0, 0,
-  0, 0, 0, 12, 0, 0, 106, 0, 25, 11,
-  0, 0, 0, 0, 36, 0, 0, 0, 0, 20,
-  0, 0, 0, 35, 28, 0, 25, 0, 6, 0,
-  68, 1, 9, 53, 37, 38, 8, 0, 43, 0,
-  0, 43, 7, 56, 0, 4, 0, 13, 10, 0,
-  65, 53, 0, 0, 0, 0, 0, 56, 0, 63,
-  0, 42, 23, 10, 1, 49, 0, 48, 0, 7,
-  80, 24, 0, 0, 14, 0, 0, 62, 18, 0,
-  0, 0, 0, 0, 30, 19, 15, 0, 0, 0,
-  0, 17, 1, 53, 0, 0, 0, 49, 63, 0,
-  24, 24, 20, 0, 11, 25, 0, 37, 36, 32,
-  0, 13, 32, 35, 0, 0, 0, 66, 17, 0,
-  0, 0, 0, 0, 37, 0, 0, 36, 37, 19,
-  0, 29, 0, 0, 14, 20, 42, 8, 3, 0,
-  121, 0, 63, 0, 10, 0, 0, 0, 0, 5,
-  0, 140, 8, 5, 3, 0, 0, 23, 36, 0,
-  0, 10, 2, 0, 0, 0, 35, 102, 17, 9,
-  0, 0, 0, 0, 0, 21, 0, 23, 35, 21,
-  4, 1, 0, 25, 0, 41, 0, 16, 0, 48,
-  13, 84, 13, 57, 0, 3, 0, 61, 0, 0,
-  24, 0, 45, 0, 39, 0, 0, 51, 0, 0,
-  78, 3, 0, 20, 24, 0, 67, 6, 31, 2,
-  0, 19, 16, 27, 0, 18, 39, 0, 33, 59,
-  0, 0, 10, 0, 0, 0, 0, 8, 0, 0,
-  12, 34, 0, 0, 0, 66, 43, 0, 0, 31,
-  31, 0, 26, 0, 0, 0, 14, 0, 0, 24,
-  0, 0, 117, 2, 21, 20, 0, 0, 0, 0,
-  24, 0, 0, 0, 0, 8, 0, 0, 0, 26,
-  43, 6, 20, 0, 13, 0, 59, 0, 10, 62,
-  36, 31, 3, 0, 46, 0, 0, 38, 0, 42,
-  6, 2, 0, 34, 0, 0, 63, 41, 15, 0,
-  0, 0, 0, 46, 0, 37, 0, 53, 25, 14,
-  17, 17, 0, 32, 15, 5, 91, 14, 0, 0,
-  28, 0, 0, 70, 0, 0, 0, 0, 0, 0,
-  24, 8, 0, 0, 0, 2, 0, 9, 17, 48,
-  0, 3, 0, 31, 71, 5, 13, 36, 17, 0,
-  4, 23, 26, 35, 36, 0, 0, 2, 17, 32,
-  0, 0, 2, 44, 36, 0, 0, 0, 12, 0,
-  55, 13, 24, 46, 43, 0, 0, 24, 0, 0,
-  42, 41, 44, 0, 0, 0, 108, 0, 71, 14,
-  0, 0, 0, 44, 70, 0, 0, 0, 0, 9,
-  53, 0, 0, 29, 11, 20, 0, 36, 26, 0,
-  0, 0, 0, 7, 73, 51, 0, 0, 16, 18,
-  0, 0, 0, 0, 0, 0, 29, 22, 0, 0,
-  0, 40, 0, 13, 0, 10, 0, 1, 22, 0,
-  0, 0, 35, 32, 22, 15, 0, 0, 28, 0,
-  0, 0, 0, 0, 0, 0, 20, 0, 30, 0,
-  2, 0, 0, 8, 3, 20, 33, 0, 0, 85,
-  0, 28, 19, 0, 42, 48, 0, 18, 0, 36,
-  33, 9, 46, 0, 0, 0, 8, 0, 0, 0,
-  0, 81, 37, 0, 0, 0, 25, 0, 70, 0,
-  22, 26, 14, 0, 0, 8, 0, 0, 28, 0,
-  0, 18, 0, 0, 19, 0, 44, 20, 0, 20,
-  0, 0, 0, 7, 0, 153, 0, 0, 0, 0,
-  0, 29, 38, 0, 0, 1, 3, 0, 0, 0,
-  24, 93, 13, 16, 0, 0, 0, 0, 0, 19,
-  0, 24, 31, 29, 0, 8, 0, 29, 0, 45,
-  0, 25, 0, 49, 3, 74, 23, 63, 0, 7,
-  0, 55, 0, 0, 19, 0, 43, 0, 36, 0,
-  0, 49, 0, 0, 76, 0, 0, 27, 37, 0,
-  74, 15, 23, 0, 0, 20, 11, 20, 0, 34,
-  35, 0, 40, 53, 0, 0, 16, 0, 0, 0,
-  0, 13, 0, 0, 26, 27, 0, 0, 0, 73,
-  26, 0, 0, 26, 12, 0, 22, 0, 0, 0,
-  6, 0, 0, 16, 0, 0, 114, 0, 19, 9,
-  0, 0, 0, 0, 29, 0, 0, 0, 0, 17,
-  0, 0, 0, 31, 35, 0, 13, 0, 8, 0,
-  56, 4, 16, 62, 36, 39, 10, 0, 30, 0,
-  0, 48, 4, 53, 0, 4, 0, 15, 0, 0,
-  72, 44, 0, 0, 0, 0, 0, 66, 0, 41,
-  0, 43, 20, 12, 12, 36, 0, 41, 0, 7,
-  95, 16, 0, 0, 21, 0, 0, 55, 9, 0,
-  0, 0, 0, 0, 32, 12, 11, 0, 0, 0,
-  0, 15, 10, 55, 0, 0, 0, 47, 64, 4,
-  32, 22, 15, 0, 7, 27, 13, 34, 54, 16,
-  0, 11, 39, 32, 0, 0, 0, 68, 22, 0,
-  0, 0, 0, 0, 48, 0, 0, 30, 26, 15,
-  0, 27, 0, 0, 25, 30, 24, 3, 1, 0,
-  121, 0, 65, 2, 0, 0, 0, 31, 59, 0,
-  8, 0, 0, 0, 53, 2, 0, 9, 30, 0,
-  0, 23, 15, 0, 8, 0, 0, 47, 79, 53,
-  0, 0, 0, 15, 0, 0, 0, 0, 0, 0,
-  52, 28, 0, 4, 0, 63, 0, 25, 0, 1,
-  0, 0, 25, 4, 0, 6, 0, 48, 20, 26,
-  0, 0, 19, 0, 8, 0, 0, 13, 0, 0,
-  18, 0, 16, 0, 9, 0, 10, 19, 20, 21,
-  21, 5, 0, 89, 0, 46, 12, 0, 50, 44,
-  4, 2, 0, 39, 7, 1, 49, 0, 0, 0,
-  4, 0, 0, 0, 6, 91, 22, 0, 0, 0,
-  9, 0, 71, 0, 0, 9, 0, 0, 0, 14,
-  0, 0, 23, 0, 0, 33, 0, 0, 26, 0,
-  73, 2, 0, 1, 0, 0, 0, 14, 0, 156,
-  0, 0, 5, 0, 0, 33, 46, 0, 0, 1,
-  2, 0, 0, 0, 35, 87, 15, 22, 9, 0,
-  0, 0, 0, 4, 0, 26, 27, 34, 0, 10,
-  0, 25, 0, 45, 0, 20, 0, 52, 5, 80,
-  36, 57, 0, 13, 0, 53, 0, 0, 18, 0,
-  38, 0, 42, 0, 0, 46, 0, 0, 78, 0,
-  0, 21, 42, 0, 77, 17, 26, 0, 0, 15,
-  17, 17, 0, 33, 33, 0, 40, 55, 0, 0,
-  30, 0, 0, 0, 0, 21, 0, 0, 19, 31,
-  0, 0, 3, 65, 28, 0, 0, 21, 9, 0,
-  22, 0, 0, 0, 0, 0, 0, 12, 0, 0,
-  106, 0, 25, 11, 0, 0, 0, 0, 36, 0,
-  0, 0, 0, 20, 0, 0, 0, 35, 28, 0,
-  25, 0, 6, 0, 68, 1, 9, 53, 37, 38,
-  8, 0, 43, 0, 0, 43, 7, 56, 0, 4,
-  0, 13, 10, 0, 65, 53, 0, 0, 0, 0,
-  0, 56, 0, 63, 0, 42, 23, 10, 1, 49,
-  0, 48, 0, 7, 80, 24, 0, 0, 14, 0,
-  0, 62, 18, 0, 0, 0, 0, 0, 30, 19,
-  15, 0, 0, 0, 0, 17, 1, 53, 0, 0,
-  0, 49, 63, 0, 24, 24, 20, 0, 11, 25,
-  0, 37, 36, 32, 0, 13, 32, 35, 0, 0,
-  0, 66, 17, 0, 0, 0, 0, 0, 37, 0,
-  0, 36, 37, 19, 0, 29, 0, 0, 14, 20,
-  42, 8, 3, 0, 121, 0, 63, 0, 10, 0,
-  0, 30, 54, 0, 0, 0, 0, 0, 58, 0,
-  7, 0, 28, 0, 0, 22, 10, 0, 2, 0,
-  0, 34, 90, 48, 0, 0, 0, 8, 0, 0,
-  0, 0, 0, 0, 60, 31, 0, 15, 0, 34,
-  0, 38, 22, 0, 0, 0, 0, 13, 0, 15,
-  0, 42, 9, 20, 3, 0, 31, 0, 11, 0,
-  0, 30, 0, 0, 11, 0, 36, 0, 0, 0,
-  39, 7, 39, 28, 0, 24, 0, 100, 0, 56,
-  6, 0, 40, 58, 4, 14, 0, 33, 0, 7,
-  54, 0, 0, 0, 20, 0, 0, 0, 0, 89,
-  27, 0, 0, 0, 2, 0, 51, 2, 0, 7,
-  14, 14, 0, 14, 0, 0, 0, 0, 9, 47,
-  0, 0, 11, 0, 57, 2, 5, 8, 0, 8,
-  0, 0, 0, 26, 43, 6, 20, 0, 13, 0,
-  59, 0, 10, 62, 36, 31, 3, 0, 46, 0,
-  0, 38, 0, 42, 6, 2, 0, 34, 0, 0,
-  63, 41, 15, 0, 0, 0, 0, 46, 0, 37,
-  0, 53, 25, 14, 17, 17, 0, 32, 15, 5,
-  91, 14, 0, 0, 28, 0, 0, 70, 0, 0,
-  0, 0, 0, 0, 24, 8, 0, 0, 0, 2,
-  0, 9, 17, 48, 0, 3, 0, 31, 71, 5,
-  13, 36, 17, 0, 4, 23, 26, 35, 36, 0,
-  0, 2, 17, 32, 0, 0, 2, 44, 36, 0,
-  0, 0, 12, 0, 55, 13, 24, 46, 43, 0,
-  0, 24, 0, 0, 42, 41, 44, 0, 0, 0,
-  108, 0, 71, 14, 0, 0, 0, 44, 70, 0,
-  0, 0, 0, 9, 53, 0, 0, 29, 11, 20,
-  0, 36, 26, 0, 0, 0, 0, 7, 73, 51,
-  0, 0, 16, 18, 0, 0, 0, 0, 0, 0,
-  29, 22, 0, 0, 0, 40, 0, 13, 0, 10,
-  0, 1, 22, 0, 0, 0, 35, 32, 22, 15,
-  0, 0, 28, 0, 0, 0, 0, 0, 0, 0,
-  20, 0, 30, 0, 2, 0, 0, 8, 3, 20,
-  33, 0, 0, 85, 0, 28, 19, 0, 42, 48,
-  0, 18, 0, 36, 33, 9, 46, 0, 0, 0,
-  8, 0, 0, 0, 0, 81, 37, 0, 0, 0,
-  25, 0, 70, 0, 22, 26, 14, 0, 0, 8,
-  0, 0, 28, 0, 0, 18, 0, 0, 19, 0,
-  44, 20, 0, 20, 102, 0, 40, 4, 0, 12,
-  0, 0, 45, 0, 0, 35, 56, 20, 0, 0,
-  9, 0, 0, 0, 0, 189, 80, 25, 0, 0,
-  0, 31, 0, 0, 16, 61, 0, 11, 0, 30,
-  0, 40, 0, 30, 0, 28, 48, 0, 38, 21,
-  24, 29, 0, 0, 0, 80, 0, 0, 100, 0,
-  63, 0, 47, 0, 14, 23, 0, 56, 27, 66,
-  0, 1, 0, 4, 12, 26, 10, 13, 0, 0,
-  0, 47, 0, 15, 0, 0, 7, 21, 0, 11,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  25, 0, 18, 61, 0, 0, 17, 0, 54, 23,
-  26, 12, 6, 14, 8, 6, 0, 0, 0, 2,
-  87, 0, 36, 39, 0, 9, 0, 0, 23, 15,
-  18, 29, 0, 17, 0, 0, 0, 31, 35, 0,
-  13, 0, 8, 0, 56, 4, 16, 62, 36, 39,
-  10, 0, 30, 0, 0, 48, 4, 53, 0, 4,
-  0, 15, 0, 0, 72, 44, 0, 0, 0, 0,
-  0, 66, 0, 41, 0, 43, 20, 12, 12, 36,
-  0, 41, 0, 7, 95, 16, 0, 0, 21, 0,
-  0, 55, 9, 0, 0, 0, 0, 0, 32, 12,
-  11, 0, 0, 0, 0, 15, 10, 55, 0, 0,
-  0, 47, 64, 4, 32, 22, 15, 0, 7, 27,
-  13, 34, 54, 16, 0, 11, 39, 32, 0, 0,
-  0, 68, 22, 0, 0, 0, 0, 0, 48, 0,
-  0, 30, 26, 15, 0, 27, 0, 0, 25, 30,
-  24, 3, 1, 0, 121, 0, 65, 2, 0, 0,
-  0, 31, 59, 0, 8, 0, 0, 0, 53, 2,
-  0, 9, 30, 0, 0, 23, 15, 0, 8, 0,
-  0, 47, 79, 53, 0, 0, 0, 15, 0, 0,
-  0, 0, 0, 0, 52, 28, 0, 4, 0, 63,
-  0, 25, 0, 1, 0, 0, 25, 4, 0, 6,
-  0, 48, 20, 26, 0, 0, 19, 0, 8, 0,
-  0, 13, 0, 0, 18, 0, 16, 0, 9, 0,
-  10, 19, 20, 21, 21, 5, 0, 89, 0, 46,
-  12, 0, 50, 44, 4, 2, 0, 39, 7, 1,
-  49, 0, 0, 0, 4, 0, 0, 0, 6, 91,
-  22, 0, 0, 0, 9, 0, 71, 0, 0, 9,
-  0, 0, 0, 14, 0, 0, 23, 0, 0, 33,
-  0, 0, 26, 0, 73, 2, 0, 1, 73, 0,
-  21, 29, 10, 2, 0, 11, 74, 0, 0, 18,
-  94, 0, 0, 0, 36, 0, 0, 0, 0, 148,
-  91, 19, 0, 0, 0, 47, 0, 0, 32, 47,
-  0, 0, 27, 32, 0, 52, 0, 43, 0, 24,
-  66, 17, 51, 51, 13, 28, 0, 0, 0, 63,
-  0, 0, 62, 0, 50, 0, 39, 0, 0, 6,
-  0, 30, 12, 20, 0, 4, 0, 0, 19, 4,
-  40, 42, 0, 0, 0, 87, 0, 19, 0, 0,
-  16, 26, 0, 11, 0, 0, 0, 0, 0, 0,
-  0, 8, 0, 0, 35, 0, 15, 55, 0, 0,
-  22, 0, 52, 8, 59, 31, 3, 19, 8, 16,
-  0, 0, 0, 0, 66, 0, 18, 40, 0, 4,
-  0, 0, 51, 0, 18, 14, 0, 20, 0, 0,
-  0, 35, 28, 0, 25, 0, 6, 0, 68, 1,
-  9, 53, 37, 38, 8, 0, 43, 0, 0, 43,
-  7, 56, 0, 4, 0, 13, 10, 0, 65, 53,
-  0, 0, 0, 0, 0, 56, 0, 63, 0, 42,
-  23, 10, 1, 49, 0, 48, 0, 7, 80, 24,
-  0, 0, 14, 0, 0, 62, 18, 0, 0, 0,
-  0, 0, 30, 19, 15, 0, 0, 0, 0, 17,
-  1, 53, 0, 0, 0, 49, 63, 0, 24, 24,
-  20, 0, 11, 25, 0, 37, 36, 32, 0, 13,
-  32, 35, 0, 0, 0, 66, 17, 0, 0, 0,
-  0, 0, 37, 0, 0, 36, 37, 19, 0, 29,
-  0, 0, 14, 20, 42, 8, 3, 0, 121, 0,
-  63, 0, 10, 0, 0, 30, 54, 0, 0, 0,
-  0, 0, 58, 0, 7, 0, 28, 0, 0, 22,
-  10, 0, 2, 0, 0, 34, 90, 48, 0, 0,
-  0, 8, 0, 0, 0, 0, 0, 0, 60, 31,
-  0, 15, 0, 34, 0, 38, 22, 0, 0, 0,
-  0, 13, 0, 15, 0, 42, 9, 20, 3, 0,
-  31, 0, 11, 0, 0, 30, 0, 0, 11, 0,
-  36, 0, 0, 0, 39, 7, 39, 28, 0, 24,
-  0, 100, 0, 56, 6, 0, 40, 58, 4, 14,
-  0, 33, 0, 7, 54, 0, 0, 0, 20, 0,
-  0, 0, 0, 89, 27, 0, 0, 0, 2, 0,
-  51, 2, 0, 7, 14, 14, 0, 14, 0, 0,
-  0, 0, 9, 47, 0, 0, 11, 0, 57, 2,
-  5, 8, 47, 0, 20, 39, 5, 0, 0, 0,
-  62, 0, 0, 14, 68, 0, 0, 21, 35, 5,
-  0, 0, 0, 128, 114, 15, 0, 0, 0, 47,
-  0, 0, 20, 52, 0, 0, 50, 20, 0, 61,
-  4, 20, 4, 18, 55, 0, 26, 27, 3, 14,
-  0, 0, 0, 37, 0, 16, 61, 0, 47, 0,
-  41, 0, 0, 22, 0, 3, 20, 0, 11, 19,
-  19, 0, 54, 9, 49, 31, 0, 0, 0, 94,
-  0, 41, 0, 0, 7, 31, 0, 19, 0, 0,
-  0, 0, 0, 0, 0, 7, 19, 0, 43, 0,
-  15, 77, 0, 0, 32, 0, 35, 20, 15, 28,
-  0, 0, 0, 17, 0, 0, 0, 0, 32, 0,
-  4, 45, 0, 0, 0, 0, 48, 0, 19, 13,
-  0, 44, 70, 0, 0, 0, 0, 9, 53, 0,
-  0, 29, 11, 20, 0, 36, 26, 0, 0, 0,
-  0, 7, 73, 51, 0, 0, 16, 18, 0, 0,
-  0, 0, 0, 0, 29, 22, 0, 0, 0, 40,
-  0, 13, 0, 10, 0, 1, 22, 0, 0, 0,
-  35, 32, 22, 15, 0, 0, 28, 0, 0, 0,
-  0, 0, 0, 0, 20, 0, 30, 0, 2, 0,
-  0, 8, 3, 20, 33, 0, 0, 85, 0, 28,
-  19, 0, 42, 48, 0, 18, 0, 36, 33, 9,
-  46, 0, 0, 0, 8, 0, 0, 0, 0, 81,
-  37, 0, 0, 0, 25, 0, 70, 0, 22, 26,
-  14, 0, 0, 8, 0, 0, 28, 0, 0, 18,
-  0, 0, 19, 0, 44, 20, 0, 20, 102, 0,
-  40, 4, 0, 12, 0, 0, 45, 0, 0, 35,
-  56, 20, 0, 0, 9, 0, 0, 0, 0, 189,
-  80, 25, 0, 0, 0, 31, 0, 0, 16, 61,
-  0, 11, 0, 30, 0, 40, 0, 30, 0, 28,
-  48, 0, 38, 21, 24, 29, 0, 0, 0, 80,
-  0, 0, 100, 0, 63, 0, 47, 0, 14, 23,
-  0, 56, 27, 66, 0, 1, 0, 4, 12, 26,
-  10, 13, 0, 0, 0, 47, 0, 15, 0, 0,
-  7, 21, 0, 11, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 25, 0, 18, 61, 0, 0,
-  17, 0, 54, 23, 26, 12, 6, 14, 8, 6,
-  0, 0, 0, 2, 87, 0, 36, 39, 0, 9,
-  0, 0, 23, 15, 18, 29, 9, 0, 0, 9,
-  0, 65, 0, 0, 41, 0, 0, 0, 45, 38,
-  0, 38, 32, 25, 0, 0, 8, 14, 5, 56,
-  28, 0, 0, 19, 0, 0, 0, 21, 10, 40,
-  27, 4, 0, 33, 0, 8, 9, 4, 50, 58,
-  50, 77, 14, 17, 0, 0, 0, 0, 0, 0,
-  0, 0, 54, 0, 0, 0, 4, 43, 0, 0,
-  0, 0, 0, 0, 12, 0, 54, 0, 14, 11,
-  0, 28, 0, 28, 0, 28, 0, 16, 0, 39,
-  0, 0, 31, 0, 14, 62, 0, 63, 0, 0,
-  13, 17, 0, 0, 0, 56, 19, 0, 0, 0,
-  17, 0, 0, 4, 0, 40, 0, 0, 0, 9,
-  0, 0, 61, 0, 8, 0, 37, 0, 3, 0,
-  29, 10, 44, 0, 0, 31, 59, 0, 8, 0,
-  0, 0, 53, 2, 0, 9, 30, 0, 0, 23,
-  15, 0, 8, 0, 0, 47, 79, 53, 0, 0,
-  0, 15, 0, 0, 0, 0, 0, 0, 52, 28,
-  0, 4, 0, 63, 0, 25, 0, 1, 0, 0,
-  25, 4, 0, 6, 0, 48, 20, 26, 0, 0,
-  19, 0, 8, 0, 0, 13, 0, 0, 18, 0,
-  16, 0, 9, 0, 10, 19, 20, 21, 21, 5,
-  0, 89, 0, 46, 12, 0, 50, 44, 4, 2,
-  0, 39, 7, 1, 49, 0, 0, 0, 4, 0,
-  0, 0, 6, 91, 22, 0, 0, 0, 9, 0,
-  71, 0, 0, 9, 0, 0, 0, 14, 0, 0,
-  23, 0, 0, 33, 0, 0, 26, 0, 73, 2,
-  0, 1, 73, 0, 21, 29, 10, 2, 0, 11,
-  74, 0, 0, 18, 94, 0, 0, 0, 36, 0,
-  0, 0, 0, 148, 91, 19, 0, 0, 0, 47,
-  0, 0, 32, 47, 0, 0, 27, 32, 0, 52,
-  0, 43, 0, 24, 66, 17, 51, 51, 13, 28,
-  0, 0, 0, 63, 0, 0, 62, 0, 50, 0,
-  39, 0, 0, 6, 0, 30, 12, 20, 0, 4,
-  0, 0, 19, 4, 40, 42, 0, 0, 0, 87,
-  0, 19, 0, 0, 16, 26, 0, 11, 0, 0,
-  0, 0, 0, 0, 0, 8, 0, 0, 35, 0,
-  15, 55, 0, 0, 22, 0, 52, 8, 59, 31,
-  3, 19, 8, 16, 0, 0, 0, 0, 66, 0,
-  18, 40, 0, 4, 0, 0, 51, 0, 18, 14,
-  0, 0, 0, 29, 1, 29, 8, 0, 54, 0,
-  0, 0, 67, 10, 9, 37, 50, 41, 0, 0,
-  0, 0, 0, 46, 33, 11, 2, 31, 0, 0,
-  8, 47, 45, 22, 0, 0, 0, 51, 0, 0,
-  0, 0, 95, 63, 29, 90, 0, 25, 0, 0,
-  0, 1, 11, 3, 0, 0, 29, 0, 0, 1,
-  0, 38, 0, 0, 3, 0, 26, 25, 4, 0,
-  48, 0, 30, 61, 0, 8, 0, 30, 0, 18,
-  0, 0, 0, 54, 0, 2, 33, 0, 0, 26,
-  0, 44, 0, 32, 0, 43, 0, 0, 0, 39,
-  13, 0, 8, 0, 38, 0, 3, 19, 0, 10,
-  9, 7, 0, 4, 0, 0, 50, 0, 0, 18,
-  13, 0, 27, 0, 42, 0, 53, 0, 0, 30,
-  54, 0, 0, 0, 0, 0, 58, 0, 7, 0,
-  28, 0, 0, 22, 10, 0, 2, 0, 0, 34,
-  90, 48, 0, 0, 0, 8, 0, 0, 0, 0,
-  0, 0, 60, 31, 0, 15, 0, 34, 0, 38,
-  22, 0, 0, 0, 0, 13, 0, 15, 0, 42,
-  9, 20, 3, 0, 31, 0, 11, 0, 0, 30,
-  0, 0, 11, 0, 36, 0, 0, 0, 39, 7,
-  39, 28, 0, 24, 0, 100, 0, 56, 6, 0,
-  40, 58, 4, 14, 0, 33, 0, 7, 54, 0,
-  0, 0, 20, 0, 0, 0, 0, 89, 27, 0,
-  0, 0, 2, 0, 51, 2, 0, 7, 14, 14,
-  0, 14, 0, 0, 0, 0, 9, 47, 0, 0,
-  11, 0, 57, 2, 5, 8, 47, 0, 20, 39,
-  5, 0, 0, 0, 62, 0, 0, 14, 68, 0,
-  0, 21, 35, 5, 0, 0, 0, 128, 114, 15,
-  0, 0, 0, 47, 0, 0, 20, 52, 0, 0,
-  50, 20, 0, 61, 4, 20, 4, 18, 55, 0,
-  26, 27, 3, 14, 0, 0, 0, 37, 0, 16,
-  61, 0, 47, 0, 41, 0, 0, 22, 0, 3,
-  20, 0, 11, 19, 19, 0, 54, 9, 49, 31,
-  0, 0, 0, 94, 0, 41, 0, 0, 7, 31,
-  0, 19, 0, 0, 0, 0, 0, 0, 0, 7,
-  19, 0, 43, 0, 15, 77, 0, 0, 32, 0,
-  35, 20, 15, 28, 0, 0, 0, 17, 0, 0,
-  0, 0, 32, 0, 4, 45, 0, 0, 0, 0,
-  48, 0, 19, 13, 7, 0, 3, 44, 17, 25,
-  0, 0, 33, 5, 0, 0, 79, 30, 6, 52,
-  69, 29, 0, 5, 0, 0, 0, 27, 43, 42,
-  0, 35, 0, 15, 23, 80, 17, 52, 0, 11,
-  0, 71, 0, 0, 0, 0, 79, 35, 26, 18,
-  0, 33, 18, 0, 0, 0, 0, 36, 0, 0,
-  12, 0, 0, 50, 0, 25, 11, 0, 0, 0,
-  34, 59, 45, 0, 6, 16, 27, 39, 11, 5,
-  0, 27, 0, 41, 0, 6, 0, 50, 30, 18,
-  19, 0, 0, 8, 0, 13, 0, 78, 0, 51,
-  3, 0, 0, 35, 0, 0, 32, 0, 33, 0,
-  0, 19, 0, 0, 22, 0, 0, 0, 0, 0,
-  41, 0, 0, 2, 9, 6, 34, 0, 46, 1,
-  49, 0, 102, 0, 40, 4, 0, 12, 0, 0,
-  45, 0, 0, 35, 56, 20, 0, 0, 9, 0,
-  0, 0, 0, 189, 80, 25, 0, 0, 0, 31,
-  0, 0, 16, 61, 0, 11, 0, 30, 0, 40,
-  0, 30, 0, 28, 48, 0, 38, 21, 24, 29,
-  0, 0, 0, 80, 0, 0, 100, 0, 63, 0,
-  47, 0, 14, 23, 0, 56, 27, 66, 0, 1,
-  0, 4, 12, 26, 10, 13, 0, 0, 0, 47,
-  0, 15, 0, 0, 7, 21, 0, 11, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 25, 0,
-  18, 61, 0, 0, 17, 0, 54, 23, 26, 12,
-  6, 14, 8, 6, 0, 0, 0, 2, 87, 0,
-  36, 39, 0, 9, 0, 0, 23, 15, 18, 29,
-  9, 0, 0, 9, 0, 65, 0, 0, 41, 0,
-  0, 0, 45, 38, 0, 38, 32, 25, 0, 0,
-  8, 14, 5, 56, 28, 0, 0, 19, 0, 0,
-  0, 21, 10, 40, 27, 4, 0, 33, 0, 8,
-  9, 4, 50, 58, 50, 77, 14, 17, 0, 0,
-  0, 0, 0, 0, 0, 0, 54, 0, 0, 0,
-  4, 43, 0, 0, 0, 0, 0, 0, 12, 0,
-  54, 0, 14, 11, 0, 28, 0, 28, 0, 28,
-  0, 16, 0, 39, 0, 0, 31, 0, 14, 62,
-  0, 63, 0, 0, 13, 17, 0, 0, 0, 56,
-  19, 0, 0, 0, 17, 0, 0, 4, 0, 40,
-  0, 0, 0, 9, 0, 0, 61, 0, 8, 0,
-  37, 0, 3, 0, 29, 10, 44, 0, 0, 14,
-  0, 0, 35, 12, 0, 0, 40, 0, 0, 15,
-  31, 88, 14, 51, 40, 12, 0, 18, 47, 0,
-  19, 50, 3, 20, 0, 2, 0, 0, 0, 0,
-  0, 38, 7, 0, 3, 31, 0, 29, 36, 1,
-  0, 74, 29, 39, 8, 0, 0, 0, 18, 2,
-  39, 14, 0, 6, 37, 0, 0, 0, 0, 4,
-  5, 0, 0, 0, 26, 0, 49, 0, 0, 0,
-  3, 3, 17, 22, 0, 17, 0, 21, 27, 60,
-  0, 26, 24, 3, 57, 0, 52, 33, 0, 62,
-  14, 8, 23, 27, 0, 0, 26, 70, 5, 0,
-  0, 0, 0, 0, 0, 16, 0, 35, 0, 0,
-  0, 12, 0, 0, 17, 3, 26, 0, 0, 0,
-  20, 0, 35, 8, 37, 0, 73, 0, 21, 29,
-  10, 2, 0, 11, 74, 0, 0, 18, 94, 0,
-  0, 0, 36, 0, 0, 0, 0, 148, 91, 19,
-  0, 0, 0, 47, 0, 0, 32, 47, 0, 0,
-  27, 32, 0, 52, 0, 43, 0, 24, 66, 17,
-  51, 51, 13, 28, 0, 0, 0, 63, 0, 0,
-  62, 0, 50, 0, 39, 0, 0, 6, 0, 30,
-  12, 20, 0, 4, 0, 0, 19, 4, 40, 42,
-  0, 0, 0, 87, 0, 19, 0, 0, 16, 26,
-  0, 11, 0, 0, 0, 0, 0, 0, 0, 8,
-  0, 0, 35, 0, 15, 55, 0, 0, 22, 0,
-  52, 8, 59, 31, 3, 19, 8, 16, 0, 0,
-  0, 0, 66, 0, 18, 40, 0, 4, 0, 0,
-  51, 0, 18, 14, 0, 0, 0, 29, 1, 29,
-  8, 0, 54, 0, 0, 0, 67, 10, 9, 37,
-  50, 41, 0, 0, 0, 0, 0, 46, 33, 11,
-  2, 31, 0, 0, 8, 47, 45, 22, 0, 0,
-  0, 51, 0, 0, 0, 0, 95, 63, 29, 90,
-  0, 25, 0, 0, 0, 1, 11, 3, 0, 0,
-  29, 0, 0, 1, 0, 38, 0, 0, 3, 0,
-  26, 25, 4, 0, 48, 0, 30, 61, 0, 8,
-  0, 30, 0, 18, 0, 0, 0, 54, 0, 2,
-  33, 0, 0, 26, 0, 44, 0, 32, 0, 43,
-  0, 0, 0, 39, 13, 0, 8, 0, 38, 0,
-  3, 19, 0, 10, 9, 7, 0, 4, 0, 0,
-  50, 0, 0, 18, 13, 0, 27, 0, 42, 0,
-  53, 0, 0, 0, 0, 5, 36, 43, 0, 0,
-  0, 0, 0, 1, 24, 87, 0, 16, 36, 0,
-  0, 9, 34, 0, 19, 29, 0, 11, 0, 0,
-  0, 24, 7, 0, 0, 36, 0, 0, 0, 26,
-  0, 8, 20, 9, 0, 66, 26, 13, 0, 36,
-  0, 0, 2, 42, 7, 10, 0, 0, 26, 0,
-  0, 0, 0, 31, 20, 0, 10, 0, 10, 15,
-  33, 0, 6, 11, 0, 7, 9, 11, 0, 16,
-  0, 29, 9, 31, 0, 20, 48, 0, 63, 19,
-  21, 0, 0, 52, 14, 4, 22, 50, 0, 0,
-  0, 71, 13, 0, 0, 0, 0, 0, 0, 1,
-  0, 0, 3, 0, 0, 16, 0, 8, 57, 0,
-  8, 0, 0, 0, 0, 0, 20, 1, 25, 0,
-  47, 0, 20, 39, 5, 0, 0, 0, 62, 0,
-  0, 14, 68, 0, 0, 21, 35, 5, 0, 0,
-  0, 128, 114, 15, 0, 0, 0, 47, 0, 0,
-  20, 52, 0, 0, 50, 20, 0, 61, 4, 20,
-  4, 18, 55, 0, 26, 27, 3, 14, 0, 0,
-  0, 37, 0, 16, 61, 0, 47, 0, 41, 0,
-  0, 22, 0, 3, 20, 0, 11, 19, 19, 0,
-  54, 9, 49, 31, 0, 0, 0, 94, 0, 41,
-  0, 0, 7, 31, 0, 19, 0, 0, 0, 0,
-  0, 0, 0, 7, 19, 0, 43, 0, 15, 77,
-  0, 0, 32, 0, 35, 20, 15, 28, 0, 0,
-  0, 17, 0, 0, 0, 0, 32, 0, 4, 45,
-  0, 0, 0, 0, 48, 0, 19, 13, 7, 0,
-  3, 44, 17, 25, 0, 0, 33, 5, 0, 0,
-  79, 30, 6, 52, 69, 29, 0, 5, 0, 0,
-  0, 27, 43, 42, 0, 35, 0, 15, 23, 80,
-  17, 52, 0, 11, 0, 71, 0, 0, 0, 0,
-  79, 35, 26, 18, 0, 33, 18, 0, 0, 0,
-  0, 36, 0, 0, 12, 0, 0, 50, 0, 25,
-  11, 0, 0, 0, 34, 59, 45, 0, 6, 16,
-  27, 39, 11, 5, 0, 27, 0, 41, 0, 6,
-  0, 50, 30, 18, 19, 0, 0, 8, 0, 13,
-  0, 78, 0, 51, 3, 0, 0, 35, 0, 0,
-  32, 0, 33, 0, 0, 19, 0, 0, 22, 0,
-  0, 0, 0, 0, 41, 0, 0, 2, 9, 6,
-  34, 0, 46, 1, 49, 0, 0, 0, 10, 17,
-  54, 56, 0, 0, 20, 0, 5, 0, 53, 99,
-  5, 43, 52, 0, 0, 5, 28, 0, 0, 23,
-  0, 24, 0, 5, 0, 39, 8, 0, 0, 50,
-  0, 0, 0, 26, 0, 39, 0, 24, 13, 63,
-  23, 0, 2, 41, 6, 0, 11, 51, 3, 40,
-  0, 0, 3, 3, 2, 3, 0, 28, 5, 0,
-  0, 0, 3, 0, 53, 0, 0, 21, 8, 0,
-  22, 6, 0, 28, 0, 59, 6, 44, 0, 0,
-  63, 6, 53, 24, 33, 0, 0, 30, 0, 30,
-  0, 66, 0, 0, 0, 63, 0, 0, 0, 0,
-  0, 0, 0, 1, 0, 0, 20, 0, 0, 6,
-  0, 0, 60, 0, 0, 0, 34, 0, 15, 0,
-  39, 0, 0, 0, 9, 0, 0, 9, 0, 65,
-  0, 0, 41, 0, 0, 0, 45, 38, 0, 38,
-  32, 25, 0, 0, 8, 14, 5, 56, 28, 0,
-  0, 19, 0, 0, 0, 21, 10, 40, 27, 4,
-  0, 33, 0, 8, 9, 4, 50, 58, 50, 77,
-  14, 17, 0, 0, 0, 0, 0, 0, 0, 0,
-  54, 0, 0, 0, 4, 43, 0, 0, 0, 0,
-  0, 0, 12, 0, 54, 0, 14, 11, 0, 28,
-  0, 28, 0, 28, 0, 16, 0, 39, 0, 0,
-  31, 0, 14, 62, 0, 63, 0, 0, 13, 17,
-  0, 0, 0, 56, 19, 0, 0, 0, 17, 0,
-  0, 4, 0, 40, 0, 0, 0, 9, 0, 0,
-  61, 0, 8, 0, 37, 0, 3, 0, 29, 10,
-  44, 0, 0, 14, 0, 0, 35, 12, 0, 0,
-  40, 0, 0, 15, 31, 88, 14, 51, 40, 12,
-  0, 18, 47, 0, 19, 50, 3, 20, 0, 2,
-  0, 0, 0, 0, 0, 38, 7, 0, 3, 31,
-  0, 29, 36, 1, 0, 74, 29, 39, 8, 0,
-  0, 0, 18, 2, 39, 14, 0, 6, 37, 0,
-  0, 0, 0, 4, 5, 0, 0, 0, 26, 0,
-  49, 0, 0, 0, 3, 3, 17, 22, 0, 17,
-  0, 21, 27, 60, 0, 26, 24, 3, 57, 0,
-  52, 33, 0, 62, 14, 8, 23, 27, 0, 0,
-  26, 70, 5, 0, 0, 0, 0, 0, 0, 16,
-  0, 35, 0, 0, 0, 12, 0, 0, 17, 3,
-  26, 0, 0, 0, 20, 0, 35, 8, 37, 0,
-  24, 0, 53, 0, 32, 0, 0, 0, 25, 0,
-  0, 1, 9, 122, 15, 0, 27, 21, 0, 8,
-  41, 13, 69, 7, 0, 0, 0, 4, 0, 0,
-  0, 0, 0, 5, 0, 0, 0, 4, 0, 26,
-  14, 10, 0, 48, 14, 0, 0, 0, 0, 0,
-  37, 104, 0, 37, 0, 0, 9, 6, 3, 0,
-  0, 0, 33, 0, 50, 22, 0, 0, 24, 22,
-  0, 1, 0, 0, 27, 0, 0, 13, 0, 41,
-  14, 36, 0, 5, 48, 0, 45, 11, 72, 0,
-  0, 2, 0, 0, 0, 25, 0, 0, 41, 57,
-  0, 0, 0, 0, 0, 0, 0, 10, 1, 0,
-  35, 0, 0, 0, 51, 0, 55, 0, 5, 0,
-  0, 0, 0, 0, 28, 1, 16, 0, 0, 0,
-  0, 29, 1, 29, 8, 0, 54, 0, 0, 0,
-  67, 10, 9, 37, 50, 41, 0, 0, 0, 0,
-  0, 46, 33, 11, 2, 31, 0, 0, 8, 47,
-  45, 22, 0, 0, 0, 51, 0, 0, 0, 0,
-  95, 63, 29, 90, 0, 25, 0, 0, 0, 1,
-  11, 3, 0, 0, 29, 0, 0, 1, 0, 38,
-  0, 0, 3, 0, 26, 25, 4, 0, 48, 0,
-  30, 61, 0, 8, 0, 30, 0, 18, 0, 0,
-  0, 54, 0, 2, 33, 0, 0, 26, 0, 44,
-  0, 32, 0, 43, 0, 0, 0, 39, 13, 0,
-  8, 0, 38, 0, 3, 19, 0, 10, 9, 7,
-  0, 4, 0, 0, 50, 0, 0, 18, 13, 0,
-  27, 0, 42, 0, 53, 0, 0, 0, 0, 5,
-  36, 43, 0, 0, 0, 0, 0, 1, 24, 87,
-  0, 16, 36, 0, 0, 9, 34, 0, 19, 29,
-  0, 11, 0, 0, 0, 24, 7, 0, 0, 36,
-  0, 0, 0, 26, 0, 8, 20, 9, 0, 66,
-  26, 13, 0, 36, 0, 0, 2, 42, 7, 10,
-  0, 0, 26, 0, 0, 0, 0, 31, 20, 0,
-  10, 0, 10, 15, 33, 0, 6, 11, 0, 7,
-  9, 11, 0, 16, 0, 29, 9, 31, 0, 20,
-  48, 0, 63, 19, 21, 0, 0, 52, 14, 4,
-  22, 50, 0, 0, 0, 71, 13, 0, 0, 0,
-  0, 0, 0, 1, 0, 0, 3, 0, 0, 16,
-  0, 8, 57, 0, 8, 0, 0, 0, 0, 0,
-  20, 1, 25, 0, 15, 8, 22, 22, 74, 0,
-  0, 1, 31, 0, 0, 0, 40, 118, 28, 13,
-  44, 0, 0, 9, 37, 0, 0, 12, 0, 12,
-  0, 24, 0, 17, 2, 0, 0, 38, 0, 0,
-  0, 6, 0, 44, 0, 22, 0, 57, 17, 0,
-  18, 21, 0, 0, 25, 88, 0, 60, 0, 0,
-  0, 21, 0, 0, 0, 0, 0, 0, 0, 3,
-  13, 0, 39, 0, 0, 18, 0, 0, 44, 0,
-  0, 3, 0, 44, 27, 45, 2, 0, 52, 4,
-  48, 24, 64, 0, 0, 0, 0, 16, 0, 45,
-  3, 2, 31, 57, 0, 0, 0, 0, 0, 0,
-  0, 10, 30, 7, 17, 0, 0, 0, 33, 0,
-  43, 0, 0, 0, 30, 0, 35, 0, 54, 0,
-  0, 0, 7, 0, 3, 44, 17, 25, 0, 0,
-  33, 5, 0, 0, 79, 30, 6, 52, 69, 29,
-  0, 5, 0, 0, 0, 27, 43, 42, 0, 35,
-  0, 15, 23, 80, 17, 52, 0, 11, 0, 71,
-  0, 0, 0, 0, 79, 35, 26, 18, 0, 33,
-  18, 0, 0, 0, 0, 36, 0, 0, 12, 0,
-  0, 50, 0, 25, 11, 0, 0, 0, 34, 59,
-  45, 0, 6, 16, 27, 39, 11, 5, 0, 27,
-  0, 41, 0, 6, 0, 50, 30, 18, 19, 0,
-  0, 8, 0, 13, 0, 78, 0, 51, 3, 0,
-  0, 35, 0, 0, 32, 0, 33, 0, 0, 19,
-  0, 0, 22, 0, 0, 0, 0, 0, 41, 0,
-  0, 2, 9, 6, 34, 0, 46, 1, 49, 0,
-  0, 0, 10, 17, 54, 56, 0, 0, 20, 0,
-  5, 0, 53, 99, 5, 43, 52, 0, 0, 5,
-  28, 0, 0, 23, 0, 24, 0, 5, 0, 39,
-  8, 0, 0, 50, 0, 0, 0, 26, 0, 39,
-  0, 24, 13, 63, 23, 0, 2, 41, 6, 0,
-  11, 51, 3, 40, 0, 0, 3, 3, 2, 3,
-  0, 28, 5, 0, 0, 0, 3, 0, 53, 0,
-  0, 21, 8, 0, 22, 6, 0, 28, 0, 59,
-  6, 44, 0, 0, 63, 6, 53, 24, 33, 0,
-  0, 30, 0, 30, 0, 66, 0, 0, 0, 63,
-  0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
-  20, 0, 0, 6, 0, 0, 60, 0, 0, 0,
-  34, 0, 15, 0, 39, 0, 0, 0, 0, 16,
-  49, 37, 80, 0, 0, 1, 64, 3, 2, 0,
-  54, 91, 27, 51, 45, 0, 0, 9, 23, 0,
-  0, 27, 0, 25, 0, 38, 0, 3, 12, 0,
-  0, 38, 0, 0, 0, 15, 0, 58, 0, 15,
-  0, 46, 0, 0, 33, 9, 0, 0, 4, 73,
-  21, 61, 0, 0, 0, 51, 0, 15, 0, 0,
-  0, 0, 0, 0, 58, 0, 53, 0, 0, 0,
-  0, 25, 36, 0, 0, 19, 0, 23, 49, 49,
-  13, 0, 41, 40, 36, 29, 68, 0, 0, 29,
-  0, 26, 0, 29, 0, 0, 3, 71, 0, 0,
-  0, 0, 0, 0, 0, 17, 24, 30, 27, 0,
-  0, 0, 28, 0, 19, 0, 0, 0, 24, 0,
-  70, 0, 63, 3, 0, 0, 0, 14, 0, 0,
-  35, 12, 0, 0, 40, 0, 0, 15, 31, 88,
-  14, 51, 40, 12, 0, 18, 47, 0, 19, 50,
-  3, 20, 0, 2, 0, 0, 0, 0, 0, 38,
-  7, 0, 3, 31, 0, 29, 36, 1, 0, 74,
-  29, 39, 8, 0, 0, 0, 18, 2, 39, 14,
-  0, 6, 37, 0, 0, 0, 0, 4, 5, 0,
-  0, 0, 26, 0, 49, 0, 0, 0, 3, 3,
-  17, 22, 0, 17, 0, 21, 27, 60, 0, 26,
-  24, 3, 57, 0, 52, 33, 0, 62, 14, 8,
-  23, 27, 0, 0, 26, 70, 5, 0, 0, 0,
-  0, 0, 0, 16, 0, 35, 0, 0, 0, 12,
-  0, 0, 17, 3, 26, 0, 0, 0, 20, 0,
-  35, 8, 37, 0, 24, 0, 53, 0, 32, 0,
-  0, 0, 25, 0, 0, 1, 9, 122, 15, 0,
-  27, 21, 0, 8, 41, 13, 69, 7, 0, 0,
-  0, 4, 0, 0, 0, 0, 0, 5, 0, 0,
-  0, 4, 0, 26, 14, 10, 0, 48, 14, 0,
-  0, 0, 0, 0, 37, 104, 0, 37, 0, 0,
-  9, 6, 3, 0, 0, 0, 33, 0, 50, 22,
-  0, 0, 24, 22, 0, 1, 0, 0, 27, 0,
-  0, 13, 0, 41, 14, 36, 0, 5, 48, 0,
-  45, 11, 72, 0, 0, 2, 0, 0, 0, 25,
-  0, 0, 41, 57, 0, 0, 0, 0, 0, 0,
-  0, 10, 1, 0, 35, 0, 0, 0, 51, 0,
-  55, 0, 5, 0, 0, 0, 0, 0, 28, 1,
-  16, 0, 30, 0, 17, 10, 31, 0, 0, 0,
-  35, 0, 0, 3, 12, 104, 13, 0, 18, 16,
-  0, 5, 51, 0, 33, 3, 0, 0, 0, 16,
-  0, 15, 0, 9, 0, 7, 0, 0, 0, 0,
-  0, 7, 0, 12, 0, 50, 13, 0, 0, 0,
-  0, 0, 32, 102, 0, 61, 0, 0, 22, 15,
-  0, 0, 0, 0, 29, 0, 32, 22, 10, 15,
-  12, 12, 0, 0, 0, 0, 42, 0, 0, 0,
-  0, 33, 26, 38, 0, 3, 31, 0, 30, 10,
-  63, 12, 0, 0, 0, 0, 0, 25, 23, 0,
-  69, 64, 0, 0, 2, 0, 4, 5, 0, 9,
-  49, 0, 33, 0, 0, 3, 60, 0, 68, 0,
-  0, 0, 8, 0, 0, 0, 49, 3, 11, 0,
-  0, 0, 0, 5, 36, 43, 0, 0, 0, 0,
-  0, 1, 24, 87, 0, 16, 36, 0, 0, 9,
-  34, 0, 19, 29, 0, 11, 0, 0, 0, 24,
-  7, 0, 0, 36, 0, 0, 0, 26, 0, 8,
-  20, 9, 0, 66, 26, 13, 0, 36, 0, 0,
-  2, 42, 7, 10, 0, 0, 26, 0, 0, 0,
-  0, 31, 20, 0, 10, 0, 10, 15, 33, 0,
-  6, 11, 0, 7, 9, 11, 0, 16, 0, 29,
-  9, 31, 0, 20, 48, 0, 63, 19, 21, 0,
-  0, 52, 14, 4, 22, 50, 0, 0, 0, 71,
-  13, 0, 0, 0, 0, 0, 0, 1, 0, 0,
-  3, 0, 0, 16, 0, 8, 57, 0, 8, 0,
-  0, 0, 0, 0, 20, 1, 25, 0, 15, 8,
-  22, 22, 74, 0, 0, 1, 31, 0, 0, 0,
-  40, 118, 28, 13, 44, 0, 0, 9, 37, 0,
-  0, 12, 0, 12, 0, 24, 0, 17, 2, 0,
-  0, 38, 0, 0, 0, 6, 0, 44, 0, 22,
-  0, 57, 17, 0, 18, 21, 0, 0, 25, 88,
-  0, 60, 0, 0, 0, 21, 0, 0, 0, 0,
-  0, 0, 0, 3, 13, 0, 39, 0, 0, 18,
-  0, 0, 44, 0, 0, 3, 0, 44, 27, 45,
-  2, 0, 52, 4, 48, 24, 64, 0, 0, 0,
-  0, 16, 0, 45, 3, 2, 31, 57, 0, 0,
-  0, 0, 0, 0, 0, 10, 30, 7, 17, 0,
-  0, 0, 33, 0, 43, 0, 0, 0, 30, 0,
-  35, 0, 54, 0, 0, 0, 0, 42, 26, 36,
-  66, 0, 0, 14, 62, 8, 0, 3, 37, 89,
-  51, 42, 59, 7, 0, 10, 42, 0, 0, 21,
-  16, 33, 0, 45, 0, 0, 4, 0, 0, 27,
-  0, 0, 0, 13, 0, 62, 0, 3, 0, 70,
-  16, 0, 32, 0, 0, 0, 21, 64, 8, 79,
-  0, 0, 0, 31, 0, 20, 0, 0, 0, 0,
-  0, 0, 49, 0, 44, 0, 0, 0, 0, 2,
-  62, 0, 0, 25, 0, 37, 50, 81, 8, 1,
-  28, 19, 26, 9, 59, 14, 0, 0, 0, 31,
-  0, 46, 17, 31, 61, 56, 0, 0, 3, 0,
-  4, 0, 0, 6, 50, 28, 14, 0, 0, 0,
-  10, 0, 0, 0, 0, 0, 7, 1, 83, 0,
-  80, 2, 9, 0, 0, 0, 10, 17, 54, 56,
-  0, 0, 20, 0, 5, 0, 53, 99, 5, 43,
-  52, 0, 0, 5, 28, 0, 0, 23, 0, 24,
-  0, 5, 0, 39, 8, 0, 0, 50, 0, 0,
-  0, 26, 0, 39, 0, 24, 13, 63, 23, 0,
-  2, 41, 6, 0, 11, 51, 3, 40, 0, 0,
-  3, 3, 2, 3, 0, 28, 5, 0, 0, 0,
-  3, 0, 53, 0, 0, 21, 8, 0, 22, 6,
-  0, 28, 0, 59, 6, 44, 0, 0, 63, 6,
-  53, 24, 33, 0, 0, 30, 0, 30, 0, 66,
-  0, 0, 0, 63, 0, 0, 0, 0, 0, 0,
-  0, 1, 0, 0, 20, 0, 0, 6, 0, 0,
-  60, 0, 0, 0, 34, 0, 15, 0, 39, 0,
-  0, 0, 0, 16, 49, 37, 80, 0, 0, 1,
-  64, 3, 2, 0, 54, 91, 27, 51, 45, 0,
-  0, 9, 23, 0, 0, 27, 0, 25, 0, 38,
-  0, 3, 12, 0, 0, 38, 0, 0, 0, 15,
-  0, 58, 0, 15, 0, 46, 0, 0, 33, 9,
-  0, 0, 4, 73, 21, 61, 0, 0, 0, 51,
-  0, 15, 0, 0, 0, 0, 0, 0, 58, 0,
-  53, 0, 0, 0, 0, 25, 36, 0, 0, 19,
-  0, 23, 49, 49, 13, 0, 41, 40, 36, 29,
-  68, 0, 0, 29, 0, 26, 0, 29, 0, 0,
-  3, 71, 0, 0, 0, 0, 0, 0, 0, 17,
-  24, 30, 27, 0, 0, 0, 28, 0, 19, 0,
-  0, 0, 24, 0, 70, 0, 63, 3, 0, 0,
-  0, 17, 93, 43, 53, 0, 0, 8, 55, 26,
-  0, 0, 17, 57, 20, 55, 57, 27, 0, 29,
-  14, 0, 0, 5, 16, 11, 6, 56, 0, 0,
-  0, 0, 0, 8, 0, 0, 0, 41, 0, 41,
-  0, 0, 0, 42, 0, 5, 36, 0, 0, 0,
-  2, 40, 0, 36, 0, 0, 0, 42, 0, 17,
-  0, 0, 0, 0, 0, 0, 82, 0, 42, 17,
-  0, 0, 1, 48, 33, 0, 0, 61, 0, 0,
-  38, 68, 6, 58, 20, 52, 28, 25, 45, 0,
-  0, 24, 0, 24, 0, 8, 0, 6, 4, 57,
-  8, 0, 0, 0, 0, 2, 0, 5, 16, 36,
-  9, 0, 0, 0, 13, 0, 5, 0, 0, 0,
-  0, 0, 58, 0, 58, 12, 0, 0, 24, 0,
-  53, 0, 32, 0, 0, 0, 25, 0, 0, 1,
-  9, 122, 15, 0, 27, 21, 0, 8, 41, 13,
-  69, 7, 0, 0, 0, 4, 0, 0, 0, 0,
-  0, 5, 0, 0, 0, 4, 0, 26, 14, 10,
-  0, 48, 14, 0, 0, 0, 0, 0, 37, 104,
-  0, 37, 0, 0, 9, 6, 3, 0, 0, 0,
-  33, 0, 50, 22, 0, 0, 24, 22, 0, 1,
-  0, 0, 27, 0, 0, 13, 0, 41, 14, 36,
-  0, 5, 48, 0, 45, 11, 72, 0, 0, 2,
-  0, 0, 0, 25, 0, 0, 41, 57, 0, 0,
-  0, 0, 0, 0, 0, 10, 1, 0, 35, 0,
-  0, 0, 51, 0, 55, 0, 5, 0, 0, 0,
-  0, 0, 28, 1, 16, 0, 30, 0, 17, 10,
-  31, 0, 0, 0, 35, 0, 0, 3, 12, 104,
-  13, 0, 18, 16, 0, 5, 51, 0, 33, 3,
-  0, 0, 0, 16, 0, 15, 0, 9, 0, 7,
-  0, 0, 0, 0, 0, 7, 0, 12, 0, 50,
-  13, 0, 0, 0, 0, 0, 32, 102, 0, 61,
-  0, 0, 22, 15, 0, 0, 0, 0, 29, 0,
-  32, 22, 10, 15, 12, 12, 0, 0, 0, 0,
-  42, 0, 0, 0, 0, 33, 26, 38, 0, 3,
-  31, 0, 30, 10, 63, 12, 0, 0, 0, 0,
-  0, 25, 23, 0, 69, 64, 0, 0, 2, 0,
-  4, 5, 0, 9, 49, 0, 33, 0, 0, 3,
-  60, 0, 68, 0, 0, 0, 8, 0, 0, 0,
-  49, 3, 11, 0, 0, 22, 0, 46, 29, 0,
-  0, 10, 69, 0, 0, 23, 38, 83, 24, 20,
-  35, 2, 0, 9, 58, 0, 0, 0, 4, 48,
-  0, 23, 0, 8, 10, 0, 0, 43, 1, 0,
-  0, 4, 0, 24, 0, 21, 0, 69, 0, 0,
-  10, 17, 0, 0, 39, 72, 4, 92, 0, 0,
-  6, 27, 0, 37, 0, 0, 0, 0, 0, 8,
-  23, 24, 37, 0, 0, 3, 0, 0, 58, 0,
-  0, 14, 0, 39, 58, 70, 0, 0, 36, 5,
-  31, 21, 43, 20, 8, 4, 0, 16, 0, 28,
-  38, 0, 72, 48, 0, 0, 6, 0, 2, 0,
-  0, 22, 64, 11, 22, 0, 0, 9, 42, 0,
-  28, 0, 0, 0, 25, 29, 79, 0, 79, 5,
-  10, 0, 15, 8, 22, 22, 74, 0, 0, 1,
-  31, 0, 0, 0, 40, 118, 28, 13, 44, 0,
-  0, 9, 37, 0, 0, 12, 0, 12, 0, 24,
-  0, 17, 2, 0, 0, 38, 0, 0, 0, 6,
-  0, 44, 0, 22, 0, 57, 17, 0, 18, 21,
-  0, 0, 25, 88, 0, 60, 0, 0, 0, 21,
-  0, 0, 0, 0, 0, 0, 0, 3, 13, 0,
-  39, 0, 0, 18, 0, 0, 44, 0, 0, 3,
-  0, 44, 27, 45, 2, 0, 52, 4, 48, 24,
-  64, 0, 0, 0, 0, 16, 0, 45, 3, 2,
-  31, 57, 0, 0, 0, 0, 0, 0, 0, 10,
-  30, 7, 17, 0, 0, 0, 33, 0, 43, 0,
-  0, 0, 30, 0, 35, 0, 54, 0, 0, 0,
-  0, 42, 26, 36, 66, 0, 0, 14, 62, 8,
-  0, 3, 37, 89, 51, 42, 59, 7, 0, 10,
-  42, 0, 0, 21, 16, 33, 0, 45, 0, 0,
-  4, 0, 0, 27, 0, 0, 0, 13, 0, 62,
-  0, 3, 0, 70, 16, 0, 32, 0, 0, 0,
-  21, 64, 8, 79, 0, 0, 0, 31, 0, 20,
-  0, 0, 0, 0, 0, 0, 49, 0, 44, 0,
-  0, 0, 0, 2, 62, 0, 0, 25, 0, 37,
-  50, 81, 8, 1, 28, 19, 26, 9, 59, 14,
-  0, 0, 0, 31, 0, 46, 17, 31, 61, 56,
-  0, 0, 3, 0, 4, 0, 0, 6, 50, 28,
-  14, 0, 0, 0, 10, 0, 0, 0, 0, 0,
-  7, 1, 83, 0, 80, 2, 9, 0, 0, 25,
-  11, 47, 41, 0, 0, 5, 47, 1, 0, 16,
-  5, 75, 19, 28, 49, 26, 0, 33, 25, 0,
-  0, 0, 18, 25, 0, 34, 0, 0, 0, 0,
-  0, 42, 0, 0, 0, 16, 0, 27, 0, 0,
-  0, 56, 0, 7, 36, 0, 0, 0, 0, 20,
-  0, 61, 0, 0, 3, 18, 0, 21, 2, 0,
-  0, 0, 0, 0, 62, 6, 75, 21, 0, 0,
-  9, 9, 54, 0, 0, 53, 0, 0, 29, 74,
-  8, 11, 30, 30, 27, 34, 17, 0, 0, 29,
-  0, 0, 22, 13, 14, 0, 41, 57, 0, 6,
-  0, 0, 3, 28, 0, 7, 12, 5, 0, 0,
-  0, 6, 0, 0, 0, 0, 0, 0, 0, 0,
-  32, 0, 54, 11, 27, 0, 0, 16, 49, 37,
-  80, 0, 0, 1, 64, 3, 2, 0, 54, 91,
-  27, 51, 45, 0, 0, 9, 23, 0, 0, 27,
-  0, 25, 0, 38, 0, 3, 12, 0, 0, 38,
-  0, 0, 0, 15, 0, 58, 0, 15, 0, 46,
-  0, 0, 33, 9, 0, 0, 4, 73, 21, 61,
-  0, 0, 0, 51, 0, 15, 0, 0, 0, 0,
-  0, 0, 58, 0, 53, 0, 0, 0, 0, 25,
-  36, 0, 0, 19, 0, 23, 49, 49, 13, 0,
-  41, 40, 36, 29, 68, 0, 0, 29, 0, 26,
-  0, 29, 0, 0, 3, 71, 0, 0, 0, 0,
-  0, 0, 0, 17, 24, 30, 27, 0, 0, 0,
-  28, 0, 19, 0, 0, 0, 24, 0, 70, 0,
-  63, 3, 0, 0, 0, 17, 93, 43, 53, 0,
-  0, 8, 55, 26, 0, 0, 17, 57, 20, 55,
-  57, 27, 0, 29, 14, 0, 0, 5, 16, 11,
-  6, 56, 0, 0, 0, 0, 0, 8, 0, 0,
-  0, 41, 0, 41, 0, 0, 0, 42, 0, 5,
-  36, 0, 0, 0, 2, 40, 0, 36, 0, 0,
-  0, 42, 0, 17, 0, 0, 0, 0, 0, 0,
-  82, 0, 42, 17, 0, 0, 1, 48, 33, 0,
-  0, 61, 0, 0, 38, 68, 6, 58, 20, 52,
-  28, 25, 45, 0, 0, 24, 0, 24, 0, 8,
-  0, 6, 4, 57, 8, 0, 0, 0, 0, 2,
-  0, 5, 16, 36, 9, 0, 0, 0, 13, 0,
-  5, 0, 0, 0, 0, 0, 58, 0, 58, 12,
-  0, 0, 0, 24, 81, 40, 49, 0, 0, 0,
-  33, 2, 0, 17, 6, 77, 0, 0, 23, 56,
-  0, 52, 2, 0, 2, 1, 41, 13, 0, 29,
-  0, 0, 0, 10, 0, 43, 0, 0, 0, 63,
-  12, 17, 0, 0, 3, 48, 0, 11, 71, 0,
-  0, 0, 6, 7, 0, 21, 0, 0, 0, 19,
-  2, 14, 27, 0, 4, 0, 42, 0, 75, 3,
-  41, 71, 0, 0, 6, 9, 38, 0, 0, 42,
-  14, 0, 7, 92, 0, 60, 38, 46, 56, 57,
-  34, 0, 0, 15, 0, 1, 11, 17, 0, 0,
-  0, 26, 10, 3, 0, 0, 0, 39, 0, 3,
-  0, 23, 0, 0, 0, 14, 4, 15, 2, 36,
-  0, 0, 0, 0, 0, 0, 48, 33, 15, 0,
-  30, 0, 17, 10, 31, 0, 0, 0, 35, 0,
-  0, 3, 12, 104, 13, 0, 18, 16, 0, 5,
-  51, 0, 33, 3, 0, 0, 0, 16, 0, 15,
-  0, 9, 0, 7, 0, 0, 0, 0, 0, 7,
-  0, 12, 0, 50, 13, 0, 0, 0, 0, 0,
-  32, 102, 0, 61, 0, 0, 22, 15, 0, 0,
-  0, 0, 29, 0, 32, 22, 10, 15, 12, 12,
-  0, 0, 0, 0, 42, 0, 0, 0, 0, 33,
-  26, 38, 0, 3, 31, 0, 30, 10, 63, 12,
-  0, 0, 0, 0, 0, 25, 23, 0, 69, 64,
-  0, 0, 2, 0, 4, 5, 0, 9, 49, 0,
-  33, 0, 0, 3, 60, 0, 68, 0, 0, 0,
-  8, 0, 0, 0, 49, 3, 11, 0, 0, 22,
-  0, 46, 29, 0, 0, 10, 69, 0, 0, 23,
-  38, 83, 24, 20, 35, 2, 0, 9, 58, 0,
-  0, 0, 4, 48, 0, 23, 0, 8, 10, 0,
-  0, 43, 1, 0, 0, 4, 0, 24, 0, 21,
-  0, 69, 0, 0, 10, 17, 0, 0, 39, 72,
-  4, 92, 0, 0, 6, 27, 0, 37, 0, 0,
-  0, 0, 0, 8, 23, 24, 37, 0, 0, 3,
-  0, 0, 58, 0, 0, 14, 0, 39, 58, 70,
-  0, 0, 36, 5, 31, 21, 43, 20, 8, 4,
-  0, 16, 0, 28, 38, 0, 72, 48, 0, 0,
-  6, 0, 2, 0, 0, 22, 64, 11, 22, 0,
-  0, 9, 42, 0, 28, 0, 0, 0, 25, 29,
-  79, 0, 79, 5, 10, 0, 0, 19, 0, 49,
-  12, 0, 0, 25, 85, 2, 1, 7, 23, 85,
-  32, 34, 52, 0, 5, 0, 23, 0, 0, 0,
-  0, 25, 0, 34, 0, 0, 0, 0, 0, 25,
-  0, 0, 0, 0, 0, 23, 0, 6, 0, 46,
-  0, 0, 22, 18, 0, 0, 24, 75, 20, 83,
-  0, 0, 0, 46, 0, 19, 0, 0, 0, 0,
-  0, 30, 41, 0, 59, 0, 0, 0, 0, 12,
-  50, 0, 0, 9, 0, 32, 59, 63, 9, 0,
-  17, 31, 16, 61, 46, 0, 20, 36, 0, 0,
-  0, 9, 42, 0, 48, 63, 0, 0, 0, 0,
-  9, 0, 0, 19, 28, 6, 15, 0, 0, 0,
-  28, 0, 22, 0, 0, 0, 15, 1, 73, 0,
-  78, 3, 7, 0, 0, 42, 26, 36, 66, 0,
-  0, 14, 62, 8, 0, 3, 37, 89, 51, 42,
-  59, 7, 0, 10, 42, 0, 0, 21, 16, 33,
-  0, 45, 0, 0, 4, 0, 0, 27, 0, 0,
-  0, 13, 0, 62, 0, 3, 0, 70, 16, 0,
-  32, 0, 0, 0, 21, 64, 8, 79, 0, 0,
-  0, 31, 0, 20, 0, 0, 0, 0, 0, 0,
-  49, 0, 44, 0, 0, 0, 0, 2, 62, 0,
-  0, 25, 0, 37, 50, 81, 8, 1, 28, 19,
-  26, 9, 59, 14, 0, 0, 0, 31, 0, 46,
-  17, 31, 61, 56, 0, 0, 3, 0, 4, 0,
-  0, 6, 50, 28, 14, 0, 0, 0, 10, 0,
-  0, 0, 0, 0, 7, 1, 83, 0, 80, 2,
-  9, 0, 0, 25, 11, 47, 41, 0, 0, 5,
-  47, 1, 0, 16, 5, 75, 19, 28, 49, 26,
-  0, 33, 25, 0, 0, 0, 18, 25, 0, 34,
-  0, 0, 0, 0, 0, 42, 0, 0, 0, 16,
-  0, 27, 0, 0, 0, 56, 0, 7, 36, 0,
-  0, 0, 0, 20, 0, 61, 0, 0, 3, 18,
-  0, 21, 2, 0, 0, 0, 0, 0, 62, 6,
-  75, 21, 0, 0, 9, 9, 54, 0, 0, 53,
-  0, 0, 29, 74, 8, 11, 30, 30, 27, 34,
-  17, 0, 0, 29, 0, 0, 22, 13, 14, 0,
-  41, 57, 0, 6, 0, 0, 3, 28, 0, 7,
-  12, 5, 0, 0, 0, 6, 0, 0, 0, 0,
-  0, 0, 0, 0, 32, 0, 54, 11, 27, 0,
-  0, 0, 0, 70, 0, 0, 0, 2, 33, 0,
-  0, 0, 0, 43, 0, 6, 22, 39, 0, 28,
-  7, 0, 9, 0, 0, 0, 28, 31, 0, 0,
-  0, 0, 0, 29, 0, 0, 2, 27, 0, 0,
-  0, 0, 0, 6, 0, 5, 36, 29, 18, 0,
-  0, 0, 0, 40, 0, 15, 23, 36, 0, 10,
-  8, 17, 0, 4, 56, 0, 56, 30, 68, 85,
-  5, 0, 19, 21, 32, 0, 0, 9, 20, 0,
-  0, 41, 10, 0, 11, 39, 17, 55, 0, 0,
-  0, 81, 0, 0, 54, 0, 6, 0, 21, 50,
-  24, 33, 0, 0, 0, 40, 0, 5, 0, 0,
-  0, 0, 0, 0, 7, 0, 7, 0, 0, 0,
-  0, 0, 0, 0, 0, 21, 20, 0, 0, 17,
-  93, 43, 53, 0, 0, 8, 55, 26, 0, 0,
-  17, 57, 20, 55, 57, 27, 0, 29, 14, 0,
-  0, 5, 16, 11, 6, 56, 0, 0, 0, 0,
-  0, 8, 0, 0, 0, 41, 0, 41, 0, 0,
-  0, 42, 0, 5, 36, 0, 0, 0, 2, 40,
-  0, 36, 0, 0, 0, 42, 0, 17, 0, 0,
-  0, 0, 0, 0, 82, 0, 42, 17, 0, 0,
-  1, 48, 33, 0, 0, 61, 0, 0, 38, 68,
-  6, 58, 20, 52, 28, 25, 45, 0, 0, 24,
-  0, 24, 0, 8, 0, 6, 4, 57, 8, 0,
-  0, 0, 0, 2, 0, 5, 16, 36, 9, 0,
-  0, 0, 13, 0, 5, 0, 0, 0, 0, 0,
-  58, 0, 58, 12, 0, 0, 0, 24, 81, 40,
-  49, 0, 0, 0, 33, 2, 0, 17, 6, 77,
-  0, 0, 23, 56, 0, 52, 2, 0, 2, 1,
-  41, 13, 0, 29, 0, 0, 0, 10, 0, 43,
-  0, 0, 0, 63, 12, 17, 0, 0, 3, 48,
-  0, 11, 71, 0, 0, 0, 6, 7, 0, 21,
-  0, 0, 0, 19, 2, 14, 27, 0, 4, 0,
-  42, 0, 75, 3, 41, 71, 0, 0, 6, 9,
-  38, 0, 0, 42, 14, 0, 7, 92, 0, 60,
-  38, 46, 56, 57, 34, 0, 0, 15, 0, 1,
-  11, 17, 0, 0, 0, 26, 10, 3, 0, 0,
-  0, 39, 0, 3, 0, 23, 0, 0, 0, 14,
-  4, 15, 2, 36, 0, 0, 0, 0, 0, 0,
-  48, 33, 15, 0, 8, 39, 11, 59, 13, 4,
-  0, 0, 0, 0, 0, 12, 0, 75, 0, 0,
-  1, 65, 7, 50, 0, 0, 29, 0, 35, 15,
-  32, 17, 0, 0, 0, 20, 0, 56, 0, 0,
-  11, 51, 0, 0, 0, 0, 4, 4, 0, 24,
-  76, 35, 6, 0, 0, 0, 0, 0, 0, 0,
-  3, 20, 4, 30, 67, 17, 10, 0, 41, 0,
-  49, 47, 42, 68, 0, 0, 19, 0, 53, 0,
-  0, 1, 65, 0, 0, 87, 0, 24, 26, 31,
-  55, 42, 0, 0, 0, 24, 7, 17, 41, 0,
-  0, 12, 27, 0, 0, 75, 0, 0, 0, 65,
-  4, 0, 0, 51, 0, 13, 0, 12, 0, 43,
-  0, 36, 11, 0, 10, 5, 0, 0, 0, 42,
-  34, 0, 0, 22, 0, 46, 29, 0, 0, 10,
-  69, 0, 0, 23, 38, 83, 24, 20, 35, 2,
-  0, 9, 58, 0, 0, 0, 4, 48, 0, 23,
-  0, 8, 10, 0, 0, 43, 1, 0, 0, 4,
-  0, 24, 0, 21, 0, 69, 0, 0, 10, 17,
-  0, 0, 39, 72, 4, 92, 0, 0, 6, 27,
-  0, 37, 0, 0, 0, 0, 0, 8, 23, 24,
-  37, 0, 0, 3, 0, 0, 58, 0, 0, 14,
-  0, 39, 58, 70, 0, 0, 36, 5, 31, 21,
-  43, 20, 8, 4, 0, 16, 0, 28, 38, 0,
-  72, 48, 0, 0, 6, 0, 2, 0, 0, 22,
-  64, 11, 22, 0, 0, 9, 42, 0, 28, 0,
-  0, 0, 25, 29, 79, 0, 79, 5, 10, 0,
-  0, 19, 0, 49, 12, 0, 0, 25, 85, 2,
-  1, 7, 23, 85, 32, 34, 52, 0, 5, 0,
-  23, 0, 0, 0, 0, 25, 0, 34, 0, 0,
-  0, 0, 0, 25, 0, 0, 0, 0, 0, 23,
-  0, 6, 0, 46, 0, 0, 22, 18, 0, 0,
-  24, 75, 20, 83, 0, 0, 0, 46, 0, 19,
-  0, 0, 0, 0, 0, 30, 41, 0, 59, 0,
-  0, 0, 0, 12, 50, 0, 0, 9, 0, 32,
-  59, 63, 9, 0, 17, 31, 16, 61, 46, 0,
-  20, 36, 0, 0, 0, 9, 42, 0, 48, 63,
-  0, 0, 0, 0, 9, 0, 0, 19, 28, 6,
-  15, 0, 0, 0, 28, 0, 22, 0, 0, 0,
-  15, 1, 73, 0, 78, 3, 7, 0, 0, 4,
-  2, 46, 13, 0, 0, 32, 107, 4, 2, 0,
-  4, 83, 44, 32, 46, 4, 0, 0, 3, 0,
-  0, 10, 0, 0, 0, 35, 0, 0, 0, 0,
-  0, 15, 0, 0, 0, 0, 0, 24, 0, 0,
-  0, 32, 0, 0, 49, 17, 0, 0, 0, 80,
-  25, 73, 0, 0, 0, 50, 0, 3, 0, 0,
-  0, 0, 0, 35, 49, 0, 61, 9, 0, 0,
-  3, 17, 57, 9, 0, 0, 0, 10, 48, 46,
-  9, 0, 7, 32, 17, 79, 43, 0, 37, 35,
-  0, 0, 0, 5, 31, 0, 49, 67, 11, 1,
-  0, 0, 15, 0, 0, 19, 8, 3, 5, 0,
-  0, 0, 19, 0, 26, 0, 0, 0, 5, 0,
-  65, 0, 62, 0, 2, 0, 0, 25, 11, 47,
-  41, 0, 0, 5, 47, 1, 0, 16, 5, 75,
-  19, 28, 49, 26, 0, 33, 25, 0, 0, 0,
-  18, 25, 0, 34, 0, 0, 0, 0, 0, 42,
-  0, 0, 0, 16, 0, 27, 0, 0, 0, 56,
-  0, 7, 36, 0, 0, 0, 0, 20, 0, 61,
-  0, 0, 3, 18, 0, 21, 2, 0, 0, 0,
-  0, 0, 62, 6, 75, 21, 0, 0, 9, 9,
-  54, 0, 0, 53, 0, 0, 29, 74, 8, 11,
-  30, 30, 27, 34, 17, 0, 0, 29, 0, 0,
-  22, 13, 14, 0, 41, 57, 0, 6, 0, 0,
-  3, 28, 0, 7, 12, 5, 0, 0, 0, 6,
-  0, 0, 0, 0, 0, 0, 0, 0, 32, 0,
-  54, 11, 27, 0, 0, 0, 0, 70, 0, 0,
-  0, 2, 33, 0, 0, 0, 0, 43, 0, 6,
-  22, 39, 0, 28, 7, 0, 9, 0, 0, 0,
-  28, 31, 0, 0, 0, 0, 0, 29, 0, 0,
-  2, 27, 0, 0, 0, 0, 0, 6, 0, 5,
-  36, 29, 18, 0, 0, 0, 0, 40, 0, 15,
-  23, 36, 0, 10, 8, 17, 0, 4, 56, 0,
-  56, 30, 68, 85, 5, 0, 19, 21, 32, 0,
-  0, 9, 20, 0, 0, 41, 10, 0, 11, 39,
-  17, 55, 0, 0, 0, 81, 0, 0, 54, 0,
-  6, 0, 21, 50, 24, 33, 0, 0, 0, 40,
-  0, 5, 0, 0, 0, 0, 0, 0, 7, 0,
-  7, 0, 0, 0, 0, 0, 0, 0, 0, 21,
-  20, 0, 0, 8, 0, 102, 1, 0, 0, 14,
-  69, 27, 0, 0, 0, 1, 0, 66, 27, 37,
-  0, 17, 6, 0, 0, 0, 2, 0, 52, 58,
-  12, 0, 0, 0, 14, 27, 0, 0, 6, 45,
-  0, 0, 2, 0, 0, 11, 0, 17, 56, 34,
-  0, 0, 0, 0, 2, 38, 0, 25, 6, 68,
-  0, 37, 0, 16, 0, 2, 22, 0, 50, 18,
-  67, 47, 0, 0, 22, 50, 27, 21, 0, 3,
-  14, 0, 29, 40, 11, 0, 0, 47, 18, 59,
-  13, 0, 37, 101, 0, 22, 37, 0, 12, 0,
-  20, 34, 37, 0, 0, 0, 4, 0, 0, 14,
-  0, 6, 0, 13, 0, 0, 10, 0, 0, 0,
-  0, 0, 4, 0, 56, 0, 21, 28, 9, 0,
-  0, 24, 81, 40, 49, 0, 0, 0, 33, 2,
-  0, 17, 6, 77, 0, 0, 23, 56, 0, 52,
-  2, 0, 2, 1, 41, 13, 0, 29, 0, 0,
-  0, 10, 0, 43, 0, 0, 0, 63, 12, 17,
-  0, 0, 3, 48, 0, 11, 71, 0, 0, 0,
-  6, 7, 0, 21, 0, 0, 0, 19, 2, 14,
-  27, 0, 4, 0, 42, 0, 75, 3, 41, 71,
-  0, 0, 6, 9, 38, 0, 0, 42, 14, 0,
-  7, 92, 0, 60, 38, 46, 56, 57, 34, 0,
-  0, 15, 0, 1, 11, 17, 0, 0, 0, 26,
-  10, 3, 0, 0, 0, 39, 0, 3, 0, 23,
-  0, 0, 0, 14, 4, 15, 2, 36, 0, 0,
-  0, 0, 0, 0, 48, 33, 15, 0, 8, 39,
-  11, 59, 13, 4, 0, 0, 0, 0, 0, 12,
-  0, 75, 0, 0, 1, 65, 7, 50, 0, 0,
-  29, 0, 35, 15, 32, 17, 0, 0, 0, 20,
-  0, 56, 0, 0, 11, 51, 0, 0, 0, 0,
-  4, 4, 0, 24, 76, 35, 6, 0, 0, 0,
-  0, 0, 0, 0, 3, 20, 4, 30, 67, 17,
-  10, 0, 41, 0, 49, 47, 42, 68, 0, 0,
-  19, 0, 53, 0, 0, 1, 65, 0, 0, 87,
-  0, 24, 26, 31, 55, 42, 0, 0, 0, 24,
-  7, 17, 41, 0, 0, 12, 27, 0, 0, 75,
-  0, 0, 0, 65, 4, 0, 0, 51, 0, 13,
-  0, 12, 0, 43, 0, 36, 11, 0, 10, 5,
-  0, 0, 0, 42, 34, 0, 17, 15, 0, 79,
-  44, 0, 0, 0, 5, 0, 0, 0, 0, 55,
-  0, 0, 0, 35, 37, 28, 4, 0, 0, 0,
-  32, 0, 63, 0, 0, 0, 16, 16, 0, 50,
-  0, 12, 49, 23, 0, 0, 6, 0, 13, 0,
-  0, 14, 60, 14, 0, 0, 0, 0, 0, 1,
-  0, 30, 1, 49, 0, 8, 60, 30, 25, 6,
-  43, 0, 30, 41, 42, 56, 0, 0, 32, 5,
-  13, 0, 0, 18, 85, 0, 0, 46, 31, 7,
-  39, 35, 18, 32, 4, 0, 0, 59, 8, 21,
-  49, 0, 0, 0, 34, 1, 3, 39, 0, 0,
-  0, 65, 0, 8, 0, 14, 0, 11, 0, 5,
-  35, 42, 0, 21, 0, 9, 13, 0, 0, 0,
-  0, 31, 11, 3, 0, 19, 0, 49, 12, 0,
-  0, 25, 85, 2, 1, 7, 23, 85, 32, 34,
-  52, 0, 5, 0, 23, 0, 0, 0, 0, 25,
-  0, 34, 0, 0, 0, 0, 0, 25, 0, 0,
-  0, 0, 0, 23, 0, 6, 0, 46, 0, 0,
-  22, 18, 0, 0, 24, 75, 20, 83, 0, 0,
-  0, 46, 0, 19, 0, 0, 0, 0, 0, 30,
-  41, 0, 59, 0, 0, 0, 0, 12, 50, 0,
-  0, 9, 0, 32, 59, 63, 9, 0, 17, 31,
-  16, 61, 46, 0, 20, 36, 0, 0, 0, 9,
-  42, 0, 48, 63, 0, 0, 0, 0, 9, 0,
-  0, 19, 28, 6, 15, 0, 0, 0, 28, 0,
-  22, 0, 0, 0, 15, 1, 73, 0, 78, 3,
-  7, 0, 0, 4, 2, 46, 13, 0, 0, 32,
-  107, 4, 2, 0, 4, 83, 44, 32, 46, 4,
-  0, 0, 3, 0, 0, 10, 0, 0, 0, 35,
-  0, 0, 0, 0, 0, 15, 0, 0, 0, 0,
-  0, 24, 0, 0, 0, 32, 0, 0, 49, 17,
-  0, 0, 0, 80, 25, 73, 0, 0, 0, 50,
-  0, 3, 0, 0, 0, 0, 0, 35, 49, 0,
-  61, 9, 0, 0, 3, 17, 57, 9, 0, 0,
-  0, 10, 48, 46, 9, 0, 7, 32, 17, 79,
-  43, 0, 37, 35, 0, 0, 0, 5, 31, 0,
-  49, 67, 11, 1, 0, 0, 15, 0, 0, 19,
-  8, 3, 5, 0, 0, 0, 19, 0, 26, 0,
-  0, 0, 5, 0, 65, 0, 62, 0, 2, 0,
-  0, 37, 0, 44, 22, 0, 8, 20, 82, 0,
-  25, 11, 12, 56, 55, 36, 59, 22, 0, 12,
-  31, 0, 0, 0, 1, 27, 0, 18, 0, 0,
-  0, 0, 0, 37, 0, 0, 0, 0, 0, 14,
-  0, 0, 0, 28, 0, 0, 38, 1, 0, 0,
-  0, 23, 0, 87, 0, 0, 4, 32, 0, 38,
-  0, 0, 0, 0, 0, 27, 62, 7, 79, 0,
-  0, 0, 0, 8, 73, 0, 0, 19, 6, 1,
-  28, 74, 0, 0, 22, 50, 31, 43, 10, 0,
-  10, 37, 0, 20, 0, 33, 31, 10, 59, 36,
-  0, 0, 0, 0, 17, 0, 0, 13, 9, 1,
-  0, 0, 0, 0, 9, 0, 0, 0, 0, 0,
-  0, 23, 74, 0, 31, 0, 36, 0, 0, 0,
-  0, 70, 0, 0, 0, 2, 33, 0, 0, 0,
-  0, 43, 0, 6, 22, 39, 0, 28, 7, 0,
-  9, 0, 0, 0, 28, 31, 0, 0, 0, 0,
-  0, 29, 0, 0, 2, 27, 0, 0, 0, 0,
-  0, 6, 0, 5, 36, 29, 18, 0, 0, 0,
-  0, 40, 0, 15, 23, 36, 0, 10, 8, 17,
-  0, 4, 56, 0, 56, 30, 68, 85, 5, 0,
-  19, 21, 32, 0, 0, 9, 20, 0, 0, 41,
-  10, 0, 11, 39, 17, 55, 0, 0, 0, 81,
-  0, 0, 54, 0, 6, 0, 21, 50, 24, 33,
-  0, 0, 0, 40, 0, 5, 0, 0, 0, 0,
-  0, 0, 7, 0, 7, 0, 0, 0, 0, 0,
-  0, 0, 0, 21, 20, 0, 0, 8, 0, 102,
-  1, 0, 0, 14, 69, 27, 0, 0, 0, 1,
-  0, 66, 27, 37, 0, 17, 6, 0, 0, 0,
-  2, 0, 52, 58, 12, 0, 0, 0, 14, 27,
-  0, 0, 6, 45, 0, 0, 2, 0, 0, 11,
-  0, 17, 56, 34, 0, 0, 0, 0, 2, 38,
-  0, 25, 6, 68, 0, 37, 0, 16, 0, 2,
-  22, 0, 50, 18, 67, 47, 0, 0, 22, 50,
-  27, 21, 0, 3, 14, 0, 29, 40, 11, 0,
-  0, 47, 18, 59, 13, 0, 37, 101, 0, 22,
-  37, 0, 12, 0, 20, 34, 37, 0, 0, 0,
-  4, 0, 0, 14, 0, 6, 0, 13, 0, 0,
-  10, 0, 0, 0, 0, 0, 4, 0, 56, 0,
-  21, 28, 9, 0, 0, 56, 17, 88, 0, 0,
-  31, 9, 81, 2, 5, 0, 0, 6, 2, 91,
-  38, 27, 0, 41, 0, 0, 0, 0, 13, 0,
-  37, 42, 0, 0, 0, 2, 9, 19, 0, 0,
-  16, 37, 0, 0, 16, 0, 0, 26, 0, 16,
-  70, 3, 0, 0, 0, 0, 0, 52, 0, 0,
-  15, 62, 0, 58, 0, 17, 0, 7, 22, 0,
-  63, 23, 93, 25, 0, 0, 31, 35, 54, 3,
-  0, 8, 19, 0, 32, 63, 17, 6, 25, 64,
-  9, 35, 25, 0, 32, 85, 0, 27, 5, 0,
-  11, 0, 41, 54, 31, 0, 0, 0, 12, 3,
-  0, 31, 0, 0, 0, 17, 0, 0, 32, 0,
-  0, 0, 0, 0, 0, 0, 65, 0, 25, 16,
-  30, 0, 8, 39, 11, 59, 13, 4, 0, 0,
-  0, 0, 0, 12, 0, 75, 0, 0, 1, 65,
-  7, 50, 0, 0, 29, 0, 35, 15, 32, 17,
-  0, 0, 0, 20, 0, 56, 0, 0, 11, 51,
-  0, 0, 0, 0, 4, 4, 0, 24, 76, 35,
-  6, 0, 0, 0, 0, 0, 0, 0, 3, 20,
-  4, 30, 67, 17, 10, 0, 41, 0, 49, 47,
-  42, 68, 0, 0, 19, 0, 53, 0, 0, 1,
-  65, 0, 0, 87, 0, 24, 26, 31, 55, 42,
-  0, 0, 0, 24, 7, 17, 41, 0, 0, 12,
-  27, 0, 0, 75, 0, 0, 0, 65, 4, 0,
-  0, 51, 0, 13, 0, 12, 0, 43, 0, 36,
-  11, 0, 10, 5, 0, 0, 0, 42, 34, 0,
-  17, 15, 0, 79, 44, 0, 0, 0, 5, 0,
-  0, 0, 0, 55, 0, 0, 0, 35, 37, 28,
-  4, 0, 0, 0, 32, 0, 63, 0, 0, 0,
-  16, 16, 0, 50, 0, 12, 49, 23, 0, 0,
-  6, 0, 13, 0, 0, 14, 60, 14, 0, 0,
-  0, 0, 0, 1, 0, 30, 1, 49, 0, 8,
-  60, 30, 25, 6, 43, 0, 30, 41, 42, 56,
-  0, 0, 32, 5, 13, 0, 0, 18, 85, 0,
-  0, 46, 31, 7, 39, 35, 18, 32, 4, 0,
-  0, 59, 8, 21, 49, 0, 0, 0, 34, 1,
-  3, 39, 0, 0, 0, 65, 0, 8, 0, 14,
-  0, 11, 0, 5, 35, 42, 0, 21, 0, 9,
-  13, 0, 0, 0, 0, 31, 11, 3, 0, 52,
-  10, 53, 45, 0, 0, 0, 8, 0, 0, 0,
-  0, 74, 0, 0, 0, 0, 17, 52, 3, 0,
-  18, 7, 0, 0, 31, 0, 0, 0, 23, 43,
-  0, 29, 0, 19, 52, 39, 0, 0, 56, 0,
-  8, 9, 0, 0, 56, 49, 5, 0, 28, 0,
-  0, 0, 24, 0, 37, 43, 61, 0, 18, 41,
-  48, 0, 82, 16, 8, 42, 39, 40, 0, 0,
-  47, 0, 25, 13, 0, 0, 67, 0, 0, 21,
-  0, 18, 51, 32, 4, 15, 16, 0, 0, 74,
-  15, 0, 13, 0, 0, 0, 53, 45, 10, 84,
-  0, 0, 0, 82, 0, 44, 0, 0, 0, 0,
-  0, 19, 65, 68, 0, 14, 8, 17, 0, 0,
-  0, 0, 0, 9, 3, 4, 0, 4, 2, 46,
-  13, 0, 0, 32, 107, 4, 2, 0, 4, 83,
-  44, 32, 46, 4, 0, 0, 3, 0, 0, 10,
-  0, 0, 0, 35, 0, 0, 0, 0, 0, 15,
-  0, 0, 0, 0, 0, 24, 0, 0, 0, 32,
-  0, 0, 49, 17, 0, 0, 0, 80, 25, 73,
-  0, 0, 0, 50, 0, 3, 0, 0, 0, 0,
-  0, 35, 49, 0, 61, 9, 0, 0, 3, 17,
-  57, 9, 0, 0, 0, 10, 48, 46, 9, 0,
-  7, 32, 17, 79, 43, 0, 37, 35, 0, 0,
-  0, 5, 31, 0, 49, 67, 11, 1, 0, 0,
-  15, 0, 0, 19, 8, 3, 5, 0, 0, 0,
-  19, 0, 26, 0, 0, 0, 5, 0, 65, 0,
-  62, 0, 2, 0, 0, 37, 0, 44, 22, 0,
-  8, 20, 82, 0, 25, 11, 12, 56, 55, 36,
-  59, 22, 0, 12, 31, 0, 0, 0, 1, 27,
-  0, 18, 0, 0, 0, 0, 0, 37, 0, 0,
-  0, 0, 0, 14, 0, 0, 0, 28, 0, 0,
-  38, 1, 0, 0, 0, 23, 0, 87, 0, 0,
-  4, 32, 0, 38, 0, 0, 0, 0, 0, 27,
-  62, 7, 79, 0, 0, 0, 0, 8, 73, 0,
-  0, 19, 6, 1, 28, 74, 0, 0, 22, 50,
-  31, 43, 10, 0, 10, 37, 0, 20, 0, 33,
-  31, 10, 59, 36, 0, 0, 0, 0, 17, 0,
-  0, 13, 9, 1, 0, 0, 0, 0, 9, 0,
-  0, 0, 0, 0, 0, 23, 74, 0, 31, 0,
-  36, 0, 0, 74, 18, 48, 36, 0, 9, 0,
-  60, 0, 36, 0, 0, 63, 66, 33, 53, 1,
-  1, 40, 5, 0, 0, 0, 0, 29, 0, 0,
-  0, 0, 0, 0, 0, 33, 0, 0, 0, 0,
-  0, 13, 0, 0, 0, 7, 0, 0, 40, 19,
-  0, 0, 0, 0, 0, 107, 0, 0, 12, 52,
-  0, 31, 0, 27, 0, 0, 0, 19, 66, 8,
-  85, 0, 0, 0, 0, 0, 65, 0, 0, 12,
-  15, 13, 23, 55, 0, 0, 38, 70, 22, 57,
-  6, 0, 10, 41, 0, 20, 0, 27, 34, 9,
-  25, 65, 0, 0, 0, 0, 11, 0, 0, 0,
-  15, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 46, 0, 22, 0, 42, 0,
-  0, 8, 0, 102, 1, 0, 0, 14, 69, 27,
-  0, 0, 0, 1, 0, 66, 27, 37, 0, 17,
-  6, 0, 0, 0, 2, 0, 52, 58, 12, 0,
-  0, 0, 14, 27, 0, 0, 6, 45, 0, 0,
-  2, 0, 0, 11, 0, 17, 56, 34, 0, 0,
-  0, 0, 2, 38, 0, 25, 6, 68, 0, 37,
-  0, 16, 0, 2, 22, 0, 50, 18, 67, 47,
-  0, 0, 22, 50, 27, 21, 0, 3, 14, 0,
-  29, 40, 11, 0, 0, 47, 18, 59, 13, 0,
-  37, 101, 0, 22, 37, 0, 12, 0, 20, 34,
-  37, 0, 0, 0, 4, 0, 0, 14, 0, 6,
-  0, 13, 0, 0, 10, 0, 0, 0, 0, 0,
-  4, 0, 56, 0, 21, 28, 9, 0, 0, 56,
-  17, 88, 0, 0, 31, 9, 81, 2, 5, 0,
-  0, 6, 2, 91, 38, 27, 0, 41, 0, 0,
-  0, 0, 13, 0, 37, 42, 0, 0, 0, 2,
-  9, 19, 0, 0, 16, 37, 0, 0, 16, 0,
-  0, 26, 0, 16, 70, 3, 0, 0, 0, 0,
-  0, 52, 0, 0, 15, 62, 0, 58, 0, 17,
-  0, 7, 22, 0, 63, 23, 93, 25, 0, 0,
-  31, 35, 54, 3, 0, 8, 19, 0, 32, 63,
-  17, 6, 25, 64, 9, 35, 25, 0, 32, 85,
-  0, 27, 5, 0, 11, 0, 41, 54, 31, 0,
-  0, 0, 12, 3, 0, 31, 0, 0, 0, 17,
-  0, 0, 32, 0, 0, 0, 0, 0, 0, 0,
-  65, 0, 25, 16, 30, 0, 0, 28, 8, 32,
-  27, 0, 2, 0, 68, 0, 19, 0, 0, 42,
-  7, 49, 43, 15, 20, 47, 0, 0, 0, 0,
-  0, 0, 3, 32, 0, 0, 0, 6, 4, 23,
-  0, 12, 7, 21, 0, 0, 2, 0, 0, 18,
-  0, 11, 54, 50, 0, 0, 0, 0, 0, 40,
-  0, 0, 45, 53, 0, 11, 0, 42, 0, 0,
-  22, 4, 38, 14, 110, 11, 16, 0, 30, 15,
-  57, 0, 0, 0, 2, 0, 0, 18, 21, 0,
-  59, 45, 0, 63, 2, 0, 3, 85, 0, 10,
-  16, 0, 9, 0, 31, 80, 7, 29, 0, 0,
-  22, 22, 0, 19, 0, 0, 0, 25, 0, 0,
-  16, 0, 0, 0, 0, 0, 0, 0, 11, 0,
-  0, 5, 46, 8, 17, 15, 0, 79, 44, 0,
-  0, 0, 5, 0, 0, 0, 0, 55, 0, 0,
-  0, 35, 37, 28, 4, 0, 0, 0, 32, 0,
-  63, 0, 0, 0, 16, 16, 0, 50, 0, 12,
-  49, 23, 0, 0, 6, 0, 13, 0, 0, 14,
-  60, 14, 0, 0, 0, 0, 0, 1, 0, 30,
-  1, 49, 0, 8, 60, 30, 25, 6, 43, 0,
-  30, 41, 42, 56, 0, 0, 32, 5, 13, 0,
-  0, 18, 85, 0, 0, 46, 31, 7, 39, 35,
-  18, 32, 4, 0, 0, 59, 8, 21, 49, 0,
-  0, 0, 34, 1, 3, 39, 0, 0, 0, 65,
-  0, 8, 0, 14, 0, 11, 0, 5, 35, 42,
-  0, 21, 0, 9, 13, 0, 0, 0, 0, 31,
-  11, 3, 0, 52, 10, 53, 45, 0, 0, 0,
-  8, 0, 0, 0, 0, 74, 0, 0, 0, 0,
-  17, 52, 3, 0, 18, 7, 0, 0, 31, 0,
-  0, 0, 23, 43, 0, 29, 0, 19, 52, 39,
-  0, 0, 56, 0, 8, 9, 0, 0, 56, 49,
-  5, 0, 28, 0, 0, 0, 24, 0, 37, 43,
-  61, 0, 18, 41, 48, 0, 82, 16, 8, 42,
-  39, 40, 0, 0, 47, 0, 25, 13, 0, 0,
-  67, 0, 0, 21, 0, 18, 51, 32, 4, 15,
-  16, 0, 0, 74, 15, 0, 13, 0, 0, 0,
-  53, 45, 10, 84, 0, 0, 0, 82, 0, 44,
-  0, 0, 0, 0, 0, 19, 65, 68, 0, 14,
-  8, 17, 0, 0, 0, 0, 0, 9, 3, 4,
-  0, 23, 27, 4, 12, 35, 0, 0, 0, 0,
-  7, 0, 0, 120, 0, 0, 0, 0, 0, 71,
-  1, 19, 66, 22, 0, 0, 0, 5, 0, 8,
-  4, 39, 0, 29, 0, 44, 65, 31, 0, 0,
-  54, 58, 0, 12, 0, 0, 47, 155, 11, 0,
-  50, 0, 0, 0, 45, 0, 62, 10, 71, 0,
-  0, 39, 35, 0, 91, 27, 0, 65, 34, 36,
-  0, 34, 14, 0, 51, 0, 0, 0, 19, 4,
-  0, 0, 14, 6, 95, 9, 0, 30, 0, 0,
-  0, 23, 0, 0, 8, 0, 0, 0, 51, 94,
-  0, 92, 0, 0, 16, 61, 0, 33, 0, 0,
-  0, 0, 0, 0, 47, 97, 0, 7, 27, 0,
-  4, 0, 0, 0, 0, 0, 0, 77, 0, 37,
-  0, 44, 22, 0, 8, 20, 82, 0, 25, 11,
-  12, 56, 55, 36, 59, 22, 0, 12, 31, 0,
-  0, 0, 1, 27, 0, 18, 0, 0, 0, 0,
-  0, 37, 0, 0, 0, 0, 0, 14, 0, 0,
-  0, 28, 0, 0, 38, 1, 0, 0, 0, 23,
-  0, 87, 0, 0, 4, 32, 0, 38, 0, 0,
-  0, 0, 0, 27, 62, 7, 79, 0, 0, 0,
-  0, 8, 73, 0, 0, 19, 6, 1, 28, 74,
-  0, 0, 22, 50, 31, 43, 10, 0, 10, 37,
-  0, 20, 0, 33, 31, 10, 59, 36, 0, 0,
-  0, 0, 17, 0, 0, 13, 9, 1, 0, 0,
-  0, 0, 9, 0, 0, 0, 0, 0, 0, 23,
-  74, 0, 31, 0, 36, 0, 0, 74, 18, 48,
-  36, 0, 9, 0, 60, 0, 36, 0, 0, 63,
-  66, 33, 53, 1, 1, 40, 5, 0, 0, 0,
-  0, 29, 0, 0, 0, 0, 0, 0, 0, 33,
-  0, 0, 0, 0, 0, 13, 0, 0, 0, 7,
-  0, 0, 40, 19, 0, 0, 0, 0, 0, 107,
-  0, 0, 12, 52, 0, 31, 0, 27, 0, 0,
-  0, 19, 66, 8, 85, 0, 0, 0, 0, 0,
-  65, 0, 0, 12, 15, 13, 23, 55, 0, 0,
-  38, 70, 22, 57, 6, 0, 10, 41, 0, 20,
-  0, 27, 34, 9, 25, 65, 0, 0, 0, 0,
-  11, 0, 0, 0, 15, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 46, 0,
-  22, 0, 42, 0, 0, 120, 19, 74, 27, 0,
-  31, 0, 61, 0, 8, 0, 21, 27, 26, 43,
-  32, 22, 11, 48, 0, 0, 11, 13, 20, 2,
-  39, 1, 0, 0, 0, 0, 45, 5, 15, 2,
-  0, 0, 0, 0, 0, 0, 0, 21, 0, 27,
-  87, 36, 0, 0, 16, 0, 0, 39, 0, 0,
-  30, 0, 0, 50, 0, 22, 0, 0, 0, 0,
-  32, 15, 38, 0, 0, 0, 27, 0, 82, 16,
-  0, 44, 0, 0, 23, 10, 32, 10, 15, 51,
-  24, 38, 8, 39, 22, 24, 0, 47, 0, 0,
-  15, 0, 42, 41, 18, 5, 0, 0, 5, 0,
-  39, 13, 35, 22, 0, 0, 0, 45, 0, 0,
-  0, 0, 9, 0, 0, 0, 49, 0, 6, 0,
-  21, 9, 0, 56, 17, 88, 0, 0, 31, 9,
-  81, 2, 5, 0, 0, 6, 2, 91, 38, 27,
-  0, 41, 0, 0, 0, 0, 13, 0, 37, 42,
-  0, 0, 0, 2, 9, 19, 0, 0, 16, 37,
-  0, 0, 16, 0, 0, 26, 0, 16, 70, 3,
-  0, 0, 0, 0, 0, 52, 0, 0, 15, 62,
-  0, 58, 0, 17, 0, 7, 22, 0, 63, 23,
-  93, 25, 0, 0, 31, 35, 54, 3, 0, 8,
-  19, 0, 32, 63, 17, 6, 25, 64, 9, 35,
-  25, 0, 32, 85, 0, 27, 5, 0, 11, 0,
-  41, 54, 31, 0, 0, 0, 12, 3, 0, 31,
-  0, 0, 0, 17, 0, 0, 32, 0, 0, 0,
-  0, 0, 0, 0, 65, 0, 25, 16, 30, 0,
-  0, 28, 8, 32, 27, 0, 2, 0, 68, 0,
-  19, 0, 0, 42, 7, 49, 43, 15, 20, 47,
-  0, 0, 0, 0, 0, 0, 3, 32, 0, 0,
-  0, 6, 4, 23, 0, 12, 7, 21, 0, 0,
-  2, 0, 0, 18, 0, 11, 54, 50, 0, 0,
-  0, 0, 0, 40, 0, 0, 45, 53, 0, 11,
-  0, 42, 0, 0, 22, 4, 38, 14, 110, 11,
-  16, 0, 30, 15, 57, 0, 0, 0, 2, 0,
-  0, 18, 21, 0, 59, 45, 0, 63, 2, 0,
-  3, 85, 0, 10, 16, 0, 9, 0, 31, 80,
-  7, 29, 0, 0, 22, 22, 0, 19, 0, 0,
-  0, 25, 0, 0, 16, 0, 0, 0, 0, 0,
-  0, 0, 11, 0, 0, 5, 46, 8, 7, 49,
-  61, 23, 56, 0, 23, 0, 71, 0, 0, 0,
-  14, 98, 16, 58, 20, 15, 28, 30, 7, 0,
-  10, 8, 0, 0, 0, 49, 0, 0, 0, 0,
-  0, 27, 0, 0, 0, 0, 0, 0, 17, 10,
-  0, 57, 0, 0, 54, 50, 0, 0, 31, 38,
-  0, 36, 0, 0, 23, 53, 0, 29, 0, 9,
-  0, 0, 24, 18, 14, 0, 53, 0, 0, 0,
-  18, 6, 59, 0, 0, 0, 0, 0, 21, 44,
-  0, 0, 68, 38, 3, 47, 64, 0, 0, 40,
-  0, 20, 0, 9, 7, 0, 28, 55, 0, 0,
-  1, 0, 35, 0, 0, 37, 14, 0, 22, 0,
-  0, 15, 86, 0, 0, 0, 20, 0, 12, 0,
-  13, 0, 9, 8, 46, 0, 0, 52, 10, 53,
-  45, 0, 0, 0, 8, 0, 0, 0, 0, 74,
-  0, 0, 0, 0, 17, 52, 3, 0, 18, 7,
-  0, 0, 31, 0, 0, 0, 23, 43, 0, 29,
-  0, 19, 52, 39, 0, 0, 56, 0, 8, 9,
-  0, 0, 56, 49, 5, 0, 28, 0, 0, 0,
-  24, 0, 37, 43, 61, 0, 18, 41, 48, 0,
-  82, 16, 8, 42, 39, 40, 0, 0, 47, 0,
-  25, 13, 0, 0, 67, 0, 0, 21, 0, 18,
-  51, 32, 4, 15, 16, 0, 0, 74, 15, 0,
-  13, 0, 0, 0, 53, 45, 10, 84, 0, 0,
-  0, 82, 0, 44, 0, 0, 0, 0, 0, 19,
-  65, 68, 0, 14, 8, 17, 0, 0, 0, 0,
-  0, 9, 3, 4, 0, 23, 27, 4, 12, 35,
-  0, 0, 0, 0, 7, 0, 0, 120, 0, 0,
-  0, 0, 0, 71, 1, 19, 66, 22, 0, 0,
-  0, 5, 0, 8, 4, 39, 0, 29, 0, 44,
-  65, 31, 0, 0, 54, 58, 0, 12, 0, 0,
-  47, 155, 11, 0, 50, 0, 0, 0, 45, 0,
-  62, 10, 71, 0, 0, 39, 35, 0, 91, 27,
-  0, 65, 34, 36, 0, 34, 14, 0, 51, 0,
-  0, 0, 19, 4, 0, 0, 14, 6, 95, 9,
-  0, 30, 0, 0, 0, 23, 0, 0, 8, 0,
-  0, 0, 51, 94, 0, 92, 0, 0, 16, 61,
-  0, 33, 0, 0, 0, 0, 0, 0, 47, 97,
-  0, 7, 27, 0, 4, 0, 0, 0, 0, 0,
-  0, 77, 45, 0, 33, 19, 45, 9, 0, 0,
-  4, 0, 2, 0, 45, 137, 0, 0, 0, 2,
-  10, 33, 44, 5, 15, 24, 0, 0, 11, 35,
-  0, 0, 0, 12, 0, 13, 0, 1, 6, 12,
-  0, 0, 8, 68, 0, 25, 0, 0, 28, 111,
-  8, 0, 44, 66, 0, 5, 0, 0, 15, 16,
-  0, 6, 0, 0, 27, 0, 53, 12, 0, 7,
-  33, 35, 0, 38, 0, 0, 31, 0, 0, 0,
-  0, 40, 0, 23, 24, 0, 54, 8, 0, 37,
-  61, 0, 0, 16, 0, 0, 0, 0, 30, 0,
-  25, 59, 0, 21, 4, 0, 13, 17, 0, 39,
-  33, 0, 20, 0, 0, 1, 63, 23, 29, 0,
-  0, 0, 72, 0, 0, 0, 0, 0, 0, 50,
-  0, 74, 18, 48, 36, 0, 9, 0, 60, 0,
-  36, 0, 0, 63, 66, 33, 53, 1, 1, 40,
-  5, 0, 0, 0, 0, 29, 0, 0, 0, 0,
-  0, 0, 0, 33, 0, 0, 0, 0, 0, 13,
-  0, 0, 0, 7, 0, 0, 40, 19, 0, 0,
-  0, 0, 0, 107, 0, 0, 12, 52, 0, 31,
-  0, 27, 0, 0, 0, 19, 66, 8, 85, 0,
-  0, 0, 0, 0, 65, 0, 0, 12, 15, 13,
-  23, 55, 0, 0, 38, 70, 22, 57, 6, 0,
-  10, 41, 0, 20, 0, 27, 34, 9, 25, 65,
-  0, 0, 0, 0, 11, 0, 0, 0, 15, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 46, 0, 22, 0, 42, 0, 0, 120,
-  19, 74, 27, 0, 31, 0, 61, 0, 8, 0,
-  21, 27, 26, 43, 32, 22, 11, 48, 0, 0,
-  11, 13, 20, 2, 39, 1, 0, 0, 0, 0,
-  45, 5, 15, 2, 0, 0, 0, 0, 0, 0,
-  0, 21, 0, 27, 87, 36, 0, 0, 16, 0,
-  0, 39, 0, 0, 30, 0, 0, 50, 0, 22,
-  0, 0, 0, 0, 32, 15, 38, 0, 0, 0,
-  27, 0, 82, 16, 0, 44, 0, 0, 23, 10,
-  32, 10, 15, 51, 24, 38, 8, 39, 22, 24,
-  0, 47, 0, 0, 15, 0, 42, 41, 18, 5,
-  0, 0, 5, 0, 39, 13, 35, 22, 0, 0,
-  0, 45, 0, 0, 0, 0, 9, 0, 0, 0,
-  49, 0, 6, 0, 21, 9, 64, 56, 7, 47,
-  47, 23, 0, 2, 27, 0, 0, 0, 42, 8,
-  0, 3, 0, 0, 56, 18, 0, 16, 26, 0,
-  2, 0, 57, 0, 1, 54, 0, 27, 23, 0,
-  74, 44, 54, 0, 12, 0, 0, 9, 0, 16,
-  14, 30, 64, 22, 0, 0, 0, 0, 0, 18,
-  39, 0, 31, 0, 0, 0, 0, 41, 29, 0,
-  11, 5, 0, 39, 0, 10, 75, 0, 74, 0,
-  24, 4, 0, 36, 30, 0, 0, 0, 49, 39,
-  40, 0, 0, 51, 36, 6, 0, 6, 0, 16,
-  0, 0, 38, 0, 41, 42, 30, 45, 15, 0,
-  0, 0, 5, 61, 41, 0, 5, 11, 0, 65,
-  38, 0, 0, 0, 29, 0, 0, 0, 0, 0,
-  0, 0, 8, 29, 0, 28, 8, 32, 27, 0,
-  2, 0, 68, 0, 19, 0, 0, 42, 7, 49,
-  43, 15, 20, 47, 0, 0, 0, 0, 0, 0,
-  3, 32, 0, 0, 0, 6, 4, 23, 0, 12,
-  7, 21, 0, 0, 2, 0, 0, 18, 0, 11,
-  54, 50, 0, 0, 0, 0, 0, 40, 0, 0,
-  45, 53, 0, 11, 0, 42, 0, 0, 22, 4,
-  38, 14, 110, 11, 16, 0, 30, 15, 57, 0,
-  0, 0, 2, 0, 0, 18, 21, 0, 59, 45,
-  0, 63, 2, 0, 3, 85, 0, 10, 16, 0,
-  9, 0, 31, 80, 7, 29, 0, 0, 22, 22,
-  0, 19, 0, 0, 0, 25, 0, 0, 16, 0,
-  0, 0, 0, 0, 0, 0, 11, 0, 0, 5,
-  46, 8, 7, 49, 61, 23, 56, 0, 23, 0,
-  71, 0, 0, 0, 14, 98, 16, 58, 20, 15,
-  28, 30, 7, 0, 10, 8, 0, 0, 0, 49,
-  0, 0, 0, 0, 0, 27, 0, 0, 0, 0,
-  0, 0, 17, 10, 0, 57, 0, 0, 54, 50,
-  0, 0, 31, 38, 0, 36, 0, 0, 23, 53,
-  0, 29, 0, 9, 0, 0, 24, 18, 14, 0,
-  53, 0, 0, 0, 18, 6, 59, 0, 0, 0,
-  0, 0, 21, 44, 0, 0, 68, 38, 3, 47,
-  64, 0, 0, 40, 0, 20, 0, 9, 7, 0,
-  28, 55, 0, 0, 1, 0, 35, 0, 0, 37,
-  14, 0, 22, 0, 0, 15, 86, 0, 0, 0,
-  20, 0, 12, 0, 13, 0, 9, 8, 46, 0,
-  51, 65, 87, 26, 42, 0, 0, 0, 24, 1,
-  1, 1, 40, 128, 0, 10, 0, 0, 20, 34,
-  11, 2, 7, 22, 0, 0, 0, 18, 0, 18,
-  19, 8, 0, 36, 8, 0, 36, 0, 0, 0,
-  19, 59, 0, 24, 0, 0, 22, 33, 0, 0,
-  46, 60, 0, 37, 0, 0, 0, 36, 0, 23,
-  0, 0, 20, 0, 14, 43, 0, 0, 6, 10,
-  0, 33, 9, 0, 41, 0, 0, 0, 32, 7,
-  0, 63, 13, 0, 60, 24, 16, 45, 93, 12,
-  0, 0, 0, 1, 0, 0, 27, 0, 35, 36,
-  0, 2, 17, 0, 23, 17, 0, 42, 39, 0,
-  25, 0, 0, 19, 110, 2, 0, 0, 0, 0,
-  14, 0, 0, 0, 0, 15, 6, 19, 0, 23,
-  27, 4, 12, 35, 0, 0, 0, 0, 7, 0,
-  0, 120, 0, 0, 0, 0, 0, 71, 1, 19,
-  66, 22, 0, 0, 0, 5, 0, 8, 4, 39,
-  0, 29, 0, 44, 65, 31, 0, 0, 54, 58,
-  0, 12, 0, 0, 47, 155, 11, 0, 50, 0,
-  0, 0, 45, 0, 62, 10, 71, 0, 0, 39,
-  35, 0, 91, 27, 0, 65, 34, 36, 0, 34,
-  14, 0, 51, 0, 0, 0, 19, 4, 0, 0,
-  14, 6, 95, 9, 0, 30, 0, 0, 0, 23,
-  0, 0, 8, 0, 0, 0, 51, 94, 0, 92,
-  0, 0, 16, 61, 0, 33, 0, 0, 0, 0,
-  0, 0, 47, 97, 0, 7, 27, 0, 4, 0,
-  0, 0, 0, 0, 0, 77, 45, 0, 33, 19,
-  45, 9, 0, 0, 4, 0, 2, 0, 45, 137,
-  0, 0, 0, 2, 10, 33, 44, 5, 15, 24,
-  0, 0, 11, 35, 0, 0, 0, 12, 0, 13,
-  0, 1, 6, 12, 0, 0, 8, 68, 0, 25,
-  0, 0, 28, 111, 8, 0, 44, 66, 0, 5,
-  0, 0, 15, 16, 0, 6, 0, 0, 27, 0,
-  53, 12, 0, 7, 33, 35, 0, 38, 0, 0,
-  31, 0, 0, 0, 0, 40, 0, 23, 24, 0,
-  54, 8, 0, 37, 61, 0, 0, 16, 0, 0,
-  0, 0, 30, 0, 25, 59, 0, 21, 4, 0,
-  13, 17, 0, 39, 33, 0, 20, 0, 0, 1,
-  63, 23, 29, 0, 0, 0, 72, 0, 0, 0,
-  0, 0, 0, 50, 46, 31, 46, 68, 33, 0,
-  0, 0, 66, 0, 8, 9, 61, 76, 4, 9,
-  2, 0, 9, 16, 52, 0, 0, 39, 0, 0,
-  46, 32, 0, 0, 28, 0, 0, 0, 1, 0,
-  0, 0, 0, 0, 0, 77, 0, 9, 0, 0,
-  10, 32, 0, 0, 39, 72, 0, 16, 9, 0,
-  2, 31, 0, 8, 0, 0, 0, 4, 0, 26,
-  19, 0, 10, 7, 0, 32, 9, 31, 6, 0,
-  0, 38, 0, 38, 15, 46, 46, 0, 9, 55,
-  0, 11, 92, 0, 0, 0, 0, 12, 0, 0,
-  74, 0, 27, 39, 0, 0, 0, 0, 18, 45,
-  0, 35, 42, 11, 31, 0, 15, 0, 62, 0,
-  3, 0, 0, 6, 60, 0, 0, 0, 0, 12,
-  0, 66, 0, 120, 19, 74, 27, 0, 31, 0,
-  61, 0, 8, 0, 21, 27, 26, 43, 32, 22,
-  11, 48, 0, 0, 11, 13, 20, 2, 39, 1,
-  0, 0, 0, 0, 45, 5, 15, 2, 0, 0,
-  0, 0, 0, 0, 0, 21, 0, 27, 87, 36,
-  0, 0, 16, 0, 0, 39, 0, 0, 30, 0,
-  0, 50, 0, 22, 0, 0, 0, 0, 32, 15,
-  38, 0, 0, 0, 27, 0, 82, 16, 0, 44,
-  0, 0, 23, 10, 32, 10, 15, 51, 24, 38,
-  8, 39, 22, 24, 0, 47, 0, 0, 15, 0,
-  42, 41, 18, 5, 0, 0, 5, 0, 39, 13,
-  35, 22, 0, 0, 0, 45, 0, 0, 0, 0,
-  9, 0, 0, 0, 49, 0, 6, 0, 21, 9,
-  64, 56, 7, 47, 47, 23, 0, 2, 27, 0,
-  0, 0, 42, 8, 0, 3, 0, 0, 56, 18,
-  0, 16, 26, 0, 2, 0, 57, 0, 1, 54,
-  0, 27, 23, 0, 74, 44, 54, 0, 12, 0,
-  0, 9, 0, 16, 14, 30, 64, 22, 0, 0,
-  0, 0, 0, 18, 39, 0, 31, 0, 0, 0,
-  0, 41, 29, 0, 11, 5, 0, 39, 0, 10,
-  75, 0, 74, 0, 24, 4, 0, 36, 30, 0,
-  0, 0, 49, 39, 40, 0, 0, 51, 36, 6,
-  0, 6, 0, 16, 0, 0, 38, 0, 41, 42,
-  30, 45, 15, 0, 0, 0, 5, 61, 41, 0,
-  5, 11, 0, 65, 38, 0, 0, 0, 29, 0,
-  0, 0, 0, 0, 0, 0, 8, 29, 59, 0,
-  21, 13, 0, 41, 0, 2, 0, 43, 0, 19,
-  0, 48, 0, 0, 0, 0, 56, 0, 3, 89,
-  5, 0, 0, 0, 21, 5, 0, 99, 0, 11,
-  0, 0, 67, 44, 117, 91, 15, 0, 39, 0,
-  3, 0, 0, 12, 0, 18, 5, 1, 0, 35,
-  0, 23, 119, 0, 0, 4, 0, 0, 0, 65,
-  91, 49, 82, 33, 0, 21, 0, 118, 80, 20,
-  83, 0, 0, 0, 0, 0, 100, 0, 0, 0,
-  15, 22, 26, 0, 0, 49, 63, 0, 0, 18,
-  0, 0, 55, 0, 41, 0, 0, 54, 58, 26,
-  28, 0, 0, 0, 0, 29, 0, 0, 19, 18,
-  0, 23, 56, 7, 0, 0, 19, 0, 0, 0,
-  0, 0, 0, 24, 61, 73, 7, 49, 61, 23,
-  56, 0, 23, 0, 71, 0, 0, 0, 14, 98,
-  16, 58, 20, 15, 28, 30, 7, 0, 10, 8,
-  0, 0, 0, 49, 0, 0, 0, 0, 0, 27,
-  0, 0, 0, 0, 0, 0, 17, 10, 0, 57,
-  0, 0, 54, 50, 0, 0, 31, 38, 0, 36,
-  0, 0, 23, 53, 0, 29, 0, 9, 0, 0,
-  24, 18, 14, 0, 53, 0, 0, 0, 18, 6,
-  59, 0, 0, 0, 0, 0, 21, 44, 0, 0,
-  68, 38, 3, 47, 64, 0, 0, 40, 0, 20,
-  0, 9, 7, 0, 28, 55, 0, 0, 1, 0,
-  35, 0, 0, 37, 14, 0, 22, 0, 0, 15,
-  86, 0, 0, 0, 20, 0, 12, 0, 13, 0,
-  9, 8, 46, 0, 51, 65, 87, 26, 42, 0,
-  0, 0, 24, 1, 1, 1, 40, 128, 0, 10,
-  0, 0, 20, 34, 11, 2, 7, 22, 0, 0,
-  0, 18, 0, 18, 19, 8, 0, 36, 8, 0,
-  36, 0, 0, 0, 19, 59, 0, 24, 0, 0,
-  22, 33, 0, 0, 46, 60, 0, 37, 0, 0,
-  0, 36, 0, 23, 0, 0, 20, 0, 14, 43,
-  0, 0, 6, 10, 0, 33, 9, 0, 41, 0,
-  0, 0, 32, 7, 0, 63, 13, 0, 60, 24,
-  16, 45, 93, 12, 0, 0, 0, 1, 0, 0,
-  27, 0, 35, 36, 0, 2, 17, 0, 23, 17,
-  0, 42, 39, 0, 25, 0, 0, 19, 110, 2,
-  0, 0, 0, 0, 14, 0, 0, 0, 0, 15,
-  6, 19, 58, 29, 70, 32, 22, 7, 0, 0,
-  38, 0, 7, 32, 60, 93, 0, 0, 0, 0,
-  38, 0, 64, 26, 0, 33, 0, 0, 30, 14,
-  0, 67, 47, 0, 0, 0, 6, 0, 43, 9,
-  0, 0, 0, 21, 0, 0, 0, 0, 0, 24,
-  0, 6, 13, 86, 0, 24, 27, 0, 0, 48,
-  0, 0, 0, 0, 12, 26, 3, 21, 0, 0,
-  0, 30, 0, 44, 10, 2, 0, 0, 0, 0,
-  48, 0, 0, 39, 61, 0, 1, 12, 0, 35,
-  123, 0, 0, 0, 0, 0, 0, 0, 63, 0,
-  17, 39, 26, 0, 0, 0, 0, 26, 0, 33,
-  42, 10, 39, 0, 4, 0, 83, 0, 0, 0,
-  0, 28, 67, 0, 0, 0, 0, 33, 0, 82,
-  45, 0, 33, 19, 45, 9, 0, 0, 4, 0,
-  2, 0, 45, 137, 0, 0, 0, 2, 10, 33,
-  44, 5, 15, 24, 0, 0, 11, 35, 0, 0,
-  0, 12, 0, 13, 0, 1, 6, 12, 0, 0,
-  8, 68, 0, 25, 0, 0, 28, 111, 8, 0,
-  44, 66, 0, 5, 0, 0, 15, 16, 0, 6,
-  0, 0, 27, 0, 53, 12, 0, 7, 33, 35,
-  0, 38, 0, 0, 31, 0, 0, 0, 0, 40,
-  0, 23, 24, 0, 54, 8, 0, 37, 61, 0,
-  0, 16, 0, 0, 0, 0, 30, 0, 25, 59,
-  0, 21, 4, 0, 13, 17, 0, 39, 33, 0,
-  20, 0, 0, 1, 63, 23, 29, 0, 0, 0,
-  72, 0, 0, 0, 0, 0, 0, 50, 46, 31,
-  46, 68, 33, 0, 0, 0, 66, 0, 8, 9,
-  61, 76, 4, 9, 2, 0, 9, 16, 52, 0,
-  0, 39, 0, 0, 46, 32, 0, 0, 28, 0,
-  0, 0, 1, 0, 0, 0, 0, 0, 0, 77,
-  0, 9, 0, 0, 10, 32, 0, 0, 39, 72,
-  0, 16, 9, 0, 2, 31, 0, 8, 0, 0,
-  0, 4, 0, 26, 19, 0, 10, 7, 0, 32,
-  9, 31, 6, 0, 0, 38, 0, 38, 15, 46,
-  46, 0, 9, 55, 0, 11, 92, 0, 0, 0,
-  0, 12, 0, 0, 74, 0, 27, 39, 0, 0,
-  0, 0, 18, 45, 0, 35, 42, 11, 31, 0,
-  15, 0, 62, 0, 3, 0, 0, 6, 60, 0,
-  0, 0, 0, 12, 0, 66, 23, 5, 71, 73,
-  1, 0, 0, 8, 79, 0, 18, 35, 49, 54,
-  0, 0, 0, 6, 44, 0, 41, 8, 0, 24,
-  0, 0, 55, 8, 0, 0, 32, 0, 5, 0,
-  0, 0, 12, 0, 0, 0, 0, 38, 0, 0,
-  0, 8, 0, 0, 0, 0, 32, 89, 0, 0,
-  52, 0, 19, 21, 0, 9, 0, 0, 0, 30,
-  3, 0, 40, 0, 15, 64, 0, 0, 41, 76,
-  0, 0, 9, 58, 0, 26, 12, 24, 95, 17,
-  0, 70, 0, 25, 100, 0, 27, 15, 0, 0,
-  8, 0, 68, 0, 16, 62, 13, 0, 0, 0,
-  0, 91, 0, 16, 1, 6, 23, 0, 3, 0,
-  73, 0, 19, 0, 0, 35, 21, 0, 0, 0,
-  0, 16, 0, 69, 64, 56, 7, 47, 47, 23,
-  0, 2, 27, 0, 0, 0, 42, 8, 0, 3,
-  0, 0, 56, 18, 0, 16, 26, 0, 2, 0,
-  57, 0, 1, 54, 0, 27, 23, 0, 74, 44,
-  54, 0, 12, 0, 0, 9, 0, 16, 14, 30,
-  64, 22, 0, 0, 0, 0, 0, 18, 39, 0,
-  31, 0, 0, 0, 0, 41, 29, 0, 11, 5,
-  0, 39, 0, 10, 75, 0, 74, 0, 24, 4,
-  0, 36, 30, 0, 0, 0, 49, 39, 40, 0,
-  0, 51, 36, 6, 0, 6, 0, 16, 0, 0,
-  38, 0, 41, 42, 30, 45, 15, 0, 0, 0,
-  5, 61, 41, 0, 5, 11, 0, 65, 38, 0,
-  0, 0, 29, 0, 0, 0, 0, 0, 0, 0,
-  8, 29, 59, 0, 21, 13, 0, 41, 0, 2,
-  0, 43, 0, 19, 0, 48, 0, 0, 0, 0,
-  56, 0, 3, 89, 5, 0, 0, 0, 21, 5,
-  0, 99, 0, 11, 0, 0, 67, 44, 117, 91,
-  15, 0, 39, 0, 3, 0, 0, 12, 0, 18,
-  5, 1, 0, 35, 0, 23, 119, 0, 0, 4,
-  0, 0, 0, 65, 91, 49, 82, 33, 0, 21,
-  0, 118, 80, 20, 83, 0, 0, 0, 0, 0,
-  100, 0, 0, 0, 15, 22, 26, 0, 0, 49,
-  63, 0, 0, 18, 0, 0, 55, 0, 41, 0,
-  0, 54, 58, 26, 28, 0, 0, 0, 0, 29,
-  0, 0, 19, 18, 0, 23, 56, 7, 0, 0,
-  19, 0, 0, 0, 0, 0, 0, 24, 61, 73,
-  32, 0, 66, 36, 9, 0, 0, 0, 5, 21,
-  0, 26, 30, 124, 0, 0, 0, 0, 23, 0,
-  28, 52, 0, 3, 0, 0, 50, 28, 0, 103,
-  0, 4, 0, 0, 39, 0, 82, 66, 0, 0,
-  35, 0, 2, 0, 0, 22, 7, 0, 0, 0,
-  0, 70, 0, 21, 74, 0, 0, 14, 10, 0,
-  0, 32, 91, 24, 64, 1, 0, 2, 0, 95,
-  0, 13, 72, 0, 0, 0, 0, 0, 86, 0,
-  0, 56, 11, 19, 0, 0, 12, 13, 141, 0,
-  0, 19, 0, 0, 4, 0, 38, 0, 0, 38,
-  31, 0, 0, 0, 0, 0, 0, 56, 51, 0,
-  69, 0, 0, 0, 107, 0, 36, 0, 0, 32,
-  38, 0, 0, 0, 0, 37, 0, 81, 51, 65,
-  87, 26, 42, 0, 0, 0, 24, 1, 1, 1,
-  40, 128, 0, 10, 0, 0, 20, 34, 11, 2,
-  7, 22, 0, 0, 0, 18, 0, 18, 19, 8,
-  0, 36, 8, 0, 36, 0, 0, 0, 19, 59,
-  0, 24, 0, 0, 22, 33, 0, 0, 46, 60,
-  0, 37, 0, 0, 0, 36, 0, 23, 0, 0,
-  20, 0, 14, 43, 0, 0, 6, 10, 0, 33,
-  9, 0, 41, 0, 0, 0, 32, 7, 0, 63,
-  13, 0, 60, 24, 16, 45, 93, 12, 0, 0,
-  0, 1, 0, 0, 27, 0, 35, 36, 0, 2,
-  17, 0, 23, 17, 0, 42, 39, 0, 25, 0,
-  0, 19, 110, 2, 0, 0, 0, 0, 14, 0,
-  0, 0, 0, 15, 6, 19, 58, 29, 70, 32,
-  22, 7, 0, 0, 38, 0, 7, 32, 60, 93,
-  0, 0, 0, 0, 38, 0, 64, 26, 0, 33,
-  0, 0, 30, 14, 0, 67, 47, 0, 0, 0,
-  6, 0, 43, 9, 0, 0, 0, 21, 0, 0,
-  0, 0, 0, 24, 0, 6, 13, 86, 0, 24,
-  27, 0, 0, 48, 0, 0, 0, 0, 12, 26,
-  3, 21, 0, 0, 0, 30, 0, 44, 10, 2,
-  0, 0, 0, 0, 48, 0, 0, 39, 61, 0,
-  1, 12, 0, 35, 123, 0, 0, 0, 0, 0,
-  0, 0, 63, 0, 17, 39, 26, 0, 0, 0,
-  0, 26, 0, 33, 42, 10, 39, 0, 4, 0,
-  83, 0, 0, 0, 0, 28, 67, 0, 0, 0,
-  0, 33, 0, 82, 37, 48, 54, 46, 22, 17,
-  0, 0, 75, 0, 31, 10, 55, 60, 0, 21,
-  0, 0, 43, 0, 38, 0, 0, 48, 0, 0,
-  41, 28, 0, 38, 57, 0, 0, 0, 24, 0,
-  32, 0, 0, 0, 0, 80, 0, 0, 0, 0,
-  14, 21, 0, 28, 36, 67, 0, 12, 53, 0,
-  1, 49, 0, 34, 0, 0, 0, 41, 0, 12,
-  9, 0, 0, 0, 0, 43, 25, 31, 0, 22,
-  14, 0, 16, 22, 0, 32, 73, 0, 0, 30,
-  3, 13, 122, 5, 40, 0, 0, 1, 0, 0,
-  93, 0, 14, 55, 0, 0, 0, 0, 0, 54,
-  0, 32, 56, 22, 48, 0, 15, 0, 63, 0,
-  0, 0, 0, 46, 59, 0, 14, 0, 6, 28,
-  0, 93, 46, 31, 46, 68, 33, 0, 0, 0,
-  66, 0, 8, 9, 61, 76, 4, 9, 2, 0,
-  9, 16, 52, 0, 0, 39, 0, 0, 46, 32,
-  0, 0, 28, 0, 0, 0, 1, 0, 0, 0,
-  0, 0, 0, 77, 0, 9, 0, 0, 10, 32,
-  0, 0, 39, 72, 0, 16, 9, 0, 2, 31,
-  0, 8, 0, 0, 0, 4, 0, 26, 19, 0,
-  10, 7, 0, 32, 9, 31, 6, 0, 0, 38,
-  0, 38, 15, 46, 46, 0, 9, 55, 0, 11,
-  92, 0, 0, 0, 0, 12, 0, 0, 74, 0,
-  27, 39, 0, 0, 0, 0, 18, 45, 0, 35,
-  42, 11, 31, 0, 15, 0, 62, 0, 3, 0,
-  0, 6, 60, 0, 0, 0, 0, 12, 0, 66,
-  23, 5, 71, 73, 1, 0, 0, 8, 79, 0,
-  18, 35, 49, 54, 0, 0, 0, 6, 44, 0,
-  41, 8, 0, 24, 0, 0, 55, 8, 0, 0,
-  32, 0, 5, 0, 0, 0, 12, 0, 0, 0,
-  0, 38, 0, 0, 0, 8, 0, 0, 0, 0,
-  32, 89, 0, 0, 52, 0, 19, 21, 0, 9,
-  0, 0, 0, 30, 3, 0, 40, 0, 15, 64,
-  0, 0, 41, 76, 0, 0, 9, 58, 0, 26,
-  12, 24, 95, 17, 0, 70, 0, 25, 100, 0,
-  27, 15, 0, 0, 8, 0, 68, 0, 16, 62,
-  13, 0, 0, 0, 0, 91, 0, 16, 1, 6,
-  23, 0, 3, 0, 73, 0, 19, 0, 0, 35,
-  21, 0, 0, 0, 0, 16, 0, 69, 0, 0,
-  76, 61, 0, 18, 0, 0, 58, 0, 2, 25,
-  0, 40, 0, 0, 19, 37, 29, 4, 20, 9,
-  0, 8, 0, 0, 28, 9, 0, 0, 7, 0,
-  8, 0, 0, 19, 34, 4, 0, 0, 0, 7,
-  0, 0, 0, 37, 0, 0, 0, 0, 40, 40,
-  0, 0, 62, 0, 3, 11, 0, 0, 0, 0,
-  0, 0, 17, 0, 43, 0, 29, 88, 0, 0,
-  53, 71, 0, 0, 0, 29, 0, 20, 2, 10,
-  49, 67, 0, 66, 3, 6, 58, 0, 34, 42,
-  0, 0, 38, 0, 45, 5, 0, 65, 19, 0,
-  0, 0, 12, 109, 0, 0, 0, 0, 12, 0,
-  0, 0, 66, 0, 15, 0, 0, 45, 0, 0,
-  0, 0, 0, 21, 19, 34, 59, 0, 21, 13,
-  0, 41, 0, 2, 0, 43, 0, 19, 0, 48,
-  0, 0, 0, 0, 56, 0, 3, 89, 5, 0,
-  0, 0, 21, 5, 0, 99, 0, 11, 0, 0,
-  67, 44, 117, 91, 15, 0, 39, 0, 3, 0,
-  0, 12, 0, 18, 5, 1, 0, 35, 0, 23,
-  119, 0, 0, 4, 0, 0, 0, 65, 91, 49,
-  82, 33, 0, 21, 0, 118, 80, 20, 83, 0,
-  0, 0, 0, 0, 100, 0, 0, 0, 15, 22,
-  26, 0, 0, 49, 63, 0, 0, 18, 0, 0,
-  55, 0, 41, 0, 0, 54, 58, 26, 28, 0,
-  0, 0, 0, 29, 0, 0, 19, 18, 0, 23,
-  56, 7, 0, 0, 19, 0, 0, 0, 0, 0,
-  0, 24, 61, 73, 32, 0, 66, 36, 9, 0,
-  0, 0, 5, 21, 0, 26, 30, 124, 0, 0,
-  0, 0, 23, 0, 28, 52, 0, 3, 0, 0,
-  50, 28, 0, 103, 0, 4, 0, 0, 39, 0,
-  82, 66, 0, 0, 35, 0, 2, 0, 0, 22,
-  7, 0, 0, 0, 0, 70, 0, 21, 74, 0,
-  0, 14, 10, 0, 0, 32, 91, 24, 64, 1,
-  0, 2, 0, 95, 0, 13, 72, 0, 0, 0,
-  0, 0, 86, 0, 0, 56, 11, 19, 0, 0,
-  12, 13, 141, 0, 0, 19, 0, 0, 4, 0,
-  38, 0, 0, 38, 31, 0, 0, 0, 0, 0,
-  0, 56, 51, 0, 69, 0, 0, 0, 107, 0,
-  36, 0, 0, 32, 38, 0, 0, 0, 0, 37,
-  0, 81, 51, 46, 25, 77, 65, 9, 0, 0,
-  20, 0, 19, 0, 51, 118, 0, 0, 0, 0,
-  16, 7, 12, 11, 0, 26, 0, 0, 55, 19,
-  0, 69, 20, 7, 22, 0, 56, 0, 0, 0,
-  0, 0, 0, 35, 0, 0, 31, 31, 30, 33,
-  0, 0, 23, 35, 0, 14, 38, 0, 27, 20,
-  0, 10, 0, 19, 19, 8, 0, 0, 0, 0,
-  2, 0, 0, 41, 51, 0, 0, 22, 0, 0,
-  35, 8, 0, 53, 41, 20, 0, 0, 35, 12,
-  95, 14, 26, 0, 0, 30, 0, 0, 70, 0,
-  0, 50, 0, 20, 0, 0, 0, 25, 0, 43,
-  127, 0, 82, 0, 12, 0, 31, 0, 14, 0,
-  0, 8, 49, 0, 2, 15, 10, 13, 0, 93,
-  58, 29, 70, 32, 22, 7, 0, 0, 38, 0,
-  7, 32, 60, 93, 0, 0, 0, 0, 38, 0,
-  64, 26, 0, 33, 0, 0, 30, 14, 0, 67,
-  47, 0, 0, 0, 6, 0, 43, 9, 0, 0,
-  0, 21, 0, 0, 0, 0, 0, 24, 0, 6,
-  13, 86, 0, 24, 27, 0, 0, 48, 0, 0,
-  0, 0, 12, 26, 3, 21, 0, 0, 0, 30,
-  0, 44, 10, 2, 0, 0, 0, 0, 48, 0,
-  0, 39, 61, 0, 1, 12, 0, 35, 123, 0,
-  0, 0, 0, 0, 0, 0, 63, 0, 17, 39,
-  26, 0, 0, 0, 0, 26, 0, 33, 42, 10,
-  39, 0, 4, 0, 83, 0, 0, 0, 0, 28,
-  67, 0, 0, 0, 0, 33, 0, 82, 37, 48,
-  54, 46, 22, 17, 0, 0, 75, 0, 31, 10,
-  55, 60, 0, 21, 0, 0, 43, 0, 38, 0,
-  0, 48, 0, 0, 41, 28, 0, 38, 57, 0,
-  0, 0, 24, 0, 32, 0, 0, 0, 0, 80,
-  0, 0, 0, 0, 14, 21, 0, 28, 36, 67,
-  0, 12, 53, 0, 1, 49, 0, 34, 0, 0,
-  0, 41, 0, 12, 9, 0, 0, 0, 0, 43,
-  25, 31, 0, 22, 14, 0, 16, 22, 0, 32,
-  73, 0, 0, 30, 3, 13, 122, 5, 40, 0,
-  0, 1, 0, 0, 93, 0, 14, 55, 0, 0,
-  0, 0, 0, 54, 0, 32, 56, 22, 48, 0,
-  15, 0, 63, 0, 0, 0, 0, 46, 59, 0,
-  14, 0, 6, 28, 0, 93, 18, 58, 66, 69,
-  39, 34, 0, 0, 61, 0, 24, 0, 24, 41,
-  11, 21, 49, 14, 29, 7, 0, 0, 0, 34,
-  1, 0, 22, 29, 0, 26, 0, 5, 31, 0,
-  36, 0, 13, 0, 0, 0, 0, 34, 0, 0,
-  10, 55, 10, 6, 0, 0, 30, 0, 0, 0,
-  35, 0, 20, 14, 0, 4, 0, 6, 0, 0,
-  0, 0, 31, 0, 49, 0, 0, 0, 64, 30,
-  0, 37, 0, 10, 0, 53, 0, 8, 43, 93,
-  0, 42, 5, 3, 30, 39, 93, 5, 0, 0,
-  11, 0, 68, 0, 0, 79, 5, 0, 0, 0,
-  30, 61, 0, 15, 39, 0, 23, 0, 0, 0,
-  0, 0, 12, 0, 0, 0, 11, 0, 7, 0,
-  19, 17, 24, 37, 23, 5, 71, 73, 1, 0,
-  0, 8, 79, 0, 18, 35, 49, 54, 0, 0,
-  0, 6, 44, 0, 41, 8, 0, 24, 0, 0,
-  55, 8, 0, 0, 32, 0, 5, 0, 0, 0,
-  12, 0, 0, 0, 0, 38, 0, 0, 0, 8,
-  0, 0, 0, 0, 32, 89, 0, 0, 52, 0,
-  19, 21, 0, 9, 0, 0, 0, 30, 3, 0,
-  40, 0, 15, 64, 0, 0, 41, 76, 0, 0,
-  9, 58, 0, 26, 12, 24, 95, 17, 0, 70,
-  0, 25, 100, 0, 27, 15, 0, 0, 8, 0,
-  68, 0, 16, 62, 13, 0, 0, 0, 0, 91,
-  0, 16, 1, 6, 23, 0, 3, 0, 73, 0,
-  19, 0, 0, 35, 21, 0, 0, 0, 0, 16,
-  0, 69, 0, 0, 76, 61, 0, 18, 0, 0,
-  58, 0, 2, 25, 0, 40, 0, 0, 19, 37,
-  29, 4, 20, 9, 0, 8, 0, 0, 28, 9,
-  0, 0, 7, 0, 8, 0, 0, 19, 34, 4,
-  0, 0, 0, 7, 0, 0, 0, 37, 0, 0,
-  0, 0, 40, 40, 0, 0, 62, 0, 3, 11,
-  0, 0, 0, 0, 0, 0, 17, 0, 43, 0,
-  29, 88, 0, 0, 53, 71, 0, 0, 0, 29,
-  0, 20, 2, 10, 49, 67, 0, 66, 3, 6,
-  58, 0, 34, 42, 0, 0, 38, 0, 45, 5,
-  0, 65, 19, 0, 0, 0, 12, 109, 0, 0,
-  0, 0, 12, 0, 0, 0, 66, 0, 15, 0,
-  0, 45, 0, 0, 0, 0, 0, 21, 19, 34,
-  21, 49, 94, 59, 0, 40, 0, 0, 37, 0,
-  0, 2, 0, 53, 10, 6, 39, 18, 0, 5,
-  0, 0, 0, 10, 0, 0, 0, 12, 0, 36,
-  18, 54, 0, 12, 26, 2, 59, 42, 0, 0,
-  0, 6, 17, 0, 0, 42, 0, 10, 0, 0,
-  60, 0, 0, 0, 47, 0, 14, 4, 5, 0,
-  0, 0, 0, 0, 0, 0, 19, 0, 49, 8,
-  0, 0, 50, 31, 0, 14, 0, 0, 0, 49,
-  0, 39, 0, 93, 0, 53, 2, 0, 47, 10,
-  28, 14, 0, 0, 7, 0, 11, 20, 0, 63,
-  0, 0, 0, 0, 64, 95, 0, 0, 0, 0,
-  42, 0, 0, 0, 37, 0, 0, 0, 0, 29,
-  0, 0, 0, 0, 8, 31, 58, 8, 32, 0,
-  66, 36, 9, 0, 0, 0, 5, 21, 0, 26,
-  30, 124, 0, 0, 0, 0, 23, 0, 28, 52,
-  0, 3, 0, 0, 50, 28, 0, 103, 0, 4,
-  0, 0, 39, 0, 82, 66, 0, 0, 35, 0,
-  2, 0, 0, 22, 7, 0, 0, 0, 0, 70,
-  0, 21, 74, 0, 0, 14, 10, 0, 0, 32,
-  91, 24, 64, 1, 0, 2, 0, 95, 0, 13,
-  72, 0, 0, 0, 0, 0, 86, 0, 0, 56,
-  11, 19, 0, 0, 12, 13, 141, 0, 0, 19,
-  0, 0, 4, 0, 38, 0, 0, 38, 31, 0,
-  0, 0, 0, 0, 0, 56, 51, 0, 69, 0,
-  0, 0, 107, 0, 36, 0, 0, 32, 38, 0,
-  0, 0, 0, 37, 0, 81, 51, 46, 25, 77,
-  65, 9, 0, 0, 20, 0, 19, 0, 51, 118,
-  0, 0, 0, 0, 16, 7, 12, 11, 0, 26,
-  0, 0, 55, 19, 0, 69, 20, 7, 22, 0,
-  56, 0, 0, 0, 0, 0, 0, 35, 0, 0,
-  31, 31, 30, 33, 0, 0, 23, 35, 0, 14,
-  38, 0, 27, 20, 0, 10, 0, 19, 19, 8,
-  0, 0, 0, 0, 2, 0, 0, 41, 51, 0,
-  0, 22, 0, 0, 35, 8, 0, 53, 41, 20,
-  0, 0, 35, 12, 95, 14, 26, 0, 0, 30,
-  0, 0, 70, 0, 0, 50, 0, 20, 0, 0,
-  0, 25, 0, 43, 127, 0, 82, 0, 12, 0,
-  31, 0, 14, 0, 0, 8, 49, 0, 2, 15,
-  10, 13, 0, 93, 42, 127, 15, 99, 80, 43,
-  0, 0, 43, 0, 32, 0, 35, 29, 0, 0,
-  11, 0, 41, 15, 0, 0, 0, 47, 24, 0,
-  52, 29, 0, 37, 5, 49, 69, 0, 20, 0,
-  0, 0, 0, 0, 0, 17, 0, 6, 19, 56,
-  44, 46, 0, 7, 4, 0, 0, 17, 32, 0,
-  50, 2, 0, 29, 21, 24, 0, 8, 0, 0,
-  52, 4, 27, 0, 0, 21, 45, 4, 6, 45,
-  10, 2, 0, 2, 0, 19, 40, 73, 0, 17,
-  5, 38, 21, 49, 107, 0, 0, 49, 0, 0,
-  90, 0, 23, 57, 7, 99, 1, 0, 25, 33,
-  41, 62, 122, 0, 7, 22, 36, 0, 0, 0,
-  0, 0, 0, 0, 13, 0, 43, 0, 45, 1,
-  13, 74, 37, 48, 54, 46, 22, 17, 0, 0,
-  75, 0, 31, 10, 55, 60, 0, 21, 0, 0,
-  43, 0, 38, 0, 0, 48, 0, 0, 41, 28,
-  0, 38, 57, 0, 0, 0, 24, 0, 32, 0,
-  0, 0, 0, 80, 0, 0, 0, 0, 14, 21,
-  0, 28, 36, 67, 0, 12, 53, 0, 1, 49,
-  0, 34, 0, 0, 0, 41, 0, 12, 9, 0,
-  0, 0, 0, 43, 25, 31, 0, 22, 14, 0,
-  16, 22, 0, 32, 73, 0, 0, 30, 3, 13,
-  122, 5, 40, 0, 0, 1, 0, 0, 93, 0,
-  14, 55, 0, 0, 0, 0, 0, 54, 0, 32,
-  56, 22, 48, 0, 15, 0, 63, 0, 0, 0,
-  0, 46, 59, 0, 14, 0, 6, 28, 0, 93,
-  18, 58, 66, 69, 39, 34, 0, 0, 61, 0,
-  24, 0, 24, 41, 11, 21, 49, 14, 29, 7,
-  0, 0, 0, 34, 1, 0, 22, 29, 0, 26,
-  0, 5, 31, 0, 36, 0, 13, 0, 0, 0,
-  0, 34, 0, 0, 10, 55, 10, 6, 0, 0,
-  30, 0, 0, 0, 35, 0, 20, 14, 0, 4,
-  0, 6, 0, 0, 0, 0, 31, 0, 49, 0,
-  0, 0, 64, 30, 0, 37, 0, 10, 0, 53,
-  0, 8, 43, 93, 0, 42, 5, 3, 30, 39,
-  93, 5, 0, 0, 11, 0, 68, 0, 0, 79,
-  5, 0, 0, 0, 30, 61, 0, 15, 39, 0,
-  23, 0, 0, 0, 0, 0, 12, 0, 0, 0,
-  11, 0, 7, 0, 19, 17, 24, 37, 19, 83,
-  100, 57, 60, 86, 0, 0, 16, 0, 0, 0,
-  1, 37, 9, 22, 45, 0, 3, 24, 0, 9,
-  0, 26, 12, 0, 0, 30, 0, 58, 0, 45,
-  5, 36, 29, 8, 0, 14, 0, 6, 0, 0,
-  0, 30, 1, 47, 31, 38, 0, 0, 15, 0,
-  0, 0, 7, 0, 28, 11, 0, 0, 0, 19,
-  0, 0, 0, 0, 25, 0, 71, 0, 0, 0,
-  48, 11, 37, 0, 0, 0, 0, 14, 0, 10,
-  19, 113, 22, 41, 0, 37, 0, 20, 39, 0,
-  0, 0, 11, 0, 10, 0, 0, 52, 9, 11,
-  0, 0, 76, 50, 5, 16, 33, 0, 25, 22,
-  0, 4, 0, 0, 10, 0, 0, 0, 0, 0,
-  0, 0, 34, 0, 47, 18, 0, 0, 76, 61,
-  0, 18, 0, 0, 58, 0, 2, 25, 0, 40,
-  0, 0, 19, 37, 29, 4, 20, 9, 0, 8,
-  0, 0, 28, 9, 0, 0, 7, 0, 8, 0,
-  0, 19, 34, 4, 0, 0, 0, 7, 0, 0,
-  0, 37, 0, 0, 0, 0, 40, 40, 0, 0,
-  62, 0, 3, 11, 0, 0, 0, 0, 0, 0,
-  17, 0, 43, 0, 29, 88, 0, 0, 53, 71,
-  0, 0, 0, 29, 0, 20, 2, 10, 49, 67,
-  0, 66, 3, 6, 58, 0, 34, 42, 0, 0,
-  38, 0, 45, 5, 0, 65, 19, 0, 0, 0,
-  12, 109, 0, 0, 0, 0, 12, 0, 0, 0,
-  66, 0, 15, 0, 0, 45, 0, 0, 0, 0,
-  0, 21, 19, 34, 21, 49, 94, 59, 0, 40,
-  0, 0, 37, 0, 0, 2, 0, 53, 10, 6,
-  39, 18, 0, 5, 0, 0, 0, 10, 0, 0,
-  0, 12, 0, 36, 18, 54, 0, 12, 26, 2,
-  59, 42, 0, 0, 0, 6, 17, 0, 0, 42,
-  0, 10, 0, 0, 60, 0, 0, 0, 47, 0,
-  14, 4, 5, 0, 0, 0, 0, 0, 0, 0,
-  19, 0, 49, 8, 0, 0, 50, 31, 0, 14,
-  0, 0, 0, 49, 0, 39, 0, 93, 0, 53,
-  2, 0, 47, 10, 28, 14, 0, 0, 7, 0,
-  11, 20, 0, 63, 0, 0, 0, 0, 64, 95,
-  0, 0, 0, 0, 42, 0, 0, 0, 37, 0,
-  0, 0, 0, 29, 0, 0, 0, 0, 8, 31,
-  58, 8, 24, 50, 130, 56, 9, 113, 0, 0,
-  0, 0, 0, 0, 18, 53, 0, 15, 32, 9,
-  0, 14, 0, 26, 0, 12, 0, 0, 0, 0,
-  0, 68, 18, 55, 0, 60, 43, 18, 30, 1,
-  0, 18, 0, 0, 0, 3, 0, 17, 0, 39,
-  0, 0, 36, 38, 0, 0, 41, 0, 32, 16,
-  29, 0, 0, 0, 0, 0, 31, 0, 0, 0,
-  41, 0, 0, 0, 42, 0, 0, 3, 0, 0,
-  2, 46, 0, 22, 20, 94, 27, 22, 13, 1,
-  28, 26, 6, 0, 0, 0, 15, 0, 0, 0,
-  0, 25, 2, 0, 0, 0, 20, 67, 0, 0,
-  0, 2, 64, 0, 0, 16, 0, 0, 21, 0,
-  0, 13, 0, 0, 0, 18, 28, 25, 23, 8,
-  51, 46, 25, 77, 65, 9, 0, 0, 20, 0,
-  19, 0, 51, 118, 0, 0, 0, 0, 16, 7,
-  12, 11, 0, 26, 0, 0, 55, 19, 0, 69,
-  20, 7, 22, 0, 56, 0, 0, 0, 0, 0,
-  0, 35, 0, 0, 31, 31, 30, 33, 0, 0,
-  23, 35, 0, 14, 38, 0, 27, 20, 0, 10,
-  0, 19, 19, 8, 0, 0, 0, 0, 2, 0,
-  0, 41, 51, 0, 0, 22, 0, 0, 35, 8,
-  0, 53, 41, 20, 0, 0, 35, 12, 95, 14,
-  26, 0, 0, 30, 0, 0, 70, 0, 0, 50,
-  0, 20, 0, 0, 0, 25, 0, 43, 127, 0,
-  82, 0, 12, 0, 31, 0, 14, 0, 0, 8,
-  49, 0, 2, 15, 10, 13, 0, 93, 42, 127,
-  15, 99, 80, 43, 0, 0, 43, 0, 32, 0,
-  35, 29, 0, 0, 11, 0, 41, 15, 0, 0,
-  0, 47, 24, 0, 52, 29, 0, 37, 5, 49,
-  69, 0, 20, 0, 0, 0, 0, 0, 0, 17,
-  0, 6, 19, 56, 44, 46, 0, 7, 4, 0,
-  0, 17, 32, 0, 50, 2, 0, 29, 21, 24,
-  0, 8, 0, 0, 52, 4, 27, 0, 0, 21,
-  45, 4, 6, 45, 10, 2, 0, 2, 0, 19,
-  40, 73, 0, 17, 5, 38, 21, 49, 107, 0,
-  0, 49, 0, 0, 90, 0, 23, 57, 7, 99,
-  1, 0, 25, 33, 41, 62, 122, 0, 7, 22,
-  36, 0, 0, 0, 0, 0, 0, 0, 13, 0,
-  43, 0, 45, 1, 13, 74, 17, 8, 86, 68,
-  23, 217, 0, 0, 29, 0, 0, 0, 32, 0,
-  0, 0, 31, 18, 66, 0, 0, 112, 15, 8,
-  7, 0, 0, 35, 0, 72, 0, 82, 0, 0,
-  0, 30, 0, 0, 1, 0, 0, 19, 0, 19,
-  0, 50, 59, 42, 0, 14, 0, 45, 0, 0,
-  97, 0, 62, 0, 33, 0, 0, 70, 0, 0,
-  53, 0, 0, 26, 12, 6, 27, 25, 76, 0,
-  0, 26, 25, 0, 0, 18, 0, 0, 77, 83,
-  0, 0, 0, 18, 0, 4, 54, 0, 0, 0,
-  24, 0, 25, 0, 15, 39, 25, 35, 17, 0,
-  0, 31, 47, 29, 0, 0, 0, 45, 0, 0,
-  0, 0, 38, 0, 3, 0, 0, 1, 0, 22,
-  25, 0, 0, 20, 18, 58, 66, 69, 39, 34,
-  0, 0, 61, 0, 24, 0, 24, 41, 11, 21,
-  49, 14, 29, 7, 0, 0, 0, 34, 1, 0,
-  22, 29, 0, 26, 0, 5, 31, 0, 36, 0,
-  13, 0, 0, 0, 0, 34, 0, 0, 10, 55,
-  10, 6, 0, 0, 30, 0, 0, 0, 35, 0,
-  20, 14, 0, 4, 0, 6, 0, 0, 0, 0,
-  31, 0, 49, 0, 0, 0, 64, 30, 0, 37,
-  0, 10, 0, 53, 0, 8, 43, 93, 0, 42,
-  5, 3, 30, 39, 93, 5, 0, 0, 11, 0,
-  68, 0, 0, 79, 5, 0, 0, 0, 30, 61,
-  0, 15, 39, 0, 23, 0, 0, 0, 0, 0,
-  12, 0, 0, 0, 11, 0, 7, 0, 19, 17,
-  24, 37, 19, 83, 100, 57, 60, 86, 0, 0,
-  16, 0, 0, 0, 1, 37, 9, 22, 45, 0,
-  3, 24, 0, 9, 0, 26, 12, 0, 0, 30,
-  0, 58, 0, 45, 5, 36, 29, 8, 0, 14,
-  0, 6, 0, 0, 0, 30, 1, 47, 31, 38,
-  0, 0, 15, 0, 0, 0, 7, 0, 28, 11,
-  0, 0, 0, 19, 0, 0, 0, 0, 25, 0,
-  71, 0, 0, 0, 48, 11, 37, 0, 0, 0,
-  0, 14, 0, 10, 19, 113, 22, 41, 0, 37,
-  0, 20, 39, 0, 0, 0, 11, 0, 10, 0,
-  0, 52, 9, 11, 0, 0, 76, 50, 5, 16,
-  33, 0, 25, 22, 0, 4, 0, 0, 10, 0,
-  0, 0, 0, 0, 0, 0, 34, 0, 47, 18,
-  11, 11, 105, 33, 25, 144, 0, 0, 0, 0,
-  0, 0, 17, 0, 0, 0, 17, 5, 23, 0,
-  0, 94, 8, 12, 0, 0, 0, 0, 0, 52,
-  0, 26, 0, 34, 0, 30, 0, 0, 0, 25,
-  0, 0, 0, 39, 0, 0, 23, 37, 0, 0,
-  0, 86, 0, 0, 64, 0, 59, 0, 41, 0,
-  0, 32, 0, 17, 51, 3, 0, 0, 41, 0,
-  4, 7, 56, 0, 27, 0, 0, 0, 0, 10,
-  0, 0, 45, 50, 55, 11, 0, 9, 2, 0,
-  0, 0, 20, 0, 18, 0, 0, 0, 20, 19,
-  0, 0, 0, 0, 22, 38, 4, 0, 0, 0,
-  37, 28, 0, 0, 0, 0, 63, 0, 8, 0,
-  0, 0, 0, 12, 39, 5, 0, 0, 21, 49,
-  94, 59, 0, 40, 0, 0, 37, 0, 0, 2,
-  0, 53, 10, 6, 39, 18, 0, 5, 0, 0,
-  0, 10, 0, 0, 0, 12, 0, 36, 18, 54,
-  0, 12, 26, 2, 59, 42, 0, 0, 0, 6,
-  17, 0, 0, 42, 0, 10, 0, 0, 60, 0,
-  0, 0, 47, 0, 14, 4, 5, 0, 0, 0,
-  0, 0, 0, 0, 19, 0, 49, 8, 0, 0,
-  50, 31, 0, 14, 0, 0, 0, 49, 0, 39,
-  0, 93, 0, 53, 2, 0, 47, 10, 28, 14,
-  0, 0, 7, 0, 11, 20, 0, 63, 0, 0,
-  0, 0, 64, 95, 0, 0, 0, 0, 42, 0,
-  0, 0, 37, 0, 0, 0, 0, 29, 0, 0,
-  0, 0, 8, 31, 58, 8, 24, 50, 130, 56,
-  9, 113, 0, 0, 0, 0, 0, 0, 18, 53,
-  0, 15, 32, 9, 0, 14, 0, 26, 0, 12,
-  0, 0, 0, 0, 0, 68, 18, 55, 0, 60,
-  43, 18, 30, 1, 0, 18, 0, 0, 0, 3,
-  0, 17, 0, 39, 0, 0, 36, 38, 0, 0,
-  41, 0, 32, 16, 29, 0, 0, 0, 0, 0,
-  31, 0, 0, 0, 41, 0, 0, 0, 42, 0,
-  0, 3, 0, 0, 2, 46, 0, 22, 20, 94,
-  27, 22, 13, 1, 28, 26, 6, 0, 0, 0,
-  15, 0, 0, 0, 0, 25, 2, 0, 0, 0,
-  20, 67, 0, 0, 0, 2, 64, 0, 0, 16,
-  0, 0, 21, 0, 0, 13, 0, 0, 0, 18,
-  28, 25, 23, 8, 18, 29, 81, 2, 20, 83,
-  0, 0, 0, 0, 0, 0, 29, 22, 0, 0,
-  11, 0, 22, 0, 16, 80, 7, 25, 0, 0,
-  0, 0, 0, 50, 53, 0, 0, 40, 19, 7,
-  0, 0, 0, 34, 18, 28, 0, 28, 19, 0,
-  0, 38, 0, 0, 0, 100, 0, 0, 72, 0,
-  56, 27, 67, 0, 0, 10, 0, 45, 0, 38,
-  0, 0, 0, 0, 0, 13, 35, 21, 7, 22,
-  0, 0, 0, 14, 4, 0, 18, 9, 61, 9,
-  0, 0, 33, 0, 0, 2, 69, 0, 11, 0,
-  0, 0, 29, 21, 0, 0, 0, 0, 26, 25,
-  0, 0, 0, 32, 64, 0, 0, 16, 0, 0,
-  50, 0, 17, 27, 16, 8, 0, 0, 53, 22,
-  0, 8, 42, 127, 15, 99, 80, 43, 0, 0,
-  43, 0, 32, 0, 35, 29, 0, 0, 11, 0,
-  41, 15, 0, 0, 0, 47, 24, 0, 52, 29,
-  0, 37, 5, 49, 69, 0, 20, 0, 0, 0,
-  0, 0, 0, 17, 0, 6, 19, 56, 44, 46,
-  0, 7, 4, 0, 0, 17, 32, 0, 50, 2,
-  0, 29, 21, 24, 0, 8, 0, 0, 52, 4,
-  27, 0, 0, 21, 45, 4, 6, 45, 10, 2,
-  0, 2, 0, 19, 40, 73, 0, 17, 5, 38,
-  21, 49, 107, 0, 0, 49, 0, 0, 90, 0,
-  23, 57, 7, 99, 1, 0, 25, 33, 41, 62,
-  122, 0, 7, 22, 36, 0, 0, 0, 0, 0,
-  0, 0, 13, 0, 43, 0, 45, 1, 13, 74,
-  17, 8, 86, 68, 23, 217, 0, 0, 29, 0,
-  0, 0, 32, 0, 0, 0, 31, 18, 66, 0,
-  0, 112, 15, 8, 7, 0, 0, 35, 0, 72,
-  0, 82, 0, 0, 0, 30, 0, 0, 1, 0,
-  0, 19, 0, 19, 0, 50, 59, 42, 0, 14,
-  0, 45, 0, 0, 97, 0, 62, 0, 33, 0,
-  0, 70, 0, 0, 53, 0, 0, 26, 12, 6,
-  27, 25, 76, 0, 0, 26, 25, 0, 0, 18,
-  0, 0, 77, 83, 0, 0, 0, 18, 0, 4,
-  54, 0, 0, 0, 24, 0, 25, 0, 15, 39,
-  25, 35, 17, 0, 0, 31, 47, 29, 0, 0,
-  0, 45, 0, 0, 0, 0, 38, 0, 3, 0,
-  0, 1, 0, 22, 25, 0, 0, 20, 0, 0,
-  0, 0, 1, 125, 0, 0, 0, 0, 0, 0,
-  59, 8, 0, 44, 12, 40, 18, 0, 40, 6,
-  0, 49, 0, 0, 0, 0, 0, 14, 40, 0,
-  0, 17, 0, 8, 0, 16, 0, 48, 35, 47,
-  0, 33, 1, 0, 7, 27, 0, 35, 0, 77,
-  28, 0, 14, 0, 38, 0, 36, 0, 0, 14,
-  0, 11, 0, 0, 0, 3, 8, 0, 16, 34,
-  27, 15, 0, 70, 0, 0, 0, 26, 7, 0,
-  14, 12, 42, 0, 12, 0, 8, 25, 0, 47,
-  52, 0, 15, 13, 0, 0, 17, 28, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 32, 29, 12,
-  0, 47, 0, 0, 66, 14, 50, 0, 35, 14,
-  18, 0, 67, 1, 0, 0, 19, 83, 100, 57,
-  60, 86, 0, 0, 16, 0, 0, 0, 1, 37,
-  9, 22, 45, 0, 3, 24, 0, 9, 0, 26,
-  12, 0, 0, 30, 0, 58, 0, 45, 5, 36,
-  29, 8, 0, 14, 0, 6, 0, 0, 0, 30,
-  1, 47, 31, 38, 0, 0, 15, 0, 0, 0,
-  7, 0, 28, 11, 0, 0, 0, 19, 0, 0,
-  0, 0, 25, 0, 71, 0, 0, 0, 48, 11,
-  37, 0, 0, 0, 0, 14, 0, 10, 19, 113,
-  22, 41, 0, 37, 0, 20, 39, 0, 0, 0,
-  11, 0, 10, 0, 0, 52, 9, 11, 0, 0,
-  76, 50, 5, 16, 33, 0, 25, 22, 0, 4,
-  0, 0, 10, 0, 0, 0, 0, 0, 0, 0,
-  34, 0, 47, 18, 11, 11, 105, 33, 25, 144,
-  0, 0, 0, 0, 0, 0, 17, 0, 0, 0,
-  17, 5, 23, 0, 0, 94, 8, 12, 0, 0,
-  0, 0, 0, 52, 0, 26, 0, 34, 0, 30,
-  0, 0, 0, 25, 0, 0, 0, 39, 0, 0,
-  23, 37, 0, 0, 0, 86, 0, 0, 64, 0,
-  59, 0, 41, 0, 0, 32, 0, 17, 51, 3,
-  0, 0, 41, 0, 4, 7, 56, 0, 27, 0,
-  0, 0, 0, 10, 0, 0, 45, 50, 55, 11,
-  0, 9, 2, 0, 0, 0, 20, 0, 18, 0,
-  0, 0, 20, 19, 0, 0, 0, 0, 22, 38,
-  4, 0, 0, 0, 37, 28, 0, 0, 0, 0,
-  63, 0, 8, 0, 0, 0, 0, 12, 39, 5,
-  0, 0, 0, 2, 46, 0, 14, 18, 11, 0,
-  12, 0, 0, 11, 59, 26, 0, 39, 3, 30,
-  27, 0, 68, 23, 33, 23, 0, 0, 0, 0,
-  0, 0, 61, 0, 0, 0, 0, 7, 0, 8,
-  0, 25, 64, 32, 0, 78, 13, 0, 0, 10,
-  0, 12, 0, 114, 19, 0, 44, 0, 53, 0,
-  52, 0, 0, 0, 0, 20, 19, 0, 0, 11,
-  0, 0, 0, 19, 15, 39, 5, 36, 0, 0,
-  0, 0, 27, 0, 8, 0, 65, 1, 0, 0,
-  39, 0, 0, 25, 36, 0, 0, 17, 0, 0,
-  33, 36, 0, 0, 0, 0, 22, 0, 0, 0,
-  0, 13, 66, 18, 0, 34, 0, 0, 63, 12,
-  74, 5, 47, 3, 0, 0, 82, 14, 12, 0,
-  24, 50, 130, 56, 9, 113, 0, 0, 0, 0,
-  0, 0, 18, 53, 0, 15, 32, 9, 0, 14,
-  0, 26, 0, 12, 0, 0, 0, 0, 0, 68,
-  18, 55, 0, 60, 43, 18, 30, 1, 0, 18,
-  0, 0, 0, 3, 0, 17, 0, 39, 0, 0,
-  36, 38, 0, 0, 41, 0, 32, 16, 29, 0,
-  0, 0, 0, 0, 31, 0, 0, 0, 41, 0,
-  0, 0, 42, 0, 0, 3, 0, 0, 2, 46,
-  0, 22, 20, 94, 27, 22, 13, 1, 28, 26,
-  6, 0, 0, 0, 15, 0, 0, 0, 0, 25,
-  2, 0, 0, 0, 20, 67, 0, 0, 0, 2,
-  64, 0, 0, 16, 0, 0, 21, 0, 0, 13,
-  0, 0, 0, 18, 28, 25, 23, 8, 18, 29,
-  81, 2, 20, 83, 0, 0, 0, 0, 0, 0,
-  29, 22, 0, 0, 11, 0, 22, 0, 16, 80,
-  7, 25, 0, 0, 0, 0, 0, 50, 53, 0,
-  0, 40, 19, 7, 0, 0, 0, 34, 18, 28,
-  0, 28, 19, 0, 0, 38, 0, 0, 0, 100,
-  0, 0, 72, 0, 56, 27, 67, 0, 0, 10,
-  0, 45, 0, 38, 0, 0, 0, 0, 0, 13,
-  35, 21, 7, 22, 0, 0, 0, 14, 4, 0,
-  18, 9, 61, 9, 0, 0, 33, 0, 0, 2,
-  69, 0, 11, 0, 0, 0, 29, 21, 0, 0,
-  0, 0, 26, 25, 0, 0, 0, 32, 64, 0,
-  0, 16, 0, 0, 50, 0, 17, 27, 16, 8,
-  0, 0, 53, 22, 0, 8, 0, 3, 48, 0,
-  28, 0, 0, 0, 12, 0, 0, 8, 33, 45,
-  0, 3, 0, 28, 37, 0, 73, 40, 75, 3,
-  0, 0, 0, 6, 0, 0, 38, 0, 0, 0,
-  0, 17, 0, 11, 18, 0, 45, 20, 0, 94,
-  30, 2, 0, 37, 0, 0, 0, 118, 0, 0,
-  57, 0, 32, 0, 52, 0, 0, 0, 6, 0,
-  65, 0, 0, 28, 0, 6, 0, 7, 0, 28,
-  10, 0, 0, 0, 0, 0, 20, 0, 18, 0,
-  66, 3, 0, 0, 33, 0, 0, 0, 0, 0,
-  0, 35, 0, 0, 33, 47, 0, 0, 0, 0,
-  30, 0, 0, 0, 0, 0, 68, 9, 0, 32,
-  0, 0, 91, 10, 53, 25, 59, 0, 0, 0,
-  63, 11, 16, 0, 17, 8, 86, 68, 23, 217,
-  0, 0, 29, 0, 0, 0, 32, 0, 0, 0,
-  31, 18, 66, 0, 0, 112, 15, 8, 7, 0,
-  0, 35, 0, 72, 0, 82, 0, 0, 0, 30,
-  0, 0, 1, 0, 0, 19, 0, 19, 0, 50,
-  59, 42, 0, 14, 0, 45, 0, 0, 97, 0,
-  62, 0, 33, 0, 0, 70, 0, 0, 53, 0,
-  0, 26, 12, 6, 27, 25, 76, 0, 0, 26,
-  25, 0, 0, 18, 0, 0, 77, 83, 0, 0,
-  0, 18, 0, 4, 54, 0, 0, 0, 24, 0,
-  25, 0, 15, 39, 25, 35, 17, 0, 0, 31,
-  47, 29, 0, 0, 0, 45, 0, 0, 0, 0,
-  38, 0, 3, 0, 0, 1, 0, 22, 25, 0,
-  0, 20, 0, 0, 0, 0, 1, 125, 0, 0,
-  0, 0, 0, 0, 59, 8, 0, 44, 12, 40,
-  18, 0, 40, 6, 0, 49, 0, 0, 0, 0,
-  0, 14, 40, 0, 0, 17, 0, 8, 0, 16,
-  0, 48, 35, 47, 0, 33, 1, 0, 7, 27,
-  0, 35, 0, 77, 28, 0, 14, 0, 38, 0,
-  36, 0, 0, 14, 0, 11, 0, 0, 0, 3,
-  8, 0, 16, 34, 27, 15, 0, 70, 0, 0,
-  0, 26, 7, 0, 14, 12, 42, 0, 12, 0,
-  8, 25, 0, 47, 52, 0, 15, 13, 0, 0,
-  17, 28, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 32, 29, 12, 0, 47, 0, 0, 66, 14,
-  50, 0, 35, 14, 18, 0, 67, 1, 0, 0,
-  0, 0, 77, 0, 0, 0, 2, 0, 0, 0,
-  0, 1, 29, 58, 0, 41, 0, 69, 29, 7,
-  59, 19, 117, 17, 0, 0, 0, 5, 0, 0,
-  15, 0, 0, 0, 0, 13, 0, 12, 0, 0,
-  66, 0, 0, 79, 32, 0, 0, 0, 0, 6,
-  0, 87, 7, 0, 39, 0, 49, 0, 7, 0,
-  0, 1, 10, 0, 77, 0, 0, 21, 0, 50,
-  0, 0, 2, 19, 0, 7, 0, 0, 0, 0,
-  19, 0, 2, 0, 62, 8, 0, 0, 25, 0,
-  0, 13, 0, 0, 16, 30, 0, 0, 0, 54,
-  3, 0, 0, 0, 20, 0, 0, 0, 0, 0,
-  62, 11, 0, 38, 13, 0, 89, 23, 44, 14,
-  34, 0, 0, 0, 57, 0, 15, 0, 11, 11,
-  105, 33, 25, 144, 0, 0, 0, 0, 0, 0,
-  17, 0, 0, 0, 17, 5, 23, 0, 0, 94,
-  8, 12, 0, 0, 0, 0, 0, 52, 0, 26,
-  0, 34, 0, 30, 0, 0, 0, 25, 0, 0,
-  0, 39, 0, 0, 23, 37, 0, 0, 0, 86,
-  0, 0, 64, 0, 59, 0, 41, 0, 0, 32,
-  0, 17, 51, 3, 0, 0, 41, 0, 4, 7,
-  56, 0, 27, 0, 0, 0, 0, 10, 0, 0,
-  45, 50, 55, 11, 0, 9, 2, 0, 0, 0,
-  20, 0, 18, 0, 0, 0, 20, 19, 0, 0,
-  0, 0, 22, 38, 4, 0, 0, 0, 37, 28,
-  0, 0, 0, 0, 63, 0, 8, 0, 0, 0,
-  0, 12, 39, 5, 0, 0, 0, 2, 46, 0,
-  14, 18, 11, 0, 12, 0, 0, 11, 59, 26,
-  0, 39, 3, 30, 27, 0, 68, 23, 33, 23,
-  0, 0, 0, 0, 0, 0, 61, 0, 0, 0,
-  0, 7, 0, 8, 0, 25, 64, 32, 0, 78,
-  13, 0, 0, 10, 0, 12, 0, 114, 19, 0,
-  44, 0, 53, 0, 52, 0, 0, 0, 0, 20,
-  19, 0, 0, 11, 0, 0, 0, 19, 15, 39,
-  5, 36, 0, 0, 0, 0, 27, 0, 8, 0,
-  65, 1, 0, 0, 39, 0, 0, 25, 36, 0,
-  0, 17, 0, 0, 33, 36, 0, 0, 0, 0,
-  22, 0, 0, 0, 0, 13, 66, 18, 0, 34,
-  0, 0, 63, 12, 74, 5, 47, 3, 0, 0,
-  82, 14, 12, 0, 5, 0, 69, 0, 12, 8,
-  0, 0, 19, 0, 0, 0, 40, 75, 0, 7,
-  0, 50, 40, 0, 68, 50, 83, 1, 0, 0,
-  0, 31, 0, 3, 20, 0, 0, 0, 0, 5,
-  0, 22, 0, 0, 22, 4, 0, 91, 26, 21,
-  0, 48, 0, 0, 1, 153, 0, 0, 66, 0,
-  33, 0, 18, 0, 0, 0, 11, 0, 112, 0,
-  0, 0, 0, 59, 0, 0, 0, 7, 0, 0,
-  0, 0, 0, 0, 9, 0, 15, 0, 36, 8,
-  0, 0, 45, 0, 0, 0, 0, 0, 6, 8,
-  0, 0, 1, 53, 30, 0, 0, 0, 16, 0,
-  0, 5, 5, 0, 72, 5, 0, 42, 10, 0,
-  150, 0, 30, 25, 71, 0, 0, 0, 50, 0,
-  12, 0, 18, 29, 81, 2, 20, 83, 0, 0,
-  0, 0, 0, 0, 29, 22, 0, 0, 11, 0,
-  22, 0, 16, 80, 7, 25, 0, 0, 0, 0,
-  0, 50, 53, 0, 0, 40, 19, 7, 0, 0,
-  0, 34, 18, 28, 0, 28, 19, 0, 0, 38,
-  0, 0, 0, 100, 0, 0, 72, 0, 56, 27,
-  67, 0, 0, 10, 0, 45, 0, 38, 0, 0,
-  0, 0, 0, 13, 35, 21, 7, 22, 0, 0,
-  0, 14, 4, 0, 18, 9, 61, 9, 0, 0,
-  33, 0, 0, 2, 69, 0, 11, 0, 0, 0,
-  29, 21, 0, 0, 0, 0, 26, 25, 0, 0,
-  0, 32, 64, 0, 0, 16, 0, 0, 50, 0,
-  17, 27, 16, 8, 0, 0, 53, 22, 0, 8,
-  0, 3, 48, 0, 28, 0, 0, 0, 12, 0,
-  0, 8, 33, 45, 0, 3, 0, 28, 37, 0,
-  73, 40, 75, 3, 0, 0, 0, 6, 0, 0,
-  38, 0, 0, 0, 0, 17, 0, 11, 18, 0,
-  45, 20, 0, 94, 30, 2, 0, 37, 0, 0,
-  0, 118, 0, 0, 57, 0, 32, 0, 52, 0,
-  0, 0, 6, 0, 65, 0, 0, 28, 0, 6,
-  0, 7, 0, 28, 10, 0, 0, 0, 0, 0,
-  20, 0, 18, 0, 66, 3, 0, 0, 33, 0,
-  0, 0, 0, 0, 0, 35, 0, 0, 33, 47,
-  0, 0, 0, 0, 30, 0, 0, 0, 0, 0,
-  68, 9, 0, 32, 0, 0, 91, 10, 53, 25,
-  59, 0, 0, 0, 63, 11, 16, 0, 8, 0,
-  33, 0, 50, 5, 0, 0, 41, 0, 0, 0,
-  30, 75, 0, 0, 0, 14, 33, 0, 50, 46,
-  16, 2, 0, 0, 0, 31, 0, 34, 0, 0,
-  0, 0, 0, 2, 0, 20, 0, 0, 0, 0,
-  0, 77, 19, 41, 0, 85, 0, 0, 0, 170,
-  0, 6, 47, 0, 22, 0, 0, 0, 0, 0,
-  0, 0, 84, 0, 0, 0, 0, 41, 0, 0,
-  0, 17, 0, 0, 0, 0, 0, 0, 22, 0,
-  8, 0, 16, 0, 0, 30, 54, 0, 23, 0,
-  0, 0, 0, 0, 8, 0, 0, 58, 30, 0,
-  2, 0, 14, 0, 12, 18, 40, 0, 63, 5,
-  0, 35, 4, 0, 159, 0, 5, 42, 83, 1,
-  29, 0, 53, 0, 1, 0, 0, 0, 0, 0,
-  1, 125, 0, 0, 0, 0, 0, 0, 59, 8,
-  0, 44, 12, 40, 18, 0, 40, 6, 0, 49,
-  0, 0, 0, 0, 0, 14, 40, 0, 0, 17,
-  0, 8, 0, 16, 0, 48, 35, 47, 0, 33,
-  1, 0, 7, 27, 0, 35, 0, 77, 28, 0,
-  14, 0, 38, 0, 36, 0, 0, 14, 0, 11,
-  0, 0, 0, 3, 8, 0, 16, 34, 27, 15,
-  0, 70, 0, 0, 0, 26, 7, 0, 14, 12,
-  42, 0, 12, 0, 8, 25, 0, 47, 52, 0,
-  15, 13, 0, 0, 17, 28, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 32, 29, 12, 0, 47,
-  0, 0, 66, 14, 50, 0, 35, 14, 18, 0,
-  67, 1, 0, 0, 0, 0, 77, 0, 0, 0,
-  2, 0, 0, 0, 0, 1, 29, 58, 0, 41,
-  0, 69, 29, 7, 59, 19, 117, 17, 0, 0,
-  0, 5, 0, 0, 15, 0, 0, 0, 0, 13,
-  0, 12, 0, 0, 66, 0, 0, 79, 32, 0,
-  0, 0, 0, 6, 0, 87, 7, 0, 39, 0,
-  49, 0, 7, 0, 0, 1, 10, 0, 77, 0,
-  0, 21, 0, 50, 0, 0, 2, 19, 0, 7,
-  0, 0, 0, 0, 19, 0, 2, 0, 62, 8,
-  0, 0, 25, 0, 0, 13, 0, 0, 16, 30,
-  0, 0, 0, 54, 3, 0, 0, 0, 20, 0,
-  0, 0, 0, 0, 62, 11, 0, 38, 13, 0,
-  89, 23, 44, 14, 34, 0, 0, 0, 57, 0,
-  15, 0, 25, 0, 64, 0, 17, 12, 0, 0,
-  23, 0, 0, 6, 16, 72, 0, 0, 0, 19,
-  42, 0, 48, 60, 61, 0, 0, 0, 0, 26,
-  0, 41, 0, 0, 0, 0, 0, 3, 0, 6,
-  0, 0, 0, 0, 0, 69, 18, 17, 0, 65,
-  0, 0, 0, 167, 0, 0, 66, 0, 29, 0,
-  4, 0, 0, 0, 24, 0, 113, 0, 0, 10,
-  0, 64, 0, 4, 0, 0, 0, 0, 0, 0,
-  0, 0, 12, 0, 12, 0, 32, 1, 0, 15,
-  43, 0, 26, 0, 0, 0, 27, 0, 11, 0,
-  0, 71, 39, 0, 0, 0, 13, 0, 0, 24,
-  30, 0, 73, 0, 0, 44, 14, 0, 155, 0,
-  5, 26, 74, 0, 0, 0, 54, 0, 0, 0,
-  0, 2, 46, 0, 14, 18, 11, 0, 12, 0,
-  0, 11, 59, 26, 0, 39, 3, 30, 27, 0,
-  68, 23, 33, 23, 0, 0, 0, 0, 0, 0,
-  61, 0, 0, 0, 0, 7, 0, 8, 0, 25,
-  64, 32, 0, 78, 13, 0, 0, 10, 0, 12,
-  0, 114, 19, 0, 44, 0, 53, 0, 52, 0,
-  0, 0, 0, 20, 19, 0, 0, 11, 0, 0,
-  0, 19, 15, 39, 5, 36, 0, 0, 0, 0,
-  27, 0, 8, 0, 65, 1, 0, 0, 39, 0,
-  0, 25, 36, 0, 0, 17, 0, 0, 33, 36,
-  0, 0, 0, 0, 22, 0, 0, 0, 0, 13,
-  66, 18, 0, 34, 0, 0, 63, 12, 74, 5,
-  47, 3, 0, 0, 82, 14, 12, 0, 5, 0,
-  69, 0, 12, 8, 0, 0, 19, 0, 0, 0,
-  40, 75, 0, 7, 0, 50, 40, 0, 68, 50,
-  83, 1, 0, 0, 0, 31, 0, 3, 20, 0,
-  0, 0, 0, 5, 0, 22, 0, 0, 22, 4,
-  0, 91, 26, 21, 0, 48, 0, 0, 1, 153,
-  0, 0, 66, 0, 33, 0, 18, 0, 0, 0,
-  11, 0, 112, 0, 0, 0, 0, 59, 0, 0,
-  0, 7, 0, 0, 0, 0, 0, 0, 9, 0,
-  15, 0, 36, 8, 0, 0, 45, 0, 0, 0,
-  0, 0, 6, 8, 0, 0, 1, 53, 30, 0,
-  0, 0, 16, 0, 0, 5, 5, 0, 72, 5,
-  0, 42, 10, 0, 150, 0, 30, 25, 71, 0,
-  0, 0, 50, 0, 12, 0, 0, 0, 9, 0,
-  23, 7, 0, 0, 42, 0, 0, 0, 8, 47,
-  0, 0, 0, 0, 32, 0, 34, 11, 0, 18,
-  0, 0, 19, 48, 0, 74, 0, 0, 9, 0,
-  0, 0, 0, 14, 0, 0, 0, 0, 0, 37,
-  0, 40, 0, 86, 0, 0, 8, 140, 13, 21,
-  34, 0, 22, 0, 0, 0, 0, 0, 0, 0,
-  51, 0, 0, 0, 0, 14, 0, 9, 0, 0,
-  0, 24, 0, 0, 0, 11, 28, 0, 0, 0,
-  0, 0, 0, 47, 50, 10, 57, 0, 0, 0,
-  10, 0, 28, 0, 0, 84, 46, 0, 26, 0,
-  7, 0, 21, 14, 59, 0, 50, 0, 0, 36,
-  7, 0, 152, 0, 0, 31, 100, 6, 74, 0,
-  41, 0, 0, 0, 0, 3, 48, 0, 28, 0,
-  0, 0, 12, 0, 0, 8, 33, 45, 0, 3,
-  0, 28, 37, 0, 73, 40, 75, 3, 0, 0,
-  0, 6, 0, 0, 38, 0, 0, 0, 0, 17,
-  0, 11, 18, 0, 45, 20, 0, 94, 30, 2,
-  0, 37, 0, 0, 0, 118, 0, 0, 57, 0,
-  32, 0, 52, 0, 0, 0, 6, 0, 65, 0,
-  0, 28, 0, 6, 0, 7, 0, 28, 10, 0,
-  0, 0, 0, 0, 20, 0, 18, 0, 66, 3,
-  0, 0, 33, 0, 0, 0, 0, 0, 0, 35,
-  0, 0, 33, 47, 0, 0, 0, 0, 30, 0,
-  0, 0, 0, 0, 68, 9, 0, 32, 0, 0,
-  91, 10, 53, 25, 59, 0, 0, 0, 63, 11,
-  16, 0, 8, 0, 33, 0, 50, 5, 0, 0,
-  41, 0, 0, 0, 30, 75, 0, 0, 0, 14,
-  33, 0, 50, 46, 16, 2, 0, 0, 0, 31,
-  0, 34, 0, 0, 0, 0, 0, 2, 0, 20,
-  0, 0, 0, 0, 0, 77, 19, 41, 0, 85,
-  0, 0, 0, 170, 0, 6, 47, 0, 22, 0,
-  0, 0, 0, 0, 0, 0, 84, 0, 0, 0,
-  0, 41, 0, 0, 0, 17, 0, 0, 0, 0,
-  0, 0, 22, 0, 8, 0, 16, 0, 0, 30,
-  54, 0, 23, 0, 0, 0, 0, 0, 8, 0,
-  0, 58, 30, 0, 2, 0, 14, 0, 12, 18,
-  40, 0, 63, 5, 0, 35, 4, 0, 159, 0,
-  5, 42, 83, 1, 29, 0, 53, 0, 1, 0,
-  0, 0, 0, 0, 8, 8, 0, 23, 35, 18,
-  0, 1, 2, 8, 0, 7, 6, 22, 10, 0,
-  3, 0, 0, 46, 0, 0, 38, 57, 0, 84,
-  0, 0, 66, 0, 0, 0, 0, 16, 0, 0,
-  0, 0, 1, 25, 24, 69, 0, 69, 0, 1,
-  25, 65, 56, 29, 12, 5, 16, 0, 0, 0,
-  0, 6, 0, 0, 0, 0, 12, 0, 0, 0,
-  0, 0, 13, 10, 0, 63, 0, 0, 0, 19,
-  57, 0, 0, 20, 0, 0, 0, 46, 34, 26,
-  87, 1, 0, 0, 7, 0, 9, 0, 0, 65,
-  36, 0, 32, 0, 1, 0, 50, 0, 55, 43,
-  17, 0, 0, 23, 0, 0, 119, 0, 0, 38,
-  90, 12, 104, 0, 46, 0, 0, 0, 0, 0,
-  77, 0, 0, 0, 2, 0, 0, 0, 0, 1,
-  29, 58, 0, 41, 0, 69, 29, 7, 59, 19,
-  117, 17, 0, 0, 0, 5, 0, 0, 15, 0,
-  0, 0, 0, 13, 0, 12, 0, 0, 66, 0,
-  0, 79, 32, 0, 0, 0, 0, 6, 0, 87,
-  7, 0, 39, 0, 49, 0, 7, 0, 0, 1,
-  10, 0, 77, 0, 0, 21, 0, 50, 0, 0,
-  2, 19, 0, 7, 0, 0, 0, 0, 19, 0,
-  2, 0, 62, 8, 0, 0, 25, 0, 0, 13,
-  0, 0, 16, 30, 0, 0, 0, 54, 3, 0,
-  0, 0, 20, 0, 0, 0, 0, 0, 62, 11,
-  0, 38, 13, 0, 89, 23, 44, 14, 34, 0,
-  0, 0, 57, 0, 15, 0, 25, 0, 64, 0,
-  17, 12, 0, 0, 23, 0, 0, 6, 16, 72,
-  0, 0, 0, 19, 42, 0, 48, 60, 61, 0,
-  0, 0, 0, 26, 0, 41, 0, 0, 0, 0,
-  0, 3, 0, 6, 0, 0, 0, 0, 0, 69,
-  18, 17, 0, 65, 0, 0, 0, 167, 0, 0,
-  66, 0, 29, 0, 4, 0, 0, 0, 24, 0,
-  113, 0, 0, 10, 0, 64, 0, 4, 0, 0,
-  0, 0, 0, 0, 0, 0, 12, 0, 12, 0,
-  32, 1, 0, 15, 43, 0, 26, 0, 0, 0,
-  27, 0, 11, 0, 0, 71, 39, 0, 0, 0,
-  13, 0, 0, 24, 30, 0, 73, 0, 0, 44,
-  14, 0, 155, 0, 5, 26, 74, 0, 0, 0,
-  54, 0, 0, 0, 0, 0, 0, 0, 12, 0,
-  0, 14, 34, 15, 0, 0, 26, 34, 0, 0,
-  0, 21, 29, 0, 8, 0, 0, 45, 0, 0,
-  48, 64, 6, 83, 0, 0, 55, 0, 0, 0,
-  0, 1, 0, 5, 0, 0, 0, 16, 10, 46,
-  0, 58, 0, 8, 7, 104, 37, 30, 33, 0,
-  15, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  6, 0, 0, 19, 0, 0, 21, 0, 0, 63,
-  0, 0, 0, 9, 39, 0, 0, 13, 0, 0,
-  0, 59, 43, 21, 114, 3, 0, 0, 28, 0,
-  36, 0, 0, 91, 40, 0, 32, 0, 7, 0,
-  28, 8, 75, 20, 37, 0, 0, 8, 5, 0,
-  131, 0, 0, 37, 103, 0, 101, 0, 70, 0,
-  0, 0, 5, 0, 69, 0, 12, 8, 0, 0,
-  19, 0, 0, 0, 40, 75, 0, 7, 0, 50,
-  40, 0, 68, 50, 83, 1, 0, 0, 0, 31,
-  0, 3, 20, 0, 0, 0, 0, 5, 0, 22,
-  0, 0, 22, 4, 0, 91, 26, 21, 0, 48,
-  0, 0, 1, 153, 0, 0, 66, 0, 33, 0,
-  18, 0, 0, 0, 11, 0, 112, 0, 0, 0,
-  0, 59, 0, 0, 0, 7, 0, 0, 0, 0,
-  0, 0, 9, 0, 15, 0, 36, 8, 0, 0,
-  45, 0, 0, 0, 0, 0, 6, 8, 0, 0,
-  1, 53, 30, 0, 0, 0, 16, 0, 0, 5,
-  5, 0, 72, 5, 0, 42, 10, 0, 150, 0,
-  30, 25, 71, 0, 0, 0, 50, 0, 12, 0,
-  0, 0, 9, 0, 23, 7, 0, 0, 42, 0,
-  0, 0, 8, 47, 0, 0, 0, 0, 32, 0,
-  34, 11, 0, 18, 0, 0, 19, 48, 0, 74,
-  0, 0, 9, 0, 0, 0, 0, 14, 0, 0,
-  0, 0, 0, 37, 0, 40, 0, 86, 0, 0,
-  8, 140, 13, 21, 34, 0, 22, 0, 0, 0,
-  0, 0, 0, 0, 51, 0, 0, 0, 0, 14,
-  0, 9, 0, 0, 0, 24, 0, 0, 0, 11,
-  28, 0, 0, 0, 0, 0, 0, 47, 50, 10,
-  57, 0, 0, 0, 10, 0, 28, 0, 0, 84,
-  46, 0, 26, 0, 7, 0, 21, 14, 59, 0,
-  50, 0, 0, 36, 7, 0, 152, 0, 0, 31,
-  100, 6, 74, 0, 41, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 24, 26, 15, 20, 0, 5,
-  0, 0, 4, 23, 15, 29, 19, 5, 0, 0,
-  0, 56, 21, 39, 37, 55, 0, 52, 0, 0,
-  82, 0, 11, 0, 0, 14, 0, 19, 0, 6,
-  0, 1, 10, 45, 30, 46, 0, 40, 24, 27,
-  55, 43, 0, 0, 9, 0, 0, 42, 0, 0,
-  0, 0, 0, 0, 32, 0, 0, 0, 0, 2,
-  11, 0, 20, 67, 0, 0, 0, 27, 69, 0,
-  0, 21, 0, 0, 2, 43, 16, 39, 82, 7,
-  0, 0, 15, 0, 21, 0, 0, 53, 8, 0,
-  42, 0, 0, 0, 48, 0, 67, 45, 15, 0,
-  2, 4, 0, 0, 73, 0, 0, 11, 69, 15,
-  131, 0, 65, 0, 0, 0, 8, 0, 33, 0,
-  50, 5, 0, 0, 41, 0, 0, 0, 30, 75,
-  0, 0, 0, 14, 33, 0, 50, 46, 16, 2,
-  0, 0, 0, 31, 0, 34, 0, 0, 0, 0,
-  0, 2, 0, 20, 0, 0, 0, 0, 0, 77,
-  19, 41, 0, 85, 0, 0, 0, 170, 0, 6,
-  47, 0, 22, 0, 0, 0, 0, 0, 0, 0,
-  84, 0, 0, 0, 0, 41, 0, 0, 0, 17,
-  0, 0, 0, 0, 0, 0, 22, 0, 8, 0,
-  16, 0, 0, 30, 54, 0, 23, 0, 0, 0,
-  0, 0, 8, 0, 0, 58, 30, 0, 2, 0,
-  14, 0, 12, 18, 40, 0, 63, 5, 0, 35,
-  4, 0, 159, 0, 5, 42, 83, 1, 29, 0,
-  53, 0, 1, 0, 0, 0, 0, 0, 8, 8,
-  0, 23, 35, 18, 0, 1, 2, 8, 0, 7,
-  6, 22, 10, 0, 3, 0, 0, 46, 0, 0,
-  38, 57, 0, 84, 0, 0, 66, 0, 0, 0,
-  0, 16, 0, 0, 0, 0, 1, 25, 24, 69,
-  0, 69, 0, 1, 25, 65, 56, 29, 12, 5,
-  16, 0, 0, 0, 0, 6, 0, 0, 0, 0,
-  12, 0, 0, 0, 0, 0, 13, 10, 0, 63,
-  0, 0, 0, 19, 57, 0, 0, 20, 0, 0,
-  0, 46, 34, 26, 87, 1, 0, 0, 7, 0,
-  9, 0, 0, 65, 36, 0, 32, 0, 1, 0,
-  50, 0, 55, 43, 17, 0, 0, 23, 0, 0,
-  119, 0, 0, 38, 90, 12, 104, 0, 46, 0,
-  0, 0, 0, 20, 0, 0, 0, 0, 29, 14,
-  2, 19, 0, 0, 0, 0, 38, 41, 27, 40,
-  14, 6, 0, 0, 0, 54, 43, 60, 8, 44,
-  0, 27, 0, 0, 65, 7, 13, 0, 0, 22,
-  3, 41, 0, 34, 37, 0, 17, 26, 31, 26,
-  0, 52, 14, 29, 52, 44, 0, 0, 0, 0,
-  0, 20, 0, 0, 0, 0, 0, 10, 54, 0,
-  11, 0, 0, 0, 18, 12, 28, 41, 0, 0,
-  0, 31, 87, 0, 6, 24, 0, 0, 7, 23,
-  21, 17, 38, 3, 0, 3, 0, 15, 11, 0,
-  0, 33, 0, 2, 25, 0, 0, 0, 36, 0,
-  28, 44, 10, 0, 0, 0, 0, 0, 17, 0,
-  0, 11, 27, 15, 97, 0, 59, 0, 0, 0,
-  25, 0, 64, 0, 17, 12, 0, 0, 23, 0,
-  0, 6, 16, 72, 0, 0, 0, 19, 42, 0,
-  48, 60, 61, 0, 0, 0, 0, 26, 0, 41,
-  0, 0, 0, 0, 0, 3, 0, 6, 0, 0,
-  0, 0, 0, 69, 18, 17, 0, 65, 0, 0,
-  0, 167, 0, 0, 66, 0, 29, 0, 4, 0,
-  0, 0, 24, 0, 113, 0, 0, 10, 0, 64,
-  0, 4, 0, 0, 0, 0, 0, 0, 0, 0,
-  12, 0, 12, 0, 32, 1, 0, 15, 43, 0,
-  26, 0, 0, 0, 27, 0, 11, 0, 0, 71,
-  39, 0, 0, 0, 13, 0, 0, 24, 30, 0,
-  73, 0, 0, 44, 14, 0, 155, 0, 5, 26,
-  74, 0, 0, 0, 54, 0, 0, 0, 0, 0,
-  0, 0, 12, 0, 0, 14, 34, 15, 0, 0,
-  26, 34, 0, 0, 0, 21, 29, 0, 8, 0,
-  0, 45, 0, 0, 48, 64, 6, 83, 0, 0,
-  55, 0, 0, 0, 0, 1, 0, 5, 0, 0,
-  0, 16, 10, 46, 0, 58, 0, 8, 7, 104,
-  37, 30, 33, 0, 15, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 6, 0, 0, 19, 0, 0,
-  21, 0, 0, 63, 0, 0, 0, 9, 39, 0,
-  0, 13, 0, 0, 0, 59, 43, 21, 114, 3,
-  0, 0, 28, 0, 36, 0, 0, 91, 40, 0,
-  32, 0, 7, 0, 28, 8, 75, 20, 37, 0,
-  0, 8, 5, 0, 131, 0, 0, 37, 103, 0,
-  101, 0, 70, 0, 0, 0, 0, 6, 23, 5,
-  0, 0, 44, 22, 34, 36, 0, 0, 1, 0,
-  0, 41, 20, 23, 3, 8, 0, 0, 0, 69,
-  18, 19, 51, 49, 164, 7, 0, 0, 85, 0,
-  15, 0, 0, 31, 6, 63, 0, 3, 29, 0,
-  23, 56, 20, 0, 0, 47, 0, 43, 48, 47,
-  7, 0, 0, 20, 0, 28, 0, 23, 0, 0,
-  0, 3, 58, 0, 2, 0, 18, 22, 54, 25,
-  23, 58, 0, 0, 0, 13, 76, 0, 7, 17,
-  0, 0, 4, 37, 62, 48, 83, 0, 0, 0,
-  8, 13, 24, 0, 0, 55, 0, 0, 26, 0,
-  38, 0, 56, 0, 44, 17, 29, 0, 10, 0,
-  0, 0, 37, 0, 0, 16, 21, 0, 77, 0,
-  71, 0, 5, 0, 0, 0, 9, 0, 23, 7,
-  0, 0, 42, 0, 0, 0, 8, 47, 0, 0,
-  0, 0, 32, 0, 34, 11, 0, 18, 0, 0,
-  19, 48, 0, 74, 0, 0, 9, 0, 0, 0,
-  0, 14, 0, 0, 0, 0, 0, 37, 0, 40,
-  0, 86, 0, 0, 8, 140, 13, 21, 34, 0,
-  22, 0, 0, 0, 0, 0, 0, 0, 51, 0,
-  0, 0, 0, 14, 0, 9, 0, 0, 0, 24,
-  0, 0, 0, 11, 28, 0, 0, 0, 0, 0,
-  0, 47, 50, 10, 57, 0, 0, 0, 10, 0,
-  28, 0, 0, 84, 46, 0, 26, 0, 7, 0,
-  21, 14, 59, 0, 50, 0, 0, 36, 7, 0,
-  152, 0, 0, 31, 100, 6, 74, 0, 41, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 24, 26,
-  15, 20, 0, 5, 0, 0, 4, 23, 15, 29,
-  19, 5, 0, 0, 0, 56, 21, 39, 37, 55,
-  0, 52, 0, 0, 82, 0, 11, 0, 0, 14,
-  0, 19, 0, 6, 0, 1, 10, 45, 30, 46,
-  0, 40, 24, 27, 55, 43, 0, 0, 9, 0,
-  0, 42, 0, 0, 0, 0, 0, 0, 32, 0,
-  0, 0, 0, 2, 11, 0, 20, 67, 0, 0,
-  0, 27, 69, 0, 0, 21, 0, 0, 2, 43,
-  16, 39, 82, 7, 0, 0, 15, 0, 21, 0,
-  0, 53, 8, 0, 42, 0, 0, 0, 48, 0,
-  67, 45, 15, 0, 2, 4, 0, 0, 73, 0,
-  0, 11, 69, 15, 131, 0, 65, 0, 0, 0,
-  0, 21, 39, 0, 0, 0, 39, 17, 22, 19,
-  5, 0, 0, 0, 20, 45, 30, 23, 5, 22,
-  0, 0, 0, 63, 27, 30, 38, 35, 115, 0,
-  0, 0, 74, 0, 11, 0, 0, 35, 3, 71,
-  0, 30, 31, 0, 4, 24, 50, 0, 0, 63,
-  18, 33, 32, 49, 0, 0, 0, 28, 0, 17,
-  6, 0, 0, 0, 0, 3, 73, 0, 42, 0,
-  0, 21, 39, 30, 32, 29, 0, 11, 0, 17,
-  87, 0, 23, 13, 0, 0, 7, 29, 62, 11,
-  41, 0, 0, 0, 0, 12, 26, 0, 0, 45,
-  0, 0, 5, 0, 19, 0, 45, 0, 16, 20,
-  23, 0, 12, 0, 0, 0, 0, 0, 0, 4,
-  0, 0, 66, 0, 50, 0, 0, 0, 0, 0,
-  0, 0, 8, 8, 0, 23, 35, 18, 0, 1,
-  2, 8, 0, 7, 6, 22, 10, 0, 3, 0,
-  0, 46, 0, 0, 38, 57, 0, 84, 0, 0,
-  66, 0, 0, 0, 0, 16, 0, 0, 0, 0,
-  1, 25, 24, 69, 0, 69, 0, 1, 25, 65,
-  56, 29, 12, 5, 16, 0, 0, 0, 0, 6,
-  0, 0, 0, 0, 12, 0, 0, 0, 0, 0,
-  13, 10, 0, 63, 0, 0, 0, 19, 57, 0,
-  0, 20, 0, 0, 0, 46, 34, 26, 87, 1,
-  0, 0, 7, 0, 9, 0, 0, 65, 36, 0,
-  32, 0, 1, 0, 50, 0, 55, 43, 17, 0,
-  0, 23, 0, 0, 119, 0, 0, 38, 90, 12,
-  104, 0, 46, 0, 0, 0, 0, 20, 0, 0,
-  0, 0, 29, 14, 2, 19, 0, 0, 0, 0,
-  38, 41, 27, 40, 14, 6, 0, 0, 0, 54,
-  43, 60, 8, 44, 0, 27, 0, 0, 65, 7,
-  13, 0, 0, 22, 3, 41, 0, 34, 37, 0,
-  17, 26, 31, 26, 0, 52, 14, 29, 52, 44,
-  0, 0, 0, 0, 0, 20, 0, 0, 0, 0,
-  0, 10, 54, 0, 11, 0, 0, 0, 18, 12,
-  28, 41, 0, 0, 0, 31, 87, 0, 6, 24,
-  0, 0, 7, 23, 21, 17, 38, 3, 0, 3,
-  0, 15, 11, 0, 0, 33, 0, 2, 25, 0,
-  0, 0, 36, 0, 28, 44, 10, 0, 0, 0,
-  0, 0, 17, 0, 0, 11, 27, 15, 97, 0,
-  59, 0, 0, 0, 0, 21, 41, 0, 0, 0,
-  50, 5, 27, 32, 0, 1, 0, 0, 18, 51,
-  26, 23, 10, 10, 0, 0, 3, 61, 32, 20,
-  24, 36, 100, 0, 0, 0, 68, 0, 15, 0,
-  0, 32, 0, 80, 0, 23, 33, 0, 0, 37,
-  49, 0, 0, 55, 6, 38, 34, 25, 3, 0,
-  7, 18, 0, 1, 6, 9, 0, 0, 0, 11,
-  56, 0, 58, 0, 18, 17, 48, 23, 33, 39,
-  0, 9, 0, 17, 86, 0, 20, 4, 0, 0,
-  14, 27, 46, 6, 34, 0, 0, 0, 0, 10,
-  3, 0, 0, 48, 0, 0, 5, 0, 21, 0,
-  43, 0, 0, 22, 7, 0, 0, 0, 0, 0,
-  0, 3, 4, 1, 0, 0, 46, 0, 47, 0,
-  0, 0, 0, 0, 0, 0, 12, 0, 0, 14,
-  34, 15, 0, 0, 26, 34, 0, 0, 0, 21,
-  29, 0, 8, 0, 0, 45, 0, 0, 48, 64,
-  6, 83, 0, 0, 55, 0, 0, 0, 0, 1,
-  0, 5, 0, 0, 0, 16, 10, 46, 0, 58,
-  0, 8, 7, 104, 37, 30, 33, 0, 15, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 6, 0,
-  0, 19, 0, 0, 21, 0, 0, 63, 0, 0,
-  0, 9, 39, 0, 0, 13, 0, 0, 0, 59,
-  43, 21, 114, 3, 0, 0, 28, 0, 36, 0,
-  0, 91, 40, 0, 32, 0, 7, 0, 28, 8,
-  75, 20, 37, 0, 0, 8, 5, 0, 131, 0,
-  0, 37, 103, 0, 101, 0, 70, 0, 0, 0,
-  0, 6, 23, 5, 0, 0, 44, 22, 34, 36,
-  0, 0, 1, 0, 0, 41, 20, 23, 3, 8,
-  0, 0, 0, 69, 18, 19, 51, 49, 164, 7,
-  0, 0, 85, 0, 15, 0, 0, 31, 6, 63,
-  0, 3, 29, 0, 23, 56, 20, 0, 0, 47,
-  0, 43, 48, 47, 7, 0, 0, 20, 0, 28,
-  0, 23, 0, 0, 0, 3, 58, 0, 2, 0,
-  18, 22, 54, 25, 23, 58, 0, 0, 0, 13,
-  76, 0, 7, 17, 0, 0, 4, 37, 62, 48,
-  83, 0, 0, 0, 8, 13, 24, 0, 0, 55,
-  0, 0, 26, 0, 38, 0, 56, 0, 44, 17,
-  29, 0, 10, 0, 0, 0, 37, 0, 0, 16,
-  21, 0, 77, 0, 71, 0, 5, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 24, 26, 15, 20, 0, 5, 0, 0,
-  4, 23, 15, 29, 19, 5, 0, 0, 0, 56,
-  21, 39, 37, 55, 0, 52, 0, 0, 82, 0,
-  11, 0, 0, 14, 0, 19, 0, 6, 0, 1,
-  10, 45, 30, 46, 0, 40, 24, 27, 55, 43,
-  0, 0, 9, 0, 0, 42, 0, 0, 0, 0,
-  0, 0, 32, 0, 0, 0, 0, 2, 11, 0,
-  20, 67, 0, 0, 0, 27, 69, 0, 0, 21,
-  0, 0, 2, 43, 16, 39, 82, 7, 0, 0,
-  15, 0, 21, 0, 0, 53, 8, 0, 42, 0,
-  0, 0, 48, 0, 67, 45, 15, 0, 2, 4,
-  0, 0, 73, 0, 0, 11, 69, 15, 131, 0,
-  65, 0, 0, 0, 0, 21, 39, 0, 0, 0,
-  39, 17, 22, 19, 5, 0, 0, 0, 20, 45,
-  30, 23, 5, 22, 0, 0, 0, 63, 27, 30,
-  38, 35, 115, 0, 0, 0, 74, 0, 11, 0,
-  0, 35, 3, 71, 0, 30, 31, 0, 4, 24,
-  50, 0, 0, 63, 18, 33, 32, 49, 0, 0,
-  0, 28, 0, 17, 6, 0, 0, 0, 0, 3,
-  73, 0, 42, 0, 0, 21, 39, 30, 32, 29,
-  0, 11, 0, 17, 87, 0, 23, 13, 0, 0,
-  7, 29, 62, 11, 41, 0, 0, 0, 0, 12,
-  26, 0, 0, 45, 0, 0, 5, 0, 19, 0,
-  45, 0, 16, 20, 23, 0, 12, 0, 0, 0,
-  0, 0, 0, 4, 0, 0, 66, 0, 50, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 20, 0, 0, 0, 0, 29, 14, 2, 19,
-  0, 0, 0, 0, 38, 41, 27, 40, 14, 6,
-  0, 0, 0, 54, 43, 60, 8, 44, 0, 27,
-  0, 0, 65, 7, 13, 0, 0, 22, 3, 41,
-  0, 34, 37, 0, 17, 26, 31, 26, 0, 52,
-  14, 29, 52, 44, 0, 0, 0, 0, 0, 20,
-  0, 0, 0, 0, 0, 10, 54, 0, 11, 0,
-  0, 0, 18, 12, 28, 41, 0, 0, 0, 31,
-  87, 0, 6, 24, 0, 0, 7, 23, 21, 17,
-  38, 3, 0, 3, 0, 15, 11, 0, 0, 33,
-  0, 2, 25, 0, 0, 0, 36, 0, 28, 44,
-  10, 0, 0, 0, 0, 0, 17, 0, 0, 11,
-  27, 15, 97, 0, 59, 0, 0, 0, 0, 21,
-  41, 0, 0, 0, 50, 5, 27, 32, 0, 1,
-  0, 0, 18, 51, 26, 23, 10, 10, 0, 0,
-  3, 61, 32, 20, 24, 36, 100, 0, 0, 0,
-  68, 0, 15, 0, 0, 32, 0, 80, 0, 23,
-  33, 0, 0, 37, 49, 0, 0, 55, 6, 38,
-  34, 25, 3, 0, 7, 18, 0, 1, 6, 9,
-  0, 0, 0, 11, 56, 0, 58, 0, 18, 17,
-  48, 23, 33, 39, 0, 9, 0, 17, 86, 0,
-  20, 4, 0, 0, 14, 27, 46, 6, 34, 0,
-  0, 0, 0, 10, 3, 0, 0, 48, 0, 0,
-  5, 0, 21, 0, 43, 0, 0, 22, 7, 0,
-  0, 0, 0, 0, 0, 3, 4, 1, 0, 0,
-  46, 0, 47, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 79, 42, 0, 0, 0, 53, 0,
-  5, 0, 0, 37, 2, 1, 18, 62, 41, 51,
-  0, 55, 86, 0, 87, 50, 0, 11, 5, 15,
-  128, 37, 1, 0, 72, 0, 36, 0, 0, 27,
-  0, 45, 39, 32, 0, 35, 80, 55, 0, 7,
-  0, 21, 12, 25, 62, 0, 16, 0, 27, 0,
-  29, 0, 13, 0, 11, 0, 0, 0, 25, 0,
-  9, 0, 3, 35, 41, 39, 37, 34, 23, 0,
-  0, 8, 79, 22, 1, 0, 0, 13, 0, 0,
-  82, 36, 0, 0, 20, 0, 0, 51, 0, 0,
-  48, 11, 5, 0, 0, 23, 29, 0, 77, 0,
-  0, 50, 18, 0, 0, 42, 0, 0, 0, 4,
-  5, 13, 24, 0, 0, 0, 28, 0, 34, 0,
-  7, 54, 57, 12, 0, 23, 17, 14, 2, 0,
-  0, 54, 68, 12, 2, 19, 58, 30, 0, 13,
-  72, 61, 94, 10, 0, 0, 0, 26, 0, 0,
-  0, 5, 68, 0, 20, 19, 0, 31, 0, 50,
-  4, 41, 0, 19, 53, 58, 0, 66, 0, 27,
-  0, 55, 24, 0, 51, 0, 26, 0, 10, 0,
-  0, 0, 0, 18, 3, 0, 0, 0, 34, 0,
-  14, 26, 9, 11, 35, 0, 48, 32, 0, 34,
-  37, 0, 35, 0, 0, 7, 0, 0, 0, 5,
-  0, 0, 0, 0, 0, 28, 25, 0, 59, 36,
-  0, 0, 14, 23, 43, 0, 49, 0, 0, 6,
-  11, 5, 0, 11, 0, 0, 8, 0, 8, 0,
-  0, 4, 5, 0, 45, 0, 20, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 59, 38, 0,
-  0, 0, 51, 10, 0, 0, 0, 39, 16, 14,
-  0, 31, 37, 50, 8, 52, 96, 0, 89, 33,
-  0, 0, 10, 17, 130, 11, 0, 0, 60, 0,
-  23, 5, 0, 27, 0, 39, 18, 30, 0, 52,
-  72, 74, 0, 1, 0, 9, 3, 38, 49, 0,
-  21, 0, 26, 0, 35, 0, 7, 0, 20, 0,
-  0, 0, 28, 0, 11, 0, 19, 32, 48, 45,
-  30, 15, 29, 8, 0, 9, 64, 8, 4, 0,
-  0, 0, 0, 0, 71, 23, 0, 0, 12, 0,
-  0, 61, 0, 0, 46, 11, 0, 0, 7, 26,
-  31, 0, 76, 0, 0, 36, 15, 0, 0, 53,
-  0, 0, 0, 21, 21, 27, 13, 0, 0, 0,
-  35, 0, 35, 0, 5, 41, 42, 14, 0, 10,
-  22, 17, 7, 0, 0, 59, 79, 18, 12, 8,
-  57, 30, 0, 8, 80, 64, 78, 4, 4, 0,
-  0, 27, 0, 0, 0, 6, 69, 0, 21, 17,
-  0, 41, 0, 56, 0, 45, 0, 25, 49, 58,
-  0, 46, 0, 36, 0, 53, 24, 7, 45, 0,
-  22, 0, 8, 0, 0, 0, 0, 27, 0, 6,
-  0, 0, 31, 0, 5, 23, 14, 9, 30, 0,
-  48, 35, 0, 35, 39, 0, 24, 0, 2, 0,
-  0, 0, 0, 6, 0, 0, 0, 3, 0, 41,
-  26, 0, 61, 31, 0, 0, 30, 12, 49, 0,
-  50, 0, 0, 4, 7, 3, 0, 14, 0, 0,
-  14, 0, 21, 1, 1, 11, 20, 0, 59, 0,
-  36, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 63, 25, 0, 12, 14, 50, 13, 5, 0,
-  0, 23, 35, 0, 0, 30, 38, 31, 5, 54,
-  55, 9, 80, 28, 0, 3, 10, 13, 116, 5,
-  0, 0, 52, 0, 36, 23, 0, 31, 3, 61,
-  0, 33, 0, 63, 55, 73, 9, 21, 0, 8,
-  0, 36, 57, 0, 2, 0, 23, 0, 17, 0,
-  5, 0, 0, 0, 6, 0, 4, 2, 29, 0,
-  67, 27, 41, 25, 49, 11, 15, 14, 0, 5,
-  68, 0, 19, 0, 11, 0, 0, 0, 45, 8,
-  0, 0, 0, 0, 0, 59, 0, 0, 45, 19,
-  0, 0, 13, 20, 31, 0, 79, 0, 0, 21,
-  1, 0, 0, 69, 0, 0, 0, 20, 30, 19,
-  9, 0, 0, 0, 44, 0, 32, 0, 1, 40,
-  20, 13, 0, 4, 30, 19, 7, 0, 0, 51,
-  83, 2, 5, 14, 52, 26, 0, 4, 59, 63,
-  73, 10, 9, 0, 0, 21, 0, 0, 0, 8,
-  79, 0, 30, 22, 0, 58, 0, 53, 0, 36,
-  0, 25, 34, 72, 4, 34, 0, 41, 0, 48,
-  26, 0, 42, 0, 22, 0, 6, 0, 0, 0,
-  0, 29, 9, 0, 0, 4, 44, 0, 36, 14,
-  25, 13, 34, 0, 45, 43, 0, 22, 40, 0,
-  24, 0, 0, 0, 0, 0, 0, 2, 0, 0,
-  0, 6, 0, 37, 22, 0, 63, 32, 0, 0,
-  27, 13, 56, 0, 49, 0, 0, 3, 0, 25,
-  0, 17, 0, 0, 5, 0, 25, 4, 6, 5,
-  11, 0, 60, 0, 35, 0, 0, 79, 42, 0,
-  0, 0, 53, 0, 5, 0, 0, 37, 2, 1,
-  18, 62, 41, 51, 0, 55, 86, 0, 87, 50,
-  0, 11, 5, 15, 128, 37, 1, 0, 72, 0,
-  36, 0, 0, 27, 0, 45, 39, 32, 0, 35,
-  80, 55, 0, 7, 0, 21, 12, 25, 62, 0,
-  16, 0, 27, 0, 29, 0, 13, 0, 11, 0,
-  0, 0, 25, 0, 9, 0, 3, 35, 41, 39,
-  37, 34, 23, 0, 0, 8, 79, 22, 1, 0,
-  0, 13, 0, 0, 82, 36, 0, 0, 20, 0,
-  0, 51, 0, 0, 48, 11, 5, 0, 0, 23,
-  29, 0, 77, 0, 0, 50, 18, 0, 0, 42,
-  0, 0, 0, 4, 5, 13, 24, 0, 0, 0,
-  28, 0, 34, 0, 7, 54, 57, 12, 0, 23,
-  17, 14, 2, 0, 0, 54, 68, 12, 2, 19,
-  58, 30, 0, 13, 72, 61, 94, 10, 0, 0,
-  0, 26, 0, 0, 0, 5, 68, 0, 20, 19,
-  0, 31, 0, 50, 4, 41, 0, 19, 53, 58,
-  0, 66, 0, 27, 0, 55, 24, 0, 51, 0,
-  26, 0, 10, 0, 0, 0, 0, 18, 3, 0,
-  0, 0, 34, 0, 14, 26, 9, 11, 35, 0,
-  48, 32, 0, 34, 37, 0, 35, 0, 0, 7,
-  0, 0, 0, 5, 0, 0, 0, 0, 0, 28,
-  25, 0, 59, 36, 0, 0, 14, 23, 43, 0,
-  49, 0, 0, 6, 11, 5, 0, 11, 0, 0,
-  8, 0, 8, 0, 0, 4, 5, 0, 45, 0,
-  20, 0, 10, 27, 29, 24, 0, 21, 22, 22,
-  24, 0, 0, 43, 79, 0, 6, 26, 56, 0,
-  0, 0, 0, 87, 1, 0, 41, 0, 0, 30,
-  0, 1, 0, 60, 72, 0, 24, 0, 0, 23,
-  0, 54, 0, 47, 13, 10, 23, 49, 26, 18,
-  0, 30, 0, 52, 4, 24, 54, 0, 32, 0,
-  10, 0, 1, 11, 0, 48, 0, 8, 0, 0,
-  39, 0, 18, 26, 11, 0, 0, 2, 47, 27,
-  0, 46, 24, 0, 46, 46, 0, 0, 13, 0,
-  0, 18, 0, 0, 0, 23, 0, 24, 55, 0,
-  15, 78, 0, 0, 25, 19, 40, 0, 26, 0,
-  5, 0, 17, 8, 0, 0, 0, 0, 7, 0,
-  0, 4, 0, 11, 36, 0, 55, 0, 17, 0,
-  0, 59, 38, 0, 0, 0, 51, 10, 0, 0,
-  0, 39, 16, 14, 0, 31, 37, 50, 8, 52,
-  96, 0, 89, 33, 0, 0, 10, 17, 130, 11,
-  0, 0, 60, 0, 23, 5, 0, 27, 0, 39,
-  18, 30, 0, 52, 72, 74, 0, 1, 0, 9,
-  3, 38, 49, 0, 21, 0, 26, 0, 35, 0,
-  7, 0, 20, 0, 0, 0, 28, 0, 11, 0,
-  19, 32, 48, 45, 30, 15, 29, 8, 0, 9,
-  64, 8, 4, 0, 0, 0, 0, 0, 71, 23,
-  0, 0, 12, 0, 0, 61, 0, 0, 46, 11,
-  0, 0, 7, 26, 31, 0, 76, 0, 0, 36,
-  15, 0, 0, 53, 0, 0, 0, 21, 21, 27,
-  13, 0, 0, 0, 35, 0, 35, 0, 5, 41,
-  42, 14, 0, 10, 22, 17, 7, 0, 0, 59,
-  79, 18, 12, 8, 57, 30, 0, 8, 80, 64,
-  78, 4, 4, 0, 0, 27, 0, 0, 0, 6,
-  69, 0, 21, 17, 0, 41, 0, 56, 0, 45,
-  0, 25, 49, 58, 0, 46, 0, 36, 0, 53,
-  24, 7, 45, 0, 22, 0, 8, 0, 0, 0,
-  0, 27, 0, 6, 0, 0, 31, 0, 5, 23,
-  14, 9, 30, 0, 48, 35, 0, 35, 39, 0,
-  24, 0, 2, 0, 0, 0, 0, 6, 0, 0,
-  0, 3, 0, 41, 26, 0, 61, 31, 0, 0,
-  30, 12, 49, 0, 50, 0, 0, 4, 7, 3,
-  0, 14, 0, 0, 14, 0, 21, 1, 1, 11,
-  20, 0, 59, 0, 36, 0, 7, 20, 30, 33,
-  0, 25, 20, 19, 31, 0, 0, 42, 85, 0,
-  9, 30, 51, 0, 0, 0, 0, 86, 1, 3,
-  48, 0, 0, 38, 0, 0, 0, 59, 74, 0,
-  25, 0, 0, 26, 0, 62, 0, 45, 16, 10,
-  25, 48, 31, 10, 0, 42, 0, 48, 3, 27,
-  52, 0, 29, 0, 9, 0, 0, 10, 0, 42,
-  0, 8, 0, 0, 37, 0, 14, 27, 13, 0,
-  0, 2, 45, 38, 0, 45, 25, 0, 49, 45,
-  0, 0, 20, 0, 0, 19, 0, 0, 0, 17,
-  0, 27, 57, 0, 16, 73, 0, 0, 26, 12,
-  40, 0, 28, 0, 0, 0, 14, 3, 0, 0,
-  0, 0, 11, 0, 0, 9, 2, 6, 37, 0,
-  65, 0, 15, 0, 0, 63, 25, 0, 12, 14,
-  50, 13, 5, 0, 0, 23, 35, 0, 0, 30,
-  38, 31, 5, 54, 55, 9, 80, 28, 0, 3,
-  10, 13, 116, 5, 0, 0, 52, 0, 36, 23,
-  0, 31, 3, 61, 0, 33, 0, 63, 55, 73,
-  9, 21, 0, 8, 0, 36, 57, 0, 2, 0,
-  23, 0, 17, 0, 5, 0, 0, 0, 6, 0,
-  4, 2, 29, 0, 67, 27, 41, 25, 49, 11,
-  15, 14, 0, 5, 68, 0, 19, 0, 11, 0,
-  0, 0, 45, 8, 0, 0, 0, 0, 0, 59,
-  0, 0, 45, 19, 0, 0, 13, 20, 31, 0,
-  79, 0, 0, 21, 1, 0, 0, 69, 0, 0,
-  0, 20, 30, 19, 9, 0, 0, 0, 44, 0,
-  32, 0, 1, 40, 20, 13, 0, 4, 30, 19,
-  7, 0, 0, 51, 83, 2, 5, 14, 52, 26,
-  0, 4, 59, 63, 73, 10, 9, 0, 0, 21,
-  0, 0, 0, 8, 79, 0, 30, 22, 0, 58,
-  0, 53, 0, 36, 0, 25, 34, 72, 4, 34,
-  0, 41, 0, 48, 26, 0, 42, 0, 22, 0,
-  6, 0, 0, 0, 0, 29, 9, 0, 0, 4,
-  44, 0, 36, 14, 25, 13, 34, 0, 45, 43,
-  0, 22, 40, 0, 24, 0, 0, 0, 0, 0,
-  0, 2, 0, 0, 0, 6, 0, 37, 22, 0,
-  63, 32, 0, 0, 27, 13, 56, 0, 49, 0,
-  0, 3, 0, 25, 0, 17, 0, 0, 5, 0,
-  25, 4, 6, 5, 11, 0, 60, 0, 35, 0,
-  2, 21, 34, 36, 0, 20, 23, 15, 27, 0,
-  0, 35, 85, 0, 12, 34, 49, 0, 0, 0,
-  0, 85, 1, 4, 48, 0, 0, 34, 0, 0,
-  0, 54, 82, 0, 29, 0, 0, 33, 0, 60,
-  0, 43, 14, 7, 23, 47, 31, 6, 0, 53,
-  0, 47, 6, 21, 54, 0, 28, 0, 6, 0,
-  3, 7, 0, 44, 0, 7, 0, 0, 39, 0,
-  13, 26, 14, 0, 0, 6, 45, 37, 0, 39,
-  28, 0, 49, 43, 0, 0, 21, 0, 0, 21,
-  1, 0, 0, 13, 0, 26, 58, 0, 13, 70,
-  1, 0, 22, 11, 31, 0, 26, 0, 0, 0,
-  14, 14, 0, 0, 0, 0, 7, 0, 0, 13,
-  6, 6, 31, 0, 67, 0, 13, 0, 7, 54,
-  57, 12, 0, 23, 17, 14, 2, 0, 0, 54,
-  68, 12, 2, 19, 58, 30, 0, 13, 72, 61,
-  94, 10, 0, 0, 0, 26, 0, 0, 0, 5,
-  68, 0, 20, 19, 0, 31, 0, 50, 4, 41,
-  0, 19, 53, 58, 0, 66, 0, 27, 0, 55,
-  24, 0, 51, 0, 26, 0, 10, 0, 0, 0,
-  0, 18, 3, 0, 0, 0, 34, 0, 14, 26,
-  9, 11, 35, 0, 48, 32, 0, 34, 37, 0,
-  35, 0, 0, 7, 0, 0, 0, 5, 0, 0,
-  0, 0, 0, 28, 25, 0, 59, 36, 0, 0,
-  14, 23, 43, 0, 49, 0, 0, 6, 11, 5,
-  0, 11, 0, 0, 8, 0, 8, 0, 0, 4,
-  5, 0, 45, 0, 20, 0, 10, 27, 29, 24,
-  0, 21, 22, 22, 24, 0, 0, 43, 79, 0,
-  6, 26, 56, 0, 0, 0, 0, 87, 1, 0,
-  41, 0, 0, 30, 0, 1, 0, 60, 72, 0,
-  24, 0, 0, 23, 0, 54, 0, 47, 13, 10,
-  23, 49, 26, 18, 0, 30, 0, 52, 4, 24,
-  54, 0, 32, 0, 10, 0, 1, 11, 0, 48,
-  0, 8, 0, 0, 39, 0, 18, 26, 11, 0,
-  0, 2, 47, 27, 0, 46, 24, 0, 46, 46,
-  0, 0, 13, 0, 0, 18, 0, 0, 0, 23,
-  0, 24, 55, 0, 15, 78, 0, 0, 25, 19,
-  40, 0, 26, 0, 5, 0, 17, 8, 0, 0,
-  0, 0, 7, 0, 0, 4, 0, 11, 36, 0,
-  55, 0, 17, 0, 0, 0, 0, 7, 0, 153,
-  0, 0, 0, 0, 0, 29, 38, 0, 0, 1,
-  3, 0, 0, 0, 24, 93, 13, 16, 0, 0,
-  0, 0, 0, 19, 0, 24, 31, 29, 0, 8,
-  0, 29, 0, 45, 0, 25, 0, 49, 3, 74,
-  23, 63, 0, 7, 0, 55, 0, 0, 19, 0,
-  43, 0, 36, 0, 0, 49, 0, 0, 76, 0,
-  0, 27, 37, 0, 74, 15, 23, 0, 0, 20,
-  11, 20, 0, 34, 35, 0, 40, 53, 0, 0,
-  16, 0, 0, 0, 0, 13, 0, 0, 26, 27,
-  0, 0, 0, 73, 26, 0, 0, 26, 12, 0,
-  22, 0, 0, 0, 6, 0, 0, 16, 0, 0,
-  114, 0, 19, 9, 0, 0, 0, 0, 29, 0,
-  0, 0, 5, 41, 42, 14, 0, 10, 22, 17,
-  7, 0, 0, 59, 79, 18, 12, 8, 57, 30,
-  0, 8, 80, 64, 78, 4, 4, 0, 0, 27,
-  0, 0, 0, 6, 69, 0, 21, 17, 0, 41,
-  0, 56, 0, 45, 0, 25, 49, 58, 0, 46,
-  0, 36, 0, 53, 24, 7, 45, 0, 22, 0,
-  8, 0, 0, 0, 0, 27, 0, 6, 0, 0,
-  31, 0, 5, 23, 14, 9, 30, 0, 48, 35,
-  0, 35, 39, 0, 24, 0, 2, 0, 0, 0,
-  0, 6, 0, 0, 0, 3, 0, 41, 26, 0,
-  61, 31, 0, 0, 30, 12, 49, 0, 50, 0,
-  0, 4, 7, 3, 0, 14, 0, 0, 14, 0,
-  21, 1, 1, 11, 20, 0, 59, 0, 36, 0,
-  7, 20, 30, 33, 0, 25, 20, 19, 31, 0,
-  0, 42, 85, 0, 9, 30, 51, 0, 0, 0,
-  0, 86, 1, 3, 48, 0, 0, 38, 0, 0,
-  0, 59, 74, 0, 25, 0, 0, 26, 0, 62,
-  0, 45, 16, 10, 25, 48, 31, 10, 0, 42,
-  0, 48, 3, 27, 52, 0, 29, 0, 9, 0,
-  0, 10, 0, 42, 0, 8, 0, 0, 37, 0,
-  14, 27, 13, 0, 0, 2, 45, 38, 0, 45,
-  25, 0, 49, 45, 0, 0, 20, 0, 0, 19,
-  0, 0, 0, 17, 0, 27, 57, 0, 16, 73,
-  0, 0, 26, 12, 40, 0, 28, 0, 0, 0,
-  14, 3, 0, 0, 0, 0, 11, 0, 0, 9,
-  2, 6, 37, 0, 65, 0, 15, 0, 0, 0,
-  0, 14, 0, 156, 0, 0, 5, 0, 0, 33,
-  46, 0, 0, 1, 2, 0, 0, 0, 35, 87,
-  15, 22, 9, 0, 0, 0, 0, 4, 0, 26,
-  27, 34, 0, 10, 0, 25, 0, 45, 0, 20,
-  0, 52, 5, 80, 36, 57, 0, 13, 0, 53,
-  0, 0, 18, 0, 38, 0, 42, 0, 0, 46,
-  0, 0, 78, 0, 0, 21, 42, 0, 77, 17,
-  26, 0, 0, 15, 17, 17, 0, 33, 33, 0,
-  40, 55, 0, 0, 30, 0, 0, 0, 0, 21,
-  0, 0, 19, 31, 0, 0, 3, 65, 28, 0,
-  0, 21, 9, 0, 22, 0, 0, 0, 0, 0,
-  0, 12, 0, 0, 106, 0, 25, 11, 0, 0,
-  0, 0, 36, 0, 0, 0, 1, 40, 20, 13,
-  0, 4, 30, 19, 7, 0, 0, 51, 83, 2,
-  5, 14, 52, 26, 0, 4, 59, 63, 73, 10,
-  9, 0, 0, 21, 0, 0, 0, 8, 79, 0,
-  30, 22, 0, 58, 0, 53, 0, 36, 0, 25,
-  34, 72, 4, 34, 0, 41, 0, 48, 26, 0,
-  42, 0, 22, 0, 6, 0, 0, 0, 0, 29,
-  9, 0, 0, 4, 44, 0, 36, 14, 25, 13,
-  34, 0, 45, 43, 0, 22, 40, 0, 24, 0,
-  0, 0, 0, 0, 0, 2, 0, 0, 0, 6,
-  0, 37, 22, 0, 63, 32, 0, 0, 27, 13,
-  56, 0, 49, 0, 0, 3, 0, 25, 0, 17,
-  0, 0, 5, 0, 25, 4, 6, 5, 11, 0,
-  60, 0, 35, 0, 2, 21, 34, 36, 0, 20,
-  23, 15, 27, 0, 0, 35, 85, 0, 12, 34,
-  49, 0, 0, 0, 0, 85, 1, 4, 48, 0,
-  0, 34, 0, 0, 0, 54, 82, 0, 29, 0,
-  0, 33, 0, 60, 0, 43, 14, 7, 23, 47,
-  31, 6, 0, 53, 0, 47, 6, 21, 54, 0,
-  28, 0, 6, 0, 3, 7, 0, 44, 0, 7,
-  0, 0, 39, 0, 13, 26, 14, 0, 0, 6,
-  45, 37, 0, 39, 28, 0, 49, 43, 0, 0,
-  21, 0, 0, 21, 1, 0, 0, 13, 0, 26,
-  58, 0, 13, 70, 1, 0, 22, 11, 31, 0,
-  26, 0, 0, 0, 14, 14, 0, 0, 0, 0,
-  7, 0, 0, 13, 6, 6, 31, 0, 67, 0,
-  13, 0, 0, 0, 0, 11, 0, 155, 2, 0,
-  5, 0, 0, 33, 42, 0, 0, 4, 0, 0,
-  0, 0, 32, 92, 22, 17, 9, 0, 0, 0,
-  0, 2, 0, 29, 24, 28, 0, 10, 0, 29,
-  0, 42, 0, 20, 0, 60, 3, 77, 36, 51,
-  0, 12, 0, 54, 0, 0, 17, 0, 44, 0,
-  43, 0, 0, 51, 0, 0, 85, 0, 0, 21,
-  43, 0, 79, 15, 29, 0, 0, 19, 21, 15,
-  0, 25, 34, 0, 39, 58, 0, 0, 33, 0,
-  0, 0, 0, 21, 2, 0, 11, 36, 0, 0,
-  0, 60, 36, 0, 0, 18, 9, 0, 23, 0,
-  0, 0, 0, 0, 0, 9, 0, 0, 107, 0,
-  27, 18, 0, 1, 0, 0, 40, 0, 0, 0,
-  10, 27, 29, 24, 0, 21, 22, 22, 24, 0,
-  0, 43, 79, 0, 6, 26, 56, 0, 0, 0,
-  0, 87, 1, 0, 41, 0, 0, 30, 0, 1,
-  0, 60, 72, 0, 24, 0, 0, 23, 0, 54,
-  0, 47, 13, 10, 23, 49, 26, 18, 0, 30,
-  0, 52, 4, 24, 54, 0, 32, 0, 10, 0,
-  1, 11, 0, 48, 0, 8, 0, 0, 39, 0,
-  18, 26, 11, 0, 0, 2, 47, 27, 0, 46,
-  24, 0, 46, 46, 0, 0, 13, 0, 0, 18,
-  0, 0, 0, 23, 0, 24, 55, 0, 15, 78,
-  0, 0, 25, 19, 40, 0, 26, 0, 5, 0,
-  17, 8, 0, 0, 0, 0, 7, 0, 0, 4,
-  0, 11, 36, 0, 55, 0, 17, 0, 0, 0,
-  0, 7, 0, 153, 0, 0, 0, 0, 0, 29,
-  38, 0, 0, 1, 3, 0, 0, 0, 24, 93,
-  13, 16, 0, 0, 0, 0, 0, 19, 0, 24,
-  31, 29, 0, 8, 0, 29, 0, 45, 0, 25,
-  0, 49, 3, 74, 23, 63, 0, 7, 0, 55,
-  0, 0, 19, 0, 43, 0, 36, 0, 0, 49,
-  0, 0, 76, 0, 0, 27, 37, 0, 74, 15,
-  23, 0, 0, 20, 11, 20, 0, 34, 35, 0,
-  40, 53, 0, 0, 16, 0, 0, 0, 0, 13,
-  0, 0, 26, 27, 0, 0, 0, 73, 26, 0,
-  0, 26, 12, 0, 22, 0, 0, 0, 6, 0,
-  0, 16, 0, 0, 114, 0, 19, 9, 0, 0,
-  0, 0, 29, 0, 0, 0, 0, 17, 0, 0,
-  0, 31, 35, 0, 13, 0, 8, 0, 56, 4,
-  16, 62, 36, 39, 10, 0, 30, 0, 0, 48,
-  4, 53, 0, 4, 0, 15, 0, 0, 72, 44,
-  0, 0, 0, 0, 0, 66, 0, 41, 0, 43,
-  20, 12, 12, 36, 0, 41, 0, 7, 95, 16,
-  0, 0, 21, 0, 0, 55, 9, 0, 0, 0,
-  0, 0, 32, 12, 11, 0, 0, 0, 0, 15,
-  10, 55, 0, 0, 0, 47, 64, 4, 32, 22,
-  15, 0, 7, 27, 13, 34, 54, 16, 0, 11,
-  39, 32, 0, 0, 0, 68, 22, 0, 0, 0,
-  0, 0, 48, 0, 0, 30, 26, 15, 0, 27,
-  0, 0, 25, 30, 24, 3, 1, 0, 121, 0,
-  65, 2, 0, 0, 7, 20, 30, 33, 0, 25,
-  20, 19, 31, 0, 0, 42, 85, 0, 9, 30,
-  51, 0, 0, 0, 0, 86, 1, 3, 48, 0,
-  0, 38, 0, 0, 0, 59, 74, 0, 25, 0,
-  0, 26, 0, 62, 0, 45, 16, 10, 25, 48,
-  31, 10, 0, 42, 0, 48, 3, 27, 52, 0,
-  29, 0, 9, 0, 0, 10, 0, 42, 0, 8,
-  0, 0, 37, 0, 14, 27, 13, 0, 0, 2,
-  45, 38, 0, 45, 25, 0, 49, 45, 0, 0,
-  20, 0, 0, 19, 0, 0, 0, 17, 0, 27,
-  57, 0, 16, 73, 0, 0, 26, 12, 40, 0,
-  28, 0, 0, 0, 14, 3, 0, 0, 0, 0,
-  11, 0, 0, 9, 2, 6, 37, 0, 65, 0,
-  15, 0, 0, 0, 0, 14, 0, 156, 0, 0,
-  5, 0, 0, 33, 46, 0, 0, 1, 2, 0,
-  0, 0, 35, 87, 15, 22, 9, 0, 0, 0,
-  0, 4, 0, 26, 27, 34, 0, 10, 0, 25,
-  0, 45, 0, 20, 0, 52, 5, 80, 36, 57,
-  0, 13, 0, 53, 0, 0, 18, 0, 38, 0,
-  42, 0, 0, 46, 0, 0, 78, 0, 0, 21,
-  42, 0, 77, 17, 26, 0, 0, 15, 17, 17,
-  0, 33, 33, 0, 40, 55, 0, 0, 30, 0,
-  0, 0, 0, 21, 0, 0, 19, 31, 0, 0,
-  3, 65, 28, 0, 0, 21, 9, 0, 22, 0,
-  0, 0, 0, 0, 0, 12, 0, 0, 106, 0,
-  25, 11, 0, 0, 0, 0, 36, 0, 0, 0,
-  0, 20, 0, 0, 0, 35, 28, 0, 25, 0,
-  6, 0, 68, 1, 9, 53, 37, 38, 8, 0,
-  43, 0, 0, 43, 7, 56, 0, 4, 0, 13,
-  10, 0, 65, 53, 0, 0, 0, 0, 0, 56,
-  0, 63, 0, 42, 23, 10, 1, 49, 0, 48,
-  0, 7, 80, 24, 0, 0, 14, 0, 0, 62,
-  18, 0, 0, 0, 0, 0, 30, 19, 15, 0,
-  0, 0, 0, 17, 1, 53, 0, 0, 0, 49,
-  63, 0, 24, 24, 20, 0, 11, 25, 0, 37,
-  36, 32, 0, 13, 32, 35, 0, 0, 0, 66,
-  17, 0, 0, 0, 0, 0, 37, 0, 0, 36,
-  37, 19, 0, 29, 0, 0, 14, 20, 42, 8,
-  3, 0, 121, 0, 63, 0, 10, 0, 2, 21,
-  34, 36, 0, 20, 23, 15, 27, 0, 0, 35,
-  85, 0, 12, 34, 49, 0, 0, 0, 0, 85,
-  1, 4, 48, 0, 0, 34, 0, 0, 0, 54,
-  82, 0, 29, 0, 0, 33, 0, 60, 0, 43,
-  14, 7, 23, 47, 31, 6, 0, 53, 0, 47,
-  6, 21, 54, 0, 28, 0, 6, 0, 3, 7,
-  0, 44, 0, 7, 0, 0, 39, 0, 13, 26,
-  14, 0, 0, 6, 45, 37, 0, 39, 28, 0,
-  49, 43, 0, 0, 21, 0, 0, 21, 1, 0,
-  0, 13, 0, 26, 58, 0, 13, 70, 1, 0,
-  22, 11, 31, 0, 26, 0, 0, 0, 14, 14,
-  0, 0, 0, 0, 7, 0, 0, 13, 6, 6,
-  31, 0, 67, 0, 13, 0, 0, 0, 0, 11,
-  0, 155, 2, 0, 5, 0, 0, 33, 42, 0,
-  0, 4, 0, 0, 0, 0, 32, 92, 22, 17,
-  9, 0, 0, 0, 0, 2, 0, 29, 24, 28,
-  0, 10, 0, 29, 0, 42, 0, 20, 0, 60,
-  3, 77, 36, 51, 0, 12, 0, 54, 0, 0,
-  17, 0, 44, 0, 43, 0, 0, 51, 0, 0,
-  85, 0, 0, 21, 43, 0, 79, 15, 29, 0,
-  0, 19, 21, 15, 0, 25, 34, 0, 39, 58,
-  0, 0, 33, 0, 0, 0, 0, 21, 2, 0,
-  11, 36, 0, 0, 0, 60, 36, 0, 0, 18,
-  9, 0, 23, 0, 0, 0, 0, 0, 0, 9,
-  0, 0, 107, 0, 27, 18, 0, 1, 0, 0,
-  40, 0, 0, 0, 0, 14, 0, 0, 0, 35,
-  30, 0, 24, 0, 0, 0, 74, 10, 3, 49,
-  34, 40, 11, 0, 46, 0, 0, 43, 6, 57,
-  0, 0, 0, 6, 17, 0, 60, 46, 0, 0,
-  0, 6, 0, 50, 0, 54, 0, 49, 22, 10,
-  0, 35, 0, 41, 0, 4, 78, 9, 0, 0,
-  19, 0, 0, 64, 27, 0, 0, 0, 0, 0,
-  28, 16, 10, 0, 0, 1, 0, 26, 0, 65,
-  0, 0, 0, 35, 53, 4, 18, 31, 20, 0,
-  14, 26, 7, 35, 30, 32, 0, 14, 17, 31,
-  0, 0, 0, 53, 24, 0, 0, 0, 0, 0,
-  40, 0, 0, 48, 34, 9, 0, 29, 0, 0,
-  32, 21, 47, 17, 0, 5, 113, 0, 63, 0,
-  10, 0,
-};
-
-unsigned char b_data[b_count] = {
-  82, 81, 82, 72, 70, 90, 88, 77, 85, 68,
-  76, 88, 77, 90, 86, 94, 88, 88, 78, 74,
-  89, 80, 75, 81, 70, 89, 81, 77, 93, 95,
-  70, 81, 109, 71, 77, 80, 80, 94, 95, 95,
-  87, 87, 77, 73, 97, 75, 91, 92, 80, 90,
-  92, 79, 162, 95, 75, 87, 99, 86, 82, 72,
-  70, 84, 85, 80, 86, 75, 79, 68, 90, 94,
-  84, 79, 81, 75, 84, 94, 91, 88, 90, 87,
-  101, 72, 84, 76, 62, 82, 80, 81, 81, 65,
-  90, 85, 83, 72, 80, 81, 85, 88, 79, 101,
-  85, 86, 81, 70, 84, 89, 79, 72, 90, 62,
-  97, 90, 70, 79, 80, 83, 78, 86, 78, 88,
-  73, 85, 71, 68, 87, 66, 65, 83, 83, 77,
-  80, 77, 68, 81, 87, 81, 88, 68, 71, 89,
-  88, 85, 88, 94, 87, 93, 75, 76, 87, 80,
-  79, 80, 73, 96, 83, 74, 87, 88, 73, 80,
-  107, 71, 80, 84, 78, 93, 93, 93, 88, 86,
-  88, 71, 96, 78, 94, 85, 78, 91, 86, 77,
-  167, 91, 77, 86, 99, 83, 85, 76, 67, 88,
-  85, 81, 83, 76, 81, 76, 89, 92, 83, 74,
-  83, 75, 86, 89, 87, 90, 92, 87, 93, 64,
-  84, 79, 66, 81, 80, 80, 82, 65, 85, 84,
-  76, 75, 81, 82, 82, 88, 83, 97, 79, 87,
-  95, 71, 90, 86, 83, 76, 89, 57, 94, 89,
-  75, 82, 84, 84, 83, 86, 85, 92, 73, 83,
-  72, 70, 89, 66, 65, 83, 83, 68, 79, 74,
-  71, 80, 90, 76, 83, 67, 75, 86, 81, 88,
-  92, 93, 86, 91, 76, 74, 81, 81, 88, 78,
-  74, 91, 82, 75, 92, 83, 74, 77, 107, 73,
-  79, 76, 76, 91, 92, 87, 88, 86, 90, 71,
-  93, 74, 86, 88, 82, 89, 90, 75, 157, 90,
-  75, 87, 94, 89, 82, 74, 70, 83, 85, 79,
-  88, 76, 79, 71, 87, 91, 87, 79, 79, 78,
-  83, 96, 90, 93, 92, 86, 101, 69, 80, 75,
-  60, 79, 83, 84, 80, 64, 85, 87, 85, 74,
-  81, 84, 84, 90, 78, 96, 86, 85, 82, 70,
-  90, 85, 80, 73, 87, 63, 90, 90, 67, 78,
-  85, 79, 87, 86, 75, 86, 72, 84, 73, 70,
-  86, 68, 67, 82, 84, 86, 80, 69, 69, 90,
-  80, 72, 88, 70, 77, 85, 82, 83, 84, 93,
-  91, 84, 77, 77, 84, 79, 78, 86, 74, 84,
-  79, 77, 86, 92, 78, 79, 105, 73, 82, 80,
-  83, 86, 91, 92, 86, 87, 80, 76, 96, 78,
-  97, 93, 78, 93, 96, 81, 169, 88, 72, 91,
-  100, 88, 79, 74, 74, 87, 81, 80, 84, 74,
-  77, 72, 83, 94, 86, 78, 84, 72, 86, 94,
-  86, 88, 82, 86, 97, 73, 82, 79, 64, 77,
-  78, 83, 79, 73, 94, 85, 82, 68, 78, 75,
-  80, 90, 85, 93, 83, 89, 94, 68, 87, 80,
-  80, 76, 93, 70, 87, 91, 75, 85, 85, 82,
-  85, 82, 84, 92, 77, 86, 70, 71, 83, 79,
-  69, 80, 83, 83, 84, 73, 64, 82, 81, 73,
-  94, 73, 75, 85, 91, 81, 88, 99, 90, 94,
-  72, 81, 88, 80, 82, 87, 77, 89, 82, 76,
-  80, 85, 82, 77, 103, 72, 82, 85, 86, 90,
-  85, 89, 90, 85, 85, 76, 94, 77, 100, 85,
-  75, 97, 92, 77, 183, 83, 76, 89, 101, 85,
-  81, 79, 70, 89, 81, 80, 79, 70, 79, 78,
-  79, 92, 83, 73, 84, 67, 86, 91, 83, 92,
-  78, 84, 90, 65, 82, 77, 68, 76, 78, 81,
-  79, 79, 95, 83, 73, 67, 81, 74, 74, 89,
-  89, 91, 74, 88, 110, 70, 90, 81, 85, 81,
-  92, 66, 82, 88, 78, 85, 88, 84, 86, 83,
-  95, 96, 77, 83, 76, 74, 86, 79, 69, 77,
-  84, 76, 85, 73, 71, 78, 84, 71, 87, 71,
-  76, 82, 81, 87, 94, 90, 89, 87, 75, 78,
-  83, 81, 89, 86, 77, 85, 83, 75, 86, 87,
-  85, 74, 102, 74, 84, 80, 82, 85, 87, 86,
-  89, 87, 81, 72, 91, 71, 92, 87, 82, 92,
-  94, 77, 162, 86, 73, 88, 93, 92, 79, 77,
-  74, 83, 81, 81, 83, 75, 83, 73, 82, 93,
-  85, 76, 81, 79, 85, 95, 88, 95, 80, 87,
-  97, 72, 79, 79, 65, 78, 85, 86, 80, 73,
-  90, 86, 84, 71, 79, 79, 80, 92, 82, 89,
-  89, 85, 93, 69, 89, 79, 83, 76, 90, 69,
-  82, 91, 72, 79, 88, 82, 87, 81, 83, 92,
-  76, 87, 73, 73, 84, 81, 72, 81, 83, 91,
-  85, 74, 76, 89, 85, 67, 84, 71, 85, 82,
-  78, 89, 91, 88, 96, 75, 81, 74, 69, 76,
-  85, 84, 74, 80, 75, 76, 91, 86, 73, 82,
-  102, 73, 81, 78, 86, 87, 92, 97, 84, 91,
-  81, 80, 96, 78, 93, 92, 81, 88, 94, 80,
-  163, 88, 68, 87, 101, 90, 76, 68, 83, 90,
-  81, 83, 83, 73, 85, 72, 81, 97, 92, 84,
-  85, 79, 84, 96, 89, 89, 84, 89, 97, 81,
-  80, 76, 63, 80, 81, 88, 81, 78, 84, 96,
-  85, 66, 75, 83, 84, 93, 84, 96, 92, 89,
-  81, 71, 82, 82, 77, 74, 91, 70, 84, 91,
-  68, 83, 81, 79, 84, 77, 74, 83, 80, 88,
-  69, 71, 82, 85, 70, 84, 85, 85, 90, 76,
-  73, 86, 81, 70, 87, 71, 84, 84, 84, 92,
-  95, 92, 98, 83, 79, 76, 78, 78, 90, 84,
-  79, 81, 80, 77, 86, 82, 76, 78, 103, 76,
-  82, 83, 92, 88, 89, 94, 84, 88, 77, 76,
-  94, 74, 95, 91, 78, 95, 93, 77, 164, 86,
-  74, 86, 101, 87, 76, 74, 83, 90, 85, 86,
-  77, 73, 89, 76, 77, 102, 83, 81, 86, 76,
-  83, 95, 88, 93, 83, 89, 90, 77, 81, 82,
-  66, 82, 80, 86, 81, 82, 87, 94, 80, 67,
-  77, 82, 77, 91, 89, 94, 92, 90, 87, 73,
-  81, 79, 78, 79, 90, 68, 81, 86, 69, 85,
-  80, 82, 85, 79, 85, 86, 79, 89, 74, 71,
-  83, 90, 72, 83, 86, 77, 91, 78, 76, 83,
-  87, 69, 83, 73, 82, 80, 78, 93, 100, 86,
-  97, 79, 77, 73, 77, 79, 89, 86, 85, 80,
-  80, 78, 89, 85, 76, 76, 103, 75, 83, 79,
-  84, 87, 90, 90, 85, 89, 71, 76, 91, 71,
-  92, 88, 83, 87, 93, 73, 159, 88, 69, 94,
-  96, 92, 73, 71, 83, 88, 81, 86, 84, 76,
-  90, 76, 80, 101, 87, 81, 80, 82, 84, 92,
-  89, 93, 84, 91, 93, 81, 76, 85, 65, 81,
-  82, 88, 83, 77, 81, 90, 85, 69, 75, 85,
-  83, 93, 83, 91, 96, 87, 83, 71, 84, 81,
-  77, 77, 91, 67, 84, 88, 68, 80, 81, 79,
-  85, 79, 76, 84, 76, 89, 72, 72, 82, 89,
-  73, 85, 78, 81, 90, 85, 58, 89, 95, 79,
-  67, 75, 82, 81, 80, 73, 85, 84, 84, 89,
-  73, 81, 73, 81, 87, 83, 81, 89, 81, 95,
-  98, 87, 108, 86, 96, 90, 82, 98, 84, 106,
-  71, 79, 99, 86, 73, 73, 80, 63, 77, 73,
-  94, 83, 73, 72, 65, 85, 73, 68, 85, 80,
-  70, 97, 100, 94, 80, 99, 79, 79, 76, 103,
-  85, 87, 92, 98, 74, 86, 89, 73, 82, 83,
-  86, 80, 69, 78, 87, 91, 81, 80, 88, 93,
-  69, 107, 81, 84, 93, 85, 71, 98, 97, 110,
-  89, 70, 78, 80, 87, 93, 89, 97, 77, 76,
-  83, 77, 83, 105, 86, 89, 94, 89, 86, 87,
-  76, 94, 87, 82, 69, 69, 73, 78, 85, 71,
-  90, 82, 77, 82, 57, 80, 92, 73, 68, 70,
-  76, 83, 83, 67, 88, 75, 86, 99, 86, 70,
-  74, 83, 88, 78, 83, 95, 81, 99, 93, 88,
-  110, 85, 92, 82, 81, 79, 79, 103, 75, 77,
-  87, 95, 78, 77, 81, 68, 74, 79, 90, 77,
-  70, 68, 68, 87, 79, 81, 82, 80, 76, 81,
-  101, 96, 73, 96, 65, 90, 77, 92, 84, 77,
-  82, 88, 77, 86, 91, 71, 76, 80, 79, 86,
-  73, 72, 84, 76, 85, 72, 88, 85, 66, 107,
-  74, 91, 98, 92, 69, 103, 100, 120, 95, 65,
-  62, 71, 85, 95, 84, 96, 76, 72, 78, 82,
-  88, 106, 82, 83, 84, 81, 76, 89, 80, 89,
-  86, 76, 71, 66, 72, 79, 93, 67, 80, 83,
-  80, 89, 65, 82, 92, 80, 70, 78, 86, 80,
-  79, 74, 85, 88, 84, 90, 75, 81, 77, 80,
-  85, 79, 86, 85, 85, 93, 92, 87, 96, 91,
-  96, 90, 89, 86, 90, 105, 76, 78, 94, 86,
-  79, 76, 85, 76, 79, 90, 96, 84, 71, 78,
-  69, 84, 77, 92, 89, 77, 77, 93, 90, 86,
-  84, 93, 92, 80, 78, 107, 85, 73, 93, 97,
-  83, 83, 90, 81, 86, 80, 76, 78, 71, 73,
-  86, 82, 86, 83, 95, 93, 73, 104, 80, 105,
-  95, 86, 93, 101, 94, 102, 87, 72, 86, 86,
-  85, 92, 88, 94, 76, 85, 85, 79, 88, 102,
-  87, 84, 76, 86, 93, 88, 81, 90, 90, 81,
-  71, 74, 72, 79, 86, 67, 79, 77, 69, 91,
-  86, 76, 86, 83, 67, 83, 89, 78, 74, 66,
-  86, 78, 63, 80, 82, 87, 88, 78, 91, 91,
-  91, 81, 93, 83, 101, 95, 90, 92, 96, 87,
-  72, 90, 103, 97, 85, 75, 104, 71, 74, 75,
-  83, 78, 81, 68, 83, 78, 68, 76, 69, 92,
-  71, 101, 89, 83, 71, 92, 78, 82, 88, 88,
-  81, 78, 82, 95, 78, 72, 114, 100, 74, 82,
-  78, 75, 93, 84, 105, 73, 78, 96, 95, 88,
-  74, 79, 92, 80, 91, 91, 72, 68, 84, 90,
-  75, 94, 87, 93, 82, 69, 82, 79, 76, 85,
-  80, 80, 86, 80, 90, 65, 71, 79, 85, 84,
-  88, 103, 83, 84, 69, 88, 90, 71, 91, 72,
-  76, 84, 82, 75, 81, 78, 71, 94, 86, 69,
-  81, 74, 69, 79, 92, 80, 70, 81, 83, 80,
-  60, 81, 86, 80, 77, 77, 82, 84, 87, 80,
-  93, 83, 97, 85, 86, 99, 95, 85, 77, 79,
-  98, 94, 71, 73, 101, 66, 83, 73, 72, 71,
-  75, 71, 79, 77, 63, 73, 72, 106, 69, 83,
-  86, 90, 63, 84, 82, 89, 87, 87, 67, 86,
-  83, 90, 84, 65, 83, 98, 80, 77, 82, 75,
-  83, 75, 94, 76, 81, 99, 88, 80, 82, 77,
-  89, 77, 78, 89, 72, 71, 79, 88, 71, 99,
-  89, 102, 79, 68, 82, 84, 75, 84, 78, 82,
-  85, 70, 88, 61, 75, 76, 79, 85, 98, 97,
-  73, 84, 72, 92, 90, 66, 102, 67, 79, 88,
-  85, 66, 78, 82, 86, 91, 87, 78, 83, 78,
-  69, 83, 90, 79, 77, 99, 86, 75, 72, 79,
-  78, 89, 73, 85, 78, 87, 85, 77, 92, 83,
-  96, 80, 89, 97, 91, 84, 87, 83, 99, 94,
-  69, 76, 99, 77, 88, 78, 85, 78, 81, 91,
-  79, 78, 67, 91, 72, 91, 72, 66, 91, 86,
-  70, 90, 75, 82, 87, 88, 87, 80, 78, 93,
-  86, 69, 71, 102, 75, 80, 83, 76, 90, 78,
-  80, 77, 77, 98, 94, 74, 87, 81, 86, 83,
-  94, 88, 73, 76, 84, 90, 74, 91, 87, 97,
-  81, 64, 82, 89, 80, 84, 79, 82, 82, 83,
-  89, 68, 80, 84, 82, 88, 93, 98, 93, 84,
-  77, 88, 89, 70, 94, 74, 77, 81, 84, 73,
-  83, 83, 85, 82, 98, 89, 75, 98, 87, 90,
-  81, 92, 89, 97, 76, 76, 75, 87, 84, 90,
-  94, 89, 94, 111, 85, 72, 100, 80, 74, 106,
-  70, 78, 95, 80, 86, 84, 94, 79, 82, 83,
-  99, 70, 76, 91, 82, 98, 94, 84, 79, 76,
-  89, 99, 84, 82, 80, 96, 106, 77, 93, 73,
-  68, 69, 79, 76, 82, 85, 88, 89, 73, 90,
-  97, 72, 97, 79, 75, 74, 89, 94, 86, 67,
-  102, 88, 102, 85, 73, 78, 85, 76, 122, 68,
-  78, 73, 80, 74, 91, 70, 66, 71, 82, 88,
-  81, 89, 83, 80, 73, 91, 91, 95, 106, 90,
-  77, 67, 93, 74, 78, 102, 101, 78, 69, 83,
-  97, 84, 89, 96, 92, 82, 73, 104, 78, 86,
-  87, 81, 95, 82, 75, 96, 86, 89, 86, 93,
-  85, 99, 75, 76, 75, 85, 81, 93, 85, 86,
-  87, 109, 86, 68, 104, 81, 67, 94, 69, 76,
-  99, 86, 98, 76, 96, 67, 82, 82, 97, 67,
-  83, 87, 75, 90, 90, 84, 81, 86, 84, 111,
-  91, 80, 75, 99, 93, 75, 89, 70, 72, 69,
-  86, 69, 84, 85, 91, 88, 71, 97, 96, 82,
-  92, 81, 74, 76, 77, 85, 94, 73, 105, 90,
-  103, 89, 73, 77, 84, 82, 127, 71, 86, 75,
-  79, 67, 86, 72, 60, 70, 75, 93, 87, 96,
-  83, 77, 71, 90, 88, 92, 106, 92, 83, 63,
-  96, 82, 85, 99, 93, 76, 63, 97, 92, 82,
-  100, 96, 94, 82, 68, 103, 79, 84, 84, 77,
-  99, 91, 76, 93, 85, 92, 81, 93, 88, 88,
-  74, 75, 79, 84, 78, 93, 74, 90, 80, 109,
-  91, 67, 101, 82, 65, 85, 71, 81, 90, 87,
-  101, 76, 93, 79, 84, 85, 96, 75, 88, 95,
-  78, 97, 91, 93, 78, 78, 86, 107, 88, 79,
-  79, 82, 96, 80, 93, 72, 67, 71, 86, 75,
-  85, 86, 83, 83, 72, 89, 85, 78, 92, 77,
-  77, 73, 84, 82, 95, 73, 100, 91, 103, 94,
-  75, 75, 77, 80, 121, 77, 74, 73, 82, 77,
-  85, 69, 69, 70, 80, 85, 84, 89, 87, 81,
-  80, 88, 88, 96, 101, 92, 85, 68, 91, 88,
-  84, 90, 96, 79, 71, 87, 82, 83, 92, 91,
-  87, 79, 77, 104, 86, 78, 84, 86, 84, 84,
-  82, 82, 93, 83, 76, 95, 99, 84, 66, 93,
-  80, 89, 84, 105, 73, 89, 74, 80, 81, 84,
-  95, 84, 95, 79, 84, 82, 83, 81, 86, 86,
-  87, 94, 115, 86, 82, 87, 91, 85, 87, 80,
-  88, 87, 75, 84, 83, 83, 83, 78, 81, 94,
-  93, 90, 86, 77, 86, 72, 87, 128, 71, 82,
-  67, 85, 77, 87, 87, 78, 88, 85, 85, 80,
-  85, 70, 75, 94, 89, 84, 86, 83, 92, 94,
-  79, 72, 86, 82, 85, 91, 82, 83, 85, 88,
-  87, 79, 87, 77, 89, 74, 89, 80, 83, 83,
-  86, 85, 83, 79, 86, 73, 90, 86, 79, 85,
-  74, 76, 85, 93, 86, 87, 83, 81, 82, 87,
-  84, 75, 84, 76, 85, 78, 86, 71, 81, 70,
-  91, 89, 85, 99, 87, 80, 68, 81, 81, 85,
-  87, 82, 79, 89, 81, 86, 80, 73, 83, 82,
-  74, 82, 75, 84, 91, 82, 80, 94, 71, 84,
-  86, 71, 70, 88, 75, 86, 79, 78, 91, 85,
-  81, 90, 88, 78, 85, 71, 80, 78, 99, 81,
-  88, 77, 83, 66, 74, 128, 71, 62, 73, 105,
-  69, 91, 89, 98, 86, 81, 84, 84, 92, 88,
-  70, 100, 89, 79, 85, 88, 85, 81, 70, 96,
-  77, 83, 79, 78, 80, 76, 86, 80, 83, 79,
-  86, 78, 91, 101, 91, 80, 70, 79, 81, 88,
-  89, 88, 90, 79, 87, 76, 82, 84, 72, 79,
-  86, 85, 75, 80, 73, 79, 100, 74, 84, 73,
-  88, 73, 91, 89, 94, 74, 80, 86, 85, 84,
-  74, 91, 78, 95, 63, 91, 80, 89, 85, 86,
-  94, 89, 88, 84, 80, 80, 92, 84, 92, 84,
-  87, 79, 88, 93, 74, 82, 77, 100, 75, 88,
-  85, 81, 75, 88, 84, 95, 88, 76, 82, 77,
-  88, 83, 86, 74, 81, 89, 90, 83, 84, 80,
-  85, 77, 86, 113, 75, 77, 68, 89, 79, 83,
-  81, 69, 85, 85, 86, 89, 82, 94, 82, 93,
-  85, 88, 86, 91, 87, 88, 98, 74, 83, 83,
-  87, 96, 87, 80, 104, 86, 85, 77, 82, 79,
-  91, 72, 86, 82, 90, 83, 91, 86, 90, 80,
-  100, 75, 92, 87, 93, 83, 81, 72, 80, 89,
-  87, 85, 86, 82, 83, 92, 85, 81, 72, 78,
-  82, 89, 74, 93, 69, 80, 88, 77, 66, 93,
-  73, 91, 65, 92, 79, 99, 79, 109, 71, 66,
-  94, 75, 72, 80, 96, 85, 103, 83, 67, 92,
-  91, 73, 86, 94, 74, 87, 75, 69, 79, 43,
-  88, 81, 77, 96, 84, 86, 73, 82, 89, 79,
-  81, 70, 78, 76, 88, 71, 85, 77, 79, 84,
-  92, 62, 79, 44, 62, 75, 87, 98, 86, 64,
-  89, 92, 87, 69, 78, 82, 81, 80, 82, 77,
-  81, 108, 68, 90, 85, 68, 81, 87, 90, 93,
-  77, 73, 95, 82, 82, 66, 74, 69, 86, 83,
-  77, 85, 86, 79, 87, 85, 69, 74, 85, 80,
-  84, 93, 71, 72, 91, 69, 60, 91, 83, 80,
-  73, 71, 72, 95, 79, 75, 98, 89, 76, 80,
-  82, 42, 93, 68, 82, 95, 99, 111, 111, 93,
-  78, 79, 87, 65, 94, 68, 69, 101, 55, 102,
-  91, 83, 71, 88, 72, 96, 107, 83, 92, 109,
-  91, 76, 87, 87, 129, 64, 92, 155, 72, 81,
-  96, 57, 96, 88, 96, 101, 81, 83, 85, 64,
-  97, 97, 103, 97, 92, 76, 96, 84, 65, 255,
-  39, 112, 73, 95, 88, 68, 73, 120, 59, 90,
-  76, 78, 102, 74, 66, 111, 96, 83, 97, 60,
-  122, 92, 30, 108, 81, 73, 82, 59, 94, 102,
-  68, 89, 84, 85, 98, 81, 70, 87, 110, 79,
-  69, 80, 79, 88, 96, 93, 106, 84, 88, 32,
-  86, 94, 60, 92, 117, 96, 55, 86, 90, 90,
-  105, 61, 93, 90, 76, 76, 92, 90, 80, 97,
-  68, 85, 82, 76, 64, 90, 66, 87, 66, 96,
-  85, 99, 81, 85, 94, 62, 94, 81, 74, 77,
-  88, 81, 104, 91, 70, 79, 93, 83, 76, 84,
-  66, 92, 71, 70, 79, 56, 79, 86, 78, 93,
-  83, 85, 80, 77, 89, 72, 82, 70, 81, 88,
-  81, 70, 84, 82, 82, 81, 90, 62, 71, 50,
-  61, 86, 91, 85, 85, 66, 87, 90, 86, 75,
-  79, 103, 83, 83, 81, 75, 76, 89, 72, 82,
-  90, 70, 74, 81, 90, 105, 82, 74, 108, 81,
-  82, 68, 78, 73, 89, 84, 80, 86, 92, 83,
-  89, 88, 77, 79, 87, 81, 91, 84, 75, 87,
-  95, 68, 67, 88, 88, 81, 82, 72, 76, 96,
-  81, 82, 84, 77, 70, 89, 97, 86, 76, 84,
-  88, 82, 73, 90, 79, 98, 69, 90, 78, 95,
-  95, 107, 75, 91, 91, 80, 83, 87, 91, 88,
-  96, 79, 86, 90, 89, 76, 72, 88, 69, 88,
-  77, 85, 83, 78, 78, 79, 82, 89, 89, 84,
-  87, 81, 88, 87, 85, 76, 86, 80, 92, 83,
-  85, 80, 77, 76, 92, 109, 91, 76, 73, 86,
-  86, 90, 82, 77, 81, 87, 91, 81, 83, 87,
-  80, 91, 84, 71, 89, 93, 83, 86, 79, 74,
-  88, 81, 88, 87, 82, 85, 91, 84, 86, 79,
-  78, 74, 78, 88, 82, 86, 94, 78, 101, 86,
-  81, 85, 90, 71, 92, 89, 84, 82, 82, 77,
-  79, 85, 86, 86, 83, 78, 80, 92, 83, 80,
-  83, 76, 86, 87, 94, 72, 78, 70, 82, 85,
-  86, 97, 89, 85, 64, 85, 76, 83, 89, 92,
-  74, 73, 81, 96, 78, 72, 87, 88, 66, 85,
-  74, 84, 88, 95, 76, 84, 83, 76, 87, 70,
-  92, 94, 74, 80, 79, 74, 91, 76, 88, 91,
-  86, 86, 83, 66, 92, 76, 93, 81, 73, 80,
-  92, 71, 80, 145, 76, 66, 72, 91, 82, 81,
-  87, 103, 69, 92, 79, 82, 92, 85, 83, 104,
-  91, 78, 90, 87, 81, 90, 62, 92, 78, 72,
-  95, 76, 89, 90, 79, 86, 82, 82, 78, 79,
-  77, 86, 87, 82, 75, 74, 90, 88, 71, 90,
-  86, 73, 84, 69, 77, 75, 79, 84, 89, 95,
-  74, 80, 74, 82, 98, 76, 81, 79, 86, 92,
-  77, 92, 95, 87, 75, 82, 86, 81, 73, 91,
-  80, 85, 68, 91, 85, 95, 92, 93, 84, 78,
-  87, 86, 81, 83, 90, 88, 92, 83, 76, 83,
-  88, 87, 71, 79, 62, 84, 96, 83, 88, 83,
-  78, 86, 82, 83, 86, 79, 87, 82, 88, 86,
-  83, 79, 88, 90, 88, 82, 82, 83, 83, 77,
-  88, 108, 82, 71, 65, 92, 87, 87, 81, 82,
-  81, 88, 88, 85, 79, 88, 85, 93, 86, 72,
-  86, 87, 89, 84, 86, 73, 83, 82, 93, 101,
-  82, 88, 94, 81, 85, 77, 92, 77, 79, 93,
-  86, 86, 98, 77, 99, 93, 84, 84, 79, 74,
-  95, 75, 75, 83, 98, 75, 84, 83, 80, 84,
-  88, 79, 82, 87, 83, 80, 101, 80, 92, 98,
-  85, 82, 69, 77, 84, 81, 77, 90, 84, 109,
-  86, 71, 97, 82, 101, 82, 89, 92, 102, 80,
-  94, 66, 97, 79, 100, 88, 89, 81, 92, 64,
-  82, 92, 79, 67, 100, 76, 88, 76, 79, 86,
-  79, 97, 83, 84, 74, 82, 102, 84, 85, 97,
-  107, 100, 92, 55, 77, 95, 78, 91, 98, 95,
-  62, 92, 72, 97, 86, 55, 98, 76, 102, 87,
-  86, 78, 96, 95, 90, 80, 91, 78, 107, 85,
-  89, 82, 99, 69, 89, 86, 49, 84, 78, 87,
-  96, 71, 90, 89, 98, 64, 66, 85, 58, 85,
-  83, 100, 95, 80, 66, 73, 85, 101, 69, 88,
-  98, 112, 89, 70, 91, 88, 96, 83, 83, 73,
-  90, 85, 112, 84, 102, 87, 79, 93, 83, 95,
-  66, 80, 80, 79, 74, 94, 81, 100, 86, 66,
-  108, 86, 113, 80, 74, 103, 77, 72, 111, 66,
-  97, 73, 110, 94, 90, 91, 99, 73, 89, 91,
-  74, 59, 107, 73, 78, 78, 93, 91, 76, 100,
-  90, 88, 72, 75, 98, 88, 85, 102, 95, 86,
-  93, 54, 80, 88, 88, 93, 99, 85, 50, 93,
-  66, 96, 90, 61, 98, 74, 98, 78, 75, 73,
-  96, 78, 82, 80, 89, 79, 123, 109, 91, 74,
-  86, 73, 82, 91, 51, 83, 82, 85, 94, 73,
-  85, 93, 77, 65, 68, 85, 54, 93, 69, 98,
-  101, 78, 70, 66, 81, 102, 73, 97, 97, 102,
-  105, 62, 88, 82, 89, 88, 78, 73, 81, 83,
-  118, 82, 71, 92, 89, 87, 73, 93, 78, 82,
-  81, 86, 73, 88, 88, 87, 92, 83, 86, 79,
-  88, 87, 80, 80, 80, 102, 91, 86, 74, 92,
-  91, 93, 83, 75, 81, 91, 81, 92, 84, 89,
-  96, 86, 83, 84, 87, 81, 84, 86, 77, 98,
-  101, 80, 88, 90, 77, 76, 86, 82, 79, 71,
-  73, 89, 84, 84, 90, 67, 67, 83, 74, 83,
-  87, 85, 95, 83, 86, 89, 90, 83, 85, 73,
-  85, 82, 82, 80, 86, 98, 84, 74, 77, 88,
-  85, 89, 82, 88, 91, 92, 81, 84, 85, 85,
-  75, 79, 91, 100, 85, 85, 107, 89, 81, 84,
-  72, 69, 92, 81, 77, 96, 98, 88, 99, 90,
-  83, 80, 81, 85, 71, 87, 94, 83, 89, 86,
-  89, 82, 71, 75, 86, 77, 67, 87, 87, 83,
-  65, 83, 73, 91, 83, 78, 85, 74, 84, 77,
-  71, 86, 77, 91, 86, 79, 92, 92, 82, 91,
-  81, 79, 88, 69, 92, 84, 89, 61, 90, 83,
-  83, 67, 76, 71, 57, 73, 82, 76, 83, 82,
-  96, 86, 91, 87, 90, 103, 86, 68, 75, 95,
-  71, 79, 100, 89, 58, 85, 72, 88, 96, 66,
-  98, 96, 95, 77, 90, 85, 86, 90, 103, 76,
-  91, 75, 100, 83, 98, 74, 93, 81, 82, 82,
-  68, 75, 78, 78, 84, 71, 82, 83, 94, 72,
-  73, 91, 74, 79, 99, 93, 79, 81, 70, 71,
-  67, 95, 82, 79, 101, 89, 79, 77, 95, 76,
-  82, 84, 73, 91, 82, 79, 94, 80, 90, 77,
-  81, 75, 82, 70, 67, 87, 80, 76, 66, 83,
-  72, 97, 86, 73, 86, 79, 79, 77, 67, 90,
-  79, 84, 99, 77, 85, 86, 94, 108, 87, 79,
-  89, 72, 90, 79, 86, 54, 91, 79, 80, 65,
-  73, 79, 52, 74, 87, 86, 84, 81, 88, 90,
-  89, 83, 79, 83, 84, 69, 83, 86, 77, 82,
-  95, 82, 50, 83, 77, 86, 94, 70, 80, 92,
-  89, 72, 86, 79, 87, 80, 92, 68, 89, 78,
-  97, 95, 101, 83, 77, 85, 82, 79, 65, 73,
-  82, 77, 74, 73, 78, 87, 77, 74, 76, 79,
-  73, 83, 92, 95, 80, 82, 69, 72, 68, 95,
-  87, 86, 109, 88, 92, 75, 91, 73, 83, 89,
-  70, 91, 79, 83, 95, 80, 72, 80, 89, 82,
-  79, 79, 84, 78, 85, 77, 72, 82, 80, 83,
-  92, 89, 77, 77, 79, 83, 86, 83, 86, 108,
-  92, 88, 75, 95, 75, 84, 82, 75, 81, 88,
-  79, 82, 85, 87, 87, 100, 80, 82, 76, 83,
-  77, 77, 79, 91, 101, 85, 84, 84, 86, 72,
-  82, 78, 78, 87, 71, 78, 84, 82, 89, 65,
-  72, 83, 91, 68, 87, 83, 77, 82, 83, 83,
-  88, 81, 85, 79, 73, 82, 89, 75, 82, 83,
-  79, 77, 68, 87, 86, 77, 90, 75, 83, 77,
-  75, 85, 81, 80, 74, 86, 82, 79, 90, 79,
-  108, 89, 70, 88, 83, 79, 87, 80, 84, 85,
-  103, 85, 89, 90, 79, 81, 82, 83, 85, 87,
-  95, 80, 82, 89, 84, 83, 76, 73, 89, 85,
-  85, 80, 89, 79, 76, 81, 84, 85, 84, 84,
-  74, 81, 83, 81, 84, 79, 85, 109, 83, 90,
-  78, 103, 88, 89, 86, 78, 80, 85, 86, 79,
-  90, 80, 87, 92, 91, 75, 82, 71, 81, 73,
-  91, 83, 93, 91, 90, 83, 79, 71, 87, 93,
-  82, 85, 70, 79, 83, 76, 93, 81, 63, 83,
-  86, 74, 87, 80, 96, 85, 91, 83, 98, 85,
-  86, 83, 84, 76, 85, 75, 81, 88, 91, 78,
-  79, 93, 78, 78, 85, 79, 77, 74, 84, 81,
-  84, 81, 90, 82, 78, 95, 90, 81, 107, 81,
-  67, 91, 87, 80, 89, 84, 87, 80, 95, 87,
-  85, 99, 88, 87, 79, 83, 78, 89, 84, 79,
-  84, 94, 84, 79, 85, 78, 85, 77, 90, 81,
-  87, 76, 78, 86, 80, 88, 92, 84, 75, 81,
-  79, 89, 84, 76, 85, 102, 89, 90, 81, 98,
-  89, 89, 87, 81, 82, 84, 86, 72, 89, 74,
-  85, 89, 87, 77, 82, 78, 78, 69, 88, 82,
-  94, 90, 88, 82, 81, 68, 84, 90, 81, 84,
-  77, 78, 83, 78, 91, 80, 69, 86, 91, 72,
-  84, 82, 75, 82, 90, 82, 100, 78, 86, 81,
-  84, 72, 88, 80, 77, 84, 91, 83, 80, 91,
-  80, 74, 81, 79, 83, 76, 77, 82, 86, 84,
-  84, 84, 81, 94, 93, 83, 111, 82, 70, 94,
-  91, 80, 93, 81, 91, 76, 95, 81, 87, 96,
-  83, 87, 84, 85, 83, 90, 83, 82, 86, 92,
-  76, 75, 85, 88, 83, 86, 91, 76, 90, 75,
-  84, 92, 87, 81, 85, 87, 76, 84, 90, 86,
-  89, 86, 85, 107, 87, 88, 79, 92, 75, 78,
-  83, 82, 84, 85, 87, 79, 83, 87, 84, 96,
-  84, 85, 90, 85, 90, 82, 82, 84, 87, 88,
-  85, 84, 77, 75, 89, 80, 83, 90, 81, 82,
-  90, 89, 86, 81, 89, 89, 87, 78, 84, 87,
-  78, 78, 95, 79, 95, 81, 83, 82, 79, 84,
-  83, 79, 83, 82, 84, 74, 80, 89, 76, 75,
-  91, 76, 89, 81, 79, 84, 85, 82, 88, 91,
-  91, 93, 84, 81, 91, 88, 78, 94, 86, 83,
-  95, 86, 84, 80, 91, 84, 88, 98, 84, 87,
-  84, 83, 81, 82, 89, 77, 77, 90, 80, 79,
-  78, 82, 112, 83, 77, 68, 81, 96, 88, 87,
-  81, 87, 83, 70, 72, 75, 67, 88, 87, 82,
-  74, 88, 94, 97, 83, 80, 86, 97, 74, 76,
-  80, 88, 71, 70, 74, 79, 86, 104, 88, 94,
-  76, 99, 79, 91, 77, 78, 64, 77, 87, 75,
-  84, 97, 86, 82, 79, 95, 69, 87, 71, 89,
-  75, 87, 100, 82, 77, 73, 84, 96, 80, 86,
-  86, 76, 70, 84, 82, 65, 76, 107, 65, 85,
-  90, 83, 95, 74, 89, 88, 90, 67, 74, 88,
-  78, 81, 79, 115, 75, 93, 89, 86, 92, 85,
-  90, 80, 85, 81, 78, 80, 94, 77, 77, 84,
-  93, 86, 97, 84, 95, 85, 78, 78, 81, 81,
-  86, 92, 84, 84, 80, 82, 77, 89, 79, 84,
-  116, 75, 88, 74, 79, 98, 82, 83, 78, 88,
-  88, 68, 72, 79, 69, 94, 77, 78, 73, 92,
-  92, 97, 87, 82, 90, 87, 78, 69, 79, 78,
-  75, 77, 82, 76, 86, 103, 88, 101, 81, 96,
-  82, 82, 76, 69, 66, 77, 93, 66, 86, 90,
-  87, 87, 83, 86, 64, 90, 71, 94, 79, 89,
-  89, 79, 70, 71, 83, 94, 81, 91, 88, 81,
-  76, 80, 79, 65, 85, 101, 65, 88, 96, 74,
-  112, 75, 82, 88, 92, 61, 79, 88, 74, 80,
-  71, 118, 71, 87, 84, 86, 88, 78, 86, 81,
-  76, 80, 78, 80, 93, 76, 90, 92, 94, 86,
-  95, 81, 73, 87, 74, 83, 75, 75, 83, 92,
-  75, 83, 79, 77, 81, 97, 84, 83, 110, 75,
-  79, 74, 83, 95, 87, 87, 79, 94, 79, 72,
-  72, 78, 72, 101, 77, 86, 87, 85, 97, 98,
-  85, 78, 85, 74, 76, 75, 80, 69, 86, 86,
-  77, 78, 94, 102, 86, 91, 85, 93, 80, 90,
-  74, 67, 65, 76, 86, 69, 82, 96, 88, 90,
-  80, 95, 72, 81, 74, 91, 76, 89, 99, 80,
-  74, 74, 89, 95, 84, 89, 92, 79, 78, 85,
-  83, 74, 79, 109, 64, 85, 90, 77, 90, 82,
-  84, 88, 85, 74, 78, 88, 82, 84, 69, 113,
-  74, 92, 88, 93, 95, 93, 85, 78, 87, 82,
-  81, 77, 91, 76, 81, 84, 91, 90, 89, 83,
-  71, 86, 77, 82, 78, 83, 80, 92, 84, 80,
-  79, 82, 79, 74, 71, 78, 101, 91, 82, 69,
-  80, 92, 94, 81, 87, 91, 92, 83, 89, 76,
-  70, 83, 85, 89, 76, 88, 102, 95, 76, 84,
-  81, 95, 75, 82, 77, 97, 73, 71, 73, 73,
-  91, 96, 87, 99, 78, 98, 83, 85, 75, 83,
-  68, 75, 94, 78, 81, 94, 84, 82, 85, 96,
-  63, 92, 75, 89, 80, 100, 95, 80, 73, 62,
-  88, 84, 78, 93, 84, 79, 68, 85, 84, 60,
-  73, 112, 68, 107, 90, 77, 105, 77, 92, 87,
-  87, 69, 71, 89, 72, 80, 85, 117, 76, 100,
-  96, 97, 80, 87, 82, 86, 75, 86, 76, 82,
-  88, 78, 80, 89, 94, 78, 84, 84, 87, 86,
-  82, 76, 78, 82, 93, 92, 82, 81, 74, 83,
-  79, 92, 74, 79, 115, 73, 90, 75, 79, 93,
-  94, 78, 88, 93, 96, 90, 88, 75, 70, 81,
-  74, 87, 71, 96, 107, 102, 76, 87, 83, 77,
-  86, 80, 75, 89, 73, 71, 72, 63, 96, 104,
-  84, 112, 79, 99, 89, 74, 76, 69, 67, 77,
-  101, 74, 83, 95, 85, 83, 85, 91, 56, 92,
-  75, 93, 81, 115, 78, 84, 74, 58, 92, 82,
-  74, 101, 81, 84, 76, 79, 81, 63, 74, 112,
-  75, 119, 102, 66, 123, 85, 74, 87, 99, 64,
-  74, 79, 67, 76, 68, 124, 73, 91, 83, 96,
-  78, 78, 77, 85, 67, 84, 73, 80, 92, 79,
-  89, 95, 95, 77, 85, 80, 66, 87, 78, 77,
-  75, 75, 99, 95, 83, 79, 70, 74, 78, 94,
-  88, 79, 97, 78, 82, 72, 80, 91, 91, 83,
-  84, 92, 87, 84, 86, 80, 75, 101, 78, 93,
-  93, 84, 108, 95, 79, 84, 80, 74, 81, 86,
-  76, 73, 90, 87, 75, 71, 99, 94, 84, 91,
-  85, 92, 83, 83, 78, 67, 66, 75, 94, 74,
-  79, 92, 84, 76, 83, 100, 66, 89, 78, 94,
-  79, 98, 93, 81, 70, 65, 90, 88, 78, 93,
-  87, 80, 82, 83, 85, 82, 76, 109, 67, 102,
-  91, 72, 102, 85, 73, 88, 82, 73, 74, 80,
-  76, 76, 71, 114, 75, 102, 82, 100, 78, 82,
-  80, 84, 74, 85, 80, 78, 85, 80, 83, 93,
-  92, 93, 81, 80, 71, 87, 82, 79, 78, 87,
-  82, 92, 86, 80, 77, 86, 77, 72, 68, 87,
-  95, 90, 74, 65, 73, 93, 90, 77, 83, 88,
-  87, 95, 90, 82, 72, 81, 82, 84, 81, 78,
-  93, 88, 84, 81, 85, 84, 78, 87, 80, 94,
-  77, 73, 74, 70, 86, 92, 85, 83, 83, 92,
-  82, 85, 80, 85, 65, 75, 92, 66, 76, 98,
-  88, 76, 87, 100, 78, 79, 86, 76, 84, 91,
-  95, 78, 77, 64, 90, 90, 78, 84, 82, 79,
-  72, 77, 88, 69, 87, 97, 70, 88, 86, 79,
-  92, 74, 97, 87, 81, 84, 73, 94, 81, 71,
-  92, 103, 79, 97, 100, 93, 87, 93, 83, 85,
-  84, 80, 82, 77, 80, 87, 82, 86, 85, 80,
-  89, 87, 83, 83, 83, 83, 79, 85, 84, 91,
-  78, 83, 83, 87, 78, 80, 75, 85, 100, 80,
-  78, 66, 70, 91, 90, 74, 84, 91, 88, 92,
-  89, 84, 67, 82, 82, 82, 84, 84, 94, 96,
-  82, 83, 87, 77, 83, 87, 75, 88, 73, 80,
-  70, 68, 88, 91, 89, 88, 80, 94, 88, 73,
-  81, 78, 65, 73, 92, 68, 74, 93, 87, 81,
-  87, 89, 74, 79, 91, 84, 85, 89, 87, 75,
-  86, 68, 89, 96, 76, 90, 79, 84, 76, 72,
-  93, 72, 84, 100, 74, 93, 88, 67, 100, 84,
-  82, 93, 85, 77, 74, 94, 78, 69, 77, 109,
-  75, 92, 86, 96, 81, 95, 79, 86, 76, 80,
-  81, 78, 82, 84, 86, 94, 87, 80, 86, 90,
-  72, 84, 82, 83, 81, 86, 82, 91, 78, 85,
-  83, 77, 74, 85, 87, 85, 97, 81, 74, 69,
-  74, 92, 88, 79, 82, 87, 85, 93, 87, 88,
-  76, 95, 85, 87, 90, 77, 97, 86, 83, 83,
-  82, 78, 82, 86, 78, 77, 80, 85, 76, 70,
-  83, 90, 89, 83, 81, 90, 86, 83, 84, 72,
-  65, 77, 90, 62, 74, 94, 85, 78, 83, 105,
-  83, 79, 87, 80, 83, 91, 87, 77, 77, 70,
-  86, 92, 74, 86, 85, 82, 84, 79, 87, 79,
-  87, 99, 70, 87, 86, 71, 89, 82, 75, 84,
-  78, 82, 74, 83, 84, 68, 75, 103, 76, 99,
-  79, 96, 86, 85, 80, 84, 84, 81, 88, 73,
-  80, 88, 83, 89, 85, 92, 86, 87, 68, 85,
-  84, 82, 88, 89, 76, 91, 80, 85, 84, 88,
-  90, 69, 70, 81, 97, 84, 64, 90, 66, 79,
-  84, 85, 67, 77, 80, 84, 77, 78, 76, 88,
-  72, 69, 74, 75, 74, 91, 88, 88, 97, 100,
-  75, 85, 70, 93, 86, 94, 93, 86, 76, 72,
-  79, 87, 72, 118, 89, 89, 72, 95, 92, 83,
-  86, 77, 88, 73, 82, 85, 71, 62, 74, 71,
-  74, 91, 80, 92, 78, 74, 82, 91, 83, 92,
-  68, 88, 96, 94, 88, 75, 93, 74, 78, 52,
-  100, 100, 89, 86, 84, 83, 77, 105, 85, 78,
-  76, 83, 77, 73, 89, 79, 92, 87, 82, 90,
-  82, 77, 98, 99, 79, 78, 101, 138, 81, 76,
-  71, 76, 75, 73, 89, 78, 81, 93, 82, 89,
-  80, 91, 78, 81, 113, 85, 76, 77, 83, 73,
-  65, 85, 102, 79, 58, 95, 69, 78, 83, 87,
-  74, 88, 85, 85, 76, 79, 73, 94, 70, 61,
-  82, 72, 68, 95, 84, 88, 92, 93, 67, 83,
-  70, 81, 95, 90, 90, 81, 76, 65, 76, 81,
-  72, 136, 83, 84, 79, 85, 80, 81, 88, 90,
-  92, 79, 76, 92, 70, 70, 89, 67, 70, 78,
-  75, 88, 86, 77, 87, 81, 79, 96, 77, 81,
-  99, 90, 95, 68, 89, 82, 78, 48, 98, 100,
-  88, 90, 68, 81, 73, 107, 95, 82, 81, 80,
-  78, 68, 87, 77, 91, 90, 80, 90, 81, 78,
-  95, 100, 80, 89, 107, 148, 85, 76, 68, 75,
-  76, 77, 74, 85, 72, 87, 80, 95, 85, 94,
-  77, 80, 117, 84, 75, 78, 91, 79, 66, 82,
-  81, 73, 67, 89, 68, 75, 83, 80, 76, 87,
-  82, 86, 80, 82, 79, 89, 77, 73, 83, 73,
-  78, 98, 89, 84, 92, 82, 79, 81, 76, 79,
-  93, 98, 91, 88, 77, 72, 79, 82, 79, 95,
-  89, 86, 74, 89, 93, 87, 85, 82, 83, 75,
-  83, 91, 75, 58, 73, 78, 79, 93, 78, 88,
-  70, 80, 85, 90, 84, 95, 75, 93, 95, 93,
-  96, 79, 97, 88, 84, 59, 84, 95, 92, 85,
-  86, 84, 72, 92, 79, 79, 77, 80, 83, 80,
-  87, 76, 89, 82, 74, 99, 80, 75, 96, 99,
-  77, 83, 96, 116, 86, 75, 69, 76, 79, 76,
-  67, 92, 81, 92, 85, 91, 86, 87, 78, 84,
-  97, 89, 82, 84, 92, 61, 65, 89, 87, 99,
-  49, 79, 86, 76, 82, 82, 73, 81, 81, 92,
-  91, 70, 82, 77, 78, 74, 76, 82, 76, 111,
-  72, 90, 96, 94, 78, 89, 68, 98, 93, 86,
-  76, 88, 68, 87, 77, 91, 81, 158, 94, 92,
-  83, 99, 70, 79, 89, 85, 94, 81, 72, 86,
-  68, 72, 85, 59, 72, 94, 74, 96, 80, 77,
-  76, 89, 80, 85, 70, 76, 83, 85, 89, 66,
-  89, 83, 65, 71, 123, 120, 84, 87, 73, 74,
-  81, 111, 94, 88, 69, 84, 81, 69, 82, 85,
-  95, 94, 83, 84, 83, 77, 92, 93, 82, 77,
-  100, 173, 62, 79, 71, 71, 76, 78, 83, 75,
-  75, 87, 89, 84, 85, 85, 65, 82, 129, 78,
-  76, 73, 82, 79, 65, 92, 94, 84, 43, 78,
-  95, 84, 79, 87, 83, 71, 93, 84, 94, 66,
-  80, 83, 74, 63, 84, 83, 76, 116, 66, 99,
-  90, 91, 81, 85, 60, 80, 92, 78, 74, 103,
-  74, 84, 81, 101, 80, 187, 95, 77, 91, 80,
-  61, 73, 93, 92, 101, 92, 71, 88, 74, 85,
-  100, 50, 59, 80, 70, 109, 73, 83, 85, 89,
-  77, 76, 64, 80, 81, 84, 96, 64, 84, 87,
-  64, 82, 129, 129, 81, 82, 65, 76, 74, 114,
-  105, 85, 70, 69, 87, 67, 71, 92, 96, 112,
-  88, 80, 74, 69, 93, 93, 89, 79, 102, 181,
-  69, 79, 80, 69, 80, 73, 84, 82, 68, 87,
-  95, 80, 81, 88, 57, 87, 150, 75, 85, 73,
-  97, 83, 76, 90, 77, 78, 57, 77, 83, 74,
-  81, 79, 73, 73, 85, 89, 86, 77, 80, 91,
-  75, 80, 97, 79, 79, 103, 81, 86, 90, 87,
-  82, 82, 72, 81, 94, 92, 78, 88, 74, 82,
-  77, 87, 83, 129, 89, 90, 86, 89, 76, 82,
-  86, 82, 87, 81, 72, 80, 73, 67, 85, 64,
-  76, 96, 69, 84, 78, 79, 78, 91, 81, 88,
-  81, 82, 90, 89, 97, 67, 98, 92, 74, 75,
-  105, 117, 85, 84, 76, 76, 79, 106, 90, 83,
-  73, 73, 84, 75, 83, 80, 94, 93, 78, 89,
-  86, 74, 88, 94, 80, 84, 97, 147, 71, 78,
-  82, 75, 80, 79, 84, 85, 89, 91, 84, 90,
-  84, 83, 69, 84, 109, 83, 77, 75, 91, 70,
-  65, 91, 94, 90, 63, 84, 79, 80, 90, 74,
-  70, 82, 77, 98, 89, 70, 84, 84, 83, 69,
-  78, 89, 83, 103, 79, 84, 94, 91, 89, 86,
-  77, 105, 90, 85, 96, 80, 74, 78, 86, 83,
-  79, 107, 87, 95, 82, 93, 88, 95, 85, 74,
-  90, 83, 78, 89, 78, 62, 86, 76, 76, 99,
-  84, 94, 79, 82, 80, 91, 74, 75, 74, 82,
-  84, 70, 84, 78, 94, 82, 77, 52, 110, 87,
-  88, 87, 82, 79, 82, 97, 79, 104, 78, 94,
-  88, 74, 91, 72, 91, 79, 89, 96, 80, 88,
-  92, 94, 85, 84, 88, 125, 70, 89, 67, 72,
-  81, 81, 79, 87, 68, 87, 91, 86, 84, 91,
-  71, 84, 98, 85, 73, 87, 92, 74, 71, 94,
-  97, 81, 60, 80, 83, 83, 86, 77, 77, 78,
-  81, 95, 90, 74, 84, 86, 74, 58, 84, 85,
-  78, 96, 79, 87, 87, 91, 90, 85, 67, 88,
-  87, 77, 90, 86, 74, 71, 92, 81, 79, 123,
-  80, 92, 90, 76, 76, 83, 87, 83, 88, 82,
-  79, 80, 77, 72, 93, 67, 71, 91, 87, 94,
-  87, 77, 88, 81, 74, 89, 64, 80, 81, 73,
-  79, 67, 89, 87, 76, 53, 113, 93, 87, 89,
-  77, 82, 79, 105, 86, 95, 74, 89, 84, 73,
-  86, 71, 92, 89, 84, 90, 79, 86, 89, 93,
-  87, 87, 85, 136, 65, 88, 75, 71, 76, 83,
-  93, 90, 74, 84, 91, 90, 86, 88, 63, 82,
-  108, 86, 77, 86, 94, 83, 86, 87, 87, 81,
-  66, 77, 80, 83, 90, 71, 71, 81, 78, 98,
-  84, 72, 84, 90, 72, 76, 91, 87, 85, 97,
-  84, 86, 86, 85, 92, 83, 78, 85, 89, 88,
-  98, 80, 78, 79, 86, 88, 82, 92, 83, 93,
-  82, 81, 89, 97, 80, 80, 80, 82, 78, 66,
-  76, 60, 84, 80, 76, 97, 81, 88, 82, 80,
-  83, 92, 83, 75, 68, 85, 86, 75, 84, 76,
-  97, 95, 74, 61, 96, 93, 89, 86, 83, 80,
-  78, 91, 82, 91, 80, 82, 89, 81, 87, 68,
-  90, 79, 80, 96, 81, 80, 89, 94, 89, 85,
-  82, 111, 69, 86, 80, 72, 79, 83, 94, 87,
-  90, 92, 89, 89, 95, 86, 72, 84, 88, 87,
-  80, 88, 86, 82, 97, 87, 81, 98, 94, 78,
-  78, 88, 81, 92, 100, 97, 87, 88, 98, 102,
-  70, 83, 88, 101, 96, 81, 86, 92, 87, 83,
-  93, 78, 78, 83, 89, 89, 68, 78, 91, 92,
-  78, 92, 83, 85, 88, 90, 80, 89, 86, 84,
-  80, 95, 56, 100, 84, 63, 83, 77, 89, 75,
-  81, 87, 97, 75, 77, 76, 90, 67, 77, 86,
-  74, 91, 84, 84, 81, 88, 79, 91, 85, 83,
-  83, 76, 87, 72, 81, 83, 92, 72, 89, 73,
-  75, 80, 78, 71, 81, 88, 76, 83, 84, 86,
-  86, 86, 64, 69, 81, 74, 81, 69, 68, 99,
-  75, 82, 74, 85, 93, 89, 92, 81, 98, 81,
-  81, 79, 80, 84, 89, 90, 83, 78, 79, 96,
-  89, 91, 85, 88, 68, 88, 92, 83, 84, 90,
-  82, 99, 117, 71, 88, 99, 103, 112, 67, 90,
-  100, 83, 79, 83, 82, 88, 100, 91, 85, 62,
-  83, 78, 82, 85, 72, 67, 90, 96, 81, 104,
-  79, 88, 93, 96, 83, 91, 85, 67, 65, 97,
-  45, 94, 97, 56, 88, 86, 90, 75, 74, 88,
-  102, 66, 75, 86, 87, 65, 82, 86, 65, 88,
-  105, 72, 80, 96, 81, 83, 78, 81, 89, 74,
-  84, 67, 85, 77, 95, 67, 85, 68, 77, 84,
-  88, 70, 70, 86, 73, 89, 85, 83, 84, 84,
-  61, 72, 86, 71, 84, 68, 72, 102, 69, 83,
-  80, 90, 104, 87, 84, 77, 94, 76, 78, 87,
-  83, 80, 87, 99, 78, 77, 90, 95, 84, 83,
-  82, 80, 79, 96, 92, 82, 74, 83, 85, 85,
-  94, 70, 92, 89, 96, 91, 75, 93, 85, 102,
-  90, 81, 82, 93, 83, 85, 86, 68, 77, 89,
-  92, 86, 84, 89, 99, 88, 82, 92, 82, 86,
-  83, 84, 81, 85, 86, 77, 84, 99, 66, 85,
-  81, 69, 81, 80, 86, 80, 84, 89, 96, 75,
-  81, 71, 88, 71, 77, 86, 77, 79, 108, 90,
-  89, 86, 80, 91, 87, 87, 85, 83, 91, 82,
-  83, 81, 85, 65, 90, 79, 81, 79, 77, 84,
-  82, 81, 81, 85, 90, 87, 84, 89, 70, 85,
-  81, 75, 78, 66, 69, 87, 74, 82, 77, 84,
-  84, 91, 77, 82, 89, 81, 83, 74, 78, 86,
-  90, 82, 91, 77, 78, 95, 88, 94, 71, 89,
-  86, 93, 81, 72, 81, 87, 91, 92, 88, 77,
-  80, 94, 115, 90, 82, 78, 94, 91, 83, 88,
-  63, 83, 75, 81, 84, 66, 99, 76, 84, 90,
-  80, 82, 91, 91, 99, 79, 72, 81, 89, 80,
-  65, 80, 71, 91, 74, 84, 91, 81, 96, 70,
-  81, 94, 79, 86, 88, 91, 83, 72, 62, 74,
-  67, 80, 81, 92, 81, 62, 91, 78, 89, 91,
-  72, 87, 89, 104, 77, 82, 86, 76, 79, 78,
-  88, 81, 93, 82, 80, 77, 91, 75, 74, 82,
-  92, 73, 84, 76, 93, 88, 56, 75, 86, 79,
-  83, 96, 86, 86, 68, 77, 77, 82, 83, 81,
-  81, 93, 85, 83, 78, 91, 86, 78, 96, 88,
-  76, 77, 87, 88, 79, 90, 87, 95, 75, 81,
-  69, 74, 96, 86, 93, 104, 110, 75, 77, 99,
-  131, 97, 83, 81, 97, 71, 74, 89, 67, 70,
-  83, 86, 76, 67, 115, 79, 75, 87, 68, 73,
-  94, 94, 82, 79, 65, 82, 98, 85, 59, 79,
-  62, 76, 57, 77, 95, 78, 109, 68, 75, 79,
-  85, 75, 73, 93, 87, 64, 53, 81, 58, 77,
-  81, 101, 72, 63, 77, 59, 98, 96, 64, 80,
-  90, 93, 76, 78, 83, 75, 83, 86, 86, 82,
-  84, 79, 74, 77, 95, 73, 60, 74, 95, 70,
-  91, 72, 76, 88, 57, 71, 90, 82, 72, 112,
-  94, 95, 70, 74, 85, 79, 91, 81, 91, 88,
-  83, 79, 69, 87, 89, 78, 86, 96, 67, 76,
-  95, 84, 81, 78, 102, 84, 92, 97, 83, 73,
-  78, 84, 90, 80, 82, 98, 84, 95, 104, 81,
-  81, 79, 84, 97, 90, 89, 87, 84, 71, 81,
-  81, 86, 99, 87, 87, 93, 78, 98, 104, 89,
-  83, 77, 79, 83, 93, 81, 72, 85, 86, 102,
-  85, 85, 88, 84, 91, 74, 81, 64, 81, 84,
-  86, 83, 82, 74, 67, 73, 69, 83, 84, 84,
-  85, 65, 85, 83, 93, 86, 71, 81, 86, 87,
-  78, 86, 90, 86, 78, 91, 85, 82, 79, 90,
-  82, 75, 84, 71, 83, 77, 81, 77, 89, 74,
-  71, 91, 65, 80, 84, 81, 81, 92, 78, 82,
-  67, 75, 88, 84, 75, 89, 91, 89, 90, 82,
-  84, 90, 83, 80, 100, 81, 85, 74, 82, 86,
-  81, 88, 79, 86, 89, 78, 69, 80, 73, 74,
-  84, 77, 74, 96, 69, 89, 106, 59, 73, 72,
-  83, 86, 74, 82, 63, 76, 75, 79, 95, 68,
-  96, 91, 80, 86, 108, 92, 100, 96, 112, 77,
-  89, 61, 86, 64, 74, 77, 88, 77, 99, 76,
-  113, 78, 84, 84, 75, 81, 66, 100, 86, 89,
-  81, 93, 93, 80, 62, 85, 82, 88, 103, 85,
-  94, 91, 89, 79, 68, 81, 96, 92, 95, 95,
-  81, 93, 73, 89, 72, 97, 92, 87, 82, 77,
-  88, 101, 85, 79, 91, 86, 91, 83, 83, 99,
-  77, 97, 78, 87, 91, 94, 87, 53, 71, 73,
-  87, 80, 75, 78, 88, 104, 66, 85, 100, 91,
-  76, 89, 78, 79, 84, 95, 82, 76, 68, 77,
-  90, 79, 86, 74, 63, 73, 67, 71, 90, 81,
-  83, 123, 74, 68, 109, 56, 66, 68, 81, 84,
-  85, 77, 72, 72, 70, 77, 104, 94, 102, 81,
-  79, 87, 91, 83, 105, 89, 107, 74, 101, 61,
-  80, 68, 77, 67, 88, 74, 96, 75, 128, 86,
-  83, 85, 69, 101, 61, 93, 92, 94, 77, 91,
-  93, 85, 56, 102, 86, 105, 105, 90, 83, 91,
-  79, 74, 71, 80, 97, 85, 98, 102, 79, 99,
-  61, 83, 73, 102, 84, 90, 78, 69, 74, 90,
-  86, 73, 89, 94, 87, 83, 85, 108, 79, 95,
-  74, 91, 92, 114, 98, 60, 71, 67, 91, 74,
-  72, 78, 97, 115, 77, 90, 103, 91, 82, 84,
-  70, 78, 83, 91, 76, 77, 78, 68, 93, 85,
-  95, 78, 70, 77, 72, 80, 81, 67, 74, 111,
-  74, 87, 99, 65, 75, 72, 86, 78, 98, 82,
-  77, 79, 79, 80, 90, 108, 91, 87, 79, 85,
-  79, 95, 98, 97, 94, 74, 89, 71, 84, 72,
-  82, 77, 90, 93, 108, 77, 105, 69, 85, 82,
-  78, 87, 73, 89, 82, 81, 80, 89, 94, 82,
-  66, 84, 89, 81, 93, 80, 80, 90, 89, 85,
-  74, 80, 91, 87, 84, 92, 84, 88, 69, 87,
-  74, 103, 79, 89, 78, 75, 85, 78, 90, 79,
-  88, 86, 93, 86, 77, 89, 78, 86, 79, 85,
-  92, 91, 79, 63, 73, 77, 87, 84, 76, 89,
-  77, 89, 99, 83, 103, 89, 93, 83, 81, 77,
-  85, 90, 85, 75, 81, 70, 93, 72, 90, 79,
-  87, 82, 84, 82, 80, 72, 83, 94, 75, 91,
-  78, 69, 63, 76, 78, 106, 97, 102, 78, 76,
-  71, 81, 96, 86, 84, 88, 92, 69, 83, 95,
-  87, 85, 96, 90, 79, 104, 81, 71, 78, 91,
-  97, 88, 84, 88, 80, 83, 82, 80, 79, 86,
-  97, 71, 89, 81, 72, 153, 81, 115, 46, 98,
-  72, 74, 102, 79, 108, 87, 80, 74, 74, 83,
-  96, 81, 87, 99, 83, 76, 93, 71, 83, 70,
-  73, 74, 88, 81, 80, 77, 93, 79, 75, 91,
-  70, 71, 86, 106, 73, 79, 82, 84, 78, 74,
-  72, 71, 70, 82, 84, 70, 73, 73, 88, 87,
-  74, 91, 90, 90, 85, 75, 80, 78, 78, 98,
-  71, 91, 86, 69, 80, 93, 88, 66, 82, 83,
-  75, 80, 85, 81, 90, 106, 76, 86, 83, 83,
-  80, 72, 116, 109, 89, 92, 80, 92, 72, 84,
-  93, 76, 88, 85, 91, 91, 84, 73, 73, 94,
-  69, 85, 82, 92, 75, 87, 79, 89, 81, 82,
-  80, 87, 73, 100, 83, 83, 79, 73, 80, 70,
-  87, 93, 72, 97, 90, 87, 74, 79, 78, 83,
-  91, 89, 64, 85, 73, 81, 83, 68, 83, 88,
-  80, 80, 87, 83, 83, 78, 87, 74, 84, 79,
-  73, 89, 77, 75, 87, 85, 69, 89, 87, 71,
-  88, 74, 80, 69, 84, 83, 92, 71, 91, 98,
-  86, 83, 94, 82, 88, 85, 92, 92, 101, 86,
-  84, 93, 84, 81, 92, 82, 77, 93, 83, 80,
-  80, 78, 76, 104, 91, 81, 92, 88, 80, 89,
-  94, 92, 90, 76, 90, 85, 92, 101, 98, 98,
-  82, 74, 77, 80, 95, 99, 87, 95, 90, 79,
-  83, 89, 97, 88, 89, 74, 86, 95, 82, 75,
-  75, 61, 100, 107, 82, 89, 79, 71, 71, 78,
-  89, 89, 79, 90, 83, 85, 72, 90, 74, 93,
-  73, 67, 93, 73, 103, 71, 77, 94, 72, 97,
-  87, 70, 81, 92, 87, 72, 68, 88, 93, 74,
-  101, 92, 76, 76, 88, 84, 88, 82, 85, 93,
-  68, 86, 72, 80, 80, 95, 91, 88, 73, 66,
-  101, 93, 87, 82, 105, 75, 108, 101, 95, 97,
-  87, 83, 109, 96, 86, 82, 87, 84, 74, 94,
-  84, 90, 87, 91, 86, 96, 95, 84, 85, 80,
-  86, 70, 80, 88, 84, 84, 80, 82, 87, 70,
-  71, 89, 75, 72, 70, 65, 67, 79, 79, 109,
-  98, 94, 81, 86, 67, 80, 90, 73, 82, 87,
-  83, 70, 66, 96, 105, 85, 103, 75, 81, 104,
-  94, 72, 89, 76, 74, 100, 87, 85, 81, 86,
-  82, 82, 87, 97, 98, 75, 95, 82, 82, 133,
-  95, 115, 47, 103, 71, 72, 89, 81, 92, 91,
-  87, 86, 72, 87, 92, 76, 73, 99, 82, 66,
-  88, 78, 85, 81, 68, 82, 83, 75, 79, 76,
-  92, 76, 68, 92, 77, 71, 72, 111, 78, 93,
-  93, 83, 71, 81, 80, 71, 73, 77, 82, 63,
-  71, 66, 78, 81, 82, 84, 93, 97, 75, 72,
-  78, 79, 81, 79, 72, 93, 85, 64, 61, 91,
-  86, 74, 85, 80, 88, 80, 83, 77, 80, 70,
-  79, 89, 80, 75, 78, 73, 104, 90, 74, 91,
-  80, 91, 71, 79, 93, 71, 77, 88, 92, 89,
-  89, 77, 84, 88, 94, 84, 79, 82, 66, 81,
-  83, 92, 78, 85, 79, 86, 79, 73, 90, 83,
-  82, 110, 81, 78, 91, 87, 75, 101, 88, 89,
-  67, 89, 73, 81, 100, 77, 100, 86, 70, 72,
-  80, 79, 91, 92, 75, 83, 80, 81, 87, 73,
-  85, 77, 79, 79, 73, 89, 79, 86, 87, 83,
-  68, 87, 81, 74, 101, 84, 79, 78, 78, 83,
-  81, 81, 89, 90, 82, 85, 79, 78, 76, 82,
-  74, 90, 77, 84, 85, 77, 83, 78, 90, 79,
-  82, 79, 80, 81, 73, 78, 100, 107, 93, 73,
-  90, 75, 79, 93, 87, 90, 84, 86, 91, 96,
-  92, 96, 94, 94, 73, 77, 79, 86, 86, 98,
-  81, 91, 82, 91, 89, 88, 96, 87, 85, 67,
-  92, 101, 70, 81, 82, 67, 81, 95, 75, 86,
-  83, 75, 71, 81, 79, 81, 86, 91, 83, 90,
-  69, 97, 83, 87, 70, 75, 81, 80, 94, 83,
-  81, 88, 81, 97, 67, 73, 68, 74, 86, 73,
-  75, 78, 88, 76, 96, 92, 80, 81, 85, 85,
-  84, 79, 86, 95, 72, 83, 74, 83, 73, 83,
-  84, 87, 84, 62, 93, 76, 78, 82, 103, 86,
-  100, 97, 91, 99, 85, 79, 98, 93, 90, 88,
-  80, 84, 81, 76, 84, 87, 87, 87, 88, 90,
-  95, 86, 89, 95, 97, 95, 84, 87, 86, 101,
-  75, 87, 80, 72, 79, 87, 82, 82, 85, 90,
-  86, 97, 84, 98, 97, 89, 97, 108, 81, 91,
-  77, 76, 93, 79, 84, 83, 77, 82, 90, 97,
-  88, 75, 79, 92, 90, 86, 87, 61, 86, 97,
-  83, 82, 91, 86, 81, 93, 84, 71, 82, 88,
-  79, 103, 88, 75, 86, 92, 66, 72, 79, 80,
-  90, 92, 68, 83, 85, 95, 84, 82, 83, 81,
-  74, 83, 87, 85, 74, 90, 90, 87, 85, 88,
-  87, 78, 78, 88, 88, 86, 81, 80, 81, 76,
-  70, 69, 89, 82, 90, 82, 93, 72, 97, 83,
-  90, 98, 80, 80, 88, 72, 76, 79, 91, 81,
-  98, 82, 82, 94, 105, 89, 91, 82, 86, 91,
-  89, 73, 68, 84, 81, 87, 86, 85, 79, 87,
-  82, 75, 82, 73, 83, 74, 76, 74, 80, 85,
-  75, 93, 80, 92, 90, 93, 83, 84, 81, 69,
-  82, 95, 82, 78, 85, 87, 88, 83, 98, 87,
-  79, 99, 98, 78, 88, 76, 76, 86, 89, 81,
-  88, 79, 87, 82, 81, 85, 87, 81, 87, 84,
-  85, 100, 90, 96, 68, 86, 77, 76, 90, 84,
-  111, 95, 82, 84, 74, 88, 90, 86, 78, 90,
-  78, 86, 82, 79, 88, 80, 79, 86, 86, 83,
-  82, 89, 101, 76, 73, 88, 79, 80, 72, 86,
-  81, 106, 88, 85, 81, 78, 86, 80, 82, 91,
-  75, 77, 77, 72, 74, 91, 74, 88, 93, 88,
-  81, 79, 88, 78, 85, 78, 82, 89, 84, 64,
-  78, 88, 86, 81, 86, 71, 73, 93, 87, 82,
-  86, 86, 86, 83, 79, 79, 83, 86, 80, 85,
-  85, 99, 82, 84, 85, 88, 74, 79, 90, 90,
-  85, 80, 83, 74, 80, 84, 79, 87, 79, 89,
-  83, 82, 80, 80, 76, 75, 92, 82, 78, 83,
-  90, 72, 85, 93, 86, 88, 92, 83, 79, 92,
-  90, 87, 84, 84, 86, 84, 90, 94, 82, 95,
-  82, 76, 78, 85, 90, 85, 90, 87, 81, 94,
-  85, 79, 83, 79, 81, 84, 90, 88, 79, 87,
-  95, 74, 73, 94, 76, 82, 91, 73, 83, 84,
-  82, 84, 90, 81, 86, 81, 76, 96, 76, 74,
-  84, 81, 83, 108, 86, 90, 85, 92, 84, 79,
-  79, 79, 84, 86, 85, 93, 87, 88, 78, 86,
-  73, 90, 76, 65, 69, 73, 79, 74, 87, 78,
-  75, 92, 75, 96, 88, 87, 103, 85, 75, 77,
-  70, 89, 61, 105, 98, 78, 90, 74, 73, 74,
-  66, 71, 81, 88, 90, 76, 59, 55, 89, 88,
-  117, 73, 82, 102, 86, 95, 80, 75, 91, 83,
-  87, 76, 73, 77, 83, 82, 95, 70, 75, 81,
-  80, 82, 76, 86, 67, 92, 72, 72, 101, 95,
-  91, 84, 71, 83, 89, 71, 81, 82, 93, 89,
-  89, 95, 88, 103, 91, 104, 100, 78, 63, 73,
-  80, 102, 78, 97, 66, 85, 92, 74, 79, 76,
-  87, 94, 79, 93, 74, 84, 113, 96, 90, 76,
-  73, 77, 89, 92, 80, 119, 100, 86, 87, 72,
-  93, 85, 86, 89, 85, 91, 68, 87, 75, 86,
-  76, 69, 70, 73, 76, 77, 86, 83, 75, 87,
-  70, 93, 83, 86, 90, 85, 80, 77, 73, 89,
-  55, 105, 100, 72, 91, 68, 73, 72, 71, 78,
-  85, 86, 85, 75, 62, 67, 94, 86, 120, 71,
-  85, 98, 85, 99, 83, 73, 90, 84, 89, 76,
-  71, 75, 94, 82, 100, 74, 79, 84, 69, 88,
-  74, 85, 72, 85, 74, 75, 97, 85, 92, 77,
-  73, 85, 82, 69, 82, 84, 94, 80, 86, 93,
-  85, 97, 89, 98, 92, 78, 75, 75, 79, 103,
-  80, 97, 70, 81, 88, 77, 77, 77, 87, 95,
-  71, 91, 69, 90, 109, 99, 92, 79, 72, 82,
-  75, 93, 88, 112, 97, 87, 72, 76, 89, 86,
-  85, 92, 85, 91, 71, 82, 69, 83, 75, 79,
-  73, 75, 77, 73, 80, 88, 77, 96, 79, 90,
-  82, 93, 79, 78, 85, 76, 75, 94, 68, 99,
-  89, 68, 87, 72, 73, 70, 78, 86, 86, 85,
-  75, 74, 66, 61, 105, 86, 110, 75, 86, 88,
-  88, 91, 88, 76, 86, 80, 83, 82, 71, 88,
-  80, 84, 97, 73, 79, 76, 85, 85, 82, 83,
-  75, 80, 85, 72, 100, 90, 91, 85, 77, 83,
-  90, 75, 81, 84, 93, 86, 86, 90, 81, 92,
-  91, 100, 96, 85, 64, 77, 86, 97, 77, 104,
-  71, 93, 97, 83, 76, 76, 90, 91, 73, 92,
-  71, 86, 104, 92, 85, 84, 76, 79, 81, 89,
-  86, 114, 94, 87, 78, 73, 89, 89, 83, 88,
-  85, 82, 75, 89, 86, 84, 81, 71, 77, 74,
-  88, 79, 90, 77, 89, 101, 77, 93, 76, 83,
-  116, 82, 75, 79, 78, 77, 56, 102, 96, 81,
-  93, 70, 81, 79, 71, 75, 71, 90, 96, 70,
-  62, 69, 118, 93, 109, 84, 72, 105, 76, 88,
-  91, 72, 87, 86, 80, 86, 66, 82, 83, 86,
-  94, 66, 72, 75, 77, 76, 83, 81, 63, 68,
-  86, 71, 91, 113, 97, 73, 74, 88, 81, 70,
-  89, 84, 93, 83, 84, 93, 89, 95, 84, 98,
-  89, 63, 72, 80, 73, 94, 91, 90, 69, 75,
-  80, 83, 77, 72, 93, 84, 78, 86, 55, 84,
-  93, 89, 89, 82, 73, 78, 75, 90, 82, 101,
-  90, 82, 74, 77, 87, 93, 89, 85, 82, 94,
-  72, 91, 91, 83, 82, 72, 78, 76, 84, 79,
-  92, 88, 85, 105, 68, 88, 71, 86, 115, 81,
-  74, 78, 75, 75, 54, 102, 93, 77, 96, 70,
-  80, 78, 74, 80, 71, 81, 88, 65, 67, 76,
-  126, 91, 112, 83, 73, 95, 73, 89, 92, 70,
-  82, 86, 77, 77, 63, 76, 87, 84, 103, 72,
-  77, 76, 68, 77, 74, 77, 68, 65, 74, 64,
-  88, 104, 99, 60, 75, 91, 80, 67, 91, 85,
-  96, 82, 81, 92, 89, 87, 80, 99, 87, 62,
-  73, 78, 73, 95, 87, 90, 74, 65, 79, 77,
-  77, 73, 102, 78, 70, 85, 58, 90, 97, 93,
-  86, 83, 74, 79, 74, 86, 86, 98, 88, 87,
-  55, 79, 80, 93, 89, 87, 85, 96, 76, 83,
-  81, 89, 78, 78, 74, 76, 85, 80, 82, 96,
-  87, 99, 81, 87, 77, 87, 92, 82, 80, 80,
-  78, 78, 66, 96, 89, 75, 89, 72, 77, 75,
-  83, 86, 72, 88, 79, 72, 70, 72, 111, 90,
-  103, 79, 76, 86, 80, 88, 91, 82, 83, 85,
-  84, 76, 71, 90, 80, 84, 95, 73, 78, 70,
-  80, 80, 85, 80, 72, 75, 77, 74, 87, 95,
-  94, 82, 79, 89, 82, 72, 88, 81, 92, 88,
-  85, 86, 90, 92, 82, 92, 88, 70, 72, 80,
-  83, 92, 90, 94, 73, 85, 82, 87, 78, 73,
-  92, 88, 71, 84, 61, 82, 97, 90, 84, 86,
-  85, 85, 91, 87, 87, 100, 82, 84, 70, 78,
-  86, 90, 89, 87, 80, 76, 84, 85, 78, 83,
-  78, 78, 80, 73, 90, 94, 92, 88, 95, 96,
-  81, 86, 81, 85, 120, 84, 75, 81, 83, 74,
-  79, 88, 88, 74, 93, 73, 76, 83, 75, 86,
-  82, 78, 92, 76, 68, 73, 121, 94, 109, 92,
-  77, 101, 72, 85, 92, 71, 90, 88, 87, 100,
-  78, 77, 83, 89, 94, 71, 71, 79, 84, 73,
-  86, 83, 67, 79, 93, 86, 92, 121, 90, 78,
-  81, 89, 82, 77, 88, 87, 101, 80, 81, 91,
-  92, 92, 85, 97, 79, 72, 70, 76, 78, 104,
-  93, 86, 79, 86, 74, 96, 78, 75, 90, 102,
-  80, 80, 52, 83, 98, 85, 88, 89, 85, 81,
-  75, 91, 89, 98, 94, 82, 74, 80, 83, 87,
-  86, 76, 78, 84, 78, 87, 79, 81, 81, 76,
-  80, 77, 91, 86, 95, 95, 98, 96, 77, 82,
-  81, 83, 120, 86, 73, 84, 84, 73, 80, 91,
-  80, 75, 96, 76, 72, 83, 74, 84, 81, 71,
-  90, 75, 64, 77, 126, 90, 107, 99, 78, 98,
-  69, 84, 94, 72, 83, 84, 80, 90, 74, 76,
-  85, 89, 103, 71, 75, 81, 77, 72, 85, 83,
-  67, 78, 83, 81, 90, 120, 94, 69, 82, 89,
-  81, 79, 88, 86, 100, 87, 80, 92, 90, 85,
-  83, 94, 83, 69, 69, 75, 73, 96, 85, 88,
-  88, 77, 73, 87, 81, 77, 101, 98, 70, 81,
-  50, 86, 99, 88, 81, 84, 88, 85, 84, 88,
-  96, 96, 91, 82, 59, 82, 80, 84, 86, 83,
-  77, 90, 79, 83, 76, 86, 74, 80, 82, 78,
-  87, 93, 87, 92, 90, 96, 88, 83, 83, 80,
-  101, 79, 81, 83, 85, 77, 83, 82, 80, 82,
-  86, 78, 79, 83, 81, 85, 81, 81, 83, 77,
-  65, 72, 108, 91, 103, 87, 79, 87, 75, 89,
-  90, 79, 87, 85, 88, 86, 80, 87, 80, 87,
-  97, 74, 82, 73, 80, 75, 89, 83, 72, 90,
-  77, 84, 88, 107, 90, 85, 83, 90, 79, 77,
-  90, 83, 94, 93, 80, 85, 94, 93, 85, 96,
-  80, 72, 72, 81, 84, 99, 89, 87, 83, 89,
-  78, 85, 76, 75, 89, 96, 78, 81, 58, 84,
-  98, 84, 84, 88, 96, 87, 98, 92, 94, 95,
-  80, 83, 74, 83, 83, 81, 86, 79, 87, 89,
-  66, 77, 75, 94, 93, 76, 85, 90, 75, 78,
-  87, 86, 86, 87, 80, 86, 65, 80, 104, 78,
-  95, 107, 69, 94, 80, 85, 89, 81, 89, 77,
-  84, 82, 80, 83, 83, 92, 97, 84, 93, 103,
-  71, 87, 116, 84, 61, 88, 82, 92, 79, 76,
-  86, 75, 78, 79, 99, 91, 86, 76, 83, 85,
-  97, 89, 89, 96, 77, 84, 72, 87, 85, 83,
-  101, 94, 82, 89, 87, 92, 79, 82, 94, 83,
-  81, 94, 79, 80, 77, 79, 93, 83, 76, 88,
-  99, 76, 82, 93, 62, 80, 84, 91, 90, 85,
-  74, 82, 87, 90, 89, 87, 69, 94, 93, 91,
-  87, 73, 80, 92, 70, 94, 89, 96, 90, 88,
-  73, 84, 85, 84, 91, 90, 86, 90, 67, 77,
-  83, 63, 83, 91, 85, 87, 87, 78, 77, 85,
-  90, 80, 86, 83, 84, 81, 103, 78, 94, 99,
-  76, 92, 83, 85, 74, 89, 91, 73, 73, 83,
-  80, 78, 86, 83, 97, 84, 82, 82, 38, 79,
-  89, 78, 72, 88, 92, 90, 79, 82, 82, 86,
-  77, 76, 81, 92, 66, 88, 92, 87, 85, 104,
-  74, 96, 81, 82, 93, 69, 68, 81, 85, 80,
-  84, 75, 90, 87, 82, 86, 88, 90, 81, 92,
-  83, 92, 76, 82, 88, 84, 80, 74, 77, 80,
-  84, 73, 81, 88, 85, 88, 79, 79, 83, 85,
-  86, 88, 82, 84, 80, 90, 91, 84, 86, 71,
-  83, 78, 79, 88, 84, 82, 87, 88, 70, 84,
-  78, 90, 92, 89, 84, 93, 83, 81, 91, 70,
-  72, 106, 81, 84, 94, 85, 72, 93, 79, 76,
-  86, 92, 100, 89, 77, 68, 89, 91, 86, 78,
-  91, 87, 81, 80, 92, 83, 64, 79, 99, 100,
-  86, 72, 95, 73, 78, 64, 40, 76, 59, 77,
-  107, 83, 88, 91, 75, 87, 82, 104, 81, 81,
-  75, 94, 68, 95, 98, 88, 84, 87, 75, 80,
-  80, 77, 119, 80, 76, 73, 71, 73, 91, 73,
-  91, 99, 97, 79, 88, 89, 89, 90, 94, 95,
-  78, 94, 86, 77, 89, 76, 61, 79, 92, 63,
-  101, 87, 89, 83, 81, 77, 86, 81, 85, 89,
-  89, 79, 84, 83, 69, 89, 79, 81, 88, 81,
-  91, 79, 73, 69, 88, 92, 76, 84, 81, 98,
-  85, 81, 80, 79, 82, 82, 80, 89, 87, 94,
-  73, 87, 90, 80, 82, 90, 81, 88, 87, 96,
-  84, 75, 81, 72, 83, 88, 79, 96, 82, 95,
-  87, 88, 91, 82, 77, 68, 72, 87, 88, 83,
-  99, 76, 87, 89, 98, 80, 114, 78, 51, 77,
-  88, 86, 78, 79, 83, 90, 72, 75, 84, 77,
-  64, 74, 78, 84, 95, 78, 75, 90, 78, 86,
-  61, 75, 76, 72, 93, 103, 71, 78, 84, 99,
-  72, 91, 93, 77, 81, 96, 83, 79, 85, 83,
-  82, 81, 79, 80, 66, 83, 82, 92, 89, 92,
-  59, 95, 88, 82, 86, 85, 82, 75, 81, 94,
-  83, 88, 108, 89, 89, 80, 83, 92, 81, 84,
-  76, 92, 90, 89, 73, 89, 76, 84, 92, 92,
-  80, 77, 109, 80, 80, 78, 81, 91, 77, 87,
-  89, 83, 71, 89, 88, 80, 89, 76, 82, 74,
-  72, 85, 80, 91, 98, 86, 75, 86, 88, 90,
-  87, 92, 78, 72, 75, 89, 88, 76, 93, 69,
-  88, 75, 71, 83, 86, 84, 84, 77, 91, 84,
-  85, 79, 85, 91, 88, 72, 81, 72, 82, 85,
-  85, 90, 91, 80, 66, 82, 94, 83, 86, 66,
-  62, 81, 76, 79, 80, 80, 81, 95, 59, 85,
-  88, 86, 80, 91, 84, 92, 76, 81, 77, 83,
-  77, 66, 67, 77, 81, 71, 88, 88, 59, 88,
-  71, 69, 89, 83, 82, 95, 85, 89, 82, 81,
-  86, 74, 79, 81, 88, 90, 86, 83, 78, 76,
-  87, 82, 82, 81, 81, 86, 89, 82, 83, 83,
-  109, 83, 85, 85, 80, 83, 87, 83, 78, 80,
-  78, 93, 91, 80, 88, 82, 75, 86, 64, 87,
-  77, 94, 102, 66, 84, 80, 94, 78, 83, 93,
-  86, 80, 88, 90, 87, 77, 88, 69, 81, 74,
-  59, 86, 64, 87, 129, 85, 84, 92, 78, 86,
-  88, 86, 95, 87, 84, 85, 113, 89, 90, 94,
-  83, 81, 68, 79, 89, 76, 122, 69, 72, 84,
-  68, 68, 100, 82, 76, 87, 81, 75, 88, 92,
-  88, 81, 88, 92, 72, 87, 89, 82, 88, 80,
-  87, 73, 81, 67, 84, 92, 90, 80, 81, 76,
-  81, 79, 101, 104, 94, 83, 80, 80, 58, 81,
-  71, 80, 88, 86, 78, 88, 84, 66, 96, 86,
-  88, 74, 98, 90, 76, 76, 80, 80, 99, 83,
-  92, 90, 79, 98, 72, 83, 104, 85, 85, 88,
-  74, 82, 96, 101, 99, 76, 68, 69, 82, 82,
-  87, 90, 81, 95, 86, 78, 89, 91, 71, 75,
-  71, 95, 94, 74, 96, 81, 84, 77, 91, 76,
-  89, 74, 67, 80, 88, 84, 79, 82, 82, 106,
-  80, 85, 78, 75, 63, 84, 95, 83, 82, 70,
-  77, 80, 81, 77, 73, 80, 74, 74, 81, 86,
-  77, 76, 77, 101, 82, 96, 93, 78, 81, 84,
-  91, 86, 90, 91, 76, 75, 77, 86, 58, 84,
-  84, 86, 112, 98, 56, 89, 85, 92, 87, 83,
-  86, 73, 78, 90, 78, 81, 94, 83, 82, 85,
-  83, 84, 80, 79, 77, 75, 82, 91, 75, 86,
-  71, 98, 89, 94, 79, 71, 115, 81, 88, 98,
-  80, 84, 79, 87, 87, 89, 88, 91, 79, 83,
-  90, 87, 83, 73, 67, 98, 72, 83, 103, 82,
-  84, 81, 93, 74, 82, 99, 80, 78, 71, 100,
-  88, 74, 91, 77, 90, 84, 115, 88, 76, 90,
-  84, 75, 86, 85, 82, 86, 87, 91, 97, 89,
-  87, 71, 99, 75, 85, 93, 86, 65, 72, 72,
-  89, 75, 78, 81, 78, 77, 76, 79, 71, 81,
-  80, 102, 77, 86, 91, 77, 94, 79, 90, 88,
-  81, 86, 76, 80, 84, 72, 81, 76, 75, 80,
-  92, 87, 56, 83, 77, 82, 82, 82, 87, 84,
-  92, 90, 78, 76, 73, 79, 76, 92, 84, 87,
-  85, 85, 81, 80, 78, 84, 87, 76, 88, 88,
-  82, 80, 82, 77, 100, 83, 82, 97, 91, 73,
-  86, 91, 72, 87, 91, 90, 85, 84, 91, 81,
-  60, 82, 80, 89, 63, 92, 105, 68, 82, 74,
-  101, 79, 80, 94, 90, 81, 82, 89, 78, 89,
-  84, 81, 80, 84, 104, 99, 69, 99, 109, 77,
-  81, 98, 82, 76, 87, 69, 99, 91, 98, 83,
-  133, 76, 74, 101, 86, 72, 73, 77, 91, 83,
-  94, 82, 84, 89, 85, 80, 77, 90, 74, 91,
-  86, 79, 92, 84, 102, 82, 82, 91, 71, 82,
-  82, 86, 87, 80, 98, 73, 73, 79, 76, 90,
-  86, 88, 78, 82, 77, 85, 99, 89, 92, 85,
-  76, 80, 59, 83, 86, 86, 90, 92, 77, 99,
-  83, 85, 93, 82, 93, 75, 104, 81, 78, 73,
-  76, 71, 84, 83, 78, 85, 69, 94, 82, 83,
-  77, 92, 97, 91, 73, 65, 84, 94, 79, 99,
-  88, 94, 74, 82, 85, 74, 81, 76, 95, 99,
-  85, 76, 91, 65, 97, 80, 76, 79, 69, 77,
-  91, 64, 94, 62, 88, 92, 80, 80, 87, 82,
-  82, 76, 85, 77, 83, 99, 74, 97, 73, 74,
-  92, 76, 83, 85, 75, 85, 79, 90, 85, 83,
-  87, 92, 93, 94, 76, 94, 72, 78, 83, 75,
-  71, 85, 83, 81, 98, 74, 81, 74, 66, 79,
-  78, 77, 81, 95, 91, 90, 83, 84, 89, 75,
-  93, 87, 101, 97, 82, 85, 82, 91, 88, 89,
-  72, 80, 87, 77, 100, 74, 90, 74, 89, 83,
-  76, 98, 94, 78, 97, 87, 84, 66, 82, 81,
-  89, 81, 74, 81, 73, 98, 82, 86, 74, 91,
-  87, 77, 80, 59, 82, 98, 81, 92, 83, 92,
-  89, 83, 83, 64, 82, 78, 98, 96, 84, 81,
-  97, 58, 106, 66, 82, 84, 77, 67, 91, 61,
-  91, 64, 82, 87, 84, 82, 77, 85, 92, 75,
-  86, 74, 87, 90, 77, 86, 75, 68, 88, 81,
-  84, 78, 81, 83, 84, 85, 84, 86, 91, 86,
-  104, 94, 80, 88, 73, 76, 92, 72, 77, 86,
-  80, 96, 92, 69, 77, 83, 75, 78, 71, 83,
-  86, 88, 90, 87, 84, 72, 93, 77, 90, 71,
-  99, 93, 80, 87, 82, 94, 87, 94, 83, 86,
-  86, 80, 110, 84, 81, 75, 87, 81, 79, 95,
-  94, 80, 89, 85, 85, 73, 86, 88, 90, 83,
-  69, 81, 69, 93, 90, 79, 75, 86, 79, 72,
-  76, 70, 81, 92, 80, 94, 86, 93, 84, 85,
-  84, 76, 79, 74, 90, 76, 92, 79, 89, 72,
-  94, 73, 74, 77, 92, 82, 89, 66, 92, 70,
-  89, 93, 80, 85, 92, 85, 77, 79, 87, 81,
-  87, 73, 65, 92, 74, 77, 83, 78, 85, 79,
-  71, 89, 79, 85, 88, 82, 78, 94, 94, 86,
-  76, 90, 73, 74, 93, 79, 71, 92, 89, 80,
-  95, 78, 80, 85, 69, 75, 83, 77, 75, 95,
-  92, 89, 82, 89, 85, 87, 86, 82, 99, 93,
-  80, 87, 81, 78, 84, 91, 89, 77, 87, 84,
-  110, 81, 87, 74, 84, 85, 79, 95, 90, 80,
-  91, 79, 79, 72, 68, 71, 81, 77, 105, 87,
-  70, 75, 59, 84, 106, 75, 93, 64, 76, 69,
-  87, 77, 90, 144, 88, 87, 86, 75, 85, 59,
-  75, 82, 104, 92, 106, 74, 90, 99, 95, 57,
-  48, 81, 69, 64, 83, 80, 91, 77, 77, 73,
-  89, 79, 69, 72, 86, 73, 66, 74, 56, 113,
-  88, 134, 61, 91, 83, 74, 75, 74, 78, 64,
-  87, 72, 88, 80, 112, 87, 77, 89, 76, 86,
-  70, 81, 79, 78, 64, 64, 77, 79, 131, 81,
-  86, 83, 65, 85, 61, 80, 79, 76, 87, 83,
-  85, 74, 88, 76, 73, 93, 98, 102, 81, 83,
-  89, 138, 89, 76, 87, 97, 82, 76, 161, 67,
-  87, 77, 96, 75, 74, 99, 69, 64, 89, 80,
-  90, 67, 70, 98, 85, 73, 111, 82, 77, 72,
-  65, 85, 114, 78, 106, 65, 80, 78, 98, 77,
-  93, 162, 80, 87, 77, 78, 85, 56, 64, 78,
-  98, 76, 120, 78, 83, 84, 83, 55, 48, 78,
-  65, 58, 86, 96, 89, 96, 83, 67, 87, 74,
-  60, 62, 92, 67, 68, 79, 49, 124, 90, 150,
-  48, 76, 76, 71, 76, 79, 67, 70, 91, 76,
-  89, 72, 99, 81, 72, 78, 87, 72, 66, 69,
-  80, 84, 78, 69, 69, 51, 169, 83, 74, 90,
-  69, 80, 57, 72, 66, 70, 70, 97, 82, 68,
-  87, 79, 59, 79, 98, 98, 78, 77, 86, 147,
-  97, 69, 90, 94, 80, 75, 168, 66, 77, 72,
-  97, 71, 73, 99, 65, 60, 99, 77, 95, 51,
-  75, 100, 94, 81, 75, 99, 66, 80, 71, 82,
-  94, 75, 85, 82, 81, 74, 82, 80, 85, 140,
-  81, 90, 78, 83, 83, 68, 85, 86, 97, 84,
-  98, 79, 96, 69, 96, 76, 75, 81, 71, 72,
-  78, 79, 90, 66, 78, 76, 89, 95, 78, 87,
-  76, 86, 63, 77, 74, 92, 81, 106, 75, 90,
-  82, 76, 75, 61, 70, 72, 88, 79, 81, 91,
-  87, 96, 91, 85, 85, 92, 80, 78, 81, 78,
-  61, 69, 83, 60, 99, 90, 75, 87, 69, 83,
-  75, 88, 85, 82, 76, 78, 88, 76, 86, 83,
-  79, 85, 96, 100, 82, 84, 87, 109, 79, 90,
-  82, 85, 84, 87, 111, 84, 99, 75, 90, 85,
-  92, 105, 73, 68, 75, 79, 83, 88, 74, 81,
-  77, 84, 64, 89, 81, 83, 87, 86, 76, 99,
-  90, 76, 78, 87, 74, 83, 85, 96, 93, 91,
-  78, 99, 96, 64, 94, 82, 93, 87, 80, 88,
-  93, 91, 86, 85, 60, 87, 91, 77, 77, 61,
-  94, 64, 77, 99, 79, 91, 86, 90, 80, 80,
-  93, 89, 86, 79, 87, 78, 95, 81, 91, 85,
-  90, 81, 86, 74, 80, 76, 81, 78, 88, 83,
-  87, 78, 71, 87, 86, 82, 78, 73, 72, 88,
-  90, 75, 91, 86, 87, 78, 81, 98, 88, 84,
-  87, 82, 98, 74, 75, 80, 84, 91, 78, 95,
-  90, 91, 87, 82, 84, 82, 69, 94, 99, 79,
-  92, 91, 109, 92, 92, 82, 90, 77, 90, 89,
-  91, 76, 85, 94, 80, 67, 73, 93, 74, 82,
-  66, 82, 82, 79, 91, 89, 80, 98, 101, 93,
-  77, 90, 76, 86, 81, 94, 93, 88, 88, 102,
-  89, 57, 94, 84, 89, 88, 75, 85, 99, 91,
-  86, 76, 67, 83, 77, 67, 79, 57, 98, 68,
-  78, 86, 77, 84, 82, 89, 83, 89, 92, 85,
-  83, 95, 89, 80, 94, 78, 92, 86, 93, 75,
-  89, 75, 91, 76, 76, 90, 97, 77, 82, 76,
-  71, 83, 87, 79, 77, 70, 78, 84, 87, 84,
-  87, 90, 83, 76, 84, 101, 90, 80, 84, 74,
-  97, 69, 79, 71, 85, 93, 88, 95, 89, 88,
-  84, 93, 83, 94, 74, 94, 89, 83, 93, 81,
-  82, 94, 93, 78, 89, 83, 94, 90, 87, 73,
-  85, 92, 80, 72, 73, 92, 73, 84, 75, 79,
-  78, 81, 91, 85, 81, 94, 93, 97, 76, 90,
-  69, 80, 82, 98, 84, 94, 88, 95, 88, 71,
-  93, 82, 84, 86, 79, 85, 86, 86, 81, 87,
-  77, 85, 72, 84, 81, 63, 90, 73, 83, 83,
-  78, 84, 92, 87, 75, 86, 86, 96, 90, 89,
-  84, 85, 89, 83, 91, 89, 92, 77, 83, 84,
-  85, 86, 81, 80, 86, 89, 83, 77, 79, 86,
-  87, 74, 77, 74, 71, 82, 89, 75, 96, 91,
-  82, 71, 77, 95, 89, 80, 82, 81, 85, 70,
-  80, 84, 83, 94, 77, 82, 95, 90, 83, 83,
-  84, 81, 72, 91, 82, 77, 95, 80, 77, 88,
-  95, 77, 92, 82, 85, 93, 89, 76, 89, 91,
-  79, 73, 97, 78, 73, 89, 91, 86, 84, 87,
-  78, 86, 98, 82, 82, 96, 64, 68, 82, 83,
-  100, 76, 85, 84, 81, 83, 91, 70, 85, 107,
-  89, 79, 86, 79, 79, 70, 82, 93, 74, 69,
-  90, 73, 81, 81, 82, 75, 91, 97, 82, 75,
-  105, 86, 111, 72, 82, 81, 95, 81, 82, 72,
-  88, 72, 92, 81, 84, 85, 90, 106, 70, 83,
-  96, 82, 75, 76, 85, 73, 84, 88, 76, 93,
-  90, 95, 106, 80, 70, 81, 72, 81, 85, 75,
-  87, 98, 73, 74, 74, 72, 78, 90, 57, 95,
-  95, 85, 89, 78, 71, 77, 88, 96, 86, 68,
-  89, 95, 74, 80, 129, 84, 78, 103, 94, 87,
-  74, 71, 117, 79, 76, 110, 93, 91, 99, 83,
-  108, 91, 72, 91, 96, 73, 88, 81, 75, 84,
-  102, 74, 85, 94, 70, 71, 90, 80, 98, 71,
-  85, 83, 75, 91, 93, 73, 81, 106, 86, 82,
-  91, 85, 75, 63, 82, 81, 71, 69, 94, 61,
-  84, 86, 84, 77, 98, 100, 81, 73, 108, 81,
-  105, 76, 88, 79, 99, 84, 91, 73, 84, 65,
-  95, 84, 83, 84, 82, 111, 69, 84, 99, 75,
-  74, 76, 79, 72, 86, 86, 72, 80, 98, 96,
-  107, 82, 68, 86, 78, 73, 72, 70, 93, 113,
-  73, 68, 68, 78, 74, 96, 57, 95, 92, 82,
-  86, 83, 70, 77, 84, 104, 79, 67, 99, 90,
-  77, 79, 132, 75, 79, 106, 81, 93, 68, 70,
-  94, 79, 75, 108, 93, 86, 103, 80, 91, 92,
-  78, 94, 89, 81, 84, 82, 79, 85, 95, 86,
-  83, 87, 64, 73, 82, 83, 101, 77, 79, 86,
-  87, 81, 85, 71, 81, 105, 86, 84, 89, 86,
-  80, 77, 82, 93, 77, 68, 88, 77, 82, 81,
-  82, 79, 88, 100, 86, 90, 102, 86, 101, 72,
-  82, 81, 91, 84, 84, 68, 94, 71, 96, 84,
-  82, 81, 93, 104, 68, 90, 96, 79, 77, 74,
-  81, 72, 90, 86, 81, 75, 99, 92, 104, 79,
-  74, 102, 74, 76, 88, 80, 84, 104, 72, 74,
-  76, 74, 79, 90, 58, 92, 83, 82, 89, 89,
-  71, 77, 86, 89, 85, 71, 87, 92, 85, 79,
-  127, 94, 72, 96, 81, 90, 73, 74, 78, 80,
-  76, 105, 91, 85, 97, 86, 94, 79, 73, 84,
-  77, 87, 88, 93, 81, 80, 96, 77, 83, 91,
-  64, 71, 91, 84, 104, 75, 87, 82, 83, 83,
-  86, 74, 89, 97, 92, 80, 88, 81, 89, 76,
-  87, 90, 78, 69, 86, 70, 94, 86, 86, 80,
-  82, 94, 84, 77, 103, 85, 113, 77, 86, 82,
-  94, 88, 88, 64, 87, 70, 86, 83, 87, 88,
-  81, 104, 69, 78, 96, 75, 82, 77, 95, 78,
-  83, 78, 74, 87, 78, 107, 101, 83, 72, 77,
-  77, 87, 83, 73, 86, 81, 78, 76, 77, 72,
-  79, 100, 61, 93, 92, 97, 85, 81, 66, 78,
-  75, 80, 83, 73, 89, 97, 86, 88, 121, 73,
-  80, 96, 87, 92, 76, 80, 101, 81, 80, 113,
-  87, 75, 99, 89, 108, 88, 76, 82, 83, 77,
-  94, 86, 76, 76, 94, 73, 85, 89, 64, 68,
-  102, 79, 102, 70, 87, 84, 77, 87, 88, 77,
-  86, 91, 94, 88, 93, 83, 82, 72, 87, 82,
-  78, 68, 100, 62, 98, 94, 87, 83, 88, 97,
-  80, 73, 107, 78, 107, 82, 94, 82, 97, 92,
-  97, 64, 83, 62, 92, 88, 88, 86, 72, 111,
-  73, 73, 102, 76, 77, 75, 90, 74, 81, 68,
-  72, 82, 74, 114, 101, 88, 73, 76, 87, 88,
-  68, 69, 92, 82, 76, 67, 63, 77, 72, 109,
-  63, 93, 87, 96, 77, 77, 69, 79, 66, 87,
-  77, 72, 88, 91, 92, 89, 122, 66, 87, 98,
-  83, 93, 68, 84, 73, 81, 73, 108, 88, 68,
-  100, 85, 87, 90, 86, 89, 78, 83, 89, 87,
-  81, 83, 92, 78, 83, 82, 62, 74, 84, 81,
-  103, 73, 79, 81, 88, 81, 82, 76, 85, 100,
-  86, 95, 89, 88, 89, 79, 85, 93, 81, 68,
-  93, 76, 88, 84, 81, 82, 83, 97, 85, 82,
-  104, 88, 102, 77, 81, 80, 90, 79, 85, 67,
-  88, 74, 90, 77, 85, 82, 83, 102, 77, 82,
-  96, 81, 74, 79, 87, 79, 87, 79, 79, 81,
-  77, 101, 98, 83, 76, 99, 78, 88, 78, 78,
-  84, 91, 78, 72, 79, 78, 75, 96, 63, 89,
-  80, 94, 86, 77, 69, 79, 76, 77, 78, 74,
-  92, 95, 95, 86, 121, 87, 75, 91, 85, 93,
-  75, 83, 69, 87, 79, 108, 89, 77, 97, 92,
-  93, 77, 66, 91, 77, 84, 84, 97, 87, 78,
-  89, 78, 85, 86, 69, 74, 84, 81, 94, 81,
-  82, 92, 78, 80, 82, 80, 93, 89, 89, 83,
-  80, 78, 92, 71, 85, 86, 86, 81, 88, 66,
-  94, 90, 76, 84, 79, 91, 90, 83, 92, 93,
-  91, 77, 87, 82, 98, 84, 91, 62, 92, 71,
-  79, 81, 91, 87, 88, 99, 70, 84, 83, 87,
-  96, 73, 97, 78, 85, 80, 77, 92, 88, 85,
-  91, 65, 78, 75, 78, 80, 87, 87, 88, 71,
-  84, 89, 82, 81, 81, 78, 67, 76, 87, 89,
-  97, 85, 77, 79, 82, 77, 88, 83, 82, 90,
-  86, 89, 110, 80, 83, 94, 83, 85, 77, 73,
-  93, 76, 85, 109, 88, 77, 95, 83, 99, 79,
-  78, 87, 76, 79, 87, 94, 90, 77, 87, 81,
-  82, 90, 69, 74, 98, 83, 93, 75, 79, 89,
-  82, 81, 80, 79, 91, 85, 92, 85, 80, 81,
-  92, 69, 82, 81, 78, 75, 93, 58, 100, 90,
-  84, 83, 80, 91, 87, 77, 87, 91, 93, 75,
-  95, 81, 97, 80, 102, 62, 92, 65, 81, 87,
-  89, 83, 76, 98, 71, 78, 82, 83, 77, 68,
-  99, 75, 79, 76, 80, 86, 85, 89, 91, 69,
-  84, 83, 83, 81, 77, 81, 94, 75, 96, 85,
-  77, 85, 73, 78, 71, 80, 82, 88, 90, 74,
-  77, 81, 76, 81, 91, 79, 80, 90, 85, 89,
-  109, 75, 85, 94, 81, 82, 70, 75, 75, 80,
-  85, 105, 89, 74, 95, 78, 87, 80, 90, 90,
-  81, 78, 87, 89, 87, 84, 84, 80, 82, 86,
-  70, 77, 79, 78, 90, 72, 72, 94, 88, 82,
-  76, 80, 88, 92, 85, 93, 81, 81, 91, 79,
-  79, 92, 83, 79, 88, 73, 94, 92, 83, 82,
-  80, 91, 89, 80, 91, 96, 88, 79, 85, 83,
-  93, 77, 87, 66, 91, 72, 82, 85, 85, 88,
-  87, 96, 77, 83, 84, 94, 72, 74, 92, 83,
-  85, 80, 81, 79, 79, 86, 91, 68, 85, 102,
-  81, 83, 82, 87, 88, 80, 84, 81, 82, 80,
-  69, 81, 66, 74, 78, 87, 98, 79, 75, 80,
-  86, 79, 84, 81, 85, 91, 91, 88, 109, 88,
-  79, 92, 81, 85, 80, 77, 66, 76, 85, 101,
-  90, 81, 93, 84, 75, 66, 87, 71, 71, 71,
-  83, 83, 94, 95, 79, 71, 82, 67, 61, 72,
-  79, 116, 75, 72, 81, 85, 90, 86, 72, 78,
-  95, 88, 110, 72, 94, 78, 87, 72, 59, 80,
-  61, 81, 90, 82, 81, 85, 76, 71, 88, 74,
-  78, 80, 97, 87, 84, 62, 77, 77, 88, 66,
-  82, 63, 73, 78, 96, 90, 87, 97, 49, 74,
-  106, 125, 76, 124, 78, 81, 110, 73, 93, 79,
-  81, 57, 79, 68, 78, 62, 88, 109, 93, 86,
-  82, 94, 53, 101, 95, 91, 85, 84, 90, 82,
-  77, 84, 96, 65, 87, 85, 100, 98, 78, 106,
-  74, 82, 75, 86, 73, 149, 86, 84, 98, 105,
-  94, 76, 105, 78, 81, 66, 72, 76, 67, 84,
-  78, 77, 70, 74, 81, 71, 71, 85, 80, 87,
-  93, 100, 75, 89, 68, 79, 63, 71, 90, 119,
-  74, 77, 80, 85, 65, 84, 69, 77, 101, 88,
-  108, 65, 86, 82, 94, 74, 65, 92, 65, 80,
-  59, 68, 83, 74, 82, 76, 89, 74, 71, 88,
-  91, 87, 81, 61, 79, 77, 91, 61, 82, 59,
-  65, 74, 98, 88, 78, 96, 54, 69, 92, 136,
-  80, 109, 75, 70, 112, 75, 95, 72, 82, 62,
-  86, 59, 83, 60, 88, 75, 89, 80, 84, 94,
-  50, 100, 91, 122, 78, 83, 107, 86, 79, 82,
-  85, 66, 91, 126, 101, 97, 88, 109, 67, 79,
-  73, 83, 76, 151, 90, 82, 91, 88, 71, 73,
-  98, 71, 70, 66, 73, 72, 64, 85, 76, 74,
-  91, 81, 96, 72, 82, 82, 67, 104, 85, 92,
-  80, 84, 85, 88, 57, 81, 94, 100, 79, 77,
-  92, 87, 69, 78, 73, 82, 98, 83, 105, 71,
-  84, 84, 112, 77, 70, 90, 72, 88, 83, 96,
-  85, 76, 75, 77, 88, 97, 80, 85, 89, 90,
-  92, 92, 79, 75, 102, 78, 92, 62, 90, 71,
-  81, 93, 83, 75, 45, 88, 81, 105, 83, 74,
-  67, 74, 127, 81, 76, 81, 75, 75, 75, 80,
-  89, 71, 91, 80, 85, 82, 89, 81, 68, 88,
-  100, 118, 82, 88, 109, 83, 71, 82, 93, 78,
-  80, 92, 93, 87, 68, 101, 76, 88, 70, 95,
-  82, 104, 89, 88, 89, 99, 76, 77, 91, 72,
-  87, 77, 90, 88, 74, 75, 90, 98, 80, 80,
-  91, 88, 86, 80, 97, 76, 78, 85, 86, 75,
-  90, 77, 82, 75, 70, 80, 76, 74, 88, 85,
-  81, 87, 80, 79, 82, 91, 91, 84, 95, 79,
-  76, 98, 73, 85, 73, 79, 92, 91, 78, 76,
-  74, 85, 77, 75, 86, 83, 82, 77, 79, 86,
-  75, 91, 78, 87, 65, 82, 81, 82, 93, 79,
-  92, 95, 87, 61, 73, 69, 82, 108, 77, 97,
-  76, 77, 97, 68, 88, 69, 90, 80, 91, 73,
-  79, 89, 99, 86, 84, 98, 77, 82, 78, 68,
-  84, 88, 72, 69, 87, 99, 86, 84, 80, 75,
-  93, 88, 94, 84, 89, 84, 98, 84, 95, 100,
-  87, 81, 88, 102, 97, 79, 93, 99, 89, 71,
-  91, 82, 81, 88, 77, 72, 79, 95, 76, 87,
-  94, 77, 103, 71, 81, 87, 84, 89, 94, 93,
-  91, 80, 74, 77, 81, 73, 73, 84, 71, 91,
-  82, 82, 82, 99, 90, 61, 105, 73, 75, 99,
-  80, 82, 70, 75, 72, 89, 79, 77, 102, 90,
-  71, 69, 86, 79, 86, 81, 83, 84, 76, 98,
-  80, 94, 58, 86, 79, 89, 94, 73, 77, 95,
-  78, 58, 65, 63, 78, 80, 95, 96, 62, 74,
-  113, 63, 90, 87, 107, 72, 94, 83, 85, 58,
-  99, 85, 83, 91, 72, 94, 70, 76, 75, 94,
-  65, 71, 95, 105, 95, 81, 72, 88, 92, 91,
-  104, 80, 81, 82, 109, 85, 99, 96, 93, 84,
-  81, 90, 72, 81, 94, 93, 71, 66, 92, 77,
-  81, 86, 67, 70, 77, 92, 77, 78, 77, 103,
-  84, 83, 77, 99, 86, 82, 68, 101, 68, 69,
-  86, 88, 78, 90, 86, 79, 68, 82, 82, 81,
-  98, 93, 88, 73, 84, 74, 83, 79, 78, 98,
-  74, 80, 67, 75, 84, 78, 83, 79, 80, 85,
-  82, 97, 82, 78, 80, 75, 69, 78, 91, 72,
-  90, 74, 75, 74, 93, 97, 93, 85, 70, 67,
-  70, 99, 82, 86, 94, 81, 94, 86, 103, 82,
-  88, 88, 100, 77, 82, 66, 79, 63, 95, 77,
-  91, 84, 73, 90, 78, 104, 78, 86, 92, 75,
-  81, 93, 82, 76, 84, 120, 98, 92, 76, 91,
-  74, 76, 86, 81, 88, 114, 84, 86, 89, 88,
-  83, 77, 86, 76, 81, 69, 78, 80, 76, 73,
-  84, 79, 80, 84, 87, 86, 88, 91, 86, 84,
-  67, 85, 88, 90, 91, 80, 90, 72, 75, 82,
-  78, 80, 90, 91, 81, 86, 87, 81, 79, 80,
-  85, 88, 77, 80, 82, 98, 80, 90, 86, 85,
-  88, 93, 81, 66, 77, 86, 83, 77, 86, 79,
-  71, 74, 85, 107, 75, 90, 75, 84, 77, 77,
-  92, 80, 79, 89, 96, 87, 86, 74, 84, 79,
-  87, 85, 81, 91, 85, 76, 87, 71, 94, 83,
-  75, 86, 96, 80, 85, 85, 83, 82, 92, 80,
-  105, 81, 87, 78, 95, 97, 82, 77, 73, 92,
-  76, 92, 87, 78, 82, 75, 75, 85, 93, 89,
-  98, 90, 87, 80, 87, 81, 77, 85, 88, 81,
-  90, 101, 91, 87, 85, 87, 92, 79, 91, 83,
-  78, 89, 91, 86, 90, 81, 87, 79, 76, 81,
-  88, 99, 101, 89, 93, 77, 78, 84, 79, 79,
-  80, 90, 82, 93, 83, 76, 78, 84, 83, 77,
-  81, 83, 86, 92, 78, 86, 90, 92, 83, 96,
-  86, 72, 93, 88, 79, 76, 83, 74, 67, 80,
-  95, 108, 75, 92, 77, 85, 73, 73, 97, 78,
-  77, 86, 88, 86, 84, 74, 79, 76, 89, 82,
-  93, 90, 86, 78, 86, 76, 93, 89, 76, 90,
-  97, 86, 90, 80, 75, 83, 87, 81, 97, 89,
-  84, 77, 94, 96, 75, 74, 80, 98, 89, 99,
-  85, 80, 76, 76, 68, 84, 85, 89, 91, 95,
-  86, 75, 87, 89, 81, 76, 85, 82, 91, 98,
-  86, 83, 85, 84, 90, 76, 87, 84, 83, 108,
-  93, 83, 86, 98, 84, 86, 77, 85, 88, 86,
-  79, 98, 78, 72, 82, 85, 79, 80, 89, 81,
-  80, 87, 86, 85, 81, 85, 77, 72, 83, 83,
-  86, 85, 85, 96, 84, 82, 79, 83, 89, 78,
-  88, 78, 79, 84, 84, 88, 81, 76, 86, 85,
-  71, 82, 85, 86, 86, 82, 77, 76, 86, 91,
-  97, 93, 74, 76, 83, 84, 95, 76, 88, 82,
-  88, 77, 98, 81, 86, 90, 90, 83, 87, 78,
-  80, 70, 80, 79, 87, 80, 90, 88, 82, 80,
-  89, 95, 90, 74, 78, 96, 94, 81, 86, 92,
-  83, 80, 67, 87, 83, 79, 97, 90, 89, 84,
-  87, 91, 80, 81, 97, 80, 86, 82, 82, 77,
-  87, 86, 81, 81, 88, 85, 82, 79, 79, 105,
-  90, 79, 81, 71, 82, 70, 71, 90, 85, 82,
-  81, 80, 87, 93, 60, 81, 86, 81, 99, 77,
-  77, 65, 83, 116, 94, 79, 84, 85, 76, 85,
-  79, 82, 78, 79, 86, 82, 86, 82, 82, 85,
-  89, 75, 83, 94, 81, 82, 82, 78, 82, 94,
-  85, 90, 65, 83, 78, 83, 87, 104, 85, 88,
-  96, 75, 78, 92, 79, 97, 75, 88, 88, 84,
-  82, 77, 85, 86, 80, 82, 69, 83, 72, 93,
-  89, 82, 79, 79, 77, 77, 80, 88, 86, 77,
-  88, 81, 103, 90, 94, 82, 82, 81, 101, 90,
-  89, 92, 75, 105, 95, 80, 78, 81, 76, 77,
-  99, 90, 94, 77, 67, 78, 85, 75, 84, 71,
-  87, 80, 70, 99, 81, 87, 83, 114, 100, 92,
-  84, 63, 88, 60, 68, 82, 87, 82, 89, 87,
-  90, 94, 55, 83, 86, 74, 87, 79, 86, 65,
-  80, 129, 97, 85, 85, 95, 78, 83, 83, 84,
-  84, 69, 84, 84, 90, 85, 87, 89, 94, 74,
-  84, 83, 81, 83, 84, 76, 79, 96, 90, 85,
-  64, 79, 77, 80, 87, 98, 86, 81, 86, 67,
-  72, 89, 74, 97, 82, 90, 81, 85, 84, 75,
-  81, 87, 80, 90, 70, 80, 78, 77, 91, 81,
-  80, 83, 76, 88, 75, 87, 86, 80, 80, 90,
-  107, 89, 89, 81, 76, 87, 97, 90, 85, 90,
-  77, 110, 100, 85, 79, 89, 77, 75, 99, 88,
-  77, 72, 58, 83, 79, 75, 84, 78, 94, 76,
-  60, 102, 83, 92, 87, 103, 84, 95, 81, 72,
-  82, 73, 72, 89, 81, 82, 80, 84, 86, 86,
-  60, 83, 80, 74, 73, 78, 84, 71, 84, 114,
-  91, 77, 86, 91, 76, 77, 76, 91, 84, 81,
-  81, 84, 81, 85, 85, 83, 89, 79, 86, 82,
-  77, 79, 82, 77, 83, 91, 85, 83, 67, 88,
-  76, 84, 90, 101, 86, 90, 96, 75, 77, 90,
-  77, 91, 93, 85, 90, 85, 83, 81, 80, 89,
-  84, 85, 71, 84, 72, 83, 89, 80, 85, 77,
-  82, 86, 80, 96, 83, 78, 76, 80, 102, 92,
-  81, 87, 82, 98, 106, 89, 85, 89, 79, 100,
-  99, 82, 78, 82, 82, 79, 95, 85, 77, 79,
-  68, 78, 78, 74, 77, 74, 89, 79, 68, 95,
-  77, 75, 85, 118, 86, 88, 76, 75, 83, 67,
-  75, 81, 84, 84, 78, 94, 88, 86, 57, 81,
-  85, 77, 98, 77, 82, 66, 75, 132, 97, 89,
-  81, 86, 79, 80, 86, 80, 79, 86, 85, 77,
-  81, 85, 77, 89, 86, 75, 79, 101, 74, 81,
-  73, 84, 79, 94, 89, 93, 62, 93, 76, 84,
-  78, 99, 84, 84, 89, 73, 83, 86, 87, 86,
-  91, 81, 77, 80, 83, 72, 83, 81, 78, 76,
-  75, 95, 66, 80, 89, 80, 76, 85, 81, 71,
-  82, 87, 86, 79, 86, 83, 110, 89, 88, 87,
-  74, 79, 101, 85, 87, 93, 80, 106, 92, 72,
-  86, 86, 83, 83, 93, 87, 85, 80, 64, 81,
-  82, 75, 88, 73, 98, 79, 59, 99, 92, 90,
-  93, 123, 95, 88, 78, 78, 100, 58, 79, 76,
-  103, 80, 84, 105, 91, 82, 53, 80, 81, 68,
-  84, 86, 88, 70, 75, 148, 97, 83, 81, 99,
-  83, 74, 91, 74, 87, 82, 88, 87, 77, 107,
-  84, 86, 92, 66, 81, 86, 73, 83, 83, 85,
-  79, 97, 91, 93, 61, 90, 66, 75, 71, 88,
-  83, 98, 68, 76, 80, 72, 85, 73, 81, 86,
-  70, 87, 79, 70, 82, 90, 74, 93, 77, 100,
-  77, 72, 89, 83, 72, 85, 80, 76, 85, 82,
-  85, 74, 69, 88, 118, 85, 91, 92, 69, 74,
-  89, 82, 77, 92, 82, 112, 100, 79, 92, 82,
-  84, 66, 91, 85, 69, 77, 57, 81, 75, 74,
-  98, 86, 111, 72, 51, 107, 79, 92, 98, 116,
-  81, 98, 76, 74, 80, 71, 74, 83, 78, 81,
-  79, 91, 86, 83, 59, 91, 78, 77, 82, 77,
-  85, 72, 78, 126, 93, 76, 82, 90, 77, 73,
-  86, 89, 85, 86, 82, 80, 79, 85, 83, 84,
-  84, 75, 79, 82, 70, 77, 77, 79, 81, 91,
-  90, 88, 66, 94, 77, 85, 83, 96, 86, 84,
-  92, 73, 82, 87, 85, 90, 89, 81, 83, 81,
-  86, 74, 81, 93, 88, 79, 75, 94, 72, 84,
-  87, 80, 86, 82, 81, 82, 79, 89, 84, 79,
-  78, 83, 107, 90, 87, 91, 75, 88, 102, 85,
-  81, 92, 81, 99, 93, 73, 84, 85, 87, 75,
-  88, 84, 89, 84, 65, 81, 74, 76, 81, 72,
-  98, 80, 61, 92, 73, 75, 86, 121, 83, 82,
-  72, 75, 81, 74, 82, 85, 81, 78, 77, 91,
-  88, 82, 58, 85, 90, 77, 89, 76, 85, 78,
-  73, 114, 92, 82, 86, 89, 80, 88, 84, 84,
-  83, 101, 84, 85, 81, 87, 78, 82, 87, 91,
-  71, 96, 72, 85, 77, 79, 86, 90, 91, 91,
-  72, 87, 88, 78, 80, 89, 81, 83, 97, 82,
-  91, 87, 94, 79, 95, 92, 85, 84, 77, 83,
-  79, 86, 80, 84, 74, 84, 66, 79, 88, 85,
-  75, 75, 77, 76, 94, 83, 82, 83, 93, 75,
-  102, 87, 84, 101, 82, 81, 100, 84, 85, 94,
-  84, 95, 84, 65, 82, 85, 78, 94, 92, 85,
-  81, 87, 73, 94, 77, 74, 80, 66, 88, 84,
-  65, 94, 73, 83, 102, 124, 85, 90, 75, 74,
-  85, 73, 82, 79, 90, 80, 78, 92, 88, 85,
-  50, 89, 83, 67, 87, 79, 85, 83, 71, 130,
-  88, 77, 83, 97, 78, 87, 85, 82, 89, 115,
-  83, 90, 79, 86, 86, 81, 87, 80, 63, 91,
-  74, 84, 79, 81, 86, 91, 86, 90, 69, 73,
-  78, 71, 74, 88, 84, 78, 88, 77, 87, 82,
-  100, 88, 84, 95, 83, 87, 75, 79, 80, 96,
-  73, 94, 76, 83, 63, 78, 88, 85, 76, 82,
-  66, 74, 93, 88, 81, 83, 89, 78, 106, 84,
-  84, 102, 73, 80, 93, 83, 77, 101, 82, 99,
-  76, 67, 82, 83, 77, 79, 90, 88, 82, 91,
-  65, 88, 74, 74, 85, 63, 95, 81, 61, 90,
-  77, 83, 92, 117, 81, 89, 75, 78, 78, 76,
-  80, 88, 81, 84, 77, 86, 89, 83, 60, 86,
-  82, 76, 83, 75, 84, 80, 71, 109, 88, 76,
-  89, 90, 79, 90, 80, 87, 86, 98, 80, 84,
-  80, 83, 90, 82, 86, 84, 71, 88, 67, 83,
-  77, 79, 85, 87, 88, 86, 78, 86, 86, 80,
-  83, 84, 83, 84, 93, 84, 87, 86, 97, 85,
-  77, 87, 88, 85, 79, 84, 83, 95, 80, 81,
-  73, 83, 72, 78, 89, 77, 92, 77, 70, 80,
-  92, 92, 83, 86, 83, 74, 98, 89, 85, 96,
-  84, 81, 101, 85, 75, 91, 84, 88, 83, 70,
-  78, 83, 78, 77, 92, 83, 98, 89, 78, 92,
-  82, 77, 80, 69, 86, 88, 70, 90, 85, 76,
-  95, 78, 81, 92, 73, 91, 73, 81, 83, 83,
-  103, 78, 96, 73, 94, 82, 79, 113, 101, 88,
-  86, 86, 82, 78, 79, 83, 81, 80, 79, 79,
-  98, 67, 65, 86, 71, 74, 70, 97, 88, 80,
-  81, 74, 86, 78, 94, 83, 84, 64, 75, 98,
-  87, 80, 89, 77, 76, 80, 81, 124, 93, 76,
-  98, 89, 95, 88, 95, 81, 83, 87, 68, 87,
-  84, 96, 79, 77, 56, 87, 105, 75, 78, 78,
-  87, 90, 87, 72, 89, 85, 76, 89, 83, 94,
-  76, 87, 78, 75, 78, 70, 89, 83, 53, 46,
-  80, 126, 82, 83, 83, 97, 95, 90, 78, 86,
-  93, 92, 92, 80, 94, 80, 65, 94, 96, 88,
-  78, 82, 60, 98, 81, 80, 82, 77, 70, 76,
-  66, 75, 62, 82, 64, 82, 87, 76, 107, 76,
-  111, 52, 111, 80, 81, 121, 86, 63, 84, 79,
-  78, 75, 86, 82, 105, 80, 68, 81, 105, 70,
-  77, 64, 81, 76, 80, 77, 76, 88, 100, 60,
-  86, 64, 78, 79, 77, 65, 75, 70, 64, 79,
-  76, 83, 73, 72, 73, 139, 91, 75, 81, 91,
-  80, 82, 108, 112, 73, 83, 81, 90, 78, 98,
-  75, 70, 60, 63, 102, 71, 66, 68, 89, 102,
-  94, 68, 80, 87, 52, 69, 89, 110, 80, 89,
-  78, 79, 80, 58, 83, 85, 53, 92, 89, 119,
-  104, 76, 92, 104, 98, 85, 75, 86, 83, 81,
-  77, 85, 69, 88, 75, 77, 99, 104, 74, 69,
-  34, 91, 92, 102, 86, 105, 81, 85, 94, 78,
-  82, 87, 99, 84, 70, 92, 72, 74, 86, 83,
-  90, 92, 82, 76, 88, 87, 84, 91, 86, 81,
-  87, 82, 79, 69, 89, 76, 88, 89, 85, 88,
-  90, 77, 76, 97, 93, 87, 97, 95, 93, 81,
-  101, 95, 82, 71, 76, 103, 108, 85, 119, 89,
-  80, 79, 94, 88, 81, 89, 91, 64, 81, 92,
-  83, 75, 92, 87, 106, 84, 84, 83, 79, 82,
-  67, 85, 103, 83, 110, 71, 85, 85, 83, 77,
-  96, 81, 101, 80, 90, 92, 76, 91, 97, 80,
-  74, 81, 80, 85, 63, 64, 82, 115, 75, 91,
-  80, 91, 84, 94, 77, 79, 98, 88, 67, 81,
-  91, 78, 70, 92, 102, 65, 87, 98, 80, 87,
-  80, 85, 91, 57, 82, 77, 85, 80, 79, 88,
-  63, 84, 99, 69, 97, 62, 96, 77, 83, 72,
-  87, 111, 89, 83, 89, 81, 69, 88, 90, 88,
-  97, 70, 74, 82, 91, 83, 88, 87, 55, 82,
-  76, 86, 81, 83, 96, 69, 84, 78, 97, 86,
-  71, 65, 77, 81, 68, 84, 84, 91, 83, 81,
-  83, 148, 81, 87, 86, 89, 85, 75, 88, 81,
-  86, 63, 95, 107, 94, 84, 81, 81, 66, 86,
-  86, 86, 58, 71, 84, 103, 97, 77, 89, 83,
-  84, 103, 84, 88, 71, 82, 95, 82, 74, 56,
-  83, 79, 54, 87, 82, 120, 75, 79, 77, 100,
-  95, 92, 86, 78, 87, 87, 80, 77, 78, 85,
-  74, 80, 77, 106, 69, 73, 59, 79, 92, 73,
-  82, 76, 79, 78, 70, 72, 67, 76, 46, 88,
-  99, 67, 99, 77, 107, 65, 93, 65, 81, 138,
-  80, 68, 83, 74, 75, 87, 92, 86, 110, 104,
-  65, 86, 86, 77, 83, 75, 79, 95, 72, 69,
-  91, 89, 81, 55, 90, 55, 77, 74, 75, 72,
-  70, 50, 40, 85, 57, 71, 81, 72, 62, 162,
-  95, 81, 78, 97, 68, 67, 92, 102, 80, 64,
-  66, 128, 86, 74, 73, 76, 78, 69, 79, 81,
-  41, 68, 77, 95, 103, 92, 79, 89, 51, 93,
-  79, 90, 84, 75, 90, 85, 75, 44, 84, 85,
-  64, 79, 94, 114, 82, 69, 75, 108, 89, 86,
-  82, 74, 77, 80, 89, 85, 66, 97, 77, 78,
-  104, 120, 52, 63, 27, 70, 100, 94, 85, 107,
-  88, 86, 88, 89, 86, 86, 100, 84, 75, 85,
-  73, 91, 85, 91, 80, 94, 83, 68, 87, 103,
-  87, 85, 75, 78, 95, 87, 88, 74, 85, 81,
-  84, 77, 89, 85, 76, 82, 80, 95, 87, 88,
-  89, 89, 91, 80, 96, 76, 73, 74, 75, 104,
-  96, 83, 120, 74, 79, 72, 93, 91, 81, 90,
-  84, 53, 81, 87, 82, 70, 90, 82, 93, 89,
-  97, 86, 77, 80, 75, 81, 72, 94, 103, 65,
-  87, 90, 79, 83, 90, 83, 101, 76, 92, 84,
-  74, 81, 90, 81, 79, 75, 93, 76, 63, 46,
-  80, 111, 70, 88, 82, 85, 81, 92, 87, 83,
-  91, 88, 75, 95, 101, 78, 76, 88, 101, 73,
-  78, 90, 76, 85, 82, 84, 94, 68, 93, 93,
-  78, 90, 82, 89, 86, 93, 86, 86, 99, 80,
-  94, 88, 81, 87, 86, 80, 97, 78, 82, 92,
-  86, 85, 77, 85, 81, 81, 93, 92, 83, 78,
-  72, 87, 72, 87, 85, 87, 89, 68, 92, 97,
-  80, 97, 89, 93, 72, 89, 80, 101, 97, 93,
-  108, 88, 79, 83, 98, 96, 73, 91, 96, 85,
-  91, 78, 91, 83, 84, 85, 85, 76, 95, 90,
-  87, 82, 84, 83, 80, 74, 90, 94, 87, 82,
-  89, 85, 89, 82, 94, 108, 86, 97, 71, 74,
-  91, 71, 79, 84, 78, 80, 59, 108, 85, 109,
-  87, 89, 91, 78, 83, 89, 86, 77, 96, 83,
-  92, 95, 80, 84, 78, 84, 87, 81, 86, 86,
-  94, 87, 90, 68, 89, 83, 82, 93, 75, 77,
-  78, 79, 90, 88, 86, 84, 103, 95, 97, 90,
-  84, 91, 86, 74, 89, 82, 88, 99, 87, 75,
-  82, 90, 90, 86, 86, 81, 82, 70, 68, 67,
-  74, 84, 84, 84, 82, 72, 85, 88, 73, 101,
-  82, 69, 68, 98, 77, 100, 93, 92, 111, 91,
-  78, 88, 94, 78, 74, 87, 91, 82, 92, 76,
-  80, 71, 77, 93, 71, 69, 87, 87, 79, 79,
-  75, 77, 75, 67, 85, 88, 95, 87, 89, 87,
-  84, 82, 105, 119, 85, 95, 77, 62, 85, 66,
-  81, 73, 94, 83, 66, 101, 78, 105, 81, 96,
-  90, 81, 78, 88, 83, 79, 90, 86, 93, 98,
-  79, 80, 71, 89, 87, 83, 82, 81, 76, 81,
-  90, 78, 88, 101, 83, 90, 83, 83, 80, 87,
-  89, 94, 86, 89, 86, 85, 89, 96, 88, 82,
-  82, 80, 83, 84, 83, 87, 82, 79, 85, 78,
-  78, 80, 87, 81, 76, 83, 87, 92, 83, 85,
-  78, 89, 89, 79, 89, 99, 84, 85, 76, 87,
-  77, 79, 80, 85, 95, 90, 100, 82, 83, 84,
-  88, 97, 81, 89, 87, 72, 91, 88, 87, 89,
-  94, 83, 78, 82, 84, 84, 88, 82, 77, 87,
-  69, 85, 98, 82, 83, 92, 88, 84, 86, 84,
-  82, 99, 79, 98, 78, 79, 96, 78, 81, 89,
-  95, 75, 70, 88, 87, 103, 86, 83, 90, 86,
-  92, 77, 89, 79, 92, 89, 76, 94, 92, 84,
-  78, 86, 86, 81, 77, 89, 89, 87, 87, 73,
-  103, 83, 91, 88, 111, 80, 73, 88, 70, 89,
-  89, 85, 92, 90, 77, 69, 85, 82, 93, 102,
-  76, 79, 76, 73, 95, 92, 69, 79, 92, 87,
-  87, 87, 86, 86, 86, 94, 74, 71, 77, 92,
-  75, 76, 97, 71, 84, 75, 75, 83, 87, 74,
-  80, 70, 70, 95, 60, 87, 77, 89, 69, 98,
-  88, 88, 106, 68, 69, 79, 82, 105, 89, 81,
-  84, 93, 86, 79, 106, 76, 76, 75, 86, 87,
-  72, 88, 82, 74, 89, 71, 91, 96, 82, 81,
-  82, 88, 82, 102, 71, 107, 93, 94, 92, 89,
-  86, 93, 95, 90, 81, 74, 83, 91, 94, 77,
-  80, 82, 95, 89, 94, 70, 84, 84, 77, 81,
-  101, 78, 73, 80, 75, 79, 88, 67, 90, 91,
-  83, 89, 100, 93, 76, 90, 78, 94, 91, 91,
-  87, 94, 76, 71, 86, 78, 90, 104, 73, 73,
-  70, 80, 90, 85, 87, 84, 95, 88, 84, 92,
-  89, 73, 90, 108, 85, 78, 81, 80, 77, 75,
-  101, 75, 90, 90, 77, 87, 79, 78, 78, 83,
-  70, 86, 80, 99, 87, 83, 82, 101, 79, 79,
-  93, 58, 66, 71, 79, 102, 75, 72, 109, 86,
-  92, 87, 103, 77, 74, 79, 83, 71, 81, 77,
-  86, 72, 82, 77, 83, 85, 80, 75, 77, 101,
-  81, 102, 80, 95, 87, 84, 78, 87, 82, 105,
-  93, 86, 84, 79, 87, 87, 99, 78, 80, 85,
-  91, 84, 89, 72, 74, 79, 81, 79, 86, 86,
-  82, 81, 73, 77, 85, 82, 80, 97, 91, 86,
-  76, 103, 81, 79, 94, 89, 79, 90, 95, 87,
-  61, 78, 80, 83, 72, 90, 84, 94, 72, 91,
-  87, 78, 107, 88, 100, 84, 88, 91, 91, 63,
-  88, 94, 83, 84, 93, 74, 86, 74, 93, 90,
-  88, 129, 97, 92, 80, 97, 79, 110, 92, 71,
-  129, 106, 104, 71, 105, 85, 71, 80, 84, 65,
-  53, 73, 65, 77, 78, 93, 91, 75, 103, 99,
-  81, 85, 94, 94, 82, 62, 91, 68, 94, 76,
-  63, 87, 88, 70, 77, 65, 92, 108, 98, 85,
-  90, 71, 66, 77, 82, 90, 89, 88, 81, 83,
-  87, 89, 90, 81, 87, 96, 79, 85, 78, 81,
-  81, 100, 101, 83, 91, 85, 95, 100, 87, 76,
-  88, 85, 75, 112, 94, 78, 85, 89, 78, 82,
-  79, 91, 78, 89, 83, 90, 81, 85, 93, 71,
-  84, 91, 87, 76, 82, 79, 79, 77, 86, 85,
-  73, 78, 81, 80, 84, 88, 75, 83, 92, 81,
-  79, 82, 77, 87, 82, 90, 92, 78, 76, 79,
-  83, 84, 84, 71, 95, 73, 78, 91, 71, 80,
-  75, 87, 72, 68, 81, 91, 90, 80, 77, 93,
-  79, 69, 94, 85, 87, 89, 85, 84, 98, 70,
-  93, 75, 80, 109, 73, 88, 80, 64, 83, 72,
-  85, 91, 87, 76, 73, 85, 92, 83, 69, 103,
-  91, 96, 102, 94, 84, 83, 83, 87, 79, 78,
-  75, 83, 68, 83, 83, 84, 90, 77, 84, 73,
-  74, 84, 85, 93, 97, 75, 69, 74, 64, 77,
-  83, 68, 91, 89, 83, 88, 94, 83, 80, 92,
-  76, 93, 93, 89, 77, 96, 88, 79, 92, 81,
-  94, 91, 72, 73, 72, 81, 84, 92, 70, 80,
-  74, 79, 87, 91, 77, 86, 88, 95, 87, 82,
-  78, 84, 86, 85, 94, 78, 83, 73, 77, 85,
-  82, 70, 95, 71, 70, 95, 71, 85, 81, 85,
-  78, 89, 80, 78, 92, 66, 68, 81, 79, 86,
-  91, 78, 84, 87, 83, 80, 103, 72, 78, 76,
-  74, 94, 81, 86, 76, 67, 96, 82, 81, 90,
-  81, 73, 70, 79, 81, 98, 76, 103, 91, 95,
-  86, 83, 78, 86, 89, 83, 77, 72, 81, 85,
-  80, 75, 83, 83, 89, 83, 78, 73, 78, 77,
-  81, 85, 83, 75, 80, 82, 63, 76, 85, 67,
-  88, 96, 87, 84, 75, 108, 84, 83, 82, 97,
-  88, 87, 85, 88, 75, 80, 86, 86, 78, 91,
-  78, 81, 71, 80, 84, 85, 91, 86, 85, 74,
-  84, 92, 80, 64, 93, 97, 85, 76, 84, 73,
-  82, 73, 84, 84, 86, 106, 91, 89, 77, 92,
-  76, 103, 82, 78, 104, 94, 95, 76, 92, 87,
-  81, 79, 84, 68, 64, 74, 67, 86, 80, 92,
-  105, 72, 96, 91, 85, 85, 91, 91, 81, 71,
-  89, 75, 82, 73, 71, 78, 93, 81, 73, 67,
-  82, 98, 90, 87, 86, 82, 78, 79, 68, 90,
-  82, 93, 87, 76, 81, 80, 86, 80, 86, 88,
-  81, 85, 75, 85, 76, 83, 99, 79, 89, 86,
-  94, 91, 88, 74, 85, 82, 77, 100, 92, 79,
-  88, 89, 76, 86, 78, 89, 79, 93, 83, 91,
-  87, 81, 89, 77, 85, 92, 81, 93, 87, 82,
-  85, 81, 84, 86, 92, 85, 86, 86, 83, 87,
-  82, 76, 96, 87, 84, 88, 77, 87, 90, 94,
-  92, 83, 80, 77, 78, 78, 82, 75, 84, 77,
-  87, 84, 75, 80, 74, 99, 75, 78, 77, 85,
-  84, 82, 82, 89, 75, 81, 88, 90, 81, 86,
-  86, 89, 99, 77, 90, 77, 79, 88, 73, 85,
-  78, 68, 82, 70, 84, 92, 86, 69, 84, 88,
-  100, 84, 71, 91, 81, 86, 104, 94, 86, 90,
-  78, 84, 91, 75, 86, 87, 80, 89, 83, 87,
-  86, 73, 82, 75, 76, 80, 91, 87, 99, 86,
-  81, 69, 74, 86, 81, 76, 89, 77, 89, 90,
-  90, 81, 81, 90, 79, 88, 94, 89, 85, 90,
-  88, 83, 97, 88, 85, 90, 76, 80, 77, 83,
-  79, 90, 82, 86, 87, 88, 88, 91, 78, 89,
-  84, 90, 88, 91, 75, 87, 91, 95, 97, 85,
-  89, 70, 75, 86, 86, 69, 93, 75, 77, 89,
-  68, 79, 77, 89, 78, 89, 83, 74, 85, 72,
-  79, 82, 76, 83, 88, 86, 77, 84, 80, 85,
-  93, 77, 83, 74, 78, 93, 75, 84, 74, 67,
-  90, 82, 78, 90, 82, 67, 75, 78, 86, 97,
-  79, 97, 87, 93, 95, 87, 85, 82, 81, 80,
-  84, 74, 85, 89, 79, 83, 83, 88, 87, 79,
-  84, 76, 83, 78, 85, 84, 84, 83, 78, 78,
-  64, 82, 81, 70, 87, 100, 85, 87, 78, 108,
-  87, 83, 75, 93, 91, 85, 90, 92, 77, 77,
-  92, 91, 76, 96, 74, 83, 72, 84, 79, 86,
-  87, 88, 88, 79, 92, 94, 82, 69, 82, 96,
-  83, 78, 75, 82, 79, 83, 93, 89, 91, 93,
-  88, 100, 84, 87, 85, 93, 81, 79, 87, 81,
-  90, 82, 93, 88, 89, 78, 81, 72, 69, 74,
-  67, 77, 87, 87, 92, 73, 88, 92, 85, 88,
-  88, 82, 80, 80, 86, 86, 75, 68, 80, 76,
-  89, 79, 78, 62, 87, 83, 87, 90, 84, 81,
-  82, 82, 80, 86, 84, 90, 89, 75, 80, 76,
-  87, 83, 86, 87, 81, 89, 80, 86, 80, 77,
-  96, 79, 88, 85, 96, 87, 88, 78, 81, 77,
-  76, 87, 77, 102, 109, 80, 84, 83, 97, 94,
-  81, 76, 77, 88, 80, 90, 77, 83, 80, 85,
-  86, 80, 88, 79, 91, 69, 87, 93, 82, 68,
-  89, 81, 82, 82, 91, 81, 82, 88, 79, 82,
-  78, 87, 74, 67, 86, 85, 80, 113, 84, 90,
-  97, 73, 79, 82, 73, 85, 70, 67, 83, 73,
-  89, 80, 76, 81, 96, 82, 89, 84, 75, 79,
-  88, 89, 86, 81, 99, 75, 72, 94, 81, 84,
-  78, 104, 77, 81, 97, 81, 89, 97, 81, 68,
-  95, 83, 78, 80, 90, 104, 77, 85, 86, 78,
-  78, 90, 85, 86, 84, 81, 93, 90, 93, 84,
-  85, 80, 95, 92, 90, 79, 83, 88, 91, 91,
-  96, 93, 84, 78, 88, 79, 70, 85, 79, 85,
-  81, 90, 100, 74, 86, 94, 106, 80, 72, 67,
-  75, 89, 94, 92, 80, 80, 85, 78, 82, 84,
-  99, 77, 84, 76, 95, 91, 78, 65, 82, 82,
-  89, 87, 96, 83, 85, 88, 82, 71, 86, 93,
-  62, 63, 93, 97, 74, 109, 90, 99, 92, 78,
-  85, 85, 72, 89, 64, 89, 85, 75, 95, 79,
-  70, 84, 96, 81, 92, 91, 69, 81, 92, 77,
-  88, 85, 83, 69, 80, 79, 84, 92, 80, 112,
-  77, 87, 98, 71, 101, 100, 82, 64, 96, 91,
-  64, 65, 80, 106, 63, 86, 83, 78, 91, 91,
-  62, 83, 76, 81, 99, 84, 98, 81, 98, 81,
-  101, 93, 83, 80, 77, 99, 93, 91, 103, 96,
-  85, 81, 97, 72, 73, 88, 82, 96, 76, 78,
-  86, 79, 85, 90, 96, 85, 80, 75, 83, 81,
-  89, 86, 83, 89, 84, 85, 88, 81, 99, 76,
-  81, 71, 87, 92, 84, 70, 79, 88, 79, 82,
-  97, 95, 87, 83, 86, 79, 90, 86, 69, 69,
-  84, 88, 78, 106, 84, 90, 98, 76, 83, 83,
-  73, 90, 68, 96, 83, 82, 88, 80, 80, 84,
-  92, 84, 90, 88, 76, 80, 92, 85, 90, 85,
-  93, 81, 76, 88, 84, 91, 81, 107, 78, 81,
-  93, 73, 99, 102, 85, 72, 97, 87, 76, 81,
-  84, 96, 78, 83, 91, 80, 90, 89, 84, 78,
-  84, 85, 90, 92, 91, 83, 83, 77, 89, 94,
-  88, 81, 78, 93, 96, 87, 96, 91, 80, 81,
-  90, 78, 65, 83, 82, 92, 73, 100, 70, 94,
-  92, 80, 82, 102, 97, 88, 73, 98, 89, 62,
-  64, 90, 80, 86, 78, 83, 71, 92, 71, 70,
-  74, 89, 103, 87, 113, 69, 59, 79, 82, 88,
-  56, 90, 107, 91, 78, 100, 97, 66, 83, 70,
-  95, 97, 75, 81, 95, 70, 59, 76, 75, 65,
-  84, 101, 89, 64, 86, 80, 88, 68, 101, 82,
-  76, 60, 87, 86, 76, 116, 102, 80, 87, 70,
-  73, 92, 63, 74, 99, 74, 88, 60, 82, 79,
-  69, 75, 85, 86, 65, 87, 87, 93, 92, 93,
-  104, 78, 91, 78, 77, 94, 102, 86, 94, 73,
-  85, 76, 69, 91, 68, 82, 73, 73, 82, 92,
-  89, 75, 72, 82, 89, 72, 77, 67, 88, 91,
-  72, 82, 78, 57, 66, 84, 75, 95, 93, 83,
-  79, 113, 103, 90, 76, 106, 92, 71, 65, 87,
-  84, 88, 81, 82, 86, 91, 82, 72, 78, 93,
-  93, 94, 106, 66, 52, 82, 85, 89, 44, 87,
-  88, 109, 77, 103, 107, 63, 75, 72, 94, 102,
-  69, 71, 88, 74, 68, 78, 75, 67, 79, 68,
-  92, 62, 91, 88, 86, 78, 104, 81, 71, 59,
-  81, 86, 76, 106, 69, 79, 98, 80, 75, 103,
-  69, 82, 73, 73, 90, 65, 71, 88, 73, 85,
-  91, 82, 52, 84, 85, 94, 89, 95, 106, 78,
-  89, 77, 64, 101, 109, 75, 87, 72, 69, 76,
-  76, 85, 66, 81, 64, 70, 87, 93, 85, 75,
-  79, 83, 91, 62, 74, 66, 84, 96, 73, 79,
-  76, 57, 76, 76, 92, 92, 88, 72, 83, 100,
-  93, 89, 80, 96, 97, 89, 69, 88, 79, 86,
-  79, 78, 92, 93, 88, 68, 80, 91, 98, 91,
-  97, 72, 62, 82, 87, 88, 57, 79, 93, 99,
-  79, 101, 98, 63, 70, 70, 90, 89, 74, 68,
-  97, 71, 63, 86, 73, 66, 79, 65, 82, 70,
-  87, 81, 83, 78, 108, 85, 79, 68, 88, 80,
-  75, 123, 69, 77, 91, 81, 75, 85, 67, 87,
-  78, 80, 84, 66, 78, 94, 77, 88, 90, 83,
-  70, 86, 85, 85, 92, 94, 98, 80, 93, 76,
-  65, 92, 102, 74, 92, 74, 79, 76, 69, 85,
-  68, 81, 69, 68, 86, 89, 93, 78, 86, 81,
-  89, 66, 81, 72, 84, 92, 68, 86, 79, 66,
-  80, 95, 71, 73, 85, 81, 89, 85, 80, 84,
-  84, 86, 91, 84, 70, 90, 78, 80, 81, 90,
-  67, 89, 82, 81, 86, 84, 93, 84, 77, 83,
-  94, 78, 79, 66, 74, 76, 95, 75, 94, 73,
-  80, 104, 82, 85, 88, 77, 98, 79, 71, 78,
-  80, 92, 80, 79, 78, 97, 68, 85, 82, 94,
-  95, 63, 83, 83, 72, 68, 86, 88, 84, 83,
-  80, 97, 75, 73, 92, 63, 78, 78, 101, 84,
-  95, 91, 80, 85, 88, 83, 79, 91, 107, 68,
-  73, 74, 87, 81, 66, 75, 88, 92, 104, 63,
-  102, 70, 93, 89, 94, 80, 74, 102, 88, 81,
-  82, 82, 77, 77, 106, 108, 81, 75, 90, 89,
-  91, 88, 77, 87, 74, 85, 85, 101, 79, 85,
-  80, 76, 86, 81, 89, 85, 81, 90, 78, 95,
-  79, 88, 73, 98, 77, 90, 85, 85, 73, 85,
-  83, 82, 78, 89, 98, 84, 71, 73, 88, 72,
-  82, 67, 71, 76, 102, 65, 79, 71, 75, 96,
-  76, 88, 99, 72, 103, 77, 74, 82, 78, 97,
-  84, 82, 86, 100, 71, 74, 83, 94, 92, 59,
-  84, 83, 83, 65, 78, 87, 77, 84, 89, 95,
-  81, 76, 95, 72, 81, 71, 113, 82, 97, 99,
-  83, 83, 83, 78, 84, 91, 116, 69, 81, 78,
-  85, 73, 75, 76, 85, 90, 88, 60, 104, 83,
-  96, 89, 96, 82, 75, 103, 86, 85, 91, 85,
-  80, 79, 106, 104, 75, 72, 81, 89, 88, 86,
-  76, 91, 79, 81, 77, 101, 79, 80, 81, 75,
-  89, 82, 86, 88, 84, 88, 84, 89, 84, 92,
-  70, 90, 75, 82, 84, 85, 83, 83, 78, 80,
-  78, 83, 96, 85, 74, 68, 100, 72, 80, 74,
-  76, 78, 102, 70, 79, 75, 74, 107, 72, 84,
-  88, 78, 100, 88, 78, 75, 79, 92, 82, 79,
-  83, 89, 71, 77, 91, 89, 89, 67, 85, 81,
-  72, 75, 75, 80, 85, 75, 84, 91, 82, 75,
-  95, 67, 80, 74, 117, 87, 91, 95, 83, 83,
-  86, 73, 90, 85, 110, 74, 75, 81, 86, 76,
-  78, 78, 86, 87, 85, 71, 97, 101, 95, 88,
-  93, 82, 71, 101, 89, 84, 96, 85, 80, 77,
-  99, 98, 63, 78, 86, 83, 87, 89, 75, 90,
-  78, 85, 81, 99, 68, 89, 88, 88, 89, 74,
-  80, 95, 111, 95, 79, 82, 97, 74, 66, 113,
-  89, 85, 75, 84, 90, 83, 101, 86, 80, 85,
-  82, 87, 91, 81, 61, 92, 101, 75, 65, 93,
-  86, 99, 89, 76, 84, 72, 93, 80, 75, 98,
-  72, 83, 92, 79, 81, 87, 90, 109, 99, 84,
-  95, 70, 87, 82, 87, 77, 84, 85, 82, 87,
-  80, 80, 106, 85, 87, 81, 101, 76, 81, 87,
-  87, 84, 82, 76, 87, 70, 99, 80, 78, 83,
-  90, 75, 72, 73, 102, 80, 83, 82, 96, 83,
-  90, 70, 87, 101, 77, 92, 96, 93, 84, 105,
-  77, 84, 70, 62, 76, 77, 93, 84, 82, 95,
-  91, 82, 72, 80, 76, 74, 95, 85, 90, 81,
-  87, 95, 64, 87, 83, 93, 99, 72, 76, 92,
-  120, 93, 82, 85, 104, 78, 72, 106, 91, 90,
-  77, 84, 101, 86, 86, 82, 82, 75, 89, 88,
-  97, 78, 57, 102, 105, 79, 63, 90, 81, 106,
-  81, 63, 73, 65, 88, 79, 65, 105, 72, 82,
-  90, 75, 84, 87, 90, 113, 87, 71, 105, 65,
-  83, 84, 88, 84, 80, 90, 67, 86, 85, 81,
-  115, 79, 81, 71, 112, 74, 72, 77, 81, 82,
-  82, 68, 87, 67, 96, 82, 80, 84, 83, 80,
-  65, 69, 99, 70, 72, 91, 98, 76, 92, 66,
-  90, 103, 67, 84, 90, 90, 75, 108, 70, 87,
-  76, 56, 73, 71, 92, 86, 91, 91, 90, 88,
-  72, 80, 80, 69, 101, 81, 84, 79, 86, 99,
-  78, 77, 88, 86, 81, 91, 80, 91, 107, 91,
-  81, 76, 97, 85, 76, 116, 87, 90, 82, 82,
-  101, 80, 73, 85, 79, 90, 87, 79, 77, 74,
-  64, 101, 107, 78, 73, 86, 88, 100, 73, 77,
-  79, 74, 82, 75, 72, 96, 71, 76, 92, 83,
-  79, 91, 91, 107, 99, 61, 101, 79, 75, 84,
-  82, 82, 87, 84, 84, 86, 91, 81, 106, 90,
-  75, 76, 104, 82, 70, 83, 79, 78, 78, 79,
-  94, 71, 93, 91, 81, 86, 78, 73, 78, 69,
-  94, 76, 78, 86, 93, 76, 88, 73, 77, 89,
-  69, 82, 92, 87, 86, 101, 74, 82, 72, 69,
-  79, 71, 95, 85, 88, 90, 96, 82, 75, 80,
-  85, 75, 107, 86, 91, 80, 94, 104, 67, 85,
-  96, 78, 94, 81, 89, 82, 77, 91, 84, 71,
-  78, 87, 67, 82, 73, 76, 77, 82, 76, 85,
-  77, 92, 82, 82, 77, 83, 95, 91, 81, 83,
-  72, 85, 82, 79, 76, 78, 87, 71, 86, 72,
-  73, 85, 79, 67, 92, 66, 81, 76, 85, 84,
-  89, 75, 86, 91, 77, 82, 93, 86, 90, 74,
-  75, 82, 79, 80, 79, 71, 96, 90, 78, 87,
-  86, 82, 90, 72, 90, 93, 100, 74, 84, 92,
-  94, 79, 80, 86, 95, 94, 84, 75, 96, 70,
-  93, 80, 85, 90, 81, 81, 92, 75, 82, 87,
-  94, 98, 65, 105, 83, 84, 76, 81, 69, 89,
-  71, 75, 88, 96, 84, 82, 83, 66, 81, 96,
-  77, 83, 84, 75, 73, 79, 63, 88, 76, 81,
-  101, 72, 93, 84, 77, 84, 92, 77, 76, 91,
-  68, 71, 71, 74, 69, 88, 77, 83, 83, 88,
-  84, 80, 80, 78, 100, 91, 83, 83, 67, 86,
-  81, 80, 80, 69, 92, 62, 87, 69, 75, 93,
-  69, 68, 92, 80, 80, 73, 98, 88, 85, 72,
-  78, 93, 76, 73, 104, 88, 92, 67, 75, 79,
-  69, 79, 76, 73, 97, 84, 89, 88, 81, 75,
-  97, 67, 89, 80, 109, 66, 79, 99, 90, 71,
-  85, 90, 85, 97, 82, 73, 87, 69, 93, 80,
-  81, 92, 81, 77, 94, 68, 74, 96, 86, 98,
-  53, 102, 81, 87, 74, 81, 67, 86, 64, 87,
-  96, 101, 74, 87, 73, 65, 78, 97, 73, 79,
-  79, 77, 63, 78, 70, 80, 76, 87, 88, 78,
-  85, 86, 86, 91, 85, 72, 77, 88, 69, 87,
-  72, 79, 79, 84, 83, 78, 89, 92, 81, 80,
-  82, 87, 92, 86, 78, 84, 86, 84, 79, 87,
-  82, 84, 76, 72, 79, 73, 76, 83, 77, 82,
-  88, 103, 85, 76, 85, 85, 87, 84, 89, 79,
-  83, 74, 87, 83, 86, 70, 81, 72, 76, 76,
-  69, 76, 106, 86, 90, 86, 93, 80, 93, 77,
-  85, 75, 91, 77, 86, 88, 96, 78, 76, 84,
-  70, 91, 83, 73, 95, 67, 88, 79, 95, 84,
-  86, 85, 87, 80, 76, 97, 98, 95, 66, 108,
-  79, 84, 76, 76, 72, 81, 80, 90, 84, 94,
-  84, 88, 77, 67, 86, 89, 86, 85, 84, 74,
-  71, 88, 95, 91, 83, 82, 80, 89, 87, 84,
-  67, 93, 76, 76, 90, 89, 74, 70, 80, 80,
-  76, 76, 80, 96, 83, 84, 79, 93, 80, 87,
-  84, 86, 97, 85, 79, 93, 93, 85, 84, 77,
-  72, 87, 84, 83, 81, 86, 98, 78, 76, 74,
-  84, 79, 89, 87, 97, 74, 87, 83, 83, 98,
-  81, 84, 82, 79, 87, 91, 79, 85, 86, 76,
-  69, 80, 89, 87, 91, 89, 90, 75, 86, 100,
-  76, 86, 84, 91, 85, 76, 84, 82, 94, 80,
-  88, 73, 90, 78, 102, 88, 76, 84, 82, 99,
-  83, 71, 89, 89, 92, 101, 85, 84, 86, 91,
-  90, 94, 76, 88, 79, 80, 86, 84, 82, 86,
-  90, 71, 89, 98, 85, 89, 75, 75, 79, 73,
-  98, 93, 77, 76, 88, 86, 89, 81, 70, 91,
-  78, 79, 96, 80, 77, 67, 82, 81, 73, 76,
-  78, 98, 92, 85, 90, 96, 76, 86, 85, 93,
-  94, 86, 73, 92, 85, 79, 82, 69, 88, 90,
-  91, 83, 78, 95, 96, 80, 81, 77, 82, 83,
-  94, 90, 94, 71, 89, 84, 82, 98, 84, 86,
-  82, 76, 87, 88, 68, 89, 90, 73, 71, 79,
-  83, 89, 89, 87, 91, 70, 91, 89, 72, 87,
-  81, 92, 88, 77, 90, 87, 87, 83, 84, 66,
-  82, 73, 99, 92, 72, 95, 80, 97, 78, 67,
-  86, 95, 89, 103, 88, 79, 87, 94, 93, 102,
-  79, 90, 73, 84, 88, 83, 88, 86, 85, 66,
-  89, 102, 84, 86, 75, 72, 78, 78, 90, 85,
-  84, 88, 80, 80, 84, 88, 71, 91, 79, 76,
-  88, 71, 70, 70, 74, 81, 75, 74, 84, 92,
-  102, 84, 88, 98, 79, 89, 84, 95, 92, 84,
-  80, 89, 78, 84, 83, 73, 88, 87, 83, 82,
-  83, 82, 96, 81, 79, 97, 88, 78, 88, 88,
-  91, 79, 88, 85, 88, 88, 87, 84, 80, 80,
-  92, 83, 72, 87, 83, 78, 78, 79, 88, 88,
-  92, 89, 88, 78, 86, 82, 72, 88, 85, 90,
-  89, 89, 83, 83, 80, 82, 87, 71, 88, 76,
-  105, 85, 81, 86, 83, 94, 86, 75, 85, 92,
-  93, 98, 82, 87, 83, 92, 86, 92, 82, 84,
-  79, 90, 89, 87, 99, 91, 89, 71, 92, 97,
-  88, 89, 79, 77, 74, 77, 78, 73, 84, 86,
-  86, 76, 91, 77, 74, 84, 79, 93, 82, 83,
-  75, 85, 79, 88, 82, 102, 79, 81, 95, 87,
-  83, 72, 101, 80, 96, 73, 81, 66, 87, 90,
-  107, 92, 73, 82, 83, 86, 72, 96, 100, 86,
-  75, 91, 86, 80, 72, 80, 140, 74, 87, 73,
-  86, 88, 74, 84, 90, 89, 69, 90, 85, 82,
-  76, 73, 81, 68, 63, 84, 76, 86, 87, 78,
-  79, 95, 89, 111, 76, 108, 93, 52, 96, 92,
-  92, 76, 87, 82, 78, 91, 87, 77, 84, 81,
-  87, 71, 81, 87, 78, 86, 85, 90, 92, 85,
-  85, 74, 82, 90, 96, 79, 85, 80, 69, 99,
-  96, 84, 87, 91, 96, 89, 80, 93, 82, 75,
-  80, 99, 85, 82, 92, 84, 74, 88, 101, 75,
-  96, 69, 80, 83, 79, 89, 81, 94, 74, 79,
-  86, 75, 74, 108, 92, 76, 79, 88, 79, 66,
-  82, 80, 100, 84, 83, 85, 80, 85, 84, 85,
-  62, 81, 97, 68, 70, 110, 87, 86, 85, 87,
-  85, 97, 75, 65, 160, 61, 84, 77, 75, 104,
-  64, 94, 82, 91, 73, 87, 95, 77, 66, 78,
-  76, 56, 62, 71, 74, 101, 75, 66, 82, 79,
-  102, 87, 67, 140, 92, 51, 83, 89, 89, 74,
-  83, 78, 77, 95, 80, 64, 77, 92, 81, 95,
-  76, 105, 90, 82, 81, 89, 96, 88, 84, 77,
-  91, 92, 92, 78, 87, 74, 66, 87, 98, 91,
-  82, 93, 98, 84, 90, 108, 57, 84, 77, 95,
-  94, 81, 75, 94, 81, 85, 83, 95, 87, 76,
-  79, 85, 83, 101, 80, 83, 73, 84, 83, 90,
-  79, 99, 95, 89, 78, 87, 77, 69, 96, 80,
-  91, 103, 77, 76, 86, 73, 82, 79, 76, 83,
-  88, 92, 77, 89, 76, 86, 87, 98, 89, 106,
-  72, 81, 127, 79, 85, 76, 88, 91, 78, 85,
-  86, 93, 70, 88, 86, 77, 69, 77, 83, 69,
-  60, 82, 88, 83, 90, 79, 89, 98, 93, 73,
-  74, 97, 96, 61, 88, 95, 90, 82, 97, 80,
-  72, 84, 86, 87, 80, 78, 83, 74, 78, 84,
-  83, 78, 80, 76, 91, 87, 84, 71, 82, 88,
-  91, 85, 85, 77, 75, 88, 81, 79, 86, 85,
-  91, 90, 95, 91, 88, 79, 77, 96, 83, 87,
-  74, 73, 79, 88, 78, 81, 88, 76, 69, 77,
-  81, 89, 74, 76, 69, 87, 80, 90, 82, 99,
-  79, 83, 89, 86, 90, 73, 95, 80, 80, 80,
-  79, 75, 88, 82, 79, 94, 73, 77, 85, 95,
-  66, 89, 92, 87, 74, 82, 89, 91, 81, 84,
-  124, 80, 85, 74, 94, 74, 75, 87, 87, 83,
-  71, 81, 84, 80, 72, 72, 89, 65, 77, 91,
-  82, 91, 84, 83, 80, 93, 80, 92, 68, 118,
-  95, 56, 95, 90, 90, 75, 81, 78, 67, 73,
-  85, 67, 85, 71, 78, 73, 91, 84, 76, 80,
-  75, 87, 89, 84, 76, 78, 74, 87, 81, 74,
-  86, 87, 72, 90, 81, 79, 72, 86, 87, 85,
-  73, 88, 87, 77, 87, 80, 76, 79, 78, 71,
-  72, 85, 83, 74, 96, 70, 77, 78, 81, 88,
-  75, 90, 77, 77, 92, 77, 77, 92, 90, 83,
-  79, 84, 85, 68, 75, 81, 79, 73, 83, 89,
-  78, 81, 78, 80, 66, 75, 94, 76, 69, 126,
-  89, 88, 80, 82, 86, 97, 82, 72, 146, 74,
-  89, 80, 87, 96, 63, 96, 85, 85, 69, 80,
-  86, 82, 63, 86, 79, 54, 84, 77, 74, 108,
-  73, 72, 85, 81, 89, 86, 59, 165, 97, 57,
-  86, 84, 90, 71, 75, 73, 71, 74, 76, 57,
-  85, 86, 75, 92, 86, 111, 87, 77, 70, 74,
-  94, 84, 64, 82, 80, 89, 69, 78, 90, 78,
-  71, 77, 83, 91, 71, 85, 92, 81, 79, 100,
-  68, 87, 85, 67, 83, 79, 72, 77, 73, 88,
-  74, 83, 87, 79, 74, 77, 84, 93, 76, 82,
-  70, 88, 80, 93, 82, 92, 90, 87, 85, 84,
-  84, 69, 93, 80, 76, 76, 75, 79, 90, 78,
-  83, 75, 69, 77, 78, 95, 71, 89, 81, 87,
-  78, 89, 90, 97, 83, 88, 114, 84, 84, 75,
-  92, 79, 78, 84, 84, 88, 72, 83, 83, 77,
-  73, 75, 88, 74, 82, 91, 83, 88, 81, 83,
-  86, 99, 83, 85, 73, 105, 96, 59, 95, 83,
-  92, 80, 92, 83, 65, 74, 85, 83, 81, 71,
-  88, 73, 87, 85, 78, 77, 72, 77, 88, 84,
-  77, 73, 70, 89, 81, 81, 86, 82, 76, 80,
-  73, 81, 86, 82, 83, 92, 88, 87, 93, 79,
-  86, 82, 77, 86, 72, 71, 80, 94, 84, 89,
-  94, 82, 78, 74, 88, 84, 84, 85, 76, 92,
-  81, 91, 83, 104, 83, 89, 88, 88, 91, 71,
-  84, 82, 97, 76, 86, 76, 84, 92, 97, 102,
-  74, 91, 94, 87, 74, 89, 94, 85, 73, 84,
-  87, 86, 81, 77, 135, 78, 80, 79, 83, 83,
-  74, 95, 93, 95, 70, 80, 81, 78, 74, 73,
-  100, 69, 73, 82, 90, 86, 87, 83, 74, 92,
-  89, 116, 73, 115, 87, 61, 95, 93, 87, 97,
-  91, 85, 79, 78, 81, 79, 88, 83, 88, 76,
-  86, 85, 82, 76, 86, 76, 80, 87, 75, 77,
-  83, 88, 73, 78, 86, 81, 69, 91, 89, 90,
-  78, 89, 90, 79, 78, 92, 83, 77, 79, 85,
-  77, 87, 73, 83, 86, 96, 89, 78, 100, 75,
-  85, 79, 92, 82, 81, 96, 82, 82, 100, 76,
-  78, 102, 93, 74, 80, 84, 84, 69, 69, 80,
-  102, 89, 96, 91, 83, 93, 93, 88, 81, 101,
-  105, 68, 79, 117, 95, 84, 81, 78, 86, 101,
-  82, 65, 152, 67, 83, 83, 75, 98, 62, 104,
-  86, 102, 70, 73, 88, 74, 67, 82, 89, 57,
-  78, 71, 75, 90, 78, 70, 76, 76, 104, 88,
-  66, 149, 90, 61, 84, 90, 84, 102, 80, 78,
-  83, 81, 72, 77, 84, 101, 87, 95, 83, 105,
-  91, 78, 89, 79, 87, 89, 65, 71, 84, 91,
-  63, 78, 97, 74, 65, 80, 89, 92, 65, 91,
-  96, 71, 81, 101, 65, 81, 70, 77, 84, 90,
-  69, 92, 88, 93, 80, 93, 90, 81, 79, 74,
-  86, 88, 76, 90, 75, 89, 82, 96, 84, 97,
-  91, 88, 90, 86, 82, 69, 86, 79, 92, 81,
-  85, 83, 91, 90, 88, 84, 73, 91, 83, 87,
-  75, 94, 84, 84, 72, 88, 91, 117, 88, 80,
-  120, 80, 82, 81, 86, 85, 76, 90, 89, 94,
-  72, 81, 80, 74, 77, 72, 88, 78, 74, 85,
-  84, 85, 82, 83, 79, 98, 84, 78, 77, 106,
-  89, 65, 96, 85, 87, 97, 96, 84, 79, 77,
-  83, 94, 86, 80, 97, 70, 85, 84, 83, 75,
-  84, 99, 80, 88, 75, 74, 78, 87, 73, 82,
-  91, 78, 72, 84, 79, 84, 86, 84, 82, 82,
-  85, 86, 90, 77, 78, 86, 75, 88, 71, 80,
-  81, 77, 89, 73, 72, 73, 98, 79, 91, 90,
-  78, 101, 70, 72, 86, 74, 97, 78, 94, 92,
-  76, 83, 88, 94, 89, 86, 94, 72, 98, 81,
-  92, 79, 83, 78, 81, 77, 83, 70, 82, 84,
-  86, 85, 72, 84, 73, 76, 73, 78, 83, 94,
-  84, 122, 89, 76, 96, 77, 89, 80, 76, 84,
-  99, 78, 73, 91, 81, 92, 106, 89, 77, 81,
-  77, 97, 85, 79, 88, 116, 83, 86, 83, 74,
-  85, 91, 87, 73, 84, 80, 88, 93, 80, 79,
-  73, 78, 100, 106, 66, 76, 85, 80, 91, 85,
-  66, 74, 80, 75, 83, 91, 79, 75, 85, 95,
-  98, 90, 77, 76, 102, 76, 94, 94, 82, 90,
-  73, 70, 84, 78, 94, 74, 70, 84, 78, 74,
-  81, 79, 64, 68, 93, 78, 100, 88, 65, 96,
-  69, 75, 91, 84, 125, 65, 84, 78, 74, 80,
-  88, 91, 87, 86, 89, 84, 106, 86, 105, 80,
-  81, 85, 82, 69, 94, 63, 88, 85, 86, 75,
-  76, 85, 71, 89, 59, 77, 78, 76, 85, 136,
-  82, 79, 104, 69, 89, 88, 89, 87, 108, 85,
-  67, 85, 81, 108, 105, 91, 76, 82, 82, 98,
-  82, 83, 96, 87, 79, 95, 86, 74, 97, 90,
-  89, 72, 79, 83, 83, 96, 82, 83, 67, 77,
-  105, 107, 70, 74, 71, 83, 91, 96, 68, 79,
-  76, 80, 100, 82, 68, 69, 81, 98, 92, 86,
-  69, 81, 94, 76, 97, 94, 92, 84, 72, 68,
-  79, 78, 97, 78, 72, 88, 83, 83, 84, 83,
-  72, 77, 95, 78, 97, 84, 77, 79, 71, 78,
-  91, 77, 104, 73, 87, 86, 73, 80, 84, 92,
-  85, 92, 90, 89, 98, 92, 96, 82, 67, 103,
-  83, 73, 103, 69, 85, 81, 93, 85, 78, 78,
-  73, 93, 74, 75, 87, 85, 82, 117, 87, 85,
-  92, 81, 86, 79, 84, 83, 98, 80, 73, 89,
-  73, 91, 101, 91, 90, 83, 77, 99, 85, 82,
-  87, 72, 80, 85, 87, 77, 82, 91, 86, 74,
-  83, 73, 87, 90, 81, 76, 72, 78, 89, 102,
-  72, 73, 80, 80, 94, 92, 71, 74, 78, 82,
-  88, 85, 68, 74, 76, 89, 90, 81, 72, 69,
-  78, 76, 92, 87, 90, 92, 80, 70, 87, 83,
-  95, 73, 75, 74, 75, 77, 84, 74, 79, 79,
-  87, 82, 75, 92, 80, 74, 82, 70, 88, 90,
-  86, 79, 84, 88, 71, 83, 91, 87, 79, 80,
-  96, 76, 94, 75, 104, 84, 94, 77, 89, 75,
-  89, 85, 93, 82, 84, 83, 78, 83, 77, 79,
-  86, 73, 81, 84, 86, 114, 85, 86, 93, 73,
-  81, 94, 72, 80, 91, 83, 73, 78, 74, 108,
-  100, 85, 86, 91, 71, 94, 101, 77, 84, 95,
-  86, 83, 80, 71, 74, 88, 93, 73, 88, 79,
-  83, 89, 76, 81, 74, 77, 94, 93, 72, 83,
-  106, 77, 87, 76, 76, 85, 85, 77, 82, 93,
-  76, 79, 75, 110, 113, 94, 72, 74, 94, 79,
-  86, 79, 81, 97, 75, 83, 78, 79, 87, 61,
-  69, 81, 85, 75, 79, 77, 76, 79, 77, 79,
-  76, 94, 66, 85, 82, 66, 94, 99, 106, 70,
-  77, 75, 73, 81, 97, 81, 78, 76, 82, 94,
-  105, 74, 102, 76, 100, 89, 89, 71, 85, 76,
-  95, 79, 80, 77, 77, 76, 82, 75, 75, 61,
-  81, 78, 86, 126, 81, 75, 100, 64, 82, 107,
-  76, 83, 102, 88, 66, 73, 72, 126, 114, 79,
-  73, 91, 71, 91, 110, 72, 90, 81, 80, 89,
-  82, 71, 85, 82, 95, 75, 81, 75, 81, 92,
-  69, 80, 70, 80, 102, 91, 74, 85, 85, 77,
-  75, 85, 81, 91, 74, 80, 91, 87, 65, 74,
-  72, 121, 124, 84, 66, 77, 81, 78, 89, 76,
-  79, 86, 61, 88, 74, 81, 80, 61, 71, 91,
-  104, 83, 82, 78, 77, 77, 83, 83, 83, 89,
-  76, 95, 81, 72, 90, 87, 95, 73, 86, 86,
-  75, 85, 93, 82, 77, 84, 93, 96, 98, 80,
-  105, 79, 79, 103, 87, 71, 86, 81, 94, 82,
-  84, 80, 80, 83, 85, 80, 82, 69, 84, 83,
-  84, 112, 87, 71, 88, 74, 81, 90, 80, 81,
-  91, 86, 69, 83, 77, 104, 101, 85, 75, 93,
-  70, 93, 109, 80, 86, 77, 78, 85, 82, 68,
-  79, 87, 87, 80, 83, 75, 83, 93, 77, 82,
-  77, 77, 92, 89, 75, 82, 77, 80, 90, 90,
-  79, 83, 84, 83, 88, 89, 74, 79, 76, 111,
-  108, 79, 78, 74, 77, 78, 91, 76, 79, 95,
-  72, 80, 78, 85, 82, 66, 81, 75, 75, 73,
-  83, 86, 84, 79, 85, 79, 74, 87, 88, 75,
-  89, 86, 79, 90, 70, 76, 80, 77, 72, 92,
-  92, 73, 77, 83, 77, 77, 82, 80, 93, 90,
-  100, 74, 98, 83, 87, 97, 94, 73, 87, 80,
-  75, 85, 84, 81, 82, 78, 82, 80, 85, 95,
-  89, 83, 87, 81, 93, 82, 74, 75, 93, 86,
-  88, 79, 71, 78, 95, 78, 93, 85, 74, 84,
-  97, 75, 81, 90, 82, 80, 78, 85, 69, 84,
-  86, 78, 80, 79, 94, 79, 77, 87, 77, 74,
-  90, 88, 75, 81, 105, 83, 85, 75, 82, 86,
-  99, 78, 79, 88, 77, 91, 80, 90, 101, 86,
-  90, 79, 80, 78, 84, 96, 78, 97, 85, 85,
-  77, 92, 89, 76, 75, 81, 88, 70, 80, 75,
-  84, 84, 83, 82, 72, 85, 71, 85, 87, 89,
-  83, 93, 72, 73, 78, 67, 73, 86, 96, 82,
-  77, 83, 73, 88, 88, 76, 88, 86, 102, 75,
-  97, 94, 85, 81, 100, 70, 80, 74, 71, 79,
-  90, 68, 87, 67, 84, 83, 82, 107, 84, 89,
-  96, 75, 96, 92, 69, 75, 103, 83, 82, 74,
-  74, 83, 102, 72, 78, 89, 68, 83, 106, 82,
-  81, 79, 80, 81, 79, 90, 65, 73, 92, 82,
-  73, 79, 89, 77, 74, 81, 79, 81, 94, 89,
-  77, 82, 92, 85, 82, 76, 83, 88, 96, 81,
-  85, 86, 72, 87, 77, 82, 116, 76, 89, 84,
-  77, 82, 86, 94, 74, 94, 80, 94, 77, 105,
-  89, 69, 77, 88, 105, 73, 81, 82, 85, 78,
-  82, 85, 78, 83, 82, 93, 86, 88, 78, 91,
-  74, 75, 88, 80, 83, 90, 96, 73, 74, 84,
-  76, 92, 87, 81, 93, 77, 92, 90, 97, 87,
-  76, 88, 95, 70, 79, 76, 76, 84, 87, 75,
-  83, 74, 82, 84, 84, 95, 87, 80, 83, 78,
-  91, 78, 74, 74, 91, 84, 87, 82, 74, 80,
-  90, 83, 67, 84, 73, 82, 108, 75, 82, 80,
-  80, 80, 78, 82, 67, 79, 87, 82, 78, 78,
-  88, 80, 76, 79, 77, 74, 86, 86, 76, 82,
-  82, 81, 86, 74, 84, 85, 95, 79, 78, 86,
-  76, 88, 81, 91, 101, 74, 85, 84, 81, 77,
-  86, 94, 80, 94, 83, 84, 81, 103, 88, 76,
-  80, 69, 101, 78, 67, 88, 85, 86, 81, 89,
-  75, 93, 87, 86, 86, 71, 88, 79, 76, 88,
-  79, 74, 86, 91, 75, 79, 83, 78, 92, 72,
-  87, 84, 81, 70, 88, 81, 93, 94, 66, 77,
-  76, 88, 80, 91, 89, 93, 84, 72, 102, 85,
-  95, 82, 86, 75, 86, 78, 69, 85, 88, 78,
-  84, 77, 79, 89, 96, 77, 86, 96, 74, 64,
-  76, 90, 76, 97, 80, 84, 86, 107, 88, 81,
-  83, 84, 85, 82, 82, 83, 88, 82, 91, 81,
-  86, 84, 94, 73, 85, 96, 69, 91, 76, 87,
-  87, 101, 83, 93, 85, 75, 86, 82, 70, 86,
-  93, 86, 87, 85, 94, 94, 84, 85, 93, 82,
-  93, 92, 68, 86, 87, 85, 87, 85, 78, 77,
-  81, 69, 65, 76, 86, 80, 77, 87, 73, 82,
-  76, 88, 85, 70, 71, 74, 57, 78, 84, 68,
-  72, 93, 67, 82, 86, 70, 97, 70, 95, 87,
-  74, 67, 69, 72, 86, 99, 80, 58, 91, 89,
-  88, 82, 90, 94, 81, 85, 111, 72, 99, 72,
-  80, 83, 81, 97, 60, 81, 95, 75, 87, 85,
-  87, 91, 82, 83, 108, 86, 64, 52, 84, 105,
-  71, 116, 75, 65, 86, 76, 97, 76, 86, 76,
-  76, 73, 73, 95, 85, 85, 99, 80, 74, 72,
-  101, 87, 61, 121, 68, 82, 92, 78, 79, 93,
-  79, 94, 92, 87, 87, 85, 75, 74, 92, 90,
-  84, 79, 104, 111, 80, 90, 89, 121, 83, 91,
-  67, 80, 76, 92, 75, 82, 77, 93, 73, 76,
-  63, 93, 87, 82, 81, 93, 79, 90, 95, 80,
-  85, 71, 78, 77, 73, 86, 74, 75, 90, 93,
-  74, 85, 86, 79, 88, 82, 78, 84, 78, 67,
-  78, 80, 93, 98, 92, 71, 90, 88, 84, 89,
-  99, 86, 83, 111, 105, 85, 96, 70, 84, 80,
-  87, 96, 68, 87, 88, 79, 87, 79, 86, 91,
-  88, 80, 95, 99, 66, 70, 87, 101, 77, 103,
-  80, 80, 85, 70, 87, 75, 84, 81, 79, 89,
-  79, 90, 90, 87, 88, 84, 83, 70, 95, 79,
-  78, 101, 73, 90, 93, 80, 89, 90, 84, 94,
-  84, 76, 93, 85, 75, 84, 81, 83, 86, 80,
-  89, 94, 83, 87, 90, 100, 78, 92, 67, 86,
-  86, 87, 80, 86, 80, 66, 108, 77, 84, 78,
-  79, 86, 88, 87, 83, 92, 97, 103, 84, 69,
-  85, 72, 81, 81, 96, 94, 80, 81, 66, 83,
-  73, 79, 93, 81, 76, 80, 86, 83, 79, 88,
-  82, 82, 76, 84, 84, 83, 77, 81, 95, 91,
-  69, 86, 88, 88, 75, 90, 82, 77, 84, 73,
-  69, 64, 82, 89, 77, 87, 81, 87, 81, 85,
-  81, 96, 70, 61, 78, 83, 88, 93, 87, 85,
-  75, 82, 79, 81, 81, 73, 85, 81, 84, 77,
-  86, 88, 77, 85, 86, 79, 93, 79, 87, 110,
-  79, 91, 72, 86, 87, 85, 85, 97, 78, 82,
-  86, 91, 74, 74, 97, 76, 86, 89, 87, 88,
-  90, 84, 91, 85, 81, 77, 78, 86, 87, 83,
-  85, 79, 78, 79, 78, 74, 108, 73, 70, 88,
-  85, 78, 85, 86, 82, 84, 80, 59, 76, 71,
-  73, 83, 97, 101, 72, 67, 65, 101, 77, 74,
-  97, 70, 72, 76, 88, 88, 72, 95, 72, 75,
-  90, 66, 91, 70, 93, 80, 126, 100, 57, 85,
-  83, 71, 71, 61, 80, 95, 76, 79, 71, 60,
-  70, 102, 81, 107, 91, 81, 72, 83, 94, 108,
-  56, 50, 79, 85, 98, 106, 78, 76, 59, 76,
-  76, 72, 89, 66, 83, 81, 79, 84, 82, 85,
-  65, 76, 93, 70, 72, 97, 84, 137, 81, 97,
-  70, 81, 79, 92, 82, 98, 78, 94, 102, 93,
-  91, 59, 91, 76, 87, 85, 83, 79, 95, 87,
-  75, 115, 72, 72, 79, 86, 86, 87, 77, 76,
-  79, 92, 80, 79, 85, 78, 77, 85, 91, 89,
-  86, 88, 103, 68, 83, 63, 77, 71, 84, 80,
-  76, 96, 76, 72, 71, 91, 77, 82, 93, 73,
-  72, 79, 86, 74, 86, 94, 74, 81, 109, 82,
-  92, 76, 96, 83, 102, 91, 67, 81, 85, 87,
-  75, 77, 80, 89, 86, 96, 72, 68, 77, 91,
-  78, 94, 87, 89, 80, 90, 83, 98, 62, 66,
-  95, 89, 91, 98, 81, 79, 74, 85, 76, 76,
-  83, 70, 86, 89, 83, 83, 86, 89, 76, 84,
-  86, 74, 88, 85, 82, 110, 84, 94, 86, 84,
-  87, 79, 84, 98, 77, 81, 98, 89, 79, 74,
-  76, 74, 87, 87, 74, 80, 85, 82, 86, 90,
-  81, 79, 79, 86, 85, 84, 84, 79, 94, 80,
-  98, 79, 83, 81, 76, 86, 82, 90, 74, 93,
-  109, 94, 82, 73, 83, 77, 87, 82, 81, 87,
-  98, 90, 75, 82, 77, 89, 78, 78, 77, 84,
-  80, 86, 76, 75, 87, 80, 83, 94, 72, 84,
-  63, 83, 83, 85, 87, 83, 76, 84, 82, 87,
-  82, 68, 83, 94, 71, 69, 78, 85, 82, 82,
-  90, 88, 88, 88, 88, 79, 79, 78, 90, 82,
-  88, 92, 96, 79, 79, 81, 83, 85, 86, 88,
-  78, 75, 92, 81, 86, 83, 90, 89, 69, 88,
-  86, 88, 84, 92, 81, 86, 88, 84, 81, 86,
-  85, 96, 79, 90, 87, 93, 83, 87, 79, 72,
-  87, 89, 92, 93, 94, 81, 94, 83, 79, 76,
-  80, 88, 91, 79, 87, 84, 86, 85, 98, 80,
-  107, 80, 67, 88, 87, 84, 77, 90, 101, 81,
-  81, 70, 81, 75, 96, 77, 78, 100, 84, 76,
-  83, 91, 79, 86, 81, 74, 77, 82, 82, 95,
-  79, 82, 91, 84, 87, 103, 82, 77, 72, 82,
-  98, 79, 81, 75, 67, 76, 86, 93, 82, 94,
-  72, 87, 66, 68, 82, 97, 91, 82, 100, 73,
-  82, 99, 87, 81, 75, 65, 89, 83, 92, 84,
-  83, 77, 67, 79, 78, 84, 96, 87, 87, 83,
-  93, 84, 86, 80, 88, 89, 72, 85, 68, 102,
-  90, 90, 85, 97, 90, 88, 78, 84, 85, 94,
-  70, 93, 96, 91, 88, 80, 74, 72, 87, 88,
-  100, 86, 87, 79, 88, 88, 73, 77, 89, 88,
-  90, 79, 93, 83, 91, 98, 99, 82, 87, 99,
-  74, 81, 80, 92, 74, 89, 103, 83, 83, 70,
-  82, 76, 94, 75, 64, 93, 83, 85, 84, 85,
-  79, 91, 72, 72, 81, 86, 79, 82, 79, 84,
-  90, 83, 90, 100, 83, 82, 75, 83, 82, 86,
-  89, 71, 71, 85, 82, 91, 82, 74, 84, 82,
-  67, 71, 79, 85, 88, 82, 91, 85, 86, 88,
-  83, 74, 78, 76, 89, 87, 87, 92, 89, 78,
-  77, 84, 83, 86, 90, 86, 83, 89, 88, 83,
-  91, 83, 91, 88, 71, 89, 84, 89, 79, 88,
-  79, 90, 95, 87, 79, 96, 82, 95, 76, 88,
-  90, 90, 79, 89, 76, 71, 82, 85, 92, 87,
-  89, 81, 96, 79, 83, 74, 76, 88, 90, 87,
-  90, 85, 84, 82, 87, 94, 77, 89, 85, 76,
-  89, 89, 77, 79, 82, 73, 70, 95, 73, 70,
-  87, 96, 78, 70, 85, 106, 63, 74, 81, 83,
-  90, 82, 81, 88, 73, 100, 98, 98, 76, 90,
-  74, 69, 87, 67, 82, 67, 86, 96, 84, 106,
-  98, 80, 83, 71, 76, 69, 73, 100, 79, 93,
-  75, 85, 84, 101, 88, 77, 77, 62, 64, 72,
-  92, 68, 111, 89, 95, 87, 83, 77, 89, 90,
-  99, 77, 85, 87, 84, 88, 78, 78, 94, 84,
-  85, 86, 80, 110, 101, 88, 73, 79, 90, 80,
-  90, 73, 75, 85, 89, 92, 87, 74, 76, 76,
-  77, 74, 84, 76, 62, 90, 77, 87, 92, 89,
-  79, 75, 68, 78, 80, 77, 78, 91, 76, 84,
-  97, 84, 68, 89, 84, 88, 80, 81, 93, 74,
-  83, 90, 101, 80, 88, 81, 92, 84, 80, 79,
-  91, 77, 88, 87, 76, 75, 73, 86, 87, 81,
-  88, 70, 87, 95, 92, 86, 71, 80, 83, 81,
-  83, 83, 66, 83, 94, 83, 75, 109, 73, 94,
-  85, 81, 87, 85, 75, 99, 66, 92, 76, 86,
-  78, 78, 79, 80, 69, 76, 68, 72, 87, 75,
-  94, 90, 81, 80, 96, 69, 84, 83, 85, 90,
-  81, 93, 95, 77, 92, 82, 89, 95, 89, 80,
-  77, 90, 85, 91, 67, 82, 93, 102, 114, 80,
-  75, 83, 81, 89, 88, 88, 82, 83, 85, 81,
-  80, 80, 81, 80, 75, 95, 89, 90, 88, 72,
-  77, 90, 92, 79, 80, 80, 85, 94, 99, 74,
-  71, 79, 77, 90, 81, 89, 78, 70, 86, 91,
-  93, 81, 93, 70, 105, 99, 84, 79, 93, 88,
-  82, 81, 74, 69, 78, 82, 68, 82, 94, 73,
-  99, 81, 104, 79, 89, 68, 75, 88, 84, 92,
-  78, 81, 93, 73, 75, 99, 71, 100, 80, 85,
-  95, 86, 88, 89, 79, 82, 78, 77, 83, 83,
-  80, 77, 77, 88, 85, 83, 77, 93, 81, 76,
-  84, 78, 89, 73, 75, 85, 79, 84, 81, 86,
-  92, 81, 88, 74, 80, 89, 88, 81, 88, 88,
-  85, 87, 80, 78, 90, 98, 105, 89, 80, 90,
-  82, 89, 82, 99, 86, 87, 70, 87, 73, 92,
-  96, 81, 78, 93, 87, 92, 83, 80, 81, 91,
-  74, 83, 85, 79, 88, 90, 76, 86, 82, 88,
-  83, 76, 79, 79, 88, 89, 79, 77, 85, 72,
-  71, 80, 71, 74, 94, 99, 71, 73, 73, 100,
-  78, 79, 85, 75, 113, 68, 77, 110, 70, 89,
-  81, 91, 90, 82, 79, 73, 87, 71, 118, 70,
-  85, 93, 79, 81, 101, 80, 86, 84, 76, 73,
-  76, 89, 95, 77, 86, 75, 97, 93, 91, 64,
-  58, 65, 74, 90, 73, 76, 101, 80, 109, 94,
-  78, 93, 92, 77, 102, 83, 82, 78, 83, 88,
-  67, 72, 88, 80, 77, 93, 82, 102, 94, 87,
-  90, 83, 95, 76, 61, 78, 77, 94, 98, 87,
-  80, 83, 83, 74, 77, 76, 86, 77, 69, 102,
-  73, 90, 79, 88, 77, 98, 72, 83, 72, 81,
-  81, 92, 75, 76, 83, 83, 67, 96, 82, 81,
-  77, 70, 95, 89, 77, 72, 100, 73, 74, 91,
-  70, 63, 73, 87, 68, 70, 73, 101, 75, 76,
-  80, 83, 107, 65, 72, 89, 69, 103, 89, 95,
-  73, 91, 78, 84, 86, 63, 83, 77, 77, 90,
-  81, 110, 88, 86, 80, 84, 88, 72, 68, 97,
-  71, 85, 84, 87, 88, 80, 76, 55, 62, 66,
-  72, 73, 99, 69, 120, 85, 92, 75, 93, 78,
-  85, 82, 103, 84, 81, 89, 89, 80, 85, 83,
-  94, 87, 83, 86, 67, 105, 85, 82, 72, 81,
-  87, 79, 95, 81, 78, 97, 90, 85, 85, 86,
-  81, 74, 73, 68, 75, 75, 62, 95, 71, 84,
-  80, 89, 76, 69, 78, 79, 79, 75, 85, 84,
-  71, 79, 97, 79, 77, 88, 85, 79, 80, 76,
-  90, 75, 87, 85, 114, 82, 86, 83, 98, 89,
-  85, 80, 75, 80, 81, 86, 85, 75, 80, 90,
-  77, 77, 98, 84, 92, 85, 94, 76, 87, 72,
-  80, 93, 84, 93, 79, 88, 85, 69, 90, 82,
-  69, 96, 76, 89, 98, 89, 75, 87, 75, 96,
-  74, 86, 83, 78, 70, 74, 63, 82, 84, 80,
-  90, 79, 68, 81, 79, 70, 90, 67, 78, 80,
-  84, 89, 87, 90, 102, 81, 100, 84, 81, 86,
-  90, 87, 76, 85, 83, 94, 69, 77, 85, 104,
-  99, 85, 82, 88, 87, 85, 82, 99, 91, 88,
-  73, 84, 75, 86, 81, 76, 81, 95, 84, 95,
-  93, 69, 77, 87, 82, 79, 89, 79, 90, 90,
-  90, 91, 88, 74, 93, 64, 97, 89, 77, 72,
-  73, 91, 86, 83, 80, 71, 78, 99, 105, 88,
-  68, 90, 88, 84, 91, 90, 84, 72, 99, 68,
-  86, 106, 96, 80, 82, 78, 81, 75, 87, 78,
-  79, 81, 147, 86, 106, 88, 76, 61, 93, 81,
-  88, 97, 82, 83, 98, 78, 103, 89, 77, 81,
-  88, 76, 98, 73, 62, 81, 75, 89, 75, 81,
-  90, 72, 102, 99, 76, 93, 80, 80, 87, 90,
-  91, 82, 83, 81, 73, 71, 83, 77, 83, 89,
-  96, 77, 91, 87, 91, 81, 92, 91, 57, 76,
-  74, 62, 84, 83, 77, 76, 91, 88, 87, 94,
-  106, 83, 83, 87, 66, 93, 85, 81, 81, 103,
-  74, 93, 80, 91, 90, 82, 85, 80, 73, 89,
-  71, 83, 79, 71, 92, 76, 85, 91, 76, 75,
-  80, 85, 70, 84, 69, 71, 85, 93, 63, 74,
-  84, 96, 80, 85, 80, 77, 107, 56, 73, 101,
-  66, 96, 95, 96, 87, 84, 68, 76, 94, 70,
-  117, 69, 73, 93, 72, 92, 104, 77, 80, 86,
-  83, 71, 78, 76, 95, 81, 89, 80, 100, 90,
-  90, 58, 60, 65, 74, 88, 97, 76, 109, 76,
-  113, 89, 87, 98, 90, 88, 99, 84, 80, 79,
-  75, 85, 66, 78, 84, 83, 79, 81, 83, 97,
-  98, 81, 87, 77, 93, 73, 72, 82, 80, 91,
-  95, 82, 88, 83, 76, 76, 78, 72, 79, 79,
-  66, 100, 68, 81, 85, 85, 72, 89, 77, 81,
-  72, 83, 84, 81, 76, 75, 86, 73, 74, 89,
-  71, 69, 87, 69, 86, 85, 81, 79, 114, 85,
-  69, 83, 85, 76, 84, 85, 64, 75, 89, 87,
-  87, 75, 84, 87, 79, 71, 76, 98, 75, 101,
-  96, 86, 95, 75, 70, 99, 99, 82, 102, 79,
-  66, 75, 81, 87, 96, 87, 73, 88, 92, 79,
-  80, 80, 85, 80, 86, 83, 93, 85, 91, 62,
-  79, 72, 78, 86, 111, 88, 86, 83, 95, 70,
-  87, 79, 84, 84, 99, 92, 82, 77, 88, 83,
-  85, 80, 92, 81, 80, 81, 78, 95, 94, 86,
-  67, 69, 88, 79, 88, 89, 82, 92, 92, 85,
-  83, 92, 81, 84, 72, 71, 74, 75, 67, 84,
-  81, 86, 93, 89, 83, 85, 83, 77, 81, 82,
-  96, 82, 77, 82, 68, 83, 79, 92, 77, 97,
-  81, 84, 68, 82, 72, 81, 93, 65, 70, 99,
-  74, 93, 81, 100, 86, 91, 89, 75, 74, 82,
-  84, 84, 98, 77, 76, 84, 84, 75, 77, 93,
-  92, 83, 91, 95, 77, 86, 95, 80, 103, 95,
-  80, 83, 85, 83, 80, 68, 76, 92, 85, 100,
-  86, 77, 82, 76, 83, 90, 83, 65, 88, 79,
-  86, 93, 86, 92, 89, 94, 93, 78, 87, 81,
-  84, 79, 90, 69, 79, 86, 80, 98, 82, 70,
-  99, 80, 84, 85, 83, 81, 78, 84, 102, 70,
-  88, 89, 90, 79, 94, 85, 85, 84, 92, 87,
-  88, 84, 84, 80, 78, 100, 87, 101, 76, 83,
-  74, 78, 84, 86, 89, 87, 72, 81, 87, 84,
-  78, 84, 67, 73, 84, 81, 80, 90, 81, 74,
-  76, 78, 67, 89, 86, 79, 68, 95, 76, 90,
-  70, 94, 92, 87, 88, 74, 68, 82, 91, 81,
-  104, 81, 72, 78, 78, 78, 77, 91, 81, 77,
-  72, 84, 75, 64, 91, 85, 116, 98, 73, 71,
-  79, 79, 71, 60, 80, 85, 88, 59, 91, 64,
-  85, 78, 80, 91, 90, 61, 91, 63, 79, 81,
-  88, 90, 82, 77, 103, 83, 83, 78, 73, 80,
-  93, 61, 81, 83, 78, 94, 74, 60, 100, 79,
-  76, 88, 81, 93, 74, 76, 113, 68, 81, 93,
-  77, 75, 88, 69, 81, 83, 85, 87, 74, 87,
-  84, 83, 86, 91, 75, 101, 85, 64, 82, 73,
-  71, 85, 96, 80, 71, 76, 90, 79, 77, 77,
-  82, 80, 92, 90, 75, 90, 85, 81, 74, 82,
-  83, 82, 92, 95, 76, 91, 74, 92, 88, 97,
-  92, 91, 91, 72, 76, 81, 83, 84, 87, 75,
-  93, 87, 80, 87, 78, 84, 90, 80, 77, 95,
-  79, 110, 88, 81, 83, 96, 87, 85, 84, 84,
-  76, 79, 78, 89, 91, 61, 76, 69, 81, 76,
-  85, 86, 82, 65, 83, 86, 85, 85, 94, 83,
-  86, 105, 83, 85, 90, 82, 89, 89, 96, 77,
-  78, 94, 84, 86, 84, 69, 98, 90, 96, 78,
-  79, 89, 79, 88, 99, 79, 95, 92, 85, 86,
-  87, 91, 95, 80, 93, 88, 87, 88, 88, 84,
-  96, 97, 89, 97, 101, 87, 88, 84, 86, 83,
-  94, 91, 80, 83, 88, 75, 84, 88, 98, 78,
-  75, 74, 84, 82, 73, 83, 85, 87, 99, 87,
-  80, 83, 76, 71, 84, 66, 72, 87, 81, 79,
-  85, 83, 81, 66, 94, 82, 84, 63, 103, 75,
-  78, 101, 98, 82, 88, 82, 72, 72, 79, 151,
-  79, 88, 92, 68, 95, 90, 75, 87, 98, 93,
-  84, 73, 75, 101, 90, 88, 73, 85, 78, 90,
-  81, 82, 69, 88, 85, 78, 96, 66, 77, 132,
-  69, 76, 83, 64, 98, 82, 51, 78, 97, 91,
-  81, 76, 85, 66, 80, 90, 102, 66, 77, 65,
-  74, 63, 79, 73, 80, 96, 87, 80, 83, 83,
-  101, 82, 83, 81, 83, 76, 71, 88, 80, 104,
-  80, 79, 121, 89, 62, 81, 89, 70, 79, 99,
-  86, 89, 94, 72, 79, 100, 103, 84, 77, 74,
-  81, 86, 79, 82, 100, 89, 101, 97, 97, 106,
-  82, 79, 100, 64, 68, 74, 84, 80, 71, 86,
-  83, 69, 96, 79, 94, 67, 113, 84, 83, 100,
-  82, 81, 97, 83, 110, 76, 73, 211, 92, 101,
-  95, 47, 98, 87, 79, 83, 100, 97, 94, 76,
-  75, 135, 84, 81, 81, 74, 72, 77, 87, 84,
-  46, 115, 86, 64, 89, 44, 68, 150, 58, 76,
-  79, 60, 97, 84, 28, 100, 105, 89, 84, 71,
-  93, 69, 68, 89, 114, 59, 77, 44, 80, 65,
-  61, 69, 80, 107, 98, 78, 70, 70, 112, 82,
-  74, 76, 77, 85, 80, 96, 86, 89, 83, 71,
-  124, 102, 63, 89, 98, 77, 70, 98, 101, 95,
-  107, 53, 86, 97, 75, 79, 84, 83, 85, 91,
-  70, 82, 83, 89, 92, 87, 67, 68, 77, 76,
-  81, 74, 78, 92, 73, 71, 78, 78, 74, 67,
-  92, 81, 72, 87, 85, 78, 79, 91, 80, 82,
-  84, 87, 65, 76, 87, 103, 79, 85, 88, 82,
-  92, 88, 73, 85, 95, 80, 85, 73, 79, 100,
-  84, 79, 76, 94, 88, 94, 80, 69, 77, 75,
-  85, 81, 93, 78, 72, 116, 80, 86, 88, 73,
-  91, 88, 61, 73, 91, 87, 85, 92, 75, 74,
-  83, 79, 86, 76, 78, 69, 72, 75, 86, 76,
-  77, 94, 89, 81, 86, 83, 93, 83, 79, 77,
-  86, 82, 65, 87, 74, 109, 80, 83, 93, 76,
-  88, 78, 77, 76, 78, 93, 77, 85, 92, 83,
-  78, 84, 71, 93, 88, 79, 85, 79, 80, 72,
-  90, 75, 78, 79, 82, 94, 73, 75, 82, 83,
-  84, 96, 90, 83, 94, 85, 84, 94, 87, 78,
-  101, 82, 74, 96, 79, 87, 80, 81, 89, 89,
-  79, 84, 93, 79, 87, 74, 80, 114, 77, 85,
-  98, 95, 86, 76, 83, 81, 81, 65, 80, 69,
-  76, 76, 83, 83, 84, 68, 90, 77, 86, 95,
-  89, 89, 78, 72, 92, 82, 86, 82, 80, 71,
-  97, 80, 80, 92, 88, 94, 76, 90, 104, 86,
-  86, 89, 101, 74, 85, 82, 91, 80, 84, 80,
-  75, 89, 93, 85, 75, 83, 94, 85, 93, 83,
-  59, 80, 89, 83, 82, 106, 81, 79, 85, 86,
-  83, 84, 83, 91, 81, 84, 92, 108, 72, 75,
-  50, 76, 77, 77, 85, 88, 76, 70, 94, 76,
-  75, 92, 60, 82, 76, 75, 84, 86, 77, 100,
-  89, 76, 98, 86, 75, 97, 89, 73, 103, 69,
-  55, 81, 71, 80, 75, 92, 79, 77, 68, 75,
-  95, 49, 89, 75, 83, 124, 69, 70, 91, 92,
-  75, 71, 82, 79, 81, 70, 81, 64, 71, 79,
-  87, 90, 80, 63, 100, 65, 88, 96, 88, 104,
-  82, 56, 102, 81, 87, 82, 65, 74, 96, 70,
-  83, 92, 74, 92, 66, 88, 106, 85, 72, 92,
-  98, 85, 84, 80, 102, 77, 78, 84, 70, 84,
-  93, 84, 67, 83, 98, 86, 91, 84, 50, 75,
-  74, 77, 77, 111, 68, 73, 107, 80, 70, 81,
-  91, 83, 74, 83, 86, 112, 71, 64, 76, 80,
-  74, 79, 80, 81, 84, 79, 90, 79, 81, 77,
-  92, 89, 73, 76, 80, 83, 84, 95, 82, 88,
-  82, 81, 79, 93, 86, 80, 87, 74, 80, 85,
-  82, 84, 93, 96, 89, 84, 87, 91, 95, 95,
-  89, 77, 77, 103, 77, 78, 92, 97, 84, 92,
-  84, 86, 78, 97, 86, 76, 79, 78, 84, 84,
-  81, 75, 76, 91, 82, 96, 88, 83, 81, 85,
-  90, 86, 82, 84, 85, 78, 91, 78, 82, 94,
-  88, 76, 83, 86, 98, 79, 85, 84, 91, 81,
-  80, 84, 85, 78, 83, 88, 91, 89, 84, 87,
-  82, 84, 96, 83, 87, 84, 67, 83, 80, 89,
-  82, 97, 75, 85, 95, 81, 86, 84, 93, 86,
-  90, 90, 94, 103, 81, 81, 82, 85, 78, 74,
-  75, 72, 76, 85, 90, 87, 81, 87, 110, 76,
-  69, 84, 79, 78, 90, 89, 72, 76, 74, 94,
-  89, 79, 92, 84, 89, 90, 81, 93, 78, 75,
-  84, 96, 88, 97, 75, 85, 98, 76, 92, 91,
-  92, 94, 73, 83, 72, 80, 85, 98, 80, 80,
-  87, 80, 79, 70, 100, 84, 98, 58, 73, 87,
-  63, 77, 68, 78, 69, 99, 118, 88, 83, 71,
-  81, 91, 83, 97, 87, 74, 83, 80, 91, 80,
-  85, 90, 86, 92, 70, 83, 76, 94, 83, 93,
-  92, 78, 87, 86, 93, 80, 97, 93, 88, 90,
-  80, 66, 72, 87, 67, 76, 83, 72, 80, 89,
-  71, 95, 74, 82, 90, 79, 71, 87, 76, 80,
-  98, 80, 84, 75, 77, 65, 80, 90, 85, 91,
-  76, 111, 92, 90, 85, 85, 56, 74, 70, 83,
-  78, 76, 88, 74, 86, 83, 77, 90, 82, 86,
-  85, 87, 91, 87, 72, 83, 77, 82, 67, 92,
-  56, 97, 55, 77, 80, 65, 68, 77, 86, 94,
-  74, 64, 89, 67, 97, 89, 79, 77, 81, 52,
-  111, 96, 88, 98, 80, 80, 90, 73, 70, 83,
-  69, 88, 75, 59, 111, 68, 110, 77, 77, 109,
-  71, 82, 71, 69, 82, 93, 78, 82, 76, 86,
-  92, 79, 82, 80, 97, 87, 74, 86, 113, 69,
-  79, 80, 59, 95, 67, 84, 88, 87, 85, 79,
-  81, 88, 68, 78, 83, 80, 98, 80, 86, 80,
-  91, 76, 86, 72, 85, 82, 91, 102, 87, 91,
-  77, 74, 94, 59, 95, 72, 100, 63, 98, 82,
-  86, 73, 75, 90, 76, 76, 89, 83, 80, 89,
-  85, 75, 89, 82, 90, 77, 90, 86, 85, 78,
-  72, 83, 87, 84, 89, 82, 74, 89, 81, 79,
-  86, 87, 79, 70, 84, 100, 81, 91, 83, 70,
-  103, 80, 73, 91, 69, 93, 68, 96, 100, 120,
-  86, 79, 75, 96, 84, 75, 91, 122, 102, 89,
-  93, 76, 83, 68, 93, 86, 89, 64, 81, 76,
-  86, 97, 91, 102, 92, 85, 107, 95, 78, 71,
-  104, 74, 78, 68, 83, 81, 77, 96, 64, 88,
-  85, 103, 87, 74, 76, 90, 96, 93, 104, 86,
-  79, 90, 90, 88, 87, 77, 106, 91, 81, 76,
-  91, 104, 91, 87, 84, 84, 84, 93, 85, 88,
-  84, 105, 65, 86, 80, 68, 85, 61, 90, 76,
-  82, 82, 123, 83, 88, 77, 87, 82, 88, 98,
-  76, 73, 73, 94, 88, 89, 87, 79, 98, 92,
-  101, 101, 80, 85, 102, 79, 98, 95, 91, 79,
-  98, 90, 100, 100, 87, 91, 88, 84, 65, 83,
-  81, 103, 85, 89, 84, 118, 67, 68, 96, 84,
-  102, 68, 79, 91, 66, 71, 86, 87, 71, 95,
-  72, 90, 67, 84, 87, 70, 90, 84, 83, 91,
-  91, 79, 95, 82, 94, 92, 85, 85, 80, 78,
-  75, 77, 91, 101, 66, 85, 93, 98, 130, 70,
-  90, 72, 90, 92, 79, 73, 69, 96, 78, 89,
-  85, 83, 70, 84, 78, 98, 58, 85, 86, 93,
-  84, 88, 78, 73, 90, 76, 89, 92, 83, 71,
-  57, 92, 72, 106, 57, 93, 85, 96, 71, 80,
-  74, 72, 68, 78, 84, 87, 83, 92, 78, 76,
-  77, 86, 79, 71, 98, 82, 112, 73, 60, 86,
-  80, 77, 90, 99, 96, 75, 64, 78, 88, 70,
-  69, 76, 87, 108, 79, 80, 73, 79, 78, 75,
-  82, 64, 97, 72, 89, 60, 86, 89, 98, 69,
-  81, 53, 61, 62, 56, 87, 77, 99, 149, 72,
-  90, 77, 87, 90, 75, 112, 84, 62, 84, 61,
-  78, 89, 74, 78, 90, 97, 47, 80, 79, 97,
-  69, 72, 116, 62, 80, 78, 76, 67, 86, 102,
-  98, 92, 86, 75, 75, 83, 65, 68, 73, 91,
-  77, 97, 68, 85, 73, 73, 73, 70, 73, 85,
-  73, 84, 83, 82, 72, 70, 79, 65, 86, 84,
-  100, 68, 83, 110, 83, 83, 84, 90, 71, 80,
-  79, 79, 77, 81, 101, 84, 98, 87, 72, 87,
-  82, 94, 84, 89, 70, 80, 81, 87, 82, 89,
-  66, 84, 71, 88, 63, 105, 79, 78, 61, 82,
-  83, 83, 79, 67, 98, 80, 88, 80, 73, 82,
-  71, 61, 112, 89, 90, 81, 74, 85, 98, 54,
-  59, 90, 86, 85, 82, 73, 49, 70, 107, 94,
-  76, 95, 71, 80, 55, 96, 86, 90, 86, 87,
-  89, 87, 89, 69, 91, 75, 98, 74, 82, 93,
-  86, 81, 78, 81, 70, 93, 66, 66, 86, 92,
-  91, 81, 96, 85, 77, 85, 88, 71, 95, 76,
-  88, 87, 62, 78, 85, 86, 95, 92, 86, 107,
-  86, 89, 78, 82, 83, 91, 63, 104, 87, 96,
-  95, 67, 86, 67, 87, 84, 89, 87, 85, 79,
-  85, 82, 78, 88, 79, 79, 80, 93, 73, 78,
-  80, 69, 81, 103, 101, 92, 88, 102, 91, 77,
-  83, 95, 75, 65, 91, 86, 90, 92, 76, 77,
-  79, 79, 74, 67, 85, 99, 91, 105, 77, 92,
-  69, 89, 84, 77, 95, 110, 88, 88, 85, 81,
-  104, 79, 81, 68, 70, 73, 81, 89, 72, 67,
-  86, 71, 72, 91, 102, 85, 86, 88, 83, 92,
-  89, 89, 88, 70, 88, 82, 99, 95, 70, 90,
-  99, 83, 110, 95, 72, 76, 86, 88, 84, 83,
-  72, 99, 81, 83, 75, 93, 69, 77, 104, 96,
-  68, 90, 81, 100, 90, 68, 79, 80, 84, 87,
-  86, 96, 83, 101, 67, 85, 78, 78, 81, 66,
-  87, 82, 72, 88, 114, 86, 71, 74, 86, 73,
-  80, 90, 76, 69, 87, 90, 89, 80, 91, 81,
-  98, 88, 101, 93, 73, 69, 98, 92, 97, 88,
-  103, 85, 98, 87, 89, 89, 69, 94, 92, 95,
-  71, 82, 74, 100, 86, 73, 86, 104, 59, 72,
-  83, 92, 95, 64, 81, 81, 71, 66, 78, 93,
-  88, 79, 98, 88, 67, 77, 97, 60, 80, 99,
-  90, 74, 91, 75, 94, 96, 90, 85, 72, 96,
-  79, 71, 68, 73, 85, 88, 63, 75, 89, 89,
-  135, 74, 90, 75, 94, 93, 96, 75, 81, 91,
-  97, 77, 82, 84, 57, 90, 81, 99, 72, 83,
-  92, 75, 72, 79, 81, 68, 88, 87, 81, 81,
-  74, 69, 67, 83, 91, 103, 72, 98, 73, 86,
-  78, 82, 59, 89, 63, 76, 79, 92, 82, 90,
-  99, 84, 78, 90, 81, 89, 89, 83, 77, 79,
-  80, 86, 83, 80, 67, 93, 94, 84, 66, 94,
-  81, 81, 54, 77, 86, 89, 86, 102, 91, 77,
-  78, 76, 76, 79, 89, 70, 100, 70, 79, 79,
-  86, 67, 96, 50, 60, 74, 73, 97, 78, 82,
-  99, 75, 91, 90, 79, 104, 71, 88, 70, 86,
-  88, 72, 71, 92, 84, 74, 94, 82, 69, 76,
-  93, 85, 82, 82, 106, 72, 83, 78, 78, 87,
-  82, 83, 92, 96, 94, 72, 84, 81, 90, 74,
-  78, 72, 72, 89, 83, 86, 82, 82, 88, 80,
-  96, 83, 88, 92, 75, 87, 78, 76, 78, 78,
-  80, 81, 93, 80, 85, 92, 81, 93, 65, 89,
-  78, 82, 74, 104, 77, 91, 77, 95, 76, 82,
-  101, 81, 76, 72, 78, 79, 99, 92, 77, 82,
-  81, 87, 84, 80, 80, 88, 86, 86, 80, 77,
-  79, 88, 108, 83, 77, 76, 103, 70, 86, 77,
-  65, 85, 81, 79, 77, 92, 83, 82, 72, 77,
-  87, 84, 80, 80, 76, 74, 81, 80, 75, 67,
-  75, 87, 87, 75, 87, 73, 83, 85, 80, 74,
-  80, 98, 76, 75, 72, 78, 87, 88, 83, 87,
-  87, 85, 89, 66, 88, 77, 93, 84, 86, 86,
-  130, 96, 97, 77, 80, 90, 87, 81, 73, 95,
-  88, 78, 82, 74, 81, 74, 80, 75, 81, 90,
-  81, 123, 79, 70, 79, 82, 74, 75, 81, 82,
-  93, 84, 82, 92, 77, 100, 65, 87, 75, 84,
-  79, 104, 77, 90, 77, 99, 75, 78, 87, 85,
-  78, 72, 77, 82, 90, 94, 76, 87, 79, 83,
-  86, 81, 79, 86, 85, 82, 78, 81, 78, 86,
-  102, 77, 75, 74, 116, 65, 84, 77, 71, 81,
-  79, 80, 79, 86, 80, 78, 72, 83, 81, 77,
-  82, 82, 76, 75, 81, 81, 77, 67, 77, 79,
-  94, 75, 87, 79, 83, 91, 80, 73, 78, 83,
-  72, 73, 76, 79, 83, 93, 81, 88, 84, 86,
-  87, 69, 88, 74, 84, 85, 85, 78, 142, 96,
-  98, 77, 77, 92, 82, 73, 68, 90, 99, 74,
-  84, 73, 78, 74, 77, 73, 81, 86, 83, 129,
-  77, 69, 78, 77, 82, 72, 81, 81, 91, 93,
-  83, 91, 82, 91, 70, 92, 82, 90, 76, 98,
-  77, 90, 79, 101, 76, 82, 76, 82, 81, 74,
-  79, 75, 93, 92, 75, 87, 80, 80, 86, 81,
-  80, 84, 87, 80, 78, 79, 79, 89, 105, 81,
-  78, 73, 101, 72, 84, 80, 68, 83, 82, 77,
-  80, 89, 82, 81, 72, 82, 84, 85, 83, 82,
-  81, 78, 77, 82, 75, 70, 80, 83, 90, 75,
-  90, 85, 79, 85, 80, 77, 79, 79, 78, 74,
-  81, 83, 84, 88, 83, 97, 85, 89, 80, 67,
-  86, 77, 78, 83, 89, 81, 124, 94, 92, 81,
-  81, 89, 83, 81, 72, 94, 85, 67, 86, 81,
-  74, 73, 83, 75, 84, 90, 78, 124, 79, 75,
-  78, 83, 74, 81, 82, 88, 84, 85, 99, 95,
-  70, 95, 66, 86, 75, 84, 83, 111, 78, 85,
-  79, 96, 74, 80, 93, 88, 85, 74, 71, 79,
-  91, 90, 77, 77, 80, 95, 75, 79, 78, 93,
-  88, 93, 82, 75, 73, 86, 96, 78, 78, 79,
-  116, 70, 84, 75, 72, 78, 78, 73, 72, 93,
-  82, 78, 75, 73, 86, 91, 81, 76, 86, 78,
-  91, 78, 74, 65, 68, 72, 87, 76, 88, 77,
-  80, 79, 75, 78, 85, 92, 71, 71, 71, 79,
-  79, 84, 84, 82, 86, 84, 87, 72, 89, 71,
-  85, 84, 82, 82, 141, 96, 92, 78, 80, 89,
-  87, 78, 79, 88, 102, 81, 76, 77, 84, 76,
-  81, 80, 82, 86, 80, 136, 78, 78, 79, 76,
-  67, 81, 79, 99, 87, 79, 105, 96, 68, 104,
-  63, 82, 73, 84, 92, 117, 78, 75, 78, 97,
-  74, 79, 78, 97, 86, 79, 69, 89, 88, 81,
-  80, 78, 78, 95, 75, 81, 74, 96, 88, 95,
-  81, 78, 77, 81, 87, 75, 79, 81, 136, 62,
-  86, 76, 86, 77, 77, 76, 69, 85, 81, 74,
-  75, 75, 82, 81, 73, 76, 89, 78, 98, 72,
-  74, 67, 64, 67, 101, 71, 90, 80, 83, 85,
-  74, 78, 82, 70, 60, 71, 73, 81, 78, 90,
-  85, 81, 82, 88, 84, 74, 91, 64, 84, 82,
-  80, 73, 166, 98, 100, 73, 77, 89, 89, 70,
-  80, 83, 124, 76, 73, 77, 75, 76, 80, 79,
-  79, 84, 87, 150, 76, 79, 78, 75, 75, 76,
-  78, 88, 85, 91, 98, 94, 73, 92, 68, 89,
-  79, 88, 81, 106, 78, 81, 78, 103, 74, 78,
-  79, 88, 83, 76, 73, 78, 84, 80, 75, 79,
-  77, 85, 82, 85, 77, 87, 87, 86, 80, 75,
-  76, 88, 97, 82, 76, 81, 115, 70, 85, 79,
-  73, 78, 77, 74, 75, 89, 84, 78, 74, 75,
-  83, 90, 87, 76, 87, 84, 91, 78, 79, 65,
-  72, 73, 95, 75, 91, 89, 83, 81, 75, 81,
-  80, 73, 72, 70, 83, 84, 76, 85, 81, 93,
-  84, 88, 79, 73, 87, 72, 77, 81, 85, 81,
-  132, 93, 92, 78, 84, 86, 88, 79, 78, 86,
-  100, 72, 76, 84, 75, 75, 81, 80, 83, 88,
-  82, 134, 78, 83, 80, 79, 81, 73, 76, 80,
-  87, 88, 96, 101, 73, 86, 69, 86, 79, 84,
-  84, 99, 77, 77, 77, 92, 79, 82, 90, 83,
-  85, 85, 76, 71, 83, 83, 78, 84, 80, 98,
-  75, 81, 78, 94, 87, 90, 80, 85, 71, 87,
-  101, 77, 77, 76, 110, 72, 90, 79, 65, 78,
-  82, 80, 75, 95, 87, 76, 71, 70, 94, 92,
-  82, 80, 90, 74, 88, 79, 78, 74, 72, 74,
-  83, 80, 95, 90, 70, 80, 75, 78, 88, 87,
-  84, 68, 74, 83, 83, 80, 77, 80, 90, 87,
-  87, 73, 89, 77, 76, 89, 86, 83, 117, 95,
-  83, 87, 86, 90, 92, 87, 83, 80, 80, 73,
-  75, 78, 81, 78, 83, 81, 82, 85, 71, 132,
-  75, 81, 74, 81, 75, 77, 76, 83, 90, 80,
-  99, 98, 73, 85, 68, 83, 75, 83, 92, 102,
-  83, 72, 77, 89, 78, 80, 83, 86, 80, 89,
-  74, 73, 81, 81, 81, 84, 82, 100, 75, 80,
-  73, 101, 87, 89, 85, 88, 77, 86, 100, 77,
-  74, 84, 118, 67, 91, 80, 69, 75, 80, 78,
-  77, 90, 86, 76, 71, 76, 92, 85, 79, 79,
-  94, 76, 97, 78, 73, 70, 72, 77, 86, 81,
-  99, 85, 67, 83, 75, 79, 83, 75, 78, 70,
-  72, 86, 81, 83, 77, 85, 90, 93, 86, 79,
-  84, 76, 78, 88, 87, 79, 119, 97, 81, 84,
-  87, 89, 91, 86, 82, 78, 86, 74, 76, 80,
-  72, 79, 82, 79, 81, 87, 79, 136, 74, 85,
-  75, 80, 82, 76, 76, 80, 87, 90, 97, 99,
-  75, 87, 69, 88, 81, 84, 83, 98, 79, 76,
-  74, 97, 75, 82, 89, 81, 77, 84, 77, 74,
-  78, 79, 81, 85, 81, 88, 80, 84, 79, 96,
-  91, 82, 82, 87, 78, 88, 104, 83, 73, 91,
-  111, 71, 90, 85, 66, 77, 83, 72, 78, 91,
-  90, 77, 71, 72, 92, 91, 88, 80, 84, 79,
-  93, 81, 77, 71, 76, 76, 88, 80, 98, 85,
-  70, 82, 76, 80, 81, 77, 82, 68, 77, 87,
-  81, 81, 77, 87, 89, 91, 80, 74, 89, 77,
-  79, 86, 87, 79, 115, 92, 82, 86, 90, 87,
-  94, 87, 81, 79, 82, 78, 80, 84, 75, 77,
-  83, 82, 87, 87, 78, 128, 75, 84, 77, 82,
-  83, 72, 90, 88, 106, 91, 74, 63, 78, 90,
-  78, 72, 82, 96, 69, 82, 85, 100, 85, 80,
-  87, 91, 100, 96, 93, 78, 81, 87, 95, 90,
-  76, 86, 63, 77, 73, 93, 79, 77, 88, 82,
-  83, 80, 84, 73, 76, 92, 89, 96, 87, 66,
-  98, 80, 105, 73, 76, 83, 72, 75, 82, 86,
-  94, 86, 88, 81, 102, 72, 81, 91, 86, 111,
-  80, 83, 91, 85, 70, 73, 73, 75, 87, 93,
-  90, 86, 84, 82, 74, 74, 84, 99, 89, 83,
-  86, 74, 78, 71, 89, 78, 87, 74, 94, 87,
-  74, 72, 84, 84, 73, 77, 88, 101, 87, 56,
-  79, 89, 92, 77, 89, 91, 102, 87, 90, 97,
-  111, 74, 93, 90, 88, 84, 90, 77, 75, 98,
-  78, 90, 133, 82, 72, 59, 77, 87, 75, 74,
-  83, 107, 77, 80, 92, 85, 85, 71, 83, 73,
-  86, 112, 100, 71, 76, 89, 103, 78, 75, 85,
-  61, 75, 84, 71, 90, 70, 94, 86, 79, 76,
-  84, 84, 87, 95, 97, 78, 76, 52, 114, 80,
-  93, 77, 60, 84, 67, 72, 87, 81, 92, 76,
-  89, 82, 89, 69, 81, 82, 80, 102, 78, 76,
-  85, 77, 73, 67, 73, 75, 100, 105, 85, 105,
-  85, 86, 63, 66, 76, 100, 88, 101, 72, 79,
-  77, 69, 81, 75, 95, 77, 90, 100, 72, 86,
-  76, 84, 72, 71, 86, 104, 93, 55, 77, 85,
-  91, 76, 86, 80, 73, 90, 84, 104, 106, 65,
-  74, 94, 84, 78, 83, 83, 80, 101, 86, 85,
-  89, 95, 77, 71, 80, 89, 75, 78, 73, 80,
-  69, 86, 92, 95, 88, 77, 82, 90, 96, 88,
-  91, 82, 83, 82, 88, 68, 79, 88, 70, 83,
-  89, 96, 84, 80, 81, 84, 81, 85, 77, 71,
-  75, 84, 92, 80, 92, 77, 92, 77, 100, 68,
-  86, 84, 74, 80, 82, 83, 95, 94, 84, 78,
-  99, 72, 75, 94, 78, 91, 101, 89, 84, 88,
-  74, 79, 78, 87, 99, 86, 90, 84, 89, 105,
-  82, 70, 83, 95, 89, 87, 87, 90, 84, 70,
-  103, 74, 85, 79, 87, 80, 78, 92, 90, 85,
-  72, 76, 83, 103, 86, 70, 85, 91, 93, 84,
-  82, 85, 81, 87, 88, 93, 79, 81, 95, 87,
-  85, 77, 88, 84, 88, 75, 84, 91, 112, 94,
-  75, 67, 71, 88, 89, 80, 93, 104, 71, 82,
-  91, 92, 96, 74, 89, 84, 102, 96, 93, 80,
-  74, 87, 104, 86, 82, 84, 50, 76, 90, 93,
-  78, 67, 101, 87, 80, 72, 82, 83, 83, 90,
-  82, 105, 75, 61, 102, 76, 95, 67, 62, 93,
-  72, 73, 84, 84, 76, 95, 79, 83, 90, 67,
-  83, 85, 89, 81, 77, 76, 102, 89, 72, 71,
-  61, 75, 83, 90, 83, 116, 95, 72, 73, 79,
-  82, 97, 100, 80, 91, 88, 83, 71, 81, 79,
-  86, 71, 80, 94, 58, 82, 74, 83, 75, 73,
-  82, 94, 85, 60, 81, 93, 92, 75, 75, 74,
-  92, 93, 83, 85, 108, 72, 86, 99, 82, 81,
-  90, 70, 85, 98, 81, 87, 155, 79, 71, 59,
-  81, 76, 99, 79, 112, 122, 78, 77, 102, 69,
-  96, 63, 82, 64, 77, 115, 102, 70, 65, 82,
-  106, 85, 81, 83, 35, 67, 102, 67, 81, 67,
-  123, 99, 76, 72, 89, 96, 99, 96, 84, 81,
-  66, 29, 121, 77, 74, 80, 34, 88, 67, 64,
-  82, 75, 67, 85, 76, 94, 70, 69, 93, 67,
-  91, 67, 74, 67, 99, 72, 70, 60, 59, 79,
-  83, 123, 76, 147, 106, 83, 69, 87, 68, 90,
-  104, 92, 84, 78, 77, 76, 56, 80, 90, 70,
-  86, 118, 54, 71, 60, 85, 66, 64, 76, 90,
-  94, 45, 95, 88, 84, 70, 72, 69, 76, 101,
-  77, 89, 101, 56, 55, 101, 78, 69, 81, 75,
-  80, 107, 84, 90, 98, 99, 79, 69, 72, 88,
-  84, 82, 76, 89, 72, 83, 91, 87, 90, 76,
-  75, 85, 93, 86, 82, 80, 75, 85, 97, 77,
-  81, 88, 57, 72, 94, 90, 82, 73, 89, 86,
-  81, 74, 82, 82, 84, 83, 76, 77, 80, 74,
-  93, 71, 91, 68, 73, 83, 71, 78, 86, 83,
-  84, 95, 81, 75, 85, 68, 88, 86, 77, 75,
-  95, 80, 89, 89, 74, 70, 69, 94, 92, 83,
-  84, 110, 97, 102, 82, 82, 76, 94, 99, 80,
-  93, 84, 82, 70, 96, 77, 89, 79, 85, 85,
-  64, 79, 81, 86, 76, 73, 79, 100, 86, 72,
-  91, 94, 95, 84, 77, 75, 91, 91, 82, 89,
-  75, 76, 83, 89, 81, 79, 88, 81, 93, 75,
-  79, 93, 79, 91, 79, 68, 77, 97, 83, 89,
-  87, 92, 67, 91, 89, 98, 85, 81, 84, 89,
-  87, 80, 86, 79, 88, 91, 91, 76, 83, 86,
-  68, 81, 89, 93, 86, 76, 85, 95, 87, 71,
-  87, 77, 70, 79, 77, 93, 77, 83, 84, 83,
-  99, 61, 78, 93, 72, 84, 86, 80, 69, 96,
-  76, 86, 110, 73, 79, 100, 95, 89, 89, 86,
-  98, 97, 74, 75, 71, 82, 83, 68, 86, 84,
-  89, 69, 81, 84, 84, 88, 95, 78, 84, 114,
-  83, 70, 91, 69, 89, 73, 73, 79, 62, 91,
-  90, 86, 90, 94, 79, 92, 83, 69, 82, 81,
-  86, 78, 80, 94, 83, 91, 91, 80, 93, 82,
-  87, 95, 89, 82, 102, 78, 84, 88, 88, 95,
-  98, 78, 75, 63, 79, 93, 87, 92, 98, 99,
-  71, 88, 100, 87, 91, 68, 79, 72, 88, 87,
-  84, 71, 81, 86, 94, 87, 88, 83, 64, 78,
-  87, 76, 87, 84, 104, 101, 88, 61, 83, 86,
-  75, 80, 68, 80, 68, 62, 95, 82, 92, 65,
-  59, 86, 60, 75, 91, 76, 62, 88, 74, 86,
-  88, 63, 81, 84, 104, 93, 73, 71, 100, 93,
-  70, 67, 69, 74, 79, 79, 84, 104, 100, 92,
-  77, 95, 79, 86, 98, 81, 76, 112, 85, 67,
-  66, 67, 90, 77, 85, 90, 55, 82, 74, 87,
-  70, 98, 77, 87, 79, 66, 90, 67, 81, 76,
-  83, 99, 79, 102, 91, 77, 81, 71, 73, 95,
-  83, 74, 95, 73, 89, 97, 86, 93, 71, 91,
-  80, 68, 78, 97, 81, 87, 72, 79, 71, 93,
-  87, 92, 83, 75, 82, 89, 99, 78, 70, 79,
-  85, 87, 84, 94, 84, 92, 74, 79, 79, 97,
-  89, 79, 83, 93, 88, 66, 76, 74, 76, 77,
-  71, 85, 78, 91, 84, 78, 97, 65, 80, 77,
-  73, 85, 87, 88, 77, 87, 83, 81, 97, 74,
-  84, 101, 90, 93, 83, 88, 85, 99, 74, 80,
-  77, 79, 79, 65, 88, 81, 93, 114, 80, 84,
-  82, 83, 93, 84, 86, 97, 79, 69, 88, 70,
-  91, 78, 91, 75, 68, 80, 92, 89, 90, 86,
-  77, 90, 86, 74, 95, 78, 82, 84, 93, 90,
-  95, 87, 89, 81, 71, 86, 87, 87, 86, 85,
-  99, 86, 86, 67, 75, 96, 79, 91, 84, 82,
-  73, 82, 80, 72, 88, 80, 78, 84, 79, 81,
-  82, 77, 85, 91, 83, 87, 78, 85, 76, 85,
-  72, 90, 81, 81, 88, 86, 71, 84, 61, 69,
-  85, 82, 75, 71, 72, 83, 78, 85, 78, 90,
-  79, 87, 73, 86, 77, 79, 83, 69, 72, 82,
-  87, 81, 82, 90, 82, 75, 77, 74, 85, 92,
-  73, 64, 83, 74, 97, 87, 85, 83, 72, 77,
-  76, 73, 81, 67, 86, 95, 78, 89, 100, 75,
-  73, 83, 93, 78, 86, 79, 73, 81, 80, 80,
-  86, 76, 82, 81, 75, 80, 74, 80, 83, 83,
-  80, 81, 75, 80, 82, 81, 71, 85, 85, 82,
-  73, 86, 84, 79, 93, 80, 90, 77, 84, 83,
-  95, 82, 75, 97, 82, 67, 74, 94, 77, 86,
-  90, 77, 86, 90, 74, 84, 71, 88, 92, 96,
-  64, 77, 74, 89, 87, 75, 94, 93, 148, 76,
-  105, 95, 79, 87, 77, 83, 98, 97, 81, 40,
-  91, 45, 65, 79, 75, 65, 104, 85, 71, 69,
-  101, 75, 69, 84, 87, 88, 68, 100, 96, 91,
-  89, 76, 105, 71, 72, 71, 93, 89, 80, 104,
-  63, 56, 99, 86, 87, 79, 80, 84, 105, 46,
-  79, 84, 72, 99, 79, 97, 88, 85, 118, 80,
-  88, 111, 85, 81, 100, 75, 88, 80, 86, 73,
-  91, 99, 85, 81, 87, 103, 81, 86, 87, 80,
-  82, 84, 82, 85, 86, 102, 79, 87, 79, 94,
-  93, 90, 96, 85, 75, 85, 101, 92, 87, 93,
-  82, 94, 76, 76, 83, 80, 74, 81, 79, 79,
-  89, 86, 80, 82, 79, 76, 83, 87, 75, 92,
-  89, 91, 84, 82, 82, 84, 105, 69, 87, 90,
-  84, 72, 79, 89, 70, 69, 81, 78, 78, 69,
-  76, 87, 81, 85, 83, 79, 75, 86, 77, 96,
-  74, 80, 90, 71, 70, 82, 92, 77, 79, 81,
-  80, 81, 73, 76, 86, 89, 80, 70, 81, 73,
-  97, 82, 86, 78, 79, 82, 83, 71, 82, 66,
-  88, 81, 79, 87, 86, 74, 86, 88, 86, 81,
-  87, 81, 80, 80, 81, 83, 71, 85, 78, 96,
-  78, 82, 74, 84, 82, 85, 80, 80, 91, 79,
-  79, 93, 76, 87, 86, 81, 79, 89, 82, 81,
-  85, 82, 88, 73, 84, 82, 85, 68, 98, 88,
-  82, 74, 85, 76, 73, 89, 77, 66, 87, 94,
-  81, 93, 85, 79, 71, 72, 82, 88, 81, 90,
-  87, 86, 86, 89, 117, 87, 89, 79, 79, 81,
-  80, 66, 84, 74, 98, 73, 83, 77, 80, 92,
-  78, 80, 82, 80, 77, 69, 90, 105, 89, 80,
-  81, 111, 73, 80, 84, 77, 80, 77, 75, 57,
-  75, 64, 74, 84, 87, 74, 92, 79, 88, 88,
-  86, 86, 71, 80, 67, 82, 76, 72, 86, 89,
-  81, 82, 98, 88, 93, 78, 77, 78, 91, 77,
-  84, 71, 86, 81, 87, 90, 80, 81, 75, 78,
-  72, 78, 72, 89, 76, 76, 87, 77, 79, 87,
-  91, 77, 72, 85, 93, 91, 86, 74, 89, 83,
-  88, 79, 86, 79, 87, 81, 89, 85, 85, 64,
-  81, 77, 73, 93, 81, 68, 94, 99, 79, 88,
-  76, 80, 81, 91, 67, 77, 77, 96, 90, 78,
-  94, 92, 159, 82, 118, 87, 69, 85, 85, 77,
-  109, 91, 95, 43, 95, 66, 73, 91, 75, 63,
-  103, 80, 63, 52, 116, 98, 82, 75, 82, 109,
-  69, 90, 102, 89, 92, 67, 88, 59, 82, 59,
-  83, 87, 92, 102, 93, 64, 83, 86, 94, 74,
-  77, 79, 89, 55, 73, 93, 71, 95, 83, 88,
-  88, 93, 119, 72, 69, 98, 92, 82, 92, 68,
-  90, 82, 93, 79, 83, 99, 82, 79, 89, 105,
-  84, 85, 81, 72, 91, 85, 71, 90, 102, 88,
-  82, 92, 101, 103, 91, 85, 86, 78, 77, 91,
-  95, 88, 78, 87, 85, 83, 81, 71, 83, 78,
-  73, 89, 78, 70, 91, 94, 82, 92, 86, 72,
-  76, 80, 82, 86, 86, 97, 83, 83, 85, 88,
-  118, 80, 90, 82, 82, 66, 78, 81, 89, 69,
-  88, 74, 86, 78, 76, 91, 83, 80, 84, 69,
-  73, 76, 94, 99, 85, 77, 88, 93, 71, 77,
-  90, 75, 78, 76, 71, 59, 71, 64, 80, 86,
-  88, 71, 98, 78, 93, 85, 88, 87, 79, 77,
-  68, 79, 78, 70, 88, 80, 77, 81, 85, 78,
-  89, 82, 79, 76, 88, 81, 80, 72, 85, 85,
-  74, 89, 77, 91, 77, 80, 70, 76, 76, 83,
-  75, 73, 92, 77, 76, 92, 87, 76, 87, 84,
-  93, 91, 77, 79, 92, 84, 87, 75, 85, 78,
-  82, 72, 87, 90, 84, 98, 84, 81, 81, 81,
-  80, 70, 91, 87, 79, 85, 75, 80, 85, 80,
-  83, 89, 85, 87, 81, 88, 84, 84, 81, 87,
-  81, 84, 88, 91, 85, 79, 83, 79, 76, 80,
-  82, 70, 78, 87, 73, 90, 79, 88, 82, 83,
-  75, 93, 76, 83, 84, 87, 80, 85, 80, 78,
-  81, 96, 74, 77, 86, 76, 67, 83, 86, 76,
-  74, 71, 83, 89, 84, 89, 74, 82, 66, 72,
-  81, 73, 90, 89, 81, 78, 96, 88, 75, 85,
-  96, 84, 89, 79, 84, 81, 84, 81, 80, 82,
-  85, 70, 80, 79, 67, 69, 79, 82, 83, 82,
-  83, 89, 86, 92, 77, 77, 93, 77, 73, 80,
-  81, 80, 91, 88, 92, 91, 79, 85, 84, 90,
-  73, 91, 86, 70, 80, 76, 88, 88, 84, 70,
-  92, 84, 78, 79, 68, 87, 94, 99, 75, 68,
-  78, 97, 87, 81, 92, 96, 137, 92, 102, 92,
-  91, 95, 95, 86, 98, 97, 78, 49, 93, 58,
-  79, 82, 79, 83, 99, 81, 77, 73, 100, 68,
-  69, 80, 89, 92, 79, 93, 97, 86, 88, 90,
-  87, 75, 82, 72, 78, 86, 97, 85, 72, 65,
-  86, 87, 89, 90, 83, 80, 85, 54, 81, 83,
-  75, 93, 75, 82, 84, 84, 100, 84, 96, 93,
-  97, 87, 89, 84, 88, 84, 92, 80, 91, 81,
-  89, 83, 90, 98, 96, 76, 91, 84, 82, 95,
-  80, 89, 80, 92, 91, 91, 82, 97, 94, 91,
-  95, 88, 83, 105, 96, 96, 78, 83, 80, 85,
-  79, 82, 77, 80, 82, 82, 83, 74, 95, 84,
-  80, 83, 77, 77, 90, 82, 78, 85, 91, 88,
-  82, 85, 79, 88, 95, 82, 83, 85, 87, 74,
-  87, 94, 88, 77, 83, 78, 87, 68, 81, 87,
-  79, 85, 80, 70, 81, 84, 78, 86, 73, 82,
-  91, 79, 78, 80, 84, 76, 79, 89, 73, 78,
-  82, 76, 77, 82, 86, 71, 94, 71, 87, 86,
-  82, 85, 77, 83, 62, 70, 80, 70, 90, 79,
-  76, 80, 80, 78, 78, 85, 91, 81, 88, 83,
-  81, 82, 87, 83, 75, 85, 82, 67, 81, 81,
-  67, 71, 80, 78, 73, 76, 85, 84, 83, 91,
-  71, 75, 85, 77, 79, 79, 75, 83, 88, 87,
-  87, 87, 81, 84, 84, 85, 78, 82, 98, 96,
-  82, 79, 79, 85, 79, 74, 87, 60, 88, 80,
-  78, 97, 79, 110, 85, 83, 83, 85, 76, 87,
-  73, 80, 93, 95, 114, 80, 72, 104, 79, 74,
-  74, 80, 74, 84, 70, 77, 86, 113, 66, 77,
-  84, 101, 80, 79, 90, 91, 92, 88, 79, 89,
-  84, 104, 93, 82, 100, 72, 87, 75, 90, 68,
-  89, 95, 85, 90, 76, 68, 75, 73, 77, 75,
-  83, 73, 85, 78, 108, 67, 69, 87, 92, 76,
-  85, 89, 113, 93, 78, 77, 85, 62, 86, 92,
-  85, 62, 79, 74, 69, 78, 89, 81, 84, 85,
-  80, 154, 84, 87, 83, 78, 77, 83, 112, 73,
-  89, 87, 86, 84, 87, 73, 81, 86, 102, 91,
-  83, 69, 82, 96, 76, 81, 101, 82, 85, 79,
-  74, 84, 80, 77, 99, 66, 93, 87, 80, 96,
-  80, 121, 84, 90, 79, 85, 82, 87, 72, 78,
-  86, 74, 118, 78, 71, 93, 77, 73, 69, 77,
-  71, 87, 75, 83, 86, 126, 71, 67, 85, 76,
-  73, 83, 90, 102, 101, 93, 77, 103, 82, 117,
-  95, 77, 96, 69, 87, 89, 77, 78, 96, 99,
-  87, 77, 85, 69, 68, 79, 81, 74, 80, 84,
-  83, 80, 112, 67, 72, 68, 94, 80, 80, 87,
-  119, 101, 74, 70, 86, 55, 76, 96, 83, 66,
-  82, 80, 64, 72, 88, 81, 86, 86, 79, 161,
-  86, 85, 89, 74, 79, 79, 112, 61, 77, 81,
-  84, 81, 85, 71, 75, 94, 109, 88, 81, 69,
-  83, 94, 80, 79, 100, 94, 76, 84, 79, 85,
-  82, 72, 87, 73, 88, 81, 78, 98, 82, 123,
-  80, 86, 87, 88, 84, 90, 82, 78, 86, 69,
-  107, 80, 75, 79, 81, 94, 83, 81, 65, 83,
-  74, 77, 84, 93, 69, 76, 80, 72, 81, 82,
-  94, 84, 89, 91, 89, 93, 84, 110, 92, 80,
-  100, 79, 88, 75, 86, 75, 103, 96, 79, 88,
-  97, 74, 80, 78, 80, 77, 86, 99, 92, 82,
-  107, 65, 75, 66, 86, 83, 81, 83, 113, 92,
-  82, 69, 86, 63, 87, 86, 90, 66, 80, 79,
-  72, 80, 81, 82, 84, 91, 82, 129, 86, 88,
-  80, 80, 81, 85, 91, 71, 82, 86, 82, 86,
-  78, 76, 75, 84, 95, 93, 79, 71, 91, 85,
-  81, 89, 72, 84, 82, 74, 85, 83, 87, 82,
-  85, 68, 87, 82, 85, 77, 77, 98, 78, 90,
-  77, 98, 78, 73, 69, 80, 79, 69, 98, 75,
-  77, 91, 82, 80, 88, 80, 81, 74, 83, 79,
-  86, 89, 72, 94, 74, 103, 82, 87, 77, 91,
-  101, 86, 86, 67, 73, 71, 90, 89, 106, 84,
-  77, 87, 72, 74, 102, 97, 82, 65, 73, 81,
-  71, 73, 73, 77, 94, 78, 70, 80, 90, 79,
-  83, 76, 74, 87, 85, 86, 105, 82, 70, 85,
-  84, 75, 87, 93, 87, 84, 80, 88, 58, 100,
-  82, 84, 85, 87, 79, 109, 83, 83, 92, 73,
-  79, 82, 92, 93, 77, 87, 78, 73, 89, 77,
-  82, 86, 90, 81, 85, 84, 95, 90, 78, 91,
-  73, 80, 86, 70, 82, 88, 91, 82, 80, 81,
-  86, 92, 85, 81, 80, 98, 84, 96, 83, 97,
-  81, 64, 76, 80, 77, 73, 88, 75, 80, 86,
-  82, 79, 89, 86, 80, 64, 96, 70, 84, 79,
-  81, 88, 75, 84, 82, 87, 83, 79, 105, 87,
-  86, 84, 83, 70, 91, 86, 112, 91, 78, 96,
-  63, 82, 108, 100, 83, 67, 77, 80, 70, 85,
-  69, 76, 93, 94, 70, 74, 88, 75, 83, 79,
-  65, 95, 80, 82, 87, 82, 70, 80, 81, 70,
-  85, 90, 88, 90, 78, 94, 62, 91, 75, 86,
-  90, 89, 77, 104, 84, 81, 82, 78, 77, 81,
-  80, 85, 85, 87, 77, 80, 84, 80, 79, 82,
-  70, 85, 86, 86, 86, 101, 78, 84, 79, 88,
-  79, 72, 79, 86, 87, 78, 95, 90, 84, 85,
-  80, 81, 78, 93, 82, 87, 85, 98, 87, 73,
-  78, 78, 76, 73, 90, 78, 78, 81, 73, 86,
-  84, 86, 78, 71, 87, 79, 77, 78, 79, 87,
-  75, 81, 87, 88, 80, 75, 94, 91, 87, 100,
-  77, 78, 89, 88, 109, 89, 81, 85, 75, 82,
-  114, 103, 77, 68, 87, 90, 75, 77, 72, 77,
-  95, 89, 71, 78, 92, 77, 85, 88, 75, 93,
-  81, 78, 95, 85, 71, 68, 85, 77, 84, 88,
-  87, 85, 79, 82, 63, 89, 80, 86, 88, 88,
-  87, 95, 88, 84, 75, 79, 81, 82, 68, 88,
-  87, 92, 83, 78, 73, 81, 79, 83, 83, 85,
-  83, 83, 89, 84, 83, 87, 57, 80, 86, 86,
-  89, 85, 91, 87, 82, 88, 78, 79, 91, 79,
-  79, 78, 85, 95, 78, 94, 81, 72, 85, 78,
-  94, 66, 78, 80, 85, 70, 73, 94, 99, 81,
-  89, 74, 87, 67, 81, 63, 86, 97, 80, 89,
-  98, 92, 70, 82, 89, 85, 88, 72, 80, 51,
-  76, 98, 100, 86, 79, 99, 74, 88, 88, 91,
-  94, 85, 73, 80, 82, 80, 74, 77, 95, 84,
-  87, 86, 73, 92, 84, 69, 64, 95, 83, 68,
-  75, 77, 77, 86, 77, 85, 94, 89, 91, 108,
-  90, 88, 69, 93, 79, 83, 89, 81, 79, 69,
-  75, 87, 89, 81, 90, 83, 72, 96, 87, 84,
-  80, 73, 93, 85, 82, 90, 87, 87, 90, 83,
-  85, 86, 76, 84, 62, 82, 85, 82, 97, 86,
-  93, 86, 67, 89, 80, 75, 92, 87, 83, 69,
-  91, 93, 84, 96, 85, 64, 93, 82, 92, 73,
-  73, 74, 85, 74, 80, 87, 100, 86, 88, 61,
-  90, 63, 83, 55, 90, 112, 85, 82, 104, 88,
-  81, 69, 88, 82, 89, 73, 93, 57, 77, 93,
-  97, 99, 81, 99, 69, 93, 84, 83, 84, 79,
-  73, 82, 87, 89, 68, 87, 101, 91, 87, 79,
-  71, 89, 89, 88, 59, 98, 86, 65, 69, 78,
-  79, 82, 77, 85, 96, 92, 88, 112, 88, 85,
-  80, 89, 74, 86, 89, 82, 85, 63, 78, 87,
-  82, 87, 90, 85, 68, 92, 91, 88, 78, 83,
-  93, 88, 83, 83, 77, 90, 93, 82, 81, 92,
-  81, 84, 61, 83, 87, 81, 86, 84, 92, 83,
-  85, 90, 76, 81, 88, 79, 78, 64, 85, 89,
-  79, 94, 87, 69, 87, 78, 92, 77, 82, 82,
-  82, 86, 72, 88, 94, 84, 87, 73, 90, 69,
-  79, 61, 89, 95, 82, 87, 106, 88, 72, 73,
-  87, 82, 88, 82, 79, 53, 81, 94, 99, 90,
-  83, 96, 78, 91, 86, 87, 85, 79, 82, 88,
-  82, 85, 63, 80, 89, 78, 85, 85, 76, 92,
-  87, 99, 64, 96, 85, 68, 72, 79, 78, 85,
-  84, 84, 97, 89, 89, 104, 79, 84, 74, 87,
-  81, 87, 89, 81, 86, 64, 77, 89, 82, 83,
-  90, 82, 65, 94, 83, 89, 83, 77, 80, 88,
-  82, 90, 80, 88, 89, 83, 83, 75, 81, 73,
-  90, 93, 88, 75, 91, 58, 95, 73, 88, 73,
-  79, 103, 71, 85, 96, 82, 73, 78, 84, 76,
-  90, 77, 81, 72, 92, 87, 98, 85, 93, 101,
-  94, 81, 89, 88, 81, 81, 81, 100, 87, 95,
-  77, 84, 99, 99, 82, 80, 81, 77, 81, 89,
-  84, 88, 75, 87, 74, 92, 95, 85, 84, 81,
-  91, 83, 71, 75, 86, 78, 80, 97, 73, 89,
-  86, 84, 68, 87, 78, 80, 86, 74, 85, 82,
-  85, 79, 75, 85, 91, 86, 67, 83, 84, 75,
-  76, 78, 76, 97, 77, 76, 80, 86, 85, 84,
-  87, 82, 85, 89, 77, 81, 87, 81, 86, 77,
-  82, 74, 89, 92, 86, 89, 84, 89, 88, 82,
-  80, 81, 97, 84, 85, 80, 85, 65, 95, 84,
-  91, 68, 79, 60, 95, 77, 87, 83, 79, 90,
-  72, 84, 99, 91, 78, 77, 82, 67, 86, 73,
-  82, 74, 89, 87, 105, 77, 90, 100, 92, 85,
-  79, 73, 89, 76, 77, 103, 79, 101, 82, 77,
-  89, 86, 73, 76, 79, 74, 76, 89, 80, 88,
-  76, 82, 76, 96, 98, 83, 83, 78, 82, 85,
-  77, 80, 83, 78, 86, 98, 67, 85, 92, 85,
-  59, 91, 73, 77, 90, 74, 87, 74, 93, 79,
-  79, 98, 85, 81, 64, 83, 92, 67, 71, 75,
-  79, 96, 85, 81, 72, 88, 88, 83, 63, 84,
-  94, 92, 83, 78, 83, 83, 91, 80, 88, 79,
-  86, 94, 86, 84, 77, 91, 83, 85, 78, 77,
-  94, 80, 86, 87, 93, 74, 92, 87, 86, 75,
-  86, 56, 92, 77, 83, 83, 80, 106, 74, 83,
-  96, 86, 84, 79, 89, 80, 79, 81, 87, 74,
-  86, 88, 91, 87, 95, 87, 92, 87, 87, 94,
-  79, 81, 81, 99, 79, 93, 86, 79, 90, 82,
-  81, 81, 82, 75, 77, 88, 88, 81, 77, 86,
-  74, 87, 95, 87, 87, 76, 94, 79, 76, 80,
-  88, 79, 84, 100, 79, 89, 97, 86, 71, 97,
-  77, 86, 86, 73, 89, 80, 83, 81, 78, 81,
-  89, 87, 70, 79, 84, 77, 74, 81, 84, 97,
-  92, 86, 85, 75, 86, 82, 79, 83, 78, 84,
-  81, 80, 83, 83, 84, 79, 85, 82, 85, 89,
-  82, 87, 77, 86, 82, 82, 83, 82, 91, 85,
-  82, 75, 73, 70, 78, 86, 94, 70, 97, 52,
-  89, 77, 77, 71, 82, 114, 73, 81, 81, 81,
-  78, 81, 87, 75, 90, 87, 82, 70, 91, 81,
-  95, 87, 101, 89, 92, 89, 78, 102, 82, 80,
-  73, 88, 83, 92, 74, 95, 98, 103, 83, 74,
-  86, 76, 80, 90, 88, 86, 78, 84, 83, 102,
-  87, 84, 82, 82, 98, 85, 75, 77, 100, 68,
-  96, 82, 77, 80, 87, 75, 76, 93, 80, 85,
-  83, 79, 79, 79, 82, 77, 69, 82, 83, 94,
-  61, 88, 77, 70, 66, 77, 90, 94, 86, 79,
-  79, 99, 88, 80, 88, 83, 86, 83, 81, 76,
-  87, 78, 80, 77, 76, 66, 79, 95, 82, 80,
-  83, 78, 80, 71, 83, 82, 90, 85, 83, 85,
-  84, 68, 83, 81, 94, 64, 89, 46, 86, 80,
-  84, 88, 86, 109, 82, 85, 82, 88, 77, 83,
-  80, 63, 81, 79, 79, 74, 93, 83, 102, 85,
-  114, 85, 91, 81, 70, 81, 88, 76, 75, 88,
-  83, 99, 77, 89, 105, 89, 74, 77, 91, 73,
-  77, 95, 83, 84, 81, 84, 79, 119, 90, 85,
-  83, 76, 77, 88, 88, 78, 98, 66, 73, 81,
-  61, 73, 97, 66, 82, 94, 66, 91, 89, 80,
-  81, 81, 85, 83, 75, 88, 76, 93, 60, 81,
-  87, 62, 53, 75, 96, 99, 88, 81, 71, 88,
-  91, 80, 76, 73, 96, 84, 88, 75, 88, 81,
-  85, 72, 76, 74, 78, 96, 97, 70, 78, 81,
-  78, 74, 87, 82, 96, 87, 78, 87, 104, 73,
-  83, 92, 92, 63, 89, 51, 85, 76, 77, 90,
-  85, 112, 74, 77, 80, 77, 80, 88, 89, 82,
-  78, 88, 86, 70, 83, 90, 88, 88, 95, 77,
-  81, 80, 76, 109, 78, 77, 79, 81, 85, 90,
-  81, 85, 95, 79, 83, 75, 85, 81, 78, 87,
-  87, 80, 82, 85, 80, 94, 91, 90, 84, 81,
-  99, 80, 86, 80, 92, 76, 72, 84, 76, 85,
-  90, 77, 79, 94, 70, 88, 86, 77, 80, 97,
-  79, 83, 78, 82, 81, 97, 62, 83, 80, 71,
-  69, 80, 91, 96, 83, 86, 83, 71, 87, 78,
-  83, 86, 82, 80, 85, 78, 80, 81, 78, 68,
-  79, 79, 98, 92, 87, 83, 78, 78, 78, 71,
-  83, 87, 87, 85, 78, 80, 86, 68, 67, 89,
-  92, 66, 105, 55, 75, 82, 78, 75, 83, 124,
-  71, 77, 71, 77, 95, 84, 82, 85, 101, 89,
-  95, 70, 91, 82, 76, 92, 98, 86, 91, 102,
-  84, 118, 80, 87, 83, 80, 84, 85, 76, 107,
-  93, 98, 92, 81, 78, 72, 85, 89, 90, 87,
-  80, 82, 98, 97, 77, 87, 88, 88, 109, 76,
-  78, 82, 94, 74, 99, 71, 104, 85, 81, 79,
-  81, 91, 86, 79, 80, 87, 80, 80, 78, 73,
-  66, 74, 91, 98, 64, 100, 78, 70, 73, 84,
-  87, 90, 92, 97, 84, 100, 83, 72, 83, 94,
-  79, 77, 74, 82, 83, 68, 67, 103, 77, 72,
-  71, 91, 85, 78, 79, 76, 88, 64, 82, 88,
-  88, 87, 77, 87, 92, 68, 61, 76, 90, 64,
-  117, 49, 68, 86, 87, 86, 86, 123, 79, 73,
-  58, 69, 88, 86, 80, 81, 89, 84, 99, 77,
-  93, 86, 64, 102, 111, 74, 87, 86, 81, 125,
-  77, 90, 84, 74, 90, 84, 74, 115, 109, 89,
-  82, 89, 78, 75, 79, 88, 88, 81, 78, 89,
-  88, 98, 75, 86, 85, 80, 96, 76, 86, 73,
-  100, 75, 82, 67, 91, 79, 84, 62, 97, 90,
-  73, 86, 80, 83, 74, 95, 68, 78, 72, 73,
-  86, 101, 53, 93, 77, 66, 60, 77, 87, 91,
-  107, 98, 83, 89, 80, 70, 95, 85, 82, 72,
-  71, 83, 79, 70, 64, 76, 77, 72, 84, 94,
-  105, 69, 83, 73, 84, 69, 87, 88, 89, 96,
-  77, 85, 93, 71, 72, 86, 92, 62, 98, 60,
-  75, 80, 84, 95, 88, 118, 78, 72, 71, 74,
-  86, 87, 93, 87, 87, 85, 95, 72, 89, 92,
-  76, 91, 93, 84, 74, 78, 79, 121, 80, 85,
-  87, 76, 98, 85, 80, 93, 85, 81, 93, 85,
-  79, 77, 84, 86, 87, 76, 75, 88, 93, 97,
-  81, 90, 89, 85, 97, 75, 81, 86, 87, 84,
-  70, 76, 97, 96, 80, 81, 80, 94, 78, 78,
-  84, 88, 69, 100, 76, 84, 97, 81, 88, 93,
-  63, 89, 82, 70, 74, 85, 86, 90, 95, 84,
-  84, 79, 84, 72, 80, 95, 86, 78, 77, 78,
-  73, 72, 69, 68, 77, 88, 102, 95, 85, 85,
-  83, 75, 89, 70, 84, 95, 88, 88, 93, 76,
-  88, 75, 77, 86, 89, 76, 83, 80, 82, 78,
-  77, 91, 91, 73, 89, 89, 70, 88, 80, 84,
-  96, 92, 74, 62, 85, 78, 94, 91, 82, 79,
-  90, 69, 87, 91, 82, 81, 98, 85, 92, 80,
-  91, 74, 85, 80, 92, 86, 63, 88, 92, 75,
-  89, 90, 88, 73, 71, 86, 80, 93, 80, 78,
-  83, 70, 88, 60, 88, 95, 67, 85, 74, 95,
-  77, 90, 69, 75, 75, 66, 88, 93, 80, 82,
-  82, 84, 66, 85, 93, 85, 62, 79, 86, 81,
-  82, 83, 90, 71, 74, 182, 87, 75, 72, 69,
-  82, 76, 95, 91, 65, 72, 82, 73, 92, 91,
-  82, 81, 74, 86, 82, 91, 86, 87, 90, 75,
-  73, 80, 97, 98, 86, 142, 100, 82, 77, 79,
-  82, 88, 89, 75, 83, 76, 84, 75, 81, 81,
-  86, 76, 85, 92, 76, 86, 87, 90, 85, 94,
-  73, 64, 87, 80, 88, 77, 81, 92, 82, 71,
-  99, 76, 80, 74, 88, 83, 81, 76, 86, 79,
-  77, 88, 91, 83, 66, 81, 80, 80, 96, 102,
-  93, 76, 74, 97, 80, 89, 80, 83, 80, 83,
-  83, 65, 85, 92, 69, 81, 75, 86, 83, 85,
-  71, 75, 72, 68, 97, 97, 84, 89, 82, 77,
-  63, 77, 84, 75, 68, 82, 90, 83, 80, 94,
-  91, 81, 83, 181, 90, 70, 67, 62, 81, 74,
-  90, 92, 65, 71, 86, 75, 92, 93, 87, 85,
-  76, 75, 74, 89, 82, 90, 86, 76, 72, 82,
-  108, 91, 87, 131, 89, 90, 75, 77, 83, 96,
-  87, 76, 86, 83, 81, 85, 84, 86, 91, 73,
-  88, 88, 72, 95, 88, 87, 80, 91, 73, 61,
-  87, 77, 83, 71, 76, 81, 93, 76, 97, 87,
-  84, 79, 85, 88, 85, 76, 93, 76, 85, 84,
-  87, 90, 71, 92, 89, 83, 87, 87, 83, 85,
-  72, 85, 88, 88, 79, 77, 83, 68, 96, 63,
-  93, 93, 68, 82, 90, 89, 77, 85, 74, 74,
-  79, 72, 99, 93, 81, 83, 88, 78, 71, 81,
-  84, 91, 64, 85, 88, 101, 82, 80, 94, 74,
-  75, 166, 86, 72, 72, 76, 81, 78, 92, 81,
-  69, 78, 86, 77, 91, 86, 83, 102, 66, 90,
-  80, 90, 88, 85, 72, 74, 73, 82, 92, 95,
-  88, 126, 88, 80, 75, 82, 80, 93, 90, 78,
-  88, 79, 82, 79, 87, 92, 86, 73, 89, 93,
-  78, 82, 84, 79, 89, 94, 78, 59, 89, 80,
-  93, 74, 86, 86, 96, 80, 68, 85, 71, 81,
-  93, 89, 79, 84, 95, 82, 78, 84, 94, 86,
-  64, 89, 99, 80, 90, 100, 86, 80, 74, 86,
-  73, 97, 74, 82, 83, 70, 85, 73, 81, 76,
-  87, 80, 88, 85, 80, 86, 72, 79, 77, 71,
-  81, 107, 80, 76, 83, 80, 75, 84, 97, 82,
-  65, 77, 84, 87, 74, 86, 94, 76, 77, 161,
-  89, 78, 69, 78, 78, 79, 87, 83, 78, 78,
-  78, 76, 86, 87, 83, 80, 63, 81, 81, 82,
-  85, 90, 84, 77, 70, 81, 97, 88, 91, 125,
-  81, 83, 75, 85, 79, 84, 91, 78, 91, 78,
-  83, 84, 85, 86, 83, 70, 86, 99, 86, 75,
-  88, 73, 86, 93, 82, 60, 89, 84, 90, 64,
-  90, 95, 91, 77, 68, 73, 64, 79, 94, 85,
-  78, 88, 91, 91, 74, 84, 97, 82, 66, 82,
-  93, 86, 96, 109, 89, 78, 75, 96, 79, 96,
-  77, 83, 84, 84, 82, 81, 82, 69, 88, 82,
-  74, 79, 80, 88, 73, 82, 71, 75, 78, 106,
-  86, 87, 78, 75, 71, 82, 84, 78, 68, 73,
-  89, 84, 76, 89, 81, 89, 86, 158, 92, 75,
-  67, 72, 82, 75, 81, 82, 82, 81, 74, 76,
-  89, 91, 88, 81, 69, 75, 75, 85, 88, 91,
-  79, 80, 70, 84, 109, 82, 92, 108, 88, 91,
-  84, 81, 79, 89, 85, 75, 88, 79, 81, 86,
-  80, 86, 86, 73, 89, 90, 76, 91, 87, 80,
-  92, 89, 77, 61, 85, 76, 87, 77, 84, 87,
-  94, 75, 89, 88, 77, 82, 95, 89, 84, 83,
-  92, 82, 82, 86, 91, 87, 73, 88, 99, 83,
-  89, 96, 85, 79, 76, 87, 78, 85, 72, 81,
-  84, 69, 91, 72, 86, 78, 82, 82, 84, 85,
-  78, 85, 76, 77, 79, 77, 82, 107, 80, 79,
-  89, 80, 79, 90, 83, 88, 65, 77, 85, 87,
-  76, 84, 91, 79, 80, 152, 84, 78, 74, 77,
-  78, 80, 86, 77, 73, 82, 78, 76, 91, 86,
-  86, 94, 71, 83, 85, 83, 89, 91, 78, 76,
-  70, 83, 93, 88, 92, 111, 87, 76, 75, 80,
-  87, 83, 91, 82, 85, 86, 82, 87, 78, 82,
-  93, 77, 97, 85, 71, 82, 84, 96, 79, 103,
-  79, 64, 99, 81, 87, 76, 90, 78, 104, 77,
-  88, 93, 87, 85, 91, 88, 94, 75, 95, 80,
-  85, 93, 91, 85, 68, 97, 93, 79, 86, 89,
-  81, 86, 74, 80, 71, 86, 66, 76, 83, 74,
-  91, 70, 86, 74, 87, 79, 95, 92, 78, 83,
-  74, 73, 81, 78, 92, 84, 85, 69, 90, 85,
-  77, 89, 96, 84, 71, 84, 79, 93, 79, 89,
-  97, 69, 70, 136, 78, 76, 82, 85, 88, 85,
-  82, 86, 80, 76, 75, 75, 85, 85, 89, 77,
-  66, 86, 73, 85, 83, 97, 85, 74, 71, 84,
-  81, 84, 91, 120, 82, 79, 76, 83, 90, 82,
-  92, 80, 81, 84, 85, 90, 74, 89, 95, 74,
-  92, 86, 75, 78, 85, 90, 81, 98, 77, 63,
-  96, 78, 87, 83, 91, 76, 96, 79, 78, 87,
-  86, 82, 91, 85, 95, 67, 92, 82, 82, 84,
-  86, 89, 67, 95, 86, 79, 86, 93, 78, 78,
-  70, 88, 74, 96, 71, 76, 87, 79, 94, 75,
-  94, 75, 83, 87, 75, 85, 76, 83, 74, 74,
-  77, 75, 89, 79, 87, 80, 88, 88, 73, 92,
-  85, 87, 67, 84, 84, 91, 76, 86, 93, 68,
-  75, 130, 76, 75, 88, 92, 92, 81, 78, 87,
-  91, 75, 74, 72, 84, 86, 86, 83, 75, 95,
-  79, 90, 86, 98, 94, 76, 73, 85, 82, 81,
-  88, 111, 86, 85, 88, 82, 86, 81, 88, 81,
-  90, 81, 83, 95, 74, 91, 90, 74, 98, 85,
-  74, 87, 89, 92, 86, 98, 81, 64, 95, 78,
-  81, 88, 88, 76, 101, 75, 90, 90, 89, 88,
-  87, 89, 91, 78, 89, 83, 83, 90, 92, 82,
-  77, 92, 91, 83, 88, 85, 79, 69, 80, 84,
-  75, 83, 68, 74, 85, 78, 86, 72, 89, 76,
-  87, 83, 72, 87, 73, 82, 75, 75, 80, 75,
-  78, 87, 86, 72, 94, 88, 83, 102, 77, 86,
-  77, 85, 83, 84, 77, 90, 87, 70, 73, 128,
-  84, 73, 81, 75, 84, 85, 83, 83, 78, 83,
-  81, 79, 92, 82, 87, 88, 78, 89, 85, 82,
-  84, 98, 90, 76, 73, 84, 84, 84, 89, 113,
-  118, 82, 96, 92, 92, 70, 80, 94, 82, 89,
-  82, 91, 79, 102, 72, 75, 88, 72, 92, 83,
-  84, 86, 83, 86, 103, 75, 88, 81, 85, 81,
-  75, 96, 79, 74, 66, 74, 96, 78, 77, 74,
-  84, 78, 82, 73, 74, 91, 98, 68, 90, 80,
-  86, 82, 88, 73, 78, 93, 73, 78, 80, 82,
-  89, 63, 91, 77, 49, 87, 94, 93, 85, 107,
-  64, 77, 78, 89, 92, 80, 83, 91, 80, 72,
-  79, 92, 94, 88, 79, 88, 79, 103, 97, 71,
-  76, 83, 62, 83, 81, 74, 90, 76, 76, 80,
-  78, 82, 82, 95, 75, 115, 99, 81, 84, 93,
-  90, 67, 84, 70, 94, 118, 106, 79, 67, 62,
-  80, 81, 67, 87, 85, 97, 73, 84, 115, 91,
-  81, 93, 90, 74, 82, 97, 75, 88, 80, 90,
-  70, 101, 72, 72, 90, 77, 81, 91, 85, 67,
-  86, 88, 82, 82, 87, 76, 94, 85, 69, 89,
-  71, 76, 72, 74, 98, 76, 81, 63, 84, 70,
-  81, 73, 76, 83, 100, 63, 84, 82, 87, 77,
-  91, 66, 78, 102, 88, 78, 79, 89, 85, 70,
-  98, 85, 63, 82, 76, 100, 71, 114, 86, 76,
-  79, 89, 100, 77, 87, 74, 99, 62, 74, 90,
-  80, 89, 78, 86, 69, 96, 94, 71, 81, 90,
-  71, 89, 85, 75, 82, 80, 81, 71, 77, 100,
-  74, 98, 72, 114, 108, 78, 85, 96, 84, 69,
-  80, 77, 101, 107, 91, 82, 61, 64, 72, 97,
-  62, 88, 83, 98, 69, 73, 119, 90, 67, 93,
-  90, 79, 83, 93, 82, 86, 85, 92, 85, 92,
-  75, 75, 82, 71, 89, 84, 91, 80, 77, 85,
-  84, 82, 87, 81, 83, 77, 68, 90, 80, 78,
-  79, 78, 90, 82, 92, 79, 87, 72, 86, 77,
-  75, 86, 94, 87, 89, 78, 86, 82, 92, 76,
-  81, 97, 79, 80, 82, 80, 88, 78, 93, 80,
-  57, 86, 73, 95, 87, 91, 96, 69, 79, 82,
-  99, 73, 86, 72, 92, 72, 85, 92, 88, 92,
-  77, 79, 69, 98, 91, 77, 79, 92, 62, 83,
-  79, 75, 90, 77, 94, 83, 79, 110, 81, 96,
-  80, 110, 99, 80, 84, 90, 70, 65, 79, 85,
-  80, 101, 77, 78, 68, 69, 81, 84, 81, 85,
-  90, 92, 72, 86, 93, 87, 84, 80, 78, 104,
-  75, 81, 87, 81, 76, 90, 94, 84, 85, 80,
-  82, 82, 77, 71, 85, 82, 75, 78, 104, 90,
-  72, 75, 83, 96, 72, 86, 85, 89, 80, 93,
-  80, 73, 81, 106, 79, 77, 77, 83, 74, 87,
-  85, 84, 80, 92, 69, 77, 90, 66, 76, 79,
-  70, 70, 83, 94, 76, 79, 76, 73, 76, 95,
-  74, 102, 79, 90, 80, 86, 87, 64, 88, 87,
-  80, 93, 71, 95, 81, 85, 85, 87, 84, 77,
-  84, 98, 77, 88, 93, 75, 74, 83, 77, 92,
-  79, 86, 93, 81, 75, 77, 74, 85, 81, 107,
-  92, 87, 79, 96, 82, 77, 89, 74, 79, 94,
-  103, 85, 84, 66, 88, 82, 80, 87, 93, 92,
-  73, 64, 78, 106, 70, 74, 73, 98, 84, 79,
-  82, 87, 72, 92, 88, 74, 86, 95, 74, 97,
-  78, 79, 86, 65, 90, 83, 90, 108, 72, 73,
-  87, 81, 81, 82, 85, 84, 86, 79, 78, 72,
-  71, 96, 73, 73, 78, 91, 61, 86, 89, 77,
-  61, 103, 68, 73, 90, 55, 76, 82, 82, 79,
-  83, 119, 72, 84, 71, 83, 82, 87, 76, 110,
-  64, 92, 71, 85, 87, 75, 99, 103, 91, 82,
-  91, 93, 83, 87, 74, 78, 88, 78, 71, 88,
-  80, 100, 94, 78, 95, 93, 72, 114, 72, 78,
-  100, 70, 71, 88, 68, 83, 92, 83, 105, 90,
-  75, 101, 81, 84, 85, 74, 82, 76, 84, 94,
-  98, 73, 80, 105, 74, 88, 102, 89, 82, 61,
-  98, 93, 83, 84, 77, 82, 79, 82, 88, 82,
-  79, 95, 94, 83, 87, 83, 74, 81, 78, 80,
-  88, 88, 97, 79, 89, 91, 75, 76, 81, 73,
-  73, 87, 85, 80, 94, 89, 77, 70, 78, 104,
-  80, 74, 87, 87, 78, 79, 85, 97, 72, 92,
-  76, 78, 88, 69, 78, 78, 76, 71, 81, 91,
-  77, 89, 80, 74, 85, 92, 80, 100, 81, 89,
-  88, 82, 87, 62, 91, 84, 81, 83, 84, 96,
-  84, 83, 84, 91, 81, 79, 73, 93, 76, 86,
-  89, 78, 75, 86, 78, 93, 81, 88, 93, 85,
-  80, 93, 74, 85, 83, 98, 99, 88, 80, 90,
-  79, 75, 89, 88, 77, 82, 85, 89, 87, 69,
-  79, 83, 82, 85, 93, 86, 74, 72, 96, 83,
-  85, 86, 82, 84, 73, 81, 89, 84, 83, 87,
-  82, 80, 87, 81, 85, 86, 77, 77, 90, 84,
-  80, 70, 95, 88, 85, 81, 79, 80, 77, 83,
-  88, 90, 85, 95, 90, 83, 84, 97, 88, 96,
-  97, 83, 81, 84, 80, 88, 85, 86, 69, 84,
-  77, 83, 75, 81, 77, 82, 83, 86, 83, 80,
-  81, 83, 84, 93, 82, 92, 84, 91, 94, 86,
-  86, 70, 78, 83, 85, 78, 71, 106, 84, 81,
-  87, 88, 86, 83, 75, 92, 80, 80, 89, 85,
-  81, 80, 81, 93, 94, 90, 94, 88, 85, 91,
-  81, 84, 76, 91, 74, 89, 85, 73, 79, 89,
-  89, 77, 80, 83, 80, 83, 95, 80, 87, 83,
-  93, 80, 94, 89, 84, 75, 85, 88, 87, 73,
-  72, 94, 75, 76, 83, 87, 85, 82, 79, 84,
-  84, 98, 83, 97, 74, 82, 92, 73, 88, 76,
-  81, 88, 86, 77, 79, 68, 79, 80, 84, 96,
-  79, 81, 95, 92, 80, 91, 86, 97, 93, 90,
-  69, 91, 85, 79, 77, 95, 72, 90, 72, 74,
-  73, 87, 88, 86, 88, 101, 82, 81, 81, 85,
-  88, 90, 86, 91, 81, 96, 89, 84, 93, 83,
-  87, 93, 86, 75, 73, 110, 86, 77, 78, 82,
-  86, 87, 72, 87, 82, 85, 88, 97, 94, 80,
-  81, 105, 84, 87, 92, 81, 80, 87, 75, 82,
-  76, 87, 76, 91, 79, 74, 86, 89, 81, 75,
-  90, 77, 85, 94, 101, 83, 78, 93, 85, 81,
-  94, 85, 86, 75, 91, 81, 87, 83, 84, 75,
-  74, 79, 90, 86, 87, 88, 85, 88, 87, 83,
-  84, 82, 77, 80, 95, 84, 81, 71, 89, 85,
-  83, 82, 76, 72, 74, 82, 87, 85, 87, 92,
-  92, 85, 86, 96, 87, 93, 91, 82, 79, 82,
-  80, 87, 81, 87, 75, 87, 75, 87, 73, 74,
-  74, 81, 85, 90, 85, 83, 84, 80, 87, 95,
-  93, 94, 91, 93, 83, 86, 91, 66, 82, 86,
-  84, 79, 71, 111, 83, 76, 87, 90, 84, 84,
-  78, 92, 77, 80, 89, 79, 82, 85, 83, 95,
-  94, 89, 88, 89, 85, 81, 79, 84, 74, 91,
-  76, 89, 86, 71, 85, 85, 89, 80, 81, 87,
-  93, 89, 97, 79, 75, 88, 97, 78, 93, 87,
-  82, 75, 88, 71, 68, 90, 86, 62, 84, 80,
-  73, 95, 79, 57, 84, 71, 77, 79, 66, 89,
-  95, 78, 96, 102, 104, 108, 106, 94, 83, 89,
-  90, 85, 88, 74, 92, 64, 46, 64, 65, 73,
-  105, 69, 74, 92, 61, 69, 87, 94, 91, 55,
-  92, 92, 79, 68, 86, 80, 104, 57, 78, 75,
-  81, 74, 118, 81, 75, 87, 44, 87, 167, 92,
-  90, 133, 15, 90, 85, 91, 86, 83, 96, 129,
-  53, 79, 77, 85, 89, 71, 78, 97, 78, 123,
-  57, 80, 85, 68, 95, 76, 83, 71, 87, 77,
-  94, 88, 60, 69, 86, 90, 93, 97, 90, 90,
-  95, 98, 85, 92, 87, 71, 65, 143, 119, 86,
-  104, 89, 96, 97, 88, 82, 102, 82, 83, 114,
-  80, 87, 86, 89, 86, 58, 80, 93, 84, 86,
-  84, 69, 73, 58, 78, 93, 81, 77, 78, 88,
-  79, 81, 78, 77, 87, 81, 83, 83, 101, 97,
-  84, 77, 74, 69, 55, 73, 103, 88, 103, 68,
-  98, 72, 79, 77, 80, 77, 83, 56, 80, 71,
-  90, 80, 90, 84, 84, 99, 79, 96, 81, 79,
-  87, 75, 109, 107, 79, 84, 83, 79, 82, 104,
-  72, 78, 98, 92, 78, 69, 83, 58, 104, 60,
-  83, 95, 79, 78, 81, 98, 63, 80, 78, 79,
-  87, 91, 86, 76, 90, 74, 85, 80, 91, 74,
-  85, 78, 82, 90, 80, 89, 79, 92, 91, 81,
-  90, 84, 80, 76, 97, 81, 57, 78, 84, 89,
-  82, 84, 86, 81, 94, 83, 75, 77, 83, 85,
-  108, 88, 83, 82, 79, 103, 89, 84, 75, 73,
-  81, 80, 73, 97, 87, 90, 85, 87, 84, 83,
-  87, 77, 78, 84, 89, 81, 90, 91, 79, 86,
-  74, 79, 62, 95, 77, 95, 81, 82, 94, 69,
-  73, 89, 85, 82, 82, 69, 75, 80, 90, 99,
-  91, 93, 75, 85, 81, 93, 82, 79, 80, 81,
-  104, 93, 100, 68, 70, 84, 75, 83, 84, 82,
-  88, 82, 78, 83, 88, 78, 92, 75, 94, 81,
-  80, 93, 84, 89, 82, 74, 92, 80, 80, 82,
-  84, 86, 79, 78, 84, 81, 84, 78, 87, 72,
-  83, 86, 81, 80, 89, 83, 79, 85, 87, 74,
-  80, 90, 88, 80, 84, 81, 78, 82, 93, 84,
-  83, 90, 89, 83, 79, 81, 90, 76, 91, 90,
-  73, 101, 77, 82, 72, 93, 81, 67, 102, 79,
-  70, 77, 75, 81, 86, 83, 86, 102, 109, 92,
-  99, 87, 71, 89, 102, 94, 78, 83, 84, 80,
-  81, 112, 82, 83, 97, 85, 86, 105, 81, 72,
-  92, 97, 81, 98, 84, 77, 84, 85, 80, 78,
-  77, 74, 72, 54, 83, 79, 93, 80, 76, 65,
-  66, 80, 104, 68, 93, 81, 92, 105, 79, 82,
-  88, 74, 81, 131, 46, 105, 78, 78, 91, 98,
-  74, 94, 88, 101, 61, 72, 96, 63, 84, 70,
-  85, 77, 79, 75, 87, 89, 73, 48, 78, 87,
-  78, 79, 87, 82, 71, 74, 84, 80, 74, 86,
-  63, 110, 103, 81, 93, 72, 91, 85, 90, 79,
-  103, 75, 80, 89, 97, 74, 46, 79, 78, 78,
-  90, 71, 75, 95, 83, 70, 88, 47, 75, 78,
-  74, 70, 77, 75, 81, 75, 79, 92, 95, 82,
-  87, 92, 84, 85, 85, 70, 82, 74, 78, 85,
-  92, 73, 123, 71, 80, 94, 88, 73, 85, 99,
-  75, 67, 82, 68, 83, 74, 99, 79, 86, 129,
-  68, 70, 79, 81, 100, 82, 89, 101, 71, 87,
-  101, 72, 93, 94, 106, 99, 80, 91, 77, 78,
-  76, 112, 96, 71, 83, 91, 84, 66, 77, 88,
-  75, 99, 72, 84, 84, 78, 87, 74, 92, 82,
-  77, 81, 107, 89, 82, 78, 87, 90, 96, 90,
-  85, 86, 94, 78, 70, 95, 79, 72, 72, 119,
-  76, 86, 88, 96, 95, 89, 90, 79, 92, 87,
-  90, 88, 83, 74, 79, 85, 82, 69, 79, 89,
-  76, 81, 83, 73, 66, 69, 78, 95, 77, 76,
-  77, 82, 70, 73, 81, 79, 78, 75, 96, 82,
-  84, 97, 89, 78, 77, 77, 76, 77, 80, 90,
-  85, 68, 97, 77, 82, 85, 87, 75, 81, 60,
-  78, 77, 91, 89, 93, 86, 79, 113, 80, 90,
-  87, 83, 86, 86, 103, 100, 89, 70, 75, 83,
-  91, 88, 96, 87, 82, 87, 82, 83, 80, 77,
-  110, 58, 88, 93, 77, 86, 82, 93, 73, 73,
-  91, 85, 79, 97, 81, 75, 83, 75, 82, 85,
-  94, 79, 94, 66, 87, 87, 88, 85, 78, 89,
-  90, 79, 80, 91, 80, 82, 82, 87, 69, 85,
-  73, 91, 84, 86, 84, 86, 79, 92, 81, 88,
-  75, 88, 108, 94, 75, 80, 76, 88, 78, 83,
-  82, 91, 88, 83, 61, 79, 75, 78, 84, 97,
-  83, 96, 87, 76, 88, 84, 78, 81, 97, 88,
-  74, 89, 80, 76, 78, 95, 83, 87, 67, 91,
-  91, 90, 84, 92, 82, 90, 87, 100, 83, 77,
-  92, 96, 79, 82, 69, 79, 87, 62, 86, 80,
-  80, 85, 91, 70, 92, 72, 80, 73, 82, 83,
-  101, 82, 82, 83, 89, 78, 75, 65, 67, 90,
-  84, 87, 72, 95, 75, 88, 83, 78, 79, 86,
-  99, 77, 84, 69, 77, 78, 82, 68, 77, 83,
-  85, 75, 76, 85, 79, 85, 84, 86, 75, 70,
-  92, 68, 78, 81, 79, 75, 72, 72, 88, 84,
-  83, 91, 90, 87, 97, 87, 72, 75, 87, 74,
-  78, 81, 78, 97, 83, 70, 77, 84, 81, 91,
-  99, 77, 80, 74, 79, 82, 81, 84, 90, 81,
-  87, 79, 83, 81, 82, 89, 84, 99, 77, 84,
-  88, 82, 74, 110, 79, 80, 85, 89, 79, 98,
-  97, 89, 79, 94, 75, 100, 88, 87, 76, 85,
-  88, 78, 75, 83, 73, 56, 83, 83, 84, 89,
-  80, 84, 97, 76, 84, 84, 87, 70, 129, 95,
-  85, 88, 77, 75, 75, 84, 72, 78, 87, 84,
-  88, 87, 79, 82, 88, 81, 71, 84, 90, 81,
-  87, 88, 84, 87, 81, 80, 92, 80, 84, 82,
-  85, 87, 74, 74, 83, 81, 69, 80, 77, 78,
-  74, 87, 77, 80, 78, 83, 90, 87, 87, 98,
-  84, 81, 92, 84, 87, 75, 84, 71, 71, 86,
-  86, 87, 82, 78, 76, 75, 83, 82, 89, 91,
-  85, 78, 73, 86, 79, 83, 86, 69, 79, 78,
-  82, 86, 91, 83, 85, 102, 91, 79, 90, 87,
-  84, 86, 82, 91, 83, 75, 79, 86, 90, 93,
-  75, 73, 82, 83, 89, 82, 78, 87, 87, 84,
-  81, 101, 77, 71, 91, 92, 88, 89, 83, 94,
-  90, 67, 79, 93, 84, 76, 94, 81, 84, 84,
-  81, 82, 72, 77, 94, 67, 85, 75, 85, 85,
-  85, 79, 86, 71, 78, 86, 83, 88, 83, 98,
-  77, 90, 83, 80, 95, 71, 85, 75, 88, 86,
-  83, 82, 82, 83, 82, 76, 75, 86, 82, 94,
-  80, 78, 79, 94, 76, 89, 84, 91, 83, 84,
-  83, 89, 86, 78, 93, 71, 93, 68, 69, 81,
-  82, 81, 73, 71, 81, 100, 89, 65, 84, 74,
-  82, 77, 56, 82, 83, 81, 77, 71, 80, 86,
-  72, 79, 103, 86, 95, 84, 85, 97, 87, 102,
-  80, 83, 78, 86, 80, 90, 89, 78, 101, 63,
-  80, 82, 106, 80, 72, 65, 75, 86, 68, 75,
-  86, 91, 69, 94, 87, 77, 87, 92, 84, 84,
-  76, 103, 96, 90, 96, 101, 74, 80, 91, 76,
-  76, 96, 86, 83, 79, 76, 68, 101, 110, 86,
-  86, 82, 72, 83, 75, 83, 90, 82, 80, 86,
-  87, 93, 93, 66, 82, 86, 79, 83, 98, 83,
-  85, 85, 71, 81, 94, 90, 66, 94, 88, 82,
-  78, 84, 85, 74, 87, 88, 75, 79, 60, 82,
-  77, 56, 81, 68, 79, 82, 80, 96, 76, 76,
-  83, 80, 86, 94, 77, 87, 72, 75, 79, 88,
-  78, 81, 88, 90, 67, 77, 70, 74, 84, 77,
-  90, 84, 88, 87, 101, 80, 77, 82, 75, 85,
-  66, 83, 80, 90, 72, 88, 91, 80, 77, 88,
-  89, 75, 84, 85, 71, 89, 82, 67, 89, 74,
-  71, 93, 86, 79, 77, 80, 68, 94, 71, 98,
-  100, 79, 67, 80, 83, 72, 88, 87, 85, 102,
-  84, 79, 80, 80, 70, 69, 86, 74, 89, 76,
-  65, 76, 91, 106, 75, 79, 88, 88, 88, 79,
-  92, 82, 71, 85, 88, 79, 89, 84, 88, 87,
-  76, 79, 84, 85, 75, 88, 97, 82, 89, 83,
-  88, 81, 100, 86, 85, 84, 65, 80, 84, 73,
-  85, 77, 83, 92, 93, 98, 82, 83, 88, 88,
-  91, 83, 89, 93, 75, 90, 80, 92, 100, 87,
-  72, 89, 74, 90, 78, 78, 91, 77, 76, 85,
-  78, 94, 99, 87, 69, 77, 96, 94, 87, 80,
-  89, 85, 78, 93, 91, 84, 79, 92, 70, 79,
-  79, 119, 86, 93, 109, 87, 80, 85, 97, 83,
-  82, 81, 84, 65, 78, 96, 76, 81, 78, 85,
-  71, 66, 101, 81, 81, 93, 90, 86, 85, 92,
-  101, 86, 91, 74, 67, 86, 80, 66, 110, 67,
-  79, 105, 80, 89, 87, 78, 75, 80, 77, 105,
-  64, 69, 91, 66, 86, 86, 87, 89, 94, 91,
-  70, 80, 88, 94, 99, 95, 93, 81, 91, 100,
-  111, 87, 102, 100, 98, 86, 98, 111, 94, 78,
-  84, 61, 71, 79, 95, 82, 67, 73, 78, 98,
-  92, 72, 91, 73, 91, 73, 49, 85, 94, 69,
-  74, 71, 78, 93, 63, 75, 118, 83, 105, 86,
-  77, 108, 88, 83, 72, 82, 74, 89, 97, 91,
-  94, 80, 92, 65, 75, 83, 105, 77, 75, 63,
-  72, 83, 65, 81, 80, 91, 78, 88, 96, 79,
-  84, 85, 70, 81, 79, 87, 83, 71, 88, 95,
-  68, 78, 86, 77, 75, 89, 80, 94, 77, 76,
-  65, 95, 100, 89, 87, 90, 76, 79, 69, 70,
-  99, 78, 67, 106, 84, 97, 91, 65, 72, 96,
-  83, 90, 91, 80, 85, 86, 73, 81, 92, 82,
-  65, 95, 83, 90, 74, 100, 88, 89, 88, 83,
-  79, 70, 59, 81, 75, 53, 75, 72, 68, 86,
-  86, 88, 82, 76, 76, 78, 81, 91, 78, 77,
-  81, 72, 90, 85, 75, 93, 108, 72, 71, 81,
-  72, 76, 73, 76, 101, 82, 82, 79, 94, 77,
-  75, 74, 69, 83, 86, 78, 88, 88, 71, 93,
-  86, 85, 72, 98, 93, 75, 81, 72, 66, 86,
-  70, 83, 82, 65, 72, 90, 88, 76, 80, 68,
-  53, 79, 71, 103, 93, 77, 83, 73, 72, 72,
-  97, 79, 83, 97, 77, 85, 77, 79, 68, 69,
-  92, 81, 92, 89, 59, 74, 82, 89, 73, 81,
-  88, 100, 84, 79, 88, 75, 74, 86, 86, 87,
-  84, 86, 85, 84, 75, 74, 73, 88, 75, 92,
-  72, 88, 81, 88, 82, 81, 101, 79, 79, 78,
-  66, 80, 78, 65, 78, 71, 71, 104, 98, 94,
-  66, 87, 100, 89, 98, 85, 92, 84, 77, 89,
-  83, 94, 114, 85, 80, 86, 74, 96, 77, 66,
-  106, 91, 79, 87, 61, 86, 108, 77, 79, 69,
-  84, 93, 83, 73, 79, 90, 71, 87, 81, 92,
-  85, 97, 65, 88, 77, 106, 88, 102, 111, 96,
-  87, 70, 101, 76, 74, 83, 90, 63, 69, 90,
-  69, 78, 84, 85, 71, 58, 119, 86, 82, 91,
-  89, 84, 83, 87, 96, 82, 104, 75, 69, 80,
-  83, 66, 106, 71, 81, 113, 80, 86, 105, 69,
-  85, 75, 81, 102, 75, 68, 93, 73, 77, 98,
-  85, 85, 100, 96, 66, 77, 96, 94, 81, 86,
-  89, 79, 79, 89, 119, 83, 102, 105, 91, 78,
-  93, 111, 88, 80, 86, 68, 79, 81, 91, 80,
-  76, 89, 83, 86, 96, 77, 86, 70, 81, 76,
-  69, 89, 83, 86, 70, 88, 74, 75, 86, 87,
-  87, 76, 90, 87, 89, 99, 81, 87, 83, 90,
-  63, 91, 90, 85, 84, 83, 88, 81, 80, 82,
-  90, 88, 78, 87, 73, 87, 83, 79, 84, 93,
-  87, 92, 93, 91, 78, 82, 93, 86, 81, 79,
-  96, 77, 91, 80, 82, 72, 81, 88, 90, 90,
-  78, 88, 78, 84, 77, 95, 78, 82, 86, 88,
-  91, 74, 84, 71, 97, 81, 86, 86, 89, 93,
-  84, 81, 72, 89, 94, 85, 84, 88, 90, 91,
-  93, 81, 83, 91, 72, 92, 83, 77, 98, 93,
-  90, 100, 104, 83, 85, 73, 73, 84, 86, 79,
-  85, 76, 60, 83, 86, 86, 86, 81, 85, 85,
-  83, 79, 84, 82, 80, 72, 80, 80, 73, 83,
-  92, 78, 67, 90, 70, 75, 84, 85, 84, 80,
-  86, 87, 90, 88, 73, 78, 82, 87, 87, 83,
-  97, 82, 80, 83, 84, 88, 78, 83, 97, 84,
-  79, 78, 70, 87, 79, 86, 86, 85, 77, 90,
-  88, 87, 83, 84, 69, 87, 72, 85, 99, 81,
-  94, 76, 72, 73, 83, 87, 87, 86, 91, 81,
-  84, 86, 68, 71, 90, 85, 84, 89, 79, 72,
-  92, 86, 82, 81, 93, 91, 83, 83, 86, 78,
-  81, 86, 90, 80, 84, 83, 81, 85, 86, 79,
-  75, 87, 69, 88, 84, 81, 96, 84, 87, 91,
-  98, 77, 90, 77, 74, 87, 82, 76, 90, 74,
-  66, 95, 92, 100, 74, 83, 93, 83, 90, 77,
-  94, 95, 71, 86, 82, 95, 88, 88, 80, 82,
-  69, 97, 83, 77, 93, 87, 77, 84, 80, 87,
-  95, 86, 82, 75, 92, 89, 87, 77, 86, 86,
-  86, 83, 86, 88, 89, 86, 80, 80, 71, 96,
-  88, 95, 109, 99, 88, 84, 87, 84, 68, 78,
-  89, 77, 77, 89, 67, 86, 83, 97, 87, 69,
-  90, 85, 87, 79, 83, 88, 90, 81, 93, 88,
-  83, 73, 91, 89, 82, 64, 97, 74, 81, 109,
-  84, 81, 106, 75, 78, 76, 87, 86, 76, 82,
-  88, 71, 85, 90, 74, 87, 95, 89, 77, 85,
-  84, 93, 96, 94, 85, 80, 84, 80, 98, 83,
-  93, 91, 85, 90, 91, 91, 85, 75, 86, 77,
-  82, 91, 91, 83, 86, 83, 84, 68, 74, 78,
-  72, 91, 82, 85, 89, 85, 81, 82, 90, 89,
-  80, 74, 78, 91, 93, 88, 84, 74, 89, 87,
-  68, 99, 85, 87, 83, 75, 85, 68, 90, 74,
-  81, 76, 96, 93, 84, 84, 101, 83, 73, 81,
-  78, 74, 89, 110, 86, 96, 79, 87, 67, 85,
-  96, 66, 84, 80, 84, 65, 87, 85, 92, 91,
-  81, 93, 80, 86, 84, 55, 93, 81, 78, 74,
-  75, 86, 86, 83, 99, 71, 95, 81, 77, 70,
-  83, 86, 87, 88, 84, 80, 78, 81, 80, 74,
-  89, 88, 110, 82, 83, 83, 93, 69, 75, 74,
-  72, 97, 92, 84, 74, 97, 89, 84, 80, 77,
-  85, 83, 75, 99, 80, 82, 77, 76, 83, 80,
-  96, 79, 92, 83, 93, 67, 71, 73, 79, 96,
-  83, 86, 92, 82, 82, 76, 79, 92, 76, 74,
-  74, 89, 81, 77, 83, 79, 89, 86, 73, 84,
-  86, 83, 80, 60, 85, 69, 85, 76, 89, 71,
-  103, 79, 91, 76, 104, 83, 68, 80, 77, 87,
-  105, 104, 90, 92, 73, 85, 63, 81, 83, 65,
-  86, 77, 81, 61, 76, 76, 95, 92, 84, 90,
-  79, 71, 86, 56, 98, 83, 82, 85, 71, 89,
-  77, 73, 99, 75, 90, 77, 78, 77, 77, 86,
-  94, 88, 84, 83, 80, 73, 76, 76, 85, 87,
-  112, 84, 88, 83, 97, 65, 76, 75, 77, 91,
-  72, 78, 70, 104, 74, 81, 62, 84, 81, 79,
-  67, 107, 81, 84, 82, 79, 84, 98, 91, 73,
-  90, 88, 76, 74, 79, 80, 72, 94, 83, 88,
-  84, 86, 86, 85, 89, 90, 83, 76, 80, 88,
-  86, 69, 80, 82, 89, 96, 86, 93, 86, 87,
-  88, 77, 83, 70, 86, 79, 80, 75, 93, 83,
-  82, 84, 90, 89, 77, 82, 82, 84, 88, 109,
-  92, 89, 77, 89, 70, 84, 99, 69, 90, 82,
-  80, 76, 82, 84, 87, 87, 82, 88, 83, 85,
-  94, 60, 91, 79, 83, 100, 82, 84, 81, 88,
-  96, 79, 97, 79, 74, 74, 77, 88, 86, 87,
-  83, 82, 88, 77, 83, 75, 90, 86, 105, 86,
-  85, 81, 97, 71, 81, 89, 77, 95, 80, 86,
-  77, 101, 71, 90, 80, 79, 81, 79, 77, 92,
-  80, 77, 84, 84, 82, 96, 88, 84, 81, 81,
-  89, 58, 69, 77, 64, 99, 81, 84, 89, 81,
-  67, 84, 87, 93, 78, 72, 89, 85, 95, 92,
-  86, 79, 83, 86, 81, 98, 86, 91, 82, 79,
-  87, 68, 86, 76, 75, 83, 99, 92, 86, 74,
-  105, 80, 79, 77, 77, 79, 88, 119, 80, 99,
-  81, 86, 64, 83, 88, 65, 83, 79, 87, 68,
-  93, 76, 106, 85, 84, 93, 77, 91, 90, 56,
-  102, 88, 86, 72, 74, 82, 85, 68, 111, 75,
-  105, 84, 67, 66, 87, 74, 85, 85, 89, 83,
-  70, 88, 83, 79, 90, 89, 108, 82, 87, 82,
-  88, 69, 85, 78, 77, 88, 99, 75, 77, 85,
-  93, 81, 92, 77, 86, 84, 80, 100, 75, 86,
-  74, 81, 82, 81, 106, 84, 80, 80, 98, 49,
-  64, 77, 75, 105, 79, 92, 95, 79, 71, 77,
-  80, 100, 74, 75, 92, 83, 98, 85, 87, 81,
-  92, 80, 85, 81, 84, 92, 79, 65, 85, 69,
-  77, 75, 86, 79, 107, 79, 96, 64, 122, 73,
-  72, 75, 70, 87, 103, 118, 78, 100, 76, 81,
-  58, 77, 78, 60, 88, 78, 83, 66, 85, 65,
-  110, 84, 87, 93, 82, 65, 90, 55, 105, 96,
-  91, 84, 72, 88, 78, 53, 125, 83, 108, 76,
-  70, 69, 83, 75, 93, 85, 84, 77, 65, 74,
-  79, 82, 86, 86, 115, 81, 106, 85, 101, 64,
-  85, 79, 78, 86, 77, 68, 72, 93, 83, 80,
-  71, 83, 78, 82, 73, 116, 74, 87, 81, 82,
-  83, 96, 83, 73, 82, 88, 81, 63, 74, 88,
-  68, 102, 81, 85, 86, 86, 80, 85, 89, 95,
-  82, 73, 88, 82, 83, 78, 85, 87, 83, 90,
-  91, 91, 86, 93, 88, 76, 87, 71, 74, 78,
-  76, 77, 96, 87, 88, 72, 98, 83, 79, 78,
-  74, 82, 85, 115, 85, 90, 80, 85, 68, 83,
-  87, 66, 95, 84, 84, 78, 89, 73, 99, 81,
-  89, 88, 83, 78, 97, 59, 98, 91, 86, 100,
-  82, 84, 80, 75, 107, 82, 101, 77, 65, 70,
-  76, 76, 84, 82, 83, 81, 77, 73, 83, 81,
-  91, 86, 108, 87, 89, 79, 91, 67, 89, 89,
-  86, 94, 82, 77, 79, 91, 74, 85, 90, 79,
-  81, 82, 83, 94, 87, 80, 80, 82, 84, 95,
-  89, 90, 79, 80, 94, 76, 74, 81, 63, 95,
-  86, 88, 83, 82, 68, 84, 89, 85, 78, 69,
-  78, 76, 80, 96, 80, 78, 78, 83, 93, 95,
-  93, 84, 86, 85, 85, 69, 84, 80, 67, 85,
-  84, 100, 79, 75, 94, 81, 81, 73, 80, 81,
-  79, 109, 86, 90, 85, 87, 68, 83, 86, 80,
-  84, 81, 86, 78, 87, 81, 95, 86, 100, 85,
-  81, 90, 87, 62, 95, 87, 83, 74, 84, 81,
-  88, 82, 98, 81, 95, 87, 68, 69, 84, 73,
-  85, 84, 85, 71, 79, 93, 86, 83, 89, 78,
-  102, 80, 81, 78, 81, 80, 91, 85, 70, 86,
-  97, 77, 82, 78, 85, 86, 88, 74, 82, 92,
-  83, 93, 83, 82, 68, 83, 86, 84, 99, 94,
-  71, 79, 105, 70, 66, 77, 75, 97, 79, 93,
-  92, 84, 70, 81, 81, 91, 80, 76, 82, 74,
-  75, 90, 80, 83, 83, 76, 91, 85, 84, 86,
-  82, 77, 83, 71, 73, 81, 73, 79, 91, 83,
-  84, 72, 109, 76, 72, 72, 74, 82, 87, 103,
-  87, 89, 82, 85, 64, 75, 79, 73, 96, 80,
-  83, 73, 87, 75, 97, 84, 102, 88, 80, 74,
-  78, 66, 96, 89, 85, 78, 84, 82, 83, 70,
-  104, 85, 100, 75, 69, 71, 80, 68, 92, 81,
-  73, 68, 64, 83, 82, 83, 83, 77, 111, 81,
-  94, 82, 89, 77, 95, 82, 66, 89, 84, 69,
-  77, 81, 80, 83, 85, 80, 78, 87, 76, 105,
-  84, 74, 82, 84, 86, 96, 85, 88, 80, 84,
-  88, 83, 76, 85, 67, 98, 85, 91, 87, 88,
-  82, 87, 89, 87, 90, 70, 79, 76, 77, 86,
-  82, 86, 77, 84, 96, 93, 91, 84, 88, 82,
-  86, 72, 72, 80, 72, 84, 86, 82, 82, 74,
-  91, 81, 80, 72, 76, 85, 80, 109, 89, 82,
-  85, 86, 72, 88, 83, 82, 98, 83, 84, 91,
-  91, 80, 92, 84, 101, 84, 83, 92, 87, 65,
-  92, 90, 88, 90, 88, 81, 85, 86, 95, 86,
-  96, 78, 67, 71, 81, 73, 87, 82, 73, 75,
-  82, 70, 87, 84, 91, 78, 103, 85, 83, 76,
-  81, 76, 94, 90, 79, 93, 83, 78, 82, 81,
-  78, 88, 83, 75, 78, 92, 82, 88, 83, 87,
-  116, 94, 88, 81, 94, 83, 87, 87, 65, 87,
-  81, 104, 76, 73, 78, 51, 93, 84, 80, 97,
-  73, 77, 90, 82, 91, 81, 96, 84, 106, 103,
-  79, 75, 71, 91, 97, 92, 77, 81, 82, 57,
-  85, 99, 63, 98, 77, 68, 74, 84, 91, 93,
-  81, 77, 80, 87, 74, 82, 101, 80, 82, 79,
-  78, 73, 88, 65, 75, 81, 88, 73, 74, 65,
-  86, 83, 75, 76, 89, 84, 89, 70, 93, 82,
-  80, 80, 74, 95, 88, 81, 95, 84, 78, 75,
-  92, 87, 84, 81, 79, 79, 79, 79, 81, 77,
-  91, 76, 82, 104, 93, 97, 85, 79, 81, 80,
-  74, 77, 91, 111, 104, 75, 86, 122, 88, 84,
-  92, 72, 93, 86, 67, 72, 73, 94, 92, 88,
-  82, 84, 99, 85, 81, 94, 67, 86, 75, 93,
-  76, 74, 74, 45, 78, 81, 96, 79, 80, 81,
-  82, 81, 85, 81, 95, 79, 106, 99, 77, 80,
-  75, 88, 90, 84, 89, 78, 88, 46, 94, 89,
-  64, 102, 73, 77, 71, 90, 93, 88, 80, 75,
-  87, 99, 84, 83, 119, 74, 77, 81, 75, 72,
-  87, 68, 65, 75, 79, 68, 104, 55, 88, 89,
-  72, 89, 83, 80, 102, 77, 96, 85, 80, 78,
-  62, 91, 91, 80, 91, 95, 73, 78, 95, 79,
-  92, 81, 74, 77, 86, 83, 74, 73, 84, 76,
-  95, 106, 101, 89, 72, 79, 73, 85, 76, 87,
-  92, 114, 94, 78, 88, 140, 82, 77, 95, 72,
-  93, 92, 63, 67, 91, 93, 71, 92, 87, 75,
-  97, 92, 83, 89, 69, 81, 95, 81, 81, 72,
-  76, 59, 95, 80, 93, 80, 90, 83, 88, 83,
-  90, 84, 91, 76, 96, 103, 82, 96, 76, 88,
-  98, 92, 99, 81, 83, 58, 80, 97, 68, 92,
-  76, 87, 73, 87, 93, 83, 82, 77, 83, 90,
-  73, 88, 104, 79, 84, 78, 85, 76, 84, 70,
-  73, 85, 83, 71, 107, 66, 89, 83, 75, 75,
-  83, 82, 98, 70, 94, 79, 78, 83, 74, 86,
-  83, 84, 86, 94, 80, 73, 88, 89, 90, 79,
-  80, 84, 85, 73, 79, 85, 93, 76, 87, 102,
-  99, 92, 87, 80, 68, 83, 74, 92, 92, 103,
-  86, 75, 88, 114, 73, 81, 99, 76, 94, 78,
-  70, 77, 71, 85, 88, 79, 89, 90, 106, 84,
-  75, 89, 86, 91, 80, 85, 84, 72, 77, 77,
-  85, 88, 94, 85, 72, 67, 84, 95, 82, 85,
-  84, 76, 97, 74, 84, 77, 78, 92, 77, 81,
-  75, 76, 81, 66, 81, 90, 81, 92, 73, 75,
-  93, 78, 81, 89, 75, 86, 79, 71, 83, 70,
-  93, 91, 79, 87, 69, 76, 86, 81, 79, 94,
-  85, 70, 73, 71, 96, 84, 89, 75, 75, 87,
-  81, 71, 87, 83, 75, 79, 81, 84, 90, 70,
-  81, 74, 99, 80, 95, 97, 73, 88, 89, 87,
-  84, 84, 76, 78, 80, 82, 84, 76, 95, 93,
-  102, 69, 82, 87, 90, 87, 88, 102, 111, 76,
-  94, 95, 85, 76, 78, 79, 78, 93, 73, 76,
-  66, 94, 75, 71, 90, 79, 112, 81, 73, 88,
-  92, 94, 81, 75, 79, 75, 79, 89, 86, 87,
-  102, 57, 73, 65, 83, 98, 70, 87, 83, 79,
-  104, 80, 83, 81, 77, 84, 66, 74, 74, 70,
-  76, 61, 100, 92, 87, 110, 76, 81, 95, 76,
-  80, 77, 64, 83, 84, 79, 88, 70, 81, 103,
-  75, 87, 69, 78, 68, 69, 76, 102, 77, 66,
-  84, 75, 93, 88, 93, 76, 70, 77, 83, 81,
-  86, 86, 82, 80, 81, 82, 89, 69, 72, 89,
-  96, 80, 83, 108, 76, 93, 87, 84, 79, 84,
-  70, 82, 71, 85, 101, 65, 103, 90, 105, 68,
-  88, 95, 90, 83, 83, 96, 99, 84, 104, 86,
-  74, 81, 81, 79, 71, 97, 74, 78, 78, 83,
-  75, 78, 85, 76, 104, 85, 81, 90, 87, 90,
-  80, 76, 84, 71, 76, 79, 88, 84, 85, 79,
-  85, 72, 86, 94, 77, 90, 81, 85, 86, 80,
-  84, 87, 79, 84, 73, 81, 80, 74, 84, 64,
-  89, 88, 82, 94, 80, 92, 92, 76, 87, 85,
-  73, 84, 80, 91, 86, 79, 97, 90, 76, 86,
-  76, 79, 89, 86, 77, 95, 81, 72, 97, 72,
-  95, 83, 88, 77, 72, 83, 89, 72, 87, 84,
-  75, 85, 79, 81, 87, 76, 81, 83, 101, 78,
-  93, 95, 81, 82, 89, 88, 78, 80, 79, 83,
-  79, 83, 87, 79, 101, 89, 98, 76, 80, 81,
-  86, 90, 86, 93, 89, 78, 93, 93, 69, 76,
-  84, 84, 79, 86, 76, 78, 85, 86, 87, 78,
-  88, 98, 94, 82, 75, 89, 82, 89, 80, 70,
-  85, 67, 64, 84, 93, 83, 82, 82, 77, 67,
-  86, 99, 85, 86, 86, 84, 77, 76, 88, 84,
-  79, 92, 86, 76, 83, 79, 74, 84, 75, 87,
-  97, 90, 90, 88, 97, 74, 74, 87, 71, 78,
-  81, 84, 76, 79, 70, 81, 89, 86, 85, 83,
-  91, 96, 86, 88, 83, 84, 91, 89, 94, 84,
-  97, 73, 66, 80, 84, 82, 78, 90, 80, 82,
-  92, 78, 83, 81, 78, 78, 82, 80, 83, 97,
-  73, 89, 95, 89, 81, 81, 85, 91, 82, 85,
-  81, 83, 96, 85, 100, 80, 91, 90, 90, 91,
-  77, 89, 99, 78, 90, 82, 84, 80, 60, 86,
-  76, 88, 84, 85, 81, 91, 90, 71, 91, 91,
-  91, 80, 71, 87, 89, 91, 92, 74, 86, 72,
-  73, 91, 93, 81, 82, 66, 80, 71, 84, 98,
-  80, 86, 78, 83, 75, 70, 99, 94, 86, 84,
-  79, 74, 74, 79, 74, 80, 79, 91, 106, 91,
-  90, 93, 97, 73, 74, 83, 64, 79, 78, 78,
-  77, 78, 58, 96, 90, 78, 80, 82, 81, 90,
-  86, 90, 81, 89, 87, 95, 84, 81, 97, 73,
-  62, 87, 74, 93, 77, 96, 84, 84, 98, 81,
-  86, 84, 74, 81, 83, 80, 73, 103, 74, 86,
-  97, 88, 84, 90, 86, 95, 76, 85, 78, 78,
-  110, 85, 103, 82, 100, 91, 83, 83, 80, 84,
-  99, 88, 94, 67, 75, 83, 67, 84, 77, 85,
-  80, 91, 88, 76, 86, 78, 87, 79, 96, 84,
-  76, 90, 82, 87, 79, 85, 87, 65, 67, 80,
-  91, 77, 78, 87, 91, 71, 79, 95, 81, 87,
-  76, 79, 79, 75, 84, 91, 87, 88, 81, 79,
-  71, 78, 79, 83, 82, 88, 96, 88, 93, 89,
-  97, 72, 78, 90, 72, 74, 82, 78, 77, 82,
-  76, 79, 89, 88, 85, 84, 94, 96, 81, 89,
-  83, 84, 90, 85, 93, 83, 92, 73, 70, 91,
-  82, 82, 78, 88, 76, 87, 90, 73, 91, 83,
-  79, 85, 81, 81, 81, 95, 80, 82, 96, 89,
-  88, 79, 83, 88, 82, 85, 80, 85, 97, 82,
-  97, 79, 94, 91, 86, 84, 85, 92, 94, 79,
-  94, 81, 75, 84, 70, 89, 78, 87, 85, 81,
-  77, 84, 87, 87, 79, 93, 81, 86, 92, 89,
-  92, 81, 83, 85, 64, 95, 86, 84, 89, 87,
-  69, 88, 83, 91, 85, 76, 85, 91, 83, 78,
-  81, 86, 86, 95, 83, 90, 90, 81, 85, 88,
-  74, 86, 68, 85, 83, 79, 86, 86, 74, 93,
-  86, 80, 89, 75, 94, 85, 83, 100, 89, 81,
-  85, 82, 76, 100, 84, 89, 89, 84, 86, 88,
-  82, 81, 91, 78, 80, 94, 78, 101, 81, 84,
-  74, 85, 90, 88, 84, 92, 80, 79, 94, 80,
-  92, 94, 93, 75, 93, 71, 77, 84, 76, 98,
-  98, 88, 88, 87, 77, 72, 64, 88, 81, 83,
-  63, 79, 82, 73, 81, 80, 84, 90, 75, 65,
-  85, 85, 77, 82, 94, 94, 88, 93, 78, 90,
-  91, 84, 83, 82, 90, 79, 83, 89, 83, 80,
-  82, 92, 67, 88, 88, 83, 70, 85, 74, 81,
-  79, 90, 81, 73, 81, 78, 83, 79, 78, 77,
-  84, 91, 81, 85, 82, 79, 86, 89, 68, 88,
-  73, 96, 96, 73, 82, 85, 64, 92, 81, 88,
-  90, 66, 91, 88, 77, 97, 93, 74, 87, 69,
-  78, 95, 93, 80, 92, 86, 83, 108, 85, 88,
-  90, 79, 75, 87, 70, 85, 79, 84, 81, 82,
-  88, 86, 89, 98, 79, 85, 99, 85, 84, 88,
-  91, 67, 92, 80, 73, 82, 79, 95, 95, 89,
-  82, 86, 62, 78, 73, 87, 79, 92, 68, 82,
-  75, 74, 81, 87, 89, 92, 71, 66, 85, 75,
-  74, 81, 96, 102, 79, 81, 78, 85, 88, 87,
-  81, 83, 76, 86, 92, 92, 89, 82, 84, 81,
-  63, 91, 86, 80, 85, 84, 67, 85, 91, 91,
-  84, 70, 85, 94, 75, 84, 84, 80, 86, 88,
-  83, 82, 89, 86, 88, 82, 78, 82, 69, 85,
-  88, 79, 87, 99, 69, 92, 84, 81, 89, 76,
-  93, 84, 78, 99, 87, 83, 87, 82, 78, 94,
-  81, 84, 90, 93, 80, 88, 85, 84, 96, 78,
-  80, 93, 81, 86, 81, 80, 79, 80, 81, 83,
-  85, 96, 77, 81, 94, 80, 90, 94, 92, 74,
-  95, 76, 78, 81, 84, 95, 100, 82, 87, 86,
-  73, 76, 61, 89, 80, 83, 66, 79, 79, 84,
-  83, 85, 89, 85, 72, 72, 88, 86, 80, 82,
-  92, 96, 85, 87, 77, 85, 102, 87, 86, 90,
-  91, 79, 74, 85, 76, 84, 82, 100, 67, 91,
-  84, 80, 64, 90, 74, 78, 78, 93, 83, 77,
-  86, 79, 106, 85, 92, 85, 80, 94, 88, 97,
-  84, 70, 82, 95, 77, 94, 100, 93, 89, 85,
-  80, 79, 80, 82, 81, 79, 90, 67, 73, 88,
-  83, 93, 89, 76, 89, 75, 69, 91, 84, 83,
-  80, 80, 77, 90, 81, 76, 92, 97, 78, 84,
-  83, 107, 80, 79, 84, 74, 89, 90, 79, 93,
-  84, 85, 89, 86, 74, 90, 92, 76, 70, 85,
-  85, 77, 75, 90, 87, 88, 81, 86, 87, 75,
-  78, 87, 80, 82, 76, 91, 70, 75, 86, 84,
-  85, 98, 80, 83, 79, 65, 68, 87, 91, 88,
-  71, 78, 73, 87, 84, 76, 80, 76, 104, 73,
-  61, 83, 73, 85, 75, 95, 69, 101, 82, 79,
-  32, 85, 97, 70, 66, 89, 70, 72, 76, 56,
-  125, 90, 105, 80, 78, 92, 88, 88, 65, 62,
-  87, 90, 92, 88, 100, 102, 112, 84, 67, 93,
-  72, 87, 83, 75, 87, 60, 60, 85, 80, 89,
-  99, 76, 86, 58, 66, 90, 77, 81, 81, 91,
-  69, 75, 75, 73, 101, 107, 72, 79, 80, 93,
-  84, 74, 97, 68, 78, 84, 78, 101, 86, 76,
-  93, 96, 64, 82, 86, 69, 64, 102, 75, 73,
-  71, 76, 79, 90, 63, 85, 97, 82, 91, 82,
-  69, 89, 87, 100, 64, 81, 79, 107, 82, 111,
-  77, 100, 80, 55, 61, 83, 80, 91, 64, 65,
-  75, 80, 84, 83, 81, 75, 90, 79, 70, 83,
-  75, 83, 87, 76, 73, 90, 84, 80, 55, 87,
-  100, 72, 83, 89, 78, 74, 84, 73, 105, 91,
-  101, 84, 78, 89, 88, 78, 80, 76, 96, 90,
-  90, 89, 79, 97, 96, 90, 81, 108, 78, 80,
-  84, 81, 88, 71, 67, 90, 77, 88, 91, 78,
-  86, 70, 67, 88, 89, 82, 80, 91, 71, 77,
-  92, 74, 99, 96, 74, 77, 83, 87, 79, 78,
-  90, 74, 78, 80, 79, 94, 79, 83, 92, 88,
-  69, 91, 84, 77, 82, 96, 82, 76, 78, 86,
-  86, 86, 77, 84, 94, 86, 75, 90, 75, 84,
-  89, 91, 72, 89, 85, 92, 88, 90, 77, 92,
-  82, 62, 69, 82, 90, 88, 72, 73, 89, 91,
-  86, 90, 82, 73, 79, 76, 79, 81, 80, 83,
-  88, 93, 72, 84, 76, 87, 90, 89, 86, 90,
-  95, 86, 82, 81, 88, 89, 74, 87, 88, 93,
-  81, 87, 78, 111, 83, 80, 85, 85, 83, 81,
-  92, 84, 95, 86, 84, 84, 83, 80, 85, 70,
-  80, 86, 73, 81, 91, 89, 82, 78, 81, 80,
-  88, 86, 74, 82, 62, 89, 78, 81, 86, 84,
-  103, 102, 88, 89, 89, 98, 73, 71, 90, 75,
-  82, 89, 81, 92, 80, 88, 81, 84, 71, 79,
-  93, 87, 65, 83, 92, 81, 79, 82, 86, 85,
-  79, 81, 81, 86, 83, 92, 87, 80, 93, 99,
-  74, 87, 74, 80, 82, 89, 85, 85, 78, 74,
-  67, 83, 91, 83, 78, 83, 83, 87, 77, 77,
-  84, 77, 87, 70, 67, 78, 78, 82, 77, 89,
-  74, 90, 69, 100, 78, 87, 102, 82, 73, 74,
-  71, 75, 91, 72, 106, 89, 103, 95, 75, 89,
-  85, 106, 71, 87, 92, 66, 101, 80, 105, 98,
-  105, 100, 72, 98, 93, 67, 82, 64, 73, 83,
-  61, 85, 92, 80, 68, 75, 72, 81, 98, 90,
-  73, 76, 60, 96, 68, 66, 86, 88, 105, 117,
-  81, 75, 91, 98, 79, 62, 96, 74, 80, 91,
-  80, 94, 83, 82, 78, 88, 78, 73, 82, 89,
-  59, 96, 91, 76, 76, 66, 81, 78, 75, 78,
-  120, 80, 88, 94, 81, 68, 122, 113, 73, 80,
-  71, 84, 85, 104, 83, 104, 77, 68, 55, 75,
-  80, 75, 80, 74, 88, 73, 77, 88, 83, 89,
-  79, 76, 75, 78, 83, 82, 88, 76, 75, 83,
-  75, 88, 92, 85, 94, 87, 67, 81, 79, 81,
-  88, 79, 74, 87, 88, 104, 79, 92, 82, 88,
-  76, 84, 90, 77, 92, 83, 81, 88, 92, 88,
-  84, 98, 87, 72, 87, 71, 77, 93, 73, 86,
-  92, 87, 76, 82, 77, 87, 95, 89, 76, 84,
-  69, 97, 75, 72, 85, 83, 104, 100, 78, 87,
-  87, 89, 73, 73, 95, 77, 80, 89, 84, 93,
-  89, 94, 78, 83, 74, 81, 87, 91, 79, 86,
-  92, 82, 82, 84, 84, 83, 78, 77, 92, 88,
-  80, 91, 86, 78, 107, 93, 77, 83, 78, 84,
-  92, 87, 82, 85, 74, 74, 72, 78, 96, 76,
-  78, 78, 94, 63, 81, 85, 83, 73, 71, 77,
-  88, 83, 91, 81, 83, 72, 85, 68, 73, 81,
-  85, 101, 81, 82, 85, 71, 95, 89, 87, 83,
-  93, 89, 78, 86, 80, 83, 72, 81, 80, 79,
-  90, 73, 85, 78, 77, 89, 92, 73, 77, 67,
-  79, 82, 69, 88, 84, 80, 85, 79, 73, 84,
-  74, 79, 99, 75, 88, 82, 92, 74, 69, 88,
-  88, 76, 73, 100, 85, 78, 84, 110, 95, 71,
-  78, 76, 81, 88, 85, 100, 103, 81, 89, 84,
-  86, 89, 74, 91, 85, 80, 84, 83, 78, 83,
-  80, 75, 87, 75, 86, 89, 84, 81, 76, 102,
-  81, 107, 83, 83, 94, 79, 77, 91, 81, 69,
-  70, 70, 88, 95, 88, 98, 98, 98, 90, 74,
-  97, 72, 68, 85, 88, 74, 72, 77, 83, 89,
-  98, 78, 81, 82, 83, 66, 76, 86, 93, 105,
-  79, 83, 83, 74, 89, 96, 84, 84, 86, 81,
-  80, 84, 73, 92, 76, 79, 76, 72, 77, 67,
-  79, 76, 80, 88, 95, 73, 70, 67, 83, 74,
-  59, 80, 79, 76, 94, 74, 79, 92, 67, 81,
-  111, 87, 90, 85, 89, 79, 61, 98, 95, 84,
-  72, 105, 94, 80, 91, 116, 94, 72, 86, 77,
-  78, 84, 80, 87, 120, 71, 78, 94, 85, 93,
-  72, 100, 92, 91, 93, 88, 78, 78, 86, 74,
-  93, 87, 89, 92, 83, 85, 77, 99, 87, 102,
-  80, 88, 97, 85, 83, 94, 65, 75, 69, 67,
-  83, 91, 77, 96, 97, 96, 98, 71, 91, 83,
-  64, 84, 83, 90, 73, 77, 93, 84, 81, 80,
-  84, 92, 86, 67, 73, 78, 81, 91, 86, 90,
-  76, 73, 76, 86, 93, 85, 95, 69, 72, 82,
-  85, 84, 79, 88, 72, 90, 81, 79, 84, 85,
-  86, 86, 86, 65, 79, 85, 76, 82, 75, 84,
-  84, 86, 88, 79, 79, 77, 77, 76, 91, 74,
-  90, 70, 87, 75, 67, 85, 93, 77, 83, 89,
-  85, 76, 85, 95, 94, 83, 85, 78, 79, 88,
-  90, 88, 93, 73, 86, 80, 88, 89, 78, 90,
-  84, 81, 84, 83, 76, 82, 86, 76, 81, 75,
-  86, 88, 87, 87, 87, 93, 82, 108, 84, 81,
-  92, 99, 73, 83, 76, 73, 75, 77, 91, 93,
-  91, 90, 90, 93, 88, 86, 97, 66, 70, 84,
-  89, 84, 79, 90, 85, 97, 105, 78, 69, 81,
-  83, 73, 90, 85, 92, 110, 76, 76, 87, 77,
-  90, 86, 81, 84, 82, 84, 68, 70, 76, 102,
-  89, 78, 78, 71, 75, 65, 88, 93, 85, 82,
-  93, 71, 86, 79, 81, 85, 70, 88, 75, 79,
-  85, 74, 82, 92, 75, 95, 98, 71, 71, 86,
-  99, 75, 60, 96, 92, 74, 87, 120, 76, 76,
-  87, 118, 99, 80, 76, 91, 77, 82, 77, 101,
-  102, 69, 97, 82, 83, 73, 76, 74, 77, 100,
-  101, 103, 85, 72, 88, 77, 93, 90, 93, 94,
-  83, 84, 75, 100, 76, 96, 75, 79, 102, 81,
-  72, 94, 82, 85, 70, 70, 82, 98, 83, 103,
-  111, 71, 110, 74, 101, 71, 77, 89, 95, 85,
-  80, 87, 81, 117, 118, 75, 74, 76, 82, 75,
-  96, 81, 105, 125, 78, 75, 85, 81, 94, 93,
-  76, 86, 72, 93, 80, 72, 63, 107, 85, 81,
-  76, 77, 82, 57, 87, 101, 77, 85, 101, 73,
-  76, 74, 92, 81, 53, 90, 69, 71, 94, 76,
-  85, 96, 67, 95, 111, 75, 64, 95, 88, 85,
-  63, 109, 91, 82, 70, 137, 77, 73, 96, 125,
-  109, 85, 77, 96, 73, 78, 71, 81, 126, 72,
-  74, 97, 83, 76, 70, 73, 84, 113, 97, 112,
-  88, 58, 88, 76, 91, 89, 107, 95, 84, 87,
-  72, 103, 80, 88, 76, 78, 112, 79, 77, 103,
-  73, 95, 71, 72, 77, 97, 72, 112, 106, 68,
-  123, 70, 92, 73, 86, 83, 81, 99, 79, 85,
-  94, 90, 89, 76, 70, 79, 79, 74, 84, 84,
-  81, 103, 86, 82, 82, 75, 78, 79, 84, 82,
-  84, 86, 64, 73, 84, 79, 83, 93, 76, 78,
-  84, 73, 86, 92, 75, 81, 89, 71, 95, 84,
-  80, 86, 75, 91, 76, 82, 90, 73, 81, 80,
-  80, 81, 89, 71, 76, 64, 93, 79, 71, 94,
-  91, 80, 72, 104, 85, 76, 88, 105, 100, 93,
-  72, 87, 77, 82, 81, 93, 87, 81, 85, 82,
-  81, 79, 82, 78, 79, 82, 87, 92, 82, 77,
-  87, 77, 91, 72, 88, 92, 81, 86, 81, 89,
-  78, 100, 84, 79, 96, 98, 70, 95, 86, 84,
-  74, 74, 92, 96, 88, 94, 99, 78, 99, 90,
-  91, 76, 68, 86, 80, 71, 83, 101, 94, 85,
-  86, 84, 69, 88, 84, 79, 85, 82, 81, 89,
-  84, 88, 67, 70, 78, 80, 96, 82, 86, 73,
-  64, 75, 89, 84, 90, 85, 75, 76, 81, 71,
-  91, 77, 81, 82, 78, 75, 88, 89, 73, 93,
-  78, 90, 80, 93, 88, 73, 78, 90, 86, 84,
-  88, 73, 83, 86, 95, 76, 71, 84, 93, 81,
-  89, 84, 85, 74, 80, 94, 85, 72, 94, 72,
-  80, 87, 87, 86, 95, 76, 88, 70, 82, 87,
-  80, 80, 72, 83, 98, 79, 82, 86, 94, 79,
-  88, 90, 90, 95, 91, 77, 69, 88, 67, 95,
-  75, 88, 90, 80, 84, 78, 73, 75, 72, 82,
-  80, 97, 90, 86, 98, 81, 97, 81, 93, 76,
-  77, 83, 82, 69, 85, 95, 90, 88, 90, 82,
-  70, 82, 87, 79, 93, 83, 88, 94, 85, 81,
-  71, 73, 81, 83, 95, 80, 80, 93, 70, 71,
-  91, 80, 84, 80, 70, 72, 89, 62, 102, 72,
-  83, 83, 90, 85, 86, 74, 78, 95, 66, 89,
-  76, 86, 91, 77, 82, 91, 80, 87, 98, 84,
-  83, 90, 79, 79, 80, 97, 85, 95, 69, 84,
-  89, 71, 77, 95, 89, 74, 94, 69, 77, 84,
-  82, 86, 103, 88, 75, 80, 82, 94, 85, 79,
-  79, 89, 100, 83, 85, 87, 83, 76, 91, 77,
-  93, 96, 90, 80, 73, 88, 73, 98, 78, 99,
-  94, 78, 81, 95, 71, 77, 72, 88, 88, 96,
-  82, 89, 99, 87, 102, 85, 84, 84, 94, 84,
-  87, 76, 83, 88, 103, 80, 85, 79, 75, 75,
-  76, 79, 81, 77, 79, 90, 81, 94, 76, 74,
-  79, 82, 92, 80, 88, 95, 72, 73, 88, 73,
-  74, 85, 81, 78, 91, 76, 86, 78, 80, 82,
-  79, 74, 95, 78, 77, 94, 83, 96, 81, 94,
-  89, 81, 80, 87, 89, 82, 87, 71, 79, 75,
-  88, 81, 86, 78, 86, 84, 66, 82, 84, 73,
-  79, 88, 86, 88, 73, 77, 80, 90, 87, 97,
-  87, 93, 73, 78, 87, 87, 82, 79, 74, 79,
-  88, 80, 80, 86, 87, 81, 89, 70, 88, 92,
-  94, 85, 80, 87, 77, 97, 83, 81, 89, 81,
-  82, 88, 82, 75, 75, 84, 95, 96, 89, 82,
-  98, 87, 89, 85, 72, 84, 82, 82, 83, 88,
-  82, 71, 89, 65, 76, 69, 90, 83, 85, 68,
-  81, 79, 81, 81, 72, 92, 90, 94, 78, 79,
-  93, 65, 81, 80, 81, 89, 83, 88, 92, 77,
-  90, 101, 86, 75, 87, 92, 83, 69, 72, 80,
-  93, 89, 83, 70, 85, 98, 94, 112, 84, 73,
-  86, 80, 68, 89, 81, 96, 82, 67, 76, 100,
-  69, 76, 97, 81, 72, 89, 87, 73, 98, 80,
-  78, 103, 84, 88, 87, 91, 78, 82, 76, 78,
-  117, 79, 98, 84, 57, 86, 83, 98, 82, 83,
-  80, 74, 87, 86, 76, 82, 73, 79, 77, 76,
-  88, 84, 81, 96, 92, 83, 94, 77, 83, 73,
-  78, 87, 78, 103, 85, 90, 77, 79, 92, 105,
-  95, 94, 74, 87, 83, 89, 82, 89, 84, 75,
-  83, 79, 73, 81, 90, 79, 82, 81, 84, 73,
-  78, 87, 57, 90, 68, 83, 95, 80, 92, 80,
-  80, 82, 71, 100, 88, 85, 76, 64, 92, 97,
-  93, 80, 78, 86, 97, 81, 79, 79, 96, 80,
-  87, 72, 84, 95, 90, 96, 84, 78, 85, 77,
-  75, 89, 90, 88, 82, 60, 67, 81, 73, 90,
-  87, 83, 79, 88, 85, 66, 90, 77, 82, 98,
-  74, 87, 88, 88, 78, 83, 78, 75, 102, 78,
-  88, 80, 65, 83, 85, 95, 72, 73, 85, 85,
-  77, 73, 65, 78, 81, 82, 73, 88, 89, 86,
-  94, 85, 86, 79, 87, 65, 80, 89, 76, 93,
-  70, 87, 79, 83, 89, 86, 84, 88, 76, 93,
-  83, 79, 84, 82, 83, 89, 83, 81, 84, 93,
-  79, 93, 78, 78, 65, 87, 90, 68, 77, 93,
-  72, 83, 69, 83, 98, 86, 90, 87, 71, 74,
-  71, 97, 86, 87, 74, 64, 94, 80, 82, 82,
-  79, 76, 94, 84, 95, 76, 98, 92, 80, 80,
-  84, 88, 88, 80, 83, 84, 82, 86, 85, 88,
-  93, 88, 85, 66, 78, 80, 69, 110, 82, 85,
-  85, 88, 91, 71, 78, 85, 92, 90, 77, 76,
-  88, 85, 90, 86, 92, 73, 106, 87, 88, 79,
-  80, 94, 100, 91, 87, 81, 78, 91, 80, 73,
-  73, 92, 95, 85, 69, 104, 94, 86, 85, 78,
-  89, 85, 80, 64, 87, 100, 82, 102, 82, 84,
-  80, 80, 86, 91, 82, 84, 66, 84, 77, 83,
-  88, 85, 92, 84, 84, 84, 90, 65, 76, 71,
-  90, 81, 85, 80, 77, 78, 86, 81, 70, 85,
-  74, 94, 79, 81, 93, 70, 107, 84, 83, 93,
-  88, 87, 80, 74, 81, 102, 96, 75, 77, 87,
-  90, 69, 79, 87, 88, 84, 85, 74, 82, 98,
-  88, 109, 89, 80, 77, 88, 62, 78, 80, 89,
-  81, 67, 66, 95, 84, 69, 99, 75, 76, 74,
-  95, 81, 96, 77, 76, 101, 79, 90, 86, 83,
-  71, 93, 81, 87, 118, 87, 93, 82, 57, 87,
-  70, 99, 80, 80, 90, 86, 75, 87, 71, 78,
-  73, 82, 84, 81, 86, 78, 82, 97, 98, 90,
-  95, 73, 72, 69, 73, 78, 76, 85, 84, 91,
-  76, 70, 92, 96, 98, 92, 72, 86, 90, 85,
-  86, 90, 89, 81, 80, 80, 72, 83, 85, 78,
-  81, 87, 80, 76, 85, 88, 59, 94, 58, 78,
-  99, 83, 91, 83, 106, 77, 70, 100, 87, 83,
-  73, 61, 82, 91, 94, 78, 82, 91, 103, 82,
-  79, 87, 87, 77, 85, 72, 85, 100, 85, 88,
-  93, 81, 83, 75, 80, 86, 86, 85, 80, 54,
-  56, 73, 82, 90, 83, 85, 74, 77, 91, 74,
-  85, 76, 83, 116, 66, 86, 81, 84, 78, 96,
-  87, 81, 112, 83, 78, 82, 67, 78, 83, 96,
-  76, 74, 88, 90, 65, 74, 64, 72, 82, 84,
-  74, 96, 90, 83, 92, 79, 94, 86, 85, 60,
-  74, 86, 80, 89, 78, 81, 75, 76, 88, 80,
-  83, 81, 71, 85, 78, 72, 77, 70, 80, 95,
-  91, 81, 81, 94, 77, 97, 78, 77, 64, 86,
-  86, 80, 77, 93, 75, 80, 65, 75, 103, 82,
-  82, 89, 94, 86, 71, 105, 85, 82, 79, 61,
-  87, 75, 78, 78, 104, 80, 107, 85, 87, 75,
-  87, 91, 75, 78, 84, 85, 80, 75, 92, 83,
-  88, 75, 99, 85, 88, 85, 86, 55, 77, 75,
-  71, 116, 71, 95, 69, 90, 99, 68, 79, 99,
-  98, 107, 71, 75, 79, 82, 94, 96, 99, 84,
-  113, 96, 79, 90, 85, 89, 110, 85, 83, 83,
-  78, 90, 75, 71, 75, 79, 100, 86, 60, 109,
-  95, 91, 84, 72, 95, 93, 78, 61, 78, 110,
-  92, 106, 86, 86, 85, 71, 82, 102, 81, 77,
-  62, 72, 77, 83, 84, 91, 89, 83, 85, 83,
-  86, 70, 84, 79, 93, 74, 87, 89, 78, 76,
-  87, 92, 93, 82, 86, 91, 84, 81, 87, 71,
-  92, 81, 87, 84, 84, 91, 79, 78, 88, 83,
-  91, 78, 86, 89, 87, 76, 80, 88, 83, 80,
-  79, 75, 82, 90, 89, 109, 86, 91, 84, 92,
-  69, 78, 76, 92, 87, 72, 75, 91, 85, 80,
-  86, 85, 82, 84, 102, 81, 91, 82, 79, 104,
-  84, 88, 89, 82, 82, 97, 87, 85, 119, 83,
-  90, 88, 65, 86, 87, 94, 78, 90, 80, 81,
-  76, 77, 70, 87, 80, 79, 73, 86, 89, 85,
-  69, 91, 88, 88, 93, 77, 84, 81, 70, 75,
-  79, 91, 85, 88, 82, 74, 86, 87, 95, 88,
-  78, 90, 84, 89, 80, 87, 87, 79, 82, 85,
-  77, 89, 85, 77, 82, 95, 81, 77, 81, 92,
-  72, 90, 74, 83, 93, 79, 96, 82, 90, 81,
-  77, 99, 83, 77, 73, 68, 92, 90, 89, 77,
-  84, 85, 98, 82, 71, 87, 82, 75, 81, 77,
-  83, 92, 86, 94, 92, 77, 82, 81, 89, 80,
-  80, 86, 85, 68, 68, 79, 82, 88, 81, 90,
-  79, 83, 96, 80, 82, 80, 81, 108, 75, 81,
-  85, 85, 81, 90, 87, 81, 107, 82, 84, 84,
-  67, 75, 91, 90, 70, 81, 82, 84, 71, 70,
-  68, 88, 91, 79, 81, 91, 83, 89, 89, 79,
-  89, 83, 86, 66, 89, 88, 78, 84, 85, 90,
-  80, 76, 89, 78, 83, 80, 80, 81, 91, 79,
-  77, 73, 83, 95, 86, 80, 86, 103, 73, 97,
-  78, 87, 68, 88, 86, 79, 76, 87, 75, 79,
-  67, 75, 99, 76, 84, 89, 78, 95, 75, 101,
-  84, 75, 77, 64, 94, 83, 80, 87, 99, 73,
-  101, 90, 68, 79, 84, 80, 83, 84, 75, 80,
-  81, 82, 103, 86, 87, 85, 96, 82, 84, 86,
-  94, 63, 76, 85, 73, 100, 72, 99, 86, 95,
-  93, 70, 80, 96, 88, 103, 76, 72, 81, 81,
-  93, 88, 94, 79, 113, 102, 91, 88, 90, 79,
-  105, 78, 85, 89, 77, 88, 73, 75, 77, 87,
-  108, 81, 71, 94, 82, 96, 97, 78, 96, 86,
-  83, 62, 86, 100, 94, 99, 89, 89, 94, 76,
-  84, 95, 86, 75, 79, 76, 86, 81, 89, 89,
-  85, 67, 80, 96, 93, 85, 76, 82, 76, 89,
-  77, 88, 70, 64, 79, 89, 79, 110, 76, 92,
-  73, 75, 96, 90, 90, 91, 72, 93, 76, 89,
-  95, 78, 80, 94, 100, 84, 88, 65, 88, 88,
-  86, 81, 85, 78, 83, 81, 103, 85, 82, 72,
-  85, 81, 80, 83, 93, 80, 104, 96, 82, 105,
-  58, 65, 95, 97, 93, 90, 76, 83, 112, 86,
-  71, 75, 74, 67, 84, 76, 81, 90, 75, 96,
-  79, 100, 98, 96, 88, 96, 93, 94, 75, 68,
-  99, 67, 84, 76, 89, 81, 76, 66, 92, 92,
-  75, 98, 77, 94, 86, 75, 93, 94, 76, 83,
-  83, 86, 86, 78, 69, 95, 88, 82, 99, 85,
-  104, 96, 78, 95, 89, 78, 86, 76, 94, 65,
-  76, 89, 81, 83, 76, 83, 64, 99, 72, 75,
-  73, 59, 71, 83, 82, 110, 66, 91, 70, 74,
-  87, 83, 106, 85, 80, 106, 76, 91, 89, 93,
-  76, 88, 78, 85, 87, 67, 92, 83, 88, 80,
-  80, 84, 84, 84, 95, 74, 82, 71, 94, 84,
-  88, 80, 90, 77, 110, 103, 83, 109, 51, 70,
-  80, 97, 89, 87, 90, 81, 93, 91, 75, 84,
-  72, 75, 91, 69, 73, 84, 70, 80, 88, 84,
-  79, 115, 82, 83, 90, 100, 82, 55, 95, 69,
-  82, 72, 89, 85, 76, 99, 96, 93, 76, 83,
-  71, 88, 80, 75, 93, 105, 66, 86, 82, 79,
-  64, 75, 72, 87, 84, 86, 93, 77, 97, 98,
-  80, 88, 84, 74, 92, 84, 89, 90, 99, 108,
-  82, 86, 79, 77, 71, 87, 86, 90, 73, 89,
-  78, 83, 92, 76, 79, 95, 88, 89, 83, 77,
-  75, 91, 80, 86, 84, 94, 89, 87, 84, 89,
-  75, 90, 83, 82, 86, 89, 81, 87, 86, 88,
-  85, 93, 94, 93, 81, 81, 83, 81, 92, 84,
-  95, 81, 78, 78, 71, 69, 77, 77, 83, 90,
-  87, 85, 77, 80, 101, 71, 85, 80, 75, 87,
-  70, 98, 88, 89, 80, 89, 84, 77, 90, 75,
-  94, 83, 88, 78, 76, 88, 90, 85, 91, 73,
-  93, 93, 69, 88, 85, 94, 88, 87, 84, 85,
-  77, 73, 80, 75, 90, 100, 89, 84, 73, 82,
-  85, 78, 103, 78, 96, 87, 87, 91, 89, 90,
-  110, 78, 103, 85, 71, 71, 65, 85, 85, 88,
-  74, 82, 79, 97, 76, 75, 78, 59, 79, 93,
-  83, 119, 94, 88, 66, 82, 78, 87, 116, 94,
-  90, 97, 76, 88, 84, 89, 91, 79, 96, 78,
-  76, 71, 86, 84, 96, 80, 70, 95, 86, 78,
-  86, 87, 85, 63, 91, 69, 83, 75, 96, 62,
-  100, 113, 93, 110, 50, 70, 84, 89, 93, 73,
-  71, 82, 102, 95, 67, 81, 68, 62, 72, 70,
-  72, 75, 77, 99, 86, 94, 89, 102, 75, 85,
-  91, 83, 85, 71, 95, 63, 82, 82, 87, 80,
-  75, 49, 95, 92, 86, 80, 79, 87, 79, 77,
-  96, 99, 72, 73, 75, 85, 82, 83, 57, 93,
-  90, 83, 97, 72, 95, 86, 85, 85, 106, 79,
-  83, 76, 78, 67, 60, 79, 78, 87, 77, 83,
-  73, 91, 76, 66, 82, 52, 65, 85, 73, 120,
-  69, 89, 68, 80, 70, 83, 123, 70, 83, 113,
-  74, 86, 97, 97, 78, 70, 92, 82, 70, 64,
-  102, 81, 89, 87, 61, 75, 83, 73, 85, 83,
-  84, 57, 91, 87, 80, 67, 92, 62, 109, 118,
-  87, 107, 37, 77, 70, 90, 94, 58, 98, 77,
-  89, 89, 70, 85, 70, 92, 81, 64, 63, 73,
-  75, 80, 86, 84, 71, 115, 61, 84, 89, 99,
-  90, 64, 101, 66, 78, 71, 89, 83, 76, 71,
-  94, 93, 85, 69, 71, 81, 70, 72, 78, 117,
-  64, 78, 59, 76, 69, 82, 66, 87, 78, 81,
-  93, 66, 92, 83, 82, 72, 86, 75, 77, 91,
-  82, 86, 79, 105, 91, 87, 78, 79, 70, 77,
-  80, 85, 79, 76, 85, 81, 78, 82, 80, 90,
-  86, 94, 84, 80, 89, 78, 76, 86, 77, 92,
-  81, 87, 74, 96, 75, 94, 81, 72, 92, 86,
-  75, 91, 84, 70, 86, 94, 91, 96, 86, 69,
-  87, 83, 85, 77, 98, 74, 85, 81, 81, 61,
-  72, 67, 77, 88, 85, 86, 85, 77, 102, 73,
-  85, 85, 69, 98, 73, 92, 79, 83, 81, 86,
-  78, 81, 86, 85, 96, 89, 89, 101, 80, 87,
-  96, 87, 82, 62, 87, 89, 83, 82, 81, 92,
-  93, 79, 88, 86, 78, 84, 70, 79, 87, 97,
-  74, 84, 88, 80, 84, 83, 100, 75, 109, 89,
-  83, 78, 90, 78, 98, 70, 96, 81, 69, 95,
-  75, 78, 78, 82, 79, 88, 83, 79, 75, 73,
-  75, 85, 95, 109, 94, 93, 107, 90, 71, 84,
-  84, 93, 94, 90, 99, 104, 77, 85, 80, 100,
-  79, 69, 79, 66, 79, 78, 88, 84, 93, 90,
-  81, 90, 86, 80, 87, 81, 85, 69, 89, 74,
-  88, 64, 87, 84, 91, 104, 96, 99, 78, 58,
-  81, 95, 78, 87, 75, 98, 89, 88, 76, 83,
-  70, 72, 80, 72, 92, 85, 82, 96, 88, 88,
-  93, 84, 82, 91, 84, 82, 94, 88, 86, 73,
-  91, 80, 89, 76, 67, 62, 94, 96, 96, 77,
-  88, 93, 85, 81, 93, 77, 83, 86, 79, 100,
-  85, 94, 69, 86, 92, 83, 96, 73, 90, 98,
-  87, 84, 100, 80, 75, 80, 73, 88, 68, 76,
-  75, 87, 81, 93, 79, 80, 73, 70, 83, 78,
-  78, 103, 81, 94, 87, 88, 67, 80, 78, 89,
-  92, 78, 88, 111, 70, 82, 89, 95, 77, 67,
-  75, 71, 86, 72, 103, 79, 92, 97, 66, 74,
-  79, 76, 96, 86, 88, 66, 86, 76, 82, 63,
-  87, 79, 96, 101, 94, 101, 68, 64, 70, 89,
-  81, 64, 81, 94, 83, 86, 73, 88, 74, 87,
-  84, 69, 86, 83, 85, 88, 88, 90, 81, 93,
-  72, 94, 85, 101, 96, 82, 101, 69, 89, 79,
-  94, 77, 69, 69, 95, 96, 88, 76, 83, 85,
-  81, 76, 80, 92, 73, 81, 71, 90, 82, 90,
-  70, 84, 77, 78, 93, 68, 89, 86, 82, 75,
-  92, 75, 69, 90, 90, 97, 81, 92, 84, 91,
-  81, 79, 75, 83, 77, 83, 83, 78, 92, 93,
-  82, 80, 80, 88, 84, 93, 87, 90, 83, 83,
-  84, 88, 74, 101, 84, 93, 83, 84, 69, 90,
-  89, 80, 88, 87, 80, 91, 86, 86, 83, 86,
-  87, 89, 85, 75, 90, 87, 82, 75, 87, 74,
-  91, 82, 83, 82, 81, 72, 73, 84, 84, 91,
-  93, 77, 92, 76, 84, 88, 72, 83, 91, 90,
-  92, 75, 80, 79, 89, 82, 89, 87, 87, 90,
-  81, 107, 91, 92, 103, 86, 91, 66, 91, 86,
-  78, 86, 89, 94, 88, 76, 92, 95, 100, 76,
-  84, 76, 84, 88, 81, 85, 94, 85, 83, 79,
-  89, 77, 105, 87, 81, 78, 82, 83, 106, 98,
-  82, 88, 97, 83, 78, 68, 78, 76, 80, 84,
-  96, 73, 91, 98, 77, 79, 77, 89, 88, 75,
-  84, 86, 100, 82, 87, 77, 86, 84, 94, 101,
-  75, 79, 80, 84, 111, 74, 91, 89, 76, 81,
-  89, 84, 76, 77, 92, 86, 83, 71, 72, 89,
-  87, 88, 87, 102, 64, 107, 98, 87, 93, 86,
-  90, 83, 81, 79, 81, 77, 86, 84, 80, 106,
-  81, 86, 85, 80, 74, 81, 94, 95, 90, 82,
-  95, 81, 88, 79, 84, 69, 103, 85, 62, 91,
-  90, 102, 74, 89, 86, 83, 94, 71, 87, 75,
-  93, 89, 87, 84, 80, 83, 87, 86, 89, 83,
-  84, 90, 91, 80, 56, 97, 85, 88, 80, 79,
-  93, 86, 103, 83, 89, 72, 103, 62, 88, 93,
-  84, 116, 73, 70, 88, 91, 70, 91, 88, 90,
-  73, 78, 87, 99, 86, 109, 87, 65, 95, 78,
-  103, 75, 94, 91, 94, 81, 81, 99, 88, 83,
-  84, 94, 106, 74, 96, 78, 68, 98, 83, 91,
-  86, 81, 80, 85, 76, 72, 98, 80, 76, 75,
-  91, 97, 68, 74, 87, 95, 83, 70, 86, 62,
-  61, 73, 59, 94, 69, 84, 95, 98, 70, 82,
-  81, 85, 80, 111, 74, 97, 74, 87, 92, 102,
-  88, 77, 87, 99, 62, 80, 84, 101, 80, 84,
-  87, 100, 82, 69, 87, 74, 84, 103, 85, 90,
-  85, 69, 76, 86, 80, 77, 86, 77, 87, 102,
-  79, 100, 63, 88, 76, 73, 73, 66, 85, 76,
-  89, 78, 92, 71, 80, 69, 65, 73, 79, 125,
-  76, 92, 96, 84, 73, 96, 71, 83, 66, 79,
-  82, 92, 78, 112, 71, 78, 95, 81, 74, 89,
-  88, 87, 83, 96, 77, 85, 99, 85, 67, 101,
-  94, 78, 77, 91, 72, 97, 77, 82, 81, 74,
-  81, 109, 81, 74, 95, 78, 85, 77, 88, 82,
-  100, 63, 96, 92, 77, 77, 81, 58, 53, 90,
-  63, 84, 79, 75, 77, 85, 84, 85, 79, 86,
-  80, 92, 74, 109, 74, 81, 83, 100, 71, 77,
-  94, 87, 76, 86, 95, 88, 86, 77, 89, 87,
-  74, 69, 92, 87, 73, 90, 84, 83, 88, 83,
-  88, 87, 87, 96, 75, 74, 91, 97, 58, 99,
-  65, 72, 74, 96, 90, 93, 92, 88, 75, 83,
-  82, 112, 97, 81, 95, 91, 102, 72, 76, 69,
-  76, 76, 79, 94, 78, 71, 86, 91, 79, 70,
-  82, 92, 95, 61, 86, 84, 102, 76, 101, 85,
-  98, 78, 91, 91, 74, 87, 62, 76, 80, 85,
-  110, 69, 93, 69, 75, 85, 69, 88, 88, 80,
-  85, 68, 83, 71, 83, 87, 84, 100, 62, 99,
-  87, 85, 97, 97, 83, 77, 79, 71, 94, 79,
-  97, 91, 54, 89, 76, 102, 78, 74, 88, 89,
-  85, 86, 86, 76, 93, 93, 85, 103, 75, 76,
-  93, 67, 73, 86, 84, 107, 68, 93, 85, 83,
-  82, 76, 73, 67, 79, 93, 89, 94, 89, 80,
-  81, 76, 85, 94, 76, 91, 96, 93, 69, 96,
-  84, 107, 80, 69, 90, 82, 88, 88, 82, 71,
-  86, 56, 108, 92, 77, 97, 71, 69, 71, 95,
-  73, 92, 64, 74, 74, 74, 88, 98, 83, 123,
-  89, 58, 111, 77, 96, 63, 91, 94, 111, 121,
-  78, 91, 88, 66, 62, 89, 103, 91, 134, 57,
-  101, 83, 62, 90, 71, 78, 72, 89, 82, 78,
-  89, 78, 75, 74, 88, 89, 76, 67, 72, 84,
-  87, 76, 79, 62, 60, 73, 71, 95, 80, 108,
-  40, 82, 79, 83, 70, 84, 91, 94, 65, 86,
-  72, 80, 78, 113, 83, 103, 78, 102, 57, 67,
-  90, 70, 80, 79, 75, 90, 85, 61, 79, 79,
-  69, 58, 90, 88, 74, 89, 72, 86, 74, 84,
-  78, 92, 90, 91, 69, 110, 92, 84, 73, 88,
-  84, 70, 79, 83, 75, 81, 89, 80, 76, 74,
-  85, 73, 83, 98, 79, 88, 91, 80, 84, 88,
-  66, 78, 69, 85, 71, 97, 87, 102, 75, 74,
-  94, 79, 80, 81, 81, 83, 103, 124, 78, 76,
-  102, 76, 64, 89, 83, 86, 91, 96, 71, 95,
-  65, 85, 78, 74, 85, 106, 86, 87, 85, 79,
-  86, 79, 85, 85, 97, 67, 93, 92, 76, 75,
-  79, 46, 55, 98, 75, 73, 81, 66, 58, 93,
-  87, 80, 79, 84, 89, 81, 55, 105, 81, 83,
-  90, 97, 78, 88, 94, 83, 76, 81, 104, 72,
-  86, 81, 82, 77, 77, 71, 96, 87, 77, 56,
-  80, 82, 88, 76, 84, 89, 88, 104, 84, 76,
-  87, 88, 43, 99, 71, 75, 76, 89, 111, 98,
-  95, 92, 81, 78, 82, 111, 90, 77, 83, 69,
-  85, 100, 79, 84, 80, 89, 87, 91, 88, 78,
-  65, 72, 79, 72, 89, 90, 85, 93, 84, 83,
-  82, 83, 89, 89, 87, 91, 86, 78, 78, 81,
-  81, 95, 84, 80, 94, 80, 100, 71, 77, 82,
-  86, 90, 64, 83, 82, 75, 87, 84, 87, 87,
-  84, 83, 76, 78, 87, 87, 89, 96, 82, 86,
-  71, 94, 73, 87, 81, 79, 86, 81, 86, 92,
-  76, 90, 87, 113, 77, 87, 81, 81, 93, 92,
-  73, 92, 77, 79, 77, 77, 97, 77, 76, 83,
-  82, 77, 87, 82, 82, 88, 74, 69, 79, 88,
-  90, 98, 98, 80, 96, 86, 82, 86, 87, 98,
-  78, 80, 102, 81, 79, 91, 83, 78, 90, 82,
-  90, 83, 84, 84, 83, 73, 60, 73, 78, 96,
-  79, 85, 80, 85, 85, 86, 64, 81, 65, 76,
-  77, 93, 83, 89, 74, 81, 83, 82, 78, 79,
-  86, 86, 95, 112, 81, 73, 92, 73, 74, 91,
-  88, 79, 84, 75, 95, 59, 69, 84, 79, 79,
-  75, 73, 82, 87, 86, 81, 90, 81, 92, 70,
-  94, 85, 89, 90, 87, 83, 90, 81, 70, 90,
-  74, 84, 72, 91, 91, 70, 90, 80, 79, 96,
-  82, 103, 83, 68, 84, 86, 81, 88, 76, 89,
-  79, 82, 83, 88, 102, 80, 77, 71, 94, 76,
-  80, 71, 84, 90, 77, 74, 80, 79, 93, 84,
-  74, 88, 89, 100, 71, 81, 96, 82, 77, 90,
-  87, 72, 80, 79, 98, 82, 92, 92, 90, 88,
-  86, 94, 84, 81, 79, 69, 96, 66, 89, 97,
-  96, 75, 89, 85, 78, 93, 82, 90, 72, 86,
-  82, 78, 71, 82, 80, 83, 79, 89, 71, 70,
-  73, 83, 78, 72, 86, 86, 78, 79, 76, 87,
-  70, 102, 71, 68, 85, 94, 88, 80, 82, 70,
-  89, 79, 78, 104, 89, 88, 92, 89, 93, 106,
-  99, 87, 83, 81, 76, 66, 85, 105, 93, 74,
-  71, 87, 79, 84, 88, 76, 85, 81, 87, 91,
-  67, 89, 96, 82, 86, 79, 96, 87, 74, 73,
-  98, 89, 81, 87, 75, 87, 92, 85, 75, 90,
-  95, 91, 84, 77, 74, 79, 93, 72, 82, 89,
-  82, 90, 78, 73, 87, 85, 78, 93, 57, 78,
-  88, 77, 94, 94, 85, 94, 93, 85, 77, 87,
-  78, 77, 84, 85, 82, 100, 90, 94, 81, 91,
-  85, 93, 79, 68, 91, 78, 84, 95, 86, 72,
-  90, 76, 100, 89, 89, 84, 82, 93, 73, 101,
-  80, 84, 87, 81, 78, 96, 86, 82, 88, 78,
-  80, 77, 85, 89, 80, 91, 88, 101, 85, 83,
-  90, 97, 74, 81, 102, 81, 78, 87, 91, 76,
-  76, 99, 85, 84, 104, 81, 82, 90, 80, 89,
-  90, 81, 96, 81, 79, 95, 76, 82, 83, 91,
-  89, 86, 93, 113, 78, 80, 81, 90, 82, 92,
-  87, 92, 85, 77, 87, 89, 90, 82, 93, 88,
-  83, 85, 84, 95, 81, 77, 89, 78, 81, 82,
-  88, 83, 86, 95, 86, 79, 90, 84, 82, 83,
-  78, 79, 80, 84, 82, 92, 84, 74, 87, 80,
-  78, 89, 81, 82, 84, 92, 87, 93, 83, 96,
-  90, 69, 91, 81, 78, 81, 77, 79, 87, 87,
-  90, 94, 85, 88, 81, 98, 88, 97, 83, 91,
-  88, 83, 92, 89, 83, 86, 75, 70, 77, 80,
-  86, 85, 82, 83, 91, 87, 88, 81, 78, 90,
-  74, 82, 94, 73, 72, 84, 95, 77, 81, 82,
-  86, 97, 86, 75, 76, 89, 79, 75, 82, 102,
-  86, 76, 81, 92, 84, 75, 87, 80, 92, 81,
-  86, 89, 75, 77, 84, 89, 72, 96, 76, 80,
-  84, 69, 82, 86, 87, 81, 96, 75, 89, 75,
-  87, 92, 82, 78, 104, 86, 81, 84, 87, 84,
-  83, 89, 78, 79, 82, 85, 79, 80, 83, 81,
-  82, 79, 87, 84, 76, 80, 79, 96, 88, 88,
-  82, 88, 84, 89, 89, 100, 83, 111, 82, 80,
-  87, 79, 81, 82, 82, 89, 85, 80, 86, 93,
-  84, 84, 87, 97, 68, 75, 78, 84, 87, 71,
-  95, 104, 81, 86, 67, 69, 81, 75, 89, 88,
-  79, 91, 84, 77, 85, 87, 86, 93, 74, 81,
-  103, 81, 77, 85, 90, 72, 75, 95, 79, 94,
-  96, 71, 83, 96, 80, 80, 84, 91, 94, 85,
-  87, 93, 84, 108, 95, 80, 87, 82, 94, 79,
-  75, 79, 90, 87, 74, 89, 82, 90, 85, 74,
-  91, 84, 86, 84, 91, 78, 87, 83, 86, 91,
-  85, 77, 93, 84, 84, 81, 90, 89, 81, 80,
-  79, 80, 79, 84, 83, 80, 73, 79, 79, 82,
-  90, 89, 79, 76, 82, 67, 81, 78, 78, 71,
-  97, 93, 72, 88, 90, 100, 61, 82, 93, 71,
-  91, 84, 78, 82, 97, 66, 80, 92, 91, 82,
-  91, 90, 150, 96, 82, 87, 83, 86, 84, 81,
-  97, 90, 79, 67, 83, 78, 92, 84, 82, 81,
-  82, 93, 85, 78, 96, 61, 73, 85, 73, 88,
-  87, 81, 83, 103, 76, 95, 97, 87, 80, 80,
-  95, 95, 88, 90, 81, 84, 83, 78, 82, 88,
-  91, 81, 91, 104, 77, 86, 86, 98, 78, 82,
-  79, 95, 77, 93, 77, 92, 72, 80, 88, 92,
-  84, 94, 93, 88, 73, 97, 91, 97, 83, 93,
-  82, 82, 70, 84, 83, 79, 95, 87, 86, 92,
-  71, 90, 77, 85, 84, 93, 74, 79, 65, 90,
-  87, 83, 92, 75, 70, 84, 79, 63, 91, 94,
-  77, 84, 89, 110, 73, 78, 86, 76, 92, 72,
-  70, 88, 91, 71, 71, 93, 92, 93, 93, 91,
-  165, 87, 90, 91, 76, 88, 88, 70, 87, 89,
-  71, 67, 77, 84, 92, 82, 90, 77, 89, 78,
-  84, 63, 90, 52, 72, 90, 60, 83, 84, 86,
-  90, 108, 85, 78, 99, 109, 78, 79, 92, 89,
-  83, 73, 70, 102, 77, 80, 81, 78, 92, 73,
-  91, 98, 75, 92, 85, 82, 75, 82, 78, 95,
-  75, 98, 66, 86, 73, 77, 77, 88, 85, 97,
-  98, 75, 74, 80, 92, 99, 80, 92, 97, 90,
-  66, 86, 85, 80, 91, 78, 83, 79, 67, 89,
-  77, 85, 89, 92, 69, 79, 64, 84, 83, 83,
-  77, 95, 88, 80, 76, 70, 89, 87, 76, 91,
-  88, 114, 65, 87, 85, 74, 87, 74, 77, 98,
-  87, 66, 73, 90, 88, 87, 94, 93, 142, 79,
-  81, 89, 78, 72, 88, 89, 90, 92, 73, 62,
-  86, 74, 91, 82, 87, 81, 80, 72, 83, 75,
-  97, 61, 70, 87, 76, 75, 86, 83, 84, 102,
-  76, 87, 95, 98, 78, 73, 97, 102, 82, 87,
-  74, 96, 82, 84, 86, 85, 92, 98, 99, 96,
-  73, 89, 87, 84, 76, 85, 80, 96, 73, 91,
-  74, 83, 69, 82, 84, 86, 83, 98, 90, 80,
-  74, 83, 89, 94, 80, 89, 85, 86, 73, 81,
-  93, 83, 90, 73, 85, 85, 70, 88, 80, 82,
-  78, 94, 69, 77, 71, 87, 85, 83, 79, 70,
-  87, 81, 93, 91, 77, 84, 79, 87, 87, 77,
-  72, 79, 85, 84, 86, 84, 90, 67, 89, 86,
-  85, 96, 82, 72, 86, 95, 75, 81, 87, 86,
-  86, 89, 75, 84, 91, 81, 75, 84, 89, 81,
-  83, 83, 79, 95, 79, 96, 78, 88, 89, 105,
-  70, 79, 105, 78, 81, 85, 95, 79, 73, 86,
-  78, 75, 89, 80, 84, 70, 86, 91, 91, 75,
-  83, 78, 78, 88, 83, 85, 77, 84, 92, 68,
-  87, 90, 79, 80, 80, 82, 91, 83, 80, 83,
-  79, 77, 90, 77, 88, 77, 81, 82, 83, 89,
-  83, 87, 75, 86, 80, 75, 72, 87, 80, 85,
-  88, 87, 75, 83, 81, 86, 82, 83, 76, 76,
-  85, 74, 87, 83, 79, 83, 91, 72, 75, 86,
-  93, 81, 68, 85, 81, 81, 82, 76, 81, 71,
-  79, 91, 89, 79, 84, 73, 85, 86, 80, 88,
-  87, 71, 88, 102, 105, 72, 90, 94, 86, 92,
-  75, 78, 83, 90, 79, 79, 88, 85, 86, 77,
-  83, 93, 78, 87, 75, 84, 84, 90, 66, 81,
-  89, 78, 73, 80, 97, 86, 88, 78, 79, 82,
-  80, 76, 85, 79, 90, 79, 81, 90, 78, 77,
-  77, 85, 91, 78, 70, 86, 88, 68, 85, 81,
-  73, 82, 82, 82, 81, 88, 72, 78, 79, 77,
-  84, 76, 86, 81, 87, 69, 86, 84, 86, 89,
-  79, 89, 95, 77, 70, 88, 72, 92, 84, 82,
-  69, 80, 79, 87, 85, 82, 86, 82, 87, 75,
-  87, 79, 86, 86, 81, 85, 92, 79, 86, 84,
-  70, 73, 79, 86, 86, 87, 81, 75, 78, 85,
-  82, 77, 90, 74, 81, 88, 80, 93, 85, 74,
-  87, 98, 74, 71, 85, 87, 84, 76, 79, 87,
-  81, 87, 87, 77, 96, 79, 84, 78, 82, 93,
-  70, 73, 74, 91, 85, 101, 69, 80, 102, 71,
-  77, 82, 94, 79, 81, 82, 75, 83, 88, 75,
-  86, 84, 86, 96, 78, 87, 79, 80, 80, 90,
-  87, 104, 72, 82, 86, 66, 88, 76, 73, 84,
-  75, 86, 80, 82, 76, 75, 77, 80, 85, 73,
-  86, 84, 84, 76, 86, 74, 84, 84, 72, 86,
-  81, 76, 75, 85, 74, 89, 82, 74, 76, 81,
-  85, 84, 87, 79, 83, 80, 81, 74, 88, 80,
-  80, 85, 87, 82, 82, 90, 99, 88, 81, 89,
-  78, 84, 94, 75, 82, 91, 86, 74, 83, 91,
-  96, 85, 88, 87, 99, 73, 83, 73, 73, 86,
-  88, 96, 90, 90, 79, 93, 81, 85, 86, 65,
-  88, 80, 83, 77, 75, 95, 62, 75, 92, 79,
-  69, 78, 88, 78, 91, 86, 78, 78, 74, 73,
-  80, 93, 92, 93, 83, 82, 75, 90, 79, 87,
-  96, 74, 83, 73, 68, 94, 88, 71, 86, 100,
-  88, 78, 73, 77, 83, 91, 102, 83, 97, 93,
-  101, 85, 74, 90, 76, 79, 88, 66, 87, 78,
-  113, 94, 86, 73, 98, 79, 95, 86, 85, 101,
-  86, 77, 73, 83, 71, 80, 86, 88, 99, 76,
-  93, 76, 85, 64, 74, 86, 83, 93, 84, 93,
-  71, 84, 91, 86, 101, 82, 85, 97, 77, 78,
-  99, 87, 83, 85, 91, 75, 90, 105, 110, 88,
-  82, 81, 91, 61, 103, 80, 70, 81, 108, 90,
-  90, 92, 76, 81, 79, 84, 84, 61, 85, 97,
-  78, 77, 86, 103, 57, 75, 103, 77, 56, 77,
-  87, 72, 88, 102, 65, 77, 74, 69, 77, 96,
-  107, 92, 85, 86, 74, 91, 85, 92, 87, 63,
-  81, 64, 66, 83, 88, 61, 82, 89, 90, 77,
-  72, 79, 90, 82, 116, 88, 86, 100, 91, 86,
-  71, 96, 64, 73, 85, 70, 88, 77, 104, 93,
-  78, 80, 101, 79, 82, 78, 94, 103, 91, 73,
-  71, 78, 66, 82, 83, 85, 82, 81, 92, 74,
-  83, 65, 82, 78, 80, 90, 76, 92, 82, 96,
-  92, 89, 99, 92, 79, 97, 78, 85, 89, 75,
-  84, 80, 85, 79, 83, 88, 93, 97, 76, 86,
-  83, 75, 91, 80, 76, 84, 91, 80, 92, 98,
-  80, 83, 84, 97, 88, 66, 88, 87, 80, 76,
-  83, 89, 66, 79, 98, 87, 70, 80, 83, 75,
-  89, 89, 80, 85, 76, 75, 77, 86, 96, 88,
-  83, 81, 76, 92, 79, 85, 92, 68, 95, 73,
-  76, 91, 95, 72, 86, 83, 97, 80, 72, 75,
-  84, 80, 101, 88, 80, 89, 99, 85, 72, 99,
-  75, 81, 85, 68, 88, 79, 82, 97, 80, 88,
-  98, 79, 93, 89, 85, 98, 82, 77, 72, 82,
-  70, 88, 74, 82, 77, 77, 96, 74, 88, 69,
-  72, 86, 81, 89, 85, 91, 100, 82, 85, 91,
-  85, 92, 81, 85, 80, 90, 86, 73, 80, 76,
-  90, 90, 82, 84, 70, 81, 73, 84, 94, 90,
-  88, 73, 74, 87, 74, 85, 85, 98, 93, 101,
-  85, 86, 80, 63, 86, 75, 75, 81, 71, 90,
-  63, 74, 97, 89, 79, 85, 92, 82, 89, 85,
-  89, 80, 83, 89, 88, 100, 73, 76, 73, 88,
-  74, 86, 68, 91, 98, 64, 82, 83, 69, 86,
-  88, 77, 86, 105, 85, 82, 80, 96, 84, 83,
-  92, 76, 93, 88, 88, 85, 84, 76, 98, 72,
-  82, 71, 79, 83, 100, 90, 84, 77, 83, 79,
-  103, 94, 87, 89, 86, 82, 80, 82, 70, 84,
-  79, 89, 83, 89, 80, 66, 85, 82, 76, 83,
-  92, 89, 71, 85, 93, 81, 92, 95, 88, 90,
-  86, 87, 80, 91, 87, 81, 84, 82, 99, 93,
-  84, 94, 70, 85, 66, 80, 93, 83, 102, 69,
-  72, 91, 87, 87, 79, 96, 101, 89, 77, 79,
-  77, 55, 82, 84, 74, 86, 73, 103, 58, 71,
-  102, 89, 65, 82, 99, 79, 83, 93, 79, 84,
-  82, 87, 88, 94, 81, 76, 70, 92, 72, 91,
-  73, 92, 96, 53, 81, 73, 72, 79, 91, 73,
-  82, 95, 80, 80, 84, 98, 92, 82, 96, 79,
-  84, 86, 85, 91, 83, 75, 89, 56, 76, 75,
-  79, 90, 104, 88, 81, 70, 81, 78, 99, 97,
-  94, 90, 88, 83, 76, 76, 71, 82, 73, 85,
-  77, 97, 73, 63, 88, 73, 76, 82, 91, 84,
-  68, 83, 97, 94, 96, 89, 87, 94, 79, 87,
-  80, 91, 86, 72, 84, 87, 85, 96, 82, 81,
-  72, 93, 68, 85, 89, 89, 91, 75, 76, 85,
-  79, 91, 86, 100, 96, 83, 83, 93, 77, 60,
-  74, 77, 74, 80, 74, 93, 62, 71, 92, 93,
-  78, 85, 91, 76, 89, 89, 87, 83, 83, 91,
-  82, 97, 78, 78, 75, 89, 77, 87, 78, 91,
-  95, 58, 84, 84, 72, 86, 95, 80, 79, 86,
-  84, 82, 82, 94, 83, 85, 95, 87, 86, 86,
-  87, 88, 83, 76, 101, 69, 75, 71, 77, 87,
-  93, 90, 82, 73, 82, 78, 94, 99, 88, 89,
-  84, 84, 73, 80, 69, 82, 75, 90, 86, 89,
-  81, 65, 91, 78, 76, 83, 88, 86, 73, 82,
-  95, 84, 84, 80, 72, 89, 71, 77, 86, 90,
-  73, 74, 86, 71, 81, 92, 79, 69, 58, 81,
-  75, 80, 89, 110, 84, 75, 95, 76, 76, 84,
-  76, 92, 82, 107, 92, 84, 79, 73, 87, 74,
-  72, 67, 85, 71, 75, 88, 75, 81, 102, 91,
-  86, 81, 93, 66, 92, 80, 91, 104, 84, 89,
-  75, 75, 76, 89, 75, 86, 64, 84, 87, 86,
-  90, 85, 89, 93, 73, 86, 80, 88, 96, 82,
-  76, 87, 81, 87, 66, 86, 92, 82, 85, 94,
-  87, 78, 103, 80, 83, 76, 72, 83, 67, 79,
-  79, 85, 78, 85, 103, 89, 67, 70, 80, 92,
-  91, 75, 66, 87, 82, 90, 76, 92, 81, 86,
-  82, 101, 69, 79, 88, 93, 67, 77, 93, 84,
-  77, 88, 68, 84, 74, 76, 82, 99, 74, 77,
-  82, 86, 93, 96, 82, 75, 57, 84, 74, 74,
-  94, 111, 83, 71, 99, 80, 94, 91, 73, 87,
-  85, 98, 95, 77, 77, 81, 79, 80, 69, 65,
-  81, 76, 74, 90, 70, 81, 96, 95, 90, 85,
-  88, 62, 91, 77, 86, 104, 93, 89, 79, 75,
-  70, 90, 74, 89, 67, 82, 94, 84, 82, 83,
-  94, 92, 77, 85, 79, 84, 91, 74, 82, 86,
-  75, 78, 60, 96, 87, 75, 85, 96, 79, 79,
-  104, 73, 79, 80, 71, 91, 85, 69, 78, 78,
-  77, 85, 115, 94, 79, 68, 76, 96, 88, 73,
-  69, 81, 70, 90, 86, 97, 72, 88, 92, 100,
-  67, 76, 90, 95, 65, 75, 94, 85, 84, 84,
-  72, 84, 71, 79, 87, 92, 74, 72, 85, 97,
-  79, 98, 82, 67, 57, 88, 84, 81, 92, 106,
-  74, 73, 97, 76, 84, 96, 75, 91, 84, 95,
-  86, 85, 77, 73, 70, 81, 76, 66, 77, 77,
-  76, 86, 64, 86, 100, 90, 87, 76, 90, 70,
-  91, 83, 94, 102, 85, 88, 74, 76, 76, 87,
-  82, 85, 69, 82, 93, 82, 86, 87, 93, 93,
-  79, 86, 76, 79, 93, 80, 78, 85, 79, 75,
-  69, 99, 93, 79, 85, 88, 83, 77, 107, 77,
-  84, 74, 71, 87, 98, 76, 82, 75, 77, 83,
-  105, 93, 71, 74, 76, 89, 89, 75, 66, 78,
-  77, 93, 99, 92, 80, 93, 101, 95, 70, 79,
-  86, 95, 67, 79, 85, 80, 77, 90, 86, 86,
-  81, 70, 94, 65, 81, 74, 87, 91, 60, 76,
-  81, 91, 107, 82, 87, 83, 90, 69, 95, 96,
-  95, 65, 92, 87, 76, 81, 80, 83, 82, 96,
-  78, 86, 82, 83, 83, 75, 99, 84, 67, 84,
-  86, 96, 80, 87, 75, 81, 87, 77, 90, 80,
-  74, 83, 81, 85, 87, 76, 90, 76, 80, 80,
-  78, 79, 83, 82, 75, 92, 82, 89, 73, 82,
-  81, 87, 102, 73, 92, 78, 82, 90, 97, 94,
-  87, 103, 98, 79, 78, 83, 72, 82, 90, 73,
-  69, 82, 82, 63, 76, 77, 75, 94, 84, 77,
-  86, 82, 79, 92, 95, 83, 48, 98, 71, 69,
-  105, 81, 121, 96, 84, 94, 89, 83, 87, 73,
-  156, 88, 91, 93, 71, 80, 102, 79, 71, 62,
-  89, 41, 76, 77, 87, 94, 59, 72, 83, 98,
-  102, 82, 99, 80, 76, 63, 94, 90, 92, 50,
-  94, 88, 70, 93, 89, 69, 79, 86, 81, 89,
-  80, 80, 83, 67, 91, 84, 65, 79, 83, 83,
-  70, 86, 78, 77, 84, 77, 92, 81, 65, 86,
-  74, 80, 91, 75, 89, 76, 67, 84, 87, 74,
-  86, 89, 81, 89, 75, 87, 68, 71, 81, 82,
-  101, 76, 96, 72, 77, 80, 95, 88, 97, 102,
-  93, 76, 68, 85, 60, 79, 75, 71, 76, 80,
-  83, 75, 76, 91, 62, 93, 96, 82, 82, 80,
-  75, 93, 88, 87, 45, 90, 80, 77, 82, 79,
-  131, 87, 89, 94, 82, 76, 96, 79, 179, 87,
-  81, 92, 81, 90, 82, 98, 74, 78, 92, 72,
-  80, 81, 84, 87, 61, 78, 83, 93, 108, 89,
-  99, 85, 79, 71, 92, 94, 93, 67, 84, 85,
-  81, 81, 83, 79, 82, 115, 82, 91, 82, 84,
-  89, 76, 82, 85, 71, 81, 88, 77, 81, 91,
-  80, 77, 84, 77, 95, 81, 77, 80, 80, 83,
-  93, 81, 88, 72, 78, 80, 79, 86, 81, 78,
-  95, 93, 89, 88, 76, 88, 83, 96, 104, 73,
-  91, 75, 86, 81, 92, 92, 106, 98, 98, 80,
-  79, 81, 73, 83, 85, 73, 72, 81, 80, 70,
-  79, 78, 81, 93, 86, 75, 85, 91, 74, 88,
-  92, 81, 49, 79, 70, 74, 85, 79, 107, 93,
-  88, 95, 94, 88, 81, 74, 140, 86, 82, 71,
-  79, 72, 88, 87, 78, 64, 92, 50, 83, 73,
-  79, 81, 70, 82, 75, 88, 101, 84, 93, 79,
-  80, 71, 94, 97, 90, 63, 99, 83, 77, 82,
-  87, 81, 88, 94, 83, 80, 84, 76, 90, 79,
-  92, 83, 78, 92, 88, 93, 80, 80, 82, 81,
-  85, 90, 92, 90, 74, 88, 85, 87, 84, 79,
-  81, 76, 89, 87, 82, 71, 94, 74, 84, 97,
-  74, 84, 79, 74, 82, 91, 90, 84, 89, 82,
-  85, 86, 92, 78, 80, 93, 97, 82, 80, 83,
-  67, 80, 81, 73, 75, 85, 75, 78, 77, 81,
-  64, 91, 96, 81, 84, 81, 75, 92, 92, 82,
-  54, 99, 69, 71, 89, 90, 113, 86, 81, 88,
-  80, 72, 92, 84, 149, 86, 86, 85, 71, 63,
-  100, 80, 71, 57, 86, 20, 79, 75, 80, 89,
-  74, 88, 73, 97, 96, 84, 96, 82, 79, 62,
-  87, 87, 86, 43, 101, 93, 65, 88, 96, 74,
-  88, 71, 84, 80, 84, 73, 94, 79, 94, 88,
-  84, 85, 81, 86, 72, 82, 82, 78, 79, 91,
-  91, 77, 67, 94, 84, 90, 87, 78, 79, 76,
-  68, 96, 84, 77, 98, 73, 69, 104, 67, 81,
-  81, 59, 86, 82, 85, 92, 93, 81, 73, 76,
-  96, 81, 93, 90, 91, 80, 66, 77, 64, 75,
-  60, 71, 82, 87, 83, 84, 77, 87, 47, 92,
-  100, 86, 85, 81, 72, 89, 89, 88, 50, 88,
-  80, 84, 78, 97, 119, 76, 83, 86, 60, 68,
-  101, 84, 162, 98, 78, 92, 86, 81, 88, 89,
-  75, 66, 88, 55, 80, 79, 81, 93, 73, 83,
-  75, 85, 99, 86, 92, 80, 82, 72, 86, 93,
-  92, 60, 88, 89, 79, 77, 87, 79, 82, 95,
-  82, 80, 83, 77, 91, 78, 89, 85, 79, 88,
-  83, 87, 80, 82, 86, 81, 80, 88, 93, 70,
-  75, 85, 86, 83, 89, 82, 81, 73, 88, 85,
-  82, 77, 95, 77, 85, 95, 80, 86, 82, 80,
-  87, 92, 92, 84, 89, 75, 84, 86, 91, 83,
-  102, 91, 94, 80, 80, 82, 70, 82, 76, 71,
-  75, 85, 82, 76, 79, 77, 73, 91, 95, 86,
-  84, 86, 74, 86, 94, 82, 56, 81, 77, 76,
-  94, 89, 105, 86, 86, 84, 82, 79, 88, 88,
-  130, 85, 82, 75, 76, 76, 83, 80, 83, 73,
-  86, 75, 82, 76, 85, 80, 69, 86, 78, 86,
-  97, 87, 93, 84, 79, 80, 100, 94, 106, 81,
-  83, 77, 78, 89, 89, 85, 82, 93, 84, 78,
-  84, 85, 90, 73, 89, 80, 77, 86, 86, 91,
-  85, 85, 91, 86, 86, 88, 90, 81, 76, 82,
-  89, 82, 85, 78, 89, 78, 90, 88, 83, 82,
-  91, 84, 95, 92, 89, 80, 83, 73, 85, 86,
-  76, 75, 85, 88, 91, 88, 87, 78, 75, 93,
-  91, 88, 80, 91, 76, 81, 87, 72, 71, 82,
-  77, 68, 81, 80, 77, 86, 90, 88, 90, 77,
-  74, 93, 88, 76, 61, 108, 76, 75, 86, 89,
-  103, 85, 81, 90, 87, 79, 89, 97, 128, 80,
-  86, 83, 85, 75, 86, 77, 83, 69, 85, 62,
-  79, 78, 83, 88, 73, 86, 76, 84, 96, 81,
-  91, 83, 85, 76, 84, 93, 108, 73, 87, 85,
-  72, 86, 98, 84, 88, 85, 84, 82, 81, 78,
-  97, 74, 91, 83, 86, 79, 74, 82, 80, 90,
-  91, 85, 87, 84, 97, 85, 67, 81, 78, 77,
-  88, 73, 94, 79, 79, 87, 77, 82, 91, 89,
-  82, 92, 82, 78, 80, 62, 85, 78, 74, 76,
-  88, 87, 89, 83, 91, 79, 87, 91, 91, 86,
-  73, 90, 70, 79, 81, 66, 77, 83, 79, 73,
-  83, 82, 71, 85, 89, 89, 84, 78, 73, 91,
-  82, 82, 57, 90, 84, 77, 86, 94, 103, 81,
-  82, 87, 83, 76, 93, 98, 129, 85, 82, 87,
-  86, 82, 88, 85, 83, 75, 85, 75, 82, 78,
-  86, 90, 69, 86, 80, 82, 96, 82, 92, 83,
-  84, 80, 84, 91, 100, 78, 78, 86, 82, 81,
-  88, 87, 76, 94, 82, 78, 81, 87, 92, 77,
-  91, 83, 81, 80, 78, 85, 89, 83, 94, 84,
-  82, 86, 94, 74, 78, 83, 86, 78, 90, 81,
-  85, 75, 85, 86, 78, 82, 92, 84, 80, 89,
-  88, 83, 86, 77, 87, 88, 79, 74, 86, 85,
-  90, 93, 84, 76, 104, 86, 90, 82, 81, 92,
-  80, 85, 84, 69, 72, 82, 91, 68, 80, 78,
-  82, 84, 91, 92, 83, 82, 75, 89, 79, 77,
-  64, 85, 83, 76, 95, 91, 99, 88, 85, 88,
-  86, 82, 89, 100, 116, 79, 87, 99, 93, 82,
-  91, 88, 80, 70, 71, 99, 73, 83, 94, 83,
-  82, 83, 82, 99, 67, 77, 70, 72, 82, 87,
-  100, 83, 77, 79, 94, 84, 84, 92, 83, 91,
-  86, 88, 83, 76, 89, 90, 80, 93, 89, 77,
-  83, 73, 91, 73, 81, 81, 82, 85, 89, 63,
-  79, 82, 87, 87, 66, 86, 94, 83, 81, 81,
-  88, 90, 81, 76, 72, 91, 69, 91, 80, 81,
-  90, 77, 84, 97, 84, 81, 76, 80, 76, 99,
-  89, 81, 82, 89, 88, 79, 66, 82, 84, 84,
-  86, 78, 75, 92, 81, 74, 72, 85, 79, 81,
-  87, 93, 87, 80, 75, 113, 69, 85, 79, 79,
-  80, 87, 75, 94, 84, 78, 70, 95, 37, 86,
-  81, 94, 69, 87, 70, 97, 107, 84, 95, 98,
-  83, 84, 75, 93, 80, 84, 83, 83, 84, 86,
-  81, 88, 93, 72, 55, 85, 62, 84, 107, 89,
-  85, 73, 92, 80, 81, 100, 74, 76, 87, 99,
-  78, 76, 94, 74, 80, 87, 108, 81, 78, 85,
-  90, 54, 77, 78, 89, 95, 80, 78, 90, 82,
-  84, 82, 73, 89, 89, 81, 85, 69, 82, 82,
-  86, 79, 68, 79, 89, 94, 67, 83, 80, 76,
-  75, 100, 80, 85, 84, 79, 98, 127, 76, 84,
-  85, 80, 87, 91, 72, 80, 73, 85, 85, 70,
-  76, 88, 55, 85, 80, 71, 83, 78, 80, 83,
-  92, 90, 88, 93, 69, 86, 86, 91, 76, 85,
-  67, 89, 92, 72, 76, 84, 65, 82, 86, 88,
-  83, 83, 48, 92, 123, 93, 73, 107, 82, 92,
-  89, 82, 95, 86, 70, 92, 80, 96, 74, 71,
-  100, 91, 64, 111, 59, 88, 107, 85, 88, 81,
-  80, 83, 75, 102, 82, 85, 88, 104, 75, 101,
-  91, 68, 105, 80, 105, 96, 69, 91, 91, 61,
-  96, 86, 89, 101, 87, 99, 100, 91, 96, 77,
-  109, 83, 79, 104, 90, 83, 75, 81, 103, 99,
-  88, 79, 88, 84, 57, 72, 84, 83, 65, 117,
-  94, 80, 85, 90, 116, 138, 88, 82, 90, 90,
-  78, 91, 105, 79, 72, 83, 82, 75, 87, 84,
-  68, 148, 89, 66, 95, 82, 107, 88, 82, 100,
-  86, 61, 75, 91, 110, 88, 92, 98, 71, 70,
-  97, 103, 82, 65, 105, 75, 87, 85, 102, 91,
-  83, 82, 84, 79, 89, 91, 81, 75, 69, 100,
-  75, 80, 88, 80, 76, 84, 78, 99, 68, 77,
-  80, 75, 82, 88, 84, 82, 84, 77, 88, 92,
-  87, 88, 81, 86, 87, 87, 83, 81, 83, 82,
-  81, 92, 95, 79, 96, 82, 80, 78, 76, 79,
-  79, 73, 86, 65, 87, 74, 86, 92, 63, 85,
-  93, 87, 89, 81, 80, 93, 75, 78, 75, 95,
-  69, 85, 86, 85, 82, 81, 89, 90, 79, 84,
-  79, 84, 66, 87, 85, 80, 86, 88, 94, 82,
-  70, 88, 83, 85, 88, 82, 82, 85, 71, 69,
-  76, 88, 80, 84, 82, 71, 88, 86, 83, 111,
-  88, 92, 80, 79, 75, 81, 84, 92, 78, 89,
-  74, 95, 37, 87, 83, 92, 72, 87, 76, 86,
-  100, 80, 91, 96, 84, 87, 67, 95, 81, 78,
-  82, 77, 77, 81, 81, 92, 92, 73, 59, 81,
-  63, 83, 86, 92, 88, 73, 88, 78, 84, 89,
-  76, 76, 91, 95, 78, 73, 80, 72, 79, 91,
-  116, 77, 98, 83, 75, 63, 73, 76, 87, 84,
-  73, 77, 87, 80, 80, 84, 67, 85, 85, 85,
-  96, 66, 77, 82, 72, 78, 65, 78, 79, 90,
-  75, 92, 70, 79, 79, 95, 83, 93, 89, 79,
-  90, 114, 73, 83, 85, 77, 90, 86, 71, 85,
-  65, 86, 82, 78, 78, 89, 49, 74, 80, 80,
-  75, 80, 79, 69, 93, 88, 101, 91, 87, 86,
-  76, 97, 68, 78, 68, 92, 80, 81, 73, 89,
-  61, 84, 83, 86, 78, 84, 45, 88, 110, 94,
-  76, 100, 84, 87, 83, 91, 91, 84, 73, 78,
-  74, 88, 73, 72, 101, 85, 69, 113, 57, 80,
-  95, 89, 90, 81, 75, 75, 79, 95, 81, 84,
-  86, 107, 68, 101, 84, 73, 108, 79, 113, 100,
-  81, 76, 75, 66, 82, 84, 82, 104, 83, 105,
-  98, 94, 90, 77, 99, 85, 84, 106, 107, 79,
-  90, 85, 87, 103, 83, 82, 96, 81, 54, 86,
-  79, 79, 71, 115, 101, 81, 87, 86, 107, 127,
-  83, 80, 87, 88, 78, 83, 92, 82, 71, 80,
-  80, 81, 87, 85, 59, 129, 94, 78, 87, 82,
-  97, 73, 90, 103, 108, 58, 90, 94, 96, 97,
-  82, 96, 70, 78, 87, 99, 82, 71, 101, 77,
-  88, 86, 102, 84, 89, 78, 78, 84, 90, 91,
-  79, 77, 69, 94, 72, 72, 89, 77, 75, 87,
-  71, 95, 68, 74, 85, 73, 80, 88, 85, 79,
-  85, 73, 98, 83, 91, 93, 80, 86, 95, 82,
-  84, 80, 86, 87, 83, 94, 81, 77, 92, 79,
-  82, 75, 79, 78, 77, 65, 92, 60, 85, 77,
-  85, 86, 65, 91, 90, 84, 79, 87, 76, 91,
-  72, 81, 76, 83, 80, 89, 83, 81, 81, 87,
-  96, 94, 76, 77, 74, 79, 73, 93, 89, 82,
-  92, 81, 94, 86, 76, 88, 87, 86, 86, 85,
-  80, 80, 77, 66, 76, 90, 83, 86, 84, 79,
-  89, 88, 78, 106, 89, 89, 80, 84, 78, 85,
-  78, 91, 81, 90, 69, 89, 42, 88, 82, 83,
-  77, 79, 79, 78, 94, 81, 91, 96, 79, 84,
-  70, 92, 75, 77, 81, 79, 81, 82, 75, 94,
-  77, 72, 67, 84, 69, 85, 78, 84, 84, 73,
-  85, 72, 83, 94, 69, 75, 89, 89, 80, 71,
-  85, 80, 81, 89, 93, 74, 97, 80, 73, 66,
-  79, 77, 78, 81, 79, 67, 83, 80, 78, 79,
-  71, 88, 84, 84, 80, 79, 80, 88, 70, 78,
-  66, 81, 77, 90, 79, 90, 70, 80, 83, 88,
-  80, 86, 85, 75, 80, 105, 78, 83, 87, 74,
-  83, 86, 68, 86, 73, 88, 80, 83, 73, 91,
-  61, 68, 75, 89, 78, 80, 82, 78, 88, 87,
-  85, 100, 87, 80, 77, 87, 77, 80, 68, 90,
-  80, 85, 64, 92, 51, 87, 74, 79, 75, 73,
-  57, 90, 89, 92, 82, 84, 81, 87, 82, 91,
-  75, 88, 79, 72, 76, 87, 74, 81, 89, 74,
-  76, 94, 68, 78, 91, 89, 90, 80, 90, 63,
-  83, 90, 77, 79, 83, 100, 73, 84, 89, 80,
-  85, 79, 96, 89, 81, 82, 74, 69, 84, 77,
-  76, 89, 79, 92, 84, 88, 83, 74, 98, 86,
-  91, 95, 89, 77, 82, 81, 82, 88, 81, 80,
-  88, 79, 70, 98, 74, 83, 74, 103, 95, 82,
-  86, 81, 97, 116, 73, 84, 89, 83, 73, 89,
-  84, 86, 79, 85, 82, 85, 80, 93, 72, 88,
-  84, 79, 81, 80, 93, 73, 97, 93, 108, 73,
-  87, 82, 86, 89, 80, 86, 69, 88, 81, 85,
-  76, 84, 87, 80, 79, 85, 87, 72, 77, 77,
-  85, 87, 93, 80, 102, 75, 77, 95, 76, 100,
-  74, 86, 115, 70, 76, 114, 79, 88, 90, 75,
-  70, 98, 101, 91, 85, 69, 94, 86, 86, 74,
-  73, 74, 76, 73, 77, 80, 90, 97, 73, 91,
-  88, 116, 83, 69, 93, 81, 64, 106, 83, 66,
-  89, 90, 88, 78, 95, 85, 73, 96, 72, 75,
-  70, 78, 81, 71, 94, 78, 92, 85, 77, 82,
-  82, 92, 96, 92, 74, 74, 88, 68, 87, 78,
-  93, 71, 74, 77, 93, 71, 80, 88, 99, 80,
-  77, 78, 82, 91, 77, 70, 93, 74, 79, 78,
-  85, 71, 77, 86, 97, 86, 77, 81, 112, 96,
-  79, 89, 84, 75, 90, 85, 72, 86, 83, 70,
-  90, 70, 75, 93, 85, 87, 76, 88, 82, 88,
-  96, 76, 97, 70, 77, 99, 74, 102, 77, 87,
-  113, 73, 73, 110, 75, 93, 89, 76, 68, 99,
-  99, 87, 83, 69, 84, 79, 85, 78, 68, 78,
-  75, 74, 79, 84, 92, 96, 76, 95, 95, 122,
-  88, 67, 91, 80, 65, 105, 79, 62, 81, 89,
-  93, 82, 92, 91, 74, 92, 76, 78, 75, 74,
-  81, 73, 93, 82, 95, 85, 80, 84, 80, 87,
-  93, 89, 76, 79, 91, 69, 86, 75, 86, 71,
-  76, 82, 89, 69, 82, 88, 89, 83, 76, 80,
-  87, 91, 80, 74, 90, 74, 78, 78, 87, 74,
-  77, 89, 94, 90, 72, 74, 107, 95, 80, 93,
-  86, 77, 83, 88, 76, 85, 63, 68, 71, 74,
-  71, 90, 93, 88, 79, 92, 78, 84, 91, 74,
-  96, 72, 80, 89, 80, 95, 76, 91, 106, 76,
-  80, 106, 80, 86, 84, 78, 73, 97, 92, 86,
-  88, 70, 89, 77, 83, 75, 75, 76, 81, 70,
-  78, 78, 90, 97, 73, 84, 95, 110, 83, 71,
-  91, 82, 64, 98, 84, 71, 78, 91, 91, 83,
-  97, 92, 78, 92, 71, 74, 75, 80, 83, 71,
-  93, 76, 94, 87, 85, 80, 79, 91, 95, 92,
-  73, 84, 94, 69, 86, 80, 95, 80, 71, 83,
-  85, 75, 78, 93, 92, 84, 76, 79, 85, 86,
-  86, 73, 84, 80, 79, 73, 82, 72, 76, 86,
-  99, 83, 88, 82, 101, 98, 76, 96, 80, 74,
-  83, 86, 75, 87, 66, 71, 88, 73, 75, 92,
-  82, 88, 77, 75, 88, 88, 92, 83, 101, 77,
-  78, 90, 84, 102, 79, 91, 114, 76, 80, 116,
-  82, 88, 93, 75, 78, 89, 95, 84, 72, 73,
-  81, 75, 84, 79, 67, 79, 73, 77, 85, 79,
-  93, 95, 71, 88, 92, 124, 95, 64, 90, 84,
-  73, 112, 82, 68, 80, 93, 87, 80, 91, 81,
-  69, 88, 73, 78, 74, 80, 79, 75, 83, 74,
-  92, 84, 80, 84, 89, 88, 89, 90, 78, 79,
-  79, 71, 84, 89, 86, 69, 80, 85, 97, 67,
-  79, 67, 97, 79, 69, 81, 84, 96, 77, 78,
-  95, 79, 75, 82, 94, 73, 81, 77, 98, 90,
-  73, 74, 108, 92, 86, 90, 84, 79, 87, 87,
-  69, 82, 68, 73, 77, 82, 79, 90, 85, 87,
-  79, 78, 83, 93, 97, 80, 96, 73, 75, 96,
-  83, 102, 80, 93, 107, 76, 74, 109, 79, 89,
-  90, 76, 73, 89, 94, 74, 73, 75, 70, 78,
-  82, 83, 64, 86, 76, 80, 87, 82, 94, 94,
-  75, 90, 95, 126, 99, 60, 91, 83, 77, 113,
-  76, 72, 73, 92, 94, 81, 89, 85, 72, 83,
-  76, 82, 80, 77, 80, 76, 80, 78, 96, 88,
-  84, 87, 86, 80, 83, 86, 79, 82, 84, 71,
-  85, 82, 78, 67, 78, 90, 94, 68, 83, 61,
-  89, 79, 73, 83, 90, 94, 79, 80, 91, 80,
-  75, 86, 95, 76, 84, 79, 98, 94, 69, 67,
-  102, 92, 89, 95, 85, 83, 86, 88, 73, 85,
-  50, 72, 59, 89, 76, 91, 91, 90, 79, 83,
-  80, 89, 87, 78, 96, 75, 78, 87, 88, 98,
-  78, 94, 105, 83, 82, 109, 78, 87, 85, 78,
-  77, 89, 91, 79, 72, 75, 76, 75, 84, 79,
-  70, 81, 76, 78, 84, 80, 91, 93, 73, 85,
-  95, 117, 92, 66, 90, 85, 74, 103, 85, 73,
-  74, 95, 87, 80, 93, 88, 74, 86, 75, 80,
-  79, 83, 80, 77, 86, 76, 94, 81, 85, 83,
-  82, 86, 85, 88, 78, 83, 81, 75, 85, 93,
-  84, 80, 77, 90, 89, 72, 78, 75, 90, 80,
-  71, 81, 85, 92, 82, 80, 84, 84, 75, 80,
-  92, 75, 81, 78, 99, 86, 80, 76, 97, 94,
-  84, 93, 82, 81, 83, 86, 75, 84, 57, 76,
-  82, 84, 77, 90, 83, 87, 77, 78, 85, 87,
-  91, 84, 106, 76, 81, 79, 81, 106, 76, 93,
-  111, 78, 85, 119, 82, 86, 94, 73, 78, 79,
-  91, 87, 75, 74, 85, 78, 85, 82, 74, 77,
-  68, 76, 86, 81, 89, 87, 75, 82, 88, 119,
-  96, 67, 94, 84, 73, 101, 75, 74, 75, 96,
-  85, 81, 93, 81, 80, 76, 78, 72, 76, 81,
-  82, 76, 82, 74, 83, 86, 84, 76, 87, 83,
-  85, 90, 79, 75, 84, 67, 89, 80, 80, 71,
-  80, 88, 99, 72, 82, 75, 95, 91, 74, 73,
-  80, 93, 80, 79, 99, 83, 81, 82, 88, 72,
-  87, 80, 100, 89, 88, 78, 101, 88, 82, 85,
-  86, 85, 83, 86, 68, 80, 72, 72, 82, 77,
-  78, 85, 85, 84, 78, 81, 84, 90, 94, 80,
-  103, 76, 77, 86, 81, 106, 74, 89, 110, 77,
-  83, 115, 79, 89, 87, 72, 72, 78, 91, 85,
-  75, 77, 74, 78, 85, 82, 75, 82, 73, 79,
-  90, 82, 88, 84, 79, 84, 88, 117, 101, 61,
-  96, 81, 78, 102, 70, 71, 71, 94, 88, 82,
-  91, 82, 81, 76, 80, 78, 79, 81, 80, 76,
-  84, 81, 84, 88, 82, 79, 87, 75, 83, 89,
-  78, 79, 92, 67, 89, 71, 75, 69, 79, 90,
-  93, 74, 83, 73, 93, 89, 76, 81, 84, 94,
-  84, 81, 92, 84, 83, 87, 90, 76, 89, 80,
-  101, 91, 92, 73, 97, 90, 85, 91, 84, 88,
-  78, 88, 71, 82, 59, 75, 75, 80, 76, 88,
-  88, 86, 76, 79, 87, 88, 84, 76, 100, 76,
-  82, 77, 84, 102, 75, 90, 105, 86, 87, 115,
-  76, 87, 85, 77, 79, 81, 93, 82, 74, 78,
-  80, 72, 86, 81, 77, 79, 72, 79, 87, 80,
-  89, 84, 80, 81, 92, 112, 94, 66, 96, 82,
-  73, 98, 79, 76, 71, 97, 86, 82, 95, 87,
-  83, 78, 78, 79, 80, 84, 82, 77, 88, 76,
-  87, 89, 84, 76, 83, 81, 82, 87, 78, 85,
-  88, 70, 88, 84, 82, 82, 77, 90, 86, 79,
-  80, 82, 93, 87, 75, 73, 79, 94, 82, 79,
-  85, 91, 84, 81, 89, 74, 84, 78, 100, 85,
-  92, 77, 95, 89, 80, 91, 84, 85, 77, 84,
-  72, 84, 65, 74, 85, 79, 79, 85, 82, 86,
-  72, 72, 75, 89, 87, 81, 80, 92, 90, 84,
-  84, 155, 112, 92, 70, 79, 62, 60, 91, 74,
-  89, 94, 82, 77, 76, 76, 73, 89, 92, 89,
-  107, 88, 68, 96, 98, 89, 73, 90, 94, 76,
-  90, 73, 54, 76, 65, 73, 79, 73, 84, 75,
-  86, 91, 86, 87, 81, 96, 73, 60, 97, 93,
-  90, 92, 81, 105, 90, 49, 97, 88, 93, 111,
-  69, 84, 75, 80, 74, 74, 107, 69, 73, 82,
-  86, 118, 64, 75, 73, 93, 83, 98, 61, 95,
-  82, 90, 79, 70, 78, 75, 104, 104, 82, 77,
-  91, 67, 77, 70, 82, 74, 81, 82, 86, 85,
-  96, 62, 81, 88, 88, 94, 67, 77, 93, 66,
-  110, 106, 73, 88, 85, 92, 74, 81, 75, 81,
-  71, 82, 90, 62, 79, 86, 87, 85, 86, 144,
-  105, 87, 76, 86, 74, 68, 88, 80, 54, 87,
-  68, 75, 79, 78, 76, 89, 93, 87, 109, 107,
-  71, 92, 97, 90, 86, 89, 91, 78, 93, 87,
-  89, 77, 71, 69, 84, 74, 74, 76, 92, 93,
-  84, 90, 80, 87, 74, 65, 101, 94, 89, 88,
-  80, 99, 83, 64, 89, 84, 87, 100, 81, 83,
-  70, 81, 80, 73, 101, 80, 81, 77, 90, 108,
-  73, 70, 76, 90, 72, 95, 72, 97, 81, 102,
-  87, 72, 81, 72, 107, 109, 67, 74, 97, 98,
-  81, 71, 76, 73, 75, 84, 84, 85, 100, 68,
-  82, 78, 92, 77, 64, 79, 94, 64, 86, 97,
-  72, 89, 84, 85, 81, 83, 72, 85, 75, 91,
-  95, 81, 85, 78, 72, 91, 79, 81, 64, 89,
-  70, 89, 75, 80, 91, 82, 92, 65, 84, 94,
-  87, 90, 79, 87, 94, 78, 70, 92, 70, 82,
-  90, 85, 75, 87, 79, 80, 82, 80, 75, 81,
-  78, 86, 82, 107, 89, 81, 92, 81, 82, 83,
-  87, 84, 75, 79, 79, 75, 84, 103, 71, 73,
-  96, 70, 83, 85, 94, 86, 84, 86, 103, 86,
-  88, 100, 79, 83, 92, 86, 89, 81, 93, 78,
-  76, 74, 91, 90, 83, 94, 87, 92, 88, 78,
-  110, 84, 91, 81, 78, 90, 83, 83, 80, 75,
-  89, 74, 67, 75, 80, 62, 90, 78, 81, 79,
-  78, 94, 95, 87, 68, 82, 91, 71, 80, 81,
-  91, 89, 80, 80, 84, 80, 60, 76, 87, 77,
-  85, 118, 101, 79, 75, 185, 114, 87, 76, 69,
-  76, 71, 91, 76, 103, 100, 75, 73, 76, 81,
-  72, 81, 98, 77, 114, 84, 74, 105, 98, 85,
-  85, 92, 97, 78, 79, 86, 68, 83, 76, 84,
-  73, 78, 82, 77, 86, 90, 96, 89, 81, 108,
-  75, 45, 102, 79, 75, 84, 90, 98, 76, 50,
-  85, 86, 89, 83, 75, 78, 74, 80, 84, 64,
-  96, 74, 72, 89, 89, 124, 77, 67, 80, 89,
-  81, 97, 61, 80, 73, 76, 72, 64, 75, 78,
-  90, 105, 93, 68, 79, 76, 86, 69, 83, 97,
-  91, 91, 86, 104, 102, 71, 82, 82, 93, 77,
-  61, 78, 89, 70, 94, 102, 78, 95, 80, 84,
-  73, 89, 84, 89, 82, 72, 88, 60, 83, 101,
-  99, 80, 75, 161, 110, 109, 83, 78, 83, 80,
-  85, 80, 55, 84, 70, 70, 82, 81, 72, 83,
-  93, 94, 104, 97, 76, 91, 89, 84, 95, 89,
-  93, 79, 86, 83, 110, 85, 78, 76, 85, 65,
-  72, 80, 87, 85, 95, 95, 77, 87, 76, 54,
-  95, 80, 77, 82, 87, 93, 75, 60, 95, 80,
-  77, 91, 69, 81, 67, 76, 85, 63, 90, 80,
-  61, 80, 94, 110, 84, 84, 76, 99, 69, 92,
-  69, 89, 75, 75, 76, 65, 64, 77, 87, 109,
-  73, 64, 89, 74, 86, 72, 77, 95, 88, 85,
-  84, 101, 97, 75, 83, 76, 98, 69, 78, 79,
-  96, 71, 77, 94, 75, 93, 81, 82, 79, 88,
-  75, 99, 72, 84, 89, 75, 90, 84, 78, 84,
-  82, 99, 69, 100, 81, 83, 78, 80, 80, 79,
-  88, 72, 83, 93, 86, 87, 74, 80, 95, 81,
-  64, 84, 71, 84, 89, 87, 77, 86, 76, 86,
-  86, 84, 88, 80, 84, 85, 78, 107, 90, 83,
-  93, 81, 89, 85, 75, 80, 78, 73, 76, 73,
-  77, 102, 83, 76, 85, 74, 87, 78, 88, 82,
-  80, 89, 99, 82, 87, 88, 75, 82, 79, 91,
-  96, 83, 90, 85, 73, 86, 87, 86, 80, 90,
-  77, 82, 84, 75, 92, 84, 80, 87, 75, 84,
-  82, 72, 80, 74, 87, 79, 74, 80, 78, 74,
-  86, 79, 80, 85, 84, 77, 105, 87, 62, 83,
-  85, 69, 78, 79, 89, 90, 70, 80, 76, 75,
-  67, 79, 85, 77, 84, 103, 86, 83, 88, 124,
-  97, 79, 64, 75, 79, 79, 98, 82, 100, 90,
-  71, 82, 81, 94, 86, 83, 86, 73, 107, 88,
-  80, 96, 86, 90, 86, 88, 83, 83, 73, 80,
-  76, 72, 81, 78, 70, 91, 87, 77, 85, 92,
-  93, 78, 87, 90, 79, 51, 100, 83, 72, 86,
-  87, 101, 83, 63, 85, 94, 85, 77, 84, 77,
-  101, 90, 82, 78, 76, 69, 88, 87, 80, 104,
-  80, 82, 82, 84, 82, 89, 68, 80, 76, 83,
-  87, 80, 81, 77, 91, 87, 78, 89, 87, 90,
-  89, 71, 85, 89, 80, 98, 84, 85, 96, 81,
-  75, 87, 87, 83, 60, 79, 81, 86, 86, 87,
-  78, 90, 91, 86, 80, 87, 76, 90, 79, 77,
-  83, 61, 80, 89, 82, 80, 84, 108, 97, 97,
-  71, 79, 86, 84, 89, 81, 65, 81, 75, 79,
-  84, 91, 86, 86, 80, 95, 98, 91, 82, 86,
-  79, 84, 95, 87, 92, 82, 80, 79, 101, 76,
-  81, 75, 80, 66, 82, 79, 87, 89, 90, 83,
-  82, 75, 81, 61, 95, 87, 78, 85, 83, 100,
-  82, 70, 95, 93, 79, 89, 66, 80, 94, 83,
-  84, 75, 78, 85, 77, 82, 85, 96, 86, 91,
-  83, 97, 72, 86, 73, 84, 79, 75, 87, 77,
-  73, 78, 86, 92, 85, 84, 91, 84, 88, 74,
-  82, 96, 81, 91, 84, 88, 87, 81, 78, 77,
-  94, 84, 93, 81, 89, 87, 86, 92, 71, 89,
-  89, 87, 83, 88, 77, 97, 71, 88, 80, 82,
-  89, 80, 71, 85, 83, 69, 78, 90, 68, 80,
-  77, 85, 89, 78, 84, 76, 90, 90, 80, 90,
-  85, 84, 84, 81, 81, 83, 72, 86, 86, 81,
-  78, 81, 83, 81, 87, 85, 81, 82, 84, 79,
-  83, 98, 89, 75, 91, 92, 90, 78, 87, 80,
-  86, 76, 78, 79, 83, 85, 84, 80, 87, 79,
-  85, 81, 90, 79, 90, 83, 109, 80, 81, 94,
-  72, 88, 81, 86, 89, 71, 91, 79, 80, 89,
-  88, 82, 85, 89, 85, 89, 91, 81, 95, 80,
-  84, 80, 85, 90, 80, 87, 87, 76, 83, 80,
-  74, 90, 87, 79, 83, 78, 80, 86, 88, 84,
-  109, 85, 72, 88, 91, 78, 75, 81, 92, 92,
-  75, 82, 73, 91, 85, 74, 79, 79, 66, 82,
-  96, 86, 83, 96, 81, 91, 66, 87, 67, 63,
-  79, 95, 85, 82, 92, 84, 83, 68, 96, 92,
-  93, 72, 92, 85, 78, 81, 74, 84, 120, 75,
-  98, 79, 79, 82, 76, 75, 80, 88, 82, 72,
-  70, 76, 65, 82, 77, 77, 88, 101, 80, 74,
-  87, 75, 95, 82, 85, 81, 67, 74, 102, 100,
-  87, 108, 80, 80, 81, 83, 75, 82, 74, 79,
-  70, 64, 86, 92, 73, 88, 79, 86, 75, 112,
-  71, 95, 89, 102, 79, 74, 93, 59, 80, 83,
-  77, 100, 88, 86, 101, 76, 88, 97, 63, 96,
-  82, 86, 85, 77, 77, 90, 87, 104, 76, 77,
-  80, 92, 96, 84, 80, 89, 80, 82, 86, 87,
-  95, 83, 82, 80, 82, 82, 72, 77, 93, 82,
-  86, 95, 76, 107, 72, 92, 69, 68, 90, 86,
-  81, 80, 91, 81, 78, 74, 98, 93, 96, 71,
-  97, 88, 76, 88, 81, 78, 120, 74, 86, 81,
-  75, 92, 77, 80, 81, 81, 91, 60, 59, 69,
-  71, 99, 81, 72, 93, 92, 84, 76, 84, 68,
-  90, 77, 97, 87, 66, 81, 86, 84, 89, 103,
-  92, 76, 70, 75, 74, 80, 70, 73, 71, 68,
-  86, 89, 63, 81, 76, 84, 82, 100, 63, 94,
-  88, 112, 85, 79, 99, 66, 89, 91, 78, 80,
-  74, 79, 105, 78, 90, 87, 65, 91, 83, 88,
-  86, 66, 69, 84, 98, 84, 84, 68, 65, 93,
-  100, 74, 80, 80, 85, 83, 89, 75, 78, 69,
-  70, 80, 83, 80, 72, 79, 92, 85, 83, 93,
-  83, 100, 73, 81, 67, 69, 81, 88, 83, 78,
-  87, 86, 82, 72, 100, 95, 85, 69, 101, 80,
-  82, 92, 87, 83, 121, 82, 72, 82, 75, 85,
-  78, 78, 79, 87, 84, 77, 66, 77, 65, 88,
-  79, 78, 89, 71, 82, 72, 88, 73, 93, 78,
-  88, 81, 69, 78, 93, 101, 93, 111, 78, 79,
-  78, 76, 76, 78, 81, 75, 76, 65, 86, 89,
-  74, 89, 80, 80, 86, 99, 70, 104, 84, 112,
-  80, 75, 94, 68, 79, 83, 87, 94, 81, 97,
-  103, 80, 98, 95, 65, 94, 85, 89, 86, 73,
-  77, 86, 97, 98, 83, 78, 74, 93, 95, 85,
-  84, 84, 83, 85, 91, 89, 74, 94, 83, 65,
-  90, 94, 85, 77, 80, 80, 82, 93, 72, 123,
-  81, 71, 72, 66, 79, 86, 82, 85, 100, 82,
-  87, 75, 87, 82, 95, 76, 102, 88, 90, 71,
-  69, 103, 106, 90, 82, 79, 84, 88, 90, 71,
-  82, 74, 81, 72, 87, 84, 75, 80, 82, 82,
-  84, 87, 77, 62, 84, 85, 100, 85, 92, 75,
-  95, 78, 80, 111, 77, 86, 64, 103, 64, 76,
-  82, 87, 77, 71, 77, 78, 81, 80, 78, 69,
-  70, 86, 87, 99, 71, 106, 76, 75, 93, 104,
-  78, 74, 78, 98, 97, 83, 74, 90, 95, 74,
-  91, 93, 79, 79, 84, 81, 80, 72, 67, 94,
-  99, 105, 64, 98, 70, 94, 98, 90, 91, 77,
-  72, 74, 84, 88, 90, 85, 56, 71, 84, 82,
-  88, 77, 75, 73, 87, 93, 78, 97, 88, 79,
-  79, 79, 95, 72, 80, 73, 89, 82, 93, 80,
-  82, 81, 89, 72, 111, 106, 85, 68, 75, 74,
-  84, 101, 85, 79, 74, 88, 83, 76, 81, 81,
-  83, 61, 78, 85, 75, 84, 81, 84, 81, 84,
-  86, 65, 82, 99, 114, 74, 91, 87, 80, 76,
-  88, 117, 77, 70, 66, 88, 62, 78, 73, 82,
-  72, 69, 79, 83, 83, 71, 75, 77, 57, 75,
-  91, 69, 67, 121, 72, 75, 96, 129, 71, 80,
-  77, 124, 93, 73, 67, 72, 87, 76, 85, 100,
-  78, 67, 70, 82, 73, 74, 72, 89, 84, 92,
-  69, 105, 55, 94, 106, 79, 86, 76, 66, 74,
-  96, 84, 81, 73, 55, 77, 89, 90, 86, 75,
-  81, 78, 86, 88, 81, 76, 84, 74, 72, 80,
-  85, 81, 88, 78, 100, 82, 95, 77, 84, 82,
-  85, 74, 101, 96, 86, 83, 85, 89, 104, 97,
-  96, 81, 80, 85, 87, 75, 82, 81, 84, 83,
-  81, 89, 70, 86, 82, 88, 79, 93, 76, 64,
-  83, 80, 97, 74, 86, 77, 86, 79, 84, 118,
-  73, 87, 87, 97, 62, 75, 74, 86, 79, 74,
-  81, 79, 86, 74, 79, 97, 74, 73, 91, 90,
-  74, 110, 75, 85, 89, 101, 85, 80, 80, 94,
-  89, 84, 73, 80, 91, 79, 89, 95, 78, 75,
-  74, 81, 79, 74, 72, 86, 85, 111, 83, 99,
-  69, 85, 91, 84, 94, 78, 72, 78, 92, 84,
-  78, 98, 90, 80, 100, 96, 87, 86, 79, 81,
-  87, 77, 71, 86, 86, 76, 77, 75, 81, 90,
-  79, 83, 90, 90, 84, 78, 81, 81, 89, 79,
-  98, 86, 101, 79, 82, 106, 80, 84, 92, 80,
-  87, 77, 84, 82, 83, 85, 85, 76, 87, 91,
-  78, 85, 78, 91, 96, 97, 81, 70, 84, 90,
-  96, 103, 76, 81, 96, 80, 79, 99, 82, 77,
-  79, 87, 81, 77, 92, 80, 72, 86, 82, 83,
-  90, 73, 99, 74, 77, 74, 83, 84, 90, 100,
-  92, 78, 89, 107, 88, 78, 85, 88, 98, 80,
-  76, 93, 84, 87, 81, 92, 90, 87, 86, 79,
-  82, 76, 78, 85, 86, 90, 84, 91, 72, 89,
-  89, 77, 80, 84, 69, 86, 77, 88, 80, 84,
-  70, 90, 89, 98, 91, 89, 72, 70, 89, 74,
-  83, 84, 101, 85, 87, 86, 78, 81, 79, 79,
-  96, 80, 85, 80, 80, 74, 84, 77, 106, 83,
-  94, 74, 74, 77, 73, 67, 85, 70, 80, 81,
-  86, 88, 75, 91, 82, 77, 87, 86, 78, 90,
-  75, 89, 93, 83, 83, 72, 80, 110, 107, 88,
-  77, 87, 96, 84, 87, 105, 84, 79, 75, 74,
-  72, 84, 84, 72, 71, 88, 78, 89, 90, 73,
-  99, 77, 71, 71, 87, 66, 89, 99, 81, 85,
-  82, 127, 82, 84, 82, 105, 82, 73, 73, 86,
-  74, 89, 77, 101, 98, 81, 70, 67, 83, 78,
-  84, 88, 90, 86, 96, 90, 64, 88, 84, 73,
-  67, 89, 57, 87, 79, 81, 75, 79, 73, 93,
-  96, 90, 87, 81, 80, 79, 92, 77, 80, 95,
-  95, 81, 75, 79, 80, 86, 86, 77, 100, 85,
-  90, 76, 81, 80, 83, 89, 93, 90, 93, 80,
-  82, 84, 78, 85, 81, 73, 91, 78, 79, 77,
-  83, 91, 86, 95, 86, 92, 81, 87, 79, 95,
-  94, 78, 76, 69, 79, 90, 97, 89, 80, 81,
-  94, 80, 95, 101, 84, 76, 86, 89, 73, 76,
-  86, 86, 80, 80, 77, 85, 97, 77, 94, 91,
-  75, 74, 81, 80, 93, 102, 85, 80, 87, 108,
-  93, 81, 87, 86, 86, 76, 78, 74, 83, 90,
-  87, 100, 87, 87, 79, 76, 87, 75, 83, 83,
-  93, 96, 98, 90, 78, 82, 79, 74, 82, 86,
-  66, 86, 82, 87, 76, 91, 98, 75, 73, 83,
-  115, 93, 78, 85, 85, 72, 94, 75, 96, 89,
-  90, 86, 89, 82, 76, 87, 82, 83, 83, 75,
-  76, 82, 91, 81, 90, 76, 82, 68, 83, 86,
-  91, 80, 84, 90, 73, 87, 80, 100, 82, 94,
-  84, 81, 80, 95, 97, 96, 90, 87, 74, 97,
-  77, 93, 90, 89, 73, 84, 81, 91, 92, 78,
-  74, 73, 84, 84, 87, 74, 78, 78, 81, 82,
-  98, 74, 83, 99, 99, 83, 74, 69, 84, 78,
-  80, 66, 94, 89, 83, 71, 74, 66, 78, 84,
-  82, 87, 83, 97, 105, 81, 84, 76, 78, 84,
-  76, 91, 84, 74, 78, 87, 89, 80, 80, 80,
-  74, 84, 85, 96, 106, 77, 75, 88, 111, 78,
-  78, 87, 77, 81, 100, 80, 81, 79, 115, 84,
-  76, 80, 79, 81, 113, 81, 97, 91, 95, 87,
-  85, 78, 86, 91, 80, 82, 85, 69, 72, 79,
-  81, 76, 97, 82, 83, 73, 78, 71, 91, 78,
-  85, 96, 71, 86, 81, 111, 82, 103, 82, 73,
-  77, 91, 94, 105, 90, 85, 72, 91, 68, 91,
-  90, 90, 75, 79, 80, 99, 86, 80, 73, 76,
-  82, 80, 88, 71, 71, 77, 84, 72, 99, 75,
-  86, 98, 96, 81, 75, 80, 83, 77, 85, 58,
-  96, 101, 75, 74, 72, 70, 79, 90, 79, 91,
-  86, 93, 104, 75, 79, 76, 77, 83, 72, 95,
-  88, 69, 84, 87, 88, 88, 91, 81, 74, 81,
-  87, 92, 88, 80, 71, 90, 113, 80, 79, 92,
-  79, 71, 87, 78, 79, 76, 111, 85, 79, 85,
-  81, 69, 85, 75, 94, 86, 92, 87, 93, 68,
-  86, 90, 81, 83, 76, 75, 76, 82, 89, 78,
-  91, 82, 77, 83, 89, 73, 90, 81, 77, 94,
-  72, 89, 77, 97, 78, 99, 84, 73, 77, 94,
-  97, 90, 87, 85, 71, 81, 77, 92, 89, 86,
-  75, 83, 81, 91, 90, 80, 76, 75, 80, 81,
-  83, 77, 74, 80, 78, 87, 97, 89, 87, 97,
-  98, 85, 75, 94, 85, 81, 83, 75, 96, 98,
-  84, 79, 77, 71, 88, 85, 85, 87, 84, 94,
-  108, 81, 83, 72, 81, 83, 74, 93, 86, 74,
-  84, 88, 87, 83, 89, 82, 91, 81, 82, 88,
-  73, 78, 81, 86, 105, 76, 81, 92, 79, 89,
-  102, 75, 81, 88, 118, 94, 76, 80, 79, 72,
-  93, 78, 97, 82, 100, 87, 90, 82, 81, 82,
-  86, 79, 86, 76, 73, 75, 85, 71, 100, 75,
-  77, 71, 84, 87, 86, 77, 80, 88, 72, 86,
-  78, 110, 83, 91, 88, 84, 79, 83, 100, 100,
-  83, 85, 74, 102, 76, 99, 90, 87, 73, 84,
-  79, 87, 91, 75, 74, 77, 85, 80, 86, 70,
-  79, 79, 81, 72, 97, 72, 75, 108, 93, 87,
-  69, 69, 93, 80, 82, 61, 99, 71, 77, 74,
-  77, 76, 76, 90, 84, 94, 83, 86, 90, 86,
-  83, 74, 82, 84, 78, 89, 81, 78, 87, 92,
-  85, 75, 89, 78, 72, 87, 83, 85, 89, 79,
-  69, 87, 108, 85, 78, 86, 80, 83, 97, 81,
-  86, 81, 120, 85, 76, 71, 75, 83, 124, 84,
-  101, 81, 108, 88, 83, 78, 85, 85, 78, 76,
-  91, 70, 67, 73, 73, 72, 108, 78, 78, 76,
-  79, 70, 85, 73, 86, 96, 72, 96, 82, 122,
-  87, 95, 93, 74, 78, 80, 100, 109, 83, 84,
-  75, 104, 67, 100, 85, 87, 72, 82, 77, 104,
-  83, 83, 74, 82, 82, 77, 90, 67, 72, 78,
-  87, 62, 100, 72, 74, 107, 88, 84, 73, 76,
-  97, 84, 81, 53, 102, 76, 67, 71, 74, 80,
-  72, 102, 81, 102, 90, 83, 83, 80, 75, 73,
-  81, 86, 74, 91, 89, 74, 92, 96, 86, 83,
-  97, 79, 75, 85, 91, 80, 68, 86, 64, 93,
-  111, 83, 78, 94, 74, 75, 87, 79, 86, 81,
-  112, 87, 77, 81, 77, 67, 88, 82, 94, 84,
-  95, 87, 92, 70, 79, 82, 86, 79, 79, 77,
-  72, 78, 79, 75, 93, 77, 72, 80, 85, 74,
-  82, 81, 78, 91, 72, 85, 84, 105, 81, 94,
-  88, 76, 76, 82, 102, 89, 84, 84, 68, 96,
-  76, 100, 88, 84, 75, 83, 78, 88, 90, 75,
-  80, 80, 79, 77, 88, 72, 76, 84, 81, 80,
-  94, 89, 74, 102, 96, 89, 71, 94, 89, 82,
-  79, 70, 97, 89, 78, 79, 82, 80, 85, 89,
-  89, 93, 80, 81, 98, 76, 82, 70, 84, 81,
-  81, 88, 83, 80, 82, 93, 87, 88, 87, 80,
-  95, 85, 83, 81, 62, 79, 80, 86, 104, 81,
-  82, 87, 80, 92, 95, 82, 82, 89, 110, 100,
-  84, 83, 79, 77, 91, 72, 91, 81, 100, 88,
-  92, 77, 85, 81, 87, 70, 83, 81, 76, 78,
-  90, 75, 86, 77, 76, 64, 87, 88, 94, 80,
-  79, 92, 72, 86, 72, 102, 76, 96, 78, 87,
-  75, 90, 94, 91, 84, 81, 71, 83, 69, 90,
-  94, 78, 73, 87, 81, 86, 90, 78, 82, 81,
-  81, 80, 85, 76, 86, 90, 74, 87, 95, 75,
-  75, 100, 85, 79, 67, 72, 88, 81, 84, 75,
-  88, 63, 90, 88, 79, 79, 82, 86, 90, 88,
-  72, 90, 100, 96, 87, 72, 80, 76, 80, 88,
-  77, 80, 85, 82, 83, 84, 86, 86, 75, 85,
-  84, 82, 83, 76, 86, 85, 99, 87, 83, 84,
-  79, 88, 91, 84, 85, 80, 113, 98, 85, 77,
-  77, 87, 117, 84, 94, 82, 103, 87, 87, 74,
-  82, 80, 80, 68, 82, 76, 74, 79, 79, 77,
-  83, 83, 82, 71, 85, 74, 97, 77, 82, 94,
-  77, 86, 80, 108, 79, 97, 82, 72, 75, 90,
-  93, 89, 86, 82, 69, 86, 68, 88, 90, 78,
-  70, 84, 84, 94, 82, 74, 87, 86, 78, 75,
-  82, 72, 81, 87, 77, 78, 95, 77, 78, 97,
-  83, 77, 67, 84, 90, 86, 85, 64, 86, 70,
-  83, 82, 74, 83, 77, 90, 86, 92, 83, 89,
-  98, 87, 84, 73, 82, 81, 81, 91, 83, 78,
-  85, 86, 87, 82, 86, 86, 79, 85, 96, 78,
-  68, 82, 81, 90, 99, 83, 84, 91, 73, 74,
-  85, 79, 86, 80, 106, 93, 82, 83, 77, 70,
-  93, 88, 89, 82, 92, 88, 94, 66, 73, 83,
-  92, 73, 79, 80, 76, 81, 87, 72, 78, 79,
-  75, 74, 86, 75, 90, 82, 76, 90, 75, 88,
-  88, 98, 77, 93, 80, 77, 74, 90, 95, 85,
-  85, 82, 70, 90, 72, 89, 92, 76, 74, 90,
-  81, 90, 88, 76, 91, 85, 77, 82, 87, 77,
-  79, 91, 76, 89, 90, 91, 73, 97, 87, 81,
-  72, 95, 85, 83, 86, 79, 82, 77, 87, 82,
-  82, 81, 82, 86, 90, 88, 77, 86, 105, 80,
-  85, 73, 82, 76, 84, 87, 80, 82, 78, 86,
-  86, 84, 79, 90, 94, 83, 86, 81, 61, 78,
-  85, 84, 97, 82, 81, 89, 85, 89, 97, 87,
-  96, 99, 79, 86, 92, 84, 97, 76, 92, 80,
-  82, 82, 95, 87, 82, 99, 91, 92, 89, 94,
-  86, 68, 79, 85, 59, 77, 78, 71, 88, 69,
-  88, 89, 90, 82, 89, 79, 88, 78, 86, 79,
-  81, 88, 85, 81, 68, 81, 86, 98, 82, 78,
-  111, 88, 77, 75, 85, 88, 62, 82, 72, 85,
-  82, 69, 84, 84, 85, 79, 82, 75, 110, 79,
-  90, 77, 90, 99, 69, 74, 85, 93, 76, 81,
-  79, 92, 75, 72, 93, 65, 86, 78, 78, 105,
-  86, 73, 78, 87, 87, 91, 71, 78, 80, 101,
-  81, 82, 99, 87, 85, 86, 83, 70, 84, 87,
-  98, 97, 97, 81, 88, 76, 90, 84, 88, 76,
-  100, 77, 92, 101, 80, 92, 96, 81, 104, 93,
-  82, 86, 116, 79, 93, 75, 105, 88, 89, 83,
-  97, 90, 82, 86, 101, 122, 82, 101, 81, 63,
-  90, 85, 89, 77, 81, 65, 92, 69, 87, 80,
-  97, 87, 93, 91, 90, 73, 90, 82, 76, 109,
-  102, 84, 49, 87, 90, 123, 86, 77, 112, 97,
-  74, 79, 95, 83, 67, 74, 74, 84, 74, 76,
-  83, 74, 86, 73, 88, 59, 122, 77, 79, 61,
-  95, 87, 76, 71, 94, 96, 87, 89, 64, 88,
-  79, 63, 113, 69, 77, 75, 64, 96, 82, 71,
-  60, 88, 87, 96, 71, 86, 78, 101, 87, 79,
-  107, 82, 86, 100, 93, 69, 84, 81, 98, 93,
-  95, 82, 103, 83, 96, 86, 80, 72, 97, 72,
-  92, 126, 77, 100, 81, 90, 98, 94, 79, 85,
-  102, 83, 98, 72, 89, 83, 89, 89, 97, 91,
-  80, 93, 87, 102, 91, 99, 80, 67, 82, 86,
-  84, 74, 81, 69, 90, 86, 89, 77, 100, 86,
-  84, 87, 88, 78, 95, 80, 79, 101, 94, 99,
-  61, 83, 87, 109, 86, 76, 114, 89, 77, 82,
-  89, 84, 67, 77, 74, 85, 80, 75, 78, 84,
-  87, 67, 94, 64, 116, 79, 92, 74, 93, 72,
-  84, 70, 94, 97, 84, 101, 72, 92, 90, 65,
-  111, 68, 82, 81, 69, 103, 94, 74, 68, 88,
-  87, 94, 69, 101, 83, 99, 86, 80, 99, 88,
-  84, 92, 92, 69, 85, 76, 94, 83, 98, 83,
-  89, 79, 77, 87, 87, 76, 97, 79, 83, 104,
-  90, 79, 85, 86, 85, 97, 65, 90, 82, 83,
-  88, 77, 84, 83, 91, 74, 94, 79, 80, 92,
-  82, 79, 88, 79, 78, 83, 75, 80, 53, 74,
-  81, 86, 82, 75, 87, 94, 74, 83, 74, 69,
-  89, 83, 93, 80, 78, 73, 72, 92, 77, 73,
-  89, 83, 78, 83, 85, 88, 72, 79, 69, 83,
-  71, 87, 73, 82, 76, 74, 86, 106, 85, 66,
-  77, 84, 89, 86, 92, 84, 83, 92, 69, 75,
-  79, 90, 76, 77, 94, 82, 81, 84, 84, 61,
-  86, 85, 89, 101, 83, 84, 87, 88, 80, 77,
-  59, 93, 84, 94, 78, 86, 82, 83, 71, 76,
-  79, 75, 81, 86, 73, 86, 83, 86, 88, 73,
-  80, 86, 92, 83, 88, 81, 85, 77, 101, 82,
-  84, 78, 88, 86, 67, 93, 84, 76, 93, 78,
-  97, 83, 92, 66, 96, 81, 82, 76, 83, 94,
-  84, 80, 72, 83, 88, 75, 79, 86, 84, 83,
-  82, 65, 91, 87, 78, 87, 86, 64, 93, 87,
-  82, 76, 76, 75, 76, 84, 69, 69, 91, 82,
-  75, 81, 79, 94, 74, 84, 75, 80, 65, 84,
-  78, 91, 59, 80, 91, 92, 77, 61, 74, 88,
-  96, 89, 86, 70, 86, 82, 68, 72, 83, 94,
-  81, 94, 94, 81, 78, 77, 82, 62, 78, 80,
-  92, 116, 77, 79, 78, 86, 82, 74, 46, 87,
-  86, 92, 75, 87, 81, 86, 75, 85, 81, 72,
-  88, 74, 82, 92, 82, 82, 97, 71, 82, 85,
-  94, 82, 79, 81, 85, 88, 91, 90, 81, 86,
-  84, 86, 67, 87, 83, 81, 95, 73, 90, 78,
-  90, 78, 92, 83, 83, 82, 84, 82, 96, 80,
-  74, 78, 79, 78, 75, 80, 82, 82, 88, 78,
-  88, 86, 81, 86, 86, 72, 90, 79, 84, 80,
-  78, 79, 74, 91, 74, 77, 91, 92, 77, 79,
-  88, 86, 74, 82, 75, 83, 71, 87, 78, 83,
-  72, 82, 93, 96, 83, 71, 79, 83, 91, 92,
-  86, 83, 85, 79, 63, 73, 82, 92, 82, 105,
-  90, 90, 78, 80, 90, 65, 88, 84, 85, 105,
-  84, 79, 80, 86, 79, 82, 57, 88, 83, 92,
-  77, 83, 79, 88, 68, 80, 81, 70, 83, 77,
-  84, 86, 95, 84, 90, 76, 76, 86, 90, 82,
-  82, 85, 81, 82, 100, 70, 82, 79, 83, 88,
-  73, 83, 77, 81, 83, 86, 87, 78, 96, 84,
-  93, 85, 76, 91, 84, 68, 78, 72, 75, 92,
-  87, 85, 76, 92, 88, 90, 81, 83, 91, 89,
-  86, 86, 69, 74, 86, 79, 106, 80, 93, 63,
-  75, 95, 86, 73, 78, 61, 67, 92, 67, 80,
-  80, 83, 67, 82, 82, 99, 79, 98, 78, 78,
-  89, 114, 95, 79, 82, 82, 88, 88, 94, 87,
-  72, 83, 82, 85, 72, 78, 73, 89, 105, 77,
-  79, 98, 70, 71, 89, 101, 92, 87, 77, 80,
-  89, 87, 86, 80, 66, 92, 78, 91, 82, 83,
-  87, 95, 80, 72, 92, 77, 84, 81, 80, 67,
-  78, 96, 89, 84, 76, 82, 87, 84, 76, 92,
-  89, 57, 99, 75, 80, 79, 73, 86, 70, 85,
-  73, 72, 79, 95, 81, 78, 93, 77, 99, 85,
-  73, 91, 90, 57, 86, 66, 77, 109, 83, 77,
-  112, 94, 88, 86, 75, 77, 90, 96, 83, 81,
-  74, 69, 89, 74, 98, 80, 89, 53, 63, 85,
-  100, 64, 74, 49, 64, 96, 55, 82, 82, 78,
-  57, 79, 81, 102, 95, 88, 76, 73, 95, 117,
-  91, 78, 86, 88, 83, 90, 98, 76, 66, 82,
-  94, 83, 70, 87, 66, 91, 125, 81, 85, 104,
-  59, 66, 81, 98, 96, 92, 83, 85, 91, 83,
-  74, 67, 55, 81, 81, 90, 80, 80, 79, 96,
-  73, 68, 90, 78, 94, 79, 83, 70, 85, 97,
-  78, 82, 77, 81, 84, 84, 64, 100, 86, 49,
-  106, 82, 90, 82, 82, 82, 78, 86, 77, 80,
-  89, 86, 88, 71, 92, 85, 99, 88, 82, 88,
-  99, 66, 94, 73, 77, 93, 84, 85, 102, 87,
-  89, 86, 79, 73, 97, 92, 85, 85, 88, 78,
-  89, 83, 89, 80, 97, 64, 68, 83, 87, 71,
-  81, 66, 66, 87, 69, 82, 80, 79, 66, 82,
-  81, 97, 84, 92, 77, 85, 95, 113, 93, 86,
-  84, 80, 90, 94, 98, 86, 76, 84, 81, 89,
-  68, 81, 71, 85, 113, 83, 77, 99, 70, 71,
-  90, 98, 92, 93, 85, 80, 90, 86, 80, 81,
-  66, 77, 83, 90, 87, 85, 86, 97, 75, 71,
-  88, 81, 88, 77, 87, 78, 98, 98, 90, 83,
-  84, 81, 81, 85, 70, 95, 91, 58, 85, 78,
-  98, 70, 68, 84, 94, 78, 100, 47, 78, 98,
-  93, 98, 63, 69, 84, 86, 69, 95, 87, 87,
-  79, 104, 89, 77, 87, 57, 92, 74, 79, 87,
-  72, 85, 70, 115, 94, 75, 85, 75, 83, 87,
-  91, 67, 81, 91, 88, 79, 64, 93, 85, 89,
-  98, 67, 96, 87, 82, 89, 73, 72, 86, 79,
-  79, 87, 73, 71, 81, 80, 87, 124, 79, 79,
-  76, 74, 85, 72, 89, 76, 75, 72, 81, 77,
-  74, 86, 76, 94, 81, 101, 82, 89, 78, 82,
-  63, 84, 114, 82, 101, 103, 98, 90, 78, 75,
-  78, 72, 113, 84, 82, 79, 75, 89, 89, 80,
-  63, 104, 90, 86, 76, 90, 90, 100, 94, 76,
-  83, 90, 86, 93, 89, 90, 84, 91, 86, 63,
-  60, 78, 85, 74, 105, 30, 71, 101, 92, 87,
-  67, 63, 85, 85, 55, 93, 82, 91, 76, 99,
-  83, 78, 84, 47, 99, 73, 76, 90, 74, 79,
-  71, 82, 96, 71, 84, 80, 86, 84, 87, 67,
-  74, 91, 94, 76, 65, 93, 84, 93, 94, 70,
-  95, 98, 71, 92, 64, 67, 78, 76, 80, 74,
-  76, 71, 82, 76, 81, 116, 107, 78, 67, 69,
-  89, 64, 89, 77, 79, 74, 82, 81, 65, 89,
-  69, 80, 87, 97, 84, 83, 64, 84, 60, 81,
-  111, 81, 110, 105, 77, 95, 75, 77, 64, 69,
-  125, 77, 77, 63, 75, 87, 94, 82, 60, 85,
-  94, 76, 80, 94, 88, 99, 97, 78, 74, 82,
-  88, 97, 83, 88, 83, 86, 83, 88, 86, 83,
-  92, 96, 93, 72, 83, 85, 74, 83, 67, 76,
-  80, 78, 91, 98, 89, 87, 74, 96, 86, 87,
-  90, 89, 75, 71, 87, 87, 68, 101, 71, 72,
-  89, 74, 90, 81, 79, 85, 80, 78, 88, 83,
-  89, 93, 69, 87, 94, 77, 88, 74, 88, 86,
-  81, 91, 81, 78, 90, 91, 80, 77, 68, 77,
-  70, 91, 88, 95, 78, 83, 82, 79, 90, 84,
-  88, 84, 78, 78, 81, 82, 87, 91, 87, 86,
-  107, 106, 81, 79, 85, 79, 70, 84, 126, 86,
-  96, 99, 85, 84, 79, 82, 102, 75, 91, 84,
-  79, 85, 70, 90, 92, 80, 73, 81, 78, 87,
-  93, 89, 91, 94, 89, 81, 85, 99, 84, 89,
-  93, 86, 85, 65, 89, 61, 70, 92, 99, 60,
-  94, 26, 69, 74, 94, 95, 70, 69, 84, 87,
-  43, 85, 104, 87, 88, 99, 89, 77, 91, 33,
-  111, 80, 92, 94, 79, 78, 96, 106, 90, 110,
-  86, 78, 76, 92, 88, 74, 73, 84, 104, 81,
-  75, 80, 85, 86, 104, 70, 89, 101, 69, 78,
-  69, 82, 74, 88, 90, 83, 86, 70, 87, 70,
-  84, 86, 95, 76, 79, 92, 82, 67, 93, 79,
-  79, 79, 90, 78, 64, 79, 71, 95, 76, 87,
-  96, 76, 63, 76, 65, 92, 78, 85, 105, 98,
-  93, 95, 65, 84, 60, 64, 109, 75, 86, 78,
-  73, 92, 97, 89, 61, 92, 83, 74, 69, 101,
-  101, 83, 102, 66, 96, 68, 81, 99, 83, 91,
-  84, 102, 78, 51, 69, 66, 96, 53, 100, 5,
-  61, 78, 112, 94, 73, 66, 87, 91, 28, 87,
-  80, 93, 72, 97, 77, 79, 86, 24, 114, 85,
-  93, 103, 89, 67, 89, 72, 92, 120, 91, 87,
-  76, 96, 100, 75, 66, 79, 110, 75, 77, 78,
-  84, 86, 102, 73, 74, 91, 62, 83, 60, 74,
-  74, 86, 89, 88, 62, 75, 94, 72, 90, 74,
-  84, 75, 71, 88, 91, 51, 92, 75, 77, 84,
-  90, 82, 61, 88, 74, 94, 74, 80, 102, 81,
-  58, 71, 57, 97, 62, 85, 108, 104, 101, 91,
-  65, 75, 40, 64, 102, 63, 76, 62, 76, 91,
-  103, 96, 59, 72, 89, 67, 73, 108, 116, 73,
-  87, 66, 88, 61, 81, 97, 76, 95, 84, 96,
-  79, 79, 81, 91, 87, 73, 89, 48, 77, 73,
-  73, 92, 69, 77, 76, 78, 69, 94, 83, 87,
-  89, 94, 80, 87, 98, 61, 91, 83, 79, 90,
-  69, 92, 79, 63, 96, 93, 85, 83, 78, 86,
-  93, 75, 86, 75, 82, 98, 82, 81, 91, 85,
-  83, 74, 97, 86, 77, 85, 77, 85, 82, 91,
-  87, 78, 87, 77, 75, 76, 76, 81, 101, 83,
-  85, 92, 88, 85, 84, 86, 76, 80, 86, 80,
-  72, 95, 79, 92, 98, 99, 97, 74, 78, 91,
-  75, 82, 109, 89, 103, 94, 84, 84, 78, 81,
-  89, 68, 94, 75, 87, 83, 77, 86, 92, 80,
-  69, 76, 82, 79, 110, 89, 73, 89, 80, 78,
-  82, 87, 81, 95, 81, 88, 89, 68, 70, 78,
-  86, 82, 94, 73, 91, 68, 75, 85, 79, 87,
-  64, 80, 82, 77, 91, 90, 88, 85, 79, 81,
-  93, 82, 93, 63, 86, 84, 84, 78, 71, 90,
-  97, 107, 87, 97, 83, 83, 84, 81, 85, 82,
-  79, 78, 94, 81, 75, 88, 80, 75, 97, 83,
-  90, 92, 70, 75, 72, 80, 80, 93, 93, 86,
-  95, 78, 75, 93, 82, 77, 92, 84, 98, 90,
-  76, 90, 93, 87, 95, 76, 88, 80, 88, 98,
-  84, 84, 77, 98, 82, 81, 83, 88, 74, 81,
-  88, 83, 86, 93, 78, 93, 77, 93, 96, 73,
-  67, 90, 86, 89, 83, 86, 82, 88, 78, 100,
-  88, 77, 78, 104, 91, 88, 82, 73, 99, 84,
-  84, 98, 83, 83, 89, 84, 73, 72, 82, 71,
-  89, 65, 91, 56, 74, 84, 86, 90, 65, 81,
-  83, 74, 85, 93, 74, 92, 83, 74, 83, 82,
-  90, 52, 89, 100, 78, 78, 75, 80, 84, 93,
-  87, 96, 88, 84, 92, 80, 78, 79, 75, 69,
-  87, 77, 79, 91, 80, 87, 96, 82, 87, 82,
-  68, 82, 69, 81, 82, 97, 99, 82, 92, 88,
-  75, 90, 79, 85, 82, 88, 95, 88, 73, 80,
-  94, 85, 90, 73, 89, 79, 76, 100, 92, 88,
-  84, 102, 78, 67, 68, 79, 74, 72, 82, 82,
-  89, 95, 79, 87, 77, 93, 86, 70, 57, 86,
-  78, 79, 74, 81, 80, 89, 69, 89, 97, 72,
-  105, 102, 89, 83, 82, 75, 92, 81, 82, 91,
-  73, 86, 88, 88, 70, 87, 91, 87, 89, 86,
-  88, 75, 79, 88, 81, 95, 61, 83, 75, 76,
-  88, 90, 88, 78, 83, 86, 86, 80, 97, 80,
-  76, 91, 86, 80, 69, 88, 77, 82, 87, 94,
-  89, 84, 84, 80, 89, 83, 88, 79, 88, 92,
-  82, 85, 89, 77, 88, 85, 90, 78, 81, 77,
-  75, 77, 80, 86, 91, 81, 88, 81, 70, 90,
-  76, 70, 85, 86, 92, 87, 82, 89, 88, 81,
-  80, 77, 83, 84, 91, 93, 76, 85, 93, 90,
-  86, 77, 95, 90, 78, 79, 96, 81, 91, 90,
-  89, 73, 76, 81, 102, 77, 72, 86, 87, 90,
-  84, 88, 85, 85, 86, 85, 84, 82, 104, 101,
-  85, 90, 87, 83, 83, 95, 80, 95, 83, 85,
-  75, 82, 95, 72, 71, 84, 79, 77, 70, 81,
-  76, 93, 77, 83, 82, 68, 73, 79, 78, 85,
-  90, 72, 86, 81, 73, 99, 71, 79, 105, 92,
-  93, 95, 77, 85, 66, 84, 94, 72, 78, 75,
-  55, 72, 84, 82, 93, 57, 82, 89, 96, 69,
-  78, 71, 84, 85, 67, 86, 79, 83, 87, 71,
-  125, 92, 88, 86, 92, 80, 77, 88, 76, 78,
-  75, 93, 84, 81, 75, 81, 88, 86, 96, 95,
-  80, 97, 81, 104, 87, 95, 92, 100, 81, 92,
-  77, 79, 92, 86, 79, 100, 87, 83, 87, 82,
-  62, 90, 92, 92, 80, 91, 77, 80, 92, 74,
-  89, 74, 76, 78, 88, 93, 92, 97, 87, 92,
-  86, 77, 70, 88, 77, 84, 82, 59, 71, 74,
-  81, 66, 70, 76, 82, 74, 61, 71, 75, 99,
-  80, 84, 84, 70, 68, 80, 71, 89, 82, 62,
-  87, 76, 74, 109, 62, 69, 106, 85, 103, 83,
-  70, 92, 79, 84, 104, 59, 79, 75, 58, 69,
-  95, 88, 100, 57, 79, 77, 94, 66, 83, 66,
-  79, 88, 53, 87, 78, 81, 95, 71, 122, 87,
-  95, 84, 83, 83, 76, 92, 81, 63, 81, 99,
-  81, 82, 78, 81, 81, 93, 108, 90, 81, 107,
-  71, 87, 101, 95, 92, 101, 80, 92, 77, 86,
-  93, 83, 75, 111, 77, 82, 80, 74, 54, 85,
-  84, 94, 76, 95, 74, 82, 87, 68, 100, 72,
-  73, 85, 93, 101, 72, 88, 81, 96, 86, 72,
-  65, 79, 74, 85, 89, 52, 79, 64, 75, 80,
-  78, 82, 80, 81, 76, 82, 77, 90, 83, 84,
-  85, 72, 76, 77, 79, 81, 82, 68, 89, 83,
-  78, 95, 77, 81, 98, 79, 85, 83, 80, 71,
-  84, 95, 87, 73, 78, 76, 64, 76, 84, 89,
-  100, 69, 89, 89, 88, 75, 83, 79, 86, 80,
-  69, 80, 82, 79, 94, 72, 111, 85, 85, 84,
-  91, 80, 78, 85, 79, 73, 91, 97, 87, 79,
-  77, 84, 95, 97, 98, 92, 81, 91, 80, 79,
-  79, 87, 85, 92, 88, 92, 79, 95, 96, 87,
-  89, 96, 89, 83, 78, 89, 64, 87, 92, 91,
-  79, 90, 79, 84, 91, 79, 85, 78, 79, 92,
-  90, 89, 78, 96, 91, 86, 91, 74, 78, 92,
-  77, 83, 83, 69, 78, 82, 84, 73, 88, 83,
-  100, 73, 79, 82, 84, 88, 79, 107, 93, 70,
-  67, 81, 90, 79, 99, 81, 77, 88, 74, 82,
-  80, 84, 91, 84, 90, 83, 88, 89, 68, 78,
-  75, 70, 60, 70, 81, 79, 79, 90, 92, 64,
-  88, 82, 78, 68, 83, 82, 77, 86, 66, 73,
-  76, 71, 85, 82, 111, 94, 78, 84, 78, 82,
-  77, 87, 76, 60, 72, 87, 79, 73, 86, 87,
-  84, 90, 78, 92, 70, 87, 85, 83, 79, 92,
-  86, 93, 84, 86, 84, 75, 76, 82, 73, 96,
-  78, 87, 87, 87, 59, 89, 90, 83, 87, 80,
-  88, 81, 105, 71, 87, 84, 79, 86, 85, 91,
-  94, 86, 98, 84, 89, 80, 76, 84, 80, 91,
-  80, 79, 80, 85, 73, 80, 81, 78, 99, 72,
-  92, 88, 83, 91, 87, 77, 94, 77, 65, 89,
-  92, 77, 84, 72, 83, 98, 79, 70, 90, 90,
-  84, 77, 84, 88, 86, 88, 69, 72, 82, 72,
-  80, 64, 81, 85, 93, 89, 96, 72, 96, 83,
-  71, 69, 86, 75, 82, 85, 64, 88, 78, 71,
-  85, 80, 118, 87, 76, 87, 69, 86, 77, 83,
-  75, 58, 73, 90, 81, 78, 84, 89, 87, 89,
-  74, 86, 71, 86, 87, 80, 64, 92, 81, 89,
-  85, 94, 87, 76, 74, 79, 69, 88, 74, 92,
-  84, 90, 57, 83, 97, 86, 106, 79, 89, 79,
-  106, 76, 81, 75, 89, 84, 76, 88, 93, 82,
-  96, 86, 94, 72, 72, 89, 72, 85, 88, 82,
-  80, 81, 73, 77, 84, 78, 93, 76, 81, 82,
-  81, 83, 80, 63, 91, 73, 71, 76, 85, 80,
-  76, 79, 83, 91, 86, 85, 79, 87, 85, 86,
-  78, 89, 86, 84, 76, 93, 78, 69, 103, 72,
-  86, 77, 94, 94, 94, 66, 91, 93, 79, 74,
-  85, 78, 80, 85, 73, 98, 78, 74, 87, 80,
-  96, 88, 73, 80, 81, 78, 81, 89, 76, 64,
-  91, 86, 82, 74, 81, 89, 83, 83, 87, 88,
-  74, 88, 82, 78, 79, 92, 86, 89, 85, 86,
-  86, 78, 79, 85, 77, 93, 77, 86, 76, 85,
-  62, 88, 86, 81, 87, 84, 85, 83, 99, 79,
-  84, 84, 83, 87, 69, 84, 92, 85, 94, 85,
-  81, 77, 83, 87, 82, 86, 79, 82, 94, 87,
-  90, 91, 98, 94, 91, 75, 90, 84, 84, 74,
-  88, 86, 85, 79, 70, 84, 97, 84, 86, 102,
-  81, 97, 86, 74, 107, 90, 87, 87, 70, 89,
-  102, 83, 89, 94, 78, 81, 67, 82, 95, 87,
-  70, 91, 91, 89, 98, 77, 57, 90, 72, 95,
-  80, 83, 93, 81, 77, 73, 93, 80, 88, 94,
-  72, 82, 83, 80, 77, 83, 74, 80, 95, 74,
-  85, 67, 91, 81, 73, 86, 74, 82, 79, 71,
-  97, 82, 75, 85, 81, 77, 89, 85, 82, 80,
-  72, 76, 90, 79, 84, 78, 97, 92, 74, 90,
-  86, 75, 97, 84, 96, 83, 113, 95, 80, 92,
-  88, 86, 74, 80, 98, 74, 93, 82, 95, 87,
-  92, 85, 91, 92, 81, 93, 99, 94, 92, 104,
-  84, 87, 86, 77, 103, 96, 83, 72, 100, 78,
-  94, 84, 73, 86, 99, 82, 73, 110, 85, 104,
-  93, 62, 119, 104, 76, 89, 62, 95, 109, 76,
-  96, 82, 87, 94, 77, 82, 94, 95, 80, 86,
-  85, 94, 103, 85, 49, 100, 76, 96, 86, 80,
-  93, 80, 74, 68, 96, 78, 83, 88, 71, 87,
-  79, 87, 74, 78, 70, 81, 84, 71, 94, 72,
-  86, 77, 77, 75, 69, 79, 82, 72, 101, 91,
-  58, 86, 76, 67, 83, 90, 76, 81, 70, 74,
-  86, 71, 89, 82, 97, 92, 73, 73, 87, 75,
-  108, 88, 99, 76, 109, 103, 79, 91, 93, 77,
-  77, 80, 104, 72, 92, 82, 88, 85, 92, 85,
-  89, 83, 79, 98, 91, 102, 85, 90, 84, 87,
-  91, 82, 91, 89, 83, 78, 88, 76, 83, 81,
-  75, 81, 95, 82, 73, 99, 88, 95, 96, 79,
-  100, 87, 78, 88, 69, 94, 101, 90, 88, 86,
-  80, 81, 91, 79, 100, 85, 84, 91, 83, 84,
-  95, 87, 70, 91, 74, 97, 84, 84, 93, 82,
-  79, 79, 89, 82, 86, 87, 75, 79, 85, 83,
-  82, 84, 77, 82, 88, 80, 84, 68, 84, 87,
-  74, 75, 74, 83, 84, 73, 92, 89, 79, 93,
-  91, 74, 88, 89, 81, 85, 74, 80, 91, 80,
-  81, 78, 87, 88, 74, 83, 85, 76, 94, 85,
-  89, 82, 103, 90, 80, 86, 89, 81, 76, 86,
-  105, 76, 92, 83, 79, 86, 91, 87, 92, 92,
-  80, 85, 93, 84, 73, 92, 86, 71, 83, 81,
-  80, 90, 79, 71, 75, 95, 80, 105, 92, 73,
-  79, 92, 67, 73, 77, 91, 81, 82, 74, 79,
-  87, 86, 100, 74, 84, 88, 104, 72, 82, 83,
-  81, 80, 81, 80, 86, 96, 72, 108, 115, 82,
-  89, 82, 75, 69, 87, 96, 80, 99, 91, 94,
-  98, 82, 93, 114, 97, 90, 74, 69, 101, 76,
-  136, 74, 80, 57, 68, 84, 75, 82, 80, 69,
-  86, 79, 97, 88, 86, 73, 94, 95, 81, 78,
-  94, 74, 67, 86, 82, 84, 70, 66, 79, 86,
-  98, 75, 73, 83, 89, 81, 99, 91, 84, 83,
-  97, 76, 70, 81, 85, 74, 86, 88, 83, 77,
-  79, 85, 88, 80, 91, 85, 92, 97, 79, 85,
-  88, 88, 51, 82, 75, 70, 86, 82, 85, 88,
-  87, 76, 95, 102, 86, 74, 83, 81, 82, 76,
-  93, 81, 81, 95, 72, 87, 70, 82, 87, 79,
-  89, 79, 77, 92, 103, 73, 84, 87, 72, 79,
-  73, 91, 89, 89, 75, 89, 71, 98, 91, 87,
-  83, 78, 85, 91, 70, 100, 96, 75, 83, 86,
-  88, 93, 89, 90, 65, 73, 83, 85, 107, 72,
-  70, 77, 74, 82, 75, 79, 87, 70, 77, 82,
-  85, 86, 89, 65, 92, 77, 77, 77, 77, 86,
-  63, 83, 78, 96, 64, 73, 86, 81, 104, 81,
-  71, 92, 86, 82, 91, 83, 88, 89, 95, 79,
-  68, 80, 87, 78, 73, 71, 64, 86, 90, 90,
-  74, 79, 77, 91, 81, 88, 88, 90, 83, 88,
-  66, 80, 71, 99, 84, 80, 84, 89, 96, 78,
-  93, 87, 85, 71, 80, 103, 84, 81, 100, 75,
-  83, 93, 76, 90, 79, 89, 89, 81, 86, 87,
-  76, 83, 94, 81, 85, 81, 78, 81, 76, 89,
-  84, 79, 84, 80, 63, 88, 92, 86, 86, 87,
-  87, 90, 73, 88, 84, 81, 73, 79, 86, 79,
-  90, 79, 87, 91, 81, 85, 83, 82, 84, 85,
-  90, 82, 80, 76, 85, 86, 83, 101, 83, 82,
-  81, 81, 81, 74, 76, 87, 81, 94, 72, 85,
-  77, 93, 85, 84, 88, 92, 84, 91, 84, 99,
-  85, 83, 77, 85, 78, 85, 86, 89, 79, 80,
-  93, 88, 77, 79, 66, 82, 85, 100, 83, 83,
-  77, 88, 82, 85, 98, 89, 89, 80, 78, 75,
-  75, 57, 82, 80, 81, 101, 70, 87, 65, 96,
-  73, 91, 78, 70, 66, 95, 79, 102, 105, 83,
-  89, 64, 79, 76, 89, 65, 64, 72, 92, 75,
-  89, 77, 82, 84, 86, 77, 100, 76, 95, 80,
-  100, 111, 97, 93, 92, 87, 81, 60, 85, 73,
-  111, 86, 120, 64, 158, 69, 74, 147, 106, 76,
-  86, 78, 85, 101, 104, 78, 73, 56, 101, 67,
-  65, 118, 80, 60, 81, 77, 78, 72, 104, 85,
-  75, 76, 81, 78, 74, 82, 73, 93, 94, 76,
-  78, 55, 70, 86, 95, 116, 73, 78, 92, 84,
-  98, 99, 93, 76, 82, 85, 59, 73, 85, 80,
-  78, 101, 77, 86, 76, 92, 70, 65, 87, 87,
-  86, 73, 75, 83, 101, 85, 67, 87, 74, 58,
-  79, 83, 89, 88, 83, 80, 100, 100, 76, 77,
-  78, 82, 79, 77, 112, 96, 104, 82, 75, 83,
-  71, 80, 91, 77, 71, 87, 78, 97, 85, 81,
-  88, 83, 88, 87, 81, 96, 72, 92, 85, 83,
-  68, 127, 87, 91, 83, 97, 87, 87, 86, 84,
-  91, 64, 103, 77, 68, 86, 92, 66, 73, 72,
-  72, 89, 83, 85, 89, 81, 76, 76, 57, 87,
-  84, 57, 63, 84, 80, 77, 94, 79, 96, 73,
-  87, 87, 67, 86, 62, 75, 84, 82, 77, 74,
-  89, 83, 83, 94, 73, 82, 81, 82, 79, 77,
-  93, 86, 91, 80, 76, 78, 79, 91, 84, 83,
-  77, 90, 79, 84, 79, 75, 89, 88, 86, 71,
-  74, 82, 93, 93, 78, 91, 71, 90, 87, 81,
-  82, 85, 90, 82, 105, 78, 92, 73, 84, 106,
-  89, 88, 101, 80, 87, 89, 78, 96, 75, 85,
-  96, 82, 99, 96, 81, 91, 93, 87, 85, 88,
-  84, 83, 71, 93, 83, 87, 84, 74, 75, 93,
-  88, 89, 90, 95, 91, 98, 73, 81, 73, 80,
-  60, 83, 85, 72, 79, 71, 79, 89, 90, 79,
-  78, 73, 82, 83, 79, 83, 81, 63, 82, 94,
-  74, 95, 87, 85, 80, 80, 90, 88, 81, 91,
-  80, 92, 69, 68, 67, 82, 79, 90, 93, 94,
-  70, 81, 81, 91, 86, 84, 79, 69, 88, 92,
-  90, 91, 93, 80, 91, 89, 76, 79, 74, 88,
-  87, 87, 87, 90, 77, 89, 84, 80, 97, 89,
-  100, 92, 79, 77, 76, 60, 72, 88, 86, 92,
-  82, 89, 79, 90, 64, 87, 75, 90, 84, 90,
-  74, 97, 112, 76, 84, 79, 76, 77, 83, 75,
-  84, 86, 77, 73, 87, 94, 82, 85, 90, 78,
-  83, 79, 94, 99, 83, 69, 93, 96, 86, 82,
-  82, 80, 85, 79, 92, 81, 95, 83, 113, 90,
-  75, 104, 112, 85, 76, 68, 76, 99, 78, 99,
-  60, 64, 97, 79, 73, 96, 92, 55, 80, 71,
-  84, 74, 93, 92, 84, 84, 83, 88, 89, 88,
-  81, 90, 98, 80, 90, 79, 81, 78, 81, 84,
-  88, 78, 98, 85, 80, 79, 100, 80, 114, 93,
-  77, 87, 81, 86, 94, 81, 90, 84, 82, 96,
-  74, 82, 100, 83, 87, 72, 82, 79, 98, 81,
-  86, 90, 74, 71, 79, 80, 92, 84, 82, 71,
-  101, 79, 81, 79, 76, 89, 79, 73, 81, 90,
-  102, 84, 88, 89, 74, 82, 83, 84, 92, 98,
-  64, 92, 85, 91, 94, 88, 87, 85, 78, 92,
-  79, 97, 72, 71, 94, 103, 82, 87, 86, 94,
-  90, 87, 80, 60, 74, 83, 84, 96, 77, 81,
-  90, 72, 79, 64, 82, 77, 81, 82, 90, 83,
-  83, 84, 69, 74, 83, 69, 69, 81, 86, 78,
-  83, 79, 91, 87, 87, 89, 81, 85, 55, 78,
-  80, 88, 74, 88, 87, 78, 61, 79, 77, 68,
-  86, 80, 81, 69, 88, 84, 100, 91, 97, 85,
-  81, 89, 95, 81, 78, 87, 81, 80, 90, 81,
-  98, 87, 91, 70, 81, 78, 90, 82, 84, 92,
-  67, 79, 87, 74, 79, 85, 87, 74, 91, 68,
-  97, 69, 83, 103, 88, 86, 84, 89, 95, 96,
-  82, 84, 77, 84, 82, 84, 97, 99, 81, 95,
-  89, 85, 94, 88, 88, 78, 83, 89, 82, 86,
-  74, 73, 91, 92, 84, 86, 90, 89, 88, 90,
-  75, 71, 75, 90, 75, 84, 92, 86, 79, 80,
-  90, 88, 92, 75, 81, 78, 76, 80, 89, 78,
-  81, 68, 81, 87, 77, 95, 90, 80, 74, 79,
-  79, 95, 79, 88, 81, 85, 67, 76, 76, 82,
-  71, 93, 84, 92, 65, 83, 78, 87, 82, 82,
-  89, 80, 83, 89, 69, 96, 93, 87, 90, 82,
-  82, 88, 88, 91, 88, 85, 88, 87, 73, 92,
-  78, 79, 95, 87, 83, 72, 104, 86, 75, 86,
-  73, 81, 80, 78, 89, 84, 70, 74, 76, 82,
-  85, 77, 82, 76, 85, 81, 100, 90, 61, 72,
-  87, 75, 76, 82, 90, 80, 85, 74, 79, 106,
-  97, 75, 83, 77, 88, 74, 76, 70, 97, 75,
-  89, 60, 89, 78, 87, 80, 81, 79, 90, 89,
-  79, 69, 74, 122, 77, 77, 82, 83, 88, 86,
-  94, 102, 79, 90, 83, 105, 83, 88, 78, 83,
-  77, 97, 80, 77, 82, 82, 81, 75, 67, 98,
-  78, 90, 89, 105, 82, 94, 86, 132, 82, 90,
-  86, 92, 96, 92, 74, 78, 80, 71, 93, 94,
-  95, 68, 87, 75, 90, 90, 75, 83, 78, 101,
-  84, 96, 80, 85, 92, 66, 71, 94, 78, 79,
-  69, 87, 84, 71, 75, 77, 72, 83, 72, 77,
-  69, 66, 84, 73, 68, 76, 69, 79, 86, 71,
-  73, 45, 78, 83, 83, 94, 69, 74, 85, 63,
-  103, 74, 95, 87, 83, 75, 80, 74, 76, 68,
-  80, 70, 77, 70, 91, 65, 95, 81, 90, 77,
-  85, 71, 69, 92, 78, 82, 85, 82, 71, 68,
-  74, 116, 83, 82, 69, 106, 77, 85, 90, 102,
-  73, 87, 93, 96, 72, 94, 70, 75, 72, 61,
-  82, 78, 81, 71, 84, 83, 72, 85, 75, 89,
-  77, 106, 65, 96, 94, 139, 85, 95, 97, 92,
-  81, 89, 66, 106, 71, 71, 104, 94, 95, 55,
-  91, 76, 91, 106, 66, 75, 90, 113, 74, 104,
-  85, 80, 97, 59, 64, 86, 75, 83, 62, 77,
-  79, 85, 82, 90, 80, 100, 76, 87, 87, 90,
-  85, 95, 70, 87, 77, 83, 85, 79, 81, 65,
-  81, 78, 88, 86, 84, 74, 85, 83, 77, 93,
-  80, 90, 88, 97, 90, 89, 91, 83, 78, 86,
-  84, 81, 93, 84, 98, 79, 91, 107, 86, 85,
-  87, 94, 89, 78, 80, 76, 84, 73, 79, 103,
-  81, 83, 87, 65, 87, 88, 72, 94, 81, 69,
-  83, 92, 83, 74, 73, 84, 84, 71, 80, 76,
-  91, 82, 79, 95, 78, 90, 92, 85, 96, 100,
-  89, 101, 86, 108, 102, 81, 72, 86, 81, 90,
-  78, 75, 82, 78, 87, 93, 88, 79, 72, 80,
-  94, 79, 77, 89, 82, 92, 94, 87, 88, 74,
-  85, 72, 81, 89, 86, 76, 73, 95, 80, 62,
-  94, 74, 75, 83, 71, 83, 80, 60, 83, 87,
-  75, 82, 74, 93, 94, 83, 85, 73, 84, 58,
-  106, 96, 61, 75, 85, 67, 106, 78, 84, 80,
-  83, 79, 71, 119, 84, 80, 78, 79, 80, 73,
-  79, 64, 78, 91, 89, 77, 82, 61, 83, 75,
-  73, 84, 86, 86, 79, 53, 68, 147, 89, 95,
-  84, 73, 90, 64, 78, 100, 99, 100, 104, 96,
-  98, 82, 73, 77, 64, 79, 76, 89, 80, 76,
-  82, 102, 73, 88, 72, 91, 83, 101, 72, 77,
-  73, 131, 88, 84, 89, 88, 92, 80, 53, 90,
-  77, 83, 94, 83, 91, 51, 90, 77, 93, 89,
-  59, 90, 80, 78, 65, 109, 87, 72, 86, 51,
-  70, 83, 86, 78, 76, 77, 65, 69, 81, 62,
-  64, 78, 67, 77, 66, 42, 80, 83, 67, 80,
-  70, 91, 104, 71, 73, 44, 78, 53, 79, 90,
-  62, 83, 78, 55, 124, 79, 83, 78, 75, 73,
-  68, 84, 65, 93, 81, 63, 70, 67, 82, 60,
-  72, 76, 81, 70, 80, 50, 83, 74, 66, 88,
-  68, 85, 69, 54, 59, 176, 101, 86, 68, 86,
-  77, 59, 74, 109, 97, 77, 81, 109, 89, 82,
-  75, 73, 43, 74, 73, 94, 80, 88, 78, 106,
-  86, 92, 70, 88, 77, 94, 64, 78, 61, 137,
-  76, 86, 97, 88, 77, 75, 45, 87, 60, 85,
-  105, 74, 92, 41, 87, 72, 102, 87, 45, 72,
-  80, 80, 82, 125, 91, 67, 102, 39, 62, 75,
-  90, 81, 86, 65, 79, 89, 90, 88, 86, 100,
-  75, 83, 85, 78, 78, 97, 70, 85, 81, 91,
-  93, 83, 82, 69, 79, 77, 73, 91, 79, 70,
-  82, 77, 98, 97, 76, 86, 88, 92, 81, 80,
-  82, 80, 79, 89, 86, 88, 86, 81, 85, 96,
-  90, 83, 97, 81, 83, 88, 83, 76, 88, 88,
-  85, 60, 73, 102, 92, 92, 95, 65, 80, 73,
-  68, 96, 82, 91, 75, 84, 93, 80, 76, 83,
-  85, 83, 70, 75, 87, 66, 79, 95, 80, 85,
-  99, 104, 86, 93, 80, 102, 82, 105, 115, 80,
-  81, 85, 85, 80, 65, 75, 79, 82, 84, 90,
-  83, 73, 82, 87, 100, 88, 73, 83, 74, 89,
-  114, 93, 84, 79, 95, 65, 84, 85, 82, 86,
-  75, 90, 90, 76, 84, 91, 78, 76, 70, 82,
-  80, 74, 76, 81, 83, 92, 77, 91, 95, 91,
-  91, 85, 86, 75, 85, 112, 76, 72, 103, 81,
-  81, 73, 94, 86, 78, 81, 93, 104, 88, 81,
-  86, 83, 89, 76, 78, 74, 69, 91, 93, 82,
-  89, 77, 78, 76, 78, 79, 84, 85, 74, 73,
-  83, 115, 81, 100, 94, 85, 93, 69, 74, 81,
-  89, 113, 92, 80, 107, 87, 78, 76, 84, 93,
-  86, 75, 81, 79, 98, 91, 76, 86, 75, 104,
-  83, 86, 75, 76, 83, 121, 84, 67, 85, 84,
-  92, 79, 58, 87, 95, 78, 76, 80, 92, 70,
-  79, 92, 83, 92, 75, 86, 84, 97, 70, 80,
-  90, 93, 84, 67, 70, 90, 83, 74, 77, 93,
-  82, 76, 85, 84, 69, 76, 70, 79, 72, 62,
-  80, 75, 70, 93, 87, 95, 101, 82, 87, 62,
-  79, 71, 75, 103, 73, 74, 101, 70, 101, 95,
-  87, 71, 75, 71, 80, 87, 78, 96, 94, 71,
-  83, 73, 82, 73, 65, 77, 80, 80, 89, 71,
-  83, 80, 72, 81, 77, 84, 68, 75, 75, 138,
-  89, 91, 78, 93, 94, 70, 67, 82, 91, 89,
-  87, 91, 100, 83, 75, 72, 72, 80, 83, 78,
-  81, 88, 100, 97, 88, 96, 75, 108, 69, 80,
-  62, 71, 75, 119, 78, 64, 95, 91, 81, 77,
-  58, 90, 88, 77, 69, 78, 97, 52, 68, 87,
-  87, 87, 63, 77, 80, 79, 90, 90, 82, 90,
-  91, 57, 61, 89, 80, 78, 83, 85, 83, 88,
-  81, 92, 87, 93, 79, 85, 83, 85, 76, 89,
-  78, 83, 75, 88, 95, 87, 87, 76, 81, 73,
-  71, 105, 83, 73, 96, 92, 77, 103, 83, 80,
-  84, 95, 75, 81, 90, 79, 87, 92, 94, 89,
-  86, 89, 76, 100, 100, 88, 92, 79, 79, 83,
-  87, 80, 93, 87, 79, 75, 86, 91, 85, 97,
-  100, 63, 79, 74, 69, 86, 85, 103, 85, 77,
-  91, 83, 86, 82, 95, 77, 76, 70, 89, 74,
-  95, 85, 78, 80, 93, 103, 88, 82, 87, 87,
-  90, 99, 104, 74, 79, 79, 100, 78, 66, 102,
-  88, 77, 76, 83, 76, 90, 83, 96, 91, 90,
-  85, 77, 91, 95, 92, 81, 89, 88, 85, 75,
-  89, 86, 87, 86, 76, 93, 85, 82, 99, 89,
-  84, 80, 80, 94, 92, 70, 85, 88, 98, 76,
-  74, 83, 99, 97, 97, 89, 47, 74, 96, 95,
-  100, 69, 81, 84, 88, 90, 75, 87, 99, 75,
-  84, 87, 71, 81, 91, 86, 69, 82, 97, 84,
-  82, 83, 105, 70, 76, 93, 90, 97, 83, 84,
-  96, 89, 89, 94, 90, 81, 78, 82, 73, 77,
-  69, 98, 95, 82, 89, 93, 91, 80, 95, 67,
-  84, 80, 82, 95, 60, 91, 87, 84, 90, 99,
-  79, 87, 78, 88, 91, 76, 94, 77, 93, 84,
-  92, 71, 94, 96, 80, 99, 78, 88, 75, 97,
-  84, 103, 81, 79, 71, 84, 74, 86, 85, 85,
-  73, 85, 82, 98, 93, 77, 89, 88, 84, 83,
-  97, 79, 85, 81, 75, 83, 113, 95, 93, 81,
-  80, 79, 84, 84, 78, 79, 74, 101, 74, 80,
-  69, 70, 75, 92, 76, 70, 99, 101, 86, 82,
-  79, 81, 109, 106, 78, 89, 72, 84, 77, 102,
-  79, 87, 86, 73, 80, 66, 66, 71, 88, 89,
-  90, 73, 103, 68, 81, 70, 79, 72, 76, 69,
-  85, 85, 80, 78, 86, 98, 89, 73, 55, 74,
-  93, 79, 80, 90, 82, 99, 92, 77, 85, 72,
-  87, 94, 69, 83, 80, 92, 81, 101, 91, 100,
-  83, 95, 79, 82, 74, 79, 99, 83, 92, 77,
-  90, 84, 66, 69, 68, 66, 77, 96, 79, 87,
-  78, 78, 73, 68, 102, 78, 67, 84, 80, 82,
-  108, 90, 73, 79, 81, 81, 73, 79, 77, 94,
-  73, 74, 77, 66, 97, 85, 86, 84, 80, 75,
-  83, 84, 78, 81, 91, 100, 71, 74, 68, 77,
-  82, 89, 90, 68, 79, 98, 73, 80, 92, 85,
-  83, 95, 82, 90, 80, 75, 86, 98, 93, 84,
-  88, 78, 85, 70, 73, 76, 100, 84, 75, 76,
-  96, 77, 83, 78, 82, 72, 77, 80, 85, 87,
-  80, 85, 97, 91, 102, 67, 69, 76, 87, 79,
-  74, 83, 86, 92, 96, 88, 78, 71, 90, 103,
-  88, 83, 84, 98, 82, 92, 88, 92, 91, 83,
-  81, 89, 84, 96, 99, 81, 85, 82, 91, 89,
-  76, 70, 75, 73, 91, 89, 84, 92, 84, 81,
-  85, 80, 101, 78, 76, 88, 87, 91, 86, 89,
-  74, 95, 104, 81, 77, 84, 82, 107, 76, 85,
-  78, 79, 109, 95, 88, 74, 70, 80, 82, 83,
-  77, 73, 87, 97, 72, 81, 91, 75, 78, 89,
-  81, 66, 100, 91, 95, 81, 75, 83, 118, 101,
-  78, 95, 72, 84, 71, 94, 88, 85, 95, 95,
-  84, 73, 61, 74, 75, 79, 88, 83, 105, 73,
-  75, 68, 76, 72, 73, 81, 80, 88, 78, 78,
-  89, 90, 84, 66, 53, 77, 96, 86, 91, 83,
-  68, 85, 96, 74, 85, 74, 86, 85, 74, 85,
-  79, 87, 77, 99, 91, 98, 85, 100, 75, 66,
-  76, 74, 97, 84, 93, 71, 89, 91, 78, 76,
-  70, 79, 81, 93, 85, 96, 76, 82, 66, 66,
-  79, 80, 68, 91, 75, 88, 93, 96, 78, 72,
-  94, 79, 71, 81, 82, 92, 76, 69, 70, 64,
-  105, 85, 90, 75, 78, 66, 82, 90, 78, 76,
-  75, 107, 80, 76, 77, 67, 73, 85, 116, 70,
-  88, 93, 78, 82, 79, 83, 108, 97, 85, 89,
-  67, 78, 66, 85, 85, 80, 86, 76, 97, 68,
-  48, 70, 79, 82, 78, 80, 92, 78, 74, 74,
-  75, 66, 62, 76, 71, 81, 77, 84, 98, 79,
-  88, 66, 45, 67, 92, 74, 75, 70, 65, 89,
-  87, 87, 84, 76, 96, 88, 79, 82, 80, 91,
-  82, 85, 85, 96, 89, 99, 76, 80, 64, 70,
-  90, 79, 82, 78, 89, 88, 75, 67, 66, 65,
-  90, 85, 87, 84, 83, 87, 74, 64, 94, 76,
-  65, 80, 81, 72, 93, 83, 69, 86, 94, 75,
-  74, 77, 75, 95, 78, 75, 79, 68, 85, 77,
-  85, 83, 85, 72, 92, 77, 87, 78, 94, 88,
-  92, 73, 85, 91, 93, 83, 106, 82, 79, 92,
-  71, 69, 88, 86, 92, 86, 96, 95, 94, 67,
-  84, 79, 93, 81, 91, 82, 92, 77, 79, 84,
-  96, 81, 79, 80, 78, 91, 81, 96, 86, 82,
-  85, 95, 89, 87, 86, 93, 92, 82, 96, 71,
-  71, 90, 76, 84, 69, 77, 84, 79, 89, 91,
-  82, 78, 92, 90, 87, 82, 89, 85, 81, 77,
-  85, 79, 85, 85, 85, 90, 84, 74, 85, 79,
-  77, 78, 91, 99, 85, 80, 77, 89, 95, 78,
-  82, 91, 90, 89, 85, 89, 88, 84, 88, 87,
-  72, 86, 76, 85, 82, 94, 107, 88, 89, 84,
-  88, 92, 88, 97, 80, 80, 96, 87, 85, 95,
-  78, 74, 73, 86, 80, 79, 90, 98, 66, 78,
-  86, 73, 85, 87, 119, 70, 88, 91, 83, 83,
-  79, 83, 93, 88, 88, 101, 76, 87, 68, 104,
-  86, 80, 96, 100, 93, 65, 55, 73, 72, 79,
-  85, 89, 103, 75, 80, 76, 74, 69, 73, 86,
-  75, 88, 77, 81, 98, 92, 93, 65, 72, 72,
-  90, 83, 97, 73, 82, 86, 93, 83, 84, 73,
-  80, 101, 73, 87, 80, 86, 78, 88, 93, 101,
-  91, 96, 87, 70, 76, 77, 95, 80, 87, 73,
-  88, 87, 82, 73, 65, 89, 85, 93, 85, 86,
-  81, 86, 82, 67, 79, 79, 65, 91, 73, 83,
-  90, 84, 73, 73, 109, 76, 76, 78, 82, 94,
-  79, 77, 82, 69, 80, 86, 80, 88, 89, 70,
-  87, 81, 82, 89, 84, 94, 83, 82, 82, 88,
-  92, 73, 129, 77, 77, 90, 74, 75, 84, 82,
-  99, 89, 92, 93, 91, 76, 79, 80, 87, 85,
-  92, 76, 90, 75, 51, 79, 79, 84, 81, 84,
-  79, 87, 85, 98, 80, 80, 78, 89, 83, 86,
-  82, 89, 90, 74, 89, 73, 67, 80, 84, 76,
-  82, 74, 85, 83, 89, 96, 83, 76, 92, 88,
-  78, 86, 89, 91, 90, 82, 81, 89, 84, 88,
-  92, 81, 76, 75, 93, 84, 80, 81, 91, 92,
-  95, 82, 69, 87, 88, 85, 78, 94, 76, 89,
-  79, 84, 91, 86, 76, 84, 77, 79, 85, 86,
-  77, 87, 102, 84, 84, 84, 82, 87, 89, 88,
-  86, 76, 81, 78, 76, 86, 91, 79, 81, 75,
-  85, 85, 93, 90, 92, 73, 81, 103, 87, 84,
-  113, 89, 79, 90, 72, 72, 94, 84, 81, 99,
-  95, 93, 105, 77, 92, 81, 90, 91, 91, 76,
-  85, 86, 78, 92, 93, 80, 86, 91, 76, 89,
-  80, 107, 96, 88, 96, 90, 101, 90, 86, 88,
-  78, 86, 89, 79, 72, 97, 71, 93, 76, 83,
-  95, 79, 88, 91, 88, 83, 75, 87, 79, 73,
-  100, 86, 80, 75, 87, 82, 74, 75, 86, 79,
-  89, 69, 82, 77, 78, 88, 84, 85, 87, 90,
-  78, 102, 87, 81, 79, 101, 82, 88, 76, 96,
-  94, 90, 89, 92, 82, 89, 85, 88, 85, 96,
-  100, 90, 81, 82, 103, 77, 91, 92, 101, 95,
-  81, 80, 83, 87, 66, 93, 96, 109, 75, 78,
-  95, 87, 80, 85, 106, 83, 66, 65, 91, 103,
-  80, 66, 83, 80, 97, 81, 81, 81, 93, 80,
-  72, 91, 100, 89, 91, 76, 93, 90, 73, 71,
-  81, 86, 77, 70, 86, 80, 66, 79, 90, 75,
-  91, 75, 70, 85, 75, 92, 89, 105, 104, 80,
-  73, 90, 90, 94, 80, 91, 73, 97, 81, 90,
-  96, 86, 83, 57, 88, 88, 79, 90, 84, 85,
-  104, 93, 88, 93, 77, 104, 90, 96, 105, 86,
-  89, 86, 83, 90, 93, 88, 89, 73, 88, 79,
-  97, 87, 80, 73, 95, 95, 79, 74, 86, 81,
-  57, 69, 79, 108, 80, 90, 98, 83, 96, 101,
-  78, 93, 90, 82, 72, 72, 90, 95, 80, 82,
-  82, 76, 70, 86, 90, 107, 74, 83, 91, 90,
-  77, 76, 91, 78, 66, 71, 78, 89, 76, 62,
-  102, 86, 90, 80, 91, 91, 87, 70, 73, 73,
-  91, 94, 93, 76, 80, 91, 78, 66, 85, 88,
-  74, 78, 84, 89, 61, 81, 85, 80, 90, 72,
-  71, 86, 65, 80, 89, 101, 109, 65, 69, 84,
-  75, 97, 71, 96, 73, 91, 92, 96, 97, 78,
-  92, 57, 87, 78, 88, 86, 82, 83, 105, 84,
-  91, 92, 74, 103, 77, 89, 98, 85, 97, 81,
-  86, 94, 90, 80, 86, 71, 84, 101, 89, 89,
-  69, 71, 98, 94, 72, 74, 96, 81, 49, 87,
-  76, 104, 79, 101, 98, 80, 93, 94, 78, 77,
-  99, 76, 72, 64, 91, 78, 90, 92, 82, 86,
-  76, 105, 88, 92, 81, 80, 73, 84, 81, 89,
-  83, 82, 75, 86, 79, 93, 94, 76, 101, 84,
-  90, 90, 82, 96, 79, 94, 84, 79, 81, 95,
-  95, 82, 69, 78, 98, 74, 85, 83, 85, 90,
-  85, 99, 87, 79, 83, 76, 83, 84, 92, 85,
-  91, 84, 78, 84, 94, 70, 77, 67, 75, 90,
-  84, 82, 94, 68, 84, 84, 96, 84, 91, 67,
-  87, 86, 77, 95, 83, 84, 82, 73, 75, 80,
-  66, 66, 84, 87, 96, 97, 106, 86, 94, 83,
-  109, 82, 88, 76, 71, 83, 96, 84, 91, 86,
-  66, 92, 82, 79, 88, 85, 73, 83, 75, 82,
-  89, 89, 77, 79, 96, 83, 94, 101, 90, 78,
-  78, 89, 82, 82, 76, 81, 75, 94, 81, 73,
-  86, 101, 75, 84, 76, 88, 78, 83, 91, 77,
-  69, 76, 84, 86, 72, 66, 95, 81, 82, 81,
-  94, 80, 100, 85, 71, 99, 109, 83, 89, 52,
-  76, 75, 106, 54, 85, 87, 58, 78, 80, 76,
-  64, 83, 92, 79, 88, 73, 90, 94, 72, 90,
-  97, 97, 98, 69, 86, 90, 98, 90, 75, 96,
-  73, 64, 96, 91, 90, 77, 84, 67, 81, 76,
-  78, 80, 90, 87, 83, 89, 90, 83, 87, 92,
-  87, 105, 99, 98, 113, 86, 83, 95, 90, 85,
-  81, 71, 74, 72, 90, 83, 80, 72, 92, 88,
-  77, 76, 90, 82, 56, 66, 80, 107, 60, 94,
-  83, 83, 83, 80, 77, 97, 89, 74, 71, 64,
-  71, 87, 86, 81, 73, 76, 88, 69, 77, 97,
-  75, 92, 79, 90, 78, 79, 81, 75, 65, 85,
-  82, 76, 97, 64, 101, 82, 73, 81, 108, 98,
-  109, 78, 70, 84, 92, 90, 91, 44, 83, 67,
-  131, 57, 80, 89, 57, 75, 75, 97, 58, 82,
-  92, 85, 91, 69, 83, 85, 61, 71, 100, 89,
-  103, 59, 78, 86, 75, 93, 73, 106, 74, 66,
-  78, 100, 79, 76, 95, 62, 83, 69, 73, 74,
-  86, 84, 82, 80, 91, 94, 72, 98, 74, 95,
-  85, 86, 116, 86, 69, 104, 86, 84, 93, 61,
-  76, 81, 82, 82, 64, 64, 95, 88, 77, 70,
-  102, 80, 51, 91, 81, 110, 85, 99, 81, 82,
-  84, 78, 78, 77, 93, 68, 69, 63, 82, 75,
-  88, 94, 84, 82, 80, 91, 81, 92, 82, 80,
-  75, 88, 71, 84, 80, 81, 85, 93, 83, 76,
-  101, 81, 89, 80, 77, 92, 101, 88, 79, 104,
-  85, 82, 78, 93, 92, 75, 72, 70, 107, 69,
-  74, 86, 73, 100, 75, 95, 82, 81, 77, 75,
-  88, 86, 97, 80, 87, 82, 72, 74, 88, 72,
-  91, 70, 68, 88, 75, 77, 90, 61, 81, 77,
-  86, 83, 88, 78, 75, 77, 73, 87, 84, 75,
-  79, 81, 70, 78, 65, 73, 74, 89, 100, 83,
-  99, 90, 97, 82, 99, 79, 99, 74, 72, 79,
-  96, 80, 100, 78, 73, 87, 85, 76, 93, 76,
-  74, 93, 83, 87, 108, 88, 72, 83, 90, 75,
-  103, 87, 93, 74, 80, 85, 95, 81, 88, 84,
-  88, 71, 82, 72, 89, 82, 83, 91, 78, 85,
-  65, 78, 84, 78, 99, 86, 84, 89, 86, 81,
-  98, 63, 109, 91, 89, 84, 80, 112, 94, 102,
-  80, 86, 84, 72, 71, 70, 109, 61, 89, 83,
-  79, 108, 75, 77, 94, 82, 86, 89, 91, 81,
-  99, 73, 94, 88, 77, 80, 94, 69, 91, 78,
-  78, 89, 71, 83, 84, 75, 86, 87, 101, 78,
-  75, 81, 93, 65, 76, 78, 95, 85, 83, 87,
-  79, 77, 80, 67, 76, 93, 102, 83, 103, 92,
-  81, 78, 100, 87, 72, 77, 70, 73, 95, 78,
-  123, 93, 74, 79, 102, 74, 86, 83, 76, 70,
-  77, 79, 71, 95, 75, 100, 82, 77, 82, 100,
-  92, 82, 79, 90, 86, 76, 74, 86, 89, 73,
-  84, 71, 85, 85, 80, 91, 80, 81, 70, 74,
-  76, 83, 93, 91, 94, 87, 84, 87, 89, 64,
-  107, 89, 101, 86, 83, 105, 93, 88, 80, 75,
-  81, 63, 86, 59, 127, 58, 79, 84, 88, 111,
-  65, 78, 91, 83, 87, 86, 92, 83, 103, 86,
-  94, 77, 73, 74, 95, 74, 88, 84, 65, 89,
-  77, 83, 81, 81, 76, 85, 96, 80, 80, 83,
-  91, 67, 80, 70, 90, 82, 82, 74, 74, 89,
-  70, 71, 67, 90, 97, 76, 96, 94, 79, 79,
-  95, 88, 96, 76, 73, 75, 91, 76, 136, 79,
-  67, 80, 110, 71, 96, 77, 79, 78, 81, 79,
-  82, 101, 77, 94, 86, 79, 85, 88, 94, 84,
-  75, 94, 86, 76, 68, 94, 90, 96, 83, 85,
-  81, 74, 84, 83, 80, 83, 68, 82, 83, 83,
-  108, 86, 89, 81, 74, 88, 87, 84, 95, 69,
-  83, 76, 73, 107, 102, 84, 79, 83, 85, 80,
-  80, 69, 92, 73, 77, 88, 84, 98, 73, 77,
-  83, 80, 85, 82, 93, 101, 97, 77, 95, 91,
-  62, 75, 82, 75, 90, 68, 70, 91, 78, 74,
-  87, 72, 78, 79, 95, 80, 80, 85, 78, 75,
-  83, 83, 94, 84, 89, 75, 75, 82, 77, 62,
-  78, 83, 81, 78, 86, 91, 89, 77, 88, 80,
-  100, 73, 66, 80, 91, 76, 106, 92, 78, 85,
-  88, 91, 82, 70, 89, 87, 92, 79, 86, 90,
-  84, 93, 95, 80, 95, 95, 91, 78, 86, 97,
-  101, 95, 91, 80, 72, 78, 82, 95, 93, 84,
-  77, 94, 85, 97, 67, 70, 70, 56, 81, 82,
-  69, 117, 93, 76, 81, 91, 103, 80, 100, 89,
-  81, 84, 76, 81, 91, 86, 108, 86, 74, 69,
-  96, 80, 68, 75, 85, 74, 81, 86, 87, 79,
-  85, 92, 92, 81, 98, 100, 74, 90, 99, 83,
-  88, 83, 113, 73, 60, 84, 79, 77, 59, 136,
-  80, 101, 75, 95, 82, 80, 79, 87, 66, 74,
-  83, 72, 84, 80, 75, 80, 74, 114, 85, 90,
-  86, 81, 90, 90, 99, 78, 85, 81, 89, 81,
-  98, 81, 87, 88, 82, 65, 87, 79, 111, 72,
-  84, 60, 85, 77, 116, 101, 99, 85, 106, 77,
-  70, 72, 97, 93, 89, 85, 72, 84, 102, 79,
-  93, 87, 63, 86, 72, 91, 104, 90, 75, 98,
-  100, 89, 65, 68, 77, 64, 103, 70, 58, 102,
-  83, 77, 84, 83, 104, 85, 98, 85, 69, 84,
-  80, 89, 89, 75, 116, 88, 79, 76, 98, 81,
-  60, 78, 78, 70, 98, 87, 79, 81, 86, 93,
-  90, 82, 119, 111, 77, 85, 94, 83, 91, 84,
-  112, 77, 62, 94, 74, 80, 58, 151, 113, 100,
-  72, 91, 77, 85, 77, 81, 59, 78, 77, 62,
-  83, 81, 77, 76, 77, 120, 86, 88, 78, 95,
-  96, 80, 98, 76, 95, 77, 89, 90, 101, 110,
-  94, 91, 86, 60, 88, 87, 117, 73, 81, 63,
-  78, 82, 121, 104, 97, 82, 118, 70, 77, 72,
-  101, 91, 97, 85, 74, 80, 89, 69, 78, 79,
-  81, 90, 82, 103, 93, 84, 77, 95, 83, 77,
-  73, 72, 72, 63, 78, 74, 68, 95, 79, 74,
-  85, 96, 98, 88, 88, 80, 83, 86, 85, 86,
-  81, 81, 105, 97, 86, 70, 92, 79, 80, 77,
-  88, 74, 83, 83, 85, 79, 86, 78, 84, 86,
-  93, 87, 75, 89, 98, 83, 82, 83, 109, 75,
-  59, 83, 74, 82, 70, 109, 103, 93, 79, 94,
-  76, 80, 80, 85, 72, 76, 84, 81, 81, 85,
-  76, 77, 79, 96, 83, 95, 89, 79, 90, 86,
-  97, 79, 88, 79, 83, 82, 94, 97, 84, 88,
-  83, 74, 81, 78, 108, 81, 81, 73, 88, 79,
-  110, 89, 77, 83, 96, 84, 88, 76, 98, 93,
-  90, 88, 73, 82, 98, 95, 98, 80, 84, 86,
-  87, 86, 79, 89, 75, 94, 92, 85, 85, 81,
-  78, 84, 86, 85, 63, 93, 106, 85, 91, 98,
-  76, 74, 86, 96, 93, 86, 81, 81, 82, 87,
-  79, 83, 79, 78, 80, 77, 82, 78, 81, 84,
-  94, 87, 85, 75, 76, 91, 91, 80, 90, 84,
-  82, 82, 65, 88, 84, 74, 80, 73, 82, 78,
-  80, 90, 78, 111, 75, 91, 73, 83, 88, 73,
-  70, 73, 65, 72, 89, 78, 93, 86, 87, 82,
-  78, 92, 89, 96, 77, 87, 68, 93, 86, 81,
-  88, 76, 87, 84, 77, 69, 85, 82, 88, 71,
-  85, 89, 92, 78, 74, 90, 79, 76, 97, 79,
-  103, 85, 84, 79, 92, 72, 83, 92, 73, 74,
-  95, 88, 87, 97, 85, 91, 81, 82, 83, 91,
-  77, 87, 76, 92, 110, 78, 77, 87, 86, 90,
-  94, 91, 73, 70, 80, 94, 98, 87, 80, 72,
-  78, 84, 96, 91, 86, 82, 87, 72, 79, 94,
-  75, 80, 74, 73, 72, 93, 79, 97, 106, 76,
-  80, 70, 82, 66, 85, 78, 74, 93, 79, 79,
-  52, 89, 82, 81, 76, 80, 62, 72, 74, 110,
-  80, 73, 78, 78, 75, 80, 98, 69, 72, 74,
-  61, 78, 85, 85, 94, 76, 92, 80, 79, 73,
-  89, 118, 82, 86, 55, 97, 74, 77, 89, 68,
-  102, 80, 63, 76, 80, 83, 92, 61, 84, 97,
-  98, 71, 73, 91, 77, 78, 88, 70, 75, 84,
-  87, 73, 86, 70, 73, 92, 72, 79, 99, 81,
-  95, 86, 85, 82, 85, 105, 89, 95, 80, 89,
-  75, 94, 79, 80, 91, 77, 80, 82, 85, 84,
-  83, 95, 82, 81, 91, 100, 84, 79, 77, 80,
-  91, 81, 83, 80, 90, 83, 82, 87, 79, 78,
-  81, 81, 72, 78, 87, 80, 85, 74, 82, 77,
-  76, 81, 85, 84, 95, 97, 80, 80, 72, 79,
-  82, 79, 88, 76, 82, 82, 78, 87, 78, 95,
-  112, 88, 76, 87, 83, 79, 79, 86, 74, 75,
-  92, 82, 95, 88, 84, 80, 81, 89, 87, 87,
-  74, 89, 76, 89, 97, 89, 91, 75, 89, 88,
-  82, 91, 86, 87, 88, 74, 86, 88, 90, 85,
-  76, 86, 86, 82, 85, 75, 80, 89, 82, 84,
-  82, 76, 81, 89, 72, 78, 89, 88, 85, 77,
-  85, 86, 85, 88, 78, 87, 74, 94, 77, 95,
-  99, 76, 89, 73, 75, 89, 76, 77, 76, 81,
-  97, 75, 88, 93, 71, 82, 81, 87, 83, 84,
-  96, 88, 86, 89, 72, 80, 85, 85, 80, 80,
-  90, 90, 79, 89, 84, 87, 82, 79, 81, 81,
-  79, 88, 80, 83, 75, 78, 79, 79, 75, 76,
-  74, 73, 87, 86, 83, 83, 82, 73, 84, 87,
-  82, 77, 83, 68, 87, 79, 87, 80, 90, 83,
-  94, 84, 77, 72, 82, 81, 89, 102, 75, 90,
-  83, 82, 83, 83, 84, 75, 76, 91, 76, 82,
-  85, 89, 78, 75, 84, 89, 80, 87, 76, 96,
-  86, 84, 80, 80, 82, 88, 79, 90, 92, 80,
-  79, 80, 71, 87, 95, 87, 75, 87, 81, 90,
-  88, 86, 87, 83, 72, 84, 78, 88, 110, 91,
-  94, 83, 80, 96, 67, 87, 87, 77, 88, 78,
-  87, 92, 63, 73, 79, 90, 83, 81, 91, 88,
-  82, 73, 78, 86, 82, 97, 82, 83, 88, 103,
-  77, 92, 81, 79, 84, 72, 87, 84, 73, 86,
-  66, 80, 68, 80, 74, 81, 67, 81, 74, 81,
-  75, 87, 79, 89, 92, 70, 74, 76, 80, 81,
-  93, 58, 90, 82, 85, 85, 91, 99, 94, 71,
-  85, 77, 84, 73, 91, 93, 66, 88, 80, 85,
-  72, 90, 81, 65, 88, 88, 65, 75, 79, 90,
-  74, 76, 78, 91, 65, 80, 80, 94, 85, 83,
-  83, 78, 72, 90, 72, 91, 84, 78, 64, 79,
-  65, 90, 96, 81, 89, 97, 80, 88, 82, 97,
-  84, 89, 74, 95, 79, 90, 90, 89, 87, 70,
-  74, 81, 76, 84, 87, 91, 84, 75, 82, 98,
-  82, 84, 77, 89, 81, 79, 94, 75, 87, 79,
-  74, 84, 80, 81, 81, 79, 76, 84, 87, 86,
-  73, 74, 83, 81, 83, 86, 82, 88, 82, 74,
-  76, 79, 79, 74, 79, 77, 81, 72, 83, 85,
-  80, 81, 84, 79, 87, 87, 83, 85, 87, 78,
-  89, 89, 82, 82, 94, 83, 98, 89, 75, 73,
-  78, 85, 89, 91, 76, 83, 84, 79, 86, 84,
-  86, 74, 90, 89, 82, 81, 88, 92, 79, 79,
-  87, 83, 80, 90, 77, 88, 88, 82, 86, 80,
-  89, 86, 80, 91, 86, 82, 83, 85, 72, 89,
-  90, 89, 72, 81, 79, 80, 92, 89, 73, 91,
-  90, 87, 80, 90, 68, 85, 58, 95, 90, 78,
-  94, 96, 79, 73, 89, 83, 94, 96, 91, 86,
-  88, 85, 84, 85, 77, 83, 80, 114, 82, 86,
-  88, 79, 78, 82, 66, 94, 97, 81, 84, 74,
-  78, 89, 81, 90, 76, 86, 87, 92, 93, 83,
-  97, 89, 85, 88, 82, 65, 63, 82, 72, 112,
-  89, 86, 104, 82, 88, 79, 75, 95, 88, 73,
-  87, 86, 85, 87, 95, 97, 87, 86, 60, 89,
-  88, 79, 112, 76, 82, 88, 98, 83, 83, 84,
-  86, 80, 87, 99, 89, 88, 65, 86, 101, 89,
-  72, 78, 76, 86, 82, 120, 79, 94, 59, 83,
-  80, 84, 74, 80, 71, 100, 81, 76, 87, 82,
-  80, 85, 94, 67, 85, 86, 86, 63, 79, 43,
-  62, 87, 104, 78, 78, 96, 86, 84, 54, 82,
-  82, 79, 86, 117, 82, 77, 85, 67, 110, 96,
-  73, 89, 72, 76, 88, 92, 77, 100, 87, 91,
-  75, 92, 95, 87, 84, 88, 89, 93, 75, 89,
-  67, 89, 86, 84, 80, 92, 78, 64, 86, 89,
-  73, 72, 76, 98, 67, 90, 87, 76, 84, 83,
-  98, 87, 75, 77, 83, 65, 79, 80, 79, 84,
-  84, 84, 53, 86, 76, 87, 66, 87, 81, 96,
-  67, 76, 59, 94, 73, 94, 99, 80, 98, 80,
-  76, 77, 77, 86, 137, 70, 77, 85, 82, 90,
-  91, 101, 75, 86, 80, 99, 81, 101, 81, 74,
-  80, 91, 82, 59, 76, 87, 81, 86, 79, 90,
-  83, 79, 92, 77, 93, 74, 79, 52, 72, 83,
-  82, 78, 70, 93, 88, 89, 67, 91, 85, 84,
-  80, 97, 89, 82, 86, 73, 88, 96, 80, 84,
-  75, 77, 89, 78, 91, 87, 71, 81, 80, 83,
-  83, 81, 83, 82, 88, 91, 71, 88, 73, 84,
-  88, 93, 85, 80, 84, 76, 90, 87, 80, 79,
-  89, 91, 90, 82, 85, 86, 82, 83, 87, 88,
-  88, 80, 84, 78, 77, 83, 84, 84, 83, 79,
-  70, 89, 83, 93, 91, 84, 89, 97, 69, 94,
-  69, 99, 102, 95, 92, 81, 84, 85, 91, 89,
-  85, 88, 92, 84, 86, 84, 80, 89, 90, 107,
-  83, 72, 91, 90, 99, 97, 75, 83, 82, 88,
-  77, 89, 79, 88, 95, 78, 80, 74, 96, 82,
-  91, 81, 81, 99, 91, 90, 80, 94, 68, 94,
-  61, 91, 85, 79, 101, 93, 74, 81, 97, 76,
-  86, 94, 82, 84, 87, 89, 84, 81, 80, 87,
-  70, 112, 93, 48, 84, 76, 87, 72, 67, 85,
-  104, 85, 75, 73, 83, 83, 75, 92, 72, 86,
-  91, 82, 91, 85, 94, 88, 84, 85, 89, 66,
-  68, 76, 66, 104, 87, 101, 72, 79, 88, 88,
-  77, 102, 90, 62, 75, 83, 83, 77, 95, 100,
-  81, 93, 63, 91, 80, 73, 106, 76, 91, 83,
-  105, 83, 84, 92, 77, 79, 93, 97, 93, 90,
-  68, 84, 101, 86, 83, 75, 80, 76, 88, 133,
-  82, 89, 74, 76, 76, 83, 82, 85, 70, 102,
-  84, 82, 81, 79, 84, 80, 102, 70, 83, 81,
-  89, 66, 79, 43, 62, 83, 108, 88, 88, 90,
-  87, 77, 54, 79, 86, 83, 78, 114, 82, 81,
-  75, 63, 110, 96, 78, 92, 77, 79, 80, 94,
-  66, 102, 75, 91, 74, 94, 97, 80, 84, 86,
-  86, 98, 78, 84, 70, 92, 84, 87, 75, 79,
-  73, 69, 81, 83, 76, 73, 76, 93, 64, 92,
-  87, 70, 86, 67, 85, 81, 68, 86, 77, 70,
-  75, 75, 69, 88, 87, 83, 55, 87, 73, 95,
-  65, 83, 79, 83, 64, 68, 56, 92, 64, 85,
-  99, 87, 80, 80, 65, 83, 77, 86, 108, 76,
-  77, 83, 70, 95, 96, 91, 71, 89, 80, 82,
-  86, 98, 75, 72, 80, 97, 89, 52, 75, 83,
-  73, 87, 86, 84, 79, 81, 86, 71, 99, 73,
-  83, 56, 75, 85, 83, 82, 78, 88, 85, 84,
-  69, 91, 83, 91, 81, 91, 94, 87, 76, 73,
-  90, 85, 77, 79, 82, 78, 94, 84, 78, 77,
-  82, 79, 78, 84, 88, 77, 83, 75, 90, 74,
-  69, 87, 70, 88, 86, 97, 83, 87, 78, 80,
-  89, 86, 82, 81, 93, 90, 81, 91, 84, 90,
-  87, 74, 87, 85, 84, 87, 79, 81, 79, 95,
-  84, 84, 87, 78, 74, 87, 89, 95, 90, 88,
-  94, 85, 69, 83, 69, 90, 88, 87, 91, 83,
-  83, 86, 77, 93, 87, 86, 73, 83, 82, 79,
-  68, 97, 92, 97, 80, 73, 84, 86, 96, 102,
-  74, 79, 71, 93, 83, 81, 77, 87, 88, 83,
-  91, 81, 104, 85, 84, 75, 82, 92, 86, 89,
-  77, 92, 74, 94, 77, 92, 82, 82, 89, 92,
-  71, 79, 102, 89, 94, 86, 85, 85, 76, 89,
-  82, 81, 84, 77, 68, 89, 98, 73, 90, 79,
-  84, 84, 84, 85, 86, 90, 96, 84, 84, 81,
-  78, 92, 79, 86, 91, 99, 85, 88, 91, 77,
-  83, 73, 84, 70, 77, 79, 76, 81, 83, 98,
-  64, 76, 84, 87, 86, 90, 91, 66, 89, 77,
-  80, 83, 86, 90, 85, 82, 68, 87, 90, 81,
-  86, 73, 82, 85, 94, 78, 92, 89, 78, 77,
-  89, 94, 98, 90, 94, 83, 85, 85, 91, 85,
-  89, 83, 87, 109, 87, 91, 86, 85, 91, 88,
-  86, 87, 78, 85, 73, 99, 84, 91, 83, 84,
-  97, 86, 77, 79, 90, 69, 75, 56, 65, 83,
-  93, 81, 93, 83, 84, 80, 67, 84, 87, 79,
-  86, 111, 89, 82, 82, 65, 95, 93, 78, 88,
-  76, 83, 83, 84, 79, 120, 75, 90, 84, 90,
-  94, 83, 81, 84, 89, 94, 74, 88, 78, 88,
-  84, 87, 82, 82, 78, 78, 84, 78, 77, 75,
-  84, 97, 80, 89, 91, 71, 84, 78, 82, 78,
-  78, 87, 80, 78, 79, 73, 80, 82, 85, 89,
-  61, 91, 77, 83, 71, 85, 82, 84, 74, 69,
-  65, 89, 77, 85, 98, 83, 76, 84, 77, 93,
-  82, 85, 82, 81, 79, 89, 68, 99, 86, 98,
-  79, 80, 83, 81, 84, 94, 80, 82, 83, 90,
-  82, 62, 72, 91, 89, 95, 87, 87, 78, 91,
-  83, 81, 96, 77, 86, 70, 75, 90, 83, 79,
-  80, 86, 82, 81, 79, 94, 84, 79, 84, 100,
-  90, 88, 83, 78, 79, 84, 80, 81, 79, 83,
-  92, 82, 82, 90, 81, 83, 81, 79, 85, 82,
-  83, 89, 83, 73, 65, 93, 78, 89, 85, 94,
-  89, 81, 85, 87, 85, 78, 81, 78, 94, 87,
-  92, 82, 82, 85, 83, 90, 78, 84, 92, 87,
-  82, 90, 83, 95, 89, 80, 87, 81, 77, 86,
-  87, 81, 93, 85, 96, 91, 86, 76, 77, 89,
-  92, 84, 88, 76, 83, 89, 85, 95, 85, 84,
-  80, 83, 80, 87, 76, 96, 81, 97, 85, 79,
-  87, 84, 92, 93, 81, 88, 79, 90, 74, 86,
-  71, 93, 100, 87, 76, 99, 86, 72, 87, 85,
-  79, 92, 91, 82, 90, 78, 81, 88, 72, 84,
-  80, 79, 78, 84, 67, 69, 90, 99, 66, 99,
-  81, 81, 87, 79, 91, 66, 81, 70, 93, 90,
-  86, 86, 67, 84, 77, 78, 87, 80, 78, 85,
-  77, 83, 74, 88, 72, 85, 88, 79, 76, 80,
-  72, 102, 90, 92, 89, 92, 88, 74, 86, 88,
-  87, 86, 74, 95, 94, 77, 99, 72, 95, 90,
-  81, 86, 104, 91, 74, 89, 87, 87, 83, 74,
-  86, 91, 91, 89, 101, 79, 95, 85, 86, 103,
-  76, 78, 90, 102, 97, 91, 83, 93, 114, 71,
-  98, 79, 75, 72, 83, 73, 94, 70, 84, 84,
-  69, 82, 88, 100, 78, 93, 87, 86, 89, 94,
-  80, 94, 122, 99, 80, 84, 81, 61, 75, 86,
-  83, 82, 74, 89, 77, 79, 74, 84, 78, 75,
-  89, 102, 81, 88, 113, 87, 74, 90, 79, 86,
-  94, 75, 86, 87, 81, 81, 75, 88, 72, 85,
-  86, 77, 79, 71, 82, 89, 87, 82, 72, 83,
-  74, 85, 77, 85, 81, 80, 90, 98, 86, 70,
-  94, 76, 88, 74, 92, 67, 61, 79, 73, 98,
-  80, 77, 105, 81, 86, 73, 87, 90, 92, 77,
-  85, 82, 79, 84, 77, 79, 81, 78, 92, 84,
-  80, 76, 79, 85, 92, 69, 82, 86, 86, 74,
-  93, 69, 84, 85, 72, 86, 90, 89, 94, 85,
-  61, 77, 76, 77, 96, 83, 72, 93, 64, 72,
-  71, 87, 78, 79, 66, 88, 89, 95, 102, 82,
-  130, 85, 86, 96, 86, 92, 76, 80, 90, 84,
-  83, 73, 92, 87, 83, 93, 79, 79, 92, 97,
-  99, 94, 91, 79, 98, 82, 87, 92, 94, 87,
-  82, 116, 92, 84, 76, 86, 80, 78, 80, 75,
-  87, 81, 66, 79, 83, 85, 90, 89, 81, 82,
-  75, 91, 88, 98, 92, 91, 88, 70, 77, 79,
-  89, 78, 92, 98, 76, 93, 69, 94, 97, 76,
-  84, 89, 80, 75, 91, 81, 102, 73, 72, 83,
-  81, 81, 89, 77, 87, 83, 91, 82, 77, 85,
-  71, 107, 82, 76, 64, 77, 89, 80, 102, 74,
-  90, 73, 68, 79, 62, 87, 74, 81, 89, 80,
-  82, 80, 88, 90, 76, 99, 82, 69, 73, 77,
-  87, 69, 86, 84, 87, 98, 94, 91, 71, 100,
-  91, 76, 87, 95, 71, 85, 96, 93, 85, 79,
-  74, 77, 73, 99, 81, 80, 80, 87, 72, 73,
-  75, 100, 75, 99, 75, 90, 84, 77, 94, 67,
-  79, 83, 78, 95, 83, 113, 76, 81, 94, 78,
-  73, 84, 65, 83, 89, 74, 76, 90, 77, 75,
-  90, 71, 81, 80, 75, 97, 98, 93, 93, 88,
-  85, 67, 72, 86, 91, 87, 66, 84, 87, 74,
-  91, 72, 96, 96, 83, 86, 86, 84, 81, 84,
-  80, 85, 87, 83, 83, 88, 91, 97, 93, 92,
-  102, 79, 81, 109, 71, 75, 84, 102, 94, 91,
-  87, 90, 96, 73, 93, 89, 80, 83, 68, 77,
-  95, 68, 72, 73, 73, 89, 99, 88, 77, 94,
-  81, 86, 86, 83, 81, 92, 119, 94, 95, 78,
-  83, 59, 75, 84, 77, 88, 73, 90, 69, 84,
-  78, 91, 76, 82, 92, 105, 89, 91, 130, 85,
-  73, 91, 75, 90, 98, 83, 94, 81, 72, 78,
-  62, 89, 78, 85, 77, 72, 92, 73, 64, 93,
-  99, 83, 74, 84, 76, 79, 71, 82, 83, 78,
-  95, 74, 88, 66, 97, 74, 82, 71, 89, 66,
-  55, 85, 66, 88, 75, 75, 86, 80, 81, 79,
-  88, 92, 85, 74, 74, 87, 85, 86, 77, 81,
-  85, 82, 94, 90, 69, 79, 73, 72, 93, 79,
-  76, 96, 84, 87, 85, 71, 79, 71, 76, 83,
-  77, 84, 87, 87, 63, 76, 89, 87, 92, 80,
-  78, 83, 71, 81, 77, 85, 82, 74, 62, 88,
-  85, 82, 113, 78, 136, 79, 78, 91, 88, 97,
-  77, 80, 83, 80, 85, 69, 103, 88, 85, 90,
-  86, 84, 96, 88, 104, 91, 77, 74, 88, 87,
-  84, 93, 94, 86, 84, 118, 92, 83, 85, 85,
-  83, 60, 78, 70, 77, 76, 72, 80, 104, 89,
-  79, 76, 87, 83, 75, 93, 89, 105, 99, 85,
-  73, 71, 70, 79, 83, 77, 93, 96, 74, 97,
-  69, 91, 90, 61, 85, 90, 76, 81, 84, 78,
-  89, 78, 72, 92, 86, 75, 99, 76, 92, 85,
-  94, 83, 77, 81, 72, 79, 78, 83, 70, 81,
-  87, 93, 87, 77, 77, 69, 66, 79, 58, 91,
-  82, 78, 82, 75, 99, 90, 80, 91, 77, 101,
-  80, 72, 70, 80, 85, 70, 86, 73, 84, 86,
-  93, 87, 87, 90, 95, 84, 88, 81, 69, 88,
-  94, 81, 82, 84, 72, 84, 77, 92, 80, 82,
-  75, 87, 85, 81, 89, 90, 82, 82, 82, 86,
-  78, 79, 85, 78, 81, 82, 75, 98, 83, 109,
-  94, 82, 96, 79, 72, 86, 76, 79, 100, 80,
-  90, 73, 86, 76, 81, 80, 77, 81, 87, 99,
-  97, 79, 84, 87, 85, 69, 80, 88, 87, 82,
-  73, 88, 89, 68, 92, 67, 96, 79, 89, 87,
-  85, 83, 86, 86, 83, 87, 84, 86, 89, 81,
-  89, 88, 89, 81, 96, 79, 84, 99, 84, 80,
-  85, 96, 89, 97, 76, 91, 81, 84, 82, 81,
-  87, 75, 69, 83, 92, 68, 78, 83, 75, 81,
-  82, 88, 79, 83, 73, 87, 78, 94, 81, 88,
-  110, 88, 82, 83, 81, 66, 79, 90, 81, 91,
-  85, 86, 83, 81, 78, 87, 76, 83, 93, 92,
-  86, 88, 102, 84, 82, 82, 81, 94, 92, 86,
-  86, 87, 87, 78, 66, 83, 91, 80, 76, 77,
-  88, 82, 71, 92, 96, 85, 87, 89, 86, 73,
-  81, 87, 83, 88, 86, 76, 87, 76, 89, 86,
-  79, 73, 86, 75, 69, 83, 73, 88, 75, 69,
-  76, 80, 83, 76, 92, 91, 90, 74, 84, 89,
-  89, 90, 85, 82, 87, 80, 83, 87, 83, 75,
-  73, 69, 85, 78, 71, 90, 92, 89, 80, 81,
-  88, 81, 74, 85, 68, 91, 90, 84, 79, 77,
-  96, 87, 87, 74, 88, 98, 69, 78, 85, 88,
-  82, 72, 73, 87, 87, 89, 96, 85, 96, 78,
-  67, 89, 83, 87, 81, 87, 85, 92, 89, 72,
-  98, 82, 84, 93, 79, 86, 87, 89, 93, 78,
-  90, 85, 80, 83, 91, 95, 87, 89, 74, 101,
-  92, 85, 80, 81, 99, 64, 72, 75, 81, 86,
-  76, 74, 96, 82, 82, 89, 83, 85, 76, 95,
-  91, 107, 87, 80, 70, 76, 68, 99, 79, 85,
-  97, 97, 85, 91, 81, 97, 79, 69, 83, 98,
-  87, 79, 87, 87, 90, 82, 83, 88, 89, 77,
-  95, 80, 86, 82, 85, 79, 84, 80, 64, 75,
-  78, 81, 70, 88, 87, 84, 87, 88, 78, 81,
-  79, 79, 69, 92, 89, 82, 75, 77, 99, 80,
-  82, 90, 92, 109, 79, 77, 85, 90, 90, 73,
-  84, 79, 83, 85, 91, 88, 74, 81, 89, 96,
-  89, 76, 87, 70, 80, 86, 77, 88, 72, 86,
-  84, 79, 88, 77, 102, 76, 61, 84, 73, 82,
-  74, 80, 95, 89, 100, 106, 89, 87, 92, 88,
-  97, 78, 80, 81, 85, 89, 87, 82, 74, 91,
-  72, 82, 78, 98, 89, 98, 89, 84, 71, 76,
-  70, 80, 66, 86, 87, 76, 75, 97, 104, 76,
-  97, 83, 94, 83, 78, 99, 81, 81, 78, 72,
-  69, 100, 68, 89, 101, 97, 81, 84, 73, 88,
-  93, 94, 82, 91, 81, 90, 100, 87, 72, 78,
-  96, 91, 55, 87, 73, 72, 80, 79, 82, 107,
-  97, 76, 88, 76, 85, 79, 84, 83, 73, 93,
-  94, 92, 92, 79, 87, 65, 73, 78, 90, 82,
-  86, 64, 83, 82, 71, 86, 88, 91, 92, 83,
-  79, 74, 90, 94, 71, 86, 72, 88, 84, 66,
-  81, 81, 107, 78, 61, 81, 83, 81, 74, 87,
-  105, 95, 88, 105, 88, 80, 83, 86, 105, 96,
-  80, 79, 88, 86, 86, 84, 70, 89, 71, 72,
-  72, 93, 81, 98, 85, 90, 69, 77, 80, 90,
-  68, 80, 87, 73, 69, 91, 97, 74, 103, 92,
-  88, 75, 72, 106, 95, 77, 77, 75, 70, 95,
-  69, 97, 105, 96, 72, 80, 77, 90, 89, 90,
-  82, 92, 71, 76, 110, 79, 70, 78, 92, 83,
-  52, 86, 79, 81, 79, 85, 88, 99, 100, 77,
-  94, 82, 84, 82, 76, 84, 76, 83, 91, 90,
-  90, 79, 89, 61, 90, 79, 92, 85, 94, 59,
-  88, 89, 79, 81, 84, 94, 85, 81, 93, 79,
-  83, 87, 74, 92, 74, 91, 88, 77, 84, 80,
-  100, 83, 72, 77, 82, 81, 76, 80, 93, 92,
-  94, 92, 90, 77, 91, 84, 95, 110, 87, 81,
-  82, 90, 86, 84, 70, 90, 73, 79, 73, 86,
-  88, 98, 86, 79, 74, 77, 77, 86, 71, 88,
-  89, 73, 75, 93, 98, 83, 90, 84, 95, 78,
-  79, 93, 94, 84, 75, 81, 69, 100, 71, 94,
-  102, 91, 81, 84, 74, 83, 89, 92, 92, 81,
-  79, 80, 102, 83, 78, 79, 79, 90, 59, 89,
-  85, 82, 81, 93, 79, 109, 96, 76, 91, 73,
-  79, 81, 72, 81, 74, 79, 82, 90, 83, 77,
-  87, 66, 96, 78, 92, 84, 89, 65, 79, 76,
-  73, 87, 77, 90, 86, 88, 77, 70, 97, 86,
-  87, 83, 84, 78, 84, 73, 94, 89, 116, 71,
-  58, 82, 75, 90, 77, 72, 88, 102, 88, 103,
-  80, 86, 85, 82, 83, 83, 80, 69, 86, 81,
-  80, 87, 78, 86, 74, 77, 70, 97, 79, 102,
-  85, 88, 63, 75, 77, 79, 72, 91, 72, 77,
-  87, 92, 90, 74, 88, 92, 95, 81, 78, 90,
-  87, 78, 85, 78, 68, 102, 81, 85, 87, 95,
-  77, 84, 79, 79, 81, 81, 84, 91, 82, 106,
-  102, 93, 61, 83, 102, 86, 49, 84, 70, 80,
-  90, 74, 79, 99, 93, 80, 85, 84, 77, 98,
-  84, 79, 88, 88, 83, 84, 91, 81, 76, 68,
-  89, 81, 81, 102, 87, 69, 86, 101, 75, 101,
-  73, 85, 84, 79, 64, 85, 110, 85, 104, 81,
-  81, 76, 79, 73, 95, 93, 137, 65, 63, 75,
-  84, 107, 72, 76, 89, 112, 102, 87, 80, 86,
-  84, 77, 91, 81, 80, 74, 76, 80, 75, 82,
-  63, 77, 72, 83, 69, 83, 73, 126, 82, 81,
-  57, 74, 97, 77, 84, 77, 74, 67, 83, 90,
-  82, 68, 62, 88, 96, 66, 70, 84, 71, 60,
-  100, 89, 72, 115, 88, 88, 86, 99, 73, 76,
-  93, 96, 72, 77, 73, 82, 77, 117, 130, 83,
-  59, 75, 98, 71, 66, 78, 81, 89, 98, 85,
-  82, 95, 85, 80, 97, 84, 76, 118, 70, 74,
-  103, 76, 77, 82, 78, 78, 72, 64, 116, 83,
-  78, 115, 102, 65, 90, 126, 74, 85, 91, 92,
-  87, 83, 86, 76, 91, 88, 84, 84, 79, 89,
-  88, 69, 89, 84, 108, 87, 78, 81, 94, 86,
-  69, 71, 94, 97, 84, 76, 85, 73, 87, 83,
-  90, 113, 79, 72, 80, 76, 83, 84, 65, 85,
-  74, 72, 66, 78, 81, 102, 84, 80, 68, 75,
-  74, 88, 76, 86, 79, 73, 82, 90, 90, 74,
-  81, 86, 91, 76, 80, 90, 87, 79, 75, 86,
-  71, 96, 77, 96, 91, 92, 76, 81, 80, 89,
-  83, 82, 82, 79, 79, 97, 102, 85, 62, 82,
-  84, 86, 50, 82, 86, 85, 90, 95, 76, 102,
-  91, 77, 91, 83, 75, 89, 77, 77, 88, 83,
-  81, 83, 72, 78, 76, 65, 97, 80, 84, 96,
-  90, 74, 85, 91, 80, 89, 79, 88, 92, 90,
-  89, 73, 87, 79, 82, 80, 86, 79, 86, 69,
-  89, 87, 97, 80, 67, 78, 76, 89, 78, 73,
-  76, 92, 82, 88, 81, 88, 89, 84, 77, 83,
-  77, 83, 88, 84, 78, 87, 89, 84, 80, 77,
-  69, 95, 80, 99, 86, 92, 70, 79, 64, 89,
-  78, 97, 75, 77, 85, 87, 88, 80, 95, 87,
-  95, 83, 85, 78, 87, 79, 80, 85, 69, 96,
-  85, 89, 83, 91, 85, 84, 74, 77, 84, 86,
-  89, 76, 89, 104, 97, 111, 69, 85, 107, 88,
-  60, 83, 71, 79, 81, 78, 69, 104, 86, 79,
-  82, 81, 83, 91, 85, 79, 89, 84, 81, 88,
-  85, 85, 82, 87, 97, 77, 70, 97, 78, 76,
-  87, 85, 86, 93, 87, 85, 94, 82, 83, 81,
-  94, 78, 98, 77, 83, 82, 88, 77, 89, 87,
-  112, 75, 74, 75, 87, 92, 72, 68, 70, 94,
-  92, 80, 84, 85, 88, 79, 83, 86, 79, 85,
-  81, 84, 79, 80, 77, 80, 76, 77, 67, 88,
-  74, 114, 83, 86, 66, 75, 74, 85, 80, 89,
-  78, 72, 83, 84, 82, 77, 77, 86, 96, 76,
-  78, 83, 76, 67, 87, 98, 69, 94, 90, 89,
-  79, 95, 79, 81, 86, 88, 79, 78, 76, 75,
-  82, 115, 100, 107, 66, 84, 108, 78, 69, 82,
-  79, 81, 92, 86, 70, 98, 74, 81, 87, 82,
-  78, 99, 80, 79, 93, 75, 84, 91, 75, 84,
-  83, 82, 105, 84, 70, 106, 76, 76, 85, 106,
-  81, 83, 96, 94, 96, 78, 96, 75, 86, 81,
-  80, 80, 80, 90, 95, 68, 89, 83, 99, 86,
-  90, 77, 102, 85, 69, 72, 82, 84, 86, 78,
-  86, 74, 93, 83, 82, 111, 79, 83, 82, 86,
-  78, 85, 71, 83, 78, 77, 63, 80, 80, 102,
-  87, 85, 74, 77, 64, 78, 76, 90, 79, 74,
-  87, 82, 89, 81, 89, 83, 89, 76, 87, 86,
-  80, 78, 73, 94, 69, 91, 84, 95, 84, 87,
-  84, 83, 83, 85, 87, 83, 85, 71, 87, 98,
-  94, 91, 72, 84, 90, 88, 62, 82, 83, 78,
-  87, 87, 67, 106, 90, 75, 89, 77, 81, 88,
-  85, 75, 83, 84, 84, 89, 77, 81, 80, 84,
-  89, 78, 72, 90, 80, 86, 87, 80, 85, 93,
-  77, 90, 83, 80, 82, 91, 78, 85, 83, 69,
-  88, 85, 74, 71, 75, 95, 91, 75, 85, 78,
-  94, 70, 93, 82, 91, 96, 94, 81, 94, 80,
-  88, 77, 83, 73, 86, 90, 89, 85, 84, 66,
-  101, 79, 64, 91, 93, 83, 75, 94, 86, 92,
-  85, 90, 92, 83, 84, 86, 82, 96, 96, 82,
-  103, 88, 99, 67, 82, 89, 72, 103, 76, 83,
-  87, 97, 88, 80, 83, 76, 102, 76, 90, 80,
-  68, 97, 67, 72, 107, 93, 84, 79, 76, 75,
-  83, 83, 92, 93, 91, 66, 82, 73, 84, 71,
-  82, 83, 77, 83, 87, 90, 100, 72, 84, 95,
-  73, 85, 93, 77, 98, 94, 87, 97, 84, 80,
-  88, 84, 101, 104, 85, 79, 81, 89, 75, 84,
-  98, 68, 77, 90, 83, 82, 86, 60, 72, 83,
-  70, 71, 74, 74, 82, 76, 93, 83, 73, 73,
-  83, 73, 78, 93, 88, 88, 87, 81, 77, 76,
-  83, 78, 92, 85, 78, 91, 83, 67, 89, 73,
-  67, 86, 108, 70, 84, 92, 78, 84, 79, 98,
-  91, 89, 95, 94, 77, 89, 99, 116, 108, 109,
-  78, 80, 77, 93, 91, 88, 71, 84, 76, 93,
-  98, 82, 82, 76, 104, 73, 83, 75, 68, 89,
-  70, 70, 83, 98, 82, 75, 83, 78, 87, 81,
-  83, 99, 89, 63, 81, 90, 85, 87, 78, 83,
-  80, 82, 83, 92, 96, 63, 84, 88, 72, 88,
-  92, 69, 79, 93, 79, 90, 90, 76, 84, 86,
-  100, 102, 85, 87, 83, 82, 87, 87, 84, 89,
-  82, 88, 75, 87, 78, 71, 79, 89, 79, 70,
-  74, 100, 88, 77, 100, 70, 82, 73, 81, 82,
-  93, 96, 89, 88, 95, 86, 87, 74, 86, 86,
-  90, 88, 75, 84, 83, 68, 83, 75, 70, 89,
-  91, 68, 75, 94, 90, 85, 82, 83, 100, 93,
-  84, 84, 85, 96, 96, 73, 96, 88, 100, 65,
-  73, 87, 74, 94, 91, 82, 84, 98, 94, 79,
-  81, 89, 91, 74, 95, 81, 71, 86, 67, 71,
-  82, 87, 86, 78, 81, 85, 88, 84, 90, 90,
-  90, 63, 84, 74, 82, 93, 81, 82, 80, 80,
-  86, 86, 95, 75, 86, 92, 73, 106, 82, 69,
-  67, 93, 85, 89, 93, 81, 91, 83, 97, 99,
-  87, 78, 74, 99, 73, 95, 96, 75, 82, 84,
-  79, 75, 94, 73, 94, 95, 77, 76, 84, 87,
-  95, 77, 92, 74, 75, 77, 97, 76, 78, 102,
-  96, 79, 101, 78, 85, 72, 84, 67, 72, 82,
-  110, 89, 65, 67, 95, 74, 70, 98, 90, 83,
-  69, 86, 89, 84, 83, 105, 62, 81, 70, 78,
-  70, 88, 96, 99, 95, 90, 72, 70, 98, 95,
-  94, 70, 65, 77, 89, 97, 89, 67, 80, 80,
-  99, 92, 72, 97, 72, 96, 85, 79, 107, 94,
-  97, 83, 70, 79, 68, 93, 71, 104, 90, 76,
-  85, 88, 77, 62, 77, 82, 89, 73, 79, 86,
-  91, 61, 87, 100, 71, 76, 78, 69, 83, 100,
-  82, 91, 104, 77, 60, 83, 86, 83, 85, 90,
-  70, 91, 69, 82, 109, 60, 67, 84, 80, 69,
-  105, 65, 82, 99, 64, 67, 80, 58, 76, 71,
-  94, 90, 62, 82, 89, 57, 62, 93, 85, 83,
-  93, 83, 68, 78, 84, 69, 85, 74, 103, 98,
-  73, 71, 83, 60, 78, 93, 96, 84, 80, 88,
-  81, 83, 72, 111, 63, 83, 87, 78, 74, 83,
-  103, 137, 99, 134, 55, 98, 90, 104, 121, 58,
-  61, 78, 75, 91, 96, 74, 79, 83, 99, 95,
-  59, 84, 74, 85, 85, 80, 71, 99, 83, 77,
-  82, 78, 82, 91, 65, 102, 86, 74, 87, 119,
-  79, 77, 77, 81, 92, 78, 70, 85, 85, 45,
-  84, 93, 73, 70, 75, 62, 66, 103, 78, 86,
-  102, 73, 43, 88, 81, 78, 80, 100, 75, 94,
-  85, 91, 102, 74, 83, 90, 75, 78, 86, 72,
-  85, 100, 82, 77, 87, 95, 88, 81, 97, 72,
-  82, 82, 86, 79, 80, 101, 91, 86, 97, 93,
-  88, 73, 85, 83, 72, 80, 91, 88, 70, 66,
-  89, 76, 77, 100, 84, 77, 70, 88, 91, 83,
-  80, 94, 67, 87, 69, 80, 74, 87, 100, 87,
-  88, 91, 78, 67, 86, 92, 94, 65, 75, 74,
-  89, 94, 97, 68, 77, 86, 93, 90, 79, 93,
-  72, 89, 83, 83, 78, 89, 94, 81, 75, 83,
-  73, 90, 69, 98, 90, 75, 88, 83, 81, 88,
-  77, 82, 88, 73, 81, 87, 83, 68, 83, 102,
-  70, 99, 75, 63, 58, 99, 79, 88, 101, 83,
-  74, 78, 86, 79, 87, 86, 71, 90, 80, 101,
-  68, 86, 78, 82, 88, 82, 93, 98, 84, 85,
-  79, 83, 84, 99, 86, 85, 95, 85, 83, 68,
-  95, 75, 78, 97, 88, 76, 89, 74, 85, 81,
-  76, 72, 79, 89, 99, 89, 76, 70, 92, 77,
-  70, 84, 74, 83, 74, 94, 92, 86, 93, 97,
-  71, 80, 75, 79, 83, 83, 87, 102, 86, 82,
-  93, 72, 90, 89, 100, 83, 76, 81, 84, 103,
-  82, 77, 77, 83, 89, 90, 72, 85, 75, 92,
-  91, 85, 105, 94, 90, 87, 83, 107, 81, 89,
-  88, 95, 80, 78, 85, 86, 88, 78, 81, 80,
-  92, 87, 86, 89, 83, 79, 87, 82, 74, 81,
-  81, 78, 81, 96, 81, 87, 90, 82, 69, 82,
-  85, 96, 79, 88, 68, 81, 77, 93, 68, 85,
-  68, 83, 87, 79, 96, 90, 69, 87, 60, 73,
-  80, 77, 76, 82, 98, 101, 80, 69, 87, 60,
-  71, 90, 79, 76, 86, 81, 74, 82, 72, 78,
-  87, 81, 87, 93, 76, 74, 87, 70, 76, 85,
-  81, 84, 79, 92, 85, 82, 91, 97, 84, 80,
-  93, 82, 80, 83, 90, 124, 92, 106, 72, 84,
-  72, 86, 114, 79, 76, 83, 75, 99, 84, 80,
-  77, 84, 81, 91, 63, 71, 81, 81, 92, 87,
-  73, 97, 85, 85, 96, 98, 89, 83, 82, 87,
-  76, 80, 78, 106, 87, 83, 84, 80, 92, 88,
-  80, 88, 82, 71, 84, 77, 76, 74, 76, 68,
-  82, 98, 81, 87, 88, 79, 65, 86, 84, 90,
-  77, 91, 72, 79, 98, 97, 73, 86, 79, 86,
-  80, 84, 84, 92, 85, 94, 84, 83, 88, 105,
-  78, 86, 92, 79, 87, 75, 87, 78, 78, 97,
-  82, 84, 88, 90, 88, 80, 78, 88, 79, 86,
-  84, 92, 78, 72, 93, 77, 77, 85, 68, 80,
-  77, 96, 93, 80, 92, 89, 78, 84, 70, 81,
-  86, 78, 86, 88, 85, 84, 95, 71, 78, 84,
-  92, 83, 78, 81, 83, 97, 86, 77, 75, 79,
-  86, 88, 76, 83, 77, 91, 85, 91, 79, 88,
-  89, 89, 85, 101, 86, 83, 78, 90, 81, 78,
-  89, 82, 92, 90, 78, 82, 94, 89, 88, 89,
-  79, 85, 86, 82, 68, 97, 80, 77, 67, 97,
-  81, 86, 94, 86, 82, 78, 87, 91, 82, 86,
-  97, 91, 86, 83, 92, 73, 77, 74, 82, 87,
-  76, 80, 121, 69, 70, 79, 84, 91, 86, 92,
-  69, 99, 68, 81, 86, 80, 105, 85, 100, 83,
-  75, 73, 78, 91, 80, 92, 102, 84, 86, 106,
-  88, 86, 99, 85, 103, 81, 83, 91, 88, 90,
-  75, 81, 85, 74, 75, 87, 76, 62, 102, 81,
-  77, 79, 96, 88, 67, 84, 88, 91, 72, 85,
-  102, 90, 80, 78, 74, 92, 82, 104, 73, 70,
-  84, 68, 92, 104, 84, 82, 91, 82, 82, 93,
-  74, 78, 86, 88, 98, 65, 86, 85, 95, 94,
-  71, 72, 79, 82, 93, 60, 77, 84, 71, 76,
-  93, 71, 81, 87, 79, 84, 89, 86, 95, 73,
-  80, 72, 77, 82, 82, 72, 77, 77, 77, 77,
-  84, 85, 94, 77, 72, 84, 74, 95, 87, 77,
-  68, 76, 68, 85, 71, 78, 79, 94, 89, 96,
-  68, 81, 78, 75, 102, 86, 98, 90, 66, 77,
-  87, 109, 81, 116, 100, 96, 82, 81, 106, 71,
-  75, 73, 130, 86, 83, 90, 108, 78, 61, 57,
-  77, 77, 68, 64, 105, 64, 124, 86, 80, 146,
-  113, 72, 71, 83, 93, 112, 79, 79, 71, 90,
-  100, 70, 74, 119, 86, 90, 57, 58, 81, 61,
-  85, 95, 74, 82, 94, 94, 58, 89, 87, 92,
-  96, 89, 122, 65, 82, 99, 81, 108, 76, 81,
-  94, 84, 85, 62, 80, 74, 68, 62, 73, 68,
-  92, 92, 74, 79, 96, 89, 95, 70, 79, 63,
-  71, 99, 73, 76, 63, 67, 91, 75, 101, 81,
-  85, 79, 82, 80, 81, 84, 79, 80, 113, 87,
-  68, 77, 87, 85, 83, 86, 98, 89, 75, 81,
-  77, 78, 99, 86, 92, 87, 83, 89, 77, 93,
-  86, 101, 105, 86, 84, 102, 77, 85, 78, 89,
-  96, 86, 86, 103, 86, 86, 81, 89, 82, 73,
-  73, 69, 79, 76, 108, 85, 76, 79, 94, 83,
-  77, 82, 83, 91, 79, 91, 82, 86, 82, 79,
-  79, 89, 84, 88, 69, 71, 88, 80, 87, 86,
-  83, 81, 89, 83, 84, 87, 81, 76, 85, 84,
-  85, 73, 87, 83, 86, 89, 76, 79, 78, 82,
-  91, 66, 78, 82, 72, 78, 93, 71, 84, 92,
-  83, 82, 74, 79, 93, 71, 96, 76, 80, 80,
-  87, 75, 72, 75, 97, 88, 52, 77, 74, 83,
-  78, 73, 67, 88, 87, 70, 109, 74, 70, 83,
-  78, 94, 83, 83, 70, 84, 73, 87, 77, 79,
-  103, 92, 89, 95, 79, 75, 70, 71, 97, 83,
-  99, 84, 91, 79, 93, 87, 80, 94, 85, 76,
-  97, 84, 79, 79, 93, 76, 90, 78, 80, 112,
-  70, 92, 75, 85, 90, 70, 84, 81, 70, 74,
-  90, 85, 77, 73, 100, 89, 71, 78, 86, 68,
-  78, 85, 86, 75, 87, 96, 82, 75, 86, 75,
-  80, 74, 90, 88, 62, 71, 82, 89, 82, 69,
-  95, 85, 118, 70, 67, 86, 69, 84, 98, 75,
-  74, 84, 94, 88, 85, 75, 74, 74, 98, 89,
-  74, 88, 91, 68, 81, 72, 65, 88, 80, 80,
-  88, 107, 100, 81, 85, 71, 71, 68, 76, 82,
-  66, 86, 89, 76, 84, 83, 62, 85, 68, 93,
-  85, 76, 71, 82, 68, 79, 76, 77, 114, 88,
-  86, 91, 83, 87, 67, 75, 91, 79, 106, 77,
-  79, 68, 102, 84, 71, 87, 91, 71, 114, 78,
-  84, 69, 92, 81, 84, 78, 81, 98, 79, 94,
-  82, 92, 87, 76, 104, 71, 72, 69, 86, 79,
-  72, 83, 83, 86, 74, 72, 85, 65, 76, 78,
-  91, 65, 81, 102, 81, 74, 86, 76, 72, 77,
-  104, 92, 67, 75, 84, 83, 100, 65, 98, 93,
-  82, 67, 75, 76, 67, 82, 92, 80, 70, 81,
-  98, 79, 98, 70, 76, 73, 102, 87, 74, 82,
-  82, 64, 87, 70, 74, 89, 76, 87, 74, 105,
-  88, 82, 113, 76, 76, 76, 81, 75, 72, 86,
-  82, 73, 100, 91, 71, 83, 79, 95, 81, 83,
-  77, 82, 80, 87, 80, 79, 94, 89, 86, 92,
-  93, 95, 68, 71, 91, 79, 95, 87, 73, 80,
-  89, 90, 76, 92, 83, 82, 109, 92, 79, 80,
-  93, 87, 88, 78, 78, 74, 65, 97, 81, 85,
-  88, 68, 81, 83, 75, 71, 92, 86, 76, 76,
-  70, 85, 73, 79, 87, 70, 80, 73, 83, 75,
-  89, 100, 79, 80, 87, 78, 72, 76, 93, 89,
-  61, 60, 81, 89, 83, 75, 98, 83, 67, 73,
-  73, 77, 69, 83, 98, 81, 68, 80, 93, 89,
-  107, 77, 79, 79, 99, 90, 68, 89, 87, 64,
-  89, 71, 72, 87, 85, 80, 86, 99, 71, 85,
-  67, 95, 86, 94, 67, 74, 88, 88, 79, 78,
-  90, 85, 81, 84, 86, 96, 83, 75, 93, 89,
-  78, 84, 84, 86, 82, 87, 91, 98, 85, 85,
-  78, 79, 82, 90, 92, 87, 76, 83, 91, 91,
-  80, 97, 80, 87, 74, 81, 76, 89, 85, 87,
-  90, 90, 92, 90, 74, 83, 80, 78, 85, 95,
-  78, 74, 95, 90, 88, 84, 93, 70, 88, 95,
-  78, 85, 87, 74, 78, 85, 75, 84, 86, 94,
-  84, 83, 83, 84, 82, 84, 80, 85, 81, 91,
-  83, 89, 90, 85, 84, 79, 99, 93, 76, 100,
-  76, 86, 86, 79, 81, 93, 76, 89, 77, 97,
-  85, 85, 90, 81, 79, 92, 80, 87, 91, 83,
-  79, 89, 91, 80, 91, 102, 71, 87, 78, 94,
-  82, 75, 71, 80, 91, 80, 82, 85, 96, 88,
-  85, 83, 88, 100, 87, 72, 84, 87, 79, 83,
-  93, 88, 85, 86, 87, 84, 94, 96, 82, 78,
-  81, 79, 84, 85, 88, 75, 86, 100, 84, 98,
-  79, 75, 87, 86, 77, 83, 85, 86, 89, 89,
-  87, 87, 76, 90, 81, 83, 82, 88, 77, 74,
-  82, 91, 103, 85, 96, 70, 74, 87, 75, 84,
-  88, 68, 79, 88, 78, 81, 87, 98, 85, 79,
-  85, 85, 78, 79, 89, 88, 83, 83, 84, 89,
-  86, 82, 83, 87, 92, 85, 71, 97, 68, 85,
-  88, 92, 84, 90, 84, 93, 76, 96, 86, 79,
-  91, 91, 78, 91, 85, 80, 88, 87, 87, 90,
-  94, 82, 96, 110, 68, 86, 95, 93, 88, 74,
-  70, 76, 90, 87, 74, 79, 91, 81, 82, 85,
-  90, 97, 82, 78, 80, 91, 90, 84, 91, 84,
-  79, 85, 85, 83, 83, 93, 79, 79, 89, 77,
-  88, 86, 83, 84, 94, 90, 93, 94, 82, 82,
-  85, 89, 77, 87, 84, 79, 87, 88, 84, 76,
-  72, 84, 86, 80, 85, 90, 76, 81, 92, 88,
-  92, 91, 90, 84, 78, 94, 83, 84, 85, 76,
-  80, 84, 76, 85, 83, 94, 79, 88, 87, 84,
-  79, 86, 78, 87, 77, 74, 85, 88, 86, 89,
-  79, 79, 74, 91, 76, 76, 77, 86, 87, 82,
-  81, 90, 75, 90, 72, 98, 85, 81, 95, 85,
-  93, 94, 79, 86, 86, 85, 80, 90, 95, 81,
-  90, 96, 70, 94, 87, 90, 82, 85, 85, 76,
-  72, 92, 74, 75, 80, 115, 69, 68, 71, 98,
-  83, 90, 87, 86, 90, 80, 86, 78, 87, 100,
-  116, 93, 73, 97, 75, 86, 74, 97, 87, 64,
-  94, 69, 87, 61, 79, 69, 70, 80, 83, 86,
-  83, 73, 88, 86, 73, 75, 72, 73, 65, 82,
-  83, 97, 82, 78, 96, 84, 103, 63, 91, 78,
-  82, 122, 73, 78, 104, 71, 77, 72, 74, 76,
-  119, 61, 82, 106, 76, 94, 82, 95, 80, 104,
-  79, 92, 82, 85, 69, 76, 93, 73, 82, 70,
-  72, 76, 78, 79, 94, 110, 125, 81, 79, 86,
-  94, 72, 78, 70, 84, 95, 81, 114, 105, 91,
-  83, 90, 89, 73, 78, 75, 85, 70, 84, 89,
-  75, 95, 78, 82, 92, 77, 85, 74, 77, 85,
-  71, 84, 84, 99, 81, 70, 72, 88, 67, 86,
-  87, 75, 78, 80, 87, 80, 80, 107, 93, 98,
-  73, 92, 75, 81, 83, 77, 93, 71, 95, 80,
-  72, 65, 85, 72, 73, 79, 75, 75, 80, 72,
-  91, 90, 75, 78, 66, 74, 54, 85, 90, 94,
-  75, 73, 99, 71, 95, 66, 95, 68, 79, 89,
-  83, 75, 92, 68, 82, 63, 70, 89, 126, 69,
-  84, 111, 67, 90, 75, 87, 87, 99, 85, 95,
-  81, 89, 68, 79, 76, 76, 81, 78, 80, 78,
-  78, 89, 88, 107, 137, 77, 75, 90, 93, 81,
-  87, 64, 89, 79, 74, 103, 84, 93, 73, 84,
-  101, 77, 84, 69, 90, 79, 79, 88, 81, 73,
-  76, 78, 84, 82, 87, 74, 71, 83, 71, 83,
-  77, 89, 80, 68, 71, 90, 81, 90, 83, 79,
-  70, 81, 79, 82, 89, 93, 95, 91, 77, 86,
-  78, 80, 82, 85, 104, 65, 87, 78, 84, 70,
-  80, 72, 74, 91, 85, 81, 83, 73, 91, 79,
-  77, 80, 75, 76, 68, 86, 84, 94, 81, 85,
-  96, 92, 114, 71, 89, 74, 85, 96, 100, 75,
-  104, 67, 81, 69, 74, 93, 120, 69, 84, 102,
-  75, 88, 83, 81, 100, 95, 79, 94, 81, 98,
-  74, 77, 91, 78, 89, 79, 78, 78, 78, 104,
-  92, 106, 122, 76, 79, 88, 93, 78, 88, 74,
-  87, 79, 79, 100, 75, 90, 81, 88, 95, 77,
-  80, 71, 85, 78, 85, 84, 82, 86, 80, 92,
-  86, 90, 87, 67, 83, 78, 78, 73, 86, 103,
-  86, 71, 80, 81, 82, 72, 86, 79, 75, 89,
-  83, 87, 76, 94, 88, 88, 85, 88, 82, 85,
-  83, 89, 83, 76, 89, 77, 77, 68, 73, 77,
-  82, 83, 84, 87, 84, 74, 95, 79, 73, 80,
-  68, 93, 64, 92, 71, 94, 83, 83, 81, 99,
-  96, 86, 78, 67, 79, 77, 79, 82, 79, 87,
-  81, 71, 80, 77, 97, 81, 84, 96, 73, 83,
-  82, 80, 77, 89, 86, 90, 75, 70, 75, 75,
-  73, 84, 87, 94, 79, 78, 74, 75, 76, 99,
-  106, 84, 84, 80, 92, 83, 95, 82, 100, 80,
-  66, 88, 93, 95, 83, 99, 103, 86, 70, 77,
-  80, 96, 83, 92, 98, 83, 74, 82, 86, 74,
-  83, 72, 82, 69, 80, 86, 96, 88, 96, 71,
-  88, 85, 80, 73, 79, 80, 78, 85, 77, 81,
-  75, 92, 78, 87, 89, 97, 93, 82, 97, 70,
-  87, 73, 94, 82, 76, 77, 79, 85, 94, 84,
-  79, 87, 86, 72, 96, 83, 73, 78, 68, 85,
-  74, 90, 79, 92, 81, 85, 80, 93, 75, 99,
-  83, 75, 81, 73, 74, 77, 75, 86, 80, 68,
-  77, 93, 81, 91, 84, 88, 77, 87, 83, 77,
-  73, 83, 73, 96, 72, 69, 79, 80, 68, 86,
-  82, 108, 80, 89, 76, 86, 75, 96, 77, 91,
-  83, 79, 87, 90, 94, 79, 104, 71, 74, 85,
-  81, 102, 73, 90, 100, 88, 72, 79, 75, 95,
-  77, 100, 90, 80, 79, 88, 84, 81, 82, 67,
-  80, 76, 73, 81, 84, 81, 90, 68, 79, 80,
-  81, 80, 79, 80, 77, 85, 78, 80, 79, 88,
-  77, 81, 86, 104, 91, 82, 95, 84, 87, 78,
-  91, 76, 80, 78, 88, 86, 87, 83, 88, 98,
-  83, 71, 92, 81, 78, 80, 72, 78, 73, 88,
-  77, 84, 82, 88, 85, 105, 100, 88, 77, 69,
-  88, 77, 89, 80, 83, 84, 82, 73, 77, 89,
-  94, 84, 88, 92, 81, 80, 87, 73, 77, 83,
-  89, 87, 79, 75, 76, 79, 78, 87, 86, 92,
-  79, 79, 71, 82, 77, 94, 98, 77, 82, 80,
-  88, 86, 101, 85, 100, 79, 80, 82, 81, 98,
-  83, 91, 92, 84, 75, 78, 82, 94, 89, 89,
-  85, 82, 78, 95, 84, 99, 84, 75, 82, 80,
-  80, 77, 89, 87, 84, 68, 87, 84, 86, 79,
-  84, 82, 73, 86, 79, 87, 88, 87, 83, 90,
-  92, 85, 86, 90, 89, 90, 84, 81, 85, 77,
-  83, 94, 76, 85, 89, 86, 93, 87, 80, 81,
-  99, 82, 83, 83, 86, 94, 68, 87, 70, 89,
-  93, 86, 80, 100, 95, 92, 79, 75, 82, 77,
-  95, 98, 84, 88, 85, 81, 85, 81, 87, 90,
-  88, 78, 80, 85, 89, 84, 80, 84, 87, 76,
-  74, 79, 79, 74, 81, 84, 82, 89, 94, 80,
-  75, 83, 76, 98, 83, 83, 89, 86, 83, 91,
-  94, 90, 93, 76, 79, 83, 93, 89, 81, 93,
-  90, 87, 72, 75, 81, 97, 91, 91, 95, 80,
-  82, 90, 78, 84, 82, 80, 80, 75, 84, 90,
-  100, 85, 82, 63, 94, 92, 89, 87, 81, 85,
-  82, 79, 79, 82, 94, 81, 76, 88, 96, 93,
-  92, 86, 97, 81, 90, 75, 83, 64, 85, 102,
-  83, 97, 94, 86, 91, 87, 83, 76, 89, 79,
-  88, 79, 92, 88, 82, 82, 75, 84, 94, 88,
-  82, 95, 79, 98, 79, 83, 83, 80, 82, 92,
-  82, 87, 92, 83, 75, 93, 80, 87, 87, 68,
-  88, 85, 96, 81, 80, 82, 75, 81, 79, 76,
-  79, 76, 79, 83, 76, 85, 90, 82, 80, 84,
-  77, 96, 59, 85, 90, 87, 76, 95, 90, 86,
-  95, 76, 86, 84, 90, 92, 75, 93, 86, 82,
-  77, 79, 80, 90, 87, 95, 86, 83, 86, 92,
-  83, 84, 79, 77, 81, 80, 81, 81, 86, 83,
-  81, 67, 88, 86, 87, 87, 78, 82, 87, 82,
-  80, 81, 90, 85, 76, 77, 90, 94, 92, 84,
-  98, 87, 84, 85, 80, 71, 87, 97, 83, 92,
-  87, 85, 93, 88, 82, 76, 92, 81, 90, 82,
-  94, 82, 79, 84, 77, 87, 90, 94, 84, 103,
-  95, 89, 79, 77, 85, 79, 85, 93, 89, 84,
-  87, 93, 80, 94, 87, 87, 91, 73, 90, 79,
-  94, 84, 81, 85, 87, 79, 81, 76, 82, 77,
-  84, 85, 80, 80, 82, 80, 76, 82, 75, 95,
-  85, 81, 84, 86, 82, 93, 92, 93, 92, 83,
-  84, 85, 90, 88, 82, 95, 84, 90, 78, 76,
-  89, 94, 96, 90, 89, 78, 85, 82, 103, 97,
-  91, 81, 81, 71, 79, 72, 71, 76, 86, 81,
-  85, 77, 78, 81, 82, 65, 65, 74, 87, 93,
-  82, 74, 87, 90, 81, 86, 91, 83, 69, 80,
-  83, 87, 83, 80, 84, 100, 86, 92, 84, 80,
-  97, 98, 94, 91, 86, 85, 80, 89, 74, 79,
-  100, 83, 87, 95, 77, 87, 85, 78, 85, 90,
-  74, 83, 88, 70, 72, 84, 90, 77, 85, 83,
-  87, 61, 84, 102, 86, 89, 85, 86, 93, 81,
-  81, 73, 91, 81, 75, 78, 74, 97, 85, 92,
-  79, 95, 90, 84, 82, 72, 84, 82, 83, 84,
-  93, 84, 89, 86, 84, 91, 86, 87, 86, 84,
-  82, 83, 90, 85, 70, 90, 90, 95, 79, 82,
-  90, 78, 77, 86, 93, 81, 75, 79, 80, 84,
-  94, 79, 74, 77, 74, 74, 74, 79, 73, 77,
-  84, 88, 92, 86, 95, 82, 78, 101, 85, 82,
-  97, 72, 78, 90, 81, 65, 72, 85, 76, 93,
-  85, 86, 72, 89, 84, 85, 82, 83, 84, 90,
-  85, 88, 88, 92, 86, 74, 83, 67, 112, 80,
-  100, 89, 80, 72, 82, 79, 80, 72, 85, 82,
-  79, 83, 67, 78, 103, 82, 81, 90, 80, 65,
-  73, 94, 79, 86, 87, 102, 78, 72, 86, 81,
-  83, 87, 86, 72, 78, 86, 83, 80, 76, 83,
-  86, 84, 73, 72, 84, 77, 85, 78, 92, 88,
-  75, 94, 85, 77, 88, 87, 62, 83, 93, 75,
-  86, 90, 82, 87, 90, 89, 84, 80, 90, 78,
-  99, 83, 101, 90, 81, 82, 72, 79, 90, 78,
-  79, 80, 98, 82, 74, 87, 70, 83, 89, 89,
-  95, 105, 98, 80, 82, 81, 97, 83, 83, 80,
-  90, 82, 82, 91, 88, 87, 90, 93, 88, 87,
-  83, 90, 79, 80, 91, 76, 77, 96, 79, 83,
-  75, 100, 78, 76, 73, 70, 86, 79, 96, 93,
-  92, 74, 84, 87, 75, 76, 69, 85, 84, 104,
-  67, 93, 93, 86, 76, 83, 77, 86, 77, 78,
-  78, 86, 89, 90, 82, 73, 94, 94, 72, 79,
-  82, 88, 80, 85, 79, 74, 87, 90, 95, 73,
-  90, 78, 79, 79, 75, 71, 80, 89, 75, 88,
-  87, 74, 77, 80, 73, 77, 89, 81, 80, 79,
-  87, 73, 85, 86, 88, 87, 93, 74, 84, 76,
-  73, 78, 99, 97, 96, 85, 79, 71, 82, 78,
-  78, 86, 80, 80, 83, 86, 81, 78, 83, 76,
-  79, 84, 80, 86, 79, 75, 88, 90, 80, 83,
-  95, 85, 66, 87, 62, 79, 78, 73, 73, 93,
-  90, 90, 88, 88, 90, 106, 90, 97, 88, 88,
-  79, 82, 78, 64, 88, 79, 89, 96, 81, 81,
-  82, 60, 70, 90, 69, 74, 88, 68, 73, 88,
-  86, 82, 86, 86, 86, 75, 69, 108, 88, 86,
-  85, 84, 84, 80, 83, 69, 87, 82, 85, 71,
-  73, 85, 82, 91, 77, 95, 88, 81, 77, 67,
-  80, 81, 86, 79, 88, 84, 88, 89, 87, 89,
-  86, 91, 62, 89, 90, 83, 85, 88, 76, 91,
-  93, 95, 80, 77, 89, 88, 89, 80, 82, 83,
-  72, 87, 75, 77, 84, 84, 75, 78, 80, 95,
-  74, 70, 73, 89, 82, 91, 90, 88, 127, 80,
-  77, 89, 86, 83, 92, 65, 68, 89, 84, 69,
-  101, 98, 75, 78, 74, 72, 60, 103, 90, 85,
-  77, 86, 78, 86, 78, 97, 77, 83, 82, 67,
-  81, 50, 96, 67, 99, 95, 83, 65, 76, 63,
-  71, 77, 93, 82, 79, 85, 73, 92, 87, 90,
-  84, 83, 93, 114, 62, 96, 78, 72, 81, 105,
-  74, 72, 99, 92, 65, 88, 83, 63, 76, 83,
-  99, 79, 74, 78, 81, 78, 76, 63, 88, 77,
-  82, 70, 83, 87, 76, 99, 78, 76, 82, 98,
-  45, 104, 105, 76, 80, 81, 85, 100, 89, 78,
-  77, 71, 89, 95, 121, 72, 84, 107, 81, 73,
-  73, 72, 88, 81, 87, 79, 100, 109, 74, 81,
-  63, 77, 96, 85, 99, 85, 98, 84, 91, 74,
-  100, 83, 79, 80, 102, 90, 88, 106, 111, 73,
-  114, 92, 80, 60, 84, 104, 84, 83, 81, 79,
-  91, 78, 79, 79, 69, 88, 76, 75, 77, 78,
-  72, 77, 92, 99, 89, 78, 84, 92, 83, 76,
-  86, 95, 89, 97, 71, 91, 73, 97, 78, 75,
-  94, 109, 92, 67, 77, 86, 83, 69, 89, 87,
-  96, 108, 83, 76, 81, 90, 85, 92, 87, 81,
-  91, 74, 91, 71, 96, 81, 86, 80, 93, 81,
-  75, 101, 94, 84, 84, 83, 75, 77, 95, 104,
-  79, 91, 85, 75, 94, 66, 82, 79, 85, 88,
-  96, 84, 89, 71, 59, 78, 101, 106, 94, 87,
-  81, 71, 86, 75, 71, 76, 84, 79, 82, 96,
-  86, 75, 79, 73, 74, 75, 77, 83, 86, 75,
-  87, 86, 83, 88, 98, 95, 73, 89, 77, 87,
-  83, 74, 81, 103, 94, 93, 88, 84, 90, 108,
-  94, 86, 87, 87, 77, 85, 79, 80, 91, 84,
-  86, 96, 86, 76, 80, 67, 76, 95, 82, 70,
-  92, 69, 92, 98, 83, 77, 83, 83, 96, 91,
-  60, 113, 89, 87, 90, 79, 86, 74, 89, 66,
-  86, 82, 88, 90, 67, 88, 87, 91, 89, 103,
-  88, 87, 81, 77, 80, 82, 82, 75, 85, 86,
-  88, 87, 78, 88, 83, 91, 62, 89, 82, 93,
-  93, 81, 69, 93, 87, 88, 76, 70, 91, 90,
-  91, 86, 52, 85, 80, 86, 86, 83, 79, 84,
-  79, 84, 75, 81, 76, 75, 73, 92, 90, 78,
-  75, 78, 86, 71, 76, 90, 92, 85, 92, 58,
-  71, 92, 96, 78, 120, 94, 95, 88, 73, 77,
-  75, 100, 100, 89, 79, 94, 87, 77, 86, 99,
-  80, 81, 85, 74, 83, 70, 98, 75, 98, 91,
-  89, 72, 80, 73, 70, 82, 81, 82, 80, 67,
-  103, 86, 88, 91, 85, 90, 85, 111, 82, 92,
-  82, 77, 85, 84, 80, 66, 96, 83, 75, 87,
-  93, 80, 75, 87, 109, 76, 78, 83, 79, 87,
-  79, 75, 93, 76, 76, 69, 78, 94, 79, 96,
-  68, 80, 83, 87, 56, 93, 61, 79, 87, 82,
-  70, 95, 90, 80, 82, 66, 87, 105, 102, 75,
-  61, 101, 93, 74, 79, 77, 75, 80, 76, 88,
-  81, 87, 64, 79, 62, 71, 87, 81, 94, 76,
-  93, 81, 86, 76, 106, 88, 87, 73, 88, 90,
-  87, 106, 85, 76, 87, 91, 83, 70, 88, 84,
-  80, 82, 75, 95, 90, 78, 92, 85, 78, 85,
-  85, 79, 77, 96, 80, 77, 91, 77, 101, 98,
-  89, 87, 85, 79, 84, 93, 90, 83, 91, 67,
-  86, 101, 78, 81, 90, 96, 113, 66, 80, 88,
-  76, 70, 77, 86, 92, 103, 86, 78, 92, 100,
-  84, 90, 98, 82, 82, 72, 76, 81, 79, 91,
-  84, 79, 93, 98, 79, 99, 90, 83, 77, 86,
-  80, 77, 91, 104, 70, 76, 79, 95, 84, 73,
-  82, 80, 90, 92, 82, 81, 94, 87, 75, 72,
-  93, 66, 81, 93, 81, 81, 79, 92, 88, 83,
-  77, 82, 85, 73, 86, 86, 79, 89, 73, 69,
-  89, 91, 94, 63, 86, 82, 93, 67, 91, 92,
-  74, 69, 88, 74, 88, 92, 77, 63, 91, 97,
-  96, 83, 95, 88, 95, 96, 75, 80, 84, 80,
-  83, 86, 90, 76, 94, 93, 71, 82, 103, 52,
-  81, 80, 83, 100, 74, 71, 87, 65, 107, 62,
-  82, 73, 75, 85, 71, 81, 95, 93, 101, 96,
-  90, 142, 70, 69, 94, 89, 91, 78, 83, 98,
-  90, 83, 92, 75, 98, 86, 80, 71, 91, 87,
-  66, 70, 92, 92, 73, 87, 83, 81, 58, 134,
-  88, 105, 82, 88, 99, 97, 83, 80, 76, 89,
-  78, 55, 76, 96, 88, 83, 81, 87, 71, 69,
-  86, 76, 83, 83, 75, 93, 68, 80, 72, 85,
-  67, 87, 92, 88, 85, 96, 102, 65, 79, 80,
-  91, 86, 104, 80, 88, 76, 73, 90, 64, 74,
-  75, 66, 89, 69, 83, 54, 78, 92, 80, 80,
-  81, 94, 83, 90, 82, 82, 77, 71, 84, 84,
-  81, 72, 97, 77, 91, 80, 99, 63, 74, 80,
-  83, 98, 63, 76, 77, 71, 97, 80, 77, 87,
-  101, 88, 65, 70, 91, 80, 84, 94, 88, 117,
-  73, 92, 79, 79, 85, 90, 97, 84, 81, 94,
-  94, 71, 91, 80, 80, 69, 119, 87, 104, 65,
-  86, 90, 61, 84, 76, 82, 70, 102, 81, 95,
-  94, 100, 80, 94, 74, 83, 74, 78, 84, 46,
-  76, 82, 99, 81, 83, 94, 86, 81, 84, 77,
-  89, 67, 74, 90, 89, 76, 69, 83, 74, 88,
-  104, 85, 90, 96, 91, 74, 93, 84, 87, 91,
-  87, 74, 96, 92, 74, 97, 72, 82, 85, 75,
-  84, 75, 82, 62, 74, 87, 83, 84, 89, 86,
-  78, 74, 89, 87, 72, 81, 89, 81, 71, 77,
-  83, 75, 94, 83, 98, 78, 75, 86, 83, 92,
-  73, 82, 80, 73, 85, 76, 78, 80, 94, 89,
-  65, 77, 88, 76, 82, 91, 94, 103, 78, 94,
-  77, 84, 69, 99, 96, 84, 78, 83, 98, 85,
-  93, 90, 88, 81, 108, 90, 118, 77, 78, 95,
-  84, 88, 76, 92, 87, 84, 94, 87, 86, 87,
-  83, 91, 86, 80, 85, 81, 94, 59, 84, 81,
-  85, 88, 83, 72, 83, 65, 80, 78, 79, 78,
-  78, 91, 74, 83, 78, 81, 82, 73, 88, 89,
-  75, 91, 72, 71, 87, 84, 84, 77, 92, 82,
-  87, 83, 82, 88, 68, 69, 82, 74, 86, 88,
-  78, 72, 80, 89, 80, 82, 88, 88, 96, 91,
-  77, 81, 84, 79, 84, 79, 82, 77, 91, 87,
-  73, 88, 100, 55, 76, 84, 76, 100, 82, 91,
-  82, 78, 92, 71, 83, 84, 84, 97, 72, 81,
-  89, 87, 88, 93, 86, 105, 72, 80, 86, 88,
-  92, 75, 86, 91, 88, 77, 93, 79, 92, 86,
-  80, 70, 87, 89, 93, 79, 94, 90, 71, 86,
-  74, 83, 74, 143, 85, 93, 88, 88, 87, 96,
-  78, 86, 81, 86, 80, 68, 80, 89, 85, 83,
-  84, 94, 67, 74, 86, 60, 92, 61, 75, 89,
-  73, 75, 80, 86, 71, 86, 91, 87, 95, 92,
-  99, 71, 80, 77, 84, 109, 105, 83, 83, 94,
-  63, 84, 72, 74, 80, 90, 82, 69, 75, 75,
-  70, 83, 80, 88, 77, 95, 81, 81, 86, 78,
-  74, 76, 87, 75, 70, 80, 81, 85, 78, 82,
-  86, 68, 86, 86, 73, 91, 76, 88, 80, 79,
-  77, 83, 85, 90, 105, 95, 72, 82, 84, 81,
-  71, 86, 79, 77, 69, 100, 74, 71, 75, 79,
-  92, 89, 70, 87, 82, 89, 84, 78, 78, 65,
-  111, 90, 135, 85, 89, 89, 75, 82, 81, 84,
-  84, 97, 77, 79, 86, 102, 68, 91, 78, 91,
-  82, 76, 89, 64, 76, 81, 96, 85, 74, 101,
-  79, 81, 87, 68, 90, 44, 82, 81, 92, 74,
-  78, 85, 80, 88, 98, 81, 94, 92, 82, 75,
-  88, 84, 90, 103, 88, 82, 79, 103, 83, 83,
-  86, 76, 87, 97, 82, 72, 73, 86, 80, 82,
-  89, 82, 84, 82, 74, 80, 97, 75, 74, 90,
-  96, 79, 63, 92, 73, 80, 80, 91, 89, 84,
-  84, 96, 81, 83, 77, 84, 81, 75, 72, 76,
-  83, 80, 87, 91, 79, 89, 87, 84, 76, 90,
-  87, 80, 76, 86, 79, 79, 73, 76, 83, 84,
-  68, 81, 83, 101, 90, 89, 80, 78, 89, 90,
-  116, 93, 84, 94, 89, 95, 89, 90, 95, 75,
-  85, 82, 77, 95, 79, 95, 75, 84, 103, 81,
-  102, 77, 74, 90, 83, 97, 83, 73, 88, 75,
-  78, 76, 84, 69, 83, 83, 75, 78, 74, 75,
-  83, 71, 96, 83, 79, 89, 69, 74, 98, 85,
-  85, 73, 82, 78, 90, 93, 80, 94, 75, 68,
-  83, 75, 87, 87, 86, 72, 85, 84, 84, 84,
-  90, 87, 92, 85, 85, 83, 75, 87, 79, 88,
-  85, 85, 90, 88, 76, 88, 98, 71, 84, 83,
-  83, 89, 79, 82, 87, 79, 91, 77, 83, 84,
-  82, 104, 70, 85, 87, 82, 94, 99, 83, 98,
-  73, 78, 87, 90, 91, 75, 86, 90, 83, 69,
-  95, 82, 91, 88, 84, 74, 83, 89, 88, 80,
-  89, 88, 89, 91, 82, 86, 81, 126, 80, 89,
-  88, 83, 94, 91, 80, 87, 86, 93, 79, 83,
-  91, 84, 82, 92, 82, 91, 73, 83, 81, 65,
-  87, 53, 83, 86, 80, 75, 69, 82, 71, 80,
-  95, 85, 97, 89, 94, 74, 93, 83, 91, 89,
-  95, 77, 88, 94, 76, 92, 73, 71, 84, 86,
-  75, 78, 85, 77, 74, 83, 85, 92, 84, 92,
-  81, 81, 87, 83, 70, 87, 86, 80, 83, 78,
-  85, 88, 72, 86, 91, 77, 90, 87, 78, 86,
-  82, 76, 90, 81, 85, 83, 84, 95, 83, 89,
-  79, 91, 85, 81, 81, 93, 79, 88, 75, 91,
-  72, 83, 83, 77, 86, 84, 71, 78, 85, 81,
-  84, 86, 83, 78, 82, 87, 100, 84, 86, 88,
-  85, 95, 94, 89, 90, 88, 75, 84, 83, 85,
-  80, 91, 81, 94, 90, 84, 91, 90, 82, 77,
-  86, 86, 72, 94, 80, 87, 79, 74, 80, 49,
-  92, 81, 97, 79, 65, 83, 71, 87, 104, 83,
-  96, 85, 98, 70, 87, 86, 97, 81, 78, 78,
-  86, 95, 87, 92, 80, 69, 86, 84, 77, 78,
-  85, 90, 79, 88, 97, 83, 86, 86, 70, 84,
-  89, 78, 68, 94, 88, 82, 72, 82, 69, 85,
-  77, 84, 94, 86, 91, 95, 82, 87, 84, 76,
-  94, 90, 82, 81, 84, 85, 71, 85, 84, 96,
-  83, 85, 88, 95, 89, 94, 82, 86, 76, 80,
-  81, 76, 80, 84, 72, 80, 83, 84, 87, 93,
-  82, 80, 84, 88, 87, 80, 84, 88, 75, 98,
-  99, 90, 97, 82, 81, 84, 85, 82, 94, 94,
-  74, 85, 92, 84, 101, 91, 88, 82, 88, 62,
-  99, 91, 87, 85, 81, 76, 63, 78, 87, 90,
-  90, 74, 65, 86, 76, 72, 75, 90, 79, 97,
-  93, 94, 89, 107, 86, 88, 93, 104, 89, 85,
-  98, 96, 89, 87, 89, 86, 67, 90, 80, 71,
-  86, 90, 72, 77, 78, 99, 77, 81, 74, 92,
-  81, 89, 92, 82, 82, 78, 82, 75, 83, 86,
-  77, 67, 83, 88, 80, 102, 88, 79, 75, 90,
-  85, 91, 72, 77, 71, 80, 89, 72, 74, 94,
-  75, 82, 67, 78, 92, 82, 104, 94, 77, 89,
-  82, 85, 74, 88, 77, 90, 78, 70, 80, 95,
-  86, 86, 99, 92, 82, 84, 71, 76, 80, 84,
-  80, 86, 97, 86, 96, 94, 75, 95, 96, 80,
-  88, 87, 97, 93, 80, 90, 77, 83, 87, 98,
-  97, 81, 85, 68, 60, 74, 78, 81, 75, 81,
-  68, 71, 76, 76, 76, 93, 93, 81, 89, 91,
-  102, 107, 88, 97, 106, 100, 76, 95, 109, 83,
-  98, 79, 86, 98, 73, 81, 70, 70, 87, 95,
-  70, 77, 77, 93, 62, 73, 78, 69, 84, 96,
-  82, 81, 77, 72, 70, 78, 89, 88, 77, 70,
-  66, 80, 86, 90, 90, 77, 76, 78, 76, 89,
-  77, 64, 67, 85, 84, 79, 66, 100, 80, 87,
-  74, 80, 91, 94, 106, 91, 81, 84, 73, 94,
-  65, 108, 70, 84, 89, 71, 74, 74, 74, 85,
-  91, 84, 89, 86, 74, 74, 79, 85, 83, 91,
-  79, 78, 76, 104, 74, 92, 83, 78, 79, 81,
-  81, 84, 95, 97, 86, 97, 79, 87, 84, 91,
-  81, 79, 60, 79, 82, 88, 91, 69, 65, 93,
-  79, 77, 76, 95, 87, 95, 84, 86, 78, 106,
-  90, 90, 82, 91, 88, 90, 100, 80, 100, 78,
-  88, 87, 70, 91, 77, 68, 83, 84, 79, 79,
-  76, 82, 72, 80, 80, 79, 74, 96, 97, 98,
-  81, 79, 78, 75, 87, 86, 84, 59, 80, 91,
-  87, 97, 88, 83, 97, 91, 87, 90, 76, 74,
-  74, 91, 91, 83, 72, 92, 77, 88, 64, 85,
-  88, 91, 101, 99, 79, 85, 85, 86, 74, 88,
-  80, 91, 88, 68, 80, 65, 86, 84, 94, 94,
-  85, 90, 76, 80, 81, 82, 85, 94, 84, 97,
-  74, 91, 82, 93, 80, 81, 82, 92, 98, 92,
-  78, 91, 85, 63, 78, 99, 102, 82, 77, 66,
-  71, 82, 80, 94, 97, 77, 69, 113, 83, 94,
-  86, 91, 93, 84, 94, 106, 89, 100, 90, 97,
-  114, 98, 91, 82, 98, 101, 78, 82, 74, 94,
-  70, 86, 81, 82, 89, 98, 71, 87, 83, 105,
-  78, 85, 61, 84, 82, 98, 83, 88, 84, 66,
-  78, 81, 85, 75, 73, 61, 80, 77, 92, 97,
-  86, 68, 88, 80, 86, 82, 78, 68, 67, 70,
-  81, 71, 72, 107, 85, 81, 71, 79, 94, 89,
-  86, 93, 74, 93, 71, 86, 64, 77, 78, 72,
-  87, 71, 70, 86, 75, 80, 97, 87, 80, 95,
-  67, 81, 78, 95, 79, 87, 82, 79, 88, 89,
-  76, 77, 89, 77, 102, 75, 84, 87, 85, 85,
-  71, 86, 80, 117, 126, 75, 71, 55, 64, 79,
-  70, 85, 75, 78, 78, 98, 79, 100, 78, 103,
-  100, 69, 81, 94, 108, 112, 82, 107, 119, 92,
-  75, 87, 100, 89, 92, 69, 70, 90, 72, 84,
-  69, 79, 99, 107, 70, 76, 77, 80, 58, 84,
-  68, 58, 73, 112, 70, 73, 69, 57, 69, 86,
-  94, 71, 71, 61, 73, 65, 95, 91, 91, 66,
-  63, 68, 81, 80, 89, 48, 57, 80, 87, 72,
-  66, 123, 90, 82, 82, 85, 94, 98, 87, 92,
-  78, 80, 59, 95, 51, 95, 74, 67, 91, 62,
-  67, 75, 64, 80, 94, 77, 85, 95, 64, 73,
-  81, 94, 81, 96, 69, 69, 64, 95, 68, 81,
-  83, 71, 89, 71, 63, 81, 105, 84, 84, 100,
-  87, 93, 101, 89, 75, 67, 68, 82, 76, 95,
-  88, 70, 66, 111, 85, 96, 87, 93, 89, 93,
-  80, 93, 91, 97, 95, 98, 103, 80, 91, 81,
-  97, 78, 88, 70, 74, 89, 72, 86, 78, 80,
-  91, 92, 72, 82, 79, 71, 70, 83, 67, 78,
-  73, 101, 87, 82, 83, 70, 77, 82, 86, 81,
-  78, 57, 79, 78, 86, 98, 90, 75, 74, 83,
-  85, 83, 85, 64, 74, 94, 83, 76, 71, 106,
-  93, 89, 66, 84, 86, 96, 87, 91, 79, 86,
-  74, 84, 65, 77, 82, 81, 88, 72, 72, 72,
-  73, 80, 96, 88, 86, 95, 73, 82, 81, 92,
-  86, 95, 88, 87, 76, 87, 83, 83, 86, 78,
-  87, 80, 86, 85, 86, 84, 88, 60, 72, 91,
-  82, 86, 78, 72, 74, 84, 84, 84, 93, 71,
-  57, 122, 80, 81, 83, 87, 78, 83, 90, 107,
-  77, 87, 99, 85, 90, 83, 98, 82, 87, 95,
-  72, 102, 95, 87, 78, 90, 80, 72, 73, 81,
-  68, 79, 94, 104, 102, 92, 69, 81, 81, 93,
-  96, 102, 96, 84, 87, 88, 77, 91, 92, 80,
-  81, 93, 101, 91, 77, 87, 98, 85, 91, 77,
-  67, 75, 89, 80, 79, 69, 68, 85, 83, 91,
-  75, 85, 95, 84, 87, 92, 68, 115, 74, 72,
-  73, 65, 73, 69, 79, 85, 63, 113, 99, 80,
-  98, 96, 69, 86, 63, 84, 70, 89, 86, 83,
-  94, 89, 79, 88, 93, 84, 83, 74, 99, 77,
-  92, 87, 72, 82, 70, 82, 81, 110, 97, 79,
-  66, 58, 80, 84, 76, 77, 80, 74, 59, 135,
-  85, 87, 81, 97, 78, 68, 87, 107, 89, 87,
-  98, 93, 109, 85, 97, 80, 92, 89, 74, 84,
-  82, 82, 67, 83, 79, 65, 80, 91, 68, 77,
-  93, 88, 87, 88, 71, 68, 78, 98, 81, 85,
-  81, 71, 82, 83, 78, 96, 82, 81, 71, 80,
-  98, 87, 83, 77, 75, 74, 84, 80, 74, 57,
-  81, 93, 73, 68, 63, 88, 88, 87, 77, 99,
-  88, 88, 91, 93, 72, 112, 65, 74, 55, 66,
-  73, 67, 84, 78, 61, 91, 77, 79, 110, 88,
-  72, 87, 60, 84, 71, 90, 81, 90, 97, 86,
-  73, 86, 80, 84, 83, 68, 93, 65, 86, 83,
-  80, 77, 94, 95, 87, 88, 83, 82, 72, 71,
-  68, 85, 84, 84, 87, 73, 57, 119, 89, 78,
-  85, 86, 74, 98, 94, 99, 83, 82, 102, 83,
-  80, 75, 102, 77, 89, 84, 72, 87, 84, 83,
-  66, 93, 77, 71, 79, 77, 70, 67, 88, 77,
-  96, 88, 71, 91, 73, 96, 96, 77, 91, 85,
-  84, 84, 81, 100, 94, 73, 82, 92, 91, 90,
-  83, 91, 71, 85, 87, 80, 74, 70, 88, 104,
-  80, 70, 71, 81, 88, 92, 72, 96, 79, 89,
-  90, 84, 71, 105, 73, 71, 71, 60, 75, 77,
-  81, 87, 63, 93, 94, 79, 103, 91, 75, 84,
-  70, 83, 71, 90, 87, 93, 110, 98, 94, 86,
-  93, 89, 85, 75, 91, 79, 91, 83, 73, 82,
-  101, 78, 92, 80, 82, 94, 96, 88, 87, 85,
-  72, 89, 81, 94, 81, 86, 87, 71, 68, 76,
-  76, 89, 81, 96, 79, 89, 73, 72, 91, 104,
-  80, 83, 81, 88, 88, 93, 95, 79, 73, 89,
-  89, 85, 87, 76, 87, 82, 82, 91, 75, 85,
-  78, 103, 76, 76, 86, 83, 74, 86, 80, 83,
-  77, 84, 73, 82, 84, 98, 87, 72, 84, 80,
-  80, 80, 77, 80, 82, 88, 80, 82, 88, 90,
-  67, 85, 80, 83, 84, 83, 79, 87, 94, 87,
-  92, 83, 80, 72, 86, 87, 87, 67, 92, 77,
-  72, 83, 77, 89, 85, 87, 87, 84, 80, 79,
-  84, 90, 86, 81, 93, 76, 96, 85, 91, 83,
-  75, 87, 86, 84, 83, 68, 88, 94, 84, 89,
-  86, 81, 70, 89, 104, 95, 89, 81, 66, 87,
-  63, 80, 92, 92, 85, 77, 53, 91, 78, 70,
-  87, 101, 85, 105, 74, 69, 89, 101, 72, 82,
-  80, 80, 92, 91, 92, 77, 74, 82, 89, 78,
-  81, 73, 89, 75, 78, 81, 94, 79, 76, 91,
-  82, 76, 89, 93, 89, 84, 74, 78, 70, 87,
-  75, 72, 97, 85, 92, 78, 74, 82, 92, 81,
-  83, 79, 89, 90, 68, 80, 90, 99, 69, 87,
-  71, 83, 77, 84, 79, 80, 98, 91, 101, 76,
-  72, 78, 89, 86, 88, 59, 82, 85, 66, 82,
-  80, 84, 88, 85, 86, 88, 87, 80, 79, 91,
-  94, 77, 84, 73, 86, 78, 78, 90, 71, 86,
-  81, 98, 82, 68, 86, 97, 102, 89, 91, 79,
-  85, 81, 90, 88, 87, 89, 70, 95, 86, 82,
-  79, 85, 87, 73, 74, 85, 84, 91, 79, 91,
-  91, 84, 79, 73, 85, 91, 76, 80, 82, 85,
-  86, 82, 92, 82, 87, 89, 83, 77, 80, 76,
-  89, 80, 80, 84, 76, 86, 78, 91, 75, 75,
-  87, 98, 71, 92, 76, 80, 76, 82, 81, 85,
-  83, 93, 92, 74, 79, 83, 90, 85, 85, 80,
-  83, 83, 79, 92, 86, 88, 69, 86, 76, 82,
-  83, 85, 77, 89, 90, 84, 91, 77, 79, 75,
-  77, 84, 85, 69, 80, 77, 74, 79, 76, 85,
-  88, 88, 92, 84, 81, 75, 79, 88, 87, 72,
-  79, 83, 84, 84, 92, 83, 74, 88, 82, 78,
-  88, 67, 85, 89, 81, 82, 81, 84, 74, 101,
-  112, 94, 86, 79, 70, 84, 81, 73, 87, 99,
-  82, 88, 47, 80, 81, 87, 80, 96, 77, 92,
-  70, 70, 98, 106, 81, 75, 77, 82, 77, 94,
-  90, 78, 73, 90, 87, 76, 80, 73, 89, 80,
-  78, 101, 83, 87, 78, 83, 87, 74, 84, 73,
-  83, 93, 73, 88, 79, 80, 78, 81, 83, 91,
-  92, 78, 87, 88, 87, 68, 83, 73, 83, 95,
-  64, 71, 93, 81, 67, 79, 76, 86, 89, 81,
-  77, 77, 88, 90, 106, 91, 69, 76, 90, 85,
-  90, 60, 91, 81, 66, 81, 90, 87, 90, 86,
-  83, 96, 76, 77, 86, 88, 99, 78, 90, 75,
-  100, 75, 87, 95, 83, 83, 83, 103, 81, 80,
-  85, 95, 73, 103, 83, 100, 60, 88, 124, 111,
-  93, 78, 63, 80, 64, 62, 96, 121, 82, 96,
-  35, 98, 78, 63, 82, 114, 86, 111, 76, 72,
-  97, 84, 79, 79, 85, 77, 86, 88, 84, 79,
-  65, 85, 77, 70, 79, 67, 85, 72, 77, 82,
-  103, 86, 74, 63, 100, 73, 82, 74, 99, 88,
-  62, 87, 76, 75, 72, 70, 83, 66, 106, 80,
-  83, 79, 80, 68, 93, 76, 97, 109, 54, 87,
-  90, 95, 74, 82, 72, 81, 80, 82, 77, 66,
-  97, 92, 149, 78, 64, 87, 100, 83, 96, 47,
-  83, 90, 56, 76, 94, 79, 93, 77, 88, 102,
-  91, 82, 83, 84, 117, 74, 78, 67, 84, 71,
-  81, 94, 79, 80, 88, 131, 82, 80, 84, 96,
-  85, 87, 91, 81, 82, 79, 101, 97, 87, 84,
-  72, 89, 79, 79, 85, 95, 85, 85, 59, 89,
-  80, 93, 85, 89, 87, 83, 79, 72, 86, 77,
-  76, 76, 75, 84, 92, 84, 90, 82, 78, 85,
-  82, 72, 81, 75, 88, 75, 77, 81, 78, 84,
-  75, 87, 78, 74, 83, 85, 78, 95, 72, 81,
-  79, 86, 86, 86, 88, 89, 98, 80, 83, 91,
-  92, 74, 94, 75, 89, 86, 68, 105, 100, 80,
-  69, 80, 70, 81, 91, 84, 78, 90, 90, 84,
-  93, 84, 74, 76, 82, 85, 86, 63, 78, 80,
-  74, 75, 86, 84, 88, 85, 92, 94, 80, 71,
-  84, 88, 94, 73, 86, 86, 87, 77, 90, 86,
-  73, 86, 75, 91, 83, 78, 84, 88, 87, 89,
-  87, 86, 80, 96, 105, 80, 87, 82, 72, 95,
-  86, 74, 94, 107, 88, 78, 63, 81, 87, 85,
-  81, 93, 82, 88, 73, 74, 90, 93, 89, 77,
-  75, 81, 73, 101, 85, 84, 92, 90, 82, 82,
-  77, 79, 91, 77, 77, 96, 78, 88, 75, 86,
-  85, 74, 83, 89, 73, 88, 82, 79, 75, 75,
-  86, 75, 82, 92, 97, 76, 80, 93, 99, 82,
-  77, 80, 80, 88, 76, 78, 79, 75, 73, 78,
-  71, 86, 89, 87, 75, 81, 95, 91, 95, 101,
-  68, 79, 85, 84, 89, 69, 90, 80, 73, 87,
-  80, 90, 87, 87, 84, 89, 87, 71, 90, 81,
-  92, 81, 85, 84, 87, 84, 92, 87, 79, 84,
-  82, 95, 77, 78, 81, 90, 78, 95, 100, 99,
-  73, 97, 106, 93, 96, 81, 65, 93, 71, 81,
-  101, 111, 89, 85, 51, 91, 81, 71, 90, 100,
-  83, 99, 74, 76, 88, 75, 82, 76, 73, 82,
-  77, 88, 80, 81, 74, 92, 66, 77, 84, 77,
-  87, 79, 76, 92, 87, 83, 73, 86, 87, 72,
-  84, 82, 84, 83, 72, 71, 73, 70, 81, 64,
-  85, 81, 103, 73, 84, 99, 89, 78, 80, 84,
-  87, 95, 64, 95, 72, 86, 73, 79, 70, 84,
-  80, 82, 82, 75, 98, 91, 110, 103, 64, 79,
-  99, 82, 87, 60, 84, 88, 73, 82, 78, 83,
-  82, 83, 87, 94, 86, 77, 87, 78, 102, 80,
-  81, 76, 87, 79, 84, 84, 83, 78, 80, 119,
-  75, 74, 77, 88, 88, 90, 91, 87, 87, 78,
-  98, 92, 89, 85, 75, 96, 81, 94, 92, 101,
-  90, 76, 75, 86, 84, 89, 84, 85, 85, 80,
-  77, 77, 87, 72, 88, 77, 77, 88, 86, 86,
-  88, 86, 78, 85, 78, 83, 92, 75, 87, 80,
-  75, 86, 75, 86, 74, 92, 77, 74, 77, 79,
-  69, 91, 78, 77, 80, 82, 91, 81, 85, 86,
-  92, 81, 83, 90, 90, 80, 88, 79, 86, 83,
-  78, 102, 88, 77, 73, 81, 68, 75, 92, 78,
-  86, 92, 94, 82, 88, 95, 74, 80, 88, 86,
-  88, 73, 85, 76, 74, 86, 81, 87, 81, 82,
-  88, 86, 89, 70, 87, 82, 90, 76, 85, 88,
-  88, 86, 95, 84, 81, 88, 79, 88, 79, 75,
-  80, 90, 90, 88, 95, 76, 90, 80, 82, 96,
-  92, 76, 82, 88, 88, 92, 82, 73, 100, 87,
-  90, 81, 64, 79, 86, 91, 89, 89, 75, 85,
-  92, 68, 72, 104, 86, 83, 104, 91, 80, 85,
-  78, 100, 77, 79, 98, 85, 75, 88, 88, 82,
-  86, 82, 75, 83, 79, 100, 93, 75, 85, 66,
-  80, 82, 81, 89, 85, 45, 74, 73, 83, 76,
-  80, 73, 93, 80, 95, 83, 97, 73, 76, 92,
-  74, 100, 85, 90, 75, 91, 79, 71, 86, 77,
-  92, 112, 78, 69, 68, 86, 92, 80, 85, 81,
-  77, 82, 72, 82, 87, 76, 98, 90, 76, 85,
-  78, 91, 83, 80, 93, 90, 67, 88, 71, 84,
-  66, 80, 78, 83, 93, 97, 83, 91, 95, 91,
-  81, 80, 85, 82, 74, 98, 97, 77, 93, 81,
-  73, 75, 80, 80, 73, 76, 75, 67, 75, 82,
-  72, 88, 84, 77, 96, 82, 92, 89, 130, 68,
-  81, 87, 80, 96, 143, 87, 99, 83, 70, 68,
-  110, 78, 113, 81, 80, 98, 77, 81, 85, 77,
-  62, 76, 85, 74, 97, 94, 81, 62, 88, 83,
-  87, 85, 89, 64, 64, 57, 58, 102, 73, 72,
-  115, 89, 84, 79, 82, 85, 84, 119, 79, 68,
-  73, 73, 80, 89, 92, 71, 101, 98, 83, 106,
-  82, 99, 89, 80, 111, 72, 88, 72, 77, 85,
-  73, 72, 101, 77, 88, 77, 86, 93, 84, 58,
-  90, 86, 67, 88, 65, 96, 74, 93, 81, 84,
-  78, 67, 92, 80, 76, 74, 74, 80, 77, 74,
-  89, 92, 74, 83, 88, 79, 107, 79, 75, 80,
-  86, 83, 76, 92, 80, 65, 72, 82, 93, 77,
-  76, 72, 91, 79, 95, 85, 106, 90, 107, 81,
-  84, 96, 82, 82, 90, 96, 79, 76, 103, 81,
-  97, 92, 70, 86, 85, 96, 73, 80, 75, 78,
-  79, 77, 73, 74, 73, 81, 99, 92, 78, 79,
-  76, 84, 70, 71, 69, 112, 77, 92, 66, 84,
-  86, 68, 74, 98, 97, 101, 85, 67, 73, 83,
-  95, 88, 109, 94, 98, 99, 89, 107, 90, 99,
-  104, 87, 94, 82, 79, 82, 77, 93, 87, 76,
-  93, 80, 88, 83, 102, 102, 83, 56, 104, 78,
-  60, 88, 92, 100, 90, 100, 96, 96, 82, 70,
-  90, 83, 74, 75, 76, 70, 84, 75, 79, 74,
-  91, 74, 77, 89, 89, 71, 94, 86, 79, 88,
-  95, 72, 95, 98, 95, 75, 87, 86, 85, 92,
-  71, 88, 70, 77, 85, 71, 80, 89, 92, 87,
-  71, 82, 75, 81, 78, 93, 69, 85, 81, 91,
-  97, 79, 80, 92, 78, 87, 84, 95, 78, 104,
-  82, 74, 89, 88, 78, 88, 85, 87, 77, 73,
-  83, 104, 79, 90, 84, 73, 76, 90, 80, 76,
-  96, 79, 85, 78, 67, 102, 94, 96, 79, 76,
-  91, 67, 82, 78, 90, 108, 76, 69, 79, 87,
-  74, 94, 73, 97, 79, 81, 78, 101, 87, 78,
-  83, 89, 87, 90, 72, 101, 80, 81, 99, 84,
-  79, 86, 81, 90, 84, 78, 73, 92, 72, 94,
-  85, 84, 96, 88, 79, 85, 61, 77, 93, 65,
-  85, 86, 79, 76, 84, 78, 72, 91, 87, 74,
-  82, 92, 100, 76, 69, 72, 68, 88, 79, 95,
-  90, 88, 105, 60, 78, 99, 96, 88, 112, 76,
-  88, 76, 70, 68, 74, 60, 110, 84, 89, 101,
-  72, 83, 83, 86, 70, 89, 81, 95, 93, 80,
-  84, 75, 71, 78, 91, 95, 91, 74, 65, 66,
-  65, 86, 73, 71, 100, 70, 88, 88, 93, 78,
-  71, 83, 88, 72, 90, 83, 83, 72, 82, 69,
-  80, 79, 87, 111, 87, 81, 64, 92, 98, 81,
-  90, 82, 83, 80, 66, 94, 88, 77, 93, 75,
-  70, 88, 90, 84, 84, 83, 91, 84, 65, 77,
-  58, 79, 77, 79, 76, 80, 95, 84, 82, 85,
-  90, 97, 81, 81, 70, 80, 91, 71, 81, 76,
-  87, 85, 80, 73, 78, 76, 70, 77, 79, 74,
-  80, 88, 80, 78, 77, 85, 79, 80, 85, 91,
-  81, 69, 86, 83, 73, 91, 88, 83, 82, 83,
-  88, 75, 106, 61, 86, 79, 78, 91, 72, 76,
-  92, 82, 59, 88, 79, 82, 84, 91, 83, 80,
-  78, 73, 89, 82, 90, 88, 76, 70, 69, 92,
-  76, 94, 82, 79, 96, 85, 82, 86, 79, 89,
-  98, 62, 85, 75, 85, 75, 86, 88, 82, 83,
-  77, 101, 78, 92, 85, 87, 98, 78, 83, 73,
-  74, 83, 76, 81, 95, 77, 95, 92, 71, 91,
-  95, 71, 88, 75, 82, 86, 79, 96, 81, 81,
-  77, 92, 80, 69, 90, 84, 81, 83, 79, 81,
-  83, 75, 95, 87, 84, 86, 74, 84, 91, 82,
-  89, 85, 85, 73, 87, 82, 91, 96, 80, 91,
-  96, 82, 97, 96, 75, 82, 82, 74, 72, 92,
-  85, 79, 90, 97, 87, 87, 87, 74, 79, 82,
-  88, 99, 65, 89, 95, 81, 87, 85, 77, 78,
-  84, 92, 79, 91, 80, 82, 88, 100, 84, 90,
-  84, 92, 81, 99, 99, 112, 78, 82, 80, 90,
-  78, 101, 80, 72, 98, 82, 93, 83, 81, 86,
-  89, 99, 82, 75, 95, 78, 90, 81, 90, 89,
-  71, 81, 101, 88, 87, 90, 66, 87, 90, 82,
-  91, 97, 84, 84, 82, 82, 85, 89, 65, 102,
-  81, 81, 100, 86, 88, 88, 90, 89, 88, 83,
-  77, 82, 64, 87, 84, 78, 92, 92, 79, 79,
-  83, 81, 96, 68, 72, 90, 85, 78, 88, 83,
-  80, 89, 86, 76, 85, 98, 98, 82, 77, 77,
-  80, 90, 70, 91, 83, 80, 82, 78, 78, 89,
-  100, 89, 89, 73, 80, 82, 73, 87, 70, 71,
-  76, 81, 99, 90, 76, 91, 79, 89, 93, 96,
-  73, 104, 81, 82, 80, 93, 80, 83, 79, 94,
-  80, 91, 85, 99, 76, 76, 75, 75, 83, 77,
-  79, 74, 90, 85, 79, 69, 81, 88, 91, 98,
-  80, 72, 86, 77, 87, 77, 98, 99, 78, 84,
-  80, 93, 83, 88, 79, 90, 90, 86, 79, 96,
-  78, 83, 90, 76, 77, 89, 73, 106, 87, 85,
-  99, 84, 80, 70, 69, 82, 86, 79, 81, 85,
-  73, 89, 86, 83, 97, 96, 88, 89, 90, 78,
-  93, 70, 77, 83, 79, 82, 82, 79, 81, 82,
-  78, 70, 84, 86, 94, 82, 67, 82, 88, 90,
-  73, 89, 75, 77, 78, 70, 84, 87, 84, 87,
-  93, 87, 83, 83, 83, 76, 84, 66, 74, 75,
-  96, 88, 77, 79, 86, 83, 81, 90, 75, 96,
-  82, 89, 86, 91, 75, 84, 84, 86, 91, 100,
-  90, 84, 79, 89, 76, 87, 88, 72, 89, 77,
-  87, 85, 78, 71, 95, 81, 90, 90, 82, 83,
-  84, 85, 82, 77, 94, 90, 74, 83, 78, 94,
-  95, 83, 76, 81, 83, 84, 80, 90, 82, 82,
-  89, 87, 80, 89, 80, 98, 87, 84, 96, 86,
-  77, 80, 88, 82, 87, 86, 81, 82, 74, 89,
-  85, 84, 90, 87, 69, 79, 76, 88, 81, 94,
-  87, 97, 112, 83, 79, 118, 92, 68, 75, 100,
-  83, 86, 85, 74, 105, 88, 92, 75, 83, 75,
-  80, 85, 92, 89, 85, 80, 104, 72, 76, 89,
-  92, 73, 109, 83, 75, 80, 74, 76, 70, 93,
-  104, 87, 86, 68, 81, 74, 88, 102, 66, 105,
-  86, 83, 85, 80, 75, 79, 82, 67, 89, 93,
-  79, 91, 85, 73, 88, 101, 98, 95, 87, 79,
-  89, 78, 79, 82, 89, 67, 72, 85, 77, 68,
-  99, 98, 68, 82, 89, 83, 81, 80, 88, 92,
-  70, 79, 94, 91, 82, 79, 87, 93, 92, 75,
-  78, 90, 88, 89, 88, 87, 82, 94, 84, 78,
-  85, 86, 82, 100, 76, 75, 78, 88, 85, 99,
-  79, 92, 58, 80, 88, 76, 87, 73, 76, 90,
-  124, 77, 87, 117, 85, 97, 77, 80, 79, 74,
-  85, 66, 90, 81, 76, 79, 80, 71, 80, 82,
-  104, 71, 83, 88, 82, 76, 77, 88, 85, 55,
-  89, 74, 52, 88, 103, 66, 72, 73, 93, 81,
-  76, 60, 93, 84, 86, 118, 61, 75, 95, 75,
-  87, 85, 74, 92, 78, 68, 73, 114, 82, 85,
-  89, 60, 76, 81, 102, 89, 84, 77, 78, 88,
-  79, 97, 87, 62, 71, 94, 77, 57, 87, 119,
-  62, 68, 93, 80, 69, 73, 84, 96, 68, 76,
-  90, 119, 79, 89, 102, 93, 79, 83, 66, 91,
-  89, 89, 98, 68, 70, 92, 100, 63, 73, 81,
-  73, 96, 86, 70, 63, 82, 74, 84, 83, 113,
-  74, 89, 101, 83, 83, 88, 87, 99, 100, 85,
-  79, 116, 85, 106, 78, 95, 80, 88, 85, 79,
-  74, 86, 91, 75, 79, 79, 87, 86, 87, 74,
-  97, 92, 100, 85, 88, 84, 86, 71, 74, 82,
-  75, 84, 103, 78, 73, 95, 96, 79, 80, 70,
-  75, 83, 88, 88, 79, 62, 83, 77, 84, 79,
-  79, 82, 86, 69, 89, 89, 78, 87, 89, 77,
-  88, 109, 91, 100, 89, 74, 80, 91, 97, 81,
-  91, 70, 68, 84, 76, 73, 91, 98, 77, 80,
-  90, 83, 88, 81, 82, 84, 75, 83, 93, 89,
-  79, 95, 89, 93, 94, 77, 81, 86, 86, 91,
-  90, 90, 83, 98, 95, 78, 77, 90, 85, 90,
-  85, 77, 86, 87, 83, 92, 79, 95, 77, 78,
-  70, 77, 78, 82, 78, 82, 116, 86, 94, 128,
-  83, 113, 71, 78, 70, 65, 91, 73, 92, 89,
-  92, 85, 77, 73, 83, 82, 94, 80, 84, 83,
-  87, 84, 86, 76, 83, 75, 75, 72, 79, 79,
-  85, 72, 81, 98, 92, 82, 81, 58, 91, 83,
-  83, 110, 67, 80, 84, 83, 81, 85, 87, 87,
-  84, 69, 71, 92, 85, 80, 96, 62, 70, 99,
-  80, 85, 84, 75, 83, 82, 67, 90, 81, 81,
-  76, 77, 74, 84, 88, 115, 69, 98, 94, 81,
-  75, 68, 90, 90, 71, 79, 89, 107, 81, 78,
-  91, 97, 78, 60, 73, 86, 79, 78, 90, 76,
-  69, 83, 93, 77, 83, 84, 79, 95, 68, 73,
-  71, 80, 78, 87, 80, 98, 68, 74, 79, 67,
-  84, 74, 72, 73, 119, 86, 105, 132, 79, 122,
-  67, 54, 64, 50, 86, 66, 84, 79, 73, 82,
-  80, 61, 77, 75, 107, 75, 78, 92, 64, 86,
-  77, 85, 86, 73, 128, 64, 82, 107, 90, 62,
-  78, 56, 88, 81, 84, 50, 116, 90, 75, 141,
-  70, 118, 83, 86, 96, 82, 82, 87, 93, 76,
-  49, 147, 97, 75, 82, 42, 80, 104, 71, 72,
-  83, 72, 79, 82, 52, 121, 79, 84, 59, 66,
-  74, 97, 73, 147, 68, 69, 81, 67, 78, 58,
-  81, 101, 69, 68, 89, 139, 70, 86, 118, 96,
-  54, 48, 58, 95, 64, 75, 92, 63, 61, 73,
-  100, 80, 75, 84, 85, 96, 75, 68, 49, 77,
-  67, 69, 86, 115, 70, 82, 91, 80, 79, 90,
-  81, 93, 105, 87, 89, 119, 78, 75, 73, 81,
-  72, 76, 89, 81, 81, 72, 85, 79, 78, 78,
-  87, 84, 86, 85, 82, 98, 93, 81, 82, 80,
-  85, 78, 101, 72, 81, 73, 88, 81, 83, 99,
-  86, 79, 82, 62, 81, 69, 85, 95, 77, 92,
-  81, 86, 82, 88, 82, 77, 90, 67, 78, 84,
-  79, 87, 89, 71, 84, 108, 88, 91, 86, 77,
-  74, 77, 69, 80, 82, 80, 70, 76, 75, 91,
-  81, 95, 66, 95, 98, 74, 82, 70, 85, 83,
-  77, 82, 89, 96, 82, 89, 89, 96, 75, 61,
-  78, 85, 71, 83, 81, 83, 73, 86, 68, 67,
-  81, 86, 79, 90, 90, 73, 83, 85, 84, 89,
-  78, 94, 78, 75, 81, 94, 78, 105, 96, 77,
-  82, 88, 89, 86, 94, 95, 78, 89, 66, 92,
-  88, 80, 87, 90, 101, 93, 84, 90, 91, 82,
-  87, 91, 89, 83, 96, 78, 81, 89, 88, 83,
-  80, 89, 91, 77, 71, 85, 85, 105, 78, 87,
-  91, 85, 77, 79, 91, 92, 76, 89, 75, 89,
-  86, 83, 83, 78, 78, 79, 93, 83, 78, 85,
-  85, 74, 95, 83, 77, 78, 88, 79, 79, 75,
-  85, 75, 83, 71, 73, 77, 95, 90, 101, 89,
-  77, 101, 90, 92, 84, 83, 108, 77, 72, 78,
-  94, 81, 93, 87, 82, 89, 92, 71, 94, 86,
-  71, 93, 97, 90, 78, 84, 91, 86, 85, 89,
-  88, 87, 84, 79, 87, 94, 87, 84, 77, 87,
-  63, 80, 96, 103, 79, 99, 92, 79, 94, 86,
-  82, 84, 84, 78, 82, 82, 62, 102, 91, 84,
-  77, 72, 92, 104, 87, 89, 99, 86, 90, 74,
-  75, 95, 100, 73, 80, 85, 76, 84, 78, 78,
-  79, 66, 79, 74, 82, 105, 76, 84, 84, 89,
-  78, 67, 101, 96, 73, 73, 80, 78, 76, 85,
-  88, 65, 77, 70, 88, 77, 84, 87, 85, 74,
-  79, 64, 85, 76, 90, 78, 70, 81, 75, 72,
-  88, 69, 74, 90, 78, 92, 97, 75, 75, 120,
-  97, 98, 71, 82, 107, 73, 74, 70, 81, 81,
-  95, 74, 72, 89, 79, 67, 92, 82, 75, 98,
-  92, 79, 80, 92, 84, 76, 82, 81, 74, 80,
-  99, 78, 77, 99, 80, 78, 79, 96, 77, 85,
-  100, 86, 78, 99, 97, 81, 77, 90, 90, 88,
-  93, 84, 81, 88, 71, 96, 89, 88, 73, 95,
-  101, 91, 80, 92, 92, 86, 83, 78, 92, 93,
-  97, 85, 97, 84, 88, 80, 87, 86, 94, 76,
-  90, 84, 82, 100, 75, 77, 94, 85, 71, 87,
-  85, 91, 80, 82, 79, 85, 86, 80, 83, 80,
-  81, 79, 90, 82, 70, 87, 90, 83, 85, 87,
-  80, 82, 84, 81, 80, 87, 82, 68, 82, 75,
-  75, 82, 94, 93, 88, 81, 81, 95, 82, 90,
-  90, 82, 92, 81, 75, 80, 81, 86, 88, 83,
-  82, 89, 91, 73, 97, 83, 74, 88, 93, 90,
-  77, 89, 89, 96, 87, 90, 92, 88, 81, 81,
-  86, 95, 88, 84, 81, 87, 99, 84, 89, 85,
-  84, 87, 81, 97, 74, 97, 78, 83, 90, 90,
-  86, 85, 88, 78, 77, 78, 78, 86, 85, 77,
-  94, 96, 84, 92, 97, 84, 82, 72, 87, 84,
-  82, 99, 86, 63, 80, 81, 81, 79, 83, 85,
-  89, 75, 98, 75, 79, 83, 83, 83, 91, 76,
-  88, 86, 85, 82, 82, 89, 81, 82, 90, 58,
-  76, 83, 87, 85, 90, 89, 81, 79, 80, 98,
-  83, 69, 86, 78, 85, 80, 84, 91, 94, 91,
-  92, 81, 58, 87, 79, 75, 87, 80, 88, 84,
-  86, 86, 82, 81, 87, 76, 91, 90, 87, 84,
-  66, 81, 78, 91, 92, 75, 86, 89, 73, 132,
-  89, 93, 87, 84, 93, 88, 86, 88, 72, 98,
-  79, 78, 65, 85, 95, 81, 81, 89, 85, 91,
-  74, 92, 73, 100, 85, 90, 87, 86, 79, 76,
-  81, 77, 83, 88, 81, 87, 81, 86, 104, 89,
-  88, 80, 101, 80, 87, 75, 85, 86, 85, 99,
-  76, 101, 78, 77, 82, 76, 69, 89, 87, 85,
-  86, 66, 84, 86, 83, 90, 86, 82, 97, 86,
-  92, 73, 90, 86, 86, 78, 89, 50, 58, 81,
-  74, 86, 82, 91, 85, 88, 81, 91, 77, 89,
-  86, 84, 86, 84, 83, 84, 100, 86, 82, 76,
-  65, 90, 77, 78, 91, 81, 99, 84, 82, 87,
-  86, 82, 77, 77, 86, 86, 79, 86, 76, 80,
-  76, 89, 72, 77, 78, 86, 87, 129, 83, 90,
-  87, 81, 81, 86, 86, 83, 80, 88, 86, 83,
-  88, 83, 84, 70, 92, 89, 91, 91, 65, 87,
-  79, 81, 87, 83, 86, 83, 72, 83, 71, 82,
-  77, 95, 88, 85, 94, 95, 97, 82, 82, 63,
-  87, 78, 98, 87, 89, 86, 94, 102, 79, 129,
-  78, 70, 89, 71, 78, 90, 91, 87, 80, 69,
-  88, 79, 84, 94, 82, 95, 97, 87, 89, 83,
-  88, 88, 84, 78, 91, 65, 71, 87, 75, 92,
-  82, 103, 67, 84, 92, 87, 83, 86, 84, 86,
-  93, 78, 84, 81, 105, 89, 78, 91, 52, 82,
-  73, 81, 94, 84, 94, 94, 74, 92, 96, 81,
-  79, 89, 80, 74, 74, 94, 134, 87, 84, 83,
-  72, 78, 82, 90, 105, 158, 89, 89, 81, 76,
-  79, 93, 96, 76, 81, 76, 80, 96, 101, 84,
-  93, 90, 79, 75, 84, 88, 81, 95, 73, 93,
-  77, 80, 96, 85, 87, 89, 91, 77, 65, 72,
-  85, 81, 82, 84, 92, 98, 77, 94, 83, 87,
-  90, 77, 82, 87, 82, 85, 85, 62, 77, 82,
-  83, 80, 88, 85, 89, 79, 97, 83, 81, 81,
-  78, 81, 92, 72, 78, 91, 84, 83, 78, 95,
-  82, 80, 83, 67, 74, 84, 89, 86, 90, 79,
-  80, 76, 74, 100, 81, 61, 86, 76, 80, 88,
-  87, 91, 87, 85, 95, 86, 61, 81, 79, 84,
-  94, 80, 82, 84, 77, 89, 83, 83, 84, 81,
-  86, 91, 89, 83, 59, 85, 76, 92, 96, 78,
-  86, 87, 68, 111, 81, 92, 78, 87, 97, 90,
-  89, 84, 70, 95, 82, 65, 64, 85, 92, 87,
-  76, 84, 81, 88, 82, 89, 73, 96, 83, 88,
-  87, 86, 81, 80, 85, 75, 85, 84, 81, 86,
-  72, 81, 100, 89, 78, 85, 83, 81, 87, 77,
-  82, 85, 76, 91, 81, 78, 80, 78, 80, 77,
-  76, 93, 86, 79, 88, 74, 83, 84, 81, 85,
-  86, 77, 92, 93, 96, 76, 92, 85, 81, 74,
-  87, 55, 57, 81, 75, 81, 86, 87, 82, 83,
-  77, 92, 75, 79, 88, 81, 79, 87, 88, 85,
-  99, 79, 89, 76, 71, 84, 75, 72, 92, 80,
-  94, 86, 78, 86, 85, 81, 75, 79, 80, 88,
-  76, 84, 63, 79, 80, 92, 80, 83, 76, 83,
-  78, 116, 76, 89, 84, 77, 81, 88, 84, 81,
-  81, 82, 87, 71, 81, 85, 77, 70, 80, 94,
-  86, 97, 70, 88, 79, 92, 81, 80, 82, 89,
-  75, 86, 77, 75, 83, 90, 84, 85, 83, 92,
-  92, 79, 89, 77, 66, 78, 96, 82, 79, 89,
-  89, 94, 78, 119, 81, 73, 86, 72, 68, 90,
-  82, 80, 90, 71, 90, 77, 81, 84, 79, 85,
-  98, 87, 98, 81, 90, 81, 79, 79, 98, 69,
-  68, 84, 76, 87, 90, 97, 75, 79, 96, 87,
-  83, 86, 86, 84, 92, 80, 82, 81, 100, 81,
-  78, 85, 57, 84, 72, 70, 92, 83, 94, 97,
-  80, 85, 89, 79, 78, 90, 75, 84, 77, 93,
-  118, 81, 84, 84, 76, 83, 76, 95, 99, 144,
-  87, 89, 75, 75, 87, 90, 88, 81, 82, 75,
-  79, 88, 95, 84, 89, 91, 77, 78, 79, 89,
-  81, 98, 75, 107, 75, 86, 91, 87, 87, 85,
-  91, 80, 63, 68, 88, 86, 85, 91, 86, 94,
-  82, 93, 91, 79, 86, 76, 79, 87, 83, 93,
-  90, 71, 76, 85, 83, 82, 89, 80, 82, 82,
-  92, 83, 81, 81, 80, 78, 97, 75, 81, 93,
-  90, 82, 83, 94, 86, 86, 93, 73, 85, 85,
-  88, 91, 87, 86, 84, 75, 76, 89, 82, 69,
-  87, 80, 86, 83, 85, 91, 88, 94, 90, 72,
-  57, 82, 80, 91, 98, 82, 93, 80, 86, 85,
-  86, 75, 81, 79, 90, 93, 105, 85, 60, 85,
-  85, 90, 89, 76, 81, 90, 75, 115, 79, 99,
-  79, 99, 102, 90, 90, 79, 66, 99, 75, 69,
-  66, 79, 95, 88, 75, 82, 81, 87, 85, 91,
-  78, 98, 85, 86, 89, 85, 85, 80, 87, 75,
-  79, 72, 88, 85, 70, 82, 93, 90, 75, 87,
-  100, 78, 85, 81, 81, 85, 76, 89, 89, 70,
-  79, 82, 85, 76, 89, 87, 81, 80, 84, 82,
-  84, 85, 82, 85, 86, 78, 87, 93, 96, 77,
-  90, 84, 81, 81, 89, 62, 62, 80, 82, 86,
-  88, 85, 79, 79, 74, 86, 75, 76, 88, 75,
-  81, 86, 88, 84, 101, 84, 89, 69, 70, 82,
-  75, 78, 93, 85, 95, 85, 78, 86, 87, 79,
-  72, 78, 85, 94, 82, 84, 60, 84, 82, 89,
-  88, 82, 77, 83, 78, 105, 81, 92, 84, 81,
-  86, 88, 86, 77, 75, 89, 83, 78, 74, 80,
-  76, 76, 72, 95, 87, 89, 79, 90, 81, 91,
-  83, 79, 84, 89, 76, 84, 80, 77, 76, 81,
-  87, 83, 83, 85, 91, 85, 81, 82, 91, 73,
-  92, 81, 79, 83, 82, 90, 85, 101, 89, 80,
-  86, 69, 81, 85, 75, 82, 87, 76, 92, 78,
-  79, 85, 81, 83, 92, 86, 99, 82, 92, 85,
-  76, 81, 91, 68, 70, 83, 79, 86, 90, 86,
-  88, 82, 85, 84, 81, 86, 82, 75, 90, 77,
-  83, 81, 97, 89, 81, 81, 56, 83, 71, 76,
-  93, 83, 99, 92, 83, 86, 90, 78, 80, 89,
-  82, 89, 79, 86, 98, 81, 81, 84, 87, 87,
-  80, 88, 95, 130, 91, 90, 79, 75, 91, 90,
-  93, 84, 86, 80, 81, 95, 85, 82, 87, 92,
-  93, 64, 79, 102, 84, 89, 88, 67, 85, 79,
-  79, 85, 80, 97, 94, 68, 82, 73, 75, 79,
-  69, 92, 72, 91, 75, 75, 91, 78, 94, 65,
-  91, 84, 73, 92, 77, 89, 82, 90, 104, 68,
-  74, 89, 87, 78, 78, 77, 88, 94, 70, 84,
-  88, 69, 96, 86, 79, 87, 96, 97, 95, 92,
-  84, 95, 86, 86, 93, 70, 80, 84, 100, 82,
-  94, 51, 81, 91, 82, 88, 69, 78, 85, 81,
-  88, 83, 87, 81, 86, 84, 85, 81, 100, 103,
-  93, 92, 71, 87, 92, 89, 81, 107, 69, 79,
-  79, 84, 79, 66, 85, 95, 78, 75, 80, 72,
-  81, 96, 84, 93, 85, 86, 103, 70, 87, 78,
-  92, 81, 85, 77, 79, 85, 85, 98, 94, 62,
-  79, 73, 87, 91, 88, 70, 85, 82, 88, 81,
-  73, 99, 88, 63, 77, 74, 72, 83, 76, 104,
-  73, 88, 80, 72, 90, 71, 104, 55, 87, 85,
-  67, 83, 78, 103, 82, 95, 115, 51, 67, 85,
-  82, 79, 83, 78, 84, 96, 72, 77, 88, 59,
-  83, 86, 86, 87, 113, 93, 95, 94, 92, 93,
-  59, 86, 102, 67, 60, 83, 80, 75, 102, 52,
-  77, 97, 77, 83, 66, 68, 83, 82, 75, 84,
-  86, 78, 84, 80, 87, 92, 89, 109, 99, 96,
-  66, 90, 87, 83, 84, 98, 56, 73, 78, 83,
-  64, 52, 81, 92, 78, 81, 84, 68, 84, 93,
-  86, 85, 86, 87, 109, 63, 84, 78, 87, 92,
-  79, 76, 72, 87, 85, 91, 94, 70, 80, 82,
-  81, 91, 85, 73, 83, 78, 81, 83, 80, 94,
-  90, 72, 87, 73, 75, 82, 94, 93, 86, 86,
-  83, 77, 89, 71, 95, 64, 87, 84, 80, 80,
-  83, 91, 85, 92, 106, 64, 72, 87, 78, 79,
-  85, 84, 88, 92, 72, 89, 87, 68, 92, 79,
-  83, 87, 98, 89, 96, 97, 84, 88, 87, 88,
-  100, 69, 80, 92, 95, 84, 93, 53, 79, 88,
-  81, 89, 65, 79, 85, 80, 78, 96, 84, 82,
-  89, 89, 89, 89, 93, 95, 96, 86, 77, 90,
-  88, 88, 76, 95, 69, 75, 85, 82, 69, 63,
-  80, 91, 75, 78, 86, 74, 83, 88, 92, 89,
-  99, 82, 100, 75, 78, 87, 87, 79, 84, 77,
-  79, 85, 95, 87, 83, 85, 80, 83, 70, 83,
-  90, 80, 82, 82, 66, 81, 75, 86, 73, 63,
-  89, 82, 76, 87, 107, 89, 75, 79, 84, 80,
-  87, 83, 85, 83, 76, 75, 84, 99, 72, 96,
-  81, 71, 106, 68, 90, 88, 92, 72, 80, 85,
-  89, 75, 86, 81, 90, 72, 95, 91, 82, 92,
-  84, 81, 94, 88, 98, 76, 74, 76, 83, 85,
-  73, 77, 98, 80, 78, 72, 82, 82, 89, 86,
-  75, 65, 94, 84, 80, 78, 87, 82, 87, 91,
-  74, 67, 80, 96, 90, 79, 80, 84, 92, 82,
-  78, 87, 78, 82, 79, 88, 71, 70, 80, 97,
-  93, 73, 81, 73, 74, 81, 93, 84, 85, 76,
-  89, 78, 87, 75, 72, 81, 82, 82, 99, 79,
-  103, 81, 88, 86, 77, 76, 69, 85, 95, 80,
-  83, 92, 63, 87, 78, 85, 68, 60, 94, 83,
-  90, 92, 89, 84, 72, 74, 89, 76, 113, 67,
-  94, 93, 69, 78, 77, 84, 81, 108, 80, 53,
-  134, 63, 84, 90, 102, 72, 80, 82, 83, 67,
-  100, 84, 89, 72, 102, 98, 93, 89, 90, 79,
-  93, 84, 110, 87, 57, 76, 84, 88, 56, 89,
-  90, 75, 77, 88, 74, 84, 101, 81, 72, 53,
-  95, 94, 69, 81, 93, 85, 84, 94, 72, 70,
-  73, 106, 95, 86, 80, 95, 100, 81, 72, 74,
-  78, 90, 71, 89, 53, 51, 76, 101, 94, 66,
-  96, 73, 71, 81, 100, 82, 85, 75, 89, 72,
-  79, 74, 66, 82, 78, 85, 93, 71, 94, 78,
-  79, 82, 81, 104, 72, 84, 87, 85, 86, 81,
-  73, 85, 75, 88, 69, 64, 97, 77, 91, 80,
-  80, 91, 78, 78, 91, 81, 91, 72, 89, 95,
-  74, 84, 82, 85, 84, 94, 77, 71, 108, 72,
-  69, 87, 93, 74, 82, 87, 87, 74, 88, 83,
-  93, 77, 93, 77, 86, 90, 86, 83, 96, 89,
-  98, 75, 68, 76, 78, 83, 70, 78, 87, 83,
-  80, 69, 79, 87, 95, 82, 75, 71, 94, 85,
-  81, 97, 81, 81, 78, 92, 79, 79, 78, 100,
-  94, 77, 85, 86, 91, 81, 78, 82, 77, 90,
-  84, 86, 66, 70, 78, 95, 100, 74, 97, 72,
-  81, 87, 86, 83, 86, 75, 85, 75, 72, 81,
-  73, 82, 85, 80, 94, 79, 86, 89, 82, 88,
-  82, 74, 69, 90, 82, 89, 91, 77, 89, 89,
-  83, 78, 70, 81, 91, 86, 85, 86, 101, 94,
-  79, 80, 89, 89, 77, 85, 84, 90, 83, 76,
-  91, 105, 82, 80, 82, 76, 93, 78, 89, 88,
-  87, 88, 71, 89, 90, 74, 85, 89, 92, 92,
-  85, 89, 72, 86, 72, 81, 92, 84, 82, 75,
-  87, 78, 80, 83, 88, 64, 95, 90, 94, 79,
-  94, 71, 81, 91, 80, 86, 94, 86, 93, 87,
-  84, 87, 91, 90, 74, 73, 70, 81, 80, 83,
-  77, 81, 79, 86, 82, 81, 75, 92, 90, 90,
-  83, 96, 90, 90, 78, 85, 91, 87, 91, 75,
-  80, 90, 83, 70, 68, 91, 90, 77, 86, 80,
-  76, 73, 95, 94, 93, 87, 87, 99, 89, 69,
-  67, 89, 90, 83, 97, 82, 98, 88, 88, 76,
-  73, 92, 99, 83, 101, 83, 67, 89, 85, 79,
-  93, 86, 101, 84, 85, 105, 92, 74, 87, 90,
-  84, 79, 89, 70, 90, 75, 96, 94, 93, 99,
-  70, 88, 90, 75, 96, 89, 94, 106, 86, 88,
-  67, 88, 58, 83, 89, 79, 83, 91, 80, 77,
-  87, 89, 80, 59, 87, 83, 89, 85, 86, 64,
-  94, 83, 87, 82, 97, 88, 98, 91, 89, 90,
-  89, 89, 76, 77, 69, 78, 68, 89, 72, 82,
-  85, 90, 82, 74, 72, 85, 84, 93, 90, 98,
-  95, 91, 93, 86, 113, 89, 95, 78, 76, 89,
-  88, 67, 60, 90, 83, 80, 90, 77, 80, 72,
-  91, 94, 86, 87, 79, 86, 87, 97, 69, 83,
-  82, 89, 89, 75, 90, 80, 82, 83, 70, 84,
-  95, 81, 93, 85, 72, 91, 84, 80, 88, 86,
-  80, 85, 80, 95, 84, 85, 87, 87, 78, 78,
-  91, 80, 97, 78, 79, 87, 87, 85, 71, 89,
-  92, 76, 85, 85, 97, 96, 82, 77, 73, 85,
-  75, 81, 91, 86, 86, 76, 87, 81, 82, 81,
-  82, 69, 91, 87, 94, 75, 91, 76, 84, 86,
-  86, 86, 93, 83, 99, 104, 81, 88, 84, 88,
-  79, 79, 70, 86, 79, 81, 82, 79, 80, 82,
-  88, 83, 74, 84, 95, 90, 86, 95, 89, 91,
-  81, 88, 96, 77, 95, 88, 81, 89, 101, 71,
-  69, 90, 72, 79, 83, 82, 80, 70, 93, 93,
-  84, 87, 86, 88, 77, 92, 79, 93, 86, 80,
-  70, 83, 86, 74, 70, 99, 87, 79, 80, 89,
-  89, 75, 68, 81, 79, 78, 85, 85, 97, 84,
-  81, 80, 84, 93, 82, 78, 87, 83, 92, 89,
-  86, 79, 82, 84, 79, 92, 84, 80, 74, 74,
-  76, 84, 87, 79, 79, 97, 85, 91, 92, 82,
-  86, 69, 83, 86, 79, 85, 78, 69, 84, 86,
-  123, 68, 84, 79, 84, 85, 71, 72, 83, 86,
-  74, 87, 78, 72, 74, 79, 88, 83, 85, 75,
-  84, 92, 80, 79, 89, 81, 83, 88, 78, 79,
-  79, 99, 84, 79, 83, 96, 77, 80, 87, 85,
-  83, 92, 76, 87, 76, 60, 72, 85, 92, 92,
-  79, 83, 80, 82, 93, 86, 85, 76, 103, 83,
-  119, 101, 74, 106, 89, 96, 87, 84, 78, 77,
-  94, 82, 64, 98, 85, 83, 87, 81, 95, 82,
-  88, 76, 81, 89, 88, 88, 78, 103, 84, 77,
-  80, 103, 132, 90, 114, 84, 87, 68, 97, 80,
-  92, 78, 95, 92, 65, 90, 77, 66, 83, 72,
-  87, 73, 76, 74, 70, 77, 84, 86, 80, 71,
-  67, 71, 81, 90, 73, 82, 82, 83, 98, 73,
-  86, 82, 81, 81, 77, 96, 75, 96, 74, 84,
-  79, 80, 75, 88, 92, 95, 72, 66, 73, 81,
-  80, 83, 99, 88, 87, 86, 79, 79, 89, 60,
-  80, 83, 78, 89, 89, 79, 76, 81, 96, 88,
-  74, 93, 65, 61, 109, 95, 87, 88, 83, 89,
-  79, 87, 74, 84, 87, 94, 86, 76, 92, 85,
-  77, 74, 85, 93, 84, 77, 71, 89, 83, 89,
-  69, 83, 79, 76, 83, 80, 82, 75, 94, 86,
-  83, 77, 89, 83, 87, 55, 82, 79, 78, 92,
-  81, 78, 82, 79, 79, 86, 76, 79, 88, 92,
-  76, 85, 86, 69, 78, 75, 84, 93, 88, 81,
-  76, 68, 85, 91, 86, 89, 86, 77, 90, 94,
-  81, 87, 99, 70, 83, 102, 80, 70, 73, 83,
-  80, 80, 76, 78, 91, 85, 81, 92, 81, 83,
-  79, 83, 79, 89, 94, 76, 80, 79, 75, 75,
-  86, 85, 84, 81, 88, 80, 72, 73, 89, 78,
-  86, 99, 74, 86, 86, 84, 93, 85, 72, 91,
-  93, 78, 106, 85, 91, 97, 85, 81, 86, 84,
-  99, 86, 85, 78, 95, 83, 71, 87, 80, 84,
-  75, 75, 90, 82, 82, 76, 91, 69, 62, 87,
-  78, 77, 92, 88, 93, 84, 73, 79, 80, 76,
-  92, 88, 89, 60, 88, 75, 76, 87, 145, 81,
-  93, 80, 87, 77, 84, 78, 86, 85, 72, 102,
-  95, 76, 70, 88, 70, 69, 88, 80, 99, 105,
-  75, 93, 98, 82, 93, 89, 74, 75, 72, 86,
-  77, 82, 91, 78, 122, 65, 94, 82, 93, 76,
-  84, 91, 76, 73, 73, 73, 75, 65, 75, 83,
-  83, 95, 84, 94, 97, 94, 82, 78, 105, 77,
-  80, 79, 111, 80, 83, 87, 91, 76, 87, 92,
-  68, 81, 81, 91, 80, 99, 76, 79, 51, 81,
-  74, 81, 88, 92, 81, 93, 83, 81, 103, 80,
-  82, 76, 105, 88, 132, 93, 67, 84, 76, 78,
-  86, 92, 95, 61, 79, 85, 57, 82, 82, 78,
-  95, 97, 85, 67, 74, 75, 82, 73, 106, 94,
-  67, 132, 93, 84, 76, 97, 193, 76, 170, 92,
-  79, 58, 118, 73, 84, 73, 71, 94, 95, 82,
-  75, 81, 79, 53, 83, 74, 99, 60, 66, 78,
-  87, 80, 92, 94, 74, 77, 71, 94, 64, 78,
-  98, 82, 69, 66, 100, 85, 82, 79, 95, 86,
-  81, 73, 70, 60, 67, 83, 76, 100, 71, 99,
-  59, 81, 80, 96, 81, 78, 105, 79, 81, 80,
-  92, 75, 92, 59, 92, 79, 76, 99, 67, 83,
-  75, 91, 100, 100, 76, 70, 64, 74, 81, 86,
-  86, 102, 81, 101, 72, 84, 86, 81, 80, 96,
-  86, 84, 113, 86, 79, 82, 75, 77, 88, 83,
-  76, 85, 76, 92, 61, 82, 78, 76, 90, 87,
-  81, 80, 91, 86, 87, 74, 91, 88, 80, 85,
-  93, 88, 72, 79, 76, 85, 66, 80, 78, 83,
-  79, 78, 82, 90, 67, 82, 97, 88, 77, 86,
-  85, 84, 91, 83, 86, 64, 77, 97, 91, 80,
-  93, 89, 87, 86, 75, 88, 83, 69, 83, 93,
-  71, 70, 81, 84, 84, 77, 80, 58, 77, 72,
-  83, 84, 76, 103, 76, 92, 70, 87, 93, 94,
-  91, 76, 78, 76, 84, 84, 83, 76, 85, 85,
-  81, 94, 95, 74, 95, 100, 70, 85, 79, 86,
-  102, 85, 79, 79, 98, 83, 108, 79, 86, 95,
-  80, 87, 82, 85, 108, 83, 82, 67, 83, 66,
-  63, 86, 98, 83, 87, 76, 89, 74, 90, 92,
-  93, 72, 84, 82, 76, 86, 84, 90, 94, 74,
-  67, 79, 89, 95, 86, 78, 85, 80, 94, 75,
-  99, 88, 105, 68, 95, 83, 74, 83, 79, 77,
-  90, 94, 86, 96, 85, 90, 81, 91, 71, 75,
-  95, 98, 94, 77, 84, 76, 97, 82, 90, 95,
-  87, 87, 81, 84, 88, 99, 80, 80, 76, 75,
-  85, 83, 97, 83, 83, 62, 74, 83, 76, 78,
-  83, 63, 79, 78, 84, 75, 81, 101, 93, 91,
-  86, 105, 92, 90, 85, 83, 96, 86, 73, 80,
-  88, 77, 91, 77, 69, 80, 72, 83, 76, 87,
-  83, 77, 61, 85, 80, 87, 70, 81, 77, 99,
-  90, 77, 95, 91, 80, 78, 83, 83, 79, 82,
-  88, 55, 90, 75, 81, 81, 97, 86, 88, 70,
-  80, 81, 71, 90, 86, 94, 84, 58, 69, 85,
-  97, 91, 96, 80, 78, 96, 94, 81, 98, 72,
-  102, 51, 107, 82, 76, 78, 84, 79, 86, 78,
-  81, 96, 95, 65, 85, 98, 75, 56, 97, 89,
-  94, 66, 82, 76, 98, 77, 93, 96, 98, 101,
-  61, 89, 83, 86, 74, 93, 35, 72, 86, 86,
-  92, 89, 85, 59, 88, 74, 74, 78, 84, 68,
-  71, 83, 67, 69, 83, 106, 89, 90, 89, 100,
-  80, 81, 83, 81, 91, 86, 71, 74, 86, 78,
-  89, 86, 69, 84, 69, 85, 80, 86, 80, 69,
-  82, 94, 51, 92, 70, 88, 73, 93, 90, 73,
-  88, 94, 74, 87, 79, 86, 96, 83, 89, 75,
-  83, 76, 84, 80, 81, 91, 83, 77, 85, 84,
-  78, 84, 86, 92, 86, 73, 90, 84, 99, 88,
-  83, 79, 85, 87, 92, 78, 91, 72, 96, 88,
-  75, 84, 89, 90, 74, 77, 91, 94, 87, 89,
-  83, 68, 80, 88, 84, 82, 92, 98, 89, 73,
-  85, 84, 95, 80, 88, 90, 83, 86, 83, 85,
-  86, 92, 75, 80, 67, 80, 79, 83, 93, 80,
-  81, 88, 68, 87, 84, 79, 88, 82, 77, 85,
-  75, 76, 85, 104, 88, 79, 83, 98, 83, 88,
-  90, 77, 83, 92, 73, 78, 87, 78, 101, 83,
-  77, 79, 76, 81, 80, 83, 87, 87, 74, 90,
-  79, 81, 67, 80, 73, 97, 86, 76, 94, 94,
-  82, 73, 93, 74, 96, 83, 91, 92, 87, 81,
-  90, 92, 73, 79, 79, 96, 82, 98, 78, 85,
-  77, 83, 83, 97, 91, 89, 90, 81, 108, 76,
-  88, 71, 71, 95, 69, 74, 77, 96, 52, 81,
-  72, 86, 87, 95, 84, 83, 95, 80, 79, 75,
-  92, 84, 72, 79, 94, 92, 86, 77, 85, 75,
-  96, 72, 87, 63, 86, 92, 74, 86, 77, 83,
-  86, 94, 81, 80, 73, 109, 84, 92, 77, 114,
-  73, 77, 79, 76, 72, 79, 87, 80, 85, 85,
-  89, 79, 90, 76, 93, 70, 78, 67, 95, 87,
-  78, 73, 81, 53, 87, 76, 97, 98, 89, 94,
-  88, 73, 76, 79, 73, 75, 77, 86, 87, 100,
-  68, 77, 91, 85, 91, 75, 94, 92, 67, 84,
-  111, 77, 76, 87, 86, 74, 86, 75, 78, 86,
-  58, 94, 84, 91, 88, 77, 83, 82, 69, 78,
-  86, 108, 75, 87, 103, 65, 101, 73, 103, 86,
-  68, 105, 86, 76, 81, 79, 59, 50, 81, 71,
-  83, 98, 74, 92, 117, 76, 85, 102, 63, 93,
-  94, 70, 85, 81, 80, 86, 69, 83, 113, 64,
-  117, 55, 95, 102, 83, 88, 81, 127, 85, 107,
-  77, 83, 67, 96, 64, 83, 82, 88, 81, 69,
-  85, 76, 97, 86, 75, 80, 86, 93, 66, 74,
-  88, 91, 108, 61, 77, 57, 84, 123, 78, 92,
-  101, 108, 71, 81, 83, 110, 127, 86, 79, 68,
-  66, 89, 53, 89, 80, 103, 75, 110, 65, 61,
-  88, 74, 78, 66, 86, 84, 48, 93, 88, 92,
-  81, 85, 86, 77, 87, 84, 94, 90, 76, 84,
-  78, 61, 84, 94, 77, 84, 81, 82, 81, 93,
-  90, 85, 83, 85, 99, 81, 88, 83, 79, 98,
-  62, 87, 71, 79, 74, 84, 77, 83, 83, 88,
-  81, 88, 94, 83, 84, 104, 91, 80, 82, 74,
-  90, 97, 86, 87, 78, 79, 90, 82, 90, 60,
-  78, 93, 79, 86, 55, 92, 88, 75, 99, 80,
-  78, 87, 78, 89, 81, 76, 89, 81, 83, 83,
-  63, 84, 84, 71, 83, 82, 86, 75, 89, 99,
-  94, 77, 88, 70, 93, 85, 88, 72, 73, 92,
-  83, 81, 96, 82, 86, 90, 86, 69, 77, 73,
-  75, 96, 68, 81, 88, 97, 69, 72, 81, 86,
-  99, 79, 88, 85, 71, 79, 90, 78, 85, 89,
-  87, 93, 92, 82, 81, 84, 79, 76, 87, 78,
-  81, 87, 73, 77, 70, 87, 76, 95, 81, 82,
-  98, 90, 97, 71, 97, 65, 78, 92, 75, 84,
-  115, 102, 55, 82, 86, 85, 93, 84, 90, 93,
-  100, 90, 96, 81, 93, 76, 75, 75, 86, 86,
-  90, 97, 79, 77, 79, 72, 81, 75, 87, 87,
-  69, 78, 56, 75, 80, 68, 109, 73, 84, 90,
-  92, 81, 76, 116, 79, 81, 73, 80, 79, 88,
-  89, 81, 92, 86, 82, 87, 83, 87, 95, 84,
-  79, 71, 87, 82, 70, 74, 69, 57, 88, 83,
-  100, 94, 79, 85, 91, 63, 85, 80, 69, 83,
-  68, 80, 66, 99, 75, 71, 84, 73, 92, 75,
-  85, 79, 69, 85, 102, 73, 78, 92, 76, 72,
-  104, 80, 67, 83, 81, 86, 86, 87, 79, 79,
-  67, 76, 60, 81, 85, 105, 74, 83, 97, 69,
-  97, 64, 93, 122, 72, 95, 88, 76, 135, 82,
-  83, 78, 83, 59, 128, 98, 86, 98, 126, 87,
-  76, 105, 75, 67, 90, 61, 76, 71, 89, 82,
-  68, 84, 99, 59, 76, 73, 107, 103, 81, 84,
-  55, 93, 72, 71, 85, 91, 99, 80, 75, 78,
-  81, 83, 72, 79, 76, 82, 96, 94, 75, 86,
-  83, 77, 67, 95, 76, 89, 127, 85, 67, 67,
-  74, 112, 82, 86, 80, 65, 76, 86, 86, 100,
-  83, 84, 84, 53, 98, 77, 53, 85, 83, 79,
-  74, 115, 72, 74, 92, 55, 79, 76, 79, 65,
-  59, 89, 82, 82, 96, 89, 84, 81, 91, 81,
-  84, 84, 79, 83, 83, 87, 82, 83, 72, 75,
-  73, 88, 74, 90, 97, 81, 76, 90, 90, 72,
-  89, 107, 86, 95, 76, 83, 83, 80, 77, 81,
-  76, 82, 91, 84, 75, 97, 90, 92, 84, 115,
-  97, 75, 76, 83, 85, 90, 86, 70, 78, 82,
-  76, 78, 84, 61, 84, 79, 73, 78, 63, 75,
-  87, 61, 85, 78, 81, 82, 81, 85, 74, 67,
-  72, 83, 77, 85, 84, 96, 91, 82, 83, 82,
-  84, 84, 80, 71, 96, 86, 79, 72, 87, 81,
-  103, 73, 67, 65, 85, 83, 100, 87, 78, 83,
-  83, 65, 110, 76, 74, 96, 72, 71, 103, 94,
-  71, 73, 85, 76, 100, 71, 84, 74, 75, 82,
-  67, 73, 75, 92, 86, 82, 84, 78, 93, 85,
-  91, 76, 90, 78, 86, 83, 70, 82, 96, 90,
-  82, 81, 95, 95, 80, 94, 80, 77, 83, 74,
-  88, 89, 83, 82, 89, 86, 79, 91, 83, 83,
-  83, 73, 61, 92, 83, 82, 85, 89, 89, 81,
-  82, 83, 82, 108, 86, 82, 93, 89, 75, 89,
-  85, 83, 85, 83, 85, 85, 85, 76, 80, 71,
-  90, 72, 91, 77, 85, 81, 86, 82, 87, 78,
-  79, 94, 78, 88, 95, 79, 93, 79, 85, 95,
-  75, 90, 80, 97, 86, 78, 82, 73, 77, 80,
-  71, 91, 98, 79, 96, 89, 78, 83, 80, 80,
-  89, 77, 86, 93, 78, 81, 63, 85, 91, 75,
-  85, 95, 81, 88, 74, 77, 84, 104, 76, 76,
-  77, 98, 87, 63, 85, 83, 91, 79, 101, 72,
-  91, 86, 83, 83, 70, 91, 102, 97, 73, 77,
-  77, 87, 81, 92, 88, 76, 78, 96, 83, 90,
-  83, 74, 94, 77, 86, 91, 86, 78, 103, 70,
-  72, 85, 83, 83, 72, 67, 91, 79, 82, 84,
-  87, 105, 80, 91, 90, 92, 69, 82, 80, 76,
-  99, 88, 80, 80, 89, 77, 74, 67, 75, 72,
-  96, 74, 79, 72, 82, 68, 91, 65, 80, 99,
-  81, 84, 100, 83, 91, 76, 92, 93, 73, 93,
-  88, 100, 83, 71, 90, 79, 84, 77, 66, 85,
-  99, 79, 106, 95, 64, 87, 90, 72, 105, 68,
-  83, 88, 98, 94, 68, 81, 80, 81, 85, 94,
-  94, 80, 75, 81, 84, 101, 67, 78, 84, 89,
-  80, 88, 82, 79, 96, 84, 92, 74, 89, 86,
-  88, 81, 72, 82, 100, 93, 64, 83, 83, 93,
-  79, 91, 82, 75, 80, 93, 90, 95, 88, 75,
-  81, 82, 86, 86, 79, 80, 85, 73, 76, 90,
-  79, 83, 74, 79, 90, 80, 83, 92, 83, 108,
-  85, 72, 93, 90, 69, 94, 85, 80, 84, 81,
-  83, 89, 87, 73, 82, 76, 63, 68, 90, 70,
-  86, 82, 87, 81, 78, 74, 81, 86, 88, 80,
-  98, 79, 92, 79, 84, 86, 71, 81, 80, 98,
-  79, 77, 80, 76, 94, 81, 77, 77, 99, 80,
-  101, 95, 82, 82, 79, 85, 101, 82, 86, 93,
-  82, 85, 85, 84, 90, 75, 98, 95, 74, 87,
-  76, 79, 85, 102, 78, 78, 75, 79, 78, 72,
-  78, 92, 92, 97, 93, 83, 89, 84, 75, 83,
-  105, 95, 95, 90, 99, 85, 79, 86, 83, 80,
-  89, 103, 95, 86, 99, 71, 76, 83, 84, 84,
-  83, 76, 92, 78, 86, 73, 88, 75, 84, 89,
-  84, 93, 82, 56, 96, 89, 93, 55, 74, 87,
-  89, 81, 79, 82, 94, 79, 87, 77, 70, 67,
-  80, 88, 92, 81, 78, 95, 88, 93, 80, 90,
-  76, 84, 84, 68, 90, 76, 74, 90, 95, 78,
-  93, 85, 76, 92, 90, 78, 60, 71, 93, 83,
-  89, 79, 88, 91, 81, 69, 67, 73, 70, 74,
-  85, 84, 99, 98, 90, 83, 91, 81, 76, 96,
-  90, 90, 82, 79, 109, 106, 60, 70, 82, 94,
-  90, 89, 71, 80, 76, 70, 78, 67, 66, 92,
-  90, 88, 92, 96, 96, 87, 77, 80, 122, 93,
-  81, 92, 90, 65, 68, 94, 78, 73, 96, 100,
-  97, 77, 107, 67, 61, 88, 80, 77, 87, 74,
-  91, 70, 82, 73, 97, 65, 96, 80, 81, 77,
-  80, 48, 99, 83, 79, 48, 69, 87, 98, 79,
-  75, 93, 94, 63, 87, 89, 52, 65, 77, 84,
-  87, 78, 70, 89, 82, 102, 84, 89, 82, 84,
-  89, 68, 80, 81, 64, 95, 90, 84, 80, 80,
-  69, 96, 91, 90, 66, 75, 92, 83, 90, 81,
-  76, 81, 80, 81, 66, 77, 70, 75, 89, 91,
-  106, 122, 89, 83, 91, 84, 81, 86, 70, 86,
-  76, 73, 98, 126, 40, 78, 68, 95, 85, 90,
-  72, 84, 88, 79, 78, 84, 82, 87, 91, 94,
-  83, 81, 81, 84, 81, 86, 101, 92, 94, 81,
-  90, 83, 75, 89, 85, 82, 89, 94, 90, 77,
-  92, 87, 78, 80, 89, 90, 84, 75, 87, 77,
-  91, 76, 99, 79, 92, 85, 85, 84, 84, 68,
-  96, 97, 92, 63, 87, 78, 84, 82, 80, 76,
-  92, 85, 85, 73, 77, 72, 79, 85, 91, 77,
-  93, 96, 87, 95, 82, 93, 76, 85, 95, 68,
-  100, 75, 84, 94, 94, 81, 82, 80, 82, 95,
-  87, 84, 63, 73, 90, 85, 93, 84, 79, 98,
-  86, 87, 66, 73, 71, 72, 78, 92, 99, 92,
-  87, 80, 90, 99, 77, 89, 69, 90, 82, 83,
-  93, 94, 72, 69, 80, 92, 88, 90, 84, 81,
-  77, 82, 86, 73, 84, 110, 100, 94, 88, 95,
-  97, 80, 79, 70, 120, 96, 89, 84, 90, 82,
-  81, 94, 82, 79, 90, 99, 97, 90, 95, 70,
-  65, 84, 100, 83, 87, 75, 86, 84, 83, 68,
-  84, 66, 84, 97, 103, 91, 75, 48, 100, 84,
-  93, 55, 70, 86, 85, 79, 82, 83, 85, 86,
-  75, 79, 64, 66, 79, 88, 89, 67, 84, 85,
-  82, 80, 86, 68, 68, 91, 71, 61, 82, 86,
-  74, 86, 85, 91, 95, 75, 89, 82, 93, 78,
-  58, 64, 89, 78, 77, 75, 110, 76, 82, 82,
-  72, 73, 66, 73, 94, 78, 101, 121, 88, 80,
-  91, 74, 84, 79, 88, 87, 73, 56, 94, 110,
-  46, 81, 75, 83, 93, 94, 91, 75, 85, 73,
-  88, 71, 72, 115, 91, 80, 81, 110, 114, 91,
-  75, 61, 143, 92, 78, 91, 81, 78, 73, 104,
-  70, 69, 98, 91, 98, 94, 109, 68, 37, 92,
-  93, 76, 98, 80, 96, 77, 78, 69, 88, 52,
-  91, 82, 110, 69, 75, 28, 106, 76, 74, 44,
-  71, 95, 103, 75, 71, 94, 93, 71, 71, 96,
-  51, 63, 76, 83, 77, 78, 76, 78, 71, 76,
-  89, 60, 74, 86, 70, 56, 64, 89, 60, 92,
-  80, 108, 78, 72, 77, 88, 91, 82, 55, 62,
-  92, 79, 70, 77, 86, 62, 81, 80, 68, 79,
-  61, 74, 94, 85, 107, 156, 83, 83, 99, 76,
-  86, 71, 74, 83, 68, 49, 91, 141, 0, 91,
-  59, 79, 88, 97, 73, 89, 96, 84, 82, 89,
-  87, 97, 95, 93, 85, 85, 91, 86, 83, 77,
-  104, 93, 86, 82, 88, 88, 76, 98, 89, 80,
-  87, 91, 93, 97, 84, 83, 69, 80, 94, 88,
-  88, 75, 92, 80, 87, 71, 88, 71, 87, 91,
-  104, 81, 79, 61, 98, 87, 98, 63, 79, 87,
-  86, 83, 78, 75, 91, 90, 71, 76, 67, 73,
-  88, 85, 82, 72, 79, 89, 84, 79, 89, 74,
-  70, 84, 72, 65, 96, 82, 84, 101, 83, 94,
-  76, 75, 90, 90, 89, 81, 58, 67, 78, 81,
-  80, 82, 82, 85, 86, 72, 68, 73, 66, 73,
-  91, 85, 100, 107, 76, 79, 89, 98, 79, 81,
-  78, 87, 76, 65, 84, 94, 60, 80, 79, 80,
-  87, 90, 69, 79, 81, 94, 79, 75, 86, 91,
-  101, 102, 86, 86, 87, 79, 86, 82, 93, 78,
-  89, 83, 88, 80, 75, 73, 86, 87, 78, 94,
-  84, 79, 77, 82, 91, 78, 99, 82, 85, 88,
-  77, 99, 98, 70, 95, 86, 86, 103, 80, 108,
-  75, 88, 85, 93, 91, 70, 73, 82, 73, 75,
-  87, 78, 84, 101, 83, 75, 88, 69, 84, 94,
-  84, 79, 95, 82, 98, 86, 80, 76, 75, 83,
-  87, 72, 93, 83, 90, 77, 90, 94, 92, 76,
-  80, 82, 94, 97, 56, 69, 85, 92, 83, 76,
-  104, 100, 82, 96, 86, 67, 79, 94, 83, 78,
-  79, 66, 80, 85, 90, 79, 82, 99, 83, 86,
-  74, 75, 88, 82, 74, 75, 109, 80, 97, 87,
-  79, 81, 88, 92, 82, 70, 86, 89, 106, 97,
-  78, 94, 102, 84, 87, 78, 99, 79, 90, 80,
-  84, 81, 73, 79, 85, 84, 86, 92, 86, 88,
-  79, 80, 89, 81, 90, 77, 92, 84, 85, 107,
-  89, 63, 84, 77, 90, 95, 100, 86, 70, 89,
-  89, 89, 93, 62, 71, 79, 79, 70, 84, 80,
-  88, 86, 83, 78, 69, 66, 90, 89, 74, 86,
-  80, 76, 90, 87, 80, 72, 77, 85, 87, 70,
-  88, 83, 97, 91, 87, 105, 84, 71, 85, 85,
-  104, 89, 56, 65, 76, 91, 74, 74, 90, 85,
-  84, 89, 79, 68, 65, 90, 90, 81, 76, 89,
-  75, 82, 88, 80, 83, 94, 80, 80, 75, 73,
-  88, 92, 59, 76, 106, 75, 89, 96, 65, 88,
-  96, 91, 77, 85, 87, 85, 97, 103, 85, 78,
-  85, 82, 89, 92, 84, 83, 85, 83, 96, 86,
-  83, 79, 94, 85, 74, 89, 84, 94, 71, 86,
-  94, 74, 90, 87, 88, 87, 85, 97, 99, 70,
-  82, 86, 88, 96, 81, 88, 78, 95, 82, 88,
-  93, 73, 74, 78, 75, 80, 85, 74, 88, 99,
-  78, 73, 85, 74, 96, 90, 79, 91, 82, 82,
-  97, 86, 86, 74, 78, 83, 78, 71, 101, 82,
-  98, 106, 88, 100, 80, 78, 81, 87, 91, 84,
-  58, 71, 73, 93, 82, 80, 87, 102, 83, 75,
-  79, 68, 81, 94, 87, 85, 76, 64, 76, 86,
-  91, 93, 85, 102, 91, 88, 76, 84, 80, 79,
-  83, 73, 109, 81, 93, 86, 78, 83, 76, 81,
-  84, 86, 69, 80, 84, 96, 84, 98, 85, 89,
-  82, 83, 82, 97, 70, 73, 88, 72, 85, 88,
-  85, 80, 93, 72, 97, 87, 98, 68, 65, 83,
-  84, 81, 84, 83, 89, 86, 80, 81, 77, 84,
-  96, 74, 82, 100, 76, 100, 84, 77, 87, 92,
-  91, 89, 77, 71, 86, 84, 88, 83, 73, 84,
-  84, 79, 93, 79, 77, 98, 79, 93, 88, 77,
-  88, 82, 74, 89, 84, 86, 79, 83, 101, 88,
-  87, 99, 94, 86, 89, 78, 88, 80, 68, 97,
-  86, 72, 78, 87, 84, 86, 92, 93, 83, 86,
-  82, 75, 93, 81, 78, 50, 92, 72, 86, 90,
-  78, 87, 84, 76, 88, 91, 90, 72, 74, 69,
-  84, 103, 76, 83, 82, 84, 76, 80, 87, 75,
-  68, 78, 88, 94, 83, 92, 92, 88, 88, 75,
-  85, 92, 67, 71, 84, 67, 77, 90, 94, 83,
-  91, 65, 86, 82, 95, 64, 61, 78, 86, 76,
-  85, 83, 89, 84, 83, 82, 85, 83, 100, 69,
-  87, 98, 77, 97, 83, 81, 86, 87, 92, 82,
-  76, 72, 82, 87, 89, 84, 72, 89, 75, 82,
-  94, 87, 80, 92, 77, 96, 86, 69, 92, 74,
-  71, 88, 85, 90, 80, 81, 104, 87, 92, 102,
-  91, 81, 87, 77, 86, 74, 64, 95, 81, 72,
-  76, 86, 84, 89, 85, 97, 81, 84, 81, 77,
-  96, 81, 75, 38, 95, 70, 86, 93, 76, 87,
-  79, 74, 88, 89, 89, 64, 64, 68, 87, 105,
-  79, 84, 81, 85, 82, 74, 85, 82, 78, 81,
-  80, 93, 86, 95, 79, 84, 84, 83, 85, 94,
-  72, 78, 71, 72, 102, 90, 93, 82, 95, 75,
-  78, 82, 95, 61, 65, 73, 89, 81, 81, 77,
-  85, 81, 82, 78, 92, 82, 90, 75, 80, 89,
-  81, 92, 83, 85, 90, 86, 88, 79, 78, 77,
-  92, 87, 84, 80, 75, 85, 91, 80, 101, 81,
-  72, 89, 82, 91, 89, 82, 86, 83, 78, 99,
-  94, 84, 80, 80, 92, 84, 87, 89, 89, 87,
-  85, 77, 83, 88, 76, 91, 83, 76, 76, 90,
-  71, 83, 87, 97, 82, 87, 85, 73, 97, 83,
-  81, 59, 95, 76, 83, 97, 84, 83, 82, 74,
-  88, 92, 88, 75, 73, 69, 85, 103, 74, 83,
-  70, 85, 77, 79, 87, 90, 84, 78, 82, 85,
-  91, 95, 86, 88, 96, 82, 88, 83, 55, 74,
-  89, 67, 85, 93, 84, 82, 92, 60, 105, 86,
-  102, 60, 65, 74, 87, 73, 82, 75, 87, 97,
-  97, 79, 73, 88, 86, 76, 75, 90, 80, 99,
-  85, 81, 89, 76, 91, 93, 79, 77, 86, 88,
-  89, 85, 78, 84, 83, 77, 98, 76, 78, 88,
-  85, 85, 89, 74, 84, 75, 76, 88, 85, 85,
-  83, 78, 99, 81, 86, 89, 95, 89, 101, 85,
-  79, 107, 79, 90, 77, 75, 68, 86, 80, 76,
-  83, 86, 75, 88, 74, 58, 98, 86, 78, 60,
-  93, 79, 79, 89, 78, 73, 82, 67, 88, 91,
-  87, 72, 59, 79, 80, 103, 70, 83, 71, 87,
-  82, 77, 87, 73, 83, 81, 85, 82, 95, 92,
-  92, 89, 97, 77, 93, 75, 53, 69, 85, 62,
-  81, 97, 93, 81, 90, 52, 103, 88, 100, 55,
-  65, 73, 88, 71, 81, 76, 87, 93, 99, 70,
-  80, 85, 84, 75, 76, 90, 84, 96, 85, 85,
-  90, 65, 86, 80, 80, 73, 78, 92, 89, 89,
-  80, 87, 66, 73, 105, 82, 80, 77, 74, 82,
-  93, 70, 87, 63, 76, 91, 84, 89, 80, 75,
-  101, 85, 86, 96, 88, 87, 97, 84, 81, 99,
-  65, 86, 69, 76, 64, 88, 76, 82, 70, 88,
-  72, 88, 75, 59, 98, 86, 72, 55, 96, 76,
-  82, 95, 80, 77, 81, 59, 87, 92, 83, 70,
-  53, 83, 81, 105, 74, 84, 72, 92, 89, 73,
-  86, 81, 87, 82, 80, 89, 91, 93, 82, 85,
-  92, 79, 90, 79, 60, 75, 76, 72, 107, 92,
-  94, 80, 91, 65, 100, 82, 101, 55, 63, 71,
-  85, 77, 79, 72, 85, 95, 104, 76, 85, 89,
-  75, 81, 75, 87, 83, 94, 83, 88, 92, 71,
-  87, 78, 82, 82, 90, 93, 88, 81, 84, 83,
-  83, 74, 106, 76, 76, 86, 82, 82, 89, 89,
-  85, 79, 79, 97, 89, 84, 80, 77, 89, 83,
-  84, 81, 81, 94, 99, 89, 77, 117, 86, 84,
-  75, 80, 65, 89, 68, 75, 82, 83, 74, 89,
-  80, 61, 97, 87, 80, 74, 91, 83, 78, 102,
-  90, 68, 83, 71, 93, 94, 80, 80, 67, 79,
-  83, 99, 71, 86, 80, 83, 85, 72, 94, 99,
-  80, 74, 71, 84, 84, 93, 80, 91, 89, 98,
-  88, 84, 66, 80, 89, 84, 110, 87, 84, 83,
-  84, 73, 85, 83, 103, 86, 69, 74, 85, 73,
-  86, 67, 78, 106, 96, 62, 76, 89, 70, 81,
-  80, 80, 79, 104, 75, 84, 95, 73, 104, 85,
-  81, 85, 89, 88, 89, 75, 97, 75, 75, 81,
-  99, 78, 78, 90, 92, 92, 77, 91, 80, 84,
-  89, 84, 76, 80, 91, 79, 80, 91, 83, 76,
-  91, 91, 92, 85, 78, 125, 90, 84, 79, 78,
-  72, 83, 75, 68, 79, 86, 78, 90, 92, 63,
-  94, 86, 87, 85, 85, 76, 75, 86, 82, 68,
-  81, 80, 92, 92, 80, 83, 79, 79, 90, 91,
-  72, 84, 79, 84, 89, 66, 86, 90, 82, 76,
-  77, 86, 86, 92, 78, 90, 88, 97, 87, 74,
-  64, 78, 90, 84, 118, 87, 82, 81, 78, 67,
-  84, 83, 102, 82, 73, 73, 81, 77, 90, 71,
-  75, 105, 102, 58, 83, 87, 69, 79, 77, 81,
-  82, 106, 78, 88, 99, 67, 100, 88, 84, 83,
-  88, 94, 89, 74, 102, 82, 71, 75, 98, 86,
-  72, 91, 86, 93, 80, 103, 78, 88, 94, 89,
-  76, 83, 90, 74, 72, 85, 80, 73, 85, 99,
-  91, 80, 81, 135, 93, 81, 74, 80, 68, 84,
-  74, 76, 82, 92, 74, 89, 102, 65, 89, 89,
-  85, 92, 83, 73, 71, 87, 88, 66, 86, 86,
-  101, 99, 75, 86, 75, 81, 95, 92, 73, 83,
-  89, 85, 82, 70, 88, 97, 88, 78, 75, 90,
-  85, 92, 76, 90, 87, 98, 87, 79, 72, 81,
-  88, 92, 121, 88, 82, 85, 86, 74, 93, 78,
-  98, 92, 72, 74, 81, 85, 90, 70, 82, 104,
-  102, 64, 88, 92, 69, 87, 79, 82, 81, 101,
-  82, 86, 98, 73, 106, 88, 84, 96, 93, 92,
-  87, 75, 102, 76, 72, 78, 92, 81, 74, 82,
-  90, 91, 79, 109, 80, 95, 89, 94, 80, 81,
-  91, 79, 69, 75, 81, 69, 81, 96, 92, 86,
-  76, 135, 102, 77, 77, 85, 70, 90, 77, 71,
-  80, 93, 80, 88, 101, 65, 87, 88, 94, 100,
-  87, 78, 71, 90, 85, 58, 84, 90, 98, 99,
-  83, 87, 87, 86, 94, 84, 72, 90, 86, 77,
-  80, 67, 87, 93, 91, 77, 67, 60, 93, 85,
-  86, 89, 74, 82, 87, 99, 84, 89, 88, 103,
-  86, 76, 89, 88, 79, 115, 92, 85, 84, 83,
-  81, 88, 81, 73, 86, 83, 79, 88, 76, 79,
-  90, 86, 82, 76, 88, 79, 80, 87, 87, 83,
-  61, 75, 87, 83, 73, 93, 81, 83, 88, 85,
-  80, 78, 90, 77, 75, 89, 89, 83, 72, 81,
-  89, 84, 84, 74, 74, 70, 85, 90, 81, 78,
-  76, 91, 94, 71, 79, 89, 85, 88, 83, 84,
-  71, 88, 80, 93, 77, 80, 90, 99, 80, 84,
-  84, 79, 88, 87, 79, 93, 86, 100, 87, 85,
-  105, 82, 95, 76, 83, 155, 93, 87, 96, 95,
-  81, 93, 97, 78, 88, 86, 84, 84, 73, 71,
-  86, 75, 94, 76, 72, 54, 99, 84, 89, 79,
-  74, 79, 91, 91, 72, 90, 92, 95, 82, 94,
-  92, 86, 82, 109, 89, 85, 85, 85, 86, 81,
-  82, 73, 82, 89, 81, 83, 77, 79, 90, 83,
-  84, 79, 95, 70, 83, 83, 92, 78, 61, 78,
-  89, 82, 75, 90, 82, 81, 90, 84, 81, 77,
-  75, 81, 78, 88, 94, 80, 72, 79, 82, 80,
-  92, 70, 71, 77, 83, 91, 82, 85, 79, 76,
-  82, 71, 74, 85, 89, 93, 84, 87, 63, 89,
-  74, 103, 77, 77, 93, 101, 78, 83, 72, 81,
-  77, 88, 76, 92, 94, 108, 88, 80, 109, 75,
-  93, 75, 71, 160, 80, 85, 92, 93, 77, 91,
-  91, 78, 71, 88, 87, 94, 79, 72, 84, 79,
-  89, 76, 71, 68, 88, 84, 81, 83, 77, 85,
-  89, 93, 85, 90, 87, 97, 93, 78, 88, 92,
-  85, 113, 93, 80, 82, 83, 82, 77, 87, 91,
-  86, 89, 85, 88, 78, 83, 87, 87, 85, 79,
-  86, 78, 80, 86, 92, 81, 62, 78, 87, 90,
-  78, 92, 83, 81, 80, 82, 79, 68, 101, 72,
-  79, 88, 84, 84, 97, 78, 88, 83, 88, 77,
-  75, 86, 85, 91, 86, 75, 73, 82, 93, 74,
-  82, 85, 86, 89, 81, 87, 69, 86, 83, 95,
-  78, 82, 85, 97, 82, 84, 85, 78, 85, 92,
-  76, 93, 84, 93, 89, 83, 99, 80, 89, 73,
-  74, 135, 88, 88, 83, 94, 85, 91, 91, 72,
-  90, 87, 83, 79, 74, 79, 79, 90, 91, 82,
-  73, 62, 95, 85, 83, 88, 78, 77, 85, 87,
-  68, 89, 91, 92, 89, 79, 90, 83, 79, 109,
-  86, 81, 81, 84, 85, 87, 77, 75, 87, 82,
-  84, 85, 87, 79, 86, 80, 81, 78, 93, 84,
-  83, 90, 92, 79, 65, 72, 87, 80, 78, 86,
-  84, 82, 95, 89, 86, 79, 78, 79, 82, 86,
-  87, 71, 72, 81, 82, 88, 85, 69, 80, 76,
-  80, 94, 81, 80, 78, 87, 79, 75, 81, 85,
-  80, 85, 84, 84, 75, 88, 79, 92, 74, 76,
-  85, 99, 84, 87, 70, 80, 68, 78, 86, 89,
-  90, 97, 83, 83, 116, 81, 82, 79, 78, 156,
-  78, 87, 99, 95, 82, 92, 97, 76, 73, 86,
-  85, 83, 72, 85, 74, 77, 94, 81, 81, 60,
-  100, 82, 89, 83, 78, 72, 91, 86, 58, 87,
-  93, 92, 82, 93, 95, 77, 76, 100, 81, 83,
-  84, 93, 90, 84, 79, 76, 88, 80, 85, 77,
-  87, 84, 90, 79, 85, 83, 98, 78, 85, 88,
-  95, 81, 64, 70, 89, 78, 81, 82, 88, 76,
-  100, 88, 87, 78, 66, 88, 86, 87, 95, 69,
-  68, 81, 78, 83, 89, 63, 80, 86, 75, 96,
-  79, 85, 81, 80, 73, 80, 77, 84, 80, 91,
-  84, 83, 68, 89, 77, 98, 74, 75, 91, 99,
-  86, 81, 62, 81, 62, 80, 92, 89, 89, 101,
-  84, 82, 120, 79, 81, 81, 70, 162, 67, 85,
-  89, 94, 75, 87, 84, 71, 59, 86, 88, 96,
-  80, 82, 82, 84, 88, 79, 76, 68, 89, 84,
-  81, 82, 75, 81, 87, 85, 72, 82, 83, 91,
-  95, 81, 90, 87, 82, 111, 85, 78, 84, 87,
-  84, 80, 79, 85, 86, 93, 84, 83, 87, 82,
-  86, 86, 84, 81, 91, 83, 84, 86, 91, 84,
-  62, 75, 85, 84, 80, 87, 86, 78, 90, 85,
-  81, 72, 79, 76, 84, 85, 87, 75, 83, 79,
-  80, 87, 88, 76, 78, 90, 83, 93, 86, 74,
-  75, 88, 83, 80, 78, 84, 79, 87, 81, 86,
-  72, 88, 80, 85, 77, 78, 87, 96, 84, 75,
-  71, 78, 68, 82, 83, 90, 94, 90, 87, 82,
-  109, 82, 82, 80, 78, 136, 80, 85, 89, 93,
-  82, 94, 91, 74, 80, 89, 84, 81, 79, 81,
-  77, 91, 88, 78, 77, 75, 83, 89, 85, 88,
-  70, 78, 90, 86, 84, 87, 88, 96, 85, 71,
-  90, 83, 75, 116, 88, 77, 80, 85, 82, 82,
-  72, 74, 82, 90, 88, 88, 89, 81, 79, 83,
-  78, 82, 90, 86, 79, 89, 89, 76, 68, 70,
-  87, 83, 76, 83, 85, 86, 92, 89, 87, 82,
-  89, 74, 85, 83, 83, 79, 79, 81, 91, 83,
-  80, 70, 74, 78, 77, 87, 85, 82, 75, 90,
-  83, 73, 78, 85, 87, 84, 83, 87, 79, 85,
-  83, 81, 74, 78, 81, 99, 81, 90, 78, 77,
-  65, 79, 83, 93, 90, 89, 81, 88, 100, 84,
-  82, 77, 80, 139, 81, 83, 89, 88, 83, 94,
-  105, 81, 93, 87, 82, 85, 78, 87, 76, 77,
-  92, 80, 81, 73, 87, 85, 95, 84, 70, 77,
-  97, 85, 77, 86, 89, 93, 83, 76, 94, 78,
-  71, 111, 83, 81, 86, 86, 81, 80, 75, 78,
-  86, 81, 90, 80, 91, 86, 84, 86, 79, 83,
-  92, 81, 84, 87, 87, 77, 62, 72, 88, 81,
-  76, 81, 93, 83, 94, 90, 89, 84, 73, 80,
-  85, 83, 91, 77, 70, 81, 89, 82, 83, 63,
-  74, 82, 80, 88, 82, 88, 77, 83, 81, 80,
-  78, 86, 88, 82, 79, 90, 82, 92, 79, 89,
-  73, 75, 89, 99, 79, 77, 72, 77, 63, 78,
-  85, 91, 83, 89, 80, 88, 104, 82, 81, 80,
-  74, 142, 77, 81, 86, 89, 80, 90, 97, 75,
-  85, 86, 88, 95, 84, 84, 80, 84, 85, 79,
-  80, 80, 83, 88, 83, 85, 70, 80, 89, 81,
-  86, 80, 78, 92, 92, 75, 85, 87, 75, 112,
-  86, 75, 84, 81, 76, 77, 74, 83, 85, 97,
-  85, 88, 89, 82, 82, 89, 83, 83, 88, 82,
-  79, 84, 89, 85, 63, 74, 85, 81, 74, 84,
-  87, 83, 91, 81, 82, 73, 86, 73, 84, 80,
-  83, 77, 82, 81, 84, 83, 80, 73, 76, 83,
-  83, 90, 86, 79, 74, 82, 83, 77, 82, 83,
-  87, 88, 80, 88, 74, 89, 83, 76, 78, 81,
-  83, 95, 78, 75, 74, 76, 66, 78, 82, 90,
-  89, 85, 82, 87, 95, 83, 83, 82, 83, 123,
-  82, 84, 94, 88, 78, 94, 97, 81, 97, 88,
-  91, 91, 92, 80, 82, 70, 78, 66, 93, 86,
-  77, 93, 120, 103, 77, 83, 73, 65, 85, 95,
-  98, 64, 82, 95, 85, 85, 85, 87, 103, 83,
-  102, 100, 67, 76, 103, 103, 81, 82, 87, 88,
-  83, 92, 89, 90, 86, 111, 86, 92, 70, 83,
-  94, 89, 97, 73, 82, 71, 63, 64, 89, 89,
-  86, 72, 82, 90, 78, 66, 67, 74, 71, 76,
-  108, 93, 73, 81, 91, 64, 80, 108, 78, 84,
-  86, 87, 104, 78, 87, 86, 84, 91, 92, 79,
-  71, 86, 87, 103, 75, 86, 81, 93, 74, 61,
-  87, 93, 90, 84, 83, 84, 70, 91, 79, 85,
-  95, 91, 74, 98, 85, 102, 73, 88, 81, 75,
-  90, 87, 82, 74, 83, 80, 89, 92, 69, 57,
-  92, 86, 69, 104, 77, 97, 84, 95, 77, 72,
-  61, 92, 66, 84, 77, 67, 90, 83, 62, 76,
-  105, 100, 67, 92, 80, 81, 111, 89, 77, 81,
-  66, 79, 71, 110, 74, 90, 65, 82, 90, 72,
-  66, 68, 85, 96, 90, 106, 96, 70, 78, 86,
-  78, 72, 89, 75, 115, 72, 71, 87, 85, 88,
-  93, 58, 76, 72, 52, 80, 92, 88, 54, 81,
-  92, 86, 79, 94, 62, 96, 74, 70, 93, 81,
-  87, 90, 64, 80, 84, 99, 70, 81, 95, 90,
-  77, 85, 114, 75, 81, 78, 79, 77, 80, 88,
-  91, 84, 93, 84, 101, 70, 75, 64, 88, 94,
-  77, 91, 66, 97, 123, 82, 82, 75, 81, 84,
-  91, 92, 83, 91, 79, 77, 80, 63, 89, 72,
-  79, 76, 75, 92, 91, 75, 89, 75, 68, 79,
-  83, 89, 89, 90, 93, 81, 37, 72, 91, 81,
-  82, 97, 82, 79, 68, 87, 77, 82, 91, 95,
-  70, 98, 89, 85, 93, 94, 90, 64, 87, 83,
-  91, 78, 97, 91, 100, 89, 70, 85, 73, 93,
-  82, 98, 118, 88, 87, 80, 76, 99, 81, 72,
-  73, 106, 87, 89, 103, 75, 77, 72, 111, 87,
-  80, 93, 71, 75, 87, 83, 95, 93, 84, 73,
-  94, 86, 83, 70, 86, 89, 115, 86, 85, 92,
-  100, 77, 73, 88, 90, 99, 86, 83, 83, 91,
-  98, 81, 98, 85, 81, 78, 74, 68, 84, 77,
-  78, 91, 74, 83, 88, 76, 88, 81, 87, 98,
-  84, 91, 79, 81, 79, 87, 91, 78, 85, 66,
-  77, 65, 93, 86, 82, 87, 114, 106, 73, 83,
-  73, 65, 84, 97, 94, 62, 83, 96, 80, 87,
-  79, 89, 80, 81, 88, 88, 71, 74, 98, 100,
-  72, 80, 83, 90, 85, 77, 90, 84, 83, 107,
-  80, 80, 75, 94, 89, 83, 91, 75, 80, 75,
-  71, 67, 87, 90, 83, 66, 72, 86, 73, 68,
-  76, 74, 75, 84, 78, 89, 70, 82, 88, 68,
-  76, 110, 71, 84, 89, 83, 109, 85, 83, 90,
-  80, 91, 75, 73, 81, 79, 94, 98, 66, 85,
-  87, 91, 90, 64, 86, 70, 85, 84, 86, 89,
-  84, 83, 78, 84, 79, 87, 72, 96, 73, 85,
-  92, 83, 67, 72, 76, 87, 77, 71, 84, 79,
-  79, 91, 60, 63, 69, 86, 70, 94, 72, 94,
-  91, 91, 80, 75, 60, 77, 62, 81, 79, 74,
-  85, 87, 71, 74, 85, 99, 59, 90, 75, 78,
-  103, 78, 76, 75, 57, 81, 55, 103, 67, 93,
-  69, 74, 82, 70, 62, 65, 88, 90, 82, 83,
-  88, 70, 88, 82, 82, 75, 84, 71, 131, 70,
-  76, 94, 88, 75, 93, 67, 62, 82, 59, 79,
-  88, 79, 65, 74, 93, 90, 82, 98, 63, 97,
-  70, 63, 91, 75, 84, 82, 72, 81, 86, 92,
-  69, 86, 91, 94, 71, 80, 118, 75, 89, 78,
-  93, 79, 77, 75, 90, 86, 99, 94, 110, 78,
-  79, 65, 75, 94, 79, 82, 61, 74, 127, 80,
-  82, 78, 78, 83, 79, 92, 74, 90, 78, 77,
-  84, 83, 87, 69, 91, 66, 87, 84, 89, 67,
-  79, 84, 85, 85, 86, 80, 89, 87, 90, 80,
-  57, 76, 77, 79, 85, 98, 84, 76, 79, 71,
-  88, 88, 91, 88, 72, 93, 88, 85, 91, 91,
-  77, 73, 90, 95, 83, 80, 93, 72, 93, 84,
-  75, 85, 77, 85, 75, 95, 113, 86, 85, 85,
-  79, 90, 86, 78, 72, 108, 79, 74, 93, 75,
-  88, 81, 96, 95, 85, 78, 81, 75, 95, 78,
-  87, 90, 93, 74, 100, 88, 81, 71, 101, 97,
-  98, 81, 83, 93, 85, 82, 79, 87, 96, 93,
-  86, 79, 81, 93, 91, 81, 100, 88, 94, 82,
-  85, 71, 80, 68, 90, 90, 52, 79, 91, 87,
-  86, 83, 89, 87, 77, 92, 79, 93, 74, 103,
-  100, 81, 89, 82, 84, 67, 82, 87, 80, 88,
-  104, 110, 62, 74, 73, 64, 81, 94, 100, 75,
-  88, 94, 78, 75, 85, 93, 95, 95, 84, 88,
-  73, 71, 91, 99, 89, 83, 83, 89, 97, 78,
-  91, 84, 80, 108, 67, 80, 81, 91, 96, 86,
-  91, 73, 82, 78, 76, 64, 80, 83, 92, 70,
-  77, 87, 78, 66, 79, 77, 82, 81, 74, 84,
-  75, 81, 89, 70, 78, 107, 73, 87, 87, 90,
-  105, 94, 80, 94, 80, 87, 79, 81, 87, 73,
-  91, 86, 67, 84, 91, 86, 105, 77, 84, 75,
-  90, 81, 88, 92, 88, 84, 82, 81, 69, 91,
-  76, 96, 84, 71, 97, 80, 75, 75, 80, 80,
-  71, 75, 89, 76, 83, 87, 71, 68, 63, 83,
-  74, 106, 79, 97, 90, 87, 74, 73, 53, 80,
-  65, 83, 76, 74, 83, 76, 99, 79, 79, 89,
-  64, 93, 77, 77, 103, 92, 78, 86, 68, 82,
-  53, 102, 82, 91, 74, 73, 85, 73, 61, 72,
-  84, 100, 77, 89, 92, 65, 95, 80, 89, 73,
-  83, 75, 125, 77, 72, 93, 93, 71, 97, 64,
-  66, 78, 72, 81, 89, 72, 92, 78, 99, 93,
-  83, 99, 69, 94, 77, 66, 97, 87, 85, 81,
-  80, 82, 97, 85, 71, 86, 86, 97, 77, 81,
-  117, 81, 90, 84, 103, 78, 82, 78, 87, 87,
-  95, 80, 108, 79, 83, 69, 72, 88, 79, 78,
-  73, 76, 110, 84, 89, 85, 83, 83, 78, 93,
-  76, 94, 84, 80, 86, 81, 82, 73, 94, 87,
-  94, 84, 81, 71, 72, 78, 76, 84, 94, 81,
-  79, 90, 83, 77, 90, 80, 81, 81, 86, 98,
-  81, 73, 59, 91, 81, 87, 90, 83, 70, 83,
-  85, 80, 86, 87, 73, 83, 85, 97, 85, 87,
-  90, 80, 97, 78, 80, 91, 73, 83, 78, 82,
-  105, 90, 80, 73, 77, 87, 84, 74, 71, 104,
-  77, 76, 81, 83, 86, 84, 95, 97, 89, 89,
-  85, 78, 93, 77, 94, 93, 84, 86, 98, 81,
-  93, 74, 91, 77, 89, 82, 91, 89, 86, 89,
-  85, 92, 94, 83, 91, 80, 81, 95, 80, 70,
-  103, 88, 98, 78, 98, 69, 78, 71, 91, 99,
-  74, 82, 93, 93, 85, 81, 77, 91, 70, 97,
-  79, 88, 85, 88, 104, 85, 79, 83, 80, 84,
-  90, 82, 79, 87, 73, 87, 82, 82, 81, 83,
-  83, 95, 77, 77, 89, 81, 95, 78, 76, 79,
-  86, 85, 86, 85, 76, 80, 76, 93, 99, 92,
-  87, 78, 92, 78, 87, 78, 77, 72, 92, 82,
-  78, 81, 85, 78, 94, 92, 91, 79, 83, 78,
-  79, 84, 86, 80, 78, 80, 86, 81, 86, 84,
-  83, 85, 82, 84, 74, 67, 83, 78, 84, 75,
-  83, 83, 75, 88, 76, 79, 90, 79, 88, 82,
-  84, 86, 80, 77, 69, 81, 90, 81, 75, 88,
-  71, 80, 84, 85, 83, 83, 83, 83, 79, 87,
-  79, 86, 92, 79, 88, 85, 88, 79, 85, 86,
-  83, 78, 90, 87, 80, 86, 87, 92, 86, 76,
-  74, 93, 91, 82, 78, 87, 97, 77, 99, 80,
-  79, 78, 78, 78, 85, 88, 83, 76, 89, 86,
-  98, 80, 87, 90, 75, 88, 79, 78, 80, 81,
-  71, 65, 84, 77, 79, 84, 78, 85, 78, 114,
-  82, 81, 86, 82, 82, 92, 85, 80, 69, 93,
-  82, 92, 106, 89, 91, 85, 87, 74, 88, 89,
-  75, 86, 67, 83, 86, 83, 90, 79, 88, 72,
-  88, 83, 88, 92, 84, 92, 75, 82, 71, 91,
-  82, 93, 82, 83, 81, 71, 85, 73, 86, 83,
-  89, 76, 82, 81, 72, 85, 74, 91, 76, 82,
-  76, 79, 75, 80, 84, 77, 89, 87, 80, 85,
-  99, 82, 81, 88, 78, 66, 89, 79, 76, 79,
-  78, 80, 90, 80, 102, 93, 77, 80, 84, 84,
-  77, 83, 81, 86, 80, 81, 86, 80, 77, 85,
-  72, 79, 81, 86, 83, 83, 81, 80, 85, 79,
-  78, 79, 81, 77, 75, 79, 87, 76, 81, 81,
-  75, 93, 82, 80, 91, 86, 84, 81, 85, 77,
-  78, 74, 76, 71, 83, 70, 76, 82, 83, 73,
-  91, 90, 90, 93, 85, 79, 80, 87, 85, 84,
-  74, 81, 86, 81, 83, 84, 83, 87, 88, 83,
-  66, 70, 84, 79, 82, 86, 88, 77, 74, 88,
-  79, 85, 87, 79, 81, 86, 83, 88, 87, 78,
-  69, 76, 93, 77, 77, 89, 95, 76, 85, 82,
-  80, 80, 86, 82, 82, 86, 86, 82, 83, 82,
-  90, 90, 81, 80, 72, 83, 80, 76, 69, 87,
-  81, 87, 82, 92, 83, 78, 77, 95, 93, 83,
-  86, 75, 89, 82, 97, 77, 77, 83, 74, 82,
-  82, 84, 84, 88, 92, 83, 77, 69, 89, 83,
-  90, 95, 84, 79, 102, 78, 76, 75, 80, 73,
-  72, 87, 84, 84, 80, 100, 79, 77, 96, 83,
-  79, 74, 80, 80, 79, 81, 82, 92, 99, 93,
-  106, 78, 85, 83, 85, 75, 86, 74, 87, 77,
-  96, 85, 88, 75, 81, 93, 80, 86, 88, 81,
-  78, 80, 79, 71, 94, 81, 86, 77, 83, 73,
-  84, 75, 83, 77, 106, 82, 80, 90, 81, 86,
-  80, 88, 80, 92, 75, 84, 83, 82, 80, 85,
-  85, 88, 80, 86, 75, 80, 89, 81, 84, 76,
-  94, 61, 80, 81, 73, 93, 84, 80, 76, 87,
-  86, 77, 81, 79, 72, 87, 82, 82, 85, 82,
-  113, 88, 111, 78, 84, 80, 77, 76, 84, 93,
-  90, 90, 120, 80, 105, 76, 81, 93, 78, 101,
-  98, 82, 212, 84, 68, 70, 107, 83, 70, 78,
-  77, 85, 71, 141, 79, 75, 96, 89, 87, 106,
-  77, 79, 81, 102, 80, 101, 109, 96, 120, 78,
-  95, 92, 98, 86, 80, 82, 84, 72, 87, 94,
-  95, 75, 87, 79, 87, 101, 115, 99, 80, 113,
-  82, 79, 97, 83, 95, 83, 92, 74, 87, 73,
-  80, 76, 120, 84, 96, 83, 105, 87, 84, 95,
-  90, 96, 82, 86, 80, 69, 76, 85, 87, 93,
-  96, 91, 80, 85, 95, 87, 80, 81, 85, 55,
-  89, 77, 68, 98, 77, 88, 83, 81, 88, 77,
-  83, 96, 73, 74, 70, 78, 86, 83, 87, 77,
-  93, 75, 76, 76, 70, 73, 83, 85, 82, 87,
-  94, 68, 91, 72, 70, 79, 81, 90, 83, 78,
-  109, 77, 73, 74, 81, 81, 76, 69, 79, 81,
-  79, 101, 77, 76, 83, 79, 75, 73, 71, 66,
-  80, 83, 81, 88, 96, 91, 105, 79, 88, 90,
-  85, 74, 84, 76, 84, 71, 92, 86, 87, 74,
-  77, 96, 85, 89, 85, 82, 78, 88, 78, 75,
-  95, 76, 89, 77, 80, 77, 82, 81, 72, 84,
-  106, 84, 84, 82, 84, 80, 80, 83, 82, 90,
-  89, 80, 88, 62, 75, 82, 83, 87, 81, 85,
-  81, 77, 80, 81, 84, 81, 88, 64, 74, 79,
-  68, 94, 70, 84, 80, 86, 82, 77, 80, 82,
-  89, 93, 86, 83, 81, 76, 79, 78, 77, 79,
-  82, 83, 82, 80, 82, 81, 87, 86, 75, 95,
-  74, 79, 87, 78, 84, 80, 73, 82, 83, 81,
-  80, 78, 75, 79, 75, 99, 85, 82, 89, 78,
-  78, 78, 97, 76, 88, 67, 79, 93, 79, 83,
-  76, 77, 79, 86, 81, 86, 78, 74, 75, 82,
-  83, 76, 77, 77, 93, 75, 82, 91, 82, 87,
-  90, 88, 86, 73, 90, 81, 81, 73, 85, 84,
-  75, 80, 70, 73, 86, 88, 85, 82, 81, 77,
-  79, 83, 70, 87, 87, 88, 77, 86, 74, 70,
-  81, 96, 85, 88, 89, 87, 84, 82, 79, 75,
-  87, 78, 86, 84, 74, 85, 81, 84, 78, 86,
-  78, 84, 73, 89, 85, 80, 87, 82, 77, 80,
-  87, 81, 79, 83, 93, 70, 94, 78, 83, 76,
-  78, 75, 86, 88, 87, 81, 91, 84, 95, 88,
-  83, 84, 69, 83, 77, 81, 105, 77, 61, 66,
-  88, 80, 69, 85, 78, 79, 78, 113, 72, 77,
-  82, 86, 79, 83, 77, 86, 71, 93, 69, 93,
-  86, 85, 90, 79, 84, 81, 79, 86, 75, 81,
-  68, 77, 90, 77, 84, 79, 85, 86, 95, 95,
-  95, 88, 82, 98, 75, 82, 77, 87, 79, 82,
-  81, 77, 79, 85, 82, 77, 93, 80, 82, 73,
-  82, 83, 76, 91, 81, 89, 72, 82, 83, 83,
-  73, 84, 83, 83, 91, 86, 73, 78, 91, 79,
-  78, 82, 73, 70, 83, 80, 73, 85, 69, 80,
-  76, 80, 96, 71, 79, 87, 84, 77, 81, 83,
-  83, 82, 81, 73, 76, 76, 78, 78, 72, 84,
-  83, 84, 81, 90, 78, 81, 92, 79, 72, 74,
-  76, 76, 74, 80, 105, 78, 77, 77, 78, 87,
-  78, 79, 79, 80, 77, 86, 74, 74, 76, 74,
-  82, 67, 73, 70, 79, 80, 75, 75, 79, 86,
-  79, 74, 80, 83, 69, 83, 82, 80, 76, 76,
-  91, 76, 88, 88, 77, 97, 83, 90, 76, 77,
-  81, 83, 80, 85, 79, 77, 76, 78, 72, 89,
-  83, 93, 79, 87, 85, 78, 82, 74, 70, 82,
-  89, 85, 82, 87, 82, 71, 84, 80, 82, 85,
-  92, 87, 83, 82, 80, 72, 83, 80, 87, 84,
-  79, 88, 83, 82, 74, 89, 64, 86, 71, 87,
-  81, 80, 85, 84, 85, 82, 62, 81, 91, 80,
-  85, 83, 72, 85, 90, 70, 71, 97, 78, 73,
-  89, 89, 84, 80, 88, 81, 82, 82, 80, 79,
-  81, 83, 99, 94, 98, 88, 76, 74, 84, 91,
-  95, 77, 92, 69, 98, 119, 78, 80, 100, 75,
-  72, 91, 109, 87, 99, 91, 85, 95, 66, 104,
-  84, 87, 88, 74, 89, 89, 115, 100, 87, 80,
-  77, 78, 78, 72, 75, 86, 79, 80, 84, 85,
-  93, 71, 91, 87, 95, 82, 102, 89, 84, 58,
-  85, 84, 95, 77, 69, 77, 76, 74, 66, 74,
-  87, 71, 83, 102, 74, 79, 74, 91, 80, 74,
-  79, 79, 102, 74, 90, 101, 77, 79, 92, 92,
-  88, 87, 73, 86, 113, 81, 79, 82, 66, 86,
-  77, 82, 97, 84, 69, 81, 89, 73, 86, 82,
-  69, 90, 92, 72, 79, 105, 83, 75, 96, 85,
-  84, 77, 73, 81, 74, 84, 87, 86, 82, 82,
-  97, 84, 93, 100, 76, 74, 86, 74, 100, 70,
-  102, 70, 97, 131, 91, 83, 104, 72, 68, 85,
-  111, 84, 99, 100, 88, 99, 74, 96, 86, 86,
-  79, 77, 89, 82, 117, 110, 82, 90, 76, 77,
-  74, 71, 84, 93, 67, 75, 83, 84, 96, 80,
-  89, 99, 96, 84, 106, 78, 88, 59, 73, 84,
-  100, 82, 69, 73, 72, 79, 66, 70, 90, 84,
-  74, 106, 70, 75, 82, 93, 83, 71, 84, 79,
-  114, 81, 99, 95, 79, 76, 98, 90, 75, 87,
-  73, 78, 98, 73, 88, 88, 76, 74, 78, 82,
-  82, 78, 76, 83, 92, 76, 78, 75, 76, 83,
-  92, 77, 68, 88, 75, 81, 86, 85, 85, 85,
-  82, 83, 82, 80, 85, 88, 81, 78, 93, 77,
-  87, 97, 81, 73, 87, 82, 89, 79, 81, 72,
-  99, 105, 97, 79, 96, 84, 79, 93, 96, 88,
-  90, 89, 77, 98, 70, 72, 85, 83, 95, 77,
-  87, 97, 107, 94, 94, 78, 74, 83, 81, 75,
-  85, 86, 92, 76, 89, 90, 94, 97, 97, 82,
-  90, 82, 100, 85, 91, 70, 81, 86, 87, 87,
-  67, 85, 80, 82, 77, 75, 81, 74, 84, 101,
-  77, 75, 74, 89, 79, 78, 82, 80, 93, 78,
-  88, 96, 81, 91, 96, 95, 74, 89, 82, 90,
-  93, 83, 77, 84, 74, 82, 79, 81, 112, 85,
-  79, 88, 85, 77, 82, 86, 74, 82, 88, 73,
-  79, 111, 88, 74, 94, 77, 88, 76, 67, 88,
-  77, 86, 89, 79, 87, 88, 89, 72, 86, 98,
-  78, 90, 88, 76, 76, 89, 70, 81, 87, 108,
-  71, 84, 77, 78, 82, 90, 98, 89, 98, 97,
-  76, 75, 70, 70, 78, 90, 82, 78, 91, 81,
-  110, 96, 82, 79, 84, 68, 109, 75, 65, 85,
-  79, 75, 90, 83, 91, 74, 83, 79, 89, 92,
-  94, 78, 83, 87, 78, 86, 96, 68, 75, 73,
-  69, 79, 75, 67, 83, 81, 80, 80, 82, 80,
-  75, 84, 84, 102, 93, 79, 84, 83, 87, 91,
-  77, 69, 86, 98, 89, 85, 72, 73, 89, 79,
-  81, 88, 81, 77, 68, 84, 100, 85, 77, 91,
-  73, 74, 82, 87, 75, 85, 84, 78, 75, 88,
-  90, 75, 100, 78, 91, 74, 74, 76, 70, 85,
-  91, 76, 92, 89, 87, 72, 66, 97, 80, 87,
-  81, 72, 78, 92, 94, 75, 89, 89, 58, 87,
-  70, 81, 83, 85, 98, 89, 95, 84, 80, 72,
-  71, 91, 76, 87, 71, 89, 103, 81, 104, 89,
-  77, 76, 90, 78, 128, 79, 75, 82, 73, 78,
-  92, 82, 91, 71, 74, 71, 90, 87, 91, 85,
-  77, 91, 70, 81, 82, 66, 73, 75, 68, 76,
-  74, 61, 80, 90, 80, 74, 85, 87, 79, 88,
-  78, 106, 101, 78, 72, 83, 66, 91, 77, 72,
-  70, 93, 85, 83, 71, 64, 80, 73, 78, 92,
-  81, 70, 69, 76, 98, 91, 73, 89, 87, 85,
-  81, 81, 76, 84, 93, 79, 86, 78, 76, 78,
-  90, 75, 88, 80, 78, 85, 80, 84, 86, 84,
-  82, 89, 90, 77, 77, 109, 78, 81, 90, 82,
-  79, 89, 103, 81, 89, 105, 80, 81, 95, 78,
-  75, 84, 96, 88, 97, 83, 78, 83, 77, 107,
-  77, 89, 83, 78, 90, 85, 103, 107, 86, 85,
-  79, 75, 95, 81, 93, 85, 77, 73, 81, 83,
-  96, 90, 88, 88, 88, 89, 101, 83, 91, 88,
-  75, 84, 87, 73, 72, 68, 69, 83, 74, 69,
-  88, 84, 79, 92, 83, 85, 78, 86, 85, 98,
-  86, 84, 89, 87, 72, 88, 84, 81, 71, 93,
-  75, 84, 79, 76, 82, 82, 83, 87, 86, 77,
-  77, 87, 84, 93, 89, 85, 88, 96, 73, 68,
-  83, 89, 73, 83, 79, 87, 89, 74, 89, 85,
-  83, 81, 80, 80, 81, 89, 95, 91, 84, 92,
-  89, 84, 85, 87, 83, 83, 89, 89, 71, 86,
-  84, 91, 82, 92, 90, 95, 81, 95, 78, 89,
-  74, 91, 86, 83, 78, 71, 84, 79, 90, 73,
-  94, 78, 85, 92, 87, 81, 84, 75, 86, 84,
-  86, 90, 78, 64, 85, 70, 87, 98, 85, 92,
-  80, 82, 84, 93, 75, 88, 89, 87, 87, 94,
-  79, 94, 88, 76, 92, 85, 89, 89, 77, 80,
-  84, 77, 87, 80, 76, 81, 95, 69, 92, 82,
-  72, 84, 80, 85, 83, 75, 68, 89, 108, 88,
-  91, 82, 91, 94, 88, 77, 94, 80, 78, 71,
-  70, 97, 81, 82, 74, 98, 83, 70, 80, 90,
-  66, 85, 72, 84, 87, 77, 80, 92, 85, 85,
-  96, 82, 95, 85, 86, 92, 84, 92, 87, 82,
-  79, 74, 82, 85, 94, 89, 80, 80, 74, 82,
-  97, 87, 81, 95, 76, 105, 74, 92, 73, 98,
-  77, 80, 77, 64, 86, 78, 96, 65, 110, 83,
-  83, 100, 86, 69, 95, 70, 83, 95, 86, 93,
-  83, 68, 89, 71, 92, 107, 84, 86, 87, 72,
-  82, 90, 68, 88, 84, 79, 88, 88, 70, 97,
-  88, 83, 104, 84, 90, 94, 72, 74, 97, 69,
-  97, 77, 74, 82, 96, 71, 97, 79, 60, 83,
-  72, 89, 83, 91, 72, 92, 95, 86, 92, 89,
-  89, 93, 85, 80, 96, 77, 79, 69, 90, 99,
-  77, 87, 88, 86, 78, 71, 87, 93, 80, 84,
-  94, 91, 77, 77, 88, 79, 85, 84, 84, 86,
-  99, 87, 79, 87, 86, 96, 86, 77, 80, 92,
-  77, 80, 93, 90, 73, 84, 87, 92, 82, 101,
-  77, 89, 88, 88, 68, 91, 83, 96, 85, 84,
-  78, 80, 80, 84, 78, 73, 88, 76, 92, 89,
-  85, 89, 86, 74, 82, 78, 96, 92, 90, 74,
-  80, 70, 85, 97, 91, 87, 91, 91, 86, 92,
-  84, 84, 95, 87, 86, 88, 81, 86, 81, 78,
-  85, 88, 84, 85, 87, 84, 88, 87, 85, 81,
-  76, 82, 95, 76, 87, 81, 75, 82, 74, 93,
-  84, 89, 72, 84, 84, 89, 91, 84, 88, 85,
-  80, 80, 95, 76, 80, 78, 85, 83, 89, 87,
-  93, 88, 90, 77, 95, 84, 75, 85, 91, 81,
-  94, 82, 86, 83, 73, 79, 85, 81, 69, 72,
-  92, 88, 85, 78, 80, 87, 82, 77, 86, 84,
-  77, 81, 91, 85, 81, 89, 102, 88, 91, 101,
-  84, 88, 75, 91, 84, 79, 90, 94, 85, 92,
-  77, 93, 90, 86, 81, 84, 82, 80, 77, 76,
-  107, 94, 69, 85, 83, 79, 68, 75, 77, 68,
-  91, 82, 91, 74, 82, 92, 78, 92, 77, 78,
-  104, 81, 88, 80, 85, 85, 60, 69, 77, 97,
-  84, 91, 88, 99, 100, 88, 87, 74, 86, 86,
-  86, 81, 84, 95, 87, 74, 80, 78, 86, 79,
-  100, 68, 93, 84, 82, 86, 73, 87, 85, 87,
-  81, 77, 84, 75, 81, 90, 83, 85, 87, 68,
-  93, 80, 88, 82, 81, 78, 93, 86, 87, 77,
-  81, 89, 83, 81, 93, 76, 64, 76, 90, 93,
-  88, 81, 73, 93, 80, 75, 102, 78, 75, 62,
-  78, 71, 78, 94, 91, 66, 87, 94, 74, 82,
-  70, 70, 87, 103, 80, 102, 88, 82, 86, 86,
-  83, 91, 79, 75, 83, 68, 85, 80, 89, 101,
-  94, 88, 73, 90, 40, 61, 83, 80, 79, 82,
-  83, 53, 81, 83, 78, 93, 82, 74, 93, 87,
-  82, 74, 93, 85, 70, 70, 73, 96, 72, 88,
-  83, 92, 89, 91, 74, 71, 80, 78, 85, 85,
-  89, 96, 84, 85, 84, 81, 85, 77, 103, 77,
-  77, 79, 76, 90, 84, 92, 99, 95, 92, 81,
-  81, 88, 79, 90, 84, 80, 90, 62, 90, 84,
-  85, 80, 77, 81, 92, 81, 82, 77, 79, 89,
-  82, 84, 92, 76, 74, 72, 91, 91, 85, 82,
-  83, 84, 79, 78, 93, 77, 93, 76, 76, 75,
-  79, 93, 90, 64, 95, 97, 74, 86, 65, 60,
-  80, 96, 83, 91, 83, 86, 84, 95, 86, 87,
-  85, 76, 88, 72, 86, 82, 91, 101, 92, 92,
-  73, 77, 73, 61, 86, 73, 82, 68, 79, 77,
-  79, 84, 80, 87, 83, 75, 90, 85, 78, 69,
-  85, 87, 74, 77, 68, 95, 79, 85, 79, 92,
-  83, 89, 73, 80, 76, 76, 89, 86, 98, 91,
-  85, 84, 81, 81, 85, 86, 88, 76, 60, 76,
-  75, 92, 77, 93, 88, 92, 92, 76, 85, 87,
-  80, 78, 89, 80, 85, 80, 97, 92, 86, 81,
-  82, 70, 81, 83, 81, 92, 80, 89, 83, 79,
-  83, 77, 89, 72, 86, 103, 85, 76, 80, 92,
-  85, 79, 86, 71, 65, 79, 85, 78, 78, 102,
-  93, 80, 75, 98, 88, 87, 80, 84, 84, 88,
-  90, 94, 86, 83, 86, 71, 92, 86, 82, 84,
-  79, 67, 79, 51, 74, 94, 82, 69, 85, 73,
-  72, 76, 91, 70, 86, 86, 80, 79, 66, 96,
-  87, 97, 78, 91, 89, 80, 76, 71, 95, 83,
-  81, 70, 72, 87, 75, 85, 80, 86, 90, 80,
-  66, 45, 78, 83, 79, 62, 89, 95, 90, 94,
-  99, 74, 90, 76, 79, 71, 101, 76, 82, 89,
-  79, 87, 87, 93, 89, 79, 85, 95, 94, 73,
-  68, 74, 71, 60, 72, 83, 78, 88, 81, 62,
-  77, 83, 68, 79, 78, 77, 83, 70, 86, 94,
-  94, 100, 87, 81, 92, 82, 74, 87, 83, 82,
-  100, 68, 75, 72, 75, 72, 91, 70, 77, 67,
-  65, 77, 74, 87, 83, 72, 88, 104, 76, 83,
-  83, 75, 93, 49, 73, 84, 86, 81, 112, 82,
-  94, 104, 41, 92, 154, 87, 83, 129, 34, 76,
-  100, 95, 67, 80, 96, 95, 68, 68, 83, 81,
-  81, 92, 76, 89, 71, 113, 73, 76, 80, 90,
-  83, 78, 71, 65, 81, 73, 69, 78, 64, 85,
-  91, 82, 83, 81, 89, 92, 83, 109, 84, 96,
-  79, 70, 66, 118, 108, 77, 97, 91, 95, 101,
-  85, 80, 84, 94, 83, 118, 93, 92, 61, 77,
-  80, 67, 69, 94, 82, 85, 79, 68, 68, 64,
-  64, 88, 80, 71, 79, 76, 80, 85, 65, 87,
-  81, 77, 90, 86, 75, 78, 75, 85, 90, 81,
-  73, 76, 93, 73, 86, 75, 76, 60, 85, 78,
-  72, 101, 84, 102, 83, 87, 86, 79, 86, 81,
-  96, 77, 80, 86, 94, 73, 113, 90, 103, 109,
-  63, 88, 110, 97, 88, 103, 84, 65, 102, 96,
-  77, 77, 82, 79, 93, 57, 86, 78, 80, 72,
-  73, 76, 72, 102, 83, 75, 84, 120, 80, 76,
-  94, 59, 81, 73, 77, 77, 74, 140, 87, 84,
-  85, 78, 85, 92, 82, 96, 71, 110, 78, 74,
-  57, 96, 60, 71, 91, 85, 75, 83, 85, 79,
-  84, 87, 77, 102, 85, 81, 86, 83, 76, 82,
-  80, 91, 88, 80, 76, 77, 73, 85, 70, 93,
-  81, 87, 78, 96, 74, 85, 98, 63, 85, 91,
-  82, 85, 87, 80, 81, 85, 86, 74, 82, 95,
-  101, 90, 85, 89, 89, 78, 73, 93, 89, 77,
-  84, 78, 83, 73, 86, 96, 78, 85, 80, 86,
-  96, 86, 83, 82, 86, 81, 88, 50, 78, 86,
-  78, 70, 79, 87, 75, 69, 88, 73, 91, 82,
-  82, 90, 66, 96, 82, 83, 67, 97, 77, 77,
-  82, 84, 94, 89, 87, 93, 69, 76, 94, 80,
-  81, 81, 82, 81, 77, 60, 83, 83, 80, 65,
-  80, 90, 87, 85, 83, 82, 96, 78, 73, 83,
-  89, 70, 74, 86, 74, 81, 93, 89, 85, 81,
-  87, 92, 103, 69, 92, 86, 70, 93, 69, 71,
-  86, 85, 76, 79, 84, 96, 69, 81, 74, 70,
-  75, 91, 90, 85, 99, 85, 101, 77, 75, 85,
-  89, 88, 95, 86, 84, 94, 103, 108, 86, 85,
-  100, 62, 76, 71, 79, 74, 84, 93, 84, 94,
-  82, 67, 92, 93, 76, 81, 74, 76, 58, 77,
-  81, 93, 102, 88, 87, 93, 79, 73, 89, 87,
-  92, 80, 90, 107, 79, 85, 80, 83, 90, 118,
-  72, 78, 79, 71, 75, 112, 83, 88, 89, 107,
-  82, 87, 89, 76, 89, 77, 91, 72, 77, 71,
-  72, 87, 85, 77, 86, 85, 92, 74, 83, 95,
-  81, 79, 79, 94, 76, 87, 69, 103, 88, 91,
-  85, 91, 91, 73, 74, 73, 88, 97, 84, 81,
-  103, 80, 65, 82, 82, 91, 73, 74, 84, 81,
-  76, 84, 79, 84, 68, 82, 74, 64, 81, 89,
-  95, 76, 79, 75, 88, 83, 80, 88, 94, 83,
-  94, 84, 85, 99, 72, 106, 88, 82, 98, 64,
-  71, 63, 89, 73, 77, 101, 82, 111, 83, 55,
-  91, 81, 80, 80, 79, 97, 55, 79, 85, 87,
-  105, 97, 93, 88, 81, 72, 74, 91, 102, 79,
-  112, 107, 80, 90, 86, 90, 82, 97, 94, 69,
-  81, 78, 79, 86, 87, 87, 90, 108, 81, 85,
-  93, 98, 86, 92, 100, 73, 76, 76, 92, 84,
-  82, 102, 88, 90, 99, 69, 85, 94, 82, 74,
-  72, 102, 77, 88, 69, 98, 86, 94, 81, 94,
-  89, 65, 77, 72, 90, 96, 85, 83, 81, 94,
-  88, 81, 92, 83, 75, 78, 83, 78, 88, 88,
-  96, 78, 80, 81, 88, 85, 90, 83, 80, 79,
-  86, 82, 91, 76, 76, 80, 81, 87, 99, 83,
-  83, 81, 102, 82, 87, 68, 94, 88, 76, 93,
-  82, 88, 77, 79, 90, 82, 82, 87, 86, 90,
-  85, 85, 87, 83, 83, 75, 92, 84, 91, 94,
-  92, 82, 91, 96, 87, 70, 96, 86, 83, 87,
-  81, 78, 80, 78, 92, 89, 81, 95, 84, 92,
-  84, 91, 67, 82, 88, 93, 88, 71, 81, 82,
-  81, 84, 83, 70, 97, 86, 72, 89, 78, 87,
-  85, 89, 83, 84, 85, 90, 83, 86, 85, 85,
-  85, 70, 78, 73, 80, 83, 81, 85, 90, 99,
-  68, 73, 101, 93, 88, 93, 79, 96, 84, 74,
-  106, 79, 77, 68, 81, 75, 93, 83, 93, 79,
-  86, 80, 90, 75, 83, 78, 86, 82, 80, 84,
-  84, 79, 75, 82, 99, 92, 105, 79, 85, 86,
-  102, 82, 80, 58, 92, 94, 75, 83, 84, 77,
-  92, 88, 95, 87, 88, 87, 80, 85, 81, 88,
-  79, 79, 81, 67, 93, 91, 98, 110, 84, 94,
-  69, 98, 89, 70, 109, 71, 76, 85, 81, 82,
-  86, 82, 89, 94, 76, 89, 81, 77, 88, 82,
-  72, 90, 75, 92, 74, 79, 70, 78, 87, 88,
-  70, 74, 83, 87, 80, 88, 73, 84, 82, 92,
-  78, 82, 84, 90, 85, 85, 88, 88, 83, 73,
-  72, 71, 77, 88, 80, 82, 90, 98, 64, 75,
-  90, 90, 89, 94, 81, 90, 82, 81, 101, 95,
-  76, 71, 84, 78, 92, 84, 95, 85, 79, 86,
-  93, 85, 91, 78, 91, 74, 85, 82, 72, 71,
-  77, 87, 84, 93, 99, 78, 82, 87, 91, 91,
-  83, 61, 77, 90, 77, 82, 80, 81, 79, 82,
-  86, 87, 88, 87, 84, 86, 80, 85, 87, 90,
-  81, 72, 81, 88, 94, 93, 83, 94, 94, 88,
-  79, 73, 106, 76, 80, 79, 79, 85, 85, 79,
-  88, 98, 82, 82, 87, 85, 83, 75, 73, 90,
-  70, 82, 80, 78, 75, 91, 85, 84, 80, 71,
-  91, 88, 97, 79, 74, 87, 78, 91, 82, 84,
-  79, 94, 87, 88, 86, 90, 86, 92, 76, 72,
-  73, 78, 80, 79, 84, 98, 73, 73, 86, 91,
-  90, 93, 89, 98, 92, 89, 83, 83, 81, 80,
-  80, 83, 84, 94, 92, 86, 75, 83, 90, 81,
-  87, 83, 82, 73, 78, 86, 93, 79, 84, 86,
-  85, 84, 91, 80, 81, 87, 92, 76, 96, 88,
-  91, 79, 88, 84, 79, 81, 75, 83, 84, 89,
-  81, 85, 81, 84, 82, 82, 81, 89, 72, 81,
-  81, 87, 95, 81, 79, 84, 99, 85, 97, 74,
-  101, 85, 80, 83, 74, 89, 83, 74, 85, 85,
-  76, 94, 86, 100, 81, 93, 77, 93, 82, 91,
-  96, 69, 72, 89, 78, 94, 85, 73, 90, 85,
-  68, 90, 69, 93, 89, 97, 82, 92, 81, 83,
-  77, 81, 88, 77, 82, 73, 78, 77, 69, 98,
-  86, 75, 80, 84, 77, 71, 85, 89, 92, 86,
-  86, 91, 102, 94, 88, 76, 78, 73, 76, 84,
-  86, 90, 80, 80, 85, 95, 87, 72, 84, 84,
-  82, 74, 74, 88, 94, 79, 86, 86, 105, 86,
-  82, 69, 77, 93, 86, 78, 86, 93, 90, 76,
-  87, 63, 75, 71, 80, 91, 90, 82, 96, 82,
-  74, 74, 80, 85, 72, 79, 69, 73, 74, 91,
-  98, 100, 68, 94, 83, 73, 102, 84, 126, 72,
-  74, 73, 73, 98, 91, 79, 79, 88, 71, 71,
-  86, 89, 95, 90, 86, 101, 70, 90, 77, 72,
-  63, 88, 82, 88, 71, 66, 73, 86, 76, 80,
-  61, 78, 92, 99, 80, 96, 83, 82, 76, 79,
-  89, 83, 81, 70, 71, 72, 76, 103, 75, 73,
-  78, 72, 77, 73, 67, 90, 78, 79, 85, 82,
-  86, 96, 85, 84, 78, 70, 83, 90, 87, 86,
-  89, 84, 77, 87, 93, 81, 92, 87, 81, 68,
-  80, 89, 84, 73, 88, 91, 90, 89, 82, 71,
-  77, 90, 80, 95, 83, 101, 84, 81, 92, 73,
-  74, 78, 75, 84, 75, 87, 91, 83, 77, 78,
-  80, 81, 82, 91, 71, 76, 72, 90, 98, 84,
-  69, 94, 104, 72, 93, 85, 121, 91, 77, 73,
-  76, 99, 85, 75, 87, 92, 80, 74, 90, 95,
-  87, 76, 81, 94, 72, 86, 75, 74, 69, 103,
-  85, 89, 79, 70, 83, 85, 96, 76, 62, 77,
-  87, 98, 83, 100, 81, 82, 78, 84, 88, 84,
-  81, 86, 77, 82, 75, 95, 82, 78, 74, 78,
-  84, 71, 69, 94, 87, 81, 80, 97, 99, 86,
-  80, 81, 81, 75, 78, 92, 78, 95, 96, 93,
-  61, 88, 92, 83, 92, 90, 94, 74, 79, 82,
-  96, 74, 92, 94, 80, 84, 82, 87, 83, 93,
-  83, 78, 88, 100, 80, 85, 99, 83, 89, 81,
-  70, 82, 66, 82, 94, 89, 73, 87, 88, 76,
-  90, 74, 78, 78, 84, 75, 104, 83, 80, 80,
-  103, 80, 81, 90, 89, 90, 79, 77, 84, 93,
-  73, 82, 74, 85, 88, 81, 82, 89, 81, 93,
-  83, 88, 85, 90, 74, 85, 82, 80, 86, 85,
-  85, 81, 94, 76, 75, 95, 59, 89, 88, 100,
-  78, 103, 86, 90, 85, 83, 95, 81, 77, 88,
-  75, 84, 80, 93, 80, 83, 77, 77, 85, 69,
-  88, 96, 89, 77, 61, 83, 89, 88, 66, 76,
-  86, 72, 74, 99, 74, 97, 69, 74, 71, 92,
-  87, 89, 86, 105, 99, 75, 87, 72, 90, 70,
-  98, 91, 105, 79, 80, 71, 76, 101, 71, 86,
-  87, 102, 72, 66, 112, 75, 85, 71, 75, 84,
-  67, 73, 117, 78, 69, 68, 87, 73, 84, 68,
-  99, 68, 82, 84, 105, 103, 80, 88, 99, 69,
-  83, 119, 105, 93, 79, 81, 91, 99, 78, 98,
-  77, 80, 86, 60, 78, 84, 87, 86, 84, 91,
-  83, 85, 50, 78, 83, 80, 81, 78, 92, 74,
-  78, 76, 82, 85, 50, 76, 93, 104, 76, 109,
-  95, 83, 77, 84, 83, 88, 85, 80, 77, 86,
-  93, 87, 71, 95, 76, 73, 83, 77, 68, 101,
-  79, 71, 74, 75, 69, 86, 70, 78, 86, 69,
-  80, 96, 80, 89, 84, 78, 63, 89, 93, 91,
-  95, 98, 93, 72, 70, 80, 77, 70, 93, 94,
-  93, 89, 83, 77, 81, 94, 79, 94, 81, 102,
-  78, 71, 107, 74, 84, 81, 83, 82, 63, 85,
-  98, 83, 72, 73, 85, 77, 90, 82, 100, 79,
-  84, 80, 98, 86, 78, 87, 99, 76, 73, 106,
-  107, 96, 94, 74, 90, 98, 72, 95, 74, 80,
-  98, 66, 83, 95, 85, 72, 77, 91, 87, 88,
-  58, 88, 90, 90, 81, 80, 90, 77, 83, 77,
-  92, 86, 55, 75, 82, 101, 77, 96, 96, 83,
-  82, 90, 83, 90, 82, 93, 74, 86, 83, 79,
-  71, 93, 81, 74, 86, 74, 77, 104, 88, 79,
-  87, 75, 100, 99, 82, 90, 79, 81, 79, 95,
-  84, 85, 87, 81, 89, 89, 84, 93, 84, 82,
-  83, 78, 97, 76, 77, 93, 76, 80, 99, 91,
-  89, 77, 88, 69, 91, 104, 81, 103, 87, 89,
-  82, 78, 73, 87, 85, 83, 72, 75, 73, 81,
-  82, 81, 88, 77, 76, 87, 77, 80, 93, 80,
-  91, 75, 83, 84, 105, 78, 84, 75, 79, 105,
-  85, 83, 70, 97, 73, 80, 83, 73, 92, 75,
-  86, 82, 78, 93, 85, 63, 142, 83, 80, 89,
-  81, 92, 83, 89, 88, 79, 83, 91, 87, 77,
-  89, 78, 76, 85, 69, 74, 73, 85, 82, 77,
-  78, 89, 82, 73, 87, 91, 87, 90, 84, 88,
-  82, 86, 77, 86, 83, 166, 76, 80, 92, 76,
-  86, 81, 94, 80, 80, 78, 73, 76, 83, 77,
-  94, 91, 88, 82, 87, 87, 72, 92, 75, 80,
-  80, 69, 80, 95, 68, 70, 101, 92, 103, 87,
-  83, 68, 93, 74, 81, 78, 85, 88, 80, 86,
-  84, 87, 88, 81, 80, 85, 63, 77, 85, 91,
-  84, 73, 77, 82, 77, 79, 98, 72, 82, 81,
-  84, 85, 88, 80, 73, 79, 74, 82, 99, 87,
-  73, 84, 82, 78, 81, 84, 95, 85, 81, 83,
-  75, 85, 89, 57, 92, 76, 89, 83, 83, 84,
-  74, 96, 79, 88, 77, 95, 82, 85, 69, 79,
-  56, 88, 76, 78, 68, 86, 78, 80, 87, 78,
-  73, 104, 83, 92, 80, 105, 80, 87, 78, 81,
-  69, 78, 81, 153, 67, 86, 84, 72, 91, 89,
-  90, 80, 79, 81, 78, 100, 86, 86, 80, 86,
-  94, 86, 87, 87, 89, 94, 78, 82, 83, 80,
-  79, 90, 83, 82, 87, 88, 90, 87, 86, 72,
-  87, 63, 88, 95, 73, 93, 87, 79, 85, 84,
-  77, 82, 81, 89, 73, 80, 82, 81, 92, 78,
-  77, 71, 76, 80, 97, 76, 86, 86, 81, 84,
-  105, 77, 78, 79, 77, 86, 94, 81, 82, 86,
-  81, 81, 81, 95, 100, 76, 85, 84, 69, 83,
-  84, 74, 67, 86, 88, 90, 81, 98, 87, 86,
-  95, 82, 82, 93, 78, 72, 81, 87, 80, 84,
-  72, 81, 79, 78, 77, 80, 88, 89, 82, 142,
-  85, 82, 90, 87, 86, 86, 82, 86, 84, 95,
-  86, 146, 82, 79, 89, 84, 84, 89, 86, 87,
-  81, 74, 72, 72, 90, 81, 84, 90, 83, 80,
-  81, 90, 73, 72, 87, 87, 91, 75, 79, 88,
-  71, 70, 108, 93, 102, 80, 91, 66, 97, 103,
-  78, 89, 86, 86, 82, 78, 74, 91, 85, 81,
-  82, 82, 69, 85, 88, 89, 85, 80, 85, 86,
-  70, 80, 90, 86, 95, 80, 85, 84, 80, 76,
-  78, 86, 80, 83, 83, 82, 67, 89, 81, 73,
-  74, 64, 92, 83, 86, 88, 83, 88, 84, 98,
-  138, 77, 80, 77, 87, 84, 81, 84, 69, 83,
-  83, 95, 91, 80, 79, 85, 64, 89, 73, 84,
-  76, 90, 82, 85, 78, 87, 74, 51, 89, 90,
-  80, 103, 81, 82, 85, 75, 67, 73, 75, 97,
-  63, 92, 89, 84, 74, 75, 97, 80, 85, 72,
-  62, 70, 90, 74, 95, 81, 77, 74, 87, 87,
-  66, 81, 80, 89, 82, 75, 84, 89, 63, 66,
-  123, 92, 121, 98, 85, 71, 99, 68, 87, 88,
-  88, 87, 78, 83, 81, 94, 97, 78, 87, 92,
-  63, 79, 88, 80, 81, 75, 80, 81, 71, 73,
-  86, 87, 99, 83, 75, 93, 60, 80, 78, 101,
-  82, 68, 80, 90, 71, 81, 90, 75, 81, 88,
-  84, 104, 80, 87, 77, 87, 83, 103, 69, 75,
-  79, 72, 87, 78, 57, 96, 64, 96, 77, 111,
-  91, 95, 75, 83, 61, 92, 81, 92, 70, 89,
-  85, 88, 78, 79, 78, 70, 80, 85, 81, 131,
-  83, 78, 77, 77, 48, 79, 69, 63, 68, 106,
-  85, 77, 83, 82, 86, 79, 80, 74, 75, 77,
-  84, 83, 77, 78, 90, 80, 82, 88, 80, 86,
-  79, 85, 85, 76, 81, 88, 79, 71, 94, 79,
-  93, 96, 88, 67, 91, 59, 87, 81, 87, 86,
-  85, 76, 92, 88, 81, 80, 90, 90, 69, 85,
-  85, 84, 88, 74, 88, 87, 72, 78, 90, 81,
-  88, 88, 84, 83, 92, 75, 73, 92, 79, 78,
-  93, 78, 82, 82, 84, 77, 79, 97, 95, 80,
-  85, 89, 74, 85, 87, 109, 64, 85, 81, 83,
-  82, 87, 90, 79, 80, 83, 83, 96, 85, 74,
-  77, 85, 70, 86, 74, 85, 80, 83, 77, 86,
-  85, 88, 75, 127, 83, 84, 95, 96, 81, 81,
-  79, 74, 73, 77, 79, 85, 68, 83, 94, 80,
-  77, 93, 87, 94, 79, 73, 76, 93, 87, 84,
-  79, 88, 87, 82, 79, 92, 87, 74, 84, 84,
-  99, 78, 82, 86, 91, 77, 90, 86, 88, 88,
-  88, 69, 99, 118, 78, 78, 78, 88, 78, 76,
-  79, 91, 80, 84, 79, 86, 81, 82, 90, 82,
-  89, 79, 84, 90, 70, 79, 84, 84, 93, 81,
-  89, 79, 97, 75, 79, 81, 78, 82, 94, 81,
-  79, 81, 83, 83, 73, 64, 92, 79, 86, 85,
-  83, 89, 83, 137, 155, 78, 83, 85, 82, 100,
-  102, 84, 83, 83, 92, 88, 89, 76, 80, 101,
-  84, 85, 100, 85, 85, 98, 76, 92, 70, 92,
-  89, 58, 88, 86, 83, 90, 91, 85, 92, 77,
-  72, 78, 74, 74, 85, 84, 97, 78, 82, 93,
-  86, 89, 79, 69, 72, 79, 83, 81, 89, 84,
-  83, 81, 81, 90, 81, 78, 80, 92, 99, 79,
-  86, 77, 84, 69, 94, 86, 84, 100, 87, 73,
-  91, 82, 84, 70, 78, 86, 75, 79, 79, 96,
-  79, 88, 84, 89, 69, 81, 87, 84, 85, 78,
-  83, 86, 66, 70, 85, 79, 93, 80, 83, 78,
-  85, 75, 83, 84, 78, 76, 85, 80, 79, 73,
-  87, 77, 75, 80, 85, 90, 85, 86, 83, 93,
-  81, 158, 111, 76, 85, 86, 79, 89, 93, 84,
-  77, 86, 93, 90, 88, 80, 78, 87, 65, 83,
-  82, 86, 81, 93, 76, 89, 73, 84, 81, 92,
-  88, 91, 97, 104, 84, 84, 84, 74, 63, 72,
-  73, 52, 72, 86, 91, 82, 82, 84, 87, 90,
-  78, 75, 79, 98, 82, 82, 79, 80, 89, 82,
-  80, 93, 92, 80, 80, 86, 94, 78, 85, 88,
-  95, 81, 76, 82, 84, 99, 88, 74, 88, 69,
-  84, 69, 81, 87, 80, 75, 87, 90, 77, 84,
-  87, 92, 77, 83, 88, 83, 92, 77, 85, 87,
-  68, 77, 85, 82, 89, 84, 89, 78, 98, 74,
-  82, 86, 77, 86, 86, 80, 84, 81, 89, 86,
-  73, 90, 92, 80, 87, 86, 77, 92, 83, 152,
-  84, 87, 89, 89, 79, 94, 105, 84, 86, 82,
-  94, 87, 85, 77, 78, 90, 87, 83, 100, 83,
-  85, 93, 76, 91, 80, 90, 86, 130, 89, 84,
-  107, 89, 94, 84, 83, 78, 76, 78, 81, 66,
-  86, 81, 78, 80, 73, 91, 80, 79, 67, 95,
-  84, 82, 77, 99, 87, 72, 68, 87, 74, 71,
-  84, 91, 87, 70, 77, 88, 79, 68, 101, 84,
-  111, 91, 79, 83, 77, 82, 70, 90, 111, 86,
-  73, 72, 88, 88, 82, 62, 78, 70, 93, 86,
-  83, 64, 141, 72, 85, 88, 83, 70, 94, 91,
-  116, 75, 82, 69, 126, 76, 74, 77, 91, 79,
-  74, 77, 70, 115, 87, 84, 74, 67, 73, 89,
-  101, 94, 86, 92, 73, 81, 77, 80, 85, 85,
-  95, 80, 72, 99, 92, 68, 90, 69, 97, 84,
-  90, 91, 88, 72, 92, 91, 88, 79, 71, 90,
-  91, 77, 74, 75, 71, 85, 115, 102, 74, 80,
-  76, 87, 94, 95, 69, 74, 72, 90, 85, 83,
-  74, 86, 69, 95, 79, 85, 72, 95, 92, 86,
-  74, 100, 84, 66, 76, 95, 79, 77, 83, 90,
-  84, 71, 83, 84, 81, 74, 97, 88, 73, 76,
-  65, 86, 76, 86, 57, 89, 88, 87, 72, 74,
-  78, 80, 86, 68, 83, 69, 93, 77, 77, 64,
-  132, 74, 90, 89, 79, 61, 99, 89, 100, 81,
-  85, 68, 125, 78, 80, 74, 87, 77, 77, 65,
-  72, 105, 88, 86, 78, 71, 71, 86, 94, 93,
-  90, 88, 74, 85, 76, 82, 83, 78, 84, 85,
-  75, 92, 82, 71, 90, 77, 91, 88, 87, 86,
-  86, 66, 94, 90, 85, 66, 75, 86, 93, 79,
-  74, 75, 72, 82, 105, 82, 76, 79, 77, 81,
-  78, 92, 74, 78, 74, 84, 85, 67, 76, 84,
-  74, 93, 80, 78, 64, 90, 89, 85, 77, 103,
-  85, 76, 70, 84, 69, 74, 81, 91, 80, 68,
-  78, 89, 76, 69, 107, 86, 96, 77, 81, 87,
-  77, 84, 71, 91, 118, 85, 73, 71, 88, 87,
-  84, 63, 78, 69, 92, 76, 86, 66, 139, 79,
-  87, 85, 86, 65, 95, 93, 110, 77, 83, 74,
-  123, 75, 79, 74, 90, 76, 78, 84, 67, 111,
-  90, 81, 80, 70, 80, 91, 109, 88, 88, 94,
-  75, 96, 79, 81, 82, 77, 92, 86, 75, 94,
-  89, 70, 89, 68, 96, 87, 91, 88, 85, 73,
-  92, 91, 90, 79, 70, 90, 99, 75, 74, 77,
-  72, 86, 108, 91, 74, 84, 76, 90, 78, 94,
-  73, 73, 72, 91, 83, 83, 82, 79, 73, 87,
-  81, 82, 79, 83, 82, 81, 85, 85, 95, 84,
-  79, 78, 72, 88, 89, 84, 86, 75, 76, 94,
-  82, 89, 85, 84, 95, 82, 81, 81, 89, 77,
-  74, 79, 80, 82, 88, 80, 87, 76, 87, 71,
-  76, 87, 76, 80, 85, 83, 106, 75, 98, 87,
-  89, 86, 88, 78, 92, 77, 86, 71, 102, 79,
-  79, 90, 86, 83, 76, 74, 78, 93, 90, 69,
-  85, 84, 71, 87, 86, 76, 85, 65, 83, 77,
-  79, 82, 83, 84, 68, 88, 83, 78, 80, 87,
-  82, 78, 83, 85, 89, 82, 76, 77, 89, 88,
-  81, 78, 91, 88, 95, 84, 62, 83, 87, 85,
-  81, 91, 87, 84, 79, 80, 87, 87, 84, 84,
-  85, 89, 82, 92, 81, 87, 75, 87, 79, 82,
-  85, 83, 81, 86, 83, 81, 90, 89, 87, 85,
-  80, 89, 90, 82, 85, 79, 77, 87, 78, 95,
-  81, 83, 70, 77, 83, 87, 87, 76, 70, 79,
-  80, 86, 84, 84, 85, 77, 85, 73, 76, 80,
-  76, 80, 84, 83, 99, 82, 99, 86, 90, 83,
-  91, 79, 88, 79, 80, 71, 103, 82, 80, 93,
-  80, 81, 81, 68, 77, 88, 90, 70, 86, 83,
-  72, 74, 84, 77, 84, 68, 85, 84, 82, 81,
-  81, 75, 59, 85, 84, 75, 76, 90, 80, 85,
-  79, 86, 87, 81, 70, 77, 91, 88, 80, 71,
-  86, 83, 93, 80, 70, 85, 90, 79, 78, 81,
-  74, 85, 81, 76, 74, 86, 86, 86, 88, 83,
-  80, 87, 83, 92, 84, 86, 82, 85, 76, 79,
-  85, 83, 85, 87, 93, 89, 79, 80, 72, 88,
-  90, 83, 84, 75, 77, 92, 72, 87, 86, 81,
-  90, 77, 90, 85, 88, 77, 72, 84, 88, 84,
-  80, 79, 85, 81, 82, 73, 74, 82, 76, 83,
-  89, 80, 106, 84, 94, 85, 93, 84, 87, 76,
-  96, 71, 82, 75, 102, 74, 78, 91, 83, 78,
-  83, 76, 77, 90, 87, 68, 86, 82, 78, 76,
-  88, 75, 82, 65, 82, 86, 81, 81, 83, 77,
-  71, 85, 84, 71, 82, 85, 81, 76, 83, 85,
-  89, 83, 73, 92, 87, 90, 81, 82, 91, 85,
-  93, 80, 70, 86, 87, 83, 83, 82, 79, 86,
-  81, 84, 77, 87, 82, 82, 87, 90, 80, 90,
-  83, 82, 76, 90, 87, 85, 82, 74, 78, 82,
-  85, 68, 91, 87, 89, 81, 82, 91, 92, 85,
-  82, 88, 85, 88, 85, 98, 90, 83, 86, 84,
-  85, 82, 100, 84, 85, 79, 80, 79, 84, 88,
-  81, 86, 90, 89, 85, 98, 76, 83, 86, 98,
-  68, 88, 93, 91, 91, 95, 87, 78, 76, 77,
-  88, 77, 85, 75, 82, 90, 88, 87, 84, 82,
-  92, 88, 83, 87, 82, 92, 83, 89, 81, 80,
-  87, 70, 88, 89, 86, 83, 81, 77, 91, 88,
-  73, 82, 80, 96, 84, 85, 80, 84, 86, 84,
-  92, 89, 87, 83, 78, 78, 93, 81, 97, 92,
-  74, 99, 94, 87, 99, 82, 95, 84, 85, 87,
-  88, 84, 83, 88, 91, 80, 88, 92, 85, 85,
-  86, 88, 81, 94, 84, 74, 69, 82, 81, 66,
-  82, 94, 91, 84, 88, 88, 89, 88, 83, 89,
-  91, 79, 80, 100, 88, 79, 74, 83, 86, 83,
-  92, 79, 84, 85, 84, 84, 85, 84, 83, 85,
-  84, 88, 80, 88, 73, 89, 89, 92, 67, 88,
-  84, 87, 88, 94, 89, 81, 77, 79, 84, 79,
-  85, 76, 86, 92, 85, 90, 85, 86, 91, 88,
-  79, 86, 81, 89, 83, 80, 78, 82, 84, 77,
-  88, 90, 87, 86, 85, 77, 86, 79, 74, 80,
-  78, 98, 82, 87, 81, 84, 82, 77, 90, 88,
-  88, 82, 81, 76, 86, 79, 87, 86, 83, 98,
-  92, 80, 98, 86, 87, 85, 82, 86, 86, 86,
-  78, 86, 89, 81, 87, 92, 86, 93, 94, 90,
-  85, 92, 82, 70, 78, 83, 83, 69, 85, 93,
-  88, 81, 80, 89, 91, 88, 86, 87, 90, 85,
-  81, 92, 90, 83, 80, 82, 82, 82, 100, 74,
-  83, 90, 81, 82, 83, 85, 82, 87, 79, 90,
-  88, 96, 76, 88, 90, 94, 69, 89, 88, 87,
-  90, 91, 88, 79, 78, 76, 87, 78, 80, 73,
-  88, 90, 88, 90, 86, 90, 82, 83, 84, 87,
-  84, 94, 86, 74, 79, 80, 87, 67, 88, 85,
-  85, 83, 86, 78, 92, 86, 76, 72, 82, 94,
-  82, 83, 82, 84, 86, 84, 93, 88, 83, 85,
-  84, 83, 98, 79, 93, 90, 81, 99, 89, 77,
-  97, 85, 89, 83, 84, 90, 92, 85, 81, 86,
-  93, 85, 87, 92, 80, 86, 90, 83, 90, 88,
-  76, 76, 68, 76, 79, 75, 101, 80, 83, 92,
-  76, 70, 81, 71, 72, 84, 97, 81, 81, 74,
-  79, 78, 102, 77, 82, 94, 78, 90, 70, 81,
-  83, 84, 94, 82, 79, 76, 83, 85, 81, 76,
-  84, 89, 81, 75, 83, 107, 81, 77, 74, 104,
-  90, 73, 91, 83, 88, 75, 82, 71, 83, 63,
-  85, 97, 92, 90, 91, 71, 88, 81, 79, 90,
-  87, 86, 87, 78, 74, 79, 73, 92, 83, 81,
-  85, 82, 73, 80, 77, 84, 78, 80, 83, 71,
-  83, 77, 90, 84, 76, 92, 82, 83, 93, 81,
-  96, 96, 89, 66, 86, 88, 81, 100, 79, 86,
-  75, 86, 91, 91, 70, 86, 74, 85, 84, 72,
-  89, 78, 78, 84, 128, 88, 113, 82, 76, 76,
-  64, 86, 77, 64, 121, 86, 85, 76, 69, 36,
-  88, 61, 75, 106, 78, 70, 80, 70, 64, 84,
-  94, 78, 84, 82, 68, 98, 79, 97, 88, 87,
-  95, 114, 77, 74, 73, 84, 77, 63, 82, 100,
-  80, 85, 77, 129, 79, 91, 44, 97, 44, 72,
-  98, 77, 91, 71, 74, 67, 82, 79, 85, 85,
-  80, 76, 118, 72, 63, 77, 81, 69, 89, 109,
-  86, 67, 87, 70, 64, 81, 96, 77, 97, 117,
-  98, 76, 63, 89, 79, 68, 73, 73, 86, 71,
-  85, 82, 78, 89, 77, 84, 85, 74, 91, 105,
-  77, 53, 105, 82, 68, 101, 91, 81, 91, 80,
-  84, 87, 77, 87, 76, 75, 103, 71, 72, 80,
-  79, 76, 106, 81, 90, 90, 81, 75, 71, 78,
-  75, 78, 87, 94, 79, 94, 84, 73, 84, 66,
-  90, 82, 83, 87, 77, 74, 82, 74, 87, 75,
-  95, 90, 73, 78, 66, 85, 88, 81, 82, 79,
-  76, 78, 76, 82, 87, 89, 83, 85, 85, 71,
-  85, 89, 87, 78, 79, 64, 94, 75, 80, 90,
-  98, 77, 81, 77, 83, 65, 93, 110, 84, 87,
-  86, 78, 97, 83, 84, 90, 89, 90, 81, 80,
-  68, 76, 76, 70, 78, 74, 104, 82, 71, 83,
-  80, 93, 83, 82, 81, 75, 88, 76, 91, 88,
-  70, 95, 91, 81, 92, 82, 78, 88, 87, 75,
-  91, 96, 79, 83, 87, 83, 88, 84, 87, 91,
-  85, 85, 79, 86, 78, 78, 87, 80, 79, 86,
-  100, 89, 91, 95, 72, 77, 74, 81, 84, 77,
-  99, 93, 81, 80, 71, 70, 81, 72, 80, 89,
-  94, 85, 95, 74, 82, 82, 101, 96, 85, 94,
-  78, 83, 89, 82, 102, 92, 79, 70, 89, 76,
-  80, 77, 80, 94, 91, 87, 82, 76, 79, 98,
-  89, 74, 76, 83, 86, 74, 91, 92, 91, 83,
-  71, 73, 89, 60, 82, 106, 81, 79, 87, 73,
-  91, 83, 83, 92, 90, 85, 73, 76, 71, 75,
-  70, 92, 83, 81, 81, 80, 67, 89, 78, 69,
-  82, 91, 82, 71, 91, 80, 82, 76, 81, 74,
-  80, 82, 78, 86, 86, 95, 89, 75, 93, 92,
-  81, 101, 89, 75, 83, 93, 97, 86, 74, 86,
-  82, 89, 82, 76, 91, 76, 78, 83, 118, 85,
-  113, 92, 77, 76, 65, 88, 76, 65, 124, 88,
-  88, 69, 66, 43, 77, 63, 84, 107, 82, 71,
-  80, 71, 66, 87, 96, 81, 81, 77, 74, 99,
-  97, 97, 95, 88, 98, 114, 93, 75, 83, 78,
-  85, 74, 89, 101, 82, 88, 75, 115, 79, 91,
-  51, 106, 42, 75, 99, 79, 79, 80, 67, 66,
-  86, 75, 77, 90, 73, 61, 112, 68, 70, 84,
-  86, 76, 83, 102, 75, 66, 86, 72, 65, 79,
-  90, 70, 91, 106, 97, 71, 69, 77, 87, 75,
-  67, 72, 91, 76, 89, 73, 81, 82, 71, 83,
-  87, 72, 80, 107, 80, 57, 108, 80, 73, 97,
-  89, 64, 92, 82, 84, 81, 81, 86, 80, 74,
-  101, 72, 75, 73, 87, 85, 86, 87, 88, 93,
-  78, 76, 80, 85, 81, 80, 100, 80, 81, 84,
-  78, 77, 83, 69, 87, 76, 92, 85, 79, 73,
-  85, 79, 90, 82, 86, 88, 74, 83, 88, 88,
-  113, 87, 97, 65, 84, 83, 84, 78, 85, 95,
-  82, 89, 88, 72, 77, 75, 88, 79, 84, 81,
-  94, 75, 86, 93, 90, 90, 73, 78, 83, 68,
-  76, 104, 79, 76, 100, 78, 102, 83, 87, 85,
-  91, 85, 80, 82, 71, 76, 76, 75, 77, 70,
-  101, 76, 70, 85, 80, 81, 85, 92, 85, 75,
-  92, 80, 100, 77, 78, 92, 87, 80, 79, 77,
-  71, 89, 87, 82, 81, 88, 82, 87, 80, 67,
-  97, 88, 92, 87, 85, 88, 89, 87, 79, 76,
-  90, 79, 83, 89, 99, 87, 79, 99, 79, 75,
-  71, 75, 84, 68, 92, 91, 77, 72, 72, 64,
-  81, 82, 85, 84, 92, 80, 89, 72, 89, 81,
-  93, 93, 91, 88, 93, 82, 90, 90, 115, 91,
-  69, 78, 90, 71, 72, 76, 77, 91, 101, 90,
-  84, 67, 83, 99, 86, 76, 80, 66, 90, 79,
-  85, 86, 94, 82, 79, 61, 91, 61, 88, 89,
-  82, 80, 95, 74, 85, 84, 82, 88, 78, 91,
-  69, 78, 71, 88, 70, 84, 81, 84, 80, 84,
-  80, 87, 91, 76, 86, 86, 88, 74, 97, 75,
-  78, 75, 76, 80, 79, 81, 79, 79, 89, 87,
-  87, 74, 96, 85, 78, 90, 88, 79, 83, 90,
-  92, 87, 80, 83, 80, 80, 92, 82, 83, 86,
-  87, 88, 105, 89, 84, 102, 78, 74, 71, 85,
-  83, 54, 108, 69, 84, 72, 71, 54, 85, 71,
-  86, 90, 86, 78, 82, 73, 78, 92, 83, 84,
-  84, 82, 82, 91, 117, 100, 117, 89, 83, 98,
-  85, 75, 84, 73, 78, 86, 102, 111, 93, 76,
-  76, 85, 83, 88, 74, 84, 64, 76, 86, 85,
-  91, 87, 69, 51, 76, 72, 88, 79, 84, 68,
-  103, 71, 80, 82, 78, 72, 75, 115, 56, 71,
-  80, 71, 77, 86, 78, 74, 83, 98, 70, 82,
-  79, 79, 93, 82, 78, 67, 98, 77, 84, 75,
-  70, 79, 73, 83, 80, 80, 82, 88, 92, 71,
-  97, 73, 74, 86, 66, 77, 103, 89, 89, 84,
-  88, 90, 80, 72, 98, 77, 77, 99, 89, 85,
-  79, 87, 74, 89, 84, 78, 76, 82, 82, 76,
-  99, 75, 81, 75, 73, 74, 84, 75, 82, 74,
-  94, 84, 79, 76, 85, 81, 83, 72, 86, 85,
-  87, 88, 89, 92, 121, 87, 93, 75, 90, 76,
-  92, 78, 76, 88, 93, 94, 87, 69, 86, 88,
-  83, 80, 87, 88, 95, 84, 85, 83, 91, 86,
-  85, 68, 88, 64, 85, 90, 85, 87, 91, 75,
-  89, 83, 83, 80, 79, 85, 83, 77, 75, 94,
-  76, 78, 76, 76, 90, 82, 84, 80, 87, 85,
-  85, 88, 84, 76, 94, 77, 98, 73, 73, 84,
-  86, 78, 74, 74, 71, 88, 82, 76, 79, 80,
-  82, 82, 83, 78, 104, 86, 89, 84, 84, 85,
-  85, 80, 94, 80, 84, 87, 80, 106, 84, 93,
-  76, 75, 75, 87, 80, 78, 74, 78, 91, 80,
-  64, 97, 80, 83, 84, 101, 75, 66, 79, 76,
-  72, 64, 90, 77, 107, 98, 92, 79, 87, 83,
-  76, 95, 95, 87, 114, 80, 79, 92, 83, 87,
-  76, 75, 88, 92, 81, 76, 94, 86, 86, 79,
-  77, 110, 87, 92, 97, 83, 74, 85, 97, 81,
-  82, 73, 93, 73, 71, 94, 108, 82, 83, 89,
-  67, 79, 74, 73, 99, 75, 84, 86, 81, 95,
-  88, 80, 89, 89, 86, 81, 89, 94, 80, 74,
-  89, 84, 83, 78, 86, 88, 95, 91, 87, 78,
-  85, 90, 80, 85, 77, 72, 77, 80, 76, 77,
-  84, 90, 49, 90, 87, 92, 83, 94, 81, 73,
-  84, 95, 74, 79, 81, 111, 68, 91, 74, 90,
-  77, 85, 76, 85, 79, 83, 95, 58, 66, 93,
-  73, 84, 78, 87, 74, 79, 88, 84, 80, 77,
-  88, 86, 79, 107, 85, 79, 84, 85, 87, 100,
-  83, 85, 115, 81, 84, 99, 81, 81, 89, 78,
-  84, 97, 85, 75, 90, 82, 87, 84, 77, 101,
-  94, 72, 85, 84, 76, 86, 81, 74, 68, 83,
-  87, 76, 69, 77, 117, 83, 84, 80, 80, 86,
-  75, 94, 90, 89, 82, 86, 83, 84, 85, 71,
-  83, 90, 61, 78, 88, 82, 85, 71, 92, 80,
-  85, 88, 88, 90, 86, 99, 84, 77, 85, 86,
-  83, 83, 84, 73, 76, 76, 80, 79, 67, 91,
-  60, 83, 90, 86, 90, 89, 81, 80, 81, 87,
-  76, 92, 79, 104, 72, 87, 83, 83, 86, 94,
-  82, 77, 78, 78, 89, 64, 78, 88, 85, 88,
-  86, 78, 82, 96, 93, 85, 83, 91, 79, 89,
-  88, 99, 84, 80, 84, 88, 79, 82, 66, 82,
-  98, 93, 87, 91, 86, 81, 91, 85, 89, 82,
-  80, 88, 91, 86, 90, 88, 81, 82, 87, 69,
-  73, 82, 93, 76, 78, 65, 78, 78, 93, 83,
-  90, 83, 93, 79, 84, 80, 91, 83, 86, 81,
-  95, 94, 91, 80, 80, 81, 86, 70, 86, 80,
-  69, 76, 79, 86, 83, 77, 82, 76, 82, 97,
-  88, 86, 75, 100, 76, 78, 86, 85, 81, 83,
-  86, 79, 78, 84, 88, 90, 63, 92, 86, 85,
-  91, 83, 99, 91, 83, 79, 86, 91, 77, 92,
-  79, 95, 85, 86, 71, 66, 80, 83, 85, 74,
-  71, 91, 78, 100, 58, 82, 75, 77, 90, 88,
-  79, 70, 78, 72, 72, 73, 98, 79, 82, 76,
-  88, 77, 81, 79, 49, 78, 74, 82, 83, 79,
-  72, 88, 75, 80, 74, 78, 90, 82, 84, 78,
-  96, 85, 87, 82, 73, 102, 86, 93, 84, 80,
-  73, 88, 109, 87, 87, 70, 100, 86, 80, 92,
-  73, 83, 78, 82, 71, 77, 85, 54, 104, 72,
-  82, 89, 73, 90, 87, 85, 88, 90, 102, 86,
-  86, 95, 77, 80, 82, 86, 81, 79, 80, 83,
-  89, 102, 89, 78, 87, 87, 83, 85, 92, 79,
-  82, 72, 76, 78, 89, 108, 66, 94, 90, 98,
-  93, 86, 81, 77, 80, 94, 76, 72, 86, 110,
-  96, 91, 79, 68, 81, 82, 79, 86, 87, 78,
-  85, 78, 63, 89, 78, 77, 82, 80, 82, 74,
-  80, 82, 82, 75, 85, 83, 64, 126, 89, 71,
-  83, 78, 78, 86, 114, 96, 111, 77, 100, 100,
-  62, 73, 80, 76, 88, 101, 87, 70, 88, 74,
-  81, 87, 83, 98, 87, 79, 72, 82, 77, 89,
-  78, 89, 57, 94, 82, 70, 73, 80, 62, 74,
-  79, 79, 78, 77, 87, 64, 87, 83, 76, 78,
-  77, 80, 93, 92, 72, 97, 71, 71, 77, 80,
-  88, 80, 87, 82, 90, 84, 93, 84, 90, 102,
-  89, 78, 77, 87, 73, 83, 87, 78, 88, 81,
-  77, 67, 74, 90, 57, 89, 96, 92, 99, 79,
-  82, 77, 78, 83, 82, 86, 85, 109, 119, 93,
-  93, 106, 84, 89, 83, 85, 90, 72, 89, 75,
-  82, 88, 92, 87, 86, 81, 87, 98, 102, 85,
-  91, 91, 71, 89, 83, 148, 91, 82, 86, 80,
-  94, 96, 96, 82, 98, 83, 96, 94, 70, 77,
-  91, 90, 92, 123, 81, 85, 81, 74, 81, 86,
-  94, 54, 81, 74, 67, 81, 91, 77, 63, 58,
-  56, 85, 75, 76, 80, 69, 70, 82, 81, 81,
-  93, 83, 92, 64, 61, 91, 83, 68, 84, 101,
-  91, 87, 77, 89, 56, 74, 81, 66, 86, 83,
-  82, 77, 87, 93, 83, 77, 84, 87, 78, 80,
-  81, 77, 75, 80, 80, 84, 98, 90, 82, 79,
-  53, 76, 78, 90, 92, 81, 93, 92, 86, 79,
-  79, 78, 82, 100, 86, 87, 92, 92, 72, 90,
-  80, 81, 89, 75, 66, 84, 84, 97, 71, 75,
-  80, 79, 94, 81, 78, 88, 79, 76, 82, 89,
-  86, 89, 90, 75, 87, 79, 72, 82, 70, 90,
-  58, 91, 72, 88, 73, 82, 76, 82, 81, 82,
-  82, 91, 87, 79, 93, 91, 82, 80, 78, 86,
-  87, 83, 83, 86, 85, 82, 94, 86, 94, 74,
-  86, 94, 78, 77, 78, 83, 82, 83, 79, 78,
-  86, 82, 84, 78, 87, 84, 73, 95, 87, 85,
-  93, 90, 100, 92, 82, 91, 80, 82, 90, 77,
-  83, 76, 76, 73, 87, 90, 86, 73, 94, 84,
-  89, 88, 88, 80, 93, 68, 82, 84, 81, 101,
-  101, 88, 84, 88, 92, 91, 84, 89, 76, 94,
-  79, 71, 85, 75, 77, 92, 81, 69, 76, 80,
-  80, 82, 83, 73, 86, 95, 86, 82, 85, 82,
-  84, 79, 87, 81, 63, 84, 85, 87, 88, 79,
-  75, 84, 79, 66, 83, 80, 78, 69, 83, 92,
-  79, 84, 83, 80, 69, 82, 80, 82, 83, 65,
-  87, 82, 84, 84, 86, 85, 87, 92, 80, 86,
-  77, 86, 85, 92, 90, 97, 77, 86, 93, 85,
-  79, 89, 63, 73, 87, 84, 80, 76, 89, 72,
-  96, 79, 84, 79, 76, 68, 96, 87, 78, 86,
-  89, 81, 71, 95, 81, 87, 84, 81, 84, 87,
-  86, 79, 79, 78, 81, 74, 91, 94, 73, 88,
-  77, 84, 96, 83, 81, 66, 82, 104, 72, 88,
-  87, 83, 104, 80, 79, 85, 84, 91, 78, 80,
-  83, 83, 102, 94, 88, 63, 82, 91, 85, 87,
-  93, 74, 83, 90, 95, 101, 92, 88, 90, 82,
-  93, 87, 79, 90, 88, 92, 84, 86, 81, 142,
-  82, 70, 99, 80, 96, 69, 122, 95, 83, 84,
-  95, 77, 66, 82, 89, 90, 89, 88, 82, 89,
-  76, 77, 83, 88, 103, 57, 88, 91, 75, 83,
-  91, 84, 77, 87, 70, 87, 78, 84, 77, 94,
-  39, 75, 91, 86, 93, 89, 88, 68, 76, 82,
-  88, 66, 86, 82, 98, 89, 64, 74, 77, 82,
-  72, 88, 85, 87, 81, 85, 85, 93, 82, 85,
-  87, 73, 75, 78, 89, 93, 72, 86, 68, 93,
-  103, 92, 87, 68, 81, 83, 63, 91, 93, 83,
-  88, 86, 76, 85, 85, 83, 78, 101, 91, 123,
-  66, 92, 87, 82, 81, 84, 81, 82, 82, 74,
-  88, 76, 70, 62, 75, 84, 85, 84, 74, 85,
-  82, 89, 79, 81, 102, 88, 98, 90, 95, 102,
-  67, 89, 76, 81, 113, 84, 80, 93, 86, 72,
-  102, 67, 89, 80, 90, 99, 68, 79, 76, 88,
-  87, 81, 71, 83, 64, 70, 68, 88, 101, 82,
-  89, 84, 75, 72, 69, 91, 78, 100, 78, 89,
-  81, 82, 90, 68, 86, 68, 109, 79, 80, 93,
-  85, 93, 88, 86, 96, 88, 74, 105, 77, 98,
-  92, 82, 87, 76, 92, 86, 88, 75, 87, 76,
-  94, 85, 81, 82, 83, 74, 91, 81, 95, 70,
-  85, 100, 89, 90, 72, 85, 78, 100, 88, 81,
-  83, 78, 89, 91, 79, 89, 81, 101, 39, 90,
-  90, 90, 67, 85, 95, 87, 75, 72, 75, 47,
-  65, 75, 77, 81, 82, 83, 70, 77, 75, 90,
-  84, 75, 101, 94, 125, 65, 69, 95, 53, 97,
-  81, 80, 112, 78, 82, 82, 81, 78, 104, 69,
-  84, 97, 89, 91, 72, 75, 70, 92, 88, 69,
-  89, 96, 64, 60, 74, 85, 85, 74, 85, 71,
-  49, 54, 45, 81, 83, 95, 117, 92, 76, 77,
-  96, 70, 89, 88, 117, 72, 80, 79, 95, 81,
-  98, 75, 87, 96, 61, 83, 72, 115, 79, 69,
-  107, 71, 85, 75, 97, 77, 80, 130, 94, 85,
-  83, 69, 79, 85, 76, 73, 78, 57, 77, 95,
-  82, 88, 72, 74, 73, 83, 65, 73, 77, 76,
-  90, 82, 82, 69, 75, 78, 44, 75, 73, 102,
-  73, 103, 76, 90, 79, 65, 61, 64, 75, 80,
-  91, 97, 90, 91, 83, 74, 71, 94, 81, 89,
-  87, 85, 110, 55, 68, 83, 87, 90, 64, 76,
-  74, 84, 56, 84, 80, 84, 85, 77, 86, 102,
-  76, 70, 88, 83, 85, 80, 84, 73, 109, 67,
-  101, 73, 85, 70, 72, 85, 85, 72, 31, 72,
-  73, 74, 95, 76, 98, 74, 109, 89, 81, 98,
-  75, 89, 74, 86, 82, 88, 95, 84, 94, 73,
-  91, 89, 69, 74, 112, 94, 74, 88, 120, 74,
-  89, 80, 83, 80, 58, 140, 81, 90, 76, 69,
-  75, 81, 70, 81, 78, 69, 84, 78, 72, 95,
-  60, 83, 89, 77, 75, 83, 90, 86, 95, 76,
-  82, 86, 90, 94, 73, 85, 84, 78, 86, 77,
-  71, 74, 87, 82, 78, 87, 93, 75, 87, 90,
-  89, 90, 79, 80, 84, 85, 77, 76, 91, 82,
-  79, 93, 101, 100, 94, 84, 98, 73, 91, 88,
-  88, 77, 83, 74, 92, 80, 83, 75, 93, 75,
-  71, 75, 71, 85, 89, 89, 79, 86, 63, 84,
-  78, 85, 99, 86, 90, 86, 83, 91, 87, 87,
-  77, 84, 78, 78, 77, 95, 84, 71, 80, 94,
-  93, 76, 91, 83, 79, 82, 84, 87, 97, 86,
-  97, 91, 88, 75, 97, 87, 72, 81, 87, 94,
-  84, 80, 74, 64, 82, 80, 75, 99, 92, 89,
-  74, 84, 84, 94, 84, 84, 86, 93, 74, 95,
-  82, 100, 80, 88, 67, 74, 79, 82, 79, 109,
-  84, 114, 79, 95, 98, 75, 86, 68, 93, 78,
-  84, 82, 84, 85, 94, 83, 82, 78, 93, 79,
-  72, 62, 92, 91, 90, 82, 79, 101, 87, 85,
-  103, 98, 80, 90, 90, 68, 95, 94, 84, 78,
-  94, 82, 102, 67, 73, 75, 105, 89, 67, 83,
-  76, 87, 85, 82, 77, 72, 45, 81, 73, 99,
-  91, 63, 83, 78, 79, 70, 75, 85, 72, 83,
-  64, 99, 65, 88, 88, 65, 95, 82, 96, 75,
-  86, 92, 86, 88, 89, 97, 86, 86, 81, 87,
-  78, 79, 97, 95, 63, 81, 90, 93, 103, 68,
-  76, 68, 89, 80, 78, 78, 94, 96, 84, 79,
-  90, 87, 74, 90, 94, 89, 75, 91, 84, 88,
-  85, 81, 82, 76, 78, 83, 87, 87, 77, 106,
-  62, 88, 72, 122, 71, 76, 88, 94, 74, 64,
-  65, 70, 70, 71, 87, 76, 85, 99, 78, 75,
-  103, 95, 84, 83, 86, 88, 101, 84, 78, 96,
-  69, 83, 67, 101, 101, 78, 84, 75, 85, 91,
-  90, 69, 77, 96, 88, 136, 87, 76, 74, 67,
-  85, 66, 100, 64, 75, 64, 73, 79, 85, 78,
-  91, 67, 49, 64, 59, 84, 91, 79, 98, 101,
-  81, 83, 89, 82, 79, 81, 89, 78, 79, 87,
-  101, 95, 94, 88, 96, 100, 71, 72, 86, 79,
-  77, 77, 92, 63, 86, 78, 92, 69, 72, 136,
-  92, 89, 74, 72, 79, 82, 77, 63, 72, 83,
-  69, 95, 76, 97, 84, 84, 80, 68, 73, 70,
-  84, 71, 87, 72, 85, 81, 86, 91, 85, 85,
-  80, 81, 77, 82, 74, 91, 81, 100, 83, 85,
-  82, 78, 94, 77, 78, 95, 78, 82, 92, 80,
-  76, 74, 101, 76, 79, 94, 89, 86, 93, 78,
-  85, 80, 81, 79, 98, 77, 79, 85, 90, 93,
-  83, 77, 87, 74, 85, 81, 78, 94, 94, 89,
-  85, 88, 83, 82, 94, 88, 85, 93, 86, 89,
-  79, 96, 90, 93, 84, 87, 80, 77, 76, 90,
-  92, 72, 79, 77, 76, 73, 97, 89, 94, 93,
-  79, 83, 87, 87, 90, 86, 95, 70, 93, 77,
-  72, 82, 81, 80, 88, 85, 73, 84, 77, 84,
-  88, 94, 92, 79, 91, 80, 80, 88, 80, 85,
-  83, 84, 85, 87, 89, 92, 73, 94, 69, 74,
-  97, 82, 87, 84, 85, 94, 98, 89, 91, 83,
-  82, 74, 82, 85, 75, 95, 96, 94, 83, 76,
-  88, 73, 77, 82, 81, 83, 95, 85, 70, 74,
-  88, 91, 81, 82, 86, 83, 92, 84, 85, 78,
-  84, 85, 88, 83, 86, 85, 91, 72, 75, 71,
-  86, 78, 91, 84, 80, 93, 89, 82, 81, 76,
-  70, 84, 83, 82, 83, 86, 81, 77, 86, 89,
-  92, 81, 78, 93, 87, 90, 73, 81, 83, 68,
-  84, 89, 74, 81, 89, 82, 91, 96, 80, 93,
-  85, 90, 77, 93, 91, 76, 94, 85, 71, 82,
-  84, 79, 90, 90, 74, 70, 80, 83, 82, 87,
-  85, 85, 95, 73, 85, 89, 79, 82, 94, 84,
-  90, 85, 88, 88, 80, 89, 79, 77, 94, 86,
-  85, 79, 76, 105, 87, 88, 88, 94, 80, 79,
-  90, 89, 80, 82, 76, 91, 62, 69, 80, 76,
-  84, 83, 96, 89, 108, 93, 77, 82, 79, 89,
-  86, 86, 82, 84, 76, 78, 69, 90, 88, 90,
-  83, 85, 101, 84, 98, 72, 82, 88, 87, 116,
-  90, 78, 87, 72, 81, 72, 88, 70, 76, 77,
-  77, 77, 84, 76, 94, 70, 66, 84, 87, 82,
-  94, 78, 83, 98, 77, 80, 87, 76, 86, 94,
-  72, 83, 86, 85, 93, 95, 85, 92, 91, 97,
-  79, 90, 88, 77, 85, 81, 84, 75, 84, 78,
-  99, 84, 75, 77, 86, 87, 73, 77, 80, 85,
-  93, 66, 77, 86, 78, 83, 82, 88, 104, 84,
-  85, 78, 81, 76, 86, 78, 91, 83, 86, 80,
-  104, 107, 89, 83, 44, 92, 83, 84, 83, 83,
-  84, 98, 86, 96, 86, 78, 86, 106, 90, 95,
-  81, 77, 89, 85, 82, 89, 93, 87, 90, 85,
-  82, 89, 83, 76, 73, 78, 90, 87, 68, 75,
-  81, 68, 83, 76, 93, 82, 77, 73, 68, 80,
-  85, 88, 96, 90, 94, 76, 84, 88, 80, 77,
-  89, 63, 112, 88, 90, 85, 84, 88, 81, 76,
-  74, 84, 81, 84, 81, 88, 64, 72, 89, 76,
-  89, 115, 80, 85, 82, 89, 78, 83, 100, 94,
-  73, 90, 84, 83, 84, 83, 89, 95, 81, 88,
-  74, 86, 86, 76, 82, 75, 81, 67, 88, 92,
-  81, 75, 76, 80, 90, 80, 80, 83, 62, 81,
-  80, 81, 83, 76, 81, 82, 88, 78, 99, 102,
-  63, 79, 65, 88, 80, 84, 81, 85, 86, 95,
-  92, 53, 85, 82, 86, 93, 89, 88, 84, 70,
-  76, 97, 88, 81, 92, 86, 88, 83, 82, 89,
-  85, 80, 82, 83, 86, 79, 114, 76, 77, 76,
-  72, 80, 93, 84, 87, 65, 74, 76, 78, 89,
-  88, 87, 92, 83, 79, 78, 87, 85, 82, 71,
-  106, 71, 61, 86, 78, 84, 83, 80, 81, 80,
-  76, 79, 81, 84, 75, 80, 92, 78, 76, 104,
-  76, 86, 81, 78, 75, 93, 85, 91, 71, 87,
-  85, 90, 81, 87, 85, 89, 71, 90, 71, 102,
-  85, 81, 83, 75, 82, 75, 89, 87, 80, 75,
-  78, 76, 76, 87, 69, 87, 73, 84, 82, 87,
-  77, 76, 82, 85, 89, 101, 81, 94, 86, 78,
-  138, 93, 71, 87, 76, 85, 92, 76, 80, 82,
-  70, 91, 82, 73, 86, 70, 76, 87, 82, 101,
-  79, 76, 70, 84, 77, 93, 93, 86, 79, 91,
-  101, 104, 86, 78, 92, 92, 78, 83, 78, 79,
-  100, 88, 100, 90, 98, 76, 78, 89, 72, 92,
-  87, 67, 80, 82, 91, 83, 86, 97, 88, 70,
-  61, 94, 67, 74, 100, 72, 68, 74, 79, 80,
-  95, 82, 87, 98, 92, 83, 76, 83, 83, 95,
-  91, 80, 73, 120, 72, 85, 66, 88, 93, 90,
-  88, 87, 90, 67, 72, 88, 75, 94, 78, 82,
-  81, 65, 77, 86, 86, 76, 95, 86, 77, 80,
-  69, 85, 91, 92, 87, 79, 87, 93, 67, 84,
-  83, 89, 80, 110, 92, 90, 87, 88, 40, 94,
-  98, 76, 85, 81, 83, 81, 78, 66, 98, 85,
-  99, 111, 75, 86, 75, 75, 84, 92, 82, 88,
-  93, 81, 97, 85, 91, 88, 99, 72, 79, 81,
-  86, 88, 63, 71, 76, 78, 77, 77, 86, 85,
-  82, 78, 65, 79, 77, 79, 96, 87, 95, 68,
-  79, 77, 82, 108, 86, 72, 79, 88, 85, 86,
-  77, 115, 84, 84, 86, 85, 75, 88, 85, 95,
-  81, 89, 80, 76, 93, 68, 83, 74, 84, 86,
-  84, 75, 71, 89, 94, 90, 85, 89, 81, 78,
-  82, 102, 90, 86, 69, 108, 86, 77, 93, 85,
-  97, 76, 77, 93, 84, 87, 73, 87, 77, 88,
-  87, 89, 78, 81, 83, 84, 77, 82, 76, 81,
-  86, 79, 87, 86, 68, 83, 76, 83, 84, 76,
-  85, 85, 85, 89, 83, 61, 87, 87, 95, 91,
-  74, 84, 79, 75, 73, 98, 77, 79, 92, 81,
-  93, 83, 82, 91, 89, 78, 62, 86, 75, 86,
-  93, 70, 73, 86, 68, 81, 87, 82, 88, 78,
-  78, 79, 78, 80, 98, 85, 88, 74, 84, 73,
-  83, 105, 87, 77, 75, 70, 61, 81, 76, 95,
-  85, 78, 73, 84, 71, 86, 86, 88, 86, 77,
-  73, 83, 82, 71, 82, 86, 84, 76, 80, 83,
-  72, 89, 85, 83, 80, 100, 76, 81, 81, 93,
-  79, 91, 72, 113, 84, 81, 93, 77, 96, 84,
-  84, 92, 81, 85, 76, 85, 79, 79, 71, 86,
-  78, 80, 82, 82, 83, 82, 79, 80, 84, 91,
-  71, 86, 81, 75, 156, 89, 66, 84, 80, 79,
-  94, 79, 82, 91, 67, 90, 84, 69, 70, 74,
-  74, 99, 83, 93, 80, 67, 70, 77, 89, 80,
-  85, 87, 79, 99, 83, 111, 83, 85, 97, 111,
-  81, 89, 85, 85, 101, 80, 103, 81, 110, 79,
-  81, 91, 74, 94, 76, 81, 85, 79, 85, 84,
-  81, 90, 81, 65, 58, 85, 69, 66, 97, 67,
-  76, 76, 73, 84, 99, 81, 91, 95, 79, 87,
-  82, 74, 88, 96, 91, 85, 74, 106, 77, 75,
-  70, 78, 82, 85, 81, 84, 84, 62, 76, 89,
-  78, 79, 78, 83, 80, 66, 80, 91, 79, 80,
-  85, 97, 81, 88, 72, 75, 93, 83, 78, 74,
-  83, 83, 69, 87, 91, 86, 74, 95, 79, 91,
-  86, 92, 54, 82, 98, 85, 86, 84, 77, 86,
-  72, 61, 100, 100, 96, 95, 71, 77, 82, 74,
-  80, 81, 76, 92, 89, 78, 87, 89, 84, 88,
-  101, 84, 81, 88, 98, 85, 76, 79, 84, 79,
-  77, 89, 79, 89, 71, 79, 67, 78, 69, 87,
-  84, 90, 89, 77, 83, 89, 86, 93, 73, 73,
-  86, 87, 93, 83, 68, 106, 77, 88, 101, 81,
-  88, 86, 86, 100, 89, 74, 88, 70, 88, 87,
-  86, 73, 80, 81, 89, 73, 87, 83, 86, 83,
-  91, 90, 86, 86, 86, 88, 90, 84, 84, 102,
-  90, 78, 98, 90, 91, 84, 70, 76, 87, 87,
-  83, 89, 94, 74, 72, 99, 95, 91, 82, 83,
-  75, 88, 77, 92, 78, 67, 74, 90, 86, 86,
-  88, 79, 86, 76, 80, 80, 83, 87, 75, 97,
-  84, 93, 88, 78, 68, 87, 84, 85, 73, 85,
-  69, 81, 83, 76, 84, 104, 79, 88, 91, 83,
-  65, 89, 95, 82, 79, 81, 89, 83, 66, 93,
-  84, 85, 72, 68, 87, 79, 78, 94, 83, 88,
-  80, 71, 83, 83, 83, 97, 78, 79, 85, 68,
-  72, 79, 82, 85, 80, 87, 82, 81, 77, 92,
-  88, 81, 86, 72, 74, 83, 81, 87, 83, 81,
-  84, 89, 81, 82, 85, 79, 72, 77, 81, 92,
-  76, 88, 81, 78, 86, 88, 84, 90, 83, 80,
-  92, 84, 84, 89, 81, 78, 90, 87, 84, 88,
-  93, 74, 72, 84, 80, 89, 83, 84, 79, 85,
-  82, 90, 79, 80, 69, 94, 89, 81, 143, 91,
-  66, 82, 81, 79, 89, 73, 76, 105, 60, 86,
-  75, 64, 72, 74, 74, 105, 90, 89, 78, 72,
-  73, 76, 77, 84, 80, 87, 80, 92, 85, 105,
-  96, 81, 91, 108, 91, 85, 83, 88, 98, 84,
-  86, 79, 111, 87, 79, 88, 68, 93, 79, 77,
-  81, 75, 88, 83, 82, 85, 85, 71, 67, 74,
-  78, 63, 88, 87, 93, 74, 74, 92, 95, 77,
-  86, 99, 73, 91, 80, 75, 90, 91, 85, 100,
-  77, 105, 80, 68, 68, 83, 87, 81, 83, 81,
-  90, 64, 83, 89, 89, 75, 80, 81, 88, 74,
-  75, 85, 83, 73, 91, 104, 89, 91, 70, 79,
-  91, 81, 83, 87, 91, 81, 71, 86, 93, 94,
-  77, 95, 80, 85, 75, 77, 79, 74, 81, 78,
-  71, 85, 76, 79, 81, 83, 73, 78, 79, 81,
-  76, 86, 91, 74, 67, 82, 77, 86, 84, 88,
-  84, 82, 84, 76, 83, 81, 80, 71, 86, 78,
-  78, 81, 78, 71, 81, 83, 84, 82, 64, 69,
-  87, 80, 88, 94, 76, 82, 79, 89, 76, 76,
-  88, 82, 72, 74, 93, 67, 88, 76, 86, 81,
-  81, 88, 69, 80, 91, 85, 74, 85, 75, 83,
-  85, 93, 78, 84, 76, 87, 73, 79, 81, 70,
-  89, 82, 88, 90, 83, 84, 80, 85, 80, 81,
-  81, 88, 87, 72, 78, 81, 77, 85, 78, 78,
-  85, 76, 80, 72, 77, 83, 85, 86, 78, 82,
-  75, 91, 86, 85, 96, 77, 92, 77, 80, 83,
-  80, 90, 89, 78, 81, 67, 81, 73, 73, 89,
-  75, 82, 91, 85, 76, 78, 77, 77, 75, 79,
-  84, 70, 70, 86, 87, 86, 83, 85, 103, 80,
-  92, 81, 80, 75, 78, 70, 87, 76, 84, 78,
-  79, 63, 83, 86, 77, 82, 70, 69, 84, 84,
-  82, 106, 85, 81, 85, 93, 75, 78, 87, 79,
-  80, 75, 89, 75, 80, 76, 80, 77, 77, 88,
-  81, 70, 79, 84, 77, 78, 71, 77, 89, 81,
-  79, 79, 81, 78, 74, 78, 74, 81, 91, 83,
-  85, 89, 87, 83, 80, 74, 81, 82, 80, 88,
-  86, 81, 72, 78, 75, 82, 73, 81, 86, 75,
-  76, 72, 76, 74, 82, 79, 69, 78, 79, 83,
-  81, 84, 99, 74, 93, 72, 80, 79, 80, 88,
-  80, 77, 76, 71, 85, 87, 71, 86, 76, 83,
-  75, 80, 76, 79, 77, 80, 77, 86, 84, 71,
-  74, 81, 86, 88, 88, 86, 79, 84, 86, 83,
-  81, 76, 75, 88, 93, 82, 75, 80, 81, 71,
-  83, 81, 83, 83, 72, 83, 88, 77, 89, 84,
-  74, 84, 83, 83, 78, 77, 84, 81, 77, 75,
-  90, 65, 88, 76, 83, 83, 80, 86, 76, 79,
-  93, 82, 79, 84, 77, 75, 89, 90, 82, 85,
-  73, 75, 77, 77, 86, 67, 87, 82, 88, 88,
-  83, 85, 82, 86, 83, 80, 74, 85, 83, 90,
-  79, 83, 81, 82, 80, 77, 82, 74, 79, 75,
-  80, 81, 83, 81, 73, 81, 77, 87, 85, 87,
-  90, 76, 85, 75, 84, 82, 99, 101, 105, 90,
-  92, 109, 55, 68, 80, 89, 84, 88, 124, 93,
-  74, 81, 87, 79, 87, 95, 90, 107, 103, 86,
-  85, 67, 77, 96, 172, 84, 87, 101, 90, 98,
-  96, 93, 74, 92, 88, 90, 84, 73, 91, 86,
-  88, 106, 72, 91, 70, 94, 77, 103, 71, 79,
-  73, 78, 67, 57, 95, 90, 84, 89, 79, 42,
-  78, 68, 81, 92, 77, 71, 99, 73, 91, 84,
-  84, 81, 77, 105, 66, 84, 72, 90, 86, 119,
-  66, 89, 95, 102, 59, 83, 90, 76, 84, 85,
-  96, 88, 81, 77, 88, 81, 108, 84, 85, 76,
-  91, 75, 105, 80, 91, 77, 76, 77, 74, 105,
-  65, 96, 96, 89, 77, 71, 79, 85, 94, 70,
-  92, 83, 91, 87, 100, 95, 100, 88, 92, 105,
-  59, 59, 77, 91, 80, 90, 139, 91, 79, 70,
-  79, 73, 77, 89, 88, 100, 109, 86, 92, 72,
-  76, 89, 173, 84, 96, 93, 80, 93, 94, 93,
-  79, 82, 92, 85, 86, 70, 90, 89, 81, 99,
-  71, 97, 68, 94, 74, 119, 80, 72, 74, 90,
-  70, 55, 92, 93, 85, 88, 75, 55, 77, 71,
-  74, 92, 72, 71, 110, 66, 75, 79, 85, 76,
-  74, 106, 73, 75, 68, 83, 87, 96, 71, 86,
-  94, 108, 63, 79, 74, 81, 92, 90, 92, 77,
-  79, 77, 87, 81, 106, 91, 81, 72, 88, 75,
-  91, 81, 84, 72, 74, 78, 66, 97, 66, 85,
-  99, 85, 83, 71, 86, 81, 89, 66, 93, 81,
-  86, 83, 98, 92, 86, 90, 84, 94, 68, 81,
-  80, 92, 86, 86, 111, 81, 78, 80, 81, 80,
-  89, 87, 89, 99, 101, 85, 92, 75, 76, 96,
-  139, 87, 87, 94, 91, 89, 79, 105, 75, 91,
-  84, 88, 80, 75, 85, 82, 85, 103, 77, 102,
-  75, 95, 76, 100, 70, 80, 80, 76, 68, 64,
-  89, 91, 85, 84, 80, 46, 80, 76, 81, 92,
-  81, 64, 97, 74, 92, 79, 89, 85, 78, 95,
-  70, 83, 81, 93, 80, 77, 72, 83, 100, 87,
-  63, 79, 85, 81, 83, 90, 96, 88, 85, 76,
-  84, 79, 96, 93, 85, 77, 93, 75, 100, 75,
-  86, 77, 74, 78, 76, 97, 62, 89, 105, 89,
-  81, 71, 95, 83, 94, 71, 89, 82, 92, 86,
-  83, 79, 84, 87, 74, 82, 80, 81, 78, 80,
-  82, 77, 91, 91, 77, 86, 87, 79, 85, 81,
-  83, 82, 75, 81, 76, 83, 82, 87, 121, 72,
-  90, 88, 79, 89, 85, 69, 75, 79, 74, 98,
-  89, 77, 79, 76, 75, 77, 77, 68, 78, 80,
-  89, 100, 80, 81, 85, 81, 76, 80, 81, 79,
-  80, 72, 84, 70, 80, 77, 85, 71, 82, 86,
-  76, 72, 88, 85, 76, 81, 77, 85, 78, 84,
-  78, 89, 82, 89, 80, 83, 77, 87, 91, 84,
-  85, 94, 81, 82, 87, 74, 84, 81, 82, 91,
-  94, 78, 82, 77, 77, 87, 69, 87, 82, 79,
-  82, 75, 78, 82, 91, 83, 80, 75, 81, 75,
-  80, 81, 88, 81, 75, 87, 83, 81, 86, 85,
-  87, 88, 75, 68, 78, 75, 82, 82, 81, 78,
-  95, 84, 81, 81, 83, 74, 77, 80, 80, 72,
-  84, 84, 78, 85, 81, 83, 132, 78, 92, 91,
-  80, 78, 85, 64, 75, 72, 81, 87, 93, 69,
-  84, 76, 77, 80, 72, 70, 74, 81, 92, 108,
-  86, 79, 91, 93, 79, 79, 79, 78, 80, 74,
-  77, 77, 72, 73, 80, 72, 76, 82, 81, 61,
-  82, 82, 78, 81, 75, 79, 82, 77, 75, 85,
-  84, 81, 83, 83, 71, 91, 86, 85, 84, 94,
-  87, 87, 84, 65, 85, 83, 81, 92, 92, 84,
-  76, 73, 72, 87, 62, 86, 83, 76, 85, 74,
-  74, 72, 84, 78, 71, 75, 85, 73, 79, 78,
-  90, 80, 77, 89, 80, 76, 82, 86, 85, 92,
-  74, 68, 84, 88, 81, 84, 81, 77, 83, 74,
-  78, 85, 84, 78, 83, 85, 80, 75, 90, 81,
-  80, 84, 83, 89, 113, 81, 87, 89, 82, 80,
-  72, 80, 82, 80, 80, 96, 87, 74, 80, 78,
-  76, 81, 80, 84, 78, 80, 89, 93, 78, 82,
-  86, 87, 78, 81, 78, 78, 79, 70, 80, 65,
-  88, 75, 82, 72, 78, 83, 77, 70, 93, 84,
-  84, 80, 79, 78, 80, 81, 83, 91, 83, 79,
-  81, 81, 78, 77, 87, 79, 82, 94, 80, 81,
-  86, 74, 82, 79, 82, 88, 91, 87, 81, 79,
-  75, 85, 74, 86, 78, 75, 81, 76, 78, 78,
-  85, 77, 78, 75, 81, 75, 83, 80, 81, 82,
-  75, 91, 83, 75, 78, 86, 85, 96, 76, 76,
-  75, 76, 96, 82, 67, 80, 84, 73, 87, 73,
-  81, 81, 61, 85, 98, 85, 87, 88, 86, 106,
-  89, 70, 104, 91, 78, 79, 98, 80, 75, 97,
-  88, 79, 85, 87, 108, 81, 99, 90, 71, 98,
-  100, 96, 82, 101, 93, 89, 82, 88, 72, 86,
-  91, 74, 83, 80, 80, 83, 86, 73, 88, 68,
-  85, 91, 87, 92, 84, 81, 83, 79, 90, 75,
-  79, 88, 85, 87, 80, 78, 75, 70, 85, 86,
-  90, 81, 87, 87, 102, 79, 66, 68, 85, 80,
-  82, 84, 83, 77, 82, 82, 67, 61, 83, 73,
-  93, 88, 92, 72, 99, 80, 84, 83, 78, 96,
-  77, 68, 78, 109, 105, 86, 92, 63, 96, 77,
-  77, 91, 82, 89, 85, 97, 86, 74, 71, 72,
-  111, 72, 53, 80, 89, 79, 88, 67, 76, 79,
-  38, 83, 107, 93, 68, 90, 79, 105, 102, 64,
-  102, 84, 71, 83, 106, 83, 83, 80, 89, 74,
-  81, 84, 102, 77, 105, 85, 70, 109, 110, 76,
-  75, 109, 87, 94, 95, 83, 74, 89, 90, 78,
-  79, 77, 79, 92, 90, 74, 82, 68, 86, 81,
-  89, 91, 91, 70, 82, 84, 82, 61, 80, 76,
-  93, 88, 85, 74, 85, 85, 77, 87, 89, 71,
-  87, 98, 96, 76, 53, 57, 78, 70, 52, 84,
-  86, 74, 85, 82, 62, 57, 82, 77, 95, 93,
-  98, 82, 100, 85, 71, 82, 84, 95, 77, 62,
-  83, 116, 102, 88, 89, 61, 104, 85, 65, 101,
-  80, 79, 84, 90, 77, 89, 78, 77, 89, 83,
-  73, 78, 80, 83, 87, 74, 79, 81, 68, 86,
-  95, 84, 72, 86, 83, 102, 90, 68, 96, 80,
-  76, 79, 90, 94, 80, 80, 83, 79, 78, 88,
-  98, 81, 93, 85, 79, 89, 88, 86, 84, 95,
-  89, 84, 80, 87, 75, 79, 91, 74, 80, 83,
-  79, 84, 84, 71, 90, 71, 89, 89, 84, 86,
-  91, 83, 76, 81, 83, 76, 78, 91, 89, 87,
-  74, 80, 83, 101, 87, 80, 87, 82, 87, 94,
-  101, 80, 71, 68, 85, 80, 87, 85, 87, 80,
-  83, 90, 71, 62, 85, 71, 95, 89, 96, 70,
-  93, 90, 85, 88, 78, 89, 81, 73, 79, 105,
-  79, 85, 87, 65, 94, 82, 82, 88, 78, 83,
-  79, 87, 83, 90, 73, 77, 119, 76, 67, 85,
-  85, 81, 86, 73, 92, 86, 47, 83, 104, 89,
-  87, 87, 79, 97, 85, 66, 100, 87, 72, 74,
-  107, 72, 76, 104, 87, 72, 85, 86, 88, 83,
-  104, 88, 78, 103, 103, 111, 83, 106, 87, 85,
-  84, 88, 73, 87, 95, 74, 82, 79, 77, 89,
-  80, 70, 83, 74, 84, 93, 92, 74, 86, 80,
-  84, 81, 82, 75, 88, 99, 75, 88, 87, 73,
-  76, 66, 84, 90, 88, 81, 84, 78, 97, 90,
-  58, 62, 88, 77, 72, 84, 83, 82, 88, 95,
-  69, 62, 80, 88, 87, 82, 84, 73, 90, 79,
-  83, 82, 80, 92, 80, 71, 82, 103, 102, 83,
-  89, 61, 95, 82, 67, 99, 80, 90, 83, 88,
-  89, 78, 68, 83, 148, 63, 56, 86, 92, 77,
-  84, 73, 94, 90, 22, 77, 111, 93, 72, 87,
-  72, 96, 98, 59, 110, 80, 64, 75, 122, 70,
-  81, 84, 82, 72, 83, 85, 78, 74, 110, 81,
-  81, 119, 118, 82, 74, 119, 84, 82, 106, 86,
-  75, 87, 97, 77, 77, 71, 69, 97, 81, 72,
-  64, 73, 95, 79, 96, 72, 80, 64, 92, 87,
-  70, 61, 89, 87, 81, 91, 97, 71, 93, 92,
-  75, 88, 87, 63, 86, 87, 96, 85, 41, 48,
-  75, 66, 41, 79, 88, 76, 82, 85, 61, 57,
-  76, 94, 92, 86, 82, 83, 90, 80, 68, 83,
-  87, 93, 84, 66, 88, 105, 93, 84, 89, 59,
-  98, 83, 52, 110, 85, 81, 86, 82, 85, 88,
-  74, 78, 104, 79, 73, 82, 78, 81, 85, 74,
-  89, 87, 57, 88, 94, 88, 84, 85, 81, 98,
-  83, 68, 92, 79, 77, 76, 97, 90, 83, 85,
-  88, 76, 82, 84, 85, 81, 95, 84, 86, 89,
-  90, 87, 85, 96, 82, 84, 83, 85, 73, 79,
-  90, 75, 84, 84, 80, 88, 80, 69, 86, 78,
-  100, 89, 84, 79, 87, 87, 75, 87, 77, 71,
-  84, 100, 78, 86, 82, 77, 83, 115, 86, 86,
-  84, 84, 83, 86, 94, 80, 67, 68, 83, 80,
-  80, 86, 82, 80, 87, 80, 73, 65, 84, 81,
-  91, 83, 86, 69, 87, 86, 84, 89, 85, 89,
-  88, 77, 79, 100, 70, 86, 85, 66, 89, 83,
-  74, 90, 81, 83, 74, 89, 80, 80, 85, 75,
-  99, 86, 74, 76, 81, 95, 79, 80, 97, 83,
-  69, 82, 91, 78, 78, 77, 83, 93, 80, 72,
-  91, 84, 83, 76, 89, 73, 70, 90, 89, 74,
-  84, 87, 91, 79, 95, 82, 85, 86, 89, 100,
-  93, 97, 85, 90, 71, 78, 71, 89, 87, 83,
-  86, 83, 81, 83, 88, 76, 85, 75, 89, 102,
-  90, 81, 86, 88, 84, 90, 76, 76, 87, 89,
-  85, 85, 73, 92, 72, 67, 95, 88, 86, 89,
-  86, 76, 83, 103, 77, 78, 92, 85, 96, 89,
-  76, 82, 84, 85, 78, 68, 80, 84, 82, 72,
-  78, 61, 88, 82, 95, 86, 87, 83, 80, 82,
-  77, 97, 82, 81, 92, 69, 91, 79, 78, 79,
-  87, 87, 83, 86, 85, 75, 78, 75, 107, 80,
-  67, 80, 86, 89, 74, 77, 96, 83, 52, 87,
-  91, 87, 76, 75, 78, 91, 86, 65, 95, 83,
-  74, 79, 95, 73, 73, 88, 88, 76, 89, 82,
-  84, 70, 92, 78, 83, 80, 93, 83, 89, 106,
-  81, 90, 80, 76, 73, 91, 91, 81, 87, 81,
-  75, 90, 87, 80, 78, 73, 101, 103, 92, 96,
-  74, 82, 90, 88, 69, 69, 83, 89, 87, 82,
-  75, 93, 74, 87, 94, 84, 87, 82, 86, 74,
-  80, 99, 67, 70, 87, 76, 80, 83, 76, 83,
-  86, 92, 75, 63, 82, 95, 78, 80, 81, 62,
-  85, 84, 85, 90, 97, 88, 81, 76, 79, 94,
-  75, 82, 89, 66, 94, 78, 73, 86, 87, 83,
-  90, 84, 80, 77, 87, 78, 93, 89, 75, 75,
-  79, 84, 79, 83, 92, 84, 72, 84, 86, 79,
-  82, 79, 91, 92, 78, 73, 84, 81, 86, 82,
-  88, 80, 79, 86, 93, 77, 86, 87, 87, 78,
-  89, 77, 83, 81, 87, 82, 93, 95, 82, 89,
-  75, 78, 75, 83, 85, 80, 87, 85, 81, 82,
-  84, 77, 86, 76, 97, 96, 85, 86, 80, 94,
-  80, 94, 73, 76, 85, 101, 86, 83, 70, 91,
-  77, 92, 92, 86, 84, 87, 86, 81, 85, 83,
-  82, 77, 83, 84, 97, 88, 72, 86, 84, 83,
-  80, 70, 89, 78, 85, 69, 81, 60, 89, 85,
-  93, 91, 86, 84, 81, 85, 79, 96, 71, 80,
-  86, 70, 87, 77, 82, 76, 78, 86, 89, 93,
-  77, 75, 85, 89, 75, 71, 90, 76, 103, 70,
-  76, 82, 86, 78, 86, 82, 92, 92, 90, 79,
-  83, 74, 98, 71, 101, 85, 90, 93, 72, 87,
-  79, 89, 83, 91, 85, 80, 81, 72, 89, 74,
-  72, 67, 94, 95, 83, 71, 85, 92, 66, 96,
-  79, 90, 73, 90, 79, 86, 87, 93, 87, 79,
-  84, 76, 91, 91, 82, 87, 84, 93, 92, 79,
-  77, 70, 77, 78, 84, 80, 80, 84, 67, 88,
-  67, 79, 79, 82, 83, 89, 76, 81, 65, 97,
-  80, 77, 85, 72, 90, 71, 74, 88, 96, 85,
-  89, 88, 85, 91, 91, 80, 93, 88, 156, 81,
-  100, 81, 90, 69, 81, 100, 94, 90, 87, 108,
-  92, 84, 90, 78, 80, 88, 86, 93, 80, 74,
-  85, 79, 77, 56, 85, 80, 114, 79, 81, 81,
-  91, 81, 82, 78, 98, 88, 81, 78, 87, 69,
-  95, 63, 102, 87, 96, 101, 73, 87, 82, 81,
-  88, 89, 78, 86, 84, 73, 95, 77, 71, 63,
-  95, 80, 80, 67, 83, 93, 67, 99, 74, 90,
-  75, 92, 82, 86, 83, 85, 83, 78, 72, 70,
-  87, 81, 78, 81, 85, 94, 86, 80, 79, 64,
-  74, 83, 88, 79, 85, 79, 69, 81, 64, 77,
-  79, 75, 83, 97, 72, 82, 68, 89, 78, 81,
-  86, 69, 96, 71, 64, 82, 84, 84, 91, 86,
-  79, 90, 91, 84, 96, 88, 156, 82, 100, 79,
-  79, 69, 78, 103, 87, 97, 84, 111, 89, 80,
-  92, 69, 77, 90, 86, 92, 78, 82, 87, 88,
-  75, 73, 91, 80, 103, 84, 76, 82, 84, 78,
-  82, 77, 87, 89, 83, 80, 84, 75, 95, 72,
-  95, 78, 90, 95, 72, 87, 80, 96, 85, 92,
-  68, 80, 84, 77, 93, 76, 78, 74, 93, 78,
-  80, 72, 81, 93, 66, 94, 80, 92, 72, 88,
-  80, 86, 93, 96, 86, 80, 79, 77, 92, 87,
-  79, 81, 94, 93, 93, 79, 81, 75, 75, 96,
-  88, 83, 83, 87, 71, 91, 71, 73, 81, 78,
-  87, 93, 78, 87, 65, 95, 88, 82, 86, 78,
-  82, 73, 71, 88, 95, 85, 88, 89, 77, 95,
-  92, 79, 92, 91, 145, 86, 96, 76, 88, 70,
-  81, 97, 82, 85, 86, 104, 89, 84, 91, 79,
-  80, 81, 92, 86, 80, 83, 80, 90, 71, 58,
-  92, 76, 102, 76, 85, 80, 92, 78, 88, 79,
-  96, 87, 81, 76, 85, 81, 86, 71, 95, 84,
-  93, 92, 76, 93, 83, 82, 78, 86, 73, 84,
-  82, 77, 87, 72, 78, 65, 99, 97, 81, 64,
-  88, 84, 71, 96, 79, 92, 77, 93, 79, 90,
-  79, 83, 81, 79, 79, 75, 94, 81, 91, 78,
-  87, 86, 86, 83, 78, 73, 78, 74, 78, 94,
-  77, 89, 68, 78, 64, 77, 81, 79, 77, 86,
-  79, 79, 75, 92, 74, 80, 77, 73, 91, 74,
-  65, 92, 71, 87, 84, 93, 89, 83, 77, 89,
-  90, 82, 153, 76, 89, 78, 79, 78, 87, 89,
-  94, 94, 88, 107, 91, 81, 88, 76, 85, 85,
-  83, 66, 86, 78, 75, 79, 70, 40, 90, 77,
-  96, 73, 87, 72, 99, 83, 87, 79, 96, 85,
-  79, 73, 84, 78, 78, 64, 96, 85, 91, 98,
-  76, 89, 83, 74, 85, 87, 73, 83, 86, 78,
-  95, 75, 80, 60, 91, 75, 82, 55, 86, 81,
-  72, 103, 79, 89, 84, 90, 84, 89, 73, 82,
-  82, 79, 73, 74, 93, 79, 85, 80, 82, 89,
-  83, 85, 76, 67, 75, 80, 81, 98, 79, 87,
-  68, 77, 63, 80, 76, 77, 77, 90, 75, 77,
-  78, 82, 69, 88, 77, 69, 95, 77, 61, 85,
-  53, 86, 85, 92, 79, 82, 72, 94, 89, 89,
-  141, 74, 94, 77, 74, 79, 86, 89, 84, 99,
-  77, 99, 84, 76, 99, 69, 78, 93, 89, 89,
-  81, 83, 84, 83, 71, 62, 94, 79, 93, 75,
-  84, 83, 87, 75, 85, 78, 85, 83, 84, 79,
-  84, 78, 85, 72, 88, 79, 87, 94, 78, 90,
-  79, 87, 79, 87, 75, 82, 84, 81, 96, 75,
-  82, 70, 94, 75, 79, 66, 82, 83, 69, 91,
-  79, 87, 76, 91, 82, 88, 78, 85, 83, 76,
-  76, 74, 93, 80, 92, 78, 86, 85, 84, 81,
-  79, 77, 76, 98, 82, 91, 81, 92, 76, 88,
-  67, 76, 75, 78, 81, 91, 82, 78, 71, 94,
-  77, 84, 78, 79, 88, 78, 66, 84, 69, 86,
-  84, 91, 82, 87, 81, 88, 88, 85, 135, 85,
-  89, 78, 90, 77, 86, 89, 86, 89, 86, 104,
-  86, 80, 91, 79, 81, 83, 91, 120, 85, 83,
-  74, 100, 75, 75, 88, 83, 100, 86, 77, 82,
-  85, 73, 83, 85, 91, 87, 84, 84, 84, 81,
-  91, 80, 91, 81, 85, 85, 74, 106, 78, 86,
-  80, 87, 71, 88, 87, 80, 86, 72, 79, 81,
-  95, 100, 76, 75, 82, 87, 75, 90, 78, 92,
-  72, 90, 84, 86, 77, 76, 86, 78, 87, 79,
-  93, 86, 92, 90, 93, 87, 89, 83, 78, 76,
-  83, 76, 84, 89, 82, 82, 65, 84, 70, 93,
-  82, 82, 85, 93, 78, 90, 76, 94, 98, 77,
-  72, 76, 82, 70, 71, 93, 82, 86, 86, 88,
-  86, 81, 79, 87, 81, 77, 155, 85, 89, 82,
-  77, 80, 84, 88, 88, 88, 85, 119, 93, 93,
-  88, 81, 87, 88, 89, 104, 90, 77, 72, 93,
-  78, 62, 94, 83, 100, 77, 81, 80, 95, 75,
-  89, 84, 91, 83, 82, 82, 82, 79, 85, 80,
-  93, 81, 85, 92, 78, 99, 74, 80, 83, 93,
-  76, 88, 85, 81, 91, 75, 81, 75, 85, 81,
-  76, 73, 83, 84, 74, 92, 78, 86, 74, 90,
-  83, 86, 71, 74, 86, 79, 74, 71, 97, 86,
-  86, 90, 82, 90, 82, 86, 76, 74, 80, 84,
-  87, 93, 81, 81, 68, 83, 68, 97, 80, 82,
-  83, 95, 83, 86, 79, 88, 88, 78, 79, 73,
-  88, 74, 67, 87, 63, 83, 83, 83, 80, 81,
-  77, 91, 78, 83, 148, 79, 87, 82, 75, 81,
-  83, 87, 86, 92, 85, 112, 89, 87, 93, 81,
-  80, 88, 97, 119, 84, 83, 76, 93, 76, 77,
-  93, 86, 96, 73, 77, 82, 81, 71, 84, 84,
-  82, 85, 84, 86, 79, 78, 86, 80, 86, 79,
-  82, 91, 77, 94, 74, 94, 80, 90, 84, 86,
-  88, 81, 92, 73, 81, 81, 90, 76, 77, 77,
-  79, 88, 72, 86, 81, 87, 75, 91, 88, 84,
-  74, 79, 87, 80, 84, 76, 90, 87, 89, 92,
-  87, 86, 90, 82, 77, 80, 84, 98, 86, 86,
-  83, 84, 73, 90, 72, 92, 77, 83, 83, 94,
-  80, 86, 71, 96, 89, 76, 75, 76, 84, 74,
-  74, 84, 77, 83, 85, 87, 82, 83, 82, 86,
-  80, 81, 136, 87, 88, 87, 92, 79, 81, 91,
-  87, 89, 87, 117, 86, 92, 89, 85, 76, 76,
-  92, 83, 83, 99, 101, 79, 84, 48, 87, 83,
-  93, 80, 87, 89, 88, 82, 93, 86, 91, 87,
-  78, 92, 82, 83, 77, 82, 91, 77, 79, 76,
-  83, 92, 92, 90, 87, 97, 75, 87, 81, 75,
-  89, 85, 81, 86, 76, 103, 63, 92, 83, 91,
-  73, 80, 75, 86, 65, 95, 68, 105, 90, 79,
-  81, 89, 93, 89, 83, 81, 90, 92, 89, 80,
-  88, 85, 75, 70, 85, 85, 80, 82, 75, 96,
-  79, 85, 85, 77, 75, 76, 89, 81, 82, 85,
-  74, 90, 73, 89, 78, 92, 81, 89, 78, 77,
-  80, 90, 102, 79, 74, 83, 78, 76, 79, 81,
-  99, 91, 93, 78, 87, 109, 75, 74, 78, 83,
-  87, 78, 82, 78, 72, 105, 81, 80, 87, 75,
-  92, 81, 107, 85, 85, 48, 98, 81, 91, 73,
-  93, 81, 94, 84, 85, 87, 83, 82, 86, 99,
-  85, 79, 72, 74, 84, 82, 75, 77, 95, 81,
-  96, 72, 91, 75, 76, 85, 87, 81, 90, 84,
-  91, 81, 81, 90, 69, 95, 87, 95, 70, 87,
-  77, 81, 70, 97, 74, 101, 84, 84, 77, 91,
-  94, 98, 87, 84, 90, 91, 79, 83, 91, 79,
-  75, 72, 85, 86, 78, 93, 78, 88, 81, 75,
-  86, 85, 76, 76, 90, 80, 79, 75, 75, 85,
-  77, 89, 83, 95, 80, 101, 82, 85, 73, 86,
-  93, 81, 83, 90, 95, 82, 83, 84, 97, 70,
-  95, 86, 89, 111, 71, 81, 87, 85, 85, 79,
-  87, 77, 60, 102, 86, 72, 90, 79, 84, 95,
-  94, 83, 79, 60, 96, 83, 80, 74, 78, 80,
-  93, 92, 92, 82, 85, 81, 80, 86, 95, 75,
-  71, 55, 76, 86, 83, 77, 90, 85, 87, 76,
-  92, 77, 83, 80, 83, 96, 90, 81, 87, 87,
-  83, 92, 73, 88, 85, 90, 68, 90, 75, 81,
-  70, 98, 73, 93, 89, 87, 78, 99, 104, 107,
-  85, 86, 91, 87, 81, 86, 86, 76, 76, 77,
-  86, 82, 72, 84, 73, 83, 83, 75, 89, 88,
-  77, 76, 86, 80, 81, 90, 82, 87, 89, 87,
-  83, 89, 81, 94, 90, 78, 81, 86, 95, 77,
-  77, 89, 87, 79, 82, 85, 92, 74, 93, 81,
-  99, 95, 76, 85, 93, 85, 79, 82, 85, 81,
-  82, 93, 76, 79, 87, 109, 80, 93, 81, 75,
-  93, 70, 67, 85, 67, 92, 76, 102, 67, 76,
-  92, 88, 85, 84, 76, 98, 78, 84, 98, 93,
-  109, 69, 94, 71, 62, 103, 78, 95, 77, 150,
-  80, 69, 92, 58, 86, 84, 71, 97, 73, 98,
-  75, 79, 77, 77, 82, 70, 89, 96, 70, 88,
-  73, 74, 108, 81, 86, 83, 78, 75, 86, 86,
-  80, 86, 99, 72, 87, 100, 73, 75, 87, 76,
-  71, 54, 88, 86, 59, 82, 77, 85, 74, 95,
-  79, 87, 75, 110, 71, 91, 83, 85, 74, 77,
-  82, 64, 62, 87, 86, 86, 77, 86, 80, 80,
-  64, 77, 77, 92, 99, 113, 82, 78, 81, 97,
-  93, 71, 66, 79, 74, 82, 84, 87, 94, 89,
-  75, 84, 85, 105, 88, 78, 93, 85, 91, 61,
-  75, 79, 81, 79, 85, 107, 80, 71, 80, 80,
-  83, 82, 84, 109, 77, 93, 84, 93, 95, 71,
-  84, 70, 78, 92, 83, 80, 69, 145, 75, 82,
-  94, 63, 78, 84, 73, 91, 74, 92, 80, 89,
-  83, 85, 86, 75, 81, 88, 70, 94, 73, 85,
-  91, 77, 79, 83, 83, 82, 93, 75, 85, 83,
-  82, 73, 93, 91, 74, 72, 83, 82, 71, 75,
-  88, 88, 61, 79, 75, 92, 74, 87, 87, 83,
-  81, 88, 71, 93, 68, 88, 73, 79, 81, 83,
-  67, 80, 78, 82, 84, 91, 82, 83, 69, 91,
-  81, 80, 102, 78, 84, 76, 90, 101, 86, 75,
-  74, 82, 88, 79, 92, 77, 73, 94, 88, 84,
-  89, 91, 88, 82, 95, 87, 85, 60, 85, 82,
-  77, 82, 75, 94, 88, 79, 87, 77, 82, 80,
-  81, 94, 87, 84, 80, 67, 79, 76, 86, 77,
-  88, 88, 84, 78, 80, 102, 86, 87, 94, 77,
-  82, 80, 83, 93, 79, 82, 81, 86, 85, 91,
-  80, 80, 80, 87, 73, 100, 75, 88, 88, 88,
-  84, 89, 91, 99, 90, 80, 92, 86, 84, 78,
-  89, 80, 79, 76, 87, 81, 76, 81, 81, 82,
-  67, 75, 79, 96, 78, 85, 93, 75, 83, 89,
-  81, 95, 80, 90, 77, 83, 80, 92, 77, 80,
-  84, 81, 96, 85, 83, 87, 77, 83, 84, 82,
-  92, 76, 88, 82, 96, 90, 89, 84, 90, 83,
-  85, 79, 94, 82, 93, 88, 106, 78, 82, 98,
-  79, 71, 78, 69, 87, 80, 71, 108, 71, 99,
-  68, 76, 77, 84, 125, 92, 86, 89, 78, 67,
-  92, 80, 102, 79, 105, 64, 114, 88, 77, 108,
-  74, 81, 86, 88, 91, 60, 82, 57, 105, 89,
-  94, 89, 84, 92, 74, 78, 87, 80, 83, 80,
-  94, 88, 91, 77, 88, 74, 105, 66, 94, 89,
-  58, 81, 66, 99, 69, 79, 83, 87, 81, 96,
-  74, 79, 96, 81, 79, 61, 96, 83, 92, 80,
-  87, 70, 76, 101, 87, 89, 79, 90, 85, 97,
-  92, 80, 83, 83, 74, 53, 63, 66, 86, 87,
-  46, 72, 94, 84, 91, 79, 83, 94, 75, 115,
-  86, 104, 85, 64, 91, 88, 81, 84, 65, 77,
-  79, 114, 98, 89, 84, 76, 76, 111, 73, 97,
-  77, 68, 84, 78, 69, 94, 64, 89, 73, 92,
-  74, 71, 104, 92, 95, 80, 75, 79, 79, 85,
-  96, 83, 93, 70, 99, 74, 66, 100, 83, 83,
-  88, 106, 87, 72, 83, 65, 87, 82, 81, 89,
-  77, 93, 80, 82, 83, 77, 83, 74, 85, 87,
-  93, 75, 88, 67, 95, 70, 91, 72, 63, 78,
-  71, 93, 67, 74, 94, 86, 85, 89, 69, 83,
-  94, 80, 76, 69, 92, 75, 79, 83, 79, 71,
-  72, 95, 84, 92, 73, 90, 81, 92, 86, 79,
-  82, 76, 70, 68, 70, 79, 88, 83, 49, 72,
-  84, 84, 76, 77, 79, 88, 81, 101, 82, 90,
-  88, 72, 83, 92, 82, 84, 67, 79, 76, 103,
-  94, 85, 95, 75, 82, 101, 80, 89, 90, 81,
-  78, 70, 78, 85, 80, 88, 68, 93, 82, 76,
-  98, 84, 87, 83, 79, 82, 80, 87, 89, 74,
-  78, 76, 91, 77, 80, 95, 78, 85, 87, 80,
-  78, 97, 84, 76, 87, 79, 89, 90, 83, 93,
-  80, 85, 83, 91, 83, 76, 84, 89, 88, 80,
-  85, 78, 95, 78, 88, 69, 76, 82, 77, 86,
-  85, 84, 93, 87, 86, 84, 72, 79, 87, 75,
-  79, 79, 86, 72, 81, 76, 82, 76, 76, 83,
-  90, 81, 83, 85, 84, 91, 85, 80, 85, 76,
-  72, 85, 78, 96, 91, 79, 67, 84, 84, 84,
-  83, 81, 83, 84, 86, 90, 81, 87, 83, 81,
-  93, 96, 98, 81, 86, 87, 86, 95, 84, 86,
-  88, 79, 97, 79, 58, 102, 79, 88, 94, 85,
-  72, 81, 77, 89, 55, 71, 85, 103, 85, 96,
-  78, 76, 122, 82, 82, 77, 89, 99, 98, 72,
-  76, 83, 77, 78, 84, 92, 76, 79, 70, 77,
-  70, 101, 87, 62, 92, 83, 83, 109, 80, 80,
-  93, 68, 80, 69, 90, 65, 95, 68, 79, 76,
-  80, 88, 72, 75, 62, 82, 79, 98, 81, 87,
-  63, 101, 72, 84, 84, 85, 94, 102, 69, 95,
-  79, 86, 84, 99, 80, 80, 86, 93, 72, 79,
-  94, 73, 79, 73, 94, 98, 79, 68, 83, 69,
-  74, 84, 89, 104, 86, 82, 63, 70, 79, 78,
-  92, 73, 87, 102, 77, 130, 102, 88, 75, 88,
-  75, 71, 84, 66, 81, 88, 86, 84, 101, 75,
-  112, 94, 90, 96, 86, 89, 89, 80, 78, 75,
-  101, 96, 73, 88, 85, 90, 95, 84, 91, 78,
-  97, 80, 87, 90, 82, 94, 84, 107, 90, 89,
-  85, 88, 80, 86, 86, 81, 81, 84, 79, 91,
-  88, 78, 81, 72, 90, 102, 77, 78, 83, 92,
-  87, 79, 77, 74, 76, 83, 82, 83, 72, 71,
-  79, 83, 79, 79, 66, 82, 84, 106, 62, 84,
-  80, 88, 78, 89, 77, 79, 76, 90, 86, 89,
-  83, 87, 88, 81, 96, 98, 82, 79, 82, 76,
-  82, 82, 89, 88, 77, 75, 82, 75, 88, 67,
-  80, 98, 84, 72, 75, 85, 79, 81, 94, 70,
-  86, 80, 95, 92, 94, 89, 79, 77, 101, 73,
-  98, 87, 97, 90, 90, 82, 96, 65, 91, 78,
-  98, 80, 81, 96, 78, 77, 85, 76, 89, 84,
-  95, 83, 84, 82, 79, 74, 96, 83, 84, 79,
-  82, 81, 82, 71, 71, 102, 94, 84, 88, 89,
-  96, 83, 92, 79, 93, 89, 86, 81, 83, 84,
-  84, 77, 90, 80, 78, 76, 74, 105, 86, 86,
-  72, 75, 77, 95, 93, 78, 79, 89, 86, 88,
-  81, 93, 88, 83, 88, 88, 81, 78, 91, 83,
-  83, 77, 78, 88, 87, 82, 90, 86, 85, 78,
-  86, 84, 86, 75, 102, 79, 75, 88, 83, 90,
-  99, 84, 78, 84, 77, 87, 86, 72, 77, 89,
-  82, 84, 81, 87, 78, 86, 89, 76, 85, 85,
-  84, 86, 84, 84, 76, 87, 105, 94, 81, 86,
-  98, 90, 87, 94, 83, 72, 63, 76, 65, 102,
-  78, 86, 79, 86, 72, 82, 71, 66, 64, 68,
-  81, 105, 82, 100, 75, 68, 108, 81, 89, 81,
-  91, 98, 116, 53, 70, 72, 80, 85, 151, 106,
-  92, 77, 61, 75, 69, 104, 92, 61, 78, 107,
-  74, 78, 83, 76, 77, 59, 81, 73, 82, 68,
-  100, 53, 79, 71, 73, 104, 69, 71, 66, 78,
-  54, 92, 92, 64, 99, 92, 83, 80, 91, 88,
-  90, 143, 87, 98, 78, 76, 95, 87, 84, 74,
-  94, 105, 54, 89, 93, 77, 80, 77, 113, 93,
-  81, 69, 90, 71, 60, 55, 88, 105, 75, 73,
-  59, 63, 81, 81, 79, 79, 84, 113, 63, 117,
-  54, 81, 62, 78, 58, 67, 81, 67, 71, 70,
-  78, 83, 91, 68, 53, 103, 78, 96, 81, 85,
-  87, 88, 71, 81, 76, 86, 76, 82, 87, 91,
-  90, 83, 90, 60, 76, 85, 90, 82, 93, 104,
-  99, 58, 84, 75, 82, 113, 87, 76, 80, 90,
-  58, 66, 83, 91, 94, 75, 77, 83, 83, 72,
-  77, 69, 78, 64, 88, 77, 77, 106, 78, 69,
-  69, 87, 83, 84, 76, 75, 81, 69, 69, 97,
-  106, 85, 96, 82, 74, 92, 80, 91, 87, 95,
-  94, 87, 81, 83, 80, 57, 88, 89, 100, 105,
-  77, 74, 86, 108, 84, 82, 103, 93, 83, 75,
-  84, 70, 73, 98, 85, 99, 91, 92, 77, 76,
-  79, 77, 79, 82, 85, 79, 89, 110, 61, 93,
-  80, 74, 85, 64, 90, 85, 84, 79, 88, 70,
-  93, 74, 67, 83, 94, 70, 86, 97, 88, 75,
-  82, 83, 76, 91, 93, 91, 87, 81, 92, 74,
-  85, 77, 83, 86, 74, 80, 89, 85, 82, 73,
-  90, 82, 86, 92, 79, 72, 76, 85, 71, 84,
-  80, 81, 93, 82, 78, 76, 91, 84, 77, 77,
-  79, 84, 84, 85, 79, 85, 80, 93, 85, 81,
-  83, 91, 90, 74, 79, 83, 89, 81, 95, 86,
-  86, 78, 86, 90, 86, 78, 87, 73, 89, 80,
-  91, 82, 87, 73, 84, 90, 85, 76, 115, 79,
-  80, 98, 84, 90, 88, 81, 82, 84, 84, 83,
-  79, 99, 75, 88, 96, 92, 90, 86, 91, 89,
-  91, 74, 78, 82, 87, 93, 73, 88, 83, 88,
-  97, 84, 92, 83, 91, 86, 89, 93, 84, 101,
-  92, 79, 93, 86, 96, 93, 79, 81, 87, 78,
-  69, 80, 70, 78, 85, 104, 89, 96, 77, 63,
-  87, 77, 83, 88, 87, 87, 99, 106, 87, 90,
-  97, 80, 87, 75, 77, 90, 75, 82, 82, 84,
-  80, 88, 77, 95, 88, 88, 81, 75, 90, 89,
-  87, 88, 90, 80, 92, 86, 96, 68, 74, 77,
-  87, 77, 79, 80, 67, 77, 79, 84, 60, 75,
-  96, 76, 93, 95, 85, 67, 100, 85, 96, 93,
-  85, 88, 85, 83, 88, 90, 98, 96, 99, 73,
-  81, 81, 95, 84, 85, 79, 94, 83, 65, 76,
-  83, 100, 74, 70, 65, 87, 91, 87, 85, 73,
-  83, 92, 84, 96, 56, 74, 76, 78, 68, 75,
-  99, 83, 91, 80, 83, 84, 91, 85, 75, 82,
-  80, 100, 82, 90, 85, 92, 73, 84, 66, 87,
-  64, 71, 84, 92, 85, 98, 81, 82, 91, 77,
-  82, 82, 93, 96, 92, 90, 86, 82, 86, 96,
-  82, 93, 86, 81, 66, 75, 84, 84, 84, 78,
-  78, 89, 83, 119, 86, 69, 81, 86, 85, 79,
-  82, 88, 86, 76, 76, 77, 88, 96, 81, 76,
-  80, 81, 55, 89, 80, 76, 84, 86, 87, 83,
-  82, 96, 84, 70, 102, 88, 88, 84, 81, 78,
-  84, 85, 92, 95, 77, 82, 97, 85, 79, 73,
-  97, 87, 86, 72, 82, 79, 68, 103, 88, 98,
-  83, 84, 72, 76, 90, 82, 85, 74, 84, 89,
-  77, 89, 76, 81, 78, 78, 79, 68, 93, 78,
-  87, 84, 84, 72, 84, 74, 72, 81, 89, 82,
-  82, 94, 92, 87, 83, 82, 84, 93, 76, 81,
-  81, 81, 86, 85, 85, 90, 89, 78, 80, 86,
-  86, 91, 78, 76, 87, 75, 79, 94, 91, 93,
-  83, 85, 75, 90, 87, 85, 93, 77, 93, 82,
-  84, 100, 86, 73, 86, 89, 79, 83, 78, 79,
-  83, 81, 81, 86, 84, 92, 80, 76, 79, 91,
-  77, 94, 80, 82, 91, 82, 82, 85, 80, 76,
-  89, 82, 83, 85, 91, 79, 87, 85, 80, 88,
-  94, 78, 86, 81, 89, 88, 84, 79, 92, 89,
-  84, 80, 83, 81, 77, 96, 80, 94, 89, 91,
-  86, 79, 93, 85, 88, 74, 78, 83, 82, 85,
-  89, 87, 86, 80, 91, 79, 87, 82, 88, 87,
-  86, 87, 89, 76, 77, 88, 86, 88, 99, 74,
-  70, 67, 89, 78, 87, 81, 83, 84, 88, 85,
-  65, 87, 89, 88, 88, 92, 95, 71, 83, 61,
-  85, 83, 88, 88, 85, 80, 99, 76, 94, 81,
-  82, 76, 72, 83, 77, 79, 101, 62, 87, 75,
-  66, 92, 83, 87, 84, 103, 91, 91, 66, 91,
-  85, 94, 96, 91, 76, 82, 82, 89, 89, 88,
-  74, 88, 65, 85, 98, 95, 81, 74, 78, 100,
-  80, 101, 83, 85, 98, 92, 83, 94, 84, 92,
-  98, 79, 85, 81, 77, 102, 80, 88, 93, 88,
-  74, 107, 84, 87, 92, 86, 89, 85, 70, 86,
-  81, 77, 79, 88, 84, 87, 92, 69, 68, 103,
-  72, 81, 85, 84, 77, 77, 75, 78, 82, 89,
-  76, 94, 90, 83, 94, 75, 97, 67, 71, 60,
-  74, 90, 99, 87, 82, 101, 82, 73, 61, 92,
-  100, 70, 86, 110, 86, 80, 89, 68, 92, 83,
-  96, 71, 75, 74, 89, 78, 85, 100, 94, 93,
-  79, 73, 73, 95, 88, 92, 81, 72, 79, 86,
-  80, 93, 82, 82, 81, 79, 60, 81, 93, 93,
-  87, 74, 76, 74, 79, 69, 79, 79, 65, 78,
-  78, 83, 76, 99, 89, 60, 76, 98, 82, 88,
-  83, 87, 85, 95, 71, 90, 86, 73, 96, 88,
-  71, 78, 77, 98, 69, 89, 87, 85, 92, 80,
-  77, 74, 74, 86, 103, 77, 54, 78, 67, 91,
-  100, 85, 73, 85, 83, 98, 69, 92, 74, 81,
-  84, 89, 77, 65, 83, 81, 82, 92, 80, 79,
-  101, 97, 92, 83, 78, 89, 86, 83, 83, 93,
-  77, 93, 64, 102, 89, 72, 105, 99, 65, 89,
-  80, 94, 80, 75, 100, 91, 86, 90, 97, 81,
-  76, 86, 70, 83, 92, 94, 90, 79, 85, 66,
-  77, 90, 79, 96, 87, 92, 90, 78, 82, 74,
-  77, 82, 100, 87, 85, 82, 69, 87, 92, 83,
-  96, 70, 63, 74, 69, 99, 83, 75, 80, 85,
-  86, 97, 84, 78, 84, 101, 79, 76, 84, 72,
-  77, 88, 68, 92, 99, 81, 85, 77, 82, 92,
-  76, 77, 103, 84, 90, 81, 92, 71, 84, 79,
-  89, 86, 88, 77, 71, 87, 67, 80, 93, 103,
-  86, 85, 88, 100, 101, 91, 84, 75, 79, 94,
-  78, 88, 88, 88, 88, 84, 73, 91, 76, 94,
-  85, 94, 100, 65, 69, 61, 75, 83, 88, 88,
-  86, 105, 86, 76, 56, 85, 109, 81, 87, 102,
-  78, 73, 90, 68, 95, 83, 93, 78, 79, 91,
-  91, 78, 75, 83, 82, 85, 78, 79, 76, 86,
-  87, 77, 78, 85, 80, 92, 84, 91, 91, 90,
-  85, 73, 66, 83, 93, 91, 89, 89, 77, 85,
-  74, 75, 91, 86, 71, 67, 74, 74, 93, 95,
-  80, 65, 82, 93, 79, 94, 86, 91, 90, 86,
-  77, 97, 87, 87, 98, 76, 75, 74, 90, 101,
-  64, 82, 85, 88, 84, 90, 75, 91, 77, 85,
-  95, 86, 64, 78, 74, 91, 82, 92, 83, 80,
-  84, 75, 62, 94, 77, 87, 82, 100, 82, 74,
-  82, 85, 83, 89, 72, 98, 86, 86, 80, 71,
-  79, 68, 68, 77, 67, 93, 94, 94, 74, 95,
-  78, 68, 73, 88, 112, 75, 103, 95, 63, 76,
-  93, 73, 115, 80, 105, 57, 59, 78, 81, 82,
-  76, 109, 88, 88, 91, 70, 71, 93, 79, 103,
-  67, 89, 91, 84, 74, 96, 83, 71, 88, 74,
-  73, 68, 98, 69, 87, 72, 84, 60, 60, 64,
-  69, 82, 65, 84, 74, 77, 64, 104, 83, 65,
-  83, 108, 73, 78, 85, 78, 74, 81, 63, 94,
-  92, 85, 78, 72, 64, 68, 77, 92, 72, 90,
-  84, 83, 107, 55, 70, 61, 73, 85, 88, 68,
-  67, 71, 52, 86, 103, 92, 76, 86, 82, 97,
-  98, 81, 77, 82, 67, 107, 65, 74, 84, 83,
-  93, 85, 86, 71, 74, 99, 83, 79, 69, 91,
-  89, 91, 86, 82, 71, 90, 56, 80, 85, 82,
-  121, 95, 69, 90, 82, 76, 76, 77, 93, 100,
-  101, 88, 87, 96, 86, 83, 61, 79, 87, 85,
-  80, 65, 90, 65, 78, 85, 84, 99, 89, 90,
-  88, 69, 86, 78, 79, 88, 118, 88, 111, 65,
-  82, 85, 89, 88, 96, 55, 51, 81, 59, 111,
-  80, 72, 82, 70, 85, 91, 85, 96, 86, 101,
-  75, 75, 82, 67, 74, 73, 63, 82, 106, 92,
-  69, 75, 96, 84, 73, 73, 123, 96, 92, 84,
-  99, 72, 77, 83, 95, 85, 71, 80, 88, 90,
-  84, 72, 81, 96, 95, 79, 75, 89, 106, 80,
-  93, 69, 77, 88, 76, 102, 93, 82, 102, 76,
-  77, 91, 79, 101, 78, 86, 88, 70, 71, 71,
-  74, 80, 94, 97, 75, 86, 82, 78, 80, 84,
-  106, 89, 78, 96, 75, 75, 100, 77, 83, 84,
-  90, 80, 73, 95, 95, 80, 82, 92, 79, 90,
-  80, 73, 83, 83, 77, 87, 80, 70, 83, 83,
-  90, 88, 86, 89, 94, 85, 80, 82, 97, 79,
-  86, 89, 86, 91, 85, 73, 77, 81, 74, 81,
-  87, 77, 91, 91, 78, 73, 85, 106, 82, 81,
-  82, 85, 92, 87, 81, 89, 86, 89, 89, 85,
-  88, 71, 85, 93, 73, 81, 85, 90, 87, 86,
-  71, 94, 88, 83, 84, 92, 65, 88, 84, 82,
-  76, 99, 79, 81, 94, 87, 78, 87, 78, 87,
-  75, 101, 73, 74, 92, 89, 90, 82, 81, 99,
-  75, 92, 72, 82, 82, 78, 75, 84, 74, 93,
-  96, 92, 66, 72, 72, 79, 97, 89, 102, 88,
-  80, 91, 68, 76, 95, 87, 103, 87, 95, 77,
-  68, 80, 76, 80, 78, 108, 90, 81, 101, 70,
-  76, 87, 78, 98, 71, 71, 86, 83, 83, 93,
-  83, 84, 102, 90, 96, 70, 97, 73, 90, 74,
-  86, 82, 70, 77, 72, 87, 72, 82, 84, 68,
-  69, 100, 82, 80, 79, 100, 83, 69, 83, 86,
-  85, 90, 71, 86, 91, 91, 76, 76, 85, 72,
-  84, 86, 93, 94, 94, 84, 116, 69, 73, 78,
-  88, 84, 70, 75, 84, 87, 81, 80, 80, 96,
-  79, 79, 83, 86, 107, 82, 85, 85, 62, 92,
-  62, 77, 84, 83, 99, 88, 77, 90, 67, 87,
-  76, 104, 82, 93, 86, 91, 83, 80, 80, 95,
-  59, 84, 74, 88, 105, 86, 71, 85, 70, 91,
-  78, 97, 83, 110, 72, 86, 83, 102, 91, 87,
-  64, 79, 87, 82, 71, 72, 88, 72, 79, 90,
-  89, 93, 104, 81, 83, 73, 95, 75, 77, 88,
-  103, 86, 103, 81, 85, 90, 83, 79, 91, 62,
-  64, 99, 74, 98, 83, 69, 93, 69, 82, 89,
-  96, 92, 70, 85, 81, 82, 89, 90, 79, 82,
-  82, 85, 92, 85, 86, 84, 87, 82, 82, 74,
-  109, 90, 87, 85, 107, 83, 78, 94, 89, 87,
-  66, 78, 91, 92, 88, 85, 77, 82, 85, 77,
-  75, 92, 83, 85, 95, 74, 79, 74, 79, 99,
-  91, 77, 89, 89, 93, 88, 83, 88, 85, 87,
-  84, 93, 88, 86, 89, 87, 72, 85, 77, 90,
-  74, 74, 87, 81, 87, 84, 84, 89, 81, 78,
-  85, 89, 87, 93, 84, 89, 80, 92, 78, 84,
-  88, 90, 92, 77, 87, 81, 79, 87, 79, 92,
-  79, 89, 93, 76, 86, 84, 80, 75, 93, 83,
-  81, 86, 88, 83, 83, 77, 94, 77, 81, 73,
-  84, 73, 78, 80, 107, 95, 90, 105, 81, 90,
-  82, 88, 77, 76, 93, 95, 93, 84, 75, 87,
-  91, 100, 91, 66, 80, 87, 92, 85, 92, 77,
-  84, 86, 74, 86, 74, 82, 88, 92, 82, 88,
-  74, 94, 78, 85, 90, 81, 76, 83, 93, 97,
-  97, 82, 80, 79, 84, 85, 85, 81, 77, 88,
-  86, 84, 79, 91, 78, 82, 81, 77, 101, 97,
-  91, 79, 93, 89, 79, 83, 88, 102, 87, 86,
-  92, 82, 89, 76, 82, 88, 89, 90, 80, 84,
-  79, 89, 86, 87, 91, 80, 74, 80, 69, 81,
-  82, 81, 87, 71, 77, 91, 74, 89, 85, 80,
-  80, 84, 86, 85, 81, 80, 83, 36, 89, 91,
-  88, 87, 76, 83, 92, 84, 79, 87, 84, 85,
-  80, 79, 96, 83, 93, 95, 87, 87, 82, 75,
-  80, 84, 88, 84, 94, 80, 84, 84, 88, 71,
-  88, 75, 79, 68, 86, 92, 74, 87, 84, 85,
-  87, 79, 65, 76, 84, 88, 79, 87, 84, 86,
-  80, 84, 90, 90, 83, 84, 99, 85, 83, 83,
-  86, 82, 87, 88, 83, 81, 78, 87, 83, 81,
-  87, 81, 83, 76, 82, 86, 104, 88, 74, 80,
-  87, 83, 79, 76, 91, 96, 83, 97, 81, 86,
-  86, 89, 84, 86, 92, 90, 76, 80, 75, 87,
-  82, 87, 94, 77, 81, 88, 80, 83, 90, 83,
-  85, 76, 78, 92, 78, 81, 92, 88, 81, 92,
-  82, 92, 76, 85, 85, 52, 90, 97, 86, 82,
-  77, 84, 88, 82, 93, 100, 86, 90, 86, 95,
-  108, 86, 86, 87, 91, 73, 80, 83, 86, 86,
-  88, 79, 87, 90, 88, 80, 86, 76, 82, 73,
-  77, 74, 87, 82, 81, 99, 85, 75, 93, 83,
-  76, 88, 83, 86, 85, 90, 97, 81, 72, 82,
-  88, 99, 81, 81, 98, 88, 81, 87, 89, 82,
-  83, 90, 77, 73, 87, 85, 82, 81, 88, 76,
-  68, 83, 91, 78, 68, 80, 91, 84, 73, 87,
-  64, 66, 76, 70, 69, 74, 76, 90, 83, 83,
-  86, 99, 94, 77, 92, 86, 112, 82, 74, 92,
-  71, 85, 71, 79, 98, 83, 91, 87, 79, 88,
-  87, 82, 85, 109, 84, 91, 91, 70, 84, 89,
-  89, 73, 100, 166, 82, 63, 88, 80, 96, 82,
-  87, 67, 66, 62, 68, 86, 86, 103, 80, 89,
-  80, 81, 89, 82, 79, 94, 83, 78, 80, 87,
-  89, 83, 64, 84, 91, 108, 73, 81, 79, 91,
-  90, 74, 106, 79, 80, 87, 79, 87, 86, 88,
-  89, 95, 97, 84, 71, 92, 79, 80, 80, 69,
-  76, 94, 79, 100, 76, 80, 77, 78, 81, 79,
-  74, 72, 85, 83, 88, 80, 74, 80, 59, 86,
-  81, 83, 70, 85, 96, 87, 80, 76, 67, 65,
-  76, 74, 80, 65, 79, 85, 79, 69, 81, 90,
-  85, 75, 94, 88, 110, 83, 75, 85, 69, 90,
-  70, 75, 96, 86, 94, 75, 87, 88, 89, 84,
-  80, 100, 77, 85, 93, 64, 84, 87, 85, 69,
-  95, 171, 74, 65, 85, 79, 86, 76, 84, 67,
-  64, 62, 72, 72, 85, 97, 112, 77, 88, 89,
-  83, 81, 85, 90, 86, 79, 77, 89, 91, 80,
-  73, 85, 89, 110, 77, 69, 73, 96, 86, 77,
-  102, 74, 83, 85, 79, 85, 78, 101, 90, 92,
-  81, 82, 65, 92, 75, 76, 79, 73, 75, 87,
-  67, 89, 69, 76, 79, 80, 80, 83, 75, 74,
-  76, 81, 82, 77, 82, 83, 73, 87, 87, 75,
-  84, 91, 97, 88, 85, 80, 84, 70, 83, 100,
-  91, 73, 86, 81, 84, 89, 83, 89, 81, 82,
-  85, 86, 83, 85, 83, 87, 82, 85, 65, 80,
-  85, 89, 87, 96, 87, 83, 87, 84, 76, 85,
-  78, 91, 88, 80, 79, 94, 85, 78, 83, 82,
-  80, 83, 88, 89, 77, 83, 83, 73, 77, 82,
-  82, 77, 79, 82, 78, 82, 94, 96, 84, 81,
-  83, 77, 80, 83, 83, 78, 95, 87, 81, 88,
-  88, 85, 76, 70, 77, 75, 83, 87, 83, 83,
-  87, 89, 83, 80, 72, 84, 87, 88, 82, 70,
-  79, 79, 70, 83, 83, 77, 80, 83, 70, 85,
-  79, 78, 85, 80, 76, 91, 91, 81, 80, 83,
-  85, 84, 79, 77, 79, 80, 89, 75, 86, 82,
-  89, 84, 85, 91, 83, 74, 84, 84, 76, 98,
-  85, 84, 92, 87, 86, 88, 96, 87, 73, 80,
-  77, 81, 90, 91, 90, 78, 71, 86, 75, 88,
-  78, 94, 81, 74, 77, 82, 84, 95, 90, 85,
-  79, 92, 86, 94, 88, 85, 88, 60, 77, 84,
-  83, 88, 90, 93, 92, 93, 81, 82, 93, 93,
-  83, 82, 62, 80, 83, 84, 74, 85, 77, 81,
-  59, 79, 93, 78, 89, 90, 79, 86, 93, 69,
-  73, 88, 95, 80, 84, 94, 87, 89, 76, 94,
-  81, 79, 76, 56, 83, 91, 84, 81, 83, 87,
-  73, 79, 80, 86, 80, 82, 97, 85, 83, 88,
-  88, 68, 89, 84, 89, 79, 91, 85, 83, 80,
-  73, 87, 70, 80, 84, 73, 74, 82, 92, 90,
-  79, 91, 69, 86, 78, 71, 74, 76, 88, 88,
-  84, 74, 92, 94, 96, 87, 82, 85, 94, 82,
-  82, 96, 77, 73, 84, 86, 79, 85, 84, 79,
-  79, 78, 76, 78, 83, 94, 80, 78, 85, 78,
-  92, 83, 88, 84, 94, 105, 79, 80, 90, 79,
-  93, 87, 89, 84, 70, 66, 79, 94, 91, 86,
-  64, 77, 89, 76, 81, 90, 84, 83, 73, 79,
-  83, 91, 90, 91, 75, 83, 88, 95, 81, 89,
-  97, 80, 91, 85, 92, 82, 81, 92, 80, 82,
-  79, 72, 90, 93, 88, 82, 75, 86, 91, 79,
-  83, 82, 83, 83, 86, 88, 75, 82, 75, 73,
-  82, 84, 82, 79, 84, 86, 87, 76, 79, 79,
-  74, 80, 83, 89, 66, 86, 87, 91, 78, 91,
-  71, 83, 66, 72, 75, 64, 80, 94, 82, 73,
-  99, 90, 85, 78, 93, 88, 90, 96, 78, 93,
-  73, 82, 81, 92, 104, 83, 97, 84, 80, 82,
-  85, 76, 79, 89, 71, 95, 101, 75, 87, 76,
-  82, 84, 85, 139, 80, 71, 88, 76, 86, 84,
-  86, 74, 81, 65, 75, 79, 89, 100, 80, 84,
-  88, 76, 79, 88, 84, 91, 93, 82, 77, 92,
-  94, 98, 72, 91, 87, 109, 83, 75, 87, 87,
-  87, 80, 97, 78, 88, 86, 72, 88, 86, 88,
-  91, 93, 93, 79, 74, 80, 86, 75, 84, 75,
-  78, 89, 77, 94, 85, 75, 69, 84, 83, 86,
-  81, 74, 78, 89, 87, 89, 76, 74, 89, 89,
-  79, 80, 70, 76, 72, 76, 69, 93, 79, 101,
-  69, 83, 81, 68, 84, 81, 83, 101, 95, 81,
-  82, 94, 80, 78, 100, 86, 122, 98, 82, 93,
-  90, 85, 86, 82, 95, 84, 80, 89, 74, 93,
-  74, 68, 80, 81, 88, 83, 87, 73, 78, 87,
-  80, 87, 80, 78, 83, 73, 81, 87, 88, 83,
-  90, 70, 83, 98, 89, 86, 79, 84, 64, 98,
-  80, 84, 70, 89, 89, 70, 82, 76, 60, 100,
-  95, 84, 90, 98, 74, 81, 72, 78, 94, 77,
-  86, 81, 81, 101, 97, 68, 81, 91, 72, 75,
-  82, 83, 87, 80, 72, 95, 82, 91, 89, 79,
-  73, 83, 81, 84, 98, 93, 75, 141, 76, 88,
-  73, 89, 94, 77, 87, 73, 82, 82, 85, 88,
-  75, 78, 75, 75, 61, 97, 81, 92, 72, 85,
-  89, 71, 84, 84, 82, 101, 84, 77, 82, 100,
-  73, 75, 107, 90, 134, 94, 80, 86, 89, 83,
-  86, 76, 92, 89, 80, 91, 83, 98, 77, 71,
-  84, 77, 78, 82, 94, 81, 80, 91, 78, 82,
-  78, 81, 86, 66, 77, 79, 91, 79, 83, 75,
-  84, 94, 89, 76, 81, 79, 64, 96, 80, 81,
-  69, 91, 91, 74, 85, 80, 61, 78, 93, 77,
-  87, 95, 75, 83, 69, 83, 86, 79, 75, 85,
-  80, 106, 86, 68, 79, 90, 72, 75, 83, 83,
-  88, 80, 73, 90, 86, 88, 89, 84, 73, 81,
-  77, 80, 95, 90, 82, 137, 77, 82, 71, 84,
-  98, 73, 82, 77, 88, 89, 82, 87, 69, 81,
-  72, 76, 75, 85, 83, 86, 71, 84, 80, 80,
-  86, 91, 78, 86, 83, 84, 77, 92, 79, 78,
-  97, 87, 117, 97, 82, 79, 82, 95, 94, 83,
-  85, 86, 87, 86, 88, 88, 73, 82, 88, 90,
-  87, 85, 91, 75, 79, 91, 84, 85, 76, 76,
-  78, 75, 83, 80, 92, 78, 84, 75, 82, 95,
-  89, 85, 89, 83, 76, 93, 85, 89, 72, 83,
-  97, 73, 81, 78, 61, 72, 97, 78, 85, 95,
-  76, 81, 77, 99, 94, 78, 85, 81, 83, 97,
-  91, 70, 80, 99, 76, 76, 81, 82, 79, 86,
-  75, 98, 84, 92, 85, 88, 79, 83, 83, 84,
-  92, 87, 94, 131, 77, 86, 74, 85, 93, 70,
-  89, 86, 77, 81, 81, 82, 77, 73, 73, 78,
-  75, 91, 81, 89, 82, 83, 82, 73, 80, 81,
-  87, 96, 85, 87, 85, 81, 81, 78, 91, 80,
-  114, 90, 85, 97, 95, 82, 91, 83, 88, 84,
-  85, 90, 72, 93, 77, 80, 92, 84, 80, 89,
-  91, 79, 86, 82, 83, 84, 83, 80, 79, 74,
-  87, 79, 91, 79, 83, 69, 86, 87, 79, 74,
-  82, 92, 67, 89, 89, 81, 62, 90, 86, 74,
-  87, 79, 62, 84, 96, 80, 87, 100, 83, 91,
-  73, 76, 89, 68, 79, 84, 81, 101, 98, 71,
-  78, 84, 76, 75, 93, 81, 86, 75, 85, 103,
-  84, 81, 89, 80, 78, 75, 80, 85, 102, 83,
-  80, 112, 82, 87, 73, 87, 100, 78, 98, 89,
-  81, 76, 82, 89, 78, 75, 76, 83, 71, 93,
-  89, 84, 84, 84, 88, 73, 83, 86, 77, 96,
-  88, 87, 87, 77, 77, 79, 97, 89, 115, 84,
-  85, 88, 94, 76, 91, 84, 89, 85, 89, 94,
-  80, 99, 83, 80, 95, 78, 73, 88, 94, 83,
-  88, 84, 90, 83, 83, 82, 85, 65, 85, 76,
-  91, 76, 74, 75, 90, 79, 76, 70, 79, 87,
-  67, 83, 88, 79, 65, 89, 79, 78, 89, 76,
-  65, 76, 89, 76, 76, 93, 84, 96, 71, 74,
-  86, 65, 72, 83, 80, 101, 89, 77, 79, 86,
-  87, 75, 89, 87, 86, 79, 85, 96, 81, 76,
-  93, 76, 72, 69, 79, 79, 94, 81, 84, 98,
-  80, 87, 70, 79, 105, 80, 87, 86, 86, 84,
-  84, 89, 75, 78, 75, 79, 79, 86, 87, 84,
-  80, 83, 76, 77, 82, 84, 74, 83, 83, 92,
-  86, 78, 79, 80, 87, 82, 104, 90, 87, 82,
-  81, 92, 86, 81, 90, 81, 87, 87, 90, 91,
-  79, 87, 90, 85, 80, 88, 93, 77, 85, 88,
-  85, 85, 81, 75, 78, 72, 86, 82, 92, 76,
-  75, 75, 86, 90, 75, 68, 87, 90, 73, 86,
-  85, 86, 66, 80, 84, 77, 86, 79, 62, 74,
-  91, 83, 82, 91, 81, 89, 76, 84, 92, 71,
-  79, 87, 82, 91, 87, 76, 74, 95, 78, 77,
-  89, 82, 81, 82, 83, 100, 84, 81, 86, 84,
-  79, 76, 83, 85, 91, 85, 91, 105, 75, 84,
-  73, 86, 98, 73, 86, 86, 72, 84, 83, 94,
-  72, 73, 68, 77, 86, 82, 85, 83, 86, 89,
-  75, 75, 82, 79, 80, 92, 88, 94, 91, 77,
-  82, 80, 86, 81, 97, 95, 84, 99, 94, 90,
-  91, 84, 92, 89, 94, 81, 75, 83, 82, 72,
-  88, 86, 84, 83, 87, 77, 85, 82, 86, 84,
-  75, 83, 73, 81, 92, 84, 85, 83, 83, 74,
-  85, 90, 79, 75, 94, 87, 76, 81, 90, 79,
-  69, 86, 90, 74, 85, 84, 61, 83, 88, 87,
-  87, 100, 81, 84, 79, 81, 97, 77, 86, 93,
-  86, 97, 94, 79, 78, 85, 83, 77, 89, 76,
-  80, 78, 85, 100, 89, 77, 82, 76, 81, 81,
-  82, 87, 96, 85, 78, 113, 79, 94, 79, 96,
-  97, 77, 83, 92, 82, 83, 83, 90, 73, 76,
-  72, 82, 86, 82, 88, 88, 83, 87, 75, 77,
-  86, 84, 77, 87, 90, 98, 87, 76, 88, 81,
-  89, 89, 89, 91, 93, 85, 92, 81, 90, 85,
-  86, 86, 94, 80, 78, 85, 84, 76, 88, 81,
-  82, 86, 84, 79, 88, 82, 90, 85, 77, 83,
-  78, 73, 86, 87, 89, 81, 75, 74, 90, 83,
-  77, 78, 83, 84, 78, 76, 92, 79, 69, 83,
-  87, 76, 87, 82, 66, 77, 81, 86, 79, 92,
-  85, 86, 80, 76, 99, 77, 86, 93, 88, 91,
-  89, 80, 83, 84, 86, 77, 81, 78, 80, 81,
-  81, 101, 87, 72, 88, 75, 78, 76, 88, 84,
-  89, 88, 85, 101, 80, 93, 79, 92, 101, 81,
-  86, 86, 86, 83, 84, 91, 74, 78, 67, 79,
-  88, 81, 91, 93, 80, 86, 70, 79, 86, 86,
-  73, 89, 94, 98, 81, 74, 80, 84, 82, 81,
-  92, 95, 88, 83, 82, 92, 85, 80, 87, 84,
-  92, 79, 77, 83, 81, 71, 88, 85, 80, 83,
-  88, 78, 85, 86, 81, 82, 77, 81, 75, 84,
-  92, 88, 88, 81, 75, 77, 85, 89, 76, 70,
-  79, 89, 80, 80, 92, 83, 72, 81, 84, 79,
-  87, 84, 63, 77, 89, 94, 77, 91, 84, 80,
-  80, 80, 93, 77, 83, 92, 88, 91, 86, 79,
-  73, 89, 89, 79, 84, 84, 78, 84, 86, 97,
-  87, 76, 82, 80, 84, 86, 90, 85, 91, 86,
-  91, 102, 76, 89, 82, 92, 96, 81, 94, 70,
-  93, 84, 76, 93, 75, 86, 85, 83, 74, 86,
-  77, 90, 72, 83, 82, 82, 96, 92, 84, 84,
-  82, 79, 82, 85, 81, 94, 97, 73, 101, 105,
-  95, 96, 87, 96, 86, 74, 93, 70, 92, 67,
-  80, 88, 91, 81, 76, 75, 87, 76, 91, 75,
-  84, 87, 103, 93, 91, 70, 84, 76, 97, 84,
-  95, 84, 83, 88, 81, 87, 80, 83, 75, 83,
-  86, 88, 83, 80, 86, 74, 76, 83, 86, 77,
-  86, 97, 73, 81, 85, 82, 91, 86, 91, 90,
-  93, 69, 73, 112, 93, 85, 84, 72, 69, 76,
-  92, 84, 83, 78, 76, 91, 79, 81, 89, 99,
-  91, 98, 90, 96, 84, 83, 80, 91, 79, 96,
-  71, 86, 86, 88, 102, 75, 80, 80, 79, 72,
-  83, 101, 76, 85, 79, 81, 70, 83, 83, 91,
-  79, 80, 87, 76, 70, 84, 76, 81, 66, 83,
-  71, 97, 73, 80, 91, 83, 97, 89, 74, 88,
-  84, 89, 90, 88, 83, 74, 79, 65, 91, 88,
-  93, 74, 68, 73, 92, 93, 84, 80, 86, 72,
-  96, 89, 70, 76, 94, 84, 94, 79, 88, 73,
-  76, 78, 77, 75, 65, 78, 88, 88, 82, 83,
-  77, 66, 84, 76, 78, 77, 85, 78, 71, 81,
-  78, 72, 82, 84, 90, 87, 80, 88, 97, 76,
-  65, 109, 91, 87, 74, 64, 71, 89, 91, 90,
-  89, 68, 65, 81, 68, 93, 81, 89, 88, 97,
-  84, 86, 76, 91, 74, 91, 81, 111, 76, 85,
-  78, 83, 90, 75, 81, 76, 77, 69, 82, 86,
-  78, 92, 80, 86, 78, 81, 99, 84, 79, 83,
-  91, 79, 60, 84, 82, 77, 79, 92, 84, 88,
-  78, 75, 78, 91, 95, 76, 77, 79, 87, 78,
-  91, 89, 84, 77, 83, 70, 92, 83, 96, 75,
-  79, 96, 89, 99, 76, 76, 87, 70, 93, 88,
-  60, 86, 93, 93, 92, 80, 80, 83, 92, 82,
-  92, 79, 56, 82, 86, 92, 100, 82, 85, 65,
-  79, 86, 71, 86, 79, 78, 78, 85, 80, 76,
-  81, 92, 96, 84, 74, 79, 94, 92, 83, 94,
-  83, 97, 71, 88, 79, 82, 94, 94, 91, 68,
-  67, 81, 76, 84, 88, 75, 88, 95, 88, 89,
-  96, 98, 82, 88, 91, 104, 90, 78, 78, 90,
-  74, 84, 88, 74, 89, 87, 77, 92, 76, 85,
-  88, 86, 86, 79, 78, 84, 71, 74, 81, 92,
-  114, 84, 73, 82, 78, 73, 98, 78, 83, 98,
-  104, 69, 83, 104, 110, 91, 91, 94, 83, 70,
-  83, 65, 97, 76, 98, 79, 89, 93, 92, 81,
-  78, 79, 91, 82, 82, 107, 114, 84, 97, 57,
-  85, 82, 89, 93, 101, 71, 68, 101, 75, 86,
-  78, 69, 82, 73, 81, 75, 86, 76, 75, 76,
-  77, 86, 84, 84, 93, 96, 74, 83, 84, 80,
-  86, 80, 90, 82, 81, 72, 81, 102, 89, 80,
-  81, 89, 69, 73, 86, 83, 69, 77, 85, 87,
-  88, 66, 89, 94, 93, 85, 88, 95, 79, 77,
-  79, 74, 79, 71, 83, 73, 101, 85, 104, 83,
-  79, 80, 77, 78, 89, 104, 68, 80, 81, 83,
-  72, 84, 76, 94, 77, 75, 90, 83, 93, 84,
-  70, 90, 59, 74, 87, 87, 75, 86, 113, 69,
-  96, 101, 86, 95, 87, 94, 77, 86, 81, 64,
-  106, 72, 110, 91, 93, 85, 71, 73, 91, 82,
-  86, 83, 82, 87, 104, 88, 84, 67, 89, 69,
-  93, 89, 97, 70, 54, 77, 75, 83, 69, 67,
-  87, 72, 67, 83, 75, 71, 76, 76, 80, 79,
-  86, 88, 73, 81, 81, 80, 75, 80, 82, 80,
-  89, 88, 96, 76, 70, 123, 97, 84, 70, 63,
-  71, 87, 85, 86, 76, 63, 78, 85, 73, 81,
-  80, 105, 92, 86, 84, 80, 72, 87, 75, 87,
-  70, 92, 70, 79, 90, 80, 107, 72, 75, 81,
-  77, 72, 85, 94, 71, 80, 82, 82, 70, 82,
-  96, 87, 84, 87, 93, 75, 66, 80, 79, 88,
-  78, 88, 91, 92, 72, 80, 93, 86, 92, 88,
-  77, 85, 84, 87, 79, 93, 88, 84, 101, 69,
-  102, 88, 83, 81, 80, 81, 93, 98, 73, 81,
-  88, 73, 91, 86, 68, 88, 96, 79, 91, 87,
-  91, 70, 77, 81, 90, 81, 63, 75, 79, 78,
-  85, 75, 78, 64, 79, 77, 82, 80, 84, 84,
-  71, 88, 84, 83, 76, 86, 91, 83, 77, 79,
-  108, 85, 71, 110, 80, 91, 73, 72, 78, 87,
-  84, 91, 86, 73, 76, 82, 70, 96, 81, 87,
-  85, 88, 86, 89, 97, 94, 80, 97, 82, 111,
-  87, 82, 86, 87, 87, 76, 77, 84, 86, 92,
-  73, 71, 92, 84, 78, 92, 87, 68, 86, 78,
-  70, 87, 67, 90, 101, 79, 79, 89, 86, 93,
-  91, 83, 97, 96, 79, 64, 77, 92, 106, 89,
-  81, 90, 83, 75, 83, 69, 91, 82, 86, 73,
-  96, 98, 101, 87, 79, 93, 87, 90, 84, 100,
-  98, 81, 85, 76, 80, 98, 83, 86, 93, 79,
-  73, 111, 81, 86, 78, 73, 86, 84, 85, 75,
-  93, 72, 77, 81, 91, 85, 92, 85, 95, 91,
-  78, 84, 93, 77, 96, 81, 70, 76, 78, 80,
-  75, 79, 77, 77, 78, 91, 76, 81, 91, 78,
-  69, 82, 91, 86, 81, 73, 95, 77, 86, 76,
-  90, 97, 88, 73, 82, 86, 82, 71, 84, 78,
-  102, 82, 88, 95, 76, 77, 83, 90, 77, 93,
-  77, 81, 79, 86, 86, 82, 76, 85, 66, 79,
-  78, 89, 104, 82, 79, 97, 63, 82, 86, 76,
-  94, 88, 99, 64, 87, 110, 102, 94, 93, 91,
-  70, 89, 83, 62, 106, 71, 89, 89, 97, 96,
-  80, 79, 85, 82, 86, 88, 79, 100, 102, 78,
-  94, 71, 76, 80, 84, 91, 92, 80, 66, 92,
-  78, 85, 76, 78, 89, 66, 74, 83, 79, 71,
-  76, 81, 83, 85, 85, 87, 87, 86, 75, 85,
-  75, 81, 80, 78, 94, 79, 80, 81, 77, 102,
-  96, 79, 77, 82, 78, 80, 89, 79, 65, 76,
-  85, 89, 82, 69, 90, 103, 94, 81, 95, 88,
-  84, 74, 73, 88, 75, 71, 75, 78, 97, 78,
-  103, 85, 86, 74, 81, 88, 74, 103, 76, 75,
-  81, 84, 76, 80, 93, 90, 75, 84, 82, 80,
-  80, 79, 87, 93, 73, 94, 85, 87, 86, 85,
-  94, 90, 91, 104, 86, 93, 83, 91, 75, 99,
-  91, 83, 113, 75, 81, 89, 87, 85, 86, 88,
-  91, 88, 79, 84, 84, 85, 96, 80, 90, 87,
-  81, 79, 87, 83, 91, 76, 76, 89, 84, 80,
-  80, 89, 76, 72, 85, 80, 81, 73, 85, 72,
-  77, 85, 86, 88, 75, 88, 82, 93, 67, 84,
-  87, 75, 92, 76, 100, 85, 77, 98, 88, 88,
-  83, 81, 81, 82, 93, 81, 84, 81, 75, 91,
-  77, 86, 88, 92, 88, 87, 92, 88, 105, 84,
-  80, 87, 88, 86, 81, 81, 90, 82, 97, 80,
-  99, 83, 74, 79, 89, 88, 69, 86, 91, 80,
-  81, 80, 92, 82, 68, 81, 87, 89, 86, 75,
-  83, 91, 73, 83, 85, 74, 85, 87, 84, 101,
-  88, 92, 72, 80, 79, 91, 73, 84, 92, 81,
-  85, 76, 90, 77, 84, 83, 78, 79, 80, 81,
-  93, 88, 86, 79, 80, 84, 83, 93, 89, 91,
-  90, 80, 96, 88, 87, 87, 98, 93, 75, 87,
-  97, 90, 98, 91, 71, 79, 78, 95, 79, 87,
-  88, 93, 74, 78, 74, 85, 84, 92, 92, 76,
-  82, 100, 74, 85, 88, 91, 91, 87, 71, 82,
-  73, 84, 80, 87, 86, 76, 83, 84, 80, 73,
-  79, 65, 80, 82, 84, 84, 77, 79, 79, 81,
-  103, 79, 84, 88, 92, 94, 95, 89, 83, 86,
-  53, 79, 85, 72, 88, 83, 92, 84, 72, 80,
-  88, 66, 80, 80, 89, 94, 82, 74, 85, 87,
-  72, 85, 88, 90, 88, 83, 80, 78, 88, 79,
-  84, 93, 76, 83, 79, 79, 82, 89, 84, 76,
-  83, 96, 76, 89, 94, 68, 76, 85, 75, 90,
-  95, 80, 88, 88, 99, 86, 87, 79, 83, 74,
-  80, 76, 82, 87, 84, 88, 87, 80, 96, 73,
-  86, 84, 86, 80, 88, 94, 88, 74, 88, 80,
-  85, 67, 79, 65, 79, 77, 88, 82, 75, 91,
-  74, 84, 80, 80, 86, 73, 70, 85, 64, 79,
-  81, 87, 86, 79, 84, 96, 82, 80, 81, 72,
-  89, 82, 67, 78, 73, 76, 81, 89, 95, 82,
-  89, 90, 94, 81, 90, 91, 88, 95, 83, 86,
-  90, 73, 96, 78, 92, 87, 76, 85, 76, 69,
-  93, 82, 92, 93, 84, 81, 81, 83, 74, 78,
-  93, 97, 85, 84, 75, 94, 89, 80, 85, 97,
-  86, 83, 95, 90, 75, 71, 95, 76, 75, 108,
-  78, 91, 97, 74, 81, 83, 70, 98, 88, 87,
-  97, 97, 103, 95, 83, 85, 84, 77, 81, 81,
-  97, 77, 80, 88, 95, 91, 95, 73, 83, 74,
-  93, 82, 97, 86, 99, 75, 92, 80, 80, 81,
-  96, 77, 87, 78, 87, 80, 72, 73, 79, 84,
-  78, 94, 85, 82, 74, 82, 79, 78, 87, 91,
-  90, 84, 86, 98, 86, 79, 82, 80, 90, 80,
-  74, 78, 83, 87, 86, 88, 83, 87, 88, 90,
-  96, 77, 83, 80, 112, 86, 69, 84, 94, 92,
-  67, 71, 76, 83, 85, 86, 81, 114, 59, 77,
-  78, 63, 75, 88, 76, 73, 70, 85, 85, 64,
-  89, 89, 102, 133, 78, 103, 71, 81, 86, 90,
-  129, 82, 116, 57, 94, 85, 77, 61, 94, 64,
-  75, 96, 90, 59, 111, 59, 71, 80, 69, 94,
-  80, 72, 81, 103, 88, 89, 101, 92, 68, 88,
-  93, 103, 95, 93, 68, 96, 96, 85, 66, 76,
-  87, 79, 88, 95, 78, 102, 70, 91, 63, 103,
-  84, 114, 73, 79, 78, 105, 93, 83, 98, 87,
-  92, 95, 85, 92, 81, 124, 81, 93, 89, 85,
-  71, 84, 88, 69, 67, 64, 67, 82, 79, 101,
-  48, 89, 84, 87, 111, 70, 63, 77, 68, 94,
-  91, 92, 95, 93, 63, 78, 77, 125, 89, 80,
-  71, 91, 74, 79, 85, 79, 66, 79, 78, 87,
-  80, 80, 78, 89, 70, 97, 74, 78, 93, 88,
-  88, 108, 84, 89, 87, 86, 80, 87, 105, 69,
-  94, 88, 80, 105, 77, 79, 83, 73, 82, 127,
-  83, 94, 76, 76, 80, 75, 90, 65, 96, 63,
-  78, 94, 88, 78, 66, 68, 47, 87, 78, 93,
-  81, 64, 70, 86, 86, 80, 84, 86, 92, 69,
-  69, 87, 78, 73, 92, 93, 66, 71, 80, 91,
-  60, 80, 81, 81, 86, 74, 88, 69, 90, 73,
-  80, 88, 56, 126, 81, 93, 78, 71, 70, 89,
-  83, 90, 79, 70, 86, 89, 46, 80, 53, 83,
-  83, 85, 107, 89, 88, 84, 73, 75, 85, 124,
-  77, 93, 87, 75, 79, 88, 104, 82, 89, 93,
-  76, 82, 68, 70, 85, 84, 85, 103, 89, 73,
-  80, 99, 72, 83, 84, 95, 89, 88, 77, 79,
-  91, 73, 93, 88, 82, 83, 59, 81, 83, 85,
-  82, 80, 84, 106, 84, 95, 89, 87, 77, 87,
-  69, 103, 90, 81, 102, 83, 92, 88, 78, 89,
-  85, 77, 64, 66, 76, 81, 77, 83, 94, 71,
-  97, 76, 82, 82, 99, 87, 81, 80, 81, 83,
-  92, 78, 91, 80, 86, 73, 85, 79, 88, 79,
-  95, 69, 76, 72, 72, 89, 80, 77, 80, 80,
-  70, 77, 82, 95, 86, 71, 80, 99, 83, 85,
-  85, 87, 93, 83, 56, 69, 73, 85, 82, 90,
-  87, 77, 95, 92, 97, 78, 78, 90, 104, 83,
-  76, 84, 91, 91, 76, 75, 70, 82, 83, 87,
-  88, 118, 62, 80, 75, 72, 80, 79, 74, 88,
-  74, 83, 72, 78, 90, 93, 90, 107, 88, 97,
-  85, 85, 72, 89, 89, 78, 77, 73, 91, 81,
-  85, 74, 80, 77, 74, 99, 90, 73, 100, 87,
-  86, 81, 67, 79, 80, 75, 80, 88, 90, 93,
-  101, 80, 71, 86, 65, 82, 100, 84, 63, 84,
-  90, 83, 65, 77, 87, 83, 85, 81, 83, 92,
-  76, 85, 79, 92, 85, 106, 93, 100, 89, 92,
-  82, 74, 91, 83, 85, 86, 89, 84, 74, 91,
-  78, 93, 82, 83, 92, 86, 81, 83, 80, 73,
-  78, 85, 89, 92, 82, 74, 81, 85, 109, 81,
-  80, 83, 85, 84, 90, 83, 93, 84, 94, 89,
-  73, 83, 90, 83, 84, 89, 80, 84, 88, 97,
-  71, 90, 79, 89, 81, 80, 78, 95, 76, 85,
-  67, 85, 90, 87, 82, 111, 87, 86, 86, 81,
-  71, 68, 104, 83, 66, 88, 85, 89, 76, 97,
-  81, 78, 87, 86, 79, 84, 80, 92, 85, 76,
-  86, 58, 93, 73, 79, 91, 78, 74, 78, 73,
-  63, 90, 71, 81, 85, 80, 42, 73, 83, 85,
-  82, 82, 85, 73, 69, 81, 83, 75, 83, 88,
-  83, 79, 71, 82, 81, 83, 80, 93, 76, 73,
-  81, 77, 87, 66, 79, 82, 72, 69, 79, 91,
-  68, 73, 78, 99, 73, 86, 89, 79, 85, 89,
-  80, 79, 84, 78, 83, 77, 97, 86, 90, 88,
-  88, 70, 87, 97, 83, 92, 97, 84, 81, 82,
-  92, 84, 93, 91, 79, 81, 75, 83, 89, 89,
-  87, 101, 85, 80, 77, 94, 80, 72, 79, 93,
-  82, 87, 74, 92, 89, 77, 90, 90, 79, 84,
-  75, 92, 78, 79, 85, 74, 82, 110, 85, 90,
-  86, 82, 80, 74, 68, 100, 77, 85, 96, 70,
-  95, 94, 85, 90, 79, 84, 66, 72, 91, 78,
-  87, 82, 93, 96, 70, 72, 73, 83, 100, 82,
-  87, 77, 63, 87, 91, 74, 81, 84, 90, 81,
-  77, 80, 82, 81, 84, 98, 76, 77, 78, 92,
-  85, 74, 85, 80, 84, 72, 82, 92, 85, 78,
-  78, 92, 80, 84, 84, 86, 91, 85, 82, 82,
-  84, 88, 85, 74, 77, 86, 88, 91, 99, 78,
-  85, 82, 106, 67, 100, 116, 72, 120, 81, 79,
-  90, 88, 76, 97, 87, 78, 70, 92, 93, 98,
-  121, 109, 77, 122, 71, 69, 83, 73, 81, 116,
-  107, 107, 103, 149, 74, 83, 74, 99, 89, 106,
-  84, 73, 76, 79, 97, 95, 79, 107, 95, 81,
-  87, 83, 84, 88, 81, 75, 101, 90, 87, 93,
-  90, 88, 89, 67, 82, 71, 70, 75, 83, 98,
-  72, 90, 87, 103, 73, 106, 76, 101, 90, 77,
-  91, 69, 75, 82, 71, 64, 86, 76, 79, 110,
-  83, 83, 87, 107, 100, 68, 89, 84, 95, 81,
-  64, 52, 89, 85, 95, 85, 85, 103, 79, 89,
-  74, 111, 79, 96, 64, 80, 93, 78, 84, 106,
-  77, 80, 98, 119, 89, 94, 83, 71, 82, 71,
-  77, 62, 100, 95, 75, 115, 96, 82, 77, 83,
-  72, 83, 97, 81, 79, 84, 73, 83, 80, 84,
-  66, 84, 65, 83, 83, 82, 72, 87, 94, 108,
-  83, 114, 71, 81, 79, 106, 83, 101, 79, 87,
-  74, 76, 98, 82, 82, 93, 87, 90, 76, 98,
-  80, 95, 91, 71, 80, 84, 71, 84, 99, 86,
-  83, 75, 74, 54, 83, 69, 86, 85, 68, 92,
-  76, 100, 80, 87, 75, 94, 84, 72, 89, 90,
-  86, 81, 77, 78, 74, 81, 97, 94, 84, 83,
-  89, 89, 92, 89, 85, 87, 88, 83, 65, 74,
-  80, 81, 83, 82, 84, 96, 78, 75, 73, 86,
-  79, 85, 67, 95, 81, 89, 93, 87, 86, 91,
-  109, 102, 88, 86, 89, 80, 83, 77, 77, 62,
-  84, 79, 83, 91, 95, 84, 79, 73, 87, 82,
-  90, 82, 85, 88, 81, 93, 71, 78, 70, 69,
-  69, 87, 86, 79, 75, 70, 85, 100, 81, 78,
-  79, 80, 87, 91, 85, 93, 87, 83, 76, 88,
-  95, 80, 95, 79, 92, 91, 79, 99, 86, 96,
-  80, 87, 85, 81, 73, 79, 94, 89, 84, 88,
-  76, 64, 84, 88, 89, 80, 80, 90, 83, 87,
-  93, 63, 77, 79, 78, 69, 84, 91, 86, 84,
-  89, 80, 88, 81, 94, 78, 87, 80, 96, 77,
-  75, 91, 79, 93, 89, 89, 66, 95, 83, 81,
-  74, 87, 79, 87, 78, 80, 82, 57, 90, 83,
-  77, 84, 87, 89, 85, 83, 77, 94, 98, 86,
-  74, 77, 86, 90, 82, 83, 93, 80, 105, 106,
-  73, 115, 84, 73, 82, 92, 70, 94, 86, 76,
-  74, 82, 77, 89, 97, 98, 69, 102, 77, 77,
-  84, 76, 85, 102, 83, 103, 80, 128, 72, 79,
-  71, 99, 81, 97, 92, 79, 75, 66, 87, 93,
-  74, 96, 100, 81, 79, 90, 74, 80, 92, 68,
-  82, 83, 83, 90, 87, 85, 88, 70, 73, 77,
-  86, 74, 84, 89, 70, 91, 75, 94, 70, 100,
-  86, 94, 81, 76, 113, 69, 88, 86, 66, 69,
-  80, 92, 82, 101, 82, 85, 86, 91, 89, 76,
-  84, 81, 90, 77, 81, 61, 91, 79, 90, 79,
-  82, 98, 84, 87, 82, 105, 74, 90, 71, 82,
-  78, 86, 83, 100, 78, 78, 101, 101, 91, 92,
-  87, 85, 84, 71, 77, 73, 89, 83, 81, 92,
-  93, 78, 80, 84, 74, 86, 97, 84, 88, 80,
-  72, 76, 59, 76, 63, 81, 66, 85, 87, 85,
-  80, 76, 80, 97, 79, 86, 75, 80, 74, 97,
-  78, 91, 87, 90, 71, 71, 86, 84, 78, 86,
-  99, 91, 78, 98, 84, 83, 95, 66, 71, 80,
-  74, 85, 96, 86, 80, 81, 72, 65, 77, 72,
-  93, 82, 70, 80, 79, 91, 87, 88, 85, 79,
-  79, 73, 92, 94, 93, 89, 77, 76, 74, 88,
-  100, 82, 86, 79, 84, 84, 80, 91, 84, 79,
-  82, 82, 74, 85, 76, 76, 81, 82, 83, 81,
-  83, 81, 79, 80, 75, 81, 78, 86, 81, 93,
-  78, 83, 85, 86, 111, 84, 78, 86, 88, 92,
-  86, 82, 80, 72, 76, 78, 87, 71, 90, 81,
-  86, 75, 94, 86, 93, 89, 89, 81, 85, 88,
-  62, 80, 74, 73, 71, 88, 93, 80, 85, 65,
-  78, 95, 81, 64, 83, 78, 87, 88, 76, 82,
-  94, 79, 70, 89, 84, 85, 97, 81, 92, 93,
-  81, 98, 87, 87, 79, 89, 84, 85, 84, 83,
-  87, 92, 82, 92, 72, 81, 82, 96, 96, 85,
-  85, 86, 81, 82, 100, 66, 82, 70, 78, 71,
-  75, 89, 90, 88, 93, 73, 93, 82, 91, 76,
-  86, 77, 96, 74, 72, 95, 79, 81, 86, 86,
-  79, 101, 77, 82, 76, 87, 77, 81, 88, 85,
-  92, 56, 85, 82, 84, 80, 91, 86, 85, 83,
-  76, 88, 96, 77, 65, 76, 81, 93, 83, 84,
-  94, 81, 83, 92, 76, 113, 82, 77, 87, 80,
-  80, 94, 86, 90, 79, 80, 73, 88, 89, 84,
-  68, 86, 84, 86, 79, 82, 83, 89, 95, 102,
-  77, 113, 76, 78, 72, 89, 90, 88, 93, 96,
-  84, 69, 82, 92, 80, 87, 91, 86, 77, 88,
-  85, 85, 90, 71, 90, 95, 81, 87, 80, 79,
-  84, 77, 75, 82, 85, 77, 95, 83, 72, 87,
-  68, 86, 77, 92, 88, 85, 79, 74, 96, 75,
-  93, 83, 73, 71, 80, 89, 88, 86, 83, 88,
-  85, 95, 78, 82, 77, 80, 96, 82, 81, 76,
-  89, 80, 81, 85, 82, 79, 79, 88, 89, 80,
-  72, 81, 76, 83, 75, 92, 83, 91, 77, 68,
-  103, 83, 85, 86, 90, 98, 84, 81, 82, 72,
-  72, 86, 83, 88, 89, 78, 89, 77, 87, 85,
-  93, 91, 90, 81, 75, 87, 66, 78, 64, 81,
-  70, 83, 84, 83, 79, 72, 84, 92, 82, 85,
-  78, 80, 78, 85, 79, 85, 86, 94, 79, 76,
-  87, 93, 80, 79, 90, 89, 80, 91, 90, 90,
-  84, 78, 83, 87, 77, 86, 88, 87, 85, 84,
-  75, 76, 90, 85, 96, 80, 75, 83, 81, 86,
-  87, 75, 84, 72, 77, 73, 74, 91, 92, 90,
-  84, 71, 84, 82, 95, 73, 84, 80, 90, 88,
-  74, 90, 77, 78, 86, 88, 77, 94, 78, 83,
-  81, 85, 80, 74, 81, 83, 88, 65, 75, 79,
-  82, 81, 86, 88, 76, 87, 83, 76, 106, 76,
-  65, 83, 83, 93, 87, 91, 80, 75, 73, 84,
-  86, 80, 82, 83, 87, 74, 95, 87, 87, 91,
-  82, 84, 78, 95, 71, 81, 75, 74, 79, 81,
-  94, 69, 86, 69, 78, 95, 83, 72, 82, 77,
-  84, 85, 80, 82, 93, 79, 81, 91, 82, 88,
-  94, 83, 95, 97, 80, 92, 86, 91, 71, 97,
-  86, 87, 83, 84, 83, 86, 87, 91, 81, 86,
-  87, 96, 89, 82, 82, 84, 78, 83, 97, 56,
-  81, 69, 79, 69, 70, 80, 87, 90, 95, 70,
-  93, 75, 90, 73, 82, 77, 98, 76, 71, 89,
-  76, 78, 89, 85, 81, 101, 82, 92, 82, 85,
-  79, 77, 81, 86, 99, 57, 78, 78, 81, 80,
-  91, 91, 94, 78, 76, 85, 98, 74, 70, 72,
-  78, 91, 87, 90, 79, 86, 84, 83, 71, 91,
-  92, 66, 83, 65, 70, 72, 87, 85, 80, 68,
-  79, 86, 70, 85, 84, 89, 86, 102, 71, 82,
-  82, 87, 89, 86, 91, 81, 87, 74, 71, 80,
-  73, 113, 85, 83, 80, 69, 92, 87, 71, 77,
-  76, 83, 87, 83, 83, 96, 92, 96, 91, 75,
-  79, 87, 85, 84, 104, 83, 86, 76, 71, 81,
-  89, 91, 80, 71, 66, 83, 79, 86, 69, 80,
-  77, 79, 80, 66, 93, 80, 83, 86, 90, 81,
-  75, 86, 99, 86, 66, 73, 85, 102, 71, 100,
-  90, 83, 82, 81, 70, 82, 81, 79, 104, 88,
-  70, 91, 78, 72, 79, 76, 83, 95, 93, 92,
-  105, 98, 70, 97, 96, 78, 77, 67, 89, 71,
-  77, 119, 76, 97, 72, 86, 73, 67, 84, 73,
-  81, 63, 74, 71, 91, 85, 81, 70, 85, 92,
-  62, 102, 90, 84, 72, 95, 70, 83, 85, 86,
-  94, 66, 86, 85, 88, 73, 76, 62, 75, 125,
-  87, 81, 85, 69, 84, 90, 75, 74, 85, 72,
-  88, 81, 82, 90, 100, 98, 87, 86, 74, 95,
-  86, 91, 102, 77, 92, 84, 57, 88, 93, 93,
-  79, 61, 80, 78, 76, 86, 68, 73, 80, 70,
-  85, 63, 94, 80, 88, 79, 86, 70, 82, 79,
-  116, 81, 69, 82, 78, 107, 63, 96, 91, 94,
-  82, 77, 73, 87, 87, 84, 96, 94, 73, 91,
-  70, 73, 75, 76, 83, 77, 89, 84, 78, 93,
-  61, 96, 90, 76, 74, 68, 88, 78, 73, 128,
-  74, 100, 70, 73, 78, 88, 91, 74, 83, 66,
-  70, 85, 92, 79, 84, 76, 81, 82, 72, 99,
-  89, 86, 87, 103, 67, 87, 88, 83, 79, 61,
-  87, 84, 85, 72, 85, 79, 84, 108, 82, 79,
-  80, 65, 81, 86, 81, 81, 81, 84, 95, 80,
-  78, 83, 89, 98, 93, 84, 78, 90, 88, 83,
-  97, 83, 82, 74, 82, 82, 87, 87, 83, 65,
-  107, 85, 95, 82, 74, 77, 80, 85, 85, 71,
-  97, 75, 82, 84, 82, 74, 94, 85, 93, 91,
-  68, 81, 86, 103, 82, 103, 94, 76, 80, 81,
-  73, 89, 84, 81, 101, 87, 74, 90, 84, 75,
-  78, 77, 86, 75, 71, 87, 70, 99, 78, 96,
-  89, 85, 78, 72, 88, 77, 77, 106, 89, 88,
-  76, 103, 83, 95, 83, 71, 85, 79, 66, 79,
-  82, 85, 76, 77, 89, 82, 87, 70, 94, 89,
-  74, 98, 85, 85, 85, 86, 87, 74, 98, 77,
-  77, 83, 61, 81, 73, 127, 89, 84, 89, 73,
-  82, 84, 70, 83, 74, 83, 79, 76, 100, 82,
-  86, 95, 97, 83, 82, 82, 89, 90, 106, 67,
-  69, 70, 60, 92, 83, 89, 88, 55, 75, 90,
-  77, 93, 71, 85, 91, 117, 68, 68, 89, 89,
-  94, 73, 93, 81, 85, 85, 89, 79, 65, 76,
-  85, 114, 70, 88, 86, 88, 91, 79, 66, 84,
-  69, 81, 75, 110, 91, 80, 78, 65, 75, 77,
-  79, 89, 79, 95, 101, 86, 76, 80, 83, 63,
-  85, 64, 85, 80, 81, 95, 87, 94, 73, 106,
-  81, 76, 76, 79, 75, 71, 66, 81, 79, 87,
-  72, 69, 91, 93, 85, 78, 85, 85, 76, 85,
-  91, 89, 80, 76, 91, 66, 100, 86, 74, 87,
-  66, 69, 72, 104, 88, 74, 91, 65, 84, 87,
-  75, 83, 76, 88, 75, 64, 102, 80, 83, 97,
-  99, 88, 93, 81, 105, 85, 110, 76, 82, 78,
-  59, 98, 80, 98, 88, 56, 64, 80, 77, 81,
-  58, 83, 93, 98, 71, 55, 86, 86, 100, 80,
-  96, 79, 88, 78, 81, 68, 67, 76, 79, 117,
-  70, 92, 82, 107, 79, 74, 68, 96, 67, 86,
-  64, 126, 106, 75, 63, 61, 70, 72, 78, 91,
-  78, 100, 84, 77, 69, 81, 82, 66, 75, 64,
-  77, 86, 70, 100, 85, 95, 81, 95, 82, 86,
-  77, 73, 87, 80, 68, 83, 88, 80, 81, 82,
-  89, 82, 90, 78, 77, 91, 88, 98, 82, 81,
-  87, 89, 81, 61, 93, 87, 78, 84, 80, 83,
-  74, 122, 82, 84, 90, 70, 90, 84, 75, 77,
-  83, 103, 85, 76, 89, 80, 89, 93, 92, 86,
-  81, 84, 91, 85, 99, 75, 68, 67, 77, 89,
-  81, 83, 92, 53, 85, 89, 82, 88, 69, 77,
-  88, 83, 76, 71, 92, 86, 91, 90, 87, 85,
-  84, 80, 88, 86, 65, 71, 84, 118, 68, 91,
-  87, 84, 77, 72, 70, 83, 74, 84, 80, 103,
-  89, 84, 76, 72, 74, 81, 83, 94, 73, 83,
-  79, 90, 87, 83, 86, 73, 84, 65, 83, 85,
-  80, 94, 88, 100, 74, 93, 84, 93, 75, 82,
-  81, 92, 69, 88, 78, 81, 72, 79, 93, 71,
-  92, 71, 90, 97, 66, 79, 87, 79, 102, 86,
-  88, 78, 95, 72, 76, 83, 75, 95, 95, 101,
-  93, 90, 92, 70, 68, 87, 78, 82, 84, 88,
-  76, 80, 93, 82, 88, 94, 86, 89, 89, 66,
-  82, 76, 90, 67, 84, 75, 64, 80, 84, 93,
-  106, 78, 97, 93, 94, 81, 69, 90, 95, 108,
-  79, 67, 89, 88, 105, 79, 95, 85, 103, 76,
-  72, 88, 79, 89, 94, 91, 79, 72, 83, 76,
-  87, 72, 75, 93, 83, 80, 58, 94, 98, 80,
-  87, 78, 74, 95, 97, 81, 86, 85, 93, 81,
-  93, 75, 89, 75, 94, 79, 101, 82, 73, 75,
-  82, 91, 81, 94, 80, 89, 69, 86, 70, 82,
-  71, 92, 72, 90, 65, 66, 85, 81, 90, 71,
-  81, 85, 80, 68, 95, 79, 97, 76, 98, 87,
-  106, 77, 79, 89, 79, 86, 95, 64, 77, 72,
-  96, 61, 79, 96, 90, 88, 86, 97, 76, 73,
-  84, 75, 80, 94, 89, 83, 95, 68, 103, 73,
-  94, 77, 97, 79, 73, 86, 83, 109, 103, 77,
-  76, 89, 90, 74, 58, 90, 93, 102, 78, 57,
-  91, 86, 115, 87, 101, 90, 96, 77, 59, 79,
-  82, 87, 95, 85, 85, 78, 72, 88, 80, 69,
-  80, 93, 74, 81, 55, 102, 120, 78, 77, 75,
-  76, 92, 94, 104, 90, 95, 102, 70, 88, 80,
-  95, 74, 83, 89, 98, 83, 67, 74, 93, 87,
-  95, 95, 83, 70, 71, 77, 84, 87, 71, 86,
-  84, 91, 83, 78, 99, 72, 93, 71, 64, 97,
-  87, 82, 88, 79, 96, 88, 82, 81, 95, 83,
-  81, 85, 79, 86, 88, 97, 74, 91, 86, 74,
-  87, 90, 76, 80, 93, 98, 80, 83, 84, 76,
-  89, 90, 88, 81, 81, 74, 86, 77, 93, 78,
-  87, 75, 75, 76, 88, 88, 104, 80, 78, 91,
-  85, 84, 65, 85, 93, 82, 80, 70, 92, 87,
-  98, 94, 93, 99, 75, 75, 71, 82, 78, 77,
-  88, 96, 81, 78, 86, 81, 72, 60, 72, 79,
-  85, 81, 66, 97, 90, 82, 81, 85, 80, 94,
-  97, 118, 83, 88, 100, 88, 94, 81, 95, 81,
-  93, 78, 100, 82, 79, 80, 82, 96, 88, 69,
-  87, 76, 87, 74, 68, 72, 72, 87, 88, 82,
-  85, 75, 90, 79, 72, 81, 71, 83, 87, 96,
-  59, 92, 82, 71, 80, 83, 89, 81, 79, 73,
-  92, 72, 79, 83, 85, 93, 76, 84, 75, 73,
-  89, 73, 80, 92, 83, 92, 81, 94, 84, 79,
-  83, 88, 80, 80, 83, 82, 83, 90, 81, 60,
-  81, 70, 82, 80, 80, 84, 79, 91, 86, 78,
-  97, 66, 77, 90, 108, 95, 86, 76, 84, 79,
-  87, 70, 89, 94, 84, 91, 88, 69, 78, 98,
-  79, 81, 89, 89, 100, 85, 84, 84, 77, 89,
-  88, 76, 81, 84, 91, 71, 88, 82, 74, 94,
-  83, 86, 83, 91, 75, 86, 71, 80, 70, 84,
-  88, 100, 85, 89, 79, 114, 81, 87, 81, 75,
-  94, 79, 74, 82, 69, 90, 92, 81, 79, 78,
-  76, 75, 74, 87, 74, 76, 105, 100, 63, 88,
-  87, 77, 106, 83, 80, 81, 69, 81, 103, 88,
-  87, 87, 76, 91, 72, 69, 67, 76, 75, 88,
-  86, 79, 76, 85, 86, 89, 97, 67, 82, 97,
-  73, 74, 99, 80, 78, 76, 80, 56, 67, 47,
-  69, 71, 72, 86, 114, 95, 77, 86, 97, 77,
-  77, 108, 120, 84, 82, 80, 78, 83, 72, 69,
-  104, 97, 84, 97, 77, 82, 89, 99, 106, 74,
-  85, 85, 114, 68, 83, 76, 70, 91, 90, 91,
-  84, 76, 85, 85, 80, 94, 68, 99, 81, 85,
-  70, 84, 78, 79, 72, 92, 78, 83, 93, 94,
-  84, 82, 95, 99, 82, 111, 83, 74, 82, 85,
-  87, 88, 86, 99, 82, 94, 67, 78, 85, 81,
-  123, 90, 95, 110, 112, 83, 68, 75, 97, 97,
-  124, 87, 83, 110, 72, 91, 75, 82, 81, 94,
-  78, 76, 74, 61, 74, 101, 70, 100, 86, 71,
-  73, 75, 89, 86, 96, 71, 107, 87, 96, 74,
-  91, 85, 80, 75, 83, 59, 59, 54, 66, 90,
-  83, 82, 122, 86, 79, 95, 80, 92, 80, 115,
-  119, 70, 78, 81, 71, 90, 75, 80, 95, 102,
-  70, 103, 67, 81, 86, 77, 126, 71, 88, 80,
-  114, 60, 92, 79, 82, 95, 89, 102, 90, 76,
-  84, 95, 80, 112, 66, 90, 86, 77, 77, 85,
-  82, 70, 85, 96, 77, 94, 94, 82, 79, 74,
-  86, 71, 89, 78, 80, 82, 83, 73, 79, 71,
-  85, 87, 88, 89, 88, 77, 89, 87, 74, 83,
-  83, 89, 74, 86, 75, 83, 84, 68, 79, 85,
-  96, 82, 90, 74, 90, 72, 82, 81, 87, 76,
-  76, 97, 82, 83, 96, 67, 79, 90, 87, 97,
-  87, 90, 82, 93, 89, 80, 89, 85, 76, 92,
-  88, 92, 79, 86, 87, 96, 86, 89, 92, 81,
-  79, 91, 86, 74, 83, 70, 84, 84, 71, 88,
-  89, 83, 96, 88, 95, 76, 83, 81, 82, 80,
-  91, 65, 77, 88, 78, 84, 87, 89, 87, 99,
-  85, 94, 84, 85, 76, 78, 81, 92, 94, 59,
-  98, 79, 82, 92, 88, 86, 85, 96, 76, 85,
-  71, 80, 60, 86, 81, 80, 85, 100, 81, 95,
-  76, 78, 82, 80, 91, 71, 83, 70, 76, 90,
-  87, 87, 90, 77, 83, 78, 67, 77, 78, 78,
-  73, 95, 72, 95, 77, 67, 86, 82, 88, 82,
-  88, 83, 96, 72, 83, 85, 72, 89, 69, 71,
-  77, 81, 84, 77, 82, 78, 86, 92, 91, 87,
-  90, 81, 73, 82, 79, 81, 86, 89, 85, 82,
-  76, 76, 67, 76, 86, 82, 85, 77, 82, 88,
-  79, 82, 96, 73, 79, 88, 95, 91, 90, 86,
-  87, 78, 82, 74, 93, 82, 88, 92, 81, 76,
-  84, 102, 86, 86, 86, 91, 100, 90, 82, 83,
-  79, 90, 85, 75, 80, 90, 86, 67, 85, 81,
-  81, 96, 86, 87, 70, 98, 76, 83, 75, 75,
-  68, 81, 80, 91, 87, 92, 85, 104, 77, 94,
-  79, 69, 89, 71, 79, 86, 74, 94, 87, 91,
-  76, 75, 75, 77, 87, 77, 77, 91, 100, 91,
-  70, 87, 94, 85, 91, 86, 86, 90, 72, 87,
-  88, 77, 85, 85, 73, 85, 71, 57, 72, 83,
-  68, 78, 90, 71, 81, 90, 80, 85, 96, 72,
-  77, 81, 79, 80, 84, 85, 86, 82, 77, 76,
-  75, 66, 82, 80, 76, 82, 112, 80, 73, 94,
-  92, 81, 78, 111, 132, 64, 90, 84, 73, 76,
-  78, 83, 82, 90, 83, 89, 73, 79, 89, 91,
-  109, 83, 86, 76, 104, 64, 82, 71, 91, 91,
-  89, 83, 79, 82, 90, 80, 83, 92, 75, 94,
-  90, 72, 79, 90, 80, 77, 81, 85, 76, 84,
-  85, 90, 84, 77, 85, 76, 90, 84, 82, 77,
-  79, 79, 83, 81, 87, 90, 83, 81, 75, 82,
-  74, 98, 79, 88, 78, 85, 89, 83, 77, 67,
-  95, 79, 82, 87, 92, 79, 92, 76, 89, 74,
-  83, 84, 89, 74, 91, 92, 90, 82, 90, 72,
-  87, 83, 82, 96, 92, 88, 82, 94, 94, 79,
-  93, 87, 78, 93, 88, 90, 82, 89, 95, 95,
-  85, 87, 85, 89, 74, 89, 86, 72, 86, 73,
-  81, 89, 83, 74, 85, 87, 98, 96, 91, 80,
-  78, 81, 83, 88, 102, 70, 80, 80, 77, 85,
-  83, 80, 84, 93, 97, 95, 85, 83, 81, 81,
-  83, 88, 101, 65, 92, 84, 81, 95, 87, 82,
-  91, 89, 77, 90, 77, 76, 67, 79, 86, 80,
-  90, 95, 88, 86, 81, 84, 85, 80, 88, 73,
-  88, 73, 85, 91, 92, 89, 93, 78, 82, 94,
-  73, 85, 74, 84, 77, 87, 77, 77, 79, 72,
-  77, 89, 92, 82, 91, 85, 91, 71, 82, 84,
-  82, 86, 82, 92, 93, 84, 86, 72, 85, 78,
-  80, 97, 97, 92, 87, 88, 85, 82, 85, 87,
-  81, 91, 90, 83, 77, 90, 77, 93, 85, 81,
-  90, 83, 78, 91, 81, 71, 87, 68, 81, 78,
-  83, 90, 88, 84, 96, 83, 89, 75, 88, 81,
-  84, 90, 88, 75, 80, 91, 78, 85, 86, 94,
-  87, 98, 87, 94, 82, 90, 78, 79, 78, 93,
-  95, 67, 84, 82, 79, 96, 85, 84, 77, 99,
-  80, 82, 78, 74, 65, 75, 78, 86, 89, 96,
-  79, 100, 79, 89, 80, 74, 90, 70, 88, 76,
-  82, 97, 86, 92, 87, 72, 78, 90, 82, 76,
-  70, 78, 107, 85, 73, 86, 78, 80, 80, 78,
-  86, 85, 77, 83, 89, 76, 84, 79, 75, 91,
-  78, 67, 83, 86, 71, 85, 88, 76, 82, 92,
-  89, 83, 87, 81, 81, 82, 80, 95, 79, 86,
-  93, 91, 73, 82, 90, 74, 92, 80, 85, 79,
-  104, 79, 76, 85, 90, 71, 77, 102, 111, 77,
-  91, 85, 84, 85, 79, 80, 82, 84, 88, 89,
-  78, 75, 86, 93, 91, 83, 88, 89, 93, 80,
-  82, 83, 87, 93, 76, 85, 75, 90, 89, 75,
-  82, 86, 76, 96, 83, 81, 78, 91, 74, 74,
-  81, 76, 72, 80, 79, 95, 86, 90, 71, 82,
-  76, 72, 90, 103, 69, 97, 70, 83, 70, 96,
-  76, 84, 89, 66, 95, 91, 89, 75, 93, 74,
-  67, 90, 71, 104, 72, 83, 98, 93, 82, 79,
-  75, 91, 88, 84, 86, 80, 90, 96, 73, 87,
-  65, 77, 96, 81, 69, 79, 75, 83, 83, 92,
-  92, 95, 86, 81, 81, 90, 82, 81, 86, 80,
-  69, 85, 105, 79, 90, 81, 69, 84, 77, 76,
-  91, 81, 83, 76, 75, 78, 92, 91, 83, 79,
-  80, 89, 85, 80, 81, 106, 99, 73, 75, 78,
-  60, 80, 93, 82, 91, 89, 76, 76, 85, 81,
-  76, 86, 92, 94, 101, 76, 88, 102, 98, 81,
-  78, 87, 73, 79, 88, 82, 76, 87, 84, 88,
-  96, 73, 76, 85, 74, 91, 74, 85, 75, 67,
-  89, 88, 73, 106, 69, 80, 65, 93, 76, 85,
-  84, 66, 92, 89, 84, 78, 76, 73, 79, 92,
-  72, 104, 77, 85, 95, 91, 83, 73, 78, 81,
-  91, 84, 85, 82, 93, 92, 71, 87, 90, 72,
-  108, 81, 63, 83, 79, 85, 86, 85, 85, 97,
-  79, 83, 79, 85, 78, 81, 84, 82, 72, 79,
-  97, 80, 87, 79, 66, 82, 78, 76, 93, 85,
-  82, 77, 73, 88, 96, 93, 81, 86, 77, 79,
-  83, 85, 81, 108, 103, 69, 75, 76, 60, 81,
-  92, 81, 96, 92, 69, 75, 84, 74, 77, 86,
-  89, 87, 103, 77, 92, 108, 113, 80, 84, 84,
-  66, 75, 74, 83, 76, 91, 83, 92, 77, 73,
-  70, 87, 75, 98, 76, 99, 80, 71, 89, 78,
-  77, 95, 76, 81, 68, 92, 75, 88, 91, 65,
-  91, 87, 86, 88, 63, 75, 90, 93, 82, 97,
-  73, 82, 91, 85, 79, 74, 80, 76, 86, 81,
-  85, 81, 89, 90, 72, 81, 98, 80, 90, 82,
-  71, 85, 74, 87, 81, 83, 83, 95, 90, 86,
-  81, 92, 82, 79, 82, 89, 73, 87, 111, 77,
-  92, 80, 71, 83, 91, 79, 99, 80, 90, 80,
-  76, 91, 96, 93, 83, 79, 75, 75, 86, 84,
-  82, 106, 94, 70, 80, 77, 62, 79, 96, 84,
-  88, 86, 73, 81, 81, 76, 78, 84, 90, 94,
-  98, 78, 89, 96, 97, 79, 74, 79, 68, 81,
-  78, 77, 79, 89, 88, 82, 87, 74, 78, 83,
-  78, 90, 69, 85, 72, 79, 91, 96, 71, 99,
-  64, 76, 74, 96, 81, 95, 89, 80, 103, 84,
-  84, 76, 86, 75, 66, 93, 72, 93, 77, 82,
-  98, 92, 86, 75, 70, 96, 86, 84, 90, 82,
-  92, 103, 77, 83, 54, 77, 95, 84, 76, 80,
-  77, 84, 80, 86, 100, 92, 79, 83, 79, 87,
-  75, 82, 91, 77, 70, 95, 92, 82, 104, 73,
-  79, 78, 77, 74, 82, 71, 85, 73, 78, 80,
-  89, 85, 85, 78, 76, 82, 90, 87, 87, 101,
-  99, 78, 69, 87, 67, 79, 90, 74, 92, 93,
-  83, 76, 84, 78, 79, 89, 99, 79, 89, 76,
-  81, 103, 91, 76, 81, 87, 76, 74, 86, 79,
-  77, 78, 87, 95, 84, 74, 66, 90, 73, 94,
-  73, 91, 77, 78, 93, 82, 72, 113, 61, 72,
-  69, 96, 86, 91, 82, 77, 101, 82, 81, 75,
-  63, 74, 74, 94, 77, 96, 82, 84, 101, 85,
-  93, 72, 67, 90, 93, 82, 89, 82, 98, 113,
-  72, 86, 68, 71, 97, 81, 76, 84, 83, 86,
-  84, 81, 92, 93, 72, 81, 77, 81, 72, 90,
-  90, 77, 66, 92, 84, 90, 104, 71, 76, 75,
-  74, 76, 81, 70, 89, 72, 76, 89, 92, 87,
-  79, 90, 74, 77, 97, 90, 89, 104, 107, 74,
-  64, 81, 68, 79, 87, 72, 100, 98, 75, 72,
-  84, 79, 79, 90, 98, 73, 86, 74, 87, 107,
-  103, 76, 87, 91, 72, 69, 73, 81, 76, 72,
-  87, 100, 63, 72, 56, 92, 72, 99, 72, 103,
-  85, 80, 91, 72, 72, 97, 69, 77, 71, 93,
-  77, 87, 89, 82, 96, 82, 81, 86, 60, 76,
-  88, 96, 85, 95, 79, 81, 89, 75, 87, 72,
-  73, 82, 90, 79, 90, 83, 95, 94, 79, 81,
-  91, 80, 87, 85, 82, 85, 76, 84, 79, 80,
-  88, 90, 83, 78, 81, 89, 79, 78, 88, 88,
-  72, 96, 95, 79, 97, 74, 76, 80, 86, 72,
-  87, 71, 88, 78, 77, 90, 94, 86, 84, 79,
-  76, 75, 91, 86, 87, 100, 95, 77, 72, 83,
-  69, 79, 92, 78, 89, 89, 73, 82, 81, 79,
-  82, 87, 92, 79, 85, 77, 82, 93, 94, 76,
-  80, 88, 75, 75, 79, 75, 78, 80, 92, 86,
-  78, 76, 71, 86, 77, 90, 70, 87, 74, 83,
-  85, 98, 72, 99, 73, 78, 76, 90, 80, 98,
-  96, 88, 113, 92, 84, 76, 81, 78, 68, 95,
-  77, 89, 81, 84, 92, 85, 81, 75, 65, 91,
-  80, 85, 89, 90, 93, 102, 85, 83, 68, 85,
-  83, 83, 83, 83, 73, 87, 82, 88, 97, 96,
-  89, 91, 81, 84, 82, 82, 83, 81, 77, 90,
-  94, 74, 102, 71, 91, 85, 88, 81, 83, 69,
-  87, 73, 79, 80, 81, 80, 91, 77, 79, 83,
-  92, 88, 89, 91, 94, 87, 75, 99, 64, 80,
-  80, 74, 88, 80, 88, 84, 85, 78, 79, 90,
-  92, 75, 90, 80, 83, 96, 87, 77, 81, 90,
-  73, 70, 86, 73, 77, 74, 81, 86, 101, 71,
-  70, 78, 73, 90, 70, 89, 85, 84, 88, 83,
-  70, 104, 69, 78, 72, 87, 82, 96, 92, 86,
-  109, 87, 80, 73, 71, 77, 78, 101, 81, 86,
-  86, 89, 85, 78, 86, 72, 65, 85, 87, 78,
-  90, 93, 101, 106, 84, 89, 65, 80, 80, 79,
-  87, 83, 79, 86, 82, 83, 92, 90, 82, 84,
-  77, 77, 78, 84, 85, 82, 72, 92, 84, 76,
-  106, 68, 92, 86, 79, 80, 84, 68, 93, 72,
-  78, 87, 80, 87, 82, 83, 79, 78, 96, 90,
-  91, 92, 98, 85, 72, 92, 64, 84, 75, 73,
-  91, 84, 76, 87, 84, 78, 81, 90, 94, 68,
-  85, 76, 83, 98, 89, 78, 89, 89, 73, 67,
-  79, 76, 78, 67, 85, 83, 85, 71, 63, 77,
-  72, 91, 71, 95, 97, 84, 82, 70, 75, 98,
-  74, 81, 77, 90, 75, 90, 97, 89, 105, 89,
-  83, 83, 78, 80, 95, 97, 84, 93, 85, 86,
-  81, 70, 86, 70, 68, 78, 85, 72, 85, 91,
-  98, 96, 91, 86, 75, 85, 79, 82, 89, 85,
-  74, 87, 79, 85, 91, 87, 92, 77, 81, 84,
-  85, 81, 84, 89, 78, 96, 96, 75, 102, 71,
-  85, 94, 83, 77, 88, 75, 88, 75, 80, 93,
-  85, 83, 91, 77, 79, 81, 93, 87, 91, 91,
-  93, 82, 75, 88, 66, 81, 82, 79, 84, 81,
-  71, 88, 83, 74, 81, 88, 87, 72, 88, 79,
-  83, 88, 92, 78, 84, 88, 80, 75, 87, 71,
-  79, 81, 93, 79, 92, 72, 74, 78, 74, 87,
-  78, 78, 94, 93, 75, 82, 107, 67, 73, 93,
-  85, 67, 79, 96, 81, 87, 81, 83, 81, 87,
-  72, 94, 80, 78, 92, 75, 90, 95, 95, 94,
-  93, 77, 91, 88, 82, 93, 90, 88, 84, 87,
-  89, 80, 81, 85, 93, 88, 86, 88, 68, 73,
-  76, 93, 104, 71, 98, 84, 90, 83, 87, 93,
-  77, 78, 84, 78, 95, 84, 80, 80, 79, 92,
-  72, 84, 74, 78, 87, 80, 70, 99, 92, 88,
-  98, 68, 94, 73, 85, 93, 88, 80, 88, 102,
-  61, 86, 69, 86, 78, 92, 86, 82, 80, 100,
-  74, 88, 86, 70, 78, 79, 107, 74, 87, 64,
-  77, 94, 84, 94, 81, 85, 88, 87, 98, 68,
-  128, 77, 91, 87, 56, 76, 82, 81, 74, 89,
-  82, 101, 51, 85, 118, 60, 65, 94, 81, 60,
-  82, 77, 79, 97, 85, 99, 78, 89, 82, 70,
-  79, 76, 93, 77, 102, 95, 107, 97, 92, 74,
-  96, 84, 88, 79, 85, 96, 78, 81, 83, 82,
-  82, 83, 86, 97, 87, 90, 57, 64, 75, 73,
-  129, 70, 85, 83, 87, 78, 83, 92, 85, 74,
-  82, 82, 93, 82, 84, 74, 78, 84, 82, 72,
-  62, 70, 81, 70, 70, 88, 92, 81, 106, 61,
-  100, 84, 86, 82, 95, 65, 97, 102, 67, 80,
-  68, 81, 67, 91, 87, 72, 87, 81, 60, 80,
-  96, 70, 63, 82, 116, 70, 92, 69, 79, 101,
-  82, 89, 83, 85, 86, 85, 94, 65, 94, 68,
-  92, 83, 44, 83, 81, 75, 78, 90, 72, 95,
-  80, 89, 97, 73, 73, 89, 83, 72, 85, 75,
-  80, 86, 89, 77, 80, 78, 80, 95, 93, 77,
-  83, 79, 89, 94, 85, 88, 92, 82, 84, 95,
-  94, 82, 97, 90, 85, 90, 83, 81, 75, 89,
-  92, 94, 74, 90, 70, 79, 78, 89, 90, 72,
-  94, 89, 81, 84, 93, 93, 82, 80, 92, 69,
-  93, 82, 91, 88, 82, 82, 87, 84, 68, 78,
-  78, 83, 74, 78, 102, 92, 98, 77, 97, 113,
-  77, 87, 95, 81, 97, 107, 64, 88, 66, 88,
-  94, 88, 82, 90, 78, 101, 77, 81, 84, 69,
-  84, 80, 97, 75, 92, 71, 83, 89, 86, 90,
-  82, 88, 88, 86, 98, 81, 73, 87, 88, 78,
-  68, 89, 84, 88, 88, 75, 86, 87, 76, 86,
-  107, 74, 78, 89, 86, 74, 85, 77, 80, 96,
-  99, 97, 73, 85, 75, 89, 82, 76, 78, 69,
-  93, 94, 101, 88, 94, 82, 89, 82, 78, 92,
-  78, 84, 85, 89, 80, 75, 83, 86, 77, 89,
-  90, 87, 67, 77, 76, 79, 104, 76, 91, 90,
-  87, 77, 88, 101, 69, 73, 80, 77, 88, 71,
-  88, 86, 79, 70, 85, 74, 94, 83, 89, 67,
-  74, 92, 87, 89, 99, 66, 88, 68, 86, 86,
-  84, 86, 87, 81, 64, 84, 74, 85, 67, 82,
-  82, 77, 96, 83, 61, 78, 78, 70, 81, 74,
-  104, 82, 79, 82, 74, 98, 82, 92, 76, 79,
-  94, 87, 91, 64, 119, 85, 102, 81, 53, 83,
-  79, 82, 81, 87, 81, 93, 52, 81, 120, 67,
-  65, 95, 80, 67, 82, 69, 81, 109, 105, 117,
-  68, 89, 79, 67, 77, 78, 88, 67, 105, 96,
-  111, 86, 93, 76, 89, 77, 77, 75, 67, 79,
-  70, 76, 86, 75, 87, 84, 70, 97, 92, 82,
-  57, 68, 71, 62, 121, 76, 74, 79, 83, 70,
-  79, 98, 79, 69, 75, 82, 80, 67, 94, 84,
-  85, 62, 75, 64, 84, 81, 86, 58, 73, 87,
-  90, 78, 104, 55, 95, 75, 90, 76, 92, 72,
-  90, 74, 73, 84, 74, 88, 54, 82, 80, 71,
-  88, 70, 47, 75, 87, 71, 80, 71, 111, 80,
-  78, 80, 73, 105, 81, 88, 77, 76, 80, 82,
-  88, 62, 72, 80, 87, 80, 37, 89, 82, 77,
-  83, 98, 75, 88, 83, 90, 93, 73, 77, 84,
-  83, 80, 89, 84, 77, 95, 98, 85, 74, 73,
-  81, 96, 89, 78, 89, 74, 92, 98, 95, 79,
-  92, 84, 84, 86, 85, 85, 79, 83, 81, 87,
-  81, 77, 86, 87, 77, 92, 80, 86, 73, 77,
-  75, 86, 87, 77, 84, 76, 85, 82, 91, 97,
-  74, 73, 80, 71, 87, 76, 99, 89, 86, 66,
-  80, 78, 84, 82, 81, 74, 76, 85, 94, 89,
-  98, 76, 93, 111, 79, 80, 90, 91, 93, 93,
-  67, 81, 75, 88, 83, 79, 80, 86, 76, 88,
-  68, 78, 76, 69, 87, 73, 96, 82, 82, 83,
-  78, 92, 82, 87, 80, 82, 91, 84, 91, 73,
-  63, 92, 91, 76, 65, 87, 83, 85, 101, 76,
-  74, 84, 92, 85, 89, 83, 82, 82, 91, 84,
-  83, 88, 79, 90, 99, 80, 72, 87, 84, 88,
-  83, 81, 75, 71, 89, 86, 82, 88, 90, 86,
-  68, 80, 81, 92, 80, 79, 91, 89, 80, 73,
-  76, 94, 77, 83, 78, 95, 74, 93, 77, 85,
-  76, 86, 98, 87, 78, 90, 95, 89, 58, 85,
-  88, 86, 90, 77, 88, 91, 82, 82, 88, 89,
-  109, 89, 92, 76, 83, 82, 80, 91, 91, 99,
-  83, 75, 86, 85, 78, 105, 94, 73, 63, 92,
-  84, 87, 74, 88, 81, 89, 83, 95, 58, 95,
-  73, 67, 90, 85, 84, 83, 76, 78, 82, 82,
-  88, 92, 82, 86, 90, 94, 90, 73, 104, 100,
-  94, 83, 74, 87, 75, 84, 99, 87, 73, 88,
-  81, 79, 97, 82, 81, 85, 92, 81, 82, 86,
-  87, 97, 104, 86, 73, 85, 76, 84, 83, 83,
-  89, 70, 90, 86, 96, 85, 82, 83, 65, 77,
-  79, 83, 77, 79, 83, 90, 87, 69, 81, 96,
-  71, 89, 80, 79, 66, 90, 74, 85, 83, 83,
-  97, 81, 75, 94, 91, 83, 63, 88, 88, 90,
-  85, 79, 92, 92, 81, 87, 81, 87, 100, 91,
-  92, 73, 82, 86, 83, 84, 94, 88, 83, 91,
-  87, 78, 80, 101, 100, 71, 68, 90, 80, 84,
-  66, 87, 78, 87, 78, 89, 54, 95, 78, 66,
-  93, 80, 85, 84, 78, 76, 86, 84, 88, 79,
-  82, 82, 90, 89, 89, 75, 79, 97, 86, 89,
-  73, 90, 79, 84, 94, 97, 70, 87, 92, 87,
-  86, 81, 83, 80, 88, 84, 83, 88, 76, 88,
-  95, 75, 71, 79, 72, 87, 87, 83, 97, 73,
-  88, 91, 76, 84, 84, 87, 73, 84, 85, 88,
-  83, 85, 88, 83, 80, 73, 88, 92, 75, 86,
-  73, 78, 81, 88, 82, 87, 71, 83, 96, 72,
-  80, 96, 94, 83, 62, 86, 87, 85, 86, 82,
-  100, 90, 84, 84, 82, 89, 99, 88, 87, 81,
-  80, 95, 87, 92, 91, 101, 84, 107, 82, 81,
-  84, 106, 94, 79, 66, 83, 82, 87, 81, 83,
-  77, 91, 76, 96, 64, 90, 72, 67, 88, 86,
-  84, 85, 83, 72, 85, 80, 87, 81, 88, 88,
-  100, 88, 87, 79, 67, 97, 84, 82, 83, 88,
-  77, 82, 89, 76, 65, 88, 71, 85, 75, 85,
-  75, 92, 84, 77, 96, 91, 68, 75, 73, 87,
-  81, 78, 90, 81, 88, 97, 74, 82, 88, 80,
-  100, 104, 88, 83, 85, 102, 76, 79, 93, 83,
-  81, 93, 84, 70, 84, 75, 81, 85, 95, 93,
-  91, 78, 75, 73, 74, 87, 76, 98, 91, 82,
-  80, 100, 96, 89, 80, 76, 80, 79, 76, 96,
-  84, 95, 92, 80, 95, 90, 85, 81, 81, 70,
-  85, 81, 66, 73, 84, 121, 78, 82, 84, 88,
-  82, 88, 80, 73, 97, 86, 77, 82, 81, 74,
-  89, 85, 90, 84, 92, 80, 86, 85, 95, 96,
-  96, 81, 71, 78, 83, 79, 70, 71, 89, 80,
-  95, 96, 68, 93, 84, 90, 98, 87, 83, 73,
-  92, 80, 82, 89, 32, 78, 65, 79, 68, 84,
-  89, 98, 142, 74, 67, 65, 101, 87, 75, 78,
-  76, 66, 92, 77, 82, 86, 75, 73, 118, 76,
-  89, 84, 68, 78, 67, 80, 81, 79, 68, 105,
-  73, 65, 85, 118, 86, 57, 84, 76, 77, 70,
-  83, 70, 61, 90, 58, 87, 82, 83, 68, 98,
-  70, 64, 72, 88, 84, 79, 71, 103, 81, 93,
-  105, 77, 59, 80, 106, 62, 69, 93, 82, 78,
-  60, 95, 71, 90, 121, 73, 79, 101, 84, 77,
-  67, 72, 82, 70, 63, 95, 87, 68, 82, 73,
-  79, 93, 97, 82, 87, 82, 101, 121, 96, 64,
-  121, 64, 79, 79, 97, 64, 87, 64, 90, 76,
-  83, 92, 72, 71, 133, 76, 77, 62, 92, 81,
-  88, 87, 84, 82, 75, 80, 77, 91, 82, 79,
-  72, 72, 72, 77, 83, 79, 83, 84, 81, 85,
-  75, 97, 96, 83, 88, 79, 90, 72, 97, 88,
-  84, 67, 89, 97, 91, 88, 86, 91, 83, 80,
-  85, 77, 86, 94, 97, 72, 94, 81, 80, 89,
-  82, 79, 87, 71, 89, 79, 84, 100, 98, 88,
-  77, 64, 76, 73, 77, 95, 85, 88, 74, 81,
-  104, 88, 99, 87, 80, 100, 90, 81, 70, 63,
-  82, 57, 78, 88, 81, 84, 81, 76, 85, 86,
-  103, 89, 93, 81, 79, 78, 87, 96, 88, 88,
-  93, 82, 84, 94, 88, 95, 92, 82, 94, 81,
-  77, 75, 100, 86, 89, 90, 95, 90, 117, 91,
-  85, 91, 86, 87, 90, 79, 93, 66, 65, 87,
-  68, 87, 78, 83, 82, 90, 87, 78, 72, 93,
-  76, 80, 81, 89, 84, 64, 98, 86, 95, 93,
-  72, 75, 88, 80, 95, 100, 85, 82, 90, 97,
-  78, 73, 89, 82, 79, 92, 86, 69, 87, 81,
-  80, 91, 94, 107, 85, 78, 82, 85, 77, 83,
-  77, 76, 97, 71, 87, 87, 95, 90, 83, 64,
-  83, 72, 76, 80, 89, 90, 80, 68, 92, 93,
-  78, 81, 87, 70, 74, 84, 75, 70, 88, 128,
-  71, 76, 87, 84, 79, 86, 75, 81, 90, 80,
-  79, 81, 83, 76, 84, 85, 86, 89, 85, 83,
-  85, 86, 94, 98, 74, 81, 87, 81, 84, 88,
-  82, 77, 78, 83, 90, 96, 72, 91, 86, 88,
-  84, 83, 82, 74, 92, 81, 82, 92, 28, 77,
-  66, 73, 76, 86, 94, 98, 146, 76, 81, 80,
-  114, 80, 79, 70, 75, 67, 86, 77, 87, 80,
-  72, 73, 111, 70, 102, 86, 70, 86, 64, 71,
-  76, 85, 71, 105, 80, 77, 87, 134, 87, 59,
-  86, 81, 69, 66, 88, 65, 72, 94, 51, 96,
-  88, 83, 70, 84, 74, 63, 64, 93, 60, 84,
-  74, 81, 91, 79, 91, 65, 56, 77, 100, 59,
-  80, 102, 64, 91, 70, 94, 77, 70, 124, 82,
-  74, 98, 78, 77, 58, 68, 79, 66, 57, 91,
-  91, 84, 78, 76, 68, 81, 92, 84, 79, 82,
-  99, 125, 76, 66, 121, 59, 78, 77, 87, 68,
-  79, 66, 94, 73, 87, 91, 69, 74, 134, 71,
-  77, 62, 84, 82, 79, 88, 86, 88, 77, 84,
-  86, 94, 85, 81, 64, 79, 73, 80, 87, 82,
-  81, 78, 86, 88, 77, 94, 95, 78, 98, 84,
-  86, 79, 73, 91, 91, 44, 88, 101, 88, 85,
-  89, 92, 92, 76, 95, 74, 94, 103, 95, 70,
-  87, 83, 85, 90, 80, 77, 98, 80, 95, 69,
-  93, 85, 92, 94, 77, 56, 76, 68, 71, 86,
-  80, 94, 78, 71, 109, 93, 95, 92, 92, 114,
-  78, 83, 77, 53, 84, 62, 62, 86, 82, 70,
-  74, 77, 78, 87, 101, 85, 91, 77, 80, 77,
-  81, 92, 91, 78, 81, 86, 83, 96, 87, 91,
-  72, 88, 82, 88, 81, 84, 69, 90, 94, 89,
-  90, 98, 120, 90, 81, 91, 74, 87, 84, 82,
-  99, 70, 84, 82, 77, 87, 78, 79, 73, 90,
-  93, 82, 78, 92, 71, 94, 90, 89, 90, 78,
-  92, 77, 82, 95, 81, 77, 86, 79, 83, 82,
-  97, 88, 90, 103, 78, 86, 86, 87, 79, 91,
-  96, 72, 85, 77, 78, 87, 92, 91, 86, 82,
-  85, 84, 78, 83, 83, 68, 96, 83, 86, 95,
-  93, 89, 91, 74, 78, 77, 77, 88, 89, 91,
-  70, 70, 85, 85, 83, 83, 81, 68, 78, 83,
-  74, 70, 88, 121, 87, 83, 83, 85, 91, 83,
-  83, 88, 84, 87, 85, 82, 82, 76, 82, 87,
-  82, 91, 92, 84, 88, 89, 105, 95, 80, 84,
-  104, 82, 86, 90, 95, 79, 61, 89, 88, 90,
-  75, 84, 84, 87, 86, 91, 85, 76, 85, 72,
-  84, 89, 46, 81, 70, 67, 67, 95, 99, 102,
-  119, 82, 81, 89, 101, 79, 73, 75, 73, 70,
-  92, 93, 83, 71, 80, 75, 98, 71, 76, 82,
-  76, 101, 66, 79, 86, 91, 69, 101, 105, 66,
-  85, 100, 75, 74, 82, 81, 72, 77, 84, 79,
-  66, 86, 69, 86, 87, 82, 86, 91, 93, 77,
-  74, 93, 78, 89, 75, 90, 93, 92, 98, 67,
-  59, 71, 92, 68, 83, 97, 68, 83, 66, 83,
-  75, 86, 91, 94, 79, 95, 87, 82, 57, 82,
-  84, 81, 80, 82, 89, 81, 86, 81, 78, 83,
-  88, 84, 81, 90, 93, 105, 74, 81, 104, 62,
-  78, 78, 73, 76, 86, 80, 89, 82, 95, 83,
-  71, 76, 109, 82, 77, 72, 92, 80, 72, 86,
-  94, 77, 82, 82, 74, 91, 94, 81, 77, 91,
-  69, 91, 93, 86, 86, 85, 86, 74, 77, 93,
-  89, 82, 92, 83, 75, 77, 82, 90, 90, 62,
-  78, 99, 93, 81, 86, 85, 103, 73, 88, 78,
-  86, 94, 88, 73, 90, 81, 82, 80, 79, 82,
-  92, 107, 93, 89, 86, 98, 87, 88, 92, 69,
-  73, 73, 73, 100, 85, 88, 83, 73, 97, 87,
-  97, 90, 84, 100, 79, 83, 80, 55, 82, 60,
-  90, 89, 91, 73, 80, 74, 83, 93, 90, 88,
-  99, 76, 79, 72, 87, 84, 84, 83, 90, 84,
-  83, 90, 96, 89, 83, 83, 83, 92, 86, 77,
-  74, 83, 96, 89, 89, 88, 106, 87, 85, 91,
-  82, 86, 86, 81, 72, 84, 89, 91, 79, 82,
-  86, 74, 88, 90, 84, 82, 79, 89, 71, 77,
-  71, 73, 91, 85, 104, 92, 80, 85, 83, 99,
-  67, 84, 89, 87, 87, 76, 78, 100, 78, 85,
-  91, 91, 84, 76, 95, 80, 85, 76, 76, 76,
-  77, 76, 90, 86, 75, 95, 69, 78, 77, 90,
-  82, 83, 80, 82, 93, 83, 82, 84, 90, 74,
-  79, 80, 93, 105, 80, 84, 76, 81, 81, 82,
-  78, 93, 88, 83, 75, 88, 81, 69, 85, 95,
-  86, 87, 87, 94, 69, 81, 88, 80, 87, 89,
-  85, 81, 78, 84, 82, 76, 81, 59, 87, 79,
-  92, 79, 90, 86, 75, 66, 88, 89, 86, 79,
-  77, 68, 81, 106, 90, 75, 86, 86, 93, 78,
-  84, 80, 69, 89, 76, 88, 67, 78, 80, 74,
-  95, 92, 85, 96, 93, 85, 78, 78, 70, 84,
-  89, 85, 90, 88, 75, 80, 93, 98, 72, 95,
-  95, 93, 88, 81, 89, 101, 79, 79, 98, 92,
-  80, 73, 93, 76, 94, 76, 71, 74, 82, 80,
-  81, 85, 71, 97, 72, 78, 82, 90, 83, 75,
-  84, 85, 100, 78, 89, 87, 87, 73, 84, 80,
-  82, 110, 89, 77, 69, 84, 86, 75, 84, 81,
-  91, 80, 84, 77, 74, 67, 84, 91, 83, 89,
-  86, 92, 56, 81, 75, 77, 87, 79, 94, 76,
-  70, 83, 85, 92, 88, 55, 95, 84, 95, 83,
-  96, 89, 80, 70, 89, 84, 87, 86, 70, 61,
-  85, 105, 90, 80, 91, 86, 99, 74, 84, 85,
-  72, 85, 81, 86, 86, 85, 81, 77, 86, 88,
-  83, 78, 77, 90, 76, 78, 74, 78, 87, 86,
-  85, 92, 81, 82, 93, 104, 69, 87, 81, 87,
-  91, 81, 80, 110, 70, 84, 95, 88, 79, 80,
-  92, 83, 94, 81, 80, 75, 77, 88, 94, 83,
-  80, 86, 67, 79, 78, 81, 79, 81, 84, 83,
-  92, 87, 87, 83, 85, 73, 81, 84, 89, 91,
-  89, 82, 77, 82, 85, 87, 71, 81, 96, 84,
-  73, 83, 81, 69, 85, 91, 92, 86, 88, 92,
-  72, 78, 87, 78, 101, 86, 81, 83, 71, 88,
-  83, 86, 78, 59, 86, 79, 85, 81, 87, 90,
-  81, 68, 87, 90, 89, 79, 82, 69, 81, 102,
-  81, 79, 81, 80, 95, 74, 85, 81, 68, 75,
-  86, 83, 67, 82, 93, 86, 101, 79, 94, 94,
-  86, 78, 80, 89, 74, 93, 84, 81, 126, 105,
-  76, 70, 84, 99, 63, 78, 107, 82, 93, 77,
-  98, 77, 89, 96, 83, 81, 75, 73, 85, 88,
-  77, 71, 71, 92, 82, 84, 80, 106, 64, 90,
-  73, 83, 87, 82, 76, 67, 80, 92, 79, 88,
-  83, 67, 95, 69, 82, 80, 86, 91, 87, 87,
-  84, 76, 81, 75, 95, 100, 68, 79, 99, 61,
-  76, 69, 78, 85, 83, 75, 82, 82, 63, 83,
-  77, 79, 58, 78, 89, 73, 98, 70, 80, 84,
-  86, 56, 95, 83, 97, 82, 86, 97, 73, 78,
-  81, 83, 95, 84, 84, 67, 93, 91, 91, 84,
-  98, 92, 94, 88, 77, 97, 58, 100, 79, 78,
-  47, 75, 98, 91, 99, 82, 101, 122, 96, 69,
-  86, 97, 83, 113, 82, 82, 97, 91, 70, 68,
-  99, 95, 75, 84, 112, 100, 104, 77, 121, 71,
-  94, 74, 84, 94, 72, 71, 80, 90, 103, 63,
-  66, 98, 94, 83, 72, 110, 56, 71, 86, 89,
-  92, 81, 78, 53, 85, 101, 87, 83, 83, 77,
-  76, 67, 96, 85, 74, 84, 72, 78, 74, 70,
-  95, 62, 114, 86, 69, 77, 114, 43, 70, 76,
-  77, 83, 80, 68, 78, 94, 52, 76, 66, 78,
-  51, 63, 97, 67, 89, 60, 76, 91, 98, 57,
-  102, 76, 102, 84, 98, 105, 73, 92, 88, 83,
-  88, 94, 75, 64, 115, 86, 82, 97, 96, 100,
-  90, 88, 81, 107, 69, 92, 95, 81, 78, 80,
-  87, 84, 101, 78, 92, 94, 81, 78, 81, 90,
-  76, 94, 81, 79, 77, 102, 86, 69, 94, 103,
-  69, 80, 98, 87, 87, 85, 96, 88, 76, 79,
-  84, 80, 74, 77, 81, 89, 114, 76, 74, 90,
-  84, 93, 86, 94, 69, 79, 70, 87, 84, 85,
-  74, 71, 86, 85, 81, 95, 88, 71, 92, 72,
-  90, 79, 77, 77, 95, 87, 79, 75, 85, 81,
-  80, 81, 76, 83, 97, 64, 79, 83, 83, 81,
-  83, 83, 88, 88, 69, 79, 78, 79, 78, 76,
-  86, 80, 73, 76, 86, 87, 86, 56, 91, 83,
-  89, 84, 89, 97, 75, 81, 83, 88, 90, 82,
-  94, 71, 95, 91, 58, 87, 87, 88, 96, 82,
-  78, 92, 77, 73, 81, 96, 75, 89, 92, 82,
-  87, 78, 90, 88, 90, 73, 67, 100, 89, 96,
-  86, 80, 103, 92, 67, 69, 90, 89, 76, 76,
-  84, 76, 91, 80, 92, 85, 89, 93, 85, 81,
-  80, 80, 80, 91, 77, 73, 78, 83, 92, 92,
-  89, 98, 61, 84, 72, 88, 84, 86, 76, 74,
-  85, 92, 84, 86, 87, 74, 103, 74, 88, 85,
-  90, 85, 101, 81, 97, 69, 72, 69, 85, 96,
-  80, 85, 96, 64, 85, 73, 78, 79, 85, 69,
-  89, 83, 66, 100, 90, 81, 71, 83, 81, 73,
-  109, 78, 87, 88, 81, 57, 89, 90, 93, 79,
-  81, 104, 71, 73, 85, 79, 95, 83, 76, 75,
-  88, 77, 87, 87, 93, 93, 96, 92, 79, 91,
-  71, 92, 93, 91, 64, 76, 93, 89, 85, 78,
-  94, 109, 95, 75, 70, 108, 101, 113, 90, 80,
-  77, 89, 74, 61, 95, 89, 80, 77, 88, 87,
-  89, 75, 99, 72, 93, 77, 87, 89, 74, 81,
-  83, 83, 86, 71, 76, 84, 113, 81, 80, 94,
-  53, 83, 76, 94, 87, 86, 76, 64, 82, 97,
-  86, 84, 83, 79, 96, 71, 102, 92, 85, 89,
-  81, 67, 87, 65, 88, 51, 93, 81, 83, 82,
-  107, 54, 83, 80, 82, 76, 82, 71, 87, 79,
-  57, 96, 77, 87, 57, 74, 84, 65, 93, 73,
-  88, 86, 93, 60, 90, 82, 90, 82, 83, 102,
-  71, 82, 91, 81, 95, 83, 81, 68, 112, 75,
-  75, 89, 83, 99, 92, 88, 88, 96, 79, 95,
-  103, 92, 82, 72, 91, 81, 85, 78, 88, 87,
-  86, 89, 72, 100, 88, 94, 85, 81, 79, 90,
-  93, 70, 91, 92, 78, 77, 74, 87, 89, 82,
-  97, 81, 78, 83, 83, 81, 73, 79, 81, 92,
-  99, 77, 80, 80, 94, 86, 94, 93, 64, 88,
-  71, 92, 75, 80, 73, 80, 86, 83, 85, 88,
-  87, 77, 100, 79, 98, 83, 83, 83, 77, 79,
-  88, 69, 82, 71, 78, 86, 80, 85, 95, 66,
-  85, 84, 81, 72, 80, 84, 89, 85, 69, 85,
-  91, 82, 82, 79, 79, 80, 76, 78, 90, 76,
-  80, 57, 87, 91, 89, 82, 86, 96, 73, 72,
-  87, 89, 92, 85, 101, 76, 87, 83, 67, 86,
-  86, 90, 94, 89, 80, 90, 77, 84, 73, 95,
-  89, 92, 79, 91, 70, 83, 84, 72, 91, 83,
-  82, 110, 108, 107, 96, 93, 86, 89, 88, 80,
-  83, 83, 79, 94, 88, 85, 78, 88, 96, 86,
-  82, 82, 74, 88, 86, 95, 79, 76, 86, 89,
-  61, 88, 93, 86, 83, 87, 84, 82, 80, 81,
-  88, 87, 73, 92, 75, 79, 83, 65, 74, 72,
-  100, 66, 84, 87, 94, 80, 80, 74, 100, 92,
-  73, 84, 73, 79, 83, 68, 96, 85, 75, 85,
-  86, 77, 104, 73, 78, 75, 87, 82, 82, 88,
-  98, 80, 85, 92, 97, 77, 87, 97, 86, 81,
-  85, 87, 86, 93, 82, 90, 71, 87, 101, 93,
-  85, 82, 87, 80, 81, 83, 78, 90, 91, 84,
-  90, 92, 81, 88, 76, 84, 87, 94, 94, 74,
-  80, 91, 84, 79, 88, 66, 98, 78, 79, 109,
-  102, 99, 98, 98, 90, 85, 77, 81, 87, 85,
-  82, 97, 95, 84, 76, 106, 106, 86, 81, 77,
-  65, 95, 86, 90, 76, 72, 84, 86, 57, 96,
-  102, 74, 76, 85, 82, 81, 86, 83, 90, 79,
-  73, 77, 72, 82, 87, 74, 71, 67, 90, 70,
-  90, 81, 97, 76, 81, 63, 109, 85, 78, 87,
-  71, 86, 81, 64, 96, 80, 78, 89, 84, 77,
-  92, 70, 76, 76, 90, 72, 67, 90, 96, 84,
-  87, 85, 93, 82, 89, 90, 82, 82, 79, 93,
-  88, 92, 86, 82, 64, 76, 94, 94, 79, 75,
-  88, 77, 78, 80, 94, 84, 88, 82, 84, 82,
-  85, 94, 81, 82, 94, 89, 86, 85, 76, 94,
-  77, 83, 88, 74, 91, 85, 80, 102, 97, 104,
-  90, 97, 84, 89, 93, 77, 87, 82, 83, 92,
-  79, 77, 78, 96, 95, 83, 85, 76, 71, 89,
-  85, 93, 87, 83, 85, 89, 68, 94, 96, 73,
-  85, 87, 81, 72, 82, 81, 92, 83, 71, 91,
-  80, 79, 82, 77, 80, 79, 103, 70, 92, 87,
-  89, 88, 87, 84, 98, 93, 79, 80, 73, 88,
-  84, 70, 94, 85, 81, 87, 82, 88, 88, 78,
-  80, 68, 84, 75, 85, 84, 90, 81, 83, 96,
-  78, 76, 81, 93, 82, 82, 87, 89, 86, 87,
-  81, 91, 76, 87, 95, 102, 86, 86, 82, 82,
-  83, 78, 88, 90, 87, 80, 93, 89, 82, 87,
-  67, 73, 84, 71, 85, 78, 77, 80, 88, 80,
-  82, 81, 72, 83, 78, 93, 80, 78, 84, 79,
-  82, 91, 78, 100, 79, 70, 85, 80, 88, 81,
-  81, 95, 93, 77, 83, 92, 91, 67, 100, 62,
-  76, 103, 81, 72, 73, 75, 78, 84, 99, 68,
-  110, 83, 83, 76, 86, 106, 77, 85, 85, 81,
-  89, 90, 81, 86, 66, 76, 99, 86, 94, 66,
-  80, 108, 80, 79, 68, 77, 84, 81, 55, 86,
-  81, 83, 77, 77, 86, 58, 89, 84, 70, 78,
-  90, 66, 87, 78, 79, 91, 78, 77, 98, 115,
-  74, 99, 96, 89, 92, 76, 67, 87, 81, 79,
-  72, 85, 88, 87, 108, 83, 75, 82, 84, 97,
-  88, 91, 83, 73, 81, 75, 96, 86, 58, 74,
-  74, 59, 78, 72, 79, 74, 84, 78, 87, 80,
-  66, 106, 75, 77, 70, 66, 79, 77, 85, 94,
-  78, 102, 81, 66, 77, 77, 95, 84, 89, 100,
-  84, 73, 85, 91, 96, 54, 101, 60, 74, 148,
-  83, 66, 73, 65, 74, 88, 99, 61, 121, 82,
-  82, 81, 84, 104, 75, 74, 102, 81, 83, 96,
-  85, 74, 47, 101, 100, 88, 84, 41, 82, 113,
-  72, 62, 68, 82, 92, 83, 46, 108, 76, 77,
-  72, 71, 96, 53, 82, 83, 71, 72, 82, 48,
-  92, 79, 67, 99, 75, 73, 105, 133, 66, 95,
-  104, 90, 83, 87, 66, 90, 68, 74, 83, 71,
-  83, 88, 122, 86, 72, 85, 91, 93, 87, 90,
-  70, 76, 77, 55, 98, 94, 76, 81, 80, 76,
-  86, 83, 74, 85, 85, 84, 86, 79, 74, 97,
-  76, 88, 77, 81, 81, 82, 78, 89, 89, 93,
-  83, 72, 90, 79, 76, 76, 86, 96, 98, 81,
-  84, 82, 84, 68, 77, 71, 79, 96, 77, 76,
-  77, 81, 78, 84, 95, 74, 97, 78, 84, 74,
-  87, 82, 70, 89, 85, 82, 86, 86, 91, 85,
-  75, 71, 89, 86, 91, 83, 83, 111, 81, 83,
-  76, 75, 81, 82, 67, 80, 85, 82, 84, 79,
-  83, 74, 88, 88, 73, 77, 94, 62, 92, 78,
-  90, 88, 80, 84, 85, 100, 71, 89, 93, 89,
-  97, 78, 73, 85, 82, 82, 87, 87, 85, 93,
-  101, 84, 77, 86, 86, 89, 83, 85, 88, 74,
-  88, 76, 88, 85, 78, 75, 74, 87, 83, 85,
-  81, 101, 81, 80, 86, 84, 79, 113, 81, 78,
-  80, 95, 95, 85, 95, 94, 96, 86, 78, 85,
-  93, 82, 97, 87, 76, 96, 89, 80, 86, 94,
-  76, 87, 85, 72, 98, 119, 78, 91, 88, 90,
-  74, 95, 84, 71, 117, 83, 81, 85, 80, 77,
-  77, 84, 95, 80, 87, 77, 94, 68, 75, 82,
-  90, 67, 81, 65, 86, 94, 95, 87, 71, 67,
-  77, 81, 63, 82, 87, 91, 85, 71, 88, 79,
-  106, 80, 79, 88, 82, 85, 86, 77, 83, 90,
-  81, 79, 92, 95, 75, 89, 85, 85, 64, 67,
-  80, 97, 88, 85, 80, 84, 87, 97, 103, 85,
-  89, 79, 91, 100, 72, 97, 90, 77, 85, 73,
-  94, 89, 75, 82, 75, 87, 82, 75, 81, 101,
-  86, 80, 84, 87, 80, 93, 79, 81, 74, 95,
-  89, 85, 89, 81, 83, 82, 83, 83, 97, 84,
-  102, 87, 71, 110, 88, 74, 82, 85, 77, 87,
-  95, 64, 101, 112, 95, 90, 96, 85, 70, 80,
-  77, 66, 122, 69, 85, 88, 78, 90, 72, 72,
-  85, 77, 88, 77, 104, 60, 61, 82, 100, 55,
-  70, 64, 80, 78, 102, 88, 67, 68, 75, 84,
-  59, 82, 87, 89, 79, 79, 78, 92, 96, 70,
-  80, 89, 85, 79, 70, 77, 82, 102, 83, 72,
-  83, 98, 78, 81, 87, 85, 48, 54, 80, 103,
-  83, 77, 85, 73, 85, 96, 92, 68, 90, 75,
-  85, 107, 77, 94, 80, 77, 78, 64, 94, 85,
-  81, 80, 85, 84, 85, 99, 79, 97, 84, 83,
-  90, 81, 82, 75, 81, 80, 77, 93, 93, 87,
-  65, 92, 86, 88, 85, 88, 101, 81, 84, 81,
-  76, 105, 90, 75, 84, 82, 82, 84, 104, 78,
-  91, 110, 92, 92, 86, 86, 77, 80, 87, 76,
-  102, 77, 80, 81, 86, 96, 80, 91, 97, 78,
-  86, 80, 87, 71, 80, 85, 91, 74, 76, 80,
-  83, 99, 94, 90, 74, 69, 77, 87, 66, 76,
-  88, 90, 86, 91, 89, 97, 98, 79, 80, 83,
-  77, 74, 97, 77, 87, 82, 85, 84, 84, 91,
-  74, 84, 85, 87, 71, 77, 85, 93, 84, 91,
-  82, 88, 84, 101, 82, 92, 92, 84, 94, 96,
-  77, 97, 87, 75, 90, 76, 93, 90, 87, 89,
-  97, 76, 90, 74, 90, 83, 91, 77, 90, 83,
-  87, 82, 89, 89, 95, 80, 93, 85, 56, 87,
-  97, 99, 89, 72, 80, 81, 84, 88, 88, 95,
-  94, 92, 86, 87, 86, 79, 80, 86, 86, 86,
-  81, 96, 63, 92, 100, 86, 91, 85, 78, 86,
-  90, 77, 91, 81, 89, 101, 91, 80, 92, 90,
-  96, 91, 85, 71, 84, 92, 87, 98, 83, 88,
-  66, 79, 77, 85, 79, 83, 88, 83, 90, 82,
-  74, 81, 96, 80, 79, 92, 91, 111, 66, 93,
-  91, 77, 90, 83, 71, 88, 74, 74, 76, 82,
-  86, 63, 89, 94, 77, 80, 73, 73, 68, 79,
-  82, 82, 81, 94, 84, 90, 81, 73, 104, 90,
-  84, 82, 94, 79, 88, 70, 80, 90, 84, 79,
-  90, 85, 86, 83, 86, 76, 91, 83, 87, 85,
-  86, 90, 90, 74, 88, 85, 73, 85, 80, 92,
-  86, 68, 79, 81, 83, 91, 88, 93, 90, 91,
-  82, 81, 91, 79, 78, 85, 91, 89, 65, 90,
-  63, 84, 87, 85, 90, 84, 77, 84, 88, 79,
-  84, 86, 86, 94, 89, 85, 99, 89, 93, 90,
-  77, 70, 86, 92, 85, 91, 84, 86, 59, 75,
-  79, 86, 82, 82, 85, 82, 85, 86, 79, 84,
-  97, 78, 82, 92, 86, 108, 67, 92, 86, 77,
-  92, 80, 76, 87, 85, 82, 75, 87, 88, 70,
-  89, 87, 75, 83, 74, 72, 67, 77, 81, 78,
-  79, 89, 82, 89, 79, 72, 93, 83, 88, 82,
-  88, 81, 88, 71, 80, 86, 79, 83, 92, 100,
-  85, 92, 93, 80, 96, 83, 83, 85, 86, 76,
-  93, 88, 93, 79, 82, 88, 77, 92, 82, 74,
-  83, 88, 79, 83, 79, 93, 88, 88, 78, 80,
-  90, 81, 78, 94, 91, 86, 68, 85, 69, 90,
-  89, 73, 88, 94, 81, 78, 77, 80, 92, 81,
-  85, 94, 85, 80, 85, 88, 89, 83, 76, 84,
-  83, 92, 84, 92, 85, 83, 74, 77, 83, 88,
-  81, 88, 82, 86, 85, 88, 80, 91, 92, 79,
-  86, 90, 85, 99, 76, 93, 83, 81, 89, 84,
-  76, 89, 92, 71, 77, 85, 87, 72, 84, 75,
-  77, 84, 83, 81, 77, 82, 84, 83, 79, 84,
-  84, 91, 78, 66, 77, 88, 85, 89, 91, 79,
-  89, 81, 79, 83, 95, 76, 87, 70, 87, 98,
-  88, 68, 83, 81, 85, 77, 97, 72, 88, 67,
-  69, 84, 68, 79, 75, 97, 80, 79, 84, 80,
-  93, 101, 100, 81, 94, 84, 107, 95, 72, 105,
-  90, 64, 68, 88, 140, 83, 76, 124, 71, 94,
-  82, 75, 99, 77, 92, 86, 66, 88, 94, 71,
-  84, 87, 78, 73, 72, 89, 75, 73, 80, 81,
-  80, 64, 73, 74, 80, 115, 76, 79, 86, 100,
-  90, 84, 99, 82, 76, 71, 81, 88, 81, 69,
-  86, 110, 49, 83, 67, 87, 74, 86, 71, 80,
-  55, 80, 81, 81, 73, 69, 92, 114, 84, 68,
-  63, 76, 86, 85, 90, 89, 75, 96, 80, 81,
-  81, 123, 115, 95, 60, 77, 80, 84, 100, 80,
-  79, 89, 70, 73, 85, 75, 84, 85, 82, 68,
-  82, 82, 84, 84, 91, 76, 79, 55, 63, 83,
-  105, 78, 77, 88, 66, 72, 83, 75, 92, 109,
-  100, 76, 85, 92, 101, 78, 74, 99, 83, 65,
-  69, 89, 85, 77, 82, 109, 59, 94, 84, 73,
-  94, 78, 92, 78, 64, 90, 89, 78, 84, 91,
-  91, 72, 76, 84, 69, 70, 82, 77, 78, 67,
-  80, 79, 69, 107, 74, 86, 93, 90, 91, 87,
-  93, 82, 78, 95, 83, 87, 83, 75, 84, 111,
-  49, 82, 73, 86, 79, 82, 76, 81, 67, 85,
-  80, 73, 73, 75, 90, 107, 78, 69, 61, 75,
-  89, 85, 83, 83, 76, 92, 83, 83, 77, 124,
-  90, 92, 65, 75, 75, 86, 98, 79, 85, 86,
-  73, 83, 85, 106, 80, 90, 92, 79, 91, 87,
-  84, 90, 91, 68, 89, 81, 85, 88, 97, 83,
-  84, 91, 77, 78, 83, 83, 90, 102, 79, 93,
-  90, 95, 85, 78, 85, 88, 76, 84, 82, 88,
-  58, 86, 71, 90, 85, 73, 90, 93, 89, 79,
-  85, 87, 86, 90, 85, 92, 81, 84, 82, 79,
-  85, 71, 75, 80, 77, 93, 88, 88, 90, 91,
-  70, 78, 88, 92, 84, 88, 80, 86, 92, 85,
-  81, 104, 95, 80, 92, 93, 88, 94, 71, 85,
-  82, 79, 88, 81, 82, 85, 93, 71, 79, 75,
-  84, 72, 87, 84, 82, 81, 84, 83, 87, 88,
-  85, 84, 76, 89, 91, 91, 80, 66, 68, 84,
-  81, 83, 95, 85, 85, 85, 84, 78, 82, 93,
-  92, 68, 88, 108, 85, 69, 88, 83, 90, 85,
-  95, 73, 86, 91, 94, 80, 92, 77, 80, 94,
-  77, 96, 85, 84, 90, 93, 85, 75, 108, 89,
-  88, 90, 87, 96, 87, 73, 65, 84, 123, 87,
-  91, 121, 65, 99, 71, 86, 79, 86, 93, 98,
-  92, 89, 88, 65, 68, 74, 74, 65, 71, 91,
-  80, 74, 75, 86, 72, 66, 76, 67, 106, 120,
-  82, 77, 79, 93, 79, 74, 112, 88, 91, 65,
-  92, 93, 90, 72, 89, 76, 56, 77, 58, 94,
-  82, 100, 77, 89, 56, 79, 82, 92, 73, 70,
-  66, 98, 92, 82, 57, 74, 98, 84, 90, 91,
-  80, 93, 78, 80, 75, 105, 104, 74, 55, 78,
-  95, 89, 84, 95, 82, 86, 60, 84, 89, 68,
-  88, 100, 74, 69, 88, 83, 87, 85, 90, 74,
-  81, 79, 91, 79, 107, 84, 81, 86, 67, 91,
-  86, 77, 93, 96, 89, 67, 102, 86, 90, 80,
-  83, 97, 86, 72, 65, 83, 92, 78, 95, 106,
-  56, 88, 74, 80, 74, 85, 89, 91, 84, 80,
-  81, 71, 69, 80, 80, 61, 76, 87, 73, 77,
-  77, 80, 72, 74, 72, 70, 94, 120, 80, 80,
-  85, 86, 84, 72, 105, 86, 94, 101, 89, 92,
-  78, 78, 88, 77, 59, 79, 61, 91, 79, 89,
-  82, 90, 66, 81, 84, 78, 74, 74, 66, 93,
-  88, 80, 63, 76, 107, 85, 86, 88, 82, 93,
-  88, 80, 76, 112, 79, 80, 61, 81, 88, 88,
-  86, 93, 82, 90, 68, 91, 85, 107, 78, 85,
-  88, 80, 91, 82, 89, 91, 86, 82, 82, 86,
-  89, 80, 79, 87, 89, 92, 77, 77, 78, 88,
-  82, 91, 75, 87, 96, 96, 85, 77, 90, 89,
-  73, 92, 84, 88, 64, 82, 77, 86, 82, 72,
-  87, 97, 80, 85, 82, 84, 92, 74, 82, 87,
-  78, 83, 81, 76, 82, 78, 81, 84, 82, 90,
-  82, 94, 80, 85, 82, 92, 89, 92, 84, 87,
-  79, 81, 97, 84, 83, 108, 90, 88, 84, 87,
-  88, 86, 73, 85, 80, 82, 88, 82, 86, 91,
-  88, 77, 85, 78, 81, 75, 91, 88, 76, 84,
-  75, 81, 84, 87, 92, 88, 85, 92, 93, 94,
-  82, 68, 68, 76, 78, 87, 99, 87, 76, 90,
-  78, 79, 77, 92, 88, 82, 82, 80, 98, 87,
-  77, 84, 71, 88, 78, 84, 78, 89, 93, 75,
-  93, 88, 73, 83, 89, 90, 86, 85, 79, 79,
-  97, 81, 85, 73, 84, 85, 97, 82, 79, 94,
-  99, 79, 85, 80, 78, 96, 79, 93, 85, 76,
-  72, 107, 114, 87, 106, 70, 90, 79, 93, 80,
-  80, 86, 90, 75, 83, 89, 98, 82, 85, 88,
-  81, 70, 93, 82, 87, 93, 83, 83, 80, 65,
-  95, 88, 95, 85, 72, 100, 75, 79, 79, 82,
-  85, 85, 86, 75, 89, 77, 80, 80, 88, 92,
-  70, 71, 84, 88, 81, 78, 73, 78, 88, 84,
-  89, 77, 81, 87, 83, 90, 84, 85, 80, 90,
-  85, 87, 83, 81, 86, 71, 84, 91, 89, 81,
-  91, 93, 73, 70, 76, 85, 89, 85, 68, 87,
-  89, 95, 82, 77, 79, 93, 82, 72, 86, 86,
-  73, 88, 86, 72, 90, 79, 82, 81, 90, 83,
-  89, 68, 94, 79, 90, 80, 78, 74, 95, 71,
-  84, 66, 73, 90, 80, 72, 81, 84, 75, 103,
-  99, 80, 88, 85, 83, 85, 84, 79, 85, 77,
-  101, 94, 80, 82, 112, 82, 72, 75, 73, 81,
-  93, 94, 84, 83, 82, 61, 79, 57, 81, 94,
-  91, 88, 66, 94, 75, 86, 94, 82, 80, 84,
-  85, 82, 85, 68, 80, 83, 88, 82, 75, 70,
-  82, 89, 77, 74, 88, 74, 95, 84, 95, 88,
-  82, 85, 81, 99, 79, 84, 75, 93, 83, 84,
-  80, 80, 71, 86, 86, 91, 90, 91, 78, 94,
-  73, 87, 72, 88, 91, 86, 67, 91, 88, 90,
-  74, 77, 76, 88, 77, 76, 80, 83, 73, 86,
-  87, 76, 84, 80, 85, 81, 78, 89, 88, 79,
-  101, 73, 84, 84, 88, 72, 95, 70, 92, 69,
-  72, 100, 82, 81, 87, 84, 81, 90, 94, 87,
-  88, 98, 85, 89, 80, 79, 89, 86, 98, 92,
-  87, 79, 103, 84, 78, 73, 99, 84, 94, 97,
-  88, 85, 81, 66, 87, 62, 83, 105, 89, 89,
-  62, 91, 82, 84, 91, 79, 85, 78, 85, 79,
-  91, 68, 80, 83, 86, 83, 80, 80, 86, 87,
-  79, 76, 89, 66, 96, 81, 77, 93, 81, 87,
-  79, 93, 75, 81, 74, 92, 77, 82, 79, 82,
-  81, 86, 79, 82, 90, 69, 85, 74, 79, 83,
-  76, 79, 84, 84, 76, 87, 78, 95, 77, 91,
-  82, 96, 86, 74, 97, 91, 100, 92, 92, 81,
-  104, 81, 86, 78, 80, 77, 101, 67, 73, 78,
-  85, 78, 87, 98, 84, 90, 85, 64, 87, 95,
-  92, 99, 80, 86, 61, 96, 102, 79, 92, 50,
-  82, 44, 92, 96, 80, 89, 80, 46, 69, 85,
-  100, 66, 93, 85, 76, 86, 90, 84, 87, 86,
-  89, 99, 76, 80, 73, 70, 113, 109, 56, 82,
-  84, 77, 77, 89, 84, 73, 95, 83, 82, 73,
-  83, 72, 90, 90, 66, 67, 80, 98, 86, 83,
-  79, 76, 81, 97, 93, 79, 85, 94, 51, 99,
-  95, 82, 77, 85, 89, 85, 74, 67, 72, 88,
-  84, 120, 90, 70, 75, 70, 100, 77, 72, 85,
-  46, 94, 104, 80, 98, 81, 84, 80, 91, 85,
-  86, 121, 85, 77, 97, 90, 94, 87, 77, 79,
-  96, 81, 77, 74, 76, 96, 78, 64, 79, 74,
-  72, 62, 81, 82, 79, 61, 97, 79, 82, 63,
-  95, 43, 77, 71, 68, 75, 63, 81, 95, 78,
-  74, 118, 80, 82, 90, 91, 68, 83, 105, 77,
-  77, 73, 66, 99, 80, 84, 96, 91, 67, 82,
-  76, 73, 57, 79, 80, 101, 99, 77, 80, 94,
-  60, 78, 71, 83, 86, 106, 100, 94, 91, 68,
-  78, 92, 65, 65, 94, 99, 95, 76, 102, 117,
-  92, 78, 73, 79, 92, 76, 95, 86, 88, 83,
-  74, 76, 73, 104, 52, 76, 72, 93, 102, 76,
-  85, 109, 76, 68, 105, 89, 74, 84, 52, 92,
-  107, 81, 85, 76, 86, 80, 80, 79, 82, 139,
-  75, 81, 84, 80, 87, 83, 67, 76, 97, 75,
-  71, 77, 73, 87, 79, 72, 70, 74, 79, 60,
-  81, 79, 91, 78, 90, 84, 80, 78, 89, 47,
-  96, 70, 67, 81, 71, 99, 96, 113, 72, 97,
-  82, 81, 86, 101, 95, 80, 90, 72, 76, 69,
-  91, 93, 85, 86, 104, 94, 66, 61, 91, 75,
-  63, 105, 75, 92, 102, 80, 79, 83, 85, 78,
-  72, 87, 85, 87, 87, 85, 90, 80, 83, 89,
-  71, 103, 89, 94, 92, 78, 95, 105, 91, 73,
-  61, 86, 84, 84, 105, 71, 75, 76, 80, 76,
-  71, 91, 51, 73, 88, 88, 92, 68, 87, 73,
-  74, 78, 92, 83, 74, 88, 87, 81, 80, 79,
-  83, 74, 69, 99, 84, 85, 80, 70, 92, 94,
-  81, 84, 80, 88, 103, 77, 79, 74, 73, 80,
-  93, 79, 97, 79, 98, 72, 91, 101, 83, 91,
-  91, 67, 87, 81, 92, 102, 78, 73, 69, 96,
-  97, 91, 91, 88, 86, 49, 95, 92, 68, 89,
-  77, 52, 80, 87, 86, 75, 94, 83, 90, 85,
-  94, 91, 89, 85, 87, 108, 81, 89, 73, 72,
-  105, 96, 53, 79, 89, 77, 79, 87, 82, 85,
-  95, 84, 83, 76, 86, 74, 97, 86, 75, 83,
-  78, 93, 82, 80, 74, 73, 81, 81, 85, 77,
-  84, 98, 55, 85, 84, 82, 84, 87, 79, 84,
-  80, 71, 81, 85, 86, 100, 84, 68, 71, 73,
-  96, 71, 73, 91, 61, 84, 98, 75, 103, 70,
-  86, 95, 97, 78, 83, 97, 76, 84, 88, 79,
-  77, 96, 85, 80, 84, 71, 56, 78, 82, 108,
-  90, 67, 86, 83, 82, 76, 86, 87, 89, 69,
-  87, 76, 81, 72, 80, 52, 79, 73, 68, 89,
-  68, 93, 99, 83, 85, 108, 79, 76, 82, 89,
-  84, 87, 82, 78, 96, 86, 87, 86, 90, 79,
-  84, 86, 73, 76, 91, 87, 63, 85, 80, 93,
-  88, 89, 83, 90, 78, 88, 76, 90, 85, 98,
-  111, 98, 86, 77, 89, 87, 83, 76, 91, 92,
-  79, 77, 95, 92, 81, 80, 76, 75, 84, 79,
-  95, 72, 74, 80, 85, 86, 71, 100, 58, 83,
-  89, 78, 97, 69, 83, 94, 104, 68, 99, 88,
-  74, 84, 59, 85, 98, 72, 95, 87, 91, 83,
-  85, 78, 76, 107, 84, 92, 95, 81, 81, 89,
-  75, 78, 80, 86, 65, 82, 78, 91, 81, 88,
-  72, 86, 85, 75, 83, 86, 81, 79, 85, 77,
-  84, 76, 77, 56, 90, 85, 71, 91, 70, 90,
-  94, 103, 80, 84, 81, 72, 78, 99, 96, 88,
-  88, 73, 88, 90, 82, 88, 87, 84, 90, 93,
-  80, 72, 81, 91, 69, 96, 73, 97, 88, 98,
-  81, 87, 91, 82, 80, 87, 84, 83, 92, 86,
-  85, 87, 82, 82, 85, 83, 91, 89, 79, 83,
-  93, 81, 83, 78, 81, 76, 79, 83, 94, 75,
-  90, 76, 91, 85, 76, 87, 61, 75, 101, 75,
-  89, 70, 92, 84, 76, 78, 74, 82, 110, 88,
-  76, 69, 81, 65, 79, 95, 71, 91, 89, 105,
-  58, 84, 92, 97, 81, 91, 87, 71, 83, 77,
-  90, 76, 98, 83, 79, 82, 73, 86, 80, 71,
-  87, 85, 75, 87, 113, 70, 92, 79, 81, 88,
-  74, 88, 105, 79, 77, 75, 79, 89, 84, 95,
-  79, 106, 90, 84, 81, 70, 80, 79, 84, 92,
-  70, 72, 83, 77, 91, 76, 90, 87, 82, 84,
-  65, 65, 82, 88, 79, 96, 98, 81, 81, 85,
-  92, 97, 80, 77, 78, 84, 74, 74, 84, 90,
-  92, 73, 75, 86, 105, 81, 91, 88, 81, 87,
-  84, 97, 89, 87, 77, 83, 102, 76, 104, 104,
-  81, 74, 86, 80, 70, 90, 75, 80, 89, 70,
-  88, 85, 69, 77, 73, 73, 104, 82, 76, 70,
-  79, 68, 79, 87, 72, 91, 92, 107, 62, 90,
-  97, 87, 80, 88, 89, 70, 79, 76, 96, 76,
-  96, 78, 81, 73, 83, 86, 85, 68, 88, 77,
-  81, 90, 101, 77, 94, 76, 74, 83, 68, 96,
-  94, 69, 88, 77, 77, 86, 78, 85, 87, 113,
-  98, 75, 75, 69, 68, 73, 91, 100, 66, 64,
-  76, 80, 86, 70, 85, 81, 83, 81, 67, 59,
-  83, 84, 79, 89, 99, 72, 84, 84, 92, 109,
-  79, 80, 78, 75, 74, 79, 79, 97, 91, 68,
-  77, 85, 102, 82, 78, 88, 86, 91, 80, 100,
-  86, 84, 78, 84, 99, 77, 82, 109, 86, 71,
-  80, 86, 67, 92, 72, 80, 91, 76, 89, 84,
-  83, 81, 75, 85, 103, 88, 83, 72, 87, 69,
-  75, 85, 77, 92, 88, 99, 63, 91, 97, 95,
-  82, 92, 90, 75, 83, 79, 84, 72, 87, 85,
-  75, 69, 90, 110, 86, 74, 85, 82, 77, 86,
-  91, 76, 95, 89, 81, 88, 77, 88, 100, 81,
-  77, 81, 85, 90, 85, 99, 83, 96, 88, 83,
-  80, 75, 92, 76, 97, 91, 71, 67, 101, 86,
-  98, 73, 84, 90, 87, 81, 66, 69, 85, 90,
-  83, 94, 93, 76, 77, 85, 92, 97, 83, 82,
-  74, 86, 86, 81, 86, 93, 83, 82, 84, 85,
-  100, 79, 88, 93, 77, 88, 89, 98, 88, 88,
-  80, 83, 100, 78, 88, 96, 82, 78, 82, 81,
-  75, 90, 80, 87, 88, 76, 90, 77, 70, 84,
-  76, 87, 111, 90, 75, 74, 79, 71, 81, 82,
-  67, 98, 85, 100, 65, 90, 98, 94, 81, 92,
-  87, 60, 86, 79, 88, 74, 101, 92, 85, 86,
-  68, 81, 84, 87, 90, 78, 82, 87, 105, 73,
-  91, 85, 72, 91, 78, 81, 115, 66, 75, 83,
-  74, 95, 78, 95, 76, 96, 88, 85, 80, 70,
-  65, 73, 84, 75, 76, 55, 94, 80, 81, 75,
-  87, 82, 88, 92, 66, 68, 74, 102, 78, 71,
-  90, 74, 79, 80, 87, 85, 80, 71, 83, 84,
-  75, 84, 92, 88, 83, 68, 69, 91, 101, 84,
-  118, 92, 82, 86, 90, 92, 91, 85, 69, 90,
-  91, 80, 93, 95, 71, 70, 80, 70, 72, 79,
-  77, 85, 80, 67, 89, 82, 73, 85, 75, 77,
-  104, 78, 73, 75, 75, 73, 82, 91, 65, 97,
-  90, 105, 69, 92, 103, 89, 82, 89, 82, 54,
-  85, 80, 91, 71, 94, 95, 90, 79, 69, 74,
-  84, 82, 87, 72, 86, 89, 107, 79, 94, 89,
-  64, 83, 74, 82, 105, 73, 79, 82, 74, 88,
-  75, 84, 77, 94, 92, 80, 81, 72, 59, 75,
-  85, 68, 72, 62, 80, 83, 70, 76, 82, 74,
-  94, 79, 63, 61, 71, 104, 78, 70, 87, 70,
-  79, 78, 86, 89, 78, 80, 80, 76, 70, 87,
-  87, 91, 78, 63, 73, 86, 103, 87, 120, 88,
-  81, 87, 93, 91, 94, 84, 65, 83, 92, 78,
-  81, 96, 66, 68, 79, 71, 59, 80, 76, 88,
-  82, 71, 86, 89, 86, 79, 74, 89, 102, 84,
-  73, 73, 82, 77, 78, 89, 69, 94, 90, 97,
-  67, 97, 92, 96, 82, 88, 84, 65, 86, 77,
-  85, 72, 90, 99, 83, 78, 83, 96, 87, 88,
-  84, 77, 81, 84, 96, 76, 91, 92, 66, 90,
-  78, 81, 106, 80, 74, 87, 78, 84, 82, 97,
-  81, 90, 87, 84, 83, 74, 77, 74, 90, 73,
-  80, 67, 85, 85, 88, 70, 85, 84, 88, 80,
-  61, 69, 77, 100, 80, 83, 88, 80, 82, 80,
-  85, 87, 81, 77, 80, 87, 76, 83, 94, 92,
-  81, 71, 75, 80, 97, 81, 109, 95, 77, 85,
-  90, 95, 92, 86, 73, 81, 97, 83, 93, 89,
-  75, 76, 80, 77, 76, 81, 78, 91, 80, 69,
-  92, 77, 79, 87, 77, 88, 93, 103, 75, 74,
-  84, 75, 79, 88, 75, 102, 86, 87, 76, 93,
-  92, 99, 82, 85, 92, 75, 96, 78, 81, 83,
-  93, 88, 88, 94, 83, 83, 90, 95, 87, 91,
-  89, 89, 84, 76, 78, 92, 84, 91, 79, 85,
-  104, 73, 75, 91, 83, 93, 82, 97, 81, 89,
-  84, 82, 80, 79, 86, 71, 99, 76, 91, 85,
-  96, 77, 94, 72, 91, 82, 79, 86, 75, 72,
-  77, 90, 89, 83, 90, 76, 86, 89, 87, 81,
-  78, 82, 85, 97, 81, 70, 102, 82, 95, 75,
-  84, 89, 91, 83, 96, 92, 83, 87, 79, 92,
-  89, 88, 88, 94, 93, 81, 90, 93, 85, 74,
-  83, 71, 94, 84, 89, 100, 75, 74, 91, 77,
-  77, 89, 76, 81, 89, 93, 75, 74, 85, 76,
-  79, 98, 74, 98, 87, 85, 81, 90, 86, 93,
-  82, 81, 92, 72, 97, 75, 85, 82, 88, 102,
-  93, 88, 84, 79, 83, 91, 89, 84, 82, 89,
-  87, 77, 79, 89, 81, 81, 81, 83, 98, 78,
-  73, 93, 82, 95, 83, 89, 83, 83, 81, 84,
-  78, 75, 81, 70, 103, 68, 92, 84, 88, 75,
-  84, 70, 94, 79, 86, 78, 72, 69, 76, 91,
-  93, 83, 91, 73, 81, 86, 87, 82, 75, 84,
-  85, 91, 79, 76, 108, 80, 87, 70, 80, 88,
-  92, 84, 98, 104, 83, 88, 85, 98, 89, 83,
-  86, 88, 94, 88, 90, 88, 77, 74, 81, 76,
-  87, 81, 90, 105, 72, 74, 83, 82, 88, 83,
-  76, 90, 88, 94, 78, 76, 87, 80, 78, 86,
-  74, 98, 89, 83, 77, 98, 78, 99, 86, 83,
-  91, 77, 98, 75, 78, 85, 86, 98, 88, 85,
-  89, 90, 85, 92, 85, 87, 85, 85, 88, 80,
-  78, 90, 86, 90, 80, 84, 99, 77, 72, 94,
-  79, 88, 85, 99, 87, 86, 83, 84, 82, 79,
-  88, 75, 108, 75, 90, 85, 86, 81, 91, 68,
-  96, 83, 81, 85, 70, 73, 79, 86, 93, 89,
-  88, 82, 79, 86, 84, 84, 79, 86, 82, 98,
-  79, 72, 105, 80, 82, 77, 89, 73, 91, 80,
-  97, 94, 86, 91, 88, 95, 79, 86, 88, 89,
-  96, 89, 99, 88, 84, 77, 82, 75, 90, 85,
-  92, 104, 78, 81, 92, 100, 91, 85, 70, 73,
-  90, 78, 86, 92, 102, 106, 88, 74, 93, 68,
-  80, 87, 85, 98, 92, 82, 87, 82, 89, 86,
-  82, 88, 81, 94, 104, 80, 92, 86, 89, 70,
-  90, 80, 98, 81, 94, 85, 94, 91, 85, 73,
-  80, 74, 74, 88, 86, 92, 93, 80, 85, 91,
-  66, 84, 76, 90, 89, 69, 93, 72, 78, 86,
-  83, 93, 76, 95, 68, 92, 84, 89, 84, 78,
-  89, 74, 81, 82, 85, 87, 76, 71, 94, 84,
-  84, 93, 93, 97, 70, 80, 92, 76, 65, 98,
-  99, 92, 67, 75, 91, 87, 84, 83, 85, 93,
-  79, 105, 72, 98, 81, 84, 97, 79, 92, 94,
-  77, 87, 78, 91, 101, 85, 65, 89, 80, 87,
-  91, 94, 86, 107, 95, 87, 81, 75, 79, 75,
-  88, 85, 86, 82, 74, 74, 71, 80, 87, 79,
-  80, 100, 70, 85, 77, 89, 95, 95, 76, 82,
-  91, 85, 84, 83, 84, 73, 87, 85, 74, 81,
-  111, 78, 85, 87, 92, 85, 86, 103, 97, 89,
-  90, 84, 80, 81, 89, 82, 85, 87, 68, 72,
-  80, 89, 77, 115, 82, 70, 73, 70, 78, 76,
-  85, 80, 99, 94, 75, 81, 85, 71, 91, 82,
-  83, 89, 80, 79, 88, 81, 86, 89, 84, 77,
-  90, 79, 65, 83, 84, 88, 63, 88, 93, 81,
-  58, 80, 77, 97, 90, 83, 91, 81, 68, 83,
-  83, 77, 80, 88, 79, 83, 75, 79, 86, 79,
-  72, 78, 86, 72, 85, 79, 82, 87, 87, 81,
-  91, 85, 107, 87, 83, 102, 72, 77, 81, 85,
-  73, 65, 85, 85, 50, 96, 94, 75, 78, 91,
-  89, 100, 85, 96, 81, 78, 72, 82, 84, 99,
-  83, 87, 77, 82, 85, 86, 78, 89, 90, 80,
-  81, 81, 67, 84, 84, 108, 102, 92, 95, 86,
-  80, 79, 84, 73, 85, 86, 99, 75, 81, 92,
-  70, 128, 85, 81, 74, 68, 62, 69, 113, 77,
-  69, 84, 82, 79, 78, 91, 84, 77, 74, 82,
-  82, 77, 83, 95, 76, 88, 82, 67, 78, 74,
-  87, 93, 99, 81, 87, 80, 84, 73, 76, 77,
-  80, 73, 80, 89, 89, 78, 70, 70, 78, 86,
-  83, 92, 68, 80, 73, 84, 90, 85, 78, 79,
-  88, 84, 88, 79, 96, 88, 79, 78, 88, 98,
-  88, 89, 69, 77, 95, 76, 75, 88, 103, 119,
-  110, 76, 95, 78, 93, 95, 92, 100, 85, 79,
-  75, 78, 85, 90, 74, 90, 87, 85, 114, 73,
-  104, 90, 99, 72, 77, 83, 98, 88, 81, 84,
-  101, 100, 81, 79, 81, 67, 62, 97, 84, 89,
-  89, 96, 85, 83, 63, 91, 73, 94, 81, 69,
-  85, 71, 72, 89, 88, 97, 82, 80, 77, 79,
-  77, 88, 82, 64, 68, 92, 74, 77, 93, 88,
-  82, 75, 101, 80, 87, 97, 93, 86, 72, 73,
-  72, 73, 66, 93, 93, 95, 80, 76, 79, 88,
-  83, 82, 85, 84, 80, 109, 74, 103, 91, 100,
-  95, 77, 87, 85, 72, 88, 92, 71, 91, 101,
-  66, 87, 83, 86, 97, 92, 82, 101, 101, 94,
-  84, 70, 78, 71, 96, 83, 87, 85, 91, 92,
-  69, 93, 82, 75, 78, 99, 59, 85, 75, 90,
-  87, 89, 70, 90, 97, 75, 75, 77, 81, 75,
-  90, 84, 71, 78, 90, 88, 75, 80, 104, 78,
-  80, 104, 93, 72, 87, 99, 78, 74, 87, 87,
-  74, 79, 73, 70, 85, 90, 78, 123, 78, 61,
-  68, 66, 83, 72, 98, 72, 90, 90, 70, 87,
-  82, 68, 86, 111, 75, 86, 85, 76, 98, 90,
-  81, 91, 83, 79, 82, 74, 57, 82, 81, 81,
-  55, 81, 89, 79, 68, 86, 69, 75, 85, 82,
-  81, 76, 76, 77, 85, 80, 79, 91, 66, 91,
-  68, 84, 110, 77, 73, 76, 85, 78, 90, 79,
-  84, 86, 71, 88, 87, 78, 77, 81, 73, 90,
-  66, 74, 86, 85, 69, 72, 85, 94, 57, 87,
-  75, 66, 79, 86, 101, 106, 74, 97, 74, 73,
-  77, 77, 93, 82, 75, 84, 68, 87, 69, 82,
-  81, 89, 82, 78, 88, 73, 56, 76, 89, 106,
-  79, 76, 96, 90, 79, 72, 86, 74, 82, 87,
-  106, 71, 100, 85, 79, 138, 99, 76, 57, 76,
-  64, 76, 107, 87, 73, 77, 92, 92, 78, 96,
-  84, 93, 82, 73, 78, 68, 82, 91, 71, 85,
-  88, 68, 72, 76, 79, 104, 99, 75, 93, 69,
-  86, 75, 95, 87, 82, 70, 88, 92, 84, 98,
-  79, 65, 78, 79, 79, 91, 66, 86, 75, 92,
-  98, 82, 69, 83, 83, 78, 84, 77, 93, 90,
-  69, 81, 81, 100, 87, 104, 67, 76, 90, 65,
-  79, 90, 97, 106, 112, 87, 81, 95, 94, 91,
-  92, 91, 83, 75, 79, 80, 69, 88, 79, 88,
-  84, 86, 94, 80, 88, 85, 90, 78, 90, 82,
-  90, 94, 89, 82, 82, 96, 77, 73, 82, 66,
-  71, 89, 78, 79, 93, 92, 81, 72, 69, 88,
-  83, 95, 83, 83, 79, 73, 81, 84, 92, 92,
-  97, 76, 82, 82, 87, 79, 82, 71, 76, 81,
-  75, 84, 86, 91, 80, 74, 86, 76, 90, 88,
-  95, 91, 66, 94, 86, 80, 70, 81, 90, 87,
-  95, 79, 83, 95, 81, 81, 88, 85, 81, 100,
-  71, 99, 81, 94, 87, 86, 96, 84, 68, 90,
-  96, 65, 89, 85, 68, 88, 89, 79, 101, 84,
-  84, 105, 94, 92, 78, 67, 81, 74, 83, 87,
-  80, 76, 92, 113, 62, 88, 76, 73, 77, 86,
-  73, 94, 99, 94, 70, 81, 79, 88, 96, 86,
-  73, 77, 68, 76, 68, 84, 89, 77, 75, 87,
-  93, 85, 87, 76, 76, 92, 79, 87, 104, 97,
-  77, 77, 89, 79, 72, 76, 82, 72, 91, 79,
-  86, 128, 87, 64, 68, 66, 85, 74, 105, 81,
-  79, 95, 87, 93, 82, 79, 89, 87, 70, 88,
-  81, 72, 92, 92, 75, 88, 82, 80, 83, 75,
-  61, 84, 96, 74, 66, 76, 86, 73, 74, 82,
-  77, 77, 87, 83, 77, 83, 71, 76, 86, 78,
-  74, 88, 68, 96, 83, 86, 127, 84, 75, 79,
-  84, 69, 88, 81, 87, 80, 72, 84, 94, 76,
-  60, 77, 70, 96, 75, 84, 79, 84, 68, 79,
-  84, 83, 61, 80, 70, 77, 83, 81, 119, 94,
-  67, 91, 72, 81, 81, 80, 84, 72, 81, 90,
-  64, 98, 48, 83, 83, 83, 75, 76, 81, 76,
-  59, 81, 91, 96, 67, 85, 97, 89, 87, 74,
-  87, 82, 90, 94, 98, 77, 89, 86, 83, 109,
-  108, 76, 65, 81, 68, 83, 95, 76, 100, 83,
-  95, 97, 79, 103, 79, 77, 91, 85, 80, 71,
-  80, 83, 72, 77, 88, 74, 79, 77, 87, 103,
-  100, 79, 100, 68, 87, 77, 86, 79, 82, 87,
-  91, 91, 89, 80, 86, 70, 95, 83, 78, 86,
-  71, 84, 69, 77, 81, 80, 66, 86, 86, 79,
-  91, 85, 96, 89, 76, 78, 86, 89, 68, 89,
-  89, 106, 93, 92, 84, 82, 80, 90, 87, 86,
-  79, 82, 83, 98, 82, 79, 86, 85, 82, 74,
-  72, 90, 82, 88, 85, 92, 84, 75, 99, 80,
-  112, 104, 77, 91, 94, 81, 75, 79, 79, 78,
-  78, 83, 88, 88, 91, 90, 67, 91, 79, 82,
-  80, 89, 75, 86, 80, 92, 78, 83, 78, 79,
-  76, 80, 87, 86, 87, 79, 101, 103, 104, 77,
-  87, 92, 79, 103, 86, 66, 76, 85, 92, 77,
-  85, 85, 86, 88, 81, 69, 83, 89, 87, 103,
-  81, 84, 89, 86, 80, 89, 63, 76, 80, 88,
-  81, 77, 80, 84, 70, 86, 84, 75, 89, 89,
-  79, 91, 94, 86, 89, 82, 87, 80, 84, 93,
-  74, 81, 88, 83, 81, 95, 66, 91, 70, 95,
-  90, 100, 97, 86, 74, 84, 73, 74, 85, 82,
-  88, 106, 81, 74, 90, 79, 95, 84, 79, 82,
-  93, 94, 75, 103, 79, 94, 91, 59, 106, 89,
-  73, 105, 71, 63, 77, 74, 85, 74, 74, 108,
-  84, 95, 87, 88, 64, 80, 86, 62, 96, 65,
-  90, 68, 80, 102, 82, 84, 78, 76, 81, 72,
-  93, 91, 77, 78, 77, 96, 118, 85, 90, 93,
-  87, 95, 79, 58, 65, 70, 93, 104, 55, 75,
-  85, 55, 64, 87, 88, 77, 89, 119, 87, 77,
-  89, 90, 79, 92, 62, 95, 82, 86, 94, 89,
-  87, 82, 78, 94, 86, 81, 89, 90, 66, 89,
-  94, 93, 97, 88, 96, 82, 94, 94, 61, 80,
-  93, 86, 85, 87, 90, 89, 87, 89, 92, 90,
-  83, 79, 79, 93, 81, 102, 82, 83, 81, 93,
-  83, 77, 77, 89, 98, 76, 81, 88, 83, 86,
-  79, 102, 88, 83, 98, 87, 99, 96, 83, 87,
-  85, 75, 76, 81, 85, 80, 74, 83, 84, 102,
-  91, 88, 64, 98, 78, 79, 85, 82, 72, 87,
-  82, 87, 79, 83, 76, 81, 84, 79, 90, 85,
-  87, 70, 76, 103, 103, 84, 85, 87, 76, 90,
-  86, 73, 77, 92, 95, 92, 88, 87, 86, 91,
-  85, 73, 87, 81, 86, 94, 84, 83, 89, 86,
-  80, 93, 62, 92, 82, 88, 80, 80, 79, 86,
-  73, 83, 102, 78, 85, 87, 91, 81, 91, 87,
-  86, 82, 74, 76, 80, 87, 75, 79, 84, 82,
-  88, 85, 58, 87, 92, 88, 61, 88, 103, 78,
-  81, 108, 86, 88, 74, 73, 81, 75, 80, 77,
-  75, 72, 68, 72, 77, 76, 81, 82, 94, 86,
-  72, 81, 90, 100, 93, 82, 79, 93, 117, 74,
-  78, 71, 90, 97, 80, 77, 84, 91, 78, 80,
-  89, 93, 78, 94, 67, 132, 82, 100, 90, 70,
-  76, 72, 92, 67, 70, 72, 88, 74, 78, 73,
-  97, 92, 90, 74, 79, 81, 77, 69, 83, 73,
-  71, 121, 84, 92, 88, 85, 85, 104, 88, 78,
-  68, 93, 81, 77, 88, 73, 89, 88, 73, 83,
-  73, 71, 80, 87, 65, 73, 77, 90, 72, 89,
-  82, 75, 77, 81, 106, 77, 70, 80, 71, 77,
-  75, 66, 70, 86, 86, 83, 86, 79, 85, 81,
-  86, 76, 103, 75, 57, 85, 108, 73, 85, 105,
-  82, 124, 74, 70, 90, 59, 83, 83, 76, 85,
-  75, 70, 71, 67, 75, 78, 103, 80, 82, 73,
-  69, 86, 85, 79, 70, 91, 112, 68, 82, 75,
-  80, 105, 86, 59, 82, 76, 72, 70, 94, 116,
-  72, 86, 65, 115, 78, 102, 89, 72, 68, 67,
-  92, 71, 62, 78, 85, 71, 78, 66, 91, 85,
-  79, 72, 85, 66, 73, 76, 80, 69, 68, 122,
-  84, 85, 100, 82, 72, 121, 106, 71, 67, 84,
-  84, 63, 79, 67, 84, 89, 76, 88, 66, 67,
-  83, 84, 63, 80, 69, 103, 74, 90, 103, 75,
-  70, 76, 124, 67, 74, 75, 71, 71, 83, 67,
-  62, 87, 89, 80, 81, 78, 82, 84, 103, 89,
-  88, 76, 65, 93, 100, 78, 78, 111, 74, 116,
-  78, 75, 82, 72, 81, 83, 88, 76, 88, 79,
-  72, 78, 87, 83, 87, 83, 87, 80, 90, 79,
-  94, 87, 88, 92, 79, 71, 88, 75, 76, 90,
-  79, 86, 77, 79, 78, 84, 75, 91, 83, 87,
-  79, 76, 83, 93, 86, 70, 78, 75, 84, 71,
-  74, 71, 93, 73, 79, 76, 72, 91, 101, 84,
-  86, 81, 79, 92, 75, 78, 71, 114, 90, 74,
-  81, 87, 78, 98, 85, 77, 77, 80, 86, 83,
-  82, 73, 91, 89, 86, 88, 70, 69, 85, 87,
-  71, 74, 76, 89, 74, 93, 100, 83, 74, 87,
-  107, 77, 84, 79, 76, 84, 91, 69, 79, 86,
-  78, 86, 84, 81, 86, 87, 81, 89, 79, 89,
-  76, 81, 95, 82, 84, 101, 78, 115, 78, 80,
-  83, 82, 86, 77, 80, 79, 70, 79, 81, 69,
-  82, 89, 91, 77, 86, 87, 89, 100, 74, 77,
-  71, 94, 86, 79, 81, 77, 103, 93, 84, 99,
-  84, 92, 79, 87, 97, 99, 88, 83, 70, 59,
-  88, 92, 87, 72, 87, 87, 88, 73, 85, 72,
-  92, 82, 85, 80, 71, 83, 86, 78, 89, 83,
-  78, 66, 74, 84, 69, 99, 87, 90, 83, 97,
-  90, 101, 81, 111, 72, 105, 83, 70, 90, 72,
-  88, 87, 77, 86, 76, 75, 83, 88, 89, 73,
-  83, 84, 62, 95, 98, 85, 79, 92, 112, 79,
-  70, 88, 73, 88, 79, 68, 74, 78, 83, 93,
-  86, 75, 87, 84, 86, 80, 98, 78, 78, 79,
-  95, 81, 88, 93, 94, 115, 78, 68, 86, 65,
-  78, 86, 89, 82, 76, 78, 71, 67, 78, 80,
-  96, 67, 86, 78, 79, 112, 71, 88, 64, 85,
-  120, 90, 87, 75, 90, 105, 101, 71, 83, 76,
-  77, 78, 104, 107, 80, 82, 58, 99, 86, 100,
-  84, 65, 74, 79, 83, 80, 77, 77, 88, 79,
-  98, 70, 93, 75, 80, 74, 91, 76, 74, 79,
-  74, 89, 69, 96, 79, 74, 99, 109, 86, 121,
-  83, 92, 69, 98, 76, 58, 76, 71, 82, 92,
-  75, 87, 73, 66, 85, 85, 79, 74, 78, 91,
-  61, 91, 97, 76, 76, 84, 88, 70, 78, 82,
-  63, 85, 86, 61, 60, 83, 95, 86, 77, 72,
-  84, 88, 80, 93, 76, 76, 77, 85, 95, 87,
-  83, 101, 84, 81, 86, 83, 83, 85, 87, 91,
-  100, 69, 97, 78, 79, 75, 85, 92, 81, 71,
-  87, 90, 93, 83, 78, 86, 80, 94, 104, 77,
-  88, 74, 84, 89, 85, 97, 78, 73, 83, 92,
-  85, 78, 90, 84, 77, 117, 92, 92, 82, 78,
-  84, 90, 95, 75, 80, 72, 93, 91, 82, 89,
-  87, 90, 96, 79, 96, 82, 81, 90, 81, 82,
-  69, 94, 86, 78, 80, 97, 90, 85, 68, 103,
-  80, 92, 82, 79, 75, 73, 90, 89, 91, 85,
-  75, 80, 87, 89, 92, 73, 86, 84, 64, 93,
-  78, 91, 81, 88, 75, 83, 86, 85, 83, 84,
-  101, 71, 84, 81, 79, 94, 92, 82, 89, 60,
-  91, 101, 83, 98, 78, 99, 82, 84, 82, 76,
-  89, 88, 76, 100, 83, 86, 80, 82, 89, 88,
-  79, 81, 86, 81, 80, 79, 93, 74, 76, 84,
-  77, 89, 94, 86, 89, 89, 81, 76, 93, 79,
-  90, 85, 91, 88, 76, 79, 75, 86, 93, 94,
-  93, 87, 81, 87, 89, 95, 83, 80, 87, 84,
-  96, 96, 95, 75, 83, 86, 89, 73, 60, 75,
-  113, 84, 83, 72, 82, 92, 94, 68, 90, 84,
-  82, 71, 88, 76, 94, 77, 96, 75, 84, 103,
-  85, 70, 108, 78, 81, 83, 82, 70, 86, 52,
-  79, 88, 81, 80, 84, 86, 78, 91, 88, 83,
-  78, 90, 98, 74, 106, 77, 80, 77, 86, 91,
-  92, 82, 96, 84, 82, 81, 94, 108, 46, 82,
-  77, 71, 79, 91, 65, 93, 85, 84, 84, 100,
-  75, 77, 72, 86, 87, 79, 81, 67, 60, 107,
-  85, 81, 95, 90, 93, 56, 74, 81, 100, 86,
-  65, 50, 65, 73, 78, 53, 76, 88, 86, 68,
-  85, 82, 85, 97, 81, 90, 89, 57, 91, 77,
-  102, 78, 84, 85, 92, 73, 116, 80, 104, 98,
-  53, 84, 145, 82, 95, 122, 42, 66, 102, 105,
-  81, 75, 84, 81, 89, 60, 82, 82, 90, 69,
-  71, 86, 78, 106, 75, 77, 89, 123, 98, 70,
-  91, 67, 88, 78, 78, 83, 77, 153, 88, 86,
-  93, 102, 97, 82, 99, 101, 73, 87, 78, 70,
-  83, 99, 59, 82, 99, 79, 87, 99, 95, 79,
-  88, 86, 85, 119, 86, 109, 69, 88, 79, 108,
-  85, 102, 83, 91, 80, 86, 79, 67, 86, 89,
-  77, 91, 90, 88, 80, 79, 73, 92, 87, 95,
-  92, 83, 80, 67, 74, 84, 91, 102, 77, 83,
-  64, 77, 82, 86, 86, 94, 99, 87, 90, 93,
-  87, 108, 88, 96, 94, 78, 85, 90, 101, 85,
-  100, 84, 90, 80, 102, 79, 74, 63, 59, 87,
-  77, 83, 94, 66, 90, 83, 100, 83, 97, 77,
-  90, 83, 71, 88, 83, 87, 91, 82, 81, 75,
-  88, 84, 87, 75, 77, 81, 91, 82, 88, 76,
-  80, 80, 82, 84, 63, 123, 88, 88, 89, 78,
-  89, 89, 91, 94, 83, 73, 85, 90, 59, 67,
-  43, 77, 96, 79, 76, 100, 88, 89, 98, 73,
-  91, 108, 87, 78, 104, 92, 78, 74, 83, 77,
-  77, 87, 81, 79, 83, 123, 79, 87, 78, 67,
-  74, 82, 81, 81, 70, 77, 79, 75, 97, 87,
-  91, 74, 85, 80, 75, 75, 81, 79, 85, 82,
-  77, 76, 89, 92, 84, 85, 80, 74, 80, 79,
-  84, 69, 87, 92, 90, 85, 77, 72, 79, 91,
-  84, 71, 90, 92, 100, 90, 85, 78, 66, 63,
-  105, 91, 45, 80, 90, 81, 80, 75, 66, 73,
-  102, 64, 87, 92, 79, 71, 83, 87, 84, 83,
-  97, 89, 91, 103, 83, 67, 95, 84, 86, 86,
-  81, 75, 92, 80, 84, 91, 91, 81, 83, 85,
-  79, 73, 87, 80, 76, 79, 102, 70, 81, 86,
-  79, 86, 75, 79, 81, 73, 90, 95, 82, 82,
-  113, 101, 85, 79, 85, 113, 82, 69, 59, 93,
-  86, 86, 99, 129, 67, 67, 81, 72, 85, 84,
-  81, 90, 80, 97, 84, 72, 91, 91, 87, 61,
-  79, 89, 86, 95, 74, 97, 66, 75, 84, 51,
-  74, 100, 81, 78, 89, 87, 75, 135, 84, 55,
-  72, 63, 82, 79, 74, 59, 67, 65, 85, 68,
-  109, 99, 87, 72, 70, 87, 109, 67, 117, 92,
-  59, 83, 82, 86, 83, 69, 67, 93, 68, 83,
-  82, 77, 89, 88, 80, 91, 87, 123, 52, 79,
-  78, 87, 91, 74, 88, 90, 81, 84, 83, 80,
-  70, 137, 90, 88, 86, 88, 105, 81, 79, 69,
-  77, 87, 69, 86, 71, 89, 80, 97, 91, 74,
-  73, 81, 75, 71, 96, 83, 88, 99, 89, 73,
-  90, 89, 68, 107, 78, 98, 83, 81, 83, 77,
-  86, 83, 79, 86, 85, 89, 84, 74, 82, 85,
-  81, 77, 78, 79, 89, 82, 86, 72, 73, 77,
-  86, 98, 90, 96, 81, 97, 97, 87, 100, 93,
-  85, 97, 88, 80, 82, 85, 88, 78, 94, 86,
-  80, 86, 76, 84, 86, 74, 80, 84, 77, 88,
-  86, 61, 74, 87, 77, 66, 95, 67, 98, 84,
-  95, 85, 86, 76, 77, 87, 73, 91, 82, 84,
-  83, 89, 78, 84, 97, 89, 76, 73, 88, 93,
-  84, 68, 93, 81, 78, 86, 82, 76, 68, 57,
-  82, 86, 61, 79, 76, 86, 67, 81, 80, 71,
-  78, 92, 70, 71, 92, 79, 80, 69, 81, 80,
-  92, 77, 90, 74, 85, 89, 82, 70, 99, 83,
-  89, 84, 89, 74, 73, 79, 74, 89, 85, 107,
-  79, 87, 84, 85, 81, 80, 84, 80, 84, 79,
-  86, 74, 100, 84, 92, 74, 90, 82, 86, 80,
-  81, 97, 78, 88, 88, 74, 81, 100, 94, 98,
-  67, 82, 80, 77, 94, 73, 80, 98, 88, 80,
-  65, 85, 78, 71, 86, 77, 96, 89, 73, 81,
-  89, 69, 79, 77, 96, 83, 68, 76, 84, 80,
-  86, 81, 71, 90, 88, 74, 89, 80, 88, 84,
-  88, 83, 92, 86, 72, 90, 96, 87, 85, 84,
-  77, 89, 82, 87, 88, 72, 85, 73, 82, 90,
-  88, 74, 86, 78, 75, 74, 85, 72, 82, 94,
-  85, 82, 94, 83, 84, 92, 76, 86, 85, 74,
-  88, 91, 86, 79, 85, 75, 91, 82, 91, 87,
-  83, 75, 77, 82, 79, 84, 94, 87, 75, 77,
-  88, 82, 87, 77, 90, 99, 86, 70, 77, 70,
-  86, 85, 84, 67, 68, 86, 80, 90, 104, 99,
-  85, 82, 92, 81, 93, 96, 91, 95, 79, 89,
-  74, 81, 89, 76, 88, 95, 82, 79, 59, 71,
-  68, 60, 84, 77, 84, 92, 80, 77, 89, 82,
-  72, 76, 102, 73, 87, 87, 86, 85, 76, 84,
-  74, 95, 84, 84, 89, 78, 86, 90, 74, 82,
-  94, 95, 60, 81, 85, 83, 86, 79, 88, 90,
-  81, 83, 84, 74, 81, 66, 81, 86, 73, 74,
-  81, 82, 69, 73, 80, 75, 76, 94, 82, 68,
-  114, 76, 83, 86, 84, 88, 82, 76, 96, 82,
-  84, 81, 81, 66, 82, 94, 88, 70, 79, 96,
-  80, 75, 80, 84, 79, 87, 73, 87, 88, 83,
-  86, 79, 81, 82, 80, 77, 79, 84, 94, 77,
-  83, 74, 83, 81, 84, 89, 77, 86, 90, 94,
-  100, 80, 91, 97, 83, 98, 72, 80, 90, 64,
-  86, 76, 96, 91, 84, 87, 72, 81, 87, 80,
-  82, 80, 86, 80, 90, 75, 80, 88, 87, 74,
-  95, 87, 101, 67, 85, 88, 83, 82, 82, 75,
-  97, 86, 87, 81, 83, 82, 78, 81, 87, 84,
-  78, 88, 84, 97, 88, 77, 86, 80, 85, 83,
-  86, 82, 76, 77, 82, 85, 84, 83, 78, 84,
-  78, 82, 80, 69, 86, 80, 93, 83, 99, 78,
-  81, 83, 83, 79, 96, 82, 85, 85, 81, 83,
-  88, 83, 81, 85, 83, 85, 79, 78, 79, 82,
-  81, 78, 85, 88, 81, 88, 89, 79, 83, 89,
-  85, 87, 84, 96, 88, 84, 83, 86, 82, 89,
-  85, 80, 86, 85, 87, 89, 82, 86, 87, 81,
-  79, 90, 87, 91, 91, 86, 91, 85, 78, 81,
-  82, 82, 79, 87, 77, 83, 80, 91, 85, 95,
-  78, 88, 91, 85, 86, 77, 82, 86, 80, 91,
-  85, 79, 75, 76, 82, 82, 88, 83, 77, 86,
-  90, 84, 87, 89, 77, 78, 93, 82, 85, 82,
-  81, 83, 78, 90, 82, 78, 75, 87, 85, 82,
-  85, 84, 89, 84, 87, 75, 81, 85, 80, 85,
-  86, 84, 88, 87, 85, 83, 86, 75, 87, 83,
-  95, 86, 80, 74, 87, 82, 82, 80, 85, 84,
-  86, 81, 80, 85, 75, 73, 79, 80, 79, 76,
-  83, 86, 84, 86, 89, 77, 81, 88, 83, 88,
-  86, 94, 85, 80, 83, 85, 72, 87, 79, 79,
-  89, 80, 87, 83, 85, 81, 86, 76, 78, 90,
-  80, 89, 86, 84, 92, 83, 80, 79, 82, 79,
-  77, 84, 76, 83, 80, 85, 83, 91, 79, 89,
-  89, 82, 87, 76, 80, 86, 80, 90, 83, 79,
-  75, 72, 84, 80, 91, 84, 79, 87, 85, 83,
-  84, 84, 75, 76, 90, 83, 80, 87, 79, 81,
-  76, 84, 81, 74, 74, 88, 84, 79, 86, 85,
-  88, 81, 86, 77, 83, 83, 76, 85, 83, 87,
-  82, 90, 80, 83, 82, 73, 87, 80, 89, 86,
-  77, 77, 86, 78, 83, 82, 87, 85, 89, 83,
-  82, 83, 81, 77, 80, 85, 84, 78, 85, 87,
-  83, 91, 89, 84, 84, 95, 90, 83, 87, 92,
-  85, 81, 88, 86, 82, 82, 87, 86, 89, 85,
-  85, 90, 80, 82, 83, 84, 83, 87, 88, 92,
-  91, 84, 87, 83, 78, 82, 80, 80, 78, 86,
-  78, 89, 81, 87, 90, 90, 82, 89, 91, 88,
-  87, 80, 78, 87, 79, 90, 86, 80, 80, 75,
-  88, 86, 85, 92, 82, 83, 90, 81, 88, 82,
-  76, 77, 89, 83, 82, 89, 81, 86, 84, 90,
-  82, 83, 81, 87, 85, 76, 86, 84, 86, 80,
-  88, 78, 86, 86, 81, 87, 84, 87, 84, 95,
-  81, 80, 84, 76, 83, 82, 91, 86, 82, 78,
-  91, 79, 81, 80, 85, 77, 79, 85, 80, 87,
-  77, 83, 80, 79, 84, 80, 80, 84, 84, 82,
-  84, 82, 84, 84, 82, 79, 79, 99, 91, 93,
-  82, 89, 81, 91, 90, 85, 89, 82, 89, 87,
-  85, 78, 85, 83, 79, 99, 91, 86, 92, 77,
-  87, 82, 82, 84, 90, 81, 84, 86, 83, 84,
-  84, 86, 84, 88, 84, 88, 92, 89, 83, 79,
-  84, 86, 80, 90, 77, 77, 75, 74, 80, 85,
-  93, 82, 72, 94, 87, 73, 85, 86, 80, 82,
-  85, 83, 88, 84, 82, 84, 81, 93, 77, 77,
-  84, 90, 83, 94, 76, 82, 88, 87, 86, 81,
-  79, 81, 81, 81, 87, 84, 88, 85, 87, 85,
-  84, 78, 88, 86, 91, 80, 72, 82, 82, 87,
-  79, 77, 81, 78, 77, 79, 75, 82, 77, 79,
-  78, 80, 85, 82, 75, 84, 87, 81, 81, 79,
-  81, 81, 82, 81, 85, 101, 83, 90, 79, 89,
-  65, 87, 83, 82, 92, 76, 85, 80, 89, 77,
-  85, 78, 82, 101, 79, 85, 90, 72, 85, 83,
-  86, 85, 85, 81, 81, 83, 87, 83, 87, 83,
-  87, 84, 83, 92, 91, 91, 79, 84, 80, 88,
-  84, 85, 79, 81, 76, 72, 83, 90, 96, 81,
-  75, 96, 83, 75, 81, 79, 82, 80, 81, 86,
-  85, 87, 83, 79, 81, 88, 73, 72, 80, 92,
-  88, 100, 75, 83, 92, 84, 87, 84, 79, 77,
-  77, 79, 86, 83, 84, 81, 84, 88, 78, 82,
-  92, 85, 80, 73, 71, 85, 84, 80, 78, 81,
-  88, 82, 79, 86, 82, 82, 75, 80, 79, 84,
-  87, 81, 83, 87, 83, 83, 86, 86, 85, 92,
-  89, 75, 90, 92, 82, 89, 87, 88, 80, 81,
-  93, 88, 92, 83, 87, 85, 85, 79, 83, 77,
-  82, 87, 87, 89, 86, 78, 80, 84, 80, 82,
-  85, 78, 82, 82, 82, 88, 81, 85, 90, 91,
-  85, 83, 90, 86, 84, 76, 77, 86, 81, 88,
-  82, 78, 80, 76, 86, 86, 91, 93, 80, 86,
-  86, 78, 85, 78, 79, 85, 86, 83, 84, 89,
-  81, 85, 85, 91, 82, 79, 89, 88, 87, 84,
-  79, 83, 85, 83, 88, 81, 84, 82, 86, 83,
-  88, 86, 88, 87, 83, 78, 79, 81, 84, 83,
-  84, 86, 74, 80, 84, 86, 80, 79, 87, 78,
-  85, 94, 84, 75, 97, 87, 81, 84, 89, 80,
-  89, 89, 70, 91, 91, 91, 87, 88, 94, 84,
-  79, 82, 84, 83, 86, 90, 171, 80, 94, 90,
-  86, 94, 86, 81, 85, 96, 81, 115, 93, 77,
-  90, 87, 82, 75, 77, 83, 80, 86, 79, 94,
-  83, 96, 77, 81, 79, 95, 80, 102, 82, 82,
-  91, 94, 81, 86, 96, 80, 76, 84, 76, 80,
-  81, 82, 78, 81, 91, 83, 92, 67, 89, 72,
-  86, 83, 78, 89, 86, 86, 96, 80, 81, 94,
-  82, 87, 90, 85, 85, 88, 79, 85, 87, 80,
-  81, 88, 80, 79, 86, 91, 86, 81, 81, 82,
-  85, 85, 86, 78, 84, 83, 83, 81, 84, 92,
-  68, 78, 78, 82, 90, 80, 86, 78, 83, 87,
-  79, 76, 97, 85, 80, 83, 90, 81, 85, 82,
-  70, 83, 90, 91, 86, 85, 92, 84, 80, 79,
-  81, 82, 86, 90, 181, 85, 85, 88, 87, 83,
-  75, 78, 92, 96, 86, 118, 100, 76, 89, 87,
-  83, 76, 73, 80, 84, 84, 75, 90, 80, 93,
-  84, 80, 82, 93, 81, 94, 86, 86, 93, 100,
-  80, 91, 93, 79, 76, 90, 82, 80, 79, 87,
-  78, 86, 91, 81, 89, 66, 84, 72, 84, 77,
-  81, 88, 79, 90, 94, 78, 84, 94, 82, 82,
-  86, 83, 87, 87, 80, 94, 92, 82, 84, 85,
-  76, 79, 85, 89, 79, 77, 78, 81, 80, 77,
-  79, 84, 82, 87, 85, 82, 80, 83, 65, 77,
-  78, 77, 87, 82, 86, 83, 89, 93, 86, 79,
-  94, 87, 81, 85, 89, 81, 92, 80, 70, 89,
-  90, 96, 88, 96, 90, 76, 81, 78, 85, 79,
-  90, 88, 167, 89, 91, 95, 87, 86, 75, 81,
-  82, 100, 89, 112, 90, 68, 91, 89, 77, 79,
-  78, 80, 78, 84, 74, 84, 80, 92, 80, 89,
-  83, 94, 87, 101, 80, 76, 87, 91, 83, 86,
-  85, 79, 75, 87, 86, 77, 83, 81, 83, 87,
-  89, 87, 93, 64, 85, 75, 85, 81, 76, 92,
-  84, 85, 90, 82, 80, 90, 84, 84, 87, 81,
-  86, 85, 87, 79, 87, 76, 80, 86, 79, 84,
-  91, 90, 85, 88, 79, 83, 84, 81, 82, 78,
-  79, 84, 82, 79, 92, 99, 72, 80, 81, 86,
-  90, 79, 79, 102, 74, 94, 70, 71, 77, 94,
-  100, 92, 72, 78, 99, 72, 66, 79, 81, 80,
-  81, 83, 68, 92, 90, 85, 79, 91, 106, 94,
-  111, 88, 60, 81, 71, 83, 60, 91, 112, 82,
-  96, 80, 91, 69, 106, 70, 72, 89, 71, 94,
-  91, 83, 82, 87, 89, 74, 100, 96, 95, 60,
-  79, 81, 86, 85, 53, 90, 62, 68, 94, 90,
-  83, 113, 89, 77, 116, 66, 82, 98, 84, 78,
-  82, 77, 85, 77, 91, 90, 83, 78, 94, 71,
-  69, 85, 81, 99, 73, 98, 112, 82, 88, 78,
-  77, 112, 94, 91, 95, 92, 70, 80, 64, 79,
-  82, 66, 77, 41, 79, 92, 106, 91, 80, 75,
-  79, 91, 78, 86, 83, 89, 78, 73, 85, 61,
-  78, 78, 82, 94, 71, 80, 66, 99, 100, 96,
-  73, 72, 81, 85, 65, 72, 76, 66, 71, 82,
-  89, 95, 93, 82, 75, 76, 111, 93, 112, 81,
-  48, 81, 59, 82, 61, 96, 110, 86, 82, 72,
-  95, 63, 69, 62, 72, 97, 78, 78, 97, 75,
-  91, 96, 83, 64, 108, 88, 98, 55, 77, 78,
-  77, 96, 49, 81, 66, 66, 77, 74, 77, 114,
-  123, 75, 113, 71, 85, 101, 88, 94, 74, 73,
-  80, 71, 92, 99, 76, 86, 90, 73, 67, 69,
-  81, 94, 76, 84, 130, 79, 87, 76, 62, 118,
-  96, 84, 87, 93, 64, 76, 66, 76, 67, 68,
-  80, 38, 74, 87, 120, 83, 91, 79, 68, 83,
-  74, 83, 72, 87, 74, 72, 76, 58, 74, 74,
-  78, 88, 81, 79, 70, 94, 91, 94, 78, 79,
-  90, 89, 67, 78, 88, 73, 82, 79, 109, 84,
-  81, 96, 88, 84, 102, 90, 91, 78, 79, 73,
-  80, 81, 61, 88, 85, 87, 76, 83, 84, 74,
-  55, 74, 82, 86, 85, 72, 90, 85, 87, 86,
-  90, 73, 97, 76, 99, 66, 84, 81, 76, 85,
-  73, 92, 64, 75, 94, 87, 82, 108, 65, 66,
-  122, 68, 83, 103, 90, 80, 64, 84, 83, 79,
-  91, 99, 83, 84, 91, 68, 82, 79, 86, 81,
-  83, 94, 115, 86, 87, 82, 65, 108, 84, 86,
-  93, 96, 81, 79, 68, 75, 79, 78, 87, 47,
-  75, 91, 106, 97, 83, 82, 81, 84, 84, 81,
-  87, 84, 83, 81, 90, 59, 71, 82, 78, 77,
-  61, 91, 88, 74, 90, 79, 79, 64, 90, 108,
-  83, 72, 85, 81, 69, 82, 92, 88, 83, 82,
-  84, 94, 91, 91, 96, 107, 109, 74, 72, 75,
-  78, 75, 94, 79, 77, 72, 81, 85, 91, 89,
-  68, 68, 81, 90, 79, 87, 82, 102, 80, 80,
-  87, 86, 74, 87, 66, 103, 97, 78, 55, 89,
-  87, 63, 99, 89, 79, 98, 60, 82, 77, 90,
-  91, 66, 83, 73, 93, 75, 86, 90, 76, 81,
-  84, 88, 89, 90, 87, 84, 68, 78, 72, 96,
-  70, 88, 97, 92, 80, 65, 90, 72, 95, 78,
-  84, 75, 79, 94, 84, 76, 85, 70, 84, 77,
-  91, 80, 87, 79, 82, 124, 108, 94, 87, 80,
-  76, 85, 81, 86, 66, 91, 64, 78, 66, 72,
-  85, 75, 108, 74, 78, 62, 95, 74, 80, 76,
-  85, 81, 65, 90, 95, 72, 84, 84, 86, 100,
-  100, 97, 97, 84, 107, 68, 64, 68, 90, 74,
-  99, 76, 77, 85, 74, 68, 103, 94, 55, 82,
-  87, 71, 70, 82, 89, 96, 79, 72, 77, 94,
-  70, 87, 58, 110, 82, 66, 54, 87, 65, 42,
-  93, 86, 76, 71, 102, 71, 75, 88, 93, 60,
-  81, 83, 118, 67, 84, 92, 81, 83, 86, 86,
-  81, 80, 107, 80, 71, 89, 75, 94, 73, 92,
-  89, 88, 62, 55, 91, 68, 87, 76, 84, 63,
-  78, 99, 98, 78, 94, 64, 78, 79, 92, 64,
-  69, 73, 68, 115, 96, 95, 88, 78, 75, 90,
-  77, 87, 68, 84, 62, 77, 77, 79, 72, 79,
-  104, 88, 80, 65, 73, 61, 82, 75, 81, 71,
-  73, 85, 81, 81, 85, 90, 92, 92, 86, 85,
-  92, 66, 110, 78, 68, 74, 84, 85, 102, 76,
-  81, 73, 79, 91, 77, 80, 77, 93, 93, 81,
-  88, 79, 81, 90, 81, 72, 100, 90, 82, 74,
-  75, 95, 88, 85, 65, 83, 72, 59, 85, 82,
-  89, 93, 117, 74, 90, 75, 98, 78, 91, 91,
-  109, 70, 81, 85, 82, 89, 81, 81, 82, 82,
-  87, 82, 65, 82, 77, 88, 103, 85, 89, 84,
-  63, 85, 91, 89, 97, 80, 81, 74, 78, 88,
-  93, 70, 85, 60, 78, 82, 85, 82, 73, 81,
-  74, 107, 82, 88, 85, 80, 81, 81, 84, 79,
-  94, 66, 73, 88, 70, 101, 92, 78, 70, 83,
-  78, 83, 82, 82, 87, 82, 92, 92, 81, 88,
-  88, 87, 82, 69, 71, 95, 76, 84, 91, 105,
-  118, 84, 96, 90, 92, 88, 83, 89, 88, 71,
-  78, 86, 85, 96, 83, 70, 93, 99, 79, 85,
-  89, 81, 87, 100, 91, 86, 73, 96, 94, 74,
-  93, 89, 77, 84, 97, 88, 91, 84, 89, 64,
-  93, 87, 75, 99, 94, 72, 73, 95, 83, 86,
-  82, 76, 78, 91, 83, 84, 87, 94, 78, 83,
-  77, 77, 88, 84, 70, 87, 97, 93, 102, 76,
-  78, 90, 88, 82, 93, 85, 90, 97, 65, 81,
-  82, 96, 94, 74, 69, 77, 72, 90, 88, 96,
-  88, 78, 86, 84, 88, 78, 82, 85, 94, 79,
-  77, 88, 65, 82, 90, 72, 72, 81, 76, 84,
-  92, 86, 95, 80, 97, 99, 84, 98, 86, 88,
-  83, 67, 75, 88, 72, 83, 84, 89, 128, 84,
-  108, 94, 93, 82, 88, 91, 84, 72, 78, 101,
-  96, 101, 83, 59, 101, 87, 66, 89, 91, 81,
-  83, 102, 80, 79, 78, 95, 93, 76, 85, 79,
-  78, 84, 79, 83, 101, 89, 91, 69, 71, 84,
-  69, 92, 92, 68, 70, 101, 77, 87, 82, 68,
-  72, 86, 98, 85, 78, 86, 80, 82, 76, 77,
-  93, 89, 63, 91, 93, 94, 89, 69, 71, 65,
-  85, 78, 85, 91, 84, 101, 65, 84, 83, 99,
-  89, 76, 80, 86, 68, 95, 100, 79, 78, 82,
-  78, 87, 78, 77, 86, 91, 80, 96, 86, 87,
-  80, 83, 76, 79, 88, 85, 80, 80, 77, 82,
-  83, 85, 89, 83, 84, 89, 79, 92, 94, 75,
-  82, 96, 71, 81, 86, 80, 118, 83, 86, 84,
-  90, 98, 83, 90, 81, 81, 85, 82, 89, 84,
-  84, 81, 104, 104, 81, 83, 88, 85, 83, 86,
-  86, 65, 75, 91, 86, 79, 82, 95, 80, 77,
-  98, 72, 93, 83, 95, 75, 100, 87, 80, 89,
-  87, 77, 83, 95, 93, 76, 79, 77, 81, 95,
-  78, 90, 75, 87, 84, 85, 71, 82, 90, 87,
-  80, 86, 90, 88, 71, 79, 85, 71, 87, 79,
-  91, 83, 85, 91, 83, 78, 79, 87, 83, 82,
-  87, 87, 106, 88, 83, 95, 87, 83, 85, 86,
-  78, 78, 85, 84, 73, 82, 74, 77, 78, 87,
-  78, 98, 80, 83, 80, 74, 67, 77, 76, 90,
-  85, 85, 77, 90, 102, 89, 84, 77, 75, 86,
-  104, 78, 92, 79, 83, 84, 100, 84, 90, 94,
-  83, 82, 95, 75, 93, 65, 78, 92, 77, 86,
-  84, 83, 91, 76, 99, 79, 87, 78, 87, 80,
-  92, 91, 78, 80, 80, 86, 81, 85, 99, 74,
-  91, 84, 56, 80, 91, 97, 82, 101, 77, 67,
-  68, 90, 88, 68, 83, 83, 75, 93, 76, 85,
-  96, 75, 86, 93, 105, 81, 98, 82, 97, 118,
-  75, 77, 101, 68, 80, 81, 87, 92, 93, 76,
-  79, 81, 62, 81, 84, 89, 87, 81, 81, 88,
-  76, 97, 82, 80, 86, 92, 84, 85, 81, 93,
-  98, 84, 68, 85, 84, 72, 86, 69, 71, 94,
-  84, 80, 101, 77, 63, 86, 76, 83, 80, 72,
-  78, 74, 88, 84, 76, 79, 78, 76, 79, 74,
-  87, 85, 87, 94, 104, 82, 81, 104, 78, 74,
-  74, 75, 100, 68, 100, 95, 78, 90, 84, 91,
-  84, 87, 96, 85, 88, 86, 86, 76, 82, 78,
-  83, 82, 73, 87, 75, 82, 96, 69, 95, 81,
-  48, 82, 88, 101, 85, 97, 78, 66, 64, 92,
-  87, 75, 84, 76, 69, 96, 73, 77, 84, 88,
-  74, 82, 91, 73, 99, 74, 89, 123, 73, 73,
-  84, 76, 79, 98, 91, 92, 79, 79, 73, 83,
-  60, 79, 88, 85, 80, 84, 82, 92, 97, 90,
-  76, 85, 88, 91, 86, 77, 82, 87, 98, 83,
-  68, 70, 89, 84, 94, 85, 82, 102, 81, 83,
-  78, 75, 63, 86, 70, 87, 85, 94, 81, 83,
-  71, 78, 90, 80, 85, 88, 96, 84, 89, 90,
-  92, 89, 98, 87, 76, 91, 86, 83, 87, 81,
-  96, 71, 103, 92, 79, 90, 79, 88, 90, 75,
-  89, 77, 78, 86, 88, 88, 87, 93, 80, 82,
-  77, 92, 74, 76, 94, 80, 85, 73, 65, 90,
-  85, 86, 75, 94, 80, 75, 68, 75, 91, 68,
-  93, 89, 74, 87, 85, 88, 86, 69, 91, 80,
-  93, 75, 100, 76, 95, 94, 83, 81, 78, 69,
-  77, 82, 85, 92, 101, 81, 87, 83, 71, 83,
-  76, 79, 84, 91, 88, 80, 87, 94, 88, 77,
-  87, 91, 89, 90, 83, 91, 90, 90, 40, 86,
-  77, 85, 75, 69, 65, 72, 92, 82, 108, 65,
-  56, 94, 73, 90, 82, 75, 74, 80, 100, 90,
-  59, 74, 70, 79, 85, 82, 100, 79, 78, 94,
-  100, 72, 92, 81, 73, 83, 105, 70, 87, 72,
-  74, 92, 55, 81, 79, 92, 83, 80, 90, 97,
-  84, 99, 72, 84, 99, 78, 88, 65, 68, 126,
-  82, 86, 63, 123, 87, 75, 94, 65, 69, 58,
-  93, 99, 68, 64, 54, 80, 97, 68, 81, 86,
-  69, 111, 76, 81, 91, 85, 85, 96, 107, 81,
-  79, 62, 100, 128, 74, 60, 94, 74, 85, 82,
-  86, 87, 81, 66, 90, 90, 71, 70, 76, 77,
-  73, 68, 75, 94, 70, 75, 69, 84, 84, 100,
-  80, 78, 88, 84, 101, 95, 32, 84, 90, 70,
-  103, 32, 67, 62, 85, 78, 142, 73, 79, 102,
-  66, 77, 76, 54, 70, 70, 82, 99, 43, 69,
-  77, 70, 58, 73, 102, 92, 98, 104, 87, 70,
-  84, 110, 68, 81, 125, 82, 103, 74, 93, 97,
-  52, 61, 85, 105, 74, 87, 87, 117, 81, 118,
-  63, 94, 73, 70, 115, 56, 61, 136, 70, 100,
-  40, 170, 86, 72, 92, 45, 82, 62, 80, 96,
-  74, 54, 41, 100, 104, 78, 81, 74, 55, 95,
-  87, 85, 63, 117, 74, 75, 83, 75, 92, 56,
-  72, 155, 67, 51, 101, 86, 76, 98, 95, 86,
-  63, 65, 73, 95, 53, 70, 81, 80, 60, 65,
-  85, 106, 92, 78, 88, 89, 88, 101, 77, 68,
-  93, 73, 109, 93, 56, 60, 85, 93, 81, 69,
-  69, 96, 84, 84, 95, 61, 50, 82, 66, 97,
-  84, 99, 81, 84, 75, 73, 80, 84, 81, 86,
-  100, 91, 83, 81, 79, 105, 103, 74, 82, 88,
-  75, 89, 75, 75, 82, 70, 89, 87, 66, 95,
-  82, 84, 90, 78, 86, 73, 87, 90, 85, 69,
-  97, 80, 83, 87, 73, 116, 87, 52, 77, 93,
-  77, 81, 91, 89, 75, 65, 91, 99, 79, 70,
-  51, 77, 87, 73, 90, 92, 75, 92, 77, 82,
-  80, 55, 87, 95, 96, 81, 69, 69, 108, 95,
-  83, 66, 75, 72, 83, 93, 85, 87, 95, 76,
-  91, 82, 79, 77, 60, 70, 80, 94, 71, 77,
-  85, 74, 68, 74, 99, 90, 96, 91, 90, 81,
-  90, 104, 61, 81, 80, 91, 79, 77, 78, 79,
-  79, 90, 92, 81, 60, 100, 77, 87, 89, 94,
-  71, 85, 91, 94, 75, 94, 88, 83, 100, 87,
-  87, 75, 87, 80, 103, 72, 95, 85, 73, 87,
-  69, 76, 81, 75, 83, 85, 66, 87, 89, 97,
-  84, 78, 93, 85, 88, 79, 79, 79, 105, 81,
-  79, 71, 80, 96, 67, 88, 82, 92, 77, 94,
-  104, 80, 78, 66, 88, 92, 86, 72, 69, 85,
-  106, 64, 82, 94, 75, 113, 102, 76, 102, 86,
-  96, 108, 97, 83, 86, 65, 104, 91, 82, 69,
-  99, 71, 79, 85, 87, 90, 87, 74, 92, 84,
-  82, 71, 67, 78, 76, 82, 80, 91, 69, 85,
-  75, 72, 93, 90, 85, 81, 79, 89, 91, 87,
-  52, 83, 89, 84, 86, 54, 80, 72, 79, 84,
-  115, 87, 62, 88, 72, 75, 80, 74, 68, 80,
-  75, 84, 60, 92, 89, 71, 84, 80, 84, 92,
-  85, 92, 103, 71, 94, 104, 69, 78, 110, 70,
-  104, 84, 85, 82, 64, 59, 97, 99, 79, 88,
-  93, 89, 83, 87, 82, 85, 95, 75, 86, 66,
-  77, 100, 54, 91, 65, 119, 75, 92, 109, 68,
-  77, 74, 87, 86, 88, 66, 66, 87, 105, 71,
-  83, 85, 65, 107, 98, 89, 79, 105, 83, 93,
-  97, 83, 91, 61, 88, 108, 75, 66, 97, 82,
-  82, 84, 87, 88, 71, 78, 75, 85, 69, 70,
-  60, 83, 62, 79, 84, 84, 92, 83, 85, 80,
-  101, 89, 78, 72, 84, 84, 93, 92, 67, 73,
-  89, 86, 79, 88, 86, 88, 79, 88, 82, 77,
-  64, 86, 79, 89, 86, 110, 72, 83, 79, 79,
-  79, 99, 92, 87, 106, 87, 78, 82, 92, 83,
-  99, 76, 91, 88, 81, 86, 95, 76, 83, 83,
-  89, 89, 70, 81, 88, 91, 88, 74, 96, 86,
-  87, 79, 79, 80, 102, 89, 87, 84, 81, 91,
-  68, 71, 85, 87, 66, 91, 94, 96, 73, 77,
-  82, 96, 91, 72, 67, 72, 92, 73, 90, 99,
-  76, 91, 101, 78, 86, 65, 96, 97, 87, 86,
-  86, 67, 92, 80, 84, 80, 88, 68, 76, 95,
-  86, 90, 90, 84, 91, 81, 80, 87, 68, 71,
-  80, 95, 80, 93, 82, 90, 87, 74, 98, 89,
-  82, 85, 79, 83, 86, 91, 90, 84, 87, 82,
-  82, 89, 82, 73, 86, 100, 79, 89, 95, 91,
-  84, 80, 71, 93, 63, 84, 89, 79, 91, 85,
-  92, 78, 93, 74, 94, 92, 80, 82, 78, 92,
-  94, 84, 85, 81, 84, 91, 80, 87, 95, 79,
-  77, 91, 89, 82, 89, 91, 85, 96, 95, 63,
-  87, 85, 77, 73, 68, 87, 83, 83, 76, 82,
-  78, 88, 82, 82, 81, 95, 80, 79, 84, 87,
-  92, 80, 83, 81, 88, 73, 85, 82, 70, 73,
-  80, 101, 93, 91, 88, 68, 74, 81, 87, 89,
-  81, 82, 77, 86, 75, 56, 87, 81, 81, 72,
-  93, 87, 96, 85, 82, 101, 93, 86, 75, 85,
-  90, 78, 88, 91, 83, 71, 78, 91, 58, 74,
-  93, 100, 69, 90, 92, 86, 80, 78, 83, 87,
-  84, 68, 75, 105, 78, 87, 96, 86, 84, 79,
-  68, 89, 59, 87, 96, 73, 93, 88, 81, 77,
-  90, 78, 84, 92, 77, 83, 77, 92, 95, 81,
-  93, 85, 86, 95, 83, 87, 89, 81, 82, 92,
-  87, 77, 84, 89, 88, 92, 95, 64, 88, 88,
-  74, 71, 64, 86, 89, 87, 79, 84, 73, 90,
-  76, 80, 84, 90, 81, 76, 80, 84, 97, 75,
-  86, 84, 89, 74, 86, 80, 63, 73, 76, 101,
-  90, 85, 89, 65, 63, 83, 85, 84, 82, 82,
-  70, 87, 82, 60, 85, 86, 79, 75, 88, 81,
-  92, 88, 82, 104, 92, 84, 69, 85, 84, 80,
-  88, 92, 83, 69, 74, 91, 51, 75, 94, 96,
-  69, 93, 85, 86, 78, 77, 86, 86, 83, 77,
-  82, 95, 82, 91, 92, 82, 83, 87, 75, 89,
-  64, 84, 94, 77, 91, 87, 82, 79, 94, 75,
-  85, 90, 81, 81, 78, 87, 96, 80, 92, 82,
-  91, 100, 84, 82, 86, 79, 79, 91, 85, 80,
-  88, 88, 87, 89, 93, 65, 86, 94, 73, 75,
-  69, 89, 89, 84, 77, 80, 77, 84, 81, 84,
-  89, 84, 88, 76, 83, 87, 96, 81, 87, 90,
-  93, 76, 84, 82, 71, 84, 76, 100, 90, 86,
-  90, 75, 70, 89, 84, 87, 79, 78, 75, 86,
-  91, 66, 90, 84, 80, 75, 90, 84, 90, 87,
-  85, 98, 91, 84, 73, 92, 82, 76, 85, 86,
-  84, 73, 71, 90, 58, 79, 87, 95, 72, 91,
-  95, 76, 92, 82, 81, 81, 70, 85, 103, 91,
-  81, 85, 93, 83, 78, 90, 88, 83, 73, 79,
-  77, 76, 77, 81, 94, 77, 90, 72, 96, 80,
-  78, 84, 75, 85, 82, 76, 96, 65, 91, 78,
-  62, 75, 83, 79, 67, 94, 98, 86, 86, 93,
-  88, 93, 90, 72, 84, 83, 76, 79, 72, 94,
-  88, 75, 62, 85, 72, 80, 87, 80, 93, 81,
-  79, 78, 85, 87, 87, 71, 81, 80, 85, 75,
-  95, 77, 92, 78, 79, 100, 96, 90, 86, 73,
-  73, 88, 67, 83, 86, 77, 65, 85, 78, 64,
-  86, 86, 85, 74, 97, 108, 83, 79, 59, 93,
-  79, 87, 83, 88, 85, 83, 84, 81, 86, 70,
-  80, 95, 65, 73, 86, 98, 68, 84, 100, 76,
-  87, 85, 80, 81, 68, 86, 97, 89, 82, 83,
-  93, 85, 76, 94, 85, 75, 76, 84, 80, 71,
-  80, 84, 84, 73, 88, 73, 81, 82, 75, 86,
-  84, 82, 81, 80, 95, 63, 87, 73, 57, 75,
-  78, 76, 70, 96, 99, 84, 85, 92, 85, 89,
-  88, 71, 86, 80, 76, 73, 68, 97, 89, 80,
-  65, 88, 67, 80, 83, 81, 99, 78, 75, 77,
-  85, 82, 93, 67, 81, 87, 83, 75, 94, 73,
-  96, 86, 73, 95, 92, 84, 81, 70, 68, 85,
-  62, 81, 84, 74, 64, 82, 85, 68, 90, 87,
-  88, 76, 98, 108, 80, 84, 56, 91, 75, 83,
-  85, 88, 80, 85, 86, 80, 85, 67, 72, 88,
-  64, 77, 82, 96, 67, 91, 91, 81, 89, 84,
-  80, 80, 72, 89, 97, 87, 83, 87, 89, 91,
-  76, 93, 86, 79, 83, 81, 86, 79, 82, 84,
-  83, 79, 92, 73, 85, 83, 82, 82, 78, 79,
-  87, 83, 101, 68, 88, 83, 66, 72, 79, 80,
-  68, 90, 92, 80, 88, 89, 90, 94, 87, 74,
-  87, 85, 78, 78, 74, 95, 88, 79, 62, 83,
-  73, 78, 86, 84, 99, 85, 83, 76, 81, 83,
-  92, 77, 84, 89, 85, 75, 94, 80, 95, 96,
-  76, 92, 91, 85, 86, 76, 72, 87, 66, 83,
-  82, 77, 69, 83, 88, 70, 89, 86, 83, 76,
-  100, 107, 84, 82, 64, 85, 79, 87, 84, 94,
-  86, 84, 82, 78, 86, 72, 72, 91, 72, 74,
-  82, 93, 73, 87, 77, 83, 99, 81, 88, 90,
-  77, 93, 110, 77, 95, 93, 86, 84, 74, 85,
-  100, 81, 94, 86, 80, 72, 66, 78, 91, 84,
-  87, 74, 84, 81, 88, 83, 73, 76, 71, 79,
-  93, 72, 94, 70, 78, 63, 93, 82, 65, 90,
-  85, 88, 106, 83, 97, 94, 78, 100, 95, 87,
-  87, 82, 98, 85, 87, 84, 69, 87, 80, 71,
-  98, 95, 101, 85, 71, 91, 76, 80, 94, 75,
-  79, 88, 96, 68, 94, 88, 111, 100, 86, 97,
-  94, 92, 86, 82, 85, 92, 64, 90, 87, 88,
-  87, 86, 87, 103, 86, 68, 82, 83, 130, 112,
-  74, 82, 60, 58, 74, 80, 116, 98, 95, 78,
-  79, 68, 80, 81, 83, 87, 82, 71, 78, 99,
-  94, 69, 76, 83, 87, 85, 88, 83, 77, 93,
-  103, 80, 98, 92, 83, 89, 69, 80, 98, 76,
-  102, 96, 83, 70, 74, 81, 87, 82, 79, 73,
-  60, 77, 87, 81, 75, 79, 75, 82, 93, 76,
-  90, 65, 82, 68, 87, 80, 71, 87, 78, 97,
-  106, 79, 93, 94, 75, 104, 96, 91, 92, 76,
-  97, 90, 82, 90, 68, 92, 80, 73, 94, 102,
-  105, 80, 72, 94, 74, 70, 109, 78, 76, 93,
-  96, 68, 89, 82, 105, 98, 92, 92, 97, 91,
-  82, 80, 84, 90, 61, 96, 89, 87, 89, 81,
-  90, 119, 88, 68, 90, 87, 138, 115, 69, 89,
-  61, 55, 71, 82, 130, 93, 92, 76, 72, 68,
-  84, 78, 79, 76, 79, 80, 75, 99, 104, 71,
-  80, 83, 82, 87, 90, 72, 81, 100, 112, 79,
-  100, 89, 85, 92, 74, 86, 102, 77, 102, 86,
-  91, 73, 79, 81, 87, 88, 86, 76, 75, 75,
-  89, 78, 77, 74, 85, 85, 94, 73, 83, 72,
-  83, 65, 83, 85, 69, 86, 84, 98, 103, 84,
-  97, 94, 77, 101, 95, 88, 86, 83, 92, 85,
-  86, 84, 67, 88, 81, 70, 103, 93, 99, 84,
-  83, 88, 73, 77, 98, 78, 79, 95, 101, 71,
-  92, 89, 108, 93, 86, 90, 98, 92, 85, 81,
-  91, 90, 63, 89, 84, 92, 89, 86, 88, 108,
-  90, 72, 77, 84, 132, 105, 76, 85, 66, 54,
-  74, 82, 115, 90, 91, 80, 73, 71, 84, 78,
-  80, 84, 90, 70, 77, 96, 93, 78, 85, 75,
-  78, 86, 139, 84, 71, 79, 73, 81, 78, 91,
-  74, 106, 77, 77, 76, 77, 85, 80, 82, 87,
-  100, 73, 88, 75, 88, 86, 94, 94, 77, 91,
-  77, 95, 88, 85, 81, 85, 89, 77, 83, 82,
-  86, 89, 76, 83, 78, 85, 79, 84, 80, 77,
-  78, 77, 87, 95, 70, 75, 91, 74, 83, 79,
-  94, 69, 91, 76, 88, 78, 86, 99, 67, 85,
-  93, 91, 76, 74, 80, 88, 72, 76, 80, 89,
-  80, 83, 57, 79, 86, 91, 74, 95, 76, 76,
-  88, 81, 93, 78, 90, 92, 79, 81, 82, 78,
-  82, 82, 83, 77, 81, 103, 80, 74, 85, 78,
-  75, 76, 96, 86, 91, 91, 84, 82, 89, 92,
-  79, 72, 97, 82, 85, 88, 83, 79, 66, 86,
-  164, 75, 66, 81, 68, 77, 82, 107, 84, 103,
-  78, 79, 77, 76, 87, 82, 84, 81, 80, 75,
-  87, 74, 90, 84, 89, 91, 84, 99, 81, 98,
-  95, 93, 86, 76, 99, 82, 84, 79, 82, 107,
-  86, 78, 86, 73, 72, 85, 79, 86, 78, 83,
-  77, 93, 66, 80, 103, 70, 88, 71, 101, 72,
-  87, 76, 89, 77, 88, 94, 77, 84, 91, 87,
-  80, 65, 85, 83, 83, 78, 82, 93, 78, 79,
-  54, 82, 86, 91, 84, 104, 73, 85, 94, 80,
-  89, 83, 94, 100, 79, 78, 88, 90, 80, 83,
-  84, 80, 75, 108, 85, 82, 82, 78, 73, 81,
-  105, 76, 75, 87, 78, 85, 95, 99, 74, 71,
-  106, 80, 83, 89, 83, 86, 77, 85, 116, 91,
-  74, 82, 78, 78, 83, 89, 83, 88, 74, 80,
-  80, 81, 87, 78, 86, 82, 78, 76, 81, 76,
-  88, 84, 92, 82, 78, 91, 77, 78, 95, 95,
-  82, 86, 89, 80, 86, 84, 80, 85, 83, 85,
-  79, 91, 80, 85, 82, 78, 82, 77, 85, 86,
-  77, 71, 88, 80, 85, 81, 88, 74, 81, 80,
-  73, 78, 81, 89, 94, 89, 99, 90, 79, 78,
-  82, 89, 79, 76, 80, 85, 86, 79, 63, 76,
-  78, 84, 76, 95, 79, 89, 86, 81, 89, 80,
-  87, 91, 81, 83, 80, 95, 79, 84, 82, 76,
-  80, 93, 79, 77, 77, 74, 73, 88, 92, 83,
-  86, 89, 83, 81, 95, 88, 83, 77, 90, 82,
-  85, 86, 79, 79, 74, 80, 172, 87, 63, 81,
-  80, 74, 75, 93, 85, 100, 78, 76, 87, 70,
-  82, 75, 81, 87, 83, 78, 86, 74, 73, 76,
-  98, 90, 75, 88, 78, 107, 81, 81, 73, 82,
-  98, 82, 85, 81, 87, 99, 86, 84, 86, 85,
-  72, 79, 84, 84, 81, 82, 77, 96, 64, 79,
-  103, 69, 74, 73, 88, 67, 85, 81, 81, 76,
-  91, 76, 69, 72, 83, 87, 75, 71, 77, 92,
-  75, 75, 91, 83, 76, 82, 56, 80, 85, 95,
-  76, 89, 71, 79, 98, 74, 94, 81, 84, 100,
-  82, 88, 90, 86, 80, 78, 82, 80, 85, 103,
-  73, 79, 80, 83, 70, 82, 112, 65, 79, 87,
-  80, 83, 90, 80, 72, 65, 102, 80, 84, 75,
-  71, 82, 72, 76, 199, 74, 55, 83, 77, 73,
-  81, 106, 101, 108, 81, 78, 89, 71, 84, 83,
-  86, 88, 78, 81, 85, 70, 72, 77, 95, 89,
-  86, 93, 77, 109, 81, 90, 80, 80, 118, 89,
-  87, 85, 81, 122, 100, 74, 91, 72, 71, 74,
-  79, 90, 80, 87, 69, 97, 69, 83, 112, 63,
-  75, 66, 91, 71, 69, 86, 85, 71, 93, 75,
-  61, 67, 83, 84, 80, 63, 80, 92, 77, 84,
-  93, 86, 74, 80, 55, 86, 83, 93, 83, 93,
-  68, 80, 103, 75, 85, 85, 82, 115, 82, 84,
-  89, 80, 82, 80, 80, 78, 78, 105, 75, 86,
-  80, 81, 68, 81, 117, 60, 65, 81, 81, 83,
-  90, 88, 65, 72, 112, 78, 83, 75, 81, 84,
-  81, 83, 135, 87, 67, 80, 81, 74, 83, 87,
-  86, 90, 76, 77, 84, 74, 80, 80, 82, 84,
-  85, 81, 78, 75, 77, 73, 93, 82, 77, 85,
-  76, 81, 86, 97, 72, 86, 100, 81, 88, 81,
-  74, 88, 88, 79, 86, 84, 74, 86, 82, 85,
-  84, 87, 77, 89, 80, 78, 94, 78, 80, 77,
-  87, 73, 80, 83, 76, 74, 83, 83, 79, 80,
-  92, 86, 78, 76, 82, 94, 76, 79, 89, 80,
-  79, 82, 63, 85, 80, 96, 73, 87, 75, 82,
-  96, 82, 80, 83, 84, 96, 77, 85, 86, 87,
-  81, 82, 82, 82, 85, 91, 72, 78, 76, 81,
-  70, 86, 103, 74, 85, 85, 81, 82, 88, 79,
-  79, 72, 88, 85, 83, 74, 76, 82, 76, 83,
-  129, 84, 72, 82, 75, 75, 84, 90, 82, 89,
-  76, 76, 91, 82, 83, 73, 83, 76, 85, 82,
-  81, 80, 90, 79, 84, 77, 84, 83, 82, 105,
-  83, 80, 93, 85, 92, 75, 81, 82, 88, 78,
-  84, 93, 83, 85, 83, 81, 80, 91, 82, 82,
-  87, 89, 74, 67, 97, 80, 77, 87, 83, 76,
-  86, 78, 86, 85, 87, 85, 93, 81, 85, 85,
-  77, 81, 80, 92, 85, 74, 81, 93, 79, 78,
-  63, 85, 86, 93, 76, 88, 84, 83, 101, 82,
-  97, 85, 83, 87, 77, 82, 76, 93, 78, 78,
-  81, 86, 81, 93, 79, 74, 85, 76, 75, 84,
-  94, 89, 73, 83, 79, 85, 84, 83, 81, 72,
-  92, 80, 86, 90, 72, 85, 80, 86, 139, 75,
-  70, 80, 73, 73, 86, 99, 90, 94, 81, 81,
-  95, 81, 86, 85, 85, 73, 84, 80, 80, 80,
-  88, 77, 82, 90, 82, 91, 80, 102, 73, 84,
-  108, 89, 103, 79, 81, 80, 88, 90, 93, 82,
-  84, 74, 80, 78, 74, 91, 80, 84, 82, 89,
-  76, 72, 97, 80, 77, 80, 89, 78, 84, 75,
-  91, 80, 88, 93, 74, 76, 86, 81, 78, 72,
-  82, 84, 91, 74, 82, 99, 75, 79, 57, 89,
-  85, 87, 84, 84, 82, 86, 103, 84, 92, 86,
-  83, 94, 79, 76, 84, 87, 77, 79, 78, 82,
-  75, 94, 77, 80, 83, 74, 74, 83, 108, 79,
-  70, 80, 82, 86, 93, 85, 77, 74, 95, 84,
-  84, 91, 78, 81, 92, 88, 101, 89, 77, 77,
-  76, 75, 88, 86, 84, 96, 75, 80, 89, 83,
-  86, 79, 81, 74, 86, 86, 78, 80, 89, 76,
-  84, 87, 83, 87, 81, 81, 76, 94, 96, 84,
-  96, 76, 82, 83, 80, 72, 85, 88, 85, 87,
-  80, 86, 81, 92, 84, 83, 90, 84, 89, 66,
-  87, 88, 84, 80, 80, 78, 75, 78, 81, 84,
-  83, 85, 79, 86, 90, 86, 78, 85, 85, 88,
-  75, 73, 78, 92, 82, 82, 68, 93, 81, 91,
-  77, 86, 86, 79, 96, 86, 79, 85, 83, 85,
-  83, 81, 72, 89, 77, 80, 84, 87, 79, 86,
-  81, 74, 87, 76, 78, 86, 84, 88, 91, 83,
-  83, 86, 91, 82, 86, 78, 82, 86, 89, 90,
-  97, 89, 68, 94, 98, 81, 70, 98, 74, 89,
-  102, 91, 100, 77, 76, 82, 84, 87, 99, 75,
-  83, 83, 83, 78, 72, 87, 88, 105, 97, 77,
-  91, 102, 68, 94, 73, 96, 94, 100, 88, 80,
-  90, 82, 74, 80, 78, 65, 72, 84, 81, 71,
-  72, 85, 71, 83, 92, 96, 74, 80, 77, 105,
-  79, 84, 80, 97, 78, 72, 70, 82, 70, 91,
-  95, 76, 76, 96, 71, 85, 89, 100, 94, 90,
-  84, 89, 62, 82, 85, 75, 87, 89, 79, 75,
-  81, 89, 79, 88, 98, 80, 96, 81, 74, 70,
-  73, 77, 86, 93, 86, 103, 71, 96, 68, 78,
-  78, 67, 81, 90, 87, 88, 79, 76, 82, 89,
-  98, 74, 82, 86, 81, 96, 98, 86, 93, 88,
-  81, 91, 92, 85, 74, 95, 70, 87, 107, 90,
-  106, 84, 82, 79, 91, 91, 107, 79, 73, 80,
-  90, 77, 74, 84, 82, 101, 82, 74, 98, 108,
-  69, 93, 68, 89, 86, 96, 83, 78, 90, 79,
-  84, 81, 77, 70, 70, 80, 77, 72, 73, 94,
-  72, 85, 87, 78, 73, 81, 66, 120, 80, 81,
-  81, 101, 68, 64, 72, 88, 66, 84, 75, 69,
-  68, 100, 72, 85, 93, 91, 87, 91, 81, 89,
-  66, 84, 87, 79, 88, 89, 67, 77, 77, 90,
-  76, 86, 93, 82, 95, 85, 68, 71, 77, 84,
-  84, 93, 79, 90, 75, 96, 72, 80, 84, 73,
-  80, 91, 87, 78, 76, 73, 83, 84, 90, 75,
-  80, 88, 80, 98, 97, 85, 86, 80, 86, 91,
-  91, 90, 72, 93, 72, 92, 97, 90, 95, 92,
-  71, 83, 81, 82, 94, 79, 69, 88, 90, 81,
-  73, 87, 85, 101, 94, 78, 96, 113, 75, 91,
-  73, 101, 107, 99, 85, 81, 90, 81, 85, 81,
-  79, 69, 76, 87, 82, 69, 71, 100, 77, 79,
-  87, 71, 83, 80, 73, 98, 80, 87, 90, 91,
-  78, 76, 64, 78, 79, 94, 68, 73, 79, 89,
-  75, 90, 83, 89, 90, 89, 84, 88, 72, 87,
-  88, 77, 85, 88, 81, 77, 80, 84, 75, 84,
-  92, 80, 94, 82, 75, 80, 78, 77, 87, 90,
-  81, 100, 71, 92, 68, 78, 82, 70, 80, 93,
-  90, 85, 81, 78, 86, 90, 88, 76, 82, 82,
-  83, 94, 97, 86, 83, 88, 89, 86, 81, 84,
-  72, 87, 86, 84, 81, 99, 87, 85, 71, 74,
-  79, 70, 70, 73, 79, 88, 86, 81, 83, 83,
-  84, 87, 101, 85, 82, 90, 79, 78, 79, 88,
-  98, 83, 84, 75, 69, 80, 86, 82, 70, 79,
-  75, 83, 89, 79, 80, 88, 86, 78, 104, 91,
-  91, 82, 111, 84, 69, 78, 61, 79, 72, 77,
-  62, 76, 92, 80, 86, 77, 78, 75, 72, 85,
-  76, 104, 98, 85, 84, 92, 70, 75, 82, 94,
-  85, 82, 81, 82, 83, 81, 108, 78, 91, 76,
-  90, 65, 89, 67, 85, 70, 69, 92, 80, 136,
-  76, 89, 80, 81, 81, 53, 68, 85, 106, 102,
-  64, 87, 78, 87, 82, 88, 90, 65, 91, 99,
-  81, 71, 77, 86, 96, 81, 78, 88, 74, 85,
-  85, 83, 79, 90, 92, 93, 75, 72, 77, 70,
-  67, 76, 81, 90, 86, 79, 79, 85, 85, 85,
-  86, 87, 90, 96, 81, 84, 74, 75, 94, 81,
-  84, 76, 73, 89, 85, 85, 72, 71, 78, 86,
-  87, 79, 80, 109, 87, 76, 98, 106, 90, 81,
-  106, 89, 68, 75, 59, 78, 81, 74, 63, 78,
-  89, 77, 96, 75, 71, 77, 73, 85, 80, 87,
-  103, 86, 80, 91, 75, 75, 82, 103, 81, 86,
-  86, 78, 86, 79, 106, 78, 83, 79, 86, 69,
-  89, 69, 90, 73, 65, 93, 87, 138, 71, 90,
-  82, 78, 85, 60, 68, 80, 106, 91, 73, 84,
-  82, 95, 79, 88, 90, 60, 90, 98, 79, 69,
-  78, 85, 81, 86, 83, 86, 73, 80, 84, 88,
-  81, 88, 89, 87, 73, 72, 77, 71, 70, 75,
-  84, 81, 88, 88, 78, 88, 84, 88, 91, 85,
-  88, 93, 75, 84, 70, 84, 106, 84, 76, 75,
-  70, 84, 81, 80, 73, 67, 83, 101, 89, 79,
-  81, 84, 89, 80, 96, 90, 97, 81, 104, 83,
-  72, 83, 68, 80, 70, 74, 69, 77, 83, 80,
-  76, 76, 80, 75, 77, 88, 76, 81, 97, 85,
-  87, 87, 74, 87, 85, 99, 79, 79, 80, 82,
-  81, 79, 100, 80, 88, 80, 88, 72, 89, 71,
-  81, 72, 75, 90, 81, 127, 73, 83, 87, 77,
-  72, 60, 71, 87, 83, 91, 85, 89, 83, 84,
-  80, 83, 93, 71, 90, 90, 80, 79, 76, 86,
-  94, 82, 79, 90, 75, 76, 86, 85, 73, 80,
-  91, 92, 83, 81, 83, 85, 55, 75, 96, 88,
-  80, 89, 86, 91, 83, 82, 89, 84, 95, 76,
-  97, 79, 91, 88, 87, 80, 82, 83, 73, 78,
-  97, 87, 83, 88, 88, 87, 88, 92, 75, 94,
-  88, 82, 107, 70, 91, 72, 100, 87, 78, 101,
-  84, 75, 86, 76, 90, 84, 90, 81, 77, 76,
-  91, 77, 75, 85, 67, 88, 78, 79, 86, 79,
-  89, 82, 82, 82, 81, 72, 77, 90, 84, 89,
-  106, 85, 80, 88, 75, 74, 96, 79, 75, 85,
-  79, 92, 81, 106, 90, 87, 84, 76, 76, 79,
-  76, 85, 85, 87, 80, 92, 92, 91, 80, 80,
-  97, 67, 93, 86, 78, 86, 73, 87, 85, 81,
-  80, 78, 74, 77, 89, 88, 77, 75, 99, 88,
-  84, 85, 86, 86, 53, 76, 104, 82, 84, 90,
-  86, 91, 82, 81, 89, 87, 98, 73, 98, 76,
-  87, 78, 84, 87, 93, 80, 75, 80, 100, 91,
-  83, 94, 87, 86, 84, 91, 74, 90, 91, 82,
-  104, 81, 95, 70, 97, 90, 79, 102, 86, 77,
-  79, 77, 91, 88, 83, 81, 83, 72, 90, 80,
-  71, 79, 71, 81, 73, 81, 82, 77, 92, 87,
-  81, 86, 79, 73, 72, 89, 85, 86, 96, 86,
-  79, 86, 75, 77, 100, 81, 75, 81, 80, 94,
-  76, 93, 84, 87, 88, 73, 75, 82, 79, 76,
-  83, 86, 84, 90, 95, 96, 77, 81, 101, 67,
-  91, 83, 80, 86, 84, 84, 82, 84, 80, 72,
-  77, 71, 87, 87, 77, 81, 95, 82, 81, 82,
-  77, 84, 63, 77, 98, 82, 95, 89, 81, 89,
-  82, 82, 88, 89, 89, 71, 96, 79, 86, 85,
-  89, 80, 91, 81, 75, 77, 89, 90, 86, 84,
-  92, 90, 87, 90, 79, 81, 88, 87, 100, 84,
-  88, 78, 98, 86, 78, 94, 85, 77, 87, 82,
-  91, 82, 80, 86, 87, 80, 88, 76, 75, 82,
-  71, 85, 74, 77, 89, 78, 91, 93, 85, 86,
-  80, 73, 80, 84, 87, 81, 106, 86, 79, 92,
-  77, 77, 100, 75, 82, 74, 84, 89, 77, 100,
-  90, 83, 83, 74, 76, 78, 74, 80, 81, 85,
-  98, 89, 88, 83, 78, 82, 96, 72, 92, 83,
-  76, 87, 93, 83, 77, 95, 81, 91, 86, 78,
-  73, 105, 94, 85, 82, 81, 80, 80, 91, 90,
-  74, 76, 80, 78, 84, 72, 85, 80, 88, 84,
-  93, 88, 78, 90, 96, 79, 72, 85, 72, 70,
-  82, 78, 82, 94, 73, 88, 78, 80, 68, 85,
-  78, 97, 77, 80, 80, 82, 95, 79, 77, 89,
-  78, 80, 84, 89, 79, 89, 84, 81, 67, 73,
-  89, 82, 79, 94, 82, 79, 80, 106, 83, 81,
-  90, 86, 69, 82, 87, 85, 83, 100, 91, 99,
-  84, 85, 79, 85, 110, 83, 71, 81, 92, 84,
-  74, 78, 75, 74, 73, 77, 84, 84, 86, 86,
-  89, 102, 85, 88, 82, 80, 78, 78, 91, 81,
-  71, 81, 96, 80, 86, 74, 87, 99, 82, 91,
-  85, 85, 78, 88, 78, 90, 83, 82, 74, 115,
-  89, 80, 82, 81, 71, 80, 95, 83, 76, 78,
-  74, 76, 86, 75, 85, 74, 90, 86, 89, 83,
-  76, 87, 94, 81, 79, 84, 76, 72, 79, 83,
-  78, 94, 73, 86, 74, 70, 70, 87, 75, 99,
-  78, 79, 73, 79, 101, 79, 77, 86, 86, 86,
-  78, 88, 80, 86, 84, 75, 67, 83, 95, 77,
-  79, 95, 84, 77, 81, 107, 84, 84, 92, 87,
-  67, 78, 86, 90, 85, 100, 86, 105, 85, 89,
-  77, 90, 115, 79, 73, 71, 92, 78, 76, 79,
-  79, 81, 77, 76, 82, 87, 91, 88, 83, 100,
-  89, 88, 84, 87, 75, 81, 81, 83, 76, 76,
-  88, 81, 86, 74, 98, 95, 84, 96, 91, 85,
-  80, 92, 82, 82, 83, 81, 75, 100, 94, 83,
-  81, 78, 80, 79, 92, 91, 76, 79, 74, 81,
-  93, 75, 89, 81, 90, 87, 91, 80, 81, 93,
-  96, 87, 81, 76, 77, 75, 77, 79, 81, 94,
-  81, 92, 73, 80, 72, 87, 81, 93, 73, 76,
-  84, 83, 97, 74, 80, 84, 79, 84, 86, 87,
-  81, 89, 90, 79, 66, 77, 88, 81, 88, 89,
-  84, 79, 80, 99, 80, 90, 95, 86, 64, 87,
-  87, 93, 82, 94, 85, 93, 85, 90, 81, 83,
-  106, 88, 74, 81, 90, 85, 79, 79, 77, 85,
-  74, 78, 81, 84, 85, 86, 90, 101, 89, 89,
-  87, 93, 78, 77, 79, 84, 72, 82, 80, 85,
-  83, 77, 88, 92, 81, 87, 88, 80, 80, 83,
-  82, 86, 85, 81, 78, 119, 95, 85, 79, 80,
-  73, 80, 93, 92, 69, 83, 71, 87, 77, 75,
-  87, 76, 85, 84, 87, 84, 75, 85, 91, 77,
-  81, 88, 76, 78, 84, 69, 85, 100, 77, 83,
-  80, 81, 69, 82, 77, 105, 73, 78, 76, 85,
-  101, 85, 78, 97, 92, 78, 83, 88, 80, 89,
-  80, 85, 70, 84, 82, 81, 81, 101, 79, 85,
-  76, 114, 75, 86, 81, 80, 75, 76, 87, 91,
-  91, 85, 89, 96, 81, 79, 71, 90, 109, 77,
-  79, 81, 83, 87, 77, 81, 77, 74, 86, 75,
-  81, 94, 87, 84, 88, 108, 76, 84, 83, 82,
-  86, 79, 85, 77, 79, 80, 93, 82, 88, 81,
-  98, 78, 94, 88, 85, 79, 77, 73, 77, 82,
-  84, 85, 84, 140, 98, 86, 76, 82, 64, 77,
-  90, 77, 70, 86, 70, 99, 81, 82, 85, 69,
-  85, 86, 81, 83, 72, 80, 86, 83, 83, 93,
-  83, 82, 84, 69, 95, 114, 65, 76, 80, 70,
-  61, 84, 76, 126, 73, 83, 68, 80, 117, 85,
-  80, 99, 113, 87, 78, 90, 83, 91, 82, 85,
-  65, 98, 78, 80, 73, 125, 79, 79, 75, 127,
-  78, 84, 77, 83, 71, 71, 80, 92, 97, 79,
-  81, 109, 84, 80, 70, 86, 128, 66, 81, 75,
-  85, 82, 77, 83, 80, 86, 101, 76, 82, 102,
-  88, 86, 86, 109, 83, 78, 85, 85, 85, 88,
-  76, 77, 87, 78, 83, 90, 86, 84, 111, 74,
-  98, 101, 92, 84, 81, 82, 85, 75, 81, 84,
-  78, 111, 97, 83, 79, 81, 75, 78, 90, 95,
-  72, 83, 78, 86, 90, 79, 86, 77, 84, 88,
-  83, 86, 80, 87, 95, 85, 77, 85, 77, 78,
-  81, 69, 87, 98, 71, 87, 78, 82, 67, 90,
-  80, 100, 70, 78, 83, 83, 105, 81, 79, 94,
-  84, 80, 83, 84, 81, 88, 85, 86, 68, 83,
-  84, 82, 80, 98, 79, 84, 81, 105, 76, 89,
-  84, 82, 70, 81, 87, 97, 89, 82, 87, 93,
-  83, 85, 78, 86, 101, 83, 79, 85, 81, 90,
-  87, 83, 80, 87, 85, 78, 81, 90, 84, 85,
-  87, 102, 82, 84, 86, 94, 87, 81, 80, 79,
-  78, 80, 80, 83, 83, 79, 103, 76, 91, 84,
-  85, 81, 78, 84, 76, 91, 87, 84, 77, 103,
-  94, 82, 83, 83, 80, 76, 88, 96, 64, 79,
-  74, 76, 79, 74, 84, 80, 92, 84, 92, 83,
-  78, 90, 91, 72, 80, 89, 77, 79, 81, 76,
-  83, 99, 76, 82, 82, 79, 77, 94, 77, 102,
-  79, 73, 83, 86, 88, 84, 80, 83, 84, 75,
-  86, 93, 84, 86, 83, 89, 72, 78, 79, 84,
-  83, 96, 78, 97, 79, 103, 78, 85, 74, 86,
-  72, 83, 91, 80, 89, 84, 89, 87, 78, 83,
-  73, 99, 108, 82, 78, 87, 83, 90, 80, 79,
-  77, 81, 78, 76, 74, 85, 78, 83, 84, 99,
-  72, 93, 87, 81, 83, 84, 81, 84, 76, 74,
-  92, 81, 91, 79, 82, 81, 87, 87, 81, 78,
-  85, 79, 73, 80, 88, 86, 85, 112, 97, 85,
-  83, 79, 71, 76, 82, 89, 64, 80, 74, 83,
-  84, 79, 80, 76, 93, 84, 85, 82, 71, 87,
-  94, 73, 83, 86, 78, 82, 82, 74, 88, 98,
-  75, 81, 86, 72, 70, 86, 74, 110, 76, 74,
-  78, 84, 106, 85, 81, 83, 90, 76, 82, 100,
-  88, 87, 89, 91, 69, 76, 76, 90, 79, 103,
-  82, 94, 74, 106, 80, 86, 72, 87, 71, 75,
-  86, 85, 89, 80, 79, 93, 81, 81, 72, 90,
-  113, 74, 80, 87, 86, 86, 76, 84, 83, 80,
-  83, 78, 74, 83, 74, 84, 84, 96, 78, 89,
-  87, 82, 84, 85, 80, 80, 78, 78, 85, 79,
-  88, 82, 96, 81, 95, 93, 91, 80, 83, 84,
-  76, 74, 87, 85, 77, 97, 94, 81, 83, 80,
-  85, 74, 83, 99, 67, 82, 72, 77, 93, 75,
-  85, 80, 88, 88, 88, 82, 77, 91, 92, 82,
-  76, 81, 78, 79, 83, 76, 79, 92, 75, 84,
-  81, 76, 77, 85, 80, 99, 75, 69, 85, 85,
-  92, 83, 80, 83, 76, 80, 88, 93, 84, 87,
-  85, 93, 73, 78, 78, 85, 78, 96, 80, 95,
-  81, 95, 77, 95, 77, 87, 67, 86, 87, 98,
-  89, 88, 82, 88, 79, 84, 76, 92, 102, 88,
-  83, 91, 81, 93, 87, 81, 78, 81, 79, 81,
-  76, 83, 80, 84, 86, 96, 74, 91, 87, 90,
-  86, 85, 85, 87, 74, 74, 83, 83, 84, 75,
-  86, 82, 85, 87, 90, 89, 84, 101, 71, 72,
-  94, 76, 73, 92, 89, 81, 77, 61, 85, 79,
-  85, 82, 105, 89, 54, 86, 96, 99, 94, 86,
-  99, 97, 99, 82, 100, 93, 83, 78, 74, 93,
-  88, 77, 86, 79, 80, 77, 72, 89, 70, 90,
-  119, 87, 68, 88, 89, 83, 92, 93, 92, 77,
-  88, 91, 95, 72, 78, 74, 105, 81, 84, 61,
-  93, 74, 88, 99, 75, 93, 82, 69, 96, 86,
-  80, 76, 83, 78, 103, 85, 65, 69, 78, 81,
-  83, 80, 88, 72, 76, 79, 72, 90, 78, 68,
-  91, 78, 71, 74, 85, 75, 101, 67, 104, 71,
-  93, 76, 88, 89, 82, 84, 92, 85, 84, 75,
-  91, 69, 75, 67, 109, 89, 73, 75, 84, 86,
-  97, 100, 92, 85, 69, 102, 69, 72, 96, 75,
-  62, 83, 81, 63, 82, 77, 88, 75, 82, 76,
-  102, 83, 49, 74, 69, 112, 82, 83, 120, 95,
-  96, 81, 101, 96, 84, 80, 71, 78, 88, 79,
-  68, 70, 76, 86, 51, 78, 61, 91, 146, 78,
-  76, 82, 88, 81, 98, 90, 97, 84, 94, 92,
-  97, 66, 88, 72, 109, 94, 80, 64, 99, 67,
-  98, 105, 76, 87, 70, 62, 110, 85, 73, 76,
-  96, 77, 98, 69, 70, 82, 77, 75, 78, 65,
-  94, 76, 82, 72, 73, 101, 74, 64, 102, 77,
-  102, 79, 87, 76, 93, 71, 118, 82, 98, 78,
-  87, 84, 71, 92, 94, 76, 82, 71, 79, 73,
-  83, 55, 94, 78, 69, 76, 83, 85, 95, 95,
-  80, 88, 69, 100, 78, 95, 95, 77, 70, 96,
-  89, 82, 74, 90, 85, 77, 82, 76, 101, 77,
-  76, 83, 72, 102, 71, 92, 103, 98, 89, 78,
-  98, 91, 81, 94, 77, 82, 90, 77, 57, 79,
-  80, 78, 64, 83, 72, 83, 102, 71, 66, 88,
-  86, 76, 91, 96, 93, 86, 85, 94, 91, 72,
-  88, 77, 110, 86, 83, 68, 93, 80, 86, 85,
-  90, 84, 78, 76, 100, 90, 80, 86, 96, 79,
-  103, 85, 77, 99, 81, 79, 93, 75, 90, 84,
-  82, 75, 69, 92, 94, 75, 92, 80, 92, 78,
-  95, 81, 91, 66, 103, 71, 91, 74, 90, 84,
-  74, 88, 90, 94, 67, 73, 77, 77, 78, 72,
-  71, 87, 73, 78, 86, 81, 98, 98, 103, 79,
-  101, 93, 64, 76, 92, 79, 71, 85, 84, 88,
-  100, 84, 85, 67, 88, 75, 74, 79, 60, 98,
-  74, 97, 96, 92, 86, 86, 87, 84, 93, 96,
-  95, 85, 78, 85, 81, 86, 72, 78, 76, 85,
-  104, 85, 93, 101, 85, 88, 74, 86, 76, 84,
-  94, 80, 86, 61, 79, 82, 84, 86, 68, 83,
-  85, 73, 85, 70, 108, 77, 91, 88, 74, 90,
-  78, 79, 79, 85, 81, 95, 78, 85, 90, 88,
-  75, 70, 84, 81, 81, 78, 77, 71, 82, 72,
-  72, 112, 70, 79, 79, 91, 62, 81, 77, 78,
-  90, 70, 94, 98, 80, 88, 81, 82, 76, 70,
-  91, 79, 73, 88, 96, 87, 87, 65, 93, 81,
-  66, 86, 89, 81, 101, 85, 89, 98, 67, 85,
-  59, 71, 100, 76, 64, 72, 76, 70, 83, 70,
-  87, 69, 78, 63, 67, 82, 81, 78, 66, 110,
-  86, 101, 83, 83, 77, 77, 90, 92, 96, 79,
-  72, 69, 73, 102, 74, 68, 75, 91, 79, 76,
-  101, 97, 81, 91, 78, 80, 81, 64, 93, 81,
-  85, 68, 85, 77, 97, 97, 73, 81, 83, 79,
-  79, 64, 126, 88, 93, 81, 62, 84, 71, 80,
-  85, 93, 82, 88, 87, 82, 82, 82, 73, 78,
-  86, 83, 74, 70, 69, 75, 79, 76, 92, 137,
-  67, 83, 82, 91, 94, 91, 78, 98, 82, 76,
-  97, 104, 87, 92, 74, 78, 64, 73, 88, 71,
-  62, 95, 70, 110, 94, 62, 84, 71, 60, 90,
-  86, 77, 104, 87, 97, 101, 72, 96, 65, 86,
-  94, 79, 69, 85, 82, 91, 90, 73, 86, 71,
-  81, 67, 72, 76, 100, 91, 80, 97, 71, 92,
-  94, 82, 83, 79, 93, 96, 93, 87, 79, 81,
-  85, 87, 84, 79, 76, 87, 62, 86, 101, 96,
-  79, 95, 75, 91, 77, 78, 94, 84, 88, 89,
-  78, 86, 87, 83, 77, 80, 86, 78, 83, 75,
-  93, 83, 92, 79, 99, 89, 71, 83, 85, 84,
-  82, 86, 86, 81, 94, 88, 85, 88, 84, 80,
-  84, 75, 76, 74, 83, 73, 75, 107, 77, 81,
-  81, 90, 106, 79, 81, 93, 87, 69, 94, 96,
-  80, 82, 82, 77, 67, 74, 88, 86, 60, 78,
-  73, 86, 83, 66, 71, 81, 70, 86, 89, 74,
-  96, 87, 92, 79, 86, 92, 92, 70, 85, 88,
-  85, 86, 83, 94, 98, 82, 75, 63, 76, 71,
-  78, 82, 90, 91, 82, 89, 85, 87, 85, 76,
-  83, 88, 77, 84, 89, 83, 88, 86, 90, 78,
-  80, 86, 66, 97, 89, 93, 89, 92, 75, 93,
-  80, 97, 73, 86, 83, 81, 82, 83, 77, 90,
-  87, 89, 68, 89, 81, 74, 85, 83, 98, 89,
-  85, 86, 86, 86, 87, 86, 78, 92, 87, 96,
-  89, 86, 88, 91, 86, 79, 82, 83, 87, 90,
-  79, 86, 83, 76, 78, 96, 78, 94, 73, 81,
-  79, 83, 78, 91, 78, 68, 72, 98, 81, 90,
-  88, 78, 83, 86, 82, 77, 78, 79, 92, 91,
-  86, 89, 79, 83, 74, 85, 102, 85, 96, 73,
-  92, 84, 78, 88, 91, 83, 81, 88, 82, 79,
-  76, 80, 84, 82, 74, 63, 72, 73, 78, 83,
-  105, 80, 81, 79, 84, 97, 78, 72, 80, 82,
-  81, 88, 95, 82, 71, 79, 79, 78, 82, 81,
-  69, 92, 96, 94, 96, 80, 66, 90, 76, 91,
-  73, 77, 74, 81, 81, 78, 78, 86, 90, 87,
-  76, 85, 87, 69, 83, 75, 94, 92, 83, 87,
-  81, 79, 79, 93, 63, 87, 91, 93, 82, 80,
-  80, 84, 92, 85, 85, 89, 77, 90, 82, 85,
-  84, 81, 80, 102, 83, 101, 74, 79, 78, 79,
-  78, 103, 79, 73, 62, 92, 88, 94, 83, 69,
-  85, 95, 80, 79, 79, 88, 82, 102, 87, 99,
-  80, 76, 75, 91, 97, 83, 99, 71, 90, 91,
-  79, 88, 89, 89, 86, 86, 84, 85, 84, 94,
-  95, 77, 78, 68, 72, 70, 79, 79, 99, 93,
-  76, 82, 82, 84, 87, 75, 76, 93, 80, 90,
-  88, 83, 88, 86, 86, 84, 80, 86, 67, 92,
-  82, 93, 93, 83, 74, 88, 82, 101, 72, 85,
-  79, 83, 77, 74, 81, 91, 87, 90, 73, 94,
-  86, 73, 85, 85, 86, 91, 86, 87, 86, 89,
-  83, 90, 72, 90, 86, 91, 88, 83, 87, 91,
-  87, 91, 83, 87, 77, 89, 82, 82, 88, 78,
-  78, 96, 79, 87, 76, 86, 90, 80, 79, 91,
-  80, 68, 76, 98, 88, 88, 84, 77, 82, 86,
-  82, 87, 83, 78, 88, 91, 90, 94, 82, 85,
-  75, 86, 99, 79, 94, 74, 89, 76, 84, 79,
-  74, 89, 94, 82, 88, 74, 88, 83, 86, 73,
-  78, 74, 106, 99, 88, 74, 88, 84, 89, 76,
-  82, 92, 81, 69, 87, 77, 81, 81, 101, 82,
-  85, 94, 91, 72, 90, 72, 75, 104, 83, 80,
-  89, 81, 71, 90, 91, 93, 90, 81, 74, 92,
-  69, 83, 90, 85, 82, 84, 81, 92, 79, 88,
-  92, 97, 90, 73, 86, 76, 81, 86, 98, 80,
-  70, 95, 85, 85, 69, 92, 92, 89, 81, 72,
-  95, 90, 94, 70, 85, 59, 76, 90, 81, 81,
-  84, 95, 83, 76, 80, 85, 81, 88, 79, 85,
-  78, 73, 90, 87, 69, 79, 86, 77, 83, 72,
-  86, 83, 79, 78, 77, 80, 75, 76, 80, 85,
-  71, 84, 91, 87, 91, 78, 84, 78, 87, 71,
-  96, 74, 82, 76, 86, 85, 95, 84, 72, 72,
-  110, 93, 80, 76, 88, 87, 76, 89, 86, 90,
-  81, 65, 85, 83, 83, 86, 96, 87, 91, 86,
-  92, 68, 90, 79, 78, 113, 88, 77, 97, 88,
-  76, 87, 97, 96, 86, 90, 70, 91, 72, 88,
-  89, 84, 80, 89, 81, 98, 81, 90, 74, 108,
-  89, 80, 95, 77, 81, 91, 96, 63, 71, 87,
-  93, 83, 70, 98, 89, 88, 84, 78, 100, 96,
-  78, 69, 86, 69, 74, 75, 78, 87, 82, 96,
-  88, 73, 85, 91, 69, 88, 78, 87, 82, 76,
-  90, 88, 77, 73, 89, 78, 87, 79, 89, 83,
-  80, 90, 81, 88, 70, 77, 66, 84, 70, 88,
-  91, 92, 86, 80, 84, 83, 74, 81, 93, 76,
-  85, 77, 82, 86, 81, 84, 79, 77, 105, 99,
-  84, 77, 85, 88, 92, 77, 84, 94, 79, 76,
-  83, 77, 80, 87, 99, 83, 85, 88, 85, 82,
-  83, 76, 78, 100, 85, 83, 89, 79, 75, 83,
-  90, 88, 87, 80, 71, 94, 73, 81, 88, 85,
-  84, 84, 85, 91, 84, 93, 95, 95, 86, 77,
-  86, 76, 81, 88, 95, 73, 73, 88, 86, 86,
-  64, 86, 91, 92, 81, 88, 93, 99, 72, 71,
-  87, 65, 80, 79, 75, 87, 83, 93, 84, 79,
-  82, 82, 84, 85, 81, 86, 80, 75, 93, 88,
-  71, 74, 82, 78, 81, 85, 85, 89, 81, 81,
-  77, 82, 69, 78, 79, 84, 68, 79, 89, 91,
-  82, 83, 76, 78, 81, 92, 92, 93, 89, 68,
-  91, 87, 84, 84, 90, 65, 102, 88, 89, 71,
-  83, 81, 75, 70, 75, 88, 78, 77, 87, 83,
-  91, 76, 99, 75, 85, 92, 77, 93, 86, 89,
-  85, 74, 81, 81, 82, 89, 62, 82, 91, 91,
-  93, 84, 71, 83, 68, 88, 89, 85, 77, 83,
-  83, 89, 79, 87, 92, 89, 89, 76, 81, 77,
-  85, 80, 99, 86, 70, 101, 79, 82, 81, 91,
-  80, 85, 73, 69, 81, 92, 91, 69, 86, 80,
-  79, 117, 78, 89, 88, 94, 76, 91, 79, 89,
-  78, 89, 77, 82, 75, 83, 85, 78, 76, 86,
-  82, 74, 87, 69, 73, 81, 75, 83, 88, 76,
-  90, 77, 80, 98, 71, 79, 90, 82, 86, 88,
-  79, 74, 82, 67, 98, 92, 83, 62, 95, 86,
-  103, 90, 78, 62, 112, 71, 81, 74, 82, 84,
-  67, 79, 82, 92, 72, 72, 82, 88, 99, 86,
-  100, 81, 84, 76, 82, 96, 102, 91, 92, 68,
-  83, 74, 85, 97, 64, 85, 103, 94, 94, 94,
-  72, 77, 66, 88, 93, 83, 77, 92, 83, 93,
-  82, 86, 57, 94, 93, 82, 82, 66, 75, 85,
-  94, 72, 69, 91, 81, 87, 78, 103, 76, 87,
-  77, 78, 83, 109, 73, 63, 83, 85, 76, 80,
-  70, 108, 76, 96, 79, 95, 77, 102, 48, 78,
-  72, 81, 76, 84, 87, 75, 77, 78, 91, 71,
-  91, 69, 76, 86, 73, 90, 94, 80, 82, 79,
-  76, 100, 68, 78, 94, 87, 76, 89, 94, 89,
-  80, 74, 91, 85, 92, 72, 86, 83, 84, 87,
-  90, 68, 95, 88, 88, 82, 84, 86, 94, 72,
-  84, 89, 79, 81, 77, 86, 86, 83, 94, 76,
-  78, 82, 72, 107, 93, 86, 89, 75, 82, 85,
-  83, 84, 70, 81, 90, 92, 90, 86, 75, 85,
-  72, 85, 83, 85, 77, 82, 87, 88, 84, 90,
-  105, 85, 88, 79, 76, 94, 76, 82, 94, 84,
-  73, 88, 81, 84, 74, 85, 84, 86, 74, 98,
-  80, 109, 71, 75, 87, 84, 83, 95, 73, 89,
-  86, 96, 75, 91, 72, 86, 83, 77, 75, 83,
-  73, 85, 89, 80, 73, 81, 81, 71, 82, 83,
-  79, 86, 83, 80, 86, 80, 78, 79, 78, 93,
-  72, 78, 93, 87, 75, 83, 86, 102, 90, 101,
-  86, 89, 96, 78, 84, 91, 78, 93, 80, 97,
-  86, 88, 94, 94, 84, 91, 72, 64, 75, 80,
-  80, 92, 95, 82, 91, 84, 82, 71, 70, 100,
-  73, 102, 72, 82, 91, 69, 77, 94, 65, 77,
-  74, 76, 72, 85, 88, 75, 72, 74, 74, 83,
-  77, 81, 89, 84, 77, 73, 97, 71, 122, 63,
-  99, 88, 74, 115, 111, 77, 92, 110, 76, 92,
-  75, 85, 97, 75, 85, 76, 76, 81, 81, 93,
-  93, 100, 78, 86, 84, 147, 76, 87, 83, 79,
-  82, 78, 69, 70, 98, 93, 90, 83, 80, 99,
-  78, 93, 75, 84, 80, 68, 76, 86, 92, 85,
-  86, 79, 82, 76, 80, 69, 100, 98, 78, 73,
-  80, 75, 69, 81, 97, 97, 77, 88, 80, 102,
-  95, 83, 86, 91, 77, 92, 76, 87, 88, 84,
-  91, 91, 80, 83, 92, 60, 79, 82, 72, 97,
-  72, 81, 91, 86, 89, 77, 70, 86, 79, 114,
-  87, 80, 91, 69, 77, 85, 57, 73, 75, 79,
-  73, 89, 89, 78, 74, 69, 74, 83, 81, 76,
-  87, 91, 84, 70, 101, 59, 96, 57, 84, 82,
-  67, 112, 92, 77, 94, 113, 72, 94, 74, 91,
-  91, 82, 81, 74, 72, 99, 69, 105, 92, 98,
-  72, 92, 83, 136, 65, 94, 77, 71, 85, 79,
-  72, 77, 96, 88, 81, 83, 69, 95, 84, 86,
-  74, 86, 79, 65, 77, 82, 84, 87, 89, 78,
-  90, 72, 86, 70, 102, 102, 78, 75, 85, 75,
-  77, 76, 91, 98, 87, 69, 84, 91, 93, 82,
-  83, 93, 77, 90, 86, 92, 79, 88, 100, 92,
-  84, 96, 109, 64, 81, 81, 84, 91, 84, 82,
-  86, 83, 87, 76, 66, 85, 74, 100, 96, 81,
-  89, 72, 80, 95, 70, 75, 73, 78, 75, 89,
-  85, 76, 76, 78, 76, 83, 74, 82, 87, 88,
-  80, 79, 101, 74, 114, 67, 83, 85, 73, 121,
-  77, 75, 88, 113, 74, 89, 81, 85, 83, 76,
-  88, 76, 80, 102, 81, 101, 92, 104, 76, 83,
-  82, 132, 75, 82, 82, 83, 80, 78, 77, 65,
-  95, 82, 91, 85, 82, 98, 80, 95, 80, 81,
-  77, 66, 71, 83, 82, 88, 88, 75, 81, 77,
-  78, 76, 95, 92, 81, 83, 83, 79, 100, 62,
-  85, 49, 84, 68, 74, 66, 71, 55, 79, 87,
-  72, 91, 96, 81, 72, 71, 82, 86, 79, 82,
-  91, 76, 66, 65, 71, 83, 82, 82, 59, 88,
-  84, 75, 94, 105, 88, 132, 94, 72, 70, 62,
-  81, 62, 92, 71, 83, 82, 53, 67, 99, 79,
-  71, 77, 76, 83, 54, 70, 86, 129, 91, 68,
-  100, 87, 78, 87, 81, 88, 77, 73, 80, 111,
-  92, 94, 77, 93, 77, 92, 81, 67, 86, 74,
-  80, 92, 106, 74, 67, 119, 66, 92, 80, 85,
-  88, 72, 87, 72, 79, 71, 79, 97, 86, 84,
-  160, 92, 119, 75, 83, 86, 78, 84, 88, 85,
-  62, 86, 91, 96, 77, 111, 141, 77, 78, 66,
-  71, 63, 103, 73, 144, 57, 93, 92, 73, 58,
-  87, 86, 76, 64, 70, 39, 74, 88, 68, 100,
-  95, 81, 76, 71, 75, 79, 73, 83, 65, 80,
-  74, 73, 73, 84, 99, 95, 64, 82, 84, 73,
-  83, 105, 83, 123, 87, 76, 66, 70, 81, 65,
-  92, 82, 80, 92, 59, 68, 93, 74, 76, 80,
-  75, 86, 57, 69, 83, 109, 93, 73, 98, 85,
-  69, 90, 74, 83, 76, 70, 82, 105, 86, 90,
-  76, 88, 85, 75, 78, 69, 89, 70, 80, 81,
-  103, 74, 77, 110, 64, 86, 77, 94, 92, 72,
-  85, 69, 86, 77, 81, 90, 77, 91, 145, 91,
-  116, 77, 89, 84, 71, 84, 83, 89, 65, 66,
-  88, 95, 86, 106, 132, 77, 94, 65, 72, 67,
-  92, 78, 130, 62, 81, 93, 89, 68, 87, 89,
-  85, 96, 73, 70, 100, 85, 85, 88, 78, 90,
-  79, 69, 93, 94, 79, 84, 71, 85, 89, 78,
-  84, 82, 88, 88, 96, 91, 82, 93, 76, 93,
-  86, 87, 81, 86, 92, 80, 80, 86, 85, 96,
-  92, 82, 97, 79, 86, 86, 81, 87, 95, 87,
-  91, 81, 88, 87, 78, 86, 93, 61, 79, 78,
-  72, 84, 88, 86, 87, 86, 78, 89, 83, 87,
-  92, 76, 75, 76, 85, 84, 97, 79, 80, 72,
-  105, 77, 77, 93, 101, 95, 93, 87, 83, 88,
-  85, 75, 96, 89, 76, 78, 74, 87, 71, 91,
-  78, 86, 79, 88, 86, 78, 98, 67, 88, 88,
-  88, 72, 77, 88, 99, 88, 80, 79, 86, 84,
-  72, 89, 86, 72, 76, 66, 78, 67, 81, 74,
-  77, 65, 86, 89, 72, 81, 89, 89, 66, 74,
-  81, 88, 82, 80, 85, 93, 79, 75, 91, 83,
-  88, 95, 79, 93, 79, 90, 95, 93, 80, 119,
-  85, 76, 64, 69, 84, 69, 82, 88, 81, 81,
-  78, 74, 94, 80, 84, 84, 82, 84, 76, 76,
-  86, 97, 76, 78, 89, 88, 69, 88, 69, 71,
-  84, 72, 85, 99, 95, 80, 80, 90, 86, 89,
-  90, 61, 80, 87, 94, 85, 91, 69, 73, 101,
-  83, 96, 89, 65, 83, 81, 95, 75, 79, 73,
-  71, 79, 66, 78, 119, 88, 99, 90, 83, 77,
-  68, 89, 82, 87, 74, 97, 82, 103, 78, 82,
-  95, 83, 79, 65, 71, 65, 90, 91, 106, 70,
-  85, 84, 73, 68, 79, 80, 82, 75, 76, 55,
-  82, 92, 71, 87, 89, 88, 67, 76, 75, 82,
-  76, 82, 72, 95, 74, 77, 92, 80, 95, 104,
-  86, 86, 76, 83, 85, 89, 78, 108, 85, 80,
-  68, 71, 82, 69, 79, 82, 76, 90, 85, 74,
-  90, 80, 87, 86, 80, 81, 77, 77, 82, 87,
-  83, 81, 89, 86, 68, 91, 73, 70, 82, 76,
-  74, 96, 88, 80, 78, 88, 89, 77, 84, 64,
-  84, 83, 92, 75, 93, 73, 82, 99, 83, 90,
-  83, 72, 85, 84, 89, 75, 85, 76, 87, 76,
-  67, 78, 108, 85, 91, 86, 88, 77, 62, 89,
-  80, 85, 75, 75, 88, 99, 87, 79, 93, 88,
-  90, 67, 74, 70, 85, 98, 94, 74, 77, 81,
-  87, 71, 80, 82, 89, 98, 80, 79, 97, 84,
-  88, 84, 82, 94, 82, 78, 87, 88, 79, 89,
-  73, 89, 90, 83, 85, 83, 88, 85, 98, 90,
-  82, 93, 82, 87, 83, 81, 83, 89, 84, 79,
-  87, 91, 84, 90, 83, 85, 92, 81, 85, 91,
-  86, 89, 91, 80, 88, 84, 86, 84, 75, 87,
-  87, 62, 77, 83, 80, 86, 86, 84, 80, 79,
-  77, 83, 83, 80, 89, 76, 71, 79, 84, 86,
-  93, 81, 76, 71, 103, 81, 84, 90, 97, 82,
-  83, 93, 83, 84, 83, 80, 97, 86, 78, 87,
-  77, 82, 59, 90, 84, 85, 72, 86, 92, 81,
-  97, 65, 91, 89, 82, 66, 71, 86, 90, 78,
-  83, 81, 88, 85, 68, 87, 83, 84, 85, 72,
-  83, 87, 82, 92, 87, 84, 88, 90, 95, 86,
-  80, 84, 76, 74, 98, 90, 86, 91, 89, 99,
-  90, 87, 92, 70, 83, 88, 96, 102, 85, 103,
-  90, 74, 83, 84, 81, 76, 88, 67, 87, 92,
-  82, 89, 85, 88, 95, 82, 91, 86, 90, 90,
-  98, 89, 91, 84, 91, 87, 72, 88, 73, 79,
-  80, 83, 81, 90, 84, 84, 88, 72, 83, 75,
-  82, 81, 86, 82, 77, 74, 80, 91, 110, 81,
-  82, 67, 67, 81, 77, 104, 90, 68, 85, 95,
-  92, 88, 80, 84, 84, 83, 78, 81, 68, 81,
-  54, 93, 93, 78, 81, 91, 84, 85, 94, 83,
-  86, 96, 83, 59, 66, 82, 86, 80, 77, 70,
-  86, 101, 61, 96, 86, 87, 85, 72, 81, 89,
-  85, 95, 85, 86, 85, 92, 91, 85, 83, 81,
-  72, 78, 92, 87, 85, 86, 85, 98, 87, 88,
-  94, 70, 85, 91, 96, 96, 87, 97, 90, 75,
-  83, 81, 84, 77, 86, 67, 86, 90, 81, 85,
-  82, 86, 96, 83, 90, 88, 91, 88, 93, 90,
-  88, 85, 85, 85, 74, 88, 74, 78, 83, 84,
-  84, 86, 83, 83, 81, 73, 79, 76, 80, 77,
-  85, 81, 76, 75, 83, 89, 112, 81, 81, 69,
-  63, 81, 82, 102, 89, 75, 86, 96, 93, 86,
-  81, 83, 95, 84, 82, 78, 71, 81, 51, 90,
-  93, 79, 82, 90, 83, 82, 92, 80, 85, 93,
-  80, 60, 67, 85, 82, 82, 81, 76, 85, 111,
-  61, 92, 81, 81, 83, 69, 77, 89, 82, 88,
-  88, 89, 80, 83, 88, 81, 79, 87, 82, 83,
-  99, 84, 86, 86, 83, 87, 94, 89, 85, 81,
-  78, 88, 87, 96, 87, 97, 86, 91, 89, 87,
-  85, 84, 87, 77, 91, 97, 84, 86, 82, 86,
-  88, 84, 86, 84, 83, 87, 87, 80, 82, 94,
-  83, 89, 71, 92, 76, 77, 84, 84, 87, 95,
-  80, 84, 82, 71, 78, 75, 89, 69, 84, 78,
-  73, 81, 79, 83, 96, 78, 78, 60, 74, 86,
-  76, 100, 78, 79, 87, 90, 92, 90, 78, 82,
-  102, 87, 88, 85, 82, 78, 68, 88, 90, 86,
-  77, 87, 93, 85, 82, 72, 89, 86, 80, 66,
-  74, 82, 89, 82, 77, 66, 85, 90, 75, 90,
-  91, 80, 88, 91, 86, 85, 78, 79, 72, 90,
-  78, 83, 92, 81, 92, 81, 70, 98, 76, 80,
-  84, 70, 72, 83, 86, 108, 79, 83, 108, 85,
-  87, 80, 72, 108, 65, 83, 79, 81, 72, 94,
-  77, 80, 81, 88, 98, 60, 79, 87, 87, 73,
-  76, 75, 74, 95, 60, 80, 81, 82, 64, 91,
-  104, 85, 92, 104, 81, 101, 85, 85, 81, 77,
-  70, 69, 77, 80, 82, 72, 80, 78, 92, 95,
-  78, 102, 88, 78, 91, 85, 87, 109, 77, 101,
-  86, 81, 80, 61, 96, 86, 89, 98, 81, 88,
-  75, 76, 87, 81, 78, 83, 75, 94, 68, 83,
-  83, 87, 85, 80, 70, 69, 86, 92, 66, 90,
-  102, 84, 75, 90, 69, 89, 78, 67, 86, 90,
-  79, 82, 81, 78, 81, 74, 76, 86, 80, 89,
-  84, 72, 92, 78, 72, 94, 71, 79, 89, 71,
-  76, 86, 89, 106, 78, 81, 91, 79, 81, 83,
-  78, 90, 67, 88, 73, 78, 82, 93, 76, 79,
-  86, 96, 103, 67, 82, 76, 81, 77, 69, 69,
-  75, 91, 64, 73, 85, 77, 69, 83, 103, 86,
-  90, 96, 78, 100, 85, 86, 82, 71, 72, 67,
-  85, 82, 86, 69, 85, 83, 89, 91, 81, 97,
-  88, 78, 84, 81, 86, 97, 74, 105, 80, 77,
-  83, 59, 81, 86, 88, 102, 78, 83, 73, 76,
-  81, 83, 80, 83, 75, 94, 67, 85, 83, 90,
-  82, 84, 64, 67, 81, 87, 62, 87, 99, 81,
-  71, 88, 63, 89, 80, 68, 81, 88, 85, 84,
-  72, 77, 74, 81, 71, 87, 83, 84, 94, 81,
-  87, 91, 79, 99, 79, 93, 83, 79, 85, 89,
-  86, 104, 85, 85, 98, 71, 87, 90, 75, 88,
-  76, 88, 79, 81, 90, 96, 86, 75, 86, 93,
-  92, 69, 83, 78, 83, 83, 75, 77, 72, 84,
-  70, 78, 80, 85, 70, 97, 105, 79, 89, 99,
-  92, 95, 83, 88, 87, 89, 83, 71, 81, 82,
-  89, 73, 80, 91, 90, 96, 76, 91, 83, 81,
-  78, 80, 80, 93, 77, 99, 84, 81, 76, 66,
-  88, 84, 92, 101, 78, 92, 75, 82, 92, 80,
-  85, 85, 75, 93, 67, 84, 85, 88, 84, 86,
-  73, 73, 88, 90, 72, 87, 96, 92, 80, 92,
-  73, 87, 80, 71, 80, 75, 75, 87, 90, 85,
-  75, 75, 72, 88, 83, 79, 79, 80, 82, 88,
-  81, 90, 76, 86, 88, 74, 72, 87, 86, 89,
-  95, 83, 87, 83, 84, 85, 77, 105, 65, 82,
-  85, 86, 75, 83, 86, 74, 79, 87, 76, 77,
-  85, 82, 81, 79, 75, 67, 81, 88, 72, 100,
-  86, 85, 78, 91, 104, 78, 86, 87, 80, 88,
-  76, 86, 84, 82, 89, 76, 68, 69, 77, 76,
-  75, 75, 82, 81, 69, 89, 80, 80, 79, 87,
-  85, 85, 81, 101, 77, 74, 76, 72, 93, 78,
-  92, 90, 87, 86, 67, 85, 86, 80, 86, 82,
-  76, 86, 67, 84, 79, 94, 83, 80, 81, 74,
-  80, 93, 74, 79, 101, 84, 80, 84, 70, 93,
-  82, 70, 80, 83, 84, 81, 78, 83, 77, 72,
-  75, 89, 85, 86, 79, 83, 77, 89, 86, 89,
-  78, 91, 88, 83, 84, 92, 88, 81, 90, 82,
-  64, 75, 85, 89, 82, 94, 70, 87, 76, 86,
-  80, 79, 83, 74, 91, 94, 73, 84, 79, 77,
-  75, 83, 72, 75, 83, 87, 76, 84, 88, 84,
-  84, 83, 105, 83, 83, 83, 83, 85, 71, 89,
-  85, 83, 77, 73, 76, 69, 81, 76, 81, 84,
-  75, 77, 78, 80, 84, 72, 74, 88, 82, 80,
-  76, 97, 73, 70, 75, 68, 86, 72, 90, 88,
-  78, 86, 60, 77, 83, 81, 83, 85, 78, 82,
-  71, 82, 77, 93, 81, 80, 81, 79, 83, 90,
-  78, 81, 98, 83, 87, 82, 74, 90, 84, 74,
-  81, 81, 86, 84, 75, 82, 74, 72, 74, 87,
-  86, 86, 88, 93, 74, 91, 84, 91, 86, 93,
-  82, 91, 84, 95, 88, 86, 98, 86, 75, 73,
-  86, 98, 79, 93, 76, 74, 86, 85, 86, 83,
-  83, 73, 90, 92, 68, 89, 85, 85, 74, 89,
-  79, 87, 81, 88, 86, 76, 84, 85, 89, 91,
-  105, 79, 84, 91, 85, 83, 72, 85, 87, 94,
-  78, 76, 68, 70, 83, 78, 87, 95, 83, 83,
-  73, 81, 84, 76, 74, 89, 78, 80, 83, 94,
-  82, 73, 78, 70, 88, 73, 91, 87, 78, 95,
-  67, 77, 90, 81, 86, 92, 74, 81, 78, 87,
-  79, 92, 81, 84, 93, 87, 90, 90, 84, 80,
-  97, 90, 84, 87, 83, 87, 86, 83, 79, 86,
-  88, 88, 94, 84, 68, 68, 80, 82, 87, 80,
-  83, 95, 69, 90, 75, 82, 82, 96, 89, 91,
-  90, 100, 87, 77, 99, 78, 90, 81, 83, 96,
-  87, 104, 79, 99, 77, 89, 89, 71, 92, 83,
-  82, 87, 72, 96, 99, 88, 74, 93, 93, 85,
-  91, 88, 95, 92, 86, 83, 106, 91, 113, 78,
-  81, 80, 75, 81, 75, 82, 82, 95, 85, 89,
-  69, 70, 73, 82, 86, 92, 75, 78, 83, 79,
-  79, 82, 68, 97, 88, 68, 100, 98, 89, 77,
-  91, 74, 97, 75, 89, 90, 94, 86, 71, 85,
-  87, 82, 90, 81, 87, 73, 84, 96, 81, 95,
-  73, 84, 91, 95, 96, 92, 88, 77, 103, 86,
-  82, 87, 83, 91, 81, 92, 78, 89, 98, 83,
-  81, 93, 75, 66, 88, 82, 87, 84, 84, 94,
-  65, 87, 80, 83, 84, 100, 92, 102, 89, 100,
-  85, 75, 100, 78, 64, 81, 78, 101, 91, 94,
-  82, 93, 73, 89, 88, 65, 85, 83, 92, 96,
-  69, 111, 95, 91, 66, 96, 94, 94, 95, 83,
-  103, 97, 86, 86, 111, 86, 110, 80, 77, 80,
-  90, 83, 71, 80, 86, 96, 95, 84, 70, 69,
-  76, 80, 90, 96, 77, 77, 90, 75, 78, 82,
-  60, 101, 88, 68, 96, 87, 92, 77, 96, 68,
-  95, 68, 83, 87, 91, 88, 80, 88, 84, 83,
-  92, 79, 87, 72, 85, 97, 79, 93, 69, 87,
-  88, 91, 96, 91, 97, 83, 105, 90, 81, 82,
-  94, 90, 82, 98, 80, 88, 88, 89, 85, 95,
-  73, 62, 86, 77, 86, 84, 86, 93, 65, 92,
-  71, 81, 80, 101, 86, 107, 82, 104, 80, 72,
-  103, 83, 78, 82, 77, 101, 97, 99, 77, 81,
-  83, 89, 88, 71, 92, 84, 87, 87, 69, 111,
-  104, 99, 69, 103, 99, 88, 95, 86, 110, 97,
-  83, 84, 114, 91, 108, 83, 82, 89, 82, 87,
-  66, 79, 86, 85, 96, 87, 70, 71, 79, 85,
-  98, 96, 87, 80, 88, 77, 77, 87, 56, 106,
-  86, 61, 95, 89, 97, 83, 100, 70, 105, 70,
-  85, 83, 93, 90, 80, 93, 93, 82, 91, 83,
-  84, 68, 89, 98, 72, 95, 77, 91, 87, 94,
-  92, 89, 95, 84, 101, 88, 89, 87, 95, 86,
-  86, 103, 79, 86, 84, 72, 84, 87, 96, 72,
-  103, 75, 80, 85, 89, 94, 72, 88, 72, 78,
-  71, 78, 88, 89, 111, 70, 89, 89, 69, 68,
-  86, 86, 93, 88, 89, 80, 72, 104, 90, 72,
-  86, 72, 103, 78, 92, 85, 80, 94, 85, 90,
-  82, 90, 79, 74, 78, 85, 90, 88, 88, 73,
-  85, 82, 84, 85, 74, 74, 86, 71, 81, 89,
-  78, 88, 74, 82, 84, 74, 88, 81, 103, 92,
-  80, 66, 88, 87, 77, 75, 95, 85, 81, 82,
-  77, 91, 70, 85, 83, 84, 85, 113, 100, 90,
-  90, 79, 66, 77, 83, 80, 104, 77, 80, 88,
-  98, 66, 73, 79, 78, 91, 75, 94, 75, 79,
-  85, 106, 87, 71, 87, 91, 77, 86, 77, 80,
-  71, 90, 75, 51, 84, 85, 95, 66, 108, 70,
-  81, 85, 96, 86, 65, 89, 69, 90, 64, 76,
-  93, 91, 98, 61, 87, 73, 59, 48, 92, 85,
-  79, 109, 104, 81, 78, 76, 93, 68, 88, 67,
-  112, 64, 92, 81, 84, 109, 93, 84, 76, 91,
-  68, 84, 82, 93, 84, 82, 81, 75, 76, 92,
-  88, 89, 82, 73, 79, 69, 91, 90, 70, 90,
-  76, 71, 77, 74, 95, 68, 129, 90, 77, 65,
-  93, 83, 64, 73, 93, 71, 83, 88, 81, 96,
-  53, 95, 80, 84, 73, 115, 102, 81, 82, 87,
-  64, 87, 63, 82, 126, 63, 89, 83, 105, 56,
-  81, 75, 74, 84, 83, 94, 75, 95, 106, 104,
-  88, 61, 86, 90, 86, 90, 73, 88, 83, 86,
-  69, 63, 85, 102, 94, 69, 95, 76, 83, 85,
-  85, 84, 76, 88, 72, 81, 70, 76, 85, 87,
-  84, 71, 95, 84, 70, 67, 82, 82, 86, 107,
-  93, 96, 77, 75, 91, 71, 89, 74, 104, 74,
-  82, 82, 82, 102, 89, 92, 79, 90, 77, 72,
-  80, 89, 90, 70, 84, 74, 80, 85, 84, 88,
-  75, 75, 84, 68, 76, 87, 76, 78, 80, 81,
-  82, 74, 93, 82, 101, 90, 78, 70, 92, 85,
-  71, 90, 95, 81, 82, 88, 80, 98, 61, 98,
-  88, 85, 99, 111, 96, 88, 82, 77, 73, 82,
-  79, 80, 104, 77, 77, 84, 93, 72, 81, 78,
-  75, 89, 82, 95, 76, 85, 94, 102, 71, 71,
-  85, 91, 85, 86, 79, 82, 70, 82, 83, 69,
-  85, 83, 92, 71, 96, 67, 84, 74, 80, 90,
-  73, 88, 69, 80, 62, 85, 99, 86, 110, 76,
-  85, 88, 75, 52, 97, 85, 74, 83, 88, 75,
-  74, 109, 87, 89, 85, 64, 99, 78, 68, 81,
-  80, 101, 83, 88, 84, 77, 89, 82, 80, 93,
-  79, 92, 80, 78, 75, 100, 80, 82, 77, 71,
-  81, 64, 85, 88, 87, 73, 86, 80, 90, 74,
-  89, 84, 96, 90, 89, 80, 94, 85, 69, 76,
-  87, 81, 77, 84, 86, 87, 59, 73, 75, 78,
-  74, 96, 96, 96, 90, 86, 70, 92, 77, 80,
-  100, 93, 88, 77, 94, 66, 84, 84, 79, 86,
-  89, 80, 75, 86, 87, 106, 100, 62, 105, 86,
-  85, 83, 84, 87, 77, 95, 81, 53, 94, 78,
-  96, 68, 79, 67, 84, 68, 97, 93, 62, 97,
-  70, 77, 48, 84, 85, 102, 80, 73, 80, 83,
-  70, 36, 101, 91, 66, 117, 115, 83, 76, 78,
-  84, 97, 96, 63, 75, 79, 74, 72, 79, 101,
-  93, 94, 80, 75, 86, 80, 86, 113, 70, 87,
-  73, 87, 70, 114, 81, 84, 74, 73, 66, 66,
-  91, 80, 98, 68, 73, 75, 84, 64, 93, 70,
-  98, 91, 78, 99, 105, 93, 66, 78, 85, 74,
-  70, 90, 89, 85, 49, 66, 69, 84, 54, 81,
-  105, 88, 84, 95, 54, 87, 56, 88, 118, 89,
-  84, 68, 117, 50, 101, 74, 80, 70, 93, 75,
-  71, 104, 100, 93, 99, 48, 106, 85, 105, 76,
-  83, 109, 70, 100, 79, 62, 88, 102, 89, 65,
-  89, 72, 82, 73, 80, 88, 77, 87, 69, 79,
-  57, 83, 68, 91, 81, 74, 93, 86, 76, 52,
-  89, 83, 71, 111, 97, 87, 78, 71, 85, 88,
-  87, 65, 92, 81, 89, 75, 80, 102, 84, 82,
-  85, 75, 89, 79, 82, 96, 80, 81, 79, 82,
-  72, 100, 80, 90, 79, 74, 86, 64, 87, 87,
-  84, 73, 73, 86, 92, 74, 92, 83, 90, 93,
-  82, 87, 97, 89, 70, 99, 87, 85, 80, 92,
-  92, 90, 56, 82, 76, 78, 82, 91, 94, 92,
-  77, 80, 71, 81, 74, 84, 99, 96, 84, 75,
-  89, 69, 94, 85, 82, 80, 92, 83, 90, 88,
-  92, 99, 74, 65, 98, 88, 89, 82, 85, 91,
-  69, 77, 84, 85, 82, 83, 89, 68, 99, 73,
-  84, 75, 87, 93, 75, 87, 61, 81, 71, 85,
-  89, 88, 93, 79, 94, 88, 88, 67, 89, 89,
-  76, 80, 89, 77, 77, 105, 77, 93, 79, 73,
-  92, 90, 76, 81, 78, 95, 78, 84, 87, 77,
-  77, 83, 79, 96, 91, 83, 80, 76, 74, 93,
-  78, 82, 79, 81, 95, 68, 84, 92, 90, 84,
-  87, 89, 94, 78, 86, 96, 88, 87, 92, 82,
-  95, 80, 82, 85, 83, 90, 87, 90, 90, 83,
-  60, 77, 86, 74, 81, 89, 83, 100, 76, 85,
-  81, 97, 84, 79, 86, 94, 78, 84, 78, 82,
-  88, 82, 90, 86, 84, 82, 73, 74, 89, 87,
-  90, 79, 101, 88, 84, 74, 92, 90, 65, 86,
-  78, 74, 79, 81, 82, 68, 87, 71, 87, 70,
-  96, 89, 76, 96, 65, 80, 57, 81, 79, 94,
-  84, 80, 85, 86, 92, 46, 92, 87, 66, 98,
-  104, 77, 71, 93, 70, 103, 88, 74, 71, 92,
-  73, 71, 76, 96, 76, 91, 83, 80, 76, 82,
-  81, 109, 81, 84, 71, 82, 69, 98, 78, 81,
-  76, 75, 100, 66, 90, 83, 103, 87, 86, 85,
-  100, 78, 85, 88, 83, 92, 86, 95, 102, 79,
-  77, 88, 82, 90, 81, 94, 86, 76, 43, 80,
-  78, 71, 66, 74, 86, 102, 73, 91, 75, 100,
-  72, 82, 90, 97, 69, 68, 71, 76, 91, 77,
-  88, 80, 85, 79, 80, 72, 87, 81, 88, 72,
-  99, 86, 92, 62, 92, 100, 70, 92, 73, 77,
-  83, 88, 90, 67, 93, 72, 80, 79, 90, 82,
-  79, 87, 64, 81, 66, 82, 77, 85, 87, 81,
-  91, 87, 92, 62, 85, 86, 75, 95, 99, 85,
-  81, 78, 75, 95, 98, 73, 85, 93, 87, 77,
-  76, 93, 73, 80, 90, 76, 78, 84, 77, 102,
-  90, 86, 77, 82, 72, 93, 81, 81, 85, 82,
-  101, 68, 79, 89, 91, 91, 75, 96, 96, 82,
-  88, 93, 82, 92, 87, 85, 96, 80, 83, 92,
-  84, 98, 86, 96, 90, 78, 54, 83, 83, 75,
-  83, 82, 85, 99, 87, 84, 80, 86, 86, 81,
-  89, 95, 75, 81, 77, 79, 90, 81, 92, 85,
-  86, 87, 95, 73, 90, 86, 82, 83, 96, 90,
-  82, 71, 97, 92, 99, 85, 81, 83, 84, 88,
-  107, 96, 78, 79, 66, 88, 85, 88, 83, 85,
-  93, 90, 92, 80, 70, 82, 99, 91, 85, 85,
-  80, 65, 95, 85, 81, 84, 101, 83, 84, 87,
-  89, 77, 83, 84, 93, 78, 92, 84, 94, 94,
-  87, 80, 90, 84, 78, 90, 81, 76, 74, 81,
-  89, 88, 74, 84, 79, 83, 77, 94, 92, 81,
-  84, 78, 85, 75, 73, 75, 89, 94, 68, 93,
-  94, 73, 84, 86, 84, 87, 80, 75, 89, 84,
-  81, 77, 90, 81, 60, 81, 86, 102, 82, 86,
-  76, 87, 77, 64, 68, 85, 82, 81, 69, 86,
-  87, 90, 65, 110, 87, 86, 92, 74, 79, 74,
-  73, 82, 99, 79, 60, 95, 57, 93, 83, 85,
-  104, 90, 100, 79, 78, 79, 92, 80, 101, 103,
-  82, 76, 64, 86, 96, 86, 85, 91, 101, 89,
-  89, 79, 89, 82, 83, 91, 84, 87, 82, 64,
-  79, 86, 80, 85, 103, 77, 83, 79, 83, 79,
-  88, 89, 84, 64, 91, 82, 80, 98, 90, 70,
-  88, 88, 82, 89, 80, 84, 71, 84, 82, 91,
-  63, 84, 73, 78, 75, 88, 74, 80, 81, 74,
-  82, 61, 69, 68, 94, 89, 69, 86, 88, 78,
-  88, 95, 84, 88, 83, 71, 80, 83, 80, 63,
-  93, 85, 69, 70, 71, 105, 72, 79, 73, 86,
-  81, 67, 59, 71, 80, 79, 66, 73, 81, 90,
-  69, 107, 81, 83, 91, 76, 76, 63, 74, 80,
-  93, 76, 77, 96, 63, 91, 86, 86, 109, 90,
-  97, 77, 73, 80, 89, 96, 105, 92, 77, 79,
-  66, 86, 87, 85, 86, 84, 90, 86, 98, 84,
-  95, 82, 82, 90, 77, 86, 83, 62, 81, 89,
-  84, 79, 99, 80, 90, 88, 85, 76, 90, 85,
-  92, 73, 71, 86, 92, 91, 89, 65, 93, 83,
-  80, 87, 84, 84, 76, 87, 96, 87, 74, 82,
-  76, 80, 74, 96, 90, 79, 85, 86, 84, 81,
-  78, 73, 88, 94, 70, 88, 91, 89, 87, 84,
-  87, 85, 85, 67, 89, 83, 74, 77, 90, 76,
-  66, 83, 84, 99, 83, 82, 76, 86, 83, 71,
-  64, 77, 78, 80, 69, 88, 88, 87, 67, 105,
-  77, 84, 89, 83, 77, 78, 86, 79, 93, 79,
-  79, 93, 63, 92, 83, 87, 105, 90, 75, 92,
-  76, 96, 86, 72, 84, 97, 91, 81, 67, 86,
-  77, 71, 73, 102, 81, 82, 89, 84, 70, 84,
-  78, 90, 83, 78, 88, 81, 87, 81, 73, 88,
-  90, 75, 70, 85, 87, 75, 102, 84, 78, 73,
-  80, 78, 72, 81, 84, 88, 87, 81, 75, 86,
-  75, 76, 78, 87, 81, 82, 94, 82, 84, 83,
-  71, 79, 95, 71, 93, 93, 93, 85, 77, 82,
-  91, 101, 74, 88, 79, 80, 77, 76, 84, 83,
-  94, 95, 84, 82, 81, 84, 85, 88, 76, 89,
-  76, 98, 86, 75, 76, 80, 80, 94, 64, 89,
-  100, 82, 78, 121, 75, 83, 64, 83, 75, 70,
-  77, 75, 90, 95, 76, 76, 86, 84, 81, 75,
-  85, 90, 87, 78, 91, 91, 75, 86, 83, 101,
-  89, 69, 70, 97, 111, 85, 74, 89, 78, 82,
-  74, 99, 84, 80, 97, 79, 83, 87, 65, 90,
-  81, 71, 87, 96, 97, 79, 70, 93, 92, 76,
-  73, 80, 80, 81, 86, 72, 66, 63, 77, 82,
-  59, 83, 78, 84, 79, 83, 73, 94, 81, 76,
-  82, 84, 79, 74, 83, 79, 87, 81, 64, 84,
-  80, 61, 97, 95, 100, 85, 73, 66, 101, 104,
-  74, 83, 73, 87, 84, 63, 82, 83, 104, 96,
-  86, 84, 75, 88, 79, 80, 92, 82, 61, 93,
-  91, 67, 86, 78, 76, 116, 64, 93, 109, 78,
-  68, 137, 72, 90, 68, 70, 67, 67, 74, 75,
-  93, 90, 77, 75, 75, 88, 84, 65, 93, 85,
-  85, 74, 91, 97, 77, 77, 74, 93, 90, 79,
-  84, 99, 97, 81, 69, 86, 78, 100, 78, 102,
-  81, 81, 90, 82, 84, 86, 71, 91, 74, 81,
-  91, 84, 82, 77, 80, 87, 97, 82, 83, 91,
-  82, 80, 71, 83, 75, 77, 72, 81, 70, 83,
-  86, 83, 89, 86, 76, 91, 83, 79, 82, 77,
-  84, 79, 93, 79, 81, 84, 71, 78, 87, 71,
-  87, 97, 97, 89, 68, 78, 91, 99, 77, 81,
-  74, 84, 85, 73, 86, 82, 91, 84, 91, 83,
-  75, 83, 85, 82, 79, 80, 78, 97, 86, 78,
-  77, 81, 84, 98, 64, 94, 96, 81, 82, 122,
-  75, 85, 69, 81, 69, 69, 75, 86, 85, 98,
-  80, 75, 83, 86, 86, 73, 91, 89, 86, 76,
-  94, 97, 62, 97, 95, 83, 77, 89, 77, 83,
-  98, 81, 81, 91, 84, 84, 66, 92, 84, 79,
-  94, 97, 80, 92, 75, 79, 69, 71, 90, 87,
-  81, 80, 88, 85, 71, 72, 72, 98, 79, 75,
-  95, 79, 78, 73, 78, 84, 69, 67, 83, 93,
-  87, 76, 88, 93, 75, 76, 72, 83, 78, 82,
-  107, 80, 88, 89, 89, 69, 93, 72, 83, 99,
-  91, 85, 70, 100, 81, 92, 85, 82, 87, 93,
-  75, 82, 83, 87, 95, 114, 98, 71, 88, 101,
-  80, 93, 89, 75, 79, 88, 81, 86, 76, 81,
-  86, 97, 80, 79, 100, 89, 86, 94, 80, 95,
-  81, 69, 75, 66, 67, 89, 100, 103, 82, 88,
-  74, 91, 82, 84, 99, 80, 98, 83, 83, 89,
-  44, 89, 86, 80, 81, 85, 67, 79, 103, 86,
-  95, 92, 83, 97, 65, 85, 81, 83, 87, 103,
-  77, 99, 75, 79, 66, 75, 90, 100, 99, 83,
-  93, 81, 72, 78, 82, 88, 84, 79, 97, 67,
-  86, 83, 78, 87, 61, 63, 83, 102, 79, 74,
-  88, 101, 77, 68, 72, 100, 70, 77, 116, 85,
-  93, 90, 78, 79, 97, 80, 86, 110, 100, 78,
-  86, 101, 77, 94, 88, 73, 89, 95, 88, 68,
-  76, 88, 91, 101, 115, 72, 83, 114, 72, 84,
-  97, 82, 90, 82, 82, 85, 75, 85, 90, 112,
-  82, 92, 111, 90, 90, 114, 77, 103, 82, 64,
-  73, 73, 65, 87, 104, 118, 81, 89, 71, 90,
-  86, 77, 97, 79, 92, 81, 85, 97, 67, 77,
-  72, 87, 82, 76, 79, 93, 101, 83, 87, 89,
-  85, 92, 75, 88, 81, 84, 88, 95, 79, 83,
-  84, 76, 66, 81, 92, 89, 80, 77, 92, 81,
-  75, 74, 76, 99, 80, 81, 76, 76, 76, 81,
-  80, 85, 67, 65, 87, 100, 91, 79, 89, 81,
-  83, 77, 77, 88, 76, 82, 111, 80, 82, 82,
-  89, 65, 92, 76, 78, 101, 94, 75, 94, 100,
-  87, 95, 87, 85, 85, 87, 83, 82, 82, 84,
-  87, 92, 96, 74, 87, 94, 80, 90, 89, 78,
-  83, 86, 91, 90, 75, 85, 87, 93, 77, 98,
-  99, 88, 89, 98, 78, 94, 81, 71, 72, 66,
-  71, 93, 89, 101, 80, 88, 78, 82, 93, 78,
-  104, 83, 96, 79, 85, 89, 94, 73, 98, 94,
-  70, 75, 88, 73, 77, 74, 83, 82, 96, 81,
-  81, 85, 77, 68, 91, 85, 90, 87, 86, 86,
-  91, 63, 100, 84, 92, 73, 107, 99, 78, 93,
-  85, 70, 90, 89, 73, 79, 75, 107, 68, 95,
-  81, 81, 91, 83, 73, 82, 75, 94, 83, 74,
-  76, 101, 70, 72, 84, 95, 84, 86, 77, 74,
-  79, 74, 102, 75, 85, 72, 68, 87, 83, 105,
-  77, 63, 82, 70, 84, 75, 92, 96, 97, 86,
-  110, 76, 85, 78, 91, 80, 73, 80, 85, 88,
-  66, 83, 91, 75, 88, 74, 72, 91, 79, 83,
-  92, 85, 77, 88, 86, 77, 94, 79, 67, 83,
-  90, 90, 72, 90, 94, 75, 87, 90, 86, 72,
-  78, 73, 85, 103, 75, 82, 87, 93, 76, 60,
-  85, 77, 76, 77, 80, 76, 86, 97, 89, 91,
-  71, 70, 80, 84, 72, 68, 70, 91, 91, 67,
-  106, 84, 102, 69, 109, 95, 79, 92, 76, 61,
-  98, 101, 99, 76, 81, 95, 78, 95, 81, 70,
-  94, 67, 70, 76, 81, 87, 79, 76, 69, 92,
-  57, 76, 88, 99, 87, 103, 90, 77, 71, 78,
-  103, 69, 92, 79, 77, 89, 81, 109, 76, 67,
-  81, 65, 93, 62, 99, 95, 86, 79, 101, 91,
-  75, 79, 95, 75, 80, 78, 94, 88, 71, 86,
-  87, 80, 101, 57, 70, 87, 86, 83, 93, 86,
-  85, 94, 87, 71, 88, 86, 65, 71, 89, 104,
-  63, 88, 91, 71, 89, 89, 81, 74, 78, 80,
-  83, 91, 88, 87, 77, 95, 76, 86, 87, 79,
-  80, 76, 83, 81, 103, 84, 83, 80, 77, 71,
-  89, 86, 66, 76, 76, 83, 93, 66, 105, 85,
-  83, 76, 98, 94, 75, 84, 82, 79, 90, 93,
-  89, 85, 78, 100, 87, 91, 85, 81, 82, 88,
-  68, 85, 77, 85, 83, 84, 79, 75, 64, 77,
-  87, 95, 84, 91, 83, 69, 78, 74, 95, 79,
-  79, 89, 85, 91, 85, 109, 79, 65, 79, 85,
-  73, 71, 92, 84, 94, 77, 103, 89, 77, 75,
-  91, 77, 75, 74, 86, 85, 74, 82, 86, 76,
-  101, 74, 74, 87, 82, 84, 93, 90, 84, 91,
-  90, 80, 70, 75, 70, 83, 95, 87, 69, 90,
-  91, 79, 93, 89, 81, 79, 76, 70, 86, 98,
-  64, 81, 103, 82, 88, 63, 71, 69, 93, 87,
-  78, 100, 95, 107, 68, 72, 78, 68, 78, 81,
-  92, 89, 79, 80, 79, 70, 99, 75, 105, 83,
-  87, 93, 76, 81, 78, 91, 76, 95, 69, 79,
-  87, 78, 73, 81, 85, 98, 68, 75, 92, 81,
-  83, 91, 88, 77, 76, 69, 68, 63, 93, 76,
-  74, 100, 82, 86, 74, 103, 81, 94, 75, 100,
-  56, 71, 84, 87, 71, 90, 75, 84, 91, 76,
-  87, 75, 80, 78, 91, 82, 84, 88, 74, 92,
-  86, 81, 80, 78, 80, 88, 77, 74, 78, 84,
-  78, 73, 86, 82, 92, 81, 80, 83, 73, 76,
-  104, 59, 69, 93, 98, 113, 107, 82, 94, 66,
-  92, 95, 77, 85, 92, 93, 75, 83, 36, 90,
-  72, 85, 86, 71, 60, 78, 98, 97, 68, 92,
-  42, 86, 72, 74, 68, 75, 91, 90, 67, 57,
-  87, 91, 71, 80, 107, 72, 107, 66, 67, 86,
-  73, 81, 73, 78, 62, 84, 71, 57, 86, 55,
-  63, 70, 90, 100, 76, 57, 107, 70, 94, 66,
-  84, 81, 94, 80, 81, 57, 88, 78, 69, 118,
-  99, 56, 92, 83, 72, 91, 67, 130, 78, 63,
-  100, 67, 89, 116, 76, 66, 104, 64, 86, 78,
-  69, 87, 65, 74, 93, 94, 56, 80, 112, 95,
-  64, 72, 117, 75, 85, 71, 76, 75, 75, 112,
-  95, 79, 116, 81, 110, 81, 80, 60, 89, 61,
-  92, 94, 82, 95, 110, 68, 64, 56, 90, 87,
-  71, 114, 100, 102, 70, 59, 69, 94, 58, 78,
-  82, 78, 77, 75, 93, 86, 82, 99, 109, 70,
-  73, 73, 75, 66, 83, 82, 68, 73, 79, 81,
-  78, 77, 101, 82, 101, 78, 81, 90, 80, 88,
-  87, 95, 78, 100, 114, 80, 96, 80, 93, 86,
-  79, 84, 61, 87, 88, 82, 81, 86, 90, 82,
-  88, 95, 78, 71, 92, 78, 75, 106, 83, 86,
-  77, 111, 69, 90, 72, 102, 102, 78, 86, 82,
-  71, 87, 77, 70, 106, 73, 93, 77, 75, 88,
-  96, 86, 89, 81, 77, 96, 97, 84, 82, 80,
-  80, 79, 82, 76, 103, 84, 77, 108, 88, 82,
-  95, 83, 91, 86, 81, 80, 78, 60, 76, 84,
-  83, 85, 72, 81, 92, 70, 88, 95, 75, 90,
-  91, 87, 75, 79, 73, 95, 101, 72, 86, 83,
-  89, 85, 89, 75, 76, 86, 87, 78, 92, 77,
-  80, 81, 76, 84, 63, 83, 80, 73, 86, 86,
-  75, 78, 83, 91, 77, 87, 99, 78, 75, 100,
-  87, 90, 96, 85, 81, 80, 76, 91, 94, 99,
-  72, 75, 88, 87, 83, 86, 83, 79, 80, 98,
-  85, 79, 96, 78, 79, 90, 86, 103, 73, 110,
-  77, 90, 78, 88, 97, 68, 92, 75, 73, 95,
-  80, 88, 83, 95, 88, 83, 87, 84, 94, 78,
-  83, 79, 87, 112, 85, 78, 79, 93, 104, 81,
-  76, 93, 100, 76, 89, 61, 82, 89, 84, 93,
-  74, 86, 84, 101, 84, 84, 89, 87, 82, 78,
-  115, 81, 93, 80, 85, 89, 81, 88, 80, 83,
-  81, 95, 68, 106, 92, 74, 98, 96, 79, 99,
-  97, 72, 80, 75, 62, 84, 80, 85, 72, 76,
-  91, 80, 62, 64, 86, 78, 86, 103, 62, 82,
-  74, 56, 88, 90, 81, 86, 66, 94, 79, 73,
-  75, 72, 72, 71, 57, 86, 106, 105, 85, 79,
-  106, 80, 94, 82, 81, 84, 78, 83, 113, 81,
-  95, 79, 70, 89, 95, 73, 72, 95, 67, 89,
-  74, 73, 92, 60, 88, 75, 83, 114, 77, 81,
-  61, 105, 86, 91, 97, 85, 89, 75, 92, 82,
-  86, 114, 96, 84, 70, 90, 118, 70, 79, 86,
-  85, 83, 83, 69, 99, 86, 83, 72, 95, 78,
-  85, 97, 80, 75, 113, 91, 77, 73, 95, 67,
-  74, 70, 93, 75, 87, 121, 94, 78, 75, 87,
-  80, 87, 97, 74, 90, 85, 92, 85, 85, 74,
-  81, 86, 90, 90, 92, 71, 73, 79, 78, 88,
-  78, 81, 84, 79, 82, 85, 76, 80, 75, 67,
-  80, 86, 99, 92, 95, 100, 85, 86, 69, 81,
-  82, 83, 66, 95, 92, 105, 74, 94, 91, 92,
-  77, 90, 82, 79, 82, 78, 84, 75, 94, 74,
-  77, 89, 84, 104, 78, 105, 74, 87, 82, 94,
-  108, 72, 87, 79, 69, 85, 83, 78, 82, 96,
-  91, 83, 76, 92, 99, 77, 90, 81, 84, 108,
-  85, 78, 81, 91, 93, 83, 77, 90, 91, 78,
-  89, 87, 83, 89, 83, 87, 79, 80, 80, 91,
-  90, 82, 87, 89, 92, 70, 70, 80, 91, 76,
-  96, 88, 93, 90, 77, 81, 79, 94, 85, 73,
-  87, 92, 96, 84, 89, 86, 72, 92, 91, 64,
-  61, 93, 89, 74, 85, 88, 96, 87, 82, 68,
-  91, 81, 106, 107, 82, 86, 93, 76, 77, 92,
-  93, 76, 70, 79, 80, 79, 83, 100, 83, 73,
-  75, 66, 93, 72, 69, 73, 94, 78, 71, 74,
-  67, 73, 78, 70, 83, 90, 74, 88, 84, 71,
-  93, 79, 95, 87, 81, 96, 77, 90, 76, 77,
-  86, 85, 82, 87, 94, 79, 101, 98, 69, 101,
-  97, 96, 64, 86, 97, 68, 80, 89, 90, 90,
-  97, 113, 78, 89, 75, 110, 80, 89, 88, 63,
-  81, 88, 91, 77, 76, 68, 77, 104, 82, 85,
-  95, 91, 71, 75, 89, 84, 60, 65, 97, 98,
-  95, 84, 62, 89, 90, 82, 82, 82, 75, 89,
-  99, 78, 85, 75, 75, 93, 96, 75, 67, 91,
-  92, 72, 89, 86, 97, 82, 83, 68, 87, 87,
-  100, 104, 75, 86, 88, 74, 79, 91, 90, 80,
-  65, 75, 79, 77, 81, 97, 85, 77, 73, 73,
-  99, 73, 69, 78, 89, 80, 66, 73, 75, 74,
-  80, 73, 78, 90, 76, 77, 92, 74, 88, 82,
-  85, 84, 75, 95, 79, 84, 78, 83, 82, 80,
-  84, 81, 99, 65, 102, 99, 71, 101, 95, 81,
-  68, 86, 94, 68, 80, 96, 83, 91, 99, 108,
-  75, 91, 81, 115, 79, 87, 80, 65, 76, 90,
-  92, 77, 74, 67, 75, 105, 82, 86, 92, 89,
-  73, 81, 73, 84, 59, 70, 89, 102, 89, 80,
-  68, 83, 91, 78, 83, 84, 78, 92, 94, 84,
-  85, 81, 75, 92, 93, 67, 70, 87, 87, 76,
-  88, 85, 94, 88, 79, 71, 91, 84, 91, 97,
-  80, 88, 90, 77, 76, 95, 97, 78, 78, 90,
-  84, 81, 81, 96, 85, 76, 77, 76, 92, 76,
-  70, 90, 93, 79, 73, 76, 71, 74, 78, 76,
-  87, 83, 76, 82, 79, 71, 92, 79, 98, 85,
-  78, 99, 80, 85, 88, 74, 85, 82, 87, 86,
-  96, 71, 99, 92, 70, 98, 96, 91, 68, 84,
-  94, 74, 79, 94, 91, 103, 94, 112, 81, 90,
-  75, 105, 79, 92, 88, 78, 79, 88, 91, 78,
-  83, 72, 75, 101, 82, 87, 96, 94, 68, 76,
-  79, 84, 61, 68, 86, 94, 91, 84, 63, 87,
-  92, 80, 87, 72, 85, 88, 103, 88, 93, 92,
-  76, 90, 85, 69, 64, 91, 93, 83, 87, 87,
-  93, 91, 83, 67, 86, 84, 104, 103, 83, 86,
-  89, 73, 83, 91, 92, 82, 79, 83, 78, 79,
-  77, 92, 84, 82, 78, 75, 100, 69, 74, 76,
-  90, 77, 77, 71, 70, 77, 81, 73, 77, 92,
-  78, 85, 84, 76, 84, 86, 90, 91, 79, 77,
-  79, 81, 82, 80, 87, 81, 85, 86, 90, 83,
-  89, 107, 67, 93, 95, 80, 68, 82, 89, 74,
-  81, 81, 81, 82, 99, 112, 78, 100, 81, 109,
-  88, 81, 77, 63, 81, 90, 86, 70, 80, 72,
-  71, 95, 81, 82, 93, 87, 66, 83, 85, 86,
-  66, 66, 89, 98, 95, 84, 65, 91, 97, 77,
-  89, 77, 77, 85, 102, 78, 93, 79, 79, 90,
-  89, 78, 65, 89, 99, 80, 92, 88, 94, 81,
-  84, 68, 81, 91, 106, 93, 78, 84, 84, 78,
-  82, 89, 86, 81, 76, 74, 80, 77, 82, 89,
-  86, 90, 77, 79, 102, 73, 81, 80, 83, 79,
-  77, 73, 77, 76, 84, 74, 75, 93, 82, 76,
-  88, 79, 80, 94, 82, 94, 77, 73, 81, 80,
-  77, 81, 85, 78, 89, 77, 94, 69, 89, 109,
-  68, 96, 93, 75, 72, 80, 87, 74, 82, 83,
-  71, 80, 96, 103, 72, 99, 88, 112, 86, 75,
-  74, 63, 77, 91, 85, 72, 77, 73, 63, 97,
-  81, 83, 88, 83, 72, 86, 74, 89, 68, 71,
-  74, 100, 84, 75, 70, 89, 97, 75, 81, 86,
-  84, 88, 99, 83, 89, 86, 80, 88, 90, 70,
-  66, 86, 88, 88, 88, 86, 92, 87, 81, 70,
-  88, 87, 99, 95, 79, 85, 86, 81, 84, 92,
-  96, 83, 78, 87, 80, 80, 84, 90, 84, 85,
-  76, 81, 96, 75, 78, 94, 88, 79, 80, 77,
-  73, 78, 81, 72, 81, 89, 83, 81, 80, 75,
-  84, 86, 94, 90, 81, 81, 79, 81, 84, 74,
-  86, 80, 85, 89, 90, 72, 90, 103, 70, 93,
-  97, 89, 71, 81, 92, 76, 83, 91, 85, 85,
-  94, 110, 78, 97, 82, 103, 81, 84, 84, 69,
-  79, 89, 84, 71, 80, 73, 70, 94, 82, 84,
-  94, 88, 66, 80, 82, 86, 68, 71, 77, 95,
-  95, 85, 63, 90, 96, 78, 89, 70, 82, 81,
-  91, 90, 96, 103, 80, 85, 81, 74, 66, 85,
-  88, 85, 85, 82, 86, 87, 80, 72, 83, 77,
-  99, 100, 95, 86, 89, 79, 79, 87, 99, 85,
-  84, 87, 79, 81, 74, 87, 81, 88, 76, 79,
-  93, 70, 80, 76, 89, 75, 72, 77, 67, 74,
-  85, 76, 82, 78, 82, 82, 78, 74, 84, 74,
-  100, 92, 79, 80, 80, 94, 93, 80, 83, 84,
-  88, 85, 88, 77, 92, 99, 66, 86, 95, 83,
-  65, 80, 87, 81, 87, 83, 85, 82, 92, 117,
-  79, 96, 71, 106, 86, 84, 91, 69, 82, 90,
-  83, 73, 78, 75, 79, 97, 81, 80, 94, 84,
-  70, 83, 83, 95, 71, 68, 87, 95, 98, 81,
-  59, 92, 88, 84, 90, 76, 79, 78, 90, 73,
-  99, 92, 83, 86, 86, 82, 65, 83, 92, 85,
-  86, 81, 91, 83, 79, 71, 79, 83, 103, 92,
-  91, 85, 85, 87, 75, 88, 98, 79, 82, 76,
-  80, 82, 77, 86, 81, 89, 76, 80, 92, 71,
-  83, 77, 87, 79, 74, 78, 73, 76, 84, 78,
-  81, 82, 83, 82, 77, 76, 81, 77, 88, 92,
-  81, 84, 85, 90, 78, 80, 83, 83, 94, 86,
-  89, 68, 92, 102, 71, 90, 96, 79, 69, 78,
-  87, 79, 86, 84, 81, 82, 95, 114, 71, 97,
-  79, 105, 88, 80, 89, 68, 80, 90, 83, 73,
-  77, 75, 79, 98, 80, 81, 89, 81, 75, 81,
-  74, 98, 74, 71, 77, 95, 97, 73, 66, 93,
-  87, 81, 83, 83, 86, 81, 92, 79, 92, 93,
-  84, 85, 84, 77, 66, 85, 84, 84, 84, 80,
-  86, 89, 80, 73, 90, 82, 99, 89, 88, 83,
-  86, 86, 76, 91, 98, 83, 77, 88, 81, 82,
-  85, 83, 81, 83, 77, 83, 93, 76, 83, 90,
-  86, 77, 74, 87, 70, 76, 88, 74, 84, 76,
-  88, 78, 77, 73, 85, 80, 107, 91, 80, 79,
-  79, 96, 84, 74, 82, 82, 89, 86, 89, 73,
-  89, 92, 71, 87, 97, 89, 70, 81, 88, 88,
-  86, 87, 86, 84, 89, 113, 79, 92, 76, 101,
-  85, 85, 95, 72, 80, 88, 84, 76, 79, 78,
-  79, 92, 79, 81, 92, 86, 69, 82, 87, 95,
-  73, 73, 80, 90, 97, 81, 57, 91, 89, 80,
-  73, 104, 73, 88, 71, 84, 87, 87, 84, 86,
-  74, 76, 79, 71, 87, 74, 79, 83, 88, 86,
-  97, 82, 91, 92, 103, 79, 88, 85, 98, 112,
-  74, 85, 83, 79, 78, 84, 89, 88, 148, 90,
-  84, 93, 67, 91, 86, 83, 87, 76, 84, 76,
-  86, 76, 90, 77, 75, 114, 76, 78, 83, 86,
-  85, 75, 96, 83, 66, 76, 84, 83, 76, 83,
-  81, 103, 78, 83, 91, 75, 86, 89, 79, 78,
-  83, 81, 85, 99, 78, 94, 84, 98, 84, 90,
-  87, 70, 73, 79, 80, 80, 90, 78, 73, 89,
-  80, 71, 96, 94, 87, 85, 85, 88, 88, 77,
-  80, 79, 76, 84, 79, 99, 77, 85, 85, 91,
-  81, 87, 84, 74, 80, 91, 89, 88, 66, 89,
-  63, 79, 90, 74, 74, 86, 82, 83, 77, 75,
-  71, 63, 75, 72, 87, 70, 76, 76, 92, 77,
-  84, 89, 101, 69, 81, 81, 120, 106, 78, 79,
-  81, 74, 68, 100, 84, 78, 156, 89, 87, 78,
-  79, 92, 98, 93, 83, 79, 86, 73, 82, 78,
-  84, 77, 67, 104, 76, 80, 94, 81, 84, 82,
-  90, 100, 50, 79, 79, 82, 81, 83, 116, 92,
-  86, 92, 86, 80, 77, 83, 88, 75, 77, 74,
-  85, 80, 85, 97, 82, 110, 73, 81, 75, 88,
-  81, 81, 82, 73, 87, 80, 78, 95, 83, 82,
-  90, 95, 88, 77, 71, 87, 82, 73, 77, 81,
-  70, 77, 72, 92, 72, 85, 76, 87, 88, 95,
-  81, 72, 77, 83, 84, 91, 68, 87, 79, 96,
-  68, 78, 87, 95, 87, 89, 75, 75, 77, 68,
-  86, 91, 83, 93, 84, 82, 90, 74, 92, 88,
-  97, 78, 83, 90, 61, 84, 82, 84, 89, 70,
-  77, 94, 57, 85, 93, 87, 96, 72, 77, 90,
-  85, 93, 90, 77, 71, 89, 84, 90, 83, 78,
-  91, 74, 81, 96, 90, 87, 83, 71, 83, 68,
-  91, 65, 85, 86, 78, 98, 70, 79, 109, 88,
-  83, 75, 77, 77, 81, 73, 102, 76, 76, 89,
-  77, 96, 88, 67, 77, 82, 81, 87, 84, 78,
-  82, 74, 89, 79, 70, 80, 85, 83, 76, 96,
-  83, 89, 85, 87, 78, 73, 71, 93, 81, 92,
-  79, 78, 87, 84, 81, 81, 88, 83, 100, 92,
-  96, 82, 83, 78, 84, 102, 76, 95, 54, 88,
-  95, 89, 95, 81, 78, 77, 87, 70, 93, 81,
-  85, 89, 86, 92, 100, 88, 106, 97, 100, 83,
-  89, 87, 90, 93, 76, 86, 81, 78, 89, 78,
-  80, 80, 98, 84, 82, 78, 68, 84, 78, 91,
-  85, 80, 75, 85, 79, 86, 88, 73, 95, 95,
-  77, 89, 85, 90, 81, 72, 89, 73, 81, 72,
-  82, 78, 79, 83, 85, 78, 84, 87, 92, 75,
-  84, 90, 77, 78, 96, 72, 81, 98, 75, 89,
-  76, 78, 87, 94, 91, 77, 80, 81, 87, 78,
-  82, 70, 75, 86, 82, 67, 80, 88, 80, 87,
-  88, 85, 83, 89, 73, 80, 89, 90, 71, 73,
-  80, 81, 83, 82, 80, 76, 94, 92, 81, 87,
-  77, 78, 76, 105, 61, 83, 75, 78, 78, 77,
-  88, 82, 78, 75, 71, 58, 79, 68, 87, 70,
-  75, 80, 91, 76, 91, 89, 100, 74, 84, 83,
-  119, 97, 76, 84, 77, 73, 73, 92, 84, 79,
-  149, 83, 86, 73, 75, 83, 87, 92, 85, 71,
-  85, 74, 81, 81, 87, 78, 76, 99, 67, 79,
-  83, 83, 85, 85, 91, 93, 57, 73, 74, 72,
-  85, 67, 108, 88, 78, 89, 86, 75, 85, 87,
-  90, 75, 74, 74, 82, 90, 78, 93, 75, 105,
-  73, 84, 78, 79, 84, 80, 83, 79, 87, 81,
-  74, 83, 75, 75, 90, 91, 79, 72, 69, 75,
-  74, 75, 77, 78, 71, 80, 65, 82, 61, 86,
-  76, 84, 87, 85, 84, 67, 69, 83, 80, 80,
-  78, 87, 57, 83, 80, 75, 77, 82, 80, 82,
-  76, 76, 75, 67, 74, 75, 89, 83, 84, 79,
-  91, 74, 86, 85, 97, 77, 84, 81, 104, 88,
-  90, 93, 82, 70, 75, 105, 90, 82, 135, 87,
-  98, 79, 84, 83, 92, 93, 90, 75, 91, 80,
-  72, 83, 85, 78, 81, 75, 72, 82, 85, 84,
-  91, 93, 93, 96, 62, 72, 72, 93, 92, 84,
-  92, 90, 93, 92, 86, 80, 76, 81, 96, 76,
-  82, 80, 80, 79, 85, 89, 78, 98, 63, 72,
-  79, 92, 86, 78, 88, 73, 87, 87, 78, 80,
-  78, 79, 82, 95, 86, 73, 70, 77, 79, 67,
-  81, 94, 74, 83, 71, 94, 72, 90, 77, 89,
-  93, 93, 85, 71, 78, 86, 86, 81, 98, 96,
-  84, 81, 59, 89, 95, 83, 80, 85, 78, 86,
-  93, 82, 83, 83, 85, 85, 88, 102, 99, 89,
-  106, 88, 96, 89, 82, 88, 80, 94, 86, 86,
-  83, 83, 89, 85, 96, 88, 109, 88, 91, 83,
-  73, 91, 83, 87, 80, 82, 75, 87, 86, 88,
-  79, 77, 103, 101, 86, 103, 93, 88, 83, 79,
-  95, 81, 87, 92, 78, 85, 73, 92, 102, 95,
-  80, 80, 86, 82, 80, 89, 75, 82, 100, 78,
-  76, 90, 92, 90, 74, 85, 85, 82, 81, 75,
-  82, 73, 85, 87, 78, 75, 75, 90, 77, 79,
-  83, 94, 87, 94, 85, 92, 86, 92, 79, 82,
-  88, 84, 75, 91, 87, 89, 92, 93, 80, 89,
-  87, 92, 91, 91, 83, 78, 86, 106, 83, 91,
-  59, 96, 90, 81, 88, 84, 81, 81, 74, 81,
-  85, 83, 89, 88, 83, 95, 93, 71, 103, 95,
-  91, 80, 89, 84, 85, 85, 85, 87, 87, 75,
-  83, 88, 87, 82, 91, 76, 85, 79, 76, 77,
-  81, 94, 84, 77, 80, 90, 93, 80, 85, 76,
-  89, 75, 75, 95, 79, 90, 87, 83, 93, 79,
-  88, 67, 81, 80, 80, 84, 87, 96, 85, 83,
-  86, 81, 86, 92, 84, 77, 90, 78, 83, 97,
-  78, 91, 82, 83, 89, 90, 90, 76, 82, 80,
-  89, 79, 87, 81, 74, 79, 80, 82, 83, 95,
-  87, 87, 86, 73, 80, 82, 79, 85, 81, 89,
-  74, 87, 80, 88, 79, 84, 90, 83, 91, 78,
-  80, 93, 75, 77, 79, 90, 68, 92, 74, 86,
-  82, 74, 80, 85, 83, 75, 86, 79, 73, 71,
-  89, 79, 84, 90, 85, 65, 98, 93, 93, 76,
-  92, 84, 86, 85, 98, 85, 81, 78, 70, 99,
-  89, 90, 120, 86, 92, 84, 76, 73, 77, 88,
-  96, 83, 93, 77, 81, 79, 83, 78, 73, 63,
-  74, 85, 80, 97, 93, 91, 92, 100, 79, 63,
-  80, 87, 95, 86, 93, 107, 80, 86, 87, 79,
-  79, 86, 87, 76, 80, 78, 85, 92, 94, 90,
-  80, 95, 78, 86, 82, 85, 86, 86, 83, 75,
-  90, 86, 77, 82, 72, 69, 86, 96, 87, 81,
-  71, 74, 81, 62, 83, 86, 77, 85, 78, 98,
-  84, 90, 85, 82, 99, 94, 81, 67, 75, 97,
-  79, 82, 107, 92, 78, 92, 85, 88, 78, 84,
-  75, 79, 68, 81, 86, 97, 97, 90, 90, 86,
-  76, 69, 76, 83, 101, 83, 87, 78, 88, 90,
-  90, 88, 83, 80, 75, 108, 89, 83, 85, 88,
-  83, 80, 85, 76, 98, 79, 80, 75, 88, 88,
-  85, 82, 89, 77, 78, 82, 83, 87, 76, 88,
-  82, 81, 81, 85, 83, 82, 87, 88, 84, 78,
-  102, 80, 95, 91, 84, 79, 83, 80, 79, 82,
-  86, 78, 86, 89, 82, 76, 73, 80, 83, 86,
-  89, 72, 65, 85, 82, 99, 80, 74, 90, 84,
-  91, 76, 76, 85, 81, 102, 77, 79, 78, 88,
-  82, 75, 73, 92, 78, 86, 71, 77, 82, 86,
-  86, 88, 74, 75, 94, 83, 88, 88, 87, 73,
-  131, 94, 88, 90, 99, 94, 76, 75, 67, 75,
-  72, 79, 93, 83, 97, 82, 86, 85, 73, 70,
-  81, 85, 88, 84, 110, 79, 94, 82, 91, 85,
-  94, 89, 80, 88, 90, 83, 78, 92, 95, 81,
-  84, 82, 82, 91, 96, 84, 87, 80, 78, 75,
-  83, 79, 78, 85, 86, 79, 66, 85, 82, 78,
-  83, 72, 87, 82, 74, 86, 100, 77, 89, 74,
-  79, 99, 77, 76, 85, 74, 69, 97, 69, 80,
-  84, 92, 95, 71, 75, 88, 79, 91, 83, 76,
-  52, 73, 74, 115, 71, 75, 86, 94, 88, 77,
-  69, 86, 78, 103, 82, 72, 72, 90, 104, 76,
-  85, 93, 77, 80, 78, 87, 84, 96, 90, 81,
-  79, 68, 104, 75, 91, 92, 88, 74, 88, 73,
-  98, 86, 80, 99, 78, 88, 90, 88, 70, 93,
-  69, 84, 92, 89, 90, 79, 75, 83, 95, 78,
-  82, 83, 91, 75, 88, 89, 87, 91, 81, 78,
-  77, 82, 87, 98, 81, 89, 81, 84, 82, 76,
-  73, 89, 78, 78, 83, 79, 92, 80, 88, 82,
-  78, 74, 82, 86, 86, 88, 91, 82, 76, 90,
-  80, 72, 91, 86, 86, 81, 92, 71, 79, 78,
-  86, 75, 82, 85, 85, 89, 72, 73, 83, 95,
-  80, 73, 80, 91, 85, 82, 90, 76, 75, 87,
-  86, 88, 89, 78, 84, 81, 89, 83, 83, 65,
-  82, 98, 81, 79, 83, 85, 80, 85, 87, 81,
-  84, 86, 80, 82, 99, 76, 81, 89, 89, 84,
-  95, 93, 80, 87, 87, 77, 119, 84, 84, 69,
-  97, 74, 72, 87, 69, 81, 73, 78, 75, 108,
-  81, 76, 81, 79, 77, 83, 75, 78, 91, 87,
-  78, 80, 87, 88, 105, 94, 93, 84, 76, 127,
-  91, 83, 112, 84, 72, 74, 84, 76, 99, 86,
-  63, 68, 73, 86, 91, 78, 85, 76, 83, 81,
-  64, 87, 87, 82, 84, 80, 88, 81, 81, 80,
-  90, 81, 80, 90, 99, 67, 107, 83, 79, 75,
-  75, 77, 82, 75, 113, 73, 84, 73, 77, 83,
-  104, 80, 90, 95, 78, 72, 73, 84, 79, 89,
-  91, 74, 75, 78, 81, 83, 81, 100, 94, 99,
-  78, 91, 76, 90, 68, 88, 71, 105, 71, 87,
-  89, 71, 65, 93, 84, 99, 69, 67, 82, 71,
-  83, 90, 78, 70, 148, 82, 97, 82, 119, 78,
-  67, 81, 58, 81, 74, 70, 89, 84, 90, 74,
-  85, 80, 84, 92, 80, 88, 70, 82, 112, 77,
-  84, 75, 103, 105, 101, 92, 81, 125, 85, 93,
-  95, 98, 118, 71, 86, 69, 73, 99, 69, 61,
-  76, 68, 83, 73, 80, 76, 82, 85, 56, 88,
-  75, 86, 75, 93, 101, 72, 80, 84, 69, 81,
-  92, 96, 108, 70, 74, 88, 76, 74, 72, 73,
-  80, 90, 84, 74, 82, 67, 91, 78, 125, 101,
-  79, 106, 72, 68, 67, 75, 63, 110, 76, 80,
-  71, 83, 82, 69, 67, 73, 97, 98, 71, 104,
-  76, 91, 76, 81, 76, 117, 68, 83, 100, 80,
-  84, 100, 84, 86, 68, 61, 81, 64, 86, 99,
-  76, 60, 94, 72, 82, 70, 79, 102, 74, 87,
-  89, 85, 79, 86, 71, 77, 75, 74, 82, 75,
-  77, 86, 97, 82, 73, 87, 87, 73, 87, 87,
-  96, 102, 80, 83, 72, 86, 81, 99, 97, 81,
-  98, 75, 82, 81, 66, 83, 68, 71, 71, 71,
-  86, 89, 89, 82, 84, 74, 75, 88, 92, 81,
-  96, 75, 85, 78, 77, 63, 82, 82, 87, 87,
-  89, 82, 68, 82, 86, 79, 70, 83, 93, 96,
-  79, 75, 78, 80, 75, 76, 87, 87, 83, 94,
-  84, 77, 76, 83, 84, 82, 85, 73, 75, 74,
-  89, 85, 87, 59, 90, 96, 90, 87, 83, 82,
-  71, 98, 78, 87, 84, 87, 89, 92, 102, 76,
-  86, 103, 99, 78, 82, 87, 81, 87, 81, 87,
-  84, 84, 82, 54, 77, 82, 81, 84, 84, 87,
-  80, 90, 78, 94, 73, 71, 68, 78, 82, 73,
-  88, 91, 74, 95, 70, 80, 93, 89, 92, 81,
-  82, 85, 98, 99, 99, 79, 105, 76, 73, 78,
-  83, 67, 94, 78, 64, 90, 71, 61, 86, 108,
-  81, 89, 87, 82, 80, 81, 89, 74, 90, 71,
-  84, 85, 71, 78, 85, 83, 74, 79, 85, 81,
-  92, 68, 93, 80, 73, 93, 88, 85, 116, 68,
-  79, 84, 86, 85, 84, 76, 87, 89, 90, 103,
-  93, 75, 81, 67, 93, 77, 89, 71, 70, 101,
-  90, 81, 85, 93, 91, 67, 80, 95, 100, 102,
-  80, 95, 92, 79, 80, 82, 72, 74, 89, 105,
-  77, 85, 83, 86, 86, 89, 73, 107, 89, 76,
-  79, 60, 79, 74, 76, 84, 75, 84, 78, 86,
-  66, 87, 78, 69, 68, 78, 75, 83, 87, 96,
-  80, 90, 72, 75, 94, 77, 89, 109, 76, 78,
-  85, 102, 91, 80, 107, 71, 92, 72, 90, 62,
-  79, 80, 61, 83, 70, 67, 79, 106, 78, 86,
-  85, 78, 71, 80, 92, 70, 93, 77, 89, 87,
-  79, 83, 83, 81, 74, 87, 79, 94, 81, 68,
-  95, 79, 71, 91, 93, 72, 106, 61, 79, 80,
-  80, 82, 86, 91, 84, 92, 86, 88, 83, 76,
-  84, 67, 94, 71, 84, 71, 74, 87, 85, 76,
-  88, 93, 95, 77, 84, 90, 78, 103, 76, 100,
-  95, 85, 92, 83, 86, 72, 82, 109, 98, 85,
-  74, 84, 77, 98, 74, 105, 83, 84, 77, 63,
-  77, 77, 85, 79, 98, 82, 82, 93, 86, 84,
-  72, 75, 67, 79, 81, 72, 92, 86, 83, 101,
-  75, 82, 88, 92, 84, 111, 80, 85, 98, 89,
-  77, 85, 102, 79, 94, 84, 75, 72, 86, 87,
-  70, 94, 75, 83, 82, 103, 80, 95, 88, 82,
-  86, 86, 89, 75, 88, 80, 82, 79, 68, 68,
-  85, 83, 79, 74, 79, 89, 76, 76, 89, 81,
-  72, 83, 90, 74, 76, 72, 79, 92, 85, 75,
-  88, 85, 75, 86, 98, 91, 90, 78, 76, 76,
-  78, 81, 87, 73, 96, 107, 82, 72, 85, 92,
-  98, 69, 84, 88, 97, 99, 89, 81, 96, 78,
-  75, 79, 84, 67, 93, 93, 118, 84, 91, 93,
-  87, 85, 79, 108, 89, 84, 79, 78, 90, 75,
-  73, 82, 86, 79, 78, 91, 80, 85, 73, 83,
-  75, 84, 76, 99, 84, 73, 100, 87, 77, 89,
-  68, 82, 88, 69, 74, 68, 75, 82, 89, 96,
-  82, 76, 77, 102, 84, 91, 81, 93, 93, 80,
-  84, 87, 79, 81, 80, 98, 87, 67, 88, 74,
-  82, 84, 97, 80, 82, 90, 94, 67, 74, 71,
-  75, 81, 102, 77, 78, 84, 87, 67, 91, 86,
-  79, 95, 88, 96, 95, 93, 87, 78, 84, 86,
-  80, 81, 104, 79, 94, 81, 70, 80, 88, 86,
-  82, 81, 95, 90, 76, 77, 67, 82, 79, 104,
-  76, 78, 84, 76, 78, 80, 76, 92, 76, 83,
-  82, 74, 73, 84, 87, 71, 92, 84, 96, 89,
-  80, 85, 94, 78, 80, 90, 82, 77, 63, 77,
-  94, 85, 73, 77, 82, 92, 103, 69, 87, 92,
-  96, 90, 89, 83, 131, 71, 72, 77, 83, 94,
-  87, 82, 100, 91, 63, 78, 98, 85, 90, 84,
-  82, 70, 64, 91, 77, 67, 84, 76, 81, 83,
-  93, 92, 73, 80, 77, 72, 79, 72, 67, 67,
-  89, 100, 104, 103, 85, 90, 64, 68, 85, 89,
-  91, 90, 72, 100, 67, 89, 80, 79, 187, 105,
-  86, 73, 78, 82, 67, 78, 77, 89, 77, 94,
-  65, 79, 79, 108, 84, 96, 79, 95, 113, 60,
-  86, 56, 81, 109, 93, 84, 107, 68, 97, 69,
-  89, 88, 92, 99, 79, 80, 76, 87, 77, 99,
-  100, 87, 85, 142, 84, 77, 68, 91, 82, 67,
-  93, 87, 87, 85, 80, 115, 67, 70, 85, 75,
-  73, 82, 89, 80, 87, 76, 88, 90, 98, 92,
-  77, 80, 80, 79, 91, 77, 78, 88, 86, 105,
-  92, 105, 67, 79, 80, 83, 89, 81, 84, 78,
-  74, 85, 88, 70, 86, 83, 89, 88, 90, 87,
-  75, 86, 80, 72, 85, 70, 63, 71, 81, 91,
-  103, 94, 86, 89, 67, 60, 67, 83, 86, 83,
-  77, 93, 67, 83, 81, 85, 139, 82, 86, 78,
-  82, 87, 78, 83, 79, 90, 81, 89, 74, 79,
-  91, 112, 83, 90, 87, 91, 107, 66, 81, 71,
-  82, 111, 83, 80, 94, 75, 87, 74, 84, 84,
-  90, 91, 78, 83, 80, 78, 73, 91, 93, 81,
-  79, 114, 89, 79, 80, 92, 83, 65, 88, 87,
-  83, 73, 89, 76, 84, 84, 81, 82, 83, 81,
-  84, 84, 76, 86, 74, 85, 78, 90, 78, 80,
-  77, 93, 83, 94, 72, 81, 85, 71, 79, 72,
-  81, 87, 94, 92, 74, 82, 75, 105, 85, 90,
-  94, 96, 84, 84, 81, 88, 81, 82, 84, 107,
-  86, 72, 84, 69, 83, 87, 96, 80, 76, 85,
-  90, 69, 78, 78, 74, 74, 92, 78, 80, 70,
-  91, 80, 91, 85, 73, 93, 84, 94, 93, 91,
-  95, 76, 84, 80, 83, 80, 104, 87, 100, 79,
-  71, 83, 89, 85, 80, 90, 88, 97, 76, 85,
-  71, 84, 75, 91, 75, 83, 90, 79, 83, 87,
-  83, 90, 72, 82, 78, 79, 81, 81, 74, 72,
-  91, 85, 93, 77, 80, 88, 89, 74, 79, 87,
-  83, 73, 73, 89, 84, 89, 71, 71, 69, 81,
-  97, 74, 76, 78, 82, 95, 81, 81, 97, 81,
-  79, 86, 92, 88, 88, 91, 77, 91, 80, 90,
-  122, 98, 88, 100, 76, 76, 68, 81, 78, 72,
-  61, 89, 86, 77, 101, 96, 73, 86, 81, 70,
-  72, 70, 75, 74, 87, 97, 84, 100, 81, 82,
-  69, 73, 66, 90, 104, 79, 84, 94, 97, 83,
-  88, 91, 132, 106, 105, 73, 78, 79, 81, 81,
-  84, 88, 88, 95, 67, 79, 86, 81, 82, 88,
-  95, 80, 85, 70, 87, 74, 77, 89, 90, 87,
-  87, 98, 83, 76, 80, 76, 72, 99, 78, 84,
-  74, 83, 73, 90, 83, 102, 72, 105, 75, 77,
-  71, 78, 73, 74, 86, 83, 92, 82, 76, 95,
-  73, 81, 81, 80, 74, 72, 73, 75, 89, 76,
-  76, 80, 86, 98, 88, 80, 85, 83, 83, 87,
-  85, 88, 89, 127, 74, 102, 80, 83, 83, 89,
-  83, 95, 85, 82, 75, 80, 80, 72, 71, 84,
-  81, 87, 100, 92, 75, 82, 80, 71, 78, 75,
-  69, 78, 77, 95, 80, 96, 88, 88, 78, 69,
-  65, 89, 97, 88, 69, 94, 92, 85, 84, 96,
-  122, 80, 88, 80, 79, 84, 83, 93, 84, 101,
-  83, 91, 69, 75, 95, 79, 81, 83, 88, 80,
-  91, 76, 82, 81, 81, 89, 84, 84, 82, 99,
-  83, 78, 77, 72, 74, 95, 76, 77, 78, 83,
-  90, 85, 84, 97, 83, 95, 78, 79, 79, 84,
-  75, 71, 85, 86, 82, 78, 84, 93, 86, 75,
-  81, 84, 82, 78, 90, 85, 81, 84, 74, 81,
-  87, 85, 81, 88, 69, 84, 97, 81, 82, 83,
-  79, 80, 78, 79, 83, 83, 76, 80, 81, 84,
-  83, 89, 85, 88, 90, 100, 96, 86, 79, 86,
-  82, 76, 83, 100, 81, 79, 80, 80, 85, 92,
-  88, 84, 85, 82, 87, 84, 87, 90, 85, 80,
-  82, 84, 81, 62, 80, 79, 86, 77, 80, 85,
-  83, 93, 88, 92, 93, 83, 90, 81, 77, 78,
-  90, 85, 95, 80, 72, 87, 84, 82, 95, 97,
-  83, 100, 84, 90, 78, 85, 82, 82, 75, 88,
-  89, 73, 94, 86, 84, 79, 85, 87, 87, 83,
-  90, 75, 81, 78, 79, 82, 88, 81, 88, 89,
-  89, 81, 75, 77, 87, 76, 90, 75, 79, 85,
-  75, 71, 82, 84, 80, 85, 67, 81, 84, 83,
-  84, 84, 73, 91, 89, 92, 84, 84, 81, 75,
-  77, 83, 93, 80, 72, 81, 79, 72, 87, 94,
-  81, 86, 89, 92, 93, 93, 80, 84, 85, 84,
-  82, 100, 84, 72, 84, 80, 90, 93, 90, 78,
-  80, 83, 87, 79, 77, 90, 82, 78, 75, 93,
-  76, 60, 90, 90, 82, 89, 76, 79, 88, 83,
-  91, 92, 93, 77, 89, 77, 81, 81, 83, 90,
-  101, 82, 78, 79, 81, 82, 84, 94, 82, 103,
-  77, 87, 74, 84, 75, 84, 73, 88, 86, 72,
-  80, 91, 82, 78, 81, 82, 74, 80, 82, 79,
-  85, 73, 83, 80, 96, 90, 77, 85, 93, 89,
-  75, 78, 83, 64, 87, 74, 83, 83, 76, 71,
-  80, 82, 74, 86, 65, 82, 85, 87, 87, 85,
-  92, 89, 79, 94, 81, 88, 83, 71, 75, 88,
-  91, 79, 78, 78, 78, 78, 86, 94, 80, 86,
-  89, 90, 100, 89, 77, 91, 82, 81, 79, 95,
-  82, 76, 86, 76, 84, 93, 84, 78, 82, 81,
-  87, 84, 83, 89, 77, 77, 79, 91, 74, 61,
-  90, 87, 82, 90, 81, 82, 82, 87, 89, 92,
-  93, 73, 88, 76, 74, 77, 79, 90, 102, 84,
-  74, 81, 83, 83, 90, 91, 82, 103, 78, 85,
-  77, 84, 77, 84, 77, 86, 90, 66, 81, 88,
-  82, 78, 82, 80, 79, 79, 81, 82, 87, 72,
-  84, 83, 94, 88, 81, 85, 94, 68, 98, 66,
-  82, 81, 78, 73, 82, 83, 70, 84, 86, 80,
-  68, 79, 78, 82, 71, 81, 78, 75, 102, 82,
-  83, 92, 80, 63, 97, 102, 81, 69, 74, 91,
-  96, 77, 79, 84, 91, 84, 82, 77, 89, 72,
-  91, 88, 93, 79, 87, 73, 85, 84, 77, 78,
-  77, 81, 86, 84, 86, 95, 70, 79, 79, 80,
-  100, 90, 88, 96, 82, 99, 73, 102, 96, 97,
-  82, 86, 77, 77, 76, 73, 84, 79, 84, 111,
-  72, 71, 93, 86, 87, 79, 87, 82, 67, 82,
-  84, 74, 85, 94, 90, 88, 91, 93, 72, 98,
-  95, 85, 77, 99, 93, 71, 71, 71, 65, 96,
-  100, 99, 109, 67, 73, 80, 72, 71, 91, 71,
-  88, 107, 81, 80, 97, 79, 85, 67, 85, 71,
-  77, 74, 86, 73, 59, 86, 92, 78, 77, 77,
-  85, 82, 60, 98, 86, 74, 82, 82, 84, 87,
-  91, 51, 101, 106, 75, 77, 75, 81, 103, 69,
-  87, 79, 83, 88, 86, 82, 84, 70, 88, 75,
-  84, 71, 106, 67, 85, 85, 75, 79, 75, 84,
-  88, 81, 91, 86, 62, 75, 81, 85, 88, 88,
-  87, 86, 81, 106, 86, 117, 103, 94, 95, 75,
-  74, 84, 85, 81, 81, 77, 70, 85, 72, 71,
-  83, 92, 91, 85, 98, 93, 64, 84, 86, 80,
-  89, 93, 88, 83, 91, 89, 71, 104, 104, 82,
-  75, 108, 96, 71, 79, 68, 72, 88, 90, 79,
-  75, 62, 63, 81, 69, 71, 82, 83, 84, 104,
-  68, 74, 92, 83, 80, 61, 81, 89, 80, 75,
-  92, 86, 67, 87, 87, 84, 76, 78, 78, 81,
-  80, 105, 90, 74, 73, 80, 83, 93, 92, 66,
-  92, 79, 85, 83, 73, 68, 94, 79, 88, 86,
-  83, 86, 85, 76, 75, 69, 94, 87, 91, 87,
-  84, 74, 84, 86, 78, 81, 79, 85, 86, 89,
-  83, 89, 72, 86, 79, 81, 99, 89, 86, 89,
-  79, 85, 95, 104, 123, 89, 97, 86, 79, 95,
-  86, 77, 83, 83, 79, 81, 75, 73, 92, 87,
-  84, 82, 87, 95, 72, 82, 75, 79, 83, 97,
-  96, 86, 88, 100, 74, 100, 86, 86, 78, 93,
-  92, 74, 81, 73, 67, 102, 85, 95, 82, 74,
-  81, 75, 78, 76, 92, 78, 88, 99, 86, 80,
-  82, 75, 82, 88, 89, 90, 87, 66, 81, 70,
-  71, 78, 87, 81, 78, 86, 73, 88, 69, 85,
-  88, 77, 92, 82, 81, 93, 66, 50, 107, 101,
-  98, 76, 73, 109, 96, 78, 79, 96, 82, 84,
-  84, 87, 97, 81, 97, 85, 93, 95, 93, 75,
-  81, 87, 76, 73, 76, 85, 86, 90, 85, 107,
-  87, 78, 82, 92, 98, 90, 85, 93, 93, 89,
-  91, 78, 75, 91, 76, 74, 77, 71, 78, 73,
-  81, 72, 78, 85, 74, 78, 91, 82, 86, 70,
-  96, 76, 63, 82, 99, 78, 96, 94, 81, 90,
-  77, 97, 81, 100, 99, 76, 80, 111, 81, 57,
-  76, 81, 71, 93, 82, 82, 103, 63, 64, 91,
-  79, 64, 80, 66, 85, 95, 70, 78, 79, 97,
-  82, 92, 94, 71, 92, 66, 86, 54, 49, 80,
-  95, 75, 95, 86, 81, 87, 56, 90, 90, 78,
-  74, 83, 76, 102, 68, 40, 112, 89, 109, 91,
-  79, 91, 92, 67, 83, 110, 88, 93, 76, 102,
-  101, 83, 100, 66, 90, 76, 114, 66, 84, 81,
-  86, 76, 69, 83, 86, 84, 89, 100, 73, 68,
-  79, 102, 73, 92, 102, 98, 90, 83, 73, 91,
-  73, 95, 83, 60, 77, 76, 70, 83, 79, 76,
-  73, 60, 74, 89, 77, 85, 92, 76, 121, 63,
-  54, 82, 86, 85, 100, 89, 84, 87, 63, 76,
-  88, 106, 111, 73, 78, 121, 86, 60, 89, 81,
-  79, 76, 72, 68, 69, 58, 54, 91, 71, 67,
-  68, 75, 70, 91, 67, 78, 86, 89, 92, 74,
-  82, 95, 87, 69, 84, 69, 66, 78, 81, 81,
-  83, 85, 75, 85, 77, 115, 83, 82, 77, 75,
-  74, 88, 77, 51, 93, 73, 95, 85, 69, 74,
-  98, 79, 88, 87, 83, 84, 83, 82, 88, 75,
-  92, 75, 93, 86, 85, 74, 80, 83, 73, 73,
-  77, 79, 89, 95, 84, 96, 82, 82, 82, 83,
-  100, 85, 82, 88, 85, 93, 94, 81, 103, 86,
-  88, 70, 80, 101, 81, 75, 82, 73, 76, 74,
-  78, 89, 89, 93, 85, 74, 89, 79, 65, 78,
-  88, 69, 95, 98, 85, 85, 80, 86, 80, 102,
-  88, 79, 81, 104, 84, 62, 88, 85, 71, 93,
-  79, 83, 98, 69, 67, 90, 78, 68, 78, 72,
-  81, 96, 71, 81, 74, 78, 74, 83, 75, 93,
-  76, 74, 78, 78, 83, 90, 86, 75, 70, 78,
-  74, 82, 87, 86, 94, 75, 93, 83, 76, 93,
-  90, 65, 87, 84, 94, 79, 79, 110, 93, 85,
-  90, 98, 80, 96, 83, 77, 89, 73, 90, 94,
-  95, 89, 83, 82, 83, 90, 78, 76, 78, 92,
-  92, 84, 84, 100, 96, 76, 88, 77, 96, 86,
-  79, 83, 91, 94, 102, 79, 77, 83, 76, 88,
-  86, 77, 92, 68, 78, 77, 82, 100, 73, 87,
-  105, 72, 97, 78, 84, 83, 72, 80, 104, 76,
-  90, 83, 81, 102, 96, 103, 78, 104, 94, 76,
-  87, 93, 74, 69, 79, 84, 78, 86, 77, 87,
-  81, 72, 79, 91, 91, 68, 79, 60, 97, 80,
-  78, 85, 75, 81, 87, 97, 84, 79, 72, 69,
-  81, 60, 71, 88, 92, 79, 82, 88, 83, 86,
-  78, 102, 88, 81, 83, 78, 72, 98, 86, 52,
-  84, 83, 100, 92, 78, 103, 84, 76, 86, 110,
-  80, 94, 91, 80, 102, 77, 89, 72, 90, 77,
-  94, 78, 81, 89, 81, 75, 78, 84, 86, 77,
-  93, 99, 92, 67, 91, 83, 82, 86, 91, 94,
-  89, 102, 78, 85, 72, 89, 77, 83, 83, 78,
-  84, 69, 75, 75, 76, 76, 76, 108, 92, 79,
-  94, 73, 86, 79, 72, 81, 104, 86, 93, 79,
-  81, 98, 84, 85, 74, 109, 89, 75, 86, 102,
-  61, 66, 82, 87, 73, 85, 80, 83, 76, 68,
-  67, 90, 85, 71, 70, 64, 88, 78, 73, 82,
-  75, 83, 92, 74, 78, 96, 79, 71, 82, 77,
-  79, 87, 89, 81, 76, 82, 78, 81, 85, 105,
-  81, 81, 84, 79, 73, 95, 91, 65, 75, 74,
-  94, 88, 78, 81, 88, 85, 87, 92, 80, 98,
-  86, 78, 93, 75, 88, 78, 91, 85, 82, 78,
-  82, 92, 75, 77, 76, 73, 91, 87, 85, 94,
-  87, 79, 86, 73, 94, 83, 87, 87, 85, 98,
-  77, 80, 96, 81, 85, 85, 84, 98, 91, 69,
-  80, 80, 80, 83, 78, 103, 84, 79, 96, 76,
-  83, 77, 73, 83, 93, 75, 90, 87, 85, 95,
-  92, 77, 81, 107, 89, 77, 87, 92, 78, 72,
-  86, 86, 77, 102, 88, 87, 113, 75, 82, 89,
-  98, 73, 80, 70, 97, 79, 81, 88, 75, 72,
-  81, 86, 82, 98, 64, 95, 91, 96, 67, 81,
-  57, 89, 67, 82, 80, 78, 80, 100, 71, 77,
-  97, 83, 78, 77, 101, 85, 101, 74, 82, 90,
-  78, 91, 109, 84, 92, 100, 77, 82, 82, 74,
-  39, 81, 77, 85, 95, 77, 96, 80, 77, 71,
-  76, 77, 93, 92, 103, 65, 91, 82, 75, 83,
-  84, 58, 65, 73, 71, 88, 85, 85, 108, 80,
-  99, 96, 86, 86, 71, 103, 80, 81, 84, 69,
-  86, 94, 77, 79, 85, 92, 73, 84, 99, 87,
-  75, 84, 120, 76, 77, 76, 76, 88, 81, 101,
-  91, 96, 90, 91, 100, 88, 73, 76, 80, 84,
-  83, 86, 81, 98, 70, 83, 91, 59, 77, 81,
-  84, 87, 94, 102, 80, 77, 87, 86, 69, 82,
-  84, 84, 78, 72, 94, 86, 72, 93, 117, 88,
-  79, 93, 77, 64, 87, 84, 60, 65, 86, 93,
-  96, 70, 105, 90, 107, 85, 100, 81, 61, 99,
-  83, 77, 79, 104, 93, 92, 88, 78, 110, 92,
-  81, 98, 80, 93, 78, 73, 79, 93, 83, 77,
-  81, 90, 64, 69, 79, 92, 92, 76, 81, 69,
-  58, 61, 69, 76, 84, 85, 105, 85, 72, 103,
-  73, 62, 78, 93, 89, 76, 88, 79, 98, 77,
-  78, 82, 93, 93, 77, 79, 67, 81, 79, 88,
-  79, 76, 87, 86, 110, 65, 82, 90, 87, 90,
-  92, 85, 88, 76, 81, 81, 80, 97, 70, 84,
-  85, 108, 69, 81, 82, 64, 86, 86, 76, 66,
-  83, 93, 82, 80, 81, 93, 61, 91, 84, 84,
-  93, 59, 87, 73, 81, 83, 89, 92, 92, 87,
-  75, 78, 81, 81, 81, 82, 86, 82, 93, 82,
-  91, 75, 70, 103, 100, 85, 81, 79, 92, 81,
-  92, 89, 81, 78, 86, 93, 98, 88, 90, 84,
-  76, 92, 66, 79, 85, 83, 92, 102, 83, 87,
-  73, 85, 86, 91, 84, 88, 74, 81, 78, 71,
-  94, 85, 62, 74, 70, 89, 82, 104, 76, 74,
-  82, 71, 83, 101, 92, 87, 93, 70, 94, 86,
-  85, 84, 88, 90, 68, 76, 80, 97, 72, 91,
-  92, 88, 105, 81, 78, 83, 92, 82, 86, 99,
-  62, 86, 82, 88, 80, 98, 83, 80, 101, 83,
-  75, 86, 76, 85, 94, 82, 82, 83, 80, 78,
-  96, 88, 65, 86, 76, 75, 91, 72, 67, 97,
-  90, 86, 77, 74, 59, 74, 64, 88, 84, 84,
-  83, 84, 89, 81, 77, 82, 84, 97, 68, 79,
-  88, 73, 88, 104, 86, 75, 68, 77, 80, 82,
-  79, 90, 69, 77, 16, 79, 92, 88, 99, 64,
-  105, 86, 88, 72, 84, 85, 80, 60, 118, 72,
-  92, 90, 79, 79, 93, 68, 52, 91, 78, 88,
-  89, 81, 60, 71, 95, 88, 91, 103, 77, 70,
-  81, 90, 86, 84, 82, 93, 86, 81, 73, 79,
-  83, 110, 118, 61, 71, 90, 113, 80, 74, 81,
-  69, 93, 82, 68, 85, 97, 94, 81, 90, 93,
-  82, 83, 80, 70, 99, 83, 75, 79, 79, 85,
-  91, 77, 82, 86, 82, 107, 98, 90, 82, 83,
-  75, 90, 77, 79, 73, 103, 59, 86, 82, 99,
-  67, 86, 67, 71, 69, 74, 76, 80, 74, 109,
-  68, 75, 78, 91, 76, 73, 108, 81, 124, 65,
-  73, 90, 65, 79, 94, 95, 77, 87, 80, 76,
-  79, 65, 79, 66, 82, 95, 73, 86, 85, 76,
-  77, 72, 87, 70, 104, 94, 95, 53, 80, 74,
-  91, 86, 80, 59, 55, 65, 50, 94, 74, 102,
-  142, 69, 86, 87, 84, 80, 72, 92, 79, 63,
-  78, 67, 82, 98, 60, 80, 91, 105, 49, 71,
-  98, 87, 68, 72, 127, 72, 84, 74, 71, 71,
-  84, 116, 89, 92, 90, 89, 106, 74, 72, 64,
-  77, 102, 80, 100, 70, 88, 60, 74, 73, 57,
-  77, 86, 67, 74, 83, 87, 69, 72, 78, 91,
-  64, 91, 87, 76, 80, 66, 90, 87, 80, 91,
-  118, 82, 81, 85, 75, 72, 83, 80, 81, 68,
-  86, 94, 91, 83, 106, 88, 88, 95, 103, 83,
-  66, 91, 79, 80, 84, 90, 87, 91, 84, 81,
-  113, 91, 81, 100, 66, 87, 77, 82, 86, 102,
-  96, 89, 82, 101, 66, 72, 84, 83, 83, 84,
-  70, 94, 71, 71, 84, 84, 72, 77, 69, 89,
-  79, 102, 71, 74, 76, 78, 80, 92, 91, 83,
-  100, 87, 83, 88, 90, 88, 78, 80, 67, 75,
-  86, 103, 66, 90, 92, 85, 99, 67, 81, 85,
-  82, 86, 86, 77, 65, 75, 73, 88, 87, 89,
-  73, 81, 86, 96, 83, 79, 75, 78, 90, 92,
-  83, 70, 85, 81, 87, 77, 79, 79, 88, 68,
-  99, 83, 98, 98, 85, 75, 73, 81, 74, 71,
-  81, 93, 77, 93, 67, 71, 91, 82, 84, 81,
-  91, 88, 63, 69, 71, 83, 81, 89, 100, 74,
-  67, 83, 78, 89, 99, 100, 70, 89, 70, 103,
-  91, 87, 95, 78, 108, 82, 94, 92, 75, 80,
-  67, 89, 103, 101, 89, 84, 72, 77, 92, 74,
-  74, 115, 85, 68, 91, 91, 79, 81, 84, 90,
-  83, 75, 87, 69, 88, 97, 103, 94, 81, 82,
-  99, 86, 78, 81, 104, 116, 73, 80, 79, 82,
-  98, 92, 72, 93, 77, 87, 94, 65, 70, 107,
-  88, 74, 87, 94, 87, 86, 91, 81, 79, 81,
-  82, 89, 88, 85, 101, 91, 71, 84, 76, 96,
-  81, 95, 77, 101, 75, 90, 104, 67, 71, 82,
-  73, 99, 87, 96, 76, 93, 55, 80, 67, 76,
-  77, 84, 81, 99, 73, 92, 84, 92, 89, 84,
-  86, 82, 88, 54, 79, 105, 81, 67, 75, 92,
-  77, 86, 66, 68, 80, 72, 65, 69, 82, 82,
-  84, 80, 88, 77, 103, 82, 97, 74, 94, 63,
-  119, 74, 98, 88, 95, 78, 94, 78, 68, 84,
-  66, 83, 77, 84, 92, 68, 96, 87, 91, 98,
-  72, 82, 73, 66, 89, 86, 81, 102, 81, 88,
-  78, 95, 79, 96, 107, 73, 75, 80, 119, 72,
-  80, 78, 57, 86, 90, 76, 86, 94, 93, 79,
-  110, 91, 78, 74, 80, 85, 83, 96, 82, 76,
-  81, 76, 92, 75, 74, 86, 77, 94, 82, 91,
-  82, 90, 80, 80, 77, 79, 87, 74, 78, 75,
-  82, 96, 78, 93, 123, 76, 63, 66, 70, 72,
-  86, 91, 85, 86, 83, 90, 86, 82, 97, 87,
-  80, 86, 93, 88, 72, 91, 88, 91, 92, 88,
-  90, 92, 87, 76, 101, 88, 79, 104, 65, 103,
-  83, 82, 89, 100, 96, 78, 89, 80, 79, 66,
-  92, 81, 94, 84, 83, 98, 69, 78, 70, 80,
-  80, 85, 104, 81, 89, 93, 73, 82, 77, 77,
-  80, 77, 91, 81, 93, 94, 80, 83, 88, 99,
-  72, 79, 89, 79, 86, 99, 83, 91, 88, 78,
-  73, 74, 82, 94, 84, 88, 80, 85, 80, 85,
-  71, 84, 87, 83, 70, 75, 84, 81, 91, 78,
-  82, 77, 90, 87, 83, 74, 85, 82, 84, 84,
-  70, 77, 81, 86, 62, 97, 86, 76, 91, 101,
-  80, 88, 89, 87, 73, 80, 77, 75, 87, 86,
-  78, 84, 85, 91, 87, 93, 83, 88, 98, 99,
-  76, 86, 73, 89, 75, 95, 94, 89, 81, 64,
-  97, 76, 84, 75, 75, 83, 81, 108, 75, 80,
-  73, 86, 94, 84, 92, 83, 90, 80, 79, 93,
-  89, 105, 85, 84, 94, 72, 76, 78, 77, 86,
-  86, 82, 82, 80, 84, 76, 91, 80, 88, 84,
-  86, 81, 92, 73, 73, 93, 81, 108, 84, 95,
-  79, 80, 77, 87, 104, 89, 80, 73, 100, 102,
-  93, 104, 89, 85, 85, 93, 90, 90, 83, 79,
-  74, 88, 77, 86, 77, 85, 73, 78, 83, 90,
-  79, 82, 103, 96, 71, 90, 83, 82, 69, 91,
-  72, 77, 48, 93, 91, 68, 82, 85, 80, 102,
-  112, 65, 81, 75, 80, 93, 80, 85, 89, 74,
-  91, 85, 91, 97, 80, 64, 102, 98, 88, 82,
-  90, 79, 98, 82, 88, 93, 71, 81, 85, 96,
-  90, 86, 66, 80, 71, 106, 55, 95, 69, 83,
-  99, 87, 80, 72, 79, 71, 81, 93, 90, 76,
-  72, 108, 85, 76, 96, 88, 59, 68, 79, 80,
-  76, 85, 87, 68, 88, 102, 74, 93, 92, 86,
-  101, 76, 87, 88, 82, 97, 82, 88, 53, 67,
-  75, 89, 75, 96, 81, 70, 74, 95, 76, 84,
-  76, 86, 73, 89, 87, 88, 74, 76, 93, 86,
-  69, 83, 82, 96, 73, 77, 89, 99, 83, 85,
-  89, 85, 65, 88, 87, 100, 73, 83, 93, 90,
-  65, 73, 85, 80, 91, 95, 73, 88, 84, 83,
-  69, 87, 81, 71, 82, 81, 80, 87, 95, 91,
-  93, 87, 90, 87, 90, 82, 83, 87, 76, 79,
-  90, 78, 87, 87, 81, 71, 87, 80, 73, 80,
-  74, 85, 92, 74, 85, 79, 69, 79, 85, 77,
-  85, 86, 76, 80, 80, 91, 88, 102, 93, 80,
-  86, 67, 86, 81, 83, 80, 78, 79, 74, 75,
-  90, 84, 95, 91, 84, 78, 82, 78, 103, 86,
-  75, 97, 79, 102, 85, 84, 74, 77, 80, 91,
-  113, 85, 75, 81, 78, 98, 90, 76, 91, 85,
-  85, 93, 87, 93, 83, 76, 89, 85, 80, 74,
-  84, 107, 98, 77, 90, 89, 77, 82, 90, 95,
-  69, 97, 80, 83, 89, 68, 87, 75, 63, 88,
-  82, 82, 86, 93, 77, 83, 80, 76, 69, 76,
-  76, 78, 83, 86, 83, 97, 95, 92, 79, 87,
-  83, 82, 100, 95, 74, 86, 74, 92, 69, 104,
-  84, 89, 82, 61, 100, 67, 80, 75, 87, 76,
-  74, 113, 78, 80, 75, 96, 79, 76, 93, 81,
-  89, 75, 79, 92, 80, 102, 80, 80, 83, 70,
-  84, 77, 73, 81, 85, 80, 91, 86, 86, 80,
-  86, 77, 78, 74, 79, 78, 80, 68, 73, 92,
-  83, 103, 78, 84, 73, 80, 77, 77, 101, 82,
-  83, 77, 84, 94, 90, 105, 90, 82, 94, 103,
-  92, 90, 74, 72, 80, 92, 75, 80, 79, 79,
-  81, 78, 72, 82, 88, 80, 100, 87, 70, 91,
-  70, 81, 91, 95, 81, 73, 47, 81, 96, 77,
-  81, 76, 78, 93, 138, 64, 87, 77, 86, 91,
-  78, 84, 91, 97, 73, 94, 82, 89, 78, 62,
-  101, 88, 97, 87, 94, 85, 89, 80, 72, 92,
-  80, 74, 80, 112, 97, 92, 77, 60, 67, 99,
-  50, 88, 72, 83, 94, 81, 76, 76, 74, 67,
-  75, 89, 79, 70, 65, 123, 57, 80, 93, 80,
-  63, 59, 72, 75, 71, 94, 84, 65, 83, 106,
-  62, 85, 93, 79, 107, 65, 92, 91, 75, 76,
-  91, 80, 54, 51, 69, 81, 60, 88, 83, 73,
-  75, 81, 51, 76, 70, 82, 79, 96, 87, 87,
-  77, 68, 109, 92, 69, 73, 81, 80, 72, 88,
-  98, 80, 75, 86, 90, 77, 63, 80, 77, 108,
-  83, 82, 87, 82, 76, 91, 74, 81, 91, 90,
-  71, 80, 73, 83, 63, 84, 83, 73, 84, 80,
-  77, 108, 79, 92, 80, 83, 88, 87, 93, 81,
-  63, 86, 74, 88, 89, 84, 79, 87, 72, 67,
-  101, 67, 81, 77, 89, 77, 78, 63, 88, 82,
-  72, 86, 70, 74, 89, 85, 81, 77, 84, 88,
-  79, 107, 87, 73, 86, 63, 89, 82, 78, 77,
-  88, 77, 84, 83, 89, 88, 87, 104, 79, 72,
-  75, 74, 95, 96, 72, 95, 79, 101, 73, 81,
-  73, 87, 82, 85, 120, 85, 80, 84, 68, 96,
-  99, 81, 92, 84, 94, 100, 88, 93, 74, 65,
-  83, 94, 78, 82, 77, 97, 108, 74, 75, 91,
-  62, 83, 80, 92, 70, 94, 71, 75, 99, 73,
-  96, 83, 69, 83, 87, 87, 97, 86, 79, 87,
-  92, 79, 76, 80, 82, 74, 86, 87, 78, 96,
-  94, 93, 85, 82, 83, 81, 89, 82, 91, 87,
-  78, 91, 74, 98, 75, 91, 78, 68, 88, 84,
-  85, 73, 84, 75, 86, 103, 76, 87, 74, 92,
-  84, 67, 95, 83, 85, 74, 82, 96, 80, 95,
-  86, 96, 85, 68, 89, 82, 73, 85, 91, 83,
-  105, 91, 88, 89, 88, 78, 84, 79, 76, 76,
-  87, 77, 80, 85, 83, 105, 85, 82, 76, 94,
-  77, 82, 90, 89, 85, 86, 81, 88, 87, 108,
-  93, 82, 98, 97, 97, 95, 79, 78, 97, 85,
-  84, 77, 88, 78, 71, 82, 83, 83, 97, 79,
-  98, 90, 76, 94, 74, 84, 86, 98, 93, 82,
-  55, 78, 90, 82, 97, 75, 76, 93, 135, 72,
-  88, 83, 89, 89, 75, 75, 87, 100, 81, 97,
-  76, 75, 73, 59, 90, 91, 80, 89, 88, 83,
-  86, 87, 76, 95, 84, 78, 87, 92, 84, 92,
-  70, 58, 76, 89, 46, 95, 72, 94, 94, 67,
-  82, 87, 70, 65, 79, 91, 77, 74, 75, 131,
-  84, 76, 92, 82, 71, 80, 100, 77, 91, 94,
-  83, 65, 86, 94, 72, 80, 87, 75, 97, 81,
-  88, 92, 77, 87, 90, 73, 55, 78, 72, 78,
-  61, 89, 75, 79, 87, 78, 71, 95, 72, 78,
-  82, 108, 86, 87, 66, 76, 104, 93, 69, 75,
-  88, 78, 84, 87, 104, 75, 75, 82, 94, 73,
-  66, 88, 78, 91, 96, 96, 67, 83, 77, 88,
-  87, 86, 96, 87, 70, 84, 93, 90, 72, 86,
-  88, 73, 88, 79, 86, 98, 82, 92, 78, 83,
-  85, 88, 81, 82, 81, 88, 81, 79, 83, 81,
-  75, 90, 92, 72, 89, 83, 72, 75, 85, 66,
-  78, 58, 86, 86, 75, 88, 78, 71, 93, 90,
-  80, 77, 79, 94, 84, 92, 94, 85, 81, 65,
-  91, 83, 77, 86, 92, 81, 90, 91, 90, 88,
-  82, 93, 74, 79, 74, 78, 96, 96, 81, 91,
-  75, 91, 78, 82, 75, 97, 80, 85, 100, 92,
-  82, 88, 89, 83, 90, 94, 92, 83, 99, 98,
-  92, 96, 87, 73, 84, 91, 85, 83, 72, 85,
-  106, 80, 85, 92, 65, 82, 84, 93, 71, 96,
-  72, 85, 88, 72, 95, 80, 78, 72, 79, 76,
-  86, 91, 97, 76, 86, 95, 80, 78, 78, 79,
-  79, 82, 76, 93, 77, 79, 99, 88, 96, 85,
-  87, 82, 80, 93, 84, 101, 81, 73, 81, 89,
-  80, 86, 94, 84, 99, 84, 95, 81, 88, 81,
-  86, 80, 97, 83, 82, 62, 71, 72, 86, 84,
-  89, 81, 68, 91, 92, 77, 84, 66, 84, 91,
-  95, 82, 91, 87, 96, 73, 96, 85, 92, 84,
-  76, 85, 74, 85, 93, 97, 83, 85, 92, 87,
-  78, 91, 86, 81, 82, 81, 76, 66, 82, 91,
-  83, 93, 91, 85, 87, 79, 82, 97, 78, 86,
-  84, 77, 79, 87, 99, 78, 94, 79, 91, 84,
-  89, 67, 90, 72, 85, 82, 90, 85, 81, 69,
-  89, 76, 83, 83, 92, 77, 76, 71, 81, 85,
-  89, 79, 93, 92, 78, 73, 80, 82, 76, 90,
-  87, 100, 77, 79, 98, 90, 92, 83, 88, 81,
-  79, 82, 66, 106, 79, 81, 82, 73, 90, 91,
-  95, 92, 83, 97, 101, 62, 81, 76, 84, 92,
-  99, 87, 81, 60, 63, 91, 79, 89, 96, 89,
-  66, 73, 92, 78, 83, 68, 89, 108, 97, 86,
-  84, 102, 89, 79, 105, 73, 88, 83, 82, 78,
-  77, 88, 92, 95, 86, 90, 85, 99, 85, 85,
-  78, 81, 76, 70, 69, 66, 76, 98, 83, 83,
-  92, 103, 94, 78, 67, 108, 84, 89, 81, 86,
-  83, 81, 107, 80, 90, 77, 76, 80, 78, 69,
-  86, 75, 80, 93, 85, 79, 75, 66, 87, 82,
-  83, 87, 80, 77, 73, 79, 89, 91, 96, 82,
-  88, 77, 79, 79, 82, 82, 81, 85, 96, 94,
-  80, 84, 89, 85, 93, 88, 86, 80, 83, 85,
-  74, 89, 75, 97, 84, 83, 91, 89, 94, 86,
-  67, 86, 95, 77, 87, 79, 86, 80, 97, 86,
-  82, 68, 71, 90, 85, 84, 88, 82, 72, 81,
-  88, 79, 77, 72, 81, 94, 99, 83, 86, 89,
-  97, 75, 96, 82, 93, 73, 84, 82, 74, 86,
-  92, 88, 84, 84, 78, 86, 79, 89, 87, 86,
-  81, 77, 73, 67, 80, 93, 87, 92, 89, 98,
-  89, 78, 83, 94, 77, 82, 82, 78, 78, 85,
-  101, 88, 76, 82, 87, 80, 84, 70, 92, 75,
-  87, 84, 89, 82, 88, 67, 91, 71, 89, 77,
-  92, 75, 88, 79, 74, 92, 98, 76, 89, 83,
-  82, 78, 79, 77, 75, 90, 80, 94, 71, 78,
-  101, 85, 76, 89, 90, 86, 91, 90, 73, 127,
-  74, 71, 73, 74, 87, 77, 96, 87, 123, 92,
-  106, 80, 80, 80, 80, 76, 89, 81, 80, 64,
-  65, 82, 87, 90, 88, 90, 75, 83, 91, 73,
-  76, 70, 79, 97, 82, 81, 90, 83, 85, 75,
-  88, 91, 82, 84, 77, 84, 77, 90, 84, 96,
-  83, 82, 88, 95, 74, 89, 72, 87, 84, 73,
-  71, 70, 78, 95, 69, 87, 78, 82, 87, 81,
-  85, 93, 79, 88, 81, 80, 80, 94, 111, 82,
-  88, 74, 84, 75, 84, 72, 78, 79, 77, 89,
-  86, 77, 87, 58, 91, 77, 74, 80, 101, 70,
-  90, 73, 69, 85, 93, 76, 90, 92, 76, 79,
-  80, 74, 68, 109, 100, 97, 74, 84, 97, 89,
-  70, 81, 91, 84, 88, 70, 60, 132, 93, 83,
-  77, 66, 92, 87, 121, 101, 100, 108, 123, 58,
-  80, 72, 86, 95, 85, 85, 79, 59, 54, 92,
-  84, 98, 95, 99, 67, 62, 97, 80, 73, 77,
-  83, 117, 83, 70, 78, 98, 77, 77, 98, 72,
-  73, 88, 83, 79, 82, 97, 81, 78, 87, 85,
-  85, 98, 79, 78, 67, 82, 76, 56, 64, 64,
-  69, 95, 74, 77, 86, 88, 88, 82, 73, 95,
-  85, 91, 69, 84, 87, 84, 113, 80, 90, 59,
-  71, 68, 70, 80, 82, 70, 70, 106, 76, 74,
-  74, 60, 90, 89, 84, 83, 92, 69, 88, 80,
-  75, 92, 98, 79, 92, 87, 79, 79, 82, 78,
-  76, 102, 118, 92, 87, 86, 88, 88, 77, 86,
-  89, 79, 91, 74, 68, 99, 76, 100, 75, 75,
-  95, 83, 101, 88, 74, 92, 111, 73, 76, 76,
-  80, 79, 86, 88, 78, 68, 66, 82, 85, 90,
-  84, 88, 75, 75, 91, 78, 74, 76, 81, 99,
-  85, 76, 85, 85, 86, 77, 91, 85, 87, 80,
-  80, 86, 77, 92, 86, 76, 86, 83, 81, 89,
-  73, 86, 71, 75, 82, 74, 71, 71, 77, 96,
-  85, 85, 77, 93, 85, 81, 81, 89, 80, 82,
-  77, 78, 90, 91, 110, 85, 81, 69, 92, 76,
-  79, 79, 94, 80, 77, 87, 83, 84, 88, 63,
-  84, 76, 78, 84, 71, 82, 88, 86, 85, 85,
-  102, 77, 88, 64, 77, 89, 78, 80, 92, 85,
-  78, 83, 75, 80, 84, 81, 88, 86, 84, 78,
-  81, 93, 90, 108, 80, 79, 84, 85, 81, 72,
-  98, 72, 109, 80, 95, 90, 84, 86, 71, 69,
-  90, 75, 78, 75, 77, 85, 88, 82, 81, 87,
-  78, 87, 85, 84, 77, 68, 75, 80, 76, 78,
-  82, 84, 89, 77, 89, 89, 88, 94, 92, 84,
-  76, 89, 88, 88, 79, 87, 89, 83, 81, 83,
-  75, 86, 85, 83, 78, 75, 86, 92, 72, 96,
-  82, 82, 88, 79, 96, 85, 81, 83, 83, 75,
-  94, 85, 100, 84, 85, 86, 77, 77, 82, 72,
-  81, 78, 84, 80, 85, 87, 92, 77, 81, 80,
-  77, 79, 75, 75, 90, 77, 81, 86, 100, 80,
-  86, 84, 74, 93, 77, 87, 90, 93, 96, 76,
-  84, 79, 82, 83, 87, 85, 90, 80, 77, 83,
-  81, 103, 85, 81, 82, 87, 81, 74, 119, 67,
-  100, 93, 103, 80, 77, 81, 69, 71, 92, 79,
-  74, 76, 70, 90, 91, 86, 83, 85, 70, 73,
-  98, 73, 75, 68, 80, 83, 76, 76, 80, 86,
-  85, 78, 91, 75, 81, 85, 90, 82, 79, 102,
-  80, 84, 85, 90, 88, 78, 90, 87, 70, 88,
-  90, 75, 73, 76, 76, 95, 73, 87, 83, 71,
-  79, 77, 98, 74, 81, 85, 80, 77, 101, 77,
-  101, 82, 88, 75, 75, 79, 77, 80, 94, 71,
-  76, 78, 79, 92, 93, 81, 84, 86, 82, 84,
-  73, 78, 89, 85, 83, 88, 102, 77, 90, 87,
-  74, 87, 77, 83, 95, 91, 101, 81, 91, 82,
-  77, 86, 90, 86, 82, 83, 84, 81, 88, 94,
-  79, 87, 83, 85, 82, 75, 103, 72, 76, 80,
-  100, 81, 76, 88, 73, 69, 88, 82, 78, 80,
-  76, 80, 88, 83, 79, 82, 77, 81, 89, 80,
-  79, 72, 79, 79, 78, 82, 76, 86, 90, 75,
-  92, 85, 88, 80, 84, 84, 76, 86, 86, 84,
-  84, 90, 85, 79, 79, 80, 74, 75, 87, 85,
-  77, 77, 85, 93, 84, 90, 82, 73, 89, 77,
-  96, 86, 84, 80, 83, 77, 105, 84, 100, 83,
-  88, 82, 90, 80, 83, 79, 93, 80, 81, 82,
-  81, 96, 91, 83, 84, 84, 88, 81, 83, 77,
-  74, 95, 93, 72, 86, 90, 110, 87, 58, 104,
-  75, 82, 83, 99, 70, 99, 98, 102, 66, 85,
-  102, 70, 85, 81, 83, 74, 109, 79, 86, 84,
-  86, 97, 82, 95, 83, 59, 87, 75, 79, 106,
-  81, 86, 87, 93, 84, 119, 88, 77, 113, 90,
-  85, 85, 98, 81, 78, 79, 85, 58, 66, 99,
-  82, 87, 77, 62, 94, 70, 109, 86, 68, 83,
-  85, 95, 71, 74, 107, 85, 95, 101, 69, 90,
-  85, 64, 115, 67, 96, 100, 71, 75, 94, 65,
-  67, 78, 93, 104, 71, 76, 81, 71, 84, 84,
-  82, 100, 77, 106, 80, 57, 90, 76, 81, 90,
-  79, 72, 87, 94, 63, 94, 100, 94, 116, 92,
-  78, 128, 89, 72, 86, 83, 84, 73, 70, 81,
-  85, 86, 82, 101, 83, 73, 64, 85, 76, 101,
-  89, 106, 70, 92, 117, 82, 78, 72, 105, 83,
-  91, 84, 94, 93, 111, 77, 80, 89, 69, 100,
-  107, 73, 84, 69, 76, 72, 87, 81, 75, 76,
-  84, 84, 85, 76, 80, 80, 88, 83, 95, 80,
-  85, 82, 84, 86, 93, 69, 55, 89, 112, 103,
-  78, 78, 88, 81, 93, 89, 74, 80, 88, 109,
-  67, 61, 85, 85, 87, 124, 81, 88, 80, 77,
-  75, 74, 96, 91, 88, 76, 86, 78, 81, 73,
-  85, 82, 75, 71, 83, 81, 83, 83, 83, 90,
-  73, 107, 74, 81, 95, 80, 73, 86, 83, 78,
-  88, 80, 74, 86, 89, 87, 78, 89, 83, 92,
-  90, 74, 99, 84, 83, 87, 69, 75, 84, 86,
-  79, 92, 86, 76, 71, 84, 76, 96, 84, 90,
-  88, 83, 89, 75, 86, 73, 88, 83, 83, 87,
-  95, 94, 91, 73, 78, 93, 73, 90, 105, 74,
-  85, 74, 71, 74, 91, 76, 79, 88, 87, 81,
-  80, 73, 80, 85, 77, 91, 84, 78, 76, 90,
-  87, 94, 95, 71, 70, 82, 89, 105, 81, 85,
-  85, 87, 84, 86, 86, 76, 92, 89, 78, 71,
-  70, 80, 79, 109, 93, 79, 91, 84, 71, 79,
-  84, 102, 94, 79, 83, 89, 88, 88, 82, 69,
-  84, 86, 89, 84, 84, 93, 82, 77, 70, 92,
-  82, 111, 86, 80, 76, 83, 80, 81, 86, 75,
-  83, 78, 76, 84, 66, 89, 78, 72, 84, 72,
-  84, 83, 84, 68, 68, 89, 79, 79, 87, 88,
-  93, 79, 59, 81, 82, 102, 85, 107, 68, 85,
-  110, 86, 77, 67, 101, 76, 94, 83, 87, 81,
-  106, 81, 77, 82, 80, 97, 95, 75, 89, 71,
-  79, 74, 83, 90, 77, 79, 83, 83, 71, 88,
-  82, 75, 87, 85, 95, 77, 88, 80, 83, 86,
-  105, 65, 56, 82, 107, 112, 81, 100, 79, 71,
-  96, 98, 70, 88, 85, 105, 72, 77, 88, 71,
-  89, 115, 74, 84, 88, 79, 69, 79, 91, 103,
-  84, 75, 91, 81, 84, 75, 86, 87, 87, 85,
-  87, 83, 70, 86, 86, 87, 64, 96, 70, 99,
-  92, 79, 90, 86, 84, 79, 85, 83, 76, 84,
-  83, 81, 84, 86, 83, 89, 86, 75, 87, 82,
-  89, 77, 82, 76, 72, 91, 79, 97, 74, 66,
-  86, 78, 89, 101, 83, 98, 90, 78, 100, 72,
-  93, 78, 78, 83, 95, 88, 101, 92, 78, 78,
-  69, 79, 60, 90, 119, 70, 86, 75, 65, 92,
-  96, 77, 75, 71, 83, 68, 81, 68, 74, 91,
-  71, 76, 85, 84, 70, 88, 81, 82, 101, 73,
-  60, 75, 92, 103, 88, 90, 75, 81, 70, 84,
-  84, 72, 91, 98, 68, 84, 81, 86, 77, 95,
-  98, 84, 81, 95, 61, 71, 73, 70, 78, 84,
-  70, 101, 90, 90, 80, 67, 67, 69, 90, 90,
-  80, 89, 76, 72, 66, 77, 85, 111, 85, 77,
-  81, 70, 77, 78, 81, 78, 86, 70, 67, 72,
-  66, 88, 84, 56, 94, 76, 88, 82, 91, 80,
-  80, 77, 79, 90, 86, 86, 91, 80, 91, 84,
-  86, 81, 83, 73, 96, 79, 66, 76, 89, 72,
-  80, 84, 92, 93, 93, 82, 78, 79, 81, 79,
-  64, 75, 98, 79, 83, 86, 76, 83, 88, 78,
-  86, 82, 87, 72, 82, 76, 79, 97, 62, 87,
-  75, 88, 76, 86, 85, 91, 91, 79, 78, 82,
-  77, 73, 92, 79, 82, 87, 73, 85, 89, 75,
-  90, 89, 86, 95, 73, 82, 82, 79, 92, 78,
-  87, 95, 70, 80, 78, 88, 87, 83, 72, 87,
-  87, 104, 81, 82, 83, 88, 91, 89, 85, 91,
-  82, 72, 82, 81, 91, 101, 80, 76, 79, 77,
-  82, 77, 85, 88, 98, 72, 79, 76, 68, 89,
-  77, 70, 95, 79, 88, 75, 86, 73, 79, 84,
-  79, 84, 89, 83, 92, 86, 71, 74, 89, 100,
-  86, 95, 72, 81, 98, 83, 94, 75, 87, 88,
-  86, 85, 90, 90, 91, 92, 72, 76, 78, 85,
-  99, 79, 88, 79, 81, 77, 83, 87, 84, 81,
-  80, 81, 78, 82, 75, 83, 86, 86, 92, 87,
-  88, 84, 80, 74, 99, 81, 65, 87, 93, 83,
-  88, 83, 83, 82, 80, 88, 76, 82, 86, 104,
-  71, 87, 80, 76, 80, 107, 82, 86, 89, 83,
-  73, 81, 84, 81, 93, 85, 84, 88, 94, 86,
-  85, 78, 83, 79, 87, 86, 84, 86, 89, 81,
-  75, 83, 73, 91, 84, 81, 91, 86, 72, 81,
-  88, 78, 87, 73, 77, 73, 78, 94, 81, 82,
-  89, 81, 84, 72, 84, 76, 82, 77, 71, 89,
-  86, 94, 81, 81, 92, 80, 90, 93, 78, 83,
-  93, 77, 93, 79, 98, 77, 78, 90, 92, 92,
-  93, 86, 77, 91, 76, 75, 76, 82, 97, 78,
-  92, 81, 76, 83, 84, 82, 85, 76, 83, 76,
-  89, 73, 75, 93, 70, 78, 79, 94, 81, 86,
-  82, 81, 93, 78, 84, 83, 87, 73, 98, 74,
-  84, 92, 74, 81, 84, 77, 86, 91, 68, 92,
-  80, 89, 79, 92, 86, 89, 81, 97, 74, 69,
-  78, 76, 88, 90, 75, 91, 89, 93, 74, 78,
-  79, 74, 87, 88, 82, 86, 91, 74, 80, 80,
-  86, 83, 79, 81, 81, 75, 74, 81, 86, 85,
-  98, 73, 79, 72, 68, 92, 74, 71, 80, 79,
-  84, 79, 82, 74, 76, 79, 73, 97, 87, 95,
-  100, 82, 91, 78, 79, 88, 81, 73, 92, 82,
-  87, 87, 98, 76, 85, 91, 86, 92, 84, 84,
-  81, 96, 79, 82, 84, 81, 93, 85, 87, 84,
-  85, 79, 79, 80, 84, 88, 82, 80, 83, 94,
-  82, 94, 73, 82, 76, 88, 91, 85, 86, 88,
-  91, 78, 92, 90, 91, 74, 97, 84, 91, 93,
-  83, 82, 91, 78, 86, 85, 75, 88, 77, 84,
-  84, 98, 81, 75, 84, 91, 84, 77, 86, 83,
-  96, 89, 81, 76, 83, 89, 76, 93, 86, 89,
-  95, 84, 79, 87, 89, 80, 79, 78, 82, 77,
-  79, 85, 79, 76, 96, 86, 89, 90, 94, 80,
-  91, 73, 81, 87, 77, 84, 80, 98, 87, 75,
-  95, 89, 91, 104, 89, 69, 72, 84, 88, 92,
-  75, 88, 88, 83, 97, 72, 82, 82, 73, 75,
-  82, 87, 82, 82, 73, 65, 78, 85, 101, 97,
-  70, 85, 76, 89, 53, 107, 89, 62, 82, 86,
-  91, 104, 74, 92, 101, 87, 89, 91, 67, 83,
-  67, 93, 92, 95, 85, 66, 75, 74, 77, 77,
-  71, 115, 92, 79, 95, 76, 97, 66, 87, 88,
-  74, 91, 75, 73, 93, 102, 82, 102, 91, 79,
-  94, 83, 82, 74, 88, 96, 79, 93, 85, 90,
-  91, 88, 57, 80, 86, 107, 90, 75, 76, 101,
-  91, 86, 92, 86, 80, 97, 98, 71, 94, 76,
-  83, 109, 81, 82, 93, 93, 70, 84, 91, 86,
-  91, 89, 81, 90, 63, 92, 82, 94, 72, 99,
-  78, 117, 89, 92, 85, 81, 60, 73, 65, 87,
-  82, 73, 109, 106, 81, 77, 95, 84, 71, 93,
-  91, 93, 90, 69, 61, 96, 85, 90, 72, 106,
-  62, 111, 70, 78, 89, 51, 77, 70, 89, 89,
-  57, 84, 91, 70, 102, 70, 78, 83, 81, 87,
-  112, 89, 78, 84, 84, 78, 82, 71, 71, 86,
-  79, 88, 82, 73, 95, 71, 107, 74, 78, 109,
-  63, 79, 63, 87, 82, 98, 77, 93, 83, 96,
-  79, 84, 73, 82, 112, 80, 68, 87, 109, 79,
-  64, 71, 80, 89, 70, 49, 98, 99, 76, 86,
-  103, 77, 65, 77, 80, 69, 104, 90, 64, 88,
-  92, 81, 85, 71, 74, 80, 89, 103, 93, 78,
-  79, 73, 79, 72, 95, 79, 74, 94, 80, 88,
-  91, 91, 75, 89, 126, 86, 60, 79, 75, 78,
-  93, 87, 90, 78, 79, 93, 78, 80, 102, 91,
-  77, 101, 84, 95, 83, 93, 80, 82, 70, 99,
-  82, 81, 92, 66, 82, 85, 86, 87, 74, 99,
-  70, 92, 79, 96, 80, 76, 90, 83, 86, 84,
-  91, 78, 109, 66, 76, 102, 62, 79, 95, 82,
-  74, 112, 82, 88, 89, 77, 67, 81, 74, 77,
-  71, 69, 84, 99, 79, 84, 80, 81, 87, 93,
-  72, 83, 94, 86, 82, 90, 92, 79, 81, 81,
-  92, 76, 83, 70, 80, 99, 87, 89, 73, 80,
-  67, 85, 93, 81, 73, 79, 81, 109, 89, 83,
-  87, 83, 88, 89, 88, 77, 93, 81, 79, 85,
-  83, 90, 66, 93, 89, 74, 73, 109, 89, 89,
-  83, 77, 75, 72, 57, 88, 83, 78, 101, 103,
-  58, 80, 77, 85, 74, 87, 100, 89, 97, 74,
-  68, 87, 75, 77, 72, 90, 93, 92, 76, 84,
-  85, 63, 82, 69, 95, 89, 77, 75, 91, 72,
-  83, 67, 81, 74, 88, 107, 100, 71, 85, 74,
-  92, 74, 82, 56, 49, 86, 79, 94, 82, 97,
-  101, 72, 95, 79, 86, 102, 72, 70, 91, 70,
-  85, 81, 77, 91, 81, 84, 84, 81, 75, 91,
-  87, 86, 71, 89, 107, 69, 73, 75, 93, 81,
-  84, 72, 93, 96, 95, 82, 84, 80, 75, 75,
-  83, 70, 86, 88, 90, 101, 79, 81, 79, 86,
-  83, 84, 82, 98, 87, 78, 79, 75, 86, 72,
-  123, 95, 69, 91, 55, 98, 80, 102, 80, 75,
-  65, 80, 55, 80, 81, 73, 96, 111, 70, 83,
-  98, 81, 71, 72, 113, 93, 118, 77, 62, 93,
-  62, 74, 66, 98, 90, 81, 68, 63, 96, 56,
-  67, 56, 90, 66, 84, 86, 78, 64, 81, 68,
-  80, 65, 97, 78, 100, 61, 76, 80, 106, 79,
-  72, 59, 62, 63, 60, 86, 74, 117, 61, 79,
-  93, 78, 86, 87, 76, 73, 81, 54, 84, 72,
-  72, 106, 73, 98, 83, 101, 55, 73, 87, 78,
-  63, 76, 113, 59, 80, 77, 69, 54, 86, 53,
-  107, 93, 89, 89, 94, 72, 63, 58, 91, 73,
-  70, 86, 92, 81, 99, 69, 58, 81, 82, 84,
-  70, 89, 78, 85, 72, 62, 84, 65, 101, 77,
-  84, 77, 82, 70, 87, 79, 77, 80, 134, 79,
-  69, 81, 84, 71, 85, 90, 94, 69, 70, 99,
-  92, 82, 100, 89, 94, 97, 106, 90, 69, 82,
-  105, 86, 80, 82, 79, 90, 86, 85, 87, 91,
-  81, 88, 106, 104, 67, 87, 80, 94, 90, 73,
-  87, 73, 78, 79, 96, 78, 101, 79, 75, 88,
-  57, 69, 80, 87, 74, 84, 69, 86, 75, 76,
-  85, 63, 79, 73, 95, 69, 91, 91, 91, 88,
-  85, 69, 89, 79, 91, 91, 77, 72, 84, 100,
-  80, 85, 92, 93, 78, 66, 82, 88, 79, 91,
-  106, 67, 72, 88, 77, 82, 106, 80, 58, 78,
-  105, 98, 62, 80, 82, 82, 83, 92, 75, 70,
-  97, 81, 93, 89, 74, 95, 78, 74, 110, 82,
-  75, 76, 93, 78, 84, 78, 86, 88, 57, 76,
-  83, 84, 74, 100, 65, 79, 87, 89, 96, 93,
-  88, 82, 79, 83, 104, 94, 78, 66, 84, 82,
-  106, 87, 86, 80, 82, 81, 85, 85, 86, 80,
-  105, 79, 83, 78, 83, 83, 89, 81, 101, 100,
-  84, 68, 85, 73, 96, 86, 79, 75, 66, 75,
-  87, 88, 86, 79, 76, 88, 85, 95, 100, 85,
-  85, 79, 82, 66, 101, 79, 84, 85, 86, 85,
-  82, 83, 83, 79, 72, 79, 83, 98, 95, 79,
-  98, 90, 111, 71, 82, 71, 80, 94, 89, 66,
-  85, 92, 104, 72, 73, 77, 64, 81, 95, 92,
-  82, 92, 92, 92, 100, 87, 78, 85, 75, 89,
-  83, 83, 81, 80, 98, 72, 100, 84, 85, 64,
-  85, 68, 81, 83, 106, 75, 74, 70, 86, 77,
-  80, 85, 90, 81, 80, 91, 101, 89, 84, 85,
-  93, 77, 122, 94, 78, 79, 89, 80, 93, 86,
-  87, 80, 82, 81, 80, 90, 74, 85, 115, 93,
-  69, 74, 84, 90, 95, 79, 89, 90, 78, 71,
-  87, 78, 102, 91, 79, 83, 74, 66, 95, 88,
-  87, 62, 60, 82, 80, 92, 96, 65, 85, 69,
-  91, 64, 101, 85, 88, 83, 87, 73, 77, 85,
-  81, 77, 68, 75, 88, 106, 82, 84, 102, 101,
-  91, 68, 76, 61, 76, 89, 91, 74, 92, 95,
-  97, 79, 91, 86, 62, 76, 88, 83, 75, 91,
-  87, 88, 90, 86, 80, 74, 78, 97, 85, 92,
-  75, 82, 84, 92, 90, 84, 89, 66, 82, 71,
-  81, 84, 104, 79, 75, 74, 90, 78, 70, 92,
-  92, 89, 97, 92, 91, 81, 78, 78, 75, 84,
-  104, 85, 94, 81, 103, 81, 78, 95, 104, 75,
-  81, 85, 88, 93, 81, 81, 96, 104, 74, 88,
-  91, 94, 98, 95, 84, 84, 76, 80, 98, 77,
-  89, 98, 78, 80, 83, 77, 100, 89, 84, 70,
-  67, 83, 78, 86, 87, 61, 82, 83, 85, 83,
-  98, 101, 92, 79, 80, 67, 82, 84, 82, 85,
-  82, 67, 94, 96, 71, 92, 97, 88, 77, 95,
-  71, 80, 79, 84, 80, 60, 76, 93, 85, 81,
-  86, 88, 74, 87, 103, 96, 86, 101, 80, 90,
-  74, 78, 73, 77, 82, 87, 90, 99, 83, 76,
-  85, 83, 82, 94, 93, 71, 88, 72, 83, 81,
-  101, 84, 89, 74, 79, 92, 73, 79, 74, 89,
-  66, 93, 97, 79, 82, 76, 102, 100, 102, 89,
-  73, 87, 85, 79, 92, 72, 115, 86, 73, 118,
-  89, 77, 72, 74, 99, 90, 72, 76, 91, 79,
-  85, 76, 71, 95, 92, 94, 103, 88, 80, 87,
-  83, 113, 68, 81, 66, 75, 100, 95, 106, 103,
-  76, 89, 86, 76, 86, 63, 85, 78, 81, 87,
-  84, 88, 92, 64, 81, 85, 89, 74, 82, 79,
-  87, 72, 86, 84, 75, 91, 87, 56, 84, 84,
-  85, 84, 89, 102, 69, 92, 85, 89, 72, 97,
-  85, 74, 79, 77, 73, 81, 100, 81, 90, 80,
-  73, 64, 90, 82, 93, 75, 73, 87, 85, 72,
-  91, 69, 97, 65, 78, 76, 82, 88, 107, 107,
-  98, 65, 81, 78, 63, 73, 79, 107, 74, 106,
-  83, 85, 81, 72, 97, 88, 115, 95, 69, 81,
-  97, 80, 93, 68, 86, 100, 59, 155, 84, 85,
-  67, 70, 92, 78, 73, 80, 75, 97, 93, 75,
-  70, 77, 88, 87, 111, 80, 83, 85, 78, 125,
-  59, 83, 64, 70, 113, 75, 90, 111, 71, 77,
-  96, 69, 91, 83, 91, 83, 82, 85, 89, 68,
-  100, 59, 70, 80, 91, 76, 82, 66, 92, 79,
-  78, 90, 70, 93, 101, 63, 77, 83, 84, 86,
-  88, 100, 59, 90, 91, 91, 95, 96, 82, 75,
-  86, 75, 75, 82, 100, 86, 85, 83, 80, 59,
-  97, 70, 94, 82, 94, 83, 87, 86, 84, 79,
-  83, 81, 86, 80, 80, 71, 72, 105, 78, 75,
-  79, 91, 84, 82, 95, 88, 91, 82, 77, 78,
-  87, 90, 87, 77, 94, 87, 83, 71, 90, 92,
-  90, 77, 72, 81, 85, 99, 77, 70, 81, 84,
-  90, 73, 74, 72, 96, 78, 80, 83, 77, 75,
-  89, 82, 96, 99, 84, 78, 94, 79, 73, 71,
-  64, 86, 97, 87, 77, 88, 84, 89, 96, 86,
-  78, 96, 96, 75, 83, 81, 84, 76, 82, 68,
-  84, 83, 89, 80, 92, 83, 96, 76, 100, 88,
-  90, 87, 84, 69, 91, 105, 81, 83, 88, 97,
-  74, 90, 87, 86, 93, 90, 87, 90, 85, 74,
-  97, 90, 90, 81, 96, 71, 77, 71, 92, 82,
-  103, 83, 74, 78, 84, 84, 78, 96, 91, 83,
-  92, 74, 90, 75, 93, 100, 93, 77, 79, 81,
-  75, 68, 80, 96, 60, 99, 86, 79, 93, 80,
-  94, 78, 104, 84, 74, 99, 96, 75, 75, 79,
-  70, 80, 98, 117, 103, 75, 80, 84, 97, 89,
-  82, 79, 100, 90, 81, 76, 80, 90, 78, 94,
-  96, 87, 90, 90, 89, 106, 84, 74, 76, 73,
-  93, 85, 91, 107, 74, 104, 81, 71, 92, 74,
-  78, 83, 94, 88, 86, 71, 84, 84, 80, 81,
-  92, 66, 88, 98, 95, 80, 72, 83, 73, 94,
-  73, 71, 93, 100, 78, 89, 86, 78, 73, 88,
-  81, 79, 87, 84, 76, 76, 89, 91, 65, 85,
-  105, 89, 78, 80, 79, 65, 81, 74, 83, 78,
-  62, 81, 80, 79, 82, 70, 90, 78, 88, 71,
-  90, 76, 103, 88, 98, 85, 77, 76, 66, 69,
-  95, 88, 85, 103, 73, 75, 85, 74, 90, 81,
-  93, 89, 70, 85, 85, 73, 70, 83, 98, 85,
-  108, 125, 89, 85, 85, 77, 85, 76, 81, 90,
-  91, 106, 78, 73, 78, 95, 67, 90, 104, 81,
-  95, 85, 83, 102, 71, 80, 80, 68, 86, 80,
-  89, 112, 70, 110, 78, 65, 100, 83, 70, 90,
-  96, 81, 82, 70, 82, 95, 72, 76, 91, 58,
-  82, 83, 97, 81, 63, 93, 69, 96, 86, 75,
-  87, 99, 73, 94, 75, 70, 65, 86, 75, 79,
-  92, 87, 72, 71, 91, 86, 91, 83, 112, 97,
-  69, 86, 71, 59, 83, 69, 78, 80, 80, 84,
-  83, 85, 82, 80, 82, 81, 88, 77, 85, 73,
-  87, 88, 87, 77, 82, 84, 88, 81, 91, 82,
-  94, 92, 79, 80, 92, 91, 84, 93, 91, 86,
-  83, 78, 87, 92, 78, 79, 100, 77, 93, 97,
-  77, 71, 87, 84, 91, 84, 78, 76, 104, 72,
-  77, 82, 79, 93, 84, 88, 96, 100, 90, 75,
-  93, 83, 76, 72, 67, 88, 95, 84, 82, 96,
-  77, 96, 94, 75, 85, 84, 74, 80, 90, 83,
-  88, 77, 84, 87, 80, 76, 85, 76, 97, 74,
-  90, 81, 76, 74, 84, 91, 98, 73, 96, 103,
-  85, 89, 87, 87, 80, 85, 86, 80, 88, 83,
-  85, 78, 84, 87, 103, 87, 84, 88, 80, 84,
-  85, 74, 83, 76, 89, 82, 87, 79, 84, 90,
-  82, 82, 81, 86, 80, 85, 81, 93, 89, 92,
-  78, 73, 73, 89, 90, 85, 102, 97, 91, 76,
-  84, 83, 96, 99, 94, 71, 82, 83, 95, 86,
-  82, 84, 82, 80, 72, 81, 98, 89, 83, 73,
-  85, 100, 68, 86, 85, 84, 78, 73, 79, 84,
-  80, 76, 89, 69, 82, 85, 93, 73, 83, 86,
-  81, 74, 62, 99, 86, 84, 77, 86, 83, 92,
-  88, 85, 83, 80, 82, 79, 91, 78, 87, 80,
-  82, 89, 94, 87, 74, 74, 90, 80, 92, 85,
-  91, 68, 87, 86, 77, 71, 93, 76, 92, 87,
-  98, 89, 87, 87, 89, 73, 81, 75, 87, 83,
-  78, 75, 81, 88, 84, 81, 80, 76, 80, 76,
-  77, 79, 93, 72, 86, 81, 72, 89, 87, 87,
-  68, 82, 82, 85, 82, 92, 94, 80, 80, 71,
-  72, 86, 92, 84, 90, 97, 90, 73, 78, 79,
-  101, 98, 87, 77, 70, 92, 96, 81, 81, 89,
-  85, 76, 81, 83, 97, 81, 95, 76, 84, 103,
-  69, 69, 77, 94, 80, 81, 80, 84, 88, 76,
-  81, 67, 80, 92, 101, 78, 76, 83, 80, 74,
-  60, 103, 85, 91, 86, 87, 83, 89, 84, 78,
-  83, 80, 82, 82, 89, 74, 88, 82, 73, 92,
-  88, 85, 67, 81, 93, 81, 82, 86, 88, 72,
-  87, 89, 70, 75, 94, 84, 85, 90, 100, 88,
-  88, 86, 97, 72, 76, 83, 80, 80, 81, 63,
-  98, 80, 84, 84, 79, 82, 74, 71, 82, 77,
-  95, 75, 81, 85, 73, 89, 84, 86, 76, 83,
-  79, 86, 82, 83, 98, 85, 85, 80, 76, 88,
-  89, 88, 80, 84, 83, 80, 84, 84, 90, 104,
-  86, 85, 82, 89, 93, 77, 80, 94, 77, 77,
-  104, 77, 102, 94, 96, 76, 86, 93, 70, 75,
-  80, 80, 81, 72, 79, 89, 86, 90, 91, 74,
-  84, 83, 87, 74, 81, 84, 78, 72, 61, 93,
-  91, 86, 84, 85, 82, 88, 90, 78, 79, 81,
-  83, 79, 84, 76, 86, 85, 85, 88, 93, 75,
-  78, 80, 86, 86, 94, 85, 78, 66, 92, 86,
-  82, 78, 97, 85, 87, 86, 96, 87, 87, 84,
-  86, 73, 77, 79, 89, 85, 78, 80, 88, 91,
-  88, 86, 80, 82, 83, 80, 77, 77, 92, 75,
-  71, 77, 81, 80, 94, 85, 83, 79, 77, 89,
-  82, 82, 126, 84, 83, 82, 83, 97, 86, 77,
-  90, 98, 88, 78, 99, 79, 89, 98, 105, 101,
-  79, 79, 56, 73, 75, 79, 89, 73, 97, 87,
-  81, 72, 98, 78, 78, 61, 83, 99, 76, 97,
-  78, 101, 83, 89, 75, 82, 66, 78, 82, 80,
-  88, 67, 82, 121, 92, 76, 80, 72, 69, 99,
-  92, 87, 82, 78, 82, 66, 95, 73, 96, 86,
-  82, 66, 87, 76, 90, 82, 92, 78, 71, 78,
-  58, 76, 71, 84, 84, 76, 85, 79, 91, 84,
-  102, 73, 94, 79, 72, 66, 70, 93, 89, 78,
-  87, 99, 84, 86, 86, 80, 67, 77, 87, 100,
-  100, 99, 76, 98, 77, 77, 86, 86, 72, 73,
-  79, 79, 93, 76, 81, 76, 80, 93, 82, 88,
-  106, 104, 78, 80, 85, 83, 85, 79, 78, 94,
-  72, 85, 97, 82, 83, 97, 92, 76, 93, 88,
-  65, 72, 86, 87, 88, 79, 61, 98, 85, 94,
-  102, 92, 84, 82, 90, 76, 73, 97, 80, 104,
-  81, 84, 82, 59, 69, 80, 86, 79, 84, 79,
-  92, 111, 74, 78, 70, 87, 76, 74, 88, 79,
-  80, 78, 94, 78, 95, 104, 92, 81, 88, 77,
-  94, 72, 88, 76, 82, 73, 82, 82, 60, 85,
-  75, 85, 85, 78, 90, 89, 71, 89, 95, 96,
-  94, 80, 77, 73, 63, 91, 93, 80, 106, 100,
-  81, 80, 96, 86, 74, 85, 90, 86, 76, 86,
-  79, 91, 85, 73, 79, 86, 75, 59, 97, 82,
-  80, 84, 76, 76, 87, 85, 78, 86, 68, 100,
-  77, 88, 92, 79, 80, 93, 81, 65, 80, 84,
-  89, 85, 80, 82, 93, 84, 80, 78, 80, 81,
-  78, 90, 82, 85, 74, 77, 73, 73, 84, 85,
-  83, 103, 97, 90, 80, 80, 85, 72, 80, 84,
-  83, 83, 96, 97, 99, 89, 76, 91, 101, 75,
-  80, 77, 75, 95, 88, 70, 68, 62, 92, 74,
-  90, 99, 83, 85, 82, 80, 94, 91, 86, 79,
-  79, 81, 97, 79, 86, 86, 86, 90, 93, 91,
-  97, 77, 75, 88, 80, 86, 98, 84, 87, 80,
-  98, 81, 86, 85, 81, 82, 87, 78, 71, 79,
-  89, 79, 89, 82, 74, 79, 85, 82, 84, 82,
-  82, 83, 74, 76, 108, 88, 95, 92, 88, 92,
-  84, 81, 76, 83, 84, 81, 118, 101, 97, 77,
-  84, 73, 96, 66, 81, 97, 76, 91, 97, 79,
-  90, 100, 97, 87, 102, 70, 64, 86, 90, 69,
-  75, 81, 91, 82, 78, 105, 85, 80, 63, 51,
-  95, 123, 85, 89, 85, 117, 90, 84, 76, 102,
-  65, 88, 68, 81, 86, 62, 77, 134, 84, 68,
-  80, 66, 93, 74, 82, 115, 59, 94, 76, 70,
-  99, 63, 81, 98, 96, 72, 114, 66, 101, 87,
-  83, 71, 94, 61, 62, 70, 72, 88, 64, 75,
-  98, 88, 100, 92, 79, 75, 94, 76, 81, 85,
-  79, 87, 100, 85, 95, 80, 89, 71, 100, 85,
-  57, 90, 99, 83, 96, 85, 92, 118, 83, 73,
-  86, 94, 78, 79, 86, 83, 85, 77, 83, 77,
-  74, 88, 80, 91, 97, 74, 80, 79, 89, 80,
-  95, 78, 69, 70, 82, 85, 104, 82, 86, 99,
-  83, 84, 80, 88, 69, 64, 73, 87, 79, 80,
-  90, 93, 85, 82, 92, 96, 77, 80, 89, 75,
-  79, 89, 89, 99, 81, 78, 84, 95, 63, 80,
-  77, 85, 80, 72, 84, 86, 86, 61, 77, 77,
-  89, 76, 95, 103, 69, 86, 85, 78, 96, 116,
-  84, 87, 91, 81, 109, 83, 86, 85, 75, 69,
-  83, 76, 67, 66, 76, 91, 63, 78, 94, 96,
-  85, 95, 86, 86, 87, 82, 78, 78, 67, 84,
-  96, 78, 89, 86, 87, 83, 85, 83, 94, 87,
-  88, 80, 62, 78, 75, 99, 86, 75, 81, 79,
-  70, 59, 75, 77, 80, 100, 79, 77, 80, 86,
-  74, 94, 60, 85, 69, 86, 86, 94, 86, 99,
-  87, 59, 78, 80, 87, 88, 79, 83, 81, 85,
-  71, 78, 76, 85, 69, 90, 83, 88, 67, 72,
-  86, 63, 87, 83, 90, 104, 92, 87, 83, 75,
-  92, 63, 78, 83, 88, 78, 97, 88, 103, 88,
-  76, 88, 106, 69, 97, 75, 73, 102, 83, 82,
-  75, 69, 95, 68, 82, 106, 82, 94, 78, 77,
-  86, 89, 80, 86, 73, 76, 105, 78, 77, 89,
-  78, 83, 89, 90, 93, 83, 73, 95, 87, 91,
-  99, 86, 78, 82, 95, 80, 86, 79, 70, 80,
-  79, 75, 73, 94, 83, 84, 85, 84, 77, 85,
-  83, 81, 79, 81, 77, 87, 76, 72, 92, 79,
-  93, 90, 97, 91, 83, 75, 65, 83, 81, 87,
-  88, 80, 83, 80, 83, 80, 90, 80, 86, 100,
-  77, 88, 84, 84, 81, 92, 96, 77, 79, 80,
-  67, 90, 83, 84, 82, 80, 60, 87, 88, 77,
-  76, 71, 81, 83, 75, 120, 84, 91, 76, 83,
-  86, 77, 76, 76, 76, 74, 76, 78, 93, 106,
-  94, 112, 91, 66, 88, 88, 87, 91, 77, 80,
-  86, 91, 65, 78, 95, 73, 88, 93, 87, 66,
-  98, 87, 97, 85, 86, 76, 62, 71, 64, 76,
-  73, 94, 76, 89, 86, 91, 85, 102, 75, 85,
-  91, 77, 96, 84, 82, 85, 75, 75, 80, 90,
-  77, 87, 82, 82, 66, 90, 81, 93, 86, 83,
-  85, 98, 85, 82, 88, 84, 87, 94, 75, 86,
-  84, 80, 83, 74, 70, 82, 81, 91, 99, 60,
-  76, 77, 89, 79, 86, 85, 78, 86, 77, 85,
-  100, 82, 76, 89, 84, 87, 75, 92, 73, 71,
-  71, 94, 79, 90, 123, 88, 95, 85, 70, 85,
-  81, 87, 75, 66, 80, 93, 75, 89, 84, 78,
-  78, 92, 77, 81, 85, 85, 89, 95, 88, 101,
-  83, 78, 89, 87, 93, 84, 86, 80, 83, 89,
-  69, 85, 98, 114, 79, 94, 88, 76, 104, 76,
-  88, 89, 78, 74, 68, 74, 64, 81, 73, 98,
-  71, 82, 86, 99, 94, 98, 80, 72, 85, 81,
-  86, 94, 75, 81, 89, 85, 75, 87, 80, 77,
-  77, 85, 102, 89, 88, 86, 71, 82, 79, 95,
-  83, 79, 87, 85, 78, 74, 62, 84, 74, 102,
-  81, 77, 83, 80, 73, 89, 79, 89, 71, 89,
-  91, 90, 82, 89, 92, 69, 73, 82, 92, 82,
-  80, 79, 91, 81, 84, 78, 77, 81, 71, 88,
-  78, 89, 102, 71, 87, 82, 85, 84, 78, 89,
-  87, 78, 86, 81, 88, 78, 80, 83, 78, 98,
-  95, 93, 94, 83, 77, 78, 103, 76, 87, 79,
-  77, 88, 77, 83, 96, 77, 82, 77, 72, 102,
-  87, 98, 83, 81, 82, 90, 91, 74, 73, 78,
-  97, 80, 91, 92, 77, 86, 81, 86, 86, 75,
-  84, 97, 93, 87, 99, 71, 83, 81, 86, 87,
-  80, 81, 87, 88, 92, 74, 81, 80, 86, 91,
-  85, 82, 83, 83, 95, 79, 88, 91, 71, 83,
-  75, 81, 74, 70, 115, 96, 64, 93, 90, 76,
-  87, 91, 77, 84, 94, 84, 56, 81, 72, 84,
-  85, 102, 110, 95, 100, 82, 78, 73, 89, 79,
-  127, 122, 102, 91, 81, 84, 80, 92, 104, 97,
-  91, 67, 115, 76, 75, 100, 69, 112, 94, 118,
-  77, 88, 75, 99, 88, 79, 110, 87, 89, 73,
-  106, 82, 72, 76, 80, 64, 69, 54, 74, 93,
-  70, 89, 94, 86, 85, 93, 65, 80, 85, 80,
-  94, 64, 86, 71, 96, 101, 74, 92, 92, 91,
-  74, 88, 86, 80, 96, 89, 89, 77, 80, 64,
-  103, 81, 91, 91, 99, 85, 89, 86, 91, 80,
-  80, 68, 81, 94, 74, 93, 80, 90, 103, 92,
-  89, 95, 77, 72, 98, 74, 89, 85, 77, 92,
-  72, 68, 104, 87, 90, 95, 88, 86, 73, 86,
-  78, 80, 89, 96, 72, 75, 85, 88, 88, 88,
-  111, 69, 100, 80, 92, 90, 75, 85, 106, 122,
-  82, 79, 81, 77, 79, 88, 82, 84, 91, 82,
-  83, 79, 68, 79, 78, 92, 79, 102, 84, 84,
-  83, 84, 80, 90, 90, 70, 86, 75, 79, 86,
-  77, 77, 87, 42, 72, 62, 80, 72, 71, 78,
-  75, 84, 85, 89, 77, 68, 75, 84, 76, 98,
-  86, 84, 87, 99, 76, 80, 97, 85, 83, 88,
-  73, 65, 71, 97, 75, 84, 86, 75, 89, 79,
-  73, 73, 84, 85, 81, 74, 84, 77, 84, 79,
-  95, 83, 87, 93, 70, 73, 106, 85, 74, 81,
-  89, 82, 97, 82, 76, 90, 86, 85, 83, 68,
-  81, 83, 99, 69, 81, 91, 77, 76, 84, 83,
-  93, 94, 86, 65, 94, 91, 87, 75, 97, 75,
-  87, 79, 94, 86, 69, 83, 95, 96, 74, 78,
-  82, 74, 76, 76, 61, 78, 102, 103, 67, 88,
-  72, 79, 78, 74, 78, 80, 89, 86, 89, 90,
-  81, 96, 63, 81, 80, 80, 72, 86, 87, 81,
-  85, 57, 79, 91, 93, 80, 78, 75, 72, 87,
-  77, 76, 91, 70, 80, 80, 78, 107, 82, 91,
-  81, 85, 89, 70, 97, 87, 83, 88, 78, 62,
-  71, 92, 72, 90, 90, 98, 93, 84, 76, 66,
-  74, 84, 83, 82, 84, 81, 74, 88, 83, 82,
-  92, 92, 73, 80, 91, 88, 75, 72, 88, 89,
-  70, 85, 67, 97, 85, 81, 77, 72, 100, 90,
-  82, 83, 89, 86, 79, 91, 83, 82, 84, 88,
-  65, 74, 78, 85, 88, 85, 109, 90, 97, 78,
-  88, 86, 84, 88, 99, 116, 87, 84, 77, 76,
-  67, 79, 72, 79, 96, 70, 88, 53, 73, 81,
-  76, 89, 83, 86, 84, 86, 69, 85, 80, 85,
-  90, 89, 82, 86, 84, 90, 83, 85, 93, 83,
-  69, 65, 76, 80, 62, 89, 71, 75, 91, 93,
-  68, 72, 75, 80, 92, 67, 91, 76, 85, 100,
-  71, 92, 85, 86, 78, 83, 85, 69, 76, 90,
-  74, 87, 81, 68, 75, 84, 79, 78, 91, 75,
-  77, 84, 79, 88, 106, 74, 83, 85, 84, 82,
-  78, 82, 113, 82, 85, 96, 93, 84, 96, 80,
-  83, 88, 83, 78, 77, 78, 88, 82, 90, 68,
-  87, 91, 86, 86, 90, 89, 83, 92, 89, 76,
-  93, 89, 92, 78, 98, 81, 77, 77, 98, 83,
-  75, 88, 88, 94, 81, 80, 88, 75, 80, 83,
-  63, 81, 108, 90, 72, 74, 67, 76, 92, 73,
-  80, 71, 86, 85, 94, 84, 75, 95, 82, 86,
-  83, 99, 79, 87, 82, 92, 93, 71, 67, 93,
-  86, 71, 72, 77, 70, 85, 83, 79, 84, 71,
-  81, 87, 64, 98, 90, 92, 80, 87, 93, 89,
-  84, 80, 90, 80, 78, 62, 75, 95, 71, 93,
-  83, 91, 74, 88, 77, 63, 88, 79, 79, 83,
-  81, 94, 88, 83, 94, 84, 93, 79, 78, 78,
-  81, 86, 84, 82, 90, 93, 69, 84, 67, 88,
-  89, 76, 84, 81, 80, 85, 79, 84, 78, 90,
-  92, 81, 91, 85, 93, 84, 92, 74, 91, 95,
-  77, 75, 84, 89, 86, 80, 94, 76, 76, 83,
-  77, 82, 78, 85, 82, 78, 87, 85, 75, 86,
-  99, 89, 74, 101, 84, 81, 84, 77, 88, 82,
-  87, 91, 91, 85, 85, 88, 76, 84, 84, 100,
-  80, 75, 89, 92, 84, 89, 91, 110, 95, 70,
-  80, 84, 79, 89, 78, 82, 88, 79, 89, 88,
-  65, 95, 86, 88, 76, 84, 95, 80, 82, 88,
-  81, 77, 78, 77, 85, 80, 78, 89, 80, 97,
-  84, 89, 90, 80, 80, 82, 80, 89, 84, 89,
-  64, 90, 75, 88, 94, 85, 82, 91, 80, 87,
-  86, 83, 79, 88, 61, 80, 70, 81, 89, 88,
-  78, 71, 94, 88, 82, 96, 81, 85, 76, 84,
-  89, 87, 83, 86, 81, 74, 79, 100, 86, 79,
-  101, 79, 83, 83, 100, 83, 82, 87, 97, 102,
-  90, 83, 78, 77, 71, 82, 62, 81, 103, 82,
-  76, 58, 69, 76, 86, 83, 92, 66, 88, 82,
-  89, 85, 78, 90, 73, 94, 74, 94, 81, 93,
-  86, 84, 88, 92, 83, 83, 91, 74, 63, 76,
-  85, 80, 87, 84, 76, 69, 77, 83, 72, 80,
-  89, 92, 79, 96, 75, 89, 87, 82, 90, 85,
-  76, 73, 77, 96, 72, 91, 79, 82, 66, 83,
-  81, 71, 87, 77, 85, 84, 74, 88, 92, 89,
-  97, 89, 88, 81, 77, 80, 108, 82, 83, 86,
-  94, 88, 71, 83, 72, 89, 84, 73, 84, 75,
-  84, 87, 82, 74, 81, 85, 86, 84, 89, 94,
-  84, 84, 95, 76, 88, 96, 82, 77, 82, 79,
-  80, 79, 100, 79, 84, 85, 81, 99, 85, 82,
-  88, 77, 91, 79, 76, 83, 102, 91, 76, 93,
-  77, 80, 99, 70, 87, 67, 92, 80, 92, 82,
-  84, 90, 81, 89, 85, 99, 81, 84, 82, 96,
-  88, 87, 80, 106, 87, 78, 71, 86, 74, 94,
-  81, 76, 87, 77, 90, 83, 60, 91, 84, 91,
-  74, 85, 92, 86, 79, 84, 88, 80, 77, 76,
-  88, 98, 78, 92, 84, 96, 73, 90, 86, 71,
-  84, 84, 84, 85, 83, 89, 81, 90, 91, 89,
-  93, 77, 83, 83, 71, 90, 85, 86, 85, 90,
-  54, 84, 66, 83, 85, 82, 87, 83, 79, 91,
-  76, 87, 76, 83, 93, 85, 86, 86, 96, 78,
-  88, 76, 85, 99, 76, 78, 81, 84, 92, 83,
-  99, 75, 92, 82, 69, 92, 86, 87, 86, 82,
-  95, 80, 85, 77, 86, 81, 81, 111, 91, 83,
-  85, 74, 100, 82, 86, 86, 84, 76, 93, 82,
-  86, 89, 87, 100, 82, 82, 84, 96, 96, 97,
-  97, 102, 83, 82, 73, 93, 84, 98, 80, 83,
-  91, 84, 92, 86, 77, 77, 80, 87, 79, 90,
-  92, 74, 80, 86, 85, 80, 86, 92, 97, 89,
-  89, 85, 76, 86, 82, 84, 92, 90, 80, 83,
-  83, 84, 86, 93, 77, 87, 76, 93, 88, 85,
-  84, 84, 79, 85, 90, 87, 76, 85, 68, 77,
-  81, 75, 85, 92, 107, 78, 97, 92, 71, 103,
-  76, 79, 69, 90, 76, 88, 86, 74, 73, 85,
-  85, 85, 93, 76, 86, 70, 106, 87, 94, 77,
-  83, 85, 93, 95, 87, 86, 80, 73, 90, 88,
-  91, 77, 66, 82, 79, 89, 70, 88, 81, 86,
-  81, 84, 77, 78, 99, 90, 91, 79, 89, 99,
-  82, 90, 60, 81, 73, 73, 87, 79, 95, 61,
-  83, 89, 86, 66, 85, 85, 68, 77, 76, 80,
-  86, 107, 96, 96, 81, 96, 76, 72, 72, 76,
-  94, 81, 107, 69, 67, 80, 84, 72, 87, 78,
-  83, 83, 89, 80, 86, 91, 75, 86, 97, 95,
-  72, 83, 83, 79, 81, 74, 92, 79, 109, 103,
-  87, 92, 85, 79, 108, 68, 84, 91, 81, 100,
-  91, 83, 123, 94, 102, 92, 73, 83, 74, 81,
-  72, 83, 76, 95, 106, 88, 76, 84, 82, 72,
-  89, 67, 80, 82, 81, 84, 83, 77, 85, 83,
-  92, 91, 92, 98, 79, 81, 90, 79, 94, 77,
-  83, 76, 74, 85, 82, 92, 80, 73, 85, 93,
-  76, 73, 93, 108, 93, 90, 83, 114, 77, 84,
-  49, 84, 76, 67, 89, 78, 87, 60, 89, 74,
-  89, 61, 99, 87, 54, 80, 79, 72, 84, 88,
-  101, 97, 79, 110, 88, 82, 73, 86, 79, 83,
-  125, 73, 68, 80, 79, 67, 71, 75, 91, 74,
-  90, 82, 83, 82, 74, 85, 98, 95, 78, 88,
-  98, 76, 89, 70, 91, 75, 112, 96, 80, 101,
-  93, 85, 98, 70, 81, 89, 80, 92, 86, 95,
-  97, 97, 88, 93, 74, 104, 77, 80, 64, 89,
-  81, 84, 86, 86, 71, 86, 83, 85, 99, 80,
-  76, 74, 97, 86, 85, 78, 84, 83, 94, 87,
-  84, 99, 77, 84, 90, 82, 92, 73, 73, 81,
-  84, 83, 82, 91, 82, 75, 80, 106, 77, 81,
-  101, 81, 90, 87, 95, 92, 89, 88, 66, 82,
-  78, 81, 88, 85, 100, 62, 90, 85, 73, 73,
-  95, 88, 69, 78, 88, 82, 83, 80, 96, 90,
-  83, 96, 80, 90, 78, 80, 86, 81, 103, 83,
-  70, 84, 85, 75, 83, 78, 87, 81, 84, 72,
-  87, 80, 77, 83, 97, 90, 80, 85, 84, 79,
-  68, 80, 90, 94, 102, 91, 83, 92, 89, 92,
-  88, 74, 79, 94, 86, 90, 91, 84, 96, 77,
-  99, 84, 87, 95, 69, 77, 88, 87, 78, 89,
-  83, 82, 74, 75, 74, 72, 75, 77, 93, 76,
-  81, 85, 88, 85, 83, 81, 97, 78, 79, 92,
-  87, 86, 85, 95, 75, 85, 57, 78, 74, 88,
-  91, 78, 88, 100, 69, 89, 88, 84, 93, 82,
-  87, 93, 83, 67, 79, 78, 64, 81, 71, 96,
-  68, 79, 82, 86, 85, 98, 86, 49, 88, 90,
-  77, 81, 63, 88, 79, 83, 77, 91, 80, 78,
-  80, 75, 73, 92, 88, 77, 96, 74, 75, 76,
-  86, 81, 90, 90, 78, 90, 76, 97, 73, 100,
-  77, 86, 78, 111, 74, 83, 82, 67, 83, 75,
-  76, 85, 112, 91, 70, 92, 79, 101, 84, 79,
-  80, 80, 83, 89, 81, 86, 90, 79, 89, 78,
-  96, 75, 66, 77, 90, 84, 84, 92, 73, 68,
-  73, 75, 70, 66, 62, 75, 96, 80, 78, 90,
-  80, 82, 91, 78, 100, 83, 68, 86, 83, 87,
-  81, 94, 73, 89, 71, 67, 76, 75, 93, 70,
-  100, 102, 59, 88, 89, 74, 85, 56, 89, 98,
-  64, 100, 86, 70, 61, 81, 70, 105, 63, 81,
-  67, 91, 95, 97, 85, 43, 90, 91, 80, 78,
-  57, 80, 83, 83, 80, 94, 81, 78, 82, 85,
-  76, 100, 81, 77, 72, 77, 74, 73, 80, 72,
-  74, 87, 79, 95, 91, 107, 72, 87, 79, 88,
-  78, 128, 83, 73, 87, 64, 67, 68, 73, 80,
-  108, 100, 85, 99, 76, 119, 80, 82, 71, 79,
-  78, 83, 84, 89, 94, 79, 84, 87, 86, 81,
-  73, 75, 84, 87, 86, 84, 92, 68, 72, 80,
-  76, 74, 77, 82, 92, 75, 97, 87, 79, 84,
-  85, 80, 97, 88, 74, 86, 86, 81, 85, 88,
-  73, 85, 90, 77, 75, 80, 89, 83, 94, 83,
-  64, 88, 88, 84, 96, 69, 87, 96, 82, 118,
-  89, 82, 66, 85, 71, 86, 69, 85, 81, 91,
-  93, 101, 82, 75, 84, 97, 77, 80, 67, 86,
-  80, 84, 78, 84, 83, 79, 82, 83, 77, 92,
-  84, 83, 92, 83, 73, 76, 84, 76, 73, 83,
-  79, 91, 102, 91, 82, 72, 78, 84, 83, 108,
-  88, 78, 87, 65, 59, 78, 79, 83, 91, 94,
-  93, 88, 77, 103, 81, 85, 73, 88, 87, 86,
-  81, 83, 93, 76, 98, 86, 96, 86, 74, 76,
-  83, 85, 76, 86, 88, 85, 63, 86, 80, 85,
-  90, 83, 86, 86, 84, 79, 90, 87, 83, 81,
-  89, 70, 78, 91, 97, 96, 73, 83, 88, 78,
-  74, 91, 78, 90, 82, 83, 86, 98, 81, 88,
-  78, 89, 68, 71, 87, 82, 96, 76, 83, 62,
-  79, 80, 82, 89, 87, 71, 87, 85, 90, 99,
-  76, 83, 98, 81, 86, 86, 76, 88, 69, 66,
-  73, 89, 74, 77, 83, 87, 86, 91, 86, 95,
-  80, 79, 81, 79, 96, 86, 91, 85, 77, 92,
-  80, 82, 89, 94, 79, 81, 68, 94, 97, 95,
-  82, 89, 86, 91, 76, 98, 83, 74, 87, 88,
-  90, 81, 84, 90, 92, 80, 88, 75, 77, 78,
-  92, 78, 95, 77, 105, 71, 75, 77, 89, 87,
-  81, 85, 82, 81, 65, 86, 81, 86, 82, 84,
-  92, 96, 79, 76, 86, 91, 77, 83, 86, 69,
-  74, 84, 98, 100, 78, 91, 92, 86, 82, 83,
-  79, 82, 86, 73, 100, 98, 67, 77, 69, 89,
-  62, 57, 87, 84, 79, 78, 83, 66, 74, 87,
-  84, 93, 87, 80, 76, 91, 88, 98, 72, 81,
-  90, 81, 92, 81, 73, 85, 75, 70, 66, 92,
-  75, 69, 83, 89, 83, 90, 85, 87, 65, 78,
-  77, 77, 89, 92, 85, 83, 81, 100, 82, 81,
-  86, 80, 82, 82, 66, 96, 98, 86, 81, 83,
-  78, 90, 70, 87, 82, 63, 96, 92, 95, 87,
-  84, 93, 97, 81, 80, 73, 86, 73, 90, 77,
-  95, 87, 91, 78, 78, 72, 88, 87, 83, 81,
-  88, 87, 67, 86, 80, 86, 87, 84, 85, 89,
-  95, 83, 84, 87, 82, 82, 86, 76, 75, 87,
-  93, 91, 80, 91, 87, 83, 90, 88, 82, 85,
-  79, 78, 85, 95, 74, 76, 77, 88, 65, 73,
-  85, 86, 94, 86, 88, 68, 81, 82, 82, 85,
-  83, 78, 85, 83, 87, 98, 74, 98, 90, 87,
-  83, 85, 77, 90, 75, 76, 69, 85, 75, 76,
-  87, 82, 82, 91, 93, 92, 76, 78, 81, 84,
-  98, 87, 78, 86, 81, 92, 93, 80, 93, 84,
-  79, 80, 73, 97, 99, 84, 77, 85, 75, 93,
-  77, 81, 80, 79, 100, 84, 88, 79, 91, 97,
-  90, 88, 88, 80, 79, 76, 87, 80, 118, 91,
-  82, 87, 75, 71, 101, 89, 86, 81, 97, 76,
-  61, 79, 86, 76, 84, 88, 101, 88, 86, 86,
-  93, 86, 92, 88, 94, 97, 93, 93, 89, 81,
-  99, 104, 97, 94, 88, 70, 93, 84, 106, 73,
-  60, 95, 94, 90, 92, 94, 82, 69, 94, 91,
-  65, 88, 109, 70, 124, 85, 66, 125, 74, 76,
-  74, 76, 83, 91, 91, 60, 93, 101, 86, 81,
-  87, 100, 80, 87, 73, 68, 83, 55, 88, 87,
-  78, 79, 91, 76, 87, 92, 82, 82, 95, 94,
-  78, 94, 80, 78, 95, 83, 75, 84, 89, 88,
-  85, 81, 91, 80, 74, 83, 76, 67, 81, 93,
-  97, 97, 74, 86, 82, 91, 74, 83, 94, 78,
-  91, 89, 71, 76, 78, 76, 113, 97, 75, 84,
-  73, 65, 102, 92, 92, 79, 103, 84, 62, 78,
-  85, 75, 82, 78, 107, 85, 87, 83, 91, 82,
-  86, 91, 85, 94, 92, 89, 85, 86, 98, 102,
-  84, 108, 87, 66, 102, 79, 105, 75, 54, 105,
-  81, 95, 89, 92, 79, 79, 90, 89, 60, 91,
-  100, 68, 129, 89, 67, 128, 72, 78, 87, 78,
-  84, 91, 95, 69, 87, 98, 82, 79, 84, 100,
-  89, 89, 64, 70, 77, 55, 86, 96, 75, 82,
-  93, 86, 79, 88, 85, 93, 93, 95, 77, 93,
-  79, 84, 111, 87, 78, 88, 91, 91, 84, 87,
-  90, 78, 69, 77, 82, 69, 80, 97, 95, 101,
-  94, 95, 86, 85, 75, 84, 91, 72, 89, 89,
-  71, 74, 87, 73, 94, 94, 84, 80, 72, 69,
-  100, 89, 91, 76, 91, 83, 58, 84, 91, 76,
-  84, 81, 98, 88, 85, 81, 84, 84, 88, 87,
-  91, 101, 93, 85, 89, 80, 98, 91, 87, 85,
-  82, 76, 93, 81, 103, 77, 66, 95, 80, 84,
-  94, 90, 87, 82, 93, 86, 67, 93, 105, 72,
-  117, 87, 65, 102, 82, 70, 78, 79, 81, 92,
-  89, 67, 79, 96, 88, 86, 84, 98, 81, 90,
-  65, 70, 80, 57, 95, 87, 75, 80, 94, 73,
-  82, 97, 82, 81, 94, 94, 83, 86, 79, 83,
-  106, 78, 79, 79, 89, 87, 83, 84, 88, 80,
-  70, 83, 80, 76, 83, 94, 91, 103, 84, 83,
-  78, 91, 72, 87, 93, 81, 88, 92, 77, 81,
-  87, 73, 77, 72, 81, 73, 101, 86, 84, 84,
-  90, 85, 77, 87, 65, 74, 72, 84, 75, 76,
-  110, 79, 85, 74, 86, 114, 84, 80, 92, 100,
-  82, 95, 87, 71, 84, 80, 108, 83, 78, 57,
-  95, 74, 112, 87, 78, 77, 72, 74, 94, 76,
-  93, 74, 90, 85, 74, 89, 110, 79, 98, 78,
-  81, 90, 95, 75, 63, 79, 77, 81, 73, 71,
-  69, 77, 99, 102, 75, 94, 76, 85, 93, 69,
-  85, 71, 86, 69, 85, 72, 82, 70, 89, 77,
-  79, 77, 83, 85, 74, 69, 84, 87, 78, 86,
-  78, 79, 92, 86, 79, 71, 82, 96, 97, 81,
-  72, 65, 75, 71, 99, 87, 70, 84, 83, 100,
-  75, 74, 89, 92, 81, 74, 69, 92, 81, 70,
-  75, 77, 77, 72, 102, 80, 84, 84, 91, 86,
-  75, 87, 66, 71, 78, 84, 71, 74, 119, 76,
-  82, 66, 89, 105, 81, 82, 88, 106, 82, 95,
-  91, 73, 81, 76, 107, 82, 82, 56, 97, 74,
-  110, 91, 68, 86, 65, 76, 93, 76, 94, 87,
-  87, 85, 75, 90, 110, 76, 101, 77, 76, 94,
-  108, 72, 69, 79, 70, 86, 73, 76, 64, 77,
-  97, 92, 75, 95, 76, 80, 93, 73, 82, 75,
-  89, 73, 83, 77, 74, 74, 83, 78, 84, 79,
-  78, 85, 73, 67, 81, 87, 83, 90, 84, 73,
-  87, 88, 77, 71, 82, 94, 94, 77, 79, 61,
-  74, 77, 104, 96, 73, 86, 79, 93, 74, 77,
-  88, 88, 84, 76, 62, 91, 90, 71, 72, 76,
-  82, 74, 96, 75, 90, 86, 86, 78, 75, 76,
-  66, 79, 75, 86, 74, 75, 103, 80, 81, 75,
-  83, 106, 78, 78, 88, 104, 87, 97, 92, 70,
-  87, 79, 97, 81, 87, 69, 91, 78, 97, 90,
-  81, 85, 70, 80, 93, 75, 93, 81, 91, 84,
-  75, 82, 102, 77, 91, 83, 76, 79, 92, 75,
-  70, 83, 76, 80, 77, 77, 62, 82, 93, 98,
-  80, 94, 76, 80, 77, 74, 83, 71, 90, 75,
-  82, 78, 70, 77, 82, 79, 82, 78, 85, 90,
-  73, 67, 85, 85, 85, 85, 86, 70, 91, 84,
-  86, 77, 88, 90, 91, 83, 85, 69, 80, 84,
-  91, 91, 64, 85, 81, 95, 76, 77, 84, 91,
-  81, 81, 76, 90, 101, 67, 63, 80, 96, 96,
-  89, 91, 77, 77, 83, 83, 90, 86, 88, 87,
-  67, 109, 84, 79, 83, 84, 74, 80, 87, 111,
-  84, 76, 78, 97, 83, 89, 91, 74, 85, 77,
-  79, 84, 86, 85, 91, 72, 86, 88, 95, 62,
-  77, 77, 85, 78, 93, 82, 84, 79, 84, 83,
-  88, 97, 63, 79, 95, 75, 80, 91, 77, 96,
-  74, 81, 74, 75, 89, 73, 99, 104, 87, 89,
-  70, 81, 94, 77, 89, 66, 84, 72, 95, 71,
-  86, 84, 84, 77, 64, 91, 69, 83, 80, 71,
-  96, 97, 79, 84, 82, 92, 92, 86, 81, 79,
-  82, 92, 78, 105, 108, 86, 90, 73, 75, 82,
-  62, 79, 85, 78, 78, 84, 77, 93, 83, 80,
-  94, 87, 96, 76, 76, 77, 97, 80, 90, 90,
-  77, 78, 81, 83, 83, 88, 93, 82, 71, 110,
-  85, 82, 78, 79, 83, 82, 87, 106, 79, 76,
-  77, 99, 83, 93, 93, 72, 86, 64, 77, 82,
-  91, 84, 86, 77, 86, 87, 91, 64, 76, 75,
-  88, 76, 101, 91, 81, 82, 85, 82, 92, 89,
-  63, 76, 93, 75, 80, 91, 78, 95, 79, 78,
-  78, 80, 76, 73, 96, 93, 88, 89, 73, 78,
-  91, 85, 85, 76, 87, 74, 94, 75, 76, 91,
-  86, 81, 67, 82, 67, 88, 76, 70, 93, 95,
-  77, 88, 82, 78, 92, 87, 75, 82, 83, 88,
-  82, 101, 113, 80, 87, 77, 80, 90, 59, 79,
-  83, 73, 78, 83, 79, 92, 87, 83, 94, 89,
-  96, 79, 86, 78, 91, 76, 80, 83, 78, 80,
-  82, 82, 87, 72, 91, 84, 67, 101, 80, 85,
-  74, 88, 94, 79, 86, 101, 78, 77, 70, 97,
-  82, 94, 88, 68, 91, 71, 79, 84, 93, 84,
-  95, 73, 85, 89, 100, 69, 79, 82, 85, 74,
-  87, 85, 80, 79, 85, 81, 88, 88, 64, 80,
-  87, 76, 78, 93, 84, 94, 76, 80, 74, 88,
-  66, 79, 95, 99, 91, 87, 72, 82, 85, 79,
-  85, 72, 84, 85, 87, 78, 70, 90, 80, 78,
-  64, 82, 74, 88, 77, 68, 93, 92, 75, 84,
-  86, 71, 94, 85, 85, 80, 87, 90, 75, 100,
-  105, 83, 89, 83, 83, 86, 68, 83, 88, 79,
-  83, 81, 70, 94, 84, 84, 95, 86, 74, 86,
-  78, 79, 73, 82, 124, 115, 55, 90, 89, 85,
-  82, 78, 71, 90, 93, 66, 77, 92, 72, 93,
-  92, 65, 78, 73, 80, 88, 87, 83, 75, 75,
-  98, 72, 79, 92, 75, 86, 88, 80, 75, 78,
-  75, 82, 77, 110, 79, 75, 76, 83, 77, 81,
-  105, 88, 90, 81, 83, 72, 98, 80, 85, 79,
-  83, 86, 84, 81, 76, 69, 75, 83, 82, 76,
-  89, 77, 87, 98, 142, 81, 84, 90, 133, 74,
-  81, 87, 73, 86, 78, 81, 99, 69, 84, 86,
-  75, 88, 84, 86, 73, 95, 74, 89, 116, 72,
-  85, 115, 83, 90, 101, 81, 76, 74, 73, 76,
-  70, 80, 79, 73, 81, 77, 94, 73, 86, 81,
-  66, 86, 83, 79, 79, 86, 77, 80, 84, 82,
-  74, 78, 120, 101, 52, 84, 87, 89, 91, 87,
-  78, 92, 93, 68, 76, 86, 79, 99, 79, 67,
-  75, 73, 75, 81, 81, 82, 81, 75, 85, 75,
-  81, 80, 78, 85, 80, 81, 79, 78, 80, 76,
-  76, 112, 87, 81, 76, 84, 71, 75, 99, 86,
-  84, 80, 74, 69, 93, 83, 91, 82, 84, 84,
-  78, 76, 76, 75, 81, 76, 78, 78, 86, 72,
-  92, 89, 139, 80, 87, 92, 120, 69, 90, 91,
-  73, 89, 84, 71, 96, 83, 78, 88, 72, 100,
-  93, 85, 67, 100, 77, 86, 107, 76, 86, 112,
-  75, 88, 99, 78, 74, 68, 81, 74, 72, 84,
-  83, 78, 75, 76, 102, 76, 80, 80, 73, 91,
-  82, 79, 76, 92, 73, 75, 83, 82, 73, 87,
-  123, 101, 58, 87, 84, 83, 82, 88, 76, 88,
-  95, 64, 76, 87, 78, 91, 83, 71, 70, 77,
-  82, 87, 80, 81, 79, 72, 98, 77, 88, 81,
-  77, 87, 75, 80, 74, 85, 73, 85, 77, 111,
-  75, 80, 75, 82, 79, 78, 105, 85, 91, 77,
-  90, 70, 96, 73, 87, 76, 83, 83, 82, 78,
-  78, 74, 79, 77, 78, 72, 87, 77, 91, 101,
-  140, 89, 89, 89, 130, 75, 87, 88, 74, 84,
-  84, 87, 96, 73, 84, 87, 78, 93, 91, 86,
-  71, 96, 71, 85, 113, 78, 85, 102, 82, 92,
-  101, 82, 77, 78, 80, 75, 75, 79, 81, 72,
-  78, 79, 92, 68, 85, 80, 67, 84, 82, 80,
-  78, 87, 86, 87, 83, 79, 81, 84, 108, 110,
-  59, 87, 89, 84, 78, 88, 79, 90, 92, 64,
-  85, 90, 80, 90, 92, 66, 83, 69, 80, 87,
-  83, 76, 85, 73, 89, 83, 82, 90, 80, 80,
-  81, 76, 70, 71, 86, 79, 81, 109, 82, 77,
-  70, 79, 80, 78, 101, 87, 79, 76, 78, 76,
-  92, 82, 93, 73, 84, 80, 86, 77, 80, 74,
-  74, 77, 78, 82, 79, 75, 80, 94, 135, 86,
-  85, 93, 119, 80, 79, 84, 72, 79, 79, 79,
-  96, 86, 90, 86, 76, 89, 91, 89, 79, 104,
-  82, 88, 103, 74, 89, 108, 85, 87, 102, 78,
-  82, 77, 79, 70, 70, 85, 82, 79, 80, 74,
-  97, 72, 91, 82, 65, 90, 83, 87, 79, 95,
-  95, 83, 83, 88, 81, 80, 109, 99, 58, 86,
-  92, 92, 95, 91, 86, 97, 93, 67, 89, 87,
-  87, 98, 72, 67, 84, 67, 73, 84, 75, 83,
-  89, 76, 81, 82, 82, 81, 81, 81, 91, 78,
-  73, 80, 89, 77, 80, 107, 91, 82, 75, 83,
-  76, 76, 94, 84, 74, 86, 71, 76, 84, 87,
-  96, 72, 84, 90, 77, 81, 79, 83, 77, 72,
-  80, 91, 72, 76, 85, 85, 133, 78, 83, 96,
-  107, 77, 85, 86, 75, 82, 81, 71, 96, 87,
-  87, 80, 73, 108, 97, 85, 83, 112, 87, 84,
-  87, 79, 98, 104, 88, 93, 100, 78, 84, 72,
-  88, 68, 77, 85, 82, 83, 76, 75, 110, 77,
-  79, 82, 73, 98, 84, 90, 84, 103, 78, 79,
-  83, 85, 79, 93, 104, 91, 62, 83, 87, 80,
-  80, 85, 80, 91, 92, 66, 85, 87, 83, 82,
-  85, 73, 75, 73, 80, 86, 79, 83, 81, 71,
-  88, 80, 78, 84, 75, 78, 85, 76, 72, 71,
-  76, 83, 80, 109, 81, 81, 71, 78, 82, 73,
-  101, 85, 80, 86, 86, 76, 93, 73, 91, 73,
-  83, 77, 85, 74, 83, 76, 75, 77, 77, 74,
-  77, 80, 83, 97, 128, 85, 87, 86, 116, 76,
-  80, 92, 72, 78, 85, 88, 95, 92, 92, 85,
-  79, 89, 91, 88, 77, 97, 76, 85, 109, 81,
-  88, 92, 86, 87, 102, 80, 78, 80, 75, 70,
-  73, 82, 77, 74, 82, 73, 91, 70, 91, 78,
-  68, 88, 82, 87, 80, 93, 81, 90, 84, 77,
-  87, 82, 106, 105, 52, 87, 88, 79, 79, 95,
-  86, 90, 94, 59, 75, 84, 75, 94, 78, 69,
-  80, 74, 81, 85, 87, 76, 80, 69, 94, 83,
-  76, 86, 75, 70, 70, 80, 71, 81, 79, 88,
-  82, 113, 77, 83, 69, 77, 86, 92, 111, 88,
-  87, 72, 78, 78, 93, 73, 98, 74, 78, 88,
-  89, 90, 82, 68, 72, 84, 79, 72, 75, 74,
-  82, 99, 138, 78, 88, 91, 124, 72, 77, 84,
-  71, 72, 74, 84, 90, 84, 89, 95, 77, 85,
-  88, 100, 79, 101, 78, 91, 105, 79, 87, 114,
-  89, 85, 98, 77, 81, 84, 84, 73, 78, 86,
-  85, 76, 79, 76, 90, 75, 90, 83, 62, 91,
-  79, 83, 76, 87, 83, 81, 80, 85, 86, 73,
-  99, 105, 54, 85, 92, 92, 85, 84, 86, 92,
-  90, 63, 79, 81, 81, 92, 76, 66, 78, 69,
-  83, 85, 85, 86, 74, 70, 90, 82, 74, 80,
-  76, 70, 85, 77, 77, 72, 76, 82, 80, 118,
-  80, 82, 75, 77, 83, 83, 102, 87, 85, 83,
-  82, 77, 85, 76, 100, 77, 78, 84, 87, 86,
-  82, 71, 69, 89, 79, 75, 76, 83, 82, 98,
-  126, 78, 85, 87, 110, 70, 75, 98, 70, 74,
-  77, 80, 87, 86, 98, 94, 74, 91, 95, 94,
-  82, 101, 79, 91, 109, 79, 90, 112, 87, 90,
-  100, 77, 84, 83, 84, 73, 78, 84, 82, 74,
-  85, 74, 93, 80, 87, 85, 66, 95, 77, 89,
-  78, 92, 74, 77, 77, 79, 84, 77, 108, 91,
-  57, 85, 89, 77, 86, 83, 87, 90, 91, 64,
-  76, 81, 82, 86, 91, 75, 79, 77, 78, 83,
-  87, 81, 79, 68, 90, 80, 75, 80, 73, 74,
-  98, 79, 76, 83, 67, 89, 82, 108, 77, 76,
-  72, 74, 88, 83, 111, 88, 88, 96, 83, 81,
-  95, 73, 96, 76, 77, 86, 87, 92, 81, 69,
-  74, 91, 85, 72, 71, 78, 80, 99, 139, 83,
-  81, 88, 121, 71, 77, 92, 75, 74, 78, 93,
-  93, 91, 90, 89, 77, 86, 82, 98, 75, 98,
-  77, 90, 108, 74, 87, 99, 90, 85, 97, 76,
-  78, 85, 74, 72, 75, 73, 80, 74, 82, 76,
-  89, 78, 93, 82, 66, 87, 79, 86, 78, 85,
-  80, 83, 88, 82, 76, 89, 99, 81, 82, 92,
-  80, 84, 86, 75, 81, 87, 84, 96, 95, 92,
-  79, 97, 87, 81, 86, 93, 82, 81, 87, 77,
-  96, 76, 89, 80, 93, 74, 68, 82, 77, 92,
-  91, 72, 81, 104, 75, 86, 90, 82, 75, 90,
-  66, 115, 96, 77, 94, 55, 92, 89, 73, 93,
-  93, 74, 72, 68, 85, 78, 81, 88, 95, 92,
-  65, 69, 82, 88, 102, 83, 89, 98, 98, 76,
-  98, 77, 73, 84, 96, 73, 83, 82, 86, 78,
-  79, 64, 78, 74, 80, 85, 81, 80, 84, 75,
-  72, 77, 87, 87, 88, 82, 75, 102, 92, 88,
-  92, 86, 90, 82, 78, 85, 92, 80, 83, 91,
-  87, 98, 82, 85, 103, 90, 85, 95, 84, 71,
-  88, 75, 86, 79, 80, 82, 73, 88, 77, 84,
-  93, 113, 59, 87, 87, 77, 79, 81, 73, 101,
-  76, 99, 90, 76, 95, 80, 90, 76, 96, 81,
-  79, 76, 88, 88, 71, 69, 72, 95, 80, 104,
-  81, 76, 85, 82, 90, 79, 87, 78, 88, 91,
-  93, 76, 72, 51, 94, 63, 81, 79, 87, 85,
-  82, 72, 51, 79, 113, 77, 85, 73, 38, 78,
-  83, 89, 81, 78, 81, 124, 89, 91, 80, 83,
-  87, 89, 76, 75, 85, 78, 66, 86, 80, 67,
-  83, 81, 79, 78, 90, 85, 84, 98, 65, 87,
-  82, 80, 85, 82, 66, 86, 101, 72, 98, 70,
-  82, 92, 83, 94, 90, 86, 88, 81, 84, 83,
-  85, 79, 73, 89, 84, 103, 92, 74, 90, 83,
-  87, 74, 68, 84, 80, 84, 74, 81, 83, 126,
-  54, 95, 90, 71, 79, 77, 80, 91, 81, 87,
-  84, 62, 87, 84, 96, 84, 89, 92, 82, 82,
-  94, 89, 88, 80, 91, 68, 84, 85, 87, 75,
-  88, 82, 83, 95, 91, 65, 113, 90, 85, 80,
-  62, 80, 90, 75, 97, 80, 72, 94, 103, 74,
-  69, 80, 100, 82, 78, 80, 48, 73, 93, 93,
-  67, 86, 64, 117, 98, 90, 79, 94, 76, 92,
-  68, 94, 84, 84, 67, 80, 83, 92, 85, 83,
-  102, 85, 89, 92, 88, 98, 88, 104, 88, 79,
-  87, 88, 79, 82, 89, 69, 88, 73, 72, 99,
-  96, 96, 92, 94, 81, 77, 85, 75, 83, 74,
-  71, 95, 84, 81, 76, 81, 74, 82, 75, 87,
-  100, 82, 86, 95, 88, 82, 96, 60, 85, 92,
-  82, 98, 92, 89, 81, 96, 84, 80, 77, 85,
-  79, 85, 89, 77, 95, 71, 98, 85, 100, 80,
-  65, 80, 81, 85, 81, 75, 87, 99, 80, 90,
-  85, 83, 76, 89, 66, 102, 86, 80, 93, 67,
-  87, 89, 74, 95, 90, 78, 59, 69, 72, 81,
-  84, 87, 94, 64, 95, 80, 79, 90, 105, 86,
-  85, 114, 84, 74, 93, 75, 85, 78, 89, 72,
-  85, 86, 79, 79, 82, 73, 79, 71, 82, 80,
-  87, 79, 89, 80, 76, 76, 80, 88, 86, 79,
-  76, 95, 85, 93, 91, 96, 85, 75, 53, 74,
-  78, 82, 82, 84, 70, 93, 90, 90, 100, 81,
-  85, 102, 102, 69, 54, 80, 78, 72, 86, 82,
-  74, 93, 93, 79, 97, 80, 56, 84, 78, 76,
-  83, 72, 67, 104, 72, 90, 85, 79, 90, 85,
-  87, 83, 84, 80, 87, 80, 123, 90, 100, 78,
-  101, 80, 91, 104, 87, 73, 95, 70, 79, 65,
-  84, 78, 87, 75, 80, 84, 85, 65, 87, 64,
-  72, 83, 84, 92, 79, 79, 36, 94, 93, 83,
-  83, 63, 64, 85, 91, 76, 84, 78, 83, 153,
-  89, 88, 73, 74, 92, 80, 73, 75, 79, 93,
-  64, 96, 78, 76, 87, 74, 92, 78, 90, 86,
-  80, 98, 70, 82, 81, 84, 72, 75, 65, 82,
-  92, 76, 81, 80, 78, 80, 67, 83, 79, 86,
-  92, 85, 64, 81, 80, 84, 69, 74, 81, 114,
-  104, 67, 68, 86, 82, 75, 74, 80, 76, 85,
-  74, 83, 79, 100, 48, 75, 78, 64, 80, 65,
-  72, 78, 80, 86, 84, 72, 90, 85, 89, 93,
-  78, 100, 80, 81, 88, 83, 94, 83, 112, 61,
-  94, 85, 79, 68, 94, 75, 81, 81, 89, 66,
-  110, 64, 78, 86, 78, 94, 82, 75, 83, 72,
-  78, 103, 111, 85, 65, 86, 92, 84, 84, 84,
-  68, 79, 97, 75, 69, 79, 83, 113, 105, 91,
-  72, 88, 74, 77, 62, 93, 71, 103, 84, 94,
-  81, 93, 87, 73, 99, 78, 86, 93, 73, 95,
-  84, 105, 83, 84, 83, 87, 79, 82, 95, 77,
-  86, 75, 73, 94, 95, 101, 80, 84, 87, 90,
-  85, 69, 73, 80, 72, 88, 76, 81, 77, 77,
-  82, 91, 79, 78, 94, 79, 86, 90, 84, 80,
-  87, 61, 101, 94, 82, 93, 85, 93, 86, 76,
-  78, 80, 75, 88, 81, 79, 80, 82, 83, 84,
-  93, 83, 95, 75, 83, 85, 69, 80, 86, 73,
-  71, 98, 81, 85, 85, 71, 81, 82, 74, 91,
-  74, 86, 89, 89, 96, 100, 91, 92, 85, 84,
-  82, 80, 103, 77, 89, 87, 83, 93, 102, 84,
-  79, 86, 99, 83, 89, 104, 90, 81, 91, 78,
-  75, 82, 89, 79, 85, 85, 85, 82, 71, 88,
-  89, 87, 88, 87, 83, 84, 86, 83, 88, 92,
-  82, 87, 100, 85, 82, 91, 79, 94, 89, 96,
-  80, 68, 71, 80, 66, 89, 83, 81, 64, 92,
-  78, 86, 100, 86, 86, 85, 83, 80, 68, 91,
-  72, 62, 93, 82, 84, 86, 85, 73, 95, 64,
-  86, 95, 80, 90, 87, 88, 80, 72, 68, 86,
-  71, 94, 95, 77, 79, 88, 79, 88, 90, 73,
-  84, 68, 87, 88, 92, 89, 84, 83, 71, 94,
-  80, 74, 84, 72, 84, 86, 88, 91, 88, 83,
-  81, 98, 90, 87, 87, 82, 84, 76, 89, 89,
-  66, 82, 85, 83, 78, 86, 89, 80, 85, 84,
-  91, 76, 88, 91, 96, 77, 88, 78, 81, 77,
-  93, 84, 78, 77, 95, 98, 70, 91, 79, 81,
-  75, 79, 87, 80, 89, 77, 78, 91, 75, 86,
-  79, 81, 77, 92, 76, 87, 84, 85, 83, 73,
-  78, 73, 57, 85, 87, 78, 65, 89, 80, 86,
-  90, 83, 82, 91, 90, 81, 91, 89, 71, 83,
-  85, 79, 77, 84, 79, 79, 89, 79, 73, 81,
-  79, 87, 86, 87, 84, 79, 97, 87, 74, 94,
-  93, 84, 83, 90, 89, 98, 84, 72, 84, 91,
-  82, 96, 97, 78, 89, 83, 69, 83, 84, 72,
-  90, 89, 87, 83, 95, 85, 91, 83, 79, 99,
-  85, 84, 91, 84, 85, 88, 95, 86, 75, 80,
-  79, 87, 80, 83, 83, 81, 90, 80, 88, 74,
-  95, 100, 94, 78, 89, 85, 77, 93, 86, 88,
-  72, 93, 96, 101, 80, 82, 77, 78, 83, 74,
-  90, 76, 85, 64, 77, 86, 80, 84, 82, 80,
-  95, 87, 84, 95, 88, 77, 84, 91, 90, 90,
-  73, 82, 90, 81, 77, 92, 83, 87, 93, 90,
-  83, 83, 66, 69, 70, 93, 79, 62, 72, 101,
-  96, 76, 83, 84, 73, 89, 77, 89, 84, 76,
-  87, 93, 90, 97, 79, 83, 86, 78, 84, 79,
-  61, 97, 86, 84, 80, 74, 80, 91, 81, 90,
-  77, 70, 94, 82, 75, 92, 58, 82, 94, 130,
-  87, 76, 88, 89, 76, 84, 90, 79, 86, 82,
-  100, 98, 71, 80, 85, 77, 81, 79, 89, 104,
-  92, 77, 84, 78, 85, 76, 86, 73, 68, 82,
-  88, 84, 86, 85, 82, 56, 88, 81, 85, 93,
-  75, 83, 95, 74, 76, 85, 87, 84, 89, 79,
-  97, 90, 79, 79, 86, 81, 76, 82, 79, 88,
-  78, 70, 82, 81, 92, 87, 81, 80, 96, 83,
-  89, 81, 107, 76, 115, 72, 77, 79, 90, 81,
-  90, 70, 72, 83, 89, 67, 76, 83, 80, 87,
-  78, 86, 79, 87, 83, 83, 81, 91, 87, 76,
-  85, 83, 89, 82, 80, 82, 90, 71, 70, 83,
-  87, 70, 80, 86, 78, 89, 82, 77, 78, 75,
-  81, 84, 68, 84, 77, 84, 97, 105, 81, 74,
-  87, 88, 81, 69, 81, 81, 91, 82, 73, 97,
-  78, 68, 82, 76, 77, 87, 80, 88, 85, 78,
-  81, 84, 84, 93, 80, 77, 80, 79, 83, 91,
-  88, 78, 69, 64, 80, 82, 85, 78, 84, 81,
-  63, 78, 76, 88, 83, 82, 79, 79, 99, 66,
-  70, 81, 77, 77, 75, 79, 89, 82, 81, 102,
-  84, 79, 77, 88, 73, 72, 92, 92, 87, 69,
-  107, 92, 70, 81, 81, 84, 81, 83, 98, 80,
-  81, 83, 91, 87, 83, 71, 77, 92, 72, 80,
-  89, 86, 85, 87, 79, 94, 74, 76, 75, 68,
-  88, 86, 93, 81, 85, 75, 80, 84, 88, 84,
-  82, 95, 78, 88, 82, 81, 85, 78, 85, 93,
-  73, 87, 92, 84, 99, 91, 87, 75, 81, 82,
-  86, 63, 81, 83, 90, 84, 72, 91, 81, 76,
-  84, 90, 85, 88, 81, 84, 83, 88, 86, 84,
-  86, 94, 87, 84, 88, 83, 78, 87, 83, 82,
-  65, 74, 87, 83, 82, 76, 88, 66, 62, 95,
-  84, 89, 89, 84, 82, 84, 100, 81, 72, 89,
-  74, 83, 85, 89, 86, 85, 73, 109, 74, 79,
-  81, 86, 79, 86, 78, 92, 89, 76, 89, 96,
-  49, 87, 86, 90, 79, 84, 59, 75, 65, 93,
-  87, 48, 73, 97, 96, 76, 93, 81, 73, 96,
-  74, 83, 73, 71, 98, 102, 109, 105, 95, 79,
-  79, 75, 89, 84, 89, 97, 84, 82, 85, 76,
-  74, 97, 89, 95, 82, 75, 97, 85, 58, 101,
-  64, 87, 78, 156, 90, 79, 86, 110, 81, 99,
-  91, 94, 78, 81, 103, 89, 69, 88, 81, 71,
-  101, 80, 91, 121, 98, 81, 105, 88, 69, 86,
-  91, 74, 66, 83, 92, 79, 86, 80, 89, 56,
-  94, 77, 92, 106, 74, 76, 100, 81, 75, 83,
-  89, 80, 93, 79, 117, 121, 82, 84, 94, 85,
-  105, 99, 79, 89, 83, 50, 87, 91, 103, 88,
-  94, 91, 103, 74, 89, 85, 110, 61, 124, 73,
-  80, 75, 107, 88, 87, 71, 67, 83, 92, 58,
-  78, 90, 71, 83, 80, 78, 82, 91, 79, 84,
-  77, 97, 95, 79, 100, 76, 92, 79, 69, 88,
-  88, 69, 91, 80, 88, 65, 80, 85, 77, 91,
-  87, 73, 68, 80, 75, 85, 63, 81, 80, 91,
-  84, 126, 78, 75, 91, 87, 83, 76, 85, 86,
-  80, 82, 68, 92, 79, 66, 77, 62, 77, 86,
-  78, 95, 88, 74, 89, 87, 90, 97, 84, 77,
-  75, 81, 82, 94, 90, 77, 69, 60, 76, 79,
-  101, 81, 90, 81, 73, 83, 69, 91, 91, 77,
-  78, 79, 106, 68, 67, 91, 76, 81, 85, 82,
-  93, 75, 79, 95, 88, 80, 82, 91, 76, 74,
-  92, 88, 83, 60, 112, 86, 74, 81, 80, 80,
-  84, 84, 91, 77, 80, 76, 90, 79, 84, 74,
-  71, 92, 70, 76, 89, 88, 79, 85, 76, 100,
-  75, 74, 83, 70, 93, 83, 84, 87, 87, 72,
-  78, 85, 91, 70, 90, 89, 83, 87, 85, 80,
-  77, 82, 80, 85, 72, 80, 93, 89, 93, 95,
-  82, 77, 82, 83, 82, 66, 92, 89, 85, 88,
-  67, 87, 88, 80, 83, 77, 82, 92, 77, 80,
-  84, 93, 91, 79, 90, 87, 85, 83, 86, 79,
-  81, 86, 84, 84, 62, 70, 85, 80, 85, 76,
-  98, 79, 70, 91, 73, 88, 88, 84, 81, 88,
-  98, 72, 71, 87, 77, 86, 86, 84, 89, 81,
-  74, 109, 81, 77, 83, 87, 84, 78, 82, 85,
-  85, 74, 91, 98, 42, 87, 86, 84, 77, 83,
-  60, 79, 66, 98, 85, 47, 75, 96, 87, 80,
-  94, 85, 75, 88, 76, 81, 73, 76, 94, 92,
-  107, 97, 87, 76, 80, 82, 97, 80, 97, 96,
-  90, 77, 84, 68, 68, 92, 87, 98, 87, 71,
-  102, 85, 60, 97, 73, 88, 72, 150, 97, 81,
-  82, 104, 74, 104, 86, 85, 83, 80, 108, 85,
-  81, 89, 97, 72, 86, 75, 88, 111, 86, 83,
-  95, 96, 64, 92, 84, 84, 70, 79, 89, 82,
-  84, 83, 88, 59, 88, 89, 88, 103, 74, 82,
-  96, 87, 77, 83, 85, 81, 88, 86, 101, 116,
-  97, 79, 88, 84, 93, 89, 88, 93, 97, 55,
-  95, 90, 105, 87, 91, 91, 99, 74, 82, 93,
-  119, 65, 114, 75, 79, 82, 103, 82, 84, 75,
-  65, 82, 89, 62, 77, 90, 68, 88, 83, 78,
-  83, 85, 78, 85, 73, 96, 86, 80, 103, 80,
-  94, 81, 73, 85, 84, 70, 99, 93, 90, 63,
-  72, 79, 71, 90, 86, 74, 79, 85, 87, 91,
-  59, 82, 93, 86, 71, 128, 81, 79, 79, 89,
-  82, 82, 87, 77, 84, 82, 75, 83, 82, 72,
-  83, 71, 75, 86, 76, 95, 80, 78, 94, 98,
-  89, 95, 80, 88, 83, 80, 76, 91, 89, 77,
-  69, 62, 77, 88, 94, 76, 89, 80, 71, 84,
-  73, 89, 94, 80, 78, 82, 93, 74, 77, 84,
-  81, 80, 84, 79, 92, 78, 76, 97, 91, 78,
-  83, 90, 79, 80, 90, 86, 81, 78, 106, 86,
-  63, 84, 78, 78, 83, 81, 91, 81, 74, 76,
-  90, 75, 79, 76, 65, 91, 69, 70, 91, 90,
-  80, 89, 72, 99, 71, 77, 92, 72, 96, 83,
-  84, 86, 84, 70, 84, 94, 93, 71, 87, 84,
-  81, 86, 86, 79, 81, 84, 86, 91, 77, 82,
-  101, 85, 78, 103, 78, 78, 76, 82, 84, 69,
-  86, 81, 90, 84, 68, 87, 92, 80, 83, 79,
-  76, 90, 75, 82, 79, 92, 77, 84, 92, 84,
-  84, 91, 93, 78, 74, 91, 85, 80, 59, 71,
-  86, 86, 86, 67, 99, 79, 77, 84, 77, 91,
-  87, 88, 80, 84, 87, 66, 76, 87, 84, 87,
-  83, 72, 92, 82, 73, 106, 83, 75, 78, 91,
-  79, 80, 87, 84, 83, 86, 93, 93, 36, 87,
-  85, 83, 77, 82, 70, 83, 90, 80, 97, 81,
-  84, 84, 75, 70, 75, 77, 78, 81, 78, 83,
-  72, 75, 73, 84, 104, 79, 62, 71, 79, 89,
-  81, 76, 97, 71, 108, 76, 75, 73, 67, 72,
-  75, 78, 87, 83, 82, 75, 68, 90, 89, 93,
-  96, 70, 79, 87, 86, 87, 88, 95, 79, 79,
-  70, 82, 93, 92, 98, 69, 93, 90, 93, 84,
-  75, 78, 75, 69, 56, 70, 82, 106, 81, 63,
-  84, 78, 89, 83, 95, 97, 85, 87, 90, 105,
-  78, 84, 99, 82, 74, 83, 79, 75, 62, 93,
-  77, 85, 74, 85, 86, 70, 80, 69, 95, 73,
-  99, 83, 81, 96, 83, 97, 72, 83, 90, 97,
-  84, 95, 90, 102, 96, 84, 86, 74, 90, 84,
-  79, 85, 70, 91, 63, 81, 96, 71, 84, 87,
-  71, 74, 76, 67, 84, 85, 81, 85, 72, 74,
-  73, 81, 74, 79, 71, 75, 76, 89, 77, 79,
-  97, 70, 101, 75, 74, 84, 68, 78, 73, 82,
-  87, 79, 88, 75, 104, 85, 88, 95, 93, 81,
-  84, 85, 90, 85, 86, 94, 82, 89, 73, 82,
-  95, 96, 100, 76, 96, 89, 94, 86, 70, 77,
-  74, 68, 81, 71, 85, 106, 84, 67, 84, 70,
-  95, 83, 89, 92, 82, 75, 85, 96, 83, 83,
-  95, 85, 76, 102, 77, 77, 69, 93, 77, 85,
-  74, 84, 90, 89, 85, 72, 103, 74, 101, 81,
-  83, 94, 73, 102, 74, 79, 84, 90, 74, 97,
-  94, 96, 81, 86, 85, 80, 88, 81, 80, 83,
-  78, 87, 55, 86, 89, 69, 80, 86, 83, 75,
-  79, 80, 89, 88, 83, 76, 72, 80, 73, 78,
-  71, 75, 86, 74, 83, 85, 81, 72, 95, 70,
-  80, 73, 76, 87, 68, 90, 79, 86, 83, 78,
-  79, 77, 104, 83, 90, 78, 92, 95, 73, 81,
-  88, 81, 85, 89, 76, 85, 80, 83, 84, 90,
-  91, 72, 91, 85, 87, 83, 69, 78, 81, 72,
-  82, 69, 91, 80, 88, 69, 73, 79, 90, 83,
-  83, 94, 90, 77, 92, 92, 102, 76, 96, 90,
-  84, 88, 73, 78, 82, 91, 74, 86, 74, 93,
-  84, 86, 78, 76, 74, 79, 88, 82, 87, 82,
-  76, 82, 71, 86, 85, 92, 80, 89, 82, 85,
-  78, 78, 83, 79, 86, 75, 75, 90, 89, 84,
-  75, 88, 85, 78, 74, 91, 82, 82, 82, 89,
-  76, 76, 78, 81, 88, 80, 94, 82, 124, 97,
-  86, 65, 79, 90, 81, 95, 82, 84, 95, 83,
-  85, 80, 86, 82, 78, 87, 84, 75, 92, 80,
-  84, 93, 86, 112, 82, 73, 89, 87, 83, 84,
-  90, 98, 108, 77, 95, 74, 90, 91, 69, 72,
-  90, 92, 86, 82, 71, 101, 77, 71, 64, 79,
-  79, 97, 84, 93, 99, 90, 66, 82, 86, 85,
-  86, 76, 80, 77, 75, 82, 79, 69, 87, 76,
-  82, 79, 71, 87, 108, 92, 84, 80, 87, 64,
-  111, 65, 106, 79, 87, 86, 88, 88, 67, 88,
-  82, 79, 82, 87, 104, 101, 88, 88, 78, 103,
-  83, 98, 88, 78, 96, 77, 93, 91, 77, 92,
-  83, 91, 71, 96, 83, 91, 77, 83, 77, 80,
-  84, 85, 92, 76, 100, 82, 96, 99, 76, 65,
-  79, 85, 84, 100, 75, 93, 96, 102, 86, 80,
-  80, 92, 82, 92, 79, 69, 90, 78, 115, 89,
-  81, 119, 80, 68, 94, 86, 85, 79, 87, 97,
-  116, 81, 97, 78, 86, 90, 77, 82, 94, 85,
-  86, 78, 68, 104, 71, 71, 77, 86, 79, 101,
-  84, 103, 108, 77, 68, 83, 82, 81, 88, 75,
-  76, 74, 71, 82, 74, 71, 90, 84, 80, 78,
-  74, 88, 114, 92, 68, 83, 87, 89, 122, 66,
-  113, 80, 91, 85, 87, 80, 66, 96, 85, 69,
-  83, 86, 81, 102, 92, 86, 68, 107, 83, 105,
-  90, 72, 96, 76, 76, 91, 82, 86, 86, 74,
-  84, 86, 82, 73, 85, 97, 92, 81, 83, 83,
-  75, 85, 78, 76, 83, 88, 87, 68, 86, 80,
-  74, 80, 93, 92, 83, 81, 81, 82, 72, 100,
-  77, 88, 83, 82, 93, 82, 115, 88, 80, 100,
-  87, 93, 79, 91, 92, 86, 91, 87, 87, 82,
-  83, 75, 82, 85, 78, 77, 88, 87, 94, 84,
-  72, 86, 76, 69, 91, 83, 83, 86, 88, 76,
-  72, 76, 76, 82, 85, 91, 83, 85, 86, 76,
-  98, 74, 85, 81, 82, 82, 85, 75, 70, 85,
-  83, 87, 74, 81, 88, 78, 82, 71, 87, 78,
-  86, 80, 80, 93, 68, 76, 75, 84, 84, 89,
-  88, 99, 90, 80, 70, 89, 87, 83, 87, 76,
-  78, 76, 87, 75, 81, 91, 85, 75, 74, 81,
-  80, 67, 77, 86, 78, 82, 75, 73, 90, 81,
-  87, 79, 103, 86, 85, 77, 74, 101, 88, 80,
-  80, 86, 82, 91, 78, 83, 72, 86, 83, 94,
-  84, 82, 73, 88, 90, 94, 96, 100, 88, 81,
-  91, 77, 78, 82, 93, 86, 102, 86, 97, 70,
-  98, 86, 79, 70, 89, 95, 84, 79, 86, 87,
-  82, 76, 82, 73, 67, 89, 85, 83, 75, 82,
-  87, 89, 79, 92, 86, 77, 83, 78, 77, 85,
-  83, 74, 83, 77, 87, 85, 69, 85, 109, 100,
-  97, 80, 78, 72, 95, 62, 71, 89, 86, 81,
-  85, 100, 78, 83, 76, 83, 80, 85, 95, 91,
-  83, 90, 75, 89, 86, 102, 87, 77, 89, 82,
-  99, 84, 96, 96, 85, 85, 72, 88, 83, 75,
-  78, 82, 73, 84, 81, 79, 98, 78, 96, 87,
-  94, 87, 79, 75, 71, 92, 92, 86, 72, 89,
-  80, 106, 82, 79, 76, 90, 83, 103, 83, 71,
-  70, 83, 101, 90, 94, 102, 89, 72, 93, 74,
-  82, 76, 90, 84, 103, 80, 97, 76, 90, 85,
-  80, 75, 93, 83, 81, 80, 80, 93, 86, 73,
-  75, 76, 71, 88, 84, 91, 83, 82, 80, 91,
-  77, 90, 85, 79, 79, 80, 73, 90, 80, 74,
-  85, 74, 83, 81, 78, 86, 113, 99, 79, 82,
-  78, 83, 105, 61, 72, 102, 94, 82, 87, 90,
-  79, 88, 78, 74, 84, 90, 77, 91, 76, 92,
-  74, 90, 83, 108, 91, 76, 91, 80, 77, 85,
-  98, 88, 92, 69, 83, 83, 86, 69, 85, 93,
-  90, 86, 76, 79, 81, 79, 78, 80, 86, 89,
-  85, 74, 75, 84, 82, 79, 91, 81, 86, 83,
-  77, 76, 80, 92, 83, 96, 81, 93, 86, 86,
-  103, 88, 83, 96, 96, 88, 82, 86, 86, 85,
-  88, 77, 78, 80, 88, 76, 85, 91, 82, 76,
-  88, 98, 95, 79, 80, 80, 84, 75, 89, 82,
-  78, 89, 83, 81, 69, 84, 77, 81, 74, 96,
-  81, 83, 88, 77, 89, 81, 85, 81, 80, 87,
-  91, 84, 71, 84, 84, 93, 83, 79, 84, 84,
-  82, 64, 80, 75, 84, 87, 87, 95, 83, 82,
-  75, 81, 91, 83, 80, 94, 92, 85, 79, 93,
-  86, 87, 85, 83, 79, 82, 86, 85, 81, 71,
-  74, 77, 82, 82, 91, 85, 80, 78, 89, 86,
-  79, 83, 74, 83, 83, 92, 77, 90, 90, 82,
-  94, 82, 81, 124, 92, 85, 84, 86, 93, 90,
-  79, 91, 78, 82, 90, 82, 99, 84, 84, 90,
-  82, 92, 95, 95, 74, 85, 85, 82, 79, 89,
-  87, 79, 77, 81, 80, 85, 85, 84, 89, 78,
-  87, 70, 79, 97, 83, 88, 75, 88, 79, 77,
-  79, 77, 81, 82, 75, 79, 88, 80, 79, 80,
-  85, 86, 79, 80, 88, 64, 73, 75, 91, 88,
-  86, 69, 78, 91, 86, 82, 75, 77, 74, 77,
-  89, 85, 75, 80, 82, 74, 85, 93, 80, 90,
-  90, 85, 81, 87, 99, 68, 81, 80, 91, 83,
-  90, 60, 80, 108, 86, 88, 76, 70, 75, 83,
-  83, 83, 103, 102, 80, 82, 93, 89, 80, 82,
-  74, 86, 78, 92, 82, 97, 78, 80, 83, 79,
-  82, 141, 86, 82, 79, 90, 100, 87, 84, 86,
-  77, 93, 87, 80, 96, 84, 92, 80, 79, 100,
-  94, 79, 70, 94, 85, 80, 77, 89, 97, 88,
-  73, 82, 71, 81, 86, 87, 87, 84, 84, 78,
-  80, 91, 73, 90, 75, 82, 80, 81, 76, 72,
-  84, 86, 79, 76, 92, 74, 78, 74, 76, 79,
-  72, 76, 89, 65, 74, 83, 91, 87, 78, 66,
-  75, 92, 88, 84, 80, 73, 84, 78, 115, 77,
-  72, 84, 83, 77, 78, 94, 88, 73, 90, 84,
-  71, 101, 109, 73, 83, 73, 96, 82, 99, 61,
-  88, 114, 85, 84, 78, 72, 81, 90, 85, 85,
-  85, 81, 80, 74, 88, 89, 80, 83, 79, 79,
-  81, 92, 87, 89, 72, 83, 82, 85, 80, 114,
-  91, 83, 88, 83, 91, 92, 83, 97, 84, 84,
-  81, 81, 93, 85, 79, 86, 83, 94, 91, 79,
-  79, 78, 87, 79, 81, 89, 86, 89, 83, 79,
-  81, 87, 83, 82, 88, 79, 86, 70, 82, 94,
-  82, 86, 82, 85, 81, 80, 83, 77, 78, 87,
-  83, 82, 82, 79, 84, 82, 84, 82, 98, 77,
-  86, 72, 77, 86, 94, 88, 83, 75, 84, 88,
-  91, 87, 75, 77, 74, 76, 86, 80, 75, 82,
-  82, 74, 82, 91, 80, 73, 82, 86, 79, 88,
-  97, 70, 81, 85, 86, 87, 93, 66, 79, 97,
-  86, 84, 80, 78, 78, 77, 73, 77, 106, 96,
-  74, 73, 81, 86, 68, 91, 73, 78, 73, 91,
-  81, 94, 90, 81, 87, 79, 84, 136, 84, 75,
-  76, 78, 86, 78, 79, 88, 73, 107, 95, 82,
-  82, 94, 75, 85, 91, 97, 93, 94, 66, 85,
-  84, 82, 83, 87, 87, 86, 72, 88, 90, 72,
-  77, 87, 80, 78, 89, 80, 78, 89, 91, 78,
-  88, 82, 87, 75, 72, 74, 90, 85, 72, 74,
-  95, 78, 79, 72, 85, 80, 81, 79, 97, 68,
-  78, 72, 77, 84, 84, 74, 67, 90, 84, 87,
-  84, 79, 73, 77, 101, 92, 76, 74, 86, 71,
-  94, 88, 75, 99, 85, 87, 80, 95, 98, 70,
-  84, 86, 102, 79, 95, 63, 92, 106, 92, 91,
-  87, 89, 74, 81, 69, 80, 127, 121, 73, 73,
-  93, 91, 71, 94, 71, 79, 68, 91, 81, 105,
-  75, 83, 72, 72, 89, 160, 79, 77, 63, 95,
-  100, 72, 74, 80, 71, 126, 99, 82, 70, 97,
-  84, 74, 87, 94, 92, 77, 64, 102, 87, 87,
-  80, 87, 98, 89, 71, 91, 73, 61, 72, 86,
-  79, 86, 80, 95, 73, 78, 84, 83, 78, 77,
-  92, 75, 66, 73, 107, 77, 71, 70, 100, 69,
-  82, 83, 74, 82, 74, 73, 103, 67, 79, 69,
-  74, 76, 73, 69, 66, 92, 86, 91, 93, 75,
-  86, 78, 130, 93, 77, 76, 94, 72, 85, 83,
-  85, 76, 86, 83, 79, 113, 104, 74, 81, 81,
-  107, 79, 106, 59, 95, 115, 77, 89, 81, 73,
-  84, 96, 77, 83, 94, 86, 77, 68, 80, 91,
-  71, 92, 81, 80, 73, 91, 80, 94, 73, 84,
-  77, 85, 83, 124, 85, 85, 79, 83, 85, 88,
-  76, 95, 74, 99, 88, 81, 81, 86, 82, 82,
-  86, 85, 92, 78, 75, 77, 84, 76, 86, 87,
-  88, 82, 79, 86, 86, 81, 80, 88, 79, 74,
-  90, 77, 83, 88, 88, 83, 82, 82, 85, 80,
-  80, 79, 83, 77, 78, 75, 88, 80, 83, 91,
-  83, 86, 100, 76, 91, 72, 82, 76, 82, 88,
-  73, 79, 72, 88, 87, 87, 82, 83, 74, 75,
-  96, 87, 77, 77, 82, 71, 82, 86, 75, 73,
-  81, 83, 90, 93, 95, 76, 73, 87, 98, 85,
-  97, 70, 88, 95, 82, 85, 82, 72, 77, 80,
-  77, 72, 93, 92, 70, 81, 79, 87, 74, 86,
-  70, 74, 84, 87, 82, 87, 80, 77, 92, 85,
-  86, 113, 91, 78, 69, 72, 81, 86, 96, 76,
-  81, 106, 89, 84, 84, 82, 85, 85, 88, 93,
-  83, 80, 69, 75, 90, 75, 86, 82, 80, 83,
-  82, 70, 92, 80, 88, 87, 81, 82, 86, 79,
-  72, 95, 89, 78, 86, 81, 89, 68, 72, 86,
-  85, 90, 79, 70, 96, 85, 80, 71, 87, 84,
-  80, 76, 91, 78, 75, 68, 75, 89, 87, 73,
-  71, 90, 75, 92, 75, 76, 77, 76, 81, 97,
-  81, 75, 81, 71, 89, 76, 62, 103, 86, 94,
-  84, 81, 89, 75, 80, 84, 96, 83, 83, 88,
-  96, 85, 81, 90, 85, 74, 70, 84, 75, 76,
-  100, 104, 69, 85, 85, 91, 73, 86, 66, 74,
-  77, 89, 81, 87, 79, 81, 81, 80, 86, 127,
-  84, 89, 63, 82, 86, 79, 84, 77, 82, 123,
-  90, 83, 80, 77, 82, 81, 83, 88, 77, 76,
-  72, 86, 91, 77, 81, 86, 87, 87, 81, 69,
-  83, 74, 84, 80, 79, 86, 101, 86, 71, 87,
-  92, 87, 75, 80, 101, 65, 73, 86, 88, 79,
-  83, 66, 100, 84, 76, 77, 84, 86, 81, 73,
-  91, 72, 75, 66, 76, 86, 81, 68, 72, 89,
-  78, 94, 80, 78, 84, 75, 97, 113, 77, 78,
-  83, 70, 81, 71, 69, 84, 84, 91, 88, 88,
-  90, 78, 76, 82, 100, 78, 91, 86, 100, 86,
-  79, 87, 76, 73, 80, 90, 80, 80, 90, 84,
-  72, 75, 81, 92, 79, 86, 75, 76, 84, 86,
-  84, 86, 87, 82, 82, 90, 82, 111, 93, 102,
-  77, 77, 82, 86, 86, 88, 83, 102, 88, 87,
-  86, 80, 85, 84, 87, 83, 81, 80, 77, 72,
-  88, 73, 87, 85, 87, 84, 87, 72, 91, 82,
-  87, 84, 79, 79, 88, 81, 74, 90, 86, 80,
-  77, 79, 87, 73, 79, 87, 81, 78, 76, 72,
-  90, 83, 81, 82, 84, 84, 99, 69, 86, 82,
-  79, 70, 82, 90, 81, 76, 79, 88, 86, 93,
-  78, 82, 77, 75, 79, 84, 83, 76, 79, 73,
-  84, 76, 65, 78, 78, 79, 86, 77, 87, 78,
-  78, 82, 92, 85, 84, 92, 93, 85, 94, 83,
-  83, 84, 87, 72, 84, 71, 74, 53, 75, 90,
-  81, 99, 70, 77, 86, 94, 72, 85, 98, 97,
-  107, 71, 91, 87, 88, 72, 95, 88, 89, 97,
-  94, 81, 91, 100, 87, 97, 82, 72, 78, 82,
-  88, 83, 79, 97, 92, 87, 80, 84, 94, 75,
-  74, 86, 96, 92, 79, 73, 78, 81, 82, 81,
-  84, 86, 83, 70, 78, 93, 87, 84, 89, 68,
-  78, 94, 75, 81, 81, 93, 92, 86, 83, 82,
-  87, 83, 76, 82, 72, 81, 88, 83, 65, 76,
-  99, 93, 69, 86, 96, 79, 104, 76, 91, 88,
-  95, 76, 82, 97, 88, 85, 72, 103, 72, 85,
-  68, 100, 83, 73, 81, 86, 59, 81, 89, 71,
-  75, 68, 96, 87, 92, 82, 101, 95, 83, 91,
-  98, 82, 87, 67, 77, 46, 81, 76, 86, 91,
-  70, 83, 92, 89, 74, 92, 90, 113, 89, 81,
-  94, 73, 90, 69, 102, 88, 84, 121, 102, 71,
-  89, 83, 91, 125, 89, 78, 80, 73, 94, 90,
-  73, 113, 110, 87, 85, 81, 83, 77, 79, 93,
-  87, 85, 78, 74, 73, 74, 83, 80, 81, 91,
-  70, 70, 85, 85, 90, 80, 85, 61, 62, 91,
-  80, 72, 98, 97, 84, 92, 84, 84, 89, 79,
-  70, 79, 72, 82, 84, 79, 57, 84, 86, 101,
-  53, 86, 111, 89, 98, 77, 83, 83, 111, 73,
-  99, 93, 82, 80, 75, 95, 78, 91, 63, 72,
-  85, 68, 87, 86, 44, 77, 90, 70, 72, 59,
-  98, 82, 94, 89, 90, 87, 79, 83, 90, 93,
-  87, 76, 73, 61, 79, 90, 86, 84, 74, 73,
-  84, 94, 76, 91, 84, 90, 75, 69, 93, 90,
-  82, 72, 88, 95, 92, 108, 91, 87, 87, 86,
-  89, 94, 90, 73, 77, 82, 90, 77, 81, 96,
-  88, 87, 76, 86, 93, 78, 77, 86, 85, 85,
-  73, 75, 76, 80, 86, 76, 92, 79, 78, 76,
-  77, 97, 75, 81, 84, 72, 89, 86, 75, 91,
-  73, 83, 82, 85, 86, 87, 80, 93, 85, 79,
-  97, 87, 91, 83, 70, 96, 96, 93, 80, 86,
-  90, 77, 82, 74, 88, 81, 89, 77, 74, 98,
-  81, 83, 74, 104, 83, 80, 76, 78, 79, 79,
-  94, 84, 63, 84, 83, 75, 81, 76, 94, 97,
-  89, 78, 91, 83, 71, 79, 88, 75, 88, 88,
-  82, 74, 77, 90, 73, 104, 75, 87, 88, 94,
-  69, 83, 89, 94, 88, 75, 82, 86, 82, 81,
-  96, 84, 84, 97, 85, 86, 88, 98, 88, 101,
-  80, 72, 79, 75, 79, 81, 69, 89, 89, 78,
-  87, 88, 92, 75, 80, 79, 91, 93, 83, 76,
-  87, 85, 78, 76, 81, 86, 84, 76, 72, 87,
-  95, 83, 90, 72, 92, 83, 80, 82, 91, 89,
-  91, 82, 86, 73, 83, 82, 82, 77, 73, 86,
-  94, 81, 80, 70, 95, 96, 82, 91, 96, 82,
-  100, 77, 86, 90, 96, 80, 71, 97, 91, 84,
-  74, 97, 76, 88, 70, 104, 81, 79, 78, 100,
-  66, 78, 85, 82, 74, 76, 94, 77, 70, 78,
-  98, 87, 77, 92, 97, 78, 92, 83, 80, 73,
-  81, 81, 72, 90, 76, 88, 91, 96, 70, 89,
-  78, 109, 82, 77, 85, 71, 83, 77, 98, 92,
-  80, 116, 85, 82, 93, 87, 91, 139, 94, 70,
-  84, 63, 81, 87, 58, 93, 108, 73, 97, 83,
-  81, 82, 87, 79, 86, 85, 87, 76, 84, 81,
-  84, 80, 80, 91, 75, 74, 77, 87, 109, 80,
-  84, 65, 82, 75, 83, 76, 99, 87, 89, 76,
-  89, 72, 88, 86, 79, 77, 72, 90, 93, 77,
-  71, 67, 82, 106, 73, 93, 98, 90, 94, 74,
-  72, 79, 106, 76, 67, 111, 86, 79, 73, 90,
-  73, 101, 65, 75, 82, 78, 84, 100, 58, 78,
-  88, 77, 73, 68, 95, 76, 71, 76, 83, 80,
-  79, 81, 87, 78, 90, 85, 83, 80, 80, 89,
-  78, 81, 79, 83, 83, 91, 72, 83, 76, 92,
-  72, 73, 83, 88, 79, 81, 89, 89, 82, 96,
-  85, 84, 87, 87, 85, 105, 90, 74, 81, 77,
-  87, 79, 72, 88, 90, 86, 81, 86, 91, 81,
-  82, 79, 86, 82, 77, 74, 88, 83, 80, 71,
-  84, 78, 77, 81, 79, 95, 84, 82, 77, 77,
-  94, 81, 78, 85, 81, 80, 73, 82, 89, 83,
-  76, 93, 85, 78, 98, 93, 96, 82, 86, 84,
-  95, 94, 82, 95, 93, 81, 84, 78, 86, 74,
-  91, 78, 66, 95, 89, 83, 73, 97, 86, 79,
-  74, 77, 83, 85, 92, 100, 74, 80, 83, 87,
-  76, 77, 94, 88, 74, 77, 87, 82, 62, 80,
-  79, 78, 79, 89, 85, 91, 73, 85, 73, 98,
-  84, 81, 83, 84, 70, 81, 86, 87, 72, 71,
-  81, 97, 70, 78, 79, 80, 88, 88, 81, 93,
-  84, 81, 96, 96, 87, 78, 80, 70, 88, 76,
-  77, 72, 95, 87, 91, 88, 92, 67, 80, 80,
-  91, 86, 85, 85, 90, 86, 75, 79, 89, 98,
-  79, 89, 79, 87, 88, 84, 84, 71, 99, 79,
-  75, 79, 77, 83, 88, 83, 83, 79, 87, 88,
-  94, 66, 76, 92, 93, 89, 101, 72, 90, 94,
-  93, 87, 94, 86, 89, 81, 86, 89, 91, 84,
-  65, 80, 84, 94, 89, 87, 82, 81, 68, 85,
-  78, 92, 73, 99, 85, 77, 87, 90, 74, 84,
-  91, 96, 72, 94, 87, 88, 72, 88, 85, 72,
-  90, 86, 80, 84, 76, 80, 73, 94, 81, 79,
-  85, 88, 75, 88, 82, 89, 77, 74, 86, 89,
-  67, 73, 95, 87, 89, 89, 82, 86, 80, 78,
-  90, 103, 94, 80, 82, 64, 80, 84, 66, 68,
-  111, 73, 95, 91, 85, 82, 88, 74, 85, 79,
-  89, 88, 98, 84, 80, 83, 92, 93, 72, 86,
-  82, 86, 102, 78, 77, 65, 95, 78, 76, 81,
-  79, 80, 91, 72, 84, 81, 84, 87, 98, 68,
-  73, 100, 97, 87, 95, 68, 95, 101, 93, 92,
-  91, 86, 89, 72, 77, 80, 84, 81, 45, 82,
-  90, 92, 86, 94, 77, 90, 64, 81, 81, 98,
-  80, 103, 82, 74, 94, 85, 80, 78, 94, 100,
-  67, 91, 88, 84, 75, 81, 76, 74, 78, 89,
-  81, 92, 75, 83, 77, 90, 85, 77, 82, 83,
-  65, 86, 83, 91, 84, 72, 81, 92, 70, 81,
-  75, 87, 85, 85, 81, 79, 84, 88, 89, 98,
-  90, 80, 82, 72, 85, 80, 82, 75, 91, 86,
-  88, 86, 89, 76, 80, 80, 86, 74, 84, 86,
-  90, 83, 78, 79, 87, 87, 79, 90, 86, 93,
-  83, 88, 67, 76, 93, 80, 74, 80, 75, 85,
-  76, 84, 82, 84, 83, 85, 96, 68, 77, 93,
-  90, 89, 103, 74, 94, 90, 88, 90, 94, 81,
-  88, 82, 88, 78, 92, 83, 68, 86, 78, 91,
-  85, 82, 90, 80, 71, 81, 84, 93, 88, 99,
-  88, 80, 97, 87, 72, 84, 90, 93, 76, 93,
-  96, 69, 80, 88, 89, 84, 81, 87, 80, 84,
-  89, 84, 80, 74, 85, 69, 79, 77, 80, 90,
-  91, 82, 81, 83, 92, 77, 87, 82, 91, 81,
-  81, 77, 71, 91, 76, 87, 76, 86, 93, 80,
-  78, 95, 88, 91, 89, 93, 85, 80, 80, 79,
-  97, 86, 82, 80, 87, 221, 79, 86, 83, 84,
-  87, 78, 78, 85, 88, 84, 79, 94, 83, 75,
-  92, 84, 79, 81, 90, 78, 75, 103, 92, 87,
-  77, 87, 85, 80, 86, 87, 87, 92, 75, 80,
-  74, 85, 78, 85, 94, 87, 82, 84, 105, 85,
-  78, 81, 83, 94, 93, 88, 83, 90, 95, 86,
-  79, 81, 92, 83, 69, 97, 89, 87, 84, 82,
-  87, 87, 82, 80, 88, 85, 86, 88, 83, 79,
-  84, 88, 86, 73, 82, 90, 89, 87, 83, 93,
-  77, 75, 82, 85, 78, 80, 86, 92, 87, 76,
-  78, 82, 83, 74, 101, 81, 87, 82, 75, 83,
-  73, 82, 79, 80, 86, 84, 67, 76, 85, 86,
-  86, 93, 86, 85, 86, 81, 75, 77, 99, 82,
-  82, 79, 83, 159, 79, 88, 82, 84, 82, 74,
-  87, 74, 87, 78, 72, 83, 73, 84, 69, 76,
-  92, 86, 89, 82, 76, 84, 90, 85, 84, 92,
-  86, 92, 75, 86, 85, 81, 82, 81, 75, 95,
-  78, 79, 89, 78, 83, 83, 85, 79, 85, 82,
-  78, 91, 90, 82, 88, 90, 91, 87, 78, 79,
-  90, 85, 80, 74, 79, 85, 75, 84, 86, 82,
-  82, 81, 79, 83, 81, 85, 87, 82, 97, 81,
-  89, 74, 80, 81, 85, 83, 87, 88, 85, 78,
-  86, 89, 80, 87, 90, 99, 88, 81, 82, 81,
-  81, 80, 93, 78, 92, 88, 84, 84, 77, 86,
-  79, 86, 87, 89, 70, 88, 93, 83, 87, 91,
-  85, 78, 88, 89, 74, 88, 88, 76, 82, 80,
-  77, 87, 82, 87, 83, 84, 88, 87, 88, 90,
-  85, 72, 83, 87, 80, 98, 72, 85, 85, 93,
-  90, 84, 79, 86, 82, 77, 88, 83, 84, 95,
-  93, 88, 91, 88, 79, 77, 74, 90, 85, 81,
-  90, 78, 84, 89, 72, 71, 80, 86, 79, 92,
-  85, 87, 85, 85, 85, 86, 89, 85, 82, 82,
-  94, 77, 82, 88, 87, 81, 79, 86, 81, 82,
-  84, 86, 84, 90, 87, 74, 80, 91, 84, 79,
-  85, 84, 81, 85, 91, 84, 80, 76, 89, 81,
-  84, 82, 85, 89, 89, 80, 76, 84, 86, 81,
-  85, 83, 88, 81, 75, 81, 84, 86, 88, 89,
-  78, 86, 83, 86, 78, 77, 83, 85, 85, 94,
-  74, 84, 79, 94, 93, 82, 86, 84, 85, 115,
-  79, 81, 86, 92, 85, 84, 83, 84, 84, 83,
-  78, 92, 85, 70, 80, 79, 83, 81, 82, 84,
-  77, 82, 86, 87, 82, 77, 87, 84, 82, 87,
-  87, 81, 76, 92, 79, 80, 86, 92, 87, 81,
-  83, 84, 91, 82, 80, 89, 83, 90, 79, 83,
-  90, 84, 83, 82, 81, 81, 86, 87, 70, 77,
-  82, 83, 82, 81, 88, 90, 88, 87, 87, 84,
-  82, 84, 88, 83, 90, 89, 83, 72, 80, 81,
-  84, 87, 84, 87, 78, 87, 82, 84, 79, 76,
-  85, 90, 81, 74, 80, 89, 81, 74, 94, 83,
-  83, 86, 81, 89, 85, 78, 88, 83, 86, 89,
-  73, 80, 83, 87, 86, 86, 83, 85, 88, 90,
-  82, 89, 96, 79, 88, 83, 85, 110, 81, 85,
-  87, 80, 80, 76, 85, 78, 81, 81, 78, 80,
-  81, 71, 53, 77, 83, 83, 85, 79, 85, 77,
-  83, 84, 86, 81, 83, 91, 83, 83, 79, 81,
-  86, 91, 72, 79, 79, 82, 77, 78, 86, 79,
-  88, 78, 78, 92, 87, 89, 83, 80, 91, 87,
-  92, 81, 84, 78, 90, 79, 79, 73, 72, 82,
-  80, 89, 85, 85, 80, 84, 81, 82, 82, 88,
-  89, 82, 90, 84, 91, 79, 77, 75, 78, 82,
-  90, 83, 79, 82, 83, 78, 74, 75, 87, 97,
-  86, 82, 79, 86, 83, 77, 92, 79, 91, 87,
-  93, 88, 82, 89, 89, 90, 85, 93, 73, 91,
-  90, 91, 87, 85, 83, 76, 98, 98, 88, 90,
-  94, 76, 86, 81, 78, 77, 83, 86, 84, 79,
-  85, 89, 82, 89, 75, 80, 82, 90, 86, 80,
-  51, 88, 78, 86, 91, 78, 85, 85, 83, 81,
-  86, 85, 85, 89, 93, 85, 85, 94, 81, 79,
-  74, 73, 85, 79, 83, 83, 85, 86, 83, 76,
-  73, 87, 89, 92, 88, 81, 91, 82, 92, 82,
-  92, 86, 85, 74, 87, 83, 80, 84, 87, 92,
-  81, 85, 77, 79, 85, 85, 83, 95, 94, 84,
-  79, 82, 84, 86, 84, 75, 75, 88, 90, 81,
-  90, 92, 82, 75, 78, 79, 84, 89, 81, 83,
-  75, 85, 84, 77, 81, 85, 86, 91, 81, 82,
-  83, 85, 98, 84, 86, 87, 97, 82, 80, 94,
-  76, 83, 85, 82, 83, 86, 78, 99, 91, 81,
-  82, 83, 88, 83, 79, 78, 84, 84, 83, 79,
-  83, 82, 85, 96, 80, 82, 82, 80, 94, 84,
-  72, 81, 84, 81, 79, 78, 76, 92, 80, 76,
-  82, 83, 88, 88, 81, 84, 88, 86, 73, 77,
-  83, 85, 85, 76, 84, 78, 86, 81, 85, 88,
-  87, 90, 84, 84, 88, 84, 82, 81, 79, 80,
-  82, 80, 93, 77, 78, 82, 87, 84, 84, 88,
-  77, 88, 86, 81, 81, 93, 87, 92, 98, 87,
-  88, 76, 83, 75, 82, 87, 87, 78, 83, 101,
-  80, 77, 78, 78, 91, 90, 77, 76, 86, 88,
-  83, 80, 85, 85, 84, 93, 83, 85, 85, 77,
-  96, 79, 82, 86, 85, 84, 82, 87, 81, 82,
-  82, 87, 85, 86, 82, 98, 87, 78, 84, 85,
-  87, 76, 77, 78, 86, 79, 81, 86, 82, 77,
-  82, 88, 84, 74, 78, 78, 66, 75, 78, 86,
-  83, 80, 83, 76, 78, 90, 83, 72, 83, 84,
-  88, 87, 79, 83, 90, 87, 72, 81, 84, 89,
-  80, 83, 87, 78, 79, 81, 79, 88, 84, 86,
-  81, 75, 87, 82, 85, 81, 89, 79, 84, 78,
-  90, 73, 70, 82, 83, 86, 84, 88, 78, 88,
-  86, 82, 84, 91, 84, 86, 98, 90, 91, 83,
-  84, 73, 78, 84, 87, 75, 78, 88, 84, 76,
-  74, 81, 89, 94, 83, 86, 90, 87, 85, 82,
-  86, 83, 91, 84, 83, 84, 89, 83, 85, 90,
-  71, 87, 78, 94, 85, 76, 85, 84, 83, 82,
-  86, 88, 89, 101, 84, 78, 85, 81, 81, 62,
-  83, 75, 82, 80, 85, 93, 78, 76, 86, 81,
-  85, 84, 80, 79, 62, 81, 80, 89, 87, 84,
-  83, 81, 80, 84, 82, 73, 86, 88, 87, 89,
-  90, 83, 77, 83, 81, 75, 89, 87, 85, 91,
-  86, 81, 80, 79, 77, 89, 80, 89, 81, 74,
-  96, 78, 85, 77, 92, 85, 83, 81, 75, 77,
-  80, 82, 83, 85, 85, 88, 77, 83, 89, 86,
-  82, 91, 88, 68, 98, 87, 79, 76, 91, 83,
-  68, 85, 78, 81, 100, 90, 80, 92, 85, 81,
-  78, 94, 80, 93, 85, 85, 90, 87, 70, 84,
-  88, 99, 99, 84, 79, 85, 92, 80, 69, 82,
-  92, 83, 77, 73, 95, 98, 91, 87, 92, 94,
-  80, 83, 95, 78, 85, 85, 73, 81, 79, 80,
-  81, 98, 80, 81, 96, 74, 82, 76, 84, 81,
-  79, 94, 95, 82, 88, 82, 89, 72, 81, 95,
-  87, 87, 83, 72, 97, 82, 79, 79, 88, 86,
-  73, 102, 82, 86, 79, 75, 76, 101, 86, 85,
-  83, 87, 80, 76, 102, 73, 89, 77, 79, 94,
-  86, 62, 85, 89, 81, 81, 79, 73, 96, 88,
-  85, 83, 93, 70, 65, 82, 95, 97, 84, 75,
-  80, 84, 77, 82, 81, 75, 94, 75, 56, 84,
-  88, 87, 105, 96, 78, 86, 87, 78, 85, 115,
-  89, 88, 80, 76, 82, 77, 56, 78, 98, 99,
-  94, 87, 60, 97, 84, 76, 61, 74, 93, 75,
-  74, 63, 89, 122, 105, 71, 81, 82, 66, 60,
-  102, 61, 75, 81, 54, 86, 76, 81, 72, 112,
-  92, 76, 100, 81, 75, 76, 80, 88, 75, 78,
-  88, 81, 79, 80, 98, 59, 77, 86, 93, 83,
-  83, 93, 89, 84, 97, 78, 82, 91, 69, 104,
-  81, 92, 79, 70, 81, 137, 87, 86, 84, 81,
-  70, 90, 96, 71, 81, 69, 84, 115, 84, 68,
-  87, 77, 76, 79, 77, 60, 81, 94, 92, 79,
-  92, 70, 40, 76, 90, 96, 86, 61, 85, 98,
-  90, 89, 72, 84, 86, 85, 69, 85, 78, 86,
-  95, 87, 80, 90, 88, 77, 80, 88, 86, 96,
-  70, 81, 79, 88, 78, 81, 84, 96, 93, 83,
-  77, 76, 95, 78, 75, 78, 86, 82, 75, 74,
-  79, 92, 94, 84, 86, 87, 76, 83, 94, 84,
-  81, 89, 77, 80, 81, 80, 80, 97, 86, 84,
-  92, 69, 82, 80, 73, 78, 79, 86, 91, 89,
-  86, 82, 89, 73, 84, 87, 93, 90, 82, 68,
-  96, 84, 78, 81, 83, 83, 71, 97, 83, 96,
-  87, 77, 87, 96, 88, 84, 94, 88, 82, 90,
-  97, 71, 89, 78, 73, 89, 84, 70, 94, 90,
-  83, 92, 71, 74, 98, 87, 88, 83, 91, 74,
-  68, 81, 90, 94, 83, 83, 103, 70, 81, 83,
-  78, 79, 91, 78, 66, 86, 95, 88, 91, 76,
-  74, 98, 82, 74, 87, 86, 84, 88, 86, 92,
-  83, 88, 79, 88, 91, 94, 94, 76, 88, 94,
-  96, 89, 75, 69, 99, 70, 65, 76, 94, 80,
-  91, 96, 81, 102, 74, 76, 100, 75, 86, 91,
-  74, 98, 69, 76, 86, 98, 85, 84, 81, 79,
-  72, 77, 77, 78, 73, 73, 112, 87, 82, 79,
-  85, 76, 80, 89, 87, 85, 84, 77, 95, 83,
-  83, 84, 87, 89, 75, 92, 76, 71, 81, 72,
-  80, 98, 85, 83, 82, 94, 72, 85, 95, 76,
-  91, 89, 80, 79, 82, 73, 85, 85, 77, 86,
-  71, 71, 77, 80, 73, 80, 88, 75, 72, 77,
-  88, 84, 89, 76, 96, 87, 77, 82, 77, 69,
-  93, 70, 55, 93, 120, 90, 103, 93, 71, 109,
-  88, 75, 105, 106, 97, 77, 69, 88, 69, 72,
-  70, 85, 101, 101, 93, 80, 70, 104, 92, 81,
-  66, 75, 91, 50, 60, 66, 105, 96, 105, 81,
-  66, 81, 59, 51, 115, 63, 71, 84, 45, 88,
-  69, 79, 65, 140, 94, 73, 73, 93, 56, 75,
-  72, 94, 65, 60, 80, 85, 74, 84, 85, 65,
-  77, 90, 95, 83, 86, 99, 87, 85, 104, 93,
-  80, 96, 70, 99, 79, 72, 73, 60, 84, 122,
-  80, 84, 74, 91, 73, 78, 96, 79, 84, 74,
-  82, 105, 76, 73, 95, 70, 65, 79, 80, 60,
-  73, 77, 71, 83, 95, 77, 36, 66, 81, 84,
-  96, 68, 96, 98, 99, 85, 74, 91, 90, 78,
-  67, 88, 89, 92, 87, 99, 74, 89, 83, 70,
-  90, 82, 85, 101, 70, 87, 72, 90, 83, 84,
-  88, 97, 95, 86, 84, 82, 95, 87, 80, 72,
-  82, 71, 56, 74, 82, 84, 96, 88, 77, 81,
-  77, 76, 98, 92, 80, 94, 76, 66, 72, 74,
-  79, 93, 89, 84, 79, 69, 73, 76, 76, 80,
-  78, 78, 75, 93, 78, 78, 85, 78, 86, 91,
-  84, 85, 84, 73, 95, 88, 82, 87, 83, 86,
-  74, 89, 78, 77, 80, 70, 82, 95, 87, 81,
-  89, 95, 74, 71, 94, 78, 86, 91, 76, 78,
-  77, 77, 97, 84, 79, 92, 83, 79, 106, 79,
-  76, 86, 90, 79, 74, 80, 83, 83, 90, 84,
-  96, 74, 82, 85, 73, 84, 79, 86, 84, 81,
-  84, 95, 83, 87, 64, 105, 82, 77, 95, 82,
-  87, 93, 82, 101, 78, 89, 94, 84, 77, 92,
-  84, 78, 87, 78, 100, 92, 87, 78, 97, 79,
-  75, 73, 73, 72, 76, 100, 86, 91, 79, 98,
-  89, 84, 96, 95, 99, 94, 74, 80, 108, 81,
-  86, 89, 80, 87, 81, 78, 75, 77, 75, 89,
-  93, 88, 83, 76, 85, 81, 86, 87, 87, 60,
-  80, 65, 96, 74, 66, 98, 84, 80, 91, 89,
-  77, 80, 91, 82, 85, 72, 82, 75, 92, 96,
-  78, 93, 87, 73, 103, 98, 75, 69, 77, 89,
-  92, 86, 90, 84, 76, 92, 69, 75, 77, 72,
-  98, 83, 89, 83, 83, 82, 86, 88, 94, 79,
-  76, 87, 65, 70, 79, 79, 82, 86, 102, 97,
-  86, 95, 72, 106, 81, 83, 104, 77, 83, 85,
-  70, 100, 76, 75, 98, 84, 90, 95, 84, 86,
-  100, 78, 104, 74, 84, 82, 91, 65, 69, 62,
-  89, 72, 76, 100, 75, 81, 67, 97, 91, 95,
-  92, 92, 87, 93, 69, 85, 94, 94, 89, 81,
-  63, 93, 73, 73, 72, 81, 65, 82, 87, 78,
-  80, 77, 82, 75, 88, 75, 94, 50, 82, 67,
-  97, 87, 70, 98, 80, 83, 95, 102, 72, 75,
-  86, 79, 84, 73, 92, 76, 80, 96, 82, 79,
-  82, 76, 106, 110, 76, 75, 77, 90, 107, 82,
-  86, 79, 80, 94, 73, 70, 66, 77, 96, 84,
-  81, 79, 72, 86, 86, 103, 88, 83, 87, 82,
-  77, 82, 81, 80, 81, 86, 82, 95, 81, 96,
-  68, 103, 80, 75, 91, 77, 72, 94, 80, 101,
-  81, 91, 92, 82, 76, 93, 89, 87, 89, 87,
-  99, 77, 87, 75, 78, 81, 71, 72, 91, 79,
-  76, 97, 86, 89, 79, 99, 88, 88, 95, 96,
-  96, 80, 75, 82, 96, 82, 91, 89, 77, 79,
-  81, 76, 79, 80, 71, 89, 70, 86, 79, 72,
-  86, 84, 85, 80, 90, 58, 85, 64, 89, 97,
-  67, 93, 85, 82, 90, 93, 76, 75, 89, 85,
-  90, 76, 79, 74, 85, 93, 80, 70, 89, 74,
-  108, 97, 74, 74, 82, 94, 92, 84, 91, 85,
-  83, 98, 94, 77, 80, 76, 84, 83, 93, 86,
-  85, 86, 91, 89, 81, 79, 81, 76, 72, 78,
-  79, 86, 89, 76, 87, 83, 76, 84, 75, 81,
-  73, 86, 89, 80, 89, 74, 88, 79, 80, 79,
-  92, 86, 101, 79, 91, 82, 99, 76, 79, 95,
-  82, 79, 82, 73, 91, 83, 78, 87, 80, 93,
-  71, 87, 84, 84, 82, 87, 68, 92, 97, 80,
-  78, 84, 76, 76, 75, 83, 79, 85, 92, 89,
-  81, 84, 84, 85, 85, 78, 73, 73, 89, 84,
-  101, 84, 82, 87, 76, 78, 86, 77, 85, 80,
-  81, 76, 82, 85, 95, 77, 78, 86, 77, 85,
-  87, 88, 85, 96, 94, 80, 84, 73, 91, 75,
-  75, 86, 80, 71, 79, 92, 90, 81, 89, 89,
-  85, 81, 86, 88, 89, 87, 81, 76, 91, 83,
-  88, 94, 80, 80, 83, 80, 74, 78, 74, 90,
-  98, 71, 94, 76, 75, 83, 75, 81, 73, 82,
-  102, 86, 79, 76, 80, 75, 87, 73, 94, 85,
-  93, 79, 82, 93, 111, 79, 77, 83, 85, 72,
-  83, 74, 86, 84, 76, 85, 71, 90, 72, 86,
-  86, 93, 92, 87, 68, 98, 107, 85, 88, 76,
-  68, 72, 80, 95, 82, 90, 91, 89, 79, 80,
-  81, 90, 82, 76, 76, 73, 85, 99, 114, 83,
-  82, 91, 80, 75, 89, 80, 82, 83, 88, 76,
-  78, 77, 106, 82, 80, 78, 82, 81, 104, 86,
-  79, 95, 96, 86, 86, 73, 84, 72, 79, 86,
-  81, 77, 72, 99, 93, 86, 86, 91, 85, 77,
-  81, 93, 81, 88, 84, 77, 99, 83, 85, 98,
-  83, 78, 82, 72, 72, 85, 78, 86, 85, 75,
-  83, 82, 78, 83, 74, 80, 79, 87, 87, 82,
-  81, 76, 76, 78, 85, 79, 93, 84, 99, 83,
-  90, 91, 97, 84, 78, 81, 85, 79, 80, 73,
-  87, 80, 88, 85, 77, 91, 73, 86, 82, 80,
-  84, 88, 70, 92, 97, 86, 79, 85, 74, 80,
-  79, 83, 82, 82, 97, 90, 80, 87, 83, 86,
-  89, 73, 78, 71, 86, 77, 96, 81, 80, 84,
-  77, 74, 88, 86, 83, 81, 82, 76, 84, 86,
-  93, 80, 80, 88, 73, 84, 81, 86, 80, 90,
-  91, 85, 84, 78, 88, 75, 74, 90, 78, 73,
-  79, 90, 92, 82, 80, 92, 82, 81, 86, 90,
-  78, 82, 80, 77, 86, 82, 85, 91, 79, 80,
-  82, 79, 77, 77, 74, 84, 98, 73, 101, 82,
-  74, 85, 78, 76, 73, 81, 97, 80, 86, 82,
-  86, 79, 85, 75, 81, 90, 84, 78, 74, 86,
-  108, 71, 82, 98, 76, 84, 79, 66, 77, 87,
-  78, 82, 73, 95, 73, 85, 84, 85, 88, 87,
-  67, 101, 104, 87, 84, 77, 76, 73, 74, 96,
-  76, 81, 89, 84, 74, 84, 94, 78, 85, 74,
-  79, 77, 92, 90, 112, 91, 80, 81, 82, 75,
-  88, 73, 89, 82, 79, 78, 78, 71, 98, 80,
-  80, 78, 85, 90, 105, 90, 90, 96, 92, 76,
-  82, 75, 83, 82, 80, 79, 78, 76, 80, 92,
-  93, 81, 80, 87, 87, 76, 80, 99, 91, 91,
-  81, 76, 92, 81, 88, 100, 77, 77, 90, 83,
-  79, 85, 72, 88, 120, 71, 109, 72, 75, 83,
-  84, 72, 70, 78, 118, 81, 82, 84, 82, 78,
-  88, 70, 86, 99, 81, 81, 62, 103, 126, 70,
-  82, 85, 77, 79, 83, 68, 70, 86, 76, 76,
-  72, 100, 71, 86, 81, 101, 101, 101, 61, 108,
-  123, 85, 83, 75, 69, 67, 69, 114, 73, 90,
-  88, 93, 68, 75, 94, 78, 80, 69, 89, 84,
-  83, 106, 135, 82, 79, 85, 81, 74, 91, 87,
-  90, 83, 85, 79, 79, 67, 106, 79, 80, 67,
-  99, 89, 127, 90, 83, 105, 96, 81, 85, 77,
-  73, 83, 83, 76, 78, 82, 79, 92, 99, 84,
-  79, 90, 88, 73, 76, 101, 81, 92, 78, 70,
-  100, 80, 87, 112, 78, 76, 87, 75, 79, 85,
-  72, 89, 97, 72, 96, 84, 76, 79, 78, 76,
-  79, 85, 97, 83, 84, 76, 76, 82, 85, 75,
-  80, 89, 81, 87, 80, 97, 103, 82, 79, 82,
-  82, 80, 84, 69, 76, 82, 83, 83, 75, 94,
-  80, 88, 84, 82, 88, 86, 68, 101, 102, 82,
-  80, 82, 72, 80, 76, 93, 76, 80, 86, 84,
-  77, 85, 90, 79, 93, 73, 80, 81, 90, 87,
-  103, 73, 77, 80, 80, 77, 92, 98, 91, 81,
-  81, 80, 80, 80, 101, 78, 84, 81, 79, 87,
-  97, 88, 79, 94, 92, 82, 85, 79, 78, 80,
-  78, 82, 79, 77, 84, 88, 98, 81, 78, 85,
-  85, 76, 79, 94, 76, 88, 81, 78, 90, 82,
-  86, 95, 78, 87, 83, 74, 71, 77, 80, 88,
-  89, 72, 88, 93, 81, 85, 77, 75, 76, 84,
-  83, 81, 81, 83, 78, 78, 87, 78, 84, 84,
-  90, 77, 74, 86, 100, 77, 78, 98, 83, 87,
-  74, 75, 79, 85, 78, 83, 77, 93, 80, 91,
-  87, 72, 87, 88, 72, 101, 96, 85, 83, 74,
-  79, 74, 78, 84, 83, 81, 87, 85, 76, 88,
-  88, 80, 83, 80, 71, 80, 93, 80, 97, 83,
-  83, 84, 83, 85, 94, 80, 89, 84, 77, 75,
-  79, 75, 91, 80, 80, 82, 85, 90, 84, 86,
-  93, 98, 90, 76, 80, 78, 83, 79, 75, 80,
-  75, 75, 83, 92, 90, 82, 85, 90, 78, 79,
-  82, 92, 90, 85, 82, 78, 83, 80, 87, 85,
-  81, 84, 91, 78, 75, 79, 76, 91, 97, 72,
-  92, 85, 84, 80, 80, 69, 72, 84, 95, 82,
-  82, 81, 78, 75, 88, 75, 91, 91, 85, 78,
-  70, 98, 113, 74, 76, 88, 82, 86, 81, 75,
-  70, 85, 83, 84, 79, 93, 82, 90, 84, 81,
-  92, 90, 70, 102, 103, 82, 81, 72, 66, 74,
-  73, 88, 79, 88, 90, 89, 73, 84, 89, 84,
-  85, 76, 71, 87, 89, 89, 105, 87, 81, 84,
-  81, 87, 95, 93, 90, 84, 81, 73, 76, 76,
-  103, 80, 80, 77, 89, 87, 92, 88, 89, 100,
-  96, 76, 79, 77, 75, 85, 80, 81, 78, 77,
-  81, 91, 94, 82, 84, 88, 84, 75, 76, 89,
-  81, 88, 82, 74, 92, 79, 87, 91, 77, 80,
-  84, 72, 75, 74, 79, 92, 90, 73, 83, 93,
-  82, 75, 76, 77, 79, 85, 87, 76, 84, 77,
-  73, 78, 90, 78, 82, 84, 88, 81, 83, 94,
-  91, 83, 78, 83, 85, 82, 82, 78, 77, 83,
-  82, 83, 77, 92, 87, 87, 87, 70, 85, 82,
-  71, 98, 96, 82, 76, 78, 75, 76, 80, 87,
-  82, 80, 79, 86, 82, 87, 85, 83, 88, 81,
-  69, 81, 93, 80, 97, 86, 82, 84, 77, 87,
-  94, 95, 93, 82, 82, 79, 83, 85, 92, 82,
-  84, 87, 83, 89, 78, 87, 85, 101, 91, 76,
-  83, 79, 81, 79, 75, 84, 79, 73, 83, 87,
-  91, 78, 87, 93, 79, 80, 82, 89, 83, 87,
-  83, 80, 83, 80, 86, 81, 87, 76, 82, 89,
-  80, 75, 102, 87, 106, 81, 77, 94, 67, 91,
-  117, 78, 76, 84, 74, 72, 78, 69, 73, 80,
-  91, 70, 92, 88, 94, 62, 85, 74, 80, 88,
-  75, 83, 72, 85, 96, 88, 70, 130, 77, 94,
-  101, 75, 81, 86, 67, 101, 83, 76, 91, 94,
-  78, 82, 84, 63, 80, 88, 67, 77, 81, 105,
-  93, 104, 79, 89, 73, 97, 75, 86, 79, 67,
-  93, 86, 112, 82, 73, 76, 93, 89, 93, 78,
-  91, 84, 75, 79, 82, 75, 91, 81, 86, 76,
-  70, 86, 74, 96, 79, 77, 98, 67, 90, 74,
-  85, 86, 86, 90, 77, 88, 86, 93, 88, 92,
-  74, 80, 95, 76, 76, 64, 95, 83, 67, 82,
-  72, 78, 88, 77, 95, 83, 80, 87, 85, 79,
-  94, 83, 91, 82, 82, 90, 69, 91, 111, 82,
-  76, 89, 75, 79, 73, 78, 70, 81, 86, 76,
-  91, 90, 80, 69, 83, 74, 83, 85, 77, 82,
-  74, 85, 95, 91, 78, 114, 75, 92, 107, 74,
-  79, 85, 77, 108, 79, 79, 83, 90, 82, 79,
-  73, 72, 82, 96, 75, 79, 81, 94, 89, 106,
-  80, 96, 77, 104, 74, 95, 81, 66, 95, 77,
-  110, 73, 80, 71, 94, 81, 92, 74, 90, 75,
-  82, 73, 78, 87, 81, 86, 88, 88, 75, 85,
-  72, 108, 83, 73, 102, 79, 86, 80, 86, 88,
-  78, 85, 78, 87, 85, 100, 89, 84, 73, 75,
-  82, 78, 76, 59, 80, 84, 54, 79, 76, 82,
-  85, 85, 85, 89, 75, 88, 86, 85, 94, 87,
-  99, 82, 78, 99, 68, 97, 111, 79, 75, 81,
-  79, 72, 79, 74, 69, 79, 82, 73, 91, 86,
-  92, 71, 82, 73, 82, 86, 74, 104, 73, 82,
-  90, 88, 73, 122, 83, 93, 101, 75, 81, 88,
-  70, 100, 83, 77, 88, 95, 76, 84, 92, 62,
-  86, 85, 76, 76, 86, 102, 92, 101, 78, 90,
-  74, 91, 84, 83, 83, 70, 95, 85, 109, 75,
-  79, 74, 93, 84, 94, 85, 89, 78, 95, 75,
-  76, 89, 93, 84, 86, 76, 74, 83, 76, 95,
-  86, 81, 100, 76, 90, 74, 82, 83, 88, 89,
-  75, 86, 90, 89, 91, 81, 69, 77, 78, 79,
-  76, 69, 67, 81, 70, 82, 72, 78, 88, 79,
-  100, 79, 76, 88, 72, 84, 102, 92, 100, 86,
-  76, 85, 75, 100, 112, 74, 84, 87, 83, 76,
-  76, 59, 83, 80, 89, 71, 84, 89, 74, 63,
-  81, 70, 82, 88, 99, 86, 73, 84, 80, 78,
-  73, 127, 92, 90, 97, 78, 82, 90, 72, 97,
-  87, 80, 77, 95, 85, 79, 81, 66, 76, 93,
-  61, 80, 76, 93, 85, 106, 85, 76, 78, 87,
-  80, 92, 76, 79, 90, 82, 105, 90, 76, 77,
-  91, 87, 82, 78, 86, 81, 75, 80, 85, 64,
-  85, 70, 83, 82, 80, 95, 73, 96, 83, 70,
-  84, 72, 82, 73, 81, 83, 85, 92, 72, 87,
-  90, 96, 89, 86, 68, 88, 94, 78, 71, 72,
-  86, 88, 64, 77, 74, 76, 91, 90, 122, 85,
-  80, 90, 77, 84, 104, 86, 95, 95, 86, 79,
-  82, 84, 118, 87, 92, 83, 86, 84, 80, 70,
-  70, 88, 93, 86, 82, 94, 62, 79, 83, 83,
-  87, 92, 96, 76, 75, 95, 93, 89, 81, 152,
-  80, 91, 111, 82, 83, 93, 85, 117, 77, 94,
-  76, 92, 102, 80, 79, 83, 75, 111, 74, 76,
-  70, 120, 80, 126, 96, 92, 86, 89, 76, 118,
-  69, 75, 99, 79, 114, 75, 76, 78, 94, 83,
-  85, 66, 95, 82, 72, 75, 90, 71, 80, 66,
-  81, 106, 77, 105, 75, 112, 90, 69, 87, 82,
-  79, 78, 87, 88, 82, 85, 83, 89, 100, 101,
-  92, 71, 64, 85, 79, 85, 74, 71, 64, 99,
-  52, 69, 87, 76, 92, 115, 90, 86, 87, 87,
-  76, 99, 95, 89, 95, 87, 74, 85, 70, 80,
-  106, 83, 85, 86, 86, 74, 89, 57, 74, 76,
-  81, 74, 78, 86, 72, 89, 79, 80, 84, 81,
-  80, 100, 79, 85, 100, 84, 76, 115, 77, 89,
-  94, 80, 84, 96, 74, 95, 90, 82, 75, 94,
-  85, 81, 83, 65, 81, 89, 68, 77, 76, 87,
-  83, 102, 86, 80, 78, 84, 84, 86, 80, 77,
-  97, 84, 103, 83, 80, 78, 91, 86, 83, 93,
-  83, 80, 86, 76, 83, 80, 84, 73, 83, 83,
-  77, 91, 74, 95, 83, 74, 82, 77, 86, 74,
-  80, 81, 85, 88, 74, 84, 101, 92, 91, 76,
-  66, 88, 81, 80, 71, 72, 57, 89, 65, 80,
-  74, 79, 90, 92, 99, 85, 73, 86, 80, 81,
-  100, 99, 99, 85, 76, 95, 75, 98, 113, 77,
-  86, 83, 86, 78, 86, 73, 74, 77, 82, 69,
-  92, 87, 84, 69, 82, 70, 83, 90, 89, 86,
-  77, 84, 86, 77, 87, 135, 90, 99, 92, 79,
-  87, 94, 73, 89, 90, 81, 83, 94, 78, 88,
-  87, 65, 81, 88, 64, 82, 75, 98, 92, 111,
-  86, 72, 76, 88, 85, 83, 80, 83, 90, 83,
-  99, 82, 86, 72, 96, 78, 82, 71, 94, 76,
-  76, 79, 75, 76, 93, 75, 84, 84, 82, 93,
-  69, 92, 87, 75, 90, 73, 93, 71, 79, 79,
-  89, 106, 77, 83, 85, 94, 92, 83, 77, 82,
-  84, 79, 74, 79, 79, 84, 66, 81, 77, 88,
-  84, 81, 108, 81, 80, 83, 82, 83, 100, 95,
-  89, 80, 76, 90, 76, 83, 109, 86, 90, 86,
-  90, 84, 88, 82, 71, 77, 78, 66, 94, 90,
-  74, 86, 80, 79, 92, 86, 91, 79, 80, 84,
-  89, 80, 93, 122, 86, 96, 91, 84, 93, 86,
-  77, 91, 89, 86, 77, 91, 86, 81, 80, 74,
-  78, 90, 77, 85, 73, 90, 81, 109, 97, 77,
-  79, 97, 75, 80, 79, 84, 90, 75, 92, 78,
-  95, 66, 98, 76, 84, 71, 89, 80, 76, 73,
-  80, 75, 90, 75, 79, 90, 80, 92, 67, 99,
-  87, 73, 91, 70, 81, 77, 72, 86, 82, 104,
-  81, 84, 90, 105, 91, 75, 81, 78, 82, 80,
-  72, 79, 69, 83, 57, 72, 81, 90, 77, 96,
-  96, 86, 91, 82, 81, 88, 99, 94, 97, 85,
-  76, 93, 72, 82, 110, 85, 87, 82, 90, 77,
-  87, 72, 73, 77, 81, 72, 87, 85, 82, 88,
-  82, 78, 83, 89, 78, 98, 80, 86, 98, 80,
-  89, 130, 79, 95, 96, 80, 86, 86, 75, 87,
-  89, 81, 79, 92, 77, 82, 85, 69, 80, 83,
-  75, 79, 72, 99, 84, 110, 93, 74, 77, 86,
-  81, 83, 80, 83, 87, 84, 97, 80, 84, 74,
-  96, 85, 85, 89, 95, 79, 81, 77, 78, 83,
-  89, 67, 87, 86, 80, 90, 73, 91, 81, 78,
-  86, 72, 93, 71, 79, 80, 86, 100, 80, 84,
-  92, 93, 94, 75, 77, 87, 84, 82, 77, 79,
-  56, 81, 69, 79, 80, 95, 86, 82, 83, 88,
-  87, 95, 81, 84, 81, 76, 79, 60, 86, 89,
-  71, 78, 79, 90, 76, 83, 84, 97, 92, 88,
-  80, 77, 87, 83, 88, 91, 92, 86, 80, 83,
-  75, 83, 86, 63, 80, 97, 80, 78, 80, 76,
-  89, 83, 75, 90, 84, 96, 77, 77, 78, 89,
-  75, 88, 94, 83, 74, 84, 82, 79, 93, 78,
-  78, 81, 96, 77, 69, 78, 92, 93, 86, 82,
-  89, 85, 90, 71, 81, 100, 77, 90, 83, 77,
-  83, 79, 85, 86, 81, 81, 90, 76, 89, 77,
-  89, 86, 75, 87, 72, 82, 89, 100, 79, 71,
-  74, 81, 80, 85, 70, 79, 81, 90, 80, 85,
-  105, 117, 85, 77, 86, 76, 92, 88, 83, 90,
-  71, 78, 89, 105, 98, 86, 85, 93, 88, 112,
-  79, 90, 83, 72, 82, 60, 93, 93, 87, 79,
-  83, 99, 79, 88, 87, 99, 93, 91, 76, 74,
-  88, 79, 94, 113, 98, 86, 79, 58, 80, 90,
-  91, 82, 78, 96, 80, 72, 83, 82, 95, 89,
-  73, 80, 87, 82, 64, 83, 78, 88, 76, 79,
-  89, 88, 74, 85, 87, 90, 106, 70, 79, 79,
-  72, 78, 78, 86, 84, 90, 81, 85, 69, 84,
-  84, 74, 90, 82, 82, 89, 86, 75, 89, 69,
-  89, 79, 88, 92, 94, 73, 80, 73, 78, 85,
-  65, 96, 73, 91, 89, 89, 79, 79, 104, 82,
-  68, 87, 75, 83, 75, 91, 76, 94, 104, 82,
-  79, 91, 81, 77, 92, 82, 81, 89, 72, 83,
-  93, 90, 107, 93, 80, 79, 91, 105, 84, 99,
-  83, 82, 77, 70, 90, 91, 80, 79, 82, 92,
-  83, 83, 76, 89, 88, 81, 85, 84, 86, 86,
-  84, 91, 79, 91, 85, 67, 80, 91, 87, 125,
-  82, 93, 81, 72, 78, 78, 92, 89, 80, 93,
-  83, 78, 81, 79, 80, 82, 76, 80, 88, 89,
-  80, 83, 87, 82, 94, 70, 82, 77, 82, 78,
-  82, 84, 93, 93, 91, 77, 81, 88, 73, 79,
-  89, 71, 87, 88, 81, 80, 84, 82, 80, 78,
-  116, 79, 90, 77, 88, 80, 91, 90, 80, 91,
-  77, 83, 79, 91, 81, 81, 82, 81, 87, 83,
-  70, 85, 78, 86, 74, 91, 99, 74, 83, 81,
-  88, 78, 95, 88, 73, 91, 72, 75, 87, 114,
-  91, 83, 82, 86, 91, 96, 77, 85, 82, 79,
-  76, 74, 86, 87, 65, 80, 79, 90, 73, 69,
-  92, 93, 95, 91, 75, 75, 85, 90, 87, 94,
-  99, 82, 79, 91, 80, 81, 80, 52, 83, 74,
-  82, 73, 93, 72, 85, 82, 71, 88, 90, 95,
-  75, 78, 80, 82, 81, 80, 88, 83, 79, 86,
-  95, 78, 83, 87, 70, 73, 92, 76, 78, 81,
-  79, 76, 92, 81, 91, 80, 87, 76, 83, 108,
-  74, 92, 84, 77, 84, 74, 84, 73, 79, 91,
-  88, 78, 91, 79, 101, 90, 80, 84, 80, 83,
-  89, 91, 77, 76, 80, 79, 88, 84, 78, 84,
-  87, 86, 81, 92, 87, 126, 85, 89, 78, 80,
-  96, 77, 81, 84, 80, 91, 85, 112, 89, 84,
-  89, 88, 92, 115, 75, 81, 85, 77, 80, 76,
-  96, 97, 79, 84, 78, 94, 74, 70, 118, 88,
-  88, 100, 77, 69, 83, 90, 90, 118, 111, 87,
-  78, 60, 79, 84, 87, 76, 77, 66, 80, 73,
-  100, 70, 93, 89, 71, 78, 95, 87, 55, 85,
-  83, 81, 78, 71, 87, 93, 75, 83, 98, 85,
-  86, 71, 65, 75, 73, 76, 80, 83, 74, 62,
-  85, 84, 78, 79, 82, 77, 86, 85, 81, 90,
-  85, 78, 91, 71, 92, 64, 89, 97, 94, 76,
-  80, 82, 91, 92, 64, 89, 74, 90, 94, 82,
-  77, 72, 114, 80, 70, 79, 82, 92, 83, 82,
-  79, 90, 81, 84, 89, 93, 80, 69, 100, 72,
-  81, 75, 72, 99, 86, 96, 99, 89, 82, 81,
-  83, 104, 81, 90, 83, 81, 77, 86, 92, 89,
-  79, 90, 81, 94, 76, 75, 94, 81, 81, 85,
-  98, 82, 88, 92, 83, 95, 89, 92, 81, 68,
-  84, 88, 86, 131, 85, 70, 81, 73, 85, 71,
-  87, 86, 77, 86, 89, 79, 77, 84, 78, 84,
-  85, 76, 84, 86, 79, 81, 98, 83, 86, 67,
-  69, 72, 69, 75, 89, 83, 83, 82, 79, 72,
-  80, 80, 74, 81, 88, 70, 78, 87, 81, 79,
-  84, 86, 80, 66, 118, 79, 85, 78, 89, 75,
-  100, 94, 76, 83, 83, 82, 79, 83, 77, 79,
-  92, 78, 90, 82, 76, 92, 84, 84, 76, 90,
-  82, 73, 88, 89, 94, 76, 96, 81, 74, 83,
-  84, 88, 81, 118, 86, 85, 88, 91, 91, 90,
-  80, 80, 74, 77, 87, 80, 74, 91, 74, 90,
-  74, 80, 79, 68, 88, 87, 90, 85, 83, 78,
-  91, 91, 86, 67, 67, 79, 76, 103, 86, 95,
-  62, 59, 98, 65, 81, 77, 83, 60, 97, 77,
-  81, 82, 90, 102, 85, 80, 82, 84, 88, 74,
-  83, 79, 83, 81, 90, 81, 78, 86, 78, 80,
-  79, 79, 83, 80, 76, 80, 80, 76, 96, 85,
-  82, 72, 86, 97, 71, 84, 75, 85, 97, 82,
-  90, 59, 67, 80, 82, 79, 92, 79, 106, 93,
-  91, 85, 90, 80, 88, 86, 72, 79, 77, 71,
-  105, 87, 77, 76, 101, 79, 82, 82, 71, 121,
-  89, 95, 75, 91, 87, 77, 85, 82, 90, 95,
-  73, 173, 79, 74, 90, 87, 87, 98, 77, 84,
-  80, 71, 86, 89, 79, 99, 81, 89, 75, 81,
-  73, 73, 97, 80, 90, 92, 82, 76, 88, 94,
-  85, 79, 74, 77, 79, 87, 86, 93, 67, 83,
-  88, 61, 81, 75, 87, 51, 94, 85, 81, 82,
-  88, 93, 74, 82, 83, 87, 88, 68, 85, 87,
-  81, 79, 99, 88, 81, 81, 68, 84, 75, 78,
-  81, 91, 77, 81, 84, 73, 96, 83, 78, 78,
-  82, 84, 78, 79, 74, 90, 96, 77, 95, 54,
-  82, 87, 79, 79, 85, 85, 113, 99, 91, 91,
-  87, 82, 96, 84, 75, 76, 78, 72, 104, 92,
-  76, 80, 103, 77, 82, 84, 64, 86, 92, 100,
-  77, 92, 91, 76, 82, 86, 85, 92, 76, 194,
-  85, 77, 92, 82, 76, 92, 78, 90, 74, 80,
-  86, 89, 76, 92, 81, 88, 76, 82, 82, 71,
-  85, 74, 86, 88, 89, 83, 90, 91, 78, 65,
-  57, 83, 82, 84, 89, 91, 80, 121, 91, 67,
-  87, 72, 81, 60, 89, 78, 86, 85, 91, 84,
-  88, 87, 84, 86, 92, 75, 76, 85, 82, 80,
-  97, 84, 81, 75, 78, 80, 68, 78, 87, 84,
-  80, 83, 76, 73, 87, 82, 72, 75, 91, 80,
-  74, 80, 74, 82, 93, 74, 89, 52, 106, 73,
-  76, 83, 89, 81, 103, 96, 91, 81, 90, 79,
-  90, 83, 70, 74, 85, 69, 106, 90, 74, 79,
-  94, 81, 78, 80, 72, 71, 91, 107, 81, 92,
-  87, 81, 80, 84, 95, 93, 70, 184, 79, 81,
-  87, 73, 92, 82, 91, 104, 75, 78, 81, 81,
-  80, 94, 77, 103, 80, 81, 77, 88, 77, 86,
-  106, 77, 60, 87, 79, 103, 87, 93, 87, 103,
-  83, 69, 78, 84, 89, 74, 86, 88, 76, 72,
-  88, 73, 71, 80, 82, 80, 71, 87, 80, 102,
-  67, 95, 81, 86, 83, 84, 74, 70, 83, 92,
-  94, 83, 79, 78, 86, 90, 87, 94, 82, 90,
-  75, 86, 93, 87, 77, 80, 84, 86, 75, 84,
-  91, 82, 87, 94, 96, 87, 90, 88, 92, 91,
-  76, 79, 77, 91, 65, 77, 81, 87, 114, 87,
-  80, 85, 96, 82, 86, 78, 77, 86, 89, 77,
-  78, 81, 90, 84, 93, 88, 80, 77, 80, 95,
-  80, 95, 79, 84, 92, 85, 88, 94, 105, 74,
-  72, 75, 82, 76, 85, 86, 73, 69, 86, 128,
-  90, 87, 76, 83, 81, 112, 92, 86, 99, 78,
-  68, 73, 90, 108, 87, 91, 89, 93, 99, 63,
-  76, 72, 89, 64, 86, 75, 81, 82, 75, 84,
-  92, 94, 92, 81, 76, 81, 59, 81, 75, 89,
-  90, 82, 91, 86, 82, 59, 87, 97, 101, 63,
-  86, 93, 69, 89, 85, 89, 66, 86, 63, 68,
-  75, 86, 74, 75, 83, 74, 79, 82, 83, 83,
-  94, 80, 114, 75, 86, 89, 92, 104, 85, 82,
-  66, 91, 66, 82, 73, 95, 86, 75, 77, 84,
-  96, 87, 61, 76, 84, 93, 79, 85, 76, 89,
-  93, 79, 90, 84, 72, 81, 86, 79, 88, 100,
-  74, 88, 70, 83, 108, 85, 100, 76, 78, 81,
-  87, 52, 74, 88, 76, 77, 88, 120, 84, 65,
-  76, 86, 73, 105, 84, 85, 69, 76, 87, 82,
-  101, 113, 90, 93, 87, 78, 93, 72, 76, 69,
-  106, 85, 86, 83, 87, 79, 76, 83, 107, 83,
-  88, 83, 87, 81, 65, 93, 71, 90, 82, 90,
-  84, 86, 77, 64, 98, 90, 96, 68, 83, 87,
-  82, 83, 88, 92, 71, 82, 87, 77, 90, 88,
-  81, 81, 87, 83, 94, 83, 92, 78, 94, 81,
-  100, 71, 86, 90, 89, 100, 79, 85, 70, 97,
-  70, 81, 79, 92, 62, 74, 78, 81, 98, 80,
-  73, 78, 76, 89, 84, 82, 74, 86, 90, 92,
-  95, 88, 71, 73, 78, 93, 76, 98, 84, 83,
-  79, 82, 99, 92, 90, 75, 89, 80, 95, 99,
-  82, 75, 85, 77, 87, 86, 78, 92, 83, 79,
-  82, 98, 75, 84, 108, 82, 57, 87, 75, 95,
-  75, 88, 93, 91, 87, 73, 86, 89, 82, 77,
-  80, 91, 88, 79, 92, 75, 62, 84, 80, 86,
-  79, 87, 84, 100, 66, 93, 79, 87, 80, 82,
-  80, 68, 89, 87, 86, 83, 80, 67, 84, 85,
-  79, 90, 77, 75, 82, 91, 84, 87, 82, 78,
-  73, 85, 77, 85, 90, 67, 87, 85, 97, 83,
-  89, 87, 91, 87, 78, 82, 87, 93, 66, 82,
-  76, 89, 122, 83, 77, 90, 86, 83, 87, 84,
-  75, 89, 89, 84, 77, 91, 88, 82, 85, 81,
-  76, 85, 80, 87, 81, 89, 74, 87, 89, 83,
-  80, 88, 104, 76, 74, 61, 73, 74, 90, 91,
-  80, 61, 98, 129, 102, 81, 70, 74, 107, 124,
-  107, 86, 94, 77, 69, 69, 85, 101, 81, 80,
-  86, 80, 111, 66, 79, 73, 77, 60, 80, 68,
-  85, 84, 77, 108, 85, 101, 92, 88, 76, 75,
-  56, 78, 64, 79, 88, 83, 99, 82, 96, 53,
-  92, 102, 96, 64, 79, 102, 72, 86, 74, 93,
-  57, 69, 60, 74, 66, 79, 77, 75, 76, 71,
-  77, 88, 70, 70, 104, 74, 119, 77, 86, 90,
-  80, 90, 83, 74, 73, 95, 61, 84, 74, 100,
-  93, 71, 71, 78, 83, 92, 63, 81, 78, 97,
-  77, 86, 79, 101, 91, 81, 82, 76, 67, 91,
-  93, 76, 81, 102, 66, 92, 61, 76, 118, 81,
-  94, 75, 90, 71, 87, 58, 78, 85, 81, 70,
-  97, 111, 92, 77, 71, 84, 92, 115, 91, 87,
-  63, 73, 89, 79, 98, 102, 82, 87, 91, 77,
-  97, 78, 77, 68, 88, 78, 77, 82, 86, 84,
-  82, 94, 115, 95, 87, 89, 89, 76, 65, 90,
-  64, 84, 83, 91, 88, 83, 88, 63, 101, 90,
-  92, 69, 80, 86, 78, 79, 85, 99, 62, 68,
-  79, 80, 75, 80, 86, 80, 81, 80, 84, 83,
-  86, 64, 97, 87, 102, 76, 83, 91, 82, 91,
-  81, 74, 76, 96, 66, 84, 77, 95, 72, 72,
-  70, 72, 87, 85, 73, 82, 69, 92, 78, 84,
-  69, 98, 89, 94, 85, 81, 68, 85, 85, 85,
-  68, 98, 72, 87, 73, 74, 102, 85, 88, 76,
-  75, 86, 88, 99, 81, 71, 72, 86, 91, 82,
-  78, 89, 79, 90, 96, 98, 94, 79, 95, 84,
-  64, 88, 78, 86, 77, 89, 86, 77, 94, 79,
-  83, 98, 76, 82, 78, 93, 96, 77, 83, 75,
-  63, 79, 75, 74, 89, 93, 89, 97, 76, 85,
-  77, 84, 79, 71, 79, 81, 87, 85, 86, 81,
-  88, 71, 89, 81, 80, 85, 82, 82, 85, 87,
-  91, 82, 77, 86, 76, 84, 86, 92, 78, 88,
-  88, 79, 90, 82, 80, 86, 92, 85, 81, 87,
-  85, 98, 78, 78, 89, 85, 99, 88, 78, 95,
-  86, 84, 93, 84, 74, 81, 83, 81, 80, 94,
-  80, 88, 86, 88, 77, 84, 84, 92, 89, 87,
-  81, 87, 92, 84, 83, 78, 95, 79, 79, 77,
-  63, 74, 87, 83, 68, 74, 96, 115, 91, 86,
-  70, 87, 118, 120, 107, 82, 87, 73, 73, 74,
-  83, 91, 80, 89, 84, 72, 98, 77, 86, 81,
-  66, 68, 84, 68, 88, 78, 80, 87, 77, 96,
-  84, 76, 84, 74, 59, 79, 78, 83, 78, 79,
-  92, 83, 80, 69, 91, 92, 92, 64, 86, 94,
-  84, 84, 82, 88, 70, 87, 72, 73, 77, 75,
-  80, 79, 78, 77, 95, 86, 61, 96, 92, 78,
-  98, 78, 82, 91, 91, 84, 83, 91, 75, 99,
-  82, 83, 92, 92, 88, 83, 78, 87, 85, 93,
-  94, 84, 80, 90, 73, 87, 76, 101, 85, 84,
-  82, 83, 66, 90, 94, 82, 85, 91, 67, 94,
-  71, 79, 110, 77, 85, 77, 87, 81, 77, 62,
-  80, 76, 65, 79, 94, 100, 84, 97, 72, 95,
-  106, 108, 98, 80, 63, 73, 92, 82, 90, 92,
-  81, 92, 82, 77, 97, 81, 82, 78, 75, 81,
-  80, 82, 83, 77, 88, 81, 106, 88, 81, 74,
-  91, 74, 73, 86, 77, 89, 76, 86, 86, 83,
-  80, 80, 97, 86, 94, 76, 86, 88, 89, 83,
-  91, 93, 68, 82, 72, 78, 80, 78, 85, 82,
-  81, 82, 94, 86, 73, 85, 86, 82, 91, 82,
-  84, 86, 91, 89, 82, 84, 83, 98, 80, 87,
-  92, 92, 82, 83, 76, 85, 85, 86, 94, 88,
-  72, 87, 74, 83, 70, 99, 86, 84, 84, 87,
-  70, 86, 92, 88, 79, 91, 74, 90, 77, 81,
-  97, 79, 71, 78, 90, 82, 76, 72, 76, 91,
-  77, 84, 65, 135, 75, 119, 72, 90, 85, 93,
-  82, 120, 91, 70, 103, 85, 70, 73, 89, 89,
-  94, 73, 69, 85, 90, 94, 91, 78, 95, 74,
-  101, 75, 82, 82, 76, 103, 94, 84, 84, 91,
-  82, 74, 93, 72, 80, 80, 84, 92, 87, 87,
-  85, 101, 83, 90, 101, 72, 74, 74, 75, 99,
-  84, 85, 85, 77, 78, 76, 80, 75, 74, 92,
-  80, 82, 84, 95, 86, 105, 75, 75, 89, 82,
-  81, 76, 93, 84, 85, 83, 82, 81, 65, 82,
-  76, 84, 99, 79, 79, 79, 92, 85, 88, 90,
-  72, 83, 89, 92, 81, 96, 72, 82, 77, 82,
-  75, 80, 95, 76, 81, 86, 61, 90, 82, 94,
-  81, 97, 83, 96, 67, 90, 81, 78, 84, 82,
-  72, 99, 102, 99, 90, 91, 75, 87, 88, 95,
-  85, 75, 86, 90, 81, 67, 82, 90, 85, 80,
-  68, 81, 79, 84, 85, 67, 97, 73, 95, 91,
-  82, 88, 80, 88, 85, 87, 78, 100, 75, 84,
-  92, 100, 87, 89, 93, 91, 66, 90, 81, 90,
-  84, 70, 86, 79, 84, 80, 70, 79, 78, 93,
-  85, 91, 74, 76, 77, 83, 78, 73, 80, 100,
-  94, 91, 89, 80, 78, 73, 98, 76, 87, 76,
-  73, 83, 80, 92, 70, 69, 79, 82, 79, 81,
-  84, 74, 84, 76, 83, 79, 88, 83, 88, 87,
-  80, 80, 86, 94, 78, 85, 84, 87, 87, 77,
-  91, 75, 98, 81, 80, 80, 81, 89, 80, 89,
-  75, 88, 63, 74, 80, 78, 88, 74, 70, 71,
-  90, 69, 97, 81, 81, 81, 90, 73, 87, 84,
-  92, 87, 83, 77, 80, 81, 83, 92, 91, 80,
-  70, 83, 93, 73, 103, 75, 92, 92, 85, 87,
-  73, 69, 70, 81, 84, 90, 77, 77, 78, 100,
-  83, 98, 94, 90, 68, 100, 75, 84, 86, 79,
-  74, 76, 92, 96, 93, 87, 89, 85, 83, 106,
-  81, 81, 79, 78, 80, 75, 88, 110, 92, 73,
-  78, 73, 84, 84, 88, 78, 98, 82, 58, 81,
-  78, 101, 73, 72, 77, 77, 84, 89, 79, 82,
-  92, 77, 81, 83, 80, 92, 80, 88, 90, 81,
-  87, 86, 82, 83, 88, 88, 89, 99, 92, 96,
-  82, 89, 89, 80, 92, 87, 61, 69, 75, 76,
-  81, 69, 78, 91, 60, 92, 68, 128, 67, 161,
-  68, 79, 97, 100, 77, 123, 88, 61, 94, 79,
-  74, 77, 90, 95, 99, 59, 68, 87, 91, 86,
-  104, 79, 103, 66, 82, 76, 70, 82, 102, 118,
-  78, 78, 76, 94, 76, 71, 109, 66, 72, 79,
-  86, 83, 107, 67, 91, 95, 74, 85, 98, 56,
-  74, 73, 63, 105, 93, 79, 79, 72, 78, 71,
-  94, 74, 74, 95, 78, 89, 72, 87, 84, 105,
-  76, 66, 87, 77, 68, 80, 87, 86, 83, 78,
-  76, 93, 75, 77, 81, 83, 87, 100, 86, 83,
-  85, 86, 90, 88, 62, 80, 83, 108, 87, 107,
-  66, 77, 66, 81, 73, 85, 84, 72, 64, 87,
-  60, 79, 81, 84, 90, 87, 76, 104, 99, 88,
-  77, 75, 72, 88, 72, 88, 99, 160, 86, 81,
-  91, 84, 89, 93, 83, 77, 70, 89, 91, 79,
-  84, 96, 92, 75, 74, 83, 90, 92, 82, 59,
-  98, 79, 65, 83, 83, 95, 100, 106, 76, 87,
-  83, 113, 83, 73, 93, 84, 88, 87, 90, 79,
-  75, 84, 75, 83, 88, 82, 78, 71, 65, 71,
-  75, 77, 98, 76, 78, 86, 68, 78, 87, 80,
-  76, 68, 76, 100, 89, 74, 103, 67, 93, 76,
-  94, 72, 75, 69, 69, 92, 85, 106, 80, 89,
-  82, 84, 77, 78, 74, 89, 85, 78, 81, 89,
-  89, 79, 84, 80, 80, 112, 84, 87, 81, 78,
-  70, 92, 80, 79, 83, 66, 103, 78, 76, 75,
-  75, 80, 83, 91, 77, 95, 90, 62, 78, 84,
-  87, 74, 76, 73, 82, 80, 94, 93, 83, 76,
-  87, 79, 80, 87, 88, 88, 94, 83, 83, 86,
-  89, 81, 88, 84, 79, 89, 94, 75, 86, 83,
-  87, 81, 87, 75, 85, 76, 72, 79, 78, 84,
-  84, 79, 77, 90, 91, 89, 95, 89, 73, 104,
-  71, 76, 96, 88, 70, 80, 82, 81, 97, 85,
-  97, 83, 80, 89, 81, 85, 79, 83, 82, 77,
-  88, 94, 95, 58, 87, 72, 91, 89, 83, 81,
-  85, 89, 69, 90, 85, 104, 76, 77, 79, 77,
-  80, 87, 78, 81, 87, 76, 81, 93, 75, 84,
-  76, 82, 89, 98, 86, 79, 86, 82, 78, 92,
-  76, 94, 73, 87, 99, 87, 88, 87, 85, 80,
-  71, 75, 71, 70, 61, 70, 86, 110, 74, 87,
-  74, 116, 70, 124, 64, 89, 91, 94, 78, 102,
-  78, 78, 87, 90, 69, 74, 88, 91, 92, 61,
-  76, 87, 88, 85, 106, 92, 108, 82, 87, 87,
-  83, 82, 100, 89, 55, 74, 80, 90, 77, 88,
-  97, 79, 82, 76, 83, 82, 101, 73, 95, 95,
-  69, 76, 93, 65, 65, 83, 62, 86, 78, 72,
-  69, 75, 97, 72, 95, 89, 75, 102, 105, 76,
-  81, 84, 83, 102, 85, 69, 82, 88, 86, 83,
-  112, 77, 87, 71, 75, 84, 74, 65, 79, 84,
-  86, 83, 88, 83, 84, 71, 90, 99, 76, 98,
-  91, 78, 83, 107, 76, 88, 82, 86, 85, 81,
-  69, 79, 76, 93, 73, 81, 82, 94, 81, 75,
-  70, 89, 94, 87, 84, 92, 64, 90, 75, 90,
-  85, 146, 70, 74, 95, 90, 83, 101, 77, 84,
-  75, 85, 79, 69, 79, 92, 89, 73, 83, 82,
-  81, 98, 94, 76, 102, 84, 64, 82, 94, 80,
-  93, 99, 64, 90, 75, 109, 81, 77, 78, 81,
-  86, 82, 82, 66, 103, 83, 80, 83, 85, 99,
-  86, 89, 78, 71, 75, 90, 80, 71, 77, 67,
-  93, 81, 88, 82, 80, 72, 104, 79, 83, 68,
-  92, 80, 88, 84, 85, 74, 68, 72, 79, 76,
-  80, 96, 87, 84, 81, 77, 68, 79, 68, 91,
-  78, 78, 73, 88, 93, 95, 72, 87, 80, 123,
-  79, 87, 96, 74, 77, 92, 78, 84, 74, 71,
-  88, 84, 79, 85, 79, 81, 84, 84, 83, 90,
-  86, 77, 79, 89, 76, 78, 80, 77, 97, 98,
-  79, 79, 84, 82, 86, 90, 78, 94, 96, 85,
-  89, 75, 79, 82, 78, 82, 85, 88, 78, 87,
-  88, 84, 95, 80, 90, 90, 93, 79, 85, 80,
-  67, 90, 74, 98, 80, 81, 75, 97, 88, 84,
-  88, 74, 94, 85, 78, 78, 88, 92, 84, 83,
-  86, 83, 86, 86, 83, 84, 82, 81, 97, 85,
-  80, 87, 84, 76, 89, 84, 82, 62, 90, 82,
-  83, 84, 83, 87, 75, 91, 75, 87, 79, 102,
-  80, 74, 83, 79, 71, 85, 73, 86, 81, 76,
-  78, 90, 80, 93, 72, 80, 90, 102, 77, 83,
-  99, 82, 89, 92, 73, 92, 78, 80, 91, 82,
-  87, 95, 79, 85, 83, 73, 89, 107, 80, 78,
-  98, 55, 65, 69, 79, 89, 83, 81, 101, 84,
-  98, 94, 88, 79, 83, 85, 81, 83, 93, 89,
-  81, 72, 97, 92, 87, 91, 76, 90, 85, 76,
-  84, 89, 89, 87, 76, 76, 92, 72, 70, 67,
-  102, 86, 105, 77, 92, 82, 82, 75, 85, 90,
-  82, 81, 79, 78, 87, 91, 77, 78, 80, 71,
-  83, 79, 88, 86, 79, 83, 84, 73, 85, 84,
-  76, 79, 85, 86, 75, 83, 67, 89, 83, 81,
-  85, 93, 84, 95, 71, 77, 89, 104, 70, 109,
-  99, 69, 87, 85, 77, 83, 78, 107, 94, 79,
-  88, 92, 89, 64, 84, 69, 70, 101, 97, 79,
-  103, 95, 81, 81, 91, 79, 78, 100, 79, 84,
-  77, 79, 76, 95, 83, 117, 76, 67, 110, 57,
-  69, 63, 75, 84, 81, 80, 113, 87, 100, 94,
-  86, 83, 93, 79, 73, 89, 90, 93, 80, 69,
-  102, 89, 87, 86, 77, 78, 87, 80, 86, 88,
-  84, 83, 76, 75, 95, 75, 73, 70, 104, 81,
-  116, 73, 97, 70, 93, 77, 81, 89, 72, 81,
-  72, 77, 91, 90, 75, 78, 70, 75, 91, 78,
-  89, 78, 81, 74, 81, 73, 94, 69, 72, 82,
-  88, 83, 80, 90, 68, 75, 78, 81, 90, 95,
-  85, 102, 70, 74, 71, 100, 69, 109, 89, 75,
-  99, 85, 78, 86, 74, 109, 90, 73, 90, 95,
-  92, 62, 88, 67, 76, 85, 83, 81, 83, 86,
-  77, 82, 89, 79, 73, 111, 71, 84, 78, 75,
-  82, 97, 86, 99, 82, 77, 93, 62, 65, 73,
-  81, 94, 82, 90, 100, 88, 98, 90, 93, 91,
-  81, 84, 80, 78, 84, 88, 85, 72, 90, 84,
-  80, 86, 78, 73, 87, 93, 89, 86, 84, 85,
-  77, 73, 80, 77, 76, 69, 97, 75, 97, 81,
-  88, 83, 78, 81, 86, 91, 85, 83, 76, 75,
-  92, 91, 78, 74, 76, 72, 81, 76, 89, 81,
-  102, 84, 87, 74, 88, 88, 78, 88, 88, 87,
-  75, 82, 70, 78, 84, 82, 97, 93, 85, 97,
-  71, 81, 93, 99, 73, 101, 103, 78, 93, 89,
-  77, 84, 72, 106, 89, 84, 83, 88, 86, 67,
-  86, 71, 72, 83, 84, 78, 79, 89, 87, 85,
-  86, 80, 74, 93, 81, 84, 82, 79, 74, 72,
-  79, 106, 83, 83, 98, 65, 69, 69, 79, 84,
-  84, 81, 102, 94, 104, 91, 90, 77, 93, 78,
-  78, 78, 92, 90, 74, 70, 104, 88, 84, 94,
-  76, 94, 73, 83, 88, 89, 93, 86, 81, 76,
-  91, 74, 77, 73, 91, 89, 99, 80, 84, 74,
-  87, 80, 80, 88, 79, 77, 80, 81, 82, 98,
-  78, 79, 70, 72, 90, 79, 88, 71, 85, 76,
-  84, 74, 68, 82, 77, 79, 82, 90, 76, 75,
-  73, 80, 87, 83, 87, 103, 76, 102, 77, 91,
-  93, 102, 69, 109, 98, 68, 76, 87, 71, 82,
-  73, 101, 82, 69, 89, 88, 82, 66, 92, 77,
-  64, 98, 84, 80, 88, 92, 79, 72, 87, 81,
-  73, 102, 79, 88, 80, 79, 71, 82, 77, 115,
-  79, 71, 104, 66, 73, 62, 73, 79, 80, 86,
-  111, 96, 103, 90, 88, 80, 97, 77, 74, 82,
-  82, 92, 71, 66, 106, 82, 80, 81, 78, 81,
-  77, 83, 87, 85, 85, 81, 80, 75, 101, 73,
-  79, 74, 90, 82, 108, 75, 88, 68, 92, 82,
-  76, 83, 74, 76, 75, 79, 89, 102, 78, 80,
-  69, 78, 94, 79, 96, 69, 78, 65, 81, 68,
-  69, 62, 74, 84, 87, 85, 77, 81, 75, 75,
-  79, 82, 86, 108, 77, 107, 74, 83, 78, 95,
-  68, 108, 88, 75, 89, 89, 73, 78, 68, 102,
-  78, 64, 91, 86, 79, 63, 97, 74, 63, 86,
-  77, 81, 78, 83, 71, 76, 88, 80, 60, 111,
-  68, 85, 77, 77, 79, 90, 84, 97, 88, 79,
-  97, 71, 67, 75, 81, 92, 81, 93, 94, 93,
-  100, 91, 93, 90, 85, 83, 87, 74, 76, 86,
-  78, 70, 95, 76, 82, 85, 80, 74, 80, 93,
-  86, 90, 82, 81, 81, 75, 89, 82, 81, 77,
-  82, 75, 95, 82, 81, 80, 77, 82, 83, 84,
-  84, 79, 82, 78, 83, 97, 84, 75, 65, 72,
-  83, 80, 97, 74, 86, 77, 81, 76, 78, 85,
-  82, 91, 85, 83, 73, 75, 78, 80, 86, 82,
-  91, 100, 77, 96, 76, 82, 94, 96, 73, 98,
-  99, 77, 92, 90, 73, 79, 71, 100, 80, 76,
-  87, 85, 85, 68, 93, 80, 71, 85, 86, 81,
-  81, 91, 84, 75, 87, 82, 71, 97, 81, 86,
-  81, 78, 81, 77, 80, 98, 85, 87, 81, 72,
-  68, 79, 80, 90, 82, 84, 96, 94, 98, 78,
-  90, 77, 97, 89, 76, 70, 87, 82, 86, 73,
-  86, 79, 85, 102, 83, 98, 63, 91, 89, 95,
-  93, 85, 87, 80, 94, 80, 88, 78, 83, 86,
-  83, 89, 82, 83, 77, 81, 87, 89, 90, 82,
-  92, 80, 80, 90, 86, 75, 75, 74, 90, 79,
-  84, 77, 91, 82, 85, 86, 64, 85, 90, 82,
-  79, 86, 79, 77, 77, 84, 83, 84, 88, 92,
-  85, 103, 78, 101, 102, 88, 75, 105, 107, 73,
-  75, 90, 73, 84, 76, 99, 88, 80, 90, 84,
-  83, 77, 86, 77, 72, 91, 86, 79, 81, 96,
-  89, 70, 85, 79, 71, 97, 89, 95, 83, 85,
-  79, 76, 80, 99, 82, 71, 81, 71, 71, 77,
-  81, 88, 80, 85, 90, 95, 98, 75, 92, 75,
-  96, 87, 80, 71, 76, 75, 84, 70, 86, 78,
-  88, 93, 85, 86, 66, 85, 93, 91, 88, 80,
-  88, 81, 94, 78, 85, 77, 75, 81, 90, 87,
-  84, 80, 79, 81, 81, 86, 93, 81, 90, 82,
-  79, 100, 90, 82, 68, 77, 86, 80, 86, 76,
-  81, 75, 83, 81, 57, 75, 91, 82, 85, 84,
-  79, 80, 77, 81, 83, 81, 82, 95, 84, 100,
-  75, 95, 101, 80, 71, 102, 104, 76, 84, 90,
-  73, 83, 71, 98, 83, 78, 90, 81, 78, 74,
-  85, 76, 70, 86, 88, 83, 78, 90, 85, 72,
-  85, 82, 64, 100, 88, 90, 78, 86, 88, 83,
-  87, 92, 89, 78, 81, 76, 66, 83, 81, 96,
-  78, 88, 89, 92, 96, 82, 90, 84, 88, 92,
-  87, 69, 76, 78, 89, 73, 77, 71, 88, 95,
-  88, 84, 75, 90, 86, 96, 88, 80, 84, 76,
-  90, 83, 89, 84, 76, 82, 85, 87, 79, 87,
-  71, 80, 87, 81, 94, 82, 92, 81, 78, 89,
-  91, 72, 76, 73, 84, 78, 87, 82, 82, 83,
-  83, 86, 70, 86, 89, 88, 84, 82, 74, 78,
-  81, 92, 82, 85, 85, 89, 82, 93, 78, 89,
-  102, 89, 76, 92, 105, 78, 89, 85, 78, 83,
-  77, 98, 85, 83, 91, 82, 84, 78, 84, 82,
-  78, 91, 89, 81, 89, 97, 88, 70, 88, 83,
-  72, 97, 88, 93, 85, 87, 64, 84, 89, 68,
-  79, 95, 77, 80, 73, 78, 70, 94, 85, 96,
-  78, 77, 86, 91, 67, 74, 83, 87, 90, 78,
-  91, 93, 65, 83, 103, 88, 93, 71, 70, 74,
-  82, 97, 84, 78, 89, 88, 79, 66, 70, 68,
-  80, 93, 87, 86, 69, 77, 91, 75, 96, 75,
-  70, 89, 78, 80, 77, 101, 82, 75, 88, 80,
-  112, 69, 95, 87, 86, 109, 85, 67, 91, 79,
-  85, 101, 77, 78, 103, 78, 79, 90, 69, 93,
-  70, 73, 108, 100, 81, 137, 82, 80, 71, 80,
-  80, 89, 85, 76, 100, 97, 78, 84, 72, 77,
-  87, 72, 78, 81, 100, 72, 77, 78, 65, 73,
-  88, 81, 97, 82, 83, 87, 127, 80, 107, 88,
-  65, 118, 87, 84, 66, 94, 79, 63, 93, 74,
-  85, 76, 64, 67, 66, 93, 86, 87, 86, 79,
-  99, 87, 60, 74, 78, 70, 76, 89, 97, 93,
-  62, 77, 100, 88, 97, 77, 77, 65, 99, 70,
-  82, 67, 85, 91, 76, 69, 84, 61, 93, 97,
-  86, 81, 77, 67, 88, 67, 91, 72, 66, 79,
-  79, 81, 59, 93, 87, 88, 92, 85, 87, 62,
-  94, 93, 93, 95, 81, 66, 88, 70, 92, 94,
-  80, 76, 106, 89, 75, 92, 83, 88, 75, 76,
-  76, 83, 81, 150, 86, 81, 64, 91, 74, 90,
-  93, 77, 90, 113, 63, 76, 63, 81, 79, 68,
-  72, 74, 107, 61, 89, 83, 69, 86, 82, 73,
-  65, 89, 79, 81, 113, 69, 96, 89, 47, 122,
-  93, 87, 69, 98, 90, 73, 74, 84, 73, 73,
-  79, 79, 68, 95, 73, 80, 82, 84, 87, 87,
-  77, 82, 74, 94, 87, 77, 82, 90, 72, 88,
-  104, 74, 89, 85, 82, 72, 88, 71, 87, 76,
-  78, 87, 77, 67, 87, 76, 76, 90, 94, 81,
-  65, 86, 81, 81, 89, 78, 77, 78, 75, 85,
-  82, 91, 82, 79, 90, 84, 117, 68, 86, 81,
-  87, 102, 101, 67, 84, 78, 88, 95, 74, 88,
-  102, 75, 83, 90, 71, 96, 77, 76, 69, 108,
-  85, 129, 78, 92, 79, 75, 93, 85, 88, 76,
-  83, 93, 88, 89, 79, 80, 83, 76, 95, 81,
-  92, 86, 83, 74, 67, 119, 92, 79, 75, 78,
-  80, 91, 93, 83, 101, 87, 75, 102, 83, 90,
-  77, 72, 82, 77, 86, 96, 88, 94, 67, 74,
-  79, 83, 81, 94, 91, 82, 102, 90, 72, 77,
-  85, 90, 92, 87, 89, 95, 71, 83, 90, 87,
-  99, 77, 74, 82, 83, 101, 77, 77, 87, 87,
-  78, 89, 75, 79, 87, 81, 86, 89, 81, 66,
-  94, 70, 96, 68, 74, 88, 81, 77, 71, 93,
-  85, 77, 76, 92, 98, 74, 96, 77, 94, 76,
-  85, 88, 103, 79, 77, 107, 73, 79, 83, 91,
-  82, 86, 79, 82, 83, 97, 108, 80, 82, 115,
-  85, 87, 79, 78, 77, 90, 85, 79, 95, 95,
-  61, 87, 75, 76, 71, 71, 80, 83, 97, 63,
-  82, 84, 67, 61, 76, 69, 89, 91, 83, 78,
-  112, 69, 99, 88, 58, 92, 85, 78, 85, 78,
-  73, 73, 105, 76, 102, 90, 54, 65, 77, 82,
-  93, 91, 97, 83, 124, 78, 69, 79, 79, 80,
-  76, 102, 100, 94, 69, 78, 87, 85, 105, 91,
-  78, 74, 89, 75, 71, 67, 95, 98, 73, 110,
-  80, 72, 98, 90, 86, 87, 89, 55, 91, 69,
-  90, 63, 67, 76, 82, 83, 59, 79, 91, 84,
-  74, 105, 79, 73, 107, 72, 107, 74, 75, 85,
-  104, 74, 76, 93, 76, 84, 74, 107, 77, 89,
-  99, 79, 93, 111, 71, 64, 83, 106, 80, 77,
-  75, 102, 66, 90, 93, 80, 85, 109, 45, 76,
-  71, 78, 57, 74, 69, 75, 96, 51, 88, 89,
-  75, 71, 76, 67, 67, 104, 82, 76, 90, 63,
-  91, 85, 35, 87, 89, 79, 75, 92, 80, 79,
-  83, 89, 86, 82, 74, 73, 76, 80, 74, 80,
-  88, 88, 99, 89, 80, 88, 81, 91, 89, 82,
-  87, 88, 77, 87, 88, 76, 94, 91, 84, 75,
-  85, 79, 71, 81, 82, 85, 79, 83, 90, 83,
-  87, 88, 94, 84, 80, 71, 88, 78, 85, 70,
-  75, 76, 80, 80, 77, 85, 84, 80, 78, 90,
-  102, 75, 92, 76, 86, 80, 87, 79, 97, 81,
-  85, 96, 69, 98, 77, 85, 81, 86, 79, 97,
-  84, 101, 65, 87, 86, 116, 83, 83, 84, 82,
-  85, 87, 84, 77, 85, 86, 76, 80, 76, 78,
-  66, 72, 92, 79, 93, 72, 82, 79, 71, 112,
-  83, 73, 79, 83, 79, 81, 82, 72, 92, 89,
-  64, 85, 87, 82, 79, 75, 87, 80, 72, 97,
-  86, 87, 79, 86, 77, 90, 88, 89, 94, 86,
-  95, 85, 82, 84, 82, 101, 86, 76, 81, 93,
-  83, 91, 90, 91, 87, 78, 81, 86, 79, 104,
-  76, 80, 80, 86, 78, 91, 86, 83, 77, 65,
-  86, 89, 75, 75, 82, 79, 94, 76, 79, 88,
-  78, 87, 85, 83, 87, 71, 81, 83, 118, 74,
-  88, 73, 86, 87, 84, 88, 95, 79, 80, 91,
-  78, 83, 96, 77, 89, 77, 78, 83, 79, 91,
-  105, 87, 88, 99, 80, 94, 90, 75, 77, 89,
-  79, 72, 93, 74, 85, 85, 86, 80, 82, 75,
-  85, 93, 88, 73, 85, 78, 66, 69, 89, 76,
-  93, 82, 82, 90, 97, 73, 95, 84, 70, 78,
-  84, 82, 78, 74, 82, 80, 81, 79, 93, 82,
-  67, 79, 74, 88, 90, 83, 99, 81, 109, 78,
-  78, 82, 88, 94, 80, 79, 87, 91, 81, 84,
-  86, 94, 81, 91, 85, 77, 83, 81, 71, 79,
-  86, 95, 79, 101, 87, 81, 83, 77, 84, 83,
-  81, 65, 77, 78, 95, 74, 76, 81, 78, 92,
-  80, 69, 90, 81, 85, 83, 109, 70, 90, 70,
-  95, 94, 82, 82, 98, 78, 80, 80, 79, 88,
-  93, 85, 88, 72, 87, 89, 83, 103, 80, 77,
-  83, 94, 74, 93, 87, 82, 69, 91, 84, 73,
-  86, 85, 81, 85, 78, 82, 73, 84, 81, 83,
-  79, 70, 85, 85, 67, 76, 88, 74, 79, 88,
-  83, 86, 80, 69, 79, 81, 56, 75, 85, 77,
-  76, 83, 79, 83, 72, 83, 89, 78, 79, 84,
-  77, 85, 80, 82, 97, 85, 92, 80, 85, 88,
-  89, 102, 88, 73, 79, 89, 86, 92, 88, 84,
-  81, 88, 86, 82, 81, 82, 75, 85, 81, 90,
-  80, 89, 86, 84, 82, 76, 85, 82, 76, 76,
-  82, 84, 88, 79, 77, 79, 76, 91, 88, 82,
-  86, 78, 83, 82, 113, 77, 83, 75, 83, 81,
-  93, 85, 93, 83, 85, 87, 75, 102, 84, 78,
-  90, 80, 79, 100, 79, 94, 76, 88, 88, 98,
-  81, 87, 93, 79, 85, 91, 80, 75, 88, 72,
-  89, 86, 87, 83, 76, 75, 91, 87, 85, 74,
-  85, 72, 71, 103, 90, 78, 82, 76, 78, 90,
-  79, 78, 86, 84, 75, 78, 84, 81, 103, 88,
-  84, 81, 75, 92, 80, 81, 90, 81, 72, 73,
-  76, 71, 72, 84, 70, 92, 82, 103, 80, 92,
-  77, 76, 77, 93, 86, 80, 92, 94, 73, 70,
-  84, 82, 82, 79, 87, 97, 105, 83, 76, 57,
-  86, 75, 93, 91, 96, 63, 99, 78, 89, 71,
-  72, 86, 80, 81, 87, 100, 68, 95, 71, 93,
-  104, 80, 77, 108, 88, 82, 89, 78, 85, 71,
-  107, 68, 80, 94, 81, 68, 95, 83, 80, 88,
-  78, 89, 60, 92, 85, 80, 81, 88, 93, 89,
-  81, 89, 103, 64, 80, 81, 86, 92, 97, 76,
-  79, 83, 85, 103, 88, 86, 74, 76, 62, 87,
-  61, 96, 70, 76, 73, 100, 81, 75, 76, 85,
-  80, 75, 74, 87, 73, 71, 138, 83, 85, 77,
-  84, 68, 71, 88, 82, 83, 84, 79, 124, 88,
-  71, 80, 74, 74, 79, 85, 80, 126, 66, 89,
-  82, 79, 74, 84, 85, 85, 92, 74, 80, 91,
-  77, 94, 75, 71, 98, 105, 75, 61, 89, 77,
-  110, 74, 98, 90, 102, 99, 74, 99, 80, 79,
-  80, 70, 56, 98, 80, 74, 89, 62, 96, 116,
-  68, 111, 85, 63, 77, 71, 86, 87, 72, 80,
-  91, 74, 79, 88, 83, 79, 70, 62, 83, 74,
-  47, 86, 81, 99, 76, 77, 71, 76, 75, 91,
-  71, 56, 95, 78, 83, 84, 90, 82, 106, 83,
-  83, 107, 72, 81, 86, 83, 85, 84, 84, 84,
-  70, 78, 79, 95, 89, 73, 77, 105, 74, 108,
-  71, 83, 77, 91, 81, 79, 91, 83, 78, 75,
-  82, 81, 87, 81, 71, 70, 64, 95, 70, 85,
-  76, 89, 83, 104, 93, 91, 92, 79, 82, 95,
-  83, 80, 87, 93, 81, 81, 75, 81, 85, 86,
-  83, 99, 71, 84, 80, 68, 78, 85, 82, 100,
-  87, 77, 101, 78, 82, 69, 73, 86, 79, 76,
-  93, 93, 78, 96, 76, 94, 88, 80, 85, 99,
-  79, 80, 94, 81, 63, 69, 103, 66, 90, 91,
-  81, 71, 98, 75, 84, 92, 84, 84, 72, 86,
-  96, 79, 78, 86, 96, 89, 87, 84, 99, 62,
-  86, 83, 83, 95, 97, 83, 77, 84, 87, 94,
-  85, 81, 77, 72, 82, 92, 68, 88, 82, 77,
-  89, 93, 83, 76, 73, 84, 87, 77, 76, 92,
-  75, 80, 103, 89, 86, 81, 72, 89, 78, 81,
-  89, 78, 67, 76, 48, 91, 74, 83, 73, 88,
-  75, 101, 86, 81, 79, 76, 76, 92, 72, 73,
-  90, 81, 78, 65, 81, 87, 74, 76, 71, 85,
-  71, 73, 74, 53, 89, 75, 103, 98, 85, 70,
-  94, 76, 91, 65, 76, 84, 81, 70, 91, 96,
-  67, 100, 70, 88, 110, 64, 84, 90, 93, 89,
-  85, 83, 65, 59, 105, 74, 80, 101, 81, 63,
-  91, 78, 75, 87, 72, 89, 60, 87, 91, 83,
-  72, 88, 89, 98, 80, 82, 102, 62, 80, 93,
-  72, 88, 90, 79, 75, 82, 85, 94, 99, 83,
-  74, 75, 75, 88, 62, 103, 61, 75, 71, 88,
-  71, 76, 83, 81, 78, 80, 64, 92, 68, 65,
-  168, 86, 96, 99, 87, 71, 69, 95, 91, 83,
-  76, 83, 141, 106, 74, 86, 78, 57, 73, 81,
-  79, 141, 64, 96, 80, 74, 64, 81, 90, 88,
-  99, 86, 93, 96, 80, 93, 73, 93, 130, 100,
-  64, 59, 89, 82, 106, 68, 92, 90, 105, 91,
-  74, 133, 84, 84, 88, 92, 57, 112, 78, 70,
-  65, 61, 93, 124, 66, 132, 73, 57, 84, 50,
-  99, 78, 53, 83, 84, 71, 80, 88, 77, 88,
-  68, 67, 98, 68, 47, 88, 76, 117, 86, 69,
-  69, 65, 75, 86, 68, 55, 108, 86, 92, 87,
-  74, 57, 114, 83, 72, 117, 87, 83, 89, 80,
-  99, 79, 90, 79, 64, 73, 88, 89, 82, 64,
-  73, 93, 74, 123, 65, 72, 66, 94, 80, 71,
-  79, 84, 79, 81, 82, 81, 92, 77, 66, 74,
-  48, 86, 74, 88, 77, 93, 80, 101, 96, 70,
-  92, 79, 79, 98, 78, 72, 85, 83, 72, 83,
-  76, 86, 72, 84, 75, 90, 85, 75, 82, 61,
-  84, 79, 95, 108, 75, 66, 93, 78, 88, 59,
-  75, 84, 82, 73, 95, 90, 78, 103, 80, 95,
-  98, 64, 83, 86, 86, 94, 87, 86, 64, 62,
-  101, 77, 84, 98, 78, 77, 90, 69, 79, 89,
-  79, 89, 69, 88, 98, 77, 66, 92, 85, 104,
-  81, 80, 98, 62, 83, 90, 79, 87, 92, 86,
-  70, 84, 86, 92, 90, 77, 74, 75, 75, 95,
-  64, 95, 62, 78, 94, 85, 78, 80, 68, 81,
-  83, 76, 66, 94, 72, 71, 103, 77, 88, 91,
-  87, 89, 83, 77, 82, 79, 73, 78, 86, 98,
-  71, 76, 74, 95, 90, 90, 94, 108, 78, 78,
-  85, 88, 84, 80, 85, 82, 95, 78, 82, 89,
-  80, 73, 76, 83, 79, 88, 82, 69, 93, 75,
-  81, 87, 86, 77, 91, 78, 93, 79, 74, 90,
-  83, 86, 78, 93, 67, 100, 86, 86, 97, 87,
-  78, 100, 94, 96, 85, 91, 75, 65, 102, 82,
-  82, 97, 90, 70, 93, 81, 76, 92, 79, 92,
-  69, 78, 86, 90, 78, 87, 85, 88, 81, 81,
-  90, 79, 88, 76, 82, 92, 81, 78, 82, 80,
-  89, 71, 107, 88, 89, 72, 97, 87, 76, 97,
-  74, 85, 69, 85, 94, 90, 86, 93, 79, 87,
-  65, 97, 76, 81, 97, 84, 78, 100, 84, 71,
-  75, 88, 75, 75, 82, 90, 90, 74, 83, 78,
-  79, 72, 84, 87, 85, 105, 73, 82, 79, 81,
-  82, 72, 80, 89, 71, 88, 89, 77, 78, 93,
-  74, 86, 85, 86, 77, 64, 85, 72, 86, 81,
-  77, 82, 90, 87, 88, 79, 80, 84, 84, 67,
-  57, 80, 67, 99, 81, 87, 97, 99, 81, 95,
-  83, 96, 78, 77, 83, 73, 91, 82, 85, 75,
-  89, 84, 92, 79, 72, 84, 73, 79, 53, 86,
-  92, 96, 67, 83, 71, 82, 70, 96, 86, 84,
-  90, 89, 77, 85, 79, 70, 89, 84, 77, 88,
-  92, 77, 80, 75, 92, 82, 74, 92, 70, 72,
-  88, 76, 80, 78, 79, 95, 73, 100, 60, 94,
-  72, 83, 88, 79, 82, 88, 87, 78, 88, 74,
-  89, 78, 72, 80, 82, 91, 73, 83, 79, 100,
-  95, 94, 95, 91, 80, 79, 77, 93, 91, 80,
-  80, 83, 85, 90, 83, 76, 77, 84, 80, 84,
-  104, 94, 83, 72, 98, 80, 80, 94, 74, 82,
-  87, 81, 91, 82, 73, 88, 87, 77, 86, 95,
-  77, 99, 86, 83, 89, 78, 78, 97, 79, 97,
-  83, 86, 88, 66, 95, 83, 85, 96, 86, 78,
-  84, 72, 79, 94, 87, 80, 70, 79, 94, 83,
-  77, 86, 82, 106, 80, 80, 89, 74, 88, 80,
-  93, 92, 79, 94, 81, 81, 89, 75, 100, 83,
-  86, 72, 95, 89, 77, 87, 74, 79, 75, 80,
-  92, 91, 72, 90, 81, 86, 66, 90, 81, 79,
-  83, 80, 103, 69, 73, 87, 86, 73, 72, 87,
-  84, 78, 83, 48, 57, 82, 87, 103, 85, 78,
-  77, 74, 95, 84, 81, 106, 83, 88, 92, 88,
-  96, 87, 74, 88, 87, 79, 86, 80, 82, 78,
-  72, 74, 83, 78, 76, 73, 88, 85, 78, 75,
-  72, 86, 65, 73, 87, 83, 102, 74, 74, 98,
-  76, 79, 94, 70, 96, 69, 76, 102, 72, 118,
-  87, 86, 98, 96, 75, 82, 76, 87, 82, 68,
-  81, 79, 91, 118, 80, 84, 89, 85, 73, 85,
-  85, 87, 84, 86, 82, 82, 77, 56, 100, 83,
-  93, 85, 104, 93, 77, 87, 81, 80, 81, 72,
-  81, 92, 77, 86, 121, 71, 119, 88, 104, 76,
-  65, 72, 96, 85, 82, 80, 89, 69, 69, 84,
-  90, 72, 82, 83, 86, 67, 64, 87, 88, 66,
-  87, 69, 57, 77, 86, 116, 94, 91, 86, 58,
-  85, 85, 95, 122, 84, 98, 94, 95, 100, 79,
-  70, 74, 88, 69, 82, 77, 60, 73, 63, 76,
-  86, 83, 74, 62, 90, 78, 81, 69, 68, 82,
-  65, 80, 83, 91, 90, 68, 79, 104, 72, 78,
-  88, 62, 96, 61, 73, 102, 61, 114, 99, 90,
-  90, 81, 88, 80, 69, 75, 84, 82, 78, 78,
-  80, 85, 96, 76, 76, 79, 71, 100, 85, 89,
-  82, 96, 70, 97, 94, 55, 96, 82, 73, 83,
-  108, 97, 90, 92, 74, 80, 90, 70, 87, 96,
-  80, 73, 109, 60, 84, 89, 104, 83, 70, 72,
-  89, 85, 85, 82, 83, 63, 79, 80, 86, 74,
-  78, 92, 84, 75, 76, 91, 89, 81, 83, 82,
-  55, 86, 90, 100, 91, 91, 89, 76, 79, 86,
-  86, 101, 92, 90, 87, 80, 94, 79, 75, 65,
-  96, 108, 95, 82, 52, 74, 71, 74, 80, 82,
-  79, 72, 91, 84, 79, 77, 76, 81, 70, 75,
-  90, 99, 106, 76, 75, 94, 76, 85, 92, 69,
-  97, 68, 92, 105, 67, 97, 109, 89, 104, 89,
-  90, 86, 79, 86, 84, 70, 85, 83, 85, 79,
-  85, 81, 84, 85, 75, 90, 86, 105, 83, 91,
-  89, 84, 81, 59, 80, 87, 94, 90, 99, 93,
-  81, 99, 81, 84, 80, 76, 84, 93, 77, 87,
-  97, 68, 84, 87, 105, 81, 78, 69, 89, 87,
-  81, 82, 89, 71, 76, 78, 97, 83, 70, 96,
-  96, 73, 68, 76, 83, 73, 79, 73, 81, 89,
-  84, 101, 91, 71, 85, 79, 87, 87, 91, 112,
-  83, 91, 97, 90, 102, 80, 71, 103, 80, 69,
-  79, 80, 67, 87, 79, 71, 78, 75, 81, 62,
-  90, 87, 79, 61, 63, 80, 64, 84, 82, 80,
-  91, 95, 72, 108, 92, 78, 79, 89, 108, 74,
-  87, 92, 86, 90, 97, 77, 80, 84, 75, 80,
-  74, 78, 91, 78, 72, 88, 79, 87, 84, 71,
-  99, 80, 73, 78, 85, 83, 80, 91, 79, 81,
-  87, 69, 99, 93, 73, 90, 102, 93, 95, 82,
-  82, 78, 79, 74, 93, 85, 77, 89, 85, 67,
-  99, 90, 104, 86, 84, 76, 99, 80, 94, 77,
-  88, 56, 70, 100, 82, 92, 87, 71, 93, 71,
-  75, 66, 87, 63, 87, 64, 81, 85, 87, 89,
-  97, 57, 88, 63, 75, 100, 120, 136, 79, 100,
-  98, 90, 121, 84, 73, 87, 80, 59, 78, 94,
-  66, 92, 86, 84, 83, 61, 79, 64, 100, 77,
-  87, 60, 60, 71, 69, 104, 74, 71, 73, 94,
-  82, 92, 104, 78, 75, 90, 73, 67, 105, 88,
-  86, 77, 69, 93, 74, 86, 79, 80, 79, 70,
-  86, 98, 68, 91, 84, 53, 90, 81, 75, 73,
-  75, 90, 78, 76, 86, 100, 68, 99, 102, 78,
-  110, 91, 68, 76, 103, 97, 98, 77, 77, 73,
-  75, 76, 93, 77, 81, 68, 66, 72, 63, 98,
-  101, 92, 86, 82, 101, 83, 95, 75, 79, 58,
-  69, 105, 100, 84, 71, 89, 94, 68, 71, 77,
-  85, 75, 82, 68, 76, 93, 89, 98, 91, 84,
-  85, 82, 88, 87, 100, 107, 84, 91, 89, 75,
-  100, 82, 68, 72, 87, 96, 85, 86, 68, 83,
-  81, 74, 81, 83, 86, 57, 95, 80, 78, 65,
-  71, 76, 65, 88, 81, 85, 91, 92, 78, 97,
-  88, 75, 81, 82, 103, 72, 97, 94, 79, 92,
-  102, 82, 82, 84, 92, 80, 79, 82, 94, 79,
-  73, 88, 81, 72, 86, 83, 85, 83, 72, 86,
-  85, 79, 80, 91, 78, 85, 86, 78, 90, 90,
-  74, 84, 92, 93, 88, 87, 84, 78, 81, 75,
-  95, 79, 74, 88, 78, 68, 90, 89, 101, 90,
-  78, 77, 87, 78, 91, 81, 86, 57, 86, 79,
-  92, 83, 69, 88, 82, 76, 74, 83, 86, 86,
-  79, 88, 80, 87, 79, 86, 91, 84, 91, 91,
-  97, 90, 87, 96, 88, 85, 91, 84, 92, 90,
-  77, 110, 76, 90, 82, 78, 59, 84, 84, 74,
-  84, 67, 73, 59, 90, 80, 77, 76, 69, 76,
-  71, 85, 84, 88, 93, 90, 85, 91, 91, 80,
-  89, 84, 110, 79, 90, 76, 90, 85, 107, 87,
-  78, 81, 72, 78, 83, 87, 92, 81, 66, 72,
-  81, 89, 75, 80, 94, 77, 95, 89, 75, 77,
-  90, 101, 89, 83, 70, 75, 92, 85, 92, 90,
-  89, 86, 88, 70, 88, 78, 76, 84, 84, 79,
-  69, 86, 75, 72, 88, 89, 91, 90, 90, 75,
-  93, 81, 90, 87, 92, 82, 83, 80, 90, 93,
-  84, 78, 77, 75, 76, 83, 84, 77, 78, 72,
-  82, 81, 84, 88, 95, 81, 91, 77, 86, 89,
-  99, 94, 82, 92, 85, 87, 95, 93, 74, 98,
-  75, 78, 79, 84, 64, 81, 93, 71, 88, 60,
-  70, 68, 89, 82, 81, 75, 65, 76, 68, 95,
-  80, 81, 83, 84, 86, 76, 99, 86, 92, 73,
-  91, 69, 89, 77, 89, 103, 86, 91, 75, 87,
-  72, 75, 93, 78, 95, 100, 58, 62, 79, 70,
-  75, 87, 79, 86, 89, 98, 72, 87, 99, 101,
-  85, 91, 76, 84, 95, 82, 92, 89, 87, 87,
-  84, 69, 85, 75, 64, 80, 82, 90, 71, 77,
-  80, 76, 78, 91, 88, 97, 91, 79, 87, 75,
-  88, 95, 89, 76, 90, 97, 91, 89, 69, 100,
-  79, 72, 78, 88, 90, 89, 81, 61, 76, 86,
-  83, 84, 91, 87, 84, 94, 83, 92, 94, 87,
-  85, 87, 81, 80, 89, 95, 72, 92, 80, 100,
-  82, 83, 85, 81, 82, 77, 80, 72, 79, 68,
-  89, 84, 81, 79, 69, 89, 66, 83, 82, 77,
-  93, 87, 89, 88, 93, 80, 91, 79, 100, 74,
-  86, 76, 90, 95, 92, 90, 79, 81, 76, 80,
-  89, 81, 91, 86, 64, 71, 82, 76, 74, 85,
-  82, 89, 94, 91, 76, 79, 92, 98, 88, 76,
-  72, 81, 93, 83, 88, 82, 86, 86, 87, 75,
-  84, 77, 75, 84, 86, 77, 67, 90, 85, 78,
-  100, 86, 89, 96, 94, 78, 85, 78, 84, 96,
-  89, 80, 83, 81, 89, 86, 90, 88, 83, 86,
-  76, 87, 88, 82, 86, 82, 78, 91, 100, 88,
-  75, 77, 89, 81, 92, 83, 85, 83, 79, 81,
-  87, 82, 84, 79, 89, 83, 88, 92, 89, 78,
-  68, 76, 78, 113, 78, 88, 96, 95, 79, 88,
-  86, 75, 87, 80, 88, 83, 68, 83, 84, 77,
-  82, 98, 67, 77, 84, 93, 99, 95, 82, 89,
-  94, 84, 87, 92, 87, 78, 83, 88, 84, 91,
-  80, 91, 89, 87, 75, 81, 77, 89, 93, 75,
-  91, 76, 71, 82, 86, 88, 83, 83, 85, 77,
-  85, 82, 82, 93, 85, 76, 93, 84, 86, 88,
-  83, 89, 78, 78, 87, 79, 93, 92, 80, 81,
-  81, 75, 71, 79, 84, 81, 77, 89, 95, 88,
-  96, 80, 85, 81, 102, 96, 92, 86, 66, 84,
-  94, 74, 93, 85, 82, 87, 99, 85, 86, 76,
-  82, 76, 85, 84, 94, 88, 72, 83, 79, 91,
-  76, 80, 87, 82, 97, 78, 96, 60, 78, 79,
-  84, 108, 87, 80, 114, 96, 74, 96, 92, 73,
-  83, 77, 78, 84, 75, 88, 73, 78, 74, 95,
-  60, 78, 84, 91, 93, 94, 80, 91, 93, 77,
-  87, 106, 87, 81, 82, 88, 71, 91, 84, 115,
-  90, 84, 92, 80, 72, 92, 85, 76, 92, 76,
-  69, 85, 73, 96, 80, 90, 90, 77, 82, 97,
-  80, 77, 79, 75, 90, 82, 87, 77, 89, 83,
-  79, 82, 86, 79, 90, 85, 82, 84, 76, 72,
-  79, 71, 86, 82, 75, 94, 91, 98, 84, 83,
-  79, 82, 81, 94, 85, 89, 77, 85, 88, 84,
-  83, 75, 77, 86, 96, 89, 82, 80, 78, 81,
-  84, 80, 90, 80, 79, 81, 80, 81, 83, 89,
-  88, 87, 83, 82, 87, 76, 80, 79, 72, 109,
-  88, 85, 102, 89, 81, 89, 83, 74, 89, 80,
-  80, 82, 71, 89, 91, 82, 78, 96, 71, 82,
-  84, 94, 96, 95, 81, 91, 90, 83, 85, 93,
-  87, 80, 85, 89, 86, 93, 76, 96, 89, 86,
-  77, 86, 80, 97, 80, 75, 94, 75, 69, 81,
-  77, 90, 85, 84, 86, 80, 86, 81, 82, 81,
-  82, 75, 97, 90, 89, 87, 82, 86, 76, 77,
-  88, 90, 84, 97, 88, 77, 82, 73, 75, 82,
-  82, 85, 79, 87, 100, 86, 80, 76, 77, 80,
-  85, 82, 82, 88, 82, 78, 97, 82, 93, 80,
-  77, 85, 107, 90, 83, 79, 93, 73, 85, 78,
-  83, 86, 82, 77, 87, 72, 85, 77, 88, 90,
-  94, 87, 75, 84, 68, 73, 75, 96, 74, 96,
-  93, 92, 68, 92, 98, 77, 82, 82, 81, 82,
-  79, 90, 83, 75, 89, 102, 76, 75, 72, 92,
-  96, 93, 79, 86, 107, 84, 93, 87, 85, 76,
-  78, 90, 75, 86, 73, 86, 87, 79, 76, 76,
-  82, 102, 94, 74, 82, 75, 87, 79, 84, 94,
-  83, 90, 87, 88, 95, 90, 74, 93, 80, 76,
-  88, 90, 75, 88, 83, 84, 72, 75, 86, 80,
-  75, 93, 78, 98, 90, 71, 69, 81, 88, 84,
-  85, 76, 90, 75, 88, 85, 84, 77, 99, 84,
-  89, 87, 70, 74, 109, 81, 104, 77, 75, 99,
-  116, 83, 102, 79, 82, 67, 78, 83, 98, 100,
-  81, 81, 81, 89, 82, 91, 93, 86, 98, 70,
-  89, 88, 76, 76, 69, 85, 80, 86, 108, 93,
-  55, 86, 102, 75, 81, 74, 84, 86, 82, 76,
-  77, 73, 73, 113, 77, 68, 71, 95, 83, 78,
-  84, 84, 107, 77, 75, 95, 95, 70, 71, 97,
-  61, 78, 65, 110, 88, 85, 97, 78, 72, 118,
-  78, 74, 86, 78, 99, 72, 68, 109, 75, 88,
-  96, 89, 73, 100, 67, 71, 72, 76, 83, 85,
-  72, 79, 89, 79, 80, 80, 89, 70, 74, 79,
-  73, 107, 89, 67, 81, 76, 102, 83, 90, 78,
-  92, 85, 77, 83, 106, 80, 77, 86, 83, 87,
-  81, 74, 93, 78, 84, 75, 78, 82, 98, 91,
-  87, 87, 74, 76, 76, 77, 98, 78, 78, 77,
-  82, 86, 85, 100, 86, 85, 84, 76, 81, 92,
-  88, 72, 70, 91, 86, 91, 93, 88, 74, 88,
-  99, 76, 89, 86, 78, 81, 83, 78, 88, 76,
-  84, 94, 80, 83, 70, 90, 91, 90, 83, 83,
-  97, 89, 78, 89, 90, 77, 77, 90, 77, 87,
-  64, 90, 87, 78, 78, 92, 87, 113, 77, 79,
-  86, 69, 87, 77, 79, 91, 79, 89, 86, 90,
-  77, 88, 75, 74, 75, 75, 79, 99, 74, 88,
-  80, 82, 81, 75, 85, 87, 81, 97, 81, 95,
-  90, 72, 70, 84, 85, 86, 88, 80, 93, 78,
-  71, 73, 68, 80, 80, 77, 85, 80, 97, 88,
-  89, 82, 80, 71, 66, 91, 91, 79, 79, 86,
-  83, 86, 75, 64, 75, 79, 85, 89, 86, 72,
-  84, 82, 88, 83, 96, 91, 91, 81, 72, 64,
-  76, 70, 77, 91, 76, 80, 96, 72, 96, 81,
-  75, 75, 79, 81, 85, 83, 87, 83, 110, 91,
-  76, 81, 86, 84, 89, 86, 66, 87, 104, 81,
-  93, 66, 90, 76, 82, 79, 91, 79, 109, 60,
-  87, 66, 72, 79, 89, 105, 94, 78, 91, 69,
-  92, 81, 91, 76, 86, 80, 81, 78, 113, 79,
-  88, 85, 98, 77, 86, 80, 76, 99, 72, 85,
-  69, 83, 70, 81, 85, 101, 72, 86, 89, 89,
-  69, 94, 84, 81, 86, 73, 83, 75, 67, 70,
-  89, 81, 79, 70, 84, 79, 92, 89, 94, 84,
-  78, 77, 69, 94, 88, 79, 90, 87, 74, 76,
-  72, 66, 84, 75, 87, 82, 89, 87, 84, 92,
-  88, 81, 87, 76, 91, 105, 78, 56, 68, 61,
-  69, 80, 69, 77, 97, 65, 106, 77, 74, 74,
-  84, 87, 87, 84, 84, 72, 99, 94, 86, 79,
-  83, 82, 81, 71, 70, 84, 115, 92, 81, 67,
-  100, 71, 83, 82, 95, 66, 104, 55, 87, 71,
-  74, 84, 82, 121, 90, 84, 90, 72, 92, 77,
-  87, 84, 89, 73, 93, 79, 92, 80, 79, 77,
-  95, 78, 79, 103, 72, 88, 72, 83, 73, 88,
-  75, 74, 95, 95, 68, 97, 92, 87, 73, 95,
-  84, 78, 84, 77, 82, 72, 64, 74, 105, 80,
-  77, 69, 85, 79, 94, 85, 86, 78, 79, 77,
-  68, 90, 83, 81, 76, 87, 79, 88, 79, 69,
-  90, 75, 83, 86, 83, 105, 89, 90, 90, 81,
-  82, 81, 92, 85, 82, 67, 76, 71, 79, 88,
-  75, 81, 108, 84, 103, 81, 82, 84, 81, 75,
-  84, 70, 82, 81, 112, 86, 75, 87, 81, 79,
-  84, 88, 69, 83, 95, 86, 70, 68, 92, 80,
-  81, 79, 90, 71, 89, 61, 85, 72, 72, 95,
-  89, 110, 88, 87, 92, 69, 92, 76, 96, 76,
-  81, 82, 78, 77, 82, 76, 90, 75, 95, 78,
-  86, 89, 73, 95, 73, 83, 82, 77, 74, 81,
-  94, 103, 80, 85, 92, 90, 69, 96, 85, 81,
-  90, 82, 83, 76, 86, 86, 81, 65, 85, 76,
-  78, 70, 87, 51, 86, 82, 77, 84, 82, 85,
-  69, 83, 83, 76, 91, 93, 88, 80, 84, 84,
-  84, 70, 81, 80, 86, 75, 85, 74, 88, 76,
-  80, 73, 88, 80, 82, 67, 88, 71, 87, 89,
-  77, 88, 88, 75, 83, 91, 71, 67, 102, 84,
-  79, 69, 97, 94, 85, 68, 120, 79, 81, 76,
-  76, 91, 87, 79, 81, 74, 82, 96, 82, 84,
-  81, 81, 73, 70, 86, 87, 90, 91, 97, 140,
-  77, 96, 88, 79, 88, 98, 92, 83, 81, 83,
-  90, 83, 89, 80, 92, 86, 148, 78, 69, 75,
-  78, 85, 80, 82, 79, 80, 94, 81, 83, 88,
-  95, 74, 91, 89, 81, 84, 74, 73, 87, 53,
-  77, 78, 82, 85, 82, 73, 85, 85, 78, 70,
-  85, 49, 91, 86, 76, 86, 86, 85, 69, 86,
-  75, 81, 91, 92, 74, 77, 85, 85, 84, 77,
-  90, 76, 88, 69, 87, 79, 94, 99, 84, 75,
-  86, 72, 78, 69, 86, 75, 91, 85, 77, 78,
-  85, 72, 88, 87, 73, 66, 100, 88, 77, 66,
-  94, 96, 91, 67, 125, 75, 71, 75, 72, 92,
-  85, 78, 88, 73, 75, 93, 78, 83, 87, 70,
-  81, 69, 88, 85, 85, 86, 99, 130, 82, 97,
-  86, 75, 82, 96, 90, 84, 76, 87, 88, 89,
-  77, 76, 88, 94, 158, 81, 69, 77, 81, 88,
-  79, 77, 78, 79, 94, 68, 85, 87, 82, 70,
-  83, 91, 84, 81, 73, 73, 87, 47, 71, 78,
-  83, 80, 79, 74, 86, 95, 83, 78, 92, 58,
-  83, 82, 84, 78, 83, 85, 76, 83, 85, 78,
-  88, 80, 77, 93, 92, 87, 84, 62, 83, 81,
-  88, 71, 93, 77, 91, 115, 75, 81, 80, 76,
-  79, 71, 79, 77, 94, 96, 93, 83, 99, 82,
-  83, 86, 72, 74, 100, 84, 92, 75, 89, 86,
-  78, 74, 110, 77, 71, 79, 91, 90, 89, 82,
-  76, 72, 86, 83, 78, 82, 79, 67, 83, 75,
-  87, 79, 95, 93, 96, 114, 110, 79, 83, 83,
-  91, 88, 92, 87, 76, 89, 88, 78, 72, 96,
-  88, 89, 113, 75, 85, 77, 68, 89, 81, 87,
-  76, 76, 84, 65, 87, 90, 85, 84, 93, 91,
-  89, 89, 91, 68, 86, 70, 85, 88, 88, 77,
-  94, 65, 93, 74, 70, 75, 77, 29, 105, 88,
-  79, 95, 92, 86, 82, 81, 84, 89, 97, 105,
-  81, 77, 78, 90, 79, 90, 95, 83, 85, 80,
-  70, 79, 89, 60, 92, 79, 88, 81, 85, 75,
-  83, 69, 84, 87, 88, 92, 74, 73, 84, 74,
-  76, 70, 87, 81, 71, 71, 94, 111, 87, 70,
-  100, 82, 82, 67, 73, 85, 80, 76, 90, 76,
-  69, 78, 84, 82, 95, 97, 81, 80, 84, 92,
-  75, 70, 99, 82, 67, 107, 85, 68, 69, 80,
-  86, 86, 86, 82, 83, 97, 98, 70, 74, 80,
-  182, 81, 51, 83, 84, 86, 74, 81, 82, 80,
-  91, 104, 77, 87, 89, 52, 78, 88, 88, 86,
-  68, 85, 87, 63, 62, 82, 81, 82, 87, 75,
-  89, 79, 69, 74, 75, 26, 115, 90, 78, 93,
-  97, 87, 88, 86, 86, 87, 82, 111, 70, 78,
-  81, 92, 80, 97, 109, 87, 85, 65, 71, 82,
-  94, 102, 95, 78, 94, 79, 82, 86, 94, 67,
-  87, 81, 85, 77, 66, 76, 88, 73, 78, 66,
-  79, 80, 70, 67, 98, 110, 93, 68, 98, 79,
-  64, 73, 81, 82, 75, 70, 84, 76, 62, 74,
-  72, 82, 101, 79, 84, 82, 86, 91, 74, 74,
-  99, 66, 77, 99, 82, 65, 66, 79, 81, 83,
-  79, 83, 81, 99, 85, 64, 71, 92, 221, 84,
-  51, 81, 91, 84, 70, 77, 81, 82, 95, 70,
-  79, 84, 82, 45, 69, 89, 77, 76, 67, 83,
-  83, 57, 51, 80, 85, 77, 82, 77, 91, 95,
-  76, 82, 88, 52, 90, 85, 92, 85, 87, 95,
-  82, 81, 76, 76, 80, 75, 80, 95, 96, 87,
-  74, 80, 96, 78, 88, 77, 80, 84, 92, 126,
-  89, 86, 85, 85, 84, 72, 87, 77, 92, 100,
-  96, 80, 92, 77, 89, 89, 73, 71, 97, 83,
-  88, 70, 91, 89, 79, 67, 93, 74, 74, 75,
-  89, 85, 95, 83, 81, 68, 74, 83, 71, 86,
-  78, 69, 90, 80, 87, 90, 85, 95, 90, 79,
-  123, 81, 86, 80, 80, 88, 88, 89, 73, 85,
-  82, 83, 75, 93, 79, 95, 98, 78, 79, 88,
-  73, 89, 76, 82, 80, 81, 84, 62, 86, 88,
-  96, 76, 90, 92, 90, 81, 85, 69, 90, 91,
-  75, 83, 90, 82, 85, 61, 90, 78, 76, 86,
-  69, 50, 83, 89, 77, 93, 83, 78, 73, 80,
-  81, 83, 90, 94, 79, 79, 80, 93, 90, 88,
-  79, 80, 82, 96, 85, 85, 81, 69, 94, 78,
-  82, 83, 87, 79, 87, 71, 87, 93, 97, 95,
-  76, 79, 82, 74, 72, 73, 94, 82, 84, 78,
-  89, 96, 84, 79, 90, 83, 83, 74, 86, 90,
-  92, 86, 91, 79, 83, 72, 85, 86, 89, 86,
-  83, 81, 82, 90, 82, 75, 101, 74, 67, 102,
-  82, 84, 83, 79, 91, 93, 93, 85, 76, 83,
-  93, 81, 85, 88, 116, 77, 70, 88, 74, 88,
-  94, 86, 84, 92, 82, 104, 80, 87, 81, 70,
-  90, 87, 87, 85, 75, 81, 91, 108, 71, 83,
-  92, 83, 88, 69, 91, 80, 78, 84, 70, 48,
-  89, 89, 82, 88, 85, 86, 74, 84, 79, 77,
-  86, 95, 76, 80, 81, 92, 90, 95, 92, 93,
-  80, 85, 84, 82, 81, 89, 89, 80, 92, 80,
-  84, 78, 90, 72, 84, 91, 91, 80, 72, 79,
-  80, 83, 76, 70, 93, 83, 87, 74, 89, 100,
-  86, 75, 85, 81, 77, 77, 93, 86, 92, 90,
-  86, 77, 78, 74, 78, 85, 89, 78, 85, 81,
-  83, 92, 80, 81, 97, 72, 74, 95, 81, 80,
-  77, 74, 94, 95, 85, 86, 75, 81, 93, 78,
-  82, 77, 118, 79, 77, 88, 74, 87, 88, 88,
-  84, 87, 80, 76, 86, 86, 88, 66, 87, 88,
-  84, 82, 72, 76, 87, 121, 70, 83, 83, 76,
-  80, 69, 85, 94, 78, 86, 85, 66, 75, 81,
-  90, 86, 87, 84, 79, 76, 81, 74, 84, 78,
-  83, 94, 86, 93, 80, 79, 82, 78, 85, 89,
-  87, 84, 88, 119, 87, 84, 89, 88, 88, 77,
-  90, 81, 92, 93, 97, 81, 90, 83, 85, 88,
-  69, 77, 91, 81, 96, 78, 86, 81, 80, 73,
-  85, 70, 72, 84, 97, 88, 97, 90, 80, 73,
-  82, 81, 74, 90, 90, 69, 85, 82, 83, 84,
-  79, 86, 88, 72, 106, 83, 83, 90, 88, 81,
-  90, 92, 84, 83, 78, 78, 84, 88, 83, 88,
-  99, 75, 79, 87, 67, 90, 90, 85, 85, 86,
-  82, 71, 91, 96, 86, 80, 91, 85, 95, 83,
-  92, 78, 90, 110, 84, 84, 88, 77, 93, 84,
-  86, 92, 70, 96, 77, 88, 93, 86, 88, 83,
-  75, 68, 77, 85, 76, 103, 76, 80, 93, 75,
-  67, 73, 64, 85, 83, 94, 84, 81, 84, 79,
-  83, 90, 70, 79, 91, 73, 73, 78, 70, 82,
-  82, 80, 85, 86, 74, 71, 92, 95, 86, 79,
-  70, 93, 91, 77, 95, 91, 76, 91, 84, 83,
-  91, 67, 83, 85, 84, 67, 85, 87, 83, 85,
-  75, 76, 83, 89, 82, 54, 70, 115, 76, 92,
-  81, 92, 75, 97, 121, 76, 79, 100, 85, 77,
-  95, 85, 84, 90, 89, 72, 89, 77, 89, 81,
-  82, 76, 77, 91, 90, 70, 77, 82, 71, 91,
-  85, 109, 95, 87, 66, 72, 92, 96, 73, 79,
-  87, 89, 85, 86, 79, 85, 97, 81, 93, 87,
-  72, 98, 82, 88, 93, 86, 87, 91, 82, 68,
-  75, 82, 75, 102, 72, 80, 86, 83, 71, 76,
-  67, 85, 90, 89, 81, 80, 79, 80, 80, 84,
-  72, 81, 89, 73, 77, 83, 72, 91, 87, 75,
-  89, 77, 68, 72, 91, 104, 89, 84, 72, 100,
-  88, 80, 99, 89, 75, 89, 87, 90, 92, 76,
-  81, 74, 75, 61, 85, 83, 80, 84, 78, 74,
-  84, 77, 88, 59, 72, 115, 79, 90, 79, 87,
-  80, 91, 130, 87, 77, 95, 81, 75, 89, 85,
-  82, 94, 86, 76, 86, 83, 92, 82, 79, 78,
-  76, 98, 98, 72, 85, 80, 69, 79, 86, 96,
-  75, 84, 64, 76, 79, 90, 75, 78, 88, 87,
-  85, 88, 83, 82, 85, 83, 87, 97, 75, 93,
-  78, 86, 81, 86, 88, 93, 77, 71, 78, 88,
-  78, 97, 72, 80, 90, 77, 77, 83, 69, 86,
-  85, 87, 93, 89, 86, 81, 88, 96, 88, 76,
-  78, 78, 71, 79, 77, 70, 77, 83, 83, 95,
-  81, 75, 87, 84, 86, 79, 81, 77, 90, 76,
-  87, 89, 81, 95, 76, 75, 84, 64, 90, 87,
-  83, 75, 90, 92, 85, 81, 80, 76, 83, 82,
-  88, 61, 72, 106, 80, 95, 83, 83, 92, 89,
-  100, 86, 80, 100, 92, 80, 93, 83, 87, 90,
-  81, 80, 86, 97, 85, 84, 81, 82, 69, 87,
-  95, 73, 81, 91, 76, 80, 82, 95, 80, 89,
-  72, 73, 74, 94, 73, 80, 83, 91, 87, 86,
-  74, 81, 96, 75, 83, 90, 57, 87, 67, 82,
-  89, 95, 83, 106, 87, 71, 77, 64, 71, 105,
-  79, 77, 85, 86, 68, 67, 61, 79, 91, 89,
-  82, 82, 75, 87, 89, 86, 80, 83, 82, 75,
-  86, 61, 69, 90, 75, 86, 80, 94, 65, 70,
-  99, 103, 85, 91, 65, 97, 77, 95, 104, 79,
-  76, 74, 89, 82, 83, 58, 87, 72, 77, 52,
-  82, 86, 70, 76, 77, 74, 80, 87, 81, 76,
-  71, 151, 79, 70, 84, 89, 77, 97, 151, 68,
-  66, 84, 89, 72, 98, 85, 89, 84, 75, 69,
-  74, 77, 88, 81, 90, 81, 74, 85, 85, 66,
-  89, 71, 66, 85, 96, 113, 77, 85, 59, 83,
-  91, 104, 79, 68, 96, 83, 82, 89, 73, 89,
-  93, 72, 88, 81, 62, 91, 75, 83, 90, 91,
-  87, 102, 93, 74, 77, 68, 72, 106, 71, 79,
-  80, 91, 71, 69, 69, 81, 94, 78, 75, 74,
-  74, 85, 76, 82, 75, 82, 99, 76, 83, 67,
-  77, 97, 74, 78, 79, 80, 61, 69, 95, 104,
-  90, 95, 64, 123, 78, 95, 99, 73, 72, 73,
-  83, 85, 76, 66, 91, 65, 75, 58, 93, 79,
-  73, 78, 77, 67, 81, 80, 87, 81, 72, 150,
-  83, 73, 84, 84, 78, 91, 155, 68, 69, 78,
-  82, 69, 84, 84, 87, 83, 74, 75, 72, 78,
-  92, 82, 86, 82, 74, 86, 95, 66, 94, 71,
-  68, 73, 94, 99, 74, 82, 56, 86, 76, 96,
-  81, 67, 97, 81, 78, 93, 75, 90, 78, 80,
-  78, 99, 67, 88, 72, 83, 85, 94, 83, 85,
-  85, 75, 77, 74, 71, 102, 71, 71, 89, 85,
-  81, 78, 70, 81, 87, 88, 86, 87, 81, 90,
-  90, 95, 96, 79, 84, 73, 89, 65, 81, 73,
-  75, 86, 76, 100, 74, 75, 92, 79, 85, 87,
-  79, 95, 82, 89, 96, 77, 83, 84, 82, 74,
-  77, 60, 95, 78, 80, 78, 82, 94, 79, 75,
-  80, 70, 87, 89, 88, 83, 73, 127, 80, 88,
-  88, 87, 89, 88, 107, 79, 70, 75, 94, 82,
-  88, 86, 88, 86, 75, 74, 73, 91, 83, 86,
-  85, 80, 73, 79, 86, 69, 87, 78, 74, 78,
-  87, 102, 85, 84, 68, 85, 72, 99, 74, 72,
-  89, 85, 81, 90, 90, 81, 85, 85, 85, 88,
-  74, 87, 88, 85, 87, 81, 85, 87, 77, 73,
-  86, 85, 76, 85, 87, 78, 75, 91, 76, 72,
-  84, 84, 83, 87, 82, 82, 85, 91, 86, 83,
-  83, 97, 69, 77, 97, 76, 79, 73, 82, 98,
-  84, 94, 80, 70, 88, 79, 98, 85, 91, 77,
-  105, 87, 80, 81, 88, 95, 95, 90, 82, 73,
-  94, 90, 88, 75, 86, 86, 88, 77, 84, 88,
-  76, 80, 78, 62, 76, 79, 91, 70, 76, 85,
-  77, 76, 99, 89, 87, 90, 95, 86, 106, 79,
-  88, 86, 83, 83, 81, 88, 94, 84, 86, 90,
-  73, 75, 92, 82, 73, 92, 79, 89, 87, 96,
-  92, 92, 81, 87, 87, 84, 74, 82, 81, 92,
-  89, 79, 93, 89, 78, 81, 82, 80, 69, 87,
-  93, 85, 90, 78, 85, 78, 81, 74, 87, 87,
-  79, 92, 82, 79, 75, 94, 83, 73, 86, 86,
-  78, 81, 73, 84, 83, 91, 78, 81, 84, 95,
-  79, 71, 91, 74, 79, 74, 83, 93, 83, 88,
-  78, 71, 85, 74, 102, 85, 89, 85, 109, 83,
-  83, 81, 88, 99, 94, 92, 76, 76, 99, 95,
-  86, 79, 80, 82, 92, 76, 86, 82, 79, 77,
-  76, 66, 77, 74, 92, 79, 79, 82, 79, 69,
-  86, 90, 87, 80, 91, 87, 95, 79, 87, 88,
-  80, 89, 82, 91, 97, 85, 83, 93, 77, 71,
-  98, 82, 71, 91, 80, 83, 87, 94, 87, 90,
-  79, 83, 79, 82, 76, 82, 83, 93, 89, 84,
-  90, 87, 81, 81, 88, 87, 78, 82, 88, 87,
-  87, 86, 91, 72, 73, 79, 86, 90, 80, 86,
-  81, 79, 87, 86, 85, 75, 82, 85, 83, 90,
-  83, 83, 86, 94, 88, 86, 95, 91, 79, 82,
-  97, 71, 84, 72, 79, 93, 83, 91, 85, 76,
-  85, 78, 93, 85, 93, 78, 92, 84, 79, 74,
-  89, 97, 89, 82, 81, 74, 93, 89, 85, 92,
-  78, 88, 88, 79, 82, 77, 79, 92, 85, 65,
-  86, 80, 90, 86, 77, 87, 84, 80, 84, 83,
-  86, 70, 100, 86, 88, 79, 86, 84, 78, 79,
-  84, 83, 90, 87, 85, 81, 81, 74, 90, 80,
-  74, 96, 83, 80, 90, 85, 97, 94, 83, 88,
-  76, 84, 71, 80, 85, 91, 90, 80, 85, 87,
-  85, 78, 79, 91, 80, 97, 82, 58, 90, 94,
-  78, 86, 68, 85, 74, 87, 88, 85, 92, 88,
-  78, 79, 88, 79, 84, 67, 78, 73, 94, 85,
-  84, 87, 77, 91, 83, 75, 94, 73, 90, 59,
-  82, 96, 84, 90, 84, 88, 78, 89, 80, 83,
-  78, 91, 89, 86, 85, 87, 97, 89, 94, 80,
-  81, 86, 77, 83, 86, 95, 81, 77, 92, 83,
-  92, 87, 90, 81, 85, 89, 62, 75, 85, 85,
-  95, 86, 81, 107, 95, 86, 76, 90, 98, 95,
-  107, 89, 84, 96, 98, 81, 91, 96, 92, 79,
-  84, 88, 103, 78, 75, 85, 76, 82, 89, 90,
-  96, 65, 87, 83, 84, 83, 76, 83, 76, 75,
-  78, 92, 85, 61, 86, 83, 88, 91, 80, 77,
-  82, 83, 76, 103, 84, 84, 83, 89, 73, 88,
-  75, 82, 77, 78, 83, 83, 78, 91, 72, 71,
-  91, 91, 87, 73, 86, 81, 93, 80, 83, 89,
-  85, 86, 82, 75, 83, 78, 74, 56, 83, 93,
-  85, 76, 87, 84, 84, 96, 81, 83, 87, 82,
-  85, 88, 95, 86, 89, 90, 94, 81, 81, 76,
-  74, 88, 77, 91, 76, 84, 80, 86, 87, 78,
-  81, 81, 85, 80, 71, 86, 85, 89, 89, 83,
-  80, 102, 95, 85, 83, 88, 102, 83, 94, 89,
-  76, 90, 93, 81, 76, 80, 85, 71, 84, 86,
-  85, 72, 81, 88, 62, 80, 86, 83, 79, 62,
-  88, 90, 96, 84, 81, 85, 86, 83, 71, 96,
-  80, 63, 80, 83, 102, 84, 87, 82, 85, 78,
-  77, 107, 88, 101, 77, 84, 89, 88, 87, 79,
-  89, 71, 83, 82, 88, 82, 81, 67, 101, 96,
-  91, 83, 75, 91, 90, 69, 87, 82, 85, 90,
-  92, 71, 87, 81, 80, 71, 83, 93, 91, 76,
-  95, 80, 95, 92, 73, 83, 84, 80, 85, 88,
-  98, 82, 85, 89, 87, 86, 83, 79, 90, 92,
-  85, 92, 80, 94, 89, 79, 88, 86, 83, 64,
-  79, 87, 79, 78, 84, 84, 96, 79, 90, 87,
-  124, 80, 84, 90, 94, 81, 78, 89, 81, 85,
-  95, 79, 92, 75, 96, 79, 100, 83, 65, 84,
-  84, 96, 81, 77, 93, 83, 68, 53, 88, 96,
-  87, 80, 105, 92, 98, 84, 65, 103, 74, 77,
-  75, 85, 83, 94, 91, 80, 78, 86, 83, 71,
-  85, 41, 69, 87, 80, 95, 77, 89, 71, 92,
-  66, 92, 86, 95, 78, 94, 79, 70, 93, 83,
-  101, 75, 70, 96, 77, 76, 70, 91, 94, 124,
-  98, 72, 86, 76, 89, 85, 88, 86, 84, 94,
-  79, 74, 84, 80, 75, 84, 80, 87, 63, 80,
-  85, 71, 78, 79, 90, 83, 70, 92, 75, 73,
-  77, 84, 86, 74, 83, 84, 88, 64, 94, 93,
-  66, 79, 84, 84, 62, 71, 67, 69, 97, 87,
-  79, 78, 62, 89, 95, 97, 75, 89, 91, 85,
-  93, 85, 70, 85, 80, 90, 148, 85, 83, 79,
-  88, 82, 92, 92, 90, 78, 81, 80, 67, 106,
-  63, 80, 76, 73, 77, 60, 93, 77, 73, 91,
-  80, 85, 78, 76, 76, 96, 72, 74, 77, 72,
-  67, 84, 69, 92, 75, 88, 76, 83, 80, 90,
-  72, 97, 65, 78, 91, 75, 86, 75, 110, 77,
-  81, 103, 70, 88, 77, 86, 85, 95, 83, 79,
-  83, 75, 81, 92, 80, 81, 81, 90, 87, 82,
-  82, 84, 84, 75, 83, 82, 82, 73, 89, 76,
-  85, 82, 87, 55, 59, 85, 63, 87, 79, 91,
-  68, 81, 86, 86, 78, 85, 96, 87, 65, 86,
-  86, 84, 64, 77, 70, 66, 124, 92, 72, 82,
-  85, 93, 94, 102, 94, 90, 90, 79, 68, 75,
-  74, 81, 84, 86, 118, 78, 93, 85, 65, 71,
-  86, 90, 84, 60, 73, 86, 95, 99, 63, 84,
-  73, 78, 62, 76, 83, 68, 80, 79, 104, 76,
-  80, 76, 87, 64, 78, 100, 81, 95, 79, 84,
-  92, 91, 84, 84, 91, 63, 93, 83, 84, 79,
-  74, 66, 102, 101, 85, 74, 92, 81, 94, 79,
-  87, 90, 80, 88, 95, 59, 83, 91, 88, 76,
-  75, 97, 82, 77, 93, 88, 94, 89, 79, 86,
-  91, 79, 88, 86, 95, 79, 93, 93, 82, 80,
-  83, 55, 69, 85, 75, 96, 91, 86, 74, 80,
-  83, 88, 78, 70, 77, 80, 67, 84, 92, 95,
-  104, 75, 94, 75, 165, 78, 79, 86, 106, 88,
-  86, 89, 79, 87, 88, 75, 86, 78, 87, 86,
-  80, 82, 49, 79, 94, 96, 76, 81, 93, 76,
-  70, 51, 78, 98, 80, 75, 95, 90, 93, 81,
-  78, 106, 81, 85, 71, 82, 84, 96, 89, 92,
-  82, 83, 72, 65, 87, 40, 75, 82, 78, 102,
-  75, 88, 73, 78, 75, 93, 86, 88, 86, 93,
-  86, 74, 102, 88, 84, 81, 80, 87, 87, 78,
-  67, 93, 83, 135, 80, 72, 89, 85, 82, 81,
-  75, 89, 84, 91, 73, 80, 81, 89, 73, 89,
-  77, 90, 70, 81, 75, 83, 62, 83, 101, 90,
-  79, 91, 74, 80, 87, 79, 78, 83, 93, 79,
-  93, 75, 89, 88, 87, 80, 87, 81, 72, 77,
-  78, 70, 109, 84, 80, 70, 64, 81, 90, 103,
-  65, 68, 91, 79, 97, 90, 75, 88, 68, 89,
-  110, 90, 88, 78, 77, 96, 86, 96, 80, 94,
-  81, 98, 82, 98, 90, 91, 81, 84, 95, 64,
-  97, 102, 82, 85, 81, 93, 76, 86, 77, 87,
-  70, 70, 87, 68, 72, 91, 74, 83, 74, 89,
-  79, 75, 85, 86, 81, 87, 76, 80, 100, 73,
-  98, 88, 98, 77, 81, 102, 80, 89, 72, 85,
-  84, 109, 91, 77, 84, 76, 78, 88, 73, 85,
-  84, 83, 86, 80, 83, 93, 81, 81, 78, 79,
-  85, 74, 86, 76, 68, 78, 96, 68, 69, 88,
-  66, 86, 87, 86, 75, 79, 90, 88, 87, 89,
-  88, 91, 75, 86, 87, 83, 74, 79, 75, 69,
-  115, 83, 74, 77, 87, 84, 90, 100, 83, 70,
-  99, 76, 75, 82, 80, 86, 81, 84, 107, 85,
-  92, 85, 77, 81, 83, 90, 79, 68, 83, 92,
-  92, 86, 80, 91, 79, 79, 75, 76, 89, 94,
-  85, 80, 97, 75, 81, 79, 87, 69, 73, 91,
-  82, 94, 81, 85, 87, 95, 83, 88, 87, 60,
-  84, 84, 90, 82, 80, 69, 102, 92, 89, 78,
-  81, 77, 95, 87, 91, 97, 80, 91, 91, 66,
-  86, 88, 91, 74, 74, 97, 76, 84, 88, 93,
-  91, 90, 77, 91, 84, 81, 86, 80, 90, 81,
-  96, 91, 75, 78, 88, 61, 84, 89, 74, 99,
-  93, 91, 71, 84, 81, 88, 80, 73, 84, 79,
-  68, 78, 87, 89, 98, 76, 92, 73, 144, 72,
-  78, 87, 104, 84, 89, 89, 78, 76, 100, 76,
-  86, 79, 86, 92, 93, 85, 71, 87, 87, 89,
-  85, 78, 93, 82, 80, 59, 86, 98, 78, 74,
-  102, 86, 94, 82, 67, 115, 79, 90, 78, 82,
-  71, 99, 86, 93, 100, 83, 89, 90, 89, 86,
-  71, 64, 58, 89, 87, 91, 85, 105, 97, 112,
-  82, 67, 102, 94, 73, 97, 92, 91, 80, 75,
-  90, 88, 93, 76, 95, 86, 93, 92, 58, 81,
-  89, 74, 88, 97, 74, 104, 82, 73, 86, 81,
-  89, 87, 65, 91, 93, 89, 84, 113, 82, 82,
-  76, 86, 74, 66, 111, 73, 69, 72, 82, 90,
-  87, 65, 94, 77, 98, 84, 83, 80, 91, 85,
-  97, 93, 85, 96, 86, 84, 95, 71, 92, 88,
-  78, 90, 83, 95, 91, 88, 97, 80, 84, 99,
-  80, 88, 75, 83, 99, 84, 90, 74, 85, 78,
-  82, 83, 91, 99, 89, 79, 70, 79, 90, 76,
-  67, 86, 89, 97, 84, 83, 84, 85, 100, 91,
-  79, 76, 74, 69, 78, 84, 75, 80, 80, 86,
-  83, 70, 73, 71, 76, 79, 74, 84, 84, 102,
-  79, 77, 75, 69, 88, 78, 95, 80, 83, 68,
-  93, 91, 82, 84, 80, 84, 89, 81, 83, 78,
-  93, 83, 73, 86, 85, 86, 72, 83, 89, 78,
-  83, 81, 77, 91, 71, 91, 59, 87, 88, 108,
-  75, 114, 71, 73, 68, 84, 66, 73, 98, 105,
-  76, 78, 76, 73, 78, 72, 82, 81, 79, 77,
-  76, 89, 82, 86, 86, 89, 78, 86, 85, 82,
-  85, 88, 82, 89, 77, 75, 91, 84, 82, 92,
-  89, 86, 77, 90, 80, 87, 77, 76, 89, 85,
-  77, 81, 62, 90, 60, 94, 98, 83, 76, 90,
-  78, 71, 80, 86, 84, 74, 112, 86, 90, 81,
-  74, 66, 83, 85, 71, 83, 84, 91, 74, 83,
-  75, 71, 82, 77, 86, 81, 88, 103, 76, 83,
-  87, 72, 87, 79, 93, 95, 95, 97, 87, 83,
-  86, 106, 79, 94, 73, 90, 93, 77, 93, 81,
-  73, 85, 96, 82, 76, 82, 82, 74, 83, 74,
-  75, 87, 78, 86, 69, 72, 82, 107, 76, 118,
-  81, 67, 80, 95, 65, 80, 73, 103, 79, 80,
-  85, 74, 76, 100, 96, 74, 76, 75, 90, 79,
-  84, 99, 78, 95, 82, 87, 75, 79, 86, 88,
-  86, 89, 79, 83, 95, 81, 81, 81, 93, 86,
-  74, 87, 66, 82, 80, 74, 102, 96, 79, 85,
-  85, 97, 91, 91, 96, 79, 73, 88, 74, 73,
-  79, 95, 86, 78, 67, 110, 87, 96, 92, 76,
-  84, 87, 90, 87, 75, 72, 60, 78, 85, 94,
-  84, 104, 107, 124, 80, 63, 96, 95, 85, 100,
-  91, 94, 77, 73, 92, 87, 85, 66, 78, 78,
-  91, 89, 70, 79, 83, 76, 81, 91, 72, 104,
-  87, 74, 90, 80, 91, 88, 72, 82, 94, 78,
-  97, 98, 92, 88, 80, 72, 84, 48, 94, 62,
-  74, 83, 73, 102, 75, 64, 92, 80, 98, 93,
-  72, 71, 85, 85, 88, 101, 89, 97, 81, 79,
-  91, 67, 109, 93, 85, 90, 79, 96, 85, 79,
-  97, 71, 85, 93, 76, 82, 80, 86, 98, 83,
-  102, 81, 99, 83, 82, 75, 102, 100, 80, 79,
-  82, 73, 84, 91, 71, 78, 89, 109, 81, 76,
-  83, 91, 97, 91, 86, 70, 81, 62, 65, 75,
-  76, 85, 88, 91, 85, 86, 73, 71, 83, 63,
-  69, 76, 78, 119, 61, 69, 71, 65, 62, 78,
-  112, 79, 88, 65, 90, 97, 69, 80, 84, 78,
-  68, 92, 67, 74, 96, 86, 75, 70, 83, 104,
-  70, 85, 76, 96, 76, 84, 74, 63, 83, 76,
-  70, 73, 79, 121, 82, 115, 42, 97, 70, 74,
-  79, 65, 78, 78, 72, 84, 70, 69, 69, 60,
-  87, 81, 68, 71, 71, 91, 90, 79, 77, 104,
-  65, 80, 79, 76, 77, 75, 76, 93, 75, 70,
-  78, 84, 76, 77, 94, 88, 78, 81, 88, 91,
-  71, 77, 94, 82, 68, 72, 74, 73, 63, 88,
-  89, 88, 73, 87, 71, 61, 83, 76, 83, 77,
-  103, 84, 87, 81, 78, 54, 79, 78, 75, 88,
-  90, 86, 86, 73, 80, 74, 91, 64, 76, 81,
-  93, 103, 55, 78, 77, 73, 65, 84, 109, 101,
-  94, 92, 86, 78, 77, 108, 84, 93, 96, 95,
-  78, 68, 83, 84, 77, 74, 93, 82, 74, 88,
-  75, 83, 82, 72, 72, 77, 88, 84, 76, 69,
-  72, 113, 80, 133, 61, 99, 78, 87, 79, 65,
-  82, 73, 74, 97, 88, 69, 69, 118, 99, 69,
-  67, 72, 84, 73, 81, 96, 58, 106, 73, 82,
-  80, 87, 85, 76, 87, 97, 73, 75, 95, 87,
-  73, 71, 96, 85, 74, 78, 81, 83, 69, 79,
-  93, 95, 76, 67, 76, 80, 103, 85, 89, 85,
-  75, 82, 76, 68, 79, 90, 86, 80, 77, 106,
-  102, 89, 92, 82, 88, 78, 87, 88, 82, 72,
-  63, 84, 88, 96, 87, 103, 94, 111, 79, 71,
-  96, 95, 91, 94, 88, 84, 73, 79, 90, 85,
-  87, 65, 89, 70, 98, 88, 85, 89, 77, 94,
-  91, 89, 80, 96, 81, 83, 83, 74, 91, 92,
-  77, 87, 98, 90, 82, 95, 89, 77, 82, 75,
-  80, 63, 89, 78, 86, 77, 79, 110, 79, 68,
-  85, 87, 96, 85, 87, 81, 78, 83, 89, 95,
-  95, 104, 90, 77, 87, 70, 97, 89, 86, 94,
-  79, 84, 83, 79, 96, 79, 87, 88, 80, 91,
-  82, 92, 89, 87, 99, 83, 101, 82, 97, 77,
-  94, 97, 80, 90, 81, 76, 94, 89, 70, 82,
-  82, 94, 80, 84, 86, 86, 95, 81, 96, 80,
-  83, 69, 77, 76, 67, 85, 92, 86, 84, 91,
-  73, 75, 85, 65, 72, 78, 82, 116, 60, 80,
-  73, 67, 78, 76, 91, 74, 103, 69, 88, 94,
-  86, 65, 98, 80, 59, 84, 81, 87, 92, 80,
-  77, 60, 81, 93, 78, 84, 78, 98, 77, 74,
-  82, 74, 77, 77, 72, 81, 85, 111, 83, 129,
-  52, 83, 76, 87, 92, 76, 76, 82, 78, 87,
-  76, 71, 83, 72, 97, 74, 72, 85, 79, 94,
-  94, 86, 77, 99, 82, 78, 77, 79, 85, 81,
-  75, 87, 77, 76, 85, 87, 76, 70, 91, 90,
-  84, 81, 86, 88, 78, 78, 97, 88, 72, 77,
-  99, 79, 47, 89, 97, 86, 76, 84, 73, 63,
-  85, 87, 84, 84, 95, 89, 97, 92, 76, 70,
-  85, 76, 70, 87, 91, 90, 84, 62, 78, 79,
-  92, 79, 84, 91, 100, 98, 73, 88, 78, 76,
-  86, 86, 89, 103, 89, 86, 87, 72, 74, 89,
-  91, 92, 94, 89, 91, 82, 74, 81, 80, 77,
-  88, 82, 72, 85, 85, 90, 82, 67, 93, 79,
-  80, 84, 77, 82, 85, 91, 77, 121, 71, 85,
-  82, 96, 89, 81, 84, 86, 83, 97, 90, 72,
-  85, 102, 85, 67, 72, 87, 83, 88, 86, 100,
-  70, 88, 85, 82, 79, 102, 86, 80, 86, 89,
-  80, 72, 101, 86, 70, 84, 94, 88, 87, 86,
-  87, 86, 71, 82, 85, 94, 83, 76, 79, 85,
-  88, 78, 94, 84, 77, 84, 76, 71, 83, 100,
-  87, 88, 92, 86, 110, 77, 79, 92, 76, 83,
-  65, 93, 97, 103, 80, 97, 73, 98, 81, 73,
-  92, 105, 105, 90, 78, 87, 71, 79, 95, 87,
-  90, 79, 114, 77, 79, 71, 79, 95, 87, 81,
-  98, 77, 86, 80, 74, 95, 95, 95, 81, 67,
-  72, 82, 81, 73, 79, 80, 88, 86, 82, 79,
-  93, 84, 78, 71, 75, 76, 67, 81, 81, 91,
-  88, 72, 89, 84, 67, 98, 85, 79, 88, 89,
-  82, 76, 88, 79, 89, 86, 74, 96, 86, 80,
-  74, 98, 88, 90, 87, 80, 75, 83, 74, 79,
-  91, 90, 83, 89, 81, 72, 81, 89, 81, 76,
-  67, 75, 74, 94, 81, 85, 84, 90, 62, 73,
-  87, 74, 88, 77, 65, 98, 80, 93, 96, 87,
-  112, 73, 91, 75, 90, 97, 66, 74, 55, 85,
-  91, 112, 86, 99, 62, 99, 88, 88, 103, 97,
-  77, 95, 99, 73, 87, 67, 86, 83, 95, 72,
-  144, 98, 77, 84, 86, 73, 89, 83, 106, 76,
-  93, 76, 98, 116, 105, 114, 76, 69, 69, 73,
-  91, 64, 66, 81, 78, 91, 99, 78, 84, 76,
-  92, 59, 83, 83, 62, 75, 73, 100, 87, 64,
-  89, 77, 42, 108, 78, 81, 106, 74, 73, 71,
-  89, 83, 81, 77, 69, 88, 88, 70, 71, 91,
-  77, 104, 85, 78, 73, 81, 87, 87, 78, 60,
-  79, 71, 73, 67, 71, 89, 73, 69, 66, 80,
-  83, 112, 77, 83, 82, 88, 76, 66, 81, 64,
-  85, 90, 52, 88, 71, 93, 122, 79, 85, 73,
-  71, 84, 79, 65, 87, 83, 73, 94, 91, 89,
-  88, 88, 76, 96, 78, 71, 86, 93, 73, 86,
-  82, 90, 86, 86, 87, 84, 84, 81, 99, 79,
-  81, 85, 80, 80, 89, 89, 84, 79, 75, 76,
-  102, 88, 91, 91, 81, 94, 68, 86, 85, 80,
-  82, 84, 73, 76, 77, 85, 96, 90, 84, 67,
-  81, 70, 72, 87, 84, 94, 92, 81, 89, 79,
-  67, 78, 80, 86, 86, 72, 79, 79, 90, 78,
-  81, 82, 78, 81, 87, 86, 78, 101, 90, 100,
-  87, 78, 96, 85, 71, 71, 88, 91, 90, 81,
-  82, 80, 85, 90, 74, 80, 73, 76, 87, 85,
-  77, 87, 85, 97, 95, 81, 88, 84, 83, 79,
-  75, 94, 80, 89, 90, 90, 94, 93, 90, 77,
-  86, 83, 79, 90, 58, 85, 97, 118, 83, 93,
-  67, 88, 92, 91, 96, 111, 115, 79, 87, 91,
-  77, 71, 100, 89, 94, 71, 95, 75, 89, 73,
-  89, 99, 84, 84, 92, 79, 94, 98, 69, 110,
-  84, 85, 78, 64, 84, 78, 82, 77, 84, 89,
-  88, 86, 90, 65, 89, 78, 69, 75, 80, 73,
-  66, 76, 68, 95, 81, 73, 79, 82, 68, 102,
-  102, 79, 94, 93, 82, 81, 78, 90, 83, 67,
-  83, 90, 88, 73, 67, 86, 80, 78, 89, 80,
-  50, 83, 86, 78, 120, 72, 68, 97, 84, 70,
-  82, 87, 79, 82, 79, 90, 77, 101, 78, 88,
-  83, 91, 62, 73, 81, 71, 84, 77, 65, 89,
-  69, 85, 103, 75, 114, 68, 75, 84, 86, 94,
-  57, 91, 46, 74, 91, 137, 85, 99, 59, 65,
-  111, 111, 118, 77, 72, 86, 92, 71, 113, 56,
-  109, 84, 104, 89, 106, 107, 94, 74, 91, 63,
-  77, 72, 94, 76, 77, 94, 93, 128, 86, 121,
-  84, 74, 80, 68, 93, 73, 67, 95, 100, 90,
-  118, 64, 75, 75, 67, 83, 81, 85, 84, 71,
-  66, 95, 78, 78, 80, 75, 46, 102, 95, 77,
-  121, 75, 72, 77, 75, 93, 89, 82, 77, 79,
-  90, 59, 62, 82, 69, 71, 80, 81, 29, 84,
-  108, 102, 95, 46, 58, 75, 82, 65, 72, 95,
-  88, 70, 79, 91, 85, 131, 79, 82, 86, 85,
-  85, 55, 83, 64, 71, 91, 47, 74, 56, 81,
-  133, 63, 80, 69, 72, 92, 84, 74, 82, 86,
-  67, 91, 93, 110, 97, 90, 69, 87, 86, 92,
-  91, 88, 70, 81, 79, 91, 113, 73, 91, 86,
-  86, 97, 89, 89, 85, 97, 78, 73, 79, 91,
-  82, 82, 90, 92, 116, 100, 85, 90, 92, 97,
-  84, 81, 85, 81, 88, 92, 77, 79, 86, 70,
-  93, 78, 77, 77, 83, 63, 72, 81, 86, 93,
-  74, 78, 75, 79, 59, 92, 94, 87, 92, 76,
-  70, 82, 89, 89, 79, 93, 83, 82, 88, 85,
-  75, 91, 82, 94, 88, 78, 81, 87, 86, 69,
-  78, 73, 78, 76, 82, 76, 86, 86, 75, 88,
-  80, 89, 86, 91, 83, 88, 89, 96, 95, 80,
-  83, 76, 65, 79, 72, 90, 73, 82, 97, 79,
-  87, 87, 79, 82, 93, 90, 85, 98, 69, 94,
-  93, 94, 93, 79, 71, 92, 100, 83, 85, 92,
-  82, 88, 62, 92, 82, 86, 91, 87, 80, 71,
-  81, 74, 87, 80, 84, 92, 82, 85, 86, 88,
-  90, 86, 79, 93, 70, 81, 89, 65, 84, 76,
-  79, 90, 82, 97, 90, 93, 80, 76, 95, 85,
-  79, 89, 92, 75, 79, 84, 81, 88, 80, 86,
-  80, 74, 84, 92, 93, 94, 87, 84, 83, 79,
-  83, 76, 88, 85, 87, 87, 85, 88, 77, 72,
-  95, 82, 90, 86, 63, 72, 75, 72, 112, 82,
-  79, 98, 87, 79, 76, 76, 77, 95, 90, 89,
-  69, 80, 77, 88, 93, 98, 85, 85, 88, 87,
-  96, 82, 75, 101, 78, 82, 86, 74, 91, 84,
-  73, 82, 94, 74, 75, 99, 64, 94, 95, 98,
-  91, 89, 69, 95, 107, 91, 87, 91, 70, 77,
-  79, 84, 99, 73, 92, 88, 89, 90, 80, 77,
-  89, 81, 84, 77, 85, 72, 87, 86, 87, 76,
-  73, 106, 68, 82, 99, 70, 79, 78, 76, 83,
-  82, 95, 84, 86, 81, 74, 84, 100, 74, 85,
-  99, 81, 89, 81, 75, 91, 78, 78, 75, 79,
-  70, 87, 103, 93, 84, 79, 88, 71, 86, 81,
-  82, 84, 88, 82, 86, 90, 77, 66, 87, 73,
-  82, 82, 56, 73, 84, 83, 93, 67, 75, 94,
-  89, 71, 80, 81, 84, 90, 87, 91, 76, 82,
-  77, 81, 102, 92, 91, 81, 88, 88, 80, 71,
-  70, 103, 70, 78, 104, 70, 82, 80, 77, 86,
-  86, 56, 86, 94, 71, 93, 93, 92, 94, 85,
-  76, 89, 93, 83, 85, 80, 86, 87, 90, 87,
-  106, 86, 87, 86, 76, 85, 82, 82, 86, 90,
-  78, 78, 82, 86, 82, 88, 84, 80, 86, 88,
-  71, 82, 100, 93, 81, 77, 79, 85, 81, 92,
-  91, 80, 79, 77, 96, 82, 81, 88, 91, 64,
-  94, 89, 90, 86, 75, 82, 75, 67, 84, 90,
-  97, 97, 85, 77, 77, 83, 88, 80, 85, 91,
-  86, 83, 90, 93, 82, 81, 98, 87, 88, 86,
-  81, 79, 78, 74, 80, 84, 84, 89, 82, 81,
-  75, 82, 77, 95, 87, 84, 85, 77, 79, 86,
-  99, 93, 89, 84, 88, 90, 71, 84, 75, 92,
-  82, 83, 88, 78, 74, 72, 110, 81, 81, 81,
-  85, 91, 82, 83, 76, 72, 89, 98, 74, 92,
-  85, 92, 85, 86, 83, 83, 85, 103, 82, 74,
-  84, 77, 84, 68, 73, 85, 91, 74, 58, 79,
-  79, 79, 78, 92, 79, 89, 85, 84, 81, 87,
-  84, 83, 95, 78, 83, 105, 99, 81, 70, 83,
-  80, 84, 83, 83, 89, 81, 96, 105, 88, 88,
-  111, 74, 84, 88, 81, 90, 78, 91, 82, 91,
-  77, 78, 88, 88, 79, 81, 86, 74, 78, 90,
-  92, 98, 87, 78, 82, 94, 79, 89, 85, 84,
-  82, 74, 87, 81, 74, 76, 73, 84, 88, 81,
-  81, 74, 81, 76, 90, 79, 75, 89, 101, 89,
-  90, 87, 80, 92, 93, 91, 82, 81, 87, 90,
-  73, 87, 78, 93, 89, 84, 92, 72, 78, 81,
-  80, 87, 74, 80, 93, 98, 74, 79, 91, 91,
-  86, 90, 84, 75, 76, 103, 81, 70, 83, 77,
-  104, 67, 60, 88, 87, 85, 52, 65, 79, 68,
-  92, 70, 76, 89, 78, 86, 86, 84, 90, 62,
-  84, 57, 96, 97, 97, 78, 59, 108, 86, 84,
-  89, 81, 88, 71, 114, 100, 90, 90, 104, 63,
-  84, 79, 98, 91, 74, 84, 79, 83, 75, 59,
-  107, 75, 77, 93, 77, 71, 78, 86, 87, 95,
-  94, 75, 83, 97, 77, 77, 94, 90, 89, 69,
-  91, 81, 71, 84, 78, 84, 89, 83, 113, 84,
-  85, 65, 79, 67, 68, 87, 106, 86, 89, 76,
-  66, 90, 87, 95, 81, 82, 80, 86, 79, 73,
-  68, 94, 75, 77, 75, 79, 84, 84, 83, 87,
-  74, 80, 93, 76, 72, 87, 84, 92, 89, 81,
-  89, 78, 76, 103, 90, 78, 90, 83, 80, 68,
-  69, 86, 92, 83, 68, 86, 87, 80, 100, 88,
-  79, 92, 85, 85, 85, 84, 83, 81, 97, 82,
-  83, 95, 101, 82, 80, 103, 78, 77, 82, 85,
-  90, 85, 89, 89, 77, 93, 98, 82, 91, 86,
-  95, 89, 89, 87, 81, 89, 83, 75, 105, 90,
-  85, 75, 84, 83, 71, 81, 91, 93, 78, 76,
-  81, 98, 81, 94, 81, 85, 85, 77, 88, 86,
-  72, 94, 75, 82, 89, 79, 79, 77, 84, 83,
-  76, 73, 80, 92, 65, 88, 82, 93, 81, 95,
-  87, 90, 86, 85, 86, 89, 76, 99, 83, 67,
-  86, 73, 101, 89, 89, 87, 63, 81, 97, 73,
-  88, 79, 74, 85, 95, 77, 82, 92, 92, 93,
-  83, 98, 80, 71, 90, 77, 102, 72, 65, 68,
-  95, 82, 111, 87, 62, 83, 76, 84, 86, 90,
-  83, 71, 91, 89, 88, 86, 86, 69, 78, 78,
-  80, 81, 60, 82, 82, 83, 78, 99, 73, 95,
-  83, 111, 75, 106, 80, 71, 93, 80, 89, 85,
-  80, 87, 91, 92, 79, 132, 87, 82, 63, 77,
-  92, 69, 74, 79, 90, 104, 75, 77, 79, 86,
-  88, 78, 95, 78, 96, 79, 85, 73, 68, 69,
-  73, 88, 94, 94, 88, 79, 74, 77, 77, 82,
-  78, 85, 81, 88, 100, 86, 75, 80, 86, 104,
-  69, 85, 70, 83, 84, 85, 84, 102, 76, 76,
-  111, 88, 82, 86, 50, 97, 111, 85, 76, 71,
-  90, 76, 119, 71, 89, 123, 79, 73, 85, 95,
-  86, 62, 83, 77, 119, 108, 61, 66, 85, 98,
-  100, 76, 80, 84, 73, 43, 85, 95, 69, 64,
-  119, 68, 84, 84, 84, 34, 87, 50, 59, 79,
-  43, 85, 105, 80, 88, 110, 75, 83, 86, 117,
-  72, 97, 79, 73, 82, 80, 75, 79, 81, 73,
-  94, 90, 95, 91, 84, 74, 46, 85, 74, 70,
-  76, 83, 82, 106, 31, 74, 72, 87, 94, 71,
-  112, 89, 101, 82, 79, 78, 74, 93, 88, 93,
-  101, 88, 126, 99, 70, 63, 69, 76, 79, 82,
-  107, 82, 86, 80, 69, 79, 88, 120, 59, 101,
-  48, 80, 95, 64, 80, 103, 101, 74, 78, 92,
-  86, 80, 65, 81, 83, 81, 90, 78, 81, 80,
-  91, 80, 80, 87, 84, 92, 83, 97, 87, 69,
-  92, 82, 101, 105, 65, 80, 92, 76, 84, 102,
-  89, 85, 95, 89, 87, 87, 89, 65, 91, 88,
-  86, 123, 93, 76, 69, 87, 78, 84, 80, 72,
-  72, 59, 79, 96, 84, 91, 75, 87, 68, 105,
-  71, 72, 88, 80, 88, 91, 87, 87, 85, 91,
-  80, 66, 84, 85, 69, 69, 92, 97, 65, 81,
-  87, 101, 69, 67, 82, 93, 94, 83, 78, 73,
-  97, 72, 86, 79, 72, 92, 72, 89, 90, 85,
-  86, 82, 64, 85, 88, 77, 81, 92, 60, 83,
-  87, 90, 77, 82, 96, 96, 72, 85, 58, 86,
-  84, 94, 75, 76, 84, 88, 83, 79, 90, 89,
-  85, 86, 77, 72, 85, 70, 80, 90, 74, 93,
-  83, 86, 87, 75, 82, 95, 74, 83, 94, 81,
-  76, 87, 70, 78, 103, 73, 95, 84, 76, 92,
-  87, 96, 83, 78, 98, 83, 76, 89, 99, 87,
-  82, 78, 90, 98, 94, 84, 80, 97, 82, 87,
-  71, 78, 83, 75, 100, 92, 78, 82, 83, 78,
-  85, 82, 101, 85, 94, 84, 97, 86, 80, 81,
-  99, 74, 83, 94, 91, 77, 84, 81, 87, 97,
-  94, 94, 79, 102, 85, 74, 87, 67, 88, 75,
-  92, 65, 71, 88, 77, 82, 83, 80, 75, 69,
-  81, 77, 84, 86, 81, 84, 81, 82, 63, 92,
-  83, 84, 77, 87, 83, 83, 81, 86, 80, 84,
-  77, 75, 94, 82, 77, 80, 90, 91, 83, 89,
-  85, 70, 77, 89, 89, 89, 80, 90, 81, 88,
-  86, 69, 83, 93, 75, 72, 96, 80, 91, 101,
-  67, 75, 107, 80, 90, 72, 82, 96, 81, 82,
-  90, 77, 84, 74, 78, 86, 100, 68, 83, 64,
-  91, 105, 89, 81, 68, 99, 83, 86, 83, 74,
-  76, 60, 113, 87, 73, 88, 82, 66, 85, 82,
-  98, 87, 93, 74, 89, 77, 87, 67, 100, 63,
-  75, 104, 85, 78, 86, 88, 81, 99, 105, 106,
-  81, 93, 88, 64, 95, 64, 93, 76, 87, 69,
-  73, 75, 76, 83, 83, 87, 87, 78, 82, 70,
-  91, 76, 74, 76, 108, 91, 70, 88, 76, 88,
-  90, 93, 80, 87, 65, 90, 81, 84, 69, 71,
-  110, 85, 80, 77, 88, 87, 84, 85, 77, 68,
-  86, 91, 85, 87, 75, 90, 75, 84, 87, 84,
-  84, 100, 83, 82, 91, 83, 72, 99, 74, 76,
-  97, 67, 81, 83, 87, 89, 69, 99, 83, 78,
-  89, 79, 77, 90, 96, 80, 89, 79, 81, 108,
-  97, 87, 83, 67, 72, 75, 68, 84, 85, 78,
-  89, 78, 76, 84, 82, 78, 84, 90, 70, 90,
-  89, 83, 92, 89, 76, 73, 83, 75, 85, 76,
-  94, 92, 86, 84, 79, 90, 85, 92, 83, 91,
-  87, 81, 73, 72, 86, 73, 82, 71, 75, 65,
-  77, 81, 81, 80, 75, 81, 82, 81, 104, 83,
-  82, 79, 89, 89, 80, 97, 83, 79, 90, 81,
-  82, 85, 77, 89, 79, 86, 77, 76, 95, 85,
-  85, 86, 77, 83, 81, 87, 87, 63, 92, 100,
-  72, 83, 83, 78, 87, 87, 100, 76, 98, 90,
-  83, 78, 79, 82, 94, 93, 100, 78, 70, 79,
-  74, 91, 89, 84, 75, 84, 79, 81, 83, 80,
-  81, 83, 82, 75, 83, 87, 78, 65, 76, 85,
-  90, 87, 77, 75, 75, 89, 91, 89, 85, 80,
-  88, 78, 100, 85, 79, 97, 78, 85, 83, 97,
-  85, 70, 69, 85, 70, 78, 82, 91, 73, 95,
-  73, 87, 83, 94, 83, 94, 79, 72, 72, 93,
-  73, 81, 91, 97, 93, 83, 83, 77, 85, 81,
-  88, 93, 98, 89, 85, 71, 74, 83, 78, 81,
-  77, 96, 105, 92, 73, 104, 93, 92, 81, 93,
-  86, 80, 79, 85, 88, 76, 81, 77, 82, 81,
-  77, 70, 78, 74, 79, 76, 105, 80, 80, 68,
-  97, 100, 102, 72, 106, 76, 81, 79, 83, 87,
-  84, 81, 96, 73, 129, 83, 68, 80, 81, 74,
-  89, 80, 78, 83, 63, 84, 104, 91, 75, 91,
-  83, 65, 68, 76, 78, 81, 78, 87, 89, 82,
-  77, 70, 63, 88, 107, 69, 81, 90, 85, 68,
-  90, 98, 61, 102, 87, 68, 70, 98, 76, 60,
-  64, 82, 82, 77, 82, 101, 79, 76, 80, 82,
-  83, 104, 84, 93, 77, 84, 67, 100, 76, 85,
-  93, 110, 78, 76, 70, 92, 78, 79, 83, 82,
-  114, 91, 85, 72, 88, 81, 76, 78, 79, 86,
-  69, 92, 79, 112, 87, 110, 80, 92, 82, 77,
-  92, 75, 80, 92, 81, 86, 86, 90, 72, 85,
-  81, 88, 82, 66, 77, 61, 77, 91, 92, 80,
-  83, 89, 92, 80, 76, 86, 87, 78, 80, 84,
-  83, 74, 99, 81, 78, 84, 96, 84, 95, 87,
-  76, 78, 78, 83, 94, 78, 82, 100, 93, 95,
-  82, 88, 80, 85, 73, 84, 87, 77, 77, 76,
-  75, 85, 87, 86, 85, 78, 91, 77, 77, 89,
-  83, 82, 96, 83, 92, 90, 88, 77, 71, 84,
-  89, 84, 80, 86, 76, 85, 76, 72, 91, 91,
-  83, 94, 78, 100, 76, 98, 93, 83, 97, 98,
-  70, 83, 78, 97, 87, 78, 84, 89, 89, 87,
-  82, 68, 83, 80, 76, 87, 82, 92, 78, 92,
-  74, 98, 85, 90, 82, 96, 82, 76, 81, 85,
-  80, 79, 93, 93, 105, 96, 78, 68, 87, 82,
-  71, 74, 74, 70, 72, 86, 82, 71, 75, 85,
-  93, 73, 80, 94, 80, 74, 82, 78, 103, 69,
-  112, 90, 75, 107, 99, 105, 76, 98, 77, 87,
-  80, 96, 68, 86, 63, 87, 111, 98, 77, 83,
-  79, 79, 73, 87, 82, 98, 81, 70, 91, 94,
-  76, 101, 91, 77, 96, 68, 80, 90, 84, 83,
-  98, 98, 77, 86, 85, 62, 70, 105, 77, 74,
-  86, 74, 86, 79, 77, 81, 95, 90, 85, 87,
-  71, 90, 84, 85, 65, 70, 97, 85, 95, 81,
-  71, 84, 83, 78, 91, 75, 102, 92, 79, 70,
-  82, 84, 73, 90, 82, 95, 70, 95, 80, 74,
-  83, 71, 75, 92, 83, 81, 72, 69, 72, 80,
-  95, 107, 118, 83, 86, 55, 87, 75, 57, 83,
-  109, 77, 94, 74, 97, 84, 78, 76, 82, 69,
-  76, 85, 88, 70, 73, 86, 109, 82, 147, 85,
-  85, 95, 78, 76, 68, 96, 87, 92, 69, 112,
-  84, 110, 56, 76, 138, 83, 40, 84, 91, 86,
-  67, 97, 67, 96, 70, 70, 92, 113, 84, 74,
-  74, 97, 73, 68, 89, 121, 68, 72, 71, 89,
-  60, 74, 88, 51, 82, 89, 61, 66, 87, 78,
-  91, 86, 90, 89, 89, 85, 84, 82, 76, 77,
-  80, 87, 53, 68, 96, 106, 108, 67, 58, 90,
-  75, 77, 97, 71, 129, 98, 76, 72, 88, 105,
-  77, 89, 82, 93, 64, 108, 124, 67, 86, 83,
-  62, 105, 82, 76, 84, 60, 82, 91, 101, 92,
-  100, 84, 72, 69, 87, 82, 73, 77, 78, 86,
-  73, 86, 85, 68, 76, 91, 80, 75, 91, 92,
-  77, 71, 77, 77, 91, 104, 106, 77, 80, 86,
-  81, 93, 80, 100, 70, 79, 87, 94, 92, 82,
-  68, 87, 108, 109, 77, 84, 78, 88, 72, 84,
-  77, 94, 81, 74, 83, 85, 76, 108, 97, 79,
-  91, 71, 88, 89, 81, 81, 79, 96, 78, 84,
-  80, 65, 70, 89, 66, 81, 86, 72, 79, 99,
-  79, 93, 91, 87, 85, 85, 74, 80, 85, 79,
-  73, 69, 103, 90, 85, 80, 76, 75, 85, 76,
-  83, 76, 90, 85, 82, 72, 81, 88, 76, 93,
-  91, 96, 109, 91, 77, 79, 83, 71, 75, 89,
-  85, 76, 71, 74, 81, 80, 85, 88, 76, 85,
-  80, 84, 82, 93, 69, 88, 83, 72, 72, 104,
-  81, 69, 92, 82, 81, 74, 83, 86, 82, 78,
-  87, 81, 84, 64, 77, 97, 74, 92, 80, 95,
-  98, 79, 76, 82, 91, 86, 92, 72, 71, 98,
-  75, 77, 95, 100, 72, 79, 76, 85, 75, 80,
-  85, 76, 83, 83, 69, 93, 114, 85, 86, 84,
-  80, 76, 84, 80, 88, 83, 106, 86, 66, 92,
-  75, 75, 109, 90, 77, 85, 88, 87, 80, 75,
-  84, 85, 80, 90, 90, 87, 78, 77, 78, 78,
-  90, 75, 63, 98, 91, 86, 91, 80, 79, 71,
-  71, 81, 84, 84, 82, 71, 84, 87, 94, 81,
-  63, 86, 82, 94, 84, 74, 78, 86, 88, 95,
-  75, 78, 86, 74, 82, 97, 76, 73, 86, 66,
-  82, 87, 61, 87, 89, 84, 79, 110, 78, 63,
-  74, 75, 78, 71, 83, 88, 76, 71, 91, 77,
-  90, 86, 69, 98, 73, 81, 77, 75, 104, 78,
-  78, 81, 105, 83, 73, 70, 67, 89, 82, 61,
-  97, 98, 82, 83, 68, 80, 71, 86, 78, 85,
-  99, 84, 55, 94, 121, 91, 87, 79, 90, 82,
-  80, 93, 86, 89, 104, 90, 69, 91, 67, 67,
-  96, 83, 78, 93, 68, 82, 77, 89, 84, 80,
-  83, 91, 81, 85, 89, 78, 75, 79, 83, 84,
-  85, 96, 87, 89, 85, 75, 100, 73, 72, 82,
-  75, 82, 75, 73, 76, 85, 101, 70, 79, 94,
-  87, 85, 88, 69, 70, 85, 95, 100, 59, 68,
-  84, 74, 83, 83, 72, 73, 80, 83, 79, 92,
-  74, 89, 85, 89, 69, 100, 84, 67, 91, 86,
-  99, 74, 87, 81, 73, 73, 86, 79, 76, 89,
-  72, 94, 77, 70, 68, 80, 93, 82, 82, 78,
-  95, 84, 74, 74, 70, 90, 69, 81, 95, 100,
-  74, 78, 75, 83, 78, 89, 83, 83, 84, 77,
-  68, 94, 115, 86, 89, 90, 89, 74, 84, 73,
-  74, 80, 105, 90, 69, 94, 73, 70, 96, 88,
-  78, 81, 77, 81, 82, 85, 85, 88, 82, 89,
-  94, 79, 78, 77, 86, 78, 90, 84, 87, 88,
-  94, 80, 91, 80, 83, 76, 68, 83, 86, 88,
-  83, 81, 88, 84, 93, 80, 109, 82, 76, 104,
-  102, 79, 78, 85, 88, 89, 77, 86, 87, 101,
-  75, 81, 97, 79, 75, 100, 81, 91, 74, 77,
-  77, 75, 73, 93, 92, 100, 94, 102, 77, 89,
-  89, 73, 93, 100, 86, 80, 84, 79, 75, 88,
-  86, 65, 71, 79, 82, 72, 101, 98, 90, 72,
-  68, 89, 78, 75, 78, 78, 85, 77, 77, 95,
-  89, 102, 104, 97, 109, 93, 84, 76, 78, 60,
-  85, 69, 68, 94, 99, 72, 98, 80, 69, 71,
-  102, 91, 81, 79, 65, 57, 77, 93, 95, 90,
-  86, 94, 85, 79, 79, 59, 103, 77, 90, 84,
-  77, 74, 93, 78, 83, 79, 86, 88, 54, 59,
-  88, 82, 84, 73, 85, 80, 86, 92, 75, 77,
-  92, 77, 70, 82, 85, 73, 78, 99, 81, 88,
-  95, 100, 97, 84, 86, 106, 86, 81, 94, 87,
-  88, 83, 75, 87, 88, 88, 83, 74, 91, 92,
-  63, 86, 83, 86, 74, 102, 86, 93, 97, 78,
-  86, 67, 88, 85, 88, 83, 77, 91, 88, 82,
-  75, 90, 84, 83, 89, 88, 86, 72, 71, 81,
-  75, 81, 86, 78, 80, 80, 74, 97, 91, 79,
-  86, 77, 89, 69, 80, 82, 99, 68, 86, 80,
-  64, 77, 90, 76, 85, 113, 70, 80, 100, 79,
-  79, 79, 83, 76, 74, 71, 90, 75, 68, 90,
-  82, 83, 85, 84, 59, 72, 95, 87, 82, 61,
-  90, 72, 89, 73, 81, 73, 76, 73, 95, 90,
-  84, 76, 85, 81, 68, 74, 78, 76, 76, 82,
-  84, 107, 102, 72, 79, 84, 92, 81, 81, 79,
-  94, 85, 81, 71, 94, 75, 90, 89, 90, 68,
-  73, 80, 90, 87, 87, 78, 104, 93, 70, 85,
-  90, 83, 77, 85, 97, 85, 77, 83, 83, 68,
-  82, 84, 84, 76, 98, 98, 89, 91, 80, 84,
-  86, 90, 77, 89, 80, 81, 73, 84, 78, 80,
-  87, 70, 81, 75, 71, 102, 94, 81, 79, 79,
-  81, 80, 84, 85, 104, 80, 76, 98, 78, 84,
-  80, 83, 79, 87, 77, 76, 88, 86, 82, 77,
-  79, 85, 99, 76, 83, 84, 75, 74, 81, 87,
-  88, 81, 78, 78, 97, 90, 95, 79, 92, 86,
-  93, 85, 82, 77, 89, 87, 94, 89, 87, 78,
-  75, 84, 75, 86, 91, 73, 74, 88, 89, 95,
-  88, 84, 79, 83, 98, 87, 87, 79, 93, 82,
-  83, 83, 81, 95, 87, 77, 81, 93, 67, 91,
-  76, 93, 77, 75, 68, 89, 70, 83, 84, 96,
-  86, 120, 69, 87, 99, 87, 100, 86, 101, 87,
-  95, 66, 67, 86, 104, 70, 113, 97, 84, 77,
-  82, 84, 80, 85, 69, 72, 74, 85, 83, 83,
-  78, 79, 81, 75, 88, 90, 97, 69, 98, 54,
-  78, 77, 80, 63, 88, 49, 60, 70, 96, 83,
-  89, 87, 65, 107, 89, 98, 85, 73, 68, 120,
-  68, 95, 84, 71, 96, 120, 74, 78, 84, 79,
-  81, 80, 114, 70, 79, 72, 93, 69, 88, 78,
-  74, 83, 64, 62, 97, 90, 84, 78, 87, 71,
-  92, 76, 80, 82, 75, 85, 44, 123, 85, 83,
-  73, 79, 82, 86, 100, 80, 80, 74, 80, 118,
-  75, 71, 75, 92, 88, 95, 86, 72, 78, 77,
-  87, 83, 100, 111, 76, 71, 77, 77, 71, 91,
-  84, 68, 65, 86, 95, 71, 83, 79, 90, 73,
-  100, 90, 87, 105, 113, 88, 97, 83, 72, 73,
-  100, 95, 97, 76, 59, 80, 107, 90, 71, 78,
-  91, 79, 86, 73, 71, 86, 61, 63, 84, 110,
-  90, 66, 82, 92, 67, 71, 78, 102, 82, 83,
-  67, 112, 59, 84, 90, 59, 84, 113, 85, 76,
-  82, 81, 78, 77, 95, 88, 95, 101, 63, 73,
-  87, 86, 107, 84, 77, 98, 84, 72, 88, 60,
-  86, 98, 100, 94, 85, 73, 93, 88, 78, 64,
-  80, 92, 55, 83, 91, 140, 67, 99, 103, 70,
-  95, 78, 79, 60, 87, 76, 85, 66, 82, 83,
-  83, 95, 84, 75, 81, 77, 86, 78, 89, 92,
-  85, 86, 83, 80, 89, 79, 80, 83, 81, 70,
-  77, 86, 82, 70, 81, 79, 82, 89, 101, 97,
-  92, 91, 84, 82, 82, 88, 76, 67, 94, 80,
-  86, 86, 67, 78, 97, 94, 72, 77, 87, 80,
-  94, 78, 74, 90, 68, 89, 89, 93, 95, 85,
-  80, 95, 92, 78, 83, 92, 81, 74, 75, 85,
-  74, 93, 83, 66, 75, 85, 86, 77, 83, 89,
-  86, 77, 80, 92, 83, 84, 98, 74, 91, 87,
-  108, 91, 79, 96, 83, 85, 80, 78, 86, 101,
-  96, 89, 75, 80, 87, 88, 85, 77, 86, 86,
-  63, 83, 101, 97, 76, 94, 87, 87, 95, 80,
-  87, 78, 86, 78, 81, 85, 82, 91, 84, 83,
-  92, 85, 77, 96, 79, 90, 81, 85, 75, 92,
-  68, 86, 79, 101, 84, 93, 78, 94, 78, 88,
-  93, 94, 93, 87, 94, 63, 72, 92, 104, 75,
-  113, 89, 75, 87, 78, 89, 95, 83, 92, 80,
-  94, 94, 82, 78, 83, 74, 76, 92, 87, 98,
-  101, 79, 92, 71, 74, 76, 78, 76, 89, 65,
-  68, 83, 73, 86, 83, 79, 78, 91, 91, 90,
-  82, 77, 73, 96, 83, 90, 90, 78, 95, 88,
-  81, 77, 82, 73, 87, 87, 98, 74, 83, 76,
-  97, 78, 82, 78, 63, 92, 77, 75, 99, 87,
-  76, 74, 73, 83, 92, 73, 83, 81, 78, 75,
-  69, 111, 55, 86, 88, 81, 74, 84, 95, 86,
-  88, 82, 78, 99, 75, 74, 66, 90, 93, 72,
-  86, 82, 80, 82, 80, 93, 100, 84, 68, 78,
-  72, 79, 72, 84, 80, 78, 65, 91, 92, 76,
-  99, 84, 89, 79, 81, 92, 97, 98, 98, 75,
-  78, 87, 78, 79, 101, 80, 95, 79, 70, 95,
-  89, 78, 83, 78, 80, 84, 86, 83, 87, 102,
-  71, 76, 80, 86, 84, 78, 89, 89, 78, 82,
-  70, 82, 87, 83, 80, 87, 84, 83, 81, 70,
-  77, 82, 98, 77, 82, 87, 82, 68, 77, 88,
-  82, 91, 81, 77, 99, 83, 108, 86, 81, 87,
-  85, 73, 76, 83, 82, 91, 95, 89, 81, 83,
-  73, 89, 93, 64, 83, 88, 71, 76, 96, 105,
-  62, 93, 95, 92, 86, 77, 83, 76, 90, 84,
-  79, 72, 81, 75, 73, 87, 85, 76, 83, 80,
-  83, 86, 86, 96, 92, 75, 76, 77, 82, 76,
-  74, 87, 81, 73, 88, 83, 81, 76, 92, 82,
-  85, 94, 80, 92, 93, 87, 90, 73, 70, 78,
-  84, 72, 89, 73, 88, 91, 79, 89, 74, 73,
-  82, 73, 83, 81, 93, 85, 84, 105, 85, 86,
-  85, 86, 81, 84, 80, 83, 95, 80, 78, 81,
-  90, 76, 81, 80, 86, 82, 80, 78, 75, 79,
-  84, 79, 82, 89, 82, 79, 75, 90, 82, 83,
-  94, 87, 106, 82, 101, 81, 82, 82, 81, 81,
-  77, 83, 79, 87, 89, 88, 85, 87, 80, 81,
-  104, 76, 83, 83, 75, 82, 100, 72, 106, 88,
-  81, 105, 94, 86, 87, 86, 84, 86, 81, 81,
-  93, 64, 63, 81, 96, 86, 83, 93, 81, 83,
-  94, 79, 70, 85, 89, 89, 96, 82, 90, 79,
-  44, 75, 60, 94, 71, 83, 79, 88, 87, 80,
-  87, 80, 82, 105, 84, 89, 76, 78, 75, 78,
-  76, 60, 93, 77, 75, 77, 89, 100, 81, 85,
-  88, 77, 83, 90, 71, 85, 75, 91, 73, 84,
-  100, 80, 71, 89, 68, 84, 80, 77, 103, 55,
-  91, 67, 90, 86, 77, 72, 90, 77, 102, 84,
-  83, 91, 90, 78, 82, 87, 89, 85, 93, 84,
-  77, 101, 76, 83, 86, 78, 91, 102, 83, 84,
-  72, 86, 80, 85, 84, 88, 72, 77, 73, 88,
-  83, 88, 85, 86, 78, 74, 90, 83, 74, 72,
-  76, 91, 74, 83, 68, 88, 91, 89, 90, 72,
-  80, 78, 73, 87, 81, 76, 84, 89, 88, 88,
-  84, 82, 97, 79, 83, 95, 81, 80, 67, 86,
-  72, 94, 75, 83, 80, 88, 78, 71, 87, 83,
-  87, 94, 89, 83, 88, 84, 82, 79, 79, 94,
-  88, 86, 89, 75, 76, 94, 88, 91, 83, 78,
-  82, 82, 81, 85, 89, 82, 83, 77, 94, 81,
-  76, 106, 76, 116, 79, 84, 86, 75, 75, 84,
-  88, 85, 79, 75, 93, 85, 91, 96, 85, 84,
-  81, 74, 89, 77, 73, 85, 90, 82, 72, 90,
-  87, 77, 78, 88, 82, 90, 80, 90, 84, 85,
-  80, 87, 86, 85, 76, 86, 75, 86, 96, 86,
-  92, 85, 79, 90, 80, 86, 83, 82, 72, 88,
-  61, 82, 78, 80, 94, 94, 88, 74, 103, 84,
-  72, 98, 80, 69, 82, 91, 73, 82, 93, 74,
-  92, 83, 70, 101, 74, 80, 84, 80, 92, 93,
-  86, 87, 81, 86, 76, 77, 84, 86, 83, 97,
-  93, 81, 92, 82, 90, 75, 85, 100, 87, 90,
-  92, 81, 81, 99, 88, 95, 78, 83, 88, 77,
-  79, 82, 95, 79, 78, 80, 91, 81, 83, 100,
-  100, 95, 72, 88, 80, 95, 76, 87, 84, 87,
-  78, 87, 93, 88, 84, 84, 83, 82, 84, 82,
-  85, 69, 75, 93, 89, 81, 80, 97, 93, 73,
-  85, 89, 68, 73, 88, 87, 92, 80, 75, 84,
-  86, 78, 88, 90, 78, 93, 100, 92, 88, 84,
-  79, 92, 96, 92, 92, 87, 80, 89, 68, 79,
-  89, 85, 82, 89, 83, 73, 61, 85, 102, 75,
-  81, 92, 78, 81, 88, 78, 68, 87, 80, 98,
-  101, 76, 82, 83, 66, 85, 64, 96, 75, 71,
-  90, 86, 108, 80, 85, 86, 85, 104, 84, 85,
-  80, 76, 83, 70, 73, 51, 87, 88, 67, 103,
-  97, 98, 84, 78, 76, 93, 90, 89, 94, 89,
-  68, 85, 87, 84, 97, 76, 83, 80, 57, 55,
-  83, 79, 114, 63, 119, 61, 80, 92, 85, 78,
-  80, 79, 116, 65, 84, 92, 90, 79, 83, 86,
-  95, 86, 80, 86, 83, 107, 71, 79, 82, 67,
-  82, 86, 110, 87, 74, 102, 87, 84, 83, 81,
-  78, 76, 77, 73, 73, 91, 72, 88, 82, 79,
-  79, 85, 80, 70, 77, 88, 102, 83, 81, 92,
-  86, 76, 86, 72, 67, 86, 91, 72, 82, 95,
-  76, 89, 94, 82, 79, 89, 96, 86, 99, 86,
-  92, 79, 75, 84, 62, 93, 71, 85, 81, 89,
-  90, 67, 87, 82, 87, 94, 80, 86, 80, 84,
-  72, 79, 79, 74, 87, 80, 88, 79, 74, 95,
-  88, 83, 87, 84, 81, 91, 89, 71, 78, 87,
-  80, 77, 92, 81, 88, 80, 64, 89, 81, 83,
-  96, 71, 87, 70, 85, 89, 79, 72, 82, 81,
-  94, 93, 86, 86, 81, 75, 91, 75, 88, 85,
-  79, 92, 73, 89, 74, 92, 86, 86, 92, 94,
-  90, 84, 77, 98, 84, 85, 77, 71, 75, 78,
-  76, 81, 84, 81, 87, 89, 81, 85, 74, 84,
-  78, 72, 74, 89, 78, 90, 75, 77, 97, 88,
-  90, 65, 83, 79, 82, 78, 86, 87, 73, 86,
-  84, 80, 87, 87, 95, 74, 79, 93, 83, 74,
-  85, 82, 80, 96, 73, 89, 83, 87, 75, 75,
-  86, 79, 86, 94, 90, 77, 82, 82, 82, 82,
-  81, 100, 84, 83, 100, 78, 75, 95, 88, 90,
-  84, 84, 82, 88, 80, 77, 84, 86, 75, 75,
-  88, 89, 86, 96, 82, 103, 77, 86, 83, 78,
-  74, 81, 88, 82, 79, 78, 85, 75, 81, 99,
-  82, 84, 80, 78, 96, 62, 84, 86, 79, 85,
-  76, 98, 81, 86, 79, 88, 81, 95, 90, 90,
-  82, 92, 78, 87, 84, 72, 80, 85, 81, 86,
-  89, 88, 86, 85, 85, 87, 80, 89, 87, 78,
-  74, 86, 62, 87, 81, 75, 88, 89, 75, 79,
-  66, 83, 88, 76, 80, 78, 100, 79, 74, 87,
-  83, 89, 68, 96, 101, 76, 77, 91, 94, 93,
-  94, 91, 77, 69, 98, 71, 122, 73, 91, 85,
-  85, 101, 86, 83, 97, 88, 88, 68, 75, 60,
-  88, 99, 69, 122, 94, 110, 74, 86, 83, 103,
-  94, 78, 104, 106, 87, 67, 126, 93, 92, 72,
-  80, 58, 67, 47, 79, 97, 101, 80, 110, 80,
-  80, 92, 78, 85, 89, 85, 108, 70, 84, 84,
-  94, 83, 78, 96, 96, 84, 81, 84, 99, 101,
-  88, 76, 89, 75, 74, 84, 136, 93, 85, 87,
-  92, 84, 97, 93, 83, 87, 79, 68, 73, 86,
-  65, 94, 86, 97, 87, 105, 86, 78, 81, 88,
-  106, 70, 95, 88, 86, 75, 70, 74, 55, 84,
-  96, 75, 78, 88, 83, 80, 91, 86, 86, 85,
-  75, 91, 99, 84, 87, 88, 87, 79, 82, 89,
-  73, 78, 90, 82, 87, 62, 84, 84, 84, 95,
-  71, 94, 93, 78, 89, 80, 74, 71, 92, 82,
-  76, 90, 79, 104, 79, 79, 81, 86, 84, 96,
-  88, 89, 80, 73, 98, 87, 95, 72, 86, 47,
-  69, 61, 81, 80, 88, 77, 118, 77, 82, 92,
-  78, 77, 79, 84, 109, 91, 90, 82, 83, 75,
-  83, 87, 93, 86, 86, 85, 85, 92, 77, 79,
-  75, 80, 91, 83, 108, 81, 74, 102, 87, 81,
-  80, 81, 77, 81, 74, 69, 74, 77, 69, 100,
-  80, 91, 86, 85, 76, 74, 84, 86, 100, 75,
-  81, 86, 85, 78, 76, 62, 63, 84, 91, 68,
-  86, 93, 79, 82, 92, 87, 88, 91, 82, 87,
-  93, 91, 93, 81, 81, 79, 74, 97, 69, 83,
-  89, 86, 82, 58, 82, 84, 85, 95, 82, 79,
-  94, 82, 73, 100, 77, 83, 90, 76, 85, 75,
-  74, 94, 82, 87, 81, 83, 80, 103, 75, 81,
-  82, 79, 84, 82, 92, 83, 89, 66, 77, 84,
-  83, 80, 92, 84, 89, 74, 86, 86, 74, 74,
-  77, 73, 102, 97, 87, 81, 80, 74, 85, 76,
-  95, 85, 77, 89, 80, 106, 71, 83, 78, 88,
-  96, 94, 102, 84, 77, 96, 84, 83, 81, 65,
-  78, 84, 72, 77, 78, 78, 80, 97, 78, 86,
-  71, 88, 79, 72, 75, 89, 77, 85, 85, 83,
-  89, 83, 68, 51, 93, 76, 52, 75, 76, 76,
-  96, 80, 57, 101, 93, 76, 82, 66, 82, 71,
-  74, 90, 83, 91, 90, 81, 92, 85, 104, 94,
-  96, 95, 90, 76, 101, 88, 94, 98, 61, 78,
-  74, 67, 77, 85, 85, 52, 71, 53, 91, 77,
-  95, 108, 61, 66, 78, 82, 59, 71, 79, 66,
-  78, 99, 120, 98, 84, 94, 87, 47, 127, 166,
-  82, 74, 74, 123, 73, 79, 67, 75, 127, 80,
-  98, 85, 75, 68, 85, 114, 80, 92, 81, 93,
-  67, 75, 84, 94, 84, 100, 84, 62, 71, 103,
-  83, 83, 55, 85, 114, 86, 77, 70, 87, 60,
-  87, 82, 86, 84, 73, 89, 71, 89, 68, 74,
-  86, 72, 87, 133, 78, 74, 35, 84, 74, 114,
-  71, 66, 68, 82, 68, 72, 81, 77, 88, 85,
-  66, 96, 90, 68, 85, 72, 91, 77, 67, 85,
-  86, 82, 79, 85, 87, 86, 95, 91, 107, 96,
-  86, 85, 95, 88, 81, 101, 70, 80, 80, 66,
-  87, 94, 88, 60, 80, 69, 92, 96, 92, 97,
-  69, 57, 83, 83, 64, 73, 72, 73, 74, 94,
-  112, 90, 82, 87, 90, 52, 96, 153, 91, 71,
-  86, 121, 72, 79, 73, 73, 121, 66, 101, 79,
-  79, 68, 84, 95, 77, 88, 82, 91, 66, 73,
-  81, 104, 86, 99, 92, 71, 79, 102, 93, 73,
-  58, 113, 106, 91, 76, 73, 88, 68, 85, 69,
-  83, 85, 72, 86, 75, 89, 72, 74, 86, 67,
-  93, 105, 83, 73, 43, 84, 79, 95, 79, 89,
-  77, 80, 89, 105, 93, 87, 90, 83, 83, 81,
-  86, 77, 74, 86, 89, 100, 93, 83, 91, 76,
-  78, 91, 76, 88, 72, 91, 85, 81, 84, 79,
-  79, 78, 80, 96, 80, 78, 78, 81, 71, 86,
-  89, 97, 83, 86, 82, 68, 86, 82, 83, 92,
-  95, 86, 95, 83, 89, 71, 81, 70, 84, 85,
-  80, 64, 96, 75, 79, 72, 91, 78, 93, 77,
-  91, 80, 80, 88, 76, 83, 90, 106, 101, 86,
-  83, 85, 79, 74, 95, 76, 104, 74, 90, 83,
-  86, 85, 101, 92, 93, 71, 84, 85, 65, 74,
-  72, 82, 82, 80, 83, 86, 85, 95, 80, 76,
-  85, 83, 70, 83, 94, 86, 83, 83, 96, 86,
-  88, 94, 91, 87, 96, 82, 89, 64, 75, 82,
-  82, 75, 94, 86, 88, 84, 76, 80, 96, 77,
-  83, 72, 67, 77, 82, 83, 86, 105, 68, 91,
-  88, 77, 106, 88, 89, 81, 90, 85, 92, 94,
-  111, 90, 74, 81, 73, 81, 92, 84, 95, 72,
-  85, 72, 82, 67, 84, 82, 75, 86, 88, 88,
-  80, 81, 62, 78, 72, 79, 87, 94, 91, 95,
-  91, 62, 77, 110, 71, 70, 84, 110, 86, 77,
-  76, 77, 95, 80, 79, 76, 79, 72, 90, 84,
-  66, 86, 88, 82, 81, 88, 84, 79, 86, 74,
-  84, 73, 69, 94, 79, 86, 53, 84, 88, 80,
-  84, 72, 89, 81, 91, 70, 82, 79, 75, 86,
-  73, 80, 75, 75, 80, 84, 76, 82, 91, 75,
-  65, 83, 68, 79, 91, 79, 70, 85, 88, 67,
-  95, 83, 82, 87, 82, 78, 101, 74, 87, 79,
-  69, 85, 79, 80, 90, 103, 79, 92, 81, 78,
-  93, 87, 93, 109, 90, 84, 89, 79, 73, 87,
-  77, 79, 94, 85, 94, 85, 85, 79, 89, 76,
-  87, 75, 84, 77, 76, 82, 88, 88, 85, 70,
-  64, 83, 75, 74, 82, 82, 91, 84, 85, 71,
-  68, 89, 67, 78, 84, 103, 85, 78, 77, 73,
-  87, 71, 71, 71, 81, 78, 91, 90, 64, 93,
-  76, 82, 86, 86, 77, 74, 90, 75, 79, 74,
-  79, 88, 83, 82, 55, 72, 83, 85, 81, 74,
-  86, 88, 84, 66, 83, 83, 80, 80, 84, 89,
-  97, 75, 83, 81, 89, 66, 90, 75, 66, 85,
-  75, 74, 86, 88, 81, 76, 87, 88, 88, 87,
-  93, 81, 93, 76, 90, 78, 82, 80, 81, 91,
-  90, 85, 90, 84, 84, 84, 73, 87, 69, 84,
-  83, 85, 85, 81, 82, 77, 79, 90, 81, 93,
-  95, 81, 75, 81, 87, 97, 83, 80, 78, 76,
-  88, 78, 82, 86, 91, 93, 95, 91, 90, 78,
-  81, 81, 76, 79, 79, 72, 92, 80, 80, 72,
-  85, 78, 93, 80, 86, 81, 85, 84, 73, 82,
-  76, 94, 96, 97, 80, 81, 79, 82, 88, 77,
-  102, 84, 85, 72, 79, 82, 89, 92, 89, 75,
-  75, 85, 72, 66, 72, 80, 91, 79, 81, 95,
-  90, 86, 75, 81, 87, 78, 82, 84, 93, 85,
-  82, 78, 86, 79, 88, 88, 96, 84, 87, 77,
-  94, 88, 89, 75, 111, 91, 92, 86, 86, 83,
-  90, 78, 93, 78, 75, 83, 76, 84, 93, 101,
-  87, 104, 74, 93, 77, 78, 77, 87, 85, 70,
-  90, 89, 88, 93, 76, 73, 79, 90, 74, 93,
-  91, 68, 71, 100, 86, 89, 79, 82, 77, 71,
-  91, 110, 90, 93, 88, 94, 84, 92, 94, 69,
-  74, 80, 68, 85, 99, 90, 84, 82, 77, 83,
-  89, 58, 93, 79, 79, 88, 70, 73, 88, 78,
-  96, 95, 65, 76, 80, 91, 88, 70, 80, 90,
-  87, 83, 89, 78, 84, 80, 84, 78, 86, 88,
-  76, 97, 68, 76, 92, 100, 91, 90, 90, 89,
-  77, 75, 82, 89, 94, 78, 84, 84, 82, 84,
-  83, 81, 84, 90, 119, 92, 81, 71, 89, 96,
-  85, 75, 105, 75, 92, 86, 85, 85, 92, 78,
-  99, 83, 86, 86, 77, 88, 92, 96, 72, 103,
-  80, 92, 84, 78, 82, 85, 81, 90, 88, 92,
-  86, 80, 73, 78, 85, 87, 93, 98, 92, 73,
-  80, 95, 83, 84, 88, 68, 72, 77, 90, 105,
-  90, 91, 88, 81, 88, 91, 96, 77, 73, 83,
-  70, 86, 93, 98, 82, 77, 82, 90, 88, 63,
-  95, 75, 81, 84, 74, 81, 76, 72, 95, 96,
-  77, 92, 79, 94, 78, 69, 84, 91, 83, 79,
-  88, 82, 77, 79, 88, 77, 82, 87, 79, 95,
-  70, 79, 86, 93, 84, 88, 89, 90, 80, 76,
-  85, 84, 100, 82, 103, 84, 89, 83, 83, 82,
-  79, 88, 111, 93, 85, 77, 88, 92, 92, 78,
-  86, 83, 83, 87, 82, 89, 91, 76, 88, 87,
-  85, 82, 83, 84, 85, 90, 82, 80, 87, 91,
-  81, 86, 72, 80, 79, 92, 82, 88, 83, 77,
-  82, 79, 86, 89, 99, 74, 87, 76, 84, 96,
-  88, 88, 78, 76, 76, 75, 89, 90, 88, 85,
-  89, 93, 96, 92, 83, 87, 81, 79, 74, 85,
-  96, 85, 81, 84, 82, 86, 87, 71, 83, 81,
-  88, 85, 75, 82, 81, 90, 94, 101, 77, 79,
-  81, 91, 85, 72, 91, 96, 86, 79, 87, 85,
-  81, 92, 93, 80, 74, 78, 88, 82, 78, 76,
-  90, 80, 82, 82, 85, 91, 80, 77, 87, 81,
-  90, 83, 100, 90, 83, 84, 90, 77, 68, 98,
-  104, 85, 82, 84, 85, 89, 77, 84, 79, 95,
-  97, 78, 79, 81, 84, 78, 93, 86, 76, 96,
-  76, 100, 101, 94, 83, 102, 79, 74, 83, 102,
-  71, 80, 92, 78, 79, 86, 84, 84, 75, 81,
-  77, 94, 97, 92, 85, 79, 91, 83, 62, 94,
-  83, 83, 85, 83, 81, 80, 80, 77, 95, 76,
-  86, 74, 86, 88, 96, 82, 81, 84, 73, 82,
-  96, 83, 75, 85, 84, 91, 85, 68, 87, 93,
-  87, 76, 74, 86, 85, 83, 87, 80, 86, 100,
-  85, 72, 76, 80, 108, 97, 90, 92, 82, 86,
-  88, 73, 89, 89, 84, 71, 90, 80, 83, 86,
-  87, 86, 77, 85, 84, 79, 91, 90, 68, 99,
-  72, 86, 96, 91, 75, 78, 97, 73, 82, 81,
-  98, 77, 58, 92, 74, 79, 74, 79, 81, 83,
-  93, 81, 78, 82, 87, 74, 65, 97, 76, 99,
-  92, 96, 93, 81, 88, 76, 77, 89, 78, 80,
-  85, 69, 69, 86, 74, 87, 71, 82, 69, 100,
-  75, 74, 105, 61, 78, 87, 72, 94, 70, 72,
-  77, 82, 79, 81, 81, 68, 88, 63, 79, 60,
-  92, 89, 105, 79, 86, 75, 74, 62, 84, 82,
-  70, 105, 74, 73, 100, 74, 82, 95, 84, 84,
-  77, 62, 82, 88, 75, 90, 74, 98, 91, 66,
-  69, 80, 109, 114, 95, 82, 104, 74, 84, 80,
-  72, 90, 103, 87, 72, 83, 65, 83, 72, 86,
-  68, 91, 79, 76, 88, 92, 67, 86, 77, 75,
-  78, 84, 85, 76, 83, 66, 83, 85, 96, 70,
-  85, 82, 86, 78, 78, 77, 95, 84, 78, 85,
-  83, 78, 88, 91, 84, 96, 77, 98, 96, 101,
-  97, 97, 96, 77, 83, 103, 77, 80, 82, 72,
-  88, 85, 84, 93, 76, 85, 83, 99, 80, 92,
-  90, 85, 76, 85, 59, 93, 81, 80, 87, 82,
-  74, 84, 78, 73, 94, 73, 80, 73, 87, 85,
-  89, 77, 78, 84, 66, 86, 88, 79, 86, 75,
-  79, 83, 89, 74, 88, 90, 88, 81, 91, 86,
-  80, 83, 91, 83, 83, 92, 92, 81, 84, 79,
-  112, 86, 91, 90, 84, 84, 91, 79, 91, 94,
-  84, 84, 90, 80, 78, 82, 77, 84, 76, 83,
-  91, 79, 90, 84, 76, 90, 80, 83, 96, 88,
-  82, 75, 94, 74, 83, 83, 99, 84, 99, 78,
-  82, 87, 74, 80, 72, 73, 75, 83, 80, 70,
-  75, 77, 79, 92, 77, 83, 85, 100, 78, 96,
-  105, 78, 84, 80, 81, 84, 94, 71, 90, 87,
-  78, 67, 87, 80, 90, 80, 108, 66, 88, 81,
-  80, 84, 89, 88, 88, 71, 80, 79, 91, 91,
-  90, 67, 84, 102, 82, 85, 95, 79, 88, 83,
-  93, 73, 71, 61, 87, 76, 76, 81, 87, 94,
-  86, 92, 85, 70, 98, 95, 67, 81, 90, 69,
-  79, 88, 62, 87, 80, 86, 89, 77, 80, 93,
-  86, 75, 92, 80, 87, 78, 83, 74, 90, 70,
-  97, 82, 78, 83, 87, 80, 76, 83, 71, 93,
-  85, 87, 84, 103, 76, 76, 62, 89, 94, 80,
-  72, 83, 82, 77, 75, 81, 157, 85, 90, 92,
-  68, 72, 74, 69, 87, 85, 80, 82, 127, 115,
-  79, 76, 88, 62, 94, 76, 70, 135, 78, 74,
-  81, 67, 88, 89, 95, 77, 111, 97, 83, 71,
-  93, 68, 106, 60, 123, 68, 68, 106, 82, 93,
-  113, 51, 96, 81, 67, 83, 97, 141, 89, 69,
-  96, 124, 58, 101, 113, 61, 98, 57, 103, 88,
-  42, 107, 76, 65, 66, 58, 88, 88, 47, 88,
-  82, 52, 105, 84, 72, 86, 93, 77, 78, 75,
-  60, 64, 71, 102, 139, 67, 58, 76, 89, 60,
-  69, 71, 105, 90, 89, 82, 86, 102, 113, 84,
-  79, 77, 71, 85, 92, 84, 96, 81, 98, 76,
-  109, 112, 62, 74, 64, 77, 97, 75, 72, 95,
-  101, 60, 75, 100, 87, 74, 82, 88, 79, 105,
-  71, 78, 81, 85, 76, 72, 68, 101, 78, 94,
-  82, 82, 80, 94, 82, 89, 89, 81, 75, 83,
-  84, 82, 87, 80, 95, 91, 76, 90, 80, 85,
-  99, 81, 70, 73, 93, 88, 81, 87, 86, 87,
-  84, 96, 85, 78, 88, 81, 93, 68, 92, 77,
-  75, 82, 90, 78, 85, 89, 95, 71, 64, 58,
-  73, 73, 84, 66, 75, 88, 83, 94, 86, 73,
-  88, 69, 85, 83, 88, 71, 84, 104, 65, 75,
-  91, 81, 91, 84, 81, 102, 91, 75, 89, 82,
-  90, 80, 81, 78, 89, 105, 92, 83, 78, 73,
-  78, 83, 77, 89, 83, 96, 85, 89, 87, 87,
-  86, 79, 67, 87, 79, 76, 80, 81, 83, 78,
-  81, 83, 88, 89, 81, 88, 70, 85, 80, 79,
-  82, 85, 76, 76, 74, 87, 82, 89, 82, 84,
-  85, 98, 69, 98, 85, 80, 83, 87, 98, 90,
-  91, 81, 92, 87, 73, 78, 101, 82, 74, 95,
-  73, 76, 92, 98, 84, 80, 75, 92, 88, 76,
-  81, 79, 108, 83, 90, 73, 77, 53, 83, 77,
-  87, 86, 74, 100, 91, 78, 83, 68, 82, 82,
-  91, 67, 78, 97, 93, 90, 87, 76, 95, 90,
-  86, 81, 87, 74, 84, 81, 70, 87, 89, 91,
-  84, 80, 89, 90, 82, 69, 93, 79, 73, 67,
-  70, 83, 85, 79, 88, 82, 86, 101, 91, 84,
-  67, 77, 85, 85, 76, 96, 87, 103, 71, 75,
-  78, 84, 83, 80, 86, 78, 84, 85, 75, 71,
-  111, 91, 84, 99, 63, 73, 77, 80, 99, 84,
-  84, 87, 120, 101, 81, 81, 98, 72, 87, 84,
-  73, 105, 78, 81, 73, 72, 112, 90, 88, 97,
-  75, 90, 87, 75, 97, 81, 81, 86, 106, 70,
-  92, 105, 76, 77, 83, 66, 82, 79, 76, 86,
-  114, 96, 95, 70, 69, 91, 67, 73, 90, 74,
-  66, 88, 98, 86, 72, 94, 83, 58, 93, 61,
-  84, 91, 83, 91, 69, 58, 88, 86, 83, 89,
-  91, 79, 83, 83, 74, 90, 84, 91, 97, 59,
-  66, 86, 86, 55, 85, 82, 80, 73, 76, 92,
-  85, 83, 93, 81, 66, 101, 80, 88, 61, 72,
-  80, 56, 75, 84, 76, 99, 86, 71, 70, 80,
-  79, 78, 89, 88, 90, 79, 63, 76, 79, 79,
-  67, 88, 77, 88, 84, 81, 92, 90, 76, 82,
-  82, 87, 78, 98, 84, 90, 88, 93, 89, 85,
-  89, 80, 74, 91, 96, 92, 86, 102, 85, 84,
-  73, 87, 85, 91, 82, 94, 87, 79, 94, 90,
-  78, 84, 78, 81, 80, 87, 86, 82, 99, 82,
-  97, 76, 86, 92, 83, 81, 84, 86, 76, 99,
-  98, 76, 74, 76, 86, 83, 88, 74, 72, 99,
-  94, 96, 80, 82, 85, 66, 85, 76, 87, 75,
-  84, 103, 76, 86, 90, 78, 78, 82, 90, 92,
-  85, 68, 87, 80, 80, 69, 93, 81, 85, 93,
-  94, 82, 86, 99, 79, 83, 64, 78, 66, 89,
-  78, 89, 71, 86, 104, 79, 76, 87, 84, 84,
-  92, 79, 80, 88, 83, 70, 86, 79, 81, 71,
-  83, 89, 98, 92, 78, 85, 86, 87, 88, 71,
-  78, 75, 79, 79, 74, 90, 78, 98, 91, 76,
-  74, 99, 89, 83, 91, 87, 90, 84, 82, 84,
-  78, 88, 92, 87, 78, 83, 85, 70, 92, 76,
-  83, 79, 81, 83, 81, 78, 101, 83, 83, 81,
-  80, 74, 101, 83, 78, 108, 91, 81, 77, 78,
-  92, 84, 83, 79, 71, 85, 83, 82, 89, 76,
-  71, 80, 85, 84, 88, 87, 87, 124, 81, 81,
-  79, 81, 81, 90, 79, 80, 83, 80, 76, 71,
-  81, 75, 80, 92, 82, 81, 102, 88, 75, 79,
-  84, 78, 100, 93, 82, 84, 76, 69, 81, 87,
-  84, 73, 90, 75, 80, 83, 95, 84, 78, 77,
-  79, 86, 78, 78, 82, 83, 71, 75, 86, 80,
-  94, 83, 78, 84, 88, 93, 82, 76, 75, 75,
-  80, 80, 79, 86, 81, 92, 85, 76, 76, 93,
-  87, 85, 87, 88, 87, 86, 79, 83, 79, 88,
-  89, 83, 73, 82, 86, 69, 84, 77, 84, 79,
-  84, 80, 83, 76, 98, 76, 79, 82, 79, 76,
-  103, 84, 72, 103, 90, 87, 80, 75, 91, 82,
-  83, 81, 73, 87, 80, 80, 88, 73, 74, 78,
-  87, 82, 92, 84, 88, 125, 81, 81, 83, 76,
-  82, 89, 82, 83, 83, 83, 73, 68, 84, 76,
-  79, 91, 80, 81, 103, 83, 76, 82, 85, 76,
-  102, 94, 86, 84, 76, 67, 85, 83, 81, 72,
-  81, 76, 80, 82, 84, 82, 73, 77, 77, 83,
-  76, 76, 92, 89, 78, 77, 91, 83, 91, 84,
-  82, 87, 86, 83, 88, 79, 80, 81, 79, 83,
-  75, 89, 86, 97, 89, 79, 75, 102, 91, 84,
-  83, 85, 89, 87, 82, 85, 85, 91, 87, 87,
-  76, 79, 85, 71, 79, 72, 80, 78, 83, 85,
-  85, 79, 101, 83, 81, 83, 83, 81, 99, 91,
-  83, 100, 92, 84, 77, 76, 93, 85, 87, 78,
-  76, 86, 89, 85, 86, 79, 75, 80, 86, 86,
-  90, 88, 89, 102, 79, 88, 85, 82, 89, 98,
-  80, 85, 83, 90, 81, 76, 84, 75, 84, 88,
-  77, 79, 101, 82, 79, 79, 85, 83, 99, 94,
-  85, 88, 77, 75, 80, 83, 87, 77, 79, 80,
-  84, 86, 81, 84, 78, 81, 74, 84, 80, 82,
-  81, 84, 80, 74, 67, 90, 115, 94, 65, 87,
-  88, 84, 88, 75, 84, 81, 87, 74, 84, 89,
-  74, 88, 87, 69, 85, 96, 84, 88, 95, 95,
-  88, 84, 88, 88, 82, 80, 91, 88, 81, 75,
-  78, 75, 87, 88, 85, 84, 86, 89, 76, 73,
-  100, 71, 78, 80, 69, 75, 91, 76, 71, 121,
-  89, 78, 86, 79, 82, 79, 79, 78, 81, 77,
-  88, 75, 103, 80, 74, 77, 80, 80, 91, 101,
-  82, 171, 84, 71, 87, 78, 81, 88, 70, 70,
-  83, 83, 76, 67, 84, 87, 79, 85, 88, 91,
-  84, 91, 72, 83, 82, 77, 90, 85, 74, 78,
-  85, 70, 95, 87, 67, 63, 85, 84, 83, 82,
-  90, 74, 85, 70, 78, 81, 78, 73, 75, 87,
-  74, 78, 69, 79, 116, 83, 62, 86, 90, 87,
-  81, 79, 81, 85, 90, 75, 86, 86, 78, 84,
-  81, 70, 93, 90, 83, 91, 97, 92, 89, 84,
-  89, 85, 86, 80, 84, 86, 77, 70, 78, 75,
-  80, 85, 87, 82, 94, 84, 80, 71, 100, 67,
-  77, 79, 65, 75, 91, 73, 64, 127, 86, 80,
-  88, 73, 79, 77, 81, 81, 85, 75, 79, 75,
-  99, 76, 80, 78, 81, 85, 92, 96, 82, 180,
-  90, 75, 95, 76, 82, 84, 75, 73, 88, 77,
-  71, 67, 83, 89, 77, 83, 88, 91, 84, 74,
-  72, 86, 81, 72, 92, 86, 82, 75, 84, 66,
-  103, 80, 65, 64, 75, 87, 83, 82, 79, 75,
-  83, 70, 75, 78, 75, 72, 89, 89, 85, 79,
-  75, 86, 105, 83, 67, 89, 85, 81, 87, 82,
-  85, 87, 88, 77, 87, 84, 84, 92, 91, 77,
-  84, 96, 86, 88, 86, 85, 90, 85, 89, 82,
-  99, 86, 85, 87, 75, 73, 83, 77, 76, 80,
-  86, 83, 88, 80, 80, 75, 103, 76, 76, 79,
-  75, 80, 89, 84, 79, 106, 87, 81, 88, 75,
-  83, 82, 84, 75, 83, 85, 82, 78, 96, 80,
-  75, 76, 81, 92, 92, 100, 86, 142, 83, 84,
-  91, 83, 89, 90, 75, 79, 85, 81, 81, 69,
-  84, 86, 84, 82, 84, 89, 85, 69, 75, 82,
-  85, 83, 91, 87, 77, 84, 85, 75, 93, 81,
-  76, 75, 79, 85, 84, 87, 79, 77, 82, 74,
-  75, 80, 80, 79, 82, 77, 81, 82, 74, 90,
-  109, 96, 70, 89, 89, 78, 93, 72, 82, 83,
-  89, 72, 87, 88, 75, 90, 88, 76, 84, 91,
-  92, 89, 91, 92, 86, 77, 85, 87, 80, 79,
-  85, 90, 78, 80, 83, 74, 83, 84, 84, 88,
-  80, 87, 73, 75, 95, 74, 73, 80, 72, 76,
-  82, 79, 85, 107, 80, 78, 85, 78, 87, 84,
-  78, 73, 76, 84, 93, 80, 105, 85, 73, 77,
-  77, 82, 79, 98, 76, 139, 83, 74, 84, 81,
-  81, 91, 74, 71, 74, 89, 80, 70, 91, 83,
-  78, 82, 75, 90, 82, 94, 69, 84, 87, 83,
-  93, 76, 73, 83, 92, 76, 87, 89, 68, 68,
-  85, 84, 80, 78, 83, 79, 83, 74, 78, 89,
-  78, 80, 73, 80, 75, 83, 75, 82, 108, 90,
-  67, 89, 93, 81, 84, 79, 84, 88, 93, 72,
-  87, 83, 80, 86, 83, 76, 87, 85, 89, 92,
-  94, 85, 87, 78, 87, 87, 84, 77, 77, 92,
-  74, 76, 83, 72, 77, 86, 84, 86, 82, 85,
-  74, 74, 97, 72, 68, 80, 66, 78, 83, 76,
-  78, 109, 74, 78, 84, 74, 86, 79, 83, 74,
-  84, 84, 83, 79, 103, 84, 77, 81, 77, 85,
-  74, 96, 75, 150, 86, 78, 87, 81, 80, 87,
-  80, 72, 80, 85, 74, 73, 94, 87, 74, 82,
-  77, 91, 81, 81, 69, 85, 86, 81, 96, 77,
-  74, 79, 93, 70, 94, 81, 64, 75, 80, 84,
-  78, 74, 74, 80, 83, 74, 76, 86, 76, 77,
-  92, 85, 86, 84, 78, 89, 101, 87, 72, 90,
-  85, 79, 91, 85, 83, 87, 90, 71, 87, 84,
-  86, 96, 91, 80, 77, 89, 90, 87, 83, 78,
-  91, 81, 87, 83, 96, 88, 83, 91, 75, 78,
-  87, 75, 78, 80, 85, 86, 80, 83, 78, 77,
-  99, 80, 70, 81, 78, 81, 83, 87, 90, 96,
-  80, 81, 88, 76, 89, 87, 81, 75, 80, 91,
-  82, 79, 94, 83, 71, 78, 79, 88, 82, 98,
-  79, 119, 84, 83, 86, 87, 87, 91, 76, 76,
-  75, 80, 84, 72, 91, 81, 82, 80, 78, 87,
-  83, 73, 74, 82, 88, 88, 92, 80, 76, 83,
-  95, 80, 83, 81, 80, 82, 86, 85, 81, 83,
-  81, 82, 81, 75, 76, 90, 80, 85, 79, 83,
-  99, 85, 77, 94, 79, 72, 84, 100, 83, 80,
-  79, 72, 89, 92, 79, 96, 67, 82, 76, 85,
-  85, 97, 81, 77, 80, 78, 87, 91, 85, 92,
-  75, 86, 95, 94, 95, 88, 81, 93, 74, 91,
-  78, 76, 84, 69, 86, 67, 64, 84, 82, 78,
-  101, 76, 83, 83, 87, 86, 62, 97, 88, 96,
-  78, 83, 94, 83, 80, 82, 86, 92, 80, 93,
-  88, 93, 85, 87, 95, 97, 78, 86, 91, 84,
-  76, 85, 66, 90, 85, 69, 86, 76, 80, 84,
-  104, 90, 81, 77, 86, 75, 80, 78, 78, 97,
-  85, 87, 87, 91, 78, 85, 69, 109, 76, 93,
-  78, 88, 86, 91, 77, 68, 91, 85, 85, 85,
-  67, 81, 77, 98, 84, 79, 87, 79, 89, 89,
-  80, 85, 87, 70, 79, 108, 79, 78, 90, 76,
-  92, 81, 84, 103, 66, 72, 82, 78, 77, 93,
-  84, 81, 78, 71, 102, 89, 93, 83, 68, 91,
-  96, 82, 89, 81, 76, 95, 72, 96, 79, 83,
-  81, 74, 103, 77, 62, 83, 78, 79, 109, 68,
-  83, 84, 87, 81, 63, 94, 91, 96, 75, 94,
-  83, 79, 80, 84, 87, 90, 87, 93, 82, 90,
-  88, 83, 90, 87, 83, 84, 87, 84, 79, 78,
-  70, 78, 86, 76, 74, 89, 69, 80, 95, 97,
-  83, 84, 79, 73, 91, 65, 73, 89, 81, 85,
-  75, 86, 84, 82, 66, 102, 73, 95, 85, 88,
-  80, 92, 83, 73, 94, 75, 83, 86, 67, 85,
-  81, 105, 81, 72, 76, 75, 80, 90, 84, 88,
-  82, 72, 91, 100, 87, 77, 84, 79, 83, 91,
-  82, 97, 72, 77, 78, 83, 88, 96, 79, 75,
-  74, 83, 85, 91, 90, 82, 73, 95, 96, 79,
-  96, 93, 72, 90, 79, 93, 78, 78, 87, 76,
-  89, 94, 64, 81, 84, 80, 102, 82, 81, 86,
-  89, 82, 63, 98, 84, 93, 79, 85, 92, 82,
-  80, 86, 87, 88, 81, 93, 89, 85, 87, 93,
-  100, 88, 84, 85, 87, 83, 71, 76, 68, 80,
-  86, 77, 85, 76, 77, 94, 100, 96, 95, 79,
-  87, 75, 80, 76, 82, 92, 82, 85, 86, 91,
-  76, 88, 68, 97, 74, 92, 78, 93, 81, 88,
-  90, 69, 90, 81, 80, 85, 70, 82, 81, 93,
-  83, 82, 86, 79, 89, 73, 80, 94, 88, 76,
-  81, 96, 83, 77, 81, 76, 91, 90, 82, 91,
-  52, 82, 72, 79, 80, 97, 79, 85, 75, 69,
-  103, 88, 94, 94, 68, 91, 90, 98, 91, 73,
-  80, 83, 77, 88, 91, 77, 82, 71, 79, 72,
-  66, 73, 79, 80, 100, 70, 88, 80, 92, 86,
-  71, 105, 87, 92, 85, 79, 89, 71, 81, 82,
-  72, 89, 86, 93, 93, 95, 84, 89, 79, 83,
-  77, 81, 88, 83, 73, 88, 74, 90, 91, 74,
-  80, 77, 75, 84, 108, 95, 74, 83, 81, 79,
-  73, 63, 68, 98, 83, 93, 70, 86, 79, 86,
-  85, 115, 80, 84, 84, 81, 85, 88, 75, 67,
-  97, 80, 83, 82, 68, 93, 74, 88, 84, 69,
-  93, 79, 68, 75, 79, 74, 95, 73, 83, 108,
-  83, 77, 92, 75, 104, 91, 93, 96, 48, 70,
-  83, 69, 82, 92, 88, 87, 70, 66, 112, 91,
-  101, 78, 71, 91, 94, 82, 79, 63, 75, 93,
-  72, 86, 80, 76, 79, 68, 98, 72, 60, 84,
-  75, 73, 104, 64, 85, 73, 90, 88, 72, 110,
-  86, 88, 82, 93, 75, 71, 86, 96, 68, 78,
-  72, 99, 98, 96, 84, 94, 78, 81, 75, 81,
-  95, 81, 69, 84, 71, 84, 84, 78, 73, 95,
-  67, 75, 98, 91, 78, 87, 73, 78, 93, 47,
-  66, 85, 77, 91, 55, 80, 90, 80, 84, 134,
-  79, 89, 93, 85, 68, 92, 79, 68, 107, 70,
-  84, 82, 76, 109, 81, 89, 83, 69, 88, 76,
-  76, 79, 82, 75, 87, 73, 86, 96, 84, 75,
-  80, 86, 90, 92, 85, 89, 57, 80, 90, 79,
-  94, 92, 77, 80, 71, 74, 99, 97, 91, 82,
-  67, 88, 93, 86, 85, 78, 80, 85, 81, 86,
-  69, 78, 81, 73, 82, 85, 67, 71, 83, 80,
-  95, 74, 83, 83, 93, 83, 74, 103, 80, 92,
-  92, 79, 97, 76, 84, 92, 75, 88, 86, 92,
-  94, 82, 85, 89, 86, 92, 82, 81, 81, 78,
-  74, 80, 77, 86, 83, 80, 80, 81, 72, 81,
-  93, 95, 88, 86, 81, 80, 86, 63, 74, 88,
-  81, 90, 68, 91, 77, 89, 82, 104, 80, 89,
-  84, 99, 78, 90, 98, 67, 96, 77, 80, 81,
-  66, 86, 81, 87, 84, 72, 81, 84, 78, 70,
-  95, 91, 81, 74, 83, 89, 85, 78, 87, 81,
-  83, 83, 76, 90, 70, 86, 75, 85, 80, 102,
-  84, 83, 84, 73, 84, 89, 84, 95, 73, 90,
-  92, 93, 91, 70, 76, 91, 91, 79, 100, 83,
-  80, 80, 82, 76, 70, 82, 74, 82, 100, 79,
-  84, 86, 95, 80, 67, 93, 87, 99, 92, 84,
-  90, 78, 86, 81, 69, 84, 86, 87, 100, 102,
-  88, 83, 86, 85, 93, 74, 89, 83, 80, 88,
-  70, 88, 88, 76, 94, 78, 76, 91, 97, 94,
-  71, 89, 90, 73, 72, 66, 74, 98, 91, 90,
-  81, 80, 83, 93, 96, 112, 86, 93, 78, 78,
-  76, 89, 81, 67, 91, 92, 81, 82, 67, 88,
-  78, 91, 86, 82, 95, 79, 70, 67, 86, 75,
-  81, 69, 82, 100, 83, 74, 91, 78, 92, 85,
-  76, 90, 57, 79, 82, 77, 82, 97, 83, 84,
-  76, 69, 94, 95, 89, 89, 74, 93, 85, 84,
-  83, 57, 77, 94, 101, 76, 94, 80, 86, 72,
-  84, 79, 70, 87, 72, 78, 101, 71, 79, 83,
-  89, 82, 70, 99, 83, 88, 97, 95, 82, 77,
-  86, 85, 62, 82, 79, 94, 100, 107, 85, 86,
-  85, 83, 85, 70, 99, 76, 72, 85, 72, 88,
-  84, 82, 84, 86, 70, 80, 104, 89, 74, 90,
-  82, 75, 82, 52, 71, 98, 89, 89, 74, 79,
-  85, 84, 88, 123, 93, 94, 82, 83, 74, 87,
-  91, 72, 93, 83, 82, 82, 67, 100, 81, 90,
-  82, 75, 88, 76, 70, 74, 89, 82, 78, 71,
-  87, 91, 85, 78, 86, 80, 81, 84, 72, 86,
-  74, 86, 89, 85, 95, 99, 77, 74, 75, 75,
-  79, 104, 88, 97, 73, 84, 84, 84, 83, 69,
-  86, 92, 101, 77, 70, 80, 79, 79, 83, 89,
-  70, 83, 79, 91, 94, 83, 79, 78, 90, 81,
-  73, 88, 79, 98, 96, 85, 94, 82, 89, 87,
-  68, 84, 78, 86, 93, 93, 87, 87, 89, 87,
-  89, 70, 88, 78, 80, 77, 74, 89, 79, 85,
-  96, 81, 76, 78, 94, 86, 84, 82, 89, 72,
-  81, 66, 74, 98, 90, 87, 77, 85, 76, 94,
-  91, 107, 92, 88, 78, 91, 85, 90, 101, 65,
-  89, 87, 91, 84, 66, 83, 85, 90, 86, 82,
-  84, 82, 84, 79, 93, 86, 91, 77, 72, 83,
-  74, 104, 81, 92, 88, 94, 89, 75, 80, 86,
-  92, 74, 78, 85, 95, 73, 102, 75, 105, 86,
-  95, 69, 77, 95, 85, 99, 82, 69, 92, 87,
-  82, 76, 78, 88, 78, 97, 78, 80, 86, 79,
-  78, 75, 91, 76, 95, 94, 77, 77, 76, 91,
-  89, 90, 105, 75, 73, 67, 85, 83, 87, 75,
-  93, 81, 83, 92, 86, 67, 82, 83, 89, 74,
-  93, 90, 97, 76, 75, 112, 88, 75, 83, 87,
-  78, 84, 79, 97, 76, 74, 85, 82, 74, 84,
-  57, 92, 75, 72, 86, 72, 84, 80, 84, 68,
-  86, 94, 72, 81, 89, 94, 73, 90, 79, 76,
-  99, 77, 74, 68, 77, 77, 77, 89, 72, 83,
-  59, 81, 98, 77, 86, 68, 66, 76, 72, 88,
-  76, 103, 88, 95, 83, 84, 74, 76, 86, 71,
-  70, 82, 98, 80, 87, 67, 101, 92, 96, 68,
-  82, 98, 90, 76, 81, 68, 78, 92, 82, 73,
-  88, 89, 84, 86, 75, 87, 83, 84, 83, 82,
-  95, 95, 91, 86, 77, 74, 84, 92, 93, 93,
-  96, 81, 69, 74, 86, 87, 90, 68, 74, 65,
-  82, 81, 88, 76, 79, 82, 89, 78, 91, 94,
-  95, 68, 85, 110, 92, 69, 90, 94, 81, 85,
-  74, 103, 72, 84, 86, 94, 76, 87, 61, 82,
-  63, 74, 87, 71, 80, 75, 88, 75, 91, 89,
-  70, 80, 82, 78, 75, 87, 72, 83, 99, 75,
-  67, 58, 78, 67, 74, 93, 75, 84, 71, 95,
-  87, 80, 83, 70, 77, 79, 76, 94, 77, 101,
-  86, 88, 92, 85, 78, 80, 80, 83, 74, 74,
-  99, 84, 89, 73, 93, 94, 96, 76, 90, 91,
-  88, 74, 86, 82, 75, 86, 86, 90, 79, 96,
-  85, 81, 74, 100, 78, 84, 84, 84, 98, 98,
-  98, 82, 78, 75, 92, 79, 90, 90, 93, 76,
-  81, 82, 91, 87, 92, 83, 77, 72, 81, 76,
-  91, 74, 86, 76, 75, 82, 95, 92, 91, 76,
-  86, 107, 96, 80, 82, 91, 83, 88, 77, 104,
-  75, 89, 94, 94, 87, 97, 67, 82, 70, 77,
-  90, 78, 83, 81, 87, 72, 88, 89, 71, 74,
-  89, 79, 88, 84, 77, 76, 98, 78, 73, 63,
-  81, 63, 77, 92, 87, 85, 87, 84, 84, 86,
-  69, 86, 83, 94, 80, 97, 81, 69, 67, 89,
-  90, 77, 92, 97, 85, 80, 81, 85, 74, 67,
-  107, 95, 100, 78, 98, 74, 73, 88, 80, 100,
-  79, 71, 83, 77, 87, 69, 71, 73, 71, 90,
-  76, 85, 97, 79, 79, 73, 81, 72, 97, 88,
-  81, 76, 77, 87, 77, 88, 94, 76, 78, 67,
-  89, 85, 75, 93, 77, 78, 84, 99, 93, 83,
-  89, 78, 84, 68, 83, 77, 81, 81, 69, 92,
-  85, 80, 69, 74, 79, 92, 76, 88, 82, 73,
-  88, 76, 74, 84, 62, 122, 86, 79, 94, 85,
-  87, 91, 78, 74, 70, 81, 94, 86, 104, 96,
-  83, 96, 91, 63, 86, 84, 67, 91, 83, 92,
-  80, 85, 80, 86, 62, 76, 92, 79, 65, 73,
-  62, 82, 76, 85, 84, 78, 80, 95, 81, 78,
-  82, 81, 87, 66, 66, 86, 83, 65, 109, 78,
-  104, 76, 104, 71, 72, 88, 82, 92, 73, 61,
-  79, 80, 82, 64, 98, 76, 71, 107, 71, 86,
-  93, 80, 81, 74, 87, 74, 85, 96, 77, 71,
-  77, 87, 74, 92, 87, 75, 75, 60, 98, 81,
-  74, 67, 89, 68, 81, 104, 83, 73, 82, 85,
-  91, 75, 87, 87, 99, 75, 72, 95, 90, 64,
-  76, 82, 67, 89, 67, 105, 75, 74, 75, 80,
-  69, 81, 56, 110, 73, 77, 92, 79, 79, 78,
-  74, 75, 80, 89, 85, 82, 89, 88, 73, 87,
-  80, 73, 85, 86, 64, 71, 79, 91, 75, 87,
-  74, 86, 64, 89, 82, 74, 72, 69, 70, 83,
-  79, 86, 86, 91, 79, 100, 80, 83, 89, 83,
-  88, 76, 80, 91, 97, 72, 109, 76, 90, 85,
-  102, 73, 86, 93, 83, 88, 70, 69, 77, 82,
-  79, 76, 91, 84, 76, 90, 72, 89, 91, 86,
-  87, 77, 99, 80, 81, 86, 78, 73, 77, 85,
-  78, 89, 84, 74, 79, 65, 116, 79, 75, 78,
-  71, 72, 79, 89, 83, 75, 85, 90, 86, 81,
-  94, 91, 105, 89, 81, 93, 95, 71, 77, 90,
-  75, 82, 74, 107, 71, 79, 80, 80, 70, 87,
-  60, 80, 66, 79, 91, 75, 77, 82, 80, 79,
-  79, 93, 80, 85, 91, 87, 93, 82, 74, 72,
-  78, 82, 63, 62, 82, 85, 76, 89, 85, 88,
-  92, 79, 64, 87, 77, 90, 93, 77, 91, 90,
-  90, 61, 60, 70, 83, 86, 110, 97, 75, 97,
-  96, 82, 72, 83, 86, 106, 79, 78, 83, 86,
-  83, 79, 88, 106, 83, 84, 82, 87, 99, 72,
-  74, 86, 78, 87, 79, 77, 92, 81, 96, 84,
-  79, 78, 94, 77, 90, 94, 80, 84, 64, 72,
-  93, 85, 87, 98, 75, 94, 85, 97, 71, 92,
-  91, 87, 96, 102, 73, 77, 81, 79, 71, 86,
-  64, 94, 92, 95, 90, 97, 84, 75, 98, 79,
-  92, 74, 86, 79, 86, 90, 76, 80, 86, 92,
-  76, 85, 92, 93, 102, 105, 92, 103, 75, 76,
-  101, 79, 86, 91, 111, 94, 83, 76, 90, 87,
-  83, 99, 112, 73, 79, 89, 91, 95, 89, 74,
-  74, 87, 72, 88, 82, 82, 92, 87, 86, 74,
-  67, 77, 86, 84, 104, 93, 83, 101, 92, 80,
-  66, 67, 90, 100, 95, 83, 92, 98, 78, 80,
-  84, 121, 76, 84, 71, 82, 98, 60, 94, 82,
-  78, 93, 73, 87, 84, 75, 91, 79, 82, 82,
-  88, 83, 94, 91, 74, 76, 67, 83, 87, 87,
-  83, 95, 76, 92, 75, 78, 87, 88, 92, 100,
-  84, 99, 79, 87, 82, 69, 76, 80, 75, 91,
-  88, 103, 86, 89, 77, 74, 86, 71, 83, 83,
-  86, 90, 85, 93, 66, 79, 73, 111, 95, 78,
-  95, 85, 102, 94, 78, 93, 82, 83, 101, 78,
-  83, 94, 103, 95, 92, 91, 89, 92, 77, 94,
-  103, 74, 91, 83, 92, 97, 76, 84, 77, 83,
-  77, 76, 75, 81, 88, 79, 97, 78, 71, 81,
-  78, 78, 102, 90, 86, 96, 88, 92, 83, 71,
-  97, 85, 85, 89, 91, 91, 83, 89, 83, 114,
-  70, 82, 80, 91, 84, 66, 94, 81, 72, 95,
-  73, 89, 90, 83, 92, 80, 95, 81, 81, 90,
-  99, 83, 73, 79, 74, 84, 88, 88, 86, 92,
-  91, 82, 78, 79, 89, 92, 93, 97, 77, 94,
-  83, 85, 85, 74, 85, 80, 89, 103, 90, 99,
-  88, 86, 81, 86, 79, 74, 79, 99, 81, 87,
-  79, 88, 67, 82, 70, 100, 77, 77, 92, 89,
-  83, 92, 76, 96, 77, 93, 87, 86, 80, 91,
-  102, 86, 88, 87, 84, 92, 76, 73, 97, 80,
-  89, 76, 69, 101, 71, 96, 91, 77, 77, 75,
-  94, 84, 92, 86, 76, 96, 81, 100, 77, 85,
-  107, 86, 81, 81, 96, 91, 85, 75, 86, 87,
-  85, 77, 86, 101, 92, 90, 77, 80, 83, 88,
-  84, 64, 95, 74, 88, 94, 86, 95, 84, 83,
-  74, 80, 82, 80, 84, 102, 95, 87, 90, 75,
-  80, 92, 94, 94, 89, 83, 76, 79, 75, 86,
-  81, 90, 83, 72, 87, 90, 73, 95, 102, 74,
-  92, 82, 93, 90, 84, 97, 72, 83, 100, 74,
-  74, 89, 78, 100, 85, 72, 82, 87, 97, 75,
-  80, 91, 76, 99, 86, 84, 107, 73, 99, 84,
-  92, 84, 74, 90, 98, 69, 90, 106, 75, 88,
-  78, 107, 83, 96, 87, 87, 80, 97, 87, 87,
-  70, 93, 71, 87, 79, 85, 81, 80, 79, 84,
-  83, 95, 88, 75, 81, 91, 76, 74, 83, 79,
-  70, 89, 72, 85, 86, 85, 73, 78, 90, 86,
-  81, 99, 76, 106, 75, 91, 82, 80, 81, 93,
-  80, 87, 91, 92, 85, 73, 89, 95, 84, 85,
-  81, 86, 84, 84, 79, 96, 83, 79, 86, 89,
-  88, 86, 81, 79, 72, 85, 71, 84, 77, 79,
-  83, 83, 74, 75, 78, 82, 84, 73, 85, 86,
-  89, 89, 73, 94, 87, 77, 97, 84, 76, 85,
-  80, 86, 88, 78, 78, 87, 89, 80, 79, 76,
-  75, 97, 76, 88, 81, 80, 79, 87, 68, 77,
-  76, 82, 77, 83, 77, 78, 64, 87, 84, 81,
-  74, 86, 78, 83, 78, 82, 79, 71, 89, 83,
-  74, 82, 84, 80, 78, 88, 73, 84, 79, 92,
-  97, 84, 83, 74, 83, 71, 70, 72, 83, 81,
-  75, 83, 82, 95, 70, 82, 89, 96, 88, 83,
-  75, 92, 87, 96, 91, 77, 77, 95, 71, 95,
-  72, 85, 91, 77, 83, 92, 84, 91, 73, 84,
-  88, 73, 82, 86, 81, 96, 88, 78, 83, 77,
-  82, 81, 84, 88, 85, 87, 81, 88, 76, 85,
-  92, 76, 89, 75, 78, 87, 78, 100, 82, 85,
-  82, 94, 92, 74, 92, 91, 85, 85, 88, 85,
-  83, 87, 84, 75, 79, 89, 82, 78, 83, 84,
-  80, 88, 75, 83, 68, 89, 68, 82, 78, 81,
-  73, 79, 81, 78, 81, 85, 86, 71, 84, 77,
-  77, 86, 77, 87, 80, 78, 77, 100, 78, 111,
-  96, 85, 71, 84, 113, 105, 96, 80, 76, 92,
-  85, 98, 90, 94, 119, 87, 75, 92, 87, 84,
-  88, 68, 97, 101, 94, 87, 71, 107, 103, 74,
-  88, 84, 84, 124, 94, 54, 71, 85, 94, 91,
-  81, 106, 93, 70, 79, 81, 76, 90, 85, 102,
-  103, 83, 97, 59, 75, 80, 73, 92, 82, 77,
-  74, 75, 71, 82, 96, 93, 78, 71, 107, 86,
-  81, 94, 121, 80, 82, 83, 89, 87, 99, 114,
-  64, 76, 98, 78, 74, 81, 87, 79, 76, 82,
-  92, 83, 111, 77, 88, 84, 79, 74, 103, 85,
-  105, 89, 99, 86, 88, 84, 82, 96, 103, 66,
-  82, 95, 86, 97, 76, 99, 83, 96, 87, 99,
-  76, 78, 92, 83, 74, 88, 103, 85, 81, 94,
-  80, 80, 80, 92, 81, 88, 87, 86, 81, 82,
-  79, 80, 79, 81, 67, 93, 75, 82, 88, 86,
-  75, 77, 95, 93, 79, 102, 78, 98, 68, 87,
-  81, 84, 84, 92, 76, 88, 94, 95, 76, 83,
-  83, 85, 89, 87, 77, 99, 83, 81, 77, 82,
-  80, 69, 93, 89, 81, 79, 77, 60, 73, 76,
-  80, 80, 82, 84, 72, 89, 75, 79, 79, 84,
-  89, 75, 72, 91, 87, 87, 79, 120, 85, 77,
-  107, 92, 73, 83, 77, 74, 88, 87, 69, 89,
-  82, 84, 69, 69, 76, 75, 81, 89, 76, 83,
-  83, 87, 71, 76, 86, 80, 74, 86, 80, 73,
-  83, 90, 81, 78, 79, 86, 76, 89, 85, 77,
-  80, 66, 86, 81, 83, 76, 83, 78, 84, 76,
-  71, 87, 77, 85, 96, 80, 84, 72, 81, 69,
-  65, 77, 86, 74, 82, 86, 86, 101, 69, 79,
-  91, 88, 94, 80, 77, 100, 83, 93, 85, 67,
-  81, 101, 79, 95, 79, 90, 93, 78, 74, 89,
-  88, 94, 73, 84, 90, 73, 81, 81, 79, 95,
-  94, 82, 95, 78, 81, 75, 77, 84, 91, 87,
-  79, 78, 75, 93, 84, 79, 84, 81, 75, 87,
-  74, 106, 86, 80, 87, 94, 91, 75, 99, 91,
-  87, 89, 88, 77, 88, 86, 79, 87, 70, 95,
-  77, 77, 77, 80, 77, 91, 71, 74, 75, 91,
-  75, 87, 88, 80, 66, 77, 83, 74, 84, 86,
-  88, 74, 82, 85, 79, 88, 87, 84, 80, 77,
-  88, 92, 81, 95, 86, 70, 81, 84, 84, 76,
-  88, 69, 72, 93, 74, 83, 79, 82, 93, 85,
-  74, 80, 89, 81, 76, 85, 90, 87, 85, 91,
-  86, 95, 91, 88, 75, 88, 89, 89, 100, 71,
-  73, 73, 83, 85, 72, 82, 94, 74, 94, 76,
-  73, 88, 83, 93, 88, 92, 98, 81, 73, 83,
-  75, 85, 93, 79, 80, 74, 77, 85, 99, 95,
-  73, 73, 102, 86, 89, 83, 78, 72, 105, 79,
-  88, 97, 84, 112, 92, 87, 98, 83, 89, 78,
-  88, 78, 95, 83, 84, 84, 93, 81, 90, 76,
-  81, 87, 77, 83, 72, 89, 83, 84, 85, 92,
-  88, 90, 79, 67, 99, 92, 81, 84, 73, 83,
-  81, 89, 82, 84, 77, 106, 82, 75, 85, 86,
-  90, 75, 77, 75, 81, 79, 74, 81, 79, 83,
-  87, 75, 77, 75, 78, 73, 67, 75, 79, 82,
-  78, 84, 82, 93, 77, 80, 86, 86, 97, 87,
-  77, 97, 70, 77, 82, 72, 85, 95, 83, 84,
-  79, 92, 80, 77, 81, 84, 91, 89, 77, 91,
-  87, 76, 79, 84, 79, 84, 90, 95, 94, 76,
-  81, 78, 77, 82, 90, 86, 89, 83, 71, 84,
-  77, 86, 85, 78, 76, 79, 78, 91, 88, 90,
-  77, 97, 90, 85, 85, 92, 90, 81, 80, 79,
-  98, 88, 69, 88, 79, 93, 70, 70, 76, 81,
-  75, 87, 76, 81, 85, 89, 80, 86, 87, 85,
-  67, 80, 88, 79, 70, 88, 84, 79, 83, 88,
-  76, 83, 85, 91, 80, 78, 86, 81, 75, 80,
-  79, 76, 74, 82, 78, 95, 80, 84, 91, 75,
-  85, 75, 81, 71, 70, 78, 89, 82, 84, 91,
-  82, 94, 78, 87, 82, 80, 91, 81, 82, 96,
-  82, 87, 83, 80, 79, 95, 87, 97, 76, 87,
-  87, 77, 72, 97, 84, 93, 75, 82, 93, 80,
-  89, 84, 82, 92, 92, 88, 102, 83, 79, 84,
-  86, 88, 91, 83, 87, 85, 77, 87, 90, 84,
-  86, 80, 81, 92, 69, 102, 87, 81, 84, 87,
-  83, 81, 80, 88, 93, 89, 90, 83, 85, 87,
-  88, 81, 83, 93, 80, 81, 84, 84, 86, 88,
-  81, 79, 80, 91, 84, 87, 88, 85, 73, 79,
-  85, 75, 81, 90, 89, 80, 82, 82, 84, 86,
-  80, 75, 88, 87, 95, 74, 84, 94, 87, 89,
-  84, 80, 74, 82, 84, 79, 96, 82, 78, 73,
-  85, 83, 83, 72, 83, 81, 72, 86, 97, 86,
-  73, 102, 87, 84, 79, 80, 94, 91, 96, 85,
-  82, 68, 80, 76, 82, 77, 71, 75, 89, 80,
-  74, 86, 73, 92, 73, 89, 79, 84, 87, 85,
-  75, 84, 90, 96, 71, 77, 88, 72, 77, 80,
-  88, 91, 81, 88, 71, 91, 88, 80, 80, 89,
-  87, 86, 82, 85, 73, 70, 99, 103, 79, 81,
-  80, 79, 75, 89, 100, 79, 94, 86, 66, 89,
-  84, 81, 79, 93, 83, 79, 94, 77, 91, 97,
-  90, 82, 76, 82, 76, 85, 79, 89, 72, 91,
-  77, 113, 105, 85, 84, 81, 81, 75, 82, 82,
-  82, 82, 85, 84, 77, 88, 89, 77, 78, 71,
-  71, 80, 72, 77, 93, 82, 83, 73, 85, 81,
-  67, 67, 72, 72, 77, 97, 87, 85, 70, 104,
-  87, 89, 74, 76, 93, 83, 87, 70, 74, 91,
-  81, 68, 75, 76, 73, 78, 86, 73, 61, 91,
-  66, 97, 66, 92, 69, 79, 83, 75, 68, 79,
-  82, 112, 76, 83, 75, 93, 77, 76, 96, 104,
-  85, 101, 74, 98, 80, 81, 92, 85, 83, 81,
-  88, 75, 71, 66, 94, 84, 89, 88, 76, 91,
-  72, 96, 85, 83, 95, 93, 67, 96, 86, 78,
-  81, 98, 91, 104, 95, 76, 115, 91, 82, 80,
-  78, 84, 74, 95, 71, 75, 76, 106, 66, 128,
-  134, 84, 84, 86, 70, 61, 85, 81, 98, 78,
-  95, 93, 78, 90, 86, 77, 78, 85, 76, 86,
-  82, 79, 80, 83, 74, 74, 87, 81, 79, 69,
-  76, 81, 83, 83, 88, 87, 74, 104, 86, 94,
-  81, 80, 98, 82, 83, 74, 72, 73, 78, 73,
-  82, 78, 77, 79, 83, 77, 71, 99, 73, 88,
-  75, 91, 77, 81, 86, 77, 78, 81, 81, 93,
-  73, 84, 87, 73, 75, 79, 75, 99, 86, 79,
-  74, 92, 91, 78, 96, 93, 86, 95, 80, 82,
-  75, 72, 97, 70, 81, 85, 95, 83, 74, 86,
-  98, 80, 92, 88, 84, 89, 83, 83, 84, 92,
-  87, 88, 94, 74, 90, 96, 88, 78, 76, 81,
-  79, 84, 80, 79, 81, 88, 75, 111, 109, 80,
-  84, 78, 79, 78, 83, 73, 86, 83, 89, 74,
-  84, 93, 81, 91, 86, 76, 71, 80, 83, 89,
-  83, 72, 84, 80, 86, 92, 82, 80, 79, 68,
-  79, 86, 95, 84, 73, 101, 88, 76, 84, 81,
-  87, 89, 103, 91, 86, 85, 79, 73, 99, 79,
-  90, 76, 89, 83, 78, 85, 79, 90, 75, 86,
-  77, 87, 80, 90, 81, 88, 93, 95, 80, 77,
-  89, 74, 89, 78, 78, 91, 79, 100, 77, 97,
-  80, 78, 83, 87, 93, 83, 80, 80, 70, 72,
-  91, 99, 74, 85, 77, 78, 74, 86, 89, 76,
-  94, 84, 72, 95, 87, 80, 66, 89, 80, 78,
-  86, 81, 94, 85, 85, 84, 76, 79, 78, 81,
-  75, 100, 83, 79, 62, 125, 98, 83, 76, 79,
-  79, 67, 82, 79, 84, 77, 77, 78, 75, 79,
-  75, 91, 82, 69, 69, 75, 75, 94, 75, 74,
-  90, 89, 90, 86, 67, 78, 78, 55, 90, 90,
-  76, 83, 68, 104, 86, 90, 80, 69, 79, 87,
-  92, 75, 71, 126, 75, 66, 103, 78, 84, 75,
-  91, 77, 67, 88, 79, 95, 70, 88, 67, 83,
-  66, 81, 78, 87, 91, 120, 79, 78, 73, 85,
-  87, 68, 71, 109, 76, 90, 72, 118, 71, 70,
-  101, 92, 94, 79, 82, 76, 67, 74, 80, 80,
-  88, 94, 83, 84, 74, 95, 79, 77, 101, 84,
-  67, 109, 88, 76, 75, 85, 81, 77, 78, 81,
-  119, 84, 76, 82, 73, 86, 83, 84, 73, 81,
-  87, 91, 65, 149, 119, 81, 76, 87, 68, 56,
-  83, 78, 93, 73, 91, 83, 81, 88, 80, 79,
-  81, 78, 74, 79, 82, 91, 73, 85, 81, 79,
-  89, 91, 77, 74, 94, 73, 89, 84, 81, 85,
-  74, 102, 86, 101, 85, 73, 86, 83, 86, 70,
-  81, 92, 77, 71, 104, 84, 80, 79, 86, 83,
-  75, 90, 78, 88, 77, 93, 73, 86, 82, 81,
-  81, 85, 88, 93, 81, 80, 87, 72, 90, 79,
-  73, 96, 79, 91, 75, 99, 87, 77, 100, 91,
-  93, 96, 76, 86, 71, 72, 91, 69, 78, 92,
-  105, 79, 75, 83, 85, 78, 95, 83, 86, 96,
-  86, 82, 85, 90, 83, 73, 85, 77, 88, 89,
-  82, 77, 75, 81, 88, 81, 77, 76, 86, 89,
-  79, 122, 103, 81, 81, 77, 75, 72, 83, 76,
-  87, 81, 89, 73, 76, 84, 78, 81, 88, 83,
-  75, 90, 80, 88, 81, 80, 80, 81, 82, 83,
-  92, 70, 84, 81, 80, 90, 96, 83, 80, 94,
-  87, 76, 83, 86, 83, 89, 98, 76, 77, 91,
-  94, 73, 93, 78, 86, 81, 88, 83, 97, 81,
-  79, 83, 80, 82, 75, 92, 76, 91, 84, 84,
-  88, 83, 85, 84, 95, 78, 83, 77, 79, 81,
-  79, 99, 77, 79, 95, 81, 85, 81, 100, 83,
-  81, 75, 74, 89, 89, 83, 76, 88, 77, 83,
-  80, 72, 89, 75, 94, 81, 76, 90, 82, 82,
-  72, 90, 73, 76, 81, 80, 82, 88, 81, 86,
-  81, 78, 79, 81, 79, 96, 81, 90, 73, 109,
-  97, 89, 73, 76, 80, 70, 81, 82, 86, 90,
-  81, 75, 74, 82, 74, 83, 90, 75, 74, 92,
-  78, 87, 72, 85, 81, 89, 78, 78, 81, 73,
-  87, 64, 88, 90, 78, 78, 80, 101, 86, 93,
-  80, 76, 83, 85, 97, 71, 70, 110, 84, 68,
-  101, 77, 89, 78, 95, 83, 90, 81, 83, 86,
-  82, 83, 72, 89, 71, 84, 85, 82, 89, 90,
-  79, 81, 89, 83, 87, 71, 69, 78, 74, 87,
-  76, 94, 90, 78, 88, 87, 96, 80, 78, 72,
-  73, 94, 84, 76, 77, 88, 81, 82, 81, 77,
-  88, 72, 103, 75, 74, 90, 87, 85, 76, 91,
-  75, 78, 82, 82, 87, 84, 76, 89, 79, 79,
-  86, 80, 78, 80, 87, 87, 72, 128, 100, 91,
-  76, 74, 72, 72, 82, 79, 86, 88, 87, 81,
-  79, 84, 84, 73, 87, 80, 78, 88, 81, 88,
-  73, 95, 79, 84, 83, 84, 89, 73, 93, 74,
-  84, 88, 82, 82, 83, 97, 84, 99, 85, 83,
-  86, 81, 86, 74, 80, 92, 79, 74, 96, 79,
-  85, 83, 86, 92, 92, 85, 80, 83, 82, 85,
-  75, 91, 79, 79, 79, 84, 81, 84, 87, 86,
-  91, 76, 85, 78, 78, 83, 77, 82, 78, 80,
-  95, 81, 90, 80, 98, 82, 71, 78, 74, 87,
-  91, 72, 77, 90, 97, 77, 79, 73, 88, 78,
-  94, 80, 86, 91, 81, 84, 86, 95, 76, 86,
-  82, 80, 77, 85, 80, 87, 82, 80, 90, 82,
-  79, 77, 85, 88, 71, 108, 97, 89, 75, 75,
-  78, 73, 82, 81, 88, 93, 76, 85, 86, 75,
-  68, 82, 72, 80, 68, 83, 79, 76, 68, 85,
-  62, 94, 89, 83, 98, 109, 62, 68, 99, 101,
-  74, 94, 78, 69, 105, 78, 84, 81, 68, 76,
-  80, 95, 74, 92, 74, 77, 93, 78, 67, 72,
-  92, 97, 90, 78, 97, 81, 71, 78, 76, 77,
-  103, 55, 127, 74, 74, 87, 80, 94, 100, 59,
-  69, 72, 80, 79, 90, 85, 95, 81, 103, 82,
-  89, 99, 72, 90, 71, 79, 86, 92, 93, 97,
-  73, 94, 76, 81, 93, 87, 109, 69, 84, 94,
-  105, 78, 89, 80, 77, 94, 85, 55, 82, 93,
-  88, 79, 96, 69, 84, 74, 85, 83, 75, 92,
-  75, 86, 79, 80, 82, 80, 63, 84, 84, 75,
-  102, 88, 81, 74, 83, 63, 101, 85, 85, 98,
-  69, 77, 83, 97, 75, 78, 99, 83, 68, 82,
-  66, 71, 83, 98, 84, 77, 95, 94, 90, 90,
-  83, 81, 123, 98, 72, 82, 49, 82, 90, 86,
-  82, 77, 75, 81, 89, 81, 89, 60, 87, 129,
-  71, 109, 93, 88, 77, 92, 88, 68, 84, 88,
-  69, 57, 66, 92, 93, 90, 85, 57, 58, 62,
-  72, 73, 81, 91, 87, 97, 79, 80, 78, 68,
-  78, 104, 79, 74, 78, 70, 101, 94, 72, 90,
-  100, 111, 55, 88, 72, 79, 85, 98, 87, 73,
-  87, 74, 91, 71, 86, 59, 94, 84, 83, 75,
-  84, 80, 73, 75, 88, 96, 68, 91, 64, 92,
-  106, 79, 67, 70, 82, 83, 82, 78, 76, 84,
-  77, 81, 88, 69, 71, 92, 78, 77, 81, 79,
-  83, 90, 91, 101, 101, 85, 91, 86, 81, 73,
-  87, 87, 101, 77, 76, 88, 91, 90, 89, 79,
-  78, 101, 93, 84, 84, 88, 93, 74, 88, 85,
-  77, 88, 89, 79, 84, 79, 81, 97, 76, 81,
-  71, 87, 90, 103, 89, 85, 78, 113, 62, 81,
-  87, 89, 96, 83, 84, 75, 79, 87, 89, 88,
-  67, 85, 86, 82, 77, 85, 76, 68, 84, 80,
-  85, 87, 91, 99, 80, 86, 95, 85, 99, 90,
-  96, 94, 74, 89, 96, 92, 68, 91, 101, 89,
-  98, 82, 94, 79, 92, 80, 86, 84, 62, 101,
-  93, 82, 85, 95, 80, 88, 97, 84, 76, 87,
-  84, 77, 89, 89, 74, 85, 86, 81, 85, 81,
-  68, 94, 85, 78, 69, 63, 83, 83, 79, 80,
-  80, 79, 73, 97, 65, 84, 87, 73, 94, 106,
-  57, 71, 78, 98, 78, 98, 72, 67, 97, 69,
-  82, 86, 59, 76, 62, 83, 77, 87, 78, 70,
-  96, 74, 74, 74, 93, 87, 90, 93, 91, 74,
-  75, 75, 85, 76, 102, 65, 128, 66, 75, 92,
-  83, 93, 103, 71, 64, 78, 73, 80, 101, 97,
-  69, 69, 113, 91, 94, 87, 83, 72, 72, 71,
-  83, 84, 85, 89, 76, 95, 69, 81, 92, 79,
-  94, 66, 89, 89, 93, 79, 88, 86, 75, 86,
-  85, 57, 85, 98, 94, 95, 100, 77, 86, 73,
-  85, 82, 74, 87, 74, 77, 71, 81, 88, 88,
-  64, 83, 83, 79, 88, 91, 82, 73, 76, 75,
-  89, 84, 90, 94, 72, 71, 87, 90, 79, 81,
-  97, 82, 68, 84, 74, 64, 77, 96, 83, 60,
-  76, 90, 96, 95, 69, 82, 99, 86, 75, 74,
-  41, 89, 83, 87, 82, 65, 75, 86, 92, 74,
-  88, 58, 85, 121, 77, 133, 91, 88, 73, 85,
-  89, 72, 81, 69, 64, 58, 63, 96, 94, 84,
-  85, 64, 62, 62, 66, 68, 98, 76, 88, 84,
-  83, 86, 86, 55, 78, 89, 73, 75, 78, 63,
-  101, 88, 68, 94, 99, 105, 54, 80, 58, 81,
-  83, 96, 67, 76, 84, 81, 70, 66, 80, 67,
-  91, 86, 78, 82, 85, 83, 67, 74, 95, 96,
-  63, 86, 70, 69, 83, 74, 60, 68, 78, 87,
-  84, 77, 73, 86, 70, 80, 85, 73, 84, 89,
-  70, 76, 86, 85, 88, 85, 92, 105, 80, 86,
-  98, 82, 88, 82, 88, 88, 99, 75, 78, 83,
-  89, 90, 75, 82, 61, 96, 93, 86, 92, 86,
-  84, 78, 83, 78, 77, 79, 81, 73, 84, 80,
-  83, 98, 84, 85, 77, 87, 84, 95, 87, 95,
-  76, 119, 64, 83, 80, 79, 90, 89, 78, 69,
-  77, 89, 91, 87, 83, 80, 76, 68, 86, 87,
-  82, 72, 82, 72, 79, 90, 94, 96, 81, 81,
-  97, 88, 92, 95, 92, 78, 85, 84, 92, 88,
-  69, 85, 90, 97, 80, 90, 88, 87, 86, 80,
-  75, 91, 65, 97, 86, 86, 94, 97, 81, 85,
-  97, 78, 72, 85, 78, 69, 74, 94, 71, 85,
-  82, 80, 80, 81, 73, 107, 91, 80, 67, 74,
-  84, 88, 77, 80, 76, 72, 69, 95, 56, 81,
-  74, 72, 95, 102, 61, 83, 103, 97, 81, 99,
-  78, 74, 88, 61, 75, 87, 69, 77, 69, 95,
-  87, 82, 84, 73, 87, 74, 83, 76, 89, 96,
-  83, 89, 97, 71, 74, 72, 87, 78, 98, 71,
-  128, 68, 73, 87, 86, 98, 96, 67, 74, 77,
-  75, 84, 90, 96, 65, 76, 114, 91, 97, 97,
-  75, 94, 80, 71, 89, 85, 88, 92, 76, 91,
-  76, 80, 81, 83, 100, 71, 90, 79, 103, 76,
-  90, 77, 67, 83, 90, 61, 89, 92, 97, 79,
-  118, 76, 95, 75, 87, 77, 77, 100, 65, 82,
-  88, 76, 89, 96, 73, 83, 80, 81, 93, 92,
-  84, 72, 76, 79, 77, 92, 85, 102, 70, 75,
-  86, 90, 76, 81, 99, 86, 59, 82, 67, 73,
-  83, 90, 95, 74, 87, 91, 102, 86, 79, 89,
-  113, 58, 84, 84, 48, 98, 97, 90, 96, 78,
-  89, 87, 98, 81, 92, 62, 76, 124, 74, 116,
-  94, 81, 82, 84, 87, 67, 81, 80, 74, 54,
-  73, 89, 97, 94, 88, 57, 76, 57, 71, 76,
-  98, 78, 95, 87, 92, 86, 84, 66, 77, 106,
-  79, 77, 74, 76, 101, 92, 72, 95, 102, 107,
-  59, 80, 75, 86, 85, 91, 78, 77, 85, 77,
-  58, 77, 77, 70, 95, 82, 84, 83, 86, 88,
-  78, 66, 93, 95, 70, 93, 67, 85, 80, 82,
-  72, 73, 90, 80, 88, 77, 81, 90, 82, 78,
-  83, 65, 78, 97, 71, 74, 88, 85, 95, 86,
-  85, 101, 88, 77, 80, 84, 81, 89, 89, 85,
-  104, 78, 83, 90, 92, 81, 80, 90, 81, 80,
-  99, 85, 84, 99, 90, 78, 87, 85, 82, 96,
-  86, 81, 88, 85, 77, 98, 82, 87, 86, 89,
-  78, 94, 91, 88, 69, 122, 64, 76, 79, 83,
-  90, 86, 82, 68, 83, 85, 96, 81, 89, 81,
-  83, 76, 85, 84, 78, 68, 75, 80, 92, 90,
-  84, 107, 87, 85, 91, 94, 94, 101, 98, 85,
-  83, 94, 98, 93, 63, 85, 82, 93, 73, 93,
-  84, 81, 87, 75, 88, 86, 64, 93, 86, 91,
-  97, 87, 85, 92, 91, 79, 77, 91, 81, 65,
-  86, 90, 80, 82, 90, 81, 85, 81, 80, 78,
-  90, 105, 69, 86, 81, 71, 95, 91, 88, 82,
-  87, 79, 84, 82, 71, 73, 104, 69, 94, 82,
-  114, 94, 83, 74, 69, 89, 91, 81, 89, 97,
-  92, 79, 74, 91, 74, 86, 79, 82, 105, 77,
-  85, 89, 75, 78, 103, 82, 78, 87, 96, 73,
-  81, 108, 91, 87, 84, 91, 87, 83, 77, 95,
-  71, 82, 80, 80, 85, 101, 78, 83, 88, 87,
-  64, 86, 76, 84, 87, 101, 80, 77, 85, 79,
-  73, 75, 83, 84, 83, 74, 70, 89, 74, 97,
-  99, 86, 75, 83, 82, 93, 91, 63, 70, 79,
-  92, 81, 89, 91, 87, 79, 85, 79, 84, 90,
-  85, 86, 87, 93, 94, 81, 89, 87, 94, 73,
-  75, 83, 96, 86, 84, 84, 68, 90, 80, 106,
-  72, 96, 74, 62, 94, 89, 86, 77, 85, 79,
-  76, 73, 74, 78, 102, 77, 90, 83, 103, 88,
-  88, 75, 74, 87, 96, 78, 97, 95, 92, 81,
-  83, 73, 83, 97, 84, 81, 110, 75, 93, 94,
-  74, 77, 103, 86, 87, 87, 95, 81, 89, 127,
-  87, 86, 75, 87, 83, 75, 88, 100, 67, 89,
-  68, 82, 89, 94, 75, 82, 82, 87, 55, 90,
-  78, 82, 78, 87, 77, 74, 84, 85, 75, 74,
-  85, 87, 83, 76, 63, 89, 69, 107, 88, 83,
-  63, 76, 65, 90, 99, 60, 70, 84, 90, 78,
-  77, 84, 76, 72, 90, 75, 96, 91, 85, 80,
-  94, 89, 75, 74, 87, 93, 81, 73, 83, 79,
-  108, 85, 76, 78, 82, 98, 88, 87, 71, 107,
-  83, 71, 96, 93, 86, 81, 80, 73, 79, 90,
-  78, 70, 101, 71, 81, 80, 89, 89, 85, 78,
-  69, 85, 86, 78, 87, 96, 88, 80, 80, 82,
-  77, 89, 76, 87, 96, 78, 86, 83, 81, 88,
-  90, 98, 80, 84, 92, 70, 85, 103, 91, 82,
-  86, 91, 85, 80, 78, 92, 74, 80, 81, 85,
-  76, 93, 73, 74, 94, 87, 70, 85, 75, 91,
-  83, 78, 78, 77, 79, 80, 87, 89, 74, 85,
-  84, 74, 75, 98, 75, 107, 102, 86, 84, 81,
-  80, 88, 104, 63, 69, 85, 96, 85, 84, 83,
-  83, 78, 87, 83, 97, 85, 88, 91, 82, 86,
-  81, 85, 90, 91, 79, 76, 65, 87, 87, 85,
-  86, 80, 69, 70, 77, 122, 82, 73, 84, 71,
-  105, 93, 76, 84, 86, 100, 80, 89, 72, 71,
-  83, 74, 93, 74, 119, 94, 81, 75, 98, 74,
-  99, 79, 85, 83, 91, 74, 85, 95, 80, 73,
-  77, 72, 94, 94, 81, 105, 79, 89, 100, 96,
-  93, 84, 92, 78, 79, 116, 83, 100, 87, 80,
-  81, 95, 75, 97, 74, 75, 79, 65, 84, 113,
-  104, 76, 107, 88, 75, 83, 67, 70, 98, 92,
-  85, 85, 97, 86, 92, 70, 81, 81, 86, 74,
-  70, 78, 60, 89, 75, 89, 64, 75, 63, 88,
-  90, 73, 70, 93, 87, 74, 85, 98, 89, 72,
-  83, 52, 88, 86, 84, 92, 81, 91, 71, 68,
-  76, 82, 91, 63, 90, 71, 91, 86, 78, 75,
-  68, 91, 97, 156, 86, 75, 76, 50, 114, 85,
-  73, 77, 83, 85, 84, 99, 69, 67, 74, 74,
-  94, 82, 83, 83, 98, 81, 122, 66, 111, 83,
-  81, 107, 102, 75, 87, 74, 82, 73, 87, 73,
-  82, 84, 93, 102, 72, 85, 111, 93, 102, 90,
-  99, 93, 99, 150, 82, 89, 67, 81, 66, 85,
-  83, 104, 76, 92, 73, 67, 90, 90, 103, 76,
-  79, 81, 62, 83, 67, 47, 96, 90, 79, 79,
-  105, 105, 106, 82, 77, 91, 92, 71, 70, 76,
-  47, 94, 56, 94, 46, 63, 36, 86, 98, 65,
-  74, 86, 73, 69, 78, 79, 86, 62, 99, 48,
-  106, 71, 83, 87, 82, 87, 76, 55, 58, 87,
-  84, 62, 117, 60, 110, 92, 51, 70, 77, 89,
-  97, 101, 76, 104, 82, 65, 96, 93, 76, 88,
-  74, 78, 77, 92, 82, 73, 87, 78, 79, 76,
-  73, 87, 91, 75, 94, 70, 95, 86, 82, 97,
-  84, 78, 84, 68, 80, 78, 82, 78, 92, 90,
-  84, 100, 80, 88, 89, 88, 90, 83, 89, 81,
-  80, 107, 78, 80, 88, 84, 80, 88, 73, 97,
-  77, 69, 84, 72, 82, 107, 88, 79, 78, 87,
-  71, 88, 69, 75, 88, 85, 73, 80, 88, 88,
-  108, 97, 74, 91, 89, 79, 75, 83, 63, 99,
-  77, 93, 71, 68, 63, 88, 99, 64, 69, 78,
-  87, 76, 83, 95, 83, 72, 85, 63, 103, 91,
-  88, 92, 83, 95, 98, 69, 76, 86, 72, 67,
-  75, 76, 82, 88, 85, 74, 76, 76, 81, 97,
-  88, 77, 73, 83, 99, 97, 71, 71, 83, 95,
-  81, 99, 69, 63, 76, 89, 83, 76, 107, 102,
-  82, 76, 106, 67, 81, 84, 72, 77, 74, 68,
-  89, 101, 88, 70, 75, 73, 78, 84, 74, 84,
-  68, 85, 81, 89, 100, 79, 81, 67, 82, 103,
-  76, 101, 103, 77, 84, 91, 68, 95, 83, 85,
-  75, 65, 82, 100, 90, 79, 98, 87, 106, 90,
-  68, 91, 97, 91, 113, 80, 82, 75, 104, 81,
-  87, 81, 81, 83, 72, 81, 67, 82, 81, 82,
-  72, 72, 68, 75, 71, 78, 67, 93, 91, 81,
-  86, 106, 73, 75, 64, 69, 81, 92, 82, 91,
-  80, 80, 74, 85, 83, 89, 93, 71, 86, 64,
-  74, 85, 99, 74, 79, 83, 90, 118, 94, 79,
-  57, 62, 103, 91, 67, 67, 83, 89, 88, 103,
-  74, 61, 72, 92, 85, 74, 79, 96, 92, 72,
-  117, 60, 99, 98, 76, 93, 87, 70, 86, 82,
-  80, 50, 82, 68, 66, 72, 77, 96, 61, 85,
-  76, 98, 98, 80, 82, 78, 97, 112, 69, 85,
-  90, 75, 80, 91, 73, 106, 83, 96, 79, 64,
-  85, 99, 102, 82, 89, 85, 97, 84, 51, 68,
-  100, 90, 106, 76, 85, 78, 132, 88, 94, 87,
-  86, 79, 78, 73, 56, 88, 61, 89, 59, 61,
-  53, 78, 76, 75, 62, 88, 86, 81, 90, 110,
-  73, 72, 60, 60, 86, 87, 77, 87, 98, 83,
-  92, 74, 65, 96, 80, 70, 97, 49, 75, 84,
-  82, 73, 81, 84, 75, 89, 86, 99, 71, 77,
-  93, 94, 76, 73, 76, 80, 79, 94, 82, 68,
-  80, 78, 78, 77, 72, 94, 87, 70, 99, 66,
-  79, 101, 73, 86, 69, 74, 86, 75, 85, 67,
-  82, 77, 78, 82, 79, 90, 67, 84, 76, 91,
-  92, 75, 81, 81, 83, 96, 79, 71, 97, 80,
-  89, 87, 68, 90, 86, 78, 77, 71, 78, 98,
-  90, 84, 78, 86, 95, 92, 61, 96, 90, 81,
-  97, 73, 77, 81, 104, 94, 81, 84, 82, 92,
-  77, 86, 69, 85, 88, 81, 75, 68, 69, 80,
-  91, 64, 70, 72, 91, 80, 89, 100, 76, 79,
-  63, 77, 92, 90, 85, 87, 91, 90, 103, 87,
-  84, 89, 81, 73, 76, 74, 73, 82, 101, 80,
-  81, 77, 79, 83, 76, 85, 75, 94, 81, 90,
-  68, 86, 88, 106, 71, 83, 84, 72, 85, 87,
-  87, 98, 90, 87, 79, 71, 85, 89, 95, 80,
-  84, 72, 84, 74, 79, 85, 67, 85, 93, 74,
-  90, 76, 89, 81, 86, 84, 78, 75, 88, 95,
-  98, 81, 95, 89, 79, 80, 64, 73, 80, 75,
-  92, 91, 85, 80, 62, 79, 123, 90, 84, 59,
-  79, 76, 99, 92, 78, 78, 75, 89, 82, 80,
-  82, 92, 88, 88, 73, 91, 98, 80, 86, 80,
-  79, 89, 95, 78, 93, 80, 68, 76, 87, 86,
-  78, 81, 92, 75, 89, 84, 79, 87, 81, 98,
-  70, 99, 75, 89, 84, 81, 81, 90, 77, 85,
-  83, 79, 96, 88, 81, 90, 80, 87, 77, 79,
-  83, 92, 102, 79, 69, 93, 78, 90, 75, 81,
-  83, 98, 68, 85, 93, 78, 93, 93, 86, 95,
-  85, 78, 91, 65, 80, 97, 94, 85, 81, 85,
-  95, 68, 77, 74, 57, 87, 121, 67, 96, 70,
-  94, 97, 92, 86, 87, 75, 86, 90, 100, 74,
-  89, 94, 71, 89, 64, 79, 74, 69, 95, 100,
-  85, 79, 55, 71, 122, 97, 98, 66, 67, 70,
-  100, 94, 77, 70, 68, 78, 82, 77, 80, 88,
-  92, 92, 73, 87, 84, 91, 77, 77, 76, 98,
-  89, 84, 90, 92, 75, 76, 88, 74, 83, 85,
-  91, 75, 81, 79, 74, 79, 80, 91, 64, 135,
-  78, 82, 84, 74, 77, 93, 77, 86, 85, 77,
-  94, 87, 80, 91, 83, 84, 72, 87, 81, 85,
-  74, 88, 76, 103, 86, 89, 67, 91, 95, 84,
-  68, 88, 81, 72, 84, 83, 78, 94, 86, 89,
-  71, 71, 85, 83, 93, 90, 77, 82, 86, 77,
-  84, 86, 71, 87, 116, 78, 85, 76, 85, 85,
-  89, 82, 80, 87, 89, 94, 97, 82, 99, 91,
-  83, 91, 77, 66, 79, 82, 92, 91, 79, 81,
-  70, 80, 101, 91, 79, 72, 78, 79, 97, 81,
-  76, 75, 75, 73, 77, 85, 80, 88, 84, 83,
-  75, 85, 86, 88, 84, 78, 81, 87, 92, 74,
-  93, 80, 67, 74, 79, 81, 80, 88, 91, 76,
-  90, 80, 89, 85, 79, 96, 66, 97, 73, 98,
-  78, 83, 82, 86, 78, 84, 88, 78, 96, 88,
-  83, 90, 77, 88, 80, 62, 73, 74, 106, 76,
-  71, 85, 73, 93, 85, 80, 71, 78, 66, 74,
-  90, 85, 90, 103, 95, 95, 105, 75, 84, 66,
-  83, 97, 105, 99, 78, 86, 92, 70, 84, 95,
-  67, 78, 141, 69, 89, 65, 95, 101, 93, 73,
-  75, 71, 87, 85, 92, 67, 73, 88, 68, 85,
-  86, 74, 73, 68, 74, 107, 81, 81, 67, 72,
-  92, 93, 93, 69, 73, 63, 95, 92, 77, 81,
-  82, 85, 109, 72, 66, 77, 83, 103, 78, 77,
-  91, 105, 64, 88, 90, 77, 85, 59, 94, 95,
-  81, 79, 78, 87, 93, 81, 87, 82, 86, 88,
-  72, 81, 84, 85, 77, 135, 69, 84, 89, 83,
-  80, 87, 58, 78, 84, 72, 72, 78, 69, 88,
-  83, 84, 78, 62, 65, 76, 137, 76, 77, 81,
-  67, 98, 90, 70, 60, 108, 73, 71, 93, 85,
-  87, 112, 102, 99, 72, 67, 81, 64, 75, 98,
-  101, 109, 82, 85, 86, 70, 83, 89, 47, 70,
-  136, 72, 90, 54, 97, 117, 101, 75, 77, 71,
-  89, 76, 86, 64, 70, 93, 60, 77, 90, 83,
-  65, 57, 78, 128, 75, 77, 69, 70, 68, 95,
-  118, 64, 66, 58, 92, 77, 90, 74, 72, 75,
-  105, 67, 67, 74, 83, 88, 90, 70, 75, 104,
-  57, 85, 87, 77, 70, 61, 94, 105, 82, 87,
-  78, 76, 74, 80, 92, 81, 90, 95, 64, 72,
-  81, 74, 80, 173, 80, 77, 87, 68, 71, 86,
-  59, 78, 90, 68, 61, 77, 74, 87, 90, 75,
-  81, 68, 70, 81, 86, 93, 77, 92, 80, 89,
-  88, 78, 79, 125, 67, 75, 89, 77, 90, 88,
-  90, 97, 75, 77, 64, 70, 89, 92, 99, 109,
-  79, 94, 92, 74, 84, 92, 69, 82, 102, 73,
-  79, 69, 92, 88, 88, 75, 82, 84, 87, 92,
-  88, 72, 79, 85, 79, 74, 93, 73, 74, 81,
-  83, 97, 81, 74, 74, 79, 76, 87, 92, 77,
-  70, 77, 92, 83, 86, 84, 78, 80, 89, 76,
-  70, 76, 79, 82, 78, 76, 83, 99, 73, 84,
-  91, 99, 85, 61, 94, 89, 79, 77, 76, 83,
-  95, 98, 85, 79, 87, 85, 83, 76, 84, 89,
-  81, 114, 72, 93, 88, 90, 78, 81, 70, 76,
-  96, 77, 81, 83, 75, 88, 83, 92, 81, 83,
-  83, 75, 64, 103, 86, 89, 88, 84, 78, 93,
-  91, 60, 76, 96, 75, 101, 82, 81, 83, 78,
-  97, 83, 83, 81, 89, 88, 85, 94, 89, 91,
-  91, 72, 76, 89, 83, 79, 104, 82, 81, 76,
-  84, 87, 77, 77, 87, 78, 80, 88, 100, 89,
-  84, 90, 81, 93, 82, 75, 80, 93, 87, 76,
-  89, 86, 93, 83, 82, 77, 80, 75, 78, 80,
-  98, 81, 77, 84, 83, 87, 92, 83, 84, 95,
-  84, 92, 85, 84, 95, 74, 98, 84, 84, 82,
-  83, 74, 93, 71, 80, 81, 88, 87, 90, 80,
-  84, 74, 84, 91, 78, 85, 81, 94, 87, 74,
-  74, 85, 93, 98, 81, 85, 82, 75, 92, 79,
-  100, 84, 80, 92, 78, 85, 82, 84, 77, 73,
-  66, 83, 93, 93, 83, 86, 77, 94, 90, 78,
-  78, 95, 68, 97, 75, 77, 88, 75, 83, 82,
-  80, 81, 98, 92, 77, 94, 92, 92, 97, 71,
-  88, 77, 81, 71, 75, 83, 77, 75, 90, 80,
-  69, 83, 90, 77, 96, 94, 93, 89, 89, 91,
-  78, 86, 83, 76, 84, 85, 89, 74, 90, 86,
-  77, 84, 76, 59, 84, 66, 73, 91, 95, 80,
-  84, 90, 78, 84, 103, 79, 89, 95, 83, 82,
-  85, 85, 85, 66, 99, 91, 91, 79, 89, 79,
-  80, 63, 85, 80, 95, 80, 91, 69, 89, 70,
-  89, 90, 76, 82, 82, 102, 93, 69, 87, 87,
-  95, 101, 67, 89, 86, 83, 94, 80, 103, 92,
-  84, 93, 83, 88, 84, 79, 85, 76, 70, 96,
-  88, 92, 89, 81, 78, 85, 89, 98, 83, 91,
-  77, 90, 82, 81, 81, 85, 94, 82, 76, 84,
-  86, 83, 78, 84, 91, 87, 86, 78, 90, 87,
-  82, 78, 67, 80, 78, 75, 81, 83, 77, 80,
-  93, 84, 80, 84, 94, 96, 87, 89, 84, 77,
-  83, 79, 76, 93, 88, 75, 85, 88, 101, 84,
-  83, 79, 79, 76, 87, 81, 96, 82, 85, 83,
-  79, 90, 93, 82, 90, 88, 80, 81, 89, 86,
-  84, 73, 97, 83, 83, 90, 83, 83, 92, 72,
-  82, 81, 85, 83, 92, 79, 83, 71, 83, 95,
-  80, 88, 77, 95, 88, 77, 77, 96, 97, 88,
-  74, 82, 88, 75, 84, 82, 95, 88, 82, 87,
-  83, 85, 95, 86, 84, 93, 86, 92, 72, 104,
-  99, 85, 83, 76, 100, 64, 64, 106, 88, 92,
-  80, 78, 84, 84, 96, 88, 71, 66, 84, 90,
-  90, 85, 81, 85, 100, 73, 84, 91, 80, 87,
-  104, 77, 90, 80, 84, 89, 86, 90, 79, 87,
-  82, 95, 80, 94, 85, 88, 104, 82, 92, 90,
-  92, 81, 77, 78, 85, 83, 83, 83, 92, 76,
-  93, 79, 105, 82, 111, 111, 70, 89, 87, 80,
-  85, 68, 102, 75, 82, 86, 92, 72, 80, 86,
-  90, 74, 84, 115, 89, 80, 96, 67, 93, 75,
-  77, 90, 97, 73, 86, 85, 76, 72, 78, 85,
-  73, 99, 88, 90, 84, 83, 83, 68, 78, 75,
-  92, 79, 68, 78, 79, 112, 91, 85, 82, 87,
-  93, 78, 93, 102, 95, 97, 69, 112, 105, 87,
-  81, 76, 93, 79, 70, 106, 84, 97, 85, 76,
-  89, 92, 99, 89, 71, 63, 100, 95, 87, 82,
-  74, 80, 98, 66, 89, 87, 73, 89, 75, 69,
-  98, 71, 87, 86, 90, 100, 80, 79, 75, 93,
-  86, 98, 85, 81, 109, 68, 93, 86, 92, 84,
-  77, 78, 85, 77, 101, 70, 92, 69, 92, 87,
-  84, 74, 129, 111, 72, 84, 87, 88, 79, 57,
-  97, 77, 86, 87, 78, 78, 83, 74, 82, 77,
-  89, 116, 89, 80, 107, 63, 86, 73, 72, 81,
-  93, 75, 84, 88, 76, 71, 77, 86, 74, 101,
-  90, 93, 93, 85, 77, 58, 97, 76, 83, 77,
-  77, 75, 81, 123, 86, 95, 83, 86, 98, 73,
-  102, 95, 90, 86, 79, 95, 92, 87, 87, 81,
-  96, 108, 68, 101, 82, 88, 88, 82, 86, 92,
-  85, 92, 71, 72, 85, 86, 81, 82, 83, 81,
-  102, 71, 85, 91, 76, 83, 69, 79, 90, 82,
-  83, 85, 80, 88, 77, 83, 80, 97, 75, 108,
-  88, 87, 112, 74, 90, 85, 94, 85, 75, 79,
-  84, 81, 85, 85, 89, 80, 94, 79, 75, 78,
-  115, 102, 77, 90, 85, 89, 80, 76, 106, 69,
-  84, 74, 88, 79, 74, 80, 94, 74, 83, 107,
-  93, 86, 95, 70, 89, 77, 80, 90, 86, 72,
-  90, 82, 77, 73, 79, 83, 74, 99, 98, 85,
-  86, 86, 92, 71, 101, 80, 92, 79, 81, 78,
-  81, 116, 91, 93, 90, 91, 90, 82, 85, 74,
-  75, 70, 72, 70, 71, 75, 79, 82, 90, 67,
-  76, 77, 84, 82, 66, 92, 76, 59, 85, 80,
-  91, 76, 70, 76, 104, 84, 93, 86, 79, 95,
-  74, 90, 104, 80, 97, 82, 80, 84, 80, 81,
-  83, 71, 86, 89, 83, 74, 80, 67, 81, 93,
-  70, 96, 82, 84, 82, 92, 99, 75, 98, 90,
-  89, 73, 98, 77, 90, 78, 86, 98, 76, 91,
-  86, 60, 82, 77, 95, 81, 78, 107, 73, 100,
-  101, 71, 77, 88, 66, 76, 66, 90, 72, 81,
-  81, 71, 86, 96, 84, 77, 81, 87, 87, 92,
-  89, 67, 78, 81, 89, 72, 86, 81, 59, 82,
-  83, 98, 78, 92, 85, 75, 73, 84, 71, 69,
-  69, 87, 68, 73, 94, 80, 78, 64, 83, 65,
-  73, 69, 64, 71, 78, 84, 86, 84, 80, 77,
-  83, 84, 63, 89, 81, 55, 66, 74, 87, 82,
-  75, 68, 105, 79, 104, 82, 72, 92, 84, 79,
-  104, 80, 75, 77, 81, 80, 90, 84, 92, 68,
-  83, 83, 85, 67, 79, 63, 81, 90, 63, 81,
-  80, 83, 76, 89, 95, 78, 99, 88, 74, 66,
-  91, 72, 100, 71, 71, 95, 72, 83, 97, 51,
-  77, 89, 103, 74, 79, 110, 67, 77, 116, 69,
-  78, 82, 48, 80, 66, 89, 65, 82, 79, 72,
-  82, 94, 90, 64, 68, 81, 81, 94, 102, 60,
-  74, 83, 95, 66, 96, 82, 57, 78, 86, 87,
-  64, 94, 82, 74, 75, 76, 74, 56, 73, 94,
-  69, 67, 88, 74, 87, 78, 77, 89, 67, 71,
-  77, 79, 85, 82, 83, 100, 72, 80, 81, 84,
-  75, 96, 81, 64, 66, 81, 76, 74, 80, 77,
-  92, 76, 89, 83, 84, 77, 75, 84, 87, 76,
-  59, 77, 77, 87, 84, 82, 80, 76, 79, 92,
-  78, 77, 79, 81, 81, 91, 84, 80, 86, 81,
-  85, 88, 93, 73, 100, 81, 90, 79, 87, 77,
-  98, 78, 75, 94, 87, 90, 93, 64, 88, 94,
-  94, 85, 81, 97, 76, 69, 96, 71, 79, 82,
-  75, 75, 72, 106, 73, 81, 90, 70, 82, 92,
-  88, 77, 78, 99, 90, 88, 85, 68, 79, 76,
-  86, 79, 87, 83, 67, 85, 93, 90, 76, 92,
-  88, 68, 82, 87, 78, 79, 75, 89, 72, 80,
-  88, 88, 85, 87, 92, 80, 78, 71, 75, 81,
-  82, 87, 94, 92, 82, 75, 85, 77, 79, 83,
-  85, 66, 84, 92, 82, 80, 84, 87, 92, 87,
-  98, 83, 85, 104, 91, 84, 81, 100, 57, 83,
-  89, 91, 87, 82, 86, 83, 84, 90, 85, 83,
-  90, 78, 84, 92, 74, 78, 83, 77, 86, 86,
-  95, 93, 91, 84, 98, 75, 85, 72, 87, 78,
-  86, 92, 80, 81, 84, 72, 80, 87, 86, 89,
-  78, 87, 78, 83, 83, 84, 78, 78, 81, 74,
-  78, 83, 87, 89, 84, 79, 92, 88, 85, 90,
-  87, 93, 88, 90, 82, 80, 88, 83, 87, 76,
-  75, 86, 71, 90, 79, 80, 75, 102, 87, 89,
-  83, 87, 79, 72, 65, 93, 70, 79, 93, 78,
-  80, 80, 95, 75, 80, 70, 68, 77, 82, 86,
-  99, 78, 83, 79, 89, 82, 81, 81, 86, 54,
-  75, 93, 84, 83, 82, 79, 101, 85, 106, 90,
-  80, 106, 86, 76, 87, 99, 86, 85, 94, 96,
-  85, 82, 83, 74, 83, 86, 94, 82, 87, 68,
-  85, 85, 68, 79, 80, 75, 84, 84, 104, 94,
-  89, 84, 85, 73, 100, 66, 91, 90, 74, 99,
-  74, 80, 81, 64, 80, 99, 81, 93, 78, 79,
-  76, 81, 88, 91, 81, 86, 72, 73, 71, 77,
-  85, 97, 75, 83, 92, 86, 90, 87, 78, 75,
-  87, 91, 83, 77, 85, 87, 85, 77, 75, 82,
-  68, 84, 75, 90, 82, 103, 86, 97, 86, 83,
-  83, 62, 62, 92, 64, 78, 85, 79, 92, 92,
-  84, 100, 72, 67, 78, 80, 85, 83, 92, 67,
-  76, 79, 88, 82, 83, 88, 89, 59, 80, 96,
-  82, 77, 82, 87, 88, 92, 89, 89, 83, 89,
-  84, 84, 80, 97, 100, 83, 91, 92, 78, 87,
-  87, 78, 83, 88, 84, 91, 87, 80, 83, 89,
-  80, 93, 83, 76, 89, 83, 93, 80, 86, 80,
-  88, 82, 85, 74, 86, 87, 81, 99, 84, 82,
-  78, 76, 85, 97, 86, 93, 78, 90, 74, 78,
-  85, 86, 85, 83, 85, 75, 73, 78, 89, 86,
-  81, 79, 90, 86, 90, 84, 87, 69, 88, 86,
-  76, 80, 86, 81, 87, 83, 77, 85, 78, 84,
-  77, 87, 97, 102, 85, 84, 86, 87, 82, 83,
-  71, 92, 71, 85, 55, 88, 86, 106, 87, 67,
-  88, 84, 82, 77, 96, 90, 79, 95, 79, 73,
-  67, 72, 107, 98, 83, 97, 75, 82, 90, 83,
-  101, 72, 113, 93, 89, 78, 92, 74, 79, 88,
-  74, 120, 91, 75, 113, 67, 92, 93, 61, 95,
-  63, 105, 94, 75, 90, 106, 77, 103, 96, 92,
-  89, 85, 108, 76, 76, 100, 128, 75, 90, 76,
-  82, 91, 70, 77, 98, 90, 61, 71, 85, 82,
-  71, 84, 114, 75, 84, 91, 101, 82, 83, 87,
-  98, 97, 80, 115, 93, 78, 55, 75, 78, 91,
-  92, 85, 63, 123, 81, 81, 86, 87, 77, 71,
-  99, 96, 122, 60, 122, 86, 94, 96, 87, 87,
-  85, 77, 89, 89, 100, 74, 109, 70, 83, 76,
-  93, 77, 61, 79, 77, 109, 86, 64, 82, 79,
-  78, 84, 92, 90, 72, 93, 81, 77, 71, 72,
-  101, 93, 93, 85, 74, 77, 86, 87, 98, 70,
-  70, 95, 85, 76, 81, 77, 82, 75, 74, 112,
-  91, 78, 99, 64, 86, 88, 64, 86, 56, 95,
-  87, 78, 80, 102, 74, 100, 90, 92, 85, 79,
-  94, 81, 76, 89, 128, 70, 95, 77, 79, 90,
-  73, 79, 92, 98, 61, 77, 86, 80, 74, 85,
-  106, 79, 80, 85, 95, 79, 75, 90, 97, 91,
-  68, 111, 80, 82, 58, 74, 79, 82, 87, 88,
-  74, 109, 85, 77, 85, 83, 74, 68, 91, 91,
-  122, 64, 120, 87, 85, 91, 84, 82, 84, 78,
-  90, 87, 110, 80, 102, 74, 81, 80, 90, 72,
-  66, 76, 73, 100, 83, 73, 86, 83, 83, 80,
-  87, 88, 77, 85, 81, 78, 74, 79, 97, 87,
-  89, 83, 77, 85, 84, 80, 99, 72, 101, 89,
-  80, 75, 83, 81, 77, 73, 74, 103, 87, 81,
-  101, 67, 83, 91, 67, 93, 61, 91, 88, 77,
-  84, 98, 79, 87, 95, 83, 88, 82, 98, 80,
-  77, 90, 120, 74, 83, 76, 82, 86, 77, 79,
-  90, 91, 64, 74, 97, 80, 79, 92, 96, 79,
-  79, 90, 87, 80, 79, 89, 96, 89, 81, 102,
-  86, 79, 61, 74, 82, 80, 83, 85, 94, 101,
-  83, 79, 82, 83, 78, 72, 96, 90, 110, 74,
-  104, 82, 85, 86, 77, 85, 93, 76, 89, 88,
-  104, 77, 92, 69, 85, 80, 85, 74, 82, 80,
-  83, 99, 78, 77, 86, 89, 77, 85, 86, 82,
-  90, 89, 87, 76, 72, 94, 93, 84, 78, 82,
-  80, 91, 88, 91, 94, 67, 98, 91, 90, 69,
-  81, 73, 79, 81, 82, 90, 82, 80, 87, 69,
-  84, 79, 93, 90, 64, 84, 83, 85, 83, 93,
-  81, 69, 93, 74, 86, 91, 67, 87, 86, 82,
-  112, 83, 76, 85, 73, 81, 64, 92, 80, 83,
-  75, 81, 81, 85, 83, 79, 90, 82, 92, 84,
-  74, 73, 79, 86, 90, 82, 81, 101, 68, 82,
-  58, 81, 85, 81, 76, 89, 53, 75, 87, 81,
-  84, 82, 70, 56, 98, 83, 105, 90, 118, 81,
-  79, 85, 84, 73, 82, 79, 82, 83, 109, 93,
-  60, 82, 82, 87, 74, 80, 90, 74, 75, 97,
-  75, 77, 86, 87, 75, 92, 83, 87, 87, 81,
-  90, 82, 78, 89, 84, 81, 88, 76, 84, 93,
-  77, 94, 99, 67, 79, 87, 83, 64, 79, 76,
-  78, 69, 82, 87, 81, 81, 81, 73, 75, 77,
-  98, 92, 52, 78, 81, 85, 78, 87, 77, 67,
-  86, 84, 85, 86, 66, 88, 86, 78, 101, 85,
-  73, 86, 68, 80, 66, 95, 79, 85, 78, 81,
-  81, 82, 87, 76, 86, 87, 88, 84, 75, 74,
-  82, 87, 86, 80, 75, 107, 56, 85, 54, 83,
-  89, 79, 74, 94, 65, 68, 85, 79, 85, 80,
-  75, 60, 90, 79, 109, 97, 110, 79, 77, 88,
-  79, 71, 74, 81, 80, 83, 96, 103, 56, 84,
-  79, 86, 73, 81, 87, 76, 70, 93, 78, 82,
-  87, 86, 77, 86, 79, 82, 87, 77, 83, 83,
-  76, 91, 84, 80, 88, 78, 84, 94, 75, 83,
-  95, 71, 93, 85, 85, 67, 83, 81, 86, 77,
-  82, 88, 81, 83, 83, 73, 79, 83, 89, 91,
-  58, 82, 81, 81, 79, 88, 81, 66, 86, 86,
-  87, 92, 69, 88, 87, 82, 102, 84, 75, 84,
-  69, 80, 75, 91, 82, 82, 75, 81, 93, 83,
-  84, 80, 89, 83, 85, 88, 74, 80, 83, 85,
-  82, 83, 85, 96, 67, 82, 59, 80, 90, 75,
-  78, 87, 82, 72, 89, 86, 86, 81, 74, 64,
-  98, 82, 100, 95, 97, 77, 78, 85, 74, 72,
-  82, 81, 81, 87, 83, 96, 58, 79, 83, 85,
-  73, 78, 87, 85, 85, 87, 82, 97, 83, 83,
-  86, 86, 73, 82, 96, 83, 88, 79, 61, 101,
-  75, 92, 70, 76, 87, 107, 90, 81, 92, 71,
-  85, 88, 80, 77, 90, 90, 89, 83, 81, 83,
-  75, 90, 69, 84, 85, 80, 94, 90, 75, 83,
-  91, 83, 87, 86, 92, 56, 92, 78, 89, 91,
-  59, 85, 87, 96, 81, 93, 76, 94, 73, 79,
-  73, 87, 86, 86, 87, 82, 87, 91, 91, 82,
-  84, 81, 82, 84, 69, 82, 85, 90, 90, 78,
-  83, 97, 68, 79, 70, 84, 87, 83, 79, 90,
-  67, 68, 79, 88, 82, 85, 70, 77, 90, 84,
-  91, 105, 105, 78, 78, 89, 83, 82, 80, 85,
-  82, 86, 90, 92, 43, 83, 90, 96, 68, 80,
-  90, 83, 80, 88, 87, 102, 80, 79, 83, 92,
-  72, 87, 95, 81, 88, 87, 66, 92, 68, 93,
-  80, 75, 100, 107, 82, 79, 85, 70, 80, 87,
-  77, 73, 83, 90, 87, 80, 85, 86, 78, 93,
-  70, 85, 74, 83, 93, 89, 73, 78, 89, 84,
-  80, 83, 88, 61, 92, 83, 88, 88, 61, 85,
-  91, 90, 77, 94, 77, 95, 74, 78, 80, 90,
-  85, 85, 88, 81, 92, 85, 94, 81, 79, 82,
-  79, 85, 66, 74, 93, 92, 90, 88, 78, 87,
-  57, 84, 67, 86, 91, 79, 85, 90, 82, 68,
-  76, 93, 84, 82, 76, 76, 84, 83, 83, 109,
-  94, 79, 79, 89, 81, 88, 81, 87, 81, 86,
-  77, 96, 41, 86, 93, 93, 74, 84, 92, 79,
-  80, 90, 83, 93, 83, 78, 83, 83, 69, 86,
-  93, 76, 82, 85, 61, 93, 75, 86, 84, 76,
-  92, 105, 81, 79, 88, 71, 81, 88, 82, 73,
-  88, 90, 88, 81, 81, 83, 80, 91, 74, 86,
-  75, 82, 91, 85, 73, 82, 87, 80, 84, 85,
-  89, 61, 92, 88, 92, 91, 60, 84, 87, 92,
-  82, 91, 74, 92, 64, 77, 78, 85, 79, 83,
-  83, 82, 93, 91, 88, 80, 80, 78, 77, 86,
-  71, 74, 91, 90, 84, 85, 85, 91, 72, 82,
-  69, 82, 88, 76, 83, 87, 91, 75, 81, 90,
-  86, 83, 72, 75, 89, 84, 87, 101, 92, 76,
-  74, 86, 80, 79, 90, 85, 83, 85, 83, 87,
-  53, 87, 93, 90, 69, 77, 88, 84, 86, 87,
-  74, 85, 73, 81, 78, 91, 88, 85, 79, 70,
-  82, 82, 77, 104, 86, 81, 86, 73, 87, 86,
-  95, 83, 73, 78, 92, 99, 101, 84, 82, 84,
-  90, 78, 87, 81, 83, 83, 79, 83, 77, 81,
-  74, 71, 90, 84, 79, 88, 70, 86, 88, 80,
-  86, 71, 70, 78, 65, 85, 89, 85, 88, 84,
-  76, 87, 84, 85, 88, 95, 70, 82, 75, 93,
-  80, 76, 84, 85, 93, 85, 84, 72, 72, 90,
-  93, 73, 92, 96, 74, 78, 78, 74, 70, 71,
-  75, 81, 86, 84, 70, 68, 76, 79, 87, 78,
-  87, 94, 80, 89, 72, 95, 80, 86, 99, 72,
-  86, 79, 81, 90, 90, 105, 92, 88, 80, 90,
-  81, 89, 91, 80, 80, 86, 72, 86, 79, 73,
-  77, 85, 79, 87, 87, 82, 76, 72, 80, 83,
-  77, 96, 86, 83, 80, 82, 79, 81, 84, 87,
-  75, 78, 87, 95, 103, 88, 83, 79, 91, 75,
-  92, 79, 72, 79, 76, 83, 88, 87, 76, 71,
-  93, 82, 76, 86, 79, 86, 90, 86, 81, 77,
-  72, 77, 64, 89, 97, 92, 88, 88, 71, 87,
-  82, 87, 93, 79, 74, 77, 73, 92, 85, 78,
-  85, 89, 104, 85, 88, 72, 76, 81, 93, 73,
-  78, 93, 77, 80, 76, 78, 74, 69, 81, 77,
-  90, 90, 81, 72, 74, 81, 84, 80, 86, 92,
-  85, 89, 78, 92, 78, 89, 95, 77, 81, 76,
-  71, 89, 92, 108, 90, 90, 83, 89, 82, 86,
-  93, 82, 85, 83, 66, 86, 79, 81, 74, 88,
-  83, 91, 88, 83, 75, 81, 82, 85, 85, 105,
-  85, 83, 78, 84, 87, 84, 69, 82, 78, 81,
-  87, 88, 91, 87, 85, 84, 99, 76, 92, 80,
-  69, 81, 79, 85, 95, 84, 76, 74, 90, 87,
-  73, 89, 74, 86, 88, 78, 92, 83, 68, 76,
-  69, 86, 90, 83, 87, 83, 85, 88, 75, 88,
-  92, 82, 88, 85, 79, 90, 93, 77, 82, 93,
-  102, 89, 87, 70, 77, 72, 89, 71, 77, 95,
-  77, 84, 77, 87, 73, 75, 90, 82, 84, 88,
-  84, 73, 81, 88, 88, 79, 83, 91, 81, 89,
-  69, 97, 77, 90, 95, 95, 77, 76, 70, 88,
-  87, 103, 83, 84, 85, 92, 78, 80, 92, 81,
-  80, 85, 95, 104, 74, 88, 79, 71, 97, 82,
-  74, 80, 90, 68, 72, 108, 81, 82, 76, 77,
-  88, 71, 79, 89, 98, 83, 80, 68, 89, 86,
-  95, 78, 80, 86, 85, 74, 79, 90, 92, 82,
-  79, 90, 70, 96, 72, 91, 101, 82, 84, 77,
-  77, 86, 86, 91, 77, 83, 77, 85, 77, 100,
-  77, 81, 70, 80, 71, 76, 94, 86, 91, 60,
-  77, 77, 69, 75, 78, 76, 88, 101, 85, 89,
-  81, 86, 84, 77, 97, 91, 87, 71, 90, 73,
-  59, 78, 69, 78, 59, 71, 88, 70, 73, 82,
-  61, 84, 86, 70, 87, 111, 83, 83, 70, 75,
-  83, 73, 87, 66, 97, 83, 81, 87, 95, 103,
-  90, 83, 80, 91, 91, 88, 79, 81, 66, 88,
-  83, 94, 79, 79, 78, 76, 99, 77, 73, 79,
-  67, 82, 70, 108, 78, 75, 68, 79, 75, 95,
-  77, 91, 78, 81, 88, 67, 81, 79, 84, 75,
-  74, 88, 72, 67, 84, 93, 81, 83, 88, 85,
-  71, 85, 72, 81, 100, 87, 80, 73, 85, 101,
-  92, 92, 73, 90, 90, 84, 79, 103, 83, 106,
-  73, 90, 71, 85, 95, 93, 105, 58, 85, 68,
-  68, 69, 77, 83, 83, 83, 94, 91, 80, 89,
-  91, 75, 92, 101, 71, 61, 90, 69, 66, 82,
-  70, 72, 66, 63, 85, 78, 84, 104, 63, 94,
-  82, 74, 88, 126, 87, 75, 68, 67, 75, 76,
-  81, 64, 98, 80, 83, 91, 98, 105, 78, 81,
-  80, 85, 84, 83, 72, 88, 75, 102, 74, 101,
-  79, 83, 79, 75, 95, 83, 74, 80, 93, 92,
-  73, 110, 89, 85, 77, 78, 71, 76, 90, 91,
-  73, 85, 84, 73, 85, 84, 91, 88, 80, 93,
-  89, 68, 81, 89, 70, 88, 79, 90, 92, 98,
-  71, 81, 98, 98, 75, 80, 81, 86, 88, 89,
-  75, 83, 77, 91, 78, 98, 77, 78, 71, 81,
-  77, 77, 84, 85, 92, 61, 84, 74, 73, 73,
-  84, 74, 80, 85, 93, 91, 88, 83, 84, 76,
-  98, 94, 79, 70, 90, 78, 62, 80, 68, 80,
-  62, 68, 84, 75, 97, 71, 67, 96, 85, 72,
-  82, 105, 86, 81, 70, 80, 78, 81, 87, 89,
-  91, 72, 78, 88, 96, 102, 73, 82, 78, 90,
-  89, 80, 79, 82, 84, 93, 101, 100, 77, 93,
-  75, 79, 104, 80, 69, 82, 104, 82, 72, 94,
-  82, 64, 74, 82, 90, 91, 87, 77, 87, 80,
-  92, 73, 87, 81, 82, 79, 75, 74, 91, 91,
-  81, 89, 83, 85, 85, 100, 96, 90, 84, 91,
-  82, 88, 86, 82, 100, 84, 91, 99, 80, 73,
-  87, 78, 97, 98, 77, 81, 77, 73, 76, 71,
-  74, 93, 84, 71, 68, 79, 86, 84, 73, 97,
-  98, 108, 74, 90, 73, 89, 98, 79, 89, 93,
-  83, 69, 85, 77, 60, 91, 87, 77, 69, 67,
-  84, 75, 67, 102, 77, 86, 86, 68, 80, 111,
-  88, 79, 70, 81, 80, 69, 83, 75, 96, 90,
-  91, 86, 92, 127, 88, 87, 88, 80, 93, 79,
-  71, 88, 68, 80, 69, 77, 75, 95, 73, 77,
-  100, 79, 68, 79, 64, 82, 74, 79, 74, 60,
-  64, 79, 102, 120, 93, 79, 78, 76, 106, 74,
-  78, 75, 75, 72, 72, 77, 79, 84, 82, 93,
-  85, 76, 97, 95, 87, 71, 101, 99, 76, 90,
-  77, 79, 104, 92, 91, 91, 84, 86, 102, 69,
-  115, 106, 82, 112, 79, 81, 79, 80, 72, 108,
-  87, 72, 87, 75, 102, 89, 67, 117, 100, 92,
-  76, 87, 67, 81, 99, 85, 76, 94, 69, 64,
-  73, 74, 73, 99, 83, 76, 74, 58, 77, 91,
-  69, 135, 88, 100, 91, 72, 87, 140, 98, 68,
-  70, 73, 68, 71, 83, 72, 85, 102, 99, 93,
-  97, 149, 89, 83, 84, 73, 83, 73, 73, 99,
-  85, 81, 78, 93, 77, 83, 74, 75, 105, 82,
-  71, 76, 102, 76, 72, 99, 84, 63, 73, 76,
-  90, 78, 92, 82, 76, 80, 92, 75, 82, 90,
-  84, 91, 76, 95, 89, 78, 84, 90, 79, 89,
-  85, 89, 87, 90, 85, 90, 80, 98, 88, 85,
-  101, 79, 91, 94, 79, 96, 82, 84, 101, 99,
-  75, 80, 77, 70, 81, 73, 75, 90, 85, 71,
-  96, 78, 88, 85, 64, 93, 95, 83, 90, 89,
-  77, 89, 93, 94, 89, 93, 81, 71, 84, 80,
-  64, 92, 85, 79, 65, 65, 83, 77, 87, 87,
-  78, 94, 86, 70, 83, 104, 91, 77, 72, 82,
-  76, 70, 83, 96, 79, 86, 79, 88, 90, 121,
-  81, 90, 90, 79, 92, 75, 70, 87, 90, 88,
-  71, 70, 83, 78, 105, 82, 80, 69, 79, 84,
-  81, 90, 90, 87, 91, 100, 81, 90, 88, 85,
-  75, 93, 80, 85, 84, 73, 78, 76, 91, 87,
-  97, 77, 82, 79, 85, 82, 78, 80, 91, 68,
-  92, 84, 82, 85, 84, 93, 95, 85, 81, 82,
-  76, 92, 78, 90, 95, 91, 78, 86, 83, 92,
-  93, 73, 77, 91, 91, 88, 81, 85, 81, 80,
-  94, 84, 91, 78, 77, 77, 90, 91, 88, 88,
-  79, 74, 96, 77, 91, 77, 79, 85, 82, 81,
-  84, 90, 82, 96, 88, 83, 84, 82, 74, 90,
-  88, 84, 89, 90, 80, 89, 76, 78, 92, 99,
-  83, 89, 88, 100, 78, 89, 83, 86, 86, 88,
-  76, 82, 82, 86, 91, 86, 78, 92, 85, 87,
-  74, 83, 94, 84, 94, 77, 81, 75, 74, 101,
-  86, 94, 76, 69, 92, 90, 89, 88, 66, 101,
-  87, 85, 83, 78, 77, 69, 86, 86, 78, 79,
-  76, 82, 83, 86, 74, 65, 85, 51, 76, 83,
-  76, 89, 93, 87, 96, 72, 91, 91, 85, 74,
-  94, 83, 100, 80, 92, 85, 85, 92, 93, 76,
-  65, 63, 85, 76, 80, 79, 73, 79, 102, 83,
-  84, 82, 72, 75, 85, 70, 89, 85, 81, 70,
-  81, 83, 84, 94, 85, 84, 84, 84, 82, 88,
-  92, 69, 85, 80, 77, 83, 75, 78, 78, 83,
-  80, 89, 79, 87, 80, 71, 82, 86, 80, 90,
-  75, 99, 87, 83, 85, 86, 83, 85, 85, 82,
-  85, 83, 82, 78, 84, 81, 94, 87, 75, 95,
-  85, 84, 94, 88, 80, 73, 80, 112, 70, 87,
-  71, 62, 90, 87, 72, 88, 87, 101, 87, 82,
-  95, 84, 82, 80, 81, 92, 68, 76, 88, 99,
-  102, 89, 82, 75, 84, 63, 80, 85, 78, 96,
-  83, 102, 88, 70, 99, 96, 89, 68, 106, 85,
-  93, 70, 98, 84, 85, 80, 88, 70, 67, 65,
-  78, 73, 83, 79, 94, 95, 96, 94, 77, 80,
-  74, 80, 82, 78, 90, 87, 83, 87, 73, 90,
-  88, 102, 90, 80, 88, 91, 87, 80, 99, 70,
-  88, 76, 86, 92, 85, 93, 86, 82, 80, 91,
-  78, 87, 76, 70, 89, 75, 75, 96, 80, 96,
-  85, 85, 78, 94, 81, 82, 76, 79, 95, 91,
-  84, 83, 88, 88, 80, 87, 73, 79, 76, 79,
-  92, 82, 75, 85, 85, 112, 85, 95, 93, 87,
-  91, 85, 90, 85, 86, 100, 84, 86, 81, 82,
-  89, 74, 77, 87, 76, 68, 71, 76, 84, 86,
-  79, 92, 83, 68, 80, 81, 76, 91, 84, 90,
-  89, 77, 74, 89, 90, 72, 86, 66, 89, 67,
-  85, 81, 83, 78, 88, 54, 66, 61, 94, 81,
-  73, 100, 62, 78, 92, 81, 81, 85, 73, 79,
-  72, 85, 91, 86, 89, 75, 78, 85, 95, 88,
-  83, 87, 86, 78, 80, 93, 95, 77, 82, 81,
-  75, 84, 75, 71, 80, 81, 84, 75, 83, 87,
-  74, 71, 87, 76, 81, 95, 83, 103, 88, 84,
-  77, 95, 88, 86, 84, 80, 89, 79, 87, 85,
-  76, 69, 124, 86, 73, 94, 64, 76, 95, 88,
-  68, 77, 80, 143, 77, 75, 79, 73, 88, 83,
-  83, 92, 114, 99, 88, 76, 92, 79, 146, 82,
-  77, 86, 54, 69, 68, 79, 97, 78, 68, 74,
-  91, 61, 64, 80, 81, 93, 94, 96, 80, 73,
-  74, 109, 94, 58, 97, 46, 92, 53, 89, 75,
-  94, 84, 85, 51, 46, 52, 80, 71, 79, 111,
-  41, 74, 85, 88, 82, 72, 74, 80, 79, 69,
-  84, 83, 86, 88, 70, 91, 90, 116, 80, 82,
-  73, 72, 84, 75, 91, 63, 79, 73, 64, 75,
-  79, 60, 76, 81, 75, 86, 90, 87, 81, 69,
-  93, 67, 72, 91, 97, 96, 120, 74, 71, 92,
-  76, 86, 68, 72, 91, 83, 78, 87, 77, 64,
-  92, 78, 81, 87, 76, 81, 88, 88, 77, 76,
-  91, 101, 90, 74, 78, 83, 87, 85, 84, 80,
-  102, 92, 103, 99, 82, 78, 114, 86, 79, 93,
-  67, 73, 93, 88, 112, 83, 80, 78, 85, 71,
-  78, 84, 89, 100, 84, 89, 75, 79, 87, 93,
-  95, 74, 99, 66, 88, 64, 88, 88, 93, 88,
-  89, 59, 62, 63, 81, 87, 79, 82, 74, 88,
-  85, 92, 91, 82, 72, 78, 84, 88, 87, 88,
-  86, 93, 72, 83, 91, 88, 75, 99, 87, 74,
-  86, 87, 92, 81, 94, 90, 78, 78, 82, 72,
-  87, 81, 87, 88, 72, 91, 79, 70, 88, 67,
-  81, 88, 93, 80, 79, 84, 69, 83, 83, 81,
-  75, 79, 101, 87, 89, 93, 87, 86, 70, 81,
-  82, 94, 74, 83, 96, 94, 77, 75, 81, 112,
-  65, 79, 89, 65, 89, 85, 75, 94, 82, 93,
-  77, 84, 88, 90, 88, 77, 79, 89, 58, 66,
-  88, 91, 94, 85, 90, 91, 82, 71, 82, 77,
-  75, 83, 79, 93, 93, 69, 87, 85, 87, 70,
-  99, 80, 86, 67, 101, 84, 87, 86, 94, 67,
-  74, 67, 83, 81, 82, 93, 93, 83, 92, 84,
-  82, 87, 74, 108, 91, 75, 92, 79, 93, 80,
-  75, 93, 88, 108, 84, 79, 92, 81, 87, 81,
-  100, 71, 79, 79, 85, 93, 86, 88, 97, 82,
-  87, 75, 79, 103, 90, 69, 72, 78, 83, 94,
-  88, 100, 96, 80, 80, 93, 85, 92, 81, 78,
-  94, 85, 86, 89, 74, 76, 85, 81, 74, 97,
-  82, 82, 95, 89, 79, 74, 78, 96, 82, 76,
-  85, 79, 94, 82, 82, 79, 85, 91, 87, 95,
-  81, 80, 102, 70, 89, 82, 67, 86, 81, 86,
-  84, 88, 76, 75, 92, 62, 68, 75, 81, 88,
-  91, 89, 86, 76, 98, 81, 94, 76, 96, 72,
-  89, 78, 88, 92, 90, 90, 91, 79, 67, 60,
-  82, 91, 86, 76, 71, 73, 95, 91, 90, 87,
-  83, 86, 95, 67, 95, 85, 89, 79, 78, 89,
-  85, 90, 89, 86, 96, 78, 90, 86, 99, 71,
-  87, 88, 77, 87, 82, 84, 86, 80, 84, 87,
-  77, 102, 87, 73, 77, 86, 77, 80, 90, 81,
-  87, 78, 77, 79, 79, 84, 77, 81, 88, 91,
-  85, 86, 85, 82, 68, 78, 81, 81, 95, 89,
-  75, 85, 82, 82, 80, 70, 98, 85, 86, 96,
-  79, 90, 86, 78, 89, 78, 81, 96, 80, 73,
-  61, 67, 89, 86, 96, 86, 97, 87, 81, 84,
-  83, 77, 78, 66, 83, 84, 82, 89, 81, 86,
-  88, 84, 86, 78, 87, 88, 87, 81, 81, 93,
-  73, 81, 86, 93, 86, 82, 84, 83, 90, 81,
-  90, 83, 86, 80, 79, 93, 90, 77, 82, 90,
-  92, 79, 99, 86, 83, 76, 85, 85, 80, 74,
-  78, 86, 96, 76, 93, 92, 80, 80, 94, 90,
-  81, 79, 74, 93, 84, 85, 73, 85, 63, 96,
-  62, 70, 84, 88, 75, 83, 98, 77, 56, 88,
-  73, 76, 72, 82, 69, 79, 78, 91, 80, 90,
-  95, 94, 79, 93, 88, 81, 85, 89, 73, 82,
-  84, 85, 79, 81, 81, 77, 82, 84, 116, 76,
-  90, 83, 77, 89, 83, 86, 75, 119, 96, 76,
-  72, 84, 81, 81, 85, 78, 81, 80, 82, 84,
-  88, 79, 82, 88, 92, 93, 82, 79, 88, 77,
-  82, 71, 77, 81, 80, 81, 80, 75, 83, 81,
-  74, 73, 90, 82, 89, 86, 84, 75, 88, 73,
-  79, 77, 83, 68, 85, 72, 84, 79, 80, 82,
-  84, 75, 78, 88, 81, 79, 82, 78, 90, 82,
-  71, 88, 87, 85, 82, 93, 115, 75, 78, 99,
-  77, 84, 84, 77, 76, 81, 73, 84, 84, 85,
-  84, 92, 88, 81, 88, 87, 86, 97, 81, 80,
-  68, 89, 81, 105, 75, 82, 94, 72, 93, 85,
-  80, 95, 87, 82, 76, 99, 75, 104, 90, 87,
-  83, 84, 78, 75, 86, 75, 139, 80, 85, 84,
-  82, 94, 84, 79, 76, 130, 77, 77, 67, 75,
-  87, 84, 80, 88, 76, 77, 82, 75, 89, 78,
-  83, 83, 97, 96, 78, 81, 91, 78, 84, 67,
-  74, 83, 74, 84, 83, 74, 81, 83, 73, 76,
-  94, 79, 90, 84, 78, 71, 82, 73, 79, 78,
-  90, 69, 80, 78, 91, 81, 78, 89, 82, 73,
-  81, 84, 79, 78, 81, 81, 86, 77, 76, 88,
-  87, 80, 82, 93, 133, 76, 80, 102, 76, 81,
-  115, 79, 74, 76, 76, 89, 79, 83, 83, 91,
-  101, 85, 88, 85, 89, 105, 88, 84, 75, 85,
-  77, 121, 76, 79, 99, 78, 92, 83, 84, 85,
-  88, 77, 86, 90, 73, 80, 86, 84, 82, 82,
-  81, 77, 83, 83, 112, 81, 87, 82, 83, 90,
-  90, 86, 79, 114, 93, 82, 69, 78, 83, 82,
-  84, 88, 79, 78, 79, 82, 84, 76, 86, 87,
-  95, 87, 78, 79, 91, 80, 76, 72, 78, 76,
-  79, 87, 84, 75, 81, 81, 73, 73, 89, 82,
-  92, 87, 84, 75, 90, 82, 84, 79, 82, 75,
-  84, 72, 83, 80, 76, 80, 85, 74, 75, 79,
-  79, 80, 76, 78, 89, 81, 71, 80, 91, 88,
-  72, 93, 109, 72, 86, 93, 78, 77, 82, 78,
-  75, 82, 75, 83, 84, 86, 81, 90, 93, 81,
-  85, 87, 82, 94, 80, 78, 80, 88, 79, 103,
-  77, 85, 93, 71, 91, 91, 77, 100, 89, 73,
-  83, 83, 72, 95, 92, 82, 75, 80, 79, 80,
-  85, 86, 127, 79, 92, 86, 85, 90, 84, 82,
-  73, 126, 79, 77, 70, 85, 88, 85, 75, 76,
-  85, 77, 82, 77, 86, 72, 81, 83, 86, 90,
-  82, 79, 88, 77, 78, 73, 76, 81, 75, 76,
-  83, 71, 86, 79, 74, 72, 88, 78, 94, 87,
-  84, 76, 89, 74, 83, 70, 78, 70, 87, 78,
-  83, 76, 87, 79, 81, 75, 78, 86, 84, 78,
-  80, 77, 85, 78, 67, 84, 80, 79, 87, 90,
-  119, 79, 83, 90, 87, 84, 101, 77, 71, 80,
-  74, 85, 87, 86, 79, 88, 86, 81, 86, 92,
-  89, 100, 85, 87, 79, 91, 85, 116, 72, 82,
-  93, 78, 99, 84, 83, 116, 94, 78, 72, 96,
-  78, 134, 101, 89, 81, 82, 79, 76, 90, 75,
-  172, 82, 88, 95, 81, 96, 89, 76, 76, 147,
-  59, 78, 68, 80, 100, 93, 72, 94, 91, 76,
-  85, 67, 82, 75, 79, 74, 88, 89, 77, 74,
-  88, 81, 76, 67, 75, 86, 74, 79, 93, 70,
-  84, 83, 76, 70, 93, 86, 86, 86, 78, 76,
-  86, 73, 74, 72, 85, 69, 82, 97, 97, 80,
-  78, 82, 78, 75, 92, 81, 88, 69, 80, 85,
-  81, 79, 78, 79, 76, 74, 101, 83, 150, 80,
-  79, 95, 88, 79, 152, 79, 71, 86, 78, 89,
-  91, 86, 76, 81, 105, 80, 87, 88, 84, 115,
-  93, 90, 86, 93, 84, 141, 76, 76, 105, 89,
-  86, 80, 91, 94, 89, 83, 84, 86, 73, 95,
-  94, 84, 79, 84, 79, 80, 85, 90, 126, 80,
-  90, 84, 80, 90, 91, 83, 76, 122, 78, 78,
-  73, 84, 91, 88, 82, 95, 81, 75, 78, 75,
-  84, 72, 89, 83, 88, 91, 81, 72, 89, 82,
-  71, 71, 78, 80, 74, 82, 85, 72, 79, 83,
-  77, 76, 89, 81, 94, 86, 85, 78, 89, 80,
-  82, 73, 77, 77, 83, 77, 83, 77, 79, 77,
-  81, 72, 79, 82, 83, 78, 81, 76, 84, 79,
-  69, 82, 81, 80, 75, 92, 113, 76, 86, 88,
-  88, 82, 94, 79, 71, 78, 76, 81, 86, 88,
-  79, 90, 92, 79, 83, 94, 77, 94, 84, 87,
-  84, 91, 81, 111, 76, 87, 95, 77, 88, 90,
-  81, 89, 85, 77, 90, 71, 76, 79, 89, 81,
-  81, 77, 78, 79, 87, 90, 107, 77, 83, 82,
-  80, 96, 90, 80, 75, 116, 98, 82, 75, 89,
-  81, 85, 77, 81, 84, 77, 87, 75, 86, 86,
-  81, 84, 89, 86, 86, 81, 82, 80, 83, 76,
-  82, 75, 75, 79, 82, 74, 89, 83, 76, 77,
-  85, 81, 91, 85, 78, 75, 88, 79, 82, 77,
-  71, 77, 89, 78, 76, 74, 88, 87, 80, 82,
-  73, 78, 88, 79, 77, 78, 85, 77, 67, 82,
-  87, 87, 84, 85, 110, 80, 89, 96, 81, 85,
-  74, 74, 72, 77, 73, 83, 73, 86, 82, 96,
-  81, 84, 83, 94, 82, 94, 85, 80, 82, 90,
-  81, 85, 75, 94, 82, 72, 89, 86, 91, 96,
-  93, 77, 83, 74, 80, 91, 85, 80, 78, 81,
-  88, 79, 88, 88, 115, 79, 85, 84, 80, 101,
-  93, 79, 76, 118, 78, 78, 68, 86, 84, 91,
-  76, 86, 83, 78, 88, 71, 84, 84, 82, 81,
-  86, 89, 86, 83, 87, 81, 81, 72, 82, 79,
-  71, 78, 87, 74, 88, 84, 73, 75, 87, 77,
-  94, 84, 78, 72, 94, 87, 80, 71, 73, 82,
-  93, 83, 80, 79, 85, 89, 80, 81, 74, 76,
-  87, 73, 83, 78, 84, 77, 69, 81, 86, 80,
-  91, 82, 116, 77, 90, 95, 86, 78, 92, 75,
-  72, 84, 75, 84, 74, 87, 84, 95, 88, 85,
-  83, 94, 79, 94, 83, 79, 84, 91, 81, 96,
-  79, 103, 86, 74, 86, 85, 88, 83, 86, 74,
-  92, 74, 76, 81, 90, 84, 80, 82, 80, 79,
-  85, 89, 107, 79, 84, 85, 80, 94, 89, 81,
-  74, 111, 94, 74, 81, 83, 80, 89, 82, 81,
-  83, 76, 79, 77, 86, 88, 82, 83, 91, 88,
-  83, 83, 81, 81, 81, 77, 79, 72, 75, 77,
-  85, 75, 87, 86, 79, 79, 87, 81, 91, 87,
-  79, 76, 90, 82, 81, 78, 74, 82, 86, 80,
-  78, 81, 83, 86, 81, 83, 71, 75, 89, 81,
-  82, 76, 86, 74, 65, 81, 88, 87, 80, 88,
-  110, 81, 90, 94, 83, 79, 72, 74, 73, 76,
-  75, 81, 73, 90, 87, 95, 83, 80, 85, 97,
-  74, 92, 85, 77, 85, 90, 77, 87, 79, 100,
-  86, 72, 89, 77, 78, 93, 66, 85, 95, 85,
-  69, 75, 88, 76, 69, 74, 89, 85, 77, 85,
-  84, 92, 82, 76, 81, 80, 76, 90, 90, 75,
-  90, 102, 88, 85, 84, 77, 80, 70, 72, 80,
-  73, 78, 76, 89, 83, 99, 76, 85, 84, 89,
-  93, 105, 71, 82, 90, 99, 84, 83, 71, 105,
-  73, 80, 85, 81, 72, 81, 89, 109, 100, 74,
-  82, 86, 81, 91, 80, 80, 88, 101, 95, 79,
-  71, 98, 108, 61, 77, 84, 92, 76, 81, 68,
-  100, 70, 91, 86, 79, 73, 92, 83, 85, 80,
-  78, 77, 94, 87, 79, 85, 87, 76, 80, 113,
-  75, 69, 86, 68, 75, 85, 85, 94, 95, 80,
-  87, 73, 56, 78, 71, 77, 113, 87, 74, 95,
-  85, 81, 76, 87, 63, 80, 98, 90, 72, 75,
-  93, 78, 72, 71, 90, 88, 82, 81, 88, 99,
-  80, 74, 82, 82, 80, 97, 90, 78, 81, 87,
-  85, 85, 85, 76, 85, 84, 74, 84, 74, 92,
-  78, 92, 85, 100, 81, 79, 83, 83, 91, 111,
-  65, 79, 93, 102, 89, 80, 75, 98, 76, 80,
-  78, 84, 67, 82, 82, 106, 95, 82, 77, 84,
-  79, 92, 85, 81, 91, 108, 96, 85, 77, 103,
-  106, 57, 75, 83, 102, 77, 84, 65, 103, 74,
-  92, 84, 82, 76, 87, 84, 91, 81, 83, 79,
-  99, 96, 86, 81, 89, 72, 81, 114, 82, 69,
-  85, 68, 79, 84, 88, 89, 85, 79, 88, 76,
-  60, 74, 74, 79, 123, 92, 73, 97, 89, 77,
-  77, 88, 68, 82, 94, 92, 66, 77, 86, 77,
-  72, 72, 91, 82, 78, 82, 82, 103, 81, 80,
-  87, 82, 75, 88, 96, 75, 82, 82, 87, 81,
-  86, 75, 94, 83, 72, 81, 78, 78, 79, 87,
-  89, 91, 79, 80, 80, 83, 91, 103, 72, 77,
-  92, 98, 82, 83, 70, 104, 77, 77, 85, 82,
-  71, 84, 92, 102, 96, 76, 81, 87, 79, 90,
-  82, 82, 86, 91, 91, 92, 79, 95, 106, 64,
-  80, 80, 92, 74, 82, 73, 96, 70, 91, 82,
-  80, 74, 81, 81, 84, 81, 87, 81, 93, 103,
-  79, 85, 86, 76, 82, 109, 81, 73, 83, 70,
-  76, 80, 84, 86, 84, 78, 87, 77, 65, 76,
-  69, 79, 107, 88, 77, 97, 96, 80, 75, 86,
-  75, 90, 95, 81, 77, 75, 91, 82, 79, 74,
-  87, 82, 74, 84, 80, 99, 75, 81, 76, 82,
-  80, 86, 84, 70, 77, 88, 84, 76, 84, 83,
-  87, 72, 73, 84, 77, 76, 81, 82, 85, 97,
-  81, 87, 75, 95, 95, 98, 69, 82, 97, 98,
-  88, 82, 78, 106, 73, 95, 94, 75, 76, 86,
-  88, 109, 84, 76, 89, 87, 84, 97, 75, 68,
-  85, 103, 91, 83, 67, 92, 106, 65, 79, 85,
-  92, 78, 80, 64, 85, 75, 87, 80, 81, 79,
-  97, 84, 79, 88, 73, 82, 95, 84, 79, 86,
-  84, 83, 82, 114, 80, 70, 83, 68, 76, 89,
-  86, 87, 96, 78, 85, 80, 59, 80, 81, 75,
-  122, 80, 77, 85, 95, 82, 79, 79, 71, 82,
-  101, 88, 83, 72, 97, 83, 78, 76, 93, 92,
-  78, 86, 78, 108, 81, 80, 78, 88, 82, 95,
-  81, 72, 71, 75, 81, 82, 80, 80, 89, 86,
-  76, 90, 73, 91, 86, 86, 84, 100, 84, 82,
-  74, 88, 100, 107, 66, 86, 100, 103, 97, 77,
-  82, 100, 77, 105, 89, 77, 72, 88, 81, 106,
-  84, 85, 85, 86, 81, 100, 79, 71, 90, 106,
-  93, 83, 68, 95, 103, 67, 75, 79, 101, 81,
-  86, 59, 88, 75, 87, 79, 82, 83, 95, 87,
-  86, 85, 76, 83, 92, 92, 83, 84, 89, 80,
-  81, 115, 82, 70, 84, 68, 82, 87, 85, 84,
-  80, 77, 85, 81, 60, 78, 84, 76, 130, 84,
-  74, 84, 96, 77, 82, 83, 81, 88, 93, 92,
-  76, 77, 87, 83, 75, 77, 89, 80, 78, 83,
-  76, 111, 84, 87, 83, 85, 79, 88, 90, 71,
-  72, 80, 83, 80, 81, 76, 93, 83, 75, 83,
-  74, 80, 81, 80, 83, 91, 80, 82, 74, 92,
-  94, 96, 70, 84, 100, 101, 87, 81, 75, 108,
-  74, 86, 94, 77, 76, 89, 89, 105, 86, 74,
-  86, 89, 82, 91, 80, 70, 87, 92, 89, 95,
-  74, 93, 107, 71, 82, 75, 92, 76, 84, 72,
-  85, 70, 85, 80, 80, 80, 83, 84, 80, 91,
-  80, 81, 91, 98, 79, 86, 86, 80, 79, 108,
-  81, 73, 80, 71, 79, 79, 86, 80, 82, 76,
-  86, 81, 66, 78, 82, 75, 117, 80, 79, 83,
-  96, 79, 83, 88, 64, 88, 87, 77, 71, 80,
-  85, 89, 79, 73, 87, 81, 72, 77, 86, 92,
-  74, 75, 79, 86, 76, 82, 81, 73, 84, 87,
-  83, 78, 92, 84, 94, 71, 78, 82, 87, 66,
-  78, 89, 90, 94, 84, 87, 72, 96, 86, 109,
-  71, 89, 95, 95, 87, 85, 75, 96, 80, 89,
-  99, 76, 77, 84, 88, 105, 80, 74, 89, 91,
-  85, 100, 75, 73, 78, 100, 90, 87, 78, 93,
-  107, 70, 77, 78, 86, 79, 79, 72, 88, 79,
-  88, 83, 85, 73, 95, 85, 78, 90, 75, 77,
-  104, 81, 76, 87, 85, 83, 81, 105, 77, 76,
-  87, 72, 74, 86, 80, 85, 83, 77, 80, 85,
-  68, 74, 71, 77, 110, 80, 77, 90, 95, 81,
-  90, 84, 65, 85, 92, 82, 74, 75, 89, 89,
-  78, 78, 86, 89, 74, 75, 86, 102, 84, 75,
-  83, 87, 76, 89, 80, 74, 79, 79, 87, 82,
-  87, 86, 84, 81, 80, 87, 78, 80, 76, 98,
-  87, 99, 87, 83, 73, 93, 89, 109, 70, 93,
-  95, 98, 93, 82, 82, 91, 81, 88, 97, 77,
-  77, 85, 86, 109, 79, 75, 86, 93, 81, 100,
-  81, 77, 80, 95, 89, 88, 77, 99, 104, 73,
-  73, 78, 92, 84, 82, 65, 94, 80, 86, 84,
-  83, 74, 94, 88, 81, 87, 78, 78, 101, 81,
-  81, 86, 85, 78, 76, 107, 76, 74, 90, 71,
-  79, 84, 81, 80, 80, 77, 82, 84, 69, 75,
-  70, 77, 118, 79, 78, 84, 95, 79, 89, 88,
-  70, 86, 87, 85, 70, 79, 82, 85, 75, 79,
-  83, 74, 71, 79, 84, 104, 85, 75, 83, 89,
-  72, 86, 86, 73, 82, 86, 89, 81, 89, 77,
-  94, 79, 82, 81, 74, 70, 75, 89, 80, 91,
-  83, 83, 76, 90, 88, 106, 72, 86, 96, 94,
-  82, 86, 76, 98, 77, 82, 100, 78, 77, 86,
-  87, 105, 81, 73, 85, 94, 85, 96, 82, 73,
-  80, 94, 89, 89, 82, 94, 108, 74, 78, 79,
-  86, 80, 85, 79, 91, 76, 90, 82, 84, 73,
-  83, 86, 80, 91, 78, 75, 97, 87, 75, 87,
-  86, 81, 78, 102, 79, 76, 85, 74, 78, 77,
-  81, 84, 84, 77, 81, 86, 74, 77, 73, 77,
-  110, 80, 76, 87, 77, 76, 84, 67, 64, 80,
-  78, 96, 76, 88, 92, 75, 84, 95, 63, 80,
-  84, 94, 77, 91, 92, 86, 97, 87, 74, 81,
-  83, 92, 94, 76, 93, 74, 84, 83, 78, 95,
-  88, 79, 80, 68, 88, 72, 82, 77, 96, 75,
-  63, 86, 86, 86, 82, 94, 78, 79, 89, 88,
-  83, 82, 85, 89, 68, 78, 84, 87, 63, 83,
-  91, 86, 80, 99, 87, 73, 92, 89, 74, 84,
-  73, 77, 72, 77, 85, 84, 78, 83, 75, 90,
-  86, 89, 69, 91, 91, 90, 76, 92, 104, 86,
-  84, 74, 87, 104, 89, 79, 83, 80, 74, 71,
-  77, 80, 77, 82, 94, 95, 95, 78, 77, 77,
-  89, 74, 79, 91, 87, 82, 80, 95, 82, 90,
-  94, 83, 83, 81, 87, 67, 62, 89, 75, 96,
-  79, 87, 90, 71, 84, 88, 65, 72, 92, 97,
-  83, 84, 85, 72, 92, 87, 92, 75, 84, 97,
-  104, 79, 98, 81, 84, 80, 83, 83, 96, 83,
-  89, 68, 90, 78, 87, 76, 94, 78, 73, 86,
-  79, 85, 82, 97, 78, 83, 98, 86, 77, 78,
-  74, 87, 70, 71, 77, 79, 57, 80, 87, 78,
-  72, 102, 88, 72, 78, 88, 78, 75, 77, 86,
-  67, 77, 92, 83, 80, 84, 76, 92, 84, 93,
-  76, 87, 75, 106, 71, 88, 103, 79, 98, 75,
-  82, 103, 91, 77, 79, 77, 75, 65, 83, 70,
-  84, 83, 94, 97, 97, 82, 80, 78, 90, 73,
-  84, 89, 80, 81, 80, 87, 74, 91, 100, 82,
-  76, 80, 86, 64, 68, 97, 76, 96, 76, 90,
-  88, 78, 82, 77, 64, 84, 87, 83, 72, 87,
-  89, 86, 81, 87, 82, 82, 82, 90, 80, 76,
-  93, 89, 81, 93, 77, 83, 93, 77, 90, 70,
-  91, 73, 88, 76, 95, 83, 69, 80, 84, 84,
-  74, 89, 75, 83, 87, 78, 81, 84, 85, 88,
-  75, 85, 81, 84, 71, 88, 85, 90, 78, 85,
-  85, 74, 94, 87, 75, 86, 79, 87, 70, 82,
-  87, 83, 88, 89, 74, 85, 82, 86, 77, 94,
-  88, 103, 78, 96, 109, 90, 76, 77, 73, 105,
-  85, 72, 85, 78, 76, 73, 74, 82, 78, 83,
-  100, 93, 95, 89, 83, 85, 85, 77, 81, 95,
-  78, 84, 77, 93, 78, 89, 91, 82, 100, 85,
-  88, 76, 78, 78, 85, 89, 72, 86, 92, 73,
-  89, 104, 69, 72, 92, 100, 89, 92, 74, 82,
-  113, 84, 88, 84, 81, 91, 107, 87, 88, 90,
-  79, 83, 77, 98, 103, 84, 77, 73, 91, 73,
-  75, 77, 69, 83, 98, 85, 88, 81, 84, 89,
-  75, 84, 85, 83, 73, 82, 76, 89, 78, 75,
-  99, 77, 67, 67, 92, 84, 101, 101, 77, 75,
-  80, 84, 82, 75, 78, 87, 80, 80, 89, 85,
-  75, 85, 79, 98, 91, 89, 73, 73, 72, 83,
-  81, 90, 86, 66, 92, 75, 104, 85, 87, 87,
-  85, 77, 86, 59, 88, 86, 84, 79, 72, 80,
-  90, 88, 84, 81, 103, 81, 92, 80, 84, 68,
-  93, 87, 87, 81, 92, 75, 110, 91, 85, 81,
-  84, 81, 87, 90, 70, 79, 91, 62, 94, 94,
-  72, 65, 98, 99, 97, 87, 77, 70, 85, 86,
-  106, 79, 78, 88, 119, 89, 89, 117, 84, 84,
-  80, 88, 106, 93, 85, 80, 88, 69, 71, 82,
-  62, 85, 123, 85, 83, 79, 89, 95, 74, 94,
-  75, 77, 60, 78, 59, 92, 86, 72, 96, 78,
-  63, 63, 97, 90, 103, 82, 85, 68, 67, 75,
-  105, 64, 85, 90, 75, 78, 98, 85, 75, 84,
-  87, 101, 94, 87, 80, 67, 66, 87, 74, 94,
-  73, 65, 96, 77, 100, 82, 75, 95, 83, 77,
-  97, 46, 101, 78, 88, 76, 76, 76, 88, 91,
-  78, 73, 88, 80, 99, 69, 79, 61, 89, 82,
-  78, 81, 102, 71, 90, 90, 79, 72, 82, 110,
-  83, 91, 74, 87, 90, 79, 86, 73, 66, 75,
-  96, 93, 87, 89, 87, 82, 73, 86, 88, 82,
-  83, 91, 95, 76, 87, 104, 79, 90, 77, 82,
-  105, 82, 85, 76, 94, 75, 73, 79, 76, 90,
-  93, 85, 87, 80, 76, 87, 75, 87, 89, 84,
-  74, 81, 73, 83, 77, 73, 98, 77, 71, 74,
-  84, 85, 89, 83, 95, 72, 86, 87, 94, 81,
-  81, 94, 75, 82, 91, 83, 83, 84, 80, 91,
-  92, 86, 82, 75, 79, 104, 81, 89, 103, 71,
-  89, 80, 75, 88, 90, 88, 84, 76, 82, 69,
-  85, 86, 83, 84, 83, 81, 91, 95, 88, 85,
-  79, 81, 88, 80, 79, 70, 85, 87, 85, 81,
-  92, 74, 83, 84, 92, 82, 91, 84, 85, 97,
-  64, 85, 91, 70, 77, 85, 78, 75, 96, 83,
-  77, 86, 71, 83, 80, 79, 102, 85, 82, 83,
-  86, 77, 80, 94, 84, 96, 97, 97, 80, 82,
-  80, 81, 99, 71, 87, 82, 68, 82, 107, 76,
-  89, 78, 86, 81, 73, 92, 80, 78, 69, 86,
-  88, 82, 80, 84, 89, 78, 88, 78, 97, 91,
-  110, 76, 75, 79, 87, 86, 71, 83, 83, 101,
-  89, 88, 89, 84, 86, 90, 83, 92, 83, 88,
-  78, 74, 77, 81, 97, 90, 69, 82, 80, 84,
-  92, 91, 80, 89, 85, 80, 88, 83, 86, 96,
-  75, 77, 70, 83, 84, 92, 79, 83, 86, 87,
-  87, 90, 79, 72, 89, 82, 96, 78, 83, 75,
-  82, 86, 77, 87, 95, 74, 87, 95, 53, 72,
-  82, 62, 79, 88, 83, 69, 96, 82, 78, 84,
-  81, 75, 77, 78, 104, 80, 74, 74, 95, 90,
-  82, 106, 88, 96, 85, 85, 88, 89, 86, 79,
-  102, 70, 75, 93, 64, 77, 114, 87, 87, 70,
-  89, 74, 67, 98, 57, 72, 56, 82, 82, 83,
-  84, 81, 90, 84, 75, 80, 100, 95, 117, 61,
-  74, 64, 80, 79, 84, 70, 83, 93, 88, 84,
-  91, 83, 82, 83, 90, 102, 88, 85, 72, 65,
-  75, 84, 97, 85, 58, 81, 76, 85, 110, 96,
-  76, 76, 81, 79, 94, 85, 99, 95, 67, 74,
-  71, 80, 78, 84, 78, 76, 77, 89, 95, 86,
-  80, 61, 79, 83, 90, 77, 85, 73, 84, 90,
-  69, 84, 86, 88, 84, 92, 65, 83, 92, 78,
-  80, 77, 75, 71, 100, 78, 78, 90, 92, 76,
-  82, 82, 82, 83, 81, 80, 80, 96, 80, 97,
-  86, 85, 84, 88, 81, 82, 81, 80, 100, 74,
-  70, 85, 71, 84, 91, 108, 86, 80, 84, 80,
-  72, 92, 83, 83, 69, 85, 88, 76, 80, 73,
-  92, 78, 82, 82, 89, 92, 109, 76, 82, 73,
-  90, 85, 86, 84, 81, 87, 82, 87, 87, 87,
-  83, 81, 77, 94, 94, 89, 81, 74, 83, 85,
-  97, 91, 75, 88, 80, 85, 102, 88, 84, 80,
-  81, 77, 84, 88, 87, 92, 72, 80, 74, 77,
-  82, 86, 86, 86, 82, 82, 83, 89, 92, 71,
-  90, 79, 92, 80, 85, 78, 82, 78, 100, 87,
-  84, 72, 80, 78, 82, 90, 104, 83, 84, 97,
-  73, 82, 76, 86, 77, 84, 70, 88, 82, 83,
-  75, 75, 90, 74, 90, 75, 94, 89, 91, 88,
-  85, 85, 73, 83, 80, 79, 75, 80, 67, 87,
-  91, 79, 74, 76, 70, 90, 84, 103, 86, 72,
-  84, 71, 73, 69, 98, 79, 89, 81, 73, 83,
-  89, 116, 86, 83, 102, 86, 81, 78, 87, 80,
-  93, 86, 99, 99, 86, 82, 88, 83, 85, 91,
-  92, 87, 90, 85, 80, 81, 87, 85, 75, 80,
-  84, 107, 72, 64, 97, 87, 77, 84, 82, 95,
-  78, 85, 71, 89, 72, 90, 86, 80, 81, 79,
-  87, 119, 83, 84, 77, 78, 73, 107, 82, 77,
-  79, 89, 99, 86, 79, 81, 87, 87, 86, 78,
-  80, 75, 89, 98, 110, 77, 79, 91, 77, 82,
-  74, 96, 82, 78, 70, 77, 82, 74, 74, 69,
-  88, 79, 84, 75, 88, 97, 90, 75, 80, 77,
-  77, 76, 100, 71, 78, 84, 70, 83, 98, 73,
-  61, 77, 69, 88, 96, 88, 86, 72, 85, 85,
-  63, 75, 97, 72, 90, 89, 75, 74, 81, 138,
-  89, 72, 87, 72, 84, 77, 86, 75, 80, 86,
-  109, 80, 92, 84, 86, 84, 72, 82, 84, 79,
-  77, 78, 80, 82, 86, 93, 79, 80, 79, 118,
-  77, 68, 92, 85, 80, 104, 93, 95, 76, 84,
-  73, 87, 77, 88, 80, 78, 76, 82, 87, 123,
-  74, 86, 73, 81, 79, 111, 75, 77, 78, 82,
-  102, 86, 83, 84, 86, 88, 90, 84, 82, 83,
-  83, 85, 101, 78, 87, 75, 76, 82, 74, 86,
-  77, 87, 68, 78, 75, 83, 87, 77, 89, 76,
-  86, 90, 87, 92, 91, 91, 81, 91, 77, 88,
-  99, 80, 77, 78, 75, 91, 91, 83, 79, 98,
-  76, 86, 84, 90, 87, 73, 86, 83, 74, 75,
-  94, 81, 87, 75, 74, 83, 86, 107, 79, 83,
-  96, 84, 99, 83, 85, 83, 95, 86, 90, 76,
-  87, 76, 95, 82, 79, 89, 88, 85, 75, 81,
-  81, 83, 86, 89, 80, 82, 84, 100, 76, 69,
-  92, 85, 78, 100, 79, 99, 78, 88, 70, 89,
-  76, 91, 82, 79, 86, 92, 78, 101, 81, 83,
-  76, 76, 80, 100, 87, 84, 85, 88, 96, 80,
-  75, 83, 84, 93, 82, 67, 77, 72, 82, 89,
-  103, 81, 87, 93, 81, 81, 83, 82, 72, 83,
-  76, 81, 76, 78, 81, 80, 77, 75, 93, 77,
-  85, 85, 93, 89, 88, 90, 68, 78, 94, 87,
-  86, 76, 69, 86, 77, 76, 69, 78, 76, 89,
-  82, 91, 84, 76, 81, 80, 80, 73, 96, 70,
-  78, 95, 74, 84, 75, 131, 79, 74, 106, 73,
-  94, 65, 86, 85, 95, 89, 96, 92, 98, 89,
-  86, 88, 80, 84, 86, 81, 87, 86, 71, 76,
-  85, 80, 83, 86, 80, 123, 77, 73, 98, 74,
-  75, 83, 78, 92, 76, 78, 73, 86, 65, 87,
-  77, 76, 80, 82, 70, 112, 80, 84, 67, 85,
-  73, 114, 81, 80, 71, 82, 102, 78, 78, 81,
-  81, 105, 83, 75, 69, 71, 99, 109, 105, 73,
-  66, 91, 100, 81, 96, 88, 75, 75, 72, 69,
-  81, 67, 88, 69, 83, 82, 87, 87, 60, 105,
-  97, 70, 84, 81, 65, 84, 93, 73, 76, 72,
-  67, 77, 79, 77, 58, 73, 75, 85, 83, 65,
-  89, 81, 75, 70, 77, 80, 81, 60, 76, 124,
-  80, 76, 70, 139, 72, 52, 115, 71, 76, 61,
-  110, 77, 85, 96, 129, 82, 93, 106, 81, 87,
-  69, 83, 68, 70, 79, 74, 65, 82, 85, 79,
-  76, 99, 89, 132, 87, 86, 86, 63, 75, 86,
-  98, 91, 82, 85, 68, 77, 67, 80, 70, 73,
-  76, 83, 69, 101, 87, 85, 49, 88, 80, 116,
-  75, 83, 69, 74, 113, 65, 79, 81, 90, 87,
-  86, 77, 76, 76, 77, 85, 101, 83, 90, 91,
-  79, 82, 84, 83, 72, 81, 71, 88, 68, 75,
-  93, 79, 81, 77, 92, 93, 93, 96, 94, 101,
-  83, 89, 74, 82, 95, 86, 90, 76, 79, 87,
-  78, 73, 74, 96, 77, 88, 81, 94, 84, 72,
-  84, 72, 78, 78, 97, 75, 83, 88, 81, 88,
-  74, 121, 78, 80, 103, 78, 84, 69, 82, 85,
-  92, 86, 83, 79, 92, 82, 91, 88, 77, 87,
-  89, 85, 82, 86, 75, 80, 79, 85, 87, 82,
-  80, 113, 77, 76, 88, 73, 79, 81, 79, 96,
-  75, 82, 72, 87, 68, 88, 88, 78, 81, 87,
-  79, 95, 90, 88, 73, 82, 80, 109, 81, 82,
-  80, 82, 96, 75, 83, 85, 77, 88, 87, 86,
-  80, 75, 73, 88, 92, 82, 87, 89, 74, 76,
-  85, 87, 79, 90, 79, 77, 79, 78, 86, 75,
-  90, 85, 88, 75, 86, 87, 97, 89, 95, 90,
-  78, 74, 88, 89, 99, 75, 93, 86, 79, 77,
-  80, 78, 77, 87, 86, 93, 78, 79, 87, 81,
-  88, 77, 79, 82, 78, 78, 87, 74, 91, 91,
-  76, 92, 101, 89, 99, 85, 83, 89, 89, 94,
-  89, 88, 99, 82, 88, 93, 88, 92, 85, 84,
-  94, 81, 73, 84, 84, 78, 84, 89, 79, 116,
-  80, 88, 88, 81, 83, 92, 78, 96, 85, 78,
-  76, 85, 80, 84, 74, 82, 78, 79, 79, 101,
-  75, 92, 84, 89, 82, 105, 82, 74, 74, 90,
-  100, 86, 78, 77, 84, 81, 86, 86, 80, 74,
-  81, 92, 94, 74, 72, 96, 83, 71, 92, 86,
-  80, 82, 78, 63, 85, 77, 90, 74, 87, 85,
-  83, 86, 89, 89, 95, 77, 91, 74, 79, 67,
-  92, 84, 96, 86, 80, 77, 67, 70, 77, 73,
-  82, 84, 84, 88, 84, 79, 81, 86, 80, 83,
-  87, 73, 76, 75, 91, 57, 86, 95, 71, 73,
-  109, 84, 85, 89, 92, 82, 90, 93, 95, 81,
-  103, 90, 84, 92, 76, 89, 86, 81, 87, 84,
-  77, 78, 82, 77, 93, 94, 77, 120, 86, 92,
-  95, 67, 80, 83, 79, 96, 79, 80, 70, 80,
-  74, 79, 78, 75, 77, 83, 85, 97, 82, 93,
-  75, 93, 87, 108, 76, 74, 75, 88, 105, 78,
-  81, 78, 85, 82, 91, 86, 76, 77, 75, 88,
-  86, 87, 82, 90, 79, 74, 84, 88, 75, 88,
-  87, 82, 87, 77, 90, 71, 89, 82, 80, 88,
-  94, 88, 94, 97, 80, 80, 82, 74, 79, 89,
-  101, 77, 79, 88, 79, 79, 81, 94, 76, 88,
-  84, 96, 80, 77, 86, 70, 85, 76, 82, 84,
-  81, 75, 88, 74, 95, 86, 82, 92, 99, 88,
-  72, 83, 84, 85, 93, 89, 88, 80, 93, 84,
-  91, 89, 83, 89, 85, 89, 86, 82, 77, 83,
-  82, 79, 85, 89, 80, 113, 80, 88, 90, 79,
-  86, 86, 83, 98, 79, 80, 78, 82, 78, 81,
-  95, 81, 81, 91, 83, 90, 98, 94, 84, 87,
-  92, 96, 79, 78, 78, 88, 99, 83, 69, 87,
-  76, 97, 104, 94, 86, 80, 93, 82, 95, 76,
-  82, 81, 84, 91, 75, 67, 86, 86, 82, 83,
-  73, 93, 85, 82, 103, 84, 86, 88, 90, 71,
-  77, 97, 127, 84, 93, 101, 88, 74, 118, 84,
-  81, 96, 85, 84, 87, 91, 80, 74, 71, 71,
-  88, 87, 93, 94, 59, 78, 73, 73, 90, 75,
-  62, 86, 86, 85, 59, 74, 84, 89, 103, 81,
-  87, 97, 84, 65, 77, 89, 92, 73, 85, 89,
-  81, 77, 104, 94, 87, 91, 90, 72, 87, 84,
-  91, 81, 86, 107, 76, 87, 89, 76, 83, 79,
-  85, 92, 87, 86, 90, 87, 91, 77, 91, 106,
-  92, 88, 81, 84, 69, 88, 92, 78, 82, 74,
-  83, 73, 82, 90, 98, 79, 72, 84, 103, 94,
-  99, 92, 79, 74, 87, 92, 92, 75, 73, 71,
-  83, 75, 76, 68, 83, 92, 77, 80, 95, 92,
-  83, 76, 96, 86, 96, 109, 95, 71, 76, 79,
-  89, 83, 91, 105, 92, 68, 138, 81, 75, 88,
-  94, 90, 85, 101, 86, 72, 77, 82, 81, 89,
-  91, 72, 53, 72, 63, 73, 90, 74, 58, 83,
-  76, 83, 69, 86, 82, 84, 90, 92, 79, 103,
-  84, 65, 81, 82, 82, 76, 82, 90, 72, 85,
-  90, 99, 81, 97, 82, 72, 81, 75, 87, 77,
-  84, 105, 80, 88, 92, 73, 76, 77, 87, 93,
-  87, 88, 88, 85, 85, 72, 106, 103, 84, 83,
-  94, 94, 96, 84, 91, 73, 73, 72, 73, 73,
-  81, 87, 105, 79, 82, 73, 99, 84, 81, 83,
-  78, 96, 86, 91, 90, 83, 77, 76, 73, 74,
-  82, 71, 84, 89, 58, 71, 91, 81, 80, 82,
-  84, 80, 82, 89, 78, 81, 85, 81, 82, 92,
-  81, 83, 83, 83, 112, 77, 80, 82, 84, 96,
-  93, 80, 93, 82, 77, 73, 90, 96, 89, 95,
-  79, 72, 69, 82, 92, 78, 77, 69, 76, 82,
-  81, 81, 84, 76, 94, 87, 82, 97, 82, 80,
-  77, 73, 80, 95, 86, 91, 70, 82, 79, 90,
-  92, 81, 96, 84, 81, 73, 80, 75, 91, 88,
-  74, 84, 102, 75, 65, 78, 87, 86, 83, 92,
-  86, 81, 91, 88, 86, 81, 92, 89, 78, 85,
-  99, 83, 79, 80, 78, 78, 92, 90, 92, 91,
-  88, 89, 71, 71, 69, 94, 84, 66, 87, 84,
-  74, 100, 96, 82, 74, 76, 77, 66, 73, 76,
-  85, 87, 75, 78, 80, 97, 82, 83, 126, 84,
-  106, 90, 70, 68, 102, 79, 145, 89, 96, 98,
-  83, 67, 151, 74, 89, 75, 103, 98, 80, 87,
-  96, 100, 62, 59, 86, 94, 110, 84, 58, 66,
-  61, 71, 95, 93, 82, 95, 71, 80, 69, 101,
-  69, 90, 84, 77, 103, 104, 78, 70, 71, 80,
-  93, 67, 80, 81, 79, 87, 83, 87, 82, 94,
-  73, 87, 103, 86, 77, 87, 104, 88, 70, 77,
-  73, 82, 73, 76, 90, 85, 85, 83, 74, 87,
-  92, 62, 95, 111, 90, 79, 77, 91, 67, 74,
-  74, 64, 65, 63, 88, 74, 77, 78, 89, 98,
-  71, 77, 80, 90, 76, 70, 83, 81, 65, 101,
-  90, 79, 68, 78, 76, 63, 70, 82, 86, 88,
-  72, 68, 92, 92, 70, 83, 112, 85, 104, 135,
-  73, 70, 109, 61, 90, 86, 83, 94, 92, 56,
-  131, 73, 76, 71, 101, 94, 76, 104, 104, 97,
-  60, 58, 85, 96, 101, 66, 72, 62, 59, 76,
-  97, 93, 90, 86, 57, 81, 76, 95, 63, 88,
-  61, 82, 99, 99, 75, 80, 72, 67, 74, 69,
-  75, 84, 76, 98, 72, 90, 76, 92, 68, 84,
-  109, 66, 68, 84, 88, 83, 75, 77, 87, 80,
-  73, 61, 86, 84, 82, 81, 70, 89, 86, 66,
-  99, 100, 89, 69, 78, 91, 99, 72, 72, 71,
-  83, 70, 81, 72, 74, 81, 90, 108, 80, 89,
-  80, 78, 83, 83, 86, 95, 88, 92, 93, 86,
-  89, 77, 78, 73, 79, 89, 87, 79, 68, 86,
-  71, 80, 80, 90, 83, 79, 92, 73, 75, 80,
-  93, 73, 81, 88, 72, 74, 81, 93, 92, 71,
-  85, 85, 90, 88, 81, 76, 88, 93, 74, 84,
-  90, 96, 95, 93, 90, 70, 77, 88, 88, 80,
-  90, 71, 75, 94, 86, 84, 80, 78, 83, 84,
-  85, 94, 84, 85, 73, 76, 63, 97, 86, 90,
-  79, 81, 87, 84, 91, 78, 89, 92, 94, 75,
-  68, 82, 84, 83, 69, 80, 99, 80, 73, 71,
-  82, 78, 82, 86, 90, 87, 75, 91, 77, 85,
-  88, 80, 70, 82, 86, 79, 80, 74, 92, 83,
-  96, 90, 94, 84, 83, 92, 82, 72, 81, 87,
-  87, 82, 73, 88, 99, 91, 89, 85, 106, 71,
-  77, 76, 83, 87, 75, 84, 70, 90, 82, 88,
-  91, 91, 84, 76, 84, 81, 74, 89, 103, 75,
-  77, 89, 102, 75, 73, 88, 92, 71, 74, 86,
-  82, 96, 86, 87, 87, 110, 61, 84, 86, 101,
-  90, 82, 90, 78, 90, 80, 80, 78, 94, 92,
-  84, 91, 77, 86, 83, 80, 84, 68, 97, 82,
-  73, 82, 71, 74, 81, 86, 83, 82, 82, 79,
-  85, 86, 85, 71, 85, 119, 87, 79, 71, 89,
-  109, 78, 56, 80, 89, 80, 83, 77, 82, 75,
-  69, 90, 75, 77, 68, 97, 67, 83, 88, 80,
-  93, 82, 81, 78, 73, 67, 77, 86, 93, 78,
-  95, 85, 80, 93, 79, 85, 82, 84, 85, 74,
-  73, 91, 97, 89, 89, 82, 105, 78, 79, 70,
-  77, 93, 78, 80, 75, 87, 76, 88, 88, 93,
-  84, 79, 86, 80, 79, 86, 108, 66, 62, 83,
-  84, 74, 84, 81, 75, 65, 72, 87, 79, 91,
-  83, 71, 86, 110, 71, 90, 87, 101, 85, 75,
-  96, 82, 92, 83, 82, 72, 89, 86, 81, 94,
-  84, 78, 79, 81, 74, 73, 88, 85, 70, 82,
-  73, 79, 65, 86, 81, 84, 89, 86, 87, 90,
-  73, 70, 94, 118, 84, 77, 73, 86, 88, 82,
-  69, 79, 100, 76, 80, 70, 83, 76, 69, 89,
-  75, 79, 69, 98, 62, 80, 88, 80, 96, 82,
-  78, 79, 80, 75, 99, 90, 94, 82, 96, 91,
-  73, 95, 83, 101, 89, 80, 83, 99, 82, 93,
-  104, 91, 85, 81, 105, 85, 94, 77, 85, 91,
-  72, 86, 75, 92, 76, 82, 84, 78, 79, 74,
-  72, 67, 81, 81, 93, 81, 84, 103, 83, 82,
-  81, 87, 90, 75, 90, 94, 88, 82, 83, 71,
-  88, 96, 84, 103, 85, 89, 81, 79, 93, 84,
-  92, 83, 81, 76, 83, 85, 88, 97, 78, 82,
-  87, 87, 86, 88, 78, 86, 78, 75, 86, 94,
-  62, 99, 88, 87, 73, 71, 95, 91, 83, 76,
-  90, 98, 72, 88, 84, 84, 86, 94, 68, 86,
-  98, 68, 83, 76, 84, 77, 76, 86, 85, 77,
-  75, 98, 64, 92, 83, 85, 86, 85, 80, 81,
-  89, 75, 91, 91, 78, 83, 90, 96, 78, 84,
-  101, 76, 66, 92, 95, 94, 85, 80, 89, 67,
-  101, 83, 85, 84, 90, 96, 84, 88, 86, 73,
-  85, 92, 99, 80, 84, 83, 77, 77, 84, 93,
-  97, 86, 103, 84, 110, 77, 69, 82, 86, 73,
-  87, 93, 82, 100, 88, 74, 105, 94, 69, 87,
-  92, 92, 93, 91, 93, 91, 83, 97, 78, 89,
-  80, 84, 78, 70, 83, 90, 86, 80, 90, 79,
-  86, 74, 71, 94, 84, 63, 86, 100, 84, 66,
-  96, 90, 80, 85, 102, 75, 85, 89, 100, 89,
-  72, 84, 80, 85, 79, 93, 97, 99, 88, 71,
-  82, 89, 82, 83, 85, 85, 96, 92, 82, 89,
-  77, 86, 84, 88, 82, 85, 74, 82, 75, 82,
-  92, 89, 71, 87, 92, 73, 85, 105, 89, 89,
-  74, 86, 96, 95, 86, 75, 84, 76, 100, 87,
-  78, 78, 96, 102, 82, 85, 91, 85, 77, 79,
-  83, 81, 88, 89, 72, 81, 81, 86, 95, 83,
-  109, 77, 95, 75, 67, 73, 87, 66, 80, 95,
-  85, 101, 90, 74, 112, 90, 66, 92, 92, 94,
-  87, 95, 90, 92, 82, 100, 74, 94, 78, 83,
-  81, 72, 80, 89, 87, 87, 80, 70, 74, 76,
-  67, 95, 85, 66, 78, 83, 81, 71, 97, 94,
-  82, 84, 100, 76, 84, 86, 111, 90, 72, 79,
-  74, 84, 70, 92, 92, 108, 83, 71, 82, 87,
-  81, 83, 85, 80, 96, 95, 89, 90, 78, 89,
-  87, 82, 75, 93, 70, 80, 76, 82, 93, 83,
-  81, 87, 91, 74, 90, 111, 99, 85, 101, 85,
-  97, 107, 81, 75, 87, 75, 90, 85, 82, 75,
-  76, 105, 85, 78, 87, 86, 72, 94, 81, 87,
-  89, 82, 87, 73, 74, 101, 94, 85, 84, 77,
-  95, 79, 82, 82, 86, 68, 88, 84, 91, 89,
-  88, 78, 102, 88, 73, 80, 85, 80, 92, 84,
-  93, 95, 83, 92, 75, 98, 81, 87, 77, 78,
-  83, 84, 86, 78, 91, 78, 78, 88, 72, 91,
-  84, 66, 90, 83, 83, 64, 92, 92, 94, 96,
-  88, 88, 88, 82, 90, 86, 66, 80, 93, 87,
-  84, 83, 97, 84, 85, 73, 83, 76, 81, 85,
-  86, 87, 89, 90, 83, 85, 92, 89, 82, 86,
-  82, 87, 87, 87, 77, 83, 89, 84, 75, 84,
-  85, 79, 89, 93, 75, 76, 86, 100, 76, 74,
-  73, 69, 92, 81, 73, 77, 69, 90, 67, 120,
-  74, 72, 79, 77, 94, 71, 80, 98, 72, 62,
-  130, 80, 110, 78, 74, 88, 69, 70, 96, 74,
-  81, 85, 81, 69, 94, 81, 73, 69, 69, 94,
-  96, 86, 109, 80, 87, 84, 96, 82, 83, 99,
-  85, 75, 84, 93, 93, 87, 72, 86, 78, 73,
-  103, 98, 89, 80, 80, 86, 96, 97, 64, 79,
-  97, 62, 97, 60, 89, 93, 91, 77, 78, 99,
-  83, 78, 93, 80, 57, 100, 84, 74, 79, 77,
-  89, 70, 84, 96, 72, 104, 74, 84, 87, 77,
-  65, 75, 64, 66, 92, 59, 68, 84, 99, 99,
-  54, 85, 71, 77, 91, 79, 85, 70, 78, 85,
-  68, 83, 74, 72, 88, 96, 69, 65, 69, 75,
-  81, 89, 70, 82, 60, 105, 74, 100, 74, 65,
-  74, 78, 76, 64, 82, 100, 72, 65, 138, 82,
-  108, 86, 68, 89, 63, 70, 74, 72, 74, 87,
-  77, 67, 87, 75, 76, 64, 65, 85, 94, 78,
-  98, 83, 86, 84, 91, 73, 74, 94, 76, 67,
-  86, 89, 97, 72, 69, 77, 75, 76, 118, 87,
-  78, 81, 71, 92, 84, 101, 65, 74, 98, 70,
-  91, 68, 88, 99, 93, 86, 65, 106, 82, 75,
-  87, 80, 57, 92, 78, 77, 69, 76, 83, 80,
-  86, 90, 70, 85, 73, 84, 77, 78, 64, 71,
-  64, 63, 97, 56, 66, 85, 113, 107, 84, 87,
-  63, 73, 85, 79, 75, 68, 77, 90, 55, 87,
-  74, 66, 72, 84, 72, 84, 69, 75, 83, 90,
-  76, 70, 67, 95, 61, 99, 73, 76, 84, 84,
-  75, 65, 88, 95, 81, 63, 122, 78, 108, 106,
-  70, 90, 59, 66, 88, 81, 100, 89, 86, 63,
-  91, 83, 82, 66, 73, 87, 85, 77, 109, 75,
-  78, 87, 95, 72, 89, 83, 86, 69, 87, 86,
-  94, 87, 70, 76, 64, 77, 109, 86, 89, 91,
-  69, 90, 105, 95, 72, 87, 101, 88, 97, 62,
-  85, 85, 82, 92, 65, 97, 85, 83, 78, 84,
-  68, 91, 89, 77, 87, 73, 93, 70, 98, 88,
-  75, 70, 78, 88, 85, 81, 70, 76, 72, 69,
-  93, 64, 76, 86, 103, 100, 106, 96, 72, 75,
-  81, 77, 72, 77, 77, 84, 69, 82, 76, 102,
-  77, 67, 85, 80, 73, 74, 80, 83, 66, 103,
-  81, 102, 57, 63, 78, 72, 95, 88, 91, 74,
-  93, 76, 72, 95, 104, 79, 93, 87, 79, 84,
-  65, 79, 79, 94, 74, 80, 92, 75, 82, 76,
-  85, 79, 105, 92, 67, 87, 109, 68, 90, 80,
-  87, 76, 87, 72, 101, 64, 87, 83, 96, 79,
-  100, 84, 74, 80, 79, 111, 77, 97, 69, 79,
-  95, 95, 75, 105, 81, 72, 90, 60, 89, 68,
-  78, 96, 76, 78, 87, 79, 71, 93, 93, 81,
-  99, 85, 86, 77, 94, 77, 71, 87, 80, 86,
-  87, 94, 83, 84, 86, 83, 95, 85, 88, 55,
-  78, 91, 93, 82, 99, 85, 85, 88, 87, 79,
-  72, 79, 93, 85, 78, 71, 87, 86, 62, 62,
-  88, 90, 74, 76, 77, 82, 72, 109, 77, 87,
-  66, 66, 81, 74, 99, 88, 81, 84, 90, 72,
-  72, 93, 89, 80, 88, 76, 83, 88, 63, 84,
-  78, 100, 73, 79, 89, 75, 83, 76, 80, 80,
-  100, 94, 63, 85, 97, 70, 94, 80, 87, 82,
-  84, 87, 102, 63, 94, 80, 91, 77, 97, 80,
-  64, 92, 77, 116, 79, 75, 76, 82, 96, 87,
-  84, 100, 83, 89, 77, 63, 89, 66, 77, 90,
-  80, 73, 89, 83, 63, 92, 90, 78, 95, 85,
-  92, 78, 95, 87, 79, 85, 77, 69, 91, 96,
-  77, 82, 86, 83, 90, 83, 80, 59, 81, 93,
-  73, 75, 102, 88, 91, 74, 81, 85, 74, 81,
-  92, 84, 72, 73, 76, 84, 62, 63, 91, 93,
-  77, 79, 80, 83, 78, 92, 90, 79, 66, 64,
-  81, 85, 96, 90, 89, 73, 81, 72, 80, 98,
-  82, 85, 83, 78, 83, 87, 77, 82, 84, 90,
-  75, 80, 81, 84, 79, 77, 84, 89, 104, 97,
-  61, 80, 103, 76, 89, 87, 88, 82, 81, 93,
-  100, 71, 89, 81, 86, 72, 95, 85, 74, 87,
-  84, 103, 78, 86, 90, 81, 98, 94, 82, 105,
-  75, 89, 88, 67, 89, 70, 82, 77, 87, 74,
-  84, 85, 74, 102, 96, 87, 99, 88, 103, 77,
-  95, 85, 86, 88, 86, 83, 84, 95, 80, 86,
-  78, 87, 92, 92, 81, 63, 83, 84, 70, 73,
-  80, 86, 87, 73, 88, 78, 80, 85, 101, 80,
-  82, 74, 79, 79, 80, 94, 74, 88, 88, 86,
-  83, 80, 78, 86, 85, 103, 71, 91, 79, 89,
-  77, 69, 78, 101, 74, 73, 95, 82, 98, 81,
-  87, 81, 82, 87, 84, 79, 85, 70, 90, 82,
-  98, 79, 74, 82, 91, 92, 96, 94, 82, 77,
-  75, 88, 82, 85, 96, 68, 92, 79, 75, 65,
-  86, 77, 95, 76, 88, 97, 77, 90, 88, 78,
-  70, 94, 76, 75, 85, 89, 84, 81, 84, 73,
-  96, 53, 87, 94, 91, 81, 70, 84, 95, 84,
-  83, 93, 82, 101, 89, 73, 99, 72, 80, 87,
-  82, 97, 83, 93, 92, 89, 85, 83, 85, 92,
-  89, 89, 81, 91, 84, 78, 89, 71, 85, 87,
-  95, 91, 86, 84, 72, 80, 81, 82, 86, 83,
-  74, 84, 79, 92, 63, 74, 87, 83, 81, 84,
-  74, 87, 82, 88, 73, 91, 77, 85, 79, 74,
-  85, 99, 79, 74, 91, 88, 89, 81, 81, 90,
-  82, 82, 86, 75, 80, 73, 94, 85, 93, 71,
-  83, 85, 78, 86, 87, 90, 84, 66, 78, 100,
-  83, 76, 97, 71, 92, 82, 87, 70, 85, 79,
-  92, 88, 86, 95, 73, 90, 87, 84, 74, 87,
-  77, 79, 88, 82, 88, 85, 82, 71, 98, 50,
-  90, 94, 84, 75, 73, 82, 77, 85, 81, 95,
-  90, 91, 95, 71, 98, 72, 78, 73, 80, 94,
-  80, 75, 87, 87, 81, 80, 84, 86, 79, 91,
-  80, 92, 85, 78, 86, 71, 82, 87, 93, 96,
-  85, 92, 71, 84, 83, 77, 83, 78, 87, 94,
-  77, 97, 84, 76, 85, 83, 82, 79, 78, 88,
-  86, 87, 74, 87, 78, 89, 81, 78, 87, 99,
-  95, 71, 96, 87, 97, 82, 86, 89, 80, 83,
-  82, 68, 78, 82, 87, 78, 100, 80, 76, 80,
-  72, 92, 99, 92, 84, 70, 76, 91, 80, 78,
-  92, 75, 89, 85, 76, 64, 86, 74, 98, 74,
-  88, 103, 80, 86, 96, 83, 76, 98, 82, 79,
-  88, 84, 93, 77, 93, 79, 95, 59, 88, 91,
-  90, 74, 71, 87, 77, 86, 79, 93, 83, 101,
-  88, 74, 91, 72, 81, 88, 81, 96, 81, 83,
-  90, 90, 85, 83, 89, 90, 89, 86, 75, 92,
-  86, 97, 81, 80, 74, 89, 91, 95, 89, 87,
-  72, 80, 84, 80, 87, 82, 101, 77, 65, 91,
-  101, 74, 85, 72, 77, 74, 108, 67, 84, 102,
-  76, 92, 104, 72, 84, 61, 87, 104, 63, 77,
-  101, 76, 86, 86, 105, 99, 84, 86, 82, 74,
-  87, 48, 82, 80, 116, 75, 83, 87, 78, 83,
-  106, 94, 93, 68, 77, 79, 67, 69, 84, 71,
-  80, 83, 68, 108, 66, 72, 83, 92, 76, 128,
-  68, 114, 87, 69, 99, 85, 66, 65, 84, 87,
-  82, 71, 81, 55, 96, 86, 64, 92, 86, 67,
-  76, 79, 82, 76, 46, 82, 60, 83, 81, 83,
-  80, 84, 84, 134, 83, 83, 74, 94, 91, 90,
-  80, 97, 83, 79, 91, 82, 75, 107, 78, 58,
-  113, 84, 77, 92, 84, 84, 95, 87, 62, 69,
-  85, 79, 101, 82, 92, 81, 73, 86, 88, 60,
-  85, 72, 86, 75, 106, 74, 80, 88, 81, 88,
-  99, 74, 85, 62, 87, 106, 62, 79, 87, 78,
-  83, 87, 93, 95, 85, 84, 83, 62, 78, 48,
-  81, 81, 104, 71, 82, 99, 81, 85, 99, 93,
-  85, 53, 78, 87, 68, 72, 88, 77, 90, 77,
-  84, 117, 64, 63, 80, 104, 73, 144, 68, 130,
-  84, 66, 100, 80, 62, 69, 88, 87, 84, 72,
-  83, 60, 94, 83, 72, 96, 83, 61, 80, 76,
-  55, 71, 50, 85, 71, 79, 81, 80, 69, 87,
-  83, 119, 82, 84, 72, 91, 87, 86, 81, 89,
-  78, 78, 84, 80, 83, 106, 77, 54, 108, 78,
-  71, 88, 86, 90, 79, 92, 63, 71, 87, 72,
-  102, 74, 102, 94, 88, 92, 102, 61, 84, 75,
-  79, 72, 102, 71, 85, 95, 79, 94, 103, 71,
-  82, 70, 78, 106, 79, 73, 93, 80, 83, 84,
-  106, 96, 82, 93, 83, 65, 94, 68, 86, 82,
-  107, 81, 85, 80, 78, 85, 105, 94, 87, 54,
-  78, 81, 66, 69, 82, 75, 78, 78, 72, 100,
-  69, 72, 85, 89, 78, 125, 70, 106, 85, 75,
-  101, 81, 69, 67, 87, 82, 95, 66, 86, 73,
-  99, 84, 64, 92, 87, 72, 77, 83, 62, 72,
-  47, 86, 63, 79, 79, 86, 77, 83, 83, 129,
-  88, 87, 77, 104, 89, 91, 83, 89, 82, 80,
-  89, 81, 80, 106, 80, 83, 102, 80, 68, 93,
-  81, 84, 78, 93, 63, 69, 79, 77, 105, 84,
-  84, 76, 70, 93, 90, 77, 84, 90, 83, 75,
-  81, 80, 77, 88, 79, 98, 95, 84, 81, 72,
-  94, 94, 75, 78, 97, 80, 91, 83, 81, 111,
-  88, 85, 89, 70, 71, 63, 94, 91, 119, 94,
-  86, 77, 74, 90, 89, 97, 95, 82, 79, 87,
-  78, 86, 81, 74, 79, 91, 75, 77, 88, 79,
-  78, 78, 95, 87, 74, 85, 81, 78, 93, 85,
-  82, 68, 98, 85, 80, 80, 78, 63, 106, 67,
-  73, 89, 85, 78, 82, 81, 89, 78, 78, 85,
-  86, 95, 85, 83, 82, 72, 80, 89, 83, 91,
-  70, 78, 85, 85, 78, 87, 82, 86, 75, 85,
-  71, 95, 86, 74, 85, 80, 82, 85, 91, 96,
-  88, 88, 83, 73, 90, 99, 91, 81, 83, 83,
-  83, 92, 80, 75, 84, 89, 91, 78, 80, 83,
-  75, 92, 76, 97, 90, 85, 83, 73, 83, 89,
-  76, 81, 87, 79, 95, 82, 72, 88, 89, 88,
-  96, 66, 69, 66, 85, 87, 98, 87, 85, 76,
-  86, 87, 80, 91, 85, 68, 81, 96, 82, 88,
-  84, 77, 86, 78, 82, 84, 82, 76, 80, 86,
-  94, 82, 70, 83, 88, 82, 91, 89, 70, 67,
-  95, 87, 84, 82, 77, 76, 107, 62, 82, 90,
-  87, 76, 85, 85, 75, 81, 74, 80, 91, 93,
-  84, 76, 74, 71, 81, 79, 78, 94, 70, 90,
-  84, 82, 82, 84, 83, 84, 77, 83, 71, 93,
-  85, 75, 86, 76, 75, 81, 87, 95, 77, 86,
-  89, 76, 96, 97, 89, 75, 86, 89, 94, 94,
-  91, 75, 80, 90, 90, 77, 78, 81, 77, 98,
-  77, 98, 96, 79, 79, 81, 74, 94, 79, 81,
-  85, 78, 93, 82, 76, 80, 89, 91, 90, 65,
-  94, 77, 89, 90, 94, 92, 89, 79, 88, 87,
-  82, 95, 94, 60, 78, 87, 80, 94, 82, 74,
-  80, 73, 77, 73, 90, 79, 79, 80, 95, 89,
-  79, 79, 80, 75, 94, 89, 70, 71, 92, 81,
-  90, 76, 79, 89, 118, 70, 73, 86, 92, 75,
-  83, 90, 74, 78, 82, 88, 86, 86, 87, 83,
-  72, 66, 77, 88, 82, 93, 74, 89, 84, 87,
-  81, 86, 84, 86, 80, 88, 72, 92, 85, 89,
-  86, 76, 72, 86, 91, 94, 77, 87, 82, 73,
-  88, 97, 90, 81, 68, 77, 95, 89, 74, 73,
-  83, 75, 84, 91, 88, 68, 91, 107, 63, 81,
-  72, 83, 78, 83, 96, 93, 78, 91, 74, 90,
-  76, 91, 94, 85, 95, 87, 74, 69, 72, 85,
-  94, 86, 99, 77, 75, 68, 84, 84, 86, 81,
-  67, 88, 96, 86, 75, 79, 92, 77, 80, 81,
-  72, 85, 85, 79, 87, 86, 78, 87, 88, 78,
-  98, 73, 81, 91, 70, 72, 97, 95, 78, 87,
-  80, 79, 97, 71, 78, 77, 79, 85, 76, 100,
-  87, 85, 79, 91, 92, 72, 74, 85, 84, 89,
-  83, 70, 80, 96, 87, 71, 80, 70, 82, 90,
-  87, 81, 76, 68, 74, 84, 81, 90, 70, 82,
-  80, 82, 87, 105, 93, 75, 85, 84, 89, 89,
-  79, 79, 70, 72, 71, 80, 91, 65, 82, 74,
-  82, 92, 88, 74, 88, 101, 71, 84, 72, 80,
-  73, 68, 92, 92, 72, 89, 76, 90, 74, 93,
-  91, 79, 93, 81, 65, 78, 75, 80, 92, 84,
-  109, 79, 72, 67, 97, 91, 97, 81, 62, 83,
-  90, 84, 87, 91, 92, 80, 64, 74, 70, 83,
-  86, 89, 86, 76, 78, 90, 87, 77, 85, 69,
-  76, 89, 81, 62, 93, 116, 72, 85, 93, 93,
-  110, 62, 82, 79, 74, 78, 66, 91, 89, 91,
-  79, 92, 94, 91, 82, 89, 83, 93, 83, 75,
-  63, 97, 83, 92, 82, 67, 82, 90, 103, 84,
-  71, 71, 87, 88, 82, 94, 76, 84, 70, 82,
-  86, 123, 88, 73, 86, 83, 82, 93, 83, 76,
-  74, 88, 69, 86, 76, 71, 80, 75, 78, 85,
-  87, 74, 86, 84, 64, 80, 80, 86, 81, 70,
-  91, 91, 72, 92, 86, 93, 78, 90, 88, 76,
-  96, 89, 75, 89, 77, 79, 93, 90, 91, 83,
-  73, 77, 94, 79, 87, 91, 70, 82, 94, 83,
-  77, 90, 88, 76, 81, 72, 71, 81, 86, 83,
-  88, 83, 74, 82, 84, 81, 82, 74, 92, 81,
-  97, 64, 98, 85, 78, 95, 73, 90, 106, 73,
-  79, 79, 81, 76, 78, 80, 93, 80, 83, 88,
-  91, 91, 74, 90, 101, 87, 84, 72, 81, 99,
-  78, 88, 78, 71, 81, 90, 84, 83, 75, 70,
-  84, 83, 81, 93, 79, 83, 77, 81, 86, 87,
-  83, 82, 87, 84, 89, 89, 81, 82, 88, 80,
-  78, 71, 110, 88, 83, 93, 82, 86, 101, 75,
-  66, 92, 76, 70, 82, 79, 85, 87, 106, 88,
-  85, 81, 64, 79, 55, 86, 88, 76, 139, 78,
-  73, 85, 101, 111, 76, 74, 91, 68, 73, 102,
-  66, 100, 78, 71, 94, 106, 74, 67, 103, 95,
-  93, 74, 65, 81, 94, 87, 95, 93, 77, 84,
-  80, 65, 83, 73, 70, 77, 81, 64, 75, 92,
-  55, 80, 93, 73, 104, 117, 75, 68, 84, 74,
-  74, 74, 76, 88, 84, 89, 101, 81, 75, 74,
-  84, 75, 71, 80, 97, 80, 88, 67, 73, 70,
-  73, 74, 89, 79, 115, 74, 88, 92, 84, 92,
-  76, 84, 72, 68, 79, 82, 94, 82, 91, 100,
-  80, 90, 74, 87, 92, 95, 85, 71, 63, 65,
-  140, 98, 68, 105, 82, 90, 100, 84, 77, 103,
-  90, 69, 94, 81, 91, 67, 80, 100, 79, 67,
-  75, 69, 60, 92, 81, 92, 170, 82, 56, 99,
-  94, 98, 76, 73, 110, 65, 68, 121, 92, 108,
-  77, 60, 100, 96, 63, 62, 125, 90, 91, 75,
-  56, 91, 102, 84, 88, 95, 74, 71, 69, 82,
-  69, 79, 53, 72, 69, 66, 71, 82, 46, 82,
-  93, 69, 155, 109, 79, 59, 80, 78, 78, 88,
-  76, 92, 76, 90, 90, 79, 82, 73, 87, 78,
-  66, 73, 113, 97, 68, 54, 76, 72, 85, 77,
-  86, 74, 129, 73, 92, 109, 97, 113, 88, 83,
-  69, 64, 69, 76, 116, 83, 85, 144, 74, 106,
-  56, 84, 108, 97, 84, 85, 74, 72, 103, 106,
-  79, 87, 76, 80, 96, 78, 75, 82, 72, 74,
-  82, 84, 85, 74, 79, 94, 76, 89, 93, 80,
-  60, 85, 81, 95, 125, 92, 78, 99, 78, 98,
-  83, 70, 85, 73, 78, 98, 110, 92, 81, 79,
-  101, 100, 76, 68, 98, 89, 92, 79, 66, 89,
-  84, 83, 89, 87, 87, 93, 85, 59, 78, 75,
-  69, 73, 79, 70, 93, 89, 57, 75, 92, 80,
-  80, 99, 86, 72, 88, 77, 83, 103, 79, 84,
-  85, 85, 96, 80, 80, 77, 86, 80, 77, 77,
-  95, 79, 67, 78, 73, 75, 75, 74, 82, 79,
-  99, 84, 83, 90, 83, 86, 79, 88, 65, 74,
-  87, 80, 93, 79, 77, 88, 82, 88, 80, 83,
-  88, 95, 86, 78, 70, 82, 89, 89, 88, 85,
-  81, 88, 92, 79, 71, 81, 70, 88, 88, 78,
-  91, 80, 78, 71, 70, 91, 89, 80, 77, 81,
-  92, 74, 93, 82, 77, 96, 114, 96, 77, 89,
-  83, 88, 95, 90, 72, 94, 64, 83, 112, 93,
-  87, 82, 90, 95, 78, 77, 76, 60, 91, 81,
-  98, 81, 80, 100, 100, 77, 95, 72, 75, 82,
-  91, 80, 82, 90, 78, 74, 102, 86, 82, 86,
-  73, 66, 78, 88, 88, 76, 78, 82, 85, 96,
-  90, 82, 76, 97, 88, 79, 78, 79, 89, 83,
-  95, 86, 72, 94, 73, 79, 93, 72, 105, 72,
-  82, 71, 82, 89, 69, 90, 75, 80, 61, 81,
-  89, 75, 74, 79, 77, 89, 83, 88, 79, 78,
-  90, 70, 74, 82, 106, 75, 81, 95, 78, 92,
-  91, 84, 70, 99, 79, 76, 91, 79, 83, 71,
-  64, 84, 80, 88, 95, 76, 83, 86, 85, 104,
-  88, 85, 74, 99, 91, 91, 91, 88, 102, 93,
-  98, 78, 65, 100, 58, 76, 133, 75, 82, 74,
-  93, 91, 74, 79, 77, 76, 97, 83, 103, 77,
-  75, 96, 100, 84, 95, 77, 86, 85, 92, 92,
-  76, 85, 70, 74, 116, 79, 90, 88, 83, 53,
-  75, 100, 82, 90, 81, 95, 81, 93, 85, 66,
-  76, 84, 87, 79, 73, 71, 89, 90, 99, 82,
-  73, 72, 78, 81, 85, 72, 106, 74, 79, 86,
-  79, 100, 80, 85, 68, 81, 75, 68, 95, 71,
-  74, 80, 71, 98, 73, 86, 82, 83, 78, 77,
-  80, 82, 79, 75, 88, 82, 82, 87, 89, 81,
-  82, 86, 68, 92, 88, 86, 87, 73, 79, 80,
-  82, 96, 97, 77, 71, 80, 85, 104, 93, 85,
-  84, 91, 85, 82, 79, 81, 86, 85, 99, 85,
-  81, 89, 70, 85, 101, 80, 89, 81, 85, 81,
-  78, 76, 77, 100, 84, 82, 94, 82, 86, 102,
-  98, 72, 85, 79, 87, 79, 82, 85, 70, 87,
-  79, 77, 99, 92, 78, 89, 71, 66, 80, 89,
-  84, 91, 76, 93, 88, 89, 87, 81, 81, 76,
-  91, 83, 74, 77, 87, 88, 86, 88, 75, 69,
-  72, 79, 91, 76, 93, 84, 82, 76, 82, 90,
-  74, 79, 59, 89, 105, 84, 92, 78, 77, 78,
-  79, 92, 84, 87, 82, 83, 69, 76, 89, 84,
-  76, 79, 71, 83, 101, 82, 72, 73, 83, 83,
-  101, 86, 73, 81, 86, 85, 80, 68, 99, 67,
-  79, 70, 78, 83, 102, 85, 85, 90, 74, 80,
-  88, 85, 74, 76, 81, 72, 76, 87, 79, 82,
-  54, 75, 79, 75, 69, 96, 66, 85, 73, 100,
-  76, 88, 82, 78, 88, 112, 83, 101, 80, 85,
-  95, 81, 68, 92, 82, 85, 84, 79, 80, 75,
-  79, 91, 121, 77, 82, 89, 87, 90, 79, 80,
-  84, 80, 77, 84, 75, 90, 92, 91, 78, 90,
-  92, 113, 83, 94, 87, 69, 95, 77, 101, 83,
-  88, 84, 75, 88, 88, 104, 88, 84, 84, 85,
-  89, 75, 88, 89, 82, 96, 94, 163, 86, 82,
-  88, 79, 79, 80, 69, 78, 87, 81, 82, 88,
-  76, 77, 97, 81, 73, 71, 84, 75, 102, 91,
-  70, 84, 83, 86, 82, 75, 91, 76, 80, 74,
-  82, 85, 90, 83, 85, 94, 79, 78, 87, 78,
-  70, 77, 74, 78, 78, 87, 80, 88, 61, 87,
-  80, 72, 68, 102, 64, 84, 76, 101, 78, 83,
-  78, 89, 92, 94, 84, 102, 79, 94, 93, 84,
-  74, 93, 82, 84, 78, 75, 80, 80, 81, 90,
-  103, 72, 88, 89, 94, 92, 84, 77, 82, 71,
-  78, 74, 72, 100, 91, 93, 80, 88, 83, 105,
-  80, 103, 87, 75, 93, 73, 95, 83, 87, 82,
-  73, 84, 88, 106, 88, 92, 83, 85, 95, 73,
-  77, 91, 83, 95, 80, 132, 82, 79, 88, 79,
-  78, 82, 77, 83, 87, 78, 78, 91, 72, 80,
-  96, 82, 73, 73, 87, 76, 99, 86, 75, 75,
-  86, 83, 81, 75, 81, 71, 83, 69, 79, 80,
-  97, 78, 85, 92, 72, 81, 92, 97, 78, 75,
-  83, 76, 81, 88, 82, 83, 62, 80, 77, 75,
-  71, 96, 67, 86, 73, 92, 74, 83, 82, 75,
-  89, 103, 83, 96, 81, 83, 100, 80, 77, 91,
-  85, 86, 90, 78, 81, 74, 81, 85, 106, 76,
-  85, 90, 85, 91, 85, 88, 84, 76, 87, 83,
-  75, 98, 92, 96, 78, 92, 91, 104, 79, 93,
-  78, 77, 93, 84, 96, 82, 84, 84, 78, 88,
-  88, 99, 93, 85, 84, 83, 85, 77, 79, 89,
-  80, 94, 69, 144, 83, 82, 80, 80, 86, 85,
-  70, 82, 81, 85, 71, 83, 83, 98, 97, 78,
-  76, 74, 83, 74, 104, 87, 73, 84, 85, 81,
-  80, 62, 90, 73, 74, 76, 78, 83, 92, 77,
-  79, 87, 80, 86, 67, 81, 68, 79, 70, 77,
-  81, 94, 84, 84, 56, 80, 80, 76, 70, 93,
-  71, 75, 77, 107, 85, 85, 81, 84, 90, 102,
-  79, 97, 80, 88, 89, 92, 79, 82, 80, 83,
-  91, 81, 84, 75, 84, 96, 104, 69, 84, 107,
-  87, 78, 76, 70, 85, 79, 81, 78, 76, 77,
-  85, 79, 84, 95, 86, 118, 85, 105, 86, 78,
-  88, 81, 93, 83, 80, 87, 82, 82, 75, 94,
-  83, 86, 82, 81, 85, 76, 80, 83, 81, 100,
-  82, 147, 87, 83, 92, 81, 80, 81, 72, 77,
-  84, 81, 78, 82, 89, 89, 89, 76, 79, 75,
-  81, 74, 105, 86, 71, 87, 83, 80, 85, 70,
-  84, 85, 76, 82, 80, 81, 78, 73, 77, 91,
-  80, 78, 68, 73, 63, 78, 74, 84, 82, 103,
-  84, 90, 63, 92, 78, 72, 74, 96, 64, 78,
-  79, 105, 86, 82, 80, 100, 90, 82, 81, 98,
-  78, 106, 91, 96, 86, 82, 83, 85, 77, 82,
-  81, 79, 82, 93, 84, 69, 87, 112, 94, 83,
-  87, 67, 88, 76, 76, 72, 76, 83, 84, 77,
-  84, 96, 78, 114, 78, 119, 91, 84, 86, 64,
-  82, 82, 76, 88, 76, 79, 72, 97, 86, 93,
-  79, 81, 92, 69, 79, 83, 80, 100, 64, 119,
-  83, 80, 93, 78, 77, 85, 77, 87, 90, 82,
-  76, 85, 81, 89, 92, 80, 79, 73, 83, 76,
-  103, 89, 74, 80, 85, 79, 82, 70, 85, 75,
-  78, 72, 79, 80, 89, 74, 79, 89, 77, 78,
-  80, 90, 72, 77, 79, 77, 83, 90, 82, 82,
-  64, 83, 77, 72, 72, 91, 73, 83, 77, 97,
-  83, 75, 81, 78, 89, 96, 80, 89, 80, 84,
-  97, 86, 87, 85, 84, 85, 76, 77, 82, 75,
-  87, 92, 96, 80, 83, 101, 84, 78, 82, 80,
-  86, 81, 80, 81, 77, 89, 89, 85, 81, 95,
-  85, 108, 83, 100, 82, 79, 92, 78, 91, 81,
-  76, 86, 85, 83, 77, 92, 91, 87, 84, 82,
-  84, 76, 84, 82, 80, 97, 61, 134, 85, 82,
-  85, 81, 82, 84, 80, 84, 78, 88, 80, 89,
-  83, 102, 100, 84, 78, 79, 83, 76, 104, 84,
-  74, 74, 91, 81, 83, 79, 81, 72, 77, 67,
-  83, 80, 94, 78, 79, 90, 81, 91, 69, 82,
-  79, 96, 71, 70, 87, 90, 85, 83, 61, 77,
-  83, 77, 69, 98, 72, 85, 75, 96, 85, 88,
-  78, 78, 93, 113, 75, 93, 81, 86, 96, 87,
-  86, 83, 85, 90, 97, 79, 89, 76, 86, 96,
-  114, 75, 82, 78, 88, 77, 80, 79, 79, 82,
-  82, 85, 85, 68, 80, 83, 80, 102, 90, 109,
-  87, 84, 83, 75, 93, 96, 95, 80, 78, 84,
-  93, 88, 77, 85, 76, 84, 78, 83, 82, 85,
-  84, 88, 88, 93, 79, 141, 91, 87, 86, 90,
-  85, 86, 78, 81, 84, 85, 87, 87, 89, 97,
-  92, 79, 77, 79, 81, 77, 103, 86, 72, 80,
-  87, 80, 90, 83, 81, 79, 79, 72, 82, 76,
-  79, 72, 81, 91, 77, 83, 66, 77, 74, 90,
-  77, 77, 89, 93, 84, 86, 63, 89, 79, 76,
-  74, 96, 69, 87, 77, 96, 84, 84, 77, 87,
-  94, 94, 78, 94, 81, 92, 88, 87, 91, 80,
-  87, 87, 81, 75, 85, 78, 86, 93, 92, 77,
-  83, 86, 93, 83, 84, 77, 81, 84, 79, 80,
-  81, 74, 76, 77, 79, 100, 81, 105, 82, 93,
-  84, 78, 85, 80, 89, 79, 74, 83, 85, 84,
-  75, 85, 78, 87, 78, 81, 83, 80, 83, 85,
-  85, 92, 70, 120, 88, 85, 88, 86, 83, 85,
-  84, 86, 98, 87, 84, 84, 81, 92, 96, 83,
-  83, 77, 81, 82, 98, 90, 76, 71, 91, 82,
-  82, 82, 83, 76, 81, 65, 81, 74, 91, 74,
-  81, 92, 79, 81, 80, 90, 81, 92, 81, 74,
-  94, 93, 81, 83, 68, 83, 80, 76, 74, 98,
-  75, 93, 76, 90, 84, 78, 79, 74, 94, 103,
-  76, 88, 82, 83, 96, 86, 93, 83, 86, 90,
-  78, 79, 87, 74, 86, 95, 108, 85, 79, 82,
-  87, 77, 84, 84, 81, 89, 78, 82, 82, 79,
-  82, 74, 78, 101, 86, 103, 85, 81, 79, 76,
-  94, 84, 91, 77, 78, 84, 92, 87, 76, 84,
-  85, 84, 80, 82, 82, 85, 88, 87, 86, 91,
-  68, 130, 88, 84, 86, 88, 84, 88, 90, 70,
-  93, 96, 85, 82, 90, 78, 94, 76, 66, 87,
-  71, 88, 104, 71, 94, 76, 92, 77, 82, 85,
-  96, 85, 104, 76, 72, 82, 95, 94, 69, 78,
-  85, 94, 86, 77, 76, 73, 84, 96, 91, 81,
-  90, 86, 50, 78, 131, 91, 75, 91, 94, 78,
-  95, 79, 98, 80, 96, 83, 77, 97, 78, 74,
-  70, 82, 76, 81, 84, 72, 112, 64, 70, 92,
-  88, 73, 112, 74, 83, 66, 63, 85, 64, 87,
-  79, 71, 99, 82, 81, 96, 91, 76, 88, 72,
-  85, 78, 77, 81, 82, 87, 119, 66, 84, 86,
-  78, 85, 89, 89, 91, 87, 84, 86, 68, 82,
-  89, 89, 83, 74, 103, 84, 82, 67, 88, 83,
-  76, 87, 94, 94, 69, 80, 87, 84, 89, 90,
-  83, 86, 94, 74, 96, 76, 62, 84, 79, 85,
-  112, 66, 96, 69, 93, 69, 97, 89, 87, 87,
-  105, 75, 79, 83, 99, 84, 68, 78, 90, 91,
-  91, 80, 75, 81, 92, 95, 85, 79, 84, 86,
-  55, 83, 135, 77, 72, 95, 91, 79, 92, 76,
-  96, 86, 98, 79, 79, 97, 82, 79, 70, 79,
-  68, 81, 78, 76, 105, 62, 84, 86, 83, 73,
-  109, 69, 82, 79, 68, 83, 63, 85, 86, 85,
-  97, 83, 81, 91, 91, 82, 85, 72, 81, 78,
-  70, 80, 79, 87, 112, 69, 81, 81, 75, 84,
-  86, 95, 91, 90, 89, 87, 62, 85, 87, 84,
-  75, 81, 89, 85, 83, 63, 71, 82, 71, 87,
-  93, 94, 69, 84, 88, 92, 88, 87, 88, 98,
-  91, 78, 83, 80, 74, 83, 83, 84, 101, 76,
-  93, 76, 94, 81, 102, 84, 92, 86, 97, 72,
-  77, 83, 87, 81, 69, 84, 86, 95, 95, 85,
-  79, 74, 89, 91, 94, 79, 78, 79, 59, 77,
-  112, 65, 77, 93, 93, 76, 93, 81, 96, 86,
-  85, 90, 75, 90, 85, 80, 78, 73, 81, 84,
-  86, 77, 105, 68, 96, 99, 86, 80, 105, 77,
-  80, 83, 75, 89, 68, 78, 81, 89, 95, 87,
-  83, 94, 89, 87, 88, 78, 84, 80, 80, 86,
-  84, 85, 101, 78, 84, 84, 75, 84, 87, 96,
-  86, 92, 90, 85, 61, 80, 86, 79, 82, 88,
-  77, 87, 88, 72, 64, 79, 80, 87, 93, 95,
-  72, 82, 90, 67, 83, 99, 84, 95, 86, 84,
-  94, 87, 72, 88, 75, 86, 89, 70, 90, 78,
-  83, 74, 72, 81, 87, 83, 94, 73, 65, 90,
-  96, 82, 64, 77, 83, 93, 82, 81, 71, 81,
-  81, 88, 91, 83, 74, 80, 59, 82, 124, 95,
-  77, 91, 95, 79, 81, 88, 82, 82, 88, 84,
-  85, 93, 77, 64, 70, 90, 80, 88, 87, 66,
-  114, 65, 74, 82, 87, 64, 104, 71, 79, 70,
-  62, 85, 70, 92, 89, 76, 94, 84, 83, 88,
-  90, 79, 87, 82, 85, 79, 83, 73, 84, 88,
-  117, 78, 85, 82, 70, 81, 91, 78, 86, 86,
-  86, 84, 70, 81, 87, 88, 80, 76, 95, 84,
-  77, 67, 92, 86, 74, 84, 90, 86, 73, 85,
-  88, 79, 88, 88, 82, 93, 87, 86, 92, 86,
-  70, 85, 76, 81, 94, 61, 91, 70, 81, 72,
-  80, 90, 87, 82, 104, 72, 66, 89, 96, 75,
-  64, 79, 83, 86, 84, 82, 73, 84, 84, 85,
-  88, 85, 73, 79, 62, 82, 128, 83, 75, 96,
-  92, 80, 77, 85, 83, 86, 88, 83, 90, 93,
-  81, 71, 69, 88, 76, 90, 88, 71, 111, 65,
-  83, 76, 84, 64, 104, 65, 79, 80, 64, 82,
-  71, 90, 93, 86, 93, 88, 80, 85, 88, 77,
-  82, 73, 83, 80, 74, 71, 83, 87, 97, 80,
-  82, 79, 70, 80, 89, 85, 84, 86, 84, 82,
-  64, 85, 87, 85, 73, 83, 85, 83, 80, 66,
-  78, 87, 63, 88, 85, 87, 76, 88, 91, 89,
-  97, 86, 84, 96, 89, 85, 80, 91, 75, 87,
-  79, 82, 85, 69, 86, 80, 89, 82, 87, 87,
-  100, 83, 97, 73, 73, 88, 87, 79, 69, 84,
-  85, 86, 88, 85, 78, 81, 81, 79, 96, 81,
-  74, 75, 65, 80, 104, 73, 79, 91, 90, 80,
-  87, 87, 89, 90, 83, 91, 85, 87, 83, 77,
-  76, 82, 85, 92, 90, 71, 103, 76, 90, 89,
-  89, 72, 99, 73, 81, 81, 70, 87, 74, 83,
-  85, 89, 91, 85, 82, 88, 86, 87, 87, 83,
-  84, 78, 83, 80, 84, 90, 83, 86, 87, 73,
-  74, 82, 91, 88, 79, 89, 88, 80, 67, 84,
-  88, 84, 82, 89, 82, 87, 82, 74, 74, 84,
-  77, 84, 90, 88, 73, 84, 90, 74, 72, 100,
-  79, 111, 77, 85, 84, 94, 69, 89, 75, 88,
-  84, 80, 105, 99, 86, 80, 66, 73, 83, 80,
-  96, 78, 72, 94, 98, 82, 66, 77, 74, 90,
-  77, 76, 86, 85, 86, 90, 99, 59, 68, 81,
-  62, 87, 126, 93, 81, 90, 86, 74, 85, 90,
-  87, 80, 77, 83, 91, 90, 87, 68, 76, 92,
-  85, 79, 93, 68, 114, 79, 76, 75, 96, 66,
-  103, 74, 68, 69, 73, 82, 72, 100, 89, 85,
-  90, 86, 86, 91, 85, 88, 88, 111, 75, 80,
-  97, 75, 76, 99, 114, 81, 83, 82, 67, 77,
-  86, 69, 79, 89, 87, 84, 71, 80, 91, 82,
-  77, 74, 82, 83, 77, 70, 87, 91, 97, 70,
-  90, 90, 74, 81, 88, 80, 83, 92, 79, 90,
-  75, 91, 85, 97, 72, 88, 80, 86, 83, 74,
-  108, 95, 84, 80, 65, 83, 96, 78, 113, 81,
-  68, 96, 97, 71, 71, 76, 76, 81, 76, 80,
-  86, 86, 90, 90, 97, 62, 69, 79, 65, 80,
-  138, 81, 80, 95, 85, 77, 81, 85, 86, 75,
-  78, 83, 100, 92, 85, 70, 75, 95, 79, 83,
-  101, 75, 115, 77, 76, 77, 93, 66, 107, 70,
-  67, 83, 69, 81, 71, 98, 90, 85, 89, 93,
-  78, 90, 81, 81, 88, 96, 81, 86, 80, 72,
-  74, 98, 93, 81, 81, 78, 64, 77, 83, 74,
-  79, 89, 84, 85, 70, 83, 92, 79, 72, 81,
-  80, 82, 85, 69, 84, 95, 94, 78, 87, 89,
-  77, 89, 95, 85, 98, 90, 82, 84, 80, 92,
-  76, 95, 76, 85, 77, 81, 79, 77, 104, 97,
-  87, 86, 74, 80, 109, 84, 109, 79, 75, 90,
-  89, 74, 75, 84, 76, 75, 86, 81, 88, 87,
-  88, 83, 101, 65, 77, 77, 69, 83, 114, 71,
-  79, 88, 88, 77, 87, 87, 94, 81, 77, 87,
-  92, 84, 87, 78, 80, 88, 83, 85, 96, 67,
-  101, 87, 79, 79, 99, 73, 97, 75, 78, 88,
-  73, 82, 75, 91, 85, 85, 82, 88, 77, 86,
-  86, 87, 85, 96, 76, 79, 86, 81, 81, 98,
-  72, 84, 84, 74, 68, 80, 83, 71, 74, 90,
-  86, 75, 74, 83, 92, 82, 84, 85, 86, 86,
-  77, 77, 85, 89, 86, 73, 86, 91, 73, 84,
-  86, 71, 124, 94, 71, 98, 88, 79, 83, 92,
-  73, 70, 82, 91, 77, 80, 76, 99, 80, 86,
-  95, 81, 109, 87, 93, 75, 98, 93, 90, 99,
-  81, 82, 93, 70, 79, 90, 90, 86, 83, 77,
-  90, 72, 72, 65, 79, 87, 88, 76, 89, 87,
-  75, 85, 96, 81, 89, 80, 90, 68, 85, 84,
-  87, 93, 81, 70, 89, 79, 93, 90, 68, 89,
-  72, 86, 95, 85, 84, 85, 88, 92, 69, 69,
-  78, 83, 79, 96, 75, 89, 87, 91, 79, 79,
-  97, 74, 88, 72, 91, 82, 72, 73, 62, 84,
-  88, 77, 82, 83, 81, 93, 75, 92, 77, 90,
-  87, 78, 83, 80, 68, 92, 92, 90, 74, 90,
-  101, 84, 78, 77, 82, 92, 80, 83, 100, 70,
-  108, 83, 85, 79, 86, 74, 87, 79, 81, 80,
-  88, 77, 86, 74, 92, 92, 86, 80, 94, 75,
-  94, 86, 99, 75, 81, 87, 93, 106, 101, 81,
-  85, 70, 73, 77, 83, 78, 100, 74, 80, 93,
-  58, 76, 88, 73, 86, 74, 79, 83, 85, 76,
-  88, 88, 87, 83, 81, 86, 85, 78, 86, 80,
-  80, 89, 71, 92, 93, 79, 67, 86, 71, 90,
-  82, 83, 85, 78, 98, 90, 62, 97, 77, 93,
-  82, 97, 89, 84, 71, 86, 75, 76, 83, 67,
-  78, 79, 73, 90, 83, 107, 65, 78, 79, 83,
-  81, 84, 83, 105, 70, 85, 78, 85, 92, 83,
-  87, 74, 86, 95, 73, 86, 79, 82, 93, 93,
-  83, 77, 83, 84, 88, 88, 83, 83, 127, 87,
-  90, 74, 81, 74, 92, 75, 90, 76, 76, 65,
-  93, 86, 85, 81, 82, 82, 84, 71, 90, 89,
-  104, 76, 75, 81, 88, 111, 103, 75, 82, 66,
-  71, 89, 68, 84, 99, 75, 92, 76, 57, 77,
-  85, 76, 106, 72, 82, 83, 76, 69, 78, 88,
-  83, 77, 76, 110, 80, 83, 89, 87, 77, 107,
-  88, 86, 97, 77, 75, 71, 82, 88, 79, 92,
-  93, 80, 97, 82, 66, 84, 79, 93, 83, 93,
-  98, 99, 63, 88, 72, 76, 80, 72, 83, 84,
-  78, 89, 89, 114, 62, 76, 83, 75, 82, 83,
-  94, 91, 71, 78, 80, 78, 91, 82, 83, 76,
-  88, 86, 86, 83, 92, 75, 95, 91, 81, 79,
-  80, 89, 91, 82, 95, 67, 105, 83, 76, 87,
-  84, 73, 78, 83, 89, 75, 92, 83, 85, 62,
-  86, 92, 89, 70, 85, 81, 95, 94, 101, 77,
-  85, 88, 91, 114, 104, 76, 85, 68, 71, 74,
-  94, 77, 96, 74, 83, 97, 60, 71, 93, 75,
-  91, 71, 80, 82, 71, 75, 90, 91, 89, 88,
-  78, 94, 77, 81, 94, 88, 74, 97, 68, 98,
-  103, 84, 69, 73, 64, 86, 84, 88, 81, 72,
-  90, 77, 65, 90, 78, 91, 79, 88, 88, 80,
-  72, 89, 78, 74, 83, 70, 85, 84, 80, 84,
-  83, 108, 64, 75, 81, 78, 88, 81, 84, 94,
-  76, 89, 75, 90, 87, 84, 89, 64, 87, 95,
-  81, 88, 82, 81, 94, 88, 75, 75, 77, 86,
-  90, 89, 93, 74, 123, 90, 94, 66, 82, 70,
-  85, 81, 90, 76, 96, 83, 90, 80, 90, 78,
-  80, 77, 87, 77, 78, 94, 102, 79, 77, 84,
-  89, 115, 106, 83, 84, 69, 65, 76, 76, 88,
-  95, 76, 88, 89, 57, 84, 94, 79, 98, 72,
-  76, 79, 73, 76, 86, 96, 78, 78, 70, 99,
-  81, 80, 89, 82, 78, 97, 62, 95, 103, 68,
-  79, 74, 66, 84, 76, 88, 82, 73, 97, 87,
-  64, 95, 85, 95, 87, 89, 99, 94, 64, 85,
-  75, 70, 77, 70, 76, 85, 70, 91, 86, 105,
-  64, 75, 75, 78, 89, 82, 87, 86, 78, 83,
-  75, 79, 87, 79, 85, 64, 91, 102, 81, 87,
-  89, 76, 90, 89, 82, 75, 81, 84, 87, 86,
-  75, 83, 126, 87, 86, 67, 76, 73, 92, 85,
-  80, 75, 77, 89, 74, 96, 79, 72, 79, 85,
-  93, 75, 80, 95, 91, 72, 83, 77, 87, 114,
-  89, 78, 83, 65, 72, 87, 74, 93, 81, 69,
-  91, 53, 68, 77, 68, 89, 103, 70, 90, 80,
-  68, 87, 82, 88, 89, 76, 84, 95, 90, 80,
-  87, 100, 92, 81, 83, 69, 97, 77, 77, 77,
-  78, 69, 97, 90, 86, 82, 85, 84, 84, 67,
-  89, 87, 83, 86, 88, 104, 76, 86, 84, 71,
-  79, 82, 81, 75, 91, 78, 84, 72, 65, 81,
-  88, 82, 82, 81, 91, 88, 81, 80, 76, 76,
-  76, 81, 81, 79, 88, 88, 103, 80, 84, 90,
-  102, 81, 79, 75, 82, 97, 82, 82, 87, 67,
-  119, 92, 78, 86, 81, 68, 74, 74, 84, 77,
-  105, 75, 84, 72, 85, 83, 84, 77, 99, 75,
-  84, 94, 97, 75, 81, 84, 93, 115, 99, 91,
-  80, 76, 64, 81, 83, 89, 93, 89, 94, 97,
-  51, 74, 91, 69, 92, 77, 91, 76, 69, 64,
-  79, 92, 76, 74, 77, 95, 81, 83, 93, 78,
-  81, 84, 69, 87, 98, 86, 85, 80, 72, 99,
-  73, 88, 77, 75, 89, 87, 63, 109, 78, 85,
-  86, 87, 96, 91, 69, 79, 84, 75, 81, 70,
-  88, 96, 70, 86, 91, 99, 76, 85, 69, 78,
-  88, 79, 91, 84, 78, 80, 63, 76, 76, 73,
-  82, 64, 89, 86, 67, 95, 92, 72, 91, 84,
-  74, 77, 86, 89, 83, 82, 74, 77, 122, 87,
-  80, 94, 80, 70, 84, 80, 76, 76, 88, 96,
-  74, 92, 78, 81, 80, 85, 110, 82, 86, 89,
-  81, 69, 82, 78, 95, 115, 80, 88, 83, 70,
-  74, 91, 82, 88, 79, 75, 92, 62, 57, 74,
-  82, 84, 91, 74, 92, 75, 70, 84, 80, 83,
-  89, 68, 82, 83, 93, 79, 85, 83, 95, 51,
-  72, 67, 81, 80, 77, 82, 74, 82, 90, 90,
-  75, 87, 88, 97, 70, 87, 84, 82, 79, 90,
-  80, 93, 86, 83, 91, 71, 85, 78, 82, 74,
-  92, 78, 85, 66, 67, 80, 81, 69, 80, 80,
-  82, 85, 82, 81, 70, 76, 75, 77, 77, 78,
-  82, 89, 101, 81, 80, 86, 98, 83, 83, 75,
-  83, 91, 75, 77, 65, 79, 101, 80, 86, 78,
-  85, 81, 87, 93, 76, 87, 71, 102, 77, 89,
-  74, 86, 96, 93, 127, 82, 78, 85, 78, 81,
-  91, 76, 95, 104, 87, 83, 87, 77, 75, 76,
-  77, 84, 76, 67, 84, 57, 68, 91, 82, 96,
-  90, 74, 101, 82, 75, 102, 85, 83, 92, 70,
-  109, 82, 106, 84, 81, 82, 96, 66, 79, 69,
-  77, 97, 71, 69, 78, 74, 100, 100, 79, 105,
-  86, 82, 81, 76, 91, 84, 83, 87, 75, 90,
-  94, 90, 93, 77, 95, 83, 84, 76, 94, 75,
-  80, 64, 66, 88, 91, 86, 87, 80, 83, 83,
-  90, 92, 83, 89, 82, 79, 94, 81, 78, 80,
-  97, 81, 89, 99, 96, 87, 85, 96, 92, 92,
-  82, 80, 81, 88, 79, 82, 65, 78, 77, 85,
-  83, 98, 81, 90, 76, 77, 76, 81, 81, 97,
-  83, 97, 82, 76, 109, 98, 88, 81, 94, 84,
-  89, 86, 82, 82, 98, 93, 99, 87, 86, 88,
-  79, 78, 80, 90, 70, 77, 96, 74, 85, 77,
-  83, 79, 76, 96, 93, 78, 96, 76, 86, 67,
-  101, 92, 89, 81, 80, 65, 74, 86, 79, 77,
-  73, 91, 77, 88, 77, 85, 81, 96, 94, 91,
-  89, 80, 82, 72, 76, 110, 73, 82, 97, 81,
-  91, 84, 90, 75, 90, 74, 84, 77, 85, 89,
-  84, 95, 67, 85, 85, 91, 85, 89, 91, 93,
-  100, 108, 87, 69, 88, 85, 70, 93, 80, 83,
-  86, 88, 70, 93, 91, 90, 76, 82, 79, 98,
-  93, 76, 81, 74, 109, 65, 71, 76, 74, 92,
-  92, 83, 87, 87, 80, 69, 79, 78, 77, 99,
-  84, 83, 95, 82, 88, 73, 72, 83, 89, 86,
-  76, 86, 78, 92, 88, 85, 90, 77, 81, 82,
-  82, 86, 78, 82, 94, 67, 76, 74, 94, 65,
-  93, 75, 77, 90, 68, 82, 84, 87, 75, 84,
-  93, 89, 90, 73, 77, 84, 77, 79, 95, 87,
-  83, 96, 79, 75, 83, 85, 73, 86, 97, 95,
-  74, 89, 76, 115, 101, 76, 96, 87, 71, 84,
-  83, 74, 72, 91, 80, 103, 93, 89, 93, 99,
-  71, 89, 78, 91, 89, 84, 81, 95, 106, 79,
-  88, 77, 80, 83, 92, 84, 60, 99, 80, 76,
-  71, 69, 75, 77, 86, 77, 88, 62, 96, 80,
-  90, 86, 111, 78, 71, 81, 66, 89, 95, 79,
-  89, 78, 80, 73, 79, 67, 69, 102, 87, 88,
-  76, 68, 90, 78, 65, 80, 88, 87, 79, 97,
-  72, 94, 89, 96, 84, 70, 72, 84, 82, 77,
-  97, 78, 94, 68, 64, 90, 101, 64, 86, 65,
-  71, 101, 54, 76, 70, 107, 66, 83, 99, 96,
-  93, 90, 87, 93, 73, 85, 101, 76, 91, 110,
-  77, 74, 87, 74, 67, 98, 108, 104, 74, 101,
-  72, 93, 111, 81, 99, 91, 80, 79, 70, 79,
-  67, 95, 84, 115, 92, 96, 93, 84, 75, 90,
-  79, 93, 92, 73, 84, 87, 103, 65, 94, 84,
-  76, 92, 102, 86, 75, 104, 77, 82, 84, 74,
-  70, 72, 96, 77, 87, 53, 79, 84, 85, 87,
-  58, 81, 82, 84, 92, 96, 79, 87, 77, 75,
-  72, 94, 81, 103, 87, 88, 80, 78, 91, 94,
-  82, 74, 105, 84, 93, 90, 81, 76, 99, 85,
-  103, 82, 89, 90, 70, 78, 80, 92, 72, 76,
-  82, 84, 95, 78, 72, 92, 73, 97, 94, 75,
-  102, 74, 92, 68, 107, 89, 87, 75, 72, 60,
-  66, 78, 70, 71, 72, 89, 76, 81, 89, 91,
-  81, 93, 97, 81, 89, 74, 85, 70, 87, 96,
-  70, 80, 95, 73, 87, 85, 89, 89, 89, 73,
-  84, 59, 71, 79, 81, 94, 78, 83, 90, 88,
-  81, 84, 78, 88, 92, 111, 85, 81, 93, 85,
-  72, 85, 74, 68, 81, 89, 67, 101, 99, 94,
-  80, 76, 81, 105, 89, 75, 74, 78, 87, 69,
-  73, 81, 80, 91, 84, 88, 83, 91, 83, 71,
-  82, 85, 83, 90, 83, 86, 96, 94, 83, 65,
-  89, 84, 92, 77, 67, 87, 90, 97, 94, 89,
-  74, 83, 76, 79, 83, 86, 74, 76, 80, 68,
-  80, 77, 83, 75, 91, 81, 81, 78, 76, 79,
-  90, 76, 83, 88, 95, 91, 79, 70, 71, 80,
-  72, 76, 93, 87, 75, 81, 83, 81, 77, 83,
-  87, 84, 93, 86, 71, 82, 81, 108, 89, 79,
-  93, 85, 70, 85, 88, 75, 80, 82, 83, 77,
-  83, 85, 89, 101, 70, 94, 81, 91, 75, 88,
-  83, 93, 92, 92, 79, 94, 85, 86, 81, 81,
-  62, 85, 77, 77, 72, 79, 80, 77, 71, 69,
-  88, 75, 95, 85, 85, 87, 100, 81, 77, 83,
-  72, 88, 88, 82, 88, 83, 82, 73, 89, 70,
-  73, 94, 89, 86, 84, 84, 86, 75, 83, 85,
-  94, 88, 69, 97, 79, 88, 90, 97, 66, 78,
-  82, 78, 85, 77, 86, 80, 86, 70, 69, 92,
-  93, 65, 98, 61, 75, 89, 62, 84, 76, 102,
-  72, 80, 96, 101, 81, 83, 82, 89, 79, 82,
-  108, 85, 85, 90, 77, 76, 81, 72, 82, 93,
-  97, 100, 72, 96, 73, 86, 107, 91, 89, 97,
-  78, 82, 75, 71, 75, 88, 80, 94, 86, 98,
-  87, 84, 76, 94, 79, 92, 74, 83, 91, 91,
-  91, 78, 86, 98, 78, 88, 91, 81, 80, 95,
-  74, 80, 83, 76, 71, 69, 78, 72, 85, 64,
-  84, 85, 90, 93, 69, 84, 84, 82, 96, 88,
-  70, 83, 82, 73, 72, 104, 70, 101, 78, 85,
-  81, 82, 93, 91, 87, 85, 94, 75, 85, 85,
-  86, 78, 86, 85, 84, 80, 81, 92, 75, 87,
-  83, 78, 76, 89, 79, 89, 92, 77, 71, 95,
-  65, 108, 95, 82, 107, 83, 89, 84, 102, 86,
-  90, 77, 80, 70, 83, 73, 75, 80, 69, 99,
-  79, 74, 71, 86, 83, 81, 92, 79, 89, 71,
-  104, 72, 88, 89, 80, 88, 93, 67, 94, 92,
-  81, 90, 79, 71, 85, 68, 70, 82, 78, 86,
-  72, 85, 88, 78, 90, 73, 70, 78, 86, 94,
-  93, 68, 88, 82, 77, 90, 84, 67, 80, 88,
-  58, 95, 95, 89, 97, 85, 73, 87, 90, 87,
-  83, 87, 74, 73, 76, 83, 97, 90, 74, 92,
-  80, 77, 81, 81, 68, 95, 80, 82, 82, 89,
-  101, 91, 91, 77, 97, 83, 82, 78, 76, 83,
-  98, 81, 92, 90, 79, 88, 79, 80, 87, 76,
-  75, 80, 73, 81, 81, 73, 77, 101, 77, 100,
-  91, 78, 98, 81, 84, 80, 92, 89, 92, 82,
-  82, 83, 83, 81, 80, 82, 71, 94, 71, 77,
-  80, 91, 79, 82, 92, 86, 87, 67, 89, 74,
-  90, 104, 85, 84, 91, 81, 84, 88, 88, 85,
-  81, 73, 79, 66, 83, 82, 80, 92, 78, 81,
-  82, 82, 86, 76, 80, 83, 85, 92, 85, 78,
-  83, 84, 74, 89, 75, 71, 81, 84, 72, 89,
-  92, 80, 85, 82, 79, 88, 92, 83, 94, 92,
-  80, 82, 79, 80, 89, 89, 78, 92, 85, 84,
-  85, 77, 71, 85, 73, 82, 87, 88, 98, 88,
-  91, 84, 96, 84, 88, 92, 76, 89, 86, 87,
-  83, 92, 71, 89, 83, 82, 89, 81, 83, 77,
-  77, 80, 75, 92, 85, 89, 92, 90, 87, 83,
-  90, 80, 74, 90, 87, 88, 93, 95, 84, 84,
-  85, 91, 80, 87, 83, 81, 86, 89, 78, 83,
-  81, 84, 94, 83, 82, 77, 87, 83, 84, 90,
-  96, 91, 92, 88, 92, 85, 87, 81, 78, 78,
-  78, 78, 89, 92, 77, 86, 76, 85, 79, 85,
-  78, 84, 89, 86, 86, 86, 92, 85, 78, 88,
-  81, 81, 91, 80, 81, 85, 85, 82, 86, 72,
-  80, 83, 78, 73,
-};
-
-unsigned char expected_c_data[c_count] = {
-  166, 113, 100, 112, 92, 110, 111, 106, 135, 122,
-  107, 118, 103, 122, 139, 115, 133, 93, 102, 103,
-  108, 107, 92, 93, 105, 111, 148, 115, 108, 121,
-  123, 102, 136, 137, 101, 137, 113, 99, 115, 128,
-  151, 105, 119, 99, 98, 98, 102, 89, 78, 99,
-  125, 118, 124, 145, 126, 107, 118, 130, 141, 105,
-  121, 108, 121, 123, 150, 158, 121, 90, 101, 115,
-  110, 115, 104, 124, 99, 117, 197, 111, 122, 111,
-  118, 117, 81, 116, 107, 107, 159, 131, 90, 119,
-  122, 111, 102, 112, 115, 132, 107, 91, 114, 149,
-  138, 106, 146, 104, 114, 99, 141, 97, 98, 88,
-  137, 107, 93, 124, 100, 82, 116, 94, 100, 102,
-  132, 120, 123, 129, 108, 129, 95, 113, 121, 129,
-  105, 108, 107, 141, 109, 77, 117, 102, 101, 131,
-  92, 118, 111, 122, 97, 115, 147, 119, 112, 113,
-  125, 120, 110, 111, 77, 109, 106, 103, 101, 109,
-  92, 102, 155, 91, 88, 105, 122, 105, 112, 102,
-  119, 94, 111, 103, 82, 123, 85, 105, 79, 141,
-  124, 121, 116, 110, 134, 99, 117, 72, 86, 108,
-  118, 103, 169, 122, 140, 102, 80, 105, 97, 94,
-  144, 158, 97, 127, 112, 138, 131, 104, 120, 82,
-  84, 93, 109, 106, 70, 89, 94, 112, 130, 124,
-  119, 117, 109, 97, 110, 131, 89, 116, 97, 119,
-  129, 96, 156, 78, 121, 118, 89, 89, 101, 102,
-  28, 108, 145, 125, 115, 132, 116, 108, 144, 127,
-  120, 121, 130, 116, 116, 136, 147, 152, 113, 84,
-  89, 114, 126, 104, 122, 117, 98, 82, 149, 104,
-  139, 91, 109, 124, 91, 115, 129, 134, 203, 144,
-  86, 102, 119, 112, 97, 99, 120, 127, 103, 76,
-  116, 155, 156, 113, 170, 96, 123, 99, 155, 125,
-  84, 85, 139, 119, 90, 140, 82, 87, 113, 99,
-  91, 104, 148, 145, 115, 121, 97, 131, 72, 120,
-  125, 131, 144, 68, 112, 164, 111, 84, 124, 92,
-  82, 146, 104, 112, 132, 135, 90, 121, 151, 134,
-  105, 113, 122, 125, 104, 118, 106, 98, 88, 102,
-  111, 108, 138, 116, 147, 79, 122, 112, 112, 144,
-  91, 71, 113, 119, 89, 102, 95, 122, 71, 102,
-  77, 149, 123, 108, 125, 89, 145, 100, 129, 85,
-  76, 110, 105, 126, 156, 112, 139, 104, 63, 95,
-  85, 106, 124, 166, 79, 121, 129, 132, 122, 102,
-  105, 93, 83, 82, 119, 101, 86, 131, 78, 103,
-  118, 127, 132, 103, 110, 94, 99, 109, 100, 130,
-  77, 146, 158, 88, 132, 95, 117, 108, 72, 120,
-  115, 121, 34, 129, 158, 115, 118, 98, 111, 122,
-  134, 99, 101, 121, 114, 125, 112, 125, 124, 110,
-  103, 96, 98, 127, 113, 105, 122, 110, 103, 85,
-  140, 119, 128, 110, 125, 114, 116, 85, 145, 135,
-  197, 142, 78, 86, 101, 132, 104, 109, 148, 129,
-  110, 93, 112, 126, 139, 114, 165, 100, 132, 102,
-  140, 165, 61, 131, 104, 120, 86, 143, 81, 105,
-  101, 124, 73, 107, 144, 156, 121, 120, 72, 129,
-  80, 122, 113, 123, 146, 55, 103, 148, 117, 142,
-  110, 101, 62, 162, 100, 100, 152, 144, 104, 114,
-  131, 146, 105, 118, 87, 105, 92, 107, 114, 88,
-  72, 112, 108, 135, 134, 142, 114, 97, 134, 101,
-  122, 158, 76, 81, 121, 140, 77, 102, 125, 105,
-  70, 94, 100, 141, 105, 103, 151, 93, 136, 112,
-  108, 94, 71, 113, 116, 132, 152, 97, 107, 107,
-  75, 113, 77, 134, 110, 128, 71, 110, 110, 95,
-  104, 79, 96, 97, 86, 93, 116, 134, 90, 131,
-  66, 90, 112, 111, 134, 97, 131, 130, 116, 91,
-  98, 140, 66, 127, 151, 119, 125, 104, 119, 72,
-  77, 109, 107, 116, 33, 128, 145, 129, 104, 109,
-  114, 121, 124, 94, 91, 146, 100, 113, 108, 130,
-  105, 89, 92, 98, 87, 98, 96, 97, 118, 120,
-  105, 132, 147, 141, 106, 119, 122, 116, 116, 79,
-  104, 115, 188, 130, 69, 97, 116, 117, 114, 111,
-  152, 127, 121, 100, 118, 115, 120, 116, 145, 89,
-  130, 115, 110, 138, 75, 134, 109, 90, 94, 145,
-  89, 115, 97, 137, 65, 111, 125, 134, 125, 145,
-  67, 115, 95, 116, 92, 126, 98, 79, 107, 134,
-  122, 128, 101, 118, 60, 161, 79, 106, 134, 128,
-  108, 99, 102, 122, 84, 116, 73, 121, 98, 95,
-  70, 74, 56, 98, 79, 147, 126, 127, 101, 110,
-  144, 114, 135, 112, 80, 95, 130, 165, 90, 126,
-  98, 99, 65, 98, 134, 138, 91, 114, 153, 104,
-  127, 116, 97, 89, 78, 112, 109, 111, 173, 110,
-  152, 106, 115, 154, 75, 128, 109, 91, 95, 114,
-  131, 101, 114, 90, 94, 104, 92, 112, 117, 101,
-  94, 99, 80, 114, 119, 95, 134, 109, 153, 139,
-  126, 111, 113, 130, 90, 105, 127, 122, 137, 103,
-  128, 59, 102, 109, 96, 121, 42, 128, 135, 138,
-  88, 142, 122, 118, 121, 110, 112, 143, 106, 112,
-  112, 117, 136, 120, 111, 123, 83, 88, 116, 97,
-  132, 131, 111, 108, 157, 130, 86, 106, 118, 121,
-  116, 108, 106, 96, 177, 130, 74, 93, 107, 114,
-  113, 121, 111, 137, 124, 85, 121, 135, 137, 131,
-  140, 91, 124, 106, 109, 100, 98, 103, 114, 109,
-  120, 133, 110, 113, 97, 137, 84, 121, 119, 129,
-  117, 135, 84, 117, 103, 119, 118, 97, 105, 100,
-  94, 114, 119, 118, 104, 117, 76, 155, 86, 134,
-  119, 124, 107, 106, 111, 104, 102, 114, 102, 112,
-  112, 118, 86, 102, 80, 97, 93, 115, 101, 100,
-  99, 107, 117, 129, 137, 107, 96, 123, 116, 134,
-  97, 104, 99, 111, 74, 97, 114, 133, 97, 131,
-  143, 103, 127, 106, 106, 81, 100, 118, 106, 100,
-  182, 115, 96, 110, 101, 149, 74, 123, 131, 88,
-  100, 112, 128, 98, 131, 95, 101, 105, 92, 124,
-  104, 84, 91, 128, 83, 97, 118, 93, 135, 105,
-  144, 109, 145, 118, 106, 126, 95, 108, 112, 126,
-  125, 98, 126, 59, 124, 111, 102, 129, 45, 119,
-  131, 115, 77, 141, 129, 126, 104, 125, 107, 122,
-  117, 105, 119, 117, 143, 133, 125, 106, 89, 93,
-  134, 103, 133, 120, 106, 108, 169, 124, 79, 105,
-  108, 128, 77, 106, 107, 100, 153, 134, 74, 79,
-  108, 135, 106, 118, 96, 125, 113, 72, 108, 133,
-  155, 112, 160, 89, 131, 77, 118, 110, 89, 89,
-  114, 120, 107, 126, 99, 114, 90, 120, 84, 120,
-  123, 124, 113, 126, 96, 120, 101, 125, 99, 104,
-  96, 98, 98, 113, 106, 119, 103, 104, 100, 149,
-  98, 131, 126, 125, 112, 108, 127, 103, 113, 115,
-  117, 97, 104, 116, 70, 91, 84, 97, 88, 103,
-  84, 127, 110, 91, 99, 126, 140, 84, 104, 113,
-  103, 100, 91, 90, 93, 125, 70, 93, 95, 115,
-  105, 128, 139, 109, 137, 98, 99, 75, 97, 111,
-  109, 105, 166, 123, 106, 112, 93, 132, 82, 102,
-  132, 90, 97, 117, 124, 111, 128, 101, 104, 94,
-  96, 130, 93, 74, 89, 128, 86, 100, 124, 86,
-  132, 113, 129, 105, 140, 128, 108, 109, 99, 105,
-  104, 120, 123, 89, 119, 52, 134, 110, 96, 133,
-  52, 106, 129, 114, 80, 128, 124, 121, 101, 112,
-  102, 119, 126, 96, 112, 120, 143, 134, 125, 107,
-  94, 99, 138, 104, 129, 110, 105, 110, 173, 110,
-  104, 92, 105, 123, 79, 100, 108, 111, 150, 139,
-  77, 80, 131, 132, 103, 105, 101, 110, 107, 70,
-  107, 127, 155, 107, 171, 97, 125, 77, 128, 113,
-  90, 85, 108, 121, 124, 126, 87, 113, 89, 97,
-  91, 119, 114, 131, 122, 115, 103, 127, 89, 117,
-  92, 89, 89, 84, 98, 108, 100, 98, 114, 87,
-  108, 137, 113, 136, 128, 137, 114, 105, 124, 125,
-  117, 119, 115, 125, 89, 108, 84, 93, 98, 95,
-  83, 101, 99, 137, 106, 85, 109, 134, 138, 104,
-  112, 92, 95, 110, 88, 81, 108, 134, 57, 80,
-  86, 119, 116, 115, 145, 101, 140, 97, 93, 78,
-  97, 119, 101, 110, 149, 117, 103, 118, 103, 125,
-  85, 99, 116, 95, 84, 118, 125, 124, 111, 99,
-  109, 94, 90, 124, 90, 66, 82, 123, 86, 105,
-  126, 78, 114, 109, 126, 97, 119, 148, 104, 89,
-  101, 105, 103, 115, 118, 81, 109, 56, 125, 107,
-  84, 123, 62, 102, 122, 103, 83, 111, 105, 106,
-  100, 93, 112, 118, 135, 97, 110, 116, 143, 147,
-  125, 103, 91, 94, 138, 99, 123, 111, 110, 111,
-  165, 108, 117, 89, 99, 120, 67, 101, 105, 106,
-  134, 137, 87, 79, 119, 114, 102, 96, 103, 114,
-  102, 71, 107, 143, 154, 91, 167, 104, 103, 90,
-  126, 102, 89, 80, 114, 131, 118, 128, 77, 107,
-  99, 87, 98, 110, 104, 125, 130, 118, 106, 125,
-  73, 119, 96, 91, 86, 72, 88, 107, 94, 102,
-  121, 77, 109, 114, 114, 138, 128, 142, 113, 102,
-  108, 133, 112, 113, 121, 117, 77, 106, 83, 107,
-  108, 88, 85, 96, 102, 119, 97, 76, 100, 135,
-  132, 101, 111, 80, 89, 117, 83, 69, 98, 124,
-  48, 67, 85, 123, 122, 109, 149, 90, 136, 93,
-  102, 79, 96, 140, 96, 114, 137, 110, 105, 122,
-  109, 118, 85, 106, 101, 100, 82, 112, 120, 128,
-  105, 96, 110, 97, 89, 110, 86, 69, 74, 110,
-  90, 114, 126, 71, 99, 104, 121, 87, 101, 164,
-  99, 76, 104, 104, 101, 104, 118, 84, 102, 64,
-  112, 96, 68, 118, 68, 98, 111, 106, 84, 101,
-  93, 99, 103, 90, 124, 120, 140, 95, 104, 111,
-  146, 155, 117, 94, 87, 90, 128, 97, 116, 114,
-  117, 96, 161, 106, 117, 88, 92, 115, 58, 103,
-  102, 96, 120, 125, 88, 74, 113, 96, 97, 90,
-  101, 110, 96, 67, 105, 156, 149, 90, 152, 98,
-  78, 95, 122, 86, 95, 71, 121, 133, 111, 129,
-  68, 97, 109, 78, 108, 99, 97, 113, 138, 112,
-  110, 119, 67, 115, 92, 97, 86, 72, 89, 112,
-  86, 102, 123, 69, 107, 98, 114, 122, 118, 145,
-  113, 99, 100, 126, 104, 110, 118, 103, 68, 104,
-  81, 121, 109, 78, 93, 87, 111, 100, 95, 74,
-  100, 126, 128, 100, 113, 81, 94, 121, 84, 71,
-  82, 119, 47, 63, 80, 122, 129, 107, 147, 80,
-  137, 84, 106, 77, 102, 153, 95, 118, 128, 106,
-  111, 123, 113, 118, 81, 114, 96, 105, 88, 110,
-  121, 125, 108, 94, 108, 94, 87, 105, 85, 74,
-  76, 95, 93, 120, 123, 76, 101, 104, 115, 78,
-  87, 163, 96, 73, 106, 111, 93, 93, 128, 87,
-  108, 75, 107, 90, 63, 118, 69, 89, 115, 112,
-  83, 98, 86, 95, 109, 94, 131, 124, 146, 102,
-  96, 109, 148, 153, 113, 99, 82, 85, 115, 93,
-  118, 112, 117, 84, 155, 108, 110, 102, 87, 110,
-  58, 114, 106, 82, 113, 109, 87, 77, 108, 86,
-  95, 95, 107, 107, 93, 65, 99, 166, 147, 90,
-  150, 95, 63, 87, 121, 80, 97, 69, 123, 134,
-  109, 125, 63, 87, 118, 73, 118, 88, 98, 111,
-  134, 102, 114, 121, 66, 111, 82, 106, 92, 76,
-  92, 118, 86, 109, 130, 65, 106, 94, 113, 109,
-  118, 153, 108, 99, 100, 114, 111, 108, 127, 95,
-  66, 105, 82, 134, 115, 73, 106, 82, 119, 97,
-  101, 72, 99, 116, 123, 102, 115, 85, 107, 121,
-  95, 78, 79, 108, 50, 68, 78, 118, 142, 103,
-  141, 79, 131, 74, 112, 83, 104, 153, 96, 120,
-  133, 107, 111, 127, 113, 120, 87, 117, 100, 123,
-  97, 115, 119, 118, 121, 94, 100, 91, 93, 104,
-  81, 75, 79, 90, 92, 125, 120, 87, 114, 104,
-  115, 77, 85, 158, 99, 85, 109, 123, 89, 93,
-  136, 99, 123, 89, 104, 105, 69, 124, 72, 91,
-  126, 100, 90, 87, 87, 97, 121, 97, 131, 120,
-  145, 109, 98, 107, 154, 149, 116, 95, 80, 85,
-  107, 99, 130, 115, 114, 82, 151, 111, 110, 119,
-  89, 106, 54, 116, 116, 91, 110, 98, 85, 84,
-  107, 85, 96, 102, 113, 112, 100, 68, 99, 162,
-  158, 91, 152, 95, 75, 95, 124, 95, 89, 71,
-  123, 134, 98, 126, 56, 83, 124, 87, 128, 86,
-  103, 111, 129, 92, 115, 126, 75, 107, 80, 107,
-  108, 85, 94, 120, 91, 121, 134, 70, 105, 101,
-  112, 106, 121, 162, 101, 99, 105, 100, 118, 107,
-  128, 97, 73, 111, 73, 141, 120, 75, 110, 90,
-  130, 110, 113, 86, 107, 106, 123, 94, 121, 102,
-  114, 124, 108, 85, 86, 99, 61, 83, 91, 109,
-  142, 104, 135, 82, 124, 70, 115, 95, 107, 145,
-  105, 126, 135, 106, 124, 124, 114, 119, 87, 123,
-  99, 122, 110, 114, 121, 113, 119, 90, 99, 88,
-  96, 103, 75, 91, 91, 88, 91, 126, 116, 92,
-  121, 107, 122, 83, 98, 147, 99, 90, 108, 121,
-  90, 96, 141, 104, 133, 87, 105, 102, 65, 124,
-  71, 102, 122, 93, 99, 85, 95, 99, 119, 97,
-  126, 132, 132, 106, 94, 108, 151, 151, 117, 88,
-  82, 77, 90, 102, 121, 119, 115, 87, 154, 113,
-  112, 135, 94, 104, 67, 113, 114, 100, 114, 100,
-  80, 97, 108, 94, 104, 104, 107, 108, 106, 67,
-  105, 145, 158, 100, 136, 98, 90, 87, 124, 113,
-  99, 68, 130, 119, 97, 131, 55, 81, 128, 103,
-  135, 90, 107, 115, 127, 89, 114, 126, 87, 105,
-  80, 96, 108, 96, 91, 98, 104, 130, 134, 70,
-  102, 103, 106, 97, 114, 164, 97, 97, 97, 93,
-  126, 107, 110, 97, 85, 113, 76, 148, 116, 69,
-  103, 98, 136, 98, 105, 101, 110, 100, 123, 92,
-  124, 117, 112, 123, 124, 82, 93, 95, 69, 95,
-  112, 102, 134, 110, 135, 81, 118, 73, 126, 87,
-  111, 133, 113, 122, 138, 107, 123, 122, 117, 119,
-  97, 126, 93, 104, 115, 110, 118, 110, 121, 88,
-  102, 85, 93, 110, 74, 84, 94, 98, 92, 119,
-  120, 86, 124, 103, 126, 87, 111, 142, 100, 85,
-  112, 111, 91, 104, 143, 104, 133, 89, 105, 92,
-  70, 127, 71, 107, 115, 102, 98, 93, 99, 95,
-  113, 104, 127, 138, 127, 106, 90, 110, 156, 152,
-  119, 84, 90, 71, 91, 100, 122, 123, 118, 92,
-  151, 114, 109, 128, 99, 102, 67, 119, 101, 100,
-  115, 104, 87, 103, 106, 106, 98, 108, 105, 106,
-  105, 74, 108, 139, 154, 101, 145, 94, 81, 86,
-  123, 95, 98, 68, 133, 111, 101, 130, 57, 81,
-  122, 101, 137, 94, 109, 113, 129, 84, 106, 120,
-  93, 110, 88, 88, 107, 93, 85, 94, 106, 128,
-  126, 68, 99, 100, 111, 100, 108, 155, 99, 92,
-  95, 94, 121, 109, 129, 96, 91, 114, 78, 157,
-  121, 70, 99, 95, 130, 102, 103, 109, 102, 112,
-  122, 85, 118, 120, 109, 118, 120, 89, 91, 93,
-  71, 96, 120, 101, 131, 115, 136, 84, 116, 75,
-  128, 100, 115, 132, 106, 116, 137, 109, 118, 127,
-  120, 130, 105, 109, 97, 107, 123, 111, 115, 117,
-  133, 98, 97, 84, 91, 118, 76, 68, 86, 103,
-  94, 118, 125, 78, 124, 102, 130, 79, 115, 145,
-  97, 77, 117, 108, 95, 100, 142, 96, 129, 92,
-  108, 114, 71, 128, 72, 107, 113, 101, 94, 90,
-  98, 94, 109, 102, 126, 131, 134, 108, 86, 106,
-  167, 157, 124, 89, 92, 72, 102, 91, 135, 125,
-  116, 88, 148, 105, 99, 109, 98, 108, 56, 111,
-  99, 103, 120, 104, 99, 106, 107, 98, 80, 112,
-  106, 112, 107, 82, 102, 157, 149, 105, 167, 91,
-  75, 93, 124, 90, 95, 62, 126, 127, 103, 123,
-  62, 86, 113, 87, 139, 96, 109, 115, 127, 85,
-  102, 112, 94, 106, 101, 88, 105, 89, 84, 102,
-  93, 123, 115, 64, 102, 100, 116, 100, 116, 143,
-  101, 94, 106, 96, 111, 107, 138, 95, 90, 116,
-  73, 160, 129, 81, 99, 90, 115, 113, 109, 102,
-  96, 123, 126, 83, 113, 108, 106, 122, 106, 77,
-  80, 97, 68, 81, 105, 102, 129, 121, 139, 80,
-  113, 66, 118, 115, 116, 134, 104, 115, 142, 111,
-  110, 120, 118, 148, 88, 94, 104, 119, 129, 109,
-  124, 130, 130, 110, 89, 85, 93, 116, 86, 73,
-  87, 95, 96, 128, 128, 74, 120, 103, 132, 76,
-  109, 152, 87, 77, 116, 122, 97, 97, 139, 94,
-  123, 87, 114, 120, 64, 123, 65, 100, 117, 95,
-  84, 86, 99, 101, 113, 101, 124, 124, 134, 97,
-  85, 101, 180, 169, 122, 101, 86, 77, 107, 93,
-  127, 128, 113, 77, 152, 99, 92, 97, 87, 118,
-  58, 104, 108, 98, 130, 114, 99, 98, 103, 88,
-  72, 111, 102, 114, 109, 78, 106, 167, 143, 112,
-  170, 89, 79, 75, 125, 103, 99, 61, 125, 141,
-  102, 124, 69, 96, 105, 86, 129, 96, 108, 128,
-  127, 97, 97, 109, 83, 110, 114, 90, 99, 92,
-  81, 105, 88, 120, 103, 67, 104, 104, 111, 94,
-  117, 145, 100, 103, 122, 96, 104, 102, 118, 92,
-  86, 113, 68, 147, 118, 78, 112, 94, 100, 99,
-  103, 84, 93, 121, 128, 92, 117, 92, 100, 118,
-  92, 68, 83, 103, 64, 63, 96, 106, 118, 134,
-  142, 73, 116, 63, 102, 95, 115, 135, 100, 112,
-  158, 115, 94, 110, 107, 154, 75, 91, 118, 123,
-  115, 107, 132, 126, 124, 117, 90, 91, 87, 112,
-  107, 88, 87, 87, 89, 118, 132, 81, 125, 106,
-  132, 78, 89, 147, 93, 94, 100, 138, 91, 94,
-  132, 94, 121, 69, 117, 115, 66, 120, 58, 98,
-  132, 102, 69, 88, 99, 108, 110, 107, 122, 115,
-  129, 95, 99, 101, 172, 168, 119, 114, 78, 86,
-  120, 98, 120, 139, 111, 70, 157, 114, 90, 99,
-  86, 124, 73, 105, 128, 108, 149, 130, 87, 71,
-  99, 86, 82, 114, 109, 110, 104, 80, 114, 164,
-  147, 116, 185, 83, 87, 72, 127, 117, 87, 72,
-  123, 146, 92, 123, 78, 105, 104, 98, 112, 98,
-  108, 133, 116, 123, 89, 132, 67, 125, 111, 121,
-  99, 94, 79, 120, 92, 110, 103, 84, 104, 122,
-  118, 110, 127, 144, 99, 111, 127, 94, 101, 107,
-  113, 92, 85, 103, 64, 119, 99, 79, 123, 108,
-  116, 99, 113, 79, 109, 111, 129, 97, 120, 92,
-  104, 121, 82, 70, 91, 106, 58, 68, 94, 112,
-  113, 141, 140, 80, 130, 69, 92, 78, 98, 133,
-  86, 121, 164, 110, 117, 105, 86, 140, 72, 96,
-  121, 124, 100, 110, 136, 102, 120, 111, 102, 111,
-  94, 106, 117, 116, 85, 111, 78, 107, 131, 97,
-  124, 99, 134, 103, 87, 124, 115, 133, 81, 137,
-  107, 88, 129, 92, 126, 69, 112, 117, 92, 128,
-  56, 113, 141, 113, 73, 90, 111, 117, 120, 122,
-  111, 112, 103, 105, 121, 113, 139, 131, 110, 119,
-  84, 96, 119, 107, 129, 145, 110, 80, 153, 130,
-  108, 120, 103, 120, 105, 93, 138, 119, 189, 134,
-  75, 68, 113, 116, 106, 121, 120, 110, 112, 88,
-  123, 144, 149, 125, 178, 83, 117, 84, 120, 156,
-  82, 95, 111, 140, 94, 130, 86, 110, 99, 119,
-  96, 106, 118, 126, 111, 134, 79, 173, 78, 128,
-  96, 144, 120, 98, 94, 129, 113, 111, 107, 107,
-  86, 150, 127, 124, 128, 127, 103, 103, 120, 100,
-  102, 119, 107, 111, 92, 100, 82, 95, 82, 96,
-  107, 119, 149, 131, 115, 87, 138, 100, 133, 108,
-  106, 116, 129, 133, 92, 94, 94, 109, 59, 91,
-  95, 120, 98, 129, 144, 93, 133, 89, 86, 78,
-  89, 124, 75, 136, 160, 117, 148, 102, 64, 120,
-  73, 141, 124, 109, 98, 117, 129, 79, 114, 110,
-  117, 122, 106, 102, 107, 143, 94, 138, 76, 99,
-  128, 106, 126, 105, 122, 146, 140, 107, 114, 159,
-  78, 125, 131, 99, 128, 90, 130, 73, 96, 111,
-  116, 142, 49, 135, 130, 128, 102, 113, 131, 129,
-  116, 139, 93, 135, 98, 113, 122, 127, 109, 94,
-  108, 114, 102, 110, 89, 110, 134, 130, 106, 111,
-  155, 132, 98, 133, 133, 118, 113, 84, 119, 114,
-  208, 130, 70, 99, 143, 141, 121, 112, 115, 110,
-  115, 105, 113, 114, 142, 131, 159, 92, 144, 78,
-  119, 153, 88, 104, 115, 112, 109, 138, 90, 111,
-  92, 128, 86, 112, 128, 136, 116, 126, 79, 169,
-  106, 122, 89, 132, 119, 91, 118, 124, 130, 129,
-  98, 119, 78, 180, 121, 117, 110, 112, 106, 90,
-  119, 115, 102, 118, 99, 124, 98, 110, 90, 77,
-  82, 96, 91, 125, 125, 165, 121, 101, 134, 109,
-  132, 123, 101, 117, 141, 114, 103, 108, 110, 113,
-  71, 114, 125, 113, 90, 116, 157, 107, 114, 109,
-  90, 95, 83, 104, 81, 128, 163, 137, 107, 104,
-  60, 118, 92, 138, 122, 92, 106, 132, 114, 98,
-  119, 104, 114, 102, 108, 106, 101, 118, 94, 157,
-  87, 100, 127, 109, 139, 104, 114, 158, 157, 122,
-  118, 145, 91, 113, 131, 126, 140, 89, 124, 77,
-  94, 117, 122, 148, 36, 137, 138, 140, 113, 129,
-  124, 129, 118, 121, 84, 109, 117, 116, 111, 128,
-  135, 105, 124, 105, 111, 120, 112, 122, 134, 117,
-  101, 109, 152, 118, 77, 110, 135, 114, 107, 90,
-  99, 115, 189, 136, 81, 119, 154, 131, 135, 110,
-  121, 121, 112, 119, 103, 117, 153, 111, 179, 100,
-  149, 73, 142, 112, 74, 87, 104, 106, 91, 130,
-  86, 114, 82, 113, 96, 113, 135, 162, 119, 113,
-  85, 144, 105, 118, 101, 109, 120, 76, 116, 123,
-  120, 123, 91, 110, 83, 188, 116, 137, 117, 122,
-  112, 101, 147, 133, 111, 118, 109, 138, 97, 119,
-  70, 81, 114, 89, 89, 120, 73, 176, 134, 99,
-  115, 148, 121, 129, 106, 94, 126, 111, 91, 118,
-  132, 123, 73, 97, 113, 101, 94, 117, 154, 117,
-  115, 105, 89, 106, 92, 103, 86, 102, 176, 145,
-  119, 100, 77, 131, 83, 97, 125, 108, 112, 126,
-  123, 128, 135, 100, 107, 74, 88, 113, 101, 87,
-  92, 112, 93, 88, 132, 98, 135, 110, 123, 123,
-  117, 138, 104, 103, 104, 120, 101, 123, 156, 80,
-  118, 73, 101, 116, 95, 127, 32, 129, 142, 120,
-  92, 105, 104, 112, 124, 87, 99, 102, 123, 113,
-  112, 122, 155, 152, 121, 98, 94, 96, 131, 106,
-  128, 120, 96, 102, 150, 101, 83, 92, 109, 128,
-  93, 88, 109, 113, 162, 138, 91, 117, 139, 98,
-  106, 106, 119, 129, 102, 103, 110, 152, 159, 104,
-  206, 101, 144, 96, 152, 98, 69, 67, 111, 127,
-  93, 121, 79, 106, 103, 105, 102, 115, 127, 160,
-  105, 114, 95, 132, 84, 116, 120, 89, 110, 74,
-  95, 109, 102, 104, 98, 98, 94, 176, 117, 138,
-  132, 134, 107, 116, 150, 123, 122, 108, 110, 122,
-  89, 118, 69, 100, 122, 86, 89, 113, 85, 133,
-  136, 83, 108, 156, 125, 113, 108, 85, 97, 129,
-  95, 71, 108, 113, 60, 88, 96, 100, 104, 138,
-  133, 93, 142, 95, 105, 105, 97, 109, 81, 110,
-  186, 132, 126, 94, 85, 137, 73, 86, 117, 123,
-  96, 120, 139, 138, 134, 101, 100, 84, 87, 102,
-  110, 76, 80, 94, 85, 92, 144, 92, 114, 107,
-  130, 105, 108, 154, 100, 101, 105, 127, 106, 93,
-  153, 85, 107, 82, 91, 119, 92, 106, 35, 129,
-  144, 104, 88, 90, 98, 109, 126, 87, 129, 91,
-  106, 109, 142, 119, 151, 175, 126, 104, 92, 90,
-  122, 85, 123, 131, 100, 79, 159, 108, 124, 97,
-  95, 130, 95, 78, 140, 122, 172, 138, 94, 82,
-  114, 110, 102, 111, 106, 110, 96, 80, 129, 171,
-  155, 115, 192, 95, 126, 101, 139, 118, 68, 73,
-  118, 160, 96, 113, 82, 109, 117, 112, 101, 113,
-  127, 130, 104, 147, 86, 151, 78, 122, 126, 114,
-  128, 80, 82, 107, 101, 113, 107, 106, 92, 149,
-  137, 129, 135, 131, 102, 103, 134, 108, 106, 102,
-  92, 97, 86, 113, 73, 104, 105, 87, 101, 101,
-  105, 94, 124, 77, 113, 115, 140, 98, 103, 112,
-  100, 121, 95, 53, 77, 109, 56, 94, 83, 117,
-  97, 145, 129, 76, 143, 92, 106, 87, 102, 122,
-  82, 139, 156, 126, 85, 91, 56, 117, 72, 105,
-  102, 123, 79, 127, 115, 127, 116, 81, 103, 100,
-  61, 81, 113, 139, 68, 121, 63, 93, 154, 101,
-  93, 89, 116, 122, 116, 124, 89, 118, 89, 129,
-  126, 92, 128, 99, 105, 104, 78, 84, 88, 93,
-  29, 114, 145, 117, 73, 90, 107, 90, 109, 143,
-  122, 99, 97, 116, 162, 149, 113, 145, 120, 99,
-  92, 109, 109, 83, 122, 117, 99, 102, 160, 145,
-  128, 95, 94, 118, 115, 61, 120, 133, 216, 131,
-  80, 82, 136, 132, 131, 112, 123, 87, 92, 94,
-  116, 138, 129, 96, 142, 84, 119, 91, 118, 139,
-  68, 100, 110, 131, 82, 118, 86, 126, 116, 114,
-  85, 111, 132, 107, 115, 174, 61, 184, 86, 133,
-  92, 180, 106, 78, 92, 129, 114, 86, 101, 107,
-  83, 124, 142, 95, 134, 126, 107, 83, 118, 121,
-  90, 107, 78, 106, 79, 84, 70, 78, 78, 98,
-  96, 118, 136, 106, 123, 70, 126, 93, 138, 116,
-  81, 103, 119, 109, 77, 90, 73, 111, 35, 102,
-  107, 130, 98, 122, 120, 97, 130, 86, 119, 78,
-  80, 107, 69, 162, 122, 131, 171, 101, 58, 121,
-  84, 123, 104, 119, 90, 147, 118, 156, 123, 93,
-  111, 110, 70, 65, 128, 142, 92, 104, 64, 124,
-  157, 93, 105, 91, 94, 154, 121, 108, 72, 140,
-  94, 153, 166, 97, 134, 114, 115, 109, 58, 93,
-  100, 124, 35, 136, 140, 143, 98, 110, 118, 103,
-  121, 151, 100, 113, 100, 120, 107, 148, 96, 99,
-  113, 102, 93, 152, 88, 111, 120, 107, 104, 88,
-  159, 128, 119, 85, 125, 114, 149, 66, 121, 134,
-  254, 131, 79, 100, 134, 140, 122, 111, 154, 99,
-  95, 98, 100, 97, 112, 138, 125, 95, 129, 104,
-  115, 146, 98, 117, 98, 99, 115, 117, 124, 134,
-  110, 115, 84, 116, 129, 136, 122, 131, 46, 179,
-  136, 120, 116, 116, 169, 82, 112, 114, 124, 114,
-  109, 109, 72, 131, 154, 106, 136, 152, 124, 66,
-  127, 141, 116, 119, 73, 116, 80, 87, 147, 78,
-  82, 123, 100, 126, 149, 128, 121, 108, 121, 129,
-  151, 221, 69, 95, 125, 135, 63, 104, 125, 125,
-  51, 113, 118, 123, 108, 117, 140, 111, 126, 98,
-  117, 103, 71, 97, 62, 139, 130, 114, 125, 106,
-  66, 125, 92, 153, 121, 110, 74, 142, 109, 158,
-  113, 85, 116, 96, 95, 70, 116, 130, 55, 181,
-  75, 129, 146, 94, 127, 87, 103, 156, 142, 106,
-  65, 145, 90, 145, 190, 118, 138, 118, 116, 97,
-  66, 107, 83, 139, 20, 127, 118, 125, 94, 110,
-  118, 95, 117, 102, 109, 127, 108, 109, 95, 118,
-  114, 105, 107, 80, 101, 147, 76, 127, 116, 112,
-  105, 94, 176, 89, 92, 93, 127, 109, 138, 73,
-  99, 104, 255, 135, 85, 106, 104, 139, 134, 103,
-  167, 127, 104, 85, 107, 93, 123, 122, 121, 94,
-  133, 84, 122, 142, 113, 97, 108, 91, 111, 123,
-  126, 127, 117, 110, 97, 110, 122, 126, 125, 122,
-  58, 151, 101, 108, 120, 106, 146, 88, 90, 93,
-  116, 160, 105, 106, 85, 121, 118, 106, 143, 151,
-  113, 80, 129, 129, 99, 108, 76, 73, 98, 92,
-  116, 72, 80, 121, 89, 136, 97, 112, 121, 111,
-  95, 133, 147, 212, 68, 88, 123, 140, 80, 78,
-  112, 130, 51, 107, 132, 112, 93, 123, 124, 104,
-  107, 89, 122, 76, 76, 93, 92, 89, 170, 113,
-  106, 101, 76, 144, 118, 139, 135, 107, 80, 134,
-  94, 161, 126, 69, 139, 70, 77, 94, 94, 139,
-  82, 135, 80, 126, 141, 99, 143, 109, 147, 128,
-  145, 132, 79, 132, 89, 126, 146, 128, 150, 113,
-  116, 107, 69, 100, 73, 119, 22, 128, 102, 108,
-  108, 114, 106, 94, 110, 78, 152, 108, 103, 92,
-  116, 112, 163, 183, 111, 90, 91, 95, 111, 104,
-  114, 126, 105, 118, 196, 94, 84, 103, 102, 124,
-  95, 77, 86, 111, 226, 160, 72, 140, 123, 134,
-  129, 94, 133, 136, 117, 79, 98, 120, 155, 106,
-  155, 95, 132, 86, 121, 104, 89, 65, 112, 96,
-  84, 131, 112, 111, 119, 97, 137, 114, 126, 121,
-  134, 133, 66, 140, 84, 114, 133, 115, 130, 86,
-  78, 90, 106, 103, 89, 105, 91, 119, 100, 94,
-  124, 152, 105, 104, 141, 126, 93, 96, 103, 90,
-  112, 102, 73, 98, 127, 88, 86, 127, 69, 79,
-  117, 119, 91, 121, 132, 107, 96, 96, 120, 104,
-  110, 75, 89, 117, 37, 94, 129, 123, 87, 133,
-  100, 93, 112, 88, 111, 51, 92, 94, 127, 97,
-  173, 118, 116, 97, 84, 152, 150, 88, 133, 132,
-  92, 125, 97, 160, 124, 73, 134, 64, 77, 100,
-  89, 75, 92, 103, 72, 138, 144, 87, 150, 120,
-  124, 95, 103, 143, 76, 101, 94, 148, 107, 108,
-  145, 102, 123, 100, 81, 110, 80, 103, 31, 142,
-  95, 97, 121, 115, 82, 89, 103, 115, 162, 119,
-  115, 91, 116, 114, 156, 185, 113, 106, 94, 82,
-  120, 91, 119, 121, 112, 102, 187, 91, 110, 107,
-  105, 127, 86, 88, 87, 124, 198, 164, 66, 117,
-  107, 143, 103, 89, 101, 102, 105, 86, 97, 133,
-  138, 119, 160, 95, 120, 101, 124, 112, 113, 82,
-  111, 103, 118, 143, 109, 122, 121, 72, 166, 112,
-  133, 132, 175, 126, 69, 115, 95, 122, 152, 116,
-  128, 64, 76, 106, 95, 103, 107, 102, 93, 110,
-  116, 92, 123, 171, 122, 109, 139, 143, 79, 103,
-  119, 111, 103, 110, 86, 110, 154, 81, 106, 111,
-  107, 78, 119, 111, 90, 117, 123, 114, 100, 81,
-  94, 102, 107, 71, 102, 112, 34, 77, 120, 166,
-  101, 124, 102, 98, 122, 120, 98, 66, 98, 113,
-  118, 139, 139, 116, 101, 102, 59, 116, 135, 75,
-  117, 149, 83, 123, 112, 129, 115, 79, 134, 97,
-  76, 88, 97, 71, 83, 91, 53, 120, 166, 87,
-  104, 103, 102, 82, 74, 122, 76, 105, 98, 163,
-  130, 117, 136, 91, 117, 85, 85, 119, 105, 101,
-  43, 133, 94, 112, 128, 115, 73, 80, 127, 136,
-  131, 109, 103, 93, 110, 127, 113, 123, 108, 101,
-  81, 98, 113, 90, 117, 98, 106, 103, 167, 111,
-  134, 120, 110, 121, 101, 100, 123, 97, 212, 132,
-  73, 103, 100, 135, 102, 84, 122, 81, 97, 109,
-  107, 111, 110, 110, 131, 103, 108, 105, 112, 115,
-  116, 111, 129, 100, 119, 144, 107, 151, 115, 84,
-  117, 117, 134, 124, 193, 140, 64, 108, 114, 134,
-  121, 141, 126, 52, 106, 149, 92, 109, 115, 112,
-  70, 112, 104, 123, 138, 173, 137, 107, 113, 149,
-  81, 109, 107, 119, 72, 95, 107, 86, 114, 104,
-  120, 137, 132, 111, 116, 88, 114, 101, 114, 135,
-  68, 67, 109, 158, 108, 87, 84, 126, 42, 78,
-  125, 192, 111, 103, 120, 97, 107, 136, 79, 83,
-  93, 106, 119, 150, 115, 107, 102, 111, 81, 98,
-  106, 98, 103, 110, 90, 122, 123, 111, 109, 77,
-  126, 118, 90, 89, 115, 123, 98, 137, 75, 122,
-  200, 95, 99, 107, 105, 113, 79, 115, 93, 131,
-  104, 143, 147, 124, 149, 103, 118, 88, 95, 111,
-  115, 104, 63, 118, 112, 128, 114, 121, 96, 89,
-  137, 115, 131, 104, 101, 107, 102, 132, 114, 108,
-  122, 112, 89, 111, 96, 104, 109, 92, 112, 116,
-  187, 133, 120, 128, 132, 97, 125, 107, 117, 112,
-  209, 118, 97, 118, 108, 117, 142, 107, 129, 118,
-  124, 122, 114, 110, 110, 109, 126, 109, 112, 102,
-  106, 117, 106, 156, 137, 103, 111, 128, 107, 158,
-  119, 109, 97, 123, 109, 117, 172, 151, 80, 118,
-  121, 126, 105, 144, 121, 84, 112, 153, 104, 110,
-  119, 122, 83, 113, 87, 144, 126, 144, 145, 102,
-  95, 134, 92, 122, 108, 136, 85, 99, 113, 102,
-  93, 120, 123, 159, 135, 115, 114, 94, 129, 114,
-  118, 139, 76, 100, 132, 176, 111, 120, 90, 124,
-  67, 95, 125, 191, 110, 98, 138, 97, 107, 124,
-  90, 88, 92, 108, 107, 137, 179, 106, 81, 132,
-  89, 106, 155, 112, 133, 138, 123, 120, 142, 132,
-  145, 144, 109, 114, 124, 111, 78, 122, 140, 100,
-  112, 122, 173, 141, 129, 115, 92, 95, 143, 117,
-  84, 104, 101, 69, 112, 97, 128, 109, 119, 98,
-  94, 92, 106, 103, 119, 104, 111, 100, 116, 142,
-  114, 108, 140, 130, 120, 118, 153, 120, 138, 137,
-  145, 128, 128, 97, 133, 122, 114, 94, 131, 105,
-  108, 116, 132, 129, 142, 130, 104, 98, 68, 118,
-  114, 110, 114, 123, 92, 116, 133, 107, 119, 96,
-  105, 123, 120, 115, 137, 156, 163, 104, 126, 135,
-  92, 104, 159, 112, 134, 118, 133, 116, 92, 141,
-  97, 85, 104, 109, 92, 102, 156, 127, 127, 97,
-  111, 123, 86, 99, 113, 120, 107, 83, 123, 170,
-  103, 76, 120, 93, 72, 146, 86, 78, 95, 136,
-  102, 118, 143, 132, 106, 120, 121, 140, 117, 138,
-  72, 110, 128, 113, 103, 111, 89, 110, 149, 97,
-  118, 114, 117, 140, 92, 78, 130, 78, 107, 125,
-  86, 120, 143, 81, 105, 142, 132, 119, 160, 113,
-  107, 104, 147, 109, 75, 112, 121, 83, 188, 102,
-  160, 126, 89, 102, 160, 109, 139, 151, 114, 139,
-  143, 159, 121, 144, 99, 114, 113, 91, 93, 104,
-  169, 82, 105, 139, 125, 152, 130, 124, 93, 116,
-  110, 105, 77, 95, 85, 85, 128, 74, 126, 87,
-  116, 124, 81, 66, 121, 137, 98, 135, 111, 90,
-  108, 134, 101, 133, 173, 129, 105, 148, 139, 151,
-  90, 148, 141, 118, 118, 108, 122, 102, 105, 85,
-  144, 97, 117, 87, 65, 151, 113, 116, 80, 108,
-  83, 133, 118, 144, 117, 152, 103, 114, 128, 100,
-  108, 66, 109, 133, 129, 122, 138, 155, 193, 108,
-  140, 137, 110, 127, 157, 143, 109, 166, 144, 125,
-  100, 161, 81, 96, 103, 160, 94, 104, 152, 160,
-  117, 84, 102, 113, 77, 125, 117, 111, 152, 54,
-  135, 138, 111, 113, 124, 112, 56, 175, 106, 71,
-  112, 156, 114, 105, 126, 153, 118, 118, 122, 169,
-  113, 171, 120, 113, 124, 106, 114, 106, 145, 114,
-  131, 92, 152, 134, 92, 154, 74, 52, 128, 116,
-  90, 147, 107, 96, 141, 97, 118, 139, 131, 107,
-  177, 88, 102, 114, 168, 115, 78, 118, 123, 103,
-  175, 97, 122, 148, 77, 97, 140, 119, 115, 133,
-  90, 135, 150, 154, 118, 149, 103, 114, 121, 81,
-  115, 70, 146, 114, 76, 138, 76, 128, 125, 109,
-  121, 96, 95, 84, 109, 106, 66, 119, 148, 88,
-  92, 113, 109, 140, 62, 115, 127, 157, 124, 169,
-  118, 95, 118, 104, 93, 172, 138, 111, 94, 133,
-  120, 157, 89, 120, 130, 93, 122, 102, 137, 105,
-  94, 116, 117, 87, 121, 96, 69, 148, 56, 127,
-  100, 93, 117, 96, 147, 151, 79, 163, 102, 97,
-  86, 129, 92, 83, 122, 135, 135, 130, 136, 109,
-  172, 116, 133, 134, 137, 128, 128, 190, 90, 169,
-  110, 142, 90, 142, 90, 99, 95, 184, 87, 106,
-  129, 176, 109, 88, 63, 108, 84, 129, 116, 91,
-  160, 60, 129, 98, 118, 197, 113, 135, 65, 178,
-  117, 68, 128, 162, 138, 95, 115, 157, 108, 113,
-  77, 108, 103, 151, 100, 98, 109, 105, 93, 114,
-  132, 122, 106, 103, 126, 120, 129, 122, 72, 80,
-  118, 138, 82, 137, 130, 90, 128, 95, 114, 117,
-  100, 108, 146, 103, 105, 104, 141, 98, 83, 130,
-  114, 108, 168, 82, 110, 147, 86, 114, 109, 151,
-  100, 104, 86, 119, 123, 103, 103, 107, 106, 104,
-  129, 101, 111, 116, 133, 128, 51, 107, 65, 109,
-  135, 90, 148, 128, 120, 59, 116, 112, 65, 100,
-  143, 106, 81, 122, 116, 80, 81, 94, 100, 152,
-  105, 150, 116, 118, 93, 120, 96, 147, 122, 95,
-  87, 159, 118, 130, 96, 127, 103, 77, 101, 109,
-  113, 82, 71, 105, 96, 88, 112, 160, 77, 120,
-  63, 132, 94, 87, 125, 80, 104, 99, 77, 142,
-  78, 95, 122, 104, 92, 92, 137, 119, 153, 120,
-  111, 86, 131, 128, 107, 116, 142, 106, 97, 146,
-  97, 145, 118, 105, 102, 135, 90, 92, 98, 171,
-  78, 111, 111, 154, 114, 107, 58, 102, 78, 101,
-  82, 116, 104, 91, 117, 98, 126, 154, 124, 123,
-  88, 177, 91, 63, 123, 146, 128, 86, 100, 120,
-  91, 102, 57, 114, 102, 121, 61, 70, 82, 79,
-  49, 131, 109, 114, 104, 95, 134, 105, 153, 108,
-  84, 86, 119, 163, 100, 148, 98, 104, 104, 101,
-  151, 106, 89, 127, 102, 107, 102, 80, 118, 92,
-  87, 125, 103, 91, 198, 97, 135, 117, 135, 157,
-  109, 167, 101, 93, 93, 129, 129, 100, 100, 109,
-  99, 100, 129, 114, 109, 96, 131, 82, 61, 121,
-  79, 130, 154, 101, 157, 144, 121, 88, 134, 109,
-  93, 72, 116, 93, 104, 126, 139, 48, 118, 94,
-  94, 155, 101, 131, 122, 143, 64, 130, 102, 116,
-  125, 112, 111, 145, 111, 137, 113, 113, 140, 113,
-  107, 140, 100, 89, 87, 88, 111, 93, 129, 113,
-  97, 119, 91, 113, 94, 91, 109, 101, 84, 74,
-  80, 147, 74, 97, 116, 93, 96, 105, 95, 134,
-  143, 119, 134, 114, 147, 132, 114, 126, 133, 103,
-  111, 82, 90, 129, 118, 97, 110, 129, 105, 81,
-  93, 168, 101, 114, 116, 141, 112, 105, 78, 106,
-  89, 90, 114, 99, 116, 110, 94, 78, 142, 122,
-  132, 125, 98, 173, 95, 103, 120, 139, 104, 98,
-  116, 101, 116, 97, 102, 116, 120, 154, 65, 110,
-  110, 71, 72, 107, 77, 74, 106, 92, 99, 120,
-  137, 100, 95, 114, 118, 122, 100, 120, 106, 107,
-  97, 105, 126, 97, 92, 160, 93, 103, 96, 69,
-  124, 87, 112, 132, 98, 77, 206, 93, 88, 112,
-  129, 159, 114, 158, 131, 104, 88, 122, 128, 95,
-  116, 118, 95, 112, 125, 125, 91, 71, 114, 99,
-  72, 102, 75, 138, 148, 97, 138, 118, 136, 98,
-  119, 93, 93, 72, 97, 110, 94, 122, 138, 50,
-  151, 92, 96, 171, 108, 119, 110, 126, 44, 113,
-  109, 113, 112, 130, 102, 128, 116, 122, 120, 118,
-  155, 122, 125, 117, 101, 82, 111, 88, 117, 81,
-  130, 101, 99, 114, 93, 102, 84, 104, 52, 109,
-  91, 96, 75, 161, 83, 78, 97, 115, 91, 99,
-  74, 122, 111, 105, 133, 123, 177, 113, 137, 131,
-  139, 93, 130, 93, 97, 102, 119, 110, 103, 123,
-  88, 81, 81, 151, 87, 101, 123, 137, 114, 92,
-  97, 109, 75, 98, 91, 85, 104, 97, 107, 88,
-  118, 120, 130, 109, 119, 161, 104, 102, 124, 141,
-  111, 106, 124, 97, 130, 99, 122, 106, 117, 156,
-  46, 100, 105, 71, 65, 85, 69, 102, 111, 73,
-  102, 116, 130, 84, 102, 104, 108, 86, 84, 102,
-  95, 121, 111, 103, 107, 86, 101, 149, 100, 103,
-  109, 68, 120, 83, 111, 131, 89, 88, 179, 97,
-  98, 124, 114, 140, 122, 132, 138, 105, 87, 120,
-  137, 112, 109, 127, 94, 125, 128, 133, 82, 64,
-  107, 107, 86, 113, 88, 132, 137, 104, 119, 97,
-  133, 108, 119, 72, 87, 74, 87, 99, 106, 115,
-  126, 47, 159, 94, 95, 175, 126, 101, 95, 113,
-  50, 96, 104, 123, 110, 104, 99, 130, 122, 122,
-  110, 122, 155, 119, 132, 123, 105, 81, 116, 89,
-  118, 82, 132, 110, 96, 114, 114, 92, 84, 103,
-  46, 98, 106, 110, 81, 167, 98, 79, 122, 111,
-  97, 87, 73, 98, 106, 96, 123, 127, 186, 101,
-  146, 149, 125, 104, 140, 96, 103, 104, 110, 122,
-  121, 119, 86, 79, 76, 139, 95, 90, 103, 140,
-  116, 80, 110, 123, 69, 91, 79, 77, 99, 82,
-  108, 79, 99, 106, 148, 103, 124, 139, 126, 100,
-  121, 152, 119, 105, 113, 116, 129, 107, 128, 144,
-  103, 148, 66, 110, 111, 78, 71, 83, 88, 113,
-  103, 72, 117, 105, 119, 91, 112, 86, 108, 93,
-  79, 88, 110, 125, 120, 97, 95, 92, 113, 121,
-  124, 96, 107, 74, 114, 92, 109, 140, 95, 87,
-  156, 87, 89, 124, 129, 128, 133, 124, 131, 107,
-  90, 117, 129, 128, 107, 116, 89, 126, 111, 123,
-  72, 55, 99, 117, 88, 128, 96, 129, 119, 105,
-  114, 101, 110, 132, 113, 63, 84, 80, 90, 91,
-  113, 106, 112, 53, 140, 97, 84, 155, 142, 99,
-  80, 100, 65, 88, 85, 122, 101, 79, 124, 143,
-  131, 131, 119, 116, 156, 138, 124, 127, 102, 83,
-  106, 81, 120, 95, 140, 118, 94, 124, 139, 102,
-  82, 106, 37, 95, 106, 111, 79, 160, 113, 89,
-  118, 96, 113, 79, 76, 102, 103, 102, 109, 153,
-  184, 81, 141, 161, 99, 125, 135, 94, 116, 110,
-  112, 132, 109, 114, 78, 76, 94, 141, 116, 76,
-  94, 120, 122, 75, 112, 127, 68, 86, 87, 79,
-  89, 75, 102, 86, 88, 109, 150, 99, 109, 108,
-  127, 105, 117, 156, 111, 108, 89, 121, 115, 103,
-  137, 143, 96, 147, 67, 129, 119, 78, 79, 86,
-  101, 85, 98, 74, 113, 109, 100, 88, 118, 75,
-  100, 95, 78, 76, 105, 108, 128, 85, 103, 97,
-  121, 113, 137, 90, 102, 81, 121, 95, 104, 157,
-  101, 95, 140, 80, 108, 120, 132, 125, 138, 125,
-  118, 118, 105, 110, 122, 133, 109, 108, 94, 122,
-  108, 103, 59, 57, 104, 104, 89, 141, 109, 122,
-  93, 107, 109, 109, 95, 141, 102, 64, 93, 84,
-  103, 84, 118, 104, 112, 68, 120, 89, 75, 136,
-  155, 103, 63, 92, 81, 95, 76, 124, 102, 84,
-  147, 154, 123, 136, 101, 111, 152, 141, 108, 121,
-  102, 88, 90, 67, 120, 105, 143, 102, 88, 124,
-  145, 120, 81, 111, 38, 105, 108, 96, 78, 138,
-  111, 103, 112, 93, 112, 70, 76, 114, 99, 108,
-  107, 165, 167, 96, 126, 154, 76, 135, 124, 83,
-  135, 120, 119, 136, 111, 112, 77, 69, 116, 149,
-  139, 62, 94, 94, 137, 60, 116, 112, 87, 80,
-  95, 77, 87, 79, 115, 87, 90, 110, 146, 98,
-  89, 90, 116, 99, 106, 160, 101, 102, 72, 110,
-  106, 103, 135, 136, 92, 149, 83, 154, 123, 71,
-  86, 84, 114, 63, 104, 87, 118, 106, 87, 101,
-  116, 82, 103, 94, 86, 80, 89, 99, 134, 86,
-  101, 102, 131, 114, 140, 87, 91, 92, 123, 91,
-  106, 153, 117, 104, 131, 79, 106, 111, 123, 118,
-  131, 126, 111, 120, 111, 109, 115, 122, 109, 108,
-  110, 109, 101, 93, 53, 59, 110, 95, 88, 135,
-  107, 121, 84, 103, 101, 111, 82, 134, 91, 70,
-  96, 93, 106, 80, 116, 102, 124, 91, 117, 87,
-  72, 125, 151, 103, 60, 92, 74, 97, 70, 125,
-  106, 98, 153, 149, 112, 143, 88, 109, 140, 135,
-  110, 114, 102, 89, 86, 53, 123, 108, 135, 90,
-  92, 130, 139, 136, 77, 110, 39, 109, 109, 89,
-  68, 115, 100, 127, 103, 91, 103, 76, 78, 118,
-  107, 102, 100, 156, 158, 103, 125, 142, 68, 113,
-  120, 90, 130, 133, 119, 121, 99, 109, 72, 69,
-  132, 149, 150, 57, 107, 80, 139, 66, 117, 112,
-  92, 91, 86, 91, 95, 79, 123, 93, 101, 122,
-  137, 100, 75, 85, 115, 95, 104, 177, 94, 102,
-  57, 101, 108, 110, 135, 122, 85, 139, 88, 157,
-  125, 68, 90, 86, 115, 64, 112, 96, 109, 102,
-  80, 97, 108, 91, 113, 92, 102, 81, 82, 90,
-  117, 99, 101, 102, 148, 122, 133, 96, 84, 109,
-  127, 88, 107, 133, 138, 105, 129, 91, 118, 116,
-  115, 111, 121, 110, 106, 116, 120, 113, 107, 110,
-  124, 107, 130, 98, 103, 86, 52, 48, 115, 94,
-  77, 126, 101, 118, 88, 93, 95, 115, 74, 132,
-  80, 84, 95, 104, 99, 82, 115, 99, 139, 112,
-  123, 97, 80, 123, 146, 109, 64, 92, 74, 92,
-  73, 119, 110, 105, 146, 125, 109, 135, 85, 102,
-  132, 125, 120, 105, 94, 110, 98, 58, 137, 111,
-  125, 88, 93, 128, 139, 142, 76, 104, 28, 107,
-  116, 106, 55, 103, 88, 138, 104, 98, 111, 76,
-  84, 108, 121, 100, 97, 137, 166, 101, 127, 136,
-  83, 108, 132, 111, 135, 135, 116, 106, 88, 110,
-  61, 83, 133, 158, 152, 77, 116, 76, 143, 79,
-  113, 119, 96, 93, 84, 88, 121, 80, 119, 104,
-  113, 131, 125, 103, 73, 90, 125, 96, 106, 187,
-  90, 99, 54, 95, 119, 113, 125, 117, 84, 138,
-  79, 150, 123, 63, 82, 93, 121, 87, 117, 111,
-  113, 106, 94, 99, 96, 110, 121, 106, 117, 86,
-  87, 93, 109, 112, 103, 106, 145, 123, 122, 100,
-  93, 132, 121, 89, 110, 119, 148, 123, 123, 101,
-  126, 107, 107, 113, 95, 107, 94, 120, 130, 109,
-  112, 106, 115, 104, 148, 97, 106, 76, 58, 60,
-  113, 92, 65, 121, 93, 119, 85, 87, 87, 119,
-  86, 120, 72, 94, 91, 104, 101, 83, 116, 80,
-  142, 108, 132, 88, 74, 117, 133, 112, 66, 94,
-  70, 103, 80, 109, 106, 102, 133, 131, 105, 129,
-  87, 101, 117, 119, 119, 108, 89, 129, 91, 56,
-  128, 114, 124, 98, 96, 129, 151, 154, 87, 92,
-  42, 105, 113, 100, 47, 103, 84, 153, 108, 115,
-  129, 76, 82, 104, 122, 99, 102, 109, 153, 106,
-  104, 141, 103, 100, 131, 121, 136, 124, 123, 98,
-  84, 114, 60, 88, 132, 173, 147, 93, 122, 74,
-  154, 107, 100, 121, 97, 79, 87, 84, 111, 84,
-  106, 105, 138, 135, 120, 107, 80, 85, 119, 88,
-  102, 181, 84, 90, 44, 95, 124, 108, 102, 107,
-  89, 127, 76, 143, 111, 54, 75, 104, 126, 77,
-  109, 97, 108, 105, 104, 95, 84, 119, 124, 114,
-  128, 79, 88, 89, 110, 118, 122, 112, 134, 125,
-  113, 91, 98, 149, 131, 71, 113, 108, 141, 126,
-  128, 113, 136, 104, 99, 106, 82, 139, 80, 116,
-  139, 103, 112, 103, 119, 96, 148, 101, 99, 85,
-  55, 84, 107, 97, 58, 110, 99, 124, 92, 71,
-  82, 125, 110, 114, 69, 86, 89, 92, 115, 92,
-  112, 73, 138, 106, 134, 82, 69, 124, 112, 105,
-  67, 107, 68, 104, 80, 101, 108, 95, 127, 143,
-  102, 119, 76, 98, 108, 118, 117, 114, 100, 138,
-  95, 52, 133, 119, 131, 98, 90, 127, 148, 145,
-  91, 85, 43, 111, 87, 94, 47, 106, 94, 158,
-  115, 112, 156, 79, 82, 110, 115, 92, 110, 104,
-  145, 108, 108, 141, 95, 88, 126, 92, 139, 121,
-  127, 85, 96, 114, 59, 94, 124, 165, 150, 97,
-  129, 74, 158, 117, 90, 111, 97, 88, 90, 90,
-  114, 78, 105, 100, 147, 126, 120, 105, 86, 81,
-  116, 87, 104, 166, 82, 75, 37, 100, 114, 104,
-  123, 101, 93, 124, 84, 147, 105, 55, 74, 94,
-  120, 77, 92, 103, 110, 106, 108, 101, 72, 120,
-  133, 103, 121, 85, 78, 94, 114, 118, 135, 96,
-  126, 131, 108, 82, 95, 151, 135, 67, 120, 109,
-  118, 114, 140, 119, 128, 116, 101, 108, 106, 143,
-  82, 106, 149, 105, 111, 108, 137, 104, 138, 98,
-  87, 97, 48, 85, 111, 118, 61, 107, 110, 134,
-  113, 68, 87, 118, 124, 114, 69, 73, 91, 81,
-  110, 93, 106, 81, 139, 115, 131, 111, 70, 135,
-  103, 109, 76, 101, 67, 86, 83, 92, 107, 84,
-  125, 139, 101, 114, 65, 90, 112, 125, 116, 114,
-  109, 118, 89, 44, 141, 126, 132, 89, 85, 122,
-  128, 131, 90, 93, 33, 112, 80, 104, 59, 113,
-  107, 157, 119, 97, 155, 90, 88, 113, 125, 92,
-  101, 125, 150, 119, 131, 138, 81, 89, 124, 78,
-  135, 113, 129, 73, 101, 105, 67, 93, 120, 143,
-  162, 96, 141, 83, 157, 94, 88, 108, 100, 79,
-  103, 76, 124, 72, 88, 85, 142, 136, 107, 92,
-  84, 85, 111, 80, 108, 163, 86, 73, 50, 103,
-  96, 103, 144, 97, 93, 137, 83, 158, 114, 66,
-  72, 84, 96, 87, 92, 119, 102, 118, 133, 109,
-  70, 105, 138, 95, 107, 71, 68, 92, 109, 109,
-  142, 85, 124, 142, 103, 78, 91, 134, 126, 86,
-  124, 107, 97, 112, 157, 108, 117, 110, 109, 128,
-  124, 127, 94, 104, 145, 112, 100, 123, 130, 128,
-  119, 80, 88, 105, 59, 82, 119, 101, 75, 122,
-  113, 147, 133, 82, 106, 103, 121, 124, 78, 67,
-  98, 84, 97, 100, 111, 96, 132, 108, 129, 111,
-  66, 136, 107, 107, 80, 99, 61, 75, 75, 92,
-  114, 94, 129, 136, 93, 111, 68, 89, 152, 149,
-  115, 116, 103, 81, 64, 46, 120, 128, 135, 81,
-  96, 123, 120, 127, 78, 112, 31, 128, 87, 110,
-  78, 128, 103, 149, 108, 96, 111, 88, 84, 121,
-  134, 100, 102, 146, 154, 126, 149, 128, 75, 91,
-  116, 79, 111, 119, 130, 73, 93, 107, 72, 80,
-  114, 140, 175, 88, 141, 105, 150, 83, 84, 107,
-  105, 72, 124, 66, 118, 75, 80, 71, 124, 134,
-  84, 93, 84, 98, 107, 69, 108, 171, 90, 82,
-  82, 98, 89, 91, 131, 98, 96, 150, 62, 168,
-  135, 60, 79, 90, 84, 63, 109, 113, 94, 130,
-  127, 89, 84, 84, 133, 92, 98, 72, 68, 86,
-  100, 97, 138, 92, 124, 161, 102, 75, 93, 110,
-  110, 92, 125, 108, 73, 105, 185, 93, 99, 106,
-  113, 153, 129, 99, 116, 111, 124, 115, 95, 129,
-  122, 153, 103, 65, 100, 113, 78, 74, 117, 68,
-  77, 124, 110, 147, 160, 95, 129, 87, 86, 123,
-  95, 65, 93, 101, 74, 99, 110, 116, 128, 80,
-  125, 87, 59, 139, 108, 97, 96, 105, 47, 82,
-  69, 103, 114, 124, 141, 130, 108, 115, 89, 95,
-  196, 161, 127, 115, 99, 62, 73, 56, 106, 127,
-  135, 61, 92, 120, 103, 119, 64, 114, 42, 144,
-  101, 134, 88, 150, 90, 121, 80, 91, 62, 88,
-  76, 133, 120, 113, 126, 157, 169, 126, 179, 116,
-  74, 90, 122, 99, 88, 116, 131, 93, 80, 124,
-  74, 69, 116, 138, 164, 71, 136, 130, 135, 86,
-  79, 106, 87, 93, 127, 79, 117, 85, 101, 94,
-  91, 108, 80, 100, 91, 126, 118, 82, 123, 178,
-  90, 99, 110, 91, 97, 93, 126, 101, 104, 139,
-  36, 154, 146, 55, 82, 98, 107, 60, 122, 101,
-  108, 126, 100, 82, 105, 83, 118, 105, 92, 86,
-  88, 95, 92, 87, 127, 99, 127, 169, 110, 79,
-  100, 79, 114, 86, 114, 122, 70, 103, 197, 89,
-  112, 124, 101, 153, 122, 72, 120, 111, 104, 122,
-  115, 110, 109, 156, 114, 81, 118, 120, 103, 67,
-  117, 80, 68, 107, 95, 133, 169, 89, 145, 77,
-  59, 104, 129, 82, 84, 106, 59, 91, 103, 121,
-  134, 69, 116, 88, 65, 163, 109, 105, 119, 106,
-  40, 82, 86, 123, 126, 148, 129, 114, 123, 118,
-  98, 108, 177, 131, 141, 120, 106, 74, 108, 82,
-  119, 115, 135, 66, 82, 118, 85, 123, 69, 97,
-  79, 146, 140, 149, 92, 158, 80, 76, 69, 95,
-  69, 97, 72, 123, 124, 107, 157, 144, 181, 126,
-  178, 100, 93, 96, 122, 158, 78, 106, 122, 125,
-  78, 145, 73, 73, 106, 138, 134, 75, 124, 144,
-  114, 95, 71, 140, 68, 124, 98, 114, 141, 97,
-  124, 107, 90, 105, 97, 105, 105, 172, 126, 98,
-  130, 166, 102, 98, 123, 98, 116, 104, 108, 113,
-  99, 120, 53, 110, 133, 59, 74, 105, 146, 99,
-  119, 94, 137, 113, 108, 100, 101, 104, 115, 128,
-  96, 110, 96, 111, 89, 98, 107, 99, 116, 152,
-  116, 87, 112, 50, 126, 88, 107, 145, 75, 118,
-  192, 100, 149, 144, 62, 134, 117, 140, 112, 107,
-  104, 122, 131, 73, 108, 149, 130, 126, 139, 118,
-  112, 105, 122, 119, 58, 87, 73, 121, 153, 87,
-  127, 93, 121, 78, 132, 98, 85, 91, 87, 95,
-  87, 116, 139, 72, 105, 95, 81, 188, 105, 127,
-  120, 116, 59, 98, 111, 141, 129, 168, 89, 139,
-  127, 110, 94, 127, 123, 84, 133, 119, 129, 86,
-  97, 100, 137, 100, 122, 107, 69, 122, 77, 131,
-  98, 84, 99, 139, 144, 118, 88, 146, 72, 65,
-  97, 108, 103, 95, 77, 124, 133, 108, 151, 103,
-  183, 127, 142, 96, 128, 78, 117, 169, 93, 114,
-  128, 126, 88, 162, 74, 80, 95, 150, 101, 95,
-  115, 150, 114, 101, 68, 163, 78, 136, 67, 142,
-  133, 87, 136, 112, 126, 136, 110, 119, 117, 217,
-  112, 83, 117, 136, 122, 83, 127, 122, 113, 111,
-  95, 117, 89, 124, 56, 69, 106, 67, 57, 116,
-  140, 157, 128, 88, 128, 101, 129, 104, 91, 108,
-  135, 117, 99, 135, 94, 117, 103, 115, 127, 85,
-  105, 127, 126, 104, 113, 56, 125, 106, 95, 135,
-  78, 116, 199, 107, 120, 160, 50, 126, 135, 184,
-  97, 105, 98, 130, 123, 89, 105, 134, 123, 144,
-  147, 109, 101, 118, 134, 124, 68, 91, 78, 125,
-  131, 81, 98, 124, 167, 91, 125, 99, 78, 77,
-  107, 119, 93, 108, 121, 90, 99, 107, 94, 194,
-  102, 132, 103, 134, 80, 96, 111, 136, 142, 129,
-  70, 109, 116, 111, 93, 119, 118, 79, 146, 114,
-  141, 99, 104, 99, 140, 97, 113, 119, 65, 132,
-  96, 116, 110, 83, 91, 122, 117, 106, 85, 157,
-  86, 93, 127, 111, 128, 86, 91, 132, 135, 121,
-  123, 101, 191, 106, 141, 121, 139, 66, 117, 122,
-  105, 123, 119, 112, 95, 147, 71, 93, 79, 138,
-  98, 98, 115, 168, 122, 94, 62, 149, 89, 119,
-  71, 142, 139, 56, 117, 99, 116, 141, 120, 125,
-  108, 233, 100, 92, 104, 126, 132, 101, 120, 142,
-  115, 118, 106, 154, 88, 146, 53, 64, 122, 68,
-  55, 102, 84, 175, 118, 91, 105, 108, 126, 118,
-  88, 90, 142, 102, 77, 166, 115, 116, 120, 114,
-  121, 77, 96, 126, 145, 110, 113, 90, 102, 106,
-  97, 123, 80, 85, 216, 108, 102, 133, 78, 133,
-  138, 141, 113, 109, 101, 124, 104, 124, 113, 118,
-  108, 110, 127, 104, 84, 105, 125, 120, 81, 85,
-  94, 144, 127, 91, 96, 113, 121, 111, 97, 54,
-  79, 75, 89, 99, 110, 101, 106, 72, 111, 102,
-  70, 157, 93, 110, 83, 130, 58, 71, 82, 106,
-  133, 66, 93, 105, 119, 114, 107, 111, 149, 123,
-  128, 112, 120, 89, 109, 59, 136, 97, 112, 118,
-  76, 133, 120, 102, 87, 102, 73, 119, 92, 105,
-  92, 166, 99, 119, 119, 76, 129, 74, 105, 125,
-  135, 128, 110, 147, 194, 92, 166, 122, 116, 95,
-  124, 96, 112, 121, 116, 94, 100, 140, 73, 92,
-  96, 125, 102, 85, 123, 151, 119, 89, 74, 127,
-  73, 101, 90, 97, 114, 55, 97, 96, 98, 121,
-  122, 107, 93, 204, 102, 95, 109, 136, 114, 118,
-  111, 137, 115, 115, 115, 155, 91, 150, 52, 95,
-  141, 64, 62, 90, 80, 103, 105, 72, 102, 139,
-  107, 106, 90, 65, 106, 110, 76, 112, 120, 81,
-  107, 100, 119, 88, 114, 155, 142, 88, 112, 88,
-  113, 104, 100, 120, 68, 86, 231, 95, 136, 102,
-  105, 152, 134, 98, 118, 122, 107, 126, 122, 152,
-  129, 137, 95, 90, 121, 105, 83, 53, 132, 78,
-  77, 111, 110, 143, 128, 106, 120, 101, 82, 139,
-  104, 54, 97, 92, 78, 78, 118, 101, 102, 77,
-  103, 102, 75, 130, 107, 114, 93, 102, 60, 80,
-  82, 117, 129, 74, 136, 106, 105, 127, 114, 108,
-  169, 160, 128, 117, 115, 88, 109, 56, 137, 105,
-  129, 82, 86, 120, 113, 110, 71, 115, 58, 119,
-  139, 114, 92, 176, 106, 103, 89, 92, 94, 83,
-  83, 119, 115, 123, 164, 185, 191, 116, 175, 118,
-  87, 111, 131, 111, 116, 121, 119, 120, 106, 143,
-  88, 88, 115, 129, 100, 85, 124, 126, 104, 85,
-  77, 126, 75, 102, 127, 51, 142, 69, 111, 94,
-  95, 122, 100, 96, 87, 172, 131, 96, 114, 147,
-  100, 99, 107, 120, 119, 114, 108, 105, 101, 160,
-  61, 123, 139, 68, 77, 75, 93, 44, 117, 87,
-  118, 136, 111, 103, 97, 86, 77, 105, 90, 72,
-  106, 83, 104, 93, 102, 108, 113, 165, 144, 81,
-  102, 73, 121, 117, 116, 142, 74, 110, 191, 80,
-  82, 117, 73, 128, 119, 84, 112, 110, 86, 130,
-  113, 140, 105, 132, 86, 106, 94, 103, 83, 68,
-  111, 116, 59, 104, 124, 127, 108, 85, 136, 109,
-  90, 128, 134, 81, 85, 100, 89, 76, 82, 117,
-  102, 111, 87, 73, 83, 123, 122, 118, 105, 80,
-  45, 87, 95, 148, 116, 171, 143, 99, 115, 137,
-  136, 143, 132, 156, 158, 99, 124, 83, 132, 89,
-  131, 93, 118, 93, 89, 136, 75, 124, 63, 101,
-  84, 108, 150, 146, 95, 166, 100, 80, 95, 106,
-  102, 87, 74, 102, 100, 112, 192, 150, 167, 97,
-  148, 94, 94, 99, 114, 144, 96, 116, 112, 163,
-  78, 148, 83, 111, 113, 130, 87, 89, 116, 103,
-  97, 116, 56, 156, 52, 138, 98, 145, 108, 77,
-  121, 108, 86, 96, 91, 115, 96, 127, 134, 66,
-  123, 141, 113, 73, 98, 129, 94, 109, 84, 93,
-  82, 108, 44, 76, 105, 74, 79, 83, 119, 68,
-  116, 73, 131, 91, 110, 91, 89, 95, 81, 104,
-  85, 105, 83, 96, 100, 97, 99, 114, 111, 130,
-  124, 102, 105, 64, 131, 113, 98, 139, 82, 151,
-  140, 87, 115, 165, 45, 118, 125, 119, 102, 81,
-  88, 158, 90, 162, 100, 132, 90, 130, 97, 82,
-  97, 137, 121, 93, 48, 127, 126, 116, 93, 85,
-  107, 122, 104, 102, 109, 109, 92, 120, 120, 90,
-  72, 139, 108, 135, 52, 71, 100, 153, 146, 138,
-  99, 114, 69, 103, 98, 163, 146, 205, 102, 112,
-  112, 139, 103, 158, 95, 102, 135, 98, 123, 105,
-  107, 120, 125, 77, 114, 105, 74, 169, 53, 119,
-  86, 86, 151, 125, 152, 146, 108, 154, 101, 93,
-  135, 111, 125, 98, 107, 94, 120, 121, 139, 84,
-  134, 132, 107, 97, 135, 108, 103, 142, 102, 124,
-  108, 140, 79, 140, 113, 145, 110, 135, 99, 101,
-  98, 124, 108, 104, 30, 179, 122, 142, 95, 161,
-  135, 92, 150, 81, 126, 98, 114, 146, 106, 124,
-  142, 61, 100, 162, 161, 58, 108, 152, 109, 124,
-  66, 125, 69, 89, 125, 55, 105, 90, 95, 105,
-  146, 126, 109, 96, 121, 101, 124, 127, 69, 89,
-  105, 133, 73, 143, 108, 115, 106, 122, 122, 90,
-  103, 107, 120, 124, 102, 78, 122, 117, 87, 118,
-  68, 152, 132, 84, 194, 173, 53, 126, 146, 148,
-  120, 73, 100, 161, 115, 200, 97, 148, 84, 137,
-  131, 72, 80, 94, 146, 130, 56, 158, 112, 102,
-  126, 78, 75, 145, 121, 101, 96, 115, 116, 127,
-  165, 118, 85, 128, 111, 137, 53, 108, 90, 189,
-  137, 154, 72, 112, 88, 95, 94, 146, 138, 126,
-  105, 121, 147, 120, 63, 106, 92, 89, 155, 110,
-  144, 154, 89, 136, 132, 72, 117, 106, 95, 104,
-  67, 113, 118, 77, 165, 125, 169, 114, 105, 148,
-  99, 83, 84, 126, 116, 92, 138, 122, 136, 97,
-  119, 65, 129, 144, 92, 122, 150, 94, 115, 155,
-  127, 103, 113, 158, 108, 133, 126, 140, 119, 121,
-  127, 105, 96, 137, 119, 51, 44, 179, 135, 92,
-  135, 82, 169, 82, 116, 54, 135, 189, 124, 125,
-  119, 137, 141, 47, 113, 186, 152, 89, 136, 150,
-  130, 107, 61, 87, 71, 111, 170, 68, 126, 110,
-  103, 97, 80, 126, 119, 109, 96, 95, 121, 241,
-  57, 89, 116, 119, 79, 98, 136, 123, 136, 119,
-  103, 69, 99, 118, 112, 122, 73, 100, 121, 118,
-  99, 101, 87, 79, 149, 80, 73, 126, 50, 110,
-  165, 164, 126, 138, 75, 119, 100, 162, 112, 110,
-  125, 130, 79, 87, 60, 105, 124, 161, 51, 117,
-  99, 114, 123, 75, 77, 115, 128, 107, 76, 117,
-  84, 115, 139, 114, 84, 108, 102, 151, 58, 90,
-  82, 148, 120, 137, 39, 81, 74, 92, 76, 105,
-  126, 76, 125, 102, 137, 97, 96, 99, 98, 138,
-  134, 94, 126, 151, 126, 91, 127, 78, 122, 148,
-  109, 99, 85, 122, 97, 102, 90, 87, 108, 91,
-  88, 151, 68, 112, 102, 131, 114, 61, 128, 141,
-  163, 104, 125, 76, 153, 77, 93, 125, 128, 94,
-  127, 114, 114, 107, 112, 128, 61, 123, 90, 115,
-  114, 105, 119, 103, 111, 88, 141, 83, 32, 140,
-  88, 79, 118, 124, 130, 56, 101, 114, 122, 152,
-  116, 107, 120, 104, 113, 28, 113, 168, 116, 115,
-  121, 145, 83, 92, 74, 81, 85, 123, 50, 77,
-  135, 83, 71, 114, 46, 76, 109, 82, 84, 62,
-  97, 132, 60, 79, 134, 102, 108, 93, 89, 114,
-  139, 107, 121, 108, 84, 130, 88, 106, 73, 111,
-  121, 82, 97, 77, 124, 68, 162, 78, 121, 105,
-  64, 116, 152, 113, 119, 151, 93, 105, 105, 124,
-  107, 96, 116, 157, 79, 99, 59, 75, 118, 99,
-  46, 132, 131, 100, 108, 83, 74, 103, 83, 117,
-  82, 111, 72, 121, 119, 113, 85, 97, 117, 142,
-  75, 83, 108, 131, 129, 146, 33, 105, 91, 114,
-  65, 96, 133, 122, 118, 109, 120, 108, 101, 114,
-  90, 118, 98, 143, 118, 124, 123, 76, 119, 104,
-  136, 118, 85, 102, 87, 90, 105, 106, 97, 96,
-  69, 99, 100, 142, 56, 127, 114, 128, 100, 63,
-  75, 109, 145, 112, 132, 108, 122, 105, 100, 145,
-  100, 119, 110, 74, 147, 125, 103, 117, 104, 106,
-  85, 141, 117, 85, 124, 108, 111, 95, 159, 90,
-  44, 102, 98, 93, 115, 98, 130, 53, 148, 166,
-  106, 102, 128, 118, 112, 98, 119, 43, 99, 165,
-  127, 112, 81, 148, 62, 116, 106, 114, 70, 138,
-  95, 94, 117, 74, 86, 118, 102, 64, 100, 93,
-  125, 80, 82, 145, 61, 77, 111, 133, 118, 107,
-  67, 120, 138, 106, 128, 176, 89, 112, 105, 85,
-  95, 137, 90, 85, 103, 78, 113, 117, 147, 86,
-  111, 141, 68, 106, 111, 105, 114, 119, 104, 115,
-  143, 101, 104, 106, 107, 185, 93, 112, 104, 42,
-  113, 91, 42, 140, 165, 84, 79, 82, 125, 100,
-  73, 104, 130, 126, 79, 123, 139, 127, 97, 96,
-  123, 107, 80, 108, 151, 142, 143, 161, 68, 104,
-  111, 146, 77, 139, 142, 134, 113, 117, 118, 143,
-  86, 120, 89, 100, 125, 139, 95, 100, 113, 99,
-  118, 113, 135, 116, 86, 107, 66, 84, 116, 104,
-  118, 111, 105, 96, 123, 119, 87, 103, 102, 109,
-  92, 85, 90, 94, 151, 120, 153, 124, 118, 113,
-  116, 149, 98, 127, 90, 85, 134, 126, 120, 159,
-  104, 98, 102, 163, 110, 117, 84, 119, 85, 101,
-  110, 111, 55, 81, 88, 123, 105, 86, 122, 81,
-  163, 158, 94, 109, 145, 147, 110, 102, 115, 90,
-  98, 145, 138, 108, 64, 127, 80, 119, 122, 120,
-  54, 123, 95, 110, 79, 91, 113, 124, 126, 101,
-  109, 102, 139, 68, 80, 122, 62, 99, 90, 163,
-  119, 112, 50, 123, 133, 122, 110, 173, 94, 96,
-  117, 88, 85, 116, 89, 106, 97, 90, 120, 118,
-  127, 93, 100, 154, 93, 115, 104, 117, 121, 98,
-  107, 119, 164, 112, 105, 90, 118, 166, 107, 116,
-  127, 90, 123, 112, 74, 149, 182, 91, 94, 98,
-  160, 108, 73, 105, 155, 149, 87, 124, 146, 107,
-  129, 115, 134, 101, 83, 105, 142, 121, 130, 168,
-  114, 95, 116, 147, 105, 169, 137, 119, 131, 122,
-  114, 155, 99, 117, 118, 126, 152, 112, 107, 92,
-  89, 135, 98, 115, 132, 135, 171, 115, 96, 113,
-  140, 88, 131, 107, 143, 117, 138, 123, 108, 114,
-  112, 109, 111, 126, 117, 97, 188, 126, 121, 132,
-  139, 107, 140, 141, 124, 113, 103, 134, 112, 162,
-  131, 162, 106, 102, 115, 139, 118, 141, 74, 129,
-  71, 117, 102, 126, 81, 111, 88, 124, 115, 124,
-  126, 115, 134, 116, 111, 119, 169, 146, 117, 105,
-  110, 106, 100, 129, 140, 106, 76, 113, 93, 145,
-  120, 123, 91, 115, 96, 141, 76, 108, 119, 119,
-  135, 100, 123, 124, 127, 70, 96, 114, 87, 137,
-  93, 149, 120, 131, 80, 101, 118, 117, 113, 148,
-  99, 100, 135, 106, 90, 103, 100, 112, 97, 107,
-  147, 119, 153, 107, 84, 134, 90, 93, 145, 106,
-  102, 158, 113, 129, 145, 137, 140, 128, 89, 128,
-  117, 118, 70, 129, 130, 82, 103, 127, 167, 146,
-  152, 100, 100, 81, 135, 96, 67, 110, 86, 91,
-  111, 92, 124, 133, 128, 99, 79, 110, 119, 102,
-  101, 126, 118, 93, 111, 138, 110, 114, 138, 121,
-  102, 135, 127, 119, 114, 128, 117, 104, 103, 101,
-  122, 118, 121, 86, 136, 98, 111, 108, 120, 155,
-  153, 157, 107, 98, 89, 105, 118, 111, 115, 119,
-  93, 113, 138, 107, 107, 97, 106, 115, 112, 123,
-  108, 126, 155, 108, 128, 139, 107, 104, 140, 154,
-  115, 123, 135, 110, 90, 135, 97, 116, 99, 138,
-  93, 110, 152, 148, 143, 107, 99, 110, 107, 133,
-  106, 120, 109, 78, 109, 138, 109, 95, 117, 115,
-  66, 145, 102, 82, 97, 148, 131, 114, 125, 141,
-  103, 116, 87, 155, 123, 141, 93, 105, 132, 114,
-  111, 103, 95, 121, 147, 111, 127, 106, 109, 146,
-  88, 74, 129, 81, 101, 124, 112, 125, 132, 65,
-  143, 138, 124, 104, 174, 127, 100, 114, 144, 103,
-  70, 124, 140, 104, 168, 105, 141, 122, 87, 76,
-  142, 109, 99, 107, 98, 142, 122, 142, 128, 130,
-  89, 125, 101, 100, 105, 121, 107, 92, 83, 131,
-  92, 144, 154, 107, 102, 120, 115, 84, 67, 108,
-  68, 108, 137, 91, 119, 100, 118, 108, 70, 76,
-  115, 131, 76, 139, 115, 129, 111, 126, 99, 127,
-  146, 104, 79, 157, 103, 132, 72, 111, 113, 93,
-  94, 102, 106, 100, 92, 87, 145, 88, 126, 98,
-  68, 190, 117, 140, 89, 104, 90, 123, 101, 143,
-  116, 134, 97, 108, 130, 95, 111, 60, 116, 153,
-  122, 136, 102, 117, 182, 89, 140, 142, 143, 127,
-  129, 142, 87, 210, 146, 96, 90, 148, 80, 119,
-  94, 187, 100, 117, 147, 160, 127, 120, 91, 106,
-  106, 131, 96, 125, 139, 60, 103, 96, 115, 123,
-  102, 137, 52, 165, 100, 97, 115, 147, 130, 93,
-  109, 150, 102, 108, 99, 173, 122, 162, 105, 92,
-  130, 98, 101, 109, 136, 110, 142, 96, 134, 163,
-  100, 122, 66, 52, 128, 126, 87, 141, 115, 115,
-  114, 73, 151, 120, 121, 93, 176, 106, 95, 120,
-  156, 98, 73, 135, 114, 115, 166, 94, 122, 125,
-  96, 90, 135, 112, 90, 101, 91, 128, 110, 148,
-  122, 130, 103, 112, 112, 79, 105, 75, 106, 110,
-  59, 133, 35, 118, 148, 98, 110, 106, 95, 79,
-  93, 106, 59, 129, 129, 99, 95, 111, 99, 137,
-  68, 105, 95, 157, 109, 145, 116, 134, 106, 92,
-  89, 135, 115, 92, 77, 112, 97, 116, 99, 91,
-  104, 91, 99, 106, 126, 115, 90, 89, 121, 86,
-  127, 92, 82, 151, 58, 131, 100, 95, 120, 88,
-  123, 147, 82, 148, 98, 102, 83, 124, 105, 70,
-  110, 155, 117, 123, 107, 88, 161, 126, 128, 134,
-  154, 113, 111, 176, 90, 145, 109, 115, 81, 115,
-  82, 104, 91, 162, 103, 95, 131, 160, 120, 88,
-  56, 98, 98, 110, 114, 79, 167, 73, 102, 86,
-  124, 171, 92, 127, 66, 156, 98, 103, 118, 146,
-  123, 88, 114, 139, 96, 99, 63, 110, 110, 149,
-  94, 90, 132, 93, 78, 109, 113, 99, 103, 102,
-  104, 142, 131, 119, 70, 79, 118, 132, 72, 116,
-  131, 101, 106, 77, 115, 95, 98, 111, 130, 100,
-  100, 104, 121, 91, 78, 139, 97, 113, 166, 78,
-  109, 109, 91, 94, 113, 149, 83, 94, 79, 106,
-  81, 89, 94, 95, 108, 108, 126, 87, 91, 118,
-  114, 124, 41, 87, 35, 103, 141, 86, 118, 113,
-  123, 62, 89, 107, 61, 107, 125, 111, 75, 101,
-  98, 76, 91, 72, 67, 156, 101, 120, 101, 125,
-  85, 103, 89, 107, 107, 85, 76, 126, 99, 78,
-  110, 109, 74, 75, 80, 111, 107, 87, 62, 79,
-  87, 88, 110, 147, 87, 118, 80, 130, 91, 83,
-  127, 78, 83, 82, 84, 132, 67, 96, 116, 105,
-  90, 76, 117, 117, 120, 117, 78, 64, 119, 127,
-  103, 105, 142, 76, 81, 145, 88, 122, 121, 83,
-  88, 110, 67, 97, 96, 137, 95, 96, 114, 140,
-  123, 95, 55, 101, 85, 102, 78, 109, 94, 90,
-  93, 97, 129, 146, 91, 115, 96, 157, 79, 86,
-  112, 131, 111, 77, 96, 107, 86, 94, 39, 97,
-  92, 110, 71, 62, 98, 73, 43, 118, 86, 104,
-  94, 84, 114, 111, 130, 101, 85, 79, 111, 140,
-  88, 123, 98, 89, 83, 87, 156, 87, 87, 129,
-  94, 97, 91, 86, 78, 83, 88, 121, 91, 98,
-  189, 93, 115, 86, 134, 121, 118, 169, 85, 82,
-  82, 116, 84, 87, 95, 90, 98, 100, 124, 110,
-  92, 98, 105, 89, 51, 84, 58, 117, 158, 96,
-  125, 115, 122, 88, 113, 101, 82, 76, 96, 102,
-  97, 105, 123, 42, 119, 73, 68, 154, 100, 109,
-  104, 151, 66, 107, 94, 99, 115, 98, 91, 101,
-  100, 92, 119, 99, 111, 112, 86, 119, 98, 97,
-  98, 80, 94, 90, 124, 107, 106, 120, 102, 109,
-  83, 84, 96, 95, 53, 78, 78, 142, 64, 98,
-  123, 84, 92, 88, 81, 136, 121, 125, 105, 93,
-  146, 118, 125, 112, 133, 85, 103, 68, 81, 113,
-  116, 75, 87, 111, 76, 88, 84, 135, 110, 106,
-  109, 144, 117, 89, 74, 101, 94, 97, 104, 91,
-  110, 101, 83, 89, 133, 103, 107, 113, 105, 149,
-  92, 119, 114, 126, 95, 94, 105, 92, 111, 95,
-  94, 107, 109, 140, 57, 98, 117, 70, 55, 94,
-  62, 73, 90, 84, 92, 121, 112, 92, 98, 109,
-  110, 111, 88, 105, 110, 89, 80, 89, 125, 86,
-  85, 154, 91, 92, 91, 86, 86, 78, 110, 126,
-  79, 86, 184, 86, 84, 89, 138, 137, 115, 151,
-  118, 101, 83, 118, 96, 86, 111, 93, 92, 107,
-  120, 117, 87, 77, 98, 94, 59, 92, 60, 124,
-  154, 100, 119, 105, 121, 94, 96, 77, 89, 76,
-  84, 106, 94, 99, 131, 39, 157, 76, 73, 168,
-  120, 114, 97, 134, 54, 94, 93, 98, 107, 108,
-  79, 100, 104, 90, 119, 104, 143, 119, 99, 108,
-  95, 87, 108, 87, 109, 86, 131, 87, 100, 110,
-  101, 97, 78, 95, 45, 94, 57, 104, 69, 158,
-  78, 87, 102, 99, 91, 86, 72, 120, 89, 123,
-  105, 117, 178, 101, 141, 127, 145, 89, 131, 82,
-  92, 100, 120, 90, 91, 109, 75, 77, 70, 124,
-  99, 97, 115, 152, 112, 78, 107, 104, 85, 97,
-  91, 74, 106, 89, 99, 91, 107, 97, 113, 98,
-  122, 131, 104, 115, 123, 128, 108, 102, 111, 81,
-  127, 87, 121, 108, 118, 161, 50, 97, 113, 68,
-  53, 73, 60, 96, 96, 73, 92, 120, 111, 85,
-  107, 98, 105, 88, 73, 84, 107, 110, 87, 83,
-  110, 80, 87, 132, 101, 95, 107, 86, 102, 83,
-  119, 138, 82, 109, 152, 91, 87, 101, 130, 131,
-  112, 123, 124, 102, 89, 117, 112, 111, 107, 109,
-  94, 111, 117, 119, 86, 64, 91, 101, 73, 120,
-  74, 119, 147, 107, 109, 85, 109, 101, 99, 52,
-  90, 87, 65, 95, 111, 99, 122, 39, 159, 83,
-  74, 166, 128, 108, 91, 121, 57, 83, 80, 99,
-  101, 82, 89, 107, 107, 95, 109, 107, 148, 119,
-  112, 114, 91, 82, 104, 82, 121, 90, 139, 86,
-  104, 106, 117, 92, 74, 100, 34, 83, 84, 122,
-  72, 155, 95, 81, 108, 100, 96, 88, 68, 84,
-  70, 106, 106, 132, 178, 94, 140, 146, 130, 102,
-  135, 94, 102, 99, 115, 93, 105, 105, 86, 71,
-  66, 114, 112, 83, 104, 145, 111, 74, 125, 107,
-  84, 93, 73, 65, 105, 75, 90, 75, 87, 95,
-  126, 92, 118, 109, 128, 109, 121, 141, 120, 106,
-  102, 90, 126, 91, 124, 129, 111, 161, 48, 103,
-  121, 74, 71, 72, 85, 108, 97, 83, 98, 104,
-  101, 82, 111, 89, 101, 91, 71, 59, 111, 119,
-  91, 78, 91, 80, 98, 94, 111, 92, 100, 89,
-  105, 95, 117, 156, 95, 103, 121, 83, 85, 103,
-  124, 113, 124, 114, 119, 106, 94, 98, 115, 128,
-  122, 102, 97, 111, 99, 99, 75, 60, 87, 114,
-  70, 126, 77, 114, 131, 103, 97, 94, 90, 113,
-  84, 56, 77, 106, 69, 90, 115, 102, 116, 51,
-  129, 97, 75, 124, 133, 105, 89, 109, 75, 84,
-  66, 89, 95, 72, 127, 114, 110, 109, 141, 113,
-  133, 128, 109, 126, 89, 95, 92, 62, 139, 98,
-  143, 99, 96, 105, 167, 112, 74, 103, 43, 73,
-  97, 111, 69, 137, 98, 92, 102, 116, 98, 98,
-  71, 81, 66, 101, 90, 147, 156, 83, 123, 154,
-  112, 120, 134, 116, 129, 120, 113, 95, 105, 97,
-  82, 75, 88, 112, 129, 74, 111, 116, 126, 82,
-  117, 114, 93, 97, 75, 77, 103, 74, 86, 89,
-  73, 100, 125, 95, 98, 77, 139, 121, 111, 149,
-  115, 112, 88, 90, 105, 94, 121, 125, 107, 148,
-  62, 112, 121, 80, 88, 87, 110, 96, 94, 85,
-  94, 109, 91, 96, 109, 88, 108, 97, 78, 60,
-  97, 115, 102, 74, 90, 105, 110, 72, 122, 93,
-  88, 111, 102, 107, 103, 161, 109, 119, 103, 88,
-  94, 100, 109, 97, 129, 105, 106, 117, 107, 83,
-  106, 118, 126, 104, 110, 118, 96, 85, 66, 55,
-  88, 106, 66, 108, 98, 103, 89, 104, 86, 115,
-  88, 111, 67, 80, 86, 108, 93, 101, 115, 102,
-  125, 72, 113, 99, 87, 85, 138, 103, 66, 99,
-  83, 106, 76, 85, 90, 95, 135, 117, 104, 119,
-  124, 113, 95, 99, 83, 122, 95, 122, 88, 54,
-  143, 98, 134, 104, 75, 104, 166, 127, 81, 105,
-  58, 89, 93, 72, 75, 103, 87, 100, 104, 130,
-  100, 99, 67, 88, 76, 103, 94, 136, 118, 106,
-  92, 144, 93, 140, 126, 104, 151, 140, 113, 90,
-  110, 100, 85, 76, 108, 114, 119, 79, 111, 76,
-  138, 100, 113, 104, 123, 97, 78, 81, 93, 86,
-  121, 107, 85, 113, 108, 93, 92, 56, 116, 120,
-  107, 143, 107, 100, 69, 82, 92, 105, 115, 123,
-  92, 124, 88, 113, 101, 90, 96, 108, 107, 91,
-  110, 92, 115, 117, 92, 115, 93, 102, 109, 97,
-  91, 66, 82, 121, 123, 91, 92, 140, 119, 67,
-  130, 94, 81, 138, 93, 99, 93, 134, 130, 116,
-  97, 97, 97, 93, 101, 92, 104, 102, 97, 102,
-  119, 79, 114, 94, 124, 115, 127, 125, 95, 84,
-  70, 53, 90, 99, 62, 90, 94, 91, 66, 92,
-  87, 117, 92, 99, 68, 100, 95, 103, 107, 104,
-  103, 83, 135, 104, 115, 99, 107, 76, 140, 101,
-  51, 105, 75, 127, 82, 102, 88, 110, 121, 96,
-  102, 117, 110, 112, 73, 88, 92, 108, 99, 142,
-  104, 51, 131, 98, 119, 97, 76, 106, 117, 115,
-  79, 109, 45, 97, 95, 72, 63, 81, 76, 119,
-  102, 119, 101, 101, 63, 110, 99, 99, 95, 109,
-  109, 93, 90, 142, 85, 119, 120, 91, 150, 134,
-  110, 97, 91, 106, 86, 91, 113, 121, 102, 90,
-  117, 55, 126, 138, 106, 95, 124, 100, 72, 89,
-  86, 98, 140, 137, 98, 103, 91, 88, 99, 58,
-  99, 123, 103, 143, 100, 98, 49, 78, 96, 118,
-  116, 112, 77, 96, 89, 105, 84, 94, 92, 118,
-  86, 98, 110, 81, 115, 116, 96, 114, 82, 116,
-  105, 98, 104, 75, 80, 122, 132, 106, 85, 145,
-  123, 86, 134, 104, 86, 142, 94, 83, 89, 102,
-  127, 94, 97, 109, 109, 101, 100, 97, 68, 95,
-  91, 92, 127, 79, 126, 86, 117, 113, 128, 128,
-  108, 88, 86, 43, 81, 97, 55, 86, 86, 76,
-  67, 75, 92, 118, 85, 95, 77, 118, 96, 102,
-  91, 92, 90, 59, 139, 119, 136, 100, 127, 92,
-  132, 103, 51, 115, 67, 133, 93, 125, 94, 105,
-  107, 78, 107, 106, 100, 108, 64, 80, 103, 93,
-  92, 159, 114, 66, 125, 107, 104, 90, 81, 101,
-  93, 89, 82, 122, 44, 85, 94, 81, 50, 80,
-  72, 113, 111, 115, 97, 90, 63, 102, 109, 92,
-  94, 84, 120, 77, 108, 130, 96, 102, 115, 92,
-  147, 121, 109, 111, 88, 112, 84, 112, 98, 129,
-  88, 111, 111, 60, 121, 152, 95, 84, 116, 93,
-  77, 79, 102, 99, 135, 154, 107, 100, 87, 88,
-  111, 68, 100, 123, 99, 137, 98, 102, 35, 78,
-  109, 126, 104, 114, 65, 93, 86, 100, 72, 83,
-  81, 108, 87, 119, 95, 81, 116, 110, 109, 109,
-  75, 130, 96, 106, 97, 79, 96, 119, 132, 115,
-  73, 137, 109, 99, 132, 95, 104, 144, 87, 75,
-  95, 78, 118, 96, 98, 115, 105, 89, 90, 120,
-  37, 95, 81, 93, 135, 77, 145, 99, 113, 105,
-  120, 123, 102, 90, 99, 35, 74, 114, 42, 86,
-  83, 79, 69, 69, 109, 123, 91, 87, 93, 121,
-  95, 100, 85, 84, 84, 42, 127, 106, 146, 103,
-  144, 97, 116, 110, 76, 110, 45, 130, 103, 149,
-  90, 100, 97, 84, 121, 108, 104, 115, 60, 93,
-  105, 98, 90, 174, 111, 77, 116, 110, 102, 100,
-  86, 108, 101, 87, 89, 131, 48, 83, 110, 68,
-  35, 87, 77, 107, 112, 123, 96, 88, 65, 97,
-  100, 98, 95, 63, 110, 86, 126, 115, 104, 96,
-  111, 90, 114, 111, 112, 137, 82, 111, 90, 122,
-  82, 143, 76, 122, 108, 72, 121, 172, 79, 91,
-  90, 98, 97, 78, 96, 97, 117, 158, 114, 106,
-  79, 94, 120, 68, 98, 116, 105, 127, 99, 99,
-  35, 90, 122, 120, 95, 100, 62, 88, 63, 100,
-  64, 86, 74, 108, 90, 119, 99, 72, 117, 103,
-  121, 92, 72, 128, 85, 105, 85, 68, 105, 111,
-  126, 112, 76, 124, 98, 117, 122, 90, 117, 133,
-  95, 69, 98, 66, 104, 104, 107, 119, 119, 73,
-  83, 123, 20, 107, 67, 84, 132, 76, 158, 119,
-  111, 104, 120, 112, 84, 95, 98, 56, 66, 100,
-  34, 81, 92, 98, 74, 61, 118, 133, 112, 87,
-  102, 119, 98, 93, 101, 73, 82, 39, 115, 101,
-  141, 119, 145, 99, 103, 115, 90, 112, 45, 98,
-  102, 158, 91, 88, 102, 95, 109, 100, 91, 111,
-  52, 113, 109, 108, 103, 178, 113, 73, 110, 110,
-  104, 101, 96, 115, 114, 94, 91, 129, 51, 84,
-  125, 83, 36, 94, 83, 105, 123, 109, 130, 85,
-  81, 102, 97, 98, 100, 55, 99, 83, 137, 105,
-  101, 88, 98, 91, 85, 109, 112, 138, 86, 109,
-  88, 125, 80, 151, 88, 119, 104, 78, 121, 191,
-  61, 103, 73, 101, 113, 102, 95, 86, 95, 125,
-  116, 88, 75, 94, 119, 63, 91, 115, 119, 121,
-  100, 90, 25, 113, 121, 112, 96, 94, 63, 79,
-  69, 107, 66, 91, 82, 92, 91, 110, 99, 84,
-  117, 103, 131, 87, 71, 126, 84, 98, 83, 64,
-  106, 103, 122, 108, 88, 97, 92, 130, 114, 84,
-  112, 123, 101, 56, 100, 75, 88, 100, 116, 113,
-  119, 74, 70, 112, 28, 124, 52, 70, 124, 78,
-  152, 118, 95, 100, 116, 110, 59, 86, 78, 91,
-  70, 104, 27, 83, 107, 111, 84, 49, 97, 132,
-  122, 87, 87, 106, 89, 87, 110, 76, 72, 42,
-  116, 116, 129, 130, 122, 107, 92, 118, 84, 112,
-  56, 60, 98, 122, 89, 74, 101, 95, 90, 83,
-  65, 102, 43, 110, 108, 109, 114, 173, 96, 50,
-  104, 114, 100, 89, 94, 107, 107, 95, 91, 109,
-  73, 85, 105, 92, 57, 94, 83, 113, 119, 94,
-  173, 81, 107, 108, 98, 95, 101, 62, 96, 86,
-  124, 106, 89, 77, 88, 100, 99, 115, 117, 116,
-  93, 92, 80, 127, 93, 129, 105, 109, 108, 80,
-  127, 186, 54, 110, 72, 89, 110, 122, 100, 64,
-  71, 84, 127, 99, 76, 83, 106, 64, 73, 116,
-  122, 129, 100, 91, 15, 124, 101, 104, 102, 86,
-  63, 78, 91, 115, 69, 89, 94, 78, 85, 105,
-  82, 94, 100, 108, 131, 116, 58, 108, 109, 89,
-  87, 49, 89, 89, 108, 101, 100, 84, 90, 128,
-  106, 75, 95, 129, 93, 52, 97, 79, 61, 93,
-  133, 108, 98, 77, 69, 107, 67, 141, 48, 85,
-  120, 79, 127, 109, 105, 102, 131, 115, 50, 83,
-  59, 119, 66, 126, 33, 83, 113, 109, 100, 48,
-  79, 112, 121, 91, 68, 97, 82, 84, 98, 86,
-  75, 49, 118, 121, 117, 107, 94, 111, 88, 114,
-  52, 116, 74, 39, 79, 79, 97, 71, 94, 84,
-  86, 70, 54, 88, 61, 102, 87, 87, 107, 154,
-  73, 38, 90, 125, 101, 81, 97, 90, 96, 110,
-  81, 90, 74, 107, 72, 89, 82, 90, 66, 124,
-  109, 88, 189, 67, 108, 112, 109, 89, 90, 70,
-  111, 102, 108, 104, 76, 70, 79, 88, 122, 122,
-  120, 82, 85, 79, 76, 111, 102, 104, 127, 103,
-  125, 79, 135, 142, 49, 112, 93, 80, 110, 109,
-  113, 51, 71, 78, 120, 109, 80, 72, 93, 69,
-  57, 96, 109, 141, 109, 82, 27, 115, 71, 101,
-  101, 95, 66, 90, 75, 123, 88, 85, 89, 84,
-  78, 93, 83, 102, 87, 111, 123, 121, 45, 90,
-  131, 83, 99, 49, 74, 84, 104, 95, 105, 74,
-  93, 132, 99, 69, 81, 127, 76, 59, 95, 72,
-  36, 82, 161, 98, 96, 78, 83, 121, 119, 137,
-  69, 108, 113, 96, 85, 113, 129, 115, 136, 100,
-  58, 87, 44, 131, 77, 113, 43, 93, 107, 116,
-  145, 70, 88, 97, 105, 100, 62, 86, 78, 84,
-  72, 83, 92, 79, 127, 91, 106, 72, 66, 118,
-  97, 114, 40, 119, 71, 36, 62, 60, 105, 85,
-  104, 95, 93, 74, 66, 82, 115, 108, 69, 88,
-  94, 112, 69, 48, 90, 134, 117, 60, 94, 89,
-  104, 127, 74, 82, 61, 143, 54, 113, 90, 116,
-  51, 145, 108, 81, 160, 66, 89, 126, 113, 94,
-  80, 84, 145, 113, 133, 99, 74, 47, 88, 87,
-  122, 110, 121, 65, 76, 87, 73, 88, 111, 104,
-  163, 94, 137, 109, 149, 99, 60, 109, 103, 82,
-  104, 86, 122, 54, 82, 91, 103, 93, 70, 71,
-  90, 98, 62, 94, 106, 166, 112, 86, 57, 98,
-  64, 100, 96, 102, 81, 113, 61, 142, 124, 70,
-  67, 96, 83, 69, 97, 121, 92, 120, 113, 106,
-  61, 88, 125, 90, 109, 59, 83, 81, 97, 84,
-  123, 76, 106, 139, 96, 75, 83, 114, 72, 74,
-  99, 81, 54, 85, 190, 83, 111, 83, 102, 141,
-  138, 92, 91, 113, 92, 122, 71, 117, 101, 117,
-  125, 76, 78, 94, 50, 106, 112, 63, 56, 98,
-  93, 129, 191, 90, 121, 89, 68, 100, 81, 92,
-  74, 83, 46, 89, 95, 111, 127, 67, 96, 67,
-  54, 148, 97, 122, 67, 108, 56, 56, 66, 74,
-  114, 118, 119, 106, 93, 82, 78, 85, 146, 119,
-  95, 102, 99, 74, 91, 57, 103, 126, 132, 62,
-  98, 113, 94, 135, 73, 75, 67, 143, 73, 141,
-  82, 153, 46, 142, 88, 80, 90, 72, 55, 131,
-  120, 106, 95, 101, 166, 114, 161, 93, 88, 43,
-  99, 130, 94, 102, 115, 82, 71, 124, 72, 83,
-  108, 123, 186, 74, 128, 148, 144, 82, 62, 108,
-  101, 102, 92, 75, 130, 68, 93, 81, 96, 90,
-  66, 83, 88, 155, 90, 114, 117, 180, 101, 90,
-  93, 97, 93, 98, 90, 109, 92, 116, 61, 135,
-  155, 53, 60, 99, 119, 63, 90, 123, 101, 126,
-  92, 94, 82, 102, 112, 116, 110, 79, 107, 78,
-  76, 72, 146, 95, 107, 142, 103, 78, 83, 96,
-  105, 78, 109, 119, 73, 105, 204, 74, 137, 103,
-  88, 145, 123, 94, 102, 101, 78, 135, 94, 91,
-  84, 121, 110, 87, 113, 102, 77, 82, 115, 78,
-  56, 96, 60, 132, 192, 92, 125, 87, 90, 86,
-  87, 96, 77, 90, 64, 93, 86, 119, 129, 56,
-  98, 82, 51, 187, 96, 126, 88, 129, 48, 75,
-  83, 103, 107, 152, 99, 144, 106, 76, 106, 98,
-  126, 94, 101, 118, 103, 70, 95, 78, 134, 105,
-  131, 85, 96, 118, 91, 129, 86, 68, 76, 125,
-  85, 124, 78, 161, 46, 89, 61, 82, 76, 74,
-  47, 119, 124, 96, 103, 91, 175, 118, 143, 94,
-  128, 60, 96, 153, 92, 105, 119, 94, 76, 155,
-  72, 79, 104, 128, 158, 83, 106, 157, 121, 81,
-  66, 129, 79, 125, 75, 96, 141, 78, 103, 96,
-  118, 126, 73, 99, 100, 207, 112, 114, 109, 158,
-  107, 83, 115, 114, 111, 91, 93, 101, 85, 118,
-  61, 85, 133, 48, 61, 98, 144, 106, 89, 102,
-  107, 123, 92, 103, 92, 97, 113, 125, 98, 104,
-  111, 84, 82, 72, 149, 111, 98, 140, 103, 93,
-  91, 93, 122, 92, 109, 145, 65, 109, 207, 73,
-  127, 129, 75, 143, 129, 151, 90, 110, 83, 130,
-  118, 95, 90, 122, 113, 123, 123, 97, 91, 104,
-  115, 87, 54, 98, 53, 143, 154, 84, 102, 108,
-  134, 81, 85, 115, 71, 98, 92, 91, 88, 111,
-  121, 78, 95, 103, 66, 188, 100, 121, 87, 135,
-  58, 65, 104, 118, 116, 119, 74, 118, 84, 74,
-  119, 101, 104, 69, 106, 117, 112, 96, 95, 90,
-  137, 105, 113, 103, 81, 124, 135, 125, 97, 74,
-  73, 104, 96, 100, 76, 156, 62, 74, 102, 92,
-  117, 72, 73, 98, 113, 102, 104, 94, 178, 111,
-  125, 118, 145, 77, 98, 132, 103, 118, 122, 101,
-  86, 159, 74, 82, 84, 129, 120, 89, 104, 153,
-  116, 79, 56, 146, 79, 113, 71, 120, 155, 71,
-  99, 88, 125, 144, 94, 110, 93, 227, 113, 112,
-  98, 132, 101, 83, 112, 130, 108, 98, 100, 130,
-  82, 129, 70, 70, 125, 67, 67, 101, 106, 129,
-  95, 89, 106, 114, 110, 116, 83, 79, 125, 106,
-  75, 146, 114, 91, 105, 75, 134, 99, 84, 132,
-  125, 102, 93, 98, 124, 89, 96, 146, 66, 92,
-  204, 72, 107, 117, 84, 127, 143, 140, 93, 119,
-  91, 114, 91, 111, 96, 97, 102, 135, 101, 89,
-  60, 119, 103, 117, 59, 98, 92, 167, 136, 87,
-  88, 113, 119, 87, 76, 92, 68, 89, 97, 85,
-  97, 96, 104, 71, 103, 95, 60, 149, 92, 96,
-  65, 104, 53, 55, 98, 103, 103, 71, 86, 120,
-  96, 72, 107, 97, 108, 80, 97, 121, 111, 111,
-  105, 63, 130, 101, 108, 118, 68, 124, 162, 135,
-  86, 83, 72, 104, 93, 96, 85, 156, 67, 97,
-  120, 68, 143, 54, 85, 92, 113, 115, 91, 117,
-  166, 79, 122, 129, 131, 89, 96, 113, 101, 128,
-  122, 95, 88, 155, 77, 78, 82, 129, 109, 65,
-  118, 129, 123, 77, 63, 140, 93, 103, 77, 111,
-  119, 69, 102, 96, 112, 138, 110, 98, 78, 202,
-  101, 102, 97, 127, 87, 96, 95, 132, 104, 98,
-  94, 140, 87, 134, 70, 81, 132, 78, 76, 92,
-  77, 87, 98, 63, 117, 122, 94, 121, 76, 52,
-  114, 92, 66, 118, 123, 82, 114, 71, 144, 89,
-  96, 133, 142, 90, 78, 109, 120, 81, 82, 137,
-  73, 86, 210, 71, 114, 92, 97, 119, 149, 116,
-  98, 113, 100, 117, 86, 132, 115, 111, 85, 110,
-  101, 88, 46, 96, 96, 100, 60, 119, 95, 173,
-  150, 98, 102, 106, 76, 108, 72, 83, 72, 88,
-  87, 99, 116, 100, 101, 73, 103, 87, 66, 132,
-  101, 92, 64, 109, 62, 78, 93, 103, 112, 70,
-  106, 130, 93, 82, 83, 93, 138, 104, 77, 121,
-  109, 106, 103, 53, 142, 108, 122, 86, 75, 122,
-  115, 136, 75, 101, 58, 118, 98, 94, 80, 161,
-  79, 107, 99, 80, 118, 56, 75, 123, 97, 126,
-  119, 142, 170, 96, 135, 126, 116, 105, 102, 96,
-  112, 133, 121, 82, 83, 157, 85, 82, 88, 134,
-  109, 62, 124, 119, 121, 68, 78, 112, 105, 106,
-  100, 55, 132, 77, 123, 97, 111, 128, 77, 84,
-  72, 179, 99, 101, 85, 137, 83, 99, 101, 107,
-  96, 101, 96, 102, 102, 154, 77, 109, 126, 66,
-  77, 77, 77, 47, 108, 83, 120, 155, 92, 110,
-  80, 58, 93, 100, 81, 82, 124, 86, 111, 61,
-  135, 104, 98, 138, 149, 81, 86, 118, 122, 85,
-  95, 148, 77, 85, 200, 64, 105, 90, 92, 117,
-  126, 72, 105, 98, 92, 121, 96, 139, 110, 120,
-  74, 104, 87, 96, 66, 49, 92, 87, 54, 111,
-  96, 136, 143, 97, 138, 102, 67, 130, 105, 84,
-  83, 107, 69, 92, 113, 105, 96, 85, 97, 77,
-  62, 139, 118, 101, 78, 93, 55, 87, 81, 120,
-  106, 105, 134, 106, 90, 90, 111, 100, 147, 155,
-  112, 108, 108, 90, 120, 62, 141, 104, 127, 70,
-  102, 117, 84, 126, 66, 95, 47, 107, 122, 126,
-  77, 165, 87, 82, 73, 82, 95, 62, 58, 126,
-  77, 101, 149, 142, 172, 92, 148, 117, 112, 122,
-  96, 119, 98, 106, 119, 118, 58, 153, 75, 85,
-  99, 135, 118, 59, 111, 106, 113, 90, 73, 125,
-  75, 113, 115, 69, 132, 78, 119, 82, 79, 104,
-  63, 100, 81, 148, 106, 94, 96, 133, 94, 80,
-  93, 106, 94, 88, 87, 86, 95, 131, 47, 102,
-  120, 49, 69, 67, 86, 57, 104, 95, 117, 134,
-  98, 90, 97, 88, 75, 102, 84, 76, 99, 96,
-  113, 54, 106, 105, 101, 134, 127, 80, 103, 100,
-  124, 84, 105, 161, 87, 113, 159, 67, 75, 115,
-  57, 113, 125, 88, 98, 81, 73, 134, 56, 148,
-  99, 92, 87, 109, 78, 84, 81, 115, 78, 122,
-  35, 96, 88, 119, 115, 81, 131, 89, 90, 115,
-  96, 97, 92, 121, 83, 93, 87, 118, 87, 97,
-  75, 42, 57, 141, 127, 100, 71, 99, 53, 77,
-  77, 108, 97, 169, 124, 104, 72, 77, 128, 122,
-  105, 146, 110, 100, 101, 70, 110, 78, 138, 76,
-  111, 90, 103, 129, 77, 119, 60, 81, 94, 119,
-  99, 137, 98, 143, 84, 76, 114, 95, 139, 61,
-  84, 97, 84, 105, 109, 95, 136, 101, 104, 94,
-  132, 105, 86, 128, 83, 92, 118, 106, 63, 145,
-  74, 110, 121, 118, 136, 71, 85, 80, 128, 124,
-  58, 138, 73, 127, 91, 170, 98, 89, 114, 67,
-  89, 62, 86, 137, 98, 127, 102, 77, 90, 136,
-  124, 61, 99, 132, 94, 100, 66, 110, 71, 72,
-  59, 76, 123, 52, 72, 98, 122, 90, 99, 84,
-  108, 96, 93, 82, 90, 80, 86, 109, 79, 113,
-  67, 98, 86, 60, 108, 94, 97, 121, 96, 105,
-  104, 86, 109, 73, 92, 143, 95, 151, 125, 98,
-  151, 137, 49, 121, 165, 110, 101, 97, 79, 143,
-  58, 197, 96, 126, 98, 121, 100, 68, 66, 106,
-  115, 62, 37, 128, 81, 108, 125, 87, 80, 92,
-  83, 121, 53, 105, 124, 148, 102, 133, 94, 119,
-  95, 141, 49, 88, 88, 149, 136, 119, 48, 112,
-  87, 83, 77, 108, 114, 142, 111, 103, 65, 76,
-  66, 99, 61, 106, 102, 113, 116, 112, 106, 96,
-  133, 73, 100, 83, 105, 126, 68, 126, 105, 86,
-  146, 144, 141, 123, 108, 129, 74, 87, 93, 110,
-  122, 69, 104, 100, 87, 107, 86, 57, 93, 132,
-  93, 94, 147, 102, 88, 136, 84, 72, 106, 109,
-  94, 137, 109, 141, 123, 97, 169, 86, 78, 112,
-  151, 59, 50, 145, 167, 119, 134, 99, 142, 72,
-  121, 50, 129, 122, 83, 139, 89, 135, 124, 68,
-  91, 174, 151, 80, 129, 160, 118, 124, 48, 107,
-  44, 83, 173, 101, 163, 90, 116, 76, 98, 94,
-  105, 120, 85, 91, 90, 167, 70, 87, 91, 96,
-  73, 78, 114, 107, 95, 67, 103, 97, 101, 127,
-  104, 123, 86, 112, 75, 100, 95, 101, 116, 108,
-  102, 93, 79, 117, 47, 94, 149, 101, 91, 129,
-  59, 88, 71, 150, 102, 109, 89, 128, 48, 74,
-  53, 68, 107, 125, 36, 80, 96, 77, 90, 65,
-  82, 85, 95, 99, 48, 113, 103, 142, 120, 151,
-  64, 108, 77, 146, 43, 86, 86, 111, 131, 112,
-  17, 85, 83, 108, 66, 91, 112, 86, 80, 79,
-  119, 60, 79, 103, 46, 109, 92, 76, 121, 130,
-  133, 89, 96, 70, 100, 132, 87, 100, 74, 115,
-  96, 98, 104, 96, 95, 98, 92, 98, 54, 96,
-  69, 103, 90, 59, 112, 136, 148, 99, 91, 49,
-  83, 61, 79, 90, 109, 91, 82, 114, 109, 86,
-  101, 108, 49, 111, 85, 155, 116, 67, 110, 96,
-  86, 83, 148, 76, 28, 113, 129, 94, 111, 96,
-  103, 51, 131, 146, 95, 137, 90, 96, 97, 97,
-  95, 55, 110, 152, 136, 111, 88, 153, 84, 96,
-  35, 67, 46, 69, 61, 78, 124, 104, 87, 99,
-  62, 83, 87, 80, 95, 69, 80, 145, 58, 78,
-  95, 138, 99, 90, 95, 100, 139, 82, 103, 140,
-  93, 119, 95, 118, 82, 118, 71, 89, 83, 62,
-  106, 85, 117, 100, 97, 107, 90, 104, 107, 113,
-  96, 119, 75, 80, 108, 107, 90, 71, 95, 140,
-  72, 86, 93, 83, 95, 90, 36, 115, 113, 61,
-  80, 67, 104, 87, 76, 102, 86, 147, 70, 122,
-  116, 114, 83, 98, 99, 136, 71, 65, 117, 117,
-  142, 124, 45, 112, 99, 133, 67, 111, 141, 94,
-  85, 86, 104, 101, 84, 100, 66, 97, 85, 115,
-  98, 112, 101, 87, 81, 119, 125, 107, 75, 99,
-  67, 69, 119, 93, 141, 100, 52, 102, 107, 90,
-  61, 111, 111, 96, 85, 87, 89, 134, 175, 99,
-  105, 102, 92, 104, 88, 130, 95, 114, 78, 41,
-  130, 107, 107, 138, 71, 94, 82, 149, 112, 71,
-  99, 110, 76, 92, 122, 91, 50, 74, 89, 82,
-  103, 100, 113, 85, 142, 152, 88, 81, 135, 112,
-  117, 83, 76, 75, 96, 109, 119, 106, 57, 110,
-  61, 109, 102, 112, 55, 106, 84, 120, 76, 99,
-  97, 131, 106, 76, 75, 84, 112, 75, 88, 123,
-  68, 100, 94, 183, 122, 117, 52, 106, 128, 103,
-  97, 153, 74, 105, 105, 86, 91, 104, 79, 73,
-  91, 58, 124, 107, 131, 106, 128, 127, 135, 134,
-  117, 117, 121, 107, 106, 104, 150, 110, 112, 100,
-  94, 133, 101, 101, 135, 59, 105, 84, 40, 159,
-  128, 86, 103, 83, 146, 87, 76, 97, 141, 141,
-  82, 122, 106, 74, 100, 112, 125, 125, 95, 115,
-  118, 156, 143, 149, 106, 96, 102, 138, 86, 138,
-  122, 92, 103, 107, 118, 135, 99, 83, 110, 122,
-  113, 109, 97, 110, 90, 106, 101, 157, 140, 72,
-  103, 104, 76, 85, 133, 97, 129, 120, 92, 116,
-  122, 103, 92, 99, 96, 92, 93, 118, 104, 111,
-  152, 122, 138, 143, 129, 140, 114, 123, 118, 128,
-  105, 83, 130, 113, 137, 152, 66, 92, 121, 124,
-  108, 99, 102, 115, 80, 108, 88, 100, 75, 63,
-  76, 94, 123, 69, 143, 127, 119, 97, 111, 111,
-  153, 136, 122, 93, 94, 107, 96, 100, 103, 111,
-  83, 75, 97, 115, 151, 139, 88, 140, 71, 162,
-  89, 97, 124, 103, 122, 88, 103, 117, 110, 57,
-  108, 106, 89, 137, 80, 143, 116, 85, 77, 84,
-  110, 129, 101, 117, 81, 116, 94, 89, 68, 79,
-  102, 111, 100, 96, 155, 105, 125, 111, 94, 132,
-  140, 140, 124, 112, 129, 120, 120, 117, 142, 112,
-  114, 98, 106, 120, 112, 100, 142, 108, 152, 94,
-  67, 158, 166, 114, 112, 106, 149, 96, 81, 95,
-  129, 152, 97, 130, 119, 92, 127, 125, 137, 112,
-  105, 113, 106, 132, 131, 150, 126, 85, 112, 135,
-  130, 119, 132, 116, 108, 126, 107, 124, 103, 115,
-  133, 128, 128, 109, 115, 116, 72, 120, 101, 147,
-  133, 120, 176, 120, 121, 148, 133, 92, 122, 97,
-  123, 109, 141, 126, 108, 110, 94, 141, 105, 142,
-  116, 93, 140, 131, 123, 140, 148, 127, 107, 129,
-  125, 103, 126, 166, 130, 141, 148, 109, 89, 99,
-  121, 106, 114, 122, 107, 119, 88, 119, 108, 121,
-  92, 115, 102, 116, 127, 116, 120, 134, 112, 88,
-  140, 129, 141, 127, 120, 111, 109, 109, 109, 111,
-  109, 106, 99, 79, 110, 138, 120, 110, 124, 141,
-  80, 153, 95, 105, 122, 105, 134, 90, 122, 129,
-  102, 72, 119, 101, 98, 149, 96, 114, 113, 118,
-  104, 71, 103, 120, 138, 138, 78, 117, 110, 103,
-  77, 101, 111, 111, 103, 111, 165, 115, 141, 110,
-  84, 149, 93, 96, 118, 107, 90, 151, 104, 150,
-  129, 122, 136, 128, 95, 150, 112, 127, 92, 126,
-  132, 75, 82, 121, 176, 127, 132, 101, 122, 68,
-  133, 93, 79, 125, 90, 106, 130, 109, 121, 145,
-  131, 104, 77, 114, 113, 108, 117, 137, 111, 101,
-  110, 144, 114, 106, 137, 126, 98, 143, 101, 119,
-  101, 127, 108, 95, 94, 117, 120, 106, 122, 107,
-  120, 98, 121, 119, 134, 159, 119, 155, 119, 88,
-  101, 109, 106, 108, 129, 137, 96, 121, 121, 120,
-  103, 104, 99, 124, 102, 135, 101, 101, 141, 94,
-  123, 158, 124, 103, 120, 170, 117, 148, 140, 97,
-  100, 112, 99, 126, 113, 157, 102, 119, 129, 162,
-  141, 115, 94, 101, 123, 141, 110, 126, 103, 89,
-  101, 124, 122, 93, 109, 137, 90, 158, 112, 88,
-  109, 153, 163, 108, 114, 146, 104, 113, 61, 143,
-  126, 146, 103, 89, 122, 106, 111, 104, 107, 127,
-  149, 109, 114, 101, 115, 134, 93, 85, 127, 86,
-  108, 112, 109, 134, 107, 70, 154, 157, 99, 101,
-  139, 138, 110, 115, 139, 97, 77, 137, 129, 108,
-  165, 104, 133, 135, 89, 89, 113, 135, 89, 89,
-  94, 156, 128, 127, 129, 132, 96, 149, 101, 121,
-  125, 123, 110, 80, 61, 124, 85, 111, 147, 101,
-  130, 126, 124, 79, 92, 119, 75, 117, 165, 99,
-  114, 109, 121, 98, 71, 79, 105, 146, 69, 136,
-  121, 191, 102, 132, 95, 123, 134, 115, 76, 145,
-  97, 124, 86, 113, 112, 94, 99, 117, 102, 95,
-  97, 105, 135, 85, 133, 102, 74, 175, 79, 123,
-  98, 94, 98, 116, 99, 129, 127, 144, 96, 109,
-  107, 103, 101, 70, 115, 156, 117, 135, 98, 90,
-  169, 92, 147, 160, 168, 113, 110, 118, 91, 220,
-  150, 99, 100, 116, 90, 128, 107, 183, 101, 125,
-  128, 165, 109, 125, 84, 105, 101, 129, 96, 117,
-  146, 75, 101, 107, 117, 99, 108, 141, 80, 177,
-  100, 110, 124, 147, 153, 91, 119, 152, 103, 109,
-  99, 160, 123, 157, 97, 73, 117, 89, 84, 112,
-  135, 121, 131, 90, 124, 157, 130, 125, 77, 63,
-  124, 145, 93, 141, 109, 130, 92, 78, 134, 122,
-  100, 95, 133, 120, 112, 106, 151, 94, 82, 145,
-  87, 114, 164, 95, 117, 120, 96, 102, 124, 121,
-  94, 96, 95, 126, 118, 141, 119, 134, 106, 122,
-  110, 90, 106, 88, 113, 110, 52, 122, 38, 107,
-  156, 96, 117, 114, 99, 75, 98, 112, 60, 137,
-  131, 91, 93, 110, 107, 126, 74, 117, 87, 173,
-  96, 132, 124, 156, 85, 80, 84, 126, 108, 93,
-  77, 98, 89, 104, 111, 92, 100, 90, 99, 114,
-  120, 115, 101, 82, 122, 88, 132, 77, 80, 142,
-  59, 111, 103, 93, 135, 79, 124, 131, 93, 152,
-  98, 101, 90, 116, 108, 80, 112, 135, 111, 113,
-  107, 79, 156, 138, 144, 134, 162, 107, 108, 167,
-  84, 120, 114, 122, 82, 93, 86, 108, 98, 144,
-  103, 100, 120, 154, 117, 79, 54, 95, 94, 102,
-  114, 91, 175, 83, 92, 93, 117, 155, 97, 121,
-  75, 163, 100, 110, 119, 148, 126, 87, 117, 141,
-  94, 102, 59, 114, 100, 146, 101, 87, 129, 90,
-  72, 114, 106, 105, 89, 106, 99, 141, 143, 126,
-  84, 75, 107, 137, 66, 101, 125, 102, 94, 84,
-  106, 95, 94, 118, 119, 99, 105, 85, 107, 93,
-  80, 136, 80, 104, 166, 69, 96, 106, 81, 93,
-  115, 144, 81, 91, 82, 89, 79, 79, 87, 92,
-  112, 116, 119, 90, 93, 120, 115, 125, 33, 77,
-  33, 92, 142, 82, 128, 98, 122, 59, 92, 112,
-  62, 111, 114, 112, 71, 96, 97, 65, 91, 66,
-  61, 156, 101, 104, 93, 120, 72, 95, 87, 103,
-  95, 89, 75, 110, 102, 56, 118, 117, 72, 75,
-  77, 105, 102, 84, 63, 83, 81, 84, 102, 149,
-  89, 116, 70, 118, 93, 88, 127, 81, 85, 70,
-  94, 135, 64, 93, 106, 103, 87, 79, 106, 109,
-  117, 106, 81, 55, 119, 114, 108, 100, 137, 78,
-  72, 143, 88, 117, 123, 85, 66, 100, 62, 99,
-  103, 128, 93, 88, 106, 127, 119, 89, 45, 96,
-  85, 103, 72, 104, 90, 96, 103, 103, 121, 143,
-  84, 113, 104, 154, 77, 92, 107, 128, 108, 76,
-  90, 109, 82, 95, 33, 92, 78, 95, 63, 65,
-  92, 75, 38, 123, 71, 102, 89, 81, 111, 112,
-  125, 96, 93, 74, 92, 133, 81, 113, 92, 80,
-  93, 91, 149, 88, 83, 132, 95, 88, 89, 66,
-  56, 77, 89, 112, 71, 82, 183, 87, 119, 89,
-  131, 110, 121, 161, 80, 83, 87, 96, 90, 82,
-  107, 79, 99, 111, 123, 114, 97, 100, 109, 85,
-  42, 78, 62, 99, 161, 91, 136, 105, 124, 92,
-  117, 93, 85, 76, 85, 99, 103, 104, 123, 36,
-  116, 70, 61, 154, 105, 99, 95, 152, 67, 98,
-  86, 99, 110, 94, 89, 92, 106, 72, 122, 107,
-  114, 109, 86, 110, 102, 93, 103, 80, 96, 93,
-  117, 104, 105, 115, 99, 100, 89, 94, 91, 98,
-  64, 87, 86, 147, 72, 89, 121, 69, 94, 85,
-  73, 135, 121, 118, 103, 88, 154, 114, 135, 115,
-  124, 91, 98, 58, 89, 110, 118, 87, 67, 106,
-  66, 87, 92, 132, 119, 93, 93, 136, 118, 77,
-  69, 90, 93, 94, 106, 88, 118, 103, 92, 85,
-  115, 94, 118, 112, 116, 140, 86, 126, 110, 118,
-  94, 98, 97, 94, 104, 102, 101, 114, 102, 127,
-  52, 119, 115, 80, 47, 89, 60, 76, 85, 94,
-  100, 118, 120, 93, 109, 112, 100, 108, 77, 107,
-  108, 82, 97, 88, 116, 84, 79, 155, 97, 80,
-  88, 71, 75, 74, 111, 125, 72, 78, 167, 87,
-  77, 93, 142, 132, 120, 145, 113, 105, 87, 107,
-  95, 86, 113, 77, 97, 112, 118, 109, 95, 87,
-  101, 95, 52, 104, 65, 124, 161, 99, 123, 87,
-  118, 94, 86, 68, 90, 75, 78, 94, 101, 108,
-  136, 43, 151, 76, 62, 168, 121, 112, 85, 136,
-  58, 87, 80, 92, 109, 89, 85, 101, 102, 69,
-  130, 104, 162, 120, 97, 107, 100, 83, 101, 71,
-  115, 98, 132, 78, 104, 108, 105, 101, 85, 105,
-  49, 93, 67, 118, 82, 165, 94, 82, 101, 86,
-  102, 86, 77, 114, 87, 126, 102, 119, 186, 101,
-  143, 128, 133, 83, 121, 88, 97, 102, 122, 99,
-  71, 110, 72, 73, 75, 126, 121, 83, 105, 142,
-  125, 76, 103, 100, 93, 89, 97, 94, 116, 87,
-  97, 73, 104, 94, 126, 101, 123, 112, 97, 118,
-  118, 116, 107, 105, 102, 78, 113, 82, 126, 123,
-  123, 152, 50, 122, 120, 77, 46, 66, 66, 90,
-  87, 92, 92, 115, 108, 83, 113, 104, 107, 87,
-  61, 88, 118, 95, 96, 72, 116, 78, 77, 129,
-  104, 84, 105, 74, 99, 77, 123, 146, 102, 110,
-  133, 91, 95, 101, 133, 129, 119, 117, 122, 111,
-  92, 111, 107, 121, 105, 99, 102, 109, 111, 100,
-  90, 79, 102, 90, 68, 135, 71, 118, 147, 109,
-  117, 78, 98, 90, 82, 55, 90, 88, 62, 103,
-  108, 109, 128, 50, 143, 86, 70, 156, 127, 115,
-  83, 124, 63, 92, 70, 95, 106, 68, 104, 109,
-  100, 84, 109, 102, 154, 132, 102, 113, 93, 86,
-  88, 57, 136, 106, 141, 79, 110, 107, 123, 106,
-  85, 116, 43, 91, 90, 135, 85, 161, 104, 89,
-  92, 109, 90, 90, 77, 82, 64, 112, 108, 139,
-  171, 95, 132, 131, 129, 100, 120, 109, 117, 109,
-  114, 91, 92, 110, 96, 73, 73, 119, 134, 76,
-  101, 129, 130, 72, 107, 94, 111, 97, 88, 71,
-  117, 71, 84, 66, 92, 95, 127, 94, 106, 91,
-  125, 113, 112, 129, 116, 109, 101, 84, 121, 85,
-  121, 131, 119, 153, 46, 115, 129, 71, 67, 65,
-  102, 89, 92, 108, 92, 108, 88, 87, 103, 97,
-  97, 91, 64, 69, 117, 103, 92, 77, 99, 92,
-  90, 92, 105, 86, 96, 81, 103, 82, 114, 152,
-  109, 111, 100, 83, 95, 103, 113, 108, 133, 98,
-  117, 123, 90, 91, 110, 133, 124, 98, 91, 110,
-  106, 89, 81, 61, 89, 109, 66, 129, 67, 103,
-  120, 103, 106, 85, 79, 92, 59, 61, 77, 111,
-  74, 106, 98, 116, 125, 58, 109, 105, 92, 110,
-  121, 126, 79, 111, 81, 115, 59, 102, 107, 88,
-  133, 126, 101, 109, 128, 111, 107, 116, 103, 116,
-  97, 101, 90, 46, 162, 101, 142, 97, 90, 98,
-  151, 116, 92, 124, 67, 86, 94, 111, 104, 138,
-  97, 96, 81, 143, 79, 107, 70, 84, 74, 90,
-  109, 148, 130, 91, 109, 132, 119, 115, 118, 126,
-  154, 121, 118, 92, 107, 106, 99, 93, 98, 108,
-  121, 78, 104, 99, 147, 71, 98, 92, 121, 114,
-  88, 73, 115, 77, 110, 96, 89, 117, 120, 102,
-  85, 59, 152, 129, 98, 146, 119, 124, 84, 88,
-  100, 94, 104, 111, 102, 140, 83, 94, 111, 78,
-  86, 84, 131, 88, 91, 107, 98, 113, 80, 111,
-  90, 100, 87, 103, 75, 70, 91, 104, 103, 86,
-  103, 130, 101, 70, 116, 91, 83, 104, 93, 102,
-  94, 143, 113, 128, 93, 92, 108, 105, 104, 85,
-  103, 105, 107, 113, 111, 82, 128, 111, 135, 98,
-  81, 114, 116, 98, 94, 59, 108, 103, 66, 99,
-  95, 92, 93, 100, 118, 135, 92, 92, 58, 94,
-  99, 113, 117, 118, 104, 115, 135, 67, 103, 105,
-  128, 71, 112, 113, 89, 103, 82, 145, 67, 121,
-  97, 114, 134, 122, 112, 129, 113, 110, 76, 93,
-  106, 134, 99, 114, 95, 68, 165, 98, 126, 121,
-  61, 116, 123, 102, 103, 129, 78, 84, 87, 73,
-  106, 99, 89, 95, 110, 130, 87, 127, 63, 101,
-  98, 89, 112, 145, 96, 98, 85, 133, 102, 129,
-  119, 92, 143, 137, 118, 89, 107, 116, 102, 113,
-  109, 102, 98, 105, 106, 75, 121, 116, 105, 95,
-  137, 124, 84, 89, 88, 108, 152, 109, 80, 119,
-  105, 104, 86, 57, 128, 126, 96, 124, 123, 117,
-  79, 86, 110, 105, 108, 107, 82, 120, 109, 92,
-  73, 100, 91, 127, 92, 109, 110, 95, 125, 120,
-  99, 116, 88, 112, 87, 109, 87, 80, 66, 132,
-  120, 103, 100, 138, 105, 60, 129, 103, 89, 98,
-  88, 97, 84, 112, 131, 140, 105, 114, 84, 109,
-  123, 103, 93, 107, 106, 94, 128, 83, 147, 94,
-  140, 113, 79, 117, 119, 120, 104, 54, 116, 102,
-  62, 104, 88, 90, 95, 94, 141, 140, 119, 91,
-  84, 105, 118, 103, 113, 108, 108, 113, 142, 84,
-  118, 114, 153, 78, 108, 114, 112, 111, 77, 156,
-  89, 164, 89, 121, 123, 114, 134, 138, 107, 108,
-  79, 91, 112, 122, 98, 128, 108, 87, 151, 110,
-  112, 116, 62, 129, 79, 77, 118, 144, 60, 103,
-  94, 88, 89, 92, 86, 85, 136, 103, 103, 135,
-  69, 129, 126, 96, 117, 132, 105, 86, 102, 132,
-  107, 118, 128, 75, 124, 95, 114, 125, 84, 124,
-  110, 122, 100, 106, 88, 128, 110, 83, 104, 133,
-  109, 80, 115, 106, 102, 94, 74, 131, 135, 126,
-  88, 88, 109, 103, 105, 63, 93, 127, 94, 105,
-  111, 120, 97, 82, 121, 120, 125, 123, 77, 113,
-  71, 110, 71, 107, 98, 131, 68, 117, 126, 89,
-  125, 120, 114, 103, 101, 132, 86, 107, 72, 84,
-  82, 125, 135, 113, 91, 122, 100, 87, 124, 105,
-  93, 78, 101, 99, 86, 99, 108, 120, 114, 119,
-  108, 116, 141, 137, 83, 120, 112, 92, 143, 95,
-  148, 105, 137, 122, 88, 117, 131, 129, 117, 72,
-  127, 95, 63, 124, 79, 105, 111, 80, 143, 101,
-  123, 89, 108, 109, 125, 103, 84, 86, 108, 105,
-  142, 81, 143, 117, 149, 107, 109, 117, 121, 110,
-  71, 134, 111, 179, 101, 115, 104, 124, 128, 128,
-  98, 110, 107, 94, 116, 115, 92, 127, 97, 103,
-  134, 127, 103, 101, 74, 117, 74, 72, 133, 155,
-  63, 108, 98, 95, 79, 106, 90, 85, 138, 101,
-  104, 127, 76, 140, 114, 88, 120, 115, 132, 80,
-  128, 133, 124, 92, 138, 82, 121, 86, 116, 145,
-  97, 135, 122, 116, 82, 113, 94, 126, 112, 119,
-  100, 117, 104, 77, 107, 89, 116, 98, 88, 139,
-  106, 113, 94, 88, 105, 105, 119, 83, 76, 128,
-  100, 101, 105, 121, 108, 79, 144, 134, 130, 146,
-  84, 131, 73, 135, 85, 104, 99, 120, 80, 122,
-  106, 94, 119, 107, 120, 101, 110, 135, 89, 100,
-  58, 86, 116, 106, 127, 126, 87, 104, 91, 109,
-  116, 92, 98, 63, 98, 104, 99, 92, 99, 109,
-  125, 121, 93, 109, 139, 166, 89, 124, 113, 82,
-  141, 102, 153, 136, 129, 113, 92, 111, 118, 138,
-  114, 72, 127, 106, 58, 136, 75, 131, 124, 76,
-  155, 91, 123, 89, 132, 103, 122, 111, 68, 86,
-  110, 113, 129, 71, 154, 125, 144, 125, 102, 117,
-  124, 99, 52, 104, 115, 187, 96, 118, 96, 135,
-  126, 124, 105, 117, 133, 114, 121, 104, 93, 120,
-  72, 115, 120, 123, 106, 104, 93, 112, 79, 76,
-  129, 156, 57, 103, 111, 94, 82, 131, 94, 87,
-  119, 111, 95, 123, 71, 133, 104, 95, 123, 98,
-  142, 86, 149, 116, 128, 84, 139, 93, 101, 99,
-  114, 146, 98, 128, 127, 108, 69, 115, 103, 98,
-  104, 145, 99, 109, 88, 78, 87, 96, 130, 90,
-  82, 130, 86, 88, 94, 104, 92, 100, 127, 91,
-  83, 125, 108, 107, 105, 115, 119, 90, 148, 132,
-  144, 141, 96, 138, 43, 145, 103, 95, 95, 129,
-  81, 125, 95, 111, 112, 100, 122, 83, 119, 130,
-  83, 96, 58, 81, 148, 90, 109, 127, 93, 96,
-  87, 139, 100, 93, 101, 53, 90, 102, 107, 90,
-  88, 106, 128, 126, 103, 98, 135, 165, 102, 96,
-  109, 74, 122, 104, 153, 164, 137, 122, 110, 101,
-  99, 141, 118, 58, 113, 99, 49, 145, 61, 139,
-  110, 81, 166, 103, 127, 90, 143, 92, 120, 108,
-  67, 75, 109, 104, 108, 76, 142, 151, 143, 111,
-  107, 117, 116, 102, 62, 69, 109, 201, 93, 117,
-  104, 149, 110, 126, 97, 108, 130, 144, 129, 99,
-  104, 122, 66, 113, 111, 115, 113, 108, 108, 101,
-  110, 74, 129, 152, 42, 101, 138, 118, 83, 150,
-  95, 91, 112, 109, 86, 108, 80, 126, 116, 104,
-  121, 88, 135, 84, 154, 115, 121, 98, 125, 114,
-  106, 111, 109, 138, 96, 122, 124, 107, 74, 124,
-  107, 74, 101, 150, 106, 116, 60, 85, 74, 104,
-  153, 79, 92, 111, 77, 70, 78, 86, 82, 97,
-  122, 80, 101, 129, 114, 104, 102, 117, 109, 125,
-  146, 125, 137, 147, 102, 142, 40, 148, 117, 89,
-  92, 121, 93, 108, 106, 123, 99, 107, 126, 71,
-  123, 116, 67, 108, 62, 79, 158, 70, 96, 132,
-  99, 95, 92, 155, 89, 99, 101, 65, 90, 92,
-  110, 88, 76, 108, 122, 124, 101, 88, 119, 148,
-  99, 74, 88, 68, 100, 92, 141, 166, 131, 127,
-  119, 91, 77, 117, 118, 50, 79, 95, 38, 151,
-  63, 131, 85, 70, 143, 121, 111, 85, 133, 92,
-  105, 103, 86, 58, 95, 81, 102, 108, 124, 155,
-  124, 96, 102, 128, 106, 96, 81, 60, 93, 213,
-  106, 113, 128, 155, 85, 123, 85, 94, 93, 145,
-  140, 100, 124, 134, 67, 91, 94, 118, 107, 108,
-  106, 102, 134, 69, 136, 132, 73, 103, 146, 113,
-  94, 152, 95, 93, 104, 107, 99, 94, 108, 134,
-  114, 95, 136, 87, 113, 91, 138, 117, 102, 95,
-  98, 130, 114, 109, 114, 134, 105, 109, 119, 105,
-  88, 121, 100, 80, 99, 124, 115, 136, 45, 105,
-  57, 109, 169, 108, 96, 79, 65, 62, 75, 84,
-  80, 106, 106, 58, 83, 129, 126, 109, 104, 138,
-  82, 156, 122, 118, 111, 124, 94, 125, 64, 152,
-  99, 93, 107, 99, 114, 84, 111, 116, 98, 101,
-  120, 89, 97, 97, 57, 113, 65, 54, 126, 54,
-  97, 144, 87, 105, 92, 150, 87, 102, 102, 88,
-  90, 84, 99, 85, 64, 110, 121, 105, 114, 81,
-  93, 121, 64, 83, 53, 67, 105, 75, 139, 139,
-  105, 128, 119, 103, 48, 86, 95, 77, 75, 103,
-  31, 115, 89, 110, 69, 47, 108, 98, 89, 77,
-  109, 108, 88, 100, 104, 59, 81, 57, 98, 130,
-  99, 129, 110, 106, 93, 124, 85, 89, 75, 52,
-  87, 166, 110, 108, 112, 124, 88, 103, 71, 95,
-  49, 120, 144, 101, 132, 157, 79, 58, 77, 114,
-  90, 92, 90, 100, 116, 83, 127, 103, 106, 108,
-  132, 88, 105, 121, 82, 98, 94, 100, 130, 81,
-  131, 135, 99, 82, 139, 70, 94, 105, 110, 111,
-  77, 77, 67, 119, 110, 88, 116, 125, 102, 97,
-  106, 115, 92, 101, 81, 102, 97, 85, 111, 142,
-  27, 124, 62, 105, 153, 143, 106, 57, 69, 78,
-  92, 95, 77, 88, 86, 60, 48, 106, 126, 109,
-  109, 141, 49, 158, 98, 114, 85, 104, 69, 94,
-  93, 138, 69, 100, 125, 92, 113, 87, 87, 102,
-  106, 98, 104, 118, 64, 93, 85, 107, 65, 46,
-  83, 58, 115, 136, 81, 101, 83, 135, 94, 75,
-  89, 104, 92, 63, 86, 61, 41, 99, 131, 91,
-  101, 70, 67, 96, 57, 117, 36, 84, 118, 68,
-  132, 106, 96, 128, 115, 125, 36, 72, 66, 116,
-  74, 146, 19, 76, 107, 88, 92, 39, 78, 70,
-  115, 83, 83, 114, 77, 89, 102, 68, 86, 51,
-  105, 113, 84, 98, 94, 115, 98, 125, 47, 92,
-  85, 22, 88, 107, 108, 80, 82, 89, 90, 69,
-  54, 87, 46, 83, 104, 88, 123, 163, 88, 43,
-  73, 114, 91, 66, 76, 82, 101, 112, 111, 85,
-  115, 130, 107, 91, 101, 101, 57, 115, 103, 98,
-  153, 69, 120, 127, 109, 75, 109, 53, 104, 121,
-  105, 97, 56, 49, 56, 119, 107, 105, 114, 101,
-  85, 82, 76, 114, 100, 92, 89, 108, 107, 81,
-  124, 120, 25, 122, 90, 94, 125, 130, 126, 45,
-  66, 79, 109, 123, 67, 81, 81, 81, 36, 96,
-  105, 120, 118, 125, 33, 129, 67, 111, 60, 102,
-  57, 88, 95, 121, 64, 104, 103, 82, 93, 93,
-  80, 109, 102, 111, 95, 131, 49, 96, 115, 89,
-  82, 56, 84, 75, 136, 121, 75, 85, 74, 115,
-  100, 60, 77, 122, 73, 53, 89, 52, 34, 70,
-  154, 73, 95, 61, 68, 93, 88, 112, 43, 106,
-  87, 94, 76, 90, 105, 101, 139, 117, 37, 75,
-  52, 136, 77, 140, 22, 65, 88, 89, 147, 57,
-  89, 71, 105, 91, 79, 111, 71, 62, 83, 81,
-  90, 76, 113, 90, 70, 72, 79, 126, 100, 118,
-  32, 104, 73, 28, 83, 66, 100, 80, 87, 89,
-  83, 56, 61, 80, 70, 84, 69, 92, 112, 128,
-  103, 59, 88, 117, 112, 87, 95, 91, 79, 140,
-  98, 80, 87, 144, 56, 122, 86, 130, 35, 143,
-  114, 88, 141, 58, 82, 144, 130, 87, 79, 49,
-  131, 94, 125, 97, 65, 28, 66, 131, 94, 123,
-  111, 72, 65, 96, 57, 97, 112, 108, 137, 94,
-  112, 110, 143, 108, 25, 103, 110, 91, 89, 105,
-  118, 52, 72, 79, 116, 103, 61, 96, 94, 119,
-  53, 118, 110, 153, 112, 98, 39, 121, 62, 104,
-  57, 116, 69, 96, 75, 105, 107, 83, 55, 98,
-  98, 74, 81, 117, 85, 124, 86, 93, 60, 103,
-  121, 87, 102, 59, 96, 77, 117, 92, 113, 85,
-  85, 111, 88, 75, 94, 123, 78, 64, 103, 75,
-  59, 68, 186, 64, 133, 78, 79, 114, 102, 108,
-  81, 105, 72, 124, 64, 90, 77, 88, 134, 92,
-  72, 86, 66, 121, 104, 58, 42, 84, 53, 115,
-  188, 88, 104, 83, 84, 87, 82, 112, 72, 70,
-  77, 76, 107, 93, 121, 68, 75, 67, 75, 163,
-  95, 121, 64, 152, 61, 70, 79, 79, 106, 132,
-  105, 117, 85, 55, 95, 103, 101, 98, 86, 117,
-  99, 93, 99, 68, 109, 115, 125, 90, 104, 119,
-  70, 134, 87, 73, 73, 124, 50, 121, 73, 172,
-  36, 143, 87, 79, 93, 54, 51, 130, 127, 97,
-  79, 64, 156, 101, 139, 105, 116, 45, 77, 107,
-  83, 90, 113, 79, 60, 128, 63, 77, 113, 121,
-  182, 83, 111, 146, 133, 95, 48, 104, 98, 107,
-  78, 89, 141, 67, 99, 90, 126, 87, 72, 108,
-  105, 177, 98, 119, 119, 168, 103, 74, 83, 131,
-  95, 90, 80, 113, 74, 116, 84, 86, 132, 54,
-  50, 87, 119, 82, 85, 102, 89, 130, 77, 85,
-  82, 96, 129, 110, 96, 100, 98, 85, 92, 75,
-  129, 100, 91, 120, 89, 84, 104, 107, 116, 85,
-  118, 118, 55, 98, 183, 62, 128, 104, 83, 123,
-  118, 130, 95, 123, 70, 135, 111, 110, 76, 98,
-  110, 103, 88, 100, 93, 82, 93, 72, 55, 95,
-  46, 140, 184, 85, 98, 110, 97, 74, 91, 117,
-  65, 104, 81, 69, 109, 97, 123, 78, 79, 99,
-  79, 184, 88, 116, 97, 149, 46, 72, 81, 108,
-  114, 117, 82, 122, 94, 67, 127, 118, 103, 80,
-  106, 114, 107, 100, 105, 82, 136, 97, 125, 82,
-  84, 126, 138, 127, 87, 76, 86, 97, 84, 103,
-  67, 163, 57, 94, 85, 93, 86, 67, 60, 94,
-  109, 96, 94, 82, 179, 123, 149, 122, 149, 93,
-  96, 108, 78, 99, 113, 111, 69, 145, 72, 80,
-  95, 130, 148, 81, 112, 160, 122, 80, 63, 140,
-  71, 126, 78, 94, 177, 68, 115, 104, 131, 133,
-  91, 114, 97, 203, 146, 113, 119, 161, 102, 85,
-  110, 145, 112, 92, 103, 117, 81, 128, 88, 75,
-  136, 69, 65, 89, 119, 119, 97, 83, 111, 125,
-  84, 113, 82, 68, 130, 104, 73, 136, 107, 93,
-  101, 60, 110, 98, 89, 114, 117, 98, 95, 106,
-  152, 95, 107, 141, 54, 102, 157, 55, 126, 114,
-  72, 98, 123, 124, 93, 141, 76, 120, 114, 109,
-  97, 99, 92, 126, 88, 109, 88, 98, 74, 101,
-  59, 95, 92, 161, 156, 80, 94, 135, 110, 68,
-  84, 125, 67, 104, 105, 85, 95, 89, 113, 75,
-  81, 109, 94, 152, 90, 111, 96, 91, 62, 62,
-  83, 112, 93, 76, 78, 146, 104, 77, 101, 106,
-  87, 59, 97, 113, 112, 105, 111, 82, 135, 88,
-  126, 104, 45, 140, 174, 165, 91, 86, 79, 98,
-  111, 108, 80, 141, 57, 83, 108, 92, 121, 56,
-  85, 97, 100, 122, 89, 91, 162, 73, 133, 128,
-  144, 114, 96, 137, 66, 142, 121, 128, 75, 157,
-  74, 80, 81, 158, 113, 72, 120, 137, 137, 98,
-  67, 156, 89, 121, 70, 117, 134, 69, 130, 105,
-  112, 155, 96, 126, 67, 191, 127, 88, 133, 151,
-  103, 92, 96, 151, 113, 94, 85, 121, 82, 134,
-  79, 78, 134, 90, 71, 107, 92, 126, 109, 68,
-  128, 117, 95, 117, 71, 39, 131, 88, 76, 107,
-  103, 113, 119, 56, 151, 86, 101, 92, 163, 99,
-  103, 109, 155, 87, 80, 125, 82, 93, 162, 52,
-  101, 103, 71, 82, 133, 139, 85, 97, 78, 114,
-  92, 114, 109, 86, 90, 112, 96, 99, 57, 127,
-  76, 127, 50, 118, 101, 152, 162, 85, 97, 120,
-  111, 77, 67, 113, 61, 84, 122, 107, 102, 93,
-  108, 78, 86, 84, 83, 135, 92, 106, 70, 122,
-  80, 76, 84, 101, 106, 80, 93, 163, 95, 68,
-  67, 99, 102, 56, 67, 110, 107, 97, 99, 67,
-  136, 100, 129, 97, 57, 132, 105, 162, 88, 94,
-  77, 126, 94, 91, 91, 141, 59, 105, 93, 86,
-  147, 43, 89, 145, 84, 120, 87, 88, 152, 84,
-  117, 124, 140, 103, 86, 101, 91, 155, 125, 102,
-  88, 153, 71, 79, 89, 154, 133, 66, 126, 125,
-  151, 82, 79, 119, 104, 100, 69, 111, 127, 78,
-  128, 81, 112, 136, 81, 112, 59, 173, 77, 82,
-  103, 152, 96, 95, 96, 125, 85, 93, 85, 118,
-  95, 148, 85, 84, 137, 79, 59, 98, 84, 96,
-  103, 78, 128, 143, 102, 131, 69, 37, 131, 103,
-  92, 102, 99, 112, 109, 48, 159, 76, 103, 92,
-  159, 83, 110, 108, 144, 73, 76, 125, 96, 63,
-  185, 69, 118, 95, 91, 110, 138, 101, 105, 80,
-  93, 132, 85, 151, 117, 102, 113, 77, 82, 92,
-  77, 78, 89, 85, 47, 128, 97, 131, 172, 100,
-  131, 101, 82, 113, 80, 95, 93, 100, 82, 104,
-  128, 103, 101, 86, 83, 86, 56, 142, 93, 96,
-  66, 122, 66, 82, 65, 83, 101, 69, 148, 130,
-  76, 69, 100, 85, 160, 139, 87, 118, 109, 89,
-  107, 54, 140, 107, 136, 71, 106, 112, 74, 130,
-  78, 102, 44, 120, 101, 127, 99, 163, 69, 105,
-  68, 93, 118, 47, 69, 148, 63, 92, 116, 108,
-  173, 99, 135, 123, 135, 109, 84, 107, 99, 117,
-  120, 92, 79, 142, 77, 75, 112, 137, 174, 56,
-  115, 111, 145, 74, 79, 100, 108, 93, 111, 55,
-  155, 78, 106, 54, 102, 106, 62, 106, 71, 163,
-  101, 99, 91, 155, 92, 89, 119, 123, 93, 75,
-  94, 107, 108, 157, 59, 118, 174, 43, 55, 84,
-  77, 56, 105, 94, 92, 164, 110, 95, 96, 67,
-  95, 97, 101, 70, 101, 102, 89, 33, 112, 88,
-  105, 127, 115, 81, 107, 85, 133, 62, 99, 143,
-  102, 81, 159, 82, 94, 86, 62, 118, 139, 78,
-  109, 109, 72, 121, 72, 157, 104, 89, 135, 83,
-  68, 86, 76, 56, 84, 92, 36, 106, 81, 95,
-  143, 84, 135, 101, 81, 113, 88, 84, 107, 112,
-  80, 105, 96, 97, 85, 96, 73, 56, 34, 119,
-  79, 79, 63, 87, 53, 81, 70, 85, 78, 135,
-  167, 118, 69, 51, 134, 109, 124, 166, 117, 115,
-  111, 79, 102, 62, 132, 78, 120, 86, 115, 85,
-  97, 106, 68, 94, 59, 107, 91, 135, 108, 144,
-  56, 75, 75, 104, 98, 39, 75, 97, 75, 70,
-  121, 97, 137, 103, 108, 107, 120, 92, 80, 127,
-  95, 82, 121, 107, 101, 131, 71, 97, 140, 106,
-  171, 61, 98, 80, 157, 91, 72, 113, 78, 122,
-  112, 114, 121, 75, 95, 89, 77, 76, 69, 100,
-  101, 126, 122, 80, 98, 153, 96, 79, 120, 144,
-  78, 76, 64, 88, 79, 103, 50, 103, 159, 37,
-  50, 85, 105, 42, 107, 79, 99, 106, 90, 100,
-  102, 66, 68, 96, 97, 82, 59, 89, 71, 36,
-  87, 125, 116, 132, 76, 100, 108, 71, 103, 62,
-  100, 131, 108, 135, 110, 110, 90, 113, 25, 96,
-  150, 92, 99, 134, 51, 118, 54, 152, 84, 93,
-  135, 129, 73, 81, 79, 73, 70, 83, 33, 99,
-  93, 69, 99, 73, 80, 109, 57, 118, 57, 98,
-  105, 142, 95, 127, 99, 100, 87, 132, 45, 77,
-  80, 110, 92, 78, 40, 94, 81, 102, 66, 88,
-  116, 166, 120, 104, 65, 68, 85, 109, 59, 107,
-  92, 94, 110, 98, 111, 91, 119, 72, 107, 89,
-  86, 100, 76, 109, 92, 92, 117, 138, 87, 111,
-  122, 119, 54, 75, 96, 99, 110, 62, 97, 84,
-  102, 78, 108, 68, 86, 96, 91, 99, 126, 90,
-  68, 123, 104, 74, 104, 95, 89, 123, 88, 160,
-  128, 89, 137, 83, 83, 91, 176, 77, 46, 114,
-  140, 158, 112, 137, 124, 64, 136, 128, 73, 86,
-  78, 122, 102, 114, 112, 70, 86, 152, 143, 86,
-  106, 165, 80, 112, 42, 96, 41, 80, 120, 92,
-  135, 77, 87, 94, 121, 73, 102, 83, 108, 85,
-  85, 116, 74, 75, 70, 129, 89, 94, 72, 107,
-  91, 65, 101, 154, 103, 118, 97, 117, 97, 112,
-  58, 81, 98, 82, 135, 143, 80, 107, 99, 139,
-  49, 78, 108, 84, 87, 95, 62, 79, 83, 115,
-  102, 88, 119, 146, 50, 85, 76, 55, 86, 97,
-  38, 77, 110, 46, 64, 60, 91, 83, 83, 89,
-  77, 122, 106, 125, 121, 168, 92, 94, 82, 130,
-  51, 91, 90, 107, 110, 85, 38, 99, 92, 153,
-  78, 108, 128, 99, 82, 82, 120, 83, 79, 110,
-  52, 101, 92, 77, 110, 95, 140, 110, 84, 86,
-  102, 117, 64, 96, 48, 88, 106, 85, 118, 145,
-  76, 92, 102, 85, 72, 83, 89, 83, 91, 83,
-  117, 131, 177, 74, 89, 79, 73, 80, 86, 104,
-  112, 103, 57, 84, 138, 83, 104, 125, 56, 94,
-  88, 181, 115, 70, 82, 103, 77, 84, 131, 88,
-  35, 92, 140, 133, 100, 94, 99, 84, 148, 174,
-  67, 84, 122, 97, 120, 97, 81, 77, 90, 114,
-  143, 99, 81, 132, 80, 98, 52, 91, 45, 63,
-  69, 92, 86, 101, 79, 125, 100, 89, 89, 68,
-  136, 78, 108, 121, 69, 96, 70, 176, 115, 113,
-  56, 105, 141, 100, 90, 157, 88, 105, 96, 110,
-  109, 111, 57, 84, 86, 49, 109, 117, 91, 117,
-  115, 125, 132, 128, 107, 119, 117, 83, 97, 84,
-  115, 111, 106, 72, 110, 125, 87, 91, 120, 71,
-  99, 89, 45, 146, 96, 55, 89, 72, 116, 72,
-  95, 86, 126, 149, 94, 113, 105, 78, 108, 97,
-  112, 126, 91, 88, 100, 140, 126, 119, 89, 95,
-  94, 163, 93, 144, 148, 89, 98, 105, 119, 129,
-  93, 93, 96, 109, 101, 103, 102, 104, 87, 104,
-  82, 138, 130, 82, 82, 97, 58, 81, 143, 80,
-  143, 126, 67, 112, 103, 89, 89, 98, 108, 88,
-  88, 118, 122, 157, 198, 89, 105, 135, 102, 139,
-  100, 125, 112, 114, 83, 56, 152, 110, 122, 159,
-  74, 86, 117, 137, 114, 78, 97, 109, 84, 105,
-  92, 83, 70, 61, 88, 73, 130, 87, 141, 128,
-  112, 114, 101, 89, 173, 113, 136, 81, 83, 99,
-  87, 83, 111, 101, 87, 70, 77, 107, 133, 139,
-  83, 118, 61, 155, 84, 97, 113, 125, 113, 71,
-  83, 103, 130, 54, 123, 112, 90, 134, 83, 169,
-  125, 101, 57, 86, 128, 117, 86, 112, 71, 119,
-  93, 91, 88, 78, 96, 99, 106, 65, 157, 117,
-  112, 128, 160, 111, 164, 157, 120, 109, 147, 115,
-  136, 113, 132, 120, 130, 108, 124, 97, 90, 94,
-  132, 62, 127, 65, 38, 176, 109, 110, 127, 89,
-  121, 86, 88, 82, 126, 154, 108, 126, 104, 54,
-  108, 100, 134, 124, 112, 132, 97, 164, 117, 142,
-  128, 74, 103, 136, 135, 123, 115, 94, 93, 111,
-  105, 126, 107, 68, 123, 127, 125, 106, 111, 134,
-  95, 110, 99, 181, 140, 61, 108, 123, 107, 119,
-  144, 97, 118, 110, 101, 109, 119, 110, 97, 116,
-  110, 130, 94, 121, 133, 100, 121, 122, 123, 150,
-  124, 164, 108, 118, 125, 94, 128, 137, 148, 136,
-  151, 110, 74, 92, 145, 109, 100, 79, 125, 102,
-  123, 114, 89, 98, 83, 76, 126, 95, 146, 80,
-  164, 147, 84, 54, 155, 136, 138, 127, 108, 99,
-  118, 110, 107, 92, 84, 107, 127, 58, 110, 112,
-  150, 141, 113, 153, 69, 161, 111, 97, 132, 91,
-  104, 83, 110, 140, 91, 54, 117, 106, 94, 135,
-  93, 102, 117, 68, 92, 85, 98, 127, 102, 94,
-  79, 131, 75, 89, 62, 109, 107, 112, 113, 89,
-  213, 120, 106, 122, 71, 107, 130, 125, 98, 96,
-  131, 132, 117, 115, 104, 102, 117, 96, 123, 88,
-  88, 83, 137, 99, 115, 112, 63, 134, 175, 130,
-  109, 89, 95, 92, 78, 80, 98, 163, 105, 121,
-  132, 138, 120, 100, 129, 92, 124, 106, 88, 130,
-  92, 112, 137, 109, 90, 144, 161, 90, 131, 139,
-  94, 115, 107, 87, 102, 117, 107, 106, 127, 115,
-  111, 162, 85, 119, 97, 149, 116, 146, 179, 131,
-  153, 147, 126, 74, 124, 94, 121, 90, 155, 119,
-  98, 120, 85, 166, 108, 126, 126, 78, 100, 111,
-  119, 126, 122, 120, 91, 110, 122, 87, 124, 158,
-  122, 142, 148, 75, 78, 99, 120, 104, 106, 88,
-  114, 98, 117, 108, 123, 151, 91, 120, 118, 123,
-  125, 119, 93, 132, 99, 120, 174, 126, 115, 113,
-  108, 101, 104, 112, 121, 111, 95, 97, 114, 86,
-  95, 121, 101, 108, 115, 119, 67, 118, 95, 105,
-  121, 121, 121, 89, 126, 105, 88, 86, 113, 105,
-  84, 110, 112, 102, 105, 118, 102, 88, 87, 108,
-  129, 175, 80, 122, 90, 93, 120, 133, 103, 89,
-  96, 93, 138, 123, 145, 108, 88, 155, 99, 100,
-  94, 117, 93, 112, 93, 153, 108, 104, 121, 132,
-  111, 152, 118, 127, 120, 127, 126, 90, 74, 105,
-  164, 100, 105, 100, 123, 68, 136, 98, 103, 136,
-  91, 95, 144, 114, 114, 121, 115, 104, 89, 98,
-  97, 116, 145, 122, 92, 115, 101, 145, 107, 101,
-  135, 135, 106, 126, 106, 107, 115, 124, 113, 106,
-  103, 126, 118, 99, 128, 119, 117, 103, 121, 132,
-  149, 149, 92, 132, 113, 79, 96, 104, 83, 102,
-  128, 135, 97, 122, 116, 117, 109, 108, 97, 119,
-  101, 132, 112, 100, 131, 81, 117, 145, 135, 98,
-  106, 146, 122, 138, 131, 98, 98, 93, 99, 113,
-  124, 146, 111, 126, 99, 137, 112, 127, 90, 103,
-  105, 124, 108, 137, 91, 105, 92, 135, 132, 80,
-  114, 133, 125, 150, 110, 97, 112, 133, 162, 101,
-  99, 127, 103, 104, 58, 128, 118, 131, 84, 73,
-  107, 95, 99, 104, 103, 121, 145, 87, 100, 106,
-  119, 111, 94, 105, 123, 94, 113, 108, 83, 134,
-  95, 91, 126, 158, 86, 105, 115, 135, 130, 101,
-  125, 88, 81, 129, 104, 105, 176, 105, 128, 139,
-  98, 105, 111, 164, 99, 95, 88, 156, 110, 124,
-  101, 120, 112, 146, 106, 119, 135, 130, 113, 68,
-  55, 110, 57, 90, 134, 102, 123, 112, 120, 77,
-  115, 122, 66, 114, 159, 80, 112, 99, 109, 108,
-  84, 70, 92, 167, 85, 129, 107, 197, 77, 121,
-  82, 124, 136, 127, 86, 116, 99, 117, 107, 111,
-  120, 109, 107, 109, 99, 90, 103, 104, 126, 92,
-  133, 91, 95, 155, 75, 95, 92, 95, 103, 107,
-  84, 118, 117, 153, 94, 108, 111, 103, 97, 82,
-  109, 130, 122, 127, 102, 92, 163, 113, 151, 134,
-  170, 96, 100, 102, 86, 172, 137, 103, 93, 94,
-  93, 112, 113, 152, 104, 114, 109, 157, 87, 110,
-  77, 110, 80, 110, 95, 113, 157, 82, 105, 115,
-  133, 73, 136, 121, 118, 173, 98, 105, 121, 138,
-  149, 94, 116, 135, 110, 105, 109, 157, 116, 141,
-  82, 67, 117, 74, 71, 94, 132, 117, 122, 86,
-  115, 129, 122, 121, 81, 81, 116, 139, 87, 147,
-  104, 120, 76, 104, 100, 101, 87, 108, 106, 119,
-  124, 88, 141, 88, 87, 136, 83, 113, 164, 97,
-  133, 118, 100, 114, 131, 125, 105, 103, 86, 131,
-  108, 139, 111, 127, 110, 114, 118, 88, 109, 83,
-  114, 101, 55, 112, 36, 110, 156, 97, 108, 103,
-  98, 66, 99, 110, 60, 136, 126, 84, 91, 104,
-  110, 124, 82, 129, 78, 193, 89, 132, 116, 135,
-  69, 65, 79, 128, 111, 88, 81, 95, 85, 98,
-  117, 91, 107, 86, 103, 108, 116, 108, 100, 89,
-  114, 90, 132, 70, 82, 126, 80, 95, 98, 92,
-  134, 70, 116, 124, 102, 157, 98, 93, 91, 109,
-  100, 83, 112, 109, 111, 109, 114, 79, 159, 137,
-  161, 122, 160, 101, 107, 170, 75, 110, 115, 113,
-  84, 93, 91, 105, 104, 133, 102, 93, 114, 154,
-  109, 71, 58, 101, 81, 103, 111, 85, 173, 80,
-  98, 85, 121, 155, 110, 111, 82, 174, 111, 98,
-  124, 153, 126, 93, 123, 139, 106, 105, 61, 110,
-  100, 137, 96, 88, 133, 84, 64, 102, 102, 107,
-  81, 105, 102, 118, 130, 132, 86, 71, 91, 125,
-  68, 87, 132, 94, 85, 94, 105, 84, 86, 130,
-  112, 100, 102, 68, 98, 93, 87, 127, 77, 107,
-  163, 68, 78, 103, 86, 97, 119, 139, 84, 82,
-  78, 89, 71, 76, 81, 81, 111, 105, 119, 86,
-  93, 121, 114, 137, 34, 68, 30, 100, 147, 82,
-  126, 83, 120, 52, 87, 107, 66, 107, 110, 113,
-  68, 94, 101, 64, 94, 65, 60, 157, 84, 96,
-  90, 114, 62, 85, 85, 99, 89, 83, 80, 108,
-  104, 52, 118, 116, 80, 72, 84, 96, 96, 76,
-  67, 88, 62, 76, 97, 150, 88, 107, 57, 111,
-  85, 78, 126, 77, 76, 71, 96, 131, 59, 89,
-  104, 97, 92, 79, 108, 100, 122, 94, 86, 58,
-  116, 100, 107, 101, 138, 69, 72, 140, 85, 118,
-  121, 76, 61, 107, 63, 96, 105, 117, 85, 89,
-  109, 122, 112, 87, 46, 93, 80, 104, 64, 103,
-  81, 98, 103, 104, 120, 142, 84, 104, 94, 160,
-  73, 86, 103, 129, 103, 77, 101, 109, 88, 94,
-  30, 91, 78, 85, 50, 67, 98, 72, 39, 121,
-  62, 95, 83, 71, 109, 108, 119, 95, 92, 66,
-  80, 133, 87, 107, 96, 73, 87, 88, 150, 80,
-  80, 136, 82, 86, 83, 58, 57, 70, 93, 108,
-  67, 84, 178, 89, 125, 86, 145, 121, 128, 151,
-  86, 86, 88, 102, 85, 90, 117, 72, 104, 100,
-  131, 111, 96, 105, 111, 79, 40, 93, 66, 107,
-  165, 97, 134, 91, 119, 95, 109, 85, 95, 75,
-  80, 92, 109, 113, 130, 47, 115, 69, 54, 148,
-  96, 89, 93, 143, 69, 83, 84, 97, 110, 90,
-  108, 99, 95, 72, 125, 105, 132, 111, 82, 116,
-  99, 82, 100, 79, 81, 102, 118, 99, 107, 107,
-  104, 97, 92, 84, 89, 91, 62, 88, 97, 145,
-  74, 93, 122, 65, 105, 86, 72, 123, 117, 107,
-  103, 101, 143, 123, 133, 126, 115, 89, 99, 54,
-  104, 113, 115, 75, 75, 111, 74, 84, 101, 115,
-  132, 95, 100, 126, 117, 75, 77, 88, 99, 97,
-  112, 90, 125, 110, 88, 71, 114, 89, 132, 108,
-  106, 145, 90, 120, 108, 116, 88, 96, 108, 94,
-  104, 105, 109, 121, 109, 130, 52, 136, 129, 79,
-  55, 86, 68, 58, 79, 101, 92, 105, 120, 94,
-  117, 107, 95, 106, 85, 101, 114, 76, 90, 85,
-  119, 80, 79, 156, 84, 73, 76, 68, 75, 72,
-  115, 126, 80, 83, 162, 88, 84, 97, 142, 133,
-  137, 132, 118, 105, 91, 108, 93, 99, 112, 77,
-  107, 112, 112, 95, 91, 84, 104, 89, 43, 123,
-  68, 131, 154, 103, 116, 92, 112, 96, 79, 72,
-  93, 79, 80, 93, 102, 120, 139, 63, 137, 82,
-  56, 146, 115, 107, 86, 123, 61, 83, 79, 82,
-  109, 90, 120, 105, 88, 68, 150, 100, 171, 131,
-  100, 122, 104, 78, 89, 59, 107, 120, 135, 76,
-  111, 104, 142, 108, 87, 94, 57, 80, 74, 121,
-  89, 167, 94, 84, 98, 93, 106, 91, 82, 107,
-  75, 121, 101, 125, 172, 115, 131, 134, 121, 83,
-  113, 104, 110, 109, 115, 93, 73, 113, 82, 69,
-  89, 105, 143, 87, 123, 117, 131, 88, 100, 107,
-  107, 89, 105, 117, 134, 90, 84, 65, 105, 89,
-  133, 101, 114, 112, 103, 113, 117, 115, 103, 104,
-  106, 82, 99, 80, 129, 122, 128, 147, 57, 125,
-  124, 77, 55, 61, 79, 72, 89, 98, 81, 93,
-  109, 97, 112, 99, 115, 87, 64, 85, 117, 98,
-  84, 75, 115, 87, 77, 122, 87, 83, 86, 93,
-  89, 72, 121, 148, 115, 114, 125, 83, 85, 104,
-  118, 113, 151, 100, 121, 118, 89, 96, 87, 124,
-  101, 95, 113, 118, 94, 74, 82, 88, 93, 92,
-  54, 126, 75, 127, 122, 105, 92, 84, 75, 81,
-  60, 78, 73, 88, 84, 110, 91, 116, 126, 71,
-  120, 92, 65, 129, 120, 118, 76, 126, 58, 95,
-  75, 77, 121, 83, 121, 112, 83, 79, 129, 106,
-  121, 117, 92, 111, 104, 100, 78, 42, 129, 129,
-  137, 85, 113, 108, 163, 121, 92, 100, 67, 84,
-  85, 132, 92, 159, 90, 104, 88, 133, 95, 90,
-  82, 79, 67, 107, 104, 129, 144, 95, 107, 124,
-  126, 109, 112, 135, 140, 121, 106, 80, 86, 117,
-  102, 75, 87, 97, 134, 79, 119, 93, 152, 73,
-  89, 92, 128, 94, 92, 88, 127, 77, 94, 86,
-  107, 94, 124, 92, 93, 79, 117, 112, 105, 128,
-  110, 103, 102, 87, 98, 95, 102, 129, 110, 134,
-  66, 97, 108, 81, 72, 66, 126, 68, 78, 100,
-  93, 109, 82, 117, 77, 87, 118, 103, 62, 88,
-  100, 100, 81, 89, 111, 126, 83, 87, 91, 82,
-  83, 126, 88, 76, 98, 142, 114, 118, 101, 79,
-  132, 103, 107, 94, 127, 102, 113, 127, 98, 90,
-  92, 122, 123, 95, 97, 124, 104, 68, 85, 83,
-  115, 90, 58, 126, 76, 109, 97, 98, 102, 87,
-  81, 81, 57, 93, 78, 104, 126, 136, 85, 107,
-  123, 60, 96, 103, 87, 105, 125, 130, 71, 122,
-  74, 134, 77, 89, 130, 102, 119, 133, 88, 103,
-  98, 108, 88, 96, 82, 148, 98, 108, 87, 56,
-  155, 119, 137, 118, 90, 100, 123, 118, 101, 104,
-  102, 111, 85, 86, 97, 128, 92, 118, 76, 133,
-  75, 106, 66, 96, 88, 94, 111, 146, 104, 111,
-  89, 140, 117, 118, 110, 111, 165, 133, 118, 84,
-  103, 115, 102, 102, 101, 97, 120, 90, 106, 86,
-  141, 80, 91, 87, 135, 112, 94, 68, 115, 92,
-  141, 107, 118, 123, 122, 102, 92, 69, 129, 127,
-  100, 132, 117, 100, 80, 82, 105, 101, 89, 110,
-  89, 131, 130, 76, 86, 96, 92, 95, 126, 81,
-  82, 87, 110, 120, 92, 143, 67, 93, 99, 119,
-  80, 100, 64, 106, 95, 100, 116, 158, 92, 69,
-  109, 84, 87, 133, 85, 81, 89, 136, 116, 129,
-  113, 96, 81, 108, 119, 97, 94, 135, 117, 108,
-  98, 96, 126, 108, 132, 95, 83, 112, 129, 93,
-  105, 71, 104, 92, 65, 115, 88, 93, 103, 105,
-  147, 103, 103, 93, 75, 103, 95, 107, 133, 117,
-  90, 109, 131, 68, 106, 99, 120, 90, 110, 130,
-  104, 112, 75, 164, 74, 128, 109, 113, 120, 111,
-  116, 122, 99, 101, 96, 112, 103, 138, 90, 90,
-  93, 94, 155, 115, 127, 126, 84, 116, 67, 95,
-  103, 113, 82, 103, 83, 70, 81, 113, 91, 92,
-  88, 96, 78, 127, 55, 116, 117, 91, 127, 151,
-  103, 86, 99, 137, 113, 99, 121, 71, 127, 131,
-  120, 104, 75, 124, 105, 104, 98, 100, 104, 116,
-  105, 79, 100, 107, 112, 82, 106, 110, 100, 79,
-  87, 125, 135, 102, 107, 132, 120, 104, 102, 58,
-  106, 125, 93, 108, 118, 103, 84, 72, 113, 111,
-  115, 98, 91, 121, 97, 85, 73, 103, 99, 119,
-  63, 96, 98, 81, 100, 114, 130, 91, 93, 120,
-  83, 104, 86, 101, 61, 126, 92, 99, 102, 135,
-  84, 69, 100, 102, 91, 87, 90, 77, 87, 132,
-  116, 129, 125, 115, 90, 120, 141, 129, 97, 127,
-  134, 102, 97, 111, 142, 106, 144, 116, 84, 96,
-  143, 118, 108, 74, 109, 85, 57, 142, 82, 99,
-  125, 101, 167, 111, 114, 106, 93, 94, 109, 111,
-  108, 94, 90, 123, 140, 72, 135, 107, 120, 104,
-  107, 138, 125, 122, 77, 135, 87, 142, 95, 111,
-  103, 108, 130, 129, 102, 92, 123, 121, 121, 124,
-  86, 89, 85, 117, 161, 130, 123, 95, 92, 108,
-  78, 81, 115, 135, 45, 103, 95, 109, 70, 125,
-  90, 74, 121, 88, 100, 131, 78, 119, 123, 103,
-  127, 156, 134, 88, 124, 133, 128, 93, 149, 68,
-  119, 112, 119, 113, 79, 132, 112, 99, 85, 94,
-  103, 123, 115, 115, 100, 101, 119, 82, 91, 102,
-  115, 98, 93, 137, 92, 95, 95, 84, 122, 92,
-  111, 66, 91, 127, 95, 97, 107, 125, 113, 63,
-  133, 115, 142, 130, 108, 143, 65, 105, 94, 93,
-  100, 111, 75, 103, 110, 95, 99, 112, 140, 98,
-  113, 130, 93, 98, 65, 88, 100, 124, 78, 102,
-  105, 112, 82, 91, 88, 102, 85, 73, 93, 87,
-  97, 134, 112, 136, 123, 112, 106, 127, 149, 155,
-  113, 119, 138, 103, 107, 121, 139, 116, 130, 132,
-  99, 91, 150, 124, 107, 82, 115, 91, 59, 143,
-  80, 121, 137, 89, 150, 82, 116, 100, 104, 88,
-  112, 115, 90, 87, 99, 126, 143, 63, 162, 122,
-  101, 123, 109, 133, 119, 114, 70, 100, 98, 125,
-  110, 111, 88, 117, 112, 111, 89, 102, 145, 119,
-  126, 123, 80, 81, 66, 110, 142, 139, 113, 89,
-  100, 111, 110, 97, 114, 137, 58, 108, 114, 112,
-  78, 141, 89, 83, 116, 109, 101, 126, 82, 127,
-  100, 106, 132, 143, 159, 93, 137, 128, 127, 86,
-  158, 97, 120, 121, 121, 103, 100, 144, 116, 89,
-  72, 99, 116, 110, 122, 144, 116, 105, 108, 92,
-  105, 106, 123, 118, 100, 134, 69, 75, 109, 96,
-  121, 92, 116, 83, 74, 133, 112, 110, 108, 125,
-  123, 63, 147, 118, 147, 147, 124, 158, 56, 116,
-  113, 90, 100, 112, 92, 112, 107, 108, 87, 102,
-  146, 87, 110, 120, 107, 98, 64, 79, 122, 115,
-  70, 114, 109, 100, 77, 107, 90, 107, 85, 84,
-  94, 96, 106, 128, 108, 132, 124, 112, 96, 121,
-  134, 159, 128, 108, 131, 88, 108, 116, 124, 127,
-  115, 131, 121, 96, 131, 118, 90, 72, 111, 89,
-  52, 129, 72, 136, 131, 78, 132, 69, 111, 86,
-  116, 84, 103, 115, 77, 95, 94, 118, 139, 59,
-  174, 123, 90, 137, 106, 127, 106, 121, 57, 78,
-  100, 122, 115, 130, 80, 118, 93, 98, 94, 105,
-  133, 119, 126, 108, 71, 88, 43, 97, 117, 126,
-  108, 96, 114, 120, 122, 95, 103, 122, 51, 97,
-  115, 108, 77, 160, 88, 91, 96, 128, 90, 111,
-  66, 109, 100, 102, 136, 116, 162, 99, 135, 120,
-  119, 85, 158, 111, 132, 139, 117, 78, 90, 138,
-  115, 82, 69, 97, 115, 86, 128, 153, 130, 110,
-  88, 88, 105, 102, 118, 110, 102, 109, 68, 79,
-  113, 108, 116, 88, 115, 86, 77, 132, 120, 123,
-  107, 117, 117, 79, 143, 114, 154, 133, 123, 150,
-  34, 106, 108, 80, 98, 131, 92, 122, 98, 124,
-  81, 99, 130, 89, 99, 100, 122, 105, 76, 77,
-  123, 108, 73, 126, 111, 105, 80, 124, 79, 113,
-  87, 112, 81, 98, 112, 120, 87, 131, 110, 116,
-  94, 117, 132, 142, 118, 79, 119, 87, 109, 121,
-  113, 134, 117, 142, 122, 115, 121, 120, 84, 62,
-  107, 89, 40, 131, 75, 124, 105, 77, 116, 61,
-  110, 76, 107, 82, 99, 111, 76, 103, 99, 100,
-  119, 64, 169, 136, 96, 134, 96, 118, 93, 150,
-  61, 85, 100, 123, 104, 130, 65, 128, 99, 98,
-  106, 104, 114, 105, 129, 132, 76, 110, 48, 99,
-  116, 109, 110, 108, 113, 110, 116, 80, 97, 120,
-  48, 104, 118, 123, 83, 162, 94, 93, 90, 134,
-  84, 90, 62, 95, 107, 98, 137, 99, 135, 99,
-  108, 147, 111, 92, 147, 104, 171, 144, 110, 73,
-  92, 120, 120, 92, 74, 86, 96, 68, 126, 144,
-  127, 110, 72, 78, 98, 99, 118, 79, 98, 98,
-  91, 106, 114, 87, 106, 84, 115, 68, 101, 138,
-  114, 112, 102, 114, 107, 113, 132, 108, 139, 143,
-  112, 148, 44, 93, 93, 81, 105, 144, 108, 116,
-  90, 121, 89, 98, 119, 105, 96, 67, 113, 125,
-  76, 78, 128, 106, 78, 133, 102, 135, 78, 128,
-  79, 102, 82, 136, 80, 94, 112, 113, 71, 133,
-  107, 118, 115, 107, 131, 139, 86, 72, 105, 87,
-  112, 115, 128, 152, 125, 156, 102, 130, 110, 111,
-  90, 50, 122, 89, 32, 160, 91, 117, 83, 74,
-  117, 90, 113, 82, 99, 75, 101, 108, 96, 85,
-  96, 80, 104, 80, 144, 139, 96, 115, 93, 113,
-  106, 138, 74, 101, 106, 152, 104, 119, 92, 157,
-  108, 114, 107, 107, 95, 98, 135, 174, 94, 138,
-  57, 92, 124, 112, 112, 115, 104, 110, 121, 67,
-  106, 115, 64, 114, 143, 98, 89, 155, 101, 88,
-  93, 128, 85, 80, 73, 121, 94, 96, 152, 111,
-  93, 104, 97, 164, 90, 91, 125, 103, 189, 134,
-  114, 101, 123, 107, 125, 111, 90, 91, 89, 74,
-  127, 131, 120, 122, 59, 84, 85, 112, 131, 61,
-  90, 84, 85, 100, 97, 72, 77, 96, 104, 52,
-  103, 133, 101, 106, 102, 116, 98, 148, 119, 109,
-  115, 144, 97, 147, 75, 99, 77, 88, 126, 132,
-  109, 88, 89, 102, 99, 90, 122, 132, 88, 44,
-  87, 121, 62, 71, 114, 97, 87, 143, 97, 151,
-  85, 127, 94, 87, 76, 130, 86, 96, 102, 110,
-  71, 125, 112, 126, 98, 99, 113, 138, 55, 81,
-  74, 63, 100, 94, 147, 164, 109, 155, 97, 113,
-  69, 93, 107, 48, 100, 85, 27, 147, 104, 112,
-  65, 71, 137, 108, 79, 93, 112, 84, 97, 111,
-  112, 63, 87, 68, 95, 113, 102, 137, 113, 102,
-  86, 116, 133, 102, 62, 88, 95, 194, 106, 114,
-  127, 148, 109, 129, 92, 106, 71, 120, 144, 146,
-  115, 147, 76, 87, 109, 107, 108, 96, 89, 131,
-  112, 65, 116, 109, 89, 113, 160, 83, 96, 139,
-  99, 66, 89, 106, 101, 89, 96, 150, 88, 97,
-  161, 97, 78, 95, 110, 137, 77, 86, 99, 96,
-  126, 107, 110, 132, 105, 103, 119, 119, 96, 113,
-  70, 94, 110, 115, 111, 153, 32, 100, 65, 129,
-  151, 94, 89, 72, 71, 89, 84, 84, 49, 103,
-  81, 43, 75, 112, 111, 104, 103, 115, 87, 163,
-  98, 108, 92, 108, 71, 114, 73, 122, 71, 86,
-  137, 108, 99, 73, 89, 87, 98, 97, 113, 103,
-  82, 63, 73, 115, 42, 54, 92, 81, 93, 140,
-  86, 131, 84, 134, 99, 72, 82, 107, 101, 80,
-  88, 100, 53, 122, 122, 119, 102, 92, 80, 112,
-  35, 89, 41, 44, 106, 72, 177, 147, 104, 149,
-  107, 105, 45, 73, 103, 74, 73, 119, 18, 105,
-  110, 80, 63, 47, 116, 73, 79, 86, 110, 99,
-  88, 106, 124, 80, 76, 52, 91, 110, 77, 126,
-  107, 102, 73, 119, 116, 80, 69, 47, 92, 187,
-  102, 100, 120, 113, 102, 109, 72, 102, 46, 114,
-  142, 102, 136, 153, 89, 71, 76, 98, 92, 77,
-  74, 116, 80, 76, 124, 94, 129, 108, 161, 100,
-  102, 110, 73, 70, 83, 98, 124, 89, 122, 141,
-  109, 79, 139, 71, 77, 115, 106, 109, 65, 74,
-  70, 129, 86, 120, 105, 140, 96, 91, 90, 116,
-  99, 112, 63, 105, 92, 98, 110, 149, 20, 116,
-  68, 132, 146, 132, 114, 62, 67, 67, 92, 124,
-  51, 87, 73, 61, 56, 99, 118, 104, 110, 106,
-  59, 155, 80, 105, 53, 73, 50, 93, 84, 133,
-  51, 90, 115, 83, 104, 84, 73, 88, 104, 109,
-  114, 108, 75, 89, 98, 99, 57, 51, 88, 92,
-  109, 126, 66, 106, 68, 133, 107, 53, 92, 97,
-  79, 50, 83, 72, 28, 105, 130, 102, 96, 70,
-  57, 80, 29, 105, 28, 72, 105, 76, 156, 95,
-  103, 128, 127, 114, 44, 77, 81, 109, 71, 177,
-  5, 56, 95, 44, 89, 34, 80, 63, 123, 86,
-  97, 109, 77, 67, 118, 92, 75, 43, 92, 99,
-  66, 83, 87, 109, 72, 102, 62, 75, 81, 22,
-  90, 113, 83, 83, 94, 93, 105, 60, 73, 96,
-  37, 84, 103, 90, 147, 154, 94, 66, 71, 101,
-  85, 107, 78, 76, 66, 101, 101, 87, 124, 112,
-  101, 98, 93, 103, 40, 100, 110, 92, 135, 65,
-  122, 121, 122, 71, 107, 41, 92, 90, 95, 99,
-  51, 41, 56, 153, 92, 126, 108, 102, 81, 84,
-  55, 100, 110, 98, 83, 108, 98, 87, 120, 125,
-  11, 114, 87, 106, 103, 140, 119, 54, 57, 71,
-  99, 124, 65, 73, 93, 94, 43, 110, 118, 116,
-  107, 92, 27, 148, 61, 101, 37, 91, 39, 91,
-  74, 102, 63, 95, 63, 77, 97, 95, 55, 80,
-  82, 121, 127, 112, 68, 90, 131, 81, 83, 62,
-  91, 96, 116, 113, 84, 90, 67, 116, 86, 62,
-  100, 106, 62, 42, 95, 53, 32, 66, 149, 92,
-  79, 71, 65, 93, 69, 128, 61, 109, 80, 105,
-  77, 84, 74, 83, 148, 108, 53, 75, 85, 154,
-  86, 107, 22, 52, 63, 67, 139, 73, 84, 62,
-  108, 83, 78, 115, 67, 43, 88, 72, 102, 61,
-  110, 89, 59, 51, 85, 138, 80, 95, 48, 132,
-  73, 46, 87, 69, 104, 111, 92, 89, 84, 43,
-  92, 118, 74, 88, 61, 89, 116, 123, 90, 69,
-  81, 112, 105, 100, 98, 97, 60, 111, 82, 89,
-  87, 120, 44, 102, 85, 138, 32, 143, 110, 86,
-  110, 44, 98, 111, 125, 95, 76, 44, 130, 70,
-  121, 101, 81, 29, 64, 82, 89, 88, 108, 69,
-  40, 98, 57, 83, 120, 108, 148, 92, 115, 114,
-  139, 95, 29, 93, 87, 97, 79, 125, 128, 59,
-  72, 97, 117, 66, 70, 92, 104, 131, 52, 106,
-  116, 147, 104, 74, 52, 149, 65, 98, 73, 110,
-  54, 92, 62, 81, 104, 76, 47, 80, 111, 87,
-  68, 87, 63, 129, 103, 78, 70, 82, 129, 91,
-  90, 100, 87, 76, 91, 93, 116, 94, 76, 115,
-  72, 70, 99, 85, 98, 62, 115, 69, 43, 69,
-  154, 82, 136, 86, 90, 126, 109, 113, 97, 133,
-  85, 147, 102, 132, 76, 81, 112, 96, 75, 103,
-  103, 105, 101, 66, 48, 94, 58, 107, 206, 90,
-  97, 82, 79, 69, 90, 104, 68, 97, 76, 66,
-  123, 96, 131, 92, 62, 91, 87, 188, 76, 120,
-  92, 155, 50, 62, 69, 91, 133, 107, 91, 111,
-  85, 71, 104, 132, 125, 93, 90, 116, 111, 94,
-  98, 73, 127, 107, 135, 64, 84, 116, 95, 100,
-  81, 85, 105, 117, 57, 118, 96, 164, 59, 130,
-  66, 104, 77, 57, 67, 105, 110, 102, 71, 72,
-  170, 137, 178, 126, 132, 93, 94, 86, 84, 100,
-  109, 109, 64, 109, 77, 92, 111, 114, 199, 83,
-  115, 172, 128, 72, 64, 120, 78, 123, 96, 79,
-  201, 72, 114, 81, 122, 102, 93, 109, 101, 186,
-  144, 106, 125, 191, 122, 86, 100, 157, 105, 94,
-  119, 112, 78, 125, 116, 91, 162, 80, 66, 80,
-  132, 118, 88, 112, 96, 129, 86, 124, 85, 63,
-  124, 88, 94, 117, 108, 105, 86, 65, 100, 95,
-  87, 108, 100, 81, 96, 76, 160, 104, 119, 122,
-  70, 103, 136, 79, 123, 115, 77, 115, 122, 105,
-  98, 141, 89, 149, 135, 127, 116, 100, 97, 107,
-  95, 136, 120, 66, 97, 90, 52, 106, 95, 119,
-  196, 94, 116, 132, 90, 62, 88, 118, 77, 130,
-  101, 83, 96, 111, 129, 87, 67, 126, 91, 171,
-  89, 128, 102, 90, 75, 53, 60, 108, 95, 83,
-  86, 152, 96, 78, 104, 108, 124, 71, 95, 125,
-  109, 71, 96, 108, 143, 100, 148, 92, 39, 133,
-  143, 152, 91, 74, 88, 101, 92, 120, 102, 140,
-  58, 94, 66, 109, 100, 62, 78, 91, 90, 136,
-  71, 73, 165, 92, 164, 137, 150, 134, 96, 169,
-  83, 166, 120, 109, 73, 121, 92, 94, 105, 154,
-  181, 80, 114, 157, 126, 101, 73, 161, 92, 132,
-  84, 87, 152, 86, 135, 71, 103, 153, 86, 130,
-  77, 190, 158, 81, 142, 192, 145, 86, 104, 163,
-  113, 93, 98, 99, 90, 135, 78, 80, 167, 93,
-  56, 114, 105, 154, 120, 122, 115, 124, 125, 119,
-  81, 48, 115, 85, 120, 84, 97, 147, 88, 51,
-  144, 86, 98, 89, 136, 107, 104, 64, 177, 103,
-  92, 134, 107, 115, 145, 75, 115, 115, 59, 89,
-  131, 151, 83, 81, 85, 133, 121, 104, 122, 88,
-  108, 116, 95, 123, 80, 119, 92, 99, 39, 111,
-  103, 109, 169, 94, 102, 155, 130, 67, 75, 121,
-  75, 99, 143, 115, 93, 99, 116, 87, 69, 98,
-  80, 138, 99, 120, 60, 136, 103, 56, 81, 92,
-  100, 97, 106, 169, 72, 55, 83, 101, 105, 45,
-  84, 116, 108, 78, 98, 96, 133, 104, 139, 107,
-  44, 132, 101, 173, 93, 70, 96, 126, 98, 97,
-  111, 130, 45, 98, 96, 111, 147, 42, 96, 125,
-  79, 128, 72, 52, 142, 88, 112, 124, 155, 97,
-  78, 147, 89, 142, 131, 97, 111, 117, 83, 83,
-  123, 148, 186, 94, 97, 125, 142, 96, 86, 153,
-  111, 99, 64, 142, 118, 92, 112, 54, 99, 111,
-  82, 121, 85, 176, 85, 63, 118, 175, 136, 84,
-  86, 142, 80, 88, 76, 125, 87, 130, 94, 71,
-  142, 86, 42, 108, 92, 137, 121, 120, 119, 120,
-  139, 132, 71, 50, 127, 106, 139, 104, 77, 163,
-  94, 57, 163, 71, 102, 79, 133, 101, 103, 78,
-  149, 88, 77, 118, 109, 85, 157, 72, 98, 97,
-  72, 102, 156, 136, 93, 73, 79, 120, 75, 139,
-  113, 97, 137, 91, 63, 90, 63, 105, 90, 108,
-  34, 108, 102, 122, 165, 93, 78, 97, 106, 97,
-  64, 101, 76, 85, 112, 107, 117, 85, 107, 112,
-  56, 94, 57, 122, 82, 95, 34, 149, 79, 64,
-  63, 69, 99, 76, 154, 121, 70, 40, 99, 95,
-  134, 109, 95, 109, 114, 109, 129, 49, 127, 118,
-  126, 93, 96, 110, 97, 136, 71, 82, 65, 121,
-  83, 113, 100, 150, 36, 137, 101, 117, 138, 37,
-  78, 131, 81, 81, 87, 62, 158, 98, 109, 115,
-  146, 74, 68, 118, 105, 91, 108, 77, 90, 105,
-  82, 89, 137, 102, 194, 79, 105, 91, 147, 70,
-  65, 99, 118, 76, 84, 84, 152, 62, 87, 90,
-  106, 92, 75, 84, 82, 150, 95, 89, 97, 187,
-  102, 96, 101, 150, 66, 90, 77, 135, 85, 126,
-  79, 100, 161, 63, 49, 92, 74, 65, 91, 94,
-  69, 143, 94, 115, 77, 51, 106, 98, 126, 84,
-  91, 115, 88, 60, 102, 99, 104, 108, 100, 91,
-  99, 103, 111, 74, 90, 106, 89, 74, 140, 69,
-  112, 62, 61, 111, 149, 82, 109, 128, 63, 104,
-  51, 147, 103, 90, 119, 100, 50, 73, 46, 62,
-  83, 88, 34, 102, 103, 94, 138, 91, 72, 88,
-  57, 110, 57, 92, 87, 104, 104, 113, 87, 74,
-  100, 115, 57, 70, 54, 109, 79, 83, 30, 107,
-  57, 77, 59, 78, 94, 120, 176, 122, 87, 61,
-  116, 113, 110, 121, 96, 119, 118, 109, 117, 55,
-  113, 101, 116, 103, 106, 82, 96, 102, 75, 93,
-  79, 93, 64, 114, 115, 130, 30, 133, 87, 99,
-  93, 38, 81, 100, 107, 63, 101, 80, 120, 93,
-  97, 116, 114, 83, 67, 111, 120, 88, 108, 93,
-  102, 91, 74, 115, 155, 79, 164, 67, 103, 76,
-  153, 59, 59, 92, 92, 89, 105, 77, 126, 48,
-  121, 150, 80, 94, 63, 63, 89, 117, 109, 84,
-  96, 185, 93, 88, 88, 164, 72, 94, 56, 93,
-  58, 94, 79, 99, 129, 58, 65, 90, 104, 26,
-  73, 81, 99, 113, 57, 142, 76, 46, 71, 118,
-  110, 87, 68, 78, 90, 73, 97, 155, 112, 122,
-  91, 90, 103, 118, 76, 84, 97, 91, 96, 121,
-  109, 82, 98, 95, 48, 111, 106, 87, 103, 122,
-  73, 102, 89, 122, 79, 77, 92, 146, 68, 76,
-  81, 50, 95, 81, 38, 109, 124, 51, 82, 82,
-  89, 120, 48, 106, 77, 125, 77, 117, 122, 128,
-  83, 81, 97, 112, 50, 70, 100, 122, 96, 101,
-  51, 94, 95, 136, 71, 107, 135, 147, 128, 108,
-  107, 102, 93, 105, 72, 92, 95, 122, 103, 82,
-  98, 97, 88, 108, 111, 117, 73, 87, 56, 82,
-  103, 92, 117, 107, 41, 85, 117, 99, 48, 113,
-  101, 87, 74, 81, 92, 99, 148, 73, 118, 97,
-  83, 87, 95, 122, 97, 99, 49, 97, 149, 95,
-  99, 126, 99, 85, 88, 159, 132, 79, 108, 97,
-  82, 83, 129, 78, 45, 83, 99, 133, 101, 98,
-  116, 72, 148, 163, 66, 93, 94, 94, 109, 108,
-  91, 89, 76, 142, 128, 93, 69, 141, 76, 107,
-  66, 102, 34, 71, 103, 96, 78, 92, 102, 124,
-  119, 63, 59, 84, 132, 90, 83, 136, 68, 73,
-  62, 168, 111, 131, 37, 91, 107, 94, 106, 173,
-  85, 101, 102, 92, 90, 121, 52, 92, 95, 76,
-  122, 142, 92, 106, 94, 135, 105, 120, 89, 104,
-  104, 75, 85, 87, 128, 109, 100, 76, 89, 142,
-  82, 85, 106, 53, 85, 93, 47, 117, 124, 44,
-  76, 73, 118, 93, 78, 86, 114, 137, 82, 109,
-  111, 100, 92, 86, 108, 111, 77, 99, 106, 150,
-  103, 123, 98, 95, 82, 170, 81, 135, 123, 103,
-  108, 104, 141, 141, 102, 95, 84, 104, 117, 94,
-  102, 75, 118, 112, 83, 123, 117, 94, 77, 100,
-  44, 72, 124, 85, 131, 130, 69, 100, 98, 89,
-  86, 91, 107, 76, 83, 119, 113, 104, 194, 82,
-  110, 127, 93, 105, 108, 111, 121, 110, 63, 74,
-  154, 86, 107, 169, 72, 83, 121, 160, 121, 85,
-  87, 104, 78, 96, 96, 93, 63, 59, 75, 125,
-  113, 78, 112, 117, 112, 132, 93, 92, 167, 109,
-  127, 84, 80, 107, 65, 100, 122, 104, 79, 84,
-  80, 100, 104, 121, 64, 81, 52, 130, 72, 96,
-  123, 126, 117, 78, 60, 89, 136, 72, 133, 112,
-  78, 120, 63, 159, 113, 106, 45, 79, 120, 116,
-  104, 126, 71, 107, 88, 93, 88, 80, 81, 100,
-  97, 73, 127, 129, 97, 126, 175, 114, 163, 160,
-  108, 120, 140, 85, 124, 101, 126, 119, 117, 95,
-  109, 112, 86, 87, 123, 72, 135, 70, 46, 160,
-  89, 93, 116, 88, 120, 68, 114, 76, 129, 148,
-  105, 115, 102, 58, 98, 100, 133, 122, 110, 124,
-  96, 172, 110, 139, 130, 88, 85, 135, 124, 123,
-  122, 91, 101, 114, 116, 146, 97, 83, 111, 112,
-  117, 105, 114, 112, 90, 98, 95, 158, 140, 65,
-  102, 117, 78, 102, 153, 101, 131, 120, 91, 108,
-  83, 96, 93, 102, 111, 123, 83, 133, 129, 118,
-  167, 112, 94, 142, 106, 168, 110, 116, 131, 81,
-  102, 111, 151, 120, 126, 127, 92, 88, 144, 130,
-  115, 79, 119, 104, 120, 117, 92, 85, 79, 68,
-  109, 88, 140, 81, 152, 140, 73, 58, 151, 132,
-  154, 119, 124, 88, 92, 114, 91, 94, 95, 102,
-  120, 56, 106, 110, 149, 128, 101, 127, 66, 165,
-  95, 94, 129, 105, 102, 82, 77, 132, 107, 63,
-  137, 114, 84, 136, 91, 105, 113, 83, 83, 65,
-  103, 127, 113, 85, 77, 132, 77, 87, 64, 99,
-  101, 117, 116, 73, 200, 127, 100, 139, 105, 100,
-  124, 149, 96, 104, 147, 123, 114, 114, 103, 109,
-  114, 122, 118, 78, 65, 84, 121, 48, 111, 80,
-  38, 143, 122, 129, 121, 82, 82, 75, 107, 79,
-  107, 147, 105, 99, 102, 95, 82, 87, 129, 117,
-  119, 136, 97, 169, 79, 116, 136, 90, 91, 138,
-  163, 100, 108, 123, 77, 95, 106, 101, 113, 105,
-  87, 97, 125, 90, 123, 166, 108, 109, 99, 161,
-  126, 89, 119, 145, 121, 102, 123, 101, 128, 92,
-  87, 81, 116, 109, 85, 116, 94, 178, 85, 113,
-  124, 69, 94, 106, 120, 110, 112, 140, 104, 93,
-  120, 59, 119, 149, 127, 115, 143, 79, 83, 98,
-  140, 125, 88, 49, 109, 93, 154, 115, 96, 130,
-  69, 75, 134, 112, 108, 80, 129, 127, 78, 91,
-  183, 162, 93, 107, 98, 94, 117, 115, 118, 112,
-  82, 103, 136, 90, 87, 111, 112, 108, 98, 112,
-  52, 106, 90, 101, 126, 97, 84, 107, 86, 117,
-  71, 70, 103, 100, 70, 90, 98, 73, 102, 71,
-  99, 88, 82, 133, 101, 146, 84, 126, 74, 81,
-  92, 136, 92, 101, 109, 63, 178, 113, 99, 118,
-  94, 100, 93, 122, 68, 103, 127, 121, 112, 116,
-  116, 119, 94, 81, 106, 85, 69, 84, 140, 86,
-  109, 107, 74, 126, 206, 117, 105, 82, 92, 103,
-  70, 92, 125, 146, 103, 93, 147, 144, 115, 89,
-  117, 68, 115, 103, 105, 134, 70, 110, 144, 127,
-  94, 149, 148, 113, 140, 129, 110, 102, 127, 87,
-  99, 149, 92, 103, 145, 106, 104, 180, 86, 115,
-  90, 122, 106, 174, 182, 120, 145, 109, 120, 63,
-  142, 85, 113, 80, 164, 122, 88, 121, 78, 154,
-  108, 113, 137, 58, 102, 92, 116, 108, 101, 101,
-  121, 94, 123, 97, 108, 128, 104, 143, 136, 102,
-  91, 97, 121, 119, 88, 65, 92, 97, 111, 137,
-  112, 175, 77, 118, 98, 136, 121, 101, 84, 104,
-  113, 132, 130, 110, 131, 89, 109, 112, 97, 129,
-  149, 137, 109, 94, 115, 131, 94, 119, 86, 114,
-  87, 79, 83, 96, 80, 118, 132, 138, 124, 121,
-  115, 93, 105, 85, 96, 146, 70, 70, 116, 106,
-  93, 126, 116, 114, 88, 122, 99, 203, 102, 112,
-  120, 88, 144, 128, 90, 100, 87, 71, 104, 118,
-  153, 106, 97, 143, 109, 121, 98, 125, 114, 90,
-  112, 135, 107, 99, 124, 140, 117, 143, 128, 120,
-  135, 127, 127, 104, 80, 96, 140, 90, 101, 107,
-  137, 76, 135, 108, 126, 154, 104, 79, 132, 103,
-  118, 103, 109, 95, 106, 82, 91, 117, 152, 105,
-  87, 121, 92, 140, 107, 117, 130, 146, 113, 112,
-  117, 98, 124, 121, 129, 132, 109, 120, 122, 107,
-  119, 119, 118, 115, 121, 131, 141, 133, 87, 117,
-  115, 80, 82, 106, 88, 112, 116, 129, 97, 116,
-  121, 106, 108, 107, 103, 120, 102, 120, 129, 110,
-  135, 91, 114, 135, 135, 105, 105, 119, 120, 115,
-  134, 115, 84, 94, 104, 91, 119, 138, 111, 122,
-  93, 115, 98, 118, 92, 115, 89, 109, 126, 130,
-  96, 126, 95, 137, 130, 76, 124, 124, 136, 147,
-  103, 107, 108, 108, 134, 106, 108, 101, 108, 95,
-  76, 109, 113, 124, 61, 81, 101, 93, 90, 102,
-  90, 104, 144, 80, 101, 101, 119, 94, 109, 123,
-  123, 96, 116, 112, 69, 123, 115, 106, 104, 126,
-  87, 124, 106, 119, 129, 84, 111, 83, 84, 111,
-  94, 102, 180, 107, 118, 130, 96, 116, 125, 160,
-  124, 113, 98, 138, 91, 120, 100, 110, 119, 132,
-  113, 106, 125, 140, 123, 73, 59, 92, 34, 95,
-  128, 99, 108, 99, 123, 71, 114, 130, 66, 104,
-  132, 70, 111, 92, 105, 122, 104, 59, 75, 174,
-  102, 111, 92, 167, 58, 105, 88, 124, 140, 144,
-  85, 104, 94, 109, 118, 114, 119, 117, 105, 96,
-  105, 98, 94, 98, 117, 104, 129, 88, 103, 139,
-  95, 87, 97, 97, 100, 97, 78, 126, 104, 154,
-  92, 105, 129, 107, 98, 85, 102, 122, 119, 114,
-  108, 100, 156, 131, 142, 125, 159, 84, 102, 108,
-  87, 135, 136, 92, 71, 96, 90, 92, 111, 123,
-  105, 101, 108, 151, 95, 86, 75, 117, 70, 109,
-  102, 132, 155, 85, 111, 120, 130, 65, 147, 107,
-  125, 175, 100, 93, 115, 125, 130, 99, 120, 120,
-  116, 95, 114, 148, 114, 135, 83, 65, 114, 71,
-  62, 84, 138, 110, 117, 87, 120, 99, 99, 118,
-  91, 86, 112, 113, 86, 148, 94, 108, 88, 113,
-  93, 83, 87, 124, 94, 110, 114, 86, 119, 89,
-  89, 112, 91, 116, 158, 98, 160, 119, 96, 109,
-  145, 123, 116, 114, 87, 133, 99, 138, 115, 122,
-  108, 117, 126, 86, 106, 71, 121, 94, 62, 105,
-  32, 118, 152, 99, 92, 108, 99, 63, 97, 117,
-  67, 127, 125, 83, 94, 104, 112, 124, 87, 138,
-  72, 206, 99, 132, 102, 117, 65, 64, 85, 130,
-  119, 87, 78, 102, 85, 90, 111, 99, 101, 79,
-  109, 113, 116, 115, 91, 99, 104, 95, 130, 76,
-  85, 117, 94, 97, 108, 83, 125, 67, 111, 124,
-  107, 162, 96, 89, 93, 107, 93, 76, 108, 106,
-  106, 105, 118, 76, 158, 131, 165, 127, 157, 102,
-  106, 176, 73, 110, 118, 98, 82, 99, 92, 107,
-  104, 132, 104, 89, 111, 162, 112, 63, 65, 103,
-  83, 111, 117, 74, 176, 76, 110, 79, 130, 167,
-  109, 109, 82, 193, 126, 89, 129, 154, 125, 93,
-  132, 148, 122, 104, 59, 111, 99, 143, 106, 85,
-  131, 83, 64, 94, 105, 110, 87, 109, 117, 97,
-  115, 146, 89, 67, 94, 110, 74, 77, 141, 90,
-  91, 95, 112, 78, 83, 134, 110, 103, 89, 78,
-  90, 97, 96, 112, 83, 110, 159, 68, 73, 107,
-  80, 87, 121, 138, 93, 79, 64, 91, 64, 70,
-  75, 73, 109, 116, 116, 87, 83, 111, 114, 142,
-  40, 66, 25, 108, 147, 81, 105, 87, 117, 53,
-  88, 119, 63, 103, 113, 112, 66, 94, 99, 73,
-  91, 76, 61, 164, 84, 104, 88, 114, 56, 80,
-  88, 96, 88, 79, 81, 106, 103, 54, 110, 115,
-  68, 68, 92, 95, 93, 87, 72, 87, 55, 78,
-  97, 152, 92, 105, 64, 112, 86, 72, 120, 72,
-  74, 76, 84, 134, 55, 85, 103, 102, 89, 74,
-  109, 98, 119, 88, 88, 56, 121, 84, 107, 109,
-  152, 66, 72, 143, 76, 112, 123, 80, 62, 106,
-  62, 100, 100, 113, 82, 92, 105, 126, 107, 86,
-  48, 92, 78, 101, 60, 101, 88, 94, 95, 100,
-  124, 150, 84, 103, 96, 169, 81, 85, 107, 129,
-  102, 79, 106, 118, 98, 95, 27, 92, 79, 86,
-  53, 52, 96, 71, 37, 116, 59, 100, 86, 66,
-  108, 99, 120, 108, 89, 65, 89, 133, 87, 107,
-  98, 70, 88, 89, 150, 79, 77, 130, 76, 93,
-  76, 75, 57, 74, 103, 99, 71, 91, 175, 84,
-  131, 87, 137, 115, 132, 143, 101, 88, 83, 108,
-  74, 91, 108, 75, 114, 111, 135, 111, 88, 106,
-  109, 82, 48, 106, 70, 115, 167, 100, 108, 82,
-  109, 109, 110, 106, 88, 77, 83, 101, 121, 121,
-  129, 73, 104, 74, 54, 148, 97, 92, 93, 144,
-  66, 78, 86, 95, 110, 81, 121, 93, 92, 77,
-  125, 106, 127, 118, 84, 134, 98, 103, 109, 72,
-  83, 116, 124, 106, 102, 108, 118, 100, 92, 78,
-  89, 89, 64, 95, 91, 148, 73, 95, 121, 76,
-  112, 82, 72, 109, 108, 97, 110, 103, 145, 129,
-  126, 136, 129, 100, 103, 47, 99, 110, 115, 80,
-  84, 112, 77, 88, 96, 100, 131, 92, 103, 118,
-  117, 78, 78, 92, 101, 97, 114, 95, 144, 108,
-  83, 79, 120, 90, 139, 113, 107, 154, 113, 113,
-  105, 110, 83, 96, 119, 101, 98, 112, 106, 117,
-  106, 136, 64, 125, 125, 77, 62, 91, 77, 54,
-  88, 98, 90, 99, 108, 100, 120, 102, 105, 110,
-  89, 94, 111, 85, 94, 91, 116, 86, 79, 145,
-  80, 73, 67, 90, 70, 79, 117, 118, 82, 89,
-  152, 74, 89, 97, 119, 122, 143, 119, 122, 119,
-  91, 104, 83, 107, 109, 95, 112, 124, 108, 92,
-  86, 90, 95, 88, 49, 119, 74, 131, 145, 100,
-  101, 91, 97, 108, 78, 98, 79, 85, 82, 104,
-  103, 130, 132, 90, 108, 83, 66, 123, 114, 106,
-  89, 117, 63, 93, 86, 83, 105, 100, 132, 87,
-  90, 81, 171, 118, 142, 142, 98, 134, 106, 101,
-  99, 56, 110, 129, 133, 78, 96, 103, 153, 110,
-  84, 85, 67, 75, 75, 124, 91, 154, 83, 94,
-  97, 118, 99, 93, 89, 94, 66, 108, 106, 118,
-  150, 124, 115, 143, 128, 103, 109, 115, 106, 101,
-  110, 95, 67, 111, 79, 78, 98, 85, 123, 86,
-  142, 91, 132, 104, 82, 109, 102, 99, 106, 127,
-  149, 94, 98, 98, 104, 84, 130, 103, 113, 107,
-  133, 107, 109, 115, 98, 106, 114, 94, 83, 96,
-  108, 109, 110, 131, 64, 106, 109, 80, 65, 73,
-  92, 68, 98, 94, 85, 87, 90, 112, 112, 94,
-  113, 93, 73, 82, 95, 110, 99, 86, 107, 110,
-  84, 118, 82, 82, 80, 113, 81, 89, 110, 134,
-  107, 112, 111, 55, 114, 101, 79, 89, 140, 93,
-  110, 132, 87, 87, 93, 112, 108, 89, 96, 132,
-  86, 67, 91, 86, 78, 95, 59, 93, 87, 122,
-  109, 87, 87, 104, 67, 84, 54, 107, 68, 88,
-  126, 112, 85, 118, 119, 84, 87, 92, 90, 110,
-  117, 116, 81, 126, 64, 103, 87, 77, 127, 116,
-  116, 99, 87, 91, 136, 134, 70, 87, 91, 120,
-  107, 129, 81, 53, 135, 114, 126, 94, 84, 100,
-  180, 117, 91, 82, 100, 74, 87, 121, 106, 128,
-  79, 108, 106, 143, 91, 96, 97, 85, 75, 103,
-  93, 109, 103, 101, 93, 117, 116, 143, 102, 132,
-  125, 138, 99, 92, 86, 116, 89, 89, 104, 78,
-  96, 83, 128, 71, 145, 87, 68, 94, 114, 99,
-  86, 107, 129, 86, 128, 114, 101, 98, 119, 91,
-  86, 84, 130, 103, 111, 133, 110, 93, 91, 104,
-  92, 109, 69, 125, 77, 100, 115, 68, 77, 106,
-  78, 89, 137, 87, 89, 85, 124, 98, 83, 173,
-  65, 77, 126, 111, 67, 102, 69, 125, 110, 98,
-  117, 143, 92, 87, 110, 74, 86, 134, 71, 111,
-  74, 119, 108, 127, 101, 62, 107, 91, 100, 82,
-  122, 128, 101, 112, 86, 83, 97, 112, 130, 83,
-  91, 114, 99, 80, 114, 109, 82, 90, 68, 105,
-  77, 115, 99, 85, 116, 117, 109, 74, 70, 122,
-  90, 81, 172, 126, 84, 108, 121, 67, 82, 97,
-  108, 95, 125, 124, 90, 134, 83, 130, 89, 116,
-  132, 88, 105, 116, 91, 104, 95, 106, 81, 94,
-  82, 134, 91, 108, 73, 72, 140, 110, 132, 121,
-  71, 123, 120, 116, 103, 87, 120, 98, 75, 80,
-  100, 99, 83, 128, 102, 106, 98, 113, 93, 124,
-  117, 109, 96, 130, 97, 111, 94, 111, 104, 140,
-  100, 94, 115, 150, 109, 106, 76, 123, 96, 92,
-  99, 102, 94, 100, 111, 72, 121, 111, 83, 93,
-  122, 92, 98, 87, 93, 113, 143, 102, 121, 125,
-  123, 106, 87, 77, 95, 114, 123, 119, 116, 80,
-  83, 77, 97, 103, 83, 123, 78, 108, 124, 82,
-  81, 130, 85, 129, 82, 85, 98, 70, 123, 122,
-  120, 125, 68, 95, 120, 116, 88, 119, 45, 112,
-  105, 102, 117, 140, 95, 81, 133, 81, 97, 106,
-  82, 95, 68, 113, 116, 110, 130, 84, 93, 86,
-  149, 123, 136, 141, 113, 97, 85, 96, 112, 113,
-  127, 94, 98, 88, 125, 101, 110, 90, 101, 88,
-  75, 142, 74, 100, 120, 101, 144, 106, 117, 93,
-  100, 101, 93, 97, 114, 90, 94, 109, 130, 83,
-  112, 97, 96, 117, 128, 138, 102, 123, 70, 133,
-  73, 129, 109, 97, 114, 91, 116, 115, 108, 85,
-  124, 140, 103, 108, 84, 97, 86, 88, 131, 116,
-  140, 97, 104, 118, 81, 89, 99, 103, 68, 90,
-  71, 91, 82, 128, 92, 106, 97, 92, 98, 115,
-  67, 133, 136, 106, 119, 154, 140, 91, 118, 115,
-  108, 104, 127, 74, 123, 106, 117, 107, 55, 131,
-  108, 75, 87, 100, 105, 107, 121, 93, 114, 92,
-  111, 77, 95, 83, 118, 65, 101, 130, 104, 92,
-  111, 112, 128, 93, 96, 66, 86, 112, 106, 109,
-  101, 104, 90, 60, 114, 97, 132, 124, 112, 140,
-  71, 103, 106, 103, 90, 116, 37, 81, 96, 88,
-  102, 117, 131, 96, 109, 121, 108, 88, 79, 102,
-  84, 98, 95, 103, 100, 110, 87, 94, 117, 97,
-  87, 82, 98, 95, 86, 135, 110, 97, 140, 101,
-  84, 106, 156, 136, 146, 124, 133, 110, 91, 118,
-  111, 110, 128, 106, 102, 89, 131, 111, 100, 84,
-  116, 88, 58, 163, 84, 113, 138, 96, 126, 86,
-  98, 104, 96, 91, 93, 110, 80, 75, 92, 120,
-  141, 71, 151, 108, 78, 143, 124, 140, 95, 106,
-  74, 107, 79, 110, 98, 103, 90, 98, 115, 103,
-  101, 78, 132, 133, 116, 111, 77, 98, 82, 103,
-  136, 140, 128, 88, 114, 107, 104, 94, 115, 121,
-  42, 82, 83, 109, 74, 147, 87, 83, 114, 111,
-  95, 104, 79, 104, 113, 113, 117, 161, 169, 91,
-  125, 135, 120, 101, 146, 98, 133, 112, 116, 93,
-  86, 137, 103, 77, 75, 91, 119, 88, 125, 126,
-  120, 82, 113, 85, 103, 96, 114, 89, 108, 117,
-  74, 77, 106, 98, 125, 95, 109, 80, 88, 129,
-  109, 106, 97, 119, 111, 63, 122, 105, 143, 142,
-  126, 167, 57, 102, 119, 83, 91, 104, 81, 95,
-  99, 113, 99, 113, 126, 99, 118, 119, 106, 93,
-  66, 75, 115, 96, 82, 94, 118, 108, 79, 103,
-  95, 99, 76, 100, 89, 99, 104, 144, 124, 120,
-  134, 103, 89, 119, 136, 129, 140, 95, 122, 114,
-  112, 119, 111, 111, 125, 111, 113, 105, 127, 103,
-  90, 70, 109, 85, 53, 138, 89, 113, 126, 84,
-  116, 79, 90, 97, 96, 92, 93, 112, 78, 88,
-  85, 116, 146, 62, 158, 112, 84, 144, 118, 144,
-  88, 106, 73, 101, 99, 96, 110, 115, 80, 102,
-  102, 100, 92, 101, 90, 115, 109, 109, 72, 110,
-  64, 92, 119, 139, 109, 100, 115, 110, 113, 100,
-  120, 118, 67, 91, 106, 101, 80, 143, 75, 88,
-  93, 142, 87, 100, 84, 94, 83, 106, 132, 128,
-  158, 89, 112, 143, 115, 97, 147, 117, 149, 131,
-  120, 84, 106, 137, 101, 87, 74, 89, 118, 87,
-  126, 132, 132, 104, 86, 80, 120, 111, 116, 85,
-  101, 108, 76, 82, 121, 111, 118, 94, 105, 83,
-  79, 141, 112, 121, 99, 115, 100, 84, 128, 113,
-  124, 137, 116, 147, 54, 98, 106, 83, 97, 108,
-  91, 100, 100, 124, 93, 104, 117, 109, 92, 105,
-  106, 104, 77, 59, 111, 103, 92, 102, 127, 131,
-  80, 115, 87, 106, 77, 132, 77, 102, 100, 125,
-  108, 115, 129, 94, 94, 117, 116, 119, 103, 82,
-  99, 100, 115, 109, 107, 110, 116, 100, 114, 118,
-  114, 95, 86, 67, 116, 84, 46, 110, 98, 101,
-  105, 68, 109, 74, 102, 87, 94, 88, 98, 101,
-  82, 105, 77, 101, 141, 53, 151, 98, 89, 145,
-  111, 135, 85, 144, 68, 100, 103, 89, 112, 138,
-  67, 94, 103, 101, 101, 112, 63, 94, 98, 118,
-  65, 123, 62, 89, 102, 118, 98, 104, 108, 113,
-  107, 81, 106, 116, 81, 88, 95, 84, 81, 125,
-  75, 97, 85, 140, 90, 93, 77, 84, 88, 87,
-  130, 103, 126, 76, 100, 152, 102, 91, 135, 96,
-  160, 135, 118, 77, 97, 127, 97, 100, 74, 88,
-  100, 96, 121, 126, 128, 122, 60, 70, 116, 104,
-  103, 85, 85, 91, 92, 100, 122, 112, 113, 91,
-  105, 82, 88, 141, 124, 128, 102, 102, 82, 106,
-  133, 113, 111, 116, 91, 113, 50, 80, 87, 81,
-  103, 123, 94, 112, 86, 109, 102, 106, 109, 111,
-  71, 88, 108, 119, 83, 76, 88, 101, 106, 103,
-  115, 145, 85, 124, 88, 91, 89, 137, 64, 98,
-  98, 110, 78, 127, 116, 92, 94, 122, 129, 127,
-  79, 92, 87, 104, 114, 113, 115, 125, 102, 105,
-  101, 124, 123, 107, 96, 68, 123, 91, 47, 123,
-  97, 88, 102, 68, 110, 63, 121, 84, 98, 84,
-  102, 94, 85, 107, 77, 100, 128, 55, 142, 106,
-  101, 151, 104, 132, 103, 160, 68, 108, 100, 110,
-  102, 126, 68, 105, 109, 103, 102, 113, 68, 91,
-  106, 155, 66, 125, 64, 96, 98, 103, 101, 104,
-  104, 120, 104, 56, 98, 123, 101, 94, 89, 96,
-  86, 124, 86, 94, 101, 118, 93, 92, 79, 82,
-  100, 82, 134, 99, 103, 90, 96, 140, 95, 88,
-  122, 75, 153, 120, 114, 103, 103, 118, 111, 104,
-  70, 72, 92, 95, 102, 129, 117, 124, 53, 53,
-  92, 95, 104, 70, 82, 97, 89, 98, 116, 103,
-  124, 95, 111, 71, 92, 150, 125, 118, 103, 98,
-  88, 127, 133, 110, 109, 137, 81, 102, 57, 73,
-  90, 90, 123, 131, 97, 114, 91, 94, 103, 104,
-  103, 119, 78, 61, 102, 126, 67, 85, 101, 107,
-  103, 108, 91, 147, 89, 116, 104, 89, 90, 113,
-  66, 96, 100, 117, 70, 127, 113, 92, 84, 124,
-  149, 147, 80, 113, 93, 107, 102, 117, 109, 148,
-  106, 129, 79, 119, 122, 116, 101, 73, 110, 86,
-  40, 158, 97, 112, 100, 73, 129, 57, 125, 92,
-  102, 74, 101, 102, 84, 99, 86, 108, 117, 69,
-  133, 124, 109, 141, 107, 127, 123, 137, 63, 105,
-  105, 152, 95, 102, 92, 139, 101, 115, 102, 109,
-  93, 100, 112, 175, 74, 114, 63, 97, 111, 106,
-  108, 109, 104, 138, 113, 65, 97, 133, 103, 118,
-  107, 94, 98, 146, 102, 78, 105, 107, 84, 91,
-  76, 115, 91, 101, 149, 117, 96, 100, 110, 127,
-  94, 85, 117, 84, 147, 125, 115, 124, 111, 116,
-  126, 104, 78, 84, 85, 92, 101, 142, 109, 118,
-  52, 54, 71, 106, 110, 64, 77, 99, 60, 80,
-  115, 97, 97, 113, 100, 52, 87, 140, 119, 111,
-  108, 101, 99, 135, 119, 114, 117, 143, 88, 122,
-  68, 88, 89, 90, 148, 127, 89, 90, 99, 88,
-  97, 101, 100, 100, 98, 36, 86, 110, 53, 73,
-  113, 93, 81, 117, 91, 143, 90, 117, 118, 89,
-  85, 86, 73, 107, 103, 138, 66, 106, 118, 95,
-  84, 109, 155, 168, 92, 110, 92, 94, 87, 116,
-  116, 173, 105, 145, 66, 108, 95, 117, 100, 69,
-  112, 82, 38, 172, 102, 134, 95, 82, 161, 81,
-  95, 108, 117, 68, 108, 116, 90, 71, 94, 111,
-  104, 93, 108, 132, 110, 122, 116, 115, 124, 116,
-  55, 85, 102, 191, 89, 103, 116, 143, 104, 124,
-  108, 101, 125, 135, 126, 144, 98, 112, 63, 104,
-  120, 103, 126, 103, 104, 142, 113, 79, 95, 134,
-  71, 123, 134, 111, 101, 173, 117, 72, 89, 103,
-  87, 90, 62, 145, 90, 113, 164, 120, 111, 99,
-  135, 120, 92, 94, 116, 89, 127, 132, 110, 132,
-  84, 111, 126, 105, 92, 111, 75, 80, 104, 148,
-  99, 115, 43, 70, 55, 114, 140, 62, 87, 90,
-  62, 76, 100, 76, 63, 118, 86, 41, 92, 111,
-  108, 104, 99, 105, 99, 145, 103, 108, 122, 125,
-  94, 145, 50, 129, 101, 77, 144, 107, 89, 61,
-  84, 92, 94, 95, 93, 74, 120, 38, 68, 105,
-  50, 54, 125, 62, 73, 126, 89, 126, 87, 137,
-  124, 80, 78, 72, 74, 108, 109, 147, 47, 108,
-  124, 103, 103, 88, 131, 157, 98, 73, 77, 59,
-  88, 97, 154, 182, 102, 158, 82, 101, 82, 93,
-  90, 58, 116, 91, 34, 154, 102, 129, 85, 86,
-  148, 98, 70, 112, 124, 73, 115, 117, 103, 60,
-  84, 92, 99, 109, 92, 138, 102, 105, 102, 113,
-  122, 79, 61, 53, 97, 221, 86, 116, 147, 137,
-  95, 125, 92, 95, 109, 144, 133, 106, 135, 119,
-  76, 94, 98, 93, 116, 90, 99, 123, 87, 78,
-  116, 116, 101, 109, 182, 125, 105, 162, 107, 58,
-  77, 99, 98, 93, 73, 128, 104, 100, 162, 99,
-  106, 131, 140, 123, 86, 91, 101, 132, 99, 99,
-  110, 157, 86, 103, 104, 106, 106, 129, 67, 73,
-  96, 136, 104, 111, 30, 111, 51, 124, 160, 89,
-  114, 82, 68, 53, 90, 108, 52, 102, 78, 51,
-  101, 93, 110, 105, 90, 97, 93, 162, 87, 114,
-  81, 83, 82, 140, 71, 162, 99, 74, 126, 86,
-  102, 52, 66, 97, 97, 92, 105, 81, 121, 58,
-  62, 110, 53, 45, 122, 46, 85, 125, 87, 101,
-  88, 145, 126, 57, 81, 64, 67, 91, 104, 124,
-  44, 119, 117, 100, 94, 83, 80, 107, 74, 73,
-  47, 44, 99, 85, 173, 136, 92, 149, 101, 104,
-  63, 73, 86, 63, 109, 160, 15, 92, 100, 90,
-  79, 59, 95, 96, 96, 102, 129, 99, 100, 79,
-  113, 68, 62, 57, 92, 108, 72, 97, 85, 108,
-  83, 84, 100, 58, 66, 44, 88, 174, 81, 123,
-  132, 111, 106, 84, 93, 109, 56, 107, 131, 98,
-  174, 143, 80, 79, 80, 89, 85, 103, 86, 97,
-  80, 79, 119, 90, 141, 86, 145, 102, 108, 129,
-  68, 57, 92, 93, 112, 83, 122, 113, 104, 85,
-  139, 54, 91, 115, 103, 120, 72, 58, 75, 162,
-  91, 93, 106, 154, 86, 92, 70, 101, 107, 106,
-  67, 84, 79, 101, 106, 114, 11, 131, 51, 110,
-  126, 138, 119, 67, 60, 61, 94, 151, 60, 75,
-  88, 81, 90, 104, 116, 108, 91, 78, 64, 175,
-  72, 113, 39, 65, 45, 97, 81, 128, 71, 83,
-  96, 68, 106, 74, 54, 72, 95, 93, 117, 125,
-  97, 65, 88, 93, 59, 71, 107, 67, 109, 118,
-  84, 99, 85, 129, 114, 49, 92, 61, 48, 66,
-  93, 90, 27, 97, 117, 88, 67, 89, 53, 88,
-  65, 130, 40, 78, 90, 100, 111, 87, 68, 99,
-  136, 111, 60, 69, 89, 128, 92, 177, 8, 47,
-  84, 60, 109, 60, 61, 72, 127, 83, 102, 115,
-  73, 53, 111, 60, 82, 40, 104, 105, 56, 34,
-  66, 125, 94, 82, 53, 97, 74, 33, 78, 90,
-  104, 107, 84, 79, 114, 47, 111, 129, 50, 78,
-  92, 89, 155, 156, 78, 83, 69, 83, 85, 105,
-  86, 63, 77, 89, 91, 81, 124, 111, 50, 83,
-  103, 118, 37, 100, 109, 88, 138, 47, 146, 111,
-  110, 81, 100, 38, 101, 72, 104, 114, 71, 33,
-  62, 98, 110, 94, 109, 98, 58, 90, 53, 89,
-  113, 77, 92, 88, 99, 97, 121, 97, 16, 100,
-  70, 88, 84, 152, 122, 57, 59, 100, 98, 95,
-  78, 75, 106, 104, 47, 96, 112, 131, 109, 71,
-  55, 167, 61, 103, 53, 103, 39, 68, 60, 68,
-  82, 88, 60, 70, 114, 96, 54, 75, 88, 102,
-  99, 133, 67, 60, 126, 82, 77, 115, 98, 76,
-  100, 112, 92, 87, 72, 108, 79, 60, 86, 66,
-  64, 58, 99, 68, 32, 60, 126, 86, 103, 94,
-  72, 122, 128, 131, 76, 106, 79, 147, 75, 134,
-  67, 74, 162, 97, 60, 94, 92, 140, 97, 89,
-  26, 86, 76, 90, 192, 93, 75, 62, 92, 75,
-  98, 112, 67, 100, 87, 53, 116, 76, 141, 110,
-  44, 81, 62, 163, 105, 131, 56, 122, 75, 27,
-  78, 81, 145, 88, 90, 79, 68, 60, 101, 121,
-  110, 89, 84, 107, 116, 123, 106, 79, 103, 104,
-  123, 71, 90, 91, 83, 99, 85, 85, 126, 133,
-  37, 114, 112, 159, 52, 160, 83, 111, 126, 58,
-  117, 107, 120, 95, 75, 58, 154, 120, 188, 119,
-  106, 72, 83, 87, 85, 92, 110, 85, 66, 99,
-  81, 93, 121, 81, 197, 85, 94, 162, 129, 69,
-  45, 96, 95, 94, 96, 105, 184, 66, 81, 70,
-  134, 96, 106, 106, 114, 150, 109, 94, 123, 215,
-  145, 80, 89, 167, 84, 113, 111, 120, 67, 99,
-  128, 86, 168, 89, 73, 90, 130, 97, 73, 134,
-  84, 105, 82, 115, 77, 70, 118, 72, 121, 109,
-  110, 82, 71, 90, 89, 88, 80, 102, 88, 73,
-  73, 67, 114, 85, 113, 99, 86, 86, 128, 107,
-  110, 117, 60, 123, 149, 92, 90, 111, 73, 161,
-  95, 132, 97, 97, 173, 99, 76, 125, 106, 61,
-  93, 101, 31, 106, 82, 83, 197, 99, 99, 90,
-  73, 75, 103, 110, 73, 158, 93, 92, 92, 95,
-  140, 97, 48, 147, 59, 152, 110, 151, 61, 91,
-  82, 50, 72, 81, 112, 100, 94, 112, 103, 52,
-  98, 98, 126, 86, 111, 127, 99, 103, 117, 115,
-  133, 108, 151, 93, 58, 97, 109, 139, 88, 69,
-  98, 98, 67, 124, 101, 154, 47, 136, 49, 128,
-  106, 70, 78, 73, 105, 114, 81, 59, 153, 103,
-  177, 117, 142, 107, 87, 171, 95, 117, 111, 75,
-  77, 110, 110, 102, 119, 104, 216, 82, 80, 159,
-  127, 98, 58, 132, 123, 115, 86, 79, 157, 91,
-  116, 83, 126, 149, 85, 107, 124, 170, 172, 89,
-  135, 227, 163, 88, 103, 156, 95, 113, 87, 98,
-  87, 111, 107, 72, 176, 88, 72, 119, 108, 131,
-  105, 151, 101, 99, 102, 115, 78, 76, 108, 90,
-  151, 76, 109, 127, 60, 71, 96, 118, 87, 83,
-  91, 106, 92, 89, 132, 81, 100, 121, 109, 111,
-  117, 140, 120, 119, 43, 96, 117, 126, 75, 86,
-  56, 128, 136, 93, 112, 115, 196, 136, 69, 114,
-  99, 66, 77, 85, 21, 87, 75, 53, 128, 87,
-  84, 144, 105, 76, 84, 129, 75, 116, 122, 110,
-  92, 66, 114, 91, 52, 127, 85, 101, 101, 129,
-  33, 147, 103, 78, 96, 77, 101, 134, 91, 118,
-  86, 44, 95, 108, 82, 59, 111, 108, 112, 122,
-  98, 105, 113, 104, 137, 112, 54, 88, 140, 143,
-  89, 70, 88, 95, 110, 85, 91, 121, 36, 112,
-  87, 146, 109, 64, 82, 81, 98, 113, 100, 28,
-  121, 81, 105, 112, 147, 88, 69, 152, 102, 90,
-  120, 76, 90, 101, 104, 87, 131, 123, 169, 108,
-  77, 109, 134, 123, 64, 156, 103, 113, 61, 107,
-  116, 95, 108, 106, 106, 87, 69, 83, 141, 147,
-  122, 76, 114, 172, 148, 97, 67, 138, 70, 109,
-  56, 107, 67, 94, 89, 67, 108, 96, 56, 113,
-  97, 133, 111, 118, 104, 92, 123, 124, 62, 90,
-  114, 116, 158, 82, 83, 146, 92, 87, 100, 134,
-  92, 75, 94, 102, 107, 115, 120, 60, 84, 90,
-  104, 92, 107, 112, 111, 104, 56, 76, 108, 131,
-  66, 90, 49, 97, 119, 110, 114, 120, 150, 145,
-  46, 77, 73, 89, 48, 125, 23, 85, 107, 69,
-  88, 61, 43, 94, 108, 106, 64, 116, 73, 94,
-  138, 96, 118, 43, 94, 129, 46, 115, 111, 80,
-  78, 99, 15, 172, 92, 89, 84, 84, 109, 114,
-  112, 82, 92, 45, 85, 125, 78, 64, 105, 101,
-  128, 176, 119, 52, 110, 101, 113, 90, 69, 70,
-  146, 102, 84, 85, 89, 119, 106, 82, 86, 112,
-  36, 137, 124, 138, 135, 52, 91, 133, 99, 81,
-  92, 36, 122, 81, 87, 121, 129, 70, 70, 113,
-  108, 87, 97, 102, 77, 74, 78, 104, 125, 102,
-  123, 117, 91, 80, 142, 120, 47, 112, 72, 86,
-  74, 110, 142, 36, 111, 146, 79, 70, 92, 59,
-  118, 122, 81, 89, 110, 170, 122, 113, 49, 158,
-  66, 117, 44, 135, 56, 90, 94, 84, 84, 102,
-  82, 101, 83, 99, 78, 62, 85, 105, 89, 164,
-  55, 66, 117, 102, 116, 78, 94, 138, 148, 104,
-  49, 163, 97, 86, 118, 100, 119, 147, 92, 66,
-  87, 73, 85, 70, 107, 69, 113, 64, 47, 81,
-  94, 106, 80, 126, 50, 74, 77, 119, 98, 92,
-  114, 134, 40, 51, 54, 95, 74, 135, 27, 63,
-  96, 87, 88, 75, 56, 85, 70, 105, 53, 122,
-  85, 108, 151, 108, 90, 50, 95, 131, 51, 76,
-  123, 86, 106, 97, 20, 126, 88, 90, 65, 88,
-  110, 106, 126, 94, 90, 76, 103, 115, 64, 75,
-  67, 113, 119, 145, 101, 53, 84, 102, 101, 104,
-  81, 87, 87, 97, 99, 90, 112, 103, 54, 91,
-  96, 94, 38, 171, 134, 99, 112, 59, 117, 144,
-  141, 93, 65, 52, 91, 73, 84, 113, 95, 88,
-  54, 94, 93, 128, 98, 98, 65, 63, 67, 116,
-  140, 82, 97, 100, 101, 69, 124, 95, 37, 88,
-  76, 72, 85, 106, 113, 31, 138, 169, 79, 92,
-  83, 73, 86, 100, 62, 88, 111, 159, 119, 80,
-  38, 166, 77, 118, 44, 124, 37, 66, 97, 88,
-  70, 105, 84, 122, 89, 61, 65, 65, 109, 115,
-  70, 144, 44, 57, 99, 136, 105, 106, 78, 89,
-  154, 123, 74, 172, 97, 101, 120, 92, 109, 147,
-  57, 91, 91, 60, 94, 93, 119, 63, 88, 91,
-  93, 116, 100, 123, 100, 95, 67, 91, 71, 117,
-  90, 64, 85, 117, 78, 72, 87, 91, 98, 92,
-  34, 122, 107, 83, 93, 94, 114, 112, 66, 104,
-  109, 139, 78, 103, 126, 93, 99, 90, 105, 114,
-  68, 69, 130, 132, 142, 127, 79, 111, 107, 147,
-  73, 126, 136, 104, 120, 92, 107, 126, 110, 97,
-  91, 101, 86, 126, 99, 93, 97, 92, 81, 134,
-  126, 117, 78, 115, 46, 87, 134, 86, 151, 100,
-  21, 104, 103, 90, 64, 150, 138, 81, 96, 104,
-  114, 144, 185, 114, 99, 114, 92, 105, 114, 112,
-  77, 130, 59, 63, 114, 91, 100, 126, 68, 75,
-  97, 128, 134, 80, 109, 115, 81, 86, 90, 102,
-  55, 72, 72, 75, 105, 84, 113, 94, 128, 138,
-  104, 97, 118, 114, 105, 87, 90, 107, 90, 119,
-  117, 87, 63, 102, 72, 111, 107, 125, 60, 86,
-  79, 122, 72, 103, 110, 135, 98, 71, 78, 108,
-  145, 102, 94, 114, 63, 104, 88, 167, 122, 142,
-  47, 77, 123, 136, 87, 152, 76, 112, 110, 100,
-  105, 100, 68, 112, 101, 84, 112, 114, 114, 98,
-  173, 107, 161, 161, 117, 118, 128, 79, 116, 114,
-  108, 122, 112, 82, 93, 100, 105, 91, 117, 56,
-  143, 68, 42, 163, 109, 95, 122, 99, 140, 105,
-  81, 97, 147, 136, 106, 117, 103, 42, 94, 102,
-  130, 118, 102, 110, 102, 183, 139, 155, 128, 87,
-  84, 141, 95, 127, 111, 106, 113, 111, 119, 150,
-  113, 76, 117, 129, 122, 106, 107, 101, 98, 113,
-  99, 155, 148, 63, 94, 122, 78, 93, 159, 93,
-  141, 104, 60, 124, 101, 111, 95, 113, 111, 99,
-  89, 127, 110, 130, 166, 131, 108, 150, 119, 146,
-  133, 117, 109, 111, 97, 92, 135, 98, 119, 123,
-  71, 87, 144, 126, 131, 87, 128, 103, 108, 111,
-  89, 92, 79, 57, 83, 88, 143, 68, 142, 141,
-  90, 61, 137, 123, 146, 122, 103, 83, 105, 116,
-  101, 106, 87, 105, 105, 59, 114, 102, 156, 129,
-  100, 139, 59, 158, 102, 92, 129, 102, 97, 81,
-  94, 137, 119, 83, 110, 123, 82, 135, 89, 111,
-  118, 73, 82, 69, 105, 145, 105, 91, 75, 134,
-  88, 99, 63, 85, 106, 139, 116, 95, 170, 124,
-  109, 124, 101, 102, 137, 151, 103, 117, 139, 110,
-  107, 115, 89, 100, 110, 106, 120, 84, 78, 87,
-  120, 58, 122, 95, 32, 132, 88, 124, 119, 89,
-  96, 81, 115, 70, 115, 133, 115, 105, 108, 78,
-  67, 94, 138, 108, 125, 138, 89, 181, 97, 124,
-  128, 99, 88, 121, 133, 91, 102, 125, 79, 103,
-  99, 107, 114, 95, 85, 94, 109, 88, 125, 141,
-  87, 104, 94, 152, 134, 83, 105, 144, 116, 106,
-  144, 94, 132, 87, 63, 94, 98, 107, 80, 103,
-  99, 156, 95, 122, 110, 95, 116, 116, 104, 116,
-  107, 146, 103, 100, 118, 62, 108, 136, 117, 111,
-  128, 66, 76, 96, 135, 116, 105, 62, 117, 91,
-  143, 106, 108, 112, 68, 78, 126, 107, 115, 91,
-  110, 131, 80, 77, 188, 166, 92, 111, 102, 84,
-  98, 113, 118, 109, 81, 92, 132, 83, 94, 107,
-  117, 108, 88, 114, 49, 122, 92, 90, 112, 100,
-  81, 102, 87, 119, 80, 80, 116, 91, 64, 106,
-  93, 76, 102, 68, 98, 68, 85, 140, 111, 118,
-  79, 138, 68, 84, 78, 117, 95, 109, 107, 64,
-  174, 121, 97, 128, 126, 107, 80, 134, 75, 122,
-  123, 128, 106, 117, 98, 117, 99, 114, 103, 86,
-  56, 85, 116, 39, 102, 85, 41, 128, 131, 115,
-  105, 73, 77, 96, 123, 88, 128, 113, 111, 74,
-  116, 122, 74, 77, 121, 91, 109, 123, 98, 173,
-  84, 118, 133, 125, 99, 139, 152, 103, 120, 121,
-  83, 95, 108, 89, 113, 143, 70, 87, 117, 90,
-  121, 165, 108, 107, 98, 122, 112, 116, 116, 122,
-  134, 75, 107, 88, 140, 83, 77, 70, 133, 124,
-  81, 108, 94, 160, 92, 92, 110, 73, 99, 81,
-  128, 95, 110, 124, 107, 85, 111, 65, 107, 124,
-  115, 92, 140, 87, 96, 99, 123, 127, 81, 56,
-  87, 82, 140, 133, 113, 146, 50, 75, 117, 123,
-  97, 60, 106, 93, 96, 118, 146, 131, 99, 93,
-  92, 106, 100, 128, 126, 134, 89, 98, 138, 140,
-  94, 104, 77, 112, 64, 87, 52, 87, 79, 110,
-  114, 103, 92, 122, 91, 95, 110, 67, 91, 135,
-  54, 48, 109, 73, 78, 94, 108, 103, 95, 151,
-  80, 173, 94, 114, 93, 76, 111, 134, 81, 95,
-  101, 53, 124, 100, 111, 114, 94, 121, 78, 129,
-  81, 118, 113, 116, 101, 130, 125, 150, 80, 65,
-  115, 92, 65, 95, 136, 86, 116, 101, 81, 148,
-  202, 120, 96, 96, 107, 111, 66, 122, 153, 116,
-  103, 93, 137, 125, 126, 104, 116, 52, 94, 104,
-  109, 137, 97, 131, 144, 108, 105, 132, 127, 140,
-  147, 97, 137, 118, 101, 122, 102, 146, 105, 123,
-  137, 114, 101, 140, 83, 104, 98, 107, 106, 169,
-  192, 128, 143, 106, 116, 68, 148, 83, 101, 89,
-  162, 152, 91, 106, 97, 121, 116, 107, 135, 78,
-  125, 95, 117, 116, 115, 100, 144, 104, 110, 107,
-  101, 122, 96, 135, 135, 118, 101, 100, 126, 109,
-  92, 93, 93, 96, 86, 158, 114, 166, 65, 113,
-  91, 141, 127, 105, 90, 78, 98, 107, 104, 117,
-  168, 114, 98, 123, 99, 161, 148, 165, 128, 100,
-  122, 169, 96, 125, 85, 126, 80, 87, 89, 112,
-  87, 119, 150, 137, 118, 113, 117, 113, 110, 73,
-  82, 130, 77, 64, 117, 108, 82, 126, 126, 105,
-  95, 138, 95, 195, 112, 116, 141, 84, 127, 123,
-  95, 107, 95, 87, 116, 112, 163, 107, 110, 119,
-  115, 139, 110, 113, 133, 95, 130, 123, 108, 104,
-  140, 141, 114, 122, 127, 114, 141, 123, 133, 101,
-  86, 98, 124, 109, 128, 109, 138, 79, 127, 122,
-  121, 158, 116, 75, 106, 112, 130, 107, 117, 97,
-  118, 77, 80, 115, 125, 93, 108, 121, 92, 140,
-  119, 109, 130, 151, 110, 96, 127, 92, 129, 124,
-  145, 147, 107, 116, 121, 119, 113, 115, 121, 130,
-  121, 117, 142, 128, 84, 117, 118, 92, 75, 122,
-  102, 123, 114, 122, 93, 114, 114, 112, 106, 108,
-  103, 121, 92, 110, 133, 124, 144, 112, 122, 121,
-  129, 101, 124, 111, 116, 106, 138, 110, 76, 102,
-  106, 83, 109, 118, 114, 111, 113, 117, 91, 106,
-  98, 121, 91, 99, 138, 118, 119, 137, 108, 139,
-  124, 74, 127, 112, 124, 151, 93, 116, 109, 99,
-  106, 114, 145, 85, 121, 94, 93, 100, 118, 121,
-  53, 98, 113, 96, 94, 101, 84, 96, 150, 91,
-  95, 100, 123, 100, 118, 129, 120, 98, 118, 105,
-  75, 117, 117, 110, 95, 109, 90, 144, 103, 105,
-  122, 83, 104, 85, 85, 101, 102, 108, 181, 102,
-  118, 108, 86, 123, 122, 131, 138, 128, 103, 117,
-  83, 117, 114, 111, 111, 116, 112, 96, 120, 137,
-  125, 86, 66, 79, 31, 109, 137, 90, 92, 83,
-  131, 75, 92, 129, 72, 97, 110, 83, 112, 86,
-  106, 134, 120, 50, 61, 167, 95, 93, 99, 132,
-  59, 98, 101, 112, 147, 157, 75, 96, 98, 94,
-  120, 128, 112, 110, 102, 100, 110, 103, 92, 102,
-  111, 115, 117, 98, 100, 132, 98, 95, 98, 95,
-  99, 101, 81, 133, 105, 143, 84, 102, 127, 121,
-  94, 82, 99, 118, 104, 98, 106, 109, 144, 131,
-  138, 117, 145, 76, 113, 127, 90, 118, 139, 88,
-  65, 103, 80, 84, 106, 100, 107, 91, 121, 153,
-  97, 78, 75, 122, 62, 118, 105, 138, 151, 83,
-  110, 124, 121, 67, 135, 102, 118, 180, 104, 80,
-  117, 123, 111, 98, 133, 116, 123, 87, 108, 140,
-  108, 116, 86, 62, 117, 78, 65, 94, 147, 115,
-  114, 81, 121, 92, 97, 120, 94, 83, 110, 100,
-  88, 148, 88, 99, 96, 108, 93, 82, 91, 135,
-  88, 97, 106, 88, 104, 95, 85, 95, 92, 124,
-  153, 98, 169, 121, 86, 102, 143, 122, 116, 117,
-  86, 129, 93, 139, 118, 126, 105, 118, 131, 86,
-  116, 70, 123, 92, 66, 101, 32, 118, 150, 96,
-  84, 108, 104, 70, 95, 125, 71, 126, 128, 82,
-  98, 102, 108, 130, 86, 140, 74, 201, 109, 128,
-  101, 109, 74, 73, 96, 125, 130, 93, 70, 102,
-  84, 89, 102, 109, 92, 75, 110, 121, 117, 124,
-  83, 112, 95, 99, 125, 84, 86, 120, 89, 106,
-  113, 80, 126, 69, 101, 123, 106, 158, 90, 95,
-  101, 115, 96, 73, 112, 108, 100, 100, 117, 76,
-  151, 123, 161, 128, 153, 106, 110, 175, 75, 109,
-  118, 94, 82, 105, 92, 109, 101, 126, 115, 92,
-  107, 171, 110, 67, 67, 103, 86, 121, 124, 80,
-  181, 75, 115, 71, 136, 174, 103, 118, 86, 204,
-  133, 80, 135, 155, 126, 88, 136, 160, 128, 102,
-  59, 113, 93, 136, 118, 81, 131, 88, 75, 101,
-  114, 115, 94, 107, 114, 95, 117, 146, 91, 69,
-  104, 106, 79, 79, 139, 92, 92, 92, 110, 76,
-  82, 130, 107, 110, 79, 91, 86, 105, 100, 103,
-  91, 113, 159, 73, 78, 111, 72, 85, 111, 143,
-  92, 86, 60, 99, 62, 68, 78, 74, 106, 113,
-  111, 89, 99, 101, 112, 135, 40, 64, 25, 101,
-  138, 78, 103, 92, 113, 60, 95, 125, 63, 108,
-  115, 119, 70, 89, 90, 83, 90, 86, 63, 166,
-  91, 109, 94, 119, 64, 91, 91, 91, 94, 77,
-  72, 101, 101, 62, 106, 122, 59, 68, 91, 98,
-  94, 93, 72, 94, 58, 82, 97, 151, 91, 109,
-  61, 110, 90, 82, 117, 71, 72, 77, 81, 134,
-  52, 83, 99, 112, 80, 69, 112, 100, 111, 92,
-  92, 57, 125, 71, 109, 106, 156, 74, 81, 134,
-  70, 108, 125, 85, 67, 101, 60, 99, 97, 117,
-  87, 93, 99, 136, 101, 88, 48, 87, 80, 107,
-  65, 93, 96, 90, 98, 97, 128, 151, 82, 108,
-  107, 180, 95, 82, 118, 128, 107, 80, 109, 127,
-  107, 91, 28, 84, 74, 85, 59, 44, 96, 75,
-  41, 116, 56, 107, 94, 61, 107, 95, 127, 105,
-  92, 68, 95, 135, 85, 109, 88, 75, 82, 96,
-  136, 87, 74, 124, 73, 98, 81, 83, 64, 80,
-  106, 93, 71, 89, 179, 94, 133, 91, 121, 120,
-  118, 137, 103, 99, 84, 117, 84, 93, 113, 74,
-  105, 109, 129, 114, 110, 99, 109, 83, 55, 110,
-  80, 103, 163, 95, 113, 89, 99, 130, 121, 115,
-  82, 80, 81, 117, 129, 118, 120, 96, 99, 81,
-  54, 150, 90, 103, 106, 143, 70, 85, 80, 96,
-  110, 74, 117, 81, 101, 89, 131, 113, 120, 130,
-  92, 141, 101, 111, 114, 76, 98, 127, 127, 110,
-  97, 113, 103, 87, 92, 96, 93, 87, 75, 106,
-  93, 145, 71, 87, 108, 80, 106, 81, 70, 99,
-  107, 92, 124, 113, 154, 123, 130, 126, 130, 114,
-  113, 44, 87, 106, 115, 100, 82, 106, 77, 89,
-  93, 104, 125, 89, 98, 123, 99, 84, 76, 93,
-  98, 100, 123, 85, 159, 102, 97, 88, 115, 83,
-  136, 119, 114, 164, 131, 108, 110, 106, 85, 105,
-  132, 106, 100, 106, 100, 103, 96, 137, 59, 116,
-  119, 79, 71, 93, 81, 61, 100, 99, 94, 98,
-  110, 96, 128, 106, 100, 113, 91, 80, 94, 98,
-  96, 98, 97, 91, 74, 146, 82, 70, 80, 89,
-  74, 91, 112, 112, 87, 93, 151, 84, 89, 97,
-  99, 122, 132, 103, 113, 138, 86, 109, 89, 105,
-  121, 97, 84, 115, 103, 98, 99, 97, 103, 90,
-  52, 108, 83, 114, 143, 92, 114, 85, 98, 117,
-  81, 104, 71, 87, 81, 107, 98, 128, 111, 112,
-  94, 79, 72, 112, 102, 119, 103, 100, 68, 98,
-  90, 95, 106, 121, 115, 70, 98, 95, 171, 142,
-  124, 149, 93, 134, 115, 103, 112, 72, 117, 124,
-  131, 92, 74, 109, 121, 92, 80, 102, 87, 87,
-  79, 134, 95, 133, 75, 87, 97, 127, 99, 96,
-  88, 87, 71, 105, 122, 123, 149, 126, 115, 132,
-  120, 104, 117, 128, 101, 97, 112, 107, 67, 106,
-  69, 99, 102, 94, 99, 84, 142, 90, 115, 106,
-  64, 102, 93, 111, 108, 129, 149, 92, 115, 123,
-  95, 64, 130, 110, 107, 105, 142, 98, 108, 114,
-  95, 114, 123, 98, 78, 98, 86, 109, 94, 119,
-  63, 95, 103, 79, 74, 85, 114, 75, 104, 89,
-  97, 92, 94, 111, 119, 90, 102, 97, 79, 85,
-  76, 103, 109, 89, 107, 112, 81, 124, 86, 80,
-  89, 101, 87, 108, 97, 124, 100, 122, 108, 76,
-  142, 106, 55, 88, 115, 111, 111, 143, 77, 108,
-  111, 114, 113, 83, 74, 109, 100, 71, 105, 90,
-  105, 81, 62, 74, 89, 107, 121, 96, 106, 108,
-  77, 87, 53, 122, 80, 101, 152, 101, 89, 124,
-  115, 94, 76, 99, 115, 108, 107, 125, 104, 116,
-  86, 104, 98, 105, 141, 143, 104, 100, 89, 106,
-  122, 148, 52, 78, 83, 116, 112, 125, 78, 98,
-  132, 97, 120, 116, 68, 97, 119, 103, 95, 82,
-  131, 77, 86, 114, 113, 110, 80, 94, 112, 140,
-  73, 112, 111, 92, 83, 100, 98, 93, 89, 105,
-  94, 119, 117, 130, 99, 125, 105, 153, 112, 88,
-  99, 120, 91, 110, 115, 91, 83, 97, 125, 89,
-  118, 72, 71, 89, 115, 127, 98, 113, 133, 95,
-  135, 111, 99, 107, 116, 107, 72, 100, 136, 100,
-  116, 146, 120, 84, 97, 119, 102, 120, 60, 123,
-  59, 84, 159, 76, 71, 123, 87, 109, 136, 112,
-  94, 98, 132, 94, 120, 181, 74, 87, 109, 106,
-  81, 114, 76, 121, 108, 93, 137, 129, 95, 93,
-  113, 74, 80, 105, 81, 131, 69, 112, 105, 140,
-  99, 74, 93, 92, 95, 98, 115, 156, 106, 100,
-  85, 104, 111, 114, 163, 87, 80, 92, 97, 95,
-  109, 127, 110, 99, 69, 119, 77, 114, 126, 91,
-  135, 141, 129, 76, 79, 124, 104, 88, 194, 103,
-  83, 127, 133, 85, 82, 108, 110, 95, 112, 115,
-  107, 139, 91, 99, 95, 140, 124, 83, 99, 105,
-  107, 112, 103, 104, 104, 105, 101, 122, 96, 111,
-  83, 112, 140, 91, 133, 119, 64, 126, 88, 111,
-  101, 81, 116, 73, 79, 91, 101, 88, 83, 117,
-  114, 97, 100, 126, 134, 121, 139, 112, 102, 105,
-  105, 106, 88, 119, 122, 136, 106, 98, 109, 160,
-  115, 86, 63, 123, 113, 109, 106, 113, 90, 120,
-  119, 86, 102, 119, 83, 98, 117, 100, 102, 103,
-  95, 134, 122, 93, 98, 125, 118, 106, 70, 92,
-  110, 114, 133, 130, 120, 88, 113, 83, 93, 111,
-  86, 115, 86, 107, 102, 94, 92, 140, 84, 149,
-  55, 100, 112, 92, 124, 116, 159, 121, 90, 103,
-  114, 114, 100, 132, 62, 123, 100, 92, 126, 115,
-  101, 95, 122, 102, 81, 77, 101, 104, 66, 104,
-  108, 115, 130, 90, 99, 82, 153, 152, 141, 130,
-  118, 100, 103, 109, 109, 117, 131, 100, 97, 91,
-  107, 109, 95, 120, 124, 77, 75, 159, 89, 103,
-  143, 103, 129, 118, 115, 87, 86, 103, 102, 99,
-  113, 72, 97, 122, 146, 91, 122, 98, 79, 131,
-  126, 123, 88, 125, 70, 101, 85, 122, 113, 95,
-  115, 99, 108, 104, 110, 78, 131, 132, 113, 118,
-  82, 108, 110, 95, 134, 122, 137, 85, 99, 131,
-  85, 93, 101, 105, 71, 70, 71, 101, 95, 130,
-  91, 118, 127, 108, 107, 111, 93, 125, 139, 103,
-  115, 140, 132, 108, 98, 126, 122, 114, 127, 84,
-  162, 119, 116, 81, 76, 122, 130, 85, 89, 95,
-  125, 105, 126, 104, 112, 99, 107, 68, 120, 87,
-  127, 81, 102, 145, 91, 78, 104, 93, 121, 100,
-  82, 86, 103, 108, 110, 116, 99, 108, 102, 66,
-  105, 97, 126, 148, 125, 140, 67, 109, 123, 97,
-  102, 116, 45, 75, 107, 122, 102, 128, 135, 106,
-  115, 120, 102, 94, 90, 103, 96, 116, 110, 98,
-  108, 108, 91, 115, 117, 100, 78, 90, 104, 105,
-  82, 128, 105, 104, 130, 94, 80, 112, 154, 138,
-  143, 93, 118, 112, 90, 108, 101, 111, 118, 106,
-  107, 109, 111, 104, 96, 72, 110, 93, 54, 157,
-  92, 104, 130, 87, 101, 84, 97, 86, 80, 96,
-  87, 113, 82, 79, 72, 113, 145, 82, 151, 110,
-  75, 156, 129, 134, 80, 105, 74, 115, 98, 99,
-  97, 124, 83, 105, 105, 89, 108, 92, 100, 110,
-  120, 128, 83, 122, 100, 97, 124, 140, 122, 99,
-  108, 121, 103, 87, 121, 116, 69, 68, 70, 93,
-  91, 137, 86, 100, 103, 144, 94, 98, 79, 98,
-  104, 99, 112, 136, 140, 103, 86, 147, 114, 103,
-  131, 118, 175, 120, 119, 83, 106, 124, 113, 94,
-  76, 75, 120, 82, 122, 116, 121, 106, 89, 67,
-  117, 102, 110, 78, 98, 116, 89, 84, 113, 110,
-  115, 105, 103, 80, 106, 132, 109, 115, 97, 111,
-  98, 87, 106, 101, 119, 145, 117, 143, 62, 90,
-  110, 87, 110, 110, 89, 102, 96, 116, 98, 128,
-  107, 113, 104, 97, 92, 102, 75, 76, 107, 99,
-  109, 92, 109, 135, 84, 112, 111, 110, 83, 125,
-  88, 100, 91, 133, 113, 115, 112, 96, 96, 124,
-  128, 108, 107, 88, 93, 106, 99, 108, 100, 114,
-  106, 104, 99, 113, 113, 96, 107, 63, 115, 89,
-  49, 125, 103, 96, 107, 72, 105, 88, 99, 89,
-  92, 97, 94, 101, 88, 93, 65, 97, 132, 66,
-  142, 98, 96, 164, 123, 125, 90, 118, 76, 120,
-  105, 97, 107, 125, 76, 111, 110, 101, 109, 115,
-  49, 90, 113, 130, 80, 145, 83, 90, 106, 120,
-  115, 110, 107, 123, 111, 73, 119, 114, 101, 83,
-  71, 81, 95, 127, 88, 98, 96, 149, 90, 97,
-  90, 91, 85, 89, 126, 105, 119, 88, 84, 152,
-  106, 92, 131, 97, 165, 116, 123, 89, 115, 127,
-  103, 113, 73, 72, 103, 90, 106, 120, 121, 129,
-  65, 56, 106, 105, 99, 65, 74, 100, 100, 105,
-  117, 111, 112, 110, 107, 72, 87, 135, 116, 123,
-  100, 102, 79, 120, 121, 109, 104, 140, 86, 114,
-  73, 85, 86, 91, 121, 128, 96, 119, 84, 93,
-  101, 121, 104, 124, 82, 71, 83, 111, 72, 70,
-  98, 95, 112, 103, 112, 154, 89, 114, 117, 109,
-  91, 127, 76, 91, 101, 109, 95, 107, 110, 92,
-  87, 118, 130, 124, 98, 110, 78, 104, 104, 103,
-  104, 137, 104, 92, 92, 110, 114, 101, 115, 71,
-  115, 98, 52, 117, 98, 91, 106, 64, 118, 80,
-  122, 88, 102, 84, 109, 87, 88, 97, 70, 97,
-  120, 54, 126, 98, 98, 166, 120, 121, 101, 140,
-  74, 115, 99, 130, 103, 117, 85, 108, 120, 109,
-  110, 123, 64, 99, 101, 123, 75, 137, 81, 89,
-  98, 96, 117, 106, 103, 131, 109, 56, 108, 115,
-  113, 90, 67, 77, 92, 121, 96, 97, 104, 118,
-  94, 94, 91, 93, 100, 84, 125, 104, 113, 97,
-  105, 131, 97, 90, 125, 72, 151, 110, 119, 117,
-  102, 134, 106, 111, 67, 80, 92, 100, 87, 124,
-  114, 129, 50, 46, 86, 103, 109, 64, 68, 97,
-  101, 103, 112, 105, 127, 111, 110, 67, 88, 134,
-  123, 124, 104, 91, 81, 132, 124, 111, 104, 135,
-  75, 89, 56, 99, 91, 94, 125, 124, 92, 111,
-  84, 86, 106, 113, 113, 109, 83, 59, 72, 113,
-  66, 94, 98, 85, 113, 107, 95, 138, 92, 126,
-  127, 98, 97, 97, 77, 92, 107, 122, 79, 113,
-  109, 95, 92, 121, 147, 158, 111, 123, 85, 121,
-  100, 109, 110, 167, 105, 95, 93, 104, 127, 116,
-  105, 81, 122, 93, 58, 145, 89, 102, 117, 75,
-  129, 71, 130, 95, 97, 66, 115, 97, 82, 88,
-  82, 114, 122, 45, 119, 118, 87, 164, 124, 128,
-  117, 114, 76, 105, 93, 144, 95, 101, 98, 139,
-  116, 121, 102, 111, 90, 118, 95, 134, 79, 107,
-  75, 93, 102, 96, 121, 99, 106, 137, 125, 63,
-  103, 118, 109, 96, 78, 97, 91, 144, 108, 95,
-  123, 97, 95, 100, 92, 101, 109, 99, 124, 125,
-  116, 113, 122, 119, 100, 78, 127, 87, 149, 110,
-  122, 130, 111, 139, 125, 101, 66, 79, 103, 98,
-  82, 143, 125, 106, 53, 51, 74, 94, 123, 62,
-  75, 98, 74, 73, 102, 111, 142, 115, 97, 62,
-  99, 137, 126, 128, 110, 96, 98, 140, 129, 112,
-  106, 143, 91, 101, 58, 115, 114, 100, 137, 114,
-  91, 87, 98, 98, 100, 106, 110, 112, 96, 46,
-  73, 105, 54, 88, 122, 82, 98, 110, 102, 122,
-  96, 129, 131, 104, 87, 79, 85, 105, 120, 150,
-  89, 117, 113, 79, 83, 120, 155, 168, 107, 116,
-  94, 114, 84, 112, 100, 166, 103, 113, 82, 105,
-  116, 126, 91, 79, 112, 88, 52, 163, 90, 129,
-  119, 83, 128, 63, 114, 101, 97, 55, 111, 102,
-  83, 89, 91, 123, 123, 39, 135, 118, 71, 153,
-  130, 120, 112, 104, 62, 87, 100, 136, 93, 101,
-  100, 163, 103, 116, 102, 100, 118, 119, 102, 151,
-  77, 94, 67, 92, 112, 97, 119, 99, 104, 137,
-  142, 86, 90, 117, 91, 110, 95, 94, 99, 168,
-  117, 76, 107, 94, 86, 88, 88, 120, 99, 116,
-  130, 140, 121, 99, 119, 112, 96, 81, 128, 96,
-  154, 136, 125, 119, 120, 140, 127, 88, 74, 88,
-  104, 87, 87, 146, 115, 94, 66, 71, 63, 99,
-  112, 68, 74, 100, 53, 71, 98, 108, 121, 112,
-  84, 53, 85, 127, 124, 122, 111, 101, 99, 131,
-  127, 102, 113, 128, 106, 125, 67, 105, 111, 90,
-  148, 112, 88, 73, 102, 93, 94, 112, 95, 107,
-  112, 32, 83, 102, 53, 79, 132, 91, 78, 109,
-  107, 132, 92, 123, 131, 110, 82, 83, 97, 111,
-  125, 180, 77, 108, 112, 64, 74, 107, 160, 163,
-  111, 107, 106, 103, 83, 107, 92, 162, 98, 144,
-  71, 110, 100, 129, 83, 79, 97, 79, 50, 154,
-  99, 155, 121, 89, 127, 61, 101, 109, 108, 63,
-  114, 112, 80, 84, 109, 126, 114, 65, 149, 117,
-  76, 141, 147, 105, 98, 114, 55, 74, 100, 139,
-  96, 101, 89, 151, 93, 105, 108, 94, 149, 125,
-  124, 141, 82, 104, 74, 91, 117, 91, 124, 91,
-  101, 144, 141, 103, 79, 120, 51, 126, 116, 112,
-  97, 185, 130, 74, 91, 100, 83, 75, 67, 128,
-  95, 126, 141, 147, 140, 104, 129, 110, 92, 118,
-  127, 85, 144, 150, 117, 113, 100, 132, 119, 77,
-  76, 108, 90, 71, 92, 147, 95, 90, 75, 80,
-  61, 101, 122, 56, 96, 101, 69, 79, 103, 80,
-  93, 105, 81, 51, 92, 104, 115, 104, 99, 101,
-  99, 122, 117, 88, 124, 126, 118, 150, 56, 117,
-  116, 78, 143, 107, 87, 63, 105, 97, 95, 115,
-  83, 83, 127, 27, 85, 102, 62, 74, 140, 86,
-  87, 112, 94, 126, 81, 129, 140, 103, 76, 84,
-  101, 111, 130, 195, 62, 101, 106, 64, 90, 88,
-  147, 150, 119, 74, 101, 96, 85, 96, 88, 161,
-  109, 167, 78, 112, 100, 119, 77, 78, 89, 80,
-  44, 152, 99, 166, 124, 92, 116, 75, 102, 117,
-  113, 65, 120, 124, 84, 92, 96, 116, 110, 88,
-  136, 119, 80, 113, 144, 94, 95, 101, 64, 71,
-  97, 166, 81, 107, 112, 158, 86, 106, 105, 97,
-  146, 132, 135, 134, 105, 114, 76, 92, 111, 93,
-  123, 90, 96, 134, 116, 105, 98, 110, 62, 134,
-  156, 131, 103, 183, 128, 76, 79, 101, 86, 72,
-  40, 133, 88, 125, 158, 137, 137, 135, 137, 120,
-  88, 108, 118, 115, 134, 139, 117, 123, 104, 122,
-  104, 75, 94, 131, 90, 53, 96, 144, 98, 100,
-  68, 95, 60, 96, 141, 56, 106, 92, 90, 85,
-  100, 72, 72, 109, 83, 50, 113, 94, 114, 96,
-  87, 103, 102, 141, 104, 96, 99, 115, 117, 164,
-  57, 145, 131, 70, 127, 107, 106, 50, 111, 100,
-  95, 99, 70, 78, 132, 26, 74, 101, 64, 56,
-  144, 68, 95, 114, 99, 110, 95, 131, 148, 93,
-  79, 79, 90, 108, 129, 185, 63, 100, 108, 70,
-  91, 84, 105, 124, 121, 55, 79, 52, 72, 87,
-  110, 151, 112, 169, 97, 106, 90, 96, 82, 74,
-  101, 119, 29, 129, 90, 130, 109, 83, 107, 97,
-  87, 123, 125, 98, 102, 114, 93, 76, 72, 97,
-  105, 109, 93, 86, 89, 106, 142, 89, 97, 87,
-  76, 78, 93, 202, 85, 143, 139, 135, 99, 105,
-  112, 117, 100, 126, 138, 120, 149, 125, 76, 104,
-  97, 93, 104, 93, 90, 125, 86, 100, 124, 84,
-  115, 130, 169, 127, 112, 167, 93, 69, 74, 98,
-  102, 77, 72, 141, 84, 107, 160, 92, 129, 129,
-  131, 121, 85, 81, 97, 145, 105, 114, 109, 159,
-  85, 113, 89, 76, 99, 125, 82, 59, 71, 118,
-  97, 94, 37, 132, 51, 105, 140, 107, 122, 84,
-  92, 92, 80, 97, 57, 104, 86, 63, 121, 113,
-  99, 107, 91, 87, 93, 171, 94, 121, 63, 95,
-  78, 121, 93, 142, 114, 84, 116, 91, 112, 60,
-  87, 107, 97, 92, 80, 104, 118, 57, 65, 97,
-  62, 86, 139, 51, 105, 126, 86, 111, 109, 123,
-  149, 73, 84, 70, 74, 98, 100, 153, 44, 103,
-  105, 79, 95, 102, 56, 102, 96, 112, 50, 27,
-  82, 94, 131, 104, 66, 143, 136, 111, 70, 88,
-  91, 95, 106, 165, 11, 79, 81, 69, 103, 68,
-  62, 94, 111, 100, 117, 113, 87, 88, 118, 62,
-  77, 54, 116, 121, 59, 54, 76, 107, 139, 106,
-  47, 82, 92, 55, 83, 156, 108, 127, 101, 87,
-  118, 66, 120, 130, 65, 84, 144, 101, 170, 150,
-  98, 113, 72, 76, 81, 102, 76, 70, 77, 88,
-  105, 74, 154, 132, 108, 88, 115, 133, 50, 80,
-  101, 99, 133, 69, 138, 111, 95, 84, 126, 57,
-  107, 106, 114, 111, 80, 74, 63, 134, 113, 91,
-  109, 144, 86, 103, 72, 82, 102, 69, 83, 70,
-  55, 104, 92, 77, 26, 130, 74, 101, 96, 143,
-  127, 62, 80, 104, 72, 122, 75, 75, 111, 94,
-  100, 92, 99, 132, 124, 78, 75, 169, 85, 124,
-  57, 108, 44, 69, 106, 85, 94, 98, 82, 66,
-  128, 111, 81, 105, 106, 96, 94, 164, 82, 73,
-  85, 88, 80, 121, 122, 84, 120, 126, 52, 101,
-  95, 99, 126, 64, 73, 70, 73, 84, 83, 104,
-  35, 77, 109, 114, 81, 114, 43, 105, 131, 145,
-  48, 62, 66, 112, 85, 102, 69, 104, 210, 108,
-  36, 104, 94, 104, 73, 140, 8, 66, 85, 51,
-  117, 72, 33, 70, 102, 88, 98, 93, 75, 96,
-  104, 68, 105, 44, 145, 114, 36, 90, 49, 110,
-  140, 143, 0, 82, 92, 40, 79, 109, 132, 93,
-  89, 72, 96, 60, 103, 116, 75, 82, 119, 81,
-  128, 175, 172, 108, 74, 84, 93, 94, 89, 43,
-  79, 82, 88, 79, 123, 127, 53, 84, 98, 130,
-  44, 143, 113, 113, 136, 71, 139, 104, 126, 67,
-  102, 55, 127, 72, 151, 114, 89, 83, 65, 97,
-  102, 79, 117, 84, 76, 95, 82, 75, 117, 58,
-  121, 88, 49, 123, 116, 65, 21, 94, 115, 104,
-  95, 123, 146, 46, 80, 115, 90, 121, 85, 75,
-  139, 113, 118, 87, 128, 198, 171, 102, 78, 166,
-  72, 135, 86, 110, 48, 69, 103, 69, 124, 102,
-  55, 96, 122, 112, 95, 127, 92, 93, 74, 125,
-  77, 81, 89, 80, 126, 98, 105, 107, 116, 117,
-  38, 109, 97, 95, 97, 82, 96, 88, 113, 72,
-  79, 75, 87, 55, 108, 138, 110, 120, 47, 106,
-  131, 87, 54, 88, 59, 125, 77, 105, 90, 99,
-  222, 112, 40, 94, 95, 53, 56, 104, 18, 78,
-  88, 35, 104, 72, 47, 57, 48, 99, 98, 100,
-  64, 127, 93, 96, 99, 44, 134, 101, 34, 154,
-  70, 103, 115, 148, 2, 107, 77, 86, 93, 101,
-  115, 124, 93, 73, 122, 61, 69, 95, 80, 88,
-  116, 94, 88, 180, 181, 126, 93, 95, 104, 82,
-  74, 32, 66, 81, 80, 95, 97, 109, 68, 99,
-  96, 136, 39, 153, 87, 122, 99, 69, 93, 91,
-  141, 59, 99, 57, 119, 74, 136, 127, 111, 89,
-  68, 113, 127, 61, 109, 80, 76, 89, 106, 87,
-  113, 63, 130, 107, 50, 127, 120, 83, 27, 85,
-  131, 96, 95, 72, 140, 75, 129, 155, 90, 102,
-  82, 55, 173, 132, 138, 105, 136, 202, 169, 113,
-  80, 143, 69, 131, 75, 100, 56, 67, 104, 51,
-  100, 96, 67, 129, 102, 106, 94, 115, 101, 78,
-  70, 135, 82, 78, 80, 136, 141, 77, 97, 133,
-  118, 102, 29, 160, 88, 84, 82, 82, 150, 108,
-  120, 51, 74, 66, 107, 84, 90, 151, 114, 123,
-  62, 101, 59, 97, 56, 108, 71, 115, 124, 116,
-  84, 106, 150, 145, 58, 77, 112, 55, 62, 98,
-  17, 99, 110, 28, 63, 69, 75, 69, 69, 110,
-  100, 121, 74, 101, 109, 94, 104, 43, 92, 97,
-  59, 140, 112, 80, 91, 106, 56, 149, 84, 138,
-  117, 120, 108, 149, 92, 109, 164, 86, 98, 130,
-  63, 71, 107, 102, 110, 191, 107, 109, 106, 79,
-  104, 97, 54, 51, 112, 74, 96, 109, 109, 115,
-  112, 67, 96, 102, 55, 107, 74, 138, 88, 70,
-  86, 102, 127, 74, 116, 53, 94, 61, 85, 127,
-  127, 103, 71, 91, 144, 85, 112, 109, 82, 97,
-  119, 109, 113, 101, 86, 113, 63, 110, 105, 133,
-  50, 91, 82, 115, 91, 70, 102, 93, 146, 172,
-  94, 48, 103, 45, 174, 124, 95, 91, 108, 135,
-  123, 121, 64, 127, 68, 111, 58, 115, 51, 72,
-  90, 50, 52, 105, 115, 124, 101, 105, 80, 78,
-  111, 63, 91, 161, 80, 84, 91, 134, 110, 86,
-  86, 117, 131, 112, 60, 181, 82, 79, 94, 68,
-  122, 117, 123, 55, 60, 55, 105, 98, 80, 131,
-  135, 117, 82, 107, 60, 92, 49, 120, 78, 114,
-  181, 162, 100, 134, 70, 149, 64, 60, 106, 66,
-  107, 72, 29, 137, 139, 41, 60, 91, 98, 92,
-  93, 127, 101, 115, 117, 110, 139, 89, 111, 53,
-  93, 132, 60, 140, 167, 68, 98, 116, 93, 135,
-  108, 105, 121, 178, 112, 121, 124, 107, 130, 119,
-  89, 140, 80, 76, 91, 120, 132, 190, 66, 79,
-  114, 73, 95, 74, 59, 95, 109, 67, 119, 116,
-  114, 132, 170, 79, 94, 94, 65, 81, 89, 132,
-  104, 77, 121, 152, 99, 104, 112, 57, 95, 79,
-  110, 121, 115, 115, 74, 118, 101, 156, 95, 151,
-  89, 92, 121, 127, 107, 135, 71, 133, 74, 127,
-  102, 133, 58, 80, 73, 144, 129, 89, 134, 51,
-  112, 117, 81, 85, 112, 72, 123, 122, 55, 86,
-  112, 141, 131, 112, 58, 160, 103, 111, 43, 136,
-  49, 101, 115, 103, 69, 122, 158, 95, 92, 93,
-  79, 97, 108, 66, 119, 192, 81, 89, 93, 93,
-  81, 75, 136, 110, 155, 115, 60, 163, 99, 87,
-  157, 84, 102, 107, 95, 113, 70, 76, 104, 89,
-  90, 94, 83, 102, 54, 87, 67, 95, 61, 116,
-  62, 84, 134, 134, 96, 97, 69, 114, 68, 47,
-  75, 93, 102, 143, 22, 76, 80, 63, 73, 94,
-  99, 90, 87, 90, 68, 107, 111, 121, 160, 129,
-  91, 67, 92, 108, 60, 100, 152, 73, 110, 109,
-  93, 93, 112, 87, 88, 144, 102, 95, 120, 104,
-  112, 109, 95, 112, 60, 72, 81, 84, 128, 135,
-  74, 71, 75, 85, 94, 123, 66, 120, 44, 89,
-  120, 106, 123, 106, 124, 102, 92, 78, 63, 108,
-  120, 89, 98, 86, 158, 172, 145, 123, 74, 53,
-  73, 61, 98, 90, 84, 95, 58, 125, 77, 159,
-  99, 123, 60, 90, 83, 131, 119, 99, 53, 127,
-  88, 87, 107, 112, 44, 71, 90, 118, 97, 143,
-  99, 43, 104, 135, 83, 135, 101, 92, 76, 97,
-  44, 90, 126, 124, 142, 72, 37, 157, 98, 114,
-  47, 116, 49, 70, 75, 85, 67, 123, 102, 111,
-  98, 107, 72, 97, 105, 100, 127, 128, 56, 87,
-  113, 156, 81, 122, 109, 79, 126, 111, 91, 145,
-  100, 98, 141, 100, 108, 113, 71, 121, 84, 80,
-  100, 78, 118, 91, 111, 103, 111, 115, 100, 128,
-  97, 72, 85, 91, 86, 119, 127, 67, 93, 93,
-  98, 74, 85, 114, 105, 110, 34, 128, 79, 79,
-  113, 98, 126, 108, 86, 94, 103, 130, 101, 100,
-  114, 87, 115, 97, 109, 97, 85, 67, 115, 121,
-  134, 122, 106, 110, 107, 126, 96, 133, 136, 80,
-  119, 80, 115, 110, 106, 83, 92, 115, 97, 93,
-  105, 111, 104, 91, 82, 131, 132, 108, 81, 119,
-  43, 93, 134, 90, 139, 100, 67, 120, 97, 85,
-  70, 131, 161, 80, 102, 103, 141, 166, 205, 117,
-  94, 112, 110, 125, 112, 103, 80, 120, 81, 64,
-  103, 108, 111, 111, 57, 96, 94, 122, 136, 85,
-  107, 124, 94, 90, 104, 92, 59, 71, 84, 77,
-  111, 105, 142, 102, 90, 103, 111, 99, 129, 120,
-  88, 83, 85, 118, 97, 95, 100, 88, 77, 87,
-  79, 104, 124, 122, 86, 111, 57, 135, 94, 93,
-  82, 112, 96, 79, 93, 120, 131, 103, 126, 105,
-  72, 138, 126, 169, 121, 132, 72, 86, 105, 115,
-  93, 106, 81, 126, 95, 98, 99, 99, 79, 94,
-  109, 96, 131, 105, 125, 111, 134, 98, 144, 148,
-  125, 110, 129, 91, 120, 120, 77, 108, 124, 107,
-  117, 83, 104, 89, 107, 76, 108, 67, 35, 147,
-  94, 120, 135, 109, 118, 102, 104, 91, 107, 141,
-  125, 102, 91, 66, 93, 103, 143, 110, 117, 115,
-  85, 165, 125, 130, 121, 106, 97, 131, 119, 105,
-  109, 116, 102, 91, 103, 99, 126, 80, 103, 128,
-  99, 102, 111, 137, 98, 111, 97, 161, 145, 61,
-  96, 148, 96, 106, 146, 99, 128, 91, 53, 115,
-  107, 117, 79, 126, 129, 135, 104, 111, 103, 133,
-  141, 129, 101, 130, 131, 159, 122, 113, 101, 97,
-  115, 98, 128, 105, 125, 71, 68, 97, 125, 118,
-  126, 79, 140, 97, 139, 97, 111, 94, 78, 77,
-  123, 90, 136, 88, 141, 137, 88, 71, 178, 131,
-  104, 124, 93, 78, 99, 121, 110, 102, 74, 100,
-  124, 74, 98, 99, 141, 112, 108, 141, 60, 149,
-  107, 83, 105, 97, 71, 85, 103, 135, 83, 100,
-  113, 90, 75, 129, 114, 83, 124, 51, 89, 80,
-  94, 126, 108, 107, 75, 155, 79, 88, 75, 114,
-  83, 102, 116, 94, 166, 122, 114, 113, 103, 105,
-  91, 127, 84, 117, 119, 120, 108, 105, 78, 95,
-  96, 111, 103, 90, 71, 77, 100, 42, 103, 96,
-  29, 106, 98, 101, 103, 78, 75, 93, 130, 68,
-  100, 115, 111, 83, 109, 113, 53, 76, 129, 90,
-  122, 113, 83, 166, 89, 119, 118, 125, 93, 139,
-  134, 89, 101, 133, 81, 86, 113, 74, 123, 128,
-  52, 82, 101, 82, 124, 151, 91, 107, 85, 127,
-  113, 119, 100, 121, 128, 87, 113, 76, 135, 82,
-  62, 75, 105, 102, 59, 114, 91, 151, 91, 97,
-  93, 86, 106, 82, 103, 97, 93, 129, 86, 93,
-  104, 52, 95, 120, 116, 93, 126, 69, 73, 95,
-  110, 118, 94, 48, 94, 83, 147, 106, 122, 125,
-  48, 80, 126, 125, 96, 79, 89, 103, 104, 115,
-  152, 127, 85, 86, 93, 90, 87, 120, 111, 122,
-  84, 85, 123, 123, 92, 99, 74, 104, 57, 80,
-  41, 94, 81, 97, 91, 102, 77, 116, 86, 94,
-  106, 70, 101, 120, 48, 67, 100, 73, 86, 88,
-  92, 88, 94, 134, 91, 142, 88, 130, 84, 75,
-  95, 132, 65, 90, 90, 51, 132, 112, 119, 116,
-  124, 120, 59, 123, 66, 122, 95, 127, 102, 119,
-  115, 136, 98, 100, 102, 98, 61, 81, 109, 42,
-  107, 75, 50, 126, 144, 97, 83, 80, 85, 107,
-  123, 111, 128, 83, 110, 67, 123, 127, 88, 77,
-  110, 70, 90, 110, 98, 153, 97, 116, 132, 109,
-  99, 135, 136, 118, 128, 84, 126, 108, 91, 112,
-  96, 143, 66, 103, 113, 122, 114, 125, 106, 90,
-  102, 107, 100, 126, 118, 117, 132, 69, 84, 78,
-  150, 87, 69, 62, 141, 131, 71, 100, 104, 121,
-  94, 80, 100, 89, 119, 68, 124, 100, 100, 116,
-  104, 98, 104, 73, 85, 99, 110, 100, 142, 107,
-  118, 92, 113, 116, 88, 79, 79, 97, 103, 135,
-  116, 146, 42, 76, 107, 139, 104, 69, 91, 64,
-  73, 96, 106, 120, 128, 100, 83, 123, 96, 147,
-  120, 152, 102, 93, 126, 168, 87, 100, 57, 123,
-  44, 82, 74, 101, 72, 117, 122, 101, 92, 90,
-  96, 87, 114, 59, 99, 130, 57, 29, 110, 78,
-  69, 107, 92, 105, 91, 151, 71, 183, 103, 119,
-  110, 60, 115, 130, 74, 84, 90, 64, 121, 94,
-  138, 110, 87, 123, 83, 127, 85, 114, 98, 114,
-  97, 133, 121, 157, 90, 68, 118, 100, 73, 98,
-  126, 93, 109, 107, 85, 140, 182, 112, 90, 102,
-  117, 121, 62, 146, 141, 98, 93, 104, 132, 115,
-  136, 109, 105, 41, 78, 97, 100, 120, 111, 124,
-  138, 91, 93, 117, 110, 145, 134, 81, 160, 123,
-  96, 133, 114, 129, 121, 152, 129, 131, 103, 116,
-  96, 89, 107, 103, 108, 149, 196, 137, 141, 112,
-  90, 79, 127, 79, 99, 99, 152, 163, 88, 99,
-  99, 86, 120, 91, 120, 102, 137, 96, 115, 131,
-  133, 92, 141, 117, 106, 117, 96, 110, 93, 129,
-  137, 128, 100, 90, 112, 101, 114, 119, 85, 109,
-  79, 148, 113, 168, 65, 117, 87, 144, 126, 109,
-  96, 69, 90, 109, 87, 117, 169, 130, 94, 119,
-  115, 176, 137, 168, 131, 102, 111, 174, 92, 119,
-  80, 110, 84, 107, 69, 113, 89, 111, 144, 117,
-  110, 69, 123, 108, 111, 86, 90, 94, 88, 66,
-  117, 109, 78, 116, 110, 105, 82, 140, 87, 170,
-  118, 131, 141, 81, 137, 120, 103, 83, 101, 110,
-  108, 114, 163, 107, 108, 113, 108, 135, 120, 111,
-  141, 102, 118, 117, 106, 108, 142, 137, 115, 111,
-  132, 111, 128, 119, 133, 95, 90, 94, 119, 124,
-  139, 107, 134, 84, 116, 126, 106, 148, 108, 71,
-  94, 115, 132, 111, 127, 96, 118, 79, 79, 118,
-  112, 97, 116, 111, 89, 143, 126, 108, 136, 155,
-  108, 83, 125, 93, 128, 135, 144, 147, 107, 101,
-  121, 116, 115, 104, 125, 135, 121, 106, 150, 137,
-  83, 121, 113, 94, 78, 122, 102, 128, 113, 123,
-  93, 120, 115, 134, 110, 111, 100, 123, 87, 112,
-  133, 128, 155, 114, 135, 120, 126, 90, 136, 116,
-  111, 97, 138, 98, 72, 107, 103, 95, 106, 107,
-  109, 113, 127, 123, 92, 106, 101, 121, 91, 106,
-  130, 113, 128, 129, 110, 139, 115, 74, 126, 109,
-  106, 155, 81, 120, 109, 106, 104, 116, 148, 85,
-  127, 102, 102, 102, 126, 116, 56, 105, 113, 99,
-  95, 97, 82, 103, 142, 103, 87, 104, 121, 108,
-  116, 127, 117, 97, 119, 97, 80, 106, 111, 110,
-  98, 110, 90, 146, 112, 106, 126, 101, 103, 85,
-  89, 97, 110, 108, 176, 100, 129, 99, 76, 116,
-  120, 111, 142, 124, 95, 107, 85, 119, 115, 117,
-  111, 109, 116, 94, 115, 127, 122, 99, 75, 67,
-  29, 113, 142, 86, 92, 80, 132, 81, 82, 111,
-  74, 96, 105, 93, 114, 78, 109, 133, 121, 54,
-  64, 166, 88, 97, 102, 121, 64, 97, 103, 114,
-  146, 159, 70, 91, 104, 90, 118, 142, 106, 107,
-  106, 97, 111, 99, 98, 95, 114, 113, 113, 111,
-  97, 134, 92, 97, 94, 95, 101, 101, 91, 138,
-  105, 135, 84, 111, 131, 137, 97, 81, 98, 110,
-  100, 97, 102, 113, 147, 120, 145, 117, 139, 85,
-  121, 142, 90, 109, 140, 91, 67, 109, 72, 95,
-  106, 98, 104, 100, 128, 156, 99, 82, 77, 127,
-  55, 127, 99, 128, 144, 66, 112, 122, 109, 76,
-  126, 100, 103, 185, 108, 76, 126, 128, 112, 93,
-  127, 123, 129, 90, 106, 138, 105, 105, 84, 64,
-  116, 87, 69, 103, 149, 131, 110, 81, 119, 99,
-  95, 126, 93, 76, 107, 102, 87, 140, 81, 89,
-  100, 106, 98, 86, 98, 133, 102, 97, 108, 97,
-  100, 95, 87, 92, 90, 129, 146, 97, 165, 123,
-  78, 97, 140, 126, 107, 111, 85, 122, 91, 144,
-  120, 131, 108, 116, 137, 87, 127, 75, 118, 100,
-  71, 93, 31, 111, 145, 94, 88, 104, 110, 78,
-  100, 112, 73, 126, 129, 80, 103, 94, 104, 130,
-  80, 140, 78, 191, 118, 129, 102, 110, 88, 76,
-  92, 128, 129, 94, 67, 97, 87, 93, 101, 112,
-  89, 81, 112, 122, 116, 121, 84, 111, 95, 94,
-  124, 85, 86, 123, 87, 107, 112, 82, 125, 68,
-  100, 124, 101, 147, 91, 101, 109, 116, 102, 76,
-  120, 106, 103, 103, 114, 81, 146, 115, 159, 126,
-  138, 111, 112, 171, 77, 109, 113, 99, 80, 104,
-  88, 112, 102, 122, 117, 97, 105, 175, 114, 74,
-  67, 107, 78, 122, 124, 86, 173, 63, 118, 75,
-  127, 174, 103, 121, 82, 202, 130, 76, 143, 155,
-  132, 88, 128, 169, 126, 101, 60, 113, 88, 126,
-  112, 88, 131, 98, 79, 112, 118, 125, 94, 105,
-  105, 103, 118, 138, 92, 64, 104, 113, 79, 82,
-  132, 90, 98, 91, 107, 75, 91, 128, 117, 117,
-  81, 91, 81, 109, 100, 102, 96, 115, 159, 70,
-  81, 115, 69, 88, 106, 155, 87, 90, 61, 97,
-  57, 75, 80, 77, 103, 104, 117, 88, 110, 104,
-  105, 135, 41, 60, 29, 92, 125, 75, 110, 92,
-  114, 66, 98, 107, 60, 105, 118, 117, 68, 80,
-  83, 83, 89, 83, 57, 163, 96, 104, 91, 117,
-  73, 95, 87, 93, 101, 73, 73, 99, 106, 65,
-  108, 124, 64, 73, 90, 99, 94, 84, 76, 94,
-  64, 80, 100, 146, 90, 110, 61, 104, 92, 84,
-  116, 67, 62, 73, 86, 129, 54, 88, 105, 109,
-  83, 68, 120, 108, 114, 93, 92, 70, 119, 75,
-  106, 100, 134, 69, 82, 124, 80, 104, 119, 85,
-  76, 101, 55, 99, 102, 105, 92, 94, 100, 136,
-  106, 89, 49, 86, 69, 105, 66, 93, 95, 78,
-  102, 104, 116, 142, 81, 104, 101, 177, 86, 79,
-  120, 123, 111, 82, 102, 130, 101, 88, 38, 89,
-  69, 82, 59, 52, 95, 79, 40, 121, 58, 103,
-  82, 58, 103, 103, 123, 100, 93, 58, 88, 144,
-  83, 113, 77, 74, 79, 93, 130, 92, 78, 127,
-  83, 96, 92, 77, 63, 79, 107, 91, 71, 83,
-  183, 91, 132, 92, 125, 132, 109, 134, 101, 114,
-  82, 115, 85, 108, 109, 71, 96, 94, 125, 106,
-  121, 96, 115, 75, 55, 107, 82, 98, 155, 96,
-  132, 96, 90, 134, 121, 101, 77, 77, 80, 104,
-  125, 110, 114, 106, 95, 84, 46, 151, 89, 107,
-  107, 127, 71, 84, 73, 104, 112, 68, 126, 74,
-  106, 96, 134, 112, 125, 145, 96, 133, 108, 99,
-  114, 72, 105, 128, 131, 98, 102, 119, 91, 80,
-  89, 105, 96, 80, 66, 119, 97, 152, 75, 93,
-  108, 76, 98, 80, 75, 96, 117, 93, 123, 125,
-  152, 131, 132, 113, 107, 105, 110, 53, 93, 96,
-  112, 99, 76, 105, 80, 98, 99, 105, 122, 95,
-  95, 128, 98, 89, 65, 89, 85, 105, 135, 76,
-  163, 91, 96, 81, 102, 81, 135, 121, 105, 158,
-  130, 106, 113, 107, 82, 109, 124, 106, 94, 99,
-  103, 105, 92, 134, 56, 132, 118, 76, 77, 86,
-  81, 47, 79, 103, 85, 102, 105, 91, 129, 104,
-  83, 114, 92, 72, 91, 86, 90, 95, 101, 96,
-  72, 160, 91, 63, 88, 82, 72, 89, 112, 110,
-  94, 95, 155, 81, 90, 89, 92, 132, 119, 83,
-  108, 134, 75, 108, 90, 113, 116, 96, 71, 100,
-  108, 88, 111, 96, 110, 88, 50, 110, 85, 104,
-  142, 89, 121, 87, 101, 110, 84, 96, 67, 90,
-  84, 96, 90, 116, 103, 123, 90, 76, 54, 121,
-  99, 128, 108, 91, 73, 94, 91, 103, 108, 131,
-  111, 76, 100, 90, 176, 148, 119, 150, 85, 141,
-  121, 90, 115, 82, 121, 122, 134, 100, 75, 116,
-  112, 86, 81, 108, 107, 85, 77, 129, 99, 136,
-  82, 81, 95, 124, 99, 91, 85, 76, 79, 105,
-  127, 124, 142, 139, 115, 119, 99, 96, 111, 142,
-  107, 105, 118, 99, 70, 102, 69, 115, 109, 97,
-  101, 95, 124, 98, 109, 102, 44, 94, 77, 118,
-  115, 130, 140, 86, 102, 118, 98, 75, 118, 121,
-  105, 99, 141, 93, 114, 114, 93, 109, 111, 99,
-  75, 87, 77, 100, 90, 111, 67, 95, 100, 72,
-  71, 77, 129, 65, 89, 90, 100, 95, 99, 112,
-  117, 81, 86, 95, 83, 90, 80, 80, 97, 80,
-  127, 116, 74, 131, 93, 72, 96, 94, 84, 106,
-  92, 121, 99, 132, 111, 84, 155, 114, 45, 90,
-  105, 117, 119, 129, 60, 124, 98, 127, 94, 88,
-  72, 97, 113, 63, 112, 94, 109, 79, 58, 83,
-  76, 100, 134, 99, 97, 115, 89, 82, 70, 137,
-  71, 121, 161, 92, 95, 111, 112, 112, 71, 107,
-  105, 133, 114, 132, 119, 122, 97, 100, 97, 116,
-  140, 151, 96, 101, 99, 98, 124, 143, 56, 80,
-  93, 125, 109, 131, 77, 115, 133, 97, 122, 133,
-  79, 97, 105, 100, 96, 90, 142, 74, 86, 96,
-  108, 125, 93, 83, 103, 136, 76, 112, 115, 96,
-  79, 102, 103, 76, 99, 117, 113, 114, 121, 108,
-  98, 127, 97, 136, 120, 96, 96, 114, 89, 122,
-  110, 109, 102, 115, 109, 107, 113, 65, 59, 85,
-  99, 123, 106, 113, 138, 90, 122, 107, 121, 126,
-  95, 125, 83, 101, 130, 97, 129, 151, 121, 77,
-  94, 128, 106, 113, 71, 115, 58, 77, 179, 73,
-  82, 113, 84, 111, 133, 128, 80, 99, 124, 104,
-  131, 165, 75, 87, 112, 103, 79, 121, 94, 86,
-  90, 80, 145, 128, 91, 88, 112, 76, 81, 91,
-  77, 119, 77, 108, 105, 135, 95, 78, 93, 106,
-  85, 102, 120, 168, 125, 105, 68, 120, 90, 126,
-  131, 90, 88, 87, 99, 90, 93, 134, 104, 126,
-  69, 121, 71, 108, 139, 93, 120, 128, 129, 77,
-  97, 149, 90, 117, 183, 94, 85, 118, 129, 106,
-  82, 117, 104, 120, 118, 120, 112, 134, 86, 89,
-  91, 145, 113, 82, 99, 87, 124, 95, 105, 96,
-  118, 119, 124, 107, 98, 138, 97, 116, 132, 85,
-  133, 125, 81, 111, 85, 115, 91, 89, 107, 56,
-  85, 111, 88, 115, 88, 109, 117, 108, 102, 118,
-  145, 106, 149, 104, 103, 72, 124, 110, 103, 111,
-  163, 123, 113, 119, 93, 124, 118, 107, 60, 118,
-  110, 123, 99, 132, 107, 127, 105, 98, 113, 105,
-  72, 96, 90, 94, 103, 93, 112, 129, 117, 101,
-  114, 136, 109, 117, 87, 89, 118, 114, 134, 136,
-  115, 93, 121, 98, 91, 110, 73, 102, 95, 98,
-  90, 83, 102, 110, 82, 155, 51, 121, 85, 80,
-  116, 118, 142, 117, 99, 109, 125, 120, 95, 135,
-  92, 103, 100, 90, 116, 111, 99, 91, 114, 112,
-  78, 82, 98, 81, 75, 97, 88, 124, 111, 90,
-  103, 91, 148, 149, 129, 129, 124, 124, 90, 117,
-  75, 119, 109, 104, 109, 90, 98, 110, 87, 145,
-  111, 96, 70, 148, 92, 100, 136, 99, 113, 96,
-  123, 81, 84, 127, 103, 111, 119, 78, 88, 115,
-  150, 92, 121, 99, 82, 139, 135, 119, 83, 133,
-  75, 101, 93, 108, 107, 113, 112, 115, 111, 101,
-  115, 79, 119, 124, 102, 107, 84, 128, 114, 92,
-  133, 115, 136, 105, 100, 126, 86, 100, 98, 112,
-  86, 61, 59, 119, 94, 133, 87, 130, 141, 123,
-  106, 108, 114, 108, 136, 100, 102, 113, 117, 119,
-  86, 117, 162, 114, 121, 90, 156, 125, 123, 75,
-  88, 126, 139, 98, 92, 102, 128, 110, 116, 99,
-  127, 97, 97, 65, 112, 90, 115, 89, 86, 152,
-  104, 94, 118, 86, 114, 118, 86, 80, 107, 107,
-  109, 110, 100, 104, 115, 85, 99, 105, 100, 151,
-  126, 128, 72, 86, 112, 80, 105, 135, 71, 97,
-  90, 105, 94, 146, 106, 103, 111, 107, 101, 120,
-  103, 111, 97, 110, 116, 101, 110, 119, 96, 110,
-  113, 112, 88, 100, 92, 86, 92, 111, 89, 120,
-  110, 85, 93, 116, 167, 144, 111, 95, 101, 121,
-  88, 109, 84, 117, 100, 111, 98, 115, 101, 110,
-  107, 79, 105, 99, 63, 147, 97, 86, 114, 81,
-  104, 75, 116, 78, 88, 95, 101, 106, 91, 94,
-  73, 104, 133, 80, 141, 108, 85, 166, 130, 116,
-  89, 136, 66, 128, 94, 97, 101, 140, 86, 121,
-  112, 100, 116, 103, 96, 100, 115, 134, 86, 136,
-  107, 89, 117, 121, 127, 105, 99, 124, 90, 72,
-  115, 108, 106, 75, 55, 91, 100, 127, 92, 108,
-  102, 130, 89, 102, 80, 103, 101, 91, 114, 135,
-  113, 110, 73, 135, 119, 109, 116, 90, 177, 105,
-  123, 92, 113, 122, 137, 108, 77, 70, 110, 97,
-  108, 111, 120, 94, 88, 51, 106, 102, 104, 58,
-  75, 120, 109, 111, 111, 103, 114, 113, 95, 74,
-  102, 125, 111, 112, 104, 105, 95, 105, 111, 100,
-  104, 158, 103, 125, 81, 71, 98, 92, 125, 120,
-  96, 115, 82, 87, 105, 143, 91, 123, 101, 67,
-  81, 119, 76, 96, 94, 104, 127, 98, 92, 148,
-  98, 108, 125, 117, 101, 106, 94, 104, 95, 131,
-  84, 108, 99, 90, 83, 128, 158, 140, 101, 124,
-  89, 117, 91, 108, 96, 147, 97, 106, 88, 111,
-  107, 117, 125, 71, 107, 101, 61, 143, 95, 88,
-  108, 80, 122, 73, 118, 88, 106, 84, 106, 105,
-  81, 75, 81, 102, 118, 59, 139, 99, 97, 178,
-  129, 111, 107, 114, 71, 122, 87, 131, 106, 116,
-  91, 135, 113, 110, 119, 112, 89, 102, 115, 133,
-  82, 123, 84, 94, 101, 99, 126, 105, 110, 142,
-  106, 76, 113, 107, 112, 82, 60, 87, 105, 132,
-  112, 87, 107, 117, 95, 96, 87, 98, 88, 91,
-  127, 126, 115, 99, 95, 123, 107, 97, 121, 80,
-  161, 105, 125, 117, 107, 130, 139, 105, 67, 83,
-  106, 96, 89, 128, 110, 104, 79, 47, 78, 102,
-  106, 53, 61, 107, 94, 93, 100, 117, 125, 125,
-  99, 65, 87, 123, 115, 123, 111, 100, 86, 126,
-  125, 104, 108, 152, 86, 104, 72, 96, 98, 98,
-  144, 127, 92, 113, 84, 77, 105, 120, 100, 103,
-  99, 51, 68, 103, 64, 78, 104, 90, 121, 106,
-  91, 135, 101, 115, 141, 122, 90, 70, 93, 107,
-  109, 144, 88, 101, 106, 82, 95, 122, 162, 164,
-  118, 134, 91, 119, 96, 102, 100, 179, 104, 105,
-  83, 106, 112, 122, 101, 86, 122, 96, 67, 151,
-  86, 110, 120, 88, 133, 79, 130, 90, 111, 74,
-  114, 108, 84, 67, 91, 117, 115, 53, 132, 115,
-  86, 166, 140, 117, 102, 102, 83, 102, 90, 148,
-  99, 102, 92, 154, 103, 116, 123, 110, 119, 118,
-  106, 132, 89, 97, 77, 85, 98, 86, 126, 97,
-  111, 143, 134, 109, 105, 110, 104, 84, 75, 90,
-  99, 143, 122, 94, 125, 107, 106, 89, 91, 97,
-  96, 111, 123, 130, 114, 125, 116, 105, 101, 95,
-  123, 98, 154, 119, 122, 125, 117, 137, 145, 97,
-  71, 90, 121, 88, 86, 140, 117, 89, 71, 57,
-  78, 103, 125, 68, 74, 108, 82, 67, 96, 117,
-  144, 122, 89, 64, 102, 121, 119, 126, 112, 91,
-  96, 125, 118, 108, 113, 155, 97, 106, 70, 127,
-  120, 99, 144, 116, 101, 94, 91, 99, 116, 108,
-  93, 92, 114, 48, 69, 101, 63, 98, 135, 81,
-  115, 110, 102, 116, 102, 130, 148, 116, 71, 74,
-  95, 111, 117, 167, 99, 108, 109, 71, 90, 114,
-  156, 181, 120, 108, 94, 123, 92, 103, 76, 193,
-  96, 108, 79, 99, 110, 116, 70, 96, 130, 100,
-  68, 159, 98, 132, 123, 100, 120, 83, 128, 104,
-  93, 64, 119, 109, 97, 74, 88, 135, 115, 51,
-  132, 130, 74, 146, 153, 115, 96, 83, 85, 88,
-  96, 119, 95, 93, 97, 172, 84, 113, 117, 105,
-  127, 119, 93, 162, 94, 82, 87, 75, 104, 93,
-  124, 102, 109, 145, 152, 139, 90, 106, 91, 97,
-  80, 94, 100, 163, 131, 109, 128, 108, 105, 81,
-  82, 104, 100, 130, 114, 133, 107, 124, 118, 100,
-  97, 83, 119, 112, 157, 129, 126, 110, 125, 142,
-  136, 94, 80, 92, 138, 76, 96, 136, 129, 78,
-  68, 77, 84, 98, 127, 70, 73, 98, 65, 58,
-  115, 121, 136, 117, 72, 57, 114, 124, 119, 136,
-  108, 94, 93, 128, 115, 112, 101, 149, 113, 120,
-  84, 126, 135, 93, 151, 108, 101, 67, 93, 108,
-  107, 115, 76, 97, 116, 35, 74, 102, 60, 103,
-  156, 74, 98, 101, 129, 127, 100, 132, 134, 112,
-  62, 93, 97, 104, 127, 186, 97, 102, 109, 62,
-  91, 105, 149, 174, 97, 107, 92, 118, 84, 103,
-  66, 187, 79, 108, 79, 95, 90, 113, 65, 97,
-  116, 81, 66, 159, 102, 133, 132, 105, 115, 77,
-  97, 112, 84, 60, 119, 107, 106, 81, 90, 142,
-  118, 33, 140, 114, 67, 130, 151, 108, 93, 109,
-  72, 89, 98, 99, 106, 104, 103, 172, 76, 103,
-  107, 104, 150, 123, 93, 179, 87, 85, 85, 80,
-  106, 91, 119, 101, 113, 136, 137, 147, 80, 97,
-  84, 108, 87, 99, 98, 171, 134, 110, 103, 99,
-  95, 73, 77, 121, 100, 121, 114, 131, 111, 100,
-  119, 96, 91, 95, 113, 93, 151, 142, 128, 104,
-  126, 146, 121, 86, 85, 99, 150, 71, 102, 133,
-  125, 82, 82, 92, 76, 107, 121, 64, 76, 101,
-  74, 69, 120, 114, 113, 106, 64, 48, 106, 126,
-  117, 135, 106, 93, 85, 122, 123, 103, 94, 120,
-  118, 120, 104, 109, 134, 80, 152, 108, 95, 53,
-  100, 105, 106, 123, 66, 103, 120, 36, 86, 107,
-  67, 100, 159, 95, 86, 87, 121, 131, 100, 123,
-  128, 113, 77, 95, 119, 97, 137, 208, 83, 109,
-  102, 68, 78, 106, 155, 159, 105, 112, 99, 117,
-  92, 94, 82, 179, 102, 121, 84, 103, 83, 128,
-  71, 94, 100, 78, 63, 146, 107, 125, 146, 105,
-  124, 72, 92, 116, 87, 64, 119, 112, 93, 79,
-  96, 146, 126, 46, 151, 117, 69, 117, 149, 110,
-  92, 120, 73, 82, 96, 96, 109, 112, 92, 161,
-  78, 103, 96, 100, 170, 129, 100, 162, 84, 92,
-  91, 84, 111, 95, 120, 87, 99, 126, 131, 149,
-  80, 94, 58, 117, 107, 130, 84, 162, 130, 104,
-  92, 94, 97, 77, 77, 110, 100, 123, 111, 139,
-  126, 106, 129, 98, 85, 125, 116, 100, 146, 148,
-  119, 108, 118, 148, 115, 76, 79, 104, 149, 70,
-  109, 137, 124, 80, 98, 96, 75, 117, 120, 64,
-  98, 109, 94, 71, 107, 95, 100, 94, 55, 49,
-  112, 114, 114, 121, 104, 92, 99, 112, 127, 95,
-  106, 120, 133, 130, 91, 111, 145, 80, 139, 104,
-  98, 73, 125, 125, 106, 139, 71, 95, 126, 42,
-  102, 112, 81, 82, 161, 111, 89, 71, 115, 116,
-  96, 121, 140, 122, 77, 84, 131, 104, 134, 218,
-  87, 122, 91, 79, 90, 105, 150, 137, 108, 93,
-  98, 112, 102, 91, 92, 159, 136, 165, 96, 112,
-  86, 140, 72, 90, 91, 70, 59, 146, 100, 113,
-  153, 97, 116, 71, 119, 122, 97, 70, 125, 121,
-  90, 107, 97, 137, 138, 65, 153, 108, 67, 99,
-  145, 102, 88, 110, 88, 88, 95, 100, 89, 115,
-  95, 181, 95, 101, 97, 102, 168, 126, 120, 160,
-  96, 95, 83, 91, 115, 106, 119, 99, 83, 114,
-  114, 140, 86, 101, 64, 131, 124, 138, 84, 154,
-  120, 93, 94, 96, 85, 77, 66, 110, 89, 126,
-  133, 137, 136, 117, 123, 103, 84, 121, 116, 121,
-  151, 161, 120, 110, 133, 151, 101, 73, 85, 117,
-  140, 72, 109, 143, 126, 87, 96, 86, 84, 108,
-  119, 58, 93, 105, 90, 97, 91, 75, 76, 87,
-  70, 55, 113, 107, 119, 107, 103, 93, 107, 121,
-  123, 95, 104, 127, 136, 157, 81, 124, 158, 86,
-  120, 116, 113, 77, 138, 116, 102, 135, 83, 87,
-  128, 39, 100, 109, 90, 81, 161, 114, 95, 78,
-  131, 118, 107, 114, 144, 125, 79, 82, 125, 107,
-  128, 205, 85, 95, 97, 87, 81, 115, 124, 132,
-  130, 73, 95, 74, 91, 83, 100, 148, 133, 181,
-  125, 124, 85, 131, 81, 83, 79, 79, 48, 149,
-  88, 89, 132, 90, 123, 73, 114, 129, 113, 89,
-  98, 127, 71, 94, 96, 126, 132, 85, 108, 84,
-  81, 96, 156, 99, 82, 116, 82, 106, 102, 164,
-  91, 147, 118, 154, 111, 108, 114, 117, 146, 130,
-  139, 123, 121, 120, 82, 116, 111, 105, 116, 87,
-  91, 119, 89, 111, 95, 93, 86, 151, 160, 143,
-  84, 164, 102, 87, 85, 107, 89, 82, 55, 130,
-  89, 103, 169, 116, 159, 108, 119, 116, 88, 119,
-  110, 123, 154, 132, 113, 133, 100, 139, 110, 66,
-  93, 128, 108, 61, 95, 122, 121, 95, 63, 100,
-  88, 114, 127, 81, 111, 107, 104, 121, 70, 71,
-  60, 95, 92, 58, 121, 134, 90, 109, 112, 100,
-  102, 138, 108, 126, 100, 131, 120, 126, 72, 117,
-  130, 93, 106, 115, 124, 70, 135, 134, 100, 123,
-  100, 85, 121, 61, 79, 114, 79, 105, 149, 95,
-  113, 106, 98, 133, 121, 118, 144, 109, 78, 92,
-  110, 109, 99, 181, 68, 89, 91, 119, 98, 152,
-  85, 109, 128, 91, 83, 38, 87, 80, 121, 129,
-  109, 170, 162, 135, 88, 116, 93, 69, 77, 113,
-  34, 122, 69, 44, 100, 76, 79, 90, 102, 109,
-  98, 92, 91, 96, 82, 82, 111, 88, 138, 126,
-  76, 75, 94, 93, 144, 113, 40, 101, 86, 114,
-  101, 195, 120, 151, 116, 123, 132, 100, 104, 127,
-  89, 106, 170, 99, 156, 131, 110, 127, 85, 93,
-  88, 93, 71, 88, 72, 80, 103, 93, 122, 156,
-  149, 109, 91, 134, 78, 85, 100, 102, 100, 83,
-  95, 121, 101, 68, 161, 97, 134, 112, 93, 120,
-  86, 97, 84, 130, 159, 79, 115, 150, 95, 137,
-  108, 74, 90, 96, 86, 66, 70, 110, 112, 75,
-  40, 129, 116, 132, 116, 123, 120, 89, 116, 126,
-  56, 90, 68, 79, 118, 85, 123, 114, 76, 118,
-  128, 107, 99, 144, 101, 140, 82, 128, 75, 86,
-  108, 106, 96, 106, 86, 93, 164, 99, 128, 133,
-  105, 105, 110, 131, 102, 85, 65, 110, 83, 123,
-  110, 107, 145, 128, 63, 122, 121, 102, 136, 90,
-  83, 85, 97, 91, 75, 124, 79, 97, 79, 141,
-  114, 163, 67, 102, 98, 113, 59, 57, 92, 80,
-  126, 114, 101, 136, 161, 137, 58, 93, 82, 56,
-  84, 141, 24, 94, 96, 21, 64, 55, 30, 80,
-  110, 87, 63, 78, 85, 75, 102, 76, 120, 48,
-  132, 113, 47, 101, 82, 86, 123, 114, 3, 82,
-  71, 124, 91, 153, 133, 120, 107, 119, 187, 104,
-  79, 119, 68, 91, 161, 90, 141, 169, 175, 103,
-  72, 79, 74, 107, 72, 51, 57, 57, 87, 97,
-  99, 131, 81, 63, 71, 90, 68, 101, 112, 97,
-  99, 81, 121, 136, 143, 34, 129, 88, 99, 56,
-  85, 127, 86, 70, 65, 95, 196, 62, 119, 131,
-  96, 119, 102, 103, 102, 59, 64, 125, 65, 104,
-  105, 64, 18, 93, 132, 117, 104, 112, 124, 59,
-  111, 159, 61, 100, 84, 53, 149, 95, 106, 88,
-  83, 143, 155, 131, 94, 150, 95, 140, 75, 102,
-  52, 59, 97, 76, 64, 115, 84, 104, 147, 90,
-  75, 80, 97, 94, 99, 166, 88, 69, 73, 98,
-  96, 99, 78, 123, 183, 137, 63, 127, 123, 90,
-  101, 70, 141, 93, 116, 58, 64, 53, 106, 69,
-  82, 136, 105, 142, 87, 100, 84, 104, 68, 99,
-  94, 105, 123, 140, 91, 102, 120, 136, 61, 66,
-  92, 59, 89, 114, 28, 130, 119, 39, 59, 70,
-  50, 59, 75, 115, 68, 91, 67, 94, 107, 66,
-  125, 49, 117, 97, 45, 141, 107, 104, 112, 120,
-  38, 82, 68, 133, 92, 158, 125, 116, 123, 134,
-  194, 130, 60, 98, 81, 96, 116, 105, 86, 182,
-  158, 85, 96, 79, 88, 74, 78, 61, 62, 63,
-  96, 114, 99, 120, 75, 64, 72, 103, 74, 118,
-  99, 106, 104, 66, 99, 134, 170, 43, 113, 99,
-  100, 61, 93, 119, 101, 96, 64, 87, 190, 67,
-  111, 163, 93, 113, 114, 124, 99, 69, 75, 147,
-  52, 109, 108, 73, 33, 60, 101, 75, 116, 69,
-  144, 67, 111, 141, 85, 95, 132, 66, 163, 111,
-  90, 101, 78, 146, 138, 128, 102, 147, 82, 132,
-  78, 103, 59, 81, 97, 71, 65, 100, 130, 118,
-  108, 73, 57, 65, 84, 77, 98, 174, 95, 52,
-  85, 120, 83, 80, 80, 116, 170, 153, 70, 156,
-  105, 78, 87, 50, 167, 96, 137, 52, 62, 32,
-  121, 93, 72, 103, 116, 128, 104, 122, 84, 107,
-  78, 137, 100, 126, 122, 196, 92, 109, 82, 117,
-  82, 66, 110, 78, 127, 85, 31, 194, 110, 87,
-  82, 88, 122, 45, 75, 138, 124, 104, 86, 112,
-  126, 89, 113, 93, 97, 113, 59, 133, 126, 99,
-  128, 120, 112, 84, 78, 118, 106, 186, 97, 114,
-  143, 172, 157, 158, 86, 121, 117, 121, 99, 126,
-  101, 142, 100, 106, 129, 80, 102, 95, 82, 112,
-  113, 92, 130, 130, 112, 143, 129, 99, 82, 123,
-  104, 86, 80, 112, 102, 79, 96, 144, 130, 88,
-  130, 96, 106, 81, 95, 111, 122, 141, 87, 104,
-  131, 130, 110, 168, 85, 124, 144, 113, 103, 119,
-  89, 109, 54, 131, 100, 118, 52, 67, 59, 105,
-  139, 71, 117, 92, 99, 85, 110, 94, 147, 113,
-  135, 106, 95, 90, 89, 130, 102, 112, 109, 146,
-  92, 113, 89, 136, 79, 118, 100, 95, 101, 102,
-  174, 107, 107, 70, 97, 95, 97, 44, 94, 147,
-  105, 52, 106, 100, 61, 94, 103, 88, 120, 150,
-  96, 148, 110, 83, 94, 68, 126, 92, 135, 92,
-  55, 78, 141, 120, 73, 93, 107, 137, 94, 119,
-  129, 88, 77, 136, 88, 136, 118, 211, 129, 145,
-  72, 115, 97, 84, 112, 90, 121, 73, 37, 215,
-  114, 95, 103, 115, 146, 78, 87, 142, 128, 96,
-  124, 149, 137, 118, 110, 129, 116, 139, 54, 131,
-  106, 78, 139, 107, 125, 89, 114, 90, 113, 211,
-  100, 123, 151, 170, 103, 163, 79, 121, 139, 123,
-  77, 106, 130, 124, 63, 117, 133, 79, 113, 99,
-  76, 154, 96, 113, 139, 120, 121, 152, 174, 140,
-  94, 126, 110, 73, 91, 109, 114, 89, 111, 171,
-  97, 122, 135, 79, 114, 94, 110, 106, 125, 142,
-  104, 157, 108, 207, 94, 109, 91, 123, 158, 117,
-  104, 155, 99, 95, 68, 145, 126, 123, 61, 74,
-  99, 170, 153, 92, 113, 79, 106, 75, 97, 128,
-  112, 155, 92, 96, 86, 68, 100, 144, 129, 103,
-  113, 162, 100, 126, 65, 137, 93, 141, 88, 125,
-  135, 98, 151, 95, 124, 70, 125, 140, 96, 61,
-  120, 105, 105, 68, 100, 118, 67, 83, 158, 97,
-  83, 122, 94, 139, 123, 97, 132, 112, 111, 110,
-  103, 114, 68, 134, 143, 112, 85, 81, 89, 154,
-  65, 96, 109, 75, 76, 91, 74, 92, 110, 146,
-  96, 110, 98, 100, 81, 85, 70, 80, 107, 108,
-  31, 116, 63, 61, 89, 99, 120, 88, 71, 96,
-  94, 102, 111, 134, 146, 162, 82, 115, 100, 107,
-  67, 95, 90, 77, 122, 79, 99, 95, 104, 122,
-  99, 154, 106, 113, 131, 122, 102, 105, 92, 110,
-  81, 96, 100, 68, 136, 91, 84, 112, 75, 96,
-  93, 156, 80, 123, 24, 111, 110, 106, 134, 126,
-  141, 120, 96, 103, 87, 78, 105, 71, 86, 104,
-  148, 166, 155, 110, 87, 60, 92, 94, 84, 91,
-  93, 81, 70, 146, 124, 138, 108, 98, 78, 113,
-  110, 126, 120, 107, 64, 88, 83, 100, 124, 90,
-  37, 80, 105, 138, 97, 137, 96, 79, 109, 140,
-  77, 120, 109, 104, 97, 78, 63, 88, 110, 121,
-  134, 85, 63, 145, 78, 124, 68, 100, 80, 81,
-  68, 88, 104, 104, 80, 107, 127, 108, 85, 117,
-  103, 93, 142, 116, 70, 95, 96, 193, 77, 121,
-  125, 90, 79, 99, 105, 132, 116, 106, 107, 108,
-  111, 103, 74, 104, 87, 131, 118, 90, 109, 107,
-  125, 126, 104, 118, 112, 120, 109, 67, 95, 97,
-  116, 115, 118, 86, 105, 105, 95, 86, 86, 101,
-  114, 103, 39, 132, 91, 73, 121, 95, 116, 102,
-  95, 94, 103, 138, 109, 93, 117, 89, 112, 102,
-  123, 86, 95, 84, 87, 128, 105, 97, 111, 117,
-  92, 147, 121, 115, 145, 95, 118, 86, 113, 96,
-  108, 93, 87, 110, 112, 87, 127, 124, 108, 102,
-  84, 131, 123, 104, 94, 109, 49, 92, 129, 92,
-  144, 102, 84, 110, 108, 91, 81, 106, 133, 104,
-  97, 104, 147, 154, 211, 103, 102, 99, 115, 139,
-  107, 112, 98, 90, 91, 69, 128, 105, 119, 111,
-  94, 108, 101, 130, 133, 87, 116, 98, 108, 86,
-  116, 70, 57, 81, 97, 90, 112, 117, 163, 115,
-  90, 96, 127, 115, 136, 102, 109, 85, 95, 127,
-  94, 95, 87, 94, 93, 96, 73, 114, 119, 98,
-  93, 110, 63, 156, 101, 90, 72, 101, 99, 90,
-  73, 113, 112, 94, 153, 120, 75, 145, 117, 161,
-  114, 115, 90, 91, 97, 98, 97, 101, 90, 138,
-  84, 83, 88, 91, 80, 85, 110, 108, 152, 105,
-  115, 121, 98, 97, 99, 126, 116, 109, 126, 97,
-  119, 111, 99, 95, 129, 112, 110, 95, 82, 84,
-  98, 75, 107, 95, 28, 119, 107, 102, 124, 94,
-  96, 101, 130, 85, 95, 133, 118, 82, 94, 86,
-  74, 88, 143, 92, 117, 116, 85, 154, 91, 119,
-  121, 116, 100, 132, 121, 81, 115, 135, 89, 79,
-  117, 87, 128, 116, 76, 106, 95, 86, 119, 155,
-  107, 105, 93, 141, 124, 86, 88, 118, 100, 85,
-  127, 94, 131, 85, 59, 92, 115, 101, 65, 132,
-  121, 144, 101, 97, 102, 105, 136, 106, 94, 102,
-  120, 151, 108, 105, 105, 72, 110, 106, 133, 100,
-  124, 90, 72, 102, 103, 123, 110, 64, 118, 91,
-  152, 99, 118, 93, 58, 79, 125, 107, 111, 90,
-  124, 113, 99, 113, 154, 119, 97, 98, 96, 82,
-  81, 132, 105, 111, 78, 92, 132, 109, 89, 103,
-  105, 99, 85, 109, 46, 131, 94, 90, 89, 102,
-  64, 111, 92, 107, 92, 105, 131, 113, 59, 102,
-  105, 79, 109, 71, 92, 87, 107, 108, 105, 126,
-  82, 145, 88, 80, 80, 106, 65, 94, 105, 69,
-  151, 115, 119, 105, 105, 110, 60, 113, 74, 111,
-  101, 119, 100, 104, 95, 107, 92, 97, 94, 103,
-  73, 76, 94, 49, 100, 91, 40, 108, 112, 89,
-  85, 75, 77, 98, 147, 86, 109, 97, 109, 70,
-  112, 124, 62, 71, 116, 76, 101, 94, 97, 150,
-  88, 117, 122, 114, 99, 137, 126, 108, 113, 101,
-  108, 92, 95, 97, 105, 139, 48, 80, 98, 100,
-  114, 134, 96, 104, 81, 104, 102, 131, 97, 109,
-  122, 65, 95, 77, 153, 96, 51, 65, 123, 106,
-  55, 114, 103, 131, 86, 84, 94, 91, 121, 68,
-  92, 92, 84, 119, 94, 99, 105, 51, 81, 106,
-  116, 91, 116, 96, 103, 87, 101, 118, 88, 57,
-  82, 95, 124, 112, 117, 120, 42, 73, 112, 127,
-  89, 67, 80, 77, 81, 106, 111, 110, 117, 90,
-  86, 106, 86, 138, 112, 135, 91, 81, 121, 155,
-  83, 100, 59, 121, 41, 75, 66, 101, 72, 107,
-  99, 112, 81, 106, 87, 78, 116, 69, 99, 129,
-  56, 40, 97, 82, 74, 112, 77, 96, 101, 131,
-  83, 166, 99, 121, 109, 62, 98, 118, 46, 89,
-  82, 51, 117, 95, 149, 101, 109, 115, 70, 123,
-  79, 116, 85, 122, 80, 117, 105, 142, 95, 90,
-  106, 103, 78, 86, 104, 44, 92, 78, 57, 125,
-  132, 99, 86, 86, 99, 111, 109, 139, 129, 69,
-  98, 75, 126, 119, 103, 79, 100, 58, 75, 106,
-  98, 131, 105, 105, 129, 90, 75, 118, 112, 139,
-  122, 57, 168, 118, 77, 140, 94, 126, 89, 133,
-  105, 134, 104, 104, 106, 77, 102, 98, 108, 142,
-  123, 125, 129, 64, 69, 83, 128, 93, 70, 72,
-  134, 153, 74, 92, 105, 69, 93, 70, 92, 120,
-  136, 79, 110, 125, 116, 98, 130, 110, 107, 91,
-  83, 73, 80, 109, 130, 129, 114, 83, 102, 97,
-  102, 103, 76, 106, 85, 126, 98, 136, 50, 85,
-  83, 120, 109, 67, 88, 54, 55, 89, 78, 120,
-  143, 117, 85, 117, 104, 158, 121, 156, 103, 97,
-  104, 171, 81, 96, 73, 114, 45, 110, 72, 116,
-  82, 117, 113, 92, 81, 48, 103, 69, 98, 63,
-  92, 94, 76, 30, 91, 84, 64, 96, 69, 96,
-  75, 149, 70, 162, 115, 131, 121, 59, 128, 94,
-  75, 90, 96, 89, 102, 86, 162, 103, 93, 106,
-  100, 133, 96, 115, 99, 102, 92, 126, 115, 146,
-  90, 77, 113, 105, 94, 101, 106, 92, 98, 106,
-  92, 129, 155, 105, 102, 108, 129, 127, 47, 157,
-  132, 95, 89, 111, 127, 85, 137, 108, 100, 38,
-  80, 90, 103, 109, 108, 112, 119, 93, 80, 101,
-  95, 150, 129, 86, 167, 114, 100, 127, 124, 113,
-  139, 170, 129, 126, 105, 109, 97, 85, 97, 100,
-  115, 122, 192, 124, 130, 104, 70, 102, 103, 78,
-  106, 112, 140, 174, 94, 91, 102, 66, 119, 81,
-  112, 105, 145, 98, 113, 141, 150, 99, 150, 120,
-  101, 120, 104, 109, 93, 111, 129, 140, 101, 79,
-  96, 91, 127, 128, 83, 117, 81, 133, 93, 130,
-  74, 131, 74, 119, 126, 109, 115, 75, 111, 117,
-  76, 108, 162, 116, 105, 115, 127, 160, 128, 159,
-  117, 108, 100, 157, 96, 105, 85, 93, 88, 132,
-  65, 118, 95, 98, 115, 94, 109, 38, 116, 95,
-  123, 96, 94, 90, 102, 74, 100, 118, 86, 102,
-  103, 107, 83, 137, 79, 131, 110, 148, 143, 75,
-  135, 92, 99, 81, 118, 124, 105, 122, 155, 104,
-  109, 112, 103, 132, 122, 113, 136, 107, 113, 124,
-  104, 110, 130, 128, 111, 115, 132, 106, 122, 121,
-  141, 87, 89, 96, 119, 124, 135, 109, 138, 87,
-  114, 118, 105, 149, 102, 69, 90, 112, 138, 107,
-  135, 92, 119, 81, 83, 129, 119, 104, 107, 114,
-  79, 141, 130, 105, 139, 159, 106, 83, 115, 97,
-  131, 140, 136, 139, 98, 99, 121, 118, 109, 106,
-  123, 129, 125, 101, 160, 134, 81, 119, 108, 95,
-  79, 120, 104, 123, 110, 127, 97, 118, 112, 147,
-  109, 110, 102, 121, 83, 118, 138, 120, 159, 103,
-  139, 129, 133, 89, 137, 115, 118, 104, 139, 90,
-  66, 109, 103, 101, 109, 125, 108, 111, 121, 122,
-  97, 104, 101, 115, 86, 109, 119, 111, 123, 120,
-  111, 130, 122, 73, 125, 113, 106, 159, 73, 120,
-  111, 110, 111, 115, 130, 92, 131, 110, 109, 110,
-  129, 116, 55, 100, 112, 94, 98, 93, 82, 112,
-  137, 103, 88, 111, 119, 114, 113, 125, 114, 94,
-  119, 98, 83, 97, 112, 103, 101, 111, 87, 142,
-  113, 109, 126, 106, 106, 81, 97, 103, 107, 101,
-  165, 99, 135, 101, 76, 112, 122, 112, 135, 125,
-  91, 118, 90, 126, 109, 114, 106, 116, 123, 95,
-  114, 126, 133, 99, 80, 69, 29, 110, 143, 89,
-  98, 81, 133, 75, 83, 103, 80, 98, 104, 102,
-  123, 78, 119, 128, 123, 68, 69, 174, 89, 109,
-  100, 132, 63, 99, 107, 115, 147, 157, 66, 94,
-  102, 91, 122, 144, 106, 100, 106, 106, 109, 96,
-  101, 93, 120, 106, 119, 111, 99, 131, 83, 93,
-  90, 99, 99, 105, 100, 139, 104, 133, 90, 110,
-  122, 143, 99, 82, 98, 109, 95, 102, 106, 107,
-  150, 118, 151, 131, 146, 90, 123, 139, 95, 119,
-  141, 92, 69, 110, 75, 105, 111, 116, 106, 100,
-  116, 157, 99, 76, 81, 125, 56, 133, 96, 118,
-  141, 58, 121, 115, 117, 83, 128, 107, 103, 190,
-  109, 76, 130, 135, 125, 92, 114, 129, 133, 101,
-  111, 142, 109, 106, 86, 70, 122, 92, 74, 105,
-  149, 142, 106, 86, 120, 105, 96, 129, 91, 76,
-  101, 104, 90, 134, 85, 83, 104, 96, 98, 90,
-  100, 130, 109, 102, 109, 99, 102, 93, 99, 102,
-  88, 133, 138, 98, 157, 128, 80, 95, 137, 128,
-  97, 110, 88, 120, 97, 150, 123, 134, 106, 122,
-  139, 91, 123, 80, 125, 104, 74, 92, 35, 106,
-  144, 99, 95, 103, 116, 75, 95, 100, 79, 129,
-  125, 83, 108, 95, 108, 127, 83, 141, 80, 185,
-  118, 131, 105, 113, 94, 75, 88, 131, 126, 92,
-  67, 98, 91, 93, 107, 107, 91, 83, 112, 127,
-  112, 115, 85, 104, 101, 89, 126, 85, 81, 124,
-  87, 104, 109, 84, 122, 66, 103, 126, 97, 140,
-  96, 99, 109, 114, 106, 79, 121, 106, 107, 104,
-  115, 82, 143, 113, 159, 132, 134, 112, 109, 170,
-  85, 114, 114, 102, 76, 101, 86, 118, 105, 129,
-  115, 99, 102, 172, 113, 74, 69, 107, 80, 122,
-  119, 85, 162, 56, 118, 82, 121, 172, 107, 120,
-  77, 194, 126, 75, 141, 156, 139, 89, 119, 170,
-  124, 104, 59, 112, 89, 125, 103, 97, 135, 105,
-  78, 121, 114, 130, 89, 106, 107, 103, 121, 137,
-  90, 61, 99, 117, 79, 85, 131, 84, 103, 87,
-  108, 78, 96, 128, 126, 119, 84, 86, 80, 104,
-  106, 112, 97, 119, 155, 65, 83, 116, 75, 89,
-  110, 150, 83, 83, 69, 93, 64, 81, 89, 83,
-  105, 110, 119, 86, 100, 109, 113, 138, 41, 62,
-  32, 93, 123, 79, 115, 91, 121, 58, 93, 103,
-  64, 105, 121, 113, 73, 79, 82, 84, 92, 80,
-  59, 159, 100, 99, 89, 114, 76, 91, 86, 102,
-  100, 73, 80, 102, 101, 62, 108, 117, 69, 76,
-  89, 108, 91, 81, 75, 88, 63, 81, 104, 147,
-  86, 113, 70, 104, 94, 80, 113, 70, 66, 71,
-  88, 127, 59, 85, 110, 101, 89, 67, 122, 113,
-  124, 94, 88, 75, 112, 85, 106, 109, 122, 69,
-  74, 121, 87, 107, 119, 85, 75, 99, 57, 102,
-  108, 110, 92, 96, 101, 127, 111, 82, 52, 91,
-  67, 94, 67, 99, 97, 77, 95, 105, 109, 139,
-  84, 102, 91, 167, 76, 75, 112, 118, 108, 78,
-  94, 127, 95, 86, 46, 95, 69, 89, 62, 62,
-  96, 81, 39, 127, 60, 99, 78, 61, 109, 107,
-  122, 103, 89, 52, 88, 149, 83, 121, 76, 72,
-  87, 89, 134, 90, 80, 129, 92, 93, 96, 72,
-  59, 73, 110, 96, 64, 81, 182, 79, 121, 87,
-  136, 132, 123, 124, 98, 108, 82, 110, 71, 112,
-  105, 74, 95, 90, 120, 94, 112, 96, 114, 82,
-  50, 105, 77, 106, 148, 101, 139, 96, 93, 118,
-  113, 101, 81, 81, 86, 91, 123, 106, 107, 111,
-  95, 83, 54, 153, 101, 100, 99, 125, 62, 80,
-  70, 109, 113, 71, 138, 77, 94, 95, 139, 106,
-  126, 153, 99, 132, 112, 97, 105, 66, 84, 127,
-  133, 94, 107, 126, 93, 83, 91, 98, 98, 80,
-  60, 128, 102, 160, 83, 96, 115, 68, 104, 73,
-  75, 107, 124, 97, 121, 126, 146, 135, 129, 123,
-  98, 101, 95, 60, 94, 102, 110, 92, 61, 102,
-  84, 98, 106, 114, 121, 88, 96, 119, 106, 84,
-  61, 87, 85, 100, 142, 75, 166, 92, 91, 79,
-  104, 87, 134, 125, 92, 143, 126, 105, 106, 104,
-  74, 102, 108, 107, 90, 92, 108, 116, 96, 142,
-  54, 140, 118, 71, 74, 82, 82, 30, 71, 103,
-  82, 108, 97, 84, 124, 101, 80, 116, 87, 68,
-  89, 79, 91, 92, 107, 95, 68, 171, 87, 61,
-  87, 79, 73, 73, 120, 112, 86, 98, 162, 62,
-  97, 79, 95, 138, 124, 98, 110, 116, 76, 101,
-  73, 120, 105, 98, 76, 91, 116, 80, 109, 107,
-  107, 96, 45, 115, 79, 107, 134, 90, 124, 90,
-  98, 95, 77, 100, 69, 95, 99, 90, 90, 106,
-  97, 123, 93, 70, 52, 130, 121, 122, 92, 105,
-  64, 95, 88, 103, 114, 128, 124, 97, 92, 83,
-  191, 149, 122, 152, 96, 148, 127, 83, 111, 88,
-  99, 124, 135, 99, 80, 116, 108, 95, 84, 94,
-  124, 78, 75, 128, 111, 149, 90, 85, 94, 118,
-  103, 81, 82, 73, 79, 100, 133, 119, 129, 146,
-  107, 126, 96, 101, 94, 139, 106, 103, 120, 99,
-  74, 101, 74, 107, 116, 101, 111, 86, 116, 104,
-  114, 87, 37, 101, 77, 126, 120, 135, 140, 89,
-  105, 116, 107, 85, 102, 126, 106, 93, 149, 90,
-  109, 112, 91, 99, 100, 105, 73, 81, 78, 97,
-  91, 116, 78, 103, 101, 69, 63, 71, 130, 44,
-  78, 94, 110, 97, 88, 111, 117, 76, 74, 88,
-  84, 95, 85, 75, 94, 77, 139, 123, 73, 138,
-  90, 65, 90, 84, 83, 86, 94, 112, 94, 137,
-  113, 73, 133, 115, 46, 106, 137, 141, 126, 99,
-  73, 118, 89, 151, 88, 101, 83, 97, 123, 77,
-  121, 112, 104, 90, 58, 95, 68, 95, 131, 99,
-  103, 127, 93, 80, 83, 134, 60, 134, 160, 85,
-  98, 103, 105, 119, 73, 107, 102, 138, 151, 134,
-  103, 134, 99, 100, 93, 116, 140, 154, 96, 113,
-  92, 92, 131, 147, 81, 91, 106, 120, 108, 120,
-  87, 125, 117, 95, 120, 132, 90, 97, 109, 108,
-  100, 86, 148, 66, 97, 86, 121, 149, 104, 87,
-  114, 137, 90, 106, 120, 87, 77, 109, 109, 67,
-  107, 131, 126, 105, 117, 122, 97, 119, 93, 114,
-  116, 109, 98, 116, 96, 111, 103, 113, 111, 116,
-  92, 131, 126, 57, 50, 104, 89, 124, 121, 126,
-  140, 85, 132, 105, 118, 134, 85, 128, 100, 81,
-  135, 93, 138, 158, 136, 83, 98, 135, 96, 112,
-  87, 107, 69, 83, 157, 93, 103, 110, 81, 106,
-  117, 125, 86, 127, 131, 111, 120, 149, 80, 78,
-  102, 96, 80, 138, 122, 79, 94, 78, 146, 130,
-  95, 89, 121, 87, 82, 76, 71, 119, 85, 93,
-  95, 120, 91, 78, 111, 115, 84, 111, 161, 143,
-  138, 103, 81, 114, 97, 153, 110, 108, 98, 93,
-  116, 105, 115, 125, 102, 132, 75, 117, 74, 92,
-  136, 97, 116, 125, 118, 78, 114, 144, 86, 138,
-  162, 99, 87, 106, 125, 109, 85, 125, 103, 132,
-  149, 138, 93, 128, 109, 94, 83, 135, 116, 96,
-  82, 98, 120, 89, 100, 101, 135, 119, 130, 92,
-  96, 144, 103, 122, 119, 78, 129, 119, 84, 97,
-  92, 109, 92, 96, 103, 60, 110, 130, 105, 139,
-  101, 105, 122, 120, 102, 102, 143, 100, 153, 115,
-  107, 60, 146, 117, 122, 102, 161, 138, 125, 132,
-  91, 114, 112, 136, 76, 124, 113, 118, 83, 139,
-  109, 119, 88, 129, 135, 84, 68, 100, 83, 87,
-  124, 81, 127, 114, 147, 109, 103, 142, 115, 117,
-  107, 78, 125, 114, 150, 146, 133, 103, 130, 109,
-  91, 107, 72, 100, 106, 98, 74, 105, 117, 107,
-  81, 151, 67, 132, 85, 109, 123, 127, 113, 129,
-  106, 98, 117, 140, 97, 138, 131, 109, 128, 92,
-  104, 117, 98, 91, 144, 120, 87, 79, 93, 93,
-  84, 89, 82, 112, 90, 87, 103, 104, 147, 134,
-  134, 130, 128, 144, 87, 105, 78, 127, 109, 101,
-  106, 98, 110, 116, 103, 147, 103, 127, 70, 132,
-  87, 91, 129, 83, 105, 75, 136, 72, 89, 119,
-  107, 113, 118, 96, 79, 100, 135, 81, 124, 86,
-  78, 141, 142, 107, 76, 135, 88, 119, 75, 88,
-  100, 122, 96, 141, 123, 93, 120, 93, 131, 105,
-  106, 107, 89, 130, 116, 99, 123, 100, 128, 117,
-  91, 106, 77, 90, 99, 102, 94, 81, 60, 135,
-  108, 125, 98, 120, 137, 107, 105, 94, 119, 123,
-  138, 112, 99, 109, 122, 119, 79, 118, 167, 110,
-  124, 95, 151, 123, 128, 104, 104, 131, 131, 100,
-  87, 105, 119, 101, 103, 108, 137, 83, 97, 61,
-  86, 83, 107, 76, 81, 141, 130, 123, 106, 85,
-  127, 114, 99, 65, 107, 107, 113, 102, 106, 105,
-  126, 95, 97, 100, 90, 151, 125, 117, 63, 86,
-  105, 84, 90, 152, 93, 111, 90, 91, 109, 143,
-  91, 111, 106, 83, 100, 154, 96, 128, 98, 118,
-  135, 96, 106, 126, 96, 105, 123, 116, 109, 78,
-  93, 83, 102, 103, 99, 116, 102, 93, 100, 116,
-  189, 162, 113, 131, 101, 144, 86, 106, 86, 154,
-  97, 105, 92, 111, 107, 116, 116, 99, 110, 97,
-  74, 162, 91, 90, 123, 84, 114, 68, 122, 84,
-  91, 87, 115, 111, 88, 79, 82, 113, 115, 77,
-  139, 96, 76, 175, 130, 100, 100, 132, 60, 129,
-  69, 101, 111, 115, 103, 145, 113, 100, 107, 102,
-  134, 106, 104, 135, 86, 110, 93, 86, 117, 117,
-  129, 95, 103, 126, 90, 89, 116, 98, 118, 88,
-  59, 101, 112, 138, 108, 100, 118, 97, 95, 96,
-  86, 127, 98, 108, 112, 147, 117, 117, 85, 122,
-  123, 100, 110, 77, 161, 103, 128, 114, 114, 124,
-  160, 99, 78, 83, 131, 92, 101, 124, 127, 76,
-  97, 45, 92, 95, 114, 64, 74, 122, 97, 93,
-  103, 101, 135, 110, 84, 70, 91, 116, 108, 114,
-  106, 104, 107, 99, 120, 95, 99, 173, 112, 124,
-  80, 95, 119, 94, 135, 119, 94, 101, 88, 96,
-  114, 120, 95, 109, 107, 59, 90, 117, 64, 107,
-  113, 105, 123, 96, 95, 126, 99, 115, 128, 112,
-  102, 61, 105, 109, 104, 146, 106, 117, 92, 92,
-  95, 116, 182, 174, 113, 134, 101, 139, 83, 102,
-  102, 185, 90, 111, 96, 110, 106, 124, 107, 77,
-  119, 89, 72, 170, 82, 105, 126, 92, 127, 69,
-  107, 98, 101, 72, 117, 136, 76, 71, 89, 125,
-  112, 68, 144, 104, 74, 175, 128, 108, 107, 100,
-  68, 102, 68, 118, 109, 96, 104, 156, 103, 111,
-  109, 98, 150, 122, 116, 132, 88, 82, 71, 80,
-  111, 100, 139, 86, 114, 145, 133, 124, 114, 99,
-  104, 83, 85, 97, 103, 152, 129, 89, 100, 112,
-  91, 95, 84, 105, 84, 119, 124, 150, 120, 109,
-  109, 105, 109, 93, 113, 99, 150, 120, 130, 113,
-  105, 132, 169, 94, 72, 98, 146, 76, 108, 136,
-  126, 77, 93, 64, 89, 104, 122, 63, 69, 111,
-  74, 67, 92, 140, 136, 119, 70, 62, 107, 111,
-  115, 133, 117, 103, 101, 104, 127, 98, 111, 145,
-  111, 126, 73, 115, 136, 94, 155, 109, 89, 94,
-  94, 102, 97, 101, 92, 85, 114, 55, 92, 98,
-  63, 86, 130, 92, 108, 98, 101, 111, 101, 117,
-  138, 120, 71, 67, 105, 112, 119, 180, 118, 124,
-  89, 82, 87, 106, 152, 164, 112, 119, 103, 128,
-  84, 82, 96, 178, 94, 116, 114, 126, 96, 122,
-  78, 85, 106, 101, 69, 149, 81, 125, 120, 91,
-  112, 90, 114, 94, 103, 78, 107, 138, 85, 77,
-  92, 131, 115, 56, 141, 122, 78, 137, 132, 109,
-  90, 95, 84, 91, 75, 113, 102, 102, 89, 151,
-  81, 108, 124, 101, 144, 111, 118, 131, 95, 82,
-  82, 67, 107, 92, 133, 92, 98, 149, 179, 164,
-  105, 96, 93, 81, 96, 81, 90, 141, 125, 97,
-  118, 129, 104, 94, 78, 78, 92, 129, 122, 135,
-  105, 124, 108, 93, 96, 103, 113, 113, 144, 128,
-  119, 101, 118, 128, 153, 91, 76, 102, 144, 62,
-  124, 122, 141, 89, 93, 91, 93, 120, 117, 85,
-  79, 111, 84, 80, 92, 134, 130, 116, 62, 50,
-  133, 109, 113, 128, 119, 100, 94, 98, 102, 113,
-  114, 141, 108, 119, 83, 115, 131, 90, 141, 116,
-  103, 96, 108, 103, 113, 106, 73, 73, 123, 58,
-  101, 110, 79, 92, 131, 109, 116, 108, 100, 123,
-  106, 112, 145, 117, 57, 97, 100, 99, 112, 185,
-  106, 122, 90, 73, 92, 98, 121, 136, 108, 109,
-  98, 110, 91, 65, 65, 155, 110, 110, 122, 130,
-  72, 113, 62, 106, 91, 114, 62, 119, 97, 126,
-  102, 85, 99, 113, 131, 108, 100, 90, 109, 125,
-  111, 90, 95, 127, 114, 66, 137, 123, 91, 97,
-  138, 105, 71, 95, 96, 97, 94, 101, 96, 106,
-  94, 146, 80, 101, 128, 115, 131, 102, 115, 144,
-  94, 99, 105, 82, 106, 85, 121, 122, 85, 139,
-  165, 182, 97, 84, 81, 98, 88, 84, 81, 133,
-  119, 129, 150, 114, 129, 86, 62, 95, 101, 130,
-  109, 115, 98, 112, 101, 79, 97, 101, 103, 104,
-  129, 143, 112, 95, 108, 131, 121, 93, 81, 113,
-  130, 72, 131, 99, 139, 103, 83, 105, 98, 115,
-  114, 99, 75, 99, 95, 112, 94, 104, 104, 105,
-  64, 44, 122, 114, 112, 121, 120, 94, 76, 98,
-  95, 125, 99, 161, 105, 109, 99, 100, 120, 91,
-  120, 127, 99, 90, 125, 91, 131, 121, 64, 72,
-  118, 57, 115, 109, 89, 100, 133, 120, 125, 117,
-  110, 129, 106, 103, 142, 121, 76, 123, 100, 84,
-  107, 181, 81, 100, 90, 85, 99, 85, 120, 136,
-  113, 121, 89, 117, 100, 67, 65, 164, 105, 97,
-  136, 125, 52, 104, 57, 126, 83, 108, 67, 123,
-  91, 114, 111, 93, 100, 94, 108, 125, 90, 89,
-  106, 114, 119, 78, 102, 131, 112, 75, 123, 105,
-  96, 79, 135, 110, 60, 104, 97, 105, 96, 99,
-  101, 100, 107, 138, 83, 103, 104, 109, 147, 115,
-  102, 138, 102, 113, 115, 88, 97, 86, 114, 109,
-  96, 117, 125, 184, 94, 82, 83, 120, 94, 104,
-  67, 139, 116, 157, 147, 99, 131, 81, 62, 123,
-  115, 122, 97, 96, 110, 99, 101, 73, 97, 108,
-  102, 89, 125, 135, 106, 111, 103, 130, 108, 82,
-  85, 116, 134, 79, 138, 101, 154, 92, 83, 99,
-  101, 107, 133, 75, 81, 95, 103, 121, 105, 95,
-  92, 90, 64, 40, 99, 115, 111, 133, 119, 94,
-  75, 99, 95, 128, 83, 155, 113, 106, 119, 112,
-  140, 94, 114, 127, 96, 68, 120, 105, 127, 127,
-  66, 91, 114, 71, 119, 104, 89, 99, 167, 114,
-  126, 99, 116, 105, 110, 103, 145, 126, 93, 138,
-  120, 73, 117, 176, 92, 102, 92, 104, 90, 90,
-  135, 146, 135, 99, 88, 123, 116, 79, 84, 170,
-  114, 100, 132, 127, 67, 117, 50, 127, 82, 105,
-  74, 127, 99, 100, 128, 103, 107, 74, 91, 129,
-  80, 87, 100, 117, 100, 81, 93, 143, 117, 56,
-  127, 111, 89, 80, 121, 121, 65, 104, 92, 105,
-  95, 84, 105, 121, 101, 133, 82, 108, 74, 103,
-  151, 122, 85, 128, 99, 106, 115, 84, 98, 91,
-  111, 88, 83, 116, 120, 176, 86, 90, 68, 121,
-  112, 133, 56, 140, 105, 160, 133, 111, 118, 88,
-  62, 110, 124, 124, 82, 92, 120, 105, 108, 88,
-  92, 108, 107, 103, 129, 119, 98, 103, 112, 137,
-  113, 89, 89, 114, 135, 84, 146, 113, 181, 90,
-  86, 98, 112, 116, 134, 72, 89, 104, 108, 113,
-  98, 95, 98, 76, 61, 42, 105, 119, 112, 139,
-  122, 106, 91, 100, 105, 127, 81, 139, 132, 114,
-  98, 108, 145, 91, 116, 118, 100, 77, 121, 132,
-  103, 139, 77, 99, 106, 70, 122, 117, 97, 70,
-  170, 117, 119, 77, 147, 100, 104, 110, 149, 128,
-  90, 139, 113, 74, 117, 176, 97, 127, 88, 119,
-  93, 114, 137, 129, 132, 103, 88, 104, 117, 89,
-  80, 158, 131, 133, 123, 122, 86, 120, 50, 103,
-  72, 106, 69, 118, 92, 82, 144, 92, 98, 83,
-  105, 124, 86, 88, 105, 107, 104, 92, 88, 142,
-  132, 43, 135, 107, 72, 85, 120, 115, 71, 133,
-  87, 106, 90, 74, 105, 139, 92, 158, 107, 109,
-  89, 114, 135, 112, 98, 131, 99, 106, 97, 79,
-  101, 97, 114, 101, 80, 115, 104, 157, 91, 91,
-  78, 111, 91, 136, 47, 125, 99, 131, 125, 97,
-  91, 90, 67, 121, 111, 117, 106, 93, 119, 96,
-  94, 114, 82, 105, 109, 113, 137, 141, 105, 91,
-  119, 137, 108, 89, 98, 106, 132, 91, 145, 132,
-  190, 87, 83, 96, 118, 113, 120, 85, 85, 103,
-  95, 123, 88, 85, 67, 75, 72, 45, 93, 151,
-  115, 125, 122, 110, 97, 108, 108, 116, 87, 147,
-  132, 130, 74, 96, 130, 95, 111, 128, 119, 92,
-  113, 125, 100, 153, 88, 96, 102, 58, 129, 119,
-  98, 102, 145, 124, 119, 73, 168, 120, 112, 105,
-  132, 129, 82, 136, 99, 90, 107, 175, 80, 114,
-  84, 125, 98, 137, 144, 147, 119, 105, 101, 93,
-  140, 96, 98, 165, 121, 150, 122, 122, 100, 99,
-  61, 84, 100, 62, 61, 152, 96, 82, 139, 94,
-  112, 70, 103, 125, 95, 96, 101, 105, 81, 86,
-  104, 146, 139, 62, 110, 99, 82, 103, 122, 110,
-  85, 163, 85, 140, 99, 113, 119, 150, 96, 135,
-  139, 122, 114, 125, 137, 111, 121, 132, 107, 134,
-  87, 91, 111, 90, 111, 84, 93, 106, 68, 116,
-  91, 106, 92, 122, 113, 123, 49, 128, 108, 113,
-  113, 96, 78, 94, 69, 116, 104, 89, 155, 102,
-  133, 98, 78, 155, 98, 111, 129, 97, 200, 127,
-  107, 98, 97, 127, 135, 100, 105, 110, 102, 93,
-  138, 140, 158, 79, 67, 68, 124, 112, 126, 68,
-  109, 118, 101, 132, 100, 81, 65, 82, 92, 52,
-  92, 182, 97, 119, 119, 126, 126, 116, 119, 126,
-  103, 164, 128, 123, 70, 96, 102, 101, 130, 130,
-  132, 81, 109, 133, 116, 145, 86, 126, 102, 57,
-  105, 125, 90, 128, 138, 120, 137, 82, 141, 150,
-  114, 110, 112, 109, 78, 124, 96, 107, 94, 167,
-  86, 99, 76, 127, 117, 161, 123, 141, 102, 89,
-  114, 90, 146, 100, 113, 166, 132, 154, 105, 135,
-  110, 81, 78, 78, 126, 70, 49, 168, 111, 81,
-  116, 83, 101, 75, 119, 112, 83, 102, 100, 100,
-  81, 97, 114, 130, 146, 97, 93, 106, 97, 118,
-  113, 107, 94, 129, 79, 167, 112, 166, 130, 141,
-  116, 153, 169, 149, 120, 125, 124, 101, 130, 142,
-  125, 136, 96, 96, 120, 91, 100, 85, 87, 100,
-  62, 98, 113, 109, 113, 147, 119, 84, 71, 113,
-  118, 104, 95, 98, 80, 85, 84, 118, 109, 78,
-  159, 116, 127, 108, 79, 162, 109, 83, 124, 102,
-  213, 104, 115, 131, 89, 140, 149, 122, 101, 115,
-  101, 95, 113, 122, 124, 64, 59, 75, 128, 121,
-  136, 88, 128, 114, 93, 121, 111, 100, 90, 106,
-  112, 72, 98, 150, 80, 109, 113, 122, 138, 119,
-  120, 130, 107, 151, 104, 113, 105, 102, 87, 109,
-  153, 122, 161, 79, 106, 125, 110, 106, 97, 149,
-  102, 60, 86, 116, 78, 118, 113, 100, 141, 110,
-  134, 155, 117, 103, 94, 80, 72, 115, 107, 104,
-  82, 134, 119, 101, 73, 119, 113, 154, 111, 124,
-  103, 98, 117, 106, 129, 99, 104, 170, 120, 131,
-  71, 113, 87, 63, 78, 70, 148, 104, 30, 164,
-  121, 96, 89, 86, 95, 79, 127, 101, 69, 103,
-  96, 95, 102, 92, 113, 109, 135, 99, 74, 125,
-  123, 119, 113, 119, 96, 81, 75, 165, 109, 178,
-  125, 116, 136, 173, 186, 159, 93, 112, 107, 105,
-  121, 118, 126, 123, 117, 81, 121, 95, 89, 101,
-  86, 117, 80, 105, 122, 123, 104, 146, 106, 71,
-  85, 112, 119, 95, 91, 111, 86, 75, 100, 135,
-  129, 91, 134, 118, 101, 86, 102, 129, 122, 82,
-  99, 103, 195, 90, 120, 164, 79, 157, 138, 147,
-  108, 103, 107, 129, 97, 103, 118, 66, 44, 73,
-  115, 106, 140, 88, 140, 87, 68, 90, 131, 124,
-  110, 127, 117, 75, 81, 105, 75, 118, 114, 116,
-  130, 141, 106, 130, 114, 129, 83, 97, 118, 92,
-  99, 103, 166, 107, 135, 72, 79, 104, 102, 89,
-  106, 162, 92, 51, 92, 85, 71, 103, 99, 72,
-  135, 138, 146, 152, 115, 87, 79, 53, 104, 105,
-  123, 99, 73, 82, 134, 93, 82, 97, 130, 124,
-  119, 121, 133, 105, 125, 135, 104, 121, 90, 192,
-  114, 109, 74, 95, 98, 60, 93, 74, 175, 86,
-  26, 192, 122, 117, 99, 116, 111, 60, 88, 123,
-  77, 102, 91, 114, 115, 100, 112, 115, 128, 96,
-  76, 149, 114, 125, 133, 136, 98, 68, 85, 123,
-  109, 167, 111, 96, 148, 181, 133, 166, 55, 90,
-  116, 129, 89, 121, 101, 107, 106, 72, 139, 97,
-  105, 95, 95, 132, 99, 124, 133, 122, 93, 150,
-  120, 106, 88, 143, 123, 106, 70, 129, 98, 63,
-  93, 135, 136, 118, 117, 121, 119, 93, 120, 120,
-  132, 124, 88, 118, 156, 126, 117, 150, 77, 171,
-  142, 143, 116, 117, 125, 115, 82, 107, 133, 82,
-  58, 67, 92, 95, 144, 76, 152, 77, 62, 34,
-  144, 159, 144, 149, 99, 90, 105, 100, 94, 135,
-  110, 103, 131, 157, 104, 134, 115, 111, 89, 118,
-  120, 96, 128, 100, 172, 80, 96, 58, 95, 112,
-  82, 68, 100, 148, 95, 43, 116, 84, 69, 91,
-  103, 63, 100, 148, 152, 148, 114, 83, 84, 57,
-  113, 114, 142, 109, 75, 77, 150, 115, 76, 82,
-  90, 131, 116, 109, 160, 108, 125, 153, 82, 144,
-  71, 203, 127, 130, 82, 96, 132, 88, 90, 95,
-  125, 86, 38, 216, 96, 125, 118, 124, 127, 49,
-  61, 148, 98, 107, 89, 137, 132, 125, 105, 148,
-  122, 130, 85, 135, 90, 113, 141, 113, 92, 89,
-  108, 93, 107, 151, 105, 110, 146, 178, 103, 156,
-  68, 100, 138, 145, 93, 114, 105, 99, 114, 111,
-  149, 95, 116, 113, 87, 150, 108, 148, 124, 118,
-  81, 161, 137, 152, 92, 158, 134, 106, 64, 115,
-  102, 61, 87, 138, 102, 128, 129, 109, 128, 76,
-  99, 121, 135, 144, 108, 137, 123, 163, 109, 102,
-  66, 159, 144, 120, 115, 135, 125, 76, 87, 115,
-  133, 118, 77, 89, 83, 118, 141, 88, 111, 87,
-  99, 72, 123, 148, 125, 160, 84, 73, 122, 82,
-  114, 142, 108, 109, 134, 151, 90, 126, 92, 105,
-  108, 149, 86, 92, 155, 88, 154, 78, 115, 65,
-  128, 123, 76, 58, 94, 95, 103, 44, 131, 112,
-  77, 93, 116, 98, 78, 133, 138, 131, 114, 90,
-  93, 108, 107, 120, 130, 99, 76, 125, 157, 140,
-  71, 76, 101, 139, 89, 101, 149, 79, 101, 138,
-  93, 134, 92, 171, 140, 164, 91, 132, 126, 103,
-  76, 104, 96, 78, 57, 183, 100, 83, 113, 106,
-  117, 87, 77, 130, 88, 113, 97, 149, 143, 145,
-  98, 163, 128, 148, 73, 98, 50, 98, 142, 86,
-  71, 101, 123, 127, 112, 132, 119, 126, 119, 137,
-  94, 126, 89, 113, 127, 131, 91, 104, 112, 94,
-  98, 124, 124, 93, 102, 126, 68, 139, 78, 152,
-  100, 94, 113, 146, 132, 150, 98, 130, 112, 104,
-  96, 115, 98, 68, 94, 158, 101, 106, 124, 84,
-  117, 107, 74, 120, 131, 121, 108, 162, 148, 181,
-  96, 71, 81, 121, 140, 127, 112, 137, 98, 89,
-  98, 114, 126, 114, 65, 100, 126, 141, 123, 106,
-  103, 104, 139, 126, 80, 90, 100, 131, 92, 75,
-  76, 62, 95, 134, 131, 113, 130, 133, 83, 133,
-  54, 118, 105, 124, 88, 98, 134, 78, 116, 105,
-  146, 51, 115, 120, 98, 83, 111, 100, 96, 61,
-  107, 159, 98, 104, 135, 138, 108, 110, 111, 139,
-  112, 100, 108, 115, 116, 133, 92, 82, 73, 147,
-  153, 118, 78, 84, 111, 150, 80, 104, 114, 76,
-  99, 81, 99, 96, 113, 117, 103, 122, 90, 139,
-  93, 98, 63, 86, 96, 93, 53, 107, 91, 62,
-  95, 89, 102, 103, 89, 95, 91, 128, 98, 121,
-  150, 141, 95, 137, 112, 112, 84, 72, 68, 117,
-  134, 70, 75, 103, 88, 171, 112, 108, 116, 119,
-  113, 117, 119, 99, 117, 116, 80, 95, 113, 84,
-  131, 99, 114, 121, 79, 112, 95, 139, 81, 114,
-  52, 128, 98, 82, 151, 121, 99, 102, 102, 101,
-  97, 101, 114, 97, 83, 102, 117, 151, 151, 94,
-  93, 78, 94, 124, 63, 107, 109, 80, 78, 115,
-  151, 102, 110, 109, 87, 109, 112, 132, 123, 105,
-  73, 99, 102, 83, 127, 86, 47, 88, 125, 111,
-  101, 116, 103, 124, 112, 159, 87, 85, 120, 93,
-  120, 75, 63, 88, 83, 109, 121, 99, 87, 110,
-  72, 129, 86, 114, 88, 77, 84, 109, 92, 96,
-  89, 126, 141, 95, 74, 108, 122, 94, 128, 117,
-  72, 99, 90, 177, 93, 128, 103, 118, 125, 106,
-  121, 124, 99, 112, 90, 99, 104, 103, 76, 86,
-  85, 137, 136, 90, 93, 116, 133, 131, 93, 127,
-  122, 124, 126, 68, 111, 102, 118, 99, 114, 101,
-  106, 124, 84, 91, 90, 81, 120, 87, 39, 113,
-  108, 80, 118, 93, 97, 94, 116, 93, 122, 149,
-  107, 82, 129, 82, 98, 107, 141, 88, 97, 106,
-  82, 159, 115, 106, 106, 121, 90, 152, 136, 99,
-  134, 111, 96, 84, 114, 99, 120, 113, 71, 99,
-  115, 83, 134, 145, 103, 107, 81, 131, 119, 87,
-  100, 112, 81, 94, 126, 83, 153, 96, 70, 99,
-  105, 95, 87, 118, 119, 133, 94, 107, 136, 125,
-  188, 105, 101, 93, 119, 152, 104, 116, 107, 73,
-  97, 73, 138, 96, 115, 114, 100, 106, 115, 137,
-  120, 91, 105, 91, 124, 87, 122, 78, 52, 78,
-  118, 92, 115, 100, 161, 125, 103, 101, 149, 123,
-  137, 92, 117, 85, 83, 135, 101, 105, 83, 95,
-  115, 106, 80, 125, 118, 105, 78, 88, 77, 155,
-  85, 97, 91, 108, 85, 107, 62, 123, 113, 101,
-  143, 131, 67, 123, 106, 112, 109, 99, 96, 80,
-  120, 110, 110, 101, 85, 137, 90, 76, 74, 98,
-  77, 104, 101, 97, 167, 91, 104, 119, 91, 104,
-  67, 121, 105, 110, 126, 107, 103, 109, 103, 93,
-  104, 100, 91, 105, 73, 81, 96, 59, 119, 111,
-  29, 107, 119, 92, 107, 84, 68, 92, 143, 85,
-  108, 120, 108, 73, 101, 107, 63, 82, 141, 76,
-  104, 122, 90, 164, 90, 126, 124, 115, 91, 136,
-  127, 86, 117, 116, 92, 89, 111, 94, 119, 132,
-  57, 79, 96, 90, 118, 151, 104, 99, 97, 121,
-  109, 111, 92, 109, 115, 74, 113, 82, 149, 91,
-  57, 73, 116, 106, 65, 129, 101, 145, 95, 98,
-  103, 91, 135, 95, 87, 90, 106, 138, 105, 110,
-  114, 55, 93, 115, 138, 96, 113, 99, 97, 94,
-  106, 134, 95, 61, 88, 91, 132, 107, 120, 106,
-  41, 63, 115, 119, 89, 75, 100, 88, 90, 111,
-  140, 131, 118, 93, 100, 94, 85, 155, 114, 132,
-  85, 87, 123, 142, 88, 111, 81, 109, 58, 81,
-  48, 109, 77, 101, 99, 103, 71, 122, 75, 102,
-  108, 92, 123, 136, 51, 66, 96, 76, 88, 96,
-  101, 77, 108, 123, 104, 145, 83, 122, 103, 70,
-  80, 118, 52, 110, 91, 53, 136, 100, 134, 105,
-  101, 108, 57, 117, 77, 115, 100, 117, 82, 116,
-  104, 114, 93, 93, 91, 111, 85, 84, 97, 60,
-  101, 81, 49, 117, 113, 95, 87, 77, 84, 103,
-  139, 110, 125, 85, 99, 71, 115, 136, 83, 76,
-  113, 60, 86, 98, 98, 141, 95, 110, 130, 99,
-  81, 121, 120, 121, 113, 70, 139, 112, 79, 124,
-  94, 130, 67, 95, 95, 123, 100, 110, 98, 87,
-  97, 97, 105, 156, 99, 120, 120, 65, 84, 75,
-  143, 107, 63, 60, 120, 129, 59, 109, 105, 95,
-  85, 80, 91, 106, 132, 81, 88, 107, 104, 98,
-  118, 114, 124, 67, 72, 87, 94, 100, 113, 118,
-  121, 74, 98, 112, 94, 84, 78, 110, 101, 116,
-  98, 119, 49, 78, 89, 122, 86, 64, 74, 60,
-  55, 87, 94, 124, 140, 113, 90, 118, 91, 164,
-  120, 146, 100, 86, 108, 164, 85, 103, 71, 121,
-  37, 93, 71, 107, 73, 116, 111, 103, 71, 81,
-  97, 70, 104, 70, 103, 111, 69, 35, 92, 87,
-  70, 110, 74, 86, 85, 146, 93, 165, 106, 118,
-  119, 61, 112, 99, 53, 104, 84, 65, 96, 77,
-  179, 98, 103, 109, 85, 126, 90, 122, 99, 123,
-  79, 121, 99, 131, 106, 93, 89, 114, 96, 105,
-  88, 71, 91, 96, 62, 107, 113, 104, 106, 90,
-  109, 104, 92, 157, 123, 65, 89, 88, 119, 104,
-  120, 92, 95, 54, 81, 99, 90, 123, 108, 83,
-  113, 89, 59, 86, 93, 142, 114, 58, 166, 111,
-  95, 127, 110, 103, 117, 150, 95, 127, 105, 95,
-  106, 68, 115, 94, 119, 136, 116, 137, 130, 74,
-  55, 101, 78, 103, 87, 87, 108, 162, 72, 89,
-  106, 33, 99, 61, 81, 134, 147, 91, 99, 142,
-  143, 85, 147, 123, 117, 97, 90, 62, 79, 122,
-  128, 132, 105, 72, 81, 84, 113, 117, 70, 108,
-  92, 117, 78, 111, 66, 95, 69, 106, 105, 62,
-  95, 53, 74, 101, 59, 105, 154, 112, 93, 124,
-  99, 158, 122, 149, 94, 109, 88, 153, 92, 88,
-  91, 108, 54, 134, 52, 114, 88, 112, 98, 78,
-  74, 36, 112, 74, 104, 82, 92, 84, 93, 46,
-  86, 94, 68, 94, 74, 91, 83, 147, 78, 117,
-  116, 154, 126, 67, 124, 84, 83, 96, 107, 112,
-  96, 86, 175, 96, 98, 98, 106, 130, 100, 111,
-  110, 104, 97, 122, 115, 130, 94, 83, 101, 114,
-  110, 106, 88, 99, 113, 100, 90, 114, 134, 111,
-  119, 109, 120, 131, 42, 152, 111, 98, 88, 116,
-  105, 74, 141, 111, 102, 40, 107, 84, 91, 122,
-  104, 105, 102, 91, 73, 90, 90, 132, 129, 97,
-  146, 112, 101, 105, 130, 100, 142, 161, 124, 120,
-  106, 106, 92, 80, 101, 103, 120, 94, 179, 130,
-  123, 112, 70, 108, 85, 78, 110, 119, 122, 174,
-  93, 86, 108, 74, 114, 84, 105, 95, 143, 99,
-  105, 145, 158, 109, 149, 121, 104, 118, 106, 120,
-  92, 106, 129, 127, 99, 78, 79, 87, 126, 127,
-  87, 103, 86, 126, 91, 94, 93, 135, 76, 112,
-  115, 115, 126, 85, 125, 112, 81, 105, 145, 97,
-  113, 129, 127, 130, 117, 149, 113, 110, 91, 135,
-  112, 96, 86, 94, 93, 145, 78, 118, 99, 88,
-  90, 90, 112, 45, 112, 107, 136, 99, 97, 101,
-  107, 89, 88, 124, 98, 99, 111, 104, 97, 127,
-  92, 108, 102, 161, 146, 76, 114, 89, 97, 94,
-  126, 132, 114, 132, 150, 101, 103, 112, 99, 131,
-  117, 117, 125, 106, 111, 127, 103, 108, 114, 123,
-  115, 113, 133, 104, 135, 132, 139, 98, 85, 97,
-  116, 116, 132, 112, 134, 95, 120, 111, 115, 143,
-  97, 67, 95, 110, 138, 100, 133, 88, 119, 79,
-  82, 142, 125, 104, 108, 124, 79, 132, 121, 105,
-  137, 156, 96, 84, 108, 94, 144, 144, 133, 130,
-  97, 104, 124, 116, 93, 103, 120, 117, 125, 98,
-  160, 131, 86, 114, 108, 98, 88, 104, 93, 119,
-  112, 125, 95, 116, 114, 146, 110, 105, 102, 113,
-  83, 119, 142, 112, 157, 106, 135, 123, 134, 90,
-  137, 113, 123, 119, 132, 89, 71, 113, 104, 96,
-  106, 123, 110, 106, 119, 129, 105, 109, 94, 112,
-  85, 111, 112, 118, 124, 111, 108, 127, 127, 76,
-  126, 116, 109, 161, 72, 118, 113, 115, 114, 109,
-  123, 98, 125, 111, 109, 118, 123, 111, 53, 87,
-  112, 92, 98, 90, 88, 121, 128, 95, 91, 116,
-  119, 116, 109, 115, 118, 93, 113, 103, 87, 97,
-  113, 101, 98, 114, 92, 140, 116, 110, 121, 101,
-  108, 82, 100, 112, 94, 95, 162, 97, 142, 107,
-  78, 117, 124, 117, 123, 127, 93, 126, 89, 131,
-  105, 109, 112, 112, 129, 100, 120, 129, 136, 93,
-  79, 71, 31, 106, 147, 96, 102, 89, 132, 71,
-  89, 104, 85, 99, 102, 109, 128, 80, 124, 119,
-  122, 78, 72, 183, 91, 117, 106, 132, 66, 98,
-  101, 118, 147, 152, 65, 95, 96, 89, 133, 149,
-  111, 97, 103, 116, 108, 93, 100, 93, 120, 97,
-  122, 110, 100, 131, 82, 90, 87, 108, 100, 106,
-  97, 139, 105, 133, 91, 107, 119, 138, 97, 83,
-  103, 95, 96, 106, 107, 100, 148, 121, 159, 125,
-  151, 91, 124, 138, 89, 119, 134, 91, 75, 109,
-  80, 101, 112, 120, 111, 100, 110, 161, 101, 80,
-  78, 121, 63, 139, 98, 108, 143, 59, 121, 116,
-  123, 85, 134, 112, 106, 195, 113, 79, 132, 145,
-  134, 92, 114, 134, 136, 106, 113, 151, 107, 102,
-  81, 71, 134, 98, 75, 109, 148, 146, 109, 90,
-  125, 108, 98, 128, 90, 72, 99, 105, 93, 129,
-  96, 83, 102, 96, 93, 93, 106, 132, 113, 110,
-  107, 87, 104, 96, 104, 115, 83, 131, 137, 99,
-  151, 128, 82, 96, 138, 123, 89, 110, 85, 122,
-  97, 155, 119, 132, 106, 117, 138, 92, 118, 81,
-  123, 104, 74, 93, 33, 103, 148, 105, 98, 96,
-  115, 69, 92, 100, 83, 135, 118, 87, 108, 100,
-  111, 126, 86, 145, 80, 183, 110, 134, 109, 108,
-  90, 73, 86, 133, 121, 93, 71, 97, 90, 90,
-  114, 106, 94, 84, 110, 128, 108, 111, 87, 99,
-  98, 88, 128, 87, 81, 121, 84, 103, 103, 91,
-  124, 61, 108, 129, 96, 140, 95, 98, 108, 111,
-  102, 82, 120, 99, 109, 106, 116, 77, 139, 114,
-  166, 126, 140, 105, 109, 176, 82, 111, 113, 108,
-  75, 98, 90, 117, 109, 134, 118, 103, 102, 168,
-  110, 78, 69, 104, 84, 122, 117, 84, 156, 61,
-  115, 85, 122, 169, 110, 120, 79, 188, 126, 77,
-  140, 162, 145, 91, 116, 171, 125, 105, 58, 111,
-  91, 119, 96, 100, 143, 109, 77, 124, 106, 129,
-  89, 104, 109, 101, 127, 136, 87, 62, 92, 121,
-  81, 81, 137, 81, 95, 83, 105, 81, 100, 132,
-  126, 122, 86, 75, 79, 97, 111, 123, 92, 120,
-  152, 67, 81, 114, 78, 88, 112, 142, 83, 76,
-  70, 90, 74, 84, 86, 83, 104, 110, 113, 85,
-  95, 116, 114, 135, 38, 66, 34, 91, 126, 85,
-  115, 86, 121, 52, 88, 111, 66, 110, 116, 115,
-  73, 84, 84, 89, 96, 84, 62, 156, 93, 103,
-  91, 118, 74, 89, 86, 101, 97, 73, 84, 100,
-  99, 58, 112, 113, 72, 74, 89, 106, 92, 82,
-  71, 87, 58, 87, 105, 150, 86, 114, 69, 107,
-  94, 81, 119, 69, 78, 70, 92, 131, 57, 86,
-  112, 98, 89, 71, 123, 104, 127, 98, 84, 70,
-  110, 88, 113, 106, 126, 66, 69, 123, 86, 111,
-  121, 90, 67, 91, 61, 105, 113, 115, 94, 95,
-  105, 121, 107, 81, 58, 93, 69, 91, 64, 106,
-  95, 82, 94, 105, 111, 137, 85, 103, 90, 159,
-  75, 75, 111, 119, 107, 77, 91, 126, 94, 85,
-  50, 96, 71, 90, 60, 65, 98, 81, 37, 125,
-  57, 103, 81, 69, 113, 106, 129, 107, 84, 57,
-  91, 154, 86, 118, 85, 69, 84, 89, 140, 86,
-  80, 130, 94, 92, 87, 65, 57, 73, 111, 100,
-  60, 82,
-};
-
-
-extern "C" JNIEXPORT void JNICALL
-Java_android_renderscript_cts_BNNMTest_getData(JNIEnv * env,
-                                                                      jclass,
-                                                                      jbyteArray a,
-                                                                      jbyteArray b,
-                                                                      jbyteArray c
-                                                                      )
-{
-    jbyte * a_byte = (jbyte *) env->GetPrimitiveArrayCritical(a, 0);
-    jbyte * b_byte = (jbyte *) env->GetPrimitiveArrayCritical(b, 0);
-    jbyte * c_byte = (jbyte *) env->GetPrimitiveArrayCritical(c, 0);
-
-    memcpy(a_byte, a_data, a_count);
-    memcpy(b_byte, b_data, b_count);
-    memcpy(c_byte, expected_c_data, c_count);
-
-
-    env->ReleasePrimitiveArrayCritical(c, c_byte, 0);
-    env->ReleasePrimitiveArrayCritical(b, b_byte, 0);
-    env->ReleasePrimitiveArrayCritical(a, a_byte, 0);
-}
diff --git a/tests/tests/renderscript/libcoremathtestcpp/Android.mk b/tests/tests/renderscript/libcoremathtestcpp/Android.mk
index 3b693e0..c62f20e 100644
--- a/tests/tests/renderscript/libcoremathtestcpp/Android.mk
+++ b/tests/tests/renderscript/libcoremathtestcpp/Android.mk
@@ -24,10 +24,13 @@
 
 LOCAL_CFLAGS := -std=c++11
 
+LOCAL_SDK_VERSION := 21
+LOCAL_NDK_STL_VARIANT := stlport_static
+
 LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
 LOCAL_C_INCLUDES += frameworks/rs/cpp
 LOCAL_C_INCLUDES += frameworks/rs
 
-LOCAL_SHARED_LIBRARIES := libdl liblog libRScpp
-LOCAL_STATIC_LIBRARIES := libcutils
+LOCAL_LDFLAGS := -llog -ldl
+LOCAL_STATIC_LIBRARIES := libRScpp_static libcutils
 include $(BUILD_SHARED_LIBRARY)
diff --git a/tests/tests/renderscript/res/drawable-nodpi/expected_output.png b/tests/tests/renderscript/res/drawable-nodpi/expected_output.png
new file mode 100644
index 0000000..77c907e
--- /dev/null
+++ b/tests/tests/renderscript/res/drawable-nodpi/expected_output.png
Binary files differ
diff --git a/tests/tests/renderscript/res/drawable-nodpi/test_depthmap.png b/tests/tests/renderscript/res/drawable-nodpi/test_depthmap.png
new file mode 100644
index 0000000..d5e8c25
--- /dev/null
+++ b/tests/tests/renderscript/res/drawable-nodpi/test_depthmap.png
Binary files differ
diff --git a/tests/tests/renderscript/res/drawable-nodpi/test_image.png b/tests/tests/renderscript/res/drawable-nodpi/test_image.png
new file mode 100644
index 0000000..0107b38
--- /dev/null
+++ b/tests/tests/renderscript/res/drawable-nodpi/test_image.png
Binary files differ
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/AllocationByteBufferTest.java b/tests/tests/renderscript/src/android/renderscript/cts/AllocationByteBufferTest.java
new file mode 100644
index 0000000..760a8ed
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/AllocationByteBufferTest.java
@@ -0,0 +1,205 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.renderscript.cts;
+
+import java.nio.ByteBuffer;
+import java.util.Random;
+
+import android.renderscript.Allocation;
+import android.renderscript.AllocationAdapter;
+import android.renderscript.Element;
+import android.renderscript.Element.DataType;
+import android.renderscript.RSIllegalArgumentException;
+import android.renderscript.Type;
+
+import android.util.Log;
+
+public class AllocationByteBufferTest extends RSBaseCompute {
+
+    protected int MAX_DIM = 128;
+    protected int RAND_SEED = 2016;
+
+    Allocation createTypedAllocation(DataType dt, int size, int dimX, int dimY) {
+        Element e = getElement(mRS, dt, size);
+        Type t;
+        if (dimY <= 1) {
+            t = Type.createX(mRS, e, dimX);
+        } else {
+            t = Type.createXY(mRS, e, dimX, dimY);
+        }
+
+        return Allocation.createTyped(mRS, t);
+    }
+
+    void testByteBufferHelper(DataType dt, int byteSize, int dimX, int dimY) {
+        Random r = new Random(RAND_SEED);
+
+        for (int size = 1; size <= 4; size++) {
+            int vecWidth = (size == 3) ? 4 : size;
+            byte[] data = new byte[dimX * dimY * vecWidth * byteSize];
+            RSUtils.genRandomBytes(RAND_SEED, data, true, 8);
+
+            Allocation alloc = createTypedAllocation(dt, size, dimX, dimY);
+            alloc.copyFromUnchecked(data);
+
+            ByteBuffer bb = alloc.getByteBuffer();
+            int stride = (int)alloc.getStride();
+            for (int i=0; i < 10; i++) {
+                int posX = r.nextInt(dimX);
+                int posY = r.nextInt(dimY);
+                byte byteInData = data[(posY * dimX + posX) * vecWidth * byteSize];
+                byte byteInBuffer = bb.get(posY * stride + posX * vecWidth * byteSize);
+                assertEquals(byteInData, byteInBuffer);
+            }
+        }
+    }
+
+    void testByteBufferHelper1D(DataType dt, int byteSize) {
+        Random r = new Random(RAND_SEED);
+        int dimX = r.nextInt(MAX_DIM) + 1;
+        testByteBufferHelper(dt, byteSize, dimX, 1);
+    }
+
+    void testByteBufferHelper2D(DataType dt, int byteSize) {
+        Random r = new Random(RAND_SEED);
+        int dimX = r.nextInt(MAX_DIM) + 1;
+        int dimY = r.nextInt(MAX_DIM) + 2; //Make sure dimY is larger than 1;
+        testByteBufferHelper(dt, byteSize, dimX, dimY);
+    }
+
+    public void test1DWrite() {
+        Random r = new Random(RAND_SEED);
+        int vecWidth = 4;
+        int dimX = r.nextInt(MAX_DIM) + 1;
+
+        Type t = Type.createX(mRS, Element.U8_4(mRS), dimX);
+        Allocation alloc = Allocation.createTyped(mRS, t);
+        ByteBuffer bb = alloc.getByteBuffer();
+
+        byte[] dataIn = new byte[dimX * vecWidth];
+        byte[] dataOut = new byte[dimX * vecWidth];
+        RSUtils.genRandomBytes(RAND_SEED, dataIn, true, 8);
+        bb.put(dataIn);
+        alloc.copyTo(dataOut);
+        for (int i = 0; i < dimX * vecWidth; i++) {
+            assertEquals(dataIn[i], dataOut[i]);
+        }
+    }
+
+    public void test2DWrite() {
+        Random r = new Random(RAND_SEED);
+        int vecWidth = 4;
+        int dimX = r.nextInt(MAX_DIM) + 1;
+        int dimY = r.nextInt(MAX_DIM) + 2; //Make sure dimY is larger than 1;
+
+        Type t = Type.createXY(mRS, Element.U8_4(mRS), dimX, dimY);
+        Allocation alloc = Allocation.createTyped(mRS, t);
+        ByteBuffer bb = alloc.getByteBuffer();
+
+        int stride = (int)alloc.getStride();
+        byte[] dataIn = new byte[stride * dimY];
+        byte[] dataOut = new byte[dimX * dimY * vecWidth];
+        RSUtils.genRandomBytes(RAND_SEED, dataIn, true, 8);
+        bb.put(dataIn);
+        alloc.copyTo(dataOut);
+        for (int i = 0; i < dimX*vecWidth; i++) {
+            for (int j = 0; j < dimY; j++) {
+                assertEquals(dataIn[j*stride + i], dataOut[j*dimX*vecWidth + i]);
+            }
+        }
+    }
+
+    public void testByteBufferU8_1D() {
+        testByteBufferHelper1D(DataType.UNSIGNED_8, 1);
+    }
+
+    public void testByteBufferU8_2D() {
+        testByteBufferHelper2D(DataType.UNSIGNED_8, 1);
+    }
+
+    public void testByteBufferU16_1D() {
+        testByteBufferHelper1D(DataType.UNSIGNED_16, 2);
+    }
+
+    public void testByteBufferU16_2D() {
+        testByteBufferHelper2D(DataType.UNSIGNED_16, 2);
+    }
+
+    public void testByteBufferU32_1D() {
+        testByteBufferHelper1D(DataType.UNSIGNED_32, 4);
+    }
+
+    public void testByteBufferU32_2D() {
+        testByteBufferHelper2D(DataType.UNSIGNED_32, 4);
+    }
+
+    public void testByteBufferU64_1D() {
+        testByteBufferHelper1D(DataType.UNSIGNED_64, 8);
+    }
+
+    public void testByteBufferU64_2D() {
+        testByteBufferHelper2D(DataType.UNSIGNED_64, 8);
+    }
+
+    public void testByteBufferS8_1D() {
+        testByteBufferHelper1D(DataType.SIGNED_8, 1);
+    }
+
+    public void testByteBufferS8_2D() {
+        testByteBufferHelper2D(DataType.SIGNED_8, 1);
+    }
+
+    public void testByteBufferS16_1D() {
+        testByteBufferHelper1D(DataType.SIGNED_16, 2);
+    }
+
+    public void testByteBufferS16_2D() {
+        testByteBufferHelper2D(DataType.SIGNED_16, 2);
+    }
+
+    public void testByteBufferS32_1D() {
+        testByteBufferHelper1D(DataType.SIGNED_32, 4);
+    }
+
+    public void testByteBufferS32_2D() {
+        testByteBufferHelper2D(DataType.SIGNED_32, 4);
+    }
+
+    public void testByteBufferS64_1D() {
+        testByteBufferHelper1D(DataType.SIGNED_64, 8);
+    }
+
+    public void testByteBufferS64_2D() {
+        testByteBufferHelper2D(DataType.UNSIGNED_64, 8);
+    }
+
+    public void testByteBufferF32_1D() {
+        testByteBufferHelper1D(DataType.FLOAT_32, 4);
+    }
+
+    public void testByteBufferF32_2D() {
+        testByteBufferHelper2D(DataType.FLOAT_32, 4);
+    }
+
+    public void testByteBufferF64_1D() {
+        testByteBufferHelper1D(DataType.FLOAT_64, 8);
+    }
+
+    public void testByteBufferF64_2D() {
+        testByteBufferHelper2D(DataType.FLOAT_64, 8);
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/AllocationCopyPaddedTest.java b/tests/tests/renderscript/src/android/renderscript/cts/AllocationCopyPaddedTest.java
index c74dbc0..bb10716 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/AllocationCopyPaddedTest.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/AllocationCopyPaddedTest.java
@@ -45,7 +45,7 @@
                 break;
             }
         }
-        assertTrue("test_AllocationCopyTo_1D_Padded_Byte Failed, output array does not match input",
+        assertTrue("test_AllocationPadded_Byte3_1D Failed, output array does not match input",
                    result);
     }
 
@@ -54,7 +54,7 @@
         int width = random.nextInt(128);
         int height = random.nextInt(128);
         int arr_len = width * height * 3;
-        
+
         byte[] inArray = new byte[arr_len];
         byte[] outArray = new byte[arr_len];
         random.nextBytes(inArray);
@@ -73,7 +73,7 @@
                 break;
             }
         }
-        assertTrue("test_2D_AllocationCopyTo_Padded_Byte Failed, output array does not match input",
+        assertTrue("test_AllocationPadded_Byte3_2D Failed, output array does not match input",
                    result);
     }
 
@@ -102,11 +102,11 @@
                 break;
             }
         }
-        assertTrue("test_AllocationCopyTo_3D_Padded_Byte Failed, output array does not match input",
+        assertTrue("test_AllocationPadded_Byte3_3D Failed, output array does not match input",
                    result);
     }
 
-    public void test_AllocationPadded_Short3_1D() {
+    void test_AllocationPadded_Short3_1D_Helper(Element element) {
         Random random = new Random(0x172d8ab9);
         int width = random.nextInt(512);
         int arr_len = width * 3;
@@ -118,7 +118,7 @@
             inArray[i] = (short)random.nextInt();
         }
 
-        Type.Builder typeBuilder = new Type.Builder(mRS, Element.I16_3(mRS));
+        Type.Builder typeBuilder = new Type.Builder(mRS, element);
         typeBuilder.setX(width);
         Allocation alloc = Allocation.createTyped(mRS, typeBuilder.create());
         alloc.setAutoPadding(true);
@@ -132,16 +132,21 @@
                 break;
             }
         }
-        assertTrue("test_AllocationCopyTo_1D_Padded_Short Failed, output array does not match input",
+        assertTrue("test_AllocationPadded_Short3_1D_Helper Failed, output array does not match input",
                    result);
     }
 
-    public void test_AllocationPadded_Short3_2D() {
+    public void test_AllocationPadded_Short3_1D() {
+        test_AllocationPadded_Short3_1D_Helper(Element.I16_3(mRS));
+        test_AllocationPadded_Short3_1D_Helper(Element.F16_3(mRS));
+    }
+
+    void test_AllocationPadded_Short3_2D_Helper(Element element) {
         Random random = new Random(0x172d8ab9);
         int width = random.nextInt(128);
         int height = random.nextInt(128);
         int arr_len = width * height * 3;
-        
+
         short[] inArray = new short[arr_len];
         short[] outArray = new short[arr_len];
 
@@ -149,7 +154,7 @@
             inArray[i] = (short)random.nextInt();
         }
 
-        Type.Builder typeBuilder = new Type.Builder(mRS, Element.I16_3(mRS));
+        Type.Builder typeBuilder = new Type.Builder(mRS, element);
         typeBuilder.setX(width).setY(height);
         Allocation alloc = Allocation.createTyped(mRS, typeBuilder.create());
         alloc.setAutoPadding(true);
@@ -163,11 +168,16 @@
                 break;
             }
         }
-        assertTrue("test_AllocationCopyTo_2D_Padded_Short Failed, output array does not match input",
+        assertTrue("test_AllocationPadded_Short3_2D_Helper Failed, output array does not match input",
                    result);
     }
 
-    public void test_AllocationPadded_Short3_3D() {
+    public void test_AllocationPadded_Short3_2D() {
+        test_AllocationPadded_Short3_2D_Helper(Element.I16_3(mRS));
+        test_AllocationPadded_Short3_2D_Helper(Element.F16_3(mRS));
+    }
+
+    void test_AllocationPadded_Short3_3D_Helper(Element element) {
         Random random = new Random(0x172d8ab9);
         int w = random.nextInt(32);
         int h = random.nextInt(32);
@@ -181,7 +191,7 @@
             inArray[i] = (short)random.nextInt();
         }
 
-        Type.Builder typeBuilder = new Type.Builder(mRS, Element.I16_3(mRS));
+        Type.Builder typeBuilder = new Type.Builder(mRS, element);
         typeBuilder.setX(w).setY(h).setZ(d);
         Allocation alloc = Allocation.createTyped(mRS, typeBuilder.create());
         alloc.setAutoPadding(true);
@@ -195,10 +205,15 @@
                 break;
             }
         }
-        assertTrue("test_AllocationCopyTo_3D_Padded_Short Failed, output array does not match input",
+        assertTrue("test_AllocationPadded_Short3_3D_Helper Failed, output array does not match input",
                    result);
     }
 
+    public void test_AllocationPadded_Short3_3D() {
+        test_AllocationPadded_Short3_3D_Helper(Element.I16_3(mRS));
+        test_AllocationPadded_Short3_3D_Helper(Element.F16_3(mRS));
+    }
+
     public void test_AllocationPadded_Int3_1D() {
         Random random = new Random(0x172d8ab9);
         int width = random.nextInt(512);
@@ -225,7 +240,7 @@
                 break;
             }
         }
-        assertTrue("test_AllocationCopyTo_1D_Padded_Int Failed, output array does not match input",
+        assertTrue("test_AllocationPadded_Int3_1D Failed, output array does not match input",
                    result);
     }
 
@@ -234,7 +249,7 @@
         int width = random.nextInt(128);
         int height = random.nextInt(128);
         int arr_len = width * height * 3;
-        
+
         int[] inArray = new int[arr_len];
         int[] outArray = new int[arr_len];
 
@@ -256,7 +271,7 @@
                 break;
             }
         }
-        assertTrue("test_AllocationCopyTo_2D_Padded_Int Failed, output array does not match input",
+        assertTrue("test_AllocationPadded_Int3_2D Failed, output array does not match input",
                    result);
     }
 
@@ -288,7 +303,7 @@
                 break;
             }
         }
-        assertTrue("test_AllocationCopyTo_3D_Padded_Int Failed, output array does not match input",
+        assertTrue("test_AllocationPadded_Int3_3D Failed, output array does not match input",
                    result);
     }
 
@@ -318,7 +333,7 @@
                 break;
             }
         }
-        assertTrue("test_AllocationCopyTo_1D_Padded_Float Failed, output array does not match input",
+        assertTrue("test_AllocationPadded_Float3_1D Failed, output array does not match input",
                    result);
     }
     public void test_AllocationPadded_Float3_2D() {
@@ -348,7 +363,7 @@
                 break;
             }
         }
-        assertTrue("test_AllocationCopyTo_2D_Padded_Float Failed, output array does not match input",
+        assertTrue("test_AllocationPadded_Float3_2D Failed, output array does not match input",
                    result);
     }
     public void test_AllocationPadded_Float3_3D() {
@@ -379,7 +394,7 @@
                 break;
             }
         }
-        assertTrue("test_AllocationCopyTo_3D_Padded_Float Failed, output array does not match input",
+        assertTrue("test_AllocationPadded_Float3_3D Failed, output array does not match input",
                    result);
     }
 
@@ -409,7 +424,7 @@
                 break;
             }
         }
-        assertTrue("test_AllocationCopyTo_1D_Padded_Double Failed, output array does not match input",
+        assertTrue("test_AllocationPadded_Double3_1D Failed, output array does not match input",
                    result);
     }
     public void test_AllocationPadded_Double3_2D() {
@@ -439,7 +454,7 @@
                 break;
             }
         }
-        assertTrue("test_AllocationCopyTo_2D_Padded_Double Failed, output array does not match input",
+        assertTrue("test_AllocationPadded_Double3_2D Failed, output array does not match input",
                    result);
     }
     public void test_AllocationPadded_Double3_3D() {
@@ -470,7 +485,7 @@
                 break;
             }
         }
-        assertTrue("test_AllocationCopyTo_3D_Padded_Double Failed, output array does not match input",
+        assertTrue("test_AllocationPadded_Double3_3D Failed, output array does not match input",
                    result);
     }
 
@@ -500,7 +515,7 @@
                 break;
             }
         }
-        assertTrue("test_AllocationCopyTo_1D_Padded_Long Failed, output array does not match input",
+        assertTrue("test_AllocationPadded_Long3_1D Failed, output array does not match input",
                    result);
     }
 
@@ -509,7 +524,7 @@
         int width = random.nextInt(128);
         int height = random.nextInt(128);
         int arr_len = width * height * 3;
-        
+
         long[] inArray = new long[arr_len];
         long[] outArray = new long[arr_len];
 
@@ -531,7 +546,7 @@
                 break;
             }
         }
-        assertTrue("test_AllocationCopyTo_2D_Padded_Long Failed, output array does not match input",
+        assertTrue("test_AllocationPadded_Long3_2D Failed, output array does not match input",
                    result);
     }
 
@@ -563,7 +578,7 @@
                 break;
             }
         }
-        assertTrue("test_AllocationCopyTo_3D_Padded_Long Failed, output array does not match input",
+        assertTrue("test_AllocationPadded_Long3_3D Failed, output array does not match input",
                    result);
     }
 
@@ -599,23 +614,23 @@
                 break;
             }
         }
-        assertTrue("test_copy1DRangeTo_Padded_Byte Failed, output array does not match input",
+        assertTrue("test_AllocationPadded_copy1DRangeTo_Byte3, output array does not match input",
                    result);
     }
 
-    public void test_AllocationPadded_copy1DRangeTo_Short3() {
+    void test_AllocationPadded_copy1DRangeTo_Short3_Helper(Element element) {
         Random random = new Random(0x172d8ab9);
         int width = random.nextInt(512);
         int arr_len = width * 3;
 
         short[] inArray = new short[arr_len];
         short[] outArray = new short[arr_len];
-        
+
         for (int i = 0; i < arr_len; i++) {
             inArray[i] = (short)random.nextInt();
         }
 
-        Type.Builder typeBuilder = new Type.Builder(mRS, Element.I16_3(mRS));
+        Type.Builder typeBuilder = new Type.Builder(mRS, element);
         typeBuilder.setX(width);
         Allocation alloc = Allocation.createTyped(mRS, typeBuilder.create());
         alloc.setAutoPadding(true);
@@ -637,10 +652,15 @@
                 break;
             }
         }
-        assertTrue("test_copy1DRangeTo_Padded_Short Failed, output array does not match input",
+        assertTrue("test_AllocationPadded_copy1DRangeTo_Short3_Helper Failed, output array does not match input",
                    result);
     }
 
+    public void test_AllocationPadded_copy1DRangeTo_Short3() {
+        test_AllocationPadded_copy1DRangeTo_Short3_Helper(Element.I16_3(mRS));
+        test_AllocationPadded_copy1DRangeTo_Short3_Helper(Element.F16_3(mRS));
+    }
+
     public void test_AllocationPadded_copy1DRangeTo_Int3() {
         Random random = new Random(0x172d8ab9);
         int width = random.nextInt(512);
@@ -675,7 +695,7 @@
                 break;
             }
         }
-        assertTrue("test_copy1DRangeTo_Padded_Int Failed, output array does not match input",
+        assertTrue("test_AllocationPadded_copy1DRangeTo_Int3 Failed, output array does not match input",
                    result);
     }
 
@@ -713,7 +733,7 @@
                 break;
             }
         }
-        assertTrue("test_copy1DRangeTo_Padded_Float Failed, output array does not match input",
+        assertTrue("test_AllocationPadded_copy1DRangeTo_Float3 Failed, output array does not match input",
                    result);
     }
 
@@ -751,7 +771,7 @@
                 break;
             }
         }
-        assertTrue("test_copy1DRangeTo_Padded_Long Failed, output array does not match input",
+        assertTrue("test_AllocationPadded_copy1DRangeTo_Long3 Failed, output array does not match input",
                    result);
     }
 
@@ -783,11 +803,11 @@
                 break;
             }
         }
-        assertTrue("test_copy2DRangeTo_Padded_Byte Failed, output array does not match input",
+        assertTrue("test_AllocationPadded_copy2DRangeTo_Byte3 Failed, output array does not match input",
                    result);
     }
 
-    public void test_AllocationPadded_copy2DRangeTo_Short3() {
+    void test_AllocationPadded_copy2DRangeTo_Short3_Helper(Element element) {
         Random random = new Random(0x172d8ab9);
         int width = random.nextInt(128);
         int height = random.nextInt(128);
@@ -799,12 +819,12 @@
 
         short[] inArray = new short[arr_len];
         short[] outArray = new short[arr_len];
-        
+
         for (int i = 0; i < arr_len; i++) {
             inArray[i] = (short)random.nextInt();
         }
 
-        Type.Builder typeBuilder = new Type.Builder(mRS, Element.I16_3(mRS));
+        Type.Builder typeBuilder = new Type.Builder(mRS, element);
         typeBuilder.setX(width).setY(height);
         Allocation alloc = Allocation.createTyped(mRS, typeBuilder.create());
         alloc.setAutoPadding(true);
@@ -818,10 +838,15 @@
                 break;
             }
         }
-        assertTrue("test_copy2DRangeTo_Padded_Short Failed, output array does not match input",
+        assertTrue("test_AllocationPadded_copy2DRangeTo_Short3_Helper Failed, output array does not match input",
                    result);
     }
 
+    public void test_AllocationPadded_copy2DRangeTo_Short3() {
+        test_AllocationPadded_copy2DRangeTo_Short3_Helper(Element.I16_3(mRS));
+        test_AllocationPadded_copy2DRangeTo_Short3_Helper(Element.F16_3(mRS));
+    }
+
     public void test_AllocationPadded_copy2DRangeTo_Int3() {
         Random random = new Random(0x172d8ab9);
         int width = random.nextInt(128);
@@ -853,7 +878,7 @@
                 break;
             }
         }
-        assertTrue("test_copy2DRangeTo_Padded_Int Failed, output array does not match input",
+        assertTrue("test_AllocationPadded_copy2DRangeTo_Int3 Failed, output array does not match input",
                    result);
     }
 
@@ -888,7 +913,7 @@
                 break;
             }
         }
-        assertTrue("test_copy2DRangeTo_Padded_Float Failed, output array does not match input",
+        assertTrue("test_AllocationPadded_copy2DRangeTo_Float3 Failed, output array does not match input",
                    result);
     }
 
@@ -923,7 +948,7 @@
                 break;
             }
         }
-        assertTrue("test_copy2DRangeTo_Padded_Long Failed, output array does not match input",
+        assertTrue("test_AllocationPadded_copy2DRangeTo_Long3 Failed, output array does not match input",
                    result);
     }
 
@@ -959,23 +984,23 @@
                 break;
             }
         }
-        assertTrue("test_copy1DRangeToUnchecked_Padded_Byte Failed, output array does not match input",
+        assertTrue("test_AllocationPadded_copy1DRangeToUnchecked_Byte3 Failed, output array does not match input",
                    result);
     }
 
-    public void test_AllocationPadded_copy1DRangeToUnchecked_Short3() {
+    void test_AllocationPadded_copy1DRangeToUnchecked_Short3_Helper(Element element) {
         Random random = new Random(0x172d8ab9);
         int width = random.nextInt(512);
         int arr_len = width * 3;
 
         short[] inArray = new short[arr_len];
         short[] outArray = new short[arr_len];
-        
+
         for (int i = 0; i < arr_len; i++) {
             inArray[i] = (short)random.nextInt();
         }
 
-        Type.Builder typeBuilder = new Type.Builder(mRS, Element.I16_3(mRS));
+        Type.Builder typeBuilder = new Type.Builder(mRS, element);
         typeBuilder.setX(width);
         Allocation alloc = Allocation.createTyped(mRS, typeBuilder.create());
         alloc.setAutoPadding(true);
@@ -997,10 +1022,15 @@
                 break;
             }
         }
-        assertTrue("test_copy1DRangeToUnchecked_Padded_Short Failed, output array does not match input",
+        assertTrue("test_AllocationPadded_copy1DRangeToUnchecked_Short3_Helper Failed, output array does not match input",
                    result);
     }
 
+    public void test_AllocationPadded_copy1DRangeToUnchecked_Short3() {
+        test_AllocationPadded_copy1DRangeToUnchecked_Short3_Helper(Element.I16_3(mRS));
+        test_AllocationPadded_copy1DRangeToUnchecked_Short3_Helper(Element.F16_3(mRS));
+    }
+
     public void test_AllocationPadded_copy1DRangeToUnchecked_Int3() {
         Random random = new Random(0x172d8ab9);
         int width = random.nextInt(512);
@@ -1035,7 +1065,7 @@
                 break;
             }
         }
-        assertTrue("test_copy1DRangeToUnchecked_1D_Padded_Int Failed, output array does not match input",
+        assertTrue("test_AllocationPadded_copy1DRangeToUnchecked_Int3 Failed, output array does not match input",
                    result);
     }
 
@@ -1073,7 +1103,7 @@
                 break;
             }
         }
-        assertTrue("test_copy1DRangeToUnchecked_Padded_Float Failed, output array does not match input",
+        assertTrue("test_AllocationPadded_copy1DRangeToUnchecked_Float3 Failed, output array does not match input",
                    result);
     }
 
@@ -1111,7 +1141,7 @@
                 break;
             }
         }
-        assertTrue("test_copy1DRangeToUnchecked_Padded_Long Failed, output array does not match input",
+        assertTrue("test_AllocationPadded_copy1DRangeToUnchecked_Long3 Failed, output array does not match input",
                    result);
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/AllocationCopyToTest.java b/tests/tests/renderscript/src/android/renderscript/cts/AllocationCopyToTest.java
index f6bef0a..0c1f773 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/AllocationCopyToTest.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/AllocationCopyToTest.java
@@ -58,7 +58,7 @@
                    result);
     }
 
-    public void test_Allocationcopy1DRangeTo_Short() {
+    void test_Allocationcopy1DRangeTo_Short_Helper(Element element, boolean testTyped) {
         Random random = new Random(0x172d8ab9);
         int width = random.nextInt(512);
         int arr_len = width;
@@ -70,13 +70,18 @@
             inArray[i] = (short)random.nextInt();
         }
 
-        Type.Builder typeBuilder = new Type.Builder(mRS, Element.I16(mRS));
+        Type.Builder typeBuilder = new Type.Builder(mRS, element);
         typeBuilder.setX(width);
         alloc = Allocation.createTyped(mRS, typeBuilder.create());
         int offset = random.nextInt(arr_len);
         int count = arr_len - offset;
-        alloc.copy1DRangeFrom(offset, count, inArray);
-        alloc.copy1DRangeTo(offset, count, outArray);
+        if (testTyped) {
+            alloc.copy1DRangeFrom(offset, count, inArray);
+            alloc.copy1DRangeTo(offset, count, outArray);
+        } else {
+            alloc.copy1DRangeFrom(offset, count, (Object) inArray);
+            alloc.copy1DRangeTo(offset, count, (Object) outArray);
+        }
 
         boolean result = true;
         for (int i = 0; i < count; i++) {
@@ -91,10 +96,16 @@
                 break;
             }
         }
-        assertTrue("test_Allocationcopy1DRangeTo_Short failed, output array does not match input",
+        assertTrue("test_Allocationcopy1DRangeTo_Short_Helper failed, output array does not match input",
                    result);
     }
 
+    public void test_Allocationcopy1DRangeTo_Short() {
+        test_Allocationcopy1DRangeTo_Short_Helper(Element.I16(mRS), true);
+        test_Allocationcopy1DRangeTo_Short_Helper(Element.F16(mRS), true);
+        test_Allocationcopy1DRangeTo_Short_Helper(Element.F16(mRS), false);
+    }
+
     public void test_Allocationcopy1DRangeTo_Int() {
         Random random = new Random(0x172d8ab9);
         int width = random.nextInt(512);
@@ -237,7 +248,7 @@
                    result);
     }
 
-    public void test_Allocationcopy2DRangeTo_Short() {
+    void test_Allocationcopy2DRangeTo_Short_Helper(Element element, boolean testTyped) {
         Random random = new Random(0x172d8ab9);
         int width = random.nextInt(128);
         int height = random.nextInt(128);
@@ -257,8 +268,13 @@
         Type.Builder typeBuilder = new Type.Builder(mRS, Element.I16(mRS));
         typeBuilder.setX(width).setY(height);
         alloc = Allocation.createTyped(mRS, typeBuilder.create());
-        alloc.copy2DRangeFrom(xoff, yoff, xcount, ycount, inArray);
-        alloc.copy2DRangeTo(xoff, yoff, xcount, ycount, outArray);
+        if (testTyped) {
+            alloc.copy2DRangeFrom(xoff, yoff, xcount, ycount, inArray);
+            alloc.copy2DRangeTo(xoff, yoff, xcount, ycount, outArray);
+        } else {
+            alloc.copy2DRangeFrom(xoff, yoff, xcount, ycount, (Object) inArray);
+            alloc.copy2DRangeTo(xoff, yoff, xcount, ycount, (Object) outArray);
+        }
 
         boolean result = true;
         for (int i = 0; i < arr_len; i++) {
@@ -267,10 +283,16 @@
                 break;
             }
         }
-        assertTrue("test_Allocationcopy2DRangeTo_Short failed, output array does not match input",
+        assertTrue("test_Allocationcopy2DRangeTo_Short_Helper failed, output array does not match input",
                    result);
     }
 
+    public void test_Allocationcopy2DRangeTo_Short() {
+        test_Allocationcopy2DRangeTo_Short_Helper(Element.I16(mRS), true);
+        test_Allocationcopy2DRangeTo_Short_Helper(Element.F16(mRS), true);
+        test_Allocationcopy2DRangeTo_Short_Helper(Element.F16(mRS), false);
+    }
+
     public void test_Allocationcopy2DRangeTo_Int() {
         Random random = new Random(0x172d8ab9);
         int width = random.nextInt(128);
@@ -410,7 +432,7 @@
                    result);
     }
 
-    public void test_Allocationcopy3DRangeTo_Short() {
+    void test_Allocationcopy3DRangeTo_Short_Helper(Element element) {
         Random random = new Random(0x172d8ab9);
         int width = random.nextInt(64);
         int height = random.nextInt(64);
@@ -432,7 +454,7 @@
             inArray[i] = (short)random.nextInt();
         }
 
-        Type.Builder typeBuilder = new Type.Builder(mRS, Element.I16(mRS));
+        Type.Builder typeBuilder = new Type.Builder(mRS, element);
         typeBuilder.setX(width).setY(height).setZ(depth);
         alloc = Allocation.createTyped(mRS, typeBuilder.create());
         alloc.copy3DRangeFrom(xoff, yoff, zoff, xcount, ycount, zcount, (Object)inArray);
@@ -446,10 +468,15 @@
                 break;
             }
         }
-        assertTrue("test_Allocationcopy3DRangeTo_Short failed, output array does not match input",
+        assertTrue("test_Allocationcopy3DRangeTo_Short_Helper failed, output array does not match input",
                    result);
     }
 
+    public void test_Allocationcopy3DRangeTo_Short() {
+        test_Allocationcopy3DRangeTo_Short_Helper(Element.I16(mRS));
+        test_Allocationcopy3DRangeTo_Short_Helper(Element.F16(mRS));
+    }
+
     public void test_Allocationcopy3DRangeTo_Int() {
         Random random = new Random(0x172d8ab9);
         int width = random.nextInt(64);
@@ -647,7 +674,7 @@
                    result);
     }
 
-    public void test_Allocationcopy1DRangeToUnchecked_Short() {
+    void test_Allocationcopy1DRangeToUnchecked_Short_Helper(Element element) {
         Random random = new Random(0x172d8ab9);
         int width = random.nextInt(512);
         int arr_len = width;
@@ -659,7 +686,7 @@
             inArray[i] = (short)random.nextInt();
         }
 
-        Type.Builder typeBuilder = new Type.Builder(mRS, Element.I16(mRS));
+        Type.Builder typeBuilder = new Type.Builder(mRS, element);
         typeBuilder.setX(width);
         alloc = Allocation.createTyped(mRS, typeBuilder.create());
         int offset = random.nextInt(arr_len);
@@ -680,10 +707,15 @@
                 break;
             }
         }
-        assertTrue("test_Allocationcopy1DRangeToUnchecked_Short failed, output array does not match input",
+        assertTrue("test_Allocationcopy1DRangeToUnchecked_Short_Helper failed, output array does not match input",
                    result);
     }
 
+    public void test_Allocationcopy1DRangeToUnchecked_Short() {
+        test_Allocationcopy1DRangeToUnchecked_Short_Helper(Element.I16(mRS));
+        test_Allocationcopy1DRangeToUnchecked_Short_Helper(Element.F16(mRS));
+    }
+
     public void test_Allocationcopy1DRangeToUnchecked_Int() {
         Random random = new Random(0x172d8ab9);
         int width = random.nextInt(512);
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/AllocationCreateAllocationsTest.java b/tests/tests/renderscript/src/android/renderscript/cts/AllocationCreateAllocationsTest.java
new file mode 100644
index 0000000..986704e
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/AllocationCreateAllocationsTest.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.renderscript.cts;
+
+import java.nio.ByteBuffer;
+import java.util.Random;
+
+import android.renderscript.Allocation;
+import android.renderscript.Element;
+import android.renderscript.Element.DataType;
+import android.renderscript.RSIllegalArgumentException;
+import android.renderscript.Type;
+
+import android.util.Log;
+import android.view.Surface;
+
+public class AllocationCreateAllocationsTest extends RSBaseCompute {
+    private int dimX = 1920;
+    private int dimY = 1080;
+    private final int MAX_NUM_IO_ALLOC = 16;
+
+    Allocation[] createAllocationsHelper(int usage, int numAlloc) {
+      Element e = Element.U8_4(mRS);
+      Type t = Type.createXY(mRS, e, dimX, dimY);
+      return Allocation.createAllocations(mRS, t, usage, numAlloc);
+    }
+
+    public void testCreateAllocations() {
+        int usage = Allocation.USAGE_SCRIPT;
+
+        int numAlloc = MAX_NUM_IO_ALLOC + 1;
+        Allocation[] allocArray;
+        allocArray = createAllocationsHelper(usage, numAlloc);
+        assertTrue("failed to create AllocationQueue", allocArray != null);
+    }
+
+    public void testCreateAllocations_USAGE_IO_INPUT() {
+        int usage = Allocation.USAGE_IO_INPUT;
+
+        int numAlloc = MAX_NUM_IO_ALLOC + 1;
+        Allocation[] allocArray;
+        try {
+            allocArray = createAllocationsHelper(usage, MAX_NUM_IO_ALLOC + 1);
+            fail("should throw RSIllegalArgumentException");
+        } catch (RSIllegalArgumentException e) {
+        }
+        numAlloc = 10;
+        allocArray = createAllocationsHelper(usage, numAlloc);
+        assertTrue("failed to create AllocationQueue", allocArray != null);
+    }
+
+    public void testGetProperties() {
+        int numAlloc = 10;
+        int usage = Allocation.USAGE_SCRIPT | Allocation.USAGE_IO_INPUT;
+        Allocation[] allocArray = createAllocationsHelper(usage, numAlloc);
+
+        Element eRef = allocArray[0].getElement();
+        Type tRef = allocArray[0].getType();
+        int uRef = allocArray[0].getUsage();
+        Surface sRef = allocArray[0].getSurface();
+        for (int i=1; i<numAlloc; i++) {
+            Element e = allocArray[i].getElement();
+            assertTrue("Element mismatch between AllocationQueue and Allocation",
+                       e.equals(eRef));
+            Type t = allocArray[i].getType();
+            assertTrue("Type mismatch between AllocationQueue and Allocation",
+                       t.equals(tRef));
+            int u = allocArray[i].getUsage();
+            assertTrue("Usage mismatch between AllocationQueue and Allocation",
+                       u == uRef);
+            Surface s = allocArray[i].getSurface();
+            assertTrue("Surface mismatch between AllocationQueue and Allocation",
+                       s.equals(sRef));
+        }
+    }
+
+    public void testMultipleIoReceive_USAGE_IO_INPUT() {
+        int usage = Allocation.USAGE_SCRIPT | Allocation.USAGE_IO_INPUT;
+        int dX = 64, dY = 64, numAlloc = 5;
+        Type t = Type.createXY(mRS, Element.U8_4(mRS), dX, dY);
+
+        Allocation[] allocArray = Allocation.createAllocations(mRS, t, usage, numAlloc);
+        Allocation inputAlloc = Allocation.createTyped(mRS, t,
+                                    Allocation.USAGE_SCRIPT | Allocation.USAGE_IO_OUTPUT);
+        inputAlloc.setSurface(allocArray[0].getSurface());
+
+        for (int i=0; i<numAlloc; i++) {
+            Random r = new Random();
+            byte[] dataIn = new byte[dX * dY * 4];
+            byte[] dataOut = new byte[dX * dY * 4];
+
+            r.nextBytes(dataIn);
+            inputAlloc.copyFromUnchecked(dataIn);
+            inputAlloc.ioSend();
+            allocArray[i].ioReceive();
+            allocArray[i].copyTo(dataOut);
+            for (int j=0; j<dX*dY*4; j++) {
+                assertTrue("IoReceive Failed, Frame: " + i, dataIn[j] == dataOut[j]);
+            }
+        }
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/AllocationTest.java b/tests/tests/renderscript/src/android/renderscript/cts/AllocationTest.java
index 7e867f7..27315dd 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/AllocationTest.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/AllocationTest.java
@@ -115,6 +115,10 @@
          createTypedHelper(Element.RGB_565(mRS));
          createTypedHelper(Element.RGB_888(mRS));
          createTypedHelper(Element.RGBA_8888(mRS));
+         createTypedHelper(Element.F16(mRS));
+         createTypedHelper(Element.F16_2(mRS));
+         createTypedHelper(Element.F16_3(mRS));
+         createTypedHelper(Element.F16_4(mRS));
          createTypedHelper(Element.F32(mRS));
          createTypedHelper(Element.F32_2(mRS));
          createTypedHelper(Element.F32_3(mRS));
@@ -154,6 +158,10 @@
          createSizedHelper(Element.RGB_565(mRS));
          createSizedHelper(Element.RGB_888(mRS));
          createSizedHelper(Element.RGBA_8888(mRS));
+         createSizedHelper(Element.F16(mRS));
+         createSizedHelper(Element.F16_2(mRS));
+         createSizedHelper(Element.F16_3(mRS));
+         createSizedHelper(Element.F16_4(mRS));
          createSizedHelper(Element.F32(mRS));
          createSizedHelper(Element.F32_2(mRS));
          createSizedHelper(Element.F32_3(mRS));
@@ -333,8 +341,9 @@
         }
     }
 
-    void helperShortCopy(int nElems, int offset, int count, int copyMode) {
-        Allocation A = Allocation.createSized(mRS, Element.I16(mRS), nElems);
+    // Accept an Element parameter so this helper can test both I16 and F16 elements.
+    void helperShortCopy(Element element, int nElems, int offset, int count, int copyMode) {
+        Allocation A = Allocation.createSized(mRS, element, nElems);
 
         short src[], dst[];
         src = new short[nElems];
@@ -522,10 +531,11 @@
         }
     }
 
-    void helperShortCopy2D(int nElemsX, int nElemsY,
+    // Accept an Element parameter so this helper can test both I16 and F16 elements.
+    void helperShortCopy2D(Element element, int nElemsX, int nElemsY,
                            int xOffset, int yOffset,
                            int width, int height) {
-        Type.Builder b = new Type.Builder(mRS, Element.I16(mRS));
+        Type.Builder b = new Type.Builder(mRS, element);
         Allocation A = Allocation.createTyped(mRS, b.setX(nElemsX).setY(nElemsY).create());
 
         short src[], dst[];
@@ -635,7 +645,8 @@
             for (int mode = 0; mode <= 1; mode ++) {
                 helperFloatCopy(s, 0, s, mode);
                 helperByteCopy(s, 0, s, mode);
-                helperShortCopy(s, 0, s, mode);
+                helperShortCopy(Element.I16(mRS), s, 0, s, mode);
+                helperShortCopy(Element.F16(mRS), s, 0, s, mode);
                 helperIntCopy(s, 0, s, mode);
                 helperBaseObjCopy(s, 0, s, mode);
             }
@@ -646,7 +657,8 @@
                     for (int count = 1; count <= s - off; count ++) {
                         helperFloatCopy(s, off, count, mode);
                         helperByteCopy(s, off, count, mode);
-                        helperShortCopy(s, off, count, mode);
+                        helperShortCopy(Element.I16(mRS), s, off, count, mode);
+                        helperShortCopy(Element.F16(mRS), s, off, count, mode);
                         helperIntCopy(s, off, count, mode);
                         helperBaseObjCopy(s, off, count, mode);
                     }
@@ -673,7 +685,8 @@
                             for (int h = 1; h <= sY - offY; h += 3) {
                                 helperFloatCopy2D(sX, sY, offX, offY, w, h);
                                 helperByteCopy2D(sX, sY, offX, offY, w, h);
-                                helperShortCopy2D(sX, sY, offX, offY, w, h);
+                                helperShortCopy2D(Element.I16(mRS), sX, sY, offX, offY, w, h);
+                                helperShortCopy2D(Element.F16(mRS), sX, sY, offX, offY, w, h);
                                 helperIntCopy2D(sX, sY, offX, offY, w, h);
                                 helperFloatAllocationCopy2D(sX, sY, offX, offY, w, h);
                                 helperByteAllocationCopy2D(sX, sY, offX, offY, w, h);
@@ -779,6 +792,47 @@
         assertTrue(result[0] == 2);
     }
 
+  public void testDimReturnsZero() {
+    Allocation a;
+    a = Allocation.createSized(mRS, Element.F32(mRS), 100);
+    assertTrue(a.getType().getX() == 100);
+    assertTrue(a.getType().getY() == 0);
+    assertTrue(a.getType().getZ() == 0);
+    a.destroy();
+
+    Type.Builder b;
+    b = new Type.Builder(mRS, Element.F32(mRS));
+    a = Allocation.createTyped(mRS, b.create());
+
+    assertTrue(a.getType().getX() == 1);
+    assertTrue(a.getType().getY() == 0);
+    assertTrue(a.getType().getZ() == 0);
+
+    a.destroy();
+
+    b = new Type.Builder(mRS, Element.F32(mRS)).setX(102);
+    a = Allocation.createTyped(mRS, b.create());
+
+    assertTrue(a.getType().getX() == 102);
+    assertTrue(a.getType().getY() == 0);
+    assertTrue(a.getType().getZ() == 0);
+    a.destroy();
+    b = new Type.Builder(mRS, Element.F32(mRS)).setX(102).setY(123);
+    a = Allocation.createTyped(mRS, b.create());
+
+    assertTrue(a.getType().getX() == 102);
+    assertTrue(a.getType().getY() == 123);
+    assertTrue(a.getType().getZ() == 0);
+    a.destroy();
+    b = new Type.Builder(mRS, Element.F32(mRS)).setX(2).setY(33).setZ(23);
+    a = Allocation.createTyped(mRS, b.create());
+
+    assertTrue(a.getType().getX() == 2);
+    assertTrue(a.getType().getY() == 33);
+    assertTrue(a.getType().getZ() == 23);
+
+    a.destroy();
+   }
 }
 
 
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/BLASData.java b/tests/tests/renderscript/src/android/renderscript/cts/BLASData.java
deleted file mode 100644
index def0352..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/BLASData.java
+++ /dev/null
@@ -1,1382 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* Don't edit this file alone!
- * The array names need to match the data generated by blas_gen.py. */
-
-package android.renderscript.cts;
-
-import android.content.res.AssetManager;
-import android.content.Context;
-import java.io.InputStream;
-import java.io.BufferedReader;
-import java.io.InputStreamReader;
-import java.io.IOException;
-
-import android.test.AndroidTestCase;
-
-public class BLASData extends AndroidTestCase {
-    private BufferedReader mBufReader;
-
-    int dM;
-    int dN;
-    int dK;
-
-    int KL;
-    int KU;
-
-    float[] L2_sGEMV_A_mn;
-    float[] L2_sGEMV_x_n1;
-    float[] L2_sGEMV_x_n2;
-    float[] L2_sGEMV_y_m1;
-    float[] L2_sGEMV_y_m2;
-    float[] L2_sGEMV_o_N;
-    float[] L2_sGEMV_o_N2;
-    float[] L2_sGEMV_o_T;
-    float[] L2_sGEMV_o_H;
-
-    double[] L2_dGEMV_A_mn;
-    double[] L2_dGEMV_x_n1;
-    double[] L2_dGEMV_x_n2;
-    double[] L2_dGEMV_y_m1;
-    double[] L2_dGEMV_y_m2;
-    double[] L2_dGEMV_o_N;
-    double[] L2_dGEMV_o_N2;
-    double[] L2_dGEMV_o_T;
-    double[] L2_dGEMV_o_H;
-
-    float[] L2_cGEMV_A_mn;
-    float[] L2_cGEMV_x_n1;
-    float[] L2_cGEMV_x_n2;
-    float[] L2_cGEMV_y_m1;
-    float[] L2_cGEMV_y_m2;
-    float[] L2_cGEMV_o_N;
-    float[] L2_cGEMV_o_N2;
-    float[] L2_cGEMV_o_T;
-    float[] L2_cGEMV_o_H;
-
-    double[] L2_zGEMV_A_mn;
-    double[] L2_zGEMV_x_n1;
-    double[] L2_zGEMV_x_n2;
-    double[] L2_zGEMV_y_m1;
-    double[] L2_zGEMV_y_m2;
-    double[] L2_zGEMV_o_N;
-    double[] L2_zGEMV_o_N2;
-    double[] L2_zGEMV_o_T;
-    double[] L2_zGEMV_o_H;
-
-    float[] L2_sGBMV_A_mn;
-    float[] L2_sGBMV_x_n1;
-    float[] L2_sGBMV_x_n2;
-    float[] L2_sGBMV_y_m1;
-    float[] L2_sGBMV_y_m2;
-    float[] L2_sGBMV_o_N;
-    float[] L2_sGBMV_o_N2;
-    float[] L2_sGBMV_o_T;
-    float[] L2_sGBMV_o_H;
-
-    double[] L2_dGBMV_A_mn;
-    double[] L2_dGBMV_x_n1;
-    double[] L2_dGBMV_x_n2;
-    double[] L2_dGBMV_y_m1;
-    double[] L2_dGBMV_y_m2;
-    double[] L2_dGBMV_o_N;
-    double[] L2_dGBMV_o_N2;
-    double[] L2_dGBMV_o_T;
-    double[] L2_dGBMV_o_H;
-
-    float[] L2_cGBMV_A_mn;
-    float[] L2_cGBMV_x_n1;
-    float[] L2_cGBMV_x_n2;
-    float[] L2_cGBMV_y_m1;
-    float[] L2_cGBMV_y_m2;
-    float[] L2_cGBMV_o_N;
-    float[] L2_cGBMV_o_N2;
-    float[] L2_cGBMV_o_T;
-    float[] L2_cGBMV_o_H;
-
-    double[] L2_zGBMV_A_mn;
-    double[] L2_zGBMV_x_n1;
-    double[] L2_zGBMV_x_n2;
-    double[] L2_zGBMV_y_m1;
-    double[] L2_zGBMV_y_m2;
-    double[] L2_zGBMV_o_N;
-    double[] L2_zGBMV_o_N2;
-    double[] L2_zGBMV_o_T;
-    double[] L2_zGBMV_o_H;
-
-    float[] L2_cHEMV_A_nn;
-    float[] L2_cHEMV_A_nn_pu;
-    float[] L2_cHEMV_x_n1;
-    float[] L2_cHEMV_x_n2;
-    float[] L2_cHEMV_y_n1;
-    float[] L2_cHEMV_y_n2;
-    float[] L2_cHEMV_o_N;
-    float[] L2_cHEMV_o_N2;
-
-    double[] L2_zHEMV_A_nn;
-    double[] L2_zHEMV_A_nn_pu;
-    double[] L2_zHEMV_x_n1;
-    double[] L2_zHEMV_x_n2;
-    double[] L2_zHEMV_y_n1;
-    double[] L2_zHEMV_y_n2;
-    double[] L2_zHEMV_o_N;
-    double[] L2_zHEMV_o_N2;
-
-    float[] L2_cHBMV_A_nn;
-    float[] L2_cHBMV_x_n1;
-    float[] L2_cHBMV_x_n2;
-    float[] L2_cHBMV_y_n1;
-    float[] L2_cHBMV_y_n2;
-    float[] L2_cHBMV_o_N;
-    float[] L2_cHBMV_o_N2;
-
-    double[] L2_zHBMV_A_nn;
-    double[] L2_zHBMV_x_n1;
-    double[] L2_zHBMV_x_n2;
-    double[] L2_zHBMV_y_n1;
-    double[] L2_zHBMV_y_n2;
-    double[] L2_zHBMV_o_N;
-    double[] L2_zHBMV_o_N2;
-
-    float[] L2_sSYMV_A_nn;
-    float[] L2_sSYMV_A_nn_pu;
-    float[] L2_sSYMV_x_n1;
-    float[] L2_sSYMV_x_n2;
-    float[] L2_sSYMV_y_n1;
-    float[] L2_sSYMV_y_n2;
-    float[] L2_sSYMV_o_N;
-    float[] L2_sSYMV_o_N2;
-
-    double[] L2_dSYMV_A_nn;
-    double[] L2_dSYMV_A_nn_pu;
-    double[] L2_dSYMV_x_n1;
-    double[] L2_dSYMV_x_n2;
-    double[] L2_dSYMV_y_n1;
-    double[] L2_dSYMV_y_n2;
-    double[] L2_dSYMV_o_N;
-    double[] L2_dSYMV_o_N2;
-
-    float[] L2_sSBMV_A_nn;
-    float[] L2_sSBMV_x_n1;
-    float[] L2_sSBMV_x_n2;
-    float[] L2_sSBMV_y_n1;
-    float[] L2_sSBMV_y_n2;
-    float[] L2_sSBMV_o_N;
-    float[] L2_sSBMV_o_N2;
-
-    double[] L2_dSBMV_A_nn;
-    double[] L2_dSBMV_x_n1;
-    double[] L2_dSBMV_x_n2;
-    double[] L2_dSBMV_y_n1;
-    double[] L2_dSBMV_y_n2;
-    double[] L2_dSBMV_o_N;
-    double[] L2_dSBMV_o_N2;
-
-    float[] L2_sTRMV_A_nn;
-    float[] L2_sTRMV_A_nn_pu;
-    float[] L2_sTRMV_x_n1;
-    float[] L2_sTRMV_x_n2;
-    float[] L2_sTRMV_o_UN;
-    float[] L2_sTRMV_o_UN2;
-    float[] L2_sTRMV_o_UT;
-    float[] L2_sTRMV_o_UH;
-
-    double[] L2_dTRMV_A_nn;
-    double[] L2_dTRMV_A_nn_pu;
-    double[] L2_dTRMV_x_n1;
-    double[] L2_dTRMV_x_n2;
-    double[] L2_dTRMV_o_UN;
-    double[] L2_dTRMV_o_UN2;
-    double[] L2_dTRMV_o_UT;
-    double[] L2_dTRMV_o_UH;
-
-    float[] L2_cTRMV_A_nn;
-    float[] L2_cTRMV_A_nn_pu;
-    float[] L2_cTRMV_x_n1;
-    float[] L2_cTRMV_x_n2;
-    float[] L2_cTRMV_o_UN;
-    float[] L2_cTRMV_o_UN2;
-    float[] L2_cTRMV_o_UT;
-    float[] L2_cTRMV_o_UH;
-
-    double[] L2_zTRMV_A_nn;
-    double[] L2_zTRMV_A_nn_pu;
-    double[] L2_zTRMV_x_n1;
-    double[] L2_zTRMV_x_n2;
-    double[] L2_zTRMV_o_UN;
-    double[] L2_zTRMV_o_UN2;
-    double[] L2_zTRMV_o_UT;
-    double[] L2_zTRMV_o_UH;
-
-    float[] L2_sTBMV_A_nn;
-    float[] L2_sTBMV_x_n1;
-    float[] L2_sTBMV_x_n2;
-    float[] L2_sTBMV_o_UN;
-    float[] L2_sTBMV_o_UN2;
-    float[] L2_sTBMV_o_UT;
-    float[] L2_sTBMV_o_UH;
-
-    double[] L2_dTBMV_A_nn;
-    double[] L2_dTBMV_x_n1;
-    double[] L2_dTBMV_x_n2;
-    double[] L2_dTBMV_o_UN;
-    double[] L2_dTBMV_o_UN2;
-    double[] L2_dTBMV_o_UT;
-    double[] L2_dTBMV_o_UH;
-
-    float[] L2_cTBMV_A_nn;
-    float[] L2_cTBMV_x_n1;
-    float[] L2_cTBMV_x_n2;
-    float[] L2_cTBMV_o_UN;
-    float[] L2_cTBMV_o_UN2;
-    float[] L2_cTBMV_o_UT;
-    float[] L2_cTBMV_o_UH;
-
-    double[] L2_zTBMV_A_nn;
-    double[] L2_zTBMV_x_n1;
-    double[] L2_zTBMV_x_n2;
-    double[] L2_zTBMV_o_UN;
-    double[] L2_zTBMV_o_UN2;
-    double[] L2_zTBMV_o_UT;
-    double[] L2_zTBMV_o_UH;
-
-    float[] L2_sTRSV_A_nn;
-    float[] L2_sTRSV_A_nn_pu;
-    float[] L2_sTRSV_x_n1;
-    float[] L2_sTRSV_x_n2;
-    float[] L2_sTRSV_o_UN;
-    float[] L2_sTRSV_o_UN2;
-    float[] L2_sTRSV_o_UT;
-    float[] L2_sTRSV_o_UH;
-
-    double[] L2_dTRSV_A_nn;
-    double[] L2_dTRSV_A_nn_pu;
-    double[] L2_dTRSV_x_n1;
-    double[] L2_dTRSV_x_n2;
-    double[] L2_dTRSV_o_UN;
-    double[] L2_dTRSV_o_UN2;
-    double[] L2_dTRSV_o_UT;
-    double[] L2_dTRSV_o_UH;
-
-    float[] L2_cTRSV_A_nn;
-    float[] L2_cTRSV_A_nn_pu;
-    float[] L2_cTRSV_x_n1;
-    float[] L2_cTRSV_x_n2;
-    float[] L2_cTRSV_o_UN;
-    float[] L2_cTRSV_o_UN2;
-    float[] L2_cTRSV_o_UT;
-    float[] L2_cTRSV_o_UH;
-
-    double[] L2_zTRSV_A_nn;
-    double[] L2_zTRSV_A_nn_pu;
-    double[] L2_zTRSV_x_n1;
-    double[] L2_zTRSV_x_n2;
-    double[] L2_zTRSV_o_UN;
-    double[] L2_zTRSV_o_UN2;
-    double[] L2_zTRSV_o_UT;
-    double[] L2_zTRSV_o_UH;
-
-    float[] L2_sTBSV_A_nn;
-    float[] L2_sTBSV_x_n1;
-    float[] L2_sTBSV_x_n2;
-    float[] L2_sTBSV_o_UN;
-    float[] L2_sTBSV_o_UN2;
-    float[] L2_sTBSV_o_UT;
-    float[] L2_sTBSV_o_UH;
-
-    double[] L2_dTBSV_A_nn;
-    double[] L2_dTBSV_x_n1;
-    double[] L2_dTBSV_x_n2;
-    double[] L2_dTBSV_o_UN;
-    double[] L2_dTBSV_o_UN2;
-    double[] L2_dTBSV_o_UT;
-    double[] L2_dTBSV_o_UH;
-
-    float[] L2_cTBSV_A_nn;
-    float[] L2_cTBSV_x_n1;
-    float[] L2_cTBSV_x_n2;
-    float[] L2_cTBSV_o_UN;
-    float[] L2_cTBSV_o_UN2;
-    float[] L2_cTBSV_o_UT;
-    float[] L2_cTBSV_o_UH;
-
-    double[] L2_zTBSV_A_nn;
-    double[] L2_zTBSV_x_n1;
-    double[] L2_zTBSV_x_n2;
-    double[] L2_zTBSV_o_UN;
-    double[] L2_zTBSV_o_UN2;
-    double[] L2_zTBSV_o_UT;
-    double[] L2_zTBSV_o_UH;
-
-    float[] L2_sGER_A_mn;
-    float[] L2_sGER_x_m1;
-    float[] L2_sGER_x_m2;
-    float[] L2_sGER_y_n1;
-    float[] L2_sGER_y_n2;
-    float[] L2_sGER_o_N;
-
-    double[] L2_dGER_A_mn;
-    double[] L2_dGER_x_m1;
-    double[] L2_dGER_x_m2;
-    double[] L2_dGER_y_n1;
-    double[] L2_dGER_y_n2;
-    double[] L2_dGER_o_N;
-
-    float[] L2_cGERU_A_mn;
-    float[] L2_cGERU_x_m1;
-    float[] L2_cGERU_x_m2;
-    float[] L2_cGERU_y_n1;
-    float[] L2_cGERU_y_n2;
-    float[] L2_cGERU_o_N;
-
-    double[] L2_zGERU_A_mn;
-    double[] L2_zGERU_x_m1;
-    double[] L2_zGERU_x_m2;
-    double[] L2_zGERU_y_n1;
-    double[] L2_zGERU_y_n2;
-    double[] L2_zGERU_o_N;
-
-    float[] L2_cGERC_A_mn;
-    float[] L2_cGERC_x_m1;
-    float[] L2_cGERC_x_m2;
-    float[] L2_cGERC_y_n1;
-    float[] L2_cGERC_y_n2;
-    float[] L2_cGERC_o_N;
-
-    double[] L2_zGERC_A_mn;
-    double[] L2_zGERC_x_m1;
-    double[] L2_zGERC_x_m2;
-    double[] L2_zGERC_y_n1;
-    double[] L2_zGERC_y_n2;
-    double[] L2_zGERC_o_N;
-
-    float[] L2_cHER_A_nn;
-    float[] L2_cHER_A_nn_pu;
-    float[] L2_cHER_x_n1;
-    float[] L2_cHER_x_n2;
-    float[] L2_cHER_o_N;
-    float[] L2_cHER_o_N_pu;
-
-    double[] L2_zHER_A_nn;
-    double[] L2_zHER_A_nn_pu;
-    double[] L2_zHER_x_n1;
-    double[] L2_zHER_x_n2;
-    double[] L2_zHER_o_N;
-    double[] L2_zHER_o_N_pu;
-
-    float[] L2_cHER2_A_nn;
-    float[] L2_cHER2_A_nn_pu;
-    float[] L2_cHER2_x_n1;
-    float[] L2_cHER2_x_n2;
-    float[] L2_cHER2_y_n1;
-    float[] L2_cHER2_y_n2;
-    float[] L2_cHER2_o_N;
-    float[] L2_cHER2_o_N_pu;
-
-    double[] L2_zHER2_A_nn;
-    double[] L2_zHER2_A_nn_pu;
-    double[] L2_zHER2_x_n1;
-    double[] L2_zHER2_x_n2;
-    double[] L2_zHER2_y_n1;
-    double[] L2_zHER2_y_n2;
-    double[] L2_zHER2_o_N;
-    double[] L2_zHER2_o_N_pu;
-
-    float[] L2_sSYR_A_nn;
-    float[] L2_sSYR_A_nn_pu;
-    float[] L2_sSYR_x_n1;
-    float[] L2_sSYR_x_n2;
-    float[] L2_sSYR_o_N;
-    float[] L2_sSYR_o_N_pu;
-
-    double[] L2_dSYR_A_nn;
-    double[] L2_dSYR_A_nn_pu;
-    double[] L2_dSYR_x_n1;
-    double[] L2_dSYR_x_n2;
-    double[] L2_dSYR_o_N;
-    double[] L2_dSYR_o_N_pu;
-
-    float[] L2_sSYR2_A_nn;
-    float[] L2_sSYR2_A_nn_pu;
-    float[] L2_sSYR2_x_n1;
-    float[] L2_sSYR2_x_n2;
-    float[] L2_sSYR2_y_n1;
-    float[] L2_sSYR2_y_n2;
-    float[] L2_sSYR2_o_N;
-    float[] L2_sSYR2_o_N_pu;
-
-    double[] L2_dSYR2_A_nn;
-    double[] L2_dSYR2_A_nn_pu;
-    double[] L2_dSYR2_x_n1;
-    double[] L2_dSYR2_x_n2;
-    double[] L2_dSYR2_y_n1;
-    double[] L2_dSYR2_y_n2;
-    double[] L2_dSYR2_o_N;
-    double[] L2_dSYR2_o_N_pu;
-
-    float[] L3_sGEMM_A_mk;
-    float[] L3_sGEMM_B_kn;
-    float[] L3_sGEMM_C_mn;
-    float[] L3_sGEMM_o_NN;
-    float[] L3_sGEMM_A_km;
-    float[] L3_sGEMM_B_nk;
-    float[] L3_sGEMM_o_TT;
-    float[] L3_sGEMM_o_HH;
-
-    double[] L3_dGEMM_A_mk;
-    double[] L3_dGEMM_B_kn;
-    double[] L3_dGEMM_C_mn;
-    double[] L3_dGEMM_o_NN;
-    double[] L3_dGEMM_A_km;
-    double[] L3_dGEMM_B_nk;
-    double[] L3_dGEMM_o_TT;
-    double[] L3_dGEMM_o_HH;
-    float[] L3_cGEMM_A_mk;
-    float[] L3_cGEMM_B_kn;
-    float[] L3_cGEMM_C_mn;
-    float[] L3_cGEMM_o_NN;
-    float[] L3_cGEMM_A_km;
-    float[] L3_cGEMM_B_nk;
-    float[] L3_cGEMM_o_TT;
-    float[] L3_cGEMM_o_HH;
-
-    double[] L3_zGEMM_A_mk;
-    double[] L3_zGEMM_B_kn;
-    double[] L3_zGEMM_C_mn;
-    double[] L3_zGEMM_o_NN;
-    double[] L3_zGEMM_A_km;
-    double[] L3_zGEMM_B_nk;
-    double[] L3_zGEMM_o_TT;
-    double[] L3_zGEMM_o_HH;
-
-    float[] L3_sSYMM_A_mm;
-    float[] L3_sSYMM_B_mn;
-    float[] L3_sSYMM_C_mn;
-    float[] L3_sSYMM_o_L;
-    float[] L3_sSYMM_A_nn;
-    float[] L3_sSYMM_o_R;
-
-    double[] L3_dSYMM_A_mm;
-    double[] L3_dSYMM_B_mn;
-    double[] L3_dSYMM_C_mn;
-    double[] L3_dSYMM_o_L;
-    double[] L3_dSYMM_A_nn;
-    double[] L3_dSYMM_o_R;
-
-    float[] L3_cSYMM_A_mm;
-    float[] L3_cSYMM_B_mn;
-    float[] L3_cSYMM_C_mn;
-    float[] L3_cSYMM_o_L;
-    float[] L3_cSYMM_A_nn;
-    float[] L3_cSYMM_o_R;
-
-    double[] L3_zSYMM_A_mm;
-    double[] L3_zSYMM_B_mn;
-    double[] L3_zSYMM_C_mn;
-    double[] L3_zSYMM_o_L;
-    double[] L3_zSYMM_A_nn;
-    double[] L3_zSYMM_o_R;
-
-    float[] L3_cHEMM_A_mm;
-    float[] L3_cHEMM_B_mn;
-    float[] L3_cHEMM_C_mn;
-    float[] L3_cHEMM_o_L;
-    float[] L3_cHEMM_A_nn;
-    float[] L3_cHEMM_o_R;
-
-    double[] L3_zHEMM_A_mm;
-    double[] L3_zHEMM_B_mn;
-    double[] L3_zHEMM_C_mn;
-    double[] L3_zHEMM_o_L;
-    double[] L3_zHEMM_A_nn;
-    double[] L3_zHEMM_o_R;
-
-    float[] L3_sSYRK_A_nk;
-    float[] L3_sSYRK_C_nn;
-    float[] L3_sSYRK_o_N;
-    float[] L3_sSYRK_A_kn;
-    float[] L3_sSYRK_o_T;
-
-    double[] L3_dSYRK_A_nk;
-    double[] L3_dSYRK_C_nn;
-    double[] L3_dSYRK_o_N;
-    double[] L3_dSYRK_A_kn;
-    double[] L3_dSYRK_o_T;
-
-    float[] L3_cSYRK_A_nk;
-    float[] L3_cSYRK_C_nn;
-    float[] L3_cSYRK_o_N;
-    float[] L3_cSYRK_A_kn;
-    float[] L3_cSYRK_o_T;
-
-    double[] L3_zSYRK_A_nk;
-    double[] L3_zSYRK_C_nn;
-    double[] L3_zSYRK_o_N;
-    double[] L3_zSYRK_A_kn;
-    double[] L3_zSYRK_o_T;
-
-    float[] L3_cHERK_A_nk;
-    float[] L3_cHERK_C_nn;
-    float[] L3_cHERK_o_N;
-    float[] L3_cHERK_A_kn;
-    float[] L3_cHERK_o_H;
-
-    double[] L3_zHERK_A_nk;
-    double[] L3_zHERK_C_nn;
-    double[] L3_zHERK_o_N;
-    double[] L3_zHERK_A_kn;
-    double[] L3_zHERK_o_H;
-
-    float[] L3_sSYR2K_A_nk;
-    float[] L3_sSYR2K_B_nk;
-    float[] L3_sSYR2K_C_nn;
-    float[] L3_sSYR2K_o_N;
-    float[] L3_sSYR2K_A_kn;
-    float[] L3_sSYR2K_B_kn;
-    float[] L3_sSYR2K_o_T;
-
-    double[] L3_dSYR2K_A_nk;
-    double[] L3_dSYR2K_B_nk;
-    double[] L3_dSYR2K_C_nn;
-    double[] L3_dSYR2K_o_N;
-    double[] L3_dSYR2K_A_kn;
-    double[] L3_dSYR2K_B_kn;
-    double[] L3_dSYR2K_o_T;
-
-    float[] L3_cSYR2K_A_nk;
-    float[] L3_cSYR2K_B_nk;
-    float[] L3_cSYR2K_C_nn;
-    float[] L3_cSYR2K_o_N;
-    float[] L3_cSYR2K_A_kn;
-    float[] L3_cSYR2K_B_kn;
-    float[] L3_cSYR2K_o_T;
-
-    double[] L3_zSYR2K_A_nk;
-    double[] L3_zSYR2K_B_nk;
-    double[] L3_zSYR2K_C_nn;
-    double[] L3_zSYR2K_o_N;
-    double[] L3_zSYR2K_A_kn;
-    double[] L3_zSYR2K_B_kn;
-    double[] L3_zSYR2K_o_T;
-
-    float[] L3_cHER2K_A_nk;
-    float[] L3_cHER2K_B_nk;
-    float[] L3_cHER2K_C_nn;
-    float[] L3_cHER2K_o_N;
-    float[] L3_cHER2K_A_kn;
-    float[] L3_cHER2K_B_kn;
-    float[] L3_cHER2K_o_H;
-
-    double[] L3_zHER2K_A_nk;
-    double[] L3_zHER2K_B_nk;
-    double[] L3_zHER2K_C_nn;
-    double[] L3_zHER2K_o_N;
-    double[] L3_zHER2K_A_kn;
-    double[] L3_zHER2K_B_kn;
-    double[] L3_zHER2K_o_H;
-
-    float[] L3_sTRMM_A_mm;
-    float[] L3_sTRMM_B_mn;
-    float[] L3_sTRMM_o_LUN;
-    float[] L3_sTRMM_A_nn;
-    float[] L3_sTRMM_o_RLT;
-
-    double[] L3_dTRMM_A_mm;
-    double[] L3_dTRMM_B_mn;
-    double[] L3_dTRMM_o_LUN;
-    double[] L3_dTRMM_A_nn;
-    double[] L3_dTRMM_o_RLT;
-
-    float[] L3_cTRMM_A_mm;
-    float[] L3_cTRMM_B_mn;
-    float[] L3_cTRMM_o_LUN;
-    float[] L3_cTRMM_A_nn;
-    float[] L3_cTRMM_o_RLT;
-
-    double[] L3_zTRMM_A_mm;
-    double[] L3_zTRMM_B_mn;
-    double[] L3_zTRMM_o_LUN;
-    double[] L3_zTRMM_A_nn;
-    double[] L3_zTRMM_o_RLT;
-
-    float[] L3_sTRSM_A_mm;
-    float[] L3_sTRSM_B_mn;
-    float[] L3_sTRSM_o_LUN;
-    float[] L3_sTRSM_A_nn;
-    float[] L3_sTRSM_o_RLT;
-
-    double[] L3_dTRSM_A_mm;
-    double[] L3_dTRSM_B_mn;
-    double[] L3_dTRSM_o_LUN;
-    double[] L3_dTRSM_A_nn;
-    double[] L3_dTRSM_o_RLT;
-
-    float[] L3_cTRSM_A_mm;
-    float[] L3_cTRSM_B_mn;
-    float[] L3_cTRSM_o_LUN;
-    float[] L3_cTRSM_A_nn;
-    float[] L3_cTRSM_o_RLT;
-
-    double[] L3_zTRSM_A_mm;
-    double[] L3_zTRSM_B_mn;
-    double[] L3_zTRSM_o_LUN;
-    double[] L3_zTRSM_A_nn;
-    double[] L3_zTRSM_o_RLT;
-
-    //load dimensions of matrixes
-    private void loadMNK() throws Exception {
-        String data = "";
-        int skipLine = 3;
-
-        for (int i = 0; i < skipLine; i++) {
-            data = mBufReader.readLine();
-        }
-        data = mBufReader.readLine();
-
-        String[] results = data.split(" ");
-        dM = Integer.parseInt(results[0]);
-        dN = Integer.parseInt(results[1]);
-        dK = Integer.parseInt(results[2]);
-        KL = Integer.parseInt(results[3]);
-        KU = Integer.parseInt(results[4]);
-    }
-
-    private float[] loadFloatArray() throws Exception {
-        String data = "";
-        int skipLine = 2;
-
-        for (int i = 0; i < skipLine; i++) {
-            data = mBufReader.readLine();
-        }
-        data = mBufReader.readLine();
-        String[] results = data.split(", ");
-
-        float[] floatArr = new float[results.length];
-        for (int i = 0; i < floatArr.length; i++) {
-            floatArr[i] = Float.parseFloat(results[i]);
-        }
-
-        return floatArr;
-    }
-
-    private double[] loadDoubleArray() throws Exception {
-        String data = "";
-        int skipLine = 2;
-
-        for (int i = 0; i < skipLine; i++) {
-            data = mBufReader.readLine();
-        }
-        data = mBufReader.readLine();
-        String[] results = data.split(", ");
-
-        double[] doubleArr = new double[results.length];
-        for (int i = 0; i < doubleArr.length; i++) {
-            doubleArr[i] = Double.parseDouble(results[i]);
-        }
-        return doubleArr;
-    }
-
-    //load data for L2 BLAS
-    private void loadGEMVData() throws Exception {
-        L2_sGEMV_A_mn = loadFloatArray();
-        L2_sGEMV_x_n1 = loadFloatArray();
-        L2_sGEMV_x_n2 = loadFloatArray();
-        L2_sGEMV_y_m1 = loadFloatArray();
-        L2_sGEMV_y_m2 = loadFloatArray();
-        L2_sGEMV_o_N = loadFloatArray();
-        L2_sGEMV_o_N2 = loadFloatArray();
-        L2_sGEMV_o_T = loadFloatArray();
-        L2_sGEMV_o_H = loadFloatArray();
-
-        L2_dGEMV_A_mn = loadDoubleArray();
-        L2_dGEMV_x_n1 = loadDoubleArray();
-        L2_dGEMV_x_n2 = loadDoubleArray();
-        L2_dGEMV_y_m1 = loadDoubleArray();
-        L2_dGEMV_y_m2 = loadDoubleArray();
-        L2_dGEMV_o_N = loadDoubleArray();
-        L2_dGEMV_o_N2 = loadDoubleArray();
-        L2_dGEMV_o_T = loadDoubleArray();
-        L2_dGEMV_o_H = loadDoubleArray();
-
-        L2_cGEMV_A_mn = loadFloatArray();
-        L2_cGEMV_x_n1 = loadFloatArray();
-        L2_cGEMV_x_n2 = loadFloatArray();
-        L2_cGEMV_y_m1 = loadFloatArray();
-        L2_cGEMV_y_m2 = loadFloatArray();
-        L2_cGEMV_o_N = loadFloatArray();
-        L2_cGEMV_o_N2 = loadFloatArray();
-        L2_cGEMV_o_T = loadFloatArray();
-        L2_cGEMV_o_H = loadFloatArray();
-
-        L2_zGEMV_A_mn = loadDoubleArray();
-        L2_zGEMV_x_n1 = loadDoubleArray();
-        L2_zGEMV_x_n2 = loadDoubleArray();
-        L2_zGEMV_y_m1 = loadDoubleArray();
-        L2_zGEMV_y_m2 = loadDoubleArray();
-        L2_zGEMV_o_N = loadDoubleArray();
-        L2_zGEMV_o_N2 = loadDoubleArray();
-        L2_zGEMV_o_T = loadDoubleArray();
-        L2_zGEMV_o_H = loadDoubleArray();
-
-    }
-
-    private void loadGBMVData() throws Exception {
-        L2_sGBMV_A_mn = loadFloatArray();
-        L2_sGBMV_x_n1 = loadFloatArray();
-        L2_sGBMV_x_n2 = loadFloatArray();
-        L2_sGBMV_y_m1 = loadFloatArray();
-        L2_sGBMV_y_m2 = loadFloatArray();
-        L2_sGBMV_o_N = loadFloatArray();
-        L2_sGBMV_o_N2 = loadFloatArray();
-        L2_sGBMV_o_T = loadFloatArray();
-        L2_sGBMV_o_H = loadFloatArray();
-
-        L2_dGBMV_A_mn = loadDoubleArray();
-        L2_dGBMV_x_n1 = loadDoubleArray();
-        L2_dGBMV_x_n2 = loadDoubleArray();
-        L2_dGBMV_y_m1 = loadDoubleArray();
-        L2_dGBMV_y_m2 = loadDoubleArray();
-        L2_dGBMV_o_N = loadDoubleArray();
-        L2_dGBMV_o_N2 = loadDoubleArray();
-        L2_dGBMV_o_T = loadDoubleArray();
-        L2_dGBMV_o_H = loadDoubleArray();
-
-        L2_cGBMV_A_mn = loadFloatArray();
-        L2_cGBMV_x_n1 = loadFloatArray();
-        L2_cGBMV_x_n2 = loadFloatArray();
-        L2_cGBMV_y_m1 = loadFloatArray();
-        L2_cGBMV_y_m2 = loadFloatArray();
-        L2_cGBMV_o_N = loadFloatArray();
-        L2_cGBMV_o_N2 = loadFloatArray();
-        L2_cGBMV_o_T = loadFloatArray();
-        L2_cGBMV_o_H = loadFloatArray();
-
-        L2_zGBMV_A_mn = loadDoubleArray();
-        L2_zGBMV_x_n1 = loadDoubleArray();
-        L2_zGBMV_x_n2 = loadDoubleArray();
-        L2_zGBMV_y_m1 = loadDoubleArray();
-        L2_zGBMV_y_m2 = loadDoubleArray();
-        L2_zGBMV_o_N = loadDoubleArray();
-        L2_zGBMV_o_N2 = loadDoubleArray();
-        L2_zGBMV_o_T = loadDoubleArray();
-        L2_zGBMV_o_H = loadDoubleArray();
-    }
-
-    private void loadHEMVData() throws Exception {
-        L2_cHEMV_A_nn = loadFloatArray();
-        L2_cHEMV_A_nn_pu = loadFloatArray();
-        L2_cHEMV_x_n1 = loadFloatArray();
-        L2_cHEMV_x_n2 = loadFloatArray();
-        L2_cHEMV_y_n1 = loadFloatArray();
-        L2_cHEMV_y_n2 = loadFloatArray();
-        L2_cHEMV_o_N = loadFloatArray();
-        L2_cHEMV_o_N2 = loadFloatArray();
-
-        L2_zHEMV_A_nn = loadDoubleArray();
-        L2_zHEMV_A_nn_pu = loadDoubleArray();
-        L2_zHEMV_x_n1 = loadDoubleArray();
-        L2_zHEMV_x_n2 = loadDoubleArray();
-        L2_zHEMV_y_n1 = loadDoubleArray();
-        L2_zHEMV_y_n2 = loadDoubleArray();
-        L2_zHEMV_o_N = loadDoubleArray();
-        L2_zHEMV_o_N2 = loadDoubleArray();
-    }
-
-    private void loadHBMVData() throws Exception {
-        L2_cHBMV_A_nn = loadFloatArray();
-        L2_cHBMV_x_n1 = loadFloatArray();
-        L2_cHBMV_x_n2 = loadFloatArray();
-        L2_cHBMV_y_n1 = loadFloatArray();
-        L2_cHBMV_y_n2 = loadFloatArray();
-        L2_cHBMV_o_N = loadFloatArray();
-        L2_cHBMV_o_N2 = loadFloatArray();
-
-        L2_zHBMV_A_nn = loadDoubleArray();
-        L2_zHBMV_x_n1 = loadDoubleArray();
-        L2_zHBMV_x_n2 = loadDoubleArray();
-        L2_zHBMV_y_n1 = loadDoubleArray();
-        L2_zHBMV_y_n2 = loadDoubleArray();
-        L2_zHBMV_o_N = loadDoubleArray();
-        L2_zHBMV_o_N2 = loadDoubleArray();
-    }
-
-    private void loadSYMVData() throws Exception {
-        L2_sSYMV_A_nn = loadFloatArray();
-        L2_sSYMV_A_nn_pu = loadFloatArray();
-        L2_sSYMV_x_n1 = loadFloatArray();
-        L2_sSYMV_x_n2 = loadFloatArray();
-        L2_sSYMV_y_n1 = loadFloatArray();
-        L2_sSYMV_y_n2 = loadFloatArray();
-        L2_sSYMV_o_N = loadFloatArray();
-        L2_sSYMV_o_N2 = loadFloatArray();
-
-        L2_dSYMV_A_nn = loadDoubleArray();
-        L2_dSYMV_A_nn_pu = loadDoubleArray();
-        L2_dSYMV_x_n1 = loadDoubleArray();
-        L2_dSYMV_x_n2 = loadDoubleArray();
-        L2_dSYMV_y_n1 = loadDoubleArray();
-        L2_dSYMV_y_n2 = loadDoubleArray();
-        L2_dSYMV_o_N = loadDoubleArray();
-        L2_dSYMV_o_N2 = loadDoubleArray();
-    }
-
-    private void loadSBMVData() throws Exception {
-        L2_sSBMV_A_nn = loadFloatArray();
-        L2_sSBMV_x_n1 = loadFloatArray();
-        L2_sSBMV_x_n2 = loadFloatArray();
-        L2_sSBMV_y_n1 = loadFloatArray();
-        L2_sSBMV_y_n2 = loadFloatArray();
-        L2_sSBMV_o_N = loadFloatArray();
-        L2_sSBMV_o_N2 = loadFloatArray();
-
-        L2_dSBMV_A_nn = loadDoubleArray();
-        L2_dSBMV_x_n1 = loadDoubleArray();
-        L2_dSBMV_x_n2 = loadDoubleArray();
-        L2_dSBMV_y_n1 = loadDoubleArray();
-        L2_dSBMV_y_n2 = loadDoubleArray();
-        L2_dSBMV_o_N = loadDoubleArray();
-        L2_dSBMV_o_N2 = loadDoubleArray();
-    }
-
-    private void loadTRMVData() throws Exception {
-        L2_sTRMV_A_nn = loadFloatArray();
-        L2_sTRMV_A_nn_pu = loadFloatArray();
-        L2_sTRMV_x_n1 = loadFloatArray();
-        L2_sTRMV_x_n2 = loadFloatArray();
-        L2_sTRMV_o_UN = loadFloatArray();
-        L2_sTRMV_o_UN2 = loadFloatArray();
-        L2_sTRMV_o_UT = loadFloatArray();
-        L2_sTRMV_o_UH = loadFloatArray();
-
-        L2_dTRMV_A_nn = loadDoubleArray();
-        L2_dTRMV_A_nn_pu = loadDoubleArray();
-        L2_dTRMV_x_n1 = loadDoubleArray();
-        L2_dTRMV_x_n2 = loadDoubleArray();
-        L2_dTRMV_o_UN = loadDoubleArray();
-        L2_dTRMV_o_UN2 = loadDoubleArray();
-        L2_dTRMV_o_UT = loadDoubleArray();
-        L2_dTRMV_o_UH = loadDoubleArray();
-
-        L2_cTRMV_A_nn = loadFloatArray();
-        L2_cTRMV_A_nn_pu = loadFloatArray();
-        L2_cTRMV_x_n1 = loadFloatArray();
-        L2_cTRMV_x_n2 = loadFloatArray();
-        L2_cTRMV_o_UN = loadFloatArray();
-        L2_cTRMV_o_UN2 = loadFloatArray();
-        L2_cTRMV_o_UT = loadFloatArray();
-        L2_cTRMV_o_UH = loadFloatArray();
-
-        L2_zTRMV_A_nn = loadDoubleArray();
-        L2_zTRMV_A_nn_pu = loadDoubleArray();
-        L2_zTRMV_x_n1 = loadDoubleArray();
-        L2_zTRMV_x_n2 = loadDoubleArray();
-        L2_zTRMV_o_UN = loadDoubleArray();
-        L2_zTRMV_o_UN2 = loadDoubleArray();
-        L2_zTRMV_o_UT = loadDoubleArray();
-        L2_zTRMV_o_UH = loadDoubleArray();
-    }
-
-    private void loadTBMVData() throws Exception {
-        L2_sTBMV_A_nn = loadFloatArray();
-        L2_sTBMV_x_n1 = loadFloatArray();
-        L2_sTBMV_x_n2 = loadFloatArray();
-        L2_sTBMV_o_UN = loadFloatArray();
-        L2_sTBMV_o_UN2 = loadFloatArray();
-        L2_sTBMV_o_UT = loadFloatArray();
-        L2_sTBMV_o_UH = loadFloatArray();
-
-        L2_dTBMV_A_nn = loadDoubleArray();
-        L2_dTBMV_x_n1 = loadDoubleArray();
-        L2_dTBMV_x_n2 = loadDoubleArray();
-        L2_dTBMV_o_UN = loadDoubleArray();
-        L2_dTBMV_o_UN2 = loadDoubleArray();
-        L2_dTBMV_o_UT = loadDoubleArray();
-        L2_dTBMV_o_UH = loadDoubleArray();
-
-        L2_cTBMV_A_nn = loadFloatArray();
-        L2_cTBMV_x_n1 = loadFloatArray();
-        L2_cTBMV_x_n2 = loadFloatArray();
-        L2_cTBMV_o_UN = loadFloatArray();
-        L2_cTBMV_o_UN2 = loadFloatArray();
-        L2_cTBMV_o_UT = loadFloatArray();
-        L2_cTBMV_o_UH = loadFloatArray();
-
-        L2_zTBMV_A_nn = loadDoubleArray();
-        L2_zTBMV_x_n1 = loadDoubleArray();
-        L2_zTBMV_x_n2 = loadDoubleArray();
-        L2_zTBMV_o_UN = loadDoubleArray();
-        L2_zTBMV_o_UN2 = loadDoubleArray();
-        L2_zTBMV_o_UT = loadDoubleArray();
-        L2_zTBMV_o_UH = loadDoubleArray();
-    }
-
-    private void loadTRSVData() throws Exception {
-        L2_sTRSV_A_nn = loadFloatArray();
-        L2_sTRSV_A_nn_pu = loadFloatArray();
-        L2_sTRSV_x_n1 = loadFloatArray();
-        L2_sTRSV_x_n2 = loadFloatArray();
-        L2_sTRSV_o_UN = loadFloatArray();
-        L2_sTRSV_o_UN2 = loadFloatArray();
-        L2_sTRSV_o_UT = loadFloatArray();
-        L2_sTRSV_o_UH = loadFloatArray();
-
-        L2_dTRSV_A_nn = loadDoubleArray();
-        L2_dTRSV_A_nn_pu = loadDoubleArray();
-        L2_dTRSV_x_n1 = loadDoubleArray();
-        L2_dTRSV_x_n2 = loadDoubleArray();
-        L2_dTRSV_o_UN = loadDoubleArray();
-        L2_dTRSV_o_UN2 = loadDoubleArray();
-        L2_dTRSV_o_UT = loadDoubleArray();
-        L2_dTRSV_o_UH = loadDoubleArray();
-
-        L2_cTRSV_A_nn = loadFloatArray();
-        L2_cTRSV_A_nn_pu = loadFloatArray();
-        L2_cTRSV_x_n1 = loadFloatArray();
-        L2_cTRSV_x_n2 = loadFloatArray();
-        L2_cTRSV_o_UN = loadFloatArray();
-        L2_cTRSV_o_UN2 = loadFloatArray();
-        L2_cTRSV_o_UT = loadFloatArray();
-        L2_cTRSV_o_UH = loadFloatArray();
-
-        L2_zTRSV_A_nn = loadDoubleArray();
-        L2_zTRSV_A_nn_pu = loadDoubleArray();
-        L2_zTRSV_x_n1 = loadDoubleArray();
-        L2_zTRSV_x_n2 = loadDoubleArray();
-        L2_zTRSV_o_UN = loadDoubleArray();
-        L2_zTRSV_o_UN2 = loadDoubleArray();
-        L2_zTRSV_o_UT = loadDoubleArray();
-        L2_zTRSV_o_UH = loadDoubleArray();
-    }
-
-    private void loadTBSVData() throws Exception {
-        L2_sTBSV_A_nn = loadFloatArray();
-        L2_sTBSV_x_n1 = loadFloatArray();
-        L2_sTBSV_x_n2 = loadFloatArray();
-        L2_sTBSV_o_UN = loadFloatArray();
-        L2_sTBSV_o_UN2 = loadFloatArray();
-        L2_sTBSV_o_UT = loadFloatArray();
-        L2_sTBSV_o_UH = loadFloatArray();
-
-        L2_dTBSV_A_nn = loadDoubleArray();
-        L2_dTBSV_x_n1 = loadDoubleArray();
-        L2_dTBSV_x_n2 = loadDoubleArray();
-        L2_dTBSV_o_UN = loadDoubleArray();
-        L2_dTBSV_o_UN2 = loadDoubleArray();
-        L2_dTBSV_o_UT = loadDoubleArray();
-        L2_dTBSV_o_UH = loadDoubleArray();
-
-        L2_cTBSV_A_nn = loadFloatArray();
-        L2_cTBSV_x_n1 = loadFloatArray();
-        L2_cTBSV_x_n2 = loadFloatArray();
-        L2_cTBSV_o_UN = loadFloatArray();
-        L2_cTBSV_o_UN2 = loadFloatArray();
-        L2_cTBSV_o_UT = loadFloatArray();
-        L2_cTBSV_o_UH = loadFloatArray();
-
-        L2_zTBSV_A_nn = loadDoubleArray();
-        L2_zTBSV_x_n1 = loadDoubleArray();
-        L2_zTBSV_x_n2 = loadDoubleArray();
-        L2_zTBSV_o_UN = loadDoubleArray();
-        L2_zTBSV_o_UN2 = loadDoubleArray();
-        L2_zTBSV_o_UT = loadDoubleArray();
-        L2_zTBSV_o_UH = loadDoubleArray();
-    }
-
-    private void loadGERData() throws Exception {
-        L2_sGER_A_mn = loadFloatArray();
-        L2_sGER_x_m1 = loadFloatArray();
-        L2_sGER_x_m2 = loadFloatArray();
-        L2_sGER_y_n1 = loadFloatArray();
-        L2_sGER_y_n2 = loadFloatArray();
-        L2_sGER_o_N = loadFloatArray();
-
-        L2_dGER_A_mn = loadDoubleArray();
-        L2_dGER_x_m1 = loadDoubleArray();
-        L2_dGER_x_m2 = loadDoubleArray();
-        L2_dGER_y_n1 = loadDoubleArray();
-        L2_dGER_y_n2 = loadDoubleArray();
-        L2_dGER_o_N = loadDoubleArray();
-    }
-
-    private void loadGERUData() throws Exception {
-        L2_cGERU_A_mn = loadFloatArray();
-        L2_cGERU_x_m1 = loadFloatArray();
-        L2_cGERU_x_m2 = loadFloatArray();
-        L2_cGERU_y_n1 = loadFloatArray();
-        L2_cGERU_y_n2 = loadFloatArray();
-        L2_cGERU_o_N = loadFloatArray();
-
-        L2_zGERU_A_mn = loadDoubleArray();
-        L2_zGERU_x_m1 = loadDoubleArray();
-        L2_zGERU_x_m2 = loadDoubleArray();
-        L2_zGERU_y_n1 = loadDoubleArray();
-        L2_zGERU_y_n2 = loadDoubleArray();
-        L2_zGERU_o_N = loadDoubleArray();
-    }
-
-    private void loadGERCData() throws Exception {
-        L2_cGERC_A_mn = loadFloatArray();
-        L2_cGERC_x_m1 = loadFloatArray();
-        L2_cGERC_x_m2 = loadFloatArray();
-        L2_cGERC_y_n1 = loadFloatArray();
-        L2_cGERC_y_n2 = loadFloatArray();
-        L2_cGERC_o_N = loadFloatArray();
-
-        L2_zGERC_A_mn = loadDoubleArray();
-        L2_zGERC_x_m1 = loadDoubleArray();
-        L2_zGERC_x_m2 = loadDoubleArray();
-        L2_zGERC_y_n1 = loadDoubleArray();
-        L2_zGERC_y_n2 = loadDoubleArray();
-        L2_zGERC_o_N = loadDoubleArray();
-    }
-
-    private void loadHERData() throws Exception {
-        L2_cHER_A_nn = loadFloatArray();
-        L2_cHER_A_nn_pu = loadFloatArray();
-        L2_cHER_x_n1 = loadFloatArray();
-        L2_cHER_x_n2 = loadFloatArray();
-        L2_cHER_o_N = loadFloatArray();
-        L2_cHER_o_N_pu = loadFloatArray();
-
-        L2_zHER_A_nn = loadDoubleArray();
-        L2_zHER_A_nn_pu = loadDoubleArray();
-        L2_zHER_x_n1 = loadDoubleArray();
-        L2_zHER_x_n2 = loadDoubleArray();
-        L2_zHER_o_N = loadDoubleArray();
-        L2_zHER_o_N_pu = loadDoubleArray();
-    }
-
-    private void loadHER2Data() throws Exception {
-        L2_cHER2_A_nn = loadFloatArray();
-        L2_cHER2_A_nn_pu = loadFloatArray();
-        L2_cHER2_x_n1 = loadFloatArray();
-        L2_cHER2_x_n2 = loadFloatArray();
-        L2_cHER2_y_n1 = loadFloatArray();
-        L2_cHER2_y_n2 = loadFloatArray();
-        L2_cHER2_o_N = loadFloatArray();
-        L2_cHER2_o_N_pu = loadFloatArray();
-
-        L2_zHER2_A_nn = loadDoubleArray();
-        L2_zHER2_A_nn_pu = loadDoubleArray();
-        L2_zHER2_x_n1 = loadDoubleArray();
-        L2_zHER2_x_n2 = loadDoubleArray();
-        L2_zHER2_y_n1 = loadDoubleArray();
-        L2_zHER2_y_n2 = loadDoubleArray();
-        L2_zHER2_o_N = loadDoubleArray();
-        L2_zHER2_o_N_pu = loadDoubleArray();
-    }
-
-    private void loadSYRData() throws Exception {
-        L2_sSYR_A_nn = loadFloatArray();
-        L2_sSYR_A_nn_pu = loadFloatArray();
-        L2_sSYR_x_n1 = loadFloatArray();
-        L2_sSYR_x_n2 = loadFloatArray();
-        L2_sSYR_o_N = loadFloatArray();
-        L2_sSYR_o_N_pu = loadFloatArray();
-
-        L2_dSYR_A_nn = loadDoubleArray();
-        L2_dSYR_A_nn_pu = loadDoubleArray();
-        L2_dSYR_x_n1 = loadDoubleArray();
-        L2_dSYR_x_n2 = loadDoubleArray();
-        L2_dSYR_o_N = loadDoubleArray();
-        L2_dSYR_o_N_pu = loadDoubleArray();
-    }
-
-    private void loadSYR2Data() throws Exception {
-        L2_sSYR2_A_nn = loadFloatArray();
-        L2_sSYR2_A_nn_pu = loadFloatArray();
-        L2_sSYR2_x_n1 = loadFloatArray();
-        L2_sSYR2_x_n2 = loadFloatArray();
-        L2_sSYR2_y_n1 = loadFloatArray();
-        L2_sSYR2_y_n2 = loadFloatArray();
-        L2_sSYR2_o_N = loadFloatArray();
-        L2_sSYR2_o_N_pu = loadFloatArray();
-
-        L2_dSYR2_A_nn = loadDoubleArray();
-        L2_dSYR2_A_nn_pu = loadDoubleArray();
-        L2_dSYR2_x_n1 = loadDoubleArray();
-        L2_dSYR2_x_n2 = loadDoubleArray();
-        L2_dSYR2_y_n1 = loadDoubleArray();
-        L2_dSYR2_y_n2 = loadDoubleArray();
-        L2_dSYR2_o_N = loadDoubleArray();
-        L2_dSYR2_o_N_pu = loadDoubleArray();
-    }
-
-    //load data for L3 BLAS
-    private void loadGEMMData() throws Exception {
-        L3_sGEMM_A_mk = loadFloatArray();
-        L3_sGEMM_B_kn = loadFloatArray();
-        L3_sGEMM_C_mn = loadFloatArray();
-        L3_sGEMM_o_NN = loadFloatArray();
-        L3_sGEMM_A_km = loadFloatArray();
-        L3_sGEMM_B_nk = loadFloatArray();
-        L3_sGEMM_o_TT = loadFloatArray();
-        L3_sGEMM_o_HH = loadFloatArray();
-
-        L3_dGEMM_A_mk = loadDoubleArray();
-        L3_dGEMM_B_kn = loadDoubleArray();
-        L3_dGEMM_C_mn = loadDoubleArray();
-        L3_dGEMM_o_NN = loadDoubleArray();
-        L3_dGEMM_A_km = loadDoubleArray();
-        L3_dGEMM_B_nk = loadDoubleArray();
-        L3_dGEMM_o_TT = loadDoubleArray();
-        L3_dGEMM_o_HH = loadDoubleArray();
-
-        L3_cGEMM_A_mk = loadFloatArray();
-        L3_cGEMM_B_kn = loadFloatArray();
-        L3_cGEMM_C_mn = loadFloatArray();
-        L3_cGEMM_o_NN = loadFloatArray();
-        L3_cGEMM_A_km = loadFloatArray();
-        L3_cGEMM_B_nk = loadFloatArray();
-        L3_cGEMM_o_TT = loadFloatArray();
-        L3_cGEMM_o_HH = loadFloatArray();
-
-        L3_zGEMM_A_mk = loadDoubleArray();
-        L3_zGEMM_B_kn = loadDoubleArray();
-        L3_zGEMM_C_mn = loadDoubleArray();
-        L3_zGEMM_o_NN = loadDoubleArray();
-        L3_zGEMM_A_km = loadDoubleArray();
-        L3_zGEMM_B_nk = loadDoubleArray();
-        L3_zGEMM_o_TT = loadDoubleArray();
-        L3_zGEMM_o_HH = loadDoubleArray();
-    }
-
-    private void loadSYMMData() throws Exception {
-        L3_sSYMM_A_mm = loadFloatArray();
-        L3_sSYMM_B_mn = loadFloatArray();
-        L3_sSYMM_C_mn = loadFloatArray();
-        L3_sSYMM_o_L = loadFloatArray();
-        L3_sSYMM_A_nn = loadFloatArray();
-        L3_sSYMM_o_R = loadFloatArray();
-
-        L3_dSYMM_A_mm = loadDoubleArray();
-        L3_dSYMM_B_mn = loadDoubleArray();
-        L3_dSYMM_C_mn = loadDoubleArray();
-        L3_dSYMM_o_L = loadDoubleArray();
-        L3_dSYMM_A_nn = loadDoubleArray();
-        L3_dSYMM_o_R = loadDoubleArray();
-
-        L3_cSYMM_A_mm = loadFloatArray();
-        L3_cSYMM_B_mn = loadFloatArray();
-        L3_cSYMM_C_mn = loadFloatArray();
-        L3_cSYMM_o_L = loadFloatArray();
-        L3_cSYMM_A_nn = loadFloatArray();
-        L3_cSYMM_o_R = loadFloatArray();
-
-        L3_zSYMM_A_mm = loadDoubleArray();
-        L3_zSYMM_B_mn = loadDoubleArray();
-        L3_zSYMM_C_mn = loadDoubleArray();
-        L3_zSYMM_o_L = loadDoubleArray();
-        L3_zSYMM_A_nn = loadDoubleArray();
-        L3_zSYMM_o_R = loadDoubleArray();
-    }
-
-    private void loadHEMMData() throws Exception {
-        L3_cHEMM_A_mm = loadFloatArray();
-        L3_cHEMM_B_mn = loadFloatArray();
-        L3_cHEMM_C_mn = loadFloatArray();
-        L3_cHEMM_o_L = loadFloatArray();
-        L3_cHEMM_A_nn = loadFloatArray();
-        L3_cHEMM_o_R = loadFloatArray();
-
-        L3_zHEMM_A_mm = loadDoubleArray();
-        L3_zHEMM_B_mn = loadDoubleArray();
-        L3_zHEMM_C_mn = loadDoubleArray();
-        L3_zHEMM_o_L = loadDoubleArray();
-        L3_zHEMM_A_nn = loadDoubleArray();
-        L3_zHEMM_o_R = loadDoubleArray();
-    }
-
-    private void loadSYRKData() throws Exception {
-        L3_sSYRK_A_nk = loadFloatArray();
-        L3_sSYRK_C_nn = loadFloatArray();
-        L3_sSYRK_o_N = loadFloatArray();
-        L3_sSYRK_A_kn = loadFloatArray();
-        L3_sSYRK_o_T = loadFloatArray();
-
-        L3_dSYRK_A_nk = loadDoubleArray();
-        L3_dSYRK_C_nn = loadDoubleArray();
-        L3_dSYRK_o_N = loadDoubleArray();
-        L3_dSYRK_A_kn = loadDoubleArray();
-        L3_dSYRK_o_T = loadDoubleArray();
-
-        L3_cSYRK_A_nk = loadFloatArray();
-        L3_cSYRK_C_nn = loadFloatArray();
-        L3_cSYRK_o_N = loadFloatArray();
-        L3_cSYRK_A_kn = loadFloatArray();
-        L3_cSYRK_o_T = loadFloatArray();
-
-        L3_zSYRK_A_nk = loadDoubleArray();
-        L3_zSYRK_C_nn = loadDoubleArray();
-        L3_zSYRK_o_N = loadDoubleArray();
-        L3_zSYRK_A_kn = loadDoubleArray();
-        L3_zSYRK_o_T = loadDoubleArray();
-    }
-
-    private void loadHERKData() throws Exception {
-        L3_cHERK_A_nk = loadFloatArray();
-        L3_cHERK_C_nn = loadFloatArray();
-        L3_cHERK_o_N = loadFloatArray();
-        L3_cHERK_A_kn = loadFloatArray();
-        L3_cHERK_o_H = loadFloatArray();
-
-        L3_zHERK_A_nk = loadDoubleArray();
-        L3_zHERK_C_nn = loadDoubleArray();
-        L3_zHERK_o_N = loadDoubleArray();
-        L3_zHERK_A_kn = loadDoubleArray();
-        L3_zHERK_o_H = loadDoubleArray();
-    }
-
-    private void loadSYR2KData() throws Exception {
-        L3_sSYR2K_A_nk = loadFloatArray();
-        L3_sSYR2K_B_nk = loadFloatArray();
-        L3_sSYR2K_C_nn = loadFloatArray();
-        L3_sSYR2K_o_N = loadFloatArray();
-        L3_sSYR2K_A_kn = loadFloatArray();
-        L3_sSYR2K_B_kn = loadFloatArray();
-        L3_sSYR2K_o_T = loadFloatArray();
-
-        L3_dSYR2K_A_nk = loadDoubleArray();
-        L3_dSYR2K_B_nk = loadDoubleArray();
-        L3_dSYR2K_C_nn = loadDoubleArray();
-        L3_dSYR2K_o_N = loadDoubleArray();
-        L3_dSYR2K_A_kn = loadDoubleArray();
-        L3_dSYR2K_B_kn = loadDoubleArray();
-        L3_dSYR2K_o_T = loadDoubleArray();
-
-        L3_cSYR2K_A_nk = loadFloatArray();
-        L3_cSYR2K_B_nk = loadFloatArray();
-        L3_cSYR2K_C_nn = loadFloatArray();
-        L3_cSYR2K_o_N = loadFloatArray();
-        L3_cSYR2K_A_kn = loadFloatArray();
-        L3_cSYR2K_B_kn = loadFloatArray();
-        L3_cSYR2K_o_T = loadFloatArray();
-
-        L3_zSYR2K_A_nk = loadDoubleArray();
-        L3_zSYR2K_B_nk = loadDoubleArray();
-        L3_zSYR2K_C_nn = loadDoubleArray();
-        L3_zSYR2K_o_N = loadDoubleArray();
-        L3_zSYR2K_A_kn = loadDoubleArray();
-        L3_zSYR2K_B_kn = loadDoubleArray();
-        L3_zSYR2K_o_T = loadDoubleArray();
-    }
-
-    private void loadHER2KData() throws Exception {
-        L3_cHER2K_A_nk = loadFloatArray();
-        L3_cHER2K_B_nk = loadFloatArray();
-        L3_cHER2K_C_nn = loadFloatArray();
-        L3_cHER2K_o_N = loadFloatArray();
-        L3_cHER2K_A_kn = loadFloatArray();
-        L3_cHER2K_B_kn = loadFloatArray();
-        L3_cHER2K_o_H = loadFloatArray();
-
-        L3_zHER2K_A_nk = loadDoubleArray();
-        L3_zHER2K_B_nk = loadDoubleArray();
-        L3_zHER2K_C_nn = loadDoubleArray();
-        L3_zHER2K_o_N = loadDoubleArray();
-        L3_zHER2K_A_kn = loadDoubleArray();
-        L3_zHER2K_B_kn = loadDoubleArray();
-        L3_zHER2K_o_H = loadDoubleArray();
-    }
-
-    private void loadTRMMData() throws Exception {
-        L3_sTRMM_A_mm = loadFloatArray();
-        L3_sTRMM_B_mn = loadFloatArray();
-        L3_sTRMM_o_LUN = loadFloatArray();
-        L3_sTRMM_A_nn = loadFloatArray();
-        L3_sTRMM_o_RLT = loadFloatArray();
-
-        L3_dTRMM_A_mm = loadDoubleArray();
-        L3_dTRMM_B_mn = loadDoubleArray();
-        L3_dTRMM_o_LUN = loadDoubleArray();
-        L3_dTRMM_A_nn = loadDoubleArray();
-        L3_dTRMM_o_RLT = loadDoubleArray();
-
-        L3_cTRMM_A_mm = loadFloatArray();
-        L3_cTRMM_B_mn = loadFloatArray();
-        L3_cTRMM_o_LUN = loadFloatArray();
-        L3_cTRMM_A_nn = loadFloatArray();
-        L3_cTRMM_o_RLT = loadFloatArray();
-
-        L3_zTRMM_A_mm = loadDoubleArray();
-        L3_zTRMM_B_mn = loadDoubleArray();
-        L3_zTRMM_o_LUN = loadDoubleArray();
-        L3_zTRMM_A_nn = loadDoubleArray();
-        L3_zTRMM_o_RLT = loadDoubleArray();
-    }
-
-    private void loadTRSMData() throws Exception {
-        L3_sTRSM_A_mm = loadFloatArray();
-        L3_sTRSM_B_mn = loadFloatArray();
-        L3_sTRSM_o_LUN = loadFloatArray();
-        L3_sTRSM_A_nn = loadFloatArray();
-        L3_sTRSM_o_RLT = loadFloatArray();
-
-        L3_dTRSM_A_mm = loadDoubleArray();
-        L3_dTRSM_B_mn = loadDoubleArray();
-        L3_dTRSM_o_LUN = loadDoubleArray();
-        L3_dTRSM_A_nn = loadDoubleArray();
-        L3_dTRSM_o_RLT = loadDoubleArray();
-
-        L3_cTRSM_A_mm = loadFloatArray();
-        L3_cTRSM_B_mn = loadFloatArray();
-        L3_cTRSM_o_LUN = loadFloatArray();
-        L3_cTRSM_A_nn = loadFloatArray();
-        L3_cTRSM_o_RLT = loadFloatArray();
-
-        L3_zTRSM_A_mm = loadDoubleArray();
-        L3_zTRSM_B_mn = loadDoubleArray();
-        L3_zTRSM_o_LUN = loadDoubleArray();
-        L3_zTRSM_A_nn = loadDoubleArray();
-        L3_zTRSM_o_RLT = loadDoubleArray();
-    }
-
-    void loadData(Context ctx) throws Exception {
-        InputStream is = ctx.getAssets().open("BLASData.txt");
-        mBufReader = new BufferedReader(new InputStreamReader(is));
-
-        //Load data sequentially
-        loadMNK();
-        loadGEMVData();
-        loadGBMVData();
-        loadHEMVData();
-        loadHBMVData();
-        loadSYMVData();
-        loadSBMVData();
-        loadTRMVData();
-        loadTBMVData();
-        loadTRSVData();
-        loadTBSVData();
-        loadGERData();
-        loadGERUData();
-        loadGERCData();
-        loadHERData();
-        loadHER2Data();
-        loadSYRData();
-        loadSYR2Data();
-        loadGEMMData();
-        loadSYMMData();
-        loadHEMMData();
-        loadSYRKData();
-        loadHERKData();
-        loadSYR2KData();
-        loadHER2KData();
-        loadTRMMData();
-        loadTRSMData();
-    }
-
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/BNNMTest.java b/tests/tests/renderscript/src/android/renderscript/cts/BNNMTest.java
deleted file mode 100644
index 1822f6a..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/BNNMTest.java
+++ /dev/null
@@ -1,500 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.renderscript.cts;
-
-import android.renderscript.*;
-import android.util.Log;
-import java.util.Random;
-import java.lang.Math;
-
-public class BNNMTest extends RSBaseCompute {
-
-    static {
-        System.loadLibrary("bnnmdata_jni");
-    }
-
-    native void getData(byte[] a, byte[] b, byte[] c);
-
-    // In Java, the eight-bit 'byte' type is signed, but the API for the 8-bit
-    // matrix multiplication deals with unsigned bytes. This is a convenience
-    // function that converts arrays of unsigned ints to their equivalent
-    // representations as signed bytes. For example, the bit pattern 0xff is 255
-    // as an unsigned value, but -127 as a Java signed byte. So if you pass in an
-    // array of int[] {255} into this function, you'll get back byte[] {-127}.
-    private byte[] unsignedToSignedByte(int[] input) {
-        byte[] output = new byte[input.length];
-        for (int i = 0; i < input.length; ++i) {
-            output[i] = (byte)(input[i]);
-        }
-        return output;
-    }
-
-    private void addByteNoise(byte[] data, int count, float frequency, int maxDelta) {
-        Random rand = new Random();
-        for (int n = 0; n < count; ++n) {
-            if (rand.nextFloat() < frequency) {
-                final int originalValue = data[n];
-                final float direction = rand.nextFloat();
-                int delta = (int)(Math.ceil(rand.nextFloat() * maxDelta));
-                if (direction < 0.5f) {
-                    delta = -delta;
-                }
-                int newValue = (originalValue + delta);
-                if (newValue < -127) {
-                    newValue = -127;
-                }
-                if (newValue > 127) {
-                    newValue = 127;
-                }
-                data[n] = (byte)(newValue);
-            }
-        }
-    }
-
-    private boolean testWithTolerance(byte[] c_byte, byte[] c_byte_output) {
-
-        // The testing procedure here is a bit complex, but the aim is to mimic the
-        // requirements we've empirically found running deep neural networks in real
-        // applications. We want to open the door to vendors using approximations that
-        // produce slightly different results for optimization's sake, but keep the
-        // precision loss within small enough bounds that we don't lose accuracy in
-        // the final result.
-        // After experimentation, we've found that we can tolerate around 5% of the
-        // output bytes being different by 1. Any larger differences are not tolerable
-        // and we can't get good results if the frequency of small differences is
-        // higher than 5%. This test tries to measure those properties on an example
-        // set of parameters that were captured from a real application.
-        // For example, if you uncommented this function that adds random noise to the
-        // results at a 3% specified frequency, the test should fail:
-        // AddByteNoise(c_byte_output, c_count, 0.03f, 1);
-
-        final boolean areSizesDifferent = (c_byte.length != c_byte_output.length);
-        final int c_count = Math.min(c_byte.length, c_byte_output.length);
-
-        int howManyDifferent = 0;
-        boolean areAnyTooDifferent = false;
-        for (int i = 0; i < c_count; i++) {
-            byte expectedValue = c_byte[i];
-            byte actualValue = c_byte_output[i];
-            int delta = (expectedValue - actualValue);
-            // First make sure that the difference is no more than one.
-            if ((delta < -1) || (delta > 1)) {
-                areAnyTooDifferent = true;
-            }
-            // If there is a difference, increment the counter to track it.
-            if (delta != 0) {
-                // Don't spam the logs if too many are different.
-                if (howManyDifferent < 50) {
-                    android.util.Log.e("BNNM", "Mismatch at " + i +
-                                       ": expected " + (expectedValue & 0xff) +
-                                       ", got " + (actualValue & 0xff));
-                }
-                ++howManyDifferent;
-            }
-        }
-        // We want no more than 2% of the values to show any differences, so work out
-        // what that means in absolute numbers.
-        final int percentThreshold = 2;
-        final int differenceThreshold = Math.max((percentThreshold * c_count) / 100, 1);
-        final boolean areTooManyDifferent = (howManyDifferent >= differenceThreshold);
-
-        if (areAnyTooDifferent) {
-            android.util.Log.e("BNNM", "Some outputs were too different.");
-        }
-
-        if (areTooManyDifferent) {
-            android.util.Log.e("BNNM", "There were too many small differences." +
-                               " We can tolerate " + percentThreshold + "% (" +
-                               differenceThreshold + "), but there were " + howManyDifferent);
-        }
-
-        return !(areAnyTooDifferent || areTooManyDifferent);
-    }
-
-
-    private byte[] runBNNM(int m, int n, int k, byte[] a_byte, int a_offset, byte[] b_byte,
-                           int b_offset, int c_offset, int c_mult_int) {
-        Allocation A, B, C;
-        Type.Builder builder = new Type.Builder(mRS, Element.U8(mRS));
-        Type a_type = builder.setX(k).setY(m).create();
-        Type b_type = builder.setX(k).setY(n).create();
-        Type c_type = builder.setX(n).setY(m).create();
-
-        A = Allocation.createTyped(mRS, a_type);
-        B = Allocation.createTyped(mRS, b_type);
-        C = Allocation.createTyped(mRS, c_type);
-
-        A.copyFrom(a_byte);
-        B.copyFrom(b_byte);
-        // C doesn't matter, is output only
-
-        ScriptIntrinsicBLAS blas = ScriptIntrinsicBLAS.create(mRS);
-        blas.BNNM(A, a_offset, B, b_offset, C, c_offset, c_mult_int);
-
-        int c_count = (m * n);
-        byte[] c_byte_output = new byte[c_count];
-        C.copyTo(c_byte_output);
-        return c_byte_output;
-    }
-
-
-
-    // This test multiplies a couple of small 8-bit matrices, and compares the
-    // results with hand-calculated expectations.
-    public void testSmallMatrices() {
-        // The A matrix is:
-        // |   1 |   4 |
-        // |   2 |   5 |
-        // |   3 |   6 |
-        byte[] a_data = unsignedToSignedByte(new int[] {
-                1, 2, 3,
-                4, 5, 6,
-            });
-        final int a_rows = 3;
-        final int a_cols = 2;
-        final int a_offset = 0;
-        // The B matrix is:
-        // |  -1 |  -2 |  -3 |  -4 |
-        // |  -5 |  -6 |  -7 |  -8 |
-        // |  -9 | -10 | -11 | -12 |
-        byte[] b_data = unsignedToSignedByte(new int[] {
-                11, 7, 3,
-                10, 6, 2,
-                9, 5, 1,
-                8, 4, 0,
-            });
-        final int b_cols = 4;
-        final int b_offset = 12;
-        // EightBitGemm implements C = B.transposed() * A,
-        // so we expect to get these results:
-        // 1*-1 + 2*-5 + 3*-9 + 128 = 90
-        // 1*-2 + 2*-6 + 3*-10 + 128 = 84
-        // 1*-3 + 2*-7 + 3*-11 + 128 = 78
-        // 1*-4 + 2*-8 + 3*-12 + 128 = 72
-        // 4*-1 + 5*-5 + 6*-9 + 128 = 45
-        // 4*-2 + 5*-6 + 6*-10 + 128 = 30
-        // 4*-3 + 5*-7 + 6*-11 + 128 = 15
-        // 4*-4 + 5*-8 + 6*-12 + 128 = 0
-        // | 90 |  45 |
-        // | 84 |  30 |
-        // | 78 | 15 |
-        // | 72 | 0 |
-        final int c_offset = 128;
-        final int c_shift = 21;
-        final int c_mult_int = (1 << c_shift);
-        byte[] expected_data = unsignedToSignedByte(new int[] {
-                90, 84, 78, 72,
-                45, 30, 15, 0,
-            });
-
-        final int m = a_cols;
-        final int n = b_cols;
-        final int k = a_rows;
-
-        byte[] c_byte_output = runBNNM(m, n, k, a_data, a_offset, b_data, b_offset,
-                                       c_offset, c_mult_int);
-        assertTrue(testWithTolerance(expected_data, c_byte_output));
-    }
-
-
-    // This test multiplies two medium-sized 8-bit matrices, and compares the
-    // results with the expected values. The data itself is fairly arbitrary.
-    public void testMediumMatrices1() {
-        byte[] a_data = unsignedToSignedByte(new int[] {
-                1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
-                12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
-                23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
-                0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
-                23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
-            });
-        final int a_rows = 11;
-        final int a_cols = 5;
-        final int a_offset = 0;
-        byte[] b_data = unsignedToSignedByte(new int[] {
-                0, 2, 4, 6, 8, 10, 1, 3, 5, 7, 9, 11,
-                10, 12, 14, 16, 18, 20, 11, 13, 15, 17, 19, 21,
-                20, 22, 24, 26, 28, 30, 21, 23, 25, 27, 29, 31,
-                30, 32, 34, 36, 38, 40, 31, 33, 35, 37, 39, 41,
-                40, 42, 44, 46, 48, 50, 41, 43, 45, 47, 49, 51,
-                50, 52, 54, 56, 58, 60, 51, 53, 55, 57, 59, 61,
-                60, 62, 64, 66, 68, 70, 61, 63, 65, 67, 69, 71,
-            });
-        final int b_cols = 7;
-        final int b_offset = 10;
-        final int c_offset = 16384;
-        final int c_shift = 21;
-        final int c_mult_int = (1 << (c_shift - 7));
-        byte[] expected_data = unsignedToSignedByte(new int[] {
-                126, 131, 135, 140, 146, 151, 155,
-                121, 135, 148, 162, 176, 190, 202,
-                116, 139, 161, 184, 206, 229, 249,
-                128, 128, 129, 129, 129, 130, 130,
-                118, 136, 155, 173, 191, 210, 226,
-            });
-
-        final int m = a_cols;
-        final int n = b_cols;
-        final int k = a_rows;
-
-        byte[] c_byte_output = runBNNM(m, n, k, a_data, a_offset, b_data, b_offset,
-                                       c_offset, c_mult_int);
-        assertTrue(testWithTolerance(expected_data, c_byte_output));
-    }
-
-    // This test multiplies another two medium 8-bit matrices, and compares the
-    // results with the expected values. The data here is arbitrary.
-    public void testMediumMatrices2() {
-        byte[] a_data = unsignedToSignedByte(new int[] {
-                1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
-                23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1,
-                1, 23, 2, 22, 3, 21, 4, 20, 5, 19, 6, 18, 7, 17, 8, 16, 9, 15, 10, 14, 11, 13, 12,
-                23, 1, 22, 2, 21, 3, 20, 4, 19, 5, 18, 6, 17, 7, 16, 8, 15, 9, 14, 10, 13, 11, 12,
-                1, 1, 1, 1, 1, 1, 1, 1, 1, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-                3, 1, 4, 1, 5, 8, 2, 3, 1, 14, 11, 15, 18, 12, 13, 11, 14, 11, 15, 18, 12, 13, 11,
-                8, 0, 5, 8, 1, 3, 7, 5, 7, 13, 10, 23, 13, 11, 17, 23, 12, 19, 17, 13, 14, 10, 19,
-            });
-        final int a_rows = 23;
-        final int a_cols = 7;
-        final int a_offset = 13;
-        byte[] b_data = unsignedToSignedByte(new int[] {
-                0, 2, 4, 6, 8, 10, 1, 3, 5, 7, 9, 11, 0, 2, 4, 6, 8, 10, 1, 3, 5, 7, 9,
-                0, 20, 40, 60, 80, 10, 11, 13, 15, 17, 19, 21, 10, 12, 14, 6, 8, 10, 1, 3, 5, 7, 9,
-                1, 21, 41, 61, 81, 11, 12, 14, 16, 18, 20, 22, 11, 13, 15, 7, 9, 11, 2, 4, 6, 8, 9,
-                0, 19, 39, 59, 79, 9, 10, 12, 14, 16, 18, 20, 9, 11, 13, 5, 7, 9, 0, 2, 4, 6, 8,
-                2, 22, 42, 62, 82, 12, 13, 15, 17, 19, 21, 23, 12, 14, 16, 8, 9, 12, 3, 5, 7, 9, 9,
-                0, 18, 38, 58, 78, 8, 9, 11, 13, 15, 17, 19, 8, 10, 12, 4, 6, 8, 0, 1, 3, 5, 7,
-                3, 23, 43, 63, 83, 13, 14, 16, 18, 20, 22, 24, 13, 15, 17, 9, 9, 13, 4, 6, 8, 9, 9,
-                0, 17, 37, 57, 77, 7, 8, 10, 12, 14, 16, 18, 7, 9, 11, 3, 5, 7, 0, 0, 2, 4, 6,
-                10, 20, 30, 40, 50, 1, 2, 3, 4, 5, 11, 12, 13, 14, 15, 21, 22, 23, 24, 25, 1, 2, 3,
-            });
-        final int b_cols = 9;
-        final int b_offset = 23;
-        final int c_offset = 2121;
-        final int c_shift = 21;
-        final int c_mult_int = 132359;
-        byte[] expected_data = unsignedToSignedByte(new int[] {
-                167, 53, 51, 54, 49, 55, 46,
-                56, 116, 153, 232, 232, 234, 231,
-                236, 232, 237, 174, 168, 131, 130,
-                132, 129, 133, 128, 133, 134, 151,
-                154, 152, 156, 151, 158, 150, 160,
-                156, 255, 113, 106, 120, 98, 127,
-                91, 134, 178, 231, 102, 97, 107,
-                92, 111, 87, 116, 164, 187, 76,
-                73, 78, 70, 81, 67, 83, 139,
-            });
-
-        final int m = a_cols;
-        final int n = b_cols;
-        final int k = a_rows;
-
-        byte[] c_byte_output = runBNNM(m, n, k, a_data, a_offset, b_data, b_offset,
-                                       c_offset, c_mult_int);
-        assertTrue(testWithTolerance(expected_data, c_byte_output));
-    }
-
-
-    // This test takes a large set of real data captured from a convolutional
-    // neural network solving a computer vision problem, and runs it through the
-    // eight-bit matrix multiply. We test the results to make sure they're close
-    // enough to be usable.
-    public void testRealData() {
-
-        int m = 256;
-        int n = 192;
-        int k = 1152;
-        int a_offset = 0;
-        int b_offset = 84;
-        int c_mult_int = 3401;
-        int c_offset = 74980;
-
-        int a_count = (m * k);
-        int b_count = (n * k);
-        int c_count = (m * n);
-
-        byte[] a_byte = new byte[a_count];
-        byte[] b_byte = new byte[b_count];
-        byte[] c_byte = new byte[c_count];
-
-        getData(a_byte, b_byte, c_byte);
-
-        byte[] c_byte_output = runBNNM(m, n, k, a_byte, a_offset, b_byte, b_offset,
-                                       c_offset, c_mult_int);
-
-        assertTrue(testWithTolerance(c_byte, c_byte_output));
-
-    }
-
-    // This test multiplies matrices where the results are expected to fall
-    // slightly outside the 0 to 255 valid output range. This test ensures the
-    // values get clamped to that range, rather than wrapping around.
-    public void testClamping() {
-        // The A matrix is:
-        // |   1 |   4 |
-        // |   2 |   5 |
-        // |   3 |   6 |
-        byte[] a_data = unsignedToSignedByte(new int[] {
-                1, 2, 3,
-                4, 5, 6,
-            });
-        final int a_rows = 3;
-        final int a_cols = 2;
-        final int a_offset = 0;
-        // The B matrix is:
-        // |  -1 |  -2 |  -3 |  -4 |
-        // |  -5 |  -6 |  -7 |  -8 |
-        // |  99 | -40 | -11 | -15 |
-        byte[] b_data = unsignedToSignedByte(new int[] {
-                126, 122, 226,
-                125, 121, 87,
-                124, 120, 116,
-                123, 119, 112,
-            });
-        final int b_cols = 4;
-        final int b_offset = 127;
-        // EightBitGemm implements C = B.transposed() * A,
-        // so we expect to get these results:
-        // 1*-1 + 2*-5 + 3* 99 + 128 = 414 (clamped to 255)
-        // 1*-2 + 2*-6 + 3*-40 + 128 = -6 (clamped to 0)
-        // 1*-3 + 2*-7 + 3*-11 + 128 = 78
-        // 1*-4 + 2*-8 + 3*-15 + 128 = 63
-        // 4*-1 + 5*-5 + 6* 99 + 128 = 693 (clamped to 255)
-        // 4*-2 + 5*-6 + 6*-40 + 128 = -150 (clamped to 0)
-        // 4*-3 + 5*-7 + 6*-11 + 128 = 15
-        // 4*-4 + 5*-8 + 6*-15 + 128 = -18 (clamped to 0)
-        // | 255 | 255 |
-        // |   0 |   0 |
-        // |  78 |  15 |
-        // |  63 |   0 |
-        final int c_offset = 128;
-        final int c_shift = 21;
-        final int c_mult_int = (1 << c_shift);
-        byte[] expected_data = unsignedToSignedByte(new int[] {
-              255, 0, 78, 63,
-              255, 0, 15, 0,
-            });
-
-        final int m = a_cols;
-        final int n = b_cols;
-        final int k = a_rows;
-
-        byte[] c_byte_output = runBNNM(m, n, k, a_data, a_offset, b_data, b_offset,
-                                       c_offset, c_mult_int);
-        assertTrue(testWithTolerance(expected_data, c_byte_output));
-    }
-
-    // This tests the exception handling for a_offset and b_offset.
-    public void testExceptionHandling() {
-        // The A matrix is:
-        // |   1 |   4 |
-        // |   2 |   5 |
-        // |   3 |   6 |
-        byte[] a_data = unsignedToSignedByte(new int[] {
-                1, 2, 3,
-                4, 5, 6,
-            });
-        final int a_rows = 3;
-        final int a_cols = 2;
-        // The B matrix is:
-        // |  -1 |  -2 |  -3 |  -4 |
-        // |  -5 |  -6 |  -7 |  -8 |
-        // |  -9 | -10 | -11 | -12 |
-        byte[] b_data = unsignedToSignedByte(new int[] {
-                11, 7, 3,
-                10, 6, 2,
-                9, 5, 1,
-                8, 4, 0,
-            });
-        final int b_cols = 4;
-        // EightBitGemm implements C = B.transposed() * A,
-        // so we expect to get these results:
-        // 1*-1 + 2*-5 + 3*-9 + 128 = 90
-        // 1*-2 + 2*-6 + 3*-10 + 128 = 84
-        // 1*-3 + 2*-7 + 3*-11 + 128 = 78
-        // 1*-4 + 2*-8 + 3*-12 + 128 = 72
-        // 4*-1 + 5*-5 + 6*-9 + 128 = 45
-        // 4*-2 + 5*-6 + 6*-10 + 128 = 30
-        // 4*-3 + 5*-7 + 6*-11 + 128 = 15
-        // 4*-4 + 5*-8 + 6*-12 + 128 = 0
-        // | 90 |  45 |
-        // | 84 |  30 |
-        // | 78 | 15 |
-        // | 72 | 0 |
-        final int c_offset = 128;
-        final int c_shift = 21;
-        final int c_mult_int = (1 << c_shift);
-        byte[] expected_data = unsignedToSignedByte(new int[] {
-                90, 84, 78, 72,
-                45, 30, 15, 0,
-            });
-
-        final int m = a_cols;
-        final int n = b_cols;
-        final int k = a_rows;
-
-        Allocation A, B, C;
-        Type.Builder builder = new Type.Builder(mRS, Element.U8(mRS));
-        Type a_type = builder.setX(k).setY(m).create();
-        Type b_type = builder.setX(k).setY(n).create();
-        Type c_type = builder.setX(n).setY(m).create();
-
-        A = Allocation.createTyped(mRS, a_type);
-        B = Allocation.createTyped(mRS, b_type);
-        C = Allocation.createTyped(mRS, c_type);
-
-        A.copyFrom(a_data);
-        B.copyFrom(b_data);
-        // C doesn't matter, is output only
-
-        ScriptIntrinsicBLAS blas = ScriptIntrinsicBLAS.create(mRS);
-        try {
-            int a_offset = 0;
-            int b_offset = 12;
-            blas.BNNM(A, a_offset, B, b_offset, C, c_offset, c_mult_int);
-        } catch (RSRuntimeException e) {
-            fail("should NOT throw RSRuntimeException for valid offsets");
-        }
-        try {
-            int a_offset = -23;
-            int b_offset = 12;
-            blas.BNNM(A, a_offset, B, b_offset, C, c_offset, c_mult_int);
-            fail("should throw RSRuntimeException for invalid offsets: a_offset < 0");
-        } catch (RSRuntimeException e) {
-        }
-        try {
-            int a_offset = 888;
-            int b_offset = 12;
-            blas.BNNM(A, a_offset, B, b_offset, C, c_offset, c_mult_int);
-            fail("should throw RSRuntimeException for invalid offsets: a_offset > 255");
-        } catch (RSRuntimeException e) {
-        }
-        try {
-            int a_offset = 0;
-            int b_offset = -1;
-            blas.BNNM(A, a_offset, B, b_offset, C, c_offset, c_mult_int);
-            fail("should throw RSRuntimeException for invalid offsets: b_offset < 0");
-        } catch (RSRuntimeException e) {
-        }
-        try {
-            int a_offset = 0;
-            int b_offset = 256;
-            blas.BNNM(A, a_offset, B, b_offset, C, c_offset, c_mult_int);
-            fail("should throw RSRuntimeException for invalid offsets: b_offset > 255");
-        } catch (RSRuntimeException e) {
-        }
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/CoreMathVerifier.java b/tests/tests/renderscript/src/android/renderscript/cts/CoreMathVerifier.java
index 686281c..bc13144 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/CoreMathVerifier.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/CoreMathVerifier.java
@@ -221,14 +221,31 @@
     static native float  convertDoubleToFloat(double x);
     static native double convertDoubleToDouble(double x);
 
+    static private Target.Floaty pi(Target t) {
+        return t.newFloaty(Math.PI);
+    }
+
     static private Target.Floaty pi32(Target t) {
         return t.new32((float) Math.PI);
     }
 
+    static private Target.Floaty any(Target t) {
+        return t.newFloaty(Double.NEGATIVE_INFINITY, Double.NaN, Double.POSITIVE_INFINITY);
+    }
+
     static private Target.Floaty any32(Target t) {
         return t.new32(Float.NEGATIVE_INFINITY, Float.NaN, Float.POSITIVE_INFINITY);
     }
 
+    static private Target.Floaty acos(double d, Target t) {
+        Target.Floaty in = t.newFloaty(d);
+        return t.newFloaty(
+            Math.acos(in.mid()),
+            Math.acos(in.min()),
+            Math.acos(in.max()));
+    }
+
+    // TODO Remove this function and similar variants that take a float parameter instead of double.
     static private Target.Floaty acos(float f, Target t) {
         Target.Floaty in = t.new32(f);
         return t.new32(
@@ -237,6 +254,16 @@
             acos(in.max32()));
     }
 
+    // NOTE: This function delegates to the floating-point version in libm.  Need to switch to the
+    // double-precision version later.
+    static private Target.Floaty acosh(double d, Target t) {
+        Target.Floaty in = t.newFloaty(d);
+        return t.newFloaty(
+            acosh((float) in.mid()),
+            acosh((float) in.min()),
+            acosh((float) in.max()));
+    }
+
     static private Target.Floaty acosh(float f, Target t) {
         Target.Floaty in = t.new32(f);
         return t.new32(
@@ -245,10 +272,22 @@
             acosh(in.max32()));
     }
 
+    static private Target.Floaty acospi(double d, Target t) {
+        return t.divide(acos(d, t), pi(t));
+    }
+
     static private Target.Floaty acospi(float f, Target t) {
         return t.divide(acos(f, t), pi32(t));
     }
 
+    static private Target.Floaty asin(double d, Target t) {
+        Target.Floaty in = t.newFloaty(d);
+        return t.newFloaty(
+            Math.asin(in.mid()),
+            Math.asin(in.min()),
+            Math.asin(in.max()));
+    }
+
     static private Target.Floaty asin(float f, Target t) {
         Target.Floaty in = t.new32(f);
         return t.new32(
@@ -257,6 +296,16 @@
             asin(in.max32()));
     }
 
+    // NOTE: This function delegates to the floating-point version in libm.  Need to switch to the
+    // double-precision version later.
+    static private Target.Floaty asinh(double d, Target t) {
+        Target.Floaty in = t.newFloaty(d);
+        return t.newFloaty(
+            asinh((float) in.mid()),
+            asinh((float) in.min()),
+            asinh((float) in.max()));
+    }
+
     static private Target.Floaty asinh(float f, Target t) {
         Target.Floaty in = t.new32(f);
         return t.new32(
@@ -265,10 +314,22 @@
             asinh(in.max32()));
     }
 
+    static private Target.Floaty asinpi(double d, Target t) {
+        return t.divide(asin(d, t), pi(t));
+    }
+
     static private Target.Floaty asinpi(float f, Target t) {
         return t.divide(asin(f, t), pi32(t));
     }
 
+    static private Target.Floaty atan(double d, Target t) {
+        Target.Floaty in = t.newFloaty(d);
+        return t.newFloaty(
+            Math.atan(in.mid()),
+            Math.atan(in.min()),
+            Math.atan(in.max()));
+    }
+
     static private Target.Floaty atan(float f, Target t) {
         Target.Floaty in = t.new32(f);
         return t.new32(
@@ -277,6 +338,16 @@
             atan(in.max32()));
     }
 
+    // NOTE: This function delegates to the floating-point version in libm.  Need to switch to the
+    // double-precision version later.
+    static private Target.Floaty atanh(double d, Target t) {
+        Target.Floaty in = t.newFloaty(d);
+        return t.newFloaty(
+            atanh((float) in.mid()),
+            atanh((float) in.min()),
+            atanh((float) in.max()));
+    }
+
     static private Target.Floaty atanh(float f, Target t) {
         Target.Floaty in = t.new32(f);
         return t.new32(
@@ -285,10 +356,25 @@
             atanh(in.max32()));
     }
 
+    static private Target.Floaty atanpi(double d, Target t) {
+        return t.divide(atan(d, t), pi(t));
+    }
+
     static private Target.Floaty atanpi(float f, Target t) {
         return t.divide(atan(f, t), pi32(t));
     }
 
+    static private Target.Floaty atan2(double y, double x, Target t) {
+        Target.Floaty numerator = t.newFloaty(y);
+        Target.Floaty denominator = t.newFloaty(x);
+        return t.newFloaty(
+            Math.atan2(numerator.mid(), denominator.mid()),
+            Math.atan2(numerator.min(), denominator.min()),
+            Math.atan2(numerator.min(), denominator.max()),
+            Math.atan2(numerator.max(), denominator.min()),
+            Math.atan2(numerator.max(), denominator.max()));
+    }
+
     static private Target.Floaty atan2(float y, float x, Target t) {
         Target.Floaty numerator = t.new32(y);
         Target.Floaty denominator = t.new32(x);
@@ -300,10 +386,22 @@
             atan2(numerator.max32(), denominator.max32()));
     }
 
+    static private Target.Floaty atan2pi(double y, double x, Target t) {
+        return t.divide(atan2(y, x, t), pi(t));
+    }
+
     static private Target.Floaty atan2pi(float y, float x, Target t) {
         return t.divide(atan2(y, x, t), pi32(t));
     }
 
+    static private Target.Floaty cbrt(double d, Target t) {
+        Target.Floaty in = t.newFloaty(d);
+        return t.newFloaty(
+            Math.cbrt(in.mid()),
+            Math.cbrt(in.min()),
+            Math.cbrt(in.max()));
+    }
+
     static private Target.Floaty cbrt(float f, Target t) {
         Target.Floaty in = t.new32(f);
         return t.new32(
@@ -312,6 +410,22 @@
             cbrt(in.max32()));
     }
 
+    static private Target.Floaty clamp(double value, double minValue, double maxValue, Target t) {
+        return t.newFloaty(Math.min(maxValue, Math.max(minValue, value)));
+    }
+
+    static private Target.Floaty copysign(double magnitude, double sign, Target t) {
+        return t.newFloaty(Math.copySign(magnitude, sign));
+    }
+
+    static private Target.Floaty cos(double d, Target t) {
+        Target.Floaty in = t.newFloaty(d);
+        return t.newFloaty(
+            Math.cos(in.mid()),
+            Math.cos(in.min()),
+            Math.cos(in.max()));
+    }
+
     static private Target.Floaty cos(float f, Target t) {
         Target.Floaty in = t.new32(f);
         return t.new32(
@@ -320,6 +434,14 @@
             cos(in.max32()));
     }
 
+    static private Target.Floaty cosh(double d, Target t) {
+        Target.Floaty in = t.newFloaty(d);
+        return t.newFloaty(
+            Math.cosh(in.mid()),
+            Math.cosh(in.min()),
+            Math.cosh(in.max()));
+    }
+
     static private Target.Floaty cosh(float f, Target t) {
         Target.Floaty in = t.new32(f);
         return t.new32(
@@ -328,6 +450,14 @@
             cosh(in.max32()));
     }
 
+    static private Target.Floaty cospi(double d, Target t) {
+        Target.Floaty in = t.multiply(t.newFloaty(d), pi(t));
+        return t.newFloaty(
+            Math.cos(in.mid()),
+            Math.cos(in.min()),
+            Math.cos(in.max()));
+    }
+
     static private Target.Floaty cospi(float f, Target t) {
         Target.Floaty in = t.multiply(t.new32(f), pi32(t));
         return t.new32(
@@ -336,6 +466,22 @@
             cos(in.max32()));
     }
 
+    // Computes the cross product of two double-precision 3D vectors.
+    static private void cross(double[] v1, double[] v2, Target.Floaty[] out, Target t) {
+        Target.Floaty a12 = t.multiply(t.newFloaty(v1[1]), t.newFloaty(v2[2]));
+        Target.Floaty a21 = t.multiply(t.newFloaty(v1[2]), t.newFloaty(v2[1]));
+        out[0] = t.subtract(a12, a21);
+        Target.Floaty a02 = t.multiply(t.newFloaty(v1[0]), t.newFloaty(v2[2]));
+        Target.Floaty a20 = t.multiply(t.newFloaty(v1[2]), t.newFloaty(v2[0]));
+        out[1] = t.subtract(a20, a02);
+        Target.Floaty a01 = t.multiply(t.newFloaty(v1[0]), t.newFloaty(v2[1]));
+        Target.Floaty a10 = t.multiply(t.newFloaty(v1[1]), t.newFloaty(v2[0]));
+        out[2] = t.subtract(a01, a10);
+        if (out.length == 4) {
+            out[3] = t.newFloaty(0.f);
+        }
+    }
+
     // Computes the cross product of two 3D vectors.
     static private void cross(float[] v1, float[] v2, Target.Floaty[] out, Target t) {
         Target.Floaty a12 = t.multiply(t.new32(v1[1]), t.new32(v2[2]));
@@ -352,6 +498,30 @@
         }
     }
 
+    static private Target.Floaty divide(double left, double right, Target t) {
+        Target.Floaty lFloaty = t.newFloaty(left);
+        Target.Floaty rFloaty = t.newFloaty(right);
+        return t.divide(lFloaty, rFloaty);
+    }
+
+    // Convert a double-precision radian value to degrees.
+    static private Target.Floaty degrees(double d, Target t) {
+        Target.Floaty in = t.newFloaty(d);
+        Target.Floaty k = t.newFloaty(180. / Math.PI);
+        return t.multiply(in, k);
+    }
+
+    // Returns the distance between two points (in double-precision) in n-dimensional space.
+    static private Target.Floaty distance(double[] point1, double[] point2, Target t) {
+        Target.Floaty sum = t.newFloaty(0.f);
+        for (int i = 0; i < point1.length; i++) {
+            Target.Floaty diff = t.subtract(t.newFloaty(point1[i]), t.newFloaty(point2[i]));
+            sum = t.add(sum, t.multiply(diff, diff));
+        }
+        Target.Floaty d = t.sqrt(sum);
+        return d;
+    }
+
     // Returns the distance between two points in n-dimensional space.
     static private Target.Floaty distance(float[] point1, float[] point2, Target t) {
         Target.Floaty sum = t.new32(0.f);
@@ -363,6 +533,36 @@
         return d;
     }
 
+    // Computes the error function for a double-precision input.
+    // NOTE: This function delegates to the floating-point version in libm.  Need to switch to the
+    // double-precision version later.
+    static private Target.Floaty erf(double d, Target t) {
+        Target.Floaty in = t.newFloaty(d);
+        return t.newFloaty(
+            erf((float) in.mid()),
+            erf((float) in.min()),
+            erf((float) in.max()));
+    }
+
+    // Computes the complementary error function for a double-precision input.
+    // NOTE: This function delegates to the floating-point version in libm.  Need to switch to the
+    // double-precision version later.
+    static private Target.Floaty erfc(double d, Target t) {
+        Target.Floaty in = t.newFloaty(d);
+        return t.newFloaty(
+            erfc((float) in.mid()),
+            erfc((float) in.min()),
+            erfc((float) in.max()));
+    }
+
+    static private Target.Floaty exp(double d, Target t) {
+        Target.Floaty in = t.newFloaty(d);
+        return t.newFloaty(
+            Math.exp(in.mid()),
+            Math.exp(in.min()),
+            Math.exp(in.max()));
+    }
+
     static private Target.Floaty exp(float f, Target t) {
         Target.Floaty in = t.new32(f);
         return t.new32(
@@ -371,6 +571,16 @@
             exp(in.max32()));
     }
 
+    // NOTE: This function delegates to the floating-point version in libm.  Need to switch to the
+    // double-precision version later.
+    static private Target.Floaty exp10(double d, Target t) {
+        Target.Floaty in = t.newFloaty(d);
+        return t.newFloaty(
+            exp10((float) in.mid()),
+            exp10((float) in.min()),
+            exp10((float) in.max()));
+    }
+
     static private Target.Floaty exp10(float f, Target t) {
         Target.Floaty in = t.new32(f);
         return t.new32(
@@ -379,6 +589,16 @@
             exp10(in.max32()));
     }
 
+    // NOTE: This function delegates to the floating-point version in libm.  Need to switch to the
+    // double-precision version later.
+    static private Target.Floaty exp2(double d, Target t) {
+        Target.Floaty in = t.newFloaty(d);
+        return t.newFloaty(
+            exp2((float) in.mid()),
+            exp2((float) in.min()),
+            exp2((float) in.max()));
+    }
+
     static private Target.Floaty exp2(float f, Target t) {
         Target.Floaty in = t.new32(f);
         return t.new32(
@@ -387,6 +607,14 @@
             exp2(in.max32()));
     }
 
+    static private Target.Floaty expm1(double d, Target t) {
+        Target.Floaty in = t.newFloaty(d);
+        return t.newFloaty(
+            Math.expm1(in.mid()),
+            Math.expm1(in.min()),
+            Math.expm1(in.max()));
+    }
+
     static private Target.Floaty expm1(float f, Target t) {
         Target.Floaty in = t.new32(f);
         return t.new32(
@@ -395,6 +623,78 @@
             expm1(in.max32()));
     }
 
+    static private Target.Floaty fabs(double d, Target t) {
+        Target.Floaty in = t.newFloaty(d);
+        return t.newFloaty(
+            Math.abs(in.mid()),
+            Math.abs(in.min()),
+            Math.abs(in.max()));
+    }
+
+    static private Target.Floaty fdim(double a, double b, Target t) {
+        Target.Floaty inA = t.newFloaty(a);
+        Target.Floaty inB = t.newFloaty(b);
+        Target.Floaty r = t.subtract(inA, inB);
+        return t.newFloaty(
+            Math.max(0., r.mid()),
+            Math.max(0., r.min()),
+            Math.max(0., r.max()));
+    }
+
+    static private Target.Floaty floor(double d, Target t) {
+        Target.Floaty in = t.newFloaty(d);
+        return t.newFloaty(
+                    Math.floor(in.mid()),
+                    Math.floor(in.min()),
+                    Math.floor(in.max()));
+    }
+
+    static private Target.Floaty fma(double m1, double m2, double offset, Target t) {
+        Target.Floaty inM1 = t.newFloaty(m1);
+        Target.Floaty inM2 = t.newFloaty(m2);
+        Target.Floaty inOffset = t.newFloaty(offset);
+
+        return t.add(t.multiply(inM1, inM2), inOffset);
+    }
+
+    static private Target.Floaty fmax(double a, double b, Target t) {
+        return t.newFloaty(Math.max(a, b));
+    }
+
+    static private Target.Floaty fmin(double a, double b, Target t) {
+        return t.newFloaty(Math.min(a, b));
+    }
+
+    static private Target.Floaty fmod(double numerator, double denominator, Target t) {
+        Target.Floaty inNumerator = t.newFloaty(numerator);
+        Target.Floaty inDenominator = t.newFloaty(denominator);
+        return t.newFloaty(
+            numerator % denominator,
+            inNumerator.min() % inDenominator.min(),
+            inNumerator.min() % inDenominator.max(),
+            inNumerator.max() % inDenominator.min(),
+            inNumerator.max() % inDenominator.max());
+    }
+
+    // Compute the fractional part of a double value and returns a result that is at most
+    // 'fractUpperBound'.
+    static private Target.Floaty fract(double d, Target t, double fractUpperBound) {
+        return t.newFloaty(Math.min(
+            d - Math.floor(d),
+            fractUpperBound));
+    }
+
+    static private Target.Floaty hypot(double x, double y, Target t) {
+        Target.Floaty inX = t.newFloaty(x);
+        Target.Floaty inY = t.newFloaty(y);
+        return t.newFloaty(
+            Math.hypot(inX.mid(), inY.mid()),
+            Math.hypot(inX.min(), inY.min()),
+            Math.hypot(inX.min(), inY.max()),
+            Math.hypot(inX.max(), inY.min()),
+            Math.hypot(inX.max(), inY.max()));
+    }
+
     static private Target.Floaty hypot(float x, float y, Target t) {
         Target.Floaty inX = t.new32(x);
         Target.Floaty inY = t.new32(y);
@@ -406,6 +706,16 @@
             hypot(inX.max32(), inY.max32()));
     }
 
+    // Returns the length of an n-dimensional vector (in double-precision).
+    static private Target.Floaty length(double[] array, Target t) {
+        Target.Floaty sum = t.newFloaty(0.);
+        for (int i = 0; i < array.length; i++) {
+            Target.Floaty f = t.newFloaty(array[i]);
+            sum = t.add(sum, t.multiply(f, f));
+        }
+        return t.sqrt(sum);
+    }
+
     // Returns the length of the n-dimensional vector.
     static private Target.Floaty length(float[] array, Target t) {
         Target.Floaty sum = t.new32(0.f);
@@ -417,6 +727,14 @@
         return l;
     }
 
+    static private Target.Floaty log(double d, Target t) {
+        Target.Floaty in = t.newFloaty(d);
+        return t.newFloaty(
+            Math.log(in.mid()),
+            Math.log(in.min()),
+            Math.log(in.max()));
+    }
+
     static private Target.Floaty log(float f, Target t) {
         Target.Floaty in = t.new32(f);
         return t.new32(
@@ -425,6 +743,14 @@
             log(in.max32()));
     }
 
+    static private Target.Floaty log10(double d, Target t) {
+        Target.Floaty in = t.newFloaty(d);
+        return t.newFloaty(
+            Math.log10(in.mid()),
+            Math.log10(in.min()),
+            Math.log10(in.max()));
+    }
+
     static private Target.Floaty log10(float f, Target t) {
         Target.Floaty in = t.new32(f);
         return t.new32(
@@ -433,6 +759,14 @@
             log10(in.max32()));
     }
 
+    static private Target.Floaty log1p(double d, Target t) {
+        Target.Floaty in = t.newFloaty(d);
+        return t.newFloaty(
+            Math.log1p(in.mid()),
+            Math.log1p(in.min()),
+            Math.log1p(in.max()));
+    }
+
     static private Target.Floaty log1p(float f, Target t) {
         Target.Floaty in = t.new32(f);
         return t.new32(
@@ -441,6 +775,16 @@
             log1p(in.max32()));
     }
 
+    // NOTE: This function delegates to the floating-point version in libm.  Need to switch to the
+    // double-precision version later.
+    static private Target.Floaty log2(double d, Target t) {
+        Target.Floaty in = t.newFloaty(d);
+        return t.newFloaty(
+            log2((float) in.mid()),
+            log2((float) in.min()),
+            log2((float) in.max()));
+    }
+
     static private Target.Floaty log2(float f, Target t) {
         Target.Floaty in = t.new32(f);
         return t.new32(
@@ -449,6 +793,50 @@
             log2(in.max32()));
     }
 
+    // NOTE: This function delegates to the floating-point version in libm.  Need to switch to the
+    // double-precision version later.
+    static private Target.Floaty logb(double d, Target t) {
+        Target.Floaty in = t.newFloaty(d);
+        return t.newFloaty(
+            logb((float) in.mid()),
+            logb((float) in.min()),
+            logb((float) in.max()));
+    }
+
+    static private Target.Floaty mad(double m1, double m2, double offset, Target t) {
+        Target.Floaty ab = t.multiply(t.newFloaty(m1), t.newFloaty(m2));
+        return t.add(ab, t.newFloaty(offset));
+    }
+
+    static private Target.Floaty max(double a, double b, Target t) {
+        return t.newFloaty(Math.max(a, b));
+    }
+
+    static private Target.Floaty min(double a, double b, Target t) {
+        return t.newFloaty(Math.min(a, b));
+    }
+
+    static private Target.Floaty mix(double start, double stop, double fraction, Target t) {
+        Target.Floaty inStart = t.newFloaty(start);
+        Target.Floaty inStop = t.newFloaty(stop);
+        Target.Floaty inFraction = t.newFloaty(fraction);
+
+        Target.Floaty diff = t.subtract(inStop, inStart);
+        return t.add(inStart, t.multiply(diff, inFraction));
+    }
+
+    // Normalizes the double-precision n-dimensional vector, i.e. makes it length 1.
+    static private void normalize(double[] in, Target.Floaty[] out, Target t) {
+        Target.Floaty l = length(in, t);
+        boolean isZero = l.get() == 0.;
+        for (int i = 0; i < in.length; i++) {
+            out[i] = t.newFloaty(in[i]);
+            if (!isZero) {
+                out[i] = t.divide(out[i], l);
+            }
+        }
+    }
+
     // Normalizes the n-dimensional vector, i.e. makes it length 1.
     static private void normalize(float[] in, Target.Floaty[] out, Target t) {
         Target.Floaty l = length(in, t);
@@ -461,6 +849,17 @@
         }
     }
 
+    static private Target.Floaty pow(double x, double y, Target t) {
+        Target.Floaty base = t.newFloaty(x);
+        Target.Floaty exponent = t.newFloaty(y);
+        return t.newFloaty(
+            Math.pow(base.mid(), exponent.mid()),
+            Math.pow(base.min(), exponent.min()),
+            Math.pow(base.min(), exponent.max()),
+            Math.pow(base.max(), exponent.min()),
+            Math.pow(base.max(), exponent.max()));
+    }
+
     static private Target.Floaty powr(float x, float y, Target t) {
         Target.Floaty base = t.new32(x);
         Target.Floaty exponent = t.new32(y);
@@ -472,11 +871,30 @@
             pow(base.max32(), exponent.max32()));
     }
 
+    static private Target.Floaty radians(double d, Target t) {
+        Target.Floaty in = t.newFloaty(d);
+        Target.Floaty k = t.newFloaty(Math.PI / 180);
+        return t.multiply(in, k);
+    }
+
+    static private Target.Floaty recip(double d, Target t) {
+        Target.Floaty in = t.newFloaty(d);
+        return t.divide(t.newFloaty(1.), in);
+    }
+
     static private Target.Floaty recip(float f, Target t) {
         Target.Floaty in = t.new32(f);
         return t.divide(t.new32(1.f), in);
     }
 
+    static private Target.Floaty rint(double d, Target t) {
+        Target.Floaty in = t.newFloaty(d);
+        return t.newFloaty(
+            Math.rint(in.mid()),
+            Math.rint(in.min()),
+            Math.rint(in.max()));
+    }
+
     static private Target.Floaty rootn(float inV, int inN, Target t) {
         /* Rootn of a negative number should be possible only if the number
          * is odd.  In cases where the int is very large, our approach will
@@ -499,11 +917,37 @@
         }
     }
 
+    // NOTE: This function delegates to the floating-point version in libm.  Need to switch to the
+    // double-precision version later.
+    //
+    // Also, use native round() instead of Math.round() as the latter has different rounding
+    // behavior in case of ties.
+    static private Target.Floaty round(double d, Target t) {
+        Target.Floaty in = t.newFloaty(d);
+        return t.newFloaty(
+            round((float) in.mid()),
+            round((float) in.min()),
+            round((float) in.max()));
+    }
+
+    static private Target.Floaty rsqrt(double d, Target t) {
+        Target.Floaty in = t.newFloaty(d);
+        return t.divide(t.newFloaty(1.), t.sqrt(in));
+    }
+
     static private Target.Floaty rsqrt(float f, Target t) {
         Target.Floaty in = t.new32(f);
         return t.divide(t.new32(1.f), t.sqrt(in));
     }
 
+    static private Target.Floaty sin(double d, Target t) {
+        Target.Floaty in = t.newFloaty(d);
+        return t.newFloaty(
+            Math.sin(in.mid()),
+            Math.sin(in.min()),
+            Math.sin(in.max()));
+    }
+
     static private Target.Floaty sin(float f, Target t) {
         Target.Floaty in = t.new32(f);
         return t.new32(
@@ -512,6 +956,14 @@
             sin(in.max32()));
     }
 
+    static private Target.Floaty sinh(double d, Target t) {
+        Target.Floaty in = t.newFloaty(d);
+        return t.newFloaty(
+            Math.sinh(in.mid()),
+            Math.sinh(in.min()),
+            Math.sinh(in.max()));
+    }
+
     static private Target.Floaty sinh(float f, Target t) {
         Target.Floaty in = t.new32(f);
         return t.new32(
@@ -520,6 +972,14 @@
             sinh(in.max32()));
     }
 
+    static private Target.Floaty sinpi(double d, Target t) {
+        Target.Floaty in = t.multiply(t.newFloaty(d), pi(t));
+        return t.newFloaty(
+            Math.sin(in.mid()),
+            Math.sin(in.min()),
+            Math.sin(in.max()));
+    }
+
     static private Target.Floaty sinpi(float f, Target t) {
         Target.Floaty in = t.multiply(t.new32(f), pi32(t));
         return t.new32(
@@ -528,25 +988,56 @@
             sin(in.max32()));
     }
 
+    static private Target.Floaty sqrt(double d, Target t) {
+        Target.Floaty in = t.newFloaty(d);
+        return t.sqrt(in);
+    }
+
     static private Target.Floaty sqrt(float f, Target t) {
         Target.Floaty in = t.new32(f);
         return t.sqrt(in);
     }
 
+    static private Target.Floaty step(double v, double edge, Target t) {
+        return t.newFloaty(v < edge ? 0.f : 1.f);
+    }
+
+    static private Target.Floaty tan(double d, Target t) {
+        Target.Floaty in = t.newFloaty(d);
+        double min = Math.tan(in.min());
+        double max = Math.tan(in.max());
+        /* If difference between in.max() and in.min() is larger than PI or if the tan of the min is
+         * greater than that of the max, we spanned a discontinuity.
+         */
+        if (in.max() - in.min() > Math.PI || min > max) {
+            return any(t);
+        } else {
+            return t.newFloaty(Math.tan(d), min, max);
+        }
+    }
+
     static private Target.Floaty tan(float f, Target t) {
         Target.Floaty in = t.new32(f);
         float min = tan(in.min32());
         float max = tan(in.max32());
-        /* If the tan of the min is greater than that of the max,
-         * we spanned a discontinuity.
+        /* If difference between in.max() and in.min() is larger than PI or if the tan of the min is
+         * greater than that of the max, we spanned a discontinuity.
          */
-        if (min > max) {
+        if (in.max() - in.min() > Math.PI || min > max) {
             return any32(t);
         } else {
             return t.new32(tan(f), min, max);
         }
     }
 
+    static private Target.Floaty tanh(double d, Target t) {
+        Target.Floaty in = t.newFloaty(d);
+        return t.newFloaty(
+            Math.tanh(in.mid()),
+            Math.tanh(in.min()),
+            Math.tanh(in.max()));
+    }
+
     static private Target.Floaty tanh(float f, Target t) {
         Target.Floaty in = t.new32(f);
         return t.new32(
@@ -555,20 +1046,55 @@
             tanh(in.max32()));
     }
 
+    static private Target.Floaty tanpi(double d, Target t) {
+        Target.Floaty in = t.multiply(t.newFloaty(d), pi(t));
+        double min = Math.tan(in.min());
+        double max = Math.tan(in.max());
+
+        /* If difference between in.max() and in.min() is larger than PI or if the tan of the min is
+         * greater than that of the max, we spanned a discontinuity.
+         */
+        if (in.max() - in.min() > Math.PI || min > max) {
+            return any(t);
+        } else {
+            return t.newFloaty(Math.tan(in.mid()), min, max);
+        }
+    }
+
     static private Target.Floaty tanpi(float f, Target t) {
         Target.Floaty in = t.multiply(t.new32(f), pi32(t));
         float min = tan(in.min32());
         float max = tan(in.max32());
-        /* If the tan of the min is greater than that of the max,
-         * we spanned a discontinuity.
+        /* If difference between in.max() and in.min() is larger than PI or if the tan of the min is
+         * greater than that of the max, we spanned a discontinuity.
          */
-        if (min > max) {
+        if (in.max() - in.min() > Math.PI || min > max) {
             return any32(t);
         } else {
             return t.new32(tan(in.mid32()), min, max);
         }
     }
 
+    // NOTE: This function delegates to the floating-point version in libm.  Need to switch to the
+    // double-precision version later.
+    static private Target.Floaty tgamma(double d, Target t) {
+        Target.Floaty in = t.newFloaty(d);
+        return t.newFloaty(
+            tgamma((float) in.mid()),
+            tgamma((float) in.min()),
+            tgamma((float) in.max()));
+    }
+
+    // NOTE: This function delegates to the floating-point version in libm.  Need to switch to the
+    // double-precision version later.
+    static private Target.Floaty trunc(double d, Target t) {
+        Target.Floaty in = t.newFloaty(d);
+        return t.newFloaty(
+            trunc((float) in.mid()),
+            trunc((float) in.min()),
+            trunc((float) in.max()));
+    }
+
     static public void computeAbs(TestAbs.ArgumentsCharUchar args) {
         args.out = (byte)Math.abs(args.inV);
     }
@@ -581,68 +1107,137 @@
         args.out = Math.abs(args.inV);
     }
 
+    static public void computeAcos(TestAcos.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(4, 4);
+        args.out = acos(args.inVDouble, t);
+    }
+
     static public void computeAcos(TestAcos.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(4, 128, false);
+        t.setPrecision(4, 128);
         args.out = acos(args.inV, t);
     }
 
+    static public void computeAcosh(TestAcosh.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(4, 4);
+        args.out = acosh(args.inVDouble, t);
+    }
+
     static public void computeAcosh(TestAcosh.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(4, 128, false);
+        t.setPrecision(4, 128);
         args.out = acosh(args.inV, t);
     }
 
+    static public void computeAcospi(TestAcospi.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(5, 5);
+        args.out = acospi(args.inVDouble, t);
+    }
+
     static public void computeAcospi(TestAcospi.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(5, 128, false);
+        t.setPrecision(5, 128);
         args.out = acospi(args.inV, t);
     }
 
+    static public void computeAsin(TestAsin.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(4, 4);
+        args.out = asin(args.inVDouble, t);
+    }
+
     static public void computeAsin(TestAsin.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(4, 128, false);
+        t.setPrecision(4, 128);
         args.out = asin(args.inV, t);
     }
 
+    static public void computeAsinh(TestAsinh.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(4, 4);
+        args.out = asinh(args.inVDouble, t);
+    }
+
     static public void computeAsinh(TestAsinh.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(4, 128, false);
+        t.setPrecision(4, 128);
         args.out = asinh(args.inV, t);
     }
 
+    static public void computeAsinpi(TestAsinpi.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(5, 5);
+        args.out = asinpi(args.inVDouble, t);
+    }
+
     static public void computeAsinpi(TestAsinpi.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(5, 128, false);
+        t.setPrecision(5, 128);
         args.out = asinpi(args.inV, t);
     }
 
+    static public void computeAtan(TestAtan.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(5, 5);
+        args.out = atan(args.inVDouble, t);
+    }
+
     static public void computeAtan(TestAtan.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(5, 128, false);
+        t.setPrecision(5, 128);
         args.out = atan(args.inV, t);
     }
 
+    static public void computeAtanh(TestAtanh.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(5, 5);
+        args.out = atanh(args.inVDouble, t);
+    }
+
     static public void computeAtanh(TestAtanh.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(5, 128, false);
+        t.setPrecision(5, 128);
         args.out = atanh(args.inV, t);
     }
 
+    static public void computeAtanpi(TestAtanpi.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(5, 5);
+        args.out = atanpi(args.inVDouble, t);
+    }
+
     static public void computeAtanpi(TestAtanpi.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(5, 128, false);
+        t.setPrecision(5, 128);
         args.out = atanpi(args.inV, t);
     }
 
+    static public void computeAtan2(TestAtan2.ArgumentsHalfHalfHalf args, Target t) {
+        t.setPrecision(6, 6);
+        args.out = atan2(args.inNumeratorDouble, args.inDenominatorDouble, t);
+    }
+
     static public void computeAtan2(TestAtan2.ArgumentsFloatFloatFloat args, Target t) {
-        t.setPrecision(6, 128, false);
+        t.setPrecision(6, 128);
         args.out = atan2(args.inNumerator, args.inDenominator, t);
     }
 
+    static public void computeAtan2pi(TestAtan2pi.ArgumentsHalfHalfHalf args, Target t) {
+        t.setPrecision(6, 6);
+        args.out = atan2pi(args.inNumeratorDouble, args.inDenominatorDouble, t);
+    }
+
     static public void computeAtan2pi(TestAtan2pi.ArgumentsFloatFloatFloat args, Target t) {
-        t.setPrecision(6, 128, false);
+        t.setPrecision(6, 128);
         args.out = atan2pi(args.inNumerator, args.inDenominator, t);
     }
 
+    static public void computeCbrt(TestCbrt.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(2, 2);
+        args.out = cbrt(args.inVDouble, t);
+    }
+
     static public void computeCbrt(TestCbrt.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(2, 128, false);
+        t.setPrecision(2, 128);
         args.out = cbrt(args.inV, t);
     }
 
+    static public void computeCeil(TestCeil.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(0, 0);
+        Target.Floaty in = t.newFloaty(args.inVDouble);
+        args.out = t.newFloaty(
+            Math.ceil(in.mid()),
+            Math.ceil(in.min()),
+            Math.ceil(in.max()));
+    }
+
     static public void computeCeil(TestCeil.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(0, 1, false);
+        t.setPrecision(0, 1);
         Target.Floaty in = t.new32(args.inV);
         args.out = t.new32(
             ceil(in.mid32()),
@@ -674,8 +1269,13 @@
         args.out = minU32(args.inMaxValue, maxU32(args.inValue, args.inMinValue));
     }
 
+    static public void computeClamp(TestClamp.ArgumentsHalfHalfHalfHalf args, Target t) {
+        t.setPrecision(0, 0);
+        args.out = clamp(args.inValueDouble, args.inMinValueDouble, args.inMaxValueDouble, t);
+    }
+
     static public void computeClamp(TestClamp.ArgumentsFloatFloatFloatFloat args, Target t) {
-        t.setPrecision(0, 0, false);
+        t.setPrecision(0, 0);
         args.out = t.new32(Math.min(args.inMaxValue,
                         Math.max(args.inValue, args.inMinValue)));
     }
@@ -739,12 +1339,16 @@
     static public void computeConvert(TestConvert.ArgumentsCharUlong args) {
         args.out = convertCharToUlong(args.inV);
     }
+    static public void computeConvert(TestConvert.ArgumentsCharHalf args, Target t) {
+        t.setPrecision(0, 0);
+        args.out = t.newFloaty(convertCharToDouble(args.inV));
+    }
     static public void computeConvert(TestConvert.ArgumentsCharFloat args, Target t) {
-        t.setPrecision(0, 0, false);
+        t.setPrecision(0, 0);
         args.out = t.new32(convertCharToFloat(args.inV));
     }
     static public void computeConvert(TestConvert.ArgumentsCharDouble args, Target t) {
-        t.setPrecision(0, 0, false);
+        t.setPrecision(0, 0);
         args.out = t.new64(convertCharToDouble(args.inV));
     }
 
@@ -772,12 +1376,16 @@
     static public void computeConvert(TestConvert.ArgumentsUcharUlong args) {
         args.out = convertUcharToUlong(args.inV);
     }
+    static public void computeConvert(TestConvert.ArgumentsUcharHalf args, Target t) {
+        t.setPrecision(0, 0);
+        args.out = t.newFloaty(convertUcharToDouble(args.inV));
+    }
     static public void computeConvert(TestConvert.ArgumentsUcharFloat args, Target t) {
-        t.setPrecision(0, 0, false);
+        t.setPrecision(0, 0);
         args.out = t.new32(convertUcharToFloat(args.inV));
     }
     static public void computeConvert(TestConvert.ArgumentsUcharDouble args, Target t) {
-        t.setPrecision(0, 0, false);
+        t.setPrecision(0, 0);
         args.out = t.new64(convertUcharToDouble(args.inV));
     }
 
@@ -805,12 +1413,16 @@
     static public void computeConvert(TestConvert.ArgumentsShortUlong args) {
         args.out = convertShortToUlong(args.inV);
     }
+    static public void computeConvert(TestConvert.ArgumentsShortHalf args, Target t) {
+        t.setPrecision(1, 1);
+        args.out = t.newFloaty(convertShortToDouble(args.inV));
+    }
     static public void computeConvert(TestConvert.ArgumentsShortFloat args, Target t) {
-        t.setPrecision(0, 0, false);
+        t.setPrecision(0, 0);
         args.out = t.new32(convertShortToFloat(args.inV));
     }
     static public void computeConvert(TestConvert.ArgumentsShortDouble args, Target t) {
-        t.setPrecision(0, 0, false);
+        t.setPrecision(0, 0);
         args.out = t.new64(convertShortToDouble(args.inV));
     }
 
@@ -838,12 +1450,16 @@
     static public void computeConvert(TestConvert.ArgumentsUshortUlong args) {
         args.out = convertUshortToUlong(args.inV);
     }
+    static public void computeConvert(TestConvert.ArgumentsUshortHalf args, Target t) {
+        t.setPrecision(1, 1);
+        args.out = t.newFloaty(convertUshortToDouble(args.inV));
+    }
     static public void computeConvert(TestConvert.ArgumentsUshortFloat args, Target t) {
-        t.setPrecision(0, 0, false);
+        t.setPrecision(0, 0);
         args.out = t.new32(convertUshortToFloat(args.inV));
     }
     static public void computeConvert(TestConvert.ArgumentsUshortDouble args, Target t) {
-        t.setPrecision(0, 0, false);
+        t.setPrecision(0, 0);
         args.out = t.new64(convertUshortToDouble(args.inV));
     }
 
@@ -871,12 +1487,16 @@
     static public void computeConvert(TestConvert.ArgumentsIntUlong args) {
         args.out = convertIntToUlong(args.inV);
     }
+    static public void computeConvert(TestConvert.ArgumentsIntHalf args, Target t) {
+        t.setPrecision(1, 1);
+        args.out = t.newFloaty(convertIntToDouble(args.inV));
+    }
     static public void computeConvert(TestConvert.ArgumentsIntFloat args, Target t) {
-        t.setPrecision(1, 1, false);
+        t.setPrecision(1, 1);
         args.out = t.new32(convertIntToFloat(args.inV));
     }
     static public void computeConvert(TestConvert.ArgumentsIntDouble args, Target t) {
-        t.setPrecision(0, 0, false);
+        t.setPrecision(0, 0);
         args.out = t.new64(convertIntToDouble(args.inV));
     }
 
@@ -904,12 +1524,16 @@
     static public void computeConvert(TestConvert.ArgumentsUintUlong args) {
         args.out = convertUintToUlong(args.inV);
     }
+    static public void computeConvert(TestConvert.ArgumentsUintHalf args, Target t) {
+        t.setPrecision(1, 1);
+        args.out = t.newFloaty(convertUintToDouble(args.inV));
+    }
     static public void computeConvert(TestConvert.ArgumentsUintFloat args, Target t) {
-        t.setPrecision(1, 1, false);
+        t.setPrecision(1, 1);
         args.out = t.new32(convertUintToFloat(args.inV));
     }
     static public void computeConvert(TestConvert.ArgumentsUintDouble args, Target t) {
-        t.setPrecision(0, 0, false);
+        t.setPrecision(0, 0);
         args.out = t.new64(convertUintToDouble(args.inV));
     }
 
@@ -937,12 +1561,16 @@
     static public void computeConvert(TestConvert.ArgumentsLongUlong args) {
         args.out = convertLongToUlong(args.inV);
     }
+    static public void computeConvert(TestConvert.ArgumentsLongHalf args, Target t) {
+        t.setPrecision(1, 1);
+        args.out = t.newFloaty(convertLongToDouble(args.inV));
+    }
     static public void computeConvert(TestConvert.ArgumentsLongFloat args, Target t) {
-        t.setPrecision(1, 1, false);
+        t.setPrecision(1, 1);
         args.out = t.new32(convertLongToFloat(args.inV));
     }
     static public void computeConvert(TestConvert.ArgumentsLongDouble args, Target t) {
-        t.setPrecision(1, 1, false);
+        t.setPrecision(1, 1);
         args.out = t.new64(convertLongToDouble(args.inV));
     }
 
@@ -970,15 +1598,56 @@
     static public void computeConvert(TestConvert.ArgumentsUlongUlong args) {
         args.out = convertUlongToUlong(args.inV);
     }
+    static public void computeConvert(TestConvert.ArgumentsUlongHalf args, Target t) {
+        t.setPrecision(1, 1);
+        args.out = t.newFloaty(convertUlongToDouble(args.inV));
+    }
     static public void computeConvert(TestConvert.ArgumentsUlongFloat args, Target t) {
-        t.setPrecision(1, 1, false);
+        t.setPrecision(1, 1);
         args.out = t.new32(convertUlongToFloat(args.inV));
     }
     static public void computeConvert(TestConvert.ArgumentsUlongDouble args, Target t) {
-        t.setPrecision(1, 1, false);
+        t.setPrecision(1, 1);
         args.out = t.new64(convertUlongToDouble(args.inV));
     }
 
+    static public void computeConvert(TestConvert.ArgumentsHalfChar args) {
+        args.out = convertDoubleToChar(args.inVDouble);
+    }
+    static public void computeConvert(TestConvert.ArgumentsHalfUchar args) {
+        args.out = convertDoubleToUchar(args.inVDouble);
+    }
+    static public void computeConvert(TestConvert.ArgumentsHalfShort args) {
+        args.out = convertDoubleToShort(args.inVDouble);
+    }
+    static public void computeConvert(TestConvert.ArgumentsHalfUshort args) {
+        args.out = convertDoubleToUshort(args.inVDouble);
+    }
+    static public void computeConvert(TestConvert.ArgumentsHalfInt args) {
+        args.out = convertDoubleToInt(args.inVDouble);
+    }
+    static public void computeConvert(TestConvert.ArgumentsHalfUint args) {
+        args.out = convertDoubleToUint(args.inVDouble);
+    }
+    static public void computeConvert(TestConvert.ArgumentsHalfLong args) {
+        args.out = convertDoubleToLong(args.inVDouble);
+    }
+    static public void computeConvert(TestConvert.ArgumentsHalfUlong args) {
+        args.out = convertDoubleToUlong(args.inVDouble);
+    }
+    static public void computeConvert(TestConvert.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(0, 0);
+        args.out = t.newFloaty(args.inVDouble);
+    }
+    static public void computeConvert(TestConvert.ArgumentsHalfFloat args, Target t) {
+        t.setPrecision(0, 0);
+        args.out = t.newFloaty(convertDoubleToFloat(args.inVDouble));
+    }
+    static public void computeConvert(TestConvert.ArgumentsHalfDouble args, Target t) {
+        t.setPrecision(0, 0);
+        args.out = t.newFloaty(args.inVDouble);
+    }
+
     static public void computeConvert(TestConvert.ArgumentsFloatChar args) {
         args.out = convertFloatToChar(args.inV);
     }
@@ -1003,12 +1672,16 @@
     static public void computeConvert(TestConvert.ArgumentsFloatUlong args) {
         args.out = convertFloatToUlong(args.inV);
     }
+    static public void computeConvert(TestConvert.ArgumentsFloatHalf args, Target t) {
+        t.setPrecision(1, 1);
+        args.out = t.newFloaty(args.inV);
+    }
     static public void computeConvert(TestConvert.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(0, 0, false);
+        t.setPrecision(0, 0);
         args.out = t.new32(convertFloatToFloat(args.inV));
     }
     static public void computeConvert(TestConvert.ArgumentsFloatDouble args, Target t) {
-        t.setPrecision(0, 0, false);
+        t.setPrecision(0, 0);
         args.out = t.new64(convertFloatToDouble(args.inV));
     }
 
@@ -1036,66 +1709,128 @@
     static public void computeConvert(TestConvert.ArgumentsDoubleUlong args) {
         args.out = convertDoubleToUlong(args.inV);
     }
+    static public void computeConvert(TestConvert.ArgumentsDoubleHalf args, Target t) {
+        t.setPrecision(1, 1);
+        args.out = t.newFloaty(args.inV);
+    }
     static public void computeConvert(TestConvert.ArgumentsDoubleFloat args, Target t) {
-        t.setPrecision(1, 1, false);
+        t.setPrecision(1, 1);
         args.out = t.new32(convertDoubleToFloat(args.inV));
     }
     static public void computeConvert(TestConvert.ArgumentsDoubleDouble args, Target t) {
-        t.setPrecision(0, 0, false);
+        t.setPrecision(0, 0);
         args.out = t.new64(convertDoubleToDouble(args.inV));
     }
 
+    static public void computeCopysign(TestCopysign.ArgumentsHalfHalfHalf args, Target t) {
+        t.setPrecision(0, 0);
+        args.out = copysign(args.inMagnitudeValueDouble, args.inSignValueDouble, t);
+    }
+
     static public void computeCopysign(TestCopysign.ArgumentsFloatFloatFloat args, Target t) {
-        t.setPrecision(0, 0, false);
+        t.setPrecision(0, 0);
         args.out = t.new32(Math.copySign(args.inMagnitudeValue, args.inSignValue));
     }
 
+    static public void computeCos(TestCos.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(4, 4);
+        args.out = cos(args.inVDouble, t);
+    }
+
     static public void computeCos(TestCos.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(4, 128, false);
+        t.setPrecision(4, 128);
         args.out = cos(args.inV, t);
     }
 
+    static public void computeCosh(TestCosh.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(4, 4);
+        args.out = cosh(args.inVDouble, t);
+    }
+
     static public void computeCosh(TestCosh.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(4, 128, false);
+        t.setPrecision(4, 128);
         args.out = cosh(args.inV, t);
     }
 
+    static public void computeCospi(TestCospi.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(4, 4);
+        args.out = cospi(args.inVDouble, t);
+    }
+
     static public void computeCospi(TestCospi.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(4, 128, false);
+        t.setPrecision(4, 128);
         args.out = cospi(args.inV, t);
     }
 
+    static public void computeCross(TestCross.ArgumentsHalfNHalfNHalfN args, Target t) {
+        t.setPrecision(1, 4);
+        cross(args.inLeftVectorDouble, args.inRightVectorDouble, args.out, t);
+    }
+
     static public void computeCross(TestCross.ArgumentsFloatNFloatNFloatN args, Target t) {
-        t.setPrecision(1, 4, false);
+        t.setPrecision(1, 4);
         cross(args.inLeftVector, args.inRightVector, args.out, t);
     }
 
+    static public void computeDegrees(TestDegrees.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(3, 3);
+        args.out = degrees(args.inVDouble, t);
+    }
+
     static public void computeDegrees(TestDegrees.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(3, 3, false);
+        t.setPrecision(3, 3);
         Target.Floaty in = t.new32(args.inV);
         Target.Floaty k = t.new32((float)(180.0 / Math.PI));
         args.out = t.multiply(in, k);
     }
 
+    static public void computeDistance(TestDistance.ArgumentsHalfHalfHalf args, Target t) {
+        t.setPrecision(1, 1); // TODO double-check precision
+        args.out = distance(new double[] {args.inLeftVectorDouble},
+                            new double[] {args.inRightVectorDouble}, t);
+    }
+    static public void computeDistance(TestDistance.ArgumentsHalfNHalfNHalf args, Target t) {
+        t.setPrecision(1, 1); // TODO double-check precision
+        args.out = distance(args.inLeftVectorDouble, args.inRightVectorDouble, t);
+    }
+
     static public void computeDistance(TestDistance.ArgumentsFloatFloatFloat args, Target t) {
-        t.setPrecision(1, 1, false);
+        t.setPrecision(1, 1);
         args.out = distance(new float[] {args.inLeftVector}, new float[] {args.inRightVector}, t);
     }
 
     static public void computeDistance(TestDistance.ArgumentsFloatNFloatNFloat args, Target t) {
-        t.setPrecision(1, 1, false);
+        t.setPrecision(1, 1);
         args.out = distance(args.inLeftVector, args.inRightVector, t);
     }
 
+    static public void computeDot(TestDot.ArgumentsHalfHalfHalf args, Target t) {
+        t.setPrecision(1, 4); // TODO double-check precision
+        Target.Floaty a = t.newFloaty(args.inLeftVectorDouble);
+        Target.Floaty b = t.newFloaty(args.inRightVectorDouble);
+        args.out = t.multiply(a, b);
+    }
+
+    static public void computeDot(TestDot.ArgumentsHalfNHalfNHalf args, Target t) {
+        t.setPrecision(1, 4); // TODO double-check precision
+        Target.Floaty sum = t.newFloaty(0.);
+        for (int i = 0; i < args.inLeftVectorDouble.length; i++) {
+            Target.Floaty a = t.newFloaty(args.inLeftVectorDouble[i]);
+            Target.Floaty b = t.newFloaty(args.inRightVectorDouble[i]);
+            sum = t.add(sum, t.multiply(a, b));
+        }
+        args.out = sum;
+    }
+
     static public void computeDot(TestDot.ArgumentsFloatFloatFloat args, Target t) {
-        t.setPrecision(1, 4, false);
+        t.setPrecision(1, 4);
         Target.Floaty a = t.new32(args.inLeftVector);
         Target.Floaty b = t.new32(args.inRightVector);
         args.out = t.multiply(a, b);
     }
 
     static public void computeDot(TestDot.ArgumentsFloatNFloatNFloat args, Target t) {
-        t.setPrecision(1, 4, false);
+        t.setPrecision(1, 4);
         Target.Floaty sum = t.new32(0.f);
         for (int i = 0; i < args.inLeftVector.length; i++) {
             Target.Floaty a = t.new32(args.inLeftVector[i]);
@@ -1105,8 +1840,13 @@
         args.out = sum;
     }
 
+    static public void computeErf(TestErf.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(16, 16);
+        args.out = erf(args.inVDouble, t);
+    }
+
     static public void computeErf(TestErf.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(16, 128, false);
+        t.setPrecision(16, 128);
         Target.Floaty in = t.new32(args.inV);
         args.out = t.new32(
             erf(args.inV),
@@ -1114,8 +1854,13 @@
             erf(in.max32()));
     }
 
+    static public void computeErfc(TestErfc.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(16, 16);
+        args.out = erfc(args.inVDouble, t);
+    }
+
     static public void computeErfc(TestErfc.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(16, 128, false);
+        t.setPrecision(16, 128);
         Target.Floaty in = t.new32(args.inV);
         args.out = t.new32(
             erfc(args.inV),
@@ -1123,28 +1868,53 @@
             erfc(in.max32()));
     }
 
+    static public void computeExp(TestExp.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(3, 3);
+        args.out = exp(args.inVDouble, t);
+    }
+
     static public void computeExp(TestExp.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(3, 16, false);
+        t.setPrecision(3, 16);
         args.out = exp(args.inV, t);
     }
 
+    static public void computeExp10(TestExp10.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(3, 3);
+        args.out = exp10(args.inVDouble, t);
+    }
+
     static public void computeExp10(TestExp10.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(3, 32, false);
+        t.setPrecision(3, 32);
         args.out = exp10(args.inV, t);
     }
 
+    static public void computeExp2(TestExp2.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(3, 3);
+        args.out = exp2(args.inVDouble, t);
+    }
+
     static public void computeExp2(TestExp2.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(3, 16, false);
+        t.setPrecision(3, 16);
         args.out = exp2(args.inV, t);
     }
 
+    static public void computeExpm1(TestExpm1.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(3, 3);
+        args.out = expm1(args.inVDouble, t);
+    }
+
     static public void computeExpm1(TestExpm1.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(3, 16, false);
+        t.setPrecision(3, 16);
         args.out = expm1(args.inV, t);
     }
 
+    static public void computeFabs(TestFabs.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(0, 0);
+        args.out = fabs(args.inVDouble, t);
+    }
+
     static public void computeFabs(TestFabs.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(0, 0, false);
+        t.setPrecision(0, 0);
         Target.Floaty in = t.new32(args.inV);
         args.out = t.new32(
             Math.abs(args.inV),
@@ -1153,39 +1923,44 @@
     }
 
     static public void computeFastDistance(TestFastDistance.ArgumentsFloatFloatFloat args, Target t) {
-        t.setPrecision(FAST_PRECISION, FAST_PRECISION, false);
+        t.setPrecision(FAST_PRECISION, FAST_PRECISION);
         args.out = distance(new float[] {args.inLeftVector}, new float[] {args.inRightVector}, t);
     }
 
     static public void computeFastDistance(TestFastDistance.ArgumentsFloatNFloatNFloat args, Target t) {
-        t.setPrecision(FAST_PRECISION, FAST_PRECISION, false);
+        t.setPrecision(FAST_PRECISION, FAST_PRECISION);
         args.out = distance(args.inLeftVector, args.inRightVector, t);
     }
 
     static public void computeFastLength(TestFastLength.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(FAST_PRECISION, FAST_PRECISION, false);
+        t.setPrecision(FAST_PRECISION, FAST_PRECISION);
         args.out = length(new float[] {args.inV}, t);
     }
 
     static public void computeFastLength(TestFastLength.ArgumentsFloatNFloat args, Target t) {
-        t.setPrecision(FAST_PRECISION, FAST_PRECISION, false);
+        t.setPrecision(FAST_PRECISION, FAST_PRECISION);
         args.out = length(args.inV, t);
     }
 
     static public void computeFastNormalize(TestFastNormalize.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(FAST_PRECISION, FAST_PRECISION, false);
+        t.setPrecision(FAST_PRECISION, FAST_PRECISION);
         Target.Floaty[] out = new Target.Floaty[1];
         normalize(new float[] {args.inV}, out, t);
         args.out = out[0];
     }
 
     static public void computeFastNormalize(TestFastNormalize.ArgumentsFloatNFloatN args, Target t) {
-        t.setPrecision(FAST_PRECISION, FAST_PRECISION, false);
+        t.setPrecision(FAST_PRECISION, FAST_PRECISION);
         normalize(args.inV, args.out, t);
     }
 
+    static public void computeFdim(TestFdim.ArgumentsHalfHalfHalf args, Target t) {
+        t.setPrecision(1, 1);
+        args.out = fdim(args.inADouble, args.inBDouble, t);
+    }
+
     static public void computeFdim(TestFdim.ArgumentsFloatFloatFloat args, Target t) {
-        t.setPrecision(1, 1, false);
+        t.setPrecision(1, 1);
         Target.Floaty inA = t.new32(args.inA);
         Target.Floaty inB = t.new32(args.inB);
         Target.Floaty r = t.subtract(inA, inB);
@@ -1195,8 +1970,13 @@
             Math.max(0.f, r.max32()));
     }
 
+    static public void computeFloor(TestFloor.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(0, 0);
+        args.out = floor(args.inVDouble, t);
+    }
+
     static public void computeFloor(TestFloor.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(0, 0, false);
+        t.setPrecision(0, 0);
         Target.Floaty in = t.new32(args.inV);
         args.out = t.new32(
             floor(args.inV),
@@ -1204,14 +1984,25 @@
             floor(in.max32()));
     }
 
+    static public void computeFma(TestFma.ArgumentsHalfHalfHalfHalf args, Target t) {
+        t.setPrecision(1, 1);
+        args.out = fma(args.inMultiplicand1Double, args.inMultiplicand2Double,
+            args.inOffsetDouble, t);
+    }
+
     static public void computeFma(TestFma.ArgumentsFloatFloatFloatFloat args, Target t) {
-        t.setPrecision(1, 1, false);
+        t.setPrecision(1, 1);
         Target.Floaty ab = t.multiply(t.new32(args.inMultiplicand1), t.new32(args.inMultiplicand2));
         args.out = t.add(ab, t.new32(args.inOffset));
     }
 
+    static public void computeFmax(TestFmax.ArgumentsHalfHalfHalf args, Target t) {
+        t.setPrecision(0, 0);
+        args.out = fmax(args.inADouble, args.inBDouble, t);
+    }
+
     static public void computeFmax(TestFmax.ArgumentsFloatFloatFloat args, Target t) {
-        t.setPrecision(0, 0, false);
+        t.setPrecision(0, 0);
         Target.Floaty a = t.new32(args.inA);
         Target.Floaty b = t.new32(args.inB);
         args.out = t.new32(
@@ -1222,8 +2013,13 @@
             Math.max(a.max32(), b.max32()));
     }
 
+    static public void computeFmin(TestFmin.ArgumentsHalfHalfHalf args, Target t) {
+        t.setPrecision(0, 0);
+        args.out = fmin(args.inADouble, args.inBDouble, t);
+    }
+
     static public void computeFmin(TestFmin.ArgumentsFloatFloatFloat args, Target t) {
-        t.setPrecision(0, 0, false);
+        t.setPrecision(0, 0);
         Target.Floaty a = t.new32(args.inA);
         Target.Floaty b = t.new32(args.inB);
         args.out = t.new32(
@@ -1234,8 +2030,13 @@
             Math.min(a.max32(), b.max32()));
     }
 
+    static public void computeFmod(TestFmod.ArgumentsHalfHalfHalf args, Target t) {
+        t.setPrecision(1, 1);
+        args.out = fmod(args.inNumeratorDouble, args.inDenominatorDouble, t);
+    }
+
     static public void computeFmod(TestFmod.ArgumentsFloatFloatFloat args, Target t) {
-        t.setPrecision(1, 1, false);
+        t.setPrecision(1, 1);
         Target.Floaty numerator = t.new32(args.inNumerator);
         Target.Floaty denominator = t.new32(args.inDenominator);
         args.out = t.new32(
@@ -1246,45 +2047,61 @@
             numerator.max32() % denominator.max32());
     }
 
+    static public void computeFract(TestFract.ArgumentsHalfHalfHalf args, Target t) {
+        t.setPrecision(1, 1);
+        args.out = fract(args.inVDouble, t, 0.99951171875 /* max float16 smaller than 1.0 */);
+        args.outFloor = floor(args.inVDouble, t);
+    }
+
     static public void computeFract(TestFract.ArgumentsFloatFloatFloat args, Target t) {
-        t.setPrecision(1, 1, false);
+        t.setPrecision(1, 1);
         float floor = floor(args.inV);
         args.outFloor = t.new32(floor);
         // 0x1.fffffep-1f is 0.999999...
         args.out = t.new32(Math.min(args.inV - floor, 0x1.fffffep-1f));
     }
 
+    static public void computeFract(TestFract.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(1, 1);
+        args.out = fract(args.inVDouble, t, 0.99951171875 /* max float16 smaller than 1.0 */);
+    }
+
     static public void computeFract(TestFract.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(1, 1, false);
+        t.setPrecision(1, 1);
         float floor = floor(args.inV);
         // 0x1.fffffep-1f is 0.999999...
         args.out = t.new32(Math.min(args.inV - floor, 0x1.fffffep-1f));
     }
 
     static public void computeFrexp(TestFrexp.ArgumentsFloatIntFloat args, Target t) {
-        t.setPrecision(0, 0, false);
+        t.setPrecision(0, 0);
         FrexpResult result = frexp(args.inV);
         args.out = t.new32(result.significand);
         args.outExponent = result.exponent;
     }
 
     static public void computeHalfRecip(TestHalfRecip.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(HALF_PRECISION, HALF_PRECISION, false);
+        t.setPrecision(HALF_PRECISION, HALF_PRECISION);
         args.out = recip(args.inV, t);
     }
 
     static public void computeHalfRsqrt(TestHalfRsqrt.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(HALF_PRECISION, HALF_PRECISION, false);
+        t.setPrecision(HALF_PRECISION, HALF_PRECISION);
         args.out = rsqrt(args.inV, t);
     }
 
     static public void computeHalfSqrt(TestHalfSqrt.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(HALF_PRECISION, HALF_PRECISION, false);
+        t.setPrecision(HALF_PRECISION, HALF_PRECISION);
         args.out = sqrt(args.inV, t);
     }
 
+    static public void computeHypot(TestHypot.ArgumentsHalfHalfHalf args, Target t) {
+        t.setPrecision(4, 4);
+        args.out = hypot(args.inADouble, args.inBDouble, t);
+    }
+
     static public void computeHypot(TestHypot.ArgumentsFloatFloatFloat args, Target t) {
-        t.setPrecision(4, 4, false);
+        t.setPrecision(4, 4);
         args.out = hypot(args.inA, args.inB, t);
     }
 
@@ -1305,7 +2122,7 @@
     }
 
     static public void computeLdexp(TestLdexp.ArgumentsFloatIntFloat args, Target t) {
-        t.setPrecision(1, 1, false);
+        t.setPrecision(1, 1);
         Target.Floaty inMantissa = t.new32(args.inMantissa);
         args.out = t.new32(
             ldexp(inMantissa.mid32(), args.inExponent),
@@ -1313,18 +2130,28 @@
             ldexp(inMantissa.max32(), args.inExponent));
     }
 
+    static public void computeLength(TestLength.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(1, 1); // TODO double-check precision
+        args.out = length(new double[]{args.inVDouble}, t);
+    }
+
+    static public void computeLength(TestLength.ArgumentsHalfNHalf args, Target t) {
+        t.setPrecision(1, 1); // TODO double-check precision
+        args.out = length(args.inVDouble, t);
+    }
+
     static public void computeLength(TestLength.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(1, 1, false);
+        t.setPrecision(1, 1);
         args.out = length(new float[]{args.inV}, t);
     }
 
     static public void computeLength(TestLength.ArgumentsFloatNFloat args, Target t) {
-        t.setPrecision(1, 1, false);
+        t.setPrecision(1, 1);
         args.out = length(args.inV, t);
     }
 
     static public void computeLgamma(TestLgamma.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(16, 128, false);
+        t.setPrecision(16, 128);
         Target.Floaty in = t.new32(args.inV);
         args.out = t.new32(
             lgamma(in.mid32()),
@@ -1336,7 +2163,7 @@
      * disable the verification of -0.  We do this with a custom verifier.  Once bionic
      * is fixed, we can restore computeLgamma and remove verifyLgamma.
     static public void computeLgamma(TestLgamma.ArgumentsFloatIntFloat args, Target t) {
-        t.setPrecision(16, 128, false);
+        t.setPrecision(16, 128);
         Target.Floaty in = t.new32(args.inV);
         LgammaResult result = lgamma2(in.mid32());
         LgammaResult resultMin = lgamma2(in.min32());
@@ -1346,7 +2173,7 @@
     }
     */
     static public String verifyLgamma(TestLgamma.ArgumentsFloatIntFloat args, Target t) {
-        t.setPrecision(16, 128, false);
+        t.setPrecision(16, 128);
         Target.Floaty in = t.new32(args.inV);
         LgammaResult result = lgamma2(in.mid32());
         LgammaResult resultMin = lgamma2(in.min32());
@@ -1372,30 +2199,55 @@
         return null;
     }
 
+    static public void computeLog(TestLog.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(3, 3);
+        args.out = log(args.inVDouble, t);
+    }
+
     // TODO The relaxed ulf for the various log are taken from the old tests.
     // They are not consistent.
     static public void computeLog(TestLog.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(3, 16, false);
+        t.setPrecision(3, 16);
         args.out = log(args.inV, t);
     }
 
+    static public void computeLog10(TestLog10.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(3, 3);
+        args.out = log10(args.inVDouble, t);
+    }
+
     static public void computeLog10(TestLog10.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(3, 16, false);
+        t.setPrecision(3, 16);
         args.out = log10(args.inV, t);
     }
 
+    static public void computeLog1p(TestLog1p.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(2, 2);
+        args.out = log1p(args.inVDouble, t);
+    }
+
     static public void computeLog1p(TestLog1p.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(2, 16, false);
+        t.setPrecision(2, 16);
         args.out = log1p(args.inV, t);
     }
 
+    static public void computeLog2(TestLog2.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(3, 3);
+        args.out = log2(args.inVDouble, t);
+    }
+
     static public void computeLog2(TestLog2.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(3, 128, false);
+        t.setPrecision(3, 128);
         args.out = log2(args.inV, t);
     }
 
+    static public void computeLogb(TestLogb.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(0, 0);
+        args.out = logb(args.inVDouble, t);
+    }
+
     static public void computeLogb(TestLogb.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(0, 0, false);
+        t.setPrecision(0, 0);
         Target.Floaty in = t.new32(args.inV);
         args.out = t.new32(
             logb(in.mid32()),
@@ -1403,8 +2255,13 @@
             logb(in.max32()));
     }
 
+    static public void computeMad(TestMad.ArgumentsHalfHalfHalfHalf args, Target t) {
+        t.setPrecision(4, 4);
+        args.out = mad(args.inMultiplicand1Double, args.inMultiplicand2Double, args.inOffsetDouble, t);
+    }
+
     static public void computeMad(TestMad.ArgumentsFloatFloatFloatFloat args, Target t) {
-        t.setPrecision(1, 4, false);
+        t.setPrecision(1, 4);
         Target.Floaty ab = t.multiply(t.new32(args.inMultiplicand1), t.new32(args.inMultiplicand2));
         args.out = t.add(ab, t.new32(args.inOffset));
     }
@@ -1441,8 +2298,13 @@
         args.out = maxU64(args.inA, args.inB);
     }
 
+    static public void computeMax(TestMax.ArgumentsHalfHalfHalf args, Target t) {
+        t.setPrecision(0, 0);
+        args.out = max(args.inADouble, args.inBDouble, t);
+    }
+
     static public void computeMax(TestMax.ArgumentsFloatFloatFloat args, Target t) {
-        t.setPrecision(0, 0, false);
+        t.setPrecision(0, 0);
         Target.Floaty a = t.new32(args.inA);
         Target.Floaty b = t.new32(args.inB);
         args.out = t.new32(
@@ -1485,13 +2347,23 @@
         args.out = minU64(args.inA, args.inB);
     }
 
+    static public void computeMin(TestMin.ArgumentsHalfHalfHalf args, Target t) {
+        t.setPrecision(0, 0);
+        args.out = min(args.inADouble, args.inBDouble, t);
+    }
+
     static public void computeMin(TestMin.ArgumentsFloatFloatFloat args, Target t) {
-        t.setPrecision(0, 0, false);
+        t.setPrecision(0, 0);
         args.out = t.new32(Math.min(args.inA, args.inB));
     }
 
+    static public void computeMix(TestMix.ArgumentsHalfHalfHalfHalf args, Target t) {
+        t.setPrecision(1, 1);
+        args.out = mix(args.inStartDouble, args.inStopDouble, args.inFractionDouble, t);
+    }
+
     static public void computeMix(TestMix.ArgumentsFloatFloatFloatFloat args, Target t) {
-        t.setPrecision(1, 4, false);
+        t.setPrecision(1, 4);
         Target.Floaty start = t.new32(args.inStart);
         Target.Floaty stop = t.new32(args.inStop);
         Target.Floaty diff = t.subtract(stop, start);
@@ -1499,146 +2371,308 @@
     }
 
     static public void computeModf(TestModf.ArgumentsFloatFloatFloat args, Target t) {
-        t.setPrecision(0, 0, false);
+        t.setPrecision(0, 0);
         float ret = (float)(int)args.inV;
         args.outIntegralPart = t.new32(ret);
         args.out = t.new32(args.inV - ret);
     }
 
     static public void computeNan(TestNan.ArgumentsUintFloat args, Target t) {
-        t.setPrecision(0, 0, false);
+        t.setPrecision(0, 0);
         // TODO(jeanluc) We're not using the input argument
         args.out = t.new32(Float.NaN);
     }
 
+    static public void computeNanHalf(TestNanHalf.ArgumentsHalf args, Target t) {
+        t.setPrecision(0, 0);
+        args.out = t.newFloaty(Double.NaN);
+    }
+
+    static public void computeNativeAcos(TestNativeAcos.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(0, 0); // extraAllowedError set in fw/rs/rs_math.spec and generated test files
+        args.out = acos(args.inVDouble, t);
+    }
+
     static public void computeNativeAcos(TestNativeAcos.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION, true);
+        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION);
         args.out = acos(args.inV, t);
     }
 
+    static public void computeNativeAcosh(TestNativeAcosh.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(4, 4);
+        args.out = acosh(args.inVDouble, t);
+    }
+
     static public void computeNativeAcosh(TestNativeAcosh.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION, true);
+        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION);
         args.out = acosh(args.inV, t);
     }
 
+    static public void computeNativeAcospi(TestNativeAcospi.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(0, 0); // extraAllowedError set in fw/rs/rs_math.spec and generated test files
+        args.out = acospi(args.inVDouble, t);
+    }
+
     static public void computeNativeAcospi(TestNativeAcospi.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION, true);
+        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION);
         args.out = acospi(args.inV, t);
     }
 
+    static public void computeNativeAsin(TestNativeAsin.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(0, 0); // extraAllowedError set in fw/rs/rs_math.spec and generated test files
+        args.out = asin(args.inVDouble, t);
+    }
+
     static public void computeNativeAsin(TestNativeAsin.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION, true);
+        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION);
         args.out = asin(args.inV, t);
     }
 
+    static public void computeNativeAsinh(TestNativeAsinh.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(4, 4);
+        args.out = asinh(args.inVDouble, t);
+    }
+
     static public void computeNativeAsinh(TestNativeAsinh.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION, true);
+        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION);
         args.out = asinh(args.inV, t);
     }
 
+    static public void computeNativeAsinpi(TestNativeAsinpi.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(0, 0); // extraAllowedError set in fw/rs/rs_math.spec and generated test files
+        args.out = asinpi(args.inVDouble, t);
+    }
+
     static public void computeNativeAsinpi(TestNativeAsinpi.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION, true);
+        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION);
         args.out = asinpi(args.inV, t);
     }
 
+    static public void computeNativeAtan(TestNativeAtan.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(5, 5);
+        args.out = atan(args.inVDouble, t);
+    }
+
     static public void computeNativeAtan(TestNativeAtan.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION, true);
+        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION);
         args.out = atan(args.inV, t);
     }
 
+    static public void computeNativeAtanh(TestNativeAtanh.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(5, 5);
+        args.out = atanh(args.inVDouble, t);
+    }
+
     static public void computeNativeAtanh(TestNativeAtanh.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION, true);
+        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION);
         args.out = atanh(args.inV, t);
     }
 
+    static public void computeNativeAtanpi(TestNativeAtanpi.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(5, 5);
+        args.out = atanpi(args.inVDouble, t);
+    }
+
     static public void computeNativeAtanpi(TestNativeAtanpi.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION, true);
+        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION);
         args.out = atanpi(args.inV, t);
     }
 
+    static public void computeNativeAtan2(TestNativeAtan2.ArgumentsHalfHalfHalf args, Target t) {
+        t.setPrecision(5, 5);
+        args.out = atan2(args.inNumeratorDouble, args.inDenominatorDouble, t);
+    }
+
     static public void computeNativeAtan2(TestNativeAtan2.ArgumentsFloatFloatFloat args, Target t) {
-        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION, true);
+        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION);
         args.out = atan2(args.inNumerator, args.inDenominator, t);
     }
 
+    static public void computeNativeAtan2pi(TestNativeAtan2pi.ArgumentsHalfHalfHalf args, Target t) {
+        t.setPrecision(5, 5);
+        args.out = atan2pi(args.inNumeratorDouble, args.inDenominatorDouble, t);
+    }
+
     static public void computeNativeAtan2pi(TestNativeAtan2pi.ArgumentsFloatFloatFloat args, Target t) {
-        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION, true);
+        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION);
         args.out = atan2pi(args.inNumerator, args.inDenominator, t);
     }
 
+    static public void computeNativeCbrt(TestNativeCbrt.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(2, 2);
+        args.out = cbrt(args.inVDouble, t);
+    }
+
     static public void computeNativeCbrt(TestNativeCbrt.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION, true);
+        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION);
         args.out = cbrt(args.inV, t);
     }
 
+    static public void computeNativeCos(TestNativeCos.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(0, 0); // extraAllowedError set in fw/rs/rs_math.spec and generated test files
+        args.out = cos(args.inVDouble, t);
+    }
+
     static public void computeNativeCos(TestNativeCos.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION, true);
+        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION);
         args.out = cos(args.inV, t);
     }
 
+    static public void computeNativeCosh(TestNativeCosh.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(4, 4);
+        args.out = cosh(args.inVDouble, t);
+    }
+
     static public void computeNativeCosh(TestNativeCosh.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION, true);
+        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION);
         args.out = cosh(args.inV, t);
     }
 
+    static public void computeNativeCospi(TestNativeCospi.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(0, 0); // extraAllowedError set in fw/rs/rs_math.spec and generated test files
+        args.out = cospi(args.inVDouble, t);
+    }
+
     static public void computeNativeCospi(TestNativeCospi.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION, true);
+        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION);
         args.out = cospi(args.inV, t);
     }
 
+    static public void computeNativeDistance(TestNativeDistance.ArgumentsHalfHalfHalf args, Target t) {
+        t.setPrecision(1, 1);
+        args.out = distance(new double[] {args.inLeftVectorDouble},
+                            new double[] {args.inRightVectorDouble}, t);
+    }
+
+    static public void computeNativeDistance(TestNativeDistance.ArgumentsHalfNHalfNHalf args, Target t) {
+        t.setPrecision(1, 1);
+        args.out = distance(args.inLeftVectorDouble, args.inRightVectorDouble, t);
+    }
+
     static public void computeNativeDistance(TestNativeDistance.ArgumentsFloatFloatFloat args, Target t) {
-        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION, true);
+        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION);
         args.out = distance(new float[]{args.inLeftVector}, new float[]{args.inRightVector}, t);
     }
 
     static public void computeNativeDistance(TestNativeDistance.ArgumentsFloatNFloatNFloat args, Target t) {
-        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION, true);
+        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION);
         args.out = distance(args.inLeftVector, args.inRightVector, t);
     }
 
+    static public void computeNativeDivide(TestNativeDivide.ArgumentsHalfHalfHalf args, Target t) {
+        t.setPrecision(3, 3);
+        args.out = divide(args.inLeftVectorDouble, args.inRightVectorDouble, t);
+    }
+
     static public void computeNativeDivide(TestNativeDivide.ArgumentsFloatFloatFloat args, Target t) {
-        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION, true);
+        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION);
         args.out = t.divide(t.new32(args.inLeftVector), t.new32(args.inRightVector));
     }
 
+    static public void computeNativeExp(TestNativeExp.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(3, 3);
+        args.out = exp(args.inVDouble, t);
+    }
+
     static public void computeNativeExp(TestNativeExp.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION, true);
+        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION);
         args.out = exp(args.inV, t);
     }
 
+    static public void computeNativeExp10(TestNativeExp10.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(3, 3);
+        args.out = exp10(args.inVDouble, t);
+    }
+
     static public void computeNativeExp10(TestNativeExp10.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION, true);
+        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION);
         args.out = exp10(args.inV, t);
     }
 
+    static public void computeNativeExp2(TestNativeExp2.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(3, 3);
+        args.out = exp2(args.inVDouble, t);
+    }
+
     static public void computeNativeExp2(TestNativeExp2.ArgumentsFloatFloat args, Target t) {
         // TODO we would like to use NATIVE_PRECISION, NATIVE_PRECISION
-        t.setPrecision(13000, 13000, true);
+        t.setPrecision(13000, 13000);
         args.out = exp2(args.inV, t);
     }
 
+    static public String verifyNativeExpm1(TestNativeExpm1.ArgumentsHalfHalf args, Target t) {
+        // Acceptable error for native_expm1 is:
+        //     < 2^-11 in [-Inf, 0.6]
+        //     3 ulp outside
+        double extraAllowedError = 0.;
+        int ulpFactor;
+        if (args.inVDouble < 0.6) {
+            ulpFactor = 0;
+            extraAllowedError = 0.00048828125; // 2^-11
+        } else {
+            ulpFactor = 3;
+        }
+        t.setPrecision(ulpFactor, ulpFactor);
+
+        Target.Floaty expectedOut = expm1(args.inVDouble, t);
+        if (!expectedOut.couldBe(args.outDouble, extraAllowedError)) {
+            StringBuilder message = new StringBuilder();
+            message.append("Ulp Factor: " + Integer.toString(ulpFactor) + "\n");
+            message.append("Extra allowed error: " + Double.toString(extraAllowedError) + "\n");
+            message.append("Expected output out: " + expectedOut.toString() + "\n");
+            return message.toString();
+        }
+        return null;
+    }
+
     static public void computeNativeExpm1(TestNativeExpm1.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION, true);
+        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION);
         args.out = expm1(args.inV, t);
     }
 
+    static public void computeNativeHypot(TestNativeHypot.ArgumentsHalfHalfHalf args, Target t) {
+        t.setPrecision(4, 4);
+        args.out = hypot(args.inADouble, args.inBDouble, t);
+    }
+
     static public void computeNativeHypot(TestNativeHypot.ArgumentsFloatFloatFloat args, Target t) {
-        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION, true);
+        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION);
         args.out = hypot(args.inA, args.inB, t);
     }
 
+    static public void computeNativeLength(TestNativeLength.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(1, 1); // TODO double-check precision
+        args.out = length(new double[]{args.inVDouble}, t);
+    }
+
+    static public void computeNativeLength(TestNativeLength.ArgumentsHalfNHalf args, Target t) {
+        t.setPrecision(1, 1); // TODO double-check precision
+        args.out = length(args.inVDouble, t);
+    }
+
     static public void computeNativeLength(TestNativeLength.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION, true);
+        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION);
         args.out = length(new float[] {args.inV}, t);
     }
 
     static public void computeNativeLength(TestNativeLength.ArgumentsFloatNFloat args, Target t) {
-        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION, true);
+        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION);
         args.out = length(args.inV, t);
     }
 
+    static public void computeNativeLog(TestNativeLog.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(3, 3);
+        // http://b/27859722 Accept anything for zero.  Negative values don't get tested (see
+        // range() for this function in fw/rs/api/rs_math.spec.
+        if (Math.abs(args.inVDouble) < 1.e-20) {
+            args.out = any(t);
+        } else {
+            args.out = log(args.inVDouble, t);
+        }
+    }
+
     static public void computeNativeLog(TestNativeLog.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION, true);
+        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION);
         // For very small values, allow anything.
         if (Math.abs(args.inV) < 1.e-20) {
             args.out = any32(t);
@@ -1647,8 +2681,19 @@
         }
     }
 
+    static public void computeNativeLog10(TestNativeLog10.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(3, 3);
+        // http://b/27859722 Accept anything for zero.  Negative values don't get tested (see
+        // range() for this function in fw/rs/api/rs_math.spec.
+        if (Math.abs(args.inVDouble) < 1.e-20) {
+            args.out = any(t);
+        } else {
+            args.out = log10(args.inVDouble, t);
+        }
+    }
+
     static public void computeNativeLog10(TestNativeLog10.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION, true);
+        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION);
         // For very small values, allow anything.
         if (Math.abs(args.inV) < 1.e-20) {
             args.out = any32(t);
@@ -1657,13 +2702,29 @@
         }
     }
 
+    static public void computeNativeLog1p(TestNativeLog1p.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(2, 2);
+        args.out = log1p(args.inVDouble, t);
+    }
+
     static public void computeNativeLog1p(TestNativeLog1p.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION, true);
+        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION);
         args.out = log1p(args.inV, t);
     }
 
+    static public void computeNativeLog2(TestNativeLog2.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(3, 3);
+        // http://b/27859722 Accept anything for zero.  Negative values don't get tested (see
+        // range() for this function in fw/rs/api/rs_math.spec.
+        if (Math.abs(args.inVDouble) < 1.e-20) {
+            args.out = any(t);
+        } else {
+            args.out = log2(args.inVDouble, t);
+        }
+    }
+
     static public void computeNativeLog2(TestNativeLog2.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION, true);
+        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION);
         // For very small values, allow anything.
         if (Math.abs(args.inV) < 1.e-20) {
             args.out = any32(t);
@@ -1672,21 +2733,44 @@
         }
     }
 
+    static public void computeNativeNormalize(TestNativeNormalize.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(1, 1); // TODO double-check precision
+        Target.Floaty[] out = new Target.Floaty[1];
+        normalize(new double[] {args.inVDouble}, out, t);
+        args.out = out[0];
+    }
+
+    static public void computeNativeNormalize(TestNativeNormalize.ArgumentsHalfNHalfN args, Target t) {
+        t.setPrecision(1, 16); // TODO double-check precision.  Extra precision needed by libclcore.
+        normalize(args.inVDouble, args.out, t);
+    }
+
     static public void computeNativeNormalize(TestNativeNormalize.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION, true);
+        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION);
         Target.Floaty[] out = new Target.Floaty[1];
         normalize(new float[] {args.inV}, out, t);
         args.out = out[0];
     }
 
     static public void computeNativeNormalize(TestNativeNormalize.ArgumentsFloatNFloatN args, Target t) {
-        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION, true);
+        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION);
         normalize(args.inV, args.out, t);
     }
 
+    static public void computeNativePowr(TestNativePowr.ArgumentsHalfHalfHalf args, Target t) {
+        t.setPrecision(16, 16);
+        // http://b/27859722 Accept anything for zero.  Negative values don't get tested (see
+        // range() for this function in fw/rs/api/rs_math.spec.
+        if (Math.abs(args.inBaseDouble) < 1.e-20) {
+            args.out = any(t);
+        } else {
+            args.out = pow(args.inBaseDouble, args.inExponentDouble, t);
+        }
+    }
+
     static public void computeNativePowr(TestNativePowr.ArgumentsFloatFloatFloat args, Target t) {
         // TODO we would like to use NATIVE_PRECISION, NATIVE_PRECISION
-        t.setPrecision(32000, 32000, true);
+        t.setPrecision(32000, 32000);
         // For very small values, allow anything.
         if (Math.abs(args.inBase) < 1.e-20) {
             args.out = any32(t);
@@ -1695,13 +2779,18 @@
         }
     }
 
+    static public void computeNativeRecip(TestNativeRecip.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(3, 3);
+        args.out = recip(args.inVDouble, t);
+    }
+
     static public void computeNativeRecip(TestNativeRecip.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION, true);
+        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION);
         args.out = recip(args.inV, t);
     }
 
     static public void computeNativeRootn(TestNativeRootn.ArgumentsFloatIntFloat args, Target t) {
-        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION, true);
+        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION);
         // Allow anything for zero.
         if (args.inN == 0) {
             args.out = any32(t);
@@ -1710,71 +2799,182 @@
         }
     }
 
+    static public void computeNativeRsqrt(TestNativeRsqrt.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(2, 2);
+        args.out = rsqrt(args.inVDouble, t);
+    }
+
     static public void computeNativeRsqrt(TestNativeRsqrt.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION, true);
+        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION);
         args.out = rsqrt(args.inV, t);
     }
 
+    static public void computeNativeSin(TestNativeSin.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(0, 0); // extraAllowedError set in fw/rs/rs_math.spec and generated test files
+        args.out = sin(args.inVDouble, t);
+    }
+
     static public void computeNativeSin(TestNativeSin.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION, true);
+        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION);
         args.out = sin(args.inV, t);
     }
 
+    static public void computeNativeSincos(TestNativeSincos.ArgumentsHalfHalfHalf args, Target t) {
+        t.setPrecision(0, 0); // extraAllowedError set in fw/rs/rs_math.spec and generated test files
+        args.outCos = cos(args.inVDouble, t);
+        args.out = sin(args.inVDouble, t);
+    }
+
     static public void computeNativeSincos(TestNativeSincos.ArgumentsFloatFloatFloat args, Target t) {
-        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION, true);
+        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION);
         args.outCos = cos(args.inV, t);
         args.out = sin(args.inV, t);
     }
 
+    static public void computeNativeSinh(TestNativeSinh.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(4, 4);
+        args.out = sinh(args.inVDouble, t);
+    }
+
     static public void computeNativeSinh(TestNativeSinh.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION, true);
+        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION);
         args.out = sinh(args.inV, t);
     }
 
+    static public void computeNativeSinpi(TestNativeSinpi.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(0, 0); // extraAllowedError set in fw/rs/rs_math.spec and generated test files
+        args.out = sinpi(args.inVDouble, t);
+    }
+
     static public void computeNativeSinpi(TestNativeSinpi.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION, true);
+        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION);
         args.out = sinpi(args.inV, t);
     }
 
+    static public void computeNativeSqrt(TestNativeSqrt.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(3, 3);
+        args.out = sqrt(args.inVDouble, t);
+    }
+
     static public void computeNativeSqrt(TestNativeSqrt.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION, true);
+        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION);
         args.out = sqrt(args.inV, t);
     }
 
+    static public String verifyNativeTan(TestNativeTan.ArgumentsHalfHalf args, Target t) {
+        // Precision for native_tan is as follows:
+        //     For integral n:
+        //         8 ulp in [(n-0.45) pi, (n+0.45) pi]
+        //         2048 ulp in [(n+0.45) pi, (n+0.55) pi]"
+
+        // Compute the fractional part of args.inVDouble / pi
+        double absoluteValueOverPi = Math.abs(args.inVDouble) / Math.PI;
+        double fract = absoluteValueOverPi - Math.floor(absoluteValueOverPi);
+
+        int ulpFactor;
+        if (0.45 <= fract && fract <= 0.55) {
+            ulpFactor = 2048;
+        } else {
+            ulpFactor = 8;
+        }
+        t.setPrecision(ulpFactor, ulpFactor);
+
+        Target.Floaty expectedOut = tan(args.inVDouble, t);
+        if (!expectedOut.couldBe(args.outDouble)) {
+            StringBuilder message = new StringBuilder();
+            message.append("Ulp Factor: " + Integer.toString(ulpFactor) + "\n");
+            message.append("Expected output out: " + expectedOut.toString() + "\n");
+            return message.toString();
+        }
+
+        return null;
+    }
+
     static public void computeNativeTan(TestNativeTan.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION, true);
+        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION);
         args.out = tan(args.inV, t);
     }
 
+    static public void computeNativeTanh(TestNativeTanh.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(5, 5);
+        args.out = tanh(args.inVDouble, t);
+    }
+
     static public void computeNativeTanh(TestNativeTanh.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION, true);
+        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION);
         args.out = tanh(args.inV, t);
     }
 
+    static public String verifyNativeTanpi(TestNativeTanpi.ArgumentsHalfHalf args, Target t) {
+        // Precision for native_tan is as follows:
+        //     For integral n:
+        //         8 ulp in [(n-0.45), (n+0.45)]
+        //         2048 ulp in [(n+0.45), (n+0.55)]"
+
+        // Compute the fractional part of args.inVDouble
+        double absoluteValue = Math.abs(args.inVDouble);
+        double fract = absoluteValue - Math.floor(absoluteValue);
+
+        int ulpFactor;
+        if (0.45 <= fract && fract <= 0.55) {
+            ulpFactor = 2048;
+        } else {
+            ulpFactor = 8;
+        }
+        t.setPrecision(ulpFactor, ulpFactor);
+
+        Target.Floaty expectedOut = tanpi(args.inVDouble, t);
+        if (!expectedOut.couldBe(args.outDouble)) {
+            StringBuilder message = new StringBuilder();
+            message.append("Ulp Factor: " + Integer.toString(ulpFactor) + "\n");
+            message.append("Expected output out: " + expectedOut.toString() + "\n");
+            return message.toString();
+        }
+
+        return null;
+    }
+
     static public void computeNativeTanpi(TestNativeTanpi.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION, true);
+        t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION);
         args.out = tanpi(args.inV, t);
     }
 
     static public void computeNextafter(TestNextafter.ArgumentsFloatFloatFloat args, Target t) {
-        t.setPrecision(0, 0, false);
+        t.setPrecision(0, 0);
         args.out = t.new32(Math.nextAfter(args.inV, args.inTarget));
     }
 
+    static public void computeNormalize(TestNormalize.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(1, 1); // TODO double-check precision
+        Target.Floaty[] out = new Target.Floaty[1];
+        normalize(new double[] {args.inVDouble}, out, t);
+        args.out = out[0];
+    }
+
+    static public void computeNormalize(TestNormalize.ArgumentsHalfNHalfN args, Target t) {
+        t.setPrecision(1, 1); // TODO double-check precision
+        normalize(args.inVDouble, args.out, t);
+    }
+
     static public void computeNormalize(TestNormalize.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(1, 1, false);
+        t.setPrecision(1, 1);
         Target.Floaty[] out = new Target.Floaty[1];
         normalize(new float[] {args.inV}, out, t);
         args.out = out[0];
     }
 
     static public void computeNormalize(TestNormalize.ArgumentsFloatNFloatN args, Target t) {
-        t.setPrecision(1, 1, false);
+        t.setPrecision(1, 1);
         normalize(args.inV, args.out, t);
     }
 
+    static public void computePow(TestPow.ArgumentsHalfHalfHalf args, Target t) {
+        t.setPrecision(16, 16);
+        args.out = pow(args.inBaseDouble, args.inExponentDouble, t);
+    }
+
     static public void computePow(TestPow.ArgumentsFloatFloatFloat args, Target t) {
-        t.setPrecision(16, 128, false);
+        t.setPrecision(16, 128);
         Target.Floaty base = t.new32(args.inBase);
         Target.Floaty exponent = t.new32(args.inExponent);
         args.out = t.new32(
@@ -1785,8 +2985,13 @@
             pow(base.max32(), exponent.max32()));
     }
 
+    static public void computePown(TestPown.ArgumentsHalfIntHalf args, Target t) {
+        t.setPrecision(16, 16);
+        args.out = pow(args.inBaseDouble, (double) args.inExponent, t);
+    }
+
     static public void computePown(TestPown.ArgumentsFloatIntFloat args, Target t) {
-        t.setPrecision(16, 128, false);
+        t.setPrecision(16, 128);
         Target.Floaty in = t.new32(args.inBase);
         // We use double for the calculations because floats does not have enough
         // mantissa bits.  Knowing if an int is odd or even will matter for negative
@@ -1798,26 +3003,45 @@
             (float) Math.pow(in.max32(), y));
     }
 
+    static public void computePowr(TestPowr.ArgumentsHalfHalfHalf args, Target t) {
+        t.setPrecision(16, 16);
+        args.out = pow(args.inBaseDouble, args.inExponentDouble, t);
+    }
+
     static public void computePowr(TestPowr.ArgumentsFloatFloatFloat args, Target t) {
-        t.setPrecision(16, 128, false);
+        t.setPrecision(16, 128);
         args.out = powr(args.inBase, args.inExponent, t);
     }
 
+    static public void computeRadians(TestRadians.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(3, 3);
+        args.out = radians(args.inVDouble, t);
+    }
+
     static public void computeRadians(TestRadians.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(3, 3, false);
+        t.setPrecision(3, 3);
         Target.Floaty in = t.new32(args.inV);
         Target.Floaty k = t.new32((float)(Math.PI / 180.0));
         args.out = t.multiply(in, k);
     }
 
+    // NOTE: This function delegates to the floating-point version in libm.  Need to switch to the
+    // double-precision version later.
+    static public void computeRemainder(TestRemainder.ArgumentsHalfHalfHalf args, Target t) {
+        t.setPrecision(0, 0);
+        RemquoResult result = remquo((float) args.inNumeratorDouble,
+            (float) args.inDenominatorDouble);
+        args.out = t.newFloaty(result.remainder);
+    }
+
     static public void computeRemainder(TestRemainder.ArgumentsFloatFloatFloat args, Target t) {
-        t.setPrecision(0, 0, false);
+        t.setPrecision(0, 0);
         RemquoResult result = remquo(args.inNumerator, args.inDenominator);
         args.out = t.new32(result.remainder);
     }
 
     static public String verifyRemquo(TestRemquo.ArgumentsFloatFloatIntFloat args, Target t) {
-        t.setPrecision(0, 0, false);
+        t.setPrecision(0, 0);
         RemquoResult expected = remquo(args.inNumerator, args.inDenominator);
         // If the expected remainder is NaN, we don't validate the quotient.  It's because of
         // a division by zero.
@@ -1843,8 +3067,13 @@
         return null;
     }
 
+    static public void computeRint(TestRint.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(0, 0);
+        args.out = rint(args.inVDouble, t);
+    }
+
     static public void computeRint(TestRint.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(0, 0, false);
+        t.setPrecision(0, 0);
         Target.Floaty in = t.new32(args.inV);
         args.out = t.new32(
             rint(in.mid32()),
@@ -1853,12 +3082,17 @@
     }
 
     static public void computeRootn(TestRootn.ArgumentsFloatIntFloat args, Target t) {
-        t.setPrecision(16, 16, false);
+        t.setPrecision(16, 16);
         args.out = rootn(args.inV, args.inN, t);
     }
 
+    static public void computeRound(TestRound.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(0, 0);
+        args.out = round(args.inVDouble, t);
+    }
+
     static public void computeRound(TestRound.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(0, 0, false);
+        t.setPrecision(0, 0);
         Target.Floaty in = t.new32(args.inV);
         args.out = t.new32(
             round(in.mid32()),
@@ -1866,64 +3100,125 @@
             round(in.max32()));
     }
 
+    static public void computeRsqrt(TestRsqrt.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(2, 2);
+        args.out = rsqrt(args.inVDouble, t);
+    }
+
     static public void computeRsqrt(TestRsqrt.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(2, 2, false);
+        t.setPrecision(2, 2);
         args.out = rsqrt(args.inV, t);
     }
 
+    static public void computeSign(TestSign.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(0, 0);
+        args.out = t.newFloaty(Math.signum(args.inVDouble));
+    }
+
     static public void computeSign(TestSign.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(0, 0, false);
+        t.setPrecision(0, 0);
         args.out = t.new32(Math.signum(args.inV));
     }
 
+    static public void computeSin(TestSin.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(4, 4);
+        args.out = sin(args.inVDouble, t);
+    }
+
     static public void computeSin(TestSin.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(4, 128, false);
+        t.setPrecision(4, 128);
         args.out = sin(args.inV, t);
     }
 
+    static public void computeSincos(TestSincos.ArgumentsHalfHalfHalf args, Target t) {
+        t.setPrecision(4, 128);
+        args.outCos = cos(args.inVDouble, t );
+        args.out = sin(args.inVDouble, t);
+    }
+
     static public void computeSincos(TestSincos.ArgumentsFloatFloatFloat args, Target t) {
-        t.setPrecision(4, 128, false);
+        t.setPrecision(4, 128);
         args.outCos = cos(args.inV,t );
         args.out = sin(args.inV, t);
     }
 
+    static public void computeSinh(TestSinh.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(4, 4);
+        args.out = sinh(args.inVDouble, t);
+    }
+
     static public void computeSinh(TestSinh.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(4, 128, false);
+        t.setPrecision(4, 128);
         args.out = sinh(args.inV, t);
     }
 
+    static public void computeSinpi(TestSinpi.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(4, 4);
+        args.out = sinpi(args.inVDouble, t);
+    }
+
     static public void computeSinpi(TestSinpi.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(4, 128, false);
+        t.setPrecision(4, 128);
         args.out = sinpi(args.inV, t);
     }
 
+    static public void computeSqrt(TestSqrt.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(3, 3);
+        args.out = sqrt(args.inVDouble, t);
+    }
+
     static public void computeSqrt(TestSqrt.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(3, 3, false);
+        t.setPrecision(3, 3);
         args.out = sqrt(args.inV, t);
     }
 
+    static public void computeStep(TestStep.ArgumentsHalfHalfHalf args, Target t) {
+        t.setPrecision(0, 0);
+        args.out = step(args.inVDouble, args.inEdgeDouble, t);
+    }
+
     static public void computeStep(TestStep.ArgumentsFloatFloatFloat args, Target t) {
-        t.setPrecision(0, 0, false);
+        t.setPrecision(0, 0);
         args.out = t.new32(args.inV < args.inEdge ? 0.f : 1.f);
     }
 
+    static public void computeTan(TestTan.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(5, 5);
+        args.out = tan(args.inVDouble, t);
+    }
+
     static public void computeTan(TestTan.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(5, 128, false);
+        t.setPrecision(5, 128);
         args.out = tan(args.inV, t);
     }
 
+    static public void computeTanh(TestTanh.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(5, 5);
+        args.out = tanh(args.inVDouble, t);
+    }
+
     static public void computeTanh(TestTanh.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(5, 128, false);
+        t.setPrecision(5, 128);
         args.out = tanh(args.inV, t);
     }
 
+    static public void computeTanpi(TestTanpi.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(4, 4);
+        args.out = tanpi(args.inVDouble, t);
+    }
+
     static public void computeTanpi(TestTanpi.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(4, 128, false);
+        t.setPrecision(4, 128);
         args.out = tanpi(args.inV, t);
     }
 
+    static public void computeTgamma(TestTgamma.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(16, 16);
+        args.out = tgamma(args.inVDouble, t);
+    }
+
     static public void computeTgamma(TestTgamma.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(16, 128, false);
+        t.setPrecision(16, 128);
         Target.Floaty in = t.new32(args.inV);
         args.out = t.new32(
             tgamma(in.mid32()),
@@ -1931,8 +3226,13 @@
             tgamma(in.max32()));
     }
 
+    static public void computeTrunc(TestTrunc.ArgumentsHalfHalf args, Target t) {
+        t.setPrecision(0, 0);
+        args.out = trunc(args.inVDouble, t);
+    }
+
     static public void computeTrunc(TestTrunc.ArgumentsFloatFloat args, Target t) {
-        t.setPrecision(0, 0, false);
+        t.setPrecision(0, 0);
         Target.Floaty in = t.new32(args.inV);
         args.out = t.new32(
             trunc(in.mid32()),
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/DoubleTest.java b/tests/tests/renderscript/src/android/renderscript/cts/DoubleTest.java
index 2de6afd..2ff23fc 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/DoubleTest.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/DoubleTest.java
@@ -19,6 +19,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.Element;
 import android.renderscript.RenderScript;
+import android.renderscript.cts.Target;
 
 public class DoubleTest extends RSBaseCompute {
 
@@ -33,8 +34,8 @@
         float[] data = new float[big];
         out.copyTo(data);
 
-        Target t = new Target(true);
-        t.setPrecision(1, 1, false);
+        Target t = new Target(Target.FunctionType.NORMAL, Target.ReturnType.DOUBLE, true);
+        t.setPrecision(1, 1);
         double pi = 3.14159265359;
         Target.Floaty pi2 = t.new32((float) (pi * 2));
         for (int x = 0; x < data.length; x++) {
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/Float16ArithmeticTest.java b/tests/tests/renderscript/src/android/renderscript/cts/Float16ArithmeticTest.java
index 8f6d4a1..bc5410f 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/Float16ArithmeticTest.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/Float16ArithmeticTest.java
@@ -25,6 +25,7 @@
 import android.content.Context;
 import android.content.res.Resources;
 import android.renderscript.Allocation;
+import android.renderscript.cts.Float16Utils;
 import android.renderscript.Element;
 import android.renderscript.RenderScript;
 import android.renderscript.RSRuntimeException;
@@ -44,74 +45,6 @@
     // mU16Matrix
     private short[] output = new short[numInputs * numInputs];
 
-    // 16-bit masks for extracting sign, exponent and mantissa bits
-    private static short SIGN_MASK     = (short) 0x8000;
-    private static short EXPONENT_MASK = (short) 0x7C00;
-    private static short MANTISSA_MASK = (short) 0x03FF;
-
-    // NaN has all exponent bits set to 1 and a non-zero mantissa
-    private boolean isFloat16NaN(short val) {
-        return (val & EXPONENT_MASK) == EXPONENT_MASK &&
-               (val & MANTISSA_MASK) != 0;
-    }
-
-    // Infinity has all exponent bits set to 1 and zeroes in mantissa
-    private boolean isFloat16Infinite(short val) {
-        return (val & EXPONENT_MASK) == EXPONENT_MASK &&
-               (val & MANTISSA_MASK) == 0;
-    }
-
-    // Subnormal numbers have exponent bits set to 0 and a non-zero mantissa
-    private boolean isFloat16SubNormal(short val) {
-        return (val & EXPONENT_MASK) == 0 && (val & MANTISSA_MASK) != 0;
-    }
-
-    // Zero has all but the sign bit set to zero
-    private boolean isFloat16Zero(short val) {
-        return (val & ~SIGN_MASK) == 0;
-    }
-
-    // Negativity test checks the sign bit
-    private boolean isFloat16Negative(short val) {
-        return (val & SIGN_MASK) != 0;
-    }
-
-    // Check if this is a finite, non-zero FP16 value
-    private boolean isFloat16FiniteNonZero(short val) {
-        return !isFloat16NaN(val) && !isFloat16Infinite(val) && !isFloat16Zero(val);
-    }
-
-    // Convert FP16 value to float
-    private float convertFloat16ToFloat(short val) {
-        // Extract sign, exponent and mantissa
-        int sign = val & SIGN_MASK;
-        int exponent = (val & EXPONENT_MASK) >> 10;
-        int mantissa = val & MANTISSA_MASK;
-
-        // 0.<mantissa> = <mantissa> * 2^-10
-        float mantissaAsFloat = Math.scalb(mantissa, -10);
-
-        float result;
-        if (isFloat16Zero(val))
-            result = 0.0f;
-        else if (isFloat16Infinite(val))
-            result = java.lang.Float.POSITIVE_INFINITY;
-        else if (isFloat16NaN(val))
-            result = java.lang.Float.NaN;
-        else if (isFloat16SubNormal(val)) {
-            // value is 2^-14 * mantissaAsFloat
-            result = Math.scalb(1, -14) * mantissaAsFloat;
-        }
-        else {
-            // value is 2^(exponent - 15) * 1.<mantissa>
-            result = Math.scalb(1, exponent - 15) * (1 + mantissaAsFloat);
-        }
-
-        if (sign != 0)
-            result = -result;
-        return result;
-    }
-
     // Create input, intermediate, and output allocations.  Copy input data to
     // the input allocation
     private void setupTest() {
@@ -143,21 +76,23 @@
 
         // Do exact match if the reference value is a special case (Nan, zero
         // infinity or their negative equivalents).
-        if (isFloat16Infinite(lb))
+        if (Float16Utils.isFloat16Infinite(lb))
             return lb == out;
         // NaN can have any non-zero mantissa.  Do not use equality check
-        if (isFloat16NaN(lb))
-            return isFloat16NaN(out);
+        if (Float16Utils.isFloat16NaN(lb))
+            return Float16Utils.isFloat16NaN(out);
         // If reference output is zero, test for exact equivalence if at least
         // one of the input values is a special-case FP16 value.
-        if (isFloat16Zero(lb)) {
-            if (!isFloat16FiniteNonZero(in1) || !isFloat16FiniteNonZero(in2))
+        if (Float16Utils.isFloat16Zero(lb)) {
+            if (!Float16Utils.isFloat16FiniteNonZero(in1) ||
+                !Float16Utils.isFloat16FiniteNonZero(in2)) {
                 return lb == out;
+            }
         }
 
-        float floatLB = convertFloat16ToFloat(lb);
-        float floatUB = convertFloat16ToFloat(ub);
-        float floatOut = convertFloat16ToFloat(out);
+        float floatLB = Float16Utils.convertFloat16ToFloat(lb);
+        float floatUB = Float16Utils.convertFloat16ToFloat(ub);
+        float floatOut = Float16Utils.convertFloat16ToFloat(out);
 
         if (floatOut < floatLB || floatOut > floatUB) {
             StringBuilder message = new StringBuilder();
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/Float16Utils.java b/tests/tests/renderscript/src/android/renderscript/cts/Float16Utils.java
new file mode 100644
index 0000000..05d0e80
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/Float16Utils.java
@@ -0,0 +1,320 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.renderscript.cts;
+
+import android.renderscript.RSRuntimeException;
+import android.util.Log;
+
+import junit.framework.Assert;
+
+/** This class contains utility functions needed by RenderScript CTS tests to handle Float16
+ * operations.
+ */
+class Float16Utils {
+    // 16-bit masks for extracting sign, exponent and mantissa bits
+    private static short SIGN_MASK     = (short) 0x8000;
+    private static short EXPONENT_MASK = (short) 0x7C00;
+    private static short MANTISSA_MASK = (short) 0x03FF;
+
+    private static long DOUBLE_SIGN_MASK = 0x8000000000000000L;
+    private static long DOUBLE_EXPONENT_MASK = 0x7ff0000000000000L;
+    private static long DOUBLE_MANTISSA_MASK = 0x000fffffffffffffL;
+
+    static double MIN_NORMAL = Math.scalb(1.0, -14); // smallest Float16 normal is 2 ^ -14
+    static double MIN_VALUE = Math.scalb(1.0, -24); // smallest Float16 value is 2 ^ -24
+    static double MAX_VALUE = 65504; // largest Float16 value is 2^16 - 32
+
+    // NaN has all exponent bits set to 1 and a non-zero mantissa
+    static boolean isFloat16NaN(short val) {
+        return (val & EXPONENT_MASK) == EXPONENT_MASK &&
+               (val & MANTISSA_MASK) != 0;
+    }
+
+    // Infinity has all exponent bits set to 1 and zeroes in mantissa
+    static boolean isFloat16Infinite(short val) {
+        return (val & EXPONENT_MASK) == EXPONENT_MASK &&
+               (val & MANTISSA_MASK) == 0;
+    }
+
+    // Subnormal numbers have exponent bits set to 0 and a non-zero mantissa
+    static boolean isFloat16SubNormal(short val) {
+        return (val & EXPONENT_MASK) == 0 && (val & MANTISSA_MASK) != 0;
+    }
+
+    // Zero has all but the sign bit set to zero
+    static boolean isFloat16Zero(short val) {
+        return (val & ~SIGN_MASK) == 0;
+    }
+
+    // Negativity test checks the sign bit
+    static boolean isFloat16Negative(short val) {
+        return (val & SIGN_MASK) != 0;
+    }
+
+    // Check if this is a finite, non-zero FP16 value
+    static boolean isFloat16FiniteNonZero(short val) {
+        return !isFloat16NaN(val) && !isFloat16Infinite(val) && !isFloat16Zero(val);
+    }
+
+    static float convertFloat16ToFloat(short val) {
+        // Extract sign, exponent and mantissa
+        int sign = val & SIGN_MASK;
+        int exponent = (val & EXPONENT_MASK) >> 10;
+        int mantissa = val & MANTISSA_MASK;
+
+        // 0.<mantissa> = <mantissa> * 2^-10
+        float mantissaAsFloat = Math.scalb(mantissa, -10);
+
+        float result;
+        if (isFloat16Zero(val))
+            result = 0.0f;
+        else if (isFloat16Infinite(val))
+            result = java.lang.Float.POSITIVE_INFINITY;
+        else if (isFloat16NaN(val))
+            result = java.lang.Float.NaN;
+        else if (isFloat16SubNormal(val)) {
+            // value is 2^-14 * mantissaAsFloat
+            result = Math.scalb(1, -14) * mantissaAsFloat;
+        }
+        else {
+            // value is 2^(exponent - 15) * 1.<mantissa>
+            result = Math.scalb(1, exponent - 15) * (1 + mantissaAsFloat);
+        }
+
+        if (sign != 0)
+            result = -result;
+        return result;
+    }
+
+    static double convertFloat16ToDouble(short val) {
+        return (double) convertFloat16ToFloat(val);
+    }
+
+    /* This utility function accepts the mantissa, exponent and an isNegative flag and constructs a
+     * double value.  The exponent should be biased, but not shifted left by 52-bits.
+     */
+    private static double constructDouble(long mantissa, long exponent, boolean isNegative) {
+        exponent = exponent << 52;
+        long bits = (exponent & DOUBLE_EXPONENT_MASK) | (mantissa & DOUBLE_MANTISSA_MASK);
+        if (isNegative) bits |= DOUBLE_SIGN_MASK;
+        return Double.longBitsToDouble(bits);
+    }
+
+    /* This function takes a double value and returns an array with the double representations of
+     * the Float16 values immediately smaller and larger than the input.  If the input value is
+     * precisely representable in Float16, it is copied into both the entries of the array.
+     *
+     * The returned values can be subnormal Float16 numbers.  Handling subnormals is delegated to
+     * the caller.
+     *
+     * TODO Extend this function to handle rounding for both float16 and float32.
+     */
+    static double[] roundToFloat16(double value) {
+        long valueBits = Double.doubleToLongBits(value);
+        long mantissa = valueBits & DOUBLE_MANTISSA_MASK; // 52-bit mantissa
+        long exponent = valueBits & DOUBLE_EXPONENT_MASK; // 11-bit exponent
+        long unbiasedExponent = (exponent >> 52) - 1023;
+        boolean isNegative = (valueBits & DOUBLE_SIGN_MASK) != 0;
+
+        double[] result = new double[2];
+        if (Double.isNaN(value) || Double.isInfinite(value)) {
+            // Input is NaN or Infinity.  Return unchanged.
+            result[0] = value;
+            result[1] = value;
+            return result; // Note that we skip the negation at the end of this function
+        }
+
+        if (unbiasedExponent == -1023 && mantissa == 0) {
+            // Zero.  Assign 0 and adjust sign at the end of this function
+            result[0] = 0.;
+            result[1] = 0.;
+        }
+        else if (unbiasedExponent < -24) {
+            // Absolute value is between 0 and MIN_VALUE.  Return 0 and MIN_VALUE
+            result[0] = 0.;
+            result[1] = MIN_VALUE;
+        }
+        else if (unbiasedExponent <= 15) {
+            /*
+             * Either subnormal or normal.  We compute a mask for the excess precision bits in the
+             * mantissa.
+             *
+             * (a) If none of these bits are set, the current value's mantissa and exponent are used
+             * for both the low and high values.
+             * (b) If some of these bits are set, we zero-out the extra bits to get the mantissa and
+             * exponent of the lower value.  For the higher value, we increment the masked mantissa
+             * at the least-significant bit within the range of this Float16 value.  To handle
+             * overflows during the the increment, we need to increment the exponent and round up to
+             * infinity if needed.
+             */
+
+            // 'mask' is used to detect and zero-out excess bits set.  'mask + 1' is the value
+            // added to zero-ed out mantissa to get the next higher Float16 value.
+            long mask;
+            long maxSigMantissaBits;
+
+            if (unbiasedExponent < -14) {
+                // Subnormal Float16.  For Float16's MIN_VALUE, mantissa can have no bits set (after
+                // adjusting for the implied one bit.  For each higher exponent, an extra bit of
+                // precision is allowed in the mantissa.  This computes to "24 + unbiasedExponent".
+                maxSigMantissaBits = 24 + unbiasedExponent;
+            } else {
+                // For normal Float16 values have 10 bits of precision in the mantissa.
+                maxSigMantissaBits = 10;
+            }
+            mask = DOUBLE_MANTISSA_MASK >> maxSigMantissaBits;
+
+            // zero-out the excess precision bits for the mantissa for both low and high values.
+            long lowFloat16Mantissa = mantissa & ~mask;
+            long highFloat16Mantissa = mantissa & ~mask;
+
+            long lowFloat16Exponent = unbiasedExponent;
+            long highFloat16Exponent = unbiasedExponent;
+
+            if ((mantissa & mask) != 0) {
+                // If mantissa has extra bits set, increment the mantissa at the LSB (for this
+                // Float16 value)
+                highFloat16Mantissa += mask + 1;
+
+                // If this overflows the mantissa into the exponent, set mantissa to zero and
+                // increment the exponent.
+                if ((highFloat16Mantissa & DOUBLE_EXPONENT_MASK) != 0) {
+                    highFloat16Mantissa = 0;
+                    highFloat16Exponent += 1;
+                }
+
+                // If the exponent exceeds the range of Float16 exponents, set it to 1024, so the
+                // value gets rounded up to Double.POSITIVE_INFINITY.
+                if (highFloat16Exponent == 16) {
+                    highFloat16Exponent = 1024;
+                }
+            }
+
+            result[0] = constructDouble(lowFloat16Mantissa, lowFloat16Exponent + 1023, false);
+            result[1] = constructDouble(highFloat16Mantissa, highFloat16Exponent + 1023, false);
+        } else {
+            // Exponent is outside Float16's range.  Use POSITIVE_INFINITY for both bounds.
+            result[0] = Double.POSITIVE_INFINITY;
+            result[1] = Double.POSITIVE_INFINITY;
+        }
+
+        // Swap values in result and negate them if the input value is negative.
+        if (isNegative) {
+            double tmp = result[0];
+            result[0] = -result[1];
+            result[1] = -tmp;
+        }
+
+        return result;
+    }
+
+    // This function takes a double value and returns 1 ulp, in Float16 precision, of that value.
+    // Both the parameter and return value have 'double' type but they should be exactly
+    // representable in Float16.  If the parameter exceeds the precision of Float16, an exception is
+    // thrown.
+    static double float16Ulp(double value) {
+        long valueBits = Double.doubleToLongBits(value);
+        long mantissa = valueBits & DOUBLE_MANTISSA_MASK; // 52-bit mantissa
+        long exponent = valueBits & DOUBLE_EXPONENT_MASK; // 11-bit exponent
+        long unbiasedExponent = (exponent >> 52) - 1023;
+
+        if (unbiasedExponent == 1024) { // i.e. NaN or infinity
+            if (mantissa == 0) {
+                return Double.POSITIVE_INFINITY; // ulp of +/- infinity is +infinity
+            } else {
+                return Double.NaN; // ulp for NaN is NaN
+            }
+        }
+
+        if (unbiasedExponent == -1023) {
+            // assert that mantissa is zero, i.e. value is zero and not a subnormal value.
+            if (mantissa != 0) {
+                throw new RSRuntimeException("float16ulp: Double parameter is subnormal");
+            }
+            return MIN_VALUE;
+        }
+
+        if (unbiasedExponent < -24 || unbiasedExponent > 15) {
+            throw new RSRuntimeException("float16Ulp: Double parameter's exponent out of range");
+        }
+
+        if (unbiasedExponent >= -24 && unbiasedExponent < -14) {
+            // Exponent within the range of Float16 subnormals.
+
+            // Ensure that mantissa doesn't have too much precision.  For example, the smallest
+            // normal number has an unbiased exponent of -24 and has one bit in mantissa.  Each
+            // higher exponent allows one extra bit of precision in the mantissa.  Combined with the
+            // implied one bit, the mantissa can have "24 + unbiasedExponent" significant bits.  The
+            // rest of the 52 bits in mantissa must be zero.
+
+            long maxSigMantissaBits = 24 + unbiasedExponent;
+            long mask = DOUBLE_MANTISSA_MASK >> maxSigMantissaBits;
+
+            if((mask & mantissa) != 0) {
+                throw new RSRuntimeException("float16ulp: Double parameter is too precise for subnormal Float16 values.");
+            }
+            return MIN_VALUE;
+        }
+        if (unbiasedExponent >= -14) {
+            // Exponent within the range of Float16 normals.  Ensure that the mantissa has at most
+            // 10 significant bits.
+            long mask = DOUBLE_MANTISSA_MASK >> 10;
+            if ((mantissa & mask) != 0) {
+                throw new RSRuntimeException("float16ulp: Double parameter is too precise for normal Float16 values.");
+            }
+            return Math.scalb(1.0, (int) (unbiasedExponent - 10));
+        }
+        throw new RSRuntimeException("float16Ulp: unreachable line executed");
+    }
+
+    // This function converts its double input value to its Float16 representation (represented as a
+    // short).  It assumes, but does not check, that the input is precisely representable in Float16
+    // precision.  No rounding is performed either.
+    static short convertDoubleToFloat16(double value) {
+        if (value == 0.) {
+            if (Double.doubleToLongBits(value) == 0)
+                return (short) 0x0;
+            else
+                return (short) 0x8000;
+        } else if (Double.isNaN(value)) {
+            // return Quiet NaN irrespective of what kind of NaN 'value' is.
+            return (short) 0x7e00;
+        } else if (value == Double.POSITIVE_INFINITY) {
+            return (short) 0x7c00;
+        } else if (value == Double.NEGATIVE_INFINITY) {
+            return (short) 0xfc00;
+        }
+
+        double positiveValue = Math.abs(value);
+        boolean isNegative = (value < 0.);
+        if (positiveValue < MIN_NORMAL) {
+            short quotient = (short) (positiveValue / MIN_VALUE);
+            return (isNegative) ? (short) (0x8000 | quotient) : quotient;
+        } else {
+            long valueBits = Double.doubleToLongBits(value);
+            long mantissa = valueBits & DOUBLE_MANTISSA_MASK; // 52-bit mantissa
+            long exponent = valueBits & DOUBLE_EXPONENT_MASK; // 11-bit exponent
+            long unbiasedExponent = (exponent >> 52) - 1023;
+
+            short halfExponent = (short) ((unbiasedExponent + 15) << 10);
+            short halfMantissa = (short) (mantissa >> 42);
+            short halfValue = (short) (halfExponent | halfMantissa);
+            return (isNegative) ? (short) (0x8000 | halfValue) : halfValue;
+        }
+    }
+
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/FloatyUnitTest.java b/tests/tests/renderscript/src/android/renderscript/cts/FloatyUnitTest.java
new file mode 100644
index 0000000..5e7a916
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/FloatyUnitTest.java
@@ -0,0 +1,560 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.renderscript.cts;
+
+import android.renderscript.cts.Target;
+import android.renderscript.cts.Float16Utils;
+import android.renderscript.RSRuntimeException;
+import android.util.Log;
+
+public class FloatyUnitTest extends RSBaseCompute {
+    static float subnormalFloat = 10000 * Float.MIN_VALUE;
+    static float normalFloat1 = 1.7833920e+16f;
+    static float normalFloat2 = -1.9905756e-16f;
+
+    static double subnormalDouble = 10000 * Double.MIN_VALUE;
+    static double normalDouble = 1.7833920e+16;
+
+    static double normalHalf = 1985; // 2048 - 63.  Magic number chosen for use in testHalf128Ulp
+    static double negativeNormalHalf = -237;
+
+    // Some double values that are precisely representable in half-precision.
+    static double[] preciseFloat16Values = {Double.NaN,
+                                            Double.POSITIVE_INFINITY,
+                                            Double.NEGATIVE_INFINITY,
+                                            0., 1, 2, 74.0625, 3000, 65504,
+                                            Float16Utils.MIN_VALUE,
+                                            Float16Utils.MIN_VALUE * 100,
+                                            -0., -1, -2, -74.0625, -3000, -65504,
+                                            -Float16Utils.MIN_VALUE,
+                                            -Float16Utils.MIN_VALUE * 100,
+                                           };
+
+    // Fail if Floaty f with an extra error allowance of 'extraAllowedError' doesn't accept 'value'
+    private void shouldAccept(Target.Floaty f, double value, double extraAllowedError) {
+        if (!f.couldBe(value, extraAllowedError)) {
+            StringBuilder message = new StringBuilder();
+            message.append("Floaty: ");
+            appendVariableToMessage(message, f);
+            message.append("\n");
+            if (extraAllowedError > 0.) {
+                message.append("extraAllowedError: ");
+                appendVariableToMessage(message, extraAllowedError);
+                message.append("\n");
+            }
+            message.append("Value: ");
+            appendVariableToMessage(message, (float) value);
+            message.append("\n");
+            assertTrue("Floaty incorrectly doesn't accept value:\n" + message.toString(), false);
+        }
+    }
+
+    // Fail if Floaty f doesn't accept value
+    private void shouldAccept(Target.Floaty f, double value) {
+        shouldAccept(f, value, 0.);
+    }
+
+    // Fail if Floaty f with an extra error allowance of 'extraAllowedError' accepts 'value'
+    private void shouldNotAccept(Target.Floaty f, double value, double extraAllowedError) {
+        if (f.couldBe(value)) {
+            StringBuilder message = new StringBuilder();
+            message.append("Floaty: ");
+            appendVariableToMessage(message, f);
+            message.append("\n");
+            if (extraAllowedError > 0.) {
+                message.append("extraAllowedError: ");
+                appendVariableToMessage(message, extraAllowedError);
+                message.append("\n");
+            }
+            message.append("Value: ");
+            appendVariableToMessage(message, (float) value);
+            message.append("\n");
+            assertTrue("Floaty incorrectly accepts value:\n" + message.toString(), false);
+        }
+    }
+
+    // Fail if Floaty f accepts value
+    private void shouldNotAccept(Target.Floaty f, double value) {
+        shouldNotAccept(f, value, 0.);
+    }
+
+    // Test Target that accepts precise 1ulp error for floating values.
+    public void testFloat1Ulp() {
+        Target t = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, false);
+        t.setPrecision(1, 1);
+
+        Target.Floaty subnormalFloaty = t.new32(subnormalFloat);
+        Target.Floaty normalFloaty = t.new32(normalFloat1);
+
+        // for subnormal
+        shouldAccept(subnormalFloaty, (double) subnormalFloat);
+        shouldAccept(subnormalFloaty, (double) subnormalFloat + Math.ulp(subnormalFloat));
+        shouldAccept(subnormalFloaty, (double) subnormalFloat - Math.ulp(subnormalFloat));
+        shouldNotAccept(subnormalFloaty, (double) subnormalFloat + 2 * Math.ulp(subnormalFloat));
+        shouldNotAccept(subnormalFloaty, (double) subnormalFloat - 2 * Math.ulp(subnormalFloat));
+        shouldNotAccept(subnormalFloaty, (double) normalFloat1);
+
+        // for normalFloaty
+        shouldAccept(normalFloaty, (double) normalFloat1);
+        shouldAccept(normalFloaty, (double) normalFloat1 + Math.ulp(normalFloat1));
+        shouldAccept(normalFloaty, (double) normalFloat1 - Math.ulp(normalFloat1));
+        shouldNotAccept(normalFloaty, (double) normalFloat1 + 2 * Math.ulp(normalFloat1));
+        shouldNotAccept(normalFloaty, (double) normalFloat1 - 2 * Math.ulp(normalFloat1));
+        shouldNotAccept(normalFloaty, (double) subnormalFloat);
+    }
+
+    // Test Target that accepts precise 8192ulp error for floating values.
+    public void testFloat8192Ulp() {
+        Target t = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, false);
+        t.setPrecision(8192, 8192);
+
+        Target.Floaty subnormalFloaty = t.new32(subnormalFloat);
+        Target.Floaty normalFloaty = t.new32(normalFloat2);
+
+        // for subnormalFloaty
+        shouldAccept(subnormalFloaty, (double) subnormalFloat);
+        shouldAccept(subnormalFloaty, (double) subnormalFloat + 8192 * Math.ulp(subnormalFloat));
+        shouldAccept(subnormalFloaty, (double) subnormalFloat - 8192 * Math.ulp(subnormalFloat));
+        shouldNotAccept(subnormalFloaty, (double) subnormalFloat + 8193 * Math.ulp(subnormalFloat));
+        shouldNotAccept(subnormalFloaty, (double) subnormalFloat - 8193 * Math.ulp(subnormalFloat));
+        shouldNotAccept(subnormalFloaty, (double) normalFloat1);
+
+        // for normalFloaty
+        shouldAccept(normalFloaty, (double) normalFloat2);
+        shouldAccept(normalFloaty, (double) normalFloat2 + 8192 * Math.ulp(normalFloat2));
+        shouldAccept(normalFloaty, (double) normalFloat2 - 8192 * Math.ulp(normalFloat2));
+        shouldNotAccept(normalFloaty, (double) normalFloat2 + 8193 * Math.ulp(normalFloat2));
+        shouldNotAccept(normalFloaty, (double) normalFloat2 - 8193 * Math.ulp(normalFloat2));
+        shouldNotAccept(normalFloaty, (double) subnormalFloat);
+    }
+
+    // Test Target that accepts relaxed 1ulp error for floating values.
+    public void testFloat1UlpRelaxed() {
+        Target t = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, true);
+        t.setPrecision(1, 1);
+
+        Target.Floaty subnormalFloaty = t.new32(subnormalFloat);
+
+        // for subnormal
+        shouldAccept(subnormalFloaty, (double) subnormalFloat);
+        // In relaxed mode, Floaty uses the smallest normal as the ULP if ULP is subnormal.
+        shouldAccept(subnormalFloaty, (double) Float.MIN_NORMAL + Float.MIN_NORMAL);
+        shouldAccept(subnormalFloaty, (double) 0.f - Float.MIN_NORMAL);
+        shouldNotAccept(subnormalFloaty, (double) Float.MIN_NORMAL + 2 * Float.MIN_NORMAL);
+        shouldNotAccept(subnormalFloaty, (double) 0.f - 2 * Float.MIN_NORMAL);
+        shouldNotAccept(subnormalFloaty, (double) normalFloat1);
+    }
+
+    // Test Target that accepts relaxed 8192ulp error for floating values.
+    public void testFloat8192UlpRelaxed() {
+        Target t = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, true);
+        t.setPrecision(8192, 8192);
+
+        Target.Floaty subnormalFloaty = t.new32(subnormalFloat);
+
+        // for subnormalFloaty
+        shouldAccept(subnormalFloaty, (double) subnormalFloat);
+        // In relaxed mode, Floaty uses the smallest normal as the ULP if ULP is subnormal.
+        shouldAccept(subnormalFloaty, (double) Float.MIN_NORMAL + 8192 * Float.MIN_NORMAL);
+        shouldAccept(subnormalFloaty, (double) 0.f - 8192 * Float.MIN_NORMAL);
+        shouldNotAccept(subnormalFloaty, (double) Float.MIN_NORMAL + 8193 * Float.MIN_NORMAL);
+        shouldNotAccept(subnormalFloaty, (double) 0.f - 8193 * Float.MIN_NORMAL);
+        shouldNotAccept(subnormalFloaty, (double) normalFloat1);
+    }
+
+    // Test Target that accepts precise 1ulp error for double values.
+    public void testDouble1Ulp() {
+        Target t = new Target(Target.FunctionType.NORMAL, Target.ReturnType.DOUBLE, false);
+        t.setPrecision(1, 1);
+
+        Target.Floaty subnormalFloaty = t.new64(subnormalDouble);
+        Target.Floaty normalFloaty = t.new64(normalDouble);
+
+        // for subnormal
+        shouldAccept(subnormalFloaty, subnormalDouble);
+        shouldAccept(subnormalFloaty, subnormalDouble + Math.ulp(subnormalDouble));
+        shouldAccept(subnormalFloaty, subnormalDouble - Math.ulp(subnormalDouble));
+        shouldNotAccept(subnormalFloaty, subnormalDouble + 2 * Math.ulp(subnormalDouble));
+        shouldNotAccept(subnormalFloaty, subnormalDouble - 2 * Math.ulp(subnormalDouble));
+        shouldNotAccept(subnormalFloaty, normalDouble);
+
+        // for normalFloaty
+        shouldAccept(normalFloaty, normalDouble);
+        shouldAccept(normalFloaty, normalDouble + Math.ulp(normalDouble));
+        shouldAccept(normalFloaty, normalDouble - Math.ulp(normalDouble));
+        shouldNotAccept(normalFloaty, normalDouble + 2 * Math.ulp(normalDouble));
+        shouldNotAccept(normalFloaty, normalDouble - 2 * Math.ulp(normalDouble));
+        shouldNotAccept(normalFloaty, subnormalDouble);
+    }
+
+    // Test Target that accepts precise 8192ulp error for double values.
+    public void testDouble8192Ulp() {
+        Target t = new Target(Target.FunctionType.NORMAL, Target.ReturnType.DOUBLE, false);
+        t.setPrecision(8192, 8192);
+
+        Target.Floaty subnormalFloaty = t.new64(subnormalDouble);
+        Target.Floaty normalFloaty = t.new64(normalDouble);
+
+        // for subnormal
+        shouldAccept(subnormalFloaty, subnormalDouble);
+        shouldAccept(subnormalFloaty, subnormalDouble + 8192 * Math.ulp(subnormalDouble));
+        shouldAccept(subnormalFloaty, subnormalDouble - 8192 * Math.ulp(subnormalDouble));
+        shouldNotAccept(subnormalFloaty, subnormalDouble + 8193 * Math.ulp(subnormalDouble));
+        shouldNotAccept(subnormalFloaty, subnormalDouble - 8193 * Math.ulp(subnormalDouble));
+        shouldNotAccept(subnormalFloaty, normalDouble);
+
+        // for normalFloaty
+        shouldAccept(normalFloaty, normalDouble);
+        shouldAccept(normalFloaty, normalDouble + 8192 * Math.ulp(normalDouble));
+        shouldAccept(normalFloaty, normalDouble - 8192 * Math.ulp(normalDouble));
+        shouldNotAccept(normalFloaty, normalDouble + 8193 * Math.ulp(normalDouble));
+        shouldNotAccept(normalFloaty, normalDouble - 8193 * Math.ulp(normalDouble));
+        shouldNotAccept(normalFloaty, subnormalDouble);
+    }
+
+    // Test Target that accepts precise 1ulp error for half values.
+    public void testHalf1Ulp() {
+        Target t = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, false);
+        t.setPrecision(1, 1);
+
+        Target.Floaty normalFloaty = t.newFloaty(normalHalf);
+        shouldAccept(normalFloaty, normalHalf);
+        shouldAccept(normalFloaty, normalHalf + Float16Utils.float16Ulp(normalHalf));
+        shouldAccept(normalFloaty, normalHalf - Float16Utils.float16Ulp(normalHalf));
+        shouldNotAccept(normalFloaty, normalHalf + 2 * Float16Utils.float16Ulp(normalHalf));
+        shouldNotAccept(normalFloaty, normalHalf - 2 * Float16Utils.float16Ulp(normalHalf));
+        shouldNotAccept(normalFloaty, 2500);
+    }
+
+    // Test Target that accepts precise 128ulp error for half values.
+    public void testHalf128Ulp() {
+        Target t = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, false);
+        t.setPrecision(128, 128);
+
+        Target.Floaty normalFloaty = t.newFloaty(normalHalf);
+        shouldAccept(normalFloaty, normalHalf);
+        shouldAccept(normalFloaty, normalHalf + 128 * Float16Utils.float16Ulp(normalHalf));
+        shouldAccept(normalFloaty, normalHalf - 128 * Float16Utils.float16Ulp(normalHalf));
+        shouldNotAccept(normalFloaty, normalHalf - 129 * Float16Utils.float16Ulp(normalHalf));
+
+        // Since normalHalf + 128ULP has a higher exponent, Floaty accepts an extra ULP to maintin
+        // the invariant that the range is always precisely representable in Float16.
+        shouldAccept(normalFloaty, normalHalf + 129 * Float16Utils.float16Ulp(normalHalf));
+        shouldNotAccept(normalFloaty, normalHalf + 130 * Float16Utils.float16Ulp(normalHalf));
+        shouldNotAccept(normalFloaty, 2500);
+    }
+
+    public void testExtraAllowedError() {
+        Target t;
+        double extraError, lb, ub;
+
+        t = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, false);
+        t.setPrecision(4, 4);
+
+        // Test normal float value with extraAllowedError
+        extraError = 1e-15;
+        Target.Floaty normalFloaty = t.newFloaty(normalFloat2);
+        ub = normalFloat2 + 4 * Math.ulp(normalFloat2) + extraError;
+        lb = normalFloat2 - 4 * Math.ulp(normalFloat2) - extraError;
+        shouldAccept(normalFloaty, ub, extraError);
+        shouldAccept(normalFloaty, lb, extraError);
+        shouldNotAccept(normalFloaty, ub + Math.ulp(ub), extraError);
+        shouldNotAccept(normalFloaty, lb - Math.ulp(lb), extraError);
+
+        t = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, false);
+        t.setPrecision(2, 2);
+        extraError = Float.MIN_VALUE;
+
+        // Test subnormal float value with extraAllowedError
+        Target.Floaty subnormalFloaty = t.newFloaty(subnormalFloat);
+        ub = subnormalFloat + 2 * Math.ulp(subnormalFloat) + extraError;
+        lb = subnormalFloat - 2 * Math.ulp(subnormalFloat) - extraError;
+        shouldAccept(subnormalFloaty, ub, extraError);
+        shouldAccept(subnormalFloaty, lb, extraError);
+        shouldNotAccept(subnormalFloaty, ub + Math.ulp(ub), extraError);
+        shouldNotAccept(subnormalFloaty, lb - Math.ulp(lb), extraError);
+
+        t = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, false);
+        t.setPrecision(0, 0);
+
+        // Test Float16 with extraAllowedError in same order of magnitude
+        extraError = 2.0;
+        Target.Floaty halfFloaty = t.newFloaty(normalHalf);
+        ub = normalHalf + extraError;
+        lb = normalHalf - extraError;
+        shouldAccept(halfFloaty, ub, extraError);
+        shouldAccept(halfFloaty, lb, extraError);
+        shouldNotAccept(halfFloaty, ub + Float16Utils.float16Ulp(ub), extraError);
+        shouldNotAccept(halfFloaty, lb - Float16Utils.float16Ulp(lb), extraError);
+
+        // Test Float16 with a tiny extraAllowedError
+        extraError = Float16Utils.MIN_NORMAL;
+        ub = normalHalf;
+        lb = normalHalf;
+        shouldAccept(halfFloaty, ub, extraError);
+        shouldAccept(halfFloaty, lb, extraError);
+        shouldNotAccept(halfFloaty, ub + Float16Utils.float16Ulp(ub), extraError);
+        shouldNotAccept(halfFloaty, lb - Float16Utils.float16Ulp(lb), extraError);
+
+        // Test negative Float16 with extraAllowedError in same order of magnitude
+        extraError = 2.0;
+        Target.Floaty negativeHalfFloaty = t.newFloaty(negativeNormalHalf);
+        ub = negativeNormalHalf + extraError;
+        lb = negativeNormalHalf - extraError;
+        shouldAccept(negativeHalfFloaty, ub, extraError);
+        shouldAccept(negativeHalfFloaty, lb, extraError);
+        shouldNotAccept(negativeHalfFloaty, ub + Float16Utils.float16Ulp(ub), extraError);
+        shouldNotAccept(negativeHalfFloaty, lb - Float16Utils.float16Ulp(lb), extraError);
+
+        // Test negative Float16 with a tiny extraAllowedError
+        extraError = Float16Utils.MIN_NORMAL;
+        ub = negativeNormalHalf;
+        lb = negativeNormalHalf;
+        shouldAccept(negativeHalfFloaty, ub, extraError);
+        shouldAccept(negativeHalfFloaty, lb, extraError);
+        shouldNotAccept(negativeHalfFloaty, ub + Float16Utils.float16Ulp(ub), extraError);
+        shouldNotAccept(negativeHalfFloaty, lb - Float16Utils.float16Ulp(lb), extraError);
+    }
+
+    // Test that range of allowed error is trimmed at the zero boundary.  This function tests both
+    // float, double, and half Targets.
+    public void testRangeDoesNotAcrossZero() {
+        Target t;
+        Target.Floaty floaty;
+
+        t = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, false);
+        t.setPrecision(4, 4);
+
+        floaty = t.new32(Float.MIN_VALUE);
+        shouldAccept(floaty, (double) Float.MIN_VALUE);
+        shouldAccept(floaty, (double) Float.MIN_VALUE + 4 * Float.MIN_VALUE);
+        shouldAccept(floaty, (double) 0.f);
+        shouldNotAccept(floaty, (double) 0.f - Float.MIN_VALUE);
+
+        floaty = t.new32(-Float.MIN_VALUE);
+        shouldAccept(floaty, (double) -Float.MIN_VALUE);
+        shouldAccept(floaty, (double) -Float.MIN_VALUE - 4 * Float.MIN_VALUE);
+        shouldAccept(floaty, (double) 0.f);
+        shouldNotAccept(floaty, (double) 0.f + Float.MIN_VALUE);
+
+        t = new Target(Target.FunctionType.NORMAL, Target.ReturnType.DOUBLE, false);
+        t.setPrecision(4, 4);
+
+        floaty = t.new64(Double.MIN_VALUE);
+        shouldAccept(floaty, Double.MIN_VALUE);
+        shouldAccept(floaty, Double.MIN_VALUE + 4 * Double.MIN_VALUE);
+        shouldAccept(floaty, 0.);
+        shouldNotAccept(floaty, 0. - Double.MIN_VALUE);
+
+        floaty = t.new64(-Double.MIN_VALUE);
+        shouldAccept(floaty, -Double.MIN_VALUE);
+        shouldAccept(floaty, -Double.MIN_VALUE - 4 * Double.MIN_VALUE);
+        shouldAccept(floaty, 0.);
+        shouldNotAccept(floaty, 0. + Double.MIN_VALUE);
+
+        t = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, false);
+        t.setPrecision(4, 4);
+
+        // Subnormals are not required to be handled for Float16.  Test with MIN_NORMAL instead.
+        floaty = t.newFloaty(Float16Utils.MIN_NORMAL);
+        shouldAccept(floaty, Float16Utils.MIN_NORMAL);
+        shouldAccept(floaty, Float16Utils.MIN_NORMAL+ 4 * Double.MIN_NORMAL);
+        shouldAccept(floaty, 0.);
+        shouldNotAccept(floaty, 0. - Float16Utils.MIN_NORMAL);
+
+        floaty = t.newFloaty(-Float16Utils.MIN_NORMAL);
+        shouldAccept(floaty, -Float16Utils.MIN_NORMAL);
+        shouldAccept(floaty, -Float16Utils.MIN_NORMAL- 4 * Float16Utils.MIN_NORMAL);
+        shouldAccept(floaty, 0.f);
+        shouldNotAccept(floaty, 0. + Float16Utils.MIN_NORMAL);
+    }
+
+    // Validate float16Ulp for a double value that is precisely representable in half-precision.
+    private void validateFloat16Ulp(double value) {
+        double absoluteValue = Math.abs(value);
+        double ulp = Float16Utils.float16Ulp(value);
+
+        if (absoluteValue == 0.) {
+            assertEquals(Float16Utils.MIN_VALUE, ulp);
+            return;
+        }
+        if (Double.isNaN(absoluteValue)) {
+            assertTrue("Ulp for NaN is not NaN", Double.isNaN(ulp));
+            return;
+        }
+        if (absoluteValue == Double.POSITIVE_INFINITY ||
+            absoluteValue == Double.NEGATIVE_INFINITY) {
+            assertEquals(Double.POSITIVE_INFINITY, ulp);
+            return;
+        }
+
+        if (absoluteValue < Math.scalb(1., -24)) {
+            assertTrue("Input double value smaller than MIN_VALUE for Float16", false);
+        }
+
+        if (absoluteValue < Math.scalb(1., -14)) {
+            // Input is subnormal Float16.  Ulp should be 2^-24
+            assertEquals(Math.scalb(1., -24), ulp);
+            return;
+        }
+
+        boolean tested = false;
+        int exponent = -13;
+        double limit = Math.scalb(1., exponent);
+        for (; exponent <= 16; exponent ++, limit *= 2) {
+            if (absoluteValue < limit) {
+                assertEquals(ulp, Math.scalb(1., exponent - 11));
+                tested = true;
+                break;
+            }
+        }
+        assertTrue("Ulp not validated.  Absolute value " + Double.toString(absoluteValue), tested);
+    }
+
+    // Test float16Ulp for all valid inputs (i.e. all Float16 values represented as Double) and test
+    // that assertions fire for Double values that are not representable in Float16.
+    public void testFloat16Ulp() {
+        // Test float16Ulp for all short values.
+        for (short s = Short.MIN_VALUE; ; s ++) {
+            validateFloat16Ulp(Float16Utils.convertFloat16ToDouble(s));
+            // Detect loop termination here.  Doing so in the for statement creates an infinite
+            // loop.
+            if (s == Short.MAX_VALUE) {
+                break;
+            }
+        }
+
+        // Test float16Ulp for some known values
+        for (double value: preciseFloat16Values) {
+            validateFloat16Ulp(value);
+        }
+
+        // Expect an exception for values not representable in Float16.  The loop below tests this
+        // for all values in this array and their negation.
+        double valuesOutOfFloat16Range[] = {Math.scalb(1., -100),
+                                            Double.valueOf("0x1.8p-24"),
+                                            Double.valueOf("0x1.ffffffffp-20"),
+                                            1024.55, 65520., 66000.
+                                           };
+
+        for (double value: valuesOutOfFloat16Range) {
+            try {
+                Float16Utils.float16Ulp(value);
+                assertTrue("Expected exception not thrown for: " + Double.toString(value), false);
+            } catch (RSRuntimeException e) {
+                // Ignore the expected exception.
+                // Log.w("testFloat16Ulp", "Received expected exception: " + e.getMessage());
+            }
+
+            try {
+                Float16Utils.float16Ulp(-value);
+                assertTrue("Expected exception not thrown for: " + Double.toString(value), false);
+            } catch (RSRuntimeException e) {
+                // Ignore the expected exception.
+                // Log.w("testFloat16Ulp", "Received expected exception: " + e.getMessage());
+            }
+        }
+    }
+
+    private void validateRoundToFloat16(double argument, double low, double high) {
+        double[] result = Float16Utils.roundToFloat16(argument);
+        double[] expected = new double[]{low, high};
+
+        for (int i = 0; i < 2; i ++) {
+            if (result[i] == expected[i])
+                continue;
+            if (Double.isNaN(result[i]) && Double.isNaN(expected[i]))
+                continue;
+
+            StringBuilder message = new StringBuilder();
+            message.append("For input ");
+            appendVariableToMessage(message, argument);
+            message.append("\n");
+            message.append("For field " + Integer.toString(i) + ": Expected output: ");
+            appendVariableToMessage(message, expected[i]);
+            message.append("\n");
+            message.append("Actual output: ");
+            appendVariableToMessage(message, result[i]);
+            message.append("\n");
+            assertTrue("roundToFloat16 error:\n" + message.toString(), false);
+        }
+    }
+
+    public void testRoundToFloat16() {
+        // Validate values that are precisely representable in Float16.  The bounds have to be the
+        // same as the input.
+        for (double value: preciseFloat16Values) {
+            validateRoundToFloat16(value, value, value);
+        }
+
+        // Validate for special cases:
+        //   Double.MIN_VALUE is between Float16 0 and MIN_VALUE
+        //   Double.MAX_VALUE is between Float16 MAX_VALUE and +Infinity
+        //   65519 and 65520 are between Float16 MAX_VALUE and +Infinity (but their exponent is
+        //       within Float16's range).
+        //   3001.5 and 3000.5 are between Float16 3000 and 3002
+        validateRoundToFloat16(Double.MIN_VALUE, 0.0, Float16Utils.MIN_VALUE);
+        validateRoundToFloat16(Double.MAX_VALUE, Double.POSITIVE_INFINITY,
+                               Double.POSITIVE_INFINITY);
+        validateRoundToFloat16(65519., 65504., Double.POSITIVE_INFINITY);
+        validateRoundToFloat16(65520., 65504., Double.POSITIVE_INFINITY);
+        validateRoundToFloat16(3001.5, 3000., 3002.);
+        validateRoundToFloat16(3000.5, 3000., 3002.);
+
+        validateRoundToFloat16(-Double.MIN_VALUE, -Float16Utils.MIN_VALUE, -0.0);
+        validateRoundToFloat16(-Double.MAX_VALUE, Double.NEGATIVE_INFINITY,
+                               Double.NEGATIVE_INFINITY);
+        validateRoundToFloat16(-65519., Double.NEGATIVE_INFINITY, -65504.);
+        validateRoundToFloat16(-65520., Double.NEGATIVE_INFINITY, -65504.);
+        validateRoundToFloat16(-3001.5, -3002., -3000.);
+        validateRoundToFloat16(-3000.5, -3002., -3000.);
+
+        // Validate that values precisely between two Float16 values get handled properly.
+        double[] float16Sample = {0., 1., 100.,
+                                  Float16Utils.MIN_VALUE,
+                                  Float16Utils.MIN_VALUE * 100,
+                                  Float16Utils.MIN_NORMAL * 100
+                                 };
+
+        for (double value: float16Sample) {
+            double ulp = Float16Utils.float16Ulp(value);
+
+            validateRoundToFloat16(value + 0.5 * ulp, value, value + ulp);
+            validateRoundToFloat16(-value - 0.5 * ulp, -value - ulp, -value);
+        }
+    }
+
+    public void testConvertDoubleToFloat16() {
+        assertEquals(Float16Utils.convertDoubleToFloat16(0.), (short) 0x0);
+        assertEquals(Float16Utils.convertDoubleToFloat16(Float16Utils.MIN_VALUE), (short) 0x0001);
+        assertEquals(Float16Utils.convertDoubleToFloat16(42 * Float16Utils.MIN_VALUE), (short) 0x002a);
+        assertEquals(Float16Utils.convertDoubleToFloat16(Float16Utils.MIN_NORMAL), (short) 0x400);
+        assertEquals(Float16Utils.convertDoubleToFloat16(42.), (short) 0x5140);
+        assertEquals(Float16Utils.convertDoubleToFloat16(1024.), (short) 0x6400);
+        assertEquals(Float16Utils.convertDoubleToFloat16(Double.POSITIVE_INFINITY), (short) 0x7c00);
+
+        assertEquals(Float16Utils.convertDoubleToFloat16(-0.), (short) 0x8000);
+        assertEquals(Float16Utils.convertDoubleToFloat16(-Float16Utils.MIN_VALUE), (short) 0x8001);
+        assertEquals(Float16Utils.convertDoubleToFloat16(-42 * Float16Utils.MIN_VALUE), (short) 0x802a);
+        assertEquals(Float16Utils.convertDoubleToFloat16(-Float16Utils.MIN_NORMAL), (short) 0x8400);
+        assertEquals(Float16Utils.convertDoubleToFloat16(-42.), (short) 0xd140);
+        assertEquals(Float16Utils.convertDoubleToFloat16(-1024.), (short) 0xe400);
+        assertEquals(Float16Utils.convertDoubleToFloat16(Double.NEGATIVE_INFINITY), (short) 0xfc00);
+
+        assertEquals(Float16Utils.convertDoubleToFloat16(Double.NaN), (short) 0x7e00);
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/GetAllocationTest.java b/tests/tests/renderscript/src/android/renderscript/cts/GetAllocationTest.java
index f938569..177a804 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/GetAllocationTest.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/GetAllocationTest.java
@@ -37,7 +37,6 @@
         Allocation mOut = Allocation.createTyped(mRS, mTemp.getType());
 
         ms.bind_pointer(mTemp);
-        ms.set_script(ms);
         ms.set_alloc_out(mOut);
         ms.invoke_start();
 
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/ImageProcessingTest.java b/tests/tests/renderscript/src/android/renderscript/cts/ImageProcessingTest.java
index f38bdb0..df8a6fe 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/ImageProcessingTest.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/ImageProcessingTest.java
@@ -47,6 +47,7 @@
 import android.renderscript.Short4;
 
 import android.renderscript.Matrix4f;
+import android.renderscript.Script;
 
 import android.renderscript.Type;
 
@@ -58,6 +59,7 @@
 import android.renderscript.ScriptIntrinsicConvolve3x3;
 import android.renderscript.ScriptIntrinsicConvolve5x5;
 import android.renderscript.ScriptIntrinsicLUT;
+import android.util.Log;
 
 public class ImageProcessingTest extends RSBaseCompute {
     private Allocation a1, a2;
@@ -100,67 +102,551 @@
     public void testBlend() {
         ScriptIntrinsicBlend mBlend;
         mBlend = ScriptIntrinsicBlend.create(mRS, Element.U8_4(mRS));
-
-        Allocation a1_copy, a2_copy;
-        a1_copy = Allocation.createTyped(mRS, a1.getType());
-        a2_copy = Allocation.createTyped(mRS, a2.getType());
-
-        for (int i = 0; i < 14; i++) {
-
-            a1_copy.copy2DRangeFrom(0, 0, a1.getType().getX(), a1.getType().getY(), a1, 0, 0);
-            a2_copy.copy2DRangeFrom(0, 0, a2.getType().getX(), a2.getType().getY(), a2, 0, 0);
+        int w = 256;
+        int h = 256;
+        Allocation src = creatAllocation(w, h);
+        Allocation dst = creatAllocation(w, h);
+        byte[] srcData = new byte[w * h * 4];
+        byte[] dstData = new byte[w * h * 4];
+        byte[] resultData = new byte[w * h * 4];
+        Script.LaunchOptions opt = new Script.LaunchOptions();
+        // unclipped but with options
+        for (int i = 0; i < 28; i++) {
+            buildSrc(srcData, w, h);
+            buildDst(dstData, w, h);
+            src.copyFromUnchecked(srcData);
+            dst.copyFromUnchecked(dstData);
 
             switch (i) {
-            case 0:
-                mBlend.forEachSrc(a1_copy, a2_copy);
-                break;
-            case 1:
-                mBlend.forEachDst(a1_copy, a2_copy);
-                break;
-            case 2:
-                mBlend.forEachSrcOver(a1_copy, a2_copy);
-                break;
-            case 3:
-                mBlend.forEachDstOver(a1_copy, a2_copy);
-                break;
-            case 4:
-                mBlend.forEachSrcIn(a1_copy, a2_copy);
-                break;
-            case 5:
-                mBlend.forEachDstIn(a1_copy, a2_copy);
-                break;
-            case 6:
-                mBlend.forEachSrcOut(a1_copy, a2_copy);
-                break;
-            case 7:
-                mBlend.forEachDstOut(a1_copy, a2_copy);
-                break;
-            case 8:
-                mBlend.forEachSrcAtop(a1_copy, a2_copy);
-                break;
-            case 9:
-                mBlend.forEachDstAtop(a1_copy, a2_copy);
-                break;
-            case 10:
-                mBlend.forEachXor(a1_copy, a2_copy);
-                break;
-            case 11:
-                mBlend.forEachAdd(a1_copy, a2_copy);
-                break;
-            case 12:
-                mBlend.forEachSubtract(a1_copy, a2_copy);
-                break;
-            case 13:
-                mBlend.forEachMultiply(a1_copy, a2_copy);
-                break;
+                case 0:
+                    mBlend.forEachSrc(src, dst);
+                    break;
+                case 1:
+                    mBlend.forEachDst(src, dst);
+                    break;
+                case 2:
+                    mBlend.forEachSrcOver(src, dst);
+                    break;
+                case 3:
+                    mBlend.forEachDstOver(src, dst);
+                    break;
+                case 4:
+                    mBlend.forEachSrcIn(src, dst);
+                    break;
+                case 5:
+                    mBlend.forEachDstIn(src, dst);
+                    break;
+                case 6:
+                    mBlend.forEachSrcOut(src, dst);
+                    break;
+                case 7:
+                    mBlend.forEachDstOut(src, dst);
+                    break;
+                case 8:
+                    mBlend.forEachSrcAtop(src, dst);
+                    break;
+                case 9:
+                    mBlend.forEachDstAtop(src, dst);
+                    break;
+                case 10:
+                    mBlend.forEachXor(src, dst);
+                    break;
+                case 11:
+                    mBlend.forEachAdd(src, dst);
+                    break;
+                case 12:
+                    mBlend.forEachSubtract(src, dst);
+                    break;
+                case 13:
+                    mBlend.forEachMultiply(src, dst);
+                    break;
+                case 14:
+                    mBlend.forEachSrc(src, dst, opt);
+                    break;
+                case 15:
+                    mBlend.forEachDst(src, dst, opt);
+                    break;
+                case 16:
+                    mBlend.forEachSrcOver(src, dst, opt);
+                    break;
+                case 17:
+                    mBlend.forEachDstOver(src, dst, opt);
+                    break;
+                case 18:
+                    mBlend.forEachSrcIn(src, dst, opt);
+                    break;
+                case 19:
+                    mBlend.forEachDstIn(src, dst, opt);
+                    break;
+                case 20:
+                    mBlend.forEachSrcOut(src, dst, opt);
+                    break;
+                case 21:
+                    mBlend.forEachDstOut(src, dst, opt);
+                    break;
+                case 22:
+                    mBlend.forEachSrcAtop(src, dst, opt);
+                    break;
+                case 23:
+                    mBlend.forEachDstAtop(src, dst, opt);
+                    break;
+                case 24:
+                    mBlend.forEachXor(src, dst, opt);
+                    break;
+                case 25:
+                    mBlend.forEachAdd(src, dst, opt);
+                    break;
+                case 26:
+                    mBlend.forEachSubtract(src, dst, opt);
+                    break;
+                case 27:
+                    mBlend.forEachMultiply(src, dst, opt);
+                    break;
             }
+            dst.copyTo(resultData);
+            String name = javaBlend(i%14, srcData, dstData);
+            assertTrue(name, similar(resultData,dstData));
+            Log.v("BlendUnit", name + " " + similar(resultData, dstData));
 
-            // validate
+        }
+    }
 
+    // utility to create and allocation of a given dimension
+    protected Allocation creatAllocation(int w, int h) {
+        Type.Builder b = new Type.Builder(mRS, Element.RGBA_8888(mRS));
+        b.setX(w);
+        b.setY(h);
+        return  Allocation.createTyped(mRS, b.create(), Allocation.USAGE_SCRIPT);
+    }
+
+   // Compare two images ensuring returning false if error is greater than 2
+   // so that it can  support integer and float non identical versions
+    public boolean similar(byte[] a, byte[] b) {
+        for (int i = 0; i < a.length; i++) {
+            int v1 = 0xFF & a[i];
+            int v2 = 0xFF & b[i];
+            int error = Math.abs(v1 - v2);
+            if (error > 2) {
+                return false;
+            }
+        }
+        return true;
+    }
+    // Build a test pattern to be the source pattern designed to provide a wide range of values
+    public void buildSrc(byte[] srcData, int width, int height) {
+        for (int i = 0; i < srcData.length / 4; i++) {
+            int x = i % width;
+            int y = i / width;
+            int d = (x - width / 2) * (x - width / 2) + (y - height / 2) * (y - height / 2);
+            d = (255 * d) / ((width / 2) * (width / 2));
+            d = (d > 255) ? 0 : d;
+
+            srcData[i * 4 + 0] = (byte) d; // red
+            srcData[i * 4 + 1] = (byte) d; // green
+            srcData[i * 4 + 2] = (byte) 0; // blue
+            srcData[i * 4 + 3] = (byte) y; // alpha
+        }
+    }
+
+    // Build a test pattern to be the destination pattern designed to provide a wide range of values
+    public void buildDst(byte[] dstData, int width, int height) {
+        for (int i = 0; i < dstData.length / 4; i++) {
+            int x = i % width;
+            int y = i / width;
+
+            dstData[i * 4 + 0] = (byte) 0; // red
+            dstData[i * 4 + 1] = (byte) 0; // green
+            dstData[i * 4 + 2] = (byte) y; // blue
+            dstData[i * 4 + 3] = (byte) x; // alpha
         }
 
     }
 
+    public String javaBlend(int type, byte[] src, byte[] dst) {
+
+        for (int i = 0; i < dst.length; i += 4) {
+            byte[] rgba = func[type].filter(src[i], src[i + 1], src[i + 2], src[i + 3],
+                    dst[i], dst[i + 1], dst[i + 2], dst[i + 3]);
+            dst[i] = rgba[0];
+            dst[i + 1] = rgba[1];
+            dst[i + 2] = rgba[2];
+            dst[i + 3] = rgba[3];
+        }
+        return func[type].name;
+    }
+
+    // Base class for Java blend implementation supporting float and int implementations
+
+    abstract class BlendFunc {
+        float srcR, srcG, srcB, srcA;
+        float dstR, dstG, dstB, dstA;
+        int s_srcR, s_srcG, s_srcB, s_srcA;
+        int s_dstR, s_dstG, s_dstB, s_dstA;
+        byte[] rgba = new byte[4];
+        String name;
+
+        final int clamp(int c) {
+            final int N = 255;
+            c &= ~(c >> 31);
+            c -= N;
+            c &= (c >> 31);
+            c += N;
+            return c;
+        }
+
+        int pack(float a, float r, float g, float b) {
+            int ia = clamp((int) (255 * a));
+            int ir = clamp((int) (255 * r));
+            int ig = clamp((int) (255 * g));
+            int ib = clamp((int) (255 * b));
+            rgba[0] = (byte) ir;
+            rgba[1] = (byte) ig;
+            rgba[2] = (byte) ib;
+            rgba[3] = (byte) ia;
+            return (ia << 24) | (ir << 16) | (ig << 8) | ib;
+        }
+
+        int pack(int a, int r, int g, int b) {
+
+            rgba[0] = (byte) clamp(r);
+            rgba[1] = (byte) clamp(g);
+            rgba[2] = (byte) clamp(b);
+            rgba[3] = (byte) clamp(a);
+            return 0;
+        }
+
+        void unpackSrc(int src) {
+            s_srcR = (0xFF & (src >> 16));
+            s_srcG = (0xFF & (src >> 8));
+            s_srcB = (0xFF & (src >> 0));
+            s_srcA = (0xFF & (src >> 24));
+            float scale = 1 / 255f;
+
+            srcR = (0xFF & (src >> 16)) * scale;
+            srcG = (0xFF & (src >> 8)) * scale;
+            srcB = (0xFF & (src >> 0)) * scale;
+            srcA = (0xFF & (src >> 24)) * scale;
+        }
+
+        void unpackDst(int dst) {
+            float scale = 1 / 255f;
+
+            s_dstR = (0xFF & (dst >> 16));
+            s_dstG = (0xFF & (dst >> 8));
+            s_dstB = (0xFF & (dst >> 0));
+            s_dstA = (0xFF & (dst >> 24));
+
+            dstR = (0xFF & (dst >> 16)) * scale;
+            dstG = (0xFF & (dst >> 8)) * scale;
+            dstB = (0xFF & (dst >> 0)) * scale;
+            dstA = (0xFF & (dst >> 24)) * scale;
+        }
+
+        int filter(int scr, int dst) {
+            unpackSrc(scr);
+            unpackDst(dst);
+            return blend();
+        }
+
+        byte[] filter(byte srcR, byte srcG, byte srcB, byte srcA,
+                      byte dstR, byte dstG, byte dstB, byte dstA) {
+            float scale = 1 / 255f;
+            this.srcR = (0xFF & (srcR)) * scale;
+            this.srcG = (0xFF & (srcG)) * scale;
+            this.srcB = (0xFF & (srcB)) * scale;
+            this.srcA = (0xFF & (srcA)) * scale;
+
+            this.dstR = (0xFF & (dstR)) * scale;
+            this.dstG = (0xFF & (dstG)) * scale;
+            this.dstB = (0xFF & (dstB)) * scale;
+            this.dstA = (0xFF & (dstA)) * scale;
+            s_dstR = (0xFF & (dstR));
+            s_dstG = (0xFF & (dstG));
+            s_dstB = (0xFF & (dstB));
+            s_dstA = (0xFF & (dstA));
+
+            s_srcR = (0xFF & (srcR));
+            s_srcG = (0xFF & (srcG));
+            s_srcB = (0xFF & (srcB));
+            s_srcA = (0xFF & (srcA));
+
+            blend();
+            return rgba;
+        }
+
+        abstract int blend();
+    }
+
+    BlendFunc blend_dstAtop = new BlendFunc() {
+        // dst = dst.rgb * src.a + (1.0 - dst.a) * src.rgb
+        // dst.a = src.a
+        {
+            name = "blend_dstAtop";
+        }
+
+        @Override
+        int blend() {
+            float r = (dstR * srcA + (1 - dstA) * srcR);
+            float g = (dstG * srcA + (1 - dstA) * srcG);
+            float b = (dstB * srcA + (1 - dstA) * srcB);
+            float a = srcA;
+
+            return pack(a, r, g, b);
+        }
+    };
+    BlendFunc blend_dstIn = new BlendFunc() {
+        // Sets dst = dst * src.a
+        {
+            name = "blend_dstIn";
+        }
+
+        @Override
+        int blend() {
+            float r = (dstR * srcA);
+            float g = (dstG * srcA);
+            float b = (dstB * srcA);
+            float a = (dstA * srcA);
+            return pack(a, r, g, b);
+        }
+    };
+
+    BlendFunc blend_add = new BlendFunc() {
+        // dst = dst + src
+        {
+            name = "blend_add";
+        }
+
+        @Override
+        int blend() {
+
+            int r = Math.min(s_dstR + s_srcR, 255);
+            int g = Math.min(s_dstG + s_srcG, 255);
+            int b = Math.min(s_dstB + s_srcB, 255);
+            int a = Math.min(s_dstA + s_srcA, 255);
+            return pack(a, r, g, b);
+
+        }
+    };
+
+    BlendFunc blend_clear = new BlendFunc() {
+        // Sets dst = {0, 0, 0, 0}
+        {
+            name = "blend_clear";
+        }
+
+        @Override
+        int blend() {
+            return pack(0, 0, 0, 0);
+        }
+    };
+
+    BlendFunc blend_dst = new BlendFunc() {
+        // Sets dst = dst
+        {
+            name = "blend_dst";
+        }
+
+        @Override
+        int blend() {
+            return pack(dstA, dstR, dstG, dstB);
+        }
+    };
+
+    BlendFunc blend_dstOut = new BlendFunc() {
+        // Sets dst = dst * (1.0 - src.a)
+        {
+            name = "blend_dstOut";
+        }
+
+        @Override
+        int blend() {
+            float r = (dstR * (1 - srcA));
+            float g = (dstG * (1 - srcA));
+            float b = (dstB * (1 - srcA));
+            float a = (dstA * (1 - srcA));
+            return pack(a, r, g, b);
+        }
+    };
+    BlendFunc blend_dstOver = new BlendFunc() {
+        // Sets dst = dst + src * (1.0 - dst.a)
+        {
+            name = "blend_dstOver";
+        }
+
+        @Override
+        int blend() {
+            float r = dstR + (srcR * (1 - dstA));
+            float g = dstG + (srcG * (1 - dstA));
+            float b = dstB + (srcB * (1 - dstA));
+            float a = dstA + (srcA * (1 - dstA));
+            return pack(a, r, g, b);
+        }
+    };
+
+    BlendFunc blend_multiply = new BlendFunc() {
+        // dst = dst * src
+        {
+            name = "blend_multiply";
+        }
+
+        @Override
+        int blend() {
+            float r = (srcR * dstR);
+            float g = (srcG * dstG);
+            float b = (srcB * dstB);
+            float a = (srcA * dstA);
+            return pack(a, r, g, b);
+        }
+    };
+
+    BlendFunc blend_src = new BlendFunc() {
+        // Sets dst =  src
+        {
+            name = "blend_src";
+        }
+
+        int blend() {
+            return pack(srcA, srcR, srcG, srcB);
+
+        }
+    };
+
+    BlendFunc blend_srcAtop = new BlendFunc() {
+        // dst.rgb = src.rgb * dst.a + (1.0 - src.a) * dst.rgb
+        // dst.a = dst.a
+        {
+            name = "blend_srcAtop";
+        }
+
+        @Override
+        int blend() {
+            float r = (srcR * dstA + (1 - srcA) * dstR);
+            float g = (srcG * dstA + (1 - srcA) * dstG);
+            float b = (srcB * dstA + (1 - srcA) * dstB);
+            float a = (srcA * dstA + (1 - srcA) * dstA);
+            return pack(a, r, g, b);
+        }
+    };
+
+    BlendFunc blend_srcIn = new BlendFunc() {
+        // dst = src * dst.a
+        {
+            name = "blend_srcIn";
+        }
+
+        @Override
+        int blend() {
+            float r = (srcR * dstA);
+            float g = (srcG * dstA);
+            float b = (srcB * dstA);
+            float a = (srcA * dstA);
+            ;
+            return pack(a, r, g, b);
+        }
+    };
+
+    BlendFunc blend_srcOut = new BlendFunc() {
+        // Sets dst = src * (1.0 - dst.a)
+        {
+            name = "blend_srcOut";
+        }
+
+        @Override
+        int blend() {
+            float r = (srcR * (1 - dstA));
+            float g = (srcG * (1 - dstA));
+            float b = (srcB * (1 - dstA));
+            float a = (srcA * (1 - dstA));
+            ;
+            return pack(a, r, g, b);
+        }
+    };
+
+    BlendFunc blend_srcOver = new BlendFunc() {
+        // Sets dst = src + dst * (1.0 - src.a)
+        {
+            name = "blend_srcOver";
+        }
+
+        @Override
+        int blend() {
+            float r = srcR + (dstR * (1 - srcA));
+            float g = srcG + (dstG * (1 - srcA));
+            float b = srcB + (dstB * (1 - srcA));
+            float a = srcA + (dstA * (1 - srcA));
+            return pack(a, r, g, b);
+        }
+    };
+
+    BlendFunc blend_subtract = new BlendFunc() {
+        // Sets dst =  dst - src
+        {
+            name = "blend_subtract";
+        }
+
+        @Override
+        int blend() {
+            float r = Math.max(dstR - srcR, 0);
+            float g = Math.max(dstG - srcG, 0);
+            float b = Math.max(dstB - srcB, 0);
+            float a = Math.max(dstA - srcA, 0);
+            return pack(a, r, g, b);
+        }
+    };
+
+    // Porter/Duff xor compositing
+    BlendFunc blend_pdxor = new BlendFunc() {
+        // dst.rgb = src.rgb*(1-dst.a)+(1-src.a)*dst.rgb;
+        // dst.a = src.a+dst.a - 2*src.a*dst.a
+        {
+            name = "blend_pdxor";
+        }
+
+        @Override
+        int blend() {
+            float r = srcR * (1 - dstA) + (dstR * (1 - srcA));
+            float g = srcG * (1 - dstA) + (dstG * (1 - srcA));
+            float b = srcB * (1 - dstA) + (dstB * (1 - srcA));
+            float a = srcA + dstA - (2 * srcA * dstA);
+            return pack(a, r, g, b);
+        }
+    };
+
+    // NOT Porter/Duff xor compositing simple XOR
+    BlendFunc blend_xor = new BlendFunc() {
+        // Sets dst = {src.r ^ dst.r, src.g ^ dst.g, src.b ^ dst.b, src.a ^ dst.a}
+        {
+            name = "blend_xor";
+        }
+
+        @Override
+        int blend() {
+            float scale = 1 / 255f;
+            float r = (((int) (dstR * 255)) ^ ((int) (srcR * 255))) * scale;
+            float g = (((int) (dstG * 255)) ^ ((int) (srcG * 255))) * scale;
+            float b = (((int) (dstB * 255)) ^ ((int) (srcB * 255))) * scale;
+            float a = (((int) (dstA * 255)) ^ ((int) (srcA * 255))) * scale;
+            return pack(a, r, g, b);
+        }
+    };
+
+    BlendFunc[] func = {
+            blend_src,
+            blend_dst,
+            blend_srcOver,
+            blend_dstOver,
+            blend_srcIn,
+            blend_dstIn,
+            blend_srcOut,
+            blend_dstOut,
+            blend_srcAtop,
+            blend_dstAtop,
+            blend_xor,
+            blend_add,
+            blend_subtract,
+            blend_multiply,
+    };
+
     public void testColorMatrix() {
         ScriptIntrinsicColorMatrix mColorMatrix;
         mColorMatrix = ScriptIntrinsicColorMatrix.create(mRS, Element.U8_4(mRS));
@@ -198,7 +684,6 @@
 
     }
 
-
     public void testConvolve3x3() {
         ScriptIntrinsicConvolve3x3 mConvolve3x3;
         mConvolve3x3 = ScriptIntrinsicConvolve3x3.create(mRS, Element.U8_4(mRS));
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/IntrinsicBLAS.java b/tests/tests/renderscript/src/android/renderscript/cts/IntrinsicBLAS.java
deleted file mode 100644
index 17f546b..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/IntrinsicBLAS.java
+++ /dev/null
@@ -1,6831 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.renderscript.cts;
-
-import android.renderscript.*;
-import android.util.Log;
-import java.util.ArrayList;
-
-public class IntrinsicBLAS extends IntrinsicBase {
-    private ScriptIntrinsicBLAS mBLAS;
-    private BLASData mBLASData;
-    private boolean mInitialized = false;
-
-    private ArrayList<Allocation> mMatrixS;
-    private final float alphaS = 1.0f;
-    private final float betaS = 1.0f;
-
-    private ArrayList<Allocation> mMatrixD;
-    private final double alphaD = 1.0;
-    private final double betaD = 1.0;
-
-    private ArrayList<Allocation> mMatrixC;
-    private final Float2 alphaC = new Float2(1.0f, 0.0f);
-    private final Float2 betaC = new Float2(1.0f, 0.0f);
-
-    private ArrayList<Allocation> mMatrixZ;
-    private final Double2 alphaZ = new Double2(1.0, 0.0);
-    private final Double2 betaZ = new Double2(1.0, 0.0);
-
-    private int[] mTranspose = {ScriptIntrinsicBLAS.NO_TRANSPOSE,
-                                ScriptIntrinsicBLAS.TRANSPOSE,
-                                ScriptIntrinsicBLAS.CONJ_TRANSPOSE,
-                                0};
-
-    private int[] mUplo = {ScriptIntrinsicBLAS.UPPER,
-                           ScriptIntrinsicBLAS.LOWER,
-                           0};
-
-    private int[] mDiag = {ScriptIntrinsicBLAS.NON_UNIT,
-                           ScriptIntrinsicBLAS.UNIT,
-                           0};
-
-    private int[] mSide = {ScriptIntrinsicBLAS.LEFT,
-                           ScriptIntrinsicBLAS.RIGHT,
-                           0};
-
-    private int[] mInc = {0, 1, 2};
-    private int[] mK = {-1, 0, 1};
-    private int[] mDim = {1, 2, 3, 256};
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-
-        // Now populate the test Matrixes and Vectors.
-        if (!mInitialized) {
-            mBLASData = new BLASData();
-            mBLASData.loadData(mCtx);
-            mBLAS = ScriptIntrinsicBLAS.create(mRS);
-            mMatrixS = new ArrayList<Allocation>();
-            mMatrixD = new ArrayList<Allocation>();
-            mMatrixC = new ArrayList<Allocation>();
-            mMatrixZ = new ArrayList<Allocation>();
-            for (int x : mDim) {
-                for (int y : mDim) {
-                    mMatrixS.add(Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), x, y)));
-                    mMatrixD.add(Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), x, y)));
-                    mMatrixC.add(Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), x, y)));
-                    mMatrixZ.add(Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), x, y)));
-                }
-            }
-            // Also need Allocation with mismatch Element.
-            Allocation misAlloc = Allocation.createTyped(mRS, Type.createXY(mRS, Element.U8(mRS), 1, 1));
-            mMatrixS.add(misAlloc);
-            mMatrixD.add(misAlloc);
-            mMatrixC.add(misAlloc);
-            mMatrixZ.add(misAlloc);
-            mInitialized = true;
-        }
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-    }
-
-    // Calculate the square of the L2 norm of a matrix.
-    private double calcL2Norm(float[] input) {
-        double l2Norm = 0;
-        for (int i = 0; i < input.length; ++i) {
-            l2Norm += input[i] * input[i];
-        }
-        return l2Norm;
-    }
-
-    private double calcL2Norm(double[] input) {
-        double l2Norm = 0;
-        for (int i = 0; i < input.length; ++i) {
-            l2Norm += input[i] * input[i];
-        }
-        return l2Norm;
-    }
-
-    // Routine to verify if matrix are equivalent.
-    private void verifyMatrix(Allocation ref, Allocation out) {
-        verifyMatrix(ref, out, false);
-    }
-
-    // Use L2 norm of a matrix as the scale to determine whether two matrices are equivalent:
-    // if the absolute square error of any elements is smaller than the average L2 Norm
-    // per element times an allowed error range (1e-6), then the two matrices are considered equivalent.
-    // Criterion: (a[i,j] - a'[i,j])^2 < epsilon * ||A||/(M*N)
-    // M, N: the dimensions of the matrix; epsilon: allowed relative error.
-    private void verifyMatrix(Allocation ref, Allocation out, boolean isUpperMatrix) {
-        double l2Norm;
-        int size;
-        Element e = ref.getType().getElement();
-        if (e.isCompatible(Element.F32(mRS)) || e.isCompatible(Element.F32_2(mRS))) {
-            size = out.getBytesSize() / 4;
-            float[] outArr = new float[size];
-            float[] refArr = new float[size];
-            out.copyTo(outArr);
-            ref.copyTo(refArr);
-
-            double l2NormOut = calcL2Norm(outArr);
-            double l2NormRef = calcL2Norm(refArr);
-            l2Norm = (l2NormOut < l2NormRef ? l2NormOut : l2NormRef) / size;
-        } else {
-            size = out.getBytesSize() / 8;
-            double[] outArr = new double[size];
-            double[] refArr = new double[size];
-            out.copyTo(outArr);
-            ref.copyTo(refArr);
-
-            double l2NormOut = calcL2Norm(outArr);
-            double l2NormRef = calcL2Norm(refArr);
-            l2Norm = (l2NormOut < l2NormRef ? l2NormOut : l2NormRef) / size;
-        }
-        mVerify.invoke_verifyMatrix(ref, out, l2Norm, isUpperMatrix);
-    }
-
-
-    private boolean validateSide(int Side) {
-        if (Side != ScriptIntrinsicBLAS.LEFT && Side != ScriptIntrinsicBLAS.RIGHT) {
-            return false;
-        }
-        return true;
-    }
-
-    private boolean validateTranspose(int Trans) {
-        if (Trans != ScriptIntrinsicBLAS.NO_TRANSPOSE &&
-            Trans != ScriptIntrinsicBLAS.TRANSPOSE &&
-            Trans != ScriptIntrinsicBLAS.CONJ_TRANSPOSE) {
-            return false;
-        }
-        return true;
-    }
-
-    private boolean validateConjTranspose(int Trans) {
-        if (Trans != ScriptIntrinsicBLAS.NO_TRANSPOSE &&
-            Trans != ScriptIntrinsicBLAS.CONJ_TRANSPOSE) {
-            return false;
-        }
-        return true;
-    }
-
-    private boolean validateDiag(int Diag) {
-        if (Diag != ScriptIntrinsicBLAS.NON_UNIT &&
-            Diag != ScriptIntrinsicBLAS.UNIT) {
-            return false;
-        }
-        return true;
-    }
-
-    private boolean validateUplo(int Uplo) {
-        if (Uplo != ScriptIntrinsicBLAS.UPPER &&
-            Uplo != ScriptIntrinsicBLAS.LOWER) {
-            return false;
-        }
-        return true;
-    }
-
-    private boolean validateVecInput(Allocation X) {
-        if (X.getType().getY() > 2) {
-            // For testing vector, need a mismatch Y for complete test coverage.
-            return false;
-        }
-        return true;
-    }
-
-    private boolean validateGEMV(Element e, int TransA, Allocation A, Allocation X, int incX, Allocation Y, int incY) {
-        if (!validateTranspose(TransA)) {
-            return false;
-        }
-        int M = A.getType().getY();
-        int N = A.getType().getX();
-        if (!A.getType().getElement().isCompatible(e) ||
-            !X.getType().getElement().isCompatible(e) ||
-            !Y.getType().getElement().isCompatible(e)) {
-            return false;
-        }
-        if (X.getType().getY() > 1 || Y.getType().getY() > 1) {
-            return false;
-        }
-
-        if (incX <= 0 || incY <= 0) {
-            return false;
-        }
-        int expectedXDim = -1, expectedYDim = -1;
-        if (TransA == ScriptIntrinsicBLAS.NO_TRANSPOSE) {
-            expectedXDim = 1 + (N - 1) * incX;
-            expectedYDim = 1 + (M - 1) * incY;
-        } else {
-            expectedXDim = 1 + (M - 1) * incX;
-            expectedYDim = 1 + (N - 1) * incY;
-        }
-        if (X.getType().getX() != expectedXDim ||
-            Y.getType().getX() != expectedYDim) {
-            return false;
-        }
-        return true;
-    }
-
-    private void xGEMV_API_test(int trans, int incX, int incY, ArrayList<Allocation> mMatrix) {
-        for (Allocation matA : mMatrix) {
-            for (Allocation vecX : mMatrix) {
-                if (!validateVecInput(vecX)) {
-                    continue;
-                }
-                for (Allocation vecY : mMatrix) {
-                    if (!validateVecInput(vecY)) {
-                        continue;
-                    }
-                    Element elemA = matA.getType().getElement();
-                    if (validateGEMV(elemA, trans, matA, vecX, incX, vecY, incY)) {
-                        try {
-                            if (elemA.isCompatible(Element.F32(mRS))) {
-                                mBLAS.SGEMV(trans, alphaS, matA, vecX, incX, betaS, vecY, incY);
-                            } else if (elemA.isCompatible(Element.F64(mRS))) {
-                                mBLAS.DGEMV(trans, alphaD, matA, vecX, incX, betaD, vecY, incY);
-                            } else if (elemA.isCompatible(Element.F32_2(mRS))) {
-                                mBLAS.CGEMV(trans, alphaC, matA, vecX, incX, betaC, vecY, incY);
-                            } else if (elemA.isCompatible(Element.F64_2(mRS))) {
-                                mBLAS.ZGEMV(trans, alphaZ, matA, vecX, incX, betaZ, vecY, incY);
-                            }
-                        } catch (RSRuntimeException e) {
-                            fail("should NOT throw RSRuntimeException");
-                        }
-                    } else {
-                        try {
-                            mBLAS.SGEMV(trans, alphaS, matA, vecX, incX, betaS, vecY, incY);
-                            fail("should throw RSRuntimeException for SGEMV");
-                        } catch (RSRuntimeException e) {
-                        }
-                        try {
-                            mBLAS.DGEMV(trans, alphaD, matA, vecX, incX, betaD, vecY, incY);
-                            fail("should throw RSRuntimeException for DGEMV");
-                        } catch (RSRuntimeException e) {
-                        }
-                        try {
-                            mBLAS.CGEMV(trans, alphaC, matA, vecX, incX, betaC, vecY, incY);
-                            fail("should throw RSRuntimeException for CGEMV");
-                        } catch (RSRuntimeException e) {
-                        }
-                        try {
-                            mBLAS.ZGEMV(trans, alphaZ, matA, vecX, incX, betaZ, vecY, incY);
-                            fail("should throw RSRuntimeException for ZGEMV");
-                        } catch (RSRuntimeException e) {
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    public void L2_xGEMV_API(ArrayList<Allocation> mMatrix) {
-        for (int trans : mTranspose) {
-            for (int incX : mInc) {
-                xGEMV_API_test(trans, incX, incX, mMatrix);
-            }
-        }
-    }
-
-    public void test_L2_SGEMV_API() {
-        L2_xGEMV_API(mMatrixS);
-    }
-
-    public void test_L2_DGEMV_API() {
-        L2_xGEMV_API(mMatrixD);
-    }
-
-    public void test_L2_CGEMV_API() {
-        L2_xGEMV_API(mMatrixC);
-    }
-
-    public void test_L2_ZGEMV_API() {
-        L2_xGEMV_API(mMatrixZ);
-    }
-
-    public void test_L2_SGEMV_Correctness() {
-        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        int incX = 1;
-        int incY = 1;
-
-        // Populate input allocations
-        Allocation matrixAS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dM));
-        Allocation vectorXS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, 1));
-        Allocation vectorYS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dM, 1));
-        matrixAS.copyFrom(mBLASData.L2_sGEMV_A_mn);
-        vectorXS.copyFrom(mBLASData.L2_sGEMV_x_n1);
-        vectorYS.copyFrom(mBLASData.L2_sGEMV_y_m1);
-
-        // Test for the default case: NO_TRANS
-        mBLAS.SGEMV(trans, alphaS, matrixAS, vectorXS, incX, betaS, vectorYS, incY);
-        Allocation vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dM, 1));
-        vectorYRef.copyFrom(mBLASData.L2_sGEMV_o_N);
-        verifyMatrix(vectorYRef, vectorYS);
-
-        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
-        trans = ScriptIntrinsicBLAS.TRANSPOSE;
-        // Reload vector Y, since it was overwritten by BLAS.
-        vectorYS.copyFrom(mBLASData.L2_sGEMV_y_m1);
-        // After Transpose matrixA, vectorX and vectorY are exchanged to match the dim of A.T
-        mBLAS.SGEMV(trans, alphaS, matrixAS, vectorYS, incY, betaS, vectorXS, incX);
-        vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, 1));
-        vectorYRef.copyFrom(mBLASData.L2_sGEMV_o_T);
-        verifyMatrix(vectorYRef, vectorXS);
-
-        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
-        vectorXS.copyFrom(mBLASData.L2_sGEMV_x_n1);
-        mBLAS.SGEMV(trans, alphaS, matrixAS, vectorYS, incY, betaS, vectorXS, incX);
-        vectorYRef.copyFrom(mBLASData.L2_sGEMV_o_H);
-        verifyMatrix(vectorYRef, vectorXS);
-
-        // Test for incX = 2 & incY = 3;
-        trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        incX = 2;
-        incY = 3;
-        int dimX = 1 + (mBLASData.dN - 1) * incX;
-        int dimY = 1 + (mBLASData.dM - 1) * incY;
-        vectorXS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimX, 1));
-        vectorYS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimY, 1));
-        vectorXS.copyFrom(mBLASData.L2_sGEMV_x_n2);
-        vectorYS.copyFrom(mBLASData.L2_sGEMV_y_m2);
-
-        mBLAS.SGEMV(trans, alphaS, matrixAS, vectorXS, incX, betaS, vectorYS, incY);
-        vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimY, 1));
-        vectorYRef.copyFrom(mBLASData.L2_sGEMV_o_N2);
-        verifyMatrix(vectorYRef, vectorYS);
-
-        mRS.finish();
-        checkError();
-    }
-
-    public void test_L2_DGEMV_Correctness() {
-        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        int incX = 1;
-        int incY = 1;
-
-        // Populate input allocations
-        Allocation matrixAD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dM));
-        Allocation vectorXD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, 1));
-        Allocation vectorYD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dM, 1));
-        matrixAD.copyFrom(mBLASData.L2_dGEMV_A_mn);
-        vectorXD.copyFrom(mBLASData.L2_dGEMV_x_n1);
-        vectorYD.copyFrom(mBLASData.L2_dGEMV_y_m1);
-
-        // Test for the default case: NO_TRANS
-        mBLAS.DGEMV(trans, alphaD, matrixAD, vectorXD, incX, betaD, vectorYD, incY);
-        Allocation vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dM, 1));
-        vectorYRef.copyFrom(mBLASData.L2_dGEMV_o_N);
-        verifyMatrix(vectorYRef, vectorYD);
-
-        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
-        trans = ScriptIntrinsicBLAS.TRANSPOSE;
-        // Reload vector Y, since it was overwritten by BLAS.
-        vectorYD.copyFrom(mBLASData.L2_dGEMV_y_m1);
-        // After Transpose matrixA, vectorX and vectorY are exchanged to match the dim of A.T
-        mBLAS.DGEMV(trans, alphaD, matrixAD, vectorYD, incY, betaD, vectorXD, incX);
-        vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, 1));
-        vectorYRef.copyFrom(mBLASData.L2_dGEMV_o_T);
-        verifyMatrix(vectorYRef, vectorXD);
-
-        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
-        vectorXD.copyFrom(mBLASData.L2_dGEMV_x_n1);
-        mBLAS.DGEMV(trans, alphaD, matrixAD, vectorYD, incY, betaD, vectorXD, incX);
-        vectorYRef.copyFrom(mBLASData.L2_dGEMV_o_H);
-        verifyMatrix(vectorYRef, vectorXD);
-
-        // Test for incX = 2 & incY = 3;
-        trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        incX = 2;
-        incY = 3;
-        int dimX = 1 + (mBLASData.dN - 1) * incX;
-        int dimY = 1 + (mBLASData.dM - 1) * incY;
-        vectorXD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimX, 1));
-        vectorYD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimY, 1));
-        vectorXD.copyFrom(mBLASData.L2_dGEMV_x_n2);
-        vectorYD.copyFrom(mBLASData.L2_dGEMV_y_m2);
-
-        mBLAS.DGEMV(trans, alphaD, matrixAD, vectorXD, incX, betaD, vectorYD, incY);
-        vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimY, 1));
-        vectorYRef.copyFrom(mBLASData.L2_dGEMV_o_N2);
-        verifyMatrix(vectorYRef, vectorYD);
-
-        mRS.finish();
-        checkError();
-    }
-
-    public void test_L2_CGEMV_Correctness() {
-        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        int incX = 1;
-        int incY = 1;
-
-        // Populate input allocations
-        Allocation matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dM));
-        Allocation vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, 1));
-        Allocation vectorYC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dM, 1));
-        matrixAC.copyFrom(mBLASData.L2_cGEMV_A_mn);
-        vectorXC.copyFrom(mBLASData.L2_cGEMV_x_n1);
-        vectorYC.copyFrom(mBLASData.L2_cGEMV_y_m1);
-
-        // Test for the default case: NO_TRANS
-        mBLAS.CGEMV(trans, alphaC, matrixAC, vectorXC, incX, betaC, vectorYC, incY);
-        Allocation vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dM, 1));
-        vectorYRef.copyFrom(mBLASData.L2_cGEMV_o_N);
-        verifyMatrix(vectorYRef, vectorYC);
-
-        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
-        trans = ScriptIntrinsicBLAS.TRANSPOSE;
-        // Reload vector Y, since it was overwritten by BLAS.
-        vectorYC.copyFrom(mBLASData.L2_cGEMV_y_m1);
-        // After Transpose matrixA, vectorX and vectorY are exchanged to match the dim of A.T
-        mBLAS.CGEMV(trans, alphaC, matrixAC, vectorYC, incY, betaC, vectorXC, incX);
-        vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, 1));
-        vectorYRef.copyFrom(mBLASData.L2_cGEMV_o_T);
-        verifyMatrix(vectorYRef, vectorXC);
-
-        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
-        vectorXC.copyFrom(mBLASData.L2_cGEMV_x_n1);
-        mBLAS.CGEMV(trans, alphaC, matrixAC, vectorYC, incY, betaC, vectorXC, incX);
-        vectorYRef.copyFrom(mBLASData.L2_cGEMV_o_H);
-        verifyMatrix(vectorYRef, vectorXC);
-
-        // Test for incX = 2 & incY = 3;
-        trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        incX = 2;
-        incY = 3;
-        int dimX = 1 + (mBLASData.dN - 1) * incX;
-        int dimY = 1 + (mBLASData.dM - 1) * incY;
-        vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimX, 1));
-        vectorYC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimY, 1));
-        vectorXC.copyFrom(mBLASData.L2_cGEMV_x_n2);
-        vectorYC.copyFrom(mBLASData.L2_cGEMV_y_m2);
-
-        mBLAS.CGEMV(trans, alphaC, matrixAC, vectorXC, incX, betaC, vectorYC, incY);
-        vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimY, 1));
-        vectorYRef.copyFrom(mBLASData.L2_cGEMV_o_N2);
-        verifyMatrix(vectorYRef, vectorYC);
-
-        mRS.finish();
-        checkError();
-    }
-
-    public void test_L2_ZGEMV_Correctness() {
-        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        int incX = 1;
-        int incY = 1;
-
-        // Populate input allocations
-        Allocation matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dM));
-        Allocation vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, 1));
-        Allocation vectorYZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dM, 1));
-        matrixAZ.copyFrom(mBLASData.L2_zGEMV_A_mn);
-        vectorXZ.copyFrom(mBLASData.L2_zGEMV_x_n1);
-        vectorYZ.copyFrom(mBLASData.L2_zGEMV_y_m1);
-
-        // Test for the default case: NO_TRANS
-        mBLAS.ZGEMV(trans, alphaZ, matrixAZ, vectorXZ, incX, betaZ, vectorYZ, incY);
-        Allocation vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dM, 1));
-        vectorYRef.copyFrom(mBLASData.L2_zGEMV_o_N);
-        verifyMatrix(vectorYRef, vectorYZ);
-
-        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
-        trans = ScriptIntrinsicBLAS.TRANSPOSE;
-        // Reload vector Y, since it was overwritten by BLAS.
-        vectorYZ.copyFrom(mBLASData.L2_zGEMV_y_m1);
-        // After Transpose matrixA, vectorX and vectorY are exchanged to match the dim of A.T
-        mBLAS.ZGEMV(trans, alphaZ, matrixAZ, vectorYZ, incY, betaZ, vectorXZ, incX);
-        vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, 1));
-        vectorYRef.copyFrom(mBLASData.L2_zGEMV_o_T);
-        verifyMatrix(vectorYRef, vectorXZ);
-
-        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
-        vectorXZ.copyFrom(mBLASData.L2_zGEMV_x_n1);
-        mBLAS.ZGEMV(trans, alphaZ, matrixAZ, vectorYZ, incY, betaZ, vectorXZ, incX);
-        vectorYRef.copyFrom(mBLASData.L2_zGEMV_o_H);
-        verifyMatrix(vectorYRef, vectorXZ);
-
-        // Test for incX = 2 & incY = 3;
-        trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        incX = 2;
-        incY = 3;
-        int dimX = 1 + (mBLASData.dN - 1) * incX;
-        int dimY = 1 + (mBLASData.dM - 1) * incY;
-        vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimX, 1));
-        vectorYZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimY, 1));
-        vectorXZ.copyFrom(mBLASData.L2_zGEMV_x_n2);
-        vectorYZ.copyFrom(mBLASData.L2_zGEMV_y_m2);
-
-        mBLAS.ZGEMV(trans, alphaZ, matrixAZ, vectorXZ, incX, betaZ, vectorYZ, incY);
-        vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimY, 1));
-        vectorYRef.copyFrom(mBLASData.L2_zGEMV_o_N2);
-        verifyMatrix(vectorYRef, vectorYZ);
-
-        mRS.finish();
-        checkError();
-    }
-
-
-
-    private void xGBMV_API_test(int trans, int KL, int KU, int incX, int incY, ArrayList<Allocation> mMatrix) {
-        for (Allocation matA : mMatrix) {
-            for (Allocation vecX : mMatrix) {
-                if (!validateVecInput(vecX)) {
-                    continue;
-                }
-                for (Allocation vecY : mMatrix) {
-                    if (!validateVecInput(vecY)) {
-                        continue;
-                    }
-                    Element elemA = matA.getType().getElement();
-                    if (validateGEMV(elemA, trans, matA, vecX, incX, vecY, incY) && KU >= 0 && KL >= 0) {
-                        try {
-                            if (elemA.isCompatible(Element.F32(mRS))) {
-                                mBLAS.SGBMV(trans, KL, KU, alphaS, matA, vecX, incX, betaS, vecY, incY);
-                            } else if (elemA.isCompatible(Element.F64(mRS))) {
-                                mBLAS.DGBMV(trans, KL, KU, alphaD, matA, vecX, incX, betaD, vecY, incY);
-                            } else if (elemA.isCompatible(Element.F32_2(mRS))) {
-                                mBLAS.CGBMV(trans, KL, KU, alphaC, matA, vecX, incX, betaC, vecY, incY);
-                            } else if (elemA.isCompatible(Element.F64_2(mRS))) {
-                                mBLAS.ZGBMV(trans, KL, KU, alphaZ, matA, vecX, incX, betaZ, vecY, incY);
-                            }
-                        } catch (RSRuntimeException e) {
-                            fail("should NOT throw RSRuntimeException");
-                        }
-                    } else {
-                        try {
-                            mBLAS.SGBMV(trans, KL, KU, alphaS, matA, vecX, incX, betaS, vecY, incY);
-                            fail("should throw RSRuntimeException for SGBMV");
-                        } catch (RSRuntimeException e) {
-                        }
-                        try {
-                            mBLAS.DGBMV(trans, KL, KU, alphaD, matA, vecX, incX, betaD, vecY, incY);
-                            fail("should throw RSRuntimeException for DGBMV");
-                        } catch (RSRuntimeException e) {
-                        }
-                        try {
-                            mBLAS.CGBMV(trans, KL, KU, alphaC, matA, vecX, incX, betaC, vecY, incY);
-                            fail("should throw RSRuntimeException for CGBMV");
-                        } catch (RSRuntimeException e) {
-                        }
-                        try {
-                            mBLAS.ZGBMV(trans, KL, KU, alphaZ, matA, vecX, incX, betaZ, vecY, incY);
-                            fail("should throw RSRuntimeException for ZGBMV");
-                        } catch (RSRuntimeException e) {
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    public void L2_xGBMV_API(ArrayList<Allocation> mMatrix) {
-        for (int trans : mTranspose) {
-            for (int incX : mInc) {
-                for (int K : mK) {
-                    xGBMV_API_test(trans, K, K, incX, incX, mMatrix);
-                }
-            }
-        }
-    }
-
-    public void test_L2_SGBMV_API() {
-        L2_xGBMV_API(mMatrixS);
-    }
-
-    public void test_L2_DGBMV_API() {
-        L2_xGBMV_API(mMatrixD);
-    }
-
-    public void test_L2_CGBMV_API() {
-        L2_xGBMV_API(mMatrixC);
-    }
-
-    public void test_L2_ZGBMV_API() {
-        L2_xGBMV_API(mMatrixZ);
-    }
-
-    public void test_L2_SGBMV_Correctness() {
-        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        int incX = 1;
-        int incY = 1;
-
-        // Populate input allocations
-        Allocation matrixAS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dM));
-        Allocation vectorXS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, 1));
-        Allocation vectorYS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dM, 1));
-        matrixAS.copy2DRangeFrom(0, 0, mBLASData.KL + mBLASData.KU + 1, mBLASData.dM, mBLASData.L2_sGBMV_A_mn);
-        vectorXS.copyFrom(mBLASData.L2_sGBMV_x_n1);
-        vectorYS.copyFrom(mBLASData.L2_sGBMV_y_m1);
-
-        // Test for the default case: NO_TRANS
-        mBLAS.SGBMV(trans, mBLASData.KL, mBLASData.KU, alphaS, matrixAS, vectorXS, incX, betaS, vectorYS, incY);
-        Allocation vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dM, 1));
-        vectorYRef.copyFrom(mBLASData.L2_sGBMV_o_N);
-        verifyMatrix(vectorYRef, vectorYS);
-
-        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
-        trans = ScriptIntrinsicBLAS.TRANSPOSE;
-        // Reload vector Y, since it was overwritten by BLAS.
-        vectorYS.copyFrom(mBLASData.L2_sGBMV_y_m1);
-        // After Transpose matrixA, vectorX and vectorY are exchanged to match the dim of A.T
-        mBLAS.SGBMV(trans, mBLASData.KL, mBLASData.KU, alphaS, matrixAS, vectorYS, incY, betaS, vectorXS, incX);
-        vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, 1));
-        vectorYRef.copyFrom(mBLASData.L2_sGBMV_o_T);
-        verifyMatrix(vectorYRef, vectorXS);
-
-        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
-        vectorXS.copyFrom(mBLASData.L2_sGBMV_x_n1);
-        mBLAS.SGBMV(trans, mBLASData.KL, mBLASData.KU, alphaS, matrixAS, vectorYS, incY, betaS, vectorXS, incX);
-        vectorYRef.copyFrom(mBLASData.L2_sGBMV_o_H);
-        verifyMatrix(vectorYRef, vectorXS);
-
-        // Test for incX = 2 & incY = 3;
-        trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        incX = 2;
-        incY = 3;
-        int dimX = 1 + (mBLASData.dN - 1) * incX;
-        int dimY = 1 + (mBLASData.dM - 1) * incY;
-        vectorXS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimX, 1));
-        vectorYS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimY, 1));
-        vectorXS.copyFrom(mBLASData.L2_sGBMV_x_n2);
-        vectorYS.copyFrom(mBLASData.L2_sGBMV_y_m2);
-
-        mBLAS.SGBMV(trans, mBLASData.KL, mBLASData.KU, alphaS, matrixAS, vectorXS, incX, betaS, vectorYS, incY);
-        vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimY, 1));
-        vectorYRef.copyFrom(mBLASData.L2_sGBMV_o_N2);
-        verifyMatrix(vectorYRef, vectorYS);
-
-        mRS.finish();
-        checkError();
-    }
-
-    public void test_L2_DGBMV_Correctness() {
-        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        int incX = 1;
-        int incY = 1;
-
-        // Populate input allocations
-        Allocation matrixAD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dM));
-        Allocation vectorXD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, 1));
-        Allocation vectorYD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dM, 1));
-        matrixAD.copy2DRangeFrom(0, 0, mBLASData.KL + mBLASData.KU + 1, mBLASData.dM, mBLASData.L2_dGBMV_A_mn);
-        vectorXD.copyFrom(mBLASData.L2_dGBMV_x_n1);
-        vectorYD.copyFrom(mBLASData.L2_dGBMV_y_m1);
-
-        // Test for the default case: NO_TRANS
-        mBLAS.DGBMV(trans, mBLASData.KL, mBLASData.KU, alphaD, matrixAD, vectorXD, incX, betaD, vectorYD, incY);
-        Allocation vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dM, 1));
-        vectorYRef.copyFrom(mBLASData.L2_dGBMV_o_N);
-        verifyMatrix(vectorYRef, vectorYD);
-
-        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
-        trans = ScriptIntrinsicBLAS.TRANSPOSE;
-        // Reload vector Y, since it was overwritten by BLAS.
-        vectorYD.copyFrom(mBLASData.L2_dGBMV_y_m1);
-        // After Transpose matrixA, vectorX and vectorY are exchanged to match the dim of A.T
-        mBLAS.DGBMV(trans, mBLASData.KL, mBLASData.KU, alphaD, matrixAD, vectorYD, incY, betaD, vectorXD, incX);
-        vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, 1));
-        vectorYRef.copyFrom(mBLASData.L2_dGBMV_o_T);
-        verifyMatrix(vectorYRef, vectorXD);
-
-        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
-        vectorXD.copyFrom(mBLASData.L2_dGBMV_x_n1);
-        mBLAS.DGBMV(trans, mBLASData.KL, mBLASData.KU, alphaD, matrixAD, vectorYD, incY, betaD, vectorXD, incX);
-        vectorYRef.copyFrom(mBLASData.L2_dGBMV_o_H);
-        verifyMatrix(vectorYRef, vectorXD);
-
-        // Test for incX = 2 & incY = 3;
-        trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        incX = 2;
-        incY = 3;
-        int dimX = 1 + (mBLASData.dN - 1) * incX;
-        int dimY = 1 + (mBLASData.dM - 1) * incY;
-        vectorXD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimX, 1));
-        vectorYD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimY, 1));
-        vectorXD.copyFrom(mBLASData.L2_dGBMV_x_n2);
-        vectorYD.copyFrom(mBLASData.L2_dGBMV_y_m2);
-
-        mBLAS.DGBMV(trans, mBLASData.KL, mBLASData.KU, alphaD, matrixAD, vectorXD, incX, betaD, vectorYD, incY);
-        vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimY, 1));
-        vectorYRef.copyFrom(mBLASData.L2_dGBMV_o_N2);
-        verifyMatrix(vectorYRef, vectorYD);
-
-        mRS.finish();
-        checkError();
-    }
-
-    public void test_L2_CGBMV_Correctness() {
-        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        int incX = 1;
-        int incY = 1;
-
-        // Populate input allocations
-        Allocation matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dM));
-        Allocation vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, 1));
-        Allocation vectorYC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dM, 1));
-        matrixAC.copy2DRangeFrom(0, 0, mBLASData.KL + mBLASData.KU + 1, mBLASData.dM, mBLASData.L2_cGBMV_A_mn);
-        vectorXC.copyFrom(mBLASData.L2_cGBMV_x_n1);
-        vectorYC.copyFrom(mBLASData.L2_cGBMV_y_m1);
-
-        // Test for the default case: NO_TRANS
-        mBLAS.CGBMV(trans, mBLASData.KL, mBLASData.KU, alphaC, matrixAC, vectorXC, incX, betaC, vectorYC, incY);
-        Allocation vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dM, 1));
-        vectorYRef.copyFrom(mBLASData.L2_cGBMV_o_N);
-        verifyMatrix(vectorYRef, vectorYC);
-
-        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
-        trans = ScriptIntrinsicBLAS.TRANSPOSE;
-        // Reload vector Y, since it was overwritten by BLAS.
-        vectorYC.copyFrom(mBLASData.L2_cGBMV_y_m1);
-        // After Transpose matrixA, vectorX and vectorY are exchanged to match the dim of A.T
-        mBLAS.CGBMV(trans, mBLASData.KL, mBLASData.KU, alphaC, matrixAC, vectorYC, incY, betaC, vectorXC, incX);
-        vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, 1));
-        vectorYRef.copyFrom(mBLASData.L2_cGBMV_o_T);
-        verifyMatrix(vectorYRef, vectorXC);
-
-        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
-        vectorXC.copyFrom(mBLASData.L2_cGBMV_x_n1);
-        mBLAS.CGBMV(trans, mBLASData.KL, mBLASData.KU, alphaC, matrixAC, vectorYC, incY, betaC, vectorXC, incX);
-        vectorYRef.copyFrom(mBLASData.L2_cGBMV_o_H);
-        verifyMatrix(vectorYRef, vectorXC);
-
-        // Test for incX = 2 & incY = 3;
-        trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        incX = 2;
-        incY = 3;
-        int dimX = 1 + (mBLASData.dN - 1) * incX;
-        int dimY = 1 + (mBLASData.dM - 1) * incY;
-        vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimX, 1));
-        vectorYC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimY, 1));
-        vectorXC.copyFrom(mBLASData.L2_cGBMV_x_n2);
-        vectorYC.copyFrom(mBLASData.L2_cGBMV_y_m2);
-
-        mBLAS.CGBMV(trans, mBLASData.KL, mBLASData.KU, alphaC, matrixAC, vectorXC, incX, betaC, vectorYC, incY);
-        vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimY, 1));
-        vectorYRef.copyFrom(mBLASData.L2_cGBMV_o_N2);
-        verifyMatrix(vectorYRef, vectorYC);
-
-        mRS.finish();
-        checkError();
-    }
-
-    public void test_L2_ZGBMV_Correctness() {
-        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        int incX = 1;
-        int incY = 1;
-
-        // Populate input allocations
-        Allocation matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dM));
-        Allocation vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, 1));
-        Allocation vectorYZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dM, 1));
-        matrixAZ.copy2DRangeFrom(0, 0, mBLASData.KL + mBLASData.KU + 1, mBLASData.dM, mBLASData.L2_zGBMV_A_mn);
-        vectorXZ.copyFrom(mBLASData.L2_zGBMV_x_n1);
-        vectorYZ.copyFrom(mBLASData.L2_zGBMV_y_m1);
-
-        // Test for the default case: NO_TRANS
-        mBLAS.ZGBMV(trans, mBLASData.KL, mBLASData.KU, alphaZ, matrixAZ, vectorXZ, incX, betaZ, vectorYZ, incY);
-        Allocation vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dM, 1));
-        vectorYRef.copyFrom(mBLASData.L2_zGBMV_o_N);
-        verifyMatrix(vectorYRef, vectorYZ);
-
-        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
-        trans = ScriptIntrinsicBLAS.TRANSPOSE;
-        // Reload vector Y, since it was overwritten by BLAS.
-        vectorYZ.copyFrom(mBLASData.L2_zGBMV_y_m1);
-        // After Transpose matrixA, vectorX and vectorY are exchanged to match the dim of A.T
-        mBLAS.ZGBMV(trans, mBLASData.KL, mBLASData.KU, alphaZ, matrixAZ, vectorYZ, incY, betaZ, vectorXZ, incX);
-        vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, 1));
-        vectorYRef.copyFrom(mBLASData.L2_zGBMV_o_T);
-        verifyMatrix(vectorYRef, vectorXZ);
-
-        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
-        vectorXZ.copyFrom(mBLASData.L2_zGBMV_x_n1);
-        mBLAS.ZGBMV(trans, mBLASData.KL, mBLASData.KU, alphaZ, matrixAZ, vectorYZ, incX, betaZ, vectorXZ, incY);
-        vectorYRef.copyFrom(mBLASData.L2_zGBMV_o_H);
-        verifyMatrix(vectorYRef, vectorXZ);
-
-        // Test for incX = 2 & incY = 3;
-        trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        incX = 2;
-        incY = 3;
-        int dimX = 1 + (mBLASData.dN - 1) * incX;
-        int dimY = 1 + (mBLASData.dM - 1) * incY;
-        vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimX, 1));
-        vectorYZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimY, 1));
-        vectorXZ.copyFrom(mBLASData.L2_zGBMV_x_n2);
-        vectorYZ.copyFrom(mBLASData.L2_zGBMV_y_m2);
-
-        mBLAS.ZGBMV(trans, mBLASData.KL, mBLASData.KU, alphaZ, matrixAZ, vectorXZ, incX, betaZ, vectorYZ, incY);
-        vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimY, 1));
-        vectorYRef.copyFrom(mBLASData.L2_zGBMV_o_N2);
-        verifyMatrix(vectorYRef, vectorYZ);
-
-        mRS.finish();
-        checkError();
-    }
-
-
-    private void xHEMV_API_test(int Uplo, int incX, int incY, ArrayList<Allocation> mMatrix) {
-        for (Allocation matA : mMatrix) {
-            for (Allocation vecX : mMatrix) {
-                if (!validateVecInput(vecX)) {
-                    continue;
-                }
-                for (Allocation vecY : mMatrix) {
-                    if (!validateVecInput(vecY)) {
-                        continue;
-                    }
-                    Element elemA = matA.getType().getElement();
-                    if (validateSYR2(elemA, Uplo, vecX, incX, vecY, incY, matA)) {
-                        try {
-                            if (elemA.isCompatible(Element.F32_2(mRS))) {
-                                mBLAS.CHEMV(Uplo, alphaC, matA, vecX, incX, betaC, vecY, incY);
-                            } else if (elemA.isCompatible(Element.F64_2(mRS))) {
-                                mBLAS.ZHEMV(Uplo, alphaZ, matA, vecX, incX, betaZ, vecY, incY);
-                            }
-                        } catch (RSRuntimeException e) {
-                            fail("should NOT throw RSRuntimeException");
-                        }
-                    } else {
-                        try {
-                            mBLAS.CHEMV(Uplo, alphaC, matA, vecX, incX, betaC, vecY, incY);
-                            fail("should throw RSRuntimeException for CHEMV");
-                        } catch (RSRuntimeException e) {
-                        }
-                        try {
-                            mBLAS.ZHEMV(Uplo, alphaZ, matA, vecX, incX, betaZ, vecY, incY);
-                            fail("should throw RSRuntimeException for ZHEMV");
-                        } catch (RSRuntimeException e) {
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    public void L2_xHEMV_API(ArrayList<Allocation> mMatrix) {
-        for (int Uplo : mUplo) {
-            for (int incX : mInc) {
-                xHEMV_API_test(Uplo, incX, incX, mMatrix);
-            }
-        }
-    }
-
-    public void test_L2_CHEMV_API() {
-        L2_xHEMV_API(mMatrixC);
-    }
-
-    public void test_L2_ZHEMV_API() {
-        L2_xHEMV_API(mMatrixZ);
-    }
-
-    public void test_L2_CHEMV_Correctness() {
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-        int incX = 1;
-        int incY = 1;
-
-        // Populate input allocations
-        Allocation matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dN));
-        Allocation vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, 1));
-        Allocation vectorYC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, 1));
-        matrixAC.copyFrom(mBLASData.L2_cHEMV_A_nn);
-        vectorXC.copyFrom(mBLASData.L2_cHEMV_x_n1);
-        vectorYC.copyFrom(mBLASData.L2_cHEMV_y_n1);
-
-        // Test for the default case:
-        mBLAS.CHEMV(uplo, alphaC, matrixAC, vectorXC, incX, betaC, vectorYC, incY);
-        Allocation vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, 1));
-        vectorYRef.copyFrom(mBLASData.L2_cHEMV_o_N);
-        verifyMatrix(vectorYRef, vectorYC);
-
-        // Test for incX = 2 & incY = 3;
-        incX = 2;
-        incY = 3;
-        int dimX = 1 + (mBLASData.dN - 1) * incX;
-        int dimY = 1 + (mBLASData.dN - 1) * incY;
-        vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimX, 1));
-        vectorYC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimY, 1));
-        vectorXC.copyFrom(mBLASData.L2_cHEMV_x_n2);
-        vectorYC.copyFrom(mBLASData.L2_cHEMV_y_n2);
-
-        mBLAS.CHEMV(uplo, alphaC, matrixAC, vectorXC, incX, betaC, vectorYC, incY);
-        vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimY, 1));
-        vectorYRef.copyFrom(mBLASData.L2_cHEMV_o_N2);
-        verifyMatrix(vectorYRef, vectorYC);
-
-        mRS.finish();
-        checkError();
-    }
-
-    public void test_L2_ZHEMV_Correctness() {
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-        int incX = 1;
-        int incY = 1;
-
-        // Populate input allocations
-        Allocation matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dN));
-        Allocation vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, 1));
-        Allocation vectorYZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, 1));
-        matrixAZ.copyFrom(mBLASData.L2_zHEMV_A_nn);
-        vectorXZ.copyFrom(mBLASData.L2_zHEMV_x_n1);
-        vectorYZ.copyFrom(mBLASData.L2_zHEMV_y_n1);
-
-        // Test for the default case: NO_TRANS
-        mBLAS.ZHEMV(uplo, alphaZ, matrixAZ, vectorXZ, incX, betaZ, vectorYZ, incY);
-        Allocation vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, 1));
-        vectorYRef.copyFrom(mBLASData.L2_zHEMV_o_N);
-        verifyMatrix(vectorYRef, vectorYZ);
-
-        // Test for incX = 2 & incY = 3;
-        incX = 2;
-        incY = 3;
-        int dimX = 1 + (mBLASData.dN - 1) * incX;
-        int dimY = 1 + (mBLASData.dN - 1) * incY;
-        vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimX, 1));
-        vectorYZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimY, 1));
-        vectorXZ.copyFrom(mBLASData.L2_zHEMV_x_n2);
-        vectorYZ.copyFrom(mBLASData.L2_zHEMV_y_n2);
-
-        mBLAS.ZHEMV(uplo, alphaZ, matrixAZ, vectorXZ, incX, betaZ, vectorYZ, incY);
-        vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimY, 1));
-        vectorYRef.copyFrom(mBLASData.L2_zHEMV_o_N2);
-        verifyMatrix(vectorYRef, vectorYZ);
-
-        mRS.finish();
-        checkError();
-    }
-
-
-
-    private void xHBMV_API_test(int Uplo, int K, int incX, int incY, ArrayList<Allocation> mMatrix) {
-        for (Allocation matA : mMatrix) {
-            for (Allocation vecX : mMatrix) {
-                if (!validateVecInput(vecX)) {
-                    continue;
-                }
-                for (Allocation vecY : mMatrix) {
-                    if (!validateVecInput(vecY)) {
-                        continue;
-                    }
-                    Element elemA = matA.getType().getElement();
-                    if (validateSYR2(elemA, Uplo, vecX, incX, vecY, incY, matA) && K >= 0) {
-                        try {
-                            if (elemA.isCompatible(Element.F32_2(mRS))) {
-                                mBLAS.CHBMV(Uplo, K, alphaC, matA, vecX, incX, betaC, vecY, incY);
-                            } else if (elemA.isCompatible(Element.F64_2(mRS))) {
-                                mBLAS.ZHBMV(Uplo, K, alphaZ, matA, vecX, incX, betaZ, vecY, incY);
-                            }
-                        } catch (RSRuntimeException e) {
-                            fail("should NOT throw RSRuntimeException");
-                        }
-                    } else {
-                        try {
-                            mBLAS.CHBMV(Uplo, K, alphaC, matA, vecX, incX, betaC, vecY, incY);
-                            fail("should throw RSRuntimeException for CHBMV");
-                        } catch (RSRuntimeException e) {
-                        }
-                        try {
-                            mBLAS.ZHBMV(Uplo, K, alphaZ, matA, vecX, incX, betaZ, vecY, incY);
-                            fail("should throw RSRuntimeException for ZHBMV");
-                        } catch (RSRuntimeException e) {
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    public void L2_xHBMV_API(ArrayList<Allocation> mMatrix) {
-        for (int Uplo : mUplo) {
-            for (int K : mK) {
-                for (int incX : mInc) {
-                        xHBMV_API_test(Uplo, K, incX, incX, mMatrix);
-                }
-            }
-        }
-    }
-
-    public void test_L2_CHBMV_API() {
-        L2_xHBMV_API(mMatrixC);
-    }
-
-    public void test_L2_ZHBMV_API() {
-        L2_xHBMV_API(mMatrixZ);
-    }
-
-    public void test_L2_CHBMV_Correctness() {
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-        int incX = 1;
-        int incY = 1;
-
-        // Populate input allocations
-        Allocation matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dN));
-        Allocation vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, 1));
-        Allocation vectorYC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, 1));
-        matrixAC.copy2DRangeFrom(0, 0, mBLASData.KL + 1, mBLASData.dN, mBLASData.L2_cHBMV_A_nn);
-        vectorXC.copyFrom(mBLASData.L2_cHBMV_x_n1);
-        vectorYC.copyFrom(mBLASData.L2_cHBMV_y_n1);
-
-        // Test for the default case:
-        mBLAS.CHBMV(uplo, mBLASData.KL, alphaC, matrixAC, vectorXC, incX, betaC, vectorYC, incY);
-        Allocation vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, 1));
-        vectorYRef.copyFrom(mBLASData.L2_cHBMV_o_N);
-        verifyMatrix(vectorYRef, vectorYC);
-
-        // Test for incX = 2 & incY = 3;
-        incX = 2;
-        incY = 3;
-        int dimX = 1 + (mBLASData.dN - 1) * incX;
-        int dimY = 1 + (mBLASData.dN - 1) * incY;
-        vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimX, 1));
-        vectorYC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimY, 1));
-        vectorXC.copyFrom(mBLASData.L2_cHBMV_x_n2);
-        vectorYC.copyFrom(mBLASData.L2_cHBMV_y_n2);
-
-        mBLAS.CHBMV(uplo, mBLASData.KL, alphaC, matrixAC, vectorXC, incX, betaC, vectorYC, incY);
-        vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimY, 1));
-        vectorYRef.copyFrom(mBLASData.L2_cHBMV_o_N2);
-        verifyMatrix(vectorYRef, vectorYC);
-
-        mRS.finish();
-        checkError();
-    }
-
-    public void test_L2_ZHBMV_Correctness() {
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-        int incX = 1;
-        int incY = 1;
-
-        // Populate input allocations
-        Allocation matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dN));
-        Allocation vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, 1));
-        Allocation vectorYZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, 1));
-        matrixAZ.copy2DRangeFrom(0, 0, mBLASData.KL + 1, mBLASData.dN, mBLASData.L2_zHBMV_A_nn);
-        vectorXZ.copyFrom(mBLASData.L2_zHBMV_x_n1);
-        vectorYZ.copyFrom(mBLASData.L2_zHBMV_y_n1);
-
-        // Test for the default case: NO_TRANS
-        mBLAS.ZHBMV(uplo, mBLASData.KL, alphaZ, matrixAZ, vectorXZ, incX, betaZ, vectorYZ, incY);
-        Allocation vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, 1));
-        vectorYRef.copyFrom(mBLASData.L2_zHBMV_o_N);
-        verifyMatrix(vectorYRef, vectorYZ);
-
-        // Test for incX = 2 & incY = 3;
-        incX = 2;
-        incY = 3;
-        int dimX = 1 + (mBLASData.dN - 1) * incX;
-        int dimY = 1 + (mBLASData.dN - 1) * incY;
-        vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimX, 1));
-        vectorYZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimY, 1));
-        vectorXZ.copyFrom(mBLASData.L2_zHBMV_x_n2);
-        vectorYZ.copyFrom(mBLASData.L2_zHBMV_y_n2);
-
-        mBLAS.ZHBMV(uplo, mBLASData.KL, alphaZ, matrixAZ, vectorXZ, incX, betaZ, vectorYZ, incY);
-        vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimY, 1));
-        vectorYRef.copyFrom(mBLASData.L2_zHBMV_o_N2);
-        verifyMatrix(vectorYRef, vectorYZ);
-
-        mRS.finish();
-        checkError();
-    }
-
-
-    private void xHPMV_API_test(int Uplo, int incX, int incY, ArrayList<Allocation> mMatrix) {
-        for (Allocation matA : mMatrix) {
-            for (Allocation vecX : mMatrix) {
-                if (!validateVecInput(vecX)) {
-                    continue;
-                }
-                for (Allocation vecY : mMatrix) {
-                    if (!validateVecInput(vecY)) {
-                        continue;
-                    }
-                    Element elemA = matA.getType().getElement();
-                    if (validateSPR2(elemA, Uplo, vecX, incX, vecY, incY, matA)) {
-                        try {
-                            if (elemA.isCompatible(Element.F32_2(mRS))) {
-                                mBLAS.CHPMV(Uplo, alphaC, matA, vecX, incX, betaC, vecY, incY);
-                            } else if (elemA.isCompatible(Element.F64_2(mRS))) {
-                                mBLAS.ZHPMV(Uplo, alphaZ, matA, vecX, incX, betaZ, vecY, incY);
-                            }
-                        } catch (RSRuntimeException e) {
-                            fail("should NOT throw RSRuntimeException");
-                        }
-                    } else {
-                        try {
-                            mBLAS.CHPMV(Uplo, alphaC, matA, vecX, incX, betaC, vecY, incY);
-                            fail("should throw RSRuntimeException for CHPMV");
-                        } catch (RSRuntimeException e) {
-                        }
-                        try {
-                            mBLAS.ZHPMV(Uplo, alphaZ, matA, vecX, incX, betaZ, vecY, incY);
-                            fail("should throw RSRuntimeException for ZHPMV");
-                        } catch (RSRuntimeException e) {
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    public void L2_xHPMV_API(ArrayList<Allocation> mMatrix) {
-        for (int Uplo : mUplo) {
-            for (int incX : mInc) {
-                xHPMV_API_test(Uplo, incX, incX, mMatrix);
-            }
-        }
-    }
-
-    public void test_L2_CHPMV_API() {
-        L2_xHPMV_API(mMatrixC);
-    }
-
-    public void test_L2_ZHPMV_API() {
-        L2_xHPMV_API(mMatrixZ);
-    }
-
-    public void test_L2_CHPMV_Correctness() {
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-        int incX = 1;
-        int incY = 1;
-
-        // Populate input allocations
-        int N = mBLASData.dN;
-        Allocation matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), N * (N+1) / 2, 1));
-        Allocation vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), N, 1));
-        Allocation vectorYC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), N, 1));
-        matrixAC.copyFrom(mBLASData.L2_cHEMV_A_nn_pu);
-        vectorXC.copyFrom(mBLASData.L2_cHEMV_x_n1);
-        vectorYC.copyFrom(mBLASData.L2_cHEMV_y_n1);
-
-        // Test for the default case:
-        mBLAS.CHPMV(uplo, alphaC, matrixAC, vectorXC, incX, betaC, vectorYC, incY);
-        Allocation vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), N, 1));
-        vectorYRef.copyFrom(mBLASData.L2_cHEMV_o_N);
-        verifyMatrix(vectorYRef, vectorYC);
-
-        // Test for incX = 2 & incY = 3;
-        incX = 2;
-        incY = 3;
-        int dimX = 1 + (N - 1) * incX;
-        int dimY = 1 + (N - 1) * incY;
-        vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimX, 1));
-        vectorYC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimY, 1));
-        vectorXC.copyFrom(mBLASData.L2_cHEMV_x_n2);
-        vectorYC.copyFrom(mBLASData.L2_cHEMV_y_n2);
-
-        mBLAS.CHPMV(uplo, alphaC, matrixAC, vectorXC, incX, betaC, vectorYC, incY);
-        vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimY, 1));
-        vectorYRef.copyFrom(mBLASData.L2_cHEMV_o_N2);
-        verifyMatrix(vectorYRef, vectorYC);
-
-        mRS.finish();
-        checkError();
-    }
-
-    public void test_L2_ZHPMV_Correctness() {
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-        int incX = 1;
-        int incY = 1;
-
-        // Populate input allocations
-        int N = mBLASData.dN;
-        Allocation matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), N * (N+1) / 2, 1));
-        Allocation vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), N, 1));
-        Allocation vectorYZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), N, 1));
-        matrixAZ.copyFrom(mBLASData.L2_zHEMV_A_nn_pu);
-        vectorXZ.copyFrom(mBLASData.L2_zHEMV_x_n1);
-        vectorYZ.copyFrom(mBLASData.L2_zHEMV_y_n1);
-
-        // Test for the default case: NO_TRANS
-        mBLAS.ZHPMV(uplo, alphaZ, matrixAZ, vectorXZ, incX, betaZ, vectorYZ, incY);
-        Allocation vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), N, 1));
-        vectorYRef.copyFrom(mBLASData.L2_zHEMV_o_N);
-        verifyMatrix(vectorYRef, vectorYZ);
-
-        // Test for incX = 2 & incY = 3;
-        incX = 2;
-        incY = 3;
-        int dimX = 1 + (N - 1) * incX;
-        int dimY = 1 + (N - 1) * incY;
-        vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimX, 1));
-        vectorYZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimY, 1));
-        vectorXZ.copyFrom(mBLASData.L2_zHEMV_x_n2);
-        vectorYZ.copyFrom(mBLASData.L2_zHEMV_y_n2);
-
-        mBLAS.ZHPMV(uplo, alphaZ, matrixAZ, vectorXZ, incX, betaZ, vectorYZ, incY);
-        vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimY, 1));
-        vectorYRef.copyFrom(mBLASData.L2_zHEMV_o_N2);
-        verifyMatrix(vectorYRef, vectorYZ);
-
-        mRS.finish();
-        checkError();
-    }
-
-
-    private boolean validateSYMV(Element e, int Uplo, Allocation A, Allocation X, int incX, Allocation Y, int incY) {
-        if (!validateUplo(Uplo)) {
-            return false;
-        }
-        int N = A.getType().getY();
-        if (A.getType().getX() != N) {
-            return false;
-        }
-        if (!A.getType().getElement().isCompatible(e) ||
-            !X.getType().getElement().isCompatible(e) ||
-            !Y.getType().getElement().isCompatible(e) ) {
-            return false;
-        }
-        if (X.getType().getY() > 1 || Y.getType().getY() > 1) {
-            return false;
-        }
-
-        if (incX <= 0 || incY <= 0) {
-            return false;
-        }
-        int expectedXDim = 1 + (N - 1) * incX;
-        if (X.getType().getX() != expectedXDim) {
-            return false;
-        }
-        int expectedYDim = 1 + (N - 1) * incY;
-        if (Y.getType().getX() != expectedYDim) {
-            return false;
-        }
-        return true;
-    }
-
-    private void xSYMV_API_test(int Uplo, int incX, int incY, ArrayList<Allocation> mMatrix) {
-        for (Allocation matA : mMatrix) {
-            for (Allocation vecX : mMatrix) {
-                if (!validateVecInput(vecX)) {
-                    continue;
-                }
-                for (Allocation vecY : mMatrix) {
-                    if (!validateVecInput(vecY)) {
-                        continue;
-                    }
-                    Element elemA = matA.getType().getElement();
-                    if (validateSYMV(elemA, Uplo, matA, vecX, incX, vecY, incY)) {
-                        try {
-                            if (elemA.isCompatible(Element.F32(mRS))) {
-                                mBLAS.SSYMV(Uplo, alphaS, matA, vecX, incX, betaS, vecY, incY);
-                            } else if (elemA.isCompatible(Element.F64(mRS))) {
-                                mBLAS.DSYMV(Uplo, alphaD, matA, vecX, incX, betaD, vecY, incY);
-                            }
-                        } catch (RSRuntimeException e) {
-                            fail("should NOT throw RSRuntimeException");
-                        }
-                    } else {
-                        try {
-                            mBLAS.SSYMV(Uplo, alphaS, matA, vecX, incX, betaS, vecY, incY);
-                            fail("should throw RSRuntimeException for SSYMV");
-                        } catch (RSRuntimeException e) {
-                        }
-                        try {
-                            mBLAS.DSYMV(Uplo, alphaD, matA, vecX, incX, betaD, vecY, incY);
-                            fail("should throw RSRuntimeException for DSYMV");
-                        } catch (RSRuntimeException e) {
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    public void L2_xSYMV_API(ArrayList<Allocation> mMatrix) {
-        for (int Uplo : mUplo) {
-            for (int incX : mInc) {
-                xSYMV_API_test(Uplo, incX, incX, mMatrix);
-            }
-        }
-    }
-
-    public void test_L2_SSYMV_API() {
-        L2_xSYMV_API(mMatrixS);
-    }
-
-    public void test_L2_DSYMV_API() {
-        L2_xSYMV_API(mMatrixD);
-    }
-
-    public void test_L2_SSYMV_Correctness() {
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-        int incX = 1;
-        int incY = 1;
-
-        // Populate input allocations
-        Allocation matrixAS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dN));
-        Allocation vectorXS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, 1));
-        Allocation vectorYS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, 1));
-        matrixAS.copyFrom(mBLASData.L2_sSYMV_A_nn);
-        vectorXS.copyFrom(mBLASData.L2_sSYMV_x_n1);
-        vectorYS.copyFrom(mBLASData.L2_sSYMV_y_n1);
-
-        // Test for the default case:
-        mBLAS.SSYMV(uplo, alphaS, matrixAS, vectorXS, incX, betaS, vectorYS, incY);
-        Allocation vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, 1));
-        vectorYRef.copyFrom(mBLASData.L2_sSYMV_o_N);
-        verifyMatrix(vectorYRef, vectorYS);
-
-        // Test for incX = 2 & incY = 3;
-        incX = 2;
-        incY = 3;
-        int dimX = 1 + (mBLASData.dN - 1) * incX;
-        int dimY = 1 + (mBLASData.dN - 1) * incY;
-        vectorXS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimX, 1));
-        vectorYS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimY, 1));
-        vectorXS.copyFrom(mBLASData.L2_sSYMV_x_n2);
-        vectorYS.copyFrom(mBLASData.L2_sSYMV_y_n2);
-
-        mBLAS.SSYMV(uplo, alphaS, matrixAS, vectorXS, incX, betaS, vectorYS, incY);
-        vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimY, 1));
-        vectorYRef.copyFrom(mBLASData.L2_sSYMV_o_N2);
-        verifyMatrix(vectorYRef, vectorYS);
-
-        mRS.finish();
-        checkError();
-    }
-
-    public void test_L2_DSYMV_Correctness() {
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-        int incX = 1;
-        int incY = 1;
-
-        // Populate input allocations
-        Allocation matrixAD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dN));
-        Allocation vectorXD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, 1));
-        Allocation vectorYD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, 1));
-        matrixAD.copyFrom(mBLASData.L2_dSYMV_A_nn);
-        vectorXD.copyFrom(mBLASData.L2_dSYMV_x_n1);
-        vectorYD.copyFrom(mBLASData.L2_dSYMV_y_n1);
-
-        // Test for the default case:
-        mBLAS.DSYMV(uplo, alphaD, matrixAD, vectorXD, incX, betaD, vectorYD, incY);
-        Allocation vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, 1));
-        vectorYRef.copyFrom(mBLASData.L2_dSYMV_o_N);
-        verifyMatrix(vectorYRef, vectorYD);
-
-        // Test for incX = 2 & incY = 3;
-        incX = 2;
-        incY = 3;
-        int dimX = 1 + (mBLASData.dN - 1) * incX;
-        int dimY = 1 + (mBLASData.dN - 1) * incY;
-        vectorXD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimX, 1));
-        vectorYD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimY, 1));
-        vectorXD.copyFrom(mBLASData.L2_dSYMV_x_n2);
-        vectorYD.copyFrom(mBLASData.L2_dSYMV_y_n2);
-
-        mBLAS.DSYMV(uplo, alphaD, matrixAD, vectorXD, incX, betaD, vectorYD, incY);
-        vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimY, 1));
-        vectorYRef.copyFrom(mBLASData.L2_dSYMV_o_N2);
-        verifyMatrix(vectorYRef, vectorYD);
-
-        mRS.finish();
-        checkError();
-    }
-
-
-
-    private void xSBMV_API_test(int Uplo, int K, int incX, int incY, ArrayList<Allocation> mMatrix) {
-        for (Allocation matA : mMatrix) {
-            for (Allocation vecX : mMatrix) {
-                if (!validateVecInput(vecX)) {
-                    continue;
-                }
-                for (Allocation vecY : mMatrix) {
-                    if (!validateVecInput(vecY)) {
-                        continue;
-                    }
-                    Element elemA = matA.getType().getElement();
-                    if (validateSYMV(elemA, Uplo, matA, vecX, incX, vecY, incY) && K >= 0) {
-                        try {
-                            if (elemA.isCompatible(Element.F32(mRS))) {
-                                mBLAS.SSBMV(Uplo, K, alphaS, matA, vecX, incX, betaS, vecY, incY);
-                            } else if (elemA.isCompatible(Element.F64(mRS))) {
-                                mBLAS.DSBMV(Uplo, K, alphaD, matA, vecX, incX, betaD, vecY, incY);
-                            }
-                        } catch (RSRuntimeException e) {
-                            fail("should NOT throw RSRuntimeException");
-                        }
-                    } else {
-                        try {
-                            mBLAS.SSBMV(Uplo, K, alphaS, matA, vecX, incX, betaS, vecY, incY);
-                            fail("should throw RSRuntimeException for SSBMV");
-                        } catch (RSRuntimeException e) {
-                        }
-                        try {
-                            mBLAS.DSBMV(Uplo, K, alphaD, matA, vecX, incX, betaD, vecY, incY);
-                            fail("should throw RSRuntimeException for DSBMV");
-                        } catch (RSRuntimeException e) {
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    public void L2_xSBMV_API(ArrayList<Allocation> mMatrix) {
-        for (int Uplo : mUplo) {
-            for (int K : mK) {
-                for (int incX : mInc) {
-                    xSBMV_API_test(Uplo, K, incX, incX, mMatrix);
-                }
-            }
-        }
-    }
-
-    public void test_L2_SSBMV_API() {
-        L2_xSBMV_API(mMatrixS);
-    }
-
-    public void test_L2_DSBMV_API() {
-        L2_xSBMV_API(mMatrixD);
-    }
-
-    public void test_L2_SSBMV_Correctness() {
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-        int incX = 1;
-        int incY = 1;
-
-        // Populate input allocations
-        Allocation matrixAS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dN));
-        Allocation vectorXS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, 1));
-        Allocation vectorYS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, 1));
-        matrixAS.copy2DRangeFrom(0, 0, mBLASData.KL + 1, mBLASData.dN, mBLASData.L2_sSBMV_A_nn);
-        vectorXS.copyFrom(mBLASData.L2_sSBMV_x_n1);
-        vectorYS.copyFrom(mBLASData.L2_sSBMV_y_n1);
-
-        // Test for the default case:
-        mBLAS.SSBMV(uplo, mBLASData.KL, alphaS, matrixAS, vectorXS, incX, betaS, vectorYS, incY);
-        Allocation vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, 1));
-        vectorYRef.copyFrom(mBLASData.L2_sSBMV_o_N);
-        verifyMatrix(vectorYRef, vectorYS);
-
-        // Test for incX = 2 & incY = 3;
-        incX = 2;
-        incY = 3;
-        int dimX = 1 + (mBLASData.dN - 1) * incX;
-        int dimY = 1 + (mBLASData.dN - 1) * incY;
-        vectorXS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimX, 1));
-        vectorYS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimY, 1));
-        vectorXS.copyFrom(mBLASData.L2_sSBMV_x_n2);
-        vectorYS.copyFrom(mBLASData.L2_sSBMV_y_n2);
-
-        mBLAS.SSBMV(uplo, mBLASData.KL, alphaS, matrixAS, vectorXS, incX, betaS, vectorYS, incY);
-        vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimY, 1));
-        vectorYRef.copyFrom(mBLASData.L2_sSBMV_o_N2);
-        verifyMatrix(vectorYRef, vectorYS);
-
-        mRS.finish();
-        checkError();
-    }
-
-    public void test_L2_DSBMV_Correctness() {
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-        int incX = 1;
-        int incY = 1;
-
-        // Populate input allocations
-        Allocation matrixAD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dN));
-        Allocation vectorXD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, 1));
-        Allocation vectorYD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, 1));
-        matrixAD.copy2DRangeFrom(0, 0, mBLASData.KL + 1, mBLASData.dN, mBLASData.L2_dSBMV_A_nn);
-        vectorXD.copyFrom(mBLASData.L2_dSBMV_x_n1);
-        vectorYD.copyFrom(mBLASData.L2_dSBMV_y_n1);
-
-        // Test for the default case:
-        mBLAS.DSBMV(uplo, mBLASData.KL, alphaD, matrixAD, vectorXD, incX, betaD, vectorYD, incY);
-        Allocation vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, 1));
-        vectorYRef.copyFrom(mBLASData.L2_dSBMV_o_N);
-        verifyMatrix(vectorYRef, vectorYD);
-
-        // Test for incX = 2 & incY = 3;
-        incX = 2;
-        incY = 3;
-        int dimX = 1 + (mBLASData.dN - 1) * incX;
-        int dimY = 1 + (mBLASData.dN - 1) * incY;
-        vectorXD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimX, 1));
-        vectorYD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimY, 1));
-        vectorXD.copyFrom(mBLASData.L2_dSBMV_x_n2);
-        vectorYD.copyFrom(mBLASData.L2_dSBMV_y_n2);
-
-        mBLAS.DSBMV(uplo, mBLASData.KL, alphaD, matrixAD, vectorXD, incX, betaD, vectorYD, incY);
-        vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimY, 1));
-        vectorYRef.copyFrom(mBLASData.L2_dSBMV_o_N2);
-        verifyMatrix(vectorYRef, vectorYD);
-
-        mRS.finish();
-        checkError();
-    }
-
-
-    private boolean validateSPMV(Element e, int Uplo, Allocation Ap, Allocation X, int incX, Allocation Y, int incY) {
-        if (!validateUplo(Uplo)) {
-            return false;
-        }
-        if (!Ap.getType().getElement().isCompatible(e) ||
-            !X.getType().getElement().isCompatible(e) ||
-            !Y.getType().getElement().isCompatible(e)) {
-            return false;
-        }
-        if (X.getType().getY() > 1 || Y.getType().getY() > 1) {
-            return false;
-        }
-
-        if (Ap.getType().getY() > 1) {
-            return false;
-        }
-
-        int N = (int)Math.sqrt((double)Ap.getType().getX() * 2);
-        if (Ap.getType().getX() != ((N * (N+1)) / 2)) {
-            return false;
-        }
-        if (incX <= 0 || incY <= 0) {
-            return false;
-        }
-        int expectedXDim = 1 + (N - 1) * incX;
-        if (X.getType().getX() != expectedXDim) {
-            return false;
-        }
-        int expectedYDim = 1 + (N - 1) * incY;
-        if (Y.getType().getX() != expectedYDim) {
-            return false;
-        }
-
-        return true;
-    }
-
-    private void xSPMV_API_test(int Uplo, int incX, int incY, ArrayList<Allocation> mMatrix) {
-        for (Allocation matA : mMatrix) {
-            for (Allocation vecX : mMatrix) {
-                if (!validateVecInput(vecX)) {
-                    continue;
-                }
-                for (Allocation vecY : mMatrix) {
-                    if (!validateVecInput(vecY)) {
-                        continue;
-                    }
-                    Element elemA = matA.getType().getElement();
-                    if (validateSPMV(elemA, Uplo, matA, vecX, incX, vecY, incY)) {
-                        try {
-                            if (elemA.isCompatible(Element.F32(mRS))) {
-                                mBLAS.SSPMV(Uplo, alphaS, matA, vecX, incX, betaS, vecY, incY);
-                            } else if (elemA.isCompatible(Element.F64(mRS))) {
-                                mBLAS.DSPMV(Uplo, alphaD, matA, vecX, incX, betaD, vecY, incY);
-                            }
-                        } catch (RSRuntimeException e) {
-                            fail("should NOT throw RSRuntimeException");
-                        }
-                    } else {
-                        try {
-                            mBLAS.SSPMV(Uplo, alphaS, matA, vecX, incX, betaS, vecY, incY);
-                            fail("should throw RSRuntimeException for SSPMV");
-                        } catch (RSRuntimeException e) {
-                        }
-                        try {
-                            mBLAS.DSPMV(Uplo, alphaD, matA, vecX, incX, betaD, vecY, incY);
-                            fail("should throw RSRuntimeException for DSPMV");
-                        } catch (RSRuntimeException e) {
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    public void L2_xSPMV_API(ArrayList<Allocation> mMatrix) {
-        for (int Uplo : mUplo) {
-            for (int incX : mInc) {
-                xSPMV_API_test(Uplo, incX, incX, mMatrix);
-            }
-        }
-    }
-
-    public void test_L2_SSPMV_API() {
-        L2_xSPMV_API(mMatrixS);
-    }
-
-    public void test_L2_DSPMV_API() {
-        L2_xSPMV_API(mMatrixD);
-    }
-
-    public void test_L2_SSPMV_Correctness() {
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-        int incX = 1;
-        int incY = 1;
-
-        // Populate input allocations
-        int N = mBLASData.dN;
-        Allocation matrixAS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), N * (N+1) / 2, 1));
-        Allocation vectorXS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), N, 1));
-        Allocation vectorYS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), N, 1));
-        matrixAS.copyFrom(mBLASData.L2_sSYMV_A_nn_pu);
-        vectorXS.copyFrom(mBLASData.L2_sSYMV_x_n1);
-        vectorYS.copyFrom(mBLASData.L2_sSYMV_y_n1);
-
-        // Test for the default case:
-        mBLAS.SSPMV(uplo, alphaS, matrixAS, vectorXS, incX, betaS, vectorYS, incY);
-        Allocation vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), N, 1));
-        vectorYRef.copyFrom(mBLASData.L2_sSYMV_o_N);
-        verifyMatrix(vectorYRef, vectorYS);
-
-        // Test for incX = 2 & incY = 3;
-        incX = 2;
-        incY = 3;
-        int dimX = 1 + (N - 1) * incX;
-        int dimY = 1 + (N - 1) * incY;
-        vectorXS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimX, 1));
-        vectorYS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimY, 1));
-        vectorXS.copyFrom(mBLASData.L2_sSYMV_x_n2);
-        vectorYS.copyFrom(mBLASData.L2_sSYMV_y_n2);
-
-        mBLAS.SSPMV(uplo, alphaS, matrixAS, vectorXS, incX, betaS, vectorYS, incY);
-        vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimY, 1));
-        vectorYRef.copyFrom(mBLASData.L2_sSYMV_o_N2);
-        verifyMatrix(vectorYRef, vectorYS);
-
-        mRS.finish();
-        checkError();
-    }
-
-    public void test_L2_DSPMV_Correctness() {
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-        int incX = 1;
-        int incY = 1;
-
-        // Populate input allocations
-        int N = mBLASData.dN;
-        Allocation matrixAD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), N * (N+1) / 2, 1));
-        Allocation vectorXD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), N, 1));
-        Allocation vectorYD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), N, 1));
-        matrixAD.copyFrom(mBLASData.L2_dSYMV_A_nn_pu);
-        vectorXD.copyFrom(mBLASData.L2_dSYMV_x_n1);
-        vectorYD.copyFrom(mBLASData.L2_dSYMV_y_n1);
-
-        // Test for the default case:
-        mBLAS.DSPMV(uplo, alphaD, matrixAD, vectorXD, incX, betaD, vectorYD, incY);
-        Allocation vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), N, 1));
-        vectorYRef.copyFrom(mBLASData.L2_dSYMV_o_N);
-        verifyMatrix(vectorYRef, vectorYD);
-
-        // Test for incX = 2 & incY = 3;
-        incX = 2;
-        incY = 3;
-        int dimX = 1 + (N - 1) * incX;
-        int dimY = 1 + (N - 1) * incY;
-        vectorXD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimX, 1));
-        vectorYD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimY, 1));
-        vectorXD.copyFrom(mBLASData.L2_dSYMV_x_n2);
-        vectorYD.copyFrom(mBLASData.L2_dSYMV_y_n2);
-
-        mBLAS.DSPMV(uplo, alphaD, matrixAD, vectorXD, incX, betaD, vectorYD, incY);
-        vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimY, 1));
-        vectorYRef.copyFrom(mBLASData.L2_dSYMV_o_N2);
-        verifyMatrix(vectorYRef, vectorYD);
-
-        mRS.finish();
-        checkError();
-    }
-
-
-
-    private boolean validateTRMV(Element e, int Uplo, int TransA, int Diag, Allocation A, Allocation X, int incX) {
-        if (!validateUplo(Uplo)) {
-            return false;
-        }
-        if (!validateTranspose(TransA)) {
-            return false;
-        }
-        if (!validateDiag(Diag)) {
-            return false;
-        }
-        int N = A.getType().getY();
-        if (A.getType().getX() != N) {
-            return false;
-        }
-        if (!A.getType().getElement().isCompatible(e) ||
-            !X.getType().getElement().isCompatible(e)) {
-            return false;
-        }
-        if (X.getType().getY() > 1) {
-            return false;
-        }
-
-        if (incX <= 0) {
-            return false;
-        }
-        int expectedXDim = 1 + (N - 1) * incX;
-        if (X.getType().getX() != expectedXDim) {
-            return false;
-        }
-        return true;
-    }
-
-    private void xTRMV_API_test(int Uplo, int TransA, int Diag, int incX, ArrayList<Allocation> mMatrix) {
-        for (Allocation matA : mMatrix) {
-            for (Allocation vecX : mMatrix) {
-                if (!validateVecInput(vecX)) {
-                    continue;
-                }
-                Element elemA = matA.getType().getElement();
-                if (validateTRMV(elemA, Uplo, TransA, Diag, matA, vecX, incX)) {
-                    try {
-                        if (elemA.isCompatible(Element.F32(mRS))) {
-                            mBLAS.STRMV(Uplo, TransA, Diag, matA, vecX, incX);
-                        } else if (elemA.isCompatible(Element.F64(mRS))) {
-                            mBLAS.DTRMV(Uplo, TransA, Diag, matA, vecX, incX);
-                        } else if (elemA.isCompatible(Element.F32_2(mRS))) {
-                            mBLAS.CTRMV(Uplo, TransA, Diag, matA, vecX, incX);
-                        } else if (elemA.isCompatible(Element.F64_2(mRS))) {
-                            mBLAS.ZTRMV(Uplo, TransA, Diag, matA, vecX, incX);
-                        }
-                    } catch (RSRuntimeException e) {
-                        fail("should NOT throw RSRuntimeException");
-                    }
-                } else {
-                    try {
-                        mBLAS.STRMV(Uplo, TransA, Diag, matA, vecX, incX);
-                        fail("should throw RSRuntimeException for STRMV");
-                    } catch (RSRuntimeException e) {
-                    }
-                    try {
-                        mBLAS.DTRMV(Uplo, TransA, Diag, matA, vecX, incX);
-                        fail("should throw RSRuntimeException for DTRMV");
-                    } catch (RSRuntimeException e) {
-                    }
-                    try {
-                        mBLAS.CTRMV(Uplo, TransA, Diag, matA, vecX, incX);
-                        fail("should throw RSRuntimeException for CTRMV");
-                    } catch (RSRuntimeException e) {
-                    }
-                    try {
-                        mBLAS.ZTRMV(Uplo, TransA, Diag, matA, vecX, incX);
-                        fail("should throw RSRuntimeException for ZTRMV");
-                    } catch (RSRuntimeException e) {
-                    }
-                }
-            }
-        }
-    }
-
-    public void L2_xTRMV_API(ArrayList<Allocation> mMatrix) {
-        for (int Uplo : mUplo) {
-            for (int TransA : mTranspose) {
-                for (int Diag : mDiag) {
-                    for (int incX : mInc) {
-                        xTRMV_API_test(Uplo, TransA, Diag, incX, mMatrix);
-                    }
-                }
-            }
-        }
-    }
-
-    public void test_L2_STRMV_API() {
-        L2_xTRMV_API(mMatrixS);
-    }
-
-    public void test_L2_DTRMV_API() {
-        L2_xTRMV_API(mMatrixD);
-    }
-
-    public void test_L2_CTRMV_API() {
-        L2_xTRMV_API(mMatrixC);
-    }
-
-    public void test_L2_ZTRMV_API() {
-        L2_xTRMV_API(mMatrixZ);
-    }
-
-    public void test_L2_STRMV_Correctness() {
-        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-        int diag = ScriptIntrinsicBLAS.NON_UNIT;
-        int incX = 1;
-
-        // Populate input allocations
-        Allocation matrixAS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dN));
-        Allocation vectorXS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, 1));
-        matrixAS.copyFrom(mBLASData.L2_sTRMV_A_nn);
-        vectorXS.copyFrom(mBLASData.L2_sTRMV_x_n1);
-
-        // Test for the default case: NO_TRANS
-        mBLAS.STRMV(uplo, trans, diag, matrixAS, vectorXS, incX);
-        Allocation vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, 1));
-        vectorXRef.copyFrom(mBLASData.L2_sTRMV_o_UN);
-        verifyMatrix(vectorXRef, vectorXS);
-
-        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
-        trans = ScriptIntrinsicBLAS.TRANSPOSE;
-        // Reload vector X, since it was overwritten by BLAS.
-        vectorXS.copyFrom(mBLASData.L2_sTRMV_x_n1);
-        mBLAS.STRMV(uplo, trans, diag, matrixAS, vectorXS, incX);
-        vectorXRef.copyFrom(mBLASData.L2_sTRMV_o_UT);
-        verifyMatrix(vectorXRef, vectorXS);
-
-        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
-        vectorXS.copyFrom(mBLASData.L2_sTRMV_x_n1);
-        mBLAS.STRMV(uplo, trans, diag, matrixAS, vectorXS, incX);
-        vectorXRef.copyFrom(mBLASData.L2_sTRMV_o_UH);
-        verifyMatrix(vectorXRef, vectorXS);
-
-        // Test for incX = 2;
-        trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        incX = 2;
-        int dimX = 1 + (mBLASData.dN - 1) * incX;
-        vectorXS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimX, 1));
-        vectorXS.copyFrom(mBLASData.L2_sTRMV_x_n2);
-
-        mBLAS.STRMV(uplo, trans, diag, matrixAS, vectorXS, incX);
-        vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimX, 1));
-        vectorXRef.copyFrom(mBLASData.L2_sTRMV_o_UN2);
-        verifyMatrix(vectorXRef, vectorXS);
-
-        mRS.finish();
-        checkError();
-    }
-
-    public void test_L2_DTRMV_Correctness() {
-        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-        int diag = ScriptIntrinsicBLAS.NON_UNIT;
-        int incX = 1;
-
-        // Populate input allocations
-        Allocation matrixAD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dN));
-        Allocation vectorXD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, 1));
-        matrixAD.copyFrom(mBLASData.L2_dTRMV_A_nn);
-        vectorXD.copyFrom(mBLASData.L2_dTRMV_x_n1);
-
-        // Test for the default case: NO_TRANS
-        mBLAS.DTRMV(uplo, trans, diag, matrixAD, vectorXD, incX);
-        Allocation vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, 1));
-        vectorXRef.copyFrom(mBLASData.L2_dTRMV_o_UN);
-        verifyMatrix(vectorXRef, vectorXD);
-
-        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
-        trans = ScriptIntrinsicBLAS.TRANSPOSE;
-        // Reload vector X, since it was overwritten by BLAS.
-        vectorXD.copyFrom(mBLASData.L2_dTRMV_x_n1);
-        mBLAS.DTRMV(uplo, trans, diag, matrixAD, vectorXD, incX);
-        vectorXRef.copyFrom(mBLASData.L2_dTRMV_o_UT);
-        verifyMatrix(vectorXRef, vectorXD);
-
-        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
-        vectorXD.copyFrom(mBLASData.L2_dTRMV_x_n1);
-        mBLAS.DTRMV(uplo, trans, diag, matrixAD, vectorXD, incX);
-        vectorXRef.copyFrom(mBLASData.L2_dTRMV_o_UH);
-        verifyMatrix(vectorXRef, vectorXD);
-
-        // Test for incX = 2;
-        trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        incX = 2;
-        int dimX = 1 + (mBLASData.dN - 1) * incX;
-        vectorXD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimX, 1));
-        vectorXD.copyFrom(mBLASData.L2_dTRMV_x_n2);
-
-        mBLAS.DTRMV(uplo, trans, diag, matrixAD, vectorXD, incX);
-        vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimX, 1));
-        vectorXRef.copyFrom(mBLASData.L2_dTRMV_o_UN2);
-        verifyMatrix(vectorXRef, vectorXD);
-
-        mRS.finish();
-        checkError();
-    }
-
-    public void test_L2_CTRMV_Correctness() {
-        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-        int diag = ScriptIntrinsicBLAS.NON_UNIT;
-        int incX = 1;
-
-        // Populate input allocations
-        Allocation matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dN));
-        Allocation vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, 1));
-        matrixAC.copyFrom(mBLASData.L2_cTRMV_A_nn);
-        vectorXC.copyFrom(mBLASData.L2_cTRMV_x_n1);
-
-        // Test for the default case: NO_TRANS
-        mBLAS.CTRMV(uplo, trans, diag, matrixAC, vectorXC, incX);
-        Allocation vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, 1));
-        vectorXRef.copyFrom(mBLASData.L2_cTRMV_o_UN);
-        verifyMatrix(vectorXRef, vectorXC);
-
-        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
-        trans = ScriptIntrinsicBLAS.TRANSPOSE;
-        // Reload vector X, since it was overwritten by BLAS.
-        vectorXC.copyFrom(mBLASData.L2_cTRMV_x_n1);
-        mBLAS.CTRMV(uplo, trans, diag, matrixAC, vectorXC, incX);
-        vectorXRef.copyFrom(mBLASData.L2_cTRMV_o_UT);
-        verifyMatrix(vectorXRef, vectorXC);
-
-        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
-        vectorXC.copyFrom(mBLASData.L2_cTRMV_x_n1);
-        mBLAS.CTRMV(uplo, trans, diag, matrixAC, vectorXC, incX);
-        vectorXRef.copyFrom(mBLASData.L2_cTRMV_o_UH);
-        verifyMatrix(vectorXRef, vectorXC);
-
-        // Test for incX = 2;
-        trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        incX = 2;
-        int dimX = 1 + (mBLASData.dN - 1) * incX;
-        vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimX, 1));
-        vectorXC.copyFrom(mBLASData.L2_cTRMV_x_n2);
-
-        mBLAS.CTRMV(uplo, trans, diag, matrixAC, vectorXC, incX);
-        vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimX, 1));
-        vectorXRef.copyFrom(mBLASData.L2_cTRMV_o_UN2);
-        verifyMatrix(vectorXRef, vectorXC);
-
-        mRS.finish();
-        checkError();
-    }
-
-    public void test_L2_ZTRMV_Correctness() {
-        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-        int diag = ScriptIntrinsicBLAS.NON_UNIT;
-        int incX = 1;
-
-        // Populate input allocations
-        Allocation matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dN));
-        Allocation vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, 1));
-        matrixAZ.copyFrom(mBLASData.L2_zTRMV_A_nn);
-        vectorXZ.copyFrom(mBLASData.L2_zTRMV_x_n1);
-
-        // Test for the default case: NO_TRANS
-        mBLAS.ZTRMV(uplo, trans, diag, matrixAZ, vectorXZ, incX);
-        Allocation vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, 1));
-        vectorXRef.copyFrom(mBLASData.L2_zTRMV_o_UN);
-        verifyMatrix(vectorXRef, vectorXZ);
-
-        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
-        trans = ScriptIntrinsicBLAS.TRANSPOSE;
-        // Reload vector X, since it was overwritten by BLAS.
-        vectorXZ.copyFrom(mBLASData.L2_zTRMV_x_n1);
-        mBLAS.ZTRMV(uplo, trans, diag, matrixAZ, vectorXZ, incX);
-        vectorXRef.copyFrom(mBLASData.L2_zTRMV_o_UT);
-        verifyMatrix(vectorXRef, vectorXZ);
-
-        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
-        vectorXZ.copyFrom(mBLASData.L2_zTRMV_x_n1);
-        mBLAS.ZTRMV(uplo, trans, diag, matrixAZ, vectorXZ, incX);
-        vectorXRef.copyFrom(mBLASData.L2_zTRMV_o_UH);
-        verifyMatrix(vectorXRef, vectorXZ);
-
-        // Test for incX = 2;
-        trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        incX = 2;
-        int dimX = 1 + (mBLASData.dN - 1) * incX;
-        vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimX, 1));
-        vectorXZ.copyFrom(mBLASData.L2_zTRMV_x_n2);
-
-        mBLAS.ZTRMV(uplo, trans, diag, matrixAZ, vectorXZ, incX);
-        vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimX, 1));
-        vectorXRef.copyFrom(mBLASData.L2_zTRMV_o_UN2);
-        verifyMatrix(vectorXRef, vectorXZ);
-
-        mRS.finish();
-        checkError();
-    }
-
-
-
-    private void xTBMV_API_test(int Uplo, int TransA, int Diag, int K, int incX, ArrayList<Allocation> mMatrix) {
-        for (Allocation matA : mMatrix) {
-            for (Allocation vecX : mMatrix) {
-                Element elemA = matA.getType().getElement();
-                if (validateTRMV(elemA, Uplo, TransA, Diag, matA, vecX, incX) && K >= 0) {
-                    try {
-                        if (elemA.isCompatible(Element.F32(mRS))) {
-                            mBLAS.STBMV(Uplo, TransA, Diag, K, matA, vecX, incX);
-                        } else if (elemA.isCompatible(Element.F64(mRS))) {
-                            mBLAS.DTBMV(Uplo, TransA, Diag, K, matA, vecX, incX);
-                        } else if (elemA.isCompatible(Element.F32_2(mRS))) {
-                            mBLAS.CTBMV(Uplo, TransA, Diag, K, matA, vecX, incX);
-                        } else if (elemA.isCompatible(Element.F64_2(mRS))) {
-                            mBLAS.ZTBMV(Uplo, TransA, Diag, K, matA, vecX, incX);
-                        }
-                    } catch (RSRuntimeException e) {
-                        fail("should NOT throw RSRuntimeException");
-                    }
-                } else {
-                    try {
-                        mBLAS.STBMV(Uplo, TransA, Diag, K, matA, vecX, incX);
-                        fail("should throw RSRuntimeException for STBMV");
-                    } catch (RSRuntimeException e) {
-                    }
-                    try {
-                        mBLAS.DTBMV(Uplo, TransA, Diag, K, matA, vecX, incX);
-                        fail("should throw RSRuntimeException for DTBMV");
-                    } catch (RSRuntimeException e) {
-                    }
-                    try {
-                        mBLAS.CTBMV(Uplo, TransA, Diag, K, matA, vecX, incX);
-                        fail("should throw RSRuntimeException for CTBMV");
-                    } catch (RSRuntimeException e) {
-                    }
-                    try {
-                        mBLAS.ZTBMV(Uplo, TransA, Diag, K, matA, vecX, incX);
-                        fail("should throw RSRuntimeException for ZTBMV");
-                    } catch (RSRuntimeException e) {
-                    }
-                }
-            }
-        }
-    }
-
-    public void L2_xTBMV_API(ArrayList<Allocation> mMatrix) {
-        for (int Uplo : mUplo) {
-            for (int TransA : mTranspose) {
-                for (int Diag : mDiag) {
-                    for (int K : mK) {
-                        for (int incX : mInc) {
-                            xTBMV_API_test(Uplo, TransA, Diag, K, incX, mMatrix);
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    public void test_L2_STBMV_API() {
-        L2_xTBMV_API(mMatrixS);
-    }
-
-    public void test_L2_DTBMV_API() {
-        L2_xTBMV_API(mMatrixD);
-    }
-
-    public void test_L2_CTBMV_API() {
-        L2_xTBMV_API(mMatrixC);
-    }
-
-    public void test_L2_ZTBMV_API() {
-        L2_xTBMV_API(mMatrixZ);
-    }
-
-    public void test_L2_STBMV_Correctness() {
-        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-        int diag = ScriptIntrinsicBLAS.NON_UNIT;
-        int incX = 1;
-
-        // Populate input allocations
-        Allocation matrixAS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dN));
-        Allocation vectorXS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, 1));
-        matrixAS.copy2DRangeFrom(0, 0, mBLASData.KL + 1, mBLASData.dN, mBLASData.L2_sTBMV_A_nn);
-        vectorXS.copyFrom(mBLASData.L2_sTBMV_x_n1);
-
-        // Test for the default case: NO_TRANS
-        mBLAS.STBMV(uplo, trans, diag, mBLASData.KL, matrixAS, vectorXS, incX);
-        Allocation vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, 1));
-        vectorXRef.copyFrom(mBLASData.L2_sTBMV_o_UN);
-        verifyMatrix(vectorXRef, vectorXS);
-
-        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
-        trans = ScriptIntrinsicBLAS.TRANSPOSE;
-        // Reload vector X, since it was overwritten by BLAS.
-        vectorXS.copyFrom(mBLASData.L2_sTBMV_x_n1);
-        mBLAS.STBMV(uplo, trans, diag, mBLASData.KL, matrixAS, vectorXS, incX);
-        vectorXRef.copyFrom(mBLASData.L2_sTBMV_o_UT);
-        verifyMatrix(vectorXRef, vectorXS);
-
-        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
-        vectorXS.copyFrom(mBLASData.L2_sTBMV_x_n1);
-        mBLAS.STBMV(uplo, trans, diag, mBLASData.KL, matrixAS, vectorXS, incX);
-        vectorXRef.copyFrom(mBLASData.L2_sTBMV_o_UH);
-        verifyMatrix(vectorXRef, vectorXS);
-
-        // Test for incX = 2;
-        trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        incX = 2;
-        int dimX = 1 + (mBLASData.dN - 1) * incX;
-        vectorXS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimX, 1));
-        vectorXS.copyFrom(mBLASData.L2_sTBMV_x_n2);
-
-        mBLAS.STBMV(uplo, trans, diag, mBLASData.KL, matrixAS, vectorXS, incX);
-        vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimX, 1));
-        vectorXRef.copyFrom(mBLASData.L2_sTBMV_o_UN2);
-        verifyMatrix(vectorXRef, vectorXS);
-
-        mRS.finish();
-        checkError();
-    }
-
-    public void test_L2_DTBMV_Correctness() {
-        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-        int diag = ScriptIntrinsicBLAS.NON_UNIT;
-        int incX = 1;
-
-        // Populate input allocations
-        Allocation matrixAD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dN));
-        Allocation vectorXD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, 1));
-        matrixAD.copy2DRangeFrom(0, 0, mBLASData.KL + 1, mBLASData.dN, mBLASData.L2_dTBMV_A_nn);
-        vectorXD.copyFrom(mBLASData.L2_dTBMV_x_n1);
-
-        // Test for the default case: NO_TRANS
-        mBLAS.DTBMV(uplo, trans, diag, mBLASData.KL, matrixAD, vectorXD, incX);
-        Allocation vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, 1));
-        vectorXRef.copyFrom(mBLASData.L2_dTBMV_o_UN);
-        verifyMatrix(vectorXRef, vectorXD);
-
-        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
-        trans = ScriptIntrinsicBLAS.TRANSPOSE;
-        // Reload vector X, since it was overwritten by BLAS.
-        vectorXD.copyFrom(mBLASData.L2_dTBMV_x_n1);
-        mBLAS.DTBMV(uplo, trans, diag, mBLASData.KL, matrixAD, vectorXD, incX);
-        vectorXRef.copyFrom(mBLASData.L2_dTBMV_o_UT);
-        verifyMatrix(vectorXRef, vectorXD);
-
-        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
-        vectorXD.copyFrom(mBLASData.L2_dTBMV_x_n1);
-        mBLAS.DTBMV(uplo, trans, diag, mBLASData.KL, matrixAD, vectorXD, incX);
-        vectorXRef.copyFrom(mBLASData.L2_dTBMV_o_UH);
-        verifyMatrix(vectorXRef, vectorXD);
-
-        // Test for incX = 2;
-        trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        incX = 2;
-        int dimX = 1 + (mBLASData.dN - 1) * incX;
-        vectorXD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimX, 1));
-        vectorXD.copyFrom(mBLASData.L2_dTBMV_x_n2);
-
-        mBLAS.DTBMV(uplo, trans, diag, mBLASData.KL, matrixAD, vectorXD, incX);
-        vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimX, 1));
-        vectorXRef.copyFrom(mBLASData.L2_dTBMV_o_UN2);
-        verifyMatrix(vectorXRef, vectorXD);
-
-        mRS.finish();
-        checkError();
-    }
-
-    public void test_L2_CTBMV_Correctness() {
-        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-        int diag = ScriptIntrinsicBLAS.NON_UNIT;
-        int incX = 1;
-
-        // Populate input allocations
-        Allocation matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dN));
-        Allocation vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, 1));
-        matrixAC.copy2DRangeFrom(0, 0, mBLASData.KL + 1, mBLASData.dN, mBLASData.L2_cTBMV_A_nn);
-        vectorXC.copyFrom(mBLASData.L2_cTBMV_x_n1);
-
-        // Test for the default case: NO_TRANS
-        mBLAS.CTBMV(uplo, trans, diag, mBLASData.KL, matrixAC, vectorXC, incX);
-        Allocation vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, 1));
-        vectorXRef.copyFrom(mBLASData.L2_cTBMV_o_UN);
-        verifyMatrix(vectorXRef, vectorXC);
-
-        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
-        trans = ScriptIntrinsicBLAS.TRANSPOSE;
-        // Reload vector X, since it was overwritten by BLAS.
-        vectorXC.copyFrom(mBLASData.L2_cTBMV_x_n1);
-        mBLAS.CTBMV(uplo, trans, diag, mBLASData.KL, matrixAC, vectorXC, incX);
-        vectorXRef.copyFrom(mBLASData.L2_cTBMV_o_UT);
-        verifyMatrix(vectorXRef, vectorXC);
-
-        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
-        vectorXC.copyFrom(mBLASData.L2_cTBMV_x_n1);
-        mBLAS.CTBMV(uplo, trans, diag, mBLASData.KL, matrixAC, vectorXC, incX);
-        vectorXRef.copyFrom(mBLASData.L2_cTBMV_o_UH);
-        verifyMatrix(vectorXRef, vectorXC);
-
-        // Test for incX = 2;
-        trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        incX = 2;
-        int dimX = 1 + (mBLASData.dN - 1) * incX;
-        vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimX, 1));
-        vectorXC.copyFrom(mBLASData.L2_cTBMV_x_n2);
-
-        mBLAS.CTBMV(uplo, trans, diag, mBLASData.KL, matrixAC, vectorXC, incX);
-        vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimX, 1));
-        vectorXRef.copyFrom(mBLASData.L2_cTBMV_o_UN2);
-        verifyMatrix(vectorXRef, vectorXC);
-
-        mRS.finish();
-        checkError();
-    }
-
-    public void test_L2_ZTBMV_Correctness() {
-        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-        int diag = ScriptIntrinsicBLAS.NON_UNIT;
-        int incX = 1;
-
-        // Populate input allocations
-        Allocation matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dN));
-        Allocation vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, 1));
-        matrixAZ.copy2DRangeFrom(0, 0, mBLASData.KL + 1, mBLASData.dN, mBLASData.L2_zTBMV_A_nn);
-        vectorXZ.copyFrom(mBLASData.L2_zTBMV_x_n1);
-
-        // Test for the default case: NO_TRANS
-        mBLAS.ZTBMV(uplo, trans, diag, mBLASData.KL, matrixAZ, vectorXZ, incX);
-        Allocation vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, 1));
-        vectorXRef.copyFrom(mBLASData.L2_zTBMV_o_UN);
-        verifyMatrix(vectorXRef, vectorXZ);
-
-        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
-        trans = ScriptIntrinsicBLAS.TRANSPOSE;
-        // Reload vector X, since it was overwritten by BLAS.
-        vectorXZ.copyFrom(mBLASData.L2_zTBMV_x_n1);
-        mBLAS.ZTBMV(uplo, trans, diag, mBLASData.KL, matrixAZ, vectorXZ, incX);
-        vectorXRef.copyFrom(mBLASData.L2_zTBMV_o_UT);
-        verifyMatrix(vectorXRef, vectorXZ);
-
-        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
-        vectorXZ.copyFrom(mBLASData.L2_zTBMV_x_n1);
-        mBLAS.ZTBMV(uplo, trans, diag, mBLASData.KL, matrixAZ, vectorXZ, incX);
-        vectorXRef.copyFrom(mBLASData.L2_zTBMV_o_UH);
-        verifyMatrix(vectorXRef, vectorXZ);
-
-        // Test for incX = 2;
-        trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        incX = 2;
-        int dimX = 1 + (mBLASData.dN - 1) * incX;
-        vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimX, 1));
-        vectorXZ.copyFrom(mBLASData.L2_zTBMV_x_n2);
-
-        mBLAS.ZTBMV(uplo, trans, diag, mBLASData.KL, matrixAZ, vectorXZ, incX);
-        vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimX, 1));
-        vectorXRef.copyFrom(mBLASData.L2_zTBMV_o_UN2);
-        verifyMatrix(vectorXRef, vectorXZ);
-
-        mRS.finish();
-        checkError();
-    }
-
-
-    private boolean validateTPMV(Element e, int Uplo, int TransA, int Diag, Allocation Ap, Allocation X, int incX) {
-        if (!validateUplo(Uplo)) {
-            return false;
-        }
-        if (!validateTranspose(TransA)) {
-            return false;
-        }
-        if (!validateDiag(Diag)) {
-            return false;
-        }
-        if (!Ap.getType().getElement().isCompatible(e) ||
-            !X.getType().getElement().isCompatible(e)) {
-            return false;
-        }
-        if (X.getType().getY() > 1) {
-            return false;
-        }
-
-        if (Ap.getType().getY() > 1) {
-            return false;
-        }
-
-        int N = (int)Math.sqrt((double)Ap.getType().getX() * 2);
-        if (Ap.getType().getX() != ((N * (N+1)) / 2)) {
-            return false;
-        }
-        if (incX <= 0) {
-            return false;
-        }
-        int expectedXDim = 1 + (N - 1) * incX;
-        if (X.getType().getX() != expectedXDim) {
-            return false;
-        }
-
-        return true;
-    }
-
-    private void xTPMV_API_test(int Uplo, int TransA, int Diag, int incX, ArrayList<Allocation> mMatrix) {
-        for (Allocation matA : mMatrix) {
-            for (Allocation vecX : mMatrix) {
-                if (!validateVecInput(vecX)) {
-                    continue;
-                }
-                Element elemA = matA.getType().getElement();
-                if (validateTPMV(elemA, Uplo, TransA, Diag, matA, vecX, incX)) {
-                    try {
-                        if (elemA.isCompatible(Element.F32(mRS))) {
-                            mBLAS.STPMV(Uplo, TransA, Diag, matA, vecX, incX);
-                        } else if (elemA.isCompatible(Element.F64(mRS))) {
-                            mBLAS.DTPMV(Uplo, TransA, Diag, matA, vecX, incX);
-                        } else if (elemA.isCompatible(Element.F32_2(mRS))) {
-                            mBLAS.CTPMV(Uplo, TransA, Diag, matA, vecX, incX);
-                        } else if (elemA.isCompatible(Element.F64_2(mRS))) {
-                            mBLAS.ZTPMV(Uplo, TransA, Diag, matA, vecX, incX);
-                        }
-                    } catch (RSRuntimeException e) {
-                        fail("should NOT throw RSRuntimeException");
-                    }
-                } else {
-                    try {
-                        mBLAS.STPMV(Uplo, TransA, Diag, matA, vecX, incX);
-                        fail("should throw RSRuntimeException for STPMV");
-                    } catch (RSRuntimeException e) {
-                    }
-                    try {
-                        mBLAS.DTPMV(Uplo, TransA, Diag, matA, vecX, incX);
-                        fail("should throw RSRuntimeException for DTPMV");
-                    } catch (RSRuntimeException e) {
-                    }
-                    try {
-                        mBLAS.CTPMV(Uplo, TransA, Diag, matA, vecX, incX);
-                        fail("should throw RSRuntimeException for CTPMV");
-                    } catch (RSRuntimeException e) {
-                    }
-                    try {
-                        mBLAS.ZTPMV(Uplo, TransA, Diag, matA, vecX, incX);
-                        fail("should throw RSRuntimeException for ZTPMV");
-                    } catch (RSRuntimeException e) {
-                    }
-                }
-            }
-        }
-    }
-
-    public void L2_xTPMV_API(ArrayList<Allocation> mMatrix) {
-        for (int Uplo : mUplo) {
-            for (int TransA : mTranspose) {
-                for (int Diag : mDiag) {
-                    for (int incX : mInc) {
-                        xTPMV_API_test(Uplo, TransA, Diag, incX, mMatrix);
-                    }
-                }
-            }
-        }
-    }
-
-    public void test_L2_STPMV_API() {
-        L2_xTPMV_API(mMatrixS);
-    }
-
-    public void test_L2_DTPMV_API() {
-        L2_xTPMV_API(mMatrixD);
-    }
-
-    public void test_L2_CTPMV_API() {
-        L2_xTPMV_API(mMatrixC);
-    }
-
-    public void test_L2_ZTPMV_API() {
-        L2_xTPMV_API(mMatrixZ);
-    }
-
-    public void test_L2_STPMV_Correctness() {
-        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-        int diag = ScriptIntrinsicBLAS.NON_UNIT;
-        int incX = 1;
-
-        // Populate input allocations
-        int N = mBLASData.dN;
-        Allocation matrixAS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), N * (N+1) / 2, 1));
-        Allocation vectorXS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), N, 1));
-        matrixAS.copyFrom(mBLASData.L2_sTRMV_A_nn_pu);
-        vectorXS.copyFrom(mBLASData.L2_sTRMV_x_n1);
-
-        // Test for the default case: NO_TRANS
-        mBLAS.STPMV(uplo, trans, diag, matrixAS, vectorXS, incX);
-        Allocation vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), N, 1));
-        vectorXRef.copyFrom(mBLASData.L2_sTRMV_o_UN);
-        verifyMatrix(vectorXRef, vectorXS);
-
-        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
-        trans = ScriptIntrinsicBLAS.TRANSPOSE;
-        // Reload vector X, since it was overwritten by BLAS.
-        vectorXS.copyFrom(mBLASData.L2_sTRMV_x_n1);
-        mBLAS.STPMV(uplo, trans, diag, matrixAS, vectorXS, incX);
-        vectorXRef.copyFrom(mBLASData.L2_sTRMV_o_UT);
-        verifyMatrix(vectorXRef, vectorXS);
-
-        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
-        vectorXS.copyFrom(mBLASData.L2_sTRMV_x_n1);
-        mBLAS.STPMV(uplo, trans, diag, matrixAS, vectorXS, incX);
-        vectorXRef.copyFrom(mBLASData.L2_sTRMV_o_UH);
-        verifyMatrix(vectorXRef, vectorXS);
-
-        // Test for incX = 2;
-        trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        incX = 2;
-        int dimX = 1 + (N - 1) * incX;
-        vectorXS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimX, 1));
-        vectorXS.copyFrom(mBLASData.L2_sTRMV_x_n2);
-
-        mBLAS.STPMV(uplo, trans, diag, matrixAS, vectorXS, incX);
-        vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimX, 1));
-        vectorXRef.copyFrom(mBLASData.L2_sTRMV_o_UN2);
-        verifyMatrix(vectorXRef, vectorXS);
-
-        mRS.finish();
-        checkError();
-    }
-
-    public void test_L2_DTPMV_Correctness() {
-        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-        int diag = ScriptIntrinsicBLAS.NON_UNIT;
-        int incX = 1;
-
-        // Populate input allocations
-        int N = mBLASData.dN;
-        Allocation matrixAD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), N * (N+1) / 2, 1));
-        Allocation vectorXD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), N, 1));
-        matrixAD.copyFrom(mBLASData.L2_dTRMV_A_nn_pu);
-        vectorXD.copyFrom(mBLASData.L2_dTRMV_x_n1);
-
-        // Test for the default case: NO_TRANS
-        mBLAS.DTPMV(uplo, trans, diag, matrixAD, vectorXD, incX);
-        Allocation vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), N, 1));
-        vectorXRef.copyFrom(mBLASData.L2_dTRMV_o_UN);
-        verifyMatrix(vectorXRef, vectorXD);
-
-        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
-        trans = ScriptIntrinsicBLAS.TRANSPOSE;
-        // Reload vector X, since it was overwritten by BLAS.
-        vectorXD.copyFrom(mBLASData.L2_dTRMV_x_n1);
-        mBLAS.DTPMV(uplo, trans, diag, matrixAD, vectorXD, incX);
-        vectorXRef.copyFrom(mBLASData.L2_dTRMV_o_UT);
-        verifyMatrix(vectorXRef, vectorXD);
-
-        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
-        vectorXD.copyFrom(mBLASData.L2_dTRMV_x_n1);
-        mBLAS.DTPMV(uplo, trans, diag, matrixAD, vectorXD, incX);
-        vectorXRef.copyFrom(mBLASData.L2_dTRMV_o_UH);
-        verifyMatrix(vectorXRef, vectorXD);
-
-        // Test for incX = 2;
-        trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        incX = 2;
-        int dimX = 1 + (N - 1) * incX;
-        vectorXD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimX, 1));
-        vectorXD.copyFrom(mBLASData.L2_dTRMV_x_n2);
-
-        mBLAS.DTPMV(uplo, trans, diag, matrixAD, vectorXD, incX);
-        vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimX, 1));
-        vectorXRef.copyFrom(mBLASData.L2_dTRMV_o_UN2);
-        verifyMatrix(vectorXRef, vectorXD);
-
-        mRS.finish();
-        checkError();
-    }
-
-    public void test_L2_CTPMV_Correctness() {
-        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-        int diag = ScriptIntrinsicBLAS.NON_UNIT;
-        int incX = 1;
-
-        // Populate input allocations
-        int N = mBLASData.dN;
-        Allocation matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), N * (N+1) / 2, 1));
-        Allocation vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), N, 1));
-        matrixAC.copyFrom(mBLASData.L2_cTRMV_A_nn_pu);
-        vectorXC.copyFrom(mBLASData.L2_cTRMV_x_n1);
-
-        // Test for the default case: NO_TRANS
-        mBLAS.CTPMV(uplo, trans, diag, matrixAC, vectorXC, incX);
-        Allocation vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), N, 1));
-        vectorXRef.copyFrom(mBLASData.L2_cTRMV_o_UN);
-        verifyMatrix(vectorXRef, vectorXC);
-
-        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
-        trans = ScriptIntrinsicBLAS.TRANSPOSE;
-        // Reload vector X, since it was overwritten by BLAS.
-        vectorXC.copyFrom(mBLASData.L2_cTRMV_x_n1);
-        mBLAS.CTPMV(uplo, trans, diag, matrixAC, vectorXC, incX);
-        vectorXRef.copyFrom(mBLASData.L2_cTRMV_o_UT);
-        verifyMatrix(vectorXRef, vectorXC);
-
-        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
-        vectorXC.copyFrom(mBLASData.L2_cTRMV_x_n1);
-        mBLAS.CTPMV(uplo, trans, diag, matrixAC, vectorXC, incX);
-        vectorXRef.copyFrom(mBLASData.L2_cTRMV_o_UH);
-        verifyMatrix(vectorXRef, vectorXC);
-
-        // Test for incX = 2;
-        trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        incX = 2;
-        int dimX = 1 + (N - 1) * incX;
-        vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimX, 1));
-        vectorXC.copyFrom(mBLASData.L2_cTRMV_x_n2);
-
-        mBLAS.CTPMV(uplo, trans, diag, matrixAC, vectorXC, incX);
-        vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimX, 1));
-        vectorXRef.copyFrom(mBLASData.L2_cTRMV_o_UN2);
-        verifyMatrix(vectorXRef, vectorXC);
-
-        mRS.finish();
-        checkError();
-    }
-
-    public void test_L2_ZTPMV_Correctness() {
-        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-        int diag = ScriptIntrinsicBLAS.NON_UNIT;
-        int incX = 1;
-
-        // Populate input allocations
-        int N = mBLASData.dN;
-        Allocation matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), N * (N+1) / 2, 1));
-        Allocation vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), N, 1));
-        matrixAZ.copyFrom(mBLASData.L2_zTRMV_A_nn_pu);
-        vectorXZ.copyFrom(mBLASData.L2_zTRMV_x_n1);
-
-        // Test for the default case: NO_TRANS
-        mBLAS.ZTPMV(uplo, trans, diag, matrixAZ, vectorXZ, incX);
-        Allocation vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), N, 1));
-        vectorXRef.copyFrom(mBLASData.L2_zTRMV_o_UN);
-        verifyMatrix(vectorXRef, vectorXZ);
-
-        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
-        trans = ScriptIntrinsicBLAS.TRANSPOSE;
-        // Reload vector X, since it was overwritten by BLAS.
-        vectorXZ.copyFrom(mBLASData.L2_zTRMV_x_n1);
-        mBLAS.ZTPMV(uplo, trans, diag, matrixAZ, vectorXZ, incX);
-        vectorXRef.copyFrom(mBLASData.L2_zTRMV_o_UT);
-        verifyMatrix(vectorXRef, vectorXZ);
-
-        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
-        vectorXZ.copyFrom(mBLASData.L2_zTRMV_x_n1);
-        mBLAS.ZTPMV(uplo, trans, diag, matrixAZ, vectorXZ, incX);
-        vectorXRef.copyFrom(mBLASData.L2_zTRMV_o_UH);
-        verifyMatrix(vectorXRef, vectorXZ);
-
-        // Test for incX = 2;
-        trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        incX = 2;
-        int dimX = 1 + (N - 1) * incX;
-        vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimX, 1));
-        vectorXZ.copyFrom(mBLASData.L2_zTRMV_x_n2);
-
-        mBLAS.ZTPMV(uplo, trans, diag, matrixAZ, vectorXZ, incX);
-        vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimX, 1));
-        vectorXRef.copyFrom(mBLASData.L2_zTRMV_o_UN2);
-        verifyMatrix(vectorXRef, vectorXZ);
-
-        mRS.finish();
-        checkError();
-    }
-
-
-    private void xTRSV_API_test(int Uplo, int TransA, int Diag, int incX, ArrayList<Allocation> mMatrix) {
-        for (Allocation matA : mMatrix) {
-            for (Allocation vecX : mMatrix) {
-                if (!validateVecInput(vecX)) {
-                    continue;
-                }
-                Element elemA = matA.getType().getElement();
-                if (validateTRMV(elemA, Uplo, TransA, Diag, matA, vecX, incX)) {
-                    try {
-                        if (elemA.isCompatible(Element.F32(mRS))) {
-                            mBLAS.STRSV(Uplo, TransA, Diag, matA, vecX, incX);
-                        } else if (elemA.isCompatible(Element.F64(mRS))) {
-                            mBLAS.DTRSV(Uplo, TransA, Diag, matA, vecX, incX);
-                        } else if (elemA.isCompatible(Element.F32_2(mRS))) {
-                            mBLAS.CTRSV(Uplo, TransA, Diag, matA, vecX, incX);
-                        } else if (elemA.isCompatible(Element.F64_2(mRS))) {
-                            mBLAS.ZTRSV(Uplo, TransA, Diag, matA, vecX, incX);
-                        }
-                    } catch (RSRuntimeException e) {
-                        fail("should NOT throw RSRuntimeException");
-                    }
-                } else {
-                    try {
-                        mBLAS.STRSV(Uplo, TransA, Diag, matA, vecX, incX);
-                        fail("should throw RSRuntimeException for STRSV");
-                    } catch (RSRuntimeException e) {
-                    }
-                    try {
-                        mBLAS.DTRSV(Uplo, TransA, Diag, matA, vecX, incX);
-                        fail("should throw RSRuntimeException for DTRSV");
-                    } catch (RSRuntimeException e) {
-                    }
-                    try {
-                        mBLAS.CTRSV(Uplo, TransA, Diag, matA, vecX, incX);
-                        fail("should throw RSRuntimeException for CTRSV");
-                    } catch (RSRuntimeException e) {
-                    }
-                    try {
-                        mBLAS.ZTRSV(Uplo, TransA, Diag, matA, vecX, incX);
-                        fail("should throw RSRuntimeException for ZTRSV");
-                    } catch (RSRuntimeException e) {
-                    }
-                }
-            }
-        }
-    }
-
-    public void L2_xTRSV_API(ArrayList<Allocation> mMatrix) {
-        for (int Uplo : mUplo) {
-            for (int TransA : mTranspose) {
-                for (int Diag : mDiag) {
-                    for (int incX : mInc) {
-                        xTRSV_API_test(Uplo, TransA, Diag, incX, mMatrix);
-                    }
-                }
-            }
-        }
-    }
-
-    public void test_L2_STRSV_API() {
-        L2_xTRSV_API(mMatrixS);
-    }
-
-    public void test_L2_DTRSV_API() {
-        L2_xTRSV_API(mMatrixD);
-    }
-
-    public void test_L2_CTRSV_API() {
-        L2_xTRSV_API(mMatrixC);
-    }
-
-    public void test_L2_ZTRSV_API() {
-        L2_xTRSV_API(mMatrixZ);
-    }
-
-    public void test_L2_STRSV_Correctness() {
-        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-        int diag = ScriptIntrinsicBLAS.NON_UNIT;
-        int incX = 1;
-
-        // Populate input allocations
-        Allocation matrixAS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dN));
-        Allocation vectorXS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, 1));
-        matrixAS.copyFrom(mBLASData.L2_sTRSV_A_nn);
-        vectorXS.copyFrom(mBLASData.L2_sTRSV_x_n1);
-
-        // Test for the default case: NO_TRANS
-        mBLAS.STRSV(uplo, trans, diag, matrixAS, vectorXS, incX);
-        Allocation vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, 1));
-        vectorXRef.copyFrom(mBLASData.L2_sTRSV_o_UN);
-        verifyMatrix(vectorXRef, vectorXS);
-
-        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
-        trans = ScriptIntrinsicBLAS.TRANSPOSE;
-        // Reload vector X, since it was overwritten by BLAS.
-        vectorXS.copyFrom(mBLASData.L2_sTRSV_x_n1);
-        mBLAS.STRSV(uplo, trans, diag, matrixAS, vectorXS, incX);
-        vectorXRef.copyFrom(mBLASData.L2_sTRSV_o_UT);
-        verifyMatrix(vectorXRef, vectorXS);
-
-        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
-        vectorXS.copyFrom(mBLASData.L2_sTRSV_x_n1);
-        mBLAS.STRSV(uplo, trans, diag, matrixAS, vectorXS, incX);
-        vectorXRef.copyFrom(mBLASData.L2_sTRSV_o_UH);
-        verifyMatrix(vectorXRef, vectorXS);
-
-        // Test for incX = 2;
-        trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        incX = 2;
-        int dimX = 1 + (mBLASData.dN - 1) * incX;
-        vectorXS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimX, 1));
-        vectorXS.copyFrom(mBLASData.L2_sTRSV_x_n2);
-
-        mBLAS.STRSV(uplo, trans, diag, matrixAS, vectorXS, incX);
-        vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimX, 1));
-        vectorXRef.copyFrom(mBLASData.L2_sTRSV_o_UN2);
-        verifyMatrix(vectorXRef, vectorXS);
-
-        mRS.finish();
-        checkError();
-    }
-
-    public void test_L2_DTRSV_Correctness() {
-        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-        int diag = ScriptIntrinsicBLAS.NON_UNIT;
-        int incX = 1;
-
-        // Populate input allocations
-        Allocation matrixAD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dN));
-        Allocation vectorXD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, 1));
-        matrixAD.copyFrom(mBLASData.L2_dTRSV_A_nn);
-        vectorXD.copyFrom(mBLASData.L2_dTRSV_x_n1);
-
-        // Test for the default case: NO_TRANS
-        mBLAS.DTRSV(uplo, trans, diag, matrixAD, vectorXD, incX);
-        Allocation vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, 1));
-        vectorXRef.copyFrom(mBLASData.L2_dTRSV_o_UN);
-        verifyMatrix(vectorXRef, vectorXD);
-
-        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
-        trans = ScriptIntrinsicBLAS.TRANSPOSE;
-        // Reload vector X, since it was overwritten by BLAS.
-        vectorXD.copyFrom(mBLASData.L2_dTRSV_x_n1);
-        mBLAS.DTRSV(uplo, trans, diag, matrixAD, vectorXD, incX);
-        vectorXRef.copyFrom(mBLASData.L2_dTRSV_o_UT);
-        verifyMatrix(vectorXRef, vectorXD);
-
-        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
-        vectorXD.copyFrom(mBLASData.L2_dTRSV_x_n1);
-        mBLAS.DTRSV(uplo, trans, diag, matrixAD, vectorXD, incX);
-        vectorXRef.copyFrom(mBLASData.L2_dTRSV_o_UH);
-        verifyMatrix(vectorXRef, vectorXD);
-
-        // Test for incX = 2;
-        trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        incX = 2;
-        int dimX = 1 + (mBLASData.dN - 1) * incX;
-        vectorXD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimX, 1));
-        vectorXD.copyFrom(mBLASData.L2_dTRSV_x_n2);
-
-        mBLAS.DTRSV(uplo, trans, diag, matrixAD, vectorXD, incX);
-        vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimX, 1));
-        vectorXRef.copyFrom(mBLASData.L2_dTRSV_o_UN2);
-        verifyMatrix(vectorXRef, vectorXD);
-
-        mRS.finish();
-        checkError();
-    }
-
-    public void test_L2_CTRSV_Correctness() {
-        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-        int diag = ScriptIntrinsicBLAS.NON_UNIT;
-        int incX = 1;
-
-        // Populate input allocations
-        Allocation matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dN));
-        Allocation vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, 1));
-        matrixAC.copyFrom(mBLASData.L2_cTRSV_A_nn);
-        vectorXC.copyFrom(mBLASData.L2_cTRSV_x_n1);
-
-        // Test for the default case: NO_TRANS
-        mBLAS.CTRSV(uplo, trans, diag, matrixAC, vectorXC, incX);
-        Allocation vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, 1));
-        vectorXRef.copyFrom(mBLASData.L2_cTRSV_o_UN);
-        verifyMatrix(vectorXRef, vectorXC);
-
-        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
-        trans = ScriptIntrinsicBLAS.TRANSPOSE;
-        // Reload vector X, since it was overwritten by BLAS.
-        vectorXC.copyFrom(mBLASData.L2_cTRSV_x_n1);
-        mBLAS.CTRSV(uplo, trans, diag, matrixAC, vectorXC, incX);
-        vectorXRef.copyFrom(mBLASData.L2_cTRSV_o_UT);
-        verifyMatrix(vectorXRef, vectorXC);
-
-        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
-        vectorXC.copyFrom(mBLASData.L2_cTRSV_x_n1);
-        mBLAS.CTRSV(uplo, trans, diag, matrixAC, vectorXC, incX);
-        vectorXRef.copyFrom(mBLASData.L2_cTRSV_o_UH);
-        verifyMatrix(vectorXRef, vectorXC);
-
-        // Test for incX = 2;
-        trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        incX = 2;
-        int dimX = 1 + (mBLASData.dN - 1) * incX;
-        vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimX, 1));
-        vectorXC.copyFrom(mBLASData.L2_cTRSV_x_n2);
-
-        mBLAS.CTRSV(uplo, trans, diag, matrixAC, vectorXC, incX);
-        vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimX, 1));
-        vectorXRef.copyFrom(mBLASData.L2_cTRSV_o_UN2);
-        verifyMatrix(vectorXRef, vectorXC);
-
-        mRS.finish();
-        checkError();
-    }
-
-    public void test_L2_ZTRSV_Correctness() {
-        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-        int diag = ScriptIntrinsicBLAS.NON_UNIT;
-        int incX = 1;
-
-        // Populate input allocations
-        Allocation matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dN));
-        Allocation vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, 1));
-        matrixAZ.copyFrom(mBLASData.L2_zTRSV_A_nn);
-        vectorXZ.copyFrom(mBLASData.L2_zTRSV_x_n1);
-
-        // Test for the default case: NO_TRANS
-        mBLAS.ZTRSV(uplo, trans, diag, matrixAZ, vectorXZ, incX);
-        Allocation vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, 1));
-        vectorXRef.copyFrom(mBLASData.L2_zTRSV_o_UN);
-        verifyMatrix(vectorXRef, vectorXZ);
-
-        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
-        trans = ScriptIntrinsicBLAS.TRANSPOSE;
-        // Reload vector X, since it was overwritten by BLAS.
-        vectorXZ.copyFrom(mBLASData.L2_zTRSV_x_n1);
-        mBLAS.ZTRSV(uplo, trans, diag, matrixAZ, vectorXZ, incX);
-        vectorXRef.copyFrom(mBLASData.L2_zTRSV_o_UT);
-        verifyMatrix(vectorXRef, vectorXZ);
-
-        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
-        vectorXZ.copyFrom(mBLASData.L2_zTRSV_x_n1);
-        mBLAS.ZTRSV(uplo, trans, diag, matrixAZ, vectorXZ, incX);
-        vectorXRef.copyFrom(mBLASData.L2_zTRSV_o_UH);
-        verifyMatrix(vectorXRef, vectorXZ);
-
-        // Test for incX = 2;
-        trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        incX = 2;
-        int dimX = 1 + (mBLASData.dN - 1) * incX;
-        vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimX, 1));
-        vectorXZ.copyFrom(mBLASData.L2_zTRSV_x_n2);
-
-        mBLAS.ZTRSV(uplo, trans, diag, matrixAZ, vectorXZ, incX);
-        vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimX, 1));
-        vectorXRef.copyFrom(mBLASData.L2_zTRSV_o_UN2);
-        verifyMatrix(vectorXRef, vectorXZ);
-
-        mRS.finish();
-        checkError();
-    }
-
-
-    private void xTBSV_API_test(int Uplo, int TransA, int Diag, int K, int incX, ArrayList<Allocation> mMatrix) {
-        for (Allocation matA : mMatrix) {
-            for (Allocation vecX : mMatrix) {
-                if (!validateVecInput(vecX)) {
-                    continue;
-                }
-                Element elemA = matA.getType().getElement();
-                if (validateTRMV(elemA, Uplo, TransA, Diag, matA, vecX, incX) && K >= 0) {
-                    try {
-                        if (elemA.isCompatible(Element.F32(mRS))) {
-                            mBLAS.STBSV(Uplo, TransA, Diag, K, matA, vecX, incX);
-                        } else if (elemA.isCompatible(Element.F64(mRS))) {
-                            mBLAS.DTBSV(Uplo, TransA, Diag, K, matA, vecX, incX);
-                        } else if (elemA.isCompatible(Element.F32_2(mRS))) {
-                            mBLAS.CTBSV(Uplo, TransA, Diag, K, matA, vecX, incX);
-                        } else if (elemA.isCompatible(Element.F64_2(mRS))) {
-                            mBLAS.ZTBSV(Uplo, TransA, Diag, K, matA, vecX, incX);
-                        }
-                    } catch (RSRuntimeException e) {
-                        fail("should NOT throw RSRuntimeException");
-                    }
-                } else {
-                    try {
-                        mBLAS.STBSV(Uplo, TransA, Diag, K, matA, vecX, incX);
-                        fail("should throw RSRuntimeException for STBSV");
-                    } catch (RSRuntimeException e) {
-                    }
-                    try {
-                        mBLAS.DTBSV(Uplo, TransA, Diag, K, matA, vecX, incX);
-                        fail("should throw RSRuntimeException for DTBSV");
-                    } catch (RSRuntimeException e) {
-                    }
-                    try {
-                        mBLAS.CTBSV(Uplo, TransA, Diag, K, matA, vecX, incX);
-                        fail("should throw RSRuntimeException for CTBSV");
-                    } catch (RSRuntimeException e) {
-                    }
-                    try {
-                        mBLAS.ZTBSV(Uplo, TransA, Diag, K, matA, vecX, incX);
-                        fail("should throw RSRuntimeException for ZTBSV");
-                    } catch (RSRuntimeException e) {
-                    }
-                }
-            }
-        }
-    }
-
-    public void L2_xTBSV_API(ArrayList<Allocation> mMatrix) {
-        for (int Uplo : mUplo) {
-            for (int TransA : mTranspose) {
-                for (int Diag : mDiag) {
-                    for (int K : mK) {
-                        for (int incX : mInc) {
-                            xTBSV_API_test(Uplo, TransA, Diag, K, incX, mMatrix);
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    public void test_L2_STBSV_API() {
-        L2_xTBSV_API(mMatrixS);
-    }
-
-    public void test_L2_DTBSV_API() {
-        L2_xTBSV_API(mMatrixD);
-    }
-
-    public void test_L2_CTBSV_API() {
-        L2_xTBSV_API(mMatrixC);
-    }
-
-    public void test_L2_ZTBSV_API() {
-        L2_xTBSV_API(mMatrixZ);
-    }
-
-    public void test_L2_STBSV_Correctness() {
-        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-        int diag = ScriptIntrinsicBLAS.NON_UNIT;
-        int incX = 1;
-
-        // Populate input allocations
-        Allocation matrixAS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dN));
-        Allocation vectorXS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, 1));
-        matrixAS.copy2DRangeFrom(0, 0, mBLASData.KL + 1, mBLASData.dN, mBLASData.L2_sTBSV_A_nn);
-        vectorXS.copyFrom(mBLASData.L2_sTBSV_x_n1);
-
-        // Test for the default case: NO_TRANS
-        mBLAS.STBSV(uplo, trans, diag, mBLASData.KL, matrixAS, vectorXS, incX);
-        Allocation vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, 1));
-        vectorXRef.copyFrom(mBLASData.L2_sTBSV_o_UN);
-        verifyMatrix(vectorXRef, vectorXS);
-
-        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
-        trans = ScriptIntrinsicBLAS.TRANSPOSE;
-        // Reload vector X, since it was overwritten by BLAS.
-        vectorXS.copyFrom(mBLASData.L2_sTBSV_x_n1);
-        mBLAS.STBSV(uplo, trans, diag, mBLASData.KL, matrixAS, vectorXS, incX);
-        vectorXRef.copyFrom(mBLASData.L2_sTBSV_o_UT);
-        verifyMatrix(vectorXRef, vectorXS);
-
-        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
-        vectorXS.copyFrom(mBLASData.L2_sTBSV_x_n1);
-        mBLAS.STBSV(uplo, trans, diag, mBLASData.KL, matrixAS, vectorXS, incX);
-        vectorXRef.copyFrom(mBLASData.L2_sTBSV_o_UH);
-        verifyMatrix(vectorXRef, vectorXS);
-
-        // Test for incX = 2;
-        trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        incX = 2;
-        int dimX = 1 + (mBLASData.dN - 1) * incX;
-        vectorXS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimX, 1));
-        vectorXS.copyFrom(mBLASData.L2_sTBSV_x_n2);
-
-        mBLAS.STBSV(uplo, trans, diag, mBLASData.KL, matrixAS, vectorXS, incX);
-        vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimX, 1));
-        vectorXRef.copyFrom(mBLASData.L2_sTBSV_o_UN2);
-        verifyMatrix(vectorXRef, vectorXS);
-
-        mRS.finish();
-        checkError();
-    }
-
-    public void test_L2_DTBSV_Correctness() {
-        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-        int diag = ScriptIntrinsicBLAS.NON_UNIT;
-        int incX = 1;
-
-        // Populate input allocations
-        Allocation matrixAD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dN));
-        Allocation vectorXD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, 1));
-        matrixAD.copy2DRangeFrom(0, 0, mBLASData.KL + 1, mBLASData.dN, mBLASData.L2_dTBSV_A_nn);
-        vectorXD.copyFrom(mBLASData.L2_dTBSV_x_n1);
-
-        // Test for the default case: NO_TRANS
-        mBLAS.DTBSV(uplo, trans, diag, mBLASData.KL, matrixAD, vectorXD, incX);
-        Allocation vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, 1));
-        vectorXRef.copyFrom(mBLASData.L2_dTBSV_o_UN);
-        verifyMatrix(vectorXRef, vectorXD);
-
-        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
-        trans = ScriptIntrinsicBLAS.TRANSPOSE;
-        // Reload vector X, since it was overwritten by BLAS.
-        vectorXD.copyFrom(mBLASData.L2_dTBSV_x_n1);
-        mBLAS.DTBSV(uplo, trans, diag, mBLASData.KL, matrixAD, vectorXD, incX);
-        vectorXRef.copyFrom(mBLASData.L2_dTBSV_o_UT);
-        verifyMatrix(vectorXRef, vectorXD);
-
-        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
-        vectorXD.copyFrom(mBLASData.L2_dTBSV_x_n1);
-        mBLAS.DTBSV(uplo, trans, diag, mBLASData.KL, matrixAD, vectorXD, incX);
-        vectorXRef.copyFrom(mBLASData.L2_dTBSV_o_UH);
-        verifyMatrix(vectorXRef, vectorXD);
-
-        // Test for incX = 2;
-        trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        incX = 2;
-        int dimX = 1 + (mBLASData.dN - 1) * incX;
-        vectorXD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimX, 1));
-        vectorXD.copyFrom(mBLASData.L2_dTBSV_x_n2);
-
-        mBLAS.DTBSV(uplo, trans, diag, mBLASData.KL, matrixAD, vectorXD, incX);
-        vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimX, 1));
-        vectorXRef.copyFrom(mBLASData.L2_dTBSV_o_UN2);
-        verifyMatrix(vectorXRef, vectorXD);
-
-        mRS.finish();
-        checkError();
-    }
-
-    public void test_L2_CTBSV_Correctness() {
-        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-        int diag = ScriptIntrinsicBLAS.NON_UNIT;
-        int incX = 1;
-
-        // Populate input allocations
-        Allocation matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dN));
-        Allocation vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, 1));
-        matrixAC.copy2DRangeFrom(0, 0, mBLASData.KL + 1, mBLASData.dN, mBLASData.L2_cTBSV_A_nn);
-        vectorXC.copyFrom(mBLASData.L2_cTBSV_x_n1);
-
-        // Test for the default case: NO_TRANS
-        mBLAS.CTBSV(uplo, trans, diag, mBLASData.KL, matrixAC, vectorXC, incX);
-        Allocation vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, 1));
-        vectorXRef.copyFrom(mBLASData.L2_cTBSV_o_UN);
-        verifyMatrix(vectorXRef, vectorXC);
-
-        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
-        trans = ScriptIntrinsicBLAS.TRANSPOSE;
-        // Reload vector X, since it was overwritten by BLAS.
-        vectorXC.copyFrom(mBLASData.L2_cTBSV_x_n1);
-        mBLAS.CTBSV(uplo, trans, diag, mBLASData.KL, matrixAC, vectorXC, incX);
-        vectorXRef.copyFrom(mBLASData.L2_cTBSV_o_UT);
-        verifyMatrix(vectorXRef, vectorXC);
-
-        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
-        vectorXC.copyFrom(mBLASData.L2_cTBSV_x_n1);
-        mBLAS.CTBSV(uplo, trans, diag, mBLASData.KL, matrixAC, vectorXC, incX);
-        vectorXRef.copyFrom(mBLASData.L2_cTBSV_o_UH);
-        verifyMatrix(vectorXRef, vectorXC);
-
-        // Test for incX = 2;
-        trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        incX = 2;
-        int dimX = 1 + (mBLASData.dN - 1) * incX;
-        vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimX, 1));
-        vectorXC.copyFrom(mBLASData.L2_cTBSV_x_n2);
-
-        mBLAS.CTBSV(uplo, trans, diag, mBLASData.KL, matrixAC, vectorXC, incX);
-        vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimX, 1));
-        vectorXRef.copyFrom(mBLASData.L2_cTBSV_o_UN2);
-        verifyMatrix(vectorXRef, vectorXC);
-
-        mRS.finish();
-        checkError();
-    }
-
-    public void test_L2_ZTBSV_Correctness() {
-        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-        int diag = ScriptIntrinsicBLAS.NON_UNIT;
-        int incX = 1;
-
-        // Populate input allocations
-        Allocation matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dN));
-        Allocation vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, 1));
-        matrixAZ.copy2DRangeFrom(0, 0, mBLASData.KL + 1, mBLASData.dN, mBLASData.L2_zTBSV_A_nn);
-        vectorXZ.copyFrom(mBLASData.L2_zTBSV_x_n1);
-
-        // Test for the default case: NO_TRANS
-        mBLAS.ZTBSV(uplo, trans, diag, mBLASData.KL, matrixAZ, vectorXZ, incX);
-        Allocation vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, 1));
-        vectorXRef.copyFrom(mBLASData.L2_zTBSV_o_UN);
-        verifyMatrix(vectorXRef, vectorXZ);
-
-        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
-        trans = ScriptIntrinsicBLAS.TRANSPOSE;
-        // Reload vector X, since it was overwritten by BLAS.
-        vectorXZ.copyFrom(mBLASData.L2_zTBSV_x_n1);
-        mBLAS.ZTBSV(uplo, trans, diag, mBLASData.KL, matrixAZ, vectorXZ, incX);
-        vectorXRef.copyFrom(mBLASData.L2_zTBSV_o_UT);
-        verifyMatrix(vectorXRef, vectorXZ);
-
-        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
-        vectorXZ.copyFrom(mBLASData.L2_zTBSV_x_n1);
-        mBLAS.ZTBSV(uplo, trans, diag, mBLASData.KL, matrixAZ, vectorXZ, incX);
-        vectorXRef.copyFrom(mBLASData.L2_zTBSV_o_UH);
-        verifyMatrix(vectorXRef, vectorXZ);
-
-        // Test for incX = 2;
-        trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        incX = 2;
-        int dimX = 1 + (mBLASData.dN - 1) * incX;
-        vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimX, 1));
-        vectorXZ.copyFrom(mBLASData.L2_zTBSV_x_n2);
-
-        mBLAS.ZTBSV(uplo, trans, diag, mBLASData.KL, matrixAZ, vectorXZ, incX);
-        vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimX, 1));
-        vectorXRef.copyFrom(mBLASData.L2_zTBSV_o_UN2);
-        verifyMatrix(vectorXRef, vectorXZ);
-
-        mRS.finish();
-        checkError();
-    }
-
-
-    private void xTPSV_API_test(int Uplo, int TransA, int Diag, int incX, ArrayList<Allocation> mMatrix) {
-        for (Allocation matA : mMatrix) {
-            for (Allocation vecX : mMatrix) {
-                if (!validateVecInput(vecX)) {
-                    continue;
-                }
-                Element elemA = matA.getType().getElement();
-                if (validateTPMV(elemA, Uplo, TransA, Diag, matA, vecX, incX)) {
-                    try {
-                        if (elemA.isCompatible(Element.F32(mRS))) {
-                            mBLAS.STPSV(Uplo, TransA, Diag, matA, vecX, incX);
-                        } else if (elemA.isCompatible(Element.F64(mRS))) {
-                            mBLAS.DTPSV(Uplo, TransA, Diag, matA, vecX, incX);
-                        } else if (elemA.isCompatible(Element.F32_2(mRS))) {
-                            mBLAS.CTPSV(Uplo, TransA, Diag, matA, vecX, incX);
-                        } else if (elemA.isCompatible(Element.F64_2(mRS))) {
-                            mBLAS.ZTPSV(Uplo, TransA, Diag, matA, vecX, incX);
-                        }
-                    } catch (RSRuntimeException e) {
-                        fail("should NOT throw RSRuntimeException");
-                    }
-                } else {
-                    try {
-                        mBLAS.STPSV(Uplo, TransA, Diag, matA, vecX, incX);
-                        fail("should throw RSRuntimeException for STPSV");
-                    } catch (RSRuntimeException e) {
-                    }
-                    try {
-                        mBLAS.DTPSV(Uplo, TransA, Diag, matA, vecX, incX);
-                        fail("should throw RSRuntimeException for DTPSV");
-                    } catch (RSRuntimeException e) {
-                    }
-                    try {
-                        mBLAS.CTPSV(Uplo, TransA, Diag, matA, vecX, incX);
-                        fail("should throw RSRuntimeException for CTPSV");
-                    } catch (RSRuntimeException e) {
-                    }
-                    try {
-                        mBLAS.ZTPSV(Uplo, TransA, Diag, matA, vecX, incX);
-                        fail("should throw RSRuntimeException for ZTPSV");
-                    } catch (RSRuntimeException e) {
-                    }
-                }
-            }
-        }
-    }
-
-    public void L2_xTPSV_API(ArrayList<Allocation> mMatrix) {
-        for (int Uplo : mUplo) {
-            for (int TransA : mTranspose) {
-                for (int Diag : mDiag) {
-                    for (int incX : mInc) {
-                        xTPSV_API_test(Uplo, TransA, Diag, incX, mMatrix);
-                    }
-                }
-            }
-        }
-    }
-
-    public void test_L2_STPSV_API() {
-        L2_xTPSV_API(mMatrixS);
-    }
-
-    public void test_L2_DTPSV_API() {
-        L2_xTPSV_API(mMatrixD);
-    }
-
-    public void test_L2_CTPSV_API() {
-        L2_xTPSV_API(mMatrixC);
-    }
-
-    public void test_L2_ZTPSV_API() {
-        L2_xTPSV_API(mMatrixZ);
-    }
-
-    public void test_L2_STPSV_Correctness() {
-        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-        int diag = ScriptIntrinsicBLAS.NON_UNIT;
-        int incX = 1;
-
-        // Populate input allocations
-        int N = mBLASData.dN;
-        Allocation matrixAS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), N * (N+1) / 2, 1));
-        Allocation vectorXS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), N, 1));
-        matrixAS.copyFrom(mBLASData.L2_sTRSV_A_nn_pu);
-        vectorXS.copyFrom(mBLASData.L2_sTRSV_x_n1);
-
-        // Test for the default case: NO_TRANS
-        mBLAS.STPSV(uplo, trans, diag, matrixAS, vectorXS, incX);
-        Allocation vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), N, 1));
-        vectorXRef.copyFrom(mBLASData.L2_sTRSV_o_UN);
-        verifyMatrix(vectorXRef, vectorXS);
-
-        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
-        trans = ScriptIntrinsicBLAS.TRANSPOSE;
-        // Reload vector X, since it was overwritten by BLAS.
-        vectorXS.copyFrom(mBLASData.L2_sTRSV_x_n1);
-        mBLAS.STPSV(uplo, trans, diag, matrixAS, vectorXS, incX);
-        vectorXRef.copyFrom(mBLASData.L2_sTRSV_o_UT);
-        verifyMatrix(vectorXRef, vectorXS);
-
-        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
-        vectorXS.copyFrom(mBLASData.L2_sTRSV_x_n1);
-        mBLAS.STPSV(uplo, trans, diag, matrixAS, vectorXS, incX);
-        vectorXRef.copyFrom(mBLASData.L2_sTRSV_o_UH);
-        verifyMatrix(vectorXRef, vectorXS);
-
-        // Test for incX = 2;
-        trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        incX = 2;
-        int dimX = 1 + (N - 1) * incX;
-        vectorXS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimX, 1));
-        vectorXS.copyFrom(mBLASData.L2_sTRSV_x_n2);
-
-        mBLAS.STPSV(uplo, trans, diag, matrixAS, vectorXS, incX);
-        vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimX, 1));
-        vectorXRef.copyFrom(mBLASData.L2_sTRSV_o_UN2);
-        verifyMatrix(vectorXRef, vectorXS);
-
-        mRS.finish();
-        checkError();
-    }
-
-    public void test_L2_DTPSV_Correctness() {
-        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-        int diag = ScriptIntrinsicBLAS.NON_UNIT;
-        int incX = 1;
-
-        // Populate input allocations
-        int N = mBLASData.dN;
-        Allocation matrixAD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), N * (N+1) / 2, 1));
-        Allocation vectorXD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), N, 1));
-        matrixAD.copyFrom(mBLASData.L2_dTRSV_A_nn_pu);
-        vectorXD.copyFrom(mBLASData.L2_dTRSV_x_n1);
-
-        // Test for the default case: NO_TRANS
-        mBLAS.DTPSV(uplo, trans, diag, matrixAD, vectorXD, incX);
-        Allocation vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), N, 1));
-        vectorXRef.copyFrom(mBLASData.L2_dTRSV_o_UN);
-        verifyMatrix(vectorXRef, vectorXD);
-
-        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
-        trans = ScriptIntrinsicBLAS.TRANSPOSE;
-        // Reload vector X, since it was overwritten by BLAS.
-        vectorXD.copyFrom(mBLASData.L2_dTRSV_x_n1);
-        mBLAS.DTPSV(uplo, trans, diag, matrixAD, vectorXD, incX);
-        vectorXRef.copyFrom(mBLASData.L2_dTRSV_o_UT);
-        verifyMatrix(vectorXRef, vectorXD);
-
-        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
-        vectorXD.copyFrom(mBLASData.L2_dTRSV_x_n1);
-        mBLAS.DTPSV(uplo, trans, diag, matrixAD, vectorXD, incX);
-        vectorXRef.copyFrom(mBLASData.L2_dTRSV_o_UH);
-        verifyMatrix(vectorXRef, vectorXD);
-
-        // Test for incX = 2;
-        trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        incX = 2;
-        int dimX = 1 + (N - 1) * incX;
-        vectorXD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimX, 1));
-        vectorXD.copyFrom(mBLASData.L2_dTRSV_x_n2);
-
-        mBLAS.DTPSV(uplo, trans, diag, matrixAD, vectorXD, incX);
-        vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimX, 1));
-        vectorXRef.copyFrom(mBLASData.L2_dTRSV_o_UN2);
-        verifyMatrix(vectorXRef, vectorXD);
-
-        mRS.finish();
-        checkError();
-    }
-
-    public void test_L2_CTPSV_Correctness() {
-        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-        int diag = ScriptIntrinsicBLAS.NON_UNIT;
-        int incX = 1;
-
-        // Populate input allocations
-        int N = mBLASData.dN;
-        Allocation matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), N * (N+1) / 2, 1));
-        Allocation vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), N, 1));
-        matrixAC.copyFrom(mBLASData.L2_cTRSV_A_nn_pu);
-        vectorXC.copyFrom(mBLASData.L2_cTRSV_x_n1);
-
-        // Test for the default case: NO_TRANS
-        mBLAS.CTPSV(uplo, trans, diag, matrixAC, vectorXC, incX);
-        Allocation vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), N, 1));
-        vectorXRef.copyFrom(mBLASData.L2_cTRSV_o_UN);
-        verifyMatrix(vectorXRef, vectorXC);
-
-        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
-        trans = ScriptIntrinsicBLAS.TRANSPOSE;
-        // Reload vector X, since it was overwritten by BLAS.
-        vectorXC.copyFrom(mBLASData.L2_cTRSV_x_n1);
-        mBLAS.CTPSV(uplo, trans, diag, matrixAC, vectorXC, incX);
-        vectorXRef.copyFrom(mBLASData.L2_cTRSV_o_UT);
-        verifyMatrix(vectorXRef, vectorXC);
-
-        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
-        vectorXC.copyFrom(mBLASData.L2_cTRSV_x_n1);
-        mBLAS.CTPSV(uplo, trans, diag, matrixAC, vectorXC, incX);
-        vectorXRef.copyFrom(mBLASData.L2_cTRSV_o_UH);
-        verifyMatrix(vectorXRef, vectorXC);
-
-        // Test for incX = 2;
-        trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        incX = 2;
-        int dimX = 1 + (N - 1) * incX;
-        vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimX, 1));
-        vectorXC.copyFrom(mBLASData.L2_cTRSV_x_n2);
-
-        mBLAS.CTPSV(uplo, trans, diag, matrixAC, vectorXC, incX);
-        vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimX, 1));
-        vectorXRef.copyFrom(mBLASData.L2_cTRSV_o_UN2);
-        verifyMatrix(vectorXRef, vectorXC);
-
-        mRS.finish();
-        checkError();
-    }
-
-    public void test_L2_ZTPSV_Correctness() {
-        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-        int diag = ScriptIntrinsicBLAS.NON_UNIT;
-        int incX = 1;
-
-        // Populate input allocations
-        int N = mBLASData.dN;
-        Allocation matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), N * (N+1) / 2, 1));
-        Allocation vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), N, 1));
-        matrixAZ.copyFrom(mBLASData.L2_zTRSV_A_nn_pu);
-        vectorXZ.copyFrom(mBLASData.L2_zTRSV_x_n1);
-
-        // Test for the default case: NO_TRANS
-        mBLAS.ZTPSV(uplo, trans, diag, matrixAZ, vectorXZ, incX);
-        Allocation vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), N, 1));
-        vectorXRef.copyFrom(mBLASData.L2_zTRSV_o_UN);
-        verifyMatrix(vectorXRef, vectorXZ);
-
-        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
-        trans = ScriptIntrinsicBLAS.TRANSPOSE;
-        // Reload vector X, since it was overwritten by BLAS.
-        vectorXZ.copyFrom(mBLASData.L2_zTRSV_x_n1);
-        mBLAS.ZTPSV(uplo, trans, diag, matrixAZ, vectorXZ, incX);
-        vectorXRef.copyFrom(mBLASData.L2_zTRSV_o_UT);
-        verifyMatrix(vectorXRef, vectorXZ);
-
-        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
-        vectorXZ.copyFrom(mBLASData.L2_zTRSV_x_n1);
-        mBLAS.ZTPSV(uplo, trans, diag, matrixAZ, vectorXZ, incX);
-        vectorXRef.copyFrom(mBLASData.L2_zTRSV_o_UH);
-        verifyMatrix(vectorXRef, vectorXZ);
-
-        // Test for incX = 2;
-        trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        incX = 2;
-        int dimX = 1 + (N - 1) * incX;
-        vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimX, 1));
-        vectorXZ.copyFrom(mBLASData.L2_zTRSV_x_n2);
-
-        mBLAS.ZTPSV(uplo, trans, diag, matrixAZ, vectorXZ, incX);
-        vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimX, 1));
-        vectorXRef.copyFrom(mBLASData.L2_zTRSV_o_UN2);
-        verifyMatrix(vectorXRef, vectorXZ);
-
-        mRS.finish();
-        checkError();
-    }
-
-
-    private boolean validateGER(Element e, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
-        if (!A.getType().getElement().isCompatible(e) ||
-            !X.getType().getElement().isCompatible(e) ||
-            !Y.getType().getElement().isCompatible(e) ) {
-            return false;
-        }
-
-        if (X.getType().getY() > 1 || Y.getType().getY() > 1) {
-            return false;
-        }
-
-        int M = A.getType().getY();
-        int N = A.getType().getX();
-
-        if (N < 1 || M < 1) {
-            return false;
-        }
-        if (incX <= 0 || incY <= 0) {
-            return false;
-        }
-        int expectedXDim = 1 + (M - 1) * incX;
-        if (X.getType().getX() != expectedXDim) {
-            return false;
-        }
-        int expectedYDim = 1 + (N - 1) * incY;
-        if (Y.getType().getX() != expectedYDim) {
-            return false;
-        }
-        return true;
-    }
-
-
-    private void xGER_API_test(int incX, int incY, ArrayList<Allocation> mMatrix) {
-        for (Allocation matA : mMatrix) {
-            for (Allocation vecX : mMatrix) {
-                if (!validateVecInput(vecX)) {
-                    continue;
-                }
-                for (Allocation vecY : mMatrix) {
-                    if (!validateVecInput(vecY)) {
-                        continue;
-                    }
-                    Element elemA = matA.getType().getElement();
-                    if (validateGER(elemA, vecX, incX, vecY, incY, matA)) {
-                        try {
-                            if (elemA.isCompatible(Element.F32(mRS))) {
-                                mBLAS.SGER(alphaS, vecX, incX, vecY, incY, matA);
-                            } else if (elemA.isCompatible(Element.F64(mRS))) {
-                                mBLAS.DGER(alphaD, vecX, incX, vecY, incY, matA);
-                            }
-                        } catch (RSRuntimeException e) {
-                            fail("should NOT throw RSRuntimeException");
-                        }
-                    } else {
-                        try {
-                            mBLAS.SGER(alphaS, vecX, incX, vecY, incY, matA);
-                            fail("should throw RSRuntimeException for SGER");
-                        } catch (RSRuntimeException e) {
-                        }
-                        try {
-                            mBLAS.DGER(alphaD, vecX, incX, vecY, incY, matA);
-                            fail("should throw RSRuntimeException for DGER");
-                        } catch (RSRuntimeException e) {
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    private void L2_xGER_API(ArrayList<Allocation> mMatrix) {
-        for (int incX : mInc) {
-            for (int incY : mInc) {
-                xGERU_API_test(incX, incY, mMatrix);
-            }
-        }
-    }
-
-    public void test_L2_SGER_API() {
-        L2_xGER_API(mMatrixS);
-    }
-
-    public void test_L2_DGER_API() {
-        L2_xGER_API(mMatrixD);
-    }
-
-    public void test_L2_SGER_Correctness() {
-        int incX = 1;
-        int incY = 1;
-
-        // Populate input allocations
-        Allocation matrixAS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dM));
-        Allocation vectorXS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dM, 1));
-        Allocation vectorYS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, 1));
-        matrixAS.copyFrom(mBLASData.L2_sGER_A_mn);
-        vectorXS.copyFrom(mBLASData.L2_sGER_x_m1);
-        vectorYS.copyFrom(mBLASData.L2_sGER_y_n1);
-
-        // Test for the default case: NO_TRANS
-        mBLAS.SGER(alphaS, vectorXS, incX, vectorYS, incY, matrixAS);
-        Allocation matrixARef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dM));
-        matrixARef.copyFrom(mBLASData.L2_sGER_o_N);
-        verifyMatrix(matrixARef, matrixAS);
-
-        // Test for incX = 2 & incY = 3;
-        incX = 2;
-        incY = 3;
-        int dimX = 1 + (mBLASData.dM - 1) * incX;
-        int dimY = 1 + (mBLASData.dN - 1) * incY;
-        vectorXS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimX, 1));
-        vectorYS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimY, 1));
-        vectorXS.copyFrom(mBLASData.L2_sGER_x_m2);
-        vectorYS.copyFrom(mBLASData.L2_sGER_y_n2);
-        matrixAS.copyFrom(mBLASData.L2_sGER_A_mn);
-
-        mBLAS.SGER(alphaS, vectorXS, incX, vectorYS, incY, matrixAS);
-        verifyMatrix(matrixARef, matrixAS);
-
-        mRS.finish();
-        checkError();
-    }
-
-    public void test_L2_DGER_Correctness() {
-        int incX = 1;
-        int incY = 1;
-
-        // Populate input allocations
-        Allocation matrixAD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dM));
-        Allocation vectorXD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dM, 1));
-        Allocation vectorYD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, 1));
-        matrixAD.copyFrom(mBLASData.L2_dGER_A_mn);
-        vectorXD.copyFrom(mBLASData.L2_dGER_x_m1);
-        vectorYD.copyFrom(mBLASData.L2_dGER_y_n1);
-
-        // Test for the default case: NO_TRANS
-        mBLAS.DGER(alphaD, vectorXD, incX, vectorYD, incY, matrixAD);
-        Allocation matrixARef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dM));
-        matrixARef.copyFrom(mBLASData.L2_dGER_o_N);
-        verifyMatrix(matrixARef, matrixAD);
-
-        // Test for incX = 2 & incY = 3;
-        incX = 2;
-        incY = 3;
-        int dimX = 1 + (mBLASData.dM - 1) * incX;
-        int dimY = 1 + (mBLASData.dN - 1) * incY;
-        vectorXD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimX, 1));
-        vectorYD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimY, 1));
-        vectorXD.copyFrom(mBLASData.L2_dGER_x_m2);
-        vectorYD.copyFrom(mBLASData.L2_dGER_y_n2);
-        matrixAD.copyFrom(mBLASData.L2_dGER_A_mn);
-
-        mBLAS.DGER(alphaD, vectorXD, incX, vectorYD, incY, matrixAD);
-        verifyMatrix(matrixARef, matrixAD);
-
-        mRS.finish();
-        checkError();
-    }
-
-
-    private boolean validateGERU(Element e, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
-        if (!A.getType().getElement().isCompatible(e) ||
-            !X.getType().getElement().isCompatible(e) ||
-            !Y.getType().getElement().isCompatible(e)) {
-            return false;
-        }
-        if (X.getType().getY() > 1 || Y.getType().getY() > 1) {
-            return false;
-        }
-
-        int M = A.getType().getY();
-        int N = A.getType().getX();
-        if (incX <= 0 || incY <= 0) {
-            return false;
-        }
-        int expectedXDim = 1 + (M - 1) * incX;
-        if (X.getType().getX() != expectedXDim) {
-            return false;
-        }
-        int expectedYDim = 1 + (N - 1) * incY;
-        if (Y.getType().getX() != expectedYDim) {
-            return false;
-        }
-        return true;
-    }
-
-    private void xGERU_API_test(int incX, int incY, ArrayList<Allocation> mMatrix) {
-        for (Allocation matA : mMatrix) {
-            for (Allocation vecX : mMatrix) {
-                if (!validateVecInput(vecX)) {
-                    continue;
-                }
-                for (Allocation vecY : mMatrix) {
-                    if (!validateVecInput(vecY)) {
-                        continue;
-                    }
-                    Element elemA = matA.getType().getElement();
-                    if (validateGERU(elemA, vecX, incX, vecY, incY, matA)) {
-                        try {
-                            if (elemA.isCompatible(Element.F32_2(mRS))) {
-                                mBLAS.CGERU(alphaC, vecX, incX, vecY, incY, matA);
-                            } else if (elemA.isCompatible(Element.F64_2(mRS))) {
-                                mBLAS.ZGERU(alphaZ, vecX, incX, vecY, incY, matA);
-                            }
-                        } catch (RSRuntimeException e) {
-                            fail("should NOT throw RSRuntimeException");
-                        }
-                    } else {
-                        try {
-                            mBLAS.CGERU(alphaC, vecX, incX, vecY, incY, matA);
-                            fail("should throw RSRuntimeException for CGERU");
-                        } catch (RSRuntimeException e) {
-                        }
-                        try {
-                            mBLAS.ZGERU(alphaZ, vecX, incX, vecY, incY, matA);
-                            fail("should throw RSRuntimeException for ZGERU");
-                        } catch (RSRuntimeException e) {
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    private void L2_xGERU_API(ArrayList<Allocation> mMatrix) {
-        for (int incX : mInc) {
-            for (int incY : mInc) {
-                xGERU_API_test(incX, incY, mMatrix);
-            }
-        }
-    }
-
-    public void test_L2_CGERU_API() {
-        L2_xGERU_API(mMatrixC);
-    }
-
-    public void test_L2_ZGERU_API() {
-        L2_xGERU_API(mMatrixZ);
-    }
-
-    public void test_L2_CGERU_Correctness() {
-        int incX = 1;
-        int incY = 1;
-
-        // Populate input allocations
-        Allocation matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dM));
-        Allocation vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dM, 1));
-        Allocation vectorYC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, 1));
-        matrixAC.copyFrom(mBLASData.L2_cGERU_A_mn);
-        vectorXC.copyFrom(mBLASData.L2_cGERU_x_m1);
-        vectorYC.copyFrom(mBLASData.L2_cGERU_y_n1);
-
-        // Test for the default case: NO_TRANS
-        mBLAS.CGERU(alphaC, vectorXC, incX, vectorYC, incY, matrixAC);
-        Allocation matrixARef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dM));
-        matrixARef.copyFrom(mBLASData.L2_cGERU_o_N);
-        verifyMatrix(matrixARef, matrixAC);
-
-        // Test for incX = 2 & incY = 3;
-        incX = 2;
-        incY = 3;
-        int dimX = 1 + (mBLASData.dM - 1) * incX;
-        int dimY = 1 + (mBLASData.dN - 1) * incY;
-        vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimX, 1));
-        vectorYC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimY, 1));
-        vectorXC.copyFrom(mBLASData.L2_cGERU_x_m2);
-        vectorYC.copyFrom(mBLASData.L2_cGERU_y_n2);
-        matrixAC.copyFrom(mBLASData.L2_cGERU_A_mn);
-
-        mBLAS.CGERU(alphaC, vectorXC, incX, vectorYC, incY, matrixAC);
-        verifyMatrix(matrixARef, matrixAC);
-
-        mRS.finish();
-        checkError();
-    }
-
-    public void test_L2_ZGERU_Correctness() {
-        int incX = 1;
-        int incY = 1;
-
-        // Populate input allocations
-        Allocation matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dM));
-        Allocation vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dM, 1));
-        Allocation vectorYZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, 1));
-        matrixAZ.copyFrom(mBLASData.L2_zGERU_A_mn);
-        vectorXZ.copyFrom(mBLASData.L2_zGERU_x_m1);
-        vectorYZ.copyFrom(mBLASData.L2_zGERU_y_n1);
-
-        // Test for the default case: NO_TRANS
-        mBLAS.ZGERU(alphaZ, vectorXZ, incX, vectorYZ, incY, matrixAZ);
-        Allocation matrixARef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dM));
-        matrixARef.copyFrom(mBLASData.L2_zGERU_o_N);
-        verifyMatrix(matrixARef, matrixAZ);
-
-        // Test for incX = 2 & incY = 3;
-        incX = 2;
-        incY = 3;
-        int dimX = 1 + (mBLASData.dM - 1) * incX;
-        int dimY = 1 + (mBLASData.dN - 1) * incY;
-        vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimX, 1));
-        vectorYZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimY, 1));
-        vectorXZ.copyFrom(mBLASData.L2_zGERU_x_m2);
-        vectorYZ.copyFrom(mBLASData.L2_zGERU_y_n2);
-        matrixAZ.copyFrom(mBLASData.L2_zGERU_A_mn);
-
-        mBLAS.ZGERU(alphaZ, vectorXZ, incX, vectorYZ, incY, matrixAZ);
-        verifyMatrix(matrixARef, matrixAZ);
-
-        mRS.finish();
-        checkError();
-    }
-
-
-
-    private void xGERC_API_test(int incX, int incY, ArrayList<Allocation> mMatrix) {
-        for (Allocation matA : mMatrix) {
-            for (Allocation vecX : mMatrix) {
-                if (!validateVecInput(vecX)) {
-                    continue;
-                }
-                for (Allocation vecY : mMatrix) {
-                    if (!validateVecInput(vecY)) {
-                        continue;
-                    }
-                    Element elemA = matA.getType().getElement();
-                    if (validateGERU(elemA, vecX, incX, vecY, incY, matA)) {
-                        try {
-                            if (elemA.isCompatible(Element.F32_2(mRS))) {
-                                mBLAS.CGERC(alphaC, vecX, incX, vecY, incY, matA);
-                            } else if (elemA.isCompatible(Element.F64_2(mRS))) {
-                                mBLAS.ZGERC(alphaZ, vecX, incX, vecY, incY, matA);
-                            }
-                        } catch (RSRuntimeException e) {
-                            fail("should NOT throw RSRuntimeException");
-                        }
-                    } else {
-                        try {
-                            mBLAS.CGERC(alphaC, vecX, incX, vecY, incY, matA);
-                            fail("should throw RSRuntimeException for CGERC");
-                        } catch (RSRuntimeException e) {
-                        }
-                        try {
-                            mBLAS.ZGERC(alphaZ, vecX, incX, vecY, incY, matA);
-                            fail("should throw RSRuntimeException for ZGERC");
-                        } catch (RSRuntimeException e) {
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    private void L2_xGERC_API(ArrayList<Allocation> mMatrix) {
-        for (int incX : mInc) {
-            for (int incY : mInc) {
-                xGERC_API_test(incX, incY, mMatrix);
-            }
-        }
-    }
-
-    public void test_L2_CGERC_API() {
-        L2_xGERC_API(mMatrixC);
-    }
-
-    public void test_L2_ZGERC_API() {
-        L2_xGERC_API(mMatrixZ);
-    }
-
-    public void test_L2_CGERC_Correctness() {
-        int incX = 1;
-        int incY = 1;
-
-        // Populate input allocations
-        Allocation matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dM));
-        Allocation vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dM, 1));
-        Allocation vectorYC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, 1));
-        matrixAC.copyFrom(mBLASData.L2_cGERC_A_mn);
-        vectorXC.copyFrom(mBLASData.L2_cGERC_x_m1);
-        vectorYC.copyFrom(mBLASData.L2_cGERC_y_n1);
-
-        // Test for the default case: NO_TRANS
-        mBLAS.CGERC(alphaC, vectorXC, incX, vectorYC, incY, matrixAC);
-        Allocation matrixARef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dM));
-        matrixARef.copyFrom(mBLASData.L2_cGERC_o_N);
-        verifyMatrix(matrixARef, matrixAC);
-
-        // Test for incX = 2 & incY = 3;
-        incX = 2;
-        incY = 3;
-        int dimX = 1 + (mBLASData.dM - 1) * incX;
-        int dimY = 1 + (mBLASData.dN - 1) * incY;
-        vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimX, 1));
-        vectorYC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimY, 1));
-        vectorXC.copyFrom(mBLASData.L2_cGERC_x_m2);
-        vectorYC.copyFrom(mBLASData.L2_cGERC_y_n2);
-        matrixAC.copyFrom(mBLASData.L2_cGERC_A_mn);
-
-        mBLAS.CGERC(alphaC, vectorXC, incX, vectorYC, incY, matrixAC);
-        verifyMatrix(matrixARef, matrixAC);
-
-        mRS.finish();
-        checkError();
-    }
-
-    public void test_L2_ZGERC_Correctness() {
-        int incX = 1;
-        int incY = 1;
-
-        // Populate input allocations
-        Allocation matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dM));
-        Allocation vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dM, 1));
-        Allocation vectorYZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, 1));
-        matrixAZ.copyFrom(mBLASData.L2_zGERC_A_mn);
-        vectorXZ.copyFrom(mBLASData.L2_zGERC_x_m1);
-        vectorYZ.copyFrom(mBLASData.L2_zGERC_y_n1);
-
-        // Test for the default case: NO_TRANS
-        mBLAS.ZGERC(alphaZ, vectorXZ, incX, vectorYZ, incY, matrixAZ);
-        Allocation matrixARef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dM));
-        matrixARef.copyFrom(mBLASData.L2_zGERC_o_N);
-        verifyMatrix(matrixARef, matrixAZ);
-
-        // Test for incX = 2 & incY = 3;
-        incX = 2;
-        incY = 3;
-        int dimX = 1 + (mBLASData.dM - 1) * incX;
-        int dimY = 1 + (mBLASData.dN - 1) * incY;
-        vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimX, 1));
-        vectorYZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimY, 1));
-        vectorXZ.copyFrom(mBLASData.L2_zGERC_x_m2);
-        vectorYZ.copyFrom(mBLASData.L2_zGERC_y_n2);
-        matrixAZ.copyFrom(mBLASData.L2_zGERC_A_mn);
-
-        mBLAS.ZGERC(alphaZ, vectorXZ, incX, vectorYZ, incY, matrixAZ);
-        verifyMatrix(matrixARef, matrixAZ);
-
-        mRS.finish();
-        checkError();
-    }
-
-
-    private void xHER_API_test(int Uplo, int incX, ArrayList<Allocation> mMatrix) {
-        for (Allocation matA : mMatrix) {
-            for (Allocation vecX : mMatrix) {
-                if (!validateVecInput(vecX)) {
-                    continue;
-                }
-                Element elemA = matA.getType().getElement();
-                if (validateSYR(elemA, Uplo, vecX, incX, matA)) {
-                    try {
-                        if (elemA.isCompatible(Element.F32_2(mRS))) {
-                            mBLAS.CHER(Uplo, alphaS, vecX, incX, matA);
-                        } else if (elemA.isCompatible(Element.F64_2(mRS))) {
-                            mBLAS.ZHER(Uplo, alphaD, vecX, incX, matA);
-                        }
-                    } catch (RSRuntimeException e) {
-                        fail("should NOT throw RSRuntimeException");
-                    }
-                } else {
-                    try {
-                        mBLAS.CHER(Uplo, alphaS, vecX, incX, matA);
-                        fail("should throw RSRuntimeException for CHER");
-                    } catch (RSRuntimeException e) {
-                    }
-                    try {
-                        mBLAS.ZHER(Uplo, alphaD, vecX, incX, matA);
-                        fail("should throw RSRuntimeException for ZHER");
-                    } catch (RSRuntimeException e) {
-                    }
-                }
-            }
-        }
-    }
-
-    public void L2_xHER_API(ArrayList<Allocation> mMatrix) {
-        for (int Uplo : mUplo) {
-            for (int incX : mInc) {
-                xHER_API_test(Uplo, incX, mMatrix);
-            }
-        }
-    }
-
-    public void test_L2_CHER_API() {
-        L2_xHER_API(mMatrixC);
-    }
-
-    public void test_L2_ZHER_API() {
-        L2_xHER_API(mMatrixZ);
-    }
-
-    public void test_L2_CHER_Correctness() {
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-        int incX = 1;
-
-        // Populate input allocations
-        Allocation matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dN));
-        Allocation vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, 1));
-        matrixAC.copyFrom(mBLASData.L2_cHER_A_nn);
-        vectorXC.copyFrom(mBLASData.L2_cHER_x_n1);
-
-        // Test for the default case: NO_TRANS
-        mBLAS.CHER(uplo, alphaS, vectorXC, incX, matrixAC);
-        Allocation matrixARef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dN));
-        matrixARef.copyFrom(mBLASData.L2_cHER_o_N);
-        verifyMatrix(matrixARef, matrixAC, true);
-
-        // Test for incX = 2;
-        incX = 2;
-        int dimX = 1 + (mBLASData.dN - 1) * incX;
-        vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimX, 1));
-        vectorXC.copyFrom(mBLASData.L2_cHER_x_n2);
-        matrixAC.copyFrom(mBLASData.L2_cHER_A_nn);
-
-        mBLAS.CHER(uplo, alphaS, vectorXC, incX, matrixAC);
-        verifyMatrix(matrixARef, matrixAC, true);
-
-        mRS.finish();
-        checkError();
-    }
-
-    public void test_L2_ZHER_Correctness() {
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-        int incX = 1;
-
-        // Populate input allocations
-        Allocation matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dN));
-        Allocation vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, 1));
-        matrixAZ.copyFrom(mBLASData.L2_zHER_A_nn);
-        vectorXZ.copyFrom(mBLASData.L2_zHER_x_n1);
-
-        // Test for the default case: NO_TRANS
-        mBLAS.ZHER(uplo, alphaD, vectorXZ, incX, matrixAZ);
-        Allocation matrixARef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dN));
-        matrixARef.copyFrom(mBLASData.L2_zHER_o_N);
-        verifyMatrix(matrixARef, matrixAZ, true);
-
-        // Test for incX = 2;
-        incX = 2;
-        int dimX = 1 + (mBLASData.dN - 1) * incX;
-        vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimX, 1));
-        vectorXZ.copyFrom(mBLASData.L2_zHER_x_n2);
-        matrixAZ.copyFrom(mBLASData.L2_zHER_A_nn);
-
-        mBLAS.ZHER(uplo, alphaD, vectorXZ, incX, matrixAZ);
-        verifyMatrix(matrixARef, matrixAZ, true);
-
-        mRS.finish();
-        checkError();
-    }
-
-
-    private void xHPR_API_test(int Uplo, int incX, ArrayList<Allocation> mMatrix) {
-        for (Allocation matA : mMatrix) {
-            for (Allocation vecX : mMatrix) {
-                if (!validateVecInput(vecX)) {
-                    continue;
-                }
-                Element elemA = matA.getType().getElement();
-                if (validateSPR(elemA, Uplo, vecX, incX, matA)) {
-                    try {
-                        if (elemA.isCompatible(Element.F32_2(mRS))) {
-                            mBLAS.CHPR(Uplo, alphaS, vecX, incX, matA);
-                        } else if (elemA.isCompatible(Element.F64_2(mRS))) {
-                            mBLAS.ZHPR(Uplo, alphaD, vecX, incX, matA);
-                        }
-                    } catch (RSRuntimeException e) {
-                        fail("should NOT throw RSRuntimeException");
-                    }
-                } else {
-                    try {
-                        mBLAS.CHPR(Uplo, alphaS, vecX, incX, matA);
-                        fail("should throw RSRuntimeException for CHPR");
-                    } catch (RSRuntimeException e) {
-                    }
-                    try {
-                        mBLAS.ZHPR(Uplo, alphaD, vecX, incX, matA);
-                        fail("should throw RSRuntimeException for ZHPR");
-                    } catch (RSRuntimeException e) {
-                    }
-                }
-            }
-        }
-    }
-
-    public void L2_xHPR_API(ArrayList<Allocation> mMatrix) {
-        for (int Uplo : mUplo) {
-            for (int incX : mInc) {
-                xHPR_API_test(Uplo, incX, mMatrix);
-            }
-        }
-    }
-
-    public void test_L2_CHPR_API() {
-        L2_xHPR_API(mMatrixC);
-    }
-
-    public void test_L2_ZHPR_API() {
-        L2_xHPR_API(mMatrixZ);
-    }
-
-    public void test_L2_CHPR_Correctness() {
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-        int incX = 1;
-
-        // Populate input allocations
-        int N = mBLASData.dN;
-        Allocation matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), N * (N+1) / 2, 1));
-        Allocation vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), N, 1));
-        matrixAC.copyFrom(mBLASData.L2_cHER_A_nn_pu);
-        vectorXC.copyFrom(mBLASData.L2_cHER_x_n1);
-
-        // Test for the default case: NO_TRANS
-        mBLAS.CHPR(uplo, alphaS, vectorXC, incX, matrixAC);
-        Allocation matrixARef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), N * (N+1) / 2, 1));
-        matrixARef.copyFrom(mBLASData.L2_cHER_o_N_pu);
-        verifyMatrix(matrixARef, matrixAC, true);
-
-        // Test for incX = 2;
-        incX = 2;
-        int dimX = 1 + (N - 1) * incX;
-        vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimX, 1));
-        vectorXC.copyFrom(mBLASData.L2_cHER_x_n2);
-        matrixAC.copyFrom(mBLASData.L2_cHER_A_nn_pu);
-
-        mBLAS.CHPR(uplo, alphaS, vectorXC, incX, matrixAC);
-        verifyMatrix(matrixARef, matrixAC, true);
-
-        mRS.finish();
-        checkError();
-    }
-
-    public void test_L2_ZHPR_Correctness() {
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-        int incX = 1;
-
-        // Populate input allocations
-        int N = mBLASData.dN;
-        Allocation matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), N * (N+1) / 2, 1));
-        Allocation vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), N, 1));
-        matrixAZ.copyFrom(mBLASData.L2_zHER_A_nn_pu);
-        vectorXZ.copyFrom(mBLASData.L2_zHER_x_n1);
-
-        // Test for the default case: NO_TRANS
-        mBLAS.ZHPR(uplo, alphaD, vectorXZ, incX, matrixAZ);
-        Allocation matrixARef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), N * (N+1) / 2, 1));
-        matrixARef.copyFrom(mBLASData.L2_zHER_o_N_pu);
-        verifyMatrix(matrixARef, matrixAZ, true);
-
-        // Test for incX = 2;
-        incX = 2;
-        int dimX = 1 + (N - 1) * incX;
-        vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimX, 1));
-        vectorXZ.copyFrom(mBLASData.L2_zHER_x_n2);
-        matrixAZ.copyFrom(mBLASData.L2_zHER_A_nn_pu);
-
-        mBLAS.ZHPR(uplo, alphaD, vectorXZ, incX, matrixAZ);
-        verifyMatrix(matrixARef, matrixAZ, true);
-
-        mRS.finish();
-        checkError();
-    }
-
-
-    private void xHER2_API_test(int Uplo, int incX, int incY, ArrayList<Allocation> mMatrix) {
-        for (Allocation matA : mMatrix) {
-            for (Allocation vecX : mMatrix) {
-                if (!validateVecInput(vecX)) {
-                    continue;
-                }
-                for (Allocation vecY : mMatrix) {
-                    if (!validateVecInput(vecY)) {
-                        continue;
-                    }
-                    Element elemA = matA.getType().getElement();
-                    if (validateSYR2(elemA, Uplo, vecX, incX, vecY, incY, matA)) {
-                        try {
-                            if (elemA.isCompatible(Element.F32_2(mRS))) {
-                                mBLAS.CHER2(Uplo, alphaC, vecX, incX, vecY, incY, matA);
-                            } else if (elemA.isCompatible(Element.F64_2(mRS))) {
-                                mBLAS.ZHER2(Uplo, alphaZ, vecX, incX, vecY, incY, matA);
-                            }
-                        } catch (RSRuntimeException e) {
-                            fail("should NOT throw RSRuntimeException");
-                        }
-                    } else {
-                        try {
-                            mBLAS.CHER2(Uplo, alphaC, vecX, incX, vecY, incY, matA);
-                            fail("should throw RSRuntimeException for CHER2");
-                        } catch (RSRuntimeException e) {
-                        }
-                        try {
-                            mBLAS.ZHER2(Uplo, alphaZ, vecX, incX, vecY, incY, matA);
-                            fail("should throw RSRuntimeException for ZHER2");
-                        } catch (RSRuntimeException e) {
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    public void L2_xHER2_API(ArrayList<Allocation> mMatrix) {
-        for (int Uplo : mUplo) {
-            for (int incX : mInc) {
-                xHER2_API_test(Uplo, incX, incX, mMatrix);
-            }
-        }
-    }
-
-    public void test_L2_CHER2_API() {
-        L2_xHER2_API(mMatrixC);
-    }
-
-    public void test_L2_ZHER2_API() {
-        L2_xHER2_API(mMatrixZ);
-    }
-
-    public void test_L2_CHER2_Correctness() {
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-        int incX = 1;
-        int incY = 1;
-
-        // Populate input allocations
-        Allocation matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dN));
-        Allocation vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, 1));
-        Allocation vectorYC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, 1));
-        matrixAC.copyFrom(mBLASData.L2_cHER2_A_nn);
-        vectorXC.copyFrom(mBLASData.L2_cHER2_x_n1);
-        vectorYC.copyFrom(mBLASData.L2_cHER2_y_n1);
-
-        // Test for the default case: NO_TRANS
-        mBLAS.CHER2(uplo, alphaC, vectorXC, incX, vectorYC, incY, matrixAC);
-        Allocation matrixARef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dN));
-        matrixARef.copyFrom(mBLASData.L2_cHER2_o_N);
-        verifyMatrix(matrixARef, matrixAC, true);
-
-        // Test for incX = 2 & incY = 3;
-        incX = 2;
-        incY = 3;
-        int dimX = 1 + (mBLASData.dN - 1) * incX;
-        int dimY = 1 + (mBLASData.dN - 1) * incY;
-        vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimX, 1));
-        vectorYC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimY, 1));
-        vectorXC.copyFrom(mBLASData.L2_cHER2_x_n2);
-        vectorYC.copyFrom(mBLASData.L2_cHER2_y_n2);
-        matrixAC.copyFrom(mBLASData.L2_cHER2_A_nn);
-
-        mBLAS.CHER2(uplo, alphaC, vectorXC, incX, vectorYC, incY, matrixAC);
-        verifyMatrix(matrixARef, matrixAC, true);
-
-        mRS.finish();
-        checkError();
-    }
-
-    public void test_L2_ZHER2_Correctness() {
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-        int incX = 1;
-        int incY = 1;
-
-        // Populate input allocations
-        Allocation matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dN));
-        Allocation vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, 1));
-        Allocation vectorYZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, 1));
-        matrixAZ.copyFrom(mBLASData.L2_zHER2_A_nn);
-        vectorXZ.copyFrom(mBLASData.L2_zHER2_x_n1);
-        vectorYZ.copyFrom(mBLASData.L2_zHER2_y_n1);
-
-        // Test for the default case: NO_TRANS
-        mBLAS.ZHER2(uplo, alphaZ, vectorXZ, incX, vectorYZ, incY, matrixAZ);
-        Allocation matrixARef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dN));
-        matrixARef.copyFrom(mBLASData.L2_zHER2_o_N);
-        verifyMatrix(matrixARef, matrixAZ, true);
-
-        // Test for incX = 2 & incY = 3;
-        incX = 2;
-        incY = 3;
-        int dimX = 1 + (mBLASData.dN - 1) * incX;
-        int dimY = 1 + (mBLASData.dN - 1) * incY;
-        vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimX, 1));
-        vectorYZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimY, 1));
-        vectorXZ.copyFrom(mBLASData.L2_zHER2_x_n2);
-        vectorYZ.copyFrom(mBLASData.L2_zHER2_y_n2);
-        matrixAZ.copyFrom(mBLASData.L2_zHER2_A_nn);
-
-        mBLAS.ZHER2(uplo, alphaZ, vectorXZ, incX, vectorYZ, incY, matrixAZ);
-        verifyMatrix(matrixARef, matrixAZ, true);
-
-        mRS.finish();
-        checkError();
-    }
-
-
-
-    private void xHPR2_API_test(int Uplo, int incX, int incY, ArrayList<Allocation> mMatrix) {
-        for (Allocation matA : mMatrix) {
-            for (Allocation vecX : mMatrix) {
-                if (!validateVecInput(vecX)) {
-                    continue;
-                }
-                for (Allocation vecY : mMatrix) {
-                    if (!validateVecInput(vecY)) {
-                        continue;
-                    }
-                    Element elemA = matA.getType().getElement();
-                    if (validateSPR2(elemA, Uplo, vecX, incX, vecY, incY, matA)) {
-                        try {
-                            if (elemA.isCompatible(Element.F32_2(mRS))) {
-                                mBLAS.CHPR2(Uplo, alphaC, vecX, incX, vecY, incY, matA);
-                            } else if (elemA.isCompatible(Element.F64_2(mRS))) {
-                                mBLAS.ZHPR2(Uplo, alphaZ, vecX, incX, vecY, incY, matA);
-                            }
-                        } catch (RSRuntimeException e) {
-                            fail("should NOT throw RSRuntimeException");
-                        }
-                    } else {
-                        try {
-                            mBLAS.CHPR2(Uplo, alphaC, vecX, incX, vecY, incY, matA);
-                            fail("should throw RSRuntimeException for CHPR2");
-                        } catch (RSRuntimeException e) {
-                        }
-                        try {
-                            mBLAS.ZHPR2(Uplo, alphaZ, vecX, incX, vecY, incY, matA);
-                            fail("should throw RSRuntimeException for ZHPR2");
-                        } catch (RSRuntimeException e) {
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    public void L2_xHPR2_API(ArrayList<Allocation> mMatrix) {
-        for (int Uplo : mUplo) {
-            for (int incX : mInc) {
-                xHPR2_API_test(Uplo, incX, incX, mMatrix);
-            }
-        }
-    }
-
-    public void test_L2_CHPR2_API() {
-        L2_xHPR2_API(mMatrixC);
-    }
-
-    public void test_L2_ZHPR2_API() {
-        L2_xHPR2_API(mMatrixZ);
-    }
-
-    public void test_L2_CHPR2_Correctness() {
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-        int incX = 1;
-        int incY = 1;
-
-        // Populate input allocations
-        int N = mBLASData.dN;
-        Allocation matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), N * (N+1) / 2, 1));
-        Allocation vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), N, 1));
-        Allocation vectorYC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), N, 1));
-        matrixAC.copyFrom(mBLASData.L2_cHER2_A_nn_pu);
-        vectorXC.copyFrom(mBLASData.L2_cHER2_x_n1);
-        vectorYC.copyFrom(mBLASData.L2_cHER2_y_n1);
-
-        // Test for the default case: NO_TRANS
-        mBLAS.CHPR2(uplo, alphaC, vectorXC, incX, vectorYC, incY, matrixAC);
-        Allocation matrixARef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), N * (N+1) / 2, 1));
-        matrixARef.copyFrom(mBLASData.L2_cHER2_o_N_pu);
-        verifyMatrix(matrixARef, matrixAC, true);
-
-        // Test for incX = 2 & incY = 3;
-        incX = 2;
-        incY = 3;
-        int dimX = 1 + (N - 1) * incX;
-        int dimY = 1 + (N - 1) * incY;
-        vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimX, 1));
-        vectorYC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimY, 1));
-        vectorXC.copyFrom(mBLASData.L2_cHER2_x_n2);
-        vectorYC.copyFrom(mBLASData.L2_cHER2_y_n2);
-        matrixAC.copyFrom(mBLASData.L2_cHER2_A_nn_pu);
-
-        mBLAS.CHPR2(uplo, alphaC, vectorXC, incX, vectorYC, incY, matrixAC);
-        verifyMatrix(matrixARef, matrixAC, true);
-
-        mRS.finish();
-        checkError();
-    }
-
-    public void test_L2_ZHPR2_Correctness() {
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-        int incX = 1;
-        int incY = 1;
-
-        // Populate input allocations
-        int N = mBLASData.dN;
-        Allocation matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), N * (N+1) / 2, 1));
-        Allocation vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), N, 1));
-        Allocation vectorYZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), N, 1));
-        matrixAZ.copyFrom(mBLASData.L2_zHER2_A_nn_pu);
-        vectorXZ.copyFrom(mBLASData.L2_zHER2_x_n1);
-        vectorYZ.copyFrom(mBLASData.L2_zHER2_y_n1);
-
-        // Test for the default case: NO_TRANS
-        mBLAS.ZHPR2(uplo, alphaZ, vectorXZ, incX, vectorYZ, incY, matrixAZ);
-        Allocation matrixARef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), N * (N+1) / 2, 1));
-        matrixARef.copyFrom(mBLASData.L2_zHER2_o_N_pu);
-        verifyMatrix(matrixARef, matrixAZ, true);
-
-        // Test for incX = 2 & incY = 3;
-        incX = 2;
-        incY = 3;
-        int dimX = 1 + (N - 1) * incX;
-        int dimY = 1 + (N - 1) * incY;
-        vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimX, 1));
-        vectorYZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimY, 1));
-        vectorXZ.copyFrom(mBLASData.L2_zHER2_x_n2);
-        vectorYZ.copyFrom(mBLASData.L2_zHER2_y_n2);
-        matrixAZ.copyFrom(mBLASData.L2_zHER2_A_nn_pu);
-
-        mBLAS.ZHPR2(uplo, alphaZ, vectorXZ, incX, vectorYZ, incY, matrixAZ);
-        verifyMatrix(matrixARef, matrixAZ, true);
-
-        mRS.finish();
-        checkError();
-    }
-
-
-
-    private boolean validateSYR(Element e, int Uplo, Allocation X, int incX, Allocation A) {
-        if (!validateUplo(Uplo)) {
-            return false;
-        }
-        if (!A.getType().getElement().isCompatible(e) ||
-            !X.getType().getElement().isCompatible(e)) {
-            return false;
-        }
-
-        int N = A.getType().getX();
-
-        if (X.getType().getY() > 1) {
-            return false;
-        }
-        if (N != A.getType().getY()) {
-            return false;
-        }
-        if (incX <= 0) {
-            return false;
-        }
-        int expectedXDim = 1 + (N - 1) * incX;
-        if (X.getType().getX() != expectedXDim) {
-            return false;
-        }
-        return true;
-    }
-
-    private void xSYR_API_test(int Uplo, int incX, ArrayList<Allocation> mMatrix) {
-        for (Allocation matA : mMatrix) {
-            for (Allocation vecX : mMatrix) {
-                if (!validateVecInput(vecX)) {
-                    continue;
-                }
-                Element elemA = matA.getType().getElement();
-                if (validateSYR(elemA, Uplo, vecX, incX, matA)) {
-                    try {
-                        if (elemA.isCompatible(Element.F32(mRS))) {
-                            mBLAS.SSYR(Uplo, alphaS, vecX, incX, matA);
-                        } else if (elemA.isCompatible(Element.F64(mRS))) {
-                            mBLAS.DSYR(Uplo, alphaD, vecX, incX, matA);
-                        }
-                    } catch (RSRuntimeException e) {
-                        fail("should NOT throw RSRuntimeException");
-                    }
-                } else {
-                    try {
-                        mBLAS.SSYR(Uplo, alphaS, vecX, incX, matA);
-                        fail("should throw RSRuntimeException for SSYR");
-                    } catch (RSRuntimeException e) {
-                    }
-                    try {
-                        mBLAS.DSYR(Uplo, alphaD, vecX, incX, matA);
-                        fail("should throw RSRuntimeException for DSYR");
-                    } catch (RSRuntimeException e) {
-                    }
-                }
-            }
-        }
-    }
-
-    public void L2_xSYR_API(ArrayList<Allocation> mMatrix) {
-        for (int Uplo : mUplo) {
-            for (int incX : mInc) {
-                xSYR_API_test(Uplo, incX, mMatrix);
-            }
-        }
-    }
-
-    public void test_L2_SSYR_API() {
-        L2_xSYR_API(mMatrixS);
-    }
-
-    public void test_L2_DSYR_API() {
-        L2_xSYR_API(mMatrixD);
-    }
-
-    public void test_L2_SSYR_Correctness() {
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-        int incX = 1;
-
-        // Populate input allocations
-        Allocation matrixAS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dN));
-        Allocation vectorXS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, 1));
-        matrixAS.copyFrom(mBLASData.L2_sSYR_A_nn);
-        vectorXS.copyFrom(mBLASData.L2_sSYR_x_n1);
-
-        // Test for the default case: NO_TRANS
-        mBLAS.SSYR(uplo, alphaS, vectorXS, incX, matrixAS);
-        Allocation matrixARef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dN));
-        matrixARef.copyFrom(mBLASData.L2_sSYR_o_N);
-        verifyMatrix(matrixARef, matrixAS, true);
-
-        // Test for incX = 2;
-        incX = 2;
-        int dimX = 1 + (mBLASData.dN - 1) * incX;
-        vectorXS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimX, 1));
-        vectorXS.copyFrom(mBLASData.L2_sSYR_x_n2);
-        matrixAS.copyFrom(mBLASData.L2_sSYR_A_nn);
-
-        mBLAS.SSYR(uplo, alphaS, vectorXS, incX, matrixAS);
-        verifyMatrix(matrixARef, matrixAS, true);
-
-        mRS.finish();
-        checkError();
-    }
-
-    public void test_L2_DSYR_Correctness() {
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-        int incX = 1;
-
-        // Populate input allocations
-        Allocation matrixAD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dN));
-        Allocation vectorXD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, 1));
-        matrixAD.copyFrom(mBLASData.L2_dSYR_A_nn);
-        vectorXD.copyFrom(mBLASData.L2_dSYR_x_n1);
-
-        // Test for the default case: NO_TRANS
-        mBLAS.DSYR(uplo, alphaD, vectorXD, incX, matrixAD);
-        Allocation matrixARef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dN));
-        matrixARef.copyFrom(mBLASData.L2_dSYR_o_N);
-        verifyMatrix(matrixARef, matrixAD, true);
-
-        // Test for incX = 2;
-        incX = 2;
-        int dimX = 1 + (mBLASData.dN - 1) * incX;
-        vectorXD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimX, 1));
-        vectorXD.copyFrom(mBLASData.L2_dSYR_x_n2);
-        matrixAD.copyFrom(mBLASData.L2_dSYR_A_nn);
-
-        mBLAS.DSYR(uplo, alphaD, vectorXD, incX, matrixAD);
-        verifyMatrix(matrixARef, matrixAD, true);
-
-        mRS.finish();
-        checkError();
-    }
-
-
-    private boolean validateSPR(Element e, int Uplo, Allocation X, int incX, Allocation Ap) {
-        if (!validateUplo(Uplo)) {
-            return false;
-        }
-        if (!Ap.getType().getElement().isCompatible(e) ||
-            !X.getType().getElement().isCompatible(e)) {
-            return false;
-        }
-        if (X.getType().getY() > 1) {
-            return false;
-        }
-
-        if (Ap.getType().getY() > 1) {
-            return false;
-        }
-
-        int N = (int)Math.sqrt((double)Ap.getType().getX() * 2);
-        if (Ap.getType().getX() != ((N * (N+1)) / 2)) {
-            return false;
-        }
-        if (incX <= 0) {
-            return false;
-        }
-        int expectedXDim = 1 + (N - 1) * incX;
-        if (X.getType().getX() != expectedXDim) {
-            return false;
-        }
-
-        return true;
-    }
-
-    private void xSPR_API_test(int Uplo, int incX, ArrayList<Allocation> mMatrix) {
-        for (Allocation matA : mMatrix) {
-            for (Allocation vecX : mMatrix) {
-                if (!validateVecInput(vecX)) {
-                    continue;
-                }
-                Element elemA = matA.getType().getElement();
-                if (validateSPR(elemA, Uplo, vecX, incX, matA)) {
-                    try {
-                        if (elemA.isCompatible(Element.F32(mRS))) {
-                            mBLAS.SSPR(Uplo, alphaS, vecX, incX, matA);
-                        } else if (elemA.isCompatible(Element.F64(mRS))) {
-                            mBLAS.DSPR(Uplo, alphaD, vecX, incX, matA);
-                        }
-                    } catch (RSRuntimeException e) {
-                        fail("should NOT throw RSRuntimeException");
-                    }
-                } else {
-                    try {
-                        mBLAS.SSPR(Uplo, alphaS, vecX, incX, matA);
-                        fail("should throw RSRuntimeException for SSPR");
-                    } catch (RSRuntimeException e) {
-                    }
-                    try {
-                        mBLAS.DSPR(Uplo, alphaD, vecX, incX, matA);
-                        fail("should throw RSRuntimeException for DSPR");
-                    } catch (RSRuntimeException e) {
-                    }
-                }
-            }
-        }
-    }
-
-    public void L2_xSPR_API(ArrayList<Allocation> mMatrix) {
-        for (int Uplo : mUplo) {
-            for (int incX : mInc) {
-                xSPR_API_test(Uplo, incX, mMatrix);
-            }
-        }
-    }
-
-    public void test_L2_SSPR_API() {
-        L2_xSPR_API(mMatrixS);
-    }
-
-    public void test_L2_DSPR_API() {
-        L2_xSPR_API(mMatrixD);
-    }
-
-    public void test_L2_SSPR_Correctness() {
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-        int incX = 1;
-
-        // Populate input allocations
-        int N = mBLASData.dN;
-        Allocation matrixAS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), N * (N+1) / 2, 1));
-        Allocation vectorXS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), N, 1));
-        matrixAS.copyFrom(mBLASData.L2_sSYR_A_nn_pu);
-        vectorXS.copyFrom(mBLASData.L2_sSYR_x_n1);
-
-        // Test for the default case: NO_TRANS
-        mBLAS.SSPR(uplo, alphaS, vectorXS, incX, matrixAS);
-        Allocation matrixARef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), N * (N+1) / 2, 1));
-        matrixARef.copyFrom(mBLASData.L2_sSYR_o_N_pu);
-        verifyMatrix(matrixARef, matrixAS, true);
-
-        // Test for incX = 2;
-        incX = 2;
-        int dimX = 1 + (N - 1) * incX;
-        vectorXS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimX, 1));
-        vectorXS.copyFrom(mBLASData.L2_sSYR_x_n2);
-        matrixAS.copyFrom(mBLASData.L2_sSYR_A_nn_pu);
-
-        mBLAS.SSPR(uplo, alphaS, vectorXS, incX, matrixAS);
-        verifyMatrix(matrixARef, matrixAS, true);
-
-        mRS.finish();
-        checkError();
-    }
-
-    public void test_L2_DSPR_Correctness() {
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-        int incX = 1;
-
-        // Populate input allocations
-        int N = mBLASData.dN;
-        Allocation matrixAD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), N * (N+1) / 2, 1));
-        Allocation vectorXD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), N, 1));
-        matrixAD.copyFrom(mBLASData.L2_dSYR_A_nn_pu);
-        vectorXD.copyFrom(mBLASData.L2_dSYR_x_n1);
-
-        // Test for the default case: NO_TRANS
-        mBLAS.DSPR(uplo, alphaD, vectorXD, incX, matrixAD);
-        Allocation matrixARef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), N * (N+1) / 2, 1));
-        matrixARef.copyFrom(mBLASData.L2_dSYR_o_N_pu);
-        verifyMatrix(matrixARef, matrixAD, true);
-
-        // Test for incX = 2;
-        incX = 2;
-        int dimX = 1 + (N - 1) * incX;
-        vectorXD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimX, 1));
-        vectorXD.copyFrom(mBLASData.L2_dSYR_x_n2);
-        matrixAD.copyFrom(mBLASData.L2_dSYR_A_nn_pu);
-
-        mBLAS.DSPR(uplo, alphaD, vectorXD, incX, matrixAD);
-        verifyMatrix(matrixARef, matrixAD, true);
-
-        mRS.finish();
-        checkError();
-    }
-
-
-    private boolean validateSYR2(Element e, int Uplo, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
-        if (!validateUplo(Uplo)) {
-            return false;
-        }
-        if (!A.getType().getElement().isCompatible(e) ||
-            !X.getType().getElement().isCompatible(e) ||
-            !Y.getType().getElement().isCompatible(e)) {
-            return false;
-        }
-
-        if (X.getType().getY() > 1 || Y.getType().getY() > 1) {
-            return false;
-        }
-
-        int N = A.getType().getX();
-
-        if (N != A.getType().getY()) {
-            return false;
-        }
-        if (incX <= 0 || incY <= 0) {
-            return false;
-        }
-        int expectedXDim = 1 + (N - 1) * incX;
-        int expectedYDim = 1 + (N - 1) * incY;
-        if (X.getType().getX() != expectedXDim || Y.getType().getX() != expectedYDim) {
-            return false;
-        }
-        return true;
-    }
-
-    private void xSYR2_API_test(int Uplo, int incX, int incY, ArrayList<Allocation> mMatrix) {
-        for (Allocation matA : mMatrix) {
-            for (Allocation vecX : mMatrix) {
-                if (!validateVecInput(vecX)) {
-                    continue;
-                }
-                for (Allocation vecY : mMatrix) {
-                    if (!validateVecInput(vecY)) {
-                        continue;
-                    }
-                    Element elemA = matA.getType().getElement();
-                    if (validateSYR2(elemA, Uplo, vecX, incX, vecY, incY, matA)) {
-                        try {
-                            if (elemA.isCompatible(Element.F32(mRS))) {
-                                mBLAS.SSYR2(Uplo, alphaS, vecX, incX, vecY, incY, matA);
-                            } else if (elemA.isCompatible(Element.F64(mRS))) {
-                                mBLAS.DSYR2(Uplo, alphaD, vecX, incX, vecY, incY, matA);
-                            }
-                        } catch (RSRuntimeException e) {
-                            fail("should NOT throw RSRuntimeException");
-                        }
-                    } else {
-                        try {
-                            mBLAS.SSYR2(Uplo, alphaS, vecX, incX, vecY, incY, matA);
-                            fail("should throw RSRuntimeException for SSYR2");
-                        } catch (RSRuntimeException e) {
-                        }
-                        try {
-                            mBLAS.DSYR2(Uplo, alphaD, vecX, incX, vecY, incY, matA);
-                            fail("should throw RSRuntimeException for DSYR2");
-                        } catch (RSRuntimeException e) {
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    public void L2_xSYR2_API(ArrayList<Allocation> mMatrix) {
-        for (int Uplo : mUplo) {
-            for (int incX : mInc) {
-                xSYR2_API_test(Uplo, incX, incX, mMatrix);
-            }
-        }
-    }
-
-    public void test_L2_SSYR2_API() {
-        L2_xSYR2_API(mMatrixS);
-    }
-
-    public void test_L2_DSYR2_API() {
-        L2_xSYR2_API(mMatrixD);
-    }
-
-    public void test_L2_SSYR2_Correctness() {
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-        int incX = 1;
-        int incY = 1;
-
-        // Populate input allocations
-        Allocation matrixAS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dN));
-        Allocation vectorXS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, 1));
-        Allocation vectorYS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, 1));
-        matrixAS.copyFrom(mBLASData.L2_sSYR2_A_nn);
-        vectorXS.copyFrom(mBLASData.L2_sSYR2_x_n1);
-        vectorYS.copyFrom(mBLASData.L2_sSYR2_y_n1);
-
-        // Test for the default case: NO_TRANS
-        mBLAS.SSYR2(uplo, alphaS, vectorXS, incX, vectorYS, incY, matrixAS);
-        Allocation matrixARef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dN));
-        matrixARef.copyFrom(mBLASData.L2_sSYR2_o_N);
-        verifyMatrix(matrixARef, matrixAS, true);
-
-        // Test for incX = 2 & incY = 3;
-        incX = 2;
-        incY = 3;
-        int dimX = 1 + (mBLASData.dN - 1) * incX;
-        int dimY = 1 + (mBLASData.dN - 1) * incY;
-        vectorXS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimX, 1));
-        vectorYS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimY, 1));
-        vectorXS.copyFrom(mBLASData.L2_sSYR2_x_n2);
-        vectorYS.copyFrom(mBLASData.L2_sSYR2_y_n2);
-        matrixAS.copyFrom(mBLASData.L2_sSYR2_A_nn);
-
-        mBLAS.SSYR2(uplo, alphaS, vectorXS, incX, vectorYS, incY, matrixAS);
-        verifyMatrix(matrixARef, matrixAS, true);
-
-        mRS.finish();
-        checkError();
-    }
-
-    public void test_L2_DSYR2_Correctness() {
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-        int incX = 1;
-        int incY = 1;
-
-        // Populate input allocations
-        Allocation matrixAD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dN));
-        Allocation vectorXD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, 1));
-        Allocation vectorYD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, 1));
-        matrixAD.copyFrom(mBLASData.L2_dSYR2_A_nn);
-        vectorXD.copyFrom(mBLASData.L2_dSYR2_x_n1);
-        vectorYD.copyFrom(mBLASData.L2_dSYR2_y_n1);
-
-        // Test for the default case: NO_TRANS
-        mBLAS.DSYR2(uplo, alphaD, vectorXD, incX, vectorYD, incY, matrixAD);
-        Allocation matrixARef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dN));
-        matrixARef.copyFrom(mBLASData.L2_dSYR2_o_N);
-        verifyMatrix(matrixARef, matrixAD, true);
-
-        // Test for incX = 2 & incY = 3;
-        incX = 2;
-        incY = 3;
-        int dimX = 1 + (mBLASData.dN - 1) * incX;
-        int dimY = 1 + (mBLASData.dN - 1) * incY;
-        vectorXD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimX, 1));
-        vectorYD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimY, 1));
-        vectorXD.copyFrom(mBLASData.L2_dSYR2_x_n2);
-        vectorYD.copyFrom(mBLASData.L2_dSYR2_y_n2);
-        matrixAD.copyFrom(mBLASData.L2_dSYR2_A_nn);
-
-        mBLAS.DSYR2(uplo, alphaD, vectorXD, incX, vectorYD, incY, matrixAD);
-        verifyMatrix(matrixARef, matrixAD, true);
-
-        mRS.finish();
-        checkError();
-    }
-
-
-    private boolean validateSPR2(Element e, int Uplo, Allocation X, int incX, Allocation Y, int incY, Allocation Ap) {
-        if (!validateUplo(Uplo)) {
-            return false;
-        }
-        if (!Ap.getType().getElement().isCompatible(e) ||
-            !X.getType().getElement().isCompatible(e) ||
-            !Y.getType().getElement().isCompatible(e)) {
-            return false;
-        }
-        if (X.getType().getY() > 1 || Y.getType().getY() > 1) {
-            return false;
-        }
-
-        if (Ap.getType().getY() > 1) {
-            return false;
-        }
-
-        int N = (int)Math.sqrt((double)Ap.getType().getX() * 2);
-        if (Ap.getType().getX() != ((N * (N+1)) / 2)) {
-            return false;
-        }
-        if (incX <= 0 || incY <= 0) {
-            return false;
-        }
-        int expectedXDim = 1 + (N - 1) * incX;
-        int expectedYDim = 1 + (N - 1) * incY;
-        if (X.getType().getX() != expectedXDim || Y.getType().getX() != expectedYDim) {
-            return false;
-        }
-
-        return true;
-    }
-
-    private void xSPR2_API_test(int Uplo, int incX, int incY, ArrayList<Allocation> mMatrix) {
-        for (Allocation matA : mMatrix) {
-            for (Allocation vecX : mMatrix) {
-                if (!validateVecInput(vecX)) {
-                    continue;
-                }
-                for (Allocation vecY : mMatrix) {
-                    if (!validateVecInput(vecY)) {
-                        continue;
-                    }
-                    Element elemA = matA.getType().getElement();
-                    if (validateSPR2(elemA, Uplo, vecX, incX, vecY, incY, matA)) {
-                        try {
-                            if (elemA.isCompatible(Element.F32(mRS))) {
-                                mBLAS.SSPR2(Uplo, alphaS, vecX, incX, vecY, incY, matA);
-                            } else if (elemA.isCompatible(Element.F64(mRS))) {
-                                mBLAS.DSPR2(Uplo, alphaD, vecX, incX, vecY, incY, matA);
-                            }
-                        } catch (RSRuntimeException e) {
-                            fail("should NOT throw RSRuntimeException");
-                        }
-                    } else {
-                        try {
-                            mBLAS.SSPR2(Uplo, alphaS, vecX, incX, vecY, incY, matA);
-                            fail("should throw RSRuntimeException for SSPR2");
-                        } catch (RSRuntimeException e) {
-                        }
-                        try {
-                            mBLAS.DSPR2(Uplo, alphaD, vecX, incX, vecY, incY, matA);
-                            fail("should throw RSRuntimeException for DSPR2");
-                        } catch (RSRuntimeException e) {
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    public void L2_xSPR2_API(ArrayList<Allocation> mMatrix) {
-        for (int Uplo : mUplo) {
-            for (int incX : mInc) {
-                xSPR2_API_test(Uplo, incX, incX, mMatrix);
-            }
-        }
-    }
-
-    public void test_L2_SSPR2_API() {
-        L2_xSPR2_API(mMatrixS);
-    }
-
-    public void test_L2_DSPR2_API() {
-        L2_xSPR2_API(mMatrixD);
-    }
-
-    public void test_L2_SSPR2_Correctness() {
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-        int incX = 1;
-        int incY = 1;
-
-        // Populate input allocations
-        int N = mBLASData.dN;
-        Allocation matrixAS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), N * (N+1) / 2, 1));
-        Allocation vectorXS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), N, 1));
-        Allocation vectorYS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), N, 1));
-        matrixAS.copyFrom(mBLASData.L2_sSYR2_A_nn_pu);
-        vectorXS.copyFrom(mBLASData.L2_sSYR2_x_n1);
-        vectorYS.copyFrom(mBLASData.L2_sSYR2_y_n1);
-
-        // Test for the default case: NO_TRANS
-        mBLAS.SSPR2(uplo, alphaS, vectorXS, incX, vectorYS, incY, matrixAS);
-        Allocation matrixARef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), N * (N+1) / 2, 1));
-        matrixARef.copyFrom(mBLASData.L2_sSYR2_o_N_pu);
-        verifyMatrix(matrixARef, matrixAS, true);
-
-        // Test for incX = 2 & incY = 3;
-        incX = 2;
-        incY = 3;
-        int dimX = 1 + (N - 1) * incX;
-        int dimY = 1 + (N - 1) * incY;
-        vectorXS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimX, 1));
-        vectorYS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimY, 1));
-        vectorXS.copyFrom(mBLASData.L2_sSYR2_x_n2);
-        vectorYS.copyFrom(mBLASData.L2_sSYR2_y_n2);
-        matrixAS.copyFrom(mBLASData.L2_sSYR2_A_nn_pu);
-
-        mBLAS.SSPR2(uplo, alphaS, vectorXS, incX, vectorYS, incY, matrixAS);
-        verifyMatrix(matrixARef, matrixAS, true);
-
-        mRS.finish();
-        checkError();
-    }
-
-    public void test_L2_DSPR2_Correctness() {
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-        int incX = 1;
-        int incY = 1;
-
-        // Populate input allocations
-        int N = mBLASData.dN;
-        Allocation matrixAD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), N * (N+1) / 2, 1));
-        Allocation vectorXD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), N, 1));
-        Allocation vectorYD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), N, 1));
-        matrixAD.copyFrom(mBLASData.L2_dSYR2_A_nn_pu);
-        vectorXD.copyFrom(mBLASData.L2_dSYR2_x_n1);
-        vectorYD.copyFrom(mBLASData.L2_dSYR2_y_n1);
-
-        // Test for the default case: NO_TRANS
-        mBLAS.DSPR2(uplo, alphaD, vectorXD, incX, vectorYD, incY, matrixAD);
-        Allocation matrixARef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), N * (N+1) / 2, 1));
-        matrixARef.copyFrom(mBLASData.L2_dSYR2_o_N_pu);
-        verifyMatrix(matrixARef, matrixAD, true);
-
-        // Test for incX = 2 & incY = 3;
-        incX = 2;
-        incY = 3;
-        int dimX = 1 + (N - 1) * incX;
-        int dimY = 1 + (N - 1) * incY;
-        vectorXD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimX, 1));
-        vectorYD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimY, 1));
-        vectorXD.copyFrom(mBLASData.L2_dSYR2_x_n2);
-        vectorYD.copyFrom(mBLASData.L2_dSYR2_y_n2);
-        matrixAD.copyFrom(mBLASData.L2_dSYR2_A_nn_pu);
-
-        mBLAS.DSPR2(uplo, alphaD, vectorXD, incX, vectorYD, incY, matrixAD);
-        verifyMatrix(matrixARef, matrixAD, true);
-
-        mRS.finish();
-        checkError();
-    }
-
-
-
-    private boolean validateL3(Element e, int TransA, int TransB, int Side, Allocation A, Allocation B, Allocation C) {
-        int aM = -1, aN = -1, bM = -1, bN = -1, cM = -1, cN = -1;
-        if ((A != null && !A.getType().getElement().isCompatible(e)) ||
-            (B != null && !B.getType().getElement().isCompatible(e)) ||
-            (C != null && !C.getType().getElement().isCompatible(e))) {
-            return false;
-        }
-        if (C == null) {
-            //since matrix C is used to store the result, it cannot be null.
-            return false;
-        }
-        cM = C.getType().getY();
-        cN = C.getType().getX();
-
-        if (Side == ScriptIntrinsicBLAS.RIGHT) {
-            if ((A == null && B != null) || (A != null && B == null)) {
-                return false;
-            }
-            if (B != null) {
-                bM = A.getType().getY();
-                bN = A.getType().getX();
-            }
-            if (A != null) {
-                aM = B.getType().getY();
-                aN = B.getType().getX();
-            }
-        } else {
-            if (A != null) {
-                if (TransA == ScriptIntrinsicBLAS.TRANSPOSE ||
-                    TransA == ScriptIntrinsicBLAS.CONJ_TRANSPOSE ) {
-                    aN = A.getType().getY();
-                    aM = A.getType().getX();
-                } else {
-                    aM = A.getType().getY();
-                    aN = A.getType().getX();
-                }
-            }
-            if (B != null) {
-                if (TransB == ScriptIntrinsicBLAS.TRANSPOSE ||
-                    TransB == ScriptIntrinsicBLAS.CONJ_TRANSPOSE ) {
-                    bN = B.getType().getY();
-                    bM = B.getType().getX();
-                } else {
-                    bM = B.getType().getY();
-                    bN = B.getType().getX();
-                }
-            }
-        }
-        if (A != null && B != null && C != null) {
-            if (aN != bM || aM != cM || bN != cN) {
-                return false;
-            }
-        } else if (A != null && C != null) {
-            // A and C only, for SYRK
-            if (cM != cN) {
-                return false;
-            }
-            if (aM != cM) {
-                return false;
-            }
-        } else if (A != null && B != null) {
-            // A and B only
-            if (aN != bM) {
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    private boolean validateL3_xGEMM(Element e, int TransA, int TransB, Allocation A, Allocation B, Allocation C) {
-        boolean result = true;
-        result &= validateTranspose(TransA);
-        result &= validateTranspose(TransB);
-        result &= validateL3(e, TransA, TransB, 0, A, B, C);
-
-        return result;
-    }
-
-    private void xGEMM_API_test(int transA, int transB, ArrayList<Allocation> mMatrix) {
-        for (Allocation matA : mMatrix) {
-            for (Allocation matB : mMatrix) {
-                for (Allocation matC : mMatrix) {
-                    Element elemA = matA.getType().getElement();
-                    if (validateL3_xGEMM(elemA, transA, transB, matA, matB, matC)) {
-                        try {
-                            if (elemA.isCompatible(Element.F32(mRS))) {
-                                mBLAS.SGEMM(transA, transB, alphaS, matA, matB, betaS, matC);
-                            } else if (elemA.isCompatible(Element.F64(mRS))) {
-                                mBLAS.DGEMM(transA, transB, alphaD, matA, matB, betaD, matC);
-                            } else if (elemA.isCompatible(Element.F32_2(mRS))) {
-                                mBLAS.CGEMM(transA, transB, alphaC, matA, matB, betaC, matC);
-                            } else if (elemA.isCompatible(Element.F64_2(mRS))) {
-                                mBLAS.ZGEMM(transA, transB, alphaZ, matA, matB, betaZ, matC);
-                            }
-                        } catch (RSRuntimeException e) {
-                            fail("should NOT throw RSRuntimeException");
-                        }
-                    } else {
-                        try {
-                            mBLAS.SGEMM(transA, transB, alphaS, matA, matB, betaS, matC);
-                            fail("should throw RSRuntimeException for SGEMM");
-                        } catch (RSRuntimeException e) {
-                        }
-                        try {
-                            mBLAS.DGEMM(transA, transB, alphaD, matA, matB, betaD, matC);
-                            fail("should throw RSRuntimeException for DGEMM");
-                        } catch (RSRuntimeException e) {
-                        }
-                        try {
-                            mBLAS.CGEMM(transA, transB, alphaC, matA, matB, betaC, matC);
-                            fail("should throw RSRuntimeException for CGEMM");
-                        } catch (RSRuntimeException e) {
-                        }
-                        try {
-                            mBLAS.ZGEMM(transA, transB, alphaZ, matA, matB, betaZ, matC);
-                            fail("should throw RSRuntimeException for ZGEMM");
-                        } catch (RSRuntimeException e) {
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    private void L3_xGEMM_API(ArrayList<Allocation> mMatrix) {
-        for (int transA : mTranspose) {
-            for (int transB : mTranspose) {
-                xGEMM_API_test(transA, transB, mMatrix);
-            }
-        }
-    }
-
-    public void test_L3_SGEMM_API() {
-        L3_xGEMM_API(mMatrixS);
-    }
-
-    public void test_L3_DGEMM_API() {
-        L3_xGEMM_API(mMatrixD);
-    }
-
-    public void test_L3_CGEMM_API() {
-        L3_xGEMM_API(mMatrixC);
-    }
-
-    public void test_L3_ZGEMM_API() {
-        L3_xGEMM_API(mMatrixZ);
-    }
-
-
-    public void test_L3_SGEMM_Correctness() {
-        int transA = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        int transB = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-
-        // Populate input allocations
-        Allocation matrixAS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dK, mBLASData.dM));
-        Allocation matrixBS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dK));
-        Allocation matrixCS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dM));
-        matrixAS.copyFrom(mBLASData.L3_sGEMM_A_mk);
-        matrixBS.copyFrom(mBLASData.L3_sGEMM_B_kn);
-        matrixCS.copyFrom(mBLASData.L3_sGEMM_C_mn);
-
-        // Test for the default case: NO_TRANS
-        mBLAS.SGEMM(transA, transB, alphaS, matrixAS, matrixBS, betaS, matrixCS);
-        Allocation matrixCRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dM));
-        matrixCRef.copyFrom(mBLASData.L3_sGEMM_o_NN);
-        verifyMatrix(matrixCRef, matrixCS);
-
-        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
-        matrixAS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dM, mBLASData.dK));
-        matrixBS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dK, mBLASData.dN));
-        matrixAS.copyFrom(mBLASData.L3_sGEMM_A_km);
-        matrixBS.copyFrom(mBLASData.L3_sGEMM_B_nk);
-
-        transA = ScriptIntrinsicBLAS.TRANSPOSE;
-        transB = ScriptIntrinsicBLAS.TRANSPOSE;
-        // Reload matrix C, since it was overwritten by BLAS.
-        matrixCS.copyFrom(mBLASData.L3_sGEMM_C_mn);
-        mBLAS.SGEMM(transA, transB, alphaS, matrixAS, matrixBS, betaS, matrixCS);
-        matrixCRef.copyFrom(mBLASData.L3_sGEMM_o_TT);
-        verifyMatrix(matrixCRef, matrixCS);
-
-        transA = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
-        transB = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
-        matrixCS.copyFrom(mBLASData.L3_sGEMM_C_mn);
-        mBLAS.SGEMM(transA, transB, alphaS, matrixAS, matrixBS, betaS, matrixCS);
-        matrixCRef.copyFrom(mBLASData.L3_sGEMM_o_HH);
-        verifyMatrix(matrixCRef, matrixCS);
-
-        mRS.finish();
-        checkError();
-    }
-
-    public void test_L3_DGEMM_Correctness() {
-        int transA = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        int transB = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-
-        // Populate input allocations
-        Allocation matrixAD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dK, mBLASData.dM));
-        Allocation matrixBD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dK));
-        Allocation matrixCD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dM));
-        matrixAD.copyFrom(mBLASData.L3_dGEMM_A_mk);
-        matrixBD.copyFrom(mBLASData.L3_dGEMM_B_kn);
-        matrixCD.copyFrom(mBLASData.L3_dGEMM_C_mn);
-        // Test for the default case: NO_TRANS
-        mBLAS.DGEMM(transA, transB, alphaD, matrixAD, matrixBD, betaD, matrixCD);
-        Allocation matrixCRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dM));
-        matrixCRef.copyFrom(mBLASData.L3_dGEMM_o_NN);
-        verifyMatrix(matrixCRef, matrixCD);
-
-        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
-        matrixAD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dM, mBLASData.dK));
-        matrixBD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dK, mBLASData.dN));
-        matrixAD.copyFrom(mBLASData.L3_dGEMM_A_km);
-        matrixBD.copyFrom(mBLASData.L3_dGEMM_B_nk);
-
-        transA = ScriptIntrinsicBLAS.TRANSPOSE;
-        transB = ScriptIntrinsicBLAS.TRANSPOSE;
-        // Reload matrix C, since it was overwritten by BLAS.
-        matrixCD.copyFrom(mBLASData.L3_dGEMM_C_mn);
-        mBLAS.DGEMM(transA, transB, alphaD, matrixAD, matrixBD, betaD, matrixCD);
-        matrixCRef.copyFrom(mBLASData.L3_dGEMM_o_TT);
-        verifyMatrix(matrixCRef, matrixCD);
-
-        transA = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
-        transB = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
-        matrixCD.copyFrom(mBLASData.L3_dGEMM_C_mn);
-        mBLAS.DGEMM(transA, transB, alphaD, matrixAD, matrixBD, betaD, matrixCD);
-        matrixCRef.copyFrom(mBLASData.L3_dGEMM_o_HH);
-        verifyMatrix(matrixCRef, matrixCD);
-
-        mRS.finish();
-        checkError();
-    }
-
-    public void test_L3_CGEMM_Correctness() {
-        int transA = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        int transB = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-
-        // Populate input allocations
-        Allocation matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dK, mBLASData.dM));
-        Allocation matrixBC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dK));
-        Allocation matrixCC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dM));
-        matrixAC.copyFrom(mBLASData.L3_cGEMM_A_mk);
-        matrixBC.copyFrom(mBLASData.L3_cGEMM_B_kn);
-        matrixCC.copyFrom(mBLASData.L3_cGEMM_C_mn);
-
-        // Test for the default case: NO_TRANS
-        mBLAS.CGEMM(transA, transB, alphaC, matrixAC, matrixBC, betaC, matrixCC);
-        Allocation matrixCRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dM));
-        matrixCRef.copyFrom(mBLASData.L3_cGEMM_o_NN);
-        verifyMatrix(matrixCRef, matrixCC);
-
-        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
-        matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dM, mBLASData.dK));
-        matrixBC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dK, mBLASData.dN));
-        matrixAC.copyFrom(mBLASData.L3_cGEMM_A_km);
-        matrixBC.copyFrom(mBLASData.L3_cGEMM_B_nk);
-
-        transA = ScriptIntrinsicBLAS.TRANSPOSE;
-        transB = ScriptIntrinsicBLAS.TRANSPOSE;
-        // Reload matrix C, since it was overwritten by BLAS.
-        matrixCC.copyFrom(mBLASData.L3_cGEMM_C_mn);
-        mBLAS.CGEMM(transA, transB, alphaC, matrixAC, matrixBC, betaC, matrixCC);
-        matrixCRef.copyFrom(mBLASData.L3_cGEMM_o_TT);
-        verifyMatrix(matrixCRef, matrixCC);
-
-        transA = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
-        transB = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
-        matrixCC.copyFrom(mBLASData.L3_cGEMM_C_mn);
-        mBLAS.CGEMM(transA, transB, alphaC, matrixAC, matrixBC, betaC, matrixCC);
-        matrixCRef.copyFrom(mBLASData.L3_cGEMM_o_HH);
-        verifyMatrix(matrixCRef, matrixCC);
-
-        mRS.finish();
-        checkError();
-    }
-
-    public void test_L3_ZGEMM_Correctness() {
-        int transA = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        int transB = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-
-        // Populate input allocations
-        Allocation matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dK, mBLASData.dM));
-        Allocation matrixBZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dK));
-        Allocation matrixCZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dM));
-        matrixAZ.copyFrom(mBLASData.L3_zGEMM_A_mk);
-        matrixBZ.copyFrom(mBLASData.L3_zGEMM_B_kn);
-        matrixCZ.copyFrom(mBLASData.L3_zGEMM_C_mn);
-
-        // Test for the default case: NO_TRANS
-        mBLAS.ZGEMM(transA, transB, alphaZ, matrixAZ, matrixBZ, betaZ, matrixCZ);
-        Allocation matrixCRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dM));
-        matrixCRef.copyFrom(mBLASData.L3_zGEMM_o_NN);
-        verifyMatrix(matrixCRef, matrixCZ);
-
-        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
-        matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dM, mBLASData.dK));
-        matrixBZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dK, mBLASData.dN));
-        matrixAZ.copyFrom(mBLASData.L3_zGEMM_A_km);
-        matrixBZ.copyFrom(mBLASData.L3_zGEMM_B_nk);
-
-        transA = ScriptIntrinsicBLAS.TRANSPOSE;
-        transB = ScriptIntrinsicBLAS.TRANSPOSE;
-        // Reload matrix C, since it was overwritten by BLAS.
-        matrixCZ.copyFrom(mBLASData.L3_zGEMM_C_mn);
-        mBLAS.ZGEMM(transA, transB, alphaZ, matrixAZ, matrixBZ, betaZ, matrixCZ);
-        matrixCRef.copyFrom(mBLASData.L3_zGEMM_o_TT);
-        verifyMatrix(matrixCRef, matrixCZ);
-
-        transA = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
-        transB = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
-        matrixCZ.copyFrom(mBLASData.L3_zGEMM_C_mn);
-        mBLAS.ZGEMM(transA, transB, alphaZ, matrixAZ, matrixBZ, betaZ, matrixCZ);
-        matrixCRef.copyFrom(mBLASData.L3_zGEMM_o_HH);
-        verifyMatrix(matrixCRef, matrixCZ);
-
-        mRS.finish();
-        checkError();
-    }
-
-
-
-    private boolean validateL3_xSYMM(Element e, int Side, int Uplo, Allocation A, Allocation B, Allocation C) {
-        boolean result = true;
-        result &= validateSide(Side);
-        result &= validateUplo(Uplo);
-        result &= validateL3(e, 0, 0, Side, A, B, C);
-        result &= (A.getType().getX() == A.getType().getY());
-        return result;
-    }
-
-    private void xSYMM_API_test(int Side, int Uplo, ArrayList<Allocation> mMatrix) {
-        for (Allocation matA : mMatrix) {
-            for (Allocation matB : mMatrix) {
-                for (Allocation matC : mMatrix) {
-                    Element elemA = matA.getType().getElement();
-                    if (validateL3_xSYMM(elemA, Side, Uplo, matA, matB, matC)) {
-                        try {
-                            if (elemA.isCompatible(Element.F32(mRS))) {
-                                mBLAS.SSYMM(Side, Uplo, alphaS, matA, matB, betaS, matC);
-                            } else if (elemA.isCompatible(Element.F64(mRS))) {
-                                mBLAS.DSYMM(Side, Uplo, alphaD, matA, matB, betaD, matC);
-                            } else if (elemA.isCompatible(Element.F32_2(mRS))) {
-                                mBLAS.CSYMM(Side, Uplo, alphaC, matA, matB, betaC, matC);
-                            } else if (elemA.isCompatible(Element.F64_2(mRS))) {
-                                mBLAS.ZSYMM(Side, Uplo, alphaZ, matA, matB, betaZ, matC);
-                            }
-                        } catch (RSRuntimeException e) {
-                            fail("should NOT throw RSRuntimeException");
-                        }
-                    } else {
-                        try {
-                            mBLAS.SSYMM(Side, Uplo, alphaS, matA, matB, betaS, matC);
-                            fail("should throw RSRuntimeException for SSYMM");
-                        } catch (RSRuntimeException e) {
-                        }
-                        try {
-                            mBLAS.DSYMM(Side, Uplo, alphaD, matA, matB, betaD, matC);
-                            fail("should throw RSRuntimeException for DSYMM");
-                        } catch (RSRuntimeException e) {
-                        }
-                        try {
-                            mBLAS.CSYMM(Side, Uplo, alphaC, matA, matB, betaC, matC);
-                            fail("should throw RSRuntimeException for CSYMM");
-                        } catch (RSRuntimeException e) {
-                        }
-                        try {
-                            mBLAS.ZSYMM(Side, Uplo, alphaZ, matA, matB, betaZ, matC);
-                            fail("should throw RSRuntimeException for ZSYMM");
-                        } catch (RSRuntimeException e) {
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    private void L3_xSYMM_API(ArrayList<Allocation> mMatrix) {
-        for (int Side : mSide) {
-            for (int Uplo : mUplo) {
-                xSYMM_API_test(Side, Uplo, mMatrix);
-            }
-        }
-    }
-
-    public void test_L3_SSYMM_API() {
-        L3_xSYMM_API(mMatrixS);
-    }
-
-    public void test_L3_DSYMM_API() {
-        L3_xSYMM_API(mMatrixD);
-    }
-
-    public void test_L3_CSYMM_API() {
-        L3_xSYMM_API(mMatrixC);
-    }
-
-    public void test_L3_ZSYMM_API() {
-        L3_xSYMM_API(mMatrixZ);
-    }
-
-
-    public void test_L3_SSYMM_Correctness() {
-        int side = ScriptIntrinsicBLAS.LEFT;
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-
-        // Populate input allocations
-        Allocation matrixAS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dM, mBLASData.dM));
-        Allocation matrixBS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dM));
-        Allocation matrixCS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dM));
-        matrixAS.copyFrom(mBLASData.L3_sSYMM_A_mm);
-        matrixBS.copyFrom(mBLASData.L3_sSYMM_B_mn);
-        matrixCS.copyFrom(mBLASData.L3_sSYMM_C_mn);
-
-        // Default case: SIDE = LEFT
-        mBLAS.SSYMM(side, uplo, alphaS, matrixAS, matrixBS, betaS, matrixCS);
-        Allocation matrixCRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dM));
-        matrixCRef.copyFrom(mBLASData.L3_sSYMM_o_L);
-        verifyMatrix(matrixCRef, matrixCS);
-
-        // SIDE = RIGHT
-        side = ScriptIntrinsicBLAS.RIGHT;
-        matrixAS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dN));
-        matrixAS.copyFrom(mBLASData.L3_sSYMM_A_nn);
-        // Reload matrix C, since it was overwritten by BLAS.
-        matrixCS.copyFrom(mBLASData.L3_sSYMM_C_mn);
-        mBLAS.SSYMM(side, uplo, alphaS, matrixAS, matrixBS, betaS, matrixCS);
-        matrixCRef.copyFrom(mBLASData.L3_sSYMM_o_R);
-        verifyMatrix(matrixCRef, matrixCS);
-
-        mRS.finish();
-        checkError();
-    }
-
-    public void test_L3_DSYMM_Correctness() {
-        int side = ScriptIntrinsicBLAS.LEFT;
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-
-        // Populate input allocations
-        Allocation matrixAD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dM, mBLASData.dM));
-        Allocation matrixBD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dM));
-        Allocation matrixCD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dM));
-        matrixAD.copyFrom(mBLASData.L3_dSYMM_A_mm);
-        matrixBD.copyFrom(mBLASData.L3_dSYMM_B_mn);
-        matrixCD.copyFrom(mBLASData.L3_dSYMM_C_mn);
-
-        // Default case: SIDE = LEFT
-        mBLAS.DSYMM(side, uplo, alphaD, matrixAD, matrixBD, betaD, matrixCD);
-        Allocation matrixCRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dM));
-        matrixCRef.copyFrom(mBLASData.L3_dSYMM_o_L);
-        verifyMatrix(matrixCRef, matrixCD);
-
-        // SIDE = RIGHT
-        side = ScriptIntrinsicBLAS.RIGHT;
-        matrixAD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dN));
-        matrixAD.copyFrom(mBLASData.L3_dSYMM_A_nn);
-        // Reload matrix C, since it was overwritten by BLAS.
-        matrixCD.copyFrom(mBLASData.L3_dSYMM_C_mn);
-        mBLAS.DSYMM(side, uplo, alphaD, matrixAD, matrixBD, betaD, matrixCD);
-        matrixCRef.copyFrom(mBLASData.L3_dSYMM_o_R);
-        verifyMatrix(matrixCRef, matrixCD);
-
-        mRS.finish();
-        checkError();
-    }
-
-    public void test_L3_CSYMM_Correctness() {
-        int side = ScriptIntrinsicBLAS.LEFT;
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-
-        // Populate input allocations
-        Allocation matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dM, mBLASData.dM));
-        Allocation matrixBC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dM));
-        Allocation matrixCC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dM));
-        matrixAC.copyFrom(mBLASData.L3_cSYMM_A_mm);
-        matrixBC.copyFrom(mBLASData.L3_cSYMM_B_mn);
-        matrixCC.copyFrom(mBLASData.L3_cSYMM_C_mn);
-
-        // Default case: SIDE = LEFT
-        mBLAS.CSYMM(side, uplo, alphaC, matrixAC, matrixBC, betaC, matrixCC);
-        Allocation matrixCRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dM));
-        matrixCRef.copyFrom(mBLASData.L3_cSYMM_o_L);
-        verifyMatrix(matrixCRef, matrixCC);
-
-        // SIDE = RIGHT
-        side = ScriptIntrinsicBLAS.RIGHT;
-        matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dN));
-        matrixAC.copyFrom(mBLASData.L3_cSYMM_A_nn);
-        // Reload matrix C, since it was overwritten by BLAS.
-        matrixCC.copyFrom(mBLASData.L3_cSYMM_C_mn);
-        mBLAS.CSYMM(side, uplo, alphaC, matrixAC, matrixBC, betaC, matrixCC);
-        matrixCRef.copyFrom(mBLASData.L3_cSYMM_o_R);
-        verifyMatrix(matrixCRef, matrixCC);
-
-        mRS.finish();
-        checkError();
-    }
-
-    public void test_L3_ZSYMM_Correctness() {
-        int side = ScriptIntrinsicBLAS.LEFT;
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-
-        // Populate input allocations
-        Allocation matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dM, mBLASData.dM));
-        Allocation matrixBZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dM));
-        Allocation matrixCZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dM));
-        matrixAZ.copyFrom(mBLASData.L3_zSYMM_A_mm);
-        matrixBZ.copyFrom(mBLASData.L3_zSYMM_B_mn);
-        matrixCZ.copyFrom(mBLASData.L3_zSYMM_C_mn);
-
-        // Default case: SIDE = LEFT
-        mBLAS.ZSYMM(side, uplo, alphaZ, matrixAZ, matrixBZ, betaZ, matrixCZ);
-        Allocation matrixCRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dM));
-        matrixCRef.copyFrom(mBLASData.L3_zSYMM_o_L);
-        verifyMatrix(matrixCRef, matrixCZ);
-
-        // SIDE = RIGHT
-        side = ScriptIntrinsicBLAS.RIGHT;
-        matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dN));
-        matrixAZ.copyFrom(mBLASData.L3_zSYMM_A_nn);
-        // Reload matrix C, since it was overwritten by BLAS.
-        matrixCZ.copyFrom(mBLASData.L3_zSYMM_C_mn);
-        mBLAS.ZSYMM(side, uplo, alphaZ, matrixAZ, matrixBZ, betaZ, matrixCZ);
-        matrixCRef.copyFrom(mBLASData.L3_zSYMM_o_R);
-        verifyMatrix(matrixCRef, matrixCZ);
-
-        mRS.finish();
-        checkError();
-    }
-
-
-    private boolean validateHEMM(Element e, int Side, int Uplo, Allocation A, Allocation B, Allocation C) {
-        if (!validateSide(Side)) {
-            return false;
-        }
-
-        if (!validateUplo(Uplo)) {
-            return false;
-        }
-
-        if (!A.getType().getElement().isCompatible(e) ||
-            !B.getType().getElement().isCompatible(e) ||
-            !C.getType().getElement().isCompatible(e)) {
-            return false;
-        }
-
-        // A must be square; can potentially be relaxed similar to TRSM
-        int adim = A.getType().getX();
-        if (adim != A.getType().getY()) {
-            return false;
-        }
-        if ((Side == ScriptIntrinsicBLAS.LEFT && adim != B.getType().getY()) ||
-            (Side == ScriptIntrinsicBLAS.RIGHT && adim != B.getType().getX())) {
-            return false;
-        }
-        if (B.getType().getX() != C.getType().getX() ||
-            B.getType().getY() != C.getType().getY()) {
-            return false;
-        }
-
-        return true;
-    }
-
-    private void xHEMM_API_test(int Side, int Uplo, ArrayList<Allocation> mMatrix) {
-        for (Allocation matA : mMatrix) {
-            for (Allocation matB : mMatrix) {
-                for (Allocation matC : mMatrix) {
-                    Element elemA = matA.getType().getElement();
-                    if (validateHEMM(elemA, Side, Uplo, matA, matB, matC)) {
-                        try {
-                            if (elemA.isCompatible(Element.F32_2(mRS))) {
-                                mBLAS.CHEMM(Side, Uplo, alphaC, matA, matB, betaC, matC);
-                            } else if (elemA.isCompatible(Element.F64_2(mRS))) {
-                                mBLAS.ZHEMM(Side, Uplo, alphaZ, matA, matB, betaZ, matC);
-                            }
-                        } catch (RSRuntimeException e) {
-                            fail("should NOT throw RSRuntimeException");
-                        }
-                    } else {
-                        try {
-                            mBLAS.CHEMM(Side, Uplo, alphaC, matA, matB, betaC, matC);
-                            fail("should throw RSRuntimeException for CHEMM");
-                        } catch (RSRuntimeException e) {
-                        }
-                        try {
-                            mBLAS.ZHEMM(Side, Uplo, alphaZ, matA, matB, betaZ, matC);
-                            fail("should throw RSRuntimeException for ZHEMM");
-                        } catch (RSRuntimeException e) {
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    public void L3_xHEMM_API(ArrayList<Allocation> mMatrix) {
-        for (int Side : mSide) {
-            for (int Uplo : mUplo) {
-                xHEMM_API_test(Side, Uplo, mMatrix);
-            }
-        }
-    }
-
-    public void test_L3_CHEMM_API() {
-        L3_xHEMM_API(mMatrixC);
-    }
-
-    public void test_L3_ZHEMM_API() {
-        L3_xHEMM_API(mMatrixZ);
-    }
-
-    public void test_L3_CHEMM_Correctness() {
-        int side = ScriptIntrinsicBLAS.LEFT;
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-
-        // Populate input allocations
-        Allocation matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dM, mBLASData.dM));
-        Allocation matrixBC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dM));
-        Allocation matrixCC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dM));
-        matrixAC.copyFrom(mBLASData.L3_cHEMM_A_mm);
-        matrixBC.copyFrom(mBLASData.L3_cHEMM_B_mn);
-        matrixCC.copyFrom(mBLASData.L3_cHEMM_C_mn);
-
-        // Default case: SIDE = LEFT
-        mBLAS.CHEMM(side, uplo, alphaC, matrixAC, matrixBC, betaC, matrixCC);
-        Allocation matrixCRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dM));
-        matrixCRef.copyFrom(mBLASData.L3_cHEMM_o_L);
-        verifyMatrix(matrixCRef, matrixCC);
-
-        // SIDE = RIGHT
-        side = ScriptIntrinsicBLAS.RIGHT;
-        matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dN));
-        matrixAC.copyFrom(mBLASData.L3_cHEMM_A_nn);
-        // Reload matrix C, since it was overwritten by BLAS.
-        matrixCC.copyFrom(mBLASData.L3_cHEMM_C_mn);
-        mBLAS.CHEMM(side, uplo, alphaC, matrixAC, matrixBC, betaC, matrixCC);
-        matrixCRef.copyFrom(mBLASData.L3_cHEMM_o_R);
-        verifyMatrix(matrixCRef, matrixCC);
-
-        mRS.finish();
-        checkError();
-    }
-
-    public void test_L3_ZHEMM_Correctness() {
-        int side = ScriptIntrinsicBLAS.LEFT;
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-
-        // Populate input allocations
-        Allocation matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dM, mBLASData.dM));
-        Allocation matrixBZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dM));
-        Allocation matrixCZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dM));
-        matrixAZ.copyFrom(mBLASData.L3_zHEMM_A_mm);
-        matrixBZ.copyFrom(mBLASData.L3_zHEMM_B_mn);
-        matrixCZ.copyFrom(mBLASData.L3_zHEMM_C_mn);
-
-        // Default case: SIDE = LEFT
-        mBLAS.ZHEMM(side, uplo, alphaZ, matrixAZ, matrixBZ, betaZ, matrixCZ);
-        Allocation matrixCRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dM));
-        matrixCRef.copyFrom(mBLASData.L3_zHEMM_o_L);
-        verifyMatrix(matrixCRef, matrixCZ);
-
-        // SIDE = RIGHT
-        side = ScriptIntrinsicBLAS.RIGHT;
-        matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dN));
-        matrixAZ.copyFrom(mBLASData.L3_zHEMM_A_nn);
-        // Reload matrix C, since it was overwritten by BLAS.
-        matrixCZ.copyFrom(mBLASData.L3_zHEMM_C_mn);
-        mBLAS.ZHEMM(side, uplo, alphaZ, matrixAZ, matrixBZ, betaZ, matrixCZ);
-        matrixCRef.copyFrom(mBLASData.L3_zHEMM_o_R);
-        verifyMatrix(matrixCRef, matrixCZ);
-
-        mRS.finish();
-        checkError();
-    }
-
-
-
-    private boolean validateL3_xSYRK(Element e, int Uplo, int Trans, Allocation A, Allocation C) {
-        boolean result = true;
-        result &= validateTranspose(Trans);
-        result &= validateUplo(Uplo);
-        result &= validateL3(e, Trans, 0, 0, A, null, C);
-
-        return result;
-    }
-
-    private void xSYRK_API_test(int Uplo, int Trans, ArrayList<Allocation> mMatrix) {
-        for (Allocation matA : mMatrix) {
-            for (Allocation matC : mMatrix) {
-                Element elemA = matA.getType().getElement();
-                if (validateL3_xSYRK(elemA, Uplo, Trans, matA, matC)) {
-                    try {
-                        if (elemA.isCompatible(Element.F32(mRS))) {
-                            mBLAS.SSYRK(Uplo, Trans, alphaS, matA, betaS, matC);
-                        } else if (elemA.isCompatible(Element.F64(mRS))) {
-                            mBLAS.DSYRK(Uplo, Trans, alphaD, matA, betaD, matC);
-                        } else if (elemA.isCompatible(Element.F32_2(mRS))) {
-                            mBLAS.CSYRK(Uplo, Trans, alphaC, matA, betaC, matC);
-                        } else if (elemA.isCompatible(Element.F64_2(mRS))) {
-                            mBLAS.ZSYRK(Uplo, Trans, alphaZ, matA, betaZ, matC);
-                        }
-                    } catch (RSRuntimeException e) {
-                        fail("should NOT throw RSRuntimeException");
-                    }
-                } else {
-                    try {
-                        mBLAS.SSYRK(Uplo, Trans, alphaS, matA, betaS, matC);
-                        fail("should throw RSRuntimeException for SSYRK");
-                    } catch (RSRuntimeException e) {
-                    }
-                    try {
-                        mBLAS.DSYRK(Uplo, Trans, alphaD, matA, betaD, matC);
-                        fail("should throw RSRuntimeException for DSYRK");
-                    } catch (RSRuntimeException e) {
-                    }
-                    try {
-                        mBLAS.CSYRK(Uplo, Trans, alphaC, matA, betaC, matC);
-                        fail("should throw RSRuntimeException for CSYRK");
-                    } catch (RSRuntimeException e) {
-                    }
-                    try {
-                        mBLAS.ZSYRK(Uplo, Trans, alphaZ, matA, betaZ, matC);
-                        fail("should throw RSRuntimeException for ZSYRK");
-                    } catch (RSRuntimeException e) {
-                    }
-                }
-            }
-        }
-    }
-
-    public void L3_xSYRK_API(ArrayList<Allocation> mMatrix) {
-        for (int Uplo : mUplo) {
-            for (int Trans : mTranspose) {
-                xSYRK_API_test(Uplo, Trans, mMatrix);
-            }
-        }
-    }
-
-    public void test_L3_SSYRK_API() {
-        L3_xSYRK_API(mMatrixS);
-    }
-
-    public void test_L3_DSYRK_API() {
-        L3_xSYRK_API(mMatrixD);
-    }
-
-    public void test_L3_CSYRK_API() {
-        L3_xSYRK_API(mMatrixC);
-    }
-
-    public void test_L3_ZSYRK_API() {
-        L3_xSYRK_API(mMatrixZ);
-    }
-
-
-    public void test_L3_SSYRK_Correctness() {
-        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-
-        // Populate input allocations
-        Allocation matrixAS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dK, mBLASData.dN));
-        Allocation matrixCS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dN));
-        matrixAS.copyFrom(mBLASData.L3_sSYRK_A_nk);
-        matrixCS.copyFrom(mBLASData.L3_sSYRK_C_nn);
-
-        // Default case: NO_TRANSPOSE
-        mBLAS.SSYRK(uplo, trans, alphaS, matrixAS, betaS, matrixCS);
-        Allocation matrixCRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dN));
-        matrixCRef.copyFrom(mBLASData.L3_sSYRK_o_N);
-        verifyMatrix(matrixCRef, matrixCS, true);
-
-        // Case: TRANSPOSE
-        matrixAS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dK));
-        matrixAS.copyFrom(mBLASData.L3_sSYRK_A_kn);
-        // Reload matrix C, since it was overwritten by BLAS.
-        matrixCS.copyFrom(mBLASData.L3_sSYRK_C_nn);
-
-        trans = ScriptIntrinsicBLAS.TRANSPOSE;
-        mBLAS.SSYRK(uplo, trans, alphaS, matrixAS, betaS, matrixCS);
-        matrixCRef.copyFrom(mBLASData.L3_sSYRK_o_T);
-        verifyMatrix(matrixCRef, matrixCS, true);
-
-        mRS.finish();
-        checkError();
-    }
-
-    public void test_L3_DSYRK_Correctness() {
-        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-
-        // Populate input allocations
-        Allocation matrixAD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dK, mBLASData.dN));
-        Allocation matrixCD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dN));
-        matrixAD.copyFrom(mBLASData.L3_dSYRK_A_nk);
-        matrixCD.copyFrom(mBLASData.L3_dSYRK_C_nn);
-
-        // Default case: NO_TRANSPOSE
-        mBLAS.DSYRK(uplo, trans, alphaD, matrixAD, betaD, matrixCD);
-        Allocation matrixCRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dN));
-        matrixCRef.copyFrom(mBLASData.L3_dSYRK_o_N);
-        verifyMatrix(matrixCRef, matrixCD, true);
-
-        // Case: TRANSPOSE
-        matrixAD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dK));
-        matrixAD.copyFrom(mBLASData.L3_dSYRK_A_kn);
-        // Reload matrix C, since it was overwritten by BLAS.
-        matrixCD.copyFrom(mBLASData.L3_dSYRK_C_nn);
-
-        trans = ScriptIntrinsicBLAS.TRANSPOSE;
-        mBLAS.DSYRK(uplo, trans, alphaD, matrixAD, betaD, matrixCD);
-        matrixCRef.copyFrom(mBLASData.L3_dSYRK_o_T);
-        verifyMatrix(matrixCRef, matrixCD, true);
-
-        mRS.finish();
-        checkError();
-    }
-
-    public void test_L3_CSYRK_Correctness() {
-        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-
-        // Populate input allocations
-        Allocation matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dK, mBLASData.dN));
-        Allocation matrixCC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dN));
-        matrixAC.copyFrom(mBLASData.L3_cSYRK_A_nk);
-        matrixCC.copyFrom(mBLASData.L3_cSYRK_C_nn);
-
-        // Default case: NO_TRANSPOSE
-        mBLAS.CSYRK(uplo, trans, alphaC, matrixAC, betaC, matrixCC);
-        Allocation matrixCRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dN));
-        matrixCRef.copyFrom(mBLASData.L3_cSYRK_o_N);
-        verifyMatrix(matrixCRef, matrixCC, true);
-
-        // Case: TRANSPOSE
-        matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dK));
-        matrixAC.copyFrom(mBLASData.L3_cSYRK_A_kn);
-        // Reload matrix C, since it was overwritten by BLAS.
-        matrixCC.copyFrom(mBLASData.L3_cSYRK_C_nn);
-
-        trans = ScriptIntrinsicBLAS.TRANSPOSE;
-        mBLAS.CSYRK(uplo, trans, alphaC, matrixAC, betaC, matrixCC);
-        matrixCRef.copyFrom(mBLASData.L3_cSYRK_o_T);
-        verifyMatrix(matrixCRef, matrixCC, true);
-
-        mRS.finish();
-        checkError();
-    }
-
-    public void test_L3_ZSYRK_Correctness() {
-        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-
-        // Populate input allocations
-        Allocation matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dK, mBLASData.dN));
-        Allocation matrixCZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dN));
-        matrixAZ.copyFrom(mBLASData.L3_zSYRK_A_nk);
-        matrixCZ.copyFrom(mBLASData.L3_zSYRK_C_nn);
-
-        // Default case: NO_TRANSPOSE
-        mBLAS.ZSYRK(uplo, trans, alphaZ, matrixAZ, betaZ, matrixCZ);
-        Allocation matrixCRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dN));
-        matrixCRef.copyFrom(mBLASData.L3_zSYRK_o_N);
-        verifyMatrix(matrixCRef, matrixCZ, true);
-
-        // Case: TRANSPOSE
-        matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dK));
-        matrixAZ.copyFrom(mBLASData.L3_zSYRK_A_kn);
-        // Reload matrix C, since it was overwritten by BLAS.
-        matrixCZ.copyFrom(mBLASData.L3_zSYRK_C_nn);
-
-        trans = ScriptIntrinsicBLAS.TRANSPOSE;
-        mBLAS.ZSYRK(uplo, trans, alphaZ, matrixAZ, betaZ, matrixCZ);
-        matrixCRef.copyFrom(mBLASData.L3_zSYRK_o_T);
-        verifyMatrix(matrixCRef, matrixCZ, true);
-
-        mRS.finish();
-        checkError();
-    }
-
-
-    private boolean validateHERK(Element e, int Uplo, int Trans, Allocation A, Allocation C) {
-        if (!validateUplo(Uplo)) {
-            return false;
-        }
-        if (!A.getType().getElement().isCompatible(e) ||
-            !C.getType().getElement().isCompatible(e)) {
-            return false;
-        }
-        if (!validateConjTranspose(Trans)) {
-            return false;
-        }
-        int cdim = C.getType().getX();
-        if (cdim != C.getType().getY()) {
-            return false;
-        }
-        if (Trans == ScriptIntrinsicBLAS.NO_TRANSPOSE) {
-            if (cdim != A.getType().getY()) {
-                return false;
-            }
-        } else {
-            if (cdim != A.getType().getX()) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    private void xHERK_API_test(int Uplo, int Trans, ArrayList<Allocation> mMatrix) {
-        for (Allocation matA : mMatrix) {
-            for (Allocation matC : mMatrix) {
-                Element elemA = matA.getType().getElement();
-                if (validateHERK(elemA, Uplo, Trans, matA, matC)) {
-                    try {
-                        if (elemA.isCompatible(Element.F32_2(mRS))) {
-                            mBLAS.CHERK(Uplo, Trans, alphaS, matA, betaS, matC);
-                        } else if (elemA.isCompatible(Element.F64_2(mRS))) {
-                            mBLAS.ZHERK(Uplo, Trans, alphaD, matA, betaD, matC);
-                        }
-                    } catch (RSRuntimeException e) {
-                        fail("should NOT throw RSRuntimeException");
-                    }
-                } else {
-                    try {
-                        mBLAS.CHERK(Uplo, Trans, alphaS, matA, betaS, matC);
-                        fail("should throw RSRuntimeException for CHERK");
-                    } catch (RSRuntimeException e) {
-                    }
-                    try {
-                        mBLAS.ZHERK(Uplo, Trans, alphaD, matA, betaD, matC);
-                        fail("should throw RSRuntimeException for ZHERK");
-                    } catch (RSRuntimeException e) {
-                    }
-                }
-            }
-        }
-    }
-
-    public void L3_xHERK_API(ArrayList<Allocation> mMatrix) {
-        for (int Uplo : mUplo) {
-            for (int Trans : mTranspose) {
-                xHERK_API_test(Uplo, Trans, mMatrix);
-            }
-        }
-    }
-
-    public void test_L3_CHERK_API() {
-        L3_xHERK_API(mMatrixC);
-    }
-
-    public void test_L3_ZHERK_API() {
-        L3_xHERK_API(mMatrixZ);
-    }
-
-    public void test_L3_CHERK_Correctness() {
-        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-
-        // Populate input allocations
-        Allocation matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dK, mBLASData.dN));
-        Allocation matrixCC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dN));
-        matrixAC.copyFrom(mBLASData.L3_cHERK_A_nk);
-        matrixCC.copyFrom(mBLASData.L3_cHERK_C_nn);
-
-        // Default case: NO_TRANSPOSE
-        mBLAS.CHERK(uplo, trans, alphaS, matrixAC, betaS, matrixCC);
-        Allocation matrixCRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dN));
-        matrixCRef.copyFrom(mBLASData.L3_cHERK_o_N);
-        verifyMatrix(matrixCRef, matrixCC, true);
-
-        // Case: TRANSPOSE
-        matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dK));
-        matrixAC.copyFrom(mBLASData.L3_cHERK_A_kn);
-        // Reload matrix C, since it was overwritten by BLAS.
-        matrixCC.copyFrom(mBLASData.L3_cHERK_C_nn);
-
-        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
-        mBLAS.CHERK(uplo, trans, alphaS, matrixAC, betaS, matrixCC);
-        matrixCRef.copyFrom(mBLASData.L3_cHERK_o_H);
-        verifyMatrix(matrixCRef, matrixCC, true);
-
-        mRS.finish();
-        checkError();
-    }
-
-    public void test_L3_ZHERK_Correctness() {
-        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-
-        // Populate input allocations
-        Allocation matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dK, mBLASData.dN));
-        Allocation matrixCZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dN));
-        matrixAZ.copyFrom(mBLASData.L3_zHERK_A_nk);
-        matrixCZ.copyFrom(mBLASData.L3_zHERK_C_nn);
-
-        // Default case: NO_TRANSPOSE
-        mBLAS.ZHERK(uplo, trans, alphaD, matrixAZ, betaD, matrixCZ);
-        Allocation matrixCRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dN));
-        matrixCRef.copyFrom(mBLASData.L3_zHERK_o_N);
-        verifyMatrix(matrixCRef, matrixCZ, true);
-
-        // Case: TRANSPOSE
-        matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dK));
-        matrixAZ.copyFrom(mBLASData.L3_zHERK_A_kn);
-        // Reload matrix C, since it was overwritten by BLAS.
-        matrixCZ.copyFrom(mBLASData.L3_zHERK_C_nn);
-
-        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
-        mBLAS.ZHERK(uplo, trans, alphaD, matrixAZ, betaD, matrixCZ);
-        matrixCRef.copyFrom(mBLASData.L3_zHERK_o_H);
-        verifyMatrix(matrixCRef, matrixCZ, true);
-
-        mRS.finish();
-        checkError();
-    }
-
-
-    private boolean validateSYR2K(Element e, int Uplo, int Trans, Allocation A, Allocation B, Allocation C) {
-        if (!validateTranspose(Trans)) {
-            return false;
-        }
-        if (!validateUplo(Uplo)) {
-            return false;
-        }
-
-        if (!A.getType().getElement().isCompatible(e) ||
-            !B.getType().getElement().isCompatible(e) ||
-            !C.getType().getElement().isCompatible(e)) {
-            return false;
-        }
-        int Cdim = -1;
-        // A is n x k if no transpose, k x n if transpose
-        // C is n x n
-        if (Trans == ScriptIntrinsicBLAS.TRANSPOSE) {
-            // check columns versus C
-            Cdim = A.getType().getX();
-        } else {
-            // check rows versus C
-            Cdim = A.getType().getY();
-        }
-        if (C.getType().getX() != Cdim || C.getType().getY() != Cdim) {
-            return false;
-        }
-        // A dims == B dims
-        if (A.getType().getX() != B.getType().getX() || A.getType().getY() != B.getType().getY()) {
-            return false;
-        }
-        return true;
-    }
-
-    private void xSYR2K_API_test(int Uplo, int Trans, ArrayList<Allocation> mMatrix) {
-        for (Allocation matA : mMatrix) {
-            for (Allocation matB : mMatrix) {
-                for (Allocation matC : mMatrix) {
-                    Element elemA = matA.getType().getElement();
-                    if (validateSYR2K(elemA, Uplo, Trans, matA, matB, matC)) {
-                        try {
-                            if (elemA.isCompatible(Element.F32(mRS))) {
-                                mBLAS.SSYR2K(Uplo, Trans, alphaS, matA, matB, betaS, matC);
-                            } else if (elemA.isCompatible(Element.F64(mRS))) {
-                                mBLAS.DSYR2K(Uplo, Trans, alphaD, matA, matB, betaD, matC);
-                            } else if (elemA.isCompatible(Element.F32_2(mRS))) {
-                                mBLAS.CSYR2K(Uplo, Trans, alphaC, matA, matB, betaC, matC);
-                            } else if (elemA.isCompatible(Element.F64_2(mRS))) {
-                                mBLAS.ZSYR2K(Uplo, Trans, alphaZ, matA, matB, betaZ, matC);
-                            }
-                        } catch (RSRuntimeException e) {
-                            fail("should NOT throw RSRuntimeException");
-                        }
-                    } else {
-                        try {
-                            mBLAS.SSYR2K(Uplo, Trans, alphaS, matA, matB, betaS, matC);
-                            fail("should throw RSRuntimeException for SSYR2K");
-                        } catch (RSRuntimeException e) {
-                        }
-                        try {
-                            mBLAS.DSYR2K(Uplo, Trans, alphaD, matA, matB, betaD, matC);
-                            fail("should throw RSRuntimeException for DSYR2K");
-                        } catch (RSRuntimeException e) {
-                        }
-                        try {
-                            mBLAS.CSYR2K(Uplo, Trans, alphaC, matA, matB, betaC, matC);
-                            fail("should throw RSRuntimeException for CSYR2K");
-                        } catch (RSRuntimeException e) {
-                        }
-                        try {
-                            mBLAS.ZSYR2K(Uplo, Trans, alphaZ, matA, matB, betaZ, matC);
-                            fail("should throw RSRuntimeException for ZSYR2K");
-                        } catch (RSRuntimeException e) {
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    public void L3_xSYR2K_API(ArrayList<Allocation> mMatrix) {
-        for (int Uplo : mUplo) {
-            for (int Trans : mTranspose) {
-                xSYR2K_API_test(Uplo, Trans, mMatrix);
-            }
-        }
-    }
-
-    public void test_L3_SSYR2K_API() {
-        L3_xSYR2K_API(mMatrixS);
-    }
-
-    public void test_L3_DSYR2K_API() {
-        L3_xSYR2K_API(mMatrixD);
-    }
-
-    public void test_L3_CSYR2K_API() {
-        L3_xSYR2K_API(mMatrixC);
-    }
-
-    public void test_L3_ZSYR2K_API() {
-        L3_xSYR2K_API(mMatrixZ);
-    }
-
-
-    public void test_L3_SSYR2K_Correctness() {
-        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-
-        // Populate input allocations
-        Allocation matrixAS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dK, mBLASData.dN));
-        Allocation matrixBS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dK, mBLASData.dN));
-        Allocation matrixCS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dN));
-        matrixAS.copyFrom(mBLASData.L3_sSYR2K_A_nk);
-        matrixBS.copyFrom(mBLASData.L3_sSYR2K_B_nk);
-        matrixCS.copyFrom(mBLASData.L3_sSYR2K_C_nn);
-
-        // Default case: NO_TRANSPOSE
-        mBLAS.SSYR2K(uplo, trans, alphaS, matrixAS, matrixBS, betaS, matrixCS);
-        Allocation matrixCRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dN));
-        matrixCRef.copyFrom(mBLASData.L3_sSYR2K_o_N);
-        verifyMatrix(matrixCRef, matrixCS, true);
-
-        // Case: TRANSPOSE
-        matrixAS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dK));
-        matrixBS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dK));
-        matrixAS.copyFrom(mBLASData.L3_sSYR2K_A_kn);
-        matrixBS.copyFrom(mBLASData.L3_sSYR2K_B_kn);
-        // Reload matrix C, since it was overwritten by BLAS.
-        matrixCS.copyFrom(mBLASData.L3_sSYR2K_C_nn);
-
-        trans = ScriptIntrinsicBLAS.TRANSPOSE;
-        mBLAS.SSYR2K(uplo, trans, alphaS, matrixAS, matrixBS, betaS, matrixCS);
-        matrixCRef.copyFrom(mBLASData.L3_sSYR2K_o_T);
-        verifyMatrix(matrixCRef, matrixCS, true);
-
-        mRS.finish();
-        checkError();
-    }
-
-    public void test_L3_DSYR2K_Correctness() {
-        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-
-        // Populate input allocations
-        Allocation matrixAD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dK, mBLASData.dN));
-        Allocation matrixBD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dK, mBLASData.dN));
-        Allocation matrixCD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dN));
-        matrixAD.copyFrom(mBLASData.L3_dSYR2K_A_nk);
-        matrixBD.copyFrom(mBLASData.L3_dSYR2K_B_nk);
-        matrixCD.copyFrom(mBLASData.L3_dSYR2K_C_nn);
-
-        // Default case: NO_TRANSPOSE
-        mBLAS.DSYR2K(uplo, trans, alphaD, matrixAD, matrixBD, betaD, matrixCD);
-        Allocation matrixCRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dN));
-        matrixCRef.copyFrom(mBLASData.L3_dSYR2K_o_N);
-        verifyMatrix(matrixCRef, matrixCD, true);
-
-        // Case: TRANSPOSE
-        matrixAD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dK));
-        matrixBD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dK));
-        matrixAD.copyFrom(mBLASData.L3_dSYR2K_A_kn);
-        matrixBD.copyFrom(mBLASData.L3_dSYR2K_B_kn);
-        // Reload matrix C, since it was overwritten by BLAS.
-        matrixCD.copyFrom(mBLASData.L3_dSYR2K_C_nn);
-
-        trans = ScriptIntrinsicBLAS.TRANSPOSE;
-        mBLAS.DSYR2K(uplo, trans, alphaD, matrixAD, matrixBD, betaD, matrixCD);
-        matrixCRef.copyFrom(mBLASData.L3_dSYR2K_o_T);
-        verifyMatrix(matrixCRef, matrixCD, true);
-
-        mRS.finish();
-        checkError();
-    }
-
-    public void test_L3_CSYR2K_Correctness() {
-        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-
-        // Populate input allocations
-        Allocation matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dK, mBLASData.dN));
-        Allocation matrixBC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dK, mBLASData.dN));
-        Allocation matrixCC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dN));
-        matrixAC.copyFrom(mBLASData.L3_cSYR2K_A_nk);
-        matrixBC.copyFrom(mBLASData.L3_cSYR2K_B_nk);
-        matrixCC.copyFrom(mBLASData.L3_cSYR2K_C_nn);
-
-        // Default case: NO_TRANSPOSE
-        mBLAS.CSYR2K(uplo, trans, alphaC, matrixAC, matrixBC, betaC, matrixCC);
-        Allocation matrixCRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dN));
-        matrixCRef.copyFrom(mBLASData.L3_cSYR2K_o_N);
-        verifyMatrix(matrixCRef, matrixCC, true);
-
-        // Case: TRANSPOSE
-        matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dK));
-        matrixBC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dK));
-        matrixAC.copyFrom(mBLASData.L3_cSYR2K_A_kn);
-        matrixBC.copyFrom(mBLASData.L3_cSYR2K_B_kn);
-        // Reload matrix C, since it was overwritten by BLAS.
-        matrixCC.copyFrom(mBLASData.L3_cSYR2K_C_nn);
-
-        trans = ScriptIntrinsicBLAS.TRANSPOSE;
-        mBLAS.CSYR2K(uplo, trans, alphaC, matrixAC, matrixBC, betaC, matrixCC);
-        matrixCRef.copyFrom(mBLASData.L3_cSYR2K_o_T);
-        verifyMatrix(matrixCRef, matrixCC, true);
-
-        mRS.finish();
-        checkError();
-    }
-
-    public void test_L3_ZSYR2K_Correctness() {
-        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-
-        // Populate input allocations
-        Allocation matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dK, mBLASData.dN));
-        Allocation matrixBZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dK, mBLASData.dN));
-        Allocation matrixCZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dN));
-        matrixAZ.copyFrom(mBLASData.L3_zSYR2K_A_nk);
-        matrixBZ.copyFrom(mBLASData.L3_zSYR2K_B_nk);
-        matrixCZ.copyFrom(mBLASData.L3_zSYR2K_C_nn);
-
-        // Default case: NO_TRANSPOSE
-        mBLAS.ZSYR2K(uplo, trans, alphaZ, matrixAZ, matrixBZ, betaZ, matrixCZ);
-        Allocation matrixCRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dN));
-        matrixCRef.copyFrom(mBLASData.L3_zSYR2K_o_N);
-        verifyMatrix(matrixCRef, matrixCZ, true);
-
-        // Case: TRANSPOSE
-        matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dK));
-        matrixBZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dK));
-        matrixAZ.copyFrom(mBLASData.L3_zSYR2K_A_kn);
-        matrixBZ.copyFrom(mBLASData.L3_zSYR2K_B_kn);
-        // Reload matrix C, since it was overwritten by BLAS.
-        matrixCZ.copyFrom(mBLASData.L3_zSYR2K_C_nn);
-
-        trans = ScriptIntrinsicBLAS.TRANSPOSE;
-        mBLAS.ZSYR2K(uplo, trans, alphaZ, matrixAZ, matrixBZ, betaZ, matrixCZ);
-        matrixCRef.copyFrom(mBLASData.L3_zSYR2K_o_T);
-        verifyMatrix(matrixCRef, matrixCZ, true);
-
-        mRS.finish();
-        checkError();
-    }
-
-
-    private boolean validateHER2K(Element e, int Uplo, int Trans, Allocation A, Allocation B, Allocation C) {
-        if (!validateUplo(Uplo)) {
-            return false;
-        }
-        if (!A.getType().getElement().isCompatible(e) ||
-            !B.getType().getElement().isCompatible(e) ||
-            !C.getType().getElement().isCompatible(e)) {
-            return false;
-        }
-        if (!validateConjTranspose(Trans)) {
-            return false;
-        }
-        int cdim = C.getType().getX();
-        if (cdim != C.getType().getY()) {
-            return false;
-        }
-        if (Trans == ScriptIntrinsicBLAS.NO_TRANSPOSE) {
-            if (A.getType().getY() != cdim) {
-                return false;
-            }
-        } else {
-            if (A.getType().getX() != cdim) {
-                return false;
-            }
-        }
-        if (A.getType().getX() != B.getType().getX() || A.getType().getY() != B.getType().getY()) {
-            return false;
-        }
-        return true;
-    }
-
-    private void xHER2K_API_test(int Uplo, int Trans, ArrayList<Allocation> mMatrix) {
-        for (Allocation matA : mMatrix) {
-            for (Allocation matB : mMatrix) {
-                for (Allocation matC : mMatrix) {
-                    Element elemA = matA.getType().getElement();
-                    if (validateHER2K(elemA, Uplo, Trans, matA, matB, matC)) {
-                        try {
-                            if (elemA.isCompatible(Element.F32_2(mRS))) {
-                                mBLAS.CHER2K(Uplo, Trans, alphaC, matA, matB, betaS, matC);
-                            } else if (elemA.isCompatible(Element.F64_2(mRS))) {
-                                mBLAS.ZHER2K(Uplo, Trans, alphaZ, matA, matB, betaD, matC);
-                            }
-                        } catch (RSRuntimeException e) {
-                            fail("should NOT throw RSRuntimeException");
-                        }
-                    } else {
-                        try {
-                            mBLAS.CHER2K(Uplo, Trans, alphaC, matA, matB, betaS, matC);
-                            fail("should throw RSRuntimeException for CHER2K");
-                        } catch (RSRuntimeException e) {
-                        }
-                        try {
-                            mBLAS.ZHER2K(Uplo, Trans, alphaZ, matA, matB, betaD, matC);
-                            fail("should throw RSRuntimeException for ZHER2K");
-                        } catch (RSRuntimeException e) {
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    public void L3_xHER2K_API(ArrayList<Allocation> mMatrix) {
-        for (int Uplo : mUplo) {
-            for (int Trans : mTranspose) {
-                xHER2K_API_test(Uplo, Trans, mMatrix);
-            }
-        }
-    }
-
-    public void test_L3_CHER2K_API() {
-        L3_xHER2K_API(mMatrixC);
-    }
-
-    public void test_L3_ZHER2K_API() {
-        L3_xHER2K_API(mMatrixZ);
-    }
-
-    public void test_L3_CHER2K_Correctness() {
-        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-
-        // Populate input allocations
-        Allocation matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dK, mBLASData.dN));
-        Allocation matrixBC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dK, mBLASData.dN));
-        Allocation matrixCC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dN));
-        matrixAC.copyFrom(mBLASData.L3_cHER2K_A_nk);
-        matrixBC.copyFrom(mBLASData.L3_cHER2K_B_nk);
-        matrixCC.copyFrom(mBLASData.L3_cHER2K_C_nn);
-
-        // Default case: NO_TRANSPOSE
-        mBLAS.CHER2K(uplo, trans, alphaC, matrixAC, matrixBC, betaS, matrixCC);
-        Allocation matrixCRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dN));
-        matrixCRef.copyFrom(mBLASData.L3_cHER2K_o_N);
-        verifyMatrix(matrixCRef, matrixCC, true);
-
-        // Case: TRANSPOSE
-        matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dK));
-        matrixBC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dK));
-        matrixAC.copyFrom(mBLASData.L3_cHER2K_A_kn);
-        matrixBC.copyFrom(mBLASData.L3_cHER2K_B_kn);
-        // Reload matrix C, since it was overwritten by BLAS.
-        matrixCC.copyFrom(mBLASData.L3_cHER2K_C_nn);
-
-        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
-        mBLAS.CHER2K(uplo, trans, alphaC, matrixAC, matrixBC, betaS, matrixCC);
-        matrixCRef.copyFrom(mBLASData.L3_cHER2K_o_H);
-        verifyMatrix(matrixCRef, matrixCC, true);
-
-        mRS.finish();
-        checkError();
-    }
-
-    public void test_L3_ZHER2K_Correctness() {
-        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-
-        // Populate input allocations
-        Allocation matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dK, mBLASData.dN));
-        Allocation matrixBZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dK, mBLASData.dN));
-        Allocation matrixCZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dN));
-        matrixAZ.copyFrom(mBLASData.L3_zHER2K_A_nk);
-        matrixBZ.copyFrom(mBLASData.L3_zHER2K_B_nk);
-        matrixCZ.copyFrom(mBLASData.L3_zHER2K_C_nn);
-
-        // Default case: NO_TRANSPOSE
-        mBLAS.ZHER2K(uplo, trans, alphaZ, matrixAZ, matrixBZ, betaD, matrixCZ);
-        Allocation matrixCRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dN));
-        matrixCRef.copyFrom(mBLASData.L3_zHER2K_o_N);
-        verifyMatrix(matrixCRef, matrixCZ, true);
-
-        // Case: TRANSPOSE
-        matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dK));
-        matrixBZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dK));
-        matrixAZ.copyFrom(mBLASData.L3_zHER2K_A_kn);
-        matrixBZ.copyFrom(mBLASData.L3_zHER2K_B_kn);
-        // Reload matrix C, since it was overwritten by BLAS.
-        matrixCZ.copyFrom(mBLASData.L3_zHER2K_C_nn);
-
-        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
-        mBLAS.ZHER2K(uplo, trans, alphaZ, matrixAZ, matrixBZ, betaD, matrixCZ);
-        matrixCRef.copyFrom(mBLASData.L3_zHER2K_o_H);
-        verifyMatrix(matrixCRef, matrixCZ, true);
-
-        mRS.finish();
-        checkError();
-    }
-
-
-    private boolean validateTRMM(Element e, int Side, int Uplo, int TransA, int Diag, Allocation A, Allocation B) {
-        if (!validateSide(Side)) {
-            return false;
-        }
-        if (!validateUplo(Uplo)) {
-            return false;
-        }
-        if (!validateTranspose(TransA)) {
-            return false;
-        }
-        if (!validateDiag(Diag)) {
-            return false;
-        }
-        int aM = -1, aN = -1, bM = -1, bN = -1;
-        if (!A.getType().getElement().isCompatible(e) ||
-            !B.getType().getElement().isCompatible(e)) {
-            return false;
-        }
-
-        aM = A.getType().getY();
-        aN = A.getType().getX();
-        if (aM != aN) {
-            return false;
-        }
-
-        bM = B.getType().getY();
-        bN = B.getType().getX();
-        if (Side == ScriptIntrinsicBLAS.LEFT) {
-            if (aN != bM) {
-                return false;
-            }
-        } else {
-            if (bN != aM) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    private void xTRMM_API_test(int Side, int Uplo, int TransA, int Diag, ArrayList<Allocation> mMatrix) {
-        for (Allocation matA : mMatrix) {
-            for (Allocation matB : mMatrix) {
-                Element elemA = matA.getType().getElement();
-                if (validateTRMM(elemA, Side, Uplo, TransA, Diag, matA, matB)) {
-                    try {
-                        if (elemA.isCompatible(Element.F32(mRS))) {
-                            mBLAS.STRMM(Side, Uplo, TransA, Diag, alphaS, matA, matB);
-                        } else if (elemA.isCompatible(Element.F64(mRS))) {
-                            mBLAS.DTRMM(Side, Uplo, TransA, Diag, alphaD, matA, matB);
-                        } else if (elemA.isCompatible(Element.F32_2(mRS))) {
-                            mBLAS.CTRMM(Side, Uplo, TransA, Diag, alphaC, matA, matB);
-                        } else if (elemA.isCompatible(Element.F64_2(mRS))) {
-                            mBLAS.ZTRMM(Side, Uplo, TransA, Diag, alphaZ, matA, matB);
-                        }
-                    } catch (RSRuntimeException e) {
-                        fail("should NOT throw RSRuntimeException");
-                    }
-                } else {
-                    try {
-                        mBLAS.STRMM(Side, Uplo, TransA, Diag, alphaS, matA, matB);
-                        fail("should throw RSRuntimeException for STRMM");
-                    } catch (RSRuntimeException e) {
-                    }
-                    try {
-                        mBLAS.DTRMM(Side, Uplo, TransA, Diag, alphaD, matA, matB);
-                        fail("should throw RSRuntimeException for DTRMM");
-                    } catch (RSRuntimeException e) {
-                    }
-                    try {
-                        mBLAS.CTRMM(Side, Uplo, TransA, Diag, alphaC, matA, matB);
-                        fail("should throw RSRuntimeException for CTRMM");
-                    } catch (RSRuntimeException e) {
-                    }
-                    try {
-                        mBLAS.ZTRMM(Side, Uplo, TransA, Diag, alphaZ, matA, matB);
-                        fail("should throw RSRuntimeException for ZTRMM");
-                    } catch (RSRuntimeException e) {
-                    }
-                }
-            }
-        }
-    }
-
-    public void L3_xTRMM_API(ArrayList<Allocation> mMatrix) {
-        for (int Side : mSide) {
-            for (int Uplo : mUplo) {
-                for (int TransA : mTranspose) {
-                    for (int Diag : mDiag) {
-                        xTRMM_API_test(Side, Uplo, TransA, Diag, mMatrix);
-                    }
-                }
-            }
-        }
-    }
-
-    public void test_L3_STRMM_API() {
-        L3_xTRMM_API(mMatrixS);
-    }
-
-    public void test_L3_DTRMM_API() {
-        L3_xTRMM_API(mMatrixD);
-    }
-
-    public void test_L3_CTRMM_API() {
-        L3_xTRMM_API(mMatrixC);
-    }
-
-    public void test_L3_ZTRMM_API() {
-        L3_xTRMM_API(mMatrixZ);
-    }
-
-
-    public void test_L3_STRMM_Correctness() {
-        int side = ScriptIntrinsicBLAS.LEFT;
-        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-        int diag = ScriptIntrinsicBLAS.NON_UNIT;
-
-        // Populate input allocations
-        Allocation matrixAS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dM, mBLASData.dM));
-        Allocation matrixBS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dM));
-        matrixAS.copyFrom(mBLASData.L3_sTRMM_A_mm);
-        matrixBS.copyFrom(mBLASData.L3_sTRMM_B_mn);
-
-        // Default case: LEFT, UPPER, NO_TRANSPOSE
-        mBLAS.STRMM(side, uplo, trans, diag, alphaS, matrixAS, matrixBS);
-        Allocation matrixBRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dM));
-        matrixBRef.copyFrom(mBLASData.L3_sTRMM_o_LUN);
-        verifyMatrix(matrixBRef, matrixBS);
-
-        // Case: RIGHT, LOWER, TRANSPOSE
-        matrixAS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dN));
-        matrixAS.copyFrom(mBLASData.L3_sTRMM_A_nn);
-        // Reload matrix B, since it was overwritten by BLAS.
-        matrixBS.copyFrom(mBLASData.L3_sTRMM_B_mn);
-
-        side = ScriptIntrinsicBLAS.RIGHT;
-        trans = ScriptIntrinsicBLAS.TRANSPOSE;
-        uplo = ScriptIntrinsicBLAS.LOWER;
-        mBLAS.STRMM(side, uplo, trans, diag, alphaS, matrixAS, matrixBS);
-        matrixBRef.copyFrom(mBLASData.L3_sTRMM_o_RLT);
-        verifyMatrix(matrixBRef, matrixBS);
-
-        mRS.finish();
-        checkError();
-    }
-
-    public void test_L3_DTRMM_Correctness() {
-        int side = ScriptIntrinsicBLAS.LEFT;
-        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-        int diag = ScriptIntrinsicBLAS.NON_UNIT;
-
-        // Populate input allocations
-        Allocation matrixAD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dM, mBLASData.dM));
-        Allocation matrixBD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dM));
-        matrixAD.copyFrom(mBLASData.L3_dTRMM_A_mm);
-        matrixBD.copyFrom(mBLASData.L3_dTRMM_B_mn);
-
-        // Default case: LEFT, UPPER, NO_TRANSPOSE
-        mBLAS.DTRMM(side, uplo, trans, diag, alphaD, matrixAD, matrixBD);
-        Allocation matrixBRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dM));
-        matrixBRef.copyFrom(mBLASData.L3_dTRMM_o_LUN);
-        verifyMatrix(matrixBRef, matrixBD);
-
-        // Case: RIGHT, LOWER, TRANSPOSE
-        matrixAD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dN));
-        matrixAD.copyFrom(mBLASData.L3_dTRMM_A_nn);
-        // Reload matrix B, since it was overwritten by BLAS.
-        matrixBD.copyFrom(mBLASData.L3_dTRMM_B_mn);
-
-        side = ScriptIntrinsicBLAS.RIGHT;
-        trans = ScriptIntrinsicBLAS.TRANSPOSE;
-        uplo = ScriptIntrinsicBLAS.LOWER;
-        mBLAS.DTRMM(side, uplo, trans, diag, alphaD, matrixAD, matrixBD);
-        matrixBRef.copyFrom(mBLASData.L3_dTRMM_o_RLT);
-        verifyMatrix(matrixBRef, matrixBD);
-
-        mRS.finish();
-        checkError();
-    }
-
-    public void test_L3_CTRMM_Correctness() {
-        int side = ScriptIntrinsicBLAS.LEFT;
-        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-        int diag = ScriptIntrinsicBLAS.NON_UNIT;
-
-        // Populate input allocations
-        Allocation matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dM, mBLASData.dM));
-        Allocation matrixBC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dM));
-        matrixAC.copyFrom(mBLASData.L3_cTRMM_A_mm);
-        matrixBC.copyFrom(mBLASData.L3_cTRMM_B_mn);
-
-        // Default case: LEFT, UPPER, NO_TRANSPOSE
-        mBLAS.CTRMM(side, uplo, trans, diag, alphaC, matrixAC, matrixBC);
-        Allocation matrixBRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dM));
-        matrixBRef.copyFrom(mBLASData.L3_cTRMM_o_LUN);
-        verifyMatrix(matrixBRef, matrixBC);
-
-        // Case: RIGHT, LOWER, TRANSPOSE
-        matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dN));
-        matrixAC.copyFrom(mBLASData.L3_cTRMM_A_nn);
-        // Reload matrix B, since it was overwritten by BLAS.
-        matrixBC.copyFrom(mBLASData.L3_cTRMM_B_mn);
-
-        side = ScriptIntrinsicBLAS.RIGHT;
-        trans = ScriptIntrinsicBLAS.TRANSPOSE;
-        uplo = ScriptIntrinsicBLAS.LOWER;
-        mBLAS.CTRMM(side, uplo, trans, diag, alphaC, matrixAC, matrixBC);
-        matrixBRef.copyFrom(mBLASData.L3_cTRMM_o_RLT);
-        verifyMatrix(matrixBRef, matrixBC);
-
-        mRS.finish();
-        checkError();
-    }
-
-    public void test_L3_ZTRMM_Correctness() {
-        int side = ScriptIntrinsicBLAS.LEFT;
-        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-        int diag = ScriptIntrinsicBLAS.NON_UNIT;
-
-        // Populate input allocations
-        Allocation matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dM, mBLASData.dM));
-        Allocation matrixBZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dM));
-        matrixAZ.copyFrom(mBLASData.L3_zTRMM_A_mm);
-        matrixBZ.copyFrom(mBLASData.L3_zTRMM_B_mn);
-
-        // Default case: LEFT, UPPER, NO_TRANSPOSE
-        mBLAS.ZTRMM(side, uplo, trans, diag, alphaZ, matrixAZ, matrixBZ);
-        Allocation matrixBRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dM));
-        matrixBRef.copyFrom(mBLASData.L3_zTRMM_o_LUN);
-        verifyMatrix(matrixBRef, matrixBZ);
-
-        // Case: RIGHT, LOWER, TRANSPOSE
-        matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dN));
-        matrixAZ.copyFrom(mBLASData.L3_zTRMM_A_nn);
-        // Reload matrix B, since it was overwritten by BLAS.
-        matrixBZ.copyFrom(mBLASData.L3_zTRMM_B_mn);
-
-        side = ScriptIntrinsicBLAS.RIGHT;
-        trans = ScriptIntrinsicBLAS.TRANSPOSE;
-        uplo = ScriptIntrinsicBLAS.LOWER;
-        mBLAS.ZTRMM(side, uplo, trans, diag, alphaZ, matrixAZ, matrixBZ);
-        matrixBRef.copyFrom(mBLASData.L3_zTRMM_o_RLT);
-        verifyMatrix(matrixBRef, matrixBZ);
-
-        mRS.finish();
-        checkError();
-    }
-
-
-    private boolean validateTRSM(Element e, int Side, int Uplo, int TransA, int Diag, Allocation A, Allocation B) {
-        int adim = -1, bM = -1, bN = -1;
-        if (!validateSide(Side)) {
-            return false;
-        }
-        if (!validateTranspose(TransA)) {
-            return false;
-        }
-        if (!validateUplo(Uplo)) {
-            return false;
-        }
-        if (!validateDiag(Diag)) {
-            return false;
-        }
-        if (!A.getType().getElement().isCompatible(e) ||
-            !B.getType().getElement().isCompatible(e)) {
-            return false;
-        }
-        adim = A.getType().getX();
-        if (adim != A.getType().getY()) {
-            // this may be unnecessary, the restriction could potentially be relaxed
-            // A needs to contain at least that symmetric matrix but could theoretically be larger
-            // for now we assume adapters are sufficient, will reevaluate in the future
-            return false;
-        }
-        bM = B.getType().getY();
-        bN = B.getType().getX();
-        if (Side == ScriptIntrinsicBLAS.LEFT) {
-            // A is M*M
-            if (adim != bM) {
-                return false;
-            }
-        } else {
-            // A is N*N
-            if (adim != bN) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    private void xTRSM_API_test(int Side, int Uplo, int TransA, int Diag, ArrayList<Allocation> mMatrix) {
-        for (Allocation matA : mMatrix) {
-            for (Allocation matB : mMatrix) {
-                Element elemA = matA.getType().getElement();
-                if (validateTRSM(elemA, Side, Uplo, TransA, Diag, matA, matB)) {
-                    try {
-                        if (elemA.isCompatible(Element.F32(mRS))) {
-                            mBLAS.STRSM(Side, Uplo, TransA, Diag, alphaS, matA, matB);
-                        } else if (elemA.isCompatible(Element.F64(mRS))) {
-                            mBLAS.DTRSM(Side, Uplo, TransA, Diag, alphaD, matA, matB);
-                        } else if (elemA.isCompatible(Element.F32_2(mRS))) {
-                            mBLAS.CTRSM(Side, Uplo, TransA, Diag, alphaC, matA, matB);
-                        } else if (elemA.isCompatible(Element.F64_2(mRS))) {
-                            mBLAS.ZTRSM(Side, Uplo, TransA, Diag, alphaZ, matA, matB);
-                        }
-                    } catch (RSRuntimeException e) {
-                        fail("should NOT throw RSRuntimeException");
-                    }
-                } else {
-                    try {
-                        mBLAS.STRSM(Side, Uplo, TransA, Diag, alphaS, matA, matB);
-                        fail("should throw RSRuntimeException for STRSM");
-                    } catch (RSRuntimeException e) {
-                    }
-                    try {
-                        mBLAS.DTRSM(Side, Uplo, TransA, Diag, alphaD, matA, matB);
-                        fail("should throw RSRuntimeException for DTRSM");
-                    } catch (RSRuntimeException e) {
-                    }
-                    try {
-                        mBLAS.CTRSM(Side, Uplo, TransA, Diag, alphaC, matA, matB);
-                        fail("should throw RSRuntimeException for CTRSM");
-                    } catch (RSRuntimeException e) {
-                    }
-                    try {
-                        mBLAS.ZTRSM(Side, Uplo, TransA, Diag, alphaZ, matA, matB);
-                        fail("should throw RSRuntimeException for ZTRSM");
-                    } catch (RSRuntimeException e) {
-                    }
-                }
-            }
-        }
-    }
-
-    public void L3_xTRSM_API(ArrayList<Allocation> mMatrix) {
-        for (int Side : mSide) {
-            for (int Uplo : mUplo) {
-                for (int TransA : mTranspose) {
-                    for (int Diag : mDiag) {
-                        xTRSM_API_test(Side, Uplo, TransA, Diag, mMatrix);
-                    }
-                }
-            }
-        }
-    }
-
-    public void test_L3_STRSM_API() {
-        L3_xTRSM_API(mMatrixS);
-    }
-
-    public void test_L3_DTRSM_API() {
-        L3_xTRSM_API(mMatrixD);
-    }
-
-    public void test_L3_CTRSM_API() {
-        L3_xTRSM_API(mMatrixC);
-    }
-
-    public void test_L3_ZTRSM_API() {
-        L3_xTRSM_API(mMatrixZ);
-    }
-
-    public void test_L3_STRSM_Correctness() {
-        int side = ScriptIntrinsicBLAS.LEFT;
-        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-        int diag = ScriptIntrinsicBLAS.NON_UNIT;
-
-        // Populate input allocations
-        Allocation matrixAS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dM, mBLASData.dM));
-        Allocation matrixBS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dM));
-        matrixAS.copyFrom(mBLASData.L3_sTRSM_A_mm);
-        matrixBS.copyFrom(mBLASData.L3_sTRSM_B_mn);
-
-        // Default case: LEFT, UPPER, NO_TRANSPOSE
-        mBLAS.STRSM(side, uplo, trans, diag, alphaS, matrixAS, matrixBS);
-        Allocation matrixBRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dM));
-        matrixBRef.copyFrom(mBLASData.L3_sTRSM_o_LUN);
-        verifyMatrix(matrixBRef, matrixBS);
-
-        // Case: RIGHT, LOWER, TRANSPOSE
-        matrixAS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dN));
-        matrixAS.copyFrom(mBLASData.L3_sTRSM_A_nn);
-        // Reload matrix B, since it was overwritten by BLAS.
-        matrixBS.copyFrom(mBLASData.L3_sTRSM_B_mn);
-
-        side = ScriptIntrinsicBLAS.RIGHT;
-        trans = ScriptIntrinsicBLAS.TRANSPOSE;
-        uplo = ScriptIntrinsicBLAS.LOWER;
-        mBLAS.STRSM(side, uplo, trans, diag, alphaS, matrixAS, matrixBS);
-        matrixBRef.copyFrom(mBLASData.L3_sTRSM_o_RLT);
-        verifyMatrix(matrixBRef, matrixBS);
-
-        mRS.finish();
-        checkError();
-    }
-
-    public void test_L3_DTRSM_Correctness() {
-        int side = ScriptIntrinsicBLAS.LEFT;
-        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-        int diag = ScriptIntrinsicBLAS.NON_UNIT;
-
-        // Populate input allocations
-        Allocation matrixAD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dM, mBLASData.dM));
-        Allocation matrixBD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dM));
-        matrixAD.copyFrom(mBLASData.L3_dTRSM_A_mm);
-        matrixBD.copyFrom(mBLASData.L3_dTRSM_B_mn);
-
-        // Default case: LEFT, UPPER, NO_TRANSPOSE
-        mBLAS.DTRSM(side, uplo, trans, diag, alphaD, matrixAD, matrixBD);
-        Allocation matrixBRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dM));
-        matrixBRef.copyFrom(mBLASData.L3_dTRSM_o_LUN);
-        verifyMatrix(matrixBRef, matrixBD);
-
-        // Case: RIGHT, LOWER, TRANSPOSE
-        matrixAD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dN));
-        matrixAD.copyFrom(mBLASData.L3_dTRSM_A_nn);
-        // Reload matrix B, since it was overwritten by BLAS.
-        matrixBD.copyFrom(mBLASData.L3_dTRSM_B_mn);
-
-        side = ScriptIntrinsicBLAS.RIGHT;
-        trans = ScriptIntrinsicBLAS.TRANSPOSE;
-        uplo = ScriptIntrinsicBLAS.LOWER;
-        mBLAS.DTRSM(side, uplo, trans, diag, alphaD, matrixAD, matrixBD);
-        matrixBRef.copyFrom(mBLASData.L3_dTRSM_o_RLT);
-        verifyMatrix(matrixBRef, matrixBD);
-
-        mRS.finish();
-        checkError();
-    }
-
-    public void test_L3_CTRSM_Correctness() {
-        int side = ScriptIntrinsicBLAS.LEFT;
-        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-        int diag = ScriptIntrinsicBLAS.NON_UNIT;
-
-        // Populate input allocations
-        Allocation matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dM, mBLASData.dM));
-        Allocation matrixBC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dM));
-        matrixAC.copyFrom(mBLASData.L3_cTRSM_A_mm);
-        matrixBC.copyFrom(mBLASData.L3_cTRSM_B_mn);
-
-        // Default case: LEFT, UPPER, NO_TRANSPOSE
-        mBLAS.CTRSM(side, uplo, trans, diag, alphaC, matrixAC, matrixBC);
-        Allocation matrixBRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dM));
-        matrixBRef.copyFrom(mBLASData.L3_cTRSM_o_LUN);
-        verifyMatrix(matrixBRef, matrixBC);
-
-        // Case: RIGHT, LOWER, TRANSPOSE
-        matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dN));
-        matrixAC.copyFrom(mBLASData.L3_cTRSM_A_nn);
-        // Reload matrix B, since it was overwritten by BLAS.
-        matrixBC.copyFrom(mBLASData.L3_cTRSM_B_mn);
-
-        side = ScriptIntrinsicBLAS.RIGHT;
-        trans = ScriptIntrinsicBLAS.TRANSPOSE;
-        uplo = ScriptIntrinsicBLAS.LOWER;
-        mBLAS.CTRSM(side, uplo, trans, diag, alphaC, matrixAC, matrixBC);
-        matrixBRef.copyFrom(mBLASData.L3_cTRSM_o_RLT);
-        verifyMatrix(matrixBRef, matrixBC);
-
-        mRS.finish();
-        checkError();
-    }
-
-    public void test_L3_ZTRSM_Correctness() {
-        int side = ScriptIntrinsicBLAS.LEFT;
-        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
-        int uplo = ScriptIntrinsicBLAS.UPPER;
-        int diag = ScriptIntrinsicBLAS.NON_UNIT;
-
-        // Populate input allocations
-        Allocation matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dM, mBLASData.dM));
-        Allocation matrixBZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dM));
-        matrixAZ.copyFrom(mBLASData.L3_zTRSM_A_mm);
-        matrixBZ.copyFrom(mBLASData.L3_zTRSM_B_mn);
-
-        // Default case: LEFT, UPPER, NO_TRANSPOSE
-        mBLAS.ZTRSM(side, uplo, trans, diag, alphaZ, matrixAZ, matrixBZ);
-        Allocation matrixBRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dM));
-        matrixBRef.copyFrom(mBLASData.L3_zTRSM_o_LUN);
-        verifyMatrix(matrixBRef, matrixBZ);
-
-        // Case: RIGHT, LOWER, TRANSPOSE
-        matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dN));
-        matrixAZ.copyFrom(mBLASData.L3_zTRSM_A_nn);
-        // Reload matrix B, since it was overwritten by BLAS.
-        matrixBZ.copyFrom(mBLASData.L3_zTRSM_B_mn);
-
-        side = ScriptIntrinsicBLAS.RIGHT;
-        trans = ScriptIntrinsicBLAS.TRANSPOSE;
-        uplo = ScriptIntrinsicBLAS.LOWER;
-        mBLAS.ZTRSM(side, uplo, trans, diag, alphaZ, matrixAZ, matrixBZ);
-        matrixBRef.copyFrom(mBLASData.L3_zTRSM_o_RLT);
-        verifyMatrix(matrixBRef, matrixBZ);
-
-        mRS.finish();
-        checkError();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/IntrinsicResize.java b/tests/tests/renderscript/src/android/renderscript/cts/IntrinsicResize.java
index c8b3640..9392db1 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/IntrinsicResize.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/IntrinsicResize.java
@@ -97,87 +97,87 @@
     }
 
 
-    public void test_U8_4_SCALE10_10_inSqure() {
+    public void test_U8_4_SCALE10_10_inSquare() {
         testResize(inX, inX, Element.DataType.UNSIGNED_8, 4, 1.f, 1.f);
         checkError();
     }
-    public void test_U8_3_SCALE10_10_inSqure() {
+    public void test_U8_3_SCALE10_10_inSquare() {
         testResize(inX, inX, Element.DataType.UNSIGNED_8, 3, 1.f, 1.f);
         checkError();
     }
-    public void test_U8_2_SCALE10_10_inSqure() {
+    public void test_U8_2_SCALE10_10_inSquare() {
         testResize(inX, inX, Element.DataType.UNSIGNED_8, 2, 1.f, 1.f);
         checkError();
     }
-    public void test_U8_1_SCALE10_10_inSqure() {
+    public void test_U8_1_SCALE10_10_inSquare() {
         testResize(inX, inX, Element.DataType.UNSIGNED_8, 1, 1.f, 1.f);
         checkError();
     }
 
-    public void test_U8_4_SCALE20_20_inSqure() {
+    public void test_U8_4_SCALE20_20_inSquare() {
         testResize(inX, inX, Element.DataType.UNSIGNED_8, 4, 2.f, 2.f);
         checkError();
     }
-    public void test_U8_3_SCALE20_20_inSqure() {
+    public void test_U8_3_SCALE20_20_inSquare() {
         testResize(inX, inX, Element.DataType.UNSIGNED_8, 3, 2.f, 2.f);
         checkError();
     }
-    public void test_U8_2_SCALE20_20_inSqure() {
+    public void test_U8_2_SCALE20_20_inSquare() {
         testResize(inX, inX, Element.DataType.UNSIGNED_8, 2, 2.f, 2.f);
         checkError();
     }
-    public void test_U8_1_SCALE20_20_inSqure() {
+    public void test_U8_1_SCALE20_20_inSquare() {
         testResize(inX, inX, Element.DataType.UNSIGNED_8, 1, 2.f, 2.f);
         checkError();
     }
 
-    public void test_U8_4_SCALE05_20_inSqure() {
+    public void test_U8_4_SCALE05_20_inSquare() {
         testResize(inX, inX, Element.DataType.UNSIGNED_8, 4, 0.5f, 2.f);
         checkError();
     }
-    public void test_U8_3_SCALE05_20_inSqure() {
+    public void test_U8_3_SCALE05_20_inSquare() {
         testResize(inX, inX, Element.DataType.UNSIGNED_8, 3, 0.5f, 2.f);
         checkError();
     }
-    public void test_U8_2_SCALE05_20_inSqure() {
+    public void test_U8_2_SCALE05_20_inSquare() {
         testResize(inX, inX, Element.DataType.UNSIGNED_8, 2, 0.5f, 2.f);
         checkError();
     }
-    public void test_U8_1_SCALE05_20_inSqure() {
+    public void test_U8_1_SCALE05_20_inSquare() {
         testResize(inX, inX, Element.DataType.UNSIGNED_8, 1, 0.5f, 2.f);
         checkError();
     }
 
-    public void test_U8_4_SCALE20_05_inSqure() {
+    public void test_U8_4_SCALE20_05_inSquare() {
         testResize(inX, inX, Element.DataType.UNSIGNED_8, 4, 2.f, 0.5f);
         checkError();
     }
-    public void test_U8_3_SCALE20_05_inSqure() {
+    public void test_U8_3_SCALE20_05_inSquare() {
         testResize(inX, inX, Element.DataType.UNSIGNED_8, 3, 2.f, 0.5f);
         checkError();
     }
-    public void test_U8_2_SCALE20_05_inSqure() {
+    public void test_U8_2_SCALE20_05_inSquare() {
         testResize(inX, inX, Element.DataType.UNSIGNED_8, 2, 2.f, 0.5f);
         checkError();
     }
-    public void test_U8_1_SCALE20_05_inSqure() {
+    public void test_U8_1_SCALE20_05_inSquare() {
         testResize(inX, inX, Element.DataType.UNSIGNED_8, 1, 2.f, 0.5f);
         checkError();
     }
 
-    public void test_U8_4_SCALE05_05_inSqure() {
+    public void test_U8_4_SCALE05_05_inSquare() {
         testResize(inX, inX, Element.DataType.UNSIGNED_8, 4, 0.5f, 0.5f);
         checkError();
     }
-    public void test_U8_3_SCALE05_05_inSqure() {
+    public void test_U8_3_SCALE05_05_inSquare() {
         testResize(inX, inX, Element.DataType.UNSIGNED_8, 3, 0.5f, 0.5f);
         checkError();
     }
-    public void test_U8_2_SCALE05_05_inSqure() {
+    public void test_U8_2_SCALE05_05_inSquare() {
         testResize(inX, inX, Element.DataType.UNSIGNED_8, 2, 0.5f, 0.5f);
         checkError();
     }
-    public void test_U8_1_SCALE05_05_inSqure() {
+    public void test_U8_1_SCALE05_05_inSquare() {
         testResize(inX, inX, Element.DataType.UNSIGNED_8, 1, 0.5f, 0.5f);
         checkError();
     }
@@ -268,87 +268,87 @@
     }
 
 
-    public void test_F32_4_SCALE10_10_inSqure() {
+    public void test_F32_4_SCALE10_10_inSquare() {
         testResize(inX, inX, Element.DataType.FLOAT_32, 4, 1.f, 1.f);
         checkError();
     }
-    public void test_F32_3_SCALE10_10_inSqure() {
+    public void test_F32_3_SCALE10_10_inSquare() {
         testResize(inX, inX, Element.DataType.FLOAT_32, 3, 1.f, 1.f);
         checkError();
     }
-    public void test_F32_2_SCALE10_10_inSqure() {
+    public void test_F32_2_SCALE10_10_inSquare() {
         testResize(inX, inX, Element.DataType.FLOAT_32, 2, 1.f, 1.f);
         checkError();
     }
-    public void test_F32_1_SCALE10_10_inSqure() {
+    public void test_F32_1_SCALE10_10_inSquare() {
         testResize(inX, inX, Element.DataType.FLOAT_32, 1, 1.f, 1.f);
         checkError();
     }
 
-    public void test_F32_4_SCALE20_20_inSqure() {
+    public void test_F32_4_SCALE20_20_inSquare() {
         testResize(inX, inX, Element.DataType.FLOAT_32, 4, 2.f, 2.f);
         checkError();
     }
-    public void test_F32_3_SCALE20_20_inSqure() {
+    public void test_F32_3_SCALE20_20_inSquare() {
         testResize(inX, inX, Element.DataType.FLOAT_32, 3, 2.f, 2.f);
         checkError();
     }
-    public void test_F32_2_SCALE20_20_inSqure() {
+    public void test_F32_2_SCALE20_20_inSquare() {
         testResize(inX, inX, Element.DataType.FLOAT_32, 2, 2.f, 2.f);
         checkError();
     }
-    public void test_F32_1_SCALE20_20_inSqure() {
+    public void test_F32_1_SCALE20_20_inSquare() {
         testResize(inX, inX, Element.DataType.FLOAT_32, 1, 2.f, 2.f);
         checkError();
     }
 
-    public void test_F32_4_SCALE05_20_inSqure() {
+    public void test_F32_4_SCALE05_20_inSquare() {
         testResize(inX, inX, Element.DataType.FLOAT_32, 4, 0.5f, 2.f);
         checkError();
     }
-    public void test_F32_3_SCALE05_20_inSqure() {
+    public void test_F32_3_SCALE05_20_inSquare() {
         testResize(inX, inX, Element.DataType.FLOAT_32, 3, 0.5f, 2.f);
         checkError();
     }
-    public void test_F32_2_SCALE05_20_inSqure() {
+    public void test_F32_2_SCALE05_20_inSquare() {
         testResize(inX, inX, Element.DataType.FLOAT_32, 2, 0.5f, 2.f);
         checkError();
     }
-    public void test_F32_1_SCALE05_20_inSqure() {
+    public void test_F32_1_SCALE05_20_inSquare() {
         testResize(inX, inX, Element.DataType.FLOAT_32, 1, 0.5f, 2.f);
         checkError();
     }
 
-    public void test_F32_4_SCALE20_05_inSqure() {
+    public void test_F32_4_SCALE20_05_inSquare() {
         testResize(inX, inX, Element.DataType.FLOAT_32, 4, 2.f, 0.5f);
         checkError();
     }
-    public void test_F32_3_SCALE20_05_inSqure() {
+    public void test_F32_3_SCALE20_05_inSquare() {
         testResize(inX, inX, Element.DataType.FLOAT_32, 3, 2.f, 0.5f);
         checkError();
     }
-    public void test_F32_2_SCALE20_05_inSqure() {
+    public void test_F32_2_SCALE20_05_inSquare() {
         testResize(inX, inX, Element.DataType.FLOAT_32, 2, 2.f, 0.5f);
         checkError();
     }
-    public void test_F32_1_SCALE20_05_inSqure() {
+    public void test_F32_1_SCALE20_05_inSquare() {
         testResize(inX, inX, Element.DataType.FLOAT_32, 1, 2.f, 0.5f);
         checkError();
     }
 
-    public void test_F32_4_SCALE05_05_inSqure() {
+    public void test_F32_4_SCALE05_05_inSquare() {
         testResize(inX, inX, Element.DataType.FLOAT_32, 4, 0.5f, 0.5f);
         checkError();
     }
-    public void test_F32_3_SCALE05_05_inSqure() {
+    public void test_F32_3_SCALE05_05_inSquare() {
         testResize(inX, inX, Element.DataType.FLOAT_32, 3, 0.5f, 0.5f);
         checkError();
     }
-    public void test_F32_2_SCALE05_05_inSqure() {
+    public void test_F32_2_SCALE05_05_inSquare() {
         testResize(inX, inX, Element.DataType.FLOAT_32, 2, 0.5f, 0.5f);
         checkError();
     }
-    public void test_F32_1_SCALE05_05_inSqure() {
+    public void test_F32_1_SCALE05_05_inSquare() {
         testResize(inX, inX, Element.DataType.FLOAT_32, 1, 0.5f, 0.5f);
         checkError();
     }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/RSBaseCompute.java b/tests/tests/renderscript/src/android/renderscript/cts/RSBaseCompute.java
index 0ba8248..717c4a0 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/RSBaseCompute.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/RSBaseCompute.java
@@ -80,6 +80,8 @@
                 element = Element.F64(rs);
             } else if (dataType == Element.DataType.FLOAT_32) {
                 element = Element.F32(rs);
+            } else if (dataType == Element.DataType.FLOAT_16) {
+                element = Element.F16(rs);
             } else if (dataType == Element.DataType.SIGNED_64) {
                 element = Element.I64(rs);
             } else if (dataType == Element.DataType.UNSIGNED_64) {
@@ -125,6 +127,12 @@
             float max = 4.0f * (float) Math.PI;
             RSUtils.genRandomFloats(seed, min, max, inArray, includeExtremes);
             alloc.copy1DRangeFrom(0, INPUTSIZE, inArray);
+        } else if (dataType == Element.DataType.FLOAT_16) {
+            short[] inArray = new short[INPUTSIZE * width];
+            double min = -4.0 * Math.PI;
+            double max = 4.0 * Math.PI;
+            RSUtils.genRandomFloat16s(seed, min, max, inArray, includeExtremes);
+            alloc.copyFrom(inArray);
         } else if (dataType == Element.DataType.SIGNED_64) {
             long[] inArray = new long[INPUTSIZE * width];
             RSUtils.genRandomLongs(seed, inArray, true, 63);
@@ -177,6 +185,10 @@
             float[] inArray = new float[INPUTSIZE * width];
             RSUtils.genRandomFloats(seed, (float) minValue, (float) maxValue, inArray, false);
             alloc.copy1DRangeFrom(0, INPUTSIZE, inArray);
+        } else if (dataType == Element.DataType.FLOAT_16) {
+            short[] inArray = new short[INPUTSIZE * width];
+            RSUtils.genRandomFloat16s(seed, minValue, maxValue, inArray, false);
+            alloc.copy1DRangeFrom(0, INPUTSIZE, inArray);
         } else {
             android.util.Log.e("RenderscriptCTS",
                                "Don't know how to create a random float allocation for " +
@@ -256,6 +268,22 @@
             }
             minAlloc.copyFrom(minArray);
             maxAlloc.copyFrom(maxArray);
+        } else if (dataType == Element.DataType.FLOAT_16) {
+            short[] minArray = new short[size];
+            short[] maxArray = new short[size];
+            minAlloc.copyTo(minArray);
+            maxAlloc.copyTo(maxArray);
+            for (int i = 0; i < size; i++) {
+                double minValue = Float16Utils.convertFloat16ToDouble(minArray[i]);
+                double maxValue = Float16Utils.convertFloat16ToDouble(maxArray[i]);
+                if (minValue > maxValue) {
+                    short temp = minArray[i];
+                    minArray[i] = maxArray[i];
+                    maxArray[i] = temp;
+                }
+            }
+            minAlloc.copyFrom(minArray);
+            maxAlloc.copyFrom(maxArray);
         } else if (dataType == Element.DataType.SIGNED_64) {
             long[] minArray = new long[size];
             long[] maxArray = new long[size];
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/RSUtils.java b/tests/tests/renderscript/src/android/renderscript/cts/RSUtils.java
index 6038d90..8704dff 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/RSUtils.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/RSUtils.java
@@ -26,6 +26,11 @@
  * This class supplies some utils for renderscript tests
  */
 public class RSUtils {
+    public static final short FLOAT16_POSITIVE_INFINITY = (short) 0x7c00;
+    public static final short FLOAT16_NEGATIVE_INFINITY = (short) 0xfc00;
+    public static final short FLOAT16_MIN_NORMAL        = (short) 0x0400;  // 0.00006103516
+    public static final short FLOAT16_MAX_VALUE         = (short) 0x7bff;  // 65504
+
     private static final double[] sInterestingDoubles = {
         0.0,
         1.0,
@@ -41,6 +46,23 @@
         -Math.PI * 2.0,
     };
 
+    // Constants E, PI etc. are set to their nearest representations in Float16.
+    private static final short[] sInterestingFloat16s = {
+        (short) 0x0, // zero
+        (short) 0x3c00, // one
+        (short) 0x4170, // E, 2.71875000000
+        (short) 0x4248, // PI, 3.14062500000
+        (short) 0x3e48, // PI / 2, 1.57031250000
+        (short) 0x4648, // PI * 2, 6.28125000000
+
+        (short) 0x8000, // negative zero
+        (short) 0xbc00, // negative one
+        (short) 0xc170, // -E, -2.71875000000
+        (short) 0xc248, // -PI, -3.14062500000
+        (short) 0xbe48, // -PI / 2, -1.57031250000
+        (short) 0xc648, // -PI * 2, -6.28125000000
+    };
+
     /**
      * Fills the array with random doubles.  Values will be between min (inclusive) and
      * max (inclusive).
@@ -143,6 +165,89 @@
         }
     }
 
+    public static void genRandomFloat16s(long seed, double minDoubleValue, double maxDoubleValue,
+            short array[], boolean includeExtremes) {
+
+        // Ensure that requests for random Float16s span a reasnoable range.
+        if (maxDoubleValue - minDoubleValue <= 1.) {
+            throw new RSRuntimeException("Unexpected: Range is too small");
+        }
+
+        boolean includeNegatives = false;
+
+        // Identify a range of 'short' values from the input range of 'double' If either
+        // minValueInHalf or maxValueInHalf is +/- infinity, use MAX_VALUE with appropriate sign
+        // instead.  The extreme values will get included if includeExtremes flag is set.
+        double minValueInHalf = Float16Utils.roundToFloat16(minDoubleValue)[1];
+        double maxValueInHalf = Float16Utils.roundToFloat16(maxDoubleValue)[0];
+
+        if (Double.isInfinite(minValueInHalf)) {
+            minValueInHalf = Math.copySign(Float16Utils.MAX_VALUE, minValueInHalf);
+        }
+        if (Double.isInfinite(maxValueInHalf)) {
+            maxValueInHalf = Math.copySign(Float16Utils.MAX_VALUE, maxValueInHalf);
+        }
+
+        short min = Float16Utils.convertDoubleToFloat16(minValueInHalf);
+        short max = Float16Utils.convertDoubleToFloat16(maxValueInHalf);
+
+        // If range spans across zero, set the range to be entirely positive and set
+        // includeNegatives to true.  In this scenario, the upper bound is set to the larger of
+        // maxValue and abs(minValue).  The lower bound is FLOAT16_MIN_NORMAL.
+        if (minDoubleValue < 0. && maxDoubleValue > 0.) {
+            includeNegatives = true;
+            min = FLOAT16_MIN_NORMAL;
+
+            // If abs(minDoubleValue) is greater than maxDoubleValue, pick abs(minValue) as the
+            // upper bound.
+            // TODO Update this function to generate random float16s exactly between minDoubleValue
+            // and maxDoubleValue.
+            if (Math.abs(minDoubleValue) > maxDoubleValue) {
+                max = (short) (0x7fff & min);
+            }
+        } else if (maxDoubleValue < 0.) {
+            throw new RSRuntimeException("Unexpected: Range is entirely negative: " +
+                Double.toString(minDoubleValue) + " to " + Double.toString(maxDoubleValue));
+        }
+
+        // If min is 0 or subnormal, set it to FLOAT16_MIN_NORMAL
+        if (Float16Utils.isFloat16Zero(min) || Float16Utils.isFloat16SubNormal(min)) {
+            min = FLOAT16_MIN_NORMAL;
+        }
+
+        Random r = new Random(seed);
+        short range = (short) (max - min + 1);
+        for (int i = 0; i < array.length; i ++) {
+            array[i] = (short) (min + r.nextInt(range));
+        }
+        array[r.nextInt(array.length)] = min;
+        array[r.nextInt(array.length)] = max;
+
+        // Negate approximately half of the elements.
+        if (includeNegatives) {
+            for (int i = 0; i < array.length; i ++) {
+                if (r.nextBoolean()) {
+                    array[i] = (short) (0x8000 | array[i]);
+                }
+            }
+        }
+
+        for (short s : sInterestingFloat16s) {
+            if (!includeNegatives && s < 0)
+                continue;
+            array[r.nextInt(array.length)] = s;
+        }
+        if (includeExtremes) {
+            array[r.nextInt(array.length)] = (short) 0x7c01; // NaN
+            array[r.nextInt(array.length)] = FLOAT16_POSITIVE_INFINITY;
+            array[r.nextInt(array.length)] = FLOAT16_NEGATIVE_INFINITY;
+            array[r.nextInt(array.length)] = FLOAT16_MIN_NORMAL;
+            array[r.nextInt(array.length)] = FLOAT16_MAX_VALUE;
+            array[r.nextInt(array.length)] = (short) 0x8400; // -MIN_NORMAL, -0.00006103516
+            array[r.nextInt(array.length)] = (short) 0xfbff; // -MAX_VALUE, -65504
+        }
+    }
+
     /**
      * Fills the array with random ints.  Values will be between min (inclusive) and
      * max (inclusive).
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/ReduceTest.java b/tests/tests/renderscript/src/android/renderscript/cts/ReduceTest.java
new file mode 100644
index 0000000..71d5549
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/ReduceTest.java
@@ -0,0 +1,765 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.renderscript.cts;
+
+import android.renderscript.*;
+import java.lang.Float;
+import java.lang.Math;
+import java.util.Arrays;
+import java.util.Random;
+
+public class ReduceTest extends RSBaseCompute {
+    private ScriptC_reduce mScript;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mScript = new ScriptC_reduce(mRS);
+        mScript.set_negInf(Float.NEGATIVE_INFINITY);
+        mScript.set_posInf(Float.POSITIVE_INFINITY);
+        mScript.invoke_setInfsHalf(RSUtils.FLOAT16_NEGATIVE_INFINITY, RSUtils.FLOAT16_POSITIVE_INFINITY);
+    }
+
+    ///////////////////////////////////////////////////////////////////
+
+    private void assertEquals(final float[] javaRslt, final float[] rsRslt) {
+        assertEquals("length", javaRslt.length, rsRslt.length);
+        for (int i = 0; i < javaRslt.length; ++i)
+            assertEquals(String.valueOf(i), javaRslt[i], rsRslt[i]);
+    }
+
+    private void assertEquals(final short[] javaRslt, final short[] rsRslt) {
+        assertEquals("length", javaRslt.length, rsRslt.length);
+        for (int i = 0; i < javaRslt.length; ++i)
+            assertEquals(String.valueOf(i), javaRslt[i], rsRslt[i]);
+    }
+
+    private void assertEquals(final Short2[] javaRslt, final Short2[] rsRslt) {
+        assertEquals("length", javaRslt.length, rsRslt.length);
+        for (int i = 0; i < javaRslt.length; ++i)
+            assertEquals(String.valueOf(i), javaRslt[i], rsRslt[i]);
+    }
+
+    private void assertEquals(final String msg, final Float2 javaRslt, final Float2 rsRslt) {
+        assertEquals(msg + "(x)", javaRslt.x, rsRslt.x);
+        assertEquals(msg + "(y)", javaRslt.y, rsRslt.y);
+    }
+
+    private void assertEquals(final Float2 javaRslt, final Float2 rsRslt) {
+        assertEquals("", javaRslt, rsRslt);
+    }
+
+    private void assertEquals(final String msg, final Int2 javaRslt, final Int2 rsRslt) {
+        assertEquals(msg + "(x)", javaRslt.x, rsRslt.x);
+        assertEquals(msg + "(y)", javaRslt.y, rsRslt.y);
+    }
+
+    private void assertEquals(final Int2 javaRslt, final Int2 rsRslt) {
+        assertEquals("", javaRslt, rsRslt);
+    }
+
+    private void assertEquals(final String msg, final Short2 javaRslt, final Short2 rsRslt) {
+        assertEquals(msg + "(x)", javaRslt.x, rsRslt.x);
+        assertEquals(msg + "(y)", javaRslt.y, rsRslt.y);
+    }
+
+    private void assertEquals(final Short2 javaRslt, final Short2 rsRslt) {
+        assertEquals("", javaRslt, rsRslt);
+    }
+
+    // Create a zero-initialized Allocation.
+    // 1D: ylen == 0, zlen == 0
+    // 2D: ylen != 0, zlen == 0
+    // 3D: ylen != 0, zlen != 0
+    private Allocation createInputAllocation(Element elt, int xlen, int ylen, int zlen) {
+        assertTrue(xlen >= 1);
+        assertTrue((zlen==0) || (ylen >= 1));
+
+        Allocation alloc;
+
+        if (zlen != 0)
+            alloc = Allocation.createTyped(mRS, Type.createXYZ(mRS, elt, xlen, ylen, zlen));
+        else if (ylen != 0)
+            alloc = Allocation.createTyped(mRS, Type.createXY(mRS, elt, xlen, ylen));
+        else
+            alloc = Allocation.createSized(mRS, elt, xlen);
+        if (elt.getVectorSize() == 3)
+            alloc.setAutoPadding(true);
+
+        byte[] init = new byte[alloc.getBytesSize()];
+        Arrays.fill(init, (byte)0);
+        alloc.copyFromUnchecked(init);
+        return alloc;
+    }
+
+    // Create an arry of zero-initialized Allocations of various dimensions --
+    // all possible 1D, 2D, and 3D Allocations where no dimension exceeds max.
+    private Allocation[] createInputAllocations(Element elt, int max) {
+        // 1D Allocations: { 1..max }
+        // 2D Allocations: { 1..max }^2
+        // 3D Allocations: { 1..max }^3
+        final int numAllocs = max + max*max + max*max*max;
+        Allocation alloc[] = new Allocation[numAllocs];
+        int count = 0;
+        for (int xlen = 1; xlen <= max; ++xlen) {
+            for (int ylen = 0; ylen <= max; ++ylen) {
+                final int zlim = ((ylen!=0) ? max : 0);
+                for (int zlen = 0; zlen <= zlim; ++zlen)
+                    alloc[count++] = createInputAllocation(elt, xlen, ylen, zlen);
+            }
+        }
+        assertTrue(count == numAllocs);
+        return alloc;
+    }
+
+    private static byte[] createInputArrayByte(int len, int seed) {
+        byte[] array = new byte[len];
+        (new Random(seed)).nextBytes(array);
+        return array;
+    }
+
+    private static short[] createInputArrayHalf(int len, int seed) {
+        short[] array = new short[len];
+        RSUtils.genRandomFloat16s(seed, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, array,
+            false);
+        return array;
+    }
+
+    private static float[] createInputArrayFloat(int len, int seed) {
+        Random rand = new Random(seed);
+        float[] array = new float[len];
+        for (int i = 0; i < len; ++i)
+            array[i] = rand.nextFloat();
+        return array;
+    }
+
+    private static int[] createInputArrayInt(int len, int seed) {
+        Random rand = new Random(seed);
+        int[] array = new int[len];
+        for (int i = 0; i < len; ++i)
+            array[i] = rand.nextInt();
+        return array;
+    }
+
+    private static int[] createInputArrayInt(int len, int seed, int eltRange) {
+        Random rand = new Random(seed);
+        int[] array = new int[len];
+        for (int i = 0; i < len; ++i)
+            array[i] = rand.nextInt(eltRange);
+        return array;
+    }
+
+    ///////////////////////////////////////////////////////////////////
+
+    private int addint(final int[] input) {
+        int rslt = 0;
+        for (int idx = 0; idx < input.length; ++idx)
+            rslt += input[idx];
+        return rslt;
+    }
+
+    public void testAddInt1D() {
+        final int[] input = createInputArrayInt(100000, 0, 1 << 13);
+
+        final int javaRslt = addint(input);
+        final int rsRslt = mScript.reduce_addint(input).get();
+
+        assertEquals(javaRslt, rsRslt);
+    }
+
+    public void testAddInt2D() {
+        final int dimX = 450, dimY = 225;
+
+        final int[] inputArray = createInputArrayInt(dimX * dimY, 1, 1 << 13);
+        Type.Builder typeBuilder = new Type.Builder(mRS, Element.I32(mRS));
+        typeBuilder.setX(dimX).setY(dimY);
+        Allocation inputAllocation = Allocation.createTyped(mRS, typeBuilder.create());
+        inputAllocation.copy2DRangeFrom(0, 0, dimX, dimY, inputArray);
+
+        final int javaRslt = addint(inputArray);
+        final int rsRslt = mScript.reduce_addint(inputAllocation).get();
+
+        assertEquals(javaRslt, rsRslt);
+    }
+
+    ///////////////////////////////////////////////////////////////////
+
+    private Int2 findMinAndMax(final float[] input) {
+        float minVal = Float.POSITIVE_INFINITY;
+        int minIdx = -1;
+        float maxVal = Float.NEGATIVE_INFINITY;
+        int maxIdx = -1;
+
+        for (int idx = 0; idx < input.length; ++idx) {
+            if (input[idx] < minVal) {
+                minVal = input[idx];
+                minIdx = idx;
+            }
+            if (input[idx] > maxVal) {
+                maxVal = input[idx];
+                maxIdx = idx;
+            }
+        }
+
+        return new Int2(minIdx, maxIdx);
+    }
+
+    public void testFindMinAndMax() {
+        final float[] input = createInputArrayFloat(100000, 4);
+
+        final Int2 javaRslt = findMinAndMax(input);
+        final Int2 rsRslt = mScript.reduce_findMinAndMax(input).get();
+
+        // Note that the Java and RenderScript algorithms are not
+        // guaranteed to find the same cells -- but they should
+        // find cells of the same value.
+        final Float2 javaVal = new Float2(input[javaRslt.x], input[javaRslt.y]);
+        final Float2 rsVal = new Float2(input[rsRslt.x], input[rsRslt.y]);
+
+        assertEquals(javaVal, rsVal);
+    }
+
+    ///////////////////////////////////////////////////////////////////
+
+    private Short2 findMinAndMaxHalf(final short[] inputArray) {
+        Allocation inputAllocation = Allocation.createSized(mRS, Element.F16(mRS), inputArray.length);
+        inputAllocation.copyFrom(inputArray);
+
+        Allocation outputAllocation = Allocation.createSized(mRS, Element.F16_2(mRS), 1);
+
+        mScript.invoke_findMinAndMaxHalf(outputAllocation, inputAllocation);
+
+        short[] outputArray = new short[2];
+        outputAllocation.copyTo(outputArray);
+        return new Short2(outputArray[0], outputArray[1]);
+    }
+
+    private short[] findMinAndMaxHalfIntoArray(final short[] inputArray) {
+        final Short2 vectorResult = findMinAndMaxHalf(inputArray);
+        final short[] arrayResult = new short[] { vectorResult.x, vectorResult.y };
+        return arrayResult;
+    }
+
+    public void testFindMinAndMaxHalf() {
+        // fewer members in the array than there are distinct half values
+        final short[] input = createInputArrayHalf(1000, 23);
+
+        // test Short2 result
+        final Short2 javaRslt = findMinAndMaxHalf(input);
+        final Short2 rsRslt = mScript.reduce_findMinAndMaxHalf(input).get();
+        assertEquals(javaRslt, rsRslt);
+
+        // test short[2] result
+        final short[] javaRsltIntoArray = findMinAndMaxHalfIntoArray(input);
+        final short[] rsRsltIntoArray = mScript.reduce_findMinAndMaxHalfIntoArray(input).get();
+        assertEquals(javaRsltIntoArray, rsRsltIntoArray);
+    }
+
+    ///////////////////////////////////////////////////////////////////
+
+    // The input is a flattened representation of an array of 2-vector
+    private Short2[] findMinAndMaxHalf2(final short[] inputArray) {
+        assertEquals(inputArray.length % 2, 0);
+
+        Allocation inputAllocation = Allocation.createSized(mRS, Element.F16_2(mRS), inputArray.length / 2);
+        inputAllocation.copyFrom(inputArray);
+
+        Allocation outputAllocation = Allocation.createSized(mRS, Element.F16_2(mRS), 2);
+
+        mScript.invoke_findMinAndMaxHalf2(outputAllocation, inputAllocation);
+
+        short[] outputArray = new short[4];
+        outputAllocation.copyTo(outputArray);
+        return new Short2[] { new Short2(outputArray[0], outputArray[1]),
+                              new Short2(outputArray[2], outputArray[3]) };
+    }
+
+    public void testFindMinAndMaxHalf2() {
+        // fewer members in the array than there are distinct half values
+        final short[] input = createInputArrayHalf(1000, 25);
+
+        final Short2[] javaRslt = findMinAndMaxHalf2(input);
+        final Short2[] rsRslt = mScript.reduce_findMinAndMaxHalf2(input).get();
+
+        assertEquals(javaRslt, rsRslt);
+    }
+
+    ///////////////////////////////////////////////////////////////////
+
+    // Both the input and the result are linearized representations of 2x2 matrices.
+    private float[] findMinMat(final float[] inputArray) {
+        float[] result = new float[4];
+        for (int i = 0; i < 4; ++i)
+            result[i] = Float.POSITIVE_INFINITY;
+
+        for (int i = 0; i < inputArray.length; ++i)
+            result[i % 4] = Math.min(result[i % 4], inputArray[i]);
+
+        return result;
+    }
+
+    public void testFindMinMat() {
+        final int length = 100000;
+
+        final float[] inputArray = createInputArrayFloat(4 * length, 24);
+        Allocation inputAllocation = Allocation.createSized(mRS, Element.MATRIX_2X2(mRS), length);
+        inputAllocation.copyFromUnchecked(inputArray);
+
+        final float[] javaRslt = findMinMat(inputArray);
+        final float[] rsRslt = mScript.reduce_findMinMat(inputAllocation).get();
+
+        assertEquals(javaRslt, rsRslt);
+    }
+
+    ///////////////////////////////////////////////////////////////////
+
+    // Both the input and the result are linearized representations of 2x2 matrices.
+    private float[] findMinAndMaxMat(final float[] inputArray) {
+        float[] result = new float[8];
+        for (int i = 0; i < 4; ++i) {
+            result[i+0] = Float.POSITIVE_INFINITY;
+            result[i+4] = Float.NEGATIVE_INFINITY;
+        }
+
+        for (int i = 0; i < inputArray.length; ++i) {
+            result[0 + i % 4] = Math.min(result[0 + i % 4], inputArray[i]);
+            result[4 + i % 4] = Math.max(result[4 + i % 4], inputArray[i]);
+        }
+
+        return result;
+    }
+
+    public void testFindMinAndMaxMat() {
+        final int length = 100000;
+
+        final float[] inputArray = createInputArrayFloat(4 * length, 26);
+        Allocation inputAllocation = Allocation.createSized(mRS, Element.MATRIX_2X2(mRS), length);
+        inputAllocation.copyFromUnchecked(inputArray);
+
+        final float[] javaRslt = findMinAndMaxMat(inputArray);
+        final float[] rsRslt = mScript.reduce_findMinAndMaxMat(inputAllocation).get();
+
+        assertEquals(javaRslt, rsRslt);
+    }
+
+    ///////////////////////////////////////////////////////////////////
+
+    public void testFz() {
+        final int inputLen = 100000;
+        int[] input = createInputArrayInt(inputLen, 5);
+        // just in case we got unlucky
+        input[(new Random(6)).nextInt(inputLen)] = 0;
+
+        final int rsRslt = mScript.reduce_fz(input).get();
+
+        assertEquals("input[" + rsRslt + "]", 0, input[rsRslt]);
+    }
+
+    ///////////////////////////////////////////////////////////////////
+
+    public void testFz2() {
+        final int dimX = 225, dimY = 450;
+        final int inputLen = dimX * dimY;
+
+        int[] inputArray = createInputArrayInt(inputLen, 7);
+        // just in case we got unlucky
+        inputArray[(new Random(8)).nextInt(inputLen)] = 0;
+
+        Type.Builder typeBuilder = new Type.Builder(mRS, Element.I32(mRS));
+        typeBuilder.setX(dimX).setY(dimY);
+        Allocation inputAllocation = Allocation.createTyped(mRS, typeBuilder.create());
+        inputAllocation.copy2DRangeFrom(0, 0, dimX, dimY, inputArray);
+
+        final Int2 rsRslt = mScript.reduce_fz2(inputAllocation).get();
+
+        final int cellVal = inputArray[rsRslt.x + dimX * rsRslt.y];
+
+        assertEquals("input[" + rsRslt.x + ", " + rsRslt.y + "]", 0, cellVal);
+    }
+
+    ///////////////////////////////////////////////////////////////////
+
+    public void testFz3() {
+        final int dimX = 59, dimY = 48, dimZ = 37;
+        final int inputLen = dimX * dimY * dimZ;
+
+        int[] inputArray = createInputArrayInt(inputLen, 9);
+        // just in case we got unlucky
+        inputArray[(new Random(10)).nextInt(inputLen)] = 0;
+
+        Type.Builder typeBuilder = new Type.Builder(mRS, Element.I32(mRS));
+        typeBuilder.setX(dimX).setY(dimY).setZ(dimZ);
+        Allocation inputAllocation = Allocation.createTyped(mRS, typeBuilder.create());
+        inputAllocation.copy3DRangeFrom(0, 0, 0, dimX, dimY, dimZ, inputArray);
+
+        final Int3 rsRslt = mScript.reduce_fz3(inputAllocation).get();
+
+        final int cellVal = inputArray[rsRslt.x + dimX * rsRslt.y + dimX * dimY * rsRslt.z];
+
+        assertEquals("input[" + rsRslt.x + ", " + rsRslt.y + ", " + rsRslt.z + "]", 0, cellVal);
+    }
+
+    ///////////////////////////////////////////////////////////////////
+
+    private static final int histogramBucketCount = 256;
+
+    private long[] histogram(final byte[] inputArray) {
+        Allocation inputAllocation = Allocation.createSized(mRS, Element.U8(mRS), inputArray.length);
+        inputAllocation.copyFrom(inputArray);
+
+        Allocation outputAllocation = Allocation.createSized(mRS, Element.U32(mRS), histogramBucketCount);
+
+        ScriptIntrinsicHistogram scriptHsg = ScriptIntrinsicHistogram.create(mRS, Element.U8(mRS));
+        scriptHsg.setOutput(outputAllocation);
+        scriptHsg.forEach(inputAllocation);
+
+        int[] outputArrayMistyped = new int[histogramBucketCount];
+        outputAllocation.copyTo(outputArrayMistyped);
+
+        long[] outputArray = new long[histogramBucketCount];
+        for (int i = 0; i < histogramBucketCount; ++i)
+            outputArray[i] = outputArrayMistyped[i] & (long)0xffffffff;
+        return outputArray;
+    }
+
+    public void testHistogram() {
+        final byte[] inputArray = createInputArrayByte(100000, 11);
+
+        final long[] javaRslt = histogram(inputArray);
+        assertEquals("javaRslt unexpected length", histogramBucketCount, javaRslt.length);
+        final long[] rsRslt = mScript.reduce_histogram(inputArray).get();
+        assertEquals("rsRslt unexpected length", histogramBucketCount, rsRslt.length);
+
+        for (int i = 0; i < histogramBucketCount; ++i) {
+            assertEquals("histogram[" + i + "]", javaRslt[i], rsRslt[i]);
+        }
+    }
+
+    //-----------------------------------------------------------------
+
+    private Int2 mode(final byte[] inputArray) {
+        long[] hsg = histogram(inputArray);
+
+        int modeIdx = 0;
+        for (int i = 1; i < hsg.length; ++i)
+            if (hsg[i] > hsg[modeIdx]) modeIdx =i;
+        return new Int2(modeIdx, (int)hsg[modeIdx]);
+    }
+
+    public void testMode() {
+        final byte[] inputArray = createInputArrayByte(100000, 12);
+
+        final Int2 javaRslt = mode(inputArray);
+        final Int2 rsRslt = mScript.reduce_mode(inputArray).get();
+
+        assertEquals(javaRslt, rsRslt);
+    }
+
+    ///////////////////////////////////////////////////////////////////
+
+    private int sumXor(final int[] input1, final int[] input2) {
+        int sum = 0;
+        for (int idx = 0; idx < input1.length; ++idx)
+            sum += (input1[idx] ^ input2[idx]);
+        return sum;
+    }
+
+    public void testSumXor() {
+        final int[] input1 = createInputArrayInt(100000, 13, 1 << 13);
+        final int[] input2 = createInputArrayInt(100000, 14, 1 << 13);
+
+        final int javaRslt = sumXor(input1, input2);
+        final int rsRslt = mScript.reduce_sumxor(input1, input2).get();
+
+        assertEquals(javaRslt, rsRslt);
+    }
+
+    public void testBadSumXorInputDimensionMismatch() {
+        Allocation[] inputs = createInputAllocations(Element.I32(mRS), 3);
+
+        // try all pairwise combinations of Allocations; we don't care
+        // about the result, only whether we correctly recognize
+        // whether or not the input Allocations have the same
+        // dimensions.
+        for (int i = 0; i < inputs.length; ++i) {
+            for (int j = 0; j < inputs.length; ++j) {
+                try {
+                    mScript.reduce_sumxor(inputs[i], inputs[j]);
+                    if (i != j)
+                        fail("expected RSRuntimeException for dimension mismatch: inputs " + i + " and " + j);
+                } catch (RSRuntimeException e) {
+                    if (i == j)
+                        fail("did not expect RSRuntimeException for dimension match: inputs " + i);
+                }
+            }
+        }
+    }
+
+    public void testBadSumXorInputLengthMismatch() {
+        final int[] input1 = createInputArrayInt(90000, 16, 1 << 13);
+        final int[] input2 = createInputArrayInt(100000, 17, 1 << 13);
+
+        // we don't care about the result, only whether we correctly recognize
+        // that the input arrays have different dimensions.
+        try {
+            mScript.reduce_sumxor(input1, input2);
+            fail("expected RSRuntimeException for mismatched array input lengths");
+        } catch (RSRuntimeException e) {
+        }
+    }
+
+    public void testBadSumXorInputNull() {
+        final int[] input = createInputArrayInt(100000, 15, 1 << 13);
+
+        // we don't care about the result, only whether we correctly recognize
+        // that the input array is null.
+
+        try {
+            mScript.reduce_sumxor(input, null);
+            fail("expected RSIllegalArgumentException for null array input");
+        } catch (RSIllegalArgumentException e) {
+        }
+
+        try {
+            mScript.reduce_sumxor(null, input);
+            fail("expected RSIllegalArgumentException for null array input");
+        } catch (RSIllegalArgumentException e) {
+        }
+    }
+
+    public void testBadSumXorInputWrongType() {
+        Allocation inputI32 = Allocation.createSized(mRS, Element.I32(mRS), 1);
+
+        Allocation badInput[] = new Allocation[]{
+            Allocation.createSized(mRS, Element.I16(mRS), 1),
+            Allocation.createSized(mRS, Element.I16_2(mRS), 1),
+            Allocation.createSized(mRS, Element.I32_2(mRS), 1),
+            Allocation.createSized(mRS, Element.U32(mRS), 1)
+        };
+
+        // we don't care about the result, only whether we correctly recognize
+        // that the input Allocation has the wrong type.
+
+        for (int i = 0; i < badInput.length; ++i) {
+            try {
+                mScript.reduce_sumxor(inputI32, badInput[i]);
+                fail("badInput[" + i + "]: expected RSRuntimeException for wrong input data type");
+            } catch (RSRuntimeException e) {
+            }
+
+            try {
+                mScript.reduce_sumxor(badInput[i], inputI32);
+                fail("badInput[" + i + "]: expected RSRuntimeException for wrong input data type");
+            } catch (RSRuntimeException e) {
+            }
+        }
+    }
+
+    ///////////////////////////////////////////////////////////////////
+
+    private long sillySum(final byte[] input1, final float[] input2, final int[] input3) {
+        // input3 is a flattened 3-vector
+        assertEquals(input1.length, input2.length);
+        assertEquals(input1.length * 3, input3.length);
+
+        long sum = 0;
+        for (int i = 0; i < input1.length; ++i)
+            sum += ((((input1[i] + (long)Math.ceil(Math.log(input2[i]))) + input3[3*i + 0]) + input3[3*i + 1]) + input3[3*i + 2]);
+        return sum;
+    }
+
+    public void testSillySum() {
+        final int length = 100000;
+
+        final byte[] input1 = createInputArrayByte(length, 16);
+        final float[] input2 = createInputArrayFloat(length, 17);
+        // input3 is a flattened 3-vector
+        final int[] input3 = createInputArrayInt(3 * length, 18);
+
+        final long javaRslt = sillySum(input1, input2, input3);
+        final long rsRslt = mScript.reduce_sillysum(input1, input2, input3).get();
+
+        assertEquals(javaRslt, rsRslt);
+    }
+
+    public void testBadSillySumInputDimensionMismatch() {
+        Allocation[] allocs1 = createInputAllocations(Element.I8(mRS), 3);
+        Allocation[] allocs2 = createInputAllocations(Element.F32(mRS), 3);
+        Allocation[] allocs3 = createInputAllocations(Element.I32_3(mRS), 3);
+
+        // try all tuples of Allocations; we don't care about the
+        // result, only whether we correctly recognize whether or not
+        // the input Allocations have the same dimensions.
+        for (int i = 0; i < allocs1.length; ++i) {
+            for (int j = 0; j < allocs2.length; ++j) {
+                for (int k = 0; k < allocs3.length; ++k) {
+                    final boolean expectException = !((i == j) && (j == k));
+                    try {
+                        mScript.reduce_sillysum(allocs1[i], allocs2[j], allocs3[k]);
+                        if (expectException)
+                            fail("expected RSRuntimeException for dimension mismatch: inputs " + i + ", " + j + ", " + k);
+                    } catch (RSRuntimeException e) {
+                        if (!expectException) {
+                            fail("did not expect RSRuntimeException for dimension match: inputs " + i);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    public void testBadSillySumInputLengthMismatch() {
+        final int[] lengths = new int[]{ 10, 100, 1000 };
+
+        // try all pairwise combinations of lengths; we don't care
+        // about the result, only whether we correctly recognize
+        // whether or not the input Allocations have the same lengths.
+        for (int len1idx = 0; len1idx < lengths.length; ++len1idx) {
+            for (int len2idx = 0; len2idx < lengths.length; ++len2idx) {
+                for (int len3idx = 0; len3idx < lengths.length; ++len3idx) {
+
+                    final byte[] input1 = createInputArrayByte(lengths[len1idx], 19);
+                    final float[] input2 = createInputArrayFloat(lengths[len2idx], 20);
+                    // input3 is a flattened 3-vector
+                    final int[] input3 = createInputArrayInt(3 * lengths[len3idx], 21);
+
+                    try {
+                        mScript.reduce_sillysum(input1, input2, input3);
+                        if ((len1idx != len2idx) || (len1idx != len3idx))
+                            fail("expected RSRuntimeException for dimension mismatch: inputs " +
+                                    len1idx + ", " + len2idx + ", " + len3idx);
+                    } catch (RSRuntimeException e) {
+                        if ((len1idx == len2idx) && (len1idx == len3idx))
+                            fail("did not expect RSRuntimeException for dimension match: inputs " + len1idx);
+                    }
+                }
+            }
+        }
+    }
+
+    ///////////////////////////////////////////////////////////////////
+
+    private static final long[] oorrGoodResults = new long[]{0L, 1L, 0x7fff_ffff_ffff_ffffL};
+    private static final long[] oorrBadResultHalfs = new long[]{0x4000_0000_0000_0000L, 0x4567_89ab_cdef_0123L};
+
+    private static final int[] oorInput = createInputArrayInt(1, 22);
+
+    public void testBadOorrSca() {
+        final int[] oorrBadPositions = new int[]{-1, 0};
+
+        for (long goodResult : oorrGoodResults) {
+            mScript.set_oorrGoodResult(goodResult);
+            for (long badResultHalf : oorrBadResultHalfs) {
+                mScript.set_oorrBadResultHalf(badResultHalf);
+                for (int badPosition : oorrBadPositions) {
+                    mScript.set_oorrBadPos(badPosition);
+
+                    // we don't care about the result, only whether
+                    // it's representible.  note that no exception is
+                    // thrown until "get()".
+                    try {
+                        mScript.reduce_oorrSca(oorInput).get();
+                        if (badPosition >= 0)
+                            fail("expected RSRuntimeException for non-representible result; expected 2*" + badResultHalf);
+                    } catch (RSRuntimeException e) {
+                        if (badPosition < 0)
+                            fail("did not expect RSRuntimeException for representible result; expected " + goodResult);
+                    }
+                }
+            }
+        }
+    }
+
+    public void testBadOorrVec4() {
+        final int[] oorrBadPositions = new int[]{-1, 0, 1, 2, 3};
+
+        for (long goodResult : oorrGoodResults) {
+            mScript.set_oorrGoodResult(goodResult);
+            for (long badResultHalf : oorrBadResultHalfs) {
+                mScript.set_oorrBadResultHalf(badResultHalf);
+                for (int badPosition : oorrBadPositions) {
+                    mScript.set_oorrBadPos(badPosition);
+
+                    // we don't care about the result, only whether
+                    // it's representible.  note that no exception is
+                    // thrown until "get()".
+                    try {
+                        mScript.reduce_oorrVec4(oorInput).get();
+                        if (badPosition >= 0)
+                            fail("expected RSRuntimeException for non-representible result; expected 2*" + badResultHalf
+                                    + " at position " + badPosition);
+                    } catch (RSRuntimeException e) {
+                        if (badPosition < 0)
+                            fail("did not expect RSRuntimeException for representible result; expected " + goodResult);
+                    }
+                }
+            }
+        }
+    }
+
+    public void testBadOorrArr9() {
+        final int[] oorrBadPositions = new int[]{-1, 0, 1, 2, 3, 4, 5, 6, 7, 8};
+
+        for (long goodResult : oorrGoodResults) {
+            mScript.set_oorrGoodResult(goodResult);
+            for (long badResultHalf : oorrBadResultHalfs) {
+                mScript.set_oorrBadResultHalf(badResultHalf);
+                for (int badPosition : oorrBadPositions) {
+                    mScript.set_oorrBadPos(badPosition);
+
+                    // we don't care about the result, only whether
+                    // it's representible.  note that no exception is
+                    // thrown until "get()".
+                    try {
+                        mScript.reduce_oorrArr9(oorInput).get();
+                        if (badPosition >= 0)
+                            fail("expected RSRuntimeException for non-representible result; expected 2*" + badResultHalf
+                                    + " at position " + badPosition);
+                    } catch (RSRuntimeException e) {
+                        if (badPosition < 0)
+                            fail("did not expect RSRuntimeException for representible result; expected " + goodResult);
+                    }
+                }
+            }
+        }
+    }
+
+    public void testBadOorrArr9Vec4() {
+        for (long goodResult : oorrGoodResults) {
+            mScript.set_oorrGoodResult(goodResult);
+            for (long badResultHalf : oorrBadResultHalfs) {
+                mScript.set_oorrBadResultHalf(badResultHalf);
+                for (int badPosition = -1; badPosition < 36; ++badPosition) {
+                    mScript.set_oorrBadPos(badPosition);
+
+                    // we don't care about the result, only whether
+                    // it's representible.  note that no exception is
+                    // thrown until "get()".
+                    try {
+                        mScript.reduce_oorrArr9Vec4(oorInput).get();
+                        if (badPosition >= 0)
+                            fail("expected RSRuntimeException for non-representible result; expected 2*" + badResultHalf
+                                    + " at position " + badPosition);
+                    } catch (RSRuntimeException e) {
+                        if (badPosition < 0)
+                            fail("did not expect RSRuntimeException for representible result; expected " + goodResult);
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/SingleSourceAllocationTest.java b/tests/tests/renderscript/src/android/renderscript/cts/SingleSourceAllocationTest.java
new file mode 100644
index 0000000..88b96ac
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/SingleSourceAllocationTest.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2015-2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.renderscript.cts;
+
+import android.util.Log;
+import android.renderscript.Allocation;
+import android.renderscript.Element;
+import android.renderscript.Script;
+import android.renderscript.Type;
+import android.renderscript.Type.Builder;
+
+public class SingleSourceAllocationTest extends RSBaseCompute {
+
+    private static final String TAG = "SingleSourceAllocationTest";
+
+    private ScriptC_single_source_alloc s;
+    private static final int dimX = 3;
+    private static final int dimY = 4;
+    private static final int dimZ = 5;
+    private static final int start = 23;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        s = new ScriptC_single_source_alloc(mRS);
+        s.set_gDimX(dimX);
+        s.set_gDimY(dimY);
+        s.set_gDimZ(dimZ);
+        s.set_gStart(start);
+    }
+
+    public void testElementCreation() {
+        s.invoke_TestElementCreation();
+        waitForMessage();
+        checkForErrors();
+    }
+
+    public void testTypeCreation() {
+        s.invoke_TestTypeCreation();
+        waitForMessage();
+        checkForErrors();
+    }
+
+    public void testAllocationCreationWithUsage() {
+        s.invoke_TestAllocationCreationWithUsage();
+        waitForMessage();
+        checkForErrors();
+    }
+
+    public void testAllocationCreationHelperFunctions() {
+        s.invoke_TestHelperFunctions();
+        waitForMessage();
+        checkForErrors();
+    }
+
+    public void testAllocationCreationAndAccess() {
+        s.invoke_TestAllocationCreationAndAccess();
+        waitForMessage();
+        checkForErrors();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/SingleSourceForEachTest.java b/tests/tests/renderscript/src/android/renderscript/cts/SingleSourceForEachTest.java
new file mode 100644
index 0000000..e005013
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/SingleSourceForEachTest.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2015-2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.Element;
+import android.renderscript.Script;
+import android.renderscript.Type;
+import android.renderscript.Type.Builder;
+
+public class SingleSourceForEachTest extends RSBaseCompute {
+
+    private static final int X = 1024;
+    private static final int Y = 768;
+
+    private Allocation testInputAlloc;
+    private Allocation testInputAlloc2;
+    private Allocation testOutputAlloc;
+    private Allocation baselineOutputAlloc;
+    private int testInputArray[];
+    private int testInputArray2[];
+    private int testOutputArray[];
+    private int baselineOutputArray[];
+    private ScriptC_single_source_script s;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        Type.Builder i32TypeBuilder = new Type.Builder(mRS, Element.I32(mRS));
+        i32TypeBuilder.setX(X).setY(Y);
+        testInputAlloc = Allocation.createTyped(mRS, i32TypeBuilder.create());
+        testInputAlloc2 = Allocation.createTyped(mRS, i32TypeBuilder.create());
+        testOutputAlloc = Allocation.createTyped(mRS, i32TypeBuilder.create());
+        baselineOutputAlloc = Allocation.createTyped(mRS, i32TypeBuilder.create());
+
+        testInputArray = new int[X * Y];
+        testInputArray2 = new int[X * Y];
+        testOutputArray = new int[X * Y];
+        baselineOutputArray = new int[X * Y];
+
+        s = new ScriptC_single_source_script(mRS);
+
+        RSUtils.genRandomInts(0x900d5eed, testInputArray, true, 32);
+        testInputAlloc.copyFrom(testInputArray);
+
+        for (int i = 0; i < testInputArray2.length; i++) {
+            testInputArray2[i] = i + 1;
+        }
+        testInputAlloc2.copyFrom(testInputArray2);
+    }
+
+    public void testSingleInputKernelLaunch() {
+        s.forEach_foo(testInputAlloc, baselineOutputAlloc);
+        s.invoke_testSingleInput(testInputAlloc, testOutputAlloc);
+        testOutputAlloc.copyTo(testOutputArray);
+        baselineOutputAlloc.copyTo(baselineOutputArray);
+        checkArray(baselineOutputArray, testOutputArray, Y, X, X);
+    }
+
+    public void testMultiInputKernelLaunch() {
+        s.forEach_goo(testInputAlloc, testInputAlloc2,
+                      baselineOutputAlloc);
+        s.invoke_testMultiInput(testInputAlloc, testInputAlloc2,
+                                testOutputAlloc);
+        testOutputAlloc.copyTo(testOutputArray);
+        baselineOutputAlloc.copyTo(baselineOutputArray);
+        checkArray(baselineOutputArray, testOutputArray, Y, X, X);
+    }
+
+    public void testKernelLaunchWithOptions() {
+        Script.LaunchOptions sc = new Script.LaunchOptions();
+        sc.setX(0, X);
+        sc.setY(0, Y / 2);
+        s.forEach_foo(testInputAlloc, baselineOutputAlloc, sc);
+        s.invoke_testLaunchOptions(testInputAlloc, testOutputAlloc, X, Y);
+        testOutputAlloc.copyTo(testOutputArray);
+        baselineOutputAlloc.copyTo(baselineOutputArray);
+        checkArray(baselineOutputArray, testOutputArray, Y, X, X);
+    }
+
+    public void testAllocationlessKernelLaunch() {
+        baselineOutputAlloc.copyFrom(testInputArray);
+        testOutputAlloc.copyFrom(testInputArray);
+
+        Script.LaunchOptions sc = new Script.LaunchOptions();
+        sc.setX(0, X);
+        sc.setY(0, Y);
+        s.set_gAllocOut(baselineOutputAlloc);
+        s.forEach_bar(sc);
+
+        s.invoke_testAllocationlessLaunch(testOutputAlloc, X, Y);
+
+        testOutputAlloc.copyTo(testOutputArray);
+        baselineOutputAlloc.copyTo(baselineOutputArray);
+        checkArray(baselineOutputArray, testOutputArray, Y, X, X);
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/SmallStructsTest.java b/tests/tests/renderscript/src/android/renderscript/cts/SmallStructsTest.java
new file mode 100644
index 0000000..28a9528
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/SmallStructsTest.java
@@ -0,0 +1,248 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.Float4;
+import android.renderscript.RenderScript;
+
+import java.lang.reflect.Method;
+
+/*
+ * This checks that small structs (<= 64 bytes) are passed and
+ * returned correctly by forEach_* style kernels.
+ *
+ * There are three steps to each test: (a) setup, (b) modify, (c) verify.
+ * (a) the setup stage initializes the Allocation of structs
+ * (b) modify calls a forEach_* kernel with the Allocation
+ * (c) verify checks that the forEach_* kernel accessed the data as expected
+ */
+public class SmallStructsTest extends RSBaseCompute {
+    static final int sAllocationElements = 1024;
+    static final int sLargestCharArrayStructSize = 64;
+
+    static final String sTwoElementStructTypes[] =
+            {"i8", "i16", "i32", "i64", "f32", "f64", "v128"};
+
+    static final byte   sInitialValue_int8_t  = (byte) 0x7;
+    static final short  sInitialValue_int16_t = (short) 0x1234;
+    static final int    sInitialValue_int32_t = 0x12345678;
+    static final long   sInitialValue_int64_t = 0x12345678abcdef1L;
+    static final float  sInitialValue_float   = 10473.f;
+    static final double sInitialValue_double  = 35353143.25;
+    static final Float4 sInitialValue_float4  = new Float4(10473.f, 353541.5f, -5433.75f, 78394.f);
+
+    ScriptC_small_structs mScript;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mScript = new ScriptC_small_structs(mRS);
+    }
+
+    void checkForErrorsInScript() {
+        mRS.finish();
+        mScript.invoke_checkError();
+        waitForMessage();
+        checkForErrors();
+    }
+
+    /**
+     * Returns the class associated with the given type. For primitive types, the unwrapped class is
+     * returned.
+     */
+    Class<?> getUnwrappedClassForType(String type) {
+        if (type.equals("i8")) {
+            return byte.class;
+        } else if (type.equals("i16")) {
+            return short.class;
+        } else if (type.equals("i32")) {
+            return int.class;
+        } else if (type.equals("i64")) {
+            return long.class;
+        } else if (type.equals("f32")) {
+            return float.class;
+        } else if (type.equals("f64")) {
+            return double.class;
+        } else if (type.equals("v128")) {
+            return Float4.class;
+        } else {
+            fail("Unknown type tag: " + type);
+            return null;
+        }
+    }
+
+    /**
+     * Returns a ScriptC_small_structs setter associated with the global of the given type.
+     */
+    Method getInitialValueSetter(String type) throws Exception {
+        String name = "set_initial_value_";
+        if (type.equals("i8")) {
+            name += "int8_t";
+        } else if (type.equals("i16")) {
+            name += "int16_t";
+        } else if (type.equals("i32")) {
+            name += "int32_t";
+        } else if (type.equals("i64")) {
+            name += "int64_t";
+        } else if (type.equals("f32")) {
+            name += "float";
+        } else if (type.equals("f64")) {
+            name += "double";
+        } else if (type.equals("v128")) {
+            name += "float4";
+        } else {
+            fail("unknown type tag: " + type);
+        }
+
+        return ScriptC_small_structs.class.getMethod(name, getUnwrappedClassForType(type));
+    }
+
+    /**
+     * Returns the (possibly wrapped) initial value associated with the global of the given type.
+     */
+    Object getInitialValue(String type) {
+        if (type.equals("i8")) {
+            return (Object) sInitialValue_int8_t;
+        } else if (type.equals("i16")) {
+            return (Object) sInitialValue_int16_t;
+        } else if (type.equals("i32")) {
+            return (Object) sInitialValue_int32_t;
+        } else if (type.equals("i64")) {
+            return (Object) sInitialValue_int64_t;
+        } else if (type.equals("f32")) {
+            return (Object) sInitialValue_float;
+        } else if (type.equals("f64")) {
+            return (Object) sInitialValue_double;
+        } else if (type.equals("v128")) {
+            return (Object) sInitialValue_float4;
+        } else {
+            fail("unknown type tag: " + type);
+            return null;
+        }
+    }
+
+    /**
+     * Structs in this test are of the form
+     *   struct char_array_N { char bytes[N]; };
+     */
+    public void testSmallStructsOfCharArray() throws Exception {
+        for (int size = 1; size <= sLargestCharArrayStructSize; ++size) {
+            // Make the input allocation.
+            Class<?> scriptFieldClass = Class.forName(
+                    "android.renderscript.cts.ScriptField_char_array_" + size);
+
+            Object field = scriptFieldClass.getConstructor(RenderScript.class, int.class)
+                    .newInstance(mRS, sAllocationElements);
+            Allocation alloc = (Allocation) scriptFieldClass.getMethod("getAllocation")
+                    .invoke(field);
+
+            // void set_bytes(int index, byte[] bytes, boolean copyNow)
+            Method set_bytes = scriptFieldClass.getMethod("set_bytes",
+                    int.class, byte[].class, boolean.class);
+
+            byte[] bytes = new byte[size];
+            for (int i = 0; i < size; ++i) {
+                bytes[i] = (byte) (1 + i);
+            }
+
+            for (int elem = 0; elem < sAllocationElements; ++elem) {
+                set_bytes.invoke(field, elem, bytes, true);
+            }
+
+            // Get methods used in testing.
+            Method modify = ScriptC_small_structs.class.getMethod(
+                    "forEach_modify_char_array_" + size,
+                    Allocation.class, Allocation.class);
+
+            Method verify = ScriptC_small_structs.class.getMethod(
+                    "invoke_verify_char_array_" + size,
+                    Allocation.class);
+
+            // Run the test.
+            modify.invoke(mScript, alloc, alloc);
+            verify.invoke(mScript, alloc);
+        }
+
+        checkForErrorsInScript();
+
+        // Check that all tests were run.
+        mScript.invoke_checkNumberOfCharArrayTestsRun();
+        waitForMessage();
+        checkForErrors();
+    }
+
+    /**
+     * Structs in this test are of the form
+     *   struct two_element_struct_X { TYPE1 a; TYPE2 b };
+     */
+    public void testSmallStructsOfHeterogeneousTypes() throws Exception {
+        // Initialize script globals.
+        for (String type: sTwoElementStructTypes) {
+            getInitialValueSetter(type).invoke(mScript, getInitialValue(type));
+        }
+
+        for (String type1: sTwoElementStructTypes) {
+            for (String type2: sTwoElementStructTypes) {
+                // Build the input allocation.
+                String tag = type1 + "_" + type2;
+                Class<?> scriptFieldClass = Class.forName(
+                        "android.renderscript.cts.ScriptField_two_element_struct_" + tag);
+
+                Object field = scriptFieldClass.getConstructor(RenderScript.class, int.class)
+                        .newInstance(mRS, sAllocationElements);
+                Allocation alloc = (Allocation) scriptFieldClass.getMethod("getAllocation")
+                        .invoke(field);
+
+                // Set the structure fields of the input.
+                for (int elem = 0; elem < sAllocationElements; ++elem) {
+                    Object initialValueA = getInitialValue(type1);
+                    // void set_a(int index, Ty val, boolean copyNow)
+                    Method fieldASetter = scriptFieldClass.getMethod("set_a",
+                            int.class, getUnwrappedClassForType(type1), boolean.class);
+                    fieldASetter.invoke(field, elem, initialValueA, true);
+
+                    Object initialValueB = getInitialValue(type2);
+                    // void set_b(int index, Ty val, boolean copyNow)
+                    Method fieldBSetter = scriptFieldClass.getMethod("set_b",
+                            int.class, getUnwrappedClassForType(type2), boolean.class);
+                    fieldBSetter.invoke(field, elem, initialValueB, true);
+                }
+
+                // Get methods used in testing.
+                Method modify = ScriptC_small_structs.class.getMethod(
+                        "forEach_modify_two_element_struct_" + tag,
+                        Allocation.class, Allocation.class);
+
+                Method verify = ScriptC_small_structs.class.getMethod(
+                        "invoke_verify_two_element_struct_" + tag,
+                        Allocation.class);
+
+                // Run the test.
+                modify.invoke(mScript, alloc, alloc);
+                verify.invoke(mScript, alloc);
+            }
+        }
+
+        checkForErrorsInScript();
+
+        // Check that all tests were run.
+        mScript.invoke_checkNumberOfTwoElementStructTestsRun();
+        waitForMessage();
+        checkForErrors();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/Target.java b/tests/tests/renderscript/src/android/renderscript/cts/Target.java
index c423792..55d3712 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/Target.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/Target.java
@@ -28,6 +28,31 @@
  */
 public class Target {
     /**
+     * Broad classification of the type of function being tested.
+     */
+    public enum FunctionType {
+        NORMAL,
+        HALF,
+        NATIVE,
+        FAST,
+    }
+
+    /**
+     * Floating point precision of the result of the function being tested.
+     */
+    public enum ReturnType {
+        HALF,
+        FLOAT,
+        DOUBLE
+    }
+
+    /* The classification of the function being tested */
+    private FunctionType mFunctionType;
+
+    /* The floating point precision of the result of the function being tested */
+    private ReturnType mReturnType;
+
+    /*
      * In relaxed precision mode, we allow:
      * - less precision in the computation
      * - using only normalized values
@@ -36,18 +61,11 @@
      */
     private boolean mIsRelaxedPrecision;
 
-    /*
-     * The following two fields are set just before the expected values are computed for a specific
-     * RenderScript function.  Hence, we can't use one instance of this class to test two APIs
-     * in parallel.  The generated Test*.java code uses one instance of Target per test, so we're
-     * safe.
-     */
+    /* If false, zero or the closest normal value are also accepted for subnormal results. */
+    private boolean mHandleSubnormal;
 
-    /**
-     * For native, we allow the same things as relaxed precision, plus:
-     * - operations don't have to return +/- infinity
-     */
-    private boolean mIsNative;
+    /* Number of bits in mReturnType */
+    private int mFloatSize;
 
     /**
      * How much we'll allow the values tested to diverge from the values
@@ -55,20 +73,64 @@
      */
     private int mUlpFactor;
 
-    Target(boolean relaxed) {
+    Target(FunctionType functionType, ReturnType returnType, boolean relaxed) {
+        mFunctionType = functionType;
+        mReturnType = returnType;
         mIsRelaxedPrecision = relaxed;
+
+        if (mReturnType == ReturnType.HALF) {
+            // HALF accepts relaxed precision by default - subnormal numbers need not be handled.
+            // 'relaxed' parameter is ignored.
+            mHandleSubnormal = false;
+            mFloatSize = 16;
+        } else if (mReturnType == ReturnType.FLOAT) {
+            // NORMAL functions, when in non-relaxed mode, need to handle subnormals.  Subnormals
+            // need not be handled in any other mode.
+            mHandleSubnormal = (mFunctionType == FunctionType.NORMAL) && !relaxed;
+            mFloatSize = 32;
+        } else if (mReturnType == ReturnType.DOUBLE) {
+            // We only have NORMAL functions for DOUBLE, with no relaxed precison - subnormal values
+            // must always be handled.  'relaxed' parameter is ignored.
+            assert(mFunctionType == FunctionType.NORMAL);
+            mHandleSubnormal = true;
+            mFloatSize = 64;
+        }
     }
 
     /**
      * Sets whether we are testing a native_* function and how many ulp we allow
      * for full and relaxed precision.
      */
-    void setPrecision(int fullUlpFactor, int relaxedUlpFactor, boolean isNative) {
-        mIsNative = isNative;
+    void setPrecision(int fullUlpFactor, int relaxedUlpFactor) {
         mUlpFactor = mIsRelaxedPrecision ? relaxedUlpFactor : fullUlpFactor;
     }
 
     /**
+     * Helper functions to create a new Floaty with the current expected level of precision.
+     * We have variations that expect one to five arguments.  Any of the passed arguments are
+     * considered valid values for that Floaty.
+     */
+    Floaty newFloaty(double a) {
+        return new Floaty(mFloatSize, new double [] { a });
+    }
+
+    Floaty newFloaty(double a, double b) {
+        return new Floaty(mFloatSize, new double [] { a, b });
+    }
+
+    Floaty newFloaty(double a, double b, double c) {
+        return new Floaty(mFloatSize, new double [] { a, b, c });
+    }
+
+    Floaty newFloaty(double a, double b, double c, double d) {
+        return new Floaty(mFloatSize, new double [] { a, b, c, d });
+    }
+
+    Floaty newFloaty(double a, double b, double c, double d, double e) {
+        return new Floaty(mFloatSize, new double [] { a, b, c, d, e });
+    }
+
+    /**
      * Helper functions to create a new 32 bit Floaty with the current expected level of precision.
      * We have variations that expect one to five arguments.  Any of the passed arguments are considered
      * valid values for that Floaty.
@@ -287,13 +349,18 @@
                 // For relaxed mode, we don't require support of subnormal values.
                 // If we have a subnormal value, we'll allow both the normalized value and zero,
                 // to cover the two ways this small value might be handled.
-                if (mIsRelaxedPrecision || mIsNative) {
+                if (!mHandleSubnormal) {
                     if (IsSubnormal(f)) {
                         updateMinAndMax(0.f);
                         updateMinAndMax(smallestNormal(f));
                     }
                 }
             }
+
+            // Expand the range to the closest value representable in the desired floating-point
+            // format
+            ExpandRangeToTargetPrecision();
+
             // Expand the range by one ulp factor to cover for the different rounding modes.
             ExpandRangeByUlpFactor();
             //Log.w("Floaty(double[], ulp)", "output: " +  toString());
@@ -315,6 +382,34 @@
             }
         }
 
+        /** Return (as double) the next highest value representable in Float16 precision */
+        private double roundFloat16Up(double value) {
+            return Float16Utils.roundToFloat16(value)[1];
+        }
+
+        /** Return (as double) the next lowest value representable in Float16 precision */
+        private double roundFloat16Down(double value) {
+            return Float16Utils.roundToFloat16(value)[0];
+        }
+
+        /**
+         * Modify mMinValue and mMaxValue to the closest value representable in mNumberOfBits.
+         * mMinValue is rounded down and mMaxValue is rounded u
+         */
+        void ExpandRangeToTargetPrecision() {
+            if (!mHasRange) return;
+
+            if (mNumberOfBits != 16) return; // For now, this function is only needed for Float16.
+
+            // Log.w("ExpandRangeToFloat16Precision", "Before: " + Double.toString(mMinValue) + " " + Double.toString(mValue) + " " + Double.toString(mMaxValue));
+
+            // TODO Should we adjust mValue to Float16-representable value?
+            mMaxValue = roundFloat16Up(mMaxValue);
+            mMinValue = roundFloat16Down(mMinValue);
+
+            //Log.w("ExpandRangeToFloat16Precision", "After: " + Double.toString(mMinValue) + " " + Double.toString(mValue) + " " + Double.toString(mMaxValue));
+        }
+
         /** Modify mMinValue and mMaxValue to allow one extra ulp factor of error on each side. */
         void ExpandRangeByUlpFactor() {
             if (mHasRange && mUlpFactor > 0) {
@@ -349,13 +444,19 @@
                 mMinValue = newValue;
             }
             // If subnormal, also allow the normalized value if it's smaller.
-            if ((mIsRelaxedPrecision || mIsNative) && IsSubnormal(mMinValue)) {
+            if (!mHandleSubnormal && IsSubnormal(mMinValue)) {
                 if (mMinValue < 0) {
                     mMinValue = smallestNormal(-1.0f);
                 } else {
                     mMinValue = 0.f;
                 }
             }
+
+            // If Float16, round minValue down to maintain invariant that the range is always
+            // representable in Float16.
+            if (mNumberOfBits == 16) {
+                mMinValue = roundFloat16Down(mMinValue);
+            }
             //Log.w("ExpandMin", "ulp " + java.lang.Double.toString(ulp) + ", delta " + java.lang.Double.toString(delta) + " for " + java.lang.Double.toString(mMinValue));
         }
 
@@ -384,13 +485,19 @@
                 mMaxValue = newValue;
             }
             // If subnormal, also allow the normalized value if it's smaller.
-            if ((mIsRelaxedPrecision || mIsNative) && IsSubnormal(mMaxValue)) {
+            if (!mHandleSubnormal && IsSubnormal(mMaxValue)) {
                 if (mMaxValue > 0) {
                     mMaxValue = smallestNormal(1.0f);
                 } else {
                     mMaxValue = 0.f;
                 }
             }
+
+            // If Float16, round mMaxValue up to maintain invariant that the range is always
+            // representable in Float16.
+            if (mNumberOfBits == 16 && mMaxValue != 0) {
+                mMaxValue = roundFloat16Up(mMaxValue);
+            }
             //Log.w("ExpandMax", "ulp " + java.lang.Double.toString(ulp) + ", delta " + java.lang.Double.toString(delta) + " for " + java.lang.Double.toString(mMaxValue));
         }
 
@@ -408,7 +515,14 @@
          * sign as f.
          */
         private double smallestNormal(double f) {
-            double answer = (mNumberOfBits == 32) ? Float.MIN_NORMAL : Double.MIN_NORMAL;
+            double answer;
+            if (mNumberOfBits == 16) {
+                answer = Float16Utils.MIN_NORMAL;
+            } else if (mNumberOfBits == 32) {
+                answer = Float.MIN_NORMAL;
+            } else {
+                answer = Double.MIN_NORMAL;
+            }
             if (f < 0) {
                 answer = -answer;
             }
@@ -418,12 +532,14 @@
         /** Returns the unit of least precision for the maximum value allowed. */
         private double Ulp() {
             double u;
-            if (mNumberOfBits == 32) {
+            if (mNumberOfBits == 16) {
+                u = Float16Utils.float16Ulp(mMaxValue);
+            } else if (mNumberOfBits == 32) {
                 u = Math.ulp((float)mMaxValue);
             } else {
                 u = Math.ulp(mMaxValue);
             }
-            if (mIsRelaxedPrecision || mIsNative) {
+            if (!mHandleSubnormal) {
                 u = Math.max(u, smallestNormal(1.f));
             }
             return u;
@@ -432,12 +548,14 @@
         /** Returns the negative of the unit of least precision for the minimum value allowed. */
         private double NegativeUlp() {
             double u;
-            if (mNumberOfBits == 32) {
+            if (mNumberOfBits == 16) {
+                u = -Float16Utils.float16Ulp(mMinValue);
+            } else if (mNumberOfBits == 32) {
                 u = -Math.ulp((float)mMinValue);
             } else {
                 u = -Math.ulp(mMinValue);
             }
-            if (mIsRelaxedPrecision || mIsNative) {
+            if (!mHandleSubnormal) {
                 u = Math.min(u, smallestNormal(-1.f));
             }
             return u;
@@ -469,7 +587,7 @@
             }
             // For native, we don't require returning +/- infinity.  If that's what we expect,
             // allow all answers.
-            if (mIsNative) {
+            if (mFunctionType == FunctionType.NATIVE) {
                 if (mMinValue == Double.NEGATIVE_INFINITY &&
                     mMaxValue == Double.NEGATIVE_INFINITY) {
                     return true;
@@ -483,6 +601,12 @@
         }
 
 
+        // TODO simplify: remove 32() and 64()
+        public double get() { return mValue; }
+        public double mid() { return mid64(); }
+        public double min() { return mMinValue; }
+        public double max() { return mMaxValue; }
+
         public double get64() { return mValue; }
         public double min64() { return mMinValue; }
         public double max64() { return mMaxValue; }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAbs.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAbs.java
index 78bdfe8..0ab7c31 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAbs.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAbs.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAbs.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAbs.rs
index 918fa14..5acb9fa 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAbs.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAbs.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAbsRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAbsRelaxed.rs
index f3672ab..a94e531 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAbsRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAbsRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAcos.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAcos.java
index 8ea35f7..a573212 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAcos.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAcos.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeAcos(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeAcos(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeAcos(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeAcos(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkAcosHalfHalf() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x4b431bc1l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testAcosHalfHalf(inV, out);
+            verifyResultsAcosHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcosHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testAcosHalfHalf(inV, out);
+            verifyResultsAcosHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcosHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAcosHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeAcos(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkAcosHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAcosHalf2Half2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x3eea831bl, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testAcosHalf2Half2(inV, out);
+            verifyResultsAcosHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcosHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testAcosHalf2Half2(inV, out);
+            verifyResultsAcosHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcosHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAcosHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeAcos(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkAcosHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAcosHalf3Half3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x9df2480fl, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testAcosHalf3Half3(inV, out);
+            verifyResultsAcosHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcosHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testAcosHalf3Half3(inV, out);
+            verifyResultsAcosHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcosHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAcosHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeAcos(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkAcosHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAcosHalf4Half4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xfcfa0d03l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testAcosHalf4Half4(inV, out);
+            verifyResultsAcosHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcosHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testAcosHalf4Half4(inV, out);
+            verifyResultsAcosHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcosHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAcosHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeAcos(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkAcosHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testAcos() {
         checkAcosFloatFloat();
         checkAcosFloat2Float2();
         checkAcosFloat3Float3();
         checkAcosFloat4Float4();
+        checkAcosHalfHalf();
+        checkAcosHalf2Half2();
+        checkAcosHalf3Half3();
+        checkAcosHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAcos.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAcos.rs
index fc21625..2e652f6 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAcos.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAcos.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testAcosFloat4Float4(float4 inV) {
     return acos(inV);
 }
+
+half __attribute__((kernel)) testAcosHalfHalf(half inV) {
+    return acos(inV);
+}
+
+half2 __attribute__((kernel)) testAcosHalf2Half2(half2 inV) {
+    return acos(inV);
+}
+
+half3 __attribute__((kernel)) testAcosHalf3Half3(half3 inV) {
+    return acos(inV);
+}
+
+half4 __attribute__((kernel)) testAcosHalf4Half4(half4 inV) {
+    return acos(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAcosRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAcosRelaxed.rs
index e2d5dc9..57773a4 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAcosRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAcosRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAcosh.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAcosh.java
index 6a4e844..277157a 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAcosh.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAcosh.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeAcosh(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeAcosh(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeAcosh(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeAcosh(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkAcoshHalfHalf() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x78f34665l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testAcoshHalfHalf(inV, out);
+            verifyResultsAcoshHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcoshHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testAcoshHalfHalf(inV, out);
+            verifyResultsAcoshHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcoshHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAcoshHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeAcosh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkAcoshHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAcoshHalf2Half2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x3c4e7d9fl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testAcoshHalf2Half2(inV, out);
+            verifyResultsAcoshHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcoshHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testAcoshHalf2Half2(inV, out);
+            verifyResultsAcoshHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcoshHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAcoshHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeAcosh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkAcoshHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAcoshHalf3Half3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x9b564293l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testAcoshHalf3Half3(inV, out);
+            verifyResultsAcoshHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcoshHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testAcoshHalf3Half3(inV, out);
+            verifyResultsAcoshHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcoshHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAcoshHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeAcosh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkAcoshHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAcoshHalf4Half4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xfa5e0787l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testAcoshHalf4Half4(inV, out);
+            verifyResultsAcoshHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcoshHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testAcoshHalf4Half4(inV, out);
+            verifyResultsAcoshHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcoshHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAcoshHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeAcosh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkAcoshHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testAcosh() {
         checkAcoshFloatFloat();
         checkAcoshFloat2Float2();
         checkAcoshFloat3Float3();
         checkAcoshFloat4Float4();
+        checkAcoshHalfHalf();
+        checkAcoshHalf2Half2();
+        checkAcoshHalf3Half3();
+        checkAcoshHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAcosh.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAcosh.rs
index 7f6330a..130f131 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAcosh.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAcosh.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testAcoshFloat4Float4(float4 inV) {
     return acosh(inV);
 }
+
+half __attribute__((kernel)) testAcoshHalfHalf(half inV) {
+    return acosh(inV);
+}
+
+half2 __attribute__((kernel)) testAcoshHalf2Half2(half2 inV) {
+    return acosh(inV);
+}
+
+half3 __attribute__((kernel)) testAcoshHalf3Half3(half3 inV) {
+    return acosh(inV);
+}
+
+half4 __attribute__((kernel)) testAcoshHalf4Half4(half4 inV) {
+    return acosh(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAcoshRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAcoshRelaxed.rs
index 4190d6e..81a8fa3 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAcoshRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAcoshRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAcospi.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAcospi.java
index 877f06b..1b37a07 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAcospi.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAcospi.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeAcospi(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeAcospi(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeAcospi(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeAcospi(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkAcospiHalfHalf() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x3b7a802cl, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testAcospiHalfHalf(inV, out);
+            verifyResultsAcospiHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcospiHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testAcospiHalfHalf(inV, out);
+            verifyResultsAcospiHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcospiHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAcospiHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeAcospi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkAcospiHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAcospiHalf2Half2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x3efecbeel, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testAcospiHalf2Half2(inV, out);
+            verifyResultsAcospiHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcospiHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testAcospiHalf2Half2(inV, out);
+            verifyResultsAcospiHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcospiHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAcospiHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeAcospi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkAcospiHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAcospiHalf3Half3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x9e0690e2l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testAcospiHalf3Half3(inV, out);
+            verifyResultsAcospiHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcospiHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testAcospiHalf3Half3(inV, out);
+            verifyResultsAcospiHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcospiHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAcospiHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeAcospi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkAcospiHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAcospiHalf4Half4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xfd0e55d6l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testAcospiHalf4Half4(inV, out);
+            verifyResultsAcospiHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcospiHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testAcospiHalf4Half4(inV, out);
+            verifyResultsAcospiHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcospiHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAcospiHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeAcospi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkAcospiHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testAcospi() {
         checkAcospiFloatFloat();
         checkAcospiFloat2Float2();
         checkAcospiFloat3Float3();
         checkAcospiFloat4Float4();
+        checkAcospiHalfHalf();
+        checkAcospiHalf2Half2();
+        checkAcospiHalf3Half3();
+        checkAcospiHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAcospi.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAcospi.rs
index 84d65b7..7654346 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAcospi.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAcospi.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testAcospiFloat4Float4(float4 inV) {
     return acospi(inV);
 }
+
+half __attribute__((kernel)) testAcospiHalfHalf(half inV) {
+    return acospi(inV);
+}
+
+half2 __attribute__((kernel)) testAcospiHalf2Half2(half2 inV) {
+    return acospi(inV);
+}
+
+half3 __attribute__((kernel)) testAcospiHalf3Half3(half3 inV) {
+    return acospi(inV);
+}
+
+half4 __attribute__((kernel)) testAcospiHalf4Half4(half4 inV) {
+    return acospi(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAcospiRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAcospiRelaxed.rs
index c3d887e..abca2f6 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAcospiRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAcospiRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAsin.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAsin.java
index 4f354fe..b1b626c 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAsin.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAsin.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeAsin(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeAsin(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeAsin(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeAsin(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkAsinHalfHalf() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x8f43a08cl, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testAsinHalfHalf(inV, out);
+            verifyResultsAsinHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testAsinHalfHalf(inV, out);
+            verifyResultsAsinHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAsinHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeAsin(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkAsinHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAsinHalf2Half2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x66a9a14el, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testAsinHalf2Half2(inV, out);
+            verifyResultsAsinHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testAsinHalf2Half2(inV, out);
+            verifyResultsAsinHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAsinHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeAsin(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkAsinHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAsinHalf3Half3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 3, 0xc5b16642l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testAsinHalf3Half3(inV, out);
+            verifyResultsAsinHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testAsinHalf3Half3(inV, out);
+            verifyResultsAsinHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAsinHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeAsin(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkAsinHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAsinHalf4Half4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x24b92b36l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testAsinHalf4Half4(inV, out);
+            verifyResultsAsinHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testAsinHalf4Half4(inV, out);
+            verifyResultsAsinHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAsinHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeAsin(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkAsinHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testAsin() {
         checkAsinFloatFloat();
         checkAsinFloat2Float2();
         checkAsinFloat3Float3();
         checkAsinFloat4Float4();
+        checkAsinHalfHalf();
+        checkAsinHalf2Half2();
+        checkAsinHalf3Half3();
+        checkAsinHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAsin.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAsin.rs
index 59313a4..29e5325 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAsin.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAsin.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testAsinFloat4Float4(float4 inV) {
     return asin(inV);
 }
+
+half __attribute__((kernel)) testAsinHalfHalf(half inV) {
+    return asin(inV);
+}
+
+half2 __attribute__((kernel)) testAsinHalf2Half2(half2 inV) {
+    return asin(inV);
+}
+
+half3 __attribute__((kernel)) testAsinHalf3Half3(half3 inV) {
+    return asin(inV);
+}
+
+half4 __attribute__((kernel)) testAsinHalf4Half4(half4 inV) {
+    return asin(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAsinRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAsinRelaxed.rs
index 6a08389..da9bd4d0 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAsinRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAsinRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAsinh.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAsinh.java
index c22e658..45ba8c8 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAsinh.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAsinh.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeAsinh(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeAsinh(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeAsinh(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeAsinh(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkAsinhHalfHalf() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xe509947el, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testAsinhHalfHalf(inV, out);
+            verifyResultsAsinhHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinhHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testAsinhHalfHalf(inV, out);
+            verifyResultsAsinhHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinhHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAsinhHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeAsinh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkAsinhHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAsinhHalf2Half2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xe9689030l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testAsinhHalf2Half2(inV, out);
+            verifyResultsAsinhHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinhHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testAsinhHalf2Half2(inV, out);
+            verifyResultsAsinhHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinhHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAsinhHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeAsinh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkAsinhHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAsinhHalf3Half3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x48705524l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testAsinhHalf3Half3(inV, out);
+            verifyResultsAsinhHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinhHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testAsinhHalf3Half3(inV, out);
+            verifyResultsAsinhHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinhHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAsinhHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeAsinh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkAsinhHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAsinhHalf4Half4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xa7781a18l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testAsinhHalf4Half4(inV, out);
+            verifyResultsAsinhHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinhHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testAsinhHalf4Half4(inV, out);
+            verifyResultsAsinhHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinhHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAsinhHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeAsinh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkAsinhHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testAsinh() {
         checkAsinhFloatFloat();
         checkAsinhFloat2Float2();
         checkAsinhFloat3Float3();
         checkAsinhFloat4Float4();
+        checkAsinhHalfHalf();
+        checkAsinhHalf2Half2();
+        checkAsinhHalf3Half3();
+        checkAsinhHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAsinh.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAsinh.rs
index 5c6f6c20..47d172d 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAsinh.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAsinh.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testAsinhFloat4Float4(float4 inV) {
     return asinh(inV);
 }
+
+half __attribute__((kernel)) testAsinhHalfHalf(half inV) {
+    return asinh(inV);
+}
+
+half2 __attribute__((kernel)) testAsinhHalf2Half2(half2 inV) {
+    return asinh(inV);
+}
+
+half3 __attribute__((kernel)) testAsinhHalf3Half3(half3 inV) {
+    return asinh(inV);
+}
+
+half4 __attribute__((kernel)) testAsinhHalf4Half4(half4 inV) {
+    return asinh(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAsinhRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAsinhRelaxed.rs
index 0d385ff..5820faa 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAsinhRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAsinhRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAsinpi.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAsinpi.java
index 5cd7a0e..3e4e481 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAsinpi.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAsinpi.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeAsinpi(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeAsinpi(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeAsinpi(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeAsinpi(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkAsinpiHalfHalf() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x63399e5fl, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testAsinpiHalfHalf(inV, out);
+            verifyResultsAsinpiHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinpiHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testAsinpiHalfHalf(inV, out);
+            verifyResultsAsinpiHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinpiHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAsinpiHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeAsinpi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkAsinpiHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAsinpiHalf2Half2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x525fea49l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testAsinpiHalf2Half2(inV, out);
+            verifyResultsAsinpiHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinpiHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testAsinpiHalf2Half2(inV, out);
+            verifyResultsAsinpiHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinpiHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAsinpiHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeAsinpi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkAsinpiHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAsinpiHalf3Half3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 3, 0xb167af3dl, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testAsinpiHalf3Half3(inV, out);
+            verifyResultsAsinpiHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinpiHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testAsinpiHalf3Half3(inV, out);
+            verifyResultsAsinpiHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinpiHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAsinpiHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeAsinpi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkAsinpiHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAsinpiHalf4Half4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x106f7431l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testAsinpiHalf4Half4(inV, out);
+            verifyResultsAsinpiHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinpiHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testAsinpiHalf4Half4(inV, out);
+            verifyResultsAsinpiHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinpiHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAsinpiHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeAsinpi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkAsinpiHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testAsinpi() {
         checkAsinpiFloatFloat();
         checkAsinpiFloat2Float2();
         checkAsinpiFloat3Float3();
         checkAsinpiFloat4Float4();
+        checkAsinpiHalfHalf();
+        checkAsinpiHalf2Half2();
+        checkAsinpiHalf3Half3();
+        checkAsinpiHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAsinpi.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAsinpi.rs
index 4bbbe13..92e347e 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAsinpi.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAsinpi.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testAsinpiFloat4Float4(float4 inV) {
     return asinpi(inV);
 }
+
+half __attribute__((kernel)) testAsinpiHalfHalf(half inV) {
+    return asinpi(inV);
+}
+
+half2 __attribute__((kernel)) testAsinpiHalf2Half2(half2 inV) {
+    return asinpi(inV);
+}
+
+half3 __attribute__((kernel)) testAsinpiHalf3Half3(half3 inV) {
+    return asinpi(inV);
+}
+
+half4 __attribute__((kernel)) testAsinpiHalf4Half4(half4 inV) {
+    return asinpi(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAsinpiRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAsinpiRelaxed.rs
index a0648dc..5fa2d67 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAsinpiRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAsinpiRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtan.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtan.java
index 331227a..8a16081 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtan.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtan.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeAtan(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeAtan(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeAtan(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeAtan(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkAtanHalfHalf() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xfa1813dfl, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testAtanHalfHalf(inV, out);
+            verifyResultsAtanHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testAtanHalfHalf(inV, out);
+            verifyResultsAtanHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAtanHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeAtan(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkAtanHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAtanHalf2Half2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xff1e93c9l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testAtanHalf2Half2(inV, out);
+            verifyResultsAtanHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testAtanHalf2Half2(inV, out);
+            verifyResultsAtanHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAtanHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeAtan(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkAtanHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAtanHalf3Half3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x5e2658bdl, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testAtanHalf3Half3(inV, out);
+            verifyResultsAtanHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testAtanHalf3Half3(inV, out);
+            verifyResultsAtanHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAtanHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeAtan(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkAtanHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAtanHalf4Half4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xbd2e1db1l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testAtanHalf4Half4(inV, out);
+            verifyResultsAtanHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testAtanHalf4Half4(inV, out);
+            verifyResultsAtanHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAtanHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeAtan(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkAtanHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testAtan() {
         checkAtanFloatFloat();
         checkAtanFloat2Float2();
         checkAtanFloat3Float3();
         checkAtanFloat4Float4();
+        checkAtanHalfHalf();
+        checkAtanHalf2Half2();
+        checkAtanHalf3Half3();
+        checkAtanHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtan.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtan.rs
index 1b987fa..bc57dc2 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtan.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtan.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testAtanFloat4Float4(float4 inV) {
     return atan(inV);
 }
+
+half __attribute__((kernel)) testAtanHalfHalf(half inV) {
+    return atan(inV);
+}
+
+half2 __attribute__((kernel)) testAtanHalf2Half2(half2 inV) {
+    return atan(inV);
+}
+
+half3 __attribute__((kernel)) testAtanHalf3Half3(half3 inV) {
+    return atan(inV);
+}
+
+half4 __attribute__((kernel)) testAtanHalf4Half4(half4 inV) {
+    return atan(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtan2.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtan2.java
index b8894cd..77f47e7 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtan2.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtan2.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -82,7 +83,7 @@
                 args.inNumerator = arrayInNumerator[i];
                 args.inDenominator = arrayInDenominator[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeAtan2(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -161,7 +162,7 @@
                 args.inNumerator = arrayInNumerator[i * 2 + j];
                 args.inDenominator = arrayInDenominator[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeAtan2(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -240,7 +241,7 @@
                 args.inNumerator = arrayInNumerator[i * 4 + j];
                 args.inDenominator = arrayInDenominator[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeAtan2(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -319,7 +320,7 @@
                 args.inNumerator = arrayInNumerator[i * 4 + j];
                 args.inDenominator = arrayInDenominator[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeAtan2(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -358,10 +359,358 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalfHalf {
+        public short inNumerator;
+        public double inNumeratorDouble;
+        public short inDenominator;
+        public double inDenominatorDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkAtan2HalfHalfHalf() {
+        Allocation inNumerator = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xa6793e31l, false);
+        Allocation inDenominator = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xc8fcd922l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.set_gAllocInDenominator(inDenominator);
+            script.forEach_testAtan2HalfHalfHalf(inNumerator, out);
+            verifyResultsAtan2HalfHalfHalf(inNumerator, inDenominator, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtan2HalfHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInDenominator(inDenominator);
+            scriptRelaxed.forEach_testAtan2HalfHalfHalf(inNumerator, out);
+            verifyResultsAtan2HalfHalfHalf(inNumerator, inDenominator, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtan2HalfHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAtan2HalfHalfHalf(Allocation inNumerator, Allocation inDenominator, Allocation out, boolean relaxed) {
+        short[] arrayInNumerator = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInNumerator, (short) 42);
+        inNumerator.copyTo(arrayInNumerator);
+        short[] arrayInDenominator = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInDenominator, (short) 42);
+        inDenominator.copyTo(arrayInDenominator);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inNumerator = arrayInNumerator[i];
+                args.inNumeratorDouble = Float16Utils.convertFloat16ToDouble(args.inNumerator);
+                args.inDenominator = arrayInDenominator[i];
+                args.inDenominatorDouble = Float16Utils.convertFloat16ToDouble(args.inDenominator);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeAtan2(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inNumerator: ");
+                        appendVariableToMessage(message, args.inNumerator);
+                        message.append("\n");
+                        message.append("Input inDenominator: ");
+                        appendVariableToMessage(message, args.inDenominator);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkAtan2HalfHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAtan2Half2Half2Half2() {
+        Allocation inNumerator = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xec117907l, false);
+        Allocation inDenominator = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x717dccc8l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.set_gAllocInDenominator(inDenominator);
+            script.forEach_testAtan2Half2Half2Half2(inNumerator, out);
+            verifyResultsAtan2Half2Half2Half2(inNumerator, inDenominator, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtan2Half2Half2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInDenominator(inDenominator);
+            scriptRelaxed.forEach_testAtan2Half2Half2Half2(inNumerator, out);
+            verifyResultsAtan2Half2Half2Half2(inNumerator, inDenominator, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtan2Half2Half2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAtan2Half2Half2Half2(Allocation inNumerator, Allocation inDenominator, Allocation out, boolean relaxed) {
+        short[] arrayInNumerator = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInNumerator, (short) 42);
+        inNumerator.copyTo(arrayInNumerator);
+        short[] arrayInDenominator = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInDenominator, (short) 42);
+        inDenominator.copyTo(arrayInDenominator);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inNumerator = arrayInNumerator[i * 2 + j];
+                args.inNumeratorDouble = Float16Utils.convertFloat16ToDouble(args.inNumerator);
+                args.inDenominator = arrayInDenominator[i * 2 + j];
+                args.inDenominatorDouble = Float16Utils.convertFloat16ToDouble(args.inDenominator);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeAtan2(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inNumerator: ");
+                        appendVariableToMessage(message, args.inNumerator);
+                        message.append("\n");
+                        message.append("Input inDenominator: ");
+                        appendVariableToMessage(message, args.inDenominator);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkAtan2Half2Half2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAtan2Half3Half3Half3() {
+        Allocation inNumerator = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x3783a976l, false);
+        Allocation inDenominator = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x5d3d9e7fl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.set_gAllocInDenominator(inDenominator);
+            script.forEach_testAtan2Half3Half3Half3(inNumerator, out);
+            verifyResultsAtan2Half3Half3Half3(inNumerator, inDenominator, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtan2Half3Half3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInDenominator(inDenominator);
+            scriptRelaxed.forEach_testAtan2Half3Half3Half3(inNumerator, out);
+            verifyResultsAtan2Half3Half3Half3(inNumerator, inDenominator, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtan2Half3Half3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAtan2Half3Half3Half3(Allocation inNumerator, Allocation inDenominator, Allocation out, boolean relaxed) {
+        short[] arrayInNumerator = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInNumerator, (short) 42);
+        inNumerator.copyTo(arrayInNumerator);
+        short[] arrayInDenominator = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInDenominator, (short) 42);
+        inDenominator.copyTo(arrayInDenominator);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inNumerator = arrayInNumerator[i * 4 + j];
+                args.inNumeratorDouble = Float16Utils.convertFloat16ToDouble(args.inNumerator);
+                args.inDenominator = arrayInDenominator[i * 4 + j];
+                args.inDenominatorDouble = Float16Utils.convertFloat16ToDouble(args.inDenominator);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeAtan2(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inNumerator: ");
+                        appendVariableToMessage(message, args.inNumerator);
+                        message.append("\n");
+                        message.append("Input inDenominator: ");
+                        appendVariableToMessage(message, args.inDenominator);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkAtan2Half3Half3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAtan2Half4Half4Half4() {
+        Allocation inNumerator = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x82f5d9e5l, false);
+        Allocation inDenominator = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x48fd7036l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.set_gAllocInDenominator(inDenominator);
+            script.forEach_testAtan2Half4Half4Half4(inNumerator, out);
+            verifyResultsAtan2Half4Half4Half4(inNumerator, inDenominator, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtan2Half4Half4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInDenominator(inDenominator);
+            scriptRelaxed.forEach_testAtan2Half4Half4Half4(inNumerator, out);
+            verifyResultsAtan2Half4Half4Half4(inNumerator, inDenominator, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtan2Half4Half4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAtan2Half4Half4Half4(Allocation inNumerator, Allocation inDenominator, Allocation out, boolean relaxed) {
+        short[] arrayInNumerator = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInNumerator, (short) 42);
+        inNumerator.copyTo(arrayInNumerator);
+        short[] arrayInDenominator = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInDenominator, (short) 42);
+        inDenominator.copyTo(arrayInDenominator);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inNumerator = arrayInNumerator[i * 4 + j];
+                args.inNumeratorDouble = Float16Utils.convertFloat16ToDouble(args.inNumerator);
+                args.inDenominator = arrayInDenominator[i * 4 + j];
+                args.inDenominatorDouble = Float16Utils.convertFloat16ToDouble(args.inDenominator);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeAtan2(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inNumerator: ");
+                        appendVariableToMessage(message, args.inNumerator);
+                        message.append("\n");
+                        message.append("Input inDenominator: ");
+                        appendVariableToMessage(message, args.inDenominator);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkAtan2Half4Half4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testAtan2() {
         checkAtan2FloatFloatFloat();
         checkAtan2Float2Float2Float2();
         checkAtan2Float3Float3Float3();
         checkAtan2Float4Float4Float4();
+        checkAtan2HalfHalfHalf();
+        checkAtan2Half2Half2Half2();
+        checkAtan2Half3Half3Half3();
+        checkAtan2Half4Half4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtan2.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtan2.rs
index 19b2ed4..229320b 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtan2.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtan2.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -40,3 +40,23 @@
     float4 inDenominator = rsGetElementAt_float4(gAllocInDenominator, x);
     return atan2(inNumerator, inDenominator);
 }
+
+half __attribute__((kernel)) testAtan2HalfHalfHalf(half inNumerator, unsigned int x) {
+    half inDenominator = rsGetElementAt_half(gAllocInDenominator, x);
+    return atan2(inNumerator, inDenominator);
+}
+
+half2 __attribute__((kernel)) testAtan2Half2Half2Half2(half2 inNumerator, unsigned int x) {
+    half2 inDenominator = rsGetElementAt_half2(gAllocInDenominator, x);
+    return atan2(inNumerator, inDenominator);
+}
+
+half3 __attribute__((kernel)) testAtan2Half3Half3Half3(half3 inNumerator, unsigned int x) {
+    half3 inDenominator = rsGetElementAt_half3(gAllocInDenominator, x);
+    return atan2(inNumerator, inDenominator);
+}
+
+half4 __attribute__((kernel)) testAtan2Half4Half4Half4(half4 inNumerator, unsigned int x) {
+    half4 inDenominator = rsGetElementAt_half4(gAllocInDenominator, x);
+    return atan2(inNumerator, inDenominator);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtan2Relaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtan2Relaxed.rs
index 54e930b..564ba1e 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtan2Relaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtan2Relaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtan2pi.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtan2pi.java
index f22b020..2d8539c 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtan2pi.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtan2pi.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -82,7 +83,7 @@
                 args.inNumerator = arrayInNumerator[i];
                 args.inDenominator = arrayInDenominator[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeAtan2pi(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -161,7 +162,7 @@
                 args.inNumerator = arrayInNumerator[i * 2 + j];
                 args.inDenominator = arrayInDenominator[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeAtan2pi(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -240,7 +241,7 @@
                 args.inNumerator = arrayInNumerator[i * 4 + j];
                 args.inDenominator = arrayInDenominator[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeAtan2pi(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -319,7 +320,7 @@
                 args.inNumerator = arrayInNumerator[i * 4 + j];
                 args.inDenominator = arrayInDenominator[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeAtan2pi(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -358,10 +359,358 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalfHalf {
+        public short inNumerator;
+        public double inNumeratorDouble;
+        public short inDenominator;
+        public double inDenominatorDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkAtan2piHalfHalfHalf() {
+        Allocation inNumerator = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x2ee67becl, false);
+        Allocation inDenominator = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x25ffb4c5l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.set_gAllocInDenominator(inDenominator);
+            script.forEach_testAtan2piHalfHalfHalf(inNumerator, out);
+            verifyResultsAtan2piHalfHalfHalf(inNumerator, inDenominator, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtan2piHalfHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInDenominator(inDenominator);
+            scriptRelaxed.forEach_testAtan2piHalfHalfHalf(inNumerator, out);
+            verifyResultsAtan2piHalfHalfHalf(inNumerator, inDenominator, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtan2piHalfHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAtan2piHalfHalfHalf(Allocation inNumerator, Allocation inDenominator, Allocation out, boolean relaxed) {
+        short[] arrayInNumerator = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInNumerator, (short) 42);
+        inNumerator.copyTo(arrayInNumerator);
+        short[] arrayInDenominator = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInDenominator, (short) 42);
+        inDenominator.copyTo(arrayInDenominator);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inNumerator = arrayInNumerator[i];
+                args.inNumeratorDouble = Float16Utils.convertFloat16ToDouble(args.inNumerator);
+                args.inDenominator = arrayInDenominator[i];
+                args.inDenominatorDouble = Float16Utils.convertFloat16ToDouble(args.inDenominator);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeAtan2pi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inNumerator: ");
+                        appendVariableToMessage(message, args.inNumerator);
+                        message.append("\n");
+                        message.append("Input inDenominator: ");
+                        appendVariableToMessage(message, args.inDenominator);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkAtan2piHalfHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAtan2piHalf2Half2Half2() {
+        Allocation inNumerator = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x8b8c5d68l, false);
+        Allocation inDenominator = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x50194d61l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.set_gAllocInDenominator(inDenominator);
+            script.forEach_testAtan2piHalf2Half2Half2(inNumerator, out);
+            verifyResultsAtan2piHalf2Half2Half2(inNumerator, inDenominator, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtan2piHalf2Half2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInDenominator(inDenominator);
+            scriptRelaxed.forEach_testAtan2piHalf2Half2Half2(inNumerator, out);
+            verifyResultsAtan2piHalf2Half2Half2(inNumerator, inDenominator, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtan2piHalf2Half2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAtan2piHalf2Half2Half2(Allocation inNumerator, Allocation inDenominator, Allocation out, boolean relaxed) {
+        short[] arrayInNumerator = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInNumerator, (short) 42);
+        inNumerator.copyTo(arrayInNumerator);
+        short[] arrayInDenominator = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInDenominator, (short) 42);
+        inDenominator.copyTo(arrayInDenominator);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inNumerator = arrayInNumerator[i * 2 + j];
+                args.inNumeratorDouble = Float16Utils.convertFloat16ToDouble(args.inNumerator);
+                args.inDenominator = arrayInDenominator[i * 2 + j];
+                args.inDenominatorDouble = Float16Utils.convertFloat16ToDouble(args.inDenominator);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeAtan2pi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inNumerator: ");
+                        appendVariableToMessage(message, args.inNumerator);
+                        message.append("\n");
+                        message.append("Input inDenominator: ");
+                        appendVariableToMessage(message, args.inDenominator);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkAtan2piHalf2Half2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAtan2piHalf3Half3Half3() {
+        Allocation inNumerator = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0xd6fe8dd7l, false);
+        Allocation inDenominator = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x3bd91f18l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.set_gAllocInDenominator(inDenominator);
+            script.forEach_testAtan2piHalf3Half3Half3(inNumerator, out);
+            verifyResultsAtan2piHalf3Half3Half3(inNumerator, inDenominator, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtan2piHalf3Half3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInDenominator(inDenominator);
+            scriptRelaxed.forEach_testAtan2piHalf3Half3Half3(inNumerator, out);
+            verifyResultsAtan2piHalf3Half3Half3(inNumerator, inDenominator, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtan2piHalf3Half3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAtan2piHalf3Half3Half3(Allocation inNumerator, Allocation inDenominator, Allocation out, boolean relaxed) {
+        short[] arrayInNumerator = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInNumerator, (short) 42);
+        inNumerator.copyTo(arrayInNumerator);
+        short[] arrayInDenominator = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInDenominator, (short) 42);
+        inDenominator.copyTo(arrayInDenominator);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inNumerator = arrayInNumerator[i * 4 + j];
+                args.inNumeratorDouble = Float16Utils.convertFloat16ToDouble(args.inNumerator);
+                args.inDenominator = arrayInDenominator[i * 4 + j];
+                args.inDenominatorDouble = Float16Utils.convertFloat16ToDouble(args.inDenominator);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeAtan2pi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inNumerator: ");
+                        appendVariableToMessage(message, args.inNumerator);
+                        message.append("\n");
+                        message.append("Input inDenominator: ");
+                        appendVariableToMessage(message, args.inDenominator);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkAtan2piHalf3Half3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAtan2piHalf4Half4Half4() {
+        Allocation inNumerator = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x2270be46l, false);
+        Allocation inDenominator = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x2798f0cfl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.set_gAllocInDenominator(inDenominator);
+            script.forEach_testAtan2piHalf4Half4Half4(inNumerator, out);
+            verifyResultsAtan2piHalf4Half4Half4(inNumerator, inDenominator, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtan2piHalf4Half4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInDenominator(inDenominator);
+            scriptRelaxed.forEach_testAtan2piHalf4Half4Half4(inNumerator, out);
+            verifyResultsAtan2piHalf4Half4Half4(inNumerator, inDenominator, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtan2piHalf4Half4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAtan2piHalf4Half4Half4(Allocation inNumerator, Allocation inDenominator, Allocation out, boolean relaxed) {
+        short[] arrayInNumerator = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInNumerator, (short) 42);
+        inNumerator.copyTo(arrayInNumerator);
+        short[] arrayInDenominator = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInDenominator, (short) 42);
+        inDenominator.copyTo(arrayInDenominator);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inNumerator = arrayInNumerator[i * 4 + j];
+                args.inNumeratorDouble = Float16Utils.convertFloat16ToDouble(args.inNumerator);
+                args.inDenominator = arrayInDenominator[i * 4 + j];
+                args.inDenominatorDouble = Float16Utils.convertFloat16ToDouble(args.inDenominator);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeAtan2pi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inNumerator: ");
+                        appendVariableToMessage(message, args.inNumerator);
+                        message.append("\n");
+                        message.append("Input inDenominator: ");
+                        appendVariableToMessage(message, args.inDenominator);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkAtan2piHalf4Half4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testAtan2pi() {
         checkAtan2piFloatFloatFloat();
         checkAtan2piFloat2Float2Float2();
         checkAtan2piFloat3Float3Float3();
         checkAtan2piFloat4Float4Float4();
+        checkAtan2piHalfHalfHalf();
+        checkAtan2piHalf2Half2Half2();
+        checkAtan2piHalf3Half3Half3();
+        checkAtan2piHalf4Half4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtan2pi.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtan2pi.rs
index 14d11d9..3daa107 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtan2pi.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtan2pi.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -40,3 +40,23 @@
     float4 inDenominator = rsGetElementAt_float4(gAllocInDenominator, x);
     return atan2pi(inNumerator, inDenominator);
 }
+
+half __attribute__((kernel)) testAtan2piHalfHalfHalf(half inNumerator, unsigned int x) {
+    half inDenominator = rsGetElementAt_half(gAllocInDenominator, x);
+    return atan2pi(inNumerator, inDenominator);
+}
+
+half2 __attribute__((kernel)) testAtan2piHalf2Half2Half2(half2 inNumerator, unsigned int x) {
+    half2 inDenominator = rsGetElementAt_half2(gAllocInDenominator, x);
+    return atan2pi(inNumerator, inDenominator);
+}
+
+half3 __attribute__((kernel)) testAtan2piHalf3Half3Half3(half3 inNumerator, unsigned int x) {
+    half3 inDenominator = rsGetElementAt_half3(gAllocInDenominator, x);
+    return atan2pi(inNumerator, inDenominator);
+}
+
+half4 __attribute__((kernel)) testAtan2piHalf4Half4Half4(half4 inNumerator, unsigned int x) {
+    half4 inDenominator = rsGetElementAt_half4(gAllocInDenominator, x);
+    return atan2pi(inNumerator, inDenominator);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtan2piRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtan2piRelaxed.rs
index 8682f5c..9429a81 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtan2piRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtan2piRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtanRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtanRelaxed.rs
index dce7eb4..d370e7f 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtanRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtanRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtanh.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtanh.java
index f292c1a..187d797 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtanh.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtanh.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeAtanh(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeAtanh(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeAtanh(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeAtanh(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkAtanhHalfHalf() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xd6b8f36fl, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testAtanhHalfHalf(inV, out);
+            verifyResultsAtanhHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanhHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testAtanhHalfHalf(inV, out);
+            verifyResultsAtanhHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanhHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAtanhHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeAtanh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkAtanhHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAtanhHalf2Half2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x850d4ad9l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testAtanhHalf2Half2(inV, out);
+            verifyResultsAtanhHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanhHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testAtanhHalf2Half2(inV, out);
+            verifyResultsAtanhHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanhHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAtanhHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeAtanh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkAtanhHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAtanhHalf3Half3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 3, 0xe4150fcdl, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testAtanhHalf3Half3(inV, out);
+            verifyResultsAtanhHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanhHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testAtanhHalf3Half3(inV, out);
+            verifyResultsAtanhHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanhHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAtanhHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeAtanh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkAtanhHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAtanhHalf4Half4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x431cd4c1l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testAtanhHalf4Half4(inV, out);
+            verifyResultsAtanhHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanhHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testAtanhHalf4Half4(inV, out);
+            verifyResultsAtanhHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanhHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAtanhHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeAtanh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkAtanhHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testAtanh() {
         checkAtanhFloatFloat();
         checkAtanhFloat2Float2();
         checkAtanhFloat3Float3();
         checkAtanhFloat4Float4();
+        checkAtanhHalfHalf();
+        checkAtanhHalf2Half2();
+        checkAtanhHalf3Half3();
+        checkAtanhHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtanh.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtanh.rs
index 06c11e9..082154c 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtanh.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtanh.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testAtanhFloat4Float4(float4 inV) {
     return atanh(inV);
 }
+
+half __attribute__((kernel)) testAtanhHalfHalf(half inV) {
+    return atanh(inV);
+}
+
+half2 __attribute__((kernel)) testAtanhHalf2Half2(half2 inV) {
+    return atanh(inV);
+}
+
+half3 __attribute__((kernel)) testAtanhHalf3Half3(half3 inV) {
+    return atanh(inV);
+}
+
+half4 __attribute__((kernel)) testAtanhHalf4Half4(half4 inV) {
+    return atanh(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtanhRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtanhRelaxed.rs
index 455c61b..00960a9 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtanhRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtanhRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtanpi.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtanpi.java
index ed33df6..36d8ae8 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtanpi.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtanpi.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeAtanpi(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeAtanpi(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeAtanpi(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeAtanpi(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkAtanpiHalfHalf() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xfbae90dal, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testAtanpiHalfHalf(inV, out);
+            verifyResultsAtanpiHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanpiHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testAtanpiHalfHalf(inV, out);
+            verifyResultsAtanpiHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanpiHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAtanpiHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeAtanpi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkAtanpiHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAtanpiHalf2Half2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x770b44acl, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testAtanpiHalf2Half2(inV, out);
+            verifyResultsAtanpiHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanpiHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testAtanpiHalf2Half2(inV, out);
+            verifyResultsAtanpiHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanpiHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAtanpiHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeAtanpi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkAtanpiHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAtanpiHalf3Half3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 3, 0xd61309a0l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testAtanpiHalf3Half3(inV, out);
+            verifyResultsAtanpiHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanpiHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testAtanpiHalf3Half3(inV, out);
+            verifyResultsAtanpiHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanpiHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAtanpiHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeAtanpi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkAtanpiHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAtanpiHalf4Half4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x351ace94l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testAtanpiHalf4Half4(inV, out);
+            verifyResultsAtanpiHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanpiHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testAtanpiHalf4Half4(inV, out);
+            verifyResultsAtanpiHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanpiHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAtanpiHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeAtanpi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkAtanpiHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testAtanpi() {
         checkAtanpiFloatFloat();
         checkAtanpiFloat2Float2();
         checkAtanpiFloat3Float3();
         checkAtanpiFloat4Float4();
+        checkAtanpiHalfHalf();
+        checkAtanpiHalf2Half2();
+        checkAtanpiHalf3Half3();
+        checkAtanpiHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtanpi.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtanpi.rs
index 501431a..b1185ee 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtanpi.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtanpi.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testAtanpiFloat4Float4(float4 inV) {
     return atanpi(inV);
 }
+
+half __attribute__((kernel)) testAtanpiHalfHalf(half inV) {
+    return atanpi(inV);
+}
+
+half2 __attribute__((kernel)) testAtanpiHalf2Half2(half2 inV) {
+    return atanpi(inV);
+}
+
+half3 __attribute__((kernel)) testAtanpiHalf3Half3(half3 inV) {
+    return atanpi(inV);
+}
+
+half4 __attribute__((kernel)) testAtanpiHalf4Half4(half4 inV) {
+    return atanpi(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtanpiRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtanpiRelaxed.rs
index 16acf54..09d487c 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtanpiRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtanpiRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCbrt.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCbrt.java
index 206b9bb..cd2592b 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCbrt.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCbrt.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeCbrt(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeCbrt(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeCbrt(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeCbrt(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkCbrtHalfHalf() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xc175945el, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testCbrtHalfHalf(inV, out);
+            verifyResultsCbrtHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCbrtHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testCbrtHalfHalf(inV, out);
+            verifyResultsCbrtHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCbrtHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCbrtHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeCbrt(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkCbrtHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkCbrtHalf2Half2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xf173a910l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testCbrtHalf2Half2(inV, out);
+            verifyResultsCbrtHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCbrtHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testCbrtHalf2Half2(inV, out);
+            verifyResultsCbrtHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCbrtHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCbrtHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeCbrt(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkCbrtHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkCbrtHalf3Half3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x507b6e04l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testCbrtHalf3Half3(inV, out);
+            verifyResultsCbrtHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCbrtHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testCbrtHalf3Half3(inV, out);
+            verifyResultsCbrtHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCbrtHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCbrtHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeCbrt(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkCbrtHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkCbrtHalf4Half4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xaf8332f8l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testCbrtHalf4Half4(inV, out);
+            verifyResultsCbrtHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCbrtHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testCbrtHalf4Half4(inV, out);
+            verifyResultsCbrtHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCbrtHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCbrtHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeCbrt(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkCbrtHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testCbrt() {
         checkCbrtFloatFloat();
         checkCbrtFloat2Float2();
         checkCbrtFloat3Float3();
         checkCbrtFloat4Float4();
+        checkCbrtHalfHalf();
+        checkCbrtHalf2Half2();
+        checkCbrtHalf3Half3();
+        checkCbrtHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCbrt.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCbrt.rs
index a7ee6ee..a9c1cc7 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCbrt.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCbrt.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testCbrtFloat4Float4(float4 inV) {
     return cbrt(inV);
 }
+
+half __attribute__((kernel)) testCbrtHalfHalf(half inV) {
+    return cbrt(inV);
+}
+
+half2 __attribute__((kernel)) testCbrtHalf2Half2(half2 inV) {
+    return cbrt(inV);
+}
+
+half3 __attribute__((kernel)) testCbrtHalf3Half3(half3 inV) {
+    return cbrt(inV);
+}
+
+half4 __attribute__((kernel)) testCbrtHalf4Half4(half4 inV) {
+    return cbrt(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCbrtRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCbrtRelaxed.rs
index 7e7f8bc..6a35bd8 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCbrtRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCbrtRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCeil.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCeil.java
index ea77e11..437479c 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCeil.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCeil.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeCeil(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeCeil(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeCeil(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeCeil(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkCeilHalfHalf() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x6f7686bel, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testCeilHalfHalf(inV, out);
+            verifyResultsCeilHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCeilHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testCeilHalfHalf(inV, out);
+            verifyResultsCeilHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCeilHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCeilHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeCeil(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkCeilHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkCeilHalf2Half2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xb64a4070l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testCeilHalf2Half2(inV, out);
+            verifyResultsCeilHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCeilHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testCeilHalf2Half2(inV, out);
+            verifyResultsCeilHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCeilHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCeilHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeCeil(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkCeilHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkCeilHalf3Half3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x15520564l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testCeilHalf3Half3(inV, out);
+            verifyResultsCeilHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCeilHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testCeilHalf3Half3(inV, out);
+            verifyResultsCeilHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCeilHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCeilHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeCeil(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkCeilHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkCeilHalf4Half4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x7459ca58l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testCeilHalf4Half4(inV, out);
+            verifyResultsCeilHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCeilHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testCeilHalf4Half4(inV, out);
+            verifyResultsCeilHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCeilHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCeilHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeCeil(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkCeilHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testCeil() {
         checkCeilFloatFloat();
         checkCeilFloat2Float2();
         checkCeilFloat3Float3();
         checkCeilFloat4Float4();
+        checkCeilHalfHalf();
+        checkCeilHalf2Half2();
+        checkCeilHalf3Half3();
+        checkCeilHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCeil.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCeil.rs
index 39a4c19..9cf05fc 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCeil.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCeil.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testCeilFloat4Float4(float4 inV) {
     return ceil(inV);
 }
+
+half __attribute__((kernel)) testCeilHalfHalf(half inV) {
+    return ceil(inV);
+}
+
+half2 __attribute__((kernel)) testCeilHalf2Half2(half2 inV) {
+    return ceil(inV);
+}
+
+half3 __attribute__((kernel)) testCeilHalf3Half3(half3 inV) {
+    return ceil(inV);
+}
+
+half4 __attribute__((kernel)) testCeilHalf4Half4(half4 inV) {
+    return ceil(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCeilRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCeilRelaxed.rs
index 90f2636..1ed24c76 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCeilRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCeilRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestClamp.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestClamp.java
index 8b0160c..7499b77 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestClamp.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestClamp.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -91,7 +92,7 @@
                 args.inMinValue = arrayInMinValue[i];
                 args.inMaxValue = arrayInMaxValue[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeClamp(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -181,7 +182,7 @@
                 args.inMinValue = arrayInMinValue[i * 2 + j];
                 args.inMaxValue = arrayInMaxValue[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeClamp(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -271,7 +272,7 @@
                 args.inMinValue = arrayInMinValue[i * 4 + j];
                 args.inMaxValue = arrayInMaxValue[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeClamp(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -361,7 +362,7 @@
                 args.inMinValue = arrayInMinValue[i * 4 + j];
                 args.inMaxValue = arrayInMaxValue[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeClamp(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -451,7 +452,7 @@
                 args.inMinValue = arrayInMinValue[i];
                 args.inMaxValue = arrayInMaxValue[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeClamp(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -541,7 +542,7 @@
                 args.inMinValue = arrayInMinValue[i];
                 args.inMaxValue = arrayInMaxValue[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeClamp(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -631,7 +632,7 @@
                 args.inMinValue = arrayInMinValue[i];
                 args.inMaxValue = arrayInMaxValue[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeClamp(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -5713,6 +5714,688 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalfHalfHalf {
+        public short inValue;
+        public double inValueDouble;
+        public short inMinValue;
+        public double inMinValueDouble;
+        public short inMaxValue;
+        public double inMaxValueDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkClampHalfHalfHalfHalf() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x4b82831l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xf102f883l, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x825fea89l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampHalfHalfHalfHalf(inValue, out);
+            verifyResultsClampHalfHalfHalfHalf(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampHalfHalfHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampHalfHalfHalfHalf(inValue, out);
+            verifyResultsClampHalfHalfHalfHalf(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampHalfHalfHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampHalfHalfHalfHalf(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        short[] arrayInValue = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInValue, (short) 42);
+        inValue.copyTo(arrayInValue);
+        short[] arrayInMinValue = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInMinValue, (short) 42);
+        inMinValue.copyTo(arrayInMinValue);
+        short[] arrayInMaxValue = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInMaxValue, (short) 42);
+        inMaxValue.copyTo(arrayInMaxValue);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalfHalf args = new ArgumentsHalfHalfHalfHalf();
+                args.inValue = arrayInValue[i];
+                args.inValueDouble = Float16Utils.convertFloat16ToDouble(args.inValue);
+                args.inMinValue = arrayInMinValue[i];
+                args.inMinValueDouble = Float16Utils.convertFloat16ToDouble(args.inMinValue);
+                args.inMaxValue = arrayInMaxValue[i];
+                args.inMaxValueDouble = Float16Utils.convertFloat16ToDouble(args.inMaxValue);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeClamp(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inValue: ");
+                        appendVariableToMessage(message, args.inValue);
+                        message.append("\n");
+                        message.append("Input inMinValue: ");
+                        appendVariableToMessage(message, args.inMinValue);
+                        message.append("\n");
+                        message.append("Input inMaxValue: ");
+                        appendVariableToMessage(message, args.inMaxValue);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkClampHalfHalfHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClampHalf2Half2Half2Half2() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xb1049715l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x6f2ebd6fl, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x8baf75l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampHalf2Half2Half2Half2(inValue, out);
+            verifyResultsClampHalf2Half2Half2Half2(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampHalf2Half2Half2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampHalf2Half2Half2Half2(inValue, out);
+            verifyResultsClampHalf2Half2Half2Half2(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampHalf2Half2Half2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampHalf2Half2Half2Half2(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        short[] arrayInValue = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInValue, (short) 42);
+        inValue.copyTo(arrayInValue);
+        short[] arrayInMinValue = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInMinValue, (short) 42);
+        inMinValue.copyTo(arrayInMinValue);
+        short[] arrayInMaxValue = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInMaxValue, (short) 42);
+        inMaxValue.copyTo(arrayInMaxValue);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalfHalf args = new ArgumentsHalfHalfHalfHalf();
+                args.inValue = arrayInValue[i * 2 + j];
+                args.inValueDouble = Float16Utils.convertFloat16ToDouble(args.inValue);
+                args.inMinValue = arrayInMinValue[i * 2 + j];
+                args.inMinValueDouble = Float16Utils.convertFloat16ToDouble(args.inMinValue);
+                args.inMaxValue = arrayInMaxValue[i * 2 + j];
+                args.inMaxValueDouble = Float16Utils.convertFloat16ToDouble(args.inMaxValue);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeClamp(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inValue: ");
+                        appendVariableToMessage(message, args.inValue);
+                        message.append("\n");
+                        message.append("Input inMinValue: ");
+                        appendVariableToMessage(message, args.inMinValue);
+                        message.append("\n");
+                        message.append("Input inMaxValue: ");
+                        appendVariableToMessage(message, args.inMaxValue);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkClampHalf2Half2Half2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClampHalf3Half3Half3Half3() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0xa6d9935dl, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x81facac7l, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x1357bccdl, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampHalf3Half3Half3Half3(inValue, out);
+            verifyResultsClampHalf3Half3Half3Half3(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampHalf3Half3Half3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampHalf3Half3Half3Half3(inValue, out);
+            verifyResultsClampHalf3Half3Half3Half3(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampHalf3Half3Half3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampHalf3Half3Half3Half3(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        short[] arrayInValue = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInValue, (short) 42);
+        inValue.copyTo(arrayInValue);
+        short[] arrayInMinValue = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInMinValue, (short) 42);
+        inMinValue.copyTo(arrayInMinValue);
+        short[] arrayInMaxValue = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInMaxValue, (short) 42);
+        inMaxValue.copyTo(arrayInMaxValue);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalfHalf args = new ArgumentsHalfHalfHalfHalf();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inValueDouble = Float16Utils.convertFloat16ToDouble(args.inValue);
+                args.inMinValue = arrayInMinValue[i * 4 + j];
+                args.inMinValueDouble = Float16Utils.convertFloat16ToDouble(args.inMinValue);
+                args.inMaxValue = arrayInMaxValue[i * 4 + j];
+                args.inMaxValueDouble = Float16Utils.convertFloat16ToDouble(args.inMaxValue);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeClamp(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inValue: ");
+                        appendVariableToMessage(message, args.inValue);
+                        message.append("\n");
+                        message.append("Input inMinValue: ");
+                        appendVariableToMessage(message, args.inMinValue);
+                        message.append("\n");
+                        message.append("Input inMaxValue: ");
+                        appendVariableToMessage(message, args.inMaxValue);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkClampHalf3Half3Half3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClampHalf4Half4Half4Half4() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x9cae8fa5l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x94c6d81fl, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x2623ca25l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampHalf4Half4Half4Half4(inValue, out);
+            verifyResultsClampHalf4Half4Half4Half4(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampHalf4Half4Half4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampHalf4Half4Half4Half4(inValue, out);
+            verifyResultsClampHalf4Half4Half4Half4(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampHalf4Half4Half4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampHalf4Half4Half4Half4(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        short[] arrayInValue = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInValue, (short) 42);
+        inValue.copyTo(arrayInValue);
+        short[] arrayInMinValue = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInMinValue, (short) 42);
+        inMinValue.copyTo(arrayInMinValue);
+        short[] arrayInMaxValue = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInMaxValue, (short) 42);
+        inMaxValue.copyTo(arrayInMaxValue);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalfHalf args = new ArgumentsHalfHalfHalfHalf();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inValueDouble = Float16Utils.convertFloat16ToDouble(args.inValue);
+                args.inMinValue = arrayInMinValue[i * 4 + j];
+                args.inMinValueDouble = Float16Utils.convertFloat16ToDouble(args.inMinValue);
+                args.inMaxValue = arrayInMaxValue[i * 4 + j];
+                args.inMaxValueDouble = Float16Utils.convertFloat16ToDouble(args.inMaxValue);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeClamp(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inValue: ");
+                        appendVariableToMessage(message, args.inValue);
+                        message.append("\n");
+                        message.append("Input inMinValue: ");
+                        appendVariableToMessage(message, args.inMinValue);
+                        message.append("\n");
+                        message.append("Input inMaxValue: ");
+                        appendVariableToMessage(message, args.inMaxValue);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkClampHalf4Half4Half4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClampHalf2HalfHalfHalf2() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x35f68507l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xbc3d6b65l, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x4d9a5d6bl, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampHalf2HalfHalfHalf2(inValue, out);
+            verifyResultsClampHalf2HalfHalfHalf2(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampHalf2HalfHalfHalf2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampHalf2HalfHalfHalf2(inValue, out);
+            verifyResultsClampHalf2HalfHalfHalf2(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampHalf2HalfHalfHalf2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampHalf2HalfHalfHalf2(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        short[] arrayInValue = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInValue, (short) 42);
+        inValue.copyTo(arrayInValue);
+        short[] arrayInMinValue = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInMinValue, (short) 42);
+        inMinValue.copyTo(arrayInMinValue);
+        short[] arrayInMaxValue = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInMaxValue, (short) 42);
+        inMaxValue.copyTo(arrayInMaxValue);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalfHalf args = new ArgumentsHalfHalfHalfHalf();
+                args.inValue = arrayInValue[i * 2 + j];
+                args.inValueDouble = Float16Utils.convertFloat16ToDouble(args.inValue);
+                args.inMinValue = arrayInMinValue[i];
+                args.inMinValueDouble = Float16Utils.convertFloat16ToDouble(args.inMinValue);
+                args.inMaxValue = arrayInMaxValue[i];
+                args.inMaxValueDouble = Float16Utils.convertFloat16ToDouble(args.inMaxValue);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeClamp(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inValue: ");
+                        appendVariableToMessage(message, args.inValue);
+                        message.append("\n");
+                        message.append("Input inMinValue: ");
+                        appendVariableToMessage(message, args.inMinValue);
+                        message.append("\n");
+                        message.append("Input inMaxValue: ");
+                        appendVariableToMessage(message, args.inMaxValue);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkClampHalf2HalfHalfHalf2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClampHalf3HalfHalfHalf3() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x1f414e1bl, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x41ad19e1l, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xd30a0be7l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampHalf3HalfHalfHalf3(inValue, out);
+            verifyResultsClampHalf3HalfHalfHalf3(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampHalf3HalfHalfHalf3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampHalf3HalfHalfHalf3(inValue, out);
+            verifyResultsClampHalf3HalfHalfHalf3(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampHalf3HalfHalfHalf3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampHalf3HalfHalfHalf3(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        short[] arrayInValue = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInValue, (short) 42);
+        inValue.copyTo(arrayInValue);
+        short[] arrayInMinValue = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInMinValue, (short) 42);
+        inMinValue.copyTo(arrayInMinValue);
+        short[] arrayInMaxValue = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInMaxValue, (short) 42);
+        inMaxValue.copyTo(arrayInMaxValue);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalfHalf args = new ArgumentsHalfHalfHalfHalf();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inValueDouble = Float16Utils.convertFloat16ToDouble(args.inValue);
+                args.inMinValue = arrayInMinValue[i];
+                args.inMinValueDouble = Float16Utils.convertFloat16ToDouble(args.inMinValue);
+                args.inMaxValue = arrayInMaxValue[i];
+                args.inMaxValueDouble = Float16Utils.convertFloat16ToDouble(args.inMaxValue);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeClamp(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inValue: ");
+                        appendVariableToMessage(message, args.inValue);
+                        message.append("\n");
+                        message.append("Input inMinValue: ");
+                        appendVariableToMessage(message, args.inMinValue);
+                        message.append("\n");
+                        message.append("Input inMaxValue: ");
+                        appendVariableToMessage(message, args.inMaxValue);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkClampHalf3HalfHalfHalf3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClampHalf4HalfHalfHalf4() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x88c172fl, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xc71cc85dl, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x5879ba63l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampHalf4HalfHalfHalf4(inValue, out);
+            verifyResultsClampHalf4HalfHalfHalf4(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampHalf4HalfHalfHalf4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampHalf4HalfHalfHalf4(inValue, out);
+            verifyResultsClampHalf4HalfHalfHalf4(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampHalf4HalfHalfHalf4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampHalf4HalfHalfHalf4(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        short[] arrayInValue = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInValue, (short) 42);
+        inValue.copyTo(arrayInValue);
+        short[] arrayInMinValue = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInMinValue, (short) 42);
+        inMinValue.copyTo(arrayInMinValue);
+        short[] arrayInMaxValue = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInMaxValue, (short) 42);
+        inMaxValue.copyTo(arrayInMaxValue);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalfHalf args = new ArgumentsHalfHalfHalfHalf();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inValueDouble = Float16Utils.convertFloat16ToDouble(args.inValue);
+                args.inMinValue = arrayInMinValue[i];
+                args.inMinValueDouble = Float16Utils.convertFloat16ToDouble(args.inMinValue);
+                args.inMaxValue = arrayInMaxValue[i];
+                args.inMaxValueDouble = Float16Utils.convertFloat16ToDouble(args.inMaxValue);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeClamp(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inValue: ");
+                        appendVariableToMessage(message, args.inValue);
+                        message.append("\n");
+                        message.append("Input inMinValue: ");
+                        appendVariableToMessage(message, args.inMinValue);
+                        message.append("\n");
+                        message.append("Input inMaxValue: ");
+                        appendVariableToMessage(message, args.inMaxValue);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkClampHalf4HalfHalfHalf4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testClamp() {
         checkClampFloatFloatFloatFloat();
         checkClampFloat2Float2Float2Float2();
@@ -5777,5 +6460,12 @@
         checkClampUlong2UlongUlongUlong2();
         checkClampUlong3UlongUlongUlong3();
         checkClampUlong4UlongUlongUlong4();
+        checkClampHalfHalfHalfHalf();
+        checkClampHalf2Half2Half2Half2();
+        checkClampHalf3Half3Half3Half3();
+        checkClampHalf4Half4Half4Half4();
+        checkClampHalf2HalfHalfHalf2();
+        checkClampHalf3HalfHalfHalf3();
+        checkClampHalf4HalfHalfHalf4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestClamp.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestClamp.rs
index 6035974..808c27c 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestClamp.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestClamp.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -399,3 +399,45 @@
     ulong inMaxValue = rsGetElementAt_ulong(gAllocInMaxValue, x);
     return clamp(inValue, inMinValue, inMaxValue);
 }
+
+half __attribute__((kernel)) testClampHalfHalfHalfHalf(half inValue, unsigned int x) {
+    half inMinValue = rsGetElementAt_half(gAllocInMinValue, x);
+    half inMaxValue = rsGetElementAt_half(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+half2 __attribute__((kernel)) testClampHalf2Half2Half2Half2(half2 inValue, unsigned int x) {
+    half2 inMinValue = rsGetElementAt_half2(gAllocInMinValue, x);
+    half2 inMaxValue = rsGetElementAt_half2(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+half3 __attribute__((kernel)) testClampHalf3Half3Half3Half3(half3 inValue, unsigned int x) {
+    half3 inMinValue = rsGetElementAt_half3(gAllocInMinValue, x);
+    half3 inMaxValue = rsGetElementAt_half3(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+half4 __attribute__((kernel)) testClampHalf4Half4Half4Half4(half4 inValue, unsigned int x) {
+    half4 inMinValue = rsGetElementAt_half4(gAllocInMinValue, x);
+    half4 inMaxValue = rsGetElementAt_half4(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+half2 __attribute__((kernel)) testClampHalf2HalfHalfHalf2(half2 inValue, unsigned int x) {
+    half inMinValue = rsGetElementAt_half(gAllocInMinValue, x);
+    half inMaxValue = rsGetElementAt_half(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+half3 __attribute__((kernel)) testClampHalf3HalfHalfHalf3(half3 inValue, unsigned int x) {
+    half inMinValue = rsGetElementAt_half(gAllocInMinValue, x);
+    half inMaxValue = rsGetElementAt_half(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+half4 __attribute__((kernel)) testClampHalf4HalfHalfHalf4(half4 inValue, unsigned int x) {
+    half inMinValue = rsGetElementAt_half(gAllocInMinValue, x);
+    half inMaxValue = rsGetElementAt_half(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestClampRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestClampRelaxed.rs
index 6d9474d..0117c74 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestClampRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestClampRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestClz.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestClz.java
index d2fe5df..fac24c9 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestClz.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestClz.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestClz.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestClz.rs
index 40570bd..65def50 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestClz.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestClz.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestClzRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestClzRelaxed.rs
index 27af443..febe4d4 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestClzRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestClzRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestConvert.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestConvert.java
index 0db6576..d7fbb9a 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestConvert.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestConvert.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeConvert(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeConvert(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeConvert(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -286,7 +287,7 @@
                 ArgumentsCharFloat args = new ArgumentsCharFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeConvert(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -355,7 +356,7 @@
                 ArgumentsCharFloat args = new ArgumentsCharFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeConvert(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -424,7 +425,7 @@
                 ArgumentsCharFloat args = new ArgumentsCharFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeConvert(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -498,7 +499,7 @@
                 ArgumentsUcharFloat args = new ArgumentsUcharFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeConvert(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -567,7 +568,7 @@
                 ArgumentsUcharFloat args = new ArgumentsUcharFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeConvert(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -636,7 +637,7 @@
                 ArgumentsUcharFloat args = new ArgumentsUcharFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeConvert(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -710,7 +711,7 @@
                 ArgumentsShortFloat args = new ArgumentsShortFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeConvert(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -779,7 +780,7 @@
                 ArgumentsShortFloat args = new ArgumentsShortFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeConvert(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -848,7 +849,7 @@
                 ArgumentsShortFloat args = new ArgumentsShortFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeConvert(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -922,7 +923,7 @@
                 ArgumentsUshortFloat args = new ArgumentsUshortFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeConvert(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -991,7 +992,7 @@
                 ArgumentsUshortFloat args = new ArgumentsUshortFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeConvert(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -1060,7 +1061,7 @@
                 ArgumentsUshortFloat args = new ArgumentsUshortFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeConvert(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -1134,7 +1135,7 @@
                 ArgumentsIntFloat args = new ArgumentsIntFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeConvert(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -1203,7 +1204,7 @@
                 ArgumentsIntFloat args = new ArgumentsIntFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeConvert(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -1272,7 +1273,7 @@
                 ArgumentsIntFloat args = new ArgumentsIntFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeConvert(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -1346,7 +1347,7 @@
                 ArgumentsUintFloat args = new ArgumentsUintFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeConvert(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -1415,7 +1416,7 @@
                 ArgumentsUintFloat args = new ArgumentsUintFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeConvert(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -1484,7 +1485,7 @@
                 ArgumentsUintFloat args = new ArgumentsUintFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeConvert(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -10336,7 +10337,7 @@
                 ArgumentsDoubleDouble args = new ArgumentsDoubleDouble();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.DOUBLE, relaxed);
                 CoreMathVerifier.computeConvert(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -10405,7 +10406,7 @@
                 ArgumentsDoubleDouble args = new ArgumentsDoubleDouble();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.DOUBLE, relaxed);
                 CoreMathVerifier.computeConvert(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -10474,7 +10475,7 @@
                 ArgumentsDoubleDouble args = new ArgumentsDoubleDouble();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.DOUBLE, relaxed);
                 CoreMathVerifier.computeConvert(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -10548,7 +10549,7 @@
                 ArgumentsLongDouble args = new ArgumentsLongDouble();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.DOUBLE, relaxed);
                 CoreMathVerifier.computeConvert(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -10617,7 +10618,7 @@
                 ArgumentsLongDouble args = new ArgumentsLongDouble();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.DOUBLE, relaxed);
                 CoreMathVerifier.computeConvert(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -10686,7 +10687,7 @@
                 ArgumentsLongDouble args = new ArgumentsLongDouble();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.DOUBLE, relaxed);
                 CoreMathVerifier.computeConvert(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -10760,7 +10761,7 @@
                 ArgumentsUlongDouble args = new ArgumentsUlongDouble();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.DOUBLE, relaxed);
                 CoreMathVerifier.computeConvert(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -10829,7 +10830,7 @@
                 ArgumentsUlongDouble args = new ArgumentsUlongDouble();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.DOUBLE, relaxed);
                 CoreMathVerifier.computeConvert(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -10898,7 +10899,7 @@
                 ArgumentsUlongDouble args = new ArgumentsUlongDouble();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.DOUBLE, relaxed);
                 CoreMathVerifier.computeConvert(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -10940,7 +10941,7 @@
     }
 
     private void checkConvertDouble2Long2() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 2, 0x430cbe95l, -4.2949662730000000000e+09, 4.2949662720000000000e+09);
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 2, 0x430cbe95l, -9.2233720368547747840e+18, 9.2233720368547747840e+18);
         try {
             Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 2), INPUTSIZE);
             script.forEach_testConvertLong2Double2Long2(inV, out);
@@ -11008,7 +11009,7 @@
     }
 
     private void checkConvertDouble3Long3() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 3, 0xa2148389l, -4.2949662730000000000e+09, 4.2949662720000000000e+09);
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 3, 0xa2148389l, -9.2233720368547747840e+18, 9.2233720368547747840e+18);
         try {
             Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 3), INPUTSIZE);
             script.forEach_testConvertLong3Double3Long3(inV, out);
@@ -11076,7 +11077,7 @@
     }
 
     private void checkConvertDouble4Long4() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 4, 0x11c487dl, -4.2949662730000000000e+09, 4.2949662720000000000e+09);
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 4, 0x11c487dl, -9.2233720368547747840e+18, 9.2233720368547747840e+18);
         try {
             Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 4), INPUTSIZE);
             script.forEach_testConvertLong4Double4Long4(inV, out);
@@ -11567,7 +11568,7 @@
     }
 
     private void checkConvertDouble2Ulong2() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 2, 0x7e12ff5el, 0.0000000000000000000e+00, 4.2949652480000000000e+09);
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 2, 0x7e12ff5el, 0.0000000000000000000e+00, 1.8446744073709549568e+19);
         try {
             Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 2), INPUTSIZE);
             script.forEach_testConvertUlong2Double2Ulong2(inV, out);
@@ -11635,7 +11636,7 @@
     }
 
     private void checkConvertDouble3Ulong3() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 3, 0x742e203cl, 0.0000000000000000000e+00, 4.2949652480000000000e+09);
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 3, 0x742e203cl, 0.0000000000000000000e+00, 1.8446744073709549568e+19);
         try {
             Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 3), INPUTSIZE);
             script.forEach_testConvertUlong3Double3Ulong3(inV, out);
@@ -11703,7 +11704,7 @@
     }
 
     private void checkConvertDouble4Ulong4() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 4, 0x6a49411al, 0.0000000000000000000e+00, 4.2949652480000000000e+09);
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 4, 0x6a49411al, 0.0000000000000000000e+00, 1.8446744073709549568e+19);
         try {
             Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 4), INPUTSIZE);
             script.forEach_testConvertUlong4Double4Ulong4(inV, out);
@@ -12226,7 +12227,7 @@
                 ArgumentsDoubleFloat args = new ArgumentsDoubleFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeConvert(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -12295,7 +12296,7 @@
                 ArgumentsDoubleFloat args = new ArgumentsDoubleFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeConvert(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -12364,7 +12365,7 @@
                 ArgumentsDoubleFloat args = new ArgumentsDoubleFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeConvert(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -12438,7 +12439,7 @@
                 ArgumentsLongFloat args = new ArgumentsLongFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeConvert(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -12507,7 +12508,7 @@
                 ArgumentsLongFloat args = new ArgumentsLongFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeConvert(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -12576,7 +12577,7 @@
                 ArgumentsLongFloat args = new ArgumentsLongFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeConvert(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -12650,7 +12651,7 @@
                 ArgumentsUlongFloat args = new ArgumentsUlongFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeConvert(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -12719,7 +12720,7 @@
                 ArgumentsUlongFloat args = new ArgumentsUlongFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeConvert(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -12788,7 +12789,7 @@
                 ArgumentsUlongFloat args = new ArgumentsUlongFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeConvert(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -16624,7 +16625,7 @@
                 ArgumentsFloatDouble args = new ArgumentsFloatDouble();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.DOUBLE, relaxed);
                 CoreMathVerifier.computeConvert(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -16693,7 +16694,7 @@
                 ArgumentsFloatDouble args = new ArgumentsFloatDouble();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.DOUBLE, relaxed);
                 CoreMathVerifier.computeConvert(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -16762,7 +16763,7 @@
                 ArgumentsFloatDouble args = new ArgumentsFloatDouble();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.DOUBLE, relaxed);
                 CoreMathVerifier.computeConvert(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -16836,7 +16837,7 @@
                 ArgumentsCharDouble args = new ArgumentsCharDouble();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.DOUBLE, relaxed);
                 CoreMathVerifier.computeConvert(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -16905,7 +16906,7 @@
                 ArgumentsCharDouble args = new ArgumentsCharDouble();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.DOUBLE, relaxed);
                 CoreMathVerifier.computeConvert(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -16974,7 +16975,7 @@
                 ArgumentsCharDouble args = new ArgumentsCharDouble();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.DOUBLE, relaxed);
                 CoreMathVerifier.computeConvert(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -17048,7 +17049,7 @@
                 ArgumentsUcharDouble args = new ArgumentsUcharDouble();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.DOUBLE, relaxed);
                 CoreMathVerifier.computeConvert(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -17117,7 +17118,7 @@
                 ArgumentsUcharDouble args = new ArgumentsUcharDouble();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.DOUBLE, relaxed);
                 CoreMathVerifier.computeConvert(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -17186,7 +17187,7 @@
                 ArgumentsUcharDouble args = new ArgumentsUcharDouble();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.DOUBLE, relaxed);
                 CoreMathVerifier.computeConvert(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -17260,7 +17261,7 @@
                 ArgumentsShortDouble args = new ArgumentsShortDouble();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.DOUBLE, relaxed);
                 CoreMathVerifier.computeConvert(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -17329,7 +17330,7 @@
                 ArgumentsShortDouble args = new ArgumentsShortDouble();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.DOUBLE, relaxed);
                 CoreMathVerifier.computeConvert(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -17398,7 +17399,7 @@
                 ArgumentsShortDouble args = new ArgumentsShortDouble();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.DOUBLE, relaxed);
                 CoreMathVerifier.computeConvert(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -17472,7 +17473,7 @@
                 ArgumentsUshortDouble args = new ArgumentsUshortDouble();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.DOUBLE, relaxed);
                 CoreMathVerifier.computeConvert(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -17541,7 +17542,7 @@
                 ArgumentsUshortDouble args = new ArgumentsUshortDouble();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.DOUBLE, relaxed);
                 CoreMathVerifier.computeConvert(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -17610,7 +17611,7 @@
                 ArgumentsUshortDouble args = new ArgumentsUshortDouble();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.DOUBLE, relaxed);
                 CoreMathVerifier.computeConvert(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -17684,7 +17685,7 @@
                 ArgumentsIntDouble args = new ArgumentsIntDouble();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.DOUBLE, relaxed);
                 CoreMathVerifier.computeConvert(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -17753,7 +17754,7 @@
                 ArgumentsIntDouble args = new ArgumentsIntDouble();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.DOUBLE, relaxed);
                 CoreMathVerifier.computeConvert(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -17822,7 +17823,7 @@
                 ArgumentsIntDouble args = new ArgumentsIntDouble();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.DOUBLE, relaxed);
                 CoreMathVerifier.computeConvert(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -17896,7 +17897,7 @@
                 ArgumentsUintDouble args = new ArgumentsUintDouble();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.DOUBLE, relaxed);
                 CoreMathVerifier.computeConvert(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -17965,7 +17966,7 @@
                 ArgumentsUintDouble args = new ArgumentsUintDouble();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.DOUBLE, relaxed);
                 CoreMathVerifier.computeConvert(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -18034,7 +18035,7 @@
                 ArgumentsUintDouble args = new ArgumentsUintDouble();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.DOUBLE, relaxed);
                 CoreMathVerifier.computeConvert(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -18076,7 +18077,7 @@
     }
 
     private void checkConvertFloat2Long2() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x7d7c0ae0l, -1.0000000000000000000e+00, 0.0000000000000000000e+00);
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x7d7c0ae0l, -9.2233714870989619200e+18, 9.2233714870989619200e+18);
         try {
             Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 2), INPUTSIZE);
             script.forEach_testConvertLong2Float2Long2(inV, out);
@@ -18144,7 +18145,7 @@
     }
 
     private void checkConvertFloat3Long3() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xdc83cfd4l, -1.0000000000000000000e+00, 0.0000000000000000000e+00);
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xdc83cfd4l, -9.2233714870989619200e+18, 9.2233714870989619200e+18);
         try {
             Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 3), INPUTSIZE);
             script.forEach_testConvertLong3Float3Long3(inV, out);
@@ -18212,7 +18213,7 @@
     }
 
     private void checkConvertFloat4Long4() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x3b8b94c8l, -1.0000000000000000000e+00, 0.0000000000000000000e+00);
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x3b8b94c8l, -9.2233714870989619200e+18, 9.2233714870989619200e+18);
         try {
             Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 4), INPUTSIZE);
             script.forEach_testConvertLong4Float4Long4(inV, out);
@@ -19539,7 +19540,7 @@
     }
 
     private void checkConvertFloat2Ulong2() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x4ec4cff7l, 0.0000000000000000000e+00, 0.0000000000000000000e+00);
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x4ec4cff7l, 0.0000000000000000000e+00, 1.8446742974197923840e+19);
         try {
             Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 2), INPUTSIZE);
             script.forEach_testConvertUlong2Float2Ulong2(inV, out);
@@ -19607,7 +19608,7 @@
     }
 
     private void checkConvertFloat3Ulong3() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x44dff0d5l, 0.0000000000000000000e+00, 0.0000000000000000000e+00);
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x44dff0d5l, 0.0000000000000000000e+00, 1.8446742974197923840e+19);
         try {
             Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 3), INPUTSIZE);
             script.forEach_testConvertUlong3Float3Ulong3(inV, out);
@@ -19675,7 +19676,7 @@
     }
 
     private void checkConvertFloat4Ulong4() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x3afb11b3l, 0.0000000000000000000e+00, 0.0000000000000000000e+00);
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x3afb11b3l, 0.0000000000000000000e+00, 1.8446742974197923840e+19);
         try {
             Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 4), INPUTSIZE);
             script.forEach_testConvertUlong4Float4Ulong4(inV, out);
@@ -20996,6 +20997,4577 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkConvertHalf2Half2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x77294e2el, -3.1129599999999998545e+04, 3.1129599999999998545e+04);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testConvertHalf2Half2Half2(inV, out);
+            verifyResultsConvertHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf2Half2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertHalf2Half2Half2(inV, out);
+            verifyResultsConvertHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf2Half2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeConvert(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkConvertHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertHalf3Half3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 3, 0xd6311322l, -3.1129599999999998545e+04, 3.1129599999999998545e+04);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testConvertHalf3Half3Half3(inV, out);
+            verifyResultsConvertHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf3Half3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertHalf3Half3Half3(inV, out);
+            verifyResultsConvertHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf3Half3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeConvert(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkConvertHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertHalf4Half4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x3538d816l, -3.1129599999999998545e+04, 3.1129599999999998545e+04);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testConvertHalf4Half4Half4(inV, out);
+            verifyResultsConvertHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf4Half4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertHalf4Half4Half4(inV, out);
+            verifyResultsConvertHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf4Half4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeConvert(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkConvertHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsHalfFloat {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkConvertHalf2Float2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xbbc7b5dbl, -3.1129599999999998545e+04, 3.1129599999999998545e+04);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testConvertFloat2Half2Float2(inV, out);
+            verifyResultsConvertHalf2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat2Half2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertFloat2Half2Float2(inV, out);
+            verifyResultsConvertHalf2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat2Half2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertHalf2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (float) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfFloat args = new ArgumentsHalfFloat();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
+                CoreMathVerifier.computeConvert(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkConvertHalf2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertHalf3Float3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 3, 0xb1e2d6b9l, -3.1129599999999998545e+04, 3.1129599999999998545e+04);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testConvertFloat3Half3Float3(inV, out);
+            verifyResultsConvertHalf3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat3Half3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertFloat3Half3Float3(inV, out);
+            verifyResultsConvertHalf3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat3Half3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertHalf3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (float) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfFloat args = new ArgumentsHalfFloat();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
+                CoreMathVerifier.computeConvert(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkConvertHalf3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertHalf4Float4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xa7fdf797l, -3.1129599999999998545e+04, 3.1129599999999998545e+04);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testConvertFloat4Half4Float4(inV, out);
+            verifyResultsConvertHalf4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat4Half4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertFloat4Half4Float4(inV, out);
+            verifyResultsConvertHalf4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat4Half4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertHalf4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (float) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfFloat args = new ArgumentsHalfFloat();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
+                CoreMathVerifier.computeConvert(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkConvertHalf4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsHalfDouble {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkConvertHalf2Double2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xb2251ea8l, -3.1129599999999998545e+04, 3.1129599999999998545e+04);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 2), INPUTSIZE);
+            script.forEach_testConvertDouble2Half2Double2(inV, out);
+            verifyResultsConvertHalf2Double2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble2Half2Double2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertDouble2Half2Double2(inV, out);
+            verifyResultsConvertHalf2Double2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble2Half2Double2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertHalf2Double2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        double[] arrayOut = new double[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (double) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfDouble args = new ArgumentsHalfDouble();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.DOUBLE, relaxed);
+                CoreMathVerifier.computeConvert(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkConvertHalf2Double2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertHalf3Double3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x880afd4l, -3.1129599999999998545e+04, 3.1129599999999998545e+04);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 3), INPUTSIZE);
+            script.forEach_testConvertDouble3Half3Double3(inV, out);
+            verifyResultsConvertHalf3Double3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble3Half3Double3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertDouble3Half3Double3(inV, out);
+            verifyResultsConvertHalf3Double3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble3Half3Double3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertHalf3Double3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        double[] arrayOut = new double[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (double) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfDouble args = new ArgumentsHalfDouble();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.DOUBLE, relaxed);
+                CoreMathVerifier.computeConvert(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkConvertHalf3Double3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertHalf4Double4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x5edc4100l, -3.1129599999999998545e+04, 3.1129599999999998545e+04);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 4), INPUTSIZE);
+            script.forEach_testConvertDouble4Half4Double4(inV, out);
+            verifyResultsConvertHalf4Double4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble4Half4Double4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertDouble4Half4Double4(inV, out);
+            verifyResultsConvertHalf4Double4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble4Half4Double4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertHalf4Double4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        double[] arrayOut = new double[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (double) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfDouble args = new ArgumentsHalfDouble();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.DOUBLE, relaxed);
+                CoreMathVerifier.computeConvert(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkConvertHalf4Double4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsHalfChar {
+        public short inV;
+        public double inVDouble;
+        public byte out;
+    }
+
+    private void checkConvertHalf2Char2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xf6709821l, -1.2800000000000000000e+02, 1.2700000000000000000e+02);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
+            script.forEach_testConvertChar2Half2Char2(inV, out);
+            verifyResultsConvertHalf2Char2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar2Half2Char2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertChar2Half2Char2(inV, out);
+            verifyResultsConvertHalf2Char2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar2Half2Char2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertHalf2Char2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        byte[] arrayOut = new byte[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (byte) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfChar args = new ArgumentsHalfChar();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeConvert(args);
+                // Validate the outputs.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        if (args.out != arrayOut[i * 2 + j]) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkConvertHalf2Char2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertHalf3Char3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x55785d15l, -1.2800000000000000000e+02, 1.2700000000000000000e+02);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
+            script.forEach_testConvertChar3Half3Char3(inV, out);
+            verifyResultsConvertHalf3Char3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar3Half3Char3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertChar3Half3Char3(inV, out);
+            verifyResultsConvertHalf3Char3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar3Half3Char3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertHalf3Char3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        byte[] arrayOut = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (byte) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfChar args = new ArgumentsHalfChar();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeConvert(args);
+                // Validate the outputs.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        if (args.out != arrayOut[i * 4 + j]) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkConvertHalf3Char3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertHalf4Char4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xb4802209l, -1.2800000000000000000e+02, 1.2700000000000000000e+02);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
+            script.forEach_testConvertChar4Half4Char4(inV, out);
+            verifyResultsConvertHalf4Char4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar4Half4Char4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertChar4Half4Char4(inV, out);
+            verifyResultsConvertHalf4Char4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar4Half4Char4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertHalf4Char4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        byte[] arrayOut = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (byte) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfChar args = new ArgumentsHalfChar();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeConvert(args);
+                // Validate the outputs.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        if (args.out != arrayOut[i * 4 + j]) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkConvertHalf4Char4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsHalfUchar {
+        public short inV;
+        public double inVDouble;
+        public byte out;
+    }
+
+    private void checkConvertHalf2Uchar2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x6869a68el, 0.0000000000000000000e+00, 2.5500000000000000000e+02);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
+            script.forEach_testConvertUchar2Half2Uchar2(inV, out);
+            verifyResultsConvertHalf2Uchar2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar2Half2Uchar2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUchar2Half2Uchar2(inV, out);
+            verifyResultsConvertHalf2Uchar2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar2Half2Uchar2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertHalf2Uchar2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        byte[] arrayOut = new byte[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (byte) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfUchar args = new ArgumentsHalfUchar();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeConvert(args);
+                // Validate the outputs.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        if (args.out != arrayOut[i * 2 + j]) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkConvertHalf2Uchar2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertHalf3Uchar3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x5e84c76cl, 0.0000000000000000000e+00, 2.5500000000000000000e+02);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
+            script.forEach_testConvertUchar3Half3Uchar3(inV, out);
+            verifyResultsConvertHalf3Uchar3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar3Half3Uchar3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUchar3Half3Uchar3(inV, out);
+            verifyResultsConvertHalf3Uchar3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar3Half3Uchar3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertHalf3Uchar3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        byte[] arrayOut = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (byte) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfUchar args = new ArgumentsHalfUchar();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeConvert(args);
+                // Validate the outputs.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        if (args.out != arrayOut[i * 4 + j]) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkConvertHalf3Uchar3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertHalf4Uchar4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x549fe84al, 0.0000000000000000000e+00, 2.5500000000000000000e+02);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
+            script.forEach_testConvertUchar4Half4Uchar4(inV, out);
+            verifyResultsConvertHalf4Uchar4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar4Half4Uchar4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUchar4Half4Uchar4(inV, out);
+            verifyResultsConvertHalf4Uchar4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar4Half4Uchar4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertHalf4Uchar4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        byte[] arrayOut = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (byte) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfUchar args = new ArgumentsHalfUchar();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeConvert(args);
+                // Validate the outputs.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        if (args.out != arrayOut[i * 4 + j]) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkConvertHalf4Uchar4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsHalfShort {
+        public short inV;
+        public double inVDouble;
+        public short out;
+    }
+
+    private void checkConvertHalf2Short2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xfd7771a7l, -3.2753000000000000000e+04, 3.2752000000000000000e+04);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
+            script.forEach_testConvertShort2Half2Short2(inV, out);
+            verifyResultsConvertHalf2Short2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort2Half2Short2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertShort2Half2Short2(inV, out);
+            verifyResultsConvertHalf2Short2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort2Half2Short2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertHalf2Short2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfShort args = new ArgumentsHalfShort();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeConvert(args);
+                // Validate the outputs.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        if (args.out != arrayOut[i * 2 + j]) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkConvertHalf2Short2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertHalf3Short3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 3, 0xf3929285l, -3.2753000000000000000e+04, 3.2752000000000000000e+04);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
+            script.forEach_testConvertShort3Half3Short3(inV, out);
+            verifyResultsConvertHalf3Short3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort3Half3Short3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertShort3Half3Short3(inV, out);
+            verifyResultsConvertHalf3Short3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort3Half3Short3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertHalf3Short3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfShort args = new ArgumentsHalfShort();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeConvert(args);
+                // Validate the outputs.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        if (args.out != arrayOut[i * 4 + j]) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkConvertHalf3Short3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertHalf4Short4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xe9adb363l, -3.2753000000000000000e+04, 3.2752000000000000000e+04);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
+            script.forEach_testConvertShort4Half4Short4(inV, out);
+            verifyResultsConvertHalf4Short4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort4Half4Short4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertShort4Half4Short4(inV, out);
+            verifyResultsConvertHalf4Short4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort4Half4Short4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertHalf4Short4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfShort args = new ArgumentsHalfShort();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeConvert(args);
+                // Validate the outputs.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        if (args.out != arrayOut[i * 4 + j]) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkConvertHalf4Short4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsHalfUshort {
+        public short inV;
+        public double inVDouble;
+        public short out;
+    }
+
+    private void checkConvertHalf2Ushort2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x224cddf6l, 0.0000000000000000000e+00, 6.5504000000000000000e+04);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
+            script.forEach_testConvertUshort2Half2Ushort2(inV, out);
+            verifyResultsConvertHalf2Ushort2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort2Half2Ushort2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUshort2Half2Ushort2(inV, out);
+            verifyResultsConvertHalf2Ushort2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort2Half2Ushort2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertHalf2Ushort2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfUshort args = new ArgumentsHalfUshort();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeConvert(args);
+                // Validate the outputs.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        if (args.out != arrayOut[i * 2 + j]) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkConvertHalf2Ushort2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertHalf3Ushort3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x78a86f22l, 0.0000000000000000000e+00, 6.5504000000000000000e+04);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
+            script.forEach_testConvertUshort3Half3Ushort3(inV, out);
+            verifyResultsConvertHalf3Ushort3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort3Half3Ushort3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUshort3Half3Ushort3(inV, out);
+            verifyResultsConvertHalf3Ushort3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort3Half3Ushort3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertHalf3Ushort3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfUshort args = new ArgumentsHalfUshort();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeConvert(args);
+                // Validate the outputs.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        if (args.out != arrayOut[i * 4 + j]) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkConvertHalf3Ushort3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertHalf4Ushort4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xcf04004el, 0.0000000000000000000e+00, 6.5504000000000000000e+04);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
+            script.forEach_testConvertUshort4Half4Ushort4(inV, out);
+            verifyResultsConvertHalf4Ushort4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort4Half4Ushort4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUshort4Half4Ushort4(inV, out);
+            verifyResultsConvertHalf4Ushort4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort4Half4Ushort4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertHalf4Ushort4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfUshort args = new ArgumentsHalfUshort();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeConvert(args);
+                // Validate the outputs.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        if (args.out != arrayOut[i * 4 + j]) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkConvertHalf4Ushort4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsHalfInt {
+        public short inV;
+        public double inVDouble;
+        public int out;
+    }
+
+    private void checkConvertHalf2Int2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xdcfe841al, -2.1464350730000000000e+09, 2.1464350720000000000e+09);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            script.forEach_testConvertInt2Half2Int2(inV, out);
+            verifyResultsConvertHalf2Int2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt2Half2Int2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertInt2Half2Int2(inV, out);
+            verifyResultsConvertHalf2Int2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt2Half2Int2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertHalf2Int2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        int[] arrayOut = new int[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (int) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfInt args = new ArgumentsHalfInt();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeConvert(args);
+                // Validate the outputs.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        if (args.out != arrayOut[i * 2 + j]) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkConvertHalf2Int2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertHalf3Int3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x26a69450l, -2.1464350730000000000e+09, 2.1464350720000000000e+09);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            script.forEach_testConvertInt3Half3Int3(inV, out);
+            verifyResultsConvertHalf3Int3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt3Half3Int3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertInt3Half3Int3(inV, out);
+            verifyResultsConvertHalf3Int3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt3Half3Int3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertHalf3Int3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        int[] arrayOut = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (int) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfInt args = new ArgumentsHalfInt();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeConvert(args);
+                // Validate the outputs.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        if (args.out != arrayOut[i * 4 + j]) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkConvertHalf3Int3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertHalf4Int4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x704ea486l, -2.1464350730000000000e+09, 2.1464350720000000000e+09);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            script.forEach_testConvertInt4Half4Int4(inV, out);
+            verifyResultsConvertHalf4Int4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt4Half4Int4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertInt4Half4Int4(inV, out);
+            verifyResultsConvertHalf4Int4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt4Half4Int4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertHalf4Int4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        int[] arrayOut = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (int) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfInt args = new ArgumentsHalfInt();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeConvert(args);
+                // Validate the outputs.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        if (args.out != arrayOut[i * 4 + j]) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkConvertHalf4Int4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsHalfUint {
+        public short inV;
+        public double inVDouble;
+        public int out;
+    }
+
+    private void checkConvertHalf2Uint2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xf45cbe1l, 0.0000000000000000000e+00, 4.2928701440000000000e+09);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
+            script.forEach_testConvertUint2Half2Uint2(inV, out);
+            verifyResultsConvertHalf2Uint2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint2Half2Uint2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUint2Half2Uint2(inV, out);
+            verifyResultsConvertHalf2Uint2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint2Half2Uint2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertHalf2Uint2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        int[] arrayOut = new int[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (int) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfUint args = new ArgumentsHalfUint();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeConvert(args);
+                // Validate the outputs.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        if (args.out != arrayOut[i * 2 + j]) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkConvertHalf2Uint2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertHalf3Uint3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x6e4d90d5l, 0.0000000000000000000e+00, 4.2928701440000000000e+09);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
+            script.forEach_testConvertUint3Half3Uint3(inV, out);
+            verifyResultsConvertHalf3Uint3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint3Half3Uint3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUint3Half3Uint3(inV, out);
+            verifyResultsConvertHalf3Uint3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint3Half3Uint3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertHalf3Uint3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        int[] arrayOut = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (int) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfUint args = new ArgumentsHalfUint();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeConvert(args);
+                // Validate the outputs.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        if (args.out != arrayOut[i * 4 + j]) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkConvertHalf3Uint3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertHalf4Uint4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xcd5555c9l, 0.0000000000000000000e+00, 4.2928701440000000000e+09);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
+            script.forEach_testConvertUint4Half4Uint4(inV, out);
+            verifyResultsConvertHalf4Uint4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint4Half4Uint4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUint4Half4Uint4(inV, out);
+            verifyResultsConvertHalf4Uint4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint4Half4Uint4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertHalf4Uint4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        int[] arrayOut = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (int) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfUint args = new ArgumentsHalfUint();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeConvert(args);
+                // Validate the outputs.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        if (args.out != arrayOut[i * 4 + j]) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkConvertHalf4Uint4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsHalfLong {
+        public short inV;
+        public double inVDouble;
+        public long out;
+    }
+
+    private void checkConvertHalf2Long2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x4a740c9fl, -9.2188684372274053120e+18, 9.2188684372274053120e+18);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 2), INPUTSIZE);
+            script.forEach_testConvertLong2Half2Long2(inV, out);
+            verifyResultsConvertHalf2Long2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong2Half2Long2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertLong2Half2Long2(inV, out);
+            verifyResultsConvertHalf2Long2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong2Half2Long2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertHalf2Long2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        long[] arrayOut = new long[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (long) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfLong args = new ArgumentsHalfLong();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeConvert(args);
+                // Validate the outputs.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        if (args.out != arrayOut[i * 2 + j]) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkConvertHalf2Long2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertHalf3Long3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 3, 0xa97bd193l, -9.2188684372274053120e+18, 9.2188684372274053120e+18);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 3), INPUTSIZE);
+            script.forEach_testConvertLong3Half3Long3(inV, out);
+            verifyResultsConvertHalf3Long3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong3Half3Long3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertLong3Half3Long3(inV, out);
+            verifyResultsConvertHalf3Long3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong3Half3Long3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertHalf3Long3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        long[] arrayOut = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (long) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfLong args = new ArgumentsHalfLong();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeConvert(args);
+                // Validate the outputs.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        if (args.out != arrayOut[i * 4 + j]) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkConvertHalf3Long3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertHalf4Long4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x8839687l, -9.2188684372274053120e+18, 9.2188684372274053120e+18);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 4), INPUTSIZE);
+            script.forEach_testConvertLong4Half4Long4(inV, out);
+            verifyResultsConvertHalf4Long4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong4Half4Long4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertLong4Half4Long4(inV, out);
+            verifyResultsConvertHalf4Long4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong4Half4Long4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertHalf4Long4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        long[] arrayOut = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (long) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfLong args = new ArgumentsHalfLong();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeConvert(args);
+                // Validate the outputs.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        if (args.out != arrayOut[i * 4 + j]) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkConvertHalf4Long4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsHalfUlong {
+        public short inV;
+        public double inVDouble;
+        public long out;
+    }
+
+    private void checkConvertHalf2Ulong2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xbc6d1b0cl, 0.0000000000000000000e+00, 1.8437736874454810624e+19);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 2), INPUTSIZE);
+            script.forEach_testConvertUlong2Half2Ulong2(inV, out);
+            verifyResultsConvertHalf2Ulong2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong2Half2Ulong2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUlong2Half2Ulong2(inV, out);
+            verifyResultsConvertHalf2Ulong2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong2Half2Ulong2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertHalf2Ulong2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        long[] arrayOut = new long[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (long) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfUlong args = new ArgumentsHalfUlong();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeConvert(args);
+                // Validate the outputs.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        if (args.out != arrayOut[i * 2 + j]) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkConvertHalf2Ulong2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertHalf3Ulong3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 3, 0xb2883beal, 0.0000000000000000000e+00, 1.8437736874454810624e+19);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 3), INPUTSIZE);
+            script.forEach_testConvertUlong3Half3Ulong3(inV, out);
+            verifyResultsConvertHalf3Ulong3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong3Half3Ulong3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUlong3Half3Ulong3(inV, out);
+            verifyResultsConvertHalf3Ulong3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong3Half3Ulong3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertHalf3Ulong3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        long[] arrayOut = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (long) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfUlong args = new ArgumentsHalfUlong();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeConvert(args);
+                // Validate the outputs.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        if (args.out != arrayOut[i * 4 + j]) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkConvertHalf3Ulong3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertHalf4Ulong4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xa8a35cc8l, 0.0000000000000000000e+00, 1.8437736874454810624e+19);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 4), INPUTSIZE);
+            script.forEach_testConvertUlong4Half4Ulong4(inV, out);
+            verifyResultsConvertHalf4Ulong4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong4Half4Ulong4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUlong4Half4Ulong4(inV, out);
+            verifyResultsConvertHalf4Ulong4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong4Half4Ulong4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertHalf4Ulong4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        long[] arrayOut = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (long) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfUlong args = new ArgumentsHalfUlong();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeConvert(args);
+                // Validate the outputs.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        if (args.out != arrayOut[i * 4 + j]) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkConvertHalf4Ulong4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsFloatHalf {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkConvertFloat2Half2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xaa314c6fl, -3.1129599999999998545e+04, 3.1129599999999998545e+04);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testConvertHalf2Float2Half2(inV, out);
+            verifyResultsConvertFloat2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf2Float2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertHalf2Float2Half2(inV, out);
+            verifyResultsConvertFloat2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf2Float2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertFloat2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatHalf args = new ArgumentsFloatHalf();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeConvert(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkConvertFloat2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertFloat3Half3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x9391163l, -3.1129599999999998545e+04, 3.1129599999999998545e+04);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testConvertHalf3Float3Half3(inV, out);
+            verifyResultsConvertFloat3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf3Float3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertHalf3Float3Half3(inV, out);
+            verifyResultsConvertFloat3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf3Float3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertFloat3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatHalf args = new ArgumentsFloatHalf();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeConvert(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkConvertFloat3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertFloat4Half4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x6840d657l, -3.1129599999999998545e+04, 3.1129599999999998545e+04);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testConvertHalf4Float4Half4(inV, out);
+            verifyResultsConvertFloat4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf4Float4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertHalf4Float4Half4(inV, out);
+            verifyResultsConvertFloat4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf4Float4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertFloat4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatHalf args = new ArgumentsFloatHalf();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeConvert(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkConvertFloat4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsDoubleHalf {
+        public double inV;
+        public Target.Floaty out;
+    }
+
+    private void checkConvertDouble2Half2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 2, 0x6fc20024l, -3.1129599999999998545e+04, 3.1129599999999998545e+04);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testConvertHalf2Double2Half2(inV, out);
+            verifyResultsConvertDouble2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf2Double2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertHalf2Double2Half2(inV, out);
+            verifyResultsConvertDouble2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf2Double2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertDouble2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        double[] arrayInV = new double[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (double) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsDoubleHalf args = new ArgumentsDoubleHalf();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeConvert(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkConvertDouble2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertDouble3Half3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 3, 0xcec9c518l, -3.1129599999999998545e+04, 3.1129599999999998545e+04);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testConvertHalf3Double3Half3(inV, out);
+            verifyResultsConvertDouble3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf3Double3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertHalf3Double3Half3(inV, out);
+            verifyResultsConvertDouble3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf3Double3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertDouble3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        double[] arrayInV = new double[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (double) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsDoubleHalf args = new ArgumentsDoubleHalf();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeConvert(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkConvertDouble3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertDouble4Half4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 4, 0x2dd18a0cl, -3.1129599999999998545e+04, 3.1129599999999998545e+04);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testConvertHalf4Double4Half4(inV, out);
+            verifyResultsConvertDouble4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf4Double4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertHalf4Double4Half4(inV, out);
+            verifyResultsConvertDouble4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf4Double4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertDouble4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        double[] arrayInV = new double[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (double) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsDoubleHalf args = new ArgumentsDoubleHalf();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeConvert(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkConvertDouble4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsCharHalf {
+        public byte inV;
+        public Target.Floaty out;
+    }
+
+    private void checkConvertChar2Half2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 2, 0x55c123afl, true, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testConvertHalf2Char2Half2(inV, out);
+            verifyResultsConvertChar2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf2Char2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertHalf2Char2Half2(inV, out);
+            verifyResultsConvertChar2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf2Char2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertChar2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (byte) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsCharHalf args = new ArgumentsCharHalf();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeConvert(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkConvertChar2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertChar3Half3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 3, 0xb4c8e8a3l, true, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testConvertHalf3Char3Half3(inV, out);
+            verifyResultsConvertChar3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf3Char3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertHalf3Char3Half3(inV, out);
+            verifyResultsConvertChar3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf3Char3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertChar3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (byte) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsCharHalf args = new ArgumentsCharHalf();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeConvert(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkConvertChar3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertChar4Half4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 4, 0x13d0ad97l, true, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testConvertHalf4Char4Half4(inV, out);
+            verifyResultsConvertChar4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf4Char4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertHalf4Char4Half4(inV, out);
+            verifyResultsConvertChar4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf4Char4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertChar4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (byte) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsCharHalf args = new ArgumentsCharHalf();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeConvert(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkConvertChar4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsUcharHalf {
+        public byte inV;
+        public Target.Floaty out;
+    }
+
+    private void checkConvertUchar2Half2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 2, 0xe8433030l, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testConvertHalf2Uchar2Half2(inV, out);
+            verifyResultsConvertUchar2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf2Uchar2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertHalf2Uchar2Half2(inV, out);
+            verifyResultsConvertUchar2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf2Uchar2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUchar2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (byte) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsUcharHalf args = new ArgumentsUcharHalf();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeConvert(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkConvertUchar2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUchar3Half3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 3, 0x474af524l, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testConvertHalf3Uchar3Half3(inV, out);
+            verifyResultsConvertUchar3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf3Uchar3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertHalf3Uchar3Half3(inV, out);
+            verifyResultsConvertUchar3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf3Uchar3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUchar3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (byte) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsUcharHalf args = new ArgumentsUcharHalf();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeConvert(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkConvertUchar3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUchar4Half4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 4, 0xa652ba18l, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testConvertHalf4Uchar4Half4(inV, out);
+            verifyResultsConvertUchar4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf4Uchar4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertHalf4Uchar4Half4(inV, out);
+            verifyResultsConvertUchar4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf4Uchar4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUchar4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (byte) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsUcharHalf args = new ArgumentsUcharHalf();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeConvert(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkConvertUchar4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsShortHalf {
+        public short inV;
+        public Target.Floaty out;
+    }
+
+    private void checkConvertShort2Half2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 2, 0x967ebe73l, true, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testConvertHalf2Short2Half2(inV, out);
+            verifyResultsConvertShort2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf2Short2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertHalf2Short2Half2(inV, out);
+            verifyResultsConvertShort2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf2Short2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertShort2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsShortHalf args = new ArgumentsShortHalf();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeConvert(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkConvertShort2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertShort3Half3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 3, 0xf5868367l, true, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testConvertHalf3Short3Half3(inV, out);
+            verifyResultsConvertShort3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf3Short3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertHalf3Short3Half3(inV, out);
+            verifyResultsConvertShort3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf3Short3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertShort3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsShortHalf args = new ArgumentsShortHalf();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeConvert(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkConvertShort3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertShort4Half4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 4, 0x548e485bl, true, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testConvertHalf4Short4Half4(inV, out);
+            verifyResultsConvertShort4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf4Short4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertHalf4Short4Half4(inV, out);
+            verifyResultsConvertShort4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf4Short4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertShort4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsShortHalf args = new ArgumentsShortHalf();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeConvert(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkConvertShort4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsUshortHalf {
+        public short inV;
+        public Target.Floaty out;
+    }
+
+    private void checkConvertUshort2Half2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 2, 0x3256d81el, false, 16);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testConvertHalf2Ushort2Half2(inV, out);
+            verifyResultsConvertUshort2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf2Ushort2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertHalf2Ushort2Half2(inV, out);
+            verifyResultsConvertUshort2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf2Ushort2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUshort2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsUshortHalf args = new ArgumentsUshortHalf();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeConvert(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkConvertUshort2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUshort3Half3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 3, 0x915e9d12l, false, 16);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testConvertHalf3Ushort3Half3(inV, out);
+            verifyResultsConvertUshort3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf3Ushort3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertHalf3Ushort3Half3(inV, out);
+            verifyResultsConvertUshort3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf3Ushort3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUshort3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsUshortHalf args = new ArgumentsUshortHalf();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeConvert(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkConvertUshort3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUshort4Half4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 4, 0xf0666206l, false, 16);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testConvertHalf4Ushort4Half4(inV, out);
+            verifyResultsConvertUshort4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf4Ushort4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertHalf4Ushort4Half4(inV, out);
+            verifyResultsConvertUshort4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf4Ushort4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUshort4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsUshortHalf args = new ArgumentsUshortHalf();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeConvert(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkConvertUshort4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsIntHalf {
+        public int inV;
+        public Target.Floaty out;
+    }
+
+    private void checkConvertInt2Half2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 2, 0xb6fb0cecl, true, 31);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testConvertHalf2Int2Half2(inV, out);
+            verifyResultsConvertInt2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf2Int2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertHalf2Int2Half2(inV, out);
+            verifyResultsConvertInt2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf2Int2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertInt2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (int) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsIntHalf args = new ArgumentsIntHalf();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeConvert(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkConvertInt2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertInt3Half3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 3, 0x1602d1e0l, true, 31);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testConvertHalf3Int3Half3(inV, out);
+            verifyResultsConvertInt3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf3Int3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertHalf3Int3Half3(inV, out);
+            verifyResultsConvertInt3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf3Int3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertInt3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (int) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsIntHalf args = new ArgumentsIntHalf();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeConvert(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkConvertInt3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertInt4Half4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 4, 0x750a96d4l, true, 31);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testConvertHalf4Int4Half4(inV, out);
+            verifyResultsConvertInt4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf4Int4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertHalf4Int4Half4(inV, out);
+            verifyResultsConvertInt4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf4Int4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertInt4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (int) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsIntHalf args = new ArgumentsIntHalf();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeConvert(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkConvertInt4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsUintHalf {
+        public int inV;
+        public Target.Floaty out;
+    }
+
+    private void checkConvertUint2Half2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 2, 0xb46f30efl, false, 32);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testConvertHalf2Uint2Half2(inV, out);
+            verifyResultsConvertUint2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf2Uint2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertHalf2Uint2Half2(inV, out);
+            verifyResultsConvertUint2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf2Uint2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUint2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (int) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsUintHalf args = new ArgumentsUintHalf();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeConvert(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkConvertUint2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUint3Half3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 3, 0x1376f5e3l, false, 32);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testConvertHalf3Uint3Half3(inV, out);
+            verifyResultsConvertUint3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf3Uint3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertHalf3Uint3Half3(inV, out);
+            verifyResultsConvertUint3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf3Uint3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUint3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (int) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsUintHalf args = new ArgumentsUintHalf();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeConvert(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkConvertUint3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUint4Half4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 4, 0x727ebad7l, false, 32);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testConvertHalf4Uint4Half4(inV, out);
+            verifyResultsConvertUint4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf4Uint4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertHalf4Uint4Half4(inV, out);
+            verifyResultsConvertUint4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf4Uint4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUint4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (int) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsUintHalf args = new ArgumentsUintHalf();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeConvert(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkConvertUint4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsLongHalf {
+        public long inV;
+        public Target.Floaty out;
+    }
+
+    private void checkConvertLong2Half2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_64, 2, 0xf4d265b9l, true, 63);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testConvertHalf2Long2Half2(inV, out);
+            verifyResultsConvertLong2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf2Long2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertHalf2Long2Half2(inV, out);
+            verifyResultsConvertLong2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf2Long2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertLong2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        long[] arrayInV = new long[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (long) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsLongHalf args = new ArgumentsLongHalf();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeConvert(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkConvertLong2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertLong3Half3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_64, 3, 0x53da2aadl, true, 63);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testConvertHalf3Long3Half3(inV, out);
+            verifyResultsConvertLong3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf3Long3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertHalf3Long3Half3(inV, out);
+            verifyResultsConvertLong3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf3Long3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertLong3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        long[] arrayInV = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (long) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsLongHalf args = new ArgumentsLongHalf();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeConvert(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkConvertLong3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertLong4Half4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_64, 4, 0xb2e1efa1l, true, 63);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testConvertHalf4Long4Half4(inV, out);
+            verifyResultsConvertLong4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf4Long4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertHalf4Long4Half4(inV, out);
+            verifyResultsConvertLong4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf4Long4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertLong4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        long[] arrayInV = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (long) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsLongHalf args = new ArgumentsLongHalf();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeConvert(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkConvertLong4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsUlongHalf {
+        public long inV;
+        public Target.Floaty out;
+    }
+
+    private void checkConvertUlong2Half2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_64, 2, 0x8754723al, false, 64);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testConvertHalf2Ulong2Half2(inV, out);
+            verifyResultsConvertUlong2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf2Ulong2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertHalf2Ulong2Half2(inV, out);
+            verifyResultsConvertUlong2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf2Ulong2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUlong2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        long[] arrayInV = new long[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (long) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsUlongHalf args = new ArgumentsUlongHalf();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeConvert(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkConvertUlong2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUlong3Half3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_64, 3, 0xe65c372el, false, 64);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testConvertHalf3Ulong3Half3(inV, out);
+            verifyResultsConvertUlong3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf3Ulong3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertHalf3Ulong3Half3(inV, out);
+            verifyResultsConvertUlong3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf3Ulong3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUlong3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        long[] arrayInV = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (long) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsUlongHalf args = new ArgumentsUlongHalf();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeConvert(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkConvertUlong3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUlong4Half4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_64, 4, 0x4563fc22l, false, 64);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testConvertHalf4Ulong4Half4(inV, out);
+            verifyResultsConvertUlong4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf4Ulong4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertHalf4Ulong4Half4(inV, out);
+            verifyResultsConvertUlong4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertHalf4Ulong4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUlong4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        long[] arrayInV = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (long) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsUlongHalf args = new ArgumentsUlongHalf();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeConvert(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkConvertUlong4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testConvert() {
         checkConvertFloat2Float2();
         checkConvertFloat3Float3();
@@ -21297,5 +25869,68 @@
         checkConvertUint2Ulong2();
         checkConvertUint3Ulong3();
         checkConvertUint4Ulong4();
+        checkConvertHalf2Half2();
+        checkConvertHalf3Half3();
+        checkConvertHalf4Half4();
+        checkConvertHalf2Float2();
+        checkConvertHalf3Float3();
+        checkConvertHalf4Float4();
+        checkConvertHalf2Double2();
+        checkConvertHalf3Double3();
+        checkConvertHalf4Double4();
+        checkConvertHalf2Char2();
+        checkConvertHalf3Char3();
+        checkConvertHalf4Char4();
+        checkConvertHalf2Uchar2();
+        checkConvertHalf3Uchar3();
+        checkConvertHalf4Uchar4();
+        checkConvertHalf2Short2();
+        checkConvertHalf3Short3();
+        checkConvertHalf4Short4();
+        checkConvertHalf2Ushort2();
+        checkConvertHalf3Ushort3();
+        checkConvertHalf4Ushort4();
+        checkConvertHalf2Int2();
+        checkConvertHalf3Int3();
+        checkConvertHalf4Int4();
+        checkConvertHalf2Uint2();
+        checkConvertHalf3Uint3();
+        checkConvertHalf4Uint4();
+        checkConvertHalf2Long2();
+        checkConvertHalf3Long3();
+        checkConvertHalf4Long4();
+        checkConvertHalf2Ulong2();
+        checkConvertHalf3Ulong3();
+        checkConvertHalf4Ulong4();
+        checkConvertFloat2Half2();
+        checkConvertFloat3Half3();
+        checkConvertFloat4Half4();
+        checkConvertDouble2Half2();
+        checkConvertDouble3Half3();
+        checkConvertDouble4Half4();
+        checkConvertChar2Half2();
+        checkConvertChar3Half3();
+        checkConvertChar4Half4();
+        checkConvertUchar2Half2();
+        checkConvertUchar3Half3();
+        checkConvertUchar4Half4();
+        checkConvertShort2Half2();
+        checkConvertShort3Half3();
+        checkConvertShort4Half4();
+        checkConvertUshort2Half2();
+        checkConvertUshort3Half3();
+        checkConvertUshort4Half4();
+        checkConvertInt2Half2();
+        checkConvertInt3Half3();
+        checkConvertInt4Half4();
+        checkConvertUint2Half2();
+        checkConvertUint3Half3();
+        checkConvertUint4Half4();
+        checkConvertLong2Half2();
+        checkConvertLong3Half3();
+        checkConvertLong4Half4();
+        checkConvertUlong2Half2();
+        checkConvertUlong3Half3();
+        checkConvertUlong4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestConvert.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestConvert.rs
index d307e92..96fdd99 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestConvert.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestConvert.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -1219,3 +1219,255 @@
 ulong4 __attribute__((kernel)) testConvertUlong4Uint4Ulong4(uint4 inV) {
     return convert_ulong4(inV);
 }
+
+half2 __attribute__((kernel)) testConvertHalf2Half2Half2(half2 inV) {
+    return convert_half2(inV);
+}
+
+half3 __attribute__((kernel)) testConvertHalf3Half3Half3(half3 inV) {
+    return convert_half3(inV);
+}
+
+half4 __attribute__((kernel)) testConvertHalf4Half4Half4(half4 inV) {
+    return convert_half4(inV);
+}
+
+float2 __attribute__((kernel)) testConvertFloat2Half2Float2(half2 inV) {
+    return convert_float2(inV);
+}
+
+float3 __attribute__((kernel)) testConvertFloat3Half3Float3(half3 inV) {
+    return convert_float3(inV);
+}
+
+float4 __attribute__((kernel)) testConvertFloat4Half4Float4(half4 inV) {
+    return convert_float4(inV);
+}
+
+double2 __attribute__((kernel)) testConvertDouble2Half2Double2(half2 inV) {
+    return convert_double2(inV);
+}
+
+double3 __attribute__((kernel)) testConvertDouble3Half3Double3(half3 inV) {
+    return convert_double3(inV);
+}
+
+double4 __attribute__((kernel)) testConvertDouble4Half4Double4(half4 inV) {
+    return convert_double4(inV);
+}
+
+char2 __attribute__((kernel)) testConvertChar2Half2Char2(half2 inV) {
+    return convert_char2(inV);
+}
+
+char3 __attribute__((kernel)) testConvertChar3Half3Char3(half3 inV) {
+    return convert_char3(inV);
+}
+
+char4 __attribute__((kernel)) testConvertChar4Half4Char4(half4 inV) {
+    return convert_char4(inV);
+}
+
+uchar2 __attribute__((kernel)) testConvertUchar2Half2Uchar2(half2 inV) {
+    return convert_uchar2(inV);
+}
+
+uchar3 __attribute__((kernel)) testConvertUchar3Half3Uchar3(half3 inV) {
+    return convert_uchar3(inV);
+}
+
+uchar4 __attribute__((kernel)) testConvertUchar4Half4Uchar4(half4 inV) {
+    return convert_uchar4(inV);
+}
+
+short2 __attribute__((kernel)) testConvertShort2Half2Short2(half2 inV) {
+    return convert_short2(inV);
+}
+
+short3 __attribute__((kernel)) testConvertShort3Half3Short3(half3 inV) {
+    return convert_short3(inV);
+}
+
+short4 __attribute__((kernel)) testConvertShort4Half4Short4(half4 inV) {
+    return convert_short4(inV);
+}
+
+ushort2 __attribute__((kernel)) testConvertUshort2Half2Ushort2(half2 inV) {
+    return convert_ushort2(inV);
+}
+
+ushort3 __attribute__((kernel)) testConvertUshort3Half3Ushort3(half3 inV) {
+    return convert_ushort3(inV);
+}
+
+ushort4 __attribute__((kernel)) testConvertUshort4Half4Ushort4(half4 inV) {
+    return convert_ushort4(inV);
+}
+
+int2 __attribute__((kernel)) testConvertInt2Half2Int2(half2 inV) {
+    return convert_int2(inV);
+}
+
+int3 __attribute__((kernel)) testConvertInt3Half3Int3(half3 inV) {
+    return convert_int3(inV);
+}
+
+int4 __attribute__((kernel)) testConvertInt4Half4Int4(half4 inV) {
+    return convert_int4(inV);
+}
+
+uint2 __attribute__((kernel)) testConvertUint2Half2Uint2(half2 inV) {
+    return convert_uint2(inV);
+}
+
+uint3 __attribute__((kernel)) testConvertUint3Half3Uint3(half3 inV) {
+    return convert_uint3(inV);
+}
+
+uint4 __attribute__((kernel)) testConvertUint4Half4Uint4(half4 inV) {
+    return convert_uint4(inV);
+}
+
+long2 __attribute__((kernel)) testConvertLong2Half2Long2(half2 inV) {
+    return convert_long2(inV);
+}
+
+long3 __attribute__((kernel)) testConvertLong3Half3Long3(half3 inV) {
+    return convert_long3(inV);
+}
+
+long4 __attribute__((kernel)) testConvertLong4Half4Long4(half4 inV) {
+    return convert_long4(inV);
+}
+
+ulong2 __attribute__((kernel)) testConvertUlong2Half2Ulong2(half2 inV) {
+    return convert_ulong2(inV);
+}
+
+ulong3 __attribute__((kernel)) testConvertUlong3Half3Ulong3(half3 inV) {
+    return convert_ulong3(inV);
+}
+
+ulong4 __attribute__((kernel)) testConvertUlong4Half4Ulong4(half4 inV) {
+    return convert_ulong4(inV);
+}
+
+half2 __attribute__((kernel)) testConvertHalf2Float2Half2(float2 inV) {
+    return convert_half2(inV);
+}
+
+half3 __attribute__((kernel)) testConvertHalf3Float3Half3(float3 inV) {
+    return convert_half3(inV);
+}
+
+half4 __attribute__((kernel)) testConvertHalf4Float4Half4(float4 inV) {
+    return convert_half4(inV);
+}
+
+half2 __attribute__((kernel)) testConvertHalf2Double2Half2(double2 inV) {
+    return convert_half2(inV);
+}
+
+half3 __attribute__((kernel)) testConvertHalf3Double3Half3(double3 inV) {
+    return convert_half3(inV);
+}
+
+half4 __attribute__((kernel)) testConvertHalf4Double4Half4(double4 inV) {
+    return convert_half4(inV);
+}
+
+half2 __attribute__((kernel)) testConvertHalf2Char2Half2(char2 inV) {
+    return convert_half2(inV);
+}
+
+half3 __attribute__((kernel)) testConvertHalf3Char3Half3(char3 inV) {
+    return convert_half3(inV);
+}
+
+half4 __attribute__((kernel)) testConvertHalf4Char4Half4(char4 inV) {
+    return convert_half4(inV);
+}
+
+half2 __attribute__((kernel)) testConvertHalf2Uchar2Half2(uchar2 inV) {
+    return convert_half2(inV);
+}
+
+half3 __attribute__((kernel)) testConvertHalf3Uchar3Half3(uchar3 inV) {
+    return convert_half3(inV);
+}
+
+half4 __attribute__((kernel)) testConvertHalf4Uchar4Half4(uchar4 inV) {
+    return convert_half4(inV);
+}
+
+half2 __attribute__((kernel)) testConvertHalf2Short2Half2(short2 inV) {
+    return convert_half2(inV);
+}
+
+half3 __attribute__((kernel)) testConvertHalf3Short3Half3(short3 inV) {
+    return convert_half3(inV);
+}
+
+half4 __attribute__((kernel)) testConvertHalf4Short4Half4(short4 inV) {
+    return convert_half4(inV);
+}
+
+half2 __attribute__((kernel)) testConvertHalf2Ushort2Half2(ushort2 inV) {
+    return convert_half2(inV);
+}
+
+half3 __attribute__((kernel)) testConvertHalf3Ushort3Half3(ushort3 inV) {
+    return convert_half3(inV);
+}
+
+half4 __attribute__((kernel)) testConvertHalf4Ushort4Half4(ushort4 inV) {
+    return convert_half4(inV);
+}
+
+half2 __attribute__((kernel)) testConvertHalf2Int2Half2(int2 inV) {
+    return convert_half2(inV);
+}
+
+half3 __attribute__((kernel)) testConvertHalf3Int3Half3(int3 inV) {
+    return convert_half3(inV);
+}
+
+half4 __attribute__((kernel)) testConvertHalf4Int4Half4(int4 inV) {
+    return convert_half4(inV);
+}
+
+half2 __attribute__((kernel)) testConvertHalf2Uint2Half2(uint2 inV) {
+    return convert_half2(inV);
+}
+
+half3 __attribute__((kernel)) testConvertHalf3Uint3Half3(uint3 inV) {
+    return convert_half3(inV);
+}
+
+half4 __attribute__((kernel)) testConvertHalf4Uint4Half4(uint4 inV) {
+    return convert_half4(inV);
+}
+
+half2 __attribute__((kernel)) testConvertHalf2Long2Half2(long2 inV) {
+    return convert_half2(inV);
+}
+
+half3 __attribute__((kernel)) testConvertHalf3Long3Half3(long3 inV) {
+    return convert_half3(inV);
+}
+
+half4 __attribute__((kernel)) testConvertHalf4Long4Half4(long4 inV) {
+    return convert_half4(inV);
+}
+
+half2 __attribute__((kernel)) testConvertHalf2Ulong2Half2(ulong2 inV) {
+    return convert_half2(inV);
+}
+
+half3 __attribute__((kernel)) testConvertHalf3Ulong3Half3(ulong3 inV) {
+    return convert_half3(inV);
+}
+
+half4 __attribute__((kernel)) testConvertHalf4Ulong4Half4(ulong4 inV) {
+    return convert_half4(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestConvertRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestConvertRelaxed.rs
index 57ae29c..7229d5d 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestConvertRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestConvertRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCopysign.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCopysign.java
index 24b71ec..e1194fd 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCopysign.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCopysign.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -82,7 +83,7 @@
                 args.inMagnitudeValue = arrayInMagnitudeValue[i];
                 args.inSignValue = arrayInSignValue[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeCopysign(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -161,7 +162,7 @@
                 args.inMagnitudeValue = arrayInMagnitudeValue[i * 2 + j];
                 args.inSignValue = arrayInSignValue[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeCopysign(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -240,7 +241,7 @@
                 args.inMagnitudeValue = arrayInMagnitudeValue[i * 4 + j];
                 args.inSignValue = arrayInSignValue[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeCopysign(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -319,7 +320,7 @@
                 args.inMagnitudeValue = arrayInMagnitudeValue[i * 4 + j];
                 args.inSignValue = arrayInSignValue[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeCopysign(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -358,10 +359,358 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalfHalf {
+        public short inMagnitudeValue;
+        public double inMagnitudeValueDouble;
+        public short inSignValue;
+        public double inSignValueDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkCopysignHalfHalfHalf() {
+        Allocation inMagnitudeValue = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x9e87c031l, false);
+        Allocation inSignValue = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x523236fcl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.set_gAllocInSignValue(inSignValue);
+            script.forEach_testCopysignHalfHalfHalf(inMagnitudeValue, out);
+            verifyResultsCopysignHalfHalfHalf(inMagnitudeValue, inSignValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCopysignHalfHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInSignValue(inSignValue);
+            scriptRelaxed.forEach_testCopysignHalfHalfHalf(inMagnitudeValue, out);
+            verifyResultsCopysignHalfHalfHalf(inMagnitudeValue, inSignValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCopysignHalfHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCopysignHalfHalfHalf(Allocation inMagnitudeValue, Allocation inSignValue, Allocation out, boolean relaxed) {
+        short[] arrayInMagnitudeValue = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInMagnitudeValue, (short) 42);
+        inMagnitudeValue.copyTo(arrayInMagnitudeValue);
+        short[] arrayInSignValue = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInSignValue, (short) 42);
+        inSignValue.copyTo(arrayInSignValue);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inMagnitudeValue = arrayInMagnitudeValue[i];
+                args.inMagnitudeValueDouble = Float16Utils.convertFloat16ToDouble(args.inMagnitudeValue);
+                args.inSignValue = arrayInSignValue[i];
+                args.inSignValueDouble = Float16Utils.convertFloat16ToDouble(args.inSignValue);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeCopysign(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inMagnitudeValue: ");
+                        appendVariableToMessage(message, args.inMagnitudeValue);
+                        message.append("\n");
+                        message.append("Input inSignValue: ");
+                        appendVariableToMessage(message, args.inSignValue);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkCopysignHalfHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkCopysignHalf2Half2Half2() {
+        Allocation inMagnitudeValue = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x5c704fabl, false);
+        Allocation inSignValue = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xa73ce4cal, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.set_gAllocInSignValue(inSignValue);
+            script.forEach_testCopysignHalf2Half2Half2(inMagnitudeValue, out);
+            verifyResultsCopysignHalf2Half2Half2(inMagnitudeValue, inSignValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCopysignHalf2Half2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInSignValue(inSignValue);
+            scriptRelaxed.forEach_testCopysignHalf2Half2Half2(inMagnitudeValue, out);
+            verifyResultsCopysignHalf2Half2Half2(inMagnitudeValue, inSignValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCopysignHalf2Half2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCopysignHalf2Half2Half2(Allocation inMagnitudeValue, Allocation inSignValue, Allocation out, boolean relaxed) {
+        short[] arrayInMagnitudeValue = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInMagnitudeValue, (short) 42);
+        inMagnitudeValue.copyTo(arrayInMagnitudeValue);
+        short[] arrayInSignValue = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInSignValue, (short) 42);
+        inSignValue.copyTo(arrayInSignValue);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inMagnitudeValue = arrayInMagnitudeValue[i * 2 + j];
+                args.inMagnitudeValueDouble = Float16Utils.convertFloat16ToDouble(args.inMagnitudeValue);
+                args.inSignValue = arrayInSignValue[i * 2 + j];
+                args.inSignValueDouble = Float16Utils.convertFloat16ToDouble(args.inSignValue);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeCopysign(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inMagnitudeValue: ");
+                        appendVariableToMessage(message, args.inMagnitudeValue);
+                        message.append("\n");
+                        message.append("Input inSignValue: ");
+                        appendVariableToMessage(message, args.inSignValue);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkCopysignHalf2Half2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkCopysignHalf3Half3Half3() {
+        Allocation inMagnitudeValue = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x38955c0l, false);
+        Allocation inSignValue = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0xf2af1539l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.set_gAllocInSignValue(inSignValue);
+            script.forEach_testCopysignHalf3Half3Half3(inMagnitudeValue, out);
+            verifyResultsCopysignHalf3Half3Half3(inMagnitudeValue, inSignValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCopysignHalf3Half3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInSignValue(inSignValue);
+            scriptRelaxed.forEach_testCopysignHalf3Half3Half3(inMagnitudeValue, out);
+            verifyResultsCopysignHalf3Half3Half3(inMagnitudeValue, inSignValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCopysignHalf3Half3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCopysignHalf3Half3Half3(Allocation inMagnitudeValue, Allocation inSignValue, Allocation out, boolean relaxed) {
+        short[] arrayInMagnitudeValue = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInMagnitudeValue, (short) 42);
+        inMagnitudeValue.copyTo(arrayInMagnitudeValue);
+        short[] arrayInSignValue = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInSignValue, (short) 42);
+        inSignValue.copyTo(arrayInSignValue);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inMagnitudeValue = arrayInMagnitudeValue[i * 4 + j];
+                args.inMagnitudeValueDouble = Float16Utils.convertFloat16ToDouble(args.inMagnitudeValue);
+                args.inSignValue = arrayInSignValue[i * 4 + j];
+                args.inSignValueDouble = Float16Utils.convertFloat16ToDouble(args.inSignValue);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeCopysign(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inMagnitudeValue: ");
+                        appendVariableToMessage(message, args.inMagnitudeValue);
+                        message.append("\n");
+                        message.append("Input inSignValue: ");
+                        appendVariableToMessage(message, args.inSignValue);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkCopysignHalf3Half3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkCopysignHalf4Half4Half4() {
+        Allocation inMagnitudeValue = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xaaa25bd5l, false);
+        Allocation inSignValue = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x3e2145a8l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.set_gAllocInSignValue(inSignValue);
+            script.forEach_testCopysignHalf4Half4Half4(inMagnitudeValue, out);
+            verifyResultsCopysignHalf4Half4Half4(inMagnitudeValue, inSignValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCopysignHalf4Half4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInSignValue(inSignValue);
+            scriptRelaxed.forEach_testCopysignHalf4Half4Half4(inMagnitudeValue, out);
+            verifyResultsCopysignHalf4Half4Half4(inMagnitudeValue, inSignValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCopysignHalf4Half4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCopysignHalf4Half4Half4(Allocation inMagnitudeValue, Allocation inSignValue, Allocation out, boolean relaxed) {
+        short[] arrayInMagnitudeValue = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInMagnitudeValue, (short) 42);
+        inMagnitudeValue.copyTo(arrayInMagnitudeValue);
+        short[] arrayInSignValue = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInSignValue, (short) 42);
+        inSignValue.copyTo(arrayInSignValue);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inMagnitudeValue = arrayInMagnitudeValue[i * 4 + j];
+                args.inMagnitudeValueDouble = Float16Utils.convertFloat16ToDouble(args.inMagnitudeValue);
+                args.inSignValue = arrayInSignValue[i * 4 + j];
+                args.inSignValueDouble = Float16Utils.convertFloat16ToDouble(args.inSignValue);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeCopysign(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inMagnitudeValue: ");
+                        appendVariableToMessage(message, args.inMagnitudeValue);
+                        message.append("\n");
+                        message.append("Input inSignValue: ");
+                        appendVariableToMessage(message, args.inSignValue);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkCopysignHalf4Half4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testCopysign() {
         checkCopysignFloatFloatFloat();
         checkCopysignFloat2Float2Float2();
         checkCopysignFloat3Float3Float3();
         checkCopysignFloat4Float4Float4();
+        checkCopysignHalfHalfHalf();
+        checkCopysignHalf2Half2Half2();
+        checkCopysignHalf3Half3Half3();
+        checkCopysignHalf4Half4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCopysign.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCopysign.rs
index 3aac45b..f5e57f8 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCopysign.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCopysign.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -40,3 +40,23 @@
     float4 inSignValue = rsGetElementAt_float4(gAllocInSignValue, x);
     return copysign(inMagnitudeValue, inSignValue);
 }
+
+half __attribute__((kernel)) testCopysignHalfHalfHalf(half inMagnitudeValue, unsigned int x) {
+    half inSignValue = rsGetElementAt_half(gAllocInSignValue, x);
+    return copysign(inMagnitudeValue, inSignValue);
+}
+
+half2 __attribute__((kernel)) testCopysignHalf2Half2Half2(half2 inMagnitudeValue, unsigned int x) {
+    half2 inSignValue = rsGetElementAt_half2(gAllocInSignValue, x);
+    return copysign(inMagnitudeValue, inSignValue);
+}
+
+half3 __attribute__((kernel)) testCopysignHalf3Half3Half3(half3 inMagnitudeValue, unsigned int x) {
+    half3 inSignValue = rsGetElementAt_half3(gAllocInSignValue, x);
+    return copysign(inMagnitudeValue, inSignValue);
+}
+
+half4 __attribute__((kernel)) testCopysignHalf4Half4Half4(half4 inMagnitudeValue, unsigned int x) {
+    half4 inSignValue = rsGetElementAt_half4(gAllocInSignValue, x);
+    return copysign(inMagnitudeValue, inSignValue);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCopysignRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCopysignRelaxed.rs
index c881b0b4..872bcab 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCopysignRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCopysignRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCos.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCos.java
index 9c321da..9d9b0e5 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCos.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCos.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeCos(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeCos(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeCos(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeCos(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkCosHalfHalf() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x151d6890l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testCosHalfHalf(inV, out);
+            verifyResultsCosHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCosHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testCosHalfHalf(inV, out);
+            verifyResultsCosHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCosHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCosHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeCos(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkCosHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkCosHalf2Half2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x289f4632l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testCosHalf2Half2(inV, out);
+            verifyResultsCosHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCosHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testCosHalf2Half2(inV, out);
+            verifyResultsCosHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCosHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCosHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeCos(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkCosHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkCosHalf3Half3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x87a70b26l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testCosHalf3Half3(inV, out);
+            verifyResultsCosHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCosHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testCosHalf3Half3(inV, out);
+            verifyResultsCosHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCosHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCosHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeCos(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkCosHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkCosHalf4Half4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xe6aed01al, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testCosHalf4Half4(inV, out);
+            verifyResultsCosHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCosHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testCosHalf4Half4(inV, out);
+            verifyResultsCosHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCosHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCosHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeCos(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkCosHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testCos() {
         checkCosFloatFloat();
         checkCosFloat2Float2();
         checkCosFloat3Float3();
         checkCosFloat4Float4();
+        checkCosHalfHalf();
+        checkCosHalf2Half2();
+        checkCosHalf3Half3();
+        checkCosHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCos.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCos.rs
index c2962ba..f7268cc 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCos.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCos.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testCosFloat4Float4(float4 inV) {
     return cos(inV);
 }
+
+half __attribute__((kernel)) testCosHalfHalf(half inV) {
+    return cos(inV);
+}
+
+half2 __attribute__((kernel)) testCosHalf2Half2(half2 inV) {
+    return cos(inV);
+}
+
+half3 __attribute__((kernel)) testCosHalf3Half3(half3 inV) {
+    return cos(inV);
+}
+
+half4 __attribute__((kernel)) testCosHalf4Half4(half4 inV) {
+    return cos(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCosRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCosRelaxed.rs
index ff383e5..a37ed10 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCosRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCosRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCosh.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCosh.java
index f089c5f..8b0755f 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCosh.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCosh.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeCosh(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeCosh(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeCosh(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeCosh(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkCoshHalfHalf() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x609e2d2al, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testCoshHalfHalf(inV, out);
+            verifyResultsCoshHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCoshHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testCoshHalfHalf(inV, out);
+            verifyResultsCoshHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCoshHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCoshHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeCosh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkCoshHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkCoshHalf2Half2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x7dab427cl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testCoshHalf2Half2(inV, out);
+            verifyResultsCoshHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCoshHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testCoshHalf2Half2(inV, out);
+            verifyResultsCoshHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCoshHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCoshHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeCosh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkCoshHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkCoshHalf3Half3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0xdcb30770l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testCoshHalf3Half3(inV, out);
+            verifyResultsCoshHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCoshHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testCoshHalf3Half3(inV, out);
+            verifyResultsCoshHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCoshHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCoshHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeCosh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkCoshHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkCoshHalf4Half4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x3bbacc64l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testCoshHalf4Half4(inV, out);
+            verifyResultsCoshHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCoshHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testCoshHalf4Half4(inV, out);
+            verifyResultsCoshHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCoshHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCoshHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeCosh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkCoshHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testCosh() {
         checkCoshFloatFloat();
         checkCoshFloat2Float2();
         checkCoshFloat3Float3();
         checkCoshFloat4Float4();
+        checkCoshHalfHalf();
+        checkCoshHalf2Half2();
+        checkCoshHalf3Half3();
+        checkCoshHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCosh.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCosh.rs
index 17c6714..01543f3 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCosh.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCosh.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testCoshFloat4Float4(float4 inV) {
     return cosh(inV);
 }
+
+half __attribute__((kernel)) testCoshHalfHalf(half inV) {
+    return cosh(inV);
+}
+
+half2 __attribute__((kernel)) testCoshHalf2Half2(half2 inV) {
+    return cosh(inV);
+}
+
+half3 __attribute__((kernel)) testCoshHalf3Half3(half3 inV) {
+    return cosh(inV);
+}
+
+half4 __attribute__((kernel)) testCoshHalf4Half4(half4 inV) {
+    return cosh(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCoshRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCoshRelaxed.rs
index 4f1c0ee..358062c 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCoshRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCoshRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCospi.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCospi.java
index 11325c5..4776433 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCospi.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCospi.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeCospi(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeCospi(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeCospi(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeCospi(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkCospiHalfHalf() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x252f4343l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testCospiHalfHalf(inV, out);
+            verifyResultsCospiHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCospiHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testCospiHalfHalf(inV, out);
+            verifyResultsCospiHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCospiHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCospiHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeCospi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkCospiHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkCospiHalf2Half2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x3993dd0dl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testCospiHalf2Half2(inV, out);
+            verifyResultsCospiHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCospiHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testCospiHalf2Half2(inV, out);
+            verifyResultsCospiHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCospiHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCospiHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeCospi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkCospiHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkCospiHalf3Half3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x989ba201l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testCospiHalf3Half3(inV, out);
+            verifyResultsCospiHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCospiHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testCospiHalf3Half3(inV, out);
+            verifyResultsCospiHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCospiHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCospiHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeCospi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkCospiHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkCospiHalf4Half4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xf7a366f5l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testCospiHalf4Half4(inV, out);
+            verifyResultsCospiHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCospiHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testCospiHalf4Half4(inV, out);
+            verifyResultsCospiHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCospiHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCospiHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeCospi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkCospiHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testCospi() {
         checkCospiFloatFloat();
         checkCospiFloat2Float2();
         checkCospiFloat3Float3();
         checkCospiFloat4Float4();
+        checkCospiHalfHalf();
+        checkCospiHalf2Half2();
+        checkCospiHalf3Half3();
+        checkCospiHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCospi.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCospi.rs
index c6e5922..1ebba63 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCospi.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCospi.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testCospiFloat4Float4(float4 inV) {
     return cospi(inV);
 }
+
+half __attribute__((kernel)) testCospiHalfHalf(half inV) {
+    return cospi(inV);
+}
+
+half2 __attribute__((kernel)) testCospiHalf2Half2(half2 inV) {
+    return cospi(inV);
+}
+
+half3 __attribute__((kernel)) testCospiHalf3Half3(half3 inV) {
+    return cospi(inV);
+}
+
+half4 __attribute__((kernel)) testCospiHalf4Half4(half4 inV) {
+    return cospi(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCospiRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCospiRelaxed.rs
index 582b8c0..d7281ba 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCospiRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCospiRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCross.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCross.java
index 61d0021..57b4a07 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCross.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCross.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -88,7 +89,7 @@
             for (int j = 0; j < 3 ; j++) {
                 args.inRightVector[j] = arrayInRightVector[i * 4 + j];
             }
-            Target target = new Target(relaxed);
+            Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
             CoreMathVerifier.computeCross(args, target);
 
             // Compare the expected outputs to the actual values returned by RS.
@@ -179,7 +180,7 @@
             for (int j = 0; j < 4 ; j++) {
                 args.inRightVector[j] = arrayInRightVector[i * 4 + j];
             }
-            Target target = new Target(relaxed);
+            Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
             CoreMathVerifier.computeCross(args, target);
 
             // Compare the expected outputs to the actual values returned by RS.
@@ -224,8 +225,214 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfNHalfNHalfN {
+        public short[] inLeftVector;
+        public double[] inLeftVectorDouble;
+        public short[] inRightVector;
+        public double[] inRightVectorDouble;
+        public Target.Floaty[] out;
+    }
+
+    private void checkCrossHalf3Half3Half3() {
+        Allocation inLeftVector = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0xfc3afdafl, false);
+        Allocation inRightVector = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0xcc0165eal, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.set_gAllocInRightVector(inRightVector);
+            script.forEach_testCrossHalf3Half3Half3(inLeftVector, out);
+            verifyResultsCrossHalf3Half3Half3(inLeftVector, inRightVector, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCrossHalf3Half3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInRightVector(inRightVector);
+            scriptRelaxed.forEach_testCrossHalf3Half3Half3(inLeftVector, out);
+            verifyResultsCrossHalf3Half3Half3(inLeftVector, inRightVector, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCrossHalf3Half3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCrossHalf3Half3Half3(Allocation inLeftVector, Allocation inRightVector, Allocation out, boolean relaxed) {
+        short[] arrayInLeftVector = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInLeftVector, (short) 42);
+        inLeftVector.copyTo(arrayInLeftVector);
+        short[] arrayInRightVector = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInRightVector, (short) 42);
+        inRightVector.copyTo(arrayInRightVector);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsHalfNHalfNHalfN args = new ArgumentsHalfNHalfNHalfN();
+            // Create the appropriate sized arrays in args
+            args.inLeftVector = new short[3];
+            args.inLeftVectorDouble = new double[3];
+            args.inRightVector = new short[3];
+            args.inRightVectorDouble = new double[3];
+            args.out = new Target.Floaty[3];
+            // Fill args with the input values
+            for (int j = 0; j < 3 ; j++) {
+                args.inLeftVector[j] = arrayInLeftVector[i * 4 + j];
+                args.inLeftVectorDouble[j] = Float16Utils.convertFloat16ToDouble(args.inLeftVector[j]);
+            }
+            for (int j = 0; j < 3 ; j++) {
+                args.inRightVector[j] = arrayInRightVector[i * 4 + j];
+                args.inRightVectorDouble[j] = Float16Utils.convertFloat16ToDouble(args.inRightVector[j]);
+            }
+            Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+            CoreMathVerifier.computeCross(args, target);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            for (int j = 0; j < 3 ; j++) {
+                if (!args.out[j].couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+            }
+            if (!valid) {
+                if (!errorFound) {
+                    errorFound = true;
+                    for (int j = 0; j < 3 ; j++) {
+                        message.append("Input inLeftVector: ");
+                        appendVariableToMessage(message, arrayInLeftVector[i * 4 + j]);
+                        message.append("\n");
+                    }
+                    for (int j = 0; j < 3 ; j++) {
+                        message.append("Input inRightVector: ");
+                        appendVariableToMessage(message, arrayInRightVector[i * 4 + j]);
+                        message.append("\n");
+                    }
+                    for (int j = 0; j < 3 ; j++) {
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out[j]);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out[j].couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                    }
+                    message.append("Errors at");
+                }
+                message.append(" [");
+                message.append(Integer.toString(i));
+                message.append("]");
+            }
+        }
+        assertFalse("Incorrect output for checkCrossHalf3Half3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkCrossHalf4Half4Half4() {
+        Allocation inLeftVector = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xa8692054l, false);
+        Allocation inRightVector = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xb7c137a1l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.set_gAllocInRightVector(inRightVector);
+            script.forEach_testCrossHalf4Half4Half4(inLeftVector, out);
+            verifyResultsCrossHalf4Half4Half4(inLeftVector, inRightVector, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCrossHalf4Half4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInRightVector(inRightVector);
+            scriptRelaxed.forEach_testCrossHalf4Half4Half4(inLeftVector, out);
+            verifyResultsCrossHalf4Half4Half4(inLeftVector, inRightVector, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCrossHalf4Half4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCrossHalf4Half4Half4(Allocation inLeftVector, Allocation inRightVector, Allocation out, boolean relaxed) {
+        short[] arrayInLeftVector = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInLeftVector, (short) 42);
+        inLeftVector.copyTo(arrayInLeftVector);
+        short[] arrayInRightVector = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInRightVector, (short) 42);
+        inRightVector.copyTo(arrayInRightVector);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsHalfNHalfNHalfN args = new ArgumentsHalfNHalfNHalfN();
+            // Create the appropriate sized arrays in args
+            args.inLeftVector = new short[4];
+            args.inLeftVectorDouble = new double[4];
+            args.inRightVector = new short[4];
+            args.inRightVectorDouble = new double[4];
+            args.out = new Target.Floaty[4];
+            // Fill args with the input values
+            for (int j = 0; j < 4 ; j++) {
+                args.inLeftVector[j] = arrayInLeftVector[i * 4 + j];
+                args.inLeftVectorDouble[j] = Float16Utils.convertFloat16ToDouble(args.inLeftVector[j]);
+            }
+            for (int j = 0; j < 4 ; j++) {
+                args.inRightVector[j] = arrayInRightVector[i * 4 + j];
+                args.inRightVectorDouble[j] = Float16Utils.convertFloat16ToDouble(args.inRightVector[j]);
+            }
+            Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+            CoreMathVerifier.computeCross(args, target);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            for (int j = 0; j < 4 ; j++) {
+                if (!args.out[j].couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+            }
+            if (!valid) {
+                if (!errorFound) {
+                    errorFound = true;
+                    for (int j = 0; j < 4 ; j++) {
+                        message.append("Input inLeftVector: ");
+                        appendVariableToMessage(message, arrayInLeftVector[i * 4 + j]);
+                        message.append("\n");
+                    }
+                    for (int j = 0; j < 4 ; j++) {
+                        message.append("Input inRightVector: ");
+                        appendVariableToMessage(message, arrayInRightVector[i * 4 + j]);
+                        message.append("\n");
+                    }
+                    for (int j = 0; j < 4 ; j++) {
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out[j]);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out[j].couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                    }
+                    message.append("Errors at");
+                }
+                message.append(" [");
+                message.append(Integer.toString(i));
+                message.append("]");
+            }
+        }
+        assertFalse("Incorrect output for checkCrossHalf4Half4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testCross() {
         checkCrossFloat3Float3Float3();
         checkCrossFloat4Float4Float4();
+        checkCrossHalf3Half3Half3();
+        checkCrossHalf4Half4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCross.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCross.rs
index 9be99a0..9849707f 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCross.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCross.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -30,3 +30,13 @@
     float4 inRightVector = rsGetElementAt_float4(gAllocInRightVector, x);
     return cross(inLeftVector, inRightVector);
 }
+
+half3 __attribute__((kernel)) testCrossHalf3Half3Half3(half3 inLeftVector, unsigned int x) {
+    half3 inRightVector = rsGetElementAt_half3(gAllocInRightVector, x);
+    return cross(inLeftVector, inRightVector);
+}
+
+half4 __attribute__((kernel)) testCrossHalf4Half4Half4(half4 inLeftVector, unsigned int x) {
+    half4 inRightVector = rsGetElementAt_half4(gAllocInRightVector, x);
+    return cross(inLeftVector, inRightVector);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCrossRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCrossRelaxed.rs
index cd95138..06a685c 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCrossRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCrossRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestDegrees.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestDegrees.java
index 03eee53..2020e2b 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestDegrees.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestDegrees.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeDegrees(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeDegrees(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeDegrees(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeDegrees(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkDegreesHalfHalf() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x17e3b944l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testDegreesHalfHalf(inV, out);
+            verifyResultsDegreesHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDegreesHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testDegreesHalfHalf(inV, out);
+            verifyResultsDegreesHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDegreesHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsDegreesHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeDegrees(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkDegreesHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkDegreesHalf2Half2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x32fc2a46l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testDegreesHalf2Half2(inV, out);
+            verifyResultsDegreesHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDegreesHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testDegreesHalf2Half2(inV, out);
+            verifyResultsDegreesHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDegreesHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsDegreesHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeDegrees(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkDegreesHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkDegreesHalf3Half3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x9203ef3al, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testDegreesHalf3Half3(inV, out);
+            verifyResultsDegreesHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDegreesHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testDegreesHalf3Half3(inV, out);
+            verifyResultsDegreesHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDegreesHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsDegreesHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeDegrees(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkDegreesHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkDegreesHalf4Half4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xf10bb42el, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testDegreesHalf4Half4(inV, out);
+            verifyResultsDegreesHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDegreesHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testDegreesHalf4Half4(inV, out);
+            verifyResultsDegreesHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDegreesHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsDegreesHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeDegrees(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkDegreesHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testDegrees() {
         checkDegreesFloatFloat();
         checkDegreesFloat2Float2();
         checkDegreesFloat3Float3();
         checkDegreesFloat4Float4();
+        checkDegreesHalfHalf();
+        checkDegreesHalf2Half2();
+        checkDegreesHalf3Half3();
+        checkDegreesHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestDegrees.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestDegrees.rs
index 24c9b4b..fb54ef1 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestDegrees.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestDegrees.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testDegreesFloat4Float4(float4 inV) {
     return degrees(inV);
 }
+
+half __attribute__((kernel)) testDegreesHalfHalf(half inV) {
+    return degrees(inV);
+}
+
+half2 __attribute__((kernel)) testDegreesHalf2Half2(half2 inV) {
+    return degrees(inV);
+}
+
+half3 __attribute__((kernel)) testDegreesHalf3Half3(half3 inV) {
+    return degrees(inV);
+}
+
+half4 __attribute__((kernel)) testDegreesHalf4Half4(half4 inV) {
+    return degrees(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestDegreesRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestDegreesRelaxed.rs
index 8977aa0..88cc208 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestDegreesRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestDegreesRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestDistance.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestDistance.java
index 6051525..c4c3b01 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestDistance.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestDistance.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -81,7 +82,7 @@
             // Fill args with the input values
             args.inLeftVector = arrayInLeftVector[i];
             args.inRightVector = arrayInRightVector[i];
-            Target target = new Target(relaxed);
+            Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
             CoreMathVerifier.computeDistance(args, target);
 
             // Compare the expected outputs to the actual values returned by RS.
@@ -169,7 +170,7 @@
             for (int j = 0; j < 2 ; j++) {
                 args.inRightVector[j] = arrayInRightVector[i * 2 + j];
             }
-            Target target = new Target(relaxed);
+            Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
             CoreMathVerifier.computeDistance(args, target);
 
             // Compare the expected outputs to the actual values returned by RS.
@@ -255,7 +256,7 @@
             for (int j = 0; j < 3 ; j++) {
                 args.inRightVector[j] = arrayInRightVector[i * 4 + j];
             }
-            Target target = new Target(relaxed);
+            Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
             CoreMathVerifier.computeDistance(args, target);
 
             // Compare the expected outputs to the actual values returned by RS.
@@ -341,7 +342,7 @@
             for (int j = 0; j < 4 ; j++) {
                 args.inRightVector[j] = arrayInRightVector[i * 4 + j];
             }
-            Target target = new Target(relaxed);
+            Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
             CoreMathVerifier.computeDistance(args, target);
 
             // Compare the expected outputs to the actual values returned by RS.
@@ -382,10 +383,390 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalfHalf {
+        public short inLeftVector;
+        public double inLeftVectorDouble;
+        public short inRightVector;
+        public double inRightVectorDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkDistanceHalfHalfHalf() {
+        Allocation inLeftVector = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xb911c71l, false);
+        Allocation inRightVector = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x5f789080l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.set_gAllocInRightVector(inRightVector);
+            script.forEach_testDistanceHalfHalfHalf(inLeftVector, out);
+            verifyResultsDistanceHalfHalfHalf(inLeftVector, inRightVector, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDistanceHalfHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInRightVector(inRightVector);
+            scriptRelaxed.forEach_testDistanceHalfHalfHalf(inLeftVector, out);
+            verifyResultsDistanceHalfHalfHalf(inLeftVector, inRightVector, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDistanceHalfHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsDistanceHalfHalfHalf(Allocation inLeftVector, Allocation inRightVector, Allocation out, boolean relaxed) {
+        short[] arrayInLeftVector = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInLeftVector, (short) 42);
+        inLeftVector.copyTo(arrayInLeftVector);
+        short[] arrayInRightVector = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInRightVector, (short) 42);
+        inRightVector.copyTo(arrayInRightVector);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+            // Create the appropriate sized arrays in args
+            // Fill args with the input values
+            args.inLeftVector = arrayInLeftVector[i];
+            args.inLeftVectorDouble = Float16Utils.convertFloat16ToDouble(args.inLeftVector);
+            args.inRightVector = arrayInRightVector[i];
+            args.inRightVectorDouble = Float16Utils.convertFloat16ToDouble(args.inRightVector);
+            Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+            CoreMathVerifier.computeDistance(args, target);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i]))) {
+                valid = false;
+            }
+            if (!valid) {
+                if (!errorFound) {
+                    errorFound = true;
+                    message.append("Input inLeftVector: ");
+                    appendVariableToMessage(message, arrayInLeftVector[i]);
+                    message.append("\n");
+                    message.append("Input inRightVector: ");
+                    appendVariableToMessage(message, arrayInRightVector[i]);
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    appendVariableToMessage(message, args.out);
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    appendVariableToMessage(message, arrayOut[i]);
+                    message.append("\n");
+                    message.append("Actual   output out (in double): ");
+                    appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i]));
+                    if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i]))) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    message.append("Errors at");
+                }
+                message.append(" [");
+                message.append(Integer.toString(i));
+                message.append("]");
+            }
+        }
+        assertFalse("Incorrect output for checkDistanceHalfHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsHalfNHalfNHalf {
+        public short[] inLeftVector;
+        public double[] inLeftVectorDouble;
+        public short[] inRightVector;
+        public double[] inRightVectorDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkDistanceHalf2Half2Half() {
+        Allocation inLeftVector = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x1fddb297l, false);
+        Allocation inRightVector = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xc855c8e2l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.set_gAllocInRightVector(inRightVector);
+            script.forEach_testDistanceHalf2Half2Half(inLeftVector, out);
+            verifyResultsDistanceHalf2Half2Half(inLeftVector, inRightVector, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDistanceHalf2Half2Half: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInRightVector(inRightVector);
+            scriptRelaxed.forEach_testDistanceHalf2Half2Half(inLeftVector, out);
+            verifyResultsDistanceHalf2Half2Half(inLeftVector, inRightVector, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDistanceHalf2Half2Half: " + e.toString());
+        }
+    }
+
+    private void verifyResultsDistanceHalf2Half2Half(Allocation inLeftVector, Allocation inRightVector, Allocation out, boolean relaxed) {
+        short[] arrayInLeftVector = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInLeftVector, (short) 42);
+        inLeftVector.copyTo(arrayInLeftVector);
+        short[] arrayInRightVector = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInRightVector, (short) 42);
+        inRightVector.copyTo(arrayInRightVector);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsHalfNHalfNHalf args = new ArgumentsHalfNHalfNHalf();
+            // Create the appropriate sized arrays in args
+            args.inLeftVector = new short[2];
+            args.inLeftVectorDouble = new double[2];
+            args.inRightVector = new short[2];
+            args.inRightVectorDouble = new double[2];
+            // Fill args with the input values
+            for (int j = 0; j < 2 ; j++) {
+                args.inLeftVector[j] = arrayInLeftVector[i * 2 + j];
+                args.inLeftVectorDouble[j] = Float16Utils.convertFloat16ToDouble(args.inLeftVector[j]);
+            }
+            for (int j = 0; j < 2 ; j++) {
+                args.inRightVector[j] = arrayInRightVector[i * 2 + j];
+                args.inRightVectorDouble[j] = Float16Utils.convertFloat16ToDouble(args.inRightVector[j]);
+            }
+            Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+            CoreMathVerifier.computeDistance(args, target);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i]))) {
+                valid = false;
+            }
+            if (!valid) {
+                if (!errorFound) {
+                    errorFound = true;
+                    for (int j = 0; j < 2 ; j++) {
+                        message.append("Input inLeftVector: ");
+                        appendVariableToMessage(message, arrayInLeftVector[i * 2 + j]);
+                        message.append("\n");
+                    }
+                    for (int j = 0; j < 2 ; j++) {
+                        message.append("Input inRightVector: ");
+                        appendVariableToMessage(message, arrayInRightVector[i * 2 + j]);
+                        message.append("\n");
+                    }
+                    message.append("Expected output out: ");
+                    appendVariableToMessage(message, args.out);
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    appendVariableToMessage(message, arrayOut[i]);
+                    message.append("\n");
+                    message.append("Actual   output out (in double): ");
+                    appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i]));
+                    if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i]))) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    message.append("Errors at");
+                }
+                message.append(" [");
+                message.append(Integer.toString(i));
+                message.append("]");
+            }
+        }
+        assertFalse("Incorrect output for checkDistanceHalf2Half2Half" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkDistanceHalf3Half3Half() {
+        Allocation inLeftVector = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0xea22ab53l, false);
+        Allocation inRightVector = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0xc1eb9076l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.set_gAllocInRightVector(inRightVector);
+            script.forEach_testDistanceHalf3Half3Half(inLeftVector, out);
+            verifyResultsDistanceHalf3Half3Half(inLeftVector, inRightVector, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDistanceHalf3Half3Half: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInRightVector(inRightVector);
+            scriptRelaxed.forEach_testDistanceHalf3Half3Half(inLeftVector, out);
+            verifyResultsDistanceHalf3Half3Half(inLeftVector, inRightVector, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDistanceHalf3Half3Half: " + e.toString());
+        }
+    }
+
+    private void verifyResultsDistanceHalf3Half3Half(Allocation inLeftVector, Allocation inRightVector, Allocation out, boolean relaxed) {
+        short[] arrayInLeftVector = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInLeftVector, (short) 42);
+        inLeftVector.copyTo(arrayInLeftVector);
+        short[] arrayInRightVector = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInRightVector, (short) 42);
+        inRightVector.copyTo(arrayInRightVector);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsHalfNHalfNHalf args = new ArgumentsHalfNHalfNHalf();
+            // Create the appropriate sized arrays in args
+            args.inLeftVector = new short[3];
+            args.inLeftVectorDouble = new double[3];
+            args.inRightVector = new short[3];
+            args.inRightVectorDouble = new double[3];
+            // Fill args with the input values
+            for (int j = 0; j < 3 ; j++) {
+                args.inLeftVector[j] = arrayInLeftVector[i * 4 + j];
+                args.inLeftVectorDouble[j] = Float16Utils.convertFloat16ToDouble(args.inLeftVector[j]);
+            }
+            for (int j = 0; j < 3 ; j++) {
+                args.inRightVector[j] = arrayInRightVector[i * 4 + j];
+                args.inRightVectorDouble[j] = Float16Utils.convertFloat16ToDouble(args.inRightVector[j]);
+            }
+            Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+            CoreMathVerifier.computeDistance(args, target);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i]))) {
+                valid = false;
+            }
+            if (!valid) {
+                if (!errorFound) {
+                    errorFound = true;
+                    for (int j = 0; j < 3 ; j++) {
+                        message.append("Input inLeftVector: ");
+                        appendVariableToMessage(message, arrayInLeftVector[i * 4 + j]);
+                        message.append("\n");
+                    }
+                    for (int j = 0; j < 3 ; j++) {
+                        message.append("Input inRightVector: ");
+                        appendVariableToMessage(message, arrayInRightVector[i * 4 + j]);
+                        message.append("\n");
+                    }
+                    message.append("Expected output out: ");
+                    appendVariableToMessage(message, args.out);
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    appendVariableToMessage(message, arrayOut[i]);
+                    message.append("\n");
+                    message.append("Actual   output out (in double): ");
+                    appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i]));
+                    if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i]))) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    message.append("Errors at");
+                }
+                message.append(" [");
+                message.append(Integer.toString(i));
+                message.append("]");
+            }
+        }
+        assertFalse("Incorrect output for checkDistanceHalf3Half3Half" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkDistanceHalf4Half4Half() {
+        Allocation inLeftVector = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xb467a40fl, false);
+        Allocation inRightVector = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xbb81580al, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.set_gAllocInRightVector(inRightVector);
+            script.forEach_testDistanceHalf4Half4Half(inLeftVector, out);
+            verifyResultsDistanceHalf4Half4Half(inLeftVector, inRightVector, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDistanceHalf4Half4Half: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInRightVector(inRightVector);
+            scriptRelaxed.forEach_testDistanceHalf4Half4Half(inLeftVector, out);
+            verifyResultsDistanceHalf4Half4Half(inLeftVector, inRightVector, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDistanceHalf4Half4Half: " + e.toString());
+        }
+    }
+
+    private void verifyResultsDistanceHalf4Half4Half(Allocation inLeftVector, Allocation inRightVector, Allocation out, boolean relaxed) {
+        short[] arrayInLeftVector = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInLeftVector, (short) 42);
+        inLeftVector.copyTo(arrayInLeftVector);
+        short[] arrayInRightVector = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInRightVector, (short) 42);
+        inRightVector.copyTo(arrayInRightVector);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsHalfNHalfNHalf args = new ArgumentsHalfNHalfNHalf();
+            // Create the appropriate sized arrays in args
+            args.inLeftVector = new short[4];
+            args.inLeftVectorDouble = new double[4];
+            args.inRightVector = new short[4];
+            args.inRightVectorDouble = new double[4];
+            // Fill args with the input values
+            for (int j = 0; j < 4 ; j++) {
+                args.inLeftVector[j] = arrayInLeftVector[i * 4 + j];
+                args.inLeftVectorDouble[j] = Float16Utils.convertFloat16ToDouble(args.inLeftVector[j]);
+            }
+            for (int j = 0; j < 4 ; j++) {
+                args.inRightVector[j] = arrayInRightVector[i * 4 + j];
+                args.inRightVectorDouble[j] = Float16Utils.convertFloat16ToDouble(args.inRightVector[j]);
+            }
+            Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+            CoreMathVerifier.computeDistance(args, target);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i]))) {
+                valid = false;
+            }
+            if (!valid) {
+                if (!errorFound) {
+                    errorFound = true;
+                    for (int j = 0; j < 4 ; j++) {
+                        message.append("Input inLeftVector: ");
+                        appendVariableToMessage(message, arrayInLeftVector[i * 4 + j]);
+                        message.append("\n");
+                    }
+                    for (int j = 0; j < 4 ; j++) {
+                        message.append("Input inRightVector: ");
+                        appendVariableToMessage(message, arrayInRightVector[i * 4 + j]);
+                        message.append("\n");
+                    }
+                    message.append("Expected output out: ");
+                    appendVariableToMessage(message, args.out);
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    appendVariableToMessage(message, arrayOut[i]);
+                    message.append("\n");
+                    message.append("Actual   output out (in double): ");
+                    appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i]));
+                    if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i]))) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    message.append("Errors at");
+                }
+                message.append(" [");
+                message.append(Integer.toString(i));
+                message.append("]");
+            }
+        }
+        assertFalse("Incorrect output for checkDistanceHalf4Half4Half" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testDistance() {
         checkDistanceFloatFloatFloat();
         checkDistanceFloat2Float2Float();
         checkDistanceFloat3Float3Float();
         checkDistanceFloat4Float4Float();
+        checkDistanceHalfHalfHalf();
+        checkDistanceHalf2Half2Half();
+        checkDistanceHalf3Half3Half();
+        checkDistanceHalf4Half4Half();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestDistance.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestDistance.rs
index a682646..4f9cbc2 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestDistance.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestDistance.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -40,3 +40,23 @@
     float4 inRightVector = rsGetElementAt_float4(gAllocInRightVector, x);
     return distance(inLeftVector, inRightVector);
 }
+
+half __attribute__((kernel)) testDistanceHalfHalfHalf(half inLeftVector, unsigned int x) {
+    half inRightVector = rsGetElementAt_half(gAllocInRightVector, x);
+    return distance(inLeftVector, inRightVector);
+}
+
+half __attribute__((kernel)) testDistanceHalf2Half2Half(half2 inLeftVector, unsigned int x) {
+    half2 inRightVector = rsGetElementAt_half2(gAllocInRightVector, x);
+    return distance(inLeftVector, inRightVector);
+}
+
+half __attribute__((kernel)) testDistanceHalf3Half3Half(half3 inLeftVector, unsigned int x) {
+    half3 inRightVector = rsGetElementAt_half3(gAllocInRightVector, x);
+    return distance(inLeftVector, inRightVector);
+}
+
+half __attribute__((kernel)) testDistanceHalf4Half4Half(half4 inLeftVector, unsigned int x) {
+    half4 inRightVector = rsGetElementAt_half4(gAllocInRightVector, x);
+    return distance(inLeftVector, inRightVector);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestDistanceRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestDistanceRelaxed.rs
index 00b0dfd..0ad21fc 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestDistanceRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestDistanceRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestDot.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestDot.java
index 3898003..5fe3d9e 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestDot.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestDot.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -81,7 +82,7 @@
             // Fill args with the input values
             args.inLeftVector = arrayInLeftVector[i];
             args.inRightVector = arrayInRightVector[i];
-            Target target = new Target(relaxed);
+            Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
             CoreMathVerifier.computeDot(args, target);
 
             // Compare the expected outputs to the actual values returned by RS.
@@ -169,7 +170,7 @@
             for (int j = 0; j < 2 ; j++) {
                 args.inRightVector[j] = arrayInRightVector[i * 2 + j];
             }
-            Target target = new Target(relaxed);
+            Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
             CoreMathVerifier.computeDot(args, target);
 
             // Compare the expected outputs to the actual values returned by RS.
@@ -255,7 +256,7 @@
             for (int j = 0; j < 3 ; j++) {
                 args.inRightVector[j] = arrayInRightVector[i * 4 + j];
             }
-            Target target = new Target(relaxed);
+            Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
             CoreMathVerifier.computeDot(args, target);
 
             // Compare the expected outputs to the actual values returned by RS.
@@ -341,7 +342,7 @@
             for (int j = 0; j < 4 ; j++) {
                 args.inRightVector[j] = arrayInRightVector[i * 4 + j];
             }
-            Target target = new Target(relaxed);
+            Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
             CoreMathVerifier.computeDot(args, target);
 
             // Compare the expected outputs to the actual values returned by RS.
@@ -382,10 +383,390 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalfHalf {
+        public short inLeftVector;
+        public double inLeftVectorDouble;
+        public short inRightVector;
+        public double inRightVectorDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkDotHalfHalfHalf() {
+        Allocation inLeftVector = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xcde53c8dl, false);
+        Allocation inRightVector = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x399f534l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.set_gAllocInRightVector(inRightVector);
+            script.forEach_testDotHalfHalfHalf(inLeftVector, out);
+            verifyResultsDotHalfHalfHalf(inLeftVector, inRightVector, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDotHalfHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInRightVector(inRightVector);
+            scriptRelaxed.forEach_testDotHalfHalfHalf(inLeftVector, out);
+            verifyResultsDotHalfHalfHalf(inLeftVector, inRightVector, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDotHalfHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsDotHalfHalfHalf(Allocation inLeftVector, Allocation inRightVector, Allocation out, boolean relaxed) {
+        short[] arrayInLeftVector = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInLeftVector, (short) 42);
+        inLeftVector.copyTo(arrayInLeftVector);
+        short[] arrayInRightVector = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInRightVector, (short) 42);
+        inRightVector.copyTo(arrayInRightVector);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+            // Create the appropriate sized arrays in args
+            // Fill args with the input values
+            args.inLeftVector = arrayInLeftVector[i];
+            args.inLeftVectorDouble = Float16Utils.convertFloat16ToDouble(args.inLeftVector);
+            args.inRightVector = arrayInRightVector[i];
+            args.inRightVectorDouble = Float16Utils.convertFloat16ToDouble(args.inRightVector);
+            Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+            CoreMathVerifier.computeDot(args, target);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i]))) {
+                valid = false;
+            }
+            if (!valid) {
+                if (!errorFound) {
+                    errorFound = true;
+                    message.append("Input inLeftVector: ");
+                    appendVariableToMessage(message, arrayInLeftVector[i]);
+                    message.append("\n");
+                    message.append("Input inRightVector: ");
+                    appendVariableToMessage(message, arrayInRightVector[i]);
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    appendVariableToMessage(message, args.out);
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    appendVariableToMessage(message, arrayOut[i]);
+                    message.append("\n");
+                    message.append("Actual   output out (in double): ");
+                    appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i]));
+                    if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i]))) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    message.append("Errors at");
+                }
+                message.append(" [");
+                message.append(Integer.toString(i));
+                message.append("]");
+            }
+        }
+        assertFalse("Incorrect output for checkDotHalfHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsHalfNHalfNHalf {
+        public short[] inLeftVector;
+        public double[] inLeftVectorDouble;
+        public short[] inRightVector;
+        public double[] inRightVectorDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkDotHalf2Half2Half() {
+        Allocation inLeftVector = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xb1799cd3l, false);
+        Allocation inRightVector = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x3d8620f6l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.set_gAllocInRightVector(inRightVector);
+            script.forEach_testDotHalf2Half2Half(inLeftVector, out);
+            verifyResultsDotHalf2Half2Half(inLeftVector, inRightVector, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDotHalf2Half2Half: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInRightVector(inRightVector);
+            scriptRelaxed.forEach_testDotHalf2Half2Half(inLeftVector, out);
+            verifyResultsDotHalf2Half2Half(inLeftVector, inRightVector, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDotHalf2Half2Half: " + e.toString());
+        }
+    }
+
+    private void verifyResultsDotHalf2Half2Half(Allocation inLeftVector, Allocation inRightVector, Allocation out, boolean relaxed) {
+        short[] arrayInLeftVector = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInLeftVector, (short) 42);
+        inLeftVector.copyTo(arrayInLeftVector);
+        short[] arrayInRightVector = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInRightVector, (short) 42);
+        inRightVector.copyTo(arrayInRightVector);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsHalfNHalfNHalf args = new ArgumentsHalfNHalfNHalf();
+            // Create the appropriate sized arrays in args
+            args.inLeftVector = new short[2];
+            args.inLeftVectorDouble = new double[2];
+            args.inRightVector = new short[2];
+            args.inRightVectorDouble = new double[2];
+            // Fill args with the input values
+            for (int j = 0; j < 2 ; j++) {
+                args.inLeftVector[j] = arrayInLeftVector[i * 2 + j];
+                args.inLeftVectorDouble[j] = Float16Utils.convertFloat16ToDouble(args.inLeftVector[j]);
+            }
+            for (int j = 0; j < 2 ; j++) {
+                args.inRightVector[j] = arrayInRightVector[i * 2 + j];
+                args.inRightVectorDouble[j] = Float16Utils.convertFloat16ToDouble(args.inRightVector[j]);
+            }
+            Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+            CoreMathVerifier.computeDot(args, target);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i]))) {
+                valid = false;
+            }
+            if (!valid) {
+                if (!errorFound) {
+                    errorFound = true;
+                    for (int j = 0; j < 2 ; j++) {
+                        message.append("Input inLeftVector: ");
+                        appendVariableToMessage(message, arrayInLeftVector[i * 2 + j]);
+                        message.append("\n");
+                    }
+                    for (int j = 0; j < 2 ; j++) {
+                        message.append("Input inRightVector: ");
+                        appendVariableToMessage(message, arrayInRightVector[i * 2 + j]);
+                        message.append("\n");
+                    }
+                    message.append("Expected output out: ");
+                    appendVariableToMessage(message, args.out);
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    appendVariableToMessage(message, arrayOut[i]);
+                    message.append("\n");
+                    message.append("Actual   output out (in double): ");
+                    appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i]));
+                    if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i]))) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    message.append("Errors at");
+                }
+                message.append(" [");
+                message.append(Integer.toString(i));
+                message.append("]");
+            }
+        }
+        assertFalse("Incorrect output for checkDotHalf2Half2Half" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkDotHalf3Half3Half() {
+        Allocation inLeftVector = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x7bbe958fl, false);
+        Allocation inRightVector = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x371be88al, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.set_gAllocInRightVector(inRightVector);
+            script.forEach_testDotHalf3Half3Half(inLeftVector, out);
+            verifyResultsDotHalf3Half3Half(inLeftVector, inRightVector, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDotHalf3Half3Half: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInRightVector(inRightVector);
+            scriptRelaxed.forEach_testDotHalf3Half3Half(inLeftVector, out);
+            verifyResultsDotHalf3Half3Half(inLeftVector, inRightVector, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDotHalf3Half3Half: " + e.toString());
+        }
+    }
+
+    private void verifyResultsDotHalf3Half3Half(Allocation inLeftVector, Allocation inRightVector, Allocation out, boolean relaxed) {
+        short[] arrayInLeftVector = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInLeftVector, (short) 42);
+        inLeftVector.copyTo(arrayInLeftVector);
+        short[] arrayInRightVector = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInRightVector, (short) 42);
+        inRightVector.copyTo(arrayInRightVector);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsHalfNHalfNHalf args = new ArgumentsHalfNHalfNHalf();
+            // Create the appropriate sized arrays in args
+            args.inLeftVector = new short[3];
+            args.inLeftVectorDouble = new double[3];
+            args.inRightVector = new short[3];
+            args.inRightVectorDouble = new double[3];
+            // Fill args with the input values
+            for (int j = 0; j < 3 ; j++) {
+                args.inLeftVector[j] = arrayInLeftVector[i * 4 + j];
+                args.inLeftVectorDouble[j] = Float16Utils.convertFloat16ToDouble(args.inLeftVector[j]);
+            }
+            for (int j = 0; j < 3 ; j++) {
+                args.inRightVector[j] = arrayInRightVector[i * 4 + j];
+                args.inRightVectorDouble[j] = Float16Utils.convertFloat16ToDouble(args.inRightVector[j]);
+            }
+            Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+            CoreMathVerifier.computeDot(args, target);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i]))) {
+                valid = false;
+            }
+            if (!valid) {
+                if (!errorFound) {
+                    errorFound = true;
+                    for (int j = 0; j < 3 ; j++) {
+                        message.append("Input inLeftVector: ");
+                        appendVariableToMessage(message, arrayInLeftVector[i * 4 + j]);
+                        message.append("\n");
+                    }
+                    for (int j = 0; j < 3 ; j++) {
+                        message.append("Input inRightVector: ");
+                        appendVariableToMessage(message, arrayInRightVector[i * 4 + j]);
+                        message.append("\n");
+                    }
+                    message.append("Expected output out: ");
+                    appendVariableToMessage(message, args.out);
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    appendVariableToMessage(message, arrayOut[i]);
+                    message.append("\n");
+                    message.append("Actual   output out (in double): ");
+                    appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i]));
+                    if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i]))) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    message.append("Errors at");
+                }
+                message.append(" [");
+                message.append(Integer.toString(i));
+                message.append("]");
+            }
+        }
+        assertFalse("Incorrect output for checkDotHalf3Half3Half" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkDotHalf4Half4Half() {
+        Allocation inLeftVector = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x46038e4bl, false);
+        Allocation inRightVector = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x30b1b01el, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.set_gAllocInRightVector(inRightVector);
+            script.forEach_testDotHalf4Half4Half(inLeftVector, out);
+            verifyResultsDotHalf4Half4Half(inLeftVector, inRightVector, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDotHalf4Half4Half: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInRightVector(inRightVector);
+            scriptRelaxed.forEach_testDotHalf4Half4Half(inLeftVector, out);
+            verifyResultsDotHalf4Half4Half(inLeftVector, inRightVector, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDotHalf4Half4Half: " + e.toString());
+        }
+    }
+
+    private void verifyResultsDotHalf4Half4Half(Allocation inLeftVector, Allocation inRightVector, Allocation out, boolean relaxed) {
+        short[] arrayInLeftVector = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInLeftVector, (short) 42);
+        inLeftVector.copyTo(arrayInLeftVector);
+        short[] arrayInRightVector = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInRightVector, (short) 42);
+        inRightVector.copyTo(arrayInRightVector);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsHalfNHalfNHalf args = new ArgumentsHalfNHalfNHalf();
+            // Create the appropriate sized arrays in args
+            args.inLeftVector = new short[4];
+            args.inLeftVectorDouble = new double[4];
+            args.inRightVector = new short[4];
+            args.inRightVectorDouble = new double[4];
+            // Fill args with the input values
+            for (int j = 0; j < 4 ; j++) {
+                args.inLeftVector[j] = arrayInLeftVector[i * 4 + j];
+                args.inLeftVectorDouble[j] = Float16Utils.convertFloat16ToDouble(args.inLeftVector[j]);
+            }
+            for (int j = 0; j < 4 ; j++) {
+                args.inRightVector[j] = arrayInRightVector[i * 4 + j];
+                args.inRightVectorDouble[j] = Float16Utils.convertFloat16ToDouble(args.inRightVector[j]);
+            }
+            Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+            CoreMathVerifier.computeDot(args, target);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i]))) {
+                valid = false;
+            }
+            if (!valid) {
+                if (!errorFound) {
+                    errorFound = true;
+                    for (int j = 0; j < 4 ; j++) {
+                        message.append("Input inLeftVector: ");
+                        appendVariableToMessage(message, arrayInLeftVector[i * 4 + j]);
+                        message.append("\n");
+                    }
+                    for (int j = 0; j < 4 ; j++) {
+                        message.append("Input inRightVector: ");
+                        appendVariableToMessage(message, arrayInRightVector[i * 4 + j]);
+                        message.append("\n");
+                    }
+                    message.append("Expected output out: ");
+                    appendVariableToMessage(message, args.out);
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    appendVariableToMessage(message, arrayOut[i]);
+                    message.append("\n");
+                    message.append("Actual   output out (in double): ");
+                    appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i]));
+                    if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i]))) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    message.append("Errors at");
+                }
+                message.append(" [");
+                message.append(Integer.toString(i));
+                message.append("]");
+            }
+        }
+        assertFalse("Incorrect output for checkDotHalf4Half4Half" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testDot() {
         checkDotFloatFloatFloat();
         checkDotFloat2Float2Float();
         checkDotFloat3Float3Float();
         checkDotFloat4Float4Float();
+        checkDotHalfHalfHalf();
+        checkDotHalf2Half2Half();
+        checkDotHalf3Half3Half();
+        checkDotHalf4Half4Half();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestDot.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestDot.rs
index d7559e3..4e7013c 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestDot.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestDot.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -40,3 +40,23 @@
     float4 inRightVector = rsGetElementAt_float4(gAllocInRightVector, x);
     return dot(inLeftVector, inRightVector);
 }
+
+half __attribute__((kernel)) testDotHalfHalfHalf(half inLeftVector, unsigned int x) {
+    half inRightVector = rsGetElementAt_half(gAllocInRightVector, x);
+    return dot(inLeftVector, inRightVector);
+}
+
+half __attribute__((kernel)) testDotHalf2Half2Half(half2 inLeftVector, unsigned int x) {
+    half2 inRightVector = rsGetElementAt_half2(gAllocInRightVector, x);
+    return dot(inLeftVector, inRightVector);
+}
+
+half __attribute__((kernel)) testDotHalf3Half3Half(half3 inLeftVector, unsigned int x) {
+    half3 inRightVector = rsGetElementAt_half3(gAllocInRightVector, x);
+    return dot(inLeftVector, inRightVector);
+}
+
+half __attribute__((kernel)) testDotHalf4Half4Half(half4 inLeftVector, unsigned int x) {
+    half4 inRightVector = rsGetElementAt_half4(gAllocInRightVector, x);
+    return dot(inLeftVector, inRightVector);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestDotRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestDotRelaxed.rs
index dd94472..50ce702 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestDotRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestDotRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestErf.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestErf.java
index bc3a073..fee259a 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestErf.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestErf.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeErf(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeErf(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeErf(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeErf(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkErfHalfHalf() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x9cc93d62l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testErfHalfHalf(inV, out);
+            verifyResultsErfHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testErfHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testErfHalfHalf(inV, out);
+            verifyResultsErfHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testErfHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsErfHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeErf(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkErfHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkErfHalf2Half2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x10b366f4l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testErfHalf2Half2(inV, out);
+            verifyResultsErfHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testErfHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testErfHalf2Half2(inV, out);
+            verifyResultsErfHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testErfHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsErfHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeErf(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkErfHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkErfHalf3Half3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x6fbb2be8l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testErfHalf3Half3(inV, out);
+            verifyResultsErfHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testErfHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testErfHalf3Half3(inV, out);
+            verifyResultsErfHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testErfHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsErfHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeErf(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkErfHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkErfHalf4Half4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xcec2f0dcl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testErfHalf4Half4(inV, out);
+            verifyResultsErfHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testErfHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testErfHalf4Half4(inV, out);
+            verifyResultsErfHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testErfHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsErfHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeErf(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkErfHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testErf() {
         checkErfFloatFloat();
         checkErfFloat2Float2();
         checkErfFloat3Float3();
         checkErfFloat4Float4();
+        checkErfHalfHalf();
+        checkErfHalf2Half2();
+        checkErfHalf3Half3();
+        checkErfHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestErf.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestErf.rs
index 246e8fb..8a07a07 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestErf.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestErf.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testErfFloat4Float4(float4 inV) {
     return erf(inV);
 }
+
+half __attribute__((kernel)) testErfHalfHalf(half inV) {
+    return erf(inV);
+}
+
+half2 __attribute__((kernel)) testErfHalf2Half2(half2 inV) {
+    return erf(inV);
+}
+
+half3 __attribute__((kernel)) testErfHalf3Half3(half3 inV) {
+    return erf(inV);
+}
+
+half4 __attribute__((kernel)) testErfHalf4Half4(half4 inV) {
+    return erf(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestErfRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestErfRelaxed.rs
index 5963f80..17d87f0 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestErfRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestErfRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestErfc.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestErfc.java
index 856bcf4..be9d6e7 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestErfc.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestErfc.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeErfc(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeErfc(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeErfc(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeErfc(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkErfcHalfHalf() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xa498d5f1l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testErfcHalfHalf(inV, out);
+            verifyResultsErfcHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testErfcHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testErfcHalfHalf(inV, out);
+            verifyResultsErfcHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testErfcHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsErfcHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeErfc(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkErfcHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkErfcHalf2Half2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x7b1847cbl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testErfcHalf2Half2(inV, out);
+            verifyResultsErfcHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testErfcHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testErfcHalf2Half2(inV, out);
+            verifyResultsErfcHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testErfcHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsErfcHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeErfc(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkErfcHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkErfcHalf3Half3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0xda200cbfl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testErfcHalf3Half3(inV, out);
+            verifyResultsErfcHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testErfcHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testErfcHalf3Half3(inV, out);
+            verifyResultsErfcHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testErfcHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsErfcHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeErfc(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkErfcHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkErfcHalf4Half4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x3927d1b3l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testErfcHalf4Half4(inV, out);
+            verifyResultsErfcHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testErfcHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testErfcHalf4Half4(inV, out);
+            verifyResultsErfcHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testErfcHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsErfcHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeErfc(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkErfcHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testErfc() {
         checkErfcFloatFloat();
         checkErfcFloat2Float2();
         checkErfcFloat3Float3();
         checkErfcFloat4Float4();
+        checkErfcHalfHalf();
+        checkErfcHalf2Half2();
+        checkErfcHalf3Half3();
+        checkErfcHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestErfc.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestErfc.rs
index 1fc8310..037df91 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestErfc.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestErfc.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testErfcFloat4Float4(float4 inV) {
     return erfc(inV);
 }
+
+half __attribute__((kernel)) testErfcHalfHalf(half inV) {
+    return erfc(inV);
+}
+
+half2 __attribute__((kernel)) testErfcHalf2Half2(half2 inV) {
+    return erfc(inV);
+}
+
+half3 __attribute__((kernel)) testErfcHalf3Half3(half3 inV) {
+    return erfc(inV);
+}
+
+half4 __attribute__((kernel)) testErfcHalf4Half4(half4 inV) {
+    return erfc(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestErfcRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestErfcRelaxed.rs
index 99449ad..19a65d9 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestErfcRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestErfcRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExp.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExp.java
index 8e73056..53e468c 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExp.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExp.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeExp(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeExp(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeExp(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeExp(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkExpHalfHalf() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xd81f8cc6l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testExpHalfHalf(inV, out);
+            verifyResultsExpHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExpHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testExpHalfHalf(inV, out);
+            verifyResultsExpHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExpHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsExpHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeExp(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkExpHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkExpHalf2Half2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xa316d038l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testExpHalf2Half2(inV, out);
+            verifyResultsExpHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExpHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testExpHalf2Half2(inV, out);
+            verifyResultsExpHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExpHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsExpHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeExp(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkExpHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkExpHalf3Half3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x21e952cl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testExpHalf3Half3(inV, out);
+            verifyResultsExpHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExpHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testExpHalf3Half3(inV, out);
+            verifyResultsExpHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExpHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsExpHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeExp(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkExpHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkExpHalf4Half4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x61265a20l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testExpHalf4Half4(inV, out);
+            verifyResultsExpHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExpHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testExpHalf4Half4(inV, out);
+            verifyResultsExpHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExpHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsExpHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeExp(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkExpHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testExp() {
         checkExpFloatFloat();
         checkExpFloat2Float2();
         checkExpFloat3Float3();
         checkExpFloat4Float4();
+        checkExpHalfHalf();
+        checkExpHalf2Half2();
+        checkExpHalf3Half3();
+        checkExpHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExp.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExp.rs
index 9e25653..2a9d5e9 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExp.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExp.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testExpFloat4Float4(float4 inV) {
     return exp(inV);
 }
+
+half __attribute__((kernel)) testExpHalfHalf(half inV) {
+    return exp(inV);
+}
+
+half2 __attribute__((kernel)) testExpHalf2Half2(half2 inV) {
+    return exp(inV);
+}
+
+half3 __attribute__((kernel)) testExpHalf3Half3(half3 inV) {
+    return exp(inV);
+}
+
+half4 __attribute__((kernel)) testExpHalf4Half4(half4 inV) {
+    return exp(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExp10.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExp10.java
index fd01beb..aa22da8 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExp10.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExp10.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeExp10(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeExp10(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeExp10(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeExp10(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkExp10HalfHalf() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xe916fd3fl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testExp10HalfHalf(inV, out);
+            verifyResultsExp10HalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExp10HalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testExp10HalfHalf(inV, out);
+            verifyResultsExp10HalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExp10HalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsExp10HalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeExp10(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkExp10HalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkExp10Half2Half2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x2e422a29l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testExp10Half2Half2(inV, out);
+            verifyResultsExp10Half2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExp10Half2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testExp10Half2Half2(inV, out);
+            verifyResultsExp10Half2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExp10Half2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsExp10Half2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeExp10(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkExp10Half2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkExp10Half3Half3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x8d49ef1dl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testExp10Half3Half3(inV, out);
+            verifyResultsExp10Half3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExp10Half3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testExp10Half3Half3(inV, out);
+            verifyResultsExp10Half3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExp10Half3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsExp10Half3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeExp10(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkExp10Half3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkExp10Half4Half4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xec51b411l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testExp10Half4Half4(inV, out);
+            verifyResultsExp10Half4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExp10Half4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testExp10Half4Half4(inV, out);
+            verifyResultsExp10Half4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExp10Half4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsExp10Half4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeExp10(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkExp10Half4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testExp10() {
         checkExp10FloatFloat();
         checkExp10Float2Float2();
         checkExp10Float3Float3();
         checkExp10Float4Float4();
+        checkExp10HalfHalf();
+        checkExp10Half2Half2();
+        checkExp10Half3Half3();
+        checkExp10Half4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExp10.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExp10.rs
index cb52b10..dc30f5a 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExp10.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExp10.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testExp10Float4Float4(float4 inV) {
     return exp10(inV);
 }
+
+half __attribute__((kernel)) testExp10HalfHalf(half inV) {
+    return exp10(inV);
+}
+
+half2 __attribute__((kernel)) testExp10Half2Half2(half2 inV) {
+    return exp10(inV);
+}
+
+half3 __attribute__((kernel)) testExp10Half3Half3(half3 inV) {
+    return exp10(inV);
+}
+
+half4 __attribute__((kernel)) testExp10Half4Half4(half4 inV) {
+    return exp10(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExp10Relaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExp10Relaxed.rs
index e3cdc42..d95f6a7 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExp10Relaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExp10Relaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExp2.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExp2.java
index 8d1c698..abc7f9d 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExp2.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExp2.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeExp2(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeExp2(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeExp2(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeExp2(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkExp2HalfHalf() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xe270827al, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testExp2HalfHalf(inV, out);
+            verifyResultsExp2HalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExp2HalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testExp2HalfHalf(inV, out);
+            verifyResultsExp2HalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExp2HalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsExp2HalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeExp2(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkExp2HalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkExp2Half2Half2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x25d5714cl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testExp2Half2Half2(inV, out);
+            verifyResultsExp2Half2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExp2Half2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testExp2Half2Half2(inV, out);
+            verifyResultsExp2Half2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExp2Half2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsExp2Half2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeExp2(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkExp2Half2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkExp2Half3Half3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x84dd3640l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testExp2Half3Half3(inV, out);
+            verifyResultsExp2Half3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExp2Half3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testExp2Half3Half3(inV, out);
+            verifyResultsExp2Half3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExp2Half3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsExp2Half3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeExp2(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkExp2Half3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkExp2Half4Half4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xe3e4fb34l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testExp2Half4Half4(inV, out);
+            verifyResultsExp2Half4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExp2Half4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testExp2Half4Half4(inV, out);
+            verifyResultsExp2Half4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExp2Half4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsExp2Half4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeExp2(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkExp2Half4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testExp2() {
         checkExp2FloatFloat();
         checkExp2Float2Float2();
         checkExp2Float3Float3();
         checkExp2Float4Float4();
+        checkExp2HalfHalf();
+        checkExp2Half2Half2();
+        checkExp2Half3Half3();
+        checkExp2Half4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExp2.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExp2.rs
index ef44e92..47007d4 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExp2.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExp2.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testExp2Float4Float4(float4 inV) {
     return exp2(inV);
 }
+
+half __attribute__((kernel)) testExp2HalfHalf(half inV) {
+    return exp2(inV);
+}
+
+half2 __attribute__((kernel)) testExp2Half2Half2(half2 inV) {
+    return exp2(inV);
+}
+
+half3 __attribute__((kernel)) testExp2Half3Half3(half3 inV) {
+    return exp2(inV);
+}
+
+half4 __attribute__((kernel)) testExp2Half4Half4(half4 inV) {
+    return exp2(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExp2Relaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExp2Relaxed.rs
index 2762dec..53dd864 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExp2Relaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExp2Relaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExpRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExpRelaxed.rs
index b0aeb3e..0971e78 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExpRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExpRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExpm1.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExpm1.java
index 6a1609f..e10b400 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExpm1.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExpm1.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeExpm1(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeExpm1(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeExpm1(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeExpm1(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkExpm1HalfHalf() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x45f98ceel, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testExpm1HalfHalf(inV, out);
+            verifyResultsExpm1HalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExpm1HalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testExpm1HalfHalf(inV, out);
+            verifyResultsExpm1HalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExpm1HalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsExpm1HalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeExpm1(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkExpm1HalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkExpm1Half2Half2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xea1f120l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testExpm1Half2Half2(inV, out);
+            verifyResultsExpm1Half2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExpm1Half2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testExpm1Half2Half2(inV, out);
+            verifyResultsExpm1Half2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExpm1Half2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsExpm1Half2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeExpm1(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkExpm1Half2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkExpm1Half3Half3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x6da9b614l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testExpm1Half3Half3(inV, out);
+            verifyResultsExpm1Half3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExpm1Half3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testExpm1Half3Half3(inV, out);
+            verifyResultsExpm1Half3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExpm1Half3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsExpm1Half3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeExpm1(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkExpm1Half3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkExpm1Half4Half4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xccb17b08l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testExpm1Half4Half4(inV, out);
+            verifyResultsExpm1Half4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExpm1Half4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testExpm1Half4Half4(inV, out);
+            verifyResultsExpm1Half4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExpm1Half4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsExpm1Half4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeExpm1(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkExpm1Half4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testExpm1() {
         checkExpm1FloatFloat();
         checkExpm1Float2Float2();
         checkExpm1Float3Float3();
         checkExpm1Float4Float4();
+        checkExpm1HalfHalf();
+        checkExpm1Half2Half2();
+        checkExpm1Half3Half3();
+        checkExpm1Half4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExpm1.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExpm1.rs
index 6cc0986..3b6f869 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExpm1.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExpm1.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testExpm1Float4Float4(float4 inV) {
     return expm1(inV);
 }
+
+half __attribute__((kernel)) testExpm1HalfHalf(half inV) {
+    return expm1(inV);
+}
+
+half2 __attribute__((kernel)) testExpm1Half2Half2(half2 inV) {
+    return expm1(inV);
+}
+
+half3 __attribute__((kernel)) testExpm1Half3Half3(half3 inV) {
+    return expm1(inV);
+}
+
+half4 __attribute__((kernel)) testExpm1Half4Half4(half4 inV) {
+    return expm1(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExpm1Relaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExpm1Relaxed.rs
index 2dfc6b3..caf0f9d 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExpm1Relaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExpm1Relaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFabs.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFabs.java
index 9303e7e..50d468b 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFabs.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFabs.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeFabs(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeFabs(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeFabs(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeFabs(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkFabsHalfHalf() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xe268991bl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testFabsHalfHalf(inV, out);
+            verifyResultsFabsHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFabsHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testFabsHalfHalf(inV, out);
+            verifyResultsFabsHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFabsHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFabsHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeFabs(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkFabsHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFabsHalf2Half2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xecb0e225l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testFabsHalf2Half2(inV, out);
+            verifyResultsFabsHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFabsHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testFabsHalf2Half2(inV, out);
+            verifyResultsFabsHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFabsHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFabsHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeFabs(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkFabsHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFabsHalf3Half3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x4bb8a719l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testFabsHalf3Half3(inV, out);
+            verifyResultsFabsHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFabsHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testFabsHalf3Half3(inV, out);
+            verifyResultsFabsHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFabsHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFabsHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeFabs(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkFabsHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFabsHalf4Half4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xaac06c0dl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testFabsHalf4Half4(inV, out);
+            verifyResultsFabsHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFabsHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testFabsHalf4Half4(inV, out);
+            verifyResultsFabsHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFabsHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFabsHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeFabs(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkFabsHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testFabs() {
         checkFabsFloatFloat();
         checkFabsFloat2Float2();
         checkFabsFloat3Float3();
         checkFabsFloat4Float4();
+        checkFabsHalfHalf();
+        checkFabsHalf2Half2();
+        checkFabsHalf3Half3();
+        checkFabsHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFabs.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFabs.rs
index 87d8b1e..6266b63 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFabs.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFabs.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testFabsFloat4Float4(float4 inV) {
     return fabs(inV);
 }
+
+half __attribute__((kernel)) testFabsHalfHalf(half inV) {
+    return fabs(inV);
+}
+
+half2 __attribute__((kernel)) testFabsHalf2Half2(half2 inV) {
+    return fabs(inV);
+}
+
+half3 __attribute__((kernel)) testFabsHalf3Half3(half3 inV) {
+    return fabs(inV);
+}
+
+half4 __attribute__((kernel)) testFabsHalf4Half4(half4 inV) {
+    return fabs(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFabsRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFabsRelaxed.rs
index a43e74d..0069908 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFabsRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFabsRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFastDistance.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFastDistance.java
index e10d5df..4c7a065 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFastDistance.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFastDistance.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -81,7 +82,7 @@
             // Fill args with the input values
             args.inLeftVector = arrayInLeftVector[i];
             args.inRightVector = arrayInRightVector[i];
-            Target target = new Target(relaxed);
+            Target target = new Target(Target.FunctionType.FAST, Target.ReturnType.FLOAT, relaxed);
             CoreMathVerifier.computeFastDistance(args, target);
 
             // Compare the expected outputs to the actual values returned by RS.
@@ -169,7 +170,7 @@
             for (int j = 0; j < 2 ; j++) {
                 args.inRightVector[j] = arrayInRightVector[i * 2 + j];
             }
-            Target target = new Target(relaxed);
+            Target target = new Target(Target.FunctionType.FAST, Target.ReturnType.FLOAT, relaxed);
             CoreMathVerifier.computeFastDistance(args, target);
 
             // Compare the expected outputs to the actual values returned by RS.
@@ -255,7 +256,7 @@
             for (int j = 0; j < 3 ; j++) {
                 args.inRightVector[j] = arrayInRightVector[i * 4 + j];
             }
-            Target target = new Target(relaxed);
+            Target target = new Target(Target.FunctionType.FAST, Target.ReturnType.FLOAT, relaxed);
             CoreMathVerifier.computeFastDistance(args, target);
 
             // Compare the expected outputs to the actual values returned by RS.
@@ -341,7 +342,7 @@
             for (int j = 0; j < 4 ; j++) {
                 args.inRightVector[j] = arrayInRightVector[i * 4 + j];
             }
-            Target target = new Target(relaxed);
+            Target target = new Target(Target.FunctionType.FAST, Target.ReturnType.FLOAT, relaxed);
             CoreMathVerifier.computeFastDistance(args, target);
 
             // Compare the expected outputs to the actual values returned by RS.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFastDistance.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFastDistance.rs
index 114523b..55f9b69 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFastDistance.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFastDistance.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFastDistanceRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFastDistanceRelaxed.rs
index cb52325..60b67d4 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFastDistanceRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFastDistanceRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFastLength.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFastLength.java
index b47adc9..e2cb9a9 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFastLength.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFastLength.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -73,7 +74,7 @@
             // Create the appropriate sized arrays in args
             // Fill args with the input values
             args.inV = arrayInV[i];
-            Target target = new Target(relaxed);
+            Target target = new Target(Target.FunctionType.FAST, Target.ReturnType.FLOAT, relaxed);
             CoreMathVerifier.computeFastLength(args, target);
 
             // Compare the expected outputs to the actual values returned by RS.
@@ -147,7 +148,7 @@
             for (int j = 0; j < 2 ; j++) {
                 args.inV[j] = arrayInV[i * 2 + j];
             }
-            Target target = new Target(relaxed);
+            Target target = new Target(Target.FunctionType.FAST, Target.ReturnType.FLOAT, relaxed);
             CoreMathVerifier.computeFastLength(args, target);
 
             // Compare the expected outputs to the actual values returned by RS.
@@ -218,7 +219,7 @@
             for (int j = 0; j < 3 ; j++) {
                 args.inV[j] = arrayInV[i * 4 + j];
             }
-            Target target = new Target(relaxed);
+            Target target = new Target(Target.FunctionType.FAST, Target.ReturnType.FLOAT, relaxed);
             CoreMathVerifier.computeFastLength(args, target);
 
             // Compare the expected outputs to the actual values returned by RS.
@@ -289,7 +290,7 @@
             for (int j = 0; j < 4 ; j++) {
                 args.inV[j] = arrayInV[i * 4 + j];
             }
-            Target target = new Target(relaxed);
+            Target target = new Target(Target.FunctionType.FAST, Target.ReturnType.FLOAT, relaxed);
             CoreMathVerifier.computeFastLength(args, target);
 
             // Compare the expected outputs to the actual values returned by RS.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFastLength.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFastLength.rs
index 46619d7..dfd3ce5 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFastLength.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFastLength.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFastLengthRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFastLengthRelaxed.rs
index d85126a..a7b92f4 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFastLengthRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFastLengthRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFastNormalize.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFastNormalize.java
index 2c3ac1a..31193e7 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFastNormalize.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFastNormalize.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -73,7 +74,7 @@
             // Create the appropriate sized arrays in args
             // Fill args with the input values
             args.inV = arrayInV[i];
-            Target target = new Target(relaxed);
+            Target target = new Target(Target.FunctionType.FAST, Target.ReturnType.FLOAT, relaxed);
             CoreMathVerifier.computeFastNormalize(args, target);
 
             // Compare the expected outputs to the actual values returned by RS.
@@ -148,7 +149,7 @@
             for (int j = 0; j < 2 ; j++) {
                 args.inV[j] = arrayInV[i * 2 + j];
             }
-            Target target = new Target(relaxed);
+            Target target = new Target(Target.FunctionType.FAST, Target.ReturnType.FLOAT, relaxed);
             CoreMathVerifier.computeFastNormalize(args, target);
 
             // Compare the expected outputs to the actual values returned by RS.
@@ -224,7 +225,7 @@
             for (int j = 0; j < 3 ; j++) {
                 args.inV[j] = arrayInV[i * 4 + j];
             }
-            Target target = new Target(relaxed);
+            Target target = new Target(Target.FunctionType.FAST, Target.ReturnType.FLOAT, relaxed);
             CoreMathVerifier.computeFastNormalize(args, target);
 
             // Compare the expected outputs to the actual values returned by RS.
@@ -300,7 +301,7 @@
             for (int j = 0; j < 4 ; j++) {
                 args.inV[j] = arrayInV[i * 4 + j];
             }
-            Target target = new Target(relaxed);
+            Target target = new Target(Target.FunctionType.FAST, Target.ReturnType.FLOAT, relaxed);
             CoreMathVerifier.computeFastNormalize(args, target);
 
             // Compare the expected outputs to the actual values returned by RS.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFastNormalize.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFastNormalize.rs
index e5f009c..857dced 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFastNormalize.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFastNormalize.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFastNormalizeRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFastNormalizeRelaxed.rs
index e8549e3..93f85a8 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFastNormalizeRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFastNormalizeRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFdim.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFdim.java
index c817296..ed9ed1e 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFdim.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFdim.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -82,7 +83,7 @@
                 args.inA = arrayInA[i];
                 args.inB = arrayInB[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeFdim(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -161,7 +162,7 @@
                 args.inA = arrayInA[i * 2 + j];
                 args.inB = arrayInB[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeFdim(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -240,7 +241,7 @@
                 args.inA = arrayInA[i * 4 + j];
                 args.inB = arrayInB[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeFdim(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -319,7 +320,7 @@
                 args.inA = arrayInA[i * 4 + j];
                 args.inB = arrayInB[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeFdim(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -358,10 +359,358 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalfHalf {
+        public short inA;
+        public double inADouble;
+        public short inB;
+        public double inBDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkFdimHalfHalfHalf() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x3357407dl, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x3357407el, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testFdimHalfHalfHalf(inA, out);
+            verifyResultsFdimHalfHalfHalf(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFdimHalfHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testFdimHalfHalfHalf(inA, out);
+            verifyResultsFdimHalfHalfHalf(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFdimHalfHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFdimHalfHalfHalf(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        short[] arrayInA = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInA, (short) 42);
+        inA.copyTo(arrayInA);
+        short[] arrayInB = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInB, (short) 42);
+        inB.copyTo(arrayInB);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inA = arrayInA[i];
+                args.inADouble = Float16Utils.convertFloat16ToDouble(args.inA);
+                args.inB = arrayInB[i];
+                args.inBDouble = Float16Utils.convertFloat16ToDouble(args.inB);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeFdim(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inA: ");
+                        appendVariableToMessage(message, args.inA);
+                        message.append("\n");
+                        message.append("Input inB: ");
+                        appendVariableToMessage(message, args.inB);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkFdimHalfHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFdimHalf2Half2Half2() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xfa8ab75bl, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xfa8ab75cl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testFdimHalf2Half2Half2(inA, out);
+            verifyResultsFdimHalf2Half2Half2(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFdimHalf2Half2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testFdimHalf2Half2Half2(inA, out);
+            verifyResultsFdimHalf2Half2Half2(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFdimHalf2Half2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFdimHalf2Half2Half2(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        short[] arrayInA = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInA, (short) 42);
+        inA.copyTo(arrayInA);
+        short[] arrayInB = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInB, (short) 42);
+        inB.copyTo(arrayInB);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inA = arrayInA[i * 2 + j];
+                args.inADouble = Float16Utils.convertFloat16ToDouble(args.inA);
+                args.inB = arrayInB[i * 2 + j];
+                args.inBDouble = Float16Utils.convertFloat16ToDouble(args.inB);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeFdim(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inA: ");
+                        appendVariableToMessage(message, args.inA);
+                        message.append("\n");
+                        message.append("Input inB: ");
+                        appendVariableToMessage(message, args.inB);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkFdimHalf2Half2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFdimHalf3Half3Half3() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x5929c82al, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x5929c82bl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testFdimHalf3Half3Half3(inA, out);
+            verifyResultsFdimHalf3Half3Half3(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFdimHalf3Half3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testFdimHalf3Half3Half3(inA, out);
+            verifyResultsFdimHalf3Half3Half3(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFdimHalf3Half3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFdimHalf3Half3Half3(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        short[] arrayInA = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInA, (short) 42);
+        inA.copyTo(arrayInA);
+        short[] arrayInB = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInB, (short) 42);
+        inB.copyTo(arrayInB);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inA = arrayInA[i * 4 + j];
+                args.inADouble = Float16Utils.convertFloat16ToDouble(args.inA);
+                args.inB = arrayInB[i * 4 + j];
+                args.inBDouble = Float16Utils.convertFloat16ToDouble(args.inB);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeFdim(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inA: ");
+                        appendVariableToMessage(message, args.inA);
+                        message.append("\n");
+                        message.append("Input inB: ");
+                        appendVariableToMessage(message, args.inB);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkFdimHalf3Half3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFdimHalf4Half4Half4() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xb7c8d8f9l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xb7c8d8fal, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testFdimHalf4Half4Half4(inA, out);
+            verifyResultsFdimHalf4Half4Half4(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFdimHalf4Half4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testFdimHalf4Half4Half4(inA, out);
+            verifyResultsFdimHalf4Half4Half4(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFdimHalf4Half4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFdimHalf4Half4Half4(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        short[] arrayInA = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInA, (short) 42);
+        inA.copyTo(arrayInA);
+        short[] arrayInB = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInB, (short) 42);
+        inB.copyTo(arrayInB);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inA = arrayInA[i * 4 + j];
+                args.inADouble = Float16Utils.convertFloat16ToDouble(args.inA);
+                args.inB = arrayInB[i * 4 + j];
+                args.inBDouble = Float16Utils.convertFloat16ToDouble(args.inB);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeFdim(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inA: ");
+                        appendVariableToMessage(message, args.inA);
+                        message.append("\n");
+                        message.append("Input inB: ");
+                        appendVariableToMessage(message, args.inB);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkFdimHalf4Half4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testFdim() {
         checkFdimFloatFloatFloat();
         checkFdimFloat2Float2Float2();
         checkFdimFloat3Float3Float3();
         checkFdimFloat4Float4Float4();
+        checkFdimHalfHalfHalf();
+        checkFdimHalf2Half2Half2();
+        checkFdimHalf3Half3Half3();
+        checkFdimHalf4Half4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFdim.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFdim.rs
index e93485c..f9c8852 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFdim.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFdim.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -40,3 +40,23 @@
     float4 inB = rsGetElementAt_float4(gAllocInB, x);
     return fdim(inA, inB);
 }
+
+half __attribute__((kernel)) testFdimHalfHalfHalf(half inA, unsigned int x) {
+    half inB = rsGetElementAt_half(gAllocInB, x);
+    return fdim(inA, inB);
+}
+
+half2 __attribute__((kernel)) testFdimHalf2Half2Half2(half2 inA, unsigned int x) {
+    half2 inB = rsGetElementAt_half2(gAllocInB, x);
+    return fdim(inA, inB);
+}
+
+half3 __attribute__((kernel)) testFdimHalf3Half3Half3(half3 inA, unsigned int x) {
+    half3 inB = rsGetElementAt_half3(gAllocInB, x);
+    return fdim(inA, inB);
+}
+
+half4 __attribute__((kernel)) testFdimHalf4Half4Half4(half4 inA, unsigned int x) {
+    half4 inB = rsGetElementAt_half4(gAllocInB, x);
+    return fdim(inA, inB);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFdimRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFdimRelaxed.rs
index caa61eb..22b63e9 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFdimRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFdimRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFloor.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFloor.java
index 0ebc227..35238b3 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFloor.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFloor.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeFloor(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeFloor(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeFloor(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeFloor(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkFloorHalfHalf() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x56dc16ffl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testFloorHalfHalf(inV, out);
+            verifyResultsFloorHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFloorHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testFloorHalfHalf(inV, out);
+            verifyResultsFloorHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFloorHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFloorHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeFloor(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkFloorHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFloorHalf2Half2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x2d925e9l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testFloorHalf2Half2(inV, out);
+            verifyResultsFloorHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFloorHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testFloorHalf2Half2(inV, out);
+            verifyResultsFloorHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFloorHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFloorHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeFloor(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkFloorHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFloorHalf3Half3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x61e0eaddl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testFloorHalf3Half3(inV, out);
+            verifyResultsFloorHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFloorHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testFloorHalf3Half3(inV, out);
+            verifyResultsFloorHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFloorHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFloorHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeFloor(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkFloorHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFloorHalf4Half4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xc0e8afd1l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testFloorHalf4Half4(inV, out);
+            verifyResultsFloorHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFloorHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testFloorHalf4Half4(inV, out);
+            verifyResultsFloorHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFloorHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFloorHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeFloor(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkFloorHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testFloor() {
         checkFloorFloatFloat();
         checkFloorFloat2Float2();
         checkFloorFloat3Float3();
         checkFloorFloat4Float4();
+        checkFloorHalfHalf();
+        checkFloorHalf2Half2();
+        checkFloorHalf3Half3();
+        checkFloorHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFloor.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFloor.rs
index 94dc5a6..def706d 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFloor.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFloor.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testFloorFloat4Float4(float4 inV) {
     return floor(inV);
 }
+
+half __attribute__((kernel)) testFloorHalfHalf(half inV) {
+    return floor(inV);
+}
+
+half2 __attribute__((kernel)) testFloorHalf2Half2(half2 inV) {
+    return floor(inV);
+}
+
+half3 __attribute__((kernel)) testFloorHalf3Half3(half3 inV) {
+    return floor(inV);
+}
+
+half4 __attribute__((kernel)) testFloorHalf4Half4(half4 inV) {
+    return floor(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFloorRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFloorRelaxed.rs
index 6b5b69d..95f6bfb 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFloorRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFloorRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFma.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFma.java
index f5f30b3..80d387b 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFma.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFma.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -90,7 +91,7 @@
                 args.inMultiplicand2 = arrayInMultiplicand2[i];
                 args.inOffset = arrayInOffset[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeFma(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -179,7 +180,7 @@
                 args.inMultiplicand2 = arrayInMultiplicand2[i * 2 + j];
                 args.inOffset = arrayInOffset[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeFma(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -268,7 +269,7 @@
                 args.inMultiplicand2 = arrayInMultiplicand2[i * 4 + j];
                 args.inOffset = arrayInOffset[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeFma(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -357,7 +358,7 @@
                 args.inMultiplicand2 = arrayInMultiplicand2[i * 4 + j];
                 args.inOffset = arrayInOffset[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeFma(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -399,10 +400,404 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalfHalfHalf {
+        public short inMultiplicand1;
+        public double inMultiplicand1Double;
+        public short inMultiplicand2;
+        public double inMultiplicand2Double;
+        public short inOffset;
+        public double inOffsetDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkFmaHalfHalfHalfHalf() {
+        Allocation inMultiplicand1 = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xd7c6a182l, false);
+        Allocation inMultiplicand2 = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xd7c6a183l, false);
+        Allocation inOffset = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x663f87al, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.set_gAllocInMultiplicand2(inMultiplicand2);
+            script.set_gAllocInOffset(inOffset);
+            script.forEach_testFmaHalfHalfHalfHalf(inMultiplicand1, out);
+            verifyResultsFmaHalfHalfHalfHalf(inMultiplicand1, inMultiplicand2, inOffset, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaHalfHalfHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMultiplicand2(inMultiplicand2);
+            scriptRelaxed.set_gAllocInOffset(inOffset);
+            scriptRelaxed.forEach_testFmaHalfHalfHalfHalf(inMultiplicand1, out);
+            verifyResultsFmaHalfHalfHalfHalf(inMultiplicand1, inMultiplicand2, inOffset, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaHalfHalfHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFmaHalfHalfHalfHalf(Allocation inMultiplicand1, Allocation inMultiplicand2, Allocation inOffset, Allocation out, boolean relaxed) {
+        short[] arrayInMultiplicand1 = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInMultiplicand1, (short) 42);
+        inMultiplicand1.copyTo(arrayInMultiplicand1);
+        short[] arrayInMultiplicand2 = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInMultiplicand2, (short) 42);
+        inMultiplicand2.copyTo(arrayInMultiplicand2);
+        short[] arrayInOffset = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInOffset, (short) 42);
+        inOffset.copyTo(arrayInOffset);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalfHalf args = new ArgumentsHalfHalfHalfHalf();
+                args.inMultiplicand1 = arrayInMultiplicand1[i];
+                args.inMultiplicand1Double = Float16Utils.convertFloat16ToDouble(args.inMultiplicand1);
+                args.inMultiplicand2 = arrayInMultiplicand2[i];
+                args.inMultiplicand2Double = Float16Utils.convertFloat16ToDouble(args.inMultiplicand2);
+                args.inOffset = arrayInOffset[i];
+                args.inOffsetDouble = Float16Utils.convertFloat16ToDouble(args.inOffset);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeFma(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inMultiplicand1: ");
+                        appendVariableToMessage(message, args.inMultiplicand1);
+                        message.append("\n");
+                        message.append("Input inMultiplicand2: ");
+                        appendVariableToMessage(message, args.inMultiplicand2);
+                        message.append("\n");
+                        message.append("Input inOffset: ");
+                        appendVariableToMessage(message, args.inOffset);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkFmaHalfHalfHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFmaHalf2Half2Half2Half2() {
+        Allocation inMultiplicand1 = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x2f0bb556l, false);
+        Allocation inMultiplicand2 = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x2f0bb557l, false);
+        Allocation inOffset = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xb6e9fa96l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.set_gAllocInMultiplicand2(inMultiplicand2);
+            script.set_gAllocInOffset(inOffset);
+            script.forEach_testFmaHalf2Half2Half2Half2(inMultiplicand1, out);
+            verifyResultsFmaHalf2Half2Half2Half2(inMultiplicand1, inMultiplicand2, inOffset, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaHalf2Half2Half2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMultiplicand2(inMultiplicand2);
+            scriptRelaxed.set_gAllocInOffset(inOffset);
+            scriptRelaxed.forEach_testFmaHalf2Half2Half2Half2(inMultiplicand1, out);
+            verifyResultsFmaHalf2Half2Half2Half2(inMultiplicand1, inMultiplicand2, inOffset, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaHalf2Half2Half2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFmaHalf2Half2Half2Half2(Allocation inMultiplicand1, Allocation inMultiplicand2, Allocation inOffset, Allocation out, boolean relaxed) {
+        short[] arrayInMultiplicand1 = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInMultiplicand1, (short) 42);
+        inMultiplicand1.copyTo(arrayInMultiplicand1);
+        short[] arrayInMultiplicand2 = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInMultiplicand2, (short) 42);
+        inMultiplicand2.copyTo(arrayInMultiplicand2);
+        short[] arrayInOffset = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInOffset, (short) 42);
+        inOffset.copyTo(arrayInOffset);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalfHalf args = new ArgumentsHalfHalfHalfHalf();
+                args.inMultiplicand1 = arrayInMultiplicand1[i * 2 + j];
+                args.inMultiplicand1Double = Float16Utils.convertFloat16ToDouble(args.inMultiplicand1);
+                args.inMultiplicand2 = arrayInMultiplicand2[i * 2 + j];
+                args.inMultiplicand2Double = Float16Utils.convertFloat16ToDouble(args.inMultiplicand2);
+                args.inOffset = arrayInOffset[i * 2 + j];
+                args.inOffsetDouble = Float16Utils.convertFloat16ToDouble(args.inOffset);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeFma(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inMultiplicand1: ");
+                        appendVariableToMessage(message, args.inMultiplicand1);
+                        message.append("\n");
+                        message.append("Input inMultiplicand2: ");
+                        appendVariableToMessage(message, args.inMultiplicand2);
+                        message.append("\n");
+                        message.append("Input inOffset: ");
+                        appendVariableToMessage(message, args.inOffset);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkFmaHalf2Half2Half2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFmaHalf3Half3Half3Half3() {
+        Allocation inMultiplicand1 = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x1a5f3c9el, false);
+        Allocation inMultiplicand2 = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x1a5f3c9fl, false);
+        Allocation inOffset = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x1b05aael, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.set_gAllocInMultiplicand2(inMultiplicand2);
+            script.set_gAllocInOffset(inOffset);
+            script.forEach_testFmaHalf3Half3Half3Half3(inMultiplicand1, out);
+            verifyResultsFmaHalf3Half3Half3Half3(inMultiplicand1, inMultiplicand2, inOffset, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaHalf3Half3Half3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMultiplicand2(inMultiplicand2);
+            scriptRelaxed.set_gAllocInOffset(inOffset);
+            scriptRelaxed.forEach_testFmaHalf3Half3Half3Half3(inMultiplicand1, out);
+            verifyResultsFmaHalf3Half3Half3Half3(inMultiplicand1, inMultiplicand2, inOffset, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaHalf3Half3Half3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFmaHalf3Half3Half3Half3(Allocation inMultiplicand1, Allocation inMultiplicand2, Allocation inOffset, Allocation out, boolean relaxed) {
+        short[] arrayInMultiplicand1 = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInMultiplicand1, (short) 42);
+        inMultiplicand1.copyTo(arrayInMultiplicand1);
+        short[] arrayInMultiplicand2 = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInMultiplicand2, (short) 42);
+        inMultiplicand2.copyTo(arrayInMultiplicand2);
+        short[] arrayInOffset = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInOffset, (short) 42);
+        inOffset.copyTo(arrayInOffset);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalfHalf args = new ArgumentsHalfHalfHalfHalf();
+                args.inMultiplicand1 = arrayInMultiplicand1[i * 4 + j];
+                args.inMultiplicand1Double = Float16Utils.convertFloat16ToDouble(args.inMultiplicand1);
+                args.inMultiplicand2 = arrayInMultiplicand2[i * 4 + j];
+                args.inMultiplicand2Double = Float16Utils.convertFloat16ToDouble(args.inMultiplicand2);
+                args.inOffset = arrayInOffset[i * 4 + j];
+                args.inOffsetDouble = Float16Utils.convertFloat16ToDouble(args.inOffset);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeFma(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inMultiplicand1: ");
+                        appendVariableToMessage(message, args.inMultiplicand1);
+                        message.append("\n");
+                        message.append("Input inMultiplicand2: ");
+                        appendVariableToMessage(message, args.inMultiplicand2);
+                        message.append("\n");
+                        message.append("Input inOffset: ");
+                        appendVariableToMessage(message, args.inOffset);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkFmaHalf3Half3Half3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFmaHalf4Half4Half4Half4() {
+        Allocation inMultiplicand1 = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x5b2c3e6l, false);
+        Allocation inMultiplicand2 = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x5b2c3e7l, false);
+        Allocation inOffset = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x4c76bac6l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.set_gAllocInMultiplicand2(inMultiplicand2);
+            script.set_gAllocInOffset(inOffset);
+            script.forEach_testFmaHalf4Half4Half4Half4(inMultiplicand1, out);
+            verifyResultsFmaHalf4Half4Half4Half4(inMultiplicand1, inMultiplicand2, inOffset, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaHalf4Half4Half4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMultiplicand2(inMultiplicand2);
+            scriptRelaxed.set_gAllocInOffset(inOffset);
+            scriptRelaxed.forEach_testFmaHalf4Half4Half4Half4(inMultiplicand1, out);
+            verifyResultsFmaHalf4Half4Half4Half4(inMultiplicand1, inMultiplicand2, inOffset, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaHalf4Half4Half4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFmaHalf4Half4Half4Half4(Allocation inMultiplicand1, Allocation inMultiplicand2, Allocation inOffset, Allocation out, boolean relaxed) {
+        short[] arrayInMultiplicand1 = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInMultiplicand1, (short) 42);
+        inMultiplicand1.copyTo(arrayInMultiplicand1);
+        short[] arrayInMultiplicand2 = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInMultiplicand2, (short) 42);
+        inMultiplicand2.copyTo(arrayInMultiplicand2);
+        short[] arrayInOffset = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInOffset, (short) 42);
+        inOffset.copyTo(arrayInOffset);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalfHalf args = new ArgumentsHalfHalfHalfHalf();
+                args.inMultiplicand1 = arrayInMultiplicand1[i * 4 + j];
+                args.inMultiplicand1Double = Float16Utils.convertFloat16ToDouble(args.inMultiplicand1);
+                args.inMultiplicand2 = arrayInMultiplicand2[i * 4 + j];
+                args.inMultiplicand2Double = Float16Utils.convertFloat16ToDouble(args.inMultiplicand2);
+                args.inOffset = arrayInOffset[i * 4 + j];
+                args.inOffsetDouble = Float16Utils.convertFloat16ToDouble(args.inOffset);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeFma(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inMultiplicand1: ");
+                        appendVariableToMessage(message, args.inMultiplicand1);
+                        message.append("\n");
+                        message.append("Input inMultiplicand2: ");
+                        appendVariableToMessage(message, args.inMultiplicand2);
+                        message.append("\n");
+                        message.append("Input inOffset: ");
+                        appendVariableToMessage(message, args.inOffset);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkFmaHalf4Half4Half4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testFma() {
         checkFmaFloatFloatFloatFloat();
         checkFmaFloat2Float2Float2Float2();
         checkFmaFloat3Float3Float3Float3();
         checkFmaFloat4Float4Float4Float4();
+        checkFmaHalfHalfHalfHalf();
+        checkFmaHalf2Half2Half2Half2();
+        checkFmaHalf3Half3Half3Half3();
+        checkFmaHalf4Half4Half4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFma.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFma.rs
index 1b720c1..9ddeb76 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFma.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFma.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -45,3 +45,27 @@
     float4 inOffset = rsGetElementAt_float4(gAllocInOffset, x);
     return fma(inMultiplicand1, inMultiplicand2, inOffset);
 }
+
+half __attribute__((kernel)) testFmaHalfHalfHalfHalf(half inMultiplicand1, unsigned int x) {
+    half inMultiplicand2 = rsGetElementAt_half(gAllocInMultiplicand2, x);
+    half inOffset = rsGetElementAt_half(gAllocInOffset, x);
+    return fma(inMultiplicand1, inMultiplicand2, inOffset);
+}
+
+half2 __attribute__((kernel)) testFmaHalf2Half2Half2Half2(half2 inMultiplicand1, unsigned int x) {
+    half2 inMultiplicand2 = rsGetElementAt_half2(gAllocInMultiplicand2, x);
+    half2 inOffset = rsGetElementAt_half2(gAllocInOffset, x);
+    return fma(inMultiplicand1, inMultiplicand2, inOffset);
+}
+
+half3 __attribute__((kernel)) testFmaHalf3Half3Half3Half3(half3 inMultiplicand1, unsigned int x) {
+    half3 inMultiplicand2 = rsGetElementAt_half3(gAllocInMultiplicand2, x);
+    half3 inOffset = rsGetElementAt_half3(gAllocInOffset, x);
+    return fma(inMultiplicand1, inMultiplicand2, inOffset);
+}
+
+half4 __attribute__((kernel)) testFmaHalf4Half4Half4Half4(half4 inMultiplicand1, unsigned int x) {
+    half4 inMultiplicand2 = rsGetElementAt_half4(gAllocInMultiplicand2, x);
+    half4 inOffset = rsGetElementAt_half4(gAllocInOffset, x);
+    return fma(inMultiplicand1, inMultiplicand2, inOffset);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFmaRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFmaRelaxed.rs
index 723cbd6..879f4da 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFmaRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFmaRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFmax.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFmax.java
index 56ea3d9..b370652 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFmax.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFmax.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -82,7 +83,7 @@
                 args.inA = arrayInA[i];
                 args.inB = arrayInB[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeFmax(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -161,7 +162,7 @@
                 args.inA = arrayInA[i * 2 + j];
                 args.inB = arrayInB[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeFmax(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -240,7 +241,7 @@
                 args.inA = arrayInA[i * 4 + j];
                 args.inB = arrayInB[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeFmax(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -319,7 +320,7 @@
                 args.inA = arrayInA[i * 4 + j];
                 args.inB = arrayInB[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeFmax(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -358,6 +359,350 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalfHalf {
+        public short inA;
+        public double inADouble;
+        public short inB;
+        public double inBDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkFmaxHalfHalfHalf() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x6dad4699l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x6dad469al, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testFmaxHalfHalfHalf(inA, out);
+            verifyResultsFmaxHalfHalfHalf(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaxHalfHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testFmaxHalfHalfHalf(inA, out);
+            verifyResultsFmaxHalfHalfHalf(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaxHalfHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFmaxHalfHalfHalf(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        short[] arrayInA = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInA, (short) 42);
+        inA.copyTo(arrayInA);
+        short[] arrayInB = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInB, (short) 42);
+        inB.copyTo(arrayInB);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inA = arrayInA[i];
+                args.inADouble = Float16Utils.convertFloat16ToDouble(args.inA);
+                args.inB = arrayInB[i];
+                args.inBDouble = Float16Utils.convertFloat16ToDouble(args.inB);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeFmax(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inA: ");
+                        appendVariableToMessage(message, args.inA);
+                        message.append("\n");
+                        message.append("Input inB: ");
+                        appendVariableToMessage(message, args.inB);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkFmaxHalfHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFmaxHalf2Half2Half2() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xa556216fl, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xa5562170l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testFmaxHalf2Half2Half2(inA, out);
+            verifyResultsFmaxHalf2Half2Half2(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaxHalf2Half2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testFmaxHalf2Half2Half2(inA, out);
+            verifyResultsFmaxHalf2Half2Half2(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaxHalf2Half2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFmaxHalf2Half2Half2(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        short[] arrayInA = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInA, (short) 42);
+        inA.copyTo(arrayInA);
+        short[] arrayInB = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInB, (short) 42);
+        inB.copyTo(arrayInB);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inA = arrayInA[i * 2 + j];
+                args.inADouble = Float16Utils.convertFloat16ToDouble(args.inA);
+                args.inB = arrayInB[i * 2 + j];
+                args.inBDouble = Float16Utils.convertFloat16ToDouble(args.inB);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeFmax(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inA: ");
+                        appendVariableToMessage(message, args.inA);
+                        message.append("\n");
+                        message.append("Input inB: ");
+                        appendVariableToMessage(message, args.inB);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkFmaxHalf2Half2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFmaxHalf3Half3Half3() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x3f5323el, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x3f5323fl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testFmaxHalf3Half3Half3(inA, out);
+            verifyResultsFmaxHalf3Half3Half3(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaxHalf3Half3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testFmaxHalf3Half3Half3(inA, out);
+            verifyResultsFmaxHalf3Half3Half3(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaxHalf3Half3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFmaxHalf3Half3Half3(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        short[] arrayInA = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInA, (short) 42);
+        inA.copyTo(arrayInA);
+        short[] arrayInB = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInB, (short) 42);
+        inB.copyTo(arrayInB);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inA = arrayInA[i * 4 + j];
+                args.inADouble = Float16Utils.convertFloat16ToDouble(args.inA);
+                args.inB = arrayInB[i * 4 + j];
+                args.inBDouble = Float16Utils.convertFloat16ToDouble(args.inB);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeFmax(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inA: ");
+                        appendVariableToMessage(message, args.inA);
+                        message.append("\n");
+                        message.append("Input inB: ");
+                        appendVariableToMessage(message, args.inB);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkFmaxHalf3Half3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFmaxHalf4Half4Half4() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x6294430dl, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x6294430el, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testFmaxHalf4Half4Half4(inA, out);
+            verifyResultsFmaxHalf4Half4Half4(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaxHalf4Half4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testFmaxHalf4Half4Half4(inA, out);
+            verifyResultsFmaxHalf4Half4Half4(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaxHalf4Half4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFmaxHalf4Half4Half4(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        short[] arrayInA = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInA, (short) 42);
+        inA.copyTo(arrayInA);
+        short[] arrayInB = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInB, (short) 42);
+        inB.copyTo(arrayInB);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inA = arrayInA[i * 4 + j];
+                args.inADouble = Float16Utils.convertFloat16ToDouble(args.inA);
+                args.inB = arrayInB[i * 4 + j];
+                args.inBDouble = Float16Utils.convertFloat16ToDouble(args.inB);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeFmax(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inA: ");
+                        appendVariableToMessage(message, args.inA);
+                        message.append("\n");
+                        message.append("Input inB: ");
+                        appendVariableToMessage(message, args.inB);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkFmaxHalf4Half4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     private void checkFmaxFloat2FloatFloat2() {
         Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xdc631102l, false);
         Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xdc631103l, false);
@@ -398,7 +743,7 @@
                 args.inA = arrayInA[i * 2 + j];
                 args.inB = arrayInB[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeFmax(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -477,7 +822,7 @@
                 args.inA = arrayInA[i * 4 + j];
                 args.inB = arrayInB[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeFmax(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -556,7 +901,7 @@
                 args.inA = arrayInA[i * 4 + j];
                 args.inB = arrayInB[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeFmax(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -595,13 +940,272 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    private void checkFmaxHalf2HalfHalf2() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x3546cdbdl, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x3546cdbel, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testFmaxHalf2HalfHalf2(inA, out);
+            verifyResultsFmaxHalf2HalfHalf2(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaxHalf2HalfHalf2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testFmaxHalf2HalfHalf2(inA, out);
+            verifyResultsFmaxHalf2HalfHalf2(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaxHalf2HalfHalf2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFmaxHalf2HalfHalf2(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        short[] arrayInA = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInA, (short) 42);
+        inA.copyTo(arrayInA);
+        short[] arrayInB = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInB, (short) 42);
+        inB.copyTo(arrayInB);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inA = arrayInA[i * 2 + j];
+                args.inADouble = Float16Utils.convertFloat16ToDouble(args.inA);
+                args.inB = arrayInB[i];
+                args.inBDouble = Float16Utils.convertFloat16ToDouble(args.inB);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeFmax(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inA: ");
+                        appendVariableToMessage(message, args.inA);
+                        message.append("\n");
+                        message.append("Input inB: ");
+                        appendVariableToMessage(message, args.inB);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkFmaxHalf2HalfHalf2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFmaxHalf3HalfHalf3() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0xe7e05f61l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xe7e05f62l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testFmaxHalf3HalfHalf3(inA, out);
+            verifyResultsFmaxHalf3HalfHalf3(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaxHalf3HalfHalf3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testFmaxHalf3HalfHalf3(inA, out);
+            verifyResultsFmaxHalf3HalfHalf3(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaxHalf3HalfHalf3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFmaxHalf3HalfHalf3(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        short[] arrayInA = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInA, (short) 42);
+        inA.copyTo(arrayInA);
+        short[] arrayInB = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInB, (short) 42);
+        inB.copyTo(arrayInB);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inA = arrayInA[i * 4 + j];
+                args.inADouble = Float16Utils.convertFloat16ToDouble(args.inA);
+                args.inB = arrayInB[i];
+                args.inBDouble = Float16Utils.convertFloat16ToDouble(args.inB);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeFmax(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inA: ");
+                        appendVariableToMessage(message, args.inA);
+                        message.append("\n");
+                        message.append("Input inB: ");
+                        appendVariableToMessage(message, args.inB);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkFmaxHalf3HalfHalf3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFmaxHalf4HalfHalf4() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x9a79f105l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x9a79f106l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testFmaxHalf4HalfHalf4(inA, out);
+            verifyResultsFmaxHalf4HalfHalf4(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaxHalf4HalfHalf4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testFmaxHalf4HalfHalf4(inA, out);
+            verifyResultsFmaxHalf4HalfHalf4(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaxHalf4HalfHalf4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFmaxHalf4HalfHalf4(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        short[] arrayInA = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInA, (short) 42);
+        inA.copyTo(arrayInA);
+        short[] arrayInB = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInB, (short) 42);
+        inB.copyTo(arrayInB);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inA = arrayInA[i * 4 + j];
+                args.inADouble = Float16Utils.convertFloat16ToDouble(args.inA);
+                args.inB = arrayInB[i];
+                args.inBDouble = Float16Utils.convertFloat16ToDouble(args.inB);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeFmax(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inA: ");
+                        appendVariableToMessage(message, args.inA);
+                        message.append("\n");
+                        message.append("Input inB: ");
+                        appendVariableToMessage(message, args.inB);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkFmaxHalf4HalfHalf4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testFmax() {
         checkFmaxFloatFloatFloat();
         checkFmaxFloat2Float2Float2();
         checkFmaxFloat3Float3Float3();
         checkFmaxFloat4Float4Float4();
+        checkFmaxHalfHalfHalf();
+        checkFmaxHalf2Half2Half2();
+        checkFmaxHalf3Half3Half3();
+        checkFmaxHalf4Half4Half4();
         checkFmaxFloat2FloatFloat2();
         checkFmaxFloat3FloatFloat3();
         checkFmaxFloat4FloatFloat4();
+        checkFmaxHalf2HalfHalf2();
+        checkFmaxHalf3HalfHalf3();
+        checkFmaxHalf4HalfHalf4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFmax.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFmax.rs
index 418c5c1..9e4ae5b 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFmax.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFmax.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -41,6 +41,26 @@
     return fmax(inA, inB);
 }
 
+half __attribute__((kernel)) testFmaxHalfHalfHalf(half inA, unsigned int x) {
+    half inB = rsGetElementAt_half(gAllocInB, x);
+    return fmax(inA, inB);
+}
+
+half2 __attribute__((kernel)) testFmaxHalf2Half2Half2(half2 inA, unsigned int x) {
+    half2 inB = rsGetElementAt_half2(gAllocInB, x);
+    return fmax(inA, inB);
+}
+
+half3 __attribute__((kernel)) testFmaxHalf3Half3Half3(half3 inA, unsigned int x) {
+    half3 inB = rsGetElementAt_half3(gAllocInB, x);
+    return fmax(inA, inB);
+}
+
+half4 __attribute__((kernel)) testFmaxHalf4Half4Half4(half4 inA, unsigned int x) {
+    half4 inB = rsGetElementAt_half4(gAllocInB, x);
+    return fmax(inA, inB);
+}
+
 float2 __attribute__((kernel)) testFmaxFloat2FloatFloat2(float2 inA, unsigned int x) {
     float inB = rsGetElementAt_float(gAllocInB, x);
     return fmax(inA, inB);
@@ -55,3 +75,18 @@
     float inB = rsGetElementAt_float(gAllocInB, x);
     return fmax(inA, inB);
 }
+
+half2 __attribute__((kernel)) testFmaxHalf2HalfHalf2(half2 inA, unsigned int x) {
+    half inB = rsGetElementAt_half(gAllocInB, x);
+    return fmax(inA, inB);
+}
+
+half3 __attribute__((kernel)) testFmaxHalf3HalfHalf3(half3 inA, unsigned int x) {
+    half inB = rsGetElementAt_half(gAllocInB, x);
+    return fmax(inA, inB);
+}
+
+half4 __attribute__((kernel)) testFmaxHalf4HalfHalf4(half4 inA, unsigned int x) {
+    half inB = rsGetElementAt_half(gAllocInB, x);
+    return fmax(inA, inB);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFmaxRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFmaxRelaxed.rs
index e0a124b..bf2d071 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFmaxRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFmaxRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFmin.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFmin.java
index c96daa4..8b81c47 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFmin.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFmin.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -82,7 +83,7 @@
                 args.inA = arrayInA[i];
                 args.inB = arrayInB[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeFmin(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -161,7 +162,7 @@
                 args.inA = arrayInA[i * 2 + j];
                 args.inB = arrayInB[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeFmin(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -240,7 +241,7 @@
                 args.inA = arrayInA[i * 4 + j];
                 args.inB = arrayInB[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeFmin(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -319,7 +320,7 @@
                 args.inA = arrayInA[i * 4 + j];
                 args.inB = arrayInB[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeFmin(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -358,6 +359,350 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalfHalf {
+        public short inA;
+        public double inADouble;
+        public short inB;
+        public double inBDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkFminHalfHalfHalf() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xc5ee8503l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xc5ee8504l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testFminHalfHalfHalf(inA, out);
+            verifyResultsFminHalfHalfHalf(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFminHalfHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testFminHalfHalfHalf(inA, out);
+            verifyResultsFminHalfHalfHalf(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFminHalfHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFminHalfHalfHalf(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        short[] arrayInA = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInA, (short) 42);
+        inA.copyTo(arrayInA);
+        short[] arrayInB = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInB, (short) 42);
+        inB.copyTo(arrayInB);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inA = arrayInA[i];
+                args.inADouble = Float16Utils.convertFloat16ToDouble(args.inA);
+                args.inB = arrayInB[i];
+                args.inBDouble = Float16Utils.convertFloat16ToDouble(args.inB);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeFmin(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inA: ");
+                        appendVariableToMessage(message, args.inA);
+                        message.append("\n");
+                        message.append("Input inB: ");
+                        appendVariableToMessage(message, args.inB);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkFminHalfHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFminHalf2Half2Half2() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x5461544dl, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x5461544el, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testFminHalf2Half2Half2(inA, out);
+            verifyResultsFminHalf2Half2Half2(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFminHalf2Half2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testFminHalf2Half2Half2(inA, out);
+            verifyResultsFminHalf2Half2Half2(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFminHalf2Half2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFminHalf2Half2Half2(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        short[] arrayInA = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInA, (short) 42);
+        inA.copyTo(arrayInA);
+        short[] arrayInB = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInB, (short) 42);
+        inB.copyTo(arrayInB);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inA = arrayInA[i * 2 + j];
+                args.inADouble = Float16Utils.convertFloat16ToDouble(args.inA);
+                args.inB = arrayInB[i * 2 + j];
+                args.inBDouble = Float16Utils.convertFloat16ToDouble(args.inB);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeFmin(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inA: ");
+                        appendVariableToMessage(message, args.inA);
+                        message.append("\n");
+                        message.append("Input inB: ");
+                        appendVariableToMessage(message, args.inB);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkFminHalf2Half2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFminHalf3Half3Half3() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0xb300651cl, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0xb300651dl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testFminHalf3Half3Half3(inA, out);
+            verifyResultsFminHalf3Half3Half3(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFminHalf3Half3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testFminHalf3Half3Half3(inA, out);
+            verifyResultsFminHalf3Half3Half3(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFminHalf3Half3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFminHalf3Half3Half3(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        short[] arrayInA = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInA, (short) 42);
+        inA.copyTo(arrayInA);
+        short[] arrayInB = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInB, (short) 42);
+        inB.copyTo(arrayInB);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inA = arrayInA[i * 4 + j];
+                args.inADouble = Float16Utils.convertFloat16ToDouble(args.inA);
+                args.inB = arrayInB[i * 4 + j];
+                args.inBDouble = Float16Utils.convertFloat16ToDouble(args.inB);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeFmin(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inA: ");
+                        appendVariableToMessage(message, args.inA);
+                        message.append("\n");
+                        message.append("Input inB: ");
+                        appendVariableToMessage(message, args.inB);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkFminHalf3Half3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFminHalf4Half4Half4() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x119f75ebl, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x119f75ecl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testFminHalf4Half4Half4(inA, out);
+            verifyResultsFminHalf4Half4Half4(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFminHalf4Half4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testFminHalf4Half4Half4(inA, out);
+            verifyResultsFminHalf4Half4Half4(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFminHalf4Half4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFminHalf4Half4Half4(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        short[] arrayInA = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInA, (short) 42);
+        inA.copyTo(arrayInA);
+        short[] arrayInB = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInB, (short) 42);
+        inB.copyTo(arrayInB);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inA = arrayInA[i * 4 + j];
+                args.inADouble = Float16Utils.convertFloat16ToDouble(args.inA);
+                args.inB = arrayInB[i * 4 + j];
+                args.inBDouble = Float16Utils.convertFloat16ToDouble(args.inB);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeFmin(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inA: ");
+                        appendVariableToMessage(message, args.inA);
+                        message.append("\n");
+                        message.append("Input inB: ");
+                        appendVariableToMessage(message, args.inB);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkFminHalf4Half4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     private void checkFminFloat2FloatFloat2() {
         Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x24457670l, false);
         Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x24457671l, false);
@@ -398,7 +743,7 @@
                 args.inA = arrayInA[i * 2 + j];
                 args.inB = arrayInB[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeFmin(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -477,7 +822,7 @@
                 args.inA = arrayInA[i * 4 + j];
                 args.inB = arrayInB[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeFmin(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -556,7 +901,7 @@
                 args.inA = arrayInA[i * 4 + j];
                 args.inB = arrayInB[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeFmin(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -595,13 +940,272 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    private void checkFminHalf2HalfHalf2() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xa4829957l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xa4829958l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testFminHalf2HalfHalf2(inA, out);
+            verifyResultsFminHalf2HalfHalf2(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFminHalf2HalfHalf2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testFminHalf2HalfHalf2(inA, out);
+            verifyResultsFminHalf2HalfHalf2(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFminHalf2HalfHalf2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFminHalf2HalfHalf2(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        short[] arrayInA = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInA, (short) 42);
+        inA.copyTo(arrayInA);
+        short[] arrayInB = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInB, (short) 42);
+        inB.copyTo(arrayInB);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inA = arrayInA[i * 2 + j];
+                args.inADouble = Float16Utils.convertFloat16ToDouble(args.inA);
+                args.inB = arrayInB[i];
+                args.inBDouble = Float16Utils.convertFloat16ToDouble(args.inB);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeFmin(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inA: ");
+                        appendVariableToMessage(message, args.inA);
+                        message.append("\n");
+                        message.append("Input inB: ");
+                        appendVariableToMessage(message, args.inB);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkFminHalf2HalfHalf2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFminHalf3HalfHalf3() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x571c2afbl, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x571c2afcl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testFminHalf3HalfHalf3(inA, out);
+            verifyResultsFminHalf3HalfHalf3(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFminHalf3HalfHalf3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testFminHalf3HalfHalf3(inA, out);
+            verifyResultsFminHalf3HalfHalf3(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFminHalf3HalfHalf3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFminHalf3HalfHalf3(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        short[] arrayInA = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInA, (short) 42);
+        inA.copyTo(arrayInA);
+        short[] arrayInB = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInB, (short) 42);
+        inB.copyTo(arrayInB);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inA = arrayInA[i * 4 + j];
+                args.inADouble = Float16Utils.convertFloat16ToDouble(args.inA);
+                args.inB = arrayInB[i];
+                args.inBDouble = Float16Utils.convertFloat16ToDouble(args.inB);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeFmin(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inA: ");
+                        appendVariableToMessage(message, args.inA);
+                        message.append("\n");
+                        message.append("Input inB: ");
+                        appendVariableToMessage(message, args.inB);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkFminHalf3HalfHalf3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFminHalf4HalfHalf4() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x9b5bc9fl, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x9b5bca0l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testFminHalf4HalfHalf4(inA, out);
+            verifyResultsFminHalf4HalfHalf4(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFminHalf4HalfHalf4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testFminHalf4HalfHalf4(inA, out);
+            verifyResultsFminHalf4HalfHalf4(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFminHalf4HalfHalf4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFminHalf4HalfHalf4(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        short[] arrayInA = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInA, (short) 42);
+        inA.copyTo(arrayInA);
+        short[] arrayInB = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInB, (short) 42);
+        inB.copyTo(arrayInB);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inA = arrayInA[i * 4 + j];
+                args.inADouble = Float16Utils.convertFloat16ToDouble(args.inA);
+                args.inB = arrayInB[i];
+                args.inBDouble = Float16Utils.convertFloat16ToDouble(args.inB);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeFmin(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inA: ");
+                        appendVariableToMessage(message, args.inA);
+                        message.append("\n");
+                        message.append("Input inB: ");
+                        appendVariableToMessage(message, args.inB);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkFminHalf4HalfHalf4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testFmin() {
         checkFminFloatFloatFloat();
         checkFminFloat2Float2Float2();
         checkFminFloat3Float3Float3();
         checkFminFloat4Float4Float4();
+        checkFminHalfHalfHalf();
+        checkFminHalf2Half2Half2();
+        checkFminHalf3Half3Half3();
+        checkFminHalf4Half4Half4();
         checkFminFloat2FloatFloat2();
         checkFminFloat3FloatFloat3();
         checkFminFloat4FloatFloat4();
+        checkFminHalf2HalfHalf2();
+        checkFminHalf3HalfHalf3();
+        checkFminHalf4HalfHalf4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFmin.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFmin.rs
index 1e25a34..7e6c6dd 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFmin.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFmin.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -41,6 +41,26 @@
     return fmin(inA, inB);
 }
 
+half __attribute__((kernel)) testFminHalfHalfHalf(half inA, unsigned int x) {
+    half inB = rsGetElementAt_half(gAllocInB, x);
+    return fmin(inA, inB);
+}
+
+half2 __attribute__((kernel)) testFminHalf2Half2Half2(half2 inA, unsigned int x) {
+    half2 inB = rsGetElementAt_half2(gAllocInB, x);
+    return fmin(inA, inB);
+}
+
+half3 __attribute__((kernel)) testFminHalf3Half3Half3(half3 inA, unsigned int x) {
+    half3 inB = rsGetElementAt_half3(gAllocInB, x);
+    return fmin(inA, inB);
+}
+
+half4 __attribute__((kernel)) testFminHalf4Half4Half4(half4 inA, unsigned int x) {
+    half4 inB = rsGetElementAt_half4(gAllocInB, x);
+    return fmin(inA, inB);
+}
+
 float2 __attribute__((kernel)) testFminFloat2FloatFloat2(float2 inA, unsigned int x) {
     float inB = rsGetElementAt_float(gAllocInB, x);
     return fmin(inA, inB);
@@ -55,3 +75,18 @@
     float inB = rsGetElementAt_float(gAllocInB, x);
     return fmin(inA, inB);
 }
+
+half2 __attribute__((kernel)) testFminHalf2HalfHalf2(half2 inA, unsigned int x) {
+    half inB = rsGetElementAt_half(gAllocInB, x);
+    return fmin(inA, inB);
+}
+
+half3 __attribute__((kernel)) testFminHalf3HalfHalf3(half3 inA, unsigned int x) {
+    half inB = rsGetElementAt_half(gAllocInB, x);
+    return fmin(inA, inB);
+}
+
+half4 __attribute__((kernel)) testFminHalf4HalfHalf4(half4 inA, unsigned int x) {
+    half inB = rsGetElementAt_half(gAllocInB, x);
+    return fmin(inA, inB);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFminRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFminRelaxed.rs
index cee70ab..5bbd2cf 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFminRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFminRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFmod.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFmod.java
index 442cad9..921c261 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFmod.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFmod.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -82,7 +83,7 @@
                 args.inNumerator = arrayInNumerator[i];
                 args.inDenominator = arrayInDenominator[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeFmod(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -161,7 +162,7 @@
                 args.inNumerator = arrayInNumerator[i * 2 + j];
                 args.inDenominator = arrayInDenominator[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeFmod(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -240,7 +241,7 @@
                 args.inNumerator = arrayInNumerator[i * 4 + j];
                 args.inDenominator = arrayInDenominator[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeFmod(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -319,7 +320,7 @@
                 args.inNumerator = arrayInNumerator[i * 4 + j];
                 args.inDenominator = arrayInDenominator[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeFmod(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -358,10 +359,358 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalfHalf {
+        public short inNumerator;
+        public double inNumeratorDouble;
+        public short inDenominator;
+        public double inDenominatorDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkFmodHalfHalfHalf() {
+        Allocation inNumerator = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x9b7bf563l, false);
+        Allocation inDenominator = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x699a0144l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.set_gAllocInDenominator(inDenominator);
+            script.forEach_testFmodHalfHalfHalf(inNumerator, out);
+            verifyResultsFmodHalfHalfHalf(inNumerator, inDenominator, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmodHalfHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInDenominator(inDenominator);
+            scriptRelaxed.forEach_testFmodHalfHalfHalf(inNumerator, out);
+            verifyResultsFmodHalfHalfHalf(inNumerator, inDenominator, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmodHalfHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFmodHalfHalfHalf(Allocation inNumerator, Allocation inDenominator, Allocation out, boolean relaxed) {
+        short[] arrayInNumerator = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInNumerator, (short) 42);
+        inNumerator.copyTo(arrayInNumerator);
+        short[] arrayInDenominator = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInDenominator, (short) 42);
+        inDenominator.copyTo(arrayInDenominator);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inNumerator = arrayInNumerator[i];
+                args.inNumeratorDouble = Float16Utils.convertFloat16ToDouble(args.inNumerator);
+                args.inDenominator = arrayInDenominator[i];
+                args.inDenominatorDouble = Float16Utils.convertFloat16ToDouble(args.inDenominator);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeFmod(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inNumerator: ");
+                        appendVariableToMessage(message, args.inNumerator);
+                        message.append("\n");
+                        message.append("Input inDenominator: ");
+                        appendVariableToMessage(message, args.inDenominator);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkFmodHalfHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFmodHalf2Half2Half2() {
+        Allocation inNumerator = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xe67736bdl, false);
+        Allocation inDenominator = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xfa55044el, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.set_gAllocInDenominator(inDenominator);
+            script.forEach_testFmodHalf2Half2Half2(inNumerator, out);
+            verifyResultsFmodHalf2Half2Half2(inNumerator, inDenominator, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmodHalf2Half2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInDenominator(inDenominator);
+            scriptRelaxed.forEach_testFmodHalf2Half2Half2(inNumerator, out);
+            verifyResultsFmodHalf2Half2Half2(inNumerator, inDenominator, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmodHalf2Half2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFmodHalf2Half2Half2(Allocation inNumerator, Allocation inDenominator, Allocation out, boolean relaxed) {
+        short[] arrayInNumerator = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInNumerator, (short) 42);
+        inNumerator.copyTo(arrayInNumerator);
+        short[] arrayInDenominator = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInDenominator, (short) 42);
+        inDenominator.copyTo(arrayInDenominator);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inNumerator = arrayInNumerator[i * 2 + j];
+                args.inNumeratorDouble = Float16Utils.convertFloat16ToDouble(args.inNumerator);
+                args.inDenominator = arrayInDenominator[i * 2 + j];
+                args.inDenominatorDouble = Float16Utils.convertFloat16ToDouble(args.inDenominator);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeFmod(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inNumerator: ");
+                        appendVariableToMessage(message, args.inNumerator);
+                        message.append("\n");
+                        message.append("Input inDenominator: ");
+                        appendVariableToMessage(message, args.inDenominator);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkFmodHalf2Half2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFmodHalf3Half3Half3() {
+        Allocation inNumerator = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x31e9672cl, false);
+        Allocation inDenominator = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0xe614d605l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.set_gAllocInDenominator(inDenominator);
+            script.forEach_testFmodHalf3Half3Half3(inNumerator, out);
+            verifyResultsFmodHalf3Half3Half3(inNumerator, inDenominator, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmodHalf3Half3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInDenominator(inDenominator);
+            scriptRelaxed.forEach_testFmodHalf3Half3Half3(inNumerator, out);
+            verifyResultsFmodHalf3Half3Half3(inNumerator, inDenominator, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmodHalf3Half3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFmodHalf3Half3Half3(Allocation inNumerator, Allocation inDenominator, Allocation out, boolean relaxed) {
+        short[] arrayInNumerator = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInNumerator, (short) 42);
+        inNumerator.copyTo(arrayInNumerator);
+        short[] arrayInDenominator = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInDenominator, (short) 42);
+        inDenominator.copyTo(arrayInDenominator);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inNumerator = arrayInNumerator[i * 4 + j];
+                args.inNumeratorDouble = Float16Utils.convertFloat16ToDouble(args.inNumerator);
+                args.inDenominator = arrayInDenominator[i * 4 + j];
+                args.inDenominatorDouble = Float16Utils.convertFloat16ToDouble(args.inDenominator);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeFmod(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inNumerator: ");
+                        appendVariableToMessage(message, args.inNumerator);
+                        message.append("\n");
+                        message.append("Input inDenominator: ");
+                        appendVariableToMessage(message, args.inDenominator);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkFmodHalf3Half3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFmodHalf4Half4Half4() {
+        Allocation inNumerator = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x7d5b979bl, false);
+        Allocation inDenominator = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xd1d4a7bcl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.set_gAllocInDenominator(inDenominator);
+            script.forEach_testFmodHalf4Half4Half4(inNumerator, out);
+            verifyResultsFmodHalf4Half4Half4(inNumerator, inDenominator, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmodHalf4Half4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInDenominator(inDenominator);
+            scriptRelaxed.forEach_testFmodHalf4Half4Half4(inNumerator, out);
+            verifyResultsFmodHalf4Half4Half4(inNumerator, inDenominator, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmodHalf4Half4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFmodHalf4Half4Half4(Allocation inNumerator, Allocation inDenominator, Allocation out, boolean relaxed) {
+        short[] arrayInNumerator = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInNumerator, (short) 42);
+        inNumerator.copyTo(arrayInNumerator);
+        short[] arrayInDenominator = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInDenominator, (short) 42);
+        inDenominator.copyTo(arrayInDenominator);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inNumerator = arrayInNumerator[i * 4 + j];
+                args.inNumeratorDouble = Float16Utils.convertFloat16ToDouble(args.inNumerator);
+                args.inDenominator = arrayInDenominator[i * 4 + j];
+                args.inDenominatorDouble = Float16Utils.convertFloat16ToDouble(args.inDenominator);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeFmod(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inNumerator: ");
+                        appendVariableToMessage(message, args.inNumerator);
+                        message.append("\n");
+                        message.append("Input inDenominator: ");
+                        appendVariableToMessage(message, args.inDenominator);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkFmodHalf4Half4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testFmod() {
         checkFmodFloatFloatFloat();
         checkFmodFloat2Float2Float2();
         checkFmodFloat3Float3Float3();
         checkFmodFloat4Float4Float4();
+        checkFmodHalfHalfHalf();
+        checkFmodHalf2Half2Half2();
+        checkFmodHalf3Half3Half3();
+        checkFmodHalf4Half4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFmod.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFmod.rs
index 8582fae..56ed83f 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFmod.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFmod.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -40,3 +40,23 @@
     float4 inDenominator = rsGetElementAt_float4(gAllocInDenominator, x);
     return fmod(inNumerator, inDenominator);
 }
+
+half __attribute__((kernel)) testFmodHalfHalfHalf(half inNumerator, unsigned int x) {
+    half inDenominator = rsGetElementAt_half(gAllocInDenominator, x);
+    return fmod(inNumerator, inDenominator);
+}
+
+half2 __attribute__((kernel)) testFmodHalf2Half2Half2(half2 inNumerator, unsigned int x) {
+    half2 inDenominator = rsGetElementAt_half2(gAllocInDenominator, x);
+    return fmod(inNumerator, inDenominator);
+}
+
+half3 __attribute__((kernel)) testFmodHalf3Half3Half3(half3 inNumerator, unsigned int x) {
+    half3 inDenominator = rsGetElementAt_half3(gAllocInDenominator, x);
+    return fmod(inNumerator, inDenominator);
+}
+
+half4 __attribute__((kernel)) testFmodHalf4Half4Half4(half4 inNumerator, unsigned int x) {
+    half4 inDenominator = rsGetElementAt_half4(gAllocInDenominator, x);
+    return fmod(inNumerator, inDenominator);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFmodRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFmodRelaxed.rs
index 08b8164..21493a2 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFmodRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFmodRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFract.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFract.java
index 11ad1be..b11b36e 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFract.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFract.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -82,7 +83,7 @@
                 ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeFract(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -170,7 +171,7 @@
                 ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeFract(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -258,7 +259,7 @@
                 ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeFract(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -346,7 +347,7 @@
                 ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeFract(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -432,7 +433,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeFract(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -501,7 +502,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeFract(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -570,7 +571,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeFract(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -639,7 +640,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeFract(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -675,6 +676,691 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty outFloor;
+        public Target.Floaty out;
+    }
+
+    private void checkFractHalfHalfHalf() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x64a42fb6l, false);
+        try {
+            Allocation outFloor = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.set_gAllocOutFloor(outFloor);
+            script.forEach_testFractHalfHalfHalf(inV, out);
+            verifyResultsFractHalfHalfHalf(inV, outFloor, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFractHalfHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation outFloor = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocOutFloor(outFloor);
+            scriptRelaxed.forEach_testFractHalfHalfHalf(inV, out);
+            verifyResultsFractHalfHalfHalf(inV, outFloor, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFractHalfHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFractHalfHalfHalf(Allocation inV, Allocation outFloor, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOutFloor = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOutFloor, (short) 42);
+        outFloor.copyTo(arrayOutFloor);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeFract(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.outFloor.couldBe(Float16Utils.convertFloat16ToDouble(arrayOutFloor[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output outFloor: ");
+                        appendVariableToMessage(message, args.outFloor);
+                        message.append("\n");
+                        message.append("Actual   output outFloor: ");
+                        appendVariableToMessage(message, arrayOutFloor[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output outFloor (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOutFloor[i * 1 + j]));
+                        if (!args.outFloor.couldBe(Float16Utils.convertFloat16ToDouble(arrayOutFloor[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkFractHalfHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFractHalf2Half2Half2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x734da11cl, false);
+        try {
+            Allocation outFloor = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.set_gAllocOutFloor(outFloor);
+            script.forEach_testFractHalf2Half2Half2(inV, out);
+            verifyResultsFractHalf2Half2Half2(inV, outFloor, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFractHalf2Half2Half2: " + e.toString());
+        }
+        try {
+            Allocation outFloor = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocOutFloor(outFloor);
+            scriptRelaxed.forEach_testFractHalf2Half2Half2(inV, out);
+            verifyResultsFractHalf2Half2Half2(inV, outFloor, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFractHalf2Half2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFractHalf2Half2Half2(Allocation inV, Allocation outFloor, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOutFloor = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOutFloor, (short) 42);
+        outFloor.copyTo(arrayOutFloor);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeFract(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.outFloor.couldBe(Float16Utils.convertFloat16ToDouble(arrayOutFloor[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output outFloor: ");
+                        appendVariableToMessage(message, args.outFloor);
+                        message.append("\n");
+                        message.append("Actual   output outFloor: ");
+                        appendVariableToMessage(message, arrayOutFloor[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output outFloor (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOutFloor[i * 2 + j]));
+                        if (!args.outFloor.couldBe(Float16Utils.convertFloat16ToDouble(arrayOutFloor[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkFractHalf2Half2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFractHalf3Half3Half3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0xd1ecb1ebl, false);
+        try {
+            Allocation outFloor = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.set_gAllocOutFloor(outFloor);
+            script.forEach_testFractHalf3Half3Half3(inV, out);
+            verifyResultsFractHalf3Half3Half3(inV, outFloor, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFractHalf3Half3Half3: " + e.toString());
+        }
+        try {
+            Allocation outFloor = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocOutFloor(outFloor);
+            scriptRelaxed.forEach_testFractHalf3Half3Half3(inV, out);
+            verifyResultsFractHalf3Half3Half3(inV, outFloor, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFractHalf3Half3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFractHalf3Half3Half3(Allocation inV, Allocation outFloor, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOutFloor = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOutFloor, (short) 42);
+        outFloor.copyTo(arrayOutFloor);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeFract(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.outFloor.couldBe(Float16Utils.convertFloat16ToDouble(arrayOutFloor[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output outFloor: ");
+                        appendVariableToMessage(message, args.outFloor);
+                        message.append("\n");
+                        message.append("Actual   output outFloor: ");
+                        appendVariableToMessage(message, arrayOutFloor[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output outFloor (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOutFloor[i * 4 + j]));
+                        if (!args.outFloor.couldBe(Float16Utils.convertFloat16ToDouble(arrayOutFloor[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkFractHalf3Half3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFractHalf4Half4Half4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x308bc2bal, false);
+        try {
+            Allocation outFloor = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.set_gAllocOutFloor(outFloor);
+            script.forEach_testFractHalf4Half4Half4(inV, out);
+            verifyResultsFractHalf4Half4Half4(inV, outFloor, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFractHalf4Half4Half4: " + e.toString());
+        }
+        try {
+            Allocation outFloor = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocOutFloor(outFloor);
+            scriptRelaxed.forEach_testFractHalf4Half4Half4(inV, out);
+            verifyResultsFractHalf4Half4Half4(inV, outFloor, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFractHalf4Half4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFractHalf4Half4Half4(Allocation inV, Allocation outFloor, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOutFloor = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOutFloor, (short) 42);
+        outFloor.copyTo(arrayOutFloor);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeFract(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.outFloor.couldBe(Float16Utils.convertFloat16ToDouble(arrayOutFloor[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output outFloor: ");
+                        appendVariableToMessage(message, args.outFloor);
+                        message.append("\n");
+                        message.append("Actual   output outFloor: ");
+                        appendVariableToMessage(message, arrayOutFloor[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output outFloor (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOutFloor[i * 4 + j]));
+                        if (!args.outFloor.couldBe(Float16Utils.convertFloat16ToDouble(arrayOutFloor[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkFractHalf4Half4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkFractHalfHalf() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x96468e55l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testFractHalfHalf(inV, out);
+            verifyResultsFractHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFractHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testFractHalfHalf(inV, out);
+            verifyResultsFractHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFractHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFractHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeFract(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkFractHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFractHalf2Half2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xad1120fl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testFractHalf2Half2(inV, out);
+            verifyResultsFractHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFractHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testFractHalf2Half2(inV, out);
+            verifyResultsFractHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFractHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFractHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeFract(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkFractHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFractHalf3Half3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x69d8d703l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testFractHalf3Half3(inV, out);
+            verifyResultsFractHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFractHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testFractHalf3Half3(inV, out);
+            verifyResultsFractHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFractHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFractHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeFract(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkFractHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFractHalf4Half4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xc8e09bf7l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testFractHalf4Half4(inV, out);
+            verifyResultsFractHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFractHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testFractHalf4Half4(inV, out);
+            verifyResultsFractHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFractHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFractHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeFract(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkFractHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testFract() {
         checkFractFloatFloatFloat();
         checkFractFloat2Float2Float2();
@@ -684,5 +1370,13 @@
         checkFractFloat2Float2();
         checkFractFloat3Float3();
         checkFractFloat4Float4();
+        checkFractHalfHalfHalf();
+        checkFractHalf2Half2Half2();
+        checkFractHalf3Half3Half3();
+        checkFractHalf4Half4Half4();
+        checkFractHalfHalf();
+        checkFractHalf2Half2();
+        checkFractHalf3Half3();
+        checkFractHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFract.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFract.rs
index cbc61fa..4fd65d3 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFract.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFract.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -64,3 +64,47 @@
 float4 __attribute__((kernel)) testFractFloat4Float4(float4 inV) {
     return fract(inV);
 }
+
+half __attribute__((kernel)) testFractHalfHalfHalf(half inV, unsigned int x) {
+    half outFloor = 0;
+    half out = fract(inV, &outFloor);
+    rsSetElementAt_half(gAllocOutFloor, outFloor, x);
+    return out;
+}
+
+half2 __attribute__((kernel)) testFractHalf2Half2Half2(half2 inV, unsigned int x) {
+    half2 outFloor = 0;
+    half2 out = fract(inV, &outFloor);
+    rsSetElementAt_half2(gAllocOutFloor, outFloor, x);
+    return out;
+}
+
+half3 __attribute__((kernel)) testFractHalf3Half3Half3(half3 inV, unsigned int x) {
+    half3 outFloor = 0;
+    half3 out = fract(inV, &outFloor);
+    rsSetElementAt_half3(gAllocOutFloor, outFloor, x);
+    return out;
+}
+
+half4 __attribute__((kernel)) testFractHalf4Half4Half4(half4 inV, unsigned int x) {
+    half4 outFloor = 0;
+    half4 out = fract(inV, &outFloor);
+    rsSetElementAt_half4(gAllocOutFloor, outFloor, x);
+    return out;
+}
+
+half __attribute__((kernel)) testFractHalfHalf(half inV) {
+    return fract(inV);
+}
+
+half2 __attribute__((kernel)) testFractHalf2Half2(half2 inV) {
+    return fract(inV);
+}
+
+half3 __attribute__((kernel)) testFractHalf3Half3(half3 inV) {
+    return fract(inV);
+}
+
+half4 __attribute__((kernel)) testFractHalf4Half4(half4 inV) {
+    return fract(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFractRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFractRelaxed.rs
index 26aa16a..344a263 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFractRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFractRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFrexp.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFrexp.java
index 72de03e..c4f9c33 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFrexp.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFrexp.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -82,7 +83,7 @@
                 ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeFrexp(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -170,7 +171,7 @@
                 ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeFrexp(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -258,7 +259,7 @@
                 ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeFrexp(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -346,7 +347,7 @@
                 ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeFrexp(args, target);
                 // Validate the outputs.
                 boolean valid = true;
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFrexp.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFrexp.rs
index 901ed3b..bf5f028 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFrexp.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFrexp.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFrexpRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFrexpRelaxed.rs
index 88acd21..d2fce54 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFrexpRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFrexpRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHalfRecip.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHalfRecip.java
index 4793b6d..f60f372 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHalfRecip.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHalfRecip.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.HALF, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeHalfRecip(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.HALF, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeHalfRecip(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.HALF, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeHalfRecip(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.HALF, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeHalfRecip(args, target);
                 // Validate the outputs.
                 boolean valid = true;
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHalfRecip.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHalfRecip.rs
index f8bcc3b..1c3aa71 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHalfRecip.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHalfRecip.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHalfRecipRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHalfRecipRelaxed.rs
index ded5ceb..7dc0a9b 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHalfRecipRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHalfRecipRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHalfRsqrt.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHalfRsqrt.java
index efe890a..072ba59 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHalfRsqrt.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHalfRsqrt.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.HALF, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeHalfRsqrt(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.HALF, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeHalfRsqrt(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.HALF, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeHalfRsqrt(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.HALF, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeHalfRsqrt(args, target);
                 // Validate the outputs.
                 boolean valid = true;
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHalfRsqrt.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHalfRsqrt.rs
index fcb34c2..090bc48 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHalfRsqrt.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHalfRsqrt.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHalfRsqrtRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHalfRsqrtRelaxed.rs
index a7928a8..7a3aaaf 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHalfRsqrtRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHalfRsqrtRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHalfSqrt.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHalfSqrt.java
index 9cf3ff2..04e191e 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHalfSqrt.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHalfSqrt.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.HALF, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeHalfSqrt(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.HALF, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeHalfSqrt(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.HALF, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeHalfSqrt(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.HALF, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeHalfSqrt(args, target);
                 // Validate the outputs.
                 boolean valid = true;
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHalfSqrt.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHalfSqrt.rs
index db18b05..013298c 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHalfSqrt.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHalfSqrt.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHalfSqrtRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHalfSqrtRelaxed.rs
index 6fcd519..7d4827a 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHalfSqrtRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHalfSqrtRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHypot.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHypot.java
index 8f2e5dd..9b02e25 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHypot.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHypot.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -82,7 +83,7 @@
                 args.inA = arrayInA[i];
                 args.inB = arrayInB[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeHypot(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -161,7 +162,7 @@
                 args.inA = arrayInA[i * 2 + j];
                 args.inB = arrayInB[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeHypot(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -240,7 +241,7 @@
                 args.inA = arrayInA[i * 4 + j];
                 args.inB = arrayInB[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeHypot(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -319,7 +320,7 @@
                 args.inA = arrayInA[i * 4 + j];
                 args.inB = arrayInB[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeHypot(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -358,10 +359,358 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalfHalf {
+        public short inA;
+        public double inADouble;
+        public short inB;
+        public double inBDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkHypotHalfHalfHalf() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xff770667l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xff770668l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testHypotHalfHalfHalf(inA, out);
+            verifyResultsHypotHalfHalfHalf(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHypotHalfHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testHypotHalfHalfHalf(inA, out);
+            verifyResultsHypotHalfHalfHalf(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHypotHalfHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsHypotHalfHalfHalf(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        short[] arrayInA = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInA, (short) 42);
+        inA.copyTo(arrayInA);
+        short[] arrayInB = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInB, (short) 42);
+        inB.copyTo(arrayInB);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inA = arrayInA[i];
+                args.inADouble = Float16Utils.convertFloat16ToDouble(args.inA);
+                args.inB = arrayInB[i];
+                args.inBDouble = Float16Utils.convertFloat16ToDouble(args.inB);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeHypot(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inA: ");
+                        appendVariableToMessage(message, args.inA);
+                        message.append("\n");
+                        message.append("Input inB: ");
+                        appendVariableToMessage(message, args.inB);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkHypotHalfHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkHypotHalf2Half2Half2() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xaa72b8b9l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xaa72b8bal, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testHypotHalf2Half2Half2(inA, out);
+            verifyResultsHypotHalf2Half2Half2(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHypotHalf2Half2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testHypotHalf2Half2Half2(inA, out);
+            verifyResultsHypotHalf2Half2Half2(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHypotHalf2Half2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsHypotHalf2Half2Half2(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        short[] arrayInA = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInA, (short) 42);
+        inA.copyTo(arrayInA);
+        short[] arrayInB = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInB, (short) 42);
+        inB.copyTo(arrayInB);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inA = arrayInA[i * 2 + j];
+                args.inADouble = Float16Utils.convertFloat16ToDouble(args.inA);
+                args.inB = arrayInB[i * 2 + j];
+                args.inBDouble = Float16Utils.convertFloat16ToDouble(args.inB);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeHypot(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inA: ");
+                        appendVariableToMessage(message, args.inA);
+                        message.append("\n");
+                        message.append("Input inB: ");
+                        appendVariableToMessage(message, args.inB);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkHypotHalf2Half2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkHypotHalf3Half3Half3() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x911c988l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x911c989l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testHypotHalf3Half3Half3(inA, out);
+            verifyResultsHypotHalf3Half3Half3(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHypotHalf3Half3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testHypotHalf3Half3Half3(inA, out);
+            verifyResultsHypotHalf3Half3Half3(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHypotHalf3Half3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsHypotHalf3Half3Half3(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        short[] arrayInA = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInA, (short) 42);
+        inA.copyTo(arrayInA);
+        short[] arrayInB = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInB, (short) 42);
+        inB.copyTo(arrayInB);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inA = arrayInA[i * 4 + j];
+                args.inADouble = Float16Utils.convertFloat16ToDouble(args.inA);
+                args.inB = arrayInB[i * 4 + j];
+                args.inBDouble = Float16Utils.convertFloat16ToDouble(args.inB);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeHypot(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inA: ");
+                        appendVariableToMessage(message, args.inA);
+                        message.append("\n");
+                        message.append("Input inB: ");
+                        appendVariableToMessage(message, args.inB);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkHypotHalf3Half3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkHypotHalf4Half4Half4() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x67b0da57l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x67b0da58l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testHypotHalf4Half4Half4(inA, out);
+            verifyResultsHypotHalf4Half4Half4(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHypotHalf4Half4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testHypotHalf4Half4Half4(inA, out);
+            verifyResultsHypotHalf4Half4Half4(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHypotHalf4Half4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsHypotHalf4Half4Half4(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        short[] arrayInA = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInA, (short) 42);
+        inA.copyTo(arrayInA);
+        short[] arrayInB = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInB, (short) 42);
+        inB.copyTo(arrayInB);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inA = arrayInA[i * 4 + j];
+                args.inADouble = Float16Utils.convertFloat16ToDouble(args.inA);
+                args.inB = arrayInB[i * 4 + j];
+                args.inBDouble = Float16Utils.convertFloat16ToDouble(args.inB);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeHypot(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inA: ");
+                        appendVariableToMessage(message, args.inA);
+                        message.append("\n");
+                        message.append("Input inB: ");
+                        appendVariableToMessage(message, args.inB);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkHypotHalf4Half4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testHypot() {
         checkHypotFloatFloatFloat();
         checkHypotFloat2Float2Float2();
         checkHypotFloat3Float3Float3();
         checkHypotFloat4Float4Float4();
+        checkHypotHalfHalfHalf();
+        checkHypotHalf2Half2Half2();
+        checkHypotHalf3Half3Half3();
+        checkHypotHalf4Half4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHypot.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHypot.rs
index fcaae50..90d822d 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHypot.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHypot.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -40,3 +40,23 @@
     float4 inB = rsGetElementAt_float4(gAllocInB, x);
     return hypot(inA, inB);
 }
+
+half __attribute__((kernel)) testHypotHalfHalfHalf(half inA, unsigned int x) {
+    half inB = rsGetElementAt_half(gAllocInB, x);
+    return hypot(inA, inB);
+}
+
+half2 __attribute__((kernel)) testHypotHalf2Half2Half2(half2 inA, unsigned int x) {
+    half2 inB = rsGetElementAt_half2(gAllocInB, x);
+    return hypot(inA, inB);
+}
+
+half3 __attribute__((kernel)) testHypotHalf3Half3Half3(half3 inA, unsigned int x) {
+    half3 inB = rsGetElementAt_half3(gAllocInB, x);
+    return hypot(inA, inB);
+}
+
+half4 __attribute__((kernel)) testHypotHalf4Half4Half4(half4 inA, unsigned int x) {
+    half4 inB = rsGetElementAt_half4(gAllocInB, x);
+    return hypot(inA, inB);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHypotRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHypotRelaxed.rs
index 90f3d69..39d142a 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHypotRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHypotRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestIlogb.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestIlogb.java
index 8a24f7a..329a759 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestIlogb.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestIlogb.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestIlogb.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestIlogb.rs
index f93ab80..3fc3f99 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestIlogb.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestIlogb.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestIlogbRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestIlogbRelaxed.rs
index 995b659..0545c3a 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestIlogbRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestIlogbRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLdexp.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLdexp.java
index 6dc48ed..2bcc552 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLdexp.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLdexp.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -82,7 +83,7 @@
                 args.inMantissa = arrayInMantissa[i];
                 args.inExponent = arrayInExponent[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeLdexp(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -161,7 +162,7 @@
                 args.inMantissa = arrayInMantissa[i * 2 + j];
                 args.inExponent = arrayInExponent[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeLdexp(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -240,7 +241,7 @@
                 args.inMantissa = arrayInMantissa[i * 4 + j];
                 args.inExponent = arrayInExponent[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeLdexp(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -319,7 +320,7 @@
                 args.inMantissa = arrayInMantissa[i * 4 + j];
                 args.inExponent = arrayInExponent[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeLdexp(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -398,7 +399,7 @@
                 args.inMantissa = arrayInMantissa[i * 2 + j];
                 args.inExponent = arrayInExponent[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeLdexp(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -477,7 +478,7 @@
                 args.inMantissa = arrayInMantissa[i * 4 + j];
                 args.inExponent = arrayInExponent[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeLdexp(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -556,7 +557,7 @@
                 args.inMantissa = arrayInMantissa[i * 4 + j];
                 args.inExponent = arrayInExponent[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeLdexp(args, target);
                 // Validate the outputs.
                 boolean valid = true;
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLdexp.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLdexp.rs
index 212a2e6..9e6562d 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLdexp.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLdexp.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLdexpRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLdexpRelaxed.rs
index 2ab8836..66bb775 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLdexpRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLdexpRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLength.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLength.java
index 1e91f42..b7e6c9f 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLength.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLength.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -73,7 +74,7 @@
             // Create the appropriate sized arrays in args
             // Fill args with the input values
             args.inV = arrayInV[i];
-            Target target = new Target(relaxed);
+            Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
             CoreMathVerifier.computeLength(args, target);
 
             // Compare the expected outputs to the actual values returned by RS.
@@ -147,7 +148,7 @@
             for (int j = 0; j < 2 ; j++) {
                 args.inV[j] = arrayInV[i * 2 + j];
             }
-            Target target = new Target(relaxed);
+            Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
             CoreMathVerifier.computeLength(args, target);
 
             // Compare the expected outputs to the actual values returned by RS.
@@ -218,7 +219,7 @@
             for (int j = 0; j < 3 ; j++) {
                 args.inV[j] = arrayInV[i * 4 + j];
             }
-            Target target = new Target(relaxed);
+            Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
             CoreMathVerifier.computeLength(args, target);
 
             // Compare the expected outputs to the actual values returned by RS.
@@ -289,7 +290,7 @@
             for (int j = 0; j < 4 ; j++) {
                 args.inV[j] = arrayInV[i * 4 + j];
             }
-            Target target = new Target(relaxed);
+            Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
             CoreMathVerifier.computeLength(args, target);
 
             // Compare the expected outputs to the actual values returned by RS.
@@ -325,10 +326,324 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkLengthHalfHalf() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x6dc47281l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testLengthHalfHalf(inV, out);
+            verifyResultsLengthHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLengthHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testLengthHalfHalf(inV, out);
+            verifyResultsLengthHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLengthHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLengthHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+            // Create the appropriate sized arrays in args
+            // Fill args with the input values
+            args.inV = arrayInV[i];
+            args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+            Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+            CoreMathVerifier.computeLength(args, target);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i]))) {
+                valid = false;
+            }
+            if (!valid) {
+                if (!errorFound) {
+                    errorFound = true;
+                    message.append("Input inV: ");
+                    appendVariableToMessage(message, arrayInV[i]);
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    appendVariableToMessage(message, args.out);
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    appendVariableToMessage(message, arrayOut[i]);
+                    message.append("\n");
+                    message.append("Actual   output out (in double): ");
+                    appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i]));
+                    if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i]))) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    message.append("Errors at");
+                }
+                message.append(" [");
+                message.append(Integer.toString(i));
+                message.append("]");
+            }
+        }
+        assertFalse("Incorrect output for checkLengthHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsHalfNHalf {
+        public short[] inV;
+        public double[] inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkLengthHalf2Half() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xf0ea410dl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testLengthHalf2Half(inV, out);
+            verifyResultsLengthHalf2Half(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLengthHalf2Half: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testLengthHalf2Half(inV, out);
+            verifyResultsLengthHalf2Half(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLengthHalf2Half: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLengthHalf2Half(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsHalfNHalf args = new ArgumentsHalfNHalf();
+            // Create the appropriate sized arrays in args
+            args.inV = new short[2];
+            args.inVDouble = new double[2];
+            // Fill args with the input values
+            for (int j = 0; j < 2 ; j++) {
+                args.inV[j] = arrayInV[i * 2 + j];
+                args.inVDouble[j] = Float16Utils.convertFloat16ToDouble(args.inV[j]);
+            }
+            Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+            CoreMathVerifier.computeLength(args, target);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i]))) {
+                valid = false;
+            }
+            if (!valid) {
+                if (!errorFound) {
+                    errorFound = true;
+                    for (int j = 0; j < 2 ; j++) {
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, arrayInV[i * 2 + j]);
+                        message.append("\n");
+                    }
+                    message.append("Expected output out: ");
+                    appendVariableToMessage(message, args.out);
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    appendVariableToMessage(message, arrayOut[i]);
+                    message.append("\n");
+                    message.append("Actual   output out (in double): ");
+                    appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i]));
+                    if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i]))) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    message.append("Errors at");
+                }
+                message.append(" [");
+                message.append(Integer.toString(i));
+                message.append("]");
+            }
+        }
+        assertFalse("Incorrect output for checkLengthHalf2Half" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkLengthHalf3Half() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x3a911ab0l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testLengthHalf3Half(inV, out);
+            verifyResultsLengthHalf3Half(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLengthHalf3Half: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testLengthHalf3Half(inV, out);
+            verifyResultsLengthHalf3Half(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLengthHalf3Half: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLengthHalf3Half(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsHalfNHalf args = new ArgumentsHalfNHalf();
+            // Create the appropriate sized arrays in args
+            args.inV = new short[3];
+            args.inVDouble = new double[3];
+            // Fill args with the input values
+            for (int j = 0; j < 3 ; j++) {
+                args.inV[j] = arrayInV[i * 4 + j];
+                args.inVDouble[j] = Float16Utils.convertFloat16ToDouble(args.inV[j]);
+            }
+            Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+            CoreMathVerifier.computeLength(args, target);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i]))) {
+                valid = false;
+            }
+            if (!valid) {
+                if (!errorFound) {
+                    errorFound = true;
+                    for (int j = 0; j < 3 ; j++) {
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, arrayInV[i * 4 + j]);
+                        message.append("\n");
+                    }
+                    message.append("Expected output out: ");
+                    appendVariableToMessage(message, args.out);
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    appendVariableToMessage(message, arrayOut[i]);
+                    message.append("\n");
+                    message.append("Actual   output out (in double): ");
+                    appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i]));
+                    if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i]))) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    message.append("Errors at");
+                }
+                message.append(" [");
+                message.append(Integer.toString(i));
+                message.append("]");
+            }
+        }
+        assertFalse("Incorrect output for checkLengthHalf3Half" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkLengthHalf4Half() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x8437f453l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testLengthHalf4Half(inV, out);
+            verifyResultsLengthHalf4Half(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLengthHalf4Half: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testLengthHalf4Half(inV, out);
+            verifyResultsLengthHalf4Half(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLengthHalf4Half: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLengthHalf4Half(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsHalfNHalf args = new ArgumentsHalfNHalf();
+            // Create the appropriate sized arrays in args
+            args.inV = new short[4];
+            args.inVDouble = new double[4];
+            // Fill args with the input values
+            for (int j = 0; j < 4 ; j++) {
+                args.inV[j] = arrayInV[i * 4 + j];
+                args.inVDouble[j] = Float16Utils.convertFloat16ToDouble(args.inV[j]);
+            }
+            Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+            CoreMathVerifier.computeLength(args, target);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i]))) {
+                valid = false;
+            }
+            if (!valid) {
+                if (!errorFound) {
+                    errorFound = true;
+                    for (int j = 0; j < 4 ; j++) {
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, arrayInV[i * 4 + j]);
+                        message.append("\n");
+                    }
+                    message.append("Expected output out: ");
+                    appendVariableToMessage(message, args.out);
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    appendVariableToMessage(message, arrayOut[i]);
+                    message.append("\n");
+                    message.append("Actual   output out (in double): ");
+                    appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i]));
+                    if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i]))) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    message.append("Errors at");
+                }
+                message.append(" [");
+                message.append(Integer.toString(i));
+                message.append("]");
+            }
+        }
+        assertFalse("Incorrect output for checkLengthHalf4Half" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testLength() {
         checkLengthFloatFloat();
         checkLengthFloat2Float();
         checkLengthFloat3Float();
         checkLengthFloat4Float();
+        checkLengthHalfHalf();
+        checkLengthHalf2Half();
+        checkLengthHalf3Half();
+        checkLengthHalf4Half();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLength.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLength.rs
index f9c451e..5abc981 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLength.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLength.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float __attribute__((kernel)) testLengthFloat4Float(float4 inV) {
     return length(inV);
 }
+
+half __attribute__((kernel)) testLengthHalfHalf(half inV) {
+    return length(inV);
+}
+
+half __attribute__((kernel)) testLengthHalf2Half(half2 inV) {
+    return length(inV);
+}
+
+half __attribute__((kernel)) testLengthHalf3Half(half3 inV) {
+    return length(inV);
+}
+
+half __attribute__((kernel)) testLengthHalf4Half(half4 inV) {
+    return length(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLengthRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLengthRelaxed.rs
index 695ff5e..c75aed9 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLengthRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLengthRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLgamma.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLgamma.java
index 073be67..d1eaa9f 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLgamma.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLgamma.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeLgamma(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeLgamma(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeLgamma(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeLgamma(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -366,7 +367,7 @@
                 args.outSignOfGamma = arrayOutSignOfGamma[i * 1 + j];
                 args.out = arrayOut[i * 1 + j];
                 // Ask the CoreMathVerifier to validate.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 String errorMessage = CoreMathVerifier.verifyLgamma(args, target);
                 boolean valid = errorMessage == null;
                 if (!valid) {
@@ -439,7 +440,7 @@
                 args.outSignOfGamma = arrayOutSignOfGamma[i * 2 + j];
                 args.out = arrayOut[i * 2 + j];
                 // Ask the CoreMathVerifier to validate.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 String errorMessage = CoreMathVerifier.verifyLgamma(args, target);
                 boolean valid = errorMessage == null;
                 if (!valid) {
@@ -512,7 +513,7 @@
                 args.outSignOfGamma = arrayOutSignOfGamma[i * 4 + j];
                 args.out = arrayOut[i * 4 + j];
                 // Ask the CoreMathVerifier to validate.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 String errorMessage = CoreMathVerifier.verifyLgamma(args, target);
                 boolean valid = errorMessage == null;
                 if (!valid) {
@@ -585,7 +586,7 @@
                 args.outSignOfGamma = arrayOutSignOfGamma[i * 4 + j];
                 args.out = arrayOut[i * 4 + j];
                 // Ask the CoreMathVerifier to validate.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 String errorMessage = CoreMathVerifier.verifyLgamma(args, target);
                 boolean valid = errorMessage == null;
                 if (!valid) {
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLgamma.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLgamma.rs
index 69cfa03..ba31b4d 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLgamma.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLgamma.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLgammaRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLgammaRelaxed.rs
index c781ec2..2d5a155 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLgammaRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLgammaRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog.java
index 2cd529e..de3eecf 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeLog(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeLog(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeLog(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeLog(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkLogHalfHalf() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x35076dfl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testLogHalfHalf(inV, out);
+            verifyResultsLogHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLogHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testLogHalfHalf(inV, out);
+            verifyResultsLogHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLogHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLogHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeLog(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkLogHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkLogHalf2Half2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x97619ec9l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testLogHalf2Half2(inV, out);
+            verifyResultsLogHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLogHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testLogHalf2Half2(inV, out);
+            verifyResultsLogHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLogHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLogHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeLog(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkLogHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkLogHalf3Half3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0xf66963bdl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testLogHalf3Half3(inV, out);
+            verifyResultsLogHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLogHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testLogHalf3Half3(inV, out);
+            verifyResultsLogHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLogHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLogHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeLog(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkLogHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkLogHalf4Half4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x557128b1l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testLogHalf4Half4(inV, out);
+            verifyResultsLogHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLogHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testLogHalf4Half4(inV, out);
+            verifyResultsLogHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLogHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLogHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeLog(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkLogHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testLog() {
         checkLogFloatFloat();
         checkLogFloat2Float2();
         checkLogFloat3Float3();
         checkLogFloat4Float4();
+        checkLogHalfHalf();
+        checkLogHalf2Half2();
+        checkLogHalf3Half3();
+        checkLogHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog.rs
index 53c9a7d..0d0881a 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testLogFloat4Float4(float4 inV) {
     return log(inV);
 }
+
+half __attribute__((kernel)) testLogHalfHalf(half inV) {
+    return log(inV);
+}
+
+half2 __attribute__((kernel)) testLogHalf2Half2(half2 inV) {
+    return log(inV);
+}
+
+half3 __attribute__((kernel)) testLogHalf3Half3(half3 inV) {
+    return log(inV);
+}
+
+half4 __attribute__((kernel)) testLogHalf4Half4(half4 inV) {
+    return log(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog10.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog10.java
index de534f0..a5589e5 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog10.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog10.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeLog10(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeLog10(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeLog10(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeLog10(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkLog10HalfHalf() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xdd61cbd0l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testLog10HalfHalf(inV, out);
+            verifyResultsLog10HalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog10HalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testLog10HalfHalf(inV, out);
+            verifyResultsLog10HalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog10HalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLog10HalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeLog10(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkLog10HalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkLog10Half2Half2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x9e901f72l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testLog10Half2Half2(inV, out);
+            verifyResultsLog10Half2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog10Half2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testLog10Half2Half2(inV, out);
+            verifyResultsLog10Half2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog10Half2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLog10Half2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeLog10(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkLog10Half2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkLog10Half3Half3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0xfd97e466l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testLog10Half3Half3(inV, out);
+            verifyResultsLog10Half3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog10Half3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testLog10Half3Half3(inV, out);
+            verifyResultsLog10Half3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog10Half3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLog10Half3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeLog10(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkLog10Half3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkLog10Half4Half4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x5c9fa95al, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testLog10Half4Half4(inV, out);
+            verifyResultsLog10Half4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog10Half4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testLog10Half4Half4(inV, out);
+            verifyResultsLog10Half4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog10Half4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLog10Half4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeLog10(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkLog10Half4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testLog10() {
         checkLog10FloatFloat();
         checkLog10Float2Float2();
         checkLog10Float3Float3();
         checkLog10Float4Float4();
+        checkLog10HalfHalf();
+        checkLog10Half2Half2();
+        checkLog10Half3Half3();
+        checkLog10Half4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog10.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog10.rs
index e9b1670..03f657d 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog10.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog10.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testLog10Float4Float4(float4 inV) {
     return log10(inV);
 }
+
+half __attribute__((kernel)) testLog10HalfHalf(half inV) {
+    return log10(inV);
+}
+
+half2 __attribute__((kernel)) testLog10Half2Half2(half2 inV) {
+    return log10(inV);
+}
+
+half3 __attribute__((kernel)) testLog10Half3Half3(half3 inV) {
+    return log10(inV);
+}
+
+half4 __attribute__((kernel)) testLog10Half4Half4(half4 inV) {
+    return log10(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog10Relaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog10Relaxed.rs
index 90b767a..48a2d4e 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog10Relaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog10Relaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog1p.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog1p.java
index 3bc188a..8a17d9e 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog1p.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog1p.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeLog1p(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeLog1p(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeLog1p(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeLog1p(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkLog1pHalfHalf() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x28afb890l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testLog1pHalfHalf(inV, out);
+            verifyResultsLog1pHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog1pHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testLog1pHalfHalf(inV, out);
+            verifyResultsLog1pHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog1pHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLog1pHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeLog1p(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkLog1pHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkLog1pHalf2Half2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x84631632l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testLog1pHalf2Half2(inV, out);
+            verifyResultsLog1pHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog1pHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testLog1pHalf2Half2(inV, out);
+            verifyResultsLog1pHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog1pHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLog1pHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeLog1p(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkLog1pHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkLog1pHalf3Half3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0xe36adb26l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testLog1pHalf3Half3(inV, out);
+            verifyResultsLog1pHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog1pHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testLog1pHalf3Half3(inV, out);
+            verifyResultsLog1pHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog1pHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLog1pHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeLog1p(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkLog1pHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkLog1pHalf4Half4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x4272a01al, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testLog1pHalf4Half4(inV, out);
+            verifyResultsLog1pHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog1pHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testLog1pHalf4Half4(inV, out);
+            verifyResultsLog1pHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog1pHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLog1pHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeLog1p(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkLog1pHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testLog1p() {
         checkLog1pFloatFloat();
         checkLog1pFloat2Float2();
         checkLog1pFloat3Float3();
         checkLog1pFloat4Float4();
+        checkLog1pHalfHalf();
+        checkLog1pHalf2Half2();
+        checkLog1pHalf3Half3();
+        checkLog1pHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog1p.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog1p.rs
index feb8f68..cc11620 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog1p.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog1p.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testLog1pFloat4Float4(float4 inV) {
     return log1p(inV);
 }
+
+half __attribute__((kernel)) testLog1pHalfHalf(half inV) {
+    return log1p(inV);
+}
+
+half2 __attribute__((kernel)) testLog1pHalf2Half2(half2 inV) {
+    return log1p(inV);
+}
+
+half3 __attribute__((kernel)) testLog1pHalf3Half3(half3 inV) {
+    return log1p(inV);
+}
+
+half4 __attribute__((kernel)) testLog1pHalf4Half4(half4 inV) {
+    return log1p(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog1pRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog1pRelaxed.rs
index f40b18c..99685fc 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog1pRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog1pRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog2.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog2.java
index ea4b352..1c3b09c 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog2.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog2.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeLog2(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeLog2(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeLog2(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeLog2(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkLog2HalfHalf() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x23a7d4adl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testLog2HalfHalf(inV, out);
+            verifyResultsLog2HalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog2HalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testLog2HalfHalf(inV, out);
+            verifyResultsLog2HalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog2HalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLog2HalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeLog2(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkLog2HalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkLog2Half2Half2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x2e6623a7l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testLog2Half2Half2(inV, out);
+            verifyResultsLog2Half2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog2Half2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testLog2Half2Half2(inV, out);
+            verifyResultsLog2Half2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog2Half2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLog2Half2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeLog2(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkLog2Half2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkLog2Half3Half3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x8d6de89bl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testLog2Half3Half3(inV, out);
+            verifyResultsLog2Half3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog2Half3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testLog2Half3Half3(inV, out);
+            verifyResultsLog2Half3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog2Half3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLog2Half3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeLog2(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkLog2Half3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkLog2Half4Half4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xec75ad8fl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testLog2Half4Half4(inV, out);
+            verifyResultsLog2Half4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog2Half4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testLog2Half4Half4(inV, out);
+            verifyResultsLog2Half4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog2Half4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLog2Half4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeLog2(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkLog2Half4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testLog2() {
         checkLog2FloatFloat();
         checkLog2Float2Float2();
         checkLog2Float3Float3();
         checkLog2Float4Float4();
+        checkLog2HalfHalf();
+        checkLog2Half2Half2();
+        checkLog2Half3Half3();
+        checkLog2Half4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog2.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog2.rs
index 8f6d43c..e11e2b6 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog2.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog2.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testLog2Float4Float4(float4 inV) {
     return log2(inV);
 }
+
+half __attribute__((kernel)) testLog2HalfHalf(half inV) {
+    return log2(inV);
+}
+
+half2 __attribute__((kernel)) testLog2Half2Half2(half2 inV) {
+    return log2(inV);
+}
+
+half3 __attribute__((kernel)) testLog2Half3Half3(half3 inV) {
+    return log2(inV);
+}
+
+half4 __attribute__((kernel)) testLog2Half4Half4(half4 inV) {
+    return log2(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog2Relaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog2Relaxed.rs
index e3fc556..4ef603e 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog2Relaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog2Relaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLogRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLogRelaxed.rs
index 9664748..4cfbfcb 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLogRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLogRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLogb.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLogb.java
index b351a39..d641200 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLogb.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLogb.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeLogb(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeLogb(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeLogb(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeLogb(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkLogbHalfHalf() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x5c22463dl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testLogbHalfHalf(inV, out);
+            verifyResultsLogbHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLogbHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testLogbHalfHalf(inV, out);
+            verifyResultsLogbHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLogbHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLogbHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeLogb(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkLogbHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkLogbHalf2Half2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x1ac45cb7l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testLogbHalf2Half2(inV, out);
+            verifyResultsLogbHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLogbHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testLogbHalf2Half2(inV, out);
+            verifyResultsLogbHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLogbHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLogbHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeLogb(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkLogbHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkLogbHalf3Half3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x79cc21abl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testLogbHalf3Half3(inV, out);
+            verifyResultsLogbHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLogbHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testLogbHalf3Half3(inV, out);
+            verifyResultsLogbHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLogbHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLogbHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeLogb(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkLogbHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkLogbHalf4Half4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xd8d3e69fl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testLogbHalf4Half4(inV, out);
+            verifyResultsLogbHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLogbHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testLogbHalf4Half4(inV, out);
+            verifyResultsLogbHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLogbHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLogbHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeLogb(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkLogbHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testLogb() {
         checkLogbFloatFloat();
         checkLogbFloat2Float2();
         checkLogbFloat3Float3();
         checkLogbFloat4Float4();
+        checkLogbHalfHalf();
+        checkLogbHalf2Half2();
+        checkLogbHalf3Half3();
+        checkLogbHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLogb.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLogb.rs
index 40f012a..45cc762 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLogb.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLogb.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testLogbFloat4Float4(float4 inV) {
     return logb(inV);
 }
+
+half __attribute__((kernel)) testLogbHalfHalf(half inV) {
+    return logb(inV);
+}
+
+half2 __attribute__((kernel)) testLogbHalf2Half2(half2 inV) {
+    return logb(inV);
+}
+
+half3 __attribute__((kernel)) testLogbHalf3Half3(half3 inV) {
+    return logb(inV);
+}
+
+half4 __attribute__((kernel)) testLogbHalf4Half4(half4 inV) {
+    return logb(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLogbRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLogbRelaxed.rs
index 134e4b7..0318d40 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLogbRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLogbRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMad.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMad.java
index 05060fb..29e2828 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMad.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMad.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -90,7 +91,7 @@
                 args.inMultiplicand2 = arrayInMultiplicand2[i];
                 args.inOffset = arrayInOffset[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeMad(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -179,7 +180,7 @@
                 args.inMultiplicand2 = arrayInMultiplicand2[i * 2 + j];
                 args.inOffset = arrayInOffset[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeMad(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -268,7 +269,7 @@
                 args.inMultiplicand2 = arrayInMultiplicand2[i * 4 + j];
                 args.inOffset = arrayInOffset[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeMad(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -357,7 +358,7 @@
                 args.inMultiplicand2 = arrayInMultiplicand2[i * 4 + j];
                 args.inOffset = arrayInOffset[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeMad(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -399,10 +400,404 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalfHalfHalf {
+        public short inMultiplicand1;
+        public double inMultiplicand1Double;
+        public short inMultiplicand2;
+        public double inMultiplicand2Double;
+        public short inOffset;
+        public double inOffsetDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkMadHalfHalfHalfHalf() {
+        Allocation inMultiplicand1 = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xcfbe7d2cl, false);
+        Allocation inMultiplicand2 = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xcfbe7d2dl, false);
+        Allocation inOffset = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xfd6cfcc8l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.set_gAllocInMultiplicand2(inMultiplicand2);
+            script.set_gAllocInOffset(inOffset);
+            script.forEach_testMadHalfHalfHalfHalf(inMultiplicand1, out);
+            verifyResultsMadHalfHalfHalfHalf(inMultiplicand1, inMultiplicand2, inOffset, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMadHalfHalfHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMultiplicand2(inMultiplicand2);
+            scriptRelaxed.set_gAllocInOffset(inOffset);
+            scriptRelaxed.forEach_testMadHalfHalfHalfHalf(inMultiplicand1, out);
+            verifyResultsMadHalfHalfHalfHalf(inMultiplicand1, inMultiplicand2, inOffset, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMadHalfHalfHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMadHalfHalfHalfHalf(Allocation inMultiplicand1, Allocation inMultiplicand2, Allocation inOffset, Allocation out, boolean relaxed) {
+        short[] arrayInMultiplicand1 = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInMultiplicand1, (short) 42);
+        inMultiplicand1.copyTo(arrayInMultiplicand1);
+        short[] arrayInMultiplicand2 = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInMultiplicand2, (short) 42);
+        inMultiplicand2.copyTo(arrayInMultiplicand2);
+        short[] arrayInOffset = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInOffset, (short) 42);
+        inOffset.copyTo(arrayInOffset);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalfHalf args = new ArgumentsHalfHalfHalfHalf();
+                args.inMultiplicand1 = arrayInMultiplicand1[i];
+                args.inMultiplicand1Double = Float16Utils.convertFloat16ToDouble(args.inMultiplicand1);
+                args.inMultiplicand2 = arrayInMultiplicand2[i];
+                args.inMultiplicand2Double = Float16Utils.convertFloat16ToDouble(args.inMultiplicand2);
+                args.inOffset = arrayInOffset[i];
+                args.inOffsetDouble = Float16Utils.convertFloat16ToDouble(args.inOffset);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeMad(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inMultiplicand1: ");
+                        appendVariableToMessage(message, args.inMultiplicand1);
+                        message.append("\n");
+                        message.append("Input inMultiplicand2: ");
+                        appendVariableToMessage(message, args.inMultiplicand2);
+                        message.append("\n");
+                        message.append("Input inOffset: ");
+                        appendVariableToMessage(message, args.inOffset);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkMadHalfHalfHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMadHalf2Half2Half2Half2() {
+        Allocation inMultiplicand1 = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xe9fc79e0l, false);
+        Allocation inMultiplicand2 = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xe9fc79e1l, false);
+        Allocation inOffset = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xdeb2c084l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.set_gAllocInMultiplicand2(inMultiplicand2);
+            script.set_gAllocInOffset(inOffset);
+            script.forEach_testMadHalf2Half2Half2Half2(inMultiplicand1, out);
+            verifyResultsMadHalf2Half2Half2Half2(inMultiplicand1, inMultiplicand2, inOffset, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMadHalf2Half2Half2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMultiplicand2(inMultiplicand2);
+            scriptRelaxed.set_gAllocInOffset(inOffset);
+            scriptRelaxed.forEach_testMadHalf2Half2Half2Half2(inMultiplicand1, out);
+            verifyResultsMadHalf2Half2Half2Half2(inMultiplicand1, inMultiplicand2, inOffset, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMadHalf2Half2Half2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMadHalf2Half2Half2Half2(Allocation inMultiplicand1, Allocation inMultiplicand2, Allocation inOffset, Allocation out, boolean relaxed) {
+        short[] arrayInMultiplicand1 = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInMultiplicand1, (short) 42);
+        inMultiplicand1.copyTo(arrayInMultiplicand1);
+        short[] arrayInMultiplicand2 = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInMultiplicand2, (short) 42);
+        inMultiplicand2.copyTo(arrayInMultiplicand2);
+        short[] arrayInOffset = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInOffset, (short) 42);
+        inOffset.copyTo(arrayInOffset);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalfHalf args = new ArgumentsHalfHalfHalfHalf();
+                args.inMultiplicand1 = arrayInMultiplicand1[i * 2 + j];
+                args.inMultiplicand1Double = Float16Utils.convertFloat16ToDouble(args.inMultiplicand1);
+                args.inMultiplicand2 = arrayInMultiplicand2[i * 2 + j];
+                args.inMultiplicand2Double = Float16Utils.convertFloat16ToDouble(args.inMultiplicand2);
+                args.inOffset = arrayInOffset[i * 2 + j];
+                args.inOffsetDouble = Float16Utils.convertFloat16ToDouble(args.inOffset);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeMad(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inMultiplicand1: ");
+                        appendVariableToMessage(message, args.inMultiplicand1);
+                        message.append("\n");
+                        message.append("Input inMultiplicand2: ");
+                        appendVariableToMessage(message, args.inMultiplicand2);
+                        message.append("\n");
+                        message.append("Input inOffset: ");
+                        appendVariableToMessage(message, args.inOffset);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkMadHalf2Half2Half2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMadHalf3Half3Half3Half3() {
+        Allocation inMultiplicand1 = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0xd5500128l, false);
+        Allocation inMultiplicand2 = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0xd5500129l, false);
+        Allocation inOffset = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x2979209cl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.set_gAllocInMultiplicand2(inMultiplicand2);
+            script.set_gAllocInOffset(inOffset);
+            script.forEach_testMadHalf3Half3Half3Half3(inMultiplicand1, out);
+            verifyResultsMadHalf3Half3Half3Half3(inMultiplicand1, inMultiplicand2, inOffset, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMadHalf3Half3Half3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMultiplicand2(inMultiplicand2);
+            scriptRelaxed.set_gAllocInOffset(inOffset);
+            scriptRelaxed.forEach_testMadHalf3Half3Half3Half3(inMultiplicand1, out);
+            verifyResultsMadHalf3Half3Half3Half3(inMultiplicand1, inMultiplicand2, inOffset, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMadHalf3Half3Half3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMadHalf3Half3Half3Half3(Allocation inMultiplicand1, Allocation inMultiplicand2, Allocation inOffset, Allocation out, boolean relaxed) {
+        short[] arrayInMultiplicand1 = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInMultiplicand1, (short) 42);
+        inMultiplicand1.copyTo(arrayInMultiplicand1);
+        short[] arrayInMultiplicand2 = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInMultiplicand2, (short) 42);
+        inMultiplicand2.copyTo(arrayInMultiplicand2);
+        short[] arrayInOffset = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInOffset, (short) 42);
+        inOffset.copyTo(arrayInOffset);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalfHalf args = new ArgumentsHalfHalfHalfHalf();
+                args.inMultiplicand1 = arrayInMultiplicand1[i * 4 + j];
+                args.inMultiplicand1Double = Float16Utils.convertFloat16ToDouble(args.inMultiplicand1);
+                args.inMultiplicand2 = arrayInMultiplicand2[i * 4 + j];
+                args.inMultiplicand2Double = Float16Utils.convertFloat16ToDouble(args.inMultiplicand2);
+                args.inOffset = arrayInOffset[i * 4 + j];
+                args.inOffsetDouble = Float16Utils.convertFloat16ToDouble(args.inOffset);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeMad(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inMultiplicand1: ");
+                        appendVariableToMessage(message, args.inMultiplicand1);
+                        message.append("\n");
+                        message.append("Input inMultiplicand2: ");
+                        appendVariableToMessage(message, args.inMultiplicand2);
+                        message.append("\n");
+                        message.append("Input inOffset: ");
+                        appendVariableToMessage(message, args.inOffset);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkMadHalf3Half3Half3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMadHalf4Half4Half4Half4() {
+        Allocation inMultiplicand1 = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xc0a38870l, false);
+        Allocation inMultiplicand2 = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xc0a38871l, false);
+        Allocation inOffset = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x743f80b4l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.set_gAllocInMultiplicand2(inMultiplicand2);
+            script.set_gAllocInOffset(inOffset);
+            script.forEach_testMadHalf4Half4Half4Half4(inMultiplicand1, out);
+            verifyResultsMadHalf4Half4Half4Half4(inMultiplicand1, inMultiplicand2, inOffset, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMadHalf4Half4Half4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMultiplicand2(inMultiplicand2);
+            scriptRelaxed.set_gAllocInOffset(inOffset);
+            scriptRelaxed.forEach_testMadHalf4Half4Half4Half4(inMultiplicand1, out);
+            verifyResultsMadHalf4Half4Half4Half4(inMultiplicand1, inMultiplicand2, inOffset, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMadHalf4Half4Half4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMadHalf4Half4Half4Half4(Allocation inMultiplicand1, Allocation inMultiplicand2, Allocation inOffset, Allocation out, boolean relaxed) {
+        short[] arrayInMultiplicand1 = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInMultiplicand1, (short) 42);
+        inMultiplicand1.copyTo(arrayInMultiplicand1);
+        short[] arrayInMultiplicand2 = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInMultiplicand2, (short) 42);
+        inMultiplicand2.copyTo(arrayInMultiplicand2);
+        short[] arrayInOffset = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInOffset, (short) 42);
+        inOffset.copyTo(arrayInOffset);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalfHalf args = new ArgumentsHalfHalfHalfHalf();
+                args.inMultiplicand1 = arrayInMultiplicand1[i * 4 + j];
+                args.inMultiplicand1Double = Float16Utils.convertFloat16ToDouble(args.inMultiplicand1);
+                args.inMultiplicand2 = arrayInMultiplicand2[i * 4 + j];
+                args.inMultiplicand2Double = Float16Utils.convertFloat16ToDouble(args.inMultiplicand2);
+                args.inOffset = arrayInOffset[i * 4 + j];
+                args.inOffsetDouble = Float16Utils.convertFloat16ToDouble(args.inOffset);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeMad(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inMultiplicand1: ");
+                        appendVariableToMessage(message, args.inMultiplicand1);
+                        message.append("\n");
+                        message.append("Input inMultiplicand2: ");
+                        appendVariableToMessage(message, args.inMultiplicand2);
+                        message.append("\n");
+                        message.append("Input inOffset: ");
+                        appendVariableToMessage(message, args.inOffset);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkMadHalf4Half4Half4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testMad() {
         checkMadFloatFloatFloatFloat();
         checkMadFloat2Float2Float2Float2();
         checkMadFloat3Float3Float3Float3();
         checkMadFloat4Float4Float4Float4();
+        checkMadHalfHalfHalfHalf();
+        checkMadHalf2Half2Half2Half2();
+        checkMadHalf3Half3Half3Half3();
+        checkMadHalf4Half4Half4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMad.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMad.rs
index aee9b23..8131cf9 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMad.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMad.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -45,3 +45,27 @@
     float4 inOffset = rsGetElementAt_float4(gAllocInOffset, x);
     return mad(inMultiplicand1, inMultiplicand2, inOffset);
 }
+
+half __attribute__((kernel)) testMadHalfHalfHalfHalf(half inMultiplicand1, unsigned int x) {
+    half inMultiplicand2 = rsGetElementAt_half(gAllocInMultiplicand2, x);
+    half inOffset = rsGetElementAt_half(gAllocInOffset, x);
+    return mad(inMultiplicand1, inMultiplicand2, inOffset);
+}
+
+half2 __attribute__((kernel)) testMadHalf2Half2Half2Half2(half2 inMultiplicand1, unsigned int x) {
+    half2 inMultiplicand2 = rsGetElementAt_half2(gAllocInMultiplicand2, x);
+    half2 inOffset = rsGetElementAt_half2(gAllocInOffset, x);
+    return mad(inMultiplicand1, inMultiplicand2, inOffset);
+}
+
+half3 __attribute__((kernel)) testMadHalf3Half3Half3Half3(half3 inMultiplicand1, unsigned int x) {
+    half3 inMultiplicand2 = rsGetElementAt_half3(gAllocInMultiplicand2, x);
+    half3 inOffset = rsGetElementAt_half3(gAllocInOffset, x);
+    return mad(inMultiplicand1, inMultiplicand2, inOffset);
+}
+
+half4 __attribute__((kernel)) testMadHalf4Half4Half4Half4(half4 inMultiplicand1, unsigned int x) {
+    half4 inMultiplicand2 = rsGetElementAt_half4(gAllocInMultiplicand2, x);
+    half4 inOffset = rsGetElementAt_half4(gAllocInOffset, x);
+    return mad(inMultiplicand1, inMultiplicand2, inOffset);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMadRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMadRelaxed.rs
index a5e9a97..f157e6e 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMadRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMadRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMax.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMax.java
index 961dafa..f01f791 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMax.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMax.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -82,7 +83,7 @@
                 args.inA = arrayInA[i];
                 args.inB = arrayInB[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeMax(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -161,7 +162,7 @@
                 args.inA = arrayInA[i * 2 + j];
                 args.inB = arrayInB[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeMax(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -240,7 +241,7 @@
                 args.inA = arrayInA[i * 4 + j];
                 args.inB = arrayInB[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeMax(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -319,7 +320,7 @@
                 args.inA = arrayInA[i * 4 + j];
                 args.inB = arrayInB[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeMax(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -358,6 +359,350 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalfHalf {
+        public short inA;
+        public double inADouble;
+        public short inB;
+        public double inBDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkMaxHalfHalfHalf() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xb6e25ddbl, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xb6e25ddcl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMaxHalfHalfHalf(inA, out);
+            verifyResultsMaxHalfHalfHalf(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxHalfHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMaxHalfHalfHalf(inA, out);
+            verifyResultsMaxHalfHalfHalf(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxHalfHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxHalfHalfHalf(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        short[] arrayInA = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInA, (short) 42);
+        inA.copyTo(arrayInA);
+        short[] arrayInB = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInB, (short) 42);
+        inB.copyTo(arrayInB);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inA = arrayInA[i];
+                args.inADouble = Float16Utils.convertFloat16ToDouble(args.inA);
+                args.inB = arrayInB[i];
+                args.inBDouble = Float16Utils.convertFloat16ToDouble(args.inB);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeMax(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inA: ");
+                        appendVariableToMessage(message, args.inA);
+                        message.append("\n");
+                        message.append("Input inB: ");
+                        appendVariableToMessage(message, args.inB);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkMaxHalfHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMaxHalf2Half2Half2() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xf8fc6855l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xf8fc6856l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMaxHalf2Half2Half2(inA, out);
+            verifyResultsMaxHalf2Half2Half2(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxHalf2Half2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMaxHalf2Half2Half2(inA, out);
+            verifyResultsMaxHalf2Half2Half2(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxHalf2Half2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxHalf2Half2Half2(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        short[] arrayInA = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInA, (short) 42);
+        inA.copyTo(arrayInA);
+        short[] arrayInB = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInB, (short) 42);
+        inB.copyTo(arrayInB);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inA = arrayInA[i * 2 + j];
+                args.inADouble = Float16Utils.convertFloat16ToDouble(args.inA);
+                args.inB = arrayInB[i * 2 + j];
+                args.inBDouble = Float16Utils.convertFloat16ToDouble(args.inB);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeMax(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inA: ");
+                        appendVariableToMessage(message, args.inA);
+                        message.append("\n");
+                        message.append("Input inB: ");
+                        appendVariableToMessage(message, args.inB);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkMaxHalf2Half2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMaxHalf3Half3Half3() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x579b7924l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x579b7925l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMaxHalf3Half3Half3(inA, out);
+            verifyResultsMaxHalf3Half3Half3(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxHalf3Half3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMaxHalf3Half3Half3(inA, out);
+            verifyResultsMaxHalf3Half3Half3(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxHalf3Half3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxHalf3Half3Half3(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        short[] arrayInA = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInA, (short) 42);
+        inA.copyTo(arrayInA);
+        short[] arrayInB = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInB, (short) 42);
+        inB.copyTo(arrayInB);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inA = arrayInA[i * 4 + j];
+                args.inADouble = Float16Utils.convertFloat16ToDouble(args.inA);
+                args.inB = arrayInB[i * 4 + j];
+                args.inBDouble = Float16Utils.convertFloat16ToDouble(args.inB);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeMax(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inA: ");
+                        appendVariableToMessage(message, args.inA);
+                        message.append("\n");
+                        message.append("Input inB: ");
+                        appendVariableToMessage(message, args.inB);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkMaxHalf3Half3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMaxHalf4Half4Half4() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xb63a89f3l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xb63a89f4l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMaxHalf4Half4Half4(inA, out);
+            verifyResultsMaxHalf4Half4Half4(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxHalf4Half4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMaxHalf4Half4Half4(inA, out);
+            verifyResultsMaxHalf4Half4Half4(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxHalf4Half4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxHalf4Half4Half4(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        short[] arrayInA = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInA, (short) 42);
+        inA.copyTo(arrayInA);
+        short[] arrayInB = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInB, (short) 42);
+        inB.copyTo(arrayInB);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inA = arrayInA[i * 4 + j];
+                args.inADouble = Float16Utils.convertFloat16ToDouble(args.inA);
+                args.inB = arrayInB[i * 4 + j];
+                args.inBDouble = Float16Utils.convertFloat16ToDouble(args.inB);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeMax(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inA: ");
+                        appendVariableToMessage(message, args.inA);
+                        message.append("\n");
+                        message.append("Input inB: ");
+                        appendVariableToMessage(message, args.inB);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkMaxHalf4Half4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     private void checkMaxFloat2FloatFloat2() {
         Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x8592438l, false);
         Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x8592439l, false);
@@ -381,11 +726,16 @@
 
     private void verifyResultsMaxFloat2FloatFloat2(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
         float[] arrayInA = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInA, (float) 42);
         inA.copyTo(arrayInA);
         float[] arrayInB = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInB, (float) 42);
         inB.copyTo(arrayInB);
         float[] arrayOut = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (float) 42);
         out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
         for (int i = 0; i < INPUTSIZE; i++) {
             for (int j = 0; j < 2 ; j++) {
                 // Extract the inputs.
@@ -393,7 +743,7 @@
                 args.inA = arrayInA[i * 2 + j];
                 args.inB = arrayInB[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeMax(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -401,27 +751,35 @@
                     valid = false;
                 }
                 if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inA: ");
-                    appendVariableToMessage(message, args.inA);
-                    message.append("\n");
-                    message.append("Input inB: ");
-                    appendVariableToMessage(message, args.inB);
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    appendVariableToMessage(message, args.out);
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    appendVariableToMessage(message, arrayOut[i * 2 + j]);
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inA: ");
+                        appendVariableToMessage(message, args.inA);
+                        message.append("\n");
+                        message.append("Input inB: ");
+                        appendVariableToMessage(message, args.inB);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
                     }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMaxFloat2FloatFloat2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
                 }
             }
         }
+        assertFalse("Incorrect output for checkMaxFloat2FloatFloat2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
     private void checkMaxFloat3FloatFloat3() {
@@ -447,11 +805,16 @@
 
     private void verifyResultsMaxFloat3FloatFloat3(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
         float[] arrayInA = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInA, (float) 42);
         inA.copyTo(arrayInA);
         float[] arrayInB = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInB, (float) 42);
         inB.copyTo(arrayInB);
         float[] arrayOut = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (float) 42);
         out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
         for (int i = 0; i < INPUTSIZE; i++) {
             for (int j = 0; j < 3 ; j++) {
                 // Extract the inputs.
@@ -459,7 +822,7 @@
                 args.inA = arrayInA[i * 4 + j];
                 args.inB = arrayInB[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeMax(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -467,27 +830,35 @@
                     valid = false;
                 }
                 if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inA: ");
-                    appendVariableToMessage(message, args.inA);
-                    message.append("\n");
-                    message.append("Input inB: ");
-                    appendVariableToMessage(message, args.inB);
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    appendVariableToMessage(message, args.out);
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    appendVariableToMessage(message, arrayOut[i * 4 + j]);
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inA: ");
+                        appendVariableToMessage(message, args.inA);
+                        message.append("\n");
+                        message.append("Input inB: ");
+                        appendVariableToMessage(message, args.inB);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
                     }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMaxFloat3FloatFloat3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
                 }
             }
         }
+        assertFalse("Incorrect output for checkMaxFloat3FloatFloat3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
     private void checkMaxFloat4FloatFloat4() {
@@ -513,11 +884,16 @@
 
     private void verifyResultsMaxFloat4FloatFloat4(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
         float[] arrayInA = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInA, (float) 42);
         inA.copyTo(arrayInA);
         float[] arrayInB = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInB, (float) 42);
         inB.copyTo(arrayInB);
         float[] arrayOut = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (float) 42);
         out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
         for (int i = 0; i < INPUTSIZE; i++) {
             for (int j = 0; j < 4 ; j++) {
                 // Extract the inputs.
@@ -525,7 +901,7 @@
                 args.inA = arrayInA[i * 4 + j];
                 args.inB = arrayInB[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeMax(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -533,27 +909,287 @@
                     valid = false;
                 }
                 if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inA: ");
-                    appendVariableToMessage(message, args.inA);
-                    message.append("\n");
-                    message.append("Input inB: ");
-                    appendVariableToMessage(message, args.inB);
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    appendVariableToMessage(message, args.out);
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    appendVariableToMessage(message, arrayOut[i * 4 + j]);
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inA: ");
+                        appendVariableToMessage(message, args.inA);
+                        message.append("\n");
+                        message.append("Input inB: ");
+                        appendVariableToMessage(message, args.inB);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
                     }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMaxFloat4FloatFloat4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
                 }
             }
         }
+        assertFalse("Incorrect output for checkMaxFloat4FloatFloat4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMaxHalf2HalfHalf2() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xf5bbc96fl, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xf5bbc970l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMaxHalf2HalfHalf2(inA, out);
+            verifyResultsMaxHalf2HalfHalf2(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxHalf2HalfHalf2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMaxHalf2HalfHalf2(inA, out);
+            verifyResultsMaxHalf2HalfHalf2(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxHalf2HalfHalf2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxHalf2HalfHalf2(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        short[] arrayInA = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInA, (short) 42);
+        inA.copyTo(arrayInA);
+        short[] arrayInB = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInB, (short) 42);
+        inB.copyTo(arrayInB);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inA = arrayInA[i * 2 + j];
+                args.inADouble = Float16Utils.convertFloat16ToDouble(args.inA);
+                args.inB = arrayInB[i];
+                args.inBDouble = Float16Utils.convertFloat16ToDouble(args.inB);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeMax(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inA: ");
+                        appendVariableToMessage(message, args.inA);
+                        message.append("\n");
+                        message.append("Input inB: ");
+                        appendVariableToMessage(message, args.inB);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkMaxHalf2HalfHalf2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMaxHalf3HalfHalf3() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0xa8555b13l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xa8555b14l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMaxHalf3HalfHalf3(inA, out);
+            verifyResultsMaxHalf3HalfHalf3(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxHalf3HalfHalf3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMaxHalf3HalfHalf3(inA, out);
+            verifyResultsMaxHalf3HalfHalf3(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxHalf3HalfHalf3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxHalf3HalfHalf3(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        short[] arrayInA = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInA, (short) 42);
+        inA.copyTo(arrayInA);
+        short[] arrayInB = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInB, (short) 42);
+        inB.copyTo(arrayInB);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inA = arrayInA[i * 4 + j];
+                args.inADouble = Float16Utils.convertFloat16ToDouble(args.inA);
+                args.inB = arrayInB[i];
+                args.inBDouble = Float16Utils.convertFloat16ToDouble(args.inB);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeMax(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inA: ");
+                        appendVariableToMessage(message, args.inA);
+                        message.append("\n");
+                        message.append("Input inB: ");
+                        appendVariableToMessage(message, args.inB);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkMaxHalf3HalfHalf3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMaxHalf4HalfHalf4() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x5aeeecb7l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x5aeeecb8l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMaxHalf4HalfHalf4(inA, out);
+            verifyResultsMaxHalf4HalfHalf4(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxHalf4HalfHalf4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMaxHalf4HalfHalf4(inA, out);
+            verifyResultsMaxHalf4HalfHalf4(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxHalf4HalfHalf4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxHalf4HalfHalf4(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        short[] arrayInA = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInA, (short) 42);
+        inA.copyTo(arrayInA);
+        short[] arrayInB = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInB, (short) 42);
+        inB.copyTo(arrayInB);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inA = arrayInA[i * 4 + j];
+                args.inADouble = Float16Utils.convertFloat16ToDouble(args.inA);
+                args.inB = arrayInB[i];
+                args.inBDouble = Float16Utils.convertFloat16ToDouble(args.inB);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeMax(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inA: ");
+                        appendVariableToMessage(message, args.inA);
+                        message.append("\n");
+                        message.append("Input inB: ");
+                        appendVariableToMessage(message, args.inB);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkMaxHalf4HalfHalf4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
     public class ArgumentsCharCharChar {
@@ -3105,9 +3741,16 @@
         checkMaxFloat2Float2Float2();
         checkMaxFloat3Float3Float3();
         checkMaxFloat4Float4Float4();
+        checkMaxHalfHalfHalf();
+        checkMaxHalf2Half2Half2();
+        checkMaxHalf3Half3Half3();
+        checkMaxHalf4Half4Half4();
         checkMaxFloat2FloatFloat2();
         checkMaxFloat3FloatFloat3();
         checkMaxFloat4FloatFloat4();
+        checkMaxHalf2HalfHalf2();
+        checkMaxHalf3HalfHalf3();
+        checkMaxHalf4HalfHalf4();
         checkMaxCharCharChar();
         checkMaxChar2Char2Char2();
         checkMaxChar3Char3Char3();
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMax.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMax.rs
index a9ca895..ae1e739 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMax.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMax.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -41,6 +41,26 @@
     return max(inA, inB);
 }
 
+half __attribute__((kernel)) testMaxHalfHalfHalf(half inA, unsigned int x) {
+    half inB = rsGetElementAt_half(gAllocInB, x);
+    return max(inA, inB);
+}
+
+half2 __attribute__((kernel)) testMaxHalf2Half2Half2(half2 inA, unsigned int x) {
+    half2 inB = rsGetElementAt_half2(gAllocInB, x);
+    return max(inA, inB);
+}
+
+half3 __attribute__((kernel)) testMaxHalf3Half3Half3(half3 inA, unsigned int x) {
+    half3 inB = rsGetElementAt_half3(gAllocInB, x);
+    return max(inA, inB);
+}
+
+half4 __attribute__((kernel)) testMaxHalf4Half4Half4(half4 inA, unsigned int x) {
+    half4 inB = rsGetElementAt_half4(gAllocInB, x);
+    return max(inA, inB);
+}
+
 float2 __attribute__((kernel)) testMaxFloat2FloatFloat2(float2 inA, unsigned int x) {
     float inB = rsGetElementAt_float(gAllocInB, x);
     return max(inA, inB);
@@ -56,6 +76,21 @@
     return max(inA, inB);
 }
 
+half2 __attribute__((kernel)) testMaxHalf2HalfHalf2(half2 inA, unsigned int x) {
+    half inB = rsGetElementAt_half(gAllocInB, x);
+    return max(inA, inB);
+}
+
+half3 __attribute__((kernel)) testMaxHalf3HalfHalf3(half3 inA, unsigned int x) {
+    half inB = rsGetElementAt_half(gAllocInB, x);
+    return max(inA, inB);
+}
+
+half4 __attribute__((kernel)) testMaxHalf4HalfHalf4(half4 inA, unsigned int x) {
+    half inB = rsGetElementAt_half(gAllocInB, x);
+    return max(inA, inB);
+}
+
 char __attribute__((kernel)) testMaxCharCharChar(char inA, unsigned int x) {
     char inB = rsGetElementAt_char(gAllocInB, x);
     return max(inA, inB);
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMaxRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMaxRelaxed.rs
index 2f3fecc..1f37a5e 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMaxRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMaxRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMin.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMin.java
index f71fac8..c806d18 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMin.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMin.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -82,7 +83,7 @@
                 args.inA = arrayInA[i];
                 args.inB = arrayInB[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeMin(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -161,7 +162,7 @@
                 args.inA = arrayInA[i * 2 + j];
                 args.inB = arrayInB[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeMin(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -240,7 +241,7 @@
                 args.inA = arrayInA[i * 4 + j];
                 args.inB = arrayInB[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeMin(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -319,7 +320,7 @@
                 args.inA = arrayInA[i * 4 + j];
                 args.inB = arrayInB[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeMin(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -358,6 +359,350 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalfHalf {
+        public short inA;
+        public double inADouble;
+        public short inB;
+        public double inBDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkMinHalfHalfHalf() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xf239c45l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xf239c46l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMinHalfHalfHalf(inA, out);
+            verifyResultsMinHalfHalfHalf(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinHalfHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMinHalfHalfHalf(inA, out);
+            verifyResultsMinHalfHalfHalf(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinHalfHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinHalfHalfHalf(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        short[] arrayInA = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInA, (short) 42);
+        inA.copyTo(arrayInA);
+        short[] arrayInB = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInB, (short) 42);
+        inB.copyTo(arrayInB);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inA = arrayInA[i];
+                args.inADouble = Float16Utils.convertFloat16ToDouble(args.inA);
+                args.inB = arrayInB[i];
+                args.inBDouble = Float16Utils.convertFloat16ToDouble(args.inB);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeMin(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inA: ");
+                        appendVariableToMessage(message, args.inA);
+                        message.append("\n");
+                        message.append("Input inB: ");
+                        appendVariableToMessage(message, args.inB);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkMinHalfHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMinHalf2Half2Half2() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xa8079b33l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xa8079b34l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMinHalf2Half2Half2(inA, out);
+            verifyResultsMinHalf2Half2Half2(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinHalf2Half2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMinHalf2Half2Half2(inA, out);
+            verifyResultsMinHalf2Half2Half2(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinHalf2Half2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinHalf2Half2Half2(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        short[] arrayInA = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInA, (short) 42);
+        inA.copyTo(arrayInA);
+        short[] arrayInB = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInB, (short) 42);
+        inB.copyTo(arrayInB);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inA = arrayInA[i * 2 + j];
+                args.inADouble = Float16Utils.convertFloat16ToDouble(args.inA);
+                args.inB = arrayInB[i * 2 + j];
+                args.inBDouble = Float16Utils.convertFloat16ToDouble(args.inB);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeMin(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inA: ");
+                        appendVariableToMessage(message, args.inA);
+                        message.append("\n");
+                        message.append("Input inB: ");
+                        appendVariableToMessage(message, args.inB);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkMinHalf2Half2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMinHalf3Half3Half3() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x6a6ac02l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x6a6ac03l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMinHalf3Half3Half3(inA, out);
+            verifyResultsMinHalf3Half3Half3(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinHalf3Half3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMinHalf3Half3Half3(inA, out);
+            verifyResultsMinHalf3Half3Half3(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinHalf3Half3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinHalf3Half3Half3(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        short[] arrayInA = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInA, (short) 42);
+        inA.copyTo(arrayInA);
+        short[] arrayInB = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInB, (short) 42);
+        inB.copyTo(arrayInB);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inA = arrayInA[i * 4 + j];
+                args.inADouble = Float16Utils.convertFloat16ToDouble(args.inA);
+                args.inB = arrayInB[i * 4 + j];
+                args.inBDouble = Float16Utils.convertFloat16ToDouble(args.inB);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeMin(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inA: ");
+                        appendVariableToMessage(message, args.inA);
+                        message.append("\n");
+                        message.append("Input inB: ");
+                        appendVariableToMessage(message, args.inB);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkMinHalf3Half3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMinHalf4Half4Half4() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x6545bcd1l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x6545bcd2l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMinHalf4Half4Half4(inA, out);
+            verifyResultsMinHalf4Half4Half4(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinHalf4Half4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMinHalf4Half4Half4(inA, out);
+            verifyResultsMinHalf4Half4Half4(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinHalf4Half4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinHalf4Half4Half4(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        short[] arrayInA = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInA, (short) 42);
+        inA.copyTo(arrayInA);
+        short[] arrayInB = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInB, (short) 42);
+        inB.copyTo(arrayInB);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inA = arrayInA[i * 4 + j];
+                args.inADouble = Float16Utils.convertFloat16ToDouble(args.inA);
+                args.inB = arrayInB[i * 4 + j];
+                args.inBDouble = Float16Utils.convertFloat16ToDouble(args.inB);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeMin(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inA: ");
+                        appendVariableToMessage(message, args.inA);
+                        message.append("\n");
+                        message.append("Input inB: ");
+                        appendVariableToMessage(message, args.inB);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkMinHalf4Half4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     private void checkMinFloat2FloatFloat2() {
         Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x503b89a6l, false);
         Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x503b89a7l, false);
@@ -381,11 +726,16 @@
 
     private void verifyResultsMinFloat2FloatFloat2(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
         float[] arrayInA = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInA, (float) 42);
         inA.copyTo(arrayInA);
         float[] arrayInB = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInB, (float) 42);
         inB.copyTo(arrayInB);
         float[] arrayOut = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (float) 42);
         out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
         for (int i = 0; i < INPUTSIZE; i++) {
             for (int j = 0; j < 2 ; j++) {
                 // Extract the inputs.
@@ -393,7 +743,7 @@
                 args.inA = arrayInA[i * 2 + j];
                 args.inB = arrayInB[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeMin(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -401,27 +751,35 @@
                     valid = false;
                 }
                 if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inA: ");
-                    appendVariableToMessage(message, args.inA);
-                    message.append("\n");
-                    message.append("Input inB: ");
-                    appendVariableToMessage(message, args.inB);
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    appendVariableToMessage(message, args.out);
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    appendVariableToMessage(message, arrayOut[i * 2 + j]);
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inA: ");
+                        appendVariableToMessage(message, args.inA);
+                        message.append("\n");
+                        message.append("Input inB: ");
+                        appendVariableToMessage(message, args.inB);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
                     }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMinFloat2FloatFloat2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
                 }
             }
         }
+        assertFalse("Incorrect output for checkMinFloat2FloatFloat2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
     private void checkMinFloat3FloatFloat3() {
@@ -447,11 +805,16 @@
 
     private void verifyResultsMinFloat3FloatFloat3(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
         float[] arrayInA = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInA, (float) 42);
         inA.copyTo(arrayInA);
         float[] arrayInB = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInB, (float) 42);
         inB.copyTo(arrayInB);
         float[] arrayOut = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (float) 42);
         out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
         for (int i = 0; i < INPUTSIZE; i++) {
             for (int j = 0; j < 3 ; j++) {
                 // Extract the inputs.
@@ -459,7 +822,7 @@
                 args.inA = arrayInA[i * 4 + j];
                 args.inB = arrayInB[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeMin(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -467,27 +830,35 @@
                     valid = false;
                 }
                 if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inA: ");
-                    appendVariableToMessage(message, args.inA);
-                    message.append("\n");
-                    message.append("Input inB: ");
-                    appendVariableToMessage(message, args.inB);
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    appendVariableToMessage(message, args.out);
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    appendVariableToMessage(message, arrayOut[i * 4 + j]);
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inA: ");
+                        appendVariableToMessage(message, args.inA);
+                        message.append("\n");
+                        message.append("Input inB: ");
+                        appendVariableToMessage(message, args.inB);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
                     }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMinFloat3FloatFloat3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
                 }
             }
         }
+        assertFalse("Incorrect output for checkMinFloat3FloatFloat3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
     private void checkMinFloat4FloatFloat4() {
@@ -513,11 +884,16 @@
 
     private void verifyResultsMinFloat4FloatFloat4(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
         float[] arrayInA = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInA, (float) 42);
         inA.copyTo(arrayInA);
         float[] arrayInB = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInB, (float) 42);
         inB.copyTo(arrayInB);
         float[] arrayOut = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (float) 42);
         out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
         for (int i = 0; i < INPUTSIZE; i++) {
             for (int j = 0; j < 4 ; j++) {
                 // Extract the inputs.
@@ -525,7 +901,7 @@
                 args.inA = arrayInA[i * 4 + j];
                 args.inB = arrayInB[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeMin(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -533,27 +909,287 @@
                     valid = false;
                 }
                 if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inA: ");
-                    appendVariableToMessage(message, args.inA);
-                    message.append("\n");
-                    message.append("Input inB: ");
-                    appendVariableToMessage(message, args.inB);
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    appendVariableToMessage(message, args.out);
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    appendVariableToMessage(message, arrayOut[i * 4 + j]);
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inA: ");
+                        appendVariableToMessage(message, args.inA);
+                        message.append("\n");
+                        message.append("Input inB: ");
+                        appendVariableToMessage(message, args.inB);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
                     }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMinFloat4FloatFloat4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
                 }
             }
         }
+        assertFalse("Incorrect output for checkMinFloat4FloatFloat4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMinHalf2HalfHalf2() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x64f79509l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x64f7950al, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMinHalf2HalfHalf2(inA, out);
+            verifyResultsMinHalf2HalfHalf2(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinHalf2HalfHalf2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMinHalf2HalfHalf2(inA, out);
+            verifyResultsMinHalf2HalfHalf2(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinHalf2HalfHalf2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinHalf2HalfHalf2(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        short[] arrayInA = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInA, (short) 42);
+        inA.copyTo(arrayInA);
+        short[] arrayInB = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInB, (short) 42);
+        inB.copyTo(arrayInB);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inA = arrayInA[i * 2 + j];
+                args.inADouble = Float16Utils.convertFloat16ToDouble(args.inA);
+                args.inB = arrayInB[i];
+                args.inBDouble = Float16Utils.convertFloat16ToDouble(args.inB);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeMin(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inA: ");
+                        appendVariableToMessage(message, args.inA);
+                        message.append("\n");
+                        message.append("Input inB: ");
+                        appendVariableToMessage(message, args.inB);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkMinHalf2HalfHalf2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMinHalf3HalfHalf3() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x179126adl, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x179126ael, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMinHalf3HalfHalf3(inA, out);
+            verifyResultsMinHalf3HalfHalf3(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinHalf3HalfHalf3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMinHalf3HalfHalf3(inA, out);
+            verifyResultsMinHalf3HalfHalf3(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinHalf3HalfHalf3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinHalf3HalfHalf3(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        short[] arrayInA = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInA, (short) 42);
+        inA.copyTo(arrayInA);
+        short[] arrayInB = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInB, (short) 42);
+        inB.copyTo(arrayInB);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inA = arrayInA[i * 4 + j];
+                args.inADouble = Float16Utils.convertFloat16ToDouble(args.inA);
+                args.inB = arrayInB[i];
+                args.inBDouble = Float16Utils.convertFloat16ToDouble(args.inB);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeMin(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inA: ");
+                        appendVariableToMessage(message, args.inA);
+                        message.append("\n");
+                        message.append("Input inB: ");
+                        appendVariableToMessage(message, args.inB);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkMinHalf3HalfHalf3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMinHalf4HalfHalf4() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xca2ab851l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xca2ab852l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMinHalf4HalfHalf4(inA, out);
+            verifyResultsMinHalf4HalfHalf4(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinHalf4HalfHalf4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMinHalf4HalfHalf4(inA, out);
+            verifyResultsMinHalf4HalfHalf4(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinHalf4HalfHalf4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinHalf4HalfHalf4(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        short[] arrayInA = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInA, (short) 42);
+        inA.copyTo(arrayInA);
+        short[] arrayInB = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInB, (short) 42);
+        inB.copyTo(arrayInB);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inA = arrayInA[i * 4 + j];
+                args.inADouble = Float16Utils.convertFloat16ToDouble(args.inA);
+                args.inB = arrayInB[i];
+                args.inBDouble = Float16Utils.convertFloat16ToDouble(args.inB);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeMin(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inA: ");
+                        appendVariableToMessage(message, args.inA);
+                        message.append("\n");
+                        message.append("Input inB: ");
+                        appendVariableToMessage(message, args.inB);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkMinHalf4HalfHalf4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
     public class ArgumentsCharCharChar {
@@ -3105,9 +3741,16 @@
         checkMinFloat2Float2Float2();
         checkMinFloat3Float3Float3();
         checkMinFloat4Float4Float4();
+        checkMinHalfHalfHalf();
+        checkMinHalf2Half2Half2();
+        checkMinHalf3Half3Half3();
+        checkMinHalf4Half4Half4();
         checkMinFloat2FloatFloat2();
         checkMinFloat3FloatFloat3();
         checkMinFloat4FloatFloat4();
+        checkMinHalf2HalfHalf2();
+        checkMinHalf3HalfHalf3();
+        checkMinHalf4HalfHalf4();
         checkMinCharCharChar();
         checkMinChar2Char2Char2();
         checkMinChar3Char3Char3();
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMin.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMin.rs
index dccff70..998f8c2 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMin.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMin.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -41,6 +41,26 @@
     return min(inA, inB);
 }
 
+half __attribute__((kernel)) testMinHalfHalfHalf(half inA, unsigned int x) {
+    half inB = rsGetElementAt_half(gAllocInB, x);
+    return min(inA, inB);
+}
+
+half2 __attribute__((kernel)) testMinHalf2Half2Half2(half2 inA, unsigned int x) {
+    half2 inB = rsGetElementAt_half2(gAllocInB, x);
+    return min(inA, inB);
+}
+
+half3 __attribute__((kernel)) testMinHalf3Half3Half3(half3 inA, unsigned int x) {
+    half3 inB = rsGetElementAt_half3(gAllocInB, x);
+    return min(inA, inB);
+}
+
+half4 __attribute__((kernel)) testMinHalf4Half4Half4(half4 inA, unsigned int x) {
+    half4 inB = rsGetElementAt_half4(gAllocInB, x);
+    return min(inA, inB);
+}
+
 float2 __attribute__((kernel)) testMinFloat2FloatFloat2(float2 inA, unsigned int x) {
     float inB = rsGetElementAt_float(gAllocInB, x);
     return min(inA, inB);
@@ -56,6 +76,21 @@
     return min(inA, inB);
 }
 
+half2 __attribute__((kernel)) testMinHalf2HalfHalf2(half2 inA, unsigned int x) {
+    half inB = rsGetElementAt_half(gAllocInB, x);
+    return min(inA, inB);
+}
+
+half3 __attribute__((kernel)) testMinHalf3HalfHalf3(half3 inA, unsigned int x) {
+    half inB = rsGetElementAt_half(gAllocInB, x);
+    return min(inA, inB);
+}
+
+half4 __attribute__((kernel)) testMinHalf4HalfHalf4(half4 inA, unsigned int x) {
+    half inB = rsGetElementAt_half(gAllocInB, x);
+    return min(inA, inB);
+}
+
 char __attribute__((kernel)) testMinCharCharChar(char inA, unsigned int x) {
     char inB = rsGetElementAt_char(gAllocInB, x);
     return min(inA, inB);
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMinRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMinRelaxed.rs
index 5c6564b..2a047af 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMinRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMinRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMix.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMix.java
index 8adfe99..7978f3a 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMix.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMix.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -90,7 +91,7 @@
                 args.inStop = arrayInStop[i];
                 args.inFraction = arrayInFraction[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeMix(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -179,7 +180,7 @@
                 args.inStop = arrayInStop[i * 2 + j];
                 args.inFraction = arrayInFraction[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeMix(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -268,7 +269,7 @@
                 args.inStop = arrayInStop[i * 4 + j];
                 args.inFraction = arrayInFraction[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeMix(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -357,7 +358,7 @@
                 args.inStop = arrayInStop[i * 4 + j];
                 args.inFraction = arrayInFraction[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeMix(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -399,6 +400,396 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalfHalfHalf {
+        public short inStart;
+        public double inStartDouble;
+        public short inStop;
+        public double inStopDouble;
+        public short inFraction;
+        public double inFractionDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkMixHalfHalfHalfHalf() {
+        Allocation inStart = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xa5c04055l, false);
+        Allocation inStop = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xbc69b07bl, false);
+        Allocation inFraction = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x4936a9cbl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.set_gAllocInStop(inStop);
+            script.set_gAllocInFraction(inFraction);
+            script.forEach_testMixHalfHalfHalfHalf(inStart, out);
+            verifyResultsMixHalfHalfHalfHalf(inStart, inStop, inFraction, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMixHalfHalfHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInStop(inStop);
+            scriptRelaxed.set_gAllocInFraction(inFraction);
+            scriptRelaxed.forEach_testMixHalfHalfHalfHalf(inStart, out);
+            verifyResultsMixHalfHalfHalfHalf(inStart, inStop, inFraction, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMixHalfHalfHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMixHalfHalfHalfHalf(Allocation inStart, Allocation inStop, Allocation inFraction, Allocation out, boolean relaxed) {
+        short[] arrayInStart = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInStart, (short) 42);
+        inStart.copyTo(arrayInStart);
+        short[] arrayInStop = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInStop, (short) 42);
+        inStop.copyTo(arrayInStop);
+        short[] arrayInFraction = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInFraction, (short) 42);
+        inFraction.copyTo(arrayInFraction);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalfHalf args = new ArgumentsHalfHalfHalfHalf();
+                args.inStart = arrayInStart[i];
+                args.inStartDouble = Float16Utils.convertFloat16ToDouble(args.inStart);
+                args.inStop = arrayInStop[i];
+                args.inStopDouble = Float16Utils.convertFloat16ToDouble(args.inStop);
+                args.inFraction = arrayInFraction[i];
+                args.inFractionDouble = Float16Utils.convertFloat16ToDouble(args.inFraction);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeMix(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inStart: ");
+                        appendVariableToMessage(message, args.inStart);
+                        message.append("\n");
+                        message.append("Input inStop: ");
+                        appendVariableToMessage(message, args.inStop);
+                        message.append("\n");
+                        message.append("Input inFraction: ");
+                        appendVariableToMessage(message, args.inFraction);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkMixHalfHalfHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMixHalf2Half2Half2Half2() {
+        Allocation inStart = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x2fe5c049l, false);
+        Allocation inStop = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x7114257l, false);
+        Allocation inFraction = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x5b09ae7l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.set_gAllocInStop(inStop);
+            script.set_gAllocInFraction(inFraction);
+            script.forEach_testMixHalf2Half2Half2Half2(inStart, out);
+            verifyResultsMixHalf2Half2Half2Half2(inStart, inStop, inFraction, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMixHalf2Half2Half2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInStop(inStop);
+            scriptRelaxed.set_gAllocInFraction(inFraction);
+            scriptRelaxed.forEach_testMixHalf2Half2Half2Half2(inStart, out);
+            verifyResultsMixHalf2Half2Half2Half2(inStart, inStop, inFraction, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMixHalf2Half2Half2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMixHalf2Half2Half2Half2(Allocation inStart, Allocation inStop, Allocation inFraction, Allocation out, boolean relaxed) {
+        short[] arrayInStart = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInStart, (short) 42);
+        inStart.copyTo(arrayInStart);
+        short[] arrayInStop = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInStop, (short) 42);
+        inStop.copyTo(arrayInStop);
+        short[] arrayInFraction = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInFraction, (short) 42);
+        inFraction.copyTo(arrayInFraction);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalfHalf args = new ArgumentsHalfHalfHalfHalf();
+                args.inStart = arrayInStart[i * 2 + j];
+                args.inStartDouble = Float16Utils.convertFloat16ToDouble(args.inStart);
+                args.inStop = arrayInStop[i * 2 + j];
+                args.inStopDouble = Float16Utils.convertFloat16ToDouble(args.inStop);
+                args.inFraction = arrayInFraction[i * 2 + j];
+                args.inFractionDouble = Float16Utils.convertFloat16ToDouble(args.inFraction);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeMix(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inStart: ");
+                        appendVariableToMessage(message, args.inStart);
+                        message.append("\n");
+                        message.append("Input inStop: ");
+                        appendVariableToMessage(message, args.inStop);
+                        message.append("\n");
+                        message.append("Input inFraction: ");
+                        appendVariableToMessage(message, args.inFraction);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkMixHalf2Half2Half2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMixHalf3Half3Half3Half3() {
+        Allocation inStart = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x25babc91l, false);
+        Allocation inStop = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0xcb4bcb2fl, false);
+        Allocation inFraction = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x187ca83fl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.set_gAllocInStop(inStop);
+            script.set_gAllocInFraction(inFraction);
+            script.forEach_testMixHalf3Half3Half3Half3(inStart, out);
+            verifyResultsMixHalf3Half3Half3Half3(inStart, inStop, inFraction, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMixHalf3Half3Half3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInStop(inStop);
+            scriptRelaxed.set_gAllocInFraction(inFraction);
+            scriptRelaxed.forEach_testMixHalf3Half3Half3Half3(inStart, out);
+            verifyResultsMixHalf3Half3Half3Half3(inStart, inStop, inFraction, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMixHalf3Half3Half3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMixHalf3Half3Half3Half3(Allocation inStart, Allocation inStop, Allocation inFraction, Allocation out, boolean relaxed) {
+        short[] arrayInStart = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInStart, (short) 42);
+        inStart.copyTo(arrayInStart);
+        short[] arrayInStop = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInStop, (short) 42);
+        inStop.copyTo(arrayInStop);
+        short[] arrayInFraction = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInFraction, (short) 42);
+        inFraction.copyTo(arrayInFraction);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalfHalf args = new ArgumentsHalfHalfHalfHalf();
+                args.inStart = arrayInStart[i * 4 + j];
+                args.inStartDouble = Float16Utils.convertFloat16ToDouble(args.inStart);
+                args.inStop = arrayInStop[i * 4 + j];
+                args.inStopDouble = Float16Utils.convertFloat16ToDouble(args.inStop);
+                args.inFraction = arrayInFraction[i * 4 + j];
+                args.inFractionDouble = Float16Utils.convertFloat16ToDouble(args.inFraction);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeMix(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inStart: ");
+                        appendVariableToMessage(message, args.inStart);
+                        message.append("\n");
+                        message.append("Input inStop: ");
+                        appendVariableToMessage(message, args.inStop);
+                        message.append("\n");
+                        message.append("Input inFraction: ");
+                        appendVariableToMessage(message, args.inFraction);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkMixHalf3Half3Half3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMixHalf4Half4Half4Half4() {
+        Allocation inStart = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x1b8fb8d9l, false);
+        Allocation inStop = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x8f865407l, false);
+        Allocation inFraction = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x2b48b597l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.set_gAllocInStop(inStop);
+            script.set_gAllocInFraction(inFraction);
+            script.forEach_testMixHalf4Half4Half4Half4(inStart, out);
+            verifyResultsMixHalf4Half4Half4Half4(inStart, inStop, inFraction, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMixHalf4Half4Half4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInStop(inStop);
+            scriptRelaxed.set_gAllocInFraction(inFraction);
+            scriptRelaxed.forEach_testMixHalf4Half4Half4Half4(inStart, out);
+            verifyResultsMixHalf4Half4Half4Half4(inStart, inStop, inFraction, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMixHalf4Half4Half4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMixHalf4Half4Half4Half4(Allocation inStart, Allocation inStop, Allocation inFraction, Allocation out, boolean relaxed) {
+        short[] arrayInStart = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInStart, (short) 42);
+        inStart.copyTo(arrayInStart);
+        short[] arrayInStop = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInStop, (short) 42);
+        inStop.copyTo(arrayInStop);
+        short[] arrayInFraction = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInFraction, (short) 42);
+        inFraction.copyTo(arrayInFraction);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalfHalf args = new ArgumentsHalfHalfHalfHalf();
+                args.inStart = arrayInStart[i * 4 + j];
+                args.inStartDouble = Float16Utils.convertFloat16ToDouble(args.inStart);
+                args.inStop = arrayInStop[i * 4 + j];
+                args.inStopDouble = Float16Utils.convertFloat16ToDouble(args.inStop);
+                args.inFraction = arrayInFraction[i * 4 + j];
+                args.inFractionDouble = Float16Utils.convertFloat16ToDouble(args.inFraction);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeMix(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inStart: ");
+                        appendVariableToMessage(message, args.inStart);
+                        message.append("\n");
+                        message.append("Input inStop: ");
+                        appendVariableToMessage(message, args.inStop);
+                        message.append("\n");
+                        message.append("Input inFraction: ");
+                        appendVariableToMessage(message, args.inFraction);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkMixHalf4Half4Half4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     private void checkMixFloat2Float2FloatFloat2() {
         Allocation inStart = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x2bd1d7c3l, false);
         Allocation inStop = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x3c8dd1c5l, false);
@@ -446,7 +837,7 @@
                 args.inStop = arrayInStop[i * 2 + j];
                 args.inFraction = arrayInFraction[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeMix(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -535,7 +926,7 @@
                 args.inStop = arrayInStop[i * 4 + j];
                 args.inFraction = arrayInFraction[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeMix(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -624,7 +1015,7 @@
                 args.inStop = arrayInStop[i * 4 + j];
                 args.inFraction = arrayInFraction[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeMix(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -666,13 +1057,305 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    private void checkMixHalf2Half2HalfHalf2() {
+        Allocation inStart = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xc5a4349l, false);
+        Allocation inStop = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x2fea4b57l, false);
+        Allocation inFraction = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xb339d3e7l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.set_gAllocInStop(inStop);
+            script.set_gAllocInFraction(inFraction);
+            script.forEach_testMixHalf2Half2HalfHalf2(inStart, out);
+            verifyResultsMixHalf2Half2HalfHalf2(inStart, inStop, inFraction, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMixHalf2Half2HalfHalf2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInStop(inStop);
+            scriptRelaxed.set_gAllocInFraction(inFraction);
+            scriptRelaxed.forEach_testMixHalf2Half2HalfHalf2(inStart, out);
+            verifyResultsMixHalf2Half2HalfHalf2(inStart, inStop, inFraction, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMixHalf2Half2HalfHalf2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMixHalf2Half2HalfHalf2(Allocation inStart, Allocation inStop, Allocation inFraction, Allocation out, boolean relaxed) {
+        short[] arrayInStart = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInStart, (short) 42);
+        inStart.copyTo(arrayInStart);
+        short[] arrayInStop = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInStop, (short) 42);
+        inStop.copyTo(arrayInStop);
+        short[] arrayInFraction = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInFraction, (short) 42);
+        inFraction.copyTo(arrayInFraction);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalfHalf args = new ArgumentsHalfHalfHalfHalf();
+                args.inStart = arrayInStart[i * 2 + j];
+                args.inStartDouble = Float16Utils.convertFloat16ToDouble(args.inStart);
+                args.inStop = arrayInStop[i * 2 + j];
+                args.inStopDouble = Float16Utils.convertFloat16ToDouble(args.inStop);
+                args.inFraction = arrayInFraction[i];
+                args.inFractionDouble = Float16Utils.convertFloat16ToDouble(args.inFraction);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeMix(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inStart: ");
+                        appendVariableToMessage(message, args.inStart);
+                        message.append("\n");
+                        message.append("Input inStop: ");
+                        appendVariableToMessage(message, args.inStop);
+                        message.append("\n");
+                        message.append("Input inFraction: ");
+                        appendVariableToMessage(message, args.inFraction);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkMixHalf2Half2HalfHalf2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMixHalf3Half3HalfHalf3() {
+        Allocation inStart = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x204615a8l, false);
+        Allocation inStop = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x541973f4l, false);
+        Allocation inFraction = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xb462aa74l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.set_gAllocInStop(inStop);
+            script.set_gAllocInFraction(inFraction);
+            script.forEach_testMixHalf3Half3HalfHalf3(inStart, out);
+            verifyResultsMixHalf3Half3HalfHalf3(inStart, inStop, inFraction, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMixHalf3Half3HalfHalf3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInStop(inStop);
+            scriptRelaxed.set_gAllocInFraction(inFraction);
+            scriptRelaxed.forEach_testMixHalf3Half3HalfHalf3(inStart, out);
+            verifyResultsMixHalf3Half3HalfHalf3(inStart, inStop, inFraction, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMixHalf3Half3HalfHalf3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMixHalf3Half3HalfHalf3(Allocation inStart, Allocation inStop, Allocation inFraction, Allocation out, boolean relaxed) {
+        short[] arrayInStart = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInStart, (short) 42);
+        inStart.copyTo(arrayInStart);
+        short[] arrayInStop = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInStop, (short) 42);
+        inStop.copyTo(arrayInStop);
+        short[] arrayInFraction = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInFraction, (short) 42);
+        inFraction.copyTo(arrayInFraction);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalfHalf args = new ArgumentsHalfHalfHalfHalf();
+                args.inStart = arrayInStart[i * 4 + j];
+                args.inStartDouble = Float16Utils.convertFloat16ToDouble(args.inStart);
+                args.inStop = arrayInStop[i * 4 + j];
+                args.inStopDouble = Float16Utils.convertFloat16ToDouble(args.inStop);
+                args.inFraction = arrayInFraction[i];
+                args.inFractionDouble = Float16Utils.convertFloat16ToDouble(args.inFraction);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeMix(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inStart: ");
+                        appendVariableToMessage(message, args.inStart);
+                        message.append("\n");
+                        message.append("Input inStop: ");
+                        appendVariableToMessage(message, args.inStop);
+                        message.append("\n");
+                        message.append("Input inFraction: ");
+                        appendVariableToMessage(message, args.inFraction);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkMixHalf3Half3HalfHalf3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMixHalf4Half4HalfHalf4() {
+        Allocation inStart = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x3431e807l, false);
+        Allocation inStop = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x78489c91l, false);
+        Allocation inFraction = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xb58b8101l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.set_gAllocInStop(inStop);
+            script.set_gAllocInFraction(inFraction);
+            script.forEach_testMixHalf4Half4HalfHalf4(inStart, out);
+            verifyResultsMixHalf4Half4HalfHalf4(inStart, inStop, inFraction, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMixHalf4Half4HalfHalf4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInStop(inStop);
+            scriptRelaxed.set_gAllocInFraction(inFraction);
+            scriptRelaxed.forEach_testMixHalf4Half4HalfHalf4(inStart, out);
+            verifyResultsMixHalf4Half4HalfHalf4(inStart, inStop, inFraction, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMixHalf4Half4HalfHalf4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMixHalf4Half4HalfHalf4(Allocation inStart, Allocation inStop, Allocation inFraction, Allocation out, boolean relaxed) {
+        short[] arrayInStart = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInStart, (short) 42);
+        inStart.copyTo(arrayInStart);
+        short[] arrayInStop = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInStop, (short) 42);
+        inStop.copyTo(arrayInStop);
+        short[] arrayInFraction = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInFraction, (short) 42);
+        inFraction.copyTo(arrayInFraction);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalfHalf args = new ArgumentsHalfHalfHalfHalf();
+                args.inStart = arrayInStart[i * 4 + j];
+                args.inStartDouble = Float16Utils.convertFloat16ToDouble(args.inStart);
+                args.inStop = arrayInStop[i * 4 + j];
+                args.inStopDouble = Float16Utils.convertFloat16ToDouble(args.inStop);
+                args.inFraction = arrayInFraction[i];
+                args.inFractionDouble = Float16Utils.convertFloat16ToDouble(args.inFraction);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeMix(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inStart: ");
+                        appendVariableToMessage(message, args.inStart);
+                        message.append("\n");
+                        message.append("Input inStop: ");
+                        appendVariableToMessage(message, args.inStop);
+                        message.append("\n");
+                        message.append("Input inFraction: ");
+                        appendVariableToMessage(message, args.inFraction);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkMixHalf4Half4HalfHalf4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testMix() {
         checkMixFloatFloatFloatFloat();
         checkMixFloat2Float2Float2Float2();
         checkMixFloat3Float3Float3Float3();
         checkMixFloat4Float4Float4Float4();
+        checkMixHalfHalfHalfHalf();
+        checkMixHalf2Half2Half2Half2();
+        checkMixHalf3Half3Half3Half3();
+        checkMixHalf4Half4Half4Half4();
         checkMixFloat2Float2FloatFloat2();
         checkMixFloat3Float3FloatFloat3();
         checkMixFloat4Float4FloatFloat4();
+        checkMixHalf2Half2HalfHalf2();
+        checkMixHalf3Half3HalfHalf3();
+        checkMixHalf4Half4HalfHalf4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMix.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMix.rs
index b83d927..b8c7440 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMix.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMix.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -46,6 +46,30 @@
     return mix(inStart, inStop, inFraction);
 }
 
+half __attribute__((kernel)) testMixHalfHalfHalfHalf(half inStart, unsigned int x) {
+    half inStop = rsGetElementAt_half(gAllocInStop, x);
+    half inFraction = rsGetElementAt_half(gAllocInFraction, x);
+    return mix(inStart, inStop, inFraction);
+}
+
+half2 __attribute__((kernel)) testMixHalf2Half2Half2Half2(half2 inStart, unsigned int x) {
+    half2 inStop = rsGetElementAt_half2(gAllocInStop, x);
+    half2 inFraction = rsGetElementAt_half2(gAllocInFraction, x);
+    return mix(inStart, inStop, inFraction);
+}
+
+half3 __attribute__((kernel)) testMixHalf3Half3Half3Half3(half3 inStart, unsigned int x) {
+    half3 inStop = rsGetElementAt_half3(gAllocInStop, x);
+    half3 inFraction = rsGetElementAt_half3(gAllocInFraction, x);
+    return mix(inStart, inStop, inFraction);
+}
+
+half4 __attribute__((kernel)) testMixHalf4Half4Half4Half4(half4 inStart, unsigned int x) {
+    half4 inStop = rsGetElementAt_half4(gAllocInStop, x);
+    half4 inFraction = rsGetElementAt_half4(gAllocInFraction, x);
+    return mix(inStart, inStop, inFraction);
+}
+
 float2 __attribute__((kernel)) testMixFloat2Float2FloatFloat2(float2 inStart, unsigned int x) {
     float2 inStop = rsGetElementAt_float2(gAllocInStop, x);
     float inFraction = rsGetElementAt_float(gAllocInFraction, x);
@@ -63,3 +87,21 @@
     float inFraction = rsGetElementAt_float(gAllocInFraction, x);
     return mix(inStart, inStop, inFraction);
 }
+
+half2 __attribute__((kernel)) testMixHalf2Half2HalfHalf2(half2 inStart, unsigned int x) {
+    half2 inStop = rsGetElementAt_half2(gAllocInStop, x);
+    half inFraction = rsGetElementAt_half(gAllocInFraction, x);
+    return mix(inStart, inStop, inFraction);
+}
+
+half3 __attribute__((kernel)) testMixHalf3Half3HalfHalf3(half3 inStart, unsigned int x) {
+    half3 inStop = rsGetElementAt_half3(gAllocInStop, x);
+    half inFraction = rsGetElementAt_half(gAllocInFraction, x);
+    return mix(inStart, inStop, inFraction);
+}
+
+half4 __attribute__((kernel)) testMixHalf4Half4HalfHalf4(half4 inStart, unsigned int x) {
+    half4 inStop = rsGetElementAt_half4(gAllocInStop, x);
+    half inFraction = rsGetElementAt_half(gAllocInFraction, x);
+    return mix(inStart, inStop, inFraction);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMixRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMixRelaxed.rs
index 50e5e4d..639dd50 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMixRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMixRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestModf.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestModf.java
index 1848ce6..d45efc4 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestModf.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestModf.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -82,7 +83,7 @@
                 ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeModf(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -170,7 +171,7 @@
                 ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeModf(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -258,7 +259,7 @@
                 ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeModf(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -346,7 +347,7 @@
                 ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeModf(args, target);
                 // Validate the outputs.
                 boolean valid = true;
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestModf.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestModf.rs
index 802ab70..5ff4155 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestModf.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestModf.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestModfRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestModfRelaxed.rs
index 33dd422..3d73523f 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestModfRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestModfRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNan.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNan.java
index e17cd2b..6558ab3 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNan.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNan.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsUintFloat args = new ArgumentsUintFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNan(args, target);
                 // Validate the outputs.
                 boolean valid = true;
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNan.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNan.rs
index cc2e3a9..5d90378 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNan.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNan.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNanHalf.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNanHalf.java
new file mode 100644
index 0000000..51f6fb7
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNanHalf.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+import android.renderscript.cts.Target;
+
+import java.util.Arrays;
+
+public class TestNanHalf extends RSBaseCompute {
+
+    private ScriptC_TestNanHalf script;
+    private ScriptC_TestNanHalfRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestNanHalf(mRS);
+        scriptRelaxed = new ScriptC_TestNanHalfRelaxed(mRS);
+    }
+
+    public class ArgumentsHalf {
+        public Target.Floaty out;
+    }
+
+    private void checkNanHalfHalf() {
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testNanHalfHalf(out);
+            verifyResultsNanHalfHalf(out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNanHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNanHalfHalf(out);
+            verifyResultsNanHalfHalf(out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNanHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNanHalfHalf(Allocation out, boolean relaxed) {
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalf args = new ArgumentsHalf();
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNanHalf(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNanHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testNanHalf() {
+        checkNanHalfHalf();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNanHalf.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNanHalf.rs
new file mode 100644
index 0000000..24a7dcf
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNanHalf.rs
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+
+half __attribute__((kernel)) testNanHalfHalf() {
+    return nan_half();
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNanHalfRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNanHalfRelaxed.rs
new file mode 100644
index 0000000..619400c
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNanHalfRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestNanHalf.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNanRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNanRelaxed.rs
index a428cde..e9970af 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNanRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNanRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAcos.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAcos.java
index 0452cc9..2fcd1e3 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAcos.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAcos.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeAcos(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeAcos(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeAcos(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeAcos(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeAcosHalfHalf() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xde848e1el, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testNativeAcosHalfHalf(inV, out);
+            verifyResultsNativeAcosHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcosHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAcosHalfHalf(inV, out);
+            verifyResultsNativeAcosHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcosHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAcosHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeAcos(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]), 0.00048828125)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]), 0.00048828125)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAcosHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAcosHalf2Half2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xd29d84d0l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testNativeAcosHalf2Half2(inV, out);
+            verifyResultsNativeAcosHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcosHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAcosHalf2Half2(inV, out);
+            verifyResultsNativeAcosHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcosHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAcosHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeAcos(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]), 0.00048828125)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]), 0.00048828125)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAcosHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAcosHalf3Half3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x31a549c4l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testNativeAcosHalf3Half3(inV, out);
+            verifyResultsNativeAcosHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcosHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAcosHalf3Half3(inV, out);
+            verifyResultsNativeAcosHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcosHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAcosHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeAcos(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]), 0.00048828125)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]), 0.00048828125)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAcosHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAcosHalf4Half4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x90ad0eb8l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testNativeAcosHalf4Half4(inV, out);
+            verifyResultsNativeAcosHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcosHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAcosHalf4Half4(inV, out);
+            verifyResultsNativeAcosHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcosHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAcosHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeAcos(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]), 0.00048828125)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]), 0.00048828125)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAcosHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testNativeAcos() {
         checkNativeAcosFloatFloat();
         checkNativeAcosFloat2Float2();
         checkNativeAcosFloat3Float3();
         checkNativeAcosFloat4Float4();
+        checkNativeAcosHalfHalf();
+        checkNativeAcosHalf2Half2();
+        checkNativeAcosHalf3Half3();
+        checkNativeAcosHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAcos.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAcos.rs
index 3d0d277..ca5bf5f 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAcos.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAcos.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testNativeAcosFloat4Float4(float4 inV) {
     return native_acos(inV);
 }
+
+half __attribute__((kernel)) testNativeAcosHalfHalf(half inV) {
+    return native_acos(inV);
+}
+
+half2 __attribute__((kernel)) testNativeAcosHalf2Half2(half2 inV) {
+    return native_acos(inV);
+}
+
+half3 __attribute__((kernel)) testNativeAcosHalf3Half3(half3 inV) {
+    return native_acos(inV);
+}
+
+half4 __attribute__((kernel)) testNativeAcosHalf4Half4(half4 inV) {
+    return native_acos(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAcosRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAcosRelaxed.rs
index 26c0058..9b857c8 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAcosRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAcosRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAcosh.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAcosh.java
index 0494901..8c609d4 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAcosh.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAcosh.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeAcosh(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeAcosh(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeAcosh(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeAcosh(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeAcoshHalfHalf() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x34f17c04l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testNativeAcoshHalfHalf(inV, out);
+            verifyResultsNativeAcoshHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcoshHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAcoshHalfHalf(inV, out);
+            verifyResultsNativeAcoshHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcoshHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAcoshHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeAcosh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAcoshHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAcoshHalf2Half2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xb5fc706l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testNativeAcoshHalf2Half2(inV, out);
+            verifyResultsNativeAcoshHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcoshHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAcoshHalf2Half2(inV, out);
+            verifyResultsNativeAcoshHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcoshHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAcoshHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeAcosh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAcoshHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAcoshHalf3Half3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x6a678bfal, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testNativeAcoshHalf3Half3(inV, out);
+            verifyResultsNativeAcoshHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcoshHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAcoshHalf3Half3(inV, out);
+            verifyResultsNativeAcoshHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcoshHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAcoshHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeAcosh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAcoshHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAcoshHalf4Half4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xc96f50eel, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testNativeAcoshHalf4Half4(inV, out);
+            verifyResultsNativeAcoshHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcoshHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAcoshHalf4Half4(inV, out);
+            verifyResultsNativeAcoshHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcoshHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAcoshHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeAcosh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAcoshHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testNativeAcosh() {
         checkNativeAcoshFloatFloat();
         checkNativeAcoshFloat2Float2();
         checkNativeAcoshFloat3Float3();
         checkNativeAcoshFloat4Float4();
+        checkNativeAcoshHalfHalf();
+        checkNativeAcoshHalf2Half2();
+        checkNativeAcoshHalf3Half3();
+        checkNativeAcoshHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAcosh.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAcosh.rs
index d6f4022..e050468 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAcosh.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAcosh.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testNativeAcoshFloat4Float4(float4 inV) {
     return native_acosh(inV);
 }
+
+half __attribute__((kernel)) testNativeAcoshHalfHalf(half inV) {
+    return native_acosh(inV);
+}
+
+half2 __attribute__((kernel)) testNativeAcoshHalf2Half2(half2 inV) {
+    return native_acosh(inV);
+}
+
+half3 __attribute__((kernel)) testNativeAcoshHalf3Half3(half3 inV) {
+    return native_acosh(inV);
+}
+
+half4 __attribute__((kernel)) testNativeAcoshHalf4Half4(half4 inV) {
+    return native_acosh(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAcoshRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAcoshRelaxed.rs
index d077f0d..3750a6e 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAcoshRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAcoshRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAcospi.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAcospi.java
index 1c84749..1a71e07 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAcospi.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAcospi.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeAcospi(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeAcospi(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeAcospi(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeAcospi(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeAcospiHalfHalf() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xcf2d81e1l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testNativeAcospiHalfHalf(inV, out);
+            verifyResultsNativeAcospiHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcospiHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAcospiHalfHalf(inV, out);
+            verifyResultsNativeAcospiHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcospiHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAcospiHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeAcospi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]), 0.00048828125)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]), 0.00048828125)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAcospiHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAcospiHalf2Half2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x6e6203bl, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testNativeAcospiHalf2Half2(inV, out);
+            verifyResultsNativeAcospiHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcospiHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAcospiHalf2Half2(inV, out);
+            verifyResultsNativeAcospiHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcospiHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAcospiHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeAcospi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]), 0.00048828125)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]), 0.00048828125)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAcospiHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAcospiHalf3Half3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x65ede52fl, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testNativeAcospiHalf3Half3(inV, out);
+            verifyResultsNativeAcospiHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcospiHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAcospiHalf3Half3(inV, out);
+            verifyResultsNativeAcospiHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcospiHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAcospiHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeAcospi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]), 0.00048828125)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]), 0.00048828125)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAcospiHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAcospiHalf4Half4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xc4f5aa23l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testNativeAcospiHalf4Half4(inV, out);
+            verifyResultsNativeAcospiHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcospiHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAcospiHalf4Half4(inV, out);
+            verifyResultsNativeAcospiHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcospiHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAcospiHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeAcospi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]), 0.00048828125)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]), 0.00048828125)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAcospiHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testNativeAcospi() {
         checkNativeAcospiFloatFloat();
         checkNativeAcospiFloat2Float2();
         checkNativeAcospiFloat3Float3();
         checkNativeAcospiFloat4Float4();
+        checkNativeAcospiHalfHalf();
+        checkNativeAcospiHalf2Half2();
+        checkNativeAcospiHalf3Half3();
+        checkNativeAcospiHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAcospi.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAcospi.rs
index 2feadae..612cf26 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAcospi.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAcospi.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testNativeAcospiFloat4Float4(float4 inV) {
     return native_acospi(inV);
 }
+
+half __attribute__((kernel)) testNativeAcospiHalfHalf(half inV) {
+    return native_acospi(inV);
+}
+
+half2 __attribute__((kernel)) testNativeAcospiHalf2Half2(half2 inV) {
+    return native_acospi(inV);
+}
+
+half3 __attribute__((kernel)) testNativeAcospiHalf3Half3(half3 inV) {
+    return native_acospi(inV);
+}
+
+half4 __attribute__((kernel)) testNativeAcospiHalf4Half4(half4 inV) {
+    return native_acospi(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAcospiRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAcospiRelaxed.rs
index 9a73980..5e900e9 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAcospiRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAcospiRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAsin.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAsin.java
index 252f99b..442b62a 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAsin.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAsin.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeAsin(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeAsin(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeAsin(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeAsin(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeAsinHalfHalf() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x228512e9l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testNativeAsinHalfHalf(inV, out);
+            verifyResultsNativeAsinHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAsinHalfHalf(inV, out);
+            verifyResultsNativeAsinHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAsinHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeAsin(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]), 0.00048828125)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]), 0.00048828125)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAsinHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAsinHalf2Half2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xfa5ca303l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testNativeAsinHalf2Half2(inV, out);
+            verifyResultsNativeAsinHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAsinHalf2Half2(inV, out);
+            verifyResultsNativeAsinHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAsinHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeAsin(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]), 0.00048828125)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]), 0.00048828125)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAsinHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAsinHalf3Half3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x596467f7l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testNativeAsinHalf3Half3(inV, out);
+            verifyResultsNativeAsinHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAsinHalf3Half3(inV, out);
+            verifyResultsNativeAsinHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAsinHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeAsin(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]), 0.00048828125)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]), 0.00048828125)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAsinHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAsinHalf4Half4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xb86c2cebl, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testNativeAsinHalf4Half4(inV, out);
+            verifyResultsNativeAsinHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAsinHalf4Half4(inV, out);
+            verifyResultsNativeAsinHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAsinHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeAsin(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]), 0.00048828125)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]), 0.00048828125)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAsinHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testNativeAsin() {
         checkNativeAsinFloatFloat();
         checkNativeAsinFloat2Float2();
         checkNativeAsinFloat3Float3();
         checkNativeAsinFloat4Float4();
+        checkNativeAsinHalfHalf();
+        checkNativeAsinHalf2Half2();
+        checkNativeAsinHalf3Half3();
+        checkNativeAsinHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAsin.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAsin.rs
index 9d0811b..ddb08c2 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAsin.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAsin.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testNativeAsinFloat4Float4(float4 inV) {
     return native_asin(inV);
 }
+
+half __attribute__((kernel)) testNativeAsinHalfHalf(half inV) {
+    return native_asin(inV);
+}
+
+half2 __attribute__((kernel)) testNativeAsinHalf2Half2(half2 inV) {
+    return native_asin(inV);
+}
+
+half3 __attribute__((kernel)) testNativeAsinHalf3Half3(half3 inV) {
+    return native_asin(inV);
+}
+
+half4 __attribute__((kernel)) testNativeAsinHalf4Half4(half4 inV) {
+    return native_asin(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAsinRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAsinRelaxed.rs
index d695124..76527d8 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAsinRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAsinRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAsinh.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAsinh.java
index 6b72cc9..581e80c 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAsinh.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAsinh.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeAsinh(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeAsinh(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeAsinh(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeAsinh(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeAsinhHalfHalf() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xa107ca1dl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testNativeAsinhHalfHalf(inV, out);
+            verifyResultsNativeAsinhHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinhHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAsinhHalfHalf(inV, out);
+            verifyResultsNativeAsinhHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinhHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAsinhHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeAsinh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAsinhHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAsinhHalf2Half2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xb879d997l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testNativeAsinhHalf2Half2(inV, out);
+            verifyResultsNativeAsinhHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinhHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAsinhHalf2Half2(inV, out);
+            verifyResultsNativeAsinhHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinhHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAsinhHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeAsinh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAsinhHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAsinhHalf3Half3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x17819e8bl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testNativeAsinhHalf3Half3(inV, out);
+            verifyResultsNativeAsinhHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinhHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAsinhHalf3Half3(inV, out);
+            verifyResultsNativeAsinhHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinhHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAsinhHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeAsinh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAsinhHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAsinhHalf4Half4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x7689637fl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testNativeAsinhHalf4Half4(inV, out);
+            verifyResultsNativeAsinhHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinhHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAsinhHalf4Half4(inV, out);
+            verifyResultsNativeAsinhHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinhHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAsinhHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeAsinh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAsinhHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testNativeAsinh() {
         checkNativeAsinhFloatFloat();
         checkNativeAsinhFloat2Float2();
         checkNativeAsinhFloat3Float3();
         checkNativeAsinhFloat4Float4();
+        checkNativeAsinhHalfHalf();
+        checkNativeAsinhHalf2Half2();
+        checkNativeAsinhHalf3Half3();
+        checkNativeAsinhHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAsinh.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAsinh.rs
index 21627f6..1b21ce7 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAsinh.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAsinh.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testNativeAsinhFloat4Float4(float4 inV) {
     return native_asinh(inV);
 }
+
+half __attribute__((kernel)) testNativeAsinhHalfHalf(half inV) {
+    return native_asinh(inV);
+}
+
+half2 __attribute__((kernel)) testNativeAsinhHalf2Half2(half2 inV) {
+    return native_asinh(inV);
+}
+
+half3 __attribute__((kernel)) testNativeAsinhHalf3Half3(half3 inV) {
+    return native_asinh(inV);
+}
+
+half4 __attribute__((kernel)) testNativeAsinhHalf4Half4(half4 inV) {
+    return native_asinh(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAsinhRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAsinhRelaxed.rs
index 0d4b6c9..9e4df93 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAsinhRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAsinhRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAsinpi.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAsinpi.java
index 84b219a..5a40037 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAsinpi.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAsinpi.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeAsinpi(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeAsinpi(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeAsinpi(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeAsinpi(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeAsinpiHalfHalf() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xf6eca014l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testNativeAsinpiHalfHalf(inV, out);
+            verifyResultsNativeAsinpiHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinpiHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAsinpiHalfHalf(inV, out);
+            verifyResultsNativeAsinpiHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinpiHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAsinpiHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeAsinpi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]), 0.00048828125)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]), 0.00048828125)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAsinpiHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAsinpiHalf2Half2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x1a473e96l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testNativeAsinpiHalf2Half2(inV, out);
+            verifyResultsNativeAsinpiHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinpiHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAsinpiHalf2Half2(inV, out);
+            verifyResultsNativeAsinpiHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinpiHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAsinpiHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeAsinpi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]), 0.00048828125)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]), 0.00048828125)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAsinpiHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAsinpiHalf3Half3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x794f038al, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testNativeAsinpiHalf3Half3(inV, out);
+            verifyResultsNativeAsinpiHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinpiHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAsinpiHalf3Half3(inV, out);
+            verifyResultsNativeAsinpiHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinpiHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAsinpiHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeAsinpi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]), 0.00048828125)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]), 0.00048828125)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAsinpiHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAsinpiHalf4Half4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xd856c87el, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testNativeAsinpiHalf4Half4(inV, out);
+            verifyResultsNativeAsinpiHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinpiHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAsinpiHalf4Half4(inV, out);
+            verifyResultsNativeAsinpiHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinpiHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAsinpiHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeAsinpi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]), 0.00048828125)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]), 0.00048828125)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAsinpiHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testNativeAsinpi() {
         checkNativeAsinpiFloatFloat();
         checkNativeAsinpiFloat2Float2();
         checkNativeAsinpiFloat3Float3();
         checkNativeAsinpiFloat4Float4();
+        checkNativeAsinpiHalfHalf();
+        checkNativeAsinpiHalf2Half2();
+        checkNativeAsinpiHalf3Half3();
+        checkNativeAsinpiHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAsinpi.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAsinpi.rs
index d924ca7..863e42c 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAsinpi.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAsinpi.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testNativeAsinpiFloat4Float4(float4 inV) {
     return native_asinpi(inV);
 }
+
+half __attribute__((kernel)) testNativeAsinpiHalfHalf(half inV) {
+    return native_asinpi(inV);
+}
+
+half2 __attribute__((kernel)) testNativeAsinpiHalf2Half2(half2 inV) {
+    return native_asinpi(inV);
+}
+
+half3 __attribute__((kernel)) testNativeAsinpiHalf3Half3(half3 inV) {
+    return native_asinpi(inV);
+}
+
+half4 __attribute__((kernel)) testNativeAsinpiHalf4Half4(half4 inV) {
+    return native_asinpi(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAsinpiRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAsinpiRelaxed.rs
index 35beace..f1ad731 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAsinpiRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAsinpiRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtan.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtan.java
index 12430dc..d12a831 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtan.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtan.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeAtan(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeAtan(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeAtan(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeAtan(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeAtanHalfHalf() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x8d59863cl, -1,  1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testNativeAtanHalfHalf(inV, out);
+            verifyResultsNativeAtanHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAtanHalfHalf(inV, out);
+            verifyResultsNativeAtanHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAtanHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeAtan(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAtanHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAtanHalf2Half2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x92d1957el, -1,  1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testNativeAtanHalf2Half2(inV, out);
+            verifyResultsNativeAtanHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAtanHalf2Half2(inV, out);
+            verifyResultsNativeAtanHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAtanHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeAtan(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAtanHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAtanHalf3Half3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 3, 0xf1d95a72l, -1,  1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testNativeAtanHalf3Half3(inV, out);
+            verifyResultsNativeAtanHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAtanHalf3Half3(inV, out);
+            verifyResultsNativeAtanHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAtanHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeAtan(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAtanHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAtanHalf4Half4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x50e11f66l, -1,  1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testNativeAtanHalf4Half4(inV, out);
+            verifyResultsNativeAtanHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAtanHalf4Half4(inV, out);
+            verifyResultsNativeAtanHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAtanHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeAtan(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAtanHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testNativeAtan() {
         checkNativeAtanFloatFloat();
         checkNativeAtanFloat2Float2();
         checkNativeAtanFloat3Float3();
         checkNativeAtanFloat4Float4();
+        checkNativeAtanHalfHalf();
+        checkNativeAtanHalf2Half2();
+        checkNativeAtanHalf3Half3();
+        checkNativeAtanHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtan.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtan.rs
index de9f739..72887bc 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtan.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtan.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testNativeAtanFloat4Float4(float4 inV) {
     return native_atan(inV);
 }
+
+half __attribute__((kernel)) testNativeAtanHalfHalf(half inV) {
+    return native_atan(inV);
+}
+
+half2 __attribute__((kernel)) testNativeAtanHalf2Half2(half2 inV) {
+    return native_atan(inV);
+}
+
+half3 __attribute__((kernel)) testNativeAtanHalf3Half3(half3 inV) {
+    return native_atan(inV);
+}
+
+half4 __attribute__((kernel)) testNativeAtanHalf4Half4(half4 inV) {
+    return native_atan(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtan2.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtan2.java
index 4cabb28..8d2a826 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtan2.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtan2.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -82,7 +83,7 @@
                 args.inNumerator = arrayInNumerator[i];
                 args.inDenominator = arrayInDenominator[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeAtan2(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -161,7 +162,7 @@
                 args.inNumerator = arrayInNumerator[i * 2 + j];
                 args.inDenominator = arrayInDenominator[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeAtan2(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -240,7 +241,7 @@
                 args.inNumerator = arrayInNumerator[i * 4 + j];
                 args.inDenominator = arrayInDenominator[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeAtan2(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -319,7 +320,7 @@
                 args.inNumerator = arrayInNumerator[i * 4 + j];
                 args.inDenominator = arrayInDenominator[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeAtan2(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -358,10 +359,358 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalfHalf {
+        public short inNumerator;
+        public double inNumeratorDouble;
+        public short inDenominator;
+        public double inDenominatorDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeAtan2HalfHalfHalf() {
+        Allocation inNumerator = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xe3d252c0l, false);
+        Allocation inDenominator = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xe16255f9l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.set_gAllocInDenominator(inDenominator);
+            script.forEach_testNativeAtan2HalfHalfHalf(inNumerator, out);
+            verifyResultsNativeAtan2HalfHalfHalf(inNumerator, inDenominator, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtan2HalfHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInDenominator(inDenominator);
+            scriptRelaxed.forEach_testNativeAtan2HalfHalfHalf(inNumerator, out);
+            verifyResultsNativeAtan2HalfHalfHalf(inNumerator, inDenominator, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtan2HalfHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAtan2HalfHalfHalf(Allocation inNumerator, Allocation inDenominator, Allocation out, boolean relaxed) {
+        short[] arrayInNumerator = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInNumerator, (short) 42);
+        inNumerator.copyTo(arrayInNumerator);
+        short[] arrayInDenominator = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInDenominator, (short) 42);
+        inDenominator.copyTo(arrayInDenominator);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inNumerator = arrayInNumerator[i];
+                args.inNumeratorDouble = Float16Utils.convertFloat16ToDouble(args.inNumerator);
+                args.inDenominator = arrayInDenominator[i];
+                args.inDenominatorDouble = Float16Utils.convertFloat16ToDouble(args.inDenominator);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeAtan2(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inNumerator: ");
+                        appendVariableToMessage(message, args.inNumerator);
+                        message.append("\n");
+                        message.append("Input inDenominator: ");
+                        appendVariableToMessage(message, args.inDenominator);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAtan2HalfHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAtan2Half2Half2Half2() {
+        Allocation inNumerator = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x51d7124l, false);
+        Allocation inDenominator = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x58f0d63dl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.set_gAllocInDenominator(inDenominator);
+            script.forEach_testNativeAtan2Half2Half2Half2(inNumerator, out);
+            verifyResultsNativeAtan2Half2Half2Half2(inNumerator, inDenominator, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtan2Half2Half2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInDenominator(inDenominator);
+            scriptRelaxed.forEach_testNativeAtan2Half2Half2Half2(inNumerator, out);
+            verifyResultsNativeAtan2Half2Half2Half2(inNumerator, inDenominator, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtan2Half2Half2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAtan2Half2Half2Half2(Allocation inNumerator, Allocation inDenominator, Allocation out, boolean relaxed) {
+        short[] arrayInNumerator = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInNumerator, (short) 42);
+        inNumerator.copyTo(arrayInNumerator);
+        short[] arrayInDenominator = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInDenominator, (short) 42);
+        inDenominator.copyTo(arrayInDenominator);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inNumerator = arrayInNumerator[i * 2 + j];
+                args.inNumeratorDouble = Float16Utils.convertFloat16ToDouble(args.inNumerator);
+                args.inDenominator = arrayInDenominator[i * 2 + j];
+                args.inDenominatorDouble = Float16Utils.convertFloat16ToDouble(args.inDenominator);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeAtan2(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inNumerator: ");
+                        appendVariableToMessage(message, args.inNumerator);
+                        message.append("\n");
+                        message.append("Input inDenominator: ");
+                        appendVariableToMessage(message, args.inDenominator);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAtan2Half2Half2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAtan2Half3Half3Half3() {
+        Allocation inNumerator = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x508fa193l, false);
+        Allocation inDenominator = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x44b0a7f4l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.set_gAllocInDenominator(inDenominator);
+            script.forEach_testNativeAtan2Half3Half3Half3(inNumerator, out);
+            verifyResultsNativeAtan2Half3Half3Half3(inNumerator, inDenominator, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtan2Half3Half3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInDenominator(inDenominator);
+            scriptRelaxed.forEach_testNativeAtan2Half3Half3Half3(inNumerator, out);
+            verifyResultsNativeAtan2Half3Half3Half3(inNumerator, inDenominator, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtan2Half3Half3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAtan2Half3Half3Half3(Allocation inNumerator, Allocation inDenominator, Allocation out, boolean relaxed) {
+        short[] arrayInNumerator = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInNumerator, (short) 42);
+        inNumerator.copyTo(arrayInNumerator);
+        short[] arrayInDenominator = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInDenominator, (short) 42);
+        inDenominator.copyTo(arrayInDenominator);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inNumerator = arrayInNumerator[i * 4 + j];
+                args.inNumeratorDouble = Float16Utils.convertFloat16ToDouble(args.inNumerator);
+                args.inDenominator = arrayInDenominator[i * 4 + j];
+                args.inDenominatorDouble = Float16Utils.convertFloat16ToDouble(args.inDenominator);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeAtan2(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inNumerator: ");
+                        appendVariableToMessage(message, args.inNumerator);
+                        message.append("\n");
+                        message.append("Input inDenominator: ");
+                        appendVariableToMessage(message, args.inDenominator);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAtan2Half3Half3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAtan2Half4Half4Half4() {
+        Allocation inNumerator = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x9c01d202l, false);
+        Allocation inDenominator = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x307079abl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.set_gAllocInDenominator(inDenominator);
+            script.forEach_testNativeAtan2Half4Half4Half4(inNumerator, out);
+            verifyResultsNativeAtan2Half4Half4Half4(inNumerator, inDenominator, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtan2Half4Half4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInDenominator(inDenominator);
+            scriptRelaxed.forEach_testNativeAtan2Half4Half4Half4(inNumerator, out);
+            verifyResultsNativeAtan2Half4Half4Half4(inNumerator, inDenominator, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtan2Half4Half4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAtan2Half4Half4Half4(Allocation inNumerator, Allocation inDenominator, Allocation out, boolean relaxed) {
+        short[] arrayInNumerator = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInNumerator, (short) 42);
+        inNumerator.copyTo(arrayInNumerator);
+        short[] arrayInDenominator = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInDenominator, (short) 42);
+        inDenominator.copyTo(arrayInDenominator);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inNumerator = arrayInNumerator[i * 4 + j];
+                args.inNumeratorDouble = Float16Utils.convertFloat16ToDouble(args.inNumerator);
+                args.inDenominator = arrayInDenominator[i * 4 + j];
+                args.inDenominatorDouble = Float16Utils.convertFloat16ToDouble(args.inDenominator);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeAtan2(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inNumerator: ");
+                        appendVariableToMessage(message, args.inNumerator);
+                        message.append("\n");
+                        message.append("Input inDenominator: ");
+                        appendVariableToMessage(message, args.inDenominator);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAtan2Half4Half4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testNativeAtan2() {
         checkNativeAtan2FloatFloatFloat();
         checkNativeAtan2Float2Float2Float2();
         checkNativeAtan2Float3Float3Float3();
         checkNativeAtan2Float4Float4Float4();
+        checkNativeAtan2HalfHalfHalf();
+        checkNativeAtan2Half2Half2Half2();
+        checkNativeAtan2Half3Half3Half3();
+        checkNativeAtan2Half4Half4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtan2.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtan2.rs
index 66ee75e..2142819 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtan2.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtan2.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -40,3 +40,23 @@
     float4 inDenominator = rsGetElementAt_float4(gAllocInDenominator, x);
     return native_atan2(inNumerator, inDenominator);
 }
+
+half __attribute__((kernel)) testNativeAtan2HalfHalfHalf(half inNumerator, unsigned int x) {
+    half inDenominator = rsGetElementAt_half(gAllocInDenominator, x);
+    return native_atan2(inNumerator, inDenominator);
+}
+
+half2 __attribute__((kernel)) testNativeAtan2Half2Half2Half2(half2 inNumerator, unsigned int x) {
+    half2 inDenominator = rsGetElementAt_half2(gAllocInDenominator, x);
+    return native_atan2(inNumerator, inDenominator);
+}
+
+half3 __attribute__((kernel)) testNativeAtan2Half3Half3Half3(half3 inNumerator, unsigned int x) {
+    half3 inDenominator = rsGetElementAt_half3(gAllocInDenominator, x);
+    return native_atan2(inNumerator, inDenominator);
+}
+
+half4 __attribute__((kernel)) testNativeAtan2Half4Half4Half4(half4 inNumerator, unsigned int x) {
+    half4 inDenominator = rsGetElementAt_half4(gAllocInDenominator, x);
+    return native_atan2(inNumerator, inDenominator);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtan2Relaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtan2Relaxed.rs
index ac6659f..9ec609d 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtan2Relaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtan2Relaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtan2pi.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtan2pi.java
index c42591c..572c8c8 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtan2pi.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtan2pi.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -82,7 +83,7 @@
                 args.inNumerator = arrayInNumerator[i];
                 args.inDenominator = arrayInDenominator[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeAtan2pi(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -161,7 +162,7 @@
                 args.inNumerator = arrayInNumerator[i * 2 + j];
                 args.inDenominator = arrayInDenominator[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeAtan2pi(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -240,7 +241,7 @@
                 args.inNumerator = arrayInNumerator[i * 4 + j];
                 args.inDenominator = arrayInDenominator[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeAtan2pi(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -319,7 +320,7 @@
                 args.inNumerator = arrayInNumerator[i * 4 + j];
                 args.inDenominator = arrayInDenominator[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeAtan2pi(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -358,10 +359,358 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalfHalf {
+        public short inNumerator;
+        public double inNumeratorDouble;
+        public short inDenominator;
+        public double inDenominatorDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeAtan2piHalfHalfHalf() {
+        Allocation inNumerator = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x474bf8c3l, false);
+        Allocation inDenominator = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x5b0261a4l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.set_gAllocInDenominator(inDenominator);
+            script.forEach_testNativeAtan2piHalfHalfHalf(inNumerator, out);
+            verifyResultsNativeAtan2piHalfHalfHalf(inNumerator, inDenominator, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtan2piHalfHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInDenominator(inDenominator);
+            scriptRelaxed.forEach_testNativeAtan2piHalfHalfHalf(inNumerator, out);
+            verifyResultsNativeAtan2piHalfHalfHalf(inNumerator, inDenominator, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtan2piHalfHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAtan2piHalfHalfHalf(Allocation inNumerator, Allocation inDenominator, Allocation out, boolean relaxed) {
+        short[] arrayInNumerator = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInNumerator, (short) 42);
+        inNumerator.copyTo(arrayInNumerator);
+        short[] arrayInDenominator = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInDenominator, (short) 42);
+        inDenominator.copyTo(arrayInDenominator);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inNumerator = arrayInNumerator[i];
+                args.inNumeratorDouble = Float16Utils.convertFloat16ToDouble(args.inNumerator);
+                args.inDenominator = arrayInDenominator[i];
+                args.inDenominatorDouble = Float16Utils.convertFloat16ToDouble(args.inDenominator);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeAtan2pi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inNumerator: ");
+                        appendVariableToMessage(message, args.inNumerator);
+                        message.append("\n");
+                        message.append("Input inDenominator: ");
+                        appendVariableToMessage(message, args.inDenominator);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAtan2piHalfHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAtan2piHalf2Half2Half2() {
+        Allocation inNumerator = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x72ff66ddl, false);
+        Allocation inDenominator = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xfdf89b6el, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.set_gAllocInDenominator(inDenominator);
+            script.forEach_testNativeAtan2piHalf2Half2Half2(inNumerator, out);
+            verifyResultsNativeAtan2piHalf2Half2Half2(inNumerator, inDenominator, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtan2piHalf2Half2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInDenominator(inDenominator);
+            scriptRelaxed.forEach_testNativeAtan2piHalf2Half2Half2(inNumerator, out);
+            verifyResultsNativeAtan2piHalf2Half2Half2(inNumerator, inDenominator, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtan2piHalf2Half2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAtan2piHalf2Half2Half2(Allocation inNumerator, Allocation inDenominator, Allocation out, boolean relaxed) {
+        short[] arrayInNumerator = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInNumerator, (short) 42);
+        inNumerator.copyTo(arrayInNumerator);
+        short[] arrayInDenominator = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInDenominator, (short) 42);
+        inDenominator.copyTo(arrayInDenominator);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inNumerator = arrayInNumerator[i * 2 + j];
+                args.inNumeratorDouble = Float16Utils.convertFloat16ToDouble(args.inNumerator);
+                args.inDenominator = arrayInDenominator[i * 2 + j];
+                args.inDenominatorDouble = Float16Utils.convertFloat16ToDouble(args.inDenominator);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeAtan2pi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inNumerator: ");
+                        appendVariableToMessage(message, args.inNumerator);
+                        message.append("\n");
+                        message.append("Input inDenominator: ");
+                        appendVariableToMessage(message, args.inDenominator);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAtan2piHalf2Half2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAtan2piHalf3Half3Half3() {
+        Allocation inNumerator = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0xbe71974cl, false);
+        Allocation inDenominator = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0xe9b86d25l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.set_gAllocInDenominator(inDenominator);
+            script.forEach_testNativeAtan2piHalf3Half3Half3(inNumerator, out);
+            verifyResultsNativeAtan2piHalf3Half3Half3(inNumerator, inDenominator, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtan2piHalf3Half3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInDenominator(inDenominator);
+            scriptRelaxed.forEach_testNativeAtan2piHalf3Half3Half3(inNumerator, out);
+            verifyResultsNativeAtan2piHalf3Half3Half3(inNumerator, inDenominator, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtan2piHalf3Half3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAtan2piHalf3Half3Half3(Allocation inNumerator, Allocation inDenominator, Allocation out, boolean relaxed) {
+        short[] arrayInNumerator = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInNumerator, (short) 42);
+        inNumerator.copyTo(arrayInNumerator);
+        short[] arrayInDenominator = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInDenominator, (short) 42);
+        inDenominator.copyTo(arrayInDenominator);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inNumerator = arrayInNumerator[i * 4 + j];
+                args.inNumeratorDouble = Float16Utils.convertFloat16ToDouble(args.inNumerator);
+                args.inDenominator = arrayInDenominator[i * 4 + j];
+                args.inDenominatorDouble = Float16Utils.convertFloat16ToDouble(args.inDenominator);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeAtan2pi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inNumerator: ");
+                        appendVariableToMessage(message, args.inNumerator);
+                        message.append("\n");
+                        message.append("Input inDenominator: ");
+                        appendVariableToMessage(message, args.inDenominator);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAtan2piHalf3Half3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAtan2piHalf4Half4Half4() {
+        Allocation inNumerator = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x9e3c7bbl, false);
+        Allocation inDenominator = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xd5783edcl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.set_gAllocInDenominator(inDenominator);
+            script.forEach_testNativeAtan2piHalf4Half4Half4(inNumerator, out);
+            verifyResultsNativeAtan2piHalf4Half4Half4(inNumerator, inDenominator, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtan2piHalf4Half4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInDenominator(inDenominator);
+            scriptRelaxed.forEach_testNativeAtan2piHalf4Half4Half4(inNumerator, out);
+            verifyResultsNativeAtan2piHalf4Half4Half4(inNumerator, inDenominator, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtan2piHalf4Half4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAtan2piHalf4Half4Half4(Allocation inNumerator, Allocation inDenominator, Allocation out, boolean relaxed) {
+        short[] arrayInNumerator = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInNumerator, (short) 42);
+        inNumerator.copyTo(arrayInNumerator);
+        short[] arrayInDenominator = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInDenominator, (short) 42);
+        inDenominator.copyTo(arrayInDenominator);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inNumerator = arrayInNumerator[i * 4 + j];
+                args.inNumeratorDouble = Float16Utils.convertFloat16ToDouble(args.inNumerator);
+                args.inDenominator = arrayInDenominator[i * 4 + j];
+                args.inDenominatorDouble = Float16Utils.convertFloat16ToDouble(args.inDenominator);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeAtan2pi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inNumerator: ");
+                        appendVariableToMessage(message, args.inNumerator);
+                        message.append("\n");
+                        message.append("Input inDenominator: ");
+                        appendVariableToMessage(message, args.inDenominator);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAtan2piHalf4Half4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testNativeAtan2pi() {
         checkNativeAtan2piFloatFloatFloat();
         checkNativeAtan2piFloat2Float2Float2();
         checkNativeAtan2piFloat3Float3Float3();
         checkNativeAtan2piFloat4Float4Float4();
+        checkNativeAtan2piHalfHalfHalf();
+        checkNativeAtan2piHalf2Half2Half2();
+        checkNativeAtan2piHalf3Half3Half3();
+        checkNativeAtan2piHalf4Half4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtan2pi.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtan2pi.rs
index 5804dd5..cf3f66d 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtan2pi.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtan2pi.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -40,3 +40,23 @@
     float4 inDenominator = rsGetElementAt_float4(gAllocInDenominator, x);
     return native_atan2pi(inNumerator, inDenominator);
 }
+
+half __attribute__((kernel)) testNativeAtan2piHalfHalfHalf(half inNumerator, unsigned int x) {
+    half inDenominator = rsGetElementAt_half(gAllocInDenominator, x);
+    return native_atan2pi(inNumerator, inDenominator);
+}
+
+half2 __attribute__((kernel)) testNativeAtan2piHalf2Half2Half2(half2 inNumerator, unsigned int x) {
+    half2 inDenominator = rsGetElementAt_half2(gAllocInDenominator, x);
+    return native_atan2pi(inNumerator, inDenominator);
+}
+
+half3 __attribute__((kernel)) testNativeAtan2piHalf3Half3Half3(half3 inNumerator, unsigned int x) {
+    half3 inDenominator = rsGetElementAt_half3(gAllocInDenominator, x);
+    return native_atan2pi(inNumerator, inDenominator);
+}
+
+half4 __attribute__((kernel)) testNativeAtan2piHalf4Half4Half4(half4 inNumerator, unsigned int x) {
+    half4 inDenominator = rsGetElementAt_half4(gAllocInDenominator, x);
+    return native_atan2pi(inNumerator, inDenominator);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtan2piRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtan2piRelaxed.rs
index 48c1ea0..e5773b1 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtan2piRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtan2piRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtanRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtanRelaxed.rs
index 21be808..c4a0fad 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtanRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtanRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtanh.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtanh.java
index c37993b..f8bd311 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtanh.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtanh.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeAtanh(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeAtanh(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeAtanh(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeAtanh(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeAtanhHalfHalf() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x92b7290el, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testNativeAtanhHalfHalf(inV, out);
+            verifyResultsNativeAtanhHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanhHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAtanhHalfHalf(inV, out);
+            verifyResultsNativeAtanhHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanhHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAtanhHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeAtanh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAtanhHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAtanhHalf2Half2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x541e9440l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testNativeAtanhHalf2Half2(inV, out);
+            verifyResultsNativeAtanhHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanhHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAtanhHalf2Half2(inV, out);
+            verifyResultsNativeAtanhHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanhHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAtanhHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeAtanh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAtanhHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAtanhHalf3Half3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 3, 0xb3265934l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testNativeAtanhHalf3Half3(inV, out);
+            verifyResultsNativeAtanhHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanhHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAtanhHalf3Half3(inV, out);
+            verifyResultsNativeAtanhHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanhHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAtanhHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeAtanh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAtanhHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAtanhHalf4Half4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x122e1e28l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testNativeAtanhHalf4Half4(inV, out);
+            verifyResultsNativeAtanhHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanhHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAtanhHalf4Half4(inV, out);
+            verifyResultsNativeAtanhHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanhHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAtanhHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeAtanh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAtanhHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testNativeAtanh() {
         checkNativeAtanhFloatFloat();
         checkNativeAtanhFloat2Float2();
         checkNativeAtanhFloat3Float3();
         checkNativeAtanhFloat4Float4();
+        checkNativeAtanhHalfHalf();
+        checkNativeAtanhHalf2Half2();
+        checkNativeAtanhHalf3Half3();
+        checkNativeAtanhHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtanh.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtanh.rs
index 394e6d3..7e117f3 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtanh.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtanh.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testNativeAtanhFloat4Float4(float4 inV) {
     return native_atanh(inV);
 }
+
+half __attribute__((kernel)) testNativeAtanhHalfHalf(half inV) {
+    return native_atanh(inV);
+}
+
+half2 __attribute__((kernel)) testNativeAtanhHalf2Half2(half2 inV) {
+    return native_atanh(inV);
+}
+
+half3 __attribute__((kernel)) testNativeAtanhHalf3Half3(half3 inV) {
+    return native_atanh(inV);
+}
+
+half4 __attribute__((kernel)) testNativeAtanhHalf4Half4(half4 inV) {
+    return native_atanh(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtanhRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtanhRelaxed.rs
index d12d443..c5384fc 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtanhRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtanhRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtanpi.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtanpi.java
index 4089adb..1ae95de 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtanpi.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtanpi.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeAtanpi(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeAtanpi(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeAtanpi(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeAtanpi(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeAtanpiHalfHalf() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x8f61928fl, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testNativeAtanpiHalfHalf(inV, out);
+            verifyResultsNativeAtanpiHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanpiHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAtanpiHalfHalf(inV, out);
+            verifyResultsNativeAtanpiHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanpiHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAtanpiHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeAtanpi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAtanpiHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAtanpiHalf2Half2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x3ef298f9l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testNativeAtanpiHalf2Half2(inV, out);
+            verifyResultsNativeAtanpiHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanpiHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAtanpiHalf2Half2(inV, out);
+            verifyResultsNativeAtanpiHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanpiHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAtanpiHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeAtanpi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAtanpiHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAtanpiHalf3Half3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x9dfa5dedl, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testNativeAtanpiHalf3Half3(inV, out);
+            verifyResultsNativeAtanpiHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanpiHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAtanpiHalf3Half3(inV, out);
+            verifyResultsNativeAtanpiHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanpiHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAtanpiHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeAtanpi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAtanpiHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAtanpiHalf4Half4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xfd0222e1l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testNativeAtanpiHalf4Half4(inV, out);
+            verifyResultsNativeAtanpiHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanpiHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAtanpiHalf4Half4(inV, out);
+            verifyResultsNativeAtanpiHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanpiHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAtanpiHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeAtanpi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAtanpiHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testNativeAtanpi() {
         checkNativeAtanpiFloatFloat();
         checkNativeAtanpiFloat2Float2();
         checkNativeAtanpiFloat3Float3();
         checkNativeAtanpiFloat4Float4();
+        checkNativeAtanpiHalfHalf();
+        checkNativeAtanpiHalf2Half2();
+        checkNativeAtanpiHalf3Half3();
+        checkNativeAtanpiHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtanpi.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtanpi.rs
index 89d306c..6eb4f87 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtanpi.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtanpi.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testNativeAtanpiFloat4Float4(float4 inV) {
     return native_atanpi(inV);
 }
+
+half __attribute__((kernel)) testNativeAtanpiHalfHalf(half inV) {
+    return native_atanpi(inV);
+}
+
+half2 __attribute__((kernel)) testNativeAtanpiHalf2Half2(half2 inV) {
+    return native_atanpi(inV);
+}
+
+half3 __attribute__((kernel)) testNativeAtanpiHalf3Half3(half3 inV) {
+    return native_atanpi(inV);
+}
+
+half4 __attribute__((kernel)) testNativeAtanpiHalf4Half4(half4 inV) {
+    return native_atanpi(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtanpiRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtanpiRelaxed.rs
index 75c9ed8..66169ee 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtanpiRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtanpiRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCbrt.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCbrt.java
index 18c76bb..f561747 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCbrt.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCbrt.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeCbrt(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeCbrt(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeCbrt(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeCbrt(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeCbrtHalfHalf() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x54b706bbl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testNativeCbrtHalfHalf(inV, out);
+            verifyResultsNativeCbrtHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCbrtHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeCbrtHalfHalf(inV, out);
+            verifyResultsNativeCbrtHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCbrtHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeCbrtHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeCbrt(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeCbrtHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeCbrtHalf2Half2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x8526aac5l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testNativeCbrtHalf2Half2(inV, out);
+            verifyResultsNativeCbrtHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCbrtHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeCbrtHalf2Half2(inV, out);
+            verifyResultsNativeCbrtHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCbrtHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeCbrtHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeCbrt(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeCbrtHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeCbrtHalf3Half3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0xe42e6fb9l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testNativeCbrtHalf3Half3(inV, out);
+            verifyResultsNativeCbrtHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCbrtHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeCbrtHalf3Half3(inV, out);
+            verifyResultsNativeCbrtHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCbrtHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeCbrtHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeCbrt(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeCbrtHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeCbrtHalf4Half4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x433634adl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testNativeCbrtHalf4Half4(inV, out);
+            verifyResultsNativeCbrtHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCbrtHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeCbrtHalf4Half4(inV, out);
+            verifyResultsNativeCbrtHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCbrtHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeCbrtHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeCbrt(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeCbrtHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testNativeCbrt() {
         checkNativeCbrtFloatFloat();
         checkNativeCbrtFloat2Float2();
         checkNativeCbrtFloat3Float3();
         checkNativeCbrtFloat4Float4();
+        checkNativeCbrtHalfHalf();
+        checkNativeCbrtHalf2Half2();
+        checkNativeCbrtHalf3Half3();
+        checkNativeCbrtHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCbrt.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCbrt.rs
index f2e44fa..38e972a 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCbrt.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCbrt.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testNativeCbrtFloat4Float4(float4 inV) {
     return native_cbrt(inV);
 }
+
+half __attribute__((kernel)) testNativeCbrtHalfHalf(half inV) {
+    return native_cbrt(inV);
+}
+
+half2 __attribute__((kernel)) testNativeCbrtHalf2Half2(half2 inV) {
+    return native_cbrt(inV);
+}
+
+half3 __attribute__((kernel)) testNativeCbrtHalf3Half3(half3 inV) {
+    return native_cbrt(inV);
+}
+
+half4 __attribute__((kernel)) testNativeCbrtHalf4Half4(half4 inV) {
+    return native_cbrt(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCbrtRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCbrtRelaxed.rs
index bfc649d..522c6a5 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCbrtRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCbrtRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCos.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCos.java
index bd9c6a6..1aefbed 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCos.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCos.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeCos(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeCos(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeCos(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeCos(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeCosHalfHalf() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x8f9bf427l, -314, 314);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testNativeCosHalfHalf(inV, out);
+            verifyResultsNativeCosHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCosHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeCosHalfHalf(inV, out);
+            verifyResultsNativeCosHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCosHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeCosHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeCos(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]), 0.00048828125)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]), 0.00048828125)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeCosHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeCosHalf2Half2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xe49d7bd1l, -314, 314);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testNativeCosHalf2Half2(inV, out);
+            verifyResultsNativeCosHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCosHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeCosHalf2Half2(inV, out);
+            verifyResultsNativeCosHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCosHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeCosHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeCos(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]), 0.00048828125)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]), 0.00048828125)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeCosHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeCosHalf3Half3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x43a540c5l, -314, 314);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testNativeCosHalf3Half3(inV, out);
+            verifyResultsNativeCosHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCosHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeCosHalf3Half3(inV, out);
+            verifyResultsNativeCosHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCosHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeCosHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeCos(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]), 0.00048828125)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]), 0.00048828125)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeCosHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeCosHalf4Half4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xa2ad05b9l, -314, 314);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testNativeCosHalf4Half4(inV, out);
+            verifyResultsNativeCosHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCosHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeCosHalf4Half4(inV, out);
+            verifyResultsNativeCosHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCosHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeCosHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeCos(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]), 0.00048828125)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]), 0.00048828125)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeCosHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testNativeCos() {
         checkNativeCosFloatFloat();
         checkNativeCosFloat2Float2();
         checkNativeCosFloat3Float3();
         checkNativeCosFloat4Float4();
+        checkNativeCosHalfHalf();
+        checkNativeCosHalf2Half2();
+        checkNativeCosHalf3Half3();
+        checkNativeCosHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCos.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCos.rs
index 6717d50..dac5219 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCos.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCos.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testNativeCosFloat4Float4(float4 inV) {
     return native_cos(inV);
 }
+
+half __attribute__((kernel)) testNativeCosHalfHalf(half inV) {
+    return native_cos(inV);
+}
+
+half2 __attribute__((kernel)) testNativeCosHalf2Half2(half2 inV) {
+    return native_cos(inV);
+}
+
+half3 __attribute__((kernel)) testNativeCosHalf3Half3(half3 inV) {
+    return native_cos(inV);
+}
+
+half4 __attribute__((kernel)) testNativeCosHalf4Half4(half4 inV) {
+    return native_cos(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCosRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCosRelaxed.rs
index 2c38290..3ab21d9 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCosRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCosRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCosh.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCosh.java
index 7bdab28..4d5ec23 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCosh.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCosh.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeCosh(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeCosh(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeCosh(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeCosh(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeCoshHalfHalf() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xf3df9f87l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testNativeCoshHalfHalf(inV, out);
+            verifyResultsNativeCoshHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCoshHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeCoshHalfHalf(inV, out);
+            verifyResultsNativeCoshHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCoshHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeCoshHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeCosh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeCoshHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeCoshHalf2Half2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x115e4431l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testNativeCoshHalf2Half2(inV, out);
+            verifyResultsNativeCoshHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCoshHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeCoshHalf2Half2(inV, out);
+            verifyResultsNativeCoshHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCoshHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeCoshHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeCosh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeCoshHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeCoshHalf3Half3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x70660925l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testNativeCoshHalf3Half3(inV, out);
+            verifyResultsNativeCoshHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCoshHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeCoshHalf3Half3(inV, out);
+            verifyResultsNativeCoshHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCoshHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeCoshHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeCosh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeCoshHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeCoshHalf4Half4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xcf6dce19l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testNativeCoshHalf4Half4(inV, out);
+            verifyResultsNativeCoshHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCoshHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeCoshHalf4Half4(inV, out);
+            verifyResultsNativeCoshHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCoshHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeCoshHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeCosh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeCoshHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testNativeCosh() {
         checkNativeCoshFloatFloat();
         checkNativeCoshFloat2Float2();
         checkNativeCoshFloat3Float3();
         checkNativeCoshFloat4Float4();
+        checkNativeCoshHalfHalf();
+        checkNativeCoshHalf2Half2();
+        checkNativeCoshHalf3Half3();
+        checkNativeCoshHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCosh.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCosh.rs
index 1a0eb5a..364c84e 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCosh.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCosh.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testNativeCoshFloat4Float4(float4 inV) {
     return native_cosh(inV);
 }
+
+half __attribute__((kernel)) testNativeCoshHalfHalf(half inV) {
+    return native_cosh(inV);
+}
+
+half2 __attribute__((kernel)) testNativeCoshHalf2Half2(half2 inV) {
+    return native_cosh(inV);
+}
+
+half3 __attribute__((kernel)) testNativeCoshHalf3Half3(half3 inV) {
+    return native_cosh(inV);
+}
+
+half4 __attribute__((kernel)) testNativeCoshHalf4Half4(half4 inV) {
+    return native_cosh(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCoshRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCoshRelaxed.rs
index 278dbe4..e549630 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCoshRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCoshRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCospi.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCospi.java
index 91b4426..5a6aa10 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCospi.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCospi.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeCospi(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeCospi(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeCospi(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeCospi(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeCospiHalfHalf() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xe12d78e2l, -100, 100);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testNativeCospiHalfHalf(inV, out);
+            verifyResultsNativeCospiHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCospiHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeCospiHalfHalf(inV, out);
+            verifyResultsNativeCospiHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCospiHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeCospiHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeCospi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]), 0.00048828125)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]), 0.00048828125)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeCospiHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeCospiHalf2Half2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x8a52674l, -100, 100);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testNativeCospiHalf2Half2(inV, out);
+            verifyResultsNativeCospiHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCospiHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeCospiHalf2Half2(inV, out);
+            verifyResultsNativeCospiHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCospiHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeCospiHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeCospi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]), 0.00048828125)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]), 0.00048828125)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeCospiHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeCospiHalf3Half3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x67aceb68l, -100, 100);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testNativeCospiHalf3Half3(inV, out);
+            verifyResultsNativeCospiHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCospiHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeCospiHalf3Half3(inV, out);
+            verifyResultsNativeCospiHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCospiHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeCospiHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeCospi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]), 0.00048828125)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]), 0.00048828125)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeCospiHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeCospiHalf4Half4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xc6b4b05cl, -100, 100);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testNativeCospiHalf4Half4(inV, out);
+            verifyResultsNativeCospiHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCospiHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeCospiHalf4Half4(inV, out);
+            verifyResultsNativeCospiHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCospiHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeCospiHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeCospi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]), 0.00048828125)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]), 0.00048828125)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeCospiHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testNativeCospi() {
         checkNativeCospiFloatFloat();
         checkNativeCospiFloat2Float2();
         checkNativeCospiFloat3Float3();
         checkNativeCospiFloat4Float4();
+        checkNativeCospiHalfHalf();
+        checkNativeCospiHalf2Half2();
+        checkNativeCospiHalf3Half3();
+        checkNativeCospiHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCospi.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCospi.rs
index d7aedb5..fbb5028 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCospi.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCospi.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testNativeCospiFloat4Float4(float4 inV) {
     return native_cospi(inV);
 }
+
+half __attribute__((kernel)) testNativeCospiHalfHalf(half inV) {
+    return native_cospi(inV);
+}
+
+half2 __attribute__((kernel)) testNativeCospiHalf2Half2(half2 inV) {
+    return native_cospi(inV);
+}
+
+half3 __attribute__((kernel)) testNativeCospiHalf3Half3(half3 inV) {
+    return native_cospi(inV);
+}
+
+half4 __attribute__((kernel)) testNativeCospiHalf4Half4(half4 inV) {
+    return native_cospi(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCospiRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCospiRelaxed.rs
index 8b57ea0..a37ecea 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCospiRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCospiRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeDistance.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeDistance.java
index 8485d16..ced227b 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeDistance.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeDistance.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -81,7 +82,7 @@
             // Fill args with the input values
             args.inLeftVector = arrayInLeftVector[i];
             args.inRightVector = arrayInRightVector[i];
-            Target target = new Target(relaxed);
+            Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
             CoreMathVerifier.computeNativeDistance(args, target);
 
             // Compare the expected outputs to the actual values returned by RS.
@@ -169,7 +170,7 @@
             for (int j = 0; j < 2 ; j++) {
                 args.inRightVector[j] = arrayInRightVector[i * 2 + j];
             }
-            Target target = new Target(relaxed);
+            Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
             CoreMathVerifier.computeNativeDistance(args, target);
 
             // Compare the expected outputs to the actual values returned by RS.
@@ -255,7 +256,7 @@
             for (int j = 0; j < 3 ; j++) {
                 args.inRightVector[j] = arrayInRightVector[i * 4 + j];
             }
-            Target target = new Target(relaxed);
+            Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
             CoreMathVerifier.computeNativeDistance(args, target);
 
             // Compare the expected outputs to the actual values returned by RS.
@@ -341,7 +342,7 @@
             for (int j = 0; j < 4 ; j++) {
                 args.inRightVector[j] = arrayInRightVector[i * 4 + j];
             }
-            Target target = new Target(relaxed);
+            Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
             CoreMathVerifier.computeNativeDistance(args, target);
 
             // Compare the expected outputs to the actual values returned by RS.
@@ -382,10 +383,390 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalfHalf {
+        public short inLeftVector;
+        public double inLeftVectorDouble;
+        public short inRightVector;
+        public double inRightVectorDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeDistanceHalfHalfHalf() {
+        Allocation inLeftVector = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x4093c950l, false);
+        Allocation inRightVector = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x46eb99f5l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.set_gAllocInRightVector(inRightVector);
+            script.forEach_testNativeDistanceHalfHalfHalf(inLeftVector, out);
+            verifyResultsNativeDistanceHalfHalfHalf(inLeftVector, inRightVector, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeDistanceHalfHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInRightVector(inRightVector);
+            scriptRelaxed.forEach_testNativeDistanceHalfHalfHalf(inLeftVector, out);
+            verifyResultsNativeDistanceHalfHalfHalf(inLeftVector, inRightVector, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeDistanceHalfHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeDistanceHalfHalfHalf(Allocation inLeftVector, Allocation inRightVector, Allocation out, boolean relaxed) {
+        short[] arrayInLeftVector = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInLeftVector, (short) 42);
+        inLeftVector.copyTo(arrayInLeftVector);
+        short[] arrayInRightVector = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInRightVector, (short) 42);
+        inRightVector.copyTo(arrayInRightVector);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+            // Create the appropriate sized arrays in args
+            // Fill args with the input values
+            args.inLeftVector = arrayInLeftVector[i];
+            args.inLeftVectorDouble = Float16Utils.convertFloat16ToDouble(args.inLeftVector);
+            args.inRightVector = arrayInRightVector[i];
+            args.inRightVectorDouble = Float16Utils.convertFloat16ToDouble(args.inRightVector);
+            Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+            CoreMathVerifier.computeNativeDistance(args, target);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i]))) {
+                valid = false;
+            }
+            if (!valid) {
+                if (!errorFound) {
+                    errorFound = true;
+                    message.append("Input inLeftVector: ");
+                    appendVariableToMessage(message, arrayInLeftVector[i]);
+                    message.append("\n");
+                    message.append("Input inRightVector: ");
+                    appendVariableToMessage(message, arrayInRightVector[i]);
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    appendVariableToMessage(message, args.out);
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    appendVariableToMessage(message, arrayOut[i]);
+                    message.append("\n");
+                    message.append("Actual   output out (in double): ");
+                    appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i]));
+                    if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i]))) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    message.append("Errors at");
+                }
+                message.append(" [");
+                message.append(Integer.toString(i));
+                message.append("]");
+            }
+        }
+        assertFalse("Incorrect output for checkNativeDistanceHalfHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsHalfNHalfNHalf {
+        public short[] inLeftVector;
+        public double[] inLeftVectorDouble;
+        public short[] inRightVector;
+        public double[] inRightVectorDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeDistanceHalf2Half2Half() {
+        Allocation inLeftVector = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x30493el, false);
+        Allocation inRightVector = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x763516efl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.set_gAllocInRightVector(inRightVector);
+            script.forEach_testNativeDistanceHalf2Half2Half(inLeftVector, out);
+            verifyResultsNativeDistanceHalf2Half2Half(inLeftVector, inRightVector, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeDistanceHalf2Half2Half: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInRightVector(inRightVector);
+            scriptRelaxed.forEach_testNativeDistanceHalf2Half2Half(inLeftVector, out);
+            verifyResultsNativeDistanceHalf2Half2Half(inLeftVector, inRightVector, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeDistanceHalf2Half2Half: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeDistanceHalf2Half2Half(Allocation inLeftVector, Allocation inRightVector, Allocation out, boolean relaxed) {
+        short[] arrayInLeftVector = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInLeftVector, (short) 42);
+        inLeftVector.copyTo(arrayInLeftVector);
+        short[] arrayInRightVector = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInRightVector, (short) 42);
+        inRightVector.copyTo(arrayInRightVector);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsHalfNHalfNHalf args = new ArgumentsHalfNHalfNHalf();
+            // Create the appropriate sized arrays in args
+            args.inLeftVector = new short[2];
+            args.inLeftVectorDouble = new double[2];
+            args.inRightVector = new short[2];
+            args.inRightVectorDouble = new double[2];
+            // Fill args with the input values
+            for (int j = 0; j < 2 ; j++) {
+                args.inLeftVector[j] = arrayInLeftVector[i * 2 + j];
+                args.inLeftVectorDouble[j] = Float16Utils.convertFloat16ToDouble(args.inLeftVector[j]);
+            }
+            for (int j = 0; j < 2 ; j++) {
+                args.inRightVector[j] = arrayInRightVector[i * 2 + j];
+                args.inRightVectorDouble[j] = Float16Utils.convertFloat16ToDouble(args.inRightVector[j]);
+            }
+            Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+            CoreMathVerifier.computeNativeDistance(args, target);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i]))) {
+                valid = false;
+            }
+            if (!valid) {
+                if (!errorFound) {
+                    errorFound = true;
+                    for (int j = 0; j < 2 ; j++) {
+                        message.append("Input inLeftVector: ");
+                        appendVariableToMessage(message, arrayInLeftVector[i * 2 + j]);
+                        message.append("\n");
+                    }
+                    for (int j = 0; j < 2 ; j++) {
+                        message.append("Input inRightVector: ");
+                        appendVariableToMessage(message, arrayInRightVector[i * 2 + j]);
+                        message.append("\n");
+                    }
+                    message.append("Expected output out: ");
+                    appendVariableToMessage(message, args.out);
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    appendVariableToMessage(message, arrayOut[i]);
+                    message.append("\n");
+                    message.append("Actual   output out (in double): ");
+                    appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i]));
+                    if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i]))) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    message.append("Errors at");
+                }
+                message.append(" [");
+                message.append(Integer.toString(i));
+                message.append("]");
+            }
+        }
+        assertFalse("Incorrect output for checkNativeDistanceHalf2Half2Half" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeDistanceHalf3Half3Half() {
+        Allocation inLeftVector = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0xca7541fal, false);
+        Allocation inRightVector = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x6fcade83l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.set_gAllocInRightVector(inRightVector);
+            script.forEach_testNativeDistanceHalf3Half3Half(inLeftVector, out);
+            verifyResultsNativeDistanceHalf3Half3Half(inLeftVector, inRightVector, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeDistanceHalf3Half3Half: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInRightVector(inRightVector);
+            scriptRelaxed.forEach_testNativeDistanceHalf3Half3Half(inLeftVector, out);
+            verifyResultsNativeDistanceHalf3Half3Half(inLeftVector, inRightVector, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeDistanceHalf3Half3Half: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeDistanceHalf3Half3Half(Allocation inLeftVector, Allocation inRightVector, Allocation out, boolean relaxed) {
+        short[] arrayInLeftVector = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInLeftVector, (short) 42);
+        inLeftVector.copyTo(arrayInLeftVector);
+        short[] arrayInRightVector = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInRightVector, (short) 42);
+        inRightVector.copyTo(arrayInRightVector);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsHalfNHalfNHalf args = new ArgumentsHalfNHalfNHalf();
+            // Create the appropriate sized arrays in args
+            args.inLeftVector = new short[3];
+            args.inLeftVectorDouble = new double[3];
+            args.inRightVector = new short[3];
+            args.inRightVectorDouble = new double[3];
+            // Fill args with the input values
+            for (int j = 0; j < 3 ; j++) {
+                args.inLeftVector[j] = arrayInLeftVector[i * 4 + j];
+                args.inLeftVectorDouble[j] = Float16Utils.convertFloat16ToDouble(args.inLeftVector[j]);
+            }
+            for (int j = 0; j < 3 ; j++) {
+                args.inRightVector[j] = arrayInRightVector[i * 4 + j];
+                args.inRightVectorDouble[j] = Float16Utils.convertFloat16ToDouble(args.inRightVector[j]);
+            }
+            Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+            CoreMathVerifier.computeNativeDistance(args, target);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i]))) {
+                valid = false;
+            }
+            if (!valid) {
+                if (!errorFound) {
+                    errorFound = true;
+                    for (int j = 0; j < 3 ; j++) {
+                        message.append("Input inLeftVector: ");
+                        appendVariableToMessage(message, arrayInLeftVector[i * 4 + j]);
+                        message.append("\n");
+                    }
+                    for (int j = 0; j < 3 ; j++) {
+                        message.append("Input inRightVector: ");
+                        appendVariableToMessage(message, arrayInRightVector[i * 4 + j]);
+                        message.append("\n");
+                    }
+                    message.append("Expected output out: ");
+                    appendVariableToMessage(message, args.out);
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    appendVariableToMessage(message, arrayOut[i]);
+                    message.append("\n");
+                    message.append("Actual   output out (in double): ");
+                    appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i]));
+                    if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i]))) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    message.append("Errors at");
+                }
+                message.append(" [");
+                message.append(Integer.toString(i));
+                message.append("]");
+            }
+        }
+        assertFalse("Incorrect output for checkNativeDistanceHalf3Half3Half" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeDistanceHalf4Half4Half() {
+        Allocation inLeftVector = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x94ba3ab6l, false);
+        Allocation inRightVector = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x6960a617l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.set_gAllocInRightVector(inRightVector);
+            script.forEach_testNativeDistanceHalf4Half4Half(inLeftVector, out);
+            verifyResultsNativeDistanceHalf4Half4Half(inLeftVector, inRightVector, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeDistanceHalf4Half4Half: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInRightVector(inRightVector);
+            scriptRelaxed.forEach_testNativeDistanceHalf4Half4Half(inLeftVector, out);
+            verifyResultsNativeDistanceHalf4Half4Half(inLeftVector, inRightVector, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeDistanceHalf4Half4Half: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeDistanceHalf4Half4Half(Allocation inLeftVector, Allocation inRightVector, Allocation out, boolean relaxed) {
+        short[] arrayInLeftVector = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInLeftVector, (short) 42);
+        inLeftVector.copyTo(arrayInLeftVector);
+        short[] arrayInRightVector = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInRightVector, (short) 42);
+        inRightVector.copyTo(arrayInRightVector);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsHalfNHalfNHalf args = new ArgumentsHalfNHalfNHalf();
+            // Create the appropriate sized arrays in args
+            args.inLeftVector = new short[4];
+            args.inLeftVectorDouble = new double[4];
+            args.inRightVector = new short[4];
+            args.inRightVectorDouble = new double[4];
+            // Fill args with the input values
+            for (int j = 0; j < 4 ; j++) {
+                args.inLeftVector[j] = arrayInLeftVector[i * 4 + j];
+                args.inLeftVectorDouble[j] = Float16Utils.convertFloat16ToDouble(args.inLeftVector[j]);
+            }
+            for (int j = 0; j < 4 ; j++) {
+                args.inRightVector[j] = arrayInRightVector[i * 4 + j];
+                args.inRightVectorDouble[j] = Float16Utils.convertFloat16ToDouble(args.inRightVector[j]);
+            }
+            Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+            CoreMathVerifier.computeNativeDistance(args, target);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i]))) {
+                valid = false;
+            }
+            if (!valid) {
+                if (!errorFound) {
+                    errorFound = true;
+                    for (int j = 0; j < 4 ; j++) {
+                        message.append("Input inLeftVector: ");
+                        appendVariableToMessage(message, arrayInLeftVector[i * 4 + j]);
+                        message.append("\n");
+                    }
+                    for (int j = 0; j < 4 ; j++) {
+                        message.append("Input inRightVector: ");
+                        appendVariableToMessage(message, arrayInRightVector[i * 4 + j]);
+                        message.append("\n");
+                    }
+                    message.append("Expected output out: ");
+                    appendVariableToMessage(message, args.out);
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    appendVariableToMessage(message, arrayOut[i]);
+                    message.append("\n");
+                    message.append("Actual   output out (in double): ");
+                    appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i]));
+                    if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i]))) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    message.append("Errors at");
+                }
+                message.append(" [");
+                message.append(Integer.toString(i));
+                message.append("]");
+            }
+        }
+        assertFalse("Incorrect output for checkNativeDistanceHalf4Half4Half" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testNativeDistance() {
         checkNativeDistanceFloatFloatFloat();
         checkNativeDistanceFloat2Float2Float();
         checkNativeDistanceFloat3Float3Float();
         checkNativeDistanceFloat4Float4Float();
+        checkNativeDistanceHalfHalfHalf();
+        checkNativeDistanceHalf2Half2Half();
+        checkNativeDistanceHalf3Half3Half();
+        checkNativeDistanceHalf4Half4Half();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeDistance.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeDistance.rs
index 3f9c64e..de717e6 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeDistance.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeDistance.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -40,3 +40,23 @@
     float4 inRightVector = rsGetElementAt_float4(gAllocInRightVector, x);
     return native_distance(inLeftVector, inRightVector);
 }
+
+half __attribute__((kernel)) testNativeDistanceHalfHalfHalf(half inLeftVector, unsigned int x) {
+    half inRightVector = rsGetElementAt_half(gAllocInRightVector, x);
+    return native_distance(inLeftVector, inRightVector);
+}
+
+half __attribute__((kernel)) testNativeDistanceHalf2Half2Half(half2 inLeftVector, unsigned int x) {
+    half2 inRightVector = rsGetElementAt_half2(gAllocInRightVector, x);
+    return native_distance(inLeftVector, inRightVector);
+}
+
+half __attribute__((kernel)) testNativeDistanceHalf3Half3Half(half3 inLeftVector, unsigned int x) {
+    half3 inRightVector = rsGetElementAt_half3(gAllocInRightVector, x);
+    return native_distance(inLeftVector, inRightVector);
+}
+
+half __attribute__((kernel)) testNativeDistanceHalf4Half4Half(half4 inLeftVector, unsigned int x) {
+    half4 inRightVector = rsGetElementAt_half4(gAllocInRightVector, x);
+    return native_distance(inLeftVector, inRightVector);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeDistanceRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeDistanceRelaxed.rs
index b35e456..0d2770b 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeDistanceRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeDistanceRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeDivide.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeDivide.java
index 194a4df..603e92f 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeDivide.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeDivide.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -82,7 +83,7 @@
                 args.inLeftVector = arrayInLeftVector[i];
                 args.inRightVector = arrayInRightVector[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeDivide(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -161,7 +162,7 @@
                 args.inLeftVector = arrayInLeftVector[i * 2 + j];
                 args.inRightVector = arrayInRightVector[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeDivide(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -240,7 +241,7 @@
                 args.inLeftVector = arrayInLeftVector[i * 4 + j];
                 args.inRightVector = arrayInRightVector[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeDivide(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -319,7 +320,7 @@
                 args.inLeftVector = arrayInLeftVector[i * 4 + j];
                 args.inRightVector = arrayInRightVector[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeDivide(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -358,10 +359,358 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalfHalf {
+        public short inLeftVector;
+        public double inLeftVectorDouble;
+        public short inRightVector;
+        public double inRightVectorDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeDivideHalfHalfHalf() {
+        Allocation inLeftVector = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xaeea6bb8l, false);
+        Allocation inRightVector = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xcf78e16dl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.set_gAllocInRightVector(inRightVector);
+            script.forEach_testNativeDivideHalfHalfHalf(inLeftVector, out);
+            verifyResultsNativeDivideHalfHalfHalf(inLeftVector, inRightVector, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeDivideHalfHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInRightVector(inRightVector);
+            scriptRelaxed.forEach_testNativeDivideHalfHalfHalf(inLeftVector, out);
+            verifyResultsNativeDivideHalfHalfHalf(inLeftVector, inRightVector, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeDivideHalfHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeDivideHalfHalfHalf(Allocation inLeftVector, Allocation inRightVector, Allocation out, boolean relaxed) {
+        short[] arrayInLeftVector = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInLeftVector, (short) 42);
+        inLeftVector.copyTo(arrayInLeftVector);
+        short[] arrayInRightVector = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInRightVector, (short) 42);
+        inRightVector.copyTo(arrayInRightVector);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inLeftVector = arrayInLeftVector[i];
+                args.inLeftVectorDouble = Float16Utils.convertFloat16ToDouble(args.inLeftVector);
+                args.inRightVector = arrayInRightVector[i];
+                args.inRightVectorDouble = Float16Utils.convertFloat16ToDouble(args.inRightVector);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeDivide(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inLeftVector: ");
+                        appendVariableToMessage(message, args.inLeftVector);
+                        message.append("\n");
+                        message.append("Input inRightVector: ");
+                        appendVariableToMessage(message, args.inRightVector);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeDivideHalfHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeDivideHalf2Half2Half2() {
+        Allocation inLeftVector = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x15982fb6l, false);
+        Allocation inRightVector = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xea8cd17l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.set_gAllocInRightVector(inRightVector);
+            script.forEach_testNativeDivideHalf2Half2Half2(inLeftVector, out);
+            verifyResultsNativeDivideHalf2Half2Half2(inLeftVector, inRightVector, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeDivideHalf2Half2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInRightVector(inRightVector);
+            scriptRelaxed.forEach_testNativeDivideHalf2Half2Half2(inLeftVector, out);
+            verifyResultsNativeDivideHalf2Half2Half2(inLeftVector, inRightVector, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeDivideHalf2Half2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeDivideHalf2Half2Half2(Allocation inLeftVector, Allocation inRightVector, Allocation out, boolean relaxed) {
+        short[] arrayInLeftVector = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInLeftVector, (short) 42);
+        inLeftVector.copyTo(arrayInLeftVector);
+        short[] arrayInRightVector = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInRightVector, (short) 42);
+        inRightVector.copyTo(arrayInRightVector);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inLeftVector = arrayInLeftVector[i * 2 + j];
+                args.inLeftVectorDouble = Float16Utils.convertFloat16ToDouble(args.inLeftVector);
+                args.inRightVector = arrayInRightVector[i * 2 + j];
+                args.inRightVectorDouble = Float16Utils.convertFloat16ToDouble(args.inRightVector);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeDivide(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inLeftVector: ");
+                        appendVariableToMessage(message, args.inLeftVector);
+                        message.append("\n");
+                        message.append("Input inRightVector: ");
+                        appendVariableToMessage(message, args.inRightVector);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeDivideHalf2Half2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeDivideHalf3Half3Half3() {
+        Allocation inLeftVector = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0xc1c6525bl, false);
+        Allocation inRightVector = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0xfa689ecel, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.set_gAllocInRightVector(inRightVector);
+            script.forEach_testNativeDivideHalf3Half3Half3(inLeftVector, out);
+            verifyResultsNativeDivideHalf3Half3Half3(inLeftVector, inRightVector, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeDivideHalf3Half3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInRightVector(inRightVector);
+            scriptRelaxed.forEach_testNativeDivideHalf3Half3Half3(inLeftVector, out);
+            verifyResultsNativeDivideHalf3Half3Half3(inLeftVector, inRightVector, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeDivideHalf3Half3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeDivideHalf3Half3Half3(Allocation inLeftVector, Allocation inRightVector, Allocation out, boolean relaxed) {
+        short[] arrayInLeftVector = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInLeftVector, (short) 42);
+        inLeftVector.copyTo(arrayInLeftVector);
+        short[] arrayInRightVector = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInRightVector, (short) 42);
+        inRightVector.copyTo(arrayInRightVector);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inLeftVector = arrayInLeftVector[i * 4 + j];
+                args.inLeftVectorDouble = Float16Utils.convertFloat16ToDouble(args.inLeftVector);
+                args.inRightVector = arrayInRightVector[i * 4 + j];
+                args.inRightVectorDouble = Float16Utils.convertFloat16ToDouble(args.inRightVector);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeDivide(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inLeftVector: ");
+                        appendVariableToMessage(message, args.inLeftVector);
+                        message.append("\n");
+                        message.append("Input inRightVector: ");
+                        appendVariableToMessage(message, args.inRightVector);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeDivideHalf3Half3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeDivideHalf4Half4Half4() {
+        Allocation inLeftVector = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x6df47500l, false);
+        Allocation inRightVector = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xe6287085l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.set_gAllocInRightVector(inRightVector);
+            script.forEach_testNativeDivideHalf4Half4Half4(inLeftVector, out);
+            verifyResultsNativeDivideHalf4Half4Half4(inLeftVector, inRightVector, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeDivideHalf4Half4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInRightVector(inRightVector);
+            scriptRelaxed.forEach_testNativeDivideHalf4Half4Half4(inLeftVector, out);
+            verifyResultsNativeDivideHalf4Half4Half4(inLeftVector, inRightVector, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeDivideHalf4Half4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeDivideHalf4Half4Half4(Allocation inLeftVector, Allocation inRightVector, Allocation out, boolean relaxed) {
+        short[] arrayInLeftVector = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInLeftVector, (short) 42);
+        inLeftVector.copyTo(arrayInLeftVector);
+        short[] arrayInRightVector = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInRightVector, (short) 42);
+        inRightVector.copyTo(arrayInRightVector);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inLeftVector = arrayInLeftVector[i * 4 + j];
+                args.inLeftVectorDouble = Float16Utils.convertFloat16ToDouble(args.inLeftVector);
+                args.inRightVector = arrayInRightVector[i * 4 + j];
+                args.inRightVectorDouble = Float16Utils.convertFloat16ToDouble(args.inRightVector);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeDivide(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inLeftVector: ");
+                        appendVariableToMessage(message, args.inLeftVector);
+                        message.append("\n");
+                        message.append("Input inRightVector: ");
+                        appendVariableToMessage(message, args.inRightVector);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeDivideHalf4Half4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testNativeDivide() {
         checkNativeDivideFloatFloatFloat();
         checkNativeDivideFloat2Float2Float2();
         checkNativeDivideFloat3Float3Float3();
         checkNativeDivideFloat4Float4Float4();
+        checkNativeDivideHalfHalfHalf();
+        checkNativeDivideHalf2Half2Half2();
+        checkNativeDivideHalf3Half3Half3();
+        checkNativeDivideHalf4Half4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeDivide.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeDivide.rs
index 6a4a6a4..7bb31c0 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeDivide.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeDivide.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -40,3 +40,23 @@
     float4 inRightVector = rsGetElementAt_float4(gAllocInRightVector, x);
     return native_divide(inLeftVector, inRightVector);
 }
+
+half __attribute__((kernel)) testNativeDivideHalfHalfHalf(half inLeftVector, unsigned int x) {
+    half inRightVector = rsGetElementAt_half(gAllocInRightVector, x);
+    return native_divide(inLeftVector, inRightVector);
+}
+
+half2 __attribute__((kernel)) testNativeDivideHalf2Half2Half2(half2 inLeftVector, unsigned int x) {
+    half2 inRightVector = rsGetElementAt_half2(gAllocInRightVector, x);
+    return native_divide(inLeftVector, inRightVector);
+}
+
+half3 __attribute__((kernel)) testNativeDivideHalf3Half3Half3(half3 inLeftVector, unsigned int x) {
+    half3 inRightVector = rsGetElementAt_half3(gAllocInRightVector, x);
+    return native_divide(inLeftVector, inRightVector);
+}
+
+half4 __attribute__((kernel)) testNativeDivideHalf4Half4Half4(half4 inLeftVector, unsigned int x) {
+    half4 inRightVector = rsGetElementAt_half4(gAllocInRightVector, x);
+    return native_divide(inLeftVector, inRightVector);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeDivideRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeDivideRelaxed.rs
index b0a48f5..32ae7c6 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeDivideRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeDivideRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExp.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExp.java
index 3643235..baef7bd 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExp.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExp.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeExp(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeExp(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeExp(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeExp(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeExpHalfHalf() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x529e185dl, -86, 86);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testNativeExpHalfHalf(inV, out);
+            verifyResultsNativeExpHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExpHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeExpHalfHalf(inV, out);
+            verifyResultsNativeExpHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExpHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeExpHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeExp(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeExpHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeExpHalf2Half2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x5f1505d7l, -86, 86);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testNativeExpHalf2Half2(inV, out);
+            verifyResultsNativeExpHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExpHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeExpHalf2Half2(inV, out);
+            verifyResultsNativeExpHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExpHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeExpHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeExp(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeExpHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeExpHalf3Half3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 3, 0xbe1ccacbl, -86, 86);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testNativeExpHalf3Half3(inV, out);
+            verifyResultsNativeExpHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExpHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeExpHalf3Half3(inV, out);
+            verifyResultsNativeExpHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExpHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeExpHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeExp(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeExpHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeExpHalf4Half4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x1d248fbfl, -86, 86);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testNativeExpHalf4Half4(inV, out);
+            verifyResultsNativeExpHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExpHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeExpHalf4Half4(inV, out);
+            verifyResultsNativeExpHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExpHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeExpHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeExp(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeExpHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testNativeExp() {
         checkNativeExpFloatFloat();
         checkNativeExpFloat2Float2();
         checkNativeExpFloat3Float3();
         checkNativeExpFloat4Float4();
+        checkNativeExpHalfHalf();
+        checkNativeExpHalf2Half2();
+        checkNativeExpHalf3Half3();
+        checkNativeExpHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExp.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExp.rs
index 92e31dc..2128469 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExp.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExp.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testNativeExpFloat4Float4(float4 inV) {
     return native_exp(inV);
 }
+
+half __attribute__((kernel)) testNativeExpHalfHalf(half inV) {
+    return native_exp(inV);
+}
+
+half2 __attribute__((kernel)) testNativeExpHalf2Half2(half2 inV) {
+    return native_exp(inV);
+}
+
+half3 __attribute__((kernel)) testNativeExpHalf3Half3(half3 inV) {
+    return native_exp(inV);
+}
+
+half4 __attribute__((kernel)) testNativeExpHalf4Half4(half4 inV) {
+    return native_exp(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExp10.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExp10.java
index 36996f9..6ff9a35 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExp10.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExp10.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeExp10(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeExp10(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeExp10(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeExp10(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeExp10HalfHalf() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xa51532del, -37, 37);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testNativeExp10HalfHalf(inV, out);
+            verifyResultsNativeExp10HalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExp10HalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeExp10HalfHalf(inV, out);
+            verifyResultsNativeExp10HalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExp10HalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeExp10HalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeExp10(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeExp10HalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeExp10Half2Half2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xfd537390l, -37, 37);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testNativeExp10Half2Half2(inV, out);
+            verifyResultsNativeExp10Half2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExp10Half2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeExp10Half2Half2(inV, out);
+            verifyResultsNativeExp10Half2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExp10Half2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeExp10Half2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeExp10(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeExp10Half2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeExp10Half3Half3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x5c5b3884l, -37, 37);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testNativeExp10Half3Half3(inV, out);
+            verifyResultsNativeExp10Half3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExp10Half3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeExp10Half3Half3(inV, out);
+            verifyResultsNativeExp10Half3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExp10Half3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeExp10Half3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeExp10(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeExp10Half3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeExp10Half4Half4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xbb62fd78l, -37, 37);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testNativeExp10Half4Half4(inV, out);
+            verifyResultsNativeExp10Half4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExp10Half4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeExp10Half4Half4(inV, out);
+            verifyResultsNativeExp10Half4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExp10Half4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeExp10Half4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeExp10(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeExp10Half4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testNativeExp10() {
         checkNativeExp10FloatFloat();
         checkNativeExp10Float2Float2();
         checkNativeExp10Float3Float3();
         checkNativeExp10Float4Float4();
+        checkNativeExp10HalfHalf();
+        checkNativeExp10Half2Half2();
+        checkNativeExp10Half3Half3();
+        checkNativeExp10Half4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExp10.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExp10.rs
index 475d70c..93130220 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExp10.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExp10.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testNativeExp10Float4Float4(float4 inV) {
     return native_exp10(inV);
 }
+
+half __attribute__((kernel)) testNativeExp10HalfHalf(half inV) {
+    return native_exp10(inV);
+}
+
+half2 __attribute__((kernel)) testNativeExp10Half2Half2(half2 inV) {
+    return native_exp10(inV);
+}
+
+half3 __attribute__((kernel)) testNativeExp10Half3Half3(half3 inV) {
+    return native_exp10(inV);
+}
+
+half4 __attribute__((kernel)) testNativeExp10Half4Half4(half4 inV) {
+    return native_exp10(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExp10Relaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExp10Relaxed.rs
index ff433f9..4883cdf 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExp10Relaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExp10Relaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExp2.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExp2.java
index 3ed45e4..4fc5cef 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExp2.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExp2.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeExp2(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeExp2(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeExp2(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeExp2(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeExp2HalfHalf() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x75b1f4d7l, -125, 125);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testNativeExp2HalfHalf(inV, out);
+            verifyResultsNativeExp2HalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExp2HalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeExp2HalfHalf(inV, out);
+            verifyResultsNativeExp2HalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExp2HalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeExp2HalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeExp2(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeExp2HalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeExp2Half2Half2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xb9887301l, -125, 125);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testNativeExp2Half2Half2(inV, out);
+            verifyResultsNativeExp2Half2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExp2Half2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeExp2Half2Half2(inV, out);
+            verifyResultsNativeExp2Half2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExp2Half2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeExp2Half2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeExp2(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeExp2Half2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeExp2Half3Half3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x189037f5l, -125, 125);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testNativeExp2Half3Half3(inV, out);
+            verifyResultsNativeExp2Half3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExp2Half3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeExp2Half3Half3(inV, out);
+            verifyResultsNativeExp2Half3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExp2Half3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeExp2Half3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeExp2(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeExp2Half3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeExp2Half4Half4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x7797fce9l, -125, 125);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testNativeExp2Half4Half4(inV, out);
+            verifyResultsNativeExp2Half4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExp2Half4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeExp2Half4Half4(inV, out);
+            verifyResultsNativeExp2Half4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExp2Half4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeExp2Half4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeExp2(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeExp2Half4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testNativeExp2() {
         checkNativeExp2FloatFloat();
         checkNativeExp2Float2Float2();
         checkNativeExp2Float3Float3();
         checkNativeExp2Float4Float4();
+        checkNativeExp2HalfHalf();
+        checkNativeExp2Half2Half2();
+        checkNativeExp2Half3Half3();
+        checkNativeExp2Half4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExp2.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExp2.rs
index 21b8a54..8aa5c0e 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExp2.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExp2.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testNativeExp2Float4Float4(float4 inV) {
     return native_exp2(inV);
 }
+
+half __attribute__((kernel)) testNativeExp2HalfHalf(half inV) {
+    return native_exp2(inV);
+}
+
+half2 __attribute__((kernel)) testNativeExp2Half2Half2(half2 inV) {
+    return native_exp2(inV);
+}
+
+half3 __attribute__((kernel)) testNativeExp2Half3Half3(half3 inV) {
+    return native_exp2(inV);
+}
+
+half4 __attribute__((kernel)) testNativeExp2Half4Half4(half4 inV) {
+    return native_exp2(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExp2Relaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExp2Relaxed.rs
index ef9f713..2fd51e6 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExp2Relaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExp2Relaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExpRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExpRelaxed.rs
index f947bc4..1200321 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExpRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExpRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExpm1.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExpm1.java
index bba5aeb..3b4412b 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExpm1.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExpm1.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeExpm1(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeExpm1(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeExpm1(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeExpm1(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,293 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public short out;
+        public double outDouble;
+    }
+
+    private void checkNativeExpm1HalfHalf() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x1f7c28dl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testNativeExpm1HalfHalf(inV, out);
+            verifyResultsNativeExpm1HalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExpm1HalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeExpm1HalfHalf(inV, out);
+            verifyResultsNativeExpm1HalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExpm1HalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeExpm1HalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Extract the outputs.
+                args.out = arrayOut[i * 1 + j];
+                args.outDouble = Float16Utils.convertFloat16ToDouble(args.out);
+                // Ask the CoreMathVerifier to validate.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                String errorMessage = CoreMathVerifier.verifyNativeExpm1(args, target);
+                boolean valid = errorMessage == null;
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("\n");
+                        message.append("Output out (in double): ");
+                        appendVariableToMessage(message, args.outDouble);
+                        message.append("\n");
+                        message.append(errorMessage);
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeExpm1HalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeExpm1Half2Half2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xddb33a87l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testNativeExpm1Half2Half2(inV, out);
+            verifyResultsNativeExpm1Half2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExpm1Half2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeExpm1Half2Half2(inV, out);
+            verifyResultsNativeExpm1Half2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExpm1Half2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeExpm1Half2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Extract the outputs.
+                args.out = arrayOut[i * 2 + j];
+                args.outDouble = Float16Utils.convertFloat16ToDouble(args.out);
+                // Ask the CoreMathVerifier to validate.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                String errorMessage = CoreMathVerifier.verifyNativeExpm1(args, target);
+                boolean valid = errorMessage == null;
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("\n");
+                        message.append("Output out (in double): ");
+                        appendVariableToMessage(message, args.outDouble);
+                        message.append("\n");
+                        message.append(errorMessage);
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeExpm1Half2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeExpm1Half3Half3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x3cbaff7bl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testNativeExpm1Half3Half3(inV, out);
+            verifyResultsNativeExpm1Half3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExpm1Half3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeExpm1Half3Half3(inV, out);
+            verifyResultsNativeExpm1Half3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExpm1Half3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeExpm1Half3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Extract the outputs.
+                args.out = arrayOut[i * 4 + j];
+                args.outDouble = Float16Utils.convertFloat16ToDouble(args.out);
+                // Ask the CoreMathVerifier to validate.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                String errorMessage = CoreMathVerifier.verifyNativeExpm1(args, target);
+                boolean valid = errorMessage == null;
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("\n");
+                        message.append("Output out (in double): ");
+                        appendVariableToMessage(message, args.outDouble);
+                        message.append("\n");
+                        message.append(errorMessage);
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeExpm1Half3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeExpm1Half4Half4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x9bc2c46fl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testNativeExpm1Half4Half4(inV, out);
+            verifyResultsNativeExpm1Half4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExpm1Half4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeExpm1Half4Half4(inV, out);
+            verifyResultsNativeExpm1Half4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExpm1Half4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeExpm1Half4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Extract the outputs.
+                args.out = arrayOut[i * 4 + j];
+                args.outDouble = Float16Utils.convertFloat16ToDouble(args.out);
+                // Ask the CoreMathVerifier to validate.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                String errorMessage = CoreMathVerifier.verifyNativeExpm1(args, target);
+                boolean valid = errorMessage == null;
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("\n");
+                        message.append("Output out (in double): ");
+                        appendVariableToMessage(message, args.outDouble);
+                        message.append("\n");
+                        message.append(errorMessage);
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeExpm1Half4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testNativeExpm1() {
         checkNativeExpm1FloatFloat();
         checkNativeExpm1Float2Float2();
         checkNativeExpm1Float3Float3();
         checkNativeExpm1Float4Float4();
+        checkNativeExpm1HalfHalf();
+        checkNativeExpm1Half2Half2();
+        checkNativeExpm1Half3Half3();
+        checkNativeExpm1Half4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExpm1.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExpm1.rs
index 848bac6..a965138 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExpm1.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExpm1.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testNativeExpm1Float4Float4(float4 inV) {
     return native_expm1(inV);
 }
+
+half __attribute__((kernel)) testNativeExpm1HalfHalf(half inV) {
+    return native_expm1(inV);
+}
+
+half2 __attribute__((kernel)) testNativeExpm1Half2Half2(half2 inV) {
+    return native_expm1(inV);
+}
+
+half3 __attribute__((kernel)) testNativeExpm1Half3Half3(half3 inV) {
+    return native_expm1(inV);
+}
+
+half4 __attribute__((kernel)) testNativeExpm1Half4Half4(half4 inV) {
+    return native_expm1(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExpm1Relaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExpm1Relaxed.rs
index 8af4aaf..4e1ca7c 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExpm1Relaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExpm1Relaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeHypot.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeHypot.java
index 650233b..4aee2bc 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeHypot.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeHypot.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -82,7 +83,7 @@
                 args.inA = arrayInA[i];
                 args.inB = arrayInB[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeHypot(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -161,7 +162,7 @@
                 args.inA = arrayInA[i * 2 + j];
                 args.inB = arrayInB[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeHypot(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -240,7 +241,7 @@
                 args.inA = arrayInA[i * 4 + j];
                 args.inB = arrayInB[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeHypot(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -319,7 +320,7 @@
                 args.inA = arrayInA[i * 4 + j];
                 args.inB = arrayInB[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeHypot(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -358,10 +359,358 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalfHalf {
+        public short inA;
+        public double inADouble;
+        public short inB;
+        public double inBDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeHypotHalfHalfHalf() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x93522f56l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x93522f57l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testNativeHypotHalfHalfHalf(inA, out);
+            verifyResultsNativeHypotHalfHalfHalf(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeHypotHalfHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testNativeHypotHalfHalfHalf(inA, out);
+            verifyResultsNativeHypotHalfHalfHalf(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeHypotHalfHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeHypotHalfHalfHalf(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        short[] arrayInA = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInA, (short) 42);
+        inA.copyTo(arrayInA);
+        short[] arrayInB = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInB, (short) 42);
+        inB.copyTo(arrayInB);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inA = arrayInA[i];
+                args.inADouble = Float16Utils.convertFloat16ToDouble(args.inA);
+                args.inB = arrayInB[i];
+                args.inBDouble = Float16Utils.convertFloat16ToDouble(args.inB);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeHypot(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inA: ");
+                        appendVariableToMessage(message, args.inA);
+                        message.append("\n");
+                        message.append("Input inB: ");
+                        appendVariableToMessage(message, args.inB);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeHypotHalfHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeHypotHalf2Half2Half2() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xf4dca3f6l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xf4dca3f7l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testNativeHypotHalf2Half2Half2(inA, out);
+            verifyResultsNativeHypotHalf2Half2Half2(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeHypotHalf2Half2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testNativeHypotHalf2Half2Half2(inA, out);
+            verifyResultsNativeHypotHalf2Half2Half2(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeHypotHalf2Half2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeHypotHalf2Half2Half2(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        short[] arrayInA = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInA, (short) 42);
+        inA.copyTo(arrayInA);
+        short[] arrayInB = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInB, (short) 42);
+        inB.copyTo(arrayInB);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inA = arrayInA[i * 2 + j];
+                args.inADouble = Float16Utils.convertFloat16ToDouble(args.inA);
+                args.inB = arrayInB[i * 2 + j];
+                args.inBDouble = Float16Utils.convertFloat16ToDouble(args.inB);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeHypot(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inA: ");
+                        appendVariableToMessage(message, args.inA);
+                        message.append("\n");
+                        message.append("Input inB: ");
+                        appendVariableToMessage(message, args.inB);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeHypotHalf2Half2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeHypotHalf3Half3Half3() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x537bb4c5l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x537bb4c6l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testNativeHypotHalf3Half3Half3(inA, out);
+            verifyResultsNativeHypotHalf3Half3Half3(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeHypotHalf3Half3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testNativeHypotHalf3Half3Half3(inA, out);
+            verifyResultsNativeHypotHalf3Half3Half3(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeHypotHalf3Half3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeHypotHalf3Half3Half3(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        short[] arrayInA = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInA, (short) 42);
+        inA.copyTo(arrayInA);
+        short[] arrayInB = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInB, (short) 42);
+        inB.copyTo(arrayInB);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inA = arrayInA[i * 4 + j];
+                args.inADouble = Float16Utils.convertFloat16ToDouble(args.inA);
+                args.inB = arrayInB[i * 4 + j];
+                args.inBDouble = Float16Utils.convertFloat16ToDouble(args.inB);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeHypot(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inA: ");
+                        appendVariableToMessage(message, args.inA);
+                        message.append("\n");
+                        message.append("Input inB: ");
+                        appendVariableToMessage(message, args.inB);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeHypotHalf3Half3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeHypotHalf4Half4Half4() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xb21ac594l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xb21ac595l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testNativeHypotHalf4Half4Half4(inA, out);
+            verifyResultsNativeHypotHalf4Half4Half4(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeHypotHalf4Half4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testNativeHypotHalf4Half4Half4(inA, out);
+            verifyResultsNativeHypotHalf4Half4Half4(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeHypotHalf4Half4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeHypotHalf4Half4Half4(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        short[] arrayInA = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInA, (short) 42);
+        inA.copyTo(arrayInA);
+        short[] arrayInB = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInB, (short) 42);
+        inB.copyTo(arrayInB);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inA = arrayInA[i * 4 + j];
+                args.inADouble = Float16Utils.convertFloat16ToDouble(args.inA);
+                args.inB = arrayInB[i * 4 + j];
+                args.inBDouble = Float16Utils.convertFloat16ToDouble(args.inB);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeHypot(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inA: ");
+                        appendVariableToMessage(message, args.inA);
+                        message.append("\n");
+                        message.append("Input inB: ");
+                        appendVariableToMessage(message, args.inB);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeHypotHalf4Half4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testNativeHypot() {
         checkNativeHypotFloatFloatFloat();
         checkNativeHypotFloat2Float2Float2();
         checkNativeHypotFloat3Float3Float3();
         checkNativeHypotFloat4Float4Float4();
+        checkNativeHypotHalfHalfHalf();
+        checkNativeHypotHalf2Half2Half2();
+        checkNativeHypotHalf3Half3Half3();
+        checkNativeHypotHalf4Half4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeHypot.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeHypot.rs
index 5e68656..8768883 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeHypot.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeHypot.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -40,3 +40,23 @@
     float4 inB = rsGetElementAt_float4(gAllocInB, x);
     return native_hypot(inA, inB);
 }
+
+half __attribute__((kernel)) testNativeHypotHalfHalfHalf(half inA, unsigned int x) {
+    half inB = rsGetElementAt_half(gAllocInB, x);
+    return native_hypot(inA, inB);
+}
+
+half2 __attribute__((kernel)) testNativeHypotHalf2Half2Half2(half2 inA, unsigned int x) {
+    half2 inB = rsGetElementAt_half2(gAllocInB, x);
+    return native_hypot(inA, inB);
+}
+
+half3 __attribute__((kernel)) testNativeHypotHalf3Half3Half3(half3 inA, unsigned int x) {
+    half3 inB = rsGetElementAt_half3(gAllocInB, x);
+    return native_hypot(inA, inB);
+}
+
+half4 __attribute__((kernel)) testNativeHypotHalf4Half4Half4(half4 inA, unsigned int x) {
+    half4 inB = rsGetElementAt_half4(gAllocInB, x);
+    return native_hypot(inA, inB);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeHypotRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeHypotRelaxed.rs
index 999a5b2..53718a9 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeHypotRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeHypotRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLength.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLength.java
index 176f75b..532379c 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLength.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLength.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -73,7 +74,7 @@
             // Create the appropriate sized arrays in args
             // Fill args with the input values
             args.inV = arrayInV[i];
-            Target target = new Target(relaxed);
+            Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
             CoreMathVerifier.computeNativeLength(args, target);
 
             // Compare the expected outputs to the actual values returned by RS.
@@ -147,7 +148,7 @@
             for (int j = 0; j < 2 ; j++) {
                 args.inV[j] = arrayInV[i * 2 + j];
             }
-            Target target = new Target(relaxed);
+            Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
             CoreMathVerifier.computeNativeLength(args, target);
 
             // Compare the expected outputs to the actual values returned by RS.
@@ -218,7 +219,7 @@
             for (int j = 0; j < 3 ; j++) {
                 args.inV[j] = arrayInV[i * 4 + j];
             }
-            Target target = new Target(relaxed);
+            Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
             CoreMathVerifier.computeNativeLength(args, target);
 
             // Compare the expected outputs to the actual values returned by RS.
@@ -289,7 +290,7 @@
             for (int j = 0; j < 4 ; j++) {
                 args.inV[j] = arrayInV[i * 4 + j];
             }
-            Target target = new Target(relaxed);
+            Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
             CoreMathVerifier.computeNativeLength(args, target);
 
             // Compare the expected outputs to the actual values returned by RS.
@@ -325,10 +326,324 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeLengthHalfHalf() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x1777436l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testNativeLengthHalfHalf(inV, out);
+            verifyResultsNativeLengthHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLengthHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeLengthHalfHalf(inV, out);
+            verifyResultsNativeLengthHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLengthHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeLengthHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+            // Create the appropriate sized arrays in args
+            // Fill args with the input values
+            args.inV = arrayInV[i];
+            args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+            Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+            CoreMathVerifier.computeNativeLength(args, target);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i]))) {
+                valid = false;
+            }
+            if (!valid) {
+                if (!errorFound) {
+                    errorFound = true;
+                    message.append("Input inV: ");
+                    appendVariableToMessage(message, arrayInV[i]);
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    appendVariableToMessage(message, args.out);
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    appendVariableToMessage(message, arrayOut[i]);
+                    message.append("\n");
+                    message.append("Actual   output out (in double): ");
+                    appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i]));
+                    if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i]))) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    message.append("Errors at");
+                }
+                message.append(" [");
+                message.append(Integer.toString(i));
+                message.append("]");
+            }
+        }
+        assertFalse("Incorrect output for checkNativeLengthHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsHalfNHalf {
+        public short[] inV;
+        public double[] inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeLengthHalf2Half() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xbffb8a74l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testNativeLengthHalf2Half(inV, out);
+            verifyResultsNativeLengthHalf2Half(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLengthHalf2Half: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeLengthHalf2Half(inV, out);
+            verifyResultsNativeLengthHalf2Half(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLengthHalf2Half: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeLengthHalf2Half(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsHalfNHalf args = new ArgumentsHalfNHalf();
+            // Create the appropriate sized arrays in args
+            args.inV = new short[2];
+            args.inVDouble = new double[2];
+            // Fill args with the input values
+            for (int j = 0; j < 2 ; j++) {
+                args.inV[j] = arrayInV[i * 2 + j];
+                args.inVDouble[j] = Float16Utils.convertFloat16ToDouble(args.inV[j]);
+            }
+            Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+            CoreMathVerifier.computeNativeLength(args, target);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i]))) {
+                valid = false;
+            }
+            if (!valid) {
+                if (!errorFound) {
+                    errorFound = true;
+                    for (int j = 0; j < 2 ; j++) {
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, arrayInV[i * 2 + j]);
+                        message.append("\n");
+                    }
+                    message.append("Expected output out: ");
+                    appendVariableToMessage(message, args.out);
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    appendVariableToMessage(message, arrayOut[i]);
+                    message.append("\n");
+                    message.append("Actual   output out (in double): ");
+                    appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i]));
+                    if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i]))) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    message.append("Errors at");
+                }
+                message.append(" [");
+                message.append(Integer.toString(i));
+                message.append("]");
+            }
+        }
+        assertFalse("Incorrect output for checkNativeLengthHalf2Half" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeLengthHalf3Half() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x9a26417l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testNativeLengthHalf3Half(inV, out);
+            verifyResultsNativeLengthHalf3Half(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLengthHalf3Half: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeLengthHalf3Half(inV, out);
+            verifyResultsNativeLengthHalf3Half(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLengthHalf3Half: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeLengthHalf3Half(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsHalfNHalf args = new ArgumentsHalfNHalf();
+            // Create the appropriate sized arrays in args
+            args.inV = new short[3];
+            args.inVDouble = new double[3];
+            // Fill args with the input values
+            for (int j = 0; j < 3 ; j++) {
+                args.inV[j] = arrayInV[i * 4 + j];
+                args.inVDouble[j] = Float16Utils.convertFloat16ToDouble(args.inV[j]);
+            }
+            Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+            CoreMathVerifier.computeNativeLength(args, target);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i]))) {
+                valid = false;
+            }
+            if (!valid) {
+                if (!errorFound) {
+                    errorFound = true;
+                    for (int j = 0; j < 3 ; j++) {
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, arrayInV[i * 4 + j]);
+                        message.append("\n");
+                    }
+                    message.append("Expected output out: ");
+                    appendVariableToMessage(message, args.out);
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    appendVariableToMessage(message, arrayOut[i]);
+                    message.append("\n");
+                    message.append("Actual   output out (in double): ");
+                    appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i]));
+                    if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i]))) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    message.append("Errors at");
+                }
+                message.append(" [");
+                message.append(Integer.toString(i));
+                message.append("]");
+            }
+        }
+        assertFalse("Incorrect output for checkNativeLengthHalf3Half" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeLengthHalf4Half() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x53493dbal, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testNativeLengthHalf4Half(inV, out);
+            verifyResultsNativeLengthHalf4Half(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLengthHalf4Half: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeLengthHalf4Half(inV, out);
+            verifyResultsNativeLengthHalf4Half(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLengthHalf4Half: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeLengthHalf4Half(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsHalfNHalf args = new ArgumentsHalfNHalf();
+            // Create the appropriate sized arrays in args
+            args.inV = new short[4];
+            args.inVDouble = new double[4];
+            // Fill args with the input values
+            for (int j = 0; j < 4 ; j++) {
+                args.inV[j] = arrayInV[i * 4 + j];
+                args.inVDouble[j] = Float16Utils.convertFloat16ToDouble(args.inV[j]);
+            }
+            Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+            CoreMathVerifier.computeNativeLength(args, target);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i]))) {
+                valid = false;
+            }
+            if (!valid) {
+                if (!errorFound) {
+                    errorFound = true;
+                    for (int j = 0; j < 4 ; j++) {
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, arrayInV[i * 4 + j]);
+                        message.append("\n");
+                    }
+                    message.append("Expected output out: ");
+                    appendVariableToMessage(message, args.out);
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    appendVariableToMessage(message, arrayOut[i]);
+                    message.append("\n");
+                    message.append("Actual   output out (in double): ");
+                    appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i]));
+                    if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i]))) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    message.append("Errors at");
+                }
+                message.append(" [");
+                message.append(Integer.toString(i));
+                message.append("]");
+            }
+        }
+        assertFalse("Incorrect output for checkNativeLengthHalf4Half" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testNativeLength() {
         checkNativeLengthFloatFloat();
         checkNativeLengthFloat2Float();
         checkNativeLengthFloat3Float();
         checkNativeLengthFloat4Float();
+        checkNativeLengthHalfHalf();
+        checkNativeLengthHalf2Half();
+        checkNativeLengthHalf3Half();
+        checkNativeLengthHalf4Half();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLength.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLength.rs
index 9245390..166f7b3 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLength.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLength.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float __attribute__((kernel)) testNativeLengthFloat4Float(float4 inV) {
     return native_length(inV);
 }
+
+half __attribute__((kernel)) testNativeLengthHalfHalf(half inV) {
+    return native_length(inV);
+}
+
+half __attribute__((kernel)) testNativeLengthHalf2Half(half2 inV) {
+    return native_length(inV);
+}
+
+half __attribute__((kernel)) testNativeLengthHalf3Half(half3 inV) {
+    return native_length(inV);
+}
+
+half __attribute__((kernel)) testNativeLengthHalf4Half(half4 inV) {
+    return native_length(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLengthRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLengthRelaxed.rs
index c7f8655..0f41162 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLengthRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLengthRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog.java
index d1d108b..dd52d7b 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeLog(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeLog(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeLog(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeLog(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeLogHalfHalf() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x7dcf0276l, 10e-5, 65504);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testNativeLogHalfHalf(inV, out);
+            verifyResultsNativeLogHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLogHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeLogHalfHalf(inV, out);
+            verifyResultsNativeLogHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLogHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeLogHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeLog(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeLogHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeLogHalf2Half2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x535fd468l, 10e-5, 65504);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testNativeLogHalf2Half2(inV, out);
+            verifyResultsNativeLogHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLogHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeLogHalf2Half2(inV, out);
+            verifyResultsNativeLogHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLogHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeLogHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeLog(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeLogHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeLogHalf3Half3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 3, 0xb267995cl, 10e-5, 65504);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testNativeLogHalf3Half3(inV, out);
+            verifyResultsNativeLogHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLogHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeLogHalf3Half3(inV, out);
+            verifyResultsNativeLogHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLogHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeLogHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeLog(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeLogHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeLogHalf4Half4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x116f5e50l, 10e-5, 65504);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testNativeLogHalf4Half4(inV, out);
+            verifyResultsNativeLogHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLogHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeLogHalf4Half4(inV, out);
+            verifyResultsNativeLogHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLogHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeLogHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeLog(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeLogHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testNativeLog() {
         checkNativeLogFloatFloat();
         checkNativeLogFloat2Float2();
         checkNativeLogFloat3Float3();
         checkNativeLogFloat4Float4();
+        checkNativeLogHalfHalf();
+        checkNativeLogHalf2Half2();
+        checkNativeLogHalf3Half3();
+        checkNativeLogHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog.rs
index bcf9a5f..179d673 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testNativeLogFloat4Float4(float4 inV) {
     return native_log(inV);
 }
+
+half __attribute__((kernel)) testNativeLogHalfHalf(half inV) {
+    return native_log(inV);
+}
+
+half2 __attribute__((kernel)) testNativeLogHalf2Half2(half2 inV) {
+    return native_log(inV);
+}
+
+half3 __attribute__((kernel)) testNativeLogHalf3Half3(half3 inV) {
+    return native_log(inV);
+}
+
+half4 __attribute__((kernel)) testNativeLogHalf4Half4(half4 inV) {
+    return native_log(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog10.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog10.java
index 4d4278b..0854f26 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog10.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog10.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeLog10(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeLog10(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeLog10(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeLog10(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeLog10HalfHalf() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x9960016fl, 10e-5, 65504);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testNativeLog10HalfHalf(inV, out);
+            verifyResultsNativeLog10HalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog10HalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeLog10HalfHalf(inV, out);
+            verifyResultsNativeLog10HalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog10HalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeLog10HalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeLog10(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeLog10HalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeLog10Half2Half2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x6da168d9l, 10e-5, 65504);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testNativeLog10Half2Half2(inV, out);
+            verifyResultsNativeLog10Half2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog10Half2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeLog10Half2Half2(inV, out);
+            verifyResultsNativeLog10Half2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog10Half2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeLog10Half2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeLog10(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeLog10Half2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeLog10Half3Half3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 3, 0xcca92dcdl, 10e-5, 65504);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testNativeLog10Half3Half3(inV, out);
+            verifyResultsNativeLog10Half3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog10Half3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeLog10Half3Half3(inV, out);
+            verifyResultsNativeLog10Half3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog10Half3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeLog10Half3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeLog10(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeLog10Half3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeLog10Half4Half4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x2bb0f2c1l, 10e-5, 65504);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testNativeLog10Half4Half4(inV, out);
+            verifyResultsNativeLog10Half4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog10Half4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeLog10Half4Half4(inV, out);
+            verifyResultsNativeLog10Half4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog10Half4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeLog10Half4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeLog10(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeLog10Half4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testNativeLog10() {
         checkNativeLog10FloatFloat();
         checkNativeLog10Float2Float2();
         checkNativeLog10Float3Float3();
         checkNativeLog10Float4Float4();
+        checkNativeLog10HalfHalf();
+        checkNativeLog10Half2Half2();
+        checkNativeLog10Half3Half3();
+        checkNativeLog10Half4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog10.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog10.rs
index e02b98a..434b275 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog10.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog10.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testNativeLog10Float4Float4(float4 inV) {
     return native_log10(inV);
 }
+
+half __attribute__((kernel)) testNativeLog10HalfHalf(half inV) {
+    return native_log10(inV);
+}
+
+half2 __attribute__((kernel)) testNativeLog10Half2Half2(half2 inV) {
+    return native_log10(inV);
+}
+
+half3 __attribute__((kernel)) testNativeLog10Half3Half3(half3 inV) {
+    return native_log10(inV);
+}
+
+half4 __attribute__((kernel)) testNativeLog10Half4Half4(half4 inV) {
+    return native_log10(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog10Relaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog10Relaxed.rs
index 341414e..94a47e1 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog10Relaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog10Relaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog1p.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog1p.java
index eaed9c2..4ef9bd1 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog1p.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog1p.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeLog1p(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeLog1p(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeLog1p(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeLog1p(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeLog1pHalfHalf() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xe4adee2fl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testNativeLog1pHalfHalf(inV, out);
+            verifyResultsNativeLog1pHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog1pHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeLog1pHalfHalf(inV, out);
+            verifyResultsNativeLog1pHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog1pHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeLog1pHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeLog1p(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeLog1pHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeLog1pHalf2Half2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x53745f99l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testNativeLog1pHalf2Half2(inV, out);
+            verifyResultsNativeLog1pHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog1pHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeLog1pHalf2Half2(inV, out);
+            verifyResultsNativeLog1pHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog1pHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeLog1pHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeLog1p(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeLog1pHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeLog1pHalf3Half3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0xb27c248dl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testNativeLog1pHalf3Half3(inV, out);
+            verifyResultsNativeLog1pHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog1pHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeLog1pHalf3Half3(inV, out);
+            verifyResultsNativeLog1pHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog1pHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeLog1pHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeLog1p(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeLog1pHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeLog1pHalf4Half4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x1183e981l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testNativeLog1pHalf4Half4(inV, out);
+            verifyResultsNativeLog1pHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog1pHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeLog1pHalf4Half4(inV, out);
+            verifyResultsNativeLog1pHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog1pHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeLog1pHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeLog1p(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeLog1pHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testNativeLog1p() {
         checkNativeLog1pFloatFloat();
         checkNativeLog1pFloat2Float2();
         checkNativeLog1pFloat3Float3();
         checkNativeLog1pFloat4Float4();
+        checkNativeLog1pHalfHalf();
+        checkNativeLog1pHalf2Half2();
+        checkNativeLog1pHalf3Half3();
+        checkNativeLog1pHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog1p.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog1p.rs
index 3a528db..3d4fd21 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog1p.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog1p.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testNativeLog1pFloat4Float4(float4 inV) {
     return native_log1p(inV);
 }
+
+half __attribute__((kernel)) testNativeLog1pHalfHalf(half inV) {
+    return native_log1p(inV);
+}
+
+half2 __attribute__((kernel)) testNativeLog1pHalf2Half2(half2 inV) {
+    return native_log1p(inV);
+}
+
+half3 __attribute__((kernel)) testNativeLog1pHalf3Half3(half3 inV) {
+    return native_log1p(inV);
+}
+
+half4 __attribute__((kernel)) testNativeLog1pHalf4Half4(half4 inV) {
+    return native_log1p(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog1pRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog1pRelaxed.rs
index ff1a719..c523f6f 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog1pRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog1pRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog2.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog2.java
index ba811a8..111150b 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog2.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog2.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeLog2(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeLog2(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeLog2(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeLog2(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeLog2HalfHalf() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xb6e9470al, 10e-5, 65504);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testNativeLog2HalfHalf(inV, out);
+            verifyResultsNativeLog2HalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog2HalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeLog2HalfHalf(inV, out);
+            verifyResultsNativeLog2HalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog2HalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeLog2HalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeLog2(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeLog2HalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeLog2Half2Half2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xc219255cl, 10e-5, 65504);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testNativeLog2Half2Half2(inV, out);
+            verifyResultsNativeLog2Half2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog2Half2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeLog2Half2Half2(inV, out);
+            verifyResultsNativeLog2Half2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog2Half2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeLog2Half2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeLog2(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeLog2Half2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeLog2Half3Half3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x2120ea50l, 10e-5, 65504);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testNativeLog2Half3Half3(inV, out);
+            verifyResultsNativeLog2Half3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog2Half3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeLog2Half3Half3(inV, out);
+            verifyResultsNativeLog2Half3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog2Half3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeLog2Half3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeLog2(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeLog2Half3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeLog2Half4Half4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x8028af44l, 10e-5, 65504);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testNativeLog2Half4Half4(inV, out);
+            verifyResultsNativeLog2Half4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog2Half4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeLog2Half4Half4(inV, out);
+            verifyResultsNativeLog2Half4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog2Half4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeLog2Half4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeLog2(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeLog2Half4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testNativeLog2() {
         checkNativeLog2FloatFloat();
         checkNativeLog2Float2Float2();
         checkNativeLog2Float3Float3();
         checkNativeLog2Float4Float4();
+        checkNativeLog2HalfHalf();
+        checkNativeLog2Half2Half2();
+        checkNativeLog2Half3Half3();
+        checkNativeLog2Half4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog2.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog2.rs
index 0410ef4..649d584 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog2.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog2.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testNativeLog2Float4Float4(float4 inV) {
     return native_log2(inV);
 }
+
+half __attribute__((kernel)) testNativeLog2HalfHalf(half inV) {
+    return native_log2(inV);
+}
+
+half2 __attribute__((kernel)) testNativeLog2Half2Half2(half2 inV) {
+    return native_log2(inV);
+}
+
+half3 __attribute__((kernel)) testNativeLog2Half3Half3(half3 inV) {
+    return native_log2(inV);
+}
+
+half4 __attribute__((kernel)) testNativeLog2Half4Half4(half4 inV) {
+    return native_log2(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog2Relaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog2Relaxed.rs
index 148796b..e2134e5 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog2Relaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog2Relaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLogRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLogRelaxed.rs
index 065dece..6f5bfa1 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLogRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLogRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeNormalize.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeNormalize.java
index d3ec54c..2e47583 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeNormalize.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeNormalize.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -73,7 +74,7 @@
             // Create the appropriate sized arrays in args
             // Fill args with the input values
             args.inV = arrayInV[i];
-            Target target = new Target(relaxed);
+            Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
             CoreMathVerifier.computeNativeNormalize(args, target);
 
             // Compare the expected outputs to the actual values returned by RS.
@@ -148,7 +149,7 @@
             for (int j = 0; j < 2 ; j++) {
                 args.inV[j] = arrayInV[i * 2 + j];
             }
-            Target target = new Target(relaxed);
+            Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
             CoreMathVerifier.computeNativeNormalize(args, target);
 
             // Compare the expected outputs to the actual values returned by RS.
@@ -224,7 +225,7 @@
             for (int j = 0; j < 3 ; j++) {
                 args.inV[j] = arrayInV[i * 4 + j];
             }
-            Target target = new Target(relaxed);
+            Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
             CoreMathVerifier.computeNativeNormalize(args, target);
 
             // Compare the expected outputs to the actual values returned by RS.
@@ -300,7 +301,7 @@
             for (int j = 0; j < 4 ; j++) {
                 args.inV[j] = arrayInV[i * 4 + j];
             }
-            Target target = new Target(relaxed);
+            Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
             CoreMathVerifier.computeNativeNormalize(args, target);
 
             // Compare the expected outputs to the actual values returned by RS.
@@ -340,10 +341,339 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeNormalizeHalfHalf() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x96cffbd5l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testNativeNormalizeHalfHalf(inV, out);
+            verifyResultsNativeNormalizeHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeNormalizeHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeNormalizeHalfHalf(inV, out);
+            verifyResultsNativeNormalizeHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeNormalizeHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeNormalizeHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+            // Create the appropriate sized arrays in args
+            // Fill args with the input values
+            args.inV = arrayInV[i];
+            args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+            Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+            CoreMathVerifier.computeNativeNormalize(args, target);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i]))) {
+                valid = false;
+            }
+            if (!valid) {
+                if (!errorFound) {
+                    errorFound = true;
+                    message.append("Input inV: ");
+                    appendVariableToMessage(message, arrayInV[i]);
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    appendVariableToMessage(message, args.out);
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    appendVariableToMessage(message, arrayOut[i]);
+                    message.append("\n");
+                    message.append("Actual   output out (in double): ");
+                    appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i]));
+                    if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i]))) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    message.append("Errors at");
+                }
+                message.append(" [");
+                message.append(Integer.toString(i));
+                message.append("]");
+            }
+        }
+        assertFalse("Incorrect output for checkNativeNormalizeHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsHalfNHalfN {
+        public short[] inV;
+        public double[] inVDouble;
+        public Target.Floaty[] out;
+    }
+
+    private void checkNativeNormalizeHalf2Half2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xeb68f38fl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testNativeNormalizeHalf2Half2(inV, out);
+            verifyResultsNativeNormalizeHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeNormalizeHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeNormalizeHalf2Half2(inV, out);
+            verifyResultsNativeNormalizeHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeNormalizeHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeNormalizeHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsHalfNHalfN args = new ArgumentsHalfNHalfN();
+            // Create the appropriate sized arrays in args
+            args.inV = new short[2];
+            args.inVDouble = new double[2];
+            args.out = new Target.Floaty[2];
+            // Fill args with the input values
+            for (int j = 0; j < 2 ; j++) {
+                args.inV[j] = arrayInV[i * 2 + j];
+                args.inVDouble[j] = Float16Utils.convertFloat16ToDouble(args.inV[j]);
+            }
+            Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+            CoreMathVerifier.computeNativeNormalize(args, target);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            for (int j = 0; j < 2 ; j++) {
+                if (!args.out[j].couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+            }
+            if (!valid) {
+                if (!errorFound) {
+                    errorFound = true;
+                    for (int j = 0; j < 2 ; j++) {
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, arrayInV[i * 2 + j]);
+                        message.append("\n");
+                    }
+                    for (int j = 0; j < 2 ; j++) {
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out[j]);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out[j].couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                    }
+                    message.append("Errors at");
+                }
+                message.append(" [");
+                message.append(Integer.toString(i));
+                message.append("]");
+            }
+        }
+        assertFalse("Incorrect output for checkNativeNormalizeHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeNormalizeHalf3Half3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x4a70b883l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testNativeNormalizeHalf3Half3(inV, out);
+            verifyResultsNativeNormalizeHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeNormalizeHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeNormalizeHalf3Half3(inV, out);
+            verifyResultsNativeNormalizeHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeNormalizeHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeNormalizeHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsHalfNHalfN args = new ArgumentsHalfNHalfN();
+            // Create the appropriate sized arrays in args
+            args.inV = new short[3];
+            args.inVDouble = new double[3];
+            args.out = new Target.Floaty[3];
+            // Fill args with the input values
+            for (int j = 0; j < 3 ; j++) {
+                args.inV[j] = arrayInV[i * 4 + j];
+                args.inVDouble[j] = Float16Utils.convertFloat16ToDouble(args.inV[j]);
+            }
+            Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+            CoreMathVerifier.computeNativeNormalize(args, target);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            for (int j = 0; j < 3 ; j++) {
+                if (!args.out[j].couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+            }
+            if (!valid) {
+                if (!errorFound) {
+                    errorFound = true;
+                    for (int j = 0; j < 3 ; j++) {
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, arrayInV[i * 4 + j]);
+                        message.append("\n");
+                    }
+                    for (int j = 0; j < 3 ; j++) {
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out[j]);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out[j].couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                    }
+                    message.append("Errors at");
+                }
+                message.append(" [");
+                message.append(Integer.toString(i));
+                message.append("]");
+            }
+        }
+        assertFalse("Incorrect output for checkNativeNormalizeHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeNormalizeHalf4Half4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xa9787d77l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testNativeNormalizeHalf4Half4(inV, out);
+            verifyResultsNativeNormalizeHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeNormalizeHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeNormalizeHalf4Half4(inV, out);
+            verifyResultsNativeNormalizeHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeNormalizeHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeNormalizeHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsHalfNHalfN args = new ArgumentsHalfNHalfN();
+            // Create the appropriate sized arrays in args
+            args.inV = new short[4];
+            args.inVDouble = new double[4];
+            args.out = new Target.Floaty[4];
+            // Fill args with the input values
+            for (int j = 0; j < 4 ; j++) {
+                args.inV[j] = arrayInV[i * 4 + j];
+                args.inVDouble[j] = Float16Utils.convertFloat16ToDouble(args.inV[j]);
+            }
+            Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+            CoreMathVerifier.computeNativeNormalize(args, target);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            for (int j = 0; j < 4 ; j++) {
+                if (!args.out[j].couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+            }
+            if (!valid) {
+                if (!errorFound) {
+                    errorFound = true;
+                    for (int j = 0; j < 4 ; j++) {
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, arrayInV[i * 4 + j]);
+                        message.append("\n");
+                    }
+                    for (int j = 0; j < 4 ; j++) {
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out[j]);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out[j].couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                    }
+                    message.append("Errors at");
+                }
+                message.append(" [");
+                message.append(Integer.toString(i));
+                message.append("]");
+            }
+        }
+        assertFalse("Incorrect output for checkNativeNormalizeHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testNativeNormalize() {
         checkNativeNormalizeFloatFloat();
         checkNativeNormalizeFloat2Float2();
         checkNativeNormalizeFloat3Float3();
         checkNativeNormalizeFloat4Float4();
+        checkNativeNormalizeHalfHalf();
+        checkNativeNormalizeHalf2Half2();
+        checkNativeNormalizeHalf3Half3();
+        checkNativeNormalizeHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeNormalize.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeNormalize.rs
index ba169bd..ba5adea 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeNormalize.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeNormalize.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testNativeNormalizeFloat4Float4(float4 inV) {
     return native_normalize(inV);
 }
+
+half __attribute__((kernel)) testNativeNormalizeHalfHalf(half inV) {
+    return native_normalize(inV);
+}
+
+half2 __attribute__((kernel)) testNativeNormalizeHalf2Half2(half2 inV) {
+    return native_normalize(inV);
+}
+
+half3 __attribute__((kernel)) testNativeNormalizeHalf3Half3(half3 inV) {
+    return native_normalize(inV);
+}
+
+half4 __attribute__((kernel)) testNativeNormalizeHalf4Half4(half4 inV) {
+    return native_normalize(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeNormalizeRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeNormalizeRelaxed.rs
index 0b85dbb..7b84267 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeNormalizeRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeNormalizeRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativePowr.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativePowr.java
index 930c892..6656c4d 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativePowr.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativePowr.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -82,7 +83,7 @@
                 args.inBase = arrayInBase[i];
                 args.inExponent = arrayInExponent[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativePowr(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -161,7 +162,7 @@
                 args.inBase = arrayInBase[i * 2 + j];
                 args.inExponent = arrayInExponent[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativePowr(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -240,7 +241,7 @@
                 args.inBase = arrayInBase[i * 4 + j];
                 args.inExponent = arrayInExponent[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativePowr(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -319,7 +320,7 @@
                 args.inBase = arrayInBase[i * 4 + j];
                 args.inExponent = arrayInExponent[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativePowr(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -358,10 +359,358 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalfHalf {
+        public short inBase;
+        public double inBaseDouble;
+        public short inExponent;
+        public double inExponentDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkNativePowrHalfHalfHalf() {
+        Allocation inBase = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x5f0b09f0l, 0, 256);
+        Allocation inExponent = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x2a404496l, -15, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.set_gAllocInExponent(inExponent);
+            script.forEach_testNativePowrHalfHalfHalf(inBase, out);
+            verifyResultsNativePowrHalfHalfHalf(inBase, inExponent, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativePowrHalfHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInExponent(inExponent);
+            scriptRelaxed.forEach_testNativePowrHalfHalfHalf(inBase, out);
+            verifyResultsNativePowrHalfHalfHalf(inBase, inExponent, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativePowrHalfHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativePowrHalfHalfHalf(Allocation inBase, Allocation inExponent, Allocation out, boolean relaxed) {
+        short[] arrayInBase = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInBase, (short) 42);
+        inBase.copyTo(arrayInBase);
+        short[] arrayInExponent = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInExponent, (short) 42);
+        inExponent.copyTo(arrayInExponent);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inBase = arrayInBase[i];
+                args.inBaseDouble = Float16Utils.convertFloat16ToDouble(args.inBase);
+                args.inExponent = arrayInExponent[i];
+                args.inExponentDouble = Float16Utils.convertFloat16ToDouble(args.inExponent);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativePowr(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inBase: ");
+                        appendVariableToMessage(message, args.inBase);
+                        message.append("\n");
+                        message.append("Input inExponent: ");
+                        appendVariableToMessage(message, args.inExponent);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativePowrHalfHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativePowrHalf2Half2Half2() {
+        Allocation inBase = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xdfd0cbe8l, 0, 256);
+        Allocation inExponent = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xb2e110el, -15, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.set_gAllocInExponent(inExponent);
+            script.forEach_testNativePowrHalf2Half2Half2(inBase, out);
+            verifyResultsNativePowrHalf2Half2Half2(inBase, inExponent, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativePowrHalf2Half2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInExponent(inExponent);
+            scriptRelaxed.forEach_testNativePowrHalf2Half2Half2(inBase, out);
+            verifyResultsNativePowrHalf2Half2Half2(inBase, inExponent, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativePowrHalf2Half2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativePowrHalf2Half2Half2(Allocation inBase, Allocation inExponent, Allocation out, boolean relaxed) {
+        short[] arrayInBase = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInBase, (short) 42);
+        inBase.copyTo(arrayInBase);
+        short[] arrayInExponent = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInExponent, (short) 42);
+        inExponent.copyTo(arrayInExponent);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inBase = arrayInBase[i * 2 + j];
+                args.inBaseDouble = Float16Utils.convertFloat16ToDouble(args.inBase);
+                args.inExponent = arrayInExponent[i * 2 + j];
+                args.inExponentDouble = Float16Utils.convertFloat16ToDouble(args.inExponent);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativePowr(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inBase: ");
+                        appendVariableToMessage(message, args.inBase);
+                        message.append("\n");
+                        message.append("Input inExponent: ");
+                        appendVariableToMessage(message, args.inExponent);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativePowrHalf2Half2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativePowrHalf3Half3Half3() {
+        Allocation inBase = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 3, 0xd3821cc5l, 0, 256);
+        Allocation inExponent = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 3, 0xcef3bdbl, -15, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.set_gAllocInExponent(inExponent);
+            script.forEach_testNativePowrHalf3Half3Half3(inBase, out);
+            verifyResultsNativePowrHalf3Half3Half3(inBase, inExponent, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativePowrHalf3Half3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInExponent(inExponent);
+            scriptRelaxed.forEach_testNativePowrHalf3Half3Half3(inBase, out);
+            verifyResultsNativePowrHalf3Half3Half3(inBase, inExponent, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativePowrHalf3Half3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativePowrHalf3Half3Half3(Allocation inBase, Allocation inExponent, Allocation out, boolean relaxed) {
+        short[] arrayInBase = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInBase, (short) 42);
+        inBase.copyTo(arrayInBase);
+        short[] arrayInExponent = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInExponent, (short) 42);
+        inExponent.copyTo(arrayInExponent);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inBase = arrayInBase[i * 4 + j];
+                args.inBaseDouble = Float16Utils.convertFloat16ToDouble(args.inBase);
+                args.inExponent = arrayInExponent[i * 4 + j];
+                args.inExponentDouble = Float16Utils.convertFloat16ToDouble(args.inExponent);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativePowr(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inBase: ");
+                        appendVariableToMessage(message, args.inBase);
+                        message.append("\n");
+                        message.append("Input inExponent: ");
+                        appendVariableToMessage(message, args.inExponent);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativePowrHalf3Half3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativePowrHalf4Half4Half4() {
+        Allocation inBase = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xc7336da2l, 0, 256);
+        Allocation inExponent = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xeb066a8l, -15, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.set_gAllocInExponent(inExponent);
+            script.forEach_testNativePowrHalf4Half4Half4(inBase, out);
+            verifyResultsNativePowrHalf4Half4Half4(inBase, inExponent, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativePowrHalf4Half4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInExponent(inExponent);
+            scriptRelaxed.forEach_testNativePowrHalf4Half4Half4(inBase, out);
+            verifyResultsNativePowrHalf4Half4Half4(inBase, inExponent, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativePowrHalf4Half4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativePowrHalf4Half4Half4(Allocation inBase, Allocation inExponent, Allocation out, boolean relaxed) {
+        short[] arrayInBase = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInBase, (short) 42);
+        inBase.copyTo(arrayInBase);
+        short[] arrayInExponent = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInExponent, (short) 42);
+        inExponent.copyTo(arrayInExponent);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inBase = arrayInBase[i * 4 + j];
+                args.inBaseDouble = Float16Utils.convertFloat16ToDouble(args.inBase);
+                args.inExponent = arrayInExponent[i * 4 + j];
+                args.inExponentDouble = Float16Utils.convertFloat16ToDouble(args.inExponent);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativePowr(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inBase: ");
+                        appendVariableToMessage(message, args.inBase);
+                        message.append("\n");
+                        message.append("Input inExponent: ");
+                        appendVariableToMessage(message, args.inExponent);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativePowrHalf4Half4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testNativePowr() {
         checkNativePowrFloatFloatFloat();
         checkNativePowrFloat2Float2Float2();
         checkNativePowrFloat3Float3Float3();
         checkNativePowrFloat4Float4Float4();
+        checkNativePowrHalfHalfHalf();
+        checkNativePowrHalf2Half2Half2();
+        checkNativePowrHalf3Half3Half3();
+        checkNativePowrHalf4Half4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativePowr.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativePowr.rs
index 4bedb98..c3c7472 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativePowr.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativePowr.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -40,3 +40,23 @@
     float4 inExponent = rsGetElementAt_float4(gAllocInExponent, x);
     return native_powr(inBase, inExponent);
 }
+
+half __attribute__((kernel)) testNativePowrHalfHalfHalf(half inBase, unsigned int x) {
+    half inExponent = rsGetElementAt_half(gAllocInExponent, x);
+    return native_powr(inBase, inExponent);
+}
+
+half2 __attribute__((kernel)) testNativePowrHalf2Half2Half2(half2 inBase, unsigned int x) {
+    half2 inExponent = rsGetElementAt_half2(gAllocInExponent, x);
+    return native_powr(inBase, inExponent);
+}
+
+half3 __attribute__((kernel)) testNativePowrHalf3Half3Half3(half3 inBase, unsigned int x) {
+    half3 inExponent = rsGetElementAt_half3(gAllocInExponent, x);
+    return native_powr(inBase, inExponent);
+}
+
+half4 __attribute__((kernel)) testNativePowrHalf4Half4Half4(half4 inBase, unsigned int x) {
+    half4 inExponent = rsGetElementAt_half4(gAllocInExponent, x);
+    return native_powr(inBase, inExponent);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativePowrRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativePowrRelaxed.rs
index c453409..1ddce4e 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativePowrRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativePowrRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeRecip.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeRecip.java
index 3793956..c33d5ba 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeRecip.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeRecip.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeRecip(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeRecip(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeRecip(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeRecip(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeRecipHalfHalf() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xee148533l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testNativeRecipHalfHalf(inV, out);
+            verifyResultsNativeRecipHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeRecipHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeRecipHalfHalf(inV, out);
+            verifyResultsNativeRecipHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeRecipHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeRecipHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeRecip(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeRecipHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeRecipHalf2Half2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x396d1b7dl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testNativeRecipHalf2Half2(inV, out);
+            verifyResultsNativeRecipHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeRecipHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeRecipHalf2Half2(inV, out);
+            verifyResultsNativeRecipHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeRecipHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeRecipHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeRecip(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeRecipHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeRecipHalf3Half3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x9874e071l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testNativeRecipHalf3Half3(inV, out);
+            verifyResultsNativeRecipHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeRecipHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeRecipHalf3Half3(inV, out);
+            verifyResultsNativeRecipHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeRecipHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeRecipHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeRecip(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeRecipHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeRecipHalf4Half4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xf77ca565l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testNativeRecipHalf4Half4(inV, out);
+            verifyResultsNativeRecipHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeRecipHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeRecipHalf4Half4(inV, out);
+            verifyResultsNativeRecipHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeRecipHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeRecipHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeRecip(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeRecipHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testNativeRecip() {
         checkNativeRecipFloatFloat();
         checkNativeRecipFloat2Float2();
         checkNativeRecipFloat3Float3();
         checkNativeRecipFloat4Float4();
+        checkNativeRecipHalfHalf();
+        checkNativeRecipHalf2Half2();
+        checkNativeRecipHalf3Half3();
+        checkNativeRecipHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeRecip.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeRecip.rs
index 7eb6419..bde315b 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeRecip.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeRecip.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testNativeRecipFloat4Float4(float4 inV) {
     return native_recip(inV);
 }
+
+half __attribute__((kernel)) testNativeRecipHalfHalf(half inV) {
+    return native_recip(inV);
+}
+
+half2 __attribute__((kernel)) testNativeRecipHalf2Half2(half2 inV) {
+    return native_recip(inV);
+}
+
+half3 __attribute__((kernel)) testNativeRecipHalf3Half3(half3 inV) {
+    return native_recip(inV);
+}
+
+half4 __attribute__((kernel)) testNativeRecipHalf4Half4(half4 inV) {
+    return native_recip(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeRecipRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeRecipRelaxed.rs
index 432a3a9..9ea5ea8 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeRecipRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeRecipRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeRootn.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeRootn.java
index 09f6c516..8143573 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeRootn.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeRootn.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -82,7 +83,7 @@
                 args.inV = arrayInV[i];
                 args.inN = arrayInN[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeRootn(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -161,7 +162,7 @@
                 args.inV = arrayInV[i * 2 + j];
                 args.inN = arrayInN[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeRootn(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -240,7 +241,7 @@
                 args.inV = arrayInV[i * 4 + j];
                 args.inN = arrayInN[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeRootn(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -319,7 +320,7 @@
                 args.inV = arrayInV[i * 4 + j];
                 args.inN = arrayInN[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeRootn(args, target);
                 // Validate the outputs.
                 boolean valid = true;
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeRootn.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeRootn.rs
index dcd3e52..e2cee8c 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeRootn.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeRootn.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeRootnRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeRootnRelaxed.rs
index ffb70c0f..d5a0f1f 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeRootnRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeRootnRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeRsqrt.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeRsqrt.java
index fd157b4..9989598b 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeRsqrt.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeRsqrt.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeRsqrt(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeRsqrt(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeRsqrt(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeRsqrt(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeRsqrtHalfHalf() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x3e331e90l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testNativeRsqrtHalfHalf(inV, out);
+            verifyResultsNativeRsqrtHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeRsqrtHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeRsqrtHalfHalf(inV, out);
+            verifyResultsNativeRsqrtHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeRsqrtHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeRsqrtHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeRsqrt(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeRsqrtHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeRsqrtHalf2Half2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xe66ecc32l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testNativeRsqrtHalf2Half2(inV, out);
+            verifyResultsNativeRsqrtHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeRsqrtHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeRsqrtHalf2Half2(inV, out);
+            verifyResultsNativeRsqrtHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeRsqrtHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeRsqrtHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeRsqrt(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeRsqrtHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeRsqrtHalf3Half3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x45769126l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testNativeRsqrtHalf3Half3(inV, out);
+            verifyResultsNativeRsqrtHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeRsqrtHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeRsqrtHalf3Half3(inV, out);
+            verifyResultsNativeRsqrtHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeRsqrtHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeRsqrtHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeRsqrt(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeRsqrtHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeRsqrtHalf4Half4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xa47e561al, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testNativeRsqrtHalf4Half4(inV, out);
+            verifyResultsNativeRsqrtHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeRsqrtHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeRsqrtHalf4Half4(inV, out);
+            verifyResultsNativeRsqrtHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeRsqrtHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeRsqrtHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeRsqrt(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeRsqrtHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testNativeRsqrt() {
         checkNativeRsqrtFloatFloat();
         checkNativeRsqrtFloat2Float2();
         checkNativeRsqrtFloat3Float3();
         checkNativeRsqrtFloat4Float4();
+        checkNativeRsqrtHalfHalf();
+        checkNativeRsqrtHalf2Half2();
+        checkNativeRsqrtHalf3Half3();
+        checkNativeRsqrtHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeRsqrt.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeRsqrt.rs
index ce49268..420e283 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeRsqrt.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeRsqrt.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testNativeRsqrtFloat4Float4(float4 inV) {
     return native_rsqrt(inV);
 }
+
+half __attribute__((kernel)) testNativeRsqrtHalfHalf(half inV) {
+    return native_rsqrt(inV);
+}
+
+half2 __attribute__((kernel)) testNativeRsqrtHalf2Half2(half2 inV) {
+    return native_rsqrt(inV);
+}
+
+half3 __attribute__((kernel)) testNativeRsqrtHalf3Half3(half3 inV) {
+    return native_rsqrt(inV);
+}
+
+half4 __attribute__((kernel)) testNativeRsqrtHalf4Half4(half4 inV) {
+    return native_rsqrt(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeRsqrtRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeRsqrtRelaxed.rs
index 6228ce5..a832c1c 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeRsqrtRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeRsqrtRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSin.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSin.java
index a49cd12..ede56bc 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSin.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSin.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeSin(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeSin(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeSin(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeSin(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeSinHalfHalf() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xd39c78f2l, -314, 314);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testNativeSinHalfHalf(inV, out);
+            verifyResultsNativeSinHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeSinHalfHalf(inV, out);
+            verifyResultsNativeSinHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeSinHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeSin(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]), 0.00048828125)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]), 0.00048828125)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeSinHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeSinHalf2Half2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xc5c9a04l, -314, 314);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testNativeSinHalf2Half2(inV, out);
+            verifyResultsNativeSinHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeSinHalf2Half2(inV, out);
+            verifyResultsNativeSinHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeSinHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeSin(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]), 0.00048828125)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]), 0.00048828125)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeSinHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeSinHalf3Half3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x6b645ef8l, -314, 314);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testNativeSinHalf3Half3(inV, out);
+            verifyResultsNativeSinHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeSinHalf3Half3(inV, out);
+            verifyResultsNativeSinHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeSinHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeSin(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]), 0.00048828125)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]), 0.00048828125)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeSinHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeSinHalf4Half4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xca6c23ecl, -314, 314);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testNativeSinHalf4Half4(inV, out);
+            verifyResultsNativeSinHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeSinHalf4Half4(inV, out);
+            verifyResultsNativeSinHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeSinHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeSin(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]), 0.00048828125)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]), 0.00048828125)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeSinHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testNativeSin() {
         checkNativeSinFloatFloat();
         checkNativeSinFloat2Float2();
         checkNativeSinFloat3Float3();
         checkNativeSinFloat4Float4();
+        checkNativeSinHalfHalf();
+        checkNativeSinHalf2Half2();
+        checkNativeSinHalf3Half3();
+        checkNativeSinHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSin.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSin.rs
index abd9be7..9850518 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSin.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSin.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testNativeSinFloat4Float4(float4 inV) {
     return native_sin(inV);
 }
+
+half __attribute__((kernel)) testNativeSinHalfHalf(half inV) {
+    return native_sin(inV);
+}
+
+half2 __attribute__((kernel)) testNativeSinHalf2Half2(half2 inV) {
+    return native_sin(inV);
+}
+
+half3 __attribute__((kernel)) testNativeSinHalf3Half3(half3 inV) {
+    return native_sin(inV);
+}
+
+half4 __attribute__((kernel)) testNativeSinHalf4Half4(half4 inV) {
+    return native_sin(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSinRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSinRelaxed.rs
index d9d8598..570618f 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSinRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSinRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSincos.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSincos.java
index 60c746b..6a1c5b5 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSincos.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSincos.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -82,7 +83,7 @@
                 ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeSincos(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -170,7 +171,7 @@
                 ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeSincos(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -258,7 +259,7 @@
                 ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeSincos(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -346,7 +347,7 @@
                 ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeSincos(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -394,10 +395,401 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty outCos;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeSincosHalfHalfHalf() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x75ce8c9al, false);
+        try {
+            Allocation outCos = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.set_gAllocOutCos(outCos);
+            script.forEach_testNativeSincosHalfHalfHalf(inV, out);
+            verifyResultsNativeSincosHalfHalfHalf(inV, outCos, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSincosHalfHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation outCos = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocOutCos(outCos);
+            scriptRelaxed.forEach_testNativeSincosHalfHalfHalf(inV, out);
+            verifyResultsNativeSincosHalfHalfHalf(inV, outCos, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSincosHalfHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeSincosHalfHalfHalf(Allocation inV, Allocation outCos, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOutCos = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOutCos, (short) 42);
+        outCos.copyTo(arrayOutCos);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeSincos(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.outCos.couldBe(Float16Utils.convertFloat16ToDouble(arrayOutCos[i * 1 + j]), 0.00048828125)) {
+                    valid = false;
+                }
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]), 0.00048828125)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output outCos: ");
+                        appendVariableToMessage(message, args.outCos);
+                        message.append("\n");
+                        message.append("Actual   output outCos: ");
+                        appendVariableToMessage(message, arrayOutCos[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output outCos (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOutCos[i * 1 + j]));
+                        if (!args.outCos.couldBe(Float16Utils.convertFloat16ToDouble(arrayOutCos[i * 1 + j]), 0.00048828125)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]), 0.00048828125)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeSincosHalfHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeSincosHalf2Half2Half2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x9b1d1008l, false);
+        try {
+            Allocation outCos = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.set_gAllocOutCos(outCos);
+            script.forEach_testNativeSincosHalf2Half2Half2(inV, out);
+            verifyResultsNativeSincosHalf2Half2Half2(inV, outCos, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSincosHalf2Half2Half2: " + e.toString());
+        }
+        try {
+            Allocation outCos = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocOutCos(outCos);
+            scriptRelaxed.forEach_testNativeSincosHalf2Half2Half2(inV, out);
+            verifyResultsNativeSincosHalf2Half2Half2(inV, outCos, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSincosHalf2Half2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeSincosHalf2Half2Half2(Allocation inV, Allocation outCos, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOutCos = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOutCos, (short) 42);
+        outCos.copyTo(arrayOutCos);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeSincos(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.outCos.couldBe(Float16Utils.convertFloat16ToDouble(arrayOutCos[i * 2 + j]), 0.00048828125)) {
+                    valid = false;
+                }
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]), 0.00048828125)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output outCos: ");
+                        appendVariableToMessage(message, args.outCos);
+                        message.append("\n");
+                        message.append("Actual   output outCos: ");
+                        appendVariableToMessage(message, arrayOutCos[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output outCos (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOutCos[i * 2 + j]));
+                        if (!args.outCos.couldBe(Float16Utils.convertFloat16ToDouble(arrayOutCos[i * 2 + j]), 0.00048828125)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]), 0.00048828125)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeSincosHalf2Half2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeSincosHalf3Half3Half3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0xf9bc20d7l, false);
+        try {
+            Allocation outCos = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.set_gAllocOutCos(outCos);
+            script.forEach_testNativeSincosHalf3Half3Half3(inV, out);
+            verifyResultsNativeSincosHalf3Half3Half3(inV, outCos, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSincosHalf3Half3Half3: " + e.toString());
+        }
+        try {
+            Allocation outCos = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocOutCos(outCos);
+            scriptRelaxed.forEach_testNativeSincosHalf3Half3Half3(inV, out);
+            verifyResultsNativeSincosHalf3Half3Half3(inV, outCos, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSincosHalf3Half3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeSincosHalf3Half3Half3(Allocation inV, Allocation outCos, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOutCos = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOutCos, (short) 42);
+        outCos.copyTo(arrayOutCos);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeSincos(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.outCos.couldBe(Float16Utils.convertFloat16ToDouble(arrayOutCos[i * 4 + j]), 0.00048828125)) {
+                    valid = false;
+                }
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]), 0.00048828125)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output outCos: ");
+                        appendVariableToMessage(message, args.outCos);
+                        message.append("\n");
+                        message.append("Actual   output outCos: ");
+                        appendVariableToMessage(message, arrayOutCos[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output outCos (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOutCos[i * 4 + j]));
+                        if (!args.outCos.couldBe(Float16Utils.convertFloat16ToDouble(arrayOutCos[i * 4 + j]), 0.00048828125)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]), 0.00048828125)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeSincosHalf3Half3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeSincosHalf4Half4Half4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x585b31a6l, false);
+        try {
+            Allocation outCos = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.set_gAllocOutCos(outCos);
+            script.forEach_testNativeSincosHalf4Half4Half4(inV, out);
+            verifyResultsNativeSincosHalf4Half4Half4(inV, outCos, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSincosHalf4Half4Half4: " + e.toString());
+        }
+        try {
+            Allocation outCos = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocOutCos(outCos);
+            scriptRelaxed.forEach_testNativeSincosHalf4Half4Half4(inV, out);
+            verifyResultsNativeSincosHalf4Half4Half4(inV, outCos, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSincosHalf4Half4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeSincosHalf4Half4Half4(Allocation inV, Allocation outCos, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOutCos = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOutCos, (short) 42);
+        outCos.copyTo(arrayOutCos);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeSincos(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.outCos.couldBe(Float16Utils.convertFloat16ToDouble(arrayOutCos[i * 4 + j]), 0.00048828125)) {
+                    valid = false;
+                }
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]), 0.00048828125)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output outCos: ");
+                        appendVariableToMessage(message, args.outCos);
+                        message.append("\n");
+                        message.append("Actual   output outCos: ");
+                        appendVariableToMessage(message, arrayOutCos[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output outCos (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOutCos[i * 4 + j]));
+                        if (!args.outCos.couldBe(Float16Utils.convertFloat16ToDouble(arrayOutCos[i * 4 + j]), 0.00048828125)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]), 0.00048828125)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeSincosHalf4Half4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testNativeSincos() {
         checkNativeSincosFloatFloatFloat();
         checkNativeSincosFloat2Float2Float2();
         checkNativeSincosFloat3Float3Float3();
         checkNativeSincosFloat4Float4Float4();
+        checkNativeSincosHalfHalfHalf();
+        checkNativeSincosHalf2Half2Half2();
+        checkNativeSincosHalf3Half3Half3();
+        checkNativeSincosHalf4Half4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSincos.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSincos.rs
index 01d2b0a..80fc27e 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSincos.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSincos.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -48,3 +48,31 @@
     rsSetElementAt_float4(gAllocOutCos, outCos, x);
     return out;
 }
+
+half __attribute__((kernel)) testNativeSincosHalfHalfHalf(half inV, unsigned int x) {
+    half outCos = 0;
+    half out = native_sincos(inV, &outCos);
+    rsSetElementAt_half(gAllocOutCos, outCos, x);
+    return out;
+}
+
+half2 __attribute__((kernel)) testNativeSincosHalf2Half2Half2(half2 inV, unsigned int x) {
+    half2 outCos = 0;
+    half2 out = native_sincos(inV, &outCos);
+    rsSetElementAt_half2(gAllocOutCos, outCos, x);
+    return out;
+}
+
+half3 __attribute__((kernel)) testNativeSincosHalf3Half3Half3(half3 inV, unsigned int x) {
+    half3 outCos = 0;
+    half3 out = native_sincos(inV, &outCos);
+    rsSetElementAt_half3(gAllocOutCos, outCos, x);
+    return out;
+}
+
+half4 __attribute__((kernel)) testNativeSincosHalf4Half4Half4(half4 inV, unsigned int x) {
+    half4 outCos = 0;
+    half4 out = native_sincos(inV, &outCos);
+    rsSetElementAt_half4(gAllocOutCos, outCos, x);
+    return out;
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSincosRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSincosRelaxed.rs
index 0b9fe34..8b7baa1 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSincosRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSincosRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSinh.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSinh.java
index 28083e9..4d7cca1 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSinh.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSinh.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeSinh(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeSinh(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeSinh(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeSinh(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeSinhHalfHalf() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x5ff5eda0l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testNativeSinhHalfHalf(inV, out);
+            verifyResultsNativeSinhHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinhHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeSinhHalfHalf(inV, out);
+            verifyResultsNativeSinhHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinhHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeSinhHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeSinh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeSinhHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeSinhHalf2Half2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xbe7856c2l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testNativeSinhHalf2Half2(inV, out);
+            verifyResultsNativeSinhHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinhHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeSinhHalf2Half2(inV, out);
+            verifyResultsNativeSinhHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinhHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeSinhHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeSinh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeSinhHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeSinhHalf3Half3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x1d801bb6l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testNativeSinhHalf3Half3(inV, out);
+            verifyResultsNativeSinhHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinhHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeSinhHalf3Half3(inV, out);
+            verifyResultsNativeSinhHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinhHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeSinhHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeSinh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeSinhHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeSinhHalf4Half4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x7c87e0aal, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testNativeSinhHalf4Half4(inV, out);
+            verifyResultsNativeSinhHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinhHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeSinhHalf4Half4(inV, out);
+            verifyResultsNativeSinhHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinhHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeSinhHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeSinh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeSinhHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testNativeSinh() {
         checkNativeSinhFloatFloat();
         checkNativeSinhFloat2Float2();
         checkNativeSinhFloat3Float3();
         checkNativeSinhFloat4Float4();
+        checkNativeSinhHalfHalf();
+        checkNativeSinhHalf2Half2();
+        checkNativeSinhHalf3Half3();
+        checkNativeSinhHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSinh.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSinh.rs
index 0440188..6ffca22 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSinh.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSinh.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testNativeSinhFloat4Float4(float4 inV) {
     return native_sinh(inV);
 }
+
+half __attribute__((kernel)) testNativeSinhHalfHalf(half inV) {
+    return native_sinh(inV);
+}
+
+half2 __attribute__((kernel)) testNativeSinhHalf2Half2(half2 inV) {
+    return native_sinh(inV);
+}
+
+half3 __attribute__((kernel)) testNativeSinhHalf3Half3(half3 inV) {
+    return native_sinh(inV);
+}
+
+half4 __attribute__((kernel)) testNativeSinhHalf4Half4(half4 inV) {
+    return native_sinh(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSinhRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSinhRelaxed.rs
index 45bc8ce..2de990c 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSinhRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSinhRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSinpi.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSinpi.java
index 8cd1abf..2d7a10d 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSinpi.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSinpi.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeSinpi(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeSinpi(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeSinpi(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeSinpi(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeSinpiHalfHalf() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x8ec9715l, -100, 100);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testNativeSinpiHalfHalf(inV, out);
+            verifyResultsNativeSinpiHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinpiHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeSinpiHalfHalf(inV, out);
+            verifyResultsNativeSinpiHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinpiHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeSinpiHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeSinpi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]), 0.00048828125)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]), 0.00048828125)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeSinpiHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeSinpiHalf2Half2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x1c0644cfl, -100, 100);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testNativeSinpiHalf2Half2(inV, out);
+            verifyResultsNativeSinpiHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinpiHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeSinpiHalf2Half2(inV, out);
+            verifyResultsNativeSinpiHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinpiHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeSinpiHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeSinpi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]), 0.00048828125)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]), 0.00048828125)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeSinpiHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeSinpiHalf3Half3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x7b0e09c3l, -100, 100);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testNativeSinpiHalf3Half3(inV, out);
+            verifyResultsNativeSinpiHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinpiHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeSinpiHalf3Half3(inV, out);
+            verifyResultsNativeSinpiHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinpiHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeSinpiHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeSinpi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]), 0.00048828125)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]), 0.00048828125)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeSinpiHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeSinpiHalf4Half4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xda15ceb7l, -100, 100);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testNativeSinpiHalf4Half4(inV, out);
+            verifyResultsNativeSinpiHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinpiHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeSinpiHalf4Half4(inV, out);
+            verifyResultsNativeSinpiHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinpiHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeSinpiHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeSinpi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]), 0.00048828125)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]), 0.00048828125)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeSinpiHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testNativeSinpi() {
         checkNativeSinpiFloatFloat();
         checkNativeSinpiFloat2Float2();
         checkNativeSinpiFloat3Float3();
         checkNativeSinpiFloat4Float4();
+        checkNativeSinpiHalfHalf();
+        checkNativeSinpiHalf2Half2();
+        checkNativeSinpiHalf3Half3();
+        checkNativeSinpiHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSinpi.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSinpi.rs
index 7cd4758..eb66c65 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSinpi.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSinpi.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testNativeSinpiFloat4Float4(float4 inV) {
     return native_sinpi(inV);
 }
+
+half __attribute__((kernel)) testNativeSinpiHalfHalf(half inV) {
+    return native_sinpi(inV);
+}
+
+half2 __attribute__((kernel)) testNativeSinpiHalf2Half2(half2 inV) {
+    return native_sinpi(inV);
+}
+
+half3 __attribute__((kernel)) testNativeSinpiHalf3Half3(half3 inV) {
+    return native_sinpi(inV);
+}
+
+half4 __attribute__((kernel)) testNativeSinpiHalf4Half4(half4 inV) {
+    return native_sinpi(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSinpiRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSinpiRelaxed.rs
index 455269d..9becf5f 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSinpiRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSinpiRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSqrt.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSqrt.java
index 75a569f..a513ba6 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSqrt.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSqrt.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeSqrt(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeSqrt(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeSqrt(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeSqrt(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeSqrtHalfHalf() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x35305520l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testNativeSqrtHalfHalf(inV, out);
+            verifyResultsNativeSqrtHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSqrtHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeSqrtHalfHalf(inV, out);
+            verifyResultsNativeSqrtHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSqrtHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeSqrtHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeSqrt(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeSqrtHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeSqrtHalf2Half2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xd14de242l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testNativeSqrtHalf2Half2(inV, out);
+            verifyResultsNativeSqrtHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSqrtHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeSqrtHalf2Half2(inV, out);
+            verifyResultsNativeSqrtHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSqrtHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeSqrtHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeSqrt(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeSqrtHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeSqrtHalf3Half3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x3055a736l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testNativeSqrtHalf3Half3(inV, out);
+            verifyResultsNativeSqrtHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSqrtHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeSqrtHalf3Half3(inV, out);
+            verifyResultsNativeSqrtHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSqrtHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeSqrtHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeSqrt(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeSqrtHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeSqrtHalf4Half4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x8f5d6c2al, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testNativeSqrtHalf4Half4(inV, out);
+            verifyResultsNativeSqrtHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSqrtHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeSqrtHalf4Half4(inV, out);
+            verifyResultsNativeSqrtHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSqrtHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeSqrtHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeSqrt(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeSqrtHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testNativeSqrt() {
         checkNativeSqrtFloatFloat();
         checkNativeSqrtFloat2Float2();
         checkNativeSqrtFloat3Float3();
         checkNativeSqrtFloat4Float4();
+        checkNativeSqrtHalfHalf();
+        checkNativeSqrtHalf2Half2();
+        checkNativeSqrtHalf3Half3();
+        checkNativeSqrtHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSqrt.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSqrt.rs
index e5dcc4e..74d4960 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSqrt.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSqrt.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testNativeSqrtFloat4Float4(float4 inV) {
     return native_sqrt(inV);
 }
+
+half __attribute__((kernel)) testNativeSqrtHalfHalf(half inV) {
+    return native_sqrt(inV);
+}
+
+half2 __attribute__((kernel)) testNativeSqrtHalf2Half2(half2 inV) {
+    return native_sqrt(inV);
+}
+
+half3 __attribute__((kernel)) testNativeSqrtHalf3Half3(half3 inV) {
+    return native_sqrt(inV);
+}
+
+half4 __attribute__((kernel)) testNativeSqrtHalf4Half4(half4 inV) {
+    return native_sqrt(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSqrtRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSqrtRelaxed.rs
index 1db9ebd..9ec1ae1 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSqrtRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSqrtRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeTan.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeTan.java
index 390538a..b43ff71 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeTan.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeTan.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeTan(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeTan(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeTan(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeTan(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,293 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public short out;
+        public double outDouble;
+    }
+
+    private void checkNativeTanHalfHalf() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x3e70ec45l, -314, 314);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testNativeTanHalfHalf(inV, out);
+            verifyResultsNativeTanHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeTanHalfHalf(inV, out);
+            verifyResultsNativeTanHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeTanHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Extract the outputs.
+                args.out = arrayOut[i * 1 + j];
+                args.outDouble = Float16Utils.convertFloat16ToDouble(args.out);
+                // Ask the CoreMathVerifier to validate.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                String errorMessage = CoreMathVerifier.verifyNativeTan(args, target);
+                boolean valid = errorMessage == null;
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("\n");
+                        message.append("Output out (in double): ");
+                        appendVariableToMessage(message, args.outDouble);
+                        message.append("\n");
+                        message.append(errorMessage);
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeTanHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeTanHalf2Half2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xa4d18c7fl, -314, 314);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testNativeTanHalf2Half2(inV, out);
+            verifyResultsNativeTanHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeTanHalf2Half2(inV, out);
+            verifyResultsNativeTanHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeTanHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Extract the outputs.
+                args.out = arrayOut[i * 2 + j];
+                args.outDouble = Float16Utils.convertFloat16ToDouble(args.out);
+                // Ask the CoreMathVerifier to validate.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                String errorMessage = CoreMathVerifier.verifyNativeTan(args, target);
+                boolean valid = errorMessage == null;
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("\n");
+                        message.append("Output out (in double): ");
+                        appendVariableToMessage(message, args.outDouble);
+                        message.append("\n");
+                        message.append(errorMessage);
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeTanHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeTanHalf3Half3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x3d95173l, -314, 314);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testNativeTanHalf3Half3(inV, out);
+            verifyResultsNativeTanHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeTanHalf3Half3(inV, out);
+            verifyResultsNativeTanHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeTanHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Extract the outputs.
+                args.out = arrayOut[i * 4 + j];
+                args.outDouble = Float16Utils.convertFloat16ToDouble(args.out);
+                // Ask the CoreMathVerifier to validate.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                String errorMessage = CoreMathVerifier.verifyNativeTan(args, target);
+                boolean valid = errorMessage == null;
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("\n");
+                        message.append("Output out (in double): ");
+                        appendVariableToMessage(message, args.outDouble);
+                        message.append("\n");
+                        message.append(errorMessage);
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeTanHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeTanHalf4Half4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x62e11667l, -314, 314);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testNativeTanHalf4Half4(inV, out);
+            verifyResultsNativeTanHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeTanHalf4Half4(inV, out);
+            verifyResultsNativeTanHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeTanHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Extract the outputs.
+                args.out = arrayOut[i * 4 + j];
+                args.outDouble = Float16Utils.convertFloat16ToDouble(args.out);
+                // Ask the CoreMathVerifier to validate.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                String errorMessage = CoreMathVerifier.verifyNativeTan(args, target);
+                boolean valid = errorMessage == null;
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("\n");
+                        message.append("Output out (in double): ");
+                        appendVariableToMessage(message, args.outDouble);
+                        message.append("\n");
+                        message.append(errorMessage);
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeTanHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testNativeTan() {
         checkNativeTanFloatFloat();
         checkNativeTanFloat2Float2();
         checkNativeTanFloat3Float3();
         checkNativeTanFloat4Float4();
+        checkNativeTanHalfHalf();
+        checkNativeTanHalf2Half2();
+        checkNativeTanHalf3Half3();
+        checkNativeTanHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeTan.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeTan.rs
index 603ed8c..f28a852 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeTan.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeTan.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testNativeTanFloat4Float4(float4 inV) {
     return native_tan(inV);
 }
+
+half __attribute__((kernel)) testNativeTanHalfHalf(half inV) {
+    return native_tan(inV);
+}
+
+half2 __attribute__((kernel)) testNativeTanHalf2Half2(half2 inV) {
+    return native_tan(inV);
+}
+
+half3 __attribute__((kernel)) testNativeTanHalf3Half3(half3 inV) {
+    return native_tan(inV);
+}
+
+half4 __attribute__((kernel)) testNativeTanHalf4Half4(half4 inV) {
+    return native_tan(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeTanRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeTanRelaxed.rs
index b098bd5..dac15e0 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeTanRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeTanRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeTanh.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeTanh.java
index 4b18a96..6b2348b 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeTanh.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeTanh.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeTanh(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeTanh(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeTanh(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeTanh(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeTanhHalfHalf() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x51a54c91l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testNativeTanhHalfHalf(inV, out);
+            verifyResultsNativeTanhHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanhHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeTanhHalfHalf(inV, out);
+            verifyResultsNativeTanhHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanhHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeTanhHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeTanh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeTanhHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeTanhHalf2Half2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x5a1d116bl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testNativeTanhHalf2Half2(inV, out);
+            verifyResultsNativeTanhHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanhHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeTanhHalf2Half2(inV, out);
+            verifyResultsNativeTanhHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanhHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeTanhHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeTanh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeTanhHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeTanhHalf3Half3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0xb924d65fl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testNativeTanhHalf3Half3(inV, out);
+            verifyResultsNativeTanhHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanhHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeTanhHalf3Half3(inV, out);
+            verifyResultsNativeTanhHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanhHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeTanhHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeTanh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeTanhHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeTanhHalf4Half4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x182c9b53l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testNativeTanhHalf4Half4(inV, out);
+            verifyResultsNativeTanhHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanhHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeTanhHalf4Half4(inV, out);
+            verifyResultsNativeTanhHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanhHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeTanhHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeNativeTanh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeTanhHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testNativeTanh() {
         checkNativeTanhFloatFloat();
         checkNativeTanhFloat2Float2();
         checkNativeTanhFloat3Float3();
         checkNativeTanhFloat4Float4();
+        checkNativeTanhHalfHalf();
+        checkNativeTanhHalf2Half2();
+        checkNativeTanhHalf3Half3();
+        checkNativeTanhHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeTanh.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeTanh.rs
index 027a89f..a857d88 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeTanh.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeTanh.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testNativeTanhFloat4Float4(float4 inV) {
     return native_tanh(inV);
 }
+
+half __attribute__((kernel)) testNativeTanhHalfHalf(half inV) {
+    return native_tanh(inV);
+}
+
+half2 __attribute__((kernel)) testNativeTanhHalf2Half2(half2 inV) {
+    return native_tanh(inV);
+}
+
+half3 __attribute__((kernel)) testNativeTanhHalf3Half3(half3 inV) {
+    return native_tanh(inV);
+}
+
+half4 __attribute__((kernel)) testNativeTanhHalf4Half4(half4 inV) {
+    return native_tanh(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeTanhRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeTanhRelaxed.rs
index f18baa7..ded8d31 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeTanhRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeTanhRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeTanpi.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeTanpi.java
index dcf2e608..4104851 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeTanpi.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeTanpi.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeTanpi(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeTanpi(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeTanpi(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNativeTanpi(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,293 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public short out;
+        public double outDouble;
+    }
+
+    private void checkNativeTanpiHalfHalf() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xa1618990l, -100, 100);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testNativeTanpiHalfHalf(inV, out);
+            verifyResultsNativeTanpiHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanpiHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeTanpiHalfHalf(inV, out);
+            verifyResultsNativeTanpiHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanpiHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeTanpiHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Extract the outputs.
+                args.out = arrayOut[i * 1 + j];
+                args.outDouble = Float16Utils.convertFloat16ToDouble(args.out);
+                // Ask the CoreMathVerifier to validate.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                String errorMessage = CoreMathVerifier.verifyNativeTanpi(args, target);
+                boolean valid = errorMessage == null;
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("\n");
+                        message.append("Output out (in double): ");
+                        appendVariableToMessage(message, args.outDouble);
+                        message.append("\n");
+                        message.append(errorMessage);
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeTanpiHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeTanpiHalf2Half2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x40b19f32l, -100, 100);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testNativeTanpiHalf2Half2(inV, out);
+            verifyResultsNativeTanpiHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanpiHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeTanpiHalf2Half2(inV, out);
+            verifyResultsNativeTanpiHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanpiHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeTanpiHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Extract the outputs.
+                args.out = arrayOut[i * 2 + j];
+                args.outDouble = Float16Utils.convertFloat16ToDouble(args.out);
+                // Ask the CoreMathVerifier to validate.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                String errorMessage = CoreMathVerifier.verifyNativeTanpi(args, target);
+                boolean valid = errorMessage == null;
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("\n");
+                        message.append("Output out (in double): ");
+                        appendVariableToMessage(message, args.outDouble);
+                        message.append("\n");
+                        message.append(errorMessage);
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeTanpiHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeTanpiHalf3Half3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x9fb96426l, -100, 100);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testNativeTanpiHalf3Half3(inV, out);
+            verifyResultsNativeTanpiHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanpiHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeTanpiHalf3Half3(inV, out);
+            verifyResultsNativeTanpiHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanpiHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeTanpiHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Extract the outputs.
+                args.out = arrayOut[i * 4 + j];
+                args.outDouble = Float16Utils.convertFloat16ToDouble(args.out);
+                // Ask the CoreMathVerifier to validate.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                String errorMessage = CoreMathVerifier.verifyNativeTanpi(args, target);
+                boolean valid = errorMessage == null;
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("\n");
+                        message.append("Output out (in double): ");
+                        appendVariableToMessage(message, args.outDouble);
+                        message.append("\n");
+                        message.append(errorMessage);
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeTanpiHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeTanpiHalf4Half4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xfec1291al, -100, 100);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testNativeTanpiHalf4Half4(inV, out);
+            verifyResultsNativeTanpiHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanpiHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeTanpiHalf4Half4(inV, out);
+            verifyResultsNativeTanpiHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanpiHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeTanpiHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Extract the outputs.
+                args.out = arrayOut[i * 4 + j];
+                args.outDouble = Float16Utils.convertFloat16ToDouble(args.out);
+                // Ask the CoreMathVerifier to validate.
+                Target target = new Target(Target.FunctionType.NATIVE, Target.ReturnType.HALF, relaxed);
+                String errorMessage = CoreMathVerifier.verifyNativeTanpi(args, target);
+                boolean valid = errorMessage == null;
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("\n");
+                        message.append("Output out (in double): ");
+                        appendVariableToMessage(message, args.outDouble);
+                        message.append("\n");
+                        message.append(errorMessage);
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeTanpiHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testNativeTanpi() {
         checkNativeTanpiFloatFloat();
         checkNativeTanpiFloat2Float2();
         checkNativeTanpiFloat3Float3();
         checkNativeTanpiFloat4Float4();
+        checkNativeTanpiHalfHalf();
+        checkNativeTanpiHalf2Half2();
+        checkNativeTanpiHalf3Half3();
+        checkNativeTanpiHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeTanpi.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeTanpi.rs
index e0c4b0b..902cda2 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeTanpi.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeTanpi.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testNativeTanpiFloat4Float4(float4 inV) {
     return native_tanpi(inV);
 }
+
+half __attribute__((kernel)) testNativeTanpiHalfHalf(half inV) {
+    return native_tanpi(inV);
+}
+
+half2 __attribute__((kernel)) testNativeTanpiHalf2Half2(half2 inV) {
+    return native_tanpi(inV);
+}
+
+half3 __attribute__((kernel)) testNativeTanpiHalf3Half3(half3 inV) {
+    return native_tanpi(inV);
+}
+
+half4 __attribute__((kernel)) testNativeTanpiHalf4Half4(half4 inV) {
+    return native_tanpi(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeTanpiRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeTanpiRelaxed.rs
index b542ad9..206ad88 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeTanpiRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeTanpiRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNextafter.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNextafter.java
index 57914c8..596909f 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNextafter.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNextafter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -82,7 +83,7 @@
                 args.inV = arrayInV[i];
                 args.inTarget = arrayInTarget[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNextafter(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -161,7 +162,7 @@
                 args.inV = arrayInV[i * 2 + j];
                 args.inTarget = arrayInTarget[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNextafter(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -240,7 +241,7 @@
                 args.inV = arrayInV[i * 4 + j];
                 args.inTarget = arrayInTarget[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNextafter(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -319,7 +320,7 @@
                 args.inV = arrayInV[i * 4 + j];
                 args.inTarget = arrayInTarget[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeNextafter(args, target);
                 // Validate the outputs.
                 boolean valid = true;
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNextafter.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNextafter.rs
index fb9ac70..e55ff17 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNextafter.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNextafter.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNextafterRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNextafterRelaxed.rs
index fd8dad3..59b48c8 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNextafterRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNextafterRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNormalize.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNormalize.java
index 8dd2708..77687d5 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNormalize.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNormalize.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -73,7 +74,7 @@
             // Create the appropriate sized arrays in args
             // Fill args with the input values
             args.inV = arrayInV[i];
-            Target target = new Target(relaxed);
+            Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
             CoreMathVerifier.computeNormalize(args, target);
 
             // Compare the expected outputs to the actual values returned by RS.
@@ -148,7 +149,7 @@
             for (int j = 0; j < 2 ; j++) {
                 args.inV[j] = arrayInV[i * 2 + j];
             }
-            Target target = new Target(relaxed);
+            Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
             CoreMathVerifier.computeNormalize(args, target);
 
             // Compare the expected outputs to the actual values returned by RS.
@@ -224,7 +225,7 @@
             for (int j = 0; j < 3 ; j++) {
                 args.inV[j] = arrayInV[i * 4 + j];
             }
-            Target target = new Target(relaxed);
+            Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
             CoreMathVerifier.computeNormalize(args, target);
 
             // Compare the expected outputs to the actual values returned by RS.
@@ -300,7 +301,7 @@
             for (int j = 0; j < 4 ; j++) {
                 args.inV[j] = arrayInV[i * 4 + j];
             }
-            Target target = new Target(relaxed);
+            Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
             CoreMathVerifier.computeNormalize(args, target);
 
             // Compare the expected outputs to the actual values returned by RS.
@@ -340,10 +341,339 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkNormalizeHalfHalf() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x2f4d2e6l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testNormalizeHalfHalf(inV, out);
+            verifyResultsNormalizeHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNormalizeHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNormalizeHalfHalf(inV, out);
+            verifyResultsNormalizeHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNormalizeHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNormalizeHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+            // Create the appropriate sized arrays in args
+            // Fill args with the input values
+            args.inV = arrayInV[i];
+            args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+            Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+            CoreMathVerifier.computeNormalize(args, target);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i]))) {
+                valid = false;
+            }
+            if (!valid) {
+                if (!errorFound) {
+                    errorFound = true;
+                    message.append("Input inV: ");
+                    appendVariableToMessage(message, arrayInV[i]);
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    appendVariableToMessage(message, args.out);
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    appendVariableToMessage(message, arrayOut[i]);
+                    message.append("\n");
+                    message.append("Actual   output out (in double): ");
+                    appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i]));
+                    if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i]))) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    message.append("Errors at");
+                }
+                message.append(" [");
+                message.append(Integer.toString(i));
+                message.append("]");
+            }
+        }
+        assertFalse("Incorrect output for checkNormalizeHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsHalfNHalfN {
+        public short[] inV;
+        public double[] inVDouble;
+        public Target.Floaty[] out;
+    }
+
+    private void checkNormalizeHalf2Half2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x17e4d58l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testNormalizeHalf2Half2(inV, out);
+            verifyResultsNormalizeHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNormalizeHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNormalizeHalf2Half2(inV, out);
+            verifyResultsNormalizeHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNormalizeHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNormalizeHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsHalfNHalfN args = new ArgumentsHalfNHalfN();
+            // Create the appropriate sized arrays in args
+            args.inV = new short[2];
+            args.inVDouble = new double[2];
+            args.out = new Target.Floaty[2];
+            // Fill args with the input values
+            for (int j = 0; j < 2 ; j++) {
+                args.inV[j] = arrayInV[i * 2 + j];
+                args.inVDouble[j] = Float16Utils.convertFloat16ToDouble(args.inV[j]);
+            }
+            Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+            CoreMathVerifier.computeNormalize(args, target);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            for (int j = 0; j < 2 ; j++) {
+                if (!args.out[j].couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+            }
+            if (!valid) {
+                if (!errorFound) {
+                    errorFound = true;
+                    for (int j = 0; j < 2 ; j++) {
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, arrayInV[i * 2 + j]);
+                        message.append("\n");
+                    }
+                    for (int j = 0; j < 2 ; j++) {
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out[j]);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out[j].couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                    }
+                    message.append("Errors at");
+                }
+                message.append(" [");
+                message.append(Integer.toString(i));
+                message.append("]");
+            }
+        }
+        assertFalse("Incorrect output for checkNormalizeHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNormalizeHalf3Half3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x6086124cl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testNormalizeHalf3Half3(inV, out);
+            verifyResultsNormalizeHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNormalizeHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNormalizeHalf3Half3(inV, out);
+            verifyResultsNormalizeHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNormalizeHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNormalizeHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsHalfNHalfN args = new ArgumentsHalfNHalfN();
+            // Create the appropriate sized arrays in args
+            args.inV = new short[3];
+            args.inVDouble = new double[3];
+            args.out = new Target.Floaty[3];
+            // Fill args with the input values
+            for (int j = 0; j < 3 ; j++) {
+                args.inV[j] = arrayInV[i * 4 + j];
+                args.inVDouble[j] = Float16Utils.convertFloat16ToDouble(args.inV[j]);
+            }
+            Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+            CoreMathVerifier.computeNormalize(args, target);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            for (int j = 0; j < 3 ; j++) {
+                if (!args.out[j].couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+            }
+            if (!valid) {
+                if (!errorFound) {
+                    errorFound = true;
+                    for (int j = 0; j < 3 ; j++) {
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, arrayInV[i * 4 + j]);
+                        message.append("\n");
+                    }
+                    for (int j = 0; j < 3 ; j++) {
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out[j]);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out[j].couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                    }
+                    message.append("Errors at");
+                }
+                message.append(" [");
+                message.append(Integer.toString(i));
+                message.append("]");
+            }
+        }
+        assertFalse("Incorrect output for checkNormalizeHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNormalizeHalf4Half4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xbf8dd740l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testNormalizeHalf4Half4(inV, out);
+            verifyResultsNormalizeHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNormalizeHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNormalizeHalf4Half4(inV, out);
+            verifyResultsNormalizeHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNormalizeHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNormalizeHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsHalfNHalfN args = new ArgumentsHalfNHalfN();
+            // Create the appropriate sized arrays in args
+            args.inV = new short[4];
+            args.inVDouble = new double[4];
+            args.out = new Target.Floaty[4];
+            // Fill args with the input values
+            for (int j = 0; j < 4 ; j++) {
+                args.inV[j] = arrayInV[i * 4 + j];
+                args.inVDouble[j] = Float16Utils.convertFloat16ToDouble(args.inV[j]);
+            }
+            Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+            CoreMathVerifier.computeNormalize(args, target);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            for (int j = 0; j < 4 ; j++) {
+                if (!args.out[j].couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+            }
+            if (!valid) {
+                if (!errorFound) {
+                    errorFound = true;
+                    for (int j = 0; j < 4 ; j++) {
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, arrayInV[i * 4 + j]);
+                        message.append("\n");
+                    }
+                    for (int j = 0; j < 4 ; j++) {
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out[j]);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out[j].couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                    }
+                    message.append("Errors at");
+                }
+                message.append(" [");
+                message.append(Integer.toString(i));
+                message.append("]");
+            }
+        }
+        assertFalse("Incorrect output for checkNormalizeHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testNormalize() {
         checkNormalizeFloatFloat();
         checkNormalizeFloat2Float2();
         checkNormalizeFloat3Float3();
         checkNormalizeFloat4Float4();
+        checkNormalizeHalfHalf();
+        checkNormalizeHalf2Half2();
+        checkNormalizeHalf3Half3();
+        checkNormalizeHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNormalize.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNormalize.rs
index 46c8aad..6eacdfc 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNormalize.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNormalize.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testNormalizeFloat4Float4(float4 inV) {
     return normalize(inV);
 }
+
+half __attribute__((kernel)) testNormalizeHalfHalf(half inV) {
+    return normalize(inV);
+}
+
+half2 __attribute__((kernel)) testNormalizeHalf2Half2(half2 inV) {
+    return normalize(inV);
+}
+
+half3 __attribute__((kernel)) testNormalizeHalf3Half3(half3 inV) {
+    return normalize(inV);
+}
+
+half4 __attribute__((kernel)) testNormalizeHalf4Half4(half4 inV) {
+    return normalize(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNormalizeRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNormalizeRelaxed.rs
index 48d69b8..e1d6a16 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNormalizeRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNormalizeRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestPow.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestPow.java
index 296927e..2aa4e99 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestPow.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestPow.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -82,7 +83,7 @@
                 args.inBase = arrayInBase[i];
                 args.inExponent = arrayInExponent[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computePow(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -161,7 +162,7 @@
                 args.inBase = arrayInBase[i * 2 + j];
                 args.inExponent = arrayInExponent[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computePow(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -240,7 +241,7 @@
                 args.inBase = arrayInBase[i * 4 + j];
                 args.inExponent = arrayInExponent[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computePow(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -319,7 +320,7 @@
                 args.inBase = arrayInBase[i * 4 + j];
                 args.inExponent = arrayInExponent[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computePow(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -358,10 +359,358 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalfHalf {
+        public short inBase;
+        public double inBaseDouble;
+        public short inExponent;
+        public double inExponentDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkPowHalfHalfHalf() {
+        Allocation inBase = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xe2a33d87l, false);
+        Allocation inExponent = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x999eb5fdl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.set_gAllocInExponent(inExponent);
+            script.forEach_testPowHalfHalfHalf(inBase, out);
+            verifyResultsPowHalfHalfHalf(inBase, inExponent, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPowHalfHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInExponent(inExponent);
+            scriptRelaxed.forEach_testPowHalfHalfHalf(inBase, out);
+            verifyResultsPowHalfHalfHalf(inBase, inExponent, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPowHalfHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsPowHalfHalfHalf(Allocation inBase, Allocation inExponent, Allocation out, boolean relaxed) {
+        short[] arrayInBase = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInBase, (short) 42);
+        inBase.copyTo(arrayInBase);
+        short[] arrayInExponent = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInExponent, (short) 42);
+        inExponent.copyTo(arrayInExponent);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inBase = arrayInBase[i];
+                args.inBaseDouble = Float16Utils.convertFloat16ToDouble(args.inBase);
+                args.inExponent = arrayInExponent[i];
+                args.inExponentDouble = Float16Utils.convertFloat16ToDouble(args.inExponent);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computePow(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inBase: ");
+                        appendVariableToMessage(message, args.inBase);
+                        message.append("\n");
+                        message.append("Input inExponent: ");
+                        appendVariableToMessage(message, args.inExponent);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkPowHalfHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkPowHalf2Half2Half2() {
+        Allocation inBase = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xbeaf459dl, false);
+        Allocation inExponent = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x5bbbe933l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.set_gAllocInExponent(inExponent);
+            script.forEach_testPowHalf2Half2Half2(inBase, out);
+            verifyResultsPowHalf2Half2Half2(inBase, inExponent, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPowHalf2Half2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInExponent(inExponent);
+            scriptRelaxed.forEach_testPowHalf2Half2Half2(inBase, out);
+            verifyResultsPowHalf2Half2Half2(inBase, inExponent, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPowHalf2Half2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsPowHalf2Half2Half2(Allocation inBase, Allocation inExponent, Allocation out, boolean relaxed) {
+        short[] arrayInBase = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInBase, (short) 42);
+        inBase.copyTo(arrayInBase);
+        short[] arrayInExponent = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInExponent, (short) 42);
+        inExponent.copyTo(arrayInExponent);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inBase = arrayInBase[i * 2 + j];
+                args.inBaseDouble = Float16Utils.convertFloat16ToDouble(args.inBase);
+                args.inExponent = arrayInExponent[i * 2 + j];
+                args.inExponentDouble = Float16Utils.convertFloat16ToDouble(args.inExponent);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computePow(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inBase: ");
+                        appendVariableToMessage(message, args.inBase);
+                        message.append("\n");
+                        message.append("Input inExponent: ");
+                        appendVariableToMessage(message, args.inExponent);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkPowHalf2Half2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkPowHalf3Half3Half3() {
+        Allocation inBase = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0xb260967al, false);
+        Allocation inExponent = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x5d7d1400l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.set_gAllocInExponent(inExponent);
+            script.forEach_testPowHalf3Half3Half3(inBase, out);
+            verifyResultsPowHalf3Half3Half3(inBase, inExponent, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPowHalf3Half3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInExponent(inExponent);
+            scriptRelaxed.forEach_testPowHalf3Half3Half3(inBase, out);
+            verifyResultsPowHalf3Half3Half3(inBase, inExponent, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPowHalf3Half3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsPowHalf3Half3Half3(Allocation inBase, Allocation inExponent, Allocation out, boolean relaxed) {
+        short[] arrayInBase = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInBase, (short) 42);
+        inBase.copyTo(arrayInBase);
+        short[] arrayInExponent = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInExponent, (short) 42);
+        inExponent.copyTo(arrayInExponent);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inBase = arrayInBase[i * 4 + j];
+                args.inBaseDouble = Float16Utils.convertFloat16ToDouble(args.inBase);
+                args.inExponent = arrayInExponent[i * 4 + j];
+                args.inExponentDouble = Float16Utils.convertFloat16ToDouble(args.inExponent);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computePow(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inBase: ");
+                        appendVariableToMessage(message, args.inBase);
+                        message.append("\n");
+                        message.append("Input inExponent: ");
+                        appendVariableToMessage(message, args.inExponent);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkPowHalf3Half3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkPowHalf4Half4Half4() {
+        Allocation inBase = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xa611e757l, false);
+        Allocation inExponent = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x5f3e3ecdl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.set_gAllocInExponent(inExponent);
+            script.forEach_testPowHalf4Half4Half4(inBase, out);
+            verifyResultsPowHalf4Half4Half4(inBase, inExponent, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPowHalf4Half4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInExponent(inExponent);
+            scriptRelaxed.forEach_testPowHalf4Half4Half4(inBase, out);
+            verifyResultsPowHalf4Half4Half4(inBase, inExponent, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPowHalf4Half4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsPowHalf4Half4Half4(Allocation inBase, Allocation inExponent, Allocation out, boolean relaxed) {
+        short[] arrayInBase = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInBase, (short) 42);
+        inBase.copyTo(arrayInBase);
+        short[] arrayInExponent = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInExponent, (short) 42);
+        inExponent.copyTo(arrayInExponent);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inBase = arrayInBase[i * 4 + j];
+                args.inBaseDouble = Float16Utils.convertFloat16ToDouble(args.inBase);
+                args.inExponent = arrayInExponent[i * 4 + j];
+                args.inExponentDouble = Float16Utils.convertFloat16ToDouble(args.inExponent);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computePow(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inBase: ");
+                        appendVariableToMessage(message, args.inBase);
+                        message.append("\n");
+                        message.append("Input inExponent: ");
+                        appendVariableToMessage(message, args.inExponent);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkPowHalf4Half4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testPow() {
         checkPowFloatFloatFloat();
         checkPowFloat2Float2Float2();
         checkPowFloat3Float3Float3();
         checkPowFloat4Float4Float4();
+        checkPowHalfHalfHalf();
+        checkPowHalf2Half2Half2();
+        checkPowHalf3Half3Half3();
+        checkPowHalf4Half4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestPow.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestPow.rs
index 2ef2106..651b41c 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestPow.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestPow.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -40,3 +40,23 @@
     float4 inExponent = rsGetElementAt_float4(gAllocInExponent, x);
     return pow(inBase, inExponent);
 }
+
+half __attribute__((kernel)) testPowHalfHalfHalf(half inBase, unsigned int x) {
+    half inExponent = rsGetElementAt_half(gAllocInExponent, x);
+    return pow(inBase, inExponent);
+}
+
+half2 __attribute__((kernel)) testPowHalf2Half2Half2(half2 inBase, unsigned int x) {
+    half2 inExponent = rsGetElementAt_half2(gAllocInExponent, x);
+    return pow(inBase, inExponent);
+}
+
+half3 __attribute__((kernel)) testPowHalf3Half3Half3(half3 inBase, unsigned int x) {
+    half3 inExponent = rsGetElementAt_half3(gAllocInExponent, x);
+    return pow(inBase, inExponent);
+}
+
+half4 __attribute__((kernel)) testPowHalf4Half4Half4(half4 inBase, unsigned int x) {
+    half4 inExponent = rsGetElementAt_half4(gAllocInExponent, x);
+    return pow(inBase, inExponent);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestPowRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestPowRelaxed.rs
index 042b07c..f00f3f4 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestPowRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestPowRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestPown.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestPown.java
index 5a866f5..51233de 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestPown.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestPown.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -82,7 +83,7 @@
                 args.inBase = arrayInBase[i];
                 args.inExponent = arrayInExponent[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computePown(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -161,7 +162,7 @@
                 args.inBase = arrayInBase[i * 2 + j];
                 args.inExponent = arrayInExponent[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computePown(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -240,7 +241,7 @@
                 args.inBase = arrayInBase[i * 4 + j];
                 args.inExponent = arrayInExponent[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computePown(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -319,7 +320,7 @@
                 args.inBase = arrayInBase[i * 4 + j];
                 args.inExponent = arrayInExponent[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computePown(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -358,10 +359,353 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfIntHalf {
+        public short inBase;
+        public double inBaseDouble;
+        public int inExponent;
+        public Target.Floaty out;
+    }
+
+    private void checkPownHalfIntHalf() {
+        Allocation inBase = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x858a42bbl, false);
+        Allocation inExponent = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0x30c3d6f1l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.set_gAllocInExponent(inExponent);
+            script.forEach_testPownHalfIntHalf(inBase, out);
+            verifyResultsPownHalfIntHalf(inBase, inExponent, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPownHalfIntHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInExponent(inExponent);
+            scriptRelaxed.forEach_testPownHalfIntHalf(inBase, out);
+            verifyResultsPownHalfIntHalf(inBase, inExponent, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPownHalfIntHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsPownHalfIntHalf(Allocation inBase, Allocation inExponent, Allocation out, boolean relaxed) {
+        short[] arrayInBase = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInBase, (short) 42);
+        inBase.copyTo(arrayInBase);
+        int[] arrayInExponent = new int[INPUTSIZE * 1];
+        Arrays.fill(arrayInExponent, (int) 42);
+        inExponent.copyTo(arrayInExponent);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfIntHalf args = new ArgumentsHalfIntHalf();
+                args.inBase = arrayInBase[i];
+                args.inBaseDouble = Float16Utils.convertFloat16ToDouble(args.inBase);
+                args.inExponent = arrayInExponent[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computePown(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inBase: ");
+                        appendVariableToMessage(message, args.inBase);
+                        message.append("\n");
+                        message.append("Input inExponent: ");
+                        appendVariableToMessage(message, args.inExponent);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkPownHalfIntHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkPownHalf2Int2Half2() {
+        Allocation inBase = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x29ccb2d5l, false);
+        Allocation inExponent = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 2, 0x6e5f9cebl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.set_gAllocInExponent(inExponent);
+            script.forEach_testPownHalf2Int2Half2(inBase, out);
+            verifyResultsPownHalf2Int2Half2(inBase, inExponent, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPownHalf2Int2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInExponent(inExponent);
+            scriptRelaxed.forEach_testPownHalf2Int2Half2(inBase, out);
+            verifyResultsPownHalf2Int2Half2(inBase, inExponent, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPownHalf2Int2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsPownHalf2Int2Half2(Allocation inBase, Allocation inExponent, Allocation out, boolean relaxed) {
+        short[] arrayInBase = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInBase, (short) 42);
+        inBase.copyTo(arrayInBase);
+        int[] arrayInExponent = new int[INPUTSIZE * 2];
+        Arrays.fill(arrayInExponent, (int) 42);
+        inExponent.copyTo(arrayInExponent);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfIntHalf args = new ArgumentsHalfIntHalf();
+                args.inBase = arrayInBase[i * 2 + j];
+                args.inBaseDouble = Float16Utils.convertFloat16ToDouble(args.inBase);
+                args.inExponent = arrayInExponent[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computePown(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inBase: ");
+                        appendVariableToMessage(message, args.inBase);
+                        message.append("\n");
+                        message.append("Input inExponent: ");
+                        appendVariableToMessage(message, args.inExponent);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkPownHalf2Int2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkPownHalf3Int3Half3() {
+        Allocation inBase = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x2f8523b4l, false);
+        Allocation inExponent = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 3, 0x92b63d1al, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.set_gAllocInExponent(inExponent);
+            script.forEach_testPownHalf3Int3Half3(inBase, out);
+            verifyResultsPownHalf3Int3Half3(inBase, inExponent, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPownHalf3Int3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInExponent(inExponent);
+            scriptRelaxed.forEach_testPownHalf3Int3Half3(inBase, out);
+            verifyResultsPownHalf3Int3Half3(inBase, inExponent, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPownHalf3Int3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsPownHalf3Int3Half3(Allocation inBase, Allocation inExponent, Allocation out, boolean relaxed) {
+        short[] arrayInBase = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInBase, (short) 42);
+        inBase.copyTo(arrayInBase);
+        int[] arrayInExponent = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInExponent, (int) 42);
+        inExponent.copyTo(arrayInExponent);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfIntHalf args = new ArgumentsHalfIntHalf();
+                args.inBase = arrayInBase[i * 4 + j];
+                args.inBaseDouble = Float16Utils.convertFloat16ToDouble(args.inBase);
+                args.inExponent = arrayInExponent[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computePown(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inBase: ");
+                        appendVariableToMessage(message, args.inBase);
+                        message.append("\n");
+                        message.append("Input inExponent: ");
+                        appendVariableToMessage(message, args.inExponent);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkPownHalf3Int3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkPownHalf4Int4Half4() {
+        Allocation inBase = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x353d9493l, false);
+        Allocation inExponent = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 4, 0xb70cdd49l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.set_gAllocInExponent(inExponent);
+            script.forEach_testPownHalf4Int4Half4(inBase, out);
+            verifyResultsPownHalf4Int4Half4(inBase, inExponent, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPownHalf4Int4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInExponent(inExponent);
+            scriptRelaxed.forEach_testPownHalf4Int4Half4(inBase, out);
+            verifyResultsPownHalf4Int4Half4(inBase, inExponent, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPownHalf4Int4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsPownHalf4Int4Half4(Allocation inBase, Allocation inExponent, Allocation out, boolean relaxed) {
+        short[] arrayInBase = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInBase, (short) 42);
+        inBase.copyTo(arrayInBase);
+        int[] arrayInExponent = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInExponent, (int) 42);
+        inExponent.copyTo(arrayInExponent);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfIntHalf args = new ArgumentsHalfIntHalf();
+                args.inBase = arrayInBase[i * 4 + j];
+                args.inBaseDouble = Float16Utils.convertFloat16ToDouble(args.inBase);
+                args.inExponent = arrayInExponent[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computePown(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inBase: ");
+                        appendVariableToMessage(message, args.inBase);
+                        message.append("\n");
+                        message.append("Input inExponent: ");
+                        appendVariableToMessage(message, args.inExponent);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkPownHalf4Int4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testPown() {
         checkPownFloatIntFloat();
         checkPownFloat2Int2Float2();
         checkPownFloat3Int3Float3();
         checkPownFloat4Int4Float4();
+        checkPownHalfIntHalf();
+        checkPownHalf2Int2Half2();
+        checkPownHalf3Int3Half3();
+        checkPownHalf4Int4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestPown.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestPown.rs
index b30af22..febc71b 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestPown.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestPown.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -40,3 +40,23 @@
     int4 inExponent = rsGetElementAt_int4(gAllocInExponent, x);
     return pown(inBase, inExponent);
 }
+
+half __attribute__((kernel)) testPownHalfIntHalf(half inBase, unsigned int x) {
+    int inExponent = rsGetElementAt_int(gAllocInExponent, x);
+    return pown(inBase, inExponent);
+}
+
+half2 __attribute__((kernel)) testPownHalf2Int2Half2(half2 inBase, unsigned int x) {
+    int2 inExponent = rsGetElementAt_int2(gAllocInExponent, x);
+    return pown(inBase, inExponent);
+}
+
+half3 __attribute__((kernel)) testPownHalf3Int3Half3(half3 inBase, unsigned int x) {
+    int3 inExponent = rsGetElementAt_int3(gAllocInExponent, x);
+    return pown(inBase, inExponent);
+}
+
+half4 __attribute__((kernel)) testPownHalf4Int4Half4(half4 inBase, unsigned int x) {
+    int4 inExponent = rsGetElementAt_int4(gAllocInExponent, x);
+    return pown(inBase, inExponent);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestPownRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestPownRelaxed.rs
index dada2ae..21607e8 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestPownRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestPownRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestPowr.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestPowr.java
index 710d89b..71b0500 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestPowr.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestPowr.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -82,7 +83,7 @@
                 args.inBase = arrayInBase[i];
                 args.inExponent = arrayInExponent[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computePowr(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -161,7 +162,7 @@
                 args.inBase = arrayInBase[i * 2 + j];
                 args.inExponent = arrayInExponent[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computePowr(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -240,7 +241,7 @@
                 args.inBase = arrayInBase[i * 4 + j];
                 args.inExponent = arrayInExponent[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computePowr(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -319,7 +320,7 @@
                 args.inBase = arrayInBase[i * 4 + j];
                 args.inExponent = arrayInExponent[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computePowr(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -358,10 +359,358 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalfHalf {
+        public short inBase;
+        public double inBaseDouble;
+        public short inExponent;
+        public double inExponentDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkPowrHalfHalfHalf() {
+        Allocation inBase = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x752063b9l, 0, 300);
+        Allocation inExponent = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x2c92528fl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.set_gAllocInExponent(inExponent);
+            script.forEach_testPowrHalfHalfHalf(inBase, out);
+            verifyResultsPowrHalfHalfHalf(inBase, inExponent, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPowrHalfHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInExponent(inExponent);
+            scriptRelaxed.forEach_testPowrHalfHalfHalf(inBase, out);
+            verifyResultsPowrHalfHalfHalf(inBase, inExponent, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPowrHalfHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsPowrHalfHalfHalf(Allocation inBase, Allocation inExponent, Allocation out, boolean relaxed) {
+        short[] arrayInBase = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInBase, (short) 42);
+        inBase.copyTo(arrayInBase);
+        short[] arrayInExponent = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInExponent, (short) 42);
+        inExponent.copyTo(arrayInExponent);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inBase = arrayInBase[i];
+                args.inBaseDouble = Float16Utils.convertFloat16ToDouble(args.inBase);
+                args.inExponent = arrayInExponent[i];
+                args.inExponentDouble = Float16Utils.convertFloat16ToDouble(args.inExponent);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computePowr(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inBase: ");
+                        appendVariableToMessage(message, args.inBase);
+                        message.append("\n");
+                        message.append("Input inExponent: ");
+                        appendVariableToMessage(message, args.inExponent);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkPowrHalfHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkPowrHalf2Half2Half2() {
+        Allocation inBase = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x68ccc053l, 0, 300);
+        Allocation inExponent = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xbd379d09l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.set_gAllocInExponent(inExponent);
+            script.forEach_testPowrHalf2Half2Half2(inBase, out);
+            verifyResultsPowrHalf2Half2Half2(inBase, inExponent, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPowrHalf2Half2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInExponent(inExponent);
+            scriptRelaxed.forEach_testPowrHalf2Half2Half2(inBase, out);
+            verifyResultsPowrHalf2Half2Half2(inBase, inExponent, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPowrHalf2Half2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsPowrHalf2Half2Half2(Allocation inBase, Allocation inExponent, Allocation out, boolean relaxed) {
+        short[] arrayInBase = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInBase, (short) 42);
+        inBase.copyTo(arrayInBase);
+        short[] arrayInExponent = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInExponent, (short) 42);
+        inExponent.copyTo(arrayInExponent);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inBase = arrayInBase[i * 2 + j];
+                args.inBaseDouble = Float16Utils.convertFloat16ToDouble(args.inBase);
+                args.inExponent = arrayInExponent[i * 2 + j];
+                args.inExponentDouble = Float16Utils.convertFloat16ToDouble(args.inExponent);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computePowr(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inBase: ");
+                        appendVariableToMessage(message, args.inBase);
+                        message.append("\n");
+                        message.append("Input inExponent: ");
+                        appendVariableToMessage(message, args.inExponent);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkPowrHalf2Half2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkPowrHalf3Half3Half3() {
+        Allocation inBase = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x5c7e1130l, 0, 300);
+        Allocation inExponent = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0xbef8c7d6l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.set_gAllocInExponent(inExponent);
+            script.forEach_testPowrHalf3Half3Half3(inBase, out);
+            verifyResultsPowrHalf3Half3Half3(inBase, inExponent, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPowrHalf3Half3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInExponent(inExponent);
+            scriptRelaxed.forEach_testPowrHalf3Half3Half3(inBase, out);
+            verifyResultsPowrHalf3Half3Half3(inBase, inExponent, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPowrHalf3Half3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsPowrHalf3Half3Half3(Allocation inBase, Allocation inExponent, Allocation out, boolean relaxed) {
+        short[] arrayInBase = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInBase, (short) 42);
+        inBase.copyTo(arrayInBase);
+        short[] arrayInExponent = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInExponent, (short) 42);
+        inExponent.copyTo(arrayInExponent);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inBase = arrayInBase[i * 4 + j];
+                args.inBaseDouble = Float16Utils.convertFloat16ToDouble(args.inBase);
+                args.inExponent = arrayInExponent[i * 4 + j];
+                args.inExponentDouble = Float16Utils.convertFloat16ToDouble(args.inExponent);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computePowr(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inBase: ");
+                        appendVariableToMessage(message, args.inBase);
+                        message.append("\n");
+                        message.append("Input inExponent: ");
+                        appendVariableToMessage(message, args.inExponent);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkPowrHalf3Half3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkPowrHalf4Half4Half4() {
+        Allocation inBase = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x502f620dl, 0, 300);
+        Allocation inExponent = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xc0b9f2a3l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.set_gAllocInExponent(inExponent);
+            script.forEach_testPowrHalf4Half4Half4(inBase, out);
+            verifyResultsPowrHalf4Half4Half4(inBase, inExponent, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPowrHalf4Half4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInExponent(inExponent);
+            scriptRelaxed.forEach_testPowrHalf4Half4Half4(inBase, out);
+            verifyResultsPowrHalf4Half4Half4(inBase, inExponent, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPowrHalf4Half4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsPowrHalf4Half4Half4(Allocation inBase, Allocation inExponent, Allocation out, boolean relaxed) {
+        short[] arrayInBase = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInBase, (short) 42);
+        inBase.copyTo(arrayInBase);
+        short[] arrayInExponent = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInExponent, (short) 42);
+        inExponent.copyTo(arrayInExponent);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inBase = arrayInBase[i * 4 + j];
+                args.inBaseDouble = Float16Utils.convertFloat16ToDouble(args.inBase);
+                args.inExponent = arrayInExponent[i * 4 + j];
+                args.inExponentDouble = Float16Utils.convertFloat16ToDouble(args.inExponent);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computePowr(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inBase: ");
+                        appendVariableToMessage(message, args.inBase);
+                        message.append("\n");
+                        message.append("Input inExponent: ");
+                        appendVariableToMessage(message, args.inExponent);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkPowrHalf4Half4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testPowr() {
         checkPowrFloatFloatFloat();
         checkPowrFloat2Float2Float2();
         checkPowrFloat3Float3Float3();
         checkPowrFloat4Float4Float4();
+        checkPowrHalfHalfHalf();
+        checkPowrHalf2Half2Half2();
+        checkPowrHalf3Half3Half3();
+        checkPowrHalf4Half4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestPowr.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestPowr.rs
index 66c0e5f..0fdf69d 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestPowr.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestPowr.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -40,3 +40,23 @@
     float4 inExponent = rsGetElementAt_float4(gAllocInExponent, x);
     return powr(inBase, inExponent);
 }
+
+half __attribute__((kernel)) testPowrHalfHalfHalf(half inBase, unsigned int x) {
+    half inExponent = rsGetElementAt_half(gAllocInExponent, x);
+    return powr(inBase, inExponent);
+}
+
+half2 __attribute__((kernel)) testPowrHalf2Half2Half2(half2 inBase, unsigned int x) {
+    half2 inExponent = rsGetElementAt_half2(gAllocInExponent, x);
+    return powr(inBase, inExponent);
+}
+
+half3 __attribute__((kernel)) testPowrHalf3Half3Half3(half3 inBase, unsigned int x) {
+    half3 inExponent = rsGetElementAt_half3(gAllocInExponent, x);
+    return powr(inBase, inExponent);
+}
+
+half4 __attribute__((kernel)) testPowrHalf4Half4Half4(half4 inBase, unsigned int x) {
+    half4 inExponent = rsGetElementAt_half4(gAllocInExponent, x);
+    return powr(inBase, inExponent);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestPowrRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestPowrRelaxed.rs
index a9c7247..9af7c33 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestPowrRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestPowrRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRadians.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRadians.java
index 3dbba71..7d7bf2f 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRadians.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRadians.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeRadians(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeRadians(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeRadians(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeRadians(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkRadiansHalfHalf() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x3875b1edl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testRadiansHalfHalf(inV, out);
+            verifyResultsRadiansHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRadiansHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testRadiansHalfHalf(inV, out);
+            verifyResultsRadiansHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRadiansHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRadiansHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeRadians(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkRadiansHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkRadiansHalf2Half2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x714926e7l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testRadiansHalf2Half2(inV, out);
+            verifyResultsRadiansHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRadiansHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testRadiansHalf2Half2(inV, out);
+            verifyResultsRadiansHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRadiansHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRadiansHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeRadians(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkRadiansHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkRadiansHalf3Half3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0xd050ebdbl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testRadiansHalf3Half3(inV, out);
+            verifyResultsRadiansHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRadiansHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testRadiansHalf3Half3(inV, out);
+            verifyResultsRadiansHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRadiansHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRadiansHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeRadians(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkRadiansHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkRadiansHalf4Half4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x2f58b0cfl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testRadiansHalf4Half4(inV, out);
+            verifyResultsRadiansHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRadiansHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testRadiansHalf4Half4(inV, out);
+            verifyResultsRadiansHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRadiansHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRadiansHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeRadians(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkRadiansHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testRadians() {
         checkRadiansFloatFloat();
         checkRadiansFloat2Float2();
         checkRadiansFloat3Float3();
         checkRadiansFloat4Float4();
+        checkRadiansHalfHalf();
+        checkRadiansHalf2Half2();
+        checkRadiansHalf3Half3();
+        checkRadiansHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRadians.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRadians.rs
index 27d178a..5ada9b9 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRadians.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRadians.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testRadiansFloat4Float4(float4 inV) {
     return radians(inV);
 }
+
+half __attribute__((kernel)) testRadiansHalfHalf(half inV) {
+    return radians(inV);
+}
+
+half2 __attribute__((kernel)) testRadiansHalf2Half2(half2 inV) {
+    return radians(inV);
+}
+
+half3 __attribute__((kernel)) testRadiansHalf3Half3(half3 inV) {
+    return radians(inV);
+}
+
+half4 __attribute__((kernel)) testRadiansHalf4Half4(half4 inV) {
+    return radians(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRadiansRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRadiansRelaxed.rs
index b8a2669..ae5a805 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRadiansRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRadiansRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRemainder.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRemainder.java
index 5bbcc3a..a8c3c07 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRemainder.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRemainder.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -82,7 +83,7 @@
                 args.inNumerator = arrayInNumerator[i];
                 args.inDenominator = arrayInDenominator[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeRemainder(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -161,7 +162,7 @@
                 args.inNumerator = arrayInNumerator[i * 2 + j];
                 args.inDenominator = arrayInDenominator[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeRemainder(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -240,7 +241,7 @@
                 args.inNumerator = arrayInNumerator[i * 4 + j];
                 args.inDenominator = arrayInDenominator[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeRemainder(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -319,7 +320,7 @@
                 args.inNumerator = arrayInNumerator[i * 4 + j];
                 args.inDenominator = arrayInDenominator[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeRemainder(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -358,10 +359,358 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalfHalf {
+        public short inNumerator;
+        public double inNumeratorDouble;
+        public short inDenominator;
+        public double inDenominatorDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkRemainderHalfHalfHalf() {
+        Allocation inNumerator = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xcd987ebel, false);
+        Allocation inDenominator = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x59b61387l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.set_gAllocInDenominator(inDenominator);
+            script.forEach_testRemainderHalfHalfHalf(inNumerator, out);
+            verifyResultsRemainderHalfHalfHalf(inNumerator, inDenominator, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRemainderHalfHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInDenominator(inDenominator);
+            scriptRelaxed.forEach_testRemainderHalfHalfHalf(inNumerator, out);
+            verifyResultsRemainderHalfHalfHalf(inNumerator, inDenominator, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRemainderHalfHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRemainderHalfHalfHalf(Allocation inNumerator, Allocation inDenominator, Allocation out, boolean relaxed) {
+        short[] arrayInNumerator = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInNumerator, (short) 42);
+        inNumerator.copyTo(arrayInNumerator);
+        short[] arrayInDenominator = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInDenominator, (short) 42);
+        inDenominator.copyTo(arrayInDenominator);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inNumerator = arrayInNumerator[i];
+                args.inNumeratorDouble = Float16Utils.convertFloat16ToDouble(args.inNumerator);
+                args.inDenominator = arrayInDenominator[i];
+                args.inDenominatorDouble = Float16Utils.convertFloat16ToDouble(args.inDenominator);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeRemainder(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inNumerator: ");
+                        appendVariableToMessage(message, args.inNumerator);
+                        message.append("\n");
+                        message.append("Input inDenominator: ");
+                        appendVariableToMessage(message, args.inDenominator);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkRemainderHalfHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkRemainderHalf2Half2Half2() {
+        Allocation inNumerator = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x3b2e47fel, false);
+        Allocation inDenominator = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xd890a2c7l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.set_gAllocInDenominator(inDenominator);
+            script.forEach_testRemainderHalf2Half2Half2(inNumerator, out);
+            verifyResultsRemainderHalf2Half2Half2(inNumerator, inDenominator, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRemainderHalf2Half2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInDenominator(inDenominator);
+            scriptRelaxed.forEach_testRemainderHalf2Half2Half2(inNumerator, out);
+            verifyResultsRemainderHalf2Half2Half2(inNumerator, inDenominator, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRemainderHalf2Half2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRemainderHalf2Half2Half2(Allocation inNumerator, Allocation inDenominator, Allocation out, boolean relaxed) {
+        short[] arrayInNumerator = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInNumerator, (short) 42);
+        inNumerator.copyTo(arrayInNumerator);
+        short[] arrayInDenominator = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInDenominator, (short) 42);
+        inDenominator.copyTo(arrayInDenominator);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inNumerator = arrayInNumerator[i * 2 + j];
+                args.inNumeratorDouble = Float16Utils.convertFloat16ToDouble(args.inNumerator);
+                args.inDenominator = arrayInDenominator[i * 2 + j];
+                args.inDenominatorDouble = Float16Utils.convertFloat16ToDouble(args.inDenominator);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeRemainder(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inNumerator: ");
+                        appendVariableToMessage(message, args.inNumerator);
+                        message.append("\n");
+                        message.append("Input inDenominator: ");
+                        appendVariableToMessage(message, args.inDenominator);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkRemainderHalf2Half2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkRemainderHalf3Half3Half3() {
+        Allocation inNumerator = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x86a0786dl, false);
+        Allocation inDenominator = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0xc450747el, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.set_gAllocInDenominator(inDenominator);
+            script.forEach_testRemainderHalf3Half3Half3(inNumerator, out);
+            verifyResultsRemainderHalf3Half3Half3(inNumerator, inDenominator, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRemainderHalf3Half3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInDenominator(inDenominator);
+            scriptRelaxed.forEach_testRemainderHalf3Half3Half3(inNumerator, out);
+            verifyResultsRemainderHalf3Half3Half3(inNumerator, inDenominator, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRemainderHalf3Half3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRemainderHalf3Half3Half3(Allocation inNumerator, Allocation inDenominator, Allocation out, boolean relaxed) {
+        short[] arrayInNumerator = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInNumerator, (short) 42);
+        inNumerator.copyTo(arrayInNumerator);
+        short[] arrayInDenominator = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInDenominator, (short) 42);
+        inDenominator.copyTo(arrayInDenominator);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inNumerator = arrayInNumerator[i * 4 + j];
+                args.inNumeratorDouble = Float16Utils.convertFloat16ToDouble(args.inNumerator);
+                args.inDenominator = arrayInDenominator[i * 4 + j];
+                args.inDenominatorDouble = Float16Utils.convertFloat16ToDouble(args.inDenominator);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeRemainder(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inNumerator: ");
+                        appendVariableToMessage(message, args.inNumerator);
+                        message.append("\n");
+                        message.append("Input inDenominator: ");
+                        appendVariableToMessage(message, args.inDenominator);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkRemainderHalf3Half3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkRemainderHalf4Half4Half4() {
+        Allocation inNumerator = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xd212a8dcl, false);
+        Allocation inDenominator = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xb0104635l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.set_gAllocInDenominator(inDenominator);
+            script.forEach_testRemainderHalf4Half4Half4(inNumerator, out);
+            verifyResultsRemainderHalf4Half4Half4(inNumerator, inDenominator, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRemainderHalf4Half4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInDenominator(inDenominator);
+            scriptRelaxed.forEach_testRemainderHalf4Half4Half4(inNumerator, out);
+            verifyResultsRemainderHalf4Half4Half4(inNumerator, inDenominator, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRemainderHalf4Half4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRemainderHalf4Half4Half4(Allocation inNumerator, Allocation inDenominator, Allocation out, boolean relaxed) {
+        short[] arrayInNumerator = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInNumerator, (short) 42);
+        inNumerator.copyTo(arrayInNumerator);
+        short[] arrayInDenominator = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInDenominator, (short) 42);
+        inDenominator.copyTo(arrayInDenominator);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inNumerator = arrayInNumerator[i * 4 + j];
+                args.inNumeratorDouble = Float16Utils.convertFloat16ToDouble(args.inNumerator);
+                args.inDenominator = arrayInDenominator[i * 4 + j];
+                args.inDenominatorDouble = Float16Utils.convertFloat16ToDouble(args.inDenominator);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeRemainder(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inNumerator: ");
+                        appendVariableToMessage(message, args.inNumerator);
+                        message.append("\n");
+                        message.append("Input inDenominator: ");
+                        appendVariableToMessage(message, args.inDenominator);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkRemainderHalf4Half4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testRemainder() {
         checkRemainderFloatFloatFloat();
         checkRemainderFloat2Float2Float2();
         checkRemainderFloat3Float3Float3();
         checkRemainderFloat4Float4Float4();
+        checkRemainderHalfHalfHalf();
+        checkRemainderHalf2Half2Half2();
+        checkRemainderHalf3Half3Half3();
+        checkRemainderHalf4Half4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRemainder.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRemainder.rs
index 38de51c..60590f6 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRemainder.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRemainder.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -40,3 +40,23 @@
     float4 inDenominator = rsGetElementAt_float4(gAllocInDenominator, x);
     return remainder(inNumerator, inDenominator);
 }
+
+half __attribute__((kernel)) testRemainderHalfHalfHalf(half inNumerator, unsigned int x) {
+    half inDenominator = rsGetElementAt_half(gAllocInDenominator, x);
+    return remainder(inNumerator, inDenominator);
+}
+
+half2 __attribute__((kernel)) testRemainderHalf2Half2Half2(half2 inNumerator, unsigned int x) {
+    half2 inDenominator = rsGetElementAt_half2(gAllocInDenominator, x);
+    return remainder(inNumerator, inDenominator);
+}
+
+half3 __attribute__((kernel)) testRemainderHalf3Half3Half3(half3 inNumerator, unsigned int x) {
+    half3 inDenominator = rsGetElementAt_half3(gAllocInDenominator, x);
+    return remainder(inNumerator, inDenominator);
+}
+
+half4 __attribute__((kernel)) testRemainderHalf4Half4Half4(half4 inNumerator, unsigned int x) {
+    half4 inDenominator = rsGetElementAt_half4(gAllocInDenominator, x);
+    return remainder(inNumerator, inDenominator);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRemainderRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRemainderRelaxed.rs
index 6a2e02f..f93e980 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRemainderRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRemainderRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRemquo.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRemquo.java
index d4868a6..2aafac6 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRemquo.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRemquo.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -93,7 +94,7 @@
                 args.outQuotient = arrayOutQuotient[i * 1 + j];
                 args.out = arrayOut[i * 1 + j];
                 // Ask the CoreMathVerifier to validate.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 String errorMessage = CoreMathVerifier.verifyRemquo(args, target);
                 boolean valid = errorMessage == null;
                 if (!valid) {
@@ -176,7 +177,7 @@
                 args.outQuotient = arrayOutQuotient[i * 2 + j];
                 args.out = arrayOut[i * 2 + j];
                 // Ask the CoreMathVerifier to validate.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 String errorMessage = CoreMathVerifier.verifyRemquo(args, target);
                 boolean valid = errorMessage == null;
                 if (!valid) {
@@ -259,7 +260,7 @@
                 args.outQuotient = arrayOutQuotient[i * 4 + j];
                 args.out = arrayOut[i * 4 + j];
                 // Ask the CoreMathVerifier to validate.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 String errorMessage = CoreMathVerifier.verifyRemquo(args, target);
                 boolean valid = errorMessage == null;
                 if (!valid) {
@@ -342,7 +343,7 @@
                 args.outQuotient = arrayOutQuotient[i * 4 + j];
                 args.out = arrayOut[i * 4 + j];
                 // Ask the CoreMathVerifier to validate.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 String errorMessage = CoreMathVerifier.verifyRemquo(args, target);
                 boolean valid = errorMessage == null;
                 if (!valid) {
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRemquo.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRemquo.rs
index 15f0034..8e75b4d 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRemquo.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRemquo.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRemquoRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRemquoRelaxed.rs
index 5d2a1a6..e9aa584 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRemquoRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRemquoRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRint.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRint.java
index 1c22e95..89dc0e8 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRint.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRint.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeRint(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeRint(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeRint(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeRint(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkRintHalfHalf() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xec6959del, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testRintHalfHalf(inV, out);
+            verifyResultsRintHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRintHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testRintHalfHalf(inV, out);
+            verifyResultsRintHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRintHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRintHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeRint(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkRintHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkRintHalf2Half2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x2c212290l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testRintHalf2Half2(inV, out);
+            verifyResultsRintHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRintHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testRintHalf2Half2(inV, out);
+            verifyResultsRintHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRintHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRintHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeRint(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkRintHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkRintHalf3Half3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x8b28e784l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testRintHalf3Half3(inV, out);
+            verifyResultsRintHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRintHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testRintHalf3Half3(inV, out);
+            verifyResultsRintHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRintHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRintHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeRint(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkRintHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkRintHalf4Half4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xea30ac78l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testRintHalf4Half4(inV, out);
+            verifyResultsRintHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRintHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testRintHalf4Half4(inV, out);
+            verifyResultsRintHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRintHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRintHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeRint(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkRintHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testRint() {
         checkRintFloatFloat();
         checkRintFloat2Float2();
         checkRintFloat3Float3();
         checkRintFloat4Float4();
+        checkRintHalfHalf();
+        checkRintHalf2Half2();
+        checkRintHalf3Half3();
+        checkRintHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRint.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRint.rs
index 4ac5eb4..3c0d0f1 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRint.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRint.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testRintFloat4Float4(float4 inV) {
     return rint(inV);
 }
+
+half __attribute__((kernel)) testRintHalfHalf(half inV) {
+    return rint(inV);
+}
+
+half2 __attribute__((kernel)) testRintHalf2Half2(half2 inV) {
+    return rint(inV);
+}
+
+half3 __attribute__((kernel)) testRintHalf3Half3(half3 inV) {
+    return rint(inV);
+}
+
+half4 __attribute__((kernel)) testRintHalf4Half4(half4 inV) {
+    return rint(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRintRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRintRelaxed.rs
index 703ca2e..bfacdea 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRintRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRintRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRootn.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRootn.java
index 5403dda..7bb77a5 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRootn.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRootn.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -82,7 +83,7 @@
                 args.inV = arrayInV[i];
                 args.inN = arrayInN[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeRootn(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -161,7 +162,7 @@
                 args.inV = arrayInV[i * 2 + j];
                 args.inN = arrayInN[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeRootn(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -240,7 +241,7 @@
                 args.inV = arrayInV[i * 4 + j];
                 args.inN = arrayInN[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeRootn(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -319,7 +320,7 @@
                 args.inV = arrayInV[i * 4 + j];
                 args.inN = arrayInN[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeRootn(args, target);
                 // Validate the outputs.
                 boolean valid = true;
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRootn.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRootn.rs
index 4e400be..d1ebb5d 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRootn.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRootn.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRootnRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRootnRelaxed.rs
index 57e29c4..9141954 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRootnRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRootnRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRound.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRound.java
index 3fde559..c13b7c0 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRound.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRound.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeRound(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeRound(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeRound(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeRound(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkRoundHalfHalf() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xe9b639c5l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testRoundHalfHalf(inV, out);
+            verifyResultsRoundHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRoundHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testRoundHalfHalf(inV, out);
+            verifyResultsRoundHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRoundHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRoundHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeRound(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkRoundHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkRoundHalf2Half2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xac5e4dffl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testRoundHalf2Half2(inV, out);
+            verifyResultsRoundHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRoundHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testRoundHalf2Half2(inV, out);
+            verifyResultsRoundHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRoundHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRoundHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeRound(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkRoundHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkRoundHalf3Half3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0xb6612f3l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testRoundHalf3Half3(inV, out);
+            verifyResultsRoundHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRoundHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testRoundHalf3Half3(inV, out);
+            verifyResultsRoundHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRoundHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRoundHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeRound(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkRoundHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkRoundHalf4Half4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x6a6dd7e7l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testRoundHalf4Half4(inV, out);
+            verifyResultsRoundHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRoundHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testRoundHalf4Half4(inV, out);
+            verifyResultsRoundHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRoundHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRoundHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeRound(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkRoundHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testRound() {
         checkRoundFloatFloat();
         checkRoundFloat2Float2();
         checkRoundFloat3Float3();
         checkRoundFloat4Float4();
+        checkRoundHalfHalf();
+        checkRoundHalf2Half2();
+        checkRoundHalf3Half3();
+        checkRoundHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRound.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRound.rs
index cf4b5e2..1966eaf 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRound.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRound.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testRoundFloat4Float4(float4 inV) {
     return round(inV);
 }
+
+half __attribute__((kernel)) testRoundHalfHalf(half inV) {
+    return round(inV);
+}
+
+half2 __attribute__((kernel)) testRoundHalf2Half2(half2 inV) {
+    return round(inV);
+}
+
+half3 __attribute__((kernel)) testRoundHalf3Half3(half3 inV) {
+    return round(inV);
+}
+
+half4 __attribute__((kernel)) testRoundHalf4Half4(half4 inV) {
+    return round(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRoundRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRoundRelaxed.rs
index bd9fdcd..dd53e55 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRoundRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRoundRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRsqrt.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRsqrt.java
index b4c3e23..118df96 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRsqrt.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRsqrt.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeRsqrt(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeRsqrt(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeRsqrt(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeRsqrt(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkRsqrtHalfHalf() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x8234e8f1l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testRsqrtHalfHalf(inV, out);
+            verifyResultsRsqrtHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRsqrtHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testRsqrtHalfHalf(inV, out);
+            verifyResultsRsqrtHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRsqrtHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRsqrtHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeRsqrt(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkRsqrtHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkRsqrtHalf2Half2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x175d82cbl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testRsqrtHalf2Half2(inV, out);
+            verifyResultsRsqrtHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRsqrtHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testRsqrtHalf2Half2(inV, out);
+            verifyResultsRsqrtHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRsqrtHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRsqrtHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeRsqrt(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkRsqrtHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkRsqrtHalf3Half3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x766547bfl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testRsqrtHalf3Half3(inV, out);
+            verifyResultsRsqrtHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRsqrtHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testRsqrtHalf3Half3(inV, out);
+            verifyResultsRsqrtHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRsqrtHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRsqrtHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeRsqrt(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkRsqrtHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkRsqrtHalf4Half4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xd56d0cb3l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testRsqrtHalf4Half4(inV, out);
+            verifyResultsRsqrtHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRsqrtHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testRsqrtHalf4Half4(inV, out);
+            verifyResultsRsqrtHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRsqrtHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRsqrtHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeRsqrt(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkRsqrtHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testRsqrt() {
         checkRsqrtFloatFloat();
         checkRsqrtFloat2Float2();
         checkRsqrtFloat3Float3();
         checkRsqrtFloat4Float4();
+        checkRsqrtHalfHalf();
+        checkRsqrtHalf2Half2();
+        checkRsqrtHalf3Half3();
+        checkRsqrtHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRsqrt.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRsqrt.rs
index 38e3d10..03ef4a1 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRsqrt.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRsqrt.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testRsqrtFloat4Float4(float4 inV) {
     return rsqrt(inV);
 }
+
+half __attribute__((kernel)) testRsqrtHalfHalf(half inV) {
+    return rsqrt(inV);
+}
+
+half2 __attribute__((kernel)) testRsqrtHalf2Half2(half2 inV) {
+    return rsqrt(inV);
+}
+
+half3 __attribute__((kernel)) testRsqrtHalf3Half3(half3 inV) {
+    return rsqrt(inV);
+}
+
+half4 __attribute__((kernel)) testRsqrtHalf4Half4(half4 inV) {
+    return rsqrt(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRsqrtRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRsqrtRelaxed.rs
index 5f52101..4e5c063 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRsqrtRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRsqrtRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSign.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSign.java
index d3f12fe..ae4ce6a 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSign.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSign.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeSign(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeSign(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeSign(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeSign(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkSignHalfHalf() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xf1994bfel, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testSignHalfHalf(inV, out);
+            verifyResultsSignHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSignHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testSignHalfHalf(inV, out);
+            verifyResultsSignHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSignHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSignHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeSign(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkSignHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkSignHalf2Half2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xa36cebb0l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testSignHalf2Half2(inV, out);
+            verifyResultsSignHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSignHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testSignHalf2Half2(inV, out);
+            verifyResultsSignHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSignHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSignHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeSign(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkSignHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkSignHalf3Half3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x274b0a4l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testSignHalf3Half3(inV, out);
+            verifyResultsSignHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSignHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testSignHalf3Half3(inV, out);
+            verifyResultsSignHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSignHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSignHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeSign(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkSignHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkSignHalf4Half4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x617c7598l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testSignHalf4Half4(inV, out);
+            verifyResultsSignHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSignHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testSignHalf4Half4(inV, out);
+            verifyResultsSignHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSignHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSignHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeSign(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkSignHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testSign() {
         checkSignFloatFloat();
         checkSignFloat2Float2();
         checkSignFloat3Float3();
         checkSignFloat4Float4();
+        checkSignHalfHalf();
+        checkSignHalf2Half2();
+        checkSignHalf3Half3();
+        checkSignHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSign.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSign.rs
index 32be4d9..3f2ef9b 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSign.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSign.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testSignFloat4Float4(float4 inV) {
     return sign(inV);
 }
+
+half __attribute__((kernel)) testSignHalfHalf(half inV) {
+    return sign(inV);
+}
+
+half2 __attribute__((kernel)) testSignHalf2Half2(half2 inV) {
+    return sign(inV);
+}
+
+half3 __attribute__((kernel)) testSignHalf3Half3(half3 inV) {
+    return sign(inV);
+}
+
+half4 __attribute__((kernel)) testSignHalf4Half4(half4 inV) {
+    return sign(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSignRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSignRelaxed.rs
index 6e27906..da1b77d 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSignRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSignRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSin.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSin.java
index 6acf220..e11ba7a 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSin.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSin.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeSin(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeSin(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeSin(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeSin(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkSinHalfHalf() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x591ded5bl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testSinHalfHalf(inV, out);
+            verifyResultsSinHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testSinHalfHalf(inV, out);
+            verifyResultsSinHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSinHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeSin(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkSinHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkSinHalf2Half2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x505e6465l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testSinHalf2Half2(inV, out);
+            verifyResultsSinHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testSinHalf2Half2(inV, out);
+            verifyResultsSinHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSinHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeSin(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkSinHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkSinHalf3Half3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0xaf662959l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testSinHalf3Half3(inV, out);
+            verifyResultsSinHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testSinHalf3Half3(inV, out);
+            verifyResultsSinHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSinHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeSin(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkSinHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkSinHalf4Half4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xe6dee4dl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testSinHalf4Half4(inV, out);
+            verifyResultsSinHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testSinHalf4Half4(inV, out);
+            verifyResultsSinHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSinHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeSin(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkSinHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testSin() {
         checkSinFloatFloat();
         checkSinFloat2Float2();
         checkSinFloat3Float3();
         checkSinFloat4Float4();
+        checkSinHalfHalf();
+        checkSinHalf2Half2();
+        checkSinHalf3Half3();
+        checkSinHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSin.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSin.rs
index b44653e..4692ec1 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSin.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSin.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testSinFloat4Float4(float4 inV) {
     return sin(inV);
 }
+
+half __attribute__((kernel)) testSinHalfHalf(half inV) {
+    return sin(inV);
+}
+
+half2 __attribute__((kernel)) testSinHalf2Half2(half2 inV) {
+    return sin(inV);
+}
+
+half3 __attribute__((kernel)) testSinHalf3Half3(half3 inV) {
+    return sin(inV);
+}
+
+half4 __attribute__((kernel)) testSinHalf4Half4(half4 inV) {
+    return sin(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSinRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSinRelaxed.rs
index dc906a3..c8ae2c2 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSinRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSinRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSincos.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSincos.java
index 64d71d4..f2e2e16 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSincos.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSincos.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -82,7 +83,7 @@
                 ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeSincos(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -170,7 +171,7 @@
                 ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeSincos(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -258,7 +259,7 @@
                 ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeSincos(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -346,7 +347,7 @@
                 ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeSincos(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -394,10 +395,401 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty outCos;
+        public Target.Floaty out;
+    }
+
+    private void checkSincosHalfHalfHalf() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x9ffeac75l, false);
+        try {
+            Allocation outCos = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.set_gAllocOutCos(outCos);
+            script.forEach_testSincosHalfHalfHalf(inV, out);
+            verifyResultsSincosHalfHalfHalf(inV, outCos, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSincosHalfHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation outCos = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocOutCos(outCos);
+            scriptRelaxed.forEach_testSincosHalfHalfHalf(inV, out);
+            verifyResultsSincosHalfHalfHalf(inV, outCos, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSincosHalfHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSincosHalfHalfHalf(Allocation inV, Allocation outCos, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOutCos = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOutCos, (short) 42);
+        outCos.copyTo(arrayOutCos);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeSincos(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.outCos.couldBe(Float16Utils.convertFloat16ToDouble(arrayOutCos[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output outCos: ");
+                        appendVariableToMessage(message, args.outCos);
+                        message.append("\n");
+                        message.append("Actual   output outCos: ");
+                        appendVariableToMessage(message, arrayOutCos[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output outCos (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOutCos[i * 1 + j]));
+                        if (!args.outCos.couldBe(Float16Utils.convertFloat16ToDouble(arrayOutCos[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkSincosHalfHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkSincosHalf2Half2Half2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x1b528cc9l, false);
+        try {
+            Allocation outCos = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.set_gAllocOutCos(outCos);
+            script.forEach_testSincosHalf2Half2Half2(inV, out);
+            verifyResultsSincosHalf2Half2Half2(inV, outCos, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSincosHalf2Half2Half2: " + e.toString());
+        }
+        try {
+            Allocation outCos = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocOutCos(outCos);
+            scriptRelaxed.forEach_testSincosHalf2Half2Half2(inV, out);
+            verifyResultsSincosHalf2Half2Half2(inV, outCos, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSincosHalf2Half2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSincosHalf2Half2Half2(Allocation inV, Allocation outCos, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOutCos = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOutCos, (short) 42);
+        outCos.copyTo(arrayOutCos);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeSincos(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.outCos.couldBe(Float16Utils.convertFloat16ToDouble(arrayOutCos[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output outCos: ");
+                        appendVariableToMessage(message, args.outCos);
+                        message.append("\n");
+                        message.append("Actual   output outCos: ");
+                        appendVariableToMessage(message, arrayOutCos[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output outCos (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOutCos[i * 2 + j]));
+                        if (!args.outCos.couldBe(Float16Utils.convertFloat16ToDouble(arrayOutCos[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkSincosHalf2Half2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkSincosHalf3Half3Half3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x79f19d98l, false);
+        try {
+            Allocation outCos = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.set_gAllocOutCos(outCos);
+            script.forEach_testSincosHalf3Half3Half3(inV, out);
+            verifyResultsSincosHalf3Half3Half3(inV, outCos, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSincosHalf3Half3Half3: " + e.toString());
+        }
+        try {
+            Allocation outCos = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocOutCos(outCos);
+            scriptRelaxed.forEach_testSincosHalf3Half3Half3(inV, out);
+            verifyResultsSincosHalf3Half3Half3(inV, outCos, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSincosHalf3Half3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSincosHalf3Half3Half3(Allocation inV, Allocation outCos, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOutCos = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOutCos, (short) 42);
+        outCos.copyTo(arrayOutCos);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeSincos(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.outCos.couldBe(Float16Utils.convertFloat16ToDouble(arrayOutCos[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output outCos: ");
+                        appendVariableToMessage(message, args.outCos);
+                        message.append("\n");
+                        message.append("Actual   output outCos: ");
+                        appendVariableToMessage(message, arrayOutCos[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output outCos (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOutCos[i * 4 + j]));
+                        if (!args.outCos.couldBe(Float16Utils.convertFloat16ToDouble(arrayOutCos[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkSincosHalf3Half3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkSincosHalf4Half4Half4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xd890ae67l, false);
+        try {
+            Allocation outCos = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.set_gAllocOutCos(outCos);
+            script.forEach_testSincosHalf4Half4Half4(inV, out);
+            verifyResultsSincosHalf4Half4Half4(inV, outCos, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSincosHalf4Half4Half4: " + e.toString());
+        }
+        try {
+            Allocation outCos = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocOutCos(outCos);
+            scriptRelaxed.forEach_testSincosHalf4Half4Half4(inV, out);
+            verifyResultsSincosHalf4Half4Half4(inV, outCos, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSincosHalf4Half4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSincosHalf4Half4Half4(Allocation inV, Allocation outCos, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOutCos = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOutCos, (short) 42);
+        outCos.copyTo(arrayOutCos);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeSincos(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.outCos.couldBe(Float16Utils.convertFloat16ToDouble(arrayOutCos[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output outCos: ");
+                        appendVariableToMessage(message, args.outCos);
+                        message.append("\n");
+                        message.append("Actual   output outCos: ");
+                        appendVariableToMessage(message, arrayOutCos[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output outCos (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOutCos[i * 4 + j]));
+                        if (!args.outCos.couldBe(Float16Utils.convertFloat16ToDouble(arrayOutCos[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkSincosHalf4Half4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testSincos() {
         checkSincosFloatFloatFloat();
         checkSincosFloat2Float2Float2();
         checkSincosFloat3Float3Float3();
         checkSincosFloat4Float4Float4();
+        checkSincosHalfHalfHalf();
+        checkSincosHalf2Half2Half2();
+        checkSincosHalf3Half3Half3();
+        checkSincosHalf4Half4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSincos.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSincos.rs
index aca40af..d7b1c67 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSincos.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSincos.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -48,3 +48,31 @@
     rsSetElementAt_float4(gAllocOutCos, outCos, x);
     return out;
 }
+
+half __attribute__((kernel)) testSincosHalfHalfHalf(half inV, unsigned int x) {
+    half outCos = 0;
+    half out = sincos(inV, &outCos);
+    rsSetElementAt_half(gAllocOutCos, outCos, x);
+    return out;
+}
+
+half2 __attribute__((kernel)) testSincosHalf2Half2Half2(half2 inV, unsigned int x) {
+    half2 outCos = 0;
+    half2 out = sincos(inV, &outCos);
+    rsSetElementAt_half2(gAllocOutCos, outCos, x);
+    return out;
+}
+
+half3 __attribute__((kernel)) testSincosHalf3Half3Half3(half3 inV, unsigned int x) {
+    half3 outCos = 0;
+    half3 out = sincos(inV, &outCos);
+    rsSetElementAt_half3(gAllocOutCos, outCos, x);
+    return out;
+}
+
+half4 __attribute__((kernel)) testSincosHalf4Half4Half4(half4 inV, unsigned int x) {
+    half4 outCos = 0;
+    half4 out = sincos(inV, &outCos);
+    rsSetElementAt_half4(gAllocOutCos, outCos, x);
+    return out;
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSincosRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSincosRelaxed.rs
index c82d495..8a90dea 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSincosRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSincosRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSinh.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSinh.java
index 20148d4..82105e1 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSinh.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSinh.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeSinh(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeSinh(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeSinh(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeSinh(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkSinhHalfHalf() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xccb47b43l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testSinhHalfHalf(inV, out);
+            verifyResultsSinhHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinhHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testSinhHalfHalf(inV, out);
+            verifyResultsSinhHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinhHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSinhHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeSinh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkSinhHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkSinhHalf2Half2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x2ac5550dl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testSinhHalf2Half2(inV, out);
+            verifyResultsSinhHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinhHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testSinhHalf2Half2(inV, out);
+            verifyResultsSinhHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinhHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSinhHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeSinh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkSinhHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkSinhHalf3Half3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x89cd1a01l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testSinhHalf3Half3(inV, out);
+            verifyResultsSinhHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinhHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testSinhHalf3Half3(inV, out);
+            verifyResultsSinhHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinhHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSinhHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeSinh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkSinhHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkSinhHalf4Half4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xe8d4def5l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testSinhHalf4Half4(inV, out);
+            verifyResultsSinhHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinhHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testSinhHalf4Half4(inV, out);
+            verifyResultsSinhHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinhHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSinhHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeSinh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkSinhHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testSinh() {
         checkSinhFloatFloat();
         checkSinhFloat2Float2();
         checkSinhFloat3Float3();
         checkSinhFloat4Float4();
+        checkSinhHalfHalf();
+        checkSinhHalf2Half2();
+        checkSinhHalf3Half3();
+        checkSinhHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSinh.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSinh.rs
index e677db7..f3201f2 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSinh.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSinh.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testSinhFloat4Float4(float4 inV) {
     return sinh(inV);
 }
+
+half __attribute__((kernel)) testSinhHalfHalf(half inV) {
+    return sinh(inV);
+}
+
+half2 __attribute__((kernel)) testSinhHalf2Half2(half2 inV) {
+    return sinh(inV);
+}
+
+half3 __attribute__((kernel)) testSinhHalf3Half3(half3 inV) {
+    return sinh(inV);
+}
+
+half4 __attribute__((kernel)) testSinhHalf4Half4(half4 inV) {
+    return sinh(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSinhRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSinhRelaxed.rs
index e85464e..e85bda0 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSinhRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSinhRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSinpi.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSinpi.java
index 61c1d24..2de4c4c 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSinpi.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSinpi.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeSinpi(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeSinpi(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeSinpi(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeSinpi(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkSinpiHalfHalf() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x4cee6176l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testSinpiHalfHalf(inV, out);
+            verifyResultsSinpiHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinpiHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testSinpiHalfHalf(inV, out);
+            verifyResultsSinpiHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinpiHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSinpiHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeSinpi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkSinpiHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkSinpiHalf2Half2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x4cf4fb68l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testSinpiHalf2Half2(inV, out);
+            verifyResultsSinpiHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinpiHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testSinpiHalf2Half2(inV, out);
+            verifyResultsSinpiHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinpiHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSinpiHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeSinpi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkSinpiHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkSinpiHalf3Half3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0xabfcc05cl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testSinpiHalf3Half3(inV, out);
+            verifyResultsSinpiHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinpiHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testSinpiHalf3Half3(inV, out);
+            verifyResultsSinpiHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinpiHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSinpiHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeSinpi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkSinpiHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkSinpiHalf4Half4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xb048550l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testSinpiHalf4Half4(inV, out);
+            verifyResultsSinpiHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinpiHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testSinpiHalf4Half4(inV, out);
+            verifyResultsSinpiHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinpiHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSinpiHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeSinpi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkSinpiHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testSinpi() {
         checkSinpiFloatFloat();
         checkSinpiFloat2Float2();
         checkSinpiFloat3Float3();
         checkSinpiFloat4Float4();
+        checkSinpiHalfHalf();
+        checkSinpiHalf2Half2();
+        checkSinpiHalf3Half3();
+        checkSinpiHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSinpi.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSinpi.rs
index f88d225..e391d41 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSinpi.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSinpi.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testSinpiFloat4Float4(float4 inV) {
     return sinpi(inV);
 }
+
+half __attribute__((kernel)) testSinpiHalfHalf(half inV) {
+    return sinpi(inV);
+}
+
+half2 __attribute__((kernel)) testSinpiHalf2Half2(half2 inV) {
+    return sinpi(inV);
+}
+
+half3 __attribute__((kernel)) testSinpiHalf3Half3(half3 inV) {
+    return sinpi(inV);
+}
+
+half4 __attribute__((kernel)) testSinpiHalf4Half4(half4 inV) {
+    return sinpi(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSinpiRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSinpiRelaxed.rs
index 3cfd204..11b6f58 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSinpiRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSinpiRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSqrt.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSqrt.java
index cbb092d..c7736c5 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSqrt.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSqrt.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeSqrt(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeSqrt(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeSqrt(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeSqrt(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkSqrtHalfHalf() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xa1eee2c3l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testSqrtHalfHalf(inV, out);
+            verifyResultsSqrtHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSqrtHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testSqrtHalfHalf(inV, out);
+            verifyResultsSqrtHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSqrtHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSqrtHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeSqrt(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkSqrtHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkSqrtHalf2Half2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x3d9ae08dl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testSqrtHalf2Half2(inV, out);
+            verifyResultsSqrtHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSqrtHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testSqrtHalf2Half2(inV, out);
+            verifyResultsSqrtHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSqrtHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSqrtHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeSqrt(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkSqrtHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkSqrtHalf3Half3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x9ca2a581l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testSqrtHalf3Half3(inV, out);
+            verifyResultsSqrtHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSqrtHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testSqrtHalf3Half3(inV, out);
+            verifyResultsSqrtHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSqrtHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSqrtHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeSqrt(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkSqrtHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkSqrtHalf4Half4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xfbaa6a75l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testSqrtHalf4Half4(inV, out);
+            verifyResultsSqrtHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSqrtHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testSqrtHalf4Half4(inV, out);
+            verifyResultsSqrtHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSqrtHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSqrtHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeSqrt(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkSqrtHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testSqrt() {
         checkSqrtFloatFloat();
         checkSqrtFloat2Float2();
         checkSqrtFloat3Float3();
         checkSqrtFloat4Float4();
+        checkSqrtHalfHalf();
+        checkSqrtHalf2Half2();
+        checkSqrtHalf3Half3();
+        checkSqrtHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSqrt.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSqrt.rs
index ae1e96e..84e59cb 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSqrt.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSqrt.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testSqrtFloat4Float4(float4 inV) {
     return sqrt(inV);
 }
+
+half __attribute__((kernel)) testSqrtHalfHalf(half inV) {
+    return sqrt(inV);
+}
+
+half2 __attribute__((kernel)) testSqrtHalf2Half2(half2 inV) {
+    return sqrt(inV);
+}
+
+half3 __attribute__((kernel)) testSqrtHalf3Half3(half3 inV) {
+    return sqrt(inV);
+}
+
+half4 __attribute__((kernel)) testSqrtHalf4Half4(half4 inV) {
+    return sqrt(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSqrtRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSqrtRelaxed.rs
index 019ca76..63ac6d3 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSqrtRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSqrtRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestStep.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestStep.java
index 097a093..55d6bbb 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestStep.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestStep.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -82,7 +83,7 @@
                 args.inEdge = arrayInEdge[i];
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeStep(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -161,7 +162,7 @@
                 args.inEdge = arrayInEdge[i * 2 + j];
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeStep(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -240,7 +241,7 @@
                 args.inEdge = arrayInEdge[i * 4 + j];
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeStep(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -319,7 +320,7 @@
                 args.inEdge = arrayInEdge[i * 4 + j];
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeStep(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -358,6 +359,350 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalfHalf {
+        public short inEdge;
+        public double inEdgeDouble;
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkStepHalfHalfHalf() {
+        Allocation inEdge = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xe2c3f577l, false);
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x3240702cl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.set_gAllocInV(inV);
+            script.forEach_testStepHalfHalfHalf(inEdge, out);
+            verifyResultsStepHalfHalfHalf(inEdge, inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepHalfHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV(inV);
+            scriptRelaxed.forEach_testStepHalfHalfHalf(inEdge, out);
+            verifyResultsStepHalfHalfHalf(inEdge, inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepHalfHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsStepHalfHalfHalf(Allocation inEdge, Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInEdge = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInEdge, (short) 42);
+        inEdge.copyTo(arrayInEdge);
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inEdge = arrayInEdge[i];
+                args.inEdgeDouble = Float16Utils.convertFloat16ToDouble(args.inEdge);
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeStep(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inEdge: ");
+                        appendVariableToMessage(message, args.inEdge);
+                        message.append("\n");
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkStepHalfHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkStepHalf2Half2Half2() {
+        Allocation inEdge = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xee08afadl, false);
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xba1588del, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.set_gAllocInV(inV);
+            script.forEach_testStepHalf2Half2Half2(inEdge, out);
+            verifyResultsStepHalf2Half2Half2(inEdge, inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepHalf2Half2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV(inV);
+            scriptRelaxed.forEach_testStepHalf2Half2Half2(inEdge, out);
+            verifyResultsStepHalf2Half2Half2(inEdge, inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepHalf2Half2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsStepHalf2Half2Half2(Allocation inEdge, Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInEdge = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInEdge, (short) 42);
+        inEdge.copyTo(arrayInEdge);
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inEdge = arrayInEdge[i * 2 + j];
+                args.inEdgeDouble = Float16Utils.convertFloat16ToDouble(args.inEdge);
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeStep(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inEdge: ");
+                        appendVariableToMessage(message, args.inEdge);
+                        message.append("\n");
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkStepHalf2Half2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkStepHalf3Half3Half3() {
+        Allocation inEdge = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0xe1ba008al, false);
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x18b499adl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.set_gAllocInV(inV);
+            script.forEach_testStepHalf3Half3Half3(inEdge, out);
+            verifyResultsStepHalf3Half3Half3(inEdge, inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepHalf3Half3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV(inV);
+            scriptRelaxed.forEach_testStepHalf3Half3Half3(inEdge, out);
+            verifyResultsStepHalf3Half3Half3(inEdge, inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepHalf3Half3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsStepHalf3Half3Half3(Allocation inEdge, Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInEdge = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInEdge, (short) 42);
+        inEdge.copyTo(arrayInEdge);
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inEdge = arrayInEdge[i * 4 + j];
+                args.inEdgeDouble = Float16Utils.convertFloat16ToDouble(args.inEdge);
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeStep(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inEdge: ");
+                        appendVariableToMessage(message, args.inEdge);
+                        message.append("\n");
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkStepHalf3Half3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkStepHalf4Half4Half4() {
+        Allocation inEdge = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xd56b5167l, false);
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x7753aa7cl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.set_gAllocInV(inV);
+            script.forEach_testStepHalf4Half4Half4(inEdge, out);
+            verifyResultsStepHalf4Half4Half4(inEdge, inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepHalf4Half4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV(inV);
+            scriptRelaxed.forEach_testStepHalf4Half4Half4(inEdge, out);
+            verifyResultsStepHalf4Half4Half4(inEdge, inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepHalf4Half4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsStepHalf4Half4Half4(Allocation inEdge, Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInEdge = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInEdge, (short) 42);
+        inEdge.copyTo(arrayInEdge);
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inEdge = arrayInEdge[i * 4 + j];
+                args.inEdgeDouble = Float16Utils.convertFloat16ToDouble(args.inEdge);
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeStep(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inEdge: ");
+                        appendVariableToMessage(message, args.inEdge);
+                        message.append("\n");
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkStepHalf4Half4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     private void checkStepFloat2FloatFloat2() {
         Allocation inEdge = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x5b3d8b26l, false);
         Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xb6d48a21l, false);
@@ -398,7 +743,7 @@
                 args.inEdge = arrayInEdge[i * 2 + j];
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeStep(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -477,7 +822,7 @@
                 args.inEdge = arrayInEdge[i * 4 + j];
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeStep(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -556,7 +901,7 @@
                 args.inEdge = arrayInEdge[i * 4 + j];
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeStep(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -595,6 +940,258 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    private void checkStepHalf2HalfHalf2() {
+        Allocation inEdge = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x2f4438d3l, false);
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x2d7ce0l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.set_gAllocInV(inV);
+            script.forEach_testStepHalf2HalfHalf2(inEdge, out);
+            verifyResultsStepHalf2HalfHalf2(inEdge, inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepHalf2HalfHalf2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV(inV);
+            scriptRelaxed.forEach_testStepHalf2HalfHalf2(inEdge, out);
+            verifyResultsStepHalf2HalfHalf2(inEdge, inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepHalf2HalfHalf2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsStepHalf2HalfHalf2(Allocation inEdge, Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInEdge = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInEdge, (short) 42);
+        inEdge.copyTo(arrayInEdge);
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inEdge = arrayInEdge[i * 2 + j];
+                args.inEdgeDouble = Float16Utils.convertFloat16ToDouble(args.inEdge);
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeStep(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inEdge: ");
+                        appendVariableToMessage(message, args.inEdge);
+                        message.append("\n");
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkStepHalf2HalfHalf2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkStepHalf3HalfHalf3() {
+        Allocation inEdge = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0xb3cf71ffl, false);
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xb2c70e84l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.set_gAllocInV(inV);
+            script.forEach_testStepHalf3HalfHalf3(inEdge, out);
+            verifyResultsStepHalf3HalfHalf3(inEdge, inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepHalf3HalfHalf3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV(inV);
+            scriptRelaxed.forEach_testStepHalf3HalfHalf3(inEdge, out);
+            verifyResultsStepHalf3HalfHalf3(inEdge, inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepHalf3HalfHalf3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsStepHalf3HalfHalf3(Allocation inEdge, Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInEdge = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInEdge, (short) 42);
+        inEdge.copyTo(arrayInEdge);
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inEdge = arrayInEdge[i * 4 + j];
+                args.inEdgeDouble = Float16Utils.convertFloat16ToDouble(args.inEdge);
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeStep(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inEdge: ");
+                        appendVariableToMessage(message, args.inEdge);
+                        message.append("\n");
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkStepHalf3HalfHalf3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkStepHalf4HalfHalf4() {
+        Allocation inEdge = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x385aab2bl, false);
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x6560a028l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.set_gAllocInV(inV);
+            script.forEach_testStepHalf4HalfHalf4(inEdge, out);
+            verifyResultsStepHalf4HalfHalf4(inEdge, inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepHalf4HalfHalf4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV(inV);
+            scriptRelaxed.forEach_testStepHalf4HalfHalf4(inEdge, out);
+            verifyResultsStepHalf4HalfHalf4(inEdge, inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepHalf4HalfHalf4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsStepHalf4HalfHalf4(Allocation inEdge, Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInEdge = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInEdge, (short) 42);
+        inEdge.copyTo(arrayInEdge);
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inEdge = arrayInEdge[i * 4 + j];
+                args.inEdgeDouble = Float16Utils.convertFloat16ToDouble(args.inEdge);
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeStep(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inEdge: ");
+                        appendVariableToMessage(message, args.inEdge);
+                        message.append("\n");
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkStepHalf4HalfHalf4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     private void checkStepFloatFloat2Float2() {
         Allocation inEdge = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x664b1852l, false);
         Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x44e2f7c5l, false);
@@ -635,7 +1232,7 @@
                 args.inEdge = arrayInEdge[i];
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeStep(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -714,7 +1311,7 @@
                 args.inEdge = arrayInEdge[i];
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeStep(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -793,7 +1390,7 @@
                 args.inEdge = arrayInEdge[i];
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeStep(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -832,16 +1429,278 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    private void checkStepHalfHalf2Half2() {
+        Allocation inEdge = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x915e1ddl, false);
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x9aa13beel, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.set_gAllocInV(inV);
+            script.forEach_testStepHalfHalf2Half2(inEdge, out);
+            verifyResultsStepHalfHalf2Half2(inEdge, inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepHalfHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV(inV);
+            scriptRelaxed.forEach_testStepHalfHalf2Half2(inEdge, out);
+            verifyResultsStepHalfHalf2Half2(inEdge, inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepHalfHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsStepHalfHalf2Half2(Allocation inEdge, Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInEdge = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInEdge, (short) 42);
+        inEdge.copyTo(arrayInEdge);
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inEdge = arrayInEdge[i];
+                args.inEdgeDouble = Float16Utils.convertFloat16ToDouble(args.inEdge);
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeStep(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inEdge: ");
+                        appendVariableToMessage(message, args.inEdge);
+                        message.append("\n");
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkStepHalfHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkStepHalfHalf3Half3() {
+        Allocation inEdge = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x30b71f9l, false);
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0xf9a900e2l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.set_gAllocInV(inV);
+            script.forEach_testStepHalfHalf3Half3(inEdge, out);
+            verifyResultsStepHalfHalf3Half3(inEdge, inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepHalfHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV(inV);
+            scriptRelaxed.forEach_testStepHalfHalf3Half3(inEdge, out);
+            verifyResultsStepHalfHalf3Half3(inEdge, inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepHalfHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsStepHalfHalf3Half3(Allocation inEdge, Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInEdge = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInEdge, (short) 42);
+        inEdge.copyTo(arrayInEdge);
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inEdge = arrayInEdge[i];
+                args.inEdgeDouble = Float16Utils.convertFloat16ToDouble(args.inEdge);
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeStep(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inEdge: ");
+                        appendVariableToMessage(message, args.inEdge);
+                        message.append("\n");
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkStepHalfHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkStepHalfHalf4Half4() {
+        Allocation inEdge = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xfd010215l, false);
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x58b0c5d6l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.set_gAllocInV(inV);
+            script.forEach_testStepHalfHalf4Half4(inEdge, out);
+            verifyResultsStepHalfHalf4Half4(inEdge, inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepHalfHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV(inV);
+            scriptRelaxed.forEach_testStepHalfHalf4Half4(inEdge, out);
+            verifyResultsStepHalfHalf4Half4(inEdge, inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepHalfHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsStepHalfHalf4Half4(Allocation inEdge, Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInEdge = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInEdge, (short) 42);
+        inEdge.copyTo(arrayInEdge);
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalfHalf args = new ArgumentsHalfHalfHalf();
+                args.inEdge = arrayInEdge[i];
+                args.inEdgeDouble = Float16Utils.convertFloat16ToDouble(args.inEdge);
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeStep(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inEdge: ");
+                        appendVariableToMessage(message, args.inEdge);
+                        message.append("\n");
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkStepHalfHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testStep() {
         checkStepFloatFloatFloat();
         checkStepFloat2Float2Float2();
         checkStepFloat3Float3Float3();
         checkStepFloat4Float4Float4();
+        checkStepHalfHalfHalf();
+        checkStepHalf2Half2Half2();
+        checkStepHalf3Half3Half3();
+        checkStepHalf4Half4Half4();
         checkStepFloat2FloatFloat2();
         checkStepFloat3FloatFloat3();
         checkStepFloat4FloatFloat4();
+        checkStepHalf2HalfHalf2();
+        checkStepHalf3HalfHalf3();
+        checkStepHalf4HalfHalf4();
         checkStepFloatFloat2Float2();
         checkStepFloatFloat3Float3();
         checkStepFloatFloat4Float4();
+        checkStepHalfHalf2Half2();
+        checkStepHalfHalf3Half3();
+        checkStepHalfHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestStep.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestStep.rs
index 4af9b23..92b874c 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestStep.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestStep.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -41,6 +41,26 @@
     return step(inEdge, inV);
 }
 
+half __attribute__((kernel)) testStepHalfHalfHalf(half inEdge, unsigned int x) {
+    half inV = rsGetElementAt_half(gAllocInV, x);
+    return step(inEdge, inV);
+}
+
+half2 __attribute__((kernel)) testStepHalf2Half2Half2(half2 inEdge, unsigned int x) {
+    half2 inV = rsGetElementAt_half2(gAllocInV, x);
+    return step(inEdge, inV);
+}
+
+half3 __attribute__((kernel)) testStepHalf3Half3Half3(half3 inEdge, unsigned int x) {
+    half3 inV = rsGetElementAt_half3(gAllocInV, x);
+    return step(inEdge, inV);
+}
+
+half4 __attribute__((kernel)) testStepHalf4Half4Half4(half4 inEdge, unsigned int x) {
+    half4 inV = rsGetElementAt_half4(gAllocInV, x);
+    return step(inEdge, inV);
+}
+
 float2 __attribute__((kernel)) testStepFloat2FloatFloat2(float2 inEdge, unsigned int x) {
     float inV = rsGetElementAt_float(gAllocInV, x);
     return step(inEdge, inV);
@@ -56,6 +76,21 @@
     return step(inEdge, inV);
 }
 
+half2 __attribute__((kernel)) testStepHalf2HalfHalf2(half2 inEdge, unsigned int x) {
+    half inV = rsGetElementAt_half(gAllocInV, x);
+    return step(inEdge, inV);
+}
+
+half3 __attribute__((kernel)) testStepHalf3HalfHalf3(half3 inEdge, unsigned int x) {
+    half inV = rsGetElementAt_half(gAllocInV, x);
+    return step(inEdge, inV);
+}
+
+half4 __attribute__((kernel)) testStepHalf4HalfHalf4(half4 inEdge, unsigned int x) {
+    half inV = rsGetElementAt_half(gAllocInV, x);
+    return step(inEdge, inV);
+}
+
 float2 __attribute__((kernel)) testStepFloatFloat2Float2(float inEdge, unsigned int x) {
     float2 inV = rsGetElementAt_float2(gAllocInV, x);
     return step(inEdge, inV);
@@ -70,3 +105,18 @@
     float4 inV = rsGetElementAt_float4(gAllocInV, x);
     return step(inEdge, inV);
 }
+
+half2 __attribute__((kernel)) testStepHalfHalf2Half2(half inEdge, unsigned int x) {
+    half2 inV = rsGetElementAt_half2(gAllocInV, x);
+    return step(inEdge, inV);
+}
+
+half3 __attribute__((kernel)) testStepHalfHalf3Half3(half inEdge, unsigned int x) {
+    half3 inV = rsGetElementAt_half3(gAllocInV, x);
+    return step(inEdge, inV);
+}
+
+half4 __attribute__((kernel)) testStepHalfHalf4Half4(half inEdge, unsigned int x) {
+    half4 inV = rsGetElementAt_half4(gAllocInV, x);
+    return step(inEdge, inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestStepRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestStepRelaxed.rs
index 6f7175d..0033811 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestStepRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestStepRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTan.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTan.java
index 908ca59..de7c016 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTan.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTan.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeTan(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeTan(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeTan(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeTan(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkTanHalfHalf() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xc3f260ael, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testTanHalfHalf(inV, out);
+            verifyResultsTanHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testTanHalfHalf(inV, out);
+            verifyResultsTanHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsTanHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeTan(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkTanHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkTanHalf2Half2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xe8d356e0l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testTanHalf2Half2(inV, out);
+            verifyResultsTanHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testTanHalf2Half2(inV, out);
+            verifyResultsTanHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsTanHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeTan(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkTanHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkTanHalf3Half3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x47db1bd4l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testTanHalf3Half3(inV, out);
+            verifyResultsTanHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testTanHalf3Half3(inV, out);
+            verifyResultsTanHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsTanHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeTan(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkTanHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkTanHalf4Half4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0xa6e2e0c8l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testTanHalf4Half4(inV, out);
+            verifyResultsTanHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testTanHalf4Half4(inV, out);
+            verifyResultsTanHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsTanHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeTan(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkTanHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testTan() {
         checkTanFloatFloat();
         checkTanFloat2Float2();
         checkTanFloat3Float3();
         checkTanFloat4Float4();
+        checkTanHalfHalf();
+        checkTanHalf2Half2();
+        checkTanHalf3Half3();
+        checkTanHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTan.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTan.rs
index bee11f5..4f99d13 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTan.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTan.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testTanFloat4Float4(float4 inV) {
     return tan(inV);
 }
+
+half __attribute__((kernel)) testTanHalfHalf(half inV) {
+    return tan(inV);
+}
+
+half2 __attribute__((kernel)) testTanHalf2Half2(half2 inV) {
+    return tan(inV);
+}
+
+half3 __attribute__((kernel)) testTanHalf3Half3(half3 inV) {
+    return tan(inV);
+}
+
+half4 __attribute__((kernel)) testTanHalf4Half4(half4 inV) {
+    return tan(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTanRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTanRelaxed.rs
index 184ff39..3d10116 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTanRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTanRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTanh.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTanh.java
index 842c402..e325ab1 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTanh.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTanh.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeTanh(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeTanh(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeTanh(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeTanh(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkTanhHalfHalf() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xbe63da34l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testTanhHalfHalf(inV, out);
+            verifyResultsTanhHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanhHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testTanhHalfHalf(inV, out);
+            verifyResultsTanhHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanhHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsTanhHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeTanh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkTanhHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkTanhHalf2Half2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xc66a0fb6l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testTanhHalf2Half2(inV, out);
+            verifyResultsTanhHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanhHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testTanhHalf2Half2(inV, out);
+            verifyResultsTanhHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanhHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsTanhHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeTanh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkTanhHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkTanhHalf3Half3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x2571d4aal, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testTanhHalf3Half3(inV, out);
+            verifyResultsTanhHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanhHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testTanhHalf3Half3(inV, out);
+            verifyResultsTanhHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanhHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsTanhHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeTanh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkTanhHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkTanhHalf4Half4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x8479999el, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testTanhHalf4Half4(inV, out);
+            verifyResultsTanhHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanhHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testTanhHalf4Half4(inV, out);
+            verifyResultsTanhHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanhHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsTanhHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeTanh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkTanhHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testTanh() {
         checkTanhFloatFloat();
         checkTanhFloat2Float2();
         checkTanhFloat3Float3();
         checkTanhFloat4Float4();
+        checkTanhHalfHalf();
+        checkTanhHalf2Half2();
+        checkTanhHalf3Half3();
+        checkTanhHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTanh.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTanh.rs
index 41eb343..82643c1 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTanh.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTanh.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testTanhFloat4Float4(float4 inV) {
     return tanh(inV);
 }
+
+half __attribute__((kernel)) testTanhHalfHalf(half inV) {
+    return tanh(inV);
+}
+
+half2 __attribute__((kernel)) testTanhHalf2Half2(half2 inV) {
+    return tanh(inV);
+}
+
+half3 __attribute__((kernel)) testTanhHalf3Half3(half3 inV) {
+    return tanh(inV);
+}
+
+half4 __attribute__((kernel)) testTanhHalf4Half4(half4 inV) {
+    return tanh(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTanhRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTanhRelaxed.rs
index 8148315..ad5676e 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTanhRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTanhRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTanpi.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTanpi.java
index 13be7d9..0702bc1 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTanpi.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTanpi.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeTanpi(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeTanpi(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeTanpi(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeTanpi(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkTanpiHalfHalf() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xe56353f1l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testTanpiHalfHalf(inV, out);
+            verifyResultsTanpiHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanpiHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testTanpiHalfHalf(inV, out);
+            verifyResultsTanpiHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanpiHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsTanpiHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeTanpi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkTanpiHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkTanpiHalf2Half2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x71a055cbl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testTanpiHalf2Half2(inV, out);
+            verifyResultsTanpiHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanpiHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testTanpiHalf2Half2(inV, out);
+            verifyResultsTanpiHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanpiHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsTanpiHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeTanpi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkTanpiHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkTanpiHalf3Half3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0xd0a81abfl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testTanpiHalf3Half3(inV, out);
+            verifyResultsTanpiHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanpiHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testTanpiHalf3Half3(inV, out);
+            verifyResultsTanpiHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanpiHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsTanpiHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeTanpi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkTanpiHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkTanpiHalf4Half4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x2fafdfb3l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testTanpiHalf4Half4(inV, out);
+            verifyResultsTanpiHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanpiHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testTanpiHalf4Half4(inV, out);
+            verifyResultsTanpiHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanpiHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsTanpiHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeTanpi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkTanpiHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testTanpi() {
         checkTanpiFloatFloat();
         checkTanpiFloat2Float2();
         checkTanpiFloat3Float3();
         checkTanpiFloat4Float4();
+        checkTanpiHalfHalf();
+        checkTanpiHalf2Half2();
+        checkTanpiHalf3Half3();
+        checkTanpiHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTanpi.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTanpi.rs
index d8954b1..ae7701a 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTanpi.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTanpi.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testTanpiFloat4Float4(float4 inV) {
     return tanpi(inV);
 }
+
+half __attribute__((kernel)) testTanpiHalfHalf(half inV) {
+    return tanpi(inV);
+}
+
+half2 __attribute__((kernel)) testTanpiHalf2Half2(half2 inV) {
+    return tanpi(inV);
+}
+
+half3 __attribute__((kernel)) testTanpiHalf3Half3(half3 inV) {
+    return tanpi(inV);
+}
+
+half4 __attribute__((kernel)) testTanpiHalf4Half4(half4 inV) {
+    return tanpi(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTanpiRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTanpiRelaxed.rs
index eb27c30..c1484bb 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTanpiRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTanpiRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTgamma.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTgamma.java
index cd11dc9..4d277f0 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTgamma.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTgamma.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeTgamma(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeTgamma(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeTgamma(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeTgamma(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkTgammaHalfHalf() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xcaee5aa0l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testTgammaHalfHalf(inV, out);
+            verifyResultsTgammaHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTgammaHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testTgammaHalfHalf(inV, out);
+            verifyResultsTgammaHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTgammaHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsTgammaHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeTgamma(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkTgammaHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkTgammaHalf2Half2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x5ac39bc2l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testTgammaHalf2Half2(inV, out);
+            verifyResultsTgammaHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTgammaHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testTgammaHalf2Half2(inV, out);
+            verifyResultsTgammaHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTgammaHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsTgammaHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeTgamma(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkTgammaHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkTgammaHalf3Half3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0xb9cb60b6l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testTgammaHalf3Half3(inV, out);
+            verifyResultsTgammaHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTgammaHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testTgammaHalf3Half3(inV, out);
+            verifyResultsTgammaHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTgammaHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsTgammaHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeTgamma(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkTgammaHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkTgammaHalf4Half4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x18d325aal, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testTgammaHalf4Half4(inV, out);
+            verifyResultsTgammaHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTgammaHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testTgammaHalf4Half4(inV, out);
+            verifyResultsTgammaHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTgammaHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsTgammaHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeTgamma(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkTgammaHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testTgamma() {
         checkTgammaFloatFloat();
         checkTgammaFloat2Float2();
         checkTgammaFloat3Float3();
         checkTgammaFloat4Float4();
+        checkTgammaHalfHalf();
+        checkTgammaHalf2Half2();
+        checkTgammaHalf3Half3();
+        checkTgammaHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTgamma.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTgamma.rs
index 5431de0..5455d0c 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTgamma.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTgamma.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testTgammaFloat4Float4(float4 inV) {
     return tgamma(inV);
 }
+
+half __attribute__((kernel)) testTgammaHalfHalf(half inV) {
+    return tgamma(inV);
+}
+
+half2 __attribute__((kernel)) testTgammaHalf2Half2(half2 inV) {
+    return tgamma(inV);
+}
+
+half3 __attribute__((kernel)) testTgammaHalf3Half3(half3 inV) {
+    return tgamma(inV);
+}
+
+half4 __attribute__((kernel)) testTgammaHalf4Half4(half4 inV) {
+    return tgamma(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTgammaRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTgammaRelaxed.rs
index afd1489..911d7fc 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTgammaRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTgammaRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTrunc.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTrunc.java
index e29de2c..0293b96 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTrunc.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTrunc.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.renderscript.Allocation;
 import android.renderscript.RSRuntimeException;
 import android.renderscript.Element;
+import android.renderscript.cts.Target;
 
 import java.util.Arrays;
 
@@ -74,7 +75,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeTrunc(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -143,7 +144,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 2 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeTrunc(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -212,7 +213,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeTrunc(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -281,7 +282,7 @@
                 ArgumentsFloatFloat args = new ArgumentsFloatFloat();
                 args.inV = arrayInV[i * 4 + j];
                 // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
                 CoreMathVerifier.computeTrunc(args, target);
                 // Validate the outputs.
                 boolean valid = true;
@@ -317,10 +318,312 @@
                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
     }
 
+    public class ArgumentsHalfHalf {
+        public short inV;
+        public double inVDouble;
+        public Target.Floaty out;
+    }
+
+    private void checkTruncHalfHalf() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x4b4bfcf3l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            script.forEach_testTruncHalfHalf(inV, out);
+            verifyResultsTruncHalfHalf(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTruncHalfHalf: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testTruncHalfHalf(inV, out);
+            verifyResultsTruncHalfHalf(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTruncHalfHalf: " + e.toString());
+        }
+    }
+
+    private void verifyResultsTruncHalfHalf(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeTrunc(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkTruncHalfHalf" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkTruncHalf2Half2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x7f0d053dl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            script.forEach_testTruncHalf2Half2(inV, out);
+            verifyResultsTruncHalf2Half2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTruncHalf2Half2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testTruncHalf2Half2(inV, out);
+            verifyResultsTruncHalf2Half2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTruncHalf2Half2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsTruncHalf2Half2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 2 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeTrunc(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 2 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkTruncHalf2Half2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkTruncHalf3Half3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0xde14ca31l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            script.forEach_testTruncHalf3Half3(inV, out);
+            verifyResultsTruncHalf3Half3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTruncHalf3Half3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testTruncHalf3Half3(inV, out);
+            verifyResultsTruncHalf3Half3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTruncHalf3Half3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsTruncHalf3Half3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeTrunc(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkTruncHalf3Half3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkTruncHalf4Half4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x3d1c8f25l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            script.forEach_testTruncHalf4Half4(inV, out);
+            verifyResultsTruncHalf4Half4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTruncHalf4Half4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testTruncHalf4Half4(inV, out);
+            verifyResultsTruncHalf4Half4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTruncHalf4Half4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsTruncHalf4Half4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (short) 42);
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayOut, (short) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsHalfHalf args = new ArgumentsHalfHalf();
+                args.inV = arrayInV[i * 4 + j];
+                args.inVDouble = Float16Utils.convertFloat16ToDouble(args.inV);
+                // Figure out what the outputs should have been.
+                Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
+                CoreMathVerifier.computeTrunc(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\n");
+                        message.append("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 4 + j]);
+                        message.append("\n");
+                        message.append("Actual   output out (in double): ");
+                        appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
+                        if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkTruncHalf4Half4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
     public void testTrunc() {
         checkTruncFloatFloat();
         checkTruncFloat2Float2();
         checkTruncFloat3Float3();
         checkTruncFloat4Float4();
+        checkTruncHalfHalf();
+        checkTruncHalf2Half2();
+        checkTruncHalf3Half3();
+        checkTruncHalf4Half4();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTrunc.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTrunc.rs
index 350a351..7dd6620 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTrunc.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTrunc.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,3 +35,19 @@
 float4 __attribute__((kernel)) testTruncFloat4Float4(float4 inV) {
     return trunc(inV);
 }
+
+half __attribute__((kernel)) testTruncHalfHalf(half inV) {
+    return trunc(inV);
+}
+
+half2 __attribute__((kernel)) testTruncHalf2Half2(half2 inV) {
+    return trunc(inV);
+}
+
+half3 __attribute__((kernel)) testTruncHalf3Half3(half3 inV) {
+    return trunc(inV);
+}
+
+half4 __attribute__((kernel)) testTruncHalf4Half4(half4 inV) {
+    return trunc(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTruncRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTruncRelaxed.rs
index 617b687..7105b22 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTruncRelaxed.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTruncRelaxed.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/get_allocation.rs b/tests/tests/renderscript/src/android/renderscript/cts/get_allocation.rs
index 0149e6c..ae7d3e6 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/get_allocation.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/get_allocation.rs
@@ -2,15 +2,14 @@
 #pragma rs java_package_name(android.renderscript.cts)
 
 const int* pointer;
-rs_script script;
 rs_allocation alloc_in;
 rs_allocation alloc_out;
 
-void root(const int* in, int *out) {
-    *out = *in;
+int __attribute__((kernel)) copy(int in) {
+    return in;
 }
 
 void start() {
     alloc_in = rsGetAllocation(pointer);
-    rsForEach(script, alloc_in, alloc_out);
+    rsForEach(copy, alloc_in, alloc_out);
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/kernel_input.rs b/tests/tests/renderscript/src/android/renderscript/cts/kernel_input.rs
index 2eaca92..a4d919f 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/kernel_input.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/kernel_input.rs
@@ -35,6 +35,12 @@
  * functions check their input against a global variable.
  */
 
+// The clear_input_* kernels have rsDebug calls so that the writes they make to
+// their parameters don't get optimized away.  To avoid logspam from the
+// rsDebug, guard calls to it with a runtime test that is guaranteed to be
+// false.
+volatile int gDummy = 0;
+
 // For clear_input_* kernels, we use a volatile qualified input argument
 // to try to inhibit any optimizations that would result in the write to
 // the input argument being optimized out by the compiler.
@@ -42,9 +48,13 @@
 #define COMMON_TEST_CODE(type)                           \
   type initial_value_##type;                             \
   type RS_KERNEL clear_input_##type(volatile type in) {  \
-    rsDebug(#type, in);                                  \
+    if (gDummy == 500) {                                 \
+      rsDebug(#type, in);                                \
+    }                                                    \
     in -= in;                                            \
-    rsDebug(#type, in);                                  \
+    if (gDummy == 500) {                                 \
+      rsDebug(#type, in);                                \
+    }                                                    \
     return in;                                           \
   }
 
@@ -174,9 +184,13 @@
 
 // See comment on volatile above.
 small RS_KERNEL clear_input_small(volatile small in) {
-  rsDebug("in.x", in.x[0]);
+  if (gDummy == 500) {
+    rsDebug("in.x", in.x[0]);
+  }
   in.x[0] = 0;
-  rsDebug("in.x", in.x[0]);
+  if (gDummy == 500) {
+    rsDebug("in.x", in.x[0]);
+  }
   return in;
 }
 
@@ -190,9 +204,13 @@
 // See comment on volatile above.
 big RS_KERNEL clear_input_big(volatile big in) {
   for (size_t i = 0; i < 100; ++i) {
-    rsDebug("in.x", in.x[i]);
+    if (gDummy == 500) {
+      rsDebug("in.x", in.x[i]);
+    }
     in.x[i] = 0;
-    rsDebug("in.x", in.x[i]);
+    if (gDummy == 500) {
+      rsDebug("in.x", in.x[i]);
+    }
   }
   return in;
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/reduce.rs b/tests/tests/renderscript/src/android/renderscript/cts/reduce.rs
new file mode 100644
index 0000000..d731561
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/reduce.rs
@@ -0,0 +1,473 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 "shared.rsh"
+
+float negInf, posInf;
+
+static half negInfHalf, posInfHalf;
+
+// At present, no support for global of type half, or for invokable
+// taking an argument of type half.
+static void translate(half *tgt, const short src) {
+  for (int i = 0; i < sizeof(half); ++i)
+    ((char *)tgt)[i] = ((const char *)&src)[i];
+}
+void setInfsHalf(short forNegInfHalf, short forPosInfHalf) {
+  translate(&negInfHalf, forNegInfHalf);
+  translate(&posInfHalf, forPosInfHalf);
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+#pragma rs reduce(addint) \
+  accumulator(aiAccum)
+
+static void aiAccum(int *accum, int val) { *accum += val; }
+
+/////////////////////////////////////////////////////////////////////////
+
+// Finds LOCATION of min and max float values
+
+#pragma rs reduce(findMinAndMax) \
+  initializer(fMMInit) accumulator(fMMAccumulator) \
+  combiner(fMMCombiner) outconverter(fMMOutConverter)
+
+typedef struct {
+  float val;
+  int idx;
+} IndexedVal;
+
+typedef struct {
+  IndexedVal min, max;
+} MinAndMax;
+
+static void fMMInit(MinAndMax *accum) {
+  accum->min.val = posInf;
+  accum->min.idx = -1;
+  accum->max.val = negInf;
+  accum->max.idx = -1;
+}
+
+static void fMMAccumulator(MinAndMax *accum, float in, int x) {
+  IndexedVal me;
+  me.val = in;
+  me.idx = x;
+
+  if (me.val < accum->min.val)
+    accum->min = me;
+  if (me.val > accum->max.val)
+    accum->max = me;
+}
+
+static void fMMCombiner(MinAndMax *accum,
+                        const MinAndMax *val) {
+  if (val->min.val < accum->min.val)
+    accum->min = val->min;
+  if (val->max.val > accum->max.val)
+    accum->max = val->max;
+}
+
+static void fMMOutConverter(int2 *result,
+                            const MinAndMax *val) {
+  result->x = val->min.idx;
+  result->y = val->max.idx;
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+// finds min and max half values (not their locations)
+
+// tests half input and half2 result
+
+// .. reduction form
+
+#pragma rs reduce(findMinAndMaxHalf) \
+  initializer(fMMHalfInit) accumulator(fMMHalfAccumulator) \
+  combiner(fMMHalfCombiner) outconverter(fMMHalfOutConverter)
+
+typedef struct {
+  half min, max;
+} MinAndMaxHalf;
+
+static void fMMHalfInit(MinAndMaxHalf *accum) {
+  accum->min = posInfHalf;
+  accum->max = negInfHalf;
+}
+
+static void fMMHalfAccumulator(MinAndMaxHalf *accum, half in) {
+  accum->min = fmin(accum->min, in);
+  accum->max = fmax(accum->max, in);
+}
+
+static void fMMHalfCombiner(MinAndMaxHalf *accum,
+                            const MinAndMaxHalf *val) {
+  accum->min = fmin(accum->min, val->min);
+  accum->max = fmax(accum->max, val->max);
+}
+
+static void fMMHalfOutConverter(half2 *result,
+                                const MinAndMaxHalf *val) {
+  result->x = val->min;
+  result->y = val->max;
+}
+
+// .. invokable (non reduction) form (no support for half computations in Java)
+
+void findMinAndMaxHalf(rs_allocation out, rs_allocation in) {
+  half min = posInfHalf, max = negInfHalf;
+
+  const uint32_t len = rsAllocationGetDimX(in);
+  for (uint32_t idx = 0; idx < len; ++idx) {
+    const half val = rsGetElementAt_half(in, idx);
+    min = fmin(min, val);
+    max = fmax(max, val);
+  }
+
+  half2 result;
+  result.x = min;
+  result.y = max;
+  rsSetElementAt_half2(out, result, 0);
+}
+
+// tests half input and array of half result;
+//   reuses functions of findMinAndMaxHalf reduction kernel
+
+#pragma rs reduce(findMinAndMaxHalfIntoArray) \
+  initializer(fMMHalfInit) accumulator(fMMHalfAccumulator) \
+  combiner(fMMHalfCombiner) outconverter(fMMHalfOutConverterIntoArray)
+
+static void fMMHalfOutConverterIntoArray(half (*result)[2],
+                                         const MinAndMaxHalf *val) {
+  (*result)[0] = val->min;
+  (*result)[1] = val->max;
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+// finds min and max half2 values (not their locations), element-wise:
+//   result[0].x = fmin(input[...].x)
+//   result[0].y = fmin(input[...].y)
+//   result[1].x = fmax(input[...].x)
+//   result[1].y = fmax(input[...].y)
+
+// tests half2 input and half2[] result
+
+// .. reduction form
+
+#pragma rs reduce(findMinAndMaxHalf2) \
+  initializer(fMMHalf2Init) accumulator(fMMHalf2Accumulator) \
+  combiner(fMMHalf2Combiner) outconverter(fMMHalf2OutConverter)
+
+typedef struct {
+  half2 min, max;
+} MinAndMaxHalf2;
+
+static void fMMHalf2Init(MinAndMaxHalf2 *accum) {
+  accum->min.x = posInfHalf;
+  accum->min.y = posInfHalf;
+  accum->max.x = negInfHalf;
+  accum->max.y = negInfHalf;
+}
+
+static void fMMHalf2Accumulator(MinAndMaxHalf2 *accum, half2 in) {
+  accum->min.x = fmin(accum->min.x, in.x);
+  accum->min.y = fmin(accum->min.y, in.y);
+  accum->max.x = fmax(accum->max.x, in.x);
+  accum->max.y = fmax(accum->max.y, in.y);
+}
+
+static void fMMHalf2Combiner(MinAndMaxHalf2 *accum,
+                            const MinAndMaxHalf2 *val) {
+  accum->min.x = fmin(accum->min.x, val->min.x);
+  accum->min.y = fmin(accum->min.y, val->min.y);
+  accum->max.x = fmax(accum->max.x, val->max.x);
+  accum->max.y = fmax(accum->max.y, val->max.y);
+}
+
+typedef half2 ArrayOf2Half2[2];
+
+static void fMMHalf2OutConverter(ArrayOf2Half2 *result,
+                                const MinAndMaxHalf2 *val) {
+  (*result)[0] = val->min;
+  (*result)[1] = val->max;
+}
+
+// .. invokable (non reduction) form (no support for half computations in Java)
+
+void findMinAndMaxHalf2(rs_allocation out, rs_allocation in) {
+  half2 min = { posInfHalf, posInfHalf }, max = { negInfHalf, negInfHalf };
+
+  const uint32_t len = rsAllocationGetDimX(in);
+  for (uint32_t idx = 0; idx < len; ++idx) {
+    const half2 val = rsGetElementAt_half2(in, idx);
+    min.x = fmin(min.x, val.x);
+    min.y = fmin(min.y, val.y);
+    max.x = fmax(max.x, val.x);
+    max.y = fmax(max.y, val.y);
+  }
+
+  rsSetElementAt_half2(out, min, 0);
+  rsSetElementAt_half2(out, max, 1);
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+// finds min values (not their locations) from matrix input
+
+// tests matrix input and matrix accumulator
+
+#pragma rs reduce(findMinMat) \
+  initializer(fMinMatInit) accumulator(fMinMatAccumulator) \
+  outconverter(fMinMatOutConverter)
+
+static void fMinMatInit(rs_matrix2x2 *accum) {
+  for (int i = 0; i < 2; ++i)
+    for (int j = 0; j < 2; ++j)
+      rsMatrixSet(accum, i, j, posInf);
+}
+
+static void fMinMatAccumulator(rs_matrix2x2 *accum, rs_matrix2x2 val) {
+  for (int i = 0; i < 2; ++i) {
+    for (int j = 0; j < 2; ++j) {
+      const float accumElt = rsMatrixGet(accum, i, j);
+      const float valElt = rsMatrixGet(&val, i, j);
+      if (valElt < accumElt)
+        rsMatrixSet(accum, i, j, valElt);
+    }
+  }
+}
+
+// reduction does not support matrix result, so use array instead
+static void fMinMatOutConverter(float (*result)[4],  const rs_matrix2x2 *accum) {
+  for (int i = 0; i < 4; ++i)
+    (*result)[i] = accum->m[i];
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+// finds min and max values (not their locations) from matrix input
+
+// tests matrix input and array of matrix accumulator (0 = min, 1 = max)
+
+#pragma rs reduce(findMinAndMaxMat) \
+  initializer(fMinMaxMatInit) accumulator(fMinMaxMatAccumulator) \
+  combiner(fMinMaxMatCombiner) outconverter(fMinMaxMatOutConverter)
+
+typedef rs_matrix2x2 MatrixPair[2];
+enum MatrixPairEntry { MPE_Min = 0, MPE_Max = 1 };  // indices into MatrixPair
+
+static void fMinMaxMatInit(MatrixPair *accum) {
+  for (int i = 0; i < 2; ++i) {
+    for (int j = 0; j < 2; ++j) {
+      rsMatrixSet(&(*accum)[MPE_Min], i, j, posInf);
+      rsMatrixSet(&(*accum)[MPE_Max], i, j, negInf);
+    }
+  }
+}
+
+static void fMinMaxMatAccumulator(MatrixPair *accum, rs_matrix2x2 val) {
+  for (int i = 0; i < 2; ++i) {
+    for (int j = 0; j < 2; ++j) {
+      const float valElt = rsMatrixGet(&val, i, j);
+
+      const float minElt = rsMatrixGet(&(*accum)[MPE_Min], i, j);
+      rsMatrixSet(&(*accum)[MPE_Min], i, j, fmin(minElt, valElt));
+
+      const float maxElt = rsMatrixGet(&(*accum)[MPE_Max], i, j);
+      rsMatrixSet(&(*accum)[MPE_Max], i, j, fmax(maxElt, valElt));
+    }
+  }
+}
+
+static void fMinMaxMatCombiner(MatrixPair *accum, const MatrixPair *other) {
+  for (int i = 0; i < 2; ++i) {
+    for (int j = 0; j < 2; ++j) {
+      const float minElt = rsMatrixGet(&(*accum)[MPE_Min], i, j);
+      const float minEltOther = rsMatrixGet(&(*other)[MPE_Min], i, j);
+      rsMatrixSet(&(*accum)[MPE_Min], i, j, fmin(minElt, minEltOther));
+
+      const float maxElt = rsMatrixGet(&(*accum)[MPE_Max], i, j);
+      const float maxEltOther = rsMatrixGet(&(*other)[MPE_Max], i, j);
+      rsMatrixSet(&(*accum)[MPE_Max], i, j, fmax(maxElt, maxEltOther));
+    }
+  }
+}
+
+// reduction does not support matrix result, so use array instead
+static void fMinMaxMatOutConverter(float (*result)[8],  const MatrixPair *accum) {
+  for (int i = 0; i < 4; ++i) {
+    (*result)[i+0] = (*accum)[MPE_Min].m[i];
+    (*result)[i+4] = (*accum)[MPE_Max].m[i];
+  }
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+#pragma rs reduce(fz) \
+  initializer(fzInit) \
+  accumulator(fzAccum) combiner(fzCombine)
+
+static void fzInit(int *accumIdx) { *accumIdx = -1; }
+
+static void fzAccum(int *accumIdx,
+                    int inVal, int x /* special arg */) {
+  if (inVal==0) *accumIdx = x;
+}
+
+static void fzCombine(int *accumIdx, const int *accumIdx2) {
+  if (*accumIdx2 >= 0) *accumIdx = *accumIdx2;
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+#pragma rs reduce(fz2) \
+  initializer(fz2Init) \
+  accumulator(fz2Accum) combiner(fz2Combine)
+
+static void fz2Init(int2 *accum) { accum->x = accum->y = -1; }
+
+static void fz2Accum(int2 *accum,
+                     int inVal,
+                     int x /* special arg */,
+                     int y /* special arg */) {
+  if (inVal==0) {
+    accum->x = x;
+    accum->y = y;
+  }
+}
+
+static void fz2Combine(int2 *accum, const int2 *accum2) {
+  if (accum2->x >= 0) *accum = *accum2;
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+#pragma rs reduce(fz3) \
+  initializer(fz3Init) \
+  accumulator(fz3Accum) combiner(fz3Combine)
+
+static void fz3Init(int3 *accum) { accum->x = accum->y = accum->z = -1; }
+
+static void fz3Accum(int3 *accum,
+                     int inVal,
+                     int x /* special arg */,
+                     int y /* special arg */,
+                     int z /* special arg */) {
+  if (inVal==0) {
+    accum->x = x;
+    accum->y = y;
+    accum->z = z;
+  }
+}
+
+static void fz3Combine(int3 *accum, const int3 *accum2) {
+  if (accum2->x >= 0) *accum = *accum2;
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+#pragma rs reduce(histogram) \
+  accumulator(hsgAccum) combiner(hsgCombine)
+
+#define BUCKETS 256
+typedef uint32_t Histogram[BUCKETS];
+
+static void hsgAccum(Histogram *h, uchar in) { ++(*h)[in]; }
+
+static void hsgCombine(Histogram *accum, const Histogram *addend) {
+  for (int i = 0; i < BUCKETS; ++i)
+    (*accum)[i] += (*addend)[i];
+}
+
+#pragma rs reduce(mode) \
+  accumulator(hsgAccum) combiner(hsgCombine) \
+  outconverter(modeOutConvert)
+
+static void modeOutConvert(int2 *result, const Histogram *h) {
+  uint32_t mode = 0;
+  for (int i = 1; i < BUCKETS; ++i)
+    if ((*h)[i] > (*h)[mode]) mode = i;
+  result->x = mode;
+  result->y = (*h)[mode];
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+// Simple test case where there are two inputs
+#pragma rs reduce(sumxor) accumulator(sxAccum) combiner(sxCombine)
+
+static void sxAccum(int *accum, int inVal1, int inVal2) { *accum += (inVal1 ^ inVal2); }
+
+static void sxCombine(int *accum, const int *accum2) { *accum += *accum2; }
+
+/////////////////////////////////////////////////////////////////////////
+
+// Test case where inputs are of different types
+#pragma rs reduce(sillysum) accumulator(ssAccum) combiner(ssCombine)
+
+static void ssAccum(long *accum, char c, float f, int3 i3) {
+  *accum += ((((c + (long)ceil(log(f))) + i3.x) + i3.y) + i3.z);
+}
+
+static void ssCombine(long *accum, const long *accum2) { *accum += *accum2; }
+
+/////////////////////////////////////////////////////////////////////////
+
+// Test out-of-range result.
+// We don't care about the input at all.
+// We use these globals to configure the generation of the result.
+ulong oorrGoodResult;     // the value of a good result
+ulong oorrBadResultHalf;  // half the value of a bad result
+                          //   ("half" because Java can only set the global from long not from ulong)
+int   oorrBadPos;         // position of bad result
+
+#define oorrBadResult (2*oorrBadResultHalf)
+
+static void oorrAccum(int *accum, int val) { }
+
+#pragma rs reduce(oorrSca) accumulator(oorrAccum) outconverter(oorrScaOut)
+static void oorrScaOut(ulong *out, const int *accum) {
+  *out = (oorrBadPos ? oorrGoodResult : oorrBadResult);
+}
+
+#pragma rs reduce(oorrVec4) accumulator(oorrAccum) outconverter(oorrVec4Out)
+static void oorrVec4Out(ulong4 *out, const int *accum) {
+  out->x = (oorrBadPos==0 ? oorrBadResult : oorrGoodResult);
+  out->y = (oorrBadPos==1 ? oorrBadResult : oorrGoodResult);
+  out->z = (oorrBadPos==2 ? oorrBadResult : oorrGoodResult);
+  out->w = (oorrBadPos==3 ? oorrBadResult : oorrGoodResult);
+}
+
+#pragma rs reduce(oorrArr9) accumulator(oorrAccum) outconverter(oorrArr9Out)
+typedef ulong Arr9[9];
+static void oorrArr9Out(Arr9 *out, const int *accum) {
+  for (int i = 0; i < 9; ++i)
+    (*out)[i] = (i == oorrBadPos ? oorrBadResult : oorrGoodResult);
+}
+
+#pragma rs reduce(oorrArr9Vec4) accumulator(oorrAccum) outconverter(oorrArr9Vec4Out)
+typedef ulong4 Arr9Vec4[9];
+static void oorrArr9Vec4Out(Arr9Vec4 *out, const int *accum) {
+  const int badIdx = (oorrBadPos >= 0 ? oorrBadPos / 4: -1);
+  const int badComp = (oorrBadPos >= 0 ? oorrBadPos % 4: -1);
+  for (int i = 0; i < 9; ++i) {
+    (*out)[i].x = ((i==badIdx) && (0==badComp)) ? oorrBadResult : oorrGoodResult;
+    (*out)[i].y = ((i==badIdx) && (1==badComp)) ? oorrBadResult : oorrGoodResult;
+    (*out)[i].z = ((i==badIdx) && (2==badComp)) ? oorrBadResult : oorrGoodResult;
+    (*out)[i].w = ((i==badIdx) && (3==badComp)) ? oorrBadResult : oorrGoodResult;
+  }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/refocus/BlurStack.java b/tests/tests/renderscript/src/android/renderscript/cts/refocus/BlurStack.java
new file mode 100644
index 0000000..391ddb2
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/refocus/BlurStack.java
@@ -0,0 +1,451 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.renderscript.cts.refocus;
+
+import android.util.Log;
+
+import java.util.ArrayList;
+
+/**
+ * An object that contains all the parameters that are needed in refocusing
+ * filtering function, including the range of depth levels, the disc blur radius
+ * of each depth level, how the depth levels are grouped into layers, which
+ * layer is in focus.
+ *
+ *  <b> Here by "depth", we mean inverse depth. Pixels with larger depth values
+ * are closer to the camera.
+ *
+ *  For a layer n, its depth interval is (@code [layerInfo[n].backDepth,
+ * layerInfo[n].frontDepth]), where (@code backDepth<=frontDepth).
+ *
+ *  The layers are ordered from near to far; note that near layers have larger
+ * depth values.
+ *
+ *  (@code focusLayer) is the index of the layer that is in focus, that is, has
+ * zero blur.
+ */
+
+public class BlurStack {
+  //private static final Log.Tag TAG = new Log.Tag("BlurStack");
+  private static final String TAG = "BlurStack";
+  /**
+   * The cap for disc radius of blur kernels.
+   */
+  private static final float MAX_DISC_RADIUS = 25.0f;
+
+  /**
+   * The minimum of the interval that is used to group depth levels into
+   * blending layers based on the corresponding blur disk radius.
+   */
+  private static final float MIN_DISK_RADIUS_STEP_SIZE = 2.0f;
+
+  /**
+   * The starting index of depth quantization level. Must be positive as zero is
+   * reserved for invalid depth.
+   */
+  private static final int MIN_DEPTH = 1;
+
+  /**
+   * The ending index of depth quantization level. It must be a power of 2.
+   */
+  private static final int MAX_DEPTH = 64;
+
+  /**
+   * The scale to apply to 8-bit depthmaps.
+   */
+  private static final int DEPTH_SCALE = 256 / MAX_DEPTH;
+
+  /**
+   * For each depth value {@code d} within [MIN_DEPTH,MAX_DEPTH], its blur disc
+   * radius is saved in {@code diskRadius[d-MIN_DEPTH]}. Hence the length
+   * {@code diskRadius} is {@code MAX_DEPTH-MIN_DEPTH+1}.
+   */
+  private float[] diskRadiusArray;
+
+  /**
+   * A set of non-overlapping layers that covers all the depth levels. The
+   * layers are ordered from front (closer to the camera) to back (farther away
+   * from the camera).
+   */
+  private LayerInfo[] layerInfo;
+
+  /**
+   * The layer in which the focal depth belongs to. <b> For this layer, we
+   * assume that it is a single depth layer. That is, the front depth and back
+   * depth both equal to focal depth.
+   */
+  private int focusLayer;
+
+  public static float getMaxDiskRadius() {
+    return MAX_DISC_RADIUS;
+  }
+
+  /**
+   * Returns the blur disk radius of a depth level.
+   *
+   * @param depth depth level
+   * @return the blur disk radius of the depth level
+   */
+  public float getDiskRadius(int depth) {
+    return diskRadiusArray[depth - MIN_DEPTH];
+  }
+
+  public int getNumLayers() {
+    return layerInfo.length;
+  }
+
+  public LayerInfo getLayerInfo(int layer) {
+    return layerInfo[layer];
+  }
+
+  /**
+   * Returns the number of depths in a given layer.
+   *
+   * @param layer layer index
+   * @return the number of depth levels in the layer
+   */
+  public int getNumDepths(int layer) {
+    return layerInfo[layer].frontDepth - layerInfo[layer].backDepth + 1;
+  }
+
+  public int getFocusLayer() {
+    return focusLayer;
+  }
+
+  /**
+   * Returns the depth given the layer and the relative depth in the layer.
+   *
+   * @param layer the layer index
+   * @param relativeDepthInLayer the relative depth index relative to the back
+   *        depth of a layer
+   * @return the depth
+   */
+  public int getDepth(int layer, int relativeDepthInLayer) {
+    return layerInfo[layer].backDepth + relativeDepthInLayer;
+  }
+
+  /**
+   * Creates an instance of BlurStack using depth range, focal depth, desired
+   * amount of blur at infinity, and the number of blending layers.
+   *
+   * @param depthTransform an object that translates between floating depth and
+   *        quantized depth.
+   * @param focusDepth3D focus depth in 3D
+   * @param depthOfField the range of depth values around focus depth 3D that
+   *        has zero blur.
+   * @param blurInfinity the desired amount of blur, represented as blur radius
+   *        at infinity
+   * @param numBlendingLayers the number of blending layers that group all the
+   *        depth levels
+   * @return an instance of {@code BlurStack}
+   */
+  public static BlurStack createFromDepthTransform(
+      final DepthTransform depthTransform, float focusDepth3D,
+      float depthOfField, float blurInfinity, int numBlendingLayers) {
+    BlurStack blurStack = new BlurStack();
+    // Finds the front and back depth levels for the focus layer.
+    if (depthOfField < 0) {
+      depthOfField = -depthOfField;
+      Log.e(TAG, "Negative depth of field");
+    }
+    int frontFocalDepth = openglDepthToStackDepth(
+        depthTransform.quantize(focusDepth3D * (1 - depthOfField)));
+    int backFocalDepth = openglDepthToStackDepth(
+        depthTransform.quantize(focusDepth3D * (1 + depthOfField)));
+    // Computes blur disk radius for all the depth levels.
+    blurStack.computeDiskRadius(depthTransform, frontFocalDepth, backFocalDepth,
+        blurInfinity);
+
+    if (numBlendingLayers >= MAX_DEPTH) {
+      blurStack.generateOneLayerForEachDepth(frontFocalDepth, backFocalDepth);
+    } else {
+      // Sets the max variation of blur disk radius in a blending layer.
+      float diskRadiusInterval = (blurStack.getDiskRadius(MIN_DEPTH)
+          + blurStack.getDiskRadius(MAX_DEPTH)) / numBlendingLayers;
+      diskRadiusInterval =
+          Math.max(diskRadiusInterval, MIN_DISK_RADIUS_STEP_SIZE);
+      // Computes {@code layerInfo, focusLayer}, assuming {@code diskRadius}
+      // have been computed.
+      blurStack.groupDepthLevelsIntoLayers(frontFocalDepth, backFocalDepth,
+          diskRadiusInterval);
+    }
+    return blurStack;
+  }
+
+  @Override
+  public String toString() {
+    String s = "disparity range: " + MAX_DEPTH + ", " + MIN_DEPTH + "\n";
+    s += "focus disparity: " + layerInfo[focusLayer].frontDepth + ", "
+        + layerInfo[focusLayer].backDepth + "\n";
+    s += "num of layers: " + getNumLayers() + "\n";
+    s += "focus layer: " + focusLayer + "\n";
+
+    for (int n = 0; n < layerInfo.length; ++n) {
+      int front = layerInfo[n].frontDepth;
+      int back = layerInfo[n].backDepth;
+      s += "\nlayer " + n + " num of disparities " + (front - back + 1) + "\n";
+
+      for (int d = front; d >= back; --d) {
+        s += "layer " + n + " disparity " + d + " disk radius "
+            + getDiskRadius(d) + "\n";
+      }
+    }
+
+    return s;
+  }
+
+  /**
+   * OpenGL depth is from 0(near) to 255(far). The depth in BlurStack is from
+   * 1(far) to MAX_DEPTH(near). Converts from openglDepth to stackDepth.
+   *
+   * @param openglDepth openGL depth.
+   * @return stackDepth stack depth.
+   */
+  private static int openglDepthToStackDepth(int openglDepth) {
+    return MAX_DEPTH - (openglDepth / DEPTH_SCALE);
+  }
+
+  /**
+   * OpenGL depth is from 0(near) to 255(far). The depth in BlurStack is from
+   * 1(far) to MAX_DEPTH(near). Converts from stackDepth to openglDepth.
+   *
+   * @param stackDepth stack depth.
+   * @return openglDepth openGL depth.
+   */
+  private static int stackDepthToOpenglDepth(int stackDepth) {
+    return (MAX_DEPTH - stackDepth) * DEPTH_SCALE;
+  }
+
+  /**
+   * A private constructor that forces users to use {@code createFromDepthRange}
+   * to construct an instance of BlurStack.
+   */
+  private BlurStack() {}
+
+  /**
+   * Quantizes the depth range into MAX_DEPTH levels in inverse depth space, and
+   * for each level, computes the blur disk radius.
+   *
+   * @param depthTransform an object that translates between floating depth and
+   *        quantized depth.
+   * @param frontFocalDepth front focal depth level
+   * @param backFocalDepth back focal depth level
+   * @param blurInfinity the amount of desired blur represented as the blur
+   *        radius at infinity
+   */
+  private void computeDiskRadius(final DepthTransform depthTransform,
+      int frontFocalDepth, int backFocalDepth, float blurInfinity) {
+    int numLevels = MAX_DEPTH - MIN_DEPTH + 1;
+    diskRadiusArray = new float[numLevels];
+    float frontFocalDepth3D =
+        depthTransform.reconstruct(stackDepthToOpenglDepth(frontFocalDepth));
+    float backFocalDepth3D =
+        depthTransform.reconstruct(stackDepthToOpenglDepth(backFocalDepth));
+
+    // Computes the blur disk radius for each depth level.
+    for (int depth = MIN_DEPTH; depth <= MAX_DEPTH; ++depth) {
+      float depth3D =
+          depthTransform.reconstruct(stackDepthToOpenglDepth(depth));
+      float radius = 0;
+      if (depth3D < frontFocalDepth3D) {
+        radius = blurInfinity * (frontFocalDepth3D - depth3D) / depth3D;
+      } else if (depth3D > backFocalDepth3D) {
+        radius = blurInfinity * (depth3D - backFocalDepth3D) / depth3D;
+      }
+      diskRadiusArray[depth - MIN_DEPTH] = Math.min(radius, MAX_DISC_RADIUS);
+    }
+  }
+
+  /**
+   * Sets up {@code focusLayer} such that each layer contains only a single
+   * depth, except that the focal layer contains frontFocalDepth and
+   * backFocalDepth.
+   *
+   * <b> This function computes {@code layerInfo, focusLayer}.
+   *
+   * @param frontFocalDepth the front depth of focal layer.
+   * @param backFocalDepth the back depth of focal layer.
+   */
+  private void generateOneLayerForEachDepth(int frontFocalDepth,
+      int backFocalDepth) {
+    int numLayers =
+        MAX_DEPTH - MIN_DEPTH + 1 - (frontFocalDepth - backFocalDepth);
+    layerInfo = new LayerInfo[numLayers];
+
+    // Pushes single depth layers in front of the focal layer to layerInfo.
+    int layer = 0;
+    for (int depth = MAX_DEPTH; depth > frontFocalDepth; --depth, ++layer) {
+      layerInfo[layer] = new LayerInfo(depth);
+    }
+
+    // Pushes focal layer to layerInfo.
+    focusLayer = layer;
+    layerInfo[layer] = new LayerInfo(frontFocalDepth, backFocalDepth);
+    ++layer;
+
+    // Pushes single depth layers behind the focal layer to layerInfo.
+    for (int depth = backFocalDepth - 1; depth >= MIN_DEPTH; --depth, ++layer) {
+      layerInfo[layer] = new LayerInfo(depth);
+    }
+  }
+
+  /**
+   * Sets up {@code focusLayer} such that within each layer, the blur radius
+   * variation due to depth difference is no larger than
+   * {@code diskRadiusInterval}.
+   *
+   * <b> This function computes {@code layerInfo, focusLayer}, assuming that
+   * {@code diskRadius} have been properly initialized.
+   *
+   * @param frontFocalDepth the front depth of focal layer.
+   * @param backFocalDepth the back depth of focal layer.
+   * @diskRadiusInterval the max allowed blur disk radius difference within each
+   *                     layer.
+   */
+  private void groupDepthLevelsIntoLayers(int frontFocalDepth,
+      int backFocalDepth, float diskRadiusInterval) {
+    // Groups depth levels behind the focal depth into several layers.
+    // The blur radius difference in each layer is no larger than
+    // diskRadiusInterval.
+    ArrayList<LayerInfo> layerInfoBehindFocus =
+        groupDepthLevelsBehindFocus(backFocalDepth, diskRadiusInterval);
+
+    // Groups depth levels in front of the focal depth into several layers.
+    // The blur radius difference in each layer is no larger than {@code
+    // diskRadiusInterval}.
+    ArrayList<LayerInfo> layerInfoInFrontOfFocus =
+        groupDepthLevelsInFrontOfFocus(frontFocalDepth, diskRadiusInterval);
+
+    // Merges the two groups of layers into one stack of layers, plus the focus
+    // depth layer.
+    int numLayers =
+        layerInfoInFrontOfFocus.size() + 1 + layerInfoBehindFocus.size();
+    layerInfo = new LayerInfo[numLayers];
+    focusLayer = layerInfoInFrontOfFocus.size();
+
+    // The merged layers is ordered from the front-most layer to the back-most
+    // layer.
+    for (int n = 0; n < numLayers; ++n) {
+      if (n < layerInfoInFrontOfFocus.size()) {
+        // Finds the corresponding layer index m in layerInfoInFrontOfFocus,
+        // which is ordered from focal depth to front-most.
+        int m = (layerInfoInFrontOfFocus.size() - 1) - n;
+        layerInfo[n] = layerInfoInFrontOfFocus.get(m);
+      } else if (n == layerInfoInFrontOfFocus.size()) {
+        layerInfo[n] = new LayerInfo(frontFocalDepth, backFocalDepth);
+      } else {
+        // Finds the corresponding layer index m in layerInfoBehindFocus, which
+        // is ordered from focal depth to back-most.
+        int m = n - (layerInfoInFrontOfFocus.size() + 1);
+        layerInfo[n] = layerInfoBehindFocus.get(m);
+      }
+    }
+  }
+
+  /**
+   * Groups depth levels behind the focal depth into several layers. The blur
+   * radius difference in each layer is no larger than
+   * {@code diskRadiusInterval}.
+   *
+   * @param backFocalDepth the back depth of focal layer.
+   * @param diskRadiusInterval max disk radius variation in each layer
+   * @return layerInfo layering of depth levels behind the focal depth
+   */
+  private ArrayList<LayerInfo> groupDepthLevelsBehindFocus(int backFocalDepth,
+      float diskRadiusInterval) {
+    // Initializes the layerInfo array with maximum capacity needed.
+    ArrayList<LayerInfo> layerInfo =
+        new ArrayList<LayerInfo>(diskRadiusArray.length);
+
+    if (backFocalDepth == MIN_DEPTH) {
+      return layerInfo;
+    }
+
+    // At this point, focusDepth > minDepth.
+    // Moves to the first depth behind the focus depth and initializes a layer.
+    int d = backFocalDepth - 1;
+    layerInfo.add(new LayerInfo(d));
+    // Sets up the max radius threshold for the layer.
+    float radiusThreshold = getDiskRadius(d) + diskRadiusInterval;
+
+    // Expands the layer to include depth levels so long as the blur disk
+    // radius within the layer is not larger than radiusThreshold.
+    // Stops the expansion when current depth is already the minDepth.
+    while (d > MIN_DEPTH) {
+      // Moves to the next depth.
+      d--;
+      if (getDiskRadius(d) <= radiusThreshold) {
+        // Expands the current layer by lowering its back depth.
+        int numLayers = layerInfo.size();
+        layerInfo.get(numLayers - 1).backDepth = d;
+      } else {
+        // Generates a new single-depth layer.
+        // Expands it in the next iteration if necessary.
+        layerInfo.add(new LayerInfo(d));
+        radiusThreshold = getDiskRadius(d) + diskRadiusInterval;
+      }
+    }
+    return layerInfo;
+  }
+
+  /**
+   * Groups depth levels in front of the focal depth into several layers. The
+   * blur radius difference in each layer is no larger than
+   * {@code diskRadiusInterval}.
+   *
+   * @param frontFocalDepth the back depth of focal layer.
+   * @param diskRadiusInterval max disk radius variation in each layer
+   * @return layerInfo layering of depth levels behind the focal depth
+   */
+  private ArrayList<LayerInfo> groupDepthLevelsInFrontOfFocus(
+      int frontFocalDepth, float diskRadiusInterval) {
+    // Initializes the layerInfo array with maximum capacity needed.
+    ArrayList<LayerInfo> layerInfo =
+        new ArrayList<LayerInfo>(diskRadiusArray.length);
+
+    if (frontFocalDepth == MAX_DEPTH) {
+      return layerInfo;
+    }
+
+    // At this point, focusDepth < maxDepth.
+    // Moves to the first depth in front of the focus depth and initializes a
+    // layer.
+    int d = frontFocalDepth + 1;
+    layerInfo.add(new LayerInfo(d));
+    // Sets up the max radius threshold for the layer.
+    float radiusThreshold = getDiskRadius(d) + diskRadiusInterval;
+
+    // Expands the layer to include depth levels so long as the blur disk
+    // radius within the layer is not larger than radiusThreshold.
+    // Stops the expansion when current depth is already the maxDepth.
+    while (d < MAX_DEPTH) {
+      // Moves to the next depth.
+      d++;
+      if (getDiskRadius(d) <= radiusThreshold) {
+        // Expands the current layer by increasing its front depth.
+        int numLayers = layerInfo.size();
+        layerInfo.get(numLayers - 1).frontDepth = d;
+      } else {
+        // Generates a new single-depth layer.
+        // Expands it in the next iteration if necessary.
+        layerInfo.add(new LayerInfo(d));
+        radiusThreshold = getDiskRadius(d) + diskRadiusInterval;
+      }
+    }
+    return layerInfo;
+  }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/refocus/DepthImage.java b/tests/tests/renderscript/src/android/renderscript/cts/refocus/DepthImage.java
new file mode 100644
index 0000000..31399f4
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/refocus/DepthImage.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.renderscript.cts.refocus;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.renderscript.cts.refocus.image.RangeInverseDepthTransform;
+import android.net.Uri;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+
+public class DepthImage {
+    private final String mFormat;
+    private final double mFar;
+    private final double mNear;
+    private final Bitmap mDepthBitmap;
+    private final double mBlurAtInfinity;
+    private final double mFocalDistance;
+    private final double mDepthOfFiled;
+    private final double mFocalPointX;
+    private final double mFocalPointY;
+    private final DepthTransform mDepthTransform;
+
+    public DepthImage(String format, double far, double near,
+                      Bitmap depthBitmap, double blurAtInfinity,
+                      double focalDistance, double depthOfField,
+                      double focalPointX, double focalPointY,
+                      DepthTransform depthTransform) {
+        mFormat = format;
+        mFar = far;
+        mNear = near;
+        mDepthBitmap = depthBitmap;
+        mBlurAtInfinity = blurAtInfinity;
+        mFocalDistance = focalDistance;
+        mDepthOfFiled = depthOfField;
+        mFocalPointX = focalPointX;
+        mFocalPointY = focalPointY;
+        mDepthTransform = depthTransform;
+    }
+
+    public static DepthImage createFromXMPMetadata(Context context, Uri image)
+            throws IOException {
+        InputStream input = context.getContentResolver().openInputStream(image);
+        XmpDepthDecode decode = new XmpDepthDecode(input);
+        return new DepthImage(decode.getFormat(), decode.getFar(),
+                              decode.getNear(), decode.getDepthBitmap(),
+                              decode.getBlurAtInfinity(),
+                              decode.getFocalDistance(),
+                              decode.getDepthOfField(),
+                              decode.getFocalPointX(),
+                              decode.getFocalPointY(),
+                              decode.getDepthTransform());
+    }
+
+    public static DepthImage createFromDepthmap(Context context, Uri uriDepthmap)
+            throws IOException {
+        Bitmap bitmap = BitmapFactory.decodeStream(context.getContentResolver().openInputStream(uriDepthmap));
+        if (bitmap == null) {
+            throw new FileNotFoundException(uriDepthmap.toString());
+        }
+
+        double near = 12.0;
+        double far = 120.0;
+        DepthTransform transform = new RangeInverseDepthTransform((float)near, (float)far);
+        return new DepthImage(RangeInverseDepthTransform.FORMAT,
+                              far,
+                              near,
+                              bitmap, // depthmap
+                              5.0,    // blur at ininity
+                              15.0,   // focal distance
+                              0.1,    // depth of field
+                              0.5,    // x of focal point
+                              0.5,    // y of focla point
+                              transform);
+    }
+
+    public Bitmap getDepthBitmap() {
+        return mDepthBitmap;
+    }
+
+    public DepthTransform getDepthTransform() { return mDepthTransform; }
+
+    public String getFormat() {
+        return mFormat;
+    }
+
+    public double getFar() {
+        return mFar;
+    }
+
+    public double getNear() {
+        return mNear;
+    }
+
+    public double getBlurAtInfinity() {
+        return mBlurAtInfinity;
+    }
+
+    public double getFocalDistance() {
+        return mFocalDistance;
+    }
+
+    public double getDepthOfField() {return mDepthOfFiled; }
+
+    public double getFocalPointX() {
+        return mFocalPointX;
+    }
+
+    public double getFocalPointY() {
+        return mFocalPointY;
+    }
+}
+
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/refocus/DepthOfFieldOptions.java b/tests/tests/renderscript/src/android/renderscript/cts/refocus/DepthOfFieldOptions.java
new file mode 100644
index 0000000..fee51ee
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/refocus/DepthOfFieldOptions.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.renderscript.cts.refocus;
+
+/**
+ * A struct containing all the data needed to apply a depth-of-field effect.
+ */
+public class DepthOfFieldOptions {
+  public final RGBZ rgbz;
+  public float focalDepth;
+  public float blurInfinity;
+  // The depth of field specifies the depth range in focus (i.e., zero blur) as
+  // a ratio of the focal depth. Its range is [0, 1). The depth of field range
+  // in depth units is computed as
+  // [(1 - depthOfField) * focalDepth,(1 + depthOfField) * focalDepth].
+  public float depthOfField;
+
+  /**
+   * Creates a {@code DepthOfFieldOptions} from an {@code RGBZ}.
+   *
+   * @param rgbz the {@code RGBZ} to render
+   */
+  public DepthOfFieldOptions(RGBZ rgbz) {
+    this.focalDepth = (float)rgbz.getFocusDepth();
+    this.depthOfField = (float)rgbz.getDepthOfField();
+    this.blurInfinity = (float)rgbz.getBlurInfinity();
+    this.rgbz = rgbz;
+  }
+
+  public void setFocusPoint(float x, float y) {
+    this.focalDepth = rgbz.getDepth((int)(x * rgbz.getWidth()), (int)(y * rgbz.getHeight()));
+  }
+
+  public void setBokeh(float bokeh) {
+    this.blurInfinity = bokeh * 200;
+  }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/refocus/DepthTransform.java b/tests/tests/renderscript/src/android/renderscript/cts/refocus/DepthTransform.java
new file mode 100644
index 0000000..f79003a
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/refocus/DepthTransform.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.renderscript.cts.refocus;
+
+/**
+ * Interface defining a depth transform that translates real depth values
+ * into an 8-bit quantized representation.
+ */
+public interface DepthTransform {
+    /**
+     * @return The near depth value
+     */
+    public float getNear();
+
+    /**
+     * @return The far depth value
+     */
+    public float getFar();
+
+    /**
+     * @return The format of the transform
+     */
+    public String getFormat();
+
+    /**
+     * @return the quantized value that corresponds to the given depth value
+     */
+    public int quantize(float depth);
+
+    /**
+     * @return the depth value that corresponds to the given quantized value
+     */
+    public float reconstruct(int value);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/refocus/ImageBuffersForRenderScript.java b/tests/tests/renderscript/src/android/renderscript/cts/refocus/ImageBuffersForRenderScript.java
new file mode 100644
index 0000000..9078764
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/refocus/ImageBuffersForRenderScript.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.renderscript.cts.refocus;
+
+import android.graphics.Bitmap;
+import android.renderscript.Allocation;
+import android.renderscript.RenderScript;
+
+/**
+ * A class that manages the image buffers that interface between Java and Render
+ * Script. This class will be specialized for float in f32 package and for byte
+ * in u8 package.
+ */
+public class ImageBuffersForRenderScript {
+  /**
+   * Input and output images and their corresponding Allocation to interface
+   * with Render Script. Both input and output images are unpadded images.
+   */
+  public Bitmap inputImage;
+  public Bitmap outputImage;
+  public Allocation inAllocation;
+  public Allocation outAllocation;
+
+  /**
+   * The following three member variables are used in the subclasses that extend
+   * this class. Therefore, they are protected.
+   */
+  public int imageWidthPadded;
+  public int imageHeightPadded;
+  public int paddedMargin;
+
+  public ImageBuffersForRenderScript(Bitmap inImage, int margin,
+                                     RenderScript renderScript) {
+    inputImage = inImage;
+    inAllocation = Allocation.createFromBitmap(renderScript, inputImage);
+
+    outputImage = Bitmap.createBitmap(inputImage.getWidth(),
+        inputImage.getHeight(), Bitmap.Config.ARGB_8888);
+    outAllocation = Allocation.createFromBitmap(renderScript, outputImage);
+
+    paddedMargin = margin;
+    imageWidthPadded = inputImage.getWidth() + 2 * margin;
+    imageHeightPadded = inputImage.getHeight() + 2 * margin;
+  }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/refocus/ImageCompare.java b/tests/tests/renderscript/src/android/renderscript/cts/refocus/ImageCompare.java
new file mode 100644
index 0000000..0ea2af0
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/refocus/ImageCompare.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.renderscript.cts.refocus;
+
+import android.graphics.Bitmap;
+import android.graphics.Color;
+import java.lang.Math;
+
+public class ImageCompare {
+
+    /**
+     * Compute the luma channel of an RGB image, i.e., the Y channel of the
+     * equivalent YCbCr image.
+     * https://en.wikipedia.org/wiki/YCbCr
+     */
+    private static double luma(int pixel) {
+        final int R = Color.red(pixel);
+        final int G = Color.green(pixel);
+        final int B = Color.blue(pixel);
+        return 0.299 * R + 0.587 * G + 0.114 * B;
+    }
+
+    /**
+     * Compute peak signal-to-noise ration (PSNR) between two images
+     * The greater the value of psnr, the closer the two images are to each
+     * other. For identical images, psnr = +infinity.
+     * For 8-bit images, a psnr above 50 is commonly acceptable for a lossy
+     * conversion.
+     *
+     * References:
+     * http://www.mathworks.com/help/vision/ref/psnr.html
+     * https://en.wikipedia.org/wiki/Peak_signal-to-noise_ratio
+     */
+    public static double psnr(Bitmap bitmap1, Bitmap bitmap2) {
+        if (bitmap1.getWidth() != bitmap2.getWidth() ||
+            bitmap1.getHeight() != bitmap2.getHeight()) {
+            throw new RuntimeException("images were of diffrent size");
+        }
+
+        if (bitmap1.sameAs(bitmap2)) {
+            android.util.Log.i("RefocusTest",
+                               "bitmaps verified to be identical in fast path.");
+            return Double.POSITIVE_INFINITY;
+        }
+
+        final int width = bitmap1.getWidth();
+        final int height = bitmap1.getHeight();
+        final int numPixels = width * height;
+
+        double noise = 0;
+        for (int y = 0; y < height; y++) {
+            for (int x = 0; x < width; x++) {
+                int pixel1 = bitmap1.getPixel(x, y);
+                int pixel2 = bitmap2.getPixel(x, y);
+                if (pixel1 != pixel2) {
+                    final double Y1 = luma(pixel1);
+                    final double Y2 = luma(pixel2);
+                    noise += (Y1 - Y2) * (Y1 - Y2);
+                }
+            }
+        }
+
+        final double mse = noise / numPixels;
+        final double psnr = 20 * Math.log10(255) - 10 * Math.log10(mse);
+        return psnr;
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/refocus/KernelDataForRenderScript.java b/tests/tests/renderscript/src/android/renderscript/cts/refocus/KernelDataForRenderScript.java
new file mode 100644
index 0000000..3b9139b
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/refocus/KernelDataForRenderScript.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.renderscript.cts.refocus;
+
+
+import android.renderscript.Allocation;
+import android.renderscript.Element;
+import android.renderscript.RenderScript;
+
+/**
+ * A class that manages the blur kernel matrices of a blending layer that
+ * interface between Java and Render Script. This class will be specialized for
+ * float in f32 package and for byte in u8 package.
+ *
+ */
+public class KernelDataForRenderScript {
+    /**
+     * A flag to turn on using optimized RenderScript.
+     * False means using original version; true means using the new version.
+     */
+    private static boolean UseNewRS = false;
+
+    /**
+     * Number of sub-pixels that is used to generate anti-aliased blur kernel
+     * matrix. That is, we divide one pixel into
+     * {@code NUM_SUB_PIXELS * NUM_SUB_PIXELS} sub-pixels to test whether or not a
+     * pixel is in the blur disk.
+     */
+    protected static final int NUM_SUB_PIXELS = 5;
+
+    /**
+     * The width of the pixels that are used to pad the image boundary to avoid
+     * boundary checking in filtering operation.
+     */
+    private static final int MAX_KERNEL_RADIUS =
+            computeKernelRadiusFromDiskRadius(BlurStack.getMaxDiskRadius());
+
+    /**
+     * The length of an array that concatenates all (vectorized) kernel matrices.
+     */
+    protected int stackLength;
+
+    /**
+     * A class automatically generated by Render Script compiler, which contains
+     * required auxiliary information to parse {@code kernelStack}, including the
+     * starting position of each kernel matrix in a memory buffer and the radius
+     * (radius_x,radius_y) of each kernel matrix. The names radius_x and radius_y
+     * follow C++ style because render script is C language.
+     */
+    protected ScriptField_KernelInfo kernelInfo;
+
+    /**
+     * Java array version of the current kernel info. Used when UseNewRS is true.
+     * 4*m: offset; 4*m + 1: radius_x; 4*m + 2: radius_y
+     */
+    protected float[] infoArray;
+
+    /**
+     * An allocation used to store global allocation of stack info. Used when UseNewRS is true.
+     */
+    public Allocation infoAllocation;
+
+    public static int getNumSubPixels() {
+        return NUM_SUB_PIXELS;
+    }
+
+    public static int getMaxKernelRadius() {
+        return MAX_KERNEL_RADIUS;
+    }
+
+    public static void setUseNewRS(boolean choice) {
+        UseNewRS = choice;
+    }
+
+    /**
+     * Computes the kernel matrix radius from the blur disk radius.
+     *
+     * @param diskRadius blur disk radius
+     * @return kernel matrix radius
+     */
+    public static int computeKernelRadiusFromDiskRadius(float diskRadius) {
+        return (int) (diskRadius) + 1;
+    }
+
+    public ScriptField_KernelInfo getKernelInfo() {
+        return kernelInfo;
+    }
+
+    /**
+     * Initializes {@code kernelInfo}.
+     *
+     * @param targetLayer  the index of a target layer
+     * @param blurStack    an instance of {@code BlurStack}
+     * @param renderScript an instance of {@code RenderScript}
+     */
+    protected KernelDataForRenderScript(int targetLayer, BlurStack blurStack,
+                                        RenderScript renderScript) {
+        if (UseNewRS) {
+            // Use the new version of renderscript files.
+            int numDepths = blurStack.getNumDepths(targetLayer);
+            infoAllocation = Allocation.createSized(
+                    renderScript, Element.F32_4(renderScript),
+                    numDepths);
+
+            infoArray = new float[4 * numDepths];
+            // Generates information for each blur kernel matrix.
+            int offset = 0;
+            for (int m = 0; m < numDepths; ++m) {
+                int depth = blurStack.getDepth(targetLayer, m);
+                float diskRadius = blurStack.getDiskRadius(depth);
+                int kernelRadius = computeKernelRadiusFromDiskRadius(diskRadius);
+
+                infoArray[m * 4] = offset;
+                infoArray[m * 4 + 1] = kernelRadius;
+                infoArray[m * 4 + 2] = kernelRadius;
+
+                // Updates offset variable.
+                int kernelLength = (2 * kernelRadius + 1) * (2 * kernelRadius + 1);
+                offset += kernelLength;
+            }
+            infoAllocation.copyFrom(infoArray);
+            stackLength = offset;
+        } else {
+            // Use original version of renderscript files.
+            int numDepths = blurStack.getNumDepths(targetLayer);
+            kernelInfo = new ScriptField_KernelInfo(renderScript, numDepths);
+
+            // Generates information for each blur kernel matrix.
+            int offset = 0;
+            for (int m = 0; m < numDepths; ++m) {
+                int depth = blurStack.getDepth(targetLayer, m);
+                float diskRadius = blurStack.getDiskRadius(depth);
+                int kernelRadius = computeKernelRadiusFromDiskRadius(diskRadius);
+                // Sets information for the {@code m}'th kernel matrix.
+                kernelInfo.set_offset(m, offset, true);
+                kernelInfo.set_radius_x(m, kernelRadius, true);
+                kernelInfo.set_radius_y(m, kernelRadius, true);
+                // Updates offset variable.
+                int kernelLength = (2 * kernelRadius + 1) * (2 * kernelRadius + 1);
+                offset += kernelLength;
+            }
+            stackLength = offset;
+        }
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/refocus/LayerInfo.java b/tests/tests/renderscript/src/android/renderscript/cts/refocus/LayerInfo.java
new file mode 100644
index 0000000..2cdbd69
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/refocus/LayerInfo.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.renderscript.cts.refocus;
+
+/**
+ * An object that defines a blending layer for refocus rendering, which groups
+ * several consecutive depth levels.
+ */
+public class LayerInfo {
+  public int frontDepth;
+  public int backDepth;
+
+  LayerInfo(int depth) {
+    frontDepth = depth;
+    backDepth = depth;
+  }
+
+  LayerInfo(int front, int back) {
+    frontDepth = front;
+    backDepth = back;
+  }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/refocus/MediaStoreSaver.java b/tests/tests/renderscript/src/android/renderscript/cts/refocus/MediaStoreSaver.java
new file mode 100644
index 0000000..11ecec8
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/refocus/MediaStoreSaver.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.renderscript.cts.refocus;
+
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Environment;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+/**
+ * Utility class to save images into android image database
+ */
+public class MediaStoreSaver {
+    public static final String savePNG(Bitmap bitmap,
+                                       String folderName,
+                                       String imageName,
+                                       Context mContext) {
+        File picDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
+        if (!picDir.exists() && picDir.mkdirs()) {
+            // The Pictures directory does not exist on an x86 emulator
+            picDir = mContext.getFilesDir();
+        }
+
+        File dir = new File(picDir, folderName);
+        if (!dir.exists() && !dir.mkdirs()) {
+            return "";
+        }
+
+        try {
+            File file = File.createTempFile(imageName, ".png", dir);
+            FileOutputStream fOut = new FileOutputStream(file);
+            bitmap.compress(Bitmap.CompressFormat.PNG, 0, fOut);
+            android.util.Log.v("RefocusTest", "saved image: " + file.getAbsolutePath());
+            fOut.flush();
+            fOut.close();
+            return file.getAbsolutePath();
+        } catch (FileNotFoundException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+
+        return "";
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/refocus/RGBZ.java b/tests/tests/renderscript/src/android/renderscript/cts/refocus/RGBZ.java
new file mode 100644
index 0000000..1e42bf1
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/refocus/RGBZ.java
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.renderscript.cts.refocus;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Color;
+import android.net.Uri;
+import android.renderscript.cts.refocus.image.RangeInverseDepthTransform;
+import android.util.Log;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
+/**
+ * An RGBZ image, where Z stands for depth, i.e. a color+depth image.
+ * The RGBZ always has a preview image, which represents the latest rendering of the RGBZ.
+ * The preview is encoded as the normal jpeg content for client compatibility,
+ * while the color channel and depth channels are encoded as XMP data.
+ * The class supports lazy initialization where the XMP meta data is loaded only when first
+ * accessed.
+ */
+public class RGBZ {
+  public static final String TAG = "RGBZ";
+
+  private Bitmap bitmap;
+  private Bitmap preview;
+  private Bitmap depthBitmap;
+  private DepthTransform depthTransform;
+  private DepthImage depthImage;
+
+  /**
+   * Creates an RGBZ from a content uri.
+   *
+   * @param uri The uri name of the RGBZ
+   * @throws FileNotFoundException if the RGBZ could not be read
+   */
+  public RGBZ(Uri uri, ContentResolver contentResolver, Context context) throws IOException {
+    preview = BitmapFactory.decodeStream(contentResolver.openInputStream(uri));
+    if (preview == null) {
+      throw new FileNotFoundException(uri.toString());
+    }
+    depthImage = DepthImage.createFromXMPMetadata(context, uri);
+    depthBitmap = depthImage.getDepthBitmap();
+    bitmap = setAlphaChannel(preview, depthBitmap);
+    depthTransform = depthImage.getDepthTransform();
+  }
+
+  /**
+   * Creates an RGBZ from uris to an image and a depthmap.
+   *
+   * @param uriImage The uri name of the image
+   * @param uriDepthmap The uri name of the depthmap
+   * @throws FileNotFoundException if the RGBZ could not be read
+   */
+  public RGBZ(Uri uriImage, Uri uriDepthmap, ContentResolver contentResolver,
+              Context context) throws IOException {
+    preview = BitmapFactory.decodeStream(contentResolver.openInputStream(uriImage));
+    if (preview == null) {
+      throw new FileNotFoundException(uriImage.toString());
+    }
+    depthImage = DepthImage.createFromDepthmap(context, uriDepthmap);
+    depthBitmap = depthImage.getDepthBitmap();
+    bitmap = setAlphaChannel(preview, depthBitmap);
+    depthTransform = depthImage.getDepthTransform();
+  }
+
+  /**
+   * @return Whether the RGBZ has a depth channel
+   */
+  public boolean hasDepthmap() {
+    return depthTransform != null;
+  }
+
+  /**
+   * @return The color+depth {@code Bitmap}
+   */
+  public Bitmap getBitmap() {
+    return bitmap;
+  }
+
+  /**
+   * @return The depthmap component of this RGBZ
+   */
+  public DepthTransform getDepthTransform() {
+    return depthTransform;
+  }
+
+  public double getFocusDepth() {
+    return this.depthImage.getFocalDistance();
+  }
+
+  public double getDepthOfField() {
+    return this.depthImage.getDepthOfField();
+  }
+
+  public double getBlurInfinity() {
+    return this.depthImage.getBlurAtInfinity();
+  }
+
+  /**
+   * @return the width of this {@code RGBZ}
+   */
+  public int getWidth() {
+    return bitmap.getWidth();
+  }
+
+  /**
+   * @return the height of this {@code RGBZ}
+   */
+  public int getHeight() {
+    return bitmap.getHeight();
+  }
+
+  /**
+   * @return the depth value of the given pixel
+   */
+
+  public float getDepth(int x, int y) {
+    if (!hasDepthmap()) {
+      return 0.0f;
+    }
+    if (x < 0 || x > depthBitmap.getWidth() ||
+            y < 0 || y > depthBitmap.getHeight()) {
+      Log.e("RGBZ getDepth", "index out of bound");
+      return 0;
+    }
+    return getDepthTransform().reconstruct(Color.blue(depthBitmap.getPixel(x, y)));
+  }
+
+  /**
+   * Sets the depthmap as the alpha channel of the {@code Bitmap}.
+   */
+  public Bitmap setAlphaChannel(Bitmap bitmap, Bitmap depthBitmap) {
+    if (bitmap == null) {
+      return bitmap;
+    }
+    Bitmap result = bitmap.copy(Bitmap.Config.ARGB_8888, true);
+    // set the alpha channel of depthBitmap to alpha of bitmap
+    result = setAlphaChannelFromBitmap(depthBitmap, bitmap, result);
+    return result;
+  }
+
+  private Bitmap setAlphaChannelFromBitmap(Bitmap depth, Bitmap orig, Bitmap dest) {
+    int w = orig.getWidth();
+    int h = orig.getHeight();
+    int[] orig_data = new int[w*h];
+    int[] depth_data = new int[w*h];
+
+    orig.getPixels(orig_data, 0, w, 0, 0, w, h);
+    depth.getPixels(depth_data, 0, w, 0, 0, w, h);
+    for (int i = 0; i < orig_data.length; i++) {
+      int v = orig_data[i] & 0x00FFFFFF;
+      int temp = (depth_data[i] & 0x000000FF) << 24;
+      v = v | temp;
+      orig_data[i] = v;
+    }
+    dest.setPixels(orig_data, 0, w, 0, 0, w, h);
+    return dest;
+  }
+}
+
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/refocus/RefocusFilter.java b/tests/tests/renderscript/src/android/renderscript/cts/refocus/RefocusFilter.java
new file mode 100644
index 0000000..f8c9f00
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/refocus/RefocusFilter.java
@@ -0,0 +1,229 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.renderscript.cts.refocus;
+
+import android.graphics.Bitmap;
+import android.renderscript.RenderScript;
+import android.util.Log;
+
+/**
+ * An abstract class that implements refocus filtering using Render Script. The
+ * main function is {@code compute}. All other functions and data structures are
+ * supporting this main function. Subclasses need to implement individual steps
+ * based on pixel representation, e.g., uint8 or float32.
+ *
+ * @param <ScriptType> pixel representation, which can be float of byte.
+ *
+ */
+public abstract class RefocusFilter<ScriptType> {
+  //private static final Log.Tag TAG = new Log.Tag("RefocusFilter");
+  protected static final String TAG = "RefocusFilter";
+  // Render Script context.
+  protected RenderScript renderScript;
+
+  // Script functions in .rs file.
+  protected ScriptType scriptC;
+
+  /*
+   * A constructor that initializes the class.
+   *
+   * @param rs the Render Script context.
+   */
+  public RefocusFilter(RenderScript rs) {
+    renderScript = rs;
+  }
+
+  /*
+   * A function that implements refocus filtering using Render Script.
+   *
+   * @param inputImage an RGBD image. RGB channels of the input image form the
+   * color image. The D channel has a range of [1,BlurStack.MAX_DEPTH], where 0
+   * is reserved for invalid padded pixels. Depth here refers to inverse depth
+   * (i.e., disparity), where larger depths are closer to the camera.
+   *
+   * @param blurStack an object that has all the parameters for refocus
+   * filtering, including: the number of blending layers, the depth levels in
+   * each blending layer, focal depth, etc. For details, please refer to the
+   * definition of {@code BlurStack}.
+   *
+   * @return a {@code Bitmap} of the filtering result
+   */
+  /*
+    Commented out for now to define in derived classes
+    so that images after each stage could be extracted
+   */
+  protected Bitmap compute(Bitmap inputImage, BlurStack blurStack) {
+
+    // Initializes {@code scriptC} and allocates required memory buffers
+    // (defined in subclasses) that interface between Java and Render Script.
+    initializeScriptAndBuffers(inputImage,
+        blurStack.getLayerInfo(blurStack.getFocusLayer()));
+
+    // Processes layers from back-most to focal depth (including the focal
+    // depth).
+    if (!processLayersFromBackToFocus(blurStack)) {
+      return null;
+    }
+
+    // Processes layers from front-most to focal depth (excluding the focal
+    // depth).
+    if (!processLayersFromFrontToFocus(blurStack)) {
+      return null;
+    }
+
+    // Extracts the result from .rs file to Java.
+    Bitmap resultImage = extractResultImage();
+    renderScript.finish();
+
+    Log.d(TAG, "filterAndBlendAllLayersUsingKernel is finished");
+    return resultImage;
+  }
+
+  /*
+   * Process layers from back-most to focal depth (including the focal depth).
+   */
+  protected boolean processLayersFromBackToFocus(BlurStack blurStack) {
+    for (int targetLayer = blurStack.getNumLayers() - 1;
+        targetLayer >= blurStack.getFocusLayer(); --targetLayer) {
+      // Sets up target layer info in Render Script.
+      LayerInfo layerInfo = blurStack.getLayerInfo(targetLayer);
+      setTargetLayer(layerInfo);
+
+      // For a layer that is behind the focal depth, its back depth has the
+      // largest blur kernel radius. Uses the kernel radius as dilation radius
+      // of this layer.
+      int dilationRadius = getKernelRadius(layerInfo.backDepth, blurStack);
+      setBlendInfo(dilationRadius);
+
+      // Sends blur kernel matrix data to Render Script.
+      setKernelData(targetLayer, blurStack);
+
+      // Marks active pixels (pixels that on this layer).
+      // Marks pixels that are close enough (within dilationRadius) to the
+      // active pixels.
+      // Computes distance transform of the active pixels in their neighborhood
+      // and use the distance value as matte for layer blending later.
+      computeLayerMatteBehindFocalDepth();
+
+      // Computes filtering for pixels on the target layer and saves the
+      // filtering result in a buffer {@code g_fuzzy_image} in .rs file.
+      filterLayerBehindFocalDepth();
+
+      // Replaces active pixels in {@code g_sharp_image} with the filtering
+      // result saved in {@code g_fuzzy_image}. The replacement is soft,
+      // blending {@code g_sharp_image} and {@code g_fuzzy_image} using the
+      // computed matte. Uses the blending result as the sharp input image for
+      // the next iteration.
+      updateSharpImageUsingFuzzyImage();
+    }
+    return true;
+  }
+
+  /*
+   * Processes layers from front-most to focal depth (excluding the focal depth)
+   */
+  protected boolean processLayersFromFrontToFocus(BlurStack blurStack) {
+    // At this point, the input image {@code g_sharp_image} has been updated by
+    // the first pass from back-most layer to focus layer {@code
+    // processLayersFromBackToFocus}.
+    for (int targetLayer = 0; targetLayer < blurStack.getFocusLayer();
+        ++targetLayer) {
+      // Sets up target layer info in Render Script.
+      LayerInfo layerInfo = blurStack.getLayerInfo(targetLayer);
+      setTargetLayer(layerInfo);
+
+      // For a layer that is in front of the focal depth, its front depth has
+      // the largest blur kernel radius. Uses the kernel radius as dilation
+      // radius of this layer.
+      int dilationRadius = getKernelRadius(layerInfo.frontDepth, blurStack);
+      setBlendInfo(dilationRadius);
+
+      // Sends blur kernel matrix data to Render Script.
+      setKernelData(targetLayer, blurStack);
+
+      // Marks active pixels (pixels that on this layer).
+      // Marks pixels that are close enough (within dilationRadius) to the
+      // active pixels.
+      // Computes distance transform of the active pixels in their neighborhood
+      // and use the distance value as matte for layer blending later.
+      computeLayerMatteInFrontOfFocalDepth();
+
+      // Computes filtering for pixels on the target layer and accumulates the
+      // filtering result to an buffer {@code g_fuzzy_image} in .rs file.
+      // The accumulating operation is soft, using the computed matte values.
+      filterLayerInFrontOfFocalDepth();
+    }
+
+    // Fills in the pixels on or behind the focal depth in {@code g_fuzzy_image}
+    // using pixels in {@code g_sharp_image}. Does the filling in a soft way by
+    // blending using the matte. Uses the blending result (saved in {@code
+    // g_fuzzy_image}) as the final output image.
+    finalizeFuzzyImageUsingSharpImage();
+    return true;
+  }
+
+  private static int getKernelRadius(int depth, BlurStack blurStack) {
+    int kernelRadius = KernelDataForRenderScript
+        .computeKernelRadiusFromDiskRadius(blurStack.getDiskRadius(depth));
+    return kernelRadius;
+  }
+
+  // ///////////////////////////////////////////////////////////////////////////
+  //
+  // The following abstract functions must be implemented in a subclass.
+  //
+  // ///////////////////////////////////////////////////////////////////////////
+
+  // Initializes the member {@code scriptC} and allocate memory buffers (defined
+  // in a subclass) that interface between Java and .rs file.
+  protected abstract void initializeScriptAndBuffers(Bitmap inputImage,
+      LayerInfo focalLayer);
+
+  // Extracts the result image from memory buffer.
+  protected abstract Bitmap extractResultImage();
+
+  // Sets target layer info in .rs file.
+  protected abstract void setTargetLayer(LayerInfo layerInfo);
+
+  // Sets dilation radius in .rs file for blending target layer.
+  protected abstract void setBlendInfo(int dilationRadius);
+
+  /*
+   * A function that prepares the blur kernels for the target layer and passes
+   * them to the Render Script. Each depth value in the layer has a kernel. The
+   * kernels are packed in a memory buffer. Auxiliary information for parsing
+   * the memory buffer is also prepared and passed to Render Script.
+   *
+   * @param targetLayer the index of a target layer
+   *
+   * @param blurStack a BlurStack object that has the layer structure of the
+   * refocus filter task in Java
+   */
+  protected abstract void setKernelData(int targetLayer, BlurStack blurStack);
+
+  protected abstract void computeLayerMatteBehindFocalDepth();
+
+  protected abstract void filterLayerBehindFocalDepth();
+
+  protected abstract void updateSharpImageUsingFuzzyImage();
+
+  protected abstract void computeLayerMatteInFrontOfFocalDepth();
+
+  protected abstract void filterLayerInFrontOfFocalDepth();
+
+  protected abstract void finalizeFuzzyImageUsingSharpImage();
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/refocus/RefocusTest.java b/tests/tests/renderscript/src/android/renderscript/cts/refocus/RefocusTest.java
new file mode 100644
index 0000000..042e2cc
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/refocus/RefocusTest.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.renderscript.cts.refocus;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.net.Uri;
+import android.renderscript.RenderScript;
+import android.renderscript.cts.RSBaseCompute;
+import android.util.Log;
+
+import android.renderscript.cts.R;
+
+import java.io.IOException;
+
+/**
+ * This is a test case for large real world renderscript code
+ * Many subtle issues with renderscript may not be caught by small unit test
+ */
+public class RefocusTest extends RSBaseCompute {
+    /**
+     * Test the orignal refocus code
+     */
+    public void testOriginalRefocus() {
+        refocus(RenderScriptTask.script.f32, Double.POSITIVE_INFINITY);
+    }
+
+    /**
+     * Test the new refocus code
+     */
+    public void testNewRefocus() {
+        // The new implementation may run on a GPU using relaxed floating point
+        // mathematics. Hence more relaxed precision requirement.
+        refocus(RenderScriptTask.script.d1new, 45);
+    }
+
+    /**
+     * Test a refocus operator against the refocus_reference image
+     * @param impl version of refocus to run
+     */
+    private void refocus(RenderScriptTask.script impl, double minimumPSNR) {
+        Context ctx = getContext();
+
+        RenderScript rs = RenderScript.create(ctx);
+        RGBZ current_rgbz = null;
+        try {
+            current_rgbz = new RGBZ(getResourceRef(R.drawable.test_image),
+                                    getResourceRef(R.drawable.test_depthmap),
+                                    ctx.getContentResolver(), ctx);
+        } catch (IOException e) {
+            e.printStackTrace();
+            assertNull(e);
+        }
+        DepthOfFieldOptions current_depth_options = new DepthOfFieldOptions(current_rgbz);
+        RsTaskParams rsTaskParam = new RsTaskParams(rs, current_depth_options);
+
+        RenderScriptTask renderScriptTask = new RenderScriptTask(rs, impl);
+        Bitmap outputImage = renderScriptTask.applyRefocusFilter(rsTaskParam.mOptions);
+
+        Bitmap expectedImage = BitmapFactory.decodeResource(ctx.getResources(), R.drawable.expected_output);
+
+        double psnr = ImageCompare.psnr(outputImage, expectedImage);
+        android.util.Log.i("RefocusTest", "psnr = " + String.format("%.02f", psnr));
+        if (psnr < minimumPSNR) {
+            MediaStoreSaver.savePNG(outputImage, "refocus", "refocus_output" , ctx);
+            assertTrue("Required minimum psnr = " + String.format("%.02f; ", minimumPSNR) +
+                       "Actual psnr = " + String.format("%.02f", psnr),
+                       false);
+        }
+        rs.destroy();
+    }
+
+
+    private static class RsTaskParams {
+        RenderScript mRenderScript;
+        DepthOfFieldOptions mOptions;
+
+        RsTaskParams(RenderScript renderScript,
+                     DepthOfFieldOptions options) {
+            mRenderScript = renderScript;
+            mOptions = options;
+        }
+    }
+
+    Uri getResourceRef(int resID) {
+        Context context = getContext().getApplicationContext();
+        Uri path = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" +
+                context.getResources().getResourcePackageName(resID) + '/' +
+                context.getResources().getResourceTypeName(resID) + '/' +
+                context.getResources().getResourceEntryName(resID));
+        return path;
+    }
+
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/refocus/RenderScriptTask.java b/tests/tests/renderscript/src/android/renderscript/cts/refocus/RenderScriptTask.java
new file mode 100644
index 0000000..29436c6
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/refocus/RenderScriptTask.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.renderscript.cts.refocus;
+
+import android.graphics.Bitmap;
+import android.renderscript.RenderScript;
+import android.renderscript.cts.refocus.d1new.RefocusFilterd1new;
+import android.renderscript.cts.refocus.f32.RefocusFilterF32;
+import android.util.Log;
+
+/**
+ * An wrapper class that calls the refocus filtering function in
+ * {@code RefocusFilter} class. The class also contains several default
+ * parameters that are used in calling the refocus filtering function.
+ *
+ * Example usage:
+ *
+ * {@code DepthOfFieldOptions options;}
+ * {@code RenderScriptTask renderScriptTask;}
+ * {@code Bitmap result = renderScriptTask.applyRefocusFilter(options);}
+ *
+ */
+public class RenderScriptTask {
+  enum script{f32, d1new};
+  /**
+   *	A flag to choose the version of RenderScript.
+   */
+  private script mScript = script.d1new;
+
+  /**
+   * An enum for the different types of Render Script tasks. (generated by zhl)
+   */
+  public enum Purpose {
+    VIEWER, SERVICE
+  }
+
+  //private static final Log.Tag TAG = new Log.Tag("RenderScriptTask");
+  private static final String TAG = "RenderScriptTask";
+  /**
+   * Number of blending layers in which the quantized depth levels are grouped.
+   */
+  private static final int NUM_BLENDING_LAYERS = 8;
+
+  /**
+   * An object that records the blur disk radius for each quantized inverse
+   * depth level and how all the depth levels are grouped into blending layers.
+   */
+  public BlurStack blurStack;
+
+  /**
+   * An image in which each pixel has red, green, blue, and quantized inverse
+   * depth level. The quantized inverse depth levels range from 1 to
+   * {@code BlurStack.MAX_DEPTH}. 0 is reserved for padding pixels.
+   *
+   * <b> The pixels with larger depth values are closer to the camera.
+   */
+  private Bitmap rgbdImage;
+
+  /**
+   * The Render Script context that is required to construct the filter.
+   */
+  private RenderScript renderScript;
+
+  /**
+   * A constructor of render script context.
+   *
+   * @param renderScript RenderScript context.
+   */
+  public RenderScriptTask(RenderScript renderScript, script sChoice) {
+    this.renderScript = renderScript;
+      this.mScript = sChoice;
+  }
+
+  /**
+   * A function that computes a refocused image from an instance of
+   * {@code DepthOfFieldOptions}.
+   *
+   * @param options an object contains color image, depth map, focal depth, and
+   *        the amount of desired blur ({@code blurInfinity})
+   * @return the refocus filtering result
+   */
+  public Bitmap applyRefocusFilter(DepthOfFieldOptions options) {
+    long startTime = System.currentTimeMillis();
+
+    // Generates {@code rgbdImage} and {@code blurStack}.
+    prepareRefocusFilter(options);
+    Bitmap outputImage = null;
+    // Check which version of RenderScript code is used.
+    switch (mScript) {
+      case f32:
+        RefocusFilterF32 rfFilterF32 = new RefocusFilterF32(renderScript);
+        outputImage =
+                rfFilterF32.compute(rgbdImage, blurStack);
+        break;
+      case d1new:
+        RefocusFilterd1new rfFilterd1new = new RefocusFilterd1new(renderScript);
+        outputImage =
+                rfFilterd1new.compute(rgbdImage, blurStack);
+        break;
+    }
+
+    long endTime = System.currentTimeMillis();
+    float duration = (endTime - startTime);
+    Log.d(TAG, "applyRefocusFilter is finished in " + (duration / 1000.0f)
+        + " seconds");
+
+    return outputImage;
+  }
+
+  /**
+   * A function that computes {@code rgbdImage} and {@code blurStack} from an
+   * instance of {@code DepthOfFieldOptions}.
+   *
+   * @param options an object contains color image, depth map, focal depth, and
+   *        the amount of desired blur ({@code blurInfinity}).
+   */
+  private void prepareRefocusFilter(DepthOfFieldOptions options) {
+    blurStack = BlurStack.createFromDepthTransform(
+        options.rgbz.getDepthTransform(), options.focalDepth,
+        options.depthOfField, options.blurInfinity, NUM_BLENDING_LAYERS);
+
+    rgbdImage = options.rgbz.getBitmap();
+  }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/refocus/XmpDepthDecode.java b/tests/tests/renderscript/src/android/renderscript/cts/refocus/XmpDepthDecode.java
new file mode 100644
index 0000000..ba3d068
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/refocus/XmpDepthDecode.java
@@ -0,0 +1,445 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.renderscript.cts.refocus;
+
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.renderscript.cts.refocus.image.RangeInverseDepthTransform;
+import android.renderscript.cts.refocus.image.RangeLinearDepthTransform;
+import android.util.Log;
+
+import com.adobe.xmp.XMPConst;
+import com.adobe.xmp.XMPException;
+import com.adobe.xmp.XMPIterator;
+import com.adobe.xmp.XMPMeta;
+import com.adobe.xmp.XMPMetaFactory;
+import com.adobe.xmp.properties.XMPPropertyInfo;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.List;
+
+public class XmpDepthDecode {
+    private static final String TAG = "XmpUtil";
+    private static final String XMP_DEPTHMAP = "http://ns.google.com/photos/1.0/depthmap/";
+    private static final String XMP_FOCUS = "http://ns.google.com/photos/1.0/focus/";
+    private static final String XMP_HEADER = "http://ns.adobe.com/xap/1.0/\0";
+    private static final String XMP_EXTENSION_HEADER =
+            "http://ns.adobe.com/xmp/extension/\0";
+    private static final String XMP_HAS_EXTENSION = "HasExtendedXMP";
+    private static final int XMP_EXTENSION_HEADER_GUID_SIZE =
+            XMP_EXTENSION_HEADER.length() + 32 + 1; // 32 byte GUID + 1 byte null termination.
+    private static final int XMP_EXTENSION_HEADER_OFFSET = 7;
+
+    private static final int M_SOI = 0xd8; // File start marker.
+    private static final int M_APP1 = 0xe1; // Marker for EXIF or XMP.
+    private static final int M_SOS = 0xda; // Image data marker.
+
+    private final String mFormat;
+    private final double mFar;
+    private final double mNear;
+    private final Bitmap mDepthBitmap;
+    private final double mBlurAtInfinity;
+    private final double mFocalDistance;
+    private final double mDepthOfFiled;
+    private final double mFocalPointX;
+    private final double mFocalPointY;
+    private final DepthTransform mDepthTransform;
+
+    public XmpDepthDecode(InputStream is) throws IOException {
+        XMPMeta meta = read(is, false);
+        try {
+            mFormat = meta.getPropertyString(XMP_DEPTHMAP, "GDepth:Format");
+
+            mFar = Double.parseDouble(meta.getPropertyString(XMP_DEPTHMAP, "GDepth:Far"));
+            mNear = Double.parseDouble(meta.getPropertyString(XMP_DEPTHMAP, "GDepth:Near"));
+
+            DepthTransform tDepthTransform = null;
+            String format = meta.getPropertyString(
+                    XMP_DEPTHMAP, "GDepth:Format");
+            if (RangeInverseDepthTransform.FORMAT.equals(format)) {
+              tDepthTransform = new RangeInverseDepthTransform((float)mNear, (float)mFar);
+            } else if (RangeLinearDepthTransform.FORMAT.equals(format)) {
+              tDepthTransform = new RangeLinearDepthTransform((float)mNear, (float)mFar);
+            } else {
+              Log.e(TAG, "Unknown GDepth format: " + format);
+            }
+            mDepthTransform = tDepthTransform;
+
+            byte[] data = meta.getPropertyBase64(XMP_DEPTHMAP, "GDepth:Data");
+            mDepthBitmap = BitmapFactory.decodeStream(new ByteArrayInputStream(data));
+
+            mBlurAtInfinity = Double.parseDouble(meta.getPropertyString(XMP_FOCUS, "GFocus:BlurAtInfinity"));
+            mFocalDistance = Double.parseDouble(meta.getPropertyString(XMP_FOCUS, "GFocus:FocalDistance"));
+            mDepthOfFiled = Double.parseDouble(meta.getPropertyString(XMP_FOCUS, "GFocus:DepthOfField"));
+            mFocalPointX = Double.parseDouble(meta.getPropertyString(XMP_FOCUS, "GFocus:FocalPointX"));
+            mFocalPointY = Double.parseDouble(meta.getPropertyString(XMP_FOCUS, "GFocus:FocalPointY"));
+        } catch (XMPException e) {
+            throw new IOException("XMP data missing");
+        }
+    }
+
+    public Bitmap getDepthBitmap() {
+        return mDepthBitmap;
+    }
+
+    public DepthTransform getDepthTransform() { return  mDepthTransform; }
+
+    public String getFormat() {
+        return mFormat;
+    }
+
+    public double getFar() {
+        return mFar;
+    }
+
+    public double getNear() {
+        return mNear;
+    }
+
+    public double getBlurAtInfinity() {
+        return mBlurAtInfinity;
+    }
+
+    public double getFocalDistance() {
+        return mFocalDistance;
+    }
+
+    public double getDepthOfField() { return mDepthOfFiled; }
+
+    public double getFocalPointX() {
+        return mFocalPointX;
+    }
+
+    public double getFocalPointY() {
+        return mFocalPointY;
+    }
+
+
+    // JPEG file is composed of many sections and image data. This class is used
+    // to hold the section data from image file.
+    private static class Section {
+        public int marker;
+        public int length;
+        public byte[] data;
+    }
+
+    static XMPMeta read(InputStream is, boolean skipExtendedContent) {
+        List<Section> sections = parse(is, true, skipExtendedContent);
+        if (sections == null) {
+            return null;
+        }
+
+        XMPMeta xmpMeta = parseFirstValidXMPSection(sections);
+        if (xmpMeta == null ||
+                !xmpMeta.doesPropertyExist(XMPConst.NS_XMP_NOTE, XMP_HAS_EXTENSION)) {
+            return xmpMeta;
+        }
+
+        String extensionName = null;
+        try {
+            extensionName = (String) xmpMeta.getProperty(
+                    XMPConst.NS_XMP_NOTE, XMP_HAS_EXTENSION).getValue();
+        } catch (XMPException e) {
+            e.printStackTrace();
+            return null;
+        }
+
+        if (skipExtendedContent) {
+            if (!checkExtendedSectionExists(sections, extensionName)) {
+                // The main XMP section referenced an extended section that is not present.
+                // This is an error.
+                return null;
+            }
+            return xmpMeta;
+        }
+
+        XMPMeta xmpExtended = parseExtendedXMPSections(sections, extensionName);
+        if (xmpExtended == null) {
+            // The main XMP section referenced an extended section that is not present.
+            // This is an error.
+            return null;
+        }
+
+        // Merge the extended properties into the main one.
+        try {
+            XMPIterator iterator = xmpExtended.iterator();
+            while (true) {
+                XMPPropertyInfo info = (XMPPropertyInfo) iterator.next();
+                if (info.getPath() != null) {
+                    xmpMeta.setProperty(info.getNamespace(), info.getPath(),
+                            info.getValue(), info.getOptions());
+                }
+            }
+        } catch (Exception e) {
+            // Catch XMPException and NoSuchElementException.
+        }
+        return xmpMeta;
+    }
+
+    /**
+     * Parses the JPEG image file. If readMetaOnly is true, only keeps the EXIF
+     * and XMP sections (with marker M_APP1) and ignore others; otherwise, keep
+     * all sections. The last section with image data will have -1 length.
+     *
+     * @param is                  Input image data stream
+     * @param readMetaOnly        Whether only reads the metadata in jpg
+     * @param skipExtendedContent Whether to skip the content of extended sections
+     * @return The parse result
+     */
+    private static List<Section> parse(InputStream is, boolean readMetaOnly,
+                                       boolean skipExtendedContent) {
+        List<Section> sections = new ArrayList<Section>();
+        if (is == null) {
+            return sections;
+        }
+
+        try {
+            if (is.read() != 0xff || is.read() != M_SOI) {
+                return sections;
+            }
+            int c;
+            while ((c = is.read()) != -1) {
+                if (c != 0xff) {
+                    return sections;
+                }
+                // Skip padding bytes.
+                while ((c = is.read()) == 0xff) {
+                }
+                if (c == -1) {
+                    return sections;
+                }
+                int marker = c;
+                if (marker == M_SOS) {
+                    // M_SOS indicates the image data will follow and no metadata after
+                    // that, so read all data at one time.
+                    if (!readMetaOnly) {
+                        Section section = new Section();
+                        section.marker = marker;
+                        section.length = -1;
+                        section.data = new byte[is.available()];
+                        is.read(section.data, 0, section.data.length);
+                        sections.add(section);
+                    }
+                    return sections;
+                }
+                int lh = is.read();
+                int ll = is.read();
+                if (lh == -1 || ll == -1) {
+                    return sections;
+                }
+                int length = lh << 8 | ll;
+                if (!readMetaOnly || marker == M_APP1) {
+                    sections.add(readSection(is, length, marker, skipExtendedContent));
+                } else {
+                    // Skip this section since all EXIF/XMP meta will be in M_APP1
+                    // section.
+                    is.skip(length - 2);
+                }
+            }
+            return sections;
+        } catch (IOException e) {
+            System.out.println("Could not parse file." + e);
+            return sections;
+        } finally {
+            if (is != null) {
+                try {
+                    is.close();
+                } catch (IOException e) {
+                    // Ignore.
+                }
+            }
+        }
+    }
+
+    /**
+     * Checks whether the byte array has XMP header. The XMP section contains
+     * a fixed length header XMP_HEADER.
+     *
+     * @param data   XMP metadata
+     * @param header The header to look for
+     */
+    private static boolean hasHeader(byte[] data, String header) {
+        if (data.length < header.length()) {
+            return false;
+        }
+        try {
+            byte[] buffer = new byte[header.length()];
+            System.arraycopy(data, 0, buffer, 0, header.length());
+            if (new String(buffer, "UTF-8").equals(header)) {
+                return true;
+            }
+        } catch (UnsupportedEncodingException e) {
+            return false;
+        }
+        return false;
+    }
+
+    private static Section readSection(InputStream is, int length,
+                                       int marker, boolean skipExtendedContent) throws IOException {
+        if (length - 2 < XMP_EXTENSION_HEADER_GUID_SIZE || !skipExtendedContent) {
+            Section section = new Section();
+            section.marker = marker;
+            section.length = length;
+            section.data = new byte[length - 2];
+            is.read(section.data, 0, length - 2);
+            return section;
+        }
+
+        byte[] header = new byte[XMP_EXTENSION_HEADER_GUID_SIZE];
+        is.read(header, 0, header.length);
+
+        if (hasHeader(header, XMP_EXTENSION_HEADER) && skipExtendedContent) {
+            Section section = new Section();
+            section.marker = marker;
+            section.length = header.length + 2;
+            section.data = header;
+            is.skip(length - 2 - header.length);
+            return section;
+        }
+
+        Section section = new Section();
+        section.marker = marker;
+        section.length = length;
+        section.data = new byte[length - 2];
+        System.arraycopy(header, 0, section.data, 0, header.length);
+        is.read(section.data, header.length, length - 2 - header.length);
+        return section;
+    }
+
+    /**
+     * Gets the end of the XMP meta content. If there is no packet wrapper,
+     * return data.length, otherwise return 1 + the position of last '>'
+     * without '?' before it.
+     * Usually the packet wrapper end is "<?xpacket end="w"?> but
+     * javax.xml.parsers.DocumentBuilder fails to parse it in android.
+     *
+     * @param data XMP metadata bytes
+     * @return The end of the XMP metadata content
+     */
+    private static int getXMPContentEnd(byte[] data) {
+        for (int i = data.length - 1; i >= 1; --i) {
+            if (data[i] == '>') {
+                if (data[i - 1] != '?') {
+                    return i + 1;
+                }
+            }
+        }
+        // It should not reach here for a valid XMP meta.
+        return data.length;
+    }
+
+    /**
+     * Parses the first valid XMP section. Any other valid XMP section will be
+     * ignored.
+     *
+     * @param sections The list of sections parse
+     * @return The parsed XMPMeta object
+     */
+    private static XMPMeta parseFirstValidXMPSection(List<Section> sections) {
+        for (Section section : sections) {
+            if (hasHeader(section.data, XMP_HEADER)) {
+                int end = getXMPContentEnd(section.data);
+                byte[] buffer = new byte[end - XMP_HEADER.length()];
+                System.arraycopy(
+                        section.data, XMP_HEADER.length(), buffer, 0, buffer.length);
+                try {
+                    XMPMeta result = XMPMetaFactory.parseFromBuffer(buffer);
+                    return result;
+                } catch (XMPException e) {
+                    System.out.println("XMP parse error " + e);
+                    return null;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Checks there is an extended section with the given name.
+     *
+     * @param sections    The list of sections to parse
+     * @param sectionName The name of the extended sections
+     * @return Whether there is an extended section with the given name
+     */
+    private static boolean checkExtendedSectionExists(List<Section> sections,
+                                                      String sectionName) {
+        String extendedHeader = XMP_EXTENSION_HEADER + sectionName + "\0";
+        for (Section section : sections) {
+            if (hasHeader(section.data, extendedHeader)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Parses the extended XMP sections with the given name. All other sections
+     * will be ignored.
+     *
+     * @param sections    The list of sections to parse
+     * @param sectionName The name of the extended sections
+     * @return The parsed XMPMeta object
+     */
+    private static XMPMeta parseExtendedXMPSections(List<Section> sections,
+                                                    String sectionName) {
+        String extendedHeader = XMP_EXTENSION_HEADER + sectionName + "\0";
+
+        // Compute the size of the buffer to parse the extended sections.
+        List<Section> xmpSections = new ArrayList<Section>();
+        List<Integer> xmpStartOffset = new ArrayList<Integer>();
+        List<Integer> xmpEndOffset = new ArrayList<Integer>();
+        int bufferSize = 0;
+        for (Section section : sections) {
+            if (hasHeader(section.data, extendedHeader)) {
+                int startOffset = extendedHeader.length() + XMP_EXTENSION_HEADER_OFFSET;
+                int endOffset = section.data.length;
+                bufferSize += Math.max(0, section.data.length - startOffset);
+                xmpSections.add(section);
+                xmpStartOffset.add(startOffset);
+                xmpEndOffset.add(endOffset);
+            }
+        }
+        if (bufferSize == 0) {
+            return null;
+        }
+
+        // Copy all the relevant sections' data into a buffer.
+        byte buffer[] = new byte[bufferSize];
+        int offset = 0;
+        for (int i = 0; i < xmpSections.size(); ++i) {
+            Section section = xmpSections.get(i);
+            int startOffset = xmpStartOffset.get(i);
+            int endOffset = xmpEndOffset.get(i);
+            int length = endOffset - startOffset;
+            System.arraycopy(
+                    section.data, startOffset, buffer, offset, length);
+            offset += length;
+        }
+
+        XMPMeta xmpExtended = null;
+        try {
+            xmpExtended = XMPMetaFactory.parseFromBuffer(buffer);
+        } catch (XMPException e) {
+            System.out.println("Extended XMP parse error " + e);
+            return null;
+        }
+        return xmpExtended;
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/refocus/camera_response.rsh b/tests/tests/renderscript/src/android/renderscript/cts/refocus/camera_response.rsh
new file mode 100644
index 0000000..87cf688
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/refocus/camera_response.rsh
@@ -0,0 +1,130 @@
+#ifndef CAMERA_RESPONSE_RSH
+#define CAMERA_RESPONSE_RSH
+
+// Adapt //depot/google3/geo/lightfield/refocus/image/camera_response.h|cc to
+// Render Script.
+//
+// Implementation of a three-parameter Camera Response Function as described in:
+//
+//     Comparametric Equations with Practical Applications
+//     in Quantigraphic Image Processing,
+//     by Steve Mann, IEEE TOIP 2000.
+//
+// The difference here is that we use a normalized model such
+// that f(0) = 0 and f(1) = 1. The function and its inverse is
+// given with respect to parameters a,b,c as:
+//
+//     f(q) = ((e^b + 1) * q^a / (e^b * q^a + 1))^c
+//     f^-1(q) = (x^(1/c) / (e^b - e^b * x^(1/c) + 1))^(1/a)
+//
+// The typical work flow is to first remove the response from a photograph,
+// do some computation in the radiance space, then re-apply the response to
+// the processed photo.
+
+// Quantize a float in [0,1] using an integer in [0,kLUTLength-1].
+static const int kLUTLength = 256;
+// Default parameters of the camera response function.
+static const float kDefaultA = 2.0f;
+static const float kDefaultB = 4.0f;
+static const float kDefaultC = 3.0f;
+
+rs_allocation g_lut_apply_crf_float;
+rs_allocation g_lut_remove_crf_float;
+
+typedef struct CameraResponse {
+  float a;
+  float b;
+  float c;
+  float lut_apply_crf_float[kLUTLength + 1];
+  float lut_remove_crf_float[kLUTLength + 1];
+  int lut_apply_crf_int[kLUTLength];
+  int lut_remove_crf_int[kLUTLength];
+} CameraResponse_t;
+
+static inline float ApplyCRF(float v, const CameraResponse_t* camera_response) {
+  const float pow_va = pow(v, camera_response->a);
+  const float exp_b = exp(camera_response->b);
+  const float x1 = (exp_b + 1.0f) * pow_va;
+  const float x2 = exp_b * pow_va + 1.0f;
+  return pow(x1 / x2, camera_response->c);
+}
+
+static inline float RemoveCRF(float v,
+                              const CameraResponse_t* camera_response) {
+  const float pow_vc = pow(v, 1.0f / camera_response->c);
+  const float x2 = exp(camera_response->b) * (1.0f - pow_vc) + 1.0f;
+  return pow(pow_vc / x2, 1.0f / camera_response->a);
+}
+
+static inline float ApplyCRFdefault(float v) {
+  const float pow_va = pow(v, kDefaultA);
+  const float exp_b = exp(kDefaultB);
+  const float x1 = (exp_b + 1.0f) * pow_va;
+  const float x2 = exp_b * pow_va + 1.0f;
+  return pow(x1 / x2, kDefaultC);
+}
+
+static inline float RemoveCRFdefault(float v) {
+  const float pow_vc = pow(v, 1.0f / kDefaultC);
+  const float x2 = exp(kDefaultB) * (1.0f - pow_vc) + 1.0f;
+  return pow(pow_vc / x2, 1.0f / kDefaultA);
+}
+
+static inline void ComputeLUTs(CameraResponse_t* camera_response) {
+  for (int i = 0; i < kLUTLength; ++i) {
+    const float value = i / (float)(kLUTLength - 1);
+
+    const float y = ApplyCRF(value, camera_response);
+    camera_response->lut_apply_crf_float[i] = y;
+    camera_response->lut_apply_crf_int[i] = round((kLUTLength - 1) * y);
+
+    const float x = RemoveCRF(value, camera_response);
+    camera_response->lut_remove_crf_float[i] = x;
+    camera_response->lut_remove_crf_int[i] = round((kLUTLength - 1) * x);
+  }
+
+  // Add a boundary to correctly deal with the max value in ApplyLUT.
+  camera_response->lut_apply_crf_float[kLUTLength] =
+      camera_response->lut_apply_crf_float[kLUTLength - 1];
+  camera_response->lut_remove_crf_float[kLUTLength] =
+      camera_response->lut_remove_crf_float[kLUTLength - 1];
+}
+
+static inline float ApplyLUT_Float(float value, float lut[kLUTLength + 1]) {
+  const float scaled_value = (kLUTLength - 1) * value;
+  const int pos = (int)(scaled_value);
+  const float delta = scaled_value - pos;
+  return lut[pos] + delta * (lut[pos + 1] - lut[pos]);
+}
+
+static inline float ApplyLUT_FloatAlloc(float value) {
+  const float scaled_value = (kLUTLength - 1) * value;
+  const int pos = (int)(scaled_value);
+  const float delta = scaled_value - pos;
+  float valPos = rsGetElementAt_float(g_lut_apply_crf_float, pos);
+  float valPosPlus = rsGetElementAt_float(g_lut_apply_crf_float, pos+1);
+  return valPos + delta * (valPosPlus - valPos);
+}
+
+static inline float ApplyLUT_FloatRemoveAlloc(float value) {
+  const float scaled_value = (kLUTLength - 1) * value;
+  const int pos = (int)(scaled_value);
+  const float delta = scaled_value - pos;
+  float valPos = rsGetElementAt_float(g_lut_remove_crf_float, pos);
+  float valPosPlus = rsGetElementAt_float(g_lut_remove_crf_float, pos+1);
+  return valPos + delta * (valPosPlus - valPos);
+}
+
+static inline int ApplyLUT_Int(int value, int lut[kLUTLength]) {
+  return lut[value];
+}
+
+static inline void InitializeDefaultCameraResponse(
+    CameraResponse_t* camera_response) {
+  camera_response->a = kDefaultA;
+  camera_response->b = kDefaultB;
+  camera_response->c = kDefaultC;
+  ComputeLUTs(camera_response);
+}
+
+#endif
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/refocus/camera_response_fast.rsh b/tests/tests/renderscript/src/android/renderscript/cts/refocus/camera_response_fast.rsh
new file mode 100644
index 0000000..d664fd2
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/refocus/camera_response_fast.rsh
@@ -0,0 +1,69 @@
+#ifndef CAMERA_RESPONSE_FAST_RSH
+#define CAMERA_RESPONSE_FAST_RSH
+
+// Adapt //depot/google3/geo/lightfield/refocus/image/camera_response.h|cc to
+// Render Script.
+//
+// Implementation of a three-parameter Camera Response Function as described in:
+//
+//     Comparametric Equations with Practical Applications
+//     in Quantigraphic Image Processing,
+//     by Steve Mann, IEEE TOIP 2000.
+//
+// The difference here is that we use a normalized model such
+// that f(0) = 0 and f(1) = 1. The function and its inverse is
+// given with respect to parameters a,b,c as:
+//
+//     f(q) = ((e^b + 1) * q^a / (e^b * q^a + 1))^c
+//     f^-1(q) = (x^(1/c) / (e^b - e^b * x^(1/c) + 1))^(1/a)
+//
+// The typical work flow is to first remove the response from a photograph,
+// do some computation in the radiance space, then re-apply the response to
+// the processed photo.
+
+// Quantize a float in [0,1] using an integer in [0,kLUTLength-1].
+static const int kLUTLength = 256;
+// Default parameters of the camera response function.
+static const float kDefaultA = 2.0f;
+static const float kDefaultB = 4.0f;
+static const float kDefaultC = 3.0f;
+
+rs_allocation g_lut_apply_crf_float;
+rs_allocation g_lut_remove_crf_float;
+
+
+
+static inline float ApplyCRFdefault(float v) {
+  const float pow_va = pow(v, kDefaultA);
+  const float exp_b = exp(kDefaultB);
+  const float x1 = (exp_b + 1.0f) * pow_va;
+  const float x2 = exp_b * pow_va + 1.0f;
+  return pow(x1 / x2, kDefaultC);
+}
+
+static inline float RemoveCRFdefault(float v) {
+  const float pow_vc = pow(v, 1.0f / kDefaultC);
+  const float x2 = exp(kDefaultB) * (1.0f - pow_vc) + 1.0f;
+  return pow(pow_vc / x2, 1.0f / kDefaultA);
+}
+
+
+static inline float ApplyLUT_FloatAlloc(float value) {
+  const float scaled_value = (kLUTLength - 1) * value;
+  const int pos = (int)(scaled_value);
+  const float delta = scaled_value - pos;
+  float valPos = rsGetElementAt_float(g_lut_apply_crf_float, pos);
+  float valPosPlus = rsGetElementAt_float(g_lut_apply_crf_float, pos+1);
+  return valPos + delta * (valPosPlus - valPos);
+}
+
+static inline float ApplyLUT_FloatRemoveAlloc(float value) {
+  const float scaled_value = (kLUTLength - 1) * value;
+  const int pos = (int)(scaled_value);
+  const float delta = scaled_value - pos;
+  float valPos = rsGetElementAt_float(g_lut_remove_crf_float, pos);
+  float valPosPlus = rsGetElementAt_float(g_lut_remove_crf_float, pos+1);
+  return valPos + delta * (valPosPlus - valPos);
+}
+
+#endif
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/refocus/d1new/ImageBuffersForRenderScriptd1new.java b/tests/tests/renderscript/src/android/renderscript/cts/refocus/d1new/ImageBuffersForRenderScriptd1new.java
new file mode 100644
index 0000000..ac67ef6
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/refocus/d1new/ImageBuffersForRenderScriptd1new.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.renderscript.cts.refocus.d1new;
+
+import android.graphics.Bitmap;
+import android.renderscript.Allocation;
+import android.renderscript.Element;
+import android.renderscript.RenderScript;
+import android.renderscript.cts.refocus.ImageBuffersForRenderScript;
+import android.renderscript.cts.refocus.LayerInfo;
+import android.renderscript.cts.refocus.ScriptC_layered_filter_fast_d1new;
+import android.util.Log;
+
+/**
+ * A class that manages the image buffers that interface between Java and Render
+ * Script. These buffers are specialized for float32 pixel representation.
+ */
+public class ImageBuffersForRenderScriptd1new extends
+        ImageBuffersForRenderScript {
+  /**
+   * SharpImage, FuzzyImage, and integralImage that are bound with memory in
+   * Render Script for layered filtering.
+   * Global allocation for images and meta data that are bound with memory in Render Script
+   *
+   */
+  private static final String myTAG = "RefocusFilterd1new";
+  public Allocation sharpRGBAAllocation;
+  public Allocation fuzzyRGBAAllocation;
+  public Allocation integralRGBAAllocation;
+
+  public Allocation sharpActualDepthAllocation;
+  public Allocation sharpDilatedDepthAllocation;
+  public Allocation sharpActiveAllocation;
+  public Allocation sharpMatteAllocation;
+
+  /**
+   * A constructor that allocates memory buffers in Java and binds the buffers
+   * with the global pointers in the Render Script.
+   *
+   * @param image an input (padded) RGBD image
+   * @param renderScript a RenderScript object that manages the {@code Context}
+   * in Java
+   * @param scriptC a RenderScript object that manages the filtering kernel
+   *                functions in .rs file
+   */
+  public ImageBuffersForRenderScriptd1new(Bitmap image, int margin,
+                                          RenderScript renderScript, ScriptC_layered_filter_fast_d1new scriptC) {
+    super(image, margin, renderScript);
+    sharpRGBAAllocation = Allocation.createSized(
+            renderScript, Element.F32_4(renderScript),
+            imageWidthPadded * imageHeightPadded);
+    sharpActualDepthAllocation = Allocation.createSized(
+            renderScript, Element.U8(renderScript),
+            imageWidthPadded * imageHeightPadded);
+    sharpDilatedDepthAllocation = Allocation.createSized(
+            renderScript, Element.U8(renderScript),
+            imageWidthPadded * imageHeightPadded);
+    sharpActiveAllocation = Allocation.createSized(
+            renderScript, Element.U8(renderScript),
+            imageWidthPadded * imageHeightPadded);
+    sharpMatteAllocation = Allocation.createSized(
+            renderScript, Element.U8(renderScript),
+            imageWidthPadded * imageHeightPadded);
+    fuzzyRGBAAllocation = Allocation.createSized(
+            renderScript, Element.F32_4(renderScript),
+            imageWidthPadded * imageHeightPadded);
+    integralRGBAAllocation = Allocation.createSized(
+            renderScript, Element.F32_4(renderScript),
+            imageWidthPadded * imageHeightPadded);
+
+    scriptC.set_g_sharp_RGBA(sharpRGBAAllocation);
+    scriptC.set_g_fuzzy_RGBA(fuzzyRGBAAllocation);
+    scriptC.set_g_integral_RGBA(integralRGBAAllocation);
+
+    scriptC.set_g_sharp_actual_depth(sharpActualDepthAllocation);
+    scriptC.set_g_sharp_active(sharpActiveAllocation);
+    scriptC.set_g_sharp_matte(sharpMatteAllocation);
+    scriptC.set_g_sharp_dilated_depth(sharpDilatedDepthAllocation);
+
+  }
+
+  /**
+   * A function that passes global parameters from Java to Render Script and
+   * sets up the input image.
+   *
+   * @param focalLayer a layer for the depth value interval that has zero blur.
+   * @param scriptC a RenderScript object that manages filtering kernels and
+   *        global variables in .rs file
+   */
+  public void initializeRenderScript(LayerInfo focalLayer,
+                                     ScriptC_layered_filter_fast_d1new scriptC) {
+    long startnow;
+    long endnow;
+    startnow = System.nanoTime();
+    scriptC.invoke_InitializeFast(imageWidthPadded, imageHeightPadded,
+            paddedMargin, focalLayer.frontDepth, focalLayer.backDepth);
+    endnow = System.nanoTime();
+    Log.d(myTAG, "Initialize: " + (endnow - startnow) + " ns");
+    // At this point, {@code inAllocation} contains input RGBD image in Java.
+    // {@code g_sharp_image} is a global pointer that points the focus image in
+    // Render Script. The following function copies {@code inAllocation} in
+    // Java to {@code g_sharp_image) in Render Script.
+    startnow = System.nanoTime();
+    scriptC.forEach_UnpackInputImage(inAllocation);
+    endnow = System.nanoTime();
+    Log.d(myTAG, "UnpackInputImage: " + (endnow - startnow) + " ns");
+  }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/refocus/d1new/KernelDataForRenderScriptd1new.java b/tests/tests/renderscript/src/android/renderscript/cts/refocus/d1new/KernelDataForRenderScriptd1new.java
new file mode 100644
index 0000000..babd257
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/refocus/d1new/KernelDataForRenderScriptd1new.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.renderscript.cts.refocus.d1new;
+import android.renderscript.Allocation;
+import android.renderscript.Element;
+import android.renderscript.RenderScript;
+import android.renderscript.cts.refocus.BlurStack;
+import android.renderscript.cts.refocus.KernelDataForRenderScript;
+
+import java.util.Arrays;
+
+/**
+ * A class that manages the blur kernel matrices of a blending layer that
+ * interface between Java and Render Script.
+ */
+public class KernelDataForRenderScriptd1new extends KernelDataForRenderScript {
+  /**
+   * A stack of blur kernel matrices packed into a continuous memory buffer.
+   */
+  float[] kernelStack;
+
+  /**
+   * The minimum blur disk in the stack.
+   */
+  float minDiskRadius;
+
+  /**
+   * An RenderScript Allocation for kernelStack.
+   */
+  Allocation stackAllocation;
+
+  /**
+   * Initializes {@code kernelStack} and {@code kernelInfo}.
+   *
+   * @param targetLayer the index of a target layer
+   * @param blurStack an instance of {@code BlurStack}
+   * @param renderScript an instance of {@code RenderScript}
+   */
+  public KernelDataForRenderScriptd1new(int targetLayer, BlurStack blurStack,
+                                        RenderScript renderScript) {
+    super(targetLayer, blurStack, renderScript);
+    // stackLength is set in super.
+
+    kernelStack = new float[stackLength];
+    int numDepths = blurStack.getNumDepths(targetLayer);
+    minDiskRadius = BlurStack.getMaxDiskRadius();
+    for (int m = 0; m < numDepths; ++m) {
+      int depth = blurStack.getDepth(targetLayer, m);
+      float diskRadius = blurStack.getDiskRadius(depth);
+      float[] kernelMatrix = getKernel(diskRadius);
+      //System.arraycopy(kernelMatrix, 0, kernelStack, kernelInfo.get_offset(m),
+        //  kernelMatrix.length);
+      System.arraycopy(kernelMatrix, 0, kernelStack, (int)infoArray[4*m],
+          kernelMatrix.length);
+      minDiskRadius = Math.min(minDiskRadius, diskRadius);
+    }
+
+  stackAllocation = Allocation.createSized(renderScript,
+      Element.F32(renderScript), kernelStack.length);
+  stackAllocation.copyFrom(kernelStack);
+  }
+
+  /**
+   * Returns the kernel matrix of a depth level.
+   *
+   * @param diskRadius disk radius of the kernel.
+   * @return the kernel matrix of the disk radius.
+   */
+  public float[] getKernel(float diskRadius) {
+    int kernelRadius = computeKernelRadiusFromDiskRadius(diskRadius);
+    return generateDiskKernelArray(diskRadius, kernelRadius);
+  }
+
+  /**
+   * Generates a blur kernel matrix for a blur disk with radius
+   * {@code diskRadius}.
+   *
+   * @param diskRadius radius of blur disk
+   * @param kernelRadius radius of blur kernel matrix
+   * @return a kernel matrix represented as an array
+   */
+  private static float[] generateDiskKernelArray(float diskRadius,
+      int kernelRadius) {
+    int kernelDim = 2 * kernelRadius + 1;
+    int kernelLength = kernelDim * kernelDim;
+
+    float[] kernel = new float[kernelLength];
+    Arrays.fill(kernel, 0);
+
+    // Generates {@code NUM_SUB_PIXELS*NUM_SUB_PIXELS} sub-pixel shifts {@code
+    // (dx,dy)} uniformly within [-0.5,0.5]*[-0.5,0.5].
+    // For each shift, tests whether or not the shifted pixel is within the
+    // disc and accumulates the count.
+    float diskRadius2 = diskRadius * diskRadius;
+    float dy0 = -0.5f + 1.0f / (2 * getNumSubPixels());
+    float dx0 = -0.5f + 1.0f / (2 * getNumSubPixels());
+
+    float sumKernelValues = 0;
+    for (int v = 0; v < getNumSubPixels(); ++v) {
+      float dy = dy0 + (float) v / (float) getNumSubPixels();
+      for (int u = 0; u < getNumSubPixels(); ++u) {
+        float dx = dx0 + (float) u / (float) getNumSubPixels();
+        for (int y = 0; y < kernelDim; ++y) {
+          float yf = y - kernelRadius + dy;
+          for (int x = 0; x < kernelDim; ++x) {
+            float xf = x - kernelRadius + dx;
+            if (yf * yf + xf * xf <= diskRadius2) {
+              kernel[y * kernelDim + x] += 1;
+              sumKernelValues += 1;
+            }
+          }
+        }
+      }
+    }
+
+    // Normalizes kernel elements such that they sum up to 1.
+    for (int n = 0; n < kernelLength; ++n) {
+      kernel[n] /= sumKernelValues;
+    }
+
+    return kernel;
+  }
+
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/refocus/d1new/RefocusFilterd1new.java b/tests/tests/renderscript/src/android/renderscript/cts/refocus/d1new/RefocusFilterd1new.java
new file mode 100644
index 0000000..3942982
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/refocus/d1new/RefocusFilterd1new.java
@@ -0,0 +1,272 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.renderscript.cts.refocus.d1new;
+
+import android.graphics.Bitmap;
+import android.renderscript.Allocation;
+import android.renderscript.RenderScript;
+
+import android.renderscript.Script;
+import android.renderscript.cts.refocus.BlurStack;
+import android.renderscript.cts.refocus.KernelDataForRenderScript;
+import android.renderscript.cts.refocus.LayerInfo;
+import android.renderscript.cts.refocus.MediaStoreSaver;
+import android.renderscript.cts.refocus.RefocusFilter;
+import android.renderscript.cts.refocus.ScriptC_layered_filter_fast_d1new;
+import android.util.Log;
+
+/**
+ * An accelerated implementation of RefocusFilter using float32 as pixel
+ * representation. The corresponding RenderScript class is
+ * ScriptC_layered_filter_Fast. Integral image is used for the speedup.
+ *
+ * Example Usage:
+ *
+ * {@code RenderScript renderScript = RenderScript.create(context);}
+ * {@code RefocusFilterd1new rfFilter = new RefocusFilterd1new(renderScript);}
+ * {@code ProgressCallback progress;}
+ * {@code Bitmap result = rfFilter.compute(rgbdImage, blurStack, progress);}
+ */
+public class RefocusFilterd1new extends
+        RefocusFilter<ScriptC_layered_filter_fast_d1new> {
+  private static final String myTAG = "RefocusFilterd1new";
+  private static final boolean ENABLE_FAST_FILTER = true;
+  private static final float MIN_DISC_RADIUS_FOR_FAST_FILTER = 3;
+  boolean useFastFilterForCurrentLayer = false;
+  ImageBuffersForRenderScriptd1new buffers;
+
+  public RefocusFilterd1new(RenderScript rs) {
+    super(rs);
+  }
+
+  @Override
+  protected void initializeScriptAndBuffers(Bitmap inputImage,
+      LayerInfo focalLayer) {
+    scriptC = new ScriptC_layered_filter_fast_d1new(renderScript);
+
+    // Allocates, binds, and initializes buffers that interface between Java
+    // and Render Script.
+    // + 1 is for the boundary case of using integral image.
+    KernelDataForRenderScript.setUseNewRS(true);
+    int margin = KernelDataForRenderScript.getMaxKernelRadius() + 1;
+    buffers = new ImageBuffersForRenderScriptd1new(inputImage, margin,
+        renderScript, scriptC);
+    buffers.initializeRenderScript(focalLayer, scriptC);
+  }
+
+  @Override
+  protected Bitmap extractResultImage() {
+    // Extracts the result from .rs file to {@code buffers.outputImage} in Java.
+    long startnow;
+    long endnow;
+    startnow = System.nanoTime();
+    scriptC.forEach_PackOutputImage(buffers.outAllocation);
+    endnow = System.nanoTime();
+    Log.d(myTAG, "PackOutputImage: "+(endnow - startnow)+ " ns" );
+
+    buffers.outAllocation.copyTo(buffers.outputImage);
+    return buffers.outputImage;
+  }
+
+  /*
+   * Utility Method to extract intermediatory result
+   */
+  private  void extractSharpImage(String name) {
+
+    Bitmap mBitmap = Bitmap.createBitmap(buffers.inputImage.getWidth(),
+            buffers.inputImage.getHeight(), Bitmap.Config.ARGB_8888);
+    Allocation mAllocation = Allocation.createFromBitmap(renderScript, mBitmap);
+    scriptC.forEach_PackSharpImage(mAllocation);
+
+    mAllocation.copyTo(mBitmap);
+    MediaStoreSaver.savePNG(mBitmap, "sharpd1new", name, renderScript.getApplicationContext());
+  }
+  /*
+   * Utility Method to extract intermediatory result
+   */
+  private  void extractFuzzyImage(String name) {
+
+    Bitmap mBitmap = Bitmap.createBitmap(buffers.inputImage.getWidth(),
+            buffers.inputImage.getHeight(), Bitmap.Config.ARGB_8888);
+    Allocation mAllocation = Allocation.createFromBitmap(renderScript, mBitmap);
+    scriptC.forEach_PackFuzzyImage(mAllocation);
+
+    mAllocation.copyTo(mBitmap);
+    MediaStoreSaver.savePNG(mBitmap, "fuzzyd1new", name, renderScript.getApplicationContext());
+  }
+
+  @Override
+  protected void setTargetLayer(LayerInfo layerInfo) {
+    scriptC.invoke_SetTargetLayer(layerInfo.frontDepth, layerInfo.backDepth);
+  }
+
+  @Override
+  protected void setBlendInfo(int dilationRadius) {
+    scriptC.invoke_SetBlendInfo(dilationRadius);
+  }
+
+  @Override
+  protected void setKernelData(int targetLayer, BlurStack blurStack) {
+    KernelDataForRenderScriptd1new kernelData =
+        new KernelDataForRenderScriptd1new(targetLayer, blurStack, renderScript);
+
+    if (ENABLE_FAST_FILTER
+        && kernelData.minDiskRadius > MIN_DISC_RADIUS_FOR_FAST_FILTER) {
+      useFastFilterForCurrentLayer = true;
+    } else {
+      useFastFilterForCurrentLayer = false;
+    }
+    scriptC.set_g_kernel_stack(kernelData.stackAllocation);
+    scriptC.set_galloc_kernel_info(kernelData.infoAllocation);
+  }
+
+  @Override
+  protected void computeLayerMatteBehindFocalDepth() {
+    // Marks active pixels (pixels that are on this target layer);
+    // Marks adjacent pixels that are close enough to active pixels;
+    long startnow;
+    long endnow;
+
+    startnow = System.nanoTime();
+    //scriptC.forEach_MarkLayerMask(buffers.inAllocation);
+    // Pass sharp meta allocation directly into the kernel
+    scriptC.forEach_MarkLayerMaskPassInput(buffers.sharpActualDepthAllocation, buffers.sharpDilatedDepthAllocation);
+    endnow = System.nanoTime();
+    Log.d(myTAG, "MarkLayerMask: "+(endnow - startnow)+ " ns" );
+
+    startnow = System.nanoTime();
+    //scriptC.forEach_ComputeLayerMatteBehindFocalDepth(buffers.inAllocation);
+    // Pass g_sharp_meta into kernel and get updated g_sharp_meta
+    scriptC.forEach_ComputeLayerMatteBehindFocalDepthPassInput(buffers.sharpDilatedDepthAllocation, buffers.sharpDilatedDepthAllocation);
+    endnow = System.nanoTime();
+    Log.d(myTAG, "ComputeLayerMatteBehindFocalDepth: "+(endnow - startnow)+ " ns" );
+  }
+
+  @Override
+  protected void filterLayerBehindFocalDepth() {
+    // Filters the target layer and saves the result to {@code g_accum_map} in
+    // .rs file.
+    long startnow;
+    long endnow;
+
+    if (useFastFilterForCurrentLayer) {
+      scriptC.invoke_SetUseIntegralImage(1);
+      Script.LaunchOptions launchOptions = new Script.LaunchOptions();
+      launchOptions.setX(0, 1);
+      launchOptions.setY(0, buffers.inputImage.getHeight());
+
+      startnow = System.nanoTime();
+      scriptC.forEach_ComputeIntegralImageForLayerBehindFocalDepth(
+          buffers.inAllocation, launchOptions);
+      endnow = System.nanoTime();
+      Log.d(myTAG, "ComputeIntegralImageForLayerBehindFocalDepth: "+(endnow - startnow)+ " ns" );
+    } else {
+      scriptC.invoke_SetUseIntegralImage(0);
+    }
+
+    startnow = System.nanoTime();
+    //scriptC.forEach_FilterLayerBehindFocalDepth(buffers.inAllocation);
+    // Pass g_fuzzy_RGBA into kernel and get g_fuzzy_RGBA as output
+    scriptC.forEach_FilterLayerBehindFocalDepthPassInput(buffers.fuzzyRGBAAllocation, buffers.fuzzyRGBAAllocation);
+    endnow = System.nanoTime();
+    Log.d(myTAG, "FilterLayerBehindFocalDepth: "+(endnow - startnow)+ " ns" );
+    //extractFuzzyImage("fuzzy_behind");
+    //extractSharpImage("sharp_behind");
+  }
+
+  @Override
+  protected void updateSharpImageUsingFuzzyImage() {
+    long startnow;
+    long endnow;
+
+    startnow = System.nanoTime();
+
+    //scriptC.forEach_UpdateSharpImageUsingFuzzyImage(buffers.inAllocation);
+    // Pass input and output version of UpdateSharpImageUsingFuzzyImage
+		scriptC.forEach_UpdateSharpUsingFuzzyPassInput(buffers.sharpDilatedDepthAllocation, buffers.sharpDilatedDepthAllocation);
+
+		endnow = System.nanoTime();
+		Log.d(myTAG, "updateSharpImageUsingFuzzyImage: "+(endnow - startnow)+ " ns" );
+    //extractSharpImage("sharp_update");
+  }
+
+  @Override
+  protected void computeLayerMatteInFrontOfFocalDepth() {
+    // Marks active pixels (pixels that are on this target layer);
+    // Marks adjacent pixels that are close enough to active pixels;
+    long startnow;
+    long endnow;
+
+    startnow = System.nanoTime();
+    //scriptC.forEach_MarkLayerMask(buffers.inAllocation);
+    // Pass sharp meta allocation directly into the kernel
+    scriptC.forEach_MarkLayerMaskPassInput(buffers.sharpActualDepthAllocation, buffers.sharpDilatedDepthAllocation);
+    endnow = System.nanoTime();
+    Log.d(myTAG, "MarkLayerMask: "+(endnow - startnow)+ " ns" );
+
+    startnow = System.nanoTime();
+    //scriptC.forEach_ComputeLayerMatteInFrontOfFocalDepth(buffers.inAllocation);
+    // Pass g_sharp_meta and g_fuzzy_RGBA directly into the kernel
+    scriptC.forEach_ComputeLayerMatteInFrontOfFocalDepthPassInput(buffers.sharpDilatedDepthAllocation, buffers.sharpDilatedDepthAllocation);
+    endnow = System.nanoTime();
+    Log.d(myTAG, "ComputeLayerMatteInFrontOfFocalDepth: "+(endnow - startnow)+ " ns" );
+  }
+
+  @Override
+  protected void filterLayerInFrontOfFocalDepth() {
+    // Filters the target layer and accumulates the result to {@code
+    // g_accum_map} in .rs file.
+    long startnow;
+    long endnow;
+    if (useFastFilterForCurrentLayer) {
+      scriptC.invoke_SetUseIntegralImage(1);
+      Script.LaunchOptions launchOptions = new Script.LaunchOptions();
+      launchOptions.setX(0, 1);
+      launchOptions.setY(0, buffers.inputImage.getHeight());
+
+      startnow = System.nanoTime();
+      scriptC.forEach_ComputeIntegralImageForLayerInFrontOfFocalDepth(
+          buffers.inAllocation, launchOptions);
+      endnow = System.nanoTime();
+      Log.d(myTAG, "ComputeIntegralImageForLayerInFrontOfFocalDepth: "+(endnow - startnow)+ " ns" );
+    } else {
+      scriptC.invoke_SetUseIntegralImage(0);
+    }
+    startnow = System.nanoTime();
+    //scriptC.forEach_FilterLayerInFrontOfFocalDepth(buffers.inAllocation);
+    // Pass g_sharp_dilated_depth into kernel and get g_fuzzy_RGBA as output
+    scriptC.forEach_FilterLayerInFrontOfFocalDepthPassInput(buffers.sharpDilatedDepthAllocation, buffers.sharpDilatedDepthAllocation);
+    endnow = System.nanoTime();
+    Log.d(myTAG, "FilterLayerInFrontOfFocalDepth: "+(endnow - startnow)+ " ns" );
+
+    //extractFuzzyImage("fuzzy_front");
+    //extractSharpImage("sharp_front");
+  }
+
+  @Override
+  protected void finalizeFuzzyImageUsingSharpImage() {
+    // Blends {@code g_accum_map} and {@code g_focus_map} in .rs file.
+    // Saves the result in {@code g_accum_map}.
+    long startnow;
+    long endnow;
+    startnow = System.nanoTime();
+    scriptC.forEach_FinalizeFuzzyImageUsingSharpImage(buffers.inAllocation);
+    //scriptC.forEach_FinalizeFuzzyImageUsingSharpImagePassInput(buffers.sharpActualDepthAllocation, buffers.fuzzyRGBAAllocation);
+    endnow = System.nanoTime();
+    Log.d(myTAG, "finalizeFuzzyImageUsingSharpImage: "+(endnow - startnow)+ " ns" );
+  }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/refocus/f32/ImageBuffersForRenderScriptF32.java b/tests/tests/renderscript/src/android/renderscript/cts/refocus/f32/ImageBuffersForRenderScriptF32.java
new file mode 100644
index 0000000..53e6e55
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/refocus/f32/ImageBuffersForRenderScriptF32.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.renderscript.cts.refocus.f32;
+
+import android.graphics.Bitmap;
+import android.renderscript.Allocation;
+import android.renderscript.Element;
+import android.renderscript.RenderScript;
+import android.renderscript.cts.refocus.ImageBuffersForRenderScript;
+import android.renderscript.cts.refocus.LayerInfo;
+import android.renderscript.cts.refocus.ScriptC_layered_filter_fast_f32;
+
+import android.util.Log;
+
+/**
+ * A class that manages the image buffers that interface between Java and Render
+ * Script. These buffers are specialized for float32 pixel representation.
+ */
+public class ImageBuffersForRenderScriptF32 extends
+        ImageBuffersForRenderScript {
+  /**
+   * SharpImage, FuzzyImage, and integralImage that are bound with memory in
+   * Render Script for layered filtering.
+   */
+  private static final String myTAG = "RefocusFilterF32";
+  public Allocation sharpImageAllocation;
+  public Allocation fuzzyImageAllocation;
+  public Allocation integralImageAllocation;
+
+  /**
+   * A constructor that allocates memory buffers in Java and binds the buffers
+   * with the global pointers in the Render Script.
+   *
+   * @param image an input (padded) RGBD image
+   * @param renderScript a RenderScript object that manages the {@code Context}
+   *        in Java
+   * @param scriptC a RenderScript object that manages the filtering kernel
+   *        functions in .rs file
+   */
+  public ImageBuffersForRenderScriptF32(Bitmap image, int margin,
+      RenderScript renderScript, ScriptC_layered_filter_fast_f32 scriptC) {
+    super(image, margin, renderScript);
+
+    sharpImageAllocation = Allocation.createSized(
+        renderScript, Element.F32_4(renderScript),
+        imageWidthPadded * imageHeightPadded);
+
+    fuzzyImageAllocation = Allocation.createSized(
+        renderScript, Element.F32_4(renderScript),
+        imageWidthPadded * imageHeightPadded);
+
+    integralImageAllocation = Allocation.createSized(renderScript,
+        Element.F32_4(renderScript), imageWidthPadded * imageHeightPadded);
+
+    scriptC.bind_g_sharp_image_buffer(sharpImageAllocation);
+    scriptC.bind_g_fuzzy_image_buffer(fuzzyImageAllocation);
+    scriptC.bind_g_integral_image_buffer(integralImageAllocation);
+  }
+
+  /**
+   * A function that passes global parameters from Java to Render Script and
+   * sets up the input image.
+   *
+   * @param focalLayer a layer for the depth value interval that has zero blur.
+   * @param scriptC a RenderScript object that manages filtering kernels and
+   *        global variables in .rs file
+   */
+  public void initializeRenderScript(LayerInfo focalLayer,
+      ScriptC_layered_filter_fast_f32 scriptC) {
+    long startnow;
+    long endnow;
+
+    startnow = System.nanoTime();
+    scriptC.invoke_InitializeF32(imageWidthPadded, imageHeightPadded,
+        paddedMargin, focalLayer.frontDepth, focalLayer.backDepth);
+    endnow = System.nanoTime();
+    Log.d(myTAG, "Initialize: " + (endnow - startnow) + " ns");
+    // At this point, {@code inAllocation} contains input RGBD image in Java.
+    // {@code g_sharp_image} is a global pointer that points the focus image in
+    // Render Script. The following function copies {@code inAllocation} in
+    // Java to {@code g_sharp_image) in Render Script.
+    startnow = System.nanoTime();
+    scriptC.forEach_UnpackInputImage(inAllocation);
+    endnow = System.nanoTime();
+    Log.d(myTAG, "UnpackInputImage: " + (endnow - startnow) + " ns");
+  }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/refocus/f32/KernelDataForRenderScriptF32.java b/tests/tests/renderscript/src/android/renderscript/cts/refocus/f32/KernelDataForRenderScriptF32.java
new file mode 100644
index 0000000..b2e99f0
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/refocus/f32/KernelDataForRenderScriptF32.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.renderscript.cts.refocus.f32;
+
+import android.renderscript.Allocation;
+import android.renderscript.Element;
+import android.renderscript.RenderScript;
+import android.renderscript.cts.refocus.BlurStack;
+import android.renderscript.cts.refocus.KernelDataForRenderScript;
+
+import java.util.Arrays;
+
+/**
+ * A class that manages the blur kernel matrices of a blending layer that
+ * interface between Java and Render Script.
+ */
+public class KernelDataForRenderScriptF32 extends KernelDataForRenderScript {
+  /**
+   * A stack of blur kernel matrices packed into a continuous memory buffer.
+   */
+  float[] kernelStack;
+
+  /**
+   * The minimum blur disk in the stack.
+   */
+  float minDiskRadius;
+
+  /**
+   * An RenderScript Allocation for kernelStack.
+   */
+  Allocation stackAllocation;
+
+  /**
+   * Initializes {@code kernelStack} and {@code kernelInfo}.
+   *
+   * @param targetLayer the index of a target layer
+   * @param blurStack an instance of {@code BlurStack}
+   * @param renderScript an instance of {@code RenderScript}
+   */
+  public KernelDataForRenderScriptF32(int targetLayer, BlurStack blurStack,
+      RenderScript renderScript) {
+    super(targetLayer, blurStack, renderScript);
+    // stackLength is set in super.
+
+    kernelStack = new float[stackLength];
+    int numDepths = blurStack.getNumDepths(targetLayer);
+    minDiskRadius = BlurStack.getMaxDiskRadius();
+    for (int m = 0; m < numDepths; ++m) {
+      int depth = blurStack.getDepth(targetLayer, m);
+      float diskRadius = blurStack.getDiskRadius(depth);
+      float[] kernelMatrix = getKernel(diskRadius);
+      System.arraycopy(kernelMatrix, 0, kernelStack, kernelInfo.get_offset(m),
+          kernelMatrix.length);
+      minDiskRadius = Math.min(minDiskRadius, diskRadius);
+    }
+
+    stackAllocation = Allocation.createSized(renderScript,
+        Element.F32(renderScript), kernelStack.length);
+    stackAllocation.copyFrom(kernelStack);
+  }
+
+  /**
+   * Returns the kernel matrix of a depth level.
+   *
+   * @param diskRadius disk radius of the kernel.
+   * @return the kernel matrix of the disk radius.
+   */
+  public float[] getKernel(float diskRadius) {
+    int kernelRadius = computeKernelRadiusFromDiskRadius(diskRadius);
+    return generateDiskKernelArray(diskRadius, kernelRadius);
+  }
+
+  /**
+   * Generates a blur kernel matrix for a blur disk with radius
+   * {@code diskRadius}.
+   *
+   * @param diskRadius radius of blur disk
+   * @param kernelRadius radius of blur kernel matrix
+   * @return a kernel matrix represented as an array
+   */
+  private static float[] generateDiskKernelArray(float diskRadius,
+      int kernelRadius) {
+    int kernelDim = 2 * kernelRadius + 1;
+    int kernelLength = kernelDim * kernelDim;
+
+    float[] kernel = new float[kernelLength];
+    Arrays.fill(kernel, 0);
+
+    // Generates {@code NUM_SUB_PIXELS*NUM_SUB_PIXELS} sub-pixel shifts {@code
+    // (dx,dy)} uniformly within [-0.5,0.5]*[-0.5,0.5].
+    // For each shift, tests whether or not the shifted pixel is within the
+    // disc and accumulates the count.
+    float diskRadius2 = diskRadius * diskRadius;
+    float dy0 = -0.5f + 1.0f / (2 * getNumSubPixels());
+    float dx0 = -0.5f + 1.0f / (2 * getNumSubPixels());
+
+    float sumKernelValues = 0;
+    for (int v = 0; v < getNumSubPixels(); ++v) {
+      float dy = dy0 + (float) v / (float) getNumSubPixels();
+      for (int u = 0; u < getNumSubPixels(); ++u) {
+        float dx = dx0 + (float) u / (float) getNumSubPixels();
+        for (int y = 0; y < kernelDim; ++y) {
+          float yf = y - kernelRadius + dy;
+          for (int x = 0; x < kernelDim; ++x) {
+            float xf = x - kernelRadius + dx;
+            if (yf * yf + xf * xf <= diskRadius2) {
+              kernel[y * kernelDim + x] += 1;
+              sumKernelValues += 1;
+            }
+          }
+        }
+      }
+    }
+
+    // Normalizes kernel elements such that they sum up to 1.
+    for (int n = 0; n < kernelLength; ++n) {
+      kernel[n] /= sumKernelValues;
+    }
+
+    return kernel;
+  }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/refocus/f32/RefocusFilterF32.java b/tests/tests/renderscript/src/android/renderscript/cts/refocus/f32/RefocusFilterF32.java
new file mode 100644
index 0000000..35b0bd4
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/refocus/f32/RefocusFilterF32.java
@@ -0,0 +1,258 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.renderscript.cts.refocus.f32;
+
+
+import android.graphics.Bitmap;
+
+import android.renderscript.Allocation;
+import android.renderscript.RenderScript;
+import android.renderscript.Script;
+import android.util.Log;
+
+import android.renderscript.cts.refocus.BlurStack;
+import android.renderscript.cts.refocus.KernelDataForRenderScript;
+import android.renderscript.cts.refocus.LayerInfo;
+import android.renderscript.cts.refocus.MediaStoreSaver;
+import android.renderscript.cts.refocus.RefocusFilter;
+import android.renderscript.cts.refocus.ScriptC_layered_filter_fast_f32;
+
+/**
+ * An accelerated implementation of RefocusFilter using float32 as pixel
+ * representation. The corresponding RenderScript class is
+ * ScriptC_layered_filter_f32. Integral image is used for the speedup.
+ *
+ * Example Usage:
+ *
+ * {@code RenderScript renderScript = RenderScript.create(context);}
+ * {@code RefocusFilterF32 rfFilter = new RefocusFilterF32(renderScript);}
+ * {@code ProgressCallback progress;}
+ * {@code Bitmap result = rfFilter.compute(rgbdImage, blurStack, progress);}
+ *
+ */
+public class RefocusFilterF32 extends
+    RefocusFilter<ScriptC_layered_filter_fast_f32> {
+  private static final String myTAG = "RefocusFilterF32";
+  private static final boolean ENABLE_FAST_FILTER = true;
+  private static final float MIN_DISC_RADIUS_FOR_FAST_FILTER = 3;
+  boolean useFastFilterForCurrentLayer = false;
+  ImageBuffersForRenderScriptF32 buffers;
+
+  public RefocusFilterF32(RenderScript rs) {
+    super(rs);
+  }
+
+  @Override
+  protected void initializeScriptAndBuffers(Bitmap inputImage,
+      LayerInfo focalLayer) {
+    scriptC = new ScriptC_layered_filter_fast_f32(renderScript);
+
+    // Allocates, binds, and initializes buffers that interface between Java
+    // and Render Script.
+    // + 1 is for the boundary case of using integral image.
+    KernelDataForRenderScript.setUseNewRS(false);
+    int margin = KernelDataForRenderScript.getMaxKernelRadius() + 1;
+    buffers = new ImageBuffersForRenderScriptF32(inputImage, margin,
+        renderScript, scriptC);
+    buffers.initializeRenderScript(focalLayer, scriptC);
+  }
+
+  @Override
+  protected Bitmap extractResultImage() {
+    // Extracts the result from .rs file to {@code buffers.outputImage} in Java.
+    long startnow;
+    long endnow;
+    startnow = System.nanoTime();
+    scriptC.forEach_PackOutputImage(buffers.outAllocation);
+    endnow = System.nanoTime();
+    Log.d(myTAG, "PackOutputImage: "+(endnow - startnow)+ " ns" );
+
+    buffers.outAllocation.copyTo(buffers.outputImage);
+    return buffers.outputImage;
+  }
+
+  /*
+   * Utility Method to extract intermediatory result
+   */
+  private  void extractSharpImage(String name) {
+
+    Bitmap mBitmap = Bitmap.createBitmap(buffers.inputImage.getWidth(),
+            buffers.inputImage.getHeight(), Bitmap.Config.ARGB_8888);
+    Allocation mAllocation = Allocation.createFromBitmap(renderScript, mBitmap);
+    scriptC.forEach_PackSharpImage(mAllocation);
+
+    mAllocation.copyTo(mBitmap);
+    MediaStoreSaver.savePNG(mBitmap, "sharpF32", name, renderScript.getApplicationContext());
+  }
+  /*
+   * Utility Method to extract intermediatory result
+   */
+  private  void extractFuzzyImage(String name) {
+
+    Bitmap mBitmap = Bitmap.createBitmap(buffers.inputImage.getWidth(),
+            buffers.inputImage.getHeight(), Bitmap.Config.ARGB_8888);
+    Allocation mAllocation = Allocation.createFromBitmap(renderScript, mBitmap);
+    scriptC.forEach_PackFuzzyImage(mAllocation);
+
+    mAllocation.copyTo(mBitmap);
+    MediaStoreSaver.savePNG(mBitmap, "fuzzyF32", name, renderScript.getApplicationContext());
+  }
+
+  @Override
+  protected void setTargetLayer(LayerInfo layerInfo) {
+    scriptC.invoke_SetTargetLayer(layerInfo.frontDepth, layerInfo.backDepth);
+  }
+
+  @Override
+  protected void setBlendInfo(int dilationRadius) {
+    scriptC.invoke_SetBlendInfo(dilationRadius);
+  }
+
+  @Override
+  protected void setKernelData(int targetLayer, BlurStack blurStack) {
+    KernelDataForRenderScriptF32 kernelData =
+        new KernelDataForRenderScriptF32(targetLayer, blurStack, renderScript);
+
+    if (ENABLE_FAST_FILTER
+        && kernelData.minDiskRadius > MIN_DISC_RADIUS_FOR_FAST_FILTER) {
+      useFastFilterForCurrentLayer = true;
+    } else {
+      useFastFilterForCurrentLayer = false;
+    }
+
+    scriptC.bind_g_kernel_info(kernelData.getKernelInfo());
+    scriptC.bind_g_kernel_stack(kernelData.stackAllocation);
+  }
+
+  @Override
+  protected void computeLayerMatteBehindFocalDepth() {
+    // Marks active pixels (pixels that are on this target layer);
+    // Marks adjacent pixels that are close enough to active pixels;
+    long startnow;
+    long endnow;
+    startnow = System.nanoTime();
+    scriptC.forEach_MarkLayerMask(buffers.inAllocation);
+    endnow = System.nanoTime();
+    Log.d(myTAG, "MarkLayerMask: "+(endnow - startnow)+ " ns" );
+
+    startnow = System.nanoTime();
+    scriptC.forEach_ComputeLayerMatteBehindFocalDepth(buffers.inAllocation);
+    endnow = System.nanoTime();
+    Log.d(myTAG, "ComputeLayerMatteBehindFocalDepth: "+(endnow - startnow)+ " ns" );
+  }
+
+  @Override
+  protected void filterLayerBehindFocalDepth() {
+    // Filters the target layer and saves the result to {@code g_accum_map} in
+    // .rs file.
+    long startnow;
+    long endnow;
+    if (useFastFilterForCurrentLayer) {
+      scriptC.invoke_SetUseIntegralImage(1);
+      Script.LaunchOptions launchOptions = new Script.LaunchOptions();
+      launchOptions.setX(0, 1);
+      launchOptions.setY(0, buffers.inputImage.getHeight());
+
+      startnow = System.nanoTime();
+      scriptC.forEach_ComputeIntegralImageForLayerBehindFocalDepth(
+          buffers.inAllocation, launchOptions);
+      endnow = System.nanoTime();
+      Log.d(myTAG, "ComputeIntegralImageForLayerBehindFocalDepth: "+(endnow - startnow)+ " ns" );
+    } else {
+      scriptC.invoke_SetUseIntegralImage(0);
+    }
+
+    startnow = System.nanoTime();
+    scriptC.forEach_FilterLayerBehindFocalDepth(buffers.inAllocation);
+    endnow = System.nanoTime();
+    Log.d(myTAG, "FilterLayerBehindFocalDepth: "+(endnow - startnow)+ " ns" );
+
+    //extractFuzzyImage("fuzzy_behind");
+    //extractSharpImage("sharp_behind");
+  }
+
+  @Override
+  protected void updateSharpImageUsingFuzzyImage() {
+		// Log the kernel execution time
+    long startnow;
+    long endnow;
+    startnow = System.nanoTime();
+    scriptC.forEach_UpdateSharpImageUsingFuzzyImage(buffers.inAllocation);
+    endnow = System.nanoTime();
+    Log.d(myTAG, "UpdateSharpImageUsingFuzzyImage: "+(endnow - startnow)+ " ns" );
+
+    //extractSharpImage("sharp_update");
+  }
+
+  @Override
+  protected void computeLayerMatteInFrontOfFocalDepth() {
+    // Marks active pixels (pixels that are on this target layer);
+    // Marks adjacent pixels that are close enough to active pixels;
+    long startnow;
+    long endnow;
+    startnow = System.nanoTime();
+    scriptC.forEach_MarkLayerMask(buffers.inAllocation);
+    endnow = System.nanoTime();
+    Log.d(myTAG, "MarkLayerMask: "+(endnow - startnow)+ " ns" );
+
+    startnow = System.nanoTime();
+    scriptC.forEach_ComputeLayerMatteInFrontOfFocalDepth(buffers.inAllocation);
+    endnow = System.nanoTime();
+    Log.d(myTAG, "ComputeLayerMatteInFrontOfFocalDepth: "+(endnow - startnow)+ " ns" );
+  }
+
+  @Override
+  protected void filterLayerInFrontOfFocalDepth() {
+    // Filters the target layer and accumulates the result to {@code
+    // g_accum_map} in .rs file.
+    long startnow;
+    long endnow;
+    if (useFastFilterForCurrentLayer) {
+      scriptC.invoke_SetUseIntegralImage(1);
+      Script.LaunchOptions launchOptions = new Script.LaunchOptions();
+      launchOptions.setX(0, 1);
+      launchOptions.setY(0, buffers.inputImage.getHeight());
+
+      startnow = System.nanoTime();
+      scriptC.forEach_ComputeIntegralImageForLayerInFrontOfFocalDepth(
+          buffers.inAllocation, launchOptions);
+      endnow = System.nanoTime();
+      Log.d(myTAG, "ComputeIntegralImageForLayerInFrontOfFocalDepth: "+(endnow - startnow)+ " ns" );
+    } else {
+      scriptC.invoke_SetUseIntegralImage(0);
+    }
+    startnow = System.nanoTime();
+    scriptC.forEach_FilterLayerInFrontOfFocalDepth(buffers.inAllocation);
+    endnow = System.nanoTime();
+    Log.d(myTAG, "FilterLayerInFrontOfFocalDepth: "+(endnow - startnow)+ " ns" );
+
+    //extractFuzzyImage("fuzzy_front");
+    //extractSharpImage("sharp_front");
+  }
+
+  @Override
+  protected void finalizeFuzzyImageUsingSharpImage() {
+    // Blends {@code g_accum_map} and {@code g_focus_map} in .rs file.
+    // Saves the result in {@code g_accum_map}.
+    long startnow;
+    long endnow;
+    startnow = System.nanoTime();
+    scriptC.forEach_FinalizeFuzzyImageUsingSharpImage(buffers.inAllocation);
+    endnow = System.nanoTime();
+    Log.d(myTAG, "FinalizeFuzzyImageUsingSharpImage: "+(endnow - startnow)+ " ns" );
+  }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/refocus/image/RangeInverseDepthTransform.java b/tests/tests/renderscript/src/android/renderscript/cts/refocus/image/RangeInverseDepthTransform.java
new file mode 100644
index 0000000..7e414eb
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/refocus/image/RangeInverseDepthTransform.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.renderscript.cts.refocus.image;
+
+import android.renderscript.cts.refocus.DepthTransform;
+
+/**
+ * An implementation of {@code DepthTransform} that uses an inverse
+ * 8-bit representation of depth similar to the OpenGL z-buffer storage.
+ */
+public class RangeInverseDepthTransform implements DepthTransform {
+  public static final String FORMAT = "RangeInverse";
+
+  private final float near;
+  private final float far;
+
+  public RangeInverseDepthTransform(float near, float far) {
+    this.near = near;
+    this.far = far;
+  }
+
+  @Override
+  public float getNear() {
+    return near;
+  }
+
+  @Override
+  public float getFar() {
+    return far;
+  }
+
+  @Override
+  public String getFormat() {
+    return FORMAT;
+  }
+
+  @Override
+  public int quantize(float value) {
+    return Math.max(0, Math.min(255,
+        (int) ((far - near * far / value) / (far - near) * 255f)));
+  }
+
+  @Override
+  public float reconstruct(int value) {
+    return (far * near) / (far - (far - near) *
+        Math.max(0, Math.min(255, value)) / 255f);
+  }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/refocus/image/RangeLinearDepthTransform.java b/tests/tests/renderscript/src/android/renderscript/cts/refocus/image/RangeLinearDepthTransform.java
new file mode 100644
index 0000000..796266a
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/refocus/image/RangeLinearDepthTransform.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.renderscript.cts.refocus.image;
+
+
+import android.renderscript.cts.refocus.DepthTransform;
+
+/**
+ * An implementation of {@code DepthTransform} that uses a linear 8-bit
+ * quantization.
+ */
+public class RangeLinearDepthTransform implements DepthTransform {
+  public static final String FORMAT = "RangeLinear";
+
+  private final float near;
+  private final float far;
+
+  public RangeLinearDepthTransform(float near, float far) {
+    this.near = near;
+    this.far = far;
+  }
+
+  @Override
+  public float getNear() {
+    return near;
+  }
+
+  @Override
+  public float getFar() {
+    return far;
+  }
+
+  @Override
+  public String getFormat() {
+    return FORMAT;
+  }
+
+  @Override
+  public int quantize(float value) {
+    return Math.max(0, Math.min(255,
+        (int) ((value - near) / (far - near) * 255f)));
+  }
+
+  @Override
+  public float reconstruct(int value) {
+    return near + (far - near) * Math.max(0, Math.min(255, value)) / 255f;
+  }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/refocus/image_and_kernel.rsh b/tests/tests/renderscript/src/android/renderscript/cts/refocus/image_and_kernel.rsh
new file mode 100644
index 0000000..2570647
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/refocus/image_and_kernel.rsh
@@ -0,0 +1,32 @@
+#ifndef IMAGE_AND_KERNEL_RSH
+#define IMAGE_AND_KERNEL_RSH
+
+// Image size
+typedef struct ImageSize {
+  // width-by-height is the dimension of a padded image with a margin.
+  int width;
+  int height;
+  // The dimension of the original unpadded image is
+  // (width-2*margin)-by-(height-2*margin).
+  int margin;
+} ImageSize_t;
+
+static void SetImageSize(int w, int h, int m, ImageSize_t *image_size) {
+  image_size->width = w;
+  image_size->height = h;
+  image_size->margin = m;
+}
+
+// Auxiliary information that is needed to extract a kernel matrix from a buffer
+// of a stack of kernel matrices.
+typedef struct KernelInfo {
+  // The starting position of a kernel matrix in a buffer of a stack of kernel
+  // matrices.
+  int offset;
+
+  // The matrix is of size (2*radius_y+1)-by-(2*radius_x+1).
+  int radius_x;
+  int radius_y;
+} KernelInfo_t;
+
+#endif
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/refocus/layer_info.rsh b/tests/tests/renderscript/src/android/renderscript/cts/refocus/layer_info.rsh
new file mode 100644
index 0000000..be351d1
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/refocus/layer_info.rsh
@@ -0,0 +1,46 @@
+#ifndef LAYER_INFO_RSH
+#define LAYER_INFO_RSH
+
+// An object that contains the front and back depths values of a layer
+typedef struct LayerInfo {
+  // Front and back depth values of this layer.
+  // front_depth >= back_depth.
+  int front_depth;
+  int back_depth;
+} LayerInfo_t;
+
+// An object that contains parameters used for computing matte for the current
+// layer.
+typedef struct BlendInfo {
+  // The max kernel radius of a layer.
+  int dilation_radius;
+
+  // A scale factor =1.0f/(1+dilation_radius), which is used to normalize a
+  // distance transform result to be a matte value within [0,1].
+  // This data member is only used for PixelFormatF32.
+  float matte_normalizer;
+} BlendInfo_t;
+
+static inline int ValidDepth(int depth) { return (depth != 0); }
+
+static inline int NotInFrontOfTheLayer(int depth,
+                                       const LayerInfo_t *layer_info) {
+  return (depth <= layer_info->front_depth);
+}
+
+static inline int OnTheLayer(int depth, const LayerInfo_t *layer_info) {
+  return (layer_info->back_depth <= depth && depth <= layer_info->front_depth);
+}
+
+static inline int ValidDepthNotInFrontOfTheLayer(
+    int depth, const LayerInfo_t *layer_info) {
+  return (depth != 0) & (depth <= layer_info->front_depth);
+}
+
+static inline int ValidDepthNotOnTheLayer(int depth,
+                                          const LayerInfo_t *layer_info) {
+  return (depth != 0) &
+         ((depth < layer_info->back_depth) | (depth > layer_info->front_depth));
+}
+
+#endif
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/refocus/layer_info_fast.rsh b/tests/tests/renderscript/src/android/renderscript/cts/refocus/layer_info_fast.rsh
new file mode 100644
index 0000000..6b7368c
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/refocus/layer_info_fast.rsh
@@ -0,0 +1,48 @@
+#ifndef LAYER_INFO_RSH
+#define LAYER_INFO_RSH
+
+// An object that contains the front and back depths values of a layer
+typedef struct LayerInfo {
+  // Front and back depth values of this layer.
+  // front_depth >= back_depth.
+  int front_depth;
+  int back_depth;
+} LayerInfo_t;
+
+// An object that contains parameters used for computing matte for the current
+// layer.
+typedef struct BlendInfo {
+  // The max kernel radius of a layer.
+  int dilation_radius;
+
+  // A scale factor =1.0f/(1+dilation_radius), which is used to normalize a
+  // distance transform result to be a matte value within [0,1].
+  // This data member is only used for PixelFormatF32.
+  float matte_normalizer;
+} BlendInfo_t;
+
+static inline int ValidDepth(int depth) { return (depth != 0); }
+
+static inline int NotInFrontOfTheLayer(int depth,
+                                       const int2 layer_info_f2) {
+  return (depth <= layer_info_f2.s0);
+}
+
+static inline int OnTheLayer(int depth, const int2 layer_info_i2) {
+  //return (layer_info->back_depth <= depth && depth <= layer_info->front_depth);
+  return (layer_info_i2.s1 <= depth && depth <= layer_info_i2.s0);
+}
+
+static inline int ValidDepthNotInFrontOfTheLayer(
+    int depth, const int2 layer_info_f2) {
+  //return (depth != 0) & (depth <= layer_info->front_depth);
+  return (depth != 0) & (depth <= layer_info_f2.s0);
+}
+
+static inline int ValidDepthNotOnTheLayer(int depth,
+                                          const int2 layer_info_f2) {
+  return (depth != 0) &
+         ((depth < layer_info_f2.s1) | (depth > layer_info_f2.s0));
+}
+
+#endif
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/refocus/layered_filter_d1new_helper.rsh b/tests/tests/renderscript/src/android/renderscript/cts/refocus/layered_filter_d1new_helper.rsh
new file mode 100644
index 0000000..39c8d90
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/refocus/layered_filter_d1new_helper.rsh
@@ -0,0 +1,261 @@
+#ifndef LAYERED_FILTER_FAST_HELPER_RSH
+#define LAYERED_FILTER_FAST_HELPER_RSH
+
+// Need to access global allocation here
+// Declared in layered_filter_fast_f32.rs
+// This allocation has three float values of red, green, blue
+rs_allocation g_sharp_RGBA;
+
+rs_allocation g_sharp_actual_depth;
+rs_allocation g_sharp_active;
+rs_allocation g_sharp_matte;
+rs_allocation g_sharp_dilated_depth;
+
+// This allocation contains four floats: red, green, blue, alpha
+rs_allocation g_fuzzy_RGBA;
+// This allocation contains four floats: red, green, blue, alpha
+rs_allocation g_integral_RGBA;
+// This allocation contains the kernel stack info: only one float per cell
+rs_allocation g_kernel_stack;
+// int2 that stores the target layer info: 1. front_depth, 2. back_depth; declared in layered_filter_f32_helper.rsh
+static int2 g_target_layer_i2;
+
+
+// Several supporting functions that are called by kernel functions defined in
+// layered_filter_f32.rs for refocus rendering.
+// For the following supporting functions, the input arguments have the
+// following meaning:
+//
+// @param x x-coordinate of a pixel in a padded image.
+// @param y y-coordinate of a pixel in a padded image.
+
+// A function that visits neighboring pixels around (x,y) and finds the closest
+// active pixel to (x,y). Sets the closest distance to sharp->matte and sets the
+// depth of the closest pixel to sharp->dilated_depth.
+// When this function is called, the initial value of sharp->dilated_depth is
+// sharp->actual_depth and must be non-zero. However, sharp->actual_depth may or
+// may not be in the depth range of the target layer.
+
+
+//Compute layer matte using global allocation
+static inline void Alloc_ComputeLayerMatteHelper(uchar sharp_input_actual_depth, int index_sharp_meta,
+                                           const int4 image_size_i4,
+                                           const int dilation_radius) {
+  const int kernel_center_x = dilation_radius;
+  const int kernel_center_y = dilation_radius;
+  const int kernel_dim_x = 2 * kernel_center_x + 1;
+
+  // Initializes the minimum distance from this pixel to the active pixels on
+  // this layer.
+  int min_dist = dilation_radius + 1;
+  min_dist *= min_dist;  // Prepares for L2 distance.
+  int depth = sharp_input_actual_depth;  // Get meta data actual_depth
+
+  int current_meta_index = index_sharp_meta - kernel_center_y * image_size_i4.s0 - kernel_center_x;  // image_size.width
+  const int jump_to_next_pixel = 1;
+  const int jump_to_next_row = image_size_i4.s0 - kernel_dim_x;  // image_size.width
+
+  for (int j = -kernel_center_y; j <= kernel_center_y; ++j) {
+    for (int i = -kernel_center_x; i <= kernel_center_x; ++i) {
+      const uchar sharp_active = rsGetElementAt_uchar(g_sharp_active, current_meta_index);
+      const uchar sharp_actual_depth = rsGetElementAt_uchar(g_sharp_actual_depth, current_meta_index);
+      // L_2 distance:
+      int this_dist = i * i + j * j;
+      // Whether or not this is an active pixel with a smaller distance.
+      int cond = (sharp_active && this_dist < min_dist);
+      // Updates min_dist and corresponding depth.
+      min_dist = cond ? this_dist : min_dist;
+      depth = cond ? sharp_actual_depth : depth;
+
+      current_meta_index += jump_to_next_pixel;
+    }
+    current_meta_index += jump_to_next_row;
+  }
+
+  // Converts min_dist to a matte value.
+  rsSetElementAt_uchar(g_sharp_matte, (uchar)(dilation_radius + 1 - (int)half_sqrt((float)min_dist)), index_sharp_meta);
+  // If sharp->matte > 0, depth must be within the depth range of this layer.
+  rsSetElementAt_uchar(g_sharp_dilated_depth, (uchar)depth, index_sharp_meta);
+}
+
+// return sharp_dilated_depth
+static inline uchar ComputeLayerMattePassInputHelper(uchar sharp_input_actual_depth, int index_sharp_meta,
+                                           const int4 image_size_i4,
+                                           const int dilation_radius) {
+  const int kernel_center_x = dilation_radius;
+  const int kernel_center_y = dilation_radius;
+  const int kernel_dim_x = 2 * kernel_center_x + 1;
+
+  // Initializes the minimum distance from this pixel to the active pixels on
+  // this layer.
+  int min_dist = dilation_radius + 1;
+  min_dist *= min_dist;  // Prepares for L2 distance.
+  int depth = sharp_input_actual_depth;  // Get meta data actual_depth
+
+  int current_meta_index = index_sharp_meta - kernel_center_y * image_size_i4.s0 - kernel_center_x;	// image_size.width
+  const int jump_to_next_pixel = 1;
+  const int jump_to_next_row = image_size_i4.s0 - kernel_dim_x;	// image_size.width
+
+  for (int j = -kernel_center_y; j <= kernel_center_y; ++j) {
+    for (int i = -kernel_center_x; i <= kernel_center_x; ++i) {
+      const uchar sharp_active = rsGetElementAt_uchar(g_sharp_active, current_meta_index);
+      const uchar sharp_actual_depth = rsGetElementAt_uchar(g_sharp_actual_depth, current_meta_index);
+      // L_2 distance:
+      int this_dist = i * i + j * j;
+      // Whether or not this is an active pixel with a smaller distance.
+      int cond = (sharp_active && this_dist < min_dist);
+      // Updates min_dist and corresponding depth.
+      min_dist = cond ? this_dist : min_dist;
+      depth = cond ? sharp_actual_depth : depth;
+
+      current_meta_index += jump_to_next_pixel;
+    }
+    current_meta_index += jump_to_next_row;
+  }
+  // Converts min_dist to a matte value.
+  rsSetElementAt_uchar(g_sharp_matte, (uchar)(dilation_radius + 1 - (int)half_sqrt((float)min_dist)), index_sharp_meta);
+  // If sharp->matte > 0, depth must be within the depth range of this layer.
+  return (uchar)depth;
+}
+
+// Filters target layer when processing layers in pass one from the back-most to
+// the sharp depth.
+// Use global allocation for filter from back most layer to focus layer
+static inline float4 AllocFilterLayerBehindFocalDepthHelper(
+    uint32_t x, uint32_t y, const int4 image_size_i4,
+    const int2 layer_info_i2, const float4 alloc_kernel_info,
+    const VisibilityProbability_t *visibility_probability) {
+  float4 result = {0.0f, 0.0f, 0.0f, 0.0f};
+
+  // Extracts kernel matrix from kernel stack using kernel_info.
+  const int kernel_center_x = alloc_kernel_info.s1;
+  const int kernel_center_y = alloc_kernel_info.s2;
+  const int kernel_dim_x = 2 * kernel_center_x + 1;
+  int current_kernel_index = alloc_kernel_info.s0;  // kernel_info.offset
+
+  // Gets the visibility probability lookup table for the target layer depth.
+  const float *vis_prob = visibility_probability->lut[layer_info_i2.s0]; // layer_info.front_depth
+
+  // Locates the top left corner of the window surrounding this pixel.
+  int current_meta_index =  (y - kernel_center_y) * image_size_i4.s0 +  // image_size.width
+                                     (x - kernel_center_x);
+
+  // Filters over the window.
+  const int jump_to_next_pixel = 1;
+  const int jump_to_next_row = image_size_i4.s0 - kernel_dim_x;  // image_size.width
+
+  for (int j = -kernel_center_y; j <= kernel_center_y; ++j) {
+    for (int i = -kernel_center_x; i <= kernel_center_x; ++i) {
+      // Filters only using pixels on or behind this layer to avoid color
+      // bleeding from layers in front of this layer. Doing visibility test in a
+      // soft way using a probability set in a heuristic way.
+        const uchar sharp_actual_depth = rsGetElementAt_uchar(g_sharp_actual_depth, current_meta_index);
+        const float4 sharp_RGBA_nbr = rsGetElementAt_float4(g_sharp_RGBA, current_meta_index);
+        const float kernel = rsGetElementAt_float(g_kernel_stack, current_kernel_index);
+
+        const float v_p = vis_prob[sharp_actual_depth];
+
+        const float weight = v_p * (kernel);
+        result.r += weight * sharp_RGBA_nbr.r;
+        result.g += weight * sharp_RGBA_nbr.g;
+        result.b += weight * sharp_RGBA_nbr.b;
+        result.a += weight;
+        current_kernel_index++;
+        current_meta_index += jump_to_next_pixel;
+    }
+    current_meta_index += jump_to_next_row;
+  }
+
+  // Normalizes and returns the result.
+  float factor = 1.0f / result.a;
+  result.r *= factor;
+  result.g *= factor;
+  result.b *= factor;
+  result.a = 1.0f;
+  return result;
+}
+
+// Filter target layer use global allocation using integral image
+static inline float4 AllocFilterLayerUsingRowwiseIntegralImage(
+    uint32_t x, uint32_t y, const int4 image_size_i4,
+    const float4 alloc_kernel_info, const SecantOffset_t *secant_offset) {
+    //const SecantOffset_t *secant_offset) {
+  float4 result = {0.0f, 0.0f, 0.0f, 0.0f};
+
+  // Extracts kernel matrix from kernel stack using kernel_info.
+  const int kernel_radius_y = alloc_kernel_info.s2;  // kernel_info->radius_y
+  const int *radius_lut =
+      secant_offset->lut[kernel_radius_y] + g_kMaxKernelRadius;
+
+  // Locates the top left corner index of the window surrounding this pixel.
+  int current_index_integral = (y - kernel_radius_y) * image_size_i4.s0 + x;  // image_size.width
+
+  // Filters over the window.
+  const int jump_to_next_row = image_size_i4.s0;  // image_size.width
+  for (int j = -kernel_radius_y; j <= kernel_radius_y; ++j) {
+    const int kernel_radius_x_at_y = radius_lut[j];
+    result += rsGetElementAt_float4(g_integral_RGBA, current_index_integral + kernel_radius_x_at_y) -
+      rsGetElementAt_float4(g_integral_RGBA, current_index_integral - kernel_radius_x_at_y - 1);
+    current_index_integral += jump_to_next_row;
+  }
+
+  // Normalizes and returns the result.
+  float factor = 1.0f / result.a;
+  result.r = result.r * factor;
+  result.g = result.g * factor;
+  result.b = result.b * factor;
+  result.a = 1.0f;
+  return result;
+}
+
+// Use global allocation to filter layer from the
+// front most layer to focus layer.
+static inline float4 AllocFilterLayerInFrontOfFocalDepthHelper(
+    uint32_t x, uint32_t y, const int4 image_size_i4,
+    const float4 alloc_kernel_info) {
+  float4 result = {0.f, 0.f, 0.f, 0.f};
+
+  // Extracts kernel matrix from kernel stack using kernel_info.
+  const int kernel_center_x = alloc_kernel_info.s1;  // kernel_info->radius_x
+  const int kernel_center_y = alloc_kernel_info.s2;  // kernel_info->radius_y
+  const int kernel_dim_x = 2 * kernel_center_x + 1;
+
+  int current_kernel_index = alloc_kernel_info.s0;  // kernel_info->offset
+
+  // Locates the top left corner of the window surrounding this pixel.
+  const int index =
+      (y - kernel_center_y) * image_size_i4.s0 + (x - kernel_center_x);  // image_size.width
+  int current_index = index;
+  // Filters over the window.
+  const int jump_to_next_pixel = 1;
+  const int jump_to_next_row = image_size_i4.s0 - kernel_dim_x;  // image_size.width
+  for (int j = -kernel_center_y; j <= kernel_center_y; ++j) {
+    for (int i = -kernel_center_x; i <= kernel_center_x; ++i) {
+      // Filters only using pixels with valid depth values (i.e. excluding
+      // padded pixels).
+      const float4 sharp_RGBA_nbr = rsGetElementAt_float4(g_sharp_RGBA, current_index);
+      const uchar sharp_meta_actual_depth = rsGetElementAt_uchar(g_sharp_actual_depth, current_index);
+      const float kernel = rsGetElementAt_float(g_kernel_stack, current_kernel_index);
+
+      const float flag = ValidDepth(sharp_meta_actual_depth);
+      const float weight = flag * (kernel);
+      result.r += weight * sharp_RGBA_nbr.r;
+      result.g += weight * sharp_RGBA_nbr.g;
+      result.b += weight * sharp_RGBA_nbr.b;
+      result.a += weight;
+      current_kernel_index++;
+      current_index += jump_to_next_pixel;
+    }
+    current_index += jump_to_next_row;
+  }
+
+  // Normalizes and returns the result
+  float fac = 1.0f / result.a;
+  result.r *= fac;
+  result.g *= fac;
+  result.b *= fac;
+  result.a = 1.0f;
+  return result;
+}
+
+#endif
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/refocus/layered_filter_f32_helper.rsh b/tests/tests/renderscript/src/android/renderscript/cts/refocus/layered_filter_f32_helper.rsh
new file mode 100644
index 0000000..821e7af
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/refocus/layered_filter_f32_helper.rsh
@@ -0,0 +1,228 @@
+#ifndef LAYERED_FILTER_F32_HELPER_RSH
+#define LAYERED_FILTER_F32_HELPER_RSH
+
+#include "pixel_format_f32.rsh"
+#include "luts_for_speedup_f32.rsh"
+
+// Several supporting functions that are called by kernel functions defined in
+// layered_filter_f32.rs for refocus rendering.
+// For the following supporting functions, the input arguments have the
+// following meaning:
+//
+// @param x x-coordinate of a pixel in a padded image.
+// @param y y-coordinate of a pixel in a padded image.
+
+// A function that visits neighboring pixels around (x,y) and finds the closest
+// active pixel to (x,y). Sets the closest distance to sharp->matte and sets the
+// depth of the closest pixel to sharp->dilated_depth.
+// When this function is called, the initial value of sharp->dilated_depth is
+// sharp->actual_depth and must be non-zero. However, sharp->actual_depth may or
+// may not be in the depth range of the target layer.
+static inline void ComputeLayerMatteHelper(SharpPixelF32_t *sharp, uint32_t x,
+                                           uint32_t y,
+                                           const ImageSize_t *image_size,
+                                           const int dilation_radius) {
+  const int kernel_center_x = dilation_radius;
+  const int kernel_center_y = dilation_radius;
+  const int kernel_dim_x = 2 * kernel_center_x + 1;
+
+  // Initializes the minimum distance from this pixel to the active pixels on
+  // this layer.
+  int min_dist = dilation_radius + 1;
+  min_dist *= min_dist;  // Prepares for L2 distance.
+  int depth = sharp->actual_depth;
+
+  const SharpPixelF32_t *sharp_nbr =
+      sharp - kernel_center_y * image_size->width - kernel_center_x;
+  const int jump_to_next_pixel = 1;
+  const int jump_to_next_row = image_size->width - kernel_dim_x;
+
+  for (int j = -kernel_center_y; j <= kernel_center_y; ++j) {
+    for (int i = -kernel_center_x; i <= kernel_center_x; ++i) {
+      // L_2 distance:
+      int this_dist = i * i + j * j;
+      // Whether or not this is an active pixel with a smaller distance.
+      int cond = (sharp_nbr->active && this_dist < min_dist);
+      // Updates min_dist and corresponding depth.
+      min_dist = cond ? this_dist : min_dist;
+      depth = cond ? sharp_nbr->actual_depth : depth;
+
+      sharp_nbr += jump_to_next_pixel;
+    }
+    sharp_nbr += jump_to_next_row;
+  }
+
+  // Converts min_dist to a matte value.
+  sharp->matte = (uchar)(dilation_radius + 1 - (int)half_sqrt((float)min_dist));
+  // If sharp->matte > 0, depth must be within the depth range of this layer.
+  sharp->dilated_depth = (uchar)depth;
+}
+
+// Filters target layer when processing layers in pass one from the back-most to
+// the sharp depth.
+static inline FuzzyPixelF32_t FilterLayerBehindFocalDepthHelper(
+    uint32_t x, uint32_t y, const ImageSize_t *image_size,
+    const LayerInfo_t *layer_info, const KernelInfo_t *kernel_info,
+    const float *kernel_stack, const SharpPixelF32_t *sharp_image,
+    const VisibilityProbability_t *visibility_probability) {
+  FuzzyPixelF32_t result = {0.0f, 0.0f, 0.0f, 0.0f};
+
+  // Extracts kernel matrix from kernel stack using kernel_info.
+  const int kernel_center_x = kernel_info->radius_x;
+  const int kernel_center_y = kernel_info->radius_y;
+  const int kernel_dim_x = 2 * kernel_center_x + 1;
+  const float *kernel = kernel_stack + kernel_info->offset;
+
+  // Gets the visibility probability lookup table for the target layer depth.
+  const float *vis_prob = visibility_probability->lut[layer_info->front_depth];
+
+  // Locates the top left corner of the window surrounding this pixel.
+  const SharpPixelF32_t *sharp_nbr = sharp_image +
+                                     (y - kernel_center_y) * image_size->width +
+                                     (x - kernel_center_x);
+
+  // Filters over the window.
+  const int jump_to_next_pixel = 1;
+  const int jump_to_next_row = image_size->width - kernel_dim_x;
+  for (int j = -kernel_center_y; j <= kernel_center_y; ++j) {
+    for (int i = -kernel_center_x; i <= kernel_center_x; ++i) {
+      // Filters only using pixels on or behind this layer to avoid color
+      // bleeding from layers in front of this layer. Doing visibility test in a
+      // soft way using a probability set in a heuristic way.
+      const float v_p = vis_prob[sharp_nbr->actual_depth];
+
+      const float weight = v_p * (*kernel);
+      result.red += weight * sharp_nbr->red;
+      result.green += weight * sharp_nbr->green;
+      result.blue += weight * sharp_nbr->blue;
+      result.alpha += weight;
+      kernel++;
+      sharp_nbr += jump_to_next_pixel;
+    }
+    sharp_nbr += jump_to_next_row;
+  }
+
+  // Normalizes and returns the result.
+  float factor = 1.0f / result.alpha;
+  result.red *= factor;
+  result.green *= factor;
+  result.blue *= factor;
+  result.alpha = 1.0f;
+  return result;
+}
+
+// Filters target layer when processing layers in pass one from the back-most to
+// the sharp depth.
+static inline FuzzyPixelF32_t FilterLayerUsingRowwiseIntegralImage(
+    uint32_t x, uint32_t y, const ImageSize_t *image_size,
+    const KernelInfo_t *kernel_info, const float4 *integral_image,
+    const SecantOffset_t *secant_offset) {
+  float4 result = {0.0f, 0.0f, 0.0f, 0.0f};
+
+  // Extracts kernel matrix from kernel stack using kernel_info.
+  const int kernel_radius_y = kernel_info->radius_y;
+  const int *radius_lut =
+      secant_offset->lut[kernel_radius_y] + g_kMaxKernelRadius;
+
+  // Locates the top left corner of the window surrounding this pixel.
+  const float4 *integral_pixel =
+      integral_image + (y - kernel_radius_y) * image_size->width + x;
+
+  // Filters over the window.
+  const int jump_to_next_row = image_size->width;
+  for (int j = -kernel_radius_y; j <= kernel_radius_y; ++j) {
+    const int kernel_radius_x_at_y = radius_lut[j];
+    result += integral_pixel[kernel_radius_x_at_y] -
+              integral_pixel[-kernel_radius_x_at_y - 1];
+    integral_pixel += jump_to_next_row;
+  }
+
+  // Normalizes and returns the result.
+  FuzzyPixelF32_t fuzzy;
+  float factor = 1.0f / result.a;
+  fuzzy.red = result.r * factor;
+  fuzzy.green = result.g * factor;
+  fuzzy.blue = result.b * factor;
+  fuzzy.alpha = 1.0f;
+  return fuzzy;
+}
+
+// Filters the target layer when processing layers in pass two from the
+// front-most to the focus depth.
+static inline FuzzyPixelF32_t FilterLayerInFrontOfFocalDepthHelper(
+    uint32_t x, uint32_t y, const ImageSize_t *image_size,
+    const KernelInfo_t *kernel_info, const float *kernel_stack,
+    const SharpPixelF32_t *sharp_image) {
+  FuzzyPixelF32_t result = {0.f, 0.f, 0.f, 0.f};
+
+  // Extracts kernel matrix from kernel stack using kernel_info.
+  const int kernel_center_x = kernel_info->radius_x;
+  const int kernel_center_y = kernel_info->radius_y;
+  const int kernel_dim_x = 2 * kernel_center_x + 1;
+  const float *kernel = kernel_stack + kernel_info->offset;
+
+  // Locates the top left corner of the window surrounding this pixel.
+  const int index =
+      (y - kernel_center_y) * image_size->width + (x - kernel_center_x);
+  const SharpPixelF32_t *sharp_nbr = sharp_image + index;
+
+  // Filters over the window.
+  const int jump_to_next_pixel = 1;
+  const int jump_to_next_row = image_size->width - kernel_dim_x;
+  for (int j = -kernel_center_y; j <= kernel_center_y; ++j) {
+    for (int i = -kernel_center_x; i <= kernel_center_x; ++i) {
+      // Filters only using pixels with valid depth values (i.e. excluding
+      // padded pixels).
+      const float flag = ValidDepth(sharp_nbr->actual_depth);
+
+      const float weight = flag * (*kernel);
+      result.red += weight * sharp_nbr->red;
+      result.green += weight * sharp_nbr->green;
+      result.blue += weight * sharp_nbr->blue;
+      result.alpha += weight;
+      kernel++;
+      sharp_nbr += jump_to_next_pixel;
+    }
+    sharp_nbr += jump_to_next_row;
+  }
+
+  // Normalizes and returns the result
+  float fac = 1.0f / result.alpha;
+  result.red *= fac;
+  result.green *= fac;
+  result.blue *= fac;
+  result.alpha = 1.0f;
+  return result;
+}
+
+static void ResetSharpImage(SharpPixelF32_t *sharp_image, int num_pixels) {
+  const SharpPixelF32_t *last_p = sharp_image + num_pixels;
+  for (SharpPixelF32_t *p = sharp_image; p != last_p; ++p) {
+    p->red = 0;
+    p->green = 0;
+    p->blue = 0;
+    p->active = 0;
+    p->dilated_depth = 0;
+    p->actual_depth = 0;
+    p->matte = 0;
+  }
+}
+
+static void ResetIntegralImage(float4 *integral_image, int num_pixels) {
+  const float4 *last_p = integral_image + num_pixels;
+  for (float4 *p = integral_image; p != last_p; ++p) {
+    *p = 0;
+  }
+}
+
+static void ResetFuzzyImage(FuzzyPixelF32_t *fuzzy_image, int num_pixels) {
+  const FuzzyPixelF32_t *last_p = fuzzy_image + num_pixels;
+  for (FuzzyPixelF32_t *p = fuzzy_image; p != last_p; ++p) {
+    p->red = 0;
+    p->green = 0;
+    p->blue = 0;
+    p->alpha = 0;
+  }
+}
+
+#endif
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/refocus/layered_filter_fast_d1new.rs b/tests/tests/renderscript/src/android/renderscript/cts/refocus/layered_filter_fast_d1new.rs
new file mode 100644
index 0000000..e7342c6
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/refocus/layered_filter_fast_d1new.rs
@@ -0,0 +1,825 @@
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts.refocus)
+#pragma rs_fp_relaxed
+// This is a speedup version of layered_filter_f32.rs using summation table.
+// Several kernel functions and global functions for refocus rendering using
+// Render Script. These functions are accessible from Java side. The assumptions
+// made in this file are (consistent with Java side):
+//
+// 1. The depth value varies between 1 and number of depth levels. 0 is reserved
+// for invalid pixels, e.g., padded pixels around image boundary.
+// 2. The depth value represents inverse depth. Larger depths are closer to the
+// camera.
+// 3. The depth values are grouped into several blending layers.
+// 4. The focal layer (i.e., the global variable g_focal_layer) is the depth
+// value interval that has no blur.
+//
+// For the following kernel functions defined in this rs file, the input
+// arguments have the following meaning:
+//
+// @param in an input RGBD pixel with @in.a being quantized inverse depth.
+// @param x x-coordinate of @param in in the unpadded input image.
+// @param y y-coordinate of @param in in the unpadded input image.
+
+#include "camera_response.rsh"
+#include "layer_info_fast.rsh"
+#include "luts_for_speedup_f32.rsh"
+#include "layered_filter_d1new_helper.rsh"
+
+// Set force CPU variable for kernels:
+// UnpackInputImage, ComputeLayerMatteBehindFocalDepth, ComputeIntegralImageForLayerBehindFocalDepth,
+// FilterLayerBehindFocalDepth, updateSharpImageUsingFuzzyImage, ComputeLayerMatteInFrontOfFocalDepth,
+// FilterLayerInFrontOfFocalDepth
+double cpuDummy = 2.0;
+void foo(double a) {
+
+}
+// Image size of padded images: g_sharp_image and g_fuzzy_image.
+// Float4 that stores the image size info: 1. width, 2. height, 3. margin
+static int4 g_image_size_i4;
+
+static CameraResponse_t g_camera_response;
+
+// This image buffer is used to store input image initially.
+// Then the input image gets updated as each layer is processed from the
+// back-most to the focal depth. This image buffer is padded.
+
+// This image buffer is used to save an integral image of g_sharp_image
+// modulated by the visibility mask.
+
+// whether or not to use integral image in this iteration.
+static int g_use_integral_image;
+
+// This image buffer is used to store output image, both for intermediate
+// results and final result.
+// In the first pass from back-most to focal depth, g_fuzzy_image holds the
+// layer filtering result temporarily and then the result is used to update the
+// input image after each layer is processed.
+// In the second pass from front-most to focal depth, g_fuzzy_image accumulates
+// all the layer filtering results and in the end, the accumulation result is
+// blended with the input image (which has been updated in the first pass) to
+// generate the final result. This image buffer is padded.
+
+// The dilation radius that controls how the current layer should be blended
+// with previous layers.
+static BlendInfo_t g_blend_info;
+
+// The depth level that is in focus.
+// int2 that stores the focal layer info: 1. front_depth, 2. back_depth
+static int2 g_focal_layer_i2;
+
+// This is an allocation to store kernel info: 1. offset, 2. radius_x, 3. radius_y
+rs_allocation galloc_kernel_info;
+
+// Precomputed LUTs for speedup.
+static VisibilityProbability_t g_visibility_probability;
+static SecantOffset_t g_secant_offset;
+
+static const float g_kOneOver255 = 1.0f / 255.0f;
+static const float g_kAlmostOne = .998f;
+
+// (1 << g_kDepthScaleShift) must be the same as BlurStack::DEPTH_SCALE.
+static const int g_kDepthScaleShift = 2;
+// g_kMaxDepth must be the same as BlurStack::MAX_DETPH.
+static const int g_kMaxDepth = 256 >> g_kDepthScaleShift;
+
+// Copies an input (unpadded) RGBD image into g_sharp_image, which has been
+// padded with margin. Initialize other fields.
+void __attribute__((kernel))
+UnpackInputImage(uchar4 in, uint32_t x, uint32_t y) {
+  // Maps (x,y) to the padded image coordinate system.
+  x += g_image_size_i4.s2;  // margin
+  y += g_image_size_i4.s2;  // margin
+
+  const int index = y * g_image_size_i4.s0 + x;  // width
+
+  float4 sharp_RGBA;
+  float3 tmp = convert_float3(in.xyz) * g_kOneOver255;
+  sharp_RGBA.r =
+      ApplyLUT_Float(tmp.r, g_camera_response.lut_remove_crf_float);
+  sharp_RGBA.g =
+      ApplyLUT_Float(tmp.g, g_camera_response.lut_remove_crf_float);
+  sharp_RGBA.b =
+      ApplyLUT_Float(tmp.b , g_camera_response.lut_remove_crf_float);
+
+  rsSetElementAt_float4(g_sharp_RGBA, sharp_RGBA, index);
+
+  rsSetElementAt_uchar(g_sharp_actual_depth, g_kMaxDepth - (in.a >> g_kDepthScaleShift), index);
+}
+
+// Marks active pixels that are on the target layer.
+// Initializes the matte of active pixels to be the dilation_radius+1, which is
+// equivalent to 1.
+// Initializes dilated_depth of active pixels and pixels that are close to
+// active pixels to be actual depths.
+void __attribute__((kernel)) MarkLayerMask(uchar4 in, uint32_t x, uint32_t y) {
+  const int actual_depth = g_kMaxDepth - (in.a >> g_kDepthScaleShift);
+  if (!OnTheLayer(actual_depth, g_target_layer_i2)) return;
+
+  // Maps (x,y) to the padded image coordinate system.
+  x += g_image_size_i4.s2;  // margin
+  y += g_image_size_i4.s2;  // margin
+
+  const int index = y * g_image_size_i4.s0 + x;  // width
+
+  // Marks this pixel as active.
+  rsSetElementAt_uchar(g_sharp_active, 1, index);
+  rsSetElementAt_uchar(g_sharp_matte, g_blend_info.dilation_radius + 1, index);
+
+  uchar sharp_actual_depth = rsGetElementAt_uchar(g_sharp_actual_depth, index);
+  rsSetElementAt_uchar(g_sharp_dilated_depth, sharp_actual_depth, index);
+
+  // Next, tries to figure out whether or not this pixel is on the boundary
+  // between active and inactive pixels
+  int is_this_pixel_on_boundary = 0;
+
+  sharp_actual_depth = rsGetElementAt_uchar(g_sharp_actual_depth, index - g_image_size_i4.s0);
+  is_this_pixel_on_boundary |=
+    ValidDepthNotOnTheLayer(sharp_actual_depth, g_target_layer_i2);
+
+  sharp_actual_depth = rsGetElementAt_uchar(g_sharp_actual_depth, index + g_image_size_i4.s0);
+  is_this_pixel_on_boundary |=
+    ValidDepthNotOnTheLayer(sharp_actual_depth, g_target_layer_i2);
+
+  sharp_actual_depth = rsGetElementAt_uchar(g_sharp_actual_depth, index - 1);
+  is_this_pixel_on_boundary |=
+    ValidDepthNotOnTheLayer(sharp_actual_depth, g_target_layer_i2);
+
+  sharp_actual_depth = rsGetElementAt_uchar(g_sharp_actual_depth, index + 1);
+  is_this_pixel_on_boundary |=
+    ValidDepthNotOnTheLayer(sharp_actual_depth, g_target_layer_i2);
+
+  if (!is_this_pixel_on_boundary) {
+    return;
+  }
+
+  // Marks pixels near the boundary of active pixels to compute matte later.
+  const int kernel_center_x = g_blend_info.dilation_radius;
+  const int kernel_center_y = g_blend_info.dilation_radius;
+  const int kernel_dim_x = 2 * kernel_center_x + 1;
+
+  // index of the current meta data, initailly set to top left sharp meta data
+  // Moves sharp_nbr to the top left corner of this pixel.
+  int current_meta_index = x - (kernel_center_y * g_image_size_i4.s0 + kernel_center_x);  // width
+  const int jump_to_next_pixel = 1;
+  const int jump_to_next_row = g_image_size_i4.s0 - kernel_dim_x;	// width
+  for (int j = -kernel_center_y; j <= kernel_center_y; ++j) {
+    // Initializes dilated_depth as actual_depth.
+    // The dilated_depth will then be updated in distance transform later.
+    // A valid, non-zero dilated_depth indicates distance transform is
+    // needed for the pixel. Otherwise, the distance transform will be
+    // skipped.
+    for (int i = -kernel_center_x; i <= kernel_center_x; ++i) {
+      sharp_actual_depth = rsGetElementAt_uchar(g_sharp_actual_depth, current_meta_index);
+      rsSetElementAt_uchar(g_sharp_dilated_depth, sharp_actual_depth, current_meta_index);
+      current_meta_index += jump_to_next_pixel;
+    }
+    current_meta_index += jump_to_next_row;
+  }
+}
+
+// Another version of MarkLayerMask kernel that directly passes input allocation to kernels
+// Input: g_sharp_actual_depth
+// Output: g_sharp_dilated_depth
+uchar __attribute__((kernel)) MarkLayerMaskPassInput(uchar in_sharp_actual_depth, uint32_t x) {
+  if (!OnTheLayer(in_sharp_actual_depth, g_target_layer_i2)) return rsGetElementAt_uchar(g_sharp_dilated_depth, x);
+
+  // Marks this pixel as active.
+  rsSetElementAt_uchar(g_sharp_active, 1, x);
+  rsSetElementAt_uchar(g_sharp_matte, g_blend_info.dilation_radius + 1, x);
+
+  // Next, tries to figure out whether or not this pixel is on the boundary
+  // between active and inactive pixels
+  int is_this_pixel_on_boundary = 0;
+
+  uchar sharp_actual_depth = rsGetElementAt_uchar(g_sharp_actual_depth, x - g_image_size_i4.s0);
+  is_this_pixel_on_boundary |=
+    ValidDepthNotOnTheLayer(sharp_actual_depth, g_target_layer_i2);
+
+  sharp_actual_depth = rsGetElementAt_uchar(g_sharp_actual_depth, x + g_image_size_i4.s0);
+  is_this_pixel_on_boundary |=
+    ValidDepthNotOnTheLayer(sharp_actual_depth, g_target_layer_i2);
+
+  sharp_actual_depth = rsGetElementAt_uchar(g_sharp_actual_depth, x - 1);
+  is_this_pixel_on_boundary |=
+    ValidDepthNotOnTheLayer(sharp_actual_depth, g_target_layer_i2);
+
+  sharp_actual_depth = rsGetElementAt_uchar(g_sharp_actual_depth, x + 1);
+  is_this_pixel_on_boundary |=
+    ValidDepthNotOnTheLayer(sharp_actual_depth, g_target_layer_i2);
+
+  if (!is_this_pixel_on_boundary) {
+    return in_sharp_actual_depth;
+  }
+
+  // Marks pixels near the boundary of active pixels to compute matte later.
+  const int kernel_center_x = g_blend_info.dilation_radius;
+  const int kernel_center_y = g_blend_info.dilation_radius;
+  const int kernel_dim_x = 2 * kernel_center_x + 1;
+
+  // index of the current meta data, initailly set to top left sharp meta data
+  // Moves sharp_nbr to the top left corner of this pixel.
+  int current_meta_index = x - (kernel_center_y * g_image_size_i4.s0 + kernel_center_x);  // width
+  const int jump_to_next_pixel = 1;
+  const int jump_to_next_row = g_image_size_i4.s0 - kernel_dim_x;	// width
+  for (int j = -kernel_center_y; j <= kernel_center_y; ++j) {
+    // Initializes dilated_depth as actual_depth.
+    // The dilated_depth will then be updated in distance transform later.
+    // A valid, non-zero dilated_depth indicates distance transform is
+    // needed for the pixel. Otherwise, the distance transform will be
+    // skipped.
+    for (int i = -kernel_center_x; i <= kernel_center_x; ++i) {
+      sharp_actual_depth = rsGetElementAt_uchar(g_sharp_actual_depth, current_meta_index);
+      rsSetElementAt_uchar(g_sharp_dilated_depth, sharp_actual_depth, current_meta_index);
+      current_meta_index += jump_to_next_pixel;
+    }
+    current_meta_index += jump_to_next_row;
+  }
+
+  return in_sharp_actual_depth;
+}
+// Distance transform in processing layers in pass one from the back-most to
+// the sharp depth.
+void __attribute__((kernel))
+ComputeLayerMatteBehindFocalDepth(uchar4 in, uint32_t x, uint32_t y) {
+  // Maps (x,y) to the padded image coordinate system.
+  x += g_image_size_i4.s2;  // margin
+  y += g_image_size_i4.s2;  // margin
+
+  const int index = y * g_image_size_i4.s0 + x;  // width
+
+  uchar sharp_active = rsGetElementAt_uchar(g_sharp_active, index);
+  uchar sharp_dilated_depth = rsGetElementAt_uchar(g_sharp_dilated_depth, index);
+  if (sharp_active == 0 && sharp_dilated_depth) {
+    // This pixel is not active but within the dilation radius of the active
+    // pixels.
+    uchar sharp_actual_depth = rsGetElementAt_uchar(g_sharp_actual_depth, index);
+    if (NotInFrontOfTheLayer(sharp_actual_depth, g_target_layer_i2)) {
+      // We do not need to compute matte for depths in front of this layer,
+      // because these pixels will be over-written later and hence we don't need
+      // to blend them now.
+      Alloc_ComputeLayerMatteHelper(sharp_actual_depth, index, g_image_size_i4,
+        g_blend_info.dilation_radius);
+      }
+  }
+}
+// Pass input allocation directly to kernel ComputeLayerMatteBehindFocalDepth
+// Input: g_sharp_dilated_depth
+// Output: g_sharp_dilated_depth
+uchar __attribute__((kernel))
+ComputeLayerMatteBehindFocalDepthPassInput(uchar in_sharp_dilated_depth, uint32_t x) {
+  uchar sharp_active = rsGetElementAt_uchar(g_sharp_active, x);
+  if (sharp_active == 0 && in_sharp_dilated_depth) {
+    // This pixel is not active but within the dilation radius of the active
+    // pixels.
+    uchar sharp_actual_depth = rsGetElementAt_uchar(g_sharp_actual_depth, x);
+    if (NotInFrontOfTheLayer(sharp_actual_depth, g_target_layer_i2)) {
+      // We do not need to compute matte for depths in front of this layer,
+      // because these pixels will be over-written later and hence we don't need
+      // to blend them now.
+      return ComputeLayerMattePassInputHelper(sharp_actual_depth, x, g_image_size_i4,
+        g_blend_info.dilation_radius);
+    }
+  }
+  return in_sharp_dilated_depth;
+}
+
+// Distance transform in processing layers in pass two from the front-most to
+// the sharp depth.
+void __attribute__((kernel))
+ComputeLayerMatteInFrontOfFocalDepth(uchar4 in, uint32_t x, uint32_t y) {
+  // Maps (x,y) to the padded image coordinate system.
+  x += g_image_size_i4.s2;  // margin
+  y += g_image_size_i4.s2;  // margin
+
+  const int index = y * g_image_size_i4.s0 + x;  // width
+
+  uchar sharp_active = rsGetElementAt_uchar(g_sharp_active, index);
+  uchar sharp_dilated_depth = rsGetElementAt_uchar(g_sharp_dilated_depth, index);
+  if (sharp_active == 0 && sharp_dilated_depth) {
+    // This pixel is not active but within the dilation radius of the active
+    // pixels.
+    float4 fuzzy_RGBA = rsGetElementAt_float4(g_fuzzy_RGBA, index);
+    if (fuzzy_RGBA.a < g_kAlmostOne) {
+      uchar sharp_actual_depth = rsGetElementAt_uchar(g_sharp_actual_depth, index);
+      Alloc_ComputeLayerMatteHelper(sharp_actual_depth, index, g_image_size_i4,
+        g_blend_info.dilation_radius);
+    }
+  }
+}
+
+// Pass input allocation directly into kernel ComputeLayerMatteInFrontOfFocalDepth
+// Input: g_sharp_dilated_depth
+// Output: g_sharp_dilated_depth
+uchar __attribute__((kernel))
+ComputeLayerMatteInFrontOfFocalDepthPassInput(uchar in_sharp_dilated_depth, uint32_t x) {
+  uchar sharp_active = rsGetElementAt_uchar(g_sharp_active, x);
+  if (sharp_active == 0 && in_sharp_dilated_depth) {
+    // This pixel is not active but within the dilation radius of the active
+    // pixels.
+    float4 fuzzy_RGBA = rsGetElementAt_float4(g_fuzzy_RGBA, x);
+    if (fuzzy_RGBA.a < g_kAlmostOne) {
+      uchar sharp_actual_depth = rsGetElementAt_uchar(g_sharp_actual_depth, x);
+      return ComputeLayerMattePassInputHelper(sharp_actual_depth,x, g_image_size_i4,
+                        g_blend_info.dilation_radius);
+    }
+  }
+  return in_sharp_dilated_depth;
+}
+
+// Computes integral image for target layer in processing layers in pass one
+// from the back-most to the sharp depth.
+void __attribute__((kernel))
+ComputeIntegralImageForLayerBehindFocalDepth(uchar4 in, uint32_t x,
+                                             uint32_t y) {
+  // Maps (x,y) to the padded image coordinate system.
+  // Kernel invocation should make sure x = 0.
+  y += g_image_size_i4.s2;  // margin
+
+  const int index = y * g_image_size_i4.s0;  // width
+  float4 sharp_RGBA;
+  float4 integral_RGBA;
+  uchar sharp_actual_depth;
+
+  int current_index = index;
+  int last_index = index + g_image_size_i4.s0;  // width
+
+  // Gets the visibility probability lookup table for the target layer depth.
+  const float *vis_prob =
+    g_visibility_probability.lut[g_target_layer_i2.s0];
+
+  float4 prev_integral_value = 0;
+  for(; current_index != last_index; current_index++) {
+    sharp_RGBA = rsGetElementAt_float4(g_sharp_RGBA, current_index);
+    sharp_actual_depth = rsGetElementAt_uchar(g_sharp_actual_depth, current_index);
+
+    const float weight = vis_prob[sharp_actual_depth];
+
+    float4 this_value = {weight * sharp_RGBA.r, weight * sharp_RGBA.g,
+                         weight * sharp_RGBA.b, weight};
+    prev_integral_value = prev_integral_value + this_value;
+
+    // update pointer image
+    integral_RGBA = prev_integral_value;
+    rsSetElementAt_float4(g_integral_RGBA, integral_RGBA, current_index);
+  }
+}
+
+void __attribute__((kernel))
+ComputeIntegralImageForLayerInFrontOfFocalDepth(uchar4 in, uint32_t x,
+                                                uint32_t y) {
+  // Maps (x,y) to the padded image coordinate system.
+  // Kernel invocation should make sure x = 0.
+  y += g_image_size_i4.s2;  // margin
+
+  const int index = y * g_image_size_i4.s0;  // width
+
+  float4 sharp_RGBA;
+  float4 integral_RGBA;
+  uchar sharp_actual_depth;
+
+  int current_index = index;
+  int last_index = index + g_image_size_i4.s0;  // width
+  float4 prev_integral_value = 0;
+  for(; current_index != last_index; current_index++) {
+    sharp_RGBA = rsGetElementAt_float4(g_sharp_RGBA, current_index);
+    sharp_actual_depth = rsGetElementAt_uchar(g_sharp_actual_depth, current_index);
+
+    const float weight = ValidDepth(sharp_actual_depth);
+    float4 this_value = {weight * sharp_RGBA.r, weight * sharp_RGBA.g,
+                         weight * sharp_RGBA.b, weight};
+    prev_integral_value = prev_integral_value + this_value;
+
+    // Update image
+    integral_RGBA = prev_integral_value;
+    rsSetElementAt_float4(g_integral_RGBA, integral_RGBA, current_index);
+  }
+}
+
+// Filters target layer in processing layers in pass one from the back-most to
+// the sharp depth.
+void __attribute__((kernel))
+FilterLayerBehindFocalDepth(uchar4 in, uint32_t x, uint32_t y) {
+  // Maps (x,y) to the padded image coordinate system.
+  x += g_image_size_i4.s2;  // margin
+  y += g_image_size_i4.s2;  // margin
+
+  const int index = y * g_image_size_i4.s0 + x;  // width
+
+  uchar matte = rsGetElementAt_uchar(g_sharp_matte, index);
+  if (matte == 0) {
+    return;
+  }
+
+  // At this point, sharp->dilated_depth must be within the depth range of
+  // this target layer. Hence, the kernel_info below is a valid pointer.
+  uchar sharp_dilated_depth = rsGetElementAt_uchar(g_sharp_dilated_depth, index);
+  const float4 alloc_kernel_info = rsGetElementAt_float4(galloc_kernel_info, sharp_dilated_depth - g_target_layer_i2.s1);
+
+  float4 result;
+  // Saves the filtering result in g_fuzzy_image temporarily.
+  if (g_use_integral_image) {
+    result = AllocFilterLayerUsingRowwiseIntegralImage(
+        x, y, g_image_size_i4, alloc_kernel_info, &g_secant_offset);
+  } else {
+    result = AllocFilterLayerBehindFocalDepthHelper(
+        x, y, g_image_size_i4, g_target_layer_i2,
+        alloc_kernel_info, &g_visibility_probability);
+  }
+  rsSetElementAt_float4(g_fuzzy_RGBA, result, index);
+  // Once the kernel invoke is completed, uses the g_fuzzy_image to update
+  // g_sharp_image.
+}
+
+// Directly pass allocation to kernel FilterLayerBehindFocalDepth
+// Input: g_fuzzy_RGBA
+// Output: g_fuzzy_RGBA
+float4 __attribute__((kernel))
+FilterLayerBehindFocalDepthPassInput(float4 in_fuzzy_RGBA, uint32_t x) {
+  uchar sharp_matte = rsGetElementAt_uchar(g_sharp_matte, x);
+  if (sharp_matte == 0) {
+    return in_fuzzy_RGBA;
+  }
+
+  // At this point, sharp->dilated_depth must be within the depth range of
+  // this target layer. Hence, the kernel_info below is a valid pointer.
+  uchar sharp_dilated_depth = rsGetElementAt_uchar(g_sharp_dilated_depth, x);
+  const float4 alloc_kernel_info = rsGetElementAt_float4(galloc_kernel_info, sharp_dilated_depth - g_target_layer_i2.s1);
+
+  float4 result;
+  // Saves the filtering result in g_fuzzy_image temporarily.
+  if (g_use_integral_image) {
+    result = AllocFilterLayerUsingRowwiseIntegralImage(
+        x, 0, g_image_size_i4, alloc_kernel_info, &g_secant_offset);
+  } else {
+    result = AllocFilterLayerBehindFocalDepthHelper(
+        x, 0, g_image_size_i4, g_target_layer_i2,
+        alloc_kernel_info, &g_visibility_probability);
+  }
+  return result;
+  // Once the kernel invoke is completed, uses the g_fuzzy_image to update
+  // g_sharp_image.
+}
+
+// Filters target layer in processing layers in pass two from the front-most
+// to the focus depth.
+void __attribute__((kernel))
+FilterLayerInFrontOfFocalDepth(uchar4 in, uint32_t x, uint32_t y) {
+  // Maps (x,y) to the padded image coordinate system.
+  x += g_image_size_i4.s2;  // margin
+  y += g_image_size_i4.s2;  // margin
+
+  const int index = y * g_image_size_i4.s0 + x;  // width
+  uchar depth = rsGetElementAt_uchar(g_sharp_dilated_depth, index);
+
+  if (depth == 0) {
+    return;
+  }
+
+  // At this point, this pixel must be either active or close enough to an
+  // active pixel.
+  // For such a pixel, its matte value can still be zero if its distance
+  // transform to the active pixels is larger than dilation_radius.
+  uchar matte = rsGetElementAt_uchar(g_sharp_matte, index);
+  // Resets fields of this pixel to prepare for the next iteration.
+
+  // Does not reset sharp->actual_depth, which will be used in future
+  // iterations.
+  rsSetElementAt_uchar(g_sharp_active, 0, index);
+  rsSetElementAt_uchar(g_sharp_matte, 0, index);
+  rsSetElementAt_uchar(g_sharp_dilated_depth, 0, index);
+
+  if (matte == 0) {
+    return;
+  }
+
+  // At this point, sharp->dilated_depth must be within the depth range of
+  // this target layer. Hence kernel_info below is a valid pointer.
+  const float4 alloc_kernel_info = rsGetElementAt_float4(galloc_kernel_info, depth - g_target_layer_i2.s1);
+
+  float4 result;
+
+  if (g_use_integral_image) {
+    result = AllocFilterLayerUsingRowwiseIntegralImage(
+        x, y, g_image_size_i4, alloc_kernel_info, &g_secant_offset);
+  } else {
+    result = AllocFilterLayerInFrontOfFocalDepthHelper(
+        x, y, g_image_size_i4, alloc_kernel_info);
+  }
+
+  // Because matte !=0 here, fuzzy->a < g_kAlmostOne must be true.
+  // Otherwise, ComputeLayerMatteHelper won't be called in
+  // ComputeLayerMatteInFrontOfFocalDepth, which results in a zero matte.
+
+  // Accumulates the filtering result to fuzzy.
+  float4 fuzzy_RGBA = rsGetElementAt_float4(g_fuzzy_RGBA, index);
+  const float capacity = 1.0f - fuzzy_RGBA.a;
+  const float factor = capacity * (float)matte * g_blend_info.matte_normalizer;
+  fuzzy_RGBA.r += factor * result.r;
+  fuzzy_RGBA.g += factor * result.g;
+  fuzzy_RGBA.b += factor * result.b;
+  fuzzy_RGBA.a += factor;
+  rsSetElementAt_float4(g_fuzzy_RGBA, fuzzy_RGBA, index);
+}
+
+// Pass input allocation directly to kernel FilterLayerInFrontOfFocalDepth
+// Input: g_sharp_dilated_depth
+// Output: g_sharp_dilated_depth
+uchar __attribute__((kernel))
+FilterLayerInFrontOfFocalDepthPassInput(uchar in_sharp_dilated_depth, uint32_t x) {
+  if (in_sharp_dilated_depth == 0) {
+    return 0;
+  }
+  // At this point, this pixel must be either active or close enough to an
+  // active pixel.
+  // For such a pixel, its matte value can still be zero if its distance
+  // transform to the active pixels is larger than dilation_radius.
+  uchar matte = rsGetElementAt_uchar(g_sharp_matte, x);
+  // Resets fields of this pixel to prepare for the next iteration.
+
+  // Does not reset sharp->actual_depth, which will be used in future
+  // iterations.
+  rsSetElementAt_uchar(g_sharp_active, 0, x);
+  rsSetElementAt_uchar(g_sharp_matte, 0, x);
+
+  if (matte == 0) {
+    return 0;
+  }
+
+  // At this point, sharp->dilated_depth must be within the depth range of
+  // this target layer. Hence kernel_info below is a valid pointer.
+  const float4 alloc_kernel_info = rsGetElementAt_float4(galloc_kernel_info, in_sharp_dilated_depth - g_target_layer_i2.s1);
+
+  float4 result;
+
+  if (g_use_integral_image) {
+    result = AllocFilterLayerUsingRowwiseIntegralImage(
+        x, 0, g_image_size_i4, alloc_kernel_info, &g_secant_offset);
+  } else {
+    result = AllocFilterLayerInFrontOfFocalDepthHelper(
+        x, 0, g_image_size_i4, alloc_kernel_info);
+  }
+
+  // Because matte !=0 here, fuzzy->a < g_kAlmostOne must be true.
+  // Otherwise, ComputeLayerMatteHelper won't be called in
+  // ComputeLayerMatteInFrontOfFocalDepth, which results in a zero matte.
+
+  // Accumulates the filtering result to fuzzy.
+  float4 fuzzy_RGBA = rsGetElementAt_float4(g_fuzzy_RGBA, x);
+  const float capacity = 1.0f - fuzzy_RGBA.a;
+  const float factor = capacity * (float)matte * g_blend_info.matte_normalizer;
+  fuzzy_RGBA.r += factor * result.r;
+  fuzzy_RGBA.g += factor * result.g;
+  fuzzy_RGBA.b += factor * result.b;
+  fuzzy_RGBA.a += factor;
+  rsSetElementAt_float4(g_fuzzy_RGBA, fuzzy_RGBA, x);
+  return 0;
+}
+
+// Replaces active pixels in g_sharp_image with the filtering result saved in
+// g_fuzzy_image. Does the replacement in a soft way by blending g_sharp_image
+// and g_fuzzy_image using the matte field.
+void __attribute__((kernel))
+UpdateSharpImageUsingFuzzyImage(uchar4 in, uint32_t x, uint32_t y) {
+  // Maps (x,y) to the padded image coordinate system.
+  x += g_image_size_i4.s2;  // margin
+  y += g_image_size_i4.s2;  // margin
+
+  const int index = y * g_image_size_i4.s0 + x;  // width
+
+  uchar depth = rsGetElementAt_uchar(g_sharp_dilated_depth, index);
+
+  if (depth == 0) {
+    return;
+  }
+
+  // At this point, this pixel must be either active or close enough to an
+  // active pixel.
+  // For such a pixel, its matte value can still be zero if its distance
+  // transform to the active pixels is larger than dilation_radius.
+
+  // Resets fields of this pixel to prepare for future layer processing (pass
+  // two).
+
+  uchar matte = rsGetElementAt_uchar(g_sharp_matte, index);
+  rsSetElementAt_uchar(g_sharp_active, 0, index);
+  rsSetElementAt_uchar(g_sharp_matte, 0, index);
+  rsSetElementAt_uchar(g_sharp_dilated_depth, 0, index);
+  // Does not reset sharp->actual depth, which will be used in future
+  // layer processing.
+
+  if (matte == 0) {
+    return;
+  }
+
+  float factor = (float)matte * g_blend_info.matte_normalizer;
+  // The following blending amounts to:
+  // sharp = (1 - factor) * sharp + factor * fuzzy.
+  float4 sharp_RGBA = rsGetElementAt_float4(g_sharp_RGBA, index);
+  float4 fuzzy_RGBA = rsGetElementAt_float4(g_fuzzy_RGBA, index);
+  sharp_RGBA.r += factor * (fuzzy_RGBA.r - sharp_RGBA.r);
+  sharp_RGBA.g += factor * (fuzzy_RGBA.g - sharp_RGBA.g);
+  sharp_RGBA.b += factor * (fuzzy_RGBA.b - sharp_RGBA.b);
+  fuzzy_RGBA.r = 0;
+  fuzzy_RGBA.g = 0;
+  fuzzy_RGBA.b = 0;
+  fuzzy_RGBA.a = 0;
+  rsSetElementAt_float4(g_sharp_RGBA, sharp_RGBA, index);
+  rsSetElementAt_float4(g_fuzzy_RGBA, fuzzy_RGBA, index);
+}
+
+// Passes allocation for g_sharp_meta from java code
+// so that one rsGetElement is eliminated.
+// Still requires set and get for g_fuzzy_RGBA and g_sharp_RGBA
+// Input: g_sharp_dilated_depth
+// Output: g_sharp_dilated_depth
+uchar __attribute__((kernel))
+UpdateSharpUsingFuzzyPassInput(uchar in_sharp_dilated_depth, uint32_t x) {
+  // Variable in is the uchar4 for sharp_meta
+  if (in_sharp_dilated_depth == 0) {
+    return 0;
+  }
+
+  // At this point, this pixel must be either active or close enough to an
+  // active pixel.
+  // For such a pixel, its matte value can still be zero if its distance
+  // transform to the active pixels is larger than dilation_radius.
+
+  // Resets fields of this pixel to prepare for future layer processing (pass
+  // two).
+
+  // Index of g_sharp_meta should align with g_fuzzy_RGBA and g_sharp_RGBA
+  uchar matte = rsGetElementAt_uchar(g_sharp_matte, x);
+  rsSetElementAt_uchar(g_sharp_active, 0, x);
+  rsSetElementAt_uchar(g_sharp_matte, 0, x);
+  // Does not reset sharp->actual depth, which will be used in future
+  // layer processing.
+
+  if (matte == 0) {
+    return 0;
+  }
+
+  float factor = (float)matte * g_blend_info.matte_normalizer;
+  // The following blending amounts to:
+  // sharp = (1 - factor) * sharp + factor * fuzzy.
+  float4 sharp_RGBA = rsGetElementAt_float4(g_sharp_RGBA, x);
+  float4 fuzzy_RGBA = rsGetElementAt_float4(g_fuzzy_RGBA, x);
+  sharp_RGBA.r += factor * (fuzzy_RGBA.r - sharp_RGBA.r);
+  sharp_RGBA.g += factor * (fuzzy_RGBA.g - sharp_RGBA.g);
+  sharp_RGBA.b += factor * (fuzzy_RGBA.b - sharp_RGBA.b);
+  fuzzy_RGBA.r = 0;
+  fuzzy_RGBA.g = 0;
+  fuzzy_RGBA.b = 0;
+  fuzzy_RGBA.a = 0;
+  rsSetElementAt_float4(g_sharp_RGBA, sharp_RGBA, x);
+  rsSetElementAt_float4(g_fuzzy_RGBA, fuzzy_RGBA, x);
+  return 0;
+}
+
+// Fills in the pixels on or behind the focal depth in g_fuzzy_image using
+// pixels in g_sharp_image. Does the filling in a soft way by blending using the
+// matte field.
+void __attribute__((kernel))
+FinalizeFuzzyImageUsingSharpImage(uchar4 in, uint32_t x, uint32_t y) {
+  // Maps (x,y) to the padded image coordinate system.
+  x += g_image_size_i4.s2;  // margin
+  y += g_image_size_i4.s2;  // margin
+
+  const int index = y * g_image_size_i4.s0 + x;  // width
+
+  float4 sharp_RGBA = rsGetElementAt_float4(g_sharp_RGBA, index);
+  float4 fuzzy_RGBA = rsGetElementAt_float4(g_fuzzy_RGBA, index);
+  uchar sharp_actual_depth = rsGetElementAt_uchar(g_sharp_actual_depth, index);
+
+  if (sharp_actual_depth && sharp_actual_depth <= g_focal_layer_i2.s0) {  // g_focal_layer.front_depth
+    float capacity = 1.0f - fuzzy_RGBA.a;
+    fuzzy_RGBA.r += sharp_RGBA.r * capacity;
+    fuzzy_RGBA.g += sharp_RGBA.g * capacity;
+    fuzzy_RGBA.b += sharp_RGBA.b * capacity;
+    fuzzy_RGBA.a = 1.0f;
+    rsSetElementAt_float4(g_fuzzy_RGBA, fuzzy_RGBA, index);
+  }
+}
+// Pass allocation directly to kernel FinalizeFuzzyImageUsingSharpImage
+// Input: g_sharp_actual_depth
+// Output: g_fuzzy_RGBA
+float4 __attribute__((kernel))
+FinalizeFuzzyImageUsingSharpImagePassInput(uchar in_sharp_actual_depth, uint32_t x) {
+  float4 sharp_RGBA = rsGetElementAt_float4(g_sharp_RGBA, x);
+  float4 fuzzy_RGBA = rsGetElementAt_float4(g_fuzzy_RGBA, x);
+
+  if (in_sharp_actual_depth && in_sharp_actual_depth <= g_focal_layer_i2.s0) {  // g_focal_layer.front_depth
+    float capacity = 1.0f - fuzzy_RGBA.a;
+    fuzzy_RGBA.r += sharp_RGBA.r * capacity;
+    fuzzy_RGBA.g += sharp_RGBA.g * capacity;
+    fuzzy_RGBA.b += sharp_RGBA.b * capacity;
+    fuzzy_RGBA.a = 1.0f;
+    return fuzzy_RGBA;
+  }
+  return rsGetElementAt_float4(g_fuzzy_RGBA, x);
+}
+
+// Copies g_fuzzy_image to output color image, excluding the padded margin.
+// (x, y) is the pixel coordinate in the output image.
+uchar4 __attribute__((kernel)) PackOutputImage(uint32_t x, uint32_t y) {
+  // Maps (x,y) to the padded image coordinate system.
+  x += g_image_size_i4.s2;  // margin
+  y += g_image_size_i4.s2;  // margin
+
+  // Returns the pixel at (x,y) after applying CRF.
+  const int index = y * g_image_size_i4.s0 + x;  // width
+
+  const float4 fuzzy_RGBA = rsGetElementAt_float4(g_fuzzy_RGBA, index);
+  float4 result;
+
+  result.r = ApplyLUT_Float(fuzzy_RGBA.r, g_camera_response.lut_apply_crf_float);
+  result.g = ApplyLUT_Float(fuzzy_RGBA.g, g_camera_response.lut_apply_crf_float);
+  result.b = ApplyLUT_Float(fuzzy_RGBA.b, g_camera_response.lut_apply_crf_float);
+  result.a = fuzzy_RGBA.a;
+
+  return rsPackColorTo8888(result);
+}
+
+// Copies g_fuzzy_image to output color image, excluding the padded margin.
+// (x, y) is the pixel coordinate in the output image.
+uchar4 __attribute__((kernel)) PackSharpImage(uint32_t x, uint32_t y) {
+  // Maps (x,y) to the padded image coordinate system.
+  x += g_image_size_i4.s2;  // margin
+  y += g_image_size_i4.s2;  // margin
+
+  // Returns the pixel at (x,y) after applying CRF.
+  const int index = y * g_image_size_i4.s0 + x;  // width
+
+  const float4 sharp_RGBA = rsGetElementAt_float4(g_sharp_RGBA, index);
+  float4 result;
+
+  result.r = ApplyLUT_Float(sharp_RGBA.r, g_camera_response.lut_apply_crf_float);
+  result.g = ApplyLUT_Float(sharp_RGBA.g, g_camera_response.lut_apply_crf_float);
+  result.b = ApplyLUT_Float(sharp_RGBA.b, g_camera_response.lut_apply_crf_float);
+
+  return rsPackColorTo8888(result);
+}
+
+// Copies g_fuzzy_image to output color image, excluding the padded margin.
+// (x, y) is the pixel coordinate in the output image.
+uchar4 __attribute__((kernel)) PackFuzzyImage(uint32_t x, uint32_t y) {
+  // Maps (x,y) to the padded image coordinate system.
+  x += g_image_size_i4.s2;  // margin
+  y += g_image_size_i4.s2;  // margin
+
+  // Returns the pixel at (x,y) after applying CRF.
+  const int index = y * g_image_size_i4.s0 + x;  // width
+
+  const float4 fuzzy_RGBA = rsGetElementAt_float4(g_fuzzy_RGBA, index);
+  float4 result;
+
+  result.r = ApplyLUT_Float(fuzzy_RGBA.r, g_camera_response.lut_apply_crf_float);
+  result.g = ApplyLUT_Float(fuzzy_RGBA.g, g_camera_response.lut_apply_crf_float);
+  result.b = ApplyLUT_Float(fuzzy_RGBA.b, g_camera_response.lut_apply_crf_float);
+  result.a = fuzzy_RGBA.a;
+
+  return rsPackColorTo8888(result);
+}
+
+void SetTargetLayer(int front, int back) {
+  g_target_layer_i2.s0 = front;
+  g_target_layer_i2.s1 = back;
+}
+
+void SetBlendInfo(int radius) {
+  g_blend_info.dilation_radius = radius;
+  g_blend_info.matte_normalizer = 1.0f / (radius + 1);
+}
+
+void SetUseIntegralImage(int use_integral_image) {
+  g_use_integral_image = use_integral_image;
+}
+
+void InitializeFast(int width, int height, int margin, int front, int back) {
+  // Initialize image size
+  g_image_size_i4.s0 = width;
+  g_image_size_i4.s1 = height;
+  g_image_size_i4.s2 = margin;
+
+  // Initialize focal layer
+  g_focal_layer_i2.s0 = front;
+  g_focal_layer_i2.s1 = back;
+
+  const int num_pixels = width * height;
+
+  for(int i = 0; i < num_pixels; i++) {
+    float4 zerof4 = {0.0f, 0.0f, 0.0f, 0.0f};
+    rsSetElementAt_float4(g_sharp_RGBA, zerof4, i);
+    rsSetElementAt_float4(g_fuzzy_RGBA, zerof4, i);
+    rsSetElementAt_float4(g_integral_RGBA, zerof4, i);
+
+    rsSetElementAt_uchar(g_sharp_actual_depth, 0, i);
+    rsSetElementAt_uchar(g_sharp_active, 0, i);
+    rsSetElementAt_uchar(g_sharp_matte, 0, i);
+    rsSetElementAt_uchar(g_sharp_dilated_depth, 0, i);
+  }
+
+  InitializeDefaultCameraResponse(&g_camera_response);
+  InitializeRadiusOffset(&g_secant_offset);
+  InitializeVisibilityProbability(&g_visibility_probability, front, back);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/refocus/layered_filter_fast_f32.rs b/tests/tests/renderscript/src/android/renderscript/cts/refocus/layered_filter_fast_f32.rs
new file mode 100644
index 0000000..ebb9baf
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/refocus/layered_filter_fast_f32.rs
@@ -0,0 +1,565 @@
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts.refocus)
+
+// This is a speedup version of layered_filter_f32.rs using summation table.
+// Several kernel functions and global functions for refocus rendering using
+// Render Script. These functions are accessible from Java side. The assumptions
+// made in this file are (consistent with Java side):
+//
+// 1. The depth value varies between 1 and number of depth levels. 0 is reserved
+// for invalid pixels, e.g., padded pixels around image boundary.
+// 2. The depth value represents inverse depth. Larger depths are closer to the
+// camera.
+// 3. The depth values are grouped into several blending layers.
+// 4. The focal layer (i.e., the global variable g_focal_layer) is the depth
+// value interval that has no blur.
+//
+// For the following kernel functions defined in this rs file, the input
+// arguments have the following meaning:
+//
+// @param in an input RGBD pixel with @in.a being quantized inverse depth.
+// @param x x-coordinate of @param in in the unpadded input image.
+// @param y y-coordinate of @param in in the unpadded input image.
+
+#include "image_and_kernel.rsh"
+#include "camera_response.rsh"
+#include "layer_info.rsh"
+#include "pixel_format_f32.rsh"
+#include "luts_for_speedup_f32.rsh"
+#include "layered_filter_f32_helper.rsh"
+
+// Image size of padded images: g_sharp_image and g_fuzzy_image.
+static ImageSize_t g_image_size;
+
+static CameraResponse_t g_camera_response;
+
+float4 *g_sharp_image_buffer = NULL;
+float4 *g_fuzzy_image_buffer = NULL;
+float4 *g_integral_image_buffer = NULL;
+
+// This image buffer is used to store input image initially.
+// Then the input image gets updated as each layer is processed from the
+// back-most to the focal depth. This image buffer is padded.
+static SharpPixelF32_t *g_sharp_image = NULL;
+
+// This image buffer is used to save an integral image of g_sharp_image
+// modulated by the visibility mask.
+static float4 *g_integral_image = NULL;
+
+// whether or not to use integral image in this iteration.
+static int g_use_integral_image;
+
+// This image buffer is used to store output image, both for intermediate
+// results and final result.
+// In the first pass from back-most to focal depth, g_fuzzy_image holds the
+// layer filtering result temporarily and then the result is used to update the
+// input image after each layer is processed.
+// In the second pass from front-most to focal depth, g_fuzzy_image accumulates
+// all the layer filtering results and in the end, the accumulation result is
+// blended with the input image (which has been updated in the first pass) to
+// generate the final result. This image buffer is padded.
+static FuzzyPixelF32_t *g_fuzzy_image = NULL;
+
+// The info of current layer that is being processed.
+static LayerInfo_t g_target_layer;
+// The dilation radius that controls how the current layer should be blended
+// with previous layers.
+static BlendInfo_t g_blend_info;
+
+// The depth level that is in focus.
+static LayerInfo_t g_focal_layer;
+
+// For depth d, let n = d-g_target_layer.back_depth be the relative depth index.
+// g_kernel_stack+g_kernel_info[n].offset is the pointer to the kernel matrix
+// for this depth level.
+// The kernel has a center at
+// (g_kernel_info[n].radius_x, g_kernel_info[n].radius_y).
+// And the kernel has a size of
+// (2*center_x+1, 2*center_y+1) ;
+float *g_kernel_stack;
+KernelInfo_t *g_kernel_info;
+
+// Precomputed LUTs for speedup.
+static VisibilityProbability_t g_visibility_probability;
+static SecantOffset_t g_secant_offset;
+
+static const float g_kOneOver255 = 1.0f / 255.0f;
+static const float g_kAlmostOne = .998f;
+
+// (1 << g_kDepthScaleShift) must be the same as BlurStack::DEPTH_SCALE.
+static const int g_kDepthScaleShift = 2;
+// g_kMaxDepth must be the same as BlurStack::MAX_DETPH.
+static const int g_kMaxDepth = 256 >> g_kDepthScaleShift;
+
+// Copies an input (unpadded) RGBD image into g_sharp_image, which has been
+// padded with margin. Initialize other fields.
+void __attribute__((kernel))
+UnpackInputImage(uchar4 in, uint32_t x, uint32_t y) {
+  // Maps (x,y) to the padded image coordinate system.
+  x += g_image_size.margin;
+  y += g_image_size.margin;
+
+  const int index = y * g_image_size.width + x;
+
+  SharpPixelF32_t *sharp = g_sharp_image + index;
+  sharp->red = in.r * g_kOneOver255;
+  sharp->green = in.g * g_kOneOver255;
+  sharp->blue = in.b * g_kOneOver255;
+
+  sharp->red =
+      ApplyLUT_Float(sharp->red, g_camera_response.lut_remove_crf_float);
+  sharp->green =
+      ApplyLUT_Float(sharp->green, g_camera_response.lut_remove_crf_float);
+  sharp->blue =
+      ApplyLUT_Float(sharp->blue, g_camera_response.lut_remove_crf_float);
+
+  sharp->actual_depth = g_kMaxDepth - (in.a >> g_kDepthScaleShift);
+
+  sharp->active = 0;
+
+  sharp->matte = 0;
+
+  sharp->dilated_depth = 0;
+}
+
+// Marks active pixels that are on the target layer.
+// Initializes the matte of active pixels to be the dilation_radius+1, which is
+// equivalent to 1.
+// Initializes dilated_depth of active pixels and pixels that are close to
+// active pixels to be actual depths.
+void __attribute__((kernel)) MarkLayerMask(uchar4 in, uint32_t x, uint32_t y) {
+  const int actual_depth = g_kMaxDepth - (in.a >> g_kDepthScaleShift);
+  if (!OnTheLayer(actual_depth, &g_target_layer)) return;
+
+  // Maps (x,y) to the padded image coordinate system.
+  x += g_image_size.margin;
+  y += g_image_size.margin;
+
+  const int index = y * g_image_size.width + x;  // index of this pixel
+  SharpPixelF32_t *sharp = g_sharp_image + index;
+
+  // Marks this pixel as active.
+  sharp->active = 1;
+  sharp->matte = g_blend_info.dilation_radius + 1;
+  sharp->dilated_depth = sharp->actual_depth;
+
+  // Next, tries to figure out whether or not this pixel is on the boundary
+  // between active and inactive pixels
+  int is_this_pixel_on_boundary = 0;
+  SharpPixelF32_t *sharp_nbr = NULL;
+
+  // Top
+  sharp_nbr = sharp - g_image_size.width;
+  is_this_pixel_on_boundary |=
+      ValidDepthNotOnTheLayer(sharp_nbr->actual_depth, &g_target_layer);
+
+  // Bottom
+  sharp_nbr = sharp + g_image_size.width;
+  is_this_pixel_on_boundary |=
+      ValidDepthNotOnTheLayer(sharp_nbr->actual_depth, &g_target_layer);
+
+  // Left
+  sharp_nbr = sharp - 1;
+  is_this_pixel_on_boundary |=
+      ValidDepthNotOnTheLayer(sharp_nbr->actual_depth, &g_target_layer);
+
+  // Right
+  sharp_nbr = sharp + 1;
+  is_this_pixel_on_boundary |=
+      ValidDepthNotOnTheLayer(sharp_nbr->actual_depth, &g_target_layer);
+
+  if (!is_this_pixel_on_boundary) {
+    return;
+  }
+
+  // Marks pixels near the boundary of active pixels to compute matte later.
+  const int kernel_center_x = g_blend_info.dilation_radius;
+  const int kernel_center_y = g_blend_info.dilation_radius;
+  const int kernel_dim_x = 2 * kernel_center_x + 1;
+
+  // Moves sharp_nbr to the top left corner of this pixel.
+  sharp_nbr = sharp - (kernel_center_y * g_image_size.width + kernel_center_x);
+
+  // Visits every pixel in the window of radius (center_x,center_y)
+  // surrounding this pixel.
+  const int jump_to_next_pixel = 1;
+  const int jump_to_next_row = g_image_size.width - kernel_dim_x;
+  for (int j = -kernel_center_y; j <= kernel_center_y; ++j) {
+    for (int i = -kernel_center_x; i <= kernel_center_x; ++i) {
+      // Initializes dilated_depth as actual_depth.
+      // The dilated_depth will then be updated in distance transform later.
+      // A valid, non-zero dilated_depth indicates distance transform is
+      // needed for the pixel. Otherwise, the distance transform will be
+      // skipped.
+      sharp_nbr->dilated_depth = sharp_nbr->actual_depth;
+
+      sharp_nbr += jump_to_next_pixel;
+    }
+    sharp_nbr += jump_to_next_row;
+  }
+}
+
+// Distance transform in processing layers in pass one from the back-most to
+// the sharp depth.
+void __attribute__((kernel))
+ComputeLayerMatteBehindFocalDepth(uchar4 in, uint32_t x, uint32_t y) {
+  // Maps (x,y) to the padded image coordinate system.
+  x += g_image_size.margin;
+  y += g_image_size.margin;
+
+  const int index = y * g_image_size.width + x;
+  SharpPixelF32_t *sharp = g_sharp_image + index;
+
+  if (sharp->active == 0 && sharp->dilated_depth) {
+    // This pixel is not active but within the dilation radius of the active
+    // pixels.
+    if (NotInFrontOfTheLayer(sharp->actual_depth, &g_target_layer)) {
+      // We do not need to compute matte for depths in front of this layer,
+      // because these pixels will be over-written later and hence we don't need
+      // to blend them now.
+      ComputeLayerMatteHelper(sharp, x, y, &g_image_size,
+                              g_blend_info.dilation_radius);
+    }
+  }
+}
+
+// Distance transform in processing layers in pass two from the front-most to
+// the sharp depth.
+void __attribute__((kernel))
+ComputeLayerMatteInFrontOfFocalDepth(uchar4 in, uint32_t x, uint32_t y) {
+  // Maps (x,y) to the padded image coordinate system.
+  x += g_image_size.margin;
+  y += g_image_size.margin;
+
+  const int index = y * g_image_size.width + x;
+  SharpPixelF32_t *sharp = g_sharp_image + index;
+
+  if (sharp->active == 0 && sharp->dilated_depth) {
+    // This pixel is not active but within the dilation radius of the active
+    // pixels.
+    FuzzyPixelF32_t *fuzzy = g_fuzzy_image + index;
+    if (fuzzy->alpha < g_kAlmostOne) {
+      // This pixel has not been completely covered by layers in front of the
+      // current layer.
+      ComputeLayerMatteHelper(sharp, x, y, &g_image_size,
+                              g_blend_info.dilation_radius);
+    }
+  }
+}
+
+// Computes integral image for target layer in processing layers in pass one
+// from the back-most to the sharp depth.
+void __attribute__((kernel))
+ComputeIntegralImageForLayerBehindFocalDepth(uchar4 in, uint32_t x,
+                                             uint32_t y) {
+  // Maps (x,y) to the padded image coordinate system.
+  // Kernel invocation should make sure x = 0.
+  y += g_image_size.margin;
+
+  // Gets the visibility probability lookup table for the target layer depth.
+  const float *vis_prob =
+      g_visibility_probability.lut[g_target_layer.front_depth];
+
+  const int index = y * g_image_size.width;
+  const SharpPixelF32_t *sharp = g_sharp_image + index;
+  const SharpPixelF32_t *last_sharp = sharp + g_image_size.width;
+  float4 *integral = g_integral_image + index;
+  float4 prev_integral_value = 0;
+  for (; sharp != last_sharp; sharp++, integral++) {
+    const float weight = vis_prob[sharp->actual_depth];
+    float4 this_value = {weight * sharp->red, weight * sharp->green,
+                         weight * sharp->blue, weight};
+    *integral = prev_integral_value + this_value;
+    prev_integral_value = *integral;
+  }
+}
+
+void __attribute__((kernel))
+ComputeIntegralImageForLayerInFrontOfFocalDepth(uchar4 in, uint32_t x,
+                                                uint32_t y) {
+  // Maps (x,y) to the padded image coordinate system.
+  // Kernel invocation should make sure x = 0.
+  y += g_image_size.margin;
+
+  const int index = y * g_image_size.width;
+  const SharpPixelF32_t *sharp = g_sharp_image + index;
+  const SharpPixelF32_t *last_sharp = sharp + g_image_size.width;
+  float4 *integral = g_integral_image + index;
+  float4 prev_integral_value = 0;
+  for (; sharp != last_sharp; sharp++, integral++) {
+    const float weight = ValidDepth(sharp->actual_depth);
+    float4 this_value = {weight * sharp->red, weight * sharp->green,
+                         weight * sharp->blue, weight};
+    *integral = prev_integral_value + this_value;
+    prev_integral_value = *integral;
+  }
+}
+
+// Filters target layer in processing layers in pass one from the back-most to
+// the sharp depth.
+void __attribute__((kernel))
+FilterLayerBehindFocalDepth(uchar4 in, uint32_t x, uint32_t y) {
+  // Maps (x,y) to the padded image coordinate system.
+  x += g_image_size.margin;
+  y += g_image_size.margin;
+
+  const int index = y * g_image_size.width + x;
+  SharpPixelF32_t *sharp = g_sharp_image + index;
+
+  if (sharp->matte == 0) {
+    return;
+  }
+
+  // At this point, sharp->dilated_depth must be within the depth range of
+  // this target layer. Hence, the kernel_info below is a valid pointer.
+  const KernelInfo_t *kernel_info =
+      g_kernel_info + sharp->dilated_depth - g_target_layer.back_depth;
+
+  // Saves the filtering result in g_fuzzy_image temporarily.
+  if (g_use_integral_image) {
+    g_fuzzy_image[index] = FilterLayerUsingRowwiseIntegralImage(
+        x, y, &g_image_size, kernel_info, g_integral_image, &g_secant_offset);
+  } else {
+    g_fuzzy_image[index] = FilterLayerBehindFocalDepthHelper(
+        x, y, &g_image_size, &g_target_layer, kernel_info, g_kernel_stack,
+        g_sharp_image, &g_visibility_probability);
+  }
+  // Once the kernel invoke is completed, uses the g_fuzzy_image to update
+  // g_sharp_image.
+}
+
+// Filters target layer in processing layers in pass two from the front-most
+// to the focus depth.
+void __attribute__((kernel))
+FilterLayerInFrontOfFocalDepth(uchar4 in, uint32_t x, uint32_t y) {
+  // Maps (x,y) to the padded image coordinate system.
+  x += g_image_size.margin;
+  y += g_image_size.margin;
+
+  const int index = y * g_image_size.width + x;
+  SharpPixelF32_t *sharp = g_sharp_image + index;
+
+  const int depth = sharp->dilated_depth;
+  if (depth == 0) {
+    return;
+  }
+
+  // At this point, this pixel must be either active or close enough to an
+  // active pixel.
+  // For such a pixel, its matte value can still be zero if its distance
+  // transform to the active pixels is larger than dilation_radius.
+  int matte = sharp->matte;
+
+  // Resets fields of this pixel to prepare for the next iteration.
+  sharp->active = 0;
+  sharp->dilated_depth = 0;
+  sharp->matte = 0;
+  // Does not reset sharp->actual_depth, which will be used in future
+  // iterations.
+
+  if (matte == 0) {
+    return;
+  }
+
+  // At this point, sharp->dilated_depth must be within the depth range of
+  // this target layer. Hence kernel_info below is a valid pointer.
+  const KernelInfo_t *kernel_info =
+      g_kernel_info + depth - g_target_layer.back_depth;
+
+  FuzzyPixelF32_t result;
+  if (g_use_integral_image) {
+    result = FilterLayerUsingRowwiseIntegralImage(
+        x, y, &g_image_size, kernel_info, g_integral_image, &g_secant_offset);
+  } else {
+    result = FilterLayerInFrontOfFocalDepthHelper(
+        x, y, &g_image_size, kernel_info, g_kernel_stack, g_sharp_image);
+  }
+
+  FuzzyPixelF32_t *fuzzy = g_fuzzy_image + index;
+  // Because matte !=0 here, fuzzy->a < g_kAlmostOne must be true.
+  // Otherwise, ComputeLayerMatteHelper won't be called in
+  // ComputeLayerMatteInFrontOfFocalDepth, which results in a zero matte.
+
+  // Accumulates the filtering result to fuzzy.
+  const float capacity = 1.0f - fuzzy->alpha;
+  const float factor = capacity * (float)matte * g_blend_info.matte_normalizer;
+  fuzzy->red += factor * result.red;
+  fuzzy->green += factor * result.green;
+  fuzzy->blue += factor * result.blue;
+  fuzzy->alpha += factor;
+}
+
+// Replaces active pixels in g_sharp_image with the filtering result saved in
+// g_fuzzy_image. Does the replacement in a soft way by blending g_sharp_image
+// and g_fuzzy_image using the matte field.
+void __attribute__((kernel))
+UpdateSharpImageUsingFuzzyImage(uchar4 in, uint32_t x, uint32_t y) {
+  // Maps (x,y) to the padded image coordinate system.
+  x += g_image_size.margin;
+  y += g_image_size.margin;
+
+  const int index = y * g_image_size.width + x;
+  SharpPixelF32_t *sharp = g_sharp_image + index;
+
+  const int depth = sharp->dilated_depth;
+
+  if (depth == 0) {
+    return;
+  }
+
+  // At this point, this pixel must be either active or close enough to an
+  // active pixel.
+  // For such a pixel, its matte value can still be zero if its distance
+  // transform to the active pixels is larger than dilation_radius.
+  const int matte = sharp->matte;
+
+  // Resets fields of this pixel to prepare for future layer processing (pass
+  // two).
+  sharp->active = 0;
+  sharp->dilated_depth = 0;
+  sharp->matte = 0;
+  // Does not reset sharp->actual depth, which will be used in future
+  // layer processing.
+
+  if (matte == 0) {
+    return;
+  }
+
+  FuzzyPixelF32_t *fuzzy = g_fuzzy_image + index;
+  float factor = (float)matte * g_blend_info.matte_normalizer;
+  // The following blending amounts to:
+  // sharp = (1 - factor) * sharp + factor * fuzzy.
+  sharp->red += factor * (fuzzy->red - sharp->red);
+  sharp->green += factor * (fuzzy->green - sharp->green);
+  sharp->blue += factor * (fuzzy->blue - sharp->blue);
+
+  fuzzy->red = 0;
+  fuzzy->green = 0;
+  fuzzy->blue = 0;
+  fuzzy->alpha = 0;
+}
+
+// Fills in the pixels on or behind the focal depth in g_fuzzy_image using
+// pixels in g_sharp_image. Does the filling in a soft way by blending using the
+// matte field.
+void __attribute__((kernel))
+FinalizeFuzzyImageUsingSharpImage(uchar4 in, uint32_t x, uint32_t y) {
+  // Maps (x,y) to the padded image coordinate system.
+  x += g_image_size.margin;
+  y += g_image_size.margin;
+
+  const int index = y * g_image_size.width + x;
+  const SharpPixelF32_t *sharp = g_sharp_image + index;
+  FuzzyPixelF32_t *fuzzy = g_fuzzy_image + index;
+
+  // Tests whether this pixel has a valid depth behind the focal depth.
+  if (sharp->actual_depth && sharp->actual_depth <= g_focal_layer.front_depth) {
+    // The alpha channel for sharp is 1.
+    // fuzzy is a result of accumulation and hence is pre-multiplied with alpha.
+    // The following blending amounts to:
+    // fuzzy = fuzzy + (1 - fuzzy->a) * sharp.
+    float capacity = 1.0f - fuzzy->alpha;
+    fuzzy->red += sharp->red * capacity;
+    fuzzy->green += sharp->green * capacity;
+    fuzzy->blue += sharp->blue * capacity;
+    fuzzy->alpha = 1.0f;
+  }
+}
+
+// Copies g_fuzzy_image to output color image, excluding the padded margin.
+// (x, y) is the pixel coordinate in the output image.
+uchar4 __attribute__((kernel)) PackOutputImage(uint32_t x, uint32_t y) {
+  // Maps (x,y) to the padded image coordinate system.
+  x += g_image_size.margin;
+  y += g_image_size.margin;
+
+  // Returns the pixel at (x,y) after applying CRF.
+  const int index = y * g_image_size.width + x;
+  const FuzzyPixelF32_t *fuzzy = g_fuzzy_image + index;
+
+  // Applies Camera Response using LUT.
+  float4 result;
+  result.r = ApplyLUT_Float(fuzzy->red, g_camera_response.lut_apply_crf_float);
+  result.g =
+      ApplyLUT_Float(fuzzy->green, g_camera_response.lut_apply_crf_float);
+  result.b = ApplyLUT_Float(fuzzy->blue, g_camera_response.lut_apply_crf_float);
+  result.a = fuzzy->alpha;
+
+  return rsPackColorTo8888(result);
+}
+
+// Copies g_fuzzy_image to output color image, excluding the padded margin.
+// (x, y) is the pixel coordinate in the output image.
+uchar4 __attribute__((kernel)) PackSharpImage(uint32_t x, uint32_t y) {
+  // Maps (x,y) to the padded image coordinate system.
+  x += g_image_size.margin;
+  y += g_image_size.margin;
+
+  // Returns the pixel at (x,y) after applying CRF.
+  const int index = y * g_image_size.width + x;
+  const SharpPixelF32_t *sharp = g_sharp_image + index;
+
+  // Applies Camera Response using LUT.
+  float4 result;
+  result.r = ApplyLUT_Float(sharp->red, g_camera_response.lut_apply_crf_float);
+  result.g =
+      ApplyLUT_Float(sharp->green, g_camera_response.lut_apply_crf_float);
+  result.b = ApplyLUT_Float(sharp->blue, g_camera_response.lut_apply_crf_float);
+
+  return rsPackColorTo8888(result);
+}
+
+// Copies g_fuzzy_image to output color image, excluding the padded margin.
+// (x, y) is the pixel coordinate in the output image.
+uchar4 __attribute__((kernel)) PackFuzzyImage(uint32_t x, uint32_t y) {
+  // Maps (x,y) to the padded image coordinate system.
+  x += g_image_size.margin;
+  y += g_image_size.margin;
+
+  // Returns the pixel at (x,y) after applying CRF.
+  const int index = y * g_image_size.width + x;
+  const FuzzyPixelF32_t *fuzzy = g_fuzzy_image + index;
+
+  // Applies Camera Response using LUT.
+  float4 result;
+  result.r = ApplyLUT_Float(fuzzy->red, g_camera_response.lut_apply_crf_float);
+  result.g =
+      ApplyLUT_Float(fuzzy->green, g_camera_response.lut_apply_crf_float);
+  result.b = ApplyLUT_Float(fuzzy->blue, g_camera_response.lut_apply_crf_float);
+  result.a = fuzzy->alpha;
+
+  return rsPackColorTo8888(result);
+}
+
+void SetTargetLayer(int front, int back) {
+  g_target_layer.front_depth = front;
+  g_target_layer.back_depth = back;
+}
+
+void SetBlendInfo(int radius) {
+  g_blend_info.dilation_radius = radius;
+  g_blend_info.matte_normalizer = 1.0f / (radius + 1);
+}
+
+void SetUseIntegralImage(int use_integral_image) {
+  g_use_integral_image = use_integral_image;
+}
+
+void InitializeF32(int width, int height, int margin, int front, int back) {
+  SetImageSize(width, height, margin, &g_image_size);
+  g_focal_layer.front_depth = front;
+  g_focal_layer.back_depth = back;
+
+  g_sharp_image = (SharpPixelF32_t *)g_sharp_image_buffer;
+  g_integral_image = g_integral_image_buffer;
+  g_fuzzy_image = (FuzzyPixelF32_t *)g_fuzzy_image_buffer;
+
+  const int num_pixels = width * height;
+  ResetSharpImage(g_sharp_image, num_pixels);
+  ResetIntegralImage(g_integral_image, num_pixels);
+  ResetFuzzyImage(g_fuzzy_image, num_pixels);
+
+  InitializeRadiusOffset(&g_secant_offset);
+  InitializeVisibilityProbability(&g_visibility_probability, front, back);
+  InitializeDefaultCameraResponse(&g_camera_response);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/refocus/luts_for_speedup_f32.rsh b/tests/tests/renderscript/src/android/renderscript/cts/refocus/luts_for_speedup_f32.rsh
new file mode 100644
index 0000000..0052291
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/refocus/luts_for_speedup_f32.rsh
@@ -0,0 +1,81 @@
+#ifndef LUTS_FOR_SPEEDUP_F32_RSH
+#define LUTS_FOR_SPEEDUP_F32_RSH
+
+// Defines several LUTs for speed up for uint8 pixel type.
+
+// Depth Range: [1,g_kMaxDepthValue]; 0 is reserved for invalid pixels.
+// g_kMaxDepthValue must be the same as BlurStack::MAX_DEPTH.
+static const int g_kMaxDepthValue = 64;
+
+// A lookup table that heuristically computes the probability that a layer with
+// depth y is visible in the presence of a pixel with depth x.
+// VisibilityProbability.lut[y][x] = 1.0f/(max(x-y,0)+1).
+// The value range of both x and y is [0,g_kMaxDepthValue].
+// The value range of VisibilityProbability.lut[y][x] is [0,1].
+typedef struct VisibilityProbability {
+  float lut[g_kMaxDepthValue + 1][g_kMaxDepthValue + 1];
+} VisibilityProbability_t;
+
+// Assumes a <= b.
+// When a = b, RemoveInterval(x,a,b) always returns x.
+// When a < b,
+//   if x <= a,     RemoveInterval(x,a,b) = x;
+//   if a < x <= b, RemoveInterval(x,a,b) = a;
+//   if b < x,      RemoveInterval(x,a,b) = a + (x-b).
+static inline int RemoveInterval(int x, int a, int b) {
+  return (x <= a) ? (x) : (a + max(x - b, 0));
+}
+
+static inline void InitializeVisibilityProbability(
+    VisibilityProbability_t* visibility_probability, int front_focal_depth,
+    int back_focal_depth) {
+  // We expect back_focal_depth <= front_focal_depth.
+  for (int y = 0; y <= g_kMaxDepthValue; y++) {
+    for (int x = 0; x <= g_kMaxDepthValue; x++) {
+      if (y == 0 || x == 0) {
+        visibility_probability->lut[y][x] = 0;
+      } else if (y <= back_focal_depth) {
+        const int z = RemoveInterval(x, back_focal_depth, front_focal_depth);
+        visibility_probability->lut[y][x] = 1.0f / (max(z - y, 0) + 1);
+      } else if (y <= front_focal_depth) {
+        // For a depth value within the focal layer, only depth values in front
+        // of the focal layer are considered as its potential occluders. That
+        // is, a depth value x that has a larger value (closer to the camera)
+        // than y but is still within the focal layer is _not_ considered as an
+        // occluder to y.
+        visibility_probability->lut[y][x] =
+            1.0f / (max(x - front_focal_depth, 0) + 1);
+      } else {
+        // For depths > front_focal_depth, visibility check is not used in
+        // filtering. So always sets it to 1.
+        visibility_probability->lut[y][x] = 1;
+      }
+    }
+  }
+}
+
+// g_kMaxKernelRadius must match the value returned by
+// KernelDataForRenderScript.computeKernelRadiusFromDiskRadius(
+// BlurStack::MaxDiscRadius).
+static const int g_kMaxKernelRadius = 25 + 1;
+
+// A lookup table that pre-computes x coordinate of the intersection between a
+// circle of radius r and a horizontal line of height y.
+// lut[r][y+g_kMaxKernelRadius] = x;
+// The value range of r is [0,g_kMaxKernelRadius].
+// The value range of y is [-g_kMaxKernelRadius,g_kMaxKernelRadius].
+typedef struct SecantOffset {
+  int lut[g_kMaxKernelRadius + 1][2 * g_kMaxKernelRadius + 1];
+} SecantOffset_t;
+
+static inline void InitializeRadiusOffset(SecantOffset_t* secant_offset) {
+  for (int r = 0; r <= g_kMaxKernelRadius; ++r) {
+    for (int y = -g_kMaxKernelRadius; y <= g_kMaxKernelRadius; ++y) {
+      float tmp = max(0, r * r - y * y);
+      secant_offset->lut[r][y + g_kMaxKernelRadius] =
+          (int)round(half_sqrt(tmp));
+    }
+  }
+}
+
+#endif
\ No newline at end of file
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/refocus/pixel_format_f32.rsh b/tests/tests/renderscript/src/android/renderscript/cts/refocus/pixel_format_f32.rsh
new file mode 100644
index 0000000..1ed9902
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/refocus/pixel_format_f32.rsh
@@ -0,0 +1,57 @@
+#ifndef PIXEL_FORMAT_F32_RSH
+#define PIXEL_FORMAT_F32_RSH
+
+// FocusPixel is the pixel format in the input image, which serves the
+// following purposes in the refocus filter pipeline.
+//
+// 1. Initially, it stores the input color (red, green, blue) and the depth
+// value (actual_depth). The actual_depth field is never changed once set.
+//
+// 2. When processing each layer, we use its field (active) to mark
+// whether or not a pixel is on the current target layer. For pixels that are
+// active or not active but "close enough" to an active pixel, a matte value is
+// computed for blending color between layers. "Close enough" means L1 distance
+// is no larger than dilation_radius defined in LayerInfo_t in "layer_info.rsh".
+//
+// 3. After each layer is processed from back-most layer to focal depth layer,
+// the color (red, green, blue) of FocusPixel is updated and ready to be used in
+// layer processing for the next iteration.
+//
+// 4. After each layer is processed from front-most layer to focal depth layer,
+// the color (red, green, blue) of FocusPixel is *not* changed.
+//
+// 5. After each layer is processed in either of the two passes, the fields
+// active, matte, and dilated_depth are reset. However, the field actual_depth
+// field remains untouched once set initially.
+typedef struct SharpPixelF32 {
+  float red;
+  float green;
+  float blue;
+
+  uchar actual_depth;
+
+  // active = 1: the pixel is on the target layer;
+  // active = 0: otherwise.
+  uchar active;
+
+  // matte is between 0 and dilation_radius+1, where dilation_radius is defined
+  // in LayerInfo below.
+  // matte/(dilation_radius+1) is the actual value used in layer blending.
+  uchar matte;
+
+  // For active pixels, dilated_depth is the same as actual depth;
+  // For inactive pixels with non-zero matte, dilated_depth is the depth of the
+  // closest active pixels;
+  // For other pixels, 0 (invalid depth).
+  uchar dilated_depth;
+
+} SharpPixelF32_t;
+
+typedef struct FuzzyPixelF32 {
+  float red;
+  float green;
+  float blue;
+  float alpha;
+} FuzzyPixelF32_t;
+
+#endif
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/shared.rsh b/tests/tests/renderscript/src/android/renderscript/cts/shared.rsh
index 2ad81fc..6fd78f6 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/shared.rsh
+++ b/tests/tests/renderscript/src/android/renderscript/cts/shared.rsh
@@ -21,6 +21,9 @@
 \
 } while (0)
 
+#define _RS_ASSERT_EQU(e1, e2) \
+  (((e1) != (e2)) ? (failed = true, rsDebug(#e1 " != " #e2, (e1), (e2)), false) : true)
+
 /* These constants must match those in UnitTest.java */
 static const int RS_MSG_TEST_PASSED = 100;
 static const int RS_MSG_TEST_FAILED = 101;
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/single_source_alloc.rs b/tests/tests/renderscript/src/android/renderscript/cts/single_source_alloc.rs
new file mode 100644
index 0000000..40566a0
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/single_source_alloc.rs
@@ -0,0 +1,465 @@
+/*
+ * Copyright (C) 2015-2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 "shared.rsh"
+
+int gDimX;
+int gDimY;
+int gDimZ;
+int gStart;
+static bool failed = false;
+
+// For each type, define 4 kernels, one per vector variant, that walk an
+// allocation and validate each cell.  The value in a cell must be gStart +
+// "index-of-the-cell-starting-from-zero".  For vector types, the 'x' field
+// must have this value.  The expected values for 'y', 'z' and 'w' follow the
+// 'x' value in increments of one.
+//
+// 'z' will be zero for 2D and 1D allocations.  'y' will be zero for 1D
+// allocations.
+
+#define VERIFY_KERNEL(CT)                                                      \
+    void RS_KERNEL verify_##CT(CT in, int x, int y, int z) {                   \
+        int val = (gStart + x + y * gDimX + z * gDimY * gDimX);                \
+        _RS_ASSERT_EQU(in, (CT) val);                                          \
+    }                                                                          \
+    void RS_KERNEL verify_##CT##2(CT##2 in, int x, int y, int z) {             \
+        int val = (gStart + x + y * gDimX + z * gDimY * gDimX);                \
+        _RS_ASSERT_EQU(in.x, (CT) val);                                        \
+        _RS_ASSERT_EQU(in.y, (CT) (val + 1));                                  \
+    }                                                                          \
+    void RS_KERNEL verify_##CT##3(CT##3 in, int x, int y, int z) {             \
+        int val = (gStart + x + y * gDimX + z * gDimY * gDimX);                \
+        _RS_ASSERT_EQU(in.x, (CT) val);                                        \
+        _RS_ASSERT_EQU(in.y, (CT) (val + 1));                                  \
+        _RS_ASSERT_EQU(in.z, (CT) (val + 2));                                  \
+    }                                                                          \
+    void RS_KERNEL verify_##CT##4(CT##4 in, int x, int y, int z) {             \
+        int val = (gStart + x + y * gDimX + z * gDimY * gDimX);                \
+        _RS_ASSERT_EQU(in.x, (CT) val);                                        \
+        _RS_ASSERT_EQU(in.y, (CT) (val + 1));                                  \
+        _RS_ASSERT_EQU(in.z, (CT) (val + 2));                                  \
+        _RS_ASSERT_EQU(in.w, (CT) (val + 3));                                  \
+    }                                                                          \
+
+VERIFY_KERNEL(half)
+VERIFY_KERNEL(float)
+VERIFY_KERNEL(double)
+VERIFY_KERNEL(char)
+VERIFY_KERNEL(short)
+VERIFY_KERNEL(int)
+VERIFY_KERNEL(long)
+VERIFY_KERNEL(uchar)
+VERIFY_KERNEL(ushort)
+VERIFY_KERNEL(uint)
+VERIFY_KERNEL(ulong)
+
+// Store to an allocation based on the vector size and dimensionality being
+// tested.  SETELEMENTAT, STORE_TO_ALLOC capture the following variables from
+// the context where they get instantiated:
+//     vecSize, gAlloc, val, x, y, z
+
+#define SETELEMENTAT(CT)                                                      \
+    if (gDimZ != 0) {                                                         \
+        rsSetElementAt_##CT(gAlloc, storeVal, x, y, z);                       \
+    }                                                                         \
+    else if (gDimY != 0) {                                                    \
+        rsSetElementAt_##CT(gAlloc, storeVal, x, y);                          \
+    }                                                                         \
+    else {                                                                    \
+        rsSetElementAt_##CT(gAlloc, storeVal, x);                             \
+    }
+
+#define STORE_TO_ALLOC(RST, CT)                                               \
+    case RST:                                                                 \
+        switch (vecSize) {                                                    \
+            case 1: {                                                         \
+                CT storeVal = (CT) val;                                       \
+                SETELEMENTAT(CT);                                             \
+                     }                                                        \
+                break;                                                        \
+            case 2: {                                                         \
+                CT##2 storeVal = {(CT) val, (CT) (val + 1)};                  \
+                SETELEMENTAT(CT##2);                                          \
+                    }                                                         \
+                break;                                                        \
+            case 3: {                                                         \
+                CT##3 storeVal = {(CT) val, (CT) (val + 1), (CT) (val + 2)};  \
+                SETELEMENTAT(CT##3);                                          \
+                    }                                                         \
+                break;                                                        \
+            case 4: {                                                         \
+                CT##4 storeVal = {(CT) val, (CT) (val + 1), (CT) (val + 2),   \
+                                  (CT) (val + 3)};                            \
+                SETELEMENTAT(CT##4);                                          \
+                    }                                                         \
+                break;                                                        \
+        }                                                                     \
+        break;                                                                \
+
+
+// Launch the verify_kernel based on the appropriate type and vector size.
+#define LAUNCH_VERIFY_KERNEL(RST, CT)                                         \
+    case RST:                                                                 \
+        if (vecSize == 1) rsForEach(verify_##CT, gAlloc);                     \
+        else if (vecSize == 2) rsForEach(verify_##CT##2, gAlloc);             \
+        else if (vecSize == 3) rsForEach(verify_##CT##3, gAlloc);             \
+        else if (vecSize == 4) rsForEach(verify_##CT##4, gAlloc);             \
+        break;
+
+void checkAndSendResult() {
+    if (failed) {
+        rsDebug("Single Source Alloc Test Failed", 0);
+        rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+    }
+    else {
+        rsDebug("Single Source Alloc Test Passed", 0);
+        rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+    }
+}
+
+static void CreateAndTestAlloc(rs_data_type dt, int vecSize, int dimX, int dimY, int dimZ) {
+    failed = false;
+
+    if (dimZ != 0 && dimY == 0) {
+        _RS_ASSERT(false); // Invalid test
+        return;
+    }
+
+    if (dimX == 0) {
+        _RS_ASSERT(false); // Invalid test
+        return;
+    }
+
+    rs_element element;
+    rs_type type;
+    rs_allocation gAlloc;
+
+    // Create and validate the rs_element object
+    if (vecSize == 1)
+        element = rsCreateElement((rs_data_type) dt);
+    else
+        element = rsCreateVectorElement((rs_data_type) dt, vecSize);
+    _RS_ASSERT(rsIsObject(element));
+    if (!rsIsObject(element)) {
+        return;
+    }
+
+    // Create and validate the rs_type object
+    type = rsCreateType(element, dimX, dimY, dimZ);
+    _RS_ASSERT(rsIsObject(type));
+    if (!rsIsObject(type)) {
+        return;
+    }
+
+    // Create and validate the rs_allocation object
+    gAlloc = rsCreateAllocation(type);
+    if (!rsIsObject(gAlloc)) {
+        return;
+    }
+
+    // Handle RenderScript's distinction between Y or Z dimension being absent
+    // and having a size of 1
+    int zEnd = (dimZ != 0) ? dimZ: 1;
+    int yEnd = (dimY != 0) ? dimY: 1;
+    for (int z = 0; z < zEnd; z ++) {
+        for (int y = 0; y < yEnd; y ++) {
+            for (int x = 0; x < dimX; x ++) {
+                int val = gStart + (x + y * dimX + z * dimY * dimX);
+
+                // Store to a cell based on the type, vector size and
+                // dimensionality
+                switch (dt) {
+                    STORE_TO_ALLOC(RS_TYPE_FLOAT_16, half);
+                    STORE_TO_ALLOC(RS_TYPE_FLOAT_32, float);
+                    STORE_TO_ALLOC(RS_TYPE_FLOAT_64, double);
+                    STORE_TO_ALLOC(RS_TYPE_SIGNED_8, char);
+                    STORE_TO_ALLOC(RS_TYPE_SIGNED_16, short);
+                    STORE_TO_ALLOC(RS_TYPE_SIGNED_32, int);
+                    STORE_TO_ALLOC(RS_TYPE_SIGNED_64, long);
+                    STORE_TO_ALLOC(RS_TYPE_UNSIGNED_8, uchar);
+                    STORE_TO_ALLOC(RS_TYPE_UNSIGNED_16, ushort);
+                    STORE_TO_ALLOC(RS_TYPE_UNSIGNED_32, uint);
+                    STORE_TO_ALLOC(RS_TYPE_UNSIGNED_64, ulong);
+                    default:
+                        // Invalid test
+                        _RS_ASSERT(false);
+                        break;
+                }
+            }
+        }
+    }
+
+    // Launch the appropriate verify_ kernel
+    switch (dt) {
+        LAUNCH_VERIFY_KERNEL(RS_TYPE_FLOAT_16, half);
+        LAUNCH_VERIFY_KERNEL(RS_TYPE_FLOAT_32, float);
+        LAUNCH_VERIFY_KERNEL(RS_TYPE_FLOAT_64, double);
+        LAUNCH_VERIFY_KERNEL(RS_TYPE_SIGNED_8, char);
+        LAUNCH_VERIFY_KERNEL(RS_TYPE_SIGNED_16, short);
+        LAUNCH_VERIFY_KERNEL(RS_TYPE_SIGNED_32, int);
+        LAUNCH_VERIFY_KERNEL(RS_TYPE_SIGNED_64, long);
+        LAUNCH_VERIFY_KERNEL(RS_TYPE_UNSIGNED_8, uchar);
+        LAUNCH_VERIFY_KERNEL(RS_TYPE_UNSIGNED_16, ushort);
+        LAUNCH_VERIFY_KERNEL(RS_TYPE_UNSIGNED_32, uint);
+        LAUNCH_VERIFY_KERNEL(RS_TYPE_UNSIGNED_64, ulong);
+
+        default:
+            // Invalid test
+            _RS_ASSERT(false);
+            break;
+    }
+}
+
+void TestAllocationCreationAndAccess() {
+    rs_data_type all_types[] = {
+        RS_TYPE_BOOLEAN,
+        RS_TYPE_FLOAT_16,
+        RS_TYPE_FLOAT_32,
+        RS_TYPE_FLOAT_64,
+        RS_TYPE_SIGNED_8,
+        RS_TYPE_SIGNED_16,
+        RS_TYPE_SIGNED_32,
+        RS_TYPE_SIGNED_64,
+        RS_TYPE_UNSIGNED_8,
+        RS_TYPE_UNSIGNED_16,
+        RS_TYPE_UNSIGNED_32,
+        RS_TYPE_UNSIGNED_64,
+    };
+
+    for (int i = 0; i < sizeof(all_types) / sizeof(all_types[0]); i++) {
+        for (int vecSize = 1; vecSize <= 4; vecSize ++) {
+            for (int nDims = 1; nDims <= 3; nDims ++) {
+                int dimY = nDims > 1 ? gDimY : 0;
+                int dimZ = nDims > 2 ? gDimZ : 0;
+                CreateAndTestAlloc(all_types[i], vecSize, gDimX, dimY, dimZ);
+            }
+        }
+    }
+
+    checkAndSendResult();
+}
+
+#define TEST_DATA_TYPE(dt, allowSimple, allowVector, allowPixel) {             \
+    if (allowSimple)                                                           \
+        _RS_ASSERT(rsIsObject(rsCreateElement(dt)));                           \
+    else                                                                       \
+        _RS_ASSERT(!rsIsObject(rsCreateElement(dt)));                          \
+    if (allowVector)                                                           \
+        _RS_ASSERT(rsIsObject(rsCreateVectorElement(dt, 3)));                  \
+    else                                                                       \
+        _RS_ASSERT(!rsIsObject(rsCreateVectorElement(dt, 3)));                 \
+    if (allowPixel)                                                            \
+        _RS_ASSERT(rsIsObject(rsCreatePixelElement(dt, RS_KIND_PIXEL_DEPTH))); \
+    else                                                                       \
+        _RS_ASSERT(!rsIsObject(rsCreatePixelElement(dt, RS_KIND_PIXEL_DEPTH)));\
+}
+
+#define TEST_SUPPORTED_PIXEL(dt, dk) {                                         \
+    _RS_ASSERT(rsIsObject(rsCreatePixelElement(dt, dk)));                      \
+}
+
+#define TEST_UNSUPPORTED_PIXEL(dt, dk) {                                       \
+    _RS_ASSERT(!rsIsObject(rsCreatePixelElement(dt, dk)));                     \
+}
+
+#define TEST_HELPER(suffix) {                                     \
+    _RS_ASSERT(rsIsObject(rsCreateAllocation_##suffix(3)));       \
+    _RS_ASSERT(rsIsObject(rsCreateAllocation_##suffix(3, 4)));    \
+    _RS_ASSERT(rsIsObject(rsCreateAllocation_##suffix(3, 4, 5))); \
+    }
+
+#define TEST_HELPERS(CT) { \
+    TEST_HELPER(CT);       \
+    TEST_HELPER(CT##2);    \
+    TEST_HELPER(CT##3);    \
+    TEST_HELPER(CT##4);    \
+}
+
+void TestElementCreation() {
+    failed = false;
+
+    // vector_width must be at least 2
+    rs_element oneElt = rsCreateVectorElement(RS_TYPE_SIGNED_32, 1);
+    _RS_ASSERT(!rsIsObject(oneElt));
+
+    // vector_width must be at most 4
+    rs_element fiveElt = rsCreateVectorElement(RS_TYPE_SIGNED_32, 5);
+    _RS_ASSERT(!rsIsObject(fiveElt));
+
+    /////////////////////////////////////////////////////////////////
+    // Element validation
+    /////////////////////////////////////////////////////////////////
+    // These types are valid for scalar and vectors, but don't support pixel
+    TEST_DATA_TYPE(RS_TYPE_BOOLEAN,     true, true, false);
+    TEST_DATA_TYPE(RS_TYPE_FLOAT_32,    true, true, false);
+    TEST_DATA_TYPE(RS_TYPE_FLOAT_64,    true, true, false);
+    TEST_DATA_TYPE(RS_TYPE_SIGNED_8,    true, true, false);
+    TEST_DATA_TYPE(RS_TYPE_SIGNED_16,   true, true, false);
+    TEST_DATA_TYPE(RS_TYPE_SIGNED_32,   true, true, false);
+    TEST_DATA_TYPE(RS_TYPE_SIGNED_64,   true, true, false);
+    TEST_DATA_TYPE(RS_TYPE_UNSIGNED_32, true, true, false);
+    TEST_DATA_TYPE(RS_TYPE_UNSIGNED_64, true, true, false);
+
+    // These types are valid only for scalars
+    TEST_DATA_TYPE(RS_TYPE_MATRIX_4X4, true, false, false);
+    TEST_DATA_TYPE(RS_TYPE_MATRIX_3X3, true, false, false);
+    TEST_DATA_TYPE(RS_TYPE_MATRIX_2X2, true, false, false);
+    TEST_DATA_TYPE(RS_TYPE_ELEMENT,    true, false, false);
+    TEST_DATA_TYPE(RS_TYPE_TYPE,       true, false, false);
+    TEST_DATA_TYPE(RS_TYPE_ALLOCATION, true, false, false);
+    TEST_DATA_TYPE(RS_TYPE_SCRIPT,     true, false, false);
+
+    // U8, U16 are valid for scalar, vector and pixel
+    TEST_DATA_TYPE(RS_TYPE_UNSIGNED_8,  true, true, true);
+    TEST_DATA_TYPE(RS_TYPE_UNSIGNED_16, true, true, true);
+
+    // These data types are only for pixels and a particular data_kind
+    TEST_SUPPORTED_PIXEL  (RS_TYPE_UNSIGNED_5_6_5,   RS_KIND_PIXEL_RGB);
+    TEST_UNSUPPORTED_PIXEL(RS_TYPE_UNSIGNED_5_6_5,   RS_KIND_PIXEL_L);
+    TEST_SUPPORTED_PIXEL  (RS_TYPE_UNSIGNED_5_5_5_1, RS_KIND_PIXEL_RGBA);
+    TEST_UNSUPPORTED_PIXEL(RS_TYPE_UNSIGNED_5_5_5_1, RS_KIND_PIXEL_L);
+    TEST_SUPPORTED_PIXEL  (RS_TYPE_UNSIGNED_4_4_4_4, RS_KIND_PIXEL_RGBA);
+    TEST_UNSUPPORTED_PIXEL(RS_TYPE_UNSIGNED_4_4_4_4, RS_KIND_PIXEL_L);
+    TEST_SUPPORTED_PIXEL  (RS_TYPE_UNSIGNED_16,      RS_KIND_PIXEL_DEPTH);
+    TEST_UNSUPPORTED_PIXEL(RS_TYPE_UNSIGNED_4_4_4_4, RS_KIND_PIXEL_L);
+
+    // These data types are not supported from single-source
+    TEST_DATA_TYPE(RS_TYPE_NONE,             false, false, false);
+    TEST_DATA_TYPE(RS_TYPE_SAMPLER,          false, false, false);
+    TEST_DATA_TYPE(RS_TYPE_MESH,             false, false, false);
+    TEST_DATA_TYPE(RS_TYPE_PROGRAM_FRAGMENT, false, false, false);
+    TEST_DATA_TYPE(RS_TYPE_PROGRAM_VERTEX,   false, false, false);
+    TEST_DATA_TYPE(RS_TYPE_PROGRAM_RASTER,   false, false, false);
+    TEST_DATA_TYPE(RS_TYPE_PROGRAM_STORE,    false, false, false);
+    TEST_DATA_TYPE(RS_TYPE_FONT,             false, false, false);
+    TEST_DATA_TYPE(RS_TYPE_INVALID,          false, false, false);
+
+    checkAndSendResult();
+}
+
+void TestTypeCreation() {
+    failed = false;
+
+    /////////////////////////////////////////////////////////////////
+    // Test rs_type creation
+    /////////////////////////////////////////////////////////////////
+    rs_element I32_3 = rsCreateVectorElement(RS_TYPE_SIGNED_32, 3);
+
+    // Create 1D, 2D, 3D types
+    _RS_ASSERT(rsIsObject(rsCreateType(I32_3, 3)));
+    _RS_ASSERT(rsIsObject(rsCreateType(I32_3, 3, 4)));
+    _RS_ASSERT(rsIsObject(rsCreateType(I32_3, 3, 4, 5)));
+    _RS_ASSERT(rsIsObject(rsCreateType(I32_3, 0))); // x = 0 is allowed
+
+    // Invalid dimensionality
+    _RS_ASSERT(!rsIsObject(rsCreateType(I32_3, 0, 4))); // x is 0 but y isn't
+    _RS_ASSERT(!rsIsObject(rsCreateType(I32_3, 0, 4, 5))); // x is 0 but z isn't
+    _RS_ASSERT(!rsIsObject(rsCreateType(I32_3, 3, 0, 5))); // y is 0 but z isn't
+
+    // shape attributes
+    // Valid yuv_format
+    _RS_ASSERT(rsIsObject(rsCreateType(I32_3, 3, 4, 0, false, false,
+                    RS_YUV_NONE)));
+    _RS_ASSERT(rsIsObject(rsCreateType(I32_3, 3, 4, 0, false, false,
+                    RS_YUV_YV12)));
+    _RS_ASSERT(rsIsObject(rsCreateType(I32_3, 3, 4, 0, false, false,
+                    RS_YUV_NV21)));
+    _RS_ASSERT(rsIsObject(rsCreateType(I32_3, 3, 4, 0, false, false,
+                    RS_YUV_420_888)));
+
+    // Invalid yuv_format
+    _RS_ASSERT(!rsIsObject(rsCreateType(I32_3, 3, 4, 5, false, false, 1024)));
+    // yuv_format with 1D or 3D is invalid
+    _RS_ASSERT(!rsIsObject(rsCreateType(I32_3, 3, 0, 0, false, false,
+                    RS_YUV_YV12)));
+    _RS_ASSERT(!rsIsObject(rsCreateType(I32_3, 3, 4, 5, false, false,
+                    RS_YUV_YV12)));
+
+    // yuv_format with mipmaps or cubemap is invalid
+    _RS_ASSERT(!rsIsObject(rsCreateType(I32_3, 3, 4, 0, false, true,
+                    RS_YUV_YV12)));
+    _RS_ASSERT(!rsIsObject(rsCreateType(I32_3, 3, 4, 0, true, false,
+                    RS_YUV_YV12)));
+
+    // mipmaps with 1D or 3D is invalid
+    _RS_ASSERT(!rsIsObject(rsCreateType(I32_3, 3, 0, 0, true, false,
+                    RS_YUV_NONE)));
+    _RS_ASSERT(!rsIsObject(rsCreateType(I32_3, 3, 4, 5, true, false,
+                    RS_YUV_NONE)));
+
+    // cubemap with 1D or 3D is invalid
+    _RS_ASSERT(!rsIsObject(rsCreateType(I32_3, 3, 0, 0, false, true,
+                    RS_YUV_NONE)));
+    _RS_ASSERT(!rsIsObject(rsCreateType(I32_3, 3, 4, 5, false, true,
+                    RS_YUV_NONE)));
+
+    checkAndSendResult();
+}
+
+void TestAllocationCreationWithUsage() {
+    failed = false;
+
+    /////////////////////////////////////////////////////////////////
+    // Test rs_allocation creation
+    /////////////////////////////////////////////////////////////////
+    rs_element I32_3 = rsCreateVectorElement(RS_TYPE_SIGNED_32, 3);
+    rs_type I32_3_2D = rsCreateType(I32_3, 3, 4);
+
+    // Valid uses
+    _RS_ASSERT(rsIsObject(rsCreateAllocation(I32_3_2D)));
+    _RS_ASSERT(rsIsObject(rsCreateAllocation(I32_3_2D,\
+                    (uint32_t) RS_ALLOCATION_USAGE_SCRIPT)));
+    _RS_ASSERT(rsIsObject(rsCreateAllocation(I32_3_2D,\
+                    (uint32_t) RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE)));
+    _RS_ASSERT(rsIsObject(rsCreateAllocation(I32_3_2D,
+                    (uint32_t) RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE |
+                               RS_ALLOCATION_USAGE_SCRIPT)));
+
+    // Invalid uses
+    _RS_ASSERT(!rsIsObject(rsCreateAllocation(I32_3_2D,
+                    (uint32_t) RS_ALLOCATION_USAGE_GRAPHICS_VERTEX)));
+    _RS_ASSERT(!rsIsObject(rsCreateAllocation(I32_3_2D,
+                    (uint32_t) RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS)));
+    _RS_ASSERT(!rsIsObject(rsCreateAllocation(I32_3_2D,
+                    (uint32_t) RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET)));
+    _RS_ASSERT(!rsIsObject(rsCreateAllocation(I32_3_2D,
+                    (uint32_t) RS_ALLOCATION_USAGE_IO_INPUT)));
+    _RS_ASSERT(!rsIsObject(rsCreateAllocation(I32_3_2D,
+                    (uint32_t) RS_ALLOCATION_USAGE_IO_OUTPUT)));
+    _RS_ASSERT(!rsIsObject(rsCreateAllocation(I32_3_2D,
+                    (uint32_t) RS_ALLOCATION_USAGE_SHARED)));
+
+    checkAndSendResult();
+}
+
+void TestHelperFunctions() {
+    failed = false;
+
+    TEST_HELPER(half);
+    TEST_HELPERS(float);
+    TEST_HELPERS(double);
+    TEST_HELPERS(char);
+    TEST_HELPERS(short);
+    TEST_HELPERS(int);
+    TEST_HELPERS(long);
+    TEST_HELPERS(uchar);
+    TEST_HELPERS(ushort);
+    TEST_HELPERS(uint);
+    TEST_HELPERS(ulong);
+
+    checkAndSendResult();
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/single_source_script.rs b/tests/tests/renderscript/src/android/renderscript/cts/single_source_script.rs
new file mode 100644
index 0000000..5e35aa3
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/single_source_script.rs
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2015-2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 "shared.rsh"
+
+rs_allocation gAllocOut;
+
+int RS_KERNEL foo(int a) {
+    return a * 2;
+}
+
+int RS_KERNEL goo(int a, int b) {
+    return a + b;
+}
+
+void RS_KERNEL bar(int x, int y) {
+  int a = rsGetElementAt_int(gAllocOut, x, y);
+  a++;
+  rsSetElementAt_int(gAllocOut, a, x, y);
+}
+
+void testSingleInput(rs_allocation in, rs_allocation out) {
+    rsForEach(foo, in, out);
+}
+
+void testMultiInput(rs_allocation in1, rs_allocation in2, rs_allocation out) {
+    rsForEach(goo, in1, in2, out);
+}
+
+void testLaunchOptions(rs_allocation in, rs_allocation out, int dimX, int dimY) {
+    rs_script_call_t opts = {};
+    opts.xStart = 0;
+    opts.xEnd = dimX;
+    opts.yStart = 0;
+    opts.yEnd = dimY / 2;
+    rsForEachWithOptions(foo, &opts, in, out);
+}
+
+void testAllocationlessLaunch(rs_allocation inAndOut, int dimX, int dimY) {
+    gAllocOut = inAndOut;
+    rs_script_call_t opts = {};
+    opts.xStart = 0;
+    opts.xEnd = dimX;
+    opts.yStart = 0;
+    opts.yEnd = dimY;
+    rsForEachWithOptions(bar, &opts);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/small_structs.rs b/tests/tests/renderscript/src/android/renderscript/cts/small_structs.rs
new file mode 100644
index 0000000..2f58151
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/small_structs.rs
@@ -0,0 +1,235 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+#include "shared.rsh"
+
+// The intention of this test is to ensure that small structs are
+// passed / returned correctly by forEach kernels. "small" here means
+// under 64 bytes in size.
+//
+// The structure of this test is as follows:
+//   - allocations are initialized in Java
+//   - modify_* kernels change the allocation of small structs
+//   - verify_* invokables check that the modification changed the data
+//     as expected
+//
+// If there was an issue with passing / returning the small structs,
+// then the verify_* invokable should detect that a value is not
+// stored correctly.
+//
+// The first set of tests, char_array_*, test structs that contain
+// char arrays of various sizes. The second set of tests,
+// two_element_struct_*, test structs that contain two different types
+// (so that non-trivial alignment rules apply).
+
+/******************************************************************************/
+/* Common code                                                                */
+/******************************************************************************/
+
+static bool failed = false;
+
+void checkError() {
+  if (failed) {
+    rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+  } else {
+    rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+  }
+}
+
+/******************************************************************************/
+/* Char array testing                                                         */
+/******************************************************************************/
+
+static int numCharArrayTestsRun;
+
+#define TOTAL_CHAR_ARRAY_TESTS 64
+
+void checkNumberOfCharArrayTestsRun() {
+  rsDebug("number of char array tests run", numCharArrayTestsRun);
+  if (numCharArrayTestsRun != TOTAL_CHAR_ARRAY_TESTS) {
+    rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+  } else {
+    rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+  }
+}
+
+#define CHAR_ARRAY_TEST(SIZE)                                \
+typedef struct char_array_##SIZE { char bytes[SIZE]; }       \
+  char_array_##SIZE;                                         \
+                                                             \
+char_array_##SIZE RS_KERNEL                                  \
+modify_char_array_##SIZE(char_array_##SIZE in) {             \
+  for (int i = 0; i < SIZE; ++i) {                           \
+    in.bytes[i] += i;                                        \
+  }                                                          \
+  return in;                                                 \
+}                                                            \
+                                                             \
+void verify_char_array_##SIZE(rs_allocation alloc) {         \
+  for (int i = 0; i < rsAllocationGetDimX(alloc); ++i) {     \
+    struct char_array_##SIZE *elem =                         \
+      (struct char_array_##SIZE *) rsGetElementAt(alloc, i); \
+    for (int j = 0; j < SIZE; ++j) {                         \
+      _RS_ASSERT(elem->bytes[j] == 2 * j + 1);               \
+    }                                                        \
+  }                                                          \
+  ++numCharArrayTestsRun;                                    \
+}
+
+CHAR_ARRAY_TEST(1)
+CHAR_ARRAY_TEST(2)
+CHAR_ARRAY_TEST(3)
+CHAR_ARRAY_TEST(4)
+CHAR_ARRAY_TEST(5)
+CHAR_ARRAY_TEST(6)
+CHAR_ARRAY_TEST(7)
+CHAR_ARRAY_TEST(8)
+CHAR_ARRAY_TEST(9)
+CHAR_ARRAY_TEST(10)
+CHAR_ARRAY_TEST(11)
+CHAR_ARRAY_TEST(12)
+CHAR_ARRAY_TEST(13)
+CHAR_ARRAY_TEST(14)
+CHAR_ARRAY_TEST(15)
+CHAR_ARRAY_TEST(16)
+CHAR_ARRAY_TEST(17)
+CHAR_ARRAY_TEST(18)
+CHAR_ARRAY_TEST(19)
+CHAR_ARRAY_TEST(20)
+CHAR_ARRAY_TEST(21)
+CHAR_ARRAY_TEST(22)
+CHAR_ARRAY_TEST(23)
+CHAR_ARRAY_TEST(24)
+CHAR_ARRAY_TEST(25)
+CHAR_ARRAY_TEST(26)
+CHAR_ARRAY_TEST(27)
+CHAR_ARRAY_TEST(28)
+CHAR_ARRAY_TEST(29)
+CHAR_ARRAY_TEST(30)
+CHAR_ARRAY_TEST(31)
+CHAR_ARRAY_TEST(32)
+CHAR_ARRAY_TEST(33)
+CHAR_ARRAY_TEST(34)
+CHAR_ARRAY_TEST(35)
+CHAR_ARRAY_TEST(36)
+CHAR_ARRAY_TEST(37)
+CHAR_ARRAY_TEST(38)
+CHAR_ARRAY_TEST(39)
+CHAR_ARRAY_TEST(40)
+CHAR_ARRAY_TEST(41)
+CHAR_ARRAY_TEST(42)
+CHAR_ARRAY_TEST(43)
+CHAR_ARRAY_TEST(44)
+CHAR_ARRAY_TEST(45)
+CHAR_ARRAY_TEST(46)
+CHAR_ARRAY_TEST(47)
+CHAR_ARRAY_TEST(48)
+CHAR_ARRAY_TEST(49)
+CHAR_ARRAY_TEST(50)
+CHAR_ARRAY_TEST(51)
+CHAR_ARRAY_TEST(52)
+CHAR_ARRAY_TEST(53)
+CHAR_ARRAY_TEST(54)
+CHAR_ARRAY_TEST(55)
+CHAR_ARRAY_TEST(56)
+CHAR_ARRAY_TEST(57)
+CHAR_ARRAY_TEST(58)
+CHAR_ARRAY_TEST(59)
+CHAR_ARRAY_TEST(60)
+CHAR_ARRAY_TEST(61)
+CHAR_ARRAY_TEST(62)
+CHAR_ARRAY_TEST(63)
+CHAR_ARRAY_TEST(64)
+
+/******************************************************************************/
+/* Two element struct testing                                                 */
+/******************************************************************************/
+
+static int numTwoElementStructTestsRun;
+
+#define TOTAL_TWO_ELEMENT_STRUCT_TESTS 49
+
+void checkNumberOfTwoElementStructTestsRun() {
+  rsDebug("number of two element struct tests run", numTwoElementStructTestsRun);
+  if (numTwoElementStructTestsRun != TOTAL_TWO_ELEMENT_STRUCT_TESTS) {
+    rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+  } else {
+    rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+  }
+}
+
+#define TWO_ELEMENT_STRUCT_TEST(TAG, TYPE1, TYPE2)                              \
+typedef struct two_element_struct_##TAG { TYPE1 a; TYPE2 b; }                   \
+  two_element_struct_##TAG;                                                     \
+                                                                                \
+two_element_struct_##TAG RS_KERNEL                                              \
+modify_two_element_struct_##TAG(two_element_struct_##TAG in, int32_t x) {       \
+  in.a += initial_value_##TYPE1 * (x % 3);                                      \
+  in.b += initial_value_##TYPE2 * (x % 4);                                      \
+  return in;                                                                    \
+}                                                                               \
+                                                                                \
+void verify_two_element_struct_##TAG(rs_allocation alloc) {                     \
+  for (int i = 0; i < rsAllocationGetDimX(alloc); ++i) {                        \
+    struct two_element_struct_##TAG *elem =                                     \
+      (struct two_element_struct_##TAG *) rsGetElementAt(alloc, i);             \
+    _RS_ASSERT(equals_##TYPE1(elem->a, (1 + (i % 3)) * initial_value_##TYPE1)); \
+    _RS_ASSERT(equals_##TYPE2(elem->b, (1 + (i % 4)) * initial_value_##TYPE2)); \
+  }                                                                             \
+  ++numTwoElementStructTestsRun;                                                \
+}
+
+int8_t  initial_value_int8_t;
+int16_t initial_value_int16_t;
+int32_t initial_value_int32_t;
+int64_t initial_value_int64_t;
+float   initial_value_float;
+double  initial_value_double;
+float4  initial_value_float4;
+
+#define MAKE_SCALAR_EQUALS(TYPE) \
+static bool equals_##TYPE(TYPE a, TYPE b) { return a == b; }
+
+MAKE_SCALAR_EQUALS(int8_t)
+MAKE_SCALAR_EQUALS(int16_t)
+MAKE_SCALAR_EQUALS(int32_t)
+MAKE_SCALAR_EQUALS(int64_t)
+MAKE_SCALAR_EQUALS(float)
+MAKE_SCALAR_EQUALS(double)
+
+static bool equals_float4(float4 a, float4 b) {
+     return a[0] == b[0] && a[1] == b[1] && a[2] == b[2] && a[3] == b[3];
+}
+
+#define MAKE_TWO_ELEMENT_STRUCT_TEST(LHS_TAG, LHS_TYPE)    \
+TWO_ELEMENT_STRUCT_TEST(LHS_TAG##_i8,   LHS_TYPE, int8_t)  \
+TWO_ELEMENT_STRUCT_TEST(LHS_TAG##_i16,  LHS_TYPE, int16_t) \
+TWO_ELEMENT_STRUCT_TEST(LHS_TAG##_i32,  LHS_TYPE, int32_t) \
+TWO_ELEMENT_STRUCT_TEST(LHS_TAG##_i64,  LHS_TYPE, int64_t) \
+TWO_ELEMENT_STRUCT_TEST(LHS_TAG##_f32,  LHS_TYPE, float)   \
+TWO_ELEMENT_STRUCT_TEST(LHS_TAG##_f64,  LHS_TYPE, double)  \
+TWO_ELEMENT_STRUCT_TEST(LHS_TAG##_v128, LHS_TYPE, float4)
+
+MAKE_TWO_ELEMENT_STRUCT_TEST(i8,   int8_t)
+MAKE_TWO_ELEMENT_STRUCT_TEST(i16,  int16_t)
+MAKE_TWO_ELEMENT_STRUCT_TEST(i32,  int32_t)
+MAKE_TWO_ELEMENT_STRUCT_TEST(i64,  int64_t)
+MAKE_TWO_ELEMENT_STRUCT_TEST(f32,  float)
+MAKE_TWO_ELEMENT_STRUCT_TEST(f64,  double)
+MAKE_TWO_ELEMENT_STRUCT_TEST(v128, float4)
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/verify.rs b/tests/tests/renderscript/src/android/renderscript/cts/verify.rs
index c3ae802..4527f1e 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/verify.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/verify.rs
@@ -18,8 +18,6 @@
 
 int gAllowedIntError = 0;
 float gAllowedFloatError = 0.0001f;
-double gAllowedFloatMatError = 0.00000001;
-double gAllowedDoubleMatError = 0.00000000001;
 static bool hadError = false;
 static int2 errorLoc = {0,0};
 
@@ -303,135 +301,6 @@
     }
 }
 
-
-static bool verify_CMatrix(rs_allocation in1, rs_allocation in2, double l2Norm, bool isUpperMatrix) {
-    uint32_t w = rsAllocationGetDimX(in1);
-    uint32_t h = rsAllocationGetDimY(in1);
-    for (uint32_t y = 0; y < h; y++) {
-        uint32_t xStart = 0;
-        if (isUpperMatrix) {
-            // Just test the upper matrix for certain BLAS routines
-            xStart = y;
-        }
-        for (uint32_t x = xStart; x < w; x++) {
-            float2 pref = rsGetElementAt_float2(in1, x, y);
-            float2 ptst = rsGetElementAt_float2(in2, x, y);
-            double absErr = (pref.x - ptst.x) * (pref.x - ptst.x) + (pref.y - ptst.y) * (pref.y - ptst.y);
-            if (absErr > l2Norm * gAllowedFloatMatError) {
-                errorLoc.x = x;
-                errorLoc.y = y;
-                hadError = true;
-                return false;
-            }
-        }
-    }
-    return true;
-}
-
-static bool verify_SMatrix(rs_allocation in1, rs_allocation in2, double l2Norm, bool isUpperMatrix) {
-    uint32_t w = rsAllocationGetDimX(in1);
-    uint32_t h = rsAllocationGetDimY(in1);
-    for (uint32_t y = 0; y < h; y++) {
-        uint32_t xStart = 0;
-        if (isUpperMatrix) {
-            // Just test the upper matrix for certain BLAS routines
-            xStart = y;
-        }
-        for (uint32_t x = xStart; x < w; x++) {
-            float pref = rsGetElementAt_float(in1, x, y);
-            float ptst = rsGetElementAt_float(in2, x, y);
-            double absErr = (pref - ptst) * (pref - ptst);
-            if (absErr > l2Norm * gAllowedFloatMatError) {
-                errorLoc.x = x;
-                errorLoc.y = y;
-                hadError = true;
-                return false;
-            }
-        }
-    }
-    return true;
-}
-
-static bool verify_ZMatrix(rs_allocation in1, rs_allocation in2, double l2Norm, bool isUpperMatrix) {
-    uint32_t w = rsAllocationGetDimX(in1);
-    uint32_t h = rsAllocationGetDimY(in1);
-    for (uint32_t y = 0; y < h; y++) {
-        uint32_t xStart = 0;
-        if (isUpperMatrix) {
-            // Just test the upper matrix for certain BLAS routines
-            xStart = y;
-        }
-        for (uint32_t x = xStart; x < w; x++) {
-            double2 pref = rsGetElementAt_double2(in1, x, y);
-            double2 ptst = rsGetElementAt_double2(in2, x, y);
-            double absErr = (pref.x - ptst.x) * (pref.x - ptst.x) + (pref.y - ptst.y) * (pref.y - ptst.y);
-            if (absErr > l2Norm * gAllowedDoubleMatError) {
-                errorLoc.x = x;
-                errorLoc.y = y;
-                hadError = true;
-                return false;
-            }
-        }
-    }
-    return true;
-}
-
-static bool verify_DMatrix(rs_allocation in1, rs_allocation in2, double l2Norm, bool isUpperMatrix) {
-    uint32_t w = rsAllocationGetDimX(in1);
-    uint32_t h = rsAllocationGetDimY(in1);
-    for (uint32_t y = 0; y < h; y++) {
-        uint32_t xStart = 0;
-        if (isUpperMatrix) {
-            // Just test the upper matrix for certain BLAS routines
-            xStart = y;
-        }
-        for (uint32_t x = xStart; x < w; x++) {
-            double pref = rsGetElementAt_double(in1, x, y);
-            double ptst = rsGetElementAt_double(in2, x, y);
-            double absErr = (pref - ptst) * (pref - ptst);
-            if (absErr > l2Norm * gAllowedDoubleMatError) {
-                errorLoc.x = x;
-                errorLoc.y = y;
-                hadError = true;
-                return false;
-            }
-        }
-    }
-    return true;
-}
-
-void verifyMatrix(rs_allocation ref_in, rs_allocation tst_in, double l2Norm, bool isUpperMatrix) {
-    rs_element e = rsAllocationGetElement(ref_in);
-    rs_data_type dt = rsElementGetDataType(e);
-    uint32_t vs = rsElementGetVectorSize(e);
-    bool valid = false;
-
-    if (dt == RS_TYPE_FLOAT_32) {
-        switch(vs) {
-        case 2:
-            valid = verify_CMatrix(ref_in, tst_in, l2Norm, isUpperMatrix);
-            break;
-        case 1:
-            valid = verify_SMatrix(ref_in, tst_in, l2Norm, isUpperMatrix);
-            break;
-        }
-    } else if (dt == RS_TYPE_FLOAT_64) {
-        switch(vs) {
-        case 2:
-            valid = verify_ZMatrix(ref_in, tst_in, l2Norm, isUpperMatrix);
-            break;
-        case 1:
-            valid = verify_DMatrix(ref_in, tst_in, l2Norm, isUpperMatrix);
-            break;
-        }
-    }
-    if (!valid) {
-        rsDebug("verify failure at xy", errorLoc);
-        printCell("Expected value ", ref_in, errorLoc);
-        printCell("Actual value   ", tst_in, errorLoc);
-    }
-}
-
 void checkError()
 {
     if (hadError) {
diff --git a/tests/tests/renderscriptlegacy/Android.mk b/tests/tests/renderscriptlegacy/Android.mk
index 31d8ed9..f29a290 100644
--- a/tests/tests/renderscriptlegacy/Android.mk
+++ b/tests/tests/renderscriptlegacy/Android.mk
@@ -30,4 +30,7 @@
 
 LOCAL_SDK_VERSION := 19
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/renderscriptlegacy/AndroidManifest.xml b/tests/tests/renderscriptlegacy/AndroidManifest.xml
index 0c0498a..bd1184f 100644
--- a/tests/tests/renderscriptlegacy/AndroidManifest.xml
+++ b/tests/tests/renderscriptlegacy/AndroidManifest.xml
@@ -19,7 +19,7 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.renderscriptlegacy">
+    package="android.renderscriptlegacy.cts">
 
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <application>
@@ -28,7 +28,7 @@
 
     <!-- This is a self-instrumenting test package. -->
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.cts.renderscriptlegacy"
+                     android:targetPackage="android.renderscriptlegacy.cts"
                      android:label="CTS tests of Renderscript component">
         <meta-data android:name="listener"
             android:value="com.android.cts.runner.CtsTestRunListener" />
diff --git a/tests/tests/renderscriptlegacy/AndroidTest.xml b/tests/tests/renderscriptlegacy/AndroidTest.xml
new file mode 100644
index 0000000..3523dfe
--- /dev/null
+++ b/tests/tests/renderscriptlegacy/AndroidTest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Configuration for Renderscript legacy Tests">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsRenderscriptLegacyTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.renderscriptlegacy.cts" />
+    </test>
+</configuration>
diff --git a/tests/tests/rsblas/Android.mk b/tests/tests/rsblas/Android.mk
new file mode 100644
index 0000000..700fba3
--- /dev/null
+++ b/tests/tests/rsblas/Android.mk
@@ -0,0 +1,43 @@
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := CtsRsBlasTestCases
+
+# Don't include this package in any target.
+LOCAL_MODULE_TAGS := optional
+
+# Include both the 32 and 64 bit versions
+LOCAL_MULTILIB := both
+
+# When built, explicitly put it in the data partition.
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
+LOCAL_JNI_SHARED_LIBRARIES := libbnnmdata_jni
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-renderscript-files-under, src)
+
+LOCAL_RENDERSCRIPT_FLAGS := -Wno-error=deprecated-declarations
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_PACKAGE)
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/tests/rsblas/AndroidManifest.xml b/tests/tests/rsblas/AndroidManifest.xml
new file mode 100644
index 0000000..f6099fb
--- /dev/null
+++ b/tests/tests/rsblas/AndroidManifest.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.cts.rsblas">
+
+    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <!-- This is a self-instrumenting test package. -->
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="com.android.cts.rsblas"
+                     android:label="CTS tests of RenderScript IntrinsicBLAS">
+        <meta-data android:name="listener"
+            android:value="com.android.cts.runner.CtsTestRunListener" />
+    </instrumentation>
+
+</manifest>
+
diff --git a/tests/tests/rsblas/AndroidTest.xml b/tests/tests/rsblas/AndroidTest.xml
new file mode 100644
index 0000000..340ca29
--- /dev/null
+++ b/tests/tests/rsblas/AndroidTest.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS RS BLAS test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsRsBlasTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="com.android.cts.rsblas" />
+        <option name="runtime-hint" value="12m57s" />
+    </test>
+</configuration>
diff --git a/tests/tests/renderscript/assets/BLASData.txt b/tests/tests/rsblas/assets/BLASData.txt
similarity index 100%
rename from tests/tests/renderscript/assets/BLASData.txt
rename to tests/tests/rsblas/assets/BLASData.txt
diff --git a/tests/tests/renderscript/assets/blas_gen.py b/tests/tests/rsblas/assets/blas_gen.py
similarity index 100%
rename from tests/tests/renderscript/assets/blas_gen.py
rename to tests/tests/rsblas/assets/blas_gen.py
diff --git a/tests/tests/rsblas/libbnnmdata/Android.mk b/tests/tests/rsblas/libbnnmdata/Android.mk
new file mode 100644
index 0000000..bbfd289
--- /dev/null
+++ b/tests/tests/rsblas/libbnnmdata/Android.mk
@@ -0,0 +1,27 @@
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+LOCAL_CLANG := true
+
+LOCAL_MODULE := libbnnmdata_jni
+LOCAL_MODULE_TAGS := optional
+LOCAL_SRC_FILES := test_data.cpp
+LOCAL_SDK_VERSION := 23
+LOCAL_NDK_STL_VARIANT := c++_static
+
+LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/tests/tests/rsblas/libbnnmdata/test_data.cpp b/tests/tests/rsblas/libbnnmdata/test_data.cpp
new file mode 100644
index 0000000..a7dbd1a
--- /dev/null
+++ b/tests/tests/rsblas/libbnnmdata/test_data.cpp
@@ -0,0 +1,56591 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 <jni.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+const int m = 256;
+const int n = 192;
+const int k = 1152;
+const int a_offset = 0;
+const int b_offset = 84;
+const int c_mult_int = 3401;
+const int c_offset = 74980;
+
+const int a_count = (m * k);
+const int b_count = (n * k);
+const int c_count = (m * n);
+
+unsigned char a_data[a_count] = {
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 39, 14, 0, 0, 0, 63, 31,
+  0, 36, 15, 0, 0, 12, 10, 93, 23, 78,
+  37, 39, 52, 0, 44, 62, 9, 23, 34, 48,
+  251, 53, 0, 0, 103, 0, 11, 0, 0, 19,
+  12, 43, 34, 0, 10, 7, 84, 61, 0, 22,
+  0, 69, 0, 28, 41, 0, 20, 0, 7, 14,
+  0, 3, 6, 7, 15, 0, 0, 16, 25, 16,
+  0, 28, 0, 14, 83, 9, 21, 62, 7, 4,
+  7, 0, 53, 0, 16, 0, 0, 1, 0, 4,
+  66, 24, 50, 9, 0, 0, 69, 27, 15, 2,
+  14, 33, 3, 0, 1, 18, 73, 0, 43, 0,
+  0, 6, 26, 16, 10, 44, 0, 0, 22, 18,
+  0, 41, 77, 0, 0, 0, 0, 0, 27, 20,
+  27, 77, 56, 1, 0, 0, 53, 33, 0, 26,
+  0, 19, 15, 40, 3, 80, 27, 70, 9, 40,
+  13, 19, 51, 56, 1, 0, 62, 39, 168, 33,
+  0, 2, 112, 0, 35, 0, 0, 8, 0, 15,
+  15, 0, 16, 4, 70, 57, 0, 21, 0, 58,
+  0, 81, 74, 0, 31, 0, 4, 0, 0, 0,
+  31, 0, 5, 36, 0, 9, 25, 0, 0, 65,
+  0, 19, 22, 10, 17, 20, 19, 22, 19, 0,
+  39, 0, 23, 18, 0, 9, 5, 21, 68, 17,
+  39, 0, 0, 0, 34, 0, 67, 16, 7, 35,
+  9, 16, 42, 18, 111, 0, 19, 7, 30, 4,
+  45, 33, 26, 6, 0, 0, 14, 0, 1, 30,
+  86, 0, 9, 0, 3, 0, 26, 19, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 12, 21, 64, 6,
+  0, 0, 17, 8, 0, 10, 24, 0, 0, 65,
+  0, 74, 92, 76, 35, 40, 22, 3, 39, 33,
+  0, 0, 31, 58, 156, 6, 15, 0, 58, 0,
+  0, 0, 0, 18, 0, 18, 5, 27, 0, 0,
+  53, 31, 0, 18, 0, 0, 0, 47, 40, 0,
+  10, 0, 0, 9, 0, 6, 28, 0, 0, 0,
+  0, 7, 44, 0, 48, 45, 0, 16, 17, 16,
+  28, 6, 22, 3, 0, 16, 38, 0, 14, 0,
+  0, 13, 0, 23, 45, 25, 8, 25, 0, 0,
+  67, 0, 51, 0, 0, 39, 3, 0, 27, 11,
+  67, 0, 18, 0, 0, 0, 20, 21, 9, 43,
+  3, 0, 12, 0, 0, 0, 64, 0, 5, 0,
+  0, 0, 55, 0, 56, 59, 50, 27, 4, 0,
+  2, 0, 0, 0, 8, 0, 48, 60, 4, 28,
+  76, 49, 0, 0, 0, 6, 1, 61, 24, 0,
+  35, 40, 0, 0, 13, 0, 67, 0, 0, 0,
+  0, 0, 0, 1, 0, 66, 2, 0, 30, 28,
+  26, 42, 0, 12, 0, 69, 96, 0, 23, 0,
+  0, 0, 0, 0, 51, 0, 0, 65, 0, 8,
+  82, 0, 40, 45, 0, 20, 0, 33, 32, 0,
+  14, 3, 0, 16, 42, 0, 37, 0, 0, 30,
+  0, 27, 36, 9, 13, 0, 0, 22, 2, 0,
+  70, 5, 0, 64, 0, 23, 40, 0, 76, 0,
+  6, 0, 58, 8, 17, 40, 5, 0, 26, 0,
+  1, 0, 0, 0, 39, 0, 71, 0, 10, 9,
+  14, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 39, 14, 0,
+  0, 0, 63, 31, 0, 36, 15, 0, 0, 12,
+  10, 93, 23, 78, 37, 39, 52, 0, 44, 62,
+  9, 23, 34, 48, 251, 53, 0, 0, 103, 0,
+  11, 0, 0, 19, 12, 43, 34, 0, 10, 7,
+  84, 61, 0, 22, 0, 69, 0, 28, 41, 0,
+  20, 0, 7, 14, 0, 3, 6, 7, 15, 0,
+  0, 16, 25, 16, 0, 28, 0, 14, 83, 9,
+  21, 62, 7, 4, 7, 0, 53, 0, 16, 0,
+  0, 1, 0, 4, 66, 24, 50, 9, 0, 0,
+  69, 27, 15, 2, 14, 33, 3, 0, 1, 18,
+  73, 0, 43, 0, 0, 6, 26, 16, 10, 44,
+  0, 0, 22, 18, 0, 41, 77, 0, 0, 0,
+  0, 0, 27, 20, 27, 77, 56, 1, 0, 0,
+  53, 33, 0, 26, 0, 19, 15, 40, 3, 80,
+  27, 70, 9, 40, 13, 19, 51, 56, 1, 0,
+  62, 39, 168, 33, 0, 2, 112, 0, 35, 0,
+  0, 8, 0, 15, 15, 0, 16, 4, 70, 57,
+  0, 21, 0, 58, 0, 81, 74, 0, 31, 0,
+  4, 0, 0, 0, 31, 0, 5, 36, 0, 9,
+  25, 0, 0, 65, 0, 19, 22, 10, 17, 20,
+  19, 22, 19, 0, 39, 0, 23, 18, 0, 9,
+  5, 21, 68, 17, 39, 0, 0, 0, 34, 0,
+  67, 16, 7, 35, 9, 16, 42, 18, 111, 0,
+  19, 7, 30, 4, 45, 33, 26, 6, 0, 0,
+  14, 0, 1, 30, 86, 0, 9, 0, 3, 0,
+  26, 19, 51, 73, 59, 31, 0, 25, 25, 27,
+  1, 0, 0, 49, 62, 54, 0, 17, 9, 31,
+  5, 0, 0, 97, 24, 47, 40, 0, 67, 36,
+  173, 0, 0, 93, 100, 0, 16, 5, 0, 0,
+  0, 8, 0, 0, 58, 12, 35, 124, 53, 23,
+  0, 49, 0, 76, 26, 0, 69, 0, 16, 0,
+  0, 0, 74, 49, 11, 40, 2, 17, 33, 10,
+  4, 69, 21, 19, 13, 0, 5, 0, 39, 35,
+  1, 0, 24, 0, 46, 72, 0, 11, 18, 1,
+  41, 28, 0, 0, 0, 0, 0, 0, 56, 0,
+  0, 45, 33, 55, 30, 39, 114, 0, 28, 15,
+  40, 0, 15, 24, 15, 0, 0, 0, 36, 0,
+  25, 27, 59, 0, 0, 0, 16, 0, 11, 50,
+  12, 21, 64, 6, 0, 0, 17, 8, 0, 10,
+  24, 0, 0, 65, 0, 74, 92, 76, 35, 40,
+  22, 3, 39, 33, 0, 0, 31, 58, 156, 6,
+  15, 0, 58, 0, 0, 0, 0, 18, 0, 18,
+  5, 27, 0, 0, 53, 31, 0, 18, 0, 0,
+  0, 47, 40, 0, 10, 0, 0, 9, 0, 6,
+  28, 0, 0, 0, 0, 7, 44, 0, 48, 45,
+  0, 16, 17, 16, 28, 6, 22, 3, 0, 16,
+  38, 0, 14, 0, 0, 13, 0, 23, 45, 25,
+  8, 25, 0, 0, 67, 0, 51, 0, 0, 39,
+  3, 0, 27, 11, 67, 0, 18, 0, 0, 0,
+  20, 21, 9, 43, 3, 0, 12, 0, 0, 0,
+  64, 0, 5, 0, 0, 0, 55, 0, 56, 59,
+  50, 27, 4, 0, 2, 0, 0, 0, 8, 0,
+  48, 60, 4, 28, 76, 49, 0, 0, 0, 6,
+  1, 61, 24, 0, 35, 40, 0, 0, 13, 0,
+  67, 0, 0, 0, 0, 0, 0, 1, 0, 66,
+  2, 0, 30, 28, 26, 42, 0, 12, 0, 69,
+  96, 0, 23, 0, 0, 0, 0, 0, 51, 0,
+  0, 65, 0, 8, 82, 0, 40, 45, 0, 20,
+  0, 33, 32, 0, 14, 3, 0, 16, 42, 0,
+  37, 0, 0, 30, 0, 27, 36, 9, 13, 0,
+  0, 22, 2, 0, 70, 5, 0, 64, 0, 23,
+  40, 0, 76, 0, 6, 0, 58, 8, 17, 40,
+  5, 0, 26, 0, 1, 0, 0, 0, 39, 0,
+  71, 0, 10, 9, 14, 0, 2, 55, 59, 38,
+  4, 35, 16, 13, 17, 0, 0, 16, 84, 0,
+  0, 22, 51, 18, 0, 0, 0, 56, 0, 33,
+  67, 0, 5, 30, 0, 0, 0, 43, 70, 0,
+  18, 0, 0, 0, 0, 41, 0, 35, 57, 2,
+  29, 80, 44, 19, 0, 21, 0, 34, 36, 10,
+  35, 0, 10, 0, 0, 0, 30, 26, 0, 32,
+  0, 0, 35, 1, 27, 0, 0, 17, 9, 19,
+  26, 0, 10, 16, 0, 22, 23, 0, 61, 69,
+  0, 5, 0, 0, 0, 42, 5, 0, 0, 31,
+  0, 24, 35, 0, 0, 65, 2, 0, 10, 12,
+  63, 0, 37, 0, 27, 0, 0, 14, 0, 0,
+  0, 0, 0, 0, 0, 0, 4, 0, 41, 0,
+  35, 0, 8, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 27, 77,
+  56, 1, 0, 0, 53, 33, 0, 26, 0, 19,
+  15, 40, 3, 80, 27, 70, 9, 40, 13, 19,
+  51, 56, 1, 0, 62, 39, 168, 33, 0, 2,
+  112, 0, 35, 0, 0, 8, 0, 15, 15, 0,
+  16, 4, 70, 57, 0, 21, 0, 58, 0, 81,
+  74, 0, 31, 0, 4, 0, 0, 0, 31, 0,
+  5, 36, 0, 9, 25, 0, 0, 65, 0, 19,
+  22, 10, 17, 20, 19, 22, 19, 0, 39, 0,
+  23, 18, 0, 9, 5, 21, 68, 17, 39, 0,
+  0, 0, 34, 0, 67, 16, 7, 35, 9, 16,
+  42, 18, 111, 0, 19, 7, 30, 4, 45, 33,
+  26, 6, 0, 0, 14, 0, 1, 30, 86, 0,
+  9, 0, 3, 0, 26, 19, 51, 73, 59, 31,
+  0, 25, 25, 27, 1, 0, 0, 49, 62, 54,
+  0, 17, 9, 31, 5, 0, 0, 97, 24, 47,
+  40, 0, 67, 36, 173, 0, 0, 93, 100, 0,
+  16, 5, 0, 0, 0, 8, 0, 0, 58, 12,
+  35, 124, 53, 23, 0, 49, 0, 76, 26, 0,
+  69, 0, 16, 0, 0, 0, 74, 49, 11, 40,
+  2, 17, 33, 10, 4, 69, 21, 19, 13, 0,
+  5, 0, 39, 35, 1, 0, 24, 0, 46, 72,
+  0, 11, 18, 1, 41, 28, 0, 0, 0, 0,
+  0, 0, 56, 0, 0, 45, 33, 55, 30, 39,
+  114, 0, 28, 15, 40, 0, 15, 24, 15, 0,
+  0, 0, 36, 0, 25, 27, 59, 0, 0, 0,
+  16, 0, 11, 50, 1, 0, 0, 19, 11, 92,
+  28, 0, 0, 0, 0, 57, 41, 55, 0, 0,
+  0, 21, 17, 3, 0, 71, 14, 58, 40, 0,
+  38, 15, 173, 20, 0, 66, 63, 35, 0, 0,
+  0, 0, 0, 44, 0, 0, 10, 45, 6, 158,
+  67, 62, 0, 26, 0, 54, 50, 0, 21, 0,
+  34, 0, 34, 0, 70, 66, 0, 18, 13, 4,
+  36, 35, 62, 39, 52, 9, 43, 0, 28, 0,
+  37, 0, 0, 0, 49, 0, 22, 62, 0, 0,
+  39, 14, 21, 0, 0, 25, 16, 0, 24, 37,
+  0, 0, 11, 49, 15, 31, 12, 45, 82, 9,
+  31, 0, 0, 16, 0, 14, 0, 7, 0, 44,
+  106, 21, 47, 22, 46, 0, 0, 0, 16, 0,
+  13, 16, 56, 59, 50, 27, 4, 0, 2, 0,
+  0, 0, 8, 0, 48, 60, 4, 28, 76, 49,
+  0, 0, 0, 6, 1, 61, 24, 0, 35, 40,
+  0, 0, 13, 0, 67, 0, 0, 0, 0, 0,
+  0, 1, 0, 66, 2, 0, 30, 28, 26, 42,
+  0, 12, 0, 69, 96, 0, 23, 0, 0, 0,
+  0, 0, 51, 0, 0, 65, 0, 8, 82, 0,
+  40, 45, 0, 20, 0, 33, 32, 0, 14, 3,
+  0, 16, 42, 0, 37, 0, 0, 30, 0, 27,
+  36, 9, 13, 0, 0, 22, 2, 0, 70, 5,
+  0, 64, 0, 23, 40, 0, 76, 0, 6, 0,
+  58, 8, 17, 40, 5, 0, 26, 0, 1, 0,
+  0, 0, 39, 0, 71, 0, 10, 9, 14, 0,
+  2, 55, 59, 38, 4, 35, 16, 13, 17, 0,
+  0, 16, 84, 0, 0, 22, 51, 18, 0, 0,
+  0, 56, 0, 33, 67, 0, 5, 30, 0, 0,
+  0, 43, 70, 0, 18, 0, 0, 0, 0, 41,
+  0, 35, 57, 2, 29, 80, 44, 19, 0, 21,
+  0, 34, 36, 10, 35, 0, 10, 0, 0, 0,
+  30, 26, 0, 32, 0, 0, 35, 1, 27, 0,
+  0, 17, 9, 19, 26, 0, 10, 16, 0, 22,
+  23, 0, 61, 69, 0, 5, 0, 0, 0, 42,
+  5, 0, 0, 31, 0, 24, 35, 0, 0, 65,
+  2, 0, 10, 12, 63, 0, 37, 0, 27, 0,
+  0, 14, 0, 0, 0, 0, 0, 0, 0, 0,
+  4, 0, 41, 0, 35, 0, 8, 0, 0, 0,
+  0, 18, 14, 124, 8, 0, 7, 0, 0, 29,
+  52, 11, 0, 6, 15, 0, 0, 0, 0, 77,
+  2, 24, 40, 0, 0, 9, 0, 14, 0, 31,
+  15, 32, 0, 0, 0, 21, 0, 76, 0, 37,
+  0, 65, 12, 85, 61, 31, 0, 0, 0, 31,
+  31, 4, 2, 0, 40, 0, 18, 0, 23, 69,
+  0, 16, 12, 9, 0, 29, 58, 0, 39, 20,
+  11, 0, 25, 21, 19, 0, 0, 29, 42, 0,
+  16, 44, 15, 0, 11, 0, 0, 8, 0, 6,
+  0, 0, 4, 72, 0, 0, 0, 72, 0, 0,
+  4, 12, 57, 0, 27, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 77, 0, 47, 0, 6, 3,
+  0, 0, 55, 0, 22, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  51, 73, 59, 31, 0, 25, 25, 27, 1, 0,
+  0, 49, 62, 54, 0, 17, 9, 31, 5, 0,
+  0, 97, 24, 47, 40, 0, 67, 36, 173, 0,
+  0, 93, 100, 0, 16, 5, 0, 0, 0, 8,
+  0, 0, 58, 12, 35, 124, 53, 23, 0, 49,
+  0, 76, 26, 0, 69, 0, 16, 0, 0, 0,
+  74, 49, 11, 40, 2, 17, 33, 10, 4, 69,
+  21, 19, 13, 0, 5, 0, 39, 35, 1, 0,
+  24, 0, 46, 72, 0, 11, 18, 1, 41, 28,
+  0, 0, 0, 0, 0, 0, 56, 0, 0, 45,
+  33, 55, 30, 39, 114, 0, 28, 15, 40, 0,
+  15, 24, 15, 0, 0, 0, 36, 0, 25, 27,
+  59, 0, 0, 0, 16, 0, 11, 50, 1, 0,
+  0, 19, 11, 92, 28, 0, 0, 0, 0, 57,
+  41, 55, 0, 0, 0, 21, 17, 3, 0, 71,
+  14, 58, 40, 0, 38, 15, 173, 20, 0, 66,
+  63, 35, 0, 0, 0, 0, 0, 44, 0, 0,
+  10, 45, 6, 158, 67, 62, 0, 26, 0, 54,
+  50, 0, 21, 0, 34, 0, 34, 0, 70, 66,
+  0, 18, 13, 4, 36, 35, 62, 39, 52, 9,
+  43, 0, 28, 0, 37, 0, 0, 0, 49, 0,
+  22, 62, 0, 0, 39, 14, 21, 0, 0, 25,
+  16, 0, 24, 37, 0, 0, 11, 49, 15, 31,
+  12, 45, 82, 9, 31, 0, 0, 16, 0, 14,
+  0, 7, 0, 44, 106, 21, 47, 22, 46, 0,
+  0, 0, 16, 0, 13, 16, 0, 38, 0, 0,
+  45, 3, 47, 0, 0, 5, 2, 35, 43, 41,
+  0, 12, 6, 26, 23, 27, 41, 0, 0, 68,
+  18, 30, 36, 25, 149, 46, 0, 0, 61, 42,
+  0, 0, 0, 0, 0, 81, 0, 0, 0, 48,
+  15, 76, 31, 35, 0, 47, 0, 53, 104, 0,
+  0, 15, 21, 0, 0, 5, 36, 26, 0, 63,
+  0, 10, 50, 5, 36, 4, 6, 13, 12, 0,
+  42, 49, 0, 0, 30, 0, 84, 0, 8, 23,
+  8, 1, 28, 38, 67, 0, 15, 10, 39, 0,
+  22, 34, 0, 0, 46, 45, 0, 15, 23, 0,
+  43, 0, 19, 15, 9, 58, 9, 7, 0, 4,
+  0, 0, 41, 21, 33, 22, 54, 6, 20, 0,
+  41, 0, 6, 0, 2, 55, 59, 38, 4, 35,
+  16, 13, 17, 0, 0, 16, 84, 0, 0, 22,
+  51, 18, 0, 0, 0, 56, 0, 33, 67, 0,
+  5, 30, 0, 0, 0, 43, 70, 0, 18, 0,
+  0, 0, 0, 41, 0, 35, 57, 2, 29, 80,
+  44, 19, 0, 21, 0, 34, 36, 10, 35, 0,
+  10, 0, 0, 0, 30, 26, 0, 32, 0, 0,
+  35, 1, 27, 0, 0, 17, 9, 19, 26, 0,
+  10, 16, 0, 22, 23, 0, 61, 69, 0, 5,
+  0, 0, 0, 42, 5, 0, 0, 31, 0, 24,
+  35, 0, 0, 65, 2, 0, 10, 12, 63, 0,
+  37, 0, 27, 0, 0, 14, 0, 0, 0, 0,
+  0, 0, 0, 0, 4, 0, 41, 0, 35, 0,
+  8, 0, 0, 0, 0, 18, 14, 124, 8, 0,
+  7, 0, 0, 29, 52, 11, 0, 6, 15, 0,
+  0, 0, 0, 77, 2, 24, 40, 0, 0, 9,
+  0, 14, 0, 31, 15, 32, 0, 0, 0, 21,
+  0, 76, 0, 37, 0, 65, 12, 85, 61, 31,
+  0, 0, 0, 31, 31, 4, 2, 0, 40, 0,
+  18, 0, 23, 69, 0, 16, 12, 9, 0, 29,
+  58, 0, 39, 20, 11, 0, 25, 21, 19, 0,
+  0, 29, 42, 0, 16, 44, 15, 0, 11, 0,
+  0, 8, 0, 6, 0, 0, 4, 72, 0, 0,
+  0, 72, 0, 0, 4, 12, 57, 0, 27, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 77, 0,
+  47, 0, 6, 3, 0, 0, 55, 0, 22, 0,
+  0, 12, 0, 0, 34, 31, 37, 0, 16, 0,
+  1, 11, 52, 11, 10, 28, 23, 12, 0, 12,
+  51, 0, 0, 50, 24, 48, 0, 15, 0, 35,
+  0, 0, 38, 48, 0, 0, 0, 6, 0, 75,
+  0, 43, 0, 59, 29, 41, 15, 15, 0, 19,
+  0, 15, 107, 18, 0, 0, 17, 0, 0, 28,
+  25, 21, 0, 41, 0, 0, 45, 6, 26, 0,
+  0, 8, 0, 14, 33, 51, 4, 0, 0, 28,
+  84, 14, 0, 6, 19, 0, 12, 21, 18, 26,
+  0, 9, 9, 21, 0, 72, 0, 4, 31, 72,
+  0, 0, 2, 0, 39, 0, 26, 7, 9, 48,
+  0, 0, 0, 3, 0, 0, 39, 24, 41, 0,
+  37, 0, 84, 0, 64, 0, 13, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 19, 11, 92, 28, 0,
+  0, 0, 0, 57, 41, 55, 0, 0, 0, 21,
+  17, 3, 0, 71, 14, 58, 40, 0, 38, 15,
+  173, 20, 0, 66, 63, 35, 0, 0, 0, 0,
+  0, 44, 0, 0, 10, 45, 6, 158, 67, 62,
+  0, 26, 0, 54, 50, 0, 21, 0, 34, 0,
+  34, 0, 70, 66, 0, 18, 13, 4, 36, 35,
+  62, 39, 52, 9, 43, 0, 28, 0, 37, 0,
+  0, 0, 49, 0, 22, 62, 0, 0, 39, 14,
+  21, 0, 0, 25, 16, 0, 24, 37, 0, 0,
+  11, 49, 15, 31, 12, 45, 82, 9, 31, 0,
+  0, 16, 0, 14, 0, 7, 0, 44, 106, 21,
+  47, 22, 46, 0, 0, 0, 16, 0, 13, 16,
+  0, 38, 0, 0, 45, 3, 47, 0, 0, 5,
+  2, 35, 43, 41, 0, 12, 6, 26, 23, 27,
+  41, 0, 0, 68, 18, 30, 36, 25, 149, 46,
+  0, 0, 61, 42, 0, 0, 0, 0, 0, 81,
+  0, 0, 0, 48, 15, 76, 31, 35, 0, 47,
+  0, 53, 104, 0, 0, 15, 21, 0, 0, 5,
+  36, 26, 0, 63, 0, 10, 50, 5, 36, 4,
+  6, 13, 12, 0, 42, 49, 0, 0, 30, 0,
+  84, 0, 8, 23, 8, 1, 28, 38, 67, 0,
+  15, 10, 39, 0, 22, 34, 0, 0, 46, 45,
+  0, 15, 23, 0, 43, 0, 19, 15, 9, 58,
+  9, 7, 0, 4, 0, 0, 41, 21, 33, 22,
+  54, 6, 20, 0, 41, 0, 6, 0, 0, 46,
+  0, 5, 8, 0, 87, 3, 13, 14, 0, 39,
+  38, 29, 17, 42, 21, 66, 26, 57, 83, 0,
+  35, 35, 10, 13, 59, 37, 156, 43, 0, 0,
+  97, 0, 28, 0, 0, 0, 0, 60, 0, 0,
+  0, 58, 6, 89, 17, 14, 0, 43, 0, 39,
+  81, 11, 0, 0, 23, 0, 0, 26, 0, 12,
+  14, 12, 0, 0, 12, 25, 19, 1, 23, 0,
+  31, 0, 56, 15, 12, 6, 36, 0, 63, 0,
+  17, 12, 2, 0, 24, 1, 58, 22, 24, 0,
+  0, 0, 11, 31, 0, 0, 72, 22, 0, 0,
+  23, 0, 40, 0, 15, 32, 13, 36, 18, 8,
+  0, 1, 0, 0, 17, 8, 16, 23, 55, 3,
+  28, 0, 23, 0, 16, 0, 0, 0, 0, 18,
+  14, 124, 8, 0, 7, 0, 0, 29, 52, 11,
+  0, 6, 15, 0, 0, 0, 0, 77, 2, 24,
+  40, 0, 0, 9, 0, 14, 0, 31, 15, 32,
+  0, 0, 0, 21, 0, 76, 0, 37, 0, 65,
+  12, 85, 61, 31, 0, 0, 0, 31, 31, 4,
+  2, 0, 40, 0, 18, 0, 23, 69, 0, 16,
+  12, 9, 0, 29, 58, 0, 39, 20, 11, 0,
+  25, 21, 19, 0, 0, 29, 42, 0, 16, 44,
+  15, 0, 11, 0, 0, 8, 0, 6, 0, 0,
+  4, 72, 0, 0, 0, 72, 0, 0, 4, 12,
+  57, 0, 27, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 77, 0, 47, 0, 6, 3, 0, 0,
+  55, 0, 22, 0, 0, 12, 0, 0, 34, 31,
+  37, 0, 16, 0, 1, 11, 52, 11, 10, 28,
+  23, 12, 0, 12, 51, 0, 0, 50, 24, 48,
+  0, 15, 0, 35, 0, 0, 38, 48, 0, 0,
+  0, 6, 0, 75, 0, 43, 0, 59, 29, 41,
+  15, 15, 0, 19, 0, 15, 107, 18, 0, 0,
+  17, 0, 0, 28, 25, 21, 0, 41, 0, 0,
+  45, 6, 26, 0, 0, 8, 0, 14, 33, 51,
+  4, 0, 0, 28, 84, 14, 0, 6, 19, 0,
+  12, 21, 18, 26, 0, 9, 9, 21, 0, 72,
+  0, 4, 31, 72, 0, 0, 2, 0, 39, 0,
+  26, 7, 9, 48, 0, 0, 0, 3, 0, 0,
+  39, 24, 41, 0, 37, 0, 84, 0, 64, 0,
+  13, 0, 0, 32, 0, 0, 20, 0, 56, 0,
+  35, 0, 0, 29, 28, 20, 52, 24, 39, 50,
+  3, 36, 95, 0, 10, 21, 21, 25, 9, 34,
+  0, 29, 0, 0, 63, 0, 10, 0, 0, 0,
+  0, 48, 0, 3, 0, 63, 16, 61, 5, 1,
+  0, 6, 0, 3, 79, 33, 0, 0, 18, 0,
+  0, 7, 0, 7, 0, 0, 0, 0, 32, 20,
+  20, 0, 0, 0, 0, 0, 62, 0, 13, 2,
+  0, 6, 67, 26, 0, 0, 6, 0, 7, 0,
+  11, 49, 18, 0, 0, 4, 0, 55, 0, 6,
+  64, 36, 0, 0, 3, 0, 34, 0, 22, 9,
+  31, 35, 0, 0, 0, 0, 0, 0, 14, 2,
+  12, 0, 45, 0, 77, 0, 41, 0, 26, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 38, 0, 0, 45, 3,
+  47, 0, 0, 5, 2, 35, 43, 41, 0, 12,
+  6, 26, 23, 27, 41, 0, 0, 68, 18, 30,
+  36, 25, 149, 46, 0, 0, 61, 42, 0, 0,
+  0, 0, 0, 81, 0, 0, 0, 48, 15, 76,
+  31, 35, 0, 47, 0, 53, 104, 0, 0, 15,
+  21, 0, 0, 5, 36, 26, 0, 63, 0, 10,
+  50, 5, 36, 4, 6, 13, 12, 0, 42, 49,
+  0, 0, 30, 0, 84, 0, 8, 23, 8, 1,
+  28, 38, 67, 0, 15, 10, 39, 0, 22, 34,
+  0, 0, 46, 45, 0, 15, 23, 0, 43, 0,
+  19, 15, 9, 58, 9, 7, 0, 4, 0, 0,
+  41, 21, 33, 22, 54, 6, 20, 0, 41, 0,
+  6, 0, 0, 46, 0, 5, 8, 0, 87, 3,
+  13, 14, 0, 39, 38, 29, 17, 42, 21, 66,
+  26, 57, 83, 0, 35, 35, 10, 13, 59, 37,
+  156, 43, 0, 0, 97, 0, 28, 0, 0, 0,
+  0, 60, 0, 0, 0, 58, 6, 89, 17, 14,
+  0, 43, 0, 39, 81, 11, 0, 0, 23, 0,
+  0, 26, 0, 12, 14, 12, 0, 0, 12, 25,
+  19, 1, 23, 0, 31, 0, 56, 15, 12, 6,
+  36, 0, 63, 0, 17, 12, 2, 0, 24, 1,
+  58, 22, 24, 0, 0, 0, 11, 31, 0, 0,
+  72, 22, 0, 0, 23, 0, 40, 0, 15, 32,
+  13, 36, 18, 8, 0, 1, 0, 0, 17, 8,
+  16, 23, 55, 3, 28, 0, 23, 0, 16, 0,
+  0, 26, 0, 19, 10, 0, 77, 11, 23, 31,
+  0, 35, 23, 57, 9, 52, 22, 74, 37, 27,
+  102, 0, 0, 31, 15, 13, 55, 46, 154, 59,
+  0, 4, 97, 0, 27, 0, 0, 0, 0, 55,
+  0, 0, 0, 52, 12, 66, 15, 9, 0, 41,
+  0, 76, 57, 46, 4, 14, 7, 0, 0, 16,
+  0, 0, 24, 8, 0, 8, 10, 17, 12, 30,
+  0, 0, 27, 0, 37, 13, 12, 0, 23, 0,
+  76, 0, 17, 2, 0, 0, 21, 18, 71, 15,
+  30, 0, 0, 0, 29, 12, 20, 0, 83, 41,
+  0, 0, 20, 0, 63, 0, 2, 35, 27, 25,
+  17, 5, 25, 0, 6, 0, 30, 0, 13, 13,
+  58, 0, 47, 0, 29, 0, 20, 0, 0, 12,
+  0, 0, 34, 31, 37, 0, 16, 0, 1, 11,
+  52, 11, 10, 28, 23, 12, 0, 12, 51, 0,
+  0, 50, 24, 48, 0, 15, 0, 35, 0, 0,
+  38, 48, 0, 0, 0, 6, 0, 75, 0, 43,
+  0, 59, 29, 41, 15, 15, 0, 19, 0, 15,
+  107, 18, 0, 0, 17, 0, 0, 28, 25, 21,
+  0, 41, 0, 0, 45, 6, 26, 0, 0, 8,
+  0, 14, 33, 51, 4, 0, 0, 28, 84, 14,
+  0, 6, 19, 0, 12, 21, 18, 26, 0, 9,
+  9, 21, 0, 72, 0, 4, 31, 72, 0, 0,
+  2, 0, 39, 0, 26, 7, 9, 48, 0, 0,
+  0, 3, 0, 0, 39, 24, 41, 0, 37, 0,
+  84, 0, 64, 0, 13, 0, 0, 32, 0, 0,
+  20, 0, 56, 0, 35, 0, 0, 29, 28, 20,
+  52, 24, 39, 50, 3, 36, 95, 0, 10, 21,
+  21, 25, 9, 34, 0, 29, 0, 0, 63, 0,
+  10, 0, 0, 0, 0, 48, 0, 3, 0, 63,
+  16, 61, 5, 1, 0, 6, 0, 3, 79, 33,
+  0, 0, 18, 0, 0, 7, 0, 7, 0, 0,
+  0, 0, 32, 20, 20, 0, 0, 0, 0, 0,
+  62, 0, 13, 2, 0, 6, 67, 26, 0, 0,
+  6, 0, 7, 0, 11, 49, 18, 0, 0, 4,
+  0, 55, 0, 6, 64, 36, 0, 0, 3, 0,
+  34, 0, 22, 9, 31, 35, 0, 0, 0, 0,
+  0, 0, 14, 2, 12, 0, 45, 0, 77, 0,
+  41, 0, 26, 0, 0, 27, 0, 15, 17, 0,
+  54, 0, 26, 19, 0, 24, 19, 41, 54, 36,
+  42, 53, 0, 29, 105, 0, 0, 24, 36, 35,
+  13, 47, 0, 36, 0, 0, 67, 9, 22, 0,
+  0, 0, 0, 30, 0, 0, 0, 58, 16, 44,
+  12, 18, 0, 3, 21, 11, 61, 51, 0, 0,
+  3, 0, 0, 16, 0, 0, 0, 0, 0, 0,
+  38, 18, 25, 0, 0, 0, 0, 0, 56, 0,
+  14, 7, 0, 10, 79, 42, 2, 0, 11, 0,
+  6, 6, 16, 33, 14, 0, 0, 12, 0, 42,
+  0, 6, 83, 38, 0, 0, 5, 0, 37, 0,
+  29, 9, 43, 27, 0, 0, 1, 0, 0, 0,
+  12, 0, 2, 0, 32, 0, 100, 0, 40, 0,
+  22, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 46, 0, 5,
+  8, 0, 87, 3, 13, 14, 0, 39, 38, 29,
+  17, 42, 21, 66, 26, 57, 83, 0, 35, 35,
+  10, 13, 59, 37, 156, 43, 0, 0, 97, 0,
+  28, 0, 0, 0, 0, 60, 0, 0, 0, 58,
+  6, 89, 17, 14, 0, 43, 0, 39, 81, 11,
+  0, 0, 23, 0, 0, 26, 0, 12, 14, 12,
+  0, 0, 12, 25, 19, 1, 23, 0, 31, 0,
+  56, 15, 12, 6, 36, 0, 63, 0, 17, 12,
+  2, 0, 24, 1, 58, 22, 24, 0, 0, 0,
+  11, 31, 0, 0, 72, 22, 0, 0, 23, 0,
+  40, 0, 15, 32, 13, 36, 18, 8, 0, 1,
+  0, 0, 17, 8, 16, 23, 55, 3, 28, 0,
+  23, 0, 16, 0, 0, 26, 0, 19, 10, 0,
+  77, 11, 23, 31, 0, 35, 23, 57, 9, 52,
+  22, 74, 37, 27, 102, 0, 0, 31, 15, 13,
+  55, 46, 154, 59, 0, 4, 97, 0, 27, 0,
+  0, 0, 0, 55, 0, 0, 0, 52, 12, 66,
+  15, 9, 0, 41, 0, 76, 57, 46, 4, 14,
+  7, 0, 0, 16, 0, 0, 24, 8, 0, 8,
+  10, 17, 12, 30, 0, 0, 27, 0, 37, 13,
+  12, 0, 23, 0, 76, 0, 17, 2, 0, 0,
+  21, 18, 71, 15, 30, 0, 0, 0, 29, 12,
+  20, 0, 83, 41, 0, 0, 20, 0, 63, 0,
+  2, 35, 27, 25, 17, 5, 25, 0, 6, 0,
+  30, 0, 13, 13, 58, 0, 47, 0, 29, 0,
+  20, 0, 0, 16, 0, 14, 1, 0, 63, 29,
+  23, 32, 0, 13, 0, 45, 0, 47, 19, 68,
+  39, 6, 67, 0, 0, 42, 12, 16, 57, 47,
+  121, 62, 0, 0, 87, 0, 30, 0, 0, 0,
+  0, 41, 0, 0, 0, 17, 8, 43, 25, 0,
+  0, 37, 11, 79, 44, 41, 28, 6, 2, 20,
+  0, 16, 0, 0, 13, 18, 0, 16, 25, 5,
+  1, 40, 0, 0, 44, 0, 27, 34, 0, 0,
+  27, 0, 77, 0, 17, 14, 0, 0, 18, 24,
+  76, 0, 60, 4, 0, 4, 30, 0, 46, 0,
+  60, 49, 0, 0, 9, 0, 57, 0, 0, 18,
+  38, 31, 23, 17, 38, 0, 21, 0, 27, 0,
+  7, 10, 58, 0, 64, 0, 40, 0, 0, 0,
+  0, 32, 0, 0, 20, 0, 56, 0, 35, 0,
+  0, 29, 28, 20, 52, 24, 39, 50, 3, 36,
+  95, 0, 10, 21, 21, 25, 9, 34, 0, 29,
+  0, 0, 63, 0, 10, 0, 0, 0, 0, 48,
+  0, 3, 0, 63, 16, 61, 5, 1, 0, 6,
+  0, 3, 79, 33, 0, 0, 18, 0, 0, 7,
+  0, 7, 0, 0, 0, 0, 32, 20, 20, 0,
+  0, 0, 0, 0, 62, 0, 13, 2, 0, 6,
+  67, 26, 0, 0, 6, 0, 7, 0, 11, 49,
+  18, 0, 0, 4, 0, 55, 0, 6, 64, 36,
+  0, 0, 3, 0, 34, 0, 22, 9, 31, 35,
+  0, 0, 0, 0, 0, 0, 14, 2, 12, 0,
+  45, 0, 77, 0, 41, 0, 26, 0, 0, 27,
+  0, 15, 17, 0, 54, 0, 26, 19, 0, 24,
+  19, 41, 54, 36, 42, 53, 0, 29, 105, 0,
+  0, 24, 36, 35, 13, 47, 0, 36, 0, 0,
+  67, 9, 22, 0, 0, 0, 0, 30, 0, 0,
+  0, 58, 16, 44, 12, 18, 0, 3, 21, 11,
+  61, 51, 0, 0, 3, 0, 0, 16, 0, 0,
+  0, 0, 0, 0, 38, 18, 25, 0, 0, 0,
+  0, 0, 56, 0, 14, 7, 0, 10, 79, 42,
+  2, 0, 11, 0, 6, 6, 16, 33, 14, 0,
+  0, 12, 0, 42, 0, 6, 83, 38, 0, 0,
+  5, 0, 37, 0, 29, 9, 43, 27, 0, 0,
+  1, 0, 0, 0, 12, 0, 2, 0, 32, 0,
+  100, 0, 40, 0, 22, 0, 0, 22, 0, 0,
+  8, 0, 32, 0, 33, 28, 0, 1, 0, 29,
+  40, 48, 56, 56, 12, 13, 56, 0, 0, 29,
+  28, 42, 16, 56, 0, 19, 0, 0, 57, 2,
+  6, 0, 0, 0, 0, 24, 0, 0, 0, 16,
+  1, 14, 21, 10, 0, 5, 37, 5, 41, 38,
+  0, 11, 0, 24, 0, 42, 0, 0, 0, 0,
+  0, 0, 70, 24, 23, 0, 0, 0, 11, 21,
+  44, 0, 8, 0, 0, 12, 70, 39, 7, 8,
+  19, 29, 0, 28, 16, 3, 38, 30, 0, 36,
+  4, 7, 0, 4, 60, 56, 0, 0, 5, 0,
+  33, 0, 12, 9, 35, 35, 0, 12, 2, 0,
+  10, 0, 0, 0, 0, 0, 6, 0, 111, 0,
+  30, 0, 9, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 26,
+  0, 19, 10, 0, 77, 11, 23, 31, 0, 35,
+  23, 57, 9, 52, 22, 74, 37, 27, 102, 0,
+  0, 31, 15, 13, 55, 46, 154, 59, 0, 4,
+  97, 0, 27, 0, 0, 0, 0, 55, 0, 0,
+  0, 52, 12, 66, 15, 9, 0, 41, 0, 76,
+  57, 46, 4, 14, 7, 0, 0, 16, 0, 0,
+  24, 8, 0, 8, 10, 17, 12, 30, 0, 0,
+  27, 0, 37, 13, 12, 0, 23, 0, 76, 0,
+  17, 2, 0, 0, 21, 18, 71, 15, 30, 0,
+  0, 0, 29, 12, 20, 0, 83, 41, 0, 0,
+  20, 0, 63, 0, 2, 35, 27, 25, 17, 5,
+  25, 0, 6, 0, 30, 0, 13, 13, 58, 0,
+  47, 0, 29, 0, 20, 0, 0, 16, 0, 14,
+  1, 0, 63, 29, 23, 32, 0, 13, 0, 45,
+  0, 47, 19, 68, 39, 6, 67, 0, 0, 42,
+  12, 16, 57, 47, 121, 62, 0, 0, 87, 0,
+  30, 0, 0, 0, 0, 41, 0, 0, 0, 17,
+  8, 43, 25, 0, 0, 37, 11, 79, 44, 41,
+  28, 6, 2, 20, 0, 16, 0, 0, 13, 18,
+  0, 16, 25, 5, 1, 40, 0, 0, 44, 0,
+  27, 34, 0, 0, 27, 0, 77, 0, 17, 14,
+  0, 0, 18, 24, 76, 0, 60, 4, 0, 4,
+  30, 0, 46, 0, 60, 49, 0, 0, 9, 0,
+  57, 0, 0, 18, 38, 31, 23, 17, 38, 0,
+  21, 0, 27, 0, 7, 10, 58, 0, 64, 0,
+  40, 0, 0, 0, 0, 26, 0, 7, 2, 0,
+  63, 38, 23, 37, 2, 6, 0, 40, 0, 45,
+  6, 67, 46, 14, 38, 0, 0, 48, 16, 24,
+  55, 58, 112, 45, 0, 0, 68, 0, 26, 0,
+  0, 0, 0, 44, 0, 0, 0, 2, 1, 25,
+  39, 0, 0, 36, 14, 72, 25, 35, 35, 0,
+  0, 49, 0, 21, 0, 0, 16, 34, 0, 26,
+  35, 0, 2, 44, 0, 0, 64, 0, 29, 35,
+  0, 1, 39, 0, 66, 5, 11, 30, 0, 6,
+  14, 27, 89, 0, 74, 5, 0, 3, 35, 0,
+  49, 0, 45, 48, 0, 0, 10, 0, 56, 0,
+  0, 23, 42, 24, 30, 23, 39, 0, 31, 0,
+  11, 0, 7, 13, 40, 0, 62, 0, 52, 0,
+  0, 2, 0, 27, 0, 15, 17, 0, 54, 0,
+  26, 19, 0, 24, 19, 41, 54, 36, 42, 53,
+  0, 29, 105, 0, 0, 24, 36, 35, 13, 47,
+  0, 36, 0, 0, 67, 9, 22, 0, 0, 0,
+  0, 30, 0, 0, 0, 58, 16, 44, 12, 18,
+  0, 3, 21, 11, 61, 51, 0, 0, 3, 0,
+  0, 16, 0, 0, 0, 0, 0, 0, 38, 18,
+  25, 0, 0, 0, 0, 0, 56, 0, 14, 7,
+  0, 10, 79, 42, 2, 0, 11, 0, 6, 6,
+  16, 33, 14, 0, 0, 12, 0, 42, 0, 6,
+  83, 38, 0, 0, 5, 0, 37, 0, 29, 9,
+  43, 27, 0, 0, 1, 0, 0, 0, 12, 0,
+  2, 0, 32, 0, 100, 0, 40, 0, 22, 0,
+  0, 22, 0, 0, 8, 0, 32, 0, 33, 28,
+  0, 1, 0, 29, 40, 48, 56, 56, 12, 13,
+  56, 0, 0, 29, 28, 42, 16, 56, 0, 19,
+  0, 0, 57, 2, 6, 0, 0, 0, 0, 24,
+  0, 0, 0, 16, 1, 14, 21, 10, 0, 5,
+  37, 5, 41, 38, 0, 11, 0, 24, 0, 42,
+  0, 0, 0, 0, 0, 0, 70, 24, 23, 0,
+  0, 0, 11, 21, 44, 0, 8, 0, 0, 12,
+  70, 39, 7, 8, 19, 29, 0, 28, 16, 3,
+  38, 30, 0, 36, 4, 7, 0, 4, 60, 56,
+  0, 0, 5, 0, 33, 0, 12, 9, 35, 35,
+  0, 12, 2, 0, 10, 0, 0, 0, 0, 0,
+  6, 0, 111, 0, 30, 0, 9, 0, 0, 40,
+  0, 0, 15, 0, 26, 0, 40, 45, 1, 0,
+  0, 24, 16, 54, 51, 59, 27, 8, 15, 0,
+  0, 41, 35, 63, 9, 78, 0, 0, 8, 0,
+  21, 0, 0, 0, 0, 0, 0, 35, 0, 0,
+  0, 0, 0, 0, 38, 0, 0, 5, 22, 8,
+  24, 27, 0, 0, 0, 65, 0, 36, 0, 0,
+  0, 33, 0, 2, 97, 14, 35, 0, 0, 0,
+  20, 36, 43, 5, 0, 0, 0, 9, 52, 53,
+  0, 20, 31, 37, 0, 46, 33, 0, 42, 41,
+  0, 48, 0, 0, 2, 16, 45, 62, 0, 0,
+  12, 0, 34, 0, 0, 17, 24, 34, 0, 27,
+  0, 0, 25, 0, 0, 14, 10, 0, 0, 8,
+  110, 0, 42, 0, 17, 9, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 16, 0, 14, 1, 0, 63, 29, 23, 32,
+  0, 13, 0, 45, 0, 47, 19, 68, 39, 6,
+  67, 0, 0, 42, 12, 16, 57, 47, 121, 62,
+  0, 0, 87, 0, 30, 0, 0, 0, 0, 41,
+  0, 0, 0, 17, 8, 43, 25, 0, 0, 37,
+  11, 79, 44, 41, 28, 6, 2, 20, 0, 16,
+  0, 0, 13, 18, 0, 16, 25, 5, 1, 40,
+  0, 0, 44, 0, 27, 34, 0, 0, 27, 0,
+  77, 0, 17, 14, 0, 0, 18, 24, 76, 0,
+  60, 4, 0, 4, 30, 0, 46, 0, 60, 49,
+  0, 0, 9, 0, 57, 0, 0, 18, 38, 31,
+  23, 17, 38, 0, 21, 0, 27, 0, 7, 10,
+  58, 0, 64, 0, 40, 0, 0, 0, 0, 26,
+  0, 7, 2, 0, 63, 38, 23, 37, 2, 6,
+  0, 40, 0, 45, 6, 67, 46, 14, 38, 0,
+  0, 48, 16, 24, 55, 58, 112, 45, 0, 0,
+  68, 0, 26, 0, 0, 0, 0, 44, 0, 0,
+  0, 2, 1, 25, 39, 0, 0, 36, 14, 72,
+  25, 35, 35, 0, 0, 49, 0, 21, 0, 0,
+  16, 34, 0, 26, 35, 0, 2, 44, 0, 0,
+  64, 0, 29, 35, 0, 1, 39, 0, 66, 5,
+  11, 30, 0, 6, 14, 27, 89, 0, 74, 5,
+  0, 3, 35, 0, 49, 0, 45, 48, 0, 0,
+  10, 0, 56, 0, 0, 23, 42, 24, 30, 23,
+  39, 0, 31, 0, 11, 0, 7, 13, 40, 0,
+  62, 0, 52, 0, 0, 2, 0, 45, 0, 0,
+  0, 0, 62, 43, 22, 57, 2, 15, 0, 41,
+  7, 47, 6, 61, 60, 24, 15, 0, 0, 43,
+  26, 39, 53, 69, 110, 31, 0, 0, 54, 0,
+  28, 0, 0, 0, 0, 53, 0, 0, 0, 0,
+  3, 7, 35, 0, 0, 41, 15, 67, 26, 42,
+  26, 0, 0, 57, 0, 32, 0, 0, 14, 45,
+  0, 35, 43, 0, 0, 32, 0, 1, 56, 0,
+  32, 31, 0, 8, 48, 0, 66, 25, 6, 25,
+  12, 12, 17, 31, 106, 0, 60, 5, 0, 7,
+  27, 0, 51, 1, 26, 50, 0, 0, 24, 0,
+  67, 0, 2, 18, 45, 33, 35, 9, 30, 0,
+  39, 0, 0, 6, 16, 9, 41, 0, 67, 0,
+  44, 0, 11, 14, 0, 22, 0, 0, 8, 0,
+  32, 0, 33, 28, 0, 1, 0, 29, 40, 48,
+  56, 56, 12, 13, 56, 0, 0, 29, 28, 42,
+  16, 56, 0, 19, 0, 0, 57, 2, 6, 0,
+  0, 0, 0, 24, 0, 0, 0, 16, 1, 14,
+  21, 10, 0, 5, 37, 5, 41, 38, 0, 11,
+  0, 24, 0, 42, 0, 0, 0, 0, 0, 0,
+  70, 24, 23, 0, 0, 0, 11, 21, 44, 0,
+  8, 0, 0, 12, 70, 39, 7, 8, 19, 29,
+  0, 28, 16, 3, 38, 30, 0, 36, 4, 7,
+  0, 4, 60, 56, 0, 0, 5, 0, 33, 0,
+  12, 9, 35, 35, 0, 12, 2, 0, 10, 0,
+  0, 0, 0, 0, 6, 0, 111, 0, 30, 0,
+  9, 0, 0, 40, 0, 0, 15, 0, 26, 0,
+  40, 45, 1, 0, 0, 24, 16, 54, 51, 59,
+  27, 8, 15, 0, 0, 41, 35, 63, 9, 78,
+  0, 0, 8, 0, 21, 0, 0, 0, 0, 0,
+  0, 35, 0, 0, 0, 0, 0, 0, 38, 0,
+  0, 5, 22, 8, 24, 27, 0, 0, 0, 65,
+  0, 36, 0, 0, 0, 33, 0, 2, 97, 14,
+  35, 0, 0, 0, 20, 36, 43, 5, 0, 0,
+  0, 9, 52, 53, 0, 20, 31, 37, 0, 46,
+  33, 0, 42, 41, 0, 48, 0, 0, 2, 16,
+  45, 62, 0, 0, 12, 0, 34, 0, 0, 17,
+  24, 34, 0, 27, 0, 0, 25, 0, 0, 14,
+  10, 0, 0, 8, 110, 0, 42, 0, 17, 9,
+  0, 44, 12, 0, 11, 0, 23, 0, 54, 79,
+  0, 0, 0, 0, 3, 53, 49, 60, 36, 23,
+  0, 0, 0, 42, 29, 49, 27, 93, 0, 0,
+  15, 0, 15, 0, 0, 0, 0, 32, 0, 20,
+  0, 0, 0, 0, 0, 7, 42, 0, 0, 5,
+  12, 12, 37, 19, 0, 0, 0, 60, 0, 25,
+  1, 12, 0, 29, 0, 0, 86, 0, 36, 9,
+  0, 0, 13, 38, 43, 13, 0, 16, 0, 0,
+  60, 35, 0, 10, 27, 23, 0, 45, 43, 0,
+  17, 49, 0, 42, 0, 0, 4, 7, 24, 57,
+  0, 0, 23, 0, 36, 0, 0, 1, 19, 59,
+  0, 22, 0, 0, 36, 0, 0, 24, 28, 0,
+  1, 18, 93, 0, 22, 0, 42, 20, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 26, 0, 7, 2, 0, 63, 38,
+  23, 37, 2, 6, 0, 40, 0, 45, 6, 67,
+  46, 14, 38, 0, 0, 48, 16, 24, 55, 58,
+  112, 45, 0, 0, 68, 0, 26, 0, 0, 0,
+  0, 44, 0, 0, 0, 2, 1, 25, 39, 0,
+  0, 36, 14, 72, 25, 35, 35, 0, 0, 49,
+  0, 21, 0, 0, 16, 34, 0, 26, 35, 0,
+  2, 44, 0, 0, 64, 0, 29, 35, 0, 1,
+  39, 0, 66, 5, 11, 30, 0, 6, 14, 27,
+  89, 0, 74, 5, 0, 3, 35, 0, 49, 0,
+  45, 48, 0, 0, 10, 0, 56, 0, 0, 23,
+  42, 24, 30, 23, 39, 0, 31, 0, 11, 0,
+  7, 13, 40, 0, 62, 0, 52, 0, 0, 2,
+  0, 45, 0, 0, 0, 0, 62, 43, 22, 57,
+  2, 15, 0, 41, 7, 47, 6, 61, 60, 24,
+  15, 0, 0, 43, 26, 39, 53, 69, 110, 31,
+  0, 0, 54, 0, 28, 0, 0, 0, 0, 53,
+  0, 0, 0, 0, 3, 7, 35, 0, 0, 41,
+  15, 67, 26, 42, 26, 0, 0, 57, 0, 32,
+  0, 0, 14, 45, 0, 35, 43, 0, 0, 32,
+  0, 1, 56, 0, 32, 31, 0, 8, 48, 0,
+  66, 25, 6, 25, 12, 12, 17, 31, 106, 0,
+  60, 5, 0, 7, 27, 0, 51, 1, 26, 50,
+  0, 0, 24, 0, 67, 0, 2, 18, 45, 33,
+  35, 9, 30, 0, 39, 0, 0, 6, 16, 9,
+  41, 0, 67, 0, 44, 0, 11, 14, 0, 50,
+  11, 0, 0, 0, 74, 36, 26, 54, 0, 25,
+  0, 0, 19, 41, 32, 80, 62, 25, 0, 0,
+  0, 42, 46, 46, 53, 65, 120, 31, 0, 0,
+  44, 0, 29, 0, 0, 0, 0, 45, 0, 0,
+  34, 0, 9, 14, 37, 0, 0, 29, 26, 40,
+  42, 29, 11, 0, 0, 42, 0, 48, 0, 0,
+  13, 56, 0, 27, 47, 0, 0, 21, 0, 6,
+  37, 0, 32, 21, 1, 6, 34, 0, 57, 25,
+  7, 31, 24, 9, 22, 28, 77, 0, 42, 0,
+  0, 21, 17, 0, 36, 22, 1, 31, 0, 0,
+  35, 0, 70, 0, 6, 12, 44, 44, 51, 12,
+  23, 0, 31, 0, 0, 14, 39, 0, 40, 13,
+  69, 0, 18, 0, 49, 15, 0, 40, 0, 0,
+  15, 0, 26, 0, 40, 45, 1, 0, 0, 24,
+  16, 54, 51, 59, 27, 8, 15, 0, 0, 41,
+  35, 63, 9, 78, 0, 0, 8, 0, 21, 0,
+  0, 0, 0, 0, 0, 35, 0, 0, 0, 0,
+  0, 0, 38, 0, 0, 5, 22, 8, 24, 27,
+  0, 0, 0, 65, 0, 36, 0, 0, 0, 33,
+  0, 2, 97, 14, 35, 0, 0, 0, 20, 36,
+  43, 5, 0, 0, 0, 9, 52, 53, 0, 20,
+  31, 37, 0, 46, 33, 0, 42, 41, 0, 48,
+  0, 0, 2, 16, 45, 62, 0, 0, 12, 0,
+  34, 0, 0, 17, 24, 34, 0, 27, 0, 0,
+  25, 0, 0, 14, 10, 0, 0, 8, 110, 0,
+  42, 0, 17, 9, 0, 44, 12, 0, 11, 0,
+  23, 0, 54, 79, 0, 0, 0, 0, 3, 53,
+  49, 60, 36, 23, 0, 0, 0, 42, 29, 49,
+  27, 93, 0, 0, 15, 0, 15, 0, 0, 0,
+  0, 32, 0, 20, 0, 0, 0, 0, 0, 7,
+  42, 0, 0, 5, 12, 12, 37, 19, 0, 0,
+  0, 60, 0, 25, 1, 12, 0, 29, 0, 0,
+  86, 0, 36, 9, 0, 0, 13, 38, 43, 13,
+  0, 16, 0, 0, 60, 35, 0, 10, 27, 23,
+  0, 45, 43, 0, 17, 49, 0, 42, 0, 0,
+  4, 7, 24, 57, 0, 0, 23, 0, 36, 0,
+  0, 1, 19, 59, 0, 22, 0, 0, 36, 0,
+  0, 24, 28, 0, 1, 18, 93, 0, 22, 0,
+  42, 20, 0, 38, 33, 0, 0, 0, 27, 0,
+  63, 89, 0, 12, 0, 0, 14, 41, 49, 72,
+  30, 11, 0, 0, 0, 57, 37, 23, 43, 98,
+  0, 0, 23, 0, 9, 0, 0, 0, 0, 70,
+  0, 0, 14, 15, 16, 0, 0, 17, 24, 0,
+  0, 0, 12, 0, 48, 0, 0, 0, 0, 33,
+  0, 3, 10, 18, 0, 50, 0, 0, 81, 0,
+  15, 42, 0, 0, 7, 44, 23, 12, 4, 28,
+  0, 0, 63, 33, 2, 27, 31, 25, 2, 25,
+  25, 0, 0, 46, 0, 33, 0, 0, 0, 14,
+  0, 51, 3, 0, 8, 0, 41, 0, 0, 18,
+  2, 64, 10, 19, 0, 0, 55, 0, 0, 23,
+  45, 0, 7, 3, 63, 0, 0, 0, 78, 18,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 45, 0, 0, 0, 0,
+  62, 43, 22, 57, 2, 15, 0, 41, 7, 47,
+  6, 61, 60, 24, 15, 0, 0, 43, 26, 39,
+  53, 69, 110, 31, 0, 0, 54, 0, 28, 0,
+  0, 0, 0, 53, 0, 0, 0, 0, 3, 7,
+  35, 0, 0, 41, 15, 67, 26, 42, 26, 0,
+  0, 57, 0, 32, 0, 0, 14, 45, 0, 35,
+  43, 0, 0, 32, 0, 1, 56, 0, 32, 31,
+  0, 8, 48, 0, 66, 25, 6, 25, 12, 12,
+  17, 31, 106, 0, 60, 5, 0, 7, 27, 0,
+  51, 1, 26, 50, 0, 0, 24, 0, 67, 0,
+  2, 18, 45, 33, 35, 9, 30, 0, 39, 0,
+  0, 6, 16, 9, 41, 0, 67, 0, 44, 0,
+  11, 14, 0, 50, 11, 0, 0, 0, 74, 36,
+  26, 54, 0, 25, 0, 0, 19, 41, 32, 80,
+  62, 25, 0, 0, 0, 42, 46, 46, 53, 65,
+  120, 31, 0, 0, 44, 0, 29, 0, 0, 0,
+  0, 45, 0, 0, 34, 0, 9, 14, 37, 0,
+  0, 29, 26, 40, 42, 29, 11, 0, 0, 42,
+  0, 48, 0, 0, 13, 56, 0, 27, 47, 0,
+  0, 21, 0, 6, 37, 0, 32, 21, 1, 6,
+  34, 0, 57, 25, 7, 31, 24, 9, 22, 28,
+  77, 0, 42, 0, 0, 21, 17, 0, 36, 22,
+  1, 31, 0, 0, 35, 0, 70, 0, 6, 12,
+  44, 44, 51, 12, 23, 0, 31, 0, 0, 14,
+  39, 0, 40, 13, 69, 0, 18, 0, 49, 15,
+  0, 53, 6, 0, 0, 0, 108, 18, 35, 62,
+  0, 10, 0, 0, 14, 70, 19, 66, 42, 16,
+  0, 0, 0, 59, 58, 43, 47, 64, 123, 32,
+  0, 0, 54, 0, 29, 0, 0, 0, 9, 45,
+  0, 0, 26, 16, 0, 23, 56, 0, 0, 30,
+  14, 43, 57, 13, 7, 3, 3, 60, 0, 52,
+  0, 9, 11, 62, 0, 31, 41, 10, 20, 3,
+  0, 13, 31, 0, 45, 36, 0, 0, 32, 0,
+  56, 38, 10, 21, 24, 0, 26, 22, 84, 1,
+  35, 0, 0, 34, 0, 0, 6, 15, 19, 40,
+  0, 0, 26, 0, 74, 0, 0, 29, 37, 36,
+  50, 12, 2, 0, 29, 0, 0, 35, 51, 0,
+  32, 0, 64, 0, 33, 0, 43, 1, 0, 44,
+  12, 0, 11, 0, 23, 0, 54, 79, 0, 0,
+  0, 0, 3, 53, 49, 60, 36, 23, 0, 0,
+  0, 42, 29, 49, 27, 93, 0, 0, 15, 0,
+  15, 0, 0, 0, 0, 32, 0, 20, 0, 0,
+  0, 0, 0, 7, 42, 0, 0, 5, 12, 12,
+  37, 19, 0, 0, 0, 60, 0, 25, 1, 12,
+  0, 29, 0, 0, 86, 0, 36, 9, 0, 0,
+  13, 38, 43, 13, 0, 16, 0, 0, 60, 35,
+  0, 10, 27, 23, 0, 45, 43, 0, 17, 49,
+  0, 42, 0, 0, 4, 7, 24, 57, 0, 0,
+  23, 0, 36, 0, 0, 1, 19, 59, 0, 22,
+  0, 0, 36, 0, 0, 24, 28, 0, 1, 18,
+  93, 0, 22, 0, 42, 20, 0, 38, 33, 0,
+  0, 0, 27, 0, 63, 89, 0, 12, 0, 0,
+  14, 41, 49, 72, 30, 11, 0, 0, 0, 57,
+  37, 23, 43, 98, 0, 0, 23, 0, 9, 0,
+  0, 0, 0, 70, 0, 0, 14, 15, 16, 0,
+  0, 17, 24, 0, 0, 0, 12, 0, 48, 0,
+  0, 0, 0, 33, 0, 3, 10, 18, 0, 50,
+  0, 0, 81, 0, 15, 42, 0, 0, 7, 44,
+  23, 12, 4, 28, 0, 0, 63, 33, 2, 27,
+  31, 25, 2, 25, 25, 0, 0, 46, 0, 33,
+  0, 0, 0, 14, 0, 51, 3, 0, 8, 0,
+  41, 0, 0, 18, 2, 64, 10, 19, 0, 0,
+  55, 0, 0, 23, 45, 0, 7, 3, 63, 0,
+  0, 0, 78, 18, 0, 39, 39, 0, 0, 0,
+  25, 0, 78, 78, 0, 0, 0, 3, 0, 17,
+  3, 41, 11, 0, 0, 0, 16, 61, 36, 0,
+  50, 80, 0, 0, 9, 0, 0, 0, 0, 0,
+  16, 73, 0, 0, 40, 8, 4, 0, 0, 14,
+  31, 0, 0, 0, 18, 0, 26, 0, 2, 0,
+  24, 52, 0, 0, 0, 48, 0, 57, 2, 2,
+  88, 0, 14, 69, 0, 0, 2, 41, 6, 46,
+  1, 15, 0, 0, 48, 46, 0, 40, 32, 26,
+  15, 28, 27, 0, 0, 65, 0, 8, 0, 0,
+  0, 0, 0, 52, 25, 0, 0, 0, 32, 0,
+  0, 39, 0, 43, 11, 0, 0, 0, 70, 0,
+  0, 25, 54, 0, 0, 0, 11, 0, 0, 0,
+  64, 2, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 50, 11, 0,
+  0, 0, 74, 36, 26, 54, 0, 25, 0, 0,
+  19, 41, 32, 80, 62, 25, 0, 0, 0, 42,
+  46, 46, 53, 65, 120, 31, 0, 0, 44, 0,
+  29, 0, 0, 0, 0, 45, 0, 0, 34, 0,
+  9, 14, 37, 0, 0, 29, 26, 40, 42, 29,
+  11, 0, 0, 42, 0, 48, 0, 0, 13, 56,
+  0, 27, 47, 0, 0, 21, 0, 6, 37, 0,
+  32, 21, 1, 6, 34, 0, 57, 25, 7, 31,
+  24, 9, 22, 28, 77, 0, 42, 0, 0, 21,
+  17, 0, 36, 22, 1, 31, 0, 0, 35, 0,
+  70, 0, 6, 12, 44, 44, 51, 12, 23, 0,
+  31, 0, 0, 14, 39, 0, 40, 13, 69, 0,
+  18, 0, 49, 15, 0, 53, 6, 0, 0, 0,
+  108, 18, 35, 62, 0, 10, 0, 0, 14, 70,
+  19, 66, 42, 16, 0, 0, 0, 59, 58, 43,
+  47, 64, 123, 32, 0, 0, 54, 0, 29, 0,
+  0, 0, 9, 45, 0, 0, 26, 16, 0, 23,
+  56, 0, 0, 30, 14, 43, 57, 13, 7, 3,
+  3, 60, 0, 52, 0, 9, 11, 62, 0, 31,
+  41, 10, 20, 3, 0, 13, 31, 0, 45, 36,
+  0, 0, 32, 0, 56, 38, 10, 21, 24, 0,
+  26, 22, 84, 1, 35, 0, 0, 34, 0, 0,
+  6, 15, 19, 40, 0, 0, 26, 0, 74, 0,
+  0, 29, 37, 36, 50, 12, 2, 0, 29, 0,
+  0, 35, 51, 0, 32, 0, 64, 0, 33, 0,
+  43, 1, 0, 47, 0, 0, 0, 0, 99, 35,
+  39, 50, 0, 17, 0, 0, 7, 70, 34, 67,
+  46, 6, 16, 0, 0, 47, 51, 51, 43, 68,
+  129, 40, 9, 0, 53, 0, 19, 0, 0, 3,
+  0, 46, 0, 0, 4, 18, 0, 21, 43, 0,
+  0, 29, 3, 44, 51, 16, 0, 0, 8, 61,
+  0, 57, 0, 8, 10, 70, 0, 30, 41, 15,
+  26, 0, 0, 5, 28, 0, 43, 38, 0, 0,
+  35, 0, 53, 27, 7, 21, 30, 0, 31, 28,
+  62, 0, 36, 0, 0, 42, 1, 0, 11, 10,
+  39, 35, 0, 0, 24, 0, 67, 0, 0, 27,
+  42, 50, 46, 18, 14, 0, 25, 0, 0, 33,
+  56, 0, 33, 24, 74, 0, 21, 0, 46, 9,
+  0, 38, 33, 0, 0, 0, 27, 0, 63, 89,
+  0, 12, 0, 0, 14, 41, 49, 72, 30, 11,
+  0, 0, 0, 57, 37, 23, 43, 98, 0, 0,
+  23, 0, 9, 0, 0, 0, 0, 70, 0, 0,
+  14, 15, 16, 0, 0, 17, 24, 0, 0, 0,
+  12, 0, 48, 0, 0, 0, 0, 33, 0, 3,
+  10, 18, 0, 50, 0, 0, 81, 0, 15, 42,
+  0, 0, 7, 44, 23, 12, 4, 28, 0, 0,
+  63, 33, 2, 27, 31, 25, 2, 25, 25, 0,
+  0, 46, 0, 33, 0, 0, 0, 14, 0, 51,
+  3, 0, 8, 0, 41, 0, 0, 18, 2, 64,
+  10, 19, 0, 0, 55, 0, 0, 23, 45, 0,
+  7, 3, 63, 0, 0, 0, 78, 18, 0, 39,
+  39, 0, 0, 0, 25, 0, 78, 78, 0, 0,
+  0, 3, 0, 17, 3, 41, 11, 0, 0, 0,
+  16, 61, 36, 0, 50, 80, 0, 0, 9, 0,
+  0, 0, 0, 0, 16, 73, 0, 0, 40, 8,
+  4, 0, 0, 14, 31, 0, 0, 0, 18, 0,
+  26, 0, 2, 0, 24, 52, 0, 0, 0, 48,
+  0, 57, 2, 2, 88, 0, 14, 69, 0, 0,
+  2, 41, 6, 46, 1, 15, 0, 0, 48, 46,
+  0, 40, 32, 26, 15, 28, 27, 0, 0, 65,
+  0, 8, 0, 0, 0, 0, 0, 52, 25, 0,
+  0, 0, 32, 0, 0, 39, 0, 43, 11, 0,
+  0, 0, 70, 0, 0, 25, 54, 0, 0, 0,
+  11, 0, 0, 0, 64, 2, 0, 29, 0, 0,
+  0, 0, 15, 0, 80, 38, 0, 0, 0, 0,
+  0, 0, 0, 35, 26, 0, 14, 0, 0, 45,
+  31, 0, 42, 64, 0, 0, 16, 0, 0, 5,
+  0, 0, 32, 60, 1, 0, 52, 0, 0, 0,
+  0, 15, 40, 0, 0, 0, 0, 2, 11, 0,
+  19, 50, 26, 49, 0, 0, 6, 43, 3, 66,
+  19, 0, 76, 0, 18, 84, 0, 0, 2, 19,
+  0, 39, 0, 5, 14, 0, 39, 27, 3, 12,
+  27, 17, 21, 31, 23, 0, 0, 98, 2, 0,
+  0, 0, 0, 0, 39, 39, 30, 37, 0, 0,
+  15, 0, 0, 33, 0, 44, 1, 9, 0, 0,
+  55, 0, 0, 24, 71, 0, 0, 0, 0, 0,
+  0, 0, 42, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 53,
+  6, 0, 0, 0, 108, 18, 35, 62, 0, 10,
+  0, 0, 14, 70, 19, 66, 42, 16, 0, 0,
+  0, 59, 58, 43, 47, 64, 123, 32, 0, 0,
+  54, 0, 29, 0, 0, 0, 9, 45, 0, 0,
+  26, 16, 0, 23, 56, 0, 0, 30, 14, 43,
+  57, 13, 7, 3, 3, 60, 0, 52, 0, 9,
+  11, 62, 0, 31, 41, 10, 20, 3, 0, 13,
+  31, 0, 45, 36, 0, 0, 32, 0, 56, 38,
+  10, 21, 24, 0, 26, 22, 84, 1, 35, 0,
+  0, 34, 0, 0, 6, 15, 19, 40, 0, 0,
+  26, 0, 74, 0, 0, 29, 37, 36, 50, 12,
+  2, 0, 29, 0, 0, 35, 51, 0, 32, 0,
+  64, 0, 33, 0, 43, 1, 0, 47, 0, 0,
+  0, 0, 99, 35, 39, 50, 0, 17, 0, 0,
+  7, 70, 34, 67, 46, 6, 16, 0, 0, 47,
+  51, 51, 43, 68, 129, 40, 9, 0, 53, 0,
+  19, 0, 0, 3, 0, 46, 0, 0, 4, 18,
+  0, 21, 43, 0, 0, 29, 3, 44, 51, 16,
+  0, 0, 8, 61, 0, 57, 0, 8, 10, 70,
+  0, 30, 41, 15, 26, 0, 0, 5, 28, 0,
+  43, 38, 0, 0, 35, 0, 53, 27, 7, 21,
+  30, 0, 31, 28, 62, 0, 36, 0, 0, 42,
+  1, 0, 11, 10, 39, 35, 0, 0, 24, 0,
+  67, 0, 0, 27, 42, 50, 46, 18, 14, 0,
+  25, 0, 0, 33, 56, 0, 33, 24, 74, 0,
+  21, 0, 46, 9, 0, 40, 0, 0, 5, 0,
+  79, 51, 29, 30, 0, 28, 9, 0, 6, 57,
+  44, 75, 60, 18, 9, 0, 0, 32, 53, 70,
+  33, 61, 135, 47, 36, 0, 45, 8, 29, 0,
+  0, 4, 0, 55, 0, 0, 25, 9, 0, 4,
+  34, 0, 0, 18, 21, 51, 44, 48, 0, 10,
+  3, 61, 0, 58, 0, 0, 12, 61, 0, 22,
+  46, 13, 15, 0, 0, 2, 14, 0, 34, 33,
+  0, 3, 31, 0, 57, 9, 0, 22, 46, 0,
+  23, 34, 53, 5, 53, 2, 0, 39, 29, 0,
+  36, 10, 25, 36, 0, 0, 19, 0, 58, 0,
+  0, 20, 53, 51, 44, 24, 38, 2, 31, 0,
+  0, 13, 50, 0, 40, 53, 98, 0, 37, 0,
+  54, 1, 0, 39, 39, 0, 0, 0, 25, 0,
+  78, 78, 0, 0, 0, 3, 0, 17, 3, 41,
+  11, 0, 0, 0, 16, 61, 36, 0, 50, 80,
+  0, 0, 9, 0, 0, 0, 0, 0, 16, 73,
+  0, 0, 40, 8, 4, 0, 0, 14, 31, 0,
+  0, 0, 18, 0, 26, 0, 2, 0, 24, 52,
+  0, 0, 0, 48, 0, 57, 2, 2, 88, 0,
+  14, 69, 0, 0, 2, 41, 6, 46, 1, 15,
+  0, 0, 48, 46, 0, 40, 32, 26, 15, 28,
+  27, 0, 0, 65, 0, 8, 0, 0, 0, 0,
+  0, 52, 25, 0, 0, 0, 32, 0, 0, 39,
+  0, 43, 11, 0, 0, 0, 70, 0, 0, 25,
+  54, 0, 0, 0, 11, 0, 0, 0, 64, 2,
+  0, 29, 0, 0, 0, 0, 15, 0, 80, 38,
+  0, 0, 0, 0, 0, 0, 0, 35, 26, 0,
+  14, 0, 0, 45, 31, 0, 42, 64, 0, 0,
+  16, 0, 0, 5, 0, 0, 32, 60, 1, 0,
+  52, 0, 0, 0, 0, 15, 40, 0, 0, 0,
+  0, 2, 11, 0, 19, 50, 26, 49, 0, 0,
+  6, 43, 3, 66, 19, 0, 76, 0, 18, 84,
+  0, 0, 2, 19, 0, 39, 0, 5, 14, 0,
+  39, 27, 3, 12, 27, 17, 21, 31, 23, 0,
+  0, 98, 2, 0, 0, 0, 0, 0, 39, 39,
+  30, 37, 0, 0, 15, 0, 0, 33, 0, 44,
+  1, 9, 0, 0, 55, 0, 0, 24, 71, 0,
+  0, 0, 0, 0, 0, 0, 42, 0, 0, 21,
+  0, 0, 2, 0, 15, 0, 74, 29, 0, 18,
+  0, 12, 0, 34, 16, 63, 31, 0, 0, 0,
+  0, 43, 15, 0, 18, 55, 0, 0, 44, 0,
+  0, 15, 0, 0, 19, 53, 0, 0, 37, 0,
+  0, 0, 0, 6, 28, 0, 0, 0, 0, 19,
+  26, 0, 3, 71, 33, 50, 0, 0, 10, 18,
+  0, 54, 2, 0, 62, 0, 20, 53, 0, 0,
+  0, 10, 0, 34, 0, 0, 19, 0, 50, 13,
+  6, 0, 30, 11, 7, 22, 34, 0, 0, 109,
+  0, 6, 0, 0, 0, 0, 36, 46, 17, 32,
+  7, 0, 17, 0, 0, 18, 0, 40, 0, 25,
+  0, 9, 51, 0, 0, 9, 68, 0, 0, 9,
+  34, 0, 14, 0, 50, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 47, 0, 0, 0, 0, 99, 35, 39, 50,
+  0, 17, 0, 0, 7, 70, 34, 67, 46, 6,
+  16, 0, 0, 47, 51, 51, 43, 68, 129, 40,
+  9, 0, 53, 0, 19, 0, 0, 3, 0, 46,
+  0, 0, 4, 18, 0, 21, 43, 0, 0, 29,
+  3, 44, 51, 16, 0, 0, 8, 61, 0, 57,
+  0, 8, 10, 70, 0, 30, 41, 15, 26, 0,
+  0, 5, 28, 0, 43, 38, 0, 0, 35, 0,
+  53, 27, 7, 21, 30, 0, 31, 28, 62, 0,
+  36, 0, 0, 42, 1, 0, 11, 10, 39, 35,
+  0, 0, 24, 0, 67, 0, 0, 27, 42, 50,
+  46, 18, 14, 0, 25, 0, 0, 33, 56, 0,
+  33, 24, 74, 0, 21, 0, 46, 9, 0, 40,
+  0, 0, 5, 0, 79, 51, 29, 30, 0, 28,
+  9, 0, 6, 57, 44, 75, 60, 18, 9, 0,
+  0, 32, 53, 70, 33, 61, 135, 47, 36, 0,
+  45, 8, 29, 0, 0, 4, 0, 55, 0, 0,
+  25, 9, 0, 4, 34, 0, 0, 18, 21, 51,
+  44, 48, 0, 10, 3, 61, 0, 58, 0, 0,
+  12, 61, 0, 22, 46, 13, 15, 0, 0, 2,
+  14, 0, 34, 33, 0, 3, 31, 0, 57, 9,
+  0, 22, 46, 0, 23, 34, 53, 5, 53, 2,
+  0, 39, 29, 0, 36, 10, 25, 36, 0, 0,
+  19, 0, 58, 0, 0, 20, 53, 51, 44, 24,
+  38, 2, 31, 0, 0, 13, 50, 0, 40, 53,
+  98, 0, 37, 0, 54, 1, 0, 57, 0, 0,
+  7, 0, 75, 49, 21, 35, 0, 26, 12, 9,
+  20, 56, 23, 65, 41, 43, 0, 0, 0, 51,
+  49, 70, 25, 60, 128, 38, 16, 1, 47, 0,
+  34, 0, 0, 0, 0, 68, 0, 0, 51, 15,
+  10, 0, 33, 0, 0, 22, 41, 66, 39, 66,
+  0, 5, 0, 59, 0, 43, 0, 0, 13, 40,
+  0, 20, 49, 2, 9, 0, 0, 5, 40, 0,
+  43, 31, 0, 19, 43, 2, 80, 35, 0, 14,
+  27, 0, 17, 32, 100, 3, 76, 2, 0, 16,
+  24, 9, 46, 5, 10, 44, 0, 0, 7, 0,
+  65, 0, 4, 31, 54, 32, 37, 0, 31, 0,
+  29, 0, 0, 0, 10, 17, 45, 22, 97, 0,
+  76, 0, 23, 0, 0, 29, 0, 0, 0, 0,
+  15, 0, 80, 38, 0, 0, 0, 0, 0, 0,
+  0, 35, 26, 0, 14, 0, 0, 45, 31, 0,
+  42, 64, 0, 0, 16, 0, 0, 5, 0, 0,
+  32, 60, 1, 0, 52, 0, 0, 0, 0, 15,
+  40, 0, 0, 0, 0, 2, 11, 0, 19, 50,
+  26, 49, 0, 0, 6, 43, 3, 66, 19, 0,
+  76, 0, 18, 84, 0, 0, 2, 19, 0, 39,
+  0, 5, 14, 0, 39, 27, 3, 12, 27, 17,
+  21, 31, 23, 0, 0, 98, 2, 0, 0, 0,
+  0, 0, 39, 39, 30, 37, 0, 0, 15, 0,
+  0, 33, 0, 44, 1, 9, 0, 0, 55, 0,
+  0, 24, 71, 0, 0, 0, 0, 0, 0, 0,
+  42, 0, 0, 21, 0, 0, 2, 0, 15, 0,
+  74, 29, 0, 18, 0, 12, 0, 34, 16, 63,
+  31, 0, 0, 0, 0, 43, 15, 0, 18, 55,
+  0, 0, 44, 0, 0, 15, 0, 0, 19, 53,
+  0, 0, 37, 0, 0, 0, 0, 6, 28, 0,
+  0, 0, 0, 19, 26, 0, 3, 71, 33, 50,
+  0, 0, 10, 18, 0, 54, 2, 0, 62, 0,
+  20, 53, 0, 0, 0, 10, 0, 34, 0, 0,
+  19, 0, 50, 13, 6, 0, 30, 11, 7, 22,
+  34, 0, 0, 109, 0, 6, 0, 0, 0, 0,
+  36, 46, 17, 32, 7, 0, 17, 0, 0, 18,
+  0, 40, 0, 25, 0, 9, 51, 0, 0, 9,
+  68, 0, 0, 9, 34, 0, 14, 0, 50, 0,
+  0, 44, 0, 0, 11, 0, 30, 0, 44, 53,
+  0, 11, 18, 12, 0, 82, 51, 71, 16, 19,
+  0, 0, 0, 63, 28, 37, 0, 67, 2, 0,
+  45, 0, 33, 25, 0, 0, 0, 52, 0, 0,
+  18, 0, 13, 17, 0, 3, 20, 20, 0, 7,
+  2, 12, 49, 14, 0, 32, 19, 44, 0, 21,
+  12, 0, 0, 24, 0, 0, 80, 1, 40, 3,
+  0, 0, 8, 26, 18, 45, 0, 0, 0, 0,
+  87, 25, 0, 0, 27, 11, 0, 26, 28, 6,
+  18, 90, 0, 29, 0, 0, 0, 0, 0, 71,
+  9, 2, 14, 0, 37, 0, 0, 24, 1, 42,
+  0, 27, 0, 6, 32, 0, 0, 6, 43, 0,
+  9, 0, 103, 0, 43, 0, 51, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 40, 0, 0, 5, 0, 79, 51,
+  29, 30, 0, 28, 9, 0, 6, 57, 44, 75,
+  60, 18, 9, 0, 0, 32, 53, 70, 33, 61,
+  135, 47, 36, 0, 45, 8, 29, 0, 0, 4,
+  0, 55, 0, 0, 25, 9, 0, 4, 34, 0,
+  0, 18, 21, 51, 44, 48, 0, 10, 3, 61,
+  0, 58, 0, 0, 12, 61, 0, 22, 46, 13,
+  15, 0, 0, 2, 14, 0, 34, 33, 0, 3,
+  31, 0, 57, 9, 0, 22, 46, 0, 23, 34,
+  53, 5, 53, 2, 0, 39, 29, 0, 36, 10,
+  25, 36, 0, 0, 19, 0, 58, 0, 0, 20,
+  53, 51, 44, 24, 38, 2, 31, 0, 0, 13,
+  50, 0, 40, 53, 98, 0, 37, 0, 54, 1,
+  0, 57, 0, 0, 7, 0, 75, 49, 21, 35,
+  0, 26, 12, 9, 20, 56, 23, 65, 41, 43,
+  0, 0, 0, 51, 49, 70, 25, 60, 128, 38,
+  16, 1, 47, 0, 34, 0, 0, 0, 0, 68,
+  0, 0, 51, 15, 10, 0, 33, 0, 0, 22,
+  41, 66, 39, 66, 0, 5, 0, 59, 0, 43,
+  0, 0, 13, 40, 0, 20, 49, 2, 9, 0,
+  0, 5, 40, 0, 43, 31, 0, 19, 43, 2,
+  80, 35, 0, 14, 27, 0, 17, 32, 100, 3,
+  76, 2, 0, 16, 24, 9, 46, 5, 10, 44,
+  0, 0, 7, 0, 65, 0, 4, 31, 54, 32,
+  37, 0, 31, 0, 29, 0, 0, 0, 10, 17,
+  45, 22, 97, 0, 76, 0, 23, 0, 0, 100,
+  25, 10, 0, 0, 70, 30, 19, 50, 0, 57,
+  14, 13, 11, 54, 10, 51, 32, 74, 0, 0,
+  0, 42, 41, 47, 55, 47, 140, 28, 0, 6,
+  69, 0, 51, 0, 0, 0, 0, 61, 0, 0,
+  55, 28, 10, 25, 39, 0, 0, 40, 29, 63,
+  62, 56, 3, 0, 0, 4, 0, 42, 0, 0,
+  18, 10, 0, 13, 27, 0, 4, 2, 3, 7,
+  57, 0, 55, 33, 0, 39, 43, 0, 86, 34,
+  0, 21, 5, 0, 34, 32, 104, 0, 59, 5,
+  0, 0, 22, 8, 33, 0, 3, 36, 0, 11,
+  27, 0, 66, 0, 37, 39, 34, 16, 38, 0,
+  27, 2, 5, 0, 0, 0, 0, 19, 44, 4,
+  64, 0, 73, 0, 11, 0, 0, 21, 0, 0,
+  2, 0, 15, 0, 74, 29, 0, 18, 0, 12,
+  0, 34, 16, 63, 31, 0, 0, 0, 0, 43,
+  15, 0, 18, 55, 0, 0, 44, 0, 0, 15,
+  0, 0, 19, 53, 0, 0, 37, 0, 0, 0,
+  0, 6, 28, 0, 0, 0, 0, 19, 26, 0,
+  3, 71, 33, 50, 0, 0, 10, 18, 0, 54,
+  2, 0, 62, 0, 20, 53, 0, 0, 0, 10,
+  0, 34, 0, 0, 19, 0, 50, 13, 6, 0,
+  30, 11, 7, 22, 34, 0, 0, 109, 0, 6,
+  0, 0, 0, 0, 36, 46, 17, 32, 7, 0,
+  17, 0, 0, 18, 0, 40, 0, 25, 0, 9,
+  51, 0, 0, 9, 68, 0, 0, 9, 34, 0,
+  14, 0, 50, 0, 0, 44, 0, 0, 11, 0,
+  30, 0, 44, 53, 0, 11, 18, 12, 0, 82,
+  51, 71, 16, 19, 0, 0, 0, 63, 28, 37,
+  0, 67, 2, 0, 45, 0, 33, 25, 0, 0,
+  0, 52, 0, 0, 18, 0, 13, 17, 0, 3,
+  20, 20, 0, 7, 2, 12, 49, 14, 0, 32,
+  19, 44, 0, 21, 12, 0, 0, 24, 0, 0,
+  80, 1, 40, 3, 0, 0, 8, 26, 18, 45,
+  0, 0, 0, 0, 87, 25, 0, 0, 27, 11,
+  0, 26, 28, 6, 18, 90, 0, 29, 0, 0,
+  0, 0, 0, 71, 9, 2, 14, 0, 37, 0,
+  0, 24, 1, 42, 0, 27, 0, 6, 32, 0,
+  0, 6, 43, 0, 9, 0, 103, 0, 43, 0,
+  51, 0, 0, 102, 14, 0, 4, 0, 39, 0,
+  27, 51, 8, 13, 23, 3, 26, 91, 67, 61,
+  21, 56, 0, 0, 0, 56, 53, 69, 6, 74,
+  0, 0, 14, 0, 81, 1, 0, 0, 0, 25,
+  0, 38, 0, 16, 42, 22, 1, 7, 22, 19,
+  0, 49, 2, 1, 68, 52, 0, 0, 0, 9,
+  0, 50, 0, 0, 0, 0, 0, 0, 91, 11,
+  34, 0, 0, 0, 15, 26, 42, 23, 0, 6,
+  0, 4, 107, 11, 0, 0, 11, 8, 10, 15,
+  30, 12, 42, 45, 0, 41, 0, 10, 0, 0,
+  0, 81, 0, 0, 14, 0, 46, 0, 23, 15,
+  32, 37, 0, 0, 0, 0, 0, 0, 0, 0,
+  12, 0, 30, 11, 149, 0, 76, 0, 46, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 57, 0, 0, 7, 0,
+  75, 49, 21, 35, 0, 26, 12, 9, 20, 56,
+  23, 65, 41, 43, 0, 0, 0, 51, 49, 70,
+  25, 60, 128, 38, 16, 1, 47, 0, 34, 0,
+  0, 0, 0, 68, 0, 0, 51, 15, 10, 0,
+  33, 0, 0, 22, 41, 66, 39, 66, 0, 5,
+  0, 59, 0, 43, 0, 0, 13, 40, 0, 20,
+  49, 2, 9, 0, 0, 5, 40, 0, 43, 31,
+  0, 19, 43, 2, 80, 35, 0, 14, 27, 0,
+  17, 32, 100, 3, 76, 2, 0, 16, 24, 9,
+  46, 5, 10, 44, 0, 0, 7, 0, 65, 0,
+  4, 31, 54, 32, 37, 0, 31, 0, 29, 0,
+  0, 0, 10, 17, 45, 22, 97, 0, 76, 0,
+  23, 0, 0, 100, 25, 10, 0, 0, 70, 30,
+  19, 50, 0, 57, 14, 13, 11, 54, 10, 51,
+  32, 74, 0, 0, 0, 42, 41, 47, 55, 47,
+  140, 28, 0, 6, 69, 0, 51, 0, 0, 0,
+  0, 61, 0, 0, 55, 28, 10, 25, 39, 0,
+  0, 40, 29, 63, 62, 56, 3, 0, 0, 4,
+  0, 42, 0, 0, 18, 10, 0, 13, 27, 0,
+  4, 2, 3, 7, 57, 0, 55, 33, 0, 39,
+  43, 0, 86, 34, 0, 21, 5, 0, 34, 32,
+  104, 0, 59, 5, 0, 0, 22, 8, 33, 0,
+  3, 36, 0, 11, 27, 0, 66, 0, 37, 39,
+  34, 16, 38, 0, 27, 2, 5, 0, 0, 0,
+  0, 19, 44, 4, 64, 0, 73, 0, 11, 0,
+  0, 123, 31, 8, 0, 0, 58, 2, 5, 19,
+  0, 61, 49, 0, 0, 22, 6, 34, 22, 59,
+  0, 0, 47, 46, 38, 9, 61, 16, 179, 16,
+  0, 0, 76, 0, 51, 37, 0, 0, 40, 47,
+  0, 0, 71, 33, 17, 78, 26, 17, 0, 47,
+  0, 63, 77, 0, 7, 0, 7, 0, 0, 10,
+  13, 30, 0, 26, 0, 3, 14, 0, 1, 0,
+  72, 10, 34, 0, 44, 21, 8, 54, 16, 0,
+  64, 0, 25, 21, 0, 5, 39, 21, 53, 0,
+  0, 0, 23, 0, 9, 12, 0, 0, 0, 25,
+  0, 51, 27, 5, 41, 0, 55, 0, 0, 34,
+  30, 0, 0, 7, 0, 0, 0, 10, 31, 34,
+  58, 5, 0, 0, 20, 0, 0, 0, 0, 44,
+  0, 0, 11, 0, 30, 0, 44, 53, 0, 11,
+  18, 12, 0, 82, 51, 71, 16, 19, 0, 0,
+  0, 63, 28, 37, 0, 67, 2, 0, 45, 0,
+  33, 25, 0, 0, 0, 52, 0, 0, 18, 0,
+  13, 17, 0, 3, 20, 20, 0, 7, 2, 12,
+  49, 14, 0, 32, 19, 44, 0, 21, 12, 0,
+  0, 24, 0, 0, 80, 1, 40, 3, 0, 0,
+  8, 26, 18, 45, 0, 0, 0, 0, 87, 25,
+  0, 0, 27, 11, 0, 26, 28, 6, 18, 90,
+  0, 29, 0, 0, 0, 0, 0, 71, 9, 2,
+  14, 0, 37, 0, 0, 24, 1, 42, 0, 27,
+  0, 6, 32, 0, 0, 6, 43, 0, 9, 0,
+  103, 0, 43, 0, 51, 0, 0, 102, 14, 0,
+  4, 0, 39, 0, 27, 51, 8, 13, 23, 3,
+  26, 91, 67, 61, 21, 56, 0, 0, 0, 56,
+  53, 69, 6, 74, 0, 0, 14, 0, 81, 1,
+  0, 0, 0, 25, 0, 38, 0, 16, 42, 22,
+  1, 7, 22, 19, 0, 49, 2, 1, 68, 52,
+  0, 0, 0, 9, 0, 50, 0, 0, 0, 0,
+  0, 0, 91, 11, 34, 0, 0, 0, 15, 26,
+  42, 23, 0, 6, 0, 4, 107, 11, 0, 0,
+  11, 8, 10, 15, 30, 12, 42, 45, 0, 41,
+  0, 10, 0, 0, 0, 81, 0, 0, 14, 0,
+  46, 0, 23, 15, 32, 37, 0, 0, 0, 0,
+  0, 0, 0, 0, 12, 0, 30, 11, 149, 0,
+  76, 0, 46, 0, 0, 131, 52, 5, 17, 0,
+  45, 0, 11, 44, 5, 23, 60, 0, 17, 55,
+  55, 49, 15, 72, 0, 0, 12, 32, 54, 53,
+  11, 54, 0, 20, 0, 0, 76, 0, 17, 0,
+  0, 0, 0, 41, 0, 25, 68, 41, 28, 22,
+  40, 0, 0, 52, 0, 3, 85, 24, 0, 0,
+  0, 0, 0, 44, 4, 0, 0, 5, 0, 0,
+  29, 13, 13, 0, 0, 0, 8, 16, 74, 5,
+  15, 32, 0, 0, 97, 0, 0, 0, 14, 0,
+  30, 16, 22, 9, 0, 0, 0, 20, 0, 26,
+  0, 0, 0, 38, 5, 16, 9, 0, 39, 0,
+  48, 8, 25, 53, 0, 0, 0, 5, 0, 0,
+  0, 24, 33, 0, 34, 5, 77, 0, 62, 0,
+  29, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 100, 25, 10,
+  0, 0, 70, 30, 19, 50, 0, 57, 14, 13,
+  11, 54, 10, 51, 32, 74, 0, 0, 0, 42,
+  41, 47, 55, 47, 140, 28, 0, 6, 69, 0,
+  51, 0, 0, 0, 0, 61, 0, 0, 55, 28,
+  10, 25, 39, 0, 0, 40, 29, 63, 62, 56,
+  3, 0, 0, 4, 0, 42, 0, 0, 18, 10,
+  0, 13, 27, 0, 4, 2, 3, 7, 57, 0,
+  55, 33, 0, 39, 43, 0, 86, 34, 0, 21,
+  5, 0, 34, 32, 104, 0, 59, 5, 0, 0,
+  22, 8, 33, 0, 3, 36, 0, 11, 27, 0,
+  66, 0, 37, 39, 34, 16, 38, 0, 27, 2,
+  5, 0, 0, 0, 0, 19, 44, 4, 64, 0,
+  73, 0, 11, 0, 0, 123, 31, 8, 0, 0,
+  58, 2, 5, 19, 0, 61, 49, 0, 0, 22,
+  6, 34, 22, 59, 0, 0, 47, 46, 38, 9,
+  61, 16, 179, 16, 0, 0, 76, 0, 51, 37,
+  0, 0, 40, 47, 0, 0, 71, 33, 17, 78,
+  26, 17, 0, 47, 0, 63, 77, 0, 7, 0,
+  7, 0, 0, 10, 13, 30, 0, 26, 0, 3,
+  14, 0, 1, 0, 72, 10, 34, 0, 44, 21,
+  8, 54, 16, 0, 64, 0, 25, 21, 0, 5,
+  39, 21, 53, 0, 0, 0, 23, 0, 9, 12,
+  0, 0, 0, 25, 0, 51, 27, 5, 41, 0,
+  55, 0, 0, 34, 30, 0, 0, 7, 0, 0,
+  0, 10, 31, 34, 58, 5, 0, 0, 20, 0,
+  0, 0, 5, 63, 0, 6, 0, 6, 70, 9,
+  0, 0, 0, 80, 68, 0, 0, 0, 4, 24,
+  17, 28, 10, 34, 89, 45, 45, 0, 53, 4,
+  206, 0, 0, 11, 57, 5, 17, 54, 0, 0,
+  60, 39, 0, 0, 1, 61, 12, 128, 21, 26,
+  0, 14, 0, 73, 56, 0, 20, 6, 28, 0,
+  28, 0, 56, 44, 0, 46, 15, 2, 13, 32,
+  46, 0, 134, 11, 24, 0, 54, 0, 56, 54,
+  12, 0, 36, 0, 34, 0, 0, 7, 35, 1,
+  23, 0, 0, 0, 35, 0, 0, 29, 0, 0,
+  59, 43, 6, 53, 7, 33, 53, 18, 22, 0,
+  0, 36, 0, 23, 0, 10, 0, 29, 0, 20,
+  61, 20, 68, 0, 0, 0, 0, 0, 0, 0,
+  0, 102, 14, 0, 4, 0, 39, 0, 27, 51,
+  8, 13, 23, 3, 26, 91, 67, 61, 21, 56,
+  0, 0, 0, 56, 53, 69, 6, 74, 0, 0,
+  14, 0, 81, 1, 0, 0, 0, 25, 0, 38,
+  0, 16, 42, 22, 1, 7, 22, 19, 0, 49,
+  2, 1, 68, 52, 0, 0, 0, 9, 0, 50,
+  0, 0, 0, 0, 0, 0, 91, 11, 34, 0,
+  0, 0, 15, 26, 42, 23, 0, 6, 0, 4,
+  107, 11, 0, 0, 11, 8, 10, 15, 30, 12,
+  42, 45, 0, 41, 0, 10, 0, 0, 0, 81,
+  0, 0, 14, 0, 46, 0, 23, 15, 32, 37,
+  0, 0, 0, 0, 0, 0, 0, 0, 12, 0,
+  30, 11, 149, 0, 76, 0, 46, 0, 0, 131,
+  52, 5, 17, 0, 45, 0, 11, 44, 5, 23,
+  60, 0, 17, 55, 55, 49, 15, 72, 0, 0,
+  12, 32, 54, 53, 11, 54, 0, 20, 0, 0,
+  76, 0, 17, 0, 0, 0, 0, 41, 0, 25,
+  68, 41, 28, 22, 40, 0, 0, 52, 0, 3,
+  85, 24, 0, 0, 0, 0, 0, 44, 4, 0,
+  0, 5, 0, 0, 29, 13, 13, 0, 0, 0,
+  8, 16, 74, 5, 15, 32, 0, 0, 97, 0,
+  0, 0, 14, 0, 30, 16, 22, 9, 0, 0,
+  0, 20, 0, 26, 0, 0, 0, 38, 5, 16,
+  9, 0, 39, 0, 48, 8, 25, 53, 0, 0,
+  0, 5, 0, 0, 0, 24, 33, 0, 34, 5,
+  77, 0, 62, 0, 29, 0, 0, 75, 0, 0,
+  5, 14, 48, 1, 0, 0, 0, 56, 51, 0,
+  0, 4, 32, 10, 13, 41, 0, 10, 71, 13,
+  29, 0, 10, 14, 0, 17, 0, 0, 42, 0,
+  5, 27, 0, 0, 9, 20, 0, 26, 0, 66,
+  11, 74, 35, 26, 0, 2, 0, 16, 68, 0,
+  0, 0, 30, 0, 1, 5, 28, 45, 0, 49,
+  0, 0, 0, 37, 29, 0, 51, 0, 22, 9,
+  83, 12, 47, 23, 0, 0, 69, 0, 4, 0,
+  38, 0, 23, 2, 0, 0, 0, 0, 0, 6,
+  0, 38, 0, 0, 22, 49, 15, 29, 19, 13,
+  22, 0, 31, 11, 0, 28, 0, 0, 0, 0,
+  0, 0, 0, 19, 71, 6, 22, 4, 0, 0,
+  22, 0, 10, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 123,
+  31, 8, 0, 0, 58, 2, 5, 19, 0, 61,
+  49, 0, 0, 22, 6, 34, 22, 59, 0, 0,
+  47, 46, 38, 9, 61, 16, 179, 16, 0, 0,
+  76, 0, 51, 37, 0, 0, 40, 47, 0, 0,
+  71, 33, 17, 78, 26, 17, 0, 47, 0, 63,
+  77, 0, 7, 0, 7, 0, 0, 10, 13, 30,
+  0, 26, 0, 3, 14, 0, 1, 0, 72, 10,
+  34, 0, 44, 21, 8, 54, 16, 0, 64, 0,
+  25, 21, 0, 5, 39, 21, 53, 0, 0, 0,
+  23, 0, 9, 12, 0, 0, 0, 25, 0, 51,
+  27, 5, 41, 0, 55, 0, 0, 34, 30, 0,
+  0, 7, 0, 0, 0, 10, 31, 34, 58, 5,
+  0, 0, 20, 0, 0, 0, 5, 63, 0, 6,
+  0, 6, 70, 9, 0, 0, 0, 80, 68, 0,
+  0, 0, 4, 24, 17, 28, 10, 34, 89, 45,
+  45, 0, 53, 4, 206, 0, 0, 11, 57, 5,
+  17, 54, 0, 0, 60, 39, 0, 0, 1, 61,
+  12, 128, 21, 26, 0, 14, 0, 73, 56, 0,
+  20, 6, 28, 0, 28, 0, 56, 44, 0, 46,
+  15, 2, 13, 32, 46, 0, 134, 11, 24, 0,
+  54, 0, 56, 54, 12, 0, 36, 0, 34, 0,
+  0, 7, 35, 1, 23, 0, 0, 0, 35, 0,
+  0, 29, 0, 0, 59, 43, 6, 53, 7, 33,
+  53, 18, 22, 0, 0, 36, 0, 23, 0, 10,
+  0, 29, 0, 20, 61, 20, 68, 0, 0, 0,
+  0, 0, 0, 0, 23, 19, 0, 34, 10, 9,
+  83, 40, 0, 0, 0, 24, 57, 8, 0, 49,
+  29, 55, 14, 27, 77, 6, 23, 33, 54, 0,
+  58, 20, 192, 4, 0, 22, 109, 15, 46, 0,
+  0, 37, 38, 5, 0, 0, 0, 70, 41, 137,
+  1, 46, 0, 13, 0, 79, 54, 2, 11, 54,
+  16, 0, 0, 0, 37, 0, 13, 6, 0, 0,
+  18, 17, 31, 11, 84, 0, 5, 0, 13, 0,
+  66, 45, 13, 0, 58, 0, 30, 0, 0, 0,
+  28, 0, 31, 38, 0, 18, 0, 18, 32, 25,
+  25, 0, 48, 37, 18, 2, 0, 55, 81, 0,
+  12, 13, 23, 14, 0, 32, 10, 37, 0, 0,
+  29, 0, 19, 21, 86, 0, 13, 0, 0, 0,
+  37, 12, 0, 131, 52, 5, 17, 0, 45, 0,
+  11, 44, 5, 23, 60, 0, 17, 55, 55, 49,
+  15, 72, 0, 0, 12, 32, 54, 53, 11, 54,
+  0, 20, 0, 0, 76, 0, 17, 0, 0, 0,
+  0, 41, 0, 25, 68, 41, 28, 22, 40, 0,
+  0, 52, 0, 3, 85, 24, 0, 0, 0, 0,
+  0, 44, 4, 0, 0, 5, 0, 0, 29, 13,
+  13, 0, 0, 0, 8, 16, 74, 5, 15, 32,
+  0, 0, 97, 0, 0, 0, 14, 0, 30, 16,
+  22, 9, 0, 0, 0, 20, 0, 26, 0, 0,
+  0, 38, 5, 16, 9, 0, 39, 0, 48, 8,
+  25, 53, 0, 0, 0, 5, 0, 0, 0, 24,
+  33, 0, 34, 5, 77, 0, 62, 0, 29, 0,
+  0, 75, 0, 0, 5, 14, 48, 1, 0, 0,
+  0, 56, 51, 0, 0, 4, 32, 10, 13, 41,
+  0, 10, 71, 13, 29, 0, 10, 14, 0, 17,
+  0, 0, 42, 0, 5, 27, 0, 0, 9, 20,
+  0, 26, 0, 66, 11, 74, 35, 26, 0, 2,
+  0, 16, 68, 0, 0, 0, 30, 0, 1, 5,
+  28, 45, 0, 49, 0, 0, 0, 37, 29, 0,
+  51, 0, 22, 9, 83, 12, 47, 23, 0, 0,
+  69, 0, 4, 0, 38, 0, 23, 2, 0, 0,
+  0, 0, 0, 6, 0, 38, 0, 0, 22, 49,
+  15, 29, 19, 13, 22, 0, 31, 11, 0, 28,
+  0, 0, 0, 0, 0, 0, 0, 19, 71, 6,
+  22, 4, 0, 0, 22, 0, 10, 0, 7, 18,
+  0, 16, 0, 21, 57, 17, 0, 0, 0, 41,
+  57, 2, 0, 6, 60, 44, 5, 5, 45, 0,
+  15, 0, 37, 0, 27, 0, 0, 35, 0, 0,
+  85, 0, 0, 0, 0, 5, 0, 0, 0, 23,
+  0, 64, 4, 113, 25, 79, 0, 0, 0, 41,
+  66, 0, 0, 22, 11, 0, 0, 0, 15, 0,
+  0, 2, 0, 0, 0, 36, 38, 0, 60, 0,
+  2, 0, 50, 0, 47, 0, 0, 0, 62, 0,
+  47, 0, 7, 0, 20, 0, 0, 8, 0, 4,
+  0, 8, 0, 7, 0, 0, 51, 44, 26, 26,
+  0, 37, 18, 0, 29, 6, 9, 13, 0, 18,
+  0, 17, 0, 0, 6, 0, 36, 0, 37, 0,
+  37, 0, 0, 0, 38, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  5, 63, 0, 6, 0, 6, 70, 9, 0, 0,
+  0, 80, 68, 0, 0, 0, 4, 24, 17, 28,
+  10, 34, 89, 45, 45, 0, 53, 4, 206, 0,
+  0, 11, 57, 5, 17, 54, 0, 0, 60, 39,
+  0, 0, 1, 61, 12, 128, 21, 26, 0, 14,
+  0, 73, 56, 0, 20, 6, 28, 0, 28, 0,
+  56, 44, 0, 46, 15, 2, 13, 32, 46, 0,
+  134, 11, 24, 0, 54, 0, 56, 54, 12, 0,
+  36, 0, 34, 0, 0, 7, 35, 1, 23, 0,
+  0, 0, 35, 0, 0, 29, 0, 0, 59, 43,
+  6, 53, 7, 33, 53, 18, 22, 0, 0, 36,
+  0, 23, 0, 10, 0, 29, 0, 20, 61, 20,
+  68, 0, 0, 0, 0, 0, 0, 0, 23, 19,
+  0, 34, 10, 9, 83, 40, 0, 0, 0, 24,
+  57, 8, 0, 49, 29, 55, 14, 27, 77, 6,
+  23, 33, 54, 0, 58, 20, 192, 4, 0, 22,
+  109, 15, 46, 0, 0, 37, 38, 5, 0, 0,
+  0, 70, 41, 137, 1, 46, 0, 13, 0, 79,
+  54, 2, 11, 54, 16, 0, 0, 0, 37, 0,
+  13, 6, 0, 0, 18, 17, 31, 11, 84, 0,
+  5, 0, 13, 0, 66, 45, 13, 0, 58, 0,
+  30, 0, 0, 0, 28, 0, 31, 38, 0, 18,
+  0, 18, 32, 25, 25, 0, 48, 37, 18, 2,
+  0, 55, 81, 0, 12, 13, 23, 14, 0, 32,
+  10, 37, 0, 0, 29, 0, 19, 21, 86, 0,
+  13, 0, 0, 0, 37, 12, 0, 33, 0, 8,
+  0, 0, 88, 51, 0, 25, 4, 29, 23, 1,
+  15, 91, 42, 50, 0, 22, 30, 0, 0, 49,
+  47, 30, 47, 45, 143, 63, 23, 6, 105, 25,
+  47, 0, 0, 39, 4, 30, 0, 3, 39, 25,
+  43, 65, 2, 47, 0, 56, 16, 77, 68, 39,
+  2, 24, 5, 0, 0, 43, 0, 0, 0, 26,
+  0, 4, 28, 0, 0, 0, 1, 21, 0, 0,
+  4, 46, 30, 14, 4, 0, 94, 0, 0, 19,
+  0, 0, 9, 3, 54, 33, 28, 12, 0, 25,
+  28, 16, 54, 0, 16, 44, 0, 0, 10, 24,
+  96, 0, 13, 21, 39, 36, 23, 10, 46, 34,
+  8, 0, 13, 0, 3, 31, 63, 19, 94, 0,
+  15, 0, 17, 0, 0, 75, 0, 0, 5, 14,
+  48, 1, 0, 0, 0, 56, 51, 0, 0, 4,
+  32, 10, 13, 41, 0, 10, 71, 13, 29, 0,
+  10, 14, 0, 17, 0, 0, 42, 0, 5, 27,
+  0, 0, 9, 20, 0, 26, 0, 66, 11, 74,
+  35, 26, 0, 2, 0, 16, 68, 0, 0, 0,
+  30, 0, 1, 5, 28, 45, 0, 49, 0, 0,
+  0, 37, 29, 0, 51, 0, 22, 9, 83, 12,
+  47, 23, 0, 0, 69, 0, 4, 0, 38, 0,
+  23, 2, 0, 0, 0, 0, 0, 6, 0, 38,
+  0, 0, 22, 49, 15, 29, 19, 13, 22, 0,
+  31, 11, 0, 28, 0, 0, 0, 0, 0, 0,
+  0, 19, 71, 6, 22, 4, 0, 0, 22, 0,
+  10, 0, 7, 18, 0, 16, 0, 21, 57, 17,
+  0, 0, 0, 41, 57, 2, 0, 6, 60, 44,
+  5, 5, 45, 0, 15, 0, 37, 0, 27, 0,
+  0, 35, 0, 0, 85, 0, 0, 0, 0, 5,
+  0, 0, 0, 23, 0, 64, 4, 113, 25, 79,
+  0, 0, 0, 41, 66, 0, 0, 22, 11, 0,
+  0, 0, 15, 0, 0, 2, 0, 0, 0, 36,
+  38, 0, 60, 0, 2, 0, 50, 0, 47, 0,
+  0, 0, 62, 0, 47, 0, 7, 0, 20, 0,
+  0, 8, 0, 4, 0, 8, 0, 7, 0, 0,
+  51, 44, 26, 26, 0, 37, 18, 0, 29, 6,
+  9, 13, 0, 18, 0, 17, 0, 0, 6, 0,
+  36, 0, 37, 0, 37, 0, 0, 0, 38, 0,
+  0, 12, 0, 42, 6, 15, 37, 28, 4, 4,
+  6, 14, 22, 0, 5, 59, 66, 39, 0, 24,
+  0, 0, 0, 20, 47, 15, 29, 33, 0, 35,
+  0, 0, 91, 34, 6, 0, 0, 11, 0, 10,
+  0, 18, 0, 22, 0, 58, 46, 78, 0, 43,
+  0, 62, 86, 46, 0, 56, 0, 0, 0, 20,
+  4, 0, 0, 0, 0, 0, 39, 0, 35, 6,
+  23, 0, 0, 0, 28, 23, 8, 0, 0, 0,
+  113, 0, 11, 9, 0, 0, 7, 22, 0, 0,
+  22, 29, 0, 8, 36, 0, 36, 0, 26, 59,
+  19, 7, 14, 19, 16, 0, 26, 17, 35, 32,
+  0, 9, 19, 42, 0, 0, 5, 0, 0, 0,
+  14, 11, 125, 0, 35, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 23, 19, 0, 34, 10, 9, 83, 40,
+  0, 0, 0, 24, 57, 8, 0, 49, 29, 55,
+  14, 27, 77, 6, 23, 33, 54, 0, 58, 20,
+  192, 4, 0, 22, 109, 15, 46, 0, 0, 37,
+  38, 5, 0, 0, 0, 70, 41, 137, 1, 46,
+  0, 13, 0, 79, 54, 2, 11, 54, 16, 0,
+  0, 0, 37, 0, 13, 6, 0, 0, 18, 17,
+  31, 11, 84, 0, 5, 0, 13, 0, 66, 45,
+  13, 0, 58, 0, 30, 0, 0, 0, 28, 0,
+  31, 38, 0, 18, 0, 18, 32, 25, 25, 0,
+  48, 37, 18, 2, 0, 55, 81, 0, 12, 13,
+  23, 14, 0, 32, 10, 37, 0, 0, 29, 0,
+  19, 21, 86, 0, 13, 0, 0, 0, 37, 12,
+  0, 33, 0, 8, 0, 0, 88, 51, 0, 25,
+  4, 29, 23, 1, 15, 91, 42, 50, 0, 22,
+  30, 0, 0, 49, 47, 30, 47, 45, 143, 63,
+  23, 6, 105, 25, 47, 0, 0, 39, 4, 30,
+  0, 3, 39, 25, 43, 65, 2, 47, 0, 56,
+  16, 77, 68, 39, 2, 24, 5, 0, 0, 43,
+  0, 0, 0, 26, 0, 4, 28, 0, 0, 0,
+  1, 21, 0, 0, 4, 46, 30, 14, 4, 0,
+  94, 0, 0, 19, 0, 0, 9, 3, 54, 33,
+  28, 12, 0, 25, 28, 16, 54, 0, 16, 44,
+  0, 0, 10, 24, 96, 0, 13, 21, 39, 36,
+  23, 10, 46, 34, 8, 0, 13, 0, 3, 31,
+  63, 19, 94, 0, 15, 0, 17, 0, 0, 98,
+  1, 0, 0, 0, 70, 26, 1, 40, 0, 18,
+  8, 0, 0, 55, 20, 56, 0, 28, 0, 0,
+  9, 77, 37, 43, 56, 51, 165, 33, 18, 0,
+  85, 0, 49, 0, 0, 7, 13, 31, 0, 0,
+  65, 0, 42, 42, 0, 0, 0, 51, 14, 68,
+  75, 5, 23, 0, 0, 0, 0, 38, 0, 3,
+  1, 24, 0, 20, 44, 0, 0, 18, 0, 29,
+  38, 5, 30, 64, 3, 48, 31, 0, 73, 0,
+  0, 22, 0, 9, 14, 16, 72, 24, 54, 0,
+  0, 3, 10, 1, 31, 0, 4, 29, 0, 13,
+  27, 0, 87, 0, 38, 9, 40, 53, 46, 4,
+  16, 15, 5, 0, 5, 0, 11, 52, 56, 10,
+  49, 0, 36, 0, 7, 0, 7, 18, 0, 16,
+  0, 21, 57, 17, 0, 0, 0, 41, 57, 2,
+  0, 6, 60, 44, 5, 5, 45, 0, 15, 0,
+  37, 0, 27, 0, 0, 35, 0, 0, 85, 0,
+  0, 0, 0, 5, 0, 0, 0, 23, 0, 64,
+  4, 113, 25, 79, 0, 0, 0, 41, 66, 0,
+  0, 22, 11, 0, 0, 0, 15, 0, 0, 2,
+  0, 0, 0, 36, 38, 0, 60, 0, 2, 0,
+  50, 0, 47, 0, 0, 0, 62, 0, 47, 0,
+  7, 0, 20, 0, 0, 8, 0, 4, 0, 8,
+  0, 7, 0, 0, 51, 44, 26, 26, 0, 37,
+  18, 0, 29, 6, 9, 13, 0, 18, 0, 17,
+  0, 0, 6, 0, 36, 0, 37, 0, 37, 0,
+  0, 0, 38, 0, 0, 12, 0, 42, 6, 15,
+  37, 28, 4, 4, 6, 14, 22, 0, 5, 59,
+  66, 39, 0, 24, 0, 0, 0, 20, 47, 15,
+  29, 33, 0, 35, 0, 0, 91, 34, 6, 0,
+  0, 11, 0, 10, 0, 18, 0, 22, 0, 58,
+  46, 78, 0, 43, 0, 62, 86, 46, 0, 56,
+  0, 0, 0, 20, 4, 0, 0, 0, 0, 0,
+  39, 0, 35, 6, 23, 0, 0, 0, 28, 23,
+  8, 0, 0, 0, 113, 0, 11, 9, 0, 0,
+  7, 22, 0, 0, 22, 29, 0, 8, 36, 0,
+  36, 0, 26, 59, 19, 7, 14, 19, 16, 0,
+  26, 17, 35, 32, 0, 9, 19, 42, 0, 0,
+  5, 0, 0, 0, 14, 11, 125, 0, 35, 0,
+  0, 0, 0, 93, 5, 24, 14, 0, 37, 16,
+  19, 24, 15, 1, 7, 0, 45, 74, 66, 43,
+  0, 20, 0, 0, 0, 49, 65, 69, 6, 62,
+  0, 1, 5, 0, 69, 27, 8, 0, 0, 8,
+  0, 34, 0, 35, 41, 0, 16, 0, 40, 0,
+  0, 56, 0, 37, 99, 45, 0, 4, 0, 17,
+  0, 45, 12, 0, 0, 33, 0, 12, 78, 0,
+  23, 0, 0, 0, 0, 6, 46, 35, 1, 18,
+  0, 2, 119, 0, 0, 1, 0, 16, 0, 27,
+  17, 29, 59, 0, 0, 26, 0, 8, 27, 0,
+  0, 42, 0, 0, 29, 0, 16, 0, 32, 10,
+  52, 56, 0, 0, 9, 11, 0, 0, 0, 0,
+  0, 0, 4, 23, 137, 0, 66, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 33, 0, 8, 0, 0,
+  88, 51, 0, 25, 4, 29, 23, 1, 15, 91,
+  42, 50, 0, 22, 30, 0, 0, 49, 47, 30,
+  47, 45, 143, 63, 23, 6, 105, 25, 47, 0,
+  0, 39, 4, 30, 0, 3, 39, 25, 43, 65,
+  2, 47, 0, 56, 16, 77, 68, 39, 2, 24,
+  5, 0, 0, 43, 0, 0, 0, 26, 0, 4,
+  28, 0, 0, 0, 1, 21, 0, 0, 4, 46,
+  30, 14, 4, 0, 94, 0, 0, 19, 0, 0,
+  9, 3, 54, 33, 28, 12, 0, 25, 28, 16,
+  54, 0, 16, 44, 0, 0, 10, 24, 96, 0,
+  13, 21, 39, 36, 23, 10, 46, 34, 8, 0,
+  13, 0, 3, 31, 63, 19, 94, 0, 15, 0,
+  17, 0, 0, 98, 1, 0, 0, 0, 70, 26,
+  1, 40, 0, 18, 8, 0, 0, 55, 20, 56,
+  0, 28, 0, 0, 9, 77, 37, 43, 56, 51,
+  165, 33, 18, 0, 85, 0, 49, 0, 0, 7,
+  13, 31, 0, 0, 65, 0, 42, 42, 0, 0,
+  0, 51, 14, 68, 75, 5, 23, 0, 0, 0,
+  0, 38, 0, 3, 1, 24, 0, 20, 44, 0,
+  0, 18, 0, 29, 38, 5, 30, 64, 3, 48,
+  31, 0, 73, 0, 0, 22, 0, 9, 14, 16,
+  72, 24, 54, 0, 0, 3, 10, 1, 31, 0,
+  4, 29, 0, 13, 27, 0, 87, 0, 38, 9,
+  40, 53, 46, 4, 16, 15, 5, 0, 5, 0,
+  11, 52, 56, 10, 49, 0, 36, 0, 7, 0,
+  21, 87, 0, 17, 0, 0, 7, 0, 27, 18,
+  0, 30, 39, 0, 0, 11, 9, 43, 15, 26,
+  0, 36, 93, 68, 12, 0, 68, 46, 209, 0,
+  0, 0, 54, 0, 48, 43, 0, 0, 65, 3,
+  0, 0, 39, 14, 18, 96, 0, 0, 0, 10,
+  0, 107, 61, 0, 69, 0, 19, 0, 17, 0,
+  20, 40, 0, 0, 35, 25, 0, 0, 0, 58,
+  134, 10, 46, 0, 8, 33, 3, 95, 34, 0,
+  24, 0, 8, 20, 0, 5, 21, 22, 59, 0,
+  30, 0, 0, 0, 54, 0, 27, 0, 10, 43,
+  26, 72, 29, 15, 69, 18, 47, 0, 13, 38,
+  8, 8, 0, 1, 0, 0, 3, 0, 8, 49,
+  53, 0, 0, 0, 36, 0, 0, 0, 0, 12,
+  0, 42, 6, 15, 37, 28, 4, 4, 6, 14,
+  22, 0, 5, 59, 66, 39, 0, 24, 0, 0,
+  0, 20, 47, 15, 29, 33, 0, 35, 0, 0,
+  91, 34, 6, 0, 0, 11, 0, 10, 0, 18,
+  0, 22, 0, 58, 46, 78, 0, 43, 0, 62,
+  86, 46, 0, 56, 0, 0, 0, 20, 4, 0,
+  0, 0, 0, 0, 39, 0, 35, 6, 23, 0,
+  0, 0, 28, 23, 8, 0, 0, 0, 113, 0,
+  11, 9, 0, 0, 7, 22, 0, 0, 22, 29,
+  0, 8, 36, 0, 36, 0, 26, 59, 19, 7,
+  14, 19, 16, 0, 26, 17, 35, 32, 0, 9,
+  19, 42, 0, 0, 5, 0, 0, 0, 14, 11,
+  125, 0, 35, 0, 0, 0, 0, 93, 5, 24,
+  14, 0, 37, 16, 19, 24, 15, 1, 7, 0,
+  45, 74, 66, 43, 0, 20, 0, 0, 0, 49,
+  65, 69, 6, 62, 0, 1, 5, 0, 69, 27,
+  8, 0, 0, 8, 0, 34, 0, 35, 41, 0,
+  16, 0, 40, 0, 0, 56, 0, 37, 99, 45,
+  0, 4, 0, 17, 0, 45, 12, 0, 0, 33,
+  0, 12, 78, 0, 23, 0, 0, 0, 0, 6,
+  46, 35, 1, 18, 0, 2, 119, 0, 0, 1,
+  0, 16, 0, 27, 17, 29, 59, 0, 0, 26,
+  0, 8, 27, 0, 0, 42, 0, 0, 29, 0,
+  16, 0, 32, 10, 52, 56, 0, 0, 9, 11,
+  0, 0, 0, 0, 0, 0, 4, 23, 137, 0,
+  66, 0, 0, 0, 0, 115, 36, 17, 6, 0,
+  3, 0, 44, 17, 0, 0, 3, 0, 0, 24,
+  36, 38, 6, 35, 0, 0, 67, 53, 19, 0,
+  40, 54, 0, 0, 0, 0, 68, 0, 53, 8,
+  0, 0, 28, 2, 0, 0, 37, 25, 0, 67,
+  27, 0, 0, 2, 0, 53, 88, 0, 20, 0,
+  26, 0, 0, 0, 0, 27, 0, 0, 0, 0,
+  0, 0, 0, 14, 53, 0, 37, 17, 61, 42,
+  0, 74, 24, 0, 64, 0, 4, 21, 0, 0,
+  6, 36, 25, 20, 74, 0, 0, 0, 24, 0,
+  0, 0, 0, 53, 38, 17, 0, 0, 21, 4,
+  62, 0, 41, 58, 0, 16, 0, 3, 0, 0,
+  0, 0, 0, 6, 0, 0, 35, 0, 53, 1,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 98, 1, 0,
+  0, 0, 70, 26, 1, 40, 0, 18, 8, 0,
+  0, 55, 20, 56, 0, 28, 0, 0, 9, 77,
+  37, 43, 56, 51, 165, 33, 18, 0, 85, 0,
+  49, 0, 0, 7, 13, 31, 0, 0, 65, 0,
+  42, 42, 0, 0, 0, 51, 14, 68, 75, 5,
+  23, 0, 0, 0, 0, 38, 0, 3, 1, 24,
+  0, 20, 44, 0, 0, 18, 0, 29, 38, 5,
+  30, 64, 3, 48, 31, 0, 73, 0, 0, 22,
+  0, 9, 14, 16, 72, 24, 54, 0, 0, 3,
+  10, 1, 31, 0, 4, 29, 0, 13, 27, 0,
+  87, 0, 38, 9, 40, 53, 46, 4, 16, 15,
+  5, 0, 5, 0, 11, 52, 56, 10, 49, 0,
+  36, 0, 7, 0, 21, 87, 0, 17, 0, 0,
+  7, 0, 27, 18, 0, 30, 39, 0, 0, 11,
+  9, 43, 15, 26, 0, 36, 93, 68, 12, 0,
+  68, 46, 209, 0, 0, 0, 54, 0, 48, 43,
+  0, 0, 65, 3, 0, 0, 39, 14, 18, 96,
+  0, 0, 0, 10, 0, 107, 61, 0, 69, 0,
+  19, 0, 17, 0, 20, 40, 0, 0, 35, 25,
+  0, 0, 0, 58, 134, 10, 46, 0, 8, 33,
+  3, 95, 34, 0, 24, 0, 8, 20, 0, 5,
+  21, 22, 59, 0, 30, 0, 0, 0, 54, 0,
+  27, 0, 10, 43, 26, 72, 29, 15, 69, 18,
+  47, 0, 13, 38, 8, 8, 0, 1, 0, 0,
+  3, 0, 8, 49, 53, 0, 0, 0, 36, 0,
+  0, 0, 121, 68, 0, 69, 37, 0, 10, 0,
+  13, 0, 0, 24, 109, 0, 0, 19, 14, 0,
+  23, 0, 0, 116, 51, 34, 64, 0, 36, 36,
+  222, 0, 6, 97, 40, 17, 23, 41, 0, 0,
+  124, 6, 0, 0, 30, 56, 59, 90, 15, 0,
+  0, 12, 0, 135, 15, 0, 103, 17, 27, 22,
+  53, 0, 58, 43, 30, 87, 0, 83, 14, 0,
+  21, 25, 137, 20, 29, 0, 0, 0, 51, 86,
+  41, 0, 7, 0, 17, 24, 0, 13, 21, 0,
+  55, 9, 0, 0, 0, 0, 22, 16, 63, 0,
+  40, 42, 4, 62, 32, 21, 74, 29, 0, 42,
+  54, 0, 12, 14, 0, 0, 0, 27, 4, 0,
+  11, 38, 71, 25, 0, 34, 62, 0, 9, 24,
+  0, 93, 5, 24, 14, 0, 37, 16, 19, 24,
+  15, 1, 7, 0, 45, 74, 66, 43, 0, 20,
+  0, 0, 0, 49, 65, 69, 6, 62, 0, 1,
+  5, 0, 69, 27, 8, 0, 0, 8, 0, 34,
+  0, 35, 41, 0, 16, 0, 40, 0, 0, 56,
+  0, 37, 99, 45, 0, 4, 0, 17, 0, 45,
+  12, 0, 0, 33, 0, 12, 78, 0, 23, 0,
+  0, 0, 0, 6, 46, 35, 1, 18, 0, 2,
+  119, 0, 0, 1, 0, 16, 0, 27, 17, 29,
+  59, 0, 0, 26, 0, 8, 27, 0, 0, 42,
+  0, 0, 29, 0, 16, 0, 32, 10, 52, 56,
+  0, 0, 9, 11, 0, 0, 0, 0, 0, 0,
+  4, 23, 137, 0, 66, 0, 0, 0, 0, 115,
+  36, 17, 6, 0, 3, 0, 44, 17, 0, 0,
+  3, 0, 0, 24, 36, 38, 6, 35, 0, 0,
+  67, 53, 19, 0, 40, 54, 0, 0, 0, 0,
+  68, 0, 53, 8, 0, 0, 28, 2, 0, 0,
+  37, 25, 0, 67, 27, 0, 0, 2, 0, 53,
+  88, 0, 20, 0, 26, 0, 0, 0, 0, 27,
+  0, 0, 0, 0, 0, 0, 0, 14, 53, 0,
+  37, 17, 61, 42, 0, 74, 24, 0, 64, 0,
+  4, 21, 0, 0, 6, 36, 25, 20, 74, 0,
+  0, 0, 24, 0, 0, 0, 0, 53, 38, 17,
+  0, 0, 21, 4, 62, 0, 41, 58, 0, 16,
+  0, 3, 0, 0, 0, 0, 0, 6, 0, 0,
+  35, 0, 53, 1, 0, 0, 55, 68, 5, 59,
+  7, 0, 0, 0, 39, 0, 0, 18, 78, 0,
+  0, 0, 25, 2, 0, 0, 0, 34, 65, 19,
+  34, 0, 18, 36, 0, 0, 0, 6, 13, 0,
+  31, 16, 0, 0, 71, 0, 0, 16, 19, 37,
+  0, 40, 14, 0, 0, 0, 0, 107, 29, 0,
+  61, 0, 36, 0, 0, 0, 0, 19, 0, 10,
+  41, 34, 0, 0, 22, 0, 133, 0, 33, 13,
+  17, 0, 9, 54, 28, 7, 16, 0, 14, 15,
+  15, 0, 15, 0, 48, 0, 1, 0, 0, 0,
+  0, 0, 10, 0, 0, 40, 0, 1, 9, 0,
+  35, 68, 7, 20, 38, 3, 0, 13, 0, 0,
+  0, 0, 0, 0, 0, 9, 0, 0, 0, 0,
+  53, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 21, 87,
+  0, 17, 0, 0, 7, 0, 27, 18, 0, 30,
+  39, 0, 0, 11, 9, 43, 15, 26, 0, 36,
+  93, 68, 12, 0, 68, 46, 209, 0, 0, 0,
+  54, 0, 48, 43, 0, 0, 65, 3, 0, 0,
+  39, 14, 18, 96, 0, 0, 0, 10, 0, 107,
+  61, 0, 69, 0, 19, 0, 17, 0, 20, 40,
+  0, 0, 35, 25, 0, 0, 0, 58, 134, 10,
+  46, 0, 8, 33, 3, 95, 34, 0, 24, 0,
+  8, 20, 0, 5, 21, 22, 59, 0, 30, 0,
+  0, 0, 54, 0, 27, 0, 10, 43, 26, 72,
+  29, 15, 69, 18, 47, 0, 13, 38, 8, 8,
+  0, 1, 0, 0, 3, 0, 8, 49, 53, 0,
+  0, 0, 36, 0, 0, 0, 121, 68, 0, 69,
+  37, 0, 10, 0, 13, 0, 0, 24, 109, 0,
+  0, 19, 14, 0, 23, 0, 0, 116, 51, 34,
+  64, 0, 36, 36, 222, 0, 6, 97, 40, 17,
+  23, 41, 0, 0, 124, 6, 0, 0, 30, 56,
+  59, 90, 15, 0, 0, 12, 0, 135, 15, 0,
+  103, 17, 27, 22, 53, 0, 58, 43, 30, 87,
+  0, 83, 14, 0, 21, 25, 137, 20, 29, 0,
+  0, 0, 51, 86, 41, 0, 7, 0, 17, 24,
+  0, 13, 21, 0, 55, 9, 0, 0, 0, 0,
+  22, 16, 63, 0, 40, 42, 4, 62, 32, 21,
+  74, 29, 0, 42, 54, 0, 12, 14, 0, 0,
+  0, 27, 4, 0, 11, 38, 71, 25, 0, 34,
+  62, 0, 9, 24, 66, 10, 0, 31, 29, 110,
+  12, 0, 20, 0, 0, 9, 85, 0, 0, 46,
+  16, 30, 0, 0, 33, 111, 0, 60, 48, 0,
+  3, 44, 255, 0, 0, 72, 42, 37, 17, 24,
+  0, 22, 96, 20, 32, 0, 17, 61, 85, 122,
+  14, 0, 0, 23, 0, 130, 26, 0, 91, 47,
+  26, 11, 67, 0, 34, 60, 32, 28, 0, 46,
+  0, 4, 12, 28, 143, 0, 41, 3, 0, 22,
+  11, 56, 20, 0, 23, 0, 1, 24, 0, 0,
+  19, 5, 50, 28, 0, 55, 8, 0, 61, 18,
+  20, 0, 39, 55, 9, 30, 21, 7, 86, 7,
+  1, 22, 0, 7, 0, 16, 0, 0, 0, 31,
+  20, 0, 35, 34, 69, 0, 0, 44, 59, 0,
+  6, 4, 0, 115, 36, 17, 6, 0, 3, 0,
+  44, 17, 0, 0, 3, 0, 0, 24, 36, 38,
+  6, 35, 0, 0, 67, 53, 19, 0, 40, 54,
+  0, 0, 0, 0, 68, 0, 53, 8, 0, 0,
+  28, 2, 0, 0, 37, 25, 0, 67, 27, 0,
+  0, 2, 0, 53, 88, 0, 20, 0, 26, 0,
+  0, 0, 0, 27, 0, 0, 0, 0, 0, 0,
+  0, 14, 53, 0, 37, 17, 61, 42, 0, 74,
+  24, 0, 64, 0, 4, 21, 0, 0, 6, 36,
+  25, 20, 74, 0, 0, 0, 24, 0, 0, 0,
+  0, 53, 38, 17, 0, 0, 21, 4, 62, 0,
+  41, 58, 0, 16, 0, 3, 0, 0, 0, 0,
+  0, 6, 0, 0, 35, 0, 53, 1, 0, 0,
+  55, 68, 5, 59, 7, 0, 0, 0, 39, 0,
+  0, 18, 78, 0, 0, 0, 25, 2, 0, 0,
+  0, 34, 65, 19, 34, 0, 18, 36, 0, 0,
+  0, 6, 13, 0, 31, 16, 0, 0, 71, 0,
+  0, 16, 19, 37, 0, 40, 14, 0, 0, 0,
+  0, 107, 29, 0, 61, 0, 36, 0, 0, 0,
+  0, 19, 0, 10, 41, 34, 0, 0, 22, 0,
+  133, 0, 33, 13, 17, 0, 9, 54, 28, 7,
+  16, 0, 14, 15, 15, 0, 15, 0, 48, 0,
+  1, 0, 0, 0, 0, 0, 10, 0, 0, 40,
+  0, 1, 9, 0, 35, 68, 7, 20, 38, 3,
+  0, 13, 0, 0, 0, 0, 0, 0, 0, 9,
+  0, 0, 0, 0, 53, 0, 0, 0, 104, 21,
+  0, 47, 20, 66, 0, 0, 53, 0, 0, 0,
+  116, 0, 0, 40, 62, 0, 2, 0, 11, 68,
+  0, 8, 23, 0, 0, 43, 3, 1, 13, 72,
+  0, 27, 24, 0, 0, 21, 96, 5, 13, 87,
+  14, 47, 59, 16, 0, 0, 0, 0, 0, 111,
+  0, 0, 107, 59, 25, 17, 19, 0, 0, 13,
+  9, 35, 0, 93, 0, 0, 13, 0, 155, 30,
+  22, 32, 0, 0, 34, 19, 0, 47, 0, 0,
+  15, 14, 42, 14, 8, 0, 73, 0, 0, 0,
+  0, 2, 0, 0, 31, 0, 21, 50, 0, 0,
+  5, 0, 30, 31, 0, 67, 22, 0, 17, 0,
+  0, 0, 0, 0, 0, 0, 0, 1, 0, 3,
+  0, 16, 53, 0, 3, 16, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  121, 68, 0, 69, 37, 0, 10, 0, 13, 0,
+  0, 24, 109, 0, 0, 19, 14, 0, 23, 0,
+  0, 116, 51, 34, 64, 0, 36, 36, 222, 0,
+  6, 97, 40, 17, 23, 41, 0, 0, 124, 6,
+  0, 0, 30, 56, 59, 90, 15, 0, 0, 12,
+  0, 135, 15, 0, 103, 17, 27, 22, 53, 0,
+  58, 43, 30, 87, 0, 83, 14, 0, 21, 25,
+  137, 20, 29, 0, 0, 0, 51, 86, 41, 0,
+  7, 0, 17, 24, 0, 13, 21, 0, 55, 9,
+  0, 0, 0, 0, 22, 16, 63, 0, 40, 42,
+  4, 62, 32, 21, 74, 29, 0, 42, 54, 0,
+  12, 14, 0, 0, 0, 27, 4, 0, 11, 38,
+  71, 25, 0, 34, 62, 0, 9, 24, 66, 10,
+  0, 31, 29, 110, 12, 0, 20, 0, 0, 9,
+  85, 0, 0, 46, 16, 30, 0, 0, 33, 111,
+  0, 60, 48, 0, 3, 44, 255, 0, 0, 72,
+  42, 37, 17, 24, 0, 22, 96, 20, 32, 0,
+  17, 61, 85, 122, 14, 0, 0, 23, 0, 130,
+  26, 0, 91, 47, 26, 11, 67, 0, 34, 60,
+  32, 28, 0, 46, 0, 4, 12, 28, 143, 0,
+  41, 3, 0, 22, 11, 56, 20, 0, 23, 0,
+  1, 24, 0, 0, 19, 5, 50, 28, 0, 55,
+  8, 0, 61, 18, 20, 0, 39, 55, 9, 30,
+  21, 7, 86, 7, 1, 22, 0, 7, 0, 16,
+  0, 0, 0, 31, 20, 0, 35, 34, 69, 0,
+  0, 44, 59, 0, 6, 4, 0, 38, 0, 0,
+  7, 72, 57, 6, 59, 17, 0, 6, 46, 16,
+  0, 163, 49, 58, 0, 0, 76, 0, 0, 90,
+  29, 28, 5, 40, 214, 33, 0, 0, 89, 29,
+  32, 0, 0, 53, 10, 75, 12, 0, 0, 45,
+  49, 87, 5, 9, 0, 73, 3, 65, 107, 1,
+  7, 49, 22, 23, 0, 54, 0, 5, 0, 32,
+  0, 1, 11, 0, 25, 0, 29, 0, 39, 11,
+  0, 97, 0, 37, 0, 1, 62, 0, 14, 26,
+  0, 4, 35, 12, 60, 53, 62, 78, 0, 3,
+  68, 5, 0, 0, 50, 64, 14, 0, 0, 0,
+  76, 0, 29, 16, 1, 58, 17, 0, 0, 22,
+  0, 0, 0, 12, 39, 12, 66, 4, 74, 0,
+  59, 0, 32, 0, 55, 68, 5, 59, 7, 0,
+  0, 0, 39, 0, 0, 18, 78, 0, 0, 0,
+  25, 2, 0, 0, 0, 34, 65, 19, 34, 0,
+  18, 36, 0, 0, 0, 6, 13, 0, 31, 16,
+  0, 0, 71, 0, 0, 16, 19, 37, 0, 40,
+  14, 0, 0, 0, 0, 107, 29, 0, 61, 0,
+  36, 0, 0, 0, 0, 19, 0, 10, 41, 34,
+  0, 0, 22, 0, 133, 0, 33, 13, 17, 0,
+  9, 54, 28, 7, 16, 0, 14, 15, 15, 0,
+  15, 0, 48, 0, 1, 0, 0, 0, 0, 0,
+  10, 0, 0, 40, 0, 1, 9, 0, 35, 68,
+  7, 20, 38, 3, 0, 13, 0, 0, 0, 0,
+  0, 0, 0, 9, 0, 0, 0, 0, 53, 0,
+  0, 0, 104, 21, 0, 47, 20, 66, 0, 0,
+  53, 0, 0, 0, 116, 0, 0, 40, 62, 0,
+  2, 0, 11, 68, 0, 8, 23, 0, 0, 43,
+  3, 1, 13, 72, 0, 27, 24, 0, 0, 21,
+  96, 5, 13, 87, 14, 47, 59, 16, 0, 0,
+  0, 0, 0, 111, 0, 0, 107, 59, 25, 17,
+  19, 0, 0, 13, 9, 35, 0, 93, 0, 0,
+  13, 0, 155, 30, 22, 32, 0, 0, 34, 19,
+  0, 47, 0, 0, 15, 14, 42, 14, 8, 0,
+  73, 0, 0, 0, 0, 2, 0, 0, 31, 0,
+  21, 50, 0, 0, 5, 0, 30, 31, 0, 67,
+  22, 0, 17, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 3, 0, 16, 53, 0, 3, 16,
+  0, 0, 0, 0, 0, 145, 0, 0, 46, 0,
+  0, 0, 34, 21, 0, 109, 67, 48, 0, 0,
+  39, 1, 0, 58, 0, 0, 0, 56, 1, 0,
+  0, 0, 49, 0, 0, 0, 22, 71, 0, 0,
+  22, 0, 0, 3, 13, 87, 0, 0, 0, 14,
+  12, 53, 23, 0, 62, 19, 29, 0, 0, 0,
+  0, 48, 0, 0, 12, 0, 16, 0, 17, 13,
+  58, 0, 50, 76, 0, 66, 0, 52, 0, 0,
+  8, 0, 17, 64, 0, 25, 19, 0, 22, 2,
+  35, 128, 0, 0, 75, 0, 0, 0, 0, 93,
+  86, 0, 0, 0, 15, 0, 0, 38, 0, 19,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 13, 0, 4, 15, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 66, 10, 0, 31, 29, 110, 12, 0,
+  20, 0, 0, 9, 85, 0, 0, 46, 16, 30,
+  0, 0, 33, 111, 0, 60, 48, 0, 3, 44,
+  255, 0, 0, 72, 42, 37, 17, 24, 0, 22,
+  96, 20, 32, 0, 17, 61, 85, 122, 14, 0,
+  0, 23, 0, 130, 26, 0, 91, 47, 26, 11,
+  67, 0, 34, 60, 32, 28, 0, 46, 0, 4,
+  12, 28, 143, 0, 41, 3, 0, 22, 11, 56,
+  20, 0, 23, 0, 1, 24, 0, 0, 19, 5,
+  50, 28, 0, 55, 8, 0, 61, 18, 20, 0,
+  39, 55, 9, 30, 21, 7, 86, 7, 1, 22,
+  0, 7, 0, 16, 0, 0, 0, 31, 20, 0,
+  35, 34, 69, 0, 0, 44, 59, 0, 6, 4,
+  0, 38, 0, 0, 7, 72, 57, 6, 59, 17,
+  0, 6, 46, 16, 0, 163, 49, 58, 0, 0,
+  76, 0, 0, 90, 29, 28, 5, 40, 214, 33,
+  0, 0, 89, 29, 32, 0, 0, 53, 10, 75,
+  12, 0, 0, 45, 49, 87, 5, 9, 0, 73,
+  3, 65, 107, 1, 7, 49, 22, 23, 0, 54,
+  0, 5, 0, 32, 0, 1, 11, 0, 25, 0,
+  29, 0, 39, 11, 0, 97, 0, 37, 0, 1,
+  62, 0, 14, 26, 0, 4, 35, 12, 60, 53,
+  62, 78, 0, 3, 68, 5, 0, 0, 50, 64,
+  14, 0, 0, 0, 76, 0, 29, 16, 1, 58,
+  17, 0, 0, 22, 0, 0, 0, 12, 39, 12,
+  66, 4, 74, 0, 59, 0, 32, 0, 0, 58,
+  63, 0, 7, 0, 21, 41, 98, 32, 26, 34,
+  16, 64, 0, 150, 62, 63, 48, 14, 52, 0,
+  0, 72, 12, 0, 54, 79, 175, 35, 0, 0,
+  104, 0, 8, 0, 3, 53, 0, 34, 0, 0,
+  0, 32, 8, 71, 0, 0, 0, 50, 34, 80,
+  101, 18, 30, 0, 24, 14, 0, 49, 0, 0,
+  0, 16, 0, 0, 47, 0, 11, 29, 0, 0,
+  63, 28, 0, 75, 0, 60, 0, 1, 62, 4,
+  40, 45, 0, 23, 18, 40, 92, 24, 106, 1,
+  0, 0, 68, 0, 17, 0, 31, 98, 42, 0,
+  7, 0, 83, 0, 3, 51, 27, 30, 31, 0,
+  16, 5, 20, 0, 0, 18, 0, 32, 51, 0,
+  76, 0, 65, 0, 38, 22, 104, 21, 0, 47,
+  20, 66, 0, 0, 53, 0, 0, 0, 116, 0,
+  0, 40, 62, 0, 2, 0, 11, 68, 0, 8,
+  23, 0, 0, 43, 3, 1, 13, 72, 0, 27,
+  24, 0, 0, 21, 96, 5, 13, 87, 14, 47,
+  59, 16, 0, 0, 0, 0, 0, 111, 0, 0,
+  107, 59, 25, 17, 19, 0, 0, 13, 9, 35,
+  0, 93, 0, 0, 13, 0, 155, 30, 22, 32,
+  0, 0, 34, 19, 0, 47, 0, 0, 15, 14,
+  42, 14, 8, 0, 73, 0, 0, 0, 0, 2,
+  0, 0, 31, 0, 21, 50, 0, 0, 5, 0,
+  30, 31, 0, 67, 22, 0, 17, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 0, 3, 0, 16,
+  53, 0, 3, 16, 0, 0, 0, 0, 0, 145,
+  0, 0, 46, 0, 0, 0, 34, 21, 0, 109,
+  67, 48, 0, 0, 39, 1, 0, 58, 0, 0,
+  0, 56, 1, 0, 0, 0, 49, 0, 0, 0,
+  22, 71, 0, 0, 22, 0, 0, 3, 13, 87,
+  0, 0, 0, 14, 12, 53, 23, 0, 62, 19,
+  29, 0, 0, 0, 0, 48, 0, 0, 12, 0,
+  16, 0, 17, 13, 58, 0, 50, 76, 0, 66,
+  0, 52, 0, 0, 8, 0, 17, 64, 0, 25,
+  19, 0, 22, 2, 35, 128, 0, 0, 75, 0,
+  0, 0, 0, 93, 86, 0, 0, 0, 15, 0,
+  0, 38, 0, 19, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 13, 0,
+  4, 15, 0, 0, 92, 0, 0, 76, 0, 0,
+  44, 0, 0, 15, 13, 93, 0, 13, 41, 74,
+  27, 0, 22, 35, 4, 32, 0, 0, 0, 34,
+  0, 0, 18, 4, 5, 0, 0, 0, 14, 65,
+  0, 0, 0, 14, 0, 0, 0, 18, 0, 0,
+  0, 0, 19, 112, 26, 0, 66, 0, 49, 0,
+  1, 0, 0, 12, 0, 0, 37, 7, 27, 10,
+  26, 96, 0, 0, 36, 15, 0, 30, 0, 21,
+  0, 0, 0, 0, 33, 83, 0, 28, 14, 34,
+  42, 0, 16, 32, 0, 0, 39, 0, 0, 0,
+  13, 107, 45, 0, 0, 0, 3, 18, 0, 20,
+  0, 5, 17, 0, 0, 0, 49, 0, 46, 44,
+  22, 4, 0, 0, 0, 0, 20, 0, 0, 18,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 38, 0, 0, 7, 72,
+  57, 6, 59, 17, 0, 6, 46, 16, 0, 163,
+  49, 58, 0, 0, 76, 0, 0, 90, 29, 28,
+  5, 40, 214, 33, 0, 0, 89, 29, 32, 0,
+  0, 53, 10, 75, 12, 0, 0, 45, 49, 87,
+  5, 9, 0, 73, 3, 65, 107, 1, 7, 49,
+  22, 23, 0, 54, 0, 5, 0, 32, 0, 1,
+  11, 0, 25, 0, 29, 0, 39, 11, 0, 97,
+  0, 37, 0, 1, 62, 0, 14, 26, 0, 4,
+  35, 12, 60, 53, 62, 78, 0, 3, 68, 5,
+  0, 0, 50, 64, 14, 0, 0, 0, 76, 0,
+  29, 16, 1, 58, 17, 0, 0, 22, 0, 0,
+  0, 12, 39, 12, 66, 4, 74, 0, 59, 0,
+  32, 0, 0, 58, 63, 0, 7, 0, 21, 41,
+  98, 32, 26, 34, 16, 64, 0, 150, 62, 63,
+  48, 14, 52, 0, 0, 72, 12, 0, 54, 79,
+  175, 35, 0, 0, 104, 0, 8, 0, 3, 53,
+  0, 34, 0, 0, 0, 32, 8, 71, 0, 0,
+  0, 50, 34, 80, 101, 18, 30, 0, 24, 14,
+  0, 49, 0, 0, 0, 16, 0, 0, 47, 0,
+  11, 29, 0, 0, 63, 28, 0, 75, 0, 60,
+  0, 1, 62, 4, 40, 45, 0, 23, 18, 40,
+  92, 24, 106, 1, 0, 0, 68, 0, 17, 0,
+  31, 98, 42, 0, 7, 0, 83, 0, 3, 51,
+  27, 30, 31, 0, 16, 5, 20, 0, 0, 18,
+  0, 32, 51, 0, 76, 0, 65, 0, 38, 22,
+  50, 21, 117, 0, 0, 33, 0, 34, 48, 0,
+  0, 21, 0, 97, 0, 11, 24, 76, 56, 29,
+  7, 79, 14, 26, 0, 0, 21, 72, 178, 23,
+  2, 77, 15, 0, 0, 17, 0, 58, 0, 0,
+  0, 0, 23, 6, 0, 52, 0, 0, 0, 0,
+  17, 138, 16, 0, 76, 0, 43, 0, 26, 0,
+  0, 0, 10, 14, 41, 10, 2, 8, 11, 125,
+  0, 0, 81, 0, 0, 29, 11, 26, 12, 0,
+  0, 0, 1, 82, 0, 0, 46, 37, 66, 0,
+  39, 0, 0, 0, 91, 0, 6, 0, 15, 66,
+  24, 0, 23, 6, 85, 90, 0, 23, 0, 0,
+  42, 20, 11, 6, 52, 0, 44, 28, 0, 49,
+  48, 0, 0, 0, 21, 0, 24, 28, 0, 0,
+  0, 0, 0, 145, 0, 0, 46, 0, 0, 0,
+  34, 21, 0, 109, 67, 48, 0, 0, 39, 1,
+  0, 58, 0, 0, 0, 56, 1, 0, 0, 0,
+  49, 0, 0, 0, 22, 71, 0, 0, 22, 0,
+  0, 3, 13, 87, 0, 0, 0, 14, 12, 53,
+  23, 0, 62, 19, 29, 0, 0, 0, 0, 48,
+  0, 0, 12, 0, 16, 0, 17, 13, 58, 0,
+  50, 76, 0, 66, 0, 52, 0, 0, 8, 0,
+  17, 64, 0, 25, 19, 0, 22, 2, 35, 128,
+  0, 0, 75, 0, 0, 0, 0, 93, 86, 0,
+  0, 0, 15, 0, 0, 38, 0, 19, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 13, 0, 4, 15, 0, 0, 92, 0,
+  0, 76, 0, 0, 44, 0, 0, 15, 13, 93,
+  0, 13, 41, 74, 27, 0, 22, 35, 4, 32,
+  0, 0, 0, 34, 0, 0, 18, 4, 5, 0,
+  0, 0, 14, 65, 0, 0, 0, 14, 0, 0,
+  0, 18, 0, 0, 0, 0, 19, 112, 26, 0,
+  66, 0, 49, 0, 1, 0, 0, 12, 0, 0,
+  37, 7, 27, 10, 26, 96, 0, 0, 36, 15,
+  0, 30, 0, 21, 0, 0, 0, 0, 33, 83,
+  0, 28, 14, 34, 42, 0, 16, 32, 0, 0,
+  39, 0, 0, 0, 13, 107, 45, 0, 0, 0,
+  3, 18, 0, 20, 0, 5, 17, 0, 0, 0,
+  49, 0, 46, 44, 22, 4, 0, 0, 0, 0,
+  20, 0, 0, 18, 0, 0, 91, 0, 0, 56,
+  0, 0, 0, 0, 0, 21, 6, 68, 0, 0,
+  3, 66, 22, 26, 0, 44, 1, 12, 25, 0,
+  0, 0, 0, 0, 35, 19, 0, 0, 0, 0,
+  0, 41, 0, 0, 0, 9, 0, 13, 0, 4,
+  17, 0, 0, 0, 11, 90, 12, 0, 37, 0,
+  34, 0, 44, 0, 0, 20, 0, 0, 71, 0,
+  0, 58, 0, 66, 0, 22, 34, 0, 4, 12,
+  0, 0, 14, 0, 0, 0, 11, 67, 48, 0,
+  47, 25, 46, 0, 0, 0, 0, 0, 2, 0,
+  0, 5, 16, 47, 0, 0, 0, 1, 0, 93,
+  0, 9, 0, 23, 27, 12, 0, 4, 70, 6,
+  57, 62, 45, 37, 28, 1, 0, 0, 18, 8,
+  3, 27, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 58, 63, 0,
+  7, 0, 21, 41, 98, 32, 26, 34, 16, 64,
+  0, 150, 62, 63, 48, 14, 52, 0, 0, 72,
+  12, 0, 54, 79, 175, 35, 0, 0, 104, 0,
+  8, 0, 3, 53, 0, 34, 0, 0, 0, 32,
+  8, 71, 0, 0, 0, 50, 34, 80, 101, 18,
+  30, 0, 24, 14, 0, 49, 0, 0, 0, 16,
+  0, 0, 47, 0, 11, 29, 0, 0, 63, 28,
+  0, 75, 0, 60, 0, 1, 62, 4, 40, 45,
+  0, 23, 18, 40, 92, 24, 106, 1, 0, 0,
+  68, 0, 17, 0, 31, 98, 42, 0, 7, 0,
+  83, 0, 3, 51, 27, 30, 31, 0, 16, 5,
+  20, 0, 0, 18, 0, 32, 51, 0, 76, 0,
+  65, 0, 38, 22, 50, 21, 117, 0, 0, 33,
+  0, 34, 48, 0, 0, 21, 0, 97, 0, 11,
+  24, 76, 56, 29, 7, 79, 14, 26, 0, 0,
+  21, 72, 178, 23, 2, 77, 15, 0, 0, 17,
+  0, 58, 0, 0, 0, 0, 23, 6, 0, 52,
+  0, 0, 0, 0, 17, 138, 16, 0, 76, 0,
+  43, 0, 26, 0, 0, 0, 10, 14, 41, 10,
+  2, 8, 11, 125, 0, 0, 81, 0, 0, 29,
+  11, 26, 12, 0, 0, 0, 1, 82, 0, 0,
+  46, 37, 66, 0, 39, 0, 0, 0, 91, 0,
+  6, 0, 15, 66, 24, 0, 23, 6, 85, 90,
+  0, 23, 0, 0, 42, 20, 11, 6, 52, 0,
+  44, 28, 0, 49, 48, 0, 0, 0, 21, 0,
+  24, 28, 37, 2, 61, 0, 0, 73, 0, 0,
+  0, 0, 0, 0, 0, 114, 0, 0, 5, 58,
+  36, 11, 0, 72, 12, 49, 0, 0, 26, 41,
+  217, 0, 0, 48, 0, 41, 0, 0, 6, 3,
+  0, 0, 0, 0, 13, 0, 0, 63, 19, 55,
+  0, 0, 20, 92, 0, 0, 70, 0, 42, 0,
+  39, 0, 25, 1, 0, 0, 74, 12, 10, 4,
+  28, 139, 25, 13, 70, 0, 0, 6, 18, 0,
+  2, 4, 0, 0, 4, 80, 0, 0, 46, 48,
+  69, 0, 0, 0, 12, 0, 60, 0, 0, 0,
+  11, 29, 28, 90, 42, 8, 49, 129, 4, 0,
+  0, 1, 4, 23, 0, 0, 30, 66, 51, 23,
+  16, 39, 2, 0, 0, 0, 0, 0, 0, 44,
+  0, 0, 92, 0, 0, 76, 0, 0, 44, 0,
+  0, 15, 13, 93, 0, 13, 41, 74, 27, 0,
+  22, 35, 4, 32, 0, 0, 0, 34, 0, 0,
+  18, 4, 5, 0, 0, 0, 14, 65, 0, 0,
+  0, 14, 0, 0, 0, 18, 0, 0, 0, 0,
+  19, 112, 26, 0, 66, 0, 49, 0, 1, 0,
+  0, 12, 0, 0, 37, 7, 27, 10, 26, 96,
+  0, 0, 36, 15, 0, 30, 0, 21, 0, 0,
+  0, 0, 33, 83, 0, 28, 14, 34, 42, 0,
+  16, 32, 0, 0, 39, 0, 0, 0, 13, 107,
+  45, 0, 0, 0, 3, 18, 0, 20, 0, 5,
+  17, 0, 0, 0, 49, 0, 46, 44, 22, 4,
+  0, 0, 0, 0, 20, 0, 0, 18, 0, 0,
+  91, 0, 0, 56, 0, 0, 0, 0, 0, 21,
+  6, 68, 0, 0, 3, 66, 22, 26, 0, 44,
+  1, 12, 25, 0, 0, 0, 0, 0, 35, 19,
+  0, 0, 0, 0, 0, 41, 0, 0, 0, 9,
+  0, 13, 0, 4, 17, 0, 0, 0, 11, 90,
+  12, 0, 37, 0, 34, 0, 44, 0, 0, 20,
+  0, 0, 71, 0, 0, 58, 0, 66, 0, 22,
+  34, 0, 4, 12, 0, 0, 14, 0, 0, 0,
+  11, 67, 48, 0, 47, 25, 46, 0, 0, 0,
+  0, 0, 2, 0, 0, 5, 16, 47, 0, 0,
+  0, 1, 0, 93, 0, 9, 0, 23, 27, 12,
+  0, 4, 70, 6, 57, 62, 45, 37, 28, 1,
+  0, 0, 18, 8, 3, 27, 0, 16, 49, 0,
+  0, 5, 31, 0, 1, 0, 0, 6, 0, 41,
+  0, 0, 0, 25, 35, 4, 0, 0, 0, 52,
+  24, 0, 16, 5, 179, 11, 21, 0, 23, 0,
+  0, 0, 0, 11, 0, 43, 0, 24, 1, 8,
+  2, 65, 31, 0, 0, 0, 0, 37, 49, 0,
+  7, 0, 6, 0, 40, 14, 28, 28, 0, 0,
+  0, 18, 44, 18, 0, 7, 0, 39, 35, 0,
+  13, 18, 0, 0, 20, 0, 17, 2, 0, 51,
+  0, 0, 32, 30, 78, 35, 0, 0, 40, 0,
+  0, 22, 0, 0, 33, 23, 14, 18, 8, 0,
+  15, 74, 44, 16, 21, 36, 0, 12, 0, 0,
+  6, 34, 56, 40, 46, 34, 33, 8, 0, 0,
+  18, 0, 14, 30, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 50, 21,
+  117, 0, 0, 33, 0, 34, 48, 0, 0, 21,
+  0, 97, 0, 11, 24, 76, 56, 29, 7, 79,
+  14, 26, 0, 0, 21, 72, 178, 23, 2, 77,
+  15, 0, 0, 17, 0, 58, 0, 0, 0, 0,
+  23, 6, 0, 52, 0, 0, 0, 0, 17, 138,
+  16, 0, 76, 0, 43, 0, 26, 0, 0, 0,
+  10, 14, 41, 10, 2, 8, 11, 125, 0, 0,
+  81, 0, 0, 29, 11, 26, 12, 0, 0, 0,
+  1, 82, 0, 0, 46, 37, 66, 0, 39, 0,
+  0, 0, 91, 0, 6, 0, 15, 66, 24, 0,
+  23, 6, 85, 90, 0, 23, 0, 0, 42, 20,
+  11, 6, 52, 0, 44, 28, 0, 49, 48, 0,
+  0, 0, 21, 0, 24, 28, 37, 2, 61, 0,
+  0, 73, 0, 0, 0, 0, 0, 0, 0, 114,
+  0, 0, 5, 58, 36, 11, 0, 72, 12, 49,
+  0, 0, 26, 41, 217, 0, 0, 48, 0, 41,
+  0, 0, 6, 3, 0, 0, 0, 0, 13, 0,
+  0, 63, 19, 55, 0, 0, 20, 92, 0, 0,
+  70, 0, 42, 0, 39, 0, 25, 1, 0, 0,
+  74, 12, 10, 4, 28, 139, 25, 13, 70, 0,
+  0, 6, 18, 0, 2, 4, 0, 0, 4, 80,
+  0, 0, 46, 48, 69, 0, 0, 0, 12, 0,
+  60, 0, 0, 0, 11, 29, 28, 90, 42, 8,
+  49, 129, 4, 0, 0, 1, 4, 23, 0, 0,
+  30, 66, 51, 23, 16, 39, 2, 0, 0, 0,
+  0, 0, 0, 44, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 91, 0, 0, 56, 0, 0,
+  0, 0, 0, 21, 6, 68, 0, 0, 3, 66,
+  22, 26, 0, 44, 1, 12, 25, 0, 0, 0,
+  0, 0, 35, 19, 0, 0, 0, 0, 0, 41,
+  0, 0, 0, 9, 0, 13, 0, 4, 17, 0,
+  0, 0, 11, 90, 12, 0, 37, 0, 34, 0,
+  44, 0, 0, 20, 0, 0, 71, 0, 0, 58,
+  0, 66, 0, 22, 34, 0, 4, 12, 0, 0,
+  14, 0, 0, 0, 11, 67, 48, 0, 47, 25,
+  46, 0, 0, 0, 0, 0, 2, 0, 0, 5,
+  16, 47, 0, 0, 0, 1, 0, 93, 0, 9,
+  0, 23, 27, 12, 0, 4, 70, 6, 57, 62,
+  45, 37, 28, 1, 0, 0, 18, 8, 3, 27,
+  0, 16, 49, 0, 0, 5, 31, 0, 1, 0,
+  0, 6, 0, 41, 0, 0, 0, 25, 35, 4,
+  0, 0, 0, 52, 24, 0, 16, 5, 179, 11,
+  21, 0, 23, 0, 0, 0, 0, 11, 0, 43,
+  0, 24, 1, 8, 2, 65, 31, 0, 0, 0,
+  0, 37, 49, 0, 7, 0, 6, 0, 40, 14,
+  28, 28, 0, 0, 0, 18, 44, 18, 0, 7,
+  0, 39, 35, 0, 13, 18, 0, 0, 20, 0,
+  17, 2, 0, 51, 0, 0, 32, 30, 78, 35,
+  0, 0, 40, 0, 0, 22, 0, 0, 33, 23,
+  14, 18, 8, 0, 15, 74, 44, 16, 21, 36,
+  0, 12, 0, 0, 6, 34, 56, 40, 46, 34,
+  33, 8, 0, 0, 18, 0, 14, 30, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 39, 14, 0, 0, 0,
+  63, 31, 0, 36, 15, 0, 0, 12, 10, 93,
+  23, 78, 37, 39, 52, 0, 44, 62, 9, 23,
+  34, 48, 251, 53, 0, 0, 103, 0, 11, 0,
+  0, 19, 12, 43, 34, 0, 10, 7, 84, 61,
+  0, 22, 0, 69, 0, 28, 41, 0, 20, 0,
+  7, 14, 0, 3, 6, 7, 15, 0, 0, 16,
+  25, 16, 0, 28, 0, 14, 83, 9, 21, 62,
+  7, 4, 7, 0, 53, 0, 16, 0, 0, 1,
+  0, 4, 66, 24, 50, 9, 0, 0, 69, 27,
+  15, 2, 14, 33, 3, 0, 1, 18, 73, 0,
+  43, 0, 0, 6, 26, 16, 10, 44, 0, 0,
+  22, 18, 0, 41, 77, 0, 0, 0, 0, 0,
+  27, 20, 27, 77, 56, 1, 0, 0, 53, 33,
+  0, 26, 0, 19, 15, 40, 3, 80, 27, 70,
+  9, 40, 13, 19, 51, 56, 1, 0, 62, 39,
+  168, 33, 0, 2, 112, 0, 35, 0, 0, 8,
+  0, 15, 15, 0, 16, 4, 70, 57, 0, 21,
+  0, 58, 0, 81, 74, 0, 31, 0, 4, 0,
+  0, 0, 31, 0, 5, 36, 0, 9, 25, 0,
+  0, 65, 0, 19, 22, 10, 17, 20, 19, 22,
+  19, 0, 39, 0, 23, 18, 0, 9, 5, 21,
+  68, 17, 39, 0, 0, 0, 34, 0, 67, 16,
+  7, 35, 9, 16, 42, 18, 111, 0, 19, 7,
+  30, 4, 45, 33, 26, 6, 0, 0, 14, 0,
+  1, 30, 86, 0, 9, 0, 3, 0, 26, 19,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 12, 21,
+  64, 6, 0, 0, 17, 8, 0, 10, 24, 0,
+  0, 65, 0, 74, 92, 76, 35, 40, 22, 3,
+  39, 33, 0, 0, 31, 58, 156, 6, 15, 0,
+  58, 0, 0, 0, 0, 18, 0, 18, 5, 27,
+  0, 0, 53, 31, 0, 18, 0, 0, 0, 47,
+  40, 0, 10, 0, 0, 9, 0, 6, 28, 0,
+  0, 0, 0, 7, 44, 0, 48, 45, 0, 16,
+  17, 16, 28, 6, 22, 3, 0, 16, 38, 0,
+  14, 0, 0, 13, 0, 23, 45, 25, 8, 25,
+  0, 0, 67, 0, 51, 0, 0, 39, 3, 0,
+  27, 11, 67, 0, 18, 0, 0, 0, 20, 21,
+  9, 43, 3, 0, 12, 0, 0, 0, 64, 0,
+  5, 0, 0, 0, 55, 0, 56, 59, 50, 27,
+  4, 0, 2, 0, 0, 0, 8, 0, 48, 60,
+  4, 28, 76, 49, 0, 0, 0, 6, 1, 61,
+  24, 0, 35, 40, 0, 0, 13, 0, 67, 0,
+  0, 0, 0, 0, 0, 1, 0, 66, 2, 0,
+  30, 28, 26, 42, 0, 12, 0, 69, 96, 0,
+  23, 0, 0, 0, 0, 0, 51, 0, 0, 65,
+  0, 8, 82, 0, 40, 45, 0, 20, 0, 33,
+  32, 0, 14, 3, 0, 16, 42, 0, 37, 0,
+  0, 30, 0, 27, 36, 9, 13, 0, 0, 22,
+  2, 0, 70, 5, 0, 64, 0, 23, 40, 0,
+  76, 0, 6, 0, 58, 8, 17, 40, 5, 0,
+  26, 0, 1, 0, 0, 0, 39, 0, 71, 0,
+  10, 9, 14, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 47, 23, 86, 28, 0, 0, 29, 6,
+  18, 0, 12, 0, 0, 94, 0, 55, 94, 25,
+  14, 29, 7, 39, 13, 18, 25, 0, 29, 32,
+  164, 9, 5, 45, 79, 0, 0, 0, 0, 37,
+  0, 0, 0, 4, 0, 10, 7, 71, 53, 0,
+  0, 0, 0, 40, 22, 15, 17, 0, 13, 0,
+  0, 3, 39, 29, 0, 0, 0, 0, 72, 0,
+  119, 51, 0, 0, 21, 0, 24, 0, 65, 11,
+  0, 23, 14, 0, 42, 0, 0, 26, 0, 0,
+  59, 5, 0, 16, 0, 5, 15, 0, 38, 1,
+  14, 93, 25, 0, 14, 51, 54, 47, 12, 0,
+  25, 0, 4, 10, 0, 41, 10, 0, 18, 0,
+  17, 0, 59, 0, 0, 0, 0, 24, 48, 21,
+  43, 69, 0, 8, 5, 11, 0, 0, 0, 0,
+  0, 0, 16, 73, 0, 0, 82, 18, 0, 0,
+  0, 41, 0, 50, 15, 0, 5, 16, 0, 0,
+  0, 19, 83, 23, 0, 0, 0, 9, 0, 0,
+  0, 6, 0, 0, 9, 74, 35, 102, 0, 0,
+  0, 29, 56, 0, 22, 0, 18, 0, 0, 0,
+  78, 24, 0, 51, 0, 0, 97, 0, 107, 49,
+  0, 0, 4, 13, 45, 0, 27, 0, 0, 5,
+  25, 0, 35, 12, 0, 12, 0, 6, 0, 6,
+  0, 26, 0, 19, 1, 0, 34, 0, 12, 95,
+  20, 81, 35, 21, 44, 44, 10, 0, 51, 0,
+  0, 63, 0, 7, 0, 0, 0, 0, 11, 0,
+  22, 0, 33, 0, 0, 27, 27, 0, 0, 39,
+  14, 0, 0, 0, 63, 31, 0, 36, 15, 0,
+  0, 12, 10, 93, 23, 78, 37, 39, 52, 0,
+  44, 62, 9, 23, 34, 48, 251, 53, 0, 0,
+  103, 0, 11, 0, 0, 19, 12, 43, 34, 0,
+  10, 7, 84, 61, 0, 22, 0, 69, 0, 28,
+  41, 0, 20, 0, 7, 14, 0, 3, 6, 7,
+  15, 0, 0, 16, 25, 16, 0, 28, 0, 14,
+  83, 9, 21, 62, 7, 4, 7, 0, 53, 0,
+  16, 0, 0, 1, 0, 4, 66, 24, 50, 9,
+  0, 0, 69, 27, 15, 2, 14, 33, 3, 0,
+  1, 18, 73, 0, 43, 0, 0, 6, 26, 16,
+  10, 44, 0, 0, 22, 18, 0, 41, 77, 0,
+  0, 0, 0, 0, 27, 20, 27, 77, 56, 1,
+  0, 0, 53, 33, 0, 26, 0, 19, 15, 40,
+  3, 80, 27, 70, 9, 40, 13, 19, 51, 56,
+  1, 0, 62, 39, 168, 33, 0, 2, 112, 0,
+  35, 0, 0, 8, 0, 15, 15, 0, 16, 4,
+  70, 57, 0, 21, 0, 58, 0, 81, 74, 0,
+  31, 0, 4, 0, 0, 0, 31, 0, 5, 36,
+  0, 9, 25, 0, 0, 65, 0, 19, 22, 10,
+  17, 20, 19, 22, 19, 0, 39, 0, 23, 18,
+  0, 9, 5, 21, 68, 17, 39, 0, 0, 0,
+  34, 0, 67, 16, 7, 35, 9, 16, 42, 18,
+  111, 0, 19, 7, 30, 4, 45, 33, 26, 6,
+  0, 0, 14, 0, 1, 30, 86, 0, 9, 0,
+  3, 0, 26, 19, 51, 73, 59, 31, 0, 25,
+  25, 27, 1, 0, 0, 49, 62, 54, 0, 17,
+  9, 31, 5, 0, 0, 97, 24, 47, 40, 0,
+  67, 36, 173, 0, 0, 93, 100, 0, 16, 5,
+  0, 0, 0, 8, 0, 0, 58, 12, 35, 124,
+  53, 23, 0, 49, 0, 76, 26, 0, 69, 0,
+  16, 0, 0, 0, 74, 49, 11, 40, 2, 17,
+  33, 10, 4, 69, 21, 19, 13, 0, 5, 0,
+  39, 35, 1, 0, 24, 0, 46, 72, 0, 11,
+  18, 1, 41, 28, 0, 0, 0, 0, 0, 0,
+  56, 0, 0, 45, 33, 55, 30, 39, 114, 0,
+  28, 15, 40, 0, 15, 24, 15, 0, 0, 0,
+  36, 0, 25, 27, 59, 0, 0, 0, 16, 0,
+  11, 50, 12, 21, 64, 6, 0, 0, 17, 8,
+  0, 10, 24, 0, 0, 65, 0, 74, 92, 76,
+  35, 40, 22, 3, 39, 33, 0, 0, 31, 58,
+  156, 6, 15, 0, 58, 0, 0, 0, 0, 18,
+  0, 18, 5, 27, 0, 0, 53, 31, 0, 18,
+  0, 0, 0, 47, 40, 0, 10, 0, 0, 9,
+  0, 6, 28, 0, 0, 0, 0, 7, 44, 0,
+  48, 45, 0, 16, 17, 16, 28, 6, 22, 3,
+  0, 16, 38, 0, 14, 0, 0, 13, 0, 23,
+  45, 25, 8, 25, 0, 0, 67, 0, 51, 0,
+  0, 39, 3, 0, 27, 11, 67, 0, 18, 0,
+  0, 0, 20, 21, 9, 43, 3, 0, 12, 0,
+  0, 0, 64, 0, 5, 0, 0, 0, 55, 0,
+  56, 59, 50, 27, 4, 0, 2, 0, 0, 0,
+  8, 0, 48, 60, 4, 28, 76, 49, 0, 0,
+  0, 6, 1, 61, 24, 0, 35, 40, 0, 0,
+  13, 0, 67, 0, 0, 0, 0, 0, 0, 1,
+  0, 66, 2, 0, 30, 28, 26, 42, 0, 12,
+  0, 69, 96, 0, 23, 0, 0, 0, 0, 0,
+  51, 0, 0, 65, 0, 8, 82, 0, 40, 45,
+  0, 20, 0, 33, 32, 0, 14, 3, 0, 16,
+  42, 0, 37, 0, 0, 30, 0, 27, 36, 9,
+  13, 0, 0, 22, 2, 0, 70, 5, 0, 64,
+  0, 23, 40, 0, 76, 0, 6, 0, 58, 8,
+  17, 40, 5, 0, 26, 0, 1, 0, 0, 0,
+  39, 0, 71, 0, 10, 9, 14, 0, 2, 55,
+  59, 38, 4, 35, 16, 13, 17, 0, 0, 16,
+  84, 0, 0, 22, 51, 18, 0, 0, 0, 56,
+  0, 33, 67, 0, 5, 30, 0, 0, 0, 43,
+  70, 0, 18, 0, 0, 0, 0, 41, 0, 35,
+  57, 2, 29, 80, 44, 19, 0, 21, 0, 34,
+  36, 10, 35, 0, 10, 0, 0, 0, 30, 26,
+  0, 32, 0, 0, 35, 1, 27, 0, 0, 17,
+  9, 19, 26, 0, 10, 16, 0, 22, 23, 0,
+  61, 69, 0, 5, 0, 0, 0, 42, 5, 0,
+  0, 31, 0, 24, 35, 0, 0, 65, 2, 0,
+  10, 12, 63, 0, 37, 0, 27, 0, 0, 14,
+  0, 0, 0, 0, 0, 0, 0, 0, 4, 0,
+  41, 0, 35, 0, 8, 0, 47, 23, 86, 28,
+  0, 0, 29, 6, 18, 0, 12, 0, 0, 94,
+  0, 55, 94, 25, 14, 29, 7, 39, 13, 18,
+  25, 0, 29, 32, 164, 9, 5, 45, 79, 0,
+  0, 0, 0, 37, 0, 0, 0, 4, 0, 10,
+  7, 71, 53, 0, 0, 0, 0, 40, 22, 15,
+  17, 0, 13, 0, 0, 3, 39, 29, 0, 0,
+  0, 0, 72, 0, 119, 51, 0, 0, 21, 0,
+  24, 0, 65, 11, 0, 23, 14, 0, 42, 0,
+  0, 26, 0, 0, 59, 5, 0, 16, 0, 5,
+  15, 0, 38, 1, 14, 93, 25, 0, 14, 51,
+  54, 47, 12, 0, 25, 0, 4, 10, 0, 41,
+  10, 0, 18, 0, 17, 0, 59, 0, 0, 0,
+  0, 24, 48, 21, 43, 69, 0, 8, 5, 11,
+  0, 0, 0, 0, 0, 0, 16, 73, 0, 0,
+  82, 18, 0, 0, 0, 41, 0, 50, 15, 0,
+  5, 16, 0, 0, 0, 19, 83, 23, 0, 0,
+  0, 9, 0, 0, 0, 6, 0, 0, 9, 74,
+  35, 102, 0, 0, 0, 29, 56, 0, 22, 0,
+  18, 0, 0, 0, 78, 24, 0, 51, 0, 0,
+  97, 0, 107, 49, 0, 0, 4, 13, 45, 0,
+  27, 0, 0, 5, 25, 0, 35, 12, 0, 12,
+  0, 6, 0, 6, 0, 26, 0, 19, 1, 0,
+  34, 0, 12, 95, 20, 81, 35, 21, 44, 44,
+  10, 0, 51, 0, 0, 63, 0, 7, 0, 0,
+  0, 0, 11, 0, 22, 0, 33, 0, 0, 27,
+  27, 0, 0, 39, 39, 29, 0, 48, 7, 15,
+  23, 0, 0, 11, 81, 0, 0, 23, 58, 7,
+  0, 0, 0, 63, 0, 21, 41, 0, 0, 12,
+  0, 0, 0, 32, 67, 3, 1, 0, 0, 13,
+  0, 47, 0, 18, 41, 13, 22, 69, 25, 53,
+  0, 12, 0, 37, 21, 7, 22, 0, 22, 0,
+  0, 0, 16, 31, 0, 29, 0, 0, 7, 0,
+  37, 0, 18, 0, 9, 21, 4, 0, 5, 11,
+  0, 39, 27, 0, 62, 62, 0, 0, 0, 0,
+  0, 18, 1, 0, 0, 19, 0, 19, 32, 0,
+  0, 78, 11, 0, 0, 10, 15, 0, 33, 0,
+  0, 0, 0, 8, 0, 0, 0, 0, 7, 0,
+  0, 0, 0, 0, 38, 0, 39, 0, 9, 0,
+  27, 77, 56, 1, 0, 0, 53, 33, 0, 26,
+  0, 19, 15, 40, 3, 80, 27, 70, 9, 40,
+  13, 19, 51, 56, 1, 0, 62, 39, 168, 33,
+  0, 2, 112, 0, 35, 0, 0, 8, 0, 15,
+  15, 0, 16, 4, 70, 57, 0, 21, 0, 58,
+  0, 81, 74, 0, 31, 0, 4, 0, 0, 0,
+  31, 0, 5, 36, 0, 9, 25, 0, 0, 65,
+  0, 19, 22, 10, 17, 20, 19, 22, 19, 0,
+  39, 0, 23, 18, 0, 9, 5, 21, 68, 17,
+  39, 0, 0, 0, 34, 0, 67, 16, 7, 35,
+  9, 16, 42, 18, 111, 0, 19, 7, 30, 4,
+  45, 33, 26, 6, 0, 0, 14, 0, 1, 30,
+  86, 0, 9, 0, 3, 0, 26, 19, 51, 73,
+  59, 31, 0, 25, 25, 27, 1, 0, 0, 49,
+  62, 54, 0, 17, 9, 31, 5, 0, 0, 97,
+  24, 47, 40, 0, 67, 36, 173, 0, 0, 93,
+  100, 0, 16, 5, 0, 0, 0, 8, 0, 0,
+  58, 12, 35, 124, 53, 23, 0, 49, 0, 76,
+  26, 0, 69, 0, 16, 0, 0, 0, 74, 49,
+  11, 40, 2, 17, 33, 10, 4, 69, 21, 19,
+  13, 0, 5, 0, 39, 35, 1, 0, 24, 0,
+  46, 72, 0, 11, 18, 1, 41, 28, 0, 0,
+  0, 0, 0, 0, 56, 0, 0, 45, 33, 55,
+  30, 39, 114, 0, 28, 15, 40, 0, 15, 24,
+  15, 0, 0, 0, 36, 0, 25, 27, 59, 0,
+  0, 0, 16, 0, 11, 50, 1, 0, 0, 19,
+  11, 92, 28, 0, 0, 0, 0, 57, 41, 55,
+  0, 0, 0, 21, 17, 3, 0, 71, 14, 58,
+  40, 0, 38, 15, 173, 20, 0, 66, 63, 35,
+  0, 0, 0, 0, 0, 44, 0, 0, 10, 45,
+  6, 158, 67, 62, 0, 26, 0, 54, 50, 0,
+  21, 0, 34, 0, 34, 0, 70, 66, 0, 18,
+  13, 4, 36, 35, 62, 39, 52, 9, 43, 0,
+  28, 0, 37, 0, 0, 0, 49, 0, 22, 62,
+  0, 0, 39, 14, 21, 0, 0, 25, 16, 0,
+  24, 37, 0, 0, 11, 49, 15, 31, 12, 45,
+  82, 9, 31, 0, 0, 16, 0, 14, 0, 7,
+  0, 44, 106, 21, 47, 22, 46, 0, 0, 0,
+  16, 0, 13, 16, 56, 59, 50, 27, 4, 0,
+  2, 0, 0, 0, 8, 0, 48, 60, 4, 28,
+  76, 49, 0, 0, 0, 6, 1, 61, 24, 0,
+  35, 40, 0, 0, 13, 0, 67, 0, 0, 0,
+  0, 0, 0, 1, 0, 66, 2, 0, 30, 28,
+  26, 42, 0, 12, 0, 69, 96, 0, 23, 0,
+  0, 0, 0, 0, 51, 0, 0, 65, 0, 8,
+  82, 0, 40, 45, 0, 20, 0, 33, 32, 0,
+  14, 3, 0, 16, 42, 0, 37, 0, 0, 30,
+  0, 27, 36, 9, 13, 0, 0, 22, 2, 0,
+  70, 5, 0, 64, 0, 23, 40, 0, 76, 0,
+  6, 0, 58, 8, 17, 40, 5, 0, 26, 0,
+  1, 0, 0, 0, 39, 0, 71, 0, 10, 9,
+  14, 0, 2, 55, 59, 38, 4, 35, 16, 13,
+  17, 0, 0, 16, 84, 0, 0, 22, 51, 18,
+  0, 0, 0, 56, 0, 33, 67, 0, 5, 30,
+  0, 0, 0, 43, 70, 0, 18, 0, 0, 0,
+  0, 41, 0, 35, 57, 2, 29, 80, 44, 19,
+  0, 21, 0, 34, 36, 10, 35, 0, 10, 0,
+  0, 0, 30, 26, 0, 32, 0, 0, 35, 1,
+  27, 0, 0, 17, 9, 19, 26, 0, 10, 16,
+  0, 22, 23, 0, 61, 69, 0, 5, 0, 0,
+  0, 42, 5, 0, 0, 31, 0, 24, 35, 0,
+  0, 65, 2, 0, 10, 12, 63, 0, 37, 0,
+  27, 0, 0, 14, 0, 0, 0, 0, 0, 0,
+  0, 0, 4, 0, 41, 0, 35, 0, 8, 0,
+  0, 0, 0, 18, 14, 124, 8, 0, 7, 0,
+  0, 29, 52, 11, 0, 6, 15, 0, 0, 0,
+  0, 77, 2, 24, 40, 0, 0, 9, 0, 14,
+  0, 31, 15, 32, 0, 0, 0, 21, 0, 76,
+  0, 37, 0, 65, 12, 85, 61, 31, 0, 0,
+  0, 31, 31, 4, 2, 0, 40, 0, 18, 0,
+  23, 69, 0, 16, 12, 9, 0, 29, 58, 0,
+  39, 20, 11, 0, 25, 21, 19, 0, 0, 29,
+  42, 0, 16, 44, 15, 0, 11, 0, 0, 8,
+  0, 6, 0, 0, 4, 72, 0, 0, 0, 72,
+  0, 0, 4, 12, 57, 0, 27, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 77, 0, 47, 0,
+  6, 3, 0, 0, 55, 0, 22, 0, 43, 69,
+  0, 8, 5, 11, 0, 0, 0, 0, 0, 0,
+  16, 73, 0, 0, 82, 18, 0, 0, 0, 41,
+  0, 50, 15, 0, 5, 16, 0, 0, 0, 19,
+  83, 23, 0, 0, 0, 9, 0, 0, 0, 6,
+  0, 0, 9, 74, 35, 102, 0, 0, 0, 29,
+  56, 0, 22, 0, 18, 0, 0, 0, 78, 24,
+  0, 51, 0, 0, 97, 0, 107, 49, 0, 0,
+  4, 13, 45, 0, 27, 0, 0, 5, 25, 0,
+  35, 12, 0, 12, 0, 6, 0, 6, 0, 26,
+  0, 19, 1, 0, 34, 0, 12, 95, 20, 81,
+  35, 21, 44, 44, 10, 0, 51, 0, 0, 63,
+  0, 7, 0, 0, 0, 0, 11, 0, 22, 0,
+  33, 0, 0, 27, 27, 0, 0, 39, 39, 29,
+  0, 48, 7, 15, 23, 0, 0, 11, 81, 0,
+  0, 23, 58, 7, 0, 0, 0, 63, 0, 21,
+  41, 0, 0, 12, 0, 0, 0, 32, 67, 3,
+  1, 0, 0, 13, 0, 47, 0, 18, 41, 13,
+  22, 69, 25, 53, 0, 12, 0, 37, 21, 7,
+  22, 0, 22, 0, 0, 0, 16, 31, 0, 29,
+  0, 0, 7, 0, 37, 0, 18, 0, 9, 21,
+  4, 0, 5, 11, 0, 39, 27, 0, 62, 62,
+  0, 0, 0, 0, 0, 18, 1, 0, 0, 19,
+  0, 19, 32, 0, 0, 78, 11, 0, 0, 10,
+  15, 0, 33, 0, 0, 0, 0, 8, 0, 0,
+  0, 0, 7, 0, 0, 0, 0, 0, 38, 0,
+  39, 0, 9, 0, 0, 0, 0, 12, 0, 128,
+  4, 0, 24, 0, 0, 24, 44, 0, 0, 3,
+  15, 0, 0, 0, 17, 87, 14, 19, 11, 0,
+  0, 0, 0, 0, 0, 22, 19, 26, 0, 6,
+  0, 37, 0, 56, 0, 21, 0, 56, 0, 77,
+  54, 47, 0, 0, 0, 41, 15, 0, 2, 0,
+  67, 0, 29, 0, 3, 66, 0, 12, 54, 5,
+  0, 16, 73, 0, 77, 17, 14, 1, 0, 19,
+  20, 20, 0, 39, 27, 0, 45, 41, 10, 0,
+  5, 0, 0, 0, 0, 17, 0, 0, 0, 33,
+  0, 0, 7, 75, 14, 0, 0, 3, 5, 0,
+  19, 0, 0, 0, 0, 0, 0, 14, 0, 0,
+  93, 0, 37, 0, 0, 0, 0, 0, 36, 0,
+  0, 0, 51, 73, 59, 31, 0, 25, 25, 27,
+  1, 0, 0, 49, 62, 54, 0, 17, 9, 31,
+  5, 0, 0, 97, 24, 47, 40, 0, 67, 36,
+  173, 0, 0, 93, 100, 0, 16, 5, 0, 0,
+  0, 8, 0, 0, 58, 12, 35, 124, 53, 23,
+  0, 49, 0, 76, 26, 0, 69, 0, 16, 0,
+  0, 0, 74, 49, 11, 40, 2, 17, 33, 10,
+  4, 69, 21, 19, 13, 0, 5, 0, 39, 35,
+  1, 0, 24, 0, 46, 72, 0, 11, 18, 1,
+  41, 28, 0, 0, 0, 0, 0, 0, 56, 0,
+  0, 45, 33, 55, 30, 39, 114, 0, 28, 15,
+  40, 0, 15, 24, 15, 0, 0, 0, 36, 0,
+  25, 27, 59, 0, 0, 0, 16, 0, 11, 50,
+  1, 0, 0, 19, 11, 92, 28, 0, 0, 0,
+  0, 57, 41, 55, 0, 0, 0, 21, 17, 3,
+  0, 71, 14, 58, 40, 0, 38, 15, 173, 20,
+  0, 66, 63, 35, 0, 0, 0, 0, 0, 44,
+  0, 0, 10, 45, 6, 158, 67, 62, 0, 26,
+  0, 54, 50, 0, 21, 0, 34, 0, 34, 0,
+  70, 66, 0, 18, 13, 4, 36, 35, 62, 39,
+  52, 9, 43, 0, 28, 0, 37, 0, 0, 0,
+  49, 0, 22, 62, 0, 0, 39, 14, 21, 0,
+  0, 25, 16, 0, 24, 37, 0, 0, 11, 49,
+  15, 31, 12, 45, 82, 9, 31, 0, 0, 16,
+  0, 14, 0, 7, 0, 44, 106, 21, 47, 22,
+  46, 0, 0, 0, 16, 0, 13, 16, 0, 38,
+  0, 0, 45, 3, 47, 0, 0, 5, 2, 35,
+  43, 41, 0, 12, 6, 26, 23, 27, 41, 0,
+  0, 68, 18, 30, 36, 25, 149, 46, 0, 0,
+  61, 42, 0, 0, 0, 0, 0, 81, 0, 0,
+  0, 48, 15, 76, 31, 35, 0, 47, 0, 53,
+  104, 0, 0, 15, 21, 0, 0, 5, 36, 26,
+  0, 63, 0, 10, 50, 5, 36, 4, 6, 13,
+  12, 0, 42, 49, 0, 0, 30, 0, 84, 0,
+  8, 23, 8, 1, 28, 38, 67, 0, 15, 10,
+  39, 0, 22, 34, 0, 0, 46, 45, 0, 15,
+  23, 0, 43, 0, 19, 15, 9, 58, 9, 7,
+  0, 4, 0, 0, 41, 21, 33, 22, 54, 6,
+  20, 0, 41, 0, 6, 0, 2, 55, 59, 38,
+  4, 35, 16, 13, 17, 0, 0, 16, 84, 0,
+  0, 22, 51, 18, 0, 0, 0, 56, 0, 33,
+  67, 0, 5, 30, 0, 0, 0, 43, 70, 0,
+  18, 0, 0, 0, 0, 41, 0, 35, 57, 2,
+  29, 80, 44, 19, 0, 21, 0, 34, 36, 10,
+  35, 0, 10, 0, 0, 0, 30, 26, 0, 32,
+  0, 0, 35, 1, 27, 0, 0, 17, 9, 19,
+  26, 0, 10, 16, 0, 22, 23, 0, 61, 69,
+  0, 5, 0, 0, 0, 42, 5, 0, 0, 31,
+  0, 24, 35, 0, 0, 65, 2, 0, 10, 12,
+  63, 0, 37, 0, 27, 0, 0, 14, 0, 0,
+  0, 0, 0, 0, 0, 0, 4, 0, 41, 0,
+  35, 0, 8, 0, 0, 0, 0, 18, 14, 124,
+  8, 0, 7, 0, 0, 29, 52, 11, 0, 6,
+  15, 0, 0, 0, 0, 77, 2, 24, 40, 0,
+  0, 9, 0, 14, 0, 31, 15, 32, 0, 0,
+  0, 21, 0, 76, 0, 37, 0, 65, 12, 85,
+  61, 31, 0, 0, 0, 31, 31, 4, 2, 0,
+  40, 0, 18, 0, 23, 69, 0, 16, 12, 9,
+  0, 29, 58, 0, 39, 20, 11, 0, 25, 21,
+  19, 0, 0, 29, 42, 0, 16, 44, 15, 0,
+  11, 0, 0, 8, 0, 6, 0, 0, 4, 72,
+  0, 0, 0, 72, 0, 0, 4, 12, 57, 0,
+  27, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  77, 0, 47, 0, 6, 3, 0, 0, 55, 0,
+  22, 0, 0, 12, 0, 0, 34, 31, 37, 0,
+  16, 0, 1, 11, 52, 11, 10, 28, 23, 12,
+  0, 12, 51, 0, 0, 50, 24, 48, 0, 15,
+  0, 35, 0, 0, 38, 48, 0, 0, 0, 6,
+  0, 75, 0, 43, 0, 59, 29, 41, 15, 15,
+  0, 19, 0, 15, 107, 18, 0, 0, 17, 0,
+  0, 28, 25, 21, 0, 41, 0, 0, 45, 6,
+  26, 0, 0, 8, 0, 14, 33, 51, 4, 0,
+  0, 28, 84, 14, 0, 6, 19, 0, 12, 21,
+  18, 26, 0, 9, 9, 21, 0, 72, 0, 4,
+  31, 72, 0, 0, 2, 0, 39, 0, 26, 7,
+  9, 48, 0, 0, 0, 3, 0, 0, 39, 24,
+  41, 0, 37, 0, 84, 0, 64, 0, 13, 0,
+  0, 39, 39, 29, 0, 48, 7, 15, 23, 0,
+  0, 11, 81, 0, 0, 23, 58, 7, 0, 0,
+  0, 63, 0, 21, 41, 0, 0, 12, 0, 0,
+  0, 32, 67, 3, 1, 0, 0, 13, 0, 47,
+  0, 18, 41, 13, 22, 69, 25, 53, 0, 12,
+  0, 37, 21, 7, 22, 0, 22, 0, 0, 0,
+  16, 31, 0, 29, 0, 0, 7, 0, 37, 0,
+  18, 0, 9, 21, 4, 0, 5, 11, 0, 39,
+  27, 0, 62, 62, 0, 0, 0, 0, 0, 18,
+  1, 0, 0, 19, 0, 19, 32, 0, 0, 78,
+  11, 0, 0, 10, 15, 0, 33, 0, 0, 0,
+  0, 8, 0, 0, 0, 0, 7, 0, 0, 0,
+  0, 0, 38, 0, 39, 0, 9, 0, 0, 0,
+  0, 12, 0, 128, 4, 0, 24, 0, 0, 24,
+  44, 0, 0, 3, 15, 0, 0, 0, 17, 87,
+  14, 19, 11, 0, 0, 0, 0, 0, 0, 22,
+  19, 26, 0, 6, 0, 37, 0, 56, 0, 21,
+  0, 56, 0, 77, 54, 47, 0, 0, 0, 41,
+  15, 0, 2, 0, 67, 0, 29, 0, 3, 66,
+  0, 12, 54, 5, 0, 16, 73, 0, 77, 17,
+  14, 1, 0, 19, 20, 20, 0, 39, 27, 0,
+  45, 41, 10, 0, 5, 0, 0, 0, 0, 17,
+  0, 0, 0, 33, 0, 0, 7, 75, 14, 0,
+  0, 3, 5, 0, 19, 0, 0, 0, 0, 0,
+  0, 14, 0, 0, 93, 0, 37, 0, 0, 0,
+  0, 0, 36, 0, 0, 0, 0, 0, 0, 0,
+  0, 48, 47, 0, 22, 0, 0, 0, 38, 0,
+  10, 49, 31, 17, 0, 15, 62, 0, 0, 40,
+  0, 20, 12, 0, 0, 26, 0, 0, 64, 55,
+  8, 0, 0, 16, 0, 41, 0, 28, 0, 56,
+  0, 45, 21, 45, 0, 12, 2, 10, 93, 9,
+  0, 9, 48, 0, 0, 35, 16, 4, 0, 1,
+  0, 0, 17, 7, 42, 0, 2, 3, 0, 21,
+  13, 42, 3, 0, 0, 26, 69, 0, 18, 2,
+  18, 0, 12, 0, 9, 8, 0, 31, 0, 8,
+  5, 29, 0, 0, 36, 54, 18, 0, 0, 0,
+  1, 0, 24, 4, 0, 31, 0, 1, 0, 19,
+  0, 0, 51, 3, 32, 0, 21, 0, 83, 0,
+  35, 0, 4, 0, 1, 0, 0, 19, 11, 92,
+  28, 0, 0, 0, 0, 57, 41, 55, 0, 0,
+  0, 21, 17, 3, 0, 71, 14, 58, 40, 0,
+  38, 15, 173, 20, 0, 66, 63, 35, 0, 0,
+  0, 0, 0, 44, 0, 0, 10, 45, 6, 158,
+  67, 62, 0, 26, 0, 54, 50, 0, 21, 0,
+  34, 0, 34, 0, 70, 66, 0, 18, 13, 4,
+  36, 35, 62, 39, 52, 9, 43, 0, 28, 0,
+  37, 0, 0, 0, 49, 0, 22, 62, 0, 0,
+  39, 14, 21, 0, 0, 25, 16, 0, 24, 37,
+  0, 0, 11, 49, 15, 31, 12, 45, 82, 9,
+  31, 0, 0, 16, 0, 14, 0, 7, 0, 44,
+  106, 21, 47, 22, 46, 0, 0, 0, 16, 0,
+  13, 16, 0, 38, 0, 0, 45, 3, 47, 0,
+  0, 5, 2, 35, 43, 41, 0, 12, 6, 26,
+  23, 27, 41, 0, 0, 68, 18, 30, 36, 25,
+  149, 46, 0, 0, 61, 42, 0, 0, 0, 0,
+  0, 81, 0, 0, 0, 48, 15, 76, 31, 35,
+  0, 47, 0, 53, 104, 0, 0, 15, 21, 0,
+  0, 5, 36, 26, 0, 63, 0, 10, 50, 5,
+  36, 4, 6, 13, 12, 0, 42, 49, 0, 0,
+  30, 0, 84, 0, 8, 23, 8, 1, 28, 38,
+  67, 0, 15, 10, 39, 0, 22, 34, 0, 0,
+  46, 45, 0, 15, 23, 0, 43, 0, 19, 15,
+  9, 58, 9, 7, 0, 4, 0, 0, 41, 21,
+  33, 22, 54, 6, 20, 0, 41, 0, 6, 0,
+  0, 46, 0, 5, 8, 0, 87, 3, 13, 14,
+  0, 39, 38, 29, 17, 42, 21, 66, 26, 57,
+  83, 0, 35, 35, 10, 13, 59, 37, 156, 43,
+  0, 0, 97, 0, 28, 0, 0, 0, 0, 60,
+  0, 0, 0, 58, 6, 89, 17, 14, 0, 43,
+  0, 39, 81, 11, 0, 0, 23, 0, 0, 26,
+  0, 12, 14, 12, 0, 0, 12, 25, 19, 1,
+  23, 0, 31, 0, 56, 15, 12, 6, 36, 0,
+  63, 0, 17, 12, 2, 0, 24, 1, 58, 22,
+  24, 0, 0, 0, 11, 31, 0, 0, 72, 22,
+  0, 0, 23, 0, 40, 0, 15, 32, 13, 36,
+  18, 8, 0, 1, 0, 0, 17, 8, 16, 23,
+  55, 3, 28, 0, 23, 0, 16, 0, 0, 0,
+  0, 18, 14, 124, 8, 0, 7, 0, 0, 29,
+  52, 11, 0, 6, 15, 0, 0, 0, 0, 77,
+  2, 24, 40, 0, 0, 9, 0, 14, 0, 31,
+  15, 32, 0, 0, 0, 21, 0, 76, 0, 37,
+  0, 65, 12, 85, 61, 31, 0, 0, 0, 31,
+  31, 4, 2, 0, 40, 0, 18, 0, 23, 69,
+  0, 16, 12, 9, 0, 29, 58, 0, 39, 20,
+  11, 0, 25, 21, 19, 0, 0, 29, 42, 0,
+  16, 44, 15, 0, 11, 0, 0, 8, 0, 6,
+  0, 0, 4, 72, 0, 0, 0, 72, 0, 0,
+  4, 12, 57, 0, 27, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 77, 0, 47, 0, 6, 3,
+  0, 0, 55, 0, 22, 0, 0, 12, 0, 0,
+  34, 31, 37, 0, 16, 0, 1, 11, 52, 11,
+  10, 28, 23, 12, 0, 12, 51, 0, 0, 50,
+  24, 48, 0, 15, 0, 35, 0, 0, 38, 48,
+  0, 0, 0, 6, 0, 75, 0, 43, 0, 59,
+  29, 41, 15, 15, 0, 19, 0, 15, 107, 18,
+  0, 0, 17, 0, 0, 28, 25, 21, 0, 41,
+  0, 0, 45, 6, 26, 0, 0, 8, 0, 14,
+  33, 51, 4, 0, 0, 28, 84, 14, 0, 6,
+  19, 0, 12, 21, 18, 26, 0, 9, 9, 21,
+  0, 72, 0, 4, 31, 72, 0, 0, 2, 0,
+  39, 0, 26, 7, 9, 48, 0, 0, 0, 3,
+  0, 0, 39, 24, 41, 0, 37, 0, 84, 0,
+  64, 0, 13, 0, 0, 32, 0, 0, 20, 0,
+  56, 0, 35, 0, 0, 29, 28, 20, 52, 24,
+  39, 50, 3, 36, 95, 0, 10, 21, 21, 25,
+  9, 34, 0, 29, 0, 0, 63, 0, 10, 0,
+  0, 0, 0, 48, 0, 3, 0, 63, 16, 61,
+  5, 1, 0, 6, 0, 3, 79, 33, 0, 0,
+  18, 0, 0, 7, 0, 7, 0, 0, 0, 0,
+  32, 20, 20, 0, 0, 0, 0, 0, 62, 0,
+  13, 2, 0, 6, 67, 26, 0, 0, 6, 0,
+  7, 0, 11, 49, 18, 0, 0, 4, 0, 55,
+  0, 6, 64, 36, 0, 0, 3, 0, 34, 0,
+  22, 9, 31, 35, 0, 0, 0, 0, 0, 0,
+  14, 2, 12, 0, 45, 0, 77, 0, 41, 0,
+  26, 0, 0, 0, 0, 12, 0, 128, 4, 0,
+  24, 0, 0, 24, 44, 0, 0, 3, 15, 0,
+  0, 0, 17, 87, 14, 19, 11, 0, 0, 0,
+  0, 0, 0, 22, 19, 26, 0, 6, 0, 37,
+  0, 56, 0, 21, 0, 56, 0, 77, 54, 47,
+  0, 0, 0, 41, 15, 0, 2, 0, 67, 0,
+  29, 0, 3, 66, 0, 12, 54, 5, 0, 16,
+  73, 0, 77, 17, 14, 1, 0, 19, 20, 20,
+  0, 39, 27, 0, 45, 41, 10, 0, 5, 0,
+  0, 0, 0, 17, 0, 0, 0, 33, 0, 0,
+  7, 75, 14, 0, 0, 3, 5, 0, 19, 0,
+  0, 0, 0, 0, 0, 14, 0, 0, 93, 0,
+  37, 0, 0, 0, 0, 0, 36, 0, 0, 0,
+  0, 0, 0, 0, 0, 48, 47, 0, 22, 0,
+  0, 0, 38, 0, 10, 49, 31, 17, 0, 15,
+  62, 0, 0, 40, 0, 20, 12, 0, 0, 26,
+  0, 0, 64, 55, 8, 0, 0, 16, 0, 41,
+  0, 28, 0, 56, 0, 45, 21, 45, 0, 12,
+  2, 10, 93, 9, 0, 9, 48, 0, 0, 35,
+  16, 4, 0, 1, 0, 0, 17, 7, 42, 0,
+  2, 3, 0, 21, 13, 42, 3, 0, 0, 26,
+  69, 0, 18, 2, 18, 0, 12, 0, 9, 8,
+  0, 31, 0, 8, 5, 29, 0, 0, 36, 54,
+  18, 0, 0, 0, 1, 0, 24, 4, 0, 31,
+  0, 1, 0, 19, 0, 0, 51, 3, 32, 0,
+  21, 0, 83, 0, 35, 0, 4, 0, 0, 9,
+  0, 0, 15, 0, 57, 0, 37, 0, 0, 0,
+  30, 12, 51, 40, 45, 47, 0, 28, 101, 0,
+  0, 27, 0, 9, 25, 8, 0, 23, 0, 0,
+  52, 4, 22, 0, 0, 12, 0, 35, 0, 7,
+  0, 70, 5, 54, 4, 16, 0, 0, 13, 8,
+  68, 27, 0, 0, 28, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 23, 1, 27, 0, 0, 0,
+  0, 10, 48, 0, 7, 9, 0, 11, 57, 13,
+  9, 0, 13, 0, 0, 0, 22, 29, 9, 0,
+  0, 15, 0, 34, 0, 0, 59, 37, 0, 0,
+  0, 0, 12, 0, 17, 14, 11, 27, 0, 0,
+  0, 5, 0, 0, 24, 0, 14, 0, 27, 0,
+  77, 0, 21, 0, 13, 0, 0, 38, 0, 0,
+  45, 3, 47, 0, 0, 5, 2, 35, 43, 41,
+  0, 12, 6, 26, 23, 27, 41, 0, 0, 68,
+  18, 30, 36, 25, 149, 46, 0, 0, 61, 42,
+  0, 0, 0, 0, 0, 81, 0, 0, 0, 48,
+  15, 76, 31, 35, 0, 47, 0, 53, 104, 0,
+  0, 15, 21, 0, 0, 5, 36, 26, 0, 63,
+  0, 10, 50, 5, 36, 4, 6, 13, 12, 0,
+  42, 49, 0, 0, 30, 0, 84, 0, 8, 23,
+  8, 1, 28, 38, 67, 0, 15, 10, 39, 0,
+  22, 34, 0, 0, 46, 45, 0, 15, 23, 0,
+  43, 0, 19, 15, 9, 58, 9, 7, 0, 4,
+  0, 0, 41, 21, 33, 22, 54, 6, 20, 0,
+  41, 0, 6, 0, 0, 46, 0, 5, 8, 0,
+  87, 3, 13, 14, 0, 39, 38, 29, 17, 42,
+  21, 66, 26, 57, 83, 0, 35, 35, 10, 13,
+  59, 37, 156, 43, 0, 0, 97, 0, 28, 0,
+  0, 0, 0, 60, 0, 0, 0, 58, 6, 89,
+  17, 14, 0, 43, 0, 39, 81, 11, 0, 0,
+  23, 0, 0, 26, 0, 12, 14, 12, 0, 0,
+  12, 25, 19, 1, 23, 0, 31, 0, 56, 15,
+  12, 6, 36, 0, 63, 0, 17, 12, 2, 0,
+  24, 1, 58, 22, 24, 0, 0, 0, 11, 31,
+  0, 0, 72, 22, 0, 0, 23, 0, 40, 0,
+  15, 32, 13, 36, 18, 8, 0, 1, 0, 0,
+  17, 8, 16, 23, 55, 3, 28, 0, 23, 0,
+  16, 0, 0, 26, 0, 19, 10, 0, 77, 11,
+  23, 31, 0, 35, 23, 57, 9, 52, 22, 74,
+  37, 27, 102, 0, 0, 31, 15, 13, 55, 46,
+  154, 59, 0, 4, 97, 0, 27, 0, 0, 0,
+  0, 55, 0, 0, 0, 52, 12, 66, 15, 9,
+  0, 41, 0, 76, 57, 46, 4, 14, 7, 0,
+  0, 16, 0, 0, 24, 8, 0, 8, 10, 17,
+  12, 30, 0, 0, 27, 0, 37, 13, 12, 0,
+  23, 0, 76, 0, 17, 2, 0, 0, 21, 18,
+  71, 15, 30, 0, 0, 0, 29, 12, 20, 0,
+  83, 41, 0, 0, 20, 0, 63, 0, 2, 35,
+  27, 25, 17, 5, 25, 0, 6, 0, 30, 0,
+  13, 13, 58, 0, 47, 0, 29, 0, 20, 0,
+  0, 12, 0, 0, 34, 31, 37, 0, 16, 0,
+  1, 11, 52, 11, 10, 28, 23, 12, 0, 12,
+  51, 0, 0, 50, 24, 48, 0, 15, 0, 35,
+  0, 0, 38, 48, 0, 0, 0, 6, 0, 75,
+  0, 43, 0, 59, 29, 41, 15, 15, 0, 19,
+  0, 15, 107, 18, 0, 0, 17, 0, 0, 28,
+  25, 21, 0, 41, 0, 0, 45, 6, 26, 0,
+  0, 8, 0, 14, 33, 51, 4, 0, 0, 28,
+  84, 14, 0, 6, 19, 0, 12, 21, 18, 26,
+  0, 9, 9, 21, 0, 72, 0, 4, 31, 72,
+  0, 0, 2, 0, 39, 0, 26, 7, 9, 48,
+  0, 0, 0, 3, 0, 0, 39, 24, 41, 0,
+  37, 0, 84, 0, 64, 0, 13, 0, 0, 32,
+  0, 0, 20, 0, 56, 0, 35, 0, 0, 29,
+  28, 20, 52, 24, 39, 50, 3, 36, 95, 0,
+  10, 21, 21, 25, 9, 34, 0, 29, 0, 0,
+  63, 0, 10, 0, 0, 0, 0, 48, 0, 3,
+  0, 63, 16, 61, 5, 1, 0, 6, 0, 3,
+  79, 33, 0, 0, 18, 0, 0, 7, 0, 7,
+  0, 0, 0, 0, 32, 20, 20, 0, 0, 0,
+  0, 0, 62, 0, 13, 2, 0, 6, 67, 26,
+  0, 0, 6, 0, 7, 0, 11, 49, 18, 0,
+  0, 4, 0, 55, 0, 6, 64, 36, 0, 0,
+  3, 0, 34, 0, 22, 9, 31, 35, 0, 0,
+  0, 0, 0, 0, 14, 2, 12, 0, 45, 0,
+  77, 0, 41, 0, 26, 0, 0, 27, 0, 15,
+  17, 0, 54, 0, 26, 19, 0, 24, 19, 41,
+  54, 36, 42, 53, 0, 29, 105, 0, 0, 24,
+  36, 35, 13, 47, 0, 36, 0, 0, 67, 9,
+  22, 0, 0, 0, 0, 30, 0, 0, 0, 58,
+  16, 44, 12, 18, 0, 3, 21, 11, 61, 51,
+  0, 0, 3, 0, 0, 16, 0, 0, 0, 0,
+  0, 0, 38, 18, 25, 0, 0, 0, 0, 0,
+  56, 0, 14, 7, 0, 10, 79, 42, 2, 0,
+  11, 0, 6, 6, 16, 33, 14, 0, 0, 12,
+  0, 42, 0, 6, 83, 38, 0, 0, 5, 0,
+  37, 0, 29, 9, 43, 27, 0, 0, 1, 0,
+  0, 0, 12, 0, 2, 0, 32, 0, 100, 0,
+  40, 0, 22, 0, 0, 0, 0, 0, 0, 48,
+  47, 0, 22, 0, 0, 0, 38, 0, 10, 49,
+  31, 17, 0, 15, 62, 0, 0, 40, 0, 20,
+  12, 0, 0, 26, 0, 0, 64, 55, 8, 0,
+  0, 16, 0, 41, 0, 28, 0, 56, 0, 45,
+  21, 45, 0, 12, 2, 10, 93, 9, 0, 9,
+  48, 0, 0, 35, 16, 4, 0, 1, 0, 0,
+  17, 7, 42, 0, 2, 3, 0, 21, 13, 42,
+  3, 0, 0, 26, 69, 0, 18, 2, 18, 0,
+  12, 0, 9, 8, 0, 31, 0, 8, 5, 29,
+  0, 0, 36, 54, 18, 0, 0, 0, 1, 0,
+  24, 4, 0, 31, 0, 1, 0, 19, 0, 0,
+  51, 3, 32, 0, 21, 0, 83, 0, 35, 0,
+  4, 0, 0, 9, 0, 0, 15, 0, 57, 0,
+  37, 0, 0, 0, 30, 12, 51, 40, 45, 47,
+  0, 28, 101, 0, 0, 27, 0, 9, 25, 8,
+  0, 23, 0, 0, 52, 4, 22, 0, 0, 12,
+  0, 35, 0, 7, 0, 70, 5, 54, 4, 16,
+  0, 0, 13, 8, 68, 27, 0, 0, 28, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 23, 1,
+  27, 0, 0, 0, 0, 10, 48, 0, 7, 9,
+  0, 11, 57, 13, 9, 0, 13, 0, 0, 0,
+  22, 29, 9, 0, 0, 15, 0, 34, 0, 0,
+  59, 37, 0, 0, 0, 0, 12, 0, 17, 14,
+  11, 27, 0, 0, 0, 5, 0, 0, 24, 0,
+  14, 0, 27, 0, 77, 0, 21, 0, 13, 0,
+  0, 33, 0, 0, 27, 0, 41, 0, 45, 22,
+  0, 7, 22, 44, 69, 48, 60, 49, 0, 17,
+  100, 0, 0, 26, 19, 29, 19, 25, 0, 21,
+  0, 0, 29, 10, 19, 0, 0, 21, 0, 35,
+  0, 0, 0, 56, 7, 31, 16, 4, 0, 0,
+  48, 0, 33, 46, 0, 2, 16, 0, 0, 12,
+  0, 0, 0, 0, 0, 0, 48, 0, 33, 0,
+  0, 0, 0, 6, 51, 0, 15, 23, 0, 30,
+  42, 35, 0, 0, 24, 0, 0, 0, 26, 42,
+  0, 0, 0, 46, 0, 27, 0, 13, 75, 38,
+  0, 0, 0, 0, 17, 0, 16, 5, 28, 44,
+  0, 0, 0, 5, 8, 0, 2, 0, 24, 0,
+  4, 0, 105, 0, 27, 6, 32, 0, 0, 46,
+  0, 5, 8, 0, 87, 3, 13, 14, 0, 39,
+  38, 29, 17, 42, 21, 66, 26, 57, 83, 0,
+  35, 35, 10, 13, 59, 37, 156, 43, 0, 0,
+  97, 0, 28, 0, 0, 0, 0, 60, 0, 0,
+  0, 58, 6, 89, 17, 14, 0, 43, 0, 39,
+  81, 11, 0, 0, 23, 0, 0, 26, 0, 12,
+  14, 12, 0, 0, 12, 25, 19, 1, 23, 0,
+  31, 0, 56, 15, 12, 6, 36, 0, 63, 0,
+  17, 12, 2, 0, 24, 1, 58, 22, 24, 0,
+  0, 0, 11, 31, 0, 0, 72, 22, 0, 0,
+  23, 0, 40, 0, 15, 32, 13, 36, 18, 8,
+  0, 1, 0, 0, 17, 8, 16, 23, 55, 3,
+  28, 0, 23, 0, 16, 0, 0, 26, 0, 19,
+  10, 0, 77, 11, 23, 31, 0, 35, 23, 57,
+  9, 52, 22, 74, 37, 27, 102, 0, 0, 31,
+  15, 13, 55, 46, 154, 59, 0, 4, 97, 0,
+  27, 0, 0, 0, 0, 55, 0, 0, 0, 52,
+  12, 66, 15, 9, 0, 41, 0, 76, 57, 46,
+  4, 14, 7, 0, 0, 16, 0, 0, 24, 8,
+  0, 8, 10, 17, 12, 30, 0, 0, 27, 0,
+  37, 13, 12, 0, 23, 0, 76, 0, 17, 2,
+  0, 0, 21, 18, 71, 15, 30, 0, 0, 0,
+  29, 12, 20, 0, 83, 41, 0, 0, 20, 0,
+  63, 0, 2, 35, 27, 25, 17, 5, 25, 0,
+  6, 0, 30, 0, 13, 13, 58, 0, 47, 0,
+  29, 0, 20, 0, 0, 16, 0, 14, 1, 0,
+  63, 29, 23, 32, 0, 13, 0, 45, 0, 47,
+  19, 68, 39, 6, 67, 0, 0, 42, 12, 16,
+  57, 47, 121, 62, 0, 0, 87, 0, 30, 0,
+  0, 0, 0, 41, 0, 0, 0, 17, 8, 43,
+  25, 0, 0, 37, 11, 79, 44, 41, 28, 6,
+  2, 20, 0, 16, 0, 0, 13, 18, 0, 16,
+  25, 5, 1, 40, 0, 0, 44, 0, 27, 34,
+  0, 0, 27, 0, 77, 0, 17, 14, 0, 0,
+  18, 24, 76, 0, 60, 4, 0, 4, 30, 0,
+  46, 0, 60, 49, 0, 0, 9, 0, 57, 0,
+  0, 18, 38, 31, 23, 17, 38, 0, 21, 0,
+  27, 0, 7, 10, 58, 0, 64, 0, 40, 0,
+  0, 0, 0, 32, 0, 0, 20, 0, 56, 0,
+  35, 0, 0, 29, 28, 20, 52, 24, 39, 50,
+  3, 36, 95, 0, 10, 21, 21, 25, 9, 34,
+  0, 29, 0, 0, 63, 0, 10, 0, 0, 0,
+  0, 48, 0, 3, 0, 63, 16, 61, 5, 1,
+  0, 6, 0, 3, 79, 33, 0, 0, 18, 0,
+  0, 7, 0, 7, 0, 0, 0, 0, 32, 20,
+  20, 0, 0, 0, 0, 0, 62, 0, 13, 2,
+  0, 6, 67, 26, 0, 0, 6, 0, 7, 0,
+  11, 49, 18, 0, 0, 4, 0, 55, 0, 6,
+  64, 36, 0, 0, 3, 0, 34, 0, 22, 9,
+  31, 35, 0, 0, 0, 0, 0, 0, 14, 2,
+  12, 0, 45, 0, 77, 0, 41, 0, 26, 0,
+  0, 27, 0, 15, 17, 0, 54, 0, 26, 19,
+  0, 24, 19, 41, 54, 36, 42, 53, 0, 29,
+  105, 0, 0, 24, 36, 35, 13, 47, 0, 36,
+  0, 0, 67, 9, 22, 0, 0, 0, 0, 30,
+  0, 0, 0, 58, 16, 44, 12, 18, 0, 3,
+  21, 11, 61, 51, 0, 0, 3, 0, 0, 16,
+  0, 0, 0, 0, 0, 0, 38, 18, 25, 0,
+  0, 0, 0, 0, 56, 0, 14, 7, 0, 10,
+  79, 42, 2, 0, 11, 0, 6, 6, 16, 33,
+  14, 0, 0, 12, 0, 42, 0, 6, 83, 38,
+  0, 0, 5, 0, 37, 0, 29, 9, 43, 27,
+  0, 0, 1, 0, 0, 0, 12, 0, 2, 0,
+  32, 0, 100, 0, 40, 0, 22, 0, 0, 22,
+  0, 0, 8, 0, 32, 0, 33, 28, 0, 1,
+  0, 29, 40, 48, 56, 56, 12, 13, 56, 0,
+  0, 29, 28, 42, 16, 56, 0, 19, 0, 0,
+  57, 2, 6, 0, 0, 0, 0, 24, 0, 0,
+  0, 16, 1, 14, 21, 10, 0, 5, 37, 5,
+  41, 38, 0, 11, 0, 24, 0, 42, 0, 0,
+  0, 0, 0, 0, 70, 24, 23, 0, 0, 0,
+  11, 21, 44, 0, 8, 0, 0, 12, 70, 39,
+  7, 8, 19, 29, 0, 28, 16, 3, 38, 30,
+  0, 36, 4, 7, 0, 4, 60, 56, 0, 0,
+  5, 0, 33, 0, 12, 9, 35, 35, 0, 12,
+  2, 0, 10, 0, 0, 0, 0, 0, 6, 0,
+  111, 0, 30, 0, 9, 0, 0, 9, 0, 0,
+  15, 0, 57, 0, 37, 0, 0, 0, 30, 12,
+  51, 40, 45, 47, 0, 28, 101, 0, 0, 27,
+  0, 9, 25, 8, 0, 23, 0, 0, 52, 4,
+  22, 0, 0, 12, 0, 35, 0, 7, 0, 70,
+  5, 54, 4, 16, 0, 0, 13, 8, 68, 27,
+  0, 0, 28, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 23, 1, 27, 0, 0, 0, 0, 10,
+  48, 0, 7, 9, 0, 11, 57, 13, 9, 0,
+  13, 0, 0, 0, 22, 29, 9, 0, 0, 15,
+  0, 34, 0, 0, 59, 37, 0, 0, 0, 0,
+  12, 0, 17, 14, 11, 27, 0, 0, 0, 5,
+  0, 0, 24, 0, 14, 0, 27, 0, 77, 0,
+  21, 0, 13, 0, 0, 33, 0, 0, 27, 0,
+  41, 0, 45, 22, 0, 7, 22, 44, 69, 48,
+  60, 49, 0, 17, 100, 0, 0, 26, 19, 29,
+  19, 25, 0, 21, 0, 0, 29, 10, 19, 0,
+  0, 21, 0, 35, 0, 0, 0, 56, 7, 31,
+  16, 4, 0, 0, 48, 0, 33, 46, 0, 2,
+  16, 0, 0, 12, 0, 0, 0, 0, 0, 0,
+  48, 0, 33, 0, 0, 0, 0, 6, 51, 0,
+  15, 23, 0, 30, 42, 35, 0, 0, 24, 0,
+  0, 0, 26, 42, 0, 0, 0, 46, 0, 27,
+  0, 13, 75, 38, 0, 0, 0, 0, 17, 0,
+  16, 5, 28, 44, 0, 0, 0, 5, 8, 0,
+  2, 0, 24, 0, 4, 0, 105, 0, 27, 6,
+  32, 0, 0, 33, 0, 0, 36, 0, 0, 3,
+  48, 28, 0, 0, 10, 59, 39, 46, 67, 44,
+  12, 0, 51, 0, 0, 36, 0, 22, 41, 60,
+  0, 0, 0, 0, 19, 0, 7, 0, 0, 22,
+  0, 24, 0, 0, 0, 4, 0, 17, 23, 0,
+  0, 0, 55, 0, 1, 17, 0, 0, 18, 15,
+  0, 17, 0, 0, 0, 0, 0, 0, 102, 0,
+  17, 0, 0, 0, 5, 41, 35, 0, 3, 53,
+  0, 13, 18, 38, 12, 42, 10, 28, 0, 30,
+  22, 26, 21, 17, 0, 42, 0, 0, 0, 2,
+  49, 55, 1, 0, 0, 0, 16, 0, 14, 19,
+  32, 69, 0, 3, 0, 0, 21, 0, 0, 0,
+  17, 0, 0, 13, 100, 0, 0, 0, 30, 37,
+  0, 26, 0, 19, 10, 0, 77, 11, 23, 31,
+  0, 35, 23, 57, 9, 52, 22, 74, 37, 27,
+  102, 0, 0, 31, 15, 13, 55, 46, 154, 59,
+  0, 4, 97, 0, 27, 0, 0, 0, 0, 55,
+  0, 0, 0, 52, 12, 66, 15, 9, 0, 41,
+  0, 76, 57, 46, 4, 14, 7, 0, 0, 16,
+  0, 0, 24, 8, 0, 8, 10, 17, 12, 30,
+  0, 0, 27, 0, 37, 13, 12, 0, 23, 0,
+  76, 0, 17, 2, 0, 0, 21, 18, 71, 15,
+  30, 0, 0, 0, 29, 12, 20, 0, 83, 41,
+  0, 0, 20, 0, 63, 0, 2, 35, 27, 25,
+  17, 5, 25, 0, 6, 0, 30, 0, 13, 13,
+  58, 0, 47, 0, 29, 0, 20, 0, 0, 16,
+  0, 14, 1, 0, 63, 29, 23, 32, 0, 13,
+  0, 45, 0, 47, 19, 68, 39, 6, 67, 0,
+  0, 42, 12, 16, 57, 47, 121, 62, 0, 0,
+  87, 0, 30, 0, 0, 0, 0, 41, 0, 0,
+  0, 17, 8, 43, 25, 0, 0, 37, 11, 79,
+  44, 41, 28, 6, 2, 20, 0, 16, 0, 0,
+  13, 18, 0, 16, 25, 5, 1, 40, 0, 0,
+  44, 0, 27, 34, 0, 0, 27, 0, 77, 0,
+  17, 14, 0, 0, 18, 24, 76, 0, 60, 4,
+  0, 4, 30, 0, 46, 0, 60, 49, 0, 0,
+  9, 0, 57, 0, 0, 18, 38, 31, 23, 17,
+  38, 0, 21, 0, 27, 0, 7, 10, 58, 0,
+  64, 0, 40, 0, 0, 0, 0, 26, 0, 7,
+  2, 0, 63, 38, 23, 37, 2, 6, 0, 40,
+  0, 45, 6, 67, 46, 14, 38, 0, 0, 48,
+  16, 24, 55, 58, 112, 45, 0, 0, 68, 0,
+  26, 0, 0, 0, 0, 44, 0, 0, 0, 2,
+  1, 25, 39, 0, 0, 36, 14, 72, 25, 35,
+  35, 0, 0, 49, 0, 21, 0, 0, 16, 34,
+  0, 26, 35, 0, 2, 44, 0, 0, 64, 0,
+  29, 35, 0, 1, 39, 0, 66, 5, 11, 30,
+  0, 6, 14, 27, 89, 0, 74, 5, 0, 3,
+  35, 0, 49, 0, 45, 48, 0, 0, 10, 0,
+  56, 0, 0, 23, 42, 24, 30, 23, 39, 0,
+  31, 0, 11, 0, 7, 13, 40, 0, 62, 0,
+  52, 0, 0, 2, 0, 27, 0, 15, 17, 0,
+  54, 0, 26, 19, 0, 24, 19, 41, 54, 36,
+  42, 53, 0, 29, 105, 0, 0, 24, 36, 35,
+  13, 47, 0, 36, 0, 0, 67, 9, 22, 0,
+  0, 0, 0, 30, 0, 0, 0, 58, 16, 44,
+  12, 18, 0, 3, 21, 11, 61, 51, 0, 0,
+  3, 0, 0, 16, 0, 0, 0, 0, 0, 0,
+  38, 18, 25, 0, 0, 0, 0, 0, 56, 0,
+  14, 7, 0, 10, 79, 42, 2, 0, 11, 0,
+  6, 6, 16, 33, 14, 0, 0, 12, 0, 42,
+  0, 6, 83, 38, 0, 0, 5, 0, 37, 0,
+  29, 9, 43, 27, 0, 0, 1, 0, 0, 0,
+  12, 0, 2, 0, 32, 0, 100, 0, 40, 0,
+  22, 0, 0, 22, 0, 0, 8, 0, 32, 0,
+  33, 28, 0, 1, 0, 29, 40, 48, 56, 56,
+  12, 13, 56, 0, 0, 29, 28, 42, 16, 56,
+  0, 19, 0, 0, 57, 2, 6, 0, 0, 0,
+  0, 24, 0, 0, 0, 16, 1, 14, 21, 10,
+  0, 5, 37, 5, 41, 38, 0, 11, 0, 24,
+  0, 42, 0, 0, 0, 0, 0, 0, 70, 24,
+  23, 0, 0, 0, 11, 21, 44, 0, 8, 0,
+  0, 12, 70, 39, 7, 8, 19, 29, 0, 28,
+  16, 3, 38, 30, 0, 36, 4, 7, 0, 4,
+  60, 56, 0, 0, 5, 0, 33, 0, 12, 9,
+  35, 35, 0, 12, 2, 0, 10, 0, 0, 0,
+  0, 0, 6, 0, 111, 0, 30, 0, 9, 0,
+  0, 40, 0, 0, 15, 0, 26, 0, 40, 45,
+  1, 0, 0, 24, 16, 54, 51, 59, 27, 8,
+  15, 0, 0, 41, 35, 63, 9, 78, 0, 0,
+  8, 0, 21, 0, 0, 0, 0, 0, 0, 35,
+  0, 0, 0, 0, 0, 0, 38, 0, 0, 5,
+  22, 8, 24, 27, 0, 0, 0, 65, 0, 36,
+  0, 0, 0, 33, 0, 2, 97, 14, 35, 0,
+  0, 0, 20, 36, 43, 5, 0, 0, 0, 9,
+  52, 53, 0, 20, 31, 37, 0, 46, 33, 0,
+  42, 41, 0, 48, 0, 0, 2, 16, 45, 62,
+  0, 0, 12, 0, 34, 0, 0, 17, 24, 34,
+  0, 27, 0, 0, 25, 0, 0, 14, 10, 0,
+  0, 8, 110, 0, 42, 0, 17, 9, 0, 33,
+  0, 0, 27, 0, 41, 0, 45, 22, 0, 7,
+  22, 44, 69, 48, 60, 49, 0, 17, 100, 0,
+  0, 26, 19, 29, 19, 25, 0, 21, 0, 0,
+  29, 10, 19, 0, 0, 21, 0, 35, 0, 0,
+  0, 56, 7, 31, 16, 4, 0, 0, 48, 0,
+  33, 46, 0, 2, 16, 0, 0, 12, 0, 0,
+  0, 0, 0, 0, 48, 0, 33, 0, 0, 0,
+  0, 6, 51, 0, 15, 23, 0, 30, 42, 35,
+  0, 0, 24, 0, 0, 0, 26, 42, 0, 0,
+  0, 46, 0, 27, 0, 13, 75, 38, 0, 0,
+  0, 0, 17, 0, 16, 5, 28, 44, 0, 0,
+  0, 5, 8, 0, 2, 0, 24, 0, 4, 0,
+  105, 0, 27, 6, 32, 0, 0, 33, 0, 0,
+  36, 0, 0, 3, 48, 28, 0, 0, 10, 59,
+  39, 46, 67, 44, 12, 0, 51, 0, 0, 36,
+  0, 22, 41, 60, 0, 0, 0, 0, 19, 0,
+  7, 0, 0, 22, 0, 24, 0, 0, 0, 4,
+  0, 17, 23, 0, 0, 0, 55, 0, 1, 17,
+  0, 0, 18, 15, 0, 17, 0, 0, 0, 0,
+  0, 0, 102, 0, 17, 0, 0, 0, 5, 41,
+  35, 0, 3, 53, 0, 13, 18, 38, 12, 42,
+  10, 28, 0, 30, 22, 26, 21, 17, 0, 42,
+  0, 0, 0, 2, 49, 55, 1, 0, 0, 0,
+  16, 0, 14, 19, 32, 69, 0, 3, 0, 0,
+  21, 0, 0, 0, 17, 0, 0, 13, 100, 0,
+  0, 0, 30, 37, 12, 0, 30, 0, 18, 0,
+  0, 0, 37, 30, 0, 0, 4, 71, 11, 0,
+  44, 48, 26, 0, 25, 1, 22, 8, 0, 6,
+  34, 49, 0, 0, 16, 0, 0, 5, 0, 0,
+  40, 32, 0, 1, 1, 0, 0, 0, 0, 0,
+  9, 0, 0, 0, 31, 0, 0, 10, 0, 0,
+  0, 51, 0, 0, 2, 6, 23, 5, 0, 0,
+  106, 5, 12, 82, 0, 0, 6, 39, 0, 0,
+  0, 50, 1, 0, 0, 34, 0, 54, 42, 31,
+  0, 69, 0, 0, 0, 56, 0, 0, 20, 0,
+  0, 15, 19, 45, 10, 6, 0, 0, 0, 0,
+  0, 21, 1, 57, 6, 0, 0, 0, 53, 11,
+  0, 0, 15, 0, 0, 26, 8, 0, 0, 12,
+  42, 48, 0, 16, 0, 14, 1, 0, 63, 29,
+  23, 32, 0, 13, 0, 45, 0, 47, 19, 68,
+  39, 6, 67, 0, 0, 42, 12, 16, 57, 47,
+  121, 62, 0, 0, 87, 0, 30, 0, 0, 0,
+  0, 41, 0, 0, 0, 17, 8, 43, 25, 0,
+  0, 37, 11, 79, 44, 41, 28, 6, 2, 20,
+  0, 16, 0, 0, 13, 18, 0, 16, 25, 5,
+  1, 40, 0, 0, 44, 0, 27, 34, 0, 0,
+  27, 0, 77, 0, 17, 14, 0, 0, 18, 24,
+  76, 0, 60, 4, 0, 4, 30, 0, 46, 0,
+  60, 49, 0, 0, 9, 0, 57, 0, 0, 18,
+  38, 31, 23, 17, 38, 0, 21, 0, 27, 0,
+  7, 10, 58, 0, 64, 0, 40, 0, 0, 0,
+  0, 26, 0, 7, 2, 0, 63, 38, 23, 37,
+  2, 6, 0, 40, 0, 45, 6, 67, 46, 14,
+  38, 0, 0, 48, 16, 24, 55, 58, 112, 45,
+  0, 0, 68, 0, 26, 0, 0, 0, 0, 44,
+  0, 0, 0, 2, 1, 25, 39, 0, 0, 36,
+  14, 72, 25, 35, 35, 0, 0, 49, 0, 21,
+  0, 0, 16, 34, 0, 26, 35, 0, 2, 44,
+  0, 0, 64, 0, 29, 35, 0, 1, 39, 0,
+  66, 5, 11, 30, 0, 6, 14, 27, 89, 0,
+  74, 5, 0, 3, 35, 0, 49, 0, 45, 48,
+  0, 0, 10, 0, 56, 0, 0, 23, 42, 24,
+  30, 23, 39, 0, 31, 0, 11, 0, 7, 13,
+  40, 0, 62, 0, 52, 0, 0, 2, 0, 45,
+  0, 0, 0, 0, 62, 43, 22, 57, 2, 15,
+  0, 41, 7, 47, 6, 61, 60, 24, 15, 0,
+  0, 43, 26, 39, 53, 69, 110, 31, 0, 0,
+  54, 0, 28, 0, 0, 0, 0, 53, 0, 0,
+  0, 0, 3, 7, 35, 0, 0, 41, 15, 67,
+  26, 42, 26, 0, 0, 57, 0, 32, 0, 0,
+  14, 45, 0, 35, 43, 0, 0, 32, 0, 1,
+  56, 0, 32, 31, 0, 8, 48, 0, 66, 25,
+  6, 25, 12, 12, 17, 31, 106, 0, 60, 5,
+  0, 7, 27, 0, 51, 1, 26, 50, 0, 0,
+  24, 0, 67, 0, 2, 18, 45, 33, 35, 9,
+  30, 0, 39, 0, 0, 6, 16, 9, 41, 0,
+  67, 0, 44, 0, 11, 14, 0, 22, 0, 0,
+  8, 0, 32, 0, 33, 28, 0, 1, 0, 29,
+  40, 48, 56, 56, 12, 13, 56, 0, 0, 29,
+  28, 42, 16, 56, 0, 19, 0, 0, 57, 2,
+  6, 0, 0, 0, 0, 24, 0, 0, 0, 16,
+  1, 14, 21, 10, 0, 5, 37, 5, 41, 38,
+  0, 11, 0, 24, 0, 42, 0, 0, 0, 0,
+  0, 0, 70, 24, 23, 0, 0, 0, 11, 21,
+  44, 0, 8, 0, 0, 12, 70, 39, 7, 8,
+  19, 29, 0, 28, 16, 3, 38, 30, 0, 36,
+  4, 7, 0, 4, 60, 56, 0, 0, 5, 0,
+  33, 0, 12, 9, 35, 35, 0, 12, 2, 0,
+  10, 0, 0, 0, 0, 0, 6, 0, 111, 0,
+  30, 0, 9, 0, 0, 40, 0, 0, 15, 0,
+  26, 0, 40, 45, 1, 0, 0, 24, 16, 54,
+  51, 59, 27, 8, 15, 0, 0, 41, 35, 63,
+  9, 78, 0, 0, 8, 0, 21, 0, 0, 0,
+  0, 0, 0, 35, 0, 0, 0, 0, 0, 0,
+  38, 0, 0, 5, 22, 8, 24, 27, 0, 0,
+  0, 65, 0, 36, 0, 0, 0, 33, 0, 2,
+  97, 14, 35, 0, 0, 0, 20, 36, 43, 5,
+  0, 0, 0, 9, 52, 53, 0, 20, 31, 37,
+  0, 46, 33, 0, 42, 41, 0, 48, 0, 0,
+  2, 16, 45, 62, 0, 0, 12, 0, 34, 0,
+  0, 17, 24, 34, 0, 27, 0, 0, 25, 0,
+  0, 14, 10, 0, 0, 8, 110, 0, 42, 0,
+  17, 9, 0, 44, 12, 0, 11, 0, 23, 0,
+  54, 79, 0, 0, 0, 0, 3, 53, 49, 60,
+  36, 23, 0, 0, 0, 42, 29, 49, 27, 93,
+  0, 0, 15, 0, 15, 0, 0, 0, 0, 32,
+  0, 20, 0, 0, 0, 0, 0, 7, 42, 0,
+  0, 5, 12, 12, 37, 19, 0, 0, 0, 60,
+  0, 25, 1, 12, 0, 29, 0, 0, 86, 0,
+  36, 9, 0, 0, 13, 38, 43, 13, 0, 16,
+  0, 0, 60, 35, 0, 10, 27, 23, 0, 45,
+  43, 0, 17, 49, 0, 42, 0, 0, 4, 7,
+  24, 57, 0, 0, 23, 0, 36, 0, 0, 1,
+  19, 59, 0, 22, 0, 0, 36, 0, 0, 24,
+  28, 0, 1, 18, 93, 0, 22, 0, 42, 20,
+  0, 33, 0, 0, 36, 0, 0, 3, 48, 28,
+  0, 0, 10, 59, 39, 46, 67, 44, 12, 0,
+  51, 0, 0, 36, 0, 22, 41, 60, 0, 0,
+  0, 0, 19, 0, 7, 0, 0, 22, 0, 24,
+  0, 0, 0, 4, 0, 17, 23, 0, 0, 0,
+  55, 0, 1, 17, 0, 0, 18, 15, 0, 17,
+  0, 0, 0, 0, 0, 0, 102, 0, 17, 0,
+  0, 0, 5, 41, 35, 0, 3, 53, 0, 13,
+  18, 38, 12, 42, 10, 28, 0, 30, 22, 26,
+  21, 17, 0, 42, 0, 0, 0, 2, 49, 55,
+  1, 0, 0, 0, 16, 0, 14, 19, 32, 69,
+  0, 3, 0, 0, 21, 0, 0, 0, 17, 0,
+  0, 13, 100, 0, 0, 0, 30, 37, 12, 0,
+  30, 0, 18, 0, 0, 0, 37, 30, 0, 0,
+  4, 71, 11, 0, 44, 48, 26, 0, 25, 1,
+  22, 8, 0, 6, 34, 49, 0, 0, 16, 0,
+  0, 5, 0, 0, 40, 32, 0, 1, 1, 0,
+  0, 0, 0, 0, 9, 0, 0, 0, 31, 0,
+  0, 10, 0, 0, 0, 51, 0, 0, 2, 6,
+  23, 5, 0, 0, 106, 5, 12, 82, 0, 0,
+  6, 39, 0, 0, 0, 50, 1, 0, 0, 34,
+  0, 54, 42, 31, 0, 69, 0, 0, 0, 56,
+  0, 0, 20, 0, 0, 15, 19, 45, 10, 6,
+  0, 0, 0, 0, 0, 21, 1, 57, 6, 0,
+  0, 0, 53, 11, 0, 0, 15, 0, 0, 26,
+  8, 0, 0, 12, 42, 48, 16, 0, 43, 0,
+  0, 0, 0, 0, 40, 54, 0, 16, 0, 59,
+  14, 0, 21, 57, 23, 17, 21, 14, 54, 0,
+  0, 0, 42, 21, 0, 0, 0, 0, 0, 0,
+  0, 0, 54, 47, 0, 0, 9, 0, 0, 0,
+  0, 0, 9, 0, 0, 0, 23, 0, 0, 0,
+  10, 0, 8, 40, 0, 0, 0, 25, 50, 0,
+  59, 21, 36, 7, 0, 114, 0, 9, 8, 6,
+  0, 0, 4, 34, 0, 0, 0, 19, 0, 29,
+  42, 2, 22, 44, 6, 0, 0, 57, 0, 0,
+  19, 0, 0, 0, 14, 17, 24, 0, 0, 0,
+  0, 0, 0, 0, 0, 39, 0, 0, 0, 0,
+  81, 4, 14, 0, 20, 0, 0, 18, 0, 0,
+  0, 19, 37, 4, 0, 26, 0, 7, 2, 0,
+  63, 38, 23, 37, 2, 6, 0, 40, 0, 45,
+  6, 67, 46, 14, 38, 0, 0, 48, 16, 24,
+  55, 58, 112, 45, 0, 0, 68, 0, 26, 0,
+  0, 0, 0, 44, 0, 0, 0, 2, 1, 25,
+  39, 0, 0, 36, 14, 72, 25, 35, 35, 0,
+  0, 49, 0, 21, 0, 0, 16, 34, 0, 26,
+  35, 0, 2, 44, 0, 0, 64, 0, 29, 35,
+  0, 1, 39, 0, 66, 5, 11, 30, 0, 6,
+  14, 27, 89, 0, 74, 5, 0, 3, 35, 0,
+  49, 0, 45, 48, 0, 0, 10, 0, 56, 0,
+  0, 23, 42, 24, 30, 23, 39, 0, 31, 0,
+  11, 0, 7, 13, 40, 0, 62, 0, 52, 0,
+  0, 2, 0, 45, 0, 0, 0, 0, 62, 43,
+  22, 57, 2, 15, 0, 41, 7, 47, 6, 61,
+  60, 24, 15, 0, 0, 43, 26, 39, 53, 69,
+  110, 31, 0, 0, 54, 0, 28, 0, 0, 0,
+  0, 53, 0, 0, 0, 0, 3, 7, 35, 0,
+  0, 41, 15, 67, 26, 42, 26, 0, 0, 57,
+  0, 32, 0, 0, 14, 45, 0, 35, 43, 0,
+  0, 32, 0, 1, 56, 0, 32, 31, 0, 8,
+  48, 0, 66, 25, 6, 25, 12, 12, 17, 31,
+  106, 0, 60, 5, 0, 7, 27, 0, 51, 1,
+  26, 50, 0, 0, 24, 0, 67, 0, 2, 18,
+  45, 33, 35, 9, 30, 0, 39, 0, 0, 6,
+  16, 9, 41, 0, 67, 0, 44, 0, 11, 14,
+  0, 50, 11, 0, 0, 0, 74, 36, 26, 54,
+  0, 25, 0, 0, 19, 41, 32, 80, 62, 25,
+  0, 0, 0, 42, 46, 46, 53, 65, 120, 31,
+  0, 0, 44, 0, 29, 0, 0, 0, 0, 45,
+  0, 0, 34, 0, 9, 14, 37, 0, 0, 29,
+  26, 40, 42, 29, 11, 0, 0, 42, 0, 48,
+  0, 0, 13, 56, 0, 27, 47, 0, 0, 21,
+  0, 6, 37, 0, 32, 21, 1, 6, 34, 0,
+  57, 25, 7, 31, 24, 9, 22, 28, 77, 0,
+  42, 0, 0, 21, 17, 0, 36, 22, 1, 31,
+  0, 0, 35, 0, 70, 0, 6, 12, 44, 44,
+  51, 12, 23, 0, 31, 0, 0, 14, 39, 0,
+  40, 13, 69, 0, 18, 0, 49, 15, 0, 40,
+  0, 0, 15, 0, 26, 0, 40, 45, 1, 0,
+  0, 24, 16, 54, 51, 59, 27, 8, 15, 0,
+  0, 41, 35, 63, 9, 78, 0, 0, 8, 0,
+  21, 0, 0, 0, 0, 0, 0, 35, 0, 0,
+  0, 0, 0, 0, 38, 0, 0, 5, 22, 8,
+  24, 27, 0, 0, 0, 65, 0, 36, 0, 0,
+  0, 33, 0, 2, 97, 14, 35, 0, 0, 0,
+  20, 36, 43, 5, 0, 0, 0, 9, 52, 53,
+  0, 20, 31, 37, 0, 46, 33, 0, 42, 41,
+  0, 48, 0, 0, 2, 16, 45, 62, 0, 0,
+  12, 0, 34, 0, 0, 17, 24, 34, 0, 27,
+  0, 0, 25, 0, 0, 14, 10, 0, 0, 8,
+  110, 0, 42, 0, 17, 9, 0, 44, 12, 0,
+  11, 0, 23, 0, 54, 79, 0, 0, 0, 0,
+  3, 53, 49, 60, 36, 23, 0, 0, 0, 42,
+  29, 49, 27, 93, 0, 0, 15, 0, 15, 0,
+  0, 0, 0, 32, 0, 20, 0, 0, 0, 0,
+  0, 7, 42, 0, 0, 5, 12, 12, 37, 19,
+  0, 0, 0, 60, 0, 25, 1, 12, 0, 29,
+  0, 0, 86, 0, 36, 9, 0, 0, 13, 38,
+  43, 13, 0, 16, 0, 0, 60, 35, 0, 10,
+  27, 23, 0, 45, 43, 0, 17, 49, 0, 42,
+  0, 0, 4, 7, 24, 57, 0, 0, 23, 0,
+  36, 0, 0, 1, 19, 59, 0, 22, 0, 0,
+  36, 0, 0, 24, 28, 0, 1, 18, 93, 0,
+  22, 0, 42, 20, 0, 38, 33, 0, 0, 0,
+  27, 0, 63, 89, 0, 12, 0, 0, 14, 41,
+  49, 72, 30, 11, 0, 0, 0, 57, 37, 23,
+  43, 98, 0, 0, 23, 0, 9, 0, 0, 0,
+  0, 70, 0, 0, 14, 15, 16, 0, 0, 17,
+  24, 0, 0, 0, 12, 0, 48, 0, 0, 0,
+  0, 33, 0, 3, 10, 18, 0, 50, 0, 0,
+  81, 0, 15, 42, 0, 0, 7, 44, 23, 12,
+  4, 28, 0, 0, 63, 33, 2, 27, 31, 25,
+  2, 25, 25, 0, 0, 46, 0, 33, 0, 0,
+  0, 14, 0, 51, 3, 0, 8, 0, 41, 0,
+  0, 18, 2, 64, 10, 19, 0, 0, 55, 0,
+  0, 23, 45, 0, 7, 3, 63, 0, 0, 0,
+  78, 18, 12, 0, 30, 0, 18, 0, 0, 0,
+  37, 30, 0, 0, 4, 71, 11, 0, 44, 48,
+  26, 0, 25, 1, 22, 8, 0, 6, 34, 49,
+  0, 0, 16, 0, 0, 5, 0, 0, 40, 32,
+  0, 1, 1, 0, 0, 0, 0, 0, 9, 0,
+  0, 0, 31, 0, 0, 10, 0, 0, 0, 51,
+  0, 0, 2, 6, 23, 5, 0, 0, 106, 5,
+  12, 82, 0, 0, 6, 39, 0, 0, 0, 50,
+  1, 0, 0, 34, 0, 54, 42, 31, 0, 69,
+  0, 0, 0, 56, 0, 0, 20, 0, 0, 15,
+  19, 45, 10, 6, 0, 0, 0, 0, 0, 21,
+  1, 57, 6, 0, 0, 0, 53, 11, 0, 0,
+  15, 0, 0, 26, 8, 0, 0, 12, 42, 48,
+  16, 0, 43, 0, 0, 0, 0, 0, 40, 54,
+  0, 16, 0, 59, 14, 0, 21, 57, 23, 17,
+  21, 14, 54, 0, 0, 0, 42, 21, 0, 0,
+  0, 0, 0, 0, 0, 0, 54, 47, 0, 0,
+  9, 0, 0, 0, 0, 0, 9, 0, 0, 0,
+  23, 0, 0, 0, 10, 0, 8, 40, 0, 0,
+  0, 25, 50, 0, 59, 21, 36, 7, 0, 114,
+  0, 9, 8, 6, 0, 0, 4, 34, 0, 0,
+  0, 19, 0, 29, 42, 2, 22, 44, 6, 0,
+  0, 57, 0, 0, 19, 0, 0, 0, 14, 17,
+  24, 0, 0, 0, 0, 0, 0, 0, 0, 39,
+  0, 0, 0, 0, 81, 4, 14, 0, 20, 0,
+  0, 18, 0, 0, 0, 19, 37, 4, 30, 0,
+  21, 8, 18, 0, 0, 0, 23, 36, 0, 0,
+  0, 54, 7, 0, 0, 65, 15, 16, 55, 1,
+  62, 10, 0, 0, 52, 0, 0, 0, 14, 0,
+  0, 0, 0, 0, 9, 33, 0, 0, 29, 0,
+  0, 9, 0, 0, 15, 0, 0, 0, 30, 30,
+  0, 0, 29, 0, 20, 15, 0, 0, 0, 14,
+  64, 0, 89, 22, 8, 0, 0, 130, 0, 14,
+  8, 0, 2, 0, 14, 22, 0, 0, 24, 0,
+  8, 22, 41, 0, 39, 0, 26, 0, 0, 30,
+  15, 0, 0, 0, 0, 0, 23, 0, 15, 0,
+  0, 0, 0, 0, 0, 32, 0, 10, 0, 9,
+  0, 0, 99, 17, 35, 0, 24, 0, 6, 0,
+  0, 0, 0, 31, 25, 0, 0, 45, 0, 0,
+  0, 0, 62, 43, 22, 57, 2, 15, 0, 41,
+  7, 47, 6, 61, 60, 24, 15, 0, 0, 43,
+  26, 39, 53, 69, 110, 31, 0, 0, 54, 0,
+  28, 0, 0, 0, 0, 53, 0, 0, 0, 0,
+  3, 7, 35, 0, 0, 41, 15, 67, 26, 42,
+  26, 0, 0, 57, 0, 32, 0, 0, 14, 45,
+  0, 35, 43, 0, 0, 32, 0, 1, 56, 0,
+  32, 31, 0, 8, 48, 0, 66, 25, 6, 25,
+  12, 12, 17, 31, 106, 0, 60, 5, 0, 7,
+  27, 0, 51, 1, 26, 50, 0, 0, 24, 0,
+  67, 0, 2, 18, 45, 33, 35, 9, 30, 0,
+  39, 0, 0, 6, 16, 9, 41, 0, 67, 0,
+  44, 0, 11, 14, 0, 50, 11, 0, 0, 0,
+  74, 36, 26, 54, 0, 25, 0, 0, 19, 41,
+  32, 80, 62, 25, 0, 0, 0, 42, 46, 46,
+  53, 65, 120, 31, 0, 0, 44, 0, 29, 0,
+  0, 0, 0, 45, 0, 0, 34, 0, 9, 14,
+  37, 0, 0, 29, 26, 40, 42, 29, 11, 0,
+  0, 42, 0, 48, 0, 0, 13, 56, 0, 27,
+  47, 0, 0, 21, 0, 6, 37, 0, 32, 21,
+  1, 6, 34, 0, 57, 25, 7, 31, 24, 9,
+  22, 28, 77, 0, 42, 0, 0, 21, 17, 0,
+  36, 22, 1, 31, 0, 0, 35, 0, 70, 0,
+  6, 12, 44, 44, 51, 12, 23, 0, 31, 0,
+  0, 14, 39, 0, 40, 13, 69, 0, 18, 0,
+  49, 15, 0, 53, 6, 0, 0, 0, 108, 18,
+  35, 62, 0, 10, 0, 0, 14, 70, 19, 66,
+  42, 16, 0, 0, 0, 59, 58, 43, 47, 64,
+  123, 32, 0, 0, 54, 0, 29, 0, 0, 0,
+  9, 45, 0, 0, 26, 16, 0, 23, 56, 0,
+  0, 30, 14, 43, 57, 13, 7, 3, 3, 60,
+  0, 52, 0, 9, 11, 62, 0, 31, 41, 10,
+  20, 3, 0, 13, 31, 0, 45, 36, 0, 0,
+  32, 0, 56, 38, 10, 21, 24, 0, 26, 22,
+  84, 1, 35, 0, 0, 34, 0, 0, 6, 15,
+  19, 40, 0, 0, 26, 0, 74, 0, 0, 29,
+  37, 36, 50, 12, 2, 0, 29, 0, 0, 35,
+  51, 0, 32, 0, 64, 0, 33, 0, 43, 1,
+  0, 44, 12, 0, 11, 0, 23, 0, 54, 79,
+  0, 0, 0, 0, 3, 53, 49, 60, 36, 23,
+  0, 0, 0, 42, 29, 49, 27, 93, 0, 0,
+  15, 0, 15, 0, 0, 0, 0, 32, 0, 20,
+  0, 0, 0, 0, 0, 7, 42, 0, 0, 5,
+  12, 12, 37, 19, 0, 0, 0, 60, 0, 25,
+  1, 12, 0, 29, 0, 0, 86, 0, 36, 9,
+  0, 0, 13, 38, 43, 13, 0, 16, 0, 0,
+  60, 35, 0, 10, 27, 23, 0, 45, 43, 0,
+  17, 49, 0, 42, 0, 0, 4, 7, 24, 57,
+  0, 0, 23, 0, 36, 0, 0, 1, 19, 59,
+  0, 22, 0, 0, 36, 0, 0, 24, 28, 0,
+  1, 18, 93, 0, 22, 0, 42, 20, 0, 38,
+  33, 0, 0, 0, 27, 0, 63, 89, 0, 12,
+  0, 0, 14, 41, 49, 72, 30, 11, 0, 0,
+  0, 57, 37, 23, 43, 98, 0, 0, 23, 0,
+  9, 0, 0, 0, 0, 70, 0, 0, 14, 15,
+  16, 0, 0, 17, 24, 0, 0, 0, 12, 0,
+  48, 0, 0, 0, 0, 33, 0, 3, 10, 18,
+  0, 50, 0, 0, 81, 0, 15, 42, 0, 0,
+  7, 44, 23, 12, 4, 28, 0, 0, 63, 33,
+  2, 27, 31, 25, 2, 25, 25, 0, 0, 46,
+  0, 33, 0, 0, 0, 14, 0, 51, 3, 0,
+  8, 0, 41, 0, 0, 18, 2, 64, 10, 19,
+  0, 0, 55, 0, 0, 23, 45, 0, 7, 3,
+  63, 0, 0, 0, 78, 18, 0, 39, 39, 0,
+  0, 0, 25, 0, 78, 78, 0, 0, 0, 3,
+  0, 17, 3, 41, 11, 0, 0, 0, 16, 61,
+  36, 0, 50, 80, 0, 0, 9, 0, 0, 0,
+  0, 0, 16, 73, 0, 0, 40, 8, 4, 0,
+  0, 14, 31, 0, 0, 0, 18, 0, 26, 0,
+  2, 0, 24, 52, 0, 0, 0, 48, 0, 57,
+  2, 2, 88, 0, 14, 69, 0, 0, 2, 41,
+  6, 46, 1, 15, 0, 0, 48, 46, 0, 40,
+  32, 26, 15, 28, 27, 0, 0, 65, 0, 8,
+  0, 0, 0, 0, 0, 52, 25, 0, 0, 0,
+  32, 0, 0, 39, 0, 43, 11, 0, 0, 0,
+  70, 0, 0, 25, 54, 0, 0, 0, 11, 0,
+  0, 0, 64, 2, 16, 0, 43, 0, 0, 0,
+  0, 0, 40, 54, 0, 16, 0, 59, 14, 0,
+  21, 57, 23, 17, 21, 14, 54, 0, 0, 0,
+  42, 21, 0, 0, 0, 0, 0, 0, 0, 0,
+  54, 47, 0, 0, 9, 0, 0, 0, 0, 0,
+  9, 0, 0, 0, 23, 0, 0, 0, 10, 0,
+  8, 40, 0, 0, 0, 25, 50, 0, 59, 21,
+  36, 7, 0, 114, 0, 9, 8, 6, 0, 0,
+  4, 34, 0, 0, 0, 19, 0, 29, 42, 2,
+  22, 44, 6, 0, 0, 57, 0, 0, 19, 0,
+  0, 0, 14, 17, 24, 0, 0, 0, 0, 0,
+  0, 0, 0, 39, 0, 0, 0, 0, 81, 4,
+  14, 0, 20, 0, 0, 18, 0, 0, 0, 19,
+  37, 4, 30, 0, 21, 8, 18, 0, 0, 0,
+  23, 36, 0, 0, 0, 54, 7, 0, 0, 65,
+  15, 16, 55, 1, 62, 10, 0, 0, 52, 0,
+  0, 0, 14, 0, 0, 0, 0, 0, 9, 33,
+  0, 0, 29, 0, 0, 9, 0, 0, 15, 0,
+  0, 0, 30, 30, 0, 0, 29, 0, 20, 15,
+  0, 0, 0, 14, 64, 0, 89, 22, 8, 0,
+  0, 130, 0, 14, 8, 0, 2, 0, 14, 22,
+  0, 0, 24, 0, 8, 22, 41, 0, 39, 0,
+  26, 0, 0, 30, 15, 0, 0, 0, 0, 0,
+  23, 0, 15, 0, 0, 0, 0, 0, 0, 32,
+  0, 10, 0, 9, 0, 0, 99, 17, 35, 0,
+  24, 0, 6, 0, 0, 0, 0, 31, 25, 0,
+  5, 13, 0, 32, 19, 0, 8, 0, 42, 4,
+  0, 13, 0, 36, 0, 0, 0, 57, 0, 20,
+  78, 0, 62, 17, 0, 0, 48, 0, 0, 0,
+  23, 0, 0, 0, 0, 0, 0, 22, 0, 0,
+  41, 0, 0, 33, 9, 0, 6, 0, 0, 0,
+  32, 6, 0, 0, 33, 0, 37, 0, 4, 0,
+  0, 39, 62, 0, 84, 8, 32, 22, 0, 130,
+  0, 9, 16, 0, 0, 9, 33, 13, 0, 0,
+  29, 13, 0, 22, 32, 0, 33, 0, 24, 0,
+  0, 28, 10, 0, 0, 0, 8, 0, 32, 0,
+  10, 12, 0, 0, 0, 0, 0, 83, 0, 0,
+  2, 0, 0, 0, 98, 36, 46, 0, 18, 0,
+  8, 0, 0, 0, 0, 28, 8, 0, 0, 50,
+  11, 0, 0, 0, 74, 36, 26, 54, 0, 25,
+  0, 0, 19, 41, 32, 80, 62, 25, 0, 0,
+  0, 42, 46, 46, 53, 65, 120, 31, 0, 0,
+  44, 0, 29, 0, 0, 0, 0, 45, 0, 0,
+  34, 0, 9, 14, 37, 0, 0, 29, 26, 40,
+  42, 29, 11, 0, 0, 42, 0, 48, 0, 0,
+  13, 56, 0, 27, 47, 0, 0, 21, 0, 6,
+  37, 0, 32, 21, 1, 6, 34, 0, 57, 25,
+  7, 31, 24, 9, 22, 28, 77, 0, 42, 0,
+  0, 21, 17, 0, 36, 22, 1, 31, 0, 0,
+  35, 0, 70, 0, 6, 12, 44, 44, 51, 12,
+  23, 0, 31, 0, 0, 14, 39, 0, 40, 13,
+  69, 0, 18, 0, 49, 15, 0, 53, 6, 0,
+  0, 0, 108, 18, 35, 62, 0, 10, 0, 0,
+  14, 70, 19, 66, 42, 16, 0, 0, 0, 59,
+  58, 43, 47, 64, 123, 32, 0, 0, 54, 0,
+  29, 0, 0, 0, 9, 45, 0, 0, 26, 16,
+  0, 23, 56, 0, 0, 30, 14, 43, 57, 13,
+  7, 3, 3, 60, 0, 52, 0, 9, 11, 62,
+  0, 31, 41, 10, 20, 3, 0, 13, 31, 0,
+  45, 36, 0, 0, 32, 0, 56, 38, 10, 21,
+  24, 0, 26, 22, 84, 1, 35, 0, 0, 34,
+  0, 0, 6, 15, 19, 40, 0, 0, 26, 0,
+  74, 0, 0, 29, 37, 36, 50, 12, 2, 0,
+  29, 0, 0, 35, 51, 0, 32, 0, 64, 0,
+  33, 0, 43, 1, 0, 47, 0, 0, 0, 0,
+  99, 35, 39, 50, 0, 17, 0, 0, 7, 70,
+  34, 67, 46, 6, 16, 0, 0, 47, 51, 51,
+  43, 68, 129, 40, 9, 0, 53, 0, 19, 0,
+  0, 3, 0, 46, 0, 0, 4, 18, 0, 21,
+  43, 0, 0, 29, 3, 44, 51, 16, 0, 0,
+  8, 61, 0, 57, 0, 8, 10, 70, 0, 30,
+  41, 15, 26, 0, 0, 5, 28, 0, 43, 38,
+  0, 0, 35, 0, 53, 27, 7, 21, 30, 0,
+  31, 28, 62, 0, 36, 0, 0, 42, 1, 0,
+  11, 10, 39, 35, 0, 0, 24, 0, 67, 0,
+  0, 27, 42, 50, 46, 18, 14, 0, 25, 0,
+  0, 33, 56, 0, 33, 24, 74, 0, 21, 0,
+  46, 9, 0, 38, 33, 0, 0, 0, 27, 0,
+  63, 89, 0, 12, 0, 0, 14, 41, 49, 72,
+  30, 11, 0, 0, 0, 57, 37, 23, 43, 98,
+  0, 0, 23, 0, 9, 0, 0, 0, 0, 70,
+  0, 0, 14, 15, 16, 0, 0, 17, 24, 0,
+  0, 0, 12, 0, 48, 0, 0, 0, 0, 33,
+  0, 3, 10, 18, 0, 50, 0, 0, 81, 0,
+  15, 42, 0, 0, 7, 44, 23, 12, 4, 28,
+  0, 0, 63, 33, 2, 27, 31, 25, 2, 25,
+  25, 0, 0, 46, 0, 33, 0, 0, 0, 14,
+  0, 51, 3, 0, 8, 0, 41, 0, 0, 18,
+  2, 64, 10, 19, 0, 0, 55, 0, 0, 23,
+  45, 0, 7, 3, 63, 0, 0, 0, 78, 18,
+  0, 39, 39, 0, 0, 0, 25, 0, 78, 78,
+  0, 0, 0, 3, 0, 17, 3, 41, 11, 0,
+  0, 0, 16, 61, 36, 0, 50, 80, 0, 0,
+  9, 0, 0, 0, 0, 0, 16, 73, 0, 0,
+  40, 8, 4, 0, 0, 14, 31, 0, 0, 0,
+  18, 0, 26, 0, 2, 0, 24, 52, 0, 0,
+  0, 48, 0, 57, 2, 2, 88, 0, 14, 69,
+  0, 0, 2, 41, 6, 46, 1, 15, 0, 0,
+  48, 46, 0, 40, 32, 26, 15, 28, 27, 0,
+  0, 65, 0, 8, 0, 0, 0, 0, 0, 52,
+  25, 0, 0, 0, 32, 0, 0, 39, 0, 43,
+  11, 0, 0, 0, 70, 0, 0, 25, 54, 0,
+  0, 0, 11, 0, 0, 0, 64, 2, 0, 29,
+  0, 0, 0, 0, 15, 0, 80, 38, 0, 0,
+  0, 0, 0, 0, 0, 35, 26, 0, 14, 0,
+  0, 45, 31, 0, 42, 64, 0, 0, 16, 0,
+  0, 5, 0, 0, 32, 60, 1, 0, 52, 0,
+  0, 0, 0, 15, 40, 0, 0, 0, 0, 2,
+  11, 0, 19, 50, 26, 49, 0, 0, 6, 43,
+  3, 66, 19, 0, 76, 0, 18, 84, 0, 0,
+  2, 19, 0, 39, 0, 5, 14, 0, 39, 27,
+  3, 12, 27, 17, 21, 31, 23, 0, 0, 98,
+  2, 0, 0, 0, 0, 0, 39, 39, 30, 37,
+  0, 0, 15, 0, 0, 33, 0, 44, 1, 9,
+  0, 0, 55, 0, 0, 24, 71, 0, 0, 0,
+  0, 0, 0, 0, 42, 0, 30, 0, 21, 8,
+  18, 0, 0, 0, 23, 36, 0, 0, 0, 54,
+  7, 0, 0, 65, 15, 16, 55, 1, 62, 10,
+  0, 0, 52, 0, 0, 0, 14, 0, 0, 0,
+  0, 0, 9, 33, 0, 0, 29, 0, 0, 9,
+  0, 0, 15, 0, 0, 0, 30, 30, 0, 0,
+  29, 0, 20, 15, 0, 0, 0, 14, 64, 0,
+  89, 22, 8, 0, 0, 130, 0, 14, 8, 0,
+  2, 0, 14, 22, 0, 0, 24, 0, 8, 22,
+  41, 0, 39, 0, 26, 0, 0, 30, 15, 0,
+  0, 0, 0, 0, 23, 0, 15, 0, 0, 0,
+  0, 0, 0, 32, 0, 10, 0, 9, 0, 0,
+  99, 17, 35, 0, 24, 0, 6, 0, 0, 0,
+  0, 31, 25, 0, 5, 13, 0, 32, 19, 0,
+  8, 0, 42, 4, 0, 13, 0, 36, 0, 0,
+  0, 57, 0, 20, 78, 0, 62, 17, 0, 0,
+  48, 0, 0, 0, 23, 0, 0, 0, 0, 0,
+  0, 22, 0, 0, 41, 0, 0, 33, 9, 0,
+  6, 0, 0, 0, 32, 6, 0, 0, 33, 0,
+  37, 0, 4, 0, 0, 39, 62, 0, 84, 8,
+  32, 22, 0, 130, 0, 9, 16, 0, 0, 9,
+  33, 13, 0, 0, 29, 13, 0, 22, 32, 0,
+  33, 0, 24, 0, 0, 28, 10, 0, 0, 0,
+  8, 0, 32, 0, 10, 12, 0, 0, 0, 0,
+  0, 83, 0, 0, 2, 0, 0, 0, 98, 36,
+  46, 0, 18, 0, 8, 0, 0, 0, 0, 28,
+  8, 0, 11, 29, 0, 45, 2, 0, 17, 0,
+  59, 0, 0, 24, 0, 0, 0, 0, 0, 40,
+  1, 11, 70, 0, 8, 10, 0, 0, 32, 0,
+  0, 0, 26, 22, 0, 7, 0, 0, 17, 26,
+  2, 0, 47, 0, 0, 21, 13, 9, 8, 0,
+  0, 0, 39, 2, 0, 18, 67, 54, 46, 0,
+  21, 0, 0, 41, 60, 20, 72, 13, 27, 31,
+  0, 123, 0, 13, 17, 0, 0, 28, 28, 13,
+  17, 0, 23, 19, 0, 3, 26, 0, 27, 0,
+  23, 0, 0, 39, 0, 0, 0, 3, 33, 0,
+  52, 9, 4, 75, 0, 0, 0, 0, 0, 100,
+  0, 0, 2, 0, 0, 11, 51, 34, 23, 0,
+  31, 0, 14, 0, 0, 0, 3, 31, 7, 0,
+  0, 53, 6, 0, 0, 0, 108, 18, 35, 62,
+  0, 10, 0, 0, 14, 70, 19, 66, 42, 16,
+  0, 0, 0, 59, 58, 43, 47, 64, 123, 32,
+  0, 0, 54, 0, 29, 0, 0, 0, 9, 45,
+  0, 0, 26, 16, 0, 23, 56, 0, 0, 30,
+  14, 43, 57, 13, 7, 3, 3, 60, 0, 52,
+  0, 9, 11, 62, 0, 31, 41, 10, 20, 3,
+  0, 13, 31, 0, 45, 36, 0, 0, 32, 0,
+  56, 38, 10, 21, 24, 0, 26, 22, 84, 1,
+  35, 0, 0, 34, 0, 0, 6, 15, 19, 40,
+  0, 0, 26, 0, 74, 0, 0, 29, 37, 36,
+  50, 12, 2, 0, 29, 0, 0, 35, 51, 0,
+  32, 0, 64, 0, 33, 0, 43, 1, 0, 47,
+  0, 0, 0, 0, 99, 35, 39, 50, 0, 17,
+  0, 0, 7, 70, 34, 67, 46, 6, 16, 0,
+  0, 47, 51, 51, 43, 68, 129, 40, 9, 0,
+  53, 0, 19, 0, 0, 3, 0, 46, 0, 0,
+  4, 18, 0, 21, 43, 0, 0, 29, 3, 44,
+  51, 16, 0, 0, 8, 61, 0, 57, 0, 8,
+  10, 70, 0, 30, 41, 15, 26, 0, 0, 5,
+  28, 0, 43, 38, 0, 0, 35, 0, 53, 27,
+  7, 21, 30, 0, 31, 28, 62, 0, 36, 0,
+  0, 42, 1, 0, 11, 10, 39, 35, 0, 0,
+  24, 0, 67, 0, 0, 27, 42, 50, 46, 18,
+  14, 0, 25, 0, 0, 33, 56, 0, 33, 24,
+  74, 0, 21, 0, 46, 9, 0, 40, 0, 0,
+  5, 0, 79, 51, 29, 30, 0, 28, 9, 0,
+  6, 57, 44, 75, 60, 18, 9, 0, 0, 32,
+  53, 70, 33, 61, 135, 47, 36, 0, 45, 8,
+  29, 0, 0, 4, 0, 55, 0, 0, 25, 9,
+  0, 4, 34, 0, 0, 18, 21, 51, 44, 48,
+  0, 10, 3, 61, 0, 58, 0, 0, 12, 61,
+  0, 22, 46, 13, 15, 0, 0, 2, 14, 0,
+  34, 33, 0, 3, 31, 0, 57, 9, 0, 22,
+  46, 0, 23, 34, 53, 5, 53, 2, 0, 39,
+  29, 0, 36, 10, 25, 36, 0, 0, 19, 0,
+  58, 0, 0, 20, 53, 51, 44, 24, 38, 2,
+  31, 0, 0, 13, 50, 0, 40, 53, 98, 0,
+  37, 0, 54, 1, 0, 39, 39, 0, 0, 0,
+  25, 0, 78, 78, 0, 0, 0, 3, 0, 17,
+  3, 41, 11, 0, 0, 0, 16, 61, 36, 0,
+  50, 80, 0, 0, 9, 0, 0, 0, 0, 0,
+  16, 73, 0, 0, 40, 8, 4, 0, 0, 14,
+  31, 0, 0, 0, 18, 0, 26, 0, 2, 0,
+  24, 52, 0, 0, 0, 48, 0, 57, 2, 2,
+  88, 0, 14, 69, 0, 0, 2, 41, 6, 46,
+  1, 15, 0, 0, 48, 46, 0, 40, 32, 26,
+  15, 28, 27, 0, 0, 65, 0, 8, 0, 0,
+  0, 0, 0, 52, 25, 0, 0, 0, 32, 0,
+  0, 39, 0, 43, 11, 0, 0, 0, 70, 0,
+  0, 25, 54, 0, 0, 0, 11, 0, 0, 0,
+  64, 2, 0, 29, 0, 0, 0, 0, 15, 0,
+  80, 38, 0, 0, 0, 0, 0, 0, 0, 35,
+  26, 0, 14, 0, 0, 45, 31, 0, 42, 64,
+  0, 0, 16, 0, 0, 5, 0, 0, 32, 60,
+  1, 0, 52, 0, 0, 0, 0, 15, 40, 0,
+  0, 0, 0, 2, 11, 0, 19, 50, 26, 49,
+  0, 0, 6, 43, 3, 66, 19, 0, 76, 0,
+  18, 84, 0, 0, 2, 19, 0, 39, 0, 5,
+  14, 0, 39, 27, 3, 12, 27, 17, 21, 31,
+  23, 0, 0, 98, 2, 0, 0, 0, 0, 0,
+  39, 39, 30, 37, 0, 0, 15, 0, 0, 33,
+  0, 44, 1, 9, 0, 0, 55, 0, 0, 24,
+  71, 0, 0, 0, 0, 0, 0, 0, 42, 0,
+  0, 21, 0, 0, 2, 0, 15, 0, 74, 29,
+  0, 18, 0, 12, 0, 34, 16, 63, 31, 0,
+  0, 0, 0, 43, 15, 0, 18, 55, 0, 0,
+  44, 0, 0, 15, 0, 0, 19, 53, 0, 0,
+  37, 0, 0, 0, 0, 6, 28, 0, 0, 0,
+  0, 19, 26, 0, 3, 71, 33, 50, 0, 0,
+  10, 18, 0, 54, 2, 0, 62, 0, 20, 53,
+  0, 0, 0, 10, 0, 34, 0, 0, 19, 0,
+  50, 13, 6, 0, 30, 11, 7, 22, 34, 0,
+  0, 109, 0, 6, 0, 0, 0, 0, 36, 46,
+  17, 32, 7, 0, 17, 0, 0, 18, 0, 40,
+  0, 25, 0, 9, 51, 0, 0, 9, 68, 0,
+  0, 9, 34, 0, 14, 0, 50, 0, 5, 13,
+  0, 32, 19, 0, 8, 0, 42, 4, 0, 13,
+  0, 36, 0, 0, 0, 57, 0, 20, 78, 0,
+  62, 17, 0, 0, 48, 0, 0, 0, 23, 0,
+  0, 0, 0, 0, 0, 22, 0, 0, 41, 0,
+  0, 33, 9, 0, 6, 0, 0, 0, 32, 6,
+  0, 0, 33, 0, 37, 0, 4, 0, 0, 39,
+  62, 0, 84, 8, 32, 22, 0, 130, 0, 9,
+  16, 0, 0, 9, 33, 13, 0, 0, 29, 13,
+  0, 22, 32, 0, 33, 0, 24, 0, 0, 28,
+  10, 0, 0, 0, 8, 0, 32, 0, 10, 12,
+  0, 0, 0, 0, 0, 83, 0, 0, 2, 0,
+  0, 0, 98, 36, 46, 0, 18, 0, 8, 0,
+  0, 0, 0, 28, 8, 0, 11, 29, 0, 45,
+  2, 0, 17, 0, 59, 0, 0, 24, 0, 0,
+  0, 0, 0, 40, 1, 11, 70, 0, 8, 10,
+  0, 0, 32, 0, 0, 0, 26, 22, 0, 7,
+  0, 0, 17, 26, 2, 0, 47, 0, 0, 21,
+  13, 9, 8, 0, 0, 0, 39, 2, 0, 18,
+  67, 54, 46, 0, 21, 0, 0, 41, 60, 20,
+  72, 13, 27, 31, 0, 123, 0, 13, 17, 0,
+  0, 28, 28, 13, 17, 0, 23, 19, 0, 3,
+  26, 0, 27, 0, 23, 0, 0, 39, 0, 0,
+  0, 3, 33, 0, 52, 9, 4, 75, 0, 0,
+  0, 0, 0, 100, 0, 0, 2, 0, 0, 11,
+  51, 34, 23, 0, 31, 0, 14, 0, 0, 0,
+  3, 31, 7, 0, 11, 24, 0, 20, 0, 8,
+  0, 0, 72, 0, 0, 35, 0, 0, 0, 0,
+  0, 45, 6, 0, 35, 11, 0, 11, 0, 0,
+  13, 0, 0, 0, 2, 13, 0, 0, 0, 0,
+  29, 44, 34, 0, 50, 0, 0, 11, 0, 7,
+  0, 0, 0, 0, 8, 60, 0, 0, 108, 136,
+  34, 5, 37, 0, 0, 24, 71, 27, 134, 39,
+  0, 0, 0, 158, 66, 0, 9, 0, 0, 10,
+  0, 0, 39, 0, 9, 0, 13, 5, 9, 0,
+  4, 0, 70, 0, 0, 80, 0, 0, 27, 0,
+  26, 0, 39, 45, 33, 130, 0, 0, 0, 0,
+  0, 84, 0, 0, 0, 0, 0, 24, 23, 13,
+  0, 0, 36, 0, 0, 0, 0, 0, 23, 31,
+  12, 0, 0, 47, 0, 0, 0, 0, 99, 35,
+  39, 50, 0, 17, 0, 0, 7, 70, 34, 67,
+  46, 6, 16, 0, 0, 47, 51, 51, 43, 68,
+  129, 40, 9, 0, 53, 0, 19, 0, 0, 3,
+  0, 46, 0, 0, 4, 18, 0, 21, 43, 0,
+  0, 29, 3, 44, 51, 16, 0, 0, 8, 61,
+  0, 57, 0, 8, 10, 70, 0, 30, 41, 15,
+  26, 0, 0, 5, 28, 0, 43, 38, 0, 0,
+  35, 0, 53, 27, 7, 21, 30, 0, 31, 28,
+  62, 0, 36, 0, 0, 42, 1, 0, 11, 10,
+  39, 35, 0, 0, 24, 0, 67, 0, 0, 27,
+  42, 50, 46, 18, 14, 0, 25, 0, 0, 33,
+  56, 0, 33, 24, 74, 0, 21, 0, 46, 9,
+  0, 40, 0, 0, 5, 0, 79, 51, 29, 30,
+  0, 28, 9, 0, 6, 57, 44, 75, 60, 18,
+  9, 0, 0, 32, 53, 70, 33, 61, 135, 47,
+  36, 0, 45, 8, 29, 0, 0, 4, 0, 55,
+  0, 0, 25, 9, 0, 4, 34, 0, 0, 18,
+  21, 51, 44, 48, 0, 10, 3, 61, 0, 58,
+  0, 0, 12, 61, 0, 22, 46, 13, 15, 0,
+  0, 2, 14, 0, 34, 33, 0, 3, 31, 0,
+  57, 9, 0, 22, 46, 0, 23, 34, 53, 5,
+  53, 2, 0, 39, 29, 0, 36, 10, 25, 36,
+  0, 0, 19, 0, 58, 0, 0, 20, 53, 51,
+  44, 24, 38, 2, 31, 0, 0, 13, 50, 0,
+  40, 53, 98, 0, 37, 0, 54, 1, 0, 57,
+  0, 0, 7, 0, 75, 49, 21, 35, 0, 26,
+  12, 9, 20, 56, 23, 65, 41, 43, 0, 0,
+  0, 51, 49, 70, 25, 60, 128, 38, 16, 1,
+  47, 0, 34, 0, 0, 0, 0, 68, 0, 0,
+  51, 15, 10, 0, 33, 0, 0, 22, 41, 66,
+  39, 66, 0, 5, 0, 59, 0, 43, 0, 0,
+  13, 40, 0, 20, 49, 2, 9, 0, 0, 5,
+  40, 0, 43, 31, 0, 19, 43, 2, 80, 35,
+  0, 14, 27, 0, 17, 32, 100, 3, 76, 2,
+  0, 16, 24, 9, 46, 5, 10, 44, 0, 0,
+  7, 0, 65, 0, 4, 31, 54, 32, 37, 0,
+  31, 0, 29, 0, 0, 0, 10, 17, 45, 22,
+  97, 0, 76, 0, 23, 0, 0, 29, 0, 0,
+  0, 0, 15, 0, 80, 38, 0, 0, 0, 0,
+  0, 0, 0, 35, 26, 0, 14, 0, 0, 45,
+  31, 0, 42, 64, 0, 0, 16, 0, 0, 5,
+  0, 0, 32, 60, 1, 0, 52, 0, 0, 0,
+  0, 15, 40, 0, 0, 0, 0, 2, 11, 0,
+  19, 50, 26, 49, 0, 0, 6, 43, 3, 66,
+  19, 0, 76, 0, 18, 84, 0, 0, 2, 19,
+  0, 39, 0, 5, 14, 0, 39, 27, 3, 12,
+  27, 17, 21, 31, 23, 0, 0, 98, 2, 0,
+  0, 0, 0, 0, 39, 39, 30, 37, 0, 0,
+  15, 0, 0, 33, 0, 44, 1, 9, 0, 0,
+  55, 0, 0, 24, 71, 0, 0, 0, 0, 0,
+  0, 0, 42, 0, 0, 21, 0, 0, 2, 0,
+  15, 0, 74, 29, 0, 18, 0, 12, 0, 34,
+  16, 63, 31, 0, 0, 0, 0, 43, 15, 0,
+  18, 55, 0, 0, 44, 0, 0, 15, 0, 0,
+  19, 53, 0, 0, 37, 0, 0, 0, 0, 6,
+  28, 0, 0, 0, 0, 19, 26, 0, 3, 71,
+  33, 50, 0, 0, 10, 18, 0, 54, 2, 0,
+  62, 0, 20, 53, 0, 0, 0, 10, 0, 34,
+  0, 0, 19, 0, 50, 13, 6, 0, 30, 11,
+  7, 22, 34, 0, 0, 109, 0, 6, 0, 0,
+  0, 0, 36, 46, 17, 32, 7, 0, 17, 0,
+  0, 18, 0, 40, 0, 25, 0, 9, 51, 0,
+  0, 9, 68, 0, 0, 9, 34, 0, 14, 0,
+  50, 0, 0, 44, 0, 0, 11, 0, 30, 0,
+  44, 53, 0, 11, 18, 12, 0, 82, 51, 71,
+  16, 19, 0, 0, 0, 63, 28, 37, 0, 67,
+  2, 0, 45, 0, 33, 25, 0, 0, 0, 52,
+  0, 0, 18, 0, 13, 17, 0, 3, 20, 20,
+  0, 7, 2, 12, 49, 14, 0, 32, 19, 44,
+  0, 21, 12, 0, 0, 24, 0, 0, 80, 1,
+  40, 3, 0, 0, 8, 26, 18, 45, 0, 0,
+  0, 0, 87, 25, 0, 0, 27, 11, 0, 26,
+  28, 6, 18, 90, 0, 29, 0, 0, 0, 0,
+  0, 71, 9, 2, 14, 0, 37, 0, 0, 24,
+  1, 42, 0, 27, 0, 6, 32, 0, 0, 6,
+  43, 0, 9, 0, 103, 0, 43, 0, 51, 0,
+  11, 29, 0, 45, 2, 0, 17, 0, 59, 0,
+  0, 24, 0, 0, 0, 0, 0, 40, 1, 11,
+  70, 0, 8, 10, 0, 0, 32, 0, 0, 0,
+  26, 22, 0, 7, 0, 0, 17, 26, 2, 0,
+  47, 0, 0, 21, 13, 9, 8, 0, 0, 0,
+  39, 2, 0, 18, 67, 54, 46, 0, 21, 0,
+  0, 41, 60, 20, 72, 13, 27, 31, 0, 123,
+  0, 13, 17, 0, 0, 28, 28, 13, 17, 0,
+  23, 19, 0, 3, 26, 0, 27, 0, 23, 0,
+  0, 39, 0, 0, 0, 3, 33, 0, 52, 9,
+  4, 75, 0, 0, 0, 0, 0, 100, 0, 0,
+  2, 0, 0, 11, 51, 34, 23, 0, 31, 0,
+  14, 0, 0, 0, 3, 31, 7, 0, 11, 24,
+  0, 20, 0, 8, 0, 0, 72, 0, 0, 35,
+  0, 0, 0, 0, 0, 45, 6, 0, 35, 11,
+  0, 11, 0, 0, 13, 0, 0, 0, 2, 13,
+  0, 0, 0, 0, 29, 44, 34, 0, 50, 0,
+  0, 11, 0, 7, 0, 0, 0, 0, 8, 60,
+  0, 0, 108, 136, 34, 5, 37, 0, 0, 24,
+  71, 27, 134, 39, 0, 0, 0, 158, 66, 0,
+  9, 0, 0, 10, 0, 0, 39, 0, 9, 0,
+  13, 5, 9, 0, 4, 0, 70, 0, 0, 80,
+  0, 0, 27, 0, 26, 0, 39, 45, 33, 130,
+  0, 0, 0, 0, 0, 84, 0, 0, 0, 0,
+  0, 24, 23, 13, 0, 0, 36, 0, 0, 0,
+  0, 0, 23, 31, 12, 0, 0, 15, 0, 0,
+  0, 50, 0, 0, 53, 14, 0, 2, 0, 0,
+  0, 0, 0, 48, 12, 0, 0, 0, 0, 19,
+  0, 0, 0, 3, 0, 0, 3, 11, 0, 0,
+  0, 9, 43, 82, 35, 0, 70, 0, 5, 16,
+  0, 7, 7, 0, 0, 0, 0, 63, 0, 0,
+  57, 160, 47, 9, 35, 0, 0, 29, 57, 0,
+  153, 4, 0, 0, 0, 121, 122, 0, 14, 27,
+  0, 33, 0, 0, 46, 0, 6, 0, 5, 13,
+  16, 0, 0, 10, 64, 0, 0, 128, 0, 0,
+  35, 0, 0, 0, 10, 76, 58, 96, 0, 0,
+  0, 0, 0, 62, 0, 0, 0, 3, 0, 35,
+  0, 0, 0, 0, 53, 0, 0, 0, 0, 0,
+  18, 28, 29, 0, 0, 40, 0, 0, 5, 0,
+  79, 51, 29, 30, 0, 28, 9, 0, 6, 57,
+  44, 75, 60, 18, 9, 0, 0, 32, 53, 70,
+  33, 61, 135, 47, 36, 0, 45, 8, 29, 0,
+  0, 4, 0, 55, 0, 0, 25, 9, 0, 4,
+  34, 0, 0, 18, 21, 51, 44, 48, 0, 10,
+  3, 61, 0, 58, 0, 0, 12, 61, 0, 22,
+  46, 13, 15, 0, 0, 2, 14, 0, 34, 33,
+  0, 3, 31, 0, 57, 9, 0, 22, 46, 0,
+  23, 34, 53, 5, 53, 2, 0, 39, 29, 0,
+  36, 10, 25, 36, 0, 0, 19, 0, 58, 0,
+  0, 20, 53, 51, 44, 24, 38, 2, 31, 0,
+  0, 13, 50, 0, 40, 53, 98, 0, 37, 0,
+  54, 1, 0, 57, 0, 0, 7, 0, 75, 49,
+  21, 35, 0, 26, 12, 9, 20, 56, 23, 65,
+  41, 43, 0, 0, 0, 51, 49, 70, 25, 60,
+  128, 38, 16, 1, 47, 0, 34, 0, 0, 0,
+  0, 68, 0, 0, 51, 15, 10, 0, 33, 0,
+  0, 22, 41, 66, 39, 66, 0, 5, 0, 59,
+  0, 43, 0, 0, 13, 40, 0, 20, 49, 2,
+  9, 0, 0, 5, 40, 0, 43, 31, 0, 19,
+  43, 2, 80, 35, 0, 14, 27, 0, 17, 32,
+  100, 3, 76, 2, 0, 16, 24, 9, 46, 5,
+  10, 44, 0, 0, 7, 0, 65, 0, 4, 31,
+  54, 32, 37, 0, 31, 0, 29, 0, 0, 0,
+  10, 17, 45, 22, 97, 0, 76, 0, 23, 0,
+  0, 100, 25, 10, 0, 0, 70, 30, 19, 50,
+  0, 57, 14, 13, 11, 54, 10, 51, 32, 74,
+  0, 0, 0, 42, 41, 47, 55, 47, 140, 28,
+  0, 6, 69, 0, 51, 0, 0, 0, 0, 61,
+  0, 0, 55, 28, 10, 25, 39, 0, 0, 40,
+  29, 63, 62, 56, 3, 0, 0, 4, 0, 42,
+  0, 0, 18, 10, 0, 13, 27, 0, 4, 2,
+  3, 7, 57, 0, 55, 33, 0, 39, 43, 0,
+  86, 34, 0, 21, 5, 0, 34, 32, 104, 0,
+  59, 5, 0, 0, 22, 8, 33, 0, 3, 36,
+  0, 11, 27, 0, 66, 0, 37, 39, 34, 16,
+  38, 0, 27, 2, 5, 0, 0, 0, 0, 19,
+  44, 4, 64, 0, 73, 0, 11, 0, 0, 21,
+  0, 0, 2, 0, 15, 0, 74, 29, 0, 18,
+  0, 12, 0, 34, 16, 63, 31, 0, 0, 0,
+  0, 43, 15, 0, 18, 55, 0, 0, 44, 0,
+  0, 15, 0, 0, 19, 53, 0, 0, 37, 0,
+  0, 0, 0, 6, 28, 0, 0, 0, 0, 19,
+  26, 0, 3, 71, 33, 50, 0, 0, 10, 18,
+  0, 54, 2, 0, 62, 0, 20, 53, 0, 0,
+  0, 10, 0, 34, 0, 0, 19, 0, 50, 13,
+  6, 0, 30, 11, 7, 22, 34, 0, 0, 109,
+  0, 6, 0, 0, 0, 0, 36, 46, 17, 32,
+  7, 0, 17, 0, 0, 18, 0, 40, 0, 25,
+  0, 9, 51, 0, 0, 9, 68, 0, 0, 9,
+  34, 0, 14, 0, 50, 0, 0, 44, 0, 0,
+  11, 0, 30, 0, 44, 53, 0, 11, 18, 12,
+  0, 82, 51, 71, 16, 19, 0, 0, 0, 63,
+  28, 37, 0, 67, 2, 0, 45, 0, 33, 25,
+  0, 0, 0, 52, 0, 0, 18, 0, 13, 17,
+  0, 3, 20, 20, 0, 7, 2, 12, 49, 14,
+  0, 32, 19, 44, 0, 21, 12, 0, 0, 24,
+  0, 0, 80, 1, 40, 3, 0, 0, 8, 26,
+  18, 45, 0, 0, 0, 0, 87, 25, 0, 0,
+  27, 11, 0, 26, 28, 6, 18, 90, 0, 29,
+  0, 0, 0, 0, 0, 71, 9, 2, 14, 0,
+  37, 0, 0, 24, 1, 42, 0, 27, 0, 6,
+  32, 0, 0, 6, 43, 0, 9, 0, 103, 0,
+  43, 0, 51, 0, 0, 102, 14, 0, 4, 0,
+  39, 0, 27, 51, 8, 13, 23, 3, 26, 91,
+  67, 61, 21, 56, 0, 0, 0, 56, 53, 69,
+  6, 74, 0, 0, 14, 0, 81, 1, 0, 0,
+  0, 25, 0, 38, 0, 16, 42, 22, 1, 7,
+  22, 19, 0, 49, 2, 1, 68, 52, 0, 0,
+  0, 9, 0, 50, 0, 0, 0, 0, 0, 0,
+  91, 11, 34, 0, 0, 0, 15, 26, 42, 23,
+  0, 6, 0, 4, 107, 11, 0, 0, 11, 8,
+  10, 15, 30, 12, 42, 45, 0, 41, 0, 10,
+  0, 0, 0, 81, 0, 0, 14, 0, 46, 0,
+  23, 15, 32, 37, 0, 0, 0, 0, 0, 0,
+  0, 0, 12, 0, 30, 11, 149, 0, 76, 0,
+  46, 0, 11, 24, 0, 20, 0, 8, 0, 0,
+  72, 0, 0, 35, 0, 0, 0, 0, 0, 45,
+  6, 0, 35, 11, 0, 11, 0, 0, 13, 0,
+  0, 0, 2, 13, 0, 0, 0, 0, 29, 44,
+  34, 0, 50, 0, 0, 11, 0, 7, 0, 0,
+  0, 0, 8, 60, 0, 0, 108, 136, 34, 5,
+  37, 0, 0, 24, 71, 27, 134, 39, 0, 0,
+  0, 158, 66, 0, 9, 0, 0, 10, 0, 0,
+  39, 0, 9, 0, 13, 5, 9, 0, 4, 0,
+  70, 0, 0, 80, 0, 0, 27, 0, 26, 0,
+  39, 45, 33, 130, 0, 0, 0, 0, 0, 84,
+  0, 0, 0, 0, 0, 24, 23, 13, 0, 0,
+  36, 0, 0, 0, 0, 0, 23, 31, 12, 0,
+  0, 15, 0, 0, 0, 50, 0, 0, 53, 14,
+  0, 2, 0, 0, 0, 0, 0, 48, 12, 0,
+  0, 0, 0, 19, 0, 0, 0, 3, 0, 0,
+  3, 11, 0, 0, 0, 9, 43, 82, 35, 0,
+  70, 0, 5, 16, 0, 7, 7, 0, 0, 0,
+  0, 63, 0, 0, 57, 160, 47, 9, 35, 0,
+  0, 29, 57, 0, 153, 4, 0, 0, 0, 121,
+  122, 0, 14, 27, 0, 33, 0, 0, 46, 0,
+  6, 0, 5, 13, 16, 0, 0, 10, 64, 0,
+  0, 128, 0, 0, 35, 0, 0, 0, 10, 76,
+  58, 96, 0, 0, 0, 0, 0, 62, 0, 0,
+  0, 3, 0, 35, 0, 0, 0, 0, 53, 0,
+  0, 0, 0, 0, 18, 28, 29, 0, 0, 39,
+  0, 0, 0, 29, 0, 0, 78, 47, 0, 0,
+  30, 0, 0, 88, 39, 61, 6, 17, 0, 0,
+  0, 41, 0, 0, 7, 53, 6, 0, 17, 0,
+  36, 0, 0, 0, 35, 96, 0, 0, 48, 0,
+  9, 30, 0, 28, 42, 19, 0, 0, 0, 32,
+  2, 0, 4, 101, 46, 8, 0, 0, 0, 0,
+  0, 0, 66, 0, 6, 4, 24, 53, 52, 0,
+  17, 37, 0, 49, 0, 0, 5, 0, 39, 0,
+  0, 0, 0, 1, 0, 30, 51, 0, 0, 131,
+  0, 0, 11, 0, 0, 0, 0, 86, 87, 31,
+  0, 0, 0, 0, 0, 48, 0, 13, 0, 11,
+  0, 8, 2, 0, 0, 2, 51, 0, 25, 0,
+  41, 0, 28, 12, 43, 0, 0, 57, 0, 0,
+  7, 0, 75, 49, 21, 35, 0, 26, 12, 9,
+  20, 56, 23, 65, 41, 43, 0, 0, 0, 51,
+  49, 70, 25, 60, 128, 38, 16, 1, 47, 0,
+  34, 0, 0, 0, 0, 68, 0, 0, 51, 15,
+  10, 0, 33, 0, 0, 22, 41, 66, 39, 66,
+  0, 5, 0, 59, 0, 43, 0, 0, 13, 40,
+  0, 20, 49, 2, 9, 0, 0, 5, 40, 0,
+  43, 31, 0, 19, 43, 2, 80, 35, 0, 14,
+  27, 0, 17, 32, 100, 3, 76, 2, 0, 16,
+  24, 9, 46, 5, 10, 44, 0, 0, 7, 0,
+  65, 0, 4, 31, 54, 32, 37, 0, 31, 0,
+  29, 0, 0, 0, 10, 17, 45, 22, 97, 0,
+  76, 0, 23, 0, 0, 100, 25, 10, 0, 0,
+  70, 30, 19, 50, 0, 57, 14, 13, 11, 54,
+  10, 51, 32, 74, 0, 0, 0, 42, 41, 47,
+  55, 47, 140, 28, 0, 6, 69, 0, 51, 0,
+  0, 0, 0, 61, 0, 0, 55, 28, 10, 25,
+  39, 0, 0, 40, 29, 63, 62, 56, 3, 0,
+  0, 4, 0, 42, 0, 0, 18, 10, 0, 13,
+  27, 0, 4, 2, 3, 7, 57, 0, 55, 33,
+  0, 39, 43, 0, 86, 34, 0, 21, 5, 0,
+  34, 32, 104, 0, 59, 5, 0, 0, 22, 8,
+  33, 0, 3, 36, 0, 11, 27, 0, 66, 0,
+  37, 39, 34, 16, 38, 0, 27, 2, 5, 0,
+  0, 0, 0, 19, 44, 4, 64, 0, 73, 0,
+  11, 0, 0, 123, 31, 8, 0, 0, 58, 2,
+  5, 19, 0, 61, 49, 0, 0, 22, 6, 34,
+  22, 59, 0, 0, 47, 46, 38, 9, 61, 16,
+  179, 16, 0, 0, 76, 0, 51, 37, 0, 0,
+  40, 47, 0, 0, 71, 33, 17, 78, 26, 17,
+  0, 47, 0, 63, 77, 0, 7, 0, 7, 0,
+  0, 10, 13, 30, 0, 26, 0, 3, 14, 0,
+  1, 0, 72, 10, 34, 0, 44, 21, 8, 54,
+  16, 0, 64, 0, 25, 21, 0, 5, 39, 21,
+  53, 0, 0, 0, 23, 0, 9, 12, 0, 0,
+  0, 25, 0, 51, 27, 5, 41, 0, 55, 0,
+  0, 34, 30, 0, 0, 7, 0, 0, 0, 10,
+  31, 34, 58, 5, 0, 0, 20, 0, 0, 0,
+  0, 44, 0, 0, 11, 0, 30, 0, 44, 53,
+  0, 11, 18, 12, 0, 82, 51, 71, 16, 19,
+  0, 0, 0, 63, 28, 37, 0, 67, 2, 0,
+  45, 0, 33, 25, 0, 0, 0, 52, 0, 0,
+  18, 0, 13, 17, 0, 3, 20, 20, 0, 7,
+  2, 12, 49, 14, 0, 32, 19, 44, 0, 21,
+  12, 0, 0, 24, 0, 0, 80, 1, 40, 3,
+  0, 0, 8, 26, 18, 45, 0, 0, 0, 0,
+  87, 25, 0, 0, 27, 11, 0, 26, 28, 6,
+  18, 90, 0, 29, 0, 0, 0, 0, 0, 71,
+  9, 2, 14, 0, 37, 0, 0, 24, 1, 42,
+  0, 27, 0, 6, 32, 0, 0, 6, 43, 0,
+  9, 0, 103, 0, 43, 0, 51, 0, 0, 102,
+  14, 0, 4, 0, 39, 0, 27, 51, 8, 13,
+  23, 3, 26, 91, 67, 61, 21, 56, 0, 0,
+  0, 56, 53, 69, 6, 74, 0, 0, 14, 0,
+  81, 1, 0, 0, 0, 25, 0, 38, 0, 16,
+  42, 22, 1, 7, 22, 19, 0, 49, 2, 1,
+  68, 52, 0, 0, 0, 9, 0, 50, 0, 0,
+  0, 0, 0, 0, 91, 11, 34, 0, 0, 0,
+  15, 26, 42, 23, 0, 6, 0, 4, 107, 11,
+  0, 0, 11, 8, 10, 15, 30, 12, 42, 45,
+  0, 41, 0, 10, 0, 0, 0, 81, 0, 0,
+  14, 0, 46, 0, 23, 15, 32, 37, 0, 0,
+  0, 0, 0, 0, 0, 0, 12, 0, 30, 11,
+  149, 0, 76, 0, 46, 0, 0, 131, 52, 5,
+  17, 0, 45, 0, 11, 44, 5, 23, 60, 0,
+  17, 55, 55, 49, 15, 72, 0, 0, 12, 32,
+  54, 53, 11, 54, 0, 20, 0, 0, 76, 0,
+  17, 0, 0, 0, 0, 41, 0, 25, 68, 41,
+  28, 22, 40, 0, 0, 52, 0, 3, 85, 24,
+  0, 0, 0, 0, 0, 44, 4, 0, 0, 5,
+  0, 0, 29, 13, 13, 0, 0, 0, 8, 16,
+  74, 5, 15, 32, 0, 0, 97, 0, 0, 0,
+  14, 0, 30, 16, 22, 9, 0, 0, 0, 20,
+  0, 26, 0, 0, 0, 38, 5, 16, 9, 0,
+  39, 0, 48, 8, 25, 53, 0, 0, 0, 5,
+  0, 0, 0, 24, 33, 0, 34, 5, 77, 0,
+  62, 0, 29, 0, 0, 15, 0, 0, 0, 50,
+  0, 0, 53, 14, 0, 2, 0, 0, 0, 0,
+  0, 48, 12, 0, 0, 0, 0, 19, 0, 0,
+  0, 3, 0, 0, 3, 11, 0, 0, 0, 9,
+  43, 82, 35, 0, 70, 0, 5, 16, 0, 7,
+  7, 0, 0, 0, 0, 63, 0, 0, 57, 160,
+  47, 9, 35, 0, 0, 29, 57, 0, 153, 4,
+  0, 0, 0, 121, 122, 0, 14, 27, 0, 33,
+  0, 0, 46, 0, 6, 0, 5, 13, 16, 0,
+  0, 10, 64, 0, 0, 128, 0, 0, 35, 0,
+  0, 0, 10, 76, 58, 96, 0, 0, 0, 0,
+  0, 62, 0, 0, 0, 3, 0, 35, 0, 0,
+  0, 0, 53, 0, 0, 0, 0, 0, 18, 28,
+  29, 0, 0, 39, 0, 0, 0, 29, 0, 0,
+  78, 47, 0, 0, 30, 0, 0, 88, 39, 61,
+  6, 17, 0, 0, 0, 41, 0, 0, 7, 53,
+  6, 0, 17, 0, 36, 0, 0, 0, 35, 96,
+  0, 0, 48, 0, 9, 30, 0, 28, 42, 19,
+  0, 0, 0, 32, 2, 0, 4, 101, 46, 8,
+  0, 0, 0, 0, 0, 0, 66, 0, 6, 4,
+  24, 53, 52, 0, 17, 37, 0, 49, 0, 0,
+  5, 0, 39, 0, 0, 0, 0, 1, 0, 30,
+  51, 0, 0, 131, 0, 0, 11, 0, 0, 0,
+  0, 86, 87, 31, 0, 0, 0, 0, 0, 48,
+  0, 13, 0, 11, 0, 8, 2, 0, 0, 2,
+  51, 0, 25, 0, 41, 0, 28, 12, 43, 0,
+  0, 93, 41, 0, 7, 0, 52, 3, 86, 40,
+  12, 0, 76, 3, 0, 125, 70, 39, 2, 33,
+  0, 0, 0, 54, 36, 13, 16, 61, 3, 0,
+  21, 0, 90, 1, 0, 0, 0, 58, 0, 29,
+  9, 0, 26, 52, 0, 59, 72, 36, 0, 44,
+  0, 0, 84, 12, 0, 0, 22, 0, 0, 42,
+  0, 0, 0, 0, 0, 0, 47, 0, 62, 0,
+  0, 0, 2, 50, 38, 28, 0, 0, 0, 0,
+  77, 11, 8, 0, 0, 21, 0, 22, 43, 0,
+  0, 57, 0, 32, 0, 0, 0, 0, 0, 79,
+  66, 0, 0, 0, 15, 0, 10, 29, 0, 69,
+  0, 1, 0, 0, 0, 0, 0, 36, 65, 0,
+  62, 0, 139, 0, 57, 16, 25, 0, 0, 100,
+  25, 10, 0, 0, 70, 30, 19, 50, 0, 57,
+  14, 13, 11, 54, 10, 51, 32, 74, 0, 0,
+  0, 42, 41, 47, 55, 47, 140, 28, 0, 6,
+  69, 0, 51, 0, 0, 0, 0, 61, 0, 0,
+  55, 28, 10, 25, 39, 0, 0, 40, 29, 63,
+  62, 56, 3, 0, 0, 4, 0, 42, 0, 0,
+  18, 10, 0, 13, 27, 0, 4, 2, 3, 7,
+  57, 0, 55, 33, 0, 39, 43, 0, 86, 34,
+  0, 21, 5, 0, 34, 32, 104, 0, 59, 5,
+  0, 0, 22, 8, 33, 0, 3, 36, 0, 11,
+  27, 0, 66, 0, 37, 39, 34, 16, 38, 0,
+  27, 2, 5, 0, 0, 0, 0, 19, 44, 4,
+  64, 0, 73, 0, 11, 0, 0, 123, 31, 8,
+  0, 0, 58, 2, 5, 19, 0, 61, 49, 0,
+  0, 22, 6, 34, 22, 59, 0, 0, 47, 46,
+  38, 9, 61, 16, 179, 16, 0, 0, 76, 0,
+  51, 37, 0, 0, 40, 47, 0, 0, 71, 33,
+  17, 78, 26, 17, 0, 47, 0, 63, 77, 0,
+  7, 0, 7, 0, 0, 10, 13, 30, 0, 26,
+  0, 3, 14, 0, 1, 0, 72, 10, 34, 0,
+  44, 21, 8, 54, 16, 0, 64, 0, 25, 21,
+  0, 5, 39, 21, 53, 0, 0, 0, 23, 0,
+  9, 12, 0, 0, 0, 25, 0, 51, 27, 5,
+  41, 0, 55, 0, 0, 34, 30, 0, 0, 7,
+  0, 0, 0, 10, 31, 34, 58, 5, 0, 0,
+  20, 0, 0, 0, 5, 63, 0, 6, 0, 6,
+  70, 9, 0, 0, 0, 80, 68, 0, 0, 0,
+  4, 24, 17, 28, 10, 34, 89, 45, 45, 0,
+  53, 4, 206, 0, 0, 11, 57, 5, 17, 54,
+  0, 0, 60, 39, 0, 0, 1, 61, 12, 128,
+  21, 26, 0, 14, 0, 73, 56, 0, 20, 6,
+  28, 0, 28, 0, 56, 44, 0, 46, 15, 2,
+  13, 32, 46, 0, 134, 11, 24, 0, 54, 0,
+  56, 54, 12, 0, 36, 0, 34, 0, 0, 7,
+  35, 1, 23, 0, 0, 0, 35, 0, 0, 29,
+  0, 0, 59, 43, 6, 53, 7, 33, 53, 18,
+  22, 0, 0, 36, 0, 23, 0, 10, 0, 29,
+  0, 20, 61, 20, 68, 0, 0, 0, 0, 0,
+  0, 0, 0, 102, 14, 0, 4, 0, 39, 0,
+  27, 51, 8, 13, 23, 3, 26, 91, 67, 61,
+  21, 56, 0, 0, 0, 56, 53, 69, 6, 74,
+  0, 0, 14, 0, 81, 1, 0, 0, 0, 25,
+  0, 38, 0, 16, 42, 22, 1, 7, 22, 19,
+  0, 49, 2, 1, 68, 52, 0, 0, 0, 9,
+  0, 50, 0, 0, 0, 0, 0, 0, 91, 11,
+  34, 0, 0, 0, 15, 26, 42, 23, 0, 6,
+  0, 4, 107, 11, 0, 0, 11, 8, 10, 15,
+  30, 12, 42, 45, 0, 41, 0, 10, 0, 0,
+  0, 81, 0, 0, 14, 0, 46, 0, 23, 15,
+  32, 37, 0, 0, 0, 0, 0, 0, 0, 0,
+  12, 0, 30, 11, 149, 0, 76, 0, 46, 0,
+  0, 131, 52, 5, 17, 0, 45, 0, 11, 44,
+  5, 23, 60, 0, 17, 55, 55, 49, 15, 72,
+  0, 0, 12, 32, 54, 53, 11, 54, 0, 20,
+  0, 0, 76, 0, 17, 0, 0, 0, 0, 41,
+  0, 25, 68, 41, 28, 22, 40, 0, 0, 52,
+  0, 3, 85, 24, 0, 0, 0, 0, 0, 44,
+  4, 0, 0, 5, 0, 0, 29, 13, 13, 0,
+  0, 0, 8, 16, 74, 5, 15, 32, 0, 0,
+  97, 0, 0, 0, 14, 0, 30, 16, 22, 9,
+  0, 0, 0, 20, 0, 26, 0, 0, 0, 38,
+  5, 16, 9, 0, 39, 0, 48, 8, 25, 53,
+  0, 0, 0, 5, 0, 0, 0, 24, 33, 0,
+  34, 5, 77, 0, 62, 0, 29, 0, 0, 75,
+  0, 0, 5, 14, 48, 1, 0, 0, 0, 56,
+  51, 0, 0, 4, 32, 10, 13, 41, 0, 10,
+  71, 13, 29, 0, 10, 14, 0, 17, 0, 0,
+  42, 0, 5, 27, 0, 0, 9, 20, 0, 26,
+  0, 66, 11, 74, 35, 26, 0, 2, 0, 16,
+  68, 0, 0, 0, 30, 0, 1, 5, 28, 45,
+  0, 49, 0, 0, 0, 37, 29, 0, 51, 0,
+  22, 9, 83, 12, 47, 23, 0, 0, 69, 0,
+  4, 0, 38, 0, 23, 2, 0, 0, 0, 0,
+  0, 6, 0, 38, 0, 0, 22, 49, 15, 29,
+  19, 13, 22, 0, 31, 11, 0, 28, 0, 0,
+  0, 0, 0, 0, 0, 19, 71, 6, 22, 4,
+  0, 0, 22, 0, 10, 0, 0, 39, 0, 0,
+  0, 29, 0, 0, 78, 47, 0, 0, 30, 0,
+  0, 88, 39, 61, 6, 17, 0, 0, 0, 41,
+  0, 0, 7, 53, 6, 0, 17, 0, 36, 0,
+  0, 0, 35, 96, 0, 0, 48, 0, 9, 30,
+  0, 28, 42, 19, 0, 0, 0, 32, 2, 0,
+  4, 101, 46, 8, 0, 0, 0, 0, 0, 0,
+  66, 0, 6, 4, 24, 53, 52, 0, 17, 37,
+  0, 49, 0, 0, 5, 0, 39, 0, 0, 0,
+  0, 1, 0, 30, 51, 0, 0, 131, 0, 0,
+  11, 0, 0, 0, 0, 86, 87, 31, 0, 0,
+  0, 0, 0, 48, 0, 13, 0, 11, 0, 8,
+  2, 0, 0, 2, 51, 0, 25, 0, 41, 0,
+  28, 12, 43, 0, 0, 93, 41, 0, 7, 0,
+  52, 3, 86, 40, 12, 0, 76, 3, 0, 125,
+  70, 39, 2, 33, 0, 0, 0, 54, 36, 13,
+  16, 61, 3, 0, 21, 0, 90, 1, 0, 0,
+  0, 58, 0, 29, 9, 0, 26, 52, 0, 59,
+  72, 36, 0, 44, 0, 0, 84, 12, 0, 0,
+  22, 0, 0, 42, 0, 0, 0, 0, 0, 0,
+  47, 0, 62, 0, 0, 0, 2, 50, 38, 28,
+  0, 0, 0, 0, 77, 11, 8, 0, 0, 21,
+  0, 22, 43, 0, 0, 57, 0, 32, 0, 0,
+  0, 0, 0, 79, 66, 0, 0, 0, 15, 0,
+  10, 29, 0, 69, 0, 1, 0, 0, 0, 0,
+  0, 36, 65, 0, 62, 0, 139, 0, 57, 16,
+  25, 0, 0, 58, 49, 0, 14, 0, 50, 16,
+  63, 8, 3, 26, 61, 1, 7, 53, 52, 0,
+  0, 15, 0, 27, 43, 19, 23, 0, 0, 13,
+  0, 0, 0, 0, 41, 0, 0, 6, 0, 16,
+  0, 79, 0, 24, 0, 55, 1, 70, 61, 46,
+  0, 21, 0, 20, 72, 1, 0, 0, 29, 0,
+  0, 0, 15, 36, 0, 43, 0, 14, 0, 0,
+  79, 0, 0, 0, 7, 27, 66, 15, 34, 28,
+  0, 0, 79, 0, 29, 0, 25, 0, 16, 0,
+  0, 0, 0, 0, 0, 17, 0, 26, 0, 0,
+  5, 71, 31, 0, 0, 0, 26, 0, 28, 0,
+  0, 38, 0, 0, 0, 2, 0, 0, 2, 14,
+  69, 0, 27, 0, 63, 0, 43, 7, 17, 0,
+  0, 123, 31, 8, 0, 0, 58, 2, 5, 19,
+  0, 61, 49, 0, 0, 22, 6, 34, 22, 59,
+  0, 0, 47, 46, 38, 9, 61, 16, 179, 16,
+  0, 0, 76, 0, 51, 37, 0, 0, 40, 47,
+  0, 0, 71, 33, 17, 78, 26, 17, 0, 47,
+  0, 63, 77, 0, 7, 0, 7, 0, 0, 10,
+  13, 30, 0, 26, 0, 3, 14, 0, 1, 0,
+  72, 10, 34, 0, 44, 21, 8, 54, 16, 0,
+  64, 0, 25, 21, 0, 5, 39, 21, 53, 0,
+  0, 0, 23, 0, 9, 12, 0, 0, 0, 25,
+  0, 51, 27, 5, 41, 0, 55, 0, 0, 34,
+  30, 0, 0, 7, 0, 0, 0, 10, 31, 34,
+  58, 5, 0, 0, 20, 0, 0, 0, 5, 63,
+  0, 6, 0, 6, 70, 9, 0, 0, 0, 80,
+  68, 0, 0, 0, 4, 24, 17, 28, 10, 34,
+  89, 45, 45, 0, 53, 4, 206, 0, 0, 11,
+  57, 5, 17, 54, 0, 0, 60, 39, 0, 0,
+  1, 61, 12, 128, 21, 26, 0, 14, 0, 73,
+  56, 0, 20, 6, 28, 0, 28, 0, 56, 44,
+  0, 46, 15, 2, 13, 32, 46, 0, 134, 11,
+  24, 0, 54, 0, 56, 54, 12, 0, 36, 0,
+  34, 0, 0, 7, 35, 1, 23, 0, 0, 0,
+  35, 0, 0, 29, 0, 0, 59, 43, 6, 53,
+  7, 33, 53, 18, 22, 0, 0, 36, 0, 23,
+  0, 10, 0, 29, 0, 20, 61, 20, 68, 0,
+  0, 0, 0, 0, 0, 0, 23, 19, 0, 34,
+  10, 9, 83, 40, 0, 0, 0, 24, 57, 8,
+  0, 49, 29, 55, 14, 27, 77, 6, 23, 33,
+  54, 0, 58, 20, 192, 4, 0, 22, 109, 15,
+  46, 0, 0, 37, 38, 5, 0, 0, 0, 70,
+  41, 137, 1, 46, 0, 13, 0, 79, 54, 2,
+  11, 54, 16, 0, 0, 0, 37, 0, 13, 6,
+  0, 0, 18, 17, 31, 11, 84, 0, 5, 0,
+  13, 0, 66, 45, 13, 0, 58, 0, 30, 0,
+  0, 0, 28, 0, 31, 38, 0, 18, 0, 18,
+  32, 25, 25, 0, 48, 37, 18, 2, 0, 55,
+  81, 0, 12, 13, 23, 14, 0, 32, 10, 37,
+  0, 0, 29, 0, 19, 21, 86, 0, 13, 0,
+  0, 0, 37, 12, 0, 131, 52, 5, 17, 0,
+  45, 0, 11, 44, 5, 23, 60, 0, 17, 55,
+  55, 49, 15, 72, 0, 0, 12, 32, 54, 53,
+  11, 54, 0, 20, 0, 0, 76, 0, 17, 0,
+  0, 0, 0, 41, 0, 25, 68, 41, 28, 22,
+  40, 0, 0, 52, 0, 3, 85, 24, 0, 0,
+  0, 0, 0, 44, 4, 0, 0, 5, 0, 0,
+  29, 13, 13, 0, 0, 0, 8, 16, 74, 5,
+  15, 32, 0, 0, 97, 0, 0, 0, 14, 0,
+  30, 16, 22, 9, 0, 0, 0, 20, 0, 26,
+  0, 0, 0, 38, 5, 16, 9, 0, 39, 0,
+  48, 8, 25, 53, 0, 0, 0, 5, 0, 0,
+  0, 24, 33, 0, 34, 5, 77, 0, 62, 0,
+  29, 0, 0, 75, 0, 0, 5, 14, 48, 1,
+  0, 0, 0, 56, 51, 0, 0, 4, 32, 10,
+  13, 41, 0, 10, 71, 13, 29, 0, 10, 14,
+  0, 17, 0, 0, 42, 0, 5, 27, 0, 0,
+  9, 20, 0, 26, 0, 66, 11, 74, 35, 26,
+  0, 2, 0, 16, 68, 0, 0, 0, 30, 0,
+  1, 5, 28, 45, 0, 49, 0, 0, 0, 37,
+  29, 0, 51, 0, 22, 9, 83, 12, 47, 23,
+  0, 0, 69, 0, 4, 0, 38, 0, 23, 2,
+  0, 0, 0, 0, 0, 6, 0, 38, 0, 0,
+  22, 49, 15, 29, 19, 13, 22, 0, 31, 11,
+  0, 28, 0, 0, 0, 0, 0, 0, 0, 19,
+  71, 6, 22, 4, 0, 0, 22, 0, 10, 0,
+  7, 18, 0, 16, 0, 21, 57, 17, 0, 0,
+  0, 41, 57, 2, 0, 6, 60, 44, 5, 5,
+  45, 0, 15, 0, 37, 0, 27, 0, 0, 35,
+  0, 0, 85, 0, 0, 0, 0, 5, 0, 0,
+  0, 23, 0, 64, 4, 113, 25, 79, 0, 0,
+  0, 41, 66, 0, 0, 22, 11, 0, 0, 0,
+  15, 0, 0, 2, 0, 0, 0, 36, 38, 0,
+  60, 0, 2, 0, 50, 0, 47, 0, 0, 0,
+  62, 0, 47, 0, 7, 0, 20, 0, 0, 8,
+  0, 4, 0, 8, 0, 7, 0, 0, 51, 44,
+  26, 26, 0, 37, 18, 0, 29, 6, 9, 13,
+  0, 18, 0, 17, 0, 0, 6, 0, 36, 0,
+  37, 0, 37, 0, 0, 0, 38, 0, 0, 93,
+  41, 0, 7, 0, 52, 3, 86, 40, 12, 0,
+  76, 3, 0, 125, 70, 39, 2, 33, 0, 0,
+  0, 54, 36, 13, 16, 61, 3, 0, 21, 0,
+  90, 1, 0, 0, 0, 58, 0, 29, 9, 0,
+  26, 52, 0, 59, 72, 36, 0, 44, 0, 0,
+  84, 12, 0, 0, 22, 0, 0, 42, 0, 0,
+  0, 0, 0, 0, 47, 0, 62, 0, 0, 0,
+  2, 50, 38, 28, 0, 0, 0, 0, 77, 11,
+  8, 0, 0, 21, 0, 22, 43, 0, 0, 57,
+  0, 32, 0, 0, 0, 0, 0, 79, 66, 0,
+  0, 0, 15, 0, 10, 29, 0, 69, 0, 1,
+  0, 0, 0, 0, 0, 36, 65, 0, 62, 0,
+  139, 0, 57, 16, 25, 0, 0, 58, 49, 0,
+  14, 0, 50, 16, 63, 8, 3, 26, 61, 1,
+  7, 53, 52, 0, 0, 15, 0, 27, 43, 19,
+  23, 0, 0, 13, 0, 0, 0, 0, 41, 0,
+  0, 6, 0, 16, 0, 79, 0, 24, 0, 55,
+  1, 70, 61, 46, 0, 21, 0, 20, 72, 1,
+  0, 0, 29, 0, 0, 0, 15, 36, 0, 43,
+  0, 14, 0, 0, 79, 0, 0, 0, 7, 27,
+  66, 15, 34, 28, 0, 0, 79, 0, 29, 0,
+  25, 0, 16, 0, 0, 0, 0, 0, 0, 17,
+  0, 26, 0, 0, 5, 71, 31, 0, 0, 0,
+  26, 0, 28, 0, 0, 38, 0, 0, 0, 2,
+  0, 0, 2, 14, 69, 0, 27, 0, 63, 0,
+  43, 7, 17, 0, 0, 6, 0, 0, 0, 1,
+  30, 12, 26, 0, 0, 25, 43, 0, 8, 23,
+  56, 23, 0, 0, 32, 29, 18, 2, 25, 0,
+  0, 0, 0, 0, 0, 0, 36, 17, 0, 0,
+  0, 0, 0, 34, 0, 11, 0, 58, 21, 87,
+  29, 59, 0, 1, 0, 52, 63, 0, 3, 0,
+  12, 0, 0, 0, 25, 4, 0, 38, 0, 10,
+  4, 0, 42, 0, 34, 0, 0, 17, 34, 0,
+  45, 41, 0, 0, 77, 0, 55, 0, 5, 0,
+  14, 0, 0, 0, 0, 31, 0, 0, 0, 22,
+  0, 0, 32, 57, 30, 0, 0, 9, 8, 0,
+  15, 0, 0, 13, 0, 14, 0, 2, 0, 0,
+  29, 0, 33, 0, 14, 0, 33, 0, 13, 6,
+  20, 0, 5, 63, 0, 6, 0, 6, 70, 9,
+  0, 0, 0, 80, 68, 0, 0, 0, 4, 24,
+  17, 28, 10, 34, 89, 45, 45, 0, 53, 4,
+  206, 0, 0, 11, 57, 5, 17, 54, 0, 0,
+  60, 39, 0, 0, 1, 61, 12, 128, 21, 26,
+  0, 14, 0, 73, 56, 0, 20, 6, 28, 0,
+  28, 0, 56, 44, 0, 46, 15, 2, 13, 32,
+  46, 0, 134, 11, 24, 0, 54, 0, 56, 54,
+  12, 0, 36, 0, 34, 0, 0, 7, 35, 1,
+  23, 0, 0, 0, 35, 0, 0, 29, 0, 0,
+  59, 43, 6, 53, 7, 33, 53, 18, 22, 0,
+  0, 36, 0, 23, 0, 10, 0, 29, 0, 20,
+  61, 20, 68, 0, 0, 0, 0, 0, 0, 0,
+  23, 19, 0, 34, 10, 9, 83, 40, 0, 0,
+  0, 24, 57, 8, 0, 49, 29, 55, 14, 27,
+  77, 6, 23, 33, 54, 0, 58, 20, 192, 4,
+  0, 22, 109, 15, 46, 0, 0, 37, 38, 5,
+  0, 0, 0, 70, 41, 137, 1, 46, 0, 13,
+  0, 79, 54, 2, 11, 54, 16, 0, 0, 0,
+  37, 0, 13, 6, 0, 0, 18, 17, 31, 11,
+  84, 0, 5, 0, 13, 0, 66, 45, 13, 0,
+  58, 0, 30, 0, 0, 0, 28, 0, 31, 38,
+  0, 18, 0, 18, 32, 25, 25, 0, 48, 37,
+  18, 2, 0, 55, 81, 0, 12, 13, 23, 14,
+  0, 32, 10, 37, 0, 0, 29, 0, 19, 21,
+  86, 0, 13, 0, 0, 0, 37, 12, 0, 33,
+  0, 8, 0, 0, 88, 51, 0, 25, 4, 29,
+  23, 1, 15, 91, 42, 50, 0, 22, 30, 0,
+  0, 49, 47, 30, 47, 45, 143, 63, 23, 6,
+  105, 25, 47, 0, 0, 39, 4, 30, 0, 3,
+  39, 25, 43, 65, 2, 47, 0, 56, 16, 77,
+  68, 39, 2, 24, 5, 0, 0, 43, 0, 0,
+  0, 26, 0, 4, 28, 0, 0, 0, 1, 21,
+  0, 0, 4, 46, 30, 14, 4, 0, 94, 0,
+  0, 19, 0, 0, 9, 3, 54, 33, 28, 12,
+  0, 25, 28, 16, 54, 0, 16, 44, 0, 0,
+  10, 24, 96, 0, 13, 21, 39, 36, 23, 10,
+  46, 34, 8, 0, 13, 0, 3, 31, 63, 19,
+  94, 0, 15, 0, 17, 0, 0, 75, 0, 0,
+  5, 14, 48, 1, 0, 0, 0, 56, 51, 0,
+  0, 4, 32, 10, 13, 41, 0, 10, 71, 13,
+  29, 0, 10, 14, 0, 17, 0, 0, 42, 0,
+  5, 27, 0, 0, 9, 20, 0, 26, 0, 66,
+  11, 74, 35, 26, 0, 2, 0, 16, 68, 0,
+  0, 0, 30, 0, 1, 5, 28, 45, 0, 49,
+  0, 0, 0, 37, 29, 0, 51, 0, 22, 9,
+  83, 12, 47, 23, 0, 0, 69, 0, 4, 0,
+  38, 0, 23, 2, 0, 0, 0, 0, 0, 6,
+  0, 38, 0, 0, 22, 49, 15, 29, 19, 13,
+  22, 0, 31, 11, 0, 28, 0, 0, 0, 0,
+  0, 0, 0, 19, 71, 6, 22, 4, 0, 0,
+  22, 0, 10, 0, 7, 18, 0, 16, 0, 21,
+  57, 17, 0, 0, 0, 41, 57, 2, 0, 6,
+  60, 44, 5, 5, 45, 0, 15, 0, 37, 0,
+  27, 0, 0, 35, 0, 0, 85, 0, 0, 0,
+  0, 5, 0, 0, 0, 23, 0, 64, 4, 113,
+  25, 79, 0, 0, 0, 41, 66, 0, 0, 22,
+  11, 0, 0, 0, 15, 0, 0, 2, 0, 0,
+  0, 36, 38, 0, 60, 0, 2, 0, 50, 0,
+  47, 0, 0, 0, 62, 0, 47, 0, 7, 0,
+  20, 0, 0, 8, 0, 4, 0, 8, 0, 7,
+  0, 0, 51, 44, 26, 26, 0, 37, 18, 0,
+  29, 6, 9, 13, 0, 18, 0, 17, 0, 0,
+  6, 0, 36, 0, 37, 0, 37, 0, 0, 0,
+  38, 0, 0, 12, 0, 42, 6, 15, 37, 28,
+  4, 4, 6, 14, 22, 0, 5, 59, 66, 39,
+  0, 24, 0, 0, 0, 20, 47, 15, 29, 33,
+  0, 35, 0, 0, 91, 34, 6, 0, 0, 11,
+  0, 10, 0, 18, 0, 22, 0, 58, 46, 78,
+  0, 43, 0, 62, 86, 46, 0, 56, 0, 0,
+  0, 20, 4, 0, 0, 0, 0, 0, 39, 0,
+  35, 6, 23, 0, 0, 0, 28, 23, 8, 0,
+  0, 0, 113, 0, 11, 9, 0, 0, 7, 22,
+  0, 0, 22, 29, 0, 8, 36, 0, 36, 0,
+  26, 59, 19, 7, 14, 19, 16, 0, 26, 17,
+  35, 32, 0, 9, 19, 42, 0, 0, 5, 0,
+  0, 0, 14, 11, 125, 0, 35, 0, 0, 0,
+  0, 58, 49, 0, 14, 0, 50, 16, 63, 8,
+  3, 26, 61, 1, 7, 53, 52, 0, 0, 15,
+  0, 27, 43, 19, 23, 0, 0, 13, 0, 0,
+  0, 0, 41, 0, 0, 6, 0, 16, 0, 79,
+  0, 24, 0, 55, 1, 70, 61, 46, 0, 21,
+  0, 20, 72, 1, 0, 0, 29, 0, 0, 0,
+  15, 36, 0, 43, 0, 14, 0, 0, 79, 0,
+  0, 0, 7, 27, 66, 15, 34, 28, 0, 0,
+  79, 0, 29, 0, 25, 0, 16, 0, 0, 0,
+  0, 0, 0, 17, 0, 26, 0, 0, 5, 71,
+  31, 0, 0, 0, 26, 0, 28, 0, 0, 38,
+  0, 0, 0, 2, 0, 0, 2, 14, 69, 0,
+  27, 0, 63, 0, 43, 7, 17, 0, 0, 6,
+  0, 0, 0, 1, 30, 12, 26, 0, 0, 25,
+  43, 0, 8, 23, 56, 23, 0, 0, 32, 29,
+  18, 2, 25, 0, 0, 0, 0, 0, 0, 0,
+  36, 17, 0, 0, 0, 0, 0, 34, 0, 11,
+  0, 58, 21, 87, 29, 59, 0, 1, 0, 52,
+  63, 0, 3, 0, 12, 0, 0, 0, 25, 4,
+  0, 38, 0, 10, 4, 0, 42, 0, 34, 0,
+  0, 17, 34, 0, 45, 41, 0, 0, 77, 0,
+  55, 0, 5, 0, 14, 0, 0, 0, 0, 31,
+  0, 0, 0, 22, 0, 0, 32, 57, 30, 0,
+  0, 9, 8, 0, 15, 0, 0, 13, 0, 14,
+  0, 2, 0, 0, 29, 0, 33, 0, 14, 0,
+  33, 0, 13, 6, 20, 0, 0, 5, 0, 30,
+  11, 9, 0, 0, 16, 0, 14, 0, 28, 0,
+  0, 43, 62, 17, 0, 4, 0, 0, 0, 14,
+  39, 0, 19, 14, 0, 0, 0, 0, 39, 51,
+  0, 0, 0, 0, 8, 0, 0, 0, 0, 26,
+  0, 76, 41, 64, 0, 17, 0, 73, 78, 15,
+  1, 58, 0, 0, 0, 0, 35, 0, 0, 26,
+  0, 0, 54, 0, 52, 39, 59, 0, 0, 16,
+  4, 0, 13, 36, 0, 0, 89, 0, 49, 0,
+  0, 20, 1, 30, 0, 0, 0, 79, 0, 0,
+  39, 0, 21, 0, 17, 79, 53, 5, 0, 14,
+  0, 0, 0, 9, 0, 17, 0, 33, 0, 25,
+  0, 0, 3, 0, 0, 0, 0, 0, 77, 0,
+  14, 5, 4, 0, 23, 19, 0, 34, 10, 9,
+  83, 40, 0, 0, 0, 24, 57, 8, 0, 49,
+  29, 55, 14, 27, 77, 6, 23, 33, 54, 0,
+  58, 20, 192, 4, 0, 22, 109, 15, 46, 0,
+  0, 37, 38, 5, 0, 0, 0, 70, 41, 137,
+  1, 46, 0, 13, 0, 79, 54, 2, 11, 54,
+  16, 0, 0, 0, 37, 0, 13, 6, 0, 0,
+  18, 17, 31, 11, 84, 0, 5, 0, 13, 0,
+  66, 45, 13, 0, 58, 0, 30, 0, 0, 0,
+  28, 0, 31, 38, 0, 18, 0, 18, 32, 25,
+  25, 0, 48, 37, 18, 2, 0, 55, 81, 0,
+  12, 13, 23, 14, 0, 32, 10, 37, 0, 0,
+  29, 0, 19, 21, 86, 0, 13, 0, 0, 0,
+  37, 12, 0, 33, 0, 8, 0, 0, 88, 51,
+  0, 25, 4, 29, 23, 1, 15, 91, 42, 50,
+  0, 22, 30, 0, 0, 49, 47, 30, 47, 45,
+  143, 63, 23, 6, 105, 25, 47, 0, 0, 39,
+  4, 30, 0, 3, 39, 25, 43, 65, 2, 47,
+  0, 56, 16, 77, 68, 39, 2, 24, 5, 0,
+  0, 43, 0, 0, 0, 26, 0, 4, 28, 0,
+  0, 0, 1, 21, 0, 0, 4, 46, 30, 14,
+  4, 0, 94, 0, 0, 19, 0, 0, 9, 3,
+  54, 33, 28, 12, 0, 25, 28, 16, 54, 0,
+  16, 44, 0, 0, 10, 24, 96, 0, 13, 21,
+  39, 36, 23, 10, 46, 34, 8, 0, 13, 0,
+  3, 31, 63, 19, 94, 0, 15, 0, 17, 0,
+  0, 98, 1, 0, 0, 0, 70, 26, 1, 40,
+  0, 18, 8, 0, 0, 55, 20, 56, 0, 28,
+  0, 0, 9, 77, 37, 43, 56, 51, 165, 33,
+  18, 0, 85, 0, 49, 0, 0, 7, 13, 31,
+  0, 0, 65, 0, 42, 42, 0, 0, 0, 51,
+  14, 68, 75, 5, 23, 0, 0, 0, 0, 38,
+  0, 3, 1, 24, 0, 20, 44, 0, 0, 18,
+  0, 29, 38, 5, 30, 64, 3, 48, 31, 0,
+  73, 0, 0, 22, 0, 9, 14, 16, 72, 24,
+  54, 0, 0, 3, 10, 1, 31, 0, 4, 29,
+  0, 13, 27, 0, 87, 0, 38, 9, 40, 53,
+  46, 4, 16, 15, 5, 0, 5, 0, 11, 52,
+  56, 10, 49, 0, 36, 0, 7, 0, 7, 18,
+  0, 16, 0, 21, 57, 17, 0, 0, 0, 41,
+  57, 2, 0, 6, 60, 44, 5, 5, 45, 0,
+  15, 0, 37, 0, 27, 0, 0, 35, 0, 0,
+  85, 0, 0, 0, 0, 5, 0, 0, 0, 23,
+  0, 64, 4, 113, 25, 79, 0, 0, 0, 41,
+  66, 0, 0, 22, 11, 0, 0, 0, 15, 0,
+  0, 2, 0, 0, 0, 36, 38, 0, 60, 0,
+  2, 0, 50, 0, 47, 0, 0, 0, 62, 0,
+  47, 0, 7, 0, 20, 0, 0, 8, 0, 4,
+  0, 8, 0, 7, 0, 0, 51, 44, 26, 26,
+  0, 37, 18, 0, 29, 6, 9, 13, 0, 18,
+  0, 17, 0, 0, 6, 0, 36, 0, 37, 0,
+  37, 0, 0, 0, 38, 0, 0, 12, 0, 42,
+  6, 15, 37, 28, 4, 4, 6, 14, 22, 0,
+  5, 59, 66, 39, 0, 24, 0, 0, 0, 20,
+  47, 15, 29, 33, 0, 35, 0, 0, 91, 34,
+  6, 0, 0, 11, 0, 10, 0, 18, 0, 22,
+  0, 58, 46, 78, 0, 43, 0, 62, 86, 46,
+  0, 56, 0, 0, 0, 20, 4, 0, 0, 0,
+  0, 0, 39, 0, 35, 6, 23, 0, 0, 0,
+  28, 23, 8, 0, 0, 0, 113, 0, 11, 9,
+  0, 0, 7, 22, 0, 0, 22, 29, 0, 8,
+  36, 0, 36, 0, 26, 59, 19, 7, 14, 19,
+  16, 0, 26, 17, 35, 32, 0, 9, 19, 42,
+  0, 0, 5, 0, 0, 0, 14, 11, 125, 0,
+  35, 0, 0, 0, 0, 93, 5, 24, 14, 0,
+  37, 16, 19, 24, 15, 1, 7, 0, 45, 74,
+  66, 43, 0, 20, 0, 0, 0, 49, 65, 69,
+  6, 62, 0, 1, 5, 0, 69, 27, 8, 0,
+  0, 8, 0, 34, 0, 35, 41, 0, 16, 0,
+  40, 0, 0, 56, 0, 37, 99, 45, 0, 4,
+  0, 17, 0, 45, 12, 0, 0, 33, 0, 12,
+  78, 0, 23, 0, 0, 0, 0, 6, 46, 35,
+  1, 18, 0, 2, 119, 0, 0, 1, 0, 16,
+  0, 27, 17, 29, 59, 0, 0, 26, 0, 8,
+  27, 0, 0, 42, 0, 0, 29, 0, 16, 0,
+  32, 10, 52, 56, 0, 0, 9, 11, 0, 0,
+  0, 0, 0, 0, 4, 23, 137, 0, 66, 0,
+  0, 0, 0, 6, 0, 0, 0, 1, 30, 12,
+  26, 0, 0, 25, 43, 0, 8, 23, 56, 23,
+  0, 0, 32, 29, 18, 2, 25, 0, 0, 0,
+  0, 0, 0, 0, 36, 17, 0, 0, 0, 0,
+  0, 34, 0, 11, 0, 58, 21, 87, 29, 59,
+  0, 1, 0, 52, 63, 0, 3, 0, 12, 0,
+  0, 0, 25, 4, 0, 38, 0, 10, 4, 0,
+  42, 0, 34, 0, 0, 17, 34, 0, 45, 41,
+  0, 0, 77, 0, 55, 0, 5, 0, 14, 0,
+  0, 0, 0, 31, 0, 0, 0, 22, 0, 0,
+  32, 57, 30, 0, 0, 9, 8, 0, 15, 0,
+  0, 13, 0, 14, 0, 2, 0, 0, 29, 0,
+  33, 0, 14, 0, 33, 0, 13, 6, 20, 0,
+  0, 5, 0, 30, 11, 9, 0, 0, 16, 0,
+  14, 0, 28, 0, 0, 43, 62, 17, 0, 4,
+  0, 0, 0, 14, 39, 0, 19, 14, 0, 0,
+  0, 0, 39, 51, 0, 0, 0, 0, 8, 0,
+  0, 0, 0, 26, 0, 76, 41, 64, 0, 17,
+  0, 73, 78, 15, 1, 58, 0, 0, 0, 0,
+  35, 0, 0, 26, 0, 0, 54, 0, 52, 39,
+  59, 0, 0, 16, 4, 0, 13, 36, 0, 0,
+  89, 0, 49, 0, 0, 20, 1, 30, 0, 0,
+  0, 79, 0, 0, 39, 0, 21, 0, 17, 79,
+  53, 5, 0, 14, 0, 0, 0, 9, 0, 17,
+  0, 33, 0, 25, 0, 0, 3, 0, 0, 0,
+  0, 0, 77, 0, 14, 5, 4, 0, 0, 37,
+  0, 30, 19, 0, 8, 0, 29, 1, 5, 0,
+  23, 0, 24, 68, 78, 31, 0, 2, 0, 0,
+  0, 40, 45, 0, 20, 28, 0, 0, 7, 0,
+  46, 69, 0, 0, 0, 8, 7, 0, 0, 0,
+  0, 16, 0, 35, 63, 39, 0, 11, 0, 42,
+  72, 27, 0, 30, 0, 4, 0, 3, 38, 0,
+  0, 31, 0, 0, 79, 0, 75, 41, 0, 0,
+  0, 12, 16, 0, 14, 1, 0, 0, 85, 0,
+  26, 0, 0, 32, 0, 18, 6, 0, 14, 72,
+  0, 6, 28, 0, 15, 0, 0, 80, 18, 0,
+  0, 7, 0, 0, 0, 0, 2, 22, 0, 30,
+  8, 22, 3, 0, 0, 0, 0, 0, 0, 0,
+  101, 0, 9, 26, 7, 0, 0, 33, 0, 8,
+  0, 0, 88, 51, 0, 25, 4, 29, 23, 1,
+  15, 91, 42, 50, 0, 22, 30, 0, 0, 49,
+  47, 30, 47, 45, 143, 63, 23, 6, 105, 25,
+  47, 0, 0, 39, 4, 30, 0, 3, 39, 25,
+  43, 65, 2, 47, 0, 56, 16, 77, 68, 39,
+  2, 24, 5, 0, 0, 43, 0, 0, 0, 26,
+  0, 4, 28, 0, 0, 0, 1, 21, 0, 0,
+  4, 46, 30, 14, 4, 0, 94, 0, 0, 19,
+  0, 0, 9, 3, 54, 33, 28, 12, 0, 25,
+  28, 16, 54, 0, 16, 44, 0, 0, 10, 24,
+  96, 0, 13, 21, 39, 36, 23, 10, 46, 34,
+  8, 0, 13, 0, 3, 31, 63, 19, 94, 0,
+  15, 0, 17, 0, 0, 98, 1, 0, 0, 0,
+  70, 26, 1, 40, 0, 18, 8, 0, 0, 55,
+  20, 56, 0, 28, 0, 0, 9, 77, 37, 43,
+  56, 51, 165, 33, 18, 0, 85, 0, 49, 0,
+  0, 7, 13, 31, 0, 0, 65, 0, 42, 42,
+  0, 0, 0, 51, 14, 68, 75, 5, 23, 0,
+  0, 0, 0, 38, 0, 3, 1, 24, 0, 20,
+  44, 0, 0, 18, 0, 29, 38, 5, 30, 64,
+  3, 48, 31, 0, 73, 0, 0, 22, 0, 9,
+  14, 16, 72, 24, 54, 0, 0, 3, 10, 1,
+  31, 0, 4, 29, 0, 13, 27, 0, 87, 0,
+  38, 9, 40, 53, 46, 4, 16, 15, 5, 0,
+  5, 0, 11, 52, 56, 10, 49, 0, 36, 0,
+  7, 0, 21, 87, 0, 17, 0, 0, 7, 0,
+  27, 18, 0, 30, 39, 0, 0, 11, 9, 43,
+  15, 26, 0, 36, 93, 68, 12, 0, 68, 46,
+  209, 0, 0, 0, 54, 0, 48, 43, 0, 0,
+  65, 3, 0, 0, 39, 14, 18, 96, 0, 0,
+  0, 10, 0, 107, 61, 0, 69, 0, 19, 0,
+  17, 0, 20, 40, 0, 0, 35, 25, 0, 0,
+  0, 58, 134, 10, 46, 0, 8, 33, 3, 95,
+  34, 0, 24, 0, 8, 20, 0, 5, 21, 22,
+  59, 0, 30, 0, 0, 0, 54, 0, 27, 0,
+  10, 43, 26, 72, 29, 15, 69, 18, 47, 0,
+  13, 38, 8, 8, 0, 1, 0, 0, 3, 0,
+  8, 49, 53, 0, 0, 0, 36, 0, 0, 0,
+  0, 12, 0, 42, 6, 15, 37, 28, 4, 4,
+  6, 14, 22, 0, 5, 59, 66, 39, 0, 24,
+  0, 0, 0, 20, 47, 15, 29, 33, 0, 35,
+  0, 0, 91, 34, 6, 0, 0, 11, 0, 10,
+  0, 18, 0, 22, 0, 58, 46, 78, 0, 43,
+  0, 62, 86, 46, 0, 56, 0, 0, 0, 20,
+  4, 0, 0, 0, 0, 0, 39, 0, 35, 6,
+  23, 0, 0, 0, 28, 23, 8, 0, 0, 0,
+  113, 0, 11, 9, 0, 0, 7, 22, 0, 0,
+  22, 29, 0, 8, 36, 0, 36, 0, 26, 59,
+  19, 7, 14, 19, 16, 0, 26, 17, 35, 32,
+  0, 9, 19, 42, 0, 0, 5, 0, 0, 0,
+  14, 11, 125, 0, 35, 0, 0, 0, 0, 93,
+  5, 24, 14, 0, 37, 16, 19, 24, 15, 1,
+  7, 0, 45, 74, 66, 43, 0, 20, 0, 0,
+  0, 49, 65, 69, 6, 62, 0, 1, 5, 0,
+  69, 27, 8, 0, 0, 8, 0, 34, 0, 35,
+  41, 0, 16, 0, 40, 0, 0, 56, 0, 37,
+  99, 45, 0, 4, 0, 17, 0, 45, 12, 0,
+  0, 33, 0, 12, 78, 0, 23, 0, 0, 0,
+  0, 6, 46, 35, 1, 18, 0, 2, 119, 0,
+  0, 1, 0, 16, 0, 27, 17, 29, 59, 0,
+  0, 26, 0, 8, 27, 0, 0, 42, 0, 0,
+  29, 0, 16, 0, 32, 10, 52, 56, 0, 0,
+  9, 11, 0, 0, 0, 0, 0, 0, 4, 23,
+  137, 0, 66, 0, 0, 0, 0, 115, 36, 17,
+  6, 0, 3, 0, 44, 17, 0, 0, 3, 0,
+  0, 24, 36, 38, 6, 35, 0, 0, 67, 53,
+  19, 0, 40, 54, 0, 0, 0, 0, 68, 0,
+  53, 8, 0, 0, 28, 2, 0, 0, 37, 25,
+  0, 67, 27, 0, 0, 2, 0, 53, 88, 0,
+  20, 0, 26, 0, 0, 0, 0, 27, 0, 0,
+  0, 0, 0, 0, 0, 14, 53, 0, 37, 17,
+  61, 42, 0, 74, 24, 0, 64, 0, 4, 21,
+  0, 0, 6, 36, 25, 20, 74, 0, 0, 0,
+  24, 0, 0, 0, 0, 53, 38, 17, 0, 0,
+  21, 4, 62, 0, 41, 58, 0, 16, 0, 3,
+  0, 0, 0, 0, 0, 6, 0, 0, 35, 0,
+  53, 1, 0, 0, 0, 5, 0, 30, 11, 9,
+  0, 0, 16, 0, 14, 0, 28, 0, 0, 43,
+  62, 17, 0, 4, 0, 0, 0, 14, 39, 0,
+  19, 14, 0, 0, 0, 0, 39, 51, 0, 0,
+  0, 0, 8, 0, 0, 0, 0, 26, 0, 76,
+  41, 64, 0, 17, 0, 73, 78, 15, 1, 58,
+  0, 0, 0, 0, 35, 0, 0, 26, 0, 0,
+  54, 0, 52, 39, 59, 0, 0, 16, 4, 0,
+  13, 36, 0, 0, 89, 0, 49, 0, 0, 20,
+  1, 30, 0, 0, 0, 79, 0, 0, 39, 0,
+  21, 0, 17, 79, 53, 5, 0, 14, 0, 0,
+  0, 9, 0, 17, 0, 33, 0, 25, 0, 0,
+  3, 0, 0, 0, 0, 0, 77, 0, 14, 5,
+  4, 0, 0, 37, 0, 30, 19, 0, 8, 0,
+  29, 1, 5, 0, 23, 0, 24, 68, 78, 31,
+  0, 2, 0, 0, 0, 40, 45, 0, 20, 28,
+  0, 0, 7, 0, 46, 69, 0, 0, 0, 8,
+  7, 0, 0, 0, 0, 16, 0, 35, 63, 39,
+  0, 11, 0, 42, 72, 27, 0, 30, 0, 4,
+  0, 3, 38, 0, 0, 31, 0, 0, 79, 0,
+  75, 41, 0, 0, 0, 12, 16, 0, 14, 1,
+  0, 0, 85, 0, 26, 0, 0, 32, 0, 18,
+  6, 0, 14, 72, 0, 6, 28, 0, 15, 0,
+  0, 80, 18, 0, 0, 7, 0, 0, 0, 0,
+  2, 22, 0, 30, 8, 22, 3, 0, 0, 0,
+  0, 0, 0, 0, 101, 0, 9, 26, 7, 0,
+  0, 119, 31, 10, 0, 0, 55, 0, 33, 18,
+  0, 0, 0, 0, 46, 39, 65, 38, 5, 18,
+  0, 0, 0, 46, 49, 6, 24, 40, 0, 0,
+  0, 0, 84, 26, 0, 0, 0, 16, 0, 3,
+  0, 0, 24, 17, 0, 45, 64, 6, 0, 10,
+  0, 0, 73, 0, 0, 0, 32, 0, 0, 35,
+  7, 5, 0, 0, 0, 0, 63, 0, 26, 11,
+  0, 0, 0, 15, 64, 26, 8, 27, 5, 0,
+  67, 3, 18, 28, 0, 6, 0, 0, 1, 26,
+  36, 0, 0, 22, 0, 0, 0, 0, 0, 60,
+  6, 0, 0, 0, 2, 0, 43, 0, 35, 36,
+  0, 21, 0, 19, 0, 0, 0, 0, 13, 0,
+  0, 0, 95, 0, 24, 41, 20, 0, 0, 98,
+  1, 0, 0, 0, 70, 26, 1, 40, 0, 18,
+  8, 0, 0, 55, 20, 56, 0, 28, 0, 0,
+  9, 77, 37, 43, 56, 51, 165, 33, 18, 0,
+  85, 0, 49, 0, 0, 7, 13, 31, 0, 0,
+  65, 0, 42, 42, 0, 0, 0, 51, 14, 68,
+  75, 5, 23, 0, 0, 0, 0, 38, 0, 3,
+  1, 24, 0, 20, 44, 0, 0, 18, 0, 29,
+  38, 5, 30, 64, 3, 48, 31, 0, 73, 0,
+  0, 22, 0, 9, 14, 16, 72, 24, 54, 0,
+  0, 3, 10, 1, 31, 0, 4, 29, 0, 13,
+  27, 0, 87, 0, 38, 9, 40, 53, 46, 4,
+  16, 15, 5, 0, 5, 0, 11, 52, 56, 10,
+  49, 0, 36, 0, 7, 0, 21, 87, 0, 17,
+  0, 0, 7, 0, 27, 18, 0, 30, 39, 0,
+  0, 11, 9, 43, 15, 26, 0, 36, 93, 68,
+  12, 0, 68, 46, 209, 0, 0, 0, 54, 0,
+  48, 43, 0, 0, 65, 3, 0, 0, 39, 14,
+  18, 96, 0, 0, 0, 10, 0, 107, 61, 0,
+  69, 0, 19, 0, 17, 0, 20, 40, 0, 0,
+  35, 25, 0, 0, 0, 58, 134, 10, 46, 0,
+  8, 33, 3, 95, 34, 0, 24, 0, 8, 20,
+  0, 5, 21, 22, 59, 0, 30, 0, 0, 0,
+  54, 0, 27, 0, 10, 43, 26, 72, 29, 15,
+  69, 18, 47, 0, 13, 38, 8, 8, 0, 1,
+  0, 0, 3, 0, 8, 49, 53, 0, 0, 0,
+  36, 0, 0, 0, 121, 68, 0, 69, 37, 0,
+  10, 0, 13, 0, 0, 24, 109, 0, 0, 19,
+  14, 0, 23, 0, 0, 116, 51, 34, 64, 0,
+  36, 36, 222, 0, 6, 97, 40, 17, 23, 41,
+  0, 0, 124, 6, 0, 0, 30, 56, 59, 90,
+  15, 0, 0, 12, 0, 135, 15, 0, 103, 17,
+  27, 22, 53, 0, 58, 43, 30, 87, 0, 83,
+  14, 0, 21, 25, 137, 20, 29, 0, 0, 0,
+  51, 86, 41, 0, 7, 0, 17, 24, 0, 13,
+  21, 0, 55, 9, 0, 0, 0, 0, 22, 16,
+  63, 0, 40, 42, 4, 62, 32, 21, 74, 29,
+  0, 42, 54, 0, 12, 14, 0, 0, 0, 27,
+  4, 0, 11, 38, 71, 25, 0, 34, 62, 0,
+  9, 24, 0, 93, 5, 24, 14, 0, 37, 16,
+  19, 24, 15, 1, 7, 0, 45, 74, 66, 43,
+  0, 20, 0, 0, 0, 49, 65, 69, 6, 62,
+  0, 1, 5, 0, 69, 27, 8, 0, 0, 8,
+  0, 34, 0, 35, 41, 0, 16, 0, 40, 0,
+  0, 56, 0, 37, 99, 45, 0, 4, 0, 17,
+  0, 45, 12, 0, 0, 33, 0, 12, 78, 0,
+  23, 0, 0, 0, 0, 6, 46, 35, 1, 18,
+  0, 2, 119, 0, 0, 1, 0, 16, 0, 27,
+  17, 29, 59, 0, 0, 26, 0, 8, 27, 0,
+  0, 42, 0, 0, 29, 0, 16, 0, 32, 10,
+  52, 56, 0, 0, 9, 11, 0, 0, 0, 0,
+  0, 0, 4, 23, 137, 0, 66, 0, 0, 0,
+  0, 115, 36, 17, 6, 0, 3, 0, 44, 17,
+  0, 0, 3, 0, 0, 24, 36, 38, 6, 35,
+  0, 0, 67, 53, 19, 0, 40, 54, 0, 0,
+  0, 0, 68, 0, 53, 8, 0, 0, 28, 2,
+  0, 0, 37, 25, 0, 67, 27, 0, 0, 2,
+  0, 53, 88, 0, 20, 0, 26, 0, 0, 0,
+  0, 27, 0, 0, 0, 0, 0, 0, 0, 14,
+  53, 0, 37, 17, 61, 42, 0, 74, 24, 0,
+  64, 0, 4, 21, 0, 0, 6, 36, 25, 20,
+  74, 0, 0, 0, 24, 0, 0, 0, 0, 53,
+  38, 17, 0, 0, 21, 4, 62, 0, 41, 58,
+  0, 16, 0, 3, 0, 0, 0, 0, 0, 6,
+  0, 0, 35, 0, 53, 1, 0, 0, 55, 68,
+  5, 59, 7, 0, 0, 0, 39, 0, 0, 18,
+  78, 0, 0, 0, 25, 2, 0, 0, 0, 34,
+  65, 19, 34, 0, 18, 36, 0, 0, 0, 6,
+  13, 0, 31, 16, 0, 0, 71, 0, 0, 16,
+  19, 37, 0, 40, 14, 0, 0, 0, 0, 107,
+  29, 0, 61, 0, 36, 0, 0, 0, 0, 19,
+  0, 10, 41, 34, 0, 0, 22, 0, 133, 0,
+  33, 13, 17, 0, 9, 54, 28, 7, 16, 0,
+  14, 15, 15, 0, 15, 0, 48, 0, 1, 0,
+  0, 0, 0, 0, 10, 0, 0, 40, 0, 1,
+  9, 0, 35, 68, 7, 20, 38, 3, 0, 13,
+  0, 0, 0, 0, 0, 0, 0, 9, 0, 0,
+  0, 0, 53, 0, 0, 0, 0, 37, 0, 30,
+  19, 0, 8, 0, 29, 1, 5, 0, 23, 0,
+  24, 68, 78, 31, 0, 2, 0, 0, 0, 40,
+  45, 0, 20, 28, 0, 0, 7, 0, 46, 69,
+  0, 0, 0, 8, 7, 0, 0, 0, 0, 16,
+  0, 35, 63, 39, 0, 11, 0, 42, 72, 27,
+  0, 30, 0, 4, 0, 3, 38, 0, 0, 31,
+  0, 0, 79, 0, 75, 41, 0, 0, 0, 12,
+  16, 0, 14, 1, 0, 0, 85, 0, 26, 0,
+  0, 32, 0, 18, 6, 0, 14, 72, 0, 6,
+  28, 0, 15, 0, 0, 80, 18, 0, 0, 7,
+  0, 0, 0, 0, 2, 22, 0, 30, 8, 22,
+  3, 0, 0, 0, 0, 0, 0, 0, 101, 0,
+  9, 26, 7, 0, 0, 119, 31, 10, 0, 0,
+  55, 0, 33, 18, 0, 0, 0, 0, 46, 39,
+  65, 38, 5, 18, 0, 0, 0, 46, 49, 6,
+  24, 40, 0, 0, 0, 0, 84, 26, 0, 0,
+  0, 16, 0, 3, 0, 0, 24, 17, 0, 45,
+  64, 6, 0, 10, 0, 0, 73, 0, 0, 0,
+  32, 0, 0, 35, 7, 5, 0, 0, 0, 0,
+  63, 0, 26, 11, 0, 0, 0, 15, 64, 26,
+  8, 27, 5, 0, 67, 3, 18, 28, 0, 6,
+  0, 0, 1, 26, 36, 0, 0, 22, 0, 0,
+  0, 0, 0, 60, 6, 0, 0, 0, 2, 0,
+  43, 0, 35, 36, 0, 21, 0, 19, 0, 0,
+  0, 0, 13, 0, 0, 0, 95, 0, 24, 41,
+  20, 0, 0, 104, 16, 18, 0, 0, 0, 0,
+  47, 19, 0, 0, 6, 0, 7, 17, 36, 23,
+  0, 2, 0, 0, 72, 39, 0, 0, 14, 29,
+  0, 0, 0, 0, 40, 0, 36, 14, 0, 1,
+  11, 0, 0, 0, 22, 32, 0, 52, 25, 0,
+  0, 0, 0, 42, 40, 0, 22, 0, 44, 0,
+  3, 0, 0, 33, 0, 0, 52, 0, 0, 0,
+  0, 10, 106, 0, 39, 32, 46, 45, 0, 59,
+  28, 0, 21, 0, 1, 31, 0, 0, 5, 21,
+  26, 0, 31, 0, 0, 0, 5, 0, 0, 0,
+  0, 52, 28, 23, 1, 0, 7, 59, 48, 1,
+  0, 29, 0, 28, 0, 8, 0, 0, 0, 0,
+  0, 12, 0, 0, 0, 0, 49, 26, 5, 0,
+  21, 87, 0, 17, 0, 0, 7, 0, 27, 18,
+  0, 30, 39, 0, 0, 11, 9, 43, 15, 26,
+  0, 36, 93, 68, 12, 0, 68, 46, 209, 0,
+  0, 0, 54, 0, 48, 43, 0, 0, 65, 3,
+  0, 0, 39, 14, 18, 96, 0, 0, 0, 10,
+  0, 107, 61, 0, 69, 0, 19, 0, 17, 0,
+  20, 40, 0, 0, 35, 25, 0, 0, 0, 58,
+  134, 10, 46, 0, 8, 33, 3, 95, 34, 0,
+  24, 0, 8, 20, 0, 5, 21, 22, 59, 0,
+  30, 0, 0, 0, 54, 0, 27, 0, 10, 43,
+  26, 72, 29, 15, 69, 18, 47, 0, 13, 38,
+  8, 8, 0, 1, 0, 0, 3, 0, 8, 49,
+  53, 0, 0, 0, 36, 0, 0, 0, 121, 68,
+  0, 69, 37, 0, 10, 0, 13, 0, 0, 24,
+  109, 0, 0, 19, 14, 0, 23, 0, 0, 116,
+  51, 34, 64, 0, 36, 36, 222, 0, 6, 97,
+  40, 17, 23, 41, 0, 0, 124, 6, 0, 0,
+  30, 56, 59, 90, 15, 0, 0, 12, 0, 135,
+  15, 0, 103, 17, 27, 22, 53, 0, 58, 43,
+  30, 87, 0, 83, 14, 0, 21, 25, 137, 20,
+  29, 0, 0, 0, 51, 86, 41, 0, 7, 0,
+  17, 24, 0, 13, 21, 0, 55, 9, 0, 0,
+  0, 0, 22, 16, 63, 0, 40, 42, 4, 62,
+  32, 21, 74, 29, 0, 42, 54, 0, 12, 14,
+  0, 0, 0, 27, 4, 0, 11, 38, 71, 25,
+  0, 34, 62, 0, 9, 24, 66, 10, 0, 31,
+  29, 110, 12, 0, 20, 0, 0, 9, 85, 0,
+  0, 46, 16, 30, 0, 0, 33, 111, 0, 60,
+  48, 0, 3, 44, 255, 0, 0, 72, 42, 37,
+  17, 24, 0, 22, 96, 20, 32, 0, 17, 61,
+  85, 122, 14, 0, 0, 23, 0, 130, 26, 0,
+  91, 47, 26, 11, 67, 0, 34, 60, 32, 28,
+  0, 46, 0, 4, 12, 28, 143, 0, 41, 3,
+  0, 22, 11, 56, 20, 0, 23, 0, 1, 24,
+  0, 0, 19, 5, 50, 28, 0, 55, 8, 0,
+  61, 18, 20, 0, 39, 55, 9, 30, 21, 7,
+  86, 7, 1, 22, 0, 7, 0, 16, 0, 0,
+  0, 31, 20, 0, 35, 34, 69, 0, 0, 44,
+  59, 0, 6, 4, 0, 115, 36, 17, 6, 0,
+  3, 0, 44, 17, 0, 0, 3, 0, 0, 24,
+  36, 38, 6, 35, 0, 0, 67, 53, 19, 0,
+  40, 54, 0, 0, 0, 0, 68, 0, 53, 8,
+  0, 0, 28, 2, 0, 0, 37, 25, 0, 67,
+  27, 0, 0, 2, 0, 53, 88, 0, 20, 0,
+  26, 0, 0, 0, 0, 27, 0, 0, 0, 0,
+  0, 0, 0, 14, 53, 0, 37, 17, 61, 42,
+  0, 74, 24, 0, 64, 0, 4, 21, 0, 0,
+  6, 36, 25, 20, 74, 0, 0, 0, 24, 0,
+  0, 0, 0, 53, 38, 17, 0, 0, 21, 4,
+  62, 0, 41, 58, 0, 16, 0, 3, 0, 0,
+  0, 0, 0, 6, 0, 0, 35, 0, 53, 1,
+  0, 0, 55, 68, 5, 59, 7, 0, 0, 0,
+  39, 0, 0, 18, 78, 0, 0, 0, 25, 2,
+  0, 0, 0, 34, 65, 19, 34, 0, 18, 36,
+  0, 0, 0, 6, 13, 0, 31, 16, 0, 0,
+  71, 0, 0, 16, 19, 37, 0, 40, 14, 0,
+  0, 0, 0, 107, 29, 0, 61, 0, 36, 0,
+  0, 0, 0, 19, 0, 10, 41, 34, 0, 0,
+  22, 0, 133, 0, 33, 13, 17, 0, 9, 54,
+  28, 7, 16, 0, 14, 15, 15, 0, 15, 0,
+  48, 0, 1, 0, 0, 0, 0, 0, 10, 0,
+  0, 40, 0, 1, 9, 0, 35, 68, 7, 20,
+  38, 3, 0, 13, 0, 0, 0, 0, 0, 0,
+  0, 9, 0, 0, 0, 0, 53, 0, 0, 0,
+  104, 21, 0, 47, 20, 66, 0, 0, 53, 0,
+  0, 0, 116, 0, 0, 40, 62, 0, 2, 0,
+  11, 68, 0, 8, 23, 0, 0, 43, 3, 1,
+  13, 72, 0, 27, 24, 0, 0, 21, 96, 5,
+  13, 87, 14, 47, 59, 16, 0, 0, 0, 0,
+  0, 111, 0, 0, 107, 59, 25, 17, 19, 0,
+  0, 13, 9, 35, 0, 93, 0, 0, 13, 0,
+  155, 30, 22, 32, 0, 0, 34, 19, 0, 47,
+  0, 0, 15, 14, 42, 14, 8, 0, 73, 0,
+  0, 0, 0, 2, 0, 0, 31, 0, 21, 50,
+  0, 0, 5, 0, 30, 31, 0, 67, 22, 0,
+  17, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+  0, 3, 0, 16, 53, 0, 3, 16, 0, 119,
+  31, 10, 0, 0, 55, 0, 33, 18, 0, 0,
+  0, 0, 46, 39, 65, 38, 5, 18, 0, 0,
+  0, 46, 49, 6, 24, 40, 0, 0, 0, 0,
+  84, 26, 0, 0, 0, 16, 0, 3, 0, 0,
+  24, 17, 0, 45, 64, 6, 0, 10, 0, 0,
+  73, 0, 0, 0, 32, 0, 0, 35, 7, 5,
+  0, 0, 0, 0, 63, 0, 26, 11, 0, 0,
+  0, 15, 64, 26, 8, 27, 5, 0, 67, 3,
+  18, 28, 0, 6, 0, 0, 1, 26, 36, 0,
+  0, 22, 0, 0, 0, 0, 0, 60, 6, 0,
+  0, 0, 2, 0, 43, 0, 35, 36, 0, 21,
+  0, 19, 0, 0, 0, 0, 13, 0, 0, 0,
+  95, 0, 24, 41, 20, 0, 0, 104, 16, 18,
+  0, 0, 0, 0, 47, 19, 0, 0, 6, 0,
+  7, 17, 36, 23, 0, 2, 0, 0, 72, 39,
+  0, 0, 14, 29, 0, 0, 0, 0, 40, 0,
+  36, 14, 0, 1, 11, 0, 0, 0, 22, 32,
+  0, 52, 25, 0, 0, 0, 0, 42, 40, 0,
+  22, 0, 44, 0, 3, 0, 0, 33, 0, 0,
+  52, 0, 0, 0, 0, 10, 106, 0, 39, 32,
+  46, 45, 0, 59, 28, 0, 21, 0, 1, 31,
+  0, 0, 5, 21, 26, 0, 31, 0, 0, 0,
+  5, 0, 0, 0, 0, 52, 28, 23, 1, 0,
+  7, 59, 48, 1, 0, 29, 0, 28, 0, 8,
+  0, 0, 0, 0, 0, 12, 0, 0, 0, 0,
+  49, 26, 5, 0, 107, 66, 16, 65, 30, 0,
+  0, 17, 71, 14, 28, 0, 85, 0, 0, 80,
+  60, 0, 13, 0, 0, 32, 32, 6, 0, 0,
+  0, 61, 0, 37, 19, 69, 10, 6, 18, 5,
+  0, 44, 103, 0, 0, 23, 0, 23, 18, 0,
+  0, 0, 0, 0, 0, 86, 0, 0, 83, 13,
+  32, 36, 9, 0, 0, 0, 0, 0, 15, 55,
+  0, 0, 11, 0, 91, 19, 43, 55, 0, 39,
+  28, 49, 0, 26, 0, 0, 19, 64, 28, 26,
+  14, 0, 86, 0, 32, 0, 0, 14, 0, 0,
+  66, 0, 5, 67, 43, 0, 9, 0, 0, 58,
+  0, 60, 9, 0, 6, 0, 0, 0, 0, 0,
+  0, 0, 0, 15, 0, 4, 0, 18, 46, 15,
+  12, 30, 121, 68, 0, 69, 37, 0, 10, 0,
+  13, 0, 0, 24, 109, 0, 0, 19, 14, 0,
+  23, 0, 0, 116, 51, 34, 64, 0, 36, 36,
+  222, 0, 6, 97, 40, 17, 23, 41, 0, 0,
+  124, 6, 0, 0, 30, 56, 59, 90, 15, 0,
+  0, 12, 0, 135, 15, 0, 103, 17, 27, 22,
+  53, 0, 58, 43, 30, 87, 0, 83, 14, 0,
+  21, 25, 137, 20, 29, 0, 0, 0, 51, 86,
+  41, 0, 7, 0, 17, 24, 0, 13, 21, 0,
+  55, 9, 0, 0, 0, 0, 22, 16, 63, 0,
+  40, 42, 4, 62, 32, 21, 74, 29, 0, 42,
+  54, 0, 12, 14, 0, 0, 0, 27, 4, 0,
+  11, 38, 71, 25, 0, 34, 62, 0, 9, 24,
+  66, 10, 0, 31, 29, 110, 12, 0, 20, 0,
+  0, 9, 85, 0, 0, 46, 16, 30, 0, 0,
+  33, 111, 0, 60, 48, 0, 3, 44, 255, 0,
+  0, 72, 42, 37, 17, 24, 0, 22, 96, 20,
+  32, 0, 17, 61, 85, 122, 14, 0, 0, 23,
+  0, 130, 26, 0, 91, 47, 26, 11, 67, 0,
+  34, 60, 32, 28, 0, 46, 0, 4, 12, 28,
+  143, 0, 41, 3, 0, 22, 11, 56, 20, 0,
+  23, 0, 1, 24, 0, 0, 19, 5, 50, 28,
+  0, 55, 8, 0, 61, 18, 20, 0, 39, 55,
+  9, 30, 21, 7, 86, 7, 1, 22, 0, 7,
+  0, 16, 0, 0, 0, 31, 20, 0, 35, 34,
+  69, 0, 0, 44, 59, 0, 6, 4, 0, 38,
+  0, 0, 7, 72, 57, 6, 59, 17, 0, 6,
+  46, 16, 0, 163, 49, 58, 0, 0, 76, 0,
+  0, 90, 29, 28, 5, 40, 214, 33, 0, 0,
+  89, 29, 32, 0, 0, 53, 10, 75, 12, 0,
+  0, 45, 49, 87, 5, 9, 0, 73, 3, 65,
+  107, 1, 7, 49, 22, 23, 0, 54, 0, 5,
+  0, 32, 0, 1, 11, 0, 25, 0, 29, 0,
+  39, 11, 0, 97, 0, 37, 0, 1, 62, 0,
+  14, 26, 0, 4, 35, 12, 60, 53, 62, 78,
+  0, 3, 68, 5, 0, 0, 50, 64, 14, 0,
+  0, 0, 76, 0, 29, 16, 1, 58, 17, 0,
+  0, 22, 0, 0, 0, 12, 39, 12, 66, 4,
+  74, 0, 59, 0, 32, 0, 55, 68, 5, 59,
+  7, 0, 0, 0, 39, 0, 0, 18, 78, 0,
+  0, 0, 25, 2, 0, 0, 0, 34, 65, 19,
+  34, 0, 18, 36, 0, 0, 0, 6, 13, 0,
+  31, 16, 0, 0, 71, 0, 0, 16, 19, 37,
+  0, 40, 14, 0, 0, 0, 0, 107, 29, 0,
+  61, 0, 36, 0, 0, 0, 0, 19, 0, 10,
+  41, 34, 0, 0, 22, 0, 133, 0, 33, 13,
+  17, 0, 9, 54, 28, 7, 16, 0, 14, 15,
+  15, 0, 15, 0, 48, 0, 1, 0, 0, 0,
+  0, 0, 10, 0, 0, 40, 0, 1, 9, 0,
+  35, 68, 7, 20, 38, 3, 0, 13, 0, 0,
+  0, 0, 0, 0, 0, 9, 0, 0, 0, 0,
+  53, 0, 0, 0, 104, 21, 0, 47, 20, 66,
+  0, 0, 53, 0, 0, 0, 116, 0, 0, 40,
+  62, 0, 2, 0, 11, 68, 0, 8, 23, 0,
+  0, 43, 3, 1, 13, 72, 0, 27, 24, 0,
+  0, 21, 96, 5, 13, 87, 14, 47, 59, 16,
+  0, 0, 0, 0, 0, 111, 0, 0, 107, 59,
+  25, 17, 19, 0, 0, 13, 9, 35, 0, 93,
+  0, 0, 13, 0, 155, 30, 22, 32, 0, 0,
+  34, 19, 0, 47, 0, 0, 15, 14, 42, 14,
+  8, 0, 73, 0, 0, 0, 0, 2, 0, 0,
+  31, 0, 21, 50, 0, 0, 5, 0, 30, 31,
+  0, 67, 22, 0, 17, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 3, 0, 16, 53, 0,
+  3, 16, 0, 0, 0, 0, 0, 145, 0, 0,
+  46, 0, 0, 0, 34, 21, 0, 109, 67, 48,
+  0, 0, 39, 1, 0, 58, 0, 0, 0, 56,
+  1, 0, 0, 0, 49, 0, 0, 0, 22, 71,
+  0, 0, 22, 0, 0, 3, 13, 87, 0, 0,
+  0, 14, 12, 53, 23, 0, 62, 19, 29, 0,
+  0, 0, 0, 48, 0, 0, 12, 0, 16, 0,
+  17, 13, 58, 0, 50, 76, 0, 66, 0, 52,
+  0, 0, 8, 0, 17, 64, 0, 25, 19, 0,
+  22, 2, 35, 128, 0, 0, 75, 0, 0, 0,
+  0, 93, 86, 0, 0, 0, 15, 0, 0, 38,
+  0, 19, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 13, 0, 4, 15,
+  0, 104, 16, 18, 0, 0, 0, 0, 47, 19,
+  0, 0, 6, 0, 7, 17, 36, 23, 0, 2,
+  0, 0, 72, 39, 0, 0, 14, 29, 0, 0,
+  0, 0, 40, 0, 36, 14, 0, 1, 11, 0,
+  0, 0, 22, 32, 0, 52, 25, 0, 0, 0,
+  0, 42, 40, 0, 22, 0, 44, 0, 3, 0,
+  0, 33, 0, 0, 52, 0, 0, 0, 0, 10,
+  106, 0, 39, 32, 46, 45, 0, 59, 28, 0,
+  21, 0, 1, 31, 0, 0, 5, 21, 26, 0,
+  31, 0, 0, 0, 5, 0, 0, 0, 0, 52,
+  28, 23, 1, 0, 7, 59, 48, 1, 0, 29,
+  0, 28, 0, 8, 0, 0, 0, 0, 0, 12,
+  0, 0, 0, 0, 49, 26, 5, 0, 107, 66,
+  16, 65, 30, 0, 0, 17, 71, 14, 28, 0,
+  85, 0, 0, 80, 60, 0, 13, 0, 0, 32,
+  32, 6, 0, 0, 0, 61, 0, 37, 19, 69,
+  10, 6, 18, 5, 0, 44, 103, 0, 0, 23,
+  0, 23, 18, 0, 0, 0, 0, 0, 0, 86,
+  0, 0, 83, 13, 32, 36, 9, 0, 0, 0,
+  0, 0, 15, 55, 0, 0, 11, 0, 91, 19,
+  43, 55, 0, 39, 28, 49, 0, 26, 0, 0,
+  19, 64, 28, 26, 14, 0, 86, 0, 32, 0,
+  0, 14, 0, 0, 66, 0, 5, 67, 43, 0,
+  9, 0, 0, 58, 0, 60, 9, 0, 6, 0,
+  0, 0, 0, 0, 0, 0, 0, 15, 0, 4,
+  0, 18, 46, 15, 12, 30, 14, 0, 60, 29,
+  0, 164, 0, 0, 18, 0, 0, 0, 3, 20,
+  0, 48, 30, 38, 0, 0, 13, 76, 24, 1,
+  0, 0, 0, 35, 0, 48, 0, 88, 0, 0,
+  0, 20, 63, 58, 24, 0, 0, 0, 0, 0,
+  0, 11, 0, 0, 13, 0, 0, 83, 0, 0,
+  99, 0, 57, 0, 22, 0, 0, 57, 14, 0,
+  110, 0, 0, 29, 2, 76, 21, 14, 67, 27,
+  0, 44, 44, 26, 0, 0, 0, 0, 32, 108,
+  0, 10, 10, 0, 11, 0, 10, 13, 0, 0,
+  58, 0, 30, 0, 0, 71, 79, 0, 0, 0,
+  0, 18, 0, 26, 0, 0, 0, 0, 0, 0,
+  4, 4, 54, 0, 0, 35, 0, 18, 0, 0,
+  0, 17, 0, 23, 66, 10, 0, 31, 29, 110,
+  12, 0, 20, 0, 0, 9, 85, 0, 0, 46,
+  16, 30, 0, 0, 33, 111, 0, 60, 48, 0,
+  3, 44, 255, 0, 0, 72, 42, 37, 17, 24,
+  0, 22, 96, 20, 32, 0, 17, 61, 85, 122,
+  14, 0, 0, 23, 0, 130, 26, 0, 91, 47,
+  26, 11, 67, 0, 34, 60, 32, 28, 0, 46,
+  0, 4, 12, 28, 143, 0, 41, 3, 0, 22,
+  11, 56, 20, 0, 23, 0, 1, 24, 0, 0,
+  19, 5, 50, 28, 0, 55, 8, 0, 61, 18,
+  20, 0, 39, 55, 9, 30, 21, 7, 86, 7,
+  1, 22, 0, 7, 0, 16, 0, 0, 0, 31,
+  20, 0, 35, 34, 69, 0, 0, 44, 59, 0,
+  6, 4, 0, 38, 0, 0, 7, 72, 57, 6,
+  59, 17, 0, 6, 46, 16, 0, 163, 49, 58,
+  0, 0, 76, 0, 0, 90, 29, 28, 5, 40,
+  214, 33, 0, 0, 89, 29, 32, 0, 0, 53,
+  10, 75, 12, 0, 0, 45, 49, 87, 5, 9,
+  0, 73, 3, 65, 107, 1, 7, 49, 22, 23,
+  0, 54, 0, 5, 0, 32, 0, 1, 11, 0,
+  25, 0, 29, 0, 39, 11, 0, 97, 0, 37,
+  0, 1, 62, 0, 14, 26, 0, 4, 35, 12,
+  60, 53, 62, 78, 0, 3, 68, 5, 0, 0,
+  50, 64, 14, 0, 0, 0, 76, 0, 29, 16,
+  1, 58, 17, 0, 0, 22, 0, 0, 0, 12,
+  39, 12, 66, 4, 74, 0, 59, 0, 32, 0,
+  0, 58, 63, 0, 7, 0, 21, 41, 98, 32,
+  26, 34, 16, 64, 0, 150, 62, 63, 48, 14,
+  52, 0, 0, 72, 12, 0, 54, 79, 175, 35,
+  0, 0, 104, 0, 8, 0, 3, 53, 0, 34,
+  0, 0, 0, 32, 8, 71, 0, 0, 0, 50,
+  34, 80, 101, 18, 30, 0, 24, 14, 0, 49,
+  0, 0, 0, 16, 0, 0, 47, 0, 11, 29,
+  0, 0, 63, 28, 0, 75, 0, 60, 0, 1,
+  62, 4, 40, 45, 0, 23, 18, 40, 92, 24,
+  106, 1, 0, 0, 68, 0, 17, 0, 31, 98,
+  42, 0, 7, 0, 83, 0, 3, 51, 27, 30,
+  31, 0, 16, 5, 20, 0, 0, 18, 0, 32,
+  51, 0, 76, 0, 65, 0, 38, 22, 104, 21,
+  0, 47, 20, 66, 0, 0, 53, 0, 0, 0,
+  116, 0, 0, 40, 62, 0, 2, 0, 11, 68,
+  0, 8, 23, 0, 0, 43, 3, 1, 13, 72,
+  0, 27, 24, 0, 0, 21, 96, 5, 13, 87,
+  14, 47, 59, 16, 0, 0, 0, 0, 0, 111,
+  0, 0, 107, 59, 25, 17, 19, 0, 0, 13,
+  9, 35, 0, 93, 0, 0, 13, 0, 155, 30,
+  22, 32, 0, 0, 34, 19, 0, 47, 0, 0,
+  15, 14, 42, 14, 8, 0, 73, 0, 0, 0,
+  0, 2, 0, 0, 31, 0, 21, 50, 0, 0,
+  5, 0, 30, 31, 0, 67, 22, 0, 17, 0,
+  0, 0, 0, 0, 0, 0, 0, 1, 0, 3,
+  0, 16, 53, 0, 3, 16, 0, 0, 0, 0,
+  0, 145, 0, 0, 46, 0, 0, 0, 34, 21,
+  0, 109, 67, 48, 0, 0, 39, 1, 0, 58,
+  0, 0, 0, 56, 1, 0, 0, 0, 49, 0,
+  0, 0, 22, 71, 0, 0, 22, 0, 0, 3,
+  13, 87, 0, 0, 0, 14, 12, 53, 23, 0,
+  62, 19, 29, 0, 0, 0, 0, 48, 0, 0,
+  12, 0, 16, 0, 17, 13, 58, 0, 50, 76,
+  0, 66, 0, 52, 0, 0, 8, 0, 17, 64,
+  0, 25, 19, 0, 22, 2, 35, 128, 0, 0,
+  75, 0, 0, 0, 0, 93, 86, 0, 0, 0,
+  15, 0, 0, 38, 0, 19, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  13, 0, 4, 15, 0, 0, 92, 0, 0, 76,
+  0, 0, 44, 0, 0, 15, 13, 93, 0, 13,
+  41, 74, 27, 0, 22, 35, 4, 32, 0, 0,
+  0, 34, 0, 0, 18, 4, 5, 0, 0, 0,
+  14, 65, 0, 0, 0, 14, 0, 0, 0, 18,
+  0, 0, 0, 0, 19, 112, 26, 0, 66, 0,
+  49, 0, 1, 0, 0, 12, 0, 0, 37, 7,
+  27, 10, 26, 96, 0, 0, 36, 15, 0, 30,
+  0, 21, 0, 0, 0, 0, 33, 83, 0, 28,
+  14, 34, 42, 0, 16, 32, 0, 0, 39, 0,
+  0, 0, 13, 107, 45, 0, 0, 0, 3, 18,
+  0, 20, 0, 5, 17, 0, 0, 0, 49, 0,
+  46, 44, 22, 4, 0, 0, 0, 0, 20, 0,
+  0, 18, 107, 66, 16, 65, 30, 0, 0, 17,
+  71, 14, 28, 0, 85, 0, 0, 80, 60, 0,
+  13, 0, 0, 32, 32, 6, 0, 0, 0, 61,
+  0, 37, 19, 69, 10, 6, 18, 5, 0, 44,
+  103, 0, 0, 23, 0, 23, 18, 0, 0, 0,
+  0, 0, 0, 86, 0, 0, 83, 13, 32, 36,
+  9, 0, 0, 0, 0, 0, 15, 55, 0, 0,
+  11, 0, 91, 19, 43, 55, 0, 39, 28, 49,
+  0, 26, 0, 0, 19, 64, 28, 26, 14, 0,
+  86, 0, 32, 0, 0, 14, 0, 0, 66, 0,
+  5, 67, 43, 0, 9, 0, 0, 58, 0, 60,
+  9, 0, 6, 0, 0, 0, 0, 0, 0, 0,
+  0, 15, 0, 4, 0, 18, 46, 15, 12, 30,
+  14, 0, 60, 29, 0, 164, 0, 0, 18, 0,
+  0, 0, 3, 20, 0, 48, 30, 38, 0, 0,
+  13, 76, 24, 1, 0, 0, 0, 35, 0, 48,
+  0, 88, 0, 0, 0, 20, 63, 58, 24, 0,
+  0, 0, 0, 0, 0, 11, 0, 0, 13, 0,
+  0, 83, 0, 0, 99, 0, 57, 0, 22, 0,
+  0, 57, 14, 0, 110, 0, 0, 29, 2, 76,
+  21, 14, 67, 27, 0, 44, 44, 26, 0, 0,
+  0, 0, 32, 108, 0, 10, 10, 0, 11, 0,
+  10, 13, 0, 0, 58, 0, 30, 0, 0, 71,
+  79, 0, 0, 0, 0, 18, 0, 26, 0, 0,
+  0, 0, 0, 0, 4, 4, 54, 0, 0, 35,
+  0, 18, 0, 0, 0, 17, 0, 23, 0, 0,
+  70, 0, 4, 150, 0, 0, 0, 0, 0, 1,
+  23, 94, 0, 0, 0, 44, 0, 0, 21, 54,
+  0, 39, 0, 0, 0, 0, 0, 45, 16, 26,
+  0, 7, 0, 0, 0, 50, 0, 0, 0, 11,
+  0, 27, 0, 8, 1, 0, 0, 0, 12, 123,
+  0, 0, 39, 0, 39, 0, 42, 0, 0, 32,
+  0, 0, 97, 0, 0, 31, 0, 64, 0, 26,
+  51, 0, 0, 17, 0, 0, 0, 0, 0, 0,
+  27, 70, 21, 0, 16, 15, 54, 0, 0, 0,
+  24, 0, 2, 0, 0, 0, 0, 60, 12, 0,
+  0, 0, 0, 79, 0, 14, 0, 5, 25, 0,
+  0, 14, 51, 41, 105, 41, 29, 52, 23, 0,
+  0, 0, 17, 23, 0, 13, 0, 38, 0, 0,
+  7, 72, 57, 6, 59, 17, 0, 6, 46, 16,
+  0, 163, 49, 58, 0, 0, 76, 0, 0, 90,
+  29, 28, 5, 40, 214, 33, 0, 0, 89, 29,
+  32, 0, 0, 53, 10, 75, 12, 0, 0, 45,
+  49, 87, 5, 9, 0, 73, 3, 65, 107, 1,
+  7, 49, 22, 23, 0, 54, 0, 5, 0, 32,
+  0, 1, 11, 0, 25, 0, 29, 0, 39, 11,
+  0, 97, 0, 37, 0, 1, 62, 0, 14, 26,
+  0, 4, 35, 12, 60, 53, 62, 78, 0, 3,
+  68, 5, 0, 0, 50, 64, 14, 0, 0, 0,
+  76, 0, 29, 16, 1, 58, 17, 0, 0, 22,
+  0, 0, 0, 12, 39, 12, 66, 4, 74, 0,
+  59, 0, 32, 0, 0, 58, 63, 0, 7, 0,
+  21, 41, 98, 32, 26, 34, 16, 64, 0, 150,
+  62, 63, 48, 14, 52, 0, 0, 72, 12, 0,
+  54, 79, 175, 35, 0, 0, 104, 0, 8, 0,
+  3, 53, 0, 34, 0, 0, 0, 32, 8, 71,
+  0, 0, 0, 50, 34, 80, 101, 18, 30, 0,
+  24, 14, 0, 49, 0, 0, 0, 16, 0, 0,
+  47, 0, 11, 29, 0, 0, 63, 28, 0, 75,
+  0, 60, 0, 1, 62, 4, 40, 45, 0, 23,
+  18, 40, 92, 24, 106, 1, 0, 0, 68, 0,
+  17, 0, 31, 98, 42, 0, 7, 0, 83, 0,
+  3, 51, 27, 30, 31, 0, 16, 5, 20, 0,
+  0, 18, 0, 32, 51, 0, 76, 0, 65, 0,
+  38, 22, 50, 21, 117, 0, 0, 33, 0, 34,
+  48, 0, 0, 21, 0, 97, 0, 11, 24, 76,
+  56, 29, 7, 79, 14, 26, 0, 0, 21, 72,
+  178, 23, 2, 77, 15, 0, 0, 17, 0, 58,
+  0, 0, 0, 0, 23, 6, 0, 52, 0, 0,
+  0, 0, 17, 138, 16, 0, 76, 0, 43, 0,
+  26, 0, 0, 0, 10, 14, 41, 10, 2, 8,
+  11, 125, 0, 0, 81, 0, 0, 29, 11, 26,
+  12, 0, 0, 0, 1, 82, 0, 0, 46, 37,
+  66, 0, 39, 0, 0, 0, 91, 0, 6, 0,
+  15, 66, 24, 0, 23, 6, 85, 90, 0, 23,
+  0, 0, 42, 20, 11, 6, 52, 0, 44, 28,
+  0, 49, 48, 0, 0, 0, 21, 0, 24, 28,
+  0, 0, 0, 0, 0, 145, 0, 0, 46, 0,
+  0, 0, 34, 21, 0, 109, 67, 48, 0, 0,
+  39, 1, 0, 58, 0, 0, 0, 56, 1, 0,
+  0, 0, 49, 0, 0, 0, 22, 71, 0, 0,
+  22, 0, 0, 3, 13, 87, 0, 0, 0, 14,
+  12, 53, 23, 0, 62, 19, 29, 0, 0, 0,
+  0, 48, 0, 0, 12, 0, 16, 0, 17, 13,
+  58, 0, 50, 76, 0, 66, 0, 52, 0, 0,
+  8, 0, 17, 64, 0, 25, 19, 0, 22, 2,
+  35, 128, 0, 0, 75, 0, 0, 0, 0, 93,
+  86, 0, 0, 0, 15, 0, 0, 38, 0, 19,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 13, 0, 4, 15, 0, 0,
+  92, 0, 0, 76, 0, 0, 44, 0, 0, 15,
+  13, 93, 0, 13, 41, 74, 27, 0, 22, 35,
+  4, 32, 0, 0, 0, 34, 0, 0, 18, 4,
+  5, 0, 0, 0, 14, 65, 0, 0, 0, 14,
+  0, 0, 0, 18, 0, 0, 0, 0, 19, 112,
+  26, 0, 66, 0, 49, 0, 1, 0, 0, 12,
+  0, 0, 37, 7, 27, 10, 26, 96, 0, 0,
+  36, 15, 0, 30, 0, 21, 0, 0, 0, 0,
+  33, 83, 0, 28, 14, 34, 42, 0, 16, 32,
+  0, 0, 39, 0, 0, 0, 13, 107, 45, 0,
+  0, 0, 3, 18, 0, 20, 0, 5, 17, 0,
+  0, 0, 49, 0, 46, 44, 22, 4, 0, 0,
+  0, 0, 20, 0, 0, 18, 0, 0, 91, 0,
+  0, 56, 0, 0, 0, 0, 0, 21, 6, 68,
+  0, 0, 3, 66, 22, 26, 0, 44, 1, 12,
+  25, 0, 0, 0, 0, 0, 35, 19, 0, 0,
+  0, 0, 0, 41, 0, 0, 0, 9, 0, 13,
+  0, 4, 17, 0, 0, 0, 11, 90, 12, 0,
+  37, 0, 34, 0, 44, 0, 0, 20, 0, 0,
+  71, 0, 0, 58, 0, 66, 0, 22, 34, 0,
+  4, 12, 0, 0, 14, 0, 0, 0, 11, 67,
+  48, 0, 47, 25, 46, 0, 0, 0, 0, 0,
+  2, 0, 0, 5, 16, 47, 0, 0, 0, 1,
+  0, 93, 0, 9, 0, 23, 27, 12, 0, 4,
+  70, 6, 57, 62, 45, 37, 28, 1, 0, 0,
+  18, 8, 3, 27, 14, 0, 60, 29, 0, 164,
+  0, 0, 18, 0, 0, 0, 3, 20, 0, 48,
+  30, 38, 0, 0, 13, 76, 24, 1, 0, 0,
+  0, 35, 0, 48, 0, 88, 0, 0, 0, 20,
+  63, 58, 24, 0, 0, 0, 0, 0, 0, 11,
+  0, 0, 13, 0, 0, 83, 0, 0, 99, 0,
+  57, 0, 22, 0, 0, 57, 14, 0, 110, 0,
+  0, 29, 2, 76, 21, 14, 67, 27, 0, 44,
+  44, 26, 0, 0, 0, 0, 32, 108, 0, 10,
+  10, 0, 11, 0, 10, 13, 0, 0, 58, 0,
+  30, 0, 0, 71, 79, 0, 0, 0, 0, 18,
+  0, 26, 0, 0, 0, 0, 0, 0, 4, 4,
+  54, 0, 0, 35, 0, 18, 0, 0, 0, 17,
+  0, 23, 0, 0, 70, 0, 4, 150, 0, 0,
+  0, 0, 0, 1, 23, 94, 0, 0, 0, 44,
+  0, 0, 21, 54, 0, 39, 0, 0, 0, 0,
+  0, 45, 16, 26, 0, 7, 0, 0, 0, 50,
+  0, 0, 0, 11, 0, 27, 0, 8, 1, 0,
+  0, 0, 12, 123, 0, 0, 39, 0, 39, 0,
+  42, 0, 0, 32, 0, 0, 97, 0, 0, 31,
+  0, 64, 0, 26, 51, 0, 0, 17, 0, 0,
+  0, 0, 0, 0, 27, 70, 21, 0, 16, 15,
+  54, 0, 0, 0, 24, 0, 2, 0, 0, 0,
+  0, 60, 12, 0, 0, 0, 0, 79, 0, 14,
+  0, 5, 25, 0, 0, 14, 51, 41, 105, 41,
+  29, 52, 23, 0, 0, 0, 17, 23, 0, 13,
+  0, 43, 48, 0, 24, 32, 13, 0, 8, 0,
+  0, 0, 63, 49, 0, 0, 3, 17, 8, 10,
+  0, 0, 0, 37, 41, 35, 6, 0, 0, 48,
+  48, 0, 0, 14, 0, 0, 0, 2, 0, 39,
+  0, 40, 0, 41, 21, 0, 3, 0, 0, 0,
+  0, 40, 61, 0, 0, 0, 14, 6, 2, 35,
+  0, 6, 0, 21, 0, 0, 0, 27, 0, 0,
+  0, 32, 20, 0, 21, 28, 0, 0, 0, 25,
+  16, 25, 21, 40, 63, 0, 39, 18, 50, 13,
+  0, 0, 32, 28, 0, 22, 0, 38, 15, 31,
+  0, 0, 0, 0, 0, 28, 14, 0, 53, 57,
+  40, 0, 0, 20, 46, 0, 33, 38, 62, 29,
+  61, 16, 47, 0, 46, 37, 0, 1, 0, 58,
+  63, 0, 7, 0, 21, 41, 98, 32, 26, 34,
+  16, 64, 0, 150, 62, 63, 48, 14, 52, 0,
+  0, 72, 12, 0, 54, 79, 175, 35, 0, 0,
+  104, 0, 8, 0, 3, 53, 0, 34, 0, 0,
+  0, 32, 8, 71, 0, 0, 0, 50, 34, 80,
+  101, 18, 30, 0, 24, 14, 0, 49, 0, 0,
+  0, 16, 0, 0, 47, 0, 11, 29, 0, 0,
+  63, 28, 0, 75, 0, 60, 0, 1, 62, 4,
+  40, 45, 0, 23, 18, 40, 92, 24, 106, 1,
+  0, 0, 68, 0, 17, 0, 31, 98, 42, 0,
+  7, 0, 83, 0, 3, 51, 27, 30, 31, 0,
+  16, 5, 20, 0, 0, 18, 0, 32, 51, 0,
+  76, 0, 65, 0, 38, 22, 50, 21, 117, 0,
+  0, 33, 0, 34, 48, 0, 0, 21, 0, 97,
+  0, 11, 24, 76, 56, 29, 7, 79, 14, 26,
+  0, 0, 21, 72, 178, 23, 2, 77, 15, 0,
+  0, 17, 0, 58, 0, 0, 0, 0, 23, 6,
+  0, 52, 0, 0, 0, 0, 17, 138, 16, 0,
+  76, 0, 43, 0, 26, 0, 0, 0, 10, 14,
+  41, 10, 2, 8, 11, 125, 0, 0, 81, 0,
+  0, 29, 11, 26, 12, 0, 0, 0, 1, 82,
+  0, 0, 46, 37, 66, 0, 39, 0, 0, 0,
+  91, 0, 6, 0, 15, 66, 24, 0, 23, 6,
+  85, 90, 0, 23, 0, 0, 42, 20, 11, 6,
+  52, 0, 44, 28, 0, 49, 48, 0, 0, 0,
+  21, 0, 24, 28, 37, 2, 61, 0, 0, 73,
+  0, 0, 0, 0, 0, 0, 0, 114, 0, 0,
+  5, 58, 36, 11, 0, 72, 12, 49, 0, 0,
+  26, 41, 217, 0, 0, 48, 0, 41, 0, 0,
+  6, 3, 0, 0, 0, 0, 13, 0, 0, 63,
+  19, 55, 0, 0, 20, 92, 0, 0, 70, 0,
+  42, 0, 39, 0, 25, 1, 0, 0, 74, 12,
+  10, 4, 28, 139, 25, 13, 70, 0, 0, 6,
+  18, 0, 2, 4, 0, 0, 4, 80, 0, 0,
+  46, 48, 69, 0, 0, 0, 12, 0, 60, 0,
+  0, 0, 11, 29, 28, 90, 42, 8, 49, 129,
+  4, 0, 0, 1, 4, 23, 0, 0, 30, 66,
+  51, 23, 16, 39, 2, 0, 0, 0, 0, 0,
+  0, 44, 0, 0, 92, 0, 0, 76, 0, 0,
+  44, 0, 0, 15, 13, 93, 0, 13, 41, 74,
+  27, 0, 22, 35, 4, 32, 0, 0, 0, 34,
+  0, 0, 18, 4, 5, 0, 0, 0, 14, 65,
+  0, 0, 0, 14, 0, 0, 0, 18, 0, 0,
+  0, 0, 19, 112, 26, 0, 66, 0, 49, 0,
+  1, 0, 0, 12, 0, 0, 37, 7, 27, 10,
+  26, 96, 0, 0, 36, 15, 0, 30, 0, 21,
+  0, 0, 0, 0, 33, 83, 0, 28, 14, 34,
+  42, 0, 16, 32, 0, 0, 39, 0, 0, 0,
+  13, 107, 45, 0, 0, 0, 3, 18, 0, 20,
+  0, 5, 17, 0, 0, 0, 49, 0, 46, 44,
+  22, 4, 0, 0, 0, 0, 20, 0, 0, 18,
+  0, 0, 91, 0, 0, 56, 0, 0, 0, 0,
+  0, 21, 6, 68, 0, 0, 3, 66, 22, 26,
+  0, 44, 1, 12, 25, 0, 0, 0, 0, 0,
+  35, 19, 0, 0, 0, 0, 0, 41, 0, 0,
+  0, 9, 0, 13, 0, 4, 17, 0, 0, 0,
+  11, 90, 12, 0, 37, 0, 34, 0, 44, 0,
+  0, 20, 0, 0, 71, 0, 0, 58, 0, 66,
+  0, 22, 34, 0, 4, 12, 0, 0, 14, 0,
+  0, 0, 11, 67, 48, 0, 47, 25, 46, 0,
+  0, 0, 0, 0, 2, 0, 0, 5, 16, 47,
+  0, 0, 0, 1, 0, 93, 0, 9, 0, 23,
+  27, 12, 0, 4, 70, 6, 57, 62, 45, 37,
+  28, 1, 0, 0, 18, 8, 3, 27, 0, 16,
+  49, 0, 0, 5, 31, 0, 1, 0, 0, 6,
+  0, 41, 0, 0, 0, 25, 35, 4, 0, 0,
+  0, 52, 24, 0, 16, 5, 179, 11, 21, 0,
+  23, 0, 0, 0, 0, 11, 0, 43, 0, 24,
+  1, 8, 2, 65, 31, 0, 0, 0, 0, 37,
+  49, 0, 7, 0, 6, 0, 40, 14, 28, 28,
+  0, 0, 0, 18, 44, 18, 0, 7, 0, 39,
+  35, 0, 13, 18, 0, 0, 20, 0, 17, 2,
+  0, 51, 0, 0, 32, 30, 78, 35, 0, 0,
+  40, 0, 0, 22, 0, 0, 33, 23, 14, 18,
+  8, 0, 15, 74, 44, 16, 21, 36, 0, 12,
+  0, 0, 6, 34, 56, 40, 46, 34, 33, 8,
+  0, 0, 18, 0, 14, 30, 0, 0, 70, 0,
+  4, 150, 0, 0, 0, 0, 0, 1, 23, 94,
+  0, 0, 0, 44, 0, 0, 21, 54, 0, 39,
+  0, 0, 0, 0, 0, 45, 16, 26, 0, 7,
+  0, 0, 0, 50, 0, 0, 0, 11, 0, 27,
+  0, 8, 1, 0, 0, 0, 12, 123, 0, 0,
+  39, 0, 39, 0, 42, 0, 0, 32, 0, 0,
+  97, 0, 0, 31, 0, 64, 0, 26, 51, 0,
+  0, 17, 0, 0, 0, 0, 0, 0, 27, 70,
+  21, 0, 16, 15, 54, 0, 0, 0, 24, 0,
+  2, 0, 0, 0, 0, 60, 12, 0, 0, 0,
+  0, 79, 0, 14, 0, 5, 25, 0, 0, 14,
+  51, 41, 105, 41, 29, 52, 23, 0, 0, 0,
+  17, 23, 0, 13, 0, 43, 48, 0, 24, 32,
+  13, 0, 8, 0, 0, 0, 63, 49, 0, 0,
+  3, 17, 8, 10, 0, 0, 0, 37, 41, 35,
+  6, 0, 0, 48, 48, 0, 0, 14, 0, 0,
+  0, 2, 0, 39, 0, 40, 0, 41, 21, 0,
+  3, 0, 0, 0, 0, 40, 61, 0, 0, 0,
+  14, 6, 2, 35, 0, 6, 0, 21, 0, 0,
+  0, 27, 0, 0, 0, 32, 20, 0, 21, 28,
+  0, 0, 0, 25, 16, 25, 21, 40, 63, 0,
+  39, 18, 50, 13, 0, 0, 32, 28, 0, 22,
+  0, 38, 15, 31, 0, 0, 0, 0, 0, 28,
+  14, 0, 53, 57, 40, 0, 0, 20, 46, 0,
+  33, 38, 62, 29, 61, 16, 47, 0, 46, 37,
+  0, 1, 0, 41, 74, 0, 7, 0, 37, 0,
+  26, 0, 0, 0, 8, 45, 0, 15, 14, 0,
+  13, 0, 0, 0, 20, 55, 23, 53, 16, 0,
+  159, 1, 19, 0, 8, 19, 20, 0, 0, 0,
+  0, 81, 7, 52, 28, 35, 49, 21, 9, 3,
+  0, 0, 0, 24, 50, 0, 0, 0, 1, 33,
+  4, 24, 7, 14, 0, 0, 0, 27, 51, 0,
+  10, 0, 0, 31, 38, 26, 32, 14, 0, 0,
+  0, 32, 48, 29, 26, 13, 31, 0, 3, 25,
+  74, 17, 4, 0, 45, 17, 0, 32, 0, 0,
+  21, 15, 0, 0, 0, 0, 6, 22, 50, 8,
+  38, 32, 47, 0, 0, 0, 1, 0, 13, 0,
+  30, 2, 0, 0, 24, 0, 46, 24, 32, 0,
+  50, 21, 117, 0, 0, 33, 0, 34, 48, 0,
+  0, 21, 0, 97, 0, 11, 24, 76, 56, 29,
+  7, 79, 14, 26, 0, 0, 21, 72, 178, 23,
+  2, 77, 15, 0, 0, 17, 0, 58, 0, 0,
+  0, 0, 23, 6, 0, 52, 0, 0, 0, 0,
+  17, 138, 16, 0, 76, 0, 43, 0, 26, 0,
+  0, 0, 10, 14, 41, 10, 2, 8, 11, 125,
+  0, 0, 81, 0, 0, 29, 11, 26, 12, 0,
+  0, 0, 1, 82, 0, 0, 46, 37, 66, 0,
+  39, 0, 0, 0, 91, 0, 6, 0, 15, 66,
+  24, 0, 23, 6, 85, 90, 0, 23, 0, 0,
+  42, 20, 11, 6, 52, 0, 44, 28, 0, 49,
+  48, 0, 0, 0, 21, 0, 24, 28, 37, 2,
+  61, 0, 0, 73, 0, 0, 0, 0, 0, 0,
+  0, 114, 0, 0, 5, 58, 36, 11, 0, 72,
+  12, 49, 0, 0, 26, 41, 217, 0, 0, 48,
+  0, 41, 0, 0, 6, 3, 0, 0, 0, 0,
+  13, 0, 0, 63, 19, 55, 0, 0, 20, 92,
+  0, 0, 70, 0, 42, 0, 39, 0, 25, 1,
+  0, 0, 74, 12, 10, 4, 28, 139, 25, 13,
+  70, 0, 0, 6, 18, 0, 2, 4, 0, 0,
+  4, 80, 0, 0, 46, 48, 69, 0, 0, 0,
+  12, 0, 60, 0, 0, 0, 11, 29, 28, 90,
+  42, 8, 49, 129, 4, 0, 0, 1, 4, 23,
+  0, 0, 30, 66, 51, 23, 16, 39, 2, 0,
+  0, 0, 0, 0, 0, 44, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 91, 0, 0, 56,
+  0, 0, 0, 0, 0, 21, 6, 68, 0, 0,
+  3, 66, 22, 26, 0, 44, 1, 12, 25, 0,
+  0, 0, 0, 0, 35, 19, 0, 0, 0, 0,
+  0, 41, 0, 0, 0, 9, 0, 13, 0, 4,
+  17, 0, 0, 0, 11, 90, 12, 0, 37, 0,
+  34, 0, 44, 0, 0, 20, 0, 0, 71, 0,
+  0, 58, 0, 66, 0, 22, 34, 0, 4, 12,
+  0, 0, 14, 0, 0, 0, 11, 67, 48, 0,
+  47, 25, 46, 0, 0, 0, 0, 0, 2, 0,
+  0, 5, 16, 47, 0, 0, 0, 1, 0, 93,
+  0, 9, 0, 23, 27, 12, 0, 4, 70, 6,
+  57, 62, 45, 37, 28, 1, 0, 0, 18, 8,
+  3, 27, 0, 16, 49, 0, 0, 5, 31, 0,
+  1, 0, 0, 6, 0, 41, 0, 0, 0, 25,
+  35, 4, 0, 0, 0, 52, 24, 0, 16, 5,
+  179, 11, 21, 0, 23, 0, 0, 0, 0, 11,
+  0, 43, 0, 24, 1, 8, 2, 65, 31, 0,
+  0, 0, 0, 37, 49, 0, 7, 0, 6, 0,
+  40, 14, 28, 28, 0, 0, 0, 18, 44, 18,
+  0, 7, 0, 39, 35, 0, 13, 18, 0, 0,
+  20, 0, 17, 2, 0, 51, 0, 0, 32, 30,
+  78, 35, 0, 0, 40, 0, 0, 22, 0, 0,
+  33, 23, 14, 18, 8, 0, 15, 74, 44, 16,
+  21, 36, 0, 12, 0, 0, 6, 34, 56, 40,
+  46, 34, 33, 8, 0, 0, 18, 0, 14, 30,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 43,
+  48, 0, 24, 32, 13, 0, 8, 0, 0, 0,
+  63, 49, 0, 0, 3, 17, 8, 10, 0, 0,
+  0, 37, 41, 35, 6, 0, 0, 48, 48, 0,
+  0, 14, 0, 0, 0, 2, 0, 39, 0, 40,
+  0, 41, 21, 0, 3, 0, 0, 0, 0, 40,
+  61, 0, 0, 0, 14, 6, 2, 35, 0, 6,
+  0, 21, 0, 0, 0, 27, 0, 0, 0, 32,
+  20, 0, 21, 28, 0, 0, 0, 25, 16, 25,
+  21, 40, 63, 0, 39, 18, 50, 13, 0, 0,
+  32, 28, 0, 22, 0, 38, 15, 31, 0, 0,
+  0, 0, 0, 28, 14, 0, 53, 57, 40, 0,
+  0, 20, 46, 0, 33, 38, 62, 29, 61, 16,
+  47, 0, 46, 37, 0, 1, 0, 41, 74, 0,
+  7, 0, 37, 0, 26, 0, 0, 0, 8, 45,
+  0, 15, 14, 0, 13, 0, 0, 0, 20, 55,
+  23, 53, 16, 0, 159, 1, 19, 0, 8, 19,
+  20, 0, 0, 0, 0, 81, 7, 52, 28, 35,
+  49, 21, 9, 3, 0, 0, 0, 24, 50, 0,
+  0, 0, 1, 33, 4, 24, 7, 14, 0, 0,
+  0, 27, 51, 0, 10, 0, 0, 31, 38, 26,
+  32, 14, 0, 0, 0, 32, 48, 29, 26, 13,
+  31, 0, 3, 25, 74, 17, 4, 0, 45, 17,
+  0, 32, 0, 0, 21, 15, 0, 0, 0, 0,
+  6, 22, 50, 8, 38, 32, 47, 0, 0, 0,
+  1, 0, 13, 0, 30, 2, 0, 0, 24, 0,
+  46, 24, 32, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  12, 21, 64, 6, 0, 0, 17, 8, 0, 10,
+  24, 0, 0, 65, 0, 74, 92, 76, 35, 40,
+  22, 3, 39, 33, 0, 0, 31, 58, 156, 6,
+  15, 0, 58, 0, 0, 0, 0, 18, 0, 18,
+  5, 27, 0, 0, 53, 31, 0, 18, 0, 0,
+  0, 47, 40, 0, 10, 0, 0, 9, 0, 6,
+  28, 0, 0, 0, 0, 7, 44, 0, 48, 45,
+  0, 16, 17, 16, 28, 6, 22, 3, 0, 16,
+  38, 0, 14, 0, 0, 13, 0, 23, 45, 25,
+  8, 25, 0, 0, 67, 0, 51, 0, 0, 39,
+  3, 0, 27, 11, 67, 0, 18, 0, 0, 0,
+  20, 21, 9, 43, 3, 0, 12, 0, 0, 0,
+  64, 0, 5, 0, 0, 0, 55, 0, 56, 59,
+  50, 27, 4, 0, 2, 0, 0, 0, 8, 0,
+  48, 60, 4, 28, 76, 49, 0, 0, 0, 6,
+  1, 61, 24, 0, 35, 40, 0, 0, 13, 0,
+  67, 0, 0, 0, 0, 0, 0, 1, 0, 66,
+  2, 0, 30, 28, 26, 42, 0, 12, 0, 69,
+  96, 0, 23, 0, 0, 0, 0, 0, 51, 0,
+  0, 65, 0, 8, 82, 0, 40, 45, 0, 20,
+  0, 33, 32, 0, 14, 3, 0, 16, 42, 0,
+  37, 0, 0, 30, 0, 27, 36, 9, 13, 0,
+  0, 22, 2, 0, 70, 5, 0, 64, 0, 23,
+  40, 0, 76, 0, 6, 0, 58, 8, 17, 40,
+  5, 0, 26, 0, 1, 0, 0, 0, 39, 0,
+  71, 0, 10, 9, 14, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 47, 23, 86, 28, 0, 0,
+  29, 6, 18, 0, 12, 0, 0, 94, 0, 55,
+  94, 25, 14, 29, 7, 39, 13, 18, 25, 0,
+  29, 32, 164, 9, 5, 45, 79, 0, 0, 0,
+  0, 37, 0, 0, 0, 4, 0, 10, 7, 71,
+  53, 0, 0, 0, 0, 40, 22, 15, 17, 0,
+  13, 0, 0, 3, 39, 29, 0, 0, 0, 0,
+  72, 0, 119, 51, 0, 0, 21, 0, 24, 0,
+  65, 11, 0, 23, 14, 0, 42, 0, 0, 26,
+  0, 0, 59, 5, 0, 16, 0, 5, 15, 0,
+  38, 1, 14, 93, 25, 0, 14, 51, 54, 47,
+  12, 0, 25, 0, 4, 10, 0, 41, 10, 0,
+  18, 0, 17, 0, 59, 0, 0, 0, 0, 24,
+  48, 21, 43, 69, 0, 8, 5, 11, 0, 0,
+  0, 0, 0, 0, 16, 73, 0, 0, 82, 18,
+  0, 0, 0, 41, 0, 50, 15, 0, 5, 16,
+  0, 0, 0, 19, 83, 23, 0, 0, 0, 9,
+  0, 0, 0, 6, 0, 0, 9, 74, 35, 102,
+  0, 0, 0, 29, 56, 0, 22, 0, 18, 0,
+  0, 0, 78, 24, 0, 51, 0, 0, 97, 0,
+  107, 49, 0, 0, 4, 13, 45, 0, 27, 0,
+  0, 5, 25, 0, 35, 12, 0, 12, 0, 6,
+  0, 6, 0, 26, 0, 19, 1, 0, 34, 0,
+  12, 95, 20, 81, 35, 21, 44, 44, 10, 0,
+  51, 0, 0, 63, 0, 7, 0, 0, 0, 0,
+  11, 0, 22, 0, 33, 0, 0, 27, 27, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 23, 32,
+  93, 27, 1, 9, 26, 5, 18, 0, 0, 0,
+  0, 103, 0, 30, 67, 4, 0, 16, 13, 75,
+  10, 41, 20, 0, 6, 20, 201, 42, 3, 62,
+  71, 0, 24, 0, 0, 56, 0, 4, 5, 32,
+  0, 22, 9, 88, 48, 0, 0, 0, 0, 51,
+  21, 3, 55, 0, 44, 0, 32, 0, 31, 72,
+  0, 0, 0, 0, 48, 9, 120, 30, 0, 10,
+  58, 0, 32, 0, 53, 0, 0, 37, 0, 0,
+  36, 11, 0, 15, 0, 0, 58, 5, 0, 0,
+  0, 3, 0, 36, 0, 0, 40, 101, 17, 0,
+  0, 52, 55, 89, 20, 0, 9, 0, 2, 9,
+  0, 33, 6, 2, 40, 0, 19, 12, 51, 0,
+  0, 0, 3, 0, 39, 30, 0, 67, 0, 11,
+  0, 33, 2, 0, 0, 0, 0, 17, 28, 49,
+  0, 0, 52, 3, 0, 0, 28, 58, 0, 42,
+  19, 0, 0, 8, 0, 9, 0, 26, 82, 21,
+  0, 0, 0, 27, 0, 8, 0, 40, 0, 22,
+  24, 91, 9, 110, 0, 0, 0, 27, 50, 0,
+  37, 0, 28, 0, 14, 0, 55, 50, 0, 43,
+  0, 0, 49, 11, 81, 0, 4, 0, 22, 7,
+  42, 0, 12, 0, 0, 26, 21, 0, 21, 24,
+  0, 0, 0, 0, 0, 9, 0, 0, 0, 9,
+  0, 20, 0, 0, 47, 83, 0, 52, 17, 21,
+  41, 51, 25, 0, 40, 5, 0, 40, 0, 11,
+  0, 0, 21, 0, 13, 13, 31, 0, 15, 0,
+  35, 1, 15, 0, 12, 21, 64, 6, 0, 0,
+  17, 8, 0, 10, 24, 0, 0, 65, 0, 74,
+  92, 76, 35, 40, 22, 3, 39, 33, 0, 0,
+  31, 58, 156, 6, 15, 0, 58, 0, 0, 0,
+  0, 18, 0, 18, 5, 27, 0, 0, 53, 31,
+  0, 18, 0, 0, 0, 47, 40, 0, 10, 0,
+  0, 9, 0, 6, 28, 0, 0, 0, 0, 7,
+  44, 0, 48, 45, 0, 16, 17, 16, 28, 6,
+  22, 3, 0, 16, 38, 0, 14, 0, 0, 13,
+  0, 23, 45, 25, 8, 25, 0, 0, 67, 0,
+  51, 0, 0, 39, 3, 0, 27, 11, 67, 0,
+  18, 0, 0, 0, 20, 21, 9, 43, 3, 0,
+  12, 0, 0, 0, 64, 0, 5, 0, 0, 0,
+  55, 0, 56, 59, 50, 27, 4, 0, 2, 0,
+  0, 0, 8, 0, 48, 60, 4, 28, 76, 49,
+  0, 0, 0, 6, 1, 61, 24, 0, 35, 40,
+  0, 0, 13, 0, 67, 0, 0, 0, 0, 0,
+  0, 1, 0, 66, 2, 0, 30, 28, 26, 42,
+  0, 12, 0, 69, 96, 0, 23, 0, 0, 0,
+  0, 0, 51, 0, 0, 65, 0, 8, 82, 0,
+  40, 45, 0, 20, 0, 33, 32, 0, 14, 3,
+  0, 16, 42, 0, 37, 0, 0, 30, 0, 27,
+  36, 9, 13, 0, 0, 22, 2, 0, 70, 5,
+  0, 64, 0, 23, 40, 0, 76, 0, 6, 0,
+  58, 8, 17, 40, 5, 0, 26, 0, 1, 0,
+  0, 0, 39, 0, 71, 0, 10, 9, 14, 0,
+  2, 55, 59, 38, 4, 35, 16, 13, 17, 0,
+  0, 16, 84, 0, 0, 22, 51, 18, 0, 0,
+  0, 56, 0, 33, 67, 0, 5, 30, 0, 0,
+  0, 43, 70, 0, 18, 0, 0, 0, 0, 41,
+  0, 35, 57, 2, 29, 80, 44, 19, 0, 21,
+  0, 34, 36, 10, 35, 0, 10, 0, 0, 0,
+  30, 26, 0, 32, 0, 0, 35, 1, 27, 0,
+  0, 17, 9, 19, 26, 0, 10, 16, 0, 22,
+  23, 0, 61, 69, 0, 5, 0, 0, 0, 42,
+  5, 0, 0, 31, 0, 24, 35, 0, 0, 65,
+  2, 0, 10, 12, 63, 0, 37, 0, 27, 0,
+  0, 14, 0, 0, 0, 0, 0, 0, 0, 0,
+  4, 0, 41, 0, 35, 0, 8, 0, 47, 23,
+  86, 28, 0, 0, 29, 6, 18, 0, 12, 0,
+  0, 94, 0, 55, 94, 25, 14, 29, 7, 39,
+  13, 18, 25, 0, 29, 32, 164, 9, 5, 45,
+  79, 0, 0, 0, 0, 37, 0, 0, 0, 4,
+  0, 10, 7, 71, 53, 0, 0, 0, 0, 40,
+  22, 15, 17, 0, 13, 0, 0, 3, 39, 29,
+  0, 0, 0, 0, 72, 0, 119, 51, 0, 0,
+  21, 0, 24, 0, 65, 11, 0, 23, 14, 0,
+  42, 0, 0, 26, 0, 0, 59, 5, 0, 16,
+  0, 5, 15, 0, 38, 1, 14, 93, 25, 0,
+  14, 51, 54, 47, 12, 0, 25, 0, 4, 10,
+  0, 41, 10, 0, 18, 0, 17, 0, 59, 0,
+  0, 0, 0, 24, 48, 21, 43, 69, 0, 8,
+  5, 11, 0, 0, 0, 0, 0, 0, 16, 73,
+  0, 0, 82, 18, 0, 0, 0, 41, 0, 50,
+  15, 0, 5, 16, 0, 0, 0, 19, 83, 23,
+  0, 0, 0, 9, 0, 0, 0, 6, 0, 0,
+  9, 74, 35, 102, 0, 0, 0, 29, 56, 0,
+  22, 0, 18, 0, 0, 0, 78, 24, 0, 51,
+  0, 0, 97, 0, 107, 49, 0, 0, 4, 13,
+  45, 0, 27, 0, 0, 5, 25, 0, 35, 12,
+  0, 12, 0, 6, 0, 6, 0, 26, 0, 19,
+  1, 0, 34, 0, 12, 95, 20, 81, 35, 21,
+  44, 44, 10, 0, 51, 0, 0, 63, 0, 7,
+  0, 0, 0, 0, 11, 0, 22, 0, 33, 0,
+  0, 27, 27, 0, 0, 39, 39, 29, 0, 48,
+  7, 15, 23, 0, 0, 11, 81, 0, 0, 23,
+  58, 7, 0, 0, 0, 63, 0, 21, 41, 0,
+  0, 12, 0, 0, 0, 32, 67, 3, 1, 0,
+  0, 13, 0, 47, 0, 18, 41, 13, 22, 69,
+  25, 53, 0, 12, 0, 37, 21, 7, 22, 0,
+  22, 0, 0, 0, 16, 31, 0, 29, 0, 0,
+  7, 0, 37, 0, 18, 0, 9, 21, 4, 0,
+  5, 11, 0, 39, 27, 0, 62, 62, 0, 0,
+  0, 0, 0, 18, 1, 0, 0, 19, 0, 19,
+  32, 0, 0, 78, 11, 0, 0, 10, 15, 0,
+  33, 0, 0, 0, 0, 8, 0, 0, 0, 0,
+  7, 0, 0, 0, 0, 0, 38, 0, 39, 0,
+  9, 0, 23, 32, 93, 27, 1, 9, 26, 5,
+  18, 0, 0, 0, 0, 103, 0, 30, 67, 4,
+  0, 16, 13, 75, 10, 41, 20, 0, 6, 20,
+  201, 42, 3, 62, 71, 0, 24, 0, 0, 56,
+  0, 4, 5, 32, 0, 22, 9, 88, 48, 0,
+  0, 0, 0, 51, 21, 3, 55, 0, 44, 0,
+  32, 0, 31, 72, 0, 0, 0, 0, 48, 9,
+  120, 30, 0, 10, 58, 0, 32, 0, 53, 0,
+  0, 37, 0, 0, 36, 11, 0, 15, 0, 0,
+  58, 5, 0, 0, 0, 3, 0, 36, 0, 0,
+  40, 101, 17, 0, 0, 52, 55, 89, 20, 0,
+  9, 0, 2, 9, 0, 33, 6, 2, 40, 0,
+  19, 12, 51, 0, 0, 0, 3, 0, 39, 30,
+  0, 67, 0, 11, 0, 33, 2, 0, 0, 0,
+  0, 17, 28, 49, 0, 0, 52, 3, 0, 0,
+  28, 58, 0, 42, 19, 0, 0, 8, 0, 9,
+  0, 26, 82, 21, 0, 0, 0, 27, 0, 8,
+  0, 40, 0, 22, 24, 91, 9, 110, 0, 0,
+  0, 27, 50, 0, 37, 0, 28, 0, 14, 0,
+  55, 50, 0, 43, 0, 0, 49, 11, 81, 0,
+  4, 0, 22, 7, 42, 0, 12, 0, 0, 26,
+  21, 0, 21, 24, 0, 0, 0, 0, 0, 9,
+  0, 0, 0, 9, 0, 20, 0, 0, 47, 83,
+  0, 52, 17, 21, 41, 51, 25, 0, 40, 5,
+  0, 40, 0, 11, 0, 0, 21, 0, 13, 13,
+  31, 0, 15, 0, 35, 1, 15, 0, 0, 27,
+  36, 37, 0, 42, 17, 9, 15, 0, 0, 22,
+  97, 0, 7, 27, 55, 8, 0, 0, 0, 69,
+  0, 8, 46, 0, 0, 20, 0, 2, 0, 37,
+  78, 0, 3, 0, 0, 24, 0, 73, 0, 34,
+  30, 29, 29, 57, 25, 42, 0, 28, 0, 43,
+  34, 9, 17, 0, 10, 0, 0, 0, 6, 14,
+  0, 16, 0, 0, 0, 0, 28, 0, 23, 6,
+  0, 10, 7, 0, 0, 23, 0, 35, 38, 0,
+  52, 56, 0, 0, 11, 0, 0, 18, 0, 0,
+  0, 4, 0, 16, 29, 0, 0, 66, 6, 0,
+  0, 10, 18, 0, 38, 0, 0, 6, 0, 7,
+  0, 1, 0, 0, 17, 0, 0, 0, 5, 0,
+  43, 0, 63, 0, 11, 0, 56, 59, 50, 27,
+  4, 0, 2, 0, 0, 0, 8, 0, 48, 60,
+  4, 28, 76, 49, 0, 0, 0, 6, 1, 61,
+  24, 0, 35, 40, 0, 0, 13, 0, 67, 0,
+  0, 0, 0, 0, 0, 1, 0, 66, 2, 0,
+  30, 28, 26, 42, 0, 12, 0, 69, 96, 0,
+  23, 0, 0, 0, 0, 0, 51, 0, 0, 65,
+  0, 8, 82, 0, 40, 45, 0, 20, 0, 33,
+  32, 0, 14, 3, 0, 16, 42, 0, 37, 0,
+  0, 30, 0, 27, 36, 9, 13, 0, 0, 22,
+  2, 0, 70, 5, 0, 64, 0, 23, 40, 0,
+  76, 0, 6, 0, 58, 8, 17, 40, 5, 0,
+  26, 0, 1, 0, 0, 0, 39, 0, 71, 0,
+  10, 9, 14, 0, 2, 55, 59, 38, 4, 35,
+  16, 13, 17, 0, 0, 16, 84, 0, 0, 22,
+  51, 18, 0, 0, 0, 56, 0, 33, 67, 0,
+  5, 30, 0, 0, 0, 43, 70, 0, 18, 0,
+  0, 0, 0, 41, 0, 35, 57, 2, 29, 80,
+  44, 19, 0, 21, 0, 34, 36, 10, 35, 0,
+  10, 0, 0, 0, 30, 26, 0, 32, 0, 0,
+  35, 1, 27, 0, 0, 17, 9, 19, 26, 0,
+  10, 16, 0, 22, 23, 0, 61, 69, 0, 5,
+  0, 0, 0, 42, 5, 0, 0, 31, 0, 24,
+  35, 0, 0, 65, 2, 0, 10, 12, 63, 0,
+  37, 0, 27, 0, 0, 14, 0, 0, 0, 0,
+  0, 0, 0, 0, 4, 0, 41, 0, 35, 0,
+  8, 0, 0, 0, 0, 18, 14, 124, 8, 0,
+  7, 0, 0, 29, 52, 11, 0, 6, 15, 0,
+  0, 0, 0, 77, 2, 24, 40, 0, 0, 9,
+  0, 14, 0, 31, 15, 32, 0, 0, 0, 21,
+  0, 76, 0, 37, 0, 65, 12, 85, 61, 31,
+  0, 0, 0, 31, 31, 4, 2, 0, 40, 0,
+  18, 0, 23, 69, 0, 16, 12, 9, 0, 29,
+  58, 0, 39, 20, 11, 0, 25, 21, 19, 0,
+  0, 29, 42, 0, 16, 44, 15, 0, 11, 0,
+  0, 8, 0, 6, 0, 0, 4, 72, 0, 0,
+  0, 72, 0, 0, 4, 12, 57, 0, 27, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 77, 0,
+  47, 0, 6, 3, 0, 0, 55, 0, 22, 0,
+  43, 69, 0, 8, 5, 11, 0, 0, 0, 0,
+  0, 0, 16, 73, 0, 0, 82, 18, 0, 0,
+  0, 41, 0, 50, 15, 0, 5, 16, 0, 0,
+  0, 19, 83, 23, 0, 0, 0, 9, 0, 0,
+  0, 6, 0, 0, 9, 74, 35, 102, 0, 0,
+  0, 29, 56, 0, 22, 0, 18, 0, 0, 0,
+  78, 24, 0, 51, 0, 0, 97, 0, 107, 49,
+  0, 0, 4, 13, 45, 0, 27, 0, 0, 5,
+  25, 0, 35, 12, 0, 12, 0, 6, 0, 6,
+  0, 26, 0, 19, 1, 0, 34, 0, 12, 95,
+  20, 81, 35, 21, 44, 44, 10, 0, 51, 0,
+  0, 63, 0, 7, 0, 0, 0, 0, 11, 0,
+  22, 0, 33, 0, 0, 27, 27, 0, 0, 39,
+  39, 29, 0, 48, 7, 15, 23, 0, 0, 11,
+  81, 0, 0, 23, 58, 7, 0, 0, 0, 63,
+  0, 21, 41, 0, 0, 12, 0, 0, 0, 32,
+  67, 3, 1, 0, 0, 13, 0, 47, 0, 18,
+  41, 13, 22, 69, 25, 53, 0, 12, 0, 37,
+  21, 7, 22, 0, 22, 0, 0, 0, 16, 31,
+  0, 29, 0, 0, 7, 0, 37, 0, 18, 0,
+  9, 21, 4, 0, 5, 11, 0, 39, 27, 0,
+  62, 62, 0, 0, 0, 0, 0, 18, 1, 0,
+  0, 19, 0, 19, 32, 0, 0, 78, 11, 0,
+  0, 10, 15, 0, 33, 0, 0, 0, 0, 8,
+  0, 0, 0, 0, 7, 0, 0, 0, 0, 0,
+  38, 0, 39, 0, 9, 0, 0, 0, 0, 12,
+  0, 128, 4, 0, 24, 0, 0, 24, 44, 0,
+  0, 3, 15, 0, 0, 0, 17, 87, 14, 19,
+  11, 0, 0, 0, 0, 0, 0, 22, 19, 26,
+  0, 6, 0, 37, 0, 56, 0, 21, 0, 56,
+  0, 77, 54, 47, 0, 0, 0, 41, 15, 0,
+  2, 0, 67, 0, 29, 0, 3, 66, 0, 12,
+  54, 5, 0, 16, 73, 0, 77, 17, 14, 1,
+  0, 19, 20, 20, 0, 39, 27, 0, 45, 41,
+  10, 0, 5, 0, 0, 0, 0, 17, 0, 0,
+  0, 33, 0, 0, 7, 75, 14, 0, 0, 3,
+  5, 0, 19, 0, 0, 0, 0, 0, 0, 14,
+  0, 0, 93, 0, 37, 0, 0, 0, 0, 0,
+  36, 0, 0, 0, 0, 67, 0, 11, 0, 33,
+  2, 0, 0, 0, 0, 17, 28, 49, 0, 0,
+  52, 3, 0, 0, 28, 58, 0, 42, 19, 0,
+  0, 8, 0, 9, 0, 26, 82, 21, 0, 0,
+  0, 27, 0, 8, 0, 40, 0, 22, 24, 91,
+  9, 110, 0, 0, 0, 27, 50, 0, 37, 0,
+  28, 0, 14, 0, 55, 50, 0, 43, 0, 0,
+  49, 11, 81, 0, 4, 0, 22, 7, 42, 0,
+  12, 0, 0, 26, 21, 0, 21, 24, 0, 0,
+  0, 0, 0, 9, 0, 0, 0, 9, 0, 20,
+  0, 0, 47, 83, 0, 52, 17, 21, 41, 51,
+  25, 0, 40, 5, 0, 40, 0, 11, 0, 0,
+  21, 0, 13, 13, 31, 0, 15, 0, 35, 1,
+  15, 0, 0, 27, 36, 37, 0, 42, 17, 9,
+  15, 0, 0, 22, 97, 0, 7, 27, 55, 8,
+  0, 0, 0, 69, 0, 8, 46, 0, 0, 20,
+  0, 2, 0, 37, 78, 0, 3, 0, 0, 24,
+  0, 73, 0, 34, 30, 29, 29, 57, 25, 42,
+  0, 28, 0, 43, 34, 9, 17, 0, 10, 0,
+  0, 0, 6, 14, 0, 16, 0, 0, 0, 0,
+  28, 0, 23, 6, 0, 10, 7, 0, 0, 23,
+  0, 35, 38, 0, 52, 56, 0, 0, 11, 0,
+  0, 18, 0, 0, 0, 4, 0, 16, 29, 0,
+  0, 66, 6, 0, 0, 10, 18, 0, 38, 0,
+  0, 6, 0, 7, 0, 1, 0, 0, 17, 0,
+  0, 0, 5, 0, 43, 0, 63, 0, 11, 0,
+  0, 0, 0, 15, 0, 142, 5, 0, 3, 0,
+  0, 27, 43, 0, 0, 0, 6, 0, 0, 0,
+  37, 88, 23, 15, 8, 0, 0, 0, 0, 13,
+  0, 22, 26, 24, 0, 2, 0, 36, 0, 50,
+  0, 35, 0, 56, 1, 71, 43, 43, 0, 0,
+  0, 38, 8, 0, 4, 0, 67, 0, 33, 0,
+  0, 57, 0, 0, 64, 0, 0, 26, 62, 0,
+  74, 26, 27, 3, 4, 32, 9, 25, 0, 31,
+  35, 0, 37, 52, 8, 0, 19, 0, 0, 0,
+  0, 11, 7, 0, 1, 26, 0, 0, 10, 66,
+  18, 0, 0, 7, 8, 0, 31, 0, 0, 0,
+  0, 0, 0, 15, 0, 0, 111, 2, 35, 3,
+  0, 0, 0, 0, 41, 0, 0, 0, 2, 55,
+  59, 38, 4, 35, 16, 13, 17, 0, 0, 16,
+  84, 0, 0, 22, 51, 18, 0, 0, 0, 56,
+  0, 33, 67, 0, 5, 30, 0, 0, 0, 43,
+  70, 0, 18, 0, 0, 0, 0, 41, 0, 35,
+  57, 2, 29, 80, 44, 19, 0, 21, 0, 34,
+  36, 10, 35, 0, 10, 0, 0, 0, 30, 26,
+  0, 32, 0, 0, 35, 1, 27, 0, 0, 17,
+  9, 19, 26, 0, 10, 16, 0, 22, 23, 0,
+  61, 69, 0, 5, 0, 0, 0, 42, 5, 0,
+  0, 31, 0, 24, 35, 0, 0, 65, 2, 0,
+  10, 12, 63, 0, 37, 0, 27, 0, 0, 14,
+  0, 0, 0, 0, 0, 0, 0, 0, 4, 0,
+  41, 0, 35, 0, 8, 0, 0, 0, 0, 18,
+  14, 124, 8, 0, 7, 0, 0, 29, 52, 11,
+  0, 6, 15, 0, 0, 0, 0, 77, 2, 24,
+  40, 0, 0, 9, 0, 14, 0, 31, 15, 32,
+  0, 0, 0, 21, 0, 76, 0, 37, 0, 65,
+  12, 85, 61, 31, 0, 0, 0, 31, 31, 4,
+  2, 0, 40, 0, 18, 0, 23, 69, 0, 16,
+  12, 9, 0, 29, 58, 0, 39, 20, 11, 0,
+  25, 21, 19, 0, 0, 29, 42, 0, 16, 44,
+  15, 0, 11, 0, 0, 8, 0, 6, 0, 0,
+  4, 72, 0, 0, 0, 72, 0, 0, 4, 12,
+  57, 0, 27, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 77, 0, 47, 0, 6, 3, 0, 0,
+  55, 0, 22, 0, 0, 12, 0, 0, 34, 31,
+  37, 0, 16, 0, 1, 11, 52, 11, 10, 28,
+  23, 12, 0, 12, 51, 0, 0, 50, 24, 48,
+  0, 15, 0, 35, 0, 0, 38, 48, 0, 0,
+  0, 6, 0, 75, 0, 43, 0, 59, 29, 41,
+  15, 15, 0, 19, 0, 15, 107, 18, 0, 0,
+  17, 0, 0, 28, 25, 21, 0, 41, 0, 0,
+  45, 6, 26, 0, 0, 8, 0, 14, 33, 51,
+  4, 0, 0, 28, 84, 14, 0, 6, 19, 0,
+  12, 21, 18, 26, 0, 9, 9, 21, 0, 72,
+  0, 4, 31, 72, 0, 0, 2, 0, 39, 0,
+  26, 7, 9, 48, 0, 0, 0, 3, 0, 0,
+  39, 24, 41, 0, 37, 0, 84, 0, 64, 0,
+  13, 0, 0, 39, 39, 29, 0, 48, 7, 15,
+  23, 0, 0, 11, 81, 0, 0, 23, 58, 7,
+  0, 0, 0, 63, 0, 21, 41, 0, 0, 12,
+  0, 0, 0, 32, 67, 3, 1, 0, 0, 13,
+  0, 47, 0, 18, 41, 13, 22, 69, 25, 53,
+  0, 12, 0, 37, 21, 7, 22, 0, 22, 0,
+  0, 0, 16, 31, 0, 29, 0, 0, 7, 0,
+  37, 0, 18, 0, 9, 21, 4, 0, 5, 11,
+  0, 39, 27, 0, 62, 62, 0, 0, 0, 0,
+  0, 18, 1, 0, 0, 19, 0, 19, 32, 0,
+  0, 78, 11, 0, 0, 10, 15, 0, 33, 0,
+  0, 0, 0, 8, 0, 0, 0, 0, 7, 0,
+  0, 0, 0, 0, 38, 0, 39, 0, 9, 0,
+  0, 0, 0, 12, 0, 128, 4, 0, 24, 0,
+  0, 24, 44, 0, 0, 3, 15, 0, 0, 0,
+  17, 87, 14, 19, 11, 0, 0, 0, 0, 0,
+  0, 22, 19, 26, 0, 6, 0, 37, 0, 56,
+  0, 21, 0, 56, 0, 77, 54, 47, 0, 0,
+  0, 41, 15, 0, 2, 0, 67, 0, 29, 0,
+  3, 66, 0, 12, 54, 5, 0, 16, 73, 0,
+  77, 17, 14, 1, 0, 19, 20, 20, 0, 39,
+  27, 0, 45, 41, 10, 0, 5, 0, 0, 0,
+  0, 17, 0, 0, 0, 33, 0, 0, 7, 75,
+  14, 0, 0, 3, 5, 0, 19, 0, 0, 0,
+  0, 0, 0, 14, 0, 0, 93, 0, 37, 0,
+  0, 0, 0, 0, 36, 0, 0, 0, 0, 0,
+  0, 0, 0, 48, 47, 0, 22, 0, 0, 0,
+  38, 0, 10, 49, 31, 17, 0, 15, 62, 0,
+  0, 40, 0, 20, 12, 0, 0, 26, 0, 0,
+  64, 55, 8, 0, 0, 16, 0, 41, 0, 28,
+  0, 56, 0, 45, 21, 45, 0, 12, 2, 10,
+  93, 9, 0, 9, 48, 0, 0, 35, 16, 4,
+  0, 1, 0, 0, 17, 7, 42, 0, 2, 3,
+  0, 21, 13, 42, 3, 0, 0, 26, 69, 0,
+  18, 2, 18, 0, 12, 0, 9, 8, 0, 31,
+  0, 8, 5, 29, 0, 0, 36, 54, 18, 0,
+  0, 0, 1, 0, 24, 4, 0, 31, 0, 1,
+  0, 19, 0, 0, 51, 3, 32, 0, 21, 0,
+  83, 0, 35, 0, 4, 0, 0, 27, 36, 37,
+  0, 42, 17, 9, 15, 0, 0, 22, 97, 0,
+  7, 27, 55, 8, 0, 0, 0, 69, 0, 8,
+  46, 0, 0, 20, 0, 2, 0, 37, 78, 0,
+  3, 0, 0, 24, 0, 73, 0, 34, 30, 29,
+  29, 57, 25, 42, 0, 28, 0, 43, 34, 9,
+  17, 0, 10, 0, 0, 0, 6, 14, 0, 16,
+  0, 0, 0, 0, 28, 0, 23, 6, 0, 10,
+  7, 0, 0, 23, 0, 35, 38, 0, 52, 56,
+  0, 0, 11, 0, 0, 18, 0, 0, 0, 4,
+  0, 16, 29, 0, 0, 66, 6, 0, 0, 10,
+  18, 0, 38, 0, 0, 6, 0, 7, 0, 1,
+  0, 0, 17, 0, 0, 0, 5, 0, 43, 0,
+  63, 0, 11, 0, 0, 0, 0, 15, 0, 142,
+  5, 0, 3, 0, 0, 27, 43, 0, 0, 0,
+  6, 0, 0, 0, 37, 88, 23, 15, 8, 0,
+  0, 0, 0, 13, 0, 22, 26, 24, 0, 2,
+  0, 36, 0, 50, 0, 35, 0, 56, 1, 71,
+  43, 43, 0, 0, 0, 38, 8, 0, 4, 0,
+  67, 0, 33, 0, 0, 57, 0, 0, 64, 0,
+  0, 26, 62, 0, 74, 26, 27, 3, 4, 32,
+  9, 25, 0, 31, 35, 0, 37, 52, 8, 0,
+  19, 0, 0, 0, 0, 11, 7, 0, 1, 26,
+  0, 0, 10, 66, 18, 0, 0, 7, 8, 0,
+  31, 0, 0, 0, 0, 0, 0, 15, 0, 0,
+  111, 2, 35, 3, 0, 0, 0, 0, 41, 0,
+  0, 0, 0, 0, 0, 0, 0, 51, 48, 0,
+  17, 0, 0, 1, 56, 0, 12, 28, 33, 20,
+  5, 18, 77, 0, 0, 29, 0, 42, 17, 0,
+  0, 38, 0, 0, 71, 57, 0, 0, 0, 12,
+  0, 39, 0, 43, 0, 51, 0, 34, 20, 45,
+  0, 31, 15, 0, 71, 13, 0, 6, 44, 0,
+  0, 54, 15, 0, 0, 0, 0, 0, 23, 28,
+  33, 0, 0, 13, 0, 22, 15, 54, 0, 0,
+  0, 29, 69, 6, 16, 0, 25, 0, 11, 13,
+  3, 2, 0, 26, 5, 14, 0, 26, 0, 0,
+  43, 47, 11, 6, 0, 0, 0, 0, 43, 0,
+  0, 46, 1, 0, 0, 11, 0, 0, 48, 15,
+  46, 0, 23, 0, 104, 0, 47, 0, 0, 0,
+  0, 0, 0, 18, 14, 124, 8, 0, 7, 0,
+  0, 29, 52, 11, 0, 6, 15, 0, 0, 0,
+  0, 77, 2, 24, 40, 0, 0, 9, 0, 14,
+  0, 31, 15, 32, 0, 0, 0, 21, 0, 76,
+  0, 37, 0, 65, 12, 85, 61, 31, 0, 0,
+  0, 31, 31, 4, 2, 0, 40, 0, 18, 0,
+  23, 69, 0, 16, 12, 9, 0, 29, 58, 0,
+  39, 20, 11, 0, 25, 21, 19, 0, 0, 29,
+  42, 0, 16, 44, 15, 0, 11, 0, 0, 8,
+  0, 6, 0, 0, 4, 72, 0, 0, 0, 72,
+  0, 0, 4, 12, 57, 0, 27, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 77, 0, 47, 0,
+  6, 3, 0, 0, 55, 0, 22, 0, 0, 12,
+  0, 0, 34, 31, 37, 0, 16, 0, 1, 11,
+  52, 11, 10, 28, 23, 12, 0, 12, 51, 0,
+  0, 50, 24, 48, 0, 15, 0, 35, 0, 0,
+  38, 48, 0, 0, 0, 6, 0, 75, 0, 43,
+  0, 59, 29, 41, 15, 15, 0, 19, 0, 15,
+  107, 18, 0, 0, 17, 0, 0, 28, 25, 21,
+  0, 41, 0, 0, 45, 6, 26, 0, 0, 8,
+  0, 14, 33, 51, 4, 0, 0, 28, 84, 14,
+  0, 6, 19, 0, 12, 21, 18, 26, 0, 9,
+  9, 21, 0, 72, 0, 4, 31, 72, 0, 0,
+  2, 0, 39, 0, 26, 7, 9, 48, 0, 0,
+  0, 3, 0, 0, 39, 24, 41, 0, 37, 0,
+  84, 0, 64, 0, 13, 0, 0, 32, 0, 0,
+  20, 0, 56, 0, 35, 0, 0, 29, 28, 20,
+  52, 24, 39, 50, 3, 36, 95, 0, 10, 21,
+  21, 25, 9, 34, 0, 29, 0, 0, 63, 0,
+  10, 0, 0, 0, 0, 48, 0, 3, 0, 63,
+  16, 61, 5, 1, 0, 6, 0, 3, 79, 33,
+  0, 0, 18, 0, 0, 7, 0, 7, 0, 0,
+  0, 0, 32, 20, 20, 0, 0, 0, 0, 0,
+  62, 0, 13, 2, 0, 6, 67, 26, 0, 0,
+  6, 0, 7, 0, 11, 49, 18, 0, 0, 4,
+  0, 55, 0, 6, 64, 36, 0, 0, 3, 0,
+  34, 0, 22, 9, 31, 35, 0, 0, 0, 0,
+  0, 0, 14, 2, 12, 0, 45, 0, 77, 0,
+  41, 0, 26, 0, 0, 0, 0, 12, 0, 128,
+  4, 0, 24, 0, 0, 24, 44, 0, 0, 3,
+  15, 0, 0, 0, 17, 87, 14, 19, 11, 0,
+  0, 0, 0, 0, 0, 22, 19, 26, 0, 6,
+  0, 37, 0, 56, 0, 21, 0, 56, 0, 77,
+  54, 47, 0, 0, 0, 41, 15, 0, 2, 0,
+  67, 0, 29, 0, 3, 66, 0, 12, 54, 5,
+  0, 16, 73, 0, 77, 17, 14, 1, 0, 19,
+  20, 20, 0, 39, 27, 0, 45, 41, 10, 0,
+  5, 0, 0, 0, 0, 17, 0, 0, 0, 33,
+  0, 0, 7, 75, 14, 0, 0, 3, 5, 0,
+  19, 0, 0, 0, 0, 0, 0, 14, 0, 0,
+  93, 0, 37, 0, 0, 0, 0, 0, 36, 0,
+  0, 0, 0, 0, 0, 0, 0, 48, 47, 0,
+  22, 0, 0, 0, 38, 0, 10, 49, 31, 17,
+  0, 15, 62, 0, 0, 40, 0, 20, 12, 0,
+  0, 26, 0, 0, 64, 55, 8, 0, 0, 16,
+  0, 41, 0, 28, 0, 56, 0, 45, 21, 45,
+  0, 12, 2, 10, 93, 9, 0, 9, 48, 0,
+  0, 35, 16, 4, 0, 1, 0, 0, 17, 7,
+  42, 0, 2, 3, 0, 21, 13, 42, 3, 0,
+  0, 26, 69, 0, 18, 2, 18, 0, 12, 0,
+  9, 8, 0, 31, 0, 8, 5, 29, 0, 0,
+  36, 54, 18, 0, 0, 0, 1, 0, 24, 4,
+  0, 31, 0, 1, 0, 19, 0, 0, 51, 3,
+  32, 0, 21, 0, 83, 0, 35, 0, 4, 0,
+  0, 9, 0, 0, 15, 0, 57, 0, 37, 0,
+  0, 0, 30, 12, 51, 40, 45, 47, 0, 28,
+  101, 0, 0, 27, 0, 9, 25, 8, 0, 23,
+  0, 0, 52, 4, 22, 0, 0, 12, 0, 35,
+  0, 7, 0, 70, 5, 54, 4, 16, 0, 0,
+  13, 8, 68, 27, 0, 0, 28, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 23, 1, 27, 0,
+  0, 0, 0, 10, 48, 0, 7, 9, 0, 11,
+  57, 13, 9, 0, 13, 0, 0, 0, 22, 29,
+  9, 0, 0, 15, 0, 34, 0, 0, 59, 37,
+  0, 0, 0, 0, 12, 0, 17, 14, 11, 27,
+  0, 0, 0, 5, 0, 0, 24, 0, 14, 0,
+  27, 0, 77, 0, 21, 0, 13, 0, 0, 0,
+  0, 15, 0, 142, 5, 0, 3, 0, 0, 27,
+  43, 0, 0, 0, 6, 0, 0, 0, 37, 88,
+  23, 15, 8, 0, 0, 0, 0, 13, 0, 22,
+  26, 24, 0, 2, 0, 36, 0, 50, 0, 35,
+  0, 56, 1, 71, 43, 43, 0, 0, 0, 38,
+  8, 0, 4, 0, 67, 0, 33, 0, 0, 57,
+  0, 0, 64, 0, 0, 26, 62, 0, 74, 26,
+  27, 3, 4, 32, 9, 25, 0, 31, 35, 0,
+  37, 52, 8, 0, 19, 0, 0, 0, 0, 11,
+  7, 0, 1, 26, 0, 0, 10, 66, 18, 0,
+  0, 7, 8, 0, 31, 0, 0, 0, 0, 0,
+  0, 15, 0, 0, 111, 2, 35, 3, 0, 0,
+  0, 0, 41, 0, 0, 0, 0, 0, 0, 0,
+  0, 51, 48, 0, 17, 0, 0, 1, 56, 0,
+  12, 28, 33, 20, 5, 18, 77, 0, 0, 29,
+  0, 42, 17, 0, 0, 38, 0, 0, 71, 57,
+  0, 0, 0, 12, 0, 39, 0, 43, 0, 51,
+  0, 34, 20, 45, 0, 31, 15, 0, 71, 13,
+  0, 6, 44, 0, 0, 54, 15, 0, 0, 0,
+  0, 0, 23, 28, 33, 0, 0, 13, 0, 22,
+  15, 54, 0, 0, 0, 29, 69, 6, 16, 0,
+  25, 0, 11, 13, 3, 2, 0, 26, 5, 14,
+  0, 26, 0, 0, 43, 47, 11, 6, 0, 0,
+  0, 0, 43, 0, 0, 46, 1, 0, 0, 11,
+  0, 0, 48, 15, 46, 0, 23, 0, 104, 0,
+  47, 0, 0, 0, 0, 29, 0, 0, 20, 0,
+  45, 0, 38, 0, 0, 2, 26, 28, 73, 29,
+  52, 53, 0, 24, 91, 0, 0, 24, 16, 39,
+  26, 0, 0, 20, 0, 0, 40, 12, 3, 0,
+  0, 8, 0, 47, 0, 9, 0, 58, 0, 33,
+  12, 19, 0, 0, 17, 3, 66, 44, 0, 0,
+  7, 0, 0, 3, 7, 0, 0, 0, 0, 0,
+  42, 7, 32, 0, 0, 0, 0, 10, 51, 0,
+  4, 0, 0, 8, 61, 18, 25, 0, 32, 0,
+  8, 4, 12, 12, 2, 0, 0, 26, 0, 31,
+  0, 0, 56, 29, 0, 2, 0, 0, 0, 0,
+  30, 0, 7, 37, 0, 0, 0, 21, 0, 0,
+  7, 6, 14, 0, 16, 0, 90, 0, 25, 0,
+  12, 0, 0, 12, 0, 0, 34, 31, 37, 0,
+  16, 0, 1, 11, 52, 11, 10, 28, 23, 12,
+  0, 12, 51, 0, 0, 50, 24, 48, 0, 15,
+  0, 35, 0, 0, 38, 48, 0, 0, 0, 6,
+  0, 75, 0, 43, 0, 59, 29, 41, 15, 15,
+  0, 19, 0, 15, 107, 18, 0, 0, 17, 0,
+  0, 28, 25, 21, 0, 41, 0, 0, 45, 6,
+  26, 0, 0, 8, 0, 14, 33, 51, 4, 0,
+  0, 28, 84, 14, 0, 6, 19, 0, 12, 21,
+  18, 26, 0, 9, 9, 21, 0, 72, 0, 4,
+  31, 72, 0, 0, 2, 0, 39, 0, 26, 7,
+  9, 48, 0, 0, 0, 3, 0, 0, 39, 24,
+  41, 0, 37, 0, 84, 0, 64, 0, 13, 0,
+  0, 32, 0, 0, 20, 0, 56, 0, 35, 0,
+  0, 29, 28, 20, 52, 24, 39, 50, 3, 36,
+  95, 0, 10, 21, 21, 25, 9, 34, 0, 29,
+  0, 0, 63, 0, 10, 0, 0, 0, 0, 48,
+  0, 3, 0, 63, 16, 61, 5, 1, 0, 6,
+  0, 3, 79, 33, 0, 0, 18, 0, 0, 7,
+  0, 7, 0, 0, 0, 0, 32, 20, 20, 0,
+  0, 0, 0, 0, 62, 0, 13, 2, 0, 6,
+  67, 26, 0, 0, 6, 0, 7, 0, 11, 49,
+  18, 0, 0, 4, 0, 55, 0, 6, 64, 36,
+  0, 0, 3, 0, 34, 0, 22, 9, 31, 35,
+  0, 0, 0, 0, 0, 0, 14, 2, 12, 0,
+  45, 0, 77, 0, 41, 0, 26, 0, 0, 27,
+  0, 15, 17, 0, 54, 0, 26, 19, 0, 24,
+  19, 41, 54, 36, 42, 53, 0, 29, 105, 0,
+  0, 24, 36, 35, 13, 47, 0, 36, 0, 0,
+  67, 9, 22, 0, 0, 0, 0, 30, 0, 0,
+  0, 58, 16, 44, 12, 18, 0, 3, 21, 11,
+  61, 51, 0, 0, 3, 0, 0, 16, 0, 0,
+  0, 0, 0, 0, 38, 18, 25, 0, 0, 0,
+  0, 0, 56, 0, 14, 7, 0, 10, 79, 42,
+  2, 0, 11, 0, 6, 6, 16, 33, 14, 0,
+  0, 12, 0, 42, 0, 6, 83, 38, 0, 0,
+  5, 0, 37, 0, 29, 9, 43, 27, 0, 0,
+  1, 0, 0, 0, 12, 0, 2, 0, 32, 0,
+  100, 0, 40, 0, 22, 0, 0, 0, 0, 0,
+  0, 48, 47, 0, 22, 0, 0, 0, 38, 0,
+  10, 49, 31, 17, 0, 15, 62, 0, 0, 40,
+  0, 20, 12, 0, 0, 26, 0, 0, 64, 55,
+  8, 0, 0, 16, 0, 41, 0, 28, 0, 56,
+  0, 45, 21, 45, 0, 12, 2, 10, 93, 9,
+  0, 9, 48, 0, 0, 35, 16, 4, 0, 1,
+  0, 0, 17, 7, 42, 0, 2, 3, 0, 21,
+  13, 42, 3, 0, 0, 26, 69, 0, 18, 2,
+  18, 0, 12, 0, 9, 8, 0, 31, 0, 8,
+  5, 29, 0, 0, 36, 54, 18, 0, 0, 0,
+  1, 0, 24, 4, 0, 31, 0, 1, 0, 19,
+  0, 0, 51, 3, 32, 0, 21, 0, 83, 0,
+  35, 0, 4, 0, 0, 9, 0, 0, 15, 0,
+  57, 0, 37, 0, 0, 0, 30, 12, 51, 40,
+  45, 47, 0, 28, 101, 0, 0, 27, 0, 9,
+  25, 8, 0, 23, 0, 0, 52, 4, 22, 0,
+  0, 12, 0, 35, 0, 7, 0, 70, 5, 54,
+  4, 16, 0, 0, 13, 8, 68, 27, 0, 0,
+  28, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  23, 1, 27, 0, 0, 0, 0, 10, 48, 0,
+  7, 9, 0, 11, 57, 13, 9, 0, 13, 0,
+  0, 0, 22, 29, 9, 0, 0, 15, 0, 34,
+  0, 0, 59, 37, 0, 0, 0, 0, 12, 0,
+  17, 14, 11, 27, 0, 0, 0, 5, 0, 0,
+  24, 0, 14, 0, 27, 0, 77, 0, 21, 0,
+  13, 0, 0, 33, 0, 0, 27, 0, 41, 0,
+  45, 22, 0, 7, 22, 44, 69, 48, 60, 49,
+  0, 17, 100, 0, 0, 26, 19, 29, 19, 25,
+  0, 21, 0, 0, 29, 10, 19, 0, 0, 21,
+  0, 35, 0, 0, 0, 56, 7, 31, 16, 4,
+  0, 0, 48, 0, 33, 46, 0, 2, 16, 0,
+  0, 12, 0, 0, 0, 0, 0, 0, 48, 0,
+  33, 0, 0, 0, 0, 6, 51, 0, 15, 23,
+  0, 30, 42, 35, 0, 0, 24, 0, 0, 0,
+  26, 42, 0, 0, 0, 46, 0, 27, 0, 13,
+  75, 38, 0, 0, 0, 0, 17, 0, 16, 5,
+  28, 44, 0, 0, 0, 5, 8, 0, 2, 0,
+  24, 0, 4, 0, 105, 0, 27, 6, 32, 0,
+  0, 0, 0, 0, 0, 51, 48, 0, 17, 0,
+  0, 1, 56, 0, 12, 28, 33, 20, 5, 18,
+  77, 0, 0, 29, 0, 42, 17, 0, 0, 38,
+  0, 0, 71, 57, 0, 0, 0, 12, 0, 39,
+  0, 43, 0, 51, 0, 34, 20, 45, 0, 31,
+  15, 0, 71, 13, 0, 6, 44, 0, 0, 54,
+  15, 0, 0, 0, 0, 0, 23, 28, 33, 0,
+  0, 13, 0, 22, 15, 54, 0, 0, 0, 29,
+  69, 6, 16, 0, 25, 0, 11, 13, 3, 2,
+  0, 26, 5, 14, 0, 26, 0, 0, 43, 47,
+  11, 6, 0, 0, 0, 0, 43, 0, 0, 46,
+  1, 0, 0, 11, 0, 0, 48, 15, 46, 0,
+  23, 0, 104, 0, 47, 0, 0, 0, 0, 29,
+  0, 0, 20, 0, 45, 0, 38, 0, 0, 2,
+  26, 28, 73, 29, 52, 53, 0, 24, 91, 0,
+  0, 24, 16, 39, 26, 0, 0, 20, 0, 0,
+  40, 12, 3, 0, 0, 8, 0, 47, 0, 9,
+  0, 58, 0, 33, 12, 19, 0, 0, 17, 3,
+  66, 44, 0, 0, 7, 0, 0, 3, 7, 0,
+  0, 0, 0, 0, 42, 7, 32, 0, 0, 0,
+  0, 10, 51, 0, 4, 0, 0, 8, 61, 18,
+  25, 0, 32, 0, 8, 4, 12, 12, 2, 0,
+  0, 26, 0, 31, 0, 0, 56, 29, 0, 2,
+  0, 0, 0, 0, 30, 0, 7, 37, 0, 0,
+  0, 21, 0, 0, 7, 6, 14, 0, 16, 0,
+  90, 0, 25, 0, 12, 0, 0, 65, 0, 0,
+  34, 0, 36, 0, 61, 12, 0, 5, 44, 54,
+  61, 74, 64, 45, 0, 12, 72, 0, 0, 33,
+  31, 57, 17, 27, 0, 12, 0, 0, 29, 8,
+  17, 0, 0, 37, 0, 58, 0, 3, 0, 54,
+  0, 29, 24, 4, 0, 0, 35, 0, 43, 56,
+  0, 0, 7, 0, 0, 32, 0, 0, 0, 0,
+  0, 0, 70, 9, 41, 0, 0, 0, 0, 18,
+  51, 0, 0, 21, 0, 27, 40, 52, 13, 20,
+  40, 15, 0, 9, 25, 57, 3, 0, 0, 59,
+  0, 27, 0, 5, 69, 44, 0, 0, 0, 0,
+  2, 0, 12, 20, 36, 60, 0, 0, 0, 21,
+  0, 0, 0, 18, 24, 0, 0, 1, 134, 0,
+  38, 0, 44, 0, 0, 32, 0, 0, 20, 0,
+  56, 0, 35, 0, 0, 29, 28, 20, 52, 24,
+  39, 50, 3, 36, 95, 0, 10, 21, 21, 25,
+  9, 34, 0, 29, 0, 0, 63, 0, 10, 0,
+  0, 0, 0, 48, 0, 3, 0, 63, 16, 61,
+  5, 1, 0, 6, 0, 3, 79, 33, 0, 0,
+  18, 0, 0, 7, 0, 7, 0, 0, 0, 0,
+  32, 20, 20, 0, 0, 0, 0, 0, 62, 0,
+  13, 2, 0, 6, 67, 26, 0, 0, 6, 0,
+  7, 0, 11, 49, 18, 0, 0, 4, 0, 55,
+  0, 6, 64, 36, 0, 0, 3, 0, 34, 0,
+  22, 9, 31, 35, 0, 0, 0, 0, 0, 0,
+  14, 2, 12, 0, 45, 0, 77, 0, 41, 0,
+  26, 0, 0, 27, 0, 15, 17, 0, 54, 0,
+  26, 19, 0, 24, 19, 41, 54, 36, 42, 53,
+  0, 29, 105, 0, 0, 24, 36, 35, 13, 47,
+  0, 36, 0, 0, 67, 9, 22, 0, 0, 0,
+  0, 30, 0, 0, 0, 58, 16, 44, 12, 18,
+  0, 3, 21, 11, 61, 51, 0, 0, 3, 0,
+  0, 16, 0, 0, 0, 0, 0, 0, 38, 18,
+  25, 0, 0, 0, 0, 0, 56, 0, 14, 7,
+  0, 10, 79, 42, 2, 0, 11, 0, 6, 6,
+  16, 33, 14, 0, 0, 12, 0, 42, 0, 6,
+  83, 38, 0, 0, 5, 0, 37, 0, 29, 9,
+  43, 27, 0, 0, 1, 0, 0, 0, 12, 0,
+  2, 0, 32, 0, 100, 0, 40, 0, 22, 0,
+  0, 22, 0, 0, 8, 0, 32, 0, 33, 28,
+  0, 1, 0, 29, 40, 48, 56, 56, 12, 13,
+  56, 0, 0, 29, 28, 42, 16, 56, 0, 19,
+  0, 0, 57, 2, 6, 0, 0, 0, 0, 24,
+  0, 0, 0, 16, 1, 14, 21, 10, 0, 5,
+  37, 5, 41, 38, 0, 11, 0, 24, 0, 42,
+  0, 0, 0, 0, 0, 0, 70, 24, 23, 0,
+  0, 0, 11, 21, 44, 0, 8, 0, 0, 12,
+  70, 39, 7, 8, 19, 29, 0, 28, 16, 3,
+  38, 30, 0, 36, 4, 7, 0, 4, 60, 56,
+  0, 0, 5, 0, 33, 0, 12, 9, 35, 35,
+  0, 12, 2, 0, 10, 0, 0, 0, 0, 0,
+  6, 0, 111, 0, 30, 0, 9, 0, 0, 9,
+  0, 0, 15, 0, 57, 0, 37, 0, 0, 0,
+  30, 12, 51, 40, 45, 47, 0, 28, 101, 0,
+  0, 27, 0, 9, 25, 8, 0, 23, 0, 0,
+  52, 4, 22, 0, 0, 12, 0, 35, 0, 7,
+  0, 70, 5, 54, 4, 16, 0, 0, 13, 8,
+  68, 27, 0, 0, 28, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 23, 1, 27, 0, 0, 0,
+  0, 10, 48, 0, 7, 9, 0, 11, 57, 13,
+  9, 0, 13, 0, 0, 0, 22, 29, 9, 0,
+  0, 15, 0, 34, 0, 0, 59, 37, 0, 0,
+  0, 0, 12, 0, 17, 14, 11, 27, 0, 0,
+  0, 5, 0, 0, 24, 0, 14, 0, 27, 0,
+  77, 0, 21, 0, 13, 0, 0, 33, 0, 0,
+  27, 0, 41, 0, 45, 22, 0, 7, 22, 44,
+  69, 48, 60, 49, 0, 17, 100, 0, 0, 26,
+  19, 29, 19, 25, 0, 21, 0, 0, 29, 10,
+  19, 0, 0, 21, 0, 35, 0, 0, 0, 56,
+  7, 31, 16, 4, 0, 0, 48, 0, 33, 46,
+  0, 2, 16, 0, 0, 12, 0, 0, 0, 0,
+  0, 0, 48, 0, 33, 0, 0, 0, 0, 6,
+  51, 0, 15, 23, 0, 30, 42, 35, 0, 0,
+  24, 0, 0, 0, 26, 42, 0, 0, 0, 46,
+  0, 27, 0, 13, 75, 38, 0, 0, 0, 0,
+  17, 0, 16, 5, 28, 44, 0, 0, 0, 5,
+  8, 0, 2, 0, 24, 0, 4, 0, 105, 0,
+  27, 6, 32, 0, 0, 33, 0, 0, 36, 0,
+  0, 3, 48, 28, 0, 0, 10, 59, 39, 46,
+  67, 44, 12, 0, 51, 0, 0, 36, 0, 22,
+  41, 60, 0, 0, 0, 0, 19, 0, 7, 0,
+  0, 22, 0, 24, 0, 0, 0, 4, 0, 17,
+  23, 0, 0, 0, 55, 0, 1, 17, 0, 0,
+  18, 15, 0, 17, 0, 0, 0, 0, 0, 0,
+  102, 0, 17, 0, 0, 0, 5, 41, 35, 0,
+  3, 53, 0, 13, 18, 38, 12, 42, 10, 28,
+  0, 30, 22, 26, 21, 17, 0, 42, 0, 0,
+  0, 2, 49, 55, 1, 0, 0, 0, 16, 0,
+  14, 19, 32, 69, 0, 3, 0, 0, 21, 0,
+  0, 0, 17, 0, 0, 13, 100, 0, 0, 0,
+  30, 37, 0, 29, 0, 0, 20, 0, 45, 0,
+  38, 0, 0, 2, 26, 28, 73, 29, 52, 53,
+  0, 24, 91, 0, 0, 24, 16, 39, 26, 0,
+  0, 20, 0, 0, 40, 12, 3, 0, 0, 8,
+  0, 47, 0, 9, 0, 58, 0, 33, 12, 19,
+  0, 0, 17, 3, 66, 44, 0, 0, 7, 0,
+  0, 3, 7, 0, 0, 0, 0, 0, 42, 7,
+  32, 0, 0, 0, 0, 10, 51, 0, 4, 0,
+  0, 8, 61, 18, 25, 0, 32, 0, 8, 4,
+  12, 12, 2, 0, 0, 26, 0, 31, 0, 0,
+  56, 29, 0, 2, 0, 0, 0, 0, 30, 0,
+  7, 37, 0, 0, 0, 21, 0, 0, 7, 6,
+  14, 0, 16, 0, 90, 0, 25, 0, 12, 0,
+  0, 65, 0, 0, 34, 0, 36, 0, 61, 12,
+  0, 5, 44, 54, 61, 74, 64, 45, 0, 12,
+  72, 0, 0, 33, 31, 57, 17, 27, 0, 12,
+  0, 0, 29, 8, 17, 0, 0, 37, 0, 58,
+  0, 3, 0, 54, 0, 29, 24, 4, 0, 0,
+  35, 0, 43, 56, 0, 0, 7, 0, 0, 32,
+  0, 0, 0, 0, 0, 0, 70, 9, 41, 0,
+  0, 0, 0, 18, 51, 0, 0, 21, 0, 27,
+  40, 52, 13, 20, 40, 15, 0, 9, 25, 57,
+  3, 0, 0, 59, 0, 27, 0, 5, 69, 44,
+  0, 0, 0, 0, 2, 0, 12, 20, 36, 60,
+  0, 0, 0, 21, 0, 0, 0, 18, 24, 0,
+  0, 1, 134, 0, 38, 0, 44, 0, 0, 26,
+  42, 0, 40, 0, 0, 0, 68, 7, 0, 5,
+  43, 69, 21, 36, 59, 16, 3, 0, 30, 7,
+  16, 33, 0, 0, 32, 69, 0, 5, 0, 0,
+  0, 0, 0, 0, 0, 55, 0, 45, 0, 4,
+  0, 0, 0, 8, 12, 0, 0, 16, 23, 16,
+  0, 8, 0, 0, 24, 20, 0, 0, 0, 0,
+  0, 0, 0, 0, 70, 10, 16, 0, 0, 0,
+  0, 27, 24, 0, 0, 57, 0, 13, 0, 13,
+  15, 76, 12, 31, 0, 45, 9, 26, 24, 0,
+  0, 11, 0, 0, 0, 0, 52, 56, 16, 0,
+  0, 0, 1, 0, 7, 24, 39, 91, 4, 0,
+  0, 0, 0, 0, 11, 0, 10, 0, 0, 35,
+  51, 0, 0, 0, 24, 66, 0, 27, 0, 15,
+  17, 0, 54, 0, 26, 19, 0, 24, 19, 41,
+  54, 36, 42, 53, 0, 29, 105, 0, 0, 24,
+  36, 35, 13, 47, 0, 36, 0, 0, 67, 9,
+  22, 0, 0, 0, 0, 30, 0, 0, 0, 58,
+  16, 44, 12, 18, 0, 3, 21, 11, 61, 51,
+  0, 0, 3, 0, 0, 16, 0, 0, 0, 0,
+  0, 0, 38, 18, 25, 0, 0, 0, 0, 0,
+  56, 0, 14, 7, 0, 10, 79, 42, 2, 0,
+  11, 0, 6, 6, 16, 33, 14, 0, 0, 12,
+  0, 42, 0, 6, 83, 38, 0, 0, 5, 0,
+  37, 0, 29, 9, 43, 27, 0, 0, 1, 0,
+  0, 0, 12, 0, 2, 0, 32, 0, 100, 0,
+  40, 0, 22, 0, 0, 22, 0, 0, 8, 0,
+  32, 0, 33, 28, 0, 1, 0, 29, 40, 48,
+  56, 56, 12, 13, 56, 0, 0, 29, 28, 42,
+  16, 56, 0, 19, 0, 0, 57, 2, 6, 0,
+  0, 0, 0, 24, 0, 0, 0, 16, 1, 14,
+  21, 10, 0, 5, 37, 5, 41, 38, 0, 11,
+  0, 24, 0, 42, 0, 0, 0, 0, 0, 0,
+  70, 24, 23, 0, 0, 0, 11, 21, 44, 0,
+  8, 0, 0, 12, 70, 39, 7, 8, 19, 29,
+  0, 28, 16, 3, 38, 30, 0, 36, 4, 7,
+  0, 4, 60, 56, 0, 0, 5, 0, 33, 0,
+  12, 9, 35, 35, 0, 12, 2, 0, 10, 0,
+  0, 0, 0, 0, 6, 0, 111, 0, 30, 0,
+  9, 0, 0, 40, 0, 0, 15, 0, 26, 0,
+  40, 45, 1, 0, 0, 24, 16, 54, 51, 59,
+  27, 8, 15, 0, 0, 41, 35, 63, 9, 78,
+  0, 0, 8, 0, 21, 0, 0, 0, 0, 0,
+  0, 35, 0, 0, 0, 0, 0, 0, 38, 0,
+  0, 5, 22, 8, 24, 27, 0, 0, 0, 65,
+  0, 36, 0, 0, 0, 33, 0, 2, 97, 14,
+  35, 0, 0, 0, 20, 36, 43, 5, 0, 0,
+  0, 9, 52, 53, 0, 20, 31, 37, 0, 46,
+  33, 0, 42, 41, 0, 48, 0, 0, 2, 16,
+  45, 62, 0, 0, 12, 0, 34, 0, 0, 17,
+  24, 34, 0, 27, 0, 0, 25, 0, 0, 14,
+  10, 0, 0, 8, 110, 0, 42, 0, 17, 9,
+  0, 33, 0, 0, 27, 0, 41, 0, 45, 22,
+  0, 7, 22, 44, 69, 48, 60, 49, 0, 17,
+  100, 0, 0, 26, 19, 29, 19, 25, 0, 21,
+  0, 0, 29, 10, 19, 0, 0, 21, 0, 35,
+  0, 0, 0, 56, 7, 31, 16, 4, 0, 0,
+  48, 0, 33, 46, 0, 2, 16, 0, 0, 12,
+  0, 0, 0, 0, 0, 0, 48, 0, 33, 0,
+  0, 0, 0, 6, 51, 0, 15, 23, 0, 30,
+  42, 35, 0, 0, 24, 0, 0, 0, 26, 42,
+  0, 0, 0, 46, 0, 27, 0, 13, 75, 38,
+  0, 0, 0, 0, 17, 0, 16, 5, 28, 44,
+  0, 0, 0, 5, 8, 0, 2, 0, 24, 0,
+  4, 0, 105, 0, 27, 6, 32, 0, 0, 33,
+  0, 0, 36, 0, 0, 3, 48, 28, 0, 0,
+  10, 59, 39, 46, 67, 44, 12, 0, 51, 0,
+  0, 36, 0, 22, 41, 60, 0, 0, 0, 0,
+  19, 0, 7, 0, 0, 22, 0, 24, 0, 0,
+  0, 4, 0, 17, 23, 0, 0, 0, 55, 0,
+  1, 17, 0, 0, 18, 15, 0, 17, 0, 0,
+  0, 0, 0, 0, 102, 0, 17, 0, 0, 0,
+  5, 41, 35, 0, 3, 53, 0, 13, 18, 38,
+  12, 42, 10, 28, 0, 30, 22, 26, 21, 17,
+  0, 42, 0, 0, 0, 2, 49, 55, 1, 0,
+  0, 0, 16, 0, 14, 19, 32, 69, 0, 3,
+  0, 0, 21, 0, 0, 0, 17, 0, 0, 13,
+  100, 0, 0, 0, 30, 37, 12, 0, 30, 0,
+  18, 0, 0, 0, 37, 30, 0, 0, 4, 71,
+  11, 0, 44, 48, 26, 0, 25, 1, 22, 8,
+  0, 6, 34, 49, 0, 0, 16, 0, 0, 5,
+  0, 0, 40, 32, 0, 1, 1, 0, 0, 0,
+  0, 0, 9, 0, 0, 0, 31, 0, 0, 10,
+  0, 0, 0, 51, 0, 0, 2, 6, 23, 5,
+  0, 0, 106, 5, 12, 82, 0, 0, 6, 39,
+  0, 0, 0, 50, 1, 0, 0, 34, 0, 54,
+  42, 31, 0, 69, 0, 0, 0, 56, 0, 0,
+  20, 0, 0, 15, 19, 45, 10, 6, 0, 0,
+  0, 0, 0, 21, 1, 57, 6, 0, 0, 0,
+  53, 11, 0, 0, 15, 0, 0, 26, 8, 0,
+  0, 12, 42, 48, 0, 65, 0, 0, 34, 0,
+  36, 0, 61, 12, 0, 5, 44, 54, 61, 74,
+  64, 45, 0, 12, 72, 0, 0, 33, 31, 57,
+  17, 27, 0, 12, 0, 0, 29, 8, 17, 0,
+  0, 37, 0, 58, 0, 3, 0, 54, 0, 29,
+  24, 4, 0, 0, 35, 0, 43, 56, 0, 0,
+  7, 0, 0, 32, 0, 0, 0, 0, 0, 0,
+  70, 9, 41, 0, 0, 0, 0, 18, 51, 0,
+  0, 21, 0, 27, 40, 52, 13, 20, 40, 15,
+  0, 9, 25, 57, 3, 0, 0, 59, 0, 27,
+  0, 5, 69, 44, 0, 0, 0, 0, 2, 0,
+  12, 20, 36, 60, 0, 0, 0, 21, 0, 0,
+  0, 18, 24, 0, 0, 1, 134, 0, 38, 0,
+  44, 0, 0, 26, 42, 0, 40, 0, 0, 0,
+  68, 7, 0, 5, 43, 69, 21, 36, 59, 16,
+  3, 0, 30, 7, 16, 33, 0, 0, 32, 69,
+  0, 5, 0, 0, 0, 0, 0, 0, 0, 55,
+  0, 45, 0, 4, 0, 0, 0, 8, 12, 0,
+  0, 16, 23, 16, 0, 8, 0, 0, 24, 20,
+  0, 0, 0, 0, 0, 0, 0, 0, 70, 10,
+  16, 0, 0, 0, 0, 27, 24, 0, 0, 57,
+  0, 13, 0, 13, 15, 76, 12, 31, 0, 45,
+  9, 26, 24, 0, 0, 11, 0, 0, 0, 0,
+  52, 56, 16, 0, 0, 0, 1, 0, 7, 24,
+  39, 91, 4, 0, 0, 0, 0, 0, 11, 0,
+  10, 0, 0, 35, 51, 0, 0, 0, 24, 66,
+  70, 0, 17, 0, 20, 30, 0, 0, 12, 0,
+  0, 0, 2, 79, 18, 0, 26, 23, 6, 5,
+  29, 52, 17, 15, 0, 0, 8, 29, 0, 0,
+  0, 9, 0, 47, 0, 0, 7, 43, 0, 12,
+  0, 10, 0, 0, 5, 0, 16, 5, 10, 0,
+  24, 4, 0, 0, 15, 0, 23, 37, 5, 0,
+  30, 16, 31, 0, 0, 12, 69, 32, 32, 66,
+  0, 18, 10, 0, 25, 0, 0, 55, 11, 6,
+  0, 12, 0, 37, 48, 12, 31, 65, 0, 0,
+  0, 0, 0, 0, 29, 0, 0, 17, 57, 30,
+  0, 27, 0, 0, 0, 60, 0, 14, 29, 64,
+  0, 0, 0, 1, 7, 52, 58, 0, 0, 0,
+  0, 32, 0, 0, 0, 19, 23, 49, 0, 22,
+  0, 0, 8, 0, 32, 0, 33, 28, 0, 1,
+  0, 29, 40, 48, 56, 56, 12, 13, 56, 0,
+  0, 29, 28, 42, 16, 56, 0, 19, 0, 0,
+  57, 2, 6, 0, 0, 0, 0, 24, 0, 0,
+  0, 16, 1, 14, 21, 10, 0, 5, 37, 5,
+  41, 38, 0, 11, 0, 24, 0, 42, 0, 0,
+  0, 0, 0, 0, 70, 24, 23, 0, 0, 0,
+  11, 21, 44, 0, 8, 0, 0, 12, 70, 39,
+  7, 8, 19, 29, 0, 28, 16, 3, 38, 30,
+  0, 36, 4, 7, 0, 4, 60, 56, 0, 0,
+  5, 0, 33, 0, 12, 9, 35, 35, 0, 12,
+  2, 0, 10, 0, 0, 0, 0, 0, 6, 0,
+  111, 0, 30, 0, 9, 0, 0, 40, 0, 0,
+  15, 0, 26, 0, 40, 45, 1, 0, 0, 24,
+  16, 54, 51, 59, 27, 8, 15, 0, 0, 41,
+  35, 63, 9, 78, 0, 0, 8, 0, 21, 0,
+  0, 0, 0, 0, 0, 35, 0, 0, 0, 0,
+  0, 0, 38, 0, 0, 5, 22, 8, 24, 27,
+  0, 0, 0, 65, 0, 36, 0, 0, 0, 33,
+  0, 2, 97, 14, 35, 0, 0, 0, 20, 36,
+  43, 5, 0, 0, 0, 9, 52, 53, 0, 20,
+  31, 37, 0, 46, 33, 0, 42, 41, 0, 48,
+  0, 0, 2, 16, 45, 62, 0, 0, 12, 0,
+  34, 0, 0, 17, 24, 34, 0, 27, 0, 0,
+  25, 0, 0, 14, 10, 0, 0, 8, 110, 0,
+  42, 0, 17, 9, 0, 44, 12, 0, 11, 0,
+  23, 0, 54, 79, 0, 0, 0, 0, 3, 53,
+  49, 60, 36, 23, 0, 0, 0, 42, 29, 49,
+  27, 93, 0, 0, 15, 0, 15, 0, 0, 0,
+  0, 32, 0, 20, 0, 0, 0, 0, 0, 7,
+  42, 0, 0, 5, 12, 12, 37, 19, 0, 0,
+  0, 60, 0, 25, 1, 12, 0, 29, 0, 0,
+  86, 0, 36, 9, 0, 0, 13, 38, 43, 13,
+  0, 16, 0, 0, 60, 35, 0, 10, 27, 23,
+  0, 45, 43, 0, 17, 49, 0, 42, 0, 0,
+  4, 7, 24, 57, 0, 0, 23, 0, 36, 0,
+  0, 1, 19, 59, 0, 22, 0, 0, 36, 0,
+  0, 24, 28, 0, 1, 18, 93, 0, 22, 0,
+  42, 20, 0, 33, 0, 0, 36, 0, 0, 3,
+  48, 28, 0, 0, 10, 59, 39, 46, 67, 44,
+  12, 0, 51, 0, 0, 36, 0, 22, 41, 60,
+  0, 0, 0, 0, 19, 0, 7, 0, 0, 22,
+  0, 24, 0, 0, 0, 4, 0, 17, 23, 0,
+  0, 0, 55, 0, 1, 17, 0, 0, 18, 15,
+  0, 17, 0, 0, 0, 0, 0, 0, 102, 0,
+  17, 0, 0, 0, 5, 41, 35, 0, 3, 53,
+  0, 13, 18, 38, 12, 42, 10, 28, 0, 30,
+  22, 26, 21, 17, 0, 42, 0, 0, 0, 2,
+  49, 55, 1, 0, 0, 0, 16, 0, 14, 19,
+  32, 69, 0, 3, 0, 0, 21, 0, 0, 0,
+  17, 0, 0, 13, 100, 0, 0, 0, 30, 37,
+  12, 0, 30, 0, 18, 0, 0, 0, 37, 30,
+  0, 0, 4, 71, 11, 0, 44, 48, 26, 0,
+  25, 1, 22, 8, 0, 6, 34, 49, 0, 0,
+  16, 0, 0, 5, 0, 0, 40, 32, 0, 1,
+  1, 0, 0, 0, 0, 0, 9, 0, 0, 0,
+  31, 0, 0, 10, 0, 0, 0, 51, 0, 0,
+  2, 6, 23, 5, 0, 0, 106, 5, 12, 82,
+  0, 0, 6, 39, 0, 0, 0, 50, 1, 0,
+  0, 34, 0, 54, 42, 31, 0, 69, 0, 0,
+  0, 56, 0, 0, 20, 0, 0, 15, 19, 45,
+  10, 6, 0, 0, 0, 0, 0, 21, 1, 57,
+  6, 0, 0, 0, 53, 11, 0, 0, 15, 0,
+  0, 26, 8, 0, 0, 12, 42, 48, 16, 0,
+  43, 0, 0, 0, 0, 0, 40, 54, 0, 16,
+  0, 59, 14, 0, 21, 57, 23, 17, 21, 14,
+  54, 0, 0, 0, 42, 21, 0, 0, 0, 0,
+  0, 0, 0, 0, 54, 47, 0, 0, 9, 0,
+  0, 0, 0, 0, 9, 0, 0, 0, 23, 0,
+  0, 0, 10, 0, 8, 40, 0, 0, 0, 25,
+  50, 0, 59, 21, 36, 7, 0, 114, 0, 9,
+  8, 6, 0, 0, 4, 34, 0, 0, 0, 19,
+  0, 29, 42, 2, 22, 44, 6, 0, 0, 57,
+  0, 0, 19, 0, 0, 0, 14, 17, 24, 0,
+  0, 0, 0, 0, 0, 0, 0, 39, 0, 0,
+  0, 0, 81, 4, 14, 0, 20, 0, 0, 18,
+  0, 0, 0, 19, 37, 4, 0, 26, 42, 0,
+  40, 0, 0, 0, 68, 7, 0, 5, 43, 69,
+  21, 36, 59, 16, 3, 0, 30, 7, 16, 33,
+  0, 0, 32, 69, 0, 5, 0, 0, 0, 0,
+  0, 0, 0, 55, 0, 45, 0, 4, 0, 0,
+  0, 8, 12, 0, 0, 16, 23, 16, 0, 8,
+  0, 0, 24, 20, 0, 0, 0, 0, 0, 0,
+  0, 0, 70, 10, 16, 0, 0, 0, 0, 27,
+  24, 0, 0, 57, 0, 13, 0, 13, 15, 76,
+  12, 31, 0, 45, 9, 26, 24, 0, 0, 11,
+  0, 0, 0, 0, 52, 56, 16, 0, 0, 0,
+  1, 0, 7, 24, 39, 91, 4, 0, 0, 0,
+  0, 0, 11, 0, 10, 0, 0, 35, 51, 0,
+  0, 0, 24, 66, 70, 0, 17, 0, 20, 30,
+  0, 0, 12, 0, 0, 0, 2, 79, 18, 0,
+  26, 23, 6, 5, 29, 52, 17, 15, 0, 0,
+  8, 29, 0, 0, 0, 9, 0, 47, 0, 0,
+  7, 43, 0, 12, 0, 10, 0, 0, 5, 0,
+  16, 5, 10, 0, 24, 4, 0, 0, 15, 0,
+  23, 37, 5, 0, 30, 16, 31, 0, 0, 12,
+  69, 32, 32, 66, 0, 18, 10, 0, 25, 0,
+  0, 55, 11, 6, 0, 12, 0, 37, 48, 12,
+  31, 65, 0, 0, 0, 0, 0, 0, 29, 0,
+  0, 17, 57, 30, 0, 27, 0, 0, 0, 60,
+  0, 14, 29, 64, 0, 0, 0, 1, 7, 52,
+  58, 0, 0, 0, 0, 32, 0, 0, 0, 19,
+  23, 49, 22, 3, 0, 0, 24, 14, 0, 0,
+  31, 13, 0, 23, 0, 61, 30, 0, 16, 46,
+  7, 38, 53, 0, 0, 0, 7, 20, 37, 0,
+  0, 0, 0, 0, 0, 35, 0, 0, 9, 0,
+  0, 0, 0, 3, 0, 3, 12, 0, 13, 5,
+  0, 0, 57, 0, 3, 0, 0, 0, 27, 17,
+  0, 0, 5, 8, 37, 0, 0, 0, 19, 60,
+  0, 39, 0, 33, 30, 0, 37, 12, 0, 30,
+  0, 10, 5, 30, 0, 0, 41, 0, 71, 36,
+  0, 13, 0, 0, 4, 0, 18, 0, 0, 16,
+  44, 2, 0, 26, 0, 0, 0, 38, 5, 6,
+  19, 51, 0, 0, 0, 14, 43, 20, 37, 0,
+  0, 0, 39, 13, 0, 0, 0, 39, 17, 0,
+  0, 40, 0, 0, 15, 0, 26, 0, 40, 45,
+  1, 0, 0, 24, 16, 54, 51, 59, 27, 8,
+  15, 0, 0, 41, 35, 63, 9, 78, 0, 0,
+  8, 0, 21, 0, 0, 0, 0, 0, 0, 35,
+  0, 0, 0, 0, 0, 0, 38, 0, 0, 5,
+  22, 8, 24, 27, 0, 0, 0, 65, 0, 36,
+  0, 0, 0, 33, 0, 2, 97, 14, 35, 0,
+  0, 0, 20, 36, 43, 5, 0, 0, 0, 9,
+  52, 53, 0, 20, 31, 37, 0, 46, 33, 0,
+  42, 41, 0, 48, 0, 0, 2, 16, 45, 62,
+  0, 0, 12, 0, 34, 0, 0, 17, 24, 34,
+  0, 27, 0, 0, 25, 0, 0, 14, 10, 0,
+  0, 8, 110, 0, 42, 0, 17, 9, 0, 44,
+  12, 0, 11, 0, 23, 0, 54, 79, 0, 0,
+  0, 0, 3, 53, 49, 60, 36, 23, 0, 0,
+  0, 42, 29, 49, 27, 93, 0, 0, 15, 0,
+  15, 0, 0, 0, 0, 32, 0, 20, 0, 0,
+  0, 0, 0, 7, 42, 0, 0, 5, 12, 12,
+  37, 19, 0, 0, 0, 60, 0, 25, 1, 12,
+  0, 29, 0, 0, 86, 0, 36, 9, 0, 0,
+  13, 38, 43, 13, 0, 16, 0, 0, 60, 35,
+  0, 10, 27, 23, 0, 45, 43, 0, 17, 49,
+  0, 42, 0, 0, 4, 7, 24, 57, 0, 0,
+  23, 0, 36, 0, 0, 1, 19, 59, 0, 22,
+  0, 0, 36, 0, 0, 24, 28, 0, 1, 18,
+  93, 0, 22, 0, 42, 20, 0, 38, 33, 0,
+  0, 0, 27, 0, 63, 89, 0, 12, 0, 0,
+  14, 41, 49, 72, 30, 11, 0, 0, 0, 57,
+  37, 23, 43, 98, 0, 0, 23, 0, 9, 0,
+  0, 0, 0, 70, 0, 0, 14, 15, 16, 0,
+  0, 17, 24, 0, 0, 0, 12, 0, 48, 0,
+  0, 0, 0, 33, 0, 3, 10, 18, 0, 50,
+  0, 0, 81, 0, 15, 42, 0, 0, 7, 44,
+  23, 12, 4, 28, 0, 0, 63, 33, 2, 27,
+  31, 25, 2, 25, 25, 0, 0, 46, 0, 33,
+  0, 0, 0, 14, 0, 51, 3, 0, 8, 0,
+  41, 0, 0, 18, 2, 64, 10, 19, 0, 0,
+  55, 0, 0, 23, 45, 0, 7, 3, 63, 0,
+  0, 0, 78, 18, 12, 0, 30, 0, 18, 0,
+  0, 0, 37, 30, 0, 0, 4, 71, 11, 0,
+  44, 48, 26, 0, 25, 1, 22, 8, 0, 6,
+  34, 49, 0, 0, 16, 0, 0, 5, 0, 0,
+  40, 32, 0, 1, 1, 0, 0, 0, 0, 0,
+  9, 0, 0, 0, 31, 0, 0, 10, 0, 0,
+  0, 51, 0, 0, 2, 6, 23, 5, 0, 0,
+  106, 5, 12, 82, 0, 0, 6, 39, 0, 0,
+  0, 50, 1, 0, 0, 34, 0, 54, 42, 31,
+  0, 69, 0, 0, 0, 56, 0, 0, 20, 0,
+  0, 15, 19, 45, 10, 6, 0, 0, 0, 0,
+  0, 21, 1, 57, 6, 0, 0, 0, 53, 11,
+  0, 0, 15, 0, 0, 26, 8, 0, 0, 12,
+  42, 48, 16, 0, 43, 0, 0, 0, 0, 0,
+  40, 54, 0, 16, 0, 59, 14, 0, 21, 57,
+  23, 17, 21, 14, 54, 0, 0, 0, 42, 21,
+  0, 0, 0, 0, 0, 0, 0, 0, 54, 47,
+  0, 0, 9, 0, 0, 0, 0, 0, 9, 0,
+  0, 0, 23, 0, 0, 0, 10, 0, 8, 40,
+  0, 0, 0, 25, 50, 0, 59, 21, 36, 7,
+  0, 114, 0, 9, 8, 6, 0, 0, 4, 34,
+  0, 0, 0, 19, 0, 29, 42, 2, 22, 44,
+  6, 0, 0, 57, 0, 0, 19, 0, 0, 0,
+  14, 17, 24, 0, 0, 0, 0, 0, 0, 0,
+  0, 39, 0, 0, 0, 0, 81, 4, 14, 0,
+  20, 0, 0, 18, 0, 0, 0, 19, 37, 4,
+  30, 0, 21, 8, 18, 0, 0, 0, 23, 36,
+  0, 0, 0, 54, 7, 0, 0, 65, 15, 16,
+  55, 1, 62, 10, 0, 0, 52, 0, 0, 0,
+  14, 0, 0, 0, 0, 0, 9, 33, 0, 0,
+  29, 0, 0, 9, 0, 0, 15, 0, 0, 0,
+  30, 30, 0, 0, 29, 0, 20, 15, 0, 0,
+  0, 14, 64, 0, 89, 22, 8, 0, 0, 130,
+  0, 14, 8, 0, 2, 0, 14, 22, 0, 0,
+  24, 0, 8, 22, 41, 0, 39, 0, 26, 0,
+  0, 30, 15, 0, 0, 0, 0, 0, 23, 0,
+  15, 0, 0, 0, 0, 0, 0, 32, 0, 10,
+  0, 9, 0, 0, 99, 17, 35, 0, 24, 0,
+  6, 0, 0, 0, 0, 31, 25, 0, 70, 0,
+  17, 0, 20, 30, 0, 0, 12, 0, 0, 0,
+  2, 79, 18, 0, 26, 23, 6, 5, 29, 52,
+  17, 15, 0, 0, 8, 29, 0, 0, 0, 9,
+  0, 47, 0, 0, 7, 43, 0, 12, 0, 10,
+  0, 0, 5, 0, 16, 5, 10, 0, 24, 4,
+  0, 0, 15, 0, 23, 37, 5, 0, 30, 16,
+  31, 0, 0, 12, 69, 32, 32, 66, 0, 18,
+  10, 0, 25, 0, 0, 55, 11, 6, 0, 12,
+  0, 37, 48, 12, 31, 65, 0, 0, 0, 0,
+  0, 0, 29, 0, 0, 17, 57, 30, 0, 27,
+  0, 0, 0, 60, 0, 14, 29, 64, 0, 0,
+  0, 1, 7, 52, 58, 0, 0, 0, 0, 32,
+  0, 0, 0, 19, 23, 49, 22, 3, 0, 0,
+  24, 14, 0, 0, 31, 13, 0, 23, 0, 61,
+  30, 0, 16, 46, 7, 38, 53, 0, 0, 0,
+  7, 20, 37, 0, 0, 0, 0, 0, 0, 35,
+  0, 0, 9, 0, 0, 0, 0, 3, 0, 3,
+  12, 0, 13, 5, 0, 0, 57, 0, 3, 0,
+  0, 0, 27, 17, 0, 0, 5, 8, 37, 0,
+  0, 0, 19, 60, 0, 39, 0, 33, 30, 0,
+  37, 12, 0, 30, 0, 10, 5, 30, 0, 0,
+  41, 0, 71, 36, 0, 13, 0, 0, 4, 0,
+  18, 0, 0, 16, 44, 2, 0, 26, 0, 0,
+  0, 38, 5, 6, 19, 51, 0, 0, 0, 14,
+  43, 20, 37, 0, 0, 0, 39, 13, 0, 0,
+  0, 39, 17, 0, 19, 51, 0, 11, 63, 0,
+  36, 0, 33, 2, 0, 24, 2, 46, 28, 0,
+  6, 25, 11, 52, 60, 0, 0, 15, 21, 37,
+  39, 0, 0, 21, 42, 0, 0, 33, 0, 0,
+  0, 0, 0, 0, 0, 29, 0, 51, 23, 0,
+  7, 28, 0, 0, 51, 0, 37, 15, 0, 12,
+  5, 0, 0, 22, 16, 2, 15, 0, 0, 0,
+  4, 57, 0, 0, 0, 41, 5, 0, 60, 0,
+  19, 1, 4, 1, 52, 31, 4, 0, 58, 0,
+  51, 26, 21, 39, 0, 0, 0, 32, 0, 23,
+  0, 0, 55, 8, 0, 36, 1, 0, 0, 0,
+  14, 29, 63, 36, 0, 0, 0, 0, 46, 0,
+  12, 0, 4, 0, 35, 1, 40, 0, 0, 33,
+  0, 0, 0, 44, 12, 0, 11, 0, 23, 0,
+  54, 79, 0, 0, 0, 0, 3, 53, 49, 60,
+  36, 23, 0, 0, 0, 42, 29, 49, 27, 93,
+  0, 0, 15, 0, 15, 0, 0, 0, 0, 32,
+  0, 20, 0, 0, 0, 0, 0, 7, 42, 0,
+  0, 5, 12, 12, 37, 19, 0, 0, 0, 60,
+  0, 25, 1, 12, 0, 29, 0, 0, 86, 0,
+  36, 9, 0, 0, 13, 38, 43, 13, 0, 16,
+  0, 0, 60, 35, 0, 10, 27, 23, 0, 45,
+  43, 0, 17, 49, 0, 42, 0, 0, 4, 7,
+  24, 57, 0, 0, 23, 0, 36, 0, 0, 1,
+  19, 59, 0, 22, 0, 0, 36, 0, 0, 24,
+  28, 0, 1, 18, 93, 0, 22, 0, 42, 20,
+  0, 38, 33, 0, 0, 0, 27, 0, 63, 89,
+  0, 12, 0, 0, 14, 41, 49, 72, 30, 11,
+  0, 0, 0, 57, 37, 23, 43, 98, 0, 0,
+  23, 0, 9, 0, 0, 0, 0, 70, 0, 0,
+  14, 15, 16, 0, 0, 17, 24, 0, 0, 0,
+  12, 0, 48, 0, 0, 0, 0, 33, 0, 3,
+  10, 18, 0, 50, 0, 0, 81, 0, 15, 42,
+  0, 0, 7, 44, 23, 12, 4, 28, 0, 0,
+  63, 33, 2, 27, 31, 25, 2, 25, 25, 0,
+  0, 46, 0, 33, 0, 0, 0, 14, 0, 51,
+  3, 0, 8, 0, 41, 0, 0, 18, 2, 64,
+  10, 19, 0, 0, 55, 0, 0, 23, 45, 0,
+  7, 3, 63, 0, 0, 0, 78, 18, 0, 39,
+  39, 0, 0, 0, 25, 0, 78, 78, 0, 0,
+  0, 3, 0, 17, 3, 41, 11, 0, 0, 0,
+  16, 61, 36, 0, 50, 80, 0, 0, 9, 0,
+  0, 0, 0, 0, 16, 73, 0, 0, 40, 8,
+  4, 0, 0, 14, 31, 0, 0, 0, 18, 0,
+  26, 0, 2, 0, 24, 52, 0, 0, 0, 48,
+  0, 57, 2, 2, 88, 0, 14, 69, 0, 0,
+  2, 41, 6, 46, 1, 15, 0, 0, 48, 46,
+  0, 40, 32, 26, 15, 28, 27, 0, 0, 65,
+  0, 8, 0, 0, 0, 0, 0, 52, 25, 0,
+  0, 0, 32, 0, 0, 39, 0, 43, 11, 0,
+  0, 0, 70, 0, 0, 25, 54, 0, 0, 0,
+  11, 0, 0, 0, 64, 2, 16, 0, 43, 0,
+  0, 0, 0, 0, 40, 54, 0, 16, 0, 59,
+  14, 0, 21, 57, 23, 17, 21, 14, 54, 0,
+  0, 0, 42, 21, 0, 0, 0, 0, 0, 0,
+  0, 0, 54, 47, 0, 0, 9, 0, 0, 0,
+  0, 0, 9, 0, 0, 0, 23, 0, 0, 0,
+  10, 0, 8, 40, 0, 0, 0, 25, 50, 0,
+  59, 21, 36, 7, 0, 114, 0, 9, 8, 6,
+  0, 0, 4, 34, 0, 0, 0, 19, 0, 29,
+  42, 2, 22, 44, 6, 0, 0, 57, 0, 0,
+  19, 0, 0, 0, 14, 17, 24, 0, 0, 0,
+  0, 0, 0, 0, 0, 39, 0, 0, 0, 0,
+  81, 4, 14, 0, 20, 0, 0, 18, 0, 0,
+  0, 19, 37, 4, 30, 0, 21, 8, 18, 0,
+  0, 0, 23, 36, 0, 0, 0, 54, 7, 0,
+  0, 65, 15, 16, 55, 1, 62, 10, 0, 0,
+  52, 0, 0, 0, 14, 0, 0, 0, 0, 0,
+  9, 33, 0, 0, 29, 0, 0, 9, 0, 0,
+  15, 0, 0, 0, 30, 30, 0, 0, 29, 0,
+  20, 15, 0, 0, 0, 14, 64, 0, 89, 22,
+  8, 0, 0, 130, 0, 14, 8, 0, 2, 0,
+  14, 22, 0, 0, 24, 0, 8, 22, 41, 0,
+  39, 0, 26, 0, 0, 30, 15, 0, 0, 0,
+  0, 0, 23, 0, 15, 0, 0, 0, 0, 0,
+  0, 32, 0, 10, 0, 9, 0, 0, 99, 17,
+  35, 0, 24, 0, 6, 0, 0, 0, 0, 31,
+  25, 0, 5, 13, 0, 32, 19, 0, 8, 0,
+  42, 4, 0, 13, 0, 36, 0, 0, 0, 57,
+  0, 20, 78, 0, 62, 17, 0, 0, 48, 0,
+  0, 0, 23, 0, 0, 0, 0, 0, 0, 22,
+  0, 0, 41, 0, 0, 33, 9, 0, 6, 0,
+  0, 0, 32, 6, 0, 0, 33, 0, 37, 0,
+  4, 0, 0, 39, 62, 0, 84, 8, 32, 22,
+  0, 130, 0, 9, 16, 0, 0, 9, 33, 13,
+  0, 0, 29, 13, 0, 22, 32, 0, 33, 0,
+  24, 0, 0, 28, 10, 0, 0, 0, 8, 0,
+  32, 0, 10, 12, 0, 0, 0, 0, 0, 83,
+  0, 0, 2, 0, 0, 0, 98, 36, 46, 0,
+  18, 0, 8, 0, 0, 0, 0, 28, 8, 0,
+  22, 3, 0, 0, 24, 14, 0, 0, 31, 13,
+  0, 23, 0, 61, 30, 0, 16, 46, 7, 38,
+  53, 0, 0, 0, 7, 20, 37, 0, 0, 0,
+  0, 0, 0, 35, 0, 0, 9, 0, 0, 0,
+  0, 3, 0, 3, 12, 0, 13, 5, 0, 0,
+  57, 0, 3, 0, 0, 0, 27, 17, 0, 0,
+  5, 8, 37, 0, 0, 0, 19, 60, 0, 39,
+  0, 33, 30, 0, 37, 12, 0, 30, 0, 10,
+  5, 30, 0, 0, 41, 0, 71, 36, 0, 13,
+  0, 0, 4, 0, 18, 0, 0, 16, 44, 2,
+  0, 26, 0, 0, 0, 38, 5, 6, 19, 51,
+  0, 0, 0, 14, 43, 20, 37, 0, 0, 0,
+  39, 13, 0, 0, 0, 39, 17, 0, 19, 51,
+  0, 11, 63, 0, 36, 0, 33, 2, 0, 24,
+  2, 46, 28, 0, 6, 25, 11, 52, 60, 0,
+  0, 15, 21, 37, 39, 0, 0, 21, 42, 0,
+  0, 33, 0, 0, 0, 0, 0, 0, 0, 29,
+  0, 51, 23, 0, 7, 28, 0, 0, 51, 0,
+  37, 15, 0, 12, 5, 0, 0, 22, 16, 2,
+  15, 0, 0, 0, 4, 57, 0, 0, 0, 41,
+  5, 0, 60, 0, 19, 1, 4, 1, 52, 31,
+  4, 0, 58, 0, 51, 26, 21, 39, 0, 0,
+  0, 32, 0, 23, 0, 0, 55, 8, 0, 36,
+  1, 0, 0, 0, 14, 29, 63, 36, 0, 0,
+  0, 0, 46, 0, 12, 0, 4, 0, 35, 1,
+  40, 0, 0, 33, 0, 0, 0, 99, 0, 38,
+  55, 0, 74, 0, 47, 0, 0, 55, 43, 30,
+  27, 0, 3, 36, 0, 59, 80, 0, 0, 26,
+  36, 49, 32, 1, 0, 12, 51, 0, 22, 17,
+  3, 0, 0, 0, 0, 0, 0, 20, 0, 83,
+  20, 23, 0, 15, 0, 0, 26, 0, 67, 45,
+  0, 11, 23, 0, 0, 37, 22, 0, 0, 0,
+  0, 0, 14, 67, 0, 0, 0, 11, 0, 0,
+  67, 0, 16, 0, 7, 0, 80, 54, 0, 0,
+  42, 0, 37, 1, 24, 67, 6, 0, 0, 40,
+  0, 45, 0, 0, 77, 8, 0, 34, 3, 0,
+  0, 0, 25, 58, 103, 36, 0, 0, 0, 0,
+  32, 0, 0, 0, 0, 0, 21, 22, 80, 0,
+  38, 25, 8, 0, 0, 38, 33, 0, 0, 0,
+  27, 0, 63, 89, 0, 12, 0, 0, 14, 41,
+  49, 72, 30, 11, 0, 0, 0, 57, 37, 23,
+  43, 98, 0, 0, 23, 0, 9, 0, 0, 0,
+  0, 70, 0, 0, 14, 15, 16, 0, 0, 17,
+  24, 0, 0, 0, 12, 0, 48, 0, 0, 0,
+  0, 33, 0, 3, 10, 18, 0, 50, 0, 0,
+  81, 0, 15, 42, 0, 0, 7, 44, 23, 12,
+  4, 28, 0, 0, 63, 33, 2, 27, 31, 25,
+  2, 25, 25, 0, 0, 46, 0, 33, 0, 0,
+  0, 14, 0, 51, 3, 0, 8, 0, 41, 0,
+  0, 18, 2, 64, 10, 19, 0, 0, 55, 0,
+  0, 23, 45, 0, 7, 3, 63, 0, 0, 0,
+  78, 18, 0, 39, 39, 0, 0, 0, 25, 0,
+  78, 78, 0, 0, 0, 3, 0, 17, 3, 41,
+  11, 0, 0, 0, 16, 61, 36, 0, 50, 80,
+  0, 0, 9, 0, 0, 0, 0, 0, 16, 73,
+  0, 0, 40, 8, 4, 0, 0, 14, 31, 0,
+  0, 0, 18, 0, 26, 0, 2, 0, 24, 52,
+  0, 0, 0, 48, 0, 57, 2, 2, 88, 0,
+  14, 69, 0, 0, 2, 41, 6, 46, 1, 15,
+  0, 0, 48, 46, 0, 40, 32, 26, 15, 28,
+  27, 0, 0, 65, 0, 8, 0, 0, 0, 0,
+  0, 52, 25, 0, 0, 0, 32, 0, 0, 39,
+  0, 43, 11, 0, 0, 0, 70, 0, 0, 25,
+  54, 0, 0, 0, 11, 0, 0, 0, 64, 2,
+  0, 29, 0, 0, 0, 0, 15, 0, 80, 38,
+  0, 0, 0, 0, 0, 0, 0, 35, 26, 0,
+  14, 0, 0, 45, 31, 0, 42, 64, 0, 0,
+  16, 0, 0, 5, 0, 0, 32, 60, 1, 0,
+  52, 0, 0, 0, 0, 15, 40, 0, 0, 0,
+  0, 2, 11, 0, 19, 50, 26, 49, 0, 0,
+  6, 43, 3, 66, 19, 0, 76, 0, 18, 84,
+  0, 0, 2, 19, 0, 39, 0, 5, 14, 0,
+  39, 27, 3, 12, 27, 17, 21, 31, 23, 0,
+  0, 98, 2, 0, 0, 0, 0, 0, 39, 39,
+  30, 37, 0, 0, 15, 0, 0, 33, 0, 44,
+  1, 9, 0, 0, 55, 0, 0, 24, 71, 0,
+  0, 0, 0, 0, 0, 0, 42, 0, 30, 0,
+  21, 8, 18, 0, 0, 0, 23, 36, 0, 0,
+  0, 54, 7, 0, 0, 65, 15, 16, 55, 1,
+  62, 10, 0, 0, 52, 0, 0, 0, 14, 0,
+  0, 0, 0, 0, 9, 33, 0, 0, 29, 0,
+  0, 9, 0, 0, 15, 0, 0, 0, 30, 30,
+  0, 0, 29, 0, 20, 15, 0, 0, 0, 14,
+  64, 0, 89, 22, 8, 0, 0, 130, 0, 14,
+  8, 0, 2, 0, 14, 22, 0, 0, 24, 0,
+  8, 22, 41, 0, 39, 0, 26, 0, 0, 30,
+  15, 0, 0, 0, 0, 0, 23, 0, 15, 0,
+  0, 0, 0, 0, 0, 32, 0, 10, 0, 9,
+  0, 0, 99, 17, 35, 0, 24, 0, 6, 0,
+  0, 0, 0, 31, 25, 0, 5, 13, 0, 32,
+  19, 0, 8, 0, 42, 4, 0, 13, 0, 36,
+  0, 0, 0, 57, 0, 20, 78, 0, 62, 17,
+  0, 0, 48, 0, 0, 0, 23, 0, 0, 0,
+  0, 0, 0, 22, 0, 0, 41, 0, 0, 33,
+  9, 0, 6, 0, 0, 0, 32, 6, 0, 0,
+  33, 0, 37, 0, 4, 0, 0, 39, 62, 0,
+  84, 8, 32, 22, 0, 130, 0, 9, 16, 0,
+  0, 9, 33, 13, 0, 0, 29, 13, 0, 22,
+  32, 0, 33, 0, 24, 0, 0, 28, 10, 0,
+  0, 0, 8, 0, 32, 0, 10, 12, 0, 0,
+  0, 0, 0, 83, 0, 0, 2, 0, 0, 0,
+  98, 36, 46, 0, 18, 0, 8, 0, 0, 0,
+  0, 28, 8, 0, 11, 29, 0, 45, 2, 0,
+  17, 0, 59, 0, 0, 24, 0, 0, 0, 0,
+  0, 40, 1, 11, 70, 0, 8, 10, 0, 0,
+  32, 0, 0, 0, 26, 22, 0, 7, 0, 0,
+  17, 26, 2, 0, 47, 0, 0, 21, 13, 9,
+  8, 0, 0, 0, 39, 2, 0, 18, 67, 54,
+  46, 0, 21, 0, 0, 41, 60, 20, 72, 13,
+  27, 31, 0, 123, 0, 13, 17, 0, 0, 28,
+  28, 13, 17, 0, 23, 19, 0, 3, 26, 0,
+  27, 0, 23, 0, 0, 39, 0, 0, 0, 3,
+  33, 0, 52, 9, 4, 75, 0, 0, 0, 0,
+  0, 100, 0, 0, 2, 0, 0, 11, 51, 34,
+  23, 0, 31, 0, 14, 0, 0, 0, 3, 31,
+  7, 0, 19, 51, 0, 11, 63, 0, 36, 0,
+  33, 2, 0, 24, 2, 46, 28, 0, 6, 25,
+  11, 52, 60, 0, 0, 15, 21, 37, 39, 0,
+  0, 21, 42, 0, 0, 33, 0, 0, 0, 0,
+  0, 0, 0, 29, 0, 51, 23, 0, 7, 28,
+  0, 0, 51, 0, 37, 15, 0, 12, 5, 0,
+  0, 22, 16, 2, 15, 0, 0, 0, 4, 57,
+  0, 0, 0, 41, 5, 0, 60, 0, 19, 1,
+  4, 1, 52, 31, 4, 0, 58, 0, 51, 26,
+  21, 39, 0, 0, 0, 32, 0, 23, 0, 0,
+  55, 8, 0, 36, 1, 0, 0, 0, 14, 29,
+  63, 36, 0, 0, 0, 0, 46, 0, 12, 0,
+  4, 0, 35, 1, 40, 0, 0, 33, 0, 0,
+  0, 99, 0, 38, 55, 0, 74, 0, 47, 0,
+  0, 55, 43, 30, 27, 0, 3, 36, 0, 59,
+  80, 0, 0, 26, 36, 49, 32, 1, 0, 12,
+  51, 0, 22, 17, 3, 0, 0, 0, 0, 0,
+  0, 20, 0, 83, 20, 23, 0, 15, 0, 0,
+  26, 0, 67, 45, 0, 11, 23, 0, 0, 37,
+  22, 0, 0, 0, 0, 0, 14, 67, 0, 0,
+  0, 11, 0, 0, 67, 0, 16, 0, 7, 0,
+  80, 54, 0, 0, 42, 0, 37, 1, 24, 67,
+  6, 0, 0, 40, 0, 45, 0, 0, 77, 8,
+  0, 34, 3, 0, 0, 0, 25, 58, 103, 36,
+  0, 0, 0, 0, 32, 0, 0, 0, 0, 0,
+  21, 22, 80, 0, 38, 25, 8, 0, 0, 129,
+  0, 59, 30, 0, 80, 0, 63, 0, 2, 62,
+  41, 13, 24, 8, 0, 36, 0, 50, 73, 0,
+  0, 34, 40, 69, 39, 5, 0, 13, 44, 0,
+  63, 0, 17, 0, 0, 0, 0, 0, 0, 30,
+  0, 55, 31, 26, 0, 15, 0, 0, 34, 0,
+  63, 66, 0, 6, 53, 0, 0, 76, 13, 0,
+  0, 0, 0, 0, 32, 81, 0, 0, 0, 20,
+  0, 0, 48, 49, 0, 0, 0, 0, 65, 72,
+  1, 0, 21, 0, 34, 0, 17, 106, 73, 0,
+  0, 66, 0, 33, 16, 0, 73, 22, 0, 27,
+  0, 0, 0, 0, 17, 70, 123, 31, 8, 0,
+  18, 0, 19, 0, 0, 0, 0, 0, 16, 21,
+  113, 10, 49, 16, 11, 0, 0, 39, 39, 0,
+  0, 0, 25, 0, 78, 78, 0, 0, 0, 3,
+  0, 17, 3, 41, 11, 0, 0, 0, 16, 61,
+  36, 0, 50, 80, 0, 0, 9, 0, 0, 0,
+  0, 0, 16, 73, 0, 0, 40, 8, 4, 0,
+  0, 14, 31, 0, 0, 0, 18, 0, 26, 0,
+  2, 0, 24, 52, 0, 0, 0, 48, 0, 57,
+  2, 2, 88, 0, 14, 69, 0, 0, 2, 41,
+  6, 46, 1, 15, 0, 0, 48, 46, 0, 40,
+  32, 26, 15, 28, 27, 0, 0, 65, 0, 8,
+  0, 0, 0, 0, 0, 52, 25, 0, 0, 0,
+  32, 0, 0, 39, 0, 43, 11, 0, 0, 0,
+  70, 0, 0, 25, 54, 0, 0, 0, 11, 0,
+  0, 0, 64, 2, 0, 29, 0, 0, 0, 0,
+  15, 0, 80, 38, 0, 0, 0, 0, 0, 0,
+  0, 35, 26, 0, 14, 0, 0, 45, 31, 0,
+  42, 64, 0, 0, 16, 0, 0, 5, 0, 0,
+  32, 60, 1, 0, 52, 0, 0, 0, 0, 15,
+  40, 0, 0, 0, 0, 2, 11, 0, 19, 50,
+  26, 49, 0, 0, 6, 43, 3, 66, 19, 0,
+  76, 0, 18, 84, 0, 0, 2, 19, 0, 39,
+  0, 5, 14, 0, 39, 27, 3, 12, 27, 17,
+  21, 31, 23, 0, 0, 98, 2, 0, 0, 0,
+  0, 0, 39, 39, 30, 37, 0, 0, 15, 0,
+  0, 33, 0, 44, 1, 9, 0, 0, 55, 0,
+  0, 24, 71, 0, 0, 0, 0, 0, 0, 0,
+  42, 0, 0, 21, 0, 0, 2, 0, 15, 0,
+  74, 29, 0, 18, 0, 12, 0, 34, 16, 63,
+  31, 0, 0, 0, 0, 43, 15, 0, 18, 55,
+  0, 0, 44, 0, 0, 15, 0, 0, 19, 53,
+  0, 0, 37, 0, 0, 0, 0, 6, 28, 0,
+  0, 0, 0, 19, 26, 0, 3, 71, 33, 50,
+  0, 0, 10, 18, 0, 54, 2, 0, 62, 0,
+  20, 53, 0, 0, 0, 10, 0, 34, 0, 0,
+  19, 0, 50, 13, 6, 0, 30, 11, 7, 22,
+  34, 0, 0, 109, 0, 6, 0, 0, 0, 0,
+  36, 46, 17, 32, 7, 0, 17, 0, 0, 18,
+  0, 40, 0, 25, 0, 9, 51, 0, 0, 9,
+  68, 0, 0, 9, 34, 0, 14, 0, 50, 0,
+  5, 13, 0, 32, 19, 0, 8, 0, 42, 4,
+  0, 13, 0, 36, 0, 0, 0, 57, 0, 20,
+  78, 0, 62, 17, 0, 0, 48, 0, 0, 0,
+  23, 0, 0, 0, 0, 0, 0, 22, 0, 0,
+  41, 0, 0, 33, 9, 0, 6, 0, 0, 0,
+  32, 6, 0, 0, 33, 0, 37, 0, 4, 0,
+  0, 39, 62, 0, 84, 8, 32, 22, 0, 130,
+  0, 9, 16, 0, 0, 9, 33, 13, 0, 0,
+  29, 13, 0, 22, 32, 0, 33, 0, 24, 0,
+  0, 28, 10, 0, 0, 0, 8, 0, 32, 0,
+  10, 12, 0, 0, 0, 0, 0, 83, 0, 0,
+  2, 0, 0, 0, 98, 36, 46, 0, 18, 0,
+  8, 0, 0, 0, 0, 28, 8, 0, 11, 29,
+  0, 45, 2, 0, 17, 0, 59, 0, 0, 24,
+  0, 0, 0, 0, 0, 40, 1, 11, 70, 0,
+  8, 10, 0, 0, 32, 0, 0, 0, 26, 22,
+  0, 7, 0, 0, 17, 26, 2, 0, 47, 0,
+  0, 21, 13, 9, 8, 0, 0, 0, 39, 2,
+  0, 18, 67, 54, 46, 0, 21, 0, 0, 41,
+  60, 20, 72, 13, 27, 31, 0, 123, 0, 13,
+  17, 0, 0, 28, 28, 13, 17, 0, 23, 19,
+  0, 3, 26, 0, 27, 0, 23, 0, 0, 39,
+  0, 0, 0, 3, 33, 0, 52, 9, 4, 75,
+  0, 0, 0, 0, 0, 100, 0, 0, 2, 0,
+  0, 11, 51, 34, 23, 0, 31, 0, 14, 0,
+  0, 0, 3, 31, 7, 0, 11, 24, 0, 20,
+  0, 8, 0, 0, 72, 0, 0, 35, 0, 0,
+  0, 0, 0, 45, 6, 0, 35, 11, 0, 11,
+  0, 0, 13, 0, 0, 0, 2, 13, 0, 0,
+  0, 0, 29, 44, 34, 0, 50, 0, 0, 11,
+  0, 7, 0, 0, 0, 0, 8, 60, 0, 0,
+  108, 136, 34, 5, 37, 0, 0, 24, 71, 27,
+  134, 39, 0, 0, 0, 158, 66, 0, 9, 0,
+  0, 10, 0, 0, 39, 0, 9, 0, 13, 5,
+  9, 0, 4, 0, 70, 0, 0, 80, 0, 0,
+  27, 0, 26, 0, 39, 45, 33, 130, 0, 0,
+  0, 0, 0, 84, 0, 0, 0, 0, 0, 24,
+  23, 13, 0, 0, 36, 0, 0, 0, 0, 0,
+  23, 31, 12, 0, 0, 99, 0, 38, 55, 0,
+  74, 0, 47, 0, 0, 55, 43, 30, 27, 0,
+  3, 36, 0, 59, 80, 0, 0, 26, 36, 49,
+  32, 1, 0, 12, 51, 0, 22, 17, 3, 0,
+  0, 0, 0, 0, 0, 20, 0, 83, 20, 23,
+  0, 15, 0, 0, 26, 0, 67, 45, 0, 11,
+  23, 0, 0, 37, 22, 0, 0, 0, 0, 0,
+  14, 67, 0, 0, 0, 11, 0, 0, 67, 0,
+  16, 0, 7, 0, 80, 54, 0, 0, 42, 0,
+  37, 1, 24, 67, 6, 0, 0, 40, 0, 45,
+  0, 0, 77, 8, 0, 34, 3, 0, 0, 0,
+  25, 58, 103, 36, 0, 0, 0, 0, 32, 0,
+  0, 0, 0, 0, 21, 22, 80, 0, 38, 25,
+  8, 0, 0, 129, 0, 59, 30, 0, 80, 0,
+  63, 0, 2, 62, 41, 13, 24, 8, 0, 36,
+  0, 50, 73, 0, 0, 34, 40, 69, 39, 5,
+  0, 13, 44, 0, 63, 0, 17, 0, 0, 0,
+  0, 0, 0, 30, 0, 55, 31, 26, 0, 15,
+  0, 0, 34, 0, 63, 66, 0, 6, 53, 0,
+  0, 76, 13, 0, 0, 0, 0, 0, 32, 81,
+  0, 0, 0, 20, 0, 0, 48, 49, 0, 0,
+  0, 0, 65, 72, 1, 0, 21, 0, 34, 0,
+  17, 106, 73, 0, 0, 66, 0, 33, 16, 0,
+  73, 22, 0, 27, 0, 0, 0, 0, 17, 70,
+  123, 31, 8, 0, 18, 0, 19, 0, 0, 0,
+  0, 0, 16, 21, 113, 10, 49, 16, 11, 0,
+  4, 112, 0, 54, 23, 0, 15, 0, 85, 7,
+  0, 53, 5, 3, 0, 0, 0, 18, 0, 13,
+  49, 0, 0, 31, 10, 11, 45, 17, 0, 0,
+  0, 9, 32, 0, 23, 0, 0, 18, 0, 0,
+  0, 0, 0, 18, 25, 27, 0, 0, 0, 0,
+  33, 14, 7, 64, 44, 38, 45, 0, 0, 10,
+  0, 11, 7, 12, 0, 7, 17, 45, 0, 29,
+  0, 13, 26, 0, 1, 55, 0, 8, 5, 0,
+  20, 44, 16, 23, 0, 0, 15, 29, 38, 55,
+  93, 0, 0, 17, 0, 0, 52, 0, 35, 52,
+  0, 80, 0, 0, 0, 0, 0, 84, 112, 0,
+  31, 0, 15, 3, 1, 0, 0, 0, 0, 0,
+  3, 0, 28, 0, 45, 32, 0, 0, 0, 29,
+  0, 0, 0, 0, 15, 0, 80, 38, 0, 0,
+  0, 0, 0, 0, 0, 35, 26, 0, 14, 0,
+  0, 45, 31, 0, 42, 64, 0, 0, 16, 0,
+  0, 5, 0, 0, 32, 60, 1, 0, 52, 0,
+  0, 0, 0, 15, 40, 0, 0, 0, 0, 2,
+  11, 0, 19, 50, 26, 49, 0, 0, 6, 43,
+  3, 66, 19, 0, 76, 0, 18, 84, 0, 0,
+  2, 19, 0, 39, 0, 5, 14, 0, 39, 27,
+  3, 12, 27, 17, 21, 31, 23, 0, 0, 98,
+  2, 0, 0, 0, 0, 0, 39, 39, 30, 37,
+  0, 0, 15, 0, 0, 33, 0, 44, 1, 9,
+  0, 0, 55, 0, 0, 24, 71, 0, 0, 0,
+  0, 0, 0, 0, 42, 0, 0, 21, 0, 0,
+  2, 0, 15, 0, 74, 29, 0, 18, 0, 12,
+  0, 34, 16, 63, 31, 0, 0, 0, 0, 43,
+  15, 0, 18, 55, 0, 0, 44, 0, 0, 15,
+  0, 0, 19, 53, 0, 0, 37, 0, 0, 0,
+  0, 6, 28, 0, 0, 0, 0, 19, 26, 0,
+  3, 71, 33, 50, 0, 0, 10, 18, 0, 54,
+  2, 0, 62, 0, 20, 53, 0, 0, 0, 10,
+  0, 34, 0, 0, 19, 0, 50, 13, 6, 0,
+  30, 11, 7, 22, 34, 0, 0, 109, 0, 6,
+  0, 0, 0, 0, 36, 46, 17, 32, 7, 0,
+  17, 0, 0, 18, 0, 40, 0, 25, 0, 9,
+  51, 0, 0, 9, 68, 0, 0, 9, 34, 0,
+  14, 0, 50, 0, 0, 44, 0, 0, 11, 0,
+  30, 0, 44, 53, 0, 11, 18, 12, 0, 82,
+  51, 71, 16, 19, 0, 0, 0, 63, 28, 37,
+  0, 67, 2, 0, 45, 0, 33, 25, 0, 0,
+  0, 52, 0, 0, 18, 0, 13, 17, 0, 3,
+  20, 20, 0, 7, 2, 12, 49, 14, 0, 32,
+  19, 44, 0, 21, 12, 0, 0, 24, 0, 0,
+  80, 1, 40, 3, 0, 0, 8, 26, 18, 45,
+  0, 0, 0, 0, 87, 25, 0, 0, 27, 11,
+  0, 26, 28, 6, 18, 90, 0, 29, 0, 0,
+  0, 0, 0, 71, 9, 2, 14, 0, 37, 0,
+  0, 24, 1, 42, 0, 27, 0, 6, 32, 0,
+  0, 6, 43, 0, 9, 0, 103, 0, 43, 0,
+  51, 0, 11, 29, 0, 45, 2, 0, 17, 0,
+  59, 0, 0, 24, 0, 0, 0, 0, 0, 40,
+  1, 11, 70, 0, 8, 10, 0, 0, 32, 0,
+  0, 0, 26, 22, 0, 7, 0, 0, 17, 26,
+  2, 0, 47, 0, 0, 21, 13, 9, 8, 0,
+  0, 0, 39, 2, 0, 18, 67, 54, 46, 0,
+  21, 0, 0, 41, 60, 20, 72, 13, 27, 31,
+  0, 123, 0, 13, 17, 0, 0, 28, 28, 13,
+  17, 0, 23, 19, 0, 3, 26, 0, 27, 0,
+  23, 0, 0, 39, 0, 0, 0, 3, 33, 0,
+  52, 9, 4, 75, 0, 0, 0, 0, 0, 100,
+  0, 0, 2, 0, 0, 11, 51, 34, 23, 0,
+  31, 0, 14, 0, 0, 0, 3, 31, 7, 0,
+  11, 24, 0, 20, 0, 8, 0, 0, 72, 0,
+  0, 35, 0, 0, 0, 0, 0, 45, 6, 0,
+  35, 11, 0, 11, 0, 0, 13, 0, 0, 0,
+  2, 13, 0, 0, 0, 0, 29, 44, 34, 0,
+  50, 0, 0, 11, 0, 7, 0, 0, 0, 0,
+  8, 60, 0, 0, 108, 136, 34, 5, 37, 0,
+  0, 24, 71, 27, 134, 39, 0, 0, 0, 158,
+  66, 0, 9, 0, 0, 10, 0, 0, 39, 0,
+  9, 0, 13, 5, 9, 0, 4, 0, 70, 0,
+  0, 80, 0, 0, 27, 0, 26, 0, 39, 45,
+  33, 130, 0, 0, 0, 0, 0, 84, 0, 0,
+  0, 0, 0, 24, 23, 13, 0, 0, 36, 0,
+  0, 0, 0, 0, 23, 31, 12, 0, 0, 15,
+  0, 0, 0, 50, 0, 0, 53, 14, 0, 2,
+  0, 0, 0, 0, 0, 48, 12, 0, 0, 0,
+  0, 19, 0, 0, 0, 3, 0, 0, 3, 11,
+  0, 0, 0, 9, 43, 82, 35, 0, 70, 0,
+  5, 16, 0, 7, 7, 0, 0, 0, 0, 63,
+  0, 0, 57, 160, 47, 9, 35, 0, 0, 29,
+  57, 0, 153, 4, 0, 0, 0, 121, 122, 0,
+  14, 27, 0, 33, 0, 0, 46, 0, 6, 0,
+  5, 13, 16, 0, 0, 10, 64, 0, 0, 128,
+  0, 0, 35, 0, 0, 0, 10, 76, 58, 96,
+  0, 0, 0, 0, 0, 62, 0, 0, 0, 3,
+  0, 35, 0, 0, 0, 0, 53, 0, 0, 0,
+  0, 0, 18, 28, 29, 0, 0, 129, 0, 59,
+  30, 0, 80, 0, 63, 0, 2, 62, 41, 13,
+  24, 8, 0, 36, 0, 50, 73, 0, 0, 34,
+  40, 69, 39, 5, 0, 13, 44, 0, 63, 0,
+  17, 0, 0, 0, 0, 0, 0, 30, 0, 55,
+  31, 26, 0, 15, 0, 0, 34, 0, 63, 66,
+  0, 6, 53, 0, 0, 76, 13, 0, 0, 0,
+  0, 0, 32, 81, 0, 0, 0, 20, 0, 0,
+  48, 49, 0, 0, 0, 0, 65, 72, 1, 0,
+  21, 0, 34, 0, 17, 106, 73, 0, 0, 66,
+  0, 33, 16, 0, 73, 22, 0, 27, 0, 0,
+  0, 0, 17, 70, 123, 31, 8, 0, 18, 0,
+  19, 0, 0, 0, 0, 0, 16, 21, 113, 10,
+  49, 16, 11, 0, 4, 112, 0, 54, 23, 0,
+  15, 0, 85, 7, 0, 53, 5, 3, 0, 0,
+  0, 18, 0, 13, 49, 0, 0, 31, 10, 11,
+  45, 17, 0, 0, 0, 9, 32, 0, 23, 0,
+  0, 18, 0, 0, 0, 0, 0, 18, 25, 27,
+  0, 0, 0, 0, 33, 14, 7, 64, 44, 38,
+  45, 0, 0, 10, 0, 11, 7, 12, 0, 7,
+  17, 45, 0, 29, 0, 13, 26, 0, 1, 55,
+  0, 8, 5, 0, 20, 44, 16, 23, 0, 0,
+  15, 29, 38, 55, 93, 0, 0, 17, 0, 0,
+  52, 0, 35, 52, 0, 80, 0, 0, 0, 0,
+  0, 84, 112, 0, 31, 0, 15, 3, 1, 0,
+  0, 0, 0, 0, 3, 0, 28, 0, 45, 32,
+  0, 0, 29, 57, 0, 24, 0, 27, 0, 0,
+  42, 0, 0, 31, 0, 13, 0, 0, 0, 38,
+  15, 0, 3, 20, 0, 0, 0, 0, 2, 0,
+  0, 0, 0, 33, 0, 0, 0, 22, 12, 36,
+  5, 0, 22, 0, 25, 16, 5, 0, 6, 0,
+  0, 0, 0, 74, 0, 26, 125, 100, 30, 22,
+  18, 0, 0, 43, 75, 37, 102, 36, 0, 20,
+  0, 109, 123, 3, 27, 0, 0, 17, 0, 0,
+  34, 0, 0, 1, 35, 33, 3, 0, 0, 8,
+  62, 0, 21, 30, 0, 0, 38, 0, 43, 0,
+  9, 59, 0, 117, 0, 0, 0, 0, 0, 80,
+  21, 0, 14, 0, 0, 24, 0, 0, 0, 0,
+  10, 0, 0, 0, 0, 0, 32, 35, 0, 0,
+  0, 21, 0, 0, 2, 0, 15, 0, 74, 29,
+  0, 18, 0, 12, 0, 34, 16, 63, 31, 0,
+  0, 0, 0, 43, 15, 0, 18, 55, 0, 0,
+  44, 0, 0, 15, 0, 0, 19, 53, 0, 0,
+  37, 0, 0, 0, 0, 6, 28, 0, 0, 0,
+  0, 19, 26, 0, 3, 71, 33, 50, 0, 0,
+  10, 18, 0, 54, 2, 0, 62, 0, 20, 53,
+  0, 0, 0, 10, 0, 34, 0, 0, 19, 0,
+  50, 13, 6, 0, 30, 11, 7, 22, 34, 0,
+  0, 109, 0, 6, 0, 0, 0, 0, 36, 46,
+  17, 32, 7, 0, 17, 0, 0, 18, 0, 40,
+  0, 25, 0, 9, 51, 0, 0, 9, 68, 0,
+  0, 9, 34, 0, 14, 0, 50, 0, 0, 44,
+  0, 0, 11, 0, 30, 0, 44, 53, 0, 11,
+  18, 12, 0, 82, 51, 71, 16, 19, 0, 0,
+  0, 63, 28, 37, 0, 67, 2, 0, 45, 0,
+  33, 25, 0, 0, 0, 52, 0, 0, 18, 0,
+  13, 17, 0, 3, 20, 20, 0, 7, 2, 12,
+  49, 14, 0, 32, 19, 44, 0, 21, 12, 0,
+  0, 24, 0, 0, 80, 1, 40, 3, 0, 0,
+  8, 26, 18, 45, 0, 0, 0, 0, 87, 25,
+  0, 0, 27, 11, 0, 26, 28, 6, 18, 90,
+  0, 29, 0, 0, 0, 0, 0, 71, 9, 2,
+  14, 0, 37, 0, 0, 24, 1, 42, 0, 27,
+  0, 6, 32, 0, 0, 6, 43, 0, 9, 0,
+  103, 0, 43, 0, 51, 0, 0, 102, 14, 0,
+  4, 0, 39, 0, 27, 51, 8, 13, 23, 3,
+  26, 91, 67, 61, 21, 56, 0, 0, 0, 56,
+  53, 69, 6, 74, 0, 0, 14, 0, 81, 1,
+  0, 0, 0, 25, 0, 38, 0, 16, 42, 22,
+  1, 7, 22, 19, 0, 49, 2, 1, 68, 52,
+  0, 0, 0, 9, 0, 50, 0, 0, 0, 0,
+  0, 0, 91, 11, 34, 0, 0, 0, 15, 26,
+  42, 23, 0, 6, 0, 4, 107, 11, 0, 0,
+  11, 8, 10, 15, 30, 12, 42, 45, 0, 41,
+  0, 10, 0, 0, 0, 81, 0, 0, 14, 0,
+  46, 0, 23, 15, 32, 37, 0, 0, 0, 0,
+  0, 0, 0, 0, 12, 0, 30, 11, 149, 0,
+  76, 0, 46, 0, 11, 24, 0, 20, 0, 8,
+  0, 0, 72, 0, 0, 35, 0, 0, 0, 0,
+  0, 45, 6, 0, 35, 11, 0, 11, 0, 0,
+  13, 0, 0, 0, 2, 13, 0, 0, 0, 0,
+  29, 44, 34, 0, 50, 0, 0, 11, 0, 7,
+  0, 0, 0, 0, 8, 60, 0, 0, 108, 136,
+  34, 5, 37, 0, 0, 24, 71, 27, 134, 39,
+  0, 0, 0, 158, 66, 0, 9, 0, 0, 10,
+  0, 0, 39, 0, 9, 0, 13, 5, 9, 0,
+  4, 0, 70, 0, 0, 80, 0, 0, 27, 0,
+  26, 0, 39, 45, 33, 130, 0, 0, 0, 0,
+  0, 84, 0, 0, 0, 0, 0, 24, 23, 13,
+  0, 0, 36, 0, 0, 0, 0, 0, 23, 31,
+  12, 0, 0, 15, 0, 0, 0, 50, 0, 0,
+  53, 14, 0, 2, 0, 0, 0, 0, 0, 48,
+  12, 0, 0, 0, 0, 19, 0, 0, 0, 3,
+  0, 0, 3, 11, 0, 0, 0, 9, 43, 82,
+  35, 0, 70, 0, 5, 16, 0, 7, 7, 0,
+  0, 0, 0, 63, 0, 0, 57, 160, 47, 9,
+  35, 0, 0, 29, 57, 0, 153, 4, 0, 0,
+  0, 121, 122, 0, 14, 27, 0, 33, 0, 0,
+  46, 0, 6, 0, 5, 13, 16, 0, 0, 10,
+  64, 0, 0, 128, 0, 0, 35, 0, 0, 0,
+  10, 76, 58, 96, 0, 0, 0, 0, 0, 62,
+  0, 0, 0, 3, 0, 35, 0, 0, 0, 0,
+  53, 0, 0, 0, 0, 0, 18, 28, 29, 0,
+  0, 39, 0, 0, 0, 29, 0, 0, 78, 47,
+  0, 0, 30, 0, 0, 88, 39, 61, 6, 17,
+  0, 0, 0, 41, 0, 0, 7, 53, 6, 0,
+  17, 0, 36, 0, 0, 0, 35, 96, 0, 0,
+  48, 0, 9, 30, 0, 28, 42, 19, 0, 0,
+  0, 32, 2, 0, 4, 101, 46, 8, 0, 0,
+  0, 0, 0, 0, 66, 0, 6, 4, 24, 53,
+  52, 0, 17, 37, 0, 49, 0, 0, 5, 0,
+  39, 0, 0, 0, 0, 1, 0, 30, 51, 0,
+  0, 131, 0, 0, 11, 0, 0, 0, 0, 86,
+  87, 31, 0, 0, 0, 0, 0, 48, 0, 13,
+  0, 11, 0, 8, 2, 0, 0, 2, 51, 0,
+  25, 0, 41, 0, 28, 12, 43, 0, 4, 112,
+  0, 54, 23, 0, 15, 0, 85, 7, 0, 53,
+  5, 3, 0, 0, 0, 18, 0, 13, 49, 0,
+  0, 31, 10, 11, 45, 17, 0, 0, 0, 9,
+  32, 0, 23, 0, 0, 18, 0, 0, 0, 0,
+  0, 18, 25, 27, 0, 0, 0, 0, 33, 14,
+  7, 64, 44, 38, 45, 0, 0, 10, 0, 11,
+  7, 12, 0, 7, 17, 45, 0, 29, 0, 13,
+  26, 0, 1, 55, 0, 8, 5, 0, 20, 44,
+  16, 23, 0, 0, 15, 29, 38, 55, 93, 0,
+  0, 17, 0, 0, 52, 0, 35, 52, 0, 80,
+  0, 0, 0, 0, 0, 84, 112, 0, 31, 0,
+  15, 3, 1, 0, 0, 0, 0, 0, 3, 0,
+  28, 0, 45, 32, 0, 0, 29, 57, 0, 24,
+  0, 27, 0, 0, 42, 0, 0, 31, 0, 13,
+  0, 0, 0, 38, 15, 0, 3, 20, 0, 0,
+  0, 0, 2, 0, 0, 0, 0, 33, 0, 0,
+  0, 22, 12, 36, 5, 0, 22, 0, 25, 16,
+  5, 0, 6, 0, 0, 0, 0, 74, 0, 26,
+  125, 100, 30, 22, 18, 0, 0, 43, 75, 37,
+  102, 36, 0, 20, 0, 109, 123, 3, 27, 0,
+  0, 17, 0, 0, 34, 0, 0, 1, 35, 33,
+  3, 0, 0, 8, 62, 0, 21, 30, 0, 0,
+  38, 0, 43, 0, 9, 59, 0, 117, 0, 0,
+  0, 0, 0, 80, 21, 0, 14, 0, 0, 24,
+  0, 0, 0, 0, 10, 0, 0, 0, 0, 0,
+  32, 35, 0, 0, 10, 25, 0, 0, 0, 85,
+  0, 0, 22, 0, 0, 0, 0, 0, 0, 0,
+  0, 39, 3, 8, 0, 40, 0, 0, 0, 0,
+  8, 3, 0, 0, 0, 38, 0, 0, 0, 43,
+  47, 68, 23, 0, 46, 0, 22, 15, 0, 13,
+  59, 13, 0, 0, 0, 55, 0, 0, 112, 118,
+  34, 26, 48, 0, 0, 57, 67, 0, 179, 5,
+  0, 32, 0, 139, 175, 0, 10, 15, 0, 0,
+  0, 0, 42, 0, 0, 0, 28, 19, 31, 0,
+  0, 11, 42, 0, 0, 116, 13, 0, 34, 0,
+  0, 0, 6, 54, 43, 142, 0, 0, 0, 0,
+  0, 58, 0, 0, 0, 29, 0, 30, 0, 10,
+  0, 0, 53, 0, 0, 0, 0, 0, 1, 29,
+  1, 6, 0, 44, 0, 0, 11, 0, 30, 0,
+  44, 53, 0, 11, 18, 12, 0, 82, 51, 71,
+  16, 19, 0, 0, 0, 63, 28, 37, 0, 67,
+  2, 0, 45, 0, 33, 25, 0, 0, 0, 52,
+  0, 0, 18, 0, 13, 17, 0, 3, 20, 20,
+  0, 7, 2, 12, 49, 14, 0, 32, 19, 44,
+  0, 21, 12, 0, 0, 24, 0, 0, 80, 1,
+  40, 3, 0, 0, 8, 26, 18, 45, 0, 0,
+  0, 0, 87, 25, 0, 0, 27, 11, 0, 26,
+  28, 6, 18, 90, 0, 29, 0, 0, 0, 0,
+  0, 71, 9, 2, 14, 0, 37, 0, 0, 24,
+  1, 42, 0, 27, 0, 6, 32, 0, 0, 6,
+  43, 0, 9, 0, 103, 0, 43, 0, 51, 0,
+  0, 102, 14, 0, 4, 0, 39, 0, 27, 51,
+  8, 13, 23, 3, 26, 91, 67, 61, 21, 56,
+  0, 0, 0, 56, 53, 69, 6, 74, 0, 0,
+  14, 0, 81, 1, 0, 0, 0, 25, 0, 38,
+  0, 16, 42, 22, 1, 7, 22, 19, 0, 49,
+  2, 1, 68, 52, 0, 0, 0, 9, 0, 50,
+  0, 0, 0, 0, 0, 0, 91, 11, 34, 0,
+  0, 0, 15, 26, 42, 23, 0, 6, 0, 4,
+  107, 11, 0, 0, 11, 8, 10, 15, 30, 12,
+  42, 45, 0, 41, 0, 10, 0, 0, 0, 81,
+  0, 0, 14, 0, 46, 0, 23, 15, 32, 37,
+  0, 0, 0, 0, 0, 0, 0, 0, 12, 0,
+  30, 11, 149, 0, 76, 0, 46, 0, 0, 131,
+  52, 5, 17, 0, 45, 0, 11, 44, 5, 23,
+  60, 0, 17, 55, 55, 49, 15, 72, 0, 0,
+  12, 32, 54, 53, 11, 54, 0, 20, 0, 0,
+  76, 0, 17, 0, 0, 0, 0, 41, 0, 25,
+  68, 41, 28, 22, 40, 0, 0, 52, 0, 3,
+  85, 24, 0, 0, 0, 0, 0, 44, 4, 0,
+  0, 5, 0, 0, 29, 13, 13, 0, 0, 0,
+  8, 16, 74, 5, 15, 32, 0, 0, 97, 0,
+  0, 0, 14, 0, 30, 16, 22, 9, 0, 0,
+  0, 20, 0, 26, 0, 0, 0, 38, 5, 16,
+  9, 0, 39, 0, 48, 8, 25, 53, 0, 0,
+  0, 5, 0, 0, 0, 24, 33, 0, 34, 5,
+  77, 0, 62, 0, 29, 0, 0, 15, 0, 0,
+  0, 50, 0, 0, 53, 14, 0, 2, 0, 0,
+  0, 0, 0, 48, 12, 0, 0, 0, 0, 19,
+  0, 0, 0, 3, 0, 0, 3, 11, 0, 0,
+  0, 9, 43, 82, 35, 0, 70, 0, 5, 16,
+  0, 7, 7, 0, 0, 0, 0, 63, 0, 0,
+  57, 160, 47, 9, 35, 0, 0, 29, 57, 0,
+  153, 4, 0, 0, 0, 121, 122, 0, 14, 27,
+  0, 33, 0, 0, 46, 0, 6, 0, 5, 13,
+  16, 0, 0, 10, 64, 0, 0, 128, 0, 0,
+  35, 0, 0, 0, 10, 76, 58, 96, 0, 0,
+  0, 0, 0, 62, 0, 0, 0, 3, 0, 35,
+  0, 0, 0, 0, 53, 0, 0, 0, 0, 0,
+  18, 28, 29, 0, 0, 39, 0, 0, 0, 29,
+  0, 0, 78, 47, 0, 0, 30, 0, 0, 88,
+  39, 61, 6, 17, 0, 0, 0, 41, 0, 0,
+  7, 53, 6, 0, 17, 0, 36, 0, 0, 0,
+  35, 96, 0, 0, 48, 0, 9, 30, 0, 28,
+  42, 19, 0, 0, 0, 32, 2, 0, 4, 101,
+  46, 8, 0, 0, 0, 0, 0, 0, 66, 0,
+  6, 4, 24, 53, 52, 0, 17, 37, 0, 49,
+  0, 0, 5, 0, 39, 0, 0, 0, 0, 1,
+  0, 30, 51, 0, 0, 131, 0, 0, 11, 0,
+  0, 0, 0, 86, 87, 31, 0, 0, 0, 0,
+  0, 48, 0, 13, 0, 11, 0, 8, 2, 0,
+  0, 2, 51, 0, 25, 0, 41, 0, 28, 12,
+  43, 0, 0, 93, 41, 0, 7, 0, 52, 3,
+  86, 40, 12, 0, 76, 3, 0, 125, 70, 39,
+  2, 33, 0, 0, 0, 54, 36, 13, 16, 61,
+  3, 0, 21, 0, 90, 1, 0, 0, 0, 58,
+  0, 29, 9, 0, 26, 52, 0, 59, 72, 36,
+  0, 44, 0, 0, 84, 12, 0, 0, 22, 0,
+  0, 42, 0, 0, 0, 0, 0, 0, 47, 0,
+  62, 0, 0, 0, 2, 50, 38, 28, 0, 0,
+  0, 0, 77, 11, 8, 0, 0, 21, 0, 22,
+  43, 0, 0, 57, 0, 32, 0, 0, 0, 0,
+  0, 79, 66, 0, 0, 0, 15, 0, 10, 29,
+  0, 69, 0, 1, 0, 0, 0, 0, 0, 36,
+  65, 0, 62, 0, 139, 0, 57, 16, 25, 0,
+  29, 57, 0, 24, 0, 27, 0, 0, 42, 0,
+  0, 31, 0, 13, 0, 0, 0, 38, 15, 0,
+  3, 20, 0, 0, 0, 0, 2, 0, 0, 0,
+  0, 33, 0, 0, 0, 22, 12, 36, 5, 0,
+  22, 0, 25, 16, 5, 0, 6, 0, 0, 0,
+  0, 74, 0, 26, 125, 100, 30, 22, 18, 0,
+  0, 43, 75, 37, 102, 36, 0, 20, 0, 109,
+  123, 3, 27, 0, 0, 17, 0, 0, 34, 0,
+  0, 1, 35, 33, 3, 0, 0, 8, 62, 0,
+  21, 30, 0, 0, 38, 0, 43, 0, 9, 59,
+  0, 117, 0, 0, 0, 0, 0, 80, 21, 0,
+  14, 0, 0, 24, 0, 0, 0, 0, 10, 0,
+  0, 0, 0, 0, 32, 35, 0, 0, 10, 25,
+  0, 0, 0, 85, 0, 0, 22, 0, 0, 0,
+  0, 0, 0, 0, 0, 39, 3, 8, 0, 40,
+  0, 0, 0, 0, 8, 3, 0, 0, 0, 38,
+  0, 0, 0, 43, 47, 68, 23, 0, 46, 0,
+  22, 15, 0, 13, 59, 13, 0, 0, 0, 55,
+  0, 0, 112, 118, 34, 26, 48, 0, 0, 57,
+  67, 0, 179, 5, 0, 32, 0, 139, 175, 0,
+  10, 15, 0, 0, 0, 0, 42, 0, 0, 0,
+  28, 19, 31, 0, 0, 11, 42, 0, 0, 116,
+  13, 0, 34, 0, 0, 0, 6, 54, 43, 142,
+  0, 0, 0, 0, 0, 58, 0, 0, 0, 29,
+  0, 30, 0, 10, 0, 0, 53, 0, 0, 0,
+  0, 0, 1, 29, 1, 6, 0, 37, 0, 0,
+  0, 81, 0, 0, 83, 32, 0, 0, 0, 9,
+  0, 42, 6, 26, 0, 10, 0, 0, 0, 25,
+  0, 0, 22, 40, 7, 0, 0, 0, 67, 0,
+  0, 20, 33, 86, 0, 0, 32, 0, 0, 10,
+  0, 67, 54, 81, 0, 26, 0, 6, 0, 0,
+  25, 36, 58, 0, 32, 0, 0, 65, 0, 0,
+  102, 0, 0, 34, 25, 57, 85, 0, 33, 59,
+  0, 79, 0, 0, 3, 0, 3, 0, 2, 0,
+  0, 0, 0, 49, 15, 0, 0, 173, 0, 0,
+  0, 0, 0, 0, 0, 64, 113, 110, 0, 0,
+  0, 0, 0, 29, 0, 22, 0, 30, 0, 19,
+  0, 0, 0, 29, 61, 0, 40, 0, 0, 0,
+  0, 15, 1, 35, 0, 102, 14, 0, 4, 0,
+  39, 0, 27, 51, 8, 13, 23, 3, 26, 91,
+  67, 61, 21, 56, 0, 0, 0, 56, 53, 69,
+  6, 74, 0, 0, 14, 0, 81, 1, 0, 0,
+  0, 25, 0, 38, 0, 16, 42, 22, 1, 7,
+  22, 19, 0, 49, 2, 1, 68, 52, 0, 0,
+  0, 9, 0, 50, 0, 0, 0, 0, 0, 0,
+  91, 11, 34, 0, 0, 0, 15, 26, 42, 23,
+  0, 6, 0, 4, 107, 11, 0, 0, 11, 8,
+  10, 15, 30, 12, 42, 45, 0, 41, 0, 10,
+  0, 0, 0, 81, 0, 0, 14, 0, 46, 0,
+  23, 15, 32, 37, 0, 0, 0, 0, 0, 0,
+  0, 0, 12, 0, 30, 11, 149, 0, 76, 0,
+  46, 0, 0, 131, 52, 5, 17, 0, 45, 0,
+  11, 44, 5, 23, 60, 0, 17, 55, 55, 49,
+  15, 72, 0, 0, 12, 32, 54, 53, 11, 54,
+  0, 20, 0, 0, 76, 0, 17, 0, 0, 0,
+  0, 41, 0, 25, 68, 41, 28, 22, 40, 0,
+  0, 52, 0, 3, 85, 24, 0, 0, 0, 0,
+  0, 44, 4, 0, 0, 5, 0, 0, 29, 13,
+  13, 0, 0, 0, 8, 16, 74, 5, 15, 32,
+  0, 0, 97, 0, 0, 0, 14, 0, 30, 16,
+  22, 9, 0, 0, 0, 20, 0, 26, 0, 0,
+  0, 38, 5, 16, 9, 0, 39, 0, 48, 8,
+  25, 53, 0, 0, 0, 5, 0, 0, 0, 24,
+  33, 0, 34, 5, 77, 0, 62, 0, 29, 0,
+  0, 75, 0, 0, 5, 14, 48, 1, 0, 0,
+  0, 56, 51, 0, 0, 4, 32, 10, 13, 41,
+  0, 10, 71, 13, 29, 0, 10, 14, 0, 17,
+  0, 0, 42, 0, 5, 27, 0, 0, 9, 20,
+  0, 26, 0, 66, 11, 74, 35, 26, 0, 2,
+  0, 16, 68, 0, 0, 0, 30, 0, 1, 5,
+  28, 45, 0, 49, 0, 0, 0, 37, 29, 0,
+  51, 0, 22, 9, 83, 12, 47, 23, 0, 0,
+  69, 0, 4, 0, 38, 0, 23, 2, 0, 0,
+  0, 0, 0, 6, 0, 38, 0, 0, 22, 49,
+  15, 29, 19, 13, 22, 0, 31, 11, 0, 28,
+  0, 0, 0, 0, 0, 0, 0, 19, 71, 6,
+  22, 4, 0, 0, 22, 0, 10, 0, 0, 39,
+  0, 0, 0, 29, 0, 0, 78, 47, 0, 0,
+  30, 0, 0, 88, 39, 61, 6, 17, 0, 0,
+  0, 41, 0, 0, 7, 53, 6, 0, 17, 0,
+  36, 0, 0, 0, 35, 96, 0, 0, 48, 0,
+  9, 30, 0, 28, 42, 19, 0, 0, 0, 32,
+  2, 0, 4, 101, 46, 8, 0, 0, 0, 0,
+  0, 0, 66, 0, 6, 4, 24, 53, 52, 0,
+  17, 37, 0, 49, 0, 0, 5, 0, 39, 0,
+  0, 0, 0, 1, 0, 30, 51, 0, 0, 131,
+  0, 0, 11, 0, 0, 0, 0, 86, 87, 31,
+  0, 0, 0, 0, 0, 48, 0, 13, 0, 11,
+  0, 8, 2, 0, 0, 2, 51, 0, 25, 0,
+  41, 0, 28, 12, 43, 0, 0, 93, 41, 0,
+  7, 0, 52, 3, 86, 40, 12, 0, 76, 3,
+  0, 125, 70, 39, 2, 33, 0, 0, 0, 54,
+  36, 13, 16, 61, 3, 0, 21, 0, 90, 1,
+  0, 0, 0, 58, 0, 29, 9, 0, 26, 52,
+  0, 59, 72, 36, 0, 44, 0, 0, 84, 12,
+  0, 0, 22, 0, 0, 42, 0, 0, 0, 0,
+  0, 0, 47, 0, 62, 0, 0, 0, 2, 50,
+  38, 28, 0, 0, 0, 0, 77, 11, 8, 0,
+  0, 21, 0, 22, 43, 0, 0, 57, 0, 32,
+  0, 0, 0, 0, 0, 79, 66, 0, 0, 0,
+  15, 0, 10, 29, 0, 69, 0, 1, 0, 0,
+  0, 0, 0, 36, 65, 0, 62, 0, 139, 0,
+  57, 16, 25, 0, 0, 58, 49, 0, 14, 0,
+  50, 16, 63, 8, 3, 26, 61, 1, 7, 53,
+  52, 0, 0, 15, 0, 27, 43, 19, 23, 0,
+  0, 13, 0, 0, 0, 0, 41, 0, 0, 6,
+  0, 16, 0, 79, 0, 24, 0, 55, 1, 70,
+  61, 46, 0, 21, 0, 20, 72, 1, 0, 0,
+  29, 0, 0, 0, 15, 36, 0, 43, 0, 14,
+  0, 0, 79, 0, 0, 0, 7, 27, 66, 15,
+  34, 28, 0, 0, 79, 0, 29, 0, 25, 0,
+  16, 0, 0, 0, 0, 0, 0, 17, 0, 26,
+  0, 0, 5, 71, 31, 0, 0, 0, 26, 0,
+  28, 0, 0, 38, 0, 0, 0, 2, 0, 0,
+  2, 14, 69, 0, 27, 0, 63, 0, 43, 7,
+  17, 0, 10, 25, 0, 0, 0, 85, 0, 0,
+  22, 0, 0, 0, 0, 0, 0, 0, 0, 39,
+  3, 8, 0, 40, 0, 0, 0, 0, 8, 3,
+  0, 0, 0, 38, 0, 0, 0, 43, 47, 68,
+  23, 0, 46, 0, 22, 15, 0, 13, 59, 13,
+  0, 0, 0, 55, 0, 0, 112, 118, 34, 26,
+  48, 0, 0, 57, 67, 0, 179, 5, 0, 32,
+  0, 139, 175, 0, 10, 15, 0, 0, 0, 0,
+  42, 0, 0, 0, 28, 19, 31, 0, 0, 11,
+  42, 0, 0, 116, 13, 0, 34, 0, 0, 0,
+  6, 54, 43, 142, 0, 0, 0, 0, 0, 58,
+  0, 0, 0, 29, 0, 30, 0, 10, 0, 0,
+  53, 0, 0, 0, 0, 0, 1, 29, 1, 6,
+  0, 37, 0, 0, 0, 81, 0, 0, 83, 32,
+  0, 0, 0, 9, 0, 42, 6, 26, 0, 10,
+  0, 0, 0, 25, 0, 0, 22, 40, 7, 0,
+  0, 0, 67, 0, 0, 20, 33, 86, 0, 0,
+  32, 0, 0, 10, 0, 67, 54, 81, 0, 26,
+  0, 6, 0, 0, 25, 36, 58, 0, 32, 0,
+  0, 65, 0, 0, 102, 0, 0, 34, 25, 57,
+  85, 0, 33, 59, 0, 79, 0, 0, 3, 0,
+  3, 0, 2, 0, 0, 0, 0, 49, 15, 0,
+  0, 173, 0, 0, 0, 0, 0, 0, 0, 64,
+  113, 110, 0, 0, 0, 0, 0, 29, 0, 22,
+  0, 30, 0, 19, 0, 0, 0, 29, 61, 0,
+  40, 0, 0, 0, 0, 15, 1, 35, 0, 34,
+  21, 0, 0, 0, 48, 33, 91, 15, 14, 16,
+  57, 1, 0, 81, 49, 0, 0, 0, 6, 20,
+  26, 30, 1, 0, 0, 23, 0, 0, 0, 0,
+  60, 0, 3, 0, 0, 56, 0, 42, 4, 5,
+  0, 43, 0, 101, 57, 64, 0, 36, 0, 14,
+  67, 0, 0, 0, 60, 0, 18, 0, 6, 36,
+  0, 46, 0, 0, 0, 0, 80, 0, 0, 0,
+  27, 50, 26, 48, 16, 11, 0, 0, 59, 0,
+  25, 0, 0, 9, 9, 3, 5, 0, 0, 63,
+  0, 14, 0, 0, 0, 0, 4, 79, 88, 0,
+  0, 0, 17, 0, 30, 2, 0, 51, 0, 7,
+  0, 20, 0, 0, 0, 31, 77, 0, 50, 0,
+  85, 0, 42, 0, 14, 0, 0, 131, 52, 5,
+  17, 0, 45, 0, 11, 44, 5, 23, 60, 0,
+  17, 55, 55, 49, 15, 72, 0, 0, 12, 32,
+  54, 53, 11, 54, 0, 20, 0, 0, 76, 0,
+  17, 0, 0, 0, 0, 41, 0, 25, 68, 41,
+  28, 22, 40, 0, 0, 52, 0, 3, 85, 24,
+  0, 0, 0, 0, 0, 44, 4, 0, 0, 5,
+  0, 0, 29, 13, 13, 0, 0, 0, 8, 16,
+  74, 5, 15, 32, 0, 0, 97, 0, 0, 0,
+  14, 0, 30, 16, 22, 9, 0, 0, 0, 20,
+  0, 26, 0, 0, 0, 38, 5, 16, 9, 0,
+  39, 0, 48, 8, 25, 53, 0, 0, 0, 5,
+  0, 0, 0, 24, 33, 0, 34, 5, 77, 0,
+  62, 0, 29, 0, 0, 75, 0, 0, 5, 14,
+  48, 1, 0, 0, 0, 56, 51, 0, 0, 4,
+  32, 10, 13, 41, 0, 10, 71, 13, 29, 0,
+  10, 14, 0, 17, 0, 0, 42, 0, 5, 27,
+  0, 0, 9, 20, 0, 26, 0, 66, 11, 74,
+  35, 26, 0, 2, 0, 16, 68, 0, 0, 0,
+  30, 0, 1, 5, 28, 45, 0, 49, 0, 0,
+  0, 37, 29, 0, 51, 0, 22, 9, 83, 12,
+  47, 23, 0, 0, 69, 0, 4, 0, 38, 0,
+  23, 2, 0, 0, 0, 0, 0, 6, 0, 38,
+  0, 0, 22, 49, 15, 29, 19, 13, 22, 0,
+  31, 11, 0, 28, 0, 0, 0, 0, 0, 0,
+  0, 19, 71, 6, 22, 4, 0, 0, 22, 0,
+  10, 0, 7, 18, 0, 16, 0, 21, 57, 17,
+  0, 0, 0, 41, 57, 2, 0, 6, 60, 44,
+  5, 5, 45, 0, 15, 0, 37, 0, 27, 0,
+  0, 35, 0, 0, 85, 0, 0, 0, 0, 5,
+  0, 0, 0, 23, 0, 64, 4, 113, 25, 79,
+  0, 0, 0, 41, 66, 0, 0, 22, 11, 0,
+  0, 0, 15, 0, 0, 2, 0, 0, 0, 36,
+  38, 0, 60, 0, 2, 0, 50, 0, 47, 0,
+  0, 0, 62, 0, 47, 0, 7, 0, 20, 0,
+  0, 8, 0, 4, 0, 8, 0, 7, 0, 0,
+  51, 44, 26, 26, 0, 37, 18, 0, 29, 6,
+  9, 13, 0, 18, 0, 17, 0, 0, 6, 0,
+  36, 0, 37, 0, 37, 0, 0, 0, 38, 0,
+  0, 93, 41, 0, 7, 0, 52, 3, 86, 40,
+  12, 0, 76, 3, 0, 125, 70, 39, 2, 33,
+  0, 0, 0, 54, 36, 13, 16, 61, 3, 0,
+  21, 0, 90, 1, 0, 0, 0, 58, 0, 29,
+  9, 0, 26, 52, 0, 59, 72, 36, 0, 44,
+  0, 0, 84, 12, 0, 0, 22, 0, 0, 42,
+  0, 0, 0, 0, 0, 0, 47, 0, 62, 0,
+  0, 0, 2, 50, 38, 28, 0, 0, 0, 0,
+  77, 11, 8, 0, 0, 21, 0, 22, 43, 0,
+  0, 57, 0, 32, 0, 0, 0, 0, 0, 79,
+  66, 0, 0, 0, 15, 0, 10, 29, 0, 69,
+  0, 1, 0, 0, 0, 0, 0, 36, 65, 0,
+  62, 0, 139, 0, 57, 16, 25, 0, 0, 58,
+  49, 0, 14, 0, 50, 16, 63, 8, 3, 26,
+  61, 1, 7, 53, 52, 0, 0, 15, 0, 27,
+  43, 19, 23, 0, 0, 13, 0, 0, 0, 0,
+  41, 0, 0, 6, 0, 16, 0, 79, 0, 24,
+  0, 55, 1, 70, 61, 46, 0, 21, 0, 20,
+  72, 1, 0, 0, 29, 0, 0, 0, 15, 36,
+  0, 43, 0, 14, 0, 0, 79, 0, 0, 0,
+  7, 27, 66, 15, 34, 28, 0, 0, 79, 0,
+  29, 0, 25, 0, 16, 0, 0, 0, 0, 0,
+  0, 17, 0, 26, 0, 0, 5, 71, 31, 0,
+  0, 0, 26, 0, 28, 0, 0, 38, 0, 0,
+  0, 2, 0, 0, 2, 14, 69, 0, 27, 0,
+  63, 0, 43, 7, 17, 0, 0, 6, 0, 0,
+  0, 1, 30, 12, 26, 0, 0, 25, 43, 0,
+  8, 23, 56, 23, 0, 0, 32, 29, 18, 2,
+  25, 0, 0, 0, 0, 0, 0, 0, 36, 17,
+  0, 0, 0, 0, 0, 34, 0, 11, 0, 58,
+  21, 87, 29, 59, 0, 1, 0, 52, 63, 0,
+  3, 0, 12, 0, 0, 0, 25, 4, 0, 38,
+  0, 10, 4, 0, 42, 0, 34, 0, 0, 17,
+  34, 0, 45, 41, 0, 0, 77, 0, 55, 0,
+  5, 0, 14, 0, 0, 0, 0, 31, 0, 0,
+  0, 22, 0, 0, 32, 57, 30, 0, 0, 9,
+  8, 0, 15, 0, 0, 13, 0, 14, 0, 2,
+  0, 0, 29, 0, 33, 0, 14, 0, 33, 0,
+  13, 6, 20, 0, 0, 37, 0, 0, 0, 81,
+  0, 0, 83, 32, 0, 0, 0, 9, 0, 42,
+  6, 26, 0, 10, 0, 0, 0, 25, 0, 0,
+  22, 40, 7, 0, 0, 0, 67, 0, 0, 20,
+  33, 86, 0, 0, 32, 0, 0, 10, 0, 67,
+  54, 81, 0, 26, 0, 6, 0, 0, 25, 36,
+  58, 0, 32, 0, 0, 65, 0, 0, 102, 0,
+  0, 34, 25, 57, 85, 0, 33, 59, 0, 79,
+  0, 0, 3, 0, 3, 0, 2, 0, 0, 0,
+  0, 49, 15, 0, 0, 173, 0, 0, 0, 0,
+  0, 0, 0, 64, 113, 110, 0, 0, 0, 0,
+  0, 29, 0, 22, 0, 30, 0, 19, 0, 0,
+  0, 29, 61, 0, 40, 0, 0, 0, 0, 15,
+  1, 35, 0, 34, 21, 0, 0, 0, 48, 33,
+  91, 15, 14, 16, 57, 1, 0, 81, 49, 0,
+  0, 0, 6, 20, 26, 30, 1, 0, 0, 23,
+  0, 0, 0, 0, 60, 0, 3, 0, 0, 56,
+  0, 42, 4, 5, 0, 43, 0, 101, 57, 64,
+  0, 36, 0, 14, 67, 0, 0, 0, 60, 0,
+  18, 0, 6, 36, 0, 46, 0, 0, 0, 0,
+  80, 0, 0, 0, 27, 50, 26, 48, 16, 11,
+  0, 0, 59, 0, 25, 0, 0, 9, 9, 3,
+  5, 0, 0, 63, 0, 14, 0, 0, 0, 0,
+  4, 79, 88, 0, 0, 0, 17, 0, 30, 2,
+  0, 51, 0, 7, 0, 20, 0, 0, 0, 31,
+  77, 0, 50, 0, 85, 0, 42, 0, 14, 0,
+  0, 27, 0, 6, 0, 0, 33, 17, 40, 0,
+  12, 29, 62, 0, 14, 33, 65, 28, 0, 0,
+  26, 32, 26, 12, 42, 0, 0, 27, 0, 0,
+  0, 0, 69, 0, 0, 0, 0, 14, 0, 40,
+  0, 14, 0, 40, 23, 88, 0, 29, 0, 18,
+  0, 24, 66, 1, 4, 0, 0, 0, 0, 0,
+  30, 14, 0, 50, 0, 7, 42, 0, 37, 0,
+  0, 0, 0, 48, 16, 0, 58, 78, 0, 0,
+  60, 0, 43, 4, 0, 14, 12, 0, 0, 2,
+  0, 24, 0, 6, 0, 25, 4, 0, 5, 84,
+  38, 0, 0, 3, 48, 0, 12, 5, 0, 1,
+  0, 12, 0, 2, 0, 0, 15, 0, 12, 0,
+  16, 0, 60, 0, 26, 0, 25, 0, 0, 75,
+  0, 0, 5, 14, 48, 1, 0, 0, 0, 56,
+  51, 0, 0, 4, 32, 10, 13, 41, 0, 10,
+  71, 13, 29, 0, 10, 14, 0, 17, 0, 0,
+  42, 0, 5, 27, 0, 0, 9, 20, 0, 26,
+  0, 66, 11, 74, 35, 26, 0, 2, 0, 16,
+  68, 0, 0, 0, 30, 0, 1, 5, 28, 45,
+  0, 49, 0, 0, 0, 37, 29, 0, 51, 0,
+  22, 9, 83, 12, 47, 23, 0, 0, 69, 0,
+  4, 0, 38, 0, 23, 2, 0, 0, 0, 0,
+  0, 6, 0, 38, 0, 0, 22, 49, 15, 29,
+  19, 13, 22, 0, 31, 11, 0, 28, 0, 0,
+  0, 0, 0, 0, 0, 19, 71, 6, 22, 4,
+  0, 0, 22, 0, 10, 0, 7, 18, 0, 16,
+  0, 21, 57, 17, 0, 0, 0, 41, 57, 2,
+  0, 6, 60, 44, 5, 5, 45, 0, 15, 0,
+  37, 0, 27, 0, 0, 35, 0, 0, 85, 0,
+  0, 0, 0, 5, 0, 0, 0, 23, 0, 64,
+  4, 113, 25, 79, 0, 0, 0, 41, 66, 0,
+  0, 22, 11, 0, 0, 0, 15, 0, 0, 2,
+  0, 0, 0, 36, 38, 0, 60, 0, 2, 0,
+  50, 0, 47, 0, 0, 0, 62, 0, 47, 0,
+  7, 0, 20, 0, 0, 8, 0, 4, 0, 8,
+  0, 7, 0, 0, 51, 44, 26, 26, 0, 37,
+  18, 0, 29, 6, 9, 13, 0, 18, 0, 17,
+  0, 0, 6, 0, 36, 0, 37, 0, 37, 0,
+  0, 0, 38, 0, 0, 12, 0, 42, 6, 15,
+  37, 28, 4, 4, 6, 14, 22, 0, 5, 59,
+  66, 39, 0, 24, 0, 0, 0, 20, 47, 15,
+  29, 33, 0, 35, 0, 0, 91, 34, 6, 0,
+  0, 11, 0, 10, 0, 18, 0, 22, 0, 58,
+  46, 78, 0, 43, 0, 62, 86, 46, 0, 56,
+  0, 0, 0, 20, 4, 0, 0, 0, 0, 0,
+  39, 0, 35, 6, 23, 0, 0, 0, 28, 23,
+  8, 0, 0, 0, 113, 0, 11, 9, 0, 0,
+  7, 22, 0, 0, 22, 29, 0, 8, 36, 0,
+  36, 0, 26, 59, 19, 7, 14, 19, 16, 0,
+  26, 17, 35, 32, 0, 9, 19, 42, 0, 0,
+  5, 0, 0, 0, 14, 11, 125, 0, 35, 0,
+  0, 0, 0, 58, 49, 0, 14, 0, 50, 16,
+  63, 8, 3, 26, 61, 1, 7, 53, 52, 0,
+  0, 15, 0, 27, 43, 19, 23, 0, 0, 13,
+  0, 0, 0, 0, 41, 0, 0, 6, 0, 16,
+  0, 79, 0, 24, 0, 55, 1, 70, 61, 46,
+  0, 21, 0, 20, 72, 1, 0, 0, 29, 0,
+  0, 0, 15, 36, 0, 43, 0, 14, 0, 0,
+  79, 0, 0, 0, 7, 27, 66, 15, 34, 28,
+  0, 0, 79, 0, 29, 0, 25, 0, 16, 0,
+  0, 0, 0, 0, 0, 17, 0, 26, 0, 0,
+  5, 71, 31, 0, 0, 0, 26, 0, 28, 0,
+  0, 38, 0, 0, 0, 2, 0, 0, 2, 14,
+  69, 0, 27, 0, 63, 0, 43, 7, 17, 0,
+  0, 6, 0, 0, 0, 1, 30, 12, 26, 0,
+  0, 25, 43, 0, 8, 23, 56, 23, 0, 0,
+  32, 29, 18, 2, 25, 0, 0, 0, 0, 0,
+  0, 0, 36, 17, 0, 0, 0, 0, 0, 34,
+  0, 11, 0, 58, 21, 87, 29, 59, 0, 1,
+  0, 52, 63, 0, 3, 0, 12, 0, 0, 0,
+  25, 4, 0, 38, 0, 10, 4, 0, 42, 0,
+  34, 0, 0, 17, 34, 0, 45, 41, 0, 0,
+  77, 0, 55, 0, 5, 0, 14, 0, 0, 0,
+  0, 31, 0, 0, 0, 22, 0, 0, 32, 57,
+  30, 0, 0, 9, 8, 0, 15, 0, 0, 13,
+  0, 14, 0, 2, 0, 0, 29, 0, 33, 0,
+  14, 0, 33, 0, 13, 6, 20, 0, 0, 5,
+  0, 30, 11, 9, 0, 0, 16, 0, 14, 0,
+  28, 0, 0, 43, 62, 17, 0, 4, 0, 0,
+  0, 14, 39, 0, 19, 14, 0, 0, 0, 0,
+  39, 51, 0, 0, 0, 0, 8, 0, 0, 0,
+  0, 26, 0, 76, 41, 64, 0, 17, 0, 73,
+  78, 15, 1, 58, 0, 0, 0, 0, 35, 0,
+  0, 26, 0, 0, 54, 0, 52, 39, 59, 0,
+  0, 16, 4, 0, 13, 36, 0, 0, 89, 0,
+  49, 0, 0, 20, 1, 30, 0, 0, 0, 79,
+  0, 0, 39, 0, 21, 0, 17, 79, 53, 5,
+  0, 14, 0, 0, 0, 9, 0, 17, 0, 33,
+  0, 25, 0, 0, 3, 0, 0, 0, 0, 0,
+  77, 0, 14, 5, 4, 0, 0, 34, 21, 0,
+  0, 0, 48, 33, 91, 15, 14, 16, 57, 1,
+  0, 81, 49, 0, 0, 0, 6, 20, 26, 30,
+  1, 0, 0, 23, 0, 0, 0, 0, 60, 0,
+  3, 0, 0, 56, 0, 42, 4, 5, 0, 43,
+  0, 101, 57, 64, 0, 36, 0, 14, 67, 0,
+  0, 0, 60, 0, 18, 0, 6, 36, 0, 46,
+  0, 0, 0, 0, 80, 0, 0, 0, 27, 50,
+  26, 48, 16, 11, 0, 0, 59, 0, 25, 0,
+  0, 9, 9, 3, 5, 0, 0, 63, 0, 14,
+  0, 0, 0, 0, 4, 79, 88, 0, 0, 0,
+  17, 0, 30, 2, 0, 51, 0, 7, 0, 20,
+  0, 0, 0, 31, 77, 0, 50, 0, 85, 0,
+  42, 0, 14, 0, 0, 27, 0, 6, 0, 0,
+  33, 17, 40, 0, 12, 29, 62, 0, 14, 33,
+  65, 28, 0, 0, 26, 32, 26, 12, 42, 0,
+  0, 27, 0, 0, 0, 0, 69, 0, 0, 0,
+  0, 14, 0, 40, 0, 14, 0, 40, 23, 88,
+  0, 29, 0, 18, 0, 24, 66, 1, 4, 0,
+  0, 0, 0, 0, 30, 14, 0, 50, 0, 7,
+  42, 0, 37, 0, 0, 0, 0, 48, 16, 0,
+  58, 78, 0, 0, 60, 0, 43, 4, 0, 14,
+  12, 0, 0, 2, 0, 24, 0, 6, 0, 25,
+  4, 0, 5, 84, 38, 0, 0, 3, 48, 0,
+  12, 5, 0, 1, 0, 12, 0, 2, 0, 0,
+  15, 0, 12, 0, 16, 0, 60, 0, 26, 0,
+  25, 0, 32, 14, 0, 17, 0, 0, 0, 0,
+  0, 0, 1, 1, 16, 0, 0, 0, 49, 11,
+  3, 0, 0, 29, 0, 16, 72, 0, 37, 30,
+  0, 0, 0, 15, 79, 12, 0, 0, 0, 13,
+  41, 0, 0, 0, 0, 11, 0, 105, 32, 28,
+  0, 0, 0, 8, 36, 0, 22, 20, 3, 0,
+  0, 0, 87, 22, 0, 54, 0, 0, 130, 30,
+  67, 49, 31, 0, 0, 36, 0, 0, 48, 46,
+  0, 0, 36, 0, 58, 28, 0, 42, 0, 0,
+  0, 0, 0, 73, 0, 0, 0, 0, 0, 0,
+  0, 113, 49, 57, 10, 33, 35, 37, 0, 0,
+  24, 0, 0, 52, 0, 0, 0, 0, 4, 0,
+  10, 0, 8, 0, 23, 0, 0, 0, 31, 19,
+  7, 18, 0, 16, 0, 21, 57, 17, 0, 0,
+  0, 41, 57, 2, 0, 6, 60, 44, 5, 5,
+  45, 0, 15, 0, 37, 0, 27, 0, 0, 35,
+  0, 0, 85, 0, 0, 0, 0, 5, 0, 0,
+  0, 23, 0, 64, 4, 113, 25, 79, 0, 0,
+  0, 41, 66, 0, 0, 22, 11, 0, 0, 0,
+  15, 0, 0, 2, 0, 0, 0, 36, 38, 0,
+  60, 0, 2, 0, 50, 0, 47, 0, 0, 0,
+  62, 0, 47, 0, 7, 0, 20, 0, 0, 8,
+  0, 4, 0, 8, 0, 7, 0, 0, 51, 44,
+  26, 26, 0, 37, 18, 0, 29, 6, 9, 13,
+  0, 18, 0, 17, 0, 0, 6, 0, 36, 0,
+  37, 0, 37, 0, 0, 0, 38, 0, 0, 12,
+  0, 42, 6, 15, 37, 28, 4, 4, 6, 14,
+  22, 0, 5, 59, 66, 39, 0, 24, 0, 0,
+  0, 20, 47, 15, 29, 33, 0, 35, 0, 0,
+  91, 34, 6, 0, 0, 11, 0, 10, 0, 18,
+  0, 22, 0, 58, 46, 78, 0, 43, 0, 62,
+  86, 46, 0, 56, 0, 0, 0, 20, 4, 0,
+  0, 0, 0, 0, 39, 0, 35, 6, 23, 0,
+  0, 0, 28, 23, 8, 0, 0, 0, 113, 0,
+  11, 9, 0, 0, 7, 22, 0, 0, 22, 29,
+  0, 8, 36, 0, 36, 0, 26, 59, 19, 7,
+  14, 19, 16, 0, 26, 17, 35, 32, 0, 9,
+  19, 42, 0, 0, 5, 0, 0, 0, 14, 11,
+  125, 0, 35, 0, 0, 0, 0, 93, 5, 24,
+  14, 0, 37, 16, 19, 24, 15, 1, 7, 0,
+  45, 74, 66, 43, 0, 20, 0, 0, 0, 49,
+  65, 69, 6, 62, 0, 1, 5, 0, 69, 27,
+  8, 0, 0, 8, 0, 34, 0, 35, 41, 0,
+  16, 0, 40, 0, 0, 56, 0, 37, 99, 45,
+  0, 4, 0, 17, 0, 45, 12, 0, 0, 33,
+  0, 12, 78, 0, 23, 0, 0, 0, 0, 6,
+  46, 35, 1, 18, 0, 2, 119, 0, 0, 1,
+  0, 16, 0, 27, 17, 29, 59, 0, 0, 26,
+  0, 8, 27, 0, 0, 42, 0, 0, 29, 0,
+  16, 0, 32, 10, 52, 56, 0, 0, 9, 11,
+  0, 0, 0, 0, 0, 0, 4, 23, 137, 0,
+  66, 0, 0, 0, 0, 6, 0, 0, 0, 1,
+  30, 12, 26, 0, 0, 25, 43, 0, 8, 23,
+  56, 23, 0, 0, 32, 29, 18, 2, 25, 0,
+  0, 0, 0, 0, 0, 0, 36, 17, 0, 0,
+  0, 0, 0, 34, 0, 11, 0, 58, 21, 87,
+  29, 59, 0, 1, 0, 52, 63, 0, 3, 0,
+  12, 0, 0, 0, 25, 4, 0, 38, 0, 10,
+  4, 0, 42, 0, 34, 0, 0, 17, 34, 0,
+  45, 41, 0, 0, 77, 0, 55, 0, 5, 0,
+  14, 0, 0, 0, 0, 31, 0, 0, 0, 22,
+  0, 0, 32, 57, 30, 0, 0, 9, 8, 0,
+  15, 0, 0, 13, 0, 14, 0, 2, 0, 0,
+  29, 0, 33, 0, 14, 0, 33, 0, 13, 6,
+  20, 0, 0, 5, 0, 30, 11, 9, 0, 0,
+  16, 0, 14, 0, 28, 0, 0, 43, 62, 17,
+  0, 4, 0, 0, 0, 14, 39, 0, 19, 14,
+  0, 0, 0, 0, 39, 51, 0, 0, 0, 0,
+  8, 0, 0, 0, 0, 26, 0, 76, 41, 64,
+  0, 17, 0, 73, 78, 15, 1, 58, 0, 0,
+  0, 0, 35, 0, 0, 26, 0, 0, 54, 0,
+  52, 39, 59, 0, 0, 16, 4, 0, 13, 36,
+  0, 0, 89, 0, 49, 0, 0, 20, 1, 30,
+  0, 0, 0, 79, 0, 0, 39, 0, 21, 0,
+  17, 79, 53, 5, 0, 14, 0, 0, 0, 9,
+  0, 17, 0, 33, 0, 25, 0, 0, 3, 0,
+  0, 0, 0, 0, 77, 0, 14, 5, 4, 0,
+  0, 37, 0, 30, 19, 0, 8, 0, 29, 1,
+  5, 0, 23, 0, 24, 68, 78, 31, 0, 2,
+  0, 0, 0, 40, 45, 0, 20, 28, 0, 0,
+  7, 0, 46, 69, 0, 0, 0, 8, 7, 0,
+  0, 0, 0, 16, 0, 35, 63, 39, 0, 11,
+  0, 42, 72, 27, 0, 30, 0, 4, 0, 3,
+  38, 0, 0, 31, 0, 0, 79, 0, 75, 41,
+  0, 0, 0, 12, 16, 0, 14, 1, 0, 0,
+  85, 0, 26, 0, 0, 32, 0, 18, 6, 0,
+  14, 72, 0, 6, 28, 0, 15, 0, 0, 80,
+  18, 0, 0, 7, 0, 0, 0, 0, 2, 22,
+  0, 30, 8, 22, 3, 0, 0, 0, 0, 0,
+  0, 0, 101, 0, 9, 26, 7, 0, 0, 27,
+  0, 6, 0, 0, 33, 17, 40, 0, 12, 29,
+  62, 0, 14, 33, 65, 28, 0, 0, 26, 32,
+  26, 12, 42, 0, 0, 27, 0, 0, 0, 0,
+  69, 0, 0, 0, 0, 14, 0, 40, 0, 14,
+  0, 40, 23, 88, 0, 29, 0, 18, 0, 24,
+  66, 1, 4, 0, 0, 0, 0, 0, 30, 14,
+  0, 50, 0, 7, 42, 0, 37, 0, 0, 0,
+  0, 48, 16, 0, 58, 78, 0, 0, 60, 0,
+  43, 4, 0, 14, 12, 0, 0, 2, 0, 24,
+  0, 6, 0, 25, 4, 0, 5, 84, 38, 0,
+  0, 3, 48, 0, 12, 5, 0, 1, 0, 12,
+  0, 2, 0, 0, 15, 0, 12, 0, 16, 0,
+  60, 0, 26, 0, 25, 0, 32, 14, 0, 17,
+  0, 0, 0, 0, 0, 0, 1, 1, 16, 0,
+  0, 0, 49, 11, 3, 0, 0, 29, 0, 16,
+  72, 0, 37, 30, 0, 0, 0, 15, 79, 12,
+  0, 0, 0, 13, 41, 0, 0, 0, 0, 11,
+  0, 105, 32, 28, 0, 0, 0, 8, 36, 0,
+  22, 20, 3, 0, 0, 0, 87, 22, 0, 54,
+  0, 0, 130, 30, 67, 49, 31, 0, 0, 36,
+  0, 0, 48, 46, 0, 0, 36, 0, 58, 28,
+  0, 42, 0, 0, 0, 0, 0, 73, 0, 0,
+  0, 0, 0, 0, 0, 113, 49, 57, 10, 33,
+  35, 37, 0, 0, 24, 0, 0, 52, 0, 0,
+  0, 0, 4, 0, 10, 0, 8, 0, 23, 0,
+  0, 0, 31, 19, 12, 13, 0, 21, 6, 5,
+  0, 0, 11, 0, 0, 0, 48, 0, 0, 18,
+  58, 12, 0, 0, 0, 8, 0, 28, 33, 0,
+  31, 20, 0, 0, 0, 2, 67, 50, 0, 0,
+  0, 26, 49, 0, 0, 0, 0, 31, 0, 97,
+  52, 74, 0, 0, 0, 36, 26, 0, 0, 44,
+  0, 0, 0, 0, 64, 9, 0, 12, 0, 0,
+  87, 26, 88, 48, 67, 0, 0, 16, 0, 0,
+  28, 0, 0, 0, 33, 0, 46, 22, 0, 32,
+  0, 0, 2, 0, 0, 84, 0, 0, 12, 0,
+  0, 0, 1, 115, 49, 54, 0, 40, 17, 26,
+  0, 0, 9, 0, 0, 49, 0, 16, 0, 0,
+  0, 0, 29, 0, 1, 0, 46, 0, 0, 0,
+  33, 16, 0, 12, 0, 42, 6, 15, 37, 28,
+  4, 4, 6, 14, 22, 0, 5, 59, 66, 39,
+  0, 24, 0, 0, 0, 20, 47, 15, 29, 33,
+  0, 35, 0, 0, 91, 34, 6, 0, 0, 11,
+  0, 10, 0, 18, 0, 22, 0, 58, 46, 78,
+  0, 43, 0, 62, 86, 46, 0, 56, 0, 0,
+  0, 20, 4, 0, 0, 0, 0, 0, 39, 0,
+  35, 6, 23, 0, 0, 0, 28, 23, 8, 0,
+  0, 0, 113, 0, 11, 9, 0, 0, 7, 22,
+  0, 0, 22, 29, 0, 8, 36, 0, 36, 0,
+  26, 59, 19, 7, 14, 19, 16, 0, 26, 17,
+  35, 32, 0, 9, 19, 42, 0, 0, 5, 0,
+  0, 0, 14, 11, 125, 0, 35, 0, 0, 0,
+  0, 93, 5, 24, 14, 0, 37, 16, 19, 24,
+  15, 1, 7, 0, 45, 74, 66, 43, 0, 20,
+  0, 0, 0, 49, 65, 69, 6, 62, 0, 1,
+  5, 0, 69, 27, 8, 0, 0, 8, 0, 34,
+  0, 35, 41, 0, 16, 0, 40, 0, 0, 56,
+  0, 37, 99, 45, 0, 4, 0, 17, 0, 45,
+  12, 0, 0, 33, 0, 12, 78, 0, 23, 0,
+  0, 0, 0, 6, 46, 35, 1, 18, 0, 2,
+  119, 0, 0, 1, 0, 16, 0, 27, 17, 29,
+  59, 0, 0, 26, 0, 8, 27, 0, 0, 42,
+  0, 0, 29, 0, 16, 0, 32, 10, 52, 56,
+  0, 0, 9, 11, 0, 0, 0, 0, 0, 0,
+  4, 23, 137, 0, 66, 0, 0, 0, 0, 115,
+  36, 17, 6, 0, 3, 0, 44, 17, 0, 0,
+  3, 0, 0, 24, 36, 38, 6, 35, 0, 0,
+  67, 53, 19, 0, 40, 54, 0, 0, 0, 0,
+  68, 0, 53, 8, 0, 0, 28, 2, 0, 0,
+  37, 25, 0, 67, 27, 0, 0, 2, 0, 53,
+  88, 0, 20, 0, 26, 0, 0, 0, 0, 27,
+  0, 0, 0, 0, 0, 0, 0, 14, 53, 0,
+  37, 17, 61, 42, 0, 74, 24, 0, 64, 0,
+  4, 21, 0, 0, 6, 36, 25, 20, 74, 0,
+  0, 0, 24, 0, 0, 0, 0, 53, 38, 17,
+  0, 0, 21, 4, 62, 0, 41, 58, 0, 16,
+  0, 3, 0, 0, 0, 0, 0, 6, 0, 0,
+  35, 0, 53, 1, 0, 0, 0, 5, 0, 30,
+  11, 9, 0, 0, 16, 0, 14, 0, 28, 0,
+  0, 43, 62, 17, 0, 4, 0, 0, 0, 14,
+  39, 0, 19, 14, 0, 0, 0, 0, 39, 51,
+  0, 0, 0, 0, 8, 0, 0, 0, 0, 26,
+  0, 76, 41, 64, 0, 17, 0, 73, 78, 15,
+  1, 58, 0, 0, 0, 0, 35, 0, 0, 26,
+  0, 0, 54, 0, 52, 39, 59, 0, 0, 16,
+  4, 0, 13, 36, 0, 0, 89, 0, 49, 0,
+  0, 20, 1, 30, 0, 0, 0, 79, 0, 0,
+  39, 0, 21, 0, 17, 79, 53, 5, 0, 14,
+  0, 0, 0, 9, 0, 17, 0, 33, 0, 25,
+  0, 0, 3, 0, 0, 0, 0, 0, 77, 0,
+  14, 5, 4, 0, 0, 37, 0, 30, 19, 0,
+  8, 0, 29, 1, 5, 0, 23, 0, 24, 68,
+  78, 31, 0, 2, 0, 0, 0, 40, 45, 0,
+  20, 28, 0, 0, 7, 0, 46, 69, 0, 0,
+  0, 8, 7, 0, 0, 0, 0, 16, 0, 35,
+  63, 39, 0, 11, 0, 42, 72, 27, 0, 30,
+  0, 4, 0, 3, 38, 0, 0, 31, 0, 0,
+  79, 0, 75, 41, 0, 0, 0, 12, 16, 0,
+  14, 1, 0, 0, 85, 0, 26, 0, 0, 32,
+  0, 18, 6, 0, 14, 72, 0, 6, 28, 0,
+  15, 0, 0, 80, 18, 0, 0, 7, 0, 0,
+  0, 0, 2, 22, 0, 30, 8, 22, 3, 0,
+  0, 0, 0, 0, 0, 0, 101, 0, 9, 26,
+  7, 0, 0, 119, 31, 10, 0, 0, 55, 0,
+  33, 18, 0, 0, 0, 0, 46, 39, 65, 38,
+  5, 18, 0, 0, 0, 46, 49, 6, 24, 40,
+  0, 0, 0, 0, 84, 26, 0, 0, 0, 16,
+  0, 3, 0, 0, 24, 17, 0, 45, 64, 6,
+  0, 10, 0, 0, 73, 0, 0, 0, 32, 0,
+  0, 35, 7, 5, 0, 0, 0, 0, 63, 0,
+  26, 11, 0, 0, 0, 15, 64, 26, 8, 27,
+  5, 0, 67, 3, 18, 28, 0, 6, 0, 0,
+  1, 26, 36, 0, 0, 22, 0, 0, 0, 0,
+  0, 60, 6, 0, 0, 0, 2, 0, 43, 0,
+  35, 36, 0, 21, 0, 19, 0, 0, 0, 0,
+  13, 0, 0, 0, 95, 0, 24, 41, 20, 0,
+  32, 14, 0, 17, 0, 0, 0, 0, 0, 0,
+  1, 1, 16, 0, 0, 0, 49, 11, 3, 0,
+  0, 29, 0, 16, 72, 0, 37, 30, 0, 0,
+  0, 15, 79, 12, 0, 0, 0, 13, 41, 0,
+  0, 0, 0, 11, 0, 105, 32, 28, 0, 0,
+  0, 8, 36, 0, 22, 20, 3, 0, 0, 0,
+  87, 22, 0, 54, 0, 0, 130, 30, 67, 49,
+  31, 0, 0, 36, 0, 0, 48, 46, 0, 0,
+  36, 0, 58, 28, 0, 42, 0, 0, 0, 0,
+  0, 73, 0, 0, 0, 0, 0, 0, 0, 113,
+  49, 57, 10, 33, 35, 37, 0, 0, 24, 0,
+  0, 52, 0, 0, 0, 0, 4, 0, 10, 0,
+  8, 0, 23, 0, 0, 0, 31, 19, 12, 13,
+  0, 21, 6, 5, 0, 0, 11, 0, 0, 0,
+  48, 0, 0, 18, 58, 12, 0, 0, 0, 8,
+  0, 28, 33, 0, 31, 20, 0, 0, 0, 2,
+  67, 50, 0, 0, 0, 26, 49, 0, 0, 0,
+  0, 31, 0, 97, 52, 74, 0, 0, 0, 36,
+  26, 0, 0, 44, 0, 0, 0, 0, 64, 9,
+  0, 12, 0, 0, 87, 26, 88, 48, 67, 0,
+  0, 16, 0, 0, 28, 0, 0, 0, 33, 0,
+  46, 22, 0, 32, 0, 0, 2, 0, 0, 84,
+  0, 0, 12, 0, 0, 0, 1, 115, 49, 54,
+  0, 40, 17, 26, 0, 0, 9, 0, 0, 49,
+  0, 16, 0, 0, 0, 0, 29, 0, 1, 0,
+  46, 0, 0, 0, 33, 16, 0, 98, 0, 20,
+  14, 0, 60, 12, 44, 16, 32, 0, 54, 0,
+  44, 107, 104, 30, 6, 0, 0, 0, 0, 40,
+  41, 45, 0, 53, 0, 0, 0, 0, 87, 64,
+  0, 0, 0, 27, 0, 41, 0, 0, 16, 28,
+  30, 44, 24, 53, 0, 28, 0, 0, 87, 10,
+  0, 0, 0, 14, 0, 58, 10, 0, 0, 24,
+  0, 0, 75, 0, 41, 0, 0, 0, 0, 48,
+  17, 40, 0, 0, 0, 12, 73, 0, 9, 26,
+  0, 32, 2, 2, 0, 43, 49, 36, 0, 65,
+  0, 26, 0, 0, 0, 86, 27, 0, 0, 0,
+  9, 0, 28, 10, 24, 30, 0, 17, 0, 27,
+  0, 0, 0, 0, 2, 0, 8, 0, 164, 0,
+  52, 9, 40, 0, 0, 93, 5, 24, 14, 0,
+  37, 16, 19, 24, 15, 1, 7, 0, 45, 74,
+  66, 43, 0, 20, 0, 0, 0, 49, 65, 69,
+  6, 62, 0, 1, 5, 0, 69, 27, 8, 0,
+  0, 8, 0, 34, 0, 35, 41, 0, 16, 0,
+  40, 0, 0, 56, 0, 37, 99, 45, 0, 4,
+  0, 17, 0, 45, 12, 0, 0, 33, 0, 12,
+  78, 0, 23, 0, 0, 0, 0, 6, 46, 35,
+  1, 18, 0, 2, 119, 0, 0, 1, 0, 16,
+  0, 27, 17, 29, 59, 0, 0, 26, 0, 8,
+  27, 0, 0, 42, 0, 0, 29, 0, 16, 0,
+  32, 10, 52, 56, 0, 0, 9, 11, 0, 0,
+  0, 0, 0, 0, 4, 23, 137, 0, 66, 0,
+  0, 0, 0, 115, 36, 17, 6, 0, 3, 0,
+  44, 17, 0, 0, 3, 0, 0, 24, 36, 38,
+  6, 35, 0, 0, 67, 53, 19, 0, 40, 54,
+  0, 0, 0, 0, 68, 0, 53, 8, 0, 0,
+  28, 2, 0, 0, 37, 25, 0, 67, 27, 0,
+  0, 2, 0, 53, 88, 0, 20, 0, 26, 0,
+  0, 0, 0, 27, 0, 0, 0, 0, 0, 0,
+  0, 14, 53, 0, 37, 17, 61, 42, 0, 74,
+  24, 0, 64, 0, 4, 21, 0, 0, 6, 36,
+  25, 20, 74, 0, 0, 0, 24, 0, 0, 0,
+  0, 53, 38, 17, 0, 0, 21, 4, 62, 0,
+  41, 58, 0, 16, 0, 3, 0, 0, 0, 0,
+  0, 6, 0, 0, 35, 0, 53, 1, 0, 0,
+  55, 68, 5, 59, 7, 0, 0, 0, 39, 0,
+  0, 18, 78, 0, 0, 0, 25, 2, 0, 0,
+  0, 34, 65, 19, 34, 0, 18, 36, 0, 0,
+  0, 6, 13, 0, 31, 16, 0, 0, 71, 0,
+  0, 16, 19, 37, 0, 40, 14, 0, 0, 0,
+  0, 107, 29, 0, 61, 0, 36, 0, 0, 0,
+  0, 19, 0, 10, 41, 34, 0, 0, 22, 0,
+  133, 0, 33, 13, 17, 0, 9, 54, 28, 7,
+  16, 0, 14, 15, 15, 0, 15, 0, 48, 0,
+  1, 0, 0, 0, 0, 0, 10, 0, 0, 40,
+  0, 1, 9, 0, 35, 68, 7, 20, 38, 3,
+  0, 13, 0, 0, 0, 0, 0, 0, 0, 9,
+  0, 0, 0, 0, 53, 0, 0, 0, 0, 37,
+  0, 30, 19, 0, 8, 0, 29, 1, 5, 0,
+  23, 0, 24, 68, 78, 31, 0, 2, 0, 0,
+  0, 40, 45, 0, 20, 28, 0, 0, 7, 0,
+  46, 69, 0, 0, 0, 8, 7, 0, 0, 0,
+  0, 16, 0, 35, 63, 39, 0, 11, 0, 42,
+  72, 27, 0, 30, 0, 4, 0, 3, 38, 0,
+  0, 31, 0, 0, 79, 0, 75, 41, 0, 0,
+  0, 12, 16, 0, 14, 1, 0, 0, 85, 0,
+  26, 0, 0, 32, 0, 18, 6, 0, 14, 72,
+  0, 6, 28, 0, 15, 0, 0, 80, 18, 0,
+  0, 7, 0, 0, 0, 0, 2, 22, 0, 30,
+  8, 22, 3, 0, 0, 0, 0, 0, 0, 0,
+  101, 0, 9, 26, 7, 0, 0, 119, 31, 10,
+  0, 0, 55, 0, 33, 18, 0, 0, 0, 0,
+  46, 39, 65, 38, 5, 18, 0, 0, 0, 46,
+  49, 6, 24, 40, 0, 0, 0, 0, 84, 26,
+  0, 0, 0, 16, 0, 3, 0, 0, 24, 17,
+  0, 45, 64, 6, 0, 10, 0, 0, 73, 0,
+  0, 0, 32, 0, 0, 35, 7, 5, 0, 0,
+  0, 0, 63, 0, 26, 11, 0, 0, 0, 15,
+  64, 26, 8, 27, 5, 0, 67, 3, 18, 28,
+  0, 6, 0, 0, 1, 26, 36, 0, 0, 22,
+  0, 0, 0, 0, 0, 60, 6, 0, 0, 0,
+  2, 0, 43, 0, 35, 36, 0, 21, 0, 19,
+  0, 0, 0, 0, 13, 0, 0, 0, 95, 0,
+  24, 41, 20, 0, 0, 104, 16, 18, 0, 0,
+  0, 0, 47, 19, 0, 0, 6, 0, 7, 17,
+  36, 23, 0, 2, 0, 0, 72, 39, 0, 0,
+  14, 29, 0, 0, 0, 0, 40, 0, 36, 14,
+  0, 1, 11, 0, 0, 0, 22, 32, 0, 52,
+  25, 0, 0, 0, 0, 42, 40, 0, 22, 0,
+  44, 0, 3, 0, 0, 33, 0, 0, 52, 0,
+  0, 0, 0, 10, 106, 0, 39, 32, 46, 45,
+  0, 59, 28, 0, 21, 0, 1, 31, 0, 0,
+  5, 21, 26, 0, 31, 0, 0, 0, 5, 0,
+  0, 0, 0, 52, 28, 23, 1, 0, 7, 59,
+  48, 1, 0, 29, 0, 28, 0, 8, 0, 0,
+  0, 0, 0, 12, 0, 0, 0, 0, 49, 26,
+  5, 0, 12, 13, 0, 21, 6, 5, 0, 0,
+  11, 0, 0, 0, 48, 0, 0, 18, 58, 12,
+  0, 0, 0, 8, 0, 28, 33, 0, 31, 20,
+  0, 0, 0, 2, 67, 50, 0, 0, 0, 26,
+  49, 0, 0, 0, 0, 31, 0, 97, 52, 74,
+  0, 0, 0, 36, 26, 0, 0, 44, 0, 0,
+  0, 0, 64, 9, 0, 12, 0, 0, 87, 26,
+  88, 48, 67, 0, 0, 16, 0, 0, 28, 0,
+  0, 0, 33, 0, 46, 22, 0, 32, 0, 0,
+  2, 0, 0, 84, 0, 0, 12, 0, 0, 0,
+  1, 115, 49, 54, 0, 40, 17, 26, 0, 0,
+  9, 0, 0, 49, 0, 16, 0, 0, 0, 0,
+  29, 0, 1, 0, 46, 0, 0, 0, 33, 16,
+  0, 98, 0, 20, 14, 0, 60, 12, 44, 16,
+  32, 0, 54, 0, 44, 107, 104, 30, 6, 0,
+  0, 0, 0, 40, 41, 45, 0, 53, 0, 0,
+  0, 0, 87, 64, 0, 0, 0, 27, 0, 41,
+  0, 0, 16, 28, 30, 44, 24, 53, 0, 28,
+  0, 0, 87, 10, 0, 0, 0, 14, 0, 58,
+  10, 0, 0, 24, 0, 0, 75, 0, 41, 0,
+  0, 0, 0, 48, 17, 40, 0, 0, 0, 12,
+  73, 0, 9, 26, 0, 32, 2, 2, 0, 43,
+  49, 36, 0, 65, 0, 26, 0, 0, 0, 86,
+  27, 0, 0, 0, 9, 0, 28, 10, 24, 30,
+  0, 17, 0, 27, 0, 0, 0, 0, 2, 0,
+  8, 0, 164, 0, 52, 9, 40, 0, 0, 111,
+  49, 4, 4, 0, 0, 13, 78, 36, 24, 0,
+  20, 0, 0, 97, 83, 24, 24, 5, 0, 0,
+  48, 50, 0, 0, 1, 78, 1, 0, 0, 0,
+  68, 0, 12, 0, 0, 28, 0, 3, 0, 0,
+  11, 19, 11, 36, 0, 0, 0, 29, 0, 18,
+  44, 0, 0, 0, 1, 0, 0, 8, 0, 0,
+  0, 0, 0, 0, 29, 0, 0, 0, 0, 0,
+  32, 72, 9, 90, 0, 112, 2, 20, 35, 0,
+  0, 53, 0, 31, 6, 61, 21, 24, 117, 0,
+  0, 0, 26, 0, 0, 0, 0, 100, 90, 0,
+  0, 0, 7, 0, 54, 21, 0, 21, 0, 0,
+  0, 15, 0, 0, 0, 0, 0, 21, 0, 0,
+  73, 0, 76, 10, 35, 0, 0, 115, 36, 17,
+  6, 0, 3, 0, 44, 17, 0, 0, 3, 0,
+  0, 24, 36, 38, 6, 35, 0, 0, 67, 53,
+  19, 0, 40, 54, 0, 0, 0, 0, 68, 0,
+  53, 8, 0, 0, 28, 2, 0, 0, 37, 25,
+  0, 67, 27, 0, 0, 2, 0, 53, 88, 0,
+  20, 0, 26, 0, 0, 0, 0, 27, 0, 0,
+  0, 0, 0, 0, 0, 14, 53, 0, 37, 17,
+  61, 42, 0, 74, 24, 0, 64, 0, 4, 21,
+  0, 0, 6, 36, 25, 20, 74, 0, 0, 0,
+  24, 0, 0, 0, 0, 53, 38, 17, 0, 0,
+  21, 4, 62, 0, 41, 58, 0, 16, 0, 3,
+  0, 0, 0, 0, 0, 6, 0, 0, 35, 0,
+  53, 1, 0, 0, 55, 68, 5, 59, 7, 0,
+  0, 0, 39, 0, 0, 18, 78, 0, 0, 0,
+  25, 2, 0, 0, 0, 34, 65, 19, 34, 0,
+  18, 36, 0, 0, 0, 6, 13, 0, 31, 16,
+  0, 0, 71, 0, 0, 16, 19, 37, 0, 40,
+  14, 0, 0, 0, 0, 107, 29, 0, 61, 0,
+  36, 0, 0, 0, 0, 19, 0, 10, 41, 34,
+  0, 0, 22, 0, 133, 0, 33, 13, 17, 0,
+  9, 54, 28, 7, 16, 0, 14, 15, 15, 0,
+  15, 0, 48, 0, 1, 0, 0, 0, 0, 0,
+  10, 0, 0, 40, 0, 1, 9, 0, 35, 68,
+  7, 20, 38, 3, 0, 13, 0, 0, 0, 0,
+  0, 0, 0, 9, 0, 0, 0, 0, 53, 0,
+  0, 0, 104, 21, 0, 47, 20, 66, 0, 0,
+  53, 0, 0, 0, 116, 0, 0, 40, 62, 0,
+  2, 0, 11, 68, 0, 8, 23, 0, 0, 43,
+  3, 1, 13, 72, 0, 27, 24, 0, 0, 21,
+  96, 5, 13, 87, 14, 47, 59, 16, 0, 0,
+  0, 0, 0, 111, 0, 0, 107, 59, 25, 17,
+  19, 0, 0, 13, 9, 35, 0, 93, 0, 0,
+  13, 0, 155, 30, 22, 32, 0, 0, 34, 19,
+  0, 47, 0, 0, 15, 14, 42, 14, 8, 0,
+  73, 0, 0, 0, 0, 2, 0, 0, 31, 0,
+  21, 50, 0, 0, 5, 0, 30, 31, 0, 67,
+  22, 0, 17, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 3, 0, 16, 53, 0, 3, 16,
+  0, 119, 31, 10, 0, 0, 55, 0, 33, 18,
+  0, 0, 0, 0, 46, 39, 65, 38, 5, 18,
+  0, 0, 0, 46, 49, 6, 24, 40, 0, 0,
+  0, 0, 84, 26, 0, 0, 0, 16, 0, 3,
+  0, 0, 24, 17, 0, 45, 64, 6, 0, 10,
+  0, 0, 73, 0, 0, 0, 32, 0, 0, 35,
+  7, 5, 0, 0, 0, 0, 63, 0, 26, 11,
+  0, 0, 0, 15, 64, 26, 8, 27, 5, 0,
+  67, 3, 18, 28, 0, 6, 0, 0, 1, 26,
+  36, 0, 0, 22, 0, 0, 0, 0, 0, 60,
+  6, 0, 0, 0, 2, 0, 43, 0, 35, 36,
+  0, 21, 0, 19, 0, 0, 0, 0, 13, 0,
+  0, 0, 95, 0, 24, 41, 20, 0, 0, 104,
+  16, 18, 0, 0, 0, 0, 47, 19, 0, 0,
+  6, 0, 7, 17, 36, 23, 0, 2, 0, 0,
+  72, 39, 0, 0, 14, 29, 0, 0, 0, 0,
+  40, 0, 36, 14, 0, 1, 11, 0, 0, 0,
+  22, 32, 0, 52, 25, 0, 0, 0, 0, 42,
+  40, 0, 22, 0, 44, 0, 3, 0, 0, 33,
+  0, 0, 52, 0, 0, 0, 0, 10, 106, 0,
+  39, 32, 46, 45, 0, 59, 28, 0, 21, 0,
+  1, 31, 0, 0, 5, 21, 26, 0, 31, 0,
+  0, 0, 5, 0, 0, 0, 0, 52, 28, 23,
+  1, 0, 7, 59, 48, 1, 0, 29, 0, 28,
+  0, 8, 0, 0, 0, 0, 0, 12, 0, 0,
+  0, 0, 49, 26, 5, 0, 107, 66, 16, 65,
+  30, 0, 0, 17, 71, 14, 28, 0, 85, 0,
+  0, 80, 60, 0, 13, 0, 0, 32, 32, 6,
+  0, 0, 0, 61, 0, 37, 19, 69, 10, 6,
+  18, 5, 0, 44, 103, 0, 0, 23, 0, 23,
+  18, 0, 0, 0, 0, 0, 0, 86, 0, 0,
+  83, 13, 32, 36, 9, 0, 0, 0, 0, 0,
+  15, 55, 0, 0, 11, 0, 91, 19, 43, 55,
+  0, 39, 28, 49, 0, 26, 0, 0, 19, 64,
+  28, 26, 14, 0, 86, 0, 32, 0, 0, 14,
+  0, 0, 66, 0, 5, 67, 43, 0, 9, 0,
+  0, 58, 0, 60, 9, 0, 6, 0, 0, 0,
+  0, 0, 0, 0, 0, 15, 0, 4, 0, 18,
+  46, 15, 12, 30, 0, 98, 0, 20, 14, 0,
+  60, 12, 44, 16, 32, 0, 54, 0, 44, 107,
+  104, 30, 6, 0, 0, 0, 0, 40, 41, 45,
+  0, 53, 0, 0, 0, 0, 87, 64, 0, 0,
+  0, 27, 0, 41, 0, 0, 16, 28, 30, 44,
+  24, 53, 0, 28, 0, 0, 87, 10, 0, 0,
+  0, 14, 0, 58, 10, 0, 0, 24, 0, 0,
+  75, 0, 41, 0, 0, 0, 0, 48, 17, 40,
+  0, 0, 0, 12, 73, 0, 9, 26, 0, 32,
+  2, 2, 0, 43, 49, 36, 0, 65, 0, 26,
+  0, 0, 0, 86, 27, 0, 0, 0, 9, 0,
+  28, 10, 24, 30, 0, 17, 0, 27, 0, 0,
+  0, 0, 2, 0, 8, 0, 164, 0, 52, 9,
+  40, 0, 0, 111, 49, 4, 4, 0, 0, 13,
+  78, 36, 24, 0, 20, 0, 0, 97, 83, 24,
+  24, 5, 0, 0, 48, 50, 0, 0, 1, 78,
+  1, 0, 0, 0, 68, 0, 12, 0, 0, 28,
+  0, 3, 0, 0, 11, 19, 11, 36, 0, 0,
+  0, 29, 0, 18, 44, 0, 0, 0, 1, 0,
+  0, 8, 0, 0, 0, 0, 0, 0, 29, 0,
+  0, 0, 0, 0, 32, 72, 9, 90, 0, 112,
+  2, 20, 35, 0, 0, 53, 0, 31, 6, 61,
+  21, 24, 117, 0, 0, 0, 26, 0, 0, 0,
+  0, 100, 90, 0, 0, 0, 7, 0, 54, 21,
+  0, 21, 0, 0, 0, 15, 0, 0, 0, 0,
+  0, 21, 0, 0, 73, 0, 76, 10, 35, 0,
+  59, 1, 72, 42, 0, 0, 0, 22, 38, 13,
+  13, 6, 0, 7, 0, 21, 38, 13, 14, 0,
+  0, 64, 43, 11, 0, 0, 1, 54, 0, 38,
+  0, 39, 17, 0, 12, 19, 36, 29, 3, 0,
+  0, 0, 0, 0, 0, 11, 0, 0, 0, 0,
+  0, 70, 0, 0, 91, 0, 38, 0, 8, 0,
+  0, 4, 0, 0, 64, 10, 0, 0, 0, 114,
+  20, 0, 74, 27, 0, 45, 12, 51, 27, 0,
+  0, 0, 15, 101, 0, 21, 22, 36, 22, 0,
+  57, 0, 0, 0, 62, 0, 29, 0, 0, 72,
+  95, 0, 0, 0, 0, 80, 0, 16, 0, 0,
+  0, 13, 0, 0, 0, 0, 0, 0, 0, 33,
+  0, 3, 0, 0, 0, 0, 4, 22, 55, 68,
+  5, 59, 7, 0, 0, 0, 39, 0, 0, 18,
+  78, 0, 0, 0, 25, 2, 0, 0, 0, 34,
+  65, 19, 34, 0, 18, 36, 0, 0, 0, 6,
+  13, 0, 31, 16, 0, 0, 71, 0, 0, 16,
+  19, 37, 0, 40, 14, 0, 0, 0, 0, 107,
+  29, 0, 61, 0, 36, 0, 0, 0, 0, 19,
+  0, 10, 41, 34, 0, 0, 22, 0, 133, 0,
+  33, 13, 17, 0, 9, 54, 28, 7, 16, 0,
+  14, 15, 15, 0, 15, 0, 48, 0, 1, 0,
+  0, 0, 0, 0, 10, 0, 0, 40, 0, 1,
+  9, 0, 35, 68, 7, 20, 38, 3, 0, 13,
+  0, 0, 0, 0, 0, 0, 0, 9, 0, 0,
+  0, 0, 53, 0, 0, 0, 104, 21, 0, 47,
+  20, 66, 0, 0, 53, 0, 0, 0, 116, 0,
+  0, 40, 62, 0, 2, 0, 11, 68, 0, 8,
+  23, 0, 0, 43, 3, 1, 13, 72, 0, 27,
+  24, 0, 0, 21, 96, 5, 13, 87, 14, 47,
+  59, 16, 0, 0, 0, 0, 0, 111, 0, 0,
+  107, 59, 25, 17, 19, 0, 0, 13, 9, 35,
+  0, 93, 0, 0, 13, 0, 155, 30, 22, 32,
+  0, 0, 34, 19, 0, 47, 0, 0, 15, 14,
+  42, 14, 8, 0, 73, 0, 0, 0, 0, 2,
+  0, 0, 31, 0, 21, 50, 0, 0, 5, 0,
+  30, 31, 0, 67, 22, 0, 17, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 0, 3, 0, 16,
+  53, 0, 3, 16, 0, 0, 0, 0, 0, 145,
+  0, 0, 46, 0, 0, 0, 34, 21, 0, 109,
+  67, 48, 0, 0, 39, 1, 0, 58, 0, 0,
+  0, 56, 1, 0, 0, 0, 49, 0, 0, 0,
+  22, 71, 0, 0, 22, 0, 0, 3, 13, 87,
+  0, 0, 0, 14, 12, 53, 23, 0, 62, 19,
+  29, 0, 0, 0, 0, 48, 0, 0, 12, 0,
+  16, 0, 17, 13, 58, 0, 50, 76, 0, 66,
+  0, 52, 0, 0, 8, 0, 17, 64, 0, 25,
+  19, 0, 22, 2, 35, 128, 0, 0, 75, 0,
+  0, 0, 0, 93, 86, 0, 0, 0, 15, 0,
+  0, 38, 0, 19, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 13, 0,
+  4, 15, 0, 104, 16, 18, 0, 0, 0, 0,
+  47, 19, 0, 0, 6, 0, 7, 17, 36, 23,
+  0, 2, 0, 0, 72, 39, 0, 0, 14, 29,
+  0, 0, 0, 0, 40, 0, 36, 14, 0, 1,
+  11, 0, 0, 0, 22, 32, 0, 52, 25, 0,
+  0, 0, 0, 42, 40, 0, 22, 0, 44, 0,
+  3, 0, 0, 33, 0, 0, 52, 0, 0, 0,
+  0, 10, 106, 0, 39, 32, 46, 45, 0, 59,
+  28, 0, 21, 0, 1, 31, 0, 0, 5, 21,
+  26, 0, 31, 0, 0, 0, 5, 0, 0, 0,
+  0, 52, 28, 23, 1, 0, 7, 59, 48, 1,
+  0, 29, 0, 28, 0, 8, 0, 0, 0, 0,
+  0, 12, 0, 0, 0, 0, 49, 26, 5, 0,
+  107, 66, 16, 65, 30, 0, 0, 17, 71, 14,
+  28, 0, 85, 0, 0, 80, 60, 0, 13, 0,
+  0, 32, 32, 6, 0, 0, 0, 61, 0, 37,
+  19, 69, 10, 6, 18, 5, 0, 44, 103, 0,
+  0, 23, 0, 23, 18, 0, 0, 0, 0, 0,
+  0, 86, 0, 0, 83, 13, 32, 36, 9, 0,
+  0, 0, 0, 0, 15, 55, 0, 0, 11, 0,
+  91, 19, 43, 55, 0, 39, 28, 49, 0, 26,
+  0, 0, 19, 64, 28, 26, 14, 0, 86, 0,
+  32, 0, 0, 14, 0, 0, 66, 0, 5, 67,
+  43, 0, 9, 0, 0, 58, 0, 60, 9, 0,
+  6, 0, 0, 0, 0, 0, 0, 0, 0, 15,
+  0, 4, 0, 18, 46, 15, 12, 30, 14, 0,
+  60, 29, 0, 164, 0, 0, 18, 0, 0, 0,
+  3, 20, 0, 48, 30, 38, 0, 0, 13, 76,
+  24, 1, 0, 0, 0, 35, 0, 48, 0, 88,
+  0, 0, 0, 20, 63, 58, 24, 0, 0, 0,
+  0, 0, 0, 11, 0, 0, 13, 0, 0, 83,
+  0, 0, 99, 0, 57, 0, 22, 0, 0, 57,
+  14, 0, 110, 0, 0, 29, 2, 76, 21, 14,
+  67, 27, 0, 44, 44, 26, 0, 0, 0, 0,
+  32, 108, 0, 10, 10, 0, 11, 0, 10, 13,
+  0, 0, 58, 0, 30, 0, 0, 71, 79, 0,
+  0, 0, 0, 18, 0, 26, 0, 0, 0, 0,
+  0, 0, 4, 4, 54, 0, 0, 35, 0, 18,
+  0, 0, 0, 17, 0, 23, 0, 111, 49, 4,
+  4, 0, 0, 13, 78, 36, 24, 0, 20, 0,
+  0, 97, 83, 24, 24, 5, 0, 0, 48, 50,
+  0, 0, 1, 78, 1, 0, 0, 0, 68, 0,
+  12, 0, 0, 28, 0, 3, 0, 0, 11, 19,
+  11, 36, 0, 0, 0, 29, 0, 18, 44, 0,
+  0, 0, 1, 0, 0, 8, 0, 0, 0, 0,
+  0, 0, 29, 0, 0, 0, 0, 0, 32, 72,
+  9, 90, 0, 112, 2, 20, 35, 0, 0, 53,
+  0, 31, 6, 61, 21, 24, 117, 0, 0, 0,
+  26, 0, 0, 0, 0, 100, 90, 0, 0, 0,
+  7, 0, 54, 21, 0, 21, 0, 0, 0, 15,
+  0, 0, 0, 0, 0, 21, 0, 0, 73, 0,
+  76, 10, 35, 0, 59, 1, 72, 42, 0, 0,
+  0, 22, 38, 13, 13, 6, 0, 7, 0, 21,
+  38, 13, 14, 0, 0, 64, 43, 11, 0, 0,
+  1, 54, 0, 38, 0, 39, 17, 0, 12, 19,
+  36, 29, 3, 0, 0, 0, 0, 0, 0, 11,
+  0, 0, 0, 0, 0, 70, 0, 0, 91, 0,
+  38, 0, 8, 0, 0, 4, 0, 0, 64, 10,
+  0, 0, 0, 114, 20, 0, 74, 27, 0, 45,
+  12, 51, 27, 0, 0, 0, 15, 101, 0, 21,
+  22, 36, 22, 0, 57, 0, 0, 0, 62, 0,
+  29, 0, 0, 72, 95, 0, 0, 0, 0, 80,
+  0, 16, 0, 0, 0, 13, 0, 0, 0, 0,
+  0, 0, 0, 33, 0, 3, 0, 0, 0, 0,
+  4, 22, 21, 0, 99, 34, 0, 157, 0, 0,
+  0, 0, 0, 17, 14, 49, 0, 0, 14, 40,
+  0, 1, 5, 82, 30, 0, 0, 0, 0, 0,
+  0, 147, 4, 78, 0, 24, 0, 23, 87, 19,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+  42, 0, 0, 78, 0, 0, 59, 0, 56, 0,
+  27, 0, 0, 28, 13, 0, 118, 0, 0, 48,
+  0, 113, 0, 36, 68, 0, 0, 7, 28, 0,
+  17, 0, 0, 0, 10, 108, 35, 0, 27, 10,
+  7, 0, 0, 0, 13, 0, 52, 0, 0, 0,
+  0, 5, 41, 0, 0, 0, 0, 82, 0, 16,
+  0, 8, 18, 0, 0, 0, 39, 10, 84, 0,
+  0, 54, 5, 43, 0, 6, 0, 3, 0, 26,
+  104, 21, 0, 47, 20, 66, 0, 0, 53, 0,
+  0, 0, 116, 0, 0, 40, 62, 0, 2, 0,
+  11, 68, 0, 8, 23, 0, 0, 43, 3, 1,
+  13, 72, 0, 27, 24, 0, 0, 21, 96, 5,
+  13, 87, 14, 47, 59, 16, 0, 0, 0, 0,
+  0, 111, 0, 0, 107, 59, 25, 17, 19, 0,
+  0, 13, 9, 35, 0, 93, 0, 0, 13, 0,
+  155, 30, 22, 32, 0, 0, 34, 19, 0, 47,
+  0, 0, 15, 14, 42, 14, 8, 0, 73, 0,
+  0, 0, 0, 2, 0, 0, 31, 0, 21, 50,
+  0, 0, 5, 0, 30, 31, 0, 67, 22, 0,
+  17, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+  0, 3, 0, 16, 53, 0, 3, 16, 0, 0,
+  0, 0, 0, 145, 0, 0, 46, 0, 0, 0,
+  34, 21, 0, 109, 67, 48, 0, 0, 39, 1,
+  0, 58, 0, 0, 0, 56, 1, 0, 0, 0,
+  49, 0, 0, 0, 22, 71, 0, 0, 22, 0,
+  0, 3, 13, 87, 0, 0, 0, 14, 12, 53,
+  23, 0, 62, 19, 29, 0, 0, 0, 0, 48,
+  0, 0, 12, 0, 16, 0, 17, 13, 58, 0,
+  50, 76, 0, 66, 0, 52, 0, 0, 8, 0,
+  17, 64, 0, 25, 19, 0, 22, 2, 35, 128,
+  0, 0, 75, 0, 0, 0, 0, 93, 86, 0,
+  0, 0, 15, 0, 0, 38, 0, 19, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 13, 0, 4, 15, 0, 0, 92, 0,
+  0, 76, 0, 0, 44, 0, 0, 15, 13, 93,
+  0, 13, 41, 74, 27, 0, 22, 35, 4, 32,
+  0, 0, 0, 34, 0, 0, 18, 4, 5, 0,
+  0, 0, 14, 65, 0, 0, 0, 14, 0, 0,
+  0, 18, 0, 0, 0, 0, 19, 112, 26, 0,
+  66, 0, 49, 0, 1, 0, 0, 12, 0, 0,
+  37, 7, 27, 10, 26, 96, 0, 0, 36, 15,
+  0, 30, 0, 21, 0, 0, 0, 0, 33, 83,
+  0, 28, 14, 34, 42, 0, 16, 32, 0, 0,
+  39, 0, 0, 0, 13, 107, 45, 0, 0, 0,
+  3, 18, 0, 20, 0, 5, 17, 0, 0, 0,
+  49, 0, 46, 44, 22, 4, 0, 0, 0, 0,
+  20, 0, 0, 18, 107, 66, 16, 65, 30, 0,
+  0, 17, 71, 14, 28, 0, 85, 0, 0, 80,
+  60, 0, 13, 0, 0, 32, 32, 6, 0, 0,
+  0, 61, 0, 37, 19, 69, 10, 6, 18, 5,
+  0, 44, 103, 0, 0, 23, 0, 23, 18, 0,
+  0, 0, 0, 0, 0, 86, 0, 0, 83, 13,
+  32, 36, 9, 0, 0, 0, 0, 0, 15, 55,
+  0, 0, 11, 0, 91, 19, 43, 55, 0, 39,
+  28, 49, 0, 26, 0, 0, 19, 64, 28, 26,
+  14, 0, 86, 0, 32, 0, 0, 14, 0, 0,
+  66, 0, 5, 67, 43, 0, 9, 0, 0, 58,
+  0, 60, 9, 0, 6, 0, 0, 0, 0, 0,
+  0, 0, 0, 15, 0, 4, 0, 18, 46, 15,
+  12, 30, 14, 0, 60, 29, 0, 164, 0, 0,
+  18, 0, 0, 0, 3, 20, 0, 48, 30, 38,
+  0, 0, 13, 76, 24, 1, 0, 0, 0, 35,
+  0, 48, 0, 88, 0, 0, 0, 20, 63, 58,
+  24, 0, 0, 0, 0, 0, 0, 11, 0, 0,
+  13, 0, 0, 83, 0, 0, 99, 0, 57, 0,
+  22, 0, 0, 57, 14, 0, 110, 0, 0, 29,
+  2, 76, 21, 14, 67, 27, 0, 44, 44, 26,
+  0, 0, 0, 0, 32, 108, 0, 10, 10, 0,
+  11, 0, 10, 13, 0, 0, 58, 0, 30, 0,
+  0, 71, 79, 0, 0, 0, 0, 18, 0, 26,
+  0, 0, 0, 0, 0, 0, 4, 4, 54, 0,
+  0, 35, 0, 18, 0, 0, 0, 17, 0, 23,
+  0, 0, 70, 0, 4, 150, 0, 0, 0, 0,
+  0, 1, 23, 94, 0, 0, 0, 44, 0, 0,
+  21, 54, 0, 39, 0, 0, 0, 0, 0, 45,
+  16, 26, 0, 7, 0, 0, 0, 50, 0, 0,
+  0, 11, 0, 27, 0, 8, 1, 0, 0, 0,
+  12, 123, 0, 0, 39, 0, 39, 0, 42, 0,
+  0, 32, 0, 0, 97, 0, 0, 31, 0, 64,
+  0, 26, 51, 0, 0, 17, 0, 0, 0, 0,
+  0, 0, 27, 70, 21, 0, 16, 15, 54, 0,
+  0, 0, 24, 0, 2, 0, 0, 0, 0, 60,
+  12, 0, 0, 0, 0, 79, 0, 14, 0, 5,
+  25, 0, 0, 14, 51, 41, 105, 41, 29, 52,
+  23, 0, 0, 0, 17, 23, 0, 13, 59, 1,
+  72, 42, 0, 0, 0, 22, 38, 13, 13, 6,
+  0, 7, 0, 21, 38, 13, 14, 0, 0, 64,
+  43, 11, 0, 0, 1, 54, 0, 38, 0, 39,
+  17, 0, 12, 19, 36, 29, 3, 0, 0, 0,
+  0, 0, 0, 11, 0, 0, 0, 0, 0, 70,
+  0, 0, 91, 0, 38, 0, 8, 0, 0, 4,
+  0, 0, 64, 10, 0, 0, 0, 114, 20, 0,
+  74, 27, 0, 45, 12, 51, 27, 0, 0, 0,
+  15, 101, 0, 21, 22, 36, 22, 0, 57, 0,
+  0, 0, 62, 0, 29, 0, 0, 72, 95, 0,
+  0, 0, 0, 80, 0, 16, 0, 0, 0, 13,
+  0, 0, 0, 0, 0, 0, 0, 33, 0, 3,
+  0, 0, 0, 0, 4, 22, 21, 0, 99, 34,
+  0, 157, 0, 0, 0, 0, 0, 17, 14, 49,
+  0, 0, 14, 40, 0, 1, 5, 82, 30, 0,
+  0, 0, 0, 0, 0, 147, 4, 78, 0, 24,
+  0, 23, 87, 19, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 3, 42, 0, 0, 78, 0, 0,
+  59, 0, 56, 0, 27, 0, 0, 28, 13, 0,
+  118, 0, 0, 48, 0, 113, 0, 36, 68, 0,
+  0, 7, 28, 0, 17, 0, 0, 0, 10, 108,
+  35, 0, 27, 10, 7, 0, 0, 0, 13, 0,
+  52, 0, 0, 0, 0, 5, 41, 0, 0, 0,
+  0, 82, 0, 16, 0, 8, 18, 0, 0, 0,
+  39, 10, 84, 0, 0, 54, 5, 43, 0, 6,
+  0, 3, 0, 26, 0, 9, 38, 0, 15, 120,
+  0, 0, 0, 0, 0, 3, 58, 72, 0, 0,
+  0, 18, 0, 18, 44, 0, 0, 51, 0, 3,
+  0, 0, 0, 91, 41, 0, 0, 22, 0, 0,
+  0, 22, 0, 25, 0, 45, 0, 53, 1, 0,
+  0, 32, 0, 0, 0, 70, 11, 0, 0, 0,
+  19, 0, 13, 14, 0, 9, 0, 0, 0, 0,
+  0, 11, 0, 0, 0, 58, 10, 0, 0, 20,
+  0, 0, 2, 19, 0, 27, 10, 28, 51, 0,
+  32, 5, 54, 4, 0, 0, 52, 5, 0, 37,
+  0, 0, 0, 30, 0, 0, 0, 0, 3, 4,
+  0, 16, 10, 25, 57, 0, 0, 17, 37, 0,
+  63, 43, 24, 47, 55, 1, 2, 0, 25, 2,
+  0, 0, 0, 0, 0, 0, 0, 145, 0, 0,
+  46, 0, 0, 0, 34, 21, 0, 109, 67, 48,
+  0, 0, 39, 1, 0, 58, 0, 0, 0, 56,
+  1, 0, 0, 0, 49, 0, 0, 0, 22, 71,
+  0, 0, 22, 0, 0, 3, 13, 87, 0, 0,
+  0, 14, 12, 53, 23, 0, 62, 19, 29, 0,
+  0, 0, 0, 48, 0, 0, 12, 0, 16, 0,
+  17, 13, 58, 0, 50, 76, 0, 66, 0, 52,
+  0, 0, 8, 0, 17, 64, 0, 25, 19, 0,
+  22, 2, 35, 128, 0, 0, 75, 0, 0, 0,
+  0, 93, 86, 0, 0, 0, 15, 0, 0, 38,
+  0, 19, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 13, 0, 4, 15,
+  0, 0, 92, 0, 0, 76, 0, 0, 44, 0,
+  0, 15, 13, 93, 0, 13, 41, 74, 27, 0,
+  22, 35, 4, 32, 0, 0, 0, 34, 0, 0,
+  18, 4, 5, 0, 0, 0, 14, 65, 0, 0,
+  0, 14, 0, 0, 0, 18, 0, 0, 0, 0,
+  19, 112, 26, 0, 66, 0, 49, 0, 1, 0,
+  0, 12, 0, 0, 37, 7, 27, 10, 26, 96,
+  0, 0, 36, 15, 0, 30, 0, 21, 0, 0,
+  0, 0, 33, 83, 0, 28, 14, 34, 42, 0,
+  16, 32, 0, 0, 39, 0, 0, 0, 13, 107,
+  45, 0, 0, 0, 3, 18, 0, 20, 0, 5,
+  17, 0, 0, 0, 49, 0, 46, 44, 22, 4,
+  0, 0, 0, 0, 20, 0, 0, 18, 0, 0,
+  91, 0, 0, 56, 0, 0, 0, 0, 0, 21,
+  6, 68, 0, 0, 3, 66, 22, 26, 0, 44,
+  1, 12, 25, 0, 0, 0, 0, 0, 35, 19,
+  0, 0, 0, 0, 0, 41, 0, 0, 0, 9,
+  0, 13, 0, 4, 17, 0, 0, 0, 11, 90,
+  12, 0, 37, 0, 34, 0, 44, 0, 0, 20,
+  0, 0, 71, 0, 0, 58, 0, 66, 0, 22,
+  34, 0, 4, 12, 0, 0, 14, 0, 0, 0,
+  11, 67, 48, 0, 47, 25, 46, 0, 0, 0,
+  0, 0, 2, 0, 0, 5, 16, 47, 0, 0,
+  0, 1, 0, 93, 0, 9, 0, 23, 27, 12,
+  0, 4, 70, 6, 57, 62, 45, 37, 28, 1,
+  0, 0, 18, 8, 3, 27, 14, 0, 60, 29,
+  0, 164, 0, 0, 18, 0, 0, 0, 3, 20,
+  0, 48, 30, 38, 0, 0, 13, 76, 24, 1,
+  0, 0, 0, 35, 0, 48, 0, 88, 0, 0,
+  0, 20, 63, 58, 24, 0, 0, 0, 0, 0,
+  0, 11, 0, 0, 13, 0, 0, 83, 0, 0,
+  99, 0, 57, 0, 22, 0, 0, 57, 14, 0,
+  110, 0, 0, 29, 2, 76, 21, 14, 67, 27,
+  0, 44, 44, 26, 0, 0, 0, 0, 32, 108,
+  0, 10, 10, 0, 11, 0, 10, 13, 0, 0,
+  58, 0, 30, 0, 0, 71, 79, 0, 0, 0,
+  0, 18, 0, 26, 0, 0, 0, 0, 0, 0,
+  4, 4, 54, 0, 0, 35, 0, 18, 0, 0,
+  0, 17, 0, 23, 0, 0, 70, 0, 4, 150,
+  0, 0, 0, 0, 0, 1, 23, 94, 0, 0,
+  0, 44, 0, 0, 21, 54, 0, 39, 0, 0,
+  0, 0, 0, 45, 16, 26, 0, 7, 0, 0,
+  0, 50, 0, 0, 0, 11, 0, 27, 0, 8,
+  1, 0, 0, 0, 12, 123, 0, 0, 39, 0,
+  39, 0, 42, 0, 0, 32, 0, 0, 97, 0,
+  0, 31, 0, 64, 0, 26, 51, 0, 0, 17,
+  0, 0, 0, 0, 0, 0, 27, 70, 21, 0,
+  16, 15, 54, 0, 0, 0, 24, 0, 2, 0,
+  0, 0, 0, 60, 12, 0, 0, 0, 0, 79,
+  0, 14, 0, 5, 25, 0, 0, 14, 51, 41,
+  105, 41, 29, 52, 23, 0, 0, 0, 17, 23,
+  0, 13, 0, 43, 48, 0, 24, 32, 13, 0,
+  8, 0, 0, 0, 63, 49, 0, 0, 3, 17,
+  8, 10, 0, 0, 0, 37, 41, 35, 6, 0,
+  0, 48, 48, 0, 0, 14, 0, 0, 0, 2,
+  0, 39, 0, 40, 0, 41, 21, 0, 3, 0,
+  0, 0, 0, 40, 61, 0, 0, 0, 14, 6,
+  2, 35, 0, 6, 0, 21, 0, 0, 0, 27,
+  0, 0, 0, 32, 20, 0, 21, 28, 0, 0,
+  0, 25, 16, 25, 21, 40, 63, 0, 39, 18,
+  50, 13, 0, 0, 32, 28, 0, 22, 0, 38,
+  15, 31, 0, 0, 0, 0, 0, 28, 14, 0,
+  53, 57, 40, 0, 0, 20, 46, 0, 33, 38,
+  62, 29, 61, 16, 47, 0, 46, 37, 0, 1,
+  21, 0, 99, 34, 0, 157, 0, 0, 0, 0,
+  0, 17, 14, 49, 0, 0, 14, 40, 0, 1,
+  5, 82, 30, 0, 0, 0, 0, 0, 0, 147,
+  4, 78, 0, 24, 0, 23, 87, 19, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 3, 42, 0,
+  0, 78, 0, 0, 59, 0, 56, 0, 27, 0,
+  0, 28, 13, 0, 118, 0, 0, 48, 0, 113,
+  0, 36, 68, 0, 0, 7, 28, 0, 17, 0,
+  0, 0, 10, 108, 35, 0, 27, 10, 7, 0,
+  0, 0, 13, 0, 52, 0, 0, 0, 0, 5,
+  41, 0, 0, 0, 0, 82, 0, 16, 0, 8,
+  18, 0, 0, 0, 39, 10, 84, 0, 0, 54,
+  5, 43, 0, 6, 0, 3, 0, 26, 0, 9,
+  38, 0, 15, 120, 0, 0, 0, 0, 0, 3,
+  58, 72, 0, 0, 0, 18, 0, 18, 44, 0,
+  0, 51, 0, 3, 0, 0, 0, 91, 41, 0,
+  0, 22, 0, 0, 0, 22, 0, 25, 0, 45,
+  0, 53, 1, 0, 0, 32, 0, 0, 0, 70,
+  11, 0, 0, 0, 19, 0, 13, 14, 0, 9,
+  0, 0, 0, 0, 0, 11, 0, 0, 0, 58,
+  10, 0, 0, 20, 0, 0, 2, 19, 0, 27,
+  10, 28, 51, 0, 32, 5, 54, 4, 0, 0,
+  52, 5, 0, 37, 0, 0, 0, 30, 0, 0,
+  0, 0, 3, 4, 0, 16, 10, 25, 57, 0,
+  0, 17, 37, 0, 63, 43, 24, 47, 55, 1,
+  2, 0, 25, 2, 0, 0, 0, 70, 65, 0,
+  63, 0, 15, 0, 1, 0, 14, 0, 64, 75,
+  0, 51, 17, 7, 26, 16, 9, 0, 0, 47,
+  38, 59, 0, 0, 0, 0, 53, 0, 0, 37,
+  12, 0, 0, 0, 0, 53, 50, 43, 24, 71,
+  73, 0, 0, 0, 0, 0, 0, 26, 50, 0,
+  0, 0, 0, 20, 1, 27, 24, 0, 0, 63,
+  0, 2, 29, 0, 0, 0, 0, 0, 7, 41,
+  16, 12, 0, 17, 0, 23, 46, 34, 33, 22,
+  87, 14, 32, 4, 49, 40, 0, 20, 24, 31,
+  0, 54, 0, 35, 3, 41, 0, 0, 0, 0,
+  0, 0, 7, 10, 34, 32, 82, 0, 0, 13,
+  31, 0, 0, 29, 54, 8, 7, 0, 55, 0,
+  75, 11, 2, 0, 0, 0, 92, 0, 0, 76,
+  0, 0, 44, 0, 0, 15, 13, 93, 0, 13,
+  41, 74, 27, 0, 22, 35, 4, 32, 0, 0,
+  0, 34, 0, 0, 18, 4, 5, 0, 0, 0,
+  14, 65, 0, 0, 0, 14, 0, 0, 0, 18,
+  0, 0, 0, 0, 19, 112, 26, 0, 66, 0,
+  49, 0, 1, 0, 0, 12, 0, 0, 37, 7,
+  27, 10, 26, 96, 0, 0, 36, 15, 0, 30,
+  0, 21, 0, 0, 0, 0, 33, 83, 0, 28,
+  14, 34, 42, 0, 16, 32, 0, 0, 39, 0,
+  0, 0, 13, 107, 45, 0, 0, 0, 3, 18,
+  0, 20, 0, 5, 17, 0, 0, 0, 49, 0,
+  46, 44, 22, 4, 0, 0, 0, 0, 20, 0,
+  0, 18, 0, 0, 91, 0, 0, 56, 0, 0,
+  0, 0, 0, 21, 6, 68, 0, 0, 3, 66,
+  22, 26, 0, 44, 1, 12, 25, 0, 0, 0,
+  0, 0, 35, 19, 0, 0, 0, 0, 0, 41,
+  0, 0, 0, 9, 0, 13, 0, 4, 17, 0,
+  0, 0, 11, 90, 12, 0, 37, 0, 34, 0,
+  44, 0, 0, 20, 0, 0, 71, 0, 0, 58,
+  0, 66, 0, 22, 34, 0, 4, 12, 0, 0,
+  14, 0, 0, 0, 11, 67, 48, 0, 47, 25,
+  46, 0, 0, 0, 0, 0, 2, 0, 0, 5,
+  16, 47, 0, 0, 0, 1, 0, 93, 0, 9,
+  0, 23, 27, 12, 0, 4, 70, 6, 57, 62,
+  45, 37, 28, 1, 0, 0, 18, 8, 3, 27,
+  0, 16, 49, 0, 0, 5, 31, 0, 1, 0,
+  0, 6, 0, 41, 0, 0, 0, 25, 35, 4,
+  0, 0, 0, 52, 24, 0, 16, 5, 179, 11,
+  21, 0, 23, 0, 0, 0, 0, 11, 0, 43,
+  0, 24, 1, 8, 2, 65, 31, 0, 0, 0,
+  0, 37, 49, 0, 7, 0, 6, 0, 40, 14,
+  28, 28, 0, 0, 0, 18, 44, 18, 0, 7,
+  0, 39, 35, 0, 13, 18, 0, 0, 20, 0,
+  17, 2, 0, 51, 0, 0, 32, 30, 78, 35,
+  0, 0, 40, 0, 0, 22, 0, 0, 33, 23,
+  14, 18, 8, 0, 15, 74, 44, 16, 21, 36,
+  0, 12, 0, 0, 6, 34, 56, 40, 46, 34,
+  33, 8, 0, 0, 18, 0, 14, 30, 0, 0,
+  70, 0, 4, 150, 0, 0, 0, 0, 0, 1,
+  23, 94, 0, 0, 0, 44, 0, 0, 21, 54,
+  0, 39, 0, 0, 0, 0, 0, 45, 16, 26,
+  0, 7, 0, 0, 0, 50, 0, 0, 0, 11,
+  0, 27, 0, 8, 1, 0, 0, 0, 12, 123,
+  0, 0, 39, 0, 39, 0, 42, 0, 0, 32,
+  0, 0, 97, 0, 0, 31, 0, 64, 0, 26,
+  51, 0, 0, 17, 0, 0, 0, 0, 0, 0,
+  27, 70, 21, 0, 16, 15, 54, 0, 0, 0,
+  24, 0, 2, 0, 0, 0, 0, 60, 12, 0,
+  0, 0, 0, 79, 0, 14, 0, 5, 25, 0,
+  0, 14, 51, 41, 105, 41, 29, 52, 23, 0,
+  0, 0, 17, 23, 0, 13, 0, 43, 48, 0,
+  24, 32, 13, 0, 8, 0, 0, 0, 63, 49,
+  0, 0, 3, 17, 8, 10, 0, 0, 0, 37,
+  41, 35, 6, 0, 0, 48, 48, 0, 0, 14,
+  0, 0, 0, 2, 0, 39, 0, 40, 0, 41,
+  21, 0, 3, 0, 0, 0, 0, 40, 61, 0,
+  0, 0, 14, 6, 2, 35, 0, 6, 0, 21,
+  0, 0, 0, 27, 0, 0, 0, 32, 20, 0,
+  21, 28, 0, 0, 0, 25, 16, 25, 21, 40,
+  63, 0, 39, 18, 50, 13, 0, 0, 32, 28,
+  0, 22, 0, 38, 15, 31, 0, 0, 0, 0,
+  0, 28, 14, 0, 53, 57, 40, 0, 0, 20,
+  46, 0, 33, 38, 62, 29, 61, 16, 47, 0,
+  46, 37, 0, 1, 0, 41, 74, 0, 7, 0,
+  37, 0, 26, 0, 0, 0, 8, 45, 0, 15,
+  14, 0, 13, 0, 0, 0, 20, 55, 23, 53,
+  16, 0, 159, 1, 19, 0, 8, 19, 20, 0,
+  0, 0, 0, 81, 7, 52, 28, 35, 49, 21,
+  9, 3, 0, 0, 0, 24, 50, 0, 0, 0,
+  1, 33, 4, 24, 7, 14, 0, 0, 0, 27,
+  51, 0, 10, 0, 0, 31, 38, 26, 32, 14,
+  0, 0, 0, 32, 48, 29, 26, 13, 31, 0,
+  3, 25, 74, 17, 4, 0, 45, 17, 0, 32,
+  0, 0, 21, 15, 0, 0, 0, 0, 6, 22,
+  50, 8, 38, 32, 47, 0, 0, 0, 1, 0,
+  13, 0, 30, 2, 0, 0, 24, 0, 46, 24,
+  32, 0, 0, 9, 38, 0, 15, 120, 0, 0,
+  0, 0, 0, 3, 58, 72, 0, 0, 0, 18,
+  0, 18, 44, 0, 0, 51, 0, 3, 0, 0,
+  0, 91, 41, 0, 0, 22, 0, 0, 0, 22,
+  0, 25, 0, 45, 0, 53, 1, 0, 0, 32,
+  0, 0, 0, 70, 11, 0, 0, 0, 19, 0,
+  13, 14, 0, 9, 0, 0, 0, 0, 0, 11,
+  0, 0, 0, 58, 10, 0, 0, 20, 0, 0,
+  2, 19, 0, 27, 10, 28, 51, 0, 32, 5,
+  54, 4, 0, 0, 52, 5, 0, 37, 0, 0,
+  0, 30, 0, 0, 0, 0, 3, 4, 0, 16,
+  10, 25, 57, 0, 0, 17, 37, 0, 63, 43,
+  24, 47, 55, 1, 2, 0, 25, 2, 0, 0,
+  0, 70, 65, 0, 63, 0, 15, 0, 1, 0,
+  14, 0, 64, 75, 0, 51, 17, 7, 26, 16,
+  9, 0, 0, 47, 38, 59, 0, 0, 0, 0,
+  53, 0, 0, 37, 12, 0, 0, 0, 0, 53,
+  50, 43, 24, 71, 73, 0, 0, 0, 0, 0,
+  0, 26, 50, 0, 0, 0, 0, 20, 1, 27,
+  24, 0, 0, 63, 0, 2, 29, 0, 0, 0,
+  0, 0, 7, 41, 16, 12, 0, 17, 0, 23,
+  46, 34, 33, 22, 87, 14, 32, 4, 49, 40,
+  0, 20, 24, 31, 0, 54, 0, 35, 3, 41,
+  0, 0, 0, 0, 0, 0, 7, 10, 34, 32,
+  82, 0, 0, 13, 31, 0, 0, 29, 54, 8,
+  7, 0, 55, 0, 75, 11, 2, 0, 0, 0,
+  119, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 103, 0, 9, 0, 6, 10, 5, 9, 50,
+  108, 24, 0, 0, 0, 8, 184, 0, 22, 0,
+  0, 31, 0, 0, 11, 12, 0, 10, 106, 0,
+  19, 21, 57, 33, 0, 2, 16, 0, 0, 65,
+  0, 0, 30, 0, 14, 26, 31, 0, 30, 40,
+  20, 0, 16, 5, 36, 0, 0, 70, 0, 0,
+  38, 61, 0, 0, 13, 0, 0, 0, 25, 10,
+  0, 19, 7, 11, 0, 47, 49, 0, 0, 54,
+  39, 0, 33, 24, 0, 0, 0, 22, 19, 7,
+  17, 0, 40, 27, 0, 5, 0, 0, 50, 3,
+  0, 0, 37, 20, 52, 0, 0, 30, 0, 0,
+  0, 0, 2, 25, 2, 0, 0, 0, 91, 0,
+  0, 56, 0, 0, 0, 0, 0, 21, 6, 68,
+  0, 0, 3, 66, 22, 26, 0, 44, 1, 12,
+  25, 0, 0, 0, 0, 0, 35, 19, 0, 0,
+  0, 0, 0, 41, 0, 0, 0, 9, 0, 13,
+  0, 4, 17, 0, 0, 0, 11, 90, 12, 0,
+  37, 0, 34, 0, 44, 0, 0, 20, 0, 0,
+  71, 0, 0, 58, 0, 66, 0, 22, 34, 0,
+  4, 12, 0, 0, 14, 0, 0, 0, 11, 67,
+  48, 0, 47, 25, 46, 0, 0, 0, 0, 0,
+  2, 0, 0, 5, 16, 47, 0, 0, 0, 1,
+  0, 93, 0, 9, 0, 23, 27, 12, 0, 4,
+  70, 6, 57, 62, 45, 37, 28, 1, 0, 0,
+  18, 8, 3, 27, 0, 16, 49, 0, 0, 5,
+  31, 0, 1, 0, 0, 6, 0, 41, 0, 0,
+  0, 25, 35, 4, 0, 0, 0, 52, 24, 0,
+  16, 5, 179, 11, 21, 0, 23, 0, 0, 0,
+  0, 11, 0, 43, 0, 24, 1, 8, 2, 65,
+  31, 0, 0, 0, 0, 37, 49, 0, 7, 0,
+  6, 0, 40, 14, 28, 28, 0, 0, 0, 18,
+  44, 18, 0, 7, 0, 39, 35, 0, 13, 18,
+  0, 0, 20, 0, 17, 2, 0, 51, 0, 0,
+  32, 30, 78, 35, 0, 0, 40, 0, 0, 22,
+  0, 0, 33, 23, 14, 18, 8, 0, 15, 74,
+  44, 16, 21, 36, 0, 12, 0, 0, 6, 34,
+  56, 40, 46, 34, 33, 8, 0, 0, 18, 0,
+  14, 30, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 43, 48, 0, 24, 32, 13, 0, 8, 0,
+  0, 0, 63, 49, 0, 0, 3, 17, 8, 10,
+  0, 0, 0, 37, 41, 35, 6, 0, 0, 48,
+  48, 0, 0, 14, 0, 0, 0, 2, 0, 39,
+  0, 40, 0, 41, 21, 0, 3, 0, 0, 0,
+  0, 40, 61, 0, 0, 0, 14, 6, 2, 35,
+  0, 6, 0, 21, 0, 0, 0, 27, 0, 0,
+  0, 32, 20, 0, 21, 28, 0, 0, 0, 25,
+  16, 25, 21, 40, 63, 0, 39, 18, 50, 13,
+  0, 0, 32, 28, 0, 22, 0, 38, 15, 31,
+  0, 0, 0, 0, 0, 28, 14, 0, 53, 57,
+  40, 0, 0, 20, 46, 0, 33, 38, 62, 29,
+  61, 16, 47, 0, 46, 37, 0, 1, 0, 41,
+  74, 0, 7, 0, 37, 0, 26, 0, 0, 0,
+  8, 45, 0, 15, 14, 0, 13, 0, 0, 0,
+  20, 55, 23, 53, 16, 0, 159, 1, 19, 0,
+  8, 19, 20, 0, 0, 0, 0, 81, 7, 52,
+  28, 35, 49, 21, 9, 3, 0, 0, 0, 24,
+  50, 0, 0, 0, 1, 33, 4, 24, 7, 14,
+  0, 0, 0, 27, 51, 0, 10, 0, 0, 31,
+  38, 26, 32, 14, 0, 0, 0, 32, 48, 29,
+  26, 13, 31, 0, 3, 25, 74, 17, 4, 0,
+  45, 17, 0, 32, 0, 0, 21, 15, 0, 0,
+  0, 0, 6, 22, 50, 8, 38, 32, 47, 0,
+  0, 0, 1, 0, 13, 0, 30, 2, 0, 0,
+  24, 0, 46, 24, 32, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 70, 65, 0, 63, 0,
+  15, 0, 1, 0, 14, 0, 64, 75, 0, 51,
+  17, 7, 26, 16, 9, 0, 0, 47, 38, 59,
+  0, 0, 0, 0, 53, 0, 0, 37, 12, 0,
+  0, 0, 0, 53, 50, 43, 24, 71, 73, 0,
+  0, 0, 0, 0, 0, 26, 50, 0, 0, 0,
+  0, 20, 1, 27, 24, 0, 0, 63, 0, 2,
+  29, 0, 0, 0, 0, 0, 7, 41, 16, 12,
+  0, 17, 0, 23, 46, 34, 33, 22, 87, 14,
+  32, 4, 49, 40, 0, 20, 24, 31, 0, 54,
+  0, 35, 3, 41, 0, 0, 0, 0, 0, 0,
+  7, 10, 34, 32, 82, 0, 0, 13, 31, 0,
+  0, 29, 54, 8, 7, 0, 55, 0, 75, 11,
+  2, 0, 0, 0, 119, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 103, 0, 9, 0, 6,
+  10, 5, 9, 50, 108, 24, 0, 0, 0, 8,
+  184, 0, 22, 0, 0, 31, 0, 0, 11, 12,
+  0, 10, 106, 0, 19, 21, 57, 33, 0, 2,
+  16, 0, 0, 65, 0, 0, 30, 0, 14, 26,
+  31, 0, 30, 40, 20, 0, 16, 5, 36, 0,
+  0, 70, 0, 0, 38, 61, 0, 0, 13, 0,
+  0, 0, 25, 10, 0, 19, 7, 11, 0, 47,
+  49, 0, 0, 54, 39, 0, 33, 24, 0, 0,
+  0, 22, 19, 7, 17, 0, 40, 27, 0, 5,
+  0, 0, 50, 3, 0, 0, 37, 20, 52, 0,
+  0, 30, 0, 0, 0, 0, 2, 25, 2, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 47, 23, 86, 28,
+  0, 0, 29, 6, 18, 0, 12, 0, 0, 94,
+  0, 55, 94, 25, 14, 29, 7, 39, 13, 18,
+  25, 0, 29, 32, 164, 9, 5, 45, 79, 0,
+  0, 0, 0, 37, 0, 0, 0, 4, 0, 10,
+  7, 71, 53, 0, 0, 0, 0, 40, 22, 15,
+  17, 0, 13, 0, 0, 3, 39, 29, 0, 0,
+  0, 0, 72, 0, 119, 51, 0, 0, 21, 0,
+  24, 0, 65, 11, 0, 23, 14, 0, 42, 0,
+  0, 26, 0, 0, 59, 5, 0, 16, 0, 5,
+  15, 0, 38, 1, 14, 93, 25, 0, 14, 51,
+  54, 47, 12, 0, 25, 0, 4, 10, 0, 41,
+  10, 0, 18, 0, 17, 0, 59, 0, 0, 0,
+  0, 24, 48, 21, 43, 69, 0, 8, 5, 11,
+  0, 0, 0, 0, 0, 0, 16, 73, 0, 0,
+  82, 18, 0, 0, 0, 41, 0, 50, 15, 0,
+  5, 16, 0, 0, 0, 19, 83, 23, 0, 0,
+  0, 9, 0, 0, 0, 6, 0, 0, 9, 74,
+  35, 102, 0, 0, 0, 29, 56, 0, 22, 0,
+  18, 0, 0, 0, 78, 24, 0, 51, 0, 0,
+  97, 0, 107, 49, 0, 0, 4, 13, 45, 0,
+  27, 0, 0, 5, 25, 0, 35, 12, 0, 12,
+  0, 6, 0, 6, 0, 26, 0, 19, 1, 0,
+  34, 0, 12, 95, 20, 81, 35, 21, 44, 44,
+  10, 0, 51, 0, 0, 63, 0, 7, 0, 0,
+  0, 0, 11, 0, 22, 0, 33, 0, 0, 27,
+  27, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  23, 32, 93, 27, 1, 9, 26, 5, 18, 0,
+  0, 0, 0, 103, 0, 30, 67, 4, 0, 16,
+  13, 75, 10, 41, 20, 0, 6, 20, 201, 42,
+  3, 62, 71, 0, 24, 0, 0, 56, 0, 4,
+  5, 32, 0, 22, 9, 88, 48, 0, 0, 0,
+  0, 51, 21, 3, 55, 0, 44, 0, 32, 0,
+  31, 72, 0, 0, 0, 0, 48, 9, 120, 30,
+  0, 10, 58, 0, 32, 0, 53, 0, 0, 37,
+  0, 0, 36, 11, 0, 15, 0, 0, 58, 5,
+  0, 0, 0, 3, 0, 36, 0, 0, 40, 101,
+  17, 0, 0, 52, 55, 89, 20, 0, 9, 0,
+  2, 9, 0, 33, 6, 2, 40, 0, 19, 12,
+  51, 0, 0, 0, 3, 0, 39, 30, 0, 67,
+  0, 11, 0, 33, 2, 0, 0, 0, 0, 17,
+  28, 49, 0, 0, 52, 3, 0, 0, 28, 58,
+  0, 42, 19, 0, 0, 8, 0, 9, 0, 26,
+  82, 21, 0, 0, 0, 27, 0, 8, 0, 40,
+  0, 22, 24, 91, 9, 110, 0, 0, 0, 27,
+  50, 0, 37, 0, 28, 0, 14, 0, 55, 50,
+  0, 43, 0, 0, 49, 11, 81, 0, 4, 0,
+  22, 7, 42, 0, 12, 0, 0, 26, 21, 0,
+  21, 24, 0, 0, 0, 0, 0, 9, 0, 0,
+  0, 9, 0, 20, 0, 0, 47, 83, 0, 52,
+  17, 21, 41, 51, 25, 0, 40, 5, 0, 40,
+  0, 11, 0, 0, 21, 0, 13, 13, 31, 0,
+  15, 0, 35, 1, 15, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 13, 24, 67, 6, 0, 18,
+  27, 22, 0, 0, 0, 0, 0, 97, 0, 0,
+  60, 4, 0, 5, 27, 86, 27, 52, 0, 0,
+  8, 9, 193, 55, 1, 28, 52, 0, 59, 1,
+  0, 58, 0, 17, 14, 39, 0, 14, 26, 83,
+  17, 0, 2, 0, 0, 64, 30, 0, 71, 0,
+  60, 0, 49, 0, 15, 71, 0, 0, 0, 0,
+  7, 6, 77, 33, 0, 22, 82, 11, 31, 27,
+  25, 0, 20, 13, 0, 0, 15, 5, 0, 0,
+  0, 0, 62, 3, 0, 0, 23, 0, 15, 37,
+  0, 0, 49, 67, 15, 0, 0, 37, 46, 75,
+  26, 0, 0, 6, 1, 16, 0, 37, 12, 0,
+  55, 0, 9, 28, 40, 0, 0, 0, 4, 0,
+  26, 26, 0, 60, 0, 15, 0, 5, 36, 23,
+  2, 0, 0, 31, 86, 8, 0, 0, 59, 11,
+  0, 0, 65, 56, 0, 25, 23, 0, 0, 13,
+  0, 13, 0, 11, 92, 0, 18, 0, 0, 32,
+  0, 53, 0, 28, 0, 44, 48, 94, 4, 86,
+  0, 7, 0, 38, 52, 0, 35, 0, 21, 0,
+  24, 0, 13, 27, 0, 40, 0, 11, 10, 0,
+  33, 0, 8, 0, 25, 13, 37, 0, 0, 0,
+  0, 15, 39, 0, 14, 13, 0, 0, 0, 0,
+  0, 24, 0, 0, 0, 13, 0, 47, 0, 0,
+  62, 50, 3, 0, 0, 13, 20, 1, 44, 0,
+  24, 28, 0, 29, 0, 15, 0, 0, 25, 0,
+  11, 10, 47, 0, 42, 0, 79, 0, 14, 0,
+  47, 23, 86, 28, 0, 0, 29, 6, 18, 0,
+  12, 0, 0, 94, 0, 55, 94, 25, 14, 29,
+  7, 39, 13, 18, 25, 0, 29, 32, 164, 9,
+  5, 45, 79, 0, 0, 0, 0, 37, 0, 0,
+  0, 4, 0, 10, 7, 71, 53, 0, 0, 0,
+  0, 40, 22, 15, 17, 0, 13, 0, 0, 3,
+  39, 29, 0, 0, 0, 0, 72, 0, 119, 51,
+  0, 0, 21, 0, 24, 0, 65, 11, 0, 23,
+  14, 0, 42, 0, 0, 26, 0, 0, 59, 5,
+  0, 16, 0, 5, 15, 0, 38, 1, 14, 93,
+  25, 0, 14, 51, 54, 47, 12, 0, 25, 0,
+  4, 10, 0, 41, 10, 0, 18, 0, 17, 0,
+  59, 0, 0, 0, 0, 24, 48, 21, 43, 69,
+  0, 8, 5, 11, 0, 0, 0, 0, 0, 0,
+  16, 73, 0, 0, 82, 18, 0, 0, 0, 41,
+  0, 50, 15, 0, 5, 16, 0, 0, 0, 19,
+  83, 23, 0, 0, 0, 9, 0, 0, 0, 6,
+  0, 0, 9, 74, 35, 102, 0, 0, 0, 29,
+  56, 0, 22, 0, 18, 0, 0, 0, 78, 24,
+  0, 51, 0, 0, 97, 0, 107, 49, 0, 0,
+  4, 13, 45, 0, 27, 0, 0, 5, 25, 0,
+  35, 12, 0, 12, 0, 6, 0, 6, 0, 26,
+  0, 19, 1, 0, 34, 0, 12, 95, 20, 81,
+  35, 21, 44, 44, 10, 0, 51, 0, 0, 63,
+  0, 7, 0, 0, 0, 0, 11, 0, 22, 0,
+  33, 0, 0, 27, 27, 0, 0, 39, 39, 29,
+  0, 48, 7, 15, 23, 0, 0, 11, 81, 0,
+  0, 23, 58, 7, 0, 0, 0, 63, 0, 21,
+  41, 0, 0, 12, 0, 0, 0, 32, 67, 3,
+  1, 0, 0, 13, 0, 47, 0, 18, 41, 13,
+  22, 69, 25, 53, 0, 12, 0, 37, 21, 7,
+  22, 0, 22, 0, 0, 0, 16, 31, 0, 29,
+  0, 0, 7, 0, 37, 0, 18, 0, 9, 21,
+  4, 0, 5, 11, 0, 39, 27, 0, 62, 62,
+  0, 0, 0, 0, 0, 18, 1, 0, 0, 19,
+  0, 19, 32, 0, 0, 78, 11, 0, 0, 10,
+  15, 0, 33, 0, 0, 0, 0, 8, 0, 0,
+  0, 0, 7, 0, 0, 0, 0, 0, 38, 0,
+  39, 0, 9, 0, 23, 32, 93, 27, 1, 9,
+  26, 5, 18, 0, 0, 0, 0, 103, 0, 30,
+  67, 4, 0, 16, 13, 75, 10, 41, 20, 0,
+  6, 20, 201, 42, 3, 62, 71, 0, 24, 0,
+  0, 56, 0, 4, 5, 32, 0, 22, 9, 88,
+  48, 0, 0, 0, 0, 51, 21, 3, 55, 0,
+  44, 0, 32, 0, 31, 72, 0, 0, 0, 0,
+  48, 9, 120, 30, 0, 10, 58, 0, 32, 0,
+  53, 0, 0, 37, 0, 0, 36, 11, 0, 15,
+  0, 0, 58, 5, 0, 0, 0, 3, 0, 36,
+  0, 0, 40, 101, 17, 0, 0, 52, 55, 89,
+  20, 0, 9, 0, 2, 9, 0, 33, 6, 2,
+  40, 0, 19, 12, 51, 0, 0, 0, 3, 0,
+  39, 30, 0, 67, 0, 11, 0, 33, 2, 0,
+  0, 0, 0, 17, 28, 49, 0, 0, 52, 3,
+  0, 0, 28, 58, 0, 42, 19, 0, 0, 8,
+  0, 9, 0, 26, 82, 21, 0, 0, 0, 27,
+  0, 8, 0, 40, 0, 22, 24, 91, 9, 110,
+  0, 0, 0, 27, 50, 0, 37, 0, 28, 0,
+  14, 0, 55, 50, 0, 43, 0, 0, 49, 11,
+  81, 0, 4, 0, 22, 7, 42, 0, 12, 0,
+  0, 26, 21, 0, 21, 24, 0, 0, 0, 0,
+  0, 9, 0, 0, 0, 9, 0, 20, 0, 0,
+  47, 83, 0, 52, 17, 21, 41, 51, 25, 0,
+  40, 5, 0, 40, 0, 11, 0, 0, 21, 0,
+  13, 13, 31, 0, 15, 0, 35, 1, 15, 0,
+  0, 27, 36, 37, 0, 42, 17, 9, 15, 0,
+  0, 22, 97, 0, 7, 27, 55, 8, 0, 0,
+  0, 69, 0, 8, 46, 0, 0, 20, 0, 2,
+  0, 37, 78, 0, 3, 0, 0, 24, 0, 73,
+  0, 34, 30, 29, 29, 57, 25, 42, 0, 28,
+  0, 43, 34, 9, 17, 0, 10, 0, 0, 0,
+  6, 14, 0, 16, 0, 0, 0, 0, 28, 0,
+  23, 6, 0, 10, 7, 0, 0, 23, 0, 35,
+  38, 0, 52, 56, 0, 0, 11, 0, 0, 18,
+  0, 0, 0, 4, 0, 16, 29, 0, 0, 66,
+  6, 0, 0, 10, 18, 0, 38, 0, 0, 6,
+  0, 7, 0, 1, 0, 0, 17, 0, 0, 0,
+  5, 0, 43, 0, 63, 0, 11, 0, 13, 24,
+  67, 6, 0, 18, 27, 22, 0, 0, 0, 0,
+  0, 97, 0, 0, 60, 4, 0, 5, 27, 86,
+  27, 52, 0, 0, 8, 9, 193, 55, 1, 28,
+  52, 0, 59, 1, 0, 58, 0, 17, 14, 39,
+  0, 14, 26, 83, 17, 0, 2, 0, 0, 64,
+  30, 0, 71, 0, 60, 0, 49, 0, 15, 71,
+  0, 0, 0, 0, 7, 6, 77, 33, 0, 22,
+  82, 11, 31, 27, 25, 0, 20, 13, 0, 0,
+  15, 5, 0, 0, 0, 0, 62, 3, 0, 0,
+  23, 0, 15, 37, 0, 0, 49, 67, 15, 0,
+  0, 37, 46, 75, 26, 0, 0, 6, 1, 16,
+  0, 37, 12, 0, 55, 0, 9, 28, 40, 0,
+  0, 0, 4, 0, 26, 26, 0, 60, 0, 15,
+  0, 5, 36, 23, 2, 0, 0, 31, 86, 8,
+  0, 0, 59, 11, 0, 0, 65, 56, 0, 25,
+  23, 0, 0, 13, 0, 13, 0, 11, 92, 0,
+  18, 0, 0, 32, 0, 53, 0, 28, 0, 44,
+  48, 94, 4, 86, 0, 7, 0, 38, 52, 0,
+  35, 0, 21, 0, 24, 0, 13, 27, 0, 40,
+  0, 11, 10, 0, 33, 0, 8, 0, 25, 13,
+  37, 0, 0, 0, 0, 15, 39, 0, 14, 13,
+  0, 0, 0, 0, 0, 24, 0, 0, 0, 13,
+  0, 47, 0, 0, 62, 50, 3, 0, 0, 13,
+  20, 1, 44, 0, 24, 28, 0, 29, 0, 15,
+  0, 0, 25, 0, 11, 10, 47, 0, 42, 0,
+  79, 0, 14, 0, 3, 28, 40, 34, 0, 19,
+  25, 3, 20, 0, 0, 31, 114, 0, 21, 37,
+  61, 3, 0, 0, 0, 74, 0, 5, 57, 0,
+  0, 30, 0, 1, 0, 41, 79, 0, 10, 0,
+  0, 27, 0, 80, 0, 41, 32, 32, 31, 55,
+  32, 23, 0, 44, 0, 50, 31, 17, 17, 0,
+  7, 0, 0, 0, 12, 0, 0, 36, 0, 0,
+  4, 0, 28, 0, 17, 10, 0, 3, 3, 0,
+  15, 36, 0, 33, 36, 0, 51, 45, 0, 0,
+  5, 0, 0, 36, 0, 0, 0, 5, 0, 25,
+  33, 0, 3, 68, 5, 0, 5, 7, 24, 0,
+  28, 0, 2, 10, 6, 14, 0, 1, 0, 0,
+  2, 0, 6, 0, 15, 4, 59, 0, 74, 0,
+  21, 0, 43, 69, 0, 8, 5, 11, 0, 0,
+  0, 0, 0, 0, 16, 73, 0, 0, 82, 18,
+  0, 0, 0, 41, 0, 50, 15, 0, 5, 16,
+  0, 0, 0, 19, 83, 23, 0, 0, 0, 9,
+  0, 0, 0, 6, 0, 0, 9, 74, 35, 102,
+  0, 0, 0, 29, 56, 0, 22, 0, 18, 0,
+  0, 0, 78, 24, 0, 51, 0, 0, 97, 0,
+  107, 49, 0, 0, 4, 13, 45, 0, 27, 0,
+  0, 5, 25, 0, 35, 12, 0, 12, 0, 6,
+  0, 6, 0, 26, 0, 19, 1, 0, 34, 0,
+  12, 95, 20, 81, 35, 21, 44, 44, 10, 0,
+  51, 0, 0, 63, 0, 7, 0, 0, 0, 0,
+  11, 0, 22, 0, 33, 0, 0, 27, 27, 0,
+  0, 39, 39, 29, 0, 48, 7, 15, 23, 0,
+  0, 11, 81, 0, 0, 23, 58, 7, 0, 0,
+  0, 63, 0, 21, 41, 0, 0, 12, 0, 0,
+  0, 32, 67, 3, 1, 0, 0, 13, 0, 47,
+  0, 18, 41, 13, 22, 69, 25, 53, 0, 12,
+  0, 37, 21, 7, 22, 0, 22, 0, 0, 0,
+  16, 31, 0, 29, 0, 0, 7, 0, 37, 0,
+  18, 0, 9, 21, 4, 0, 5, 11, 0, 39,
+  27, 0, 62, 62, 0, 0, 0, 0, 0, 18,
+  1, 0, 0, 19, 0, 19, 32, 0, 0, 78,
+  11, 0, 0, 10, 15, 0, 33, 0, 0, 0,
+  0, 8, 0, 0, 0, 0, 7, 0, 0, 0,
+  0, 0, 38, 0, 39, 0, 9, 0, 0, 0,
+  0, 12, 0, 128, 4, 0, 24, 0, 0, 24,
+  44, 0, 0, 3, 15, 0, 0, 0, 17, 87,
+  14, 19, 11, 0, 0, 0, 0, 0, 0, 22,
+  19, 26, 0, 6, 0, 37, 0, 56, 0, 21,
+  0, 56, 0, 77, 54, 47, 0, 0, 0, 41,
+  15, 0, 2, 0, 67, 0, 29, 0, 3, 66,
+  0, 12, 54, 5, 0, 16, 73, 0, 77, 17,
+  14, 1, 0, 19, 20, 20, 0, 39, 27, 0,
+  45, 41, 10, 0, 5, 0, 0, 0, 0, 17,
+  0, 0, 0, 33, 0, 0, 7, 75, 14, 0,
+  0, 3, 5, 0, 19, 0, 0, 0, 0, 0,
+  0, 14, 0, 0, 93, 0, 37, 0, 0, 0,
+  0, 0, 36, 0, 0, 0, 0, 67, 0, 11,
+  0, 33, 2, 0, 0, 0, 0, 17, 28, 49,
+  0, 0, 52, 3, 0, 0, 28, 58, 0, 42,
+  19, 0, 0, 8, 0, 9, 0, 26, 82, 21,
+  0, 0, 0, 27, 0, 8, 0, 40, 0, 22,
+  24, 91, 9, 110, 0, 0, 0, 27, 50, 0,
+  37, 0, 28, 0, 14, 0, 55, 50, 0, 43,
+  0, 0, 49, 11, 81, 0, 4, 0, 22, 7,
+  42, 0, 12, 0, 0, 26, 21, 0, 21, 24,
+  0, 0, 0, 0, 0, 9, 0, 0, 0, 9,
+  0, 20, 0, 0, 47, 83, 0, 52, 17, 21,
+  41, 51, 25, 0, 40, 5, 0, 40, 0, 11,
+  0, 0, 21, 0, 13, 13, 31, 0, 15, 0,
+  35, 1, 15, 0, 0, 27, 36, 37, 0, 42,
+  17, 9, 15, 0, 0, 22, 97, 0, 7, 27,
+  55, 8, 0, 0, 0, 69, 0, 8, 46, 0,
+  0, 20, 0, 2, 0, 37, 78, 0, 3, 0,
+  0, 24, 0, 73, 0, 34, 30, 29, 29, 57,
+  25, 42, 0, 28, 0, 43, 34, 9, 17, 0,
+  10, 0, 0, 0, 6, 14, 0, 16, 0, 0,
+  0, 0, 28, 0, 23, 6, 0, 10, 7, 0,
+  0, 23, 0, 35, 38, 0, 52, 56, 0, 0,
+  11, 0, 0, 18, 0, 0, 0, 4, 0, 16,
+  29, 0, 0, 66, 6, 0, 0, 10, 18, 0,
+  38, 0, 0, 6, 0, 7, 0, 1, 0, 0,
+  17, 0, 0, 0, 5, 0, 43, 0, 63, 0,
+  11, 0, 0, 0, 0, 15, 0, 142, 5, 0,
+  3, 0, 0, 27, 43, 0, 0, 0, 6, 0,
+  0, 0, 37, 88, 23, 15, 8, 0, 0, 0,
+  0, 13, 0, 22, 26, 24, 0, 2, 0, 36,
+  0, 50, 0, 35, 0, 56, 1, 71, 43, 43,
+  0, 0, 0, 38, 8, 0, 4, 0, 67, 0,
+  33, 0, 0, 57, 0, 0, 64, 0, 0, 26,
+  62, 0, 74, 26, 27, 3, 4, 32, 9, 25,
+  0, 31, 35, 0, 37, 52, 8, 0, 19, 0,
+  0, 0, 0, 11, 7, 0, 1, 26, 0, 0,
+  10, 66, 18, 0, 0, 7, 8, 0, 31, 0,
+  0, 0, 0, 0, 0, 15, 0, 0, 111, 2,
+  35, 3, 0, 0, 0, 0, 41, 0, 0, 0,
+  0, 60, 0, 15, 0, 5, 36, 23, 2, 0,
+  0, 31, 86, 8, 0, 0, 59, 11, 0, 0,
+  65, 56, 0, 25, 23, 0, 0, 13, 0, 13,
+  0, 11, 92, 0, 18, 0, 0, 32, 0, 53,
+  0, 28, 0, 44, 48, 94, 4, 86, 0, 7,
+  0, 38, 52, 0, 35, 0, 21, 0, 24, 0,
+  13, 27, 0, 40, 0, 11, 10, 0, 33, 0,
+  8, 0, 25, 13, 37, 0, 0, 0, 0, 15,
+  39, 0, 14, 13, 0, 0, 0, 0, 0, 24,
+  0, 0, 0, 13, 0, 47, 0, 0, 62, 50,
+  3, 0, 0, 13, 20, 1, 44, 0, 24, 28,
+  0, 29, 0, 15, 0, 0, 25, 0, 11, 10,
+  47, 0, 42, 0, 79, 0, 14, 0, 3, 28,
+  40, 34, 0, 19, 25, 3, 20, 0, 0, 31,
+  114, 0, 21, 37, 61, 3, 0, 0, 0, 74,
+  0, 5, 57, 0, 0, 30, 0, 1, 0, 41,
+  79, 0, 10, 0, 0, 27, 0, 80, 0, 41,
+  32, 32, 31, 55, 32, 23, 0, 44, 0, 50,
+  31, 17, 17, 0, 7, 0, 0, 0, 12, 0,
+  0, 36, 0, 0, 4, 0, 28, 0, 17, 10,
+  0, 3, 3, 0, 15, 36, 0, 33, 36, 0,
+  51, 45, 0, 0, 5, 0, 0, 36, 0, 0,
+  0, 5, 0, 25, 33, 0, 3, 68, 5, 0,
+  5, 7, 24, 0, 28, 0, 2, 10, 6, 14,
+  0, 1, 0, 0, 2, 0, 6, 0, 15, 4,
+  59, 0, 74, 0, 21, 0, 0, 0, 0, 16,
+  0, 145, 3, 0, 12, 0, 0, 27, 50, 0,
+  0, 22, 2, 0, 1, 0, 35, 91, 18, 9,
+  3, 0, 0, 0, 0, 4, 0, 27, 23, 43,
+  0, 0, 0, 30, 0, 60, 0, 29, 0, 69,
+  6, 72, 26, 52, 0, 0, 0, 48, 12, 0,
+  0, 0, 56, 0, 35, 0, 2, 55, 0, 0,
+  72, 0, 0, 20, 53, 0, 83, 22, 17, 0,
+  0, 33, 2, 22, 0, 37, 41, 0, 32, 49,
+  7, 0, 27, 0, 0, 0, 0, 13, 1, 0,
+  15, 38, 0, 0, 2, 68, 27, 0, 0, 7,
+  17, 0, 22, 0, 0, 0, 0, 0, 0, 29,
+  0, 0, 104, 4, 40, 7, 0, 0, 0, 0,
+  54, 0, 3, 0, 0, 39, 39, 29, 0, 48,
+  7, 15, 23, 0, 0, 11, 81, 0, 0, 23,
+  58, 7, 0, 0, 0, 63, 0, 21, 41, 0,
+  0, 12, 0, 0, 0, 32, 67, 3, 1, 0,
+  0, 13, 0, 47, 0, 18, 41, 13, 22, 69,
+  25, 53, 0, 12, 0, 37, 21, 7, 22, 0,
+  22, 0, 0, 0, 16, 31, 0, 29, 0, 0,
+  7, 0, 37, 0, 18, 0, 9, 21, 4, 0,
+  5, 11, 0, 39, 27, 0, 62, 62, 0, 0,
+  0, 0, 0, 18, 1, 0, 0, 19, 0, 19,
+  32, 0, 0, 78, 11, 0, 0, 10, 15, 0,
+  33, 0, 0, 0, 0, 8, 0, 0, 0, 0,
+  7, 0, 0, 0, 0, 0, 38, 0, 39, 0,
+  9, 0, 0, 0, 0, 12, 0, 128, 4, 0,
+  24, 0, 0, 24, 44, 0, 0, 3, 15, 0,
+  0, 0, 17, 87, 14, 19, 11, 0, 0, 0,
+  0, 0, 0, 22, 19, 26, 0, 6, 0, 37,
+  0, 56, 0, 21, 0, 56, 0, 77, 54, 47,
+  0, 0, 0, 41, 15, 0, 2, 0, 67, 0,
+  29, 0, 3, 66, 0, 12, 54, 5, 0, 16,
+  73, 0, 77, 17, 14, 1, 0, 19, 20, 20,
+  0, 39, 27, 0, 45, 41, 10, 0, 5, 0,
+  0, 0, 0, 17, 0, 0, 0, 33, 0, 0,
+  7, 75, 14, 0, 0, 3, 5, 0, 19, 0,
+  0, 0, 0, 0, 0, 14, 0, 0, 93, 0,
+  37, 0, 0, 0, 0, 0, 36, 0, 0, 0,
+  0, 0, 0, 0, 0, 48, 47, 0, 22, 0,
+  0, 0, 38, 0, 10, 49, 31, 17, 0, 15,
+  62, 0, 0, 40, 0, 20, 12, 0, 0, 26,
+  0, 0, 64, 55, 8, 0, 0, 16, 0, 41,
+  0, 28, 0, 56, 0, 45, 21, 45, 0, 12,
+  2, 10, 93, 9, 0, 9, 48, 0, 0, 35,
+  16, 4, 0, 1, 0, 0, 17, 7, 42, 0,
+  2, 3, 0, 21, 13, 42, 3, 0, 0, 26,
+  69, 0, 18, 2, 18, 0, 12, 0, 9, 8,
+  0, 31, 0, 8, 5, 29, 0, 0, 36, 54,
+  18, 0, 0, 0, 1, 0, 24, 4, 0, 31,
+  0, 1, 0, 19, 0, 0, 51, 3, 32, 0,
+  21, 0, 83, 0, 35, 0, 4, 0, 0, 27,
+  36, 37, 0, 42, 17, 9, 15, 0, 0, 22,
+  97, 0, 7, 27, 55, 8, 0, 0, 0, 69,
+  0, 8, 46, 0, 0, 20, 0, 2, 0, 37,
+  78, 0, 3, 0, 0, 24, 0, 73, 0, 34,
+  30, 29, 29, 57, 25, 42, 0, 28, 0, 43,
+  34, 9, 17, 0, 10, 0, 0, 0, 6, 14,
+  0, 16, 0, 0, 0, 0, 28, 0, 23, 6,
+  0, 10, 7, 0, 0, 23, 0, 35, 38, 0,
+  52, 56, 0, 0, 11, 0, 0, 18, 0, 0,
+  0, 4, 0, 16, 29, 0, 0, 66, 6, 0,
+  0, 10, 18, 0, 38, 0, 0, 6, 0, 7,
+  0, 1, 0, 0, 17, 0, 0, 0, 5, 0,
+  43, 0, 63, 0, 11, 0, 0, 0, 0, 15,
+  0, 142, 5, 0, 3, 0, 0, 27, 43, 0,
+  0, 0, 6, 0, 0, 0, 37, 88, 23, 15,
+  8, 0, 0, 0, 0, 13, 0, 22, 26, 24,
+  0, 2, 0, 36, 0, 50, 0, 35, 0, 56,
+  1, 71, 43, 43, 0, 0, 0, 38, 8, 0,
+  4, 0, 67, 0, 33, 0, 0, 57, 0, 0,
+  64, 0, 0, 26, 62, 0, 74, 26, 27, 3,
+  4, 32, 9, 25, 0, 31, 35, 0, 37, 52,
+  8, 0, 19, 0, 0, 0, 0, 11, 7, 0,
+  1, 26, 0, 0, 10, 66, 18, 0, 0, 7,
+  8, 0, 31, 0, 0, 0, 0, 0, 0, 15,
+  0, 0, 111, 2, 35, 3, 0, 0, 0, 0,
+  41, 0, 0, 0, 0, 0, 0, 0, 0, 51,
+  48, 0, 17, 0, 0, 1, 56, 0, 12, 28,
+  33, 20, 5, 18, 77, 0, 0, 29, 0, 42,
+  17, 0, 0, 38, 0, 0, 71, 57, 0, 0,
+  0, 12, 0, 39, 0, 43, 0, 51, 0, 34,
+  20, 45, 0, 31, 15, 0, 71, 13, 0, 6,
+  44, 0, 0, 54, 15, 0, 0, 0, 0, 0,
+  23, 28, 33, 0, 0, 13, 0, 22, 15, 54,
+  0, 0, 0, 29, 69, 6, 16, 0, 25, 0,
+  11, 13, 3, 2, 0, 26, 5, 14, 0, 26,
+  0, 0, 43, 47, 11, 6, 0, 0, 0, 0,
+  43, 0, 0, 46, 1, 0, 0, 11, 0, 0,
+  48, 15, 46, 0, 23, 0, 104, 0, 47, 0,
+  0, 0, 3, 28, 40, 34, 0, 19, 25, 3,
+  20, 0, 0, 31, 114, 0, 21, 37, 61, 3,
+  0, 0, 0, 74, 0, 5, 57, 0, 0, 30,
+  0, 1, 0, 41, 79, 0, 10, 0, 0, 27,
+  0, 80, 0, 41, 32, 32, 31, 55, 32, 23,
+  0, 44, 0, 50, 31, 17, 17, 0, 7, 0,
+  0, 0, 12, 0, 0, 36, 0, 0, 4, 0,
+  28, 0, 17, 10, 0, 3, 3, 0, 15, 36,
+  0, 33, 36, 0, 51, 45, 0, 0, 5, 0,
+  0, 36, 0, 0, 0, 5, 0, 25, 33, 0,
+  3, 68, 5, 0, 5, 7, 24, 0, 28, 0,
+  2, 10, 6, 14, 0, 1, 0, 0, 2, 0,
+  6, 0, 15, 4, 59, 0, 74, 0, 21, 0,
+  0, 0, 0, 16, 0, 145, 3, 0, 12, 0,
+  0, 27, 50, 0, 0, 22, 2, 0, 1, 0,
+  35, 91, 18, 9, 3, 0, 0, 0, 0, 4,
+  0, 27, 23, 43, 0, 0, 0, 30, 0, 60,
+  0, 29, 0, 69, 6, 72, 26, 52, 0, 0,
+  0, 48, 12, 0, 0, 0, 56, 0, 35, 0,
+  2, 55, 0, 0, 72, 0, 0, 20, 53, 0,
+  83, 22, 17, 0, 0, 33, 2, 22, 0, 37,
+  41, 0, 32, 49, 7, 0, 27, 0, 0, 0,
+  0, 13, 1, 0, 15, 38, 0, 0, 2, 68,
+  27, 0, 0, 7, 17, 0, 22, 0, 0, 0,
+  0, 0, 0, 29, 0, 0, 104, 4, 40, 7,
+  0, 0, 0, 0, 54, 0, 3, 0, 0, 0,
+  0, 0, 0, 45, 41, 0, 20, 0, 0, 0,
+  75, 11, 19, 55, 39, 21, 25, 2, 84, 0,
+  0, 27, 13, 52, 3, 2, 0, 52, 0, 0,
+  56, 63, 0, 0, 0, 0, 0, 59, 0, 43,
+  0, 45, 7, 20, 17, 36, 0, 46, 0, 0,
+  66, 22, 0, 0, 25, 0, 0, 76, 20, 0,
+  0, 2, 0, 0, 13, 21, 31, 0, 0, 26,
+  0, 14, 8, 55, 0, 0, 0, 54, 58, 17,
+  20, 5, 37, 0, 12, 14, 8, 14, 4, 15,
+  7, 17, 1, 41, 0, 0, 39, 55, 6, 0,
+  4, 0, 0, 0, 35, 0, 0, 42, 13, 0,
+  0, 5, 0, 0, 43, 15, 52, 0, 18, 3,
+  121, 0, 68, 0, 9, 0, 0, 0, 0, 12,
+  0, 128, 4, 0, 24, 0, 0, 24, 44, 0,
+  0, 3, 15, 0, 0, 0, 17, 87, 14, 19,
+  11, 0, 0, 0, 0, 0, 0, 22, 19, 26,
+  0, 6, 0, 37, 0, 56, 0, 21, 0, 56,
+  0, 77, 54, 47, 0, 0, 0, 41, 15, 0,
+  2, 0, 67, 0, 29, 0, 3, 66, 0, 12,
+  54, 5, 0, 16, 73, 0, 77, 17, 14, 1,
+  0, 19, 20, 20, 0, 39, 27, 0, 45, 41,
+  10, 0, 5, 0, 0, 0, 0, 17, 0, 0,
+  0, 33, 0, 0, 7, 75, 14, 0, 0, 3,
+  5, 0, 19, 0, 0, 0, 0, 0, 0, 14,
+  0, 0, 93, 0, 37, 0, 0, 0, 0, 0,
+  36, 0, 0, 0, 0, 0, 0, 0, 0, 48,
+  47, 0, 22, 0, 0, 0, 38, 0, 10, 49,
+  31, 17, 0, 15, 62, 0, 0, 40, 0, 20,
+  12, 0, 0, 26, 0, 0, 64, 55, 8, 0,
+  0, 16, 0, 41, 0, 28, 0, 56, 0, 45,
+  21, 45, 0, 12, 2, 10, 93, 9, 0, 9,
+  48, 0, 0, 35, 16, 4, 0, 1, 0, 0,
+  17, 7, 42, 0, 2, 3, 0, 21, 13, 42,
+  3, 0, 0, 26, 69, 0, 18, 2, 18, 0,
+  12, 0, 9, 8, 0, 31, 0, 8, 5, 29,
+  0, 0, 36, 54, 18, 0, 0, 0, 1, 0,
+  24, 4, 0, 31, 0, 1, 0, 19, 0, 0,
+  51, 3, 32, 0, 21, 0, 83, 0, 35, 0,
+  4, 0, 0, 9, 0, 0, 15, 0, 57, 0,
+  37, 0, 0, 0, 30, 12, 51, 40, 45, 47,
+  0, 28, 101, 0, 0, 27, 0, 9, 25, 8,
+  0, 23, 0, 0, 52, 4, 22, 0, 0, 12,
+  0, 35, 0, 7, 0, 70, 5, 54, 4, 16,
+  0, 0, 13, 8, 68, 27, 0, 0, 28, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 23, 1,
+  27, 0, 0, 0, 0, 10, 48, 0, 7, 9,
+  0, 11, 57, 13, 9, 0, 13, 0, 0, 0,
+  22, 29, 9, 0, 0, 15, 0, 34, 0, 0,
+  59, 37, 0, 0, 0, 0, 12, 0, 17, 14,
+  11, 27, 0, 0, 0, 5, 0, 0, 24, 0,
+  14, 0, 27, 0, 77, 0, 21, 0, 13, 0,
+  0, 0, 0, 15, 0, 142, 5, 0, 3, 0,
+  0, 27, 43, 0, 0, 0, 6, 0, 0, 0,
+  37, 88, 23, 15, 8, 0, 0, 0, 0, 13,
+  0, 22, 26, 24, 0, 2, 0, 36, 0, 50,
+  0, 35, 0, 56, 1, 71, 43, 43, 0, 0,
+  0, 38, 8, 0, 4, 0, 67, 0, 33, 0,
+  0, 57, 0, 0, 64, 0, 0, 26, 62, 0,
+  74, 26, 27, 3, 4, 32, 9, 25, 0, 31,
+  35, 0, 37, 52, 8, 0, 19, 0, 0, 0,
+  0, 11, 7, 0, 1, 26, 0, 0, 10, 66,
+  18, 0, 0, 7, 8, 0, 31, 0, 0, 0,
+  0, 0, 0, 15, 0, 0, 111, 2, 35, 3,
+  0, 0, 0, 0, 41, 0, 0, 0, 0, 0,
+  0, 0, 0, 51, 48, 0, 17, 0, 0, 1,
+  56, 0, 12, 28, 33, 20, 5, 18, 77, 0,
+  0, 29, 0, 42, 17, 0, 0, 38, 0, 0,
+  71, 57, 0, 0, 0, 12, 0, 39, 0, 43,
+  0, 51, 0, 34, 20, 45, 0, 31, 15, 0,
+  71, 13, 0, 6, 44, 0, 0, 54, 15, 0,
+  0, 0, 0, 0, 23, 28, 33, 0, 0, 13,
+  0, 22, 15, 54, 0, 0, 0, 29, 69, 6,
+  16, 0, 25, 0, 11, 13, 3, 2, 0, 26,
+  5, 14, 0, 26, 0, 0, 43, 47, 11, 6,
+  0, 0, 0, 0, 43, 0, 0, 46, 1, 0,
+  0, 11, 0, 0, 48, 15, 46, 0, 23, 0,
+  104, 0, 47, 0, 0, 0, 0, 29, 0, 0,
+  20, 0, 45, 0, 38, 0, 0, 2, 26, 28,
+  73, 29, 52, 53, 0, 24, 91, 0, 0, 24,
+  16, 39, 26, 0, 0, 20, 0, 0, 40, 12,
+  3, 0, 0, 8, 0, 47, 0, 9, 0, 58,
+  0, 33, 12, 19, 0, 0, 17, 3, 66, 44,
+  0, 0, 7, 0, 0, 3, 7, 0, 0, 0,
+  0, 0, 42, 7, 32, 0, 0, 0, 0, 10,
+  51, 0, 4, 0, 0, 8, 61, 18, 25, 0,
+  32, 0, 8, 4, 12, 12, 2, 0, 0, 26,
+  0, 31, 0, 0, 56, 29, 0, 2, 0, 0,
+  0, 0, 30, 0, 7, 37, 0, 0, 0, 21,
+  0, 0, 7, 6, 14, 0, 16, 0, 90, 0,
+  25, 0, 12, 0, 0, 0, 0, 16, 0, 145,
+  3, 0, 12, 0, 0, 27, 50, 0, 0, 22,
+  2, 0, 1, 0, 35, 91, 18, 9, 3, 0,
+  0, 0, 0, 4, 0, 27, 23, 43, 0, 0,
+  0, 30, 0, 60, 0, 29, 0, 69, 6, 72,
+  26, 52, 0, 0, 0, 48, 12, 0, 0, 0,
+  56, 0, 35, 0, 2, 55, 0, 0, 72, 0,
+  0, 20, 53, 0, 83, 22, 17, 0, 0, 33,
+  2, 22, 0, 37, 41, 0, 32, 49, 7, 0,
+  27, 0, 0, 0, 0, 13, 1, 0, 15, 38,
+  0, 0, 2, 68, 27, 0, 0, 7, 17, 0,
+  22, 0, 0, 0, 0, 0, 0, 29, 0, 0,
+  104, 4, 40, 7, 0, 0, 0, 0, 54, 0,
+  3, 0, 0, 0, 0, 0, 0, 45, 41, 0,
+  20, 0, 0, 0, 75, 11, 19, 55, 39, 21,
+  25, 2, 84, 0, 0, 27, 13, 52, 3, 2,
+  0, 52, 0, 0, 56, 63, 0, 0, 0, 0,
+  0, 59, 0, 43, 0, 45, 7, 20, 17, 36,
+  0, 46, 0, 0, 66, 22, 0, 0, 25, 0,
+  0, 76, 20, 0, 0, 2, 0, 0, 13, 21,
+  31, 0, 0, 26, 0, 14, 8, 55, 0, 0,
+  0, 54, 58, 17, 20, 5, 37, 0, 12, 14,
+  8, 14, 4, 15, 7, 17, 1, 41, 0, 0,
+  39, 55, 6, 0, 4, 0, 0, 0, 35, 0,
+  0, 42, 13, 0, 0, 5, 0, 0, 43, 15,
+  52, 0, 18, 3, 121, 0, 68, 0, 9, 0,
+  0, 49, 1, 0, 30, 0, 15, 0, 64, 0,
+  0, 7, 46, 41, 52, 60, 59, 47, 14, 4,
+  85, 0, 0, 29, 21, 32, 22, 9, 0, 19,
+  0, 0, 33, 0, 0, 0, 0, 0, 0, 62,
+  0, 0, 0, 54, 0, 32, 4, 0, 0, 16,
+  7, 12, 54, 37, 0, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0, 49, 0, 30, 0,
+  0, 0, 5, 29, 27, 0, 0, 9, 0, 21,
+  35, 23, 45, 0, 23, 22, 4, 26, 21, 30,
+  26, 0, 0, 24, 0, 19, 0, 0, 46, 43,
+  11, 0, 0, 0, 0, 0, 30, 1, 0, 44,
+  0, 0, 0, 16, 0, 0, 1, 3, 6, 0,
+  0, 0, 95, 0, 52, 0, 20, 0, 0, 0,
+  0, 0, 0, 48, 47, 0, 22, 0, 0, 0,
+  38, 0, 10, 49, 31, 17, 0, 15, 62, 0,
+  0, 40, 0, 20, 12, 0, 0, 26, 0, 0,
+  64, 55, 8, 0, 0, 16, 0, 41, 0, 28,
+  0, 56, 0, 45, 21, 45, 0, 12, 2, 10,
+  93, 9, 0, 9, 48, 0, 0, 35, 16, 4,
+  0, 1, 0, 0, 17, 7, 42, 0, 2, 3,
+  0, 21, 13, 42, 3, 0, 0, 26, 69, 0,
+  18, 2, 18, 0, 12, 0, 9, 8, 0, 31,
+  0, 8, 5, 29, 0, 0, 36, 54, 18, 0,
+  0, 0, 1, 0, 24, 4, 0, 31, 0, 1,
+  0, 19, 0, 0, 51, 3, 32, 0, 21, 0,
+  83, 0, 35, 0, 4, 0, 0, 9, 0, 0,
+  15, 0, 57, 0, 37, 0, 0, 0, 30, 12,
+  51, 40, 45, 47, 0, 28, 101, 0, 0, 27,
+  0, 9, 25, 8, 0, 23, 0, 0, 52, 4,
+  22, 0, 0, 12, 0, 35, 0, 7, 0, 70,
+  5, 54, 4, 16, 0, 0, 13, 8, 68, 27,
+  0, 0, 28, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 23, 1, 27, 0, 0, 0, 0, 10,
+  48, 0, 7, 9, 0, 11, 57, 13, 9, 0,
+  13, 0, 0, 0, 22, 29, 9, 0, 0, 15,
+  0, 34, 0, 0, 59, 37, 0, 0, 0, 0,
+  12, 0, 17, 14, 11, 27, 0, 0, 0, 5,
+  0, 0, 24, 0, 14, 0, 27, 0, 77, 0,
+  21, 0, 13, 0, 0, 33, 0, 0, 27, 0,
+  41, 0, 45, 22, 0, 7, 22, 44, 69, 48,
+  60, 49, 0, 17, 100, 0, 0, 26, 19, 29,
+  19, 25, 0, 21, 0, 0, 29, 10, 19, 0,
+  0, 21, 0, 35, 0, 0, 0, 56, 7, 31,
+  16, 4, 0, 0, 48, 0, 33, 46, 0, 2,
+  16, 0, 0, 12, 0, 0, 0, 0, 0, 0,
+  48, 0, 33, 0, 0, 0, 0, 6, 51, 0,
+  15, 23, 0, 30, 42, 35, 0, 0, 24, 0,
+  0, 0, 26, 42, 0, 0, 0, 46, 0, 27,
+  0, 13, 75, 38, 0, 0, 0, 0, 17, 0,
+  16, 5, 28, 44, 0, 0, 0, 5, 8, 0,
+  2, 0, 24, 0, 4, 0, 105, 0, 27, 6,
+  32, 0, 0, 0, 0, 0, 0, 51, 48, 0,
+  17, 0, 0, 1, 56, 0, 12, 28, 33, 20,
+  5, 18, 77, 0, 0, 29, 0, 42, 17, 0,
+  0, 38, 0, 0, 71, 57, 0, 0, 0, 12,
+  0, 39, 0, 43, 0, 51, 0, 34, 20, 45,
+  0, 31, 15, 0, 71, 13, 0, 6, 44, 0,
+  0, 54, 15, 0, 0, 0, 0, 0, 23, 28,
+  33, 0, 0, 13, 0, 22, 15, 54, 0, 0,
+  0, 29, 69, 6, 16, 0, 25, 0, 11, 13,
+  3, 2, 0, 26, 5, 14, 0, 26, 0, 0,
+  43, 47, 11, 6, 0, 0, 0, 0, 43, 0,
+  0, 46, 1, 0, 0, 11, 0, 0, 48, 15,
+  46, 0, 23, 0, 104, 0, 47, 0, 0, 0,
+  0, 29, 0, 0, 20, 0, 45, 0, 38, 0,
+  0, 2, 26, 28, 73, 29, 52, 53, 0, 24,
+  91, 0, 0, 24, 16, 39, 26, 0, 0, 20,
+  0, 0, 40, 12, 3, 0, 0, 8, 0, 47,
+  0, 9, 0, 58, 0, 33, 12, 19, 0, 0,
+  17, 3, 66, 44, 0, 0, 7, 0, 0, 3,
+  7, 0, 0, 0, 0, 0, 42, 7, 32, 0,
+  0, 0, 0, 10, 51, 0, 4, 0, 0, 8,
+  61, 18, 25, 0, 32, 0, 8, 4, 12, 12,
+  2, 0, 0, 26, 0, 31, 0, 0, 56, 29,
+  0, 2, 0, 0, 0, 0, 30, 0, 7, 37,
+  0, 0, 0, 21, 0, 0, 7, 6, 14, 0,
+  16, 0, 90, 0, 25, 0, 12, 0, 0, 65,
+  0, 0, 34, 0, 36, 0, 61, 12, 0, 5,
+  44, 54, 61, 74, 64, 45, 0, 12, 72, 0,
+  0, 33, 31, 57, 17, 27, 0, 12, 0, 0,
+  29, 8, 17, 0, 0, 37, 0, 58, 0, 3,
+  0, 54, 0, 29, 24, 4, 0, 0, 35, 0,
+  43, 56, 0, 0, 7, 0, 0, 32, 0, 0,
+  0, 0, 0, 0, 70, 9, 41, 0, 0, 0,
+  0, 18, 51, 0, 0, 21, 0, 27, 40, 52,
+  13, 20, 40, 15, 0, 9, 25, 57, 3, 0,
+  0, 59, 0, 27, 0, 5, 69, 44, 0, 0,
+  0, 0, 2, 0, 12, 20, 36, 60, 0, 0,
+  0, 21, 0, 0, 0, 18, 24, 0, 0, 1,
+  134, 0, 38, 0, 44, 0, 0, 0, 0, 0,
+  0, 45, 41, 0, 20, 0, 0, 0, 75, 11,
+  19, 55, 39, 21, 25, 2, 84, 0, 0, 27,
+  13, 52, 3, 2, 0, 52, 0, 0, 56, 63,
+  0, 0, 0, 0, 0, 59, 0, 43, 0, 45,
+  7, 20, 17, 36, 0, 46, 0, 0, 66, 22,
+  0, 0, 25, 0, 0, 76, 20, 0, 0, 2,
+  0, 0, 13, 21, 31, 0, 0, 26, 0, 14,
+  8, 55, 0, 0, 0, 54, 58, 17, 20, 5,
+  37, 0, 12, 14, 8, 14, 4, 15, 7, 17,
+  1, 41, 0, 0, 39, 55, 6, 0, 4, 0,
+  0, 0, 35, 0, 0, 42, 13, 0, 0, 5,
+  0, 0, 43, 15, 52, 0, 18, 3, 121, 0,
+  68, 0, 9, 0, 0, 49, 1, 0, 30, 0,
+  15, 0, 64, 0, 0, 7, 46, 41, 52, 60,
+  59, 47, 14, 4, 85, 0, 0, 29, 21, 32,
+  22, 9, 0, 19, 0, 0, 33, 0, 0, 0,
+  0, 0, 0, 62, 0, 0, 0, 54, 0, 32,
+  4, 0, 0, 16, 7, 12, 54, 37, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+  49, 0, 30, 0, 0, 0, 5, 29, 27, 0,
+  0, 9, 0, 21, 35, 23, 45, 0, 23, 22,
+  4, 26, 21, 30, 26, 0, 0, 24, 0, 19,
+  0, 0, 46, 43, 11, 0, 0, 0, 0, 0,
+  30, 1, 0, 44, 0, 0, 0, 16, 0, 0,
+  1, 3, 6, 0, 0, 0, 95, 0, 52, 0,
+  20, 0, 0, 44, 27, 0, 33, 0, 0, 0,
+  76, 0, 0, 1, 67, 69, 11, 51, 63, 32,
+  6, 0, 66, 0, 0, 38, 0, 0, 28, 40,
+  0, 0, 0, 0, 7, 0, 0, 0, 0, 27,
+  0, 47, 0, 0, 0, 20, 0, 38, 0, 0,
+  0, 16, 0, 34, 21, 7, 0, 0, 0, 8,
+  0, 0, 0, 0, 0, 0, 0, 0, 98, 0,
+  25, 5, 0, 0, 0, 78, 9, 0, 0, 35,
+  0, 0, 12, 5, 38, 41, 20, 53, 0, 44,
+  32, 14, 27, 37, 0, 13, 0, 0, 0, 0,
+  28, 63, 38, 0, 0, 0, 0, 0, 3, 36,
+  0, 61, 0, 0, 0, 5, 3, 0, 4, 0,
+  0, 0, 0, 0, 77, 0, 26, 0, 18, 21,
+  0, 9, 0, 0, 15, 0, 57, 0, 37, 0,
+  0, 0, 30, 12, 51, 40, 45, 47, 0, 28,
+  101, 0, 0, 27, 0, 9, 25, 8, 0, 23,
+  0, 0, 52, 4, 22, 0, 0, 12, 0, 35,
+  0, 7, 0, 70, 5, 54, 4, 16, 0, 0,
+  13, 8, 68, 27, 0, 0, 28, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 23, 1, 27, 0,
+  0, 0, 0, 10, 48, 0, 7, 9, 0, 11,
+  57, 13, 9, 0, 13, 0, 0, 0, 22, 29,
+  9, 0, 0, 15, 0, 34, 0, 0, 59, 37,
+  0, 0, 0, 0, 12, 0, 17, 14, 11, 27,
+  0, 0, 0, 5, 0, 0, 24, 0, 14, 0,
+  27, 0, 77, 0, 21, 0, 13, 0, 0, 33,
+  0, 0, 27, 0, 41, 0, 45, 22, 0, 7,
+  22, 44, 69, 48, 60, 49, 0, 17, 100, 0,
+  0, 26, 19, 29, 19, 25, 0, 21, 0, 0,
+  29, 10, 19, 0, 0, 21, 0, 35, 0, 0,
+  0, 56, 7, 31, 16, 4, 0, 0, 48, 0,
+  33, 46, 0, 2, 16, 0, 0, 12, 0, 0,
+  0, 0, 0, 0, 48, 0, 33, 0, 0, 0,
+  0, 6, 51, 0, 15, 23, 0, 30, 42, 35,
+  0, 0, 24, 0, 0, 0, 26, 42, 0, 0,
+  0, 46, 0, 27, 0, 13, 75, 38, 0, 0,
+  0, 0, 17, 0, 16, 5, 28, 44, 0, 0,
+  0, 5, 8, 0, 2, 0, 24, 0, 4, 0,
+  105, 0, 27, 6, 32, 0, 0, 33, 0, 0,
+  36, 0, 0, 3, 48, 28, 0, 0, 10, 59,
+  39, 46, 67, 44, 12, 0, 51, 0, 0, 36,
+  0, 22, 41, 60, 0, 0, 0, 0, 19, 0,
+  7, 0, 0, 22, 0, 24, 0, 0, 0, 4,
+  0, 17, 23, 0, 0, 0, 55, 0, 1, 17,
+  0, 0, 18, 15, 0, 17, 0, 0, 0, 0,
+  0, 0, 102, 0, 17, 0, 0, 0, 5, 41,
+  35, 0, 3, 53, 0, 13, 18, 38, 12, 42,
+  10, 28, 0, 30, 22, 26, 21, 17, 0, 42,
+  0, 0, 0, 2, 49, 55, 1, 0, 0, 0,
+  16, 0, 14, 19, 32, 69, 0, 3, 0, 0,
+  21, 0, 0, 0, 17, 0, 0, 13, 100, 0,
+  0, 0, 30, 37, 0, 29, 0, 0, 20, 0,
+  45, 0, 38, 0, 0, 2, 26, 28, 73, 29,
+  52, 53, 0, 24, 91, 0, 0, 24, 16, 39,
+  26, 0, 0, 20, 0, 0, 40, 12, 3, 0,
+  0, 8, 0, 47, 0, 9, 0, 58, 0, 33,
+  12, 19, 0, 0, 17, 3, 66, 44, 0, 0,
+  7, 0, 0, 3, 7, 0, 0, 0, 0, 0,
+  42, 7, 32, 0, 0, 0, 0, 10, 51, 0,
+  4, 0, 0, 8, 61, 18, 25, 0, 32, 0,
+  8, 4, 12, 12, 2, 0, 0, 26, 0, 31,
+  0, 0, 56, 29, 0, 2, 0, 0, 0, 0,
+  30, 0, 7, 37, 0, 0, 0, 21, 0, 0,
+  7, 6, 14, 0, 16, 0, 90, 0, 25, 0,
+  12, 0, 0, 65, 0, 0, 34, 0, 36, 0,
+  61, 12, 0, 5, 44, 54, 61, 74, 64, 45,
+  0, 12, 72, 0, 0, 33, 31, 57, 17, 27,
+  0, 12, 0, 0, 29, 8, 17, 0, 0, 37,
+  0, 58, 0, 3, 0, 54, 0, 29, 24, 4,
+  0, 0, 35, 0, 43, 56, 0, 0, 7, 0,
+  0, 32, 0, 0, 0, 0, 0, 0, 70, 9,
+  41, 0, 0, 0, 0, 18, 51, 0, 0, 21,
+  0, 27, 40, 52, 13, 20, 40, 15, 0, 9,
+  25, 57, 3, 0, 0, 59, 0, 27, 0, 5,
+  69, 44, 0, 0, 0, 0, 2, 0, 12, 20,
+  36, 60, 0, 0, 0, 21, 0, 0, 0, 18,
+  24, 0, 0, 1, 134, 0, 38, 0, 44, 0,
+  0, 26, 42, 0, 40, 0, 0, 0, 68, 7,
+  0, 5, 43, 69, 21, 36, 59, 16, 3, 0,
+  30, 7, 16, 33, 0, 0, 32, 69, 0, 5,
+  0, 0, 0, 0, 0, 0, 0, 55, 0, 45,
+  0, 4, 0, 0, 0, 8, 12, 0, 0, 16,
+  23, 16, 0, 8, 0, 0, 24, 20, 0, 0,
+  0, 0, 0, 0, 0, 0, 70, 10, 16, 0,
+  0, 0, 0, 27, 24, 0, 0, 57, 0, 13,
+  0, 13, 15, 76, 12, 31, 0, 45, 9, 26,
+  24, 0, 0, 11, 0, 0, 0, 0, 52, 56,
+  16, 0, 0, 0, 1, 0, 7, 24, 39, 91,
+  4, 0, 0, 0, 0, 0, 11, 0, 10, 0,
+  0, 35, 51, 0, 0, 0, 24, 66, 0, 49,
+  1, 0, 30, 0, 15, 0, 64, 0, 0, 7,
+  46, 41, 52, 60, 59, 47, 14, 4, 85, 0,
+  0, 29, 21, 32, 22, 9, 0, 19, 0, 0,
+  33, 0, 0, 0, 0, 0, 0, 62, 0, 0,
+  0, 54, 0, 32, 4, 0, 0, 16, 7, 12,
+  54, 37, 0, 0, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 49, 0, 30, 0, 0, 0,
+  5, 29, 27, 0, 0, 9, 0, 21, 35, 23,
+  45, 0, 23, 22, 4, 26, 21, 30, 26, 0,
+  0, 24, 0, 19, 0, 0, 46, 43, 11, 0,
+  0, 0, 0, 0, 30, 1, 0, 44, 0, 0,
+  0, 16, 0, 0, 1, 3, 6, 0, 0, 0,
+  95, 0, 52, 0, 20, 0, 0, 44, 27, 0,
+  33, 0, 0, 0, 76, 0, 0, 1, 67, 69,
+  11, 51, 63, 32, 6, 0, 66, 0, 0, 38,
+  0, 0, 28, 40, 0, 0, 0, 0, 7, 0,
+  0, 0, 0, 27, 0, 47, 0, 0, 0, 20,
+  0, 38, 0, 0, 0, 16, 0, 34, 21, 7,
+  0, 0, 0, 8, 0, 0, 0, 0, 0, 0,
+  0, 0, 98, 0, 25, 5, 0, 0, 0, 78,
+  9, 0, 0, 35, 0, 0, 12, 5, 38, 41,
+  20, 53, 0, 44, 32, 14, 27, 37, 0, 13,
+  0, 0, 0, 0, 28, 63, 38, 0, 0, 0,
+  0, 0, 3, 36, 0, 61, 0, 0, 0, 5,
+  3, 0, 4, 0, 0, 0, 0, 0, 77, 0,
+  26, 0, 18, 21, 29, 0, 57, 0, 12, 30,
+  0, 0, 52, 0, 0, 2, 43, 101, 14, 0,
+  40, 0, 0, 0, 32, 66, 0, 35, 0, 0,
+  0, 29, 0, 8, 0, 0, 0, 11, 0, 0,
+  0, 50, 0, 48, 0, 31, 0, 0, 0, 0,
+  0, 0, 6, 9, 0, 67, 0, 0, 11, 0,
+  13, 40, 0, 0, 5, 7, 0, 44, 0, 15,
+  58, 0, 30, 45, 0, 14, 0, 32, 0, 0,
+  0, 10, 0, 27, 0, 3, 29, 32, 45, 49,
+  0, 64, 21, 0, 0, 14, 0, 0, 0, 0,
+  0, 0, 30, 78, 0, 0, 0, 0, 0, 18,
+  0, 23, 14, 57, 17, 0, 0, 0, 29, 0,
+  59, 1, 9, 2, 0, 17, 0, 0, 0, 0,
+  0, 41, 0, 33, 0, 0, 27, 0, 41, 0,
+  45, 22, 0, 7, 22, 44, 69, 48, 60, 49,
+  0, 17, 100, 0, 0, 26, 19, 29, 19, 25,
+  0, 21, 0, 0, 29, 10, 19, 0, 0, 21,
+  0, 35, 0, 0, 0, 56, 7, 31, 16, 4,
+  0, 0, 48, 0, 33, 46, 0, 2, 16, 0,
+  0, 12, 0, 0, 0, 0, 0, 0, 48, 0,
+  33, 0, 0, 0, 0, 6, 51, 0, 15, 23,
+  0, 30, 42, 35, 0, 0, 24, 0, 0, 0,
+  26, 42, 0, 0, 0, 46, 0, 27, 0, 13,
+  75, 38, 0, 0, 0, 0, 17, 0, 16, 5,
+  28, 44, 0, 0, 0, 5, 8, 0, 2, 0,
+  24, 0, 4, 0, 105, 0, 27, 6, 32, 0,
+  0, 33, 0, 0, 36, 0, 0, 3, 48, 28,
+  0, 0, 10, 59, 39, 46, 67, 44, 12, 0,
+  51, 0, 0, 36, 0, 22, 41, 60, 0, 0,
+  0, 0, 19, 0, 7, 0, 0, 22, 0, 24,
+  0, 0, 0, 4, 0, 17, 23, 0, 0, 0,
+  55, 0, 1, 17, 0, 0, 18, 15, 0, 17,
+  0, 0, 0, 0, 0, 0, 102, 0, 17, 0,
+  0, 0, 5, 41, 35, 0, 3, 53, 0, 13,
+  18, 38, 12, 42, 10, 28, 0, 30, 22, 26,
+  21, 17, 0, 42, 0, 0, 0, 2, 49, 55,
+  1, 0, 0, 0, 16, 0, 14, 19, 32, 69,
+  0, 3, 0, 0, 21, 0, 0, 0, 17, 0,
+  0, 13, 100, 0, 0, 0, 30, 37, 12, 0,
+  30, 0, 18, 0, 0, 0, 37, 30, 0, 0,
+  4, 71, 11, 0, 44, 48, 26, 0, 25, 1,
+  22, 8, 0, 6, 34, 49, 0, 0, 16, 0,
+  0, 5, 0, 0, 40, 32, 0, 1, 1, 0,
+  0, 0, 0, 0, 9, 0, 0, 0, 31, 0,
+  0, 10, 0, 0, 0, 51, 0, 0, 2, 6,
+  23, 5, 0, 0, 106, 5, 12, 82, 0, 0,
+  6, 39, 0, 0, 0, 50, 1, 0, 0, 34,
+  0, 54, 42, 31, 0, 69, 0, 0, 0, 56,
+  0, 0, 20, 0, 0, 15, 19, 45, 10, 6,
+  0, 0, 0, 0, 0, 21, 1, 57, 6, 0,
+  0, 0, 53, 11, 0, 0, 15, 0, 0, 26,
+  8, 0, 0, 12, 42, 48, 0, 65, 0, 0,
+  34, 0, 36, 0, 61, 12, 0, 5, 44, 54,
+  61, 74, 64, 45, 0, 12, 72, 0, 0, 33,
+  31, 57, 17, 27, 0, 12, 0, 0, 29, 8,
+  17, 0, 0, 37, 0, 58, 0, 3, 0, 54,
+  0, 29, 24, 4, 0, 0, 35, 0, 43, 56,
+  0, 0, 7, 0, 0, 32, 0, 0, 0, 0,
+  0, 0, 70, 9, 41, 0, 0, 0, 0, 18,
+  51, 0, 0, 21, 0, 27, 40, 52, 13, 20,
+  40, 15, 0, 9, 25, 57, 3, 0, 0, 59,
+  0, 27, 0, 5, 69, 44, 0, 0, 0, 0,
+  2, 0, 12, 20, 36, 60, 0, 0, 0, 21,
+  0, 0, 0, 18, 24, 0, 0, 1, 134, 0,
+  38, 0, 44, 0, 0, 26, 42, 0, 40, 0,
+  0, 0, 68, 7, 0, 5, 43, 69, 21, 36,
+  59, 16, 3, 0, 30, 7, 16, 33, 0, 0,
+  32, 69, 0, 5, 0, 0, 0, 0, 0, 0,
+  0, 55, 0, 45, 0, 4, 0, 0, 0, 8,
+  12, 0, 0, 16, 23, 16, 0, 8, 0, 0,
+  24, 20, 0, 0, 0, 0, 0, 0, 0, 0,
+  70, 10, 16, 0, 0, 0, 0, 27, 24, 0,
+  0, 57, 0, 13, 0, 13, 15, 76, 12, 31,
+  0, 45, 9, 26, 24, 0, 0, 11, 0, 0,
+  0, 0, 52, 56, 16, 0, 0, 0, 1, 0,
+  7, 24, 39, 91, 4, 0, 0, 0, 0, 0,
+  11, 0, 10, 0, 0, 35, 51, 0, 0, 0,
+  24, 66, 70, 0, 17, 0, 20, 30, 0, 0,
+  12, 0, 0, 0, 2, 79, 18, 0, 26, 23,
+  6, 5, 29, 52, 17, 15, 0, 0, 8, 29,
+  0, 0, 0, 9, 0, 47, 0, 0, 7, 43,
+  0, 12, 0, 10, 0, 0, 5, 0, 16, 5,
+  10, 0, 24, 4, 0, 0, 15, 0, 23, 37,
+  5, 0, 30, 16, 31, 0, 0, 12, 69, 32,
+  32, 66, 0, 18, 10, 0, 25, 0, 0, 55,
+  11, 6, 0, 12, 0, 37, 48, 12, 31, 65,
+  0, 0, 0, 0, 0, 0, 29, 0, 0, 17,
+  57, 30, 0, 27, 0, 0, 0, 60, 0, 14,
+  29, 64, 0, 0, 0, 1, 7, 52, 58, 0,
+  0, 0, 0, 32, 0, 0, 0, 19, 23, 49,
+  0, 44, 27, 0, 33, 0, 0, 0, 76, 0,
+  0, 1, 67, 69, 11, 51, 63, 32, 6, 0,
+  66, 0, 0, 38, 0, 0, 28, 40, 0, 0,
+  0, 0, 7, 0, 0, 0, 0, 27, 0, 47,
+  0, 0, 0, 20, 0, 38, 0, 0, 0, 16,
+  0, 34, 21, 7, 0, 0, 0, 8, 0, 0,
+  0, 0, 0, 0, 0, 0, 98, 0, 25, 5,
+  0, 0, 0, 78, 9, 0, 0, 35, 0, 0,
+  12, 5, 38, 41, 20, 53, 0, 44, 32, 14,
+  27, 37, 0, 13, 0, 0, 0, 0, 28, 63,
+  38, 0, 0, 0, 0, 0, 3, 36, 0, 61,
+  0, 0, 0, 5, 3, 0, 4, 0, 0, 0,
+  0, 0, 77, 0, 26, 0, 18, 21, 29, 0,
+  57, 0, 12, 30, 0, 0, 52, 0, 0, 2,
+  43, 101, 14, 0, 40, 0, 0, 0, 32, 66,
+  0, 35, 0, 0, 0, 29, 0, 8, 0, 0,
+  0, 11, 0, 0, 0, 50, 0, 48, 0, 31,
+  0, 0, 0, 0, 0, 0, 6, 9, 0, 67,
+  0, 0, 11, 0, 13, 40, 0, 0, 5, 7,
+  0, 44, 0, 15, 58, 0, 30, 45, 0, 14,
+  0, 32, 0, 0, 0, 10, 0, 27, 0, 3,
+  29, 32, 45, 49, 0, 64, 21, 0, 0, 14,
+  0, 0, 0, 0, 0, 0, 30, 78, 0, 0,
+  0, 0, 0, 18, 0, 23, 14, 57, 17, 0,
+  0, 0, 29, 0, 59, 1, 9, 2, 0, 17,
+  0, 0, 0, 0, 0, 41, 0, 0, 0, 0,
+  31, 51, 0, 0, 37, 2, 0, 0, 4, 70,
+  43, 0, 24, 35, 0, 14, 56, 0, 0, 39,
+  0, 0, 9, 13, 0, 36, 0, 0, 0, 14,
+  0, 0, 0, 19, 0, 41, 0, 0, 0, 5,
+  3, 0, 4, 0, 0, 0, 23, 13, 20, 0,
+  0, 0, 18, 34, 0, 0, 4, 17, 0, 0,
+  0, 0, 21, 0, 0, 0, 0, 23, 10, 1,
+  39, 9, 0, 0, 1, 25, 3, 20, 0, 8,
+  17, 5, 38, 41, 32, 19, 10, 0, 6, 0,
+  0, 0, 0, 5, 45, 39, 4, 0, 0, 0,
+  0, 31, 0, 9, 12, 73, 0, 0, 0, 0,
+  2, 0, 65, 11, 0, 5, 37, 0, 20, 0,
+  0, 11, 0, 8, 0, 33, 0, 0, 36, 0,
+  0, 3, 48, 28, 0, 0, 10, 59, 39, 46,
+  67, 44, 12, 0, 51, 0, 0, 36, 0, 22,
+  41, 60, 0, 0, 0, 0, 19, 0, 7, 0,
+  0, 22, 0, 24, 0, 0, 0, 4, 0, 17,
+  23, 0, 0, 0, 55, 0, 1, 17, 0, 0,
+  18, 15, 0, 17, 0, 0, 0, 0, 0, 0,
+  102, 0, 17, 0, 0, 0, 5, 41, 35, 0,
+  3, 53, 0, 13, 18, 38, 12, 42, 10, 28,
+  0, 30, 22, 26, 21, 17, 0, 42, 0, 0,
+  0, 2, 49, 55, 1, 0, 0, 0, 16, 0,
+  14, 19, 32, 69, 0, 3, 0, 0, 21, 0,
+  0, 0, 17, 0, 0, 13, 100, 0, 0, 0,
+  30, 37, 12, 0, 30, 0, 18, 0, 0, 0,
+  37, 30, 0, 0, 4, 71, 11, 0, 44, 48,
+  26, 0, 25, 1, 22, 8, 0, 6, 34, 49,
+  0, 0, 16, 0, 0, 5, 0, 0, 40, 32,
+  0, 1, 1, 0, 0, 0, 0, 0, 9, 0,
+  0, 0, 31, 0, 0, 10, 0, 0, 0, 51,
+  0, 0, 2, 6, 23, 5, 0, 0, 106, 5,
+  12, 82, 0, 0, 6, 39, 0, 0, 0, 50,
+  1, 0, 0, 34, 0, 54, 42, 31, 0, 69,
+  0, 0, 0, 56, 0, 0, 20, 0, 0, 15,
+  19, 45, 10, 6, 0, 0, 0, 0, 0, 21,
+  1, 57, 6, 0, 0, 0, 53, 11, 0, 0,
+  15, 0, 0, 26, 8, 0, 0, 12, 42, 48,
+  16, 0, 43, 0, 0, 0, 0, 0, 40, 54,
+  0, 16, 0, 59, 14, 0, 21, 57, 23, 17,
+  21, 14, 54, 0, 0, 0, 42, 21, 0, 0,
+  0, 0, 0, 0, 0, 0, 54, 47, 0, 0,
+  9, 0, 0, 0, 0, 0, 9, 0, 0, 0,
+  23, 0, 0, 0, 10, 0, 8, 40, 0, 0,
+  0, 25, 50, 0, 59, 21, 36, 7, 0, 114,
+  0, 9, 8, 6, 0, 0, 4, 34, 0, 0,
+  0, 19, 0, 29, 42, 2, 22, 44, 6, 0,
+  0, 57, 0, 0, 19, 0, 0, 0, 14, 17,
+  24, 0, 0, 0, 0, 0, 0, 0, 0, 39,
+  0, 0, 0, 0, 81, 4, 14, 0, 20, 0,
+  0, 18, 0, 0, 0, 19, 37, 4, 0, 26,
+  42, 0, 40, 0, 0, 0, 68, 7, 0, 5,
+  43, 69, 21, 36, 59, 16, 3, 0, 30, 7,
+  16, 33, 0, 0, 32, 69, 0, 5, 0, 0,
+  0, 0, 0, 0, 0, 55, 0, 45, 0, 4,
+  0, 0, 0, 8, 12, 0, 0, 16, 23, 16,
+  0, 8, 0, 0, 24, 20, 0, 0, 0, 0,
+  0, 0, 0, 0, 70, 10, 16, 0, 0, 0,
+  0, 27, 24, 0, 0, 57, 0, 13, 0, 13,
+  15, 76, 12, 31, 0, 45, 9, 26, 24, 0,
+  0, 11, 0, 0, 0, 0, 52, 56, 16, 0,
+  0, 0, 1, 0, 7, 24, 39, 91, 4, 0,
+  0, 0, 0, 0, 11, 0, 10, 0, 0, 35,
+  51, 0, 0, 0, 24, 66, 70, 0, 17, 0,
+  20, 30, 0, 0, 12, 0, 0, 0, 2, 79,
+  18, 0, 26, 23, 6, 5, 29, 52, 17, 15,
+  0, 0, 8, 29, 0, 0, 0, 9, 0, 47,
+  0, 0, 7, 43, 0, 12, 0, 10, 0, 0,
+  5, 0, 16, 5, 10, 0, 24, 4, 0, 0,
+  15, 0, 23, 37, 5, 0, 30, 16, 31, 0,
+  0, 12, 69, 32, 32, 66, 0, 18, 10, 0,
+  25, 0, 0, 55, 11, 6, 0, 12, 0, 37,
+  48, 12, 31, 65, 0, 0, 0, 0, 0, 0,
+  29, 0, 0, 17, 57, 30, 0, 27, 0, 0,
+  0, 60, 0, 14, 29, 64, 0, 0, 0, 1,
+  7, 52, 58, 0, 0, 0, 0, 32, 0, 0,
+  0, 19, 23, 49, 22, 3, 0, 0, 24, 14,
+  0, 0, 31, 13, 0, 23, 0, 61, 30, 0,
+  16, 46, 7, 38, 53, 0, 0, 0, 7, 20,
+  37, 0, 0, 0, 0, 0, 0, 35, 0, 0,
+  9, 0, 0, 0, 0, 3, 0, 3, 12, 0,
+  13, 5, 0, 0, 57, 0, 3, 0, 0, 0,
+  27, 17, 0, 0, 5, 8, 37, 0, 0, 0,
+  19, 60, 0, 39, 0, 33, 30, 0, 37, 12,
+  0, 30, 0, 10, 5, 30, 0, 0, 41, 0,
+  71, 36, 0, 13, 0, 0, 4, 0, 18, 0,
+  0, 16, 44, 2, 0, 26, 0, 0, 0, 38,
+  5, 6, 19, 51, 0, 0, 0, 14, 43, 20,
+  37, 0, 0, 0, 39, 13, 0, 0, 0, 39,
+  17, 0, 29, 0, 57, 0, 12, 30, 0, 0,
+  52, 0, 0, 2, 43, 101, 14, 0, 40, 0,
+  0, 0, 32, 66, 0, 35, 0, 0, 0, 29,
+  0, 8, 0, 0, 0, 11, 0, 0, 0, 50,
+  0, 48, 0, 31, 0, 0, 0, 0, 0, 0,
+  6, 9, 0, 67, 0, 0, 11, 0, 13, 40,
+  0, 0, 5, 7, 0, 44, 0, 15, 58, 0,
+  30, 45, 0, 14, 0, 32, 0, 0, 0, 10,
+  0, 27, 0, 3, 29, 32, 45, 49, 0, 64,
+  21, 0, 0, 14, 0, 0, 0, 0, 0, 0,
+  30, 78, 0, 0, 0, 0, 0, 18, 0, 23,
+  14, 57, 17, 0, 0, 0, 29, 0, 59, 1,
+  9, 2, 0, 17, 0, 0, 0, 0, 0, 41,
+  0, 0, 0, 0, 31, 51, 0, 0, 37, 2,
+  0, 0, 4, 70, 43, 0, 24, 35, 0, 14,
+  56, 0, 0, 39, 0, 0, 9, 13, 0, 36,
+  0, 0, 0, 14, 0, 0, 0, 19, 0, 41,
+  0, 0, 0, 5, 3, 0, 4, 0, 0, 0,
+  23, 13, 20, 0, 0, 0, 18, 34, 0, 0,
+  4, 17, 0, 0, 0, 0, 21, 0, 0, 0,
+  0, 23, 10, 1, 39, 9, 0, 0, 1, 25,
+  3, 20, 0, 8, 17, 5, 38, 41, 32, 19,
+  10, 0, 6, 0, 0, 0, 0, 5, 45, 39,
+  4, 0, 0, 0, 0, 31, 0, 9, 12, 73,
+  0, 0, 0, 0, 2, 0, 65, 11, 0, 5,
+  37, 0, 20, 0, 0, 11, 0, 8, 0, 32,
+  0, 0, 31, 0, 19, 0, 50, 0, 0, 16,
+  7, 64, 58, 24, 16, 46, 0, 28, 76, 0,
+  0, 47, 16, 40, 25, 0, 0, 27, 0, 0,
+  0, 37, 5, 0, 0, 0, 0, 29, 0, 1,
+  0, 41, 21, 3, 4, 6, 0, 0, 60, 0,
+  56, 11, 0, 0, 8, 6, 0, 26, 13, 0,
+  0, 0, 0, 0, 17, 6, 0, 0, 0, 25,
+  0, 0, 41, 13, 0, 0, 0, 30, 48, 39,
+  12, 0, 31, 0, 58, 23, 37, 56, 3, 0,
+  8, 19, 0, 16, 0, 10, 57, 33, 0, 0,
+  0, 0, 0, 0, 23, 0, 31, 59, 0, 0,
+  0, 1, 24, 0, 21, 0, 8, 0, 47, 0,
+  77, 0, 1, 23, 9, 0, 12, 0, 30, 0,
+  18, 0, 0, 0, 37, 30, 0, 0, 4, 71,
+  11, 0, 44, 48, 26, 0, 25, 1, 22, 8,
+  0, 6, 34, 49, 0, 0, 16, 0, 0, 5,
+  0, 0, 40, 32, 0, 1, 1, 0, 0, 0,
+  0, 0, 9, 0, 0, 0, 31, 0, 0, 10,
+  0, 0, 0, 51, 0, 0, 2, 6, 23, 5,
+  0, 0, 106, 5, 12, 82, 0, 0, 6, 39,
+  0, 0, 0, 50, 1, 0, 0, 34, 0, 54,
+  42, 31, 0, 69, 0, 0, 0, 56, 0, 0,
+  20, 0, 0, 15, 19, 45, 10, 6, 0, 0,
+  0, 0, 0, 21, 1, 57, 6, 0, 0, 0,
+  53, 11, 0, 0, 15, 0, 0, 26, 8, 0,
+  0, 12, 42, 48, 16, 0, 43, 0, 0, 0,
+  0, 0, 40, 54, 0, 16, 0, 59, 14, 0,
+  21, 57, 23, 17, 21, 14, 54, 0, 0, 0,
+  42, 21, 0, 0, 0, 0, 0, 0, 0, 0,
+  54, 47, 0, 0, 9, 0, 0, 0, 0, 0,
+  9, 0, 0, 0, 23, 0, 0, 0, 10, 0,
+  8, 40, 0, 0, 0, 25, 50, 0, 59, 21,
+  36, 7, 0, 114, 0, 9, 8, 6, 0, 0,
+  4, 34, 0, 0, 0, 19, 0, 29, 42, 2,
+  22, 44, 6, 0, 0, 57, 0, 0, 19, 0,
+  0, 0, 14, 17, 24, 0, 0, 0, 0, 0,
+  0, 0, 0, 39, 0, 0, 0, 0, 81, 4,
+  14, 0, 20, 0, 0, 18, 0, 0, 0, 19,
+  37, 4, 30, 0, 21, 8, 18, 0, 0, 0,
+  23, 36, 0, 0, 0, 54, 7, 0, 0, 65,
+  15, 16, 55, 1, 62, 10, 0, 0, 52, 0,
+  0, 0, 14, 0, 0, 0, 0, 0, 9, 33,
+  0, 0, 29, 0, 0, 9, 0, 0, 15, 0,
+  0, 0, 30, 30, 0, 0, 29, 0, 20, 15,
+  0, 0, 0, 14, 64, 0, 89, 22, 8, 0,
+  0, 130, 0, 14, 8, 0, 2, 0, 14, 22,
+  0, 0, 24, 0, 8, 22, 41, 0, 39, 0,
+  26, 0, 0, 30, 15, 0, 0, 0, 0, 0,
+  23, 0, 15, 0, 0, 0, 0, 0, 0, 32,
+  0, 10, 0, 9, 0, 0, 99, 17, 35, 0,
+  24, 0, 6, 0, 0, 0, 0, 31, 25, 0,
+  70, 0, 17, 0, 20, 30, 0, 0, 12, 0,
+  0, 0, 2, 79, 18, 0, 26, 23, 6, 5,
+  29, 52, 17, 15, 0, 0, 8, 29, 0, 0,
+  0, 9, 0, 47, 0, 0, 7, 43, 0, 12,
+  0, 10, 0, 0, 5, 0, 16, 5, 10, 0,
+  24, 4, 0, 0, 15, 0, 23, 37, 5, 0,
+  30, 16, 31, 0, 0, 12, 69, 32, 32, 66,
+  0, 18, 10, 0, 25, 0, 0, 55, 11, 6,
+  0, 12, 0, 37, 48, 12, 31, 65, 0, 0,
+  0, 0, 0, 0, 29, 0, 0, 17, 57, 30,
+  0, 27, 0, 0, 0, 60, 0, 14, 29, 64,
+  0, 0, 0, 1, 7, 52, 58, 0, 0, 0,
+  0, 32, 0, 0, 0, 19, 23, 49, 22, 3,
+  0, 0, 24, 14, 0, 0, 31, 13, 0, 23,
+  0, 61, 30, 0, 16, 46, 7, 38, 53, 0,
+  0, 0, 7, 20, 37, 0, 0, 0, 0, 0,
+  0, 35, 0, 0, 9, 0, 0, 0, 0, 3,
+  0, 3, 12, 0, 13, 5, 0, 0, 57, 0,
+  3, 0, 0, 0, 27, 17, 0, 0, 5, 8,
+  37, 0, 0, 0, 19, 60, 0, 39, 0, 33,
+  30, 0, 37, 12, 0, 30, 0, 10, 5, 30,
+  0, 0, 41, 0, 71, 36, 0, 13, 0, 0,
+  4, 0, 18, 0, 0, 16, 44, 2, 0, 26,
+  0, 0, 0, 38, 5, 6, 19, 51, 0, 0,
+  0, 14, 43, 20, 37, 0, 0, 0, 39, 13,
+  0, 0, 0, 39, 17, 0, 19, 51, 0, 11,
+  63, 0, 36, 0, 33, 2, 0, 24, 2, 46,
+  28, 0, 6, 25, 11, 52, 60, 0, 0, 15,
+  21, 37, 39, 0, 0, 21, 42, 0, 0, 33,
+  0, 0, 0, 0, 0, 0, 0, 29, 0, 51,
+  23, 0, 7, 28, 0, 0, 51, 0, 37, 15,
+  0, 12, 5, 0, 0, 22, 16, 2, 15, 0,
+  0, 0, 4, 57, 0, 0, 0, 41, 5, 0,
+  60, 0, 19, 1, 4, 1, 52, 31, 4, 0,
+  58, 0, 51, 26, 21, 39, 0, 0, 0, 32,
+  0, 23, 0, 0, 55, 8, 0, 36, 1, 0,
+  0, 0, 14, 29, 63, 36, 0, 0, 0, 0,
+  46, 0, 12, 0, 4, 0, 35, 1, 40, 0,
+  0, 33, 0, 0, 0, 0, 0, 0, 31, 51,
+  0, 0, 37, 2, 0, 0, 4, 70, 43, 0,
+  24, 35, 0, 14, 56, 0, 0, 39, 0, 0,
+  9, 13, 0, 36, 0, 0, 0, 14, 0, 0,
+  0, 19, 0, 41, 0, 0, 0, 5, 3, 0,
+  4, 0, 0, 0, 23, 13, 20, 0, 0, 0,
+  18, 34, 0, 0, 4, 17, 0, 0, 0, 0,
+  21, 0, 0, 0, 0, 23, 10, 1, 39, 9,
+  0, 0, 1, 25, 3, 20, 0, 8, 17, 5,
+  38, 41, 32, 19, 10, 0, 6, 0, 0, 0,
+  0, 5, 45, 39, 4, 0, 0, 0, 0, 31,
+  0, 9, 12, 73, 0, 0, 0, 0, 2, 0,
+  65, 11, 0, 5, 37, 0, 20, 0, 0, 11,
+  0, 8, 0, 32, 0, 0, 31, 0, 19, 0,
+  50, 0, 0, 16, 7, 64, 58, 24, 16, 46,
+  0, 28, 76, 0, 0, 47, 16, 40, 25, 0,
+  0, 27, 0, 0, 0, 37, 5, 0, 0, 0,
+  0, 29, 0, 1, 0, 41, 21, 3, 4, 6,
+  0, 0, 60, 0, 56, 11, 0, 0, 8, 6,
+  0, 26, 13, 0, 0, 0, 0, 0, 17, 6,
+  0, 0, 0, 25, 0, 0, 41, 13, 0, 0,
+  0, 30, 48, 39, 12, 0, 31, 0, 58, 23,
+  37, 56, 3, 0, 8, 19, 0, 16, 0, 10,
+  57, 33, 0, 0, 0, 0, 0, 0, 23, 0,
+  31, 59, 0, 0, 0, 1, 24, 0, 21, 0,
+  8, 0, 47, 0, 77, 0, 1, 23, 9, 0,
+  0, 86, 6, 8, 42, 0, 32, 0, 64, 4,
+  0, 0, 6, 42, 74, 53, 38, 43, 0, 27,
+  68, 0, 0, 42, 0, 47, 25, 9, 0, 24,
+  6, 0, 0, 29, 9, 0, 0, 0, 0, 25,
+  0, 26, 0, 59, 9, 0, 0, 24, 0, 0,
+  45, 0, 88, 34, 0, 0, 0, 0, 0, 9,
+  6, 0, 0, 0, 0, 0, 36, 0, 0, 0,
+  0, 0, 0, 17, 64, 0, 2, 0, 1, 0,
+  91, 28, 8, 0, 51, 13, 35, 13, 47, 25,
+  0, 0, 0, 32, 0, 22, 0, 0, 48, 22,
+  0, 7, 0, 0, 23, 0, 25, 21, 43, 64,
+  10, 0, 0, 0, 29, 0, 0, 0, 18, 0,
+  4, 0, 74, 0, 0, 37, 25, 0, 16, 0,
+  43, 0, 0, 0, 0, 0, 40, 54, 0, 16,
+  0, 59, 14, 0, 21, 57, 23, 17, 21, 14,
+  54, 0, 0, 0, 42, 21, 0, 0, 0, 0,
+  0, 0, 0, 0, 54, 47, 0, 0, 9, 0,
+  0, 0, 0, 0, 9, 0, 0, 0, 23, 0,
+  0, 0, 10, 0, 8, 40, 0, 0, 0, 25,
+  50, 0, 59, 21, 36, 7, 0, 114, 0, 9,
+  8, 6, 0, 0, 4, 34, 0, 0, 0, 19,
+  0, 29, 42, 2, 22, 44, 6, 0, 0, 57,
+  0, 0, 19, 0, 0, 0, 14, 17, 24, 0,
+  0, 0, 0, 0, 0, 0, 0, 39, 0, 0,
+  0, 0, 81, 4, 14, 0, 20, 0, 0, 18,
+  0, 0, 0, 19, 37, 4, 30, 0, 21, 8,
+  18, 0, 0, 0, 23, 36, 0, 0, 0, 54,
+  7, 0, 0, 65, 15, 16, 55, 1, 62, 10,
+  0, 0, 52, 0, 0, 0, 14, 0, 0, 0,
+  0, 0, 9, 33, 0, 0, 29, 0, 0, 9,
+  0, 0, 15, 0, 0, 0, 30, 30, 0, 0,
+  29, 0, 20, 15, 0, 0, 0, 14, 64, 0,
+  89, 22, 8, 0, 0, 130, 0, 14, 8, 0,
+  2, 0, 14, 22, 0, 0, 24, 0, 8, 22,
+  41, 0, 39, 0, 26, 0, 0, 30, 15, 0,
+  0, 0, 0, 0, 23, 0, 15, 0, 0, 0,
+  0, 0, 0, 32, 0, 10, 0, 9, 0, 0,
+  99, 17, 35, 0, 24, 0, 6, 0, 0, 0,
+  0, 31, 25, 0, 5, 13, 0, 32, 19, 0,
+  8, 0, 42, 4, 0, 13, 0, 36, 0, 0,
+  0, 57, 0, 20, 78, 0, 62, 17, 0, 0,
+  48, 0, 0, 0, 23, 0, 0, 0, 0, 0,
+  0, 22, 0, 0, 41, 0, 0, 33, 9, 0,
+  6, 0, 0, 0, 32, 6, 0, 0, 33, 0,
+  37, 0, 4, 0, 0, 39, 62, 0, 84, 8,
+  32, 22, 0, 130, 0, 9, 16, 0, 0, 9,
+  33, 13, 0, 0, 29, 13, 0, 22, 32, 0,
+  33, 0, 24, 0, 0, 28, 10, 0, 0, 0,
+  8, 0, 32, 0, 10, 12, 0, 0, 0, 0,
+  0, 83, 0, 0, 2, 0, 0, 0, 98, 36,
+  46, 0, 18, 0, 8, 0, 0, 0, 0, 28,
+  8, 0, 22, 3, 0, 0, 24, 14, 0, 0,
+  31, 13, 0, 23, 0, 61, 30, 0, 16, 46,
+  7, 38, 53, 0, 0, 0, 7, 20, 37, 0,
+  0, 0, 0, 0, 0, 35, 0, 0, 9, 0,
+  0, 0, 0, 3, 0, 3, 12, 0, 13, 5,
+  0, 0, 57, 0, 3, 0, 0, 0, 27, 17,
+  0, 0, 5, 8, 37, 0, 0, 0, 19, 60,
+  0, 39, 0, 33, 30, 0, 37, 12, 0, 30,
+  0, 10, 5, 30, 0, 0, 41, 0, 71, 36,
+  0, 13, 0, 0, 4, 0, 18, 0, 0, 16,
+  44, 2, 0, 26, 0, 0, 0, 38, 5, 6,
+  19, 51, 0, 0, 0, 14, 43, 20, 37, 0,
+  0, 0, 39, 13, 0, 0, 0, 39, 17, 0,
+  19, 51, 0, 11, 63, 0, 36, 0, 33, 2,
+  0, 24, 2, 46, 28, 0, 6, 25, 11, 52,
+  60, 0, 0, 15, 21, 37, 39, 0, 0, 21,
+  42, 0, 0, 33, 0, 0, 0, 0, 0, 0,
+  0, 29, 0, 51, 23, 0, 7, 28, 0, 0,
+  51, 0, 37, 15, 0, 12, 5, 0, 0, 22,
+  16, 2, 15, 0, 0, 0, 4, 57, 0, 0,
+  0, 41, 5, 0, 60, 0, 19, 1, 4, 1,
+  52, 31, 4, 0, 58, 0, 51, 26, 21, 39,
+  0, 0, 0, 32, 0, 23, 0, 0, 55, 8,
+  0, 36, 1, 0, 0, 0, 14, 29, 63, 36,
+  0, 0, 0, 0, 46, 0, 12, 0, 4, 0,
+  35, 1, 40, 0, 0, 33, 0, 0, 0, 99,
+  0, 38, 55, 0, 74, 0, 47, 0, 0, 55,
+  43, 30, 27, 0, 3, 36, 0, 59, 80, 0,
+  0, 26, 36, 49, 32, 1, 0, 12, 51, 0,
+  22, 17, 3, 0, 0, 0, 0, 0, 0, 20,
+  0, 83, 20, 23, 0, 15, 0, 0, 26, 0,
+  67, 45, 0, 11, 23, 0, 0, 37, 22, 0,
+  0, 0, 0, 0, 14, 67, 0, 0, 0, 11,
+  0, 0, 67, 0, 16, 0, 7, 0, 80, 54,
+  0, 0, 42, 0, 37, 1, 24, 67, 6, 0,
+  0, 40, 0, 45, 0, 0, 77, 8, 0, 34,
+  3, 0, 0, 0, 25, 58, 103, 36, 0, 0,
+  0, 0, 32, 0, 0, 0, 0, 0, 21, 22,
+  80, 0, 38, 25, 8, 0, 0, 32, 0, 0,
+  31, 0, 19, 0, 50, 0, 0, 16, 7, 64,
+  58, 24, 16, 46, 0, 28, 76, 0, 0, 47,
+  16, 40, 25, 0, 0, 27, 0, 0, 0, 37,
+  5, 0, 0, 0, 0, 29, 0, 1, 0, 41,
+  21, 3, 4, 6, 0, 0, 60, 0, 56, 11,
+  0, 0, 8, 6, 0, 26, 13, 0, 0, 0,
+  0, 0, 17, 6, 0, 0, 0, 25, 0, 0,
+  41, 13, 0, 0, 0, 30, 48, 39, 12, 0,
+  31, 0, 58, 23, 37, 56, 3, 0, 8, 19,
+  0, 16, 0, 10, 57, 33, 0, 0, 0, 0,
+  0, 0, 23, 0, 31, 59, 0, 0, 0, 1,
+  24, 0, 21, 0, 8, 0, 47, 0, 77, 0,
+  1, 23, 9, 0, 0, 86, 6, 8, 42, 0,
+  32, 0, 64, 4, 0, 0, 6, 42, 74, 53,
+  38, 43, 0, 27, 68, 0, 0, 42, 0, 47,
+  25, 9, 0, 24, 6, 0, 0, 29, 9, 0,
+  0, 0, 0, 25, 0, 26, 0, 59, 9, 0,
+  0, 24, 0, 0, 45, 0, 88, 34, 0, 0,
+  0, 0, 0, 9, 6, 0, 0, 0, 0, 0,
+  36, 0, 0, 0, 0, 0, 0, 17, 64, 0,
+  2, 0, 1, 0, 91, 28, 8, 0, 51, 13,
+  35, 13, 47, 25, 0, 0, 0, 32, 0, 22,
+  0, 0, 48, 22, 0, 7, 0, 0, 23, 0,
+  25, 21, 43, 64, 10, 0, 0, 0, 29, 0,
+  0, 0, 18, 0, 4, 0, 74, 0, 0, 37,
+  25, 0, 0, 96, 8, 3, 33, 0, 35, 0,
+  85, 3, 0, 27, 4, 58, 40, 66, 33, 44,
+  0, 33, 67, 0, 11, 33, 0, 10, 35, 17,
+  0, 0, 0, 0, 16, 0, 0, 0, 0, 12,
+  0, 0, 0, 9, 0, 67, 0, 25, 0, 38,
+  0, 0, 28, 0, 77, 30, 0, 0, 25, 0,
+  0, 0, 0, 0, 0, 0, 2, 0, 21, 0,
+  17, 0, 0, 0, 18, 29, 78, 0, 11, 0,
+  0, 0, 78, 36, 3, 0, 35, 3, 44, 7,
+  36, 20, 0, 27, 0, 26, 0, 8, 0, 0,
+  61, 33, 8, 16, 0, 0, 58, 0, 22, 29,
+  12, 37, 7, 0, 0, 0, 41, 0, 0, 0,
+  20, 0, 0, 0, 52, 0, 0, 31, 46, 0,
+  30, 0, 21, 8, 18, 0, 0, 0, 23, 36,
+  0, 0, 0, 54, 7, 0, 0, 65, 15, 16,
+  55, 1, 62, 10, 0, 0, 52, 0, 0, 0,
+  14, 0, 0, 0, 0, 0, 9, 33, 0, 0,
+  29, 0, 0, 9, 0, 0, 15, 0, 0, 0,
+  30, 30, 0, 0, 29, 0, 20, 15, 0, 0,
+  0, 14, 64, 0, 89, 22, 8, 0, 0, 130,
+  0, 14, 8, 0, 2, 0, 14, 22, 0, 0,
+  24, 0, 8, 22, 41, 0, 39, 0, 26, 0,
+  0, 30, 15, 0, 0, 0, 0, 0, 23, 0,
+  15, 0, 0, 0, 0, 0, 0, 32, 0, 10,
+  0, 9, 0, 0, 99, 17, 35, 0, 24, 0,
+  6, 0, 0, 0, 0, 31, 25, 0, 5, 13,
+  0, 32, 19, 0, 8, 0, 42, 4, 0, 13,
+  0, 36, 0, 0, 0, 57, 0, 20, 78, 0,
+  62, 17, 0, 0, 48, 0, 0, 0, 23, 0,
+  0, 0, 0, 0, 0, 22, 0, 0, 41, 0,
+  0, 33, 9, 0, 6, 0, 0, 0, 32, 6,
+  0, 0, 33, 0, 37, 0, 4, 0, 0, 39,
+  62, 0, 84, 8, 32, 22, 0, 130, 0, 9,
+  16, 0, 0, 9, 33, 13, 0, 0, 29, 13,
+  0, 22, 32, 0, 33, 0, 24, 0, 0, 28,
+  10, 0, 0, 0, 8, 0, 32, 0, 10, 12,
+  0, 0, 0, 0, 0, 83, 0, 0, 2, 0,
+  0, 0, 98, 36, 46, 0, 18, 0, 8, 0,
+  0, 0, 0, 28, 8, 0, 11, 29, 0, 45,
+  2, 0, 17, 0, 59, 0, 0, 24, 0, 0,
+  0, 0, 0, 40, 1, 11, 70, 0, 8, 10,
+  0, 0, 32, 0, 0, 0, 26, 22, 0, 7,
+  0, 0, 17, 26, 2, 0, 47, 0, 0, 21,
+  13, 9, 8, 0, 0, 0, 39, 2, 0, 18,
+  67, 54, 46, 0, 21, 0, 0, 41, 60, 20,
+  72, 13, 27, 31, 0, 123, 0, 13, 17, 0,
+  0, 28, 28, 13, 17, 0, 23, 19, 0, 3,
+  26, 0, 27, 0, 23, 0, 0, 39, 0, 0,
+  0, 3, 33, 0, 52, 9, 4, 75, 0, 0,
+  0, 0, 0, 100, 0, 0, 2, 0, 0, 11,
+  51, 34, 23, 0, 31, 0, 14, 0, 0, 0,
+  3, 31, 7, 0, 19, 51, 0, 11, 63, 0,
+  36, 0, 33, 2, 0, 24, 2, 46, 28, 0,
+  6, 25, 11, 52, 60, 0, 0, 15, 21, 37,
+  39, 0, 0, 21, 42, 0, 0, 33, 0, 0,
+  0, 0, 0, 0, 0, 29, 0, 51, 23, 0,
+  7, 28, 0, 0, 51, 0, 37, 15, 0, 12,
+  5, 0, 0, 22, 16, 2, 15, 0, 0, 0,
+  4, 57, 0, 0, 0, 41, 5, 0, 60, 0,
+  19, 1, 4, 1, 52, 31, 4, 0, 58, 0,
+  51, 26, 21, 39, 0, 0, 0, 32, 0, 23,
+  0, 0, 55, 8, 0, 36, 1, 0, 0, 0,
+  14, 29, 63, 36, 0, 0, 0, 0, 46, 0,
+  12, 0, 4, 0, 35, 1, 40, 0, 0, 33,
+  0, 0, 0, 99, 0, 38, 55, 0, 74, 0,
+  47, 0, 0, 55, 43, 30, 27, 0, 3, 36,
+  0, 59, 80, 0, 0, 26, 36, 49, 32, 1,
+  0, 12, 51, 0, 22, 17, 3, 0, 0, 0,
+  0, 0, 0, 20, 0, 83, 20, 23, 0, 15,
+  0, 0, 26, 0, 67, 45, 0, 11, 23, 0,
+  0, 37, 22, 0, 0, 0, 0, 0, 14, 67,
+  0, 0, 0, 11, 0, 0, 67, 0, 16, 0,
+  7, 0, 80, 54, 0, 0, 42, 0, 37, 1,
+  24, 67, 6, 0, 0, 40, 0, 45, 0, 0,
+  77, 8, 0, 34, 3, 0, 0, 0, 25, 58,
+  103, 36, 0, 0, 0, 0, 32, 0, 0, 0,
+  0, 0, 21, 22, 80, 0, 38, 25, 8, 0,
+  0, 129, 0, 59, 30, 0, 80, 0, 63, 0,
+  2, 62, 41, 13, 24, 8, 0, 36, 0, 50,
+  73, 0, 0, 34, 40, 69, 39, 5, 0, 13,
+  44, 0, 63, 0, 17, 0, 0, 0, 0, 0,
+  0, 30, 0, 55, 31, 26, 0, 15, 0, 0,
+  34, 0, 63, 66, 0, 6, 53, 0, 0, 76,
+  13, 0, 0, 0, 0, 0, 32, 81, 0, 0,
+  0, 20, 0, 0, 48, 49, 0, 0, 0, 0,
+  65, 72, 1, 0, 21, 0, 34, 0, 17, 106,
+  73, 0, 0, 66, 0, 33, 16, 0, 73, 22,
+  0, 27, 0, 0, 0, 0, 17, 70, 123, 31,
+  8, 0, 18, 0, 19, 0, 0, 0, 0, 0,
+  16, 21, 113, 10, 49, 16, 11, 0, 0, 86,
+  6, 8, 42, 0, 32, 0, 64, 4, 0, 0,
+  6, 42, 74, 53, 38, 43, 0, 27, 68, 0,
+  0, 42, 0, 47, 25, 9, 0, 24, 6, 0,
+  0, 29, 9, 0, 0, 0, 0, 25, 0, 26,
+  0, 59, 9, 0, 0, 24, 0, 0, 45, 0,
+  88, 34, 0, 0, 0, 0, 0, 9, 6, 0,
+  0, 0, 0, 0, 36, 0, 0, 0, 0, 0,
+  0, 17, 64, 0, 2, 0, 1, 0, 91, 28,
+  8, 0, 51, 13, 35, 13, 47, 25, 0, 0,
+  0, 32, 0, 22, 0, 0, 48, 22, 0, 7,
+  0, 0, 23, 0, 25, 21, 43, 64, 10, 0,
+  0, 0, 29, 0, 0, 0, 18, 0, 4, 0,
+  74, 0, 0, 37, 25, 0, 0, 96, 8, 3,
+  33, 0, 35, 0, 85, 3, 0, 27, 4, 58,
+  40, 66, 33, 44, 0, 33, 67, 0, 11, 33,
+  0, 10, 35, 17, 0, 0, 0, 0, 16, 0,
+  0, 0, 0, 12, 0, 0, 0, 9, 0, 67,
+  0, 25, 0, 38, 0, 0, 28, 0, 77, 30,
+  0, 0, 25, 0, 0, 0, 0, 0, 0, 0,
+  2, 0, 21, 0, 17, 0, 0, 0, 18, 29,
+  78, 0, 11, 0, 0, 0, 78, 36, 3, 0,
+  35, 3, 44, 7, 36, 20, 0, 27, 0, 26,
+  0, 8, 0, 0, 61, 33, 8, 16, 0, 0,
+  58, 0, 22, 29, 12, 37, 7, 0, 0, 0,
+  41, 0, 0, 0, 20, 0, 0, 0, 52, 0,
+  0, 31, 46, 0, 0, 50, 11, 21, 17, 0,
+  0, 0, 67, 0, 0, 42, 4, 106, 9, 17,
+  15, 45, 0, 24, 71, 0, 40, 19, 0, 0,
+  0, 3, 0, 0, 0, 0, 0, 10, 0, 0,
+  0, 0, 0, 0, 4, 19, 0, 50, 0, 0,
+  0, 45, 0, 0, 34, 65, 36, 45, 0, 0,
+  44, 0, 0, 0, 0, 0, 7, 0, 60, 7,
+  0, 7, 12, 15, 0, 0, 10, 2, 40, 0,
+  0, 0, 0, 1, 42, 35, 2, 0, 21, 0,
+  58, 15, 51, 12, 0, 30, 0, 0, 0, 9,
+  0, 0, 58, 45, 6, 2, 0, 0, 16, 0,
+  0, 13, 0, 3, 7, 0, 0, 0, 80, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 4,
+  12, 0, 5, 13, 0, 32, 19, 0, 8, 0,
+  42, 4, 0, 13, 0, 36, 0, 0, 0, 57,
+  0, 20, 78, 0, 62, 17, 0, 0, 48, 0,
+  0, 0, 23, 0, 0, 0, 0, 0, 0, 22,
+  0, 0, 41, 0, 0, 33, 9, 0, 6, 0,
+  0, 0, 32, 6, 0, 0, 33, 0, 37, 0,
+  4, 0, 0, 39, 62, 0, 84, 8, 32, 22,
+  0, 130, 0, 9, 16, 0, 0, 9, 33, 13,
+  0, 0, 29, 13, 0, 22, 32, 0, 33, 0,
+  24, 0, 0, 28, 10, 0, 0, 0, 8, 0,
+  32, 0, 10, 12, 0, 0, 0, 0, 0, 83,
+  0, 0, 2, 0, 0, 0, 98, 36, 46, 0,
+  18, 0, 8, 0, 0, 0, 0, 28, 8, 0,
+  11, 29, 0, 45, 2, 0, 17, 0, 59, 0,
+  0, 24, 0, 0, 0, 0, 0, 40, 1, 11,
+  70, 0, 8, 10, 0, 0, 32, 0, 0, 0,
+  26, 22, 0, 7, 0, 0, 17, 26, 2, 0,
+  47, 0, 0, 21, 13, 9, 8, 0, 0, 0,
+  39, 2, 0, 18, 67, 54, 46, 0, 21, 0,
+  0, 41, 60, 20, 72, 13, 27, 31, 0, 123,
+  0, 13, 17, 0, 0, 28, 28, 13, 17, 0,
+  23, 19, 0, 3, 26, 0, 27, 0, 23, 0,
+  0, 39, 0, 0, 0, 3, 33, 0, 52, 9,
+  4, 75, 0, 0, 0, 0, 0, 100, 0, 0,
+  2, 0, 0, 11, 51, 34, 23, 0, 31, 0,
+  14, 0, 0, 0, 3, 31, 7, 0, 11, 24,
+  0, 20, 0, 8, 0, 0, 72, 0, 0, 35,
+  0, 0, 0, 0, 0, 45, 6, 0, 35, 11,
+  0, 11, 0, 0, 13, 0, 0, 0, 2, 13,
+  0, 0, 0, 0, 29, 44, 34, 0, 50, 0,
+  0, 11, 0, 7, 0, 0, 0, 0, 8, 60,
+  0, 0, 108, 136, 34, 5, 37, 0, 0, 24,
+  71, 27, 134, 39, 0, 0, 0, 158, 66, 0,
+  9, 0, 0, 10, 0, 0, 39, 0, 9, 0,
+  13, 5, 9, 0, 4, 0, 70, 0, 0, 80,
+  0, 0, 27, 0, 26, 0, 39, 45, 33, 130,
+  0, 0, 0, 0, 0, 84, 0, 0, 0, 0,
+  0, 24, 23, 13, 0, 0, 36, 0, 0, 0,
+  0, 0, 23, 31, 12, 0, 0, 99, 0, 38,
+  55, 0, 74, 0, 47, 0, 0, 55, 43, 30,
+  27, 0, 3, 36, 0, 59, 80, 0, 0, 26,
+  36, 49, 32, 1, 0, 12, 51, 0, 22, 17,
+  3, 0, 0, 0, 0, 0, 0, 20, 0, 83,
+  20, 23, 0, 15, 0, 0, 26, 0, 67, 45,
+  0, 11, 23, 0, 0, 37, 22, 0, 0, 0,
+  0, 0, 14, 67, 0, 0, 0, 11, 0, 0,
+  67, 0, 16, 0, 7, 0, 80, 54, 0, 0,
+  42, 0, 37, 1, 24, 67, 6, 0, 0, 40,
+  0, 45, 0, 0, 77, 8, 0, 34, 3, 0,
+  0, 0, 25, 58, 103, 36, 0, 0, 0, 0,
+  32, 0, 0, 0, 0, 0, 21, 22, 80, 0,
+  38, 25, 8, 0, 0, 129, 0, 59, 30, 0,
+  80, 0, 63, 0, 2, 62, 41, 13, 24, 8,
+  0, 36, 0, 50, 73, 0, 0, 34, 40, 69,
+  39, 5, 0, 13, 44, 0, 63, 0, 17, 0,
+  0, 0, 0, 0, 0, 30, 0, 55, 31, 26,
+  0, 15, 0, 0, 34, 0, 63, 66, 0, 6,
+  53, 0, 0, 76, 13, 0, 0, 0, 0, 0,
+  32, 81, 0, 0, 0, 20, 0, 0, 48, 49,
+  0, 0, 0, 0, 65, 72, 1, 0, 21, 0,
+  34, 0, 17, 106, 73, 0, 0, 66, 0, 33,
+  16, 0, 73, 22, 0, 27, 0, 0, 0, 0,
+  17, 70, 123, 31, 8, 0, 18, 0, 19, 0,
+  0, 0, 0, 0, 16, 21, 113, 10, 49, 16,
+  11, 0, 4, 112, 0, 54, 23, 0, 15, 0,
+  85, 7, 0, 53, 5, 3, 0, 0, 0, 18,
+  0, 13, 49, 0, 0, 31, 10, 11, 45, 17,
+  0, 0, 0, 9, 32, 0, 23, 0, 0, 18,
+  0, 0, 0, 0, 0, 18, 25, 27, 0, 0,
+  0, 0, 33, 14, 7, 64, 44, 38, 45, 0,
+  0, 10, 0, 11, 7, 12, 0, 7, 17, 45,
+  0, 29, 0, 13, 26, 0, 1, 55, 0, 8,
+  5, 0, 20, 44, 16, 23, 0, 0, 15, 29,
+  38, 55, 93, 0, 0, 17, 0, 0, 52, 0,
+  35, 52, 0, 80, 0, 0, 0, 0, 0, 84,
+  112, 0, 31, 0, 15, 3, 1, 0, 0, 0,
+  0, 0, 3, 0, 28, 0, 45, 32, 0, 0,
+  0, 96, 8, 3, 33, 0, 35, 0, 85, 3,
+  0, 27, 4, 58, 40, 66, 33, 44, 0, 33,
+  67, 0, 11, 33, 0, 10, 35, 17, 0, 0,
+  0, 0, 16, 0, 0, 0, 0, 12, 0, 0,
+  0, 9, 0, 67, 0, 25, 0, 38, 0, 0,
+  28, 0, 77, 30, 0, 0, 25, 0, 0, 0,
+  0, 0, 0, 0, 2, 0, 21, 0, 17, 0,
+  0, 0, 18, 29, 78, 0, 11, 0, 0, 0,
+  78, 36, 3, 0, 35, 3, 44, 7, 36, 20,
+  0, 27, 0, 26, 0, 8, 0, 0, 61, 33,
+  8, 16, 0, 0, 58, 0, 22, 29, 12, 37,
+  7, 0, 0, 0, 41, 0, 0, 0, 20, 0,
+  0, 0, 52, 0, 0, 31, 46, 0, 0, 50,
+  11, 21, 17, 0, 0, 0, 67, 0, 0, 42,
+  4, 106, 9, 17, 15, 45, 0, 24, 71, 0,
+  40, 19, 0, 0, 0, 3, 0, 0, 0, 0,
+  0, 10, 0, 0, 0, 0, 0, 0, 4, 19,
+  0, 50, 0, 0, 0, 45, 0, 0, 34, 65,
+  36, 45, 0, 0, 44, 0, 0, 0, 0, 0,
+  7, 0, 60, 7, 0, 7, 12, 15, 0, 0,
+  10, 2, 40, 0, 0, 0, 0, 1, 42, 35,
+  2, 0, 21, 0, 58, 15, 51, 12, 0, 30,
+  0, 0, 0, 9, 0, 0, 58, 45, 6, 2,
+  0, 0, 16, 0, 0, 13, 0, 3, 7, 0,
+  0, 0, 80, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 4, 12, 0, 20, 58, 19, 29,
+  24, 0, 0, 0, 79, 0, 0, 44, 19, 100,
+  0, 0, 0, 11, 0, 4, 57, 0, 28, 24,
+  0, 0, 2, 0, 0, 3, 5, 0, 0, 6,
+  0, 0, 0, 0, 0, 0, 0, 34, 0, 24,
+  0, 0, 6, 41, 0, 0, 50, 104, 10, 72,
+  18, 0, 43, 0, 5, 0, 0, 0, 14, 0,
+  25, 49, 0, 0, 0, 41, 0, 14, 1, 0,
+  14, 2, 0, 0, 0, 33, 14, 52, 21, 0,
+  21, 0, 41, 46, 70, 27, 15, 0, 0, 0,
+  0, 6, 30, 0, 57, 63, 0, 18, 0, 0,
+  0, 0, 0, 23, 55, 0, 32, 0, 0, 0,
+  90, 0, 14, 0, 0, 0, 5, 1, 0, 0,
+  20, 7, 0, 0, 11, 29, 0, 45, 2, 0,
+  17, 0, 59, 0, 0, 24, 0, 0, 0, 0,
+  0, 40, 1, 11, 70, 0, 8, 10, 0, 0,
+  32, 0, 0, 0, 26, 22, 0, 7, 0, 0,
+  17, 26, 2, 0, 47, 0, 0, 21, 13, 9,
+  8, 0, 0, 0, 39, 2, 0, 18, 67, 54,
+  46, 0, 21, 0, 0, 41, 60, 20, 72, 13,
+  27, 31, 0, 123, 0, 13, 17, 0, 0, 28,
+  28, 13, 17, 0, 23, 19, 0, 3, 26, 0,
+  27, 0, 23, 0, 0, 39, 0, 0, 0, 3,
+  33, 0, 52, 9, 4, 75, 0, 0, 0, 0,
+  0, 100, 0, 0, 2, 0, 0, 11, 51, 34,
+  23, 0, 31, 0, 14, 0, 0, 0, 3, 31,
+  7, 0, 11, 24, 0, 20, 0, 8, 0, 0,
+  72, 0, 0, 35, 0, 0, 0, 0, 0, 45,
+  6, 0, 35, 11, 0, 11, 0, 0, 13, 0,
+  0, 0, 2, 13, 0, 0, 0, 0, 29, 44,
+  34, 0, 50, 0, 0, 11, 0, 7, 0, 0,
+  0, 0, 8, 60, 0, 0, 108, 136, 34, 5,
+  37, 0, 0, 24, 71, 27, 134, 39, 0, 0,
+  0, 158, 66, 0, 9, 0, 0, 10, 0, 0,
+  39, 0, 9, 0, 13, 5, 9, 0, 4, 0,
+  70, 0, 0, 80, 0, 0, 27, 0, 26, 0,
+  39, 45, 33, 130, 0, 0, 0, 0, 0, 84,
+  0, 0, 0, 0, 0, 24, 23, 13, 0, 0,
+  36, 0, 0, 0, 0, 0, 23, 31, 12, 0,
+  0, 15, 0, 0, 0, 50, 0, 0, 53, 14,
+  0, 2, 0, 0, 0, 0, 0, 48, 12, 0,
+  0, 0, 0, 19, 0, 0, 0, 3, 0, 0,
+  3, 11, 0, 0, 0, 9, 43, 82, 35, 0,
+  70, 0, 5, 16, 0, 7, 7, 0, 0, 0,
+  0, 63, 0, 0, 57, 160, 47, 9, 35, 0,
+  0, 29, 57, 0, 153, 4, 0, 0, 0, 121,
+  122, 0, 14, 27, 0, 33, 0, 0, 46, 0,
+  6, 0, 5, 13, 16, 0, 0, 10, 64, 0,
+  0, 128, 0, 0, 35, 0, 0, 0, 10, 76,
+  58, 96, 0, 0, 0, 0, 0, 62, 0, 0,
+  0, 3, 0, 35, 0, 0, 0, 0, 53, 0,
+  0, 0, 0, 0, 18, 28, 29, 0, 0, 129,
+  0, 59, 30, 0, 80, 0, 63, 0, 2, 62,
+  41, 13, 24, 8, 0, 36, 0, 50, 73, 0,
+  0, 34, 40, 69, 39, 5, 0, 13, 44, 0,
+  63, 0, 17, 0, 0, 0, 0, 0, 0, 30,
+  0, 55, 31, 26, 0, 15, 0, 0, 34, 0,
+  63, 66, 0, 6, 53, 0, 0, 76, 13, 0,
+  0, 0, 0, 0, 32, 81, 0, 0, 0, 20,
+  0, 0, 48, 49, 0, 0, 0, 0, 65, 72,
+  1, 0, 21, 0, 34, 0, 17, 106, 73, 0,
+  0, 66, 0, 33, 16, 0, 73, 22, 0, 27,
+  0, 0, 0, 0, 17, 70, 123, 31, 8, 0,
+  18, 0, 19, 0, 0, 0, 0, 0, 16, 21,
+  113, 10, 49, 16, 11, 0, 4, 112, 0, 54,
+  23, 0, 15, 0, 85, 7, 0, 53, 5, 3,
+  0, 0, 0, 18, 0, 13, 49, 0, 0, 31,
+  10, 11, 45, 17, 0, 0, 0, 9, 32, 0,
+  23, 0, 0, 18, 0, 0, 0, 0, 0, 18,
+  25, 27, 0, 0, 0, 0, 33, 14, 7, 64,
+  44, 38, 45, 0, 0, 10, 0, 11, 7, 12,
+  0, 7, 17, 45, 0, 29, 0, 13, 26, 0,
+  1, 55, 0, 8, 5, 0, 20, 44, 16, 23,
+  0, 0, 15, 29, 38, 55, 93, 0, 0, 17,
+  0, 0, 52, 0, 35, 52, 0, 80, 0, 0,
+  0, 0, 0, 84, 112, 0, 31, 0, 15, 3,
+  1, 0, 0, 0, 0, 0, 3, 0, 28, 0,
+  45, 32, 0, 0, 29, 57, 0, 24, 0, 27,
+  0, 0, 42, 0, 0, 31, 0, 13, 0, 0,
+  0, 38, 15, 0, 3, 20, 0, 0, 0, 0,
+  2, 0, 0, 0, 0, 33, 0, 0, 0, 22,
+  12, 36, 5, 0, 22, 0, 25, 16, 5, 0,
+  6, 0, 0, 0, 0, 74, 0, 26, 125, 100,
+  30, 22, 18, 0, 0, 43, 75, 37, 102, 36,
+  0, 20, 0, 109, 123, 3, 27, 0, 0, 17,
+  0, 0, 34, 0, 0, 1, 35, 33, 3, 0,
+  0, 8, 62, 0, 21, 30, 0, 0, 38, 0,
+  43, 0, 9, 59, 0, 117, 0, 0, 0, 0,
+  0, 80, 21, 0, 14, 0, 0, 24, 0, 0,
+  0, 0, 10, 0, 0, 0, 0, 0, 32, 35,
+  0, 0, 0, 50, 11, 21, 17, 0, 0, 0,
+  67, 0, 0, 42, 4, 106, 9, 17, 15, 45,
+  0, 24, 71, 0, 40, 19, 0, 0, 0, 3,
+  0, 0, 0, 0, 0, 10, 0, 0, 0, 0,
+  0, 0, 4, 19, 0, 50, 0, 0, 0, 45,
+  0, 0, 34, 65, 36, 45, 0, 0, 44, 0,
+  0, 0, 0, 0, 7, 0, 60, 7, 0, 7,
+  12, 15, 0, 0, 10, 2, 40, 0, 0, 0,
+  0, 1, 42, 35, 2, 0, 21, 0, 58, 15,
+  51, 12, 0, 30, 0, 0, 0, 9, 0, 0,
+  58, 45, 6, 2, 0, 0, 16, 0, 0, 13,
+  0, 3, 7, 0, 0, 0, 80, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 4, 12, 0,
+  20, 58, 19, 29, 24, 0, 0, 0, 79, 0,
+  0, 44, 19, 100, 0, 0, 0, 11, 0, 4,
+  57, 0, 28, 24, 0, 0, 2, 0, 0, 3,
+  5, 0, 0, 6, 0, 0, 0, 0, 0, 0,
+  0, 34, 0, 24, 0, 0, 6, 41, 0, 0,
+  50, 104, 10, 72, 18, 0, 43, 0, 5, 0,
+  0, 0, 14, 0, 25, 49, 0, 0, 0, 41,
+  0, 14, 1, 0, 14, 2, 0, 0, 0, 33,
+  14, 52, 21, 0, 21, 0, 41, 46, 70, 27,
+  15, 0, 0, 0, 0, 6, 30, 0, 57, 63,
+  0, 18, 0, 0, 0, 0, 0, 23, 55, 0,
+  32, 0, 0, 0, 90, 0, 14, 0, 0, 0,
+  5, 1, 0, 0, 20, 7, 0, 0, 56, 103,
+  0, 45, 15, 0, 0, 0, 58, 0, 0, 52,
+  30, 60, 0, 0, 0, 11, 22, 8, 26, 0,
+  0, 48, 0, 0, 58, 0, 0, 0, 19, 13,
+  0, 0, 3, 0, 0, 0, 0, 0, 0, 0,
+  0, 14, 26, 11, 2, 0, 0, 0, 23, 83,
+  1, 41, 67, 0, 39, 3, 0, 0, 0, 31,
+  34, 12, 4, 15, 0, 13, 0, 63, 0, 12,
+  10, 0, 0, 36, 0, 0, 33, 0, 0, 39,
+  30, 13, 0, 0, 19, 60, 73, 69, 93, 0,
+  0, 0, 0, 0, 59, 0, 21, 68, 23, 82,
+  0, 0, 0, 0, 0, 52, 129, 3, 21, 0,
+  0, 7, 40, 0, 0, 0, 3, 0, 26, 0,
+  14, 0, 57, 39, 0, 0, 11, 24, 0, 20,
+  0, 8, 0, 0, 72, 0, 0, 35, 0, 0,
+  0, 0, 0, 45, 6, 0, 35, 11, 0, 11,
+  0, 0, 13, 0, 0, 0, 2, 13, 0, 0,
+  0, 0, 29, 44, 34, 0, 50, 0, 0, 11,
+  0, 7, 0, 0, 0, 0, 8, 60, 0, 0,
+  108, 136, 34, 5, 37, 0, 0, 24, 71, 27,
+  134, 39, 0, 0, 0, 158, 66, 0, 9, 0,
+  0, 10, 0, 0, 39, 0, 9, 0, 13, 5,
+  9, 0, 4, 0, 70, 0, 0, 80, 0, 0,
+  27, 0, 26, 0, 39, 45, 33, 130, 0, 0,
+  0, 0, 0, 84, 0, 0, 0, 0, 0, 24,
+  23, 13, 0, 0, 36, 0, 0, 0, 0, 0,
+  23, 31, 12, 0, 0, 15, 0, 0, 0, 50,
+  0, 0, 53, 14, 0, 2, 0, 0, 0, 0,
+  0, 48, 12, 0, 0, 0, 0, 19, 0, 0,
+  0, 3, 0, 0, 3, 11, 0, 0, 0, 9,
+  43, 82, 35, 0, 70, 0, 5, 16, 0, 7,
+  7, 0, 0, 0, 0, 63, 0, 0, 57, 160,
+  47, 9, 35, 0, 0, 29, 57, 0, 153, 4,
+  0, 0, 0, 121, 122, 0, 14, 27, 0, 33,
+  0, 0, 46, 0, 6, 0, 5, 13, 16, 0,
+  0, 10, 64, 0, 0, 128, 0, 0, 35, 0,
+  0, 0, 10, 76, 58, 96, 0, 0, 0, 0,
+  0, 62, 0, 0, 0, 3, 0, 35, 0, 0,
+  0, 0, 53, 0, 0, 0, 0, 0, 18, 28,
+  29, 0, 0, 39, 0, 0, 0, 29, 0, 0,
+  78, 47, 0, 0, 30, 0, 0, 88, 39, 61,
+  6, 17, 0, 0, 0, 41, 0, 0, 7, 53,
+  6, 0, 17, 0, 36, 0, 0, 0, 35, 96,
+  0, 0, 48, 0, 9, 30, 0, 28, 42, 19,
+  0, 0, 0, 32, 2, 0, 4, 101, 46, 8,
+  0, 0, 0, 0, 0, 0, 66, 0, 6, 4,
+  24, 53, 52, 0, 17, 37, 0, 49, 0, 0,
+  5, 0, 39, 0, 0, 0, 0, 1, 0, 30,
+  51, 0, 0, 131, 0, 0, 11, 0, 0, 0,
+  0, 86, 87, 31, 0, 0, 0, 0, 0, 48,
+  0, 13, 0, 11, 0, 8, 2, 0, 0, 2,
+  51, 0, 25, 0, 41, 0, 28, 12, 43, 0,
+  4, 112, 0, 54, 23, 0, 15, 0, 85, 7,
+  0, 53, 5, 3, 0, 0, 0, 18, 0, 13,
+  49, 0, 0, 31, 10, 11, 45, 17, 0, 0,
+  0, 9, 32, 0, 23, 0, 0, 18, 0, 0,
+  0, 0, 0, 18, 25, 27, 0, 0, 0, 0,
+  33, 14, 7, 64, 44, 38, 45, 0, 0, 10,
+  0, 11, 7, 12, 0, 7, 17, 45, 0, 29,
+  0, 13, 26, 0, 1, 55, 0, 8, 5, 0,
+  20, 44, 16, 23, 0, 0, 15, 29, 38, 55,
+  93, 0, 0, 17, 0, 0, 52, 0, 35, 52,
+  0, 80, 0, 0, 0, 0, 0, 84, 112, 0,
+  31, 0, 15, 3, 1, 0, 0, 0, 0, 0,
+  3, 0, 28, 0, 45, 32, 0, 0, 29, 57,
+  0, 24, 0, 27, 0, 0, 42, 0, 0, 31,
+  0, 13, 0, 0, 0, 38, 15, 0, 3, 20,
+  0, 0, 0, 0, 2, 0, 0, 0, 0, 33,
+  0, 0, 0, 22, 12, 36, 5, 0, 22, 0,
+  25, 16, 5, 0, 6, 0, 0, 0, 0, 74,
+  0, 26, 125, 100, 30, 22, 18, 0, 0, 43,
+  75, 37, 102, 36, 0, 20, 0, 109, 123, 3,
+  27, 0, 0, 17, 0, 0, 34, 0, 0, 1,
+  35, 33, 3, 0, 0, 8, 62, 0, 21, 30,
+  0, 0, 38, 0, 43, 0, 9, 59, 0, 117,
+  0, 0, 0, 0, 0, 80, 21, 0, 14, 0,
+  0, 24, 0, 0, 0, 0, 10, 0, 0, 0,
+  0, 0, 32, 35, 0, 0, 10, 25, 0, 0,
+  0, 85, 0, 0, 22, 0, 0, 0, 0, 0,
+  0, 0, 0, 39, 3, 8, 0, 40, 0, 0,
+  0, 0, 8, 3, 0, 0, 0, 38, 0, 0,
+  0, 43, 47, 68, 23, 0, 46, 0, 22, 15,
+  0, 13, 59, 13, 0, 0, 0, 55, 0, 0,
+  112, 118, 34, 26, 48, 0, 0, 57, 67, 0,
+  179, 5, 0, 32, 0, 139, 175, 0, 10, 15,
+  0, 0, 0, 0, 42, 0, 0, 0, 28, 19,
+  31, 0, 0, 11, 42, 0, 0, 116, 13, 0,
+  34, 0, 0, 0, 6, 54, 43, 142, 0, 0,
+  0, 0, 0, 58, 0, 0, 0, 29, 0, 30,
+  0, 10, 0, 0, 53, 0, 0, 0, 0, 0,
+  1, 29, 1, 6, 20, 58, 19, 29, 24, 0,
+  0, 0, 79, 0, 0, 44, 19, 100, 0, 0,
+  0, 11, 0, 4, 57, 0, 28, 24, 0, 0,
+  2, 0, 0, 3, 5, 0, 0, 6, 0, 0,
+  0, 0, 0, 0, 0, 34, 0, 24, 0, 0,
+  6, 41, 0, 0, 50, 104, 10, 72, 18, 0,
+  43, 0, 5, 0, 0, 0, 14, 0, 25, 49,
+  0, 0, 0, 41, 0, 14, 1, 0, 14, 2,
+  0, 0, 0, 33, 14, 52, 21, 0, 21, 0,
+  41, 46, 70, 27, 15, 0, 0, 0, 0, 6,
+  30, 0, 57, 63, 0, 18, 0, 0, 0, 0,
+  0, 23, 55, 0, 32, 0, 0, 0, 90, 0,
+  14, 0, 0, 0, 5, 1, 0, 0, 20, 7,
+  0, 0, 56, 103, 0, 45, 15, 0, 0, 0,
+  58, 0, 0, 52, 30, 60, 0, 0, 0, 11,
+  22, 8, 26, 0, 0, 48, 0, 0, 58, 0,
+  0, 0, 19, 13, 0, 0, 3, 0, 0, 0,
+  0, 0, 0, 0, 0, 14, 26, 11, 2, 0,
+  0, 0, 23, 83, 1, 41, 67, 0, 39, 3,
+  0, 0, 0, 31, 34, 12, 4, 15, 0, 13,
+  0, 63, 0, 12, 10, 0, 0, 36, 0, 0,
+  33, 0, 0, 39, 30, 13, 0, 0, 19, 60,
+  73, 69, 93, 0, 0, 0, 0, 0, 59, 0,
+  21, 68, 23, 82, 0, 0, 0, 0, 0, 52,
+  129, 3, 21, 0, 0, 7, 40, 0, 0, 0,
+  3, 0, 26, 0, 14, 0, 57, 39, 0, 0,
+  46, 82, 0, 50, 1, 35, 0, 0, 22, 0,
+  0, 15, 41, 6, 0, 0, 0, 19, 21, 11,
+  13, 31, 0, 0, 0, 0, 64, 0, 0, 0,
+  30, 54, 0, 0, 28, 29, 0, 17, 0, 0,
+  0, 0, 1, 18, 5, 11, 10, 0, 0, 0,
+  0, 57, 0, 22, 95, 48, 30, 4, 0, 0,
+  0, 73, 54, 11, 88, 0, 0, 66, 0, 94,
+  130, 13, 9, 0, 0, 4, 0, 2, 68, 0,
+  0, 0, 23, 16, 20, 0, 0, 28, 33, 13,
+  56, 0, 0, 0, 6, 0, 47, 0, 18, 68,
+  22, 150, 0, 0, 0, 0, 0, 82, 91, 0,
+  7, 26, 10, 31, 0, 0, 0, 0, 31, 0,
+  0, 0, 0, 0, 50, 35, 0, 2, 0, 15,
+  0, 0, 0, 50, 0, 0, 53, 14, 0, 2,
+  0, 0, 0, 0, 0, 48, 12, 0, 0, 0,
+  0, 19, 0, 0, 0, 3, 0, 0, 3, 11,
+  0, 0, 0, 9, 43, 82, 35, 0, 70, 0,
+  5, 16, 0, 7, 7, 0, 0, 0, 0, 63,
+  0, 0, 57, 160, 47, 9, 35, 0, 0, 29,
+  57, 0, 153, 4, 0, 0, 0, 121, 122, 0,
+  14, 27, 0, 33, 0, 0, 46, 0, 6, 0,
+  5, 13, 16, 0, 0, 10, 64, 0, 0, 128,
+  0, 0, 35, 0, 0, 0, 10, 76, 58, 96,
+  0, 0, 0, 0, 0, 62, 0, 0, 0, 3,
+  0, 35, 0, 0, 0, 0, 53, 0, 0, 0,
+  0, 0, 18, 28, 29, 0, 0, 39, 0, 0,
+  0, 29, 0, 0, 78, 47, 0, 0, 30, 0,
+  0, 88, 39, 61, 6, 17, 0, 0, 0, 41,
+  0, 0, 7, 53, 6, 0, 17, 0, 36, 0,
+  0, 0, 35, 96, 0, 0, 48, 0, 9, 30,
+  0, 28, 42, 19, 0, 0, 0, 32, 2, 0,
+  4, 101, 46, 8, 0, 0, 0, 0, 0, 0,
+  66, 0, 6, 4, 24, 53, 52, 0, 17, 37,
+  0, 49, 0, 0, 5, 0, 39, 0, 0, 0,
+  0, 1, 0, 30, 51, 0, 0, 131, 0, 0,
+  11, 0, 0, 0, 0, 86, 87, 31, 0, 0,
+  0, 0, 0, 48, 0, 13, 0, 11, 0, 8,
+  2, 0, 0, 2, 51, 0, 25, 0, 41, 0,
+  28, 12, 43, 0, 0, 93, 41, 0, 7, 0,
+  52, 3, 86, 40, 12, 0, 76, 3, 0, 125,
+  70, 39, 2, 33, 0, 0, 0, 54, 36, 13,
+  16, 61, 3, 0, 21, 0, 90, 1, 0, 0,
+  0, 58, 0, 29, 9, 0, 26, 52, 0, 59,
+  72, 36, 0, 44, 0, 0, 84, 12, 0, 0,
+  22, 0, 0, 42, 0, 0, 0, 0, 0, 0,
+  47, 0, 62, 0, 0, 0, 2, 50, 38, 28,
+  0, 0, 0, 0, 77, 11, 8, 0, 0, 21,
+  0, 22, 43, 0, 0, 57, 0, 32, 0, 0,
+  0, 0, 0, 79, 66, 0, 0, 0, 15, 0,
+  10, 29, 0, 69, 0, 1, 0, 0, 0, 0,
+  0, 36, 65, 0, 62, 0, 139, 0, 57, 16,
+  25, 0, 29, 57, 0, 24, 0, 27, 0, 0,
+  42, 0, 0, 31, 0, 13, 0, 0, 0, 38,
+  15, 0, 3, 20, 0, 0, 0, 0, 2, 0,
+  0, 0, 0, 33, 0, 0, 0, 22, 12, 36,
+  5, 0, 22, 0, 25, 16, 5, 0, 6, 0,
+  0, 0, 0, 74, 0, 26, 125, 100, 30, 22,
+  18, 0, 0, 43, 75, 37, 102, 36, 0, 20,
+  0, 109, 123, 3, 27, 0, 0, 17, 0, 0,
+  34, 0, 0, 1, 35, 33, 3, 0, 0, 8,
+  62, 0, 21, 30, 0, 0, 38, 0, 43, 0,
+  9, 59, 0, 117, 0, 0, 0, 0, 0, 80,
+  21, 0, 14, 0, 0, 24, 0, 0, 0, 0,
+  10, 0, 0, 0, 0, 0, 32, 35, 0, 0,
+  10, 25, 0, 0, 0, 85, 0, 0, 22, 0,
+  0, 0, 0, 0, 0, 0, 0, 39, 3, 8,
+  0, 40, 0, 0, 0, 0, 8, 3, 0, 0,
+  0, 38, 0, 0, 0, 43, 47, 68, 23, 0,
+  46, 0, 22, 15, 0, 13, 59, 13, 0, 0,
+  0, 55, 0, 0, 112, 118, 34, 26, 48, 0,
+  0, 57, 67, 0, 179, 5, 0, 32, 0, 139,
+  175, 0, 10, 15, 0, 0, 0, 0, 42, 0,
+  0, 0, 28, 19, 31, 0, 0, 11, 42, 0,
+  0, 116, 13, 0, 34, 0, 0, 0, 6, 54,
+  43, 142, 0, 0, 0, 0, 0, 58, 0, 0,
+  0, 29, 0, 30, 0, 10, 0, 0, 53, 0,
+  0, 0, 0, 0, 1, 29, 1, 6, 0, 37,
+  0, 0, 0, 81, 0, 0, 83, 32, 0, 0,
+  0, 9, 0, 42, 6, 26, 0, 10, 0, 0,
+  0, 25, 0, 0, 22, 40, 7, 0, 0, 0,
+  67, 0, 0, 20, 33, 86, 0, 0, 32, 0,
+  0, 10, 0, 67, 54, 81, 0, 26, 0, 6,
+  0, 0, 25, 36, 58, 0, 32, 0, 0, 65,
+  0, 0, 102, 0, 0, 34, 25, 57, 85, 0,
+  33, 59, 0, 79, 0, 0, 3, 0, 3, 0,
+  2, 0, 0, 0, 0, 49, 15, 0, 0, 173,
+  0, 0, 0, 0, 0, 0, 0, 64, 113, 110,
+  0, 0, 0, 0, 0, 29, 0, 22, 0, 30,
+  0, 19, 0, 0, 0, 29, 61, 0, 40, 0,
+  0, 0, 0, 15, 1, 35, 56, 103, 0, 45,
+  15, 0, 0, 0, 58, 0, 0, 52, 30, 60,
+  0, 0, 0, 11, 22, 8, 26, 0, 0, 48,
+  0, 0, 58, 0, 0, 0, 19, 13, 0, 0,
+  3, 0, 0, 0, 0, 0, 0, 0, 0, 14,
+  26, 11, 2, 0, 0, 0, 23, 83, 1, 41,
+  67, 0, 39, 3, 0, 0, 0, 31, 34, 12,
+  4, 15, 0, 13, 0, 63, 0, 12, 10, 0,
+  0, 36, 0, 0, 33, 0, 0, 39, 30, 13,
+  0, 0, 19, 60, 73, 69, 93, 0, 0, 0,
+  0, 0, 59, 0, 21, 68, 23, 82, 0, 0,
+  0, 0, 0, 52, 129, 3, 21, 0, 0, 7,
+  40, 0, 0, 0, 3, 0, 26, 0, 14, 0,
+  57, 39, 0, 0, 46, 82, 0, 50, 1, 35,
+  0, 0, 22, 0, 0, 15, 41, 6, 0, 0,
+  0, 19, 21, 11, 13, 31, 0, 0, 0, 0,
+  64, 0, 0, 0, 30, 54, 0, 0, 28, 29,
+  0, 17, 0, 0, 0, 0, 1, 18, 5, 11,
+  10, 0, 0, 0, 0, 57, 0, 22, 95, 48,
+  30, 4, 0, 0, 0, 73, 54, 11, 88, 0,
+  0, 66, 0, 94, 130, 13, 9, 0, 0, 4,
+  0, 2, 68, 0, 0, 0, 23, 16, 20, 0,
+  0, 28, 33, 13, 56, 0, 0, 0, 6, 0,
+  47, 0, 18, 68, 22, 150, 0, 0, 0, 0,
+  0, 82, 91, 0, 7, 26, 10, 31, 0, 0,
+  0, 0, 31, 0, 0, 0, 0, 0, 50, 35,
+  0, 2, 1, 12, 0, 19, 0, 115, 0, 0,
+  17, 0, 0, 0, 0, 1, 0, 0, 0, 28,
+  11, 16, 0, 65, 2, 0, 0, 0, 23, 0,
+  0, 0, 0, 17, 8, 0, 9, 65, 12, 45,
+  5, 0, 48, 0, 0, 18, 0, 33, 46, 0,
+  0, 7, 0, 29, 0, 0, 131, 59, 54, 5,
+  43, 0, 0, 107, 51, 0, 166, 0, 0, 46,
+  0, 112, 193, 0, 44, 0, 0, 35, 0, 0,
+  29, 0, 0, 0, 32, 0, 28, 0, 0, 1,
+  14, 0, 0, 79, 16, 0, 38, 0, 0, 0,
+  3, 61, 47, 127, 0, 0, 0, 0, 0, 36,
+  0, 0, 0, 55, 0, 53, 0, 0, 0, 0,
+  47, 0, 0, 0, 0, 0, 13, 18, 0, 12,
+  0, 39, 0, 0, 0, 29, 0, 0, 78, 47,
+  0, 0, 30, 0, 0, 88, 39, 61, 6, 17,
+  0, 0, 0, 41, 0, 0, 7, 53, 6, 0,
+  17, 0, 36, 0, 0, 0, 35, 96, 0, 0,
+  48, 0, 9, 30, 0, 28, 42, 19, 0, 0,
+  0, 32, 2, 0, 4, 101, 46, 8, 0, 0,
+  0, 0, 0, 0, 66, 0, 6, 4, 24, 53,
+  52, 0, 17, 37, 0, 49, 0, 0, 5, 0,
+  39, 0, 0, 0, 0, 1, 0, 30, 51, 0,
+  0, 131, 0, 0, 11, 0, 0, 0, 0, 86,
+  87, 31, 0, 0, 0, 0, 0, 48, 0, 13,
+  0, 11, 0, 8, 2, 0, 0, 2, 51, 0,
+  25, 0, 41, 0, 28, 12, 43, 0, 0, 93,
+  41, 0, 7, 0, 52, 3, 86, 40, 12, 0,
+  76, 3, 0, 125, 70, 39, 2, 33, 0, 0,
+  0, 54, 36, 13, 16, 61, 3, 0, 21, 0,
+  90, 1, 0, 0, 0, 58, 0, 29, 9, 0,
+  26, 52, 0, 59, 72, 36, 0, 44, 0, 0,
+  84, 12, 0, 0, 22, 0, 0, 42, 0, 0,
+  0, 0, 0, 0, 47, 0, 62, 0, 0, 0,
+  2, 50, 38, 28, 0, 0, 0, 0, 77, 11,
+  8, 0, 0, 21, 0, 22, 43, 0, 0, 57,
+  0, 32, 0, 0, 0, 0, 0, 79, 66, 0,
+  0, 0, 15, 0, 10, 29, 0, 69, 0, 1,
+  0, 0, 0, 0, 0, 36, 65, 0, 62, 0,
+  139, 0, 57, 16, 25, 0, 0, 58, 49, 0,
+  14, 0, 50, 16, 63, 8, 3, 26, 61, 1,
+  7, 53, 52, 0, 0, 15, 0, 27, 43, 19,
+  23, 0, 0, 13, 0, 0, 0, 0, 41, 0,
+  0, 6, 0, 16, 0, 79, 0, 24, 0, 55,
+  1, 70, 61, 46, 0, 21, 0, 20, 72, 1,
+  0, 0, 29, 0, 0, 0, 15, 36, 0, 43,
+  0, 14, 0, 0, 79, 0, 0, 0, 7, 27,
+  66, 15, 34, 28, 0, 0, 79, 0, 29, 0,
+  25, 0, 16, 0, 0, 0, 0, 0, 0, 17,
+  0, 26, 0, 0, 5, 71, 31, 0, 0, 0,
+  26, 0, 28, 0, 0, 38, 0, 0, 0, 2,
+  0, 0, 2, 14, 69, 0, 27, 0, 63, 0,
+  43, 7, 17, 0, 10, 25, 0, 0, 0, 85,
+  0, 0, 22, 0, 0, 0, 0, 0, 0, 0,
+  0, 39, 3, 8, 0, 40, 0, 0, 0, 0,
+  8, 3, 0, 0, 0, 38, 0, 0, 0, 43,
+  47, 68, 23, 0, 46, 0, 22, 15, 0, 13,
+  59, 13, 0, 0, 0, 55, 0, 0, 112, 118,
+  34, 26, 48, 0, 0, 57, 67, 0, 179, 5,
+  0, 32, 0, 139, 175, 0, 10, 15, 0, 0,
+  0, 0, 42, 0, 0, 0, 28, 19, 31, 0,
+  0, 11, 42, 0, 0, 116, 13, 0, 34, 0,
+  0, 0, 6, 54, 43, 142, 0, 0, 0, 0,
+  0, 58, 0, 0, 0, 29, 0, 30, 0, 10,
+  0, 0, 53, 0, 0, 0, 0, 0, 1, 29,
+  1, 6, 0, 37, 0, 0, 0, 81, 0, 0,
+  83, 32, 0, 0, 0, 9, 0, 42, 6, 26,
+  0, 10, 0, 0, 0, 25, 0, 0, 22, 40,
+  7, 0, 0, 0, 67, 0, 0, 20, 33, 86,
+  0, 0, 32, 0, 0, 10, 0, 67, 54, 81,
+  0, 26, 0, 6, 0, 0, 25, 36, 58, 0,
+  32, 0, 0, 65, 0, 0, 102, 0, 0, 34,
+  25, 57, 85, 0, 33, 59, 0, 79, 0, 0,
+  3, 0, 3, 0, 2, 0, 0, 0, 0, 49,
+  15, 0, 0, 173, 0, 0, 0, 0, 0, 0,
+  0, 64, 113, 110, 0, 0, 0, 0, 0, 29,
+  0, 22, 0, 30, 0, 19, 0, 0, 0, 29,
+  61, 0, 40, 0, 0, 0, 0, 15, 1, 35,
+  0, 34, 21, 0, 0, 0, 48, 33, 91, 15,
+  14, 16, 57, 1, 0, 81, 49, 0, 0, 0,
+  6, 20, 26, 30, 1, 0, 0, 23, 0, 0,
+  0, 0, 60, 0, 3, 0, 0, 56, 0, 42,
+  4, 5, 0, 43, 0, 101, 57, 64, 0, 36,
+  0, 14, 67, 0, 0, 0, 60, 0, 18, 0,
+  6, 36, 0, 46, 0, 0, 0, 0, 80, 0,
+  0, 0, 27, 50, 26, 48, 16, 11, 0, 0,
+  59, 0, 25, 0, 0, 9, 9, 3, 5, 0,
+  0, 63, 0, 14, 0, 0, 0, 0, 4, 79,
+  88, 0, 0, 0, 17, 0, 30, 2, 0, 51,
+  0, 7, 0, 20, 0, 0, 0, 31, 77, 0,
+  50, 0, 85, 0, 42, 0, 14, 0, 46, 82,
+  0, 50, 1, 35, 0, 0, 22, 0, 0, 15,
+  41, 6, 0, 0, 0, 19, 21, 11, 13, 31,
+  0, 0, 0, 0, 64, 0, 0, 0, 30, 54,
+  0, 0, 28, 29, 0, 17, 0, 0, 0, 0,
+  1, 18, 5, 11, 10, 0, 0, 0, 0, 57,
+  0, 22, 95, 48, 30, 4, 0, 0, 0, 73,
+  54, 11, 88, 0, 0, 66, 0, 94, 130, 13,
+  9, 0, 0, 4, 0, 2, 68, 0, 0, 0,
+  23, 16, 20, 0, 0, 28, 33, 13, 56, 0,
+  0, 0, 6, 0, 47, 0, 18, 68, 22, 150,
+  0, 0, 0, 0, 0, 82, 91, 0, 7, 26,
+  10, 31, 0, 0, 0, 0, 31, 0, 0, 0,
+  0, 0, 50, 35, 0, 2, 1, 12, 0, 19,
+  0, 115, 0, 0, 17, 0, 0, 0, 0, 1,
+  0, 0, 0, 28, 11, 16, 0, 65, 2, 0,
+  0, 0, 23, 0, 0, 0, 0, 17, 8, 0,
+  9, 65, 12, 45, 5, 0, 48, 0, 0, 18,
+  0, 33, 46, 0, 0, 7, 0, 29, 0, 0,
+  131, 59, 54, 5, 43, 0, 0, 107, 51, 0,
+  166, 0, 0, 46, 0, 112, 193, 0, 44, 0,
+  0, 35, 0, 0, 29, 0, 0, 0, 32, 0,
+  28, 0, 0, 1, 14, 0, 0, 79, 16, 0,
+  38, 0, 0, 0, 3, 61, 47, 127, 0, 0,
+  0, 0, 0, 36, 0, 0, 0, 55, 0, 53,
+  0, 0, 0, 0, 47, 0, 0, 0, 0, 0,
+  13, 18, 0, 12, 0, 1, 0, 0, 0, 57,
+  0, 18, 70, 15, 0, 4, 0, 0, 0, 50,
+  13, 20, 0, 0, 47, 47, 29, 12, 0, 0,
+  0, 10, 0, 0, 0, 0, 50, 0, 0, 44,
+  0, 64, 0, 0, 54, 0, 0, 47, 0, 99,
+  16, 46, 0, 15, 0, 37, 0, 0, 63, 0,
+  74, 0, 64, 0, 0, 62, 0, 0, 90, 0,
+  0, 12, 30, 23, 61, 0, 70, 60, 0, 76,
+  0, 1, 0, 0, 21, 0, 0, 0, 0, 0,
+  8, 0, 5, 0, 0, 121, 9, 0, 0, 0,
+  0, 0, 20, 54, 116, 17, 0, 0, 0, 0,
+  11, 9, 0, 21, 0, 19, 0, 73, 0, 0,
+  0, 0, 56, 0, 53, 0, 0, 0, 21, 0,
+  18, 0, 0, 93, 41, 0, 7, 0, 52, 3,
+  86, 40, 12, 0, 76, 3, 0, 125, 70, 39,
+  2, 33, 0, 0, 0, 54, 36, 13, 16, 61,
+  3, 0, 21, 0, 90, 1, 0, 0, 0, 58,
+  0, 29, 9, 0, 26, 52, 0, 59, 72, 36,
+  0, 44, 0, 0, 84, 12, 0, 0, 22, 0,
+  0, 42, 0, 0, 0, 0, 0, 0, 47, 0,
+  62, 0, 0, 0, 2, 50, 38, 28, 0, 0,
+  0, 0, 77, 11, 8, 0, 0, 21, 0, 22,
+  43, 0, 0, 57, 0, 32, 0, 0, 0, 0,
+  0, 79, 66, 0, 0, 0, 15, 0, 10, 29,
+  0, 69, 0, 1, 0, 0, 0, 0, 0, 36,
+  65, 0, 62, 0, 139, 0, 57, 16, 25, 0,
+  0, 58, 49, 0, 14, 0, 50, 16, 63, 8,
+  3, 26, 61, 1, 7, 53, 52, 0, 0, 15,
+  0, 27, 43, 19, 23, 0, 0, 13, 0, 0,
+  0, 0, 41, 0, 0, 6, 0, 16, 0, 79,
+  0, 24, 0, 55, 1, 70, 61, 46, 0, 21,
+  0, 20, 72, 1, 0, 0, 29, 0, 0, 0,
+  15, 36, 0, 43, 0, 14, 0, 0, 79, 0,
+  0, 0, 7, 27, 66, 15, 34, 28, 0, 0,
+  79, 0, 29, 0, 25, 0, 16, 0, 0, 0,
+  0, 0, 0, 17, 0, 26, 0, 0, 5, 71,
+  31, 0, 0, 0, 26, 0, 28, 0, 0, 38,
+  0, 0, 0, 2, 0, 0, 2, 14, 69, 0,
+  27, 0, 63, 0, 43, 7, 17, 0, 0, 6,
+  0, 0, 0, 1, 30, 12, 26, 0, 0, 25,
+  43, 0, 8, 23, 56, 23, 0, 0, 32, 29,
+  18, 2, 25, 0, 0, 0, 0, 0, 0, 0,
+  36, 17, 0, 0, 0, 0, 0, 34, 0, 11,
+  0, 58, 21, 87, 29, 59, 0, 1, 0, 52,
+  63, 0, 3, 0, 12, 0, 0, 0, 25, 4,
+  0, 38, 0, 10, 4, 0, 42, 0, 34, 0,
+  0, 17, 34, 0, 45, 41, 0, 0, 77, 0,
+  55, 0, 5, 0, 14, 0, 0, 0, 0, 31,
+  0, 0, 0, 22, 0, 0, 32, 57, 30, 0,
+  0, 9, 8, 0, 15, 0, 0, 13, 0, 14,
+  0, 2, 0, 0, 29, 0, 33, 0, 14, 0,
+  33, 0, 13, 6, 20, 0, 0, 37, 0, 0,
+  0, 81, 0, 0, 83, 32, 0, 0, 0, 9,
+  0, 42, 6, 26, 0, 10, 0, 0, 0, 25,
+  0, 0, 22, 40, 7, 0, 0, 0, 67, 0,
+  0, 20, 33, 86, 0, 0, 32, 0, 0, 10,
+  0, 67, 54, 81, 0, 26, 0, 6, 0, 0,
+  25, 36, 58, 0, 32, 0, 0, 65, 0, 0,
+  102, 0, 0, 34, 25, 57, 85, 0, 33, 59,
+  0, 79, 0, 0, 3, 0, 3, 0, 2, 0,
+  0, 0, 0, 49, 15, 0, 0, 173, 0, 0,
+  0, 0, 0, 0, 0, 64, 113, 110, 0, 0,
+  0, 0, 0, 29, 0, 22, 0, 30, 0, 19,
+  0, 0, 0, 29, 61, 0, 40, 0, 0, 0,
+  0, 15, 1, 35, 0, 34, 21, 0, 0, 0,
+  48, 33, 91, 15, 14, 16, 57, 1, 0, 81,
+  49, 0, 0, 0, 6, 20, 26, 30, 1, 0,
+  0, 23, 0, 0, 0, 0, 60, 0, 3, 0,
+  0, 56, 0, 42, 4, 5, 0, 43, 0, 101,
+  57, 64, 0, 36, 0, 14, 67, 0, 0, 0,
+  60, 0, 18, 0, 6, 36, 0, 46, 0, 0,
+  0, 0, 80, 0, 0, 0, 27, 50, 26, 48,
+  16, 11, 0, 0, 59, 0, 25, 0, 0, 9,
+  9, 3, 5, 0, 0, 63, 0, 14, 0, 0,
+  0, 0, 4, 79, 88, 0, 0, 0, 17, 0,
+  30, 2, 0, 51, 0, 7, 0, 20, 0, 0,
+  0, 31, 77, 0, 50, 0, 85, 0, 42, 0,
+  14, 0, 0, 27, 0, 6, 0, 0, 33, 17,
+  40, 0, 12, 29, 62, 0, 14, 33, 65, 28,
+  0, 0, 26, 32, 26, 12, 42, 0, 0, 27,
+  0, 0, 0, 0, 69, 0, 0, 0, 0, 14,
+  0, 40, 0, 14, 0, 40, 23, 88, 0, 29,
+  0, 18, 0, 24, 66, 1, 4, 0, 0, 0,
+  0, 0, 30, 14, 0, 50, 0, 7, 42, 0,
+  37, 0, 0, 0, 0, 48, 16, 0, 58, 78,
+  0, 0, 60, 0, 43, 4, 0, 14, 12, 0,
+  0, 2, 0, 24, 0, 6, 0, 25, 4, 0,
+  5, 84, 38, 0, 0, 3, 48, 0, 12, 5,
+  0, 1, 0, 12, 0, 2, 0, 0, 15, 0,
+  12, 0, 16, 0, 60, 0, 26, 0, 25, 0,
+  1, 12, 0, 19, 0, 115, 0, 0, 17, 0,
+  0, 0, 0, 1, 0, 0, 0, 28, 11, 16,
+  0, 65, 2, 0, 0, 0, 23, 0, 0, 0,
+  0, 17, 8, 0, 9, 65, 12, 45, 5, 0,
+  48, 0, 0, 18, 0, 33, 46, 0, 0, 7,
+  0, 29, 0, 0, 131, 59, 54, 5, 43, 0,
+  0, 107, 51, 0, 166, 0, 0, 46, 0, 112,
+  193, 0, 44, 0, 0, 35, 0, 0, 29, 0,
+  0, 0, 32, 0, 28, 0, 0, 1, 14, 0,
+  0, 79, 16, 0, 38, 0, 0, 0, 3, 61,
+  47, 127, 0, 0, 0, 0, 0, 36, 0, 0,
+  0, 55, 0, 53, 0, 0, 0, 0, 47, 0,
+  0, 0, 0, 0, 13, 18, 0, 12, 0, 1,
+  0, 0, 0, 57, 0, 18, 70, 15, 0, 4,
+  0, 0, 0, 50, 13, 20, 0, 0, 47, 47,
+  29, 12, 0, 0, 0, 10, 0, 0, 0, 0,
+  50, 0, 0, 44, 0, 64, 0, 0, 54, 0,
+  0, 47, 0, 99, 16, 46, 0, 15, 0, 37,
+  0, 0, 63, 0, 74, 0, 64, 0, 0, 62,
+  0, 0, 90, 0, 0, 12, 30, 23, 61, 0,
+  70, 60, 0, 76, 0, 1, 0, 0, 21, 0,
+  0, 0, 0, 0, 8, 0, 5, 0, 0, 121,
+  9, 0, 0, 0, 0, 0, 20, 54, 116, 17,
+  0, 0, 0, 0, 11, 9, 0, 21, 0, 19,
+  0, 73, 0, 0, 0, 0, 56, 0, 53, 0,
+  0, 0, 21, 0, 18, 0, 0, 48, 16, 0,
+  0, 0, 50, 44, 75, 3, 3, 42, 110, 0,
+  16, 61, 79, 13, 2, 0, 31, 54, 4, 6,
+  49, 0, 0, 45, 0, 0, 0, 0, 83, 0,
+  2, 0, 0, 62, 0, 80, 0, 35, 4, 49,
+  18, 97, 6, 35, 0, 42, 0, 40, 48, 0,
+  23, 0, 3, 0, 0, 0, 0, 5, 0, 59,
+  0, 17, 20, 0, 40, 0, 0, 0, 0, 48,
+  8, 0, 29, 54, 0, 0, 33, 0, 42, 5,
+  0, 9, 4, 0, 0, 8, 0, 4, 0, 44,
+  0, 13, 5, 8, 15, 84, 41, 0, 0, 0,
+  34, 0, 24, 13, 4, 22, 0, 21, 0, 22,
+  0, 0, 0, 0, 35, 0, 31, 0, 111, 0,
+  71, 0, 32, 0, 0, 58, 49, 0, 14, 0,
+  50, 16, 63, 8, 3, 26, 61, 1, 7, 53,
+  52, 0, 0, 15, 0, 27, 43, 19, 23, 0,
+  0, 13, 0, 0, 0, 0, 41, 0, 0, 6,
+  0, 16, 0, 79, 0, 24, 0, 55, 1, 70,
+  61, 46, 0, 21, 0, 20, 72, 1, 0, 0,
+  29, 0, 0, 0, 15, 36, 0, 43, 0, 14,
+  0, 0, 79, 0, 0, 0, 7, 27, 66, 15,
+  34, 28, 0, 0, 79, 0, 29, 0, 25, 0,
+  16, 0, 0, 0, 0, 0, 0, 17, 0, 26,
+  0, 0, 5, 71, 31, 0, 0, 0, 26, 0,
+  28, 0, 0, 38, 0, 0, 0, 2, 0, 0,
+  2, 14, 69, 0, 27, 0, 63, 0, 43, 7,
+  17, 0, 0, 6, 0, 0, 0, 1, 30, 12,
+  26, 0, 0, 25, 43, 0, 8, 23, 56, 23,
+  0, 0, 32, 29, 18, 2, 25, 0, 0, 0,
+  0, 0, 0, 0, 36, 17, 0, 0, 0, 0,
+  0, 34, 0, 11, 0, 58, 21, 87, 29, 59,
+  0, 1, 0, 52, 63, 0, 3, 0, 12, 0,
+  0, 0, 25, 4, 0, 38, 0, 10, 4, 0,
+  42, 0, 34, 0, 0, 17, 34, 0, 45, 41,
+  0, 0, 77, 0, 55, 0, 5, 0, 14, 0,
+  0, 0, 0, 31, 0, 0, 0, 22, 0, 0,
+  32, 57, 30, 0, 0, 9, 8, 0, 15, 0,
+  0, 13, 0, 14, 0, 2, 0, 0, 29, 0,
+  33, 0, 14, 0, 33, 0, 13, 6, 20, 0,
+  0, 5, 0, 30, 11, 9, 0, 0, 16, 0,
+  14, 0, 28, 0, 0, 43, 62, 17, 0, 4,
+  0, 0, 0, 14, 39, 0, 19, 14, 0, 0,
+  0, 0, 39, 51, 0, 0, 0, 0, 8, 0,
+  0, 0, 0, 26, 0, 76, 41, 64, 0, 17,
+  0, 73, 78, 15, 1, 58, 0, 0, 0, 0,
+  35, 0, 0, 26, 0, 0, 54, 0, 52, 39,
+  59, 0, 0, 16, 4, 0, 13, 36, 0, 0,
+  89, 0, 49, 0, 0, 20, 1, 30, 0, 0,
+  0, 79, 0, 0, 39, 0, 21, 0, 17, 79,
+  53, 5, 0, 14, 0, 0, 0, 9, 0, 17,
+  0, 33, 0, 25, 0, 0, 3, 0, 0, 0,
+  0, 0, 77, 0, 14, 5, 4, 0, 0, 34,
+  21, 0, 0, 0, 48, 33, 91, 15, 14, 16,
+  57, 1, 0, 81, 49, 0, 0, 0, 6, 20,
+  26, 30, 1, 0, 0, 23, 0, 0, 0, 0,
+  60, 0, 3, 0, 0, 56, 0, 42, 4, 5,
+  0, 43, 0, 101, 57, 64, 0, 36, 0, 14,
+  67, 0, 0, 0, 60, 0, 18, 0, 6, 36,
+  0, 46, 0, 0, 0, 0, 80, 0, 0, 0,
+  27, 50, 26, 48, 16, 11, 0, 0, 59, 0,
+  25, 0, 0, 9, 9, 3, 5, 0, 0, 63,
+  0, 14, 0, 0, 0, 0, 4, 79, 88, 0,
+  0, 0, 17, 0, 30, 2, 0, 51, 0, 7,
+  0, 20, 0, 0, 0, 31, 77, 0, 50, 0,
+  85, 0, 42, 0, 14, 0, 0, 27, 0, 6,
+  0, 0, 33, 17, 40, 0, 12, 29, 62, 0,
+  14, 33, 65, 28, 0, 0, 26, 32, 26, 12,
+  42, 0, 0, 27, 0, 0, 0, 0, 69, 0,
+  0, 0, 0, 14, 0, 40, 0, 14, 0, 40,
+  23, 88, 0, 29, 0, 18, 0, 24, 66, 1,
+  4, 0, 0, 0, 0, 0, 30, 14, 0, 50,
+  0, 7, 42, 0, 37, 0, 0, 0, 0, 48,
+  16, 0, 58, 78, 0, 0, 60, 0, 43, 4,
+  0, 14, 12, 0, 0, 2, 0, 24, 0, 6,
+  0, 25, 4, 0, 5, 84, 38, 0, 0, 3,
+  48, 0, 12, 5, 0, 1, 0, 12, 0, 2,
+  0, 0, 15, 0, 12, 0, 16, 0, 60, 0,
+  26, 0, 25, 0, 32, 14, 0, 17, 0, 0,
+  0, 0, 0, 0, 1, 1, 16, 0, 0, 0,
+  49, 11, 3, 0, 0, 29, 0, 16, 72, 0,
+  37, 30, 0, 0, 0, 15, 79, 12, 0, 0,
+  0, 13, 41, 0, 0, 0, 0, 11, 0, 105,
+  32, 28, 0, 0, 0, 8, 36, 0, 22, 20,
+  3, 0, 0, 0, 87, 22, 0, 54, 0, 0,
+  130, 30, 67, 49, 31, 0, 0, 36, 0, 0,
+  48, 46, 0, 0, 36, 0, 58, 28, 0, 42,
+  0, 0, 0, 0, 0, 73, 0, 0, 0, 0,
+  0, 0, 0, 113, 49, 57, 10, 33, 35, 37,
+  0, 0, 24, 0, 0, 52, 0, 0, 0, 0,
+  4, 0, 10, 0, 8, 0, 23, 0, 0, 0,
+  31, 19, 0, 1, 0, 0, 0, 57, 0, 18,
+  70, 15, 0, 4, 0, 0, 0, 50, 13, 20,
+  0, 0, 47, 47, 29, 12, 0, 0, 0, 10,
+  0, 0, 0, 0, 50, 0, 0, 44, 0, 64,
+  0, 0, 54, 0, 0, 47, 0, 99, 16, 46,
+  0, 15, 0, 37, 0, 0, 63, 0, 74, 0,
+  64, 0, 0, 62, 0, 0, 90, 0, 0, 12,
+  30, 23, 61, 0, 70, 60, 0, 76, 0, 1,
+  0, 0, 21, 0, 0, 0, 0, 0, 8, 0,
+  5, 0, 0, 121, 9, 0, 0, 0, 0, 0,
+  20, 54, 116, 17, 0, 0, 0, 0, 11, 9,
+  0, 21, 0, 19, 0, 73, 0, 0, 0, 0,
+  56, 0, 53, 0, 0, 0, 21, 0, 18, 0,
+  0, 48, 16, 0, 0, 0, 50, 44, 75, 3,
+  3, 42, 110, 0, 16, 61, 79, 13, 2, 0,
+  31, 54, 4, 6, 49, 0, 0, 45, 0, 0,
+  0, 0, 83, 0, 2, 0, 0, 62, 0, 80,
+  0, 35, 4, 49, 18, 97, 6, 35, 0, 42,
+  0, 40, 48, 0, 23, 0, 3, 0, 0, 0,
+  0, 5, 0, 59, 0, 17, 20, 0, 40, 0,
+  0, 0, 0, 48, 8, 0, 29, 54, 0, 0,
+  33, 0, 42, 5, 0, 9, 4, 0, 0, 8,
+  0, 4, 0, 44, 0, 13, 5, 8, 15, 84,
+  41, 0, 0, 0, 34, 0, 24, 13, 4, 22,
+  0, 21, 0, 22, 0, 0, 0, 0, 35, 0,
+  31, 0, 111, 0, 71, 0, 32, 0, 3, 37,
+  0, 0, 14, 0, 32, 0, 0, 0, 3, 23,
+  56, 0, 0, 4, 62, 15, 4, 0, 0, 72,
+  0, 17, 107, 0, 0, 48, 0, 0, 0, 48,
+  90, 0, 0, 0, 0, 51, 43, 7, 0, 46,
+  21, 29, 25, 100, 41, 0, 0, 5, 0, 0,
+  5, 0, 27, 0, 7, 0, 20, 2, 58, 63,
+  0, 50, 0, 0, 97, 52, 73, 0, 0, 0,
+  9, 20, 30, 0, 53, 59, 0, 0, 0, 0,
+  39, 57, 10, 31, 0, 0, 0, 14, 0, 0,
+  0, 54, 0, 21, 0, 18, 0, 113, 24, 11,
+  22, 20, 39, 43, 10, 0, 43, 0, 0, 50,
+  0, 0, 0, 0, 10, 1, 48, 0, 7, 0,
+  27, 0, 30, 0, 30, 47, 0, 6, 0, 0,
+  0, 1, 30, 12, 26, 0, 0, 25, 43, 0,
+  8, 23, 56, 23, 0, 0, 32, 29, 18, 2,
+  25, 0, 0, 0, 0, 0, 0, 0, 36, 17,
+  0, 0, 0, 0, 0, 34, 0, 11, 0, 58,
+  21, 87, 29, 59, 0, 1, 0, 52, 63, 0,
+  3, 0, 12, 0, 0, 0, 25, 4, 0, 38,
+  0, 10, 4, 0, 42, 0, 34, 0, 0, 17,
+  34, 0, 45, 41, 0, 0, 77, 0, 55, 0,
+  5, 0, 14, 0, 0, 0, 0, 31, 0, 0,
+  0, 22, 0, 0, 32, 57, 30, 0, 0, 9,
+  8, 0, 15, 0, 0, 13, 0, 14, 0, 2,
+  0, 0, 29, 0, 33, 0, 14, 0, 33, 0,
+  13, 6, 20, 0, 0, 5, 0, 30, 11, 9,
+  0, 0, 16, 0, 14, 0, 28, 0, 0, 43,
+  62, 17, 0, 4, 0, 0, 0, 14, 39, 0,
+  19, 14, 0, 0, 0, 0, 39, 51, 0, 0,
+  0, 0, 8, 0, 0, 0, 0, 26, 0, 76,
+  41, 64, 0, 17, 0, 73, 78, 15, 1, 58,
+  0, 0, 0, 0, 35, 0, 0, 26, 0, 0,
+  54, 0, 52, 39, 59, 0, 0, 16, 4, 0,
+  13, 36, 0, 0, 89, 0, 49, 0, 0, 20,
+  1, 30, 0, 0, 0, 79, 0, 0, 39, 0,
+  21, 0, 17, 79, 53, 5, 0, 14, 0, 0,
+  0, 9, 0, 17, 0, 33, 0, 25, 0, 0,
+  3, 0, 0, 0, 0, 0, 77, 0, 14, 5,
+  4, 0, 0, 37, 0, 30, 19, 0, 8, 0,
+  29, 1, 5, 0, 23, 0, 24, 68, 78, 31,
+  0, 2, 0, 0, 0, 40, 45, 0, 20, 28,
+  0, 0, 7, 0, 46, 69, 0, 0, 0, 8,
+  7, 0, 0, 0, 0, 16, 0, 35, 63, 39,
+  0, 11, 0, 42, 72, 27, 0, 30, 0, 4,
+  0, 3, 38, 0, 0, 31, 0, 0, 79, 0,
+  75, 41, 0, 0, 0, 12, 16, 0, 14, 1,
+  0, 0, 85, 0, 26, 0, 0, 32, 0, 18,
+  6, 0, 14, 72, 0, 6, 28, 0, 15, 0,
+  0, 80, 18, 0, 0, 7, 0, 0, 0, 0,
+  2, 22, 0, 30, 8, 22, 3, 0, 0, 0,
+  0, 0, 0, 0, 101, 0, 9, 26, 7, 0,
+  0, 27, 0, 6, 0, 0, 33, 17, 40, 0,
+  12, 29, 62, 0, 14, 33, 65, 28, 0, 0,
+  26, 32, 26, 12, 42, 0, 0, 27, 0, 0,
+  0, 0, 69, 0, 0, 0, 0, 14, 0, 40,
+  0, 14, 0, 40, 23, 88, 0, 29, 0, 18,
+  0, 24, 66, 1, 4, 0, 0, 0, 0, 0,
+  30, 14, 0, 50, 0, 7, 42, 0, 37, 0,
+  0, 0, 0, 48, 16, 0, 58, 78, 0, 0,
+  60, 0, 43, 4, 0, 14, 12, 0, 0, 2,
+  0, 24, 0, 6, 0, 25, 4, 0, 5, 84,
+  38, 0, 0, 3, 48, 0, 12, 5, 0, 1,
+  0, 12, 0, 2, 0, 0, 15, 0, 12, 0,
+  16, 0, 60, 0, 26, 0, 25, 0, 32, 14,
+  0, 17, 0, 0, 0, 0, 0, 0, 1, 1,
+  16, 0, 0, 0, 49, 11, 3, 0, 0, 29,
+  0, 16, 72, 0, 37, 30, 0, 0, 0, 15,
+  79, 12, 0, 0, 0, 13, 41, 0, 0, 0,
+  0, 11, 0, 105, 32, 28, 0, 0, 0, 8,
+  36, 0, 22, 20, 3, 0, 0, 0, 87, 22,
+  0, 54, 0, 0, 130, 30, 67, 49, 31, 0,
+  0, 36, 0, 0, 48, 46, 0, 0, 36, 0,
+  58, 28, 0, 42, 0, 0, 0, 0, 0, 73,
+  0, 0, 0, 0, 0, 0, 0, 113, 49, 57,
+  10, 33, 35, 37, 0, 0, 24, 0, 0, 52,
+  0, 0, 0, 0, 4, 0, 10, 0, 8, 0,
+  23, 0, 0, 0, 31, 19, 12, 13, 0, 21,
+  6, 5, 0, 0, 11, 0, 0, 0, 48, 0,
+  0, 18, 58, 12, 0, 0, 0, 8, 0, 28,
+  33, 0, 31, 20, 0, 0, 0, 2, 67, 50,
+  0, 0, 0, 26, 49, 0, 0, 0, 0, 31,
+  0, 97, 52, 74, 0, 0, 0, 36, 26, 0,
+  0, 44, 0, 0, 0, 0, 64, 9, 0, 12,
+  0, 0, 87, 26, 88, 48, 67, 0, 0, 16,
+  0, 0, 28, 0, 0, 0, 33, 0, 46, 22,
+  0, 32, 0, 0, 2, 0, 0, 84, 0, 0,
+  12, 0, 0, 0, 1, 115, 49, 54, 0, 40,
+  17, 26, 0, 0, 9, 0, 0, 49, 0, 16,
+  0, 0, 0, 0, 29, 0, 1, 0, 46, 0,
+  0, 0, 33, 16, 0, 48, 16, 0, 0, 0,
+  50, 44, 75, 3, 3, 42, 110, 0, 16, 61,
+  79, 13, 2, 0, 31, 54, 4, 6, 49, 0,
+  0, 45, 0, 0, 0, 0, 83, 0, 2, 0,
+  0, 62, 0, 80, 0, 35, 4, 49, 18, 97,
+  6, 35, 0, 42, 0, 40, 48, 0, 23, 0,
+  3, 0, 0, 0, 0, 5, 0, 59, 0, 17,
+  20, 0, 40, 0, 0, 0, 0, 48, 8, 0,
+  29, 54, 0, 0, 33, 0, 42, 5, 0, 9,
+  4, 0, 0, 8, 0, 4, 0, 44, 0, 13,
+  5, 8, 15, 84, 41, 0, 0, 0, 34, 0,
+  24, 13, 4, 22, 0, 21, 0, 22, 0, 0,
+  0, 0, 35, 0, 31, 0, 111, 0, 71, 0,
+  32, 0, 3, 37, 0, 0, 14, 0, 32, 0,
+  0, 0, 3, 23, 56, 0, 0, 4, 62, 15,
+  4, 0, 0, 72, 0, 17, 107, 0, 0, 48,
+  0, 0, 0, 48, 90, 0, 0, 0, 0, 51,
+  43, 7, 0, 46, 21, 29, 25, 100, 41, 0,
+  0, 5, 0, 0, 5, 0, 27, 0, 7, 0,
+  20, 2, 58, 63, 0, 50, 0, 0, 97, 52,
+  73, 0, 0, 0, 9, 20, 30, 0, 53, 59,
+  0, 0, 0, 0, 39, 57, 10, 31, 0, 0,
+  0, 14, 0, 0, 0, 54, 0, 21, 0, 18,
+  0, 113, 24, 11, 22, 20, 39, 43, 10, 0,
+  43, 0, 0, 50, 0, 0, 0, 0, 10, 1,
+  48, 0, 7, 0, 27, 0, 30, 0, 30, 47,
+  0, 22, 0, 0, 13, 12, 20, 0, 30, 0,
+  12, 20, 47, 4, 0, 16, 61, 0, 3, 0,
+  0, 56, 0, 10, 36, 0, 0, 41, 0, 0,
+  2, 0, 51, 24, 0, 0, 0, 75, 57, 0,
+  0, 1, 0, 46, 0, 115, 40, 68, 0, 0,
+  0, 16, 0, 0, 30, 32, 30, 0, 49, 0,
+  37, 54, 0, 31, 7, 0, 25, 63, 98, 0,
+  89, 0, 26, 32, 28, 22, 29, 0, 0, 0,
+  0, 0, 23, 34, 22, 43, 0, 13, 0, 0,
+  0, 67, 0, 29, 0, 0, 0, 0, 28, 122,
+  64, 34, 0, 28, 14, 55, 5, 5, 0, 0,
+  0, 59, 0, 9, 0, 5, 0, 38, 80, 0,
+  0, 0, 7, 0, 12, 0, 22, 22, 0, 5,
+  0, 30, 11, 9, 0, 0, 16, 0, 14, 0,
+  28, 0, 0, 43, 62, 17, 0, 4, 0, 0,
+  0, 14, 39, 0, 19, 14, 0, 0, 0, 0,
+  39, 51, 0, 0, 0, 0, 8, 0, 0, 0,
+  0, 26, 0, 76, 41, 64, 0, 17, 0, 73,
+  78, 15, 1, 58, 0, 0, 0, 0, 35, 0,
+  0, 26, 0, 0, 54, 0, 52, 39, 59, 0,
+  0, 16, 4, 0, 13, 36, 0, 0, 89, 0,
+  49, 0, 0, 20, 1, 30, 0, 0, 0, 79,
+  0, 0, 39, 0, 21, 0, 17, 79, 53, 5,
+  0, 14, 0, 0, 0, 9, 0, 17, 0, 33,
+  0, 25, 0, 0, 3, 0, 0, 0, 0, 0,
+  77, 0, 14, 5, 4, 0, 0, 37, 0, 30,
+  19, 0, 8, 0, 29, 1, 5, 0, 23, 0,
+  24, 68, 78, 31, 0, 2, 0, 0, 0, 40,
+  45, 0, 20, 28, 0, 0, 7, 0, 46, 69,
+  0, 0, 0, 8, 7, 0, 0, 0, 0, 16,
+  0, 35, 63, 39, 0, 11, 0, 42, 72, 27,
+  0, 30, 0, 4, 0, 3, 38, 0, 0, 31,
+  0, 0, 79, 0, 75, 41, 0, 0, 0, 12,
+  16, 0, 14, 1, 0, 0, 85, 0, 26, 0,
+  0, 32, 0, 18, 6, 0, 14, 72, 0, 6,
+  28, 0, 15, 0, 0, 80, 18, 0, 0, 7,
+  0, 0, 0, 0, 2, 22, 0, 30, 8, 22,
+  3, 0, 0, 0, 0, 0, 0, 0, 101, 0,
+  9, 26, 7, 0, 0, 119, 31, 10, 0, 0,
+  55, 0, 33, 18, 0, 0, 0, 0, 46, 39,
+  65, 38, 5, 18, 0, 0, 0, 46, 49, 6,
+  24, 40, 0, 0, 0, 0, 84, 26, 0, 0,
+  0, 16, 0, 3, 0, 0, 24, 17, 0, 45,
+  64, 6, 0, 10, 0, 0, 73, 0, 0, 0,
+  32, 0, 0, 35, 7, 5, 0, 0, 0, 0,
+  63, 0, 26, 11, 0, 0, 0, 15, 64, 26,
+  8, 27, 5, 0, 67, 3, 18, 28, 0, 6,
+  0, 0, 1, 26, 36, 0, 0, 22, 0, 0,
+  0, 0, 0, 60, 6, 0, 0, 0, 2, 0,
+  43, 0, 35, 36, 0, 21, 0, 19, 0, 0,
+  0, 0, 13, 0, 0, 0, 95, 0, 24, 41,
+  20, 0, 32, 14, 0, 17, 0, 0, 0, 0,
+  0, 0, 1, 1, 16, 0, 0, 0, 49, 11,
+  3, 0, 0, 29, 0, 16, 72, 0, 37, 30,
+  0, 0, 0, 15, 79, 12, 0, 0, 0, 13,
+  41, 0, 0, 0, 0, 11, 0, 105, 32, 28,
+  0, 0, 0, 8, 36, 0, 22, 20, 3, 0,
+  0, 0, 87, 22, 0, 54, 0, 0, 130, 30,
+  67, 49, 31, 0, 0, 36, 0, 0, 48, 46,
+  0, 0, 36, 0, 58, 28, 0, 42, 0, 0,
+  0, 0, 0, 73, 0, 0, 0, 0, 0, 0,
+  0, 113, 49, 57, 10, 33, 35, 37, 0, 0,
+  24, 0, 0, 52, 0, 0, 0, 0, 4, 0,
+  10, 0, 8, 0, 23, 0, 0, 0, 31, 19,
+  12, 13, 0, 21, 6, 5, 0, 0, 11, 0,
+  0, 0, 48, 0, 0, 18, 58, 12, 0, 0,
+  0, 8, 0, 28, 33, 0, 31, 20, 0, 0,
+  0, 2, 67, 50, 0, 0, 0, 26, 49, 0,
+  0, 0, 0, 31, 0, 97, 52, 74, 0, 0,
+  0, 36, 26, 0, 0, 44, 0, 0, 0, 0,
+  64, 9, 0, 12, 0, 0, 87, 26, 88, 48,
+  67, 0, 0, 16, 0, 0, 28, 0, 0, 0,
+  33, 0, 46, 22, 0, 32, 0, 0, 2, 0,
+  0, 84, 0, 0, 12, 0, 0, 0, 1, 115,
+  49, 54, 0, 40, 17, 26, 0, 0, 9, 0,
+  0, 49, 0, 16, 0, 0, 0, 0, 29, 0,
+  1, 0, 46, 0, 0, 0, 33, 16, 0, 98,
+  0, 20, 14, 0, 60, 12, 44, 16, 32, 0,
+  54, 0, 44, 107, 104, 30, 6, 0, 0, 0,
+  0, 40, 41, 45, 0, 53, 0, 0, 0, 0,
+  87, 64, 0, 0, 0, 27, 0, 41, 0, 0,
+  16, 28, 30, 44, 24, 53, 0, 28, 0, 0,
+  87, 10, 0, 0, 0, 14, 0, 58, 10, 0,
+  0, 24, 0, 0, 75, 0, 41, 0, 0, 0,
+  0, 48, 17, 40, 0, 0, 0, 12, 73, 0,
+  9, 26, 0, 32, 2, 2, 0, 43, 49, 36,
+  0, 65, 0, 26, 0, 0, 0, 86, 27, 0,
+  0, 0, 9, 0, 28, 10, 24, 30, 0, 17,
+  0, 27, 0, 0, 0, 0, 2, 0, 8, 0,
+  164, 0, 52, 9, 40, 0, 3, 37, 0, 0,
+  14, 0, 32, 0, 0, 0, 3, 23, 56, 0,
+  0, 4, 62, 15, 4, 0, 0, 72, 0, 17,
+  107, 0, 0, 48, 0, 0, 0, 48, 90, 0,
+  0, 0, 0, 51, 43, 7, 0, 46, 21, 29,
+  25, 100, 41, 0, 0, 5, 0, 0, 5, 0,
+  27, 0, 7, 0, 20, 2, 58, 63, 0, 50,
+  0, 0, 97, 52, 73, 0, 0, 0, 9, 20,
+  30, 0, 53, 59, 0, 0, 0, 0, 39, 57,
+  10, 31, 0, 0, 0, 14, 0, 0, 0, 54,
+  0, 21, 0, 18, 0, 113, 24, 11, 22, 20,
+  39, 43, 10, 0, 43, 0, 0, 50, 0, 0,
+  0, 0, 10, 1, 48, 0, 7, 0, 27, 0,
+  30, 0, 30, 47, 0, 22, 0, 0, 13, 12,
+  20, 0, 30, 0, 12, 20, 47, 4, 0, 16,
+  61, 0, 3, 0, 0, 56, 0, 10, 36, 0,
+  0, 41, 0, 0, 2, 0, 51, 24, 0, 0,
+  0, 75, 57, 0, 0, 1, 0, 46, 0, 115,
+  40, 68, 0, 0, 0, 16, 0, 0, 30, 32,
+  30, 0, 49, 0, 37, 54, 0, 31, 7, 0,
+  25, 63, 98, 0, 89, 0, 26, 32, 28, 22,
+  29, 0, 0, 0, 0, 0, 23, 34, 22, 43,
+  0, 13, 0, 0, 0, 67, 0, 29, 0, 0,
+  0, 0, 28, 122, 64, 34, 0, 28, 14, 55,
+  5, 5, 0, 0, 0, 59, 0, 9, 0, 5,
+  0, 38, 80, 0, 0, 0, 7, 0, 12, 0,
+  22, 22, 0, 49, 0, 0, 0, 0, 12, 0,
+  80, 43, 25, 0, 73, 2, 0, 149, 100, 43,
+  17, 0, 0, 0, 0, 25, 0, 0, 21, 90,
+  9, 0, 9, 0, 115, 13, 0, 0, 4, 73,
+  0, 0, 23, 0, 0, 26, 0, 80, 0, 54,
+  0, 37, 0, 15, 61, 0, 0, 23, 13, 7,
+  0, 32, 0, 0, 0, 0, 0, 0, 27, 12,
+  61, 0, 7, 0, 0, 98, 0, 66, 0, 13,
+  0, 0, 19, 3, 24, 48, 0, 47, 3, 23,
+  13, 19, 53, 124, 0, 32, 23, 0, 0, 0,
+  0, 90, 142, 0, 0, 0, 8, 0, 0, 33,
+  0, 34, 0, 47, 0, 22, 0, 0, 0, 0,
+  6, 0, 0, 0, 122, 0, 29, 0, 52, 16,
+  0, 37, 0, 30, 19, 0, 8, 0, 29, 1,
+  5, 0, 23, 0, 24, 68, 78, 31, 0, 2,
+  0, 0, 0, 40, 45, 0, 20, 28, 0, 0,
+  7, 0, 46, 69, 0, 0, 0, 8, 7, 0,
+  0, 0, 0, 16, 0, 35, 63, 39, 0, 11,
+  0, 42, 72, 27, 0, 30, 0, 4, 0, 3,
+  38, 0, 0, 31, 0, 0, 79, 0, 75, 41,
+  0, 0, 0, 12, 16, 0, 14, 1, 0, 0,
+  85, 0, 26, 0, 0, 32, 0, 18, 6, 0,
+  14, 72, 0, 6, 28, 0, 15, 0, 0, 80,
+  18, 0, 0, 7, 0, 0, 0, 0, 2, 22,
+  0, 30, 8, 22, 3, 0, 0, 0, 0, 0,
+  0, 0, 101, 0, 9, 26, 7, 0, 0, 119,
+  31, 10, 0, 0, 55, 0, 33, 18, 0, 0,
+  0, 0, 46, 39, 65, 38, 5, 18, 0, 0,
+  0, 46, 49, 6, 24, 40, 0, 0, 0, 0,
+  84, 26, 0, 0, 0, 16, 0, 3, 0, 0,
+  24, 17, 0, 45, 64, 6, 0, 10, 0, 0,
+  73, 0, 0, 0, 32, 0, 0, 35, 7, 5,
+  0, 0, 0, 0, 63, 0, 26, 11, 0, 0,
+  0, 15, 64, 26, 8, 27, 5, 0, 67, 3,
+  18, 28, 0, 6, 0, 0, 1, 26, 36, 0,
+  0, 22, 0, 0, 0, 0, 0, 60, 6, 0,
+  0, 0, 2, 0, 43, 0, 35, 36, 0, 21,
+  0, 19, 0, 0, 0, 0, 13, 0, 0, 0,
+  95, 0, 24, 41, 20, 0, 0, 104, 16, 18,
+  0, 0, 0, 0, 47, 19, 0, 0, 6, 0,
+  7, 17, 36, 23, 0, 2, 0, 0, 72, 39,
+  0, 0, 14, 29, 0, 0, 0, 0, 40, 0,
+  36, 14, 0, 1, 11, 0, 0, 0, 22, 32,
+  0, 52, 25, 0, 0, 0, 0, 42, 40, 0,
+  22, 0, 44, 0, 3, 0, 0, 33, 0, 0,
+  52, 0, 0, 0, 0, 10, 106, 0, 39, 32,
+  46, 45, 0, 59, 28, 0, 21, 0, 1, 31,
+  0, 0, 5, 21, 26, 0, 31, 0, 0, 0,
+  5, 0, 0, 0, 0, 52, 28, 23, 1, 0,
+  7, 59, 48, 1, 0, 29, 0, 28, 0, 8,
+  0, 0, 0, 0, 0, 12, 0, 0, 0, 0,
+  49, 26, 5, 0, 12, 13, 0, 21, 6, 5,
+  0, 0, 11, 0, 0, 0, 48, 0, 0, 18,
+  58, 12, 0, 0, 0, 8, 0, 28, 33, 0,
+  31, 20, 0, 0, 0, 2, 67, 50, 0, 0,
+  0, 26, 49, 0, 0, 0, 0, 31, 0, 97,
+  52, 74, 0, 0, 0, 36, 26, 0, 0, 44,
+  0, 0, 0, 0, 64, 9, 0, 12, 0, 0,
+  87, 26, 88, 48, 67, 0, 0, 16, 0, 0,
+  28, 0, 0, 0, 33, 0, 46, 22, 0, 32,
+  0, 0, 2, 0, 0, 84, 0, 0, 12, 0,
+  0, 0, 1, 115, 49, 54, 0, 40, 17, 26,
+  0, 0, 9, 0, 0, 49, 0, 16, 0, 0,
+  0, 0, 29, 0, 1, 0, 46, 0, 0, 0,
+  33, 16, 0, 98, 0, 20, 14, 0, 60, 12,
+  44, 16, 32, 0, 54, 0, 44, 107, 104, 30,
+  6, 0, 0, 0, 0, 40, 41, 45, 0, 53,
+  0, 0, 0, 0, 87, 64, 0, 0, 0, 27,
+  0, 41, 0, 0, 16, 28, 30, 44, 24, 53,
+  0, 28, 0, 0, 87, 10, 0, 0, 0, 14,
+  0, 58, 10, 0, 0, 24, 0, 0, 75, 0,
+  41, 0, 0, 0, 0, 48, 17, 40, 0, 0,
+  0, 12, 73, 0, 9, 26, 0, 32, 2, 2,
+  0, 43, 49, 36, 0, 65, 0, 26, 0, 0,
+  0, 86, 27, 0, 0, 0, 9, 0, 28, 10,
+  24, 30, 0, 17, 0, 27, 0, 0, 0, 0,
+  2, 0, 8, 0, 164, 0, 52, 9, 40, 0,
+  0, 111, 49, 4, 4, 0, 0, 13, 78, 36,
+  24, 0, 20, 0, 0, 97, 83, 24, 24, 5,
+  0, 0, 48, 50, 0, 0, 1, 78, 1, 0,
+  0, 0, 68, 0, 12, 0, 0, 28, 0, 3,
+  0, 0, 11, 19, 11, 36, 0, 0, 0, 29,
+  0, 18, 44, 0, 0, 0, 1, 0, 0, 8,
+  0, 0, 0, 0, 0, 0, 29, 0, 0, 0,
+  0, 0, 32, 72, 9, 90, 0, 112, 2, 20,
+  35, 0, 0, 53, 0, 31, 6, 61, 21, 24,
+  117, 0, 0, 0, 26, 0, 0, 0, 0, 100,
+  90, 0, 0, 0, 7, 0, 54, 21, 0, 21,
+  0, 0, 0, 15, 0, 0, 0, 0, 0, 21,
+  0, 0, 73, 0, 76, 10, 35, 0, 0, 22,
+  0, 0, 13, 12, 20, 0, 30, 0, 12, 20,
+  47, 4, 0, 16, 61, 0, 3, 0, 0, 56,
+  0, 10, 36, 0, 0, 41, 0, 0, 2, 0,
+  51, 24, 0, 0, 0, 75, 57, 0, 0, 1,
+  0, 46, 0, 115, 40, 68, 0, 0, 0, 16,
+  0, 0, 30, 32, 30, 0, 49, 0, 37, 54,
+  0, 31, 7, 0, 25, 63, 98, 0, 89, 0,
+  26, 32, 28, 22, 29, 0, 0, 0, 0, 0,
+  23, 34, 22, 43, 0, 13, 0, 0, 0, 67,
+  0, 29, 0, 0, 0, 0, 28, 122, 64, 34,
+  0, 28, 14, 55, 5, 5, 0, 0, 0, 59,
+  0, 9, 0, 5, 0, 38, 80, 0, 0, 0,
+  7, 0, 12, 0, 22, 22, 0, 49, 0, 0,
+  0, 0, 12, 0, 80, 43, 25, 0, 73, 2,
+  0, 149, 100, 43, 17, 0, 0, 0, 0, 25,
+  0, 0, 21, 90, 9, 0, 9, 0, 115, 13,
+  0, 0, 4, 73, 0, 0, 23, 0, 0, 26,
+  0, 80, 0, 54, 0, 37, 0, 15, 61, 0,
+  0, 23, 13, 7, 0, 32, 0, 0, 0, 0,
+  0, 0, 27, 12, 61, 0, 7, 0, 0, 98,
+  0, 66, 0, 13, 0, 0, 19, 3, 24, 48,
+  0, 47, 3, 23, 13, 19, 53, 124, 0, 32,
+  23, 0, 0, 0, 0, 90, 142, 0, 0, 0,
+  8, 0, 0, 33, 0, 34, 0, 47, 0, 22,
+  0, 0, 0, 0, 6, 0, 0, 0, 122, 0,
+  29, 0, 52, 16, 0, 27, 108, 0, 0, 0,
+  0, 0, 90, 42, 15, 0, 26, 53, 0, 84,
+  60, 35, 50, 0, 0, 15, 20, 31, 0, 0,
+  3, 111, 0, 0, 0, 0, 61, 0, 0, 0,
+  0, 79, 0, 0, 3, 0, 0, 0, 0, 28,
+  0, 0, 0, 35, 0, 82, 11, 0, 69, 0,
+  27, 18, 0, 0, 0, 0, 0, 0, 27, 0,
+  48, 0, 11, 70, 0, 0, 22, 90, 0, 69,
+  0, 68, 0, 0, 7, 0, 32, 92, 0, 47,
+  0, 58, 48, 0, 85, 34, 0, 0, 11, 0,
+  0, 0, 0, 133, 125, 0, 0, 0, 8, 0,
+  0, 61, 0, 16, 7, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 45, 0, 54, 0,
+  21, 46, 0, 119, 31, 10, 0, 0, 55, 0,
+  33, 18, 0, 0, 0, 0, 46, 39, 65, 38,
+  5, 18, 0, 0, 0, 46, 49, 6, 24, 40,
+  0, 0, 0, 0, 84, 26, 0, 0, 0, 16,
+  0, 3, 0, 0, 24, 17, 0, 45, 64, 6,
+  0, 10, 0, 0, 73, 0, 0, 0, 32, 0,
+  0, 35, 7, 5, 0, 0, 0, 0, 63, 0,
+  26, 11, 0, 0, 0, 15, 64, 26, 8, 27,
+  5, 0, 67, 3, 18, 28, 0, 6, 0, 0,
+  1, 26, 36, 0, 0, 22, 0, 0, 0, 0,
+  0, 60, 6, 0, 0, 0, 2, 0, 43, 0,
+  35, 36, 0, 21, 0, 19, 0, 0, 0, 0,
+  13, 0, 0, 0, 95, 0, 24, 41, 20, 0,
+  0, 104, 16, 18, 0, 0, 0, 0, 47, 19,
+  0, 0, 6, 0, 7, 17, 36, 23, 0, 2,
+  0, 0, 72, 39, 0, 0, 14, 29, 0, 0,
+  0, 0, 40, 0, 36, 14, 0, 1, 11, 0,
+  0, 0, 22, 32, 0, 52, 25, 0, 0, 0,
+  0, 42, 40, 0, 22, 0, 44, 0, 3, 0,
+  0, 33, 0, 0, 52, 0, 0, 0, 0, 10,
+  106, 0, 39, 32, 46, 45, 0, 59, 28, 0,
+  21, 0, 1, 31, 0, 0, 5, 21, 26, 0,
+  31, 0, 0, 0, 5, 0, 0, 0, 0, 52,
+  28, 23, 1, 0, 7, 59, 48, 1, 0, 29,
+  0, 28, 0, 8, 0, 0, 0, 0, 0, 12,
+  0, 0, 0, 0, 49, 26, 5, 0, 107, 66,
+  16, 65, 30, 0, 0, 17, 71, 14, 28, 0,
+  85, 0, 0, 80, 60, 0, 13, 0, 0, 32,
+  32, 6, 0, 0, 0, 61, 0, 37, 19, 69,
+  10, 6, 18, 5, 0, 44, 103, 0, 0, 23,
+  0, 23, 18, 0, 0, 0, 0, 0, 0, 86,
+  0, 0, 83, 13, 32, 36, 9, 0, 0, 0,
+  0, 0, 15, 55, 0, 0, 11, 0, 91, 19,
+  43, 55, 0, 39, 28, 49, 0, 26, 0, 0,
+  19, 64, 28, 26, 14, 0, 86, 0, 32, 0,
+  0, 14, 0, 0, 66, 0, 5, 67, 43, 0,
+  9, 0, 0, 58, 0, 60, 9, 0, 6, 0,
+  0, 0, 0, 0, 0, 0, 0, 15, 0, 4,
+  0, 18, 46, 15, 12, 30, 0, 98, 0, 20,
+  14, 0, 60, 12, 44, 16, 32, 0, 54, 0,
+  44, 107, 104, 30, 6, 0, 0, 0, 0, 40,
+  41, 45, 0, 53, 0, 0, 0, 0, 87, 64,
+  0, 0, 0, 27, 0, 41, 0, 0, 16, 28,
+  30, 44, 24, 53, 0, 28, 0, 0, 87, 10,
+  0, 0, 0, 14, 0, 58, 10, 0, 0, 24,
+  0, 0, 75, 0, 41, 0, 0, 0, 0, 48,
+  17, 40, 0, 0, 0, 12, 73, 0, 9, 26,
+  0, 32, 2, 2, 0, 43, 49, 36, 0, 65,
+  0, 26, 0, 0, 0, 86, 27, 0, 0, 0,
+  9, 0, 28, 10, 24, 30, 0, 17, 0, 27,
+  0, 0, 0, 0, 2, 0, 8, 0, 164, 0,
+  52, 9, 40, 0, 0, 111, 49, 4, 4, 0,
+  0, 13, 78, 36, 24, 0, 20, 0, 0, 97,
+  83, 24, 24, 5, 0, 0, 48, 50, 0, 0,
+  1, 78, 1, 0, 0, 0, 68, 0, 12, 0,
+  0, 28, 0, 3, 0, 0, 11, 19, 11, 36,
+  0, 0, 0, 29, 0, 18, 44, 0, 0, 0,
+  1, 0, 0, 8, 0, 0, 0, 0, 0, 0,
+  29, 0, 0, 0, 0, 0, 32, 72, 9, 90,
+  0, 112, 2, 20, 35, 0, 0, 53, 0, 31,
+  6, 61, 21, 24, 117, 0, 0, 0, 26, 0,
+  0, 0, 0, 100, 90, 0, 0, 0, 7, 0,
+  54, 21, 0, 21, 0, 0, 0, 15, 0, 0,
+  0, 0, 0, 21, 0, 0, 73, 0, 76, 10,
+  35, 0, 59, 1, 72, 42, 0, 0, 0, 22,
+  38, 13, 13, 6, 0, 7, 0, 21, 38, 13,
+  14, 0, 0, 64, 43, 11, 0, 0, 1, 54,
+  0, 38, 0, 39, 17, 0, 12, 19, 36, 29,
+  3, 0, 0, 0, 0, 0, 0, 11, 0, 0,
+  0, 0, 0, 70, 0, 0, 91, 0, 38, 0,
+  8, 0, 0, 4, 0, 0, 64, 10, 0, 0,
+  0, 114, 20, 0, 74, 27, 0, 45, 12, 51,
+  27, 0, 0, 0, 15, 101, 0, 21, 22, 36,
+  22, 0, 57, 0, 0, 0, 62, 0, 29, 0,
+  0, 72, 95, 0, 0, 0, 0, 80, 0, 16,
+  0, 0, 0, 13, 0, 0, 0, 0, 0, 0,
+  0, 33, 0, 3, 0, 0, 0, 0, 4, 22,
+  0, 49, 0, 0, 0, 0, 12, 0, 80, 43,
+  25, 0, 73, 2, 0, 149, 100, 43, 17, 0,
+  0, 0, 0, 25, 0, 0, 21, 90, 9, 0,
+  9, 0, 115, 13, 0, 0, 4, 73, 0, 0,
+  23, 0, 0, 26, 0, 80, 0, 54, 0, 37,
+  0, 15, 61, 0, 0, 23, 13, 7, 0, 32,
+  0, 0, 0, 0, 0, 0, 27, 12, 61, 0,
+  7, 0, 0, 98, 0, 66, 0, 13, 0, 0,
+  19, 3, 24, 48, 0, 47, 3, 23, 13, 19,
+  53, 124, 0, 32, 23, 0, 0, 0, 0, 90,
+  142, 0, 0, 0, 8, 0, 0, 33, 0, 34,
+  0, 47, 0, 22, 0, 0, 0, 0, 6, 0,
+  0, 0, 122, 0, 29, 0, 52, 16, 0, 27,
+  108, 0, 0, 0, 0, 0, 90, 42, 15, 0,
+  26, 53, 0, 84, 60, 35, 50, 0, 0, 15,
+  20, 31, 0, 0, 3, 111, 0, 0, 0, 0,
+  61, 0, 0, 0, 0, 79, 0, 0, 3, 0,
+  0, 0, 0, 28, 0, 0, 0, 35, 0, 82,
+  11, 0, 69, 0, 27, 18, 0, 0, 0, 0,
+  0, 0, 27, 0, 48, 0, 11, 70, 0, 0,
+  22, 90, 0, 69, 0, 68, 0, 0, 7, 0,
+  32, 92, 0, 47, 0, 58, 48, 0, 85, 34,
+  0, 0, 11, 0, 0, 0, 0, 133, 125, 0,
+  0, 0, 8, 0, 0, 61, 0, 16, 7, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  45, 0, 54, 0, 21, 46, 0, 0, 117, 0,
+  0, 75, 0, 0, 21, 0, 0, 1, 34, 80,
+  0, 0, 0, 31, 19, 0, 0, 94, 14, 24,
+  0, 0, 0, 29, 0, 0, 10, 39, 0, 0,
+  0, 0, 0, 56, 0, 0, 0, 0, 0, 7,
+  0, 0, 0, 0, 0, 0, 0, 155, 0, 0,
+  71, 0, 21, 0, 50, 0, 0, 5, 0, 0,
+  108, 0, 0, 0, 0, 98, 0, 0, 39, 7,
+  0, 0, 0, 22, 15, 0, 0, 0, 31, 74,
+  16, 3, 15, 30, 48, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 72, 30, 0, 0, 0,
+  0, 78, 0, 23, 0, 11, 40, 0, 0, 0,
+  17, 16, 68, 25, 10, 51, 0, 3, 0, 0,
+  33, 0, 0, 53, 0, 104, 16, 18, 0, 0,
+  0, 0, 47, 19, 0, 0, 6, 0, 7, 17,
+  36, 23, 0, 2, 0, 0, 72, 39, 0, 0,
+  14, 29, 0, 0, 0, 0, 40, 0, 36, 14,
+  0, 1, 11, 0, 0, 0, 22, 32, 0, 52,
+  25, 0, 0, 0, 0, 42, 40, 0, 22, 0,
+  44, 0, 3, 0, 0, 33, 0, 0, 52, 0,
+  0, 0, 0, 10, 106, 0, 39, 32, 46, 45,
+  0, 59, 28, 0, 21, 0, 1, 31, 0, 0,
+  5, 21, 26, 0, 31, 0, 0, 0, 5, 0,
+  0, 0, 0, 52, 28, 23, 1, 0, 7, 59,
+  48, 1, 0, 29, 0, 28, 0, 8, 0, 0,
+  0, 0, 0, 12, 0, 0, 0, 0, 49, 26,
+  5, 0, 107, 66, 16, 65, 30, 0, 0, 17,
+  71, 14, 28, 0, 85, 0, 0, 80, 60, 0,
+  13, 0, 0, 32, 32, 6, 0, 0, 0, 61,
+  0, 37, 19, 69, 10, 6, 18, 5, 0, 44,
+  103, 0, 0, 23, 0, 23, 18, 0, 0, 0,
+  0, 0, 0, 86, 0, 0, 83, 13, 32, 36,
+  9, 0, 0, 0, 0, 0, 15, 55, 0, 0,
+  11, 0, 91, 19, 43, 55, 0, 39, 28, 49,
+  0, 26, 0, 0, 19, 64, 28, 26, 14, 0,
+  86, 0, 32, 0, 0, 14, 0, 0, 66, 0,
+  5, 67, 43, 0, 9, 0, 0, 58, 0, 60,
+  9, 0, 6, 0, 0, 0, 0, 0, 0, 0,
+  0, 15, 0, 4, 0, 18, 46, 15, 12, 30,
+  14, 0, 60, 29, 0, 164, 0, 0, 18, 0,
+  0, 0, 3, 20, 0, 48, 30, 38, 0, 0,
+  13, 76, 24, 1, 0, 0, 0, 35, 0, 48,
+  0, 88, 0, 0, 0, 20, 63, 58, 24, 0,
+  0, 0, 0, 0, 0, 11, 0, 0, 13, 0,
+  0, 83, 0, 0, 99, 0, 57, 0, 22, 0,
+  0, 57, 14, 0, 110, 0, 0, 29, 2, 76,
+  21, 14, 67, 27, 0, 44, 44, 26, 0, 0,
+  0, 0, 32, 108, 0, 10, 10, 0, 11, 0,
+  10, 13, 0, 0, 58, 0, 30, 0, 0, 71,
+  79, 0, 0, 0, 0, 18, 0, 26, 0, 0,
+  0, 0, 0, 0, 4, 4, 54, 0, 0, 35,
+  0, 18, 0, 0, 0, 17, 0, 23, 0, 111,
+  49, 4, 4, 0, 0, 13, 78, 36, 24, 0,
+  20, 0, 0, 97, 83, 24, 24, 5, 0, 0,
+  48, 50, 0, 0, 1, 78, 1, 0, 0, 0,
+  68, 0, 12, 0, 0, 28, 0, 3, 0, 0,
+  11, 19, 11, 36, 0, 0, 0, 29, 0, 18,
+  44, 0, 0, 0, 1, 0, 0, 8, 0, 0,
+  0, 0, 0, 0, 29, 0, 0, 0, 0, 0,
+  32, 72, 9, 90, 0, 112, 2, 20, 35, 0,
+  0, 53, 0, 31, 6, 61, 21, 24, 117, 0,
+  0, 0, 26, 0, 0, 0, 0, 100, 90, 0,
+  0, 0, 7, 0, 54, 21, 0, 21, 0, 0,
+  0, 15, 0, 0, 0, 0, 0, 21, 0, 0,
+  73, 0, 76, 10, 35, 0, 59, 1, 72, 42,
+  0, 0, 0, 22, 38, 13, 13, 6, 0, 7,
+  0, 21, 38, 13, 14, 0, 0, 64, 43, 11,
+  0, 0, 1, 54, 0, 38, 0, 39, 17, 0,
+  12, 19, 36, 29, 3, 0, 0, 0, 0, 0,
+  0, 11, 0, 0, 0, 0, 0, 70, 0, 0,
+  91, 0, 38, 0, 8, 0, 0, 4, 0, 0,
+  64, 10, 0, 0, 0, 114, 20, 0, 74, 27,
+  0, 45, 12, 51, 27, 0, 0, 0, 15, 101,
+  0, 21, 22, 36, 22, 0, 57, 0, 0, 0,
+  62, 0, 29, 0, 0, 72, 95, 0, 0, 0,
+  0, 80, 0, 16, 0, 0, 0, 13, 0, 0,
+  0, 0, 0, 0, 0, 33, 0, 3, 0, 0,
+  0, 0, 4, 22, 21, 0, 99, 34, 0, 157,
+  0, 0, 0, 0, 0, 17, 14, 49, 0, 0,
+  14, 40, 0, 1, 5, 82, 30, 0, 0, 0,
+  0, 0, 0, 147, 4, 78, 0, 24, 0, 23,
+  87, 19, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 3, 42, 0, 0, 78, 0, 0, 59, 0,
+  56, 0, 27, 0, 0, 28, 13, 0, 118, 0,
+  0, 48, 0, 113, 0, 36, 68, 0, 0, 7,
+  28, 0, 17, 0, 0, 0, 10, 108, 35, 0,
+  27, 10, 7, 0, 0, 0, 13, 0, 52, 0,
+  0, 0, 0, 5, 41, 0, 0, 0, 0, 82,
+  0, 16, 0, 8, 18, 0, 0, 0, 39, 10,
+  84, 0, 0, 54, 5, 43, 0, 6, 0, 3,
+  0, 26, 0, 27, 108, 0, 0, 0, 0, 0,
+  90, 42, 15, 0, 26, 53, 0, 84, 60, 35,
+  50, 0, 0, 15, 20, 31, 0, 0, 3, 111,
+  0, 0, 0, 0, 61, 0, 0, 0, 0, 79,
+  0, 0, 3, 0, 0, 0, 0, 28, 0, 0,
+  0, 35, 0, 82, 11, 0, 69, 0, 27, 18,
+  0, 0, 0, 0, 0, 0, 27, 0, 48, 0,
+  11, 70, 0, 0, 22, 90, 0, 69, 0, 68,
+  0, 0, 7, 0, 32, 92, 0, 47, 0, 58,
+  48, 0, 85, 34, 0, 0, 11, 0, 0, 0,
+  0, 133, 125, 0, 0, 0, 8, 0, 0, 61,
+  0, 16, 7, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 45, 0, 54, 0, 21, 46,
+  0, 0, 117, 0, 0, 75, 0, 0, 21, 0,
+  0, 1, 34, 80, 0, 0, 0, 31, 19, 0,
+  0, 94, 14, 24, 0, 0, 0, 29, 0, 0,
+  10, 39, 0, 0, 0, 0, 0, 56, 0, 0,
+  0, 0, 0, 7, 0, 0, 0, 0, 0, 0,
+  0, 155, 0, 0, 71, 0, 21, 0, 50, 0,
+  0, 5, 0, 0, 108, 0, 0, 0, 0, 98,
+  0, 0, 39, 7, 0, 0, 0, 22, 15, 0,
+  0, 0, 31, 74, 16, 3, 15, 30, 48, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 72,
+  30, 0, 0, 0, 0, 78, 0, 23, 0, 11,
+  40, 0, 0, 0, 17, 16, 68, 25, 10, 51,
+  0, 3, 0, 0, 33, 0, 0, 53, 0, 0,
+  59, 0, 5, 69, 0, 0, 0, 0, 0, 19,
+  45, 76, 0, 0, 0, 17, 2, 8, 10, 22,
+  0, 35, 0, 0, 0, 0, 0, 77, 41, 11,
+  0, 18, 0, 0, 0, 17, 0, 13, 0, 0,
+  0, 39, 0, 0, 0, 0, 0, 0, 0, 110,
+  0, 0, 0, 0, 15, 4, 28, 0, 0, 0,
+  0, 0, 48, 0, 0, 6, 0, 9, 0, 40,
+  17, 0, 0, 0, 0, 0, 53, 0, 0, 17,
+  0, 52, 45, 0, 40, 9, 68, 0, 0, 0,
+  56, 0, 0, 5, 0, 0, 0, 21, 0, 0,
+  0, 0, 1, 53, 0, 16, 7, 45, 50, 0,
+  0, 13, 38, 10, 68, 48, 19, 52, 56, 0,
+  0, 0, 26, 9, 0, 10, 107, 66, 16, 65,
+  30, 0, 0, 17, 71, 14, 28, 0, 85, 0,
+  0, 80, 60, 0, 13, 0, 0, 32, 32, 6,
+  0, 0, 0, 61, 0, 37, 19, 69, 10, 6,
+  18, 5, 0, 44, 103, 0, 0, 23, 0, 23,
+  18, 0, 0, 0, 0, 0, 0, 86, 0, 0,
+  83, 13, 32, 36, 9, 0, 0, 0, 0, 0,
+  15, 55, 0, 0, 11, 0, 91, 19, 43, 55,
+  0, 39, 28, 49, 0, 26, 0, 0, 19, 64,
+  28, 26, 14, 0, 86, 0, 32, 0, 0, 14,
+  0, 0, 66, 0, 5, 67, 43, 0, 9, 0,
+  0, 58, 0, 60, 9, 0, 6, 0, 0, 0,
+  0, 0, 0, 0, 0, 15, 0, 4, 0, 18,
+  46, 15, 12, 30, 14, 0, 60, 29, 0, 164,
+  0, 0, 18, 0, 0, 0, 3, 20, 0, 48,
+  30, 38, 0, 0, 13, 76, 24, 1, 0, 0,
+  0, 35, 0, 48, 0, 88, 0, 0, 0, 20,
+  63, 58, 24, 0, 0, 0, 0, 0, 0, 11,
+  0, 0, 13, 0, 0, 83, 0, 0, 99, 0,
+  57, 0, 22, 0, 0, 57, 14, 0, 110, 0,
+  0, 29, 2, 76, 21, 14, 67, 27, 0, 44,
+  44, 26, 0, 0, 0, 0, 32, 108, 0, 10,
+  10, 0, 11, 0, 10, 13, 0, 0, 58, 0,
+  30, 0, 0, 71, 79, 0, 0, 0, 0, 18,
+  0, 26, 0, 0, 0, 0, 0, 0, 4, 4,
+  54, 0, 0, 35, 0, 18, 0, 0, 0, 17,
+  0, 23, 0, 0, 70, 0, 4, 150, 0, 0,
+  0, 0, 0, 1, 23, 94, 0, 0, 0, 44,
+  0, 0, 21, 54, 0, 39, 0, 0, 0, 0,
+  0, 45, 16, 26, 0, 7, 0, 0, 0, 50,
+  0, 0, 0, 11, 0, 27, 0, 8, 1, 0,
+  0, 0, 12, 123, 0, 0, 39, 0, 39, 0,
+  42, 0, 0, 32, 0, 0, 97, 0, 0, 31,
+  0, 64, 0, 26, 51, 0, 0, 17, 0, 0,
+  0, 0, 0, 0, 27, 70, 21, 0, 16, 15,
+  54, 0, 0, 0, 24, 0, 2, 0, 0, 0,
+  0, 60, 12, 0, 0, 0, 0, 79, 0, 14,
+  0, 5, 25, 0, 0, 14, 51, 41, 105, 41,
+  29, 52, 23, 0, 0, 0, 17, 23, 0, 13,
+  59, 1, 72, 42, 0, 0, 0, 22, 38, 13,
+  13, 6, 0, 7, 0, 21, 38, 13, 14, 0,
+  0, 64, 43, 11, 0, 0, 1, 54, 0, 38,
+  0, 39, 17, 0, 12, 19, 36, 29, 3, 0,
+  0, 0, 0, 0, 0, 11, 0, 0, 0, 0,
+  0, 70, 0, 0, 91, 0, 38, 0, 8, 0,
+  0, 4, 0, 0, 64, 10, 0, 0, 0, 114,
+  20, 0, 74, 27, 0, 45, 12, 51, 27, 0,
+  0, 0, 15, 101, 0, 21, 22, 36, 22, 0,
+  57, 0, 0, 0, 62, 0, 29, 0, 0, 72,
+  95, 0, 0, 0, 0, 80, 0, 16, 0, 0,
+  0, 13, 0, 0, 0, 0, 0, 0, 0, 33,
+  0, 3, 0, 0, 0, 0, 4, 22, 21, 0,
+  99, 34, 0, 157, 0, 0, 0, 0, 0, 17,
+  14, 49, 0, 0, 14, 40, 0, 1, 5, 82,
+  30, 0, 0, 0, 0, 0, 0, 147, 4, 78,
+  0, 24, 0, 23, 87, 19, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 3, 42, 0, 0, 78,
+  0, 0, 59, 0, 56, 0, 27, 0, 0, 28,
+  13, 0, 118, 0, 0, 48, 0, 113, 0, 36,
+  68, 0, 0, 7, 28, 0, 17, 0, 0, 0,
+  10, 108, 35, 0, 27, 10, 7, 0, 0, 0,
+  13, 0, 52, 0, 0, 0, 0, 5, 41, 0,
+  0, 0, 0, 82, 0, 16, 0, 8, 18, 0,
+  0, 0, 39, 10, 84, 0, 0, 54, 5, 43,
+  0, 6, 0, 3, 0, 26, 0, 9, 38, 0,
+  15, 120, 0, 0, 0, 0, 0, 3, 58, 72,
+  0, 0, 0, 18, 0, 18, 44, 0, 0, 51,
+  0, 3, 0, 0, 0, 91, 41, 0, 0, 22,
+  0, 0, 0, 22, 0, 25, 0, 45, 0, 53,
+  1, 0, 0, 32, 0, 0, 0, 70, 11, 0,
+  0, 0, 19, 0, 13, 14, 0, 9, 0, 0,
+  0, 0, 0, 11, 0, 0, 0, 58, 10, 0,
+  0, 20, 0, 0, 2, 19, 0, 27, 10, 28,
+  51, 0, 32, 5, 54, 4, 0, 0, 52, 5,
+  0, 37, 0, 0, 0, 30, 0, 0, 0, 0,
+  3, 4, 0, 16, 10, 25, 57, 0, 0, 17,
+  37, 0, 63, 43, 24, 47, 55, 1, 2, 0,
+  25, 2, 0, 0, 0, 0, 117, 0, 0, 75,
+  0, 0, 21, 0, 0, 1, 34, 80, 0, 0,
+  0, 31, 19, 0, 0, 94, 14, 24, 0, 0,
+  0, 29, 0, 0, 10, 39, 0, 0, 0, 0,
+  0, 56, 0, 0, 0, 0, 0, 7, 0, 0,
+  0, 0, 0, 0, 0, 155, 0, 0, 71, 0,
+  21, 0, 50, 0, 0, 5, 0, 0, 108, 0,
+  0, 0, 0, 98, 0, 0, 39, 7, 0, 0,
+  0, 22, 15, 0, 0, 0, 31, 74, 16, 3,
+  15, 30, 48, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 72, 30, 0, 0, 0, 0, 78,
+  0, 23, 0, 11, 40, 0, 0, 0, 17, 16,
+  68, 25, 10, 51, 0, 3, 0, 0, 33, 0,
+  0, 53, 0, 0, 59, 0, 5, 69, 0, 0,
+  0, 0, 0, 19, 45, 76, 0, 0, 0, 17,
+  2, 8, 10, 22, 0, 35, 0, 0, 0, 0,
+  0, 77, 41, 11, 0, 18, 0, 0, 0, 17,
+  0, 13, 0, 0, 0, 39, 0, 0, 0, 0,
+  0, 0, 0, 110, 0, 0, 0, 0, 15, 4,
+  28, 0, 0, 0, 0, 0, 48, 0, 0, 6,
+  0, 9, 0, 40, 17, 0, 0, 0, 0, 0,
+  53, 0, 0, 17, 0, 52, 45, 0, 40, 9,
+  68, 0, 0, 0, 56, 0, 0, 5, 0, 0,
+  0, 21, 0, 0, 0, 0, 1, 53, 0, 16,
+  7, 45, 50, 0, 0, 13, 38, 10, 68, 48,
+  19, 52, 56, 0, 0, 0, 26, 9, 0, 10,
+  0, 52, 52, 0, 44, 0, 21, 0, 7, 0,
+  0, 3, 68, 73, 3, 33, 10, 1, 18, 0,
+  44, 0, 0, 50, 14, 42, 0, 0, 0, 12,
+  60, 0, 0, 39, 0, 0, 0, 7, 0, 62,
+  39, 63, 0, 87, 51, 0, 0, 0, 0, 0,
+  0, 78, 42, 0, 0, 0, 18, 20, 19, 14,
+  11, 0, 3, 81, 0, 28, 0, 0, 0, 0,
+  0, 30, 0, 13, 8, 1, 0, 0, 0, 18,
+  37, 38, 21, 0, 88, 0, 16, 0, 65, 54,
+  0, 0, 46, 25, 0, 61, 0, 19, 5, 30,
+  0, 0, 0, 0, 0, 0, 0, 15, 38, 43,
+  88, 0, 0, 20, 22, 0, 0, 24, 58, 18,
+  39, 4, 45, 0, 79, 0, 1, 0, 14, 0,
+  60, 29, 0, 164, 0, 0, 18, 0, 0, 0,
+  3, 20, 0, 48, 30, 38, 0, 0, 13, 76,
+  24, 1, 0, 0, 0, 35, 0, 48, 0, 88,
+  0, 0, 0, 20, 63, 58, 24, 0, 0, 0,
+  0, 0, 0, 11, 0, 0, 13, 0, 0, 83,
+  0, 0, 99, 0, 57, 0, 22, 0, 0, 57,
+  14, 0, 110, 0, 0, 29, 2, 76, 21, 14,
+  67, 27, 0, 44, 44, 26, 0, 0, 0, 0,
+  32, 108, 0, 10, 10, 0, 11, 0, 10, 13,
+  0, 0, 58, 0, 30, 0, 0, 71, 79, 0,
+  0, 0, 0, 18, 0, 26, 0, 0, 0, 0,
+  0, 0, 4, 4, 54, 0, 0, 35, 0, 18,
+  0, 0, 0, 17, 0, 23, 0, 0, 70, 0,
+  4, 150, 0, 0, 0, 0, 0, 1, 23, 94,
+  0, 0, 0, 44, 0, 0, 21, 54, 0, 39,
+  0, 0, 0, 0, 0, 45, 16, 26, 0, 7,
+  0, 0, 0, 50, 0, 0, 0, 11, 0, 27,
+  0, 8, 1, 0, 0, 0, 12, 123, 0, 0,
+  39, 0, 39, 0, 42, 0, 0, 32, 0, 0,
+  97, 0, 0, 31, 0, 64, 0, 26, 51, 0,
+  0, 17, 0, 0, 0, 0, 0, 0, 27, 70,
+  21, 0, 16, 15, 54, 0, 0, 0, 24, 0,
+  2, 0, 0, 0, 0, 60, 12, 0, 0, 0,
+  0, 79, 0, 14, 0, 5, 25, 0, 0, 14,
+  51, 41, 105, 41, 29, 52, 23, 0, 0, 0,
+  17, 23, 0, 13, 0, 43, 48, 0, 24, 32,
+  13, 0, 8, 0, 0, 0, 63, 49, 0, 0,
+  3, 17, 8, 10, 0, 0, 0, 37, 41, 35,
+  6, 0, 0, 48, 48, 0, 0, 14, 0, 0,
+  0, 2, 0, 39, 0, 40, 0, 41, 21, 0,
+  3, 0, 0, 0, 0, 40, 61, 0, 0, 0,
+  14, 6, 2, 35, 0, 6, 0, 21, 0, 0,
+  0, 27, 0, 0, 0, 32, 20, 0, 21, 28,
+  0, 0, 0, 25, 16, 25, 21, 40, 63, 0,
+  39, 18, 50, 13, 0, 0, 32, 28, 0, 22,
+  0, 38, 15, 31, 0, 0, 0, 0, 0, 28,
+  14, 0, 53, 57, 40, 0, 0, 20, 46, 0,
+  33, 38, 62, 29, 61, 16, 47, 0, 46, 37,
+  0, 1, 21, 0, 99, 34, 0, 157, 0, 0,
+  0, 0, 0, 17, 14, 49, 0, 0, 14, 40,
+  0, 1, 5, 82, 30, 0, 0, 0, 0, 0,
+  0, 147, 4, 78, 0, 24, 0, 23, 87, 19,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+  42, 0, 0, 78, 0, 0, 59, 0, 56, 0,
+  27, 0, 0, 28, 13, 0, 118, 0, 0, 48,
+  0, 113, 0, 36, 68, 0, 0, 7, 28, 0,
+  17, 0, 0, 0, 10, 108, 35, 0, 27, 10,
+  7, 0, 0, 0, 13, 0, 52, 0, 0, 0,
+  0, 5, 41, 0, 0, 0, 0, 82, 0, 16,
+  0, 8, 18, 0, 0, 0, 39, 10, 84, 0,
+  0, 54, 5, 43, 0, 6, 0, 3, 0, 26,
+  0, 9, 38, 0, 15, 120, 0, 0, 0, 0,
+  0, 3, 58, 72, 0, 0, 0, 18, 0, 18,
+  44, 0, 0, 51, 0, 3, 0, 0, 0, 91,
+  41, 0, 0, 22, 0, 0, 0, 22, 0, 25,
+  0, 45, 0, 53, 1, 0, 0, 32, 0, 0,
+  0, 70, 11, 0, 0, 0, 19, 0, 13, 14,
+  0, 9, 0, 0, 0, 0, 0, 11, 0, 0,
+  0, 58, 10, 0, 0, 20, 0, 0, 2, 19,
+  0, 27, 10, 28, 51, 0, 32, 5, 54, 4,
+  0, 0, 52, 5, 0, 37, 0, 0, 0, 30,
+  0, 0, 0, 0, 3, 4, 0, 16, 10, 25,
+  57, 0, 0, 17, 37, 0, 63, 43, 24, 47,
+  55, 1, 2, 0, 25, 2, 0, 0, 0, 70,
+  65, 0, 63, 0, 15, 0, 1, 0, 14, 0,
+  64, 75, 0, 51, 17, 7, 26, 16, 9, 0,
+  0, 47, 38, 59, 0, 0, 0, 0, 53, 0,
+  0, 37, 12, 0, 0, 0, 0, 53, 50, 43,
+  24, 71, 73, 0, 0, 0, 0, 0, 0, 26,
+  50, 0, 0, 0, 0, 20, 1, 27, 24, 0,
+  0, 63, 0, 2, 29, 0, 0, 0, 0, 0,
+  7, 41, 16, 12, 0, 17, 0, 23, 46, 34,
+  33, 22, 87, 14, 32, 4, 49, 40, 0, 20,
+  24, 31, 0, 54, 0, 35, 3, 41, 0, 0,
+  0, 0, 0, 0, 7, 10, 34, 32, 82, 0,
+  0, 13, 31, 0, 0, 29, 54, 8, 7, 0,
+  55, 0, 75, 11, 2, 0, 0, 0, 59, 0,
+  5, 69, 0, 0, 0, 0, 0, 19, 45, 76,
+  0, 0, 0, 17, 2, 8, 10, 22, 0, 35,
+  0, 0, 0, 0, 0, 77, 41, 11, 0, 18,
+  0, 0, 0, 17, 0, 13, 0, 0, 0, 39,
+  0, 0, 0, 0, 0, 0, 0, 110, 0, 0,
+  0, 0, 15, 4, 28, 0, 0, 0, 0, 0,
+  48, 0, 0, 6, 0, 9, 0, 40, 17, 0,
+  0, 0, 0, 0, 53, 0, 0, 17, 0, 52,
+  45, 0, 40, 9, 68, 0, 0, 0, 56, 0,
+  0, 5, 0, 0, 0, 21, 0, 0, 0, 0,
+  1, 53, 0, 16, 7, 45, 50, 0, 0, 13,
+  38, 10, 68, 48, 19, 52, 56, 0, 0, 0,
+  26, 9, 0, 10, 0, 52, 52, 0, 44, 0,
+  21, 0, 7, 0, 0, 3, 68, 73, 3, 33,
+  10, 1, 18, 0, 44, 0, 0, 50, 14, 42,
+  0, 0, 0, 12, 60, 0, 0, 39, 0, 0,
+  0, 7, 0, 62, 39, 63, 0, 87, 51, 0,
+  0, 0, 0, 0, 0, 78, 42, 0, 0, 0,
+  18, 20, 19, 14, 11, 0, 3, 81, 0, 28,
+  0, 0, 0, 0, 0, 30, 0, 13, 8, 1,
+  0, 0, 0, 18, 37, 38, 21, 0, 88, 0,
+  16, 0, 65, 54, 0, 0, 46, 25, 0, 61,
+  0, 19, 5, 30, 0, 0, 0, 0, 0, 0,
+  0, 15, 38, 43, 88, 0, 0, 20, 22, 0,
+  0, 24, 58, 18, 39, 4, 45, 0, 79, 0,
+  1, 0, 0, 16, 100, 0, 22, 0, 0, 0,
+  0, 0, 0, 11, 22, 94, 0, 49, 0, 51,
+  31, 35, 50, 27, 110, 9, 0, 0, 0, 0,
+  0, 0, 32, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 94, 0, 0, 96, 51, 18, 0, 0,
+  0, 0, 0, 79, 0, 0, 15, 0, 24, 0,
+  24, 0, 7, 8, 19, 6, 56, 0, 0, 10,
+  0, 51, 0, 0, 21, 34, 0, 0, 0, 16,
+  0, 0, 24, 0, 36, 0, 41, 12, 2, 0,
+  43, 21, 0, 36, 0, 0, 5, 39, 0, 0,
+  0, 27, 23, 0, 0, 0, 0, 0, 0, 11,
+  0, 6, 79, 9, 0, 5, 40, 0, 52, 15,
+  28, 31, 21, 0, 0, 0, 55, 12, 0, 0,
+  0, 0, 70, 0, 4, 150, 0, 0, 0, 0,
+  0, 1, 23, 94, 0, 0, 0, 44, 0, 0,
+  21, 54, 0, 39, 0, 0, 0, 0, 0, 45,
+  16, 26, 0, 7, 0, 0, 0, 50, 0, 0,
+  0, 11, 0, 27, 0, 8, 1, 0, 0, 0,
+  12, 123, 0, 0, 39, 0, 39, 0, 42, 0,
+  0, 32, 0, 0, 97, 0, 0, 31, 0, 64,
+  0, 26, 51, 0, 0, 17, 0, 0, 0, 0,
+  0, 0, 27, 70, 21, 0, 16, 15, 54, 0,
+  0, 0, 24, 0, 2, 0, 0, 0, 0, 60,
+  12, 0, 0, 0, 0, 79, 0, 14, 0, 5,
+  25, 0, 0, 14, 51, 41, 105, 41, 29, 52,
+  23, 0, 0, 0, 17, 23, 0, 13, 0, 43,
+  48, 0, 24, 32, 13, 0, 8, 0, 0, 0,
+  63, 49, 0, 0, 3, 17, 8, 10, 0, 0,
+  0, 37, 41, 35, 6, 0, 0, 48, 48, 0,
+  0, 14, 0, 0, 0, 2, 0, 39, 0, 40,
+  0, 41, 21, 0, 3, 0, 0, 0, 0, 40,
+  61, 0, 0, 0, 14, 6, 2, 35, 0, 6,
+  0, 21, 0, 0, 0, 27, 0, 0, 0, 32,
+  20, 0, 21, 28, 0, 0, 0, 25, 16, 25,
+  21, 40, 63, 0, 39, 18, 50, 13, 0, 0,
+  32, 28, 0, 22, 0, 38, 15, 31, 0, 0,
+  0, 0, 0, 28, 14, 0, 53, 57, 40, 0,
+  0, 20, 46, 0, 33, 38, 62, 29, 61, 16,
+  47, 0, 46, 37, 0, 1, 0, 41, 74, 0,
+  7, 0, 37, 0, 26, 0, 0, 0, 8, 45,
+  0, 15, 14, 0, 13, 0, 0, 0, 20, 55,
+  23, 53, 16, 0, 159, 1, 19, 0, 8, 19,
+  20, 0, 0, 0, 0, 81, 7, 52, 28, 35,
+  49, 21, 9, 3, 0, 0, 0, 24, 50, 0,
+  0, 0, 1, 33, 4, 24, 7, 14, 0, 0,
+  0, 27, 51, 0, 10, 0, 0, 31, 38, 26,
+  32, 14, 0, 0, 0, 32, 48, 29, 26, 13,
+  31, 0, 3, 25, 74, 17, 4, 0, 45, 17,
+  0, 32, 0, 0, 21, 15, 0, 0, 0, 0,
+  6, 22, 50, 8, 38, 32, 47, 0, 0, 0,
+  1, 0, 13, 0, 30, 2, 0, 0, 24, 0,
+  46, 24, 32, 0, 0, 9, 38, 0, 15, 120,
+  0, 0, 0, 0, 0, 3, 58, 72, 0, 0,
+  0, 18, 0, 18, 44, 0, 0, 51, 0, 3,
+  0, 0, 0, 91, 41, 0, 0, 22, 0, 0,
+  0, 22, 0, 25, 0, 45, 0, 53, 1, 0,
+  0, 32, 0, 0, 0, 70, 11, 0, 0, 0,
+  19, 0, 13, 14, 0, 9, 0, 0, 0, 0,
+  0, 11, 0, 0, 0, 58, 10, 0, 0, 20,
+  0, 0, 2, 19, 0, 27, 10, 28, 51, 0,
+  32, 5, 54, 4, 0, 0, 52, 5, 0, 37,
+  0, 0, 0, 30, 0, 0, 0, 0, 3, 4,
+  0, 16, 10, 25, 57, 0, 0, 17, 37, 0,
+  63, 43, 24, 47, 55, 1, 2, 0, 25, 2,
+  0, 0, 0, 70, 65, 0, 63, 0, 15, 0,
+  1, 0, 14, 0, 64, 75, 0, 51, 17, 7,
+  26, 16, 9, 0, 0, 47, 38, 59, 0, 0,
+  0, 0, 53, 0, 0, 37, 12, 0, 0, 0,
+  0, 53, 50, 43, 24, 71, 73, 0, 0, 0,
+  0, 0, 0, 26, 50, 0, 0, 0, 0, 20,
+  1, 27, 24, 0, 0, 63, 0, 2, 29, 0,
+  0, 0, 0, 0, 7, 41, 16, 12, 0, 17,
+  0, 23, 46, 34, 33, 22, 87, 14, 32, 4,
+  49, 40, 0, 20, 24, 31, 0, 54, 0, 35,
+  3, 41, 0, 0, 0, 0, 0, 0, 7, 10,
+  34, 32, 82, 0, 0, 13, 31, 0, 0, 29,
+  54, 8, 7, 0, 55, 0, 75, 11, 2, 0,
+  0, 0, 119, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 103, 0, 9, 0, 6, 10, 5,
+  9, 50, 108, 24, 0, 0, 0, 8, 184, 0,
+  22, 0, 0, 31, 0, 0, 11, 12, 0, 10,
+  106, 0, 19, 21, 57, 33, 0, 2, 16, 0,
+  0, 65, 0, 0, 30, 0, 14, 26, 31, 0,
+  30, 40, 20, 0, 16, 5, 36, 0, 0, 70,
+  0, 0, 38, 61, 0, 0, 13, 0, 0, 0,
+  25, 10, 0, 19, 7, 11, 0, 47, 49, 0,
+  0, 54, 39, 0, 33, 24, 0, 0, 0, 22,
+  19, 7, 17, 0, 40, 27, 0, 5, 0, 0,
+  50, 3, 0, 0, 37, 20, 52, 0, 0, 30,
+  0, 0, 0, 0, 2, 25, 2, 0, 0, 52,
+  52, 0, 44, 0, 21, 0, 7, 0, 0, 3,
+  68, 73, 3, 33, 10, 1, 18, 0, 44, 0,
+  0, 50, 14, 42, 0, 0, 0, 12, 60, 0,
+  0, 39, 0, 0, 0, 7, 0, 62, 39, 63,
+  0, 87, 51, 0, 0, 0, 0, 0, 0, 78,
+  42, 0, 0, 0, 18, 20, 19, 14, 11, 0,
+  3, 81, 0, 28, 0, 0, 0, 0, 0, 30,
+  0, 13, 8, 1, 0, 0, 0, 18, 37, 38,
+  21, 0, 88, 0, 16, 0, 65, 54, 0, 0,
+  46, 25, 0, 61, 0, 19, 5, 30, 0, 0,
+  0, 0, 0, 0, 0, 15, 38, 43, 88, 0,
+  0, 20, 22, 0, 0, 24, 58, 18, 39, 4,
+  45, 0, 79, 0, 1, 0, 0, 16, 100, 0,
+  22, 0, 0, 0, 0, 0, 0, 11, 22, 94,
+  0, 49, 0, 51, 31, 35, 50, 27, 110, 9,
+  0, 0, 0, 0, 0, 0, 32, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 94, 0, 0, 96,
+  51, 18, 0, 0, 0, 0, 0, 79, 0, 0,
+  15, 0, 24, 0, 24, 0, 7, 8, 19, 6,
+  56, 0, 0, 10, 0, 51, 0, 0, 21, 34,
+  0, 0, 0, 16, 0, 0, 24, 0, 36, 0,
+  41, 12, 2, 0, 43, 21, 0, 36, 0, 0,
+  5, 39, 0, 0, 0, 27, 23, 0, 0, 0,
+  0, 0, 0, 11, 0, 6, 79, 9, 0, 5,
+  40, 0, 52, 15, 28, 31, 21, 0, 0, 0,
+  55, 12, 0, 0, 20, 0, 91, 19, 0, 0,
+  0, 12, 20, 0, 0, 0, 0, 125, 0, 0,
+  0, 22, 28, 1, 36, 70, 81, 11, 0, 0,
+  7, 35, 205, 0, 23, 21, 0, 15, 0, 0,
+  0, 31, 0, 0, 65, 0, 0, 38, 53, 70,
+  0, 0, 0, 0, 0, 120, 0, 6, 74, 0,
+  21, 12, 39, 0, 24, 17, 49, 0, 50, 0,
+  10, 0, 0, 102, 0, 0, 27, 14, 0, 0,
+  25, 0, 0, 0, 12, 2, 2, 20, 0, 0,
+  0, 33, 96, 33, 0, 2, 0, 0, 53, 20,
+  39, 0, 2, 26, 35, 12, 15, 0, 81, 19,
+  3, 30, 19, 0, 74, 0, 14, 0, 19, 31,
+  105, 0, 0, 54, 0, 0, 0, 0, 40, 22,
+  0, 17, 0, 43, 48, 0, 24, 32, 13, 0,
+  8, 0, 0, 0, 63, 49, 0, 0, 3, 17,
+  8, 10, 0, 0, 0, 37, 41, 35, 6, 0,
+  0, 48, 48, 0, 0, 14, 0, 0, 0, 2,
+  0, 39, 0, 40, 0, 41, 21, 0, 3, 0,
+  0, 0, 0, 40, 61, 0, 0, 0, 14, 6,
+  2, 35, 0, 6, 0, 21, 0, 0, 0, 27,
+  0, 0, 0, 32, 20, 0, 21, 28, 0, 0,
+  0, 25, 16, 25, 21, 40, 63, 0, 39, 18,
+  50, 13, 0, 0, 32, 28, 0, 22, 0, 38,
+  15, 31, 0, 0, 0, 0, 0, 28, 14, 0,
+  53, 57, 40, 0, 0, 20, 46, 0, 33, 38,
+  62, 29, 61, 16, 47, 0, 46, 37, 0, 1,
+  0, 41, 74, 0, 7, 0, 37, 0, 26, 0,
+  0, 0, 8, 45, 0, 15, 14, 0, 13, 0,
+  0, 0, 20, 55, 23, 53, 16, 0, 159, 1,
+  19, 0, 8, 19, 20, 0, 0, 0, 0, 81,
+  7, 52, 28, 35, 49, 21, 9, 3, 0, 0,
+  0, 24, 50, 0, 0, 0, 1, 33, 4, 24,
+  7, 14, 0, 0, 0, 27, 51, 0, 10, 0,
+  0, 31, 38, 26, 32, 14, 0, 0, 0, 32,
+  48, 29, 26, 13, 31, 0, 3, 25, 74, 17,
+  4, 0, 45, 17, 0, 32, 0, 0, 21, 15,
+  0, 0, 0, 0, 6, 22, 50, 8, 38, 32,
+  47, 0, 0, 0, 1, 0, 13, 0, 30, 2,
+  0, 0, 24, 0, 46, 24, 32, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 70, 65, 0,
+  63, 0, 15, 0, 1, 0, 14, 0, 64, 75,
+  0, 51, 17, 7, 26, 16, 9, 0, 0, 47,
+  38, 59, 0, 0, 0, 0, 53, 0, 0, 37,
+  12, 0, 0, 0, 0, 53, 50, 43, 24, 71,
+  73, 0, 0, 0, 0, 0, 0, 26, 50, 0,
+  0, 0, 0, 20, 1, 27, 24, 0, 0, 63,
+  0, 2, 29, 0, 0, 0, 0, 0, 7, 41,
+  16, 12, 0, 17, 0, 23, 46, 34, 33, 22,
+  87, 14, 32, 4, 49, 40, 0, 20, 24, 31,
+  0, 54, 0, 35, 3, 41, 0, 0, 0, 0,
+  0, 0, 7, 10, 34, 32, 82, 0, 0, 13,
+  31, 0, 0, 29, 54, 8, 7, 0, 55, 0,
+  75, 11, 2, 0, 0, 0, 119, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 103, 0, 9,
+  0, 6, 10, 5, 9, 50, 108, 24, 0, 0,
+  0, 8, 184, 0, 22, 0, 0, 31, 0, 0,
+  11, 12, 0, 10, 106, 0, 19, 21, 57, 33,
+  0, 2, 16, 0, 0, 65, 0, 0, 30, 0,
+  14, 26, 31, 0, 30, 40, 20, 0, 16, 5,
+  36, 0, 0, 70, 0, 0, 38, 61, 0, 0,
+  13, 0, 0, 0, 25, 10, 0, 19, 7, 11,
+  0, 47, 49, 0, 0, 54, 39, 0, 33, 24,
+  0, 0, 0, 22, 19, 7, 17, 0, 40, 27,
+  0, 5, 0, 0, 50, 3, 0, 0, 37, 20,
+  52, 0, 0, 30, 0, 0, 0, 0, 2, 25,
+  2, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 16, 100, 0, 22, 0, 0, 0, 0, 0,
+  0, 11, 22, 94, 0, 49, 0, 51, 31, 35,
+  50, 27, 110, 9, 0, 0, 0, 0, 0, 0,
+  32, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  94, 0, 0, 96, 51, 18, 0, 0, 0, 0,
+  0, 79, 0, 0, 15, 0, 24, 0, 24, 0,
+  7, 8, 19, 6, 56, 0, 0, 10, 0, 51,
+  0, 0, 21, 34, 0, 0, 0, 16, 0, 0,
+  24, 0, 36, 0, 41, 12, 2, 0, 43, 21,
+  0, 36, 0, 0, 5, 39, 0, 0, 0, 27,
+  23, 0, 0, 0, 0, 0, 0, 11, 0, 6,
+  79, 9, 0, 5, 40, 0, 52, 15, 28, 31,
+  21, 0, 0, 0, 55, 12, 0, 0, 20, 0,
+  91, 19, 0, 0, 0, 12, 20, 0, 0, 0,
+  0, 125, 0, 0, 0, 22, 28, 1, 36, 70,
+  81, 11, 0, 0, 7, 35, 205, 0, 23, 21,
+  0, 15, 0, 0, 0, 31, 0, 0, 65, 0,
+  0, 38, 53, 70, 0, 0, 0, 0, 0, 120,
+  0, 6, 74, 0, 21, 12, 39, 0, 24, 17,
+  49, 0, 50, 0, 10, 0, 0, 102, 0, 0,
+  27, 14, 0, 0, 25, 0, 0, 0, 12, 2,
+  2, 20, 0, 0, 0, 33, 96, 33, 0, 2,
+  0, 0, 53, 20, 39, 0, 2, 26, 35, 12,
+  15, 0, 81, 19, 3, 30, 19, 0, 74, 0,
+  14, 0, 19, 31, 105, 0, 0, 54, 0, 0,
+  0, 0, 40, 22, 0, 17, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 23, 32, 93, 27, 1, 9, 26, 5,
+  18, 0, 0, 0, 0, 103, 0, 30, 67, 4,
+  0, 16, 13, 75, 10, 41, 20, 0, 6, 20,
+  201, 42, 3, 62, 71, 0, 24, 0, 0, 56,
+  0, 4, 5, 32, 0, 22, 9, 88, 48, 0,
+  0, 0, 0, 51, 21, 3, 55, 0, 44, 0,
+  32, 0, 31, 72, 0, 0, 0, 0, 48, 9,
+  120, 30, 0, 10, 58, 0, 32, 0, 53, 0,
+  0, 37, 0, 0, 36, 11, 0, 15, 0, 0,
+  58, 5, 0, 0, 0, 3, 0, 36, 0, 0,
+  40, 101, 17, 0, 0, 52, 55, 89, 20, 0,
+  9, 0, 2, 9, 0, 33, 6, 2, 40, 0,
+  19, 12, 51, 0, 0, 0, 3, 0, 39, 30,
+  0, 67, 0, 11, 0, 33, 2, 0, 0, 0,
+  0, 17, 28, 49, 0, 0, 52, 3, 0, 0,
+  28, 58, 0, 42, 19, 0, 0, 8, 0, 9,
+  0, 26, 82, 21, 0, 0, 0, 27, 0, 8,
+  0, 40, 0, 22, 24, 91, 9, 110, 0, 0,
+  0, 27, 50, 0, 37, 0, 28, 0, 14, 0,
+  55, 50, 0, 43, 0, 0, 49, 11, 81, 0,
+  4, 0, 22, 7, 42, 0, 12, 0, 0, 26,
+  21, 0, 21, 24, 0, 0, 0, 0, 0, 9,
+  0, 0, 0, 9, 0, 20, 0, 0, 47, 83,
+  0, 52, 17, 21, 41, 51, 25, 0, 40, 5,
+  0, 40, 0, 11, 0, 0, 21, 0, 13, 13,
+  31, 0, 15, 0, 35, 1, 15, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 13, 24, 67, 6,
+  0, 18, 27, 22, 0, 0, 0, 0, 0, 97,
+  0, 0, 60, 4, 0, 5, 27, 86, 27, 52,
+  0, 0, 8, 9, 193, 55, 1, 28, 52, 0,
+  59, 1, 0, 58, 0, 17, 14, 39, 0, 14,
+  26, 83, 17, 0, 2, 0, 0, 64, 30, 0,
+  71, 0, 60, 0, 49, 0, 15, 71, 0, 0,
+  0, 0, 7, 6, 77, 33, 0, 22, 82, 11,
+  31, 27, 25, 0, 20, 13, 0, 0, 15, 5,
+  0, 0, 0, 0, 62, 3, 0, 0, 23, 0,
+  15, 37, 0, 0, 49, 67, 15, 0, 0, 37,
+  46, 75, 26, 0, 0, 6, 1, 16, 0, 37,
+  12, 0, 55, 0, 9, 28, 40, 0, 0, 0,
+  4, 0, 26, 26, 0, 60, 0, 15, 0, 5,
+  36, 23, 2, 0, 0, 31, 86, 8, 0, 0,
+  59, 11, 0, 0, 65, 56, 0, 25, 23, 0,
+  0, 13, 0, 13, 0, 11, 92, 0, 18, 0,
+  0, 32, 0, 53, 0, 28, 0, 44, 48, 94,
+  4, 86, 0, 7, 0, 38, 52, 0, 35, 0,
+  21, 0, 24, 0, 13, 27, 0, 40, 0, 11,
+  10, 0, 33, 0, 8, 0, 25, 13, 37, 0,
+  0, 0, 0, 15, 39, 0, 14, 13, 0, 0,
+  0, 0, 0, 24, 0, 0, 0, 13, 0, 47,
+  0, 0, 62, 50, 3, 0, 0, 13, 20, 1,
+  44, 0, 24, 28, 0, 29, 0, 15, 0, 0,
+  25, 0, 11, 10, 47, 0, 42, 0, 79, 0,
+  14, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 30, 25, 0, 1, 3, 33, 18, 0, 0,
+  0, 0, 0, 38, 0, 18, 43, 15, 0, 40,
+  38, 17, 58, 51, 0, 9, 8, 5, 128, 38,
+  0, 0, 54, 0, 69, 16, 0, 30, 0, 38,
+  21, 38, 0, 22, 60, 37, 2, 0, 0, 0,
+  0, 13, 47, 0, 16, 0, 64, 0, 29, 0,
+  6, 33, 7, 0, 0, 0, 7, 19, 25, 0,
+  0, 36, 79, 26, 45, 46, 0, 7, 30, 1,
+  38, 2, 13, 0, 0, 0, 0, 0, 54, 6,
+  3, 0, 38, 1, 15, 56, 0, 0, 37, 35,
+  9, 0, 0, 19, 20, 19, 57, 1, 0, 26,
+  0, 8, 0, 33, 5, 0, 23, 13, 0, 22,
+  19, 0, 0, 0, 19, 0, 11, 9, 0, 48,
+  13, 14, 0, 0, 29, 34, 3, 0, 0, 37,
+  105, 0, 2, 11, 53, 15, 0, 14, 67, 51,
+  53, 17, 9, 0, 0, 9, 0, 0, 0, 0,
+  96, 0, 32, 9, 0, 24, 0, 75, 0, 32,
+  0, 38, 68, 64, 0, 61, 0, 41, 0, 28,
+  43, 1, 16, 0, 14, 0, 11, 0, 0, 0,
+  0, 18, 0, 0, 0, 0, 17, 0, 10, 2,
+  29, 20, 37, 0, 16, 39, 0, 22, 45, 0,
+  41, 0, 0, 0, 0, 0, 0, 7, 0, 0,
+  0, 7, 0, 48, 0, 0, 52, 46, 8, 0,
+  0, 12, 18, 0, 59, 0, 0, 16, 0, 17,
+  0, 17, 0, 0, 14, 0, 6, 8, 40, 0,
+  40, 0, 76, 0, 11, 0, 23, 32, 93, 27,
+  1, 9, 26, 5, 18, 0, 0, 0, 0, 103,
+  0, 30, 67, 4, 0, 16, 13, 75, 10, 41,
+  20, 0, 6, 20, 201, 42, 3, 62, 71, 0,
+  24, 0, 0, 56, 0, 4, 5, 32, 0, 22,
+  9, 88, 48, 0, 0, 0, 0, 51, 21, 3,
+  55, 0, 44, 0, 32, 0, 31, 72, 0, 0,
+  0, 0, 48, 9, 120, 30, 0, 10, 58, 0,
+  32, 0, 53, 0, 0, 37, 0, 0, 36, 11,
+  0, 15, 0, 0, 58, 5, 0, 0, 0, 3,
+  0, 36, 0, 0, 40, 101, 17, 0, 0, 52,
+  55, 89, 20, 0, 9, 0, 2, 9, 0, 33,
+  6, 2, 40, 0, 19, 12, 51, 0, 0, 0,
+  3, 0, 39, 30, 0, 67, 0, 11, 0, 33,
+  2, 0, 0, 0, 0, 17, 28, 49, 0, 0,
+  52, 3, 0, 0, 28, 58, 0, 42, 19, 0,
+  0, 8, 0, 9, 0, 26, 82, 21, 0, 0,
+  0, 27, 0, 8, 0, 40, 0, 22, 24, 91,
+  9, 110, 0, 0, 0, 27, 50, 0, 37, 0,
+  28, 0, 14, 0, 55, 50, 0, 43, 0, 0,
+  49, 11, 81, 0, 4, 0, 22, 7, 42, 0,
+  12, 0, 0, 26, 21, 0, 21, 24, 0, 0,
+  0, 0, 0, 9, 0, 0, 0, 9, 0, 20,
+  0, 0, 47, 83, 0, 52, 17, 21, 41, 51,
+  25, 0, 40, 5, 0, 40, 0, 11, 0, 0,
+  21, 0, 13, 13, 31, 0, 15, 0, 35, 1,
+  15, 0, 0, 27, 36, 37, 0, 42, 17, 9,
+  15, 0, 0, 22, 97, 0, 7, 27, 55, 8,
+  0, 0, 0, 69, 0, 8, 46, 0, 0, 20,
+  0, 2, 0, 37, 78, 0, 3, 0, 0, 24,
+  0, 73, 0, 34, 30, 29, 29, 57, 25, 42,
+  0, 28, 0, 43, 34, 9, 17, 0, 10, 0,
+  0, 0, 6, 14, 0, 16, 0, 0, 0, 0,
+  28, 0, 23, 6, 0, 10, 7, 0, 0, 23,
+  0, 35, 38, 0, 52, 56, 0, 0, 11, 0,
+  0, 18, 0, 0, 0, 4, 0, 16, 29, 0,
+  0, 66, 6, 0, 0, 10, 18, 0, 38, 0,
+  0, 6, 0, 7, 0, 1, 0, 0, 17, 0,
+  0, 0, 5, 0, 43, 0, 63, 0, 11, 0,
+  13, 24, 67, 6, 0, 18, 27, 22, 0, 0,
+  0, 0, 0, 97, 0, 0, 60, 4, 0, 5,
+  27, 86, 27, 52, 0, 0, 8, 9, 193, 55,
+  1, 28, 52, 0, 59, 1, 0, 58, 0, 17,
+  14, 39, 0, 14, 26, 83, 17, 0, 2, 0,
+  0, 64, 30, 0, 71, 0, 60, 0, 49, 0,
+  15, 71, 0, 0, 0, 0, 7, 6, 77, 33,
+  0, 22, 82, 11, 31, 27, 25, 0, 20, 13,
+  0, 0, 15, 5, 0, 0, 0, 0, 62, 3,
+  0, 0, 23, 0, 15, 37, 0, 0, 49, 67,
+  15, 0, 0, 37, 46, 75, 26, 0, 0, 6,
+  1, 16, 0, 37, 12, 0, 55, 0, 9, 28,
+  40, 0, 0, 0, 4, 0, 26, 26, 0, 60,
+  0, 15, 0, 5, 36, 23, 2, 0, 0, 31,
+  86, 8, 0, 0, 59, 11, 0, 0, 65, 56,
+  0, 25, 23, 0, 0, 13, 0, 13, 0, 11,
+  92, 0, 18, 0, 0, 32, 0, 53, 0, 28,
+  0, 44, 48, 94, 4, 86, 0, 7, 0, 38,
+  52, 0, 35, 0, 21, 0, 24, 0, 13, 27,
+  0, 40, 0, 11, 10, 0, 33, 0, 8, 0,
+  25, 13, 37, 0, 0, 0, 0, 15, 39, 0,
+  14, 13, 0, 0, 0, 0, 0, 24, 0, 0,
+  0, 13, 0, 47, 0, 0, 62, 50, 3, 0,
+  0, 13, 20, 1, 44, 0, 24, 28, 0, 29,
+  0, 15, 0, 0, 25, 0, 11, 10, 47, 0,
+  42, 0, 79, 0, 14, 0, 3, 28, 40, 34,
+  0, 19, 25, 3, 20, 0, 0, 31, 114, 0,
+  21, 37, 61, 3, 0, 0, 0, 74, 0, 5,
+  57, 0, 0, 30, 0, 1, 0, 41, 79, 0,
+  10, 0, 0, 27, 0, 80, 0, 41, 32, 32,
+  31, 55, 32, 23, 0, 44, 0, 50, 31, 17,
+  17, 0, 7, 0, 0, 0, 12, 0, 0, 36,
+  0, 0, 4, 0, 28, 0, 17, 10, 0, 3,
+  3, 0, 15, 36, 0, 33, 36, 0, 51, 45,
+  0, 0, 5, 0, 0, 36, 0, 0, 0, 5,
+  0, 25, 33, 0, 3, 68, 5, 0, 5, 7,
+  24, 0, 28, 0, 2, 10, 6, 14, 0, 1,
+  0, 0, 2, 0, 6, 0, 15, 4, 59, 0,
+  74, 0, 21, 0, 0, 30, 25, 0, 1, 3,
+  33, 18, 0, 0, 0, 0, 0, 38, 0, 18,
+  43, 15, 0, 40, 38, 17, 58, 51, 0, 9,
+  8, 5, 128, 38, 0, 0, 54, 0, 69, 16,
+  0, 30, 0, 38, 21, 38, 0, 22, 60, 37,
+  2, 0, 0, 0, 0, 13, 47, 0, 16, 0,
+  64, 0, 29, 0, 6, 33, 7, 0, 0, 0,
+  7, 19, 25, 0, 0, 36, 79, 26, 45, 46,
+  0, 7, 30, 1, 38, 2, 13, 0, 0, 0,
+  0, 0, 54, 6, 3, 0, 38, 1, 15, 56,
+  0, 0, 37, 35, 9, 0, 0, 19, 20, 19,
+  57, 1, 0, 26, 0, 8, 0, 33, 5, 0,
+  23, 13, 0, 22, 19, 0, 0, 0, 19, 0,
+  11, 9, 0, 48, 13, 14, 0, 0, 29, 34,
+  3, 0, 0, 37, 105, 0, 2, 11, 53, 15,
+  0, 14, 67, 51, 53, 17, 9, 0, 0, 9,
+  0, 0, 0, 0, 96, 0, 32, 9, 0, 24,
+  0, 75, 0, 32, 0, 38, 68, 64, 0, 61,
+  0, 41, 0, 28, 43, 1, 16, 0, 14, 0,
+  11, 0, 0, 0, 0, 18, 0, 0, 0, 0,
+  17, 0, 10, 2, 29, 20, 37, 0, 16, 39,
+  0, 22, 45, 0, 41, 0, 0, 0, 0, 0,
+  0, 7, 0, 0, 0, 7, 0, 48, 0, 0,
+  52, 46, 8, 0, 0, 12, 18, 0, 59, 0,
+  0, 16, 0, 17, 0, 17, 0, 0, 14, 0,
+  6, 8, 40, 0, 40, 0, 76, 0, 11, 0,
+  4, 29, 39, 21, 0, 5, 28, 2, 19, 0,
+  0, 34, 112, 0, 22, 39, 53, 0, 0, 0,
+  0, 83, 0, 10, 59, 0, 0, 23, 0, 0,
+  0, 41, 82, 0, 23, 0, 0, 23, 0, 78,
+  0, 55, 37, 22, 36, 48, 30, 16, 0, 54,
+  0, 60, 33, 24, 31, 0, 11, 0, 7, 0,
+  17, 0, 0, 63, 0, 10, 7, 0, 36, 0,
+  8, 20, 0, 4, 0, 0, 33, 43, 0, 29,
+  44, 0, 61, 29, 0, 0, 0, 0, 0, 31,
+  0, 0, 0, 4, 0, 29, 42, 0, 5, 76,
+  2, 0, 8, 14, 30, 0, 21, 0, 0, 0,
+  8, 15, 0, 0, 0, 0, 0, 0, 6, 2,
+  19, 0, 53, 0, 69, 0, 17, 0, 0, 67,
+  0, 11, 0, 33, 2, 0, 0, 0, 0, 17,
+  28, 49, 0, 0, 52, 3, 0, 0, 28, 58,
+  0, 42, 19, 0, 0, 8, 0, 9, 0, 26,
+  82, 21, 0, 0, 0, 27, 0, 8, 0, 40,
+  0, 22, 24, 91, 9, 110, 0, 0, 0, 27,
+  50, 0, 37, 0, 28, 0, 14, 0, 55, 50,
+  0, 43, 0, 0, 49, 11, 81, 0, 4, 0,
+  22, 7, 42, 0, 12, 0, 0, 26, 21, 0,
+  21, 24, 0, 0, 0, 0, 0, 9, 0, 0,
+  0, 9, 0, 20, 0, 0, 47, 83, 0, 52,
+  17, 21, 41, 51, 25, 0, 40, 5, 0, 40,
+  0, 11, 0, 0, 21, 0, 13, 13, 31, 0,
+  15, 0, 35, 1, 15, 0, 0, 27, 36, 37,
+  0, 42, 17, 9, 15, 0, 0, 22, 97, 0,
+  7, 27, 55, 8, 0, 0, 0, 69, 0, 8,
+  46, 0, 0, 20, 0, 2, 0, 37, 78, 0,
+  3, 0, 0, 24, 0, 73, 0, 34, 30, 29,
+  29, 57, 25, 42, 0, 28, 0, 43, 34, 9,
+  17, 0, 10, 0, 0, 0, 6, 14, 0, 16,
+  0, 0, 0, 0, 28, 0, 23, 6, 0, 10,
+  7, 0, 0, 23, 0, 35, 38, 0, 52, 56,
+  0, 0, 11, 0, 0, 18, 0, 0, 0, 4,
+  0, 16, 29, 0, 0, 66, 6, 0, 0, 10,
+  18, 0, 38, 0, 0, 6, 0, 7, 0, 1,
+  0, 0, 17, 0, 0, 0, 5, 0, 43, 0,
+  63, 0, 11, 0, 0, 0, 0, 15, 0, 142,
+  5, 0, 3, 0, 0, 27, 43, 0, 0, 0,
+  6, 0, 0, 0, 37, 88, 23, 15, 8, 0,
+  0, 0, 0, 13, 0, 22, 26, 24, 0, 2,
+  0, 36, 0, 50, 0, 35, 0, 56, 1, 71,
+  43, 43, 0, 0, 0, 38, 8, 0, 4, 0,
+  67, 0, 33, 0, 0, 57, 0, 0, 64, 0,
+  0, 26, 62, 0, 74, 26, 27, 3, 4, 32,
+  9, 25, 0, 31, 35, 0, 37, 52, 8, 0,
+  19, 0, 0, 0, 0, 11, 7, 0, 1, 26,
+  0, 0, 10, 66, 18, 0, 0, 7, 8, 0,
+  31, 0, 0, 0, 0, 0, 0, 15, 0, 0,
+  111, 2, 35, 3, 0, 0, 0, 0, 41, 0,
+  0, 0, 0, 60, 0, 15, 0, 5, 36, 23,
+  2, 0, 0, 31, 86, 8, 0, 0, 59, 11,
+  0, 0, 65, 56, 0, 25, 23, 0, 0, 13,
+  0, 13, 0, 11, 92, 0, 18, 0, 0, 32,
+  0, 53, 0, 28, 0, 44, 48, 94, 4, 86,
+  0, 7, 0, 38, 52, 0, 35, 0, 21, 0,
+  24, 0, 13, 27, 0, 40, 0, 11, 10, 0,
+  33, 0, 8, 0, 25, 13, 37, 0, 0, 0,
+  0, 15, 39, 0, 14, 13, 0, 0, 0, 0,
+  0, 24, 0, 0, 0, 13, 0, 47, 0, 0,
+  62, 50, 3, 0, 0, 13, 20, 1, 44, 0,
+  24, 28, 0, 29, 0, 15, 0, 0, 25, 0,
+  11, 10, 47, 0, 42, 0, 79, 0, 14, 0,
+  3, 28, 40, 34, 0, 19, 25, 3, 20, 0,
+  0, 31, 114, 0, 21, 37, 61, 3, 0, 0,
+  0, 74, 0, 5, 57, 0, 0, 30, 0, 1,
+  0, 41, 79, 0, 10, 0, 0, 27, 0, 80,
+  0, 41, 32, 32, 31, 55, 32, 23, 0, 44,
+  0, 50, 31, 17, 17, 0, 7, 0, 0, 0,
+  12, 0, 0, 36, 0, 0, 4, 0, 28, 0,
+  17, 10, 0, 3, 3, 0, 15, 36, 0, 33,
+  36, 0, 51, 45, 0, 0, 5, 0, 0, 36,
+  0, 0, 0, 5, 0, 25, 33, 0, 3, 68,
+  5, 0, 5, 7, 24, 0, 28, 0, 2, 10,
+  6, 14, 0, 1, 0, 0, 2, 0, 6, 0,
+  15, 4, 59, 0, 74, 0, 21, 0, 0, 0,
+  0, 16, 0, 145, 3, 0, 12, 0, 0, 27,
+  50, 0, 0, 22, 2, 0, 1, 0, 35, 91,
+  18, 9, 3, 0, 0, 0, 0, 4, 0, 27,
+  23, 43, 0, 0, 0, 30, 0, 60, 0, 29,
+  0, 69, 6, 72, 26, 52, 0, 0, 0, 48,
+  12, 0, 0, 0, 56, 0, 35, 0, 2, 55,
+  0, 0, 72, 0, 0, 20, 53, 0, 83, 22,
+  17, 0, 0, 33, 2, 22, 0, 37, 41, 0,
+  32, 49, 7, 0, 27, 0, 0, 0, 0, 13,
+  1, 0, 15, 38, 0, 0, 2, 68, 27, 0,
+  0, 7, 17, 0, 22, 0, 0, 0, 0, 0,
+  0, 29, 0, 0, 104, 4, 40, 7, 0, 0,
+  0, 0, 54, 0, 3, 0, 0, 48, 13, 14,
+  0, 0, 29, 34, 3, 0, 0, 37, 105, 0,
+  2, 11, 53, 15, 0, 14, 67, 51, 53, 17,
+  9, 0, 0, 9, 0, 0, 0, 0, 96, 0,
+  32, 9, 0, 24, 0, 75, 0, 32, 0, 38,
+  68, 64, 0, 61, 0, 41, 0, 28, 43, 1,
+  16, 0, 14, 0, 11, 0, 0, 0, 0, 18,
+  0, 0, 0, 0, 17, 0, 10, 2, 29, 20,
+  37, 0, 16, 39, 0, 22, 45, 0, 41, 0,
+  0, 0, 0, 0, 0, 7, 0, 0, 0, 7,
+  0, 48, 0, 0, 52, 46, 8, 0, 0, 12,
+  18, 0, 59, 0, 0, 16, 0, 17, 0, 17,
+  0, 0, 14, 0, 6, 8, 40, 0, 40, 0,
+  76, 0, 11, 0, 4, 29, 39, 21, 0, 5,
+  28, 2, 19, 0, 0, 34, 112, 0, 22, 39,
+  53, 0, 0, 0, 0, 83, 0, 10, 59, 0,
+  0, 23, 0, 0, 0, 41, 82, 0, 23, 0,
+  0, 23, 0, 78, 0, 55, 37, 22, 36, 48,
+  30, 16, 0, 54, 0, 60, 33, 24, 31, 0,
+  11, 0, 7, 0, 17, 0, 0, 63, 0, 10,
+  7, 0, 36, 0, 8, 20, 0, 4, 0, 0,
+  33, 43, 0, 29, 44, 0, 61, 29, 0, 0,
+  0, 0, 0, 31, 0, 0, 0, 4, 0, 29,
+  42, 0, 5, 76, 2, 0, 8, 14, 30, 0,
+  21, 0, 0, 0, 8, 15, 0, 0, 0, 0,
+  0, 0, 6, 2, 19, 0, 53, 0, 69, 0,
+  17, 0, 0, 0, 0, 10, 0, 139, 4, 0,
+  12, 0, 0, 18, 33, 0, 0, 25, 0, 0,
+  0, 0, 30, 95, 19, 11, 3, 0, 0, 0,
+  0, 0, 0, 27, 29, 38, 0, 0, 0, 23,
+  0, 54, 0, 22, 0, 53, 1, 90, 35, 56,
+  0, 0, 0, 51, 6, 0, 10, 0, 55, 0,
+  49, 0, 11, 61, 0, 0, 76, 3, 0, 3,
+  55, 0, 82, 11, 11, 0, 0, 21, 26, 25,
+  0, 32, 34, 0, 41, 44, 0, 0, 22, 0,
+  0, 7, 0, 21, 4, 0, 4, 31, 0, 0,
+  7, 66, 36, 0, 0, 23, 27, 0, 16, 0,
+  0, 0, 0, 0, 0, 35, 0, 0, 100, 2,
+  34, 1, 0, 0, 0, 0, 28, 0, 0, 0,
+  0, 27, 36, 37, 0, 42, 17, 9, 15, 0,
+  0, 22, 97, 0, 7, 27, 55, 8, 0, 0,
+  0, 69, 0, 8, 46, 0, 0, 20, 0, 2,
+  0, 37, 78, 0, 3, 0, 0, 24, 0, 73,
+  0, 34, 30, 29, 29, 57, 25, 42, 0, 28,
+  0, 43, 34, 9, 17, 0, 10, 0, 0, 0,
+  6, 14, 0, 16, 0, 0, 0, 0, 28, 0,
+  23, 6, 0, 10, 7, 0, 0, 23, 0, 35,
+  38, 0, 52, 56, 0, 0, 11, 0, 0, 18,
+  0, 0, 0, 4, 0, 16, 29, 0, 0, 66,
+  6, 0, 0, 10, 18, 0, 38, 0, 0, 6,
+  0, 7, 0, 1, 0, 0, 17, 0, 0, 0,
+  5, 0, 43, 0, 63, 0, 11, 0, 0, 0,
+  0, 15, 0, 142, 5, 0, 3, 0, 0, 27,
+  43, 0, 0, 0, 6, 0, 0, 0, 37, 88,
+  23, 15, 8, 0, 0, 0, 0, 13, 0, 22,
+  26, 24, 0, 2, 0, 36, 0, 50, 0, 35,
+  0, 56, 1, 71, 43, 43, 0, 0, 0, 38,
+  8, 0, 4, 0, 67, 0, 33, 0, 0, 57,
+  0, 0, 64, 0, 0, 26, 62, 0, 74, 26,
+  27, 3, 4, 32, 9, 25, 0, 31, 35, 0,
+  37, 52, 8, 0, 19, 0, 0, 0, 0, 11,
+  7, 0, 1, 26, 0, 0, 10, 66, 18, 0,
+  0, 7, 8, 0, 31, 0, 0, 0, 0, 0,
+  0, 15, 0, 0, 111, 2, 35, 3, 0, 0,
+  0, 0, 41, 0, 0, 0, 0, 0, 0, 0,
+  0, 51, 48, 0, 17, 0, 0, 1, 56, 0,
+  12, 28, 33, 20, 5, 18, 77, 0, 0, 29,
+  0, 42, 17, 0, 0, 38, 0, 0, 71, 57,
+  0, 0, 0, 12, 0, 39, 0, 43, 0, 51,
+  0, 34, 20, 45, 0, 31, 15, 0, 71, 13,
+  0, 6, 44, 0, 0, 54, 15, 0, 0, 0,
+  0, 0, 23, 28, 33, 0, 0, 13, 0, 22,
+  15, 54, 0, 0, 0, 29, 69, 6, 16, 0,
+  25, 0, 11, 13, 3, 2, 0, 26, 5, 14,
+  0, 26, 0, 0, 43, 47, 11, 6, 0, 0,
+  0, 0, 43, 0, 0, 46, 1, 0, 0, 11,
+  0, 0, 48, 15, 46, 0, 23, 0, 104, 0,
+  47, 0, 0, 0, 3, 28, 40, 34, 0, 19,
+  25, 3, 20, 0, 0, 31, 114, 0, 21, 37,
+  61, 3, 0, 0, 0, 74, 0, 5, 57, 0,
+  0, 30, 0, 1, 0, 41, 79, 0, 10, 0,
+  0, 27, 0, 80, 0, 41, 32, 32, 31, 55,
+  32, 23, 0, 44, 0, 50, 31, 17, 17, 0,
+  7, 0, 0, 0, 12, 0, 0, 36, 0, 0,
+  4, 0, 28, 0, 17, 10, 0, 3, 3, 0,
+  15, 36, 0, 33, 36, 0, 51, 45, 0, 0,
+  5, 0, 0, 36, 0, 0, 0, 5, 0, 25,
+  33, 0, 3, 68, 5, 0, 5, 7, 24, 0,
+  28, 0, 2, 10, 6, 14, 0, 1, 0, 0,
+  2, 0, 6, 0, 15, 4, 59, 0, 74, 0,
+  21, 0, 0, 0, 0, 16, 0, 145, 3, 0,
+  12, 0, 0, 27, 50, 0, 0, 22, 2, 0,
+  1, 0, 35, 91, 18, 9, 3, 0, 0, 0,
+  0, 4, 0, 27, 23, 43, 0, 0, 0, 30,
+  0, 60, 0, 29, 0, 69, 6, 72, 26, 52,
+  0, 0, 0, 48, 12, 0, 0, 0, 56, 0,
+  35, 0, 2, 55, 0, 0, 72, 0, 0, 20,
+  53, 0, 83, 22, 17, 0, 0, 33, 2, 22,
+  0, 37, 41, 0, 32, 49, 7, 0, 27, 0,
+  0, 0, 0, 13, 1, 0, 15, 38, 0, 0,
+  2, 68, 27, 0, 0, 7, 17, 0, 22, 0,
+  0, 0, 0, 0, 0, 29, 0, 0, 104, 4,
+  40, 7, 0, 0, 0, 0, 54, 0, 3, 0,
+  0, 0, 0, 0, 0, 45, 41, 0, 20, 0,
+  0, 0, 75, 11, 19, 55, 39, 21, 25, 2,
+  84, 0, 0, 27, 13, 52, 3, 2, 0, 52,
+  0, 0, 56, 63, 0, 0, 0, 0, 0, 59,
+  0, 43, 0, 45, 7, 20, 17, 36, 0, 46,
+  0, 0, 66, 22, 0, 0, 25, 0, 0, 76,
+  20, 0, 0, 2, 0, 0, 13, 21, 31, 0,
+  0, 26, 0, 14, 8, 55, 0, 0, 0, 54,
+  58, 17, 20, 5, 37, 0, 12, 14, 8, 14,
+  4, 15, 7, 17, 1, 41, 0, 0, 39, 55,
+  6, 0, 4, 0, 0, 0, 35, 0, 0, 42,
+  13, 0, 0, 5, 0, 0, 43, 15, 52, 0,
+  18, 3, 121, 0, 68, 0, 9, 0, 4, 29,
+  39, 21, 0, 5, 28, 2, 19, 0, 0, 34,
+  112, 0, 22, 39, 53, 0, 0, 0, 0, 83,
+  0, 10, 59, 0, 0, 23, 0, 0, 0, 41,
+  82, 0, 23, 0, 0, 23, 0, 78, 0, 55,
+  37, 22, 36, 48, 30, 16, 0, 54, 0, 60,
+  33, 24, 31, 0, 11, 0, 7, 0, 17, 0,
+  0, 63, 0, 10, 7, 0, 36, 0, 8, 20,
+  0, 4, 0, 0, 33, 43, 0, 29, 44, 0,
+  61, 29, 0, 0, 0, 0, 0, 31, 0, 0,
+  0, 4, 0, 29, 42, 0, 5, 76, 2, 0,
+  8, 14, 30, 0, 21, 0, 0, 0, 8, 15,
+  0, 0, 0, 0, 0, 0, 6, 2, 19, 0,
+  53, 0, 69, 0, 17, 0, 0, 0, 0, 10,
+  0, 139, 4, 0, 12, 0, 0, 18, 33, 0,
+  0, 25, 0, 0, 0, 0, 30, 95, 19, 11,
+  3, 0, 0, 0, 0, 0, 0, 27, 29, 38,
+  0, 0, 0, 23, 0, 54, 0, 22, 0, 53,
+  1, 90, 35, 56, 0, 0, 0, 51, 6, 0,
+  10, 0, 55, 0, 49, 0, 11, 61, 0, 0,
+  76, 3, 0, 3, 55, 0, 82, 11, 11, 0,
+  0, 21, 26, 25, 0, 32, 34, 0, 41, 44,
+  0, 0, 22, 0, 0, 7, 0, 21, 4, 0,
+  4, 31, 0, 0, 7, 66, 36, 0, 0, 23,
+  27, 0, 16, 0, 0, 0, 0, 0, 0, 35,
+  0, 0, 100, 2, 34, 1, 0, 0, 0, 0,
+  28, 0, 0, 0, 0, 0, 0, 0, 9, 38,
+  29, 0, 28, 0, 15, 0, 49, 21, 13, 59,
+  25, 11, 12, 5, 68, 0, 0, 42, 2, 24,
+  1, 0, 0, 35, 0, 0, 51, 61, 4, 0,
+  0, 0, 0, 42, 8, 38, 0, 45, 9, 26,
+  16, 31, 0, 20, 23, 0, 74, 24, 0, 0,
+  43, 0, 0, 56, 26, 7, 0, 0, 0, 0,
+  26, 8, 30, 0, 0, 7, 0, 8, 2, 45,
+  9, 0, 0, 52, 52, 14, 29, 21, 20, 0,
+  7, 19, 17, 28, 6, 32, 0, 6, 20, 41,
+  0, 0, 30, 59, 7, 0, 1, 0, 0, 0,
+  35, 0, 0, 25, 13, 0, 0, 13, 0, 0,
+  41, 20, 37, 0, 1, 0, 90, 0, 36, 0,
+  0, 0, 0, 0, 0, 15, 0, 142, 5, 0,
+  3, 0, 0, 27, 43, 0, 0, 0, 6, 0,
+  0, 0, 37, 88, 23, 15, 8, 0, 0, 0,
+  0, 13, 0, 22, 26, 24, 0, 2, 0, 36,
+  0, 50, 0, 35, 0, 56, 1, 71, 43, 43,
+  0, 0, 0, 38, 8, 0, 4, 0, 67, 0,
+  33, 0, 0, 57, 0, 0, 64, 0, 0, 26,
+  62, 0, 74, 26, 27, 3, 4, 32, 9, 25,
+  0, 31, 35, 0, 37, 52, 8, 0, 19, 0,
+  0, 0, 0, 11, 7, 0, 1, 26, 0, 0,
+  10, 66, 18, 0, 0, 7, 8, 0, 31, 0,
+  0, 0, 0, 0, 0, 15, 0, 0, 111, 2,
+  35, 3, 0, 0, 0, 0, 41, 0, 0, 0,
+  0, 0, 0, 0, 0, 51, 48, 0, 17, 0,
+  0, 1, 56, 0, 12, 28, 33, 20, 5, 18,
+  77, 0, 0, 29, 0, 42, 17, 0, 0, 38,
+  0, 0, 71, 57, 0, 0, 0, 12, 0, 39,
+  0, 43, 0, 51, 0, 34, 20, 45, 0, 31,
+  15, 0, 71, 13, 0, 6, 44, 0, 0, 54,
+  15, 0, 0, 0, 0, 0, 23, 28, 33, 0,
+  0, 13, 0, 22, 15, 54, 0, 0, 0, 29,
+  69, 6, 16, 0, 25, 0, 11, 13, 3, 2,
+  0, 26, 5, 14, 0, 26, 0, 0, 43, 47,
+  11, 6, 0, 0, 0, 0, 43, 0, 0, 46,
+  1, 0, 0, 11, 0, 0, 48, 15, 46, 0,
+  23, 0, 104, 0, 47, 0, 0, 0, 0, 29,
+  0, 0, 20, 0, 45, 0, 38, 0, 0, 2,
+  26, 28, 73, 29, 52, 53, 0, 24, 91, 0,
+  0, 24, 16, 39, 26, 0, 0, 20, 0, 0,
+  40, 12, 3, 0, 0, 8, 0, 47, 0, 9,
+  0, 58, 0, 33, 12, 19, 0, 0, 17, 3,
+  66, 44, 0, 0, 7, 0, 0, 3, 7, 0,
+  0, 0, 0, 0, 42, 7, 32, 0, 0, 0,
+  0, 10, 51, 0, 4, 0, 0, 8, 61, 18,
+  25, 0, 32, 0, 8, 4, 12, 12, 2, 0,
+  0, 26, 0, 31, 0, 0, 56, 29, 0, 2,
+  0, 0, 0, 0, 30, 0, 7, 37, 0, 0,
+  0, 21, 0, 0, 7, 6, 14, 0, 16, 0,
+  90, 0, 25, 0, 12, 0, 0, 0, 0, 16,
+  0, 145, 3, 0, 12, 0, 0, 27, 50, 0,
+  0, 22, 2, 0, 1, 0, 35, 91, 18, 9,
+  3, 0, 0, 0, 0, 4, 0, 27, 23, 43,
+  0, 0, 0, 30, 0, 60, 0, 29, 0, 69,
+  6, 72, 26, 52, 0, 0, 0, 48, 12, 0,
+  0, 0, 56, 0, 35, 0, 2, 55, 0, 0,
+  72, 0, 0, 20, 53, 0, 83, 22, 17, 0,
+  0, 33, 2, 22, 0, 37, 41, 0, 32, 49,
+  7, 0, 27, 0, 0, 0, 0, 13, 1, 0,
+  15, 38, 0, 0, 2, 68, 27, 0, 0, 7,
+  17, 0, 22, 0, 0, 0, 0, 0, 0, 29,
+  0, 0, 104, 4, 40, 7, 0, 0, 0, 0,
+  54, 0, 3, 0, 0, 0, 0, 0, 0, 45,
+  41, 0, 20, 0, 0, 0, 75, 11, 19, 55,
+  39, 21, 25, 2, 84, 0, 0, 27, 13, 52,
+  3, 2, 0, 52, 0, 0, 56, 63, 0, 0,
+  0, 0, 0, 59, 0, 43, 0, 45, 7, 20,
+  17, 36, 0, 46, 0, 0, 66, 22, 0, 0,
+  25, 0, 0, 76, 20, 0, 0, 2, 0, 0,
+  13, 21, 31, 0, 0, 26, 0, 14, 8, 55,
+  0, 0, 0, 54, 58, 17, 20, 5, 37, 0,
+  12, 14, 8, 14, 4, 15, 7, 17, 1, 41,
+  0, 0, 39, 55, 6, 0, 4, 0, 0, 0,
+  35, 0, 0, 42, 13, 0, 0, 5, 0, 0,
+  43, 15, 52, 0, 18, 3, 121, 0, 68, 0,
+  9, 0, 0, 49, 1, 0, 30, 0, 15, 0,
+  64, 0, 0, 7, 46, 41, 52, 60, 59, 47,
+  14, 4, 85, 0, 0, 29, 21, 32, 22, 9,
+  0, 19, 0, 0, 33, 0, 0, 0, 0, 0,
+  0, 62, 0, 0, 0, 54, 0, 32, 4, 0,
+  0, 16, 7, 12, 54, 37, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0, 0, 0, 49, 0,
+  30, 0, 0, 0, 5, 29, 27, 0, 0, 9,
+  0, 21, 35, 23, 45, 0, 23, 22, 4, 26,
+  21, 30, 26, 0, 0, 24, 0, 19, 0, 0,
+  46, 43, 11, 0, 0, 0, 0, 0, 30, 1,
+  0, 44, 0, 0, 0, 16, 0, 0, 1, 3,
+  6, 0, 0, 0, 95, 0, 52, 0, 20, 0,
+  0, 0, 0, 10, 0, 139, 4, 0, 12, 0,
+  0, 18, 33, 0, 0, 25, 0, 0, 0, 0,
+  30, 95, 19, 11, 3, 0, 0, 0, 0, 0,
+  0, 27, 29, 38, 0, 0, 0, 23, 0, 54,
+  0, 22, 0, 53, 1, 90, 35, 56, 0, 0,
+  0, 51, 6, 0, 10, 0, 55, 0, 49, 0,
+  11, 61, 0, 0, 76, 3, 0, 3, 55, 0,
+  82, 11, 11, 0, 0, 21, 26, 25, 0, 32,
+  34, 0, 41, 44, 0, 0, 22, 0, 0, 7,
+  0, 21, 4, 0, 4, 31, 0, 0, 7, 66,
+  36, 0, 0, 23, 27, 0, 16, 0, 0, 0,
+  0, 0, 0, 35, 0, 0, 100, 2, 34, 1,
+  0, 0, 0, 0, 28, 0, 0, 0, 0, 0,
+  0, 0, 9, 38, 29, 0, 28, 0, 15, 0,
+  49, 21, 13, 59, 25, 11, 12, 5, 68, 0,
+  0, 42, 2, 24, 1, 0, 0, 35, 0, 0,
+  51, 61, 4, 0, 0, 0, 0, 42, 8, 38,
+  0, 45, 9, 26, 16, 31, 0, 20, 23, 0,
+  74, 24, 0, 0, 43, 0, 0, 56, 26, 7,
+  0, 0, 0, 0, 26, 8, 30, 0, 0, 7,
+  0, 8, 2, 45, 9, 0, 0, 52, 52, 14,
+  29, 21, 20, 0, 7, 19, 17, 28, 6, 32,
+  0, 6, 20, 41, 0, 0, 30, 59, 7, 0,
+  1, 0, 0, 0, 35, 0, 0, 25, 13, 0,
+  0, 13, 0, 0, 41, 20, 37, 0, 1, 0,
+  90, 0, 36, 0, 0, 0, 0, 41, 38, 0,
+  0, 0, 0, 0, 61, 6, 0, 16, 12, 19,
+  25, 54, 49, 37, 21, 5, 43, 0, 53, 32,
+  0, 0, 35, 21, 0, 0, 0, 0, 32, 0,
+  3, 0, 0, 0, 0, 35, 0, 0, 0, 27,
+  0, 26, 0, 0, 0, 15, 28, 3, 38, 9,
+  0, 0, 27, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 56, 0, 5, 0, 0, 0, 1, 44,
+  11, 11, 0, 62, 0, 23, 13, 12, 56, 44,
+  1, 24, 0, 29, 27, 31, 52, 10, 0, 0,
+  12, 0, 0, 0, 11, 51, 42, 0, 0, 0,
+  0, 0, 41, 0, 0, 48, 5, 0, 0, 10,
+  0, 0, 7, 0, 0, 0, 0, 0, 47, 0,
+  21, 0, 1, 20, 0, 0, 0, 0, 0, 51,
+  48, 0, 17, 0, 0, 1, 56, 0, 12, 28,
+  33, 20, 5, 18, 77, 0, 0, 29, 0, 42,
+  17, 0, 0, 38, 0, 0, 71, 57, 0, 0,
+  0, 12, 0, 39, 0, 43, 0, 51, 0, 34,
+  20, 45, 0, 31, 15, 0, 71, 13, 0, 6,
+  44, 0, 0, 54, 15, 0, 0, 0, 0, 0,
+  23, 28, 33, 0, 0, 13, 0, 22, 15, 54,
+  0, 0, 0, 29, 69, 6, 16, 0, 25, 0,
+  11, 13, 3, 2, 0, 26, 5, 14, 0, 26,
+  0, 0, 43, 47, 11, 6, 0, 0, 0, 0,
+  43, 0, 0, 46, 1, 0, 0, 11, 0, 0,
+  48, 15, 46, 0, 23, 0, 104, 0, 47, 0,
+  0, 0, 0, 29, 0, 0, 20, 0, 45, 0,
+  38, 0, 0, 2, 26, 28, 73, 29, 52, 53,
+  0, 24, 91, 0, 0, 24, 16, 39, 26, 0,
+  0, 20, 0, 0, 40, 12, 3, 0, 0, 8,
+  0, 47, 0, 9, 0, 58, 0, 33, 12, 19,
+  0, 0, 17, 3, 66, 44, 0, 0, 7, 0,
+  0, 3, 7, 0, 0, 0, 0, 0, 42, 7,
+  32, 0, 0, 0, 0, 10, 51, 0, 4, 0,
+  0, 8, 61, 18, 25, 0, 32, 0, 8, 4,
+  12, 12, 2, 0, 0, 26, 0, 31, 0, 0,
+  56, 29, 0, 2, 0, 0, 0, 0, 30, 0,
+  7, 37, 0, 0, 0, 21, 0, 0, 7, 6,
+  14, 0, 16, 0, 90, 0, 25, 0, 12, 0,
+  0, 65, 0, 0, 34, 0, 36, 0, 61, 12,
+  0, 5, 44, 54, 61, 74, 64, 45, 0, 12,
+  72, 0, 0, 33, 31, 57, 17, 27, 0, 12,
+  0, 0, 29, 8, 17, 0, 0, 37, 0, 58,
+  0, 3, 0, 54, 0, 29, 24, 4, 0, 0,
+  35, 0, 43, 56, 0, 0, 7, 0, 0, 32,
+  0, 0, 0, 0, 0, 0, 70, 9, 41, 0,
+  0, 0, 0, 18, 51, 0, 0, 21, 0, 27,
+  40, 52, 13, 20, 40, 15, 0, 9, 25, 57,
+  3, 0, 0, 59, 0, 27, 0, 5, 69, 44,
+  0, 0, 0, 0, 2, 0, 12, 20, 36, 60,
+  0, 0, 0, 21, 0, 0, 0, 18, 24, 0,
+  0, 1, 134, 0, 38, 0, 44, 0, 0, 0,
+  0, 0, 0, 45, 41, 0, 20, 0, 0, 0,
+  75, 11, 19, 55, 39, 21, 25, 2, 84, 0,
+  0, 27, 13, 52, 3, 2, 0, 52, 0, 0,
+  56, 63, 0, 0, 0, 0, 0, 59, 0, 43,
+  0, 45, 7, 20, 17, 36, 0, 46, 0, 0,
+  66, 22, 0, 0, 25, 0, 0, 76, 20, 0,
+  0, 2, 0, 0, 13, 21, 31, 0, 0, 26,
+  0, 14, 8, 55, 0, 0, 0, 54, 58, 17,
+  20, 5, 37, 0, 12, 14, 8, 14, 4, 15,
+  7, 17, 1, 41, 0, 0, 39, 55, 6, 0,
+  4, 0, 0, 0, 35, 0, 0, 42, 13, 0,
+  0, 5, 0, 0, 43, 15, 52, 0, 18, 3,
+  121, 0, 68, 0, 9, 0, 0, 49, 1, 0,
+  30, 0, 15, 0, 64, 0, 0, 7, 46, 41,
+  52, 60, 59, 47, 14, 4, 85, 0, 0, 29,
+  21, 32, 22, 9, 0, 19, 0, 0, 33, 0,
+  0, 0, 0, 0, 0, 62, 0, 0, 0, 54,
+  0, 32, 4, 0, 0, 16, 7, 12, 54, 37,
+  0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 49, 0, 30, 0, 0, 0, 5, 29,
+  27, 0, 0, 9, 0, 21, 35, 23, 45, 0,
+  23, 22, 4, 26, 21, 30, 26, 0, 0, 24,
+  0, 19, 0, 0, 46, 43, 11, 0, 0, 0,
+  0, 0, 30, 1, 0, 44, 0, 0, 0, 16,
+  0, 0, 1, 3, 6, 0, 0, 0, 95, 0,
+  52, 0, 20, 0, 0, 44, 27, 0, 33, 0,
+  0, 0, 76, 0, 0, 1, 67, 69, 11, 51,
+  63, 32, 6, 0, 66, 0, 0, 38, 0, 0,
+  28, 40, 0, 0, 0, 0, 7, 0, 0, 0,
+  0, 27, 0, 47, 0, 0, 0, 20, 0, 38,
+  0, 0, 0, 16, 0, 34, 21, 7, 0, 0,
+  0, 8, 0, 0, 0, 0, 0, 0, 0, 0,
+  98, 0, 25, 5, 0, 0, 0, 78, 9, 0,
+  0, 35, 0, 0, 12, 5, 38, 41, 20, 53,
+  0, 44, 32, 14, 27, 37, 0, 13, 0, 0,
+  0, 0, 28, 63, 38, 0, 0, 0, 0, 0,
+  3, 36, 0, 61, 0, 0, 0, 5, 3, 0,
+  4, 0, 0, 0, 0, 0, 77, 0, 26, 0,
+  18, 21, 0, 0, 0, 0, 9, 38, 29, 0,
+  28, 0, 15, 0, 49, 21, 13, 59, 25, 11,
+  12, 5, 68, 0, 0, 42, 2, 24, 1, 0,
+  0, 35, 0, 0, 51, 61, 4, 0, 0, 0,
+  0, 42, 8, 38, 0, 45, 9, 26, 16, 31,
+  0, 20, 23, 0, 74, 24, 0, 0, 43, 0,
+  0, 56, 26, 7, 0, 0, 0, 0, 26, 8,
+  30, 0, 0, 7, 0, 8, 2, 45, 9, 0,
+  0, 52, 52, 14, 29, 21, 20, 0, 7, 19,
+  17, 28, 6, 32, 0, 6, 20, 41, 0, 0,
+  30, 59, 7, 0, 1, 0, 0, 0, 35, 0,
+  0, 25, 13, 0, 0, 13, 0, 0, 41, 20,
+  37, 0, 1, 0, 90, 0, 36, 0, 0, 0,
+  0, 41, 38, 0, 0, 0, 0, 0, 61, 6,
+  0, 16, 12, 19, 25, 54, 49, 37, 21, 5,
+  43, 0, 53, 32, 0, 0, 35, 21, 0, 0,
+  0, 0, 32, 0, 3, 0, 0, 0, 0, 35,
+  0, 0, 0, 27, 0, 26, 0, 0, 0, 15,
+  28, 3, 38, 9, 0, 0, 27, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 56, 0, 5, 0,
+  0, 0, 1, 44, 11, 11, 0, 62, 0, 23,
+  13, 12, 56, 44, 1, 24, 0, 29, 27, 31,
+  52, 10, 0, 0, 12, 0, 0, 0, 11, 51,
+  42, 0, 0, 0, 0, 0, 41, 0, 0, 48,
+  5, 0, 0, 10, 0, 0, 7, 0, 0, 0,
+  0, 0, 47, 0, 21, 0, 1, 20, 52, 0,
+  43, 0, 22, 0, 0, 0, 29, 0, 0, 0,
+  38, 88, 0, 0, 38, 0, 13, 0, 33, 104,
+  68, 26, 0, 0, 8, 50, 0, 0, 0, 10,
+  0, 4, 0, 0, 0, 20, 0, 11, 1, 0,
+  0, 0, 0, 16, 0, 0, 0, 7, 0, 77,
+  0, 0, 52, 0, 26, 23, 6, 0, 25, 0,
+  0, 6, 24, 0, 92, 16, 18, 73, 0, 0,
+  0, 73, 0, 0, 0, 50, 0, 0, 0, 0,
+  11, 59, 10, 49, 0, 55, 10, 0, 0, 37,
+  0, 0, 5, 0, 13, 0, 23, 61, 29, 7,
+  1, 0, 19, 2, 0, 26, 0, 53, 0, 7,
+  0, 0, 0, 23, 69, 0, 1, 0, 0, 31,
+  0, 0, 4, 0, 0, 61, 0, 29, 0, 0,
+  20, 0, 45, 0, 38, 0, 0, 2, 26, 28,
+  73, 29, 52, 53, 0, 24, 91, 0, 0, 24,
+  16, 39, 26, 0, 0, 20, 0, 0, 40, 12,
+  3, 0, 0, 8, 0, 47, 0, 9, 0, 58,
+  0, 33, 12, 19, 0, 0, 17, 3, 66, 44,
+  0, 0, 7, 0, 0, 3, 7, 0, 0, 0,
+  0, 0, 42, 7, 32, 0, 0, 0, 0, 10,
+  51, 0, 4, 0, 0, 8, 61, 18, 25, 0,
+  32, 0, 8, 4, 12, 12, 2, 0, 0, 26,
+  0, 31, 0, 0, 56, 29, 0, 2, 0, 0,
+  0, 0, 30, 0, 7, 37, 0, 0, 0, 21,
+  0, 0, 7, 6, 14, 0, 16, 0, 90, 0,
+  25, 0, 12, 0, 0, 65, 0, 0, 34, 0,
+  36, 0, 61, 12, 0, 5, 44, 54, 61, 74,
+  64, 45, 0, 12, 72, 0, 0, 33, 31, 57,
+  17, 27, 0, 12, 0, 0, 29, 8, 17, 0,
+  0, 37, 0, 58, 0, 3, 0, 54, 0, 29,
+  24, 4, 0, 0, 35, 0, 43, 56, 0, 0,
+  7, 0, 0, 32, 0, 0, 0, 0, 0, 0,
+  70, 9, 41, 0, 0, 0, 0, 18, 51, 0,
+  0, 21, 0, 27, 40, 52, 13, 20, 40, 15,
+  0, 9, 25, 57, 3, 0, 0, 59, 0, 27,
+  0, 5, 69, 44, 0, 0, 0, 0, 2, 0,
+  12, 20, 36, 60, 0, 0, 0, 21, 0, 0,
+  0, 18, 24, 0, 0, 1, 134, 0, 38, 0,
+  44, 0, 0, 26, 42, 0, 40, 0, 0, 0,
+  68, 7, 0, 5, 43, 69, 21, 36, 59, 16,
+  3, 0, 30, 7, 16, 33, 0, 0, 32, 69,
+  0, 5, 0, 0, 0, 0, 0, 0, 0, 55,
+  0, 45, 0, 4, 0, 0, 0, 8, 12, 0,
+  0, 16, 23, 16, 0, 8, 0, 0, 24, 20,
+  0, 0, 0, 0, 0, 0, 0, 0, 70, 10,
+  16, 0, 0, 0, 0, 27, 24, 0, 0, 57,
+  0, 13, 0, 13, 15, 76, 12, 31, 0, 45,
+  9, 26, 24, 0, 0, 11, 0, 0, 0, 0,
+  52, 56, 16, 0, 0, 0, 1, 0, 7, 24,
+  39, 91, 4, 0, 0, 0, 0, 0, 11, 0,
+  10, 0, 0, 35, 51, 0, 0, 0, 24, 66,
+  0, 49, 1, 0, 30, 0, 15, 0, 64, 0,
+  0, 7, 46, 41, 52, 60, 59, 47, 14, 4,
+  85, 0, 0, 29, 21, 32, 22, 9, 0, 19,
+  0, 0, 33, 0, 0, 0, 0, 0, 0, 62,
+  0, 0, 0, 54, 0, 32, 4, 0, 0, 16,
+  7, 12, 54, 37, 0, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0, 49, 0, 30, 0,
+  0, 0, 5, 29, 27, 0, 0, 9, 0, 21,
+  35, 23, 45, 0, 23, 22, 4, 26, 21, 30,
+  26, 0, 0, 24, 0, 19, 0, 0, 46, 43,
+  11, 0, 0, 0, 0, 0, 30, 1, 0, 44,
+  0, 0, 0, 16, 0, 0, 1, 3, 6, 0,
+  0, 0, 95, 0, 52, 0, 20, 0, 0, 44,
+  27, 0, 33, 0, 0, 0, 76, 0, 0, 1,
+  67, 69, 11, 51, 63, 32, 6, 0, 66, 0,
+  0, 38, 0, 0, 28, 40, 0, 0, 0, 0,
+  7, 0, 0, 0, 0, 27, 0, 47, 0, 0,
+  0, 20, 0, 38, 0, 0, 0, 16, 0, 34,
+  21, 7, 0, 0, 0, 8, 0, 0, 0, 0,
+  0, 0, 0, 0, 98, 0, 25, 5, 0, 0,
+  0, 78, 9, 0, 0, 35, 0, 0, 12, 5,
+  38, 41, 20, 53, 0, 44, 32, 14, 27, 37,
+  0, 13, 0, 0, 0, 0, 28, 63, 38, 0,
+  0, 0, 0, 0, 3, 36, 0, 61, 0, 0,
+  0, 5, 3, 0, 4, 0, 0, 0, 0, 0,
+  77, 0, 26, 0, 18, 21, 29, 0, 57, 0,
+  12, 30, 0, 0, 52, 0, 0, 2, 43, 101,
+  14, 0, 40, 0, 0, 0, 32, 66, 0, 35,
+  0, 0, 0, 29, 0, 8, 0, 0, 0, 11,
+  0, 0, 0, 50, 0, 48, 0, 31, 0, 0,
+  0, 0, 0, 0, 6, 9, 0, 67, 0, 0,
+  11, 0, 13, 40, 0, 0, 5, 7, 0, 44,
+  0, 15, 58, 0, 30, 45, 0, 14, 0, 32,
+  0, 0, 0, 10, 0, 27, 0, 3, 29, 32,
+  45, 49, 0, 64, 21, 0, 0, 14, 0, 0,
+  0, 0, 0, 0, 30, 78, 0, 0, 0, 0,
+  0, 18, 0, 23, 14, 57, 17, 0, 0, 0,
+  29, 0, 59, 1, 9, 2, 0, 17, 0, 0,
+  0, 0, 0, 41, 0, 41, 38, 0, 0, 0,
+  0, 0, 61, 6, 0, 16, 12, 19, 25, 54,
+  49, 37, 21, 5, 43, 0, 53, 32, 0, 0,
+  35, 21, 0, 0, 0, 0, 32, 0, 3, 0,
+  0, 0, 0, 35, 0, 0, 0, 27, 0, 26,
+  0, 0, 0, 15, 28, 3, 38, 9, 0, 0,
+  27, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  56, 0, 5, 0, 0, 0, 1, 44, 11, 11,
+  0, 62, 0, 23, 13, 12, 56, 44, 1, 24,
+  0, 29, 27, 31, 52, 10, 0, 0, 12, 0,
+  0, 0, 11, 51, 42, 0, 0, 0, 0, 0,
+  41, 0, 0, 48, 5, 0, 0, 10, 0, 0,
+  7, 0, 0, 0, 0, 0, 47, 0, 21, 0,
+  1, 20, 52, 0, 43, 0, 22, 0, 0, 0,
+  29, 0, 0, 0, 38, 88, 0, 0, 38, 0,
+  13, 0, 33, 104, 68, 26, 0, 0, 8, 50,
+  0, 0, 0, 10, 0, 4, 0, 0, 0, 20,
+  0, 11, 1, 0, 0, 0, 0, 16, 0, 0,
+  0, 7, 0, 77, 0, 0, 52, 0, 26, 23,
+  6, 0, 25, 0, 0, 6, 24, 0, 92, 16,
+  18, 73, 0, 0, 0, 73, 0, 0, 0, 50,
+  0, 0, 0, 0, 11, 59, 10, 49, 0, 55,
+  10, 0, 0, 37, 0, 0, 5, 0, 13, 0,
+  23, 61, 29, 7, 1, 0, 19, 2, 0, 26,
+  0, 53, 0, 7, 0, 0, 0, 23, 69, 0,
+  1, 0, 0, 31, 0, 0, 4, 0, 0, 61,
+  44, 0, 0, 0, 25, 73, 0, 0, 7, 0,
+  0, 0, 26, 81, 0, 0, 48, 0, 0, 0,
+  40, 70, 0, 48, 0, 0, 0, 16, 0, 0,
+  0, 0, 0, 39, 0, 0, 0, 36, 0, 27,
+  0, 6, 0, 0, 20, 1, 0, 24, 22, 0,
+  0, 39, 0, 0, 0, 0, 10, 25, 0, 0,
+  31, 12, 0, 4, 0, 0, 87, 23, 22, 30,
+  0, 6, 0, 43, 7, 0, 0, 5, 0, 16,
+  0, 0, 0, 7, 9, 33, 0, 49, 1, 0,
+  0, 56, 0, 0, 0, 0, 0, 0, 17, 64,
+  6, 22, 16, 0, 10, 13, 0, 13, 8, 65,
+  0, 0, 0, 0, 0, 16, 82, 0, 8, 0,
+  12, 7, 0, 0, 0, 7, 4, 20, 0, 65,
+  0, 0, 34, 0, 36, 0, 61, 12, 0, 5,
+  44, 54, 61, 74, 64, 45, 0, 12, 72, 0,
+  0, 33, 31, 57, 17, 27, 0, 12, 0, 0,
+  29, 8, 17, 0, 0, 37, 0, 58, 0, 3,
+  0, 54, 0, 29, 24, 4, 0, 0, 35, 0,
+  43, 56, 0, 0, 7, 0, 0, 32, 0, 0,
+  0, 0, 0, 0, 70, 9, 41, 0, 0, 0,
+  0, 18, 51, 0, 0, 21, 0, 27, 40, 52,
+  13, 20, 40, 15, 0, 9, 25, 57, 3, 0,
+  0, 59, 0, 27, 0, 5, 69, 44, 0, 0,
+  0, 0, 2, 0, 12, 20, 36, 60, 0, 0,
+  0, 21, 0, 0, 0, 18, 24, 0, 0, 1,
+  134, 0, 38, 0, 44, 0, 0, 26, 42, 0,
+  40, 0, 0, 0, 68, 7, 0, 5, 43, 69,
+  21, 36, 59, 16, 3, 0, 30, 7, 16, 33,
+  0, 0, 32, 69, 0, 5, 0, 0, 0, 0,
+  0, 0, 0, 55, 0, 45, 0, 4, 0, 0,
+  0, 8, 12, 0, 0, 16, 23, 16, 0, 8,
+  0, 0, 24, 20, 0, 0, 0, 0, 0, 0,
+  0, 0, 70, 10, 16, 0, 0, 0, 0, 27,
+  24, 0, 0, 57, 0, 13, 0, 13, 15, 76,
+  12, 31, 0, 45, 9, 26, 24, 0, 0, 11,
+  0, 0, 0, 0, 52, 56, 16, 0, 0, 0,
+  1, 0, 7, 24, 39, 91, 4, 0, 0, 0,
+  0, 0, 11, 0, 10, 0, 0, 35, 51, 0,
+  0, 0, 24, 66, 70, 0, 17, 0, 20, 30,
+  0, 0, 12, 0, 0, 0, 2, 79, 18, 0,
+  26, 23, 6, 5, 29, 52, 17, 15, 0, 0,
+  8, 29, 0, 0, 0, 9, 0, 47, 0, 0,
+  7, 43, 0, 12, 0, 10, 0, 0, 5, 0,
+  16, 5, 10, 0, 24, 4, 0, 0, 15, 0,
+  23, 37, 5, 0, 30, 16, 31, 0, 0, 12,
+  69, 32, 32, 66, 0, 18, 10, 0, 25, 0,
+  0, 55, 11, 6, 0, 12, 0, 37, 48, 12,
+  31, 65, 0, 0, 0, 0, 0, 0, 29, 0,
+  0, 17, 57, 30, 0, 27, 0, 0, 0, 60,
+  0, 14, 29, 64, 0, 0, 0, 1, 7, 52,
+  58, 0, 0, 0, 0, 32, 0, 0, 0, 19,
+  23, 49, 0, 44, 27, 0, 33, 0, 0, 0,
+  76, 0, 0, 1, 67, 69, 11, 51, 63, 32,
+  6, 0, 66, 0, 0, 38, 0, 0, 28, 40,
+  0, 0, 0, 0, 7, 0, 0, 0, 0, 27,
+  0, 47, 0, 0, 0, 20, 0, 38, 0, 0,
+  0, 16, 0, 34, 21, 7, 0, 0, 0, 8,
+  0, 0, 0, 0, 0, 0, 0, 0, 98, 0,
+  25, 5, 0, 0, 0, 78, 9, 0, 0, 35,
+  0, 0, 12, 5, 38, 41, 20, 53, 0, 44,
+  32, 14, 27, 37, 0, 13, 0, 0, 0, 0,
+  28, 63, 38, 0, 0, 0, 0, 0, 3, 36,
+  0, 61, 0, 0, 0, 5, 3, 0, 4, 0,
+  0, 0, 0, 0, 77, 0, 26, 0, 18, 21,
+  29, 0, 57, 0, 12, 30, 0, 0, 52, 0,
+  0, 2, 43, 101, 14, 0, 40, 0, 0, 0,
+  32, 66, 0, 35, 0, 0, 0, 29, 0, 8,
+  0, 0, 0, 11, 0, 0, 0, 50, 0, 48,
+  0, 31, 0, 0, 0, 0, 0, 0, 6, 9,
+  0, 67, 0, 0, 11, 0, 13, 40, 0, 0,
+  5, 7, 0, 44, 0, 15, 58, 0, 30, 45,
+  0, 14, 0, 32, 0, 0, 0, 10, 0, 27,
+  0, 3, 29, 32, 45, 49, 0, 64, 21, 0,
+  0, 14, 0, 0, 0, 0, 0, 0, 30, 78,
+  0, 0, 0, 0, 0, 18, 0, 23, 14, 57,
+  17, 0, 0, 0, 29, 0, 59, 1, 9, 2,
+  0, 17, 0, 0, 0, 0, 0, 41, 0, 0,
+  0, 0, 31, 51, 0, 0, 37, 2, 0, 0,
+  4, 70, 43, 0, 24, 35, 0, 14, 56, 0,
+  0, 39, 0, 0, 9, 13, 0, 36, 0, 0,
+  0, 14, 0, 0, 0, 19, 0, 41, 0, 0,
+  0, 5, 3, 0, 4, 0, 0, 0, 23, 13,
+  20, 0, 0, 0, 18, 34, 0, 0, 4, 17,
+  0, 0, 0, 0, 21, 0, 0, 0, 0, 23,
+  10, 1, 39, 9, 0, 0, 1, 25, 3, 20,
+  0, 8, 17, 5, 38, 41, 32, 19, 10, 0,
+  6, 0, 0, 0, 0, 5, 45, 39, 4, 0,
+  0, 0, 0, 31, 0, 9, 12, 73, 0, 0,
+  0, 0, 2, 0, 65, 11, 0, 5, 37, 0,
+  20, 0, 0, 11, 0, 8, 52, 0, 43, 0,
+  22, 0, 0, 0, 29, 0, 0, 0, 38, 88,
+  0, 0, 38, 0, 13, 0, 33, 104, 68, 26,
+  0, 0, 8, 50, 0, 0, 0, 10, 0, 4,
+  0, 0, 0, 20, 0, 11, 1, 0, 0, 0,
+  0, 16, 0, 0, 0, 7, 0, 77, 0, 0,
+  52, 0, 26, 23, 6, 0, 25, 0, 0, 6,
+  24, 0, 92, 16, 18, 73, 0, 0, 0, 73,
+  0, 0, 0, 50, 0, 0, 0, 0, 11, 59,
+  10, 49, 0, 55, 10, 0, 0, 37, 0, 0,
+  5, 0, 13, 0, 23, 61, 29, 7, 1, 0,
+  19, 2, 0, 26, 0, 53, 0, 7, 0, 0,
+  0, 23, 69, 0, 1, 0, 0, 31, 0, 0,
+  4, 0, 0, 61, 44, 0, 0, 0, 25, 73,
+  0, 0, 7, 0, 0, 0, 26, 81, 0, 0,
+  48, 0, 0, 0, 40, 70, 0, 48, 0, 0,
+  0, 16, 0, 0, 0, 0, 0, 39, 0, 0,
+  0, 36, 0, 27, 0, 6, 0, 0, 20, 1,
+  0, 24, 22, 0, 0, 39, 0, 0, 0, 0,
+  10, 25, 0, 0, 31, 12, 0, 4, 0, 0,
+  87, 23, 22, 30, 0, 6, 0, 43, 7, 0,
+  0, 5, 0, 16, 0, 0, 0, 7, 9, 33,
+  0, 49, 1, 0, 0, 56, 0, 0, 0, 0,
+  0, 0, 17, 64, 6, 22, 16, 0, 10, 13,
+  0, 13, 8, 65, 0, 0, 0, 0, 0, 16,
+  82, 0, 8, 0, 12, 7, 0, 0, 0, 7,
+  4, 20, 0, 17, 0, 0, 21, 28, 30, 14,
+  58, 16, 0, 5, 32, 30, 51, 35, 42, 53,
+  0, 21, 81, 0, 0, 49, 7, 50, 21, 0,
+  0, 19, 0, 0, 2, 16, 18, 0, 0, 7,
+  0, 43, 0, 40, 0, 33, 27, 19, 0, 12,
+  0, 0, 23, 0, 84, 2, 0, 0, 0, 0,
+  0, 29, 0, 0, 0, 0, 0, 0, 33, 0,
+  0, 0, 0, 25, 18, 30, 44, 27, 0, 0,
+  0, 44, 47, 23, 14, 0, 26, 7, 56, 14,
+  51, 35, 8, 27, 0, 39, 0, 19, 0, 4,
+  43, 43, 0, 0, 0, 0, 0, 0, 8, 13,
+  9, 61, 0, 0, 0, 0, 12, 0, 28, 21,
+  21, 0, 50, 0, 111, 0, 14, 14, 3, 0,
+  0, 26, 42, 0, 40, 0, 0, 0, 68, 7,
+  0, 5, 43, 69, 21, 36, 59, 16, 3, 0,
+  30, 7, 16, 33, 0, 0, 32, 69, 0, 5,
+  0, 0, 0, 0, 0, 0, 0, 55, 0, 45,
+  0, 4, 0, 0, 0, 8, 12, 0, 0, 16,
+  23, 16, 0, 8, 0, 0, 24, 20, 0, 0,
+  0, 0, 0, 0, 0, 0, 70, 10, 16, 0,
+  0, 0, 0, 27, 24, 0, 0, 57, 0, 13,
+  0, 13, 15, 76, 12, 31, 0, 45, 9, 26,
+  24, 0, 0, 11, 0, 0, 0, 0, 52, 56,
+  16, 0, 0, 0, 1, 0, 7, 24, 39, 91,
+  4, 0, 0, 0, 0, 0, 11, 0, 10, 0,
+  0, 35, 51, 0, 0, 0, 24, 66, 70, 0,
+  17, 0, 20, 30, 0, 0, 12, 0, 0, 0,
+  2, 79, 18, 0, 26, 23, 6, 5, 29, 52,
+  17, 15, 0, 0, 8, 29, 0, 0, 0, 9,
+  0, 47, 0, 0, 7, 43, 0, 12, 0, 10,
+  0, 0, 5, 0, 16, 5, 10, 0, 24, 4,
+  0, 0, 15, 0, 23, 37, 5, 0, 30, 16,
+  31, 0, 0, 12, 69, 32, 32, 66, 0, 18,
+  10, 0, 25, 0, 0, 55, 11, 6, 0, 12,
+  0, 37, 48, 12, 31, 65, 0, 0, 0, 0,
+  0, 0, 29, 0, 0, 17, 57, 30, 0, 27,
+  0, 0, 0, 60, 0, 14, 29, 64, 0, 0,
+  0, 1, 7, 52, 58, 0, 0, 0, 0, 32,
+  0, 0, 0, 19, 23, 49, 22, 3, 0, 0,
+  24, 14, 0, 0, 31, 13, 0, 23, 0, 61,
+  30, 0, 16, 46, 7, 38, 53, 0, 0, 0,
+  7, 20, 37, 0, 0, 0, 0, 0, 0, 35,
+  0, 0, 9, 0, 0, 0, 0, 3, 0, 3,
+  12, 0, 13, 5, 0, 0, 57, 0, 3, 0,
+  0, 0, 27, 17, 0, 0, 5, 8, 37, 0,
+  0, 0, 19, 60, 0, 39, 0, 33, 30, 0,
+  37, 12, 0, 30, 0, 10, 5, 30, 0, 0,
+  41, 0, 71, 36, 0, 13, 0, 0, 4, 0,
+  18, 0, 0, 16, 44, 2, 0, 26, 0, 0,
+  0, 38, 5, 6, 19, 51, 0, 0, 0, 14,
+  43, 20, 37, 0, 0, 0, 39, 13, 0, 0,
+  0, 39, 17, 0, 29, 0, 57, 0, 12, 30,
+  0, 0, 52, 0, 0, 2, 43, 101, 14, 0,
+  40, 0, 0, 0, 32, 66, 0, 35, 0, 0,
+  0, 29, 0, 8, 0, 0, 0, 11, 0, 0,
+  0, 50, 0, 48, 0, 31, 0, 0, 0, 0,
+  0, 0, 6, 9, 0, 67, 0, 0, 11, 0,
+  13, 40, 0, 0, 5, 7, 0, 44, 0, 15,
+  58, 0, 30, 45, 0, 14, 0, 32, 0, 0,
+  0, 10, 0, 27, 0, 3, 29, 32, 45, 49,
+  0, 64, 21, 0, 0, 14, 0, 0, 0, 0,
+  0, 0, 30, 78, 0, 0, 0, 0, 0, 18,
+  0, 23, 14, 57, 17, 0, 0, 0, 29, 0,
+  59, 1, 9, 2, 0, 17, 0, 0, 0, 0,
+  0, 41, 0, 0, 0, 0, 31, 51, 0, 0,
+  37, 2, 0, 0, 4, 70, 43, 0, 24, 35,
+  0, 14, 56, 0, 0, 39, 0, 0, 9, 13,
+  0, 36, 0, 0, 0, 14, 0, 0, 0, 19,
+  0, 41, 0, 0, 0, 5, 3, 0, 4, 0,
+  0, 0, 23, 13, 20, 0, 0, 0, 18, 34,
+  0, 0, 4, 17, 0, 0, 0, 0, 21, 0,
+  0, 0, 0, 23, 10, 1, 39, 9, 0, 0,
+  1, 25, 3, 20, 0, 8, 17, 5, 38, 41,
+  32, 19, 10, 0, 6, 0, 0, 0, 0, 5,
+  45, 39, 4, 0, 0, 0, 0, 31, 0, 9,
+  12, 73, 0, 0, 0, 0, 2, 0, 65, 11,
+  0, 5, 37, 0, 20, 0, 0, 11, 0, 8,
+  0, 32, 0, 0, 31, 0, 19, 0, 50, 0,
+  0, 16, 7, 64, 58, 24, 16, 46, 0, 28,
+  76, 0, 0, 47, 16, 40, 25, 0, 0, 27,
+  0, 0, 0, 37, 5, 0, 0, 0, 0, 29,
+  0, 1, 0, 41, 21, 3, 4, 6, 0, 0,
+  60, 0, 56, 11, 0, 0, 8, 6, 0, 26,
+  13, 0, 0, 0, 0, 0, 17, 6, 0, 0,
+  0, 25, 0, 0, 41, 13, 0, 0, 0, 30,
+  48, 39, 12, 0, 31, 0, 58, 23, 37, 56,
+  3, 0, 8, 19, 0, 16, 0, 10, 57, 33,
+  0, 0, 0, 0, 0, 0, 23, 0, 31, 59,
+  0, 0, 0, 1, 24, 0, 21, 0, 8, 0,
+  47, 0, 77, 0, 1, 23, 9, 0, 44, 0,
+  0, 0, 25, 73, 0, 0, 7, 0, 0, 0,
+  26, 81, 0, 0, 48, 0, 0, 0, 40, 70,
+  0, 48, 0, 0, 0, 16, 0, 0, 0, 0,
+  0, 39, 0, 0, 0, 36, 0, 27, 0, 6,
+  0, 0, 20, 1, 0, 24, 22, 0, 0, 39,
+  0, 0, 0, 0, 10, 25, 0, 0, 31, 12,
+  0, 4, 0, 0, 87, 23, 22, 30, 0, 6,
+  0, 43, 7, 0, 0, 5, 0, 16, 0, 0,
+  0, 7, 9, 33, 0, 49, 1, 0, 0, 56,
+  0, 0, 0, 0, 0, 0, 17, 64, 6, 22,
+  16, 0, 10, 13, 0, 13, 8, 65, 0, 0,
+  0, 0, 0, 16, 82, 0, 8, 0, 12, 7,
+  0, 0, 0, 7, 4, 20, 0, 17, 0, 0,
+  21, 28, 30, 14, 58, 16, 0, 5, 32, 30,
+  51, 35, 42, 53, 0, 21, 81, 0, 0, 49,
+  7, 50, 21, 0, 0, 19, 0, 0, 2, 16,
+  18, 0, 0, 7, 0, 43, 0, 40, 0, 33,
+  27, 19, 0, 12, 0, 0, 23, 0, 84, 2,
+  0, 0, 0, 0, 0, 29, 0, 0, 0, 0,
+  0, 0, 33, 0, 0, 0, 0, 25, 18, 30,
+  44, 27, 0, 0, 0, 44, 47, 23, 14, 0,
+  26, 7, 56, 14, 51, 35, 8, 27, 0, 39,
+  0, 19, 0, 4, 43, 43, 0, 0, 0, 0,
+  0, 0, 8, 13, 9, 61, 0, 0, 0, 0,
+  12, 0, 28, 21, 21, 0, 50, 0, 111, 0,
+  14, 14, 3, 0, 0, 47, 23, 0, 8, 0,
+  33, 0, 55, 0, 0, 17, 28, 56, 45, 66,
+  49, 49, 0, 15, 78, 0, 0, 46, 13, 29,
+  27, 0, 0, 0, 14, 0, 11, 19, 4, 0,
+  0, 0, 0, 33, 12, 13, 0, 55, 6, 0,
+  0, 0, 0, 0, 63, 12, 64, 29, 0, 0,
+  0, 0, 0, 23, 0, 0, 0, 0, 0, 0,
+  42, 0, 0, 0, 0, 0, 0, 41, 36, 0,
+  0, 29, 0, 27, 65, 51, 36, 6, 50, 11,
+  55, 0, 58, 33, 0, 14, 0, 30, 0, 20,
+  0, 12, 43, 51, 0, 0, 0, 0, 0, 0,
+  5, 6, 14, 33, 30, 0, 0, 0, 41, 0,
+  0, 0, 5, 0, 0, 0, 81, 0, 6, 22,
+  17, 0, 70, 0, 17, 0, 20, 30, 0, 0,
+  12, 0, 0, 0, 2, 79, 18, 0, 26, 23,
+  6, 5, 29, 52, 17, 15, 0, 0, 8, 29,
+  0, 0, 0, 9, 0, 47, 0, 0, 7, 43,
+  0, 12, 0, 10, 0, 0, 5, 0, 16, 5,
+  10, 0, 24, 4, 0, 0, 15, 0, 23, 37,
+  5, 0, 30, 16, 31, 0, 0, 12, 69, 32,
+  32, 66, 0, 18, 10, 0, 25, 0, 0, 55,
+  11, 6, 0, 12, 0, 37, 48, 12, 31, 65,
+  0, 0, 0, 0, 0, 0, 29, 0, 0, 17,
+  57, 30, 0, 27, 0, 0, 0, 60, 0, 14,
+  29, 64, 0, 0, 0, 1, 7, 52, 58, 0,
+  0, 0, 0, 32, 0, 0, 0, 19, 23, 49,
+  22, 3, 0, 0, 24, 14, 0, 0, 31, 13,
+  0, 23, 0, 61, 30, 0, 16, 46, 7, 38,
+  53, 0, 0, 0, 7, 20, 37, 0, 0, 0,
+  0, 0, 0, 35, 0, 0, 9, 0, 0, 0,
+  0, 3, 0, 3, 12, 0, 13, 5, 0, 0,
+  57, 0, 3, 0, 0, 0, 27, 17, 0, 0,
+  5, 8, 37, 0, 0, 0, 19, 60, 0, 39,
+  0, 33, 30, 0, 37, 12, 0, 30, 0, 10,
+  5, 30, 0, 0, 41, 0, 71, 36, 0, 13,
+  0, 0, 4, 0, 18, 0, 0, 16, 44, 2,
+  0, 26, 0, 0, 0, 38, 5, 6, 19, 51,
+  0, 0, 0, 14, 43, 20, 37, 0, 0, 0,
+  39, 13, 0, 0, 0, 39, 17, 0, 19, 51,
+  0, 11, 63, 0, 36, 0, 33, 2, 0, 24,
+  2, 46, 28, 0, 6, 25, 11, 52, 60, 0,
+  0, 15, 21, 37, 39, 0, 0, 21, 42, 0,
+  0, 33, 0, 0, 0, 0, 0, 0, 0, 29,
+  0, 51, 23, 0, 7, 28, 0, 0, 51, 0,
+  37, 15, 0, 12, 5, 0, 0, 22, 16, 2,
+  15, 0, 0, 0, 4, 57, 0, 0, 0, 41,
+  5, 0, 60, 0, 19, 1, 4, 1, 52, 31,
+  4, 0, 58, 0, 51, 26, 21, 39, 0, 0,
+  0, 32, 0, 23, 0, 0, 55, 8, 0, 36,
+  1, 0, 0, 0, 14, 29, 63, 36, 0, 0,
+  0, 0, 46, 0, 12, 0, 4, 0, 35, 1,
+  40, 0, 0, 33, 0, 0, 0, 0, 0, 0,
+  31, 51, 0, 0, 37, 2, 0, 0, 4, 70,
+  43, 0, 24, 35, 0, 14, 56, 0, 0, 39,
+  0, 0, 9, 13, 0, 36, 0, 0, 0, 14,
+  0, 0, 0, 19, 0, 41, 0, 0, 0, 5,
+  3, 0, 4, 0, 0, 0, 23, 13, 20, 0,
+  0, 0, 18, 34, 0, 0, 4, 17, 0, 0,
+  0, 0, 21, 0, 0, 0, 0, 23, 10, 1,
+  39, 9, 0, 0, 1, 25, 3, 20, 0, 8,
+  17, 5, 38, 41, 32, 19, 10, 0, 6, 0,
+  0, 0, 0, 5, 45, 39, 4, 0, 0, 0,
+  0, 31, 0, 9, 12, 73, 0, 0, 0, 0,
+  2, 0, 65, 11, 0, 5, 37, 0, 20, 0,
+  0, 11, 0, 8, 0, 32, 0, 0, 31, 0,
+  19, 0, 50, 0, 0, 16, 7, 64, 58, 24,
+  16, 46, 0, 28, 76, 0, 0, 47, 16, 40,
+  25, 0, 0, 27, 0, 0, 0, 37, 5, 0,
+  0, 0, 0, 29, 0, 1, 0, 41, 21, 3,
+  4, 6, 0, 0, 60, 0, 56, 11, 0, 0,
+  8, 6, 0, 26, 13, 0, 0, 0, 0, 0,
+  17, 6, 0, 0, 0, 25, 0, 0, 41, 13,
+  0, 0, 0, 30, 48, 39, 12, 0, 31, 0,
+  58, 23, 37, 56, 3, 0, 8, 19, 0, 16,
+  0, 10, 57, 33, 0, 0, 0, 0, 0, 0,
+  23, 0, 31, 59, 0, 0, 0, 1, 24, 0,
+  21, 0, 8, 0, 47, 0, 77, 0, 1, 23,
+  9, 0, 0, 86, 6, 8, 42, 0, 32, 0,
+  64, 4, 0, 0, 6, 42, 74, 53, 38, 43,
+  0, 27, 68, 0, 0, 42, 0, 47, 25, 9,
+  0, 24, 6, 0, 0, 29, 9, 0, 0, 0,
+  0, 25, 0, 26, 0, 59, 9, 0, 0, 24,
+  0, 0, 45, 0, 88, 34, 0, 0, 0, 0,
+  0, 9, 6, 0, 0, 0, 0, 0, 36, 0,
+  0, 0, 0, 0, 0, 17, 64, 0, 2, 0,
+  1, 0, 91, 28, 8, 0, 51, 13, 35, 13,
+  47, 25, 0, 0, 0, 32, 0, 22, 0, 0,
+  48, 22, 0, 7, 0, 0, 23, 0, 25, 21,
+  43, 64, 10, 0, 0, 0, 29, 0, 0, 0,
+  18, 0, 4, 0, 74, 0, 0, 37, 25, 0,
+  0, 17, 0, 0, 21, 28, 30, 14, 58, 16,
+  0, 5, 32, 30, 51, 35, 42, 53, 0, 21,
+  81, 0, 0, 49, 7, 50, 21, 0, 0, 19,
+  0, 0, 2, 16, 18, 0, 0, 7, 0, 43,
+  0, 40, 0, 33, 27, 19, 0, 12, 0, 0,
+  23, 0, 84, 2, 0, 0, 0, 0, 0, 29,
+  0, 0, 0, 0, 0, 0, 33, 0, 0, 0,
+  0, 25, 18, 30, 44, 27, 0, 0, 0, 44,
+  47, 23, 14, 0, 26, 7, 56, 14, 51, 35,
+  8, 27, 0, 39, 0, 19, 0, 4, 43, 43,
+  0, 0, 0, 0, 0, 0, 8, 13, 9, 61,
+  0, 0, 0, 0, 12, 0, 28, 21, 21, 0,
+  50, 0, 111, 0, 14, 14, 3, 0, 0, 47,
+  23, 0, 8, 0, 33, 0, 55, 0, 0, 17,
+  28, 56, 45, 66, 49, 49, 0, 15, 78, 0,
+  0, 46, 13, 29, 27, 0, 0, 0, 14, 0,
+  11, 19, 4, 0, 0, 0, 0, 33, 12, 13,
+  0, 55, 6, 0, 0, 0, 0, 0, 63, 12,
+  64, 29, 0, 0, 0, 0, 0, 23, 0, 0,
+  0, 0, 0, 0, 42, 0, 0, 0, 0, 0,
+  0, 41, 36, 0, 0, 29, 0, 27, 65, 51,
+  36, 6, 50, 11, 55, 0, 58, 33, 0, 14,
+  0, 30, 0, 20, 0, 12, 43, 51, 0, 0,
+  0, 0, 0, 0, 5, 6, 14, 33, 30, 0,
+  0, 0, 41, 0, 0, 0, 5, 0, 0, 0,
+  81, 0, 6, 22, 17, 0, 0, 43, 70, 0,
+  11, 0, 9, 0, 57, 6, 0, 0, 0, 60,
+  23, 63, 30, 38, 0, 12, 39, 0, 33, 35,
+  0, 0, 9, 14, 0, 0, 27, 0, 0, 0,
+  0, 0, 0, 17, 0, 12, 27, 0, 0, 40,
+  0, 0, 0, 0, 0, 0, 48, 52, 41, 12,
+  0, 0, 19, 12, 0, 0, 0, 0, 0, 0,
+  24, 0, 45, 0, 11, 4, 0, 0, 0, 28,
+  32, 0, 0, 18, 0, 0, 58, 19, 0, 21,
+  59, 13, 23, 9, 64, 10, 0, 32, 0, 0,
+  0, 0, 0, 0, 40, 51, 0, 0, 0, 0,
+  36, 0, 0, 22, 4, 24, 40, 0, 0, 0,
+  86, 0, 2, 0, 26, 0, 0, 1, 21, 0,
+  0, 24, 22, 0, 22, 3, 0, 0, 24, 14,
+  0, 0, 31, 13, 0, 23, 0, 61, 30, 0,
+  16, 46, 7, 38, 53, 0, 0, 0, 7, 20,
+  37, 0, 0, 0, 0, 0, 0, 35, 0, 0,
+  9, 0, 0, 0, 0, 3, 0, 3, 12, 0,
+  13, 5, 0, 0, 57, 0, 3, 0, 0, 0,
+  27, 17, 0, 0, 5, 8, 37, 0, 0, 0,
+  19, 60, 0, 39, 0, 33, 30, 0, 37, 12,
+  0, 30, 0, 10, 5, 30, 0, 0, 41, 0,
+  71, 36, 0, 13, 0, 0, 4, 0, 18, 0,
+  0, 16, 44, 2, 0, 26, 0, 0, 0, 38,
+  5, 6, 19, 51, 0, 0, 0, 14, 43, 20,
+  37, 0, 0, 0, 39, 13, 0, 0, 0, 39,
+  17, 0, 19, 51, 0, 11, 63, 0, 36, 0,
+  33, 2, 0, 24, 2, 46, 28, 0, 6, 25,
+  11, 52, 60, 0, 0, 15, 21, 37, 39, 0,
+  0, 21, 42, 0, 0, 33, 0, 0, 0, 0,
+  0, 0, 0, 29, 0, 51, 23, 0, 7, 28,
+  0, 0, 51, 0, 37, 15, 0, 12, 5, 0,
+  0, 22, 16, 2, 15, 0, 0, 0, 4, 57,
+  0, 0, 0, 41, 5, 0, 60, 0, 19, 1,
+  4, 1, 52, 31, 4, 0, 58, 0, 51, 26,
+  21, 39, 0, 0, 0, 32, 0, 23, 0, 0,
+  55, 8, 0, 36, 1, 0, 0, 0, 14, 29,
+  63, 36, 0, 0, 0, 0, 46, 0, 12, 0,
+  4, 0, 35, 1, 40, 0, 0, 33, 0, 0,
+  0, 99, 0, 38, 55, 0, 74, 0, 47, 0,
+  0, 55, 43, 30, 27, 0, 3, 36, 0, 59,
+  80, 0, 0, 26, 36, 49, 32, 1, 0, 12,
+  51, 0, 22, 17, 3, 0, 0, 0, 0, 0,
+  0, 20, 0, 83, 20, 23, 0, 15, 0, 0,
+  26, 0, 67, 45, 0, 11, 23, 0, 0, 37,
+  22, 0, 0, 0, 0, 0, 14, 67, 0, 0,
+  0, 11, 0, 0, 67, 0, 16, 0, 7, 0,
+  80, 54, 0, 0, 42, 0, 37, 1, 24, 67,
+  6, 0, 0, 40, 0, 45, 0, 0, 77, 8,
+  0, 34, 3, 0, 0, 0, 25, 58, 103, 36,
+  0, 0, 0, 0, 32, 0, 0, 0, 0, 0,
+  21, 22, 80, 0, 38, 25, 8, 0, 0, 32,
+  0, 0, 31, 0, 19, 0, 50, 0, 0, 16,
+  7, 64, 58, 24, 16, 46, 0, 28, 76, 0,
+  0, 47, 16, 40, 25, 0, 0, 27, 0, 0,
+  0, 37, 5, 0, 0, 0, 0, 29, 0, 1,
+  0, 41, 21, 3, 4, 6, 0, 0, 60, 0,
+  56, 11, 0, 0, 8, 6, 0, 26, 13, 0,
+  0, 0, 0, 0, 17, 6, 0, 0, 0, 25,
+  0, 0, 41, 13, 0, 0, 0, 30, 48, 39,
+  12, 0, 31, 0, 58, 23, 37, 56, 3, 0,
+  8, 19, 0, 16, 0, 10, 57, 33, 0, 0,
+  0, 0, 0, 0, 23, 0, 31, 59, 0, 0,
+  0, 1, 24, 0, 21, 0, 8, 0, 47, 0,
+  77, 0, 1, 23, 9, 0, 0, 86, 6, 8,
+  42, 0, 32, 0, 64, 4, 0, 0, 6, 42,
+  74, 53, 38, 43, 0, 27, 68, 0, 0, 42,
+  0, 47, 25, 9, 0, 24, 6, 0, 0, 29,
+  9, 0, 0, 0, 0, 25, 0, 26, 0, 59,
+  9, 0, 0, 24, 0, 0, 45, 0, 88, 34,
+  0, 0, 0, 0, 0, 9, 6, 0, 0, 0,
+  0, 0, 36, 0, 0, 0, 0, 0, 0, 17,
+  64, 0, 2, 0, 1, 0, 91, 28, 8, 0,
+  51, 13, 35, 13, 47, 25, 0, 0, 0, 32,
+  0, 22, 0, 0, 48, 22, 0, 7, 0, 0,
+  23, 0, 25, 21, 43, 64, 10, 0, 0, 0,
+  29, 0, 0, 0, 18, 0, 4, 0, 74, 0,
+  0, 37, 25, 0, 0, 96, 8, 3, 33, 0,
+  35, 0, 85, 3, 0, 27, 4, 58, 40, 66,
+  33, 44, 0, 33, 67, 0, 11, 33, 0, 10,
+  35, 17, 0, 0, 0, 0, 16, 0, 0, 0,
+  0, 12, 0, 0, 0, 9, 0, 67, 0, 25,
+  0, 38, 0, 0, 28, 0, 77, 30, 0, 0,
+  25, 0, 0, 0, 0, 0, 0, 0, 2, 0,
+  21, 0, 17, 0, 0, 0, 18, 29, 78, 0,
+  11, 0, 0, 0, 78, 36, 3, 0, 35, 3,
+  44, 7, 36, 20, 0, 27, 0, 26, 0, 8,
+  0, 0, 61, 33, 8, 16, 0, 0, 58, 0,
+  22, 29, 12, 37, 7, 0, 0, 0, 41, 0,
+  0, 0, 20, 0, 0, 0, 52, 0, 0, 31,
+  46, 0, 0, 47, 23, 0, 8, 0, 33, 0,
+  55, 0, 0, 17, 28, 56, 45, 66, 49, 49,
+  0, 15, 78, 0, 0, 46, 13, 29, 27, 0,
+  0, 0, 14, 0, 11, 19, 4, 0, 0, 0,
+  0, 33, 12, 13, 0, 55, 6, 0, 0, 0,
+  0, 0, 63, 12, 64, 29, 0, 0, 0, 0,
+  0, 23, 0, 0, 0, 0, 0, 0, 42, 0,
+  0, 0, 0, 0, 0, 41, 36, 0, 0, 29,
+  0, 27, 65, 51, 36, 6, 50, 11, 55, 0,
+  58, 33, 0, 14, 0, 30, 0, 20, 0, 12,
+  43, 51, 0, 0, 0, 0, 0, 0, 5, 6,
+  14, 33, 30, 0, 0, 0, 41, 0, 0, 0,
+  5, 0, 0, 0, 81, 0, 6, 22, 17, 0,
+  0, 43, 70, 0, 11, 0, 9, 0, 57, 6,
+  0, 0, 0, 60, 23, 63, 30, 38, 0, 12,
+  39, 0, 33, 35, 0, 0, 9, 14, 0, 0,
+  27, 0, 0, 0, 0, 0, 0, 17, 0, 12,
+  27, 0, 0, 40, 0, 0, 0, 0, 0, 0,
+  48, 52, 41, 12, 0, 0, 19, 12, 0, 0,
+  0, 0, 0, 0, 24, 0, 45, 0, 11, 4,
+  0, 0, 0, 28, 32, 0, 0, 18, 0, 0,
+  58, 19, 0, 21, 59, 13, 23, 9, 64, 10,
+  0, 32, 0, 0, 0, 0, 0, 0, 40, 51,
+  0, 0, 0, 0, 36, 0, 0, 22, 4, 24,
+  40, 0, 0, 0, 86, 0, 2, 0, 26, 0,
+  0, 1, 21, 0, 0, 24, 22, 0, 0, 1,
+  54, 0, 0, 0, 0, 0, 42, 0, 0, 7,
+  0, 86, 0, 0, 1, 43, 0, 15, 50, 15,
+  93, 16, 0, 0, 0, 18, 0, 0, 16, 0,
+  0, 0, 0, 0, 0, 25, 0, 0, 34, 33,
+  0, 35, 0, 0, 0, 17, 0, 0, 34, 96,
+  0, 0, 21, 0, 40, 0, 14, 0, 0, 2,
+  21, 0, 100, 23, 1, 3, 2, 71, 0, 0,
+  0, 0, 18, 0, 0, 0, 0, 0, 25, 5,
+  0, 25, 63, 0, 32, 16, 62, 0, 0, 28,
+  0, 0, 0, 0, 0, 0, 67, 44, 0, 0,
+  0, 0, 26, 0, 0, 29, 0, 5, 41, 0,
+  0, 0, 99, 0, 45, 0, 46, 0, 0, 13,
+  0, 0, 0, 6, 19, 0, 19, 51, 0, 11,
+  63, 0, 36, 0, 33, 2, 0, 24, 2, 46,
+  28, 0, 6, 25, 11, 52, 60, 0, 0, 15,
+  21, 37, 39, 0, 0, 21, 42, 0, 0, 33,
+  0, 0, 0, 0, 0, 0, 0, 29, 0, 51,
+  23, 0, 7, 28, 0, 0, 51, 0, 37, 15,
+  0, 12, 5, 0, 0, 22, 16, 2, 15, 0,
+  0, 0, 4, 57, 0, 0, 0, 41, 5, 0,
+  60, 0, 19, 1, 4, 1, 52, 31, 4, 0,
+  58, 0, 51, 26, 21, 39, 0, 0, 0, 32,
+  0, 23, 0, 0, 55, 8, 0, 36, 1, 0,
+  0, 0, 14, 29, 63, 36, 0, 0, 0, 0,
+  46, 0, 12, 0, 4, 0, 35, 1, 40, 0,
+  0, 33, 0, 0, 0, 99, 0, 38, 55, 0,
+  74, 0, 47, 0, 0, 55, 43, 30, 27, 0,
+  3, 36, 0, 59, 80, 0, 0, 26, 36, 49,
+  32, 1, 0, 12, 51, 0, 22, 17, 3, 0,
+  0, 0, 0, 0, 0, 20, 0, 83, 20, 23,
+  0, 15, 0, 0, 26, 0, 67, 45, 0, 11,
+  23, 0, 0, 37, 22, 0, 0, 0, 0, 0,
+  14, 67, 0, 0, 0, 11, 0, 0, 67, 0,
+  16, 0, 7, 0, 80, 54, 0, 0, 42, 0,
+  37, 1, 24, 67, 6, 0, 0, 40, 0, 45,
+  0, 0, 77, 8, 0, 34, 3, 0, 0, 0,
+  25, 58, 103, 36, 0, 0, 0, 0, 32, 0,
+  0, 0, 0, 0, 21, 22, 80, 0, 38, 25,
+  8, 0, 0, 129, 0, 59, 30, 0, 80, 0,
+  63, 0, 2, 62, 41, 13, 24, 8, 0, 36,
+  0, 50, 73, 0, 0, 34, 40, 69, 39, 5,
+  0, 13, 44, 0, 63, 0, 17, 0, 0, 0,
+  0, 0, 0, 30, 0, 55, 31, 26, 0, 15,
+  0, 0, 34, 0, 63, 66, 0, 6, 53, 0,
+  0, 76, 13, 0, 0, 0, 0, 0, 32, 81,
+  0, 0, 0, 20, 0, 0, 48, 49, 0, 0,
+  0, 0, 65, 72, 1, 0, 21, 0, 34, 0,
+  17, 106, 73, 0, 0, 66, 0, 33, 16, 0,
+  73, 22, 0, 27, 0, 0, 0, 0, 17, 70,
+  123, 31, 8, 0, 18, 0, 19, 0, 0, 0,
+  0, 0, 16, 21, 113, 10, 49, 16, 11, 0,
+  0, 86, 6, 8, 42, 0, 32, 0, 64, 4,
+  0, 0, 6, 42, 74, 53, 38, 43, 0, 27,
+  68, 0, 0, 42, 0, 47, 25, 9, 0, 24,
+  6, 0, 0, 29, 9, 0, 0, 0, 0, 25,
+  0, 26, 0, 59, 9, 0, 0, 24, 0, 0,
+  45, 0, 88, 34, 0, 0, 0, 0, 0, 9,
+  6, 0, 0, 0, 0, 0, 36, 0, 0, 0,
+  0, 0, 0, 17, 64, 0, 2, 0, 1, 0,
+  91, 28, 8, 0, 51, 13, 35, 13, 47, 25,
+  0, 0, 0, 32, 0, 22, 0, 0, 48, 22,
+  0, 7, 0, 0, 23, 0, 25, 21, 43, 64,
+  10, 0, 0, 0, 29, 0, 0, 0, 18, 0,
+  4, 0, 74, 0, 0, 37, 25, 0, 0, 96,
+  8, 3, 33, 0, 35, 0, 85, 3, 0, 27,
+  4, 58, 40, 66, 33, 44, 0, 33, 67, 0,
+  11, 33, 0, 10, 35, 17, 0, 0, 0, 0,
+  16, 0, 0, 0, 0, 12, 0, 0, 0, 9,
+  0, 67, 0, 25, 0, 38, 0, 0, 28, 0,
+  77, 30, 0, 0, 25, 0, 0, 0, 0, 0,
+  0, 0, 2, 0, 21, 0, 17, 0, 0, 0,
+  18, 29, 78, 0, 11, 0, 0, 0, 78, 36,
+  3, 0, 35, 3, 44, 7, 36, 20, 0, 27,
+  0, 26, 0, 8, 0, 0, 61, 33, 8, 16,
+  0, 0, 58, 0, 22, 29, 12, 37, 7, 0,
+  0, 0, 41, 0, 0, 0, 20, 0, 0, 0,
+  52, 0, 0, 31, 46, 0, 0, 50, 11, 21,
+  17, 0, 0, 0, 67, 0, 0, 42, 4, 106,
+  9, 17, 15, 45, 0, 24, 71, 0, 40, 19,
+  0, 0, 0, 3, 0, 0, 0, 0, 0, 10,
+  0, 0, 0, 0, 0, 0, 4, 19, 0, 50,
+  0, 0, 0, 45, 0, 0, 34, 65, 36, 45,
+  0, 0, 44, 0, 0, 0, 0, 0, 7, 0,
+  60, 7, 0, 7, 12, 15, 0, 0, 10, 2,
+  40, 0, 0, 0, 0, 1, 42, 35, 2, 0,
+  21, 0, 58, 15, 51, 12, 0, 30, 0, 0,
+  0, 9, 0, 0, 58, 45, 6, 2, 0, 0,
+  16, 0, 0, 13, 0, 3, 7, 0, 0, 0,
+  80, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 4, 12, 0, 0, 43, 70, 0, 11, 0,
+  9, 0, 57, 6, 0, 0, 0, 60, 23, 63,
+  30, 38, 0, 12, 39, 0, 33, 35, 0, 0,
+  9, 14, 0, 0, 27, 0, 0, 0, 0, 0,
+  0, 17, 0, 12, 27, 0, 0, 40, 0, 0,
+  0, 0, 0, 0, 48, 52, 41, 12, 0, 0,
+  19, 12, 0, 0, 0, 0, 0, 0, 24, 0,
+  45, 0, 11, 4, 0, 0, 0, 28, 32, 0,
+  0, 18, 0, 0, 58, 19, 0, 21, 59, 13,
+  23, 9, 64, 10, 0, 32, 0, 0, 0, 0,
+  0, 0, 40, 51, 0, 0, 0, 0, 36, 0,
+  0, 22, 4, 24, 40, 0, 0, 0, 86, 0,
+  2, 0, 26, 0, 0, 1, 21, 0, 0, 24,
+  22, 0, 0, 1, 54, 0, 0, 0, 0, 0,
+  42, 0, 0, 7, 0, 86, 0, 0, 1, 43,
+  0, 15, 50, 15, 93, 16, 0, 0, 0, 18,
+  0, 0, 16, 0, 0, 0, 0, 0, 0, 25,
+  0, 0, 34, 33, 0, 35, 0, 0, 0, 17,
+  0, 0, 34, 96, 0, 0, 21, 0, 40, 0,
+  14, 0, 0, 2, 21, 0, 100, 23, 1, 3,
+  2, 71, 0, 0, 0, 0, 18, 0, 0, 0,
+  0, 0, 25, 5, 0, 25, 63, 0, 32, 16,
+  62, 0, 0, 28, 0, 0, 0, 0, 0, 0,
+  67, 44, 0, 0, 0, 0, 26, 0, 0, 29,
+  0, 5, 41, 0, 0, 0, 99, 0, 45, 0,
+  46, 0, 0, 13, 0, 0, 0, 6, 19, 0,
+  16, 0, 16, 11, 0, 0, 0, 0, 35, 0,
+  0, 25, 4, 106, 0, 0, 0, 36, 2, 10,
+  68, 10, 49, 2, 0, 0, 0, 0, 0, 0,
+  0, 2, 0, 9, 0, 0, 0, 0, 0, 0,
+  5, 41, 0, 45, 0, 0, 0, 31, 0, 0,
+  66, 127, 0, 42, 14, 0, 16, 0, 2, 0,
+  0, 0, 48, 0, 110, 32, 0, 9, 0, 60,
+  0, 11, 0, 0, 22, 0, 0, 0, 0, 41,
+  18, 32, 0, 0, 51, 0, 58, 18, 81, 0,
+  0, 0, 0, 0, 0, 12, 11, 0, 73, 49,
+  0, 0, 0, 0, 6, 0, 0, 8, 11, 0,
+  36, 0, 0, 0, 95, 0, 70, 0, 20, 0,
+  1, 0, 0, 0, 8, 0, 11, 0, 0, 99,
+  0, 38, 55, 0, 74, 0, 47, 0, 0, 55,
+  43, 30, 27, 0, 3, 36, 0, 59, 80, 0,
+  0, 26, 36, 49, 32, 1, 0, 12, 51, 0,
+  22, 17, 3, 0, 0, 0, 0, 0, 0, 20,
+  0, 83, 20, 23, 0, 15, 0, 0, 26, 0,
+  67, 45, 0, 11, 23, 0, 0, 37, 22, 0,
+  0, 0, 0, 0, 14, 67, 0, 0, 0, 11,
+  0, 0, 67, 0, 16, 0, 7, 0, 80, 54,
+  0, 0, 42, 0, 37, 1, 24, 67, 6, 0,
+  0, 40, 0, 45, 0, 0, 77, 8, 0, 34,
+  3, 0, 0, 0, 25, 58, 103, 36, 0, 0,
+  0, 0, 32, 0, 0, 0, 0, 0, 21, 22,
+  80, 0, 38, 25, 8, 0, 0, 129, 0, 59,
+  30, 0, 80, 0, 63, 0, 2, 62, 41, 13,
+  24, 8, 0, 36, 0, 50, 73, 0, 0, 34,
+  40, 69, 39, 5, 0, 13, 44, 0, 63, 0,
+  17, 0, 0, 0, 0, 0, 0, 30, 0, 55,
+  31, 26, 0, 15, 0, 0, 34, 0, 63, 66,
+  0, 6, 53, 0, 0, 76, 13, 0, 0, 0,
+  0, 0, 32, 81, 0, 0, 0, 20, 0, 0,
+  48, 49, 0, 0, 0, 0, 65, 72, 1, 0,
+  21, 0, 34, 0, 17, 106, 73, 0, 0, 66,
+  0, 33, 16, 0, 73, 22, 0, 27, 0, 0,
+  0, 0, 17, 70, 123, 31, 8, 0, 18, 0,
+  19, 0, 0, 0, 0, 0, 16, 21, 113, 10,
+  49, 16, 11, 0, 4, 112, 0, 54, 23, 0,
+  15, 0, 85, 7, 0, 53, 5, 3, 0, 0,
+  0, 18, 0, 13, 49, 0, 0, 31, 10, 11,
+  45, 17, 0, 0, 0, 9, 32, 0, 23, 0,
+  0, 18, 0, 0, 0, 0, 0, 18, 25, 27,
+  0, 0, 0, 0, 33, 14, 7, 64, 44, 38,
+  45, 0, 0, 10, 0, 11, 7, 12, 0, 7,
+  17, 45, 0, 29, 0, 13, 26, 0, 1, 55,
+  0, 8, 5, 0, 20, 44, 16, 23, 0, 0,
+  15, 29, 38, 55, 93, 0, 0, 17, 0, 0,
+  52, 0, 35, 52, 0, 80, 0, 0, 0, 0,
+  0, 84, 112, 0, 31, 0, 15, 3, 1, 0,
+  0, 0, 0, 0, 3, 0, 28, 0, 45, 32,
+  0, 0, 0, 96, 8, 3, 33, 0, 35, 0,
+  85, 3, 0, 27, 4, 58, 40, 66, 33, 44,
+  0, 33, 67, 0, 11, 33, 0, 10, 35, 17,
+  0, 0, 0, 0, 16, 0, 0, 0, 0, 12,
+  0, 0, 0, 9, 0, 67, 0, 25, 0, 38,
+  0, 0, 28, 0, 77, 30, 0, 0, 25, 0,
+  0, 0, 0, 0, 0, 0, 2, 0, 21, 0,
+  17, 0, 0, 0, 18, 29, 78, 0, 11, 0,
+  0, 0, 78, 36, 3, 0, 35, 3, 44, 7,
+  36, 20, 0, 27, 0, 26, 0, 8, 0, 0,
+  61, 33, 8, 16, 0, 0, 58, 0, 22, 29,
+  12, 37, 7, 0, 0, 0, 41, 0, 0, 0,
+  20, 0, 0, 0, 52, 0, 0, 31, 46, 0,
+  0, 50, 11, 21, 17, 0, 0, 0, 67, 0,
+  0, 42, 4, 106, 9, 17, 15, 45, 0, 24,
+  71, 0, 40, 19, 0, 0, 0, 3, 0, 0,
+  0, 0, 0, 10, 0, 0, 0, 0, 0, 0,
+  4, 19, 0, 50, 0, 0, 0, 45, 0, 0,
+  34, 65, 36, 45, 0, 0, 44, 0, 0, 0,
+  0, 0, 7, 0, 60, 7, 0, 7, 12, 15,
+  0, 0, 10, 2, 40, 0, 0, 0, 0, 1,
+  42, 35, 2, 0, 21, 0, 58, 15, 51, 12,
+  0, 30, 0, 0, 0, 9, 0, 0, 58, 45,
+  6, 2, 0, 0, 16, 0, 0, 13, 0, 3,
+  7, 0, 0, 0, 80, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 4, 12, 0, 20, 58,
+  19, 29, 24, 0, 0, 0, 79, 0, 0, 44,
+  19, 100, 0, 0, 0, 11, 0, 4, 57, 0,
+  28, 24, 0, 0, 2, 0, 0, 3, 5, 0,
+  0, 6, 0, 0, 0, 0, 0, 0, 0, 34,
+  0, 24, 0, 0, 6, 41, 0, 0, 50, 104,
+  10, 72, 18, 0, 43, 0, 5, 0, 0, 0,
+  14, 0, 25, 49, 0, 0, 0, 41, 0, 14,
+  1, 0, 14, 2, 0, 0, 0, 33, 14, 52,
+  21, 0, 21, 0, 41, 46, 70, 27, 15, 0,
+  0, 0, 0, 6, 30, 0, 57, 63, 0, 18,
+  0, 0, 0, 0, 0, 23, 55, 0, 32, 0,
+  0, 0, 90, 0, 14, 0, 0, 0, 5, 1,
+  0, 0, 20, 7, 0, 0, 0, 1, 54, 0,
+  0, 0, 0, 0, 42, 0, 0, 7, 0, 86,
+  0, 0, 1, 43, 0, 15, 50, 15, 93, 16,
+  0, 0, 0, 18, 0, 0, 16, 0, 0, 0,
+  0, 0, 0, 25, 0, 0, 34, 33, 0, 35,
+  0, 0, 0, 17, 0, 0, 34, 96, 0, 0,
+  21, 0, 40, 0, 14, 0, 0, 2, 21, 0,
+  100, 23, 1, 3, 2, 71, 0, 0, 0, 0,
+  18, 0, 0, 0, 0, 0, 25, 5, 0, 25,
+  63, 0, 32, 16, 62, 0, 0, 28, 0, 0,
+  0, 0, 0, 0, 67, 44, 0, 0, 0, 0,
+  26, 0, 0, 29, 0, 5, 41, 0, 0, 0,
+  99, 0, 45, 0, 46, 0, 0, 13, 0, 0,
+  0, 6, 19, 0, 16, 0, 16, 11, 0, 0,
+  0, 0, 35, 0, 0, 25, 4, 106, 0, 0,
+  0, 36, 2, 10, 68, 10, 49, 2, 0, 0,
+  0, 0, 0, 0, 0, 2, 0, 9, 0, 0,
+  0, 0, 0, 0, 5, 41, 0, 45, 0, 0,
+  0, 31, 0, 0, 66, 127, 0, 42, 14, 0,
+  16, 0, 2, 0, 0, 0, 48, 0, 110, 32,
+  0, 9, 0, 60, 0, 11, 0, 0, 22, 0,
+  0, 0, 0, 41, 18, 32, 0, 0, 51, 0,
+  58, 18, 81, 0, 0, 0, 0, 0, 0, 12,
+  11, 0, 73, 49, 0, 0, 0, 0, 6, 0,
+  0, 8, 11, 0, 36, 0, 0, 0, 95, 0,
+  70, 0, 20, 0, 1, 0, 0, 0, 8, 0,
+  11, 0, 7, 17, 0, 25, 21, 11, 0, 0,
+  61, 0, 0, 19, 7, 87, 0, 0, 0, 20,
+  13, 16, 69, 0, 0, 19, 0, 0, 0, 0,
+  0, 18, 0, 0, 0, 6, 0, 0, 0, 0,
+  0, 0, 0, 18, 0, 55, 0, 0, 10, 38,
+  0, 0, 71, 103, 0, 69, 0, 0, 31, 9,
+  0, 0, 0, 0, 4, 0, 42, 20, 0, 14,
+  0, 7, 0, 2, 0, 0, 39, 0, 0, 0,
+  0, 43, 31, 45, 9, 0, 36, 0, 50, 45,
+  79, 24, 11, 1, 0, 0, 0, 13, 32, 0,
+  65, 65, 1, 23, 0, 0, 0, 0, 0, 13,
+  64, 0, 7, 0, 0, 0, 59, 0, 45, 0,
+  6, 0, 45, 0, 40, 0, 47, 0, 8, 0,
+  0, 129, 0, 59, 30, 0, 80, 0, 63, 0,
+  2, 62, 41, 13, 24, 8, 0, 36, 0, 50,
+  73, 0, 0, 34, 40, 69, 39, 5, 0, 13,
+  44, 0, 63, 0, 17, 0, 0, 0, 0, 0,
+  0, 30, 0, 55, 31, 26, 0, 15, 0, 0,
+  34, 0, 63, 66, 0, 6, 53, 0, 0, 76,
+  13, 0, 0, 0, 0, 0, 32, 81, 0, 0,
+  0, 20, 0, 0, 48, 49, 0, 0, 0, 0,
+  65, 72, 1, 0, 21, 0, 34, 0, 17, 106,
+  73, 0, 0, 66, 0, 33, 16, 0, 73, 22,
+  0, 27, 0, 0, 0, 0, 17, 70, 123, 31,
+  8, 0, 18, 0, 19, 0, 0, 0, 0, 0,
+  16, 21, 113, 10, 49, 16, 11, 0, 4, 112,
+  0, 54, 23, 0, 15, 0, 85, 7, 0, 53,
+  5, 3, 0, 0, 0, 18, 0, 13, 49, 0,
+  0, 31, 10, 11, 45, 17, 0, 0, 0, 9,
+  32, 0, 23, 0, 0, 18, 0, 0, 0, 0,
+  0, 18, 25, 27, 0, 0, 0, 0, 33, 14,
+  7, 64, 44, 38, 45, 0, 0, 10, 0, 11,
+  7, 12, 0, 7, 17, 45, 0, 29, 0, 13,
+  26, 0, 1, 55, 0, 8, 5, 0, 20, 44,
+  16, 23, 0, 0, 15, 29, 38, 55, 93, 0,
+  0, 17, 0, 0, 52, 0, 35, 52, 0, 80,
+  0, 0, 0, 0, 0, 84, 112, 0, 31, 0,
+  15, 3, 1, 0, 0, 0, 0, 0, 3, 0,
+  28, 0, 45, 32, 0, 0, 29, 57, 0, 24,
+  0, 27, 0, 0, 42, 0, 0, 31, 0, 13,
+  0, 0, 0, 38, 15, 0, 3, 20, 0, 0,
+  0, 0, 2, 0, 0, 0, 0, 33, 0, 0,
+  0, 22, 12, 36, 5, 0, 22, 0, 25, 16,
+  5, 0, 6, 0, 0, 0, 0, 74, 0, 26,
+  125, 100, 30, 22, 18, 0, 0, 43, 75, 37,
+  102, 36, 0, 20, 0, 109, 123, 3, 27, 0,
+  0, 17, 0, 0, 34, 0, 0, 1, 35, 33,
+  3, 0, 0, 8, 62, 0, 21, 30, 0, 0,
+  38, 0, 43, 0, 9, 59, 0, 117, 0, 0,
+  0, 0, 0, 80, 21, 0, 14, 0, 0, 24,
+  0, 0, 0, 0, 10, 0, 0, 0, 0, 0,
+  32, 35, 0, 0, 0, 50, 11, 21, 17, 0,
+  0, 0, 67, 0, 0, 42, 4, 106, 9, 17,
+  15, 45, 0, 24, 71, 0, 40, 19, 0, 0,
+  0, 3, 0, 0, 0, 0, 0, 10, 0, 0,
+  0, 0, 0, 0, 4, 19, 0, 50, 0, 0,
+  0, 45, 0, 0, 34, 65, 36, 45, 0, 0,
+  44, 0, 0, 0, 0, 0, 7, 0, 60, 7,
+  0, 7, 12, 15, 0, 0, 10, 2, 40, 0,
+  0, 0, 0, 1, 42, 35, 2, 0, 21, 0,
+  58, 15, 51, 12, 0, 30, 0, 0, 0, 9,
+  0, 0, 58, 45, 6, 2, 0, 0, 16, 0,
+  0, 13, 0, 3, 7, 0, 0, 0, 80, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 4,
+  12, 0, 20, 58, 19, 29, 24, 0, 0, 0,
+  79, 0, 0, 44, 19, 100, 0, 0, 0, 11,
+  0, 4, 57, 0, 28, 24, 0, 0, 2, 0,
+  0, 3, 5, 0, 0, 6, 0, 0, 0, 0,
+  0, 0, 0, 34, 0, 24, 0, 0, 6, 41,
+  0, 0, 50, 104, 10, 72, 18, 0, 43, 0,
+  5, 0, 0, 0, 14, 0, 25, 49, 0, 0,
+  0, 41, 0, 14, 1, 0, 14, 2, 0, 0,
+  0, 33, 14, 52, 21, 0, 21, 0, 41, 46,
+  70, 27, 15, 0, 0, 0, 0, 6, 30, 0,
+  57, 63, 0, 18, 0, 0, 0, 0, 0, 23,
+  55, 0, 32, 0, 0, 0, 90, 0, 14, 0,
+  0, 0, 5, 1, 0, 0, 20, 7, 0, 0,
+  56, 103, 0, 45, 15, 0, 0, 0, 58, 0,
+  0, 52, 30, 60, 0, 0, 0, 11, 22, 8,
+  26, 0, 0, 48, 0, 0, 58, 0, 0, 0,
+  19, 13, 0, 0, 3, 0, 0, 0, 0, 0,
+  0, 0, 0, 14, 26, 11, 2, 0, 0, 0,
+  23, 83, 1, 41, 67, 0, 39, 3, 0, 0,
+  0, 31, 34, 12, 4, 15, 0, 13, 0, 63,
+  0, 12, 10, 0, 0, 36, 0, 0, 33, 0,
+  0, 39, 30, 13, 0, 0, 19, 60, 73, 69,
+  93, 0, 0, 0, 0, 0, 59, 0, 21, 68,
+  23, 82, 0, 0, 0, 0, 0, 52, 129, 3,
+  21, 0, 0, 7, 40, 0, 0, 0, 3, 0,
+  26, 0, 14, 0, 57, 39, 0, 0, 16, 0,
+  16, 11, 0, 0, 0, 0, 35, 0, 0, 25,
+  4, 106, 0, 0, 0, 36, 2, 10, 68, 10,
+  49, 2, 0, 0, 0, 0, 0, 0, 0, 2,
+  0, 9, 0, 0, 0, 0, 0, 0, 5, 41,
+  0, 45, 0, 0, 0, 31, 0, 0, 66, 127,
+  0, 42, 14, 0, 16, 0, 2, 0, 0, 0,
+  48, 0, 110, 32, 0, 9, 0, 60, 0, 11,
+  0, 0, 22, 0, 0, 0, 0, 41, 18, 32,
+  0, 0, 51, 0, 58, 18, 81, 0, 0, 0,
+  0, 0, 0, 12, 11, 0, 73, 49, 0, 0,
+  0, 0, 6, 0, 0, 8, 11, 0, 36, 0,
+  0, 0, 95, 0, 70, 0, 20, 0, 1, 0,
+  0, 0, 8, 0, 11, 0, 7, 17, 0, 25,
+  21, 11, 0, 0, 61, 0, 0, 19, 7, 87,
+  0, 0, 0, 20, 13, 16, 69, 0, 0, 19,
+  0, 0, 0, 0, 0, 18, 0, 0, 0, 6,
+  0, 0, 0, 0, 0, 0, 0, 18, 0, 55,
+  0, 0, 10, 38, 0, 0, 71, 103, 0, 69,
+  0, 0, 31, 9, 0, 0, 0, 0, 4, 0,
+  42, 20, 0, 14, 0, 7, 0, 2, 0, 0,
+  39, 0, 0, 0, 0, 43, 31, 45, 9, 0,
+  36, 0, 50, 45, 79, 24, 11, 1, 0, 0,
+  0, 13, 32, 0, 65, 65, 1, 23, 0, 0,
+  0, 0, 0, 13, 64, 0, 7, 0, 0, 0,
+  59, 0, 45, 0, 6, 0, 45, 0, 40, 0,
+  47, 0, 8, 0, 0, 108, 0, 50, 20, 0,
+  23, 0, 76, 0, 5, 27, 31, 30, 12, 0,
+  0, 17, 12, 30, 55, 0, 0, 56, 13, 61,
+  39, 0, 0, 26, 15, 0, 27, 4, 0, 0,
+  0, 0, 0, 5, 0, 21, 0, 47, 11, 0,
+  10, 19, 0, 0, 54, 49, 57, 86, 0, 0,
+  20, 0, 0, 49, 9, 0, 0, 0, 0, 0,
+  32, 13, 0, 0, 0, 12, 0, 0, 51, 32,
+  0, 0, 0, 19, 65, 67, 24, 0, 19, 0,
+  39, 50, 52, 88, 74, 0, 0, 18, 0, 13,
+  42, 0, 60, 63, 11, 32, 0, 0, 0, 0,
+  14, 25, 123, 40, 2, 0, 0, 0, 13, 0,
+  5, 0, 0, 0, 42, 3, 144, 0, 86, 0,
+  0, 0, 4, 112, 0, 54, 23, 0, 15, 0,
+  85, 7, 0, 53, 5, 3, 0, 0, 0, 18,
+  0, 13, 49, 0, 0, 31, 10, 11, 45, 17,
+  0, 0, 0, 9, 32, 0, 23, 0, 0, 18,
+  0, 0, 0, 0, 0, 18, 25, 27, 0, 0,
+  0, 0, 33, 14, 7, 64, 44, 38, 45, 0,
+  0, 10, 0, 11, 7, 12, 0, 7, 17, 45,
+  0, 29, 0, 13, 26, 0, 1, 55, 0, 8,
+  5, 0, 20, 44, 16, 23, 0, 0, 15, 29,
+  38, 55, 93, 0, 0, 17, 0, 0, 52, 0,
+  35, 52, 0, 80, 0, 0, 0, 0, 0, 84,
+  112, 0, 31, 0, 15, 3, 1, 0, 0, 0,
+  0, 0, 3, 0, 28, 0, 45, 32, 0, 0,
+  29, 57, 0, 24, 0, 27, 0, 0, 42, 0,
+  0, 31, 0, 13, 0, 0, 0, 38, 15, 0,
+  3, 20, 0, 0, 0, 0, 2, 0, 0, 0,
+  0, 33, 0, 0, 0, 22, 12, 36, 5, 0,
+  22, 0, 25, 16, 5, 0, 6, 0, 0, 0,
+  0, 74, 0, 26, 125, 100, 30, 22, 18, 0,
+  0, 43, 75, 37, 102, 36, 0, 20, 0, 109,
+  123, 3, 27, 0, 0, 17, 0, 0, 34, 0,
+  0, 1, 35, 33, 3, 0, 0, 8, 62, 0,
+  21, 30, 0, 0, 38, 0, 43, 0, 9, 59,
+  0, 117, 0, 0, 0, 0, 0, 80, 21, 0,
+  14, 0, 0, 24, 0, 0, 0, 0, 10, 0,
+  0, 0, 0, 0, 32, 35, 0, 0, 10, 25,
+  0, 0, 0, 85, 0, 0, 22, 0, 0, 0,
+  0, 0, 0, 0, 0, 39, 3, 8, 0, 40,
+  0, 0, 0, 0, 8, 3, 0, 0, 0, 38,
+  0, 0, 0, 43, 47, 68, 23, 0, 46, 0,
+  22, 15, 0, 13, 59, 13, 0, 0, 0, 55,
+  0, 0, 112, 118, 34, 26, 48, 0, 0, 57,
+  67, 0, 179, 5, 0, 32, 0, 139, 175, 0,
+  10, 15, 0, 0, 0, 0, 42, 0, 0, 0,
+  28, 19, 31, 0, 0, 11, 42, 0, 0, 116,
+  13, 0, 34, 0, 0, 0, 6, 54, 43, 142,
+  0, 0, 0, 0, 0, 58, 0, 0, 0, 29,
+  0, 30, 0, 10, 0, 0, 53, 0, 0, 0,
+  0, 0, 1, 29, 1, 6, 20, 58, 19, 29,
+  24, 0, 0, 0, 79, 0, 0, 44, 19, 100,
+  0, 0, 0, 11, 0, 4, 57, 0, 28, 24,
+  0, 0, 2, 0, 0, 3, 5, 0, 0, 6,
+  0, 0, 0, 0, 0, 0, 0, 34, 0, 24,
+  0, 0, 6, 41, 0, 0, 50, 104, 10, 72,
+  18, 0, 43, 0, 5, 0, 0, 0, 14, 0,
+  25, 49, 0, 0, 0, 41, 0, 14, 1, 0,
+  14, 2, 0, 0, 0, 33, 14, 52, 21, 0,
+  21, 0, 41, 46, 70, 27, 15, 0, 0, 0,
+  0, 6, 30, 0, 57, 63, 0, 18, 0, 0,
+  0, 0, 0, 23, 55, 0, 32, 0, 0, 0,
+  90, 0, 14, 0, 0, 0, 5, 1, 0, 0,
+  20, 7, 0, 0, 56, 103, 0, 45, 15, 0,
+  0, 0, 58, 0, 0, 52, 30, 60, 0, 0,
+  0, 11, 22, 8, 26, 0, 0, 48, 0, 0,
+  58, 0, 0, 0, 19, 13, 0, 0, 3, 0,
+  0, 0, 0, 0, 0, 0, 0, 14, 26, 11,
+  2, 0, 0, 0, 23, 83, 1, 41, 67, 0,
+  39, 3, 0, 0, 0, 31, 34, 12, 4, 15,
+  0, 13, 0, 63, 0, 12, 10, 0, 0, 36,
+  0, 0, 33, 0, 0, 39, 30, 13, 0, 0,
+  19, 60, 73, 69, 93, 0, 0, 0, 0, 0,
+  59, 0, 21, 68, 23, 82, 0, 0, 0, 0,
+  0, 52, 129, 3, 21, 0, 0, 7, 40, 0,
+  0, 0, 3, 0, 26, 0, 14, 0, 57, 39,
+  0, 0, 46, 82, 0, 50, 1, 35, 0, 0,
+  22, 0, 0, 15, 41, 6, 0, 0, 0, 19,
+  21, 11, 13, 31, 0, 0, 0, 0, 64, 0,
+  0, 0, 30, 54, 0, 0, 28, 29, 0, 17,
+  0, 0, 0, 0, 1, 18, 5, 11, 10, 0,
+  0, 0, 0, 57, 0, 22, 95, 48, 30, 4,
+  0, 0, 0, 73, 54, 11, 88, 0, 0, 66,
+  0, 94, 130, 13, 9, 0, 0, 4, 0, 2,
+  68, 0, 0, 0, 23, 16, 20, 0, 0, 28,
+  33, 13, 56, 0, 0, 0, 6, 0, 47, 0,
+  18, 68, 22, 150, 0, 0, 0, 0, 0, 82,
+  91, 0, 7, 26, 10, 31, 0, 0, 0, 0,
+  31, 0, 0, 0, 0, 0, 50, 35, 0, 2,
+  7, 17, 0, 25, 21, 11, 0, 0, 61, 0,
+  0, 19, 7, 87, 0, 0, 0, 20, 13, 16,
+  69, 0, 0, 19, 0, 0, 0, 0, 0, 18,
+  0, 0, 0, 6, 0, 0, 0, 0, 0, 0,
+  0, 18, 0, 55, 0, 0, 10, 38, 0, 0,
+  71, 103, 0, 69, 0, 0, 31, 9, 0, 0,
+  0, 0, 4, 0, 42, 20, 0, 14, 0, 7,
+  0, 2, 0, 0, 39, 0, 0, 0, 0, 43,
+  31, 45, 9, 0, 36, 0, 50, 45, 79, 24,
+  11, 1, 0, 0, 0, 13, 32, 0, 65, 65,
+  1, 23, 0, 0, 0, 0, 0, 13, 64, 0,
+  7, 0, 0, 0, 59, 0, 45, 0, 6, 0,
+  45, 0, 40, 0, 47, 0, 8, 0, 0, 108,
+  0, 50, 20, 0, 23, 0, 76, 0, 5, 27,
+  31, 30, 12, 0, 0, 17, 12, 30, 55, 0,
+  0, 56, 13, 61, 39, 0, 0, 26, 15, 0,
+  27, 4, 0, 0, 0, 0, 0, 5, 0, 21,
+  0, 47, 11, 0, 10, 19, 0, 0, 54, 49,
+  57, 86, 0, 0, 20, 0, 0, 49, 9, 0,
+  0, 0, 0, 0, 32, 13, 0, 0, 0, 12,
+  0, 0, 51, 32, 0, 0, 0, 19, 65, 67,
+  24, 0, 19, 0, 39, 50, 52, 88, 74, 0,
+  0, 18, 0, 13, 42, 0, 60, 63, 11, 32,
+  0, 0, 0, 0, 14, 25, 123, 40, 2, 0,
+  0, 0, 13, 0, 5, 0, 0, 0, 42, 3,
+  144, 0, 86, 0, 0, 0, 0, 155, 0, 57,
+  4, 0, 35, 0, 65, 0, 13, 22, 77, 0,
+  0, 0, 0, 12, 22, 43, 12, 0, 0, 61,
+  29, 33, 73, 13, 3, 0, 36, 0, 52, 0,
+  38, 0, 0, 0, 0, 0, 0, 22, 0, 53,
+  11, 0, 16, 0, 0, 0, 43, 52, 47, 51,
+  11, 17, 36, 0, 0, 49, 1, 0, 0, 0,
+  0, 0, 2, 16, 0, 0, 11, 34, 0, 0,
+  39, 55, 0, 69, 4, 0, 37, 56, 49, 10,
+  11, 0, 0, 58, 72, 93, 137, 0, 0, 11,
+  0, 0, 57, 0, 44, 81, 42, 39, 0, 0,
+  0, 0, 27, 70, 152, 18, 4, 0, 17, 10,
+  0, 0, 0, 0, 0, 0, 3, 0, 133, 2,
+  119, 5, 0, 0, 29, 57, 0, 24, 0, 27,
+  0, 0, 42, 0, 0, 31, 0, 13, 0, 0,
+  0, 38, 15, 0, 3, 20, 0, 0, 0, 0,
+  2, 0, 0, 0, 0, 33, 0, 0, 0, 22,
+  12, 36, 5, 0, 22, 0, 25, 16, 5, 0,
+  6, 0, 0, 0, 0, 74, 0, 26, 125, 100,
+  30, 22, 18, 0, 0, 43, 75, 37, 102, 36,
+  0, 20, 0, 109, 123, 3, 27, 0, 0, 17,
+  0, 0, 34, 0, 0, 1, 35, 33, 3, 0,
+  0, 8, 62, 0, 21, 30, 0, 0, 38, 0,
+  43, 0, 9, 59, 0, 117, 0, 0, 0, 0,
+  0, 80, 21, 0, 14, 0, 0, 24, 0, 0,
+  0, 0, 10, 0, 0, 0, 0, 0, 32, 35,
+  0, 0, 10, 25, 0, 0, 0, 85, 0, 0,
+  22, 0, 0, 0, 0, 0, 0, 0, 0, 39,
+  3, 8, 0, 40, 0, 0, 0, 0, 8, 3,
+  0, 0, 0, 38, 0, 0, 0, 43, 47, 68,
+  23, 0, 46, 0, 22, 15, 0, 13, 59, 13,
+  0, 0, 0, 55, 0, 0, 112, 118, 34, 26,
+  48, 0, 0, 57, 67, 0, 179, 5, 0, 32,
+  0, 139, 175, 0, 10, 15, 0, 0, 0, 0,
+  42, 0, 0, 0, 28, 19, 31, 0, 0, 11,
+  42, 0, 0, 116, 13, 0, 34, 0, 0, 0,
+  6, 54, 43, 142, 0, 0, 0, 0, 0, 58,
+  0, 0, 0, 29, 0, 30, 0, 10, 0, 0,
+  53, 0, 0, 0, 0, 0, 1, 29, 1, 6,
+  0, 37, 0, 0, 0, 81, 0, 0, 83, 32,
+  0, 0, 0, 9, 0, 42, 6, 26, 0, 10,
+  0, 0, 0, 25, 0, 0, 22, 40, 7, 0,
+  0, 0, 67, 0, 0, 20, 33, 86, 0, 0,
+  32, 0, 0, 10, 0, 67, 54, 81, 0, 26,
+  0, 6, 0, 0, 25, 36, 58, 0, 32, 0,
+  0, 65, 0, 0, 102, 0, 0, 34, 25, 57,
+  85, 0, 33, 59, 0, 79, 0, 0, 3, 0,
+  3, 0, 2, 0, 0, 0, 0, 49, 15, 0,
+  0, 173, 0, 0, 0, 0, 0, 0, 0, 64,
+  113, 110, 0, 0, 0, 0, 0, 29, 0, 22,
+  0, 30, 0, 19, 0, 0, 0, 29, 61, 0,
+  40, 0, 0, 0, 0, 15, 1, 35, 56, 103,
+  0, 45, 15, 0, 0, 0, 58, 0, 0, 52,
+  30, 60, 0, 0, 0, 11, 22, 8, 26, 0,
+  0, 48, 0, 0, 58, 0, 0, 0, 19, 13,
+  0, 0, 3, 0, 0, 0, 0, 0, 0, 0,
+  0, 14, 26, 11, 2, 0, 0, 0, 23, 83,
+  1, 41, 67, 0, 39, 3, 0, 0, 0, 31,
+  34, 12, 4, 15, 0, 13, 0, 63, 0, 12,
+  10, 0, 0, 36, 0, 0, 33, 0, 0, 39,
+  30, 13, 0, 0, 19, 60, 73, 69, 93, 0,
+  0, 0, 0, 0, 59, 0, 21, 68, 23, 82,
+  0, 0, 0, 0, 0, 52, 129, 3, 21, 0,
+  0, 7, 40, 0, 0, 0, 3, 0, 26, 0,
+  14, 0, 57, 39, 0, 0, 46, 82, 0, 50,
+  1, 35, 0, 0, 22, 0, 0, 15, 41, 6,
+  0, 0, 0, 19, 21, 11, 13, 31, 0, 0,
+  0, 0, 64, 0, 0, 0, 30, 54, 0, 0,
+  28, 29, 0, 17, 0, 0, 0, 0, 1, 18,
+  5, 11, 10, 0, 0, 0, 0, 57, 0, 22,
+  95, 48, 30, 4, 0, 0, 0, 73, 54, 11,
+  88, 0, 0, 66, 0, 94, 130, 13, 9, 0,
+  0, 4, 0, 2, 68, 0, 0, 0, 23, 16,
+  20, 0, 0, 28, 33, 13, 56, 0, 0, 0,
+  6, 0, 47, 0, 18, 68, 22, 150, 0, 0,
+  0, 0, 0, 82, 91, 0, 7, 26, 10, 31,
+  0, 0, 0, 0, 31, 0, 0, 0, 0, 0,
+  50, 35, 0, 2, 1, 12, 0, 19, 0, 115,
+  0, 0, 17, 0, 0, 0, 0, 1, 0, 0,
+  0, 28, 11, 16, 0, 65, 2, 0, 0, 0,
+  23, 0, 0, 0, 0, 17, 8, 0, 9, 65,
+  12, 45, 5, 0, 48, 0, 0, 18, 0, 33,
+  46, 0, 0, 7, 0, 29, 0, 0, 131, 59,
+  54, 5, 43, 0, 0, 107, 51, 0, 166, 0,
+  0, 46, 0, 112, 193, 0, 44, 0, 0, 35,
+  0, 0, 29, 0, 0, 0, 32, 0, 28, 0,
+  0, 1, 14, 0, 0, 79, 16, 0, 38, 0,
+  0, 0, 3, 61, 47, 127, 0, 0, 0, 0,
+  0, 36, 0, 0, 0, 55, 0, 53, 0, 0,
+  0, 0, 47, 0, 0, 0, 0, 0, 13, 18,
+  0, 12, 0, 108, 0, 50, 20, 0, 23, 0,
+  76, 0, 5, 27, 31, 30, 12, 0, 0, 17,
+  12, 30, 55, 0, 0, 56, 13, 61, 39, 0,
+  0, 26, 15, 0, 27, 4, 0, 0, 0, 0,
+  0, 5, 0, 21, 0, 47, 11, 0, 10, 19,
+  0, 0, 54, 49, 57, 86, 0, 0, 20, 0,
+  0, 49, 9, 0, 0, 0, 0, 0, 32, 13,
+  0, 0, 0, 12, 0, 0, 51, 32, 0, 0,
+  0, 19, 65, 67, 24, 0, 19, 0, 39, 50,
+  52, 88, 74, 0, 0, 18, 0, 13, 42, 0,
+  60, 63, 11, 32, 0, 0, 0, 0, 14, 25,
+  123, 40, 2, 0, 0, 0, 13, 0, 5, 0,
+  0, 0, 42, 3, 144, 0, 86, 0, 0, 0,
+  0, 155, 0, 57, 4, 0, 35, 0, 65, 0,
+  13, 22, 77, 0, 0, 0, 0, 12, 22, 43,
+  12, 0, 0, 61, 29, 33, 73, 13, 3, 0,
+  36, 0, 52, 0, 38, 0, 0, 0, 0, 0,
+  0, 22, 0, 53, 11, 0, 16, 0, 0, 0,
+  43, 52, 47, 51, 11, 17, 36, 0, 0, 49,
+  1, 0, 0, 0, 0, 0, 2, 16, 0, 0,
+  11, 34, 0, 0, 39, 55, 0, 69, 4, 0,
+  37, 56, 49, 10, 11, 0, 0, 58, 72, 93,
+  137, 0, 0, 11, 0, 0, 57, 0, 44, 81,
+  42, 39, 0, 0, 0, 0, 27, 70, 152, 18,
+  4, 0, 17, 10, 0, 0, 0, 0, 0, 0,
+  3, 0, 133, 2, 119, 5, 0, 0, 21, 77,
+  0, 54, 0, 57, 1, 0, 24, 0, 0, 9,
+  43, 0, 0, 0, 0, 20, 47, 27, 0, 27,
+  1, 0, 0, 0, 69, 0, 0, 0, 4, 19,
+  15, 0, 32, 49, 0, 0, 3, 0, 0, 7,
+  0, 34, 8, 10, 16, 0, 0, 0, 3, 45,
+  0, 0, 93, 35, 51, 0, 0, 0, 0, 53,
+  20, 0, 103, 0, 0, 43, 0, 68, 175, 29,
+  22, 0, 0, 35, 0, 61, 4, 6, 0, 0,
+  64, 5, 21, 0, 0, 19, 51, 0, 81, 0,
+  0, 0, 7, 0, 55, 0, 12, 95, 28, 106,
+  1, 0, 0, 0, 4, 67, 71, 0, 2, 16,
+  0, 39, 0, 0, 0, 0, 25, 0, 0, 0,
+  0, 18, 65, 17, 0, 0, 10, 25, 0, 0,
+  0, 85, 0, 0, 22, 0, 0, 0, 0, 0,
+  0, 0, 0, 39, 3, 8, 0, 40, 0, 0,
+  0, 0, 8, 3, 0, 0, 0, 38, 0, 0,
+  0, 43, 47, 68, 23, 0, 46, 0, 22, 15,
+  0, 13, 59, 13, 0, 0, 0, 55, 0, 0,
+  112, 118, 34, 26, 48, 0, 0, 57, 67, 0,
+  179, 5, 0, 32, 0, 139, 175, 0, 10, 15,
+  0, 0, 0, 0, 42, 0, 0, 0, 28, 19,
+  31, 0, 0, 11, 42, 0, 0, 116, 13, 0,
+  34, 0, 0, 0, 6, 54, 43, 142, 0, 0,
+  0, 0, 0, 58, 0, 0, 0, 29, 0, 30,
+  0, 10, 0, 0, 53, 0, 0, 0, 0, 0,
+  1, 29, 1, 6, 0, 37, 0, 0, 0, 81,
+  0, 0, 83, 32, 0, 0, 0, 9, 0, 42,
+  6, 26, 0, 10, 0, 0, 0, 25, 0, 0,
+  22, 40, 7, 0, 0, 0, 67, 0, 0, 20,
+  33, 86, 0, 0, 32, 0, 0, 10, 0, 67,
+  54, 81, 0, 26, 0, 6, 0, 0, 25, 36,
+  58, 0, 32, 0, 0, 65, 0, 0, 102, 0,
+  0, 34, 25, 57, 85, 0, 33, 59, 0, 79,
+  0, 0, 3, 0, 3, 0, 2, 0, 0, 0,
+  0, 49, 15, 0, 0, 173, 0, 0, 0, 0,
+  0, 0, 0, 64, 113, 110, 0, 0, 0, 0,
+  0, 29, 0, 22, 0, 30, 0, 19, 0, 0,
+  0, 29, 61, 0, 40, 0, 0, 0, 0, 15,
+  1, 35, 0, 34, 21, 0, 0, 0, 48, 33,
+  91, 15, 14, 16, 57, 1, 0, 81, 49, 0,
+  0, 0, 6, 20, 26, 30, 1, 0, 0, 23,
+  0, 0, 0, 0, 60, 0, 3, 0, 0, 56,
+  0, 42, 4, 5, 0, 43, 0, 101, 57, 64,
+  0, 36, 0, 14, 67, 0, 0, 0, 60, 0,
+  18, 0, 6, 36, 0, 46, 0, 0, 0, 0,
+  80, 0, 0, 0, 27, 50, 26, 48, 16, 11,
+  0, 0, 59, 0, 25, 0, 0, 9, 9, 3,
+  5, 0, 0, 63, 0, 14, 0, 0, 0, 0,
+  4, 79, 88, 0, 0, 0, 17, 0, 30, 2,
+  0, 51, 0, 7, 0, 20, 0, 0, 0, 31,
+  77, 0, 50, 0, 85, 0, 42, 0, 14, 0,
+  46, 82, 0, 50, 1, 35, 0, 0, 22, 0,
+  0, 15, 41, 6, 0, 0, 0, 19, 21, 11,
+  13, 31, 0, 0, 0, 0, 64, 0, 0, 0,
+  30, 54, 0, 0, 28, 29, 0, 17, 0, 0,
+  0, 0, 1, 18, 5, 11, 10, 0, 0, 0,
+  0, 57, 0, 22, 95, 48, 30, 4, 0, 0,
+  0, 73, 54, 11, 88, 0, 0, 66, 0, 94,
+  130, 13, 9, 0, 0, 4, 0, 2, 68, 0,
+  0, 0, 23, 16, 20, 0, 0, 28, 33, 13,
+  56, 0, 0, 0, 6, 0, 47, 0, 18, 68,
+  22, 150, 0, 0, 0, 0, 0, 82, 91, 0,
+  7, 26, 10, 31, 0, 0, 0, 0, 31, 0,
+  0, 0, 0, 0, 50, 35, 0, 2, 1, 12,
+  0, 19, 0, 115, 0, 0, 17, 0, 0, 0,
+  0, 1, 0, 0, 0, 28, 11, 16, 0, 65,
+  2, 0, 0, 0, 23, 0, 0, 0, 0, 17,
+  8, 0, 9, 65, 12, 45, 5, 0, 48, 0,
+  0, 18, 0, 33, 46, 0, 0, 7, 0, 29,
+  0, 0, 131, 59, 54, 5, 43, 0, 0, 107,
+  51, 0, 166, 0, 0, 46, 0, 112, 193, 0,
+  44, 0, 0, 35, 0, 0, 29, 0, 0, 0,
+  32, 0, 28, 0, 0, 1, 14, 0, 0, 79,
+  16, 0, 38, 0, 0, 0, 3, 61, 47, 127,
+  0, 0, 0, 0, 0, 36, 0, 0, 0, 55,
+  0, 53, 0, 0, 0, 0, 47, 0, 0, 0,
+  0, 0, 13, 18, 0, 12, 0, 1, 0, 0,
+  0, 57, 0, 18, 70, 15, 0, 4, 0, 0,
+  0, 50, 13, 20, 0, 0, 47, 47, 29, 12,
+  0, 0, 0, 10, 0, 0, 0, 0, 50, 0,
+  0, 44, 0, 64, 0, 0, 54, 0, 0, 47,
+  0, 99, 16, 46, 0, 15, 0, 37, 0, 0,
+  63, 0, 74, 0, 64, 0, 0, 62, 0, 0,
+  90, 0, 0, 12, 30, 23, 61, 0, 70, 60,
+  0, 76, 0, 1, 0, 0, 21, 0, 0, 0,
+  0, 0, 8, 0, 5, 0, 0, 121, 9, 0,
+  0, 0, 0, 0, 20, 54, 116, 17, 0, 0,
+  0, 0, 11, 9, 0, 21, 0, 19, 0, 73,
+  0, 0, 0, 0, 56, 0, 53, 0, 0, 0,
+  21, 0, 18, 0, 0, 155, 0, 57, 4, 0,
+  35, 0, 65, 0, 13, 22, 77, 0, 0, 0,
+  0, 12, 22, 43, 12, 0, 0, 61, 29, 33,
+  73, 13, 3, 0, 36, 0, 52, 0, 38, 0,
+  0, 0, 0, 0, 0, 22, 0, 53, 11, 0,
+  16, 0, 0, 0, 43, 52, 47, 51, 11, 17,
+  36, 0, 0, 49, 1, 0, 0, 0, 0, 0,
+  2, 16, 0, 0, 11, 34, 0, 0, 39, 55,
+  0, 69, 4, 0, 37, 56, 49, 10, 11, 0,
+  0, 58, 72, 93, 137, 0, 0, 11, 0, 0,
+  57, 0, 44, 81, 42, 39, 0, 0, 0, 0,
+  27, 70, 152, 18, 4, 0, 17, 10, 0, 0,
+  0, 0, 0, 0, 3, 0, 133, 2, 119, 5,
+  0, 0, 21, 77, 0, 54, 0, 57, 1, 0,
+  24, 0, 0, 9, 43, 0, 0, 0, 0, 20,
+  47, 27, 0, 27, 1, 0, 0, 0, 69, 0,
+  0, 0, 4, 19, 15, 0, 32, 49, 0, 0,
+  3, 0, 0, 7, 0, 34, 8, 10, 16, 0,
+  0, 0, 3, 45, 0, 0, 93, 35, 51, 0,
+  0, 0, 0, 53, 20, 0, 103, 0, 0, 43,
+  0, 68, 175, 29, 22, 0, 0, 35, 0, 61,
+  4, 6, 0, 0, 64, 5, 21, 0, 0, 19,
+  51, 0, 81, 0, 0, 0, 7, 0, 55, 0,
+  12, 95, 28, 106, 1, 0, 0, 0, 4, 67,
+  71, 0, 2, 16, 0, 39, 0, 0, 0, 0,
+  25, 0, 0, 0, 0, 18, 65, 17, 0, 0,
+  0, 0, 0, 25, 0, 135, 0, 7, 42, 0,
+  0, 4, 0, 6, 0, 0, 0, 25, 13, 0,
+  41, 106, 15, 0, 0, 0, 0, 1, 0, 0,
+  0, 1, 9, 0, 0, 82, 0, 40, 0, 0,
+  45, 0, 0, 46, 0, 80, 0, 4, 0, 0,
+  0, 52, 0, 0, 133, 36, 44, 0, 57, 0,
+  0, 92, 42, 0, 155, 0, 0, 30, 0, 77,
+  196, 0, 59, 34, 0, 31, 0, 16, 9, 0,
+  0, 0, 35, 0, 0, 0, 1, 0, 11, 0,
+  0, 92, 0, 0, 27, 0, 0, 0, 7, 76,
+  78, 108, 0, 0, 0, 0, 0, 30, 0, 0,
+  0, 38, 0, 95, 0, 0, 0, 0, 52, 0,
+  0, 0, 0, 0, 21, 0, 0, 6, 0, 37,
+  0, 0, 0, 81, 0, 0, 83, 32, 0, 0,
+  0, 9, 0, 42, 6, 26, 0, 10, 0, 0,
+  0, 25, 0, 0, 22, 40, 7, 0, 0, 0,
+  67, 0, 0, 20, 33, 86, 0, 0, 32, 0,
+  0, 10, 0, 67, 54, 81, 0, 26, 0, 6,
+  0, 0, 25, 36, 58, 0, 32, 0, 0, 65,
+  0, 0, 102, 0, 0, 34, 25, 57, 85, 0,
+  33, 59, 0, 79, 0, 0, 3, 0, 3, 0,
+  2, 0, 0, 0, 0, 49, 15, 0, 0, 173,
+  0, 0, 0, 0, 0, 0, 0, 64, 113, 110,
+  0, 0, 0, 0, 0, 29, 0, 22, 0, 30,
+  0, 19, 0, 0, 0, 29, 61, 0, 40, 0,
+  0, 0, 0, 15, 1, 35, 0, 34, 21, 0,
+  0, 0, 48, 33, 91, 15, 14, 16, 57, 1,
+  0, 81, 49, 0, 0, 0, 6, 20, 26, 30,
+  1, 0, 0, 23, 0, 0, 0, 0, 60, 0,
+  3, 0, 0, 56, 0, 42, 4, 5, 0, 43,
+  0, 101, 57, 64, 0, 36, 0, 14, 67, 0,
+  0, 0, 60, 0, 18, 0, 6, 36, 0, 46,
+  0, 0, 0, 0, 80, 0, 0, 0, 27, 50,
+  26, 48, 16, 11, 0, 0, 59, 0, 25, 0,
+  0, 9, 9, 3, 5, 0, 0, 63, 0, 14,
+  0, 0, 0, 0, 4, 79, 88, 0, 0, 0,
+  17, 0, 30, 2, 0, 51, 0, 7, 0, 20,
+  0, 0, 0, 31, 77, 0, 50, 0, 85, 0,
+  42, 0, 14, 0, 0, 27, 0, 6, 0, 0,
+  33, 17, 40, 0, 12, 29, 62, 0, 14, 33,
+  65, 28, 0, 0, 26, 32, 26, 12, 42, 0,
+  0, 27, 0, 0, 0, 0, 69, 0, 0, 0,
+  0, 14, 0, 40, 0, 14, 0, 40, 23, 88,
+  0, 29, 0, 18, 0, 24, 66, 1, 4, 0,
+  0, 0, 0, 0, 30, 14, 0, 50, 0, 7,
+  42, 0, 37, 0, 0, 0, 0, 48, 16, 0,
+  58, 78, 0, 0, 60, 0, 43, 4, 0, 14,
+  12, 0, 0, 2, 0, 24, 0, 6, 0, 25,
+  4, 0, 5, 84, 38, 0, 0, 3, 48, 0,
+  12, 5, 0, 1, 0, 12, 0, 2, 0, 0,
+  15, 0, 12, 0, 16, 0, 60, 0, 26, 0,
+  25, 0, 1, 12, 0, 19, 0, 115, 0, 0,
+  17, 0, 0, 0, 0, 1, 0, 0, 0, 28,
+  11, 16, 0, 65, 2, 0, 0, 0, 23, 0,
+  0, 0, 0, 17, 8, 0, 9, 65, 12, 45,
+  5, 0, 48, 0, 0, 18, 0, 33, 46, 0,
+  0, 7, 0, 29, 0, 0, 131, 59, 54, 5,
+  43, 0, 0, 107, 51, 0, 166, 0, 0, 46,
+  0, 112, 193, 0, 44, 0, 0, 35, 0, 0,
+  29, 0, 0, 0, 32, 0, 28, 0, 0, 1,
+  14, 0, 0, 79, 16, 0, 38, 0, 0, 0,
+  3, 61, 47, 127, 0, 0, 0, 0, 0, 36,
+  0, 0, 0, 55, 0, 53, 0, 0, 0, 0,
+  47, 0, 0, 0, 0, 0, 13, 18, 0, 12,
+  0, 1, 0, 0, 0, 57, 0, 18, 70, 15,
+  0, 4, 0, 0, 0, 50, 13, 20, 0, 0,
+  47, 47, 29, 12, 0, 0, 0, 10, 0, 0,
+  0, 0, 50, 0, 0, 44, 0, 64, 0, 0,
+  54, 0, 0, 47, 0, 99, 16, 46, 0, 15,
+  0, 37, 0, 0, 63, 0, 74, 0, 64, 0,
+  0, 62, 0, 0, 90, 0, 0, 12, 30, 23,
+  61, 0, 70, 60, 0, 76, 0, 1, 0, 0,
+  21, 0, 0, 0, 0, 0, 8, 0, 5, 0,
+  0, 121, 9, 0, 0, 0, 0, 0, 20, 54,
+  116, 17, 0, 0, 0, 0, 11, 9, 0, 21,
+  0, 19, 0, 73, 0, 0, 0, 0, 56, 0,
+  53, 0, 0, 0, 21, 0, 18, 0, 0, 48,
+  16, 0, 0, 0, 50, 44, 75, 3, 3, 42,
+  110, 0, 16, 61, 79, 13, 2, 0, 31, 54,
+  4, 6, 49, 0, 0, 45, 0, 0, 0, 0,
+  83, 0, 2, 0, 0, 62, 0, 80, 0, 35,
+  4, 49, 18, 97, 6, 35, 0, 42, 0, 40,
+  48, 0, 23, 0, 3, 0, 0, 0, 0, 5,
+  0, 59, 0, 17, 20, 0, 40, 0, 0, 0,
+  0, 48, 8, 0, 29, 54, 0, 0, 33, 0,
+  42, 5, 0, 9, 4, 0, 0, 8, 0, 4,
+  0, 44, 0, 13, 5, 8, 15, 84, 41, 0,
+  0, 0, 34, 0, 24, 13, 4, 22, 0, 21,
+  0, 22, 0, 0, 0, 0, 35, 0, 31, 0,
+  111, 0, 71, 0, 32, 0, 21, 77, 0, 54,
+  0, 57, 1, 0, 24, 0, 0, 9, 43, 0,
+  0, 0, 0, 20, 47, 27, 0, 27, 1, 0,
+  0, 0, 69, 0, 0, 0, 4, 19, 15, 0,
+  32, 49, 0, 0, 3, 0, 0, 7, 0, 34,
+  8, 10, 16, 0, 0, 0, 3, 45, 0, 0,
+  93, 35, 51, 0, 0, 0, 0, 53, 20, 0,
+  103, 0, 0, 43, 0, 68, 175, 29, 22, 0,
+  0, 35, 0, 61, 4, 6, 0, 0, 64, 5,
+  21, 0, 0, 19, 51, 0, 81, 0, 0, 0,
+  7, 0, 55, 0, 12, 95, 28, 106, 1, 0,
+  0, 0, 4, 67, 71, 0, 2, 16, 0, 39,
+  0, 0, 0, 0, 25, 0, 0, 0, 0, 18,
+  65, 17, 0, 0, 0, 0, 0, 25, 0, 135,
+  0, 7, 42, 0, 0, 4, 0, 6, 0, 0,
+  0, 25, 13, 0, 41, 106, 15, 0, 0, 0,
+  0, 1, 0, 0, 0, 1, 9, 0, 0, 82,
+  0, 40, 0, 0, 45, 0, 0, 46, 0, 80,
+  0, 4, 0, 0, 0, 52, 0, 0, 133, 36,
+  44, 0, 57, 0, 0, 92, 42, 0, 155, 0,
+  0, 30, 0, 77, 196, 0, 59, 34, 0, 31,
+  0, 16, 9, 0, 0, 0, 35, 0, 0, 0,
+  1, 0, 11, 0, 0, 92, 0, 0, 27, 0,
+  0, 0, 7, 76, 78, 108, 0, 0, 0, 0,
+  0, 30, 0, 0, 0, 38, 0, 95, 0, 0,
+  0, 0, 52, 0, 0, 0, 0, 0, 21, 0,
+  0, 6, 0, 28, 0, 8, 0, 24, 24, 29,
+  104, 12, 0, 37, 106, 0, 0, 105, 62, 22,
+  0, 0, 41, 62, 0, 12, 2, 0, 0, 43,
+  0, 0, 0, 0, 76, 0, 33, 0, 0, 91,
+  0, 53, 32, 0, 4, 39, 5, 115, 2, 34,
+  0, 36, 0, 56, 16, 0, 56, 0, 6, 0,
+  36, 0, 0, 14, 0, 21, 0, 0, 0, 0,
+  27, 0, 37, 0, 47, 52, 0, 14, 8, 31,
+  0, 0, 8, 0, 29, 0, 0, 10, 11, 0,
+  20, 0, 0, 68, 0, 34, 0, 0, 0, 0,
+  26, 84, 90, 0, 0, 0, 22, 0, 15, 31,
+  0, 34, 0, 30, 0, 52, 0, 0, 0, 0,
+  60, 0, 39, 0, 79, 0, 69, 0, 34, 16,
+  0, 34, 21, 0, 0, 0, 48, 33, 91, 15,
+  14, 16, 57, 1, 0, 81, 49, 0, 0, 0,
+  6, 20, 26, 30, 1, 0, 0, 23, 0, 0,
+  0, 0, 60, 0, 3, 0, 0, 56, 0, 42,
+  4, 5, 0, 43, 0, 101, 57, 64, 0, 36,
+  0, 14, 67, 0, 0, 0, 60, 0, 18, 0,
+  6, 36, 0, 46, 0, 0, 0, 0, 80, 0,
+  0, 0, 27, 50, 26, 48, 16, 11, 0, 0,
+  59, 0, 25, 0, 0, 9, 9, 3, 5, 0,
+  0, 63, 0, 14, 0, 0, 0, 0, 4, 79,
+  88, 0, 0, 0, 17, 0, 30, 2, 0, 51,
+  0, 7, 0, 20, 0, 0, 0, 31, 77, 0,
+  50, 0, 85, 0, 42, 0, 14, 0, 0, 27,
+  0, 6, 0, 0, 33, 17, 40, 0, 12, 29,
+  62, 0, 14, 33, 65, 28, 0, 0, 26, 32,
+  26, 12, 42, 0, 0, 27, 0, 0, 0, 0,
+  69, 0, 0, 0, 0, 14, 0, 40, 0, 14,
+  0, 40, 23, 88, 0, 29, 0, 18, 0, 24,
+  66, 1, 4, 0, 0, 0, 0, 0, 30, 14,
+  0, 50, 0, 7, 42, 0, 37, 0, 0, 0,
+  0, 48, 16, 0, 58, 78, 0, 0, 60, 0,
+  43, 4, 0, 14, 12, 0, 0, 2, 0, 24,
+  0, 6, 0, 25, 4, 0, 5, 84, 38, 0,
+  0, 3, 48, 0, 12, 5, 0, 1, 0, 12,
+  0, 2, 0, 0, 15, 0, 12, 0, 16, 0,
+  60, 0, 26, 0, 25, 0, 32, 14, 0, 17,
+  0, 0, 0, 0, 0, 0, 1, 1, 16, 0,
+  0, 0, 49, 11, 3, 0, 0, 29, 0, 16,
+  72, 0, 37, 30, 0, 0, 0, 15, 79, 12,
+  0, 0, 0, 13, 41, 0, 0, 0, 0, 11,
+  0, 105, 32, 28, 0, 0, 0, 8, 36, 0,
+  22, 20, 3, 0, 0, 0, 87, 22, 0, 54,
+  0, 0, 130, 30, 67, 49, 31, 0, 0, 36,
+  0, 0, 48, 46, 0, 0, 36, 0, 58, 28,
+  0, 42, 0, 0, 0, 0, 0, 73, 0, 0,
+  0, 0, 0, 0, 0, 113, 49, 57, 10, 33,
+  35, 37, 0, 0, 24, 0, 0, 52, 0, 0,
+  0, 0, 4, 0, 10, 0, 8, 0, 23, 0,
+  0, 0, 31, 19, 0, 1, 0, 0, 0, 57,
+  0, 18, 70, 15, 0, 4, 0, 0, 0, 50,
+  13, 20, 0, 0, 47, 47, 29, 12, 0, 0,
+  0, 10, 0, 0, 0, 0, 50, 0, 0, 44,
+  0, 64, 0, 0, 54, 0, 0, 47, 0, 99,
+  16, 46, 0, 15, 0, 37, 0, 0, 63, 0,
+  74, 0, 64, 0, 0, 62, 0, 0, 90, 0,
+  0, 12, 30, 23, 61, 0, 70, 60, 0, 76,
+  0, 1, 0, 0, 21, 0, 0, 0, 0, 0,
+  8, 0, 5, 0, 0, 121, 9, 0, 0, 0,
+  0, 0, 20, 54, 116, 17, 0, 0, 0, 0,
+  11, 9, 0, 21, 0, 19, 0, 73, 0, 0,
+  0, 0, 56, 0, 53, 0, 0, 0, 21, 0,
+  18, 0, 0, 48, 16, 0, 0, 0, 50, 44,
+  75, 3, 3, 42, 110, 0, 16, 61, 79, 13,
+  2, 0, 31, 54, 4, 6, 49, 0, 0, 45,
+  0, 0, 0, 0, 83, 0, 2, 0, 0, 62,
+  0, 80, 0, 35, 4, 49, 18, 97, 6, 35,
+  0, 42, 0, 40, 48, 0, 23, 0, 3, 0,
+  0, 0, 0, 5, 0, 59, 0, 17, 20, 0,
+  40, 0, 0, 0, 0, 48, 8, 0, 29, 54,
+  0, 0, 33, 0, 42, 5, 0, 9, 4, 0,
+  0, 8, 0, 4, 0, 44, 0, 13, 5, 8,
+  15, 84, 41, 0, 0, 0, 34, 0, 24, 13,
+  4, 22, 0, 21, 0, 22, 0, 0, 0, 0,
+  35, 0, 31, 0, 111, 0, 71, 0, 32, 0,
+  3, 37, 0, 0, 14, 0, 32, 0, 0, 0,
+  3, 23, 56, 0, 0, 4, 62, 15, 4, 0,
+  0, 72, 0, 17, 107, 0, 0, 48, 0, 0,
+  0, 48, 90, 0, 0, 0, 0, 51, 43, 7,
+  0, 46, 21, 29, 25, 100, 41, 0, 0, 5,
+  0, 0, 5, 0, 27, 0, 7, 0, 20, 2,
+  58, 63, 0, 50, 0, 0, 97, 52, 73, 0,
+  0, 0, 9, 20, 30, 0, 53, 59, 0, 0,
+  0, 0, 39, 57, 10, 31, 0, 0, 0, 14,
+  0, 0, 0, 54, 0, 21, 0, 18, 0, 113,
+  24, 11, 22, 20, 39, 43, 10, 0, 43, 0,
+  0, 50, 0, 0, 0, 0, 10, 1, 48, 0,
+  7, 0, 27, 0, 30, 0, 30, 47, 0, 0,
+  0, 25, 0, 135, 0, 7, 42, 0, 0, 4,
+  0, 6, 0, 0, 0, 25, 13, 0, 41, 106,
+  15, 0, 0, 0, 0, 1, 0, 0, 0, 1,
+  9, 0, 0, 82, 0, 40, 0, 0, 45, 0,
+  0, 46, 0, 80, 0, 4, 0, 0, 0, 52,
+  0, 0, 133, 36, 44, 0, 57, 0, 0, 92,
+  42, 0, 155, 0, 0, 30, 0, 77, 196, 0,
+  59, 34, 0, 31, 0, 16, 9, 0, 0, 0,
+  35, 0, 0, 0, 1, 0, 11, 0, 0, 92,
+  0, 0, 27, 0, 0, 0, 7, 76, 78, 108,
+  0, 0, 0, 0, 0, 30, 0, 0, 0, 38,
+  0, 95, 0, 0, 0, 0, 52, 0, 0, 0,
+  0, 0, 21, 0, 0, 6, 0, 28, 0, 8,
+  0, 24, 24, 29, 104, 12, 0, 37, 106, 0,
+  0, 105, 62, 22, 0, 0, 41, 62, 0, 12,
+  2, 0, 0, 43, 0, 0, 0, 0, 76, 0,
+  33, 0, 0, 91, 0, 53, 32, 0, 4, 39,
+  5, 115, 2, 34, 0, 36, 0, 56, 16, 0,
+  56, 0, 6, 0, 36, 0, 0, 14, 0, 21,
+  0, 0, 0, 0, 27, 0, 37, 0, 47, 52,
+  0, 14, 8, 31, 0, 0, 8, 0, 29, 0,
+  0, 10, 11, 0, 20, 0, 0, 68, 0, 34,
+  0, 0, 0, 0, 26, 84, 90, 0, 0, 0,
+  22, 0, 15, 31, 0, 34, 0, 30, 0, 52,
+  0, 0, 0, 0, 60, 0, 39, 0, 79, 0,
+  69, 0, 34, 16, 0, 39, 58, 0, 0, 0,
+  35, 20, 76, 0, 11, 39, 97, 0, 0, 94,
+  63, 17, 0, 0, 0, 47, 11, 21, 63, 0,
+  0, 58, 0, 0, 0, 24, 97, 0, 27, 0,
+  0, 89, 26, 22, 38, 4, 46, 33, 23, 117,
+  42, 0, 0, 22, 0, 0, 14, 0, 32, 0,
+  5, 0, 47, 0, 0, 49, 0, 19, 0, 0,
+  17, 1, 30, 0, 0, 0, 56, 43, 10, 31,
+  22, 65, 0, 0, 6, 0, 19, 88, 0, 42,
+  0, 0, 0, 23, 0, 11, 0, 31, 0, 0,
+  0, 0, 0, 85, 98, 0, 0, 0, 13, 0,
+  31, 29, 0, 24, 0, 19, 0, 5, 0, 0,
+  0, 12, 70, 0, 0, 0, 32, 0, 63, 0,
+  24, 34, 0, 27, 0, 6, 0, 0, 33, 17,
+  40, 0, 12, 29, 62, 0, 14, 33, 65, 28,
+  0, 0, 26, 32, 26, 12, 42, 0, 0, 27,
+  0, 0, 0, 0, 69, 0, 0, 0, 0, 14,
+  0, 40, 0, 14, 0, 40, 23, 88, 0, 29,
+  0, 18, 0, 24, 66, 1, 4, 0, 0, 0,
+  0, 0, 30, 14, 0, 50, 0, 7, 42, 0,
+  37, 0, 0, 0, 0, 48, 16, 0, 58, 78,
+  0, 0, 60, 0, 43, 4, 0, 14, 12, 0,
+  0, 2, 0, 24, 0, 6, 0, 25, 4, 0,
+  5, 84, 38, 0, 0, 3, 48, 0, 12, 5,
+  0, 1, 0, 12, 0, 2, 0, 0, 15, 0,
+  12, 0, 16, 0, 60, 0, 26, 0, 25, 0,
+  32, 14, 0, 17, 0, 0, 0, 0, 0, 0,
+  1, 1, 16, 0, 0, 0, 49, 11, 3, 0,
+  0, 29, 0, 16, 72, 0, 37, 30, 0, 0,
+  0, 15, 79, 12, 0, 0, 0, 13, 41, 0,
+  0, 0, 0, 11, 0, 105, 32, 28, 0, 0,
+  0, 8, 36, 0, 22, 20, 3, 0, 0, 0,
+  87, 22, 0, 54, 0, 0, 130, 30, 67, 49,
+  31, 0, 0, 36, 0, 0, 48, 46, 0, 0,
+  36, 0, 58, 28, 0, 42, 0, 0, 0, 0,
+  0, 73, 0, 0, 0, 0, 0, 0, 0, 113,
+  49, 57, 10, 33, 35, 37, 0, 0, 24, 0,
+  0, 52, 0, 0, 0, 0, 4, 0, 10, 0,
+  8, 0, 23, 0, 0, 0, 31, 19, 12, 13,
+  0, 21, 6, 5, 0, 0, 11, 0, 0, 0,
+  48, 0, 0, 18, 58, 12, 0, 0, 0, 8,
+  0, 28, 33, 0, 31, 20, 0, 0, 0, 2,
+  67, 50, 0, 0, 0, 26, 49, 0, 0, 0,
+  0, 31, 0, 97, 52, 74, 0, 0, 0, 36,
+  26, 0, 0, 44, 0, 0, 0, 0, 64, 9,
+  0, 12, 0, 0, 87, 26, 88, 48, 67, 0,
+  0, 16, 0, 0, 28, 0, 0, 0, 33, 0,
+  46, 22, 0, 32, 0, 0, 2, 0, 0, 84,
+  0, 0, 12, 0, 0, 0, 1, 115, 49, 54,
+  0, 40, 17, 26, 0, 0, 9, 0, 0, 49,
+  0, 16, 0, 0, 0, 0, 29, 0, 1, 0,
+  46, 0, 0, 0, 33, 16, 0, 48, 16, 0,
+  0, 0, 50, 44, 75, 3, 3, 42, 110, 0,
+  16, 61, 79, 13, 2, 0, 31, 54, 4, 6,
+  49, 0, 0, 45, 0, 0, 0, 0, 83, 0,
+  2, 0, 0, 62, 0, 80, 0, 35, 4, 49,
+  18, 97, 6, 35, 0, 42, 0, 40, 48, 0,
+  23, 0, 3, 0, 0, 0, 0, 5, 0, 59,
+  0, 17, 20, 0, 40, 0, 0, 0, 0, 48,
+  8, 0, 29, 54, 0, 0, 33, 0, 42, 5,
+  0, 9, 4, 0, 0, 8, 0, 4, 0, 44,
+  0, 13, 5, 8, 15, 84, 41, 0, 0, 0,
+  34, 0, 24, 13, 4, 22, 0, 21, 0, 22,
+  0, 0, 0, 0, 35, 0, 31, 0, 111, 0,
+  71, 0, 32, 0, 3, 37, 0, 0, 14, 0,
+  32, 0, 0, 0, 3, 23, 56, 0, 0, 4,
+  62, 15, 4, 0, 0, 72, 0, 17, 107, 0,
+  0, 48, 0, 0, 0, 48, 90, 0, 0, 0,
+  0, 51, 43, 7, 0, 46, 21, 29, 25, 100,
+  41, 0, 0, 5, 0, 0, 5, 0, 27, 0,
+  7, 0, 20, 2, 58, 63, 0, 50, 0, 0,
+  97, 52, 73, 0, 0, 0, 9, 20, 30, 0,
+  53, 59, 0, 0, 0, 0, 39, 57, 10, 31,
+  0, 0, 0, 14, 0, 0, 0, 54, 0, 21,
+  0, 18, 0, 113, 24, 11, 22, 20, 39, 43,
+  10, 0, 43, 0, 0, 50, 0, 0, 0, 0,
+  10, 1, 48, 0, 7, 0, 27, 0, 30, 0,
+  30, 47, 0, 22, 0, 0, 13, 12, 20, 0,
+  30, 0, 12, 20, 47, 4, 0, 16, 61, 0,
+  3, 0, 0, 56, 0, 10, 36, 0, 0, 41,
+  0, 0, 2, 0, 51, 24, 0, 0, 0, 75,
+  57, 0, 0, 1, 0, 46, 0, 115, 40, 68,
+  0, 0, 0, 16, 0, 0, 30, 32, 30, 0,
+  49, 0, 37, 54, 0, 31, 7, 0, 25, 63,
+  98, 0, 89, 0, 26, 32, 28, 22, 29, 0,
+  0, 0, 0, 0, 23, 34, 22, 43, 0, 13,
+  0, 0, 0, 67, 0, 29, 0, 0, 0, 0,
+  28, 122, 64, 34, 0, 28, 14, 55, 5, 5,
+  0, 0, 0, 59, 0, 9, 0, 5, 0, 38,
+  80, 0, 0, 0, 7, 0, 12, 0, 22, 22,
+  0, 28, 0, 8, 0, 24, 24, 29, 104, 12,
+  0, 37, 106, 0, 0, 105, 62, 22, 0, 0,
+  41, 62, 0, 12, 2, 0, 0, 43, 0, 0,
+  0, 0, 76, 0, 33, 0, 0, 91, 0, 53,
+  32, 0, 4, 39, 5, 115, 2, 34, 0, 36,
+  0, 56, 16, 0, 56, 0, 6, 0, 36, 0,
+  0, 14, 0, 21, 0, 0, 0, 0, 27, 0,
+  37, 0, 47, 52, 0, 14, 8, 31, 0, 0,
+  8, 0, 29, 0, 0, 10, 11, 0, 20, 0,
+  0, 68, 0, 34, 0, 0, 0, 0, 26, 84,
+  90, 0, 0, 0, 22, 0, 15, 31, 0, 34,
+  0, 30, 0, 52, 0, 0, 0, 0, 60, 0,
+  39, 0, 79, 0, 69, 0, 34, 16, 0, 39,
+  58, 0, 0, 0, 35, 20, 76, 0, 11, 39,
+  97, 0, 0, 94, 63, 17, 0, 0, 0, 47,
+  11, 21, 63, 0, 0, 58, 0, 0, 0, 24,
+  97, 0, 27, 0, 0, 89, 26, 22, 38, 4,
+  46, 33, 23, 117, 42, 0, 0, 22, 0, 0,
+  14, 0, 32, 0, 5, 0, 47, 0, 0, 49,
+  0, 19, 0, 0, 17, 1, 30, 0, 0, 0,
+  56, 43, 10, 31, 22, 65, 0, 0, 6, 0,
+  19, 88, 0, 42, 0, 0, 0, 23, 0, 11,
+  0, 31, 0, 0, 0, 0, 0, 85, 98, 0,
+  0, 0, 13, 0, 31, 29, 0, 24, 0, 19,
+  0, 5, 0, 0, 0, 12, 70, 0, 0, 0,
+  32, 0, 63, 0, 24, 34, 0, 10, 0, 0,
+  0, 0, 0, 1, 32, 2, 16, 56, 0, 30,
+  0, 9, 3, 0, 2, 0, 1, 27, 71, 20,
+  5, 0, 0, 23, 0, 18, 0, 0, 30, 0,
+  15, 0, 59, 84, 34, 0, 85, 0, 0, 5,
+  0, 98, 39, 10, 0, 0, 0, 0, 0, 0,
+  57, 0, 55, 0, 96, 0, 0, 81, 9, 12,
+  28, 9, 50, 46, 29, 21, 0, 0, 85, 58,
+  7, 94, 37, 18, 0, 0, 0, 22, 0, 74,
+  0, 50, 11, 36, 0, 0, 0, 84, 19, 16,
+  0, 0, 0, 0, 17, 49, 89, 0, 0, 0,
+  0, 27, 5, 0, 0, 3, 0, 9, 0, 9,
+  21, 75, 0, 33, 64, 0, 0, 0, 0, 0,
+  0, 0, 0, 41, 32, 14, 0, 17, 0, 0,
+  0, 0, 0, 0, 1, 1, 16, 0, 0, 0,
+  49, 11, 3, 0, 0, 29, 0, 16, 72, 0,
+  37, 30, 0, 0, 0, 15, 79, 12, 0, 0,
+  0, 13, 41, 0, 0, 0, 0, 11, 0, 105,
+  32, 28, 0, 0, 0, 8, 36, 0, 22, 20,
+  3, 0, 0, 0, 87, 22, 0, 54, 0, 0,
+  130, 30, 67, 49, 31, 0, 0, 36, 0, 0,
+  48, 46, 0, 0, 36, 0, 58, 28, 0, 42,
+  0, 0, 0, 0, 0, 73, 0, 0, 0, 0,
+  0, 0, 0, 113, 49, 57, 10, 33, 35, 37,
+  0, 0, 24, 0, 0, 52, 0, 0, 0, 0,
+  4, 0, 10, 0, 8, 0, 23, 0, 0, 0,
+  31, 19, 12, 13, 0, 21, 6, 5, 0, 0,
+  11, 0, 0, 0, 48, 0, 0, 18, 58, 12,
+  0, 0, 0, 8, 0, 28, 33, 0, 31, 20,
+  0, 0, 0, 2, 67, 50, 0, 0, 0, 26,
+  49, 0, 0, 0, 0, 31, 0, 97, 52, 74,
+  0, 0, 0, 36, 26, 0, 0, 44, 0, 0,
+  0, 0, 64, 9, 0, 12, 0, 0, 87, 26,
+  88, 48, 67, 0, 0, 16, 0, 0, 28, 0,
+  0, 0, 33, 0, 46, 22, 0, 32, 0, 0,
+  2, 0, 0, 84, 0, 0, 12, 0, 0, 0,
+  1, 115, 49, 54, 0, 40, 17, 26, 0, 0,
+  9, 0, 0, 49, 0, 16, 0, 0, 0, 0,
+  29, 0, 1, 0, 46, 0, 0, 0, 33, 16,
+  0, 98, 0, 20, 14, 0, 60, 12, 44, 16,
+  32, 0, 54, 0, 44, 107, 104, 30, 6, 0,
+  0, 0, 0, 40, 41, 45, 0, 53, 0, 0,
+  0, 0, 87, 64, 0, 0, 0, 27, 0, 41,
+  0, 0, 16, 28, 30, 44, 24, 53, 0, 28,
+  0, 0, 87, 10, 0, 0, 0, 14, 0, 58,
+  10, 0, 0, 24, 0, 0, 75, 0, 41, 0,
+  0, 0, 0, 48, 17, 40, 0, 0, 0, 12,
+  73, 0, 9, 26, 0, 32, 2, 2, 0, 43,
+  49, 36, 0, 65, 0, 26, 0, 0, 0, 86,
+  27, 0, 0, 0, 9, 0, 28, 10, 24, 30,
+  0, 17, 0, 27, 0, 0, 0, 0, 2, 0,
+  8, 0, 164, 0, 52, 9, 40, 0, 3, 37,
+  0, 0, 14, 0, 32, 0, 0, 0, 3, 23,
+  56, 0, 0, 4, 62, 15, 4, 0, 0, 72,
+  0, 17, 107, 0, 0, 48, 0, 0, 0, 48,
+  90, 0, 0, 0, 0, 51, 43, 7, 0, 46,
+  21, 29, 25, 100, 41, 0, 0, 5, 0, 0,
+  5, 0, 27, 0, 7, 0, 20, 2, 58, 63,
+  0, 50, 0, 0, 97, 52, 73, 0, 0, 0,
+  9, 20, 30, 0, 53, 59, 0, 0, 0, 0,
+  39, 57, 10, 31, 0, 0, 0, 14, 0, 0,
+  0, 54, 0, 21, 0, 18, 0, 113, 24, 11,
+  22, 20, 39, 43, 10, 0, 43, 0, 0, 50,
+  0, 0, 0, 0, 10, 1, 48, 0, 7, 0,
+  27, 0, 30, 0, 30, 47, 0, 22, 0, 0,
+  13, 12, 20, 0, 30, 0, 12, 20, 47, 4,
+  0, 16, 61, 0, 3, 0, 0, 56, 0, 10,
+  36, 0, 0, 41, 0, 0, 2, 0, 51, 24,
+  0, 0, 0, 75, 57, 0, 0, 1, 0, 46,
+  0, 115, 40, 68, 0, 0, 0, 16, 0, 0,
+  30, 32, 30, 0, 49, 0, 37, 54, 0, 31,
+  7, 0, 25, 63, 98, 0, 89, 0, 26, 32,
+  28, 22, 29, 0, 0, 0, 0, 0, 23, 34,
+  22, 43, 0, 13, 0, 0, 0, 67, 0, 29,
+  0, 0, 0, 0, 28, 122, 64, 34, 0, 28,
+  14, 55, 5, 5, 0, 0, 0, 59, 0, 9,
+  0, 5, 0, 38, 80, 0, 0, 0, 7, 0,
+  12, 0, 22, 22, 0, 49, 0, 0, 0, 0,
+  12, 0, 80, 43, 25, 0, 73, 2, 0, 149,
+  100, 43, 17, 0, 0, 0, 0, 25, 0, 0,
+  21, 90, 9, 0, 9, 0, 115, 13, 0, 0,
+  4, 73, 0, 0, 23, 0, 0, 26, 0, 80,
+  0, 54, 0, 37, 0, 15, 61, 0, 0, 23,
+  13, 7, 0, 32, 0, 0, 0, 0, 0, 0,
+  27, 12, 61, 0, 7, 0, 0, 98, 0, 66,
+  0, 13, 0, 0, 19, 3, 24, 48, 0, 47,
+  3, 23, 13, 19, 53, 124, 0, 32, 23, 0,
+  0, 0, 0, 90, 142, 0, 0, 0, 8, 0,
+  0, 33, 0, 34, 0, 47, 0, 22, 0, 0,
+  0, 0, 6, 0, 0, 0, 122, 0, 29, 0,
+  52, 16, 0, 39, 58, 0, 0, 0, 35, 20,
+  76, 0, 11, 39, 97, 0, 0, 94, 63, 17,
+  0, 0, 0, 47, 11, 21, 63, 0, 0, 58,
+  0, 0, 0, 24, 97, 0, 27, 0, 0, 89,
+  26, 22, 38, 4, 46, 33, 23, 117, 42, 0,
+  0, 22, 0, 0, 14, 0, 32, 0, 5, 0,
+  47, 0, 0, 49, 0, 19, 0, 0, 17, 1,
+  30, 0, 0, 0, 56, 43, 10, 31, 22, 65,
+  0, 0, 6, 0, 19, 88, 0, 42, 0, 0,
+  0, 23, 0, 11, 0, 31, 0, 0, 0, 0,
+  0, 85, 98, 0, 0, 0, 13, 0, 31, 29,
+  0, 24, 0, 19, 0, 5, 0, 0, 0, 12,
+  70, 0, 0, 0, 32, 0, 63, 0, 24, 34,
+  0, 10, 0, 0, 0, 0, 0, 1, 32, 2,
+  16, 56, 0, 30, 0, 9, 3, 0, 2, 0,
+  1, 27, 71, 20, 5, 0, 0, 23, 0, 18,
+  0, 0, 30, 0, 15, 0, 59, 84, 34, 0,
+  85, 0, 0, 5, 0, 98, 39, 10, 0, 0,
+  0, 0, 0, 0, 57, 0, 55, 0, 96, 0,
+  0, 81, 9, 12, 28, 9, 50, 46, 29, 21,
+  0, 0, 85, 58, 7, 94, 37, 18, 0, 0,
+  0, 22, 0, 74, 0, 50, 11, 36, 0, 0,
+  0, 84, 19, 16, 0, 0, 0, 0, 17, 49,
+  89, 0, 0, 0, 0, 27, 5, 0, 0, 3,
+  0, 9, 0, 9, 21, 75, 0, 33, 64, 0,
+  0, 0, 0, 0, 0, 0, 0, 41, 4, 18,
+  11, 6, 0, 0, 0, 0, 60, 44, 0, 0,
+  0, 54, 0, 0, 0, 29, 17, 0, 3, 11,
+  34, 17, 0, 0, 58, 48, 0, 0, 0, 0,
+  53, 0, 0, 0, 74, 109, 0, 0, 46, 0,
+  0, 0, 0, 59, 0, 51, 0, 23, 0, 0,
+  0, 0, 78, 7, 34, 8, 0, 0, 0, 52,
+  29, 14, 74, 2, 53, 17, 8, 144, 9, 0,
+  46, 89, 0, 57, 27, 0, 12, 0, 0, 0,
+  31, 87, 0, 30, 0, 43, 20, 0, 0, 171,
+  0, 0, 22, 0, 7, 0, 0, 57, 123, 33,
+  0, 0, 0, 0, 0, 2, 0, 0, 0, 24,
+  0, 10, 20, 24, 0, 0, 14, 0, 0, 0,
+  0, 0, 0, 4, 58, 62, 12, 13, 0, 21,
+  6, 5, 0, 0, 11, 0, 0, 0, 48, 0,
+  0, 18, 58, 12, 0, 0, 0, 8, 0, 28,
+  33, 0, 31, 20, 0, 0, 0, 2, 67, 50,
+  0, 0, 0, 26, 49, 0, 0, 0, 0, 31,
+  0, 97, 52, 74, 0, 0, 0, 36, 26, 0,
+  0, 44, 0, 0, 0, 0, 64, 9, 0, 12,
+  0, 0, 87, 26, 88, 48, 67, 0, 0, 16,
+  0, 0, 28, 0, 0, 0, 33, 0, 46, 22,
+  0, 32, 0, 0, 2, 0, 0, 84, 0, 0,
+  12, 0, 0, 0, 1, 115, 49, 54, 0, 40,
+  17, 26, 0, 0, 9, 0, 0, 49, 0, 16,
+  0, 0, 0, 0, 29, 0, 1, 0, 46, 0,
+  0, 0, 33, 16, 0, 98, 0, 20, 14, 0,
+  60, 12, 44, 16, 32, 0, 54, 0, 44, 107,
+  104, 30, 6, 0, 0, 0, 0, 40, 41, 45,
+  0, 53, 0, 0, 0, 0, 87, 64, 0, 0,
+  0, 27, 0, 41, 0, 0, 16, 28, 30, 44,
+  24, 53, 0, 28, 0, 0, 87, 10, 0, 0,
+  0, 14, 0, 58, 10, 0, 0, 24, 0, 0,
+  75, 0, 41, 0, 0, 0, 0, 48, 17, 40,
+  0, 0, 0, 12, 73, 0, 9, 26, 0, 32,
+  2, 2, 0, 43, 49, 36, 0, 65, 0, 26,
+  0, 0, 0, 86, 27, 0, 0, 0, 9, 0,
+  28, 10, 24, 30, 0, 17, 0, 27, 0, 0,
+  0, 0, 2, 0, 8, 0, 164, 0, 52, 9,
+  40, 0, 0, 111, 49, 4, 4, 0, 0, 13,
+  78, 36, 24, 0, 20, 0, 0, 97, 83, 24,
+  24, 5, 0, 0, 48, 50, 0, 0, 1, 78,
+  1, 0, 0, 0, 68, 0, 12, 0, 0, 28,
+  0, 3, 0, 0, 11, 19, 11, 36, 0, 0,
+  0, 29, 0, 18, 44, 0, 0, 0, 1, 0,
+  0, 8, 0, 0, 0, 0, 0, 0, 29, 0,
+  0, 0, 0, 0, 32, 72, 9, 90, 0, 112,
+  2, 20, 35, 0, 0, 53, 0, 31, 6, 61,
+  21, 24, 117, 0, 0, 0, 26, 0, 0, 0,
+  0, 100, 90, 0, 0, 0, 7, 0, 54, 21,
+  0, 21, 0, 0, 0, 15, 0, 0, 0, 0,
+  0, 21, 0, 0, 73, 0, 76, 10, 35, 0,
+  0, 22, 0, 0, 13, 12, 20, 0, 30, 0,
+  12, 20, 47, 4, 0, 16, 61, 0, 3, 0,
+  0, 56, 0, 10, 36, 0, 0, 41, 0, 0,
+  2, 0, 51, 24, 0, 0, 0, 75, 57, 0,
+  0, 1, 0, 46, 0, 115, 40, 68, 0, 0,
+  0, 16, 0, 0, 30, 32, 30, 0, 49, 0,
+  37, 54, 0, 31, 7, 0, 25, 63, 98, 0,
+  89, 0, 26, 32, 28, 22, 29, 0, 0, 0,
+  0, 0, 23, 34, 22, 43, 0, 13, 0, 0,
+  0, 67, 0, 29, 0, 0, 0, 0, 28, 122,
+  64, 34, 0, 28, 14, 55, 5, 5, 0, 0,
+  0, 59, 0, 9, 0, 5, 0, 38, 80, 0,
+  0, 0, 7, 0, 12, 0, 22, 22, 0, 49,
+  0, 0, 0, 0, 12, 0, 80, 43, 25, 0,
+  73, 2, 0, 149, 100, 43, 17, 0, 0, 0,
+  0, 25, 0, 0, 21, 90, 9, 0, 9, 0,
+  115, 13, 0, 0, 4, 73, 0, 0, 23, 0,
+  0, 26, 0, 80, 0, 54, 0, 37, 0, 15,
+  61, 0, 0, 23, 13, 7, 0, 32, 0, 0,
+  0, 0, 0, 0, 27, 12, 61, 0, 7, 0,
+  0, 98, 0, 66, 0, 13, 0, 0, 19, 3,
+  24, 48, 0, 47, 3, 23, 13, 19, 53, 124,
+  0, 32, 23, 0, 0, 0, 0, 90, 142, 0,
+  0, 0, 8, 0, 0, 33, 0, 34, 0, 47,
+  0, 22, 0, 0, 0, 0, 6, 0, 0, 0,
+  122, 0, 29, 0, 52, 16, 0, 27, 108, 0,
+  0, 0, 0, 0, 90, 42, 15, 0, 26, 53,
+  0, 84, 60, 35, 50, 0, 0, 15, 20, 31,
+  0, 0, 3, 111, 0, 0, 0, 0, 61, 0,
+  0, 0, 0, 79, 0, 0, 3, 0, 0, 0,
+  0, 28, 0, 0, 0, 35, 0, 82, 11, 0,
+  69, 0, 27, 18, 0, 0, 0, 0, 0, 0,
+  27, 0, 48, 0, 11, 70, 0, 0, 22, 90,
+  0, 69, 0, 68, 0, 0, 7, 0, 32, 92,
+  0, 47, 0, 58, 48, 0, 85, 34, 0, 0,
+  11, 0, 0, 0, 0, 133, 125, 0, 0, 0,
+  8, 0, 0, 61, 0, 16, 7, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 45, 0,
+  54, 0, 21, 46, 0, 10, 0, 0, 0, 0,
+  0, 1, 32, 2, 16, 56, 0, 30, 0, 9,
+  3, 0, 2, 0, 1, 27, 71, 20, 5, 0,
+  0, 23, 0, 18, 0, 0, 30, 0, 15, 0,
+  59, 84, 34, 0, 85, 0, 0, 5, 0, 98,
+  39, 10, 0, 0, 0, 0, 0, 0, 57, 0,
+  55, 0, 96, 0, 0, 81, 9, 12, 28, 9,
+  50, 46, 29, 21, 0, 0, 85, 58, 7, 94,
+  37, 18, 0, 0, 0, 22, 0, 74, 0, 50,
+  11, 36, 0, 0, 0, 84, 19, 16, 0, 0,
+  0, 0, 17, 49, 89, 0, 0, 0, 0, 27,
+  5, 0, 0, 3, 0, 9, 0, 9, 21, 75,
+  0, 33, 64, 0, 0, 0, 0, 0, 0, 0,
+  0, 41, 4, 18, 11, 6, 0, 0, 0, 0,
+  60, 44, 0, 0, 0, 54, 0, 0, 0, 29,
+  17, 0, 3, 11, 34, 17, 0, 0, 58, 48,
+  0, 0, 0, 0, 53, 0, 0, 0, 74, 109,
+  0, 0, 46, 0, 0, 0, 0, 59, 0, 51,
+  0, 23, 0, 0, 0, 0, 78, 7, 34, 8,
+  0, 0, 0, 52, 29, 14, 74, 2, 53, 17,
+  8, 144, 9, 0, 46, 89, 0, 57, 27, 0,
+  12, 0, 0, 0, 31, 87, 0, 30, 0, 43,
+  20, 0, 0, 171, 0, 0, 22, 0, 7, 0,
+  0, 57, 123, 33, 0, 0, 0, 0, 0, 2,
+  0, 0, 0, 24, 0, 10, 20, 24, 0, 0,
+  14, 0, 0, 0, 0, 0, 0, 4, 58, 62,
+  28, 0, 51, 0, 0, 127, 0, 0, 28, 13,
+  0, 0, 0, 82, 0, 0, 9, 29, 31, 0,
+  0, 85, 28, 32, 0, 0, 13, 55, 0, 0,
+  0, 43, 0, 0, 0, 17, 44, 93, 0, 0,
+  24, 0, 15, 0, 0, 32, 0, 29, 0, 35,
+  0, 77, 0, 0, 138, 0, 12, 0, 0, 0,
+  0, 64, 0, 0, 81, 0, 9, 6, 12, 125,
+  8, 0, 33, 55, 0, 39, 22, 0, 0, 0,
+  0, 0, 28, 82, 0, 10, 0, 46, 0, 0,
+  0, 123, 0, 0, 55, 0, 11, 0, 0, 88,
+  63, 49, 0, 0, 27, 0, 0, 10, 0, 6,
+  1, 11, 0, 0, 9, 35, 24, 0, 11, 0,
+  0, 0, 0, 0, 0, 3, 9, 79, 0, 98,
+  0, 20, 14, 0, 60, 12, 44, 16, 32, 0,
+  54, 0, 44, 107, 104, 30, 6, 0, 0, 0,
+  0, 40, 41, 45, 0, 53, 0, 0, 0, 0,
+  87, 64, 0, 0, 0, 27, 0, 41, 0, 0,
+  16, 28, 30, 44, 24, 53, 0, 28, 0, 0,
+  87, 10, 0, 0, 0, 14, 0, 58, 10, 0,
+  0, 24, 0, 0, 75, 0, 41, 0, 0, 0,
+  0, 48, 17, 40, 0, 0, 0, 12, 73, 0,
+  9, 26, 0, 32, 2, 2, 0, 43, 49, 36,
+  0, 65, 0, 26, 0, 0, 0, 86, 27, 0,
+  0, 0, 9, 0, 28, 10, 24, 30, 0, 17,
+  0, 27, 0, 0, 0, 0, 2, 0, 8, 0,
+  164, 0, 52, 9, 40, 0, 0, 111, 49, 4,
+  4, 0, 0, 13, 78, 36, 24, 0, 20, 0,
+  0, 97, 83, 24, 24, 5, 0, 0, 48, 50,
+  0, 0, 1, 78, 1, 0, 0, 0, 68, 0,
+  12, 0, 0, 28, 0, 3, 0, 0, 11, 19,
+  11, 36, 0, 0, 0, 29, 0, 18, 44, 0,
+  0, 0, 1, 0, 0, 8, 0, 0, 0, 0,
+  0, 0, 29, 0, 0, 0, 0, 0, 32, 72,
+  9, 90, 0, 112, 2, 20, 35, 0, 0, 53,
+  0, 31, 6, 61, 21, 24, 117, 0, 0, 0,
+  26, 0, 0, 0, 0, 100, 90, 0, 0, 0,
+  7, 0, 54, 21, 0, 21, 0, 0, 0, 15,
+  0, 0, 0, 0, 0, 21, 0, 0, 73, 0,
+  76, 10, 35, 0, 59, 1, 72, 42, 0, 0,
+  0, 22, 38, 13, 13, 6, 0, 7, 0, 21,
+  38, 13, 14, 0, 0, 64, 43, 11, 0, 0,
+  1, 54, 0, 38, 0, 39, 17, 0, 12, 19,
+  36, 29, 3, 0, 0, 0, 0, 0, 0, 11,
+  0, 0, 0, 0, 0, 70, 0, 0, 91, 0,
+  38, 0, 8, 0, 0, 4, 0, 0, 64, 10,
+  0, 0, 0, 114, 20, 0, 74, 27, 0, 45,
+  12, 51, 27, 0, 0, 0, 15, 101, 0, 21,
+  22, 36, 22, 0, 57, 0, 0, 0, 62, 0,
+  29, 0, 0, 72, 95, 0, 0, 0, 0, 80,
+  0, 16, 0, 0, 0, 13, 0, 0, 0, 0,
+  0, 0, 0, 33, 0, 3, 0, 0, 0, 0,
+  4, 22, 0, 49, 0, 0, 0, 0, 12, 0,
+  80, 43, 25, 0, 73, 2, 0, 149, 100, 43,
+  17, 0, 0, 0, 0, 25, 0, 0, 21, 90,
+  9, 0, 9, 0, 115, 13, 0, 0, 4, 73,
+  0, 0, 23, 0, 0, 26, 0, 80, 0, 54,
+  0, 37, 0, 15, 61, 0, 0, 23, 13, 7,
+  0, 32, 0, 0, 0, 0, 0, 0, 27, 12,
+  61, 0, 7, 0, 0, 98, 0, 66, 0, 13,
+  0, 0, 19, 3, 24, 48, 0, 47, 3, 23,
+  13, 19, 53, 124, 0, 32, 23, 0, 0, 0,
+  0, 90, 142, 0, 0, 0, 8, 0, 0, 33,
+  0, 34, 0, 47, 0, 22, 0, 0, 0, 0,
+  6, 0, 0, 0, 122, 0, 29, 0, 52, 16,
+  0, 27, 108, 0, 0, 0, 0, 0, 90, 42,
+  15, 0, 26, 53, 0, 84, 60, 35, 50, 0,
+  0, 15, 20, 31, 0, 0, 3, 111, 0, 0,
+  0, 0, 61, 0, 0, 0, 0, 79, 0, 0,
+  3, 0, 0, 0, 0, 28, 0, 0, 0, 35,
+  0, 82, 11, 0, 69, 0, 27, 18, 0, 0,
+  0, 0, 0, 0, 27, 0, 48, 0, 11, 70,
+  0, 0, 22, 90, 0, 69, 0, 68, 0, 0,
+  7, 0, 32, 92, 0, 47, 0, 58, 48, 0,
+  85, 34, 0, 0, 11, 0, 0, 0, 0, 133,
+  125, 0, 0, 0, 8, 0, 0, 61, 0, 16,
+  7, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 45, 0, 54, 0, 21, 46, 0, 0,
+  117, 0, 0, 75, 0, 0, 21, 0, 0, 1,
+  34, 80, 0, 0, 0, 31, 19, 0, 0, 94,
+  14, 24, 0, 0, 0, 29, 0, 0, 10, 39,
+  0, 0, 0, 0, 0, 56, 0, 0, 0, 0,
+  0, 7, 0, 0, 0, 0, 0, 0, 0, 155,
+  0, 0, 71, 0, 21, 0, 50, 0, 0, 5,
+  0, 0, 108, 0, 0, 0, 0, 98, 0, 0,
+  39, 7, 0, 0, 0, 22, 15, 0, 0, 0,
+  31, 74, 16, 3, 15, 30, 48, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 72, 30, 0,
+  0, 0, 0, 78, 0, 23, 0, 11, 40, 0,
+  0, 0, 17, 16, 68, 25, 10, 51, 0, 3,
+  0, 0, 33, 0, 0, 53, 4, 18, 11, 6,
+  0, 0, 0, 0, 60, 44, 0, 0, 0, 54,
+  0, 0, 0, 29, 17, 0, 3, 11, 34, 17,
+  0, 0, 58, 48, 0, 0, 0, 0, 53, 0,
+  0, 0, 74, 109, 0, 0, 46, 0, 0, 0,
+  0, 59, 0, 51, 0, 23, 0, 0, 0, 0,
+  78, 7, 34, 8, 0, 0, 0, 52, 29, 14,
+  74, 2, 53, 17, 8, 144, 9, 0, 46, 89,
+  0, 57, 27, 0, 12, 0, 0, 0, 31, 87,
+  0, 30, 0, 43, 20, 0, 0, 171, 0, 0,
+  22, 0, 7, 0, 0, 57, 123, 33, 0, 0,
+  0, 0, 0, 2, 0, 0, 0, 24, 0, 10,
+  20, 24, 0, 0, 14, 0, 0, 0, 0, 0,
+  0, 4, 58, 62, 28, 0, 51, 0, 0, 127,
+  0, 0, 28, 13, 0, 0, 0, 82, 0, 0,
+  9, 29, 31, 0, 0, 85, 28, 32, 0, 0,
+  13, 55, 0, 0, 0, 43, 0, 0, 0, 17,
+  44, 93, 0, 0, 24, 0, 15, 0, 0, 32,
+  0, 29, 0, 35, 0, 77, 0, 0, 138, 0,
+  12, 0, 0, 0, 0, 64, 0, 0, 81, 0,
+  9, 6, 12, 125, 8, 0, 33, 55, 0, 39,
+  22, 0, 0, 0, 0, 0, 28, 82, 0, 10,
+  0, 46, 0, 0, 0, 123, 0, 0, 55, 0,
+  11, 0, 0, 88, 63, 49, 0, 0, 27, 0,
+  0, 10, 0, 6, 1, 11, 0, 0, 9, 35,
+  24, 0, 11, 0, 0, 0, 0, 0, 0, 3,
+  9, 79, 0, 0, 30, 0, 26, 161, 0, 0,
+  0, 0, 0, 0, 49, 60, 0, 0, 11, 55,
+  0, 0, 7, 16, 0, 50, 0, 0, 0, 0,
+  0, 35, 21, 0, 0, 13, 0, 0, 0, 55,
+  0, 3, 0, 20, 0, 22, 0, 12, 34, 22,
+  0, 0, 13, 103, 4, 0, 17, 0, 10, 0,
+  46, 0, 0, 0, 0, 0, 54, 0, 0, 2,
+  0, 4, 0, 34, 24, 5, 0, 40, 0, 0,
+  0, 10, 0, 0, 18, 36, 19, 0, 31, 36,
+  38, 0, 0, 22, 13, 0, 4, 0, 0, 0,
+  1, 46, 1, 0, 0, 0, 0, 10, 0, 22,
+  0, 25, 23, 0, 0, 0, 5, 29, 102, 47,
+  32, 3, 54, 0, 0, 0, 37, 15, 0, 14,
+  0, 111, 49, 4, 4, 0, 0, 13, 78, 36,
+  24, 0, 20, 0, 0, 97, 83, 24, 24, 5,
+  0, 0, 48, 50, 0, 0, 1, 78, 1, 0,
+  0, 0, 68, 0, 12, 0, 0, 28, 0, 3,
+  0, 0, 11, 19, 11, 36, 0, 0, 0, 29,
+  0, 18, 44, 0, 0, 0, 1, 0, 0, 8,
+  0, 0, 0, 0, 0, 0, 29, 0, 0, 0,
+  0, 0, 32, 72, 9, 90, 0, 112, 2, 20,
+  35, 0, 0, 53, 0, 31, 6, 61, 21, 24,
+  117, 0, 0, 0, 26, 0, 0, 0, 0, 100,
+  90, 0, 0, 0, 7, 0, 54, 21, 0, 21,
+  0, 0, 0, 15, 0, 0, 0, 0, 0, 21,
+  0, 0, 73, 0, 76, 10, 35, 0, 59, 1,
+  72, 42, 0, 0, 0, 22, 38, 13, 13, 6,
+  0, 7, 0, 21, 38, 13, 14, 0, 0, 64,
+  43, 11, 0, 0, 1, 54, 0, 38, 0, 39,
+  17, 0, 12, 19, 36, 29, 3, 0, 0, 0,
+  0, 0, 0, 11, 0, 0, 0, 0, 0, 70,
+  0, 0, 91, 0, 38, 0, 8, 0, 0, 4,
+  0, 0, 64, 10, 0, 0, 0, 114, 20, 0,
+  74, 27, 0, 45, 12, 51, 27, 0, 0, 0,
+  15, 101, 0, 21, 22, 36, 22, 0, 57, 0,
+  0, 0, 62, 0, 29, 0, 0, 72, 95, 0,
+  0, 0, 0, 80, 0, 16, 0, 0, 0, 13,
+  0, 0, 0, 0, 0, 0, 0, 33, 0, 3,
+  0, 0, 0, 0, 4, 22, 21, 0, 99, 34,
+  0, 157, 0, 0, 0, 0, 0, 17, 14, 49,
+  0, 0, 14, 40, 0, 1, 5, 82, 30, 0,
+  0, 0, 0, 0, 0, 147, 4, 78, 0, 24,
+  0, 23, 87, 19, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 3, 42, 0, 0, 78, 0, 0,
+  59, 0, 56, 0, 27, 0, 0, 28, 13, 0,
+  118, 0, 0, 48, 0, 113, 0, 36, 68, 0,
+  0, 7, 28, 0, 17, 0, 0, 0, 10, 108,
+  35, 0, 27, 10, 7, 0, 0, 0, 13, 0,
+  52, 0, 0, 0, 0, 5, 41, 0, 0, 0,
+  0, 82, 0, 16, 0, 8, 18, 0, 0, 0,
+  39, 10, 84, 0, 0, 54, 5, 43, 0, 6,
+  0, 3, 0, 26, 0, 27, 108, 0, 0, 0,
+  0, 0, 90, 42, 15, 0, 26, 53, 0, 84,
+  60, 35, 50, 0, 0, 15, 20, 31, 0, 0,
+  3, 111, 0, 0, 0, 0, 61, 0, 0, 0,
+  0, 79, 0, 0, 3, 0, 0, 0, 0, 28,
+  0, 0, 0, 35, 0, 82, 11, 0, 69, 0,
+  27, 18, 0, 0, 0, 0, 0, 0, 27, 0,
+  48, 0, 11, 70, 0, 0, 22, 90, 0, 69,
+  0, 68, 0, 0, 7, 0, 32, 92, 0, 47,
+  0, 58, 48, 0, 85, 34, 0, 0, 11, 0,
+  0, 0, 0, 133, 125, 0, 0, 0, 8, 0,
+  0, 61, 0, 16, 7, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 45, 0, 54, 0,
+  21, 46, 0, 0, 117, 0, 0, 75, 0, 0,
+  21, 0, 0, 1, 34, 80, 0, 0, 0, 31,
+  19, 0, 0, 94, 14, 24, 0, 0, 0, 29,
+  0, 0, 10, 39, 0, 0, 0, 0, 0, 56,
+  0, 0, 0, 0, 0, 7, 0, 0, 0, 0,
+  0, 0, 0, 155, 0, 0, 71, 0, 21, 0,
+  50, 0, 0, 5, 0, 0, 108, 0, 0, 0,
+  0, 98, 0, 0, 39, 7, 0, 0, 0, 22,
+  15, 0, 0, 0, 31, 74, 16, 3, 15, 30,
+  48, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 72, 30, 0, 0, 0, 0, 78, 0, 23,
+  0, 11, 40, 0, 0, 0, 17, 16, 68, 25,
+  10, 51, 0, 3, 0, 0, 33, 0, 0, 53,
+  0, 0, 59, 0, 5, 69, 0, 0, 0, 0,
+  0, 19, 45, 76, 0, 0, 0, 17, 2, 8,
+  10, 22, 0, 35, 0, 0, 0, 0, 0, 77,
+  41, 11, 0, 18, 0, 0, 0, 17, 0, 13,
+  0, 0, 0, 39, 0, 0, 0, 0, 0, 0,
+  0, 110, 0, 0, 0, 0, 15, 4, 28, 0,
+  0, 0, 0, 0, 48, 0, 0, 6, 0, 9,
+  0, 40, 17, 0, 0, 0, 0, 0, 53, 0,
+  0, 17, 0, 52, 45, 0, 40, 9, 68, 0,
+  0, 0, 56, 0, 0, 5, 0, 0, 0, 21,
+  0, 0, 0, 0, 1, 53, 0, 16, 7, 45,
+  50, 0, 0, 13, 38, 10, 68, 48, 19, 52,
+  56, 0, 0, 0, 26, 9, 0, 10, 28, 0,
+  51, 0, 0, 127, 0, 0, 28, 13, 0, 0,
+  0, 82, 0, 0, 9, 29, 31, 0, 0, 85,
+  28, 32, 0, 0, 13, 55, 0, 0, 0, 43,
+  0, 0, 0, 17, 44, 93, 0, 0, 24, 0,
+  15, 0, 0, 32, 0, 29, 0, 35, 0, 77,
+  0, 0, 138, 0, 12, 0, 0, 0, 0, 64,
+  0, 0, 81, 0, 9, 6, 12, 125, 8, 0,
+  33, 55, 0, 39, 22, 0, 0, 0, 0, 0,
+  28, 82, 0, 10, 0, 46, 0, 0, 0, 123,
+  0, 0, 55, 0, 11, 0, 0, 88, 63, 49,
+  0, 0, 27, 0, 0, 10, 0, 6, 1, 11,
+  0, 0, 9, 35, 24, 0, 11, 0, 0, 0,
+  0, 0, 0, 3, 9, 79, 0, 0, 30, 0,
+  26, 161, 0, 0, 0, 0, 0, 0, 49, 60,
+  0, 0, 11, 55, 0, 0, 7, 16, 0, 50,
+  0, 0, 0, 0, 0, 35, 21, 0, 0, 13,
+  0, 0, 0, 55, 0, 3, 0, 20, 0, 22,
+  0, 12, 34, 22, 0, 0, 13, 103, 4, 0,
+  17, 0, 10, 0, 46, 0, 0, 0, 0, 0,
+  54, 0, 0, 2, 0, 4, 0, 34, 24, 5,
+  0, 40, 0, 0, 0, 10, 0, 0, 18, 36,
+  19, 0, 31, 36, 38, 0, 0, 22, 13, 0,
+  4, 0, 0, 0, 1, 46, 1, 0, 0, 0,
+  0, 10, 0, 22, 0, 25, 23, 0, 0, 0,
+  5, 29, 102, 47, 32, 3, 54, 0, 0, 0,
+  37, 15, 0, 14, 0, 49, 11, 0, 44, 0,
+  25, 0, 19, 0, 0, 0, 81, 51, 5, 17,
+  15, 0, 0, 0, 3, 0, 0, 60, 21, 63,
+  0, 0, 0, 12, 63, 0, 0, 27, 12, 0,
+  0, 6, 0, 70, 0, 97, 10, 75, 53, 0,
+  0, 0, 0, 6, 0, 65, 94, 0, 0, 3,
+  21, 23, 4, 21, 0, 0, 0, 70, 0, 12,
+  8, 0, 0, 0, 0, 33, 0, 19, 20, 29,
+  0, 0, 0, 27, 44, 20, 19, 0, 78, 0,
+  29, 0, 66, 38, 0, 0, 42, 37, 0, 32,
+  0, 38, 3, 45, 0, 0, 0, 0, 0, 0,
+  3, 5, 71, 72, 88, 0, 0, 7, 31, 0,
+  0, 31, 64, 18, 57, 10, 85, 0, 91, 2,
+  0, 0, 59, 1, 72, 42, 0, 0, 0, 22,
+  38, 13, 13, 6, 0, 7, 0, 21, 38, 13,
+  14, 0, 0, 64, 43, 11, 0, 0, 1, 54,
+  0, 38, 0, 39, 17, 0, 12, 19, 36, 29,
+  3, 0, 0, 0, 0, 0, 0, 11, 0, 0,
+  0, 0, 0, 70, 0, 0, 91, 0, 38, 0,
+  8, 0, 0, 4, 0, 0, 64, 10, 0, 0,
+  0, 114, 20, 0, 74, 27, 0, 45, 12, 51,
+  27, 0, 0, 0, 15, 101, 0, 21, 22, 36,
+  22, 0, 57, 0, 0, 0, 62, 0, 29, 0,
+  0, 72, 95, 0, 0, 0, 0, 80, 0, 16,
+  0, 0, 0, 13, 0, 0, 0, 0, 0, 0,
+  0, 33, 0, 3, 0, 0, 0, 0, 4, 22,
+  21, 0, 99, 34, 0, 157, 0, 0, 0, 0,
+  0, 17, 14, 49, 0, 0, 14, 40, 0, 1,
+  5, 82, 30, 0, 0, 0, 0, 0, 0, 147,
+  4, 78, 0, 24, 0, 23, 87, 19, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 3, 42, 0,
+  0, 78, 0, 0, 59, 0, 56, 0, 27, 0,
+  0, 28, 13, 0, 118, 0, 0, 48, 0, 113,
+  0, 36, 68, 0, 0, 7, 28, 0, 17, 0,
+  0, 0, 10, 108, 35, 0, 27, 10, 7, 0,
+  0, 0, 13, 0, 52, 0, 0, 0, 0, 5,
+  41, 0, 0, 0, 0, 82, 0, 16, 0, 8,
+  18, 0, 0, 0, 39, 10, 84, 0, 0, 54,
+  5, 43, 0, 6, 0, 3, 0, 26, 0, 9,
+  38, 0, 15, 120, 0, 0, 0, 0, 0, 3,
+  58, 72, 0, 0, 0, 18, 0, 18, 44, 0,
+  0, 51, 0, 3, 0, 0, 0, 91, 41, 0,
+  0, 22, 0, 0, 0, 22, 0, 25, 0, 45,
+  0, 53, 1, 0, 0, 32, 0, 0, 0, 70,
+  11, 0, 0, 0, 19, 0, 13, 14, 0, 9,
+  0, 0, 0, 0, 0, 11, 0, 0, 0, 58,
+  10, 0, 0, 20, 0, 0, 2, 19, 0, 27,
+  10, 28, 51, 0, 32, 5, 54, 4, 0, 0,
+  52, 5, 0, 37, 0, 0, 0, 30, 0, 0,
+  0, 0, 3, 4, 0, 16, 10, 25, 57, 0,
+  0, 17, 37, 0, 63, 43, 24, 47, 55, 1,
+  2, 0, 25, 2, 0, 0, 0, 0, 117, 0,
+  0, 75, 0, 0, 21, 0, 0, 1, 34, 80,
+  0, 0, 0, 31, 19, 0, 0, 94, 14, 24,
+  0, 0, 0, 29, 0, 0, 10, 39, 0, 0,
+  0, 0, 0, 56, 0, 0, 0, 0, 0, 7,
+  0, 0, 0, 0, 0, 0, 0, 155, 0, 0,
+  71, 0, 21, 0, 50, 0, 0, 5, 0, 0,
+  108, 0, 0, 0, 0, 98, 0, 0, 39, 7,
+  0, 0, 0, 22, 15, 0, 0, 0, 31, 74,
+  16, 3, 15, 30, 48, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 72, 30, 0, 0, 0,
+  0, 78, 0, 23, 0, 11, 40, 0, 0, 0,
+  17, 16, 68, 25, 10, 51, 0, 3, 0, 0,
+  33, 0, 0, 53, 0, 0, 59, 0, 5, 69,
+  0, 0, 0, 0, 0, 19, 45, 76, 0, 0,
+  0, 17, 2, 8, 10, 22, 0, 35, 0, 0,
+  0, 0, 0, 77, 41, 11, 0, 18, 0, 0,
+  0, 17, 0, 13, 0, 0, 0, 39, 0, 0,
+  0, 0, 0, 0, 0, 110, 0, 0, 0, 0,
+  15, 4, 28, 0, 0, 0, 0, 0, 48, 0,
+  0, 6, 0, 9, 0, 40, 17, 0, 0, 0,
+  0, 0, 53, 0, 0, 17, 0, 52, 45, 0,
+  40, 9, 68, 0, 0, 0, 56, 0, 0, 5,
+  0, 0, 0, 21, 0, 0, 0, 0, 1, 53,
+  0, 16, 7, 45, 50, 0, 0, 13, 38, 10,
+  68, 48, 19, 52, 56, 0, 0, 0, 26, 9,
+  0, 10, 0, 52, 52, 0, 44, 0, 21, 0,
+  7, 0, 0, 3, 68, 73, 3, 33, 10, 1,
+  18, 0, 44, 0, 0, 50, 14, 42, 0, 0,
+  0, 12, 60, 0, 0, 39, 0, 0, 0, 7,
+  0, 62, 39, 63, 0, 87, 51, 0, 0, 0,
+  0, 0, 0, 78, 42, 0, 0, 0, 18, 20,
+  19, 14, 11, 0, 3, 81, 0, 28, 0, 0,
+  0, 0, 0, 30, 0, 13, 8, 1, 0, 0,
+  0, 18, 37, 38, 21, 0, 88, 0, 16, 0,
+  65, 54, 0, 0, 46, 25, 0, 61, 0, 19,
+  5, 30, 0, 0, 0, 0, 0, 0, 0, 15,
+  38, 43, 88, 0, 0, 20, 22, 0, 0, 24,
+  58, 18, 39, 4, 45, 0, 79, 0, 1, 0,
+  0, 0, 30, 0, 26, 161, 0, 0, 0, 0,
+  0, 0, 49, 60, 0, 0, 11, 55, 0, 0,
+  7, 16, 0, 50, 0, 0, 0, 0, 0, 35,
+  21, 0, 0, 13, 0, 0, 0, 55, 0, 3,
+  0, 20, 0, 22, 0, 12, 34, 22, 0, 0,
+  13, 103, 4, 0, 17, 0, 10, 0, 46, 0,
+  0, 0, 0, 0, 54, 0, 0, 2, 0, 4,
+  0, 34, 24, 5, 0, 40, 0, 0, 0, 10,
+  0, 0, 18, 36, 19, 0, 31, 36, 38, 0,
+  0, 22, 13, 0, 4, 0, 0, 0, 1, 46,
+  1, 0, 0, 0, 0, 10, 0, 22, 0, 25,
+  23, 0, 0, 0, 5, 29, 102, 47, 32, 3,
+  54, 0, 0, 0, 37, 15, 0, 14, 0, 49,
+  11, 0, 44, 0, 25, 0, 19, 0, 0, 0,
+  81, 51, 5, 17, 15, 0, 0, 0, 3, 0,
+  0, 60, 21, 63, 0, 0, 0, 12, 63, 0,
+  0, 27, 12, 0, 0, 6, 0, 70, 0, 97,
+  10, 75, 53, 0, 0, 0, 0, 6, 0, 65,
+  94, 0, 0, 3, 21, 23, 4, 21, 0, 0,
+  0, 70, 0, 12, 8, 0, 0, 0, 0, 33,
+  0, 19, 20, 29, 0, 0, 0, 27, 44, 20,
+  19, 0, 78, 0, 29, 0, 66, 38, 0, 0,
+  42, 37, 0, 32, 0, 38, 3, 45, 0, 0,
+  0, 0, 0, 0, 3, 5, 71, 72, 88, 0,
+  0, 7, 31, 0, 0, 31, 64, 18, 57, 10,
+  85, 0, 91, 2, 0, 0, 0, 21, 76, 0,
+  26, 0, 1, 0, 0, 0, 0, 6, 28, 78,
+  0, 20, 4, 29, 21, 10, 35, 34, 113, 11,
+  0, 0, 0, 0, 0, 0, 18, 0, 0, 0,
+  0, 0, 0, 1, 0, 10, 66, 3, 0, 101,
+  57, 6, 0, 0, 0, 0, 0, 90, 1, 0,
+  17, 0, 40, 0, 25, 0, 0, 10, 7, 19,
+  34, 0, 0, 18, 0, 29, 0, 0, 0, 43,
+  3, 0, 0, 28, 0, 0, 37, 0, 22, 0,
+  65, 9, 0, 0, 20, 0, 0, 16, 13, 0,
+  0, 46, 0, 0, 0, 39, 0, 0, 0, 0,
+  1, 0, 0, 4, 0, 7, 72, 14, 0, 12,
+  20, 0, 52, 13, 51, 13, 13, 0, 0, 0,
+  64, 0, 0, 0, 21, 0, 99, 34, 0, 157,
+  0, 0, 0, 0, 0, 17, 14, 49, 0, 0,
+  14, 40, 0, 1, 5, 82, 30, 0, 0, 0,
+  0, 0, 0, 147, 4, 78, 0, 24, 0, 23,
+  87, 19, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 3, 42, 0, 0, 78, 0, 0, 59, 0,
+  56, 0, 27, 0, 0, 28, 13, 0, 118, 0,
+  0, 48, 0, 113, 0, 36, 68, 0, 0, 7,
+  28, 0, 17, 0, 0, 0, 10, 108, 35, 0,
+  27, 10, 7, 0, 0, 0, 13, 0, 52, 0,
+  0, 0, 0, 5, 41, 0, 0, 0, 0, 82,
+  0, 16, 0, 8, 18, 0, 0, 0, 39, 10,
+  84, 0, 0, 54, 5, 43, 0, 6, 0, 3,
+  0, 26, 0, 9, 38, 0, 15, 120, 0, 0,
+  0, 0, 0, 3, 58, 72, 0, 0, 0, 18,
+  0, 18, 44, 0, 0, 51, 0, 3, 0, 0,
+  0, 91, 41, 0, 0, 22, 0, 0, 0, 22,
+  0, 25, 0, 45, 0, 53, 1, 0, 0, 32,
+  0, 0, 0, 70, 11, 0, 0, 0, 19, 0,
+  13, 14, 0, 9, 0, 0, 0, 0, 0, 11,
+  0, 0, 0, 58, 10, 0, 0, 20, 0, 0,
+  2, 19, 0, 27, 10, 28, 51, 0, 32, 5,
+  54, 4, 0, 0, 52, 5, 0, 37, 0, 0,
+  0, 30, 0, 0, 0, 0, 3, 4, 0, 16,
+  10, 25, 57, 0, 0, 17, 37, 0, 63, 43,
+  24, 47, 55, 1, 2, 0, 25, 2, 0, 0,
+  0, 70, 65, 0, 63, 0, 15, 0, 1, 0,
+  14, 0, 64, 75, 0, 51, 17, 7, 26, 16,
+  9, 0, 0, 47, 38, 59, 0, 0, 0, 0,
+  53, 0, 0, 37, 12, 0, 0, 0, 0, 53,
+  50, 43, 24, 71, 73, 0, 0, 0, 0, 0,
+  0, 26, 50, 0, 0, 0, 0, 20, 1, 27,
+  24, 0, 0, 63, 0, 2, 29, 0, 0, 0,
+  0, 0, 7, 41, 16, 12, 0, 17, 0, 23,
+  46, 34, 33, 22, 87, 14, 32, 4, 49, 40,
+  0, 20, 24, 31, 0, 54, 0, 35, 3, 41,
+  0, 0, 0, 0, 0, 0, 7, 10, 34, 32,
+  82, 0, 0, 13, 31, 0, 0, 29, 54, 8,
+  7, 0, 55, 0, 75, 11, 2, 0, 0, 0,
+  59, 0, 5, 69, 0, 0, 0, 0, 0, 19,
+  45, 76, 0, 0, 0, 17, 2, 8, 10, 22,
+  0, 35, 0, 0, 0, 0, 0, 77, 41, 11,
+  0, 18, 0, 0, 0, 17, 0, 13, 0, 0,
+  0, 39, 0, 0, 0, 0, 0, 0, 0, 110,
+  0, 0, 0, 0, 15, 4, 28, 0, 0, 0,
+  0, 0, 48, 0, 0, 6, 0, 9, 0, 40,
+  17, 0, 0, 0, 0, 0, 53, 0, 0, 17,
+  0, 52, 45, 0, 40, 9, 68, 0, 0, 0,
+  56, 0, 0, 5, 0, 0, 0, 21, 0, 0,
+  0, 0, 1, 53, 0, 16, 7, 45, 50, 0,
+  0, 13, 38, 10, 68, 48, 19, 52, 56, 0,
+  0, 0, 26, 9, 0, 10, 0, 52, 52, 0,
+  44, 0, 21, 0, 7, 0, 0, 3, 68, 73,
+  3, 33, 10, 1, 18, 0, 44, 0, 0, 50,
+  14, 42, 0, 0, 0, 12, 60, 0, 0, 39,
+  0, 0, 0, 7, 0, 62, 39, 63, 0, 87,
+  51, 0, 0, 0, 0, 0, 0, 78, 42, 0,
+  0, 0, 18, 20, 19, 14, 11, 0, 3, 81,
+  0, 28, 0, 0, 0, 0, 0, 30, 0, 13,
+  8, 1, 0, 0, 0, 18, 37, 38, 21, 0,
+  88, 0, 16, 0, 65, 54, 0, 0, 46, 25,
+  0, 61, 0, 19, 5, 30, 0, 0, 0, 0,
+  0, 0, 0, 15, 38, 43, 88, 0, 0, 20,
+  22, 0, 0, 24, 58, 18, 39, 4, 45, 0,
+  79, 0, 1, 0, 0, 16, 100, 0, 22, 0,
+  0, 0, 0, 0, 0, 11, 22, 94, 0, 49,
+  0, 51, 31, 35, 50, 27, 110, 9, 0, 0,
+  0, 0, 0, 0, 32, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 94, 0, 0, 96, 51, 18,
+  0, 0, 0, 0, 0, 79, 0, 0, 15, 0,
+  24, 0, 24, 0, 7, 8, 19, 6, 56, 0,
+  0, 10, 0, 51, 0, 0, 21, 34, 0, 0,
+  0, 16, 0, 0, 24, 0, 36, 0, 41, 12,
+  2, 0, 43, 21, 0, 36, 0, 0, 5, 39,
+  0, 0, 0, 27, 23, 0, 0, 0, 0, 0,
+  0, 11, 0, 6, 79, 9, 0, 5, 40, 0,
+  52, 15, 28, 31, 21, 0, 0, 0, 55, 12,
+  0, 0, 0, 49, 11, 0, 44, 0, 25, 0,
+  19, 0, 0, 0, 81, 51, 5, 17, 15, 0,
+  0, 0, 3, 0, 0, 60, 21, 63, 0, 0,
+  0, 12, 63, 0, 0, 27, 12, 0, 0, 6,
+  0, 70, 0, 97, 10, 75, 53, 0, 0, 0,
+  0, 6, 0, 65, 94, 0, 0, 3, 21, 23,
+  4, 21, 0, 0, 0, 70, 0, 12, 8, 0,
+  0, 0, 0, 33, 0, 19, 20, 29, 0, 0,
+  0, 27, 44, 20, 19, 0, 78, 0, 29, 0,
+  66, 38, 0, 0, 42, 37, 0, 32, 0, 38,
+  3, 45, 0, 0, 0, 0, 0, 0, 3, 5,
+  71, 72, 88, 0, 0, 7, 31, 0, 0, 31,
+  64, 18, 57, 10, 85, 0, 91, 2, 0, 0,
+  0, 21, 76, 0, 26, 0, 1, 0, 0, 0,
+  0, 6, 28, 78, 0, 20, 4, 29, 21, 10,
+  35, 34, 113, 11, 0, 0, 0, 0, 0, 0,
+  18, 0, 0, 0, 0, 0, 0, 1, 0, 10,
+  66, 3, 0, 101, 57, 6, 0, 0, 0, 0,
+  0, 90, 1, 0, 17, 0, 40, 0, 25, 0,
+  0, 10, 7, 19, 34, 0, 0, 18, 0, 29,
+  0, 0, 0, 43, 3, 0, 0, 28, 0, 0,
+  37, 0, 22, 0, 65, 9, 0, 0, 20, 0,
+  0, 16, 13, 0, 0, 46, 0, 0, 0, 39,
+  0, 0, 0, 0, 1, 0, 0, 4, 0, 7,
+  72, 14, 0, 12, 20, 0, 52, 13, 51, 13,
+  13, 0, 0, 0, 64, 0, 0, 0, 4, 0,
+  79, 3, 6, 0, 0, 0, 14, 0, 0, 8,
+  0, 94, 0, 3, 0, 47, 45, 17, 53, 54,
+  102, 0, 0, 0, 0, 16, 0, 0, 0, 0,
+  0, 0, 0, 14, 0, 0, 0, 0, 37, 0,
+  0, 85, 38, 32, 0, 6, 0, 0, 0, 126,
+  0, 0, 66, 0, 24, 0, 20, 0, 0, 0,
+  29, 0, 99, 0, 0, 10, 0, 92, 0, 0,
+  18, 0, 0, 0, 4, 0, 0, 0, 11, 0,
+  20, 0, 18, 0, 0, 0, 39, 0, 0, 7,
+  0, 0, 22, 29, 2, 0, 4, 32, 23, 0,
+  0, 0, 28, 0, 0, 3, 17, 0, 84, 3,
+  0, 15, 21, 0, 112, 0, 10, 16, 55, 0,
+  0, 0, 57, 15, 0, 0, 0, 9, 38, 0,
+  15, 120, 0, 0, 0, 0, 0, 3, 58, 72,
+  0, 0, 0, 18, 0, 18, 44, 0, 0, 51,
+  0, 3, 0, 0, 0, 91, 41, 0, 0, 22,
+  0, 0, 0, 22, 0, 25, 0, 45, 0, 53,
+  1, 0, 0, 32, 0, 0, 0, 70, 11, 0,
+  0, 0, 19, 0, 13, 14, 0, 9, 0, 0,
+  0, 0, 0, 11, 0, 0, 0, 58, 10, 0,
+  0, 20, 0, 0, 2, 19, 0, 27, 10, 28,
+  51, 0, 32, 5, 54, 4, 0, 0, 52, 5,
+  0, 37, 0, 0, 0, 30, 0, 0, 0, 0,
+  3, 4, 0, 16, 10, 25, 57, 0, 0, 17,
+  37, 0, 63, 43, 24, 47, 55, 1, 2, 0,
+  25, 2, 0, 0, 0, 70, 65, 0, 63, 0,
+  15, 0, 1, 0, 14, 0, 64, 75, 0, 51,
+  17, 7, 26, 16, 9, 0, 0, 47, 38, 59,
+  0, 0, 0, 0, 53, 0, 0, 37, 12, 0,
+  0, 0, 0, 53, 50, 43, 24, 71, 73, 0,
+  0, 0, 0, 0, 0, 26, 50, 0, 0, 0,
+  0, 20, 1, 27, 24, 0, 0, 63, 0, 2,
+  29, 0, 0, 0, 0, 0, 7, 41, 16, 12,
+  0, 17, 0, 23, 46, 34, 33, 22, 87, 14,
+  32, 4, 49, 40, 0, 20, 24, 31, 0, 54,
+  0, 35, 3, 41, 0, 0, 0, 0, 0, 0,
+  7, 10, 34, 32, 82, 0, 0, 13, 31, 0,
+  0, 29, 54, 8, 7, 0, 55, 0, 75, 11,
+  2, 0, 0, 0, 119, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 103, 0, 9, 0, 6,
+  10, 5, 9, 50, 108, 24, 0, 0, 0, 8,
+  184, 0, 22, 0, 0, 31, 0, 0, 11, 12,
+  0, 10, 106, 0, 19, 21, 57, 33, 0, 2,
+  16, 0, 0, 65, 0, 0, 30, 0, 14, 26,
+  31, 0, 30, 40, 20, 0, 16, 5, 36, 0,
+  0, 70, 0, 0, 38, 61, 0, 0, 13, 0,
+  0, 0, 25, 10, 0, 19, 7, 11, 0, 47,
+  49, 0, 0, 54, 39, 0, 33, 24, 0, 0,
+  0, 22, 19, 7, 17, 0, 40, 27, 0, 5,
+  0, 0, 50, 3, 0, 0, 37, 20, 52, 0,
+  0, 30, 0, 0, 0, 0, 2, 25, 2, 0,
+  0, 52, 52, 0, 44, 0, 21, 0, 7, 0,
+  0, 3, 68, 73, 3, 33, 10, 1, 18, 0,
+  44, 0, 0, 50, 14, 42, 0, 0, 0, 12,
+  60, 0, 0, 39, 0, 0, 0, 7, 0, 62,
+  39, 63, 0, 87, 51, 0, 0, 0, 0, 0,
+  0, 78, 42, 0, 0, 0, 18, 20, 19, 14,
+  11, 0, 3, 81, 0, 28, 0, 0, 0, 0,
+  0, 30, 0, 13, 8, 1, 0, 0, 0, 18,
+  37, 38, 21, 0, 88, 0, 16, 0, 65, 54,
+  0, 0, 46, 25, 0, 61, 0, 19, 5, 30,
+  0, 0, 0, 0, 0, 0, 0, 15, 38, 43,
+  88, 0, 0, 20, 22, 0, 0, 24, 58, 18,
+  39, 4, 45, 0, 79, 0, 1, 0, 0, 16,
+  100, 0, 22, 0, 0, 0, 0, 0, 0, 11,
+  22, 94, 0, 49, 0, 51, 31, 35, 50, 27,
+  110, 9, 0, 0, 0, 0, 0, 0, 32, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 94, 0,
+  0, 96, 51, 18, 0, 0, 0, 0, 0, 79,
+  0, 0, 15, 0, 24, 0, 24, 0, 7, 8,
+  19, 6, 56, 0, 0, 10, 0, 51, 0, 0,
+  21, 34, 0, 0, 0, 16, 0, 0, 24, 0,
+  36, 0, 41, 12, 2, 0, 43, 21, 0, 36,
+  0, 0, 5, 39, 0, 0, 0, 27, 23, 0,
+  0, 0, 0, 0, 0, 11, 0, 6, 79, 9,
+  0, 5, 40, 0, 52, 15, 28, 31, 21, 0,
+  0, 0, 55, 12, 0, 0, 20, 0, 91, 19,
+  0, 0, 0, 12, 20, 0, 0, 0, 0, 125,
+  0, 0, 0, 22, 28, 1, 36, 70, 81, 11,
+  0, 0, 7, 35, 205, 0, 23, 21, 0, 15,
+  0, 0, 0, 31, 0, 0, 65, 0, 0, 38,
+  53, 70, 0, 0, 0, 0, 0, 120, 0, 6,
+  74, 0, 21, 12, 39, 0, 24, 17, 49, 0,
+  50, 0, 10, 0, 0, 102, 0, 0, 27, 14,
+  0, 0, 25, 0, 0, 0, 12, 2, 2, 20,
+  0, 0, 0, 33, 96, 33, 0, 2, 0, 0,
+  53, 20, 39, 0, 2, 26, 35, 12, 15, 0,
+  81, 19, 3, 30, 19, 0, 74, 0, 14, 0,
+  19, 31, 105, 0, 0, 54, 0, 0, 0, 0,
+  40, 22, 0, 17, 0, 21, 76, 0, 26, 0,
+  1, 0, 0, 0, 0, 6, 28, 78, 0, 20,
+  4, 29, 21, 10, 35, 34, 113, 11, 0, 0,
+  0, 0, 0, 0, 18, 0, 0, 0, 0, 0,
+  0, 1, 0, 10, 66, 3, 0, 101, 57, 6,
+  0, 0, 0, 0, 0, 90, 1, 0, 17, 0,
+  40, 0, 25, 0, 0, 10, 7, 19, 34, 0,
+  0, 18, 0, 29, 0, 0, 0, 43, 3, 0,
+  0, 28, 0, 0, 37, 0, 22, 0, 65, 9,
+  0, 0, 20, 0, 0, 16, 13, 0, 0, 46,
+  0, 0, 0, 39, 0, 0, 0, 0, 1, 0,
+  0, 4, 0, 7, 72, 14, 0, 12, 20, 0,
+  52, 13, 51, 13, 13, 0, 0, 0, 64, 0,
+  0, 0, 4, 0, 79, 3, 6, 0, 0, 0,
+  14, 0, 0, 8, 0, 94, 0, 3, 0, 47,
+  45, 17, 53, 54, 102, 0, 0, 0, 0, 16,
+  0, 0, 0, 0, 0, 0, 0, 14, 0, 0,
+  0, 0, 37, 0, 0, 85, 38, 32, 0, 6,
+  0, 0, 0, 126, 0, 0, 66, 0, 24, 0,
+  20, 0, 0, 0, 29, 0, 99, 0, 0, 10,
+  0, 92, 0, 0, 18, 0, 0, 0, 4, 0,
+  0, 0, 11, 0, 20, 0, 18, 0, 0, 0,
+  39, 0, 0, 7, 0, 0, 22, 29, 2, 0,
+  4, 32, 23, 0, 0, 0, 28, 0, 0, 3,
+  17, 0, 84, 3, 0, 15, 21, 0, 112, 0,
+  10, 16, 55, 0, 0, 0, 57, 15, 0, 0,
+  2, 0, 42, 31, 0, 0, 14, 24, 59, 0,
+  4, 0, 0, 82, 0, 0, 0, 8, 26, 0,
+  35, 19, 23, 27, 0, 0, 38, 57, 187, 16,
+  19, 10, 32, 0, 0, 0, 0, 25, 0, 0,
+  0, 0, 0, 32, 38, 93, 0, 17, 0, 0,
+  3, 110, 0, 32, 59, 0, 9, 0, 14, 0,
+  0, 22, 8, 0, 4, 0, 20, 0, 0, 39,
+  0, 6, 29, 4, 0, 9, 34, 0, 0, 0,
+  24, 0, 1, 24, 0, 0, 0, 30, 103, 45,
+  40, 0, 0, 0, 18, 12, 59, 0, 26, 51,
+  26, 6, 18, 0, 84, 0, 42, 12, 87, 0,
+  79, 0, 10, 0, 1, 0, 115, 0, 0, 34,
+  41, 0, 5, 0, 59, 9, 0, 24, 0, 70,
+  65, 0, 63, 0, 15, 0, 1, 0, 14, 0,
+  64, 75, 0, 51, 17, 7, 26, 16, 9, 0,
+  0, 47, 38, 59, 0, 0, 0, 0, 53, 0,
+  0, 37, 12, 0, 0, 0, 0, 53, 50, 43,
+  24, 71, 73, 0, 0, 0, 0, 0, 0, 26,
+  50, 0, 0, 0, 0, 20, 1, 27, 24, 0,
+  0, 63, 0, 2, 29, 0, 0, 0, 0, 0,
+  7, 41, 16, 12, 0, 17, 0, 23, 46, 34,
+  33, 22, 87, 14, 32, 4, 49, 40, 0, 20,
+  24, 31, 0, 54, 0, 35, 3, 41, 0, 0,
+  0, 0, 0, 0, 7, 10, 34, 32, 82, 0,
+  0, 13, 31, 0, 0, 29, 54, 8, 7, 0,
+  55, 0, 75, 11, 2, 0, 0, 0, 119, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 103,
+  0, 9, 0, 6, 10, 5, 9, 50, 108, 24,
+  0, 0, 0, 8, 184, 0, 22, 0, 0, 31,
+  0, 0, 11, 12, 0, 10, 106, 0, 19, 21,
+  57, 33, 0, 2, 16, 0, 0, 65, 0, 0,
+  30, 0, 14, 26, 31, 0, 30, 40, 20, 0,
+  16, 5, 36, 0, 0, 70, 0, 0, 38, 61,
+  0, 0, 13, 0, 0, 0, 25, 10, 0, 19,
+  7, 11, 0, 47, 49, 0, 0, 54, 39, 0,
+  33, 24, 0, 0, 0, 22, 19, 7, 17, 0,
+  40, 27, 0, 5, 0, 0, 50, 3, 0, 0,
+  37, 20, 52, 0, 0, 30, 0, 0, 0, 0,
+  2, 25, 2, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 16, 100, 0, 22, 0, 0, 0,
+  0, 0, 0, 11, 22, 94, 0, 49, 0, 51,
+  31, 35, 50, 27, 110, 9, 0, 0, 0, 0,
+  0, 0, 32, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 94, 0, 0, 96, 51, 18, 0, 0,
+  0, 0, 0, 79, 0, 0, 15, 0, 24, 0,
+  24, 0, 7, 8, 19, 6, 56, 0, 0, 10,
+  0, 51, 0, 0, 21, 34, 0, 0, 0, 16,
+  0, 0, 24, 0, 36, 0, 41, 12, 2, 0,
+  43, 21, 0, 36, 0, 0, 5, 39, 0, 0,
+  0, 27, 23, 0, 0, 0, 0, 0, 0, 11,
+  0, 6, 79, 9, 0, 5, 40, 0, 52, 15,
+  28, 31, 21, 0, 0, 0, 55, 12, 0, 0,
+  20, 0, 91, 19, 0, 0, 0, 12, 20, 0,
+  0, 0, 0, 125, 0, 0, 0, 22, 28, 1,
+  36, 70, 81, 11, 0, 0, 7, 35, 205, 0,
+  23, 21, 0, 15, 0, 0, 0, 31, 0, 0,
+  65, 0, 0, 38, 53, 70, 0, 0, 0, 0,
+  0, 120, 0, 6, 74, 0, 21, 12, 39, 0,
+  24, 17, 49, 0, 50, 0, 10, 0, 0, 102,
+  0, 0, 27, 14, 0, 0, 25, 0, 0, 0,
+  12, 2, 2, 20, 0, 0, 0, 33, 96, 33,
+  0, 2, 0, 0, 53, 20, 39, 0, 2, 26,
+  35, 12, 15, 0, 81, 19, 3, 30, 19, 0,
+  74, 0, 14, 0, 19, 31, 105, 0, 0, 54,
+  0, 0, 0, 0, 40, 22, 0, 17, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 4, 0, 79, 3,
+  6, 0, 0, 0, 14, 0, 0, 8, 0, 94,
+  0, 3, 0, 47, 45, 17, 53, 54, 102, 0,
+  0, 0, 0, 16, 0, 0, 0, 0, 0, 0,
+  0, 14, 0, 0, 0, 0, 37, 0, 0, 85,
+  38, 32, 0, 6, 0, 0, 0, 126, 0, 0,
+  66, 0, 24, 0, 20, 0, 0, 0, 29, 0,
+  99, 0, 0, 10, 0, 92, 0, 0, 18, 0,
+  0, 0, 4, 0, 0, 0, 11, 0, 20, 0,
+  18, 0, 0, 0, 39, 0, 0, 7, 0, 0,
+  22, 29, 2, 0, 4, 32, 23, 0, 0, 0,
+  28, 0, 0, 3, 17, 0, 84, 3, 0, 15,
+  21, 0, 112, 0, 10, 16, 55, 0, 0, 0,
+  57, 15, 0, 0, 2, 0, 42, 31, 0, 0,
+  14, 24, 59, 0, 4, 0, 0, 82, 0, 0,
+  0, 8, 26, 0, 35, 19, 23, 27, 0, 0,
+  38, 57, 187, 16, 19, 10, 32, 0, 0, 0,
+  0, 25, 0, 0, 0, 0, 0, 32, 38, 93,
+  0, 17, 0, 0, 3, 110, 0, 32, 59, 0,
+  9, 0, 14, 0, 0, 22, 8, 0, 4, 0,
+  20, 0, 0, 39, 0, 6, 29, 4, 0, 9,
+  34, 0, 0, 0, 24, 0, 1, 24, 0, 0,
+  0, 30, 103, 45, 40, 0, 0, 0, 18, 12,
+  59, 0, 26, 51, 26, 6, 18, 0, 84, 0,
+  42, 12, 87, 0, 79, 0, 10, 0, 1, 0,
+  115, 0, 0, 34, 41, 0, 5, 0, 59, 9,
+  0, 24, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 13, 24,
+  67, 6, 0, 18, 27, 22, 0, 0, 0, 0,
+  0, 97, 0, 0, 60, 4, 0, 5, 27, 86,
+  27, 52, 0, 0, 8, 9, 193, 55, 1, 28,
+  52, 0, 59, 1, 0, 58, 0, 17, 14, 39,
+  0, 14, 26, 83, 17, 0, 2, 0, 0, 64,
+  30, 0, 71, 0, 60, 0, 49, 0, 15, 71,
+  0, 0, 0, 0, 7, 6, 77, 33, 0, 22,
+  82, 11, 31, 27, 25, 0, 20, 13, 0, 0,
+  15, 5, 0, 0, 0, 0, 62, 3, 0, 0,
+  23, 0, 15, 37, 0, 0, 49, 67, 15, 0,
+  0, 37, 46, 75, 26, 0, 0, 6, 1, 16,
+  0, 37, 12, 0, 55, 0, 9, 28, 40, 0,
+  0, 0, 4, 0, 26, 26, 0, 60, 0, 15,
+  0, 5, 36, 23, 2, 0, 0, 31, 86, 8,
+  0, 0, 59, 11, 0, 0, 65, 56, 0, 25,
+  23, 0, 0, 13, 0, 13, 0, 11, 92, 0,
+  18, 0, 0, 32, 0, 53, 0, 28, 0, 44,
+  48, 94, 4, 86, 0, 7, 0, 38, 52, 0,
+  35, 0, 21, 0, 24, 0, 13, 27, 0, 40,
+  0, 11, 10, 0, 33, 0, 8, 0, 25, 13,
+  37, 0, 0, 0, 0, 15, 39, 0, 14, 13,
+  0, 0, 0, 0, 0, 24, 0, 0, 0, 13,
+  0, 47, 0, 0, 62, 50, 3, 0, 0, 13,
+  20, 1, 44, 0, 24, 28, 0, 29, 0, 15,
+  0, 0, 25, 0, 11, 10, 47, 0, 42, 0,
+  79, 0, 14, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 30, 25, 0, 1, 3, 33, 18,
+  0, 0, 0, 0, 0, 38, 0, 18, 43, 15,
+  0, 40, 38, 17, 58, 51, 0, 9, 8, 5,
+  128, 38, 0, 0, 54, 0, 69, 16, 0, 30,
+  0, 38, 21, 38, 0, 22, 60, 37, 2, 0,
+  0, 0, 0, 13, 47, 0, 16, 0, 64, 0,
+  29, 0, 6, 33, 7, 0, 0, 0, 7, 19,
+  25, 0, 0, 36, 79, 26, 45, 46, 0, 7,
+  30, 1, 38, 2, 13, 0, 0, 0, 0, 0,
+  54, 6, 3, 0, 38, 1, 15, 56, 0, 0,
+  37, 35, 9, 0, 0, 19, 20, 19, 57, 1,
+  0, 26, 0, 8, 0, 33, 5, 0, 23, 13,
+  0, 22, 19, 0, 0, 0, 19, 0, 11, 9,
+  0, 48, 13, 14, 0, 0, 29, 34, 3, 0,
+  0, 37, 105, 0, 2, 11, 53, 15, 0, 14,
+  67, 51, 53, 17, 9, 0, 0, 9, 0, 0,
+  0, 0, 96, 0, 32, 9, 0, 24, 0, 75,
+  0, 32, 0, 38, 68, 64, 0, 61, 0, 41,
+  0, 28, 43, 1, 16, 0, 14, 0, 11, 0,
+  0, 0, 0, 18, 0, 0, 0, 0, 17, 0,
+  10, 2, 29, 20, 37, 0, 16, 39, 0, 22,
+  45, 0, 41, 0, 0, 0, 0, 0, 0, 7,
+  0, 0, 0, 7, 0, 48, 0, 0, 52, 46,
+  8, 0, 0, 12, 18, 0, 59, 0, 0, 16,
+  0, 17, 0, 17, 0, 0, 14, 0, 6, 8,
+  40, 0, 40, 0, 76, 0, 11, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 62, 32, 0,
+  2, 1, 44, 3, 0, 0, 16, 4, 12, 0,
+  5, 53, 33, 30, 0, 74, 61, 0, 71, 46,
+  0, 36, 0, 3, 111, 34, 1, 0, 57, 0,
+  53, 22, 0, 16, 0, 48, 40, 30, 5, 36,
+  99, 16, 0, 12, 0, 8, 1, 0, 56, 0,
+  0, 0, 43, 0, 7, 33, 9, 0, 16, 0,
+  0, 0, 18, 21, 0, 0, 8, 32, 42, 43,
+  43, 31, 0, 15, 0, 0, 70, 13, 10, 0,
+  12, 12, 0, 0, 50, 9, 2, 0, 16, 0,
+  5, 73, 0, 0, 8, 21, 2, 0, 0, 16,
+  17, 0, 77, 9, 0, 22, 29, 1, 0, 33,
+  0, 0, 0, 15, 0, 33, 26, 0, 0, 0,
+  28, 0, 14, 0, 5, 45, 49, 8, 0, 13,
+  12, 23, 0, 0, 0, 49, 90, 0, 0, 29,
+  44, 13, 0, 25, 68, 58, 82, 13, 0, 0,
+  0, 11, 0, 0, 0, 0, 81, 0, 34, 31,
+  0, 20, 0, 59, 2, 29, 0, 28, 67, 52,
+  0, 60, 0, 43, 0, 42, 24, 0, 22, 0,
+  17, 0, 7, 0, 0, 0, 0, 9, 8, 0,
+  0, 0, 16, 0, 14, 13, 19, 19, 30, 0,
+  40, 53, 0, 19, 43, 0, 42, 0, 0, 11,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 33,
+  18, 0, 37, 45, 21, 0, 0, 23, 29, 0,
+  60, 0, 0, 7, 11, 13, 0, 17, 0, 0,
+  0, 0, 1, 9, 37, 0, 7, 0, 52, 0,
+  8, 2, 13, 24, 67, 6, 0, 18, 27, 22,
+  0, 0, 0, 0, 0, 97, 0, 0, 60, 4,
+  0, 5, 27, 86, 27, 52, 0, 0, 8, 9,
+  193, 55, 1, 28, 52, 0, 59, 1, 0, 58,
+  0, 17, 14, 39, 0, 14, 26, 83, 17, 0,
+  2, 0, 0, 64, 30, 0, 71, 0, 60, 0,
+  49, 0, 15, 71, 0, 0, 0, 0, 7, 6,
+  77, 33, 0, 22, 82, 11, 31, 27, 25, 0,
+  20, 13, 0, 0, 15, 5, 0, 0, 0, 0,
+  62, 3, 0, 0, 23, 0, 15, 37, 0, 0,
+  49, 67, 15, 0, 0, 37, 46, 75, 26, 0,
+  0, 6, 1, 16, 0, 37, 12, 0, 55, 0,
+  9, 28, 40, 0, 0, 0, 4, 0, 26, 26,
+  0, 60, 0, 15, 0, 5, 36, 23, 2, 0,
+  0, 31, 86, 8, 0, 0, 59, 11, 0, 0,
+  65, 56, 0, 25, 23, 0, 0, 13, 0, 13,
+  0, 11, 92, 0, 18, 0, 0, 32, 0, 53,
+  0, 28, 0, 44, 48, 94, 4, 86, 0, 7,
+  0, 38, 52, 0, 35, 0, 21, 0, 24, 0,
+  13, 27, 0, 40, 0, 11, 10, 0, 33, 0,
+  8, 0, 25, 13, 37, 0, 0, 0, 0, 15,
+  39, 0, 14, 13, 0, 0, 0, 0, 0, 24,
+  0, 0, 0, 13, 0, 47, 0, 0, 62, 50,
+  3, 0, 0, 13, 20, 1, 44, 0, 24, 28,
+  0, 29, 0, 15, 0, 0, 25, 0, 11, 10,
+  47, 0, 42, 0, 79, 0, 14, 0, 3, 28,
+  40, 34, 0, 19, 25, 3, 20, 0, 0, 31,
+  114, 0, 21, 37, 61, 3, 0, 0, 0, 74,
+  0, 5, 57, 0, 0, 30, 0, 1, 0, 41,
+  79, 0, 10, 0, 0, 27, 0, 80, 0, 41,
+  32, 32, 31, 55, 32, 23, 0, 44, 0, 50,
+  31, 17, 17, 0, 7, 0, 0, 0, 12, 0,
+  0, 36, 0, 0, 4, 0, 28, 0, 17, 10,
+  0, 3, 3, 0, 15, 36, 0, 33, 36, 0,
+  51, 45, 0, 0, 5, 0, 0, 36, 0, 0,
+  0, 5, 0, 25, 33, 0, 3, 68, 5, 0,
+  5, 7, 24, 0, 28, 0, 2, 10, 6, 14,
+  0, 1, 0, 0, 2, 0, 6, 0, 15, 4,
+  59, 0, 74, 0, 21, 0, 0, 30, 25, 0,
+  1, 3, 33, 18, 0, 0, 0, 0, 0, 38,
+  0, 18, 43, 15, 0, 40, 38, 17, 58, 51,
+  0, 9, 8, 5, 128, 38, 0, 0, 54, 0,
+  69, 16, 0, 30, 0, 38, 21, 38, 0, 22,
+  60, 37, 2, 0, 0, 0, 0, 13, 47, 0,
+  16, 0, 64, 0, 29, 0, 6, 33, 7, 0,
+  0, 0, 7, 19, 25, 0, 0, 36, 79, 26,
+  45, 46, 0, 7, 30, 1, 38, 2, 13, 0,
+  0, 0, 0, 0, 54, 6, 3, 0, 38, 1,
+  15, 56, 0, 0, 37, 35, 9, 0, 0, 19,
+  20, 19, 57, 1, 0, 26, 0, 8, 0, 33,
+  5, 0, 23, 13, 0, 22, 19, 0, 0, 0,
+  19, 0, 11, 9, 0, 48, 13, 14, 0, 0,
+  29, 34, 3, 0, 0, 37, 105, 0, 2, 11,
+  53, 15, 0, 14, 67, 51, 53, 17, 9, 0,
+  0, 9, 0, 0, 0, 0, 96, 0, 32, 9,
+  0, 24, 0, 75, 0, 32, 0, 38, 68, 64,
+  0, 61, 0, 41, 0, 28, 43, 1, 16, 0,
+  14, 0, 11, 0, 0, 0, 0, 18, 0, 0,
+  0, 0, 17, 0, 10, 2, 29, 20, 37, 0,
+  16, 39, 0, 22, 45, 0, 41, 0, 0, 0,
+  0, 0, 0, 7, 0, 0, 0, 7, 0, 48,
+  0, 0, 52, 46, 8, 0, 0, 12, 18, 0,
+  59, 0, 0, 16, 0, 17, 0, 17, 0, 0,
+  14, 0, 6, 8, 40, 0, 40, 0, 76, 0,
+  11, 0, 4, 29, 39, 21, 0, 5, 28, 2,
+  19, 0, 0, 34, 112, 0, 22, 39, 53, 0,
+  0, 0, 0, 83, 0, 10, 59, 0, 0, 23,
+  0, 0, 0, 41, 82, 0, 23, 0, 0, 23,
+  0, 78, 0, 55, 37, 22, 36, 48, 30, 16,
+  0, 54, 0, 60, 33, 24, 31, 0, 11, 0,
+  7, 0, 17, 0, 0, 63, 0, 10, 7, 0,
+  36, 0, 8, 20, 0, 4, 0, 0, 33, 43,
+  0, 29, 44, 0, 61, 29, 0, 0, 0, 0,
+  0, 31, 0, 0, 0, 4, 0, 29, 42, 0,
+  5, 76, 2, 0, 8, 14, 30, 0, 21, 0,
+  0, 0, 8, 15, 0, 0, 0, 0, 0, 0,
+  6, 2, 19, 0, 53, 0, 69, 0, 17, 0,
+  0, 62, 32, 0, 2, 1, 44, 3, 0, 0,
+  16, 4, 12, 0, 5, 53, 33, 30, 0, 74,
+  61, 0, 71, 46, 0, 36, 0, 3, 111, 34,
+  1, 0, 57, 0, 53, 22, 0, 16, 0, 48,
+  40, 30, 5, 36, 99, 16, 0, 12, 0, 8,
+  1, 0, 56, 0, 0, 0, 43, 0, 7, 33,
+  9, 0, 16, 0, 0, 0, 18, 21, 0, 0,
+  8, 32, 42, 43, 43, 31, 0, 15, 0, 0,
+  70, 13, 10, 0, 12, 12, 0, 0, 50, 9,
+  2, 0, 16, 0, 5, 73, 0, 0, 8, 21,
+  2, 0, 0, 16, 17, 0, 77, 9, 0, 22,
+  29, 1, 0, 33, 0, 0, 0, 15, 0, 33,
+  26, 0, 0, 0, 28, 0, 14, 0, 5, 45,
+  49, 8, 0, 13, 12, 23, 0, 0, 0, 49,
+  90, 0, 0, 29, 44, 13, 0, 25, 68, 58,
+  82, 13, 0, 0, 0, 11, 0, 0, 0, 0,
+  81, 0, 34, 31, 0, 20, 0, 59, 2, 29,
+  0, 28, 67, 52, 0, 60, 0, 43, 0, 42,
+  24, 0, 22, 0, 17, 0, 7, 0, 0, 0,
+  0, 9, 8, 0, 0, 0, 16, 0, 14, 13,
+  19, 19, 30, 0, 40, 53, 0, 19, 43, 0,
+  42, 0, 0, 11, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 33, 18, 0, 37, 45, 21, 0,
+  0, 23, 29, 0, 60, 0, 0, 7, 11, 13,
+  0, 17, 0, 0, 0, 0, 1, 9, 37, 0,
+  7, 0, 52, 0, 8, 2, 2, 29, 35, 14,
+  0, 2, 25, 15, 25, 0, 0, 41, 100, 0,
+  19, 33, 52, 0, 0, 0, 0, 93, 0, 8,
+  42, 0, 0, 23, 0, 0, 0, 43, 78, 0,
+  33, 0, 0, 18, 0, 68, 0, 56, 40, 13,
+  39, 47, 17, 12, 0, 48, 0, 63, 25, 25,
+  42, 0, 13, 0, 12, 0, 4, 7, 0, 68,
+  0, 15, 1, 0, 32, 0, 7, 15, 0, 11,
+  0, 0, 44, 48, 0, 33, 43, 0, 60, 25,
+  0, 0, 0, 0, 0, 17, 0, 0, 0, 3,
+  0, 32, 43, 0, 2, 82, 3, 0, 8, 22,
+  34, 0, 25, 0, 0, 0, 17, 10, 0, 0,
+  0, 0, 0, 0, 2, 15, 15, 5, 38, 0,
+  55, 0, 13, 0, 0, 60, 0, 15, 0, 5,
+  36, 23, 2, 0, 0, 31, 86, 8, 0, 0,
+  59, 11, 0, 0, 65, 56, 0, 25, 23, 0,
+  0, 13, 0, 13, 0, 11, 92, 0, 18, 0,
+  0, 32, 0, 53, 0, 28, 0, 44, 48, 94,
+  4, 86, 0, 7, 0, 38, 52, 0, 35, 0,
+  21, 0, 24, 0, 13, 27, 0, 40, 0, 11,
+  10, 0, 33, 0, 8, 0, 25, 13, 37, 0,
+  0, 0, 0, 15, 39, 0, 14, 13, 0, 0,
+  0, 0, 0, 24, 0, 0, 0, 13, 0, 47,
+  0, 0, 62, 50, 3, 0, 0, 13, 20, 1,
+  44, 0, 24, 28, 0, 29, 0, 15, 0, 0,
+  25, 0, 11, 10, 47, 0, 42, 0, 79, 0,
+  14, 0, 3, 28, 40, 34, 0, 19, 25, 3,
+  20, 0, 0, 31, 114, 0, 21, 37, 61, 3,
+  0, 0, 0, 74, 0, 5, 57, 0, 0, 30,
+  0, 1, 0, 41, 79, 0, 10, 0, 0, 27,
+  0, 80, 0, 41, 32, 32, 31, 55, 32, 23,
+  0, 44, 0, 50, 31, 17, 17, 0, 7, 0,
+  0, 0, 12, 0, 0, 36, 0, 0, 4, 0,
+  28, 0, 17, 10, 0, 3, 3, 0, 15, 36,
+  0, 33, 36, 0, 51, 45, 0, 0, 5, 0,
+  0, 36, 0, 0, 0, 5, 0, 25, 33, 0,
+  3, 68, 5, 0, 5, 7, 24, 0, 28, 0,
+  2, 10, 6, 14, 0, 1, 0, 0, 2, 0,
+  6, 0, 15, 4, 59, 0, 74, 0, 21, 0,
+  0, 0, 0, 16, 0, 145, 3, 0, 12, 0,
+  0, 27, 50, 0, 0, 22, 2, 0, 1, 0,
+  35, 91, 18, 9, 3, 0, 0, 0, 0, 4,
+  0, 27, 23, 43, 0, 0, 0, 30, 0, 60,
+  0, 29, 0, 69, 6, 72, 26, 52, 0, 0,
+  0, 48, 12, 0, 0, 0, 56, 0, 35, 0,
+  2, 55, 0, 0, 72, 0, 0, 20, 53, 0,
+  83, 22, 17, 0, 0, 33, 2, 22, 0, 37,
+  41, 0, 32, 49, 7, 0, 27, 0, 0, 0,
+  0, 13, 1, 0, 15, 38, 0, 0, 2, 68,
+  27, 0, 0, 7, 17, 0, 22, 0, 0, 0,
+  0, 0, 0, 29, 0, 0, 104, 4, 40, 7,
+  0, 0, 0, 0, 54, 0, 3, 0, 0, 48,
+  13, 14, 0, 0, 29, 34, 3, 0, 0, 37,
+  105, 0, 2, 11, 53, 15, 0, 14, 67, 51,
+  53, 17, 9, 0, 0, 9, 0, 0, 0, 0,
+  96, 0, 32, 9, 0, 24, 0, 75, 0, 32,
+  0, 38, 68, 64, 0, 61, 0, 41, 0, 28,
+  43, 1, 16, 0, 14, 0, 11, 0, 0, 0,
+  0, 18, 0, 0, 0, 0, 17, 0, 10, 2,
+  29, 20, 37, 0, 16, 39, 0, 22, 45, 0,
+  41, 0, 0, 0, 0, 0, 0, 7, 0, 0,
+  0, 7, 0, 48, 0, 0, 52, 46, 8, 0,
+  0, 12, 18, 0, 59, 0, 0, 16, 0, 17,
+  0, 17, 0, 0, 14, 0, 6, 8, 40, 0,
+  40, 0, 76, 0, 11, 0, 4, 29, 39, 21,
+  0, 5, 28, 2, 19, 0, 0, 34, 112, 0,
+  22, 39, 53, 0, 0, 0, 0, 83, 0, 10,
+  59, 0, 0, 23, 0, 0, 0, 41, 82, 0,
+  23, 0, 0, 23, 0, 78, 0, 55, 37, 22,
+  36, 48, 30, 16, 0, 54, 0, 60, 33, 24,
+  31, 0, 11, 0, 7, 0, 17, 0, 0, 63,
+  0, 10, 7, 0, 36, 0, 8, 20, 0, 4,
+  0, 0, 33, 43, 0, 29, 44, 0, 61, 29,
+  0, 0, 0, 0, 0, 31, 0, 0, 0, 4,
+  0, 29, 42, 0, 5, 76, 2, 0, 8, 14,
+  30, 0, 21, 0, 0, 0, 8, 15, 0, 0,
+  0, 0, 0, 0, 6, 2, 19, 0, 53, 0,
+  69, 0, 17, 0, 0, 0, 0, 10, 0, 139,
+  4, 0, 12, 0, 0, 18, 33, 0, 0, 25,
+  0, 0, 0, 0, 30, 95, 19, 11, 3, 0,
+  0, 0, 0, 0, 0, 27, 29, 38, 0, 0,
+  0, 23, 0, 54, 0, 22, 0, 53, 1, 90,
+  35, 56, 0, 0, 0, 51, 6, 0, 10, 0,
+  55, 0, 49, 0, 11, 61, 0, 0, 76, 3,
+  0, 3, 55, 0, 82, 11, 11, 0, 0, 21,
+  26, 25, 0, 32, 34, 0, 41, 44, 0, 0,
+  22, 0, 0, 7, 0, 21, 4, 0, 4, 31,
+  0, 0, 7, 66, 36, 0, 0, 23, 27, 0,
+  16, 0, 0, 0, 0, 0, 0, 35, 0, 0,
+  100, 2, 34, 1, 0, 0, 0, 0, 28, 0,
+  0, 0, 5, 45, 49, 8, 0, 13, 12, 23,
+  0, 0, 0, 49, 90, 0, 0, 29, 44, 13,
+  0, 25, 68, 58, 82, 13, 0, 0, 0, 11,
+  0, 0, 0, 0, 81, 0, 34, 31, 0, 20,
+  0, 59, 2, 29, 0, 28, 67, 52, 0, 60,
+  0, 43, 0, 42, 24, 0, 22, 0, 17, 0,
+  7, 0, 0, 0, 0, 9, 8, 0, 0, 0,
+  16, 0, 14, 13, 19, 19, 30, 0, 40, 53,
+  0, 19, 43, 0, 42, 0, 0, 11, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 33, 18, 0,
+  37, 45, 21, 0, 0, 23, 29, 0, 60, 0,
+  0, 7, 11, 13, 0, 17, 0, 0, 0, 0,
+  1, 9, 37, 0, 7, 0, 52, 0, 8, 2,
+  2, 29, 35, 14, 0, 2, 25, 15, 25, 0,
+  0, 41, 100, 0, 19, 33, 52, 0, 0, 0,
+  0, 93, 0, 8, 42, 0, 0, 23, 0, 0,
+  0, 43, 78, 0, 33, 0, 0, 18, 0, 68,
+  0, 56, 40, 13, 39, 47, 17, 12, 0, 48,
+  0, 63, 25, 25, 42, 0, 13, 0, 12, 0,
+  4, 7, 0, 68, 0, 15, 1, 0, 32, 0,
+  7, 15, 0, 11, 0, 0, 44, 48, 0, 33,
+  43, 0, 60, 25, 0, 0, 0, 0, 0, 17,
+  0, 0, 0, 3, 0, 32, 43, 0, 2, 82,
+  3, 0, 8, 22, 34, 0, 25, 0, 0, 0,
+  17, 10, 0, 0, 0, 0, 0, 0, 2, 15,
+  15, 5, 38, 0, 55, 0, 13, 0, 0, 0,
+  0, 2, 0, 130, 10, 0, 4, 0, 0, 17,
+  27, 0, 0, 13, 0, 0, 0, 0, 39, 101,
+  22, 12, 0, 0, 0, 0, 0, 3, 0, 24,
+  35, 28, 1, 0, 0, 22, 0, 43, 0, 20,
+  0, 45, 17, 92, 24, 56, 0, 1, 0, 50,
+  0, 0, 17, 0, 51, 0, 51, 0, 0, 57,
+  0, 0, 72, 8, 0, 8, 34, 0, 64, 5,
+  28, 6, 0, 15, 34, 35, 0, 21, 42, 0,
+  36, 58, 0, 0, 16, 0, 0, 0, 0, 14,
+  4, 0, 0, 35, 0, 0, 0, 63, 44, 0,
+  0, 33, 35, 0, 21, 0, 0, 0, 3, 0,
+  0, 32, 0, 0, 109, 11, 25, 17, 0, 0,
+  0, 0, 15, 0, 0, 0, 3, 28, 40, 34,
+  0, 19, 25, 3, 20, 0, 0, 31, 114, 0,
+  21, 37, 61, 3, 0, 0, 0, 74, 0, 5,
+  57, 0, 0, 30, 0, 1, 0, 41, 79, 0,
+  10, 0, 0, 27, 0, 80, 0, 41, 32, 32,
+  31, 55, 32, 23, 0, 44, 0, 50, 31, 17,
+  17, 0, 7, 0, 0, 0, 12, 0, 0, 36,
+  0, 0, 4, 0, 28, 0, 17, 10, 0, 3,
+  3, 0, 15, 36, 0, 33, 36, 0, 51, 45,
+  0, 0, 5, 0, 0, 36, 0, 0, 0, 5,
+  0, 25, 33, 0, 3, 68, 5, 0, 5, 7,
+  24, 0, 28, 0, 2, 10, 6, 14, 0, 1,
+  0, 0, 2, 0, 6, 0, 15, 4, 59, 0,
+  74, 0, 21, 0, 0, 0, 0, 16, 0, 145,
+  3, 0, 12, 0, 0, 27, 50, 0, 0, 22,
+  2, 0, 1, 0, 35, 91, 18, 9, 3, 0,
+  0, 0, 0, 4, 0, 27, 23, 43, 0, 0,
+  0, 30, 0, 60, 0, 29, 0, 69, 6, 72,
+  26, 52, 0, 0, 0, 48, 12, 0, 0, 0,
+  56, 0, 35, 0, 2, 55, 0, 0, 72, 0,
+  0, 20, 53, 0, 83, 22, 17, 0, 0, 33,
+  2, 22, 0, 37, 41, 0, 32, 49, 7, 0,
+  27, 0, 0, 0, 0, 13, 1, 0, 15, 38,
+  0, 0, 2, 68, 27, 0, 0, 7, 17, 0,
+  22, 0, 0, 0, 0, 0, 0, 29, 0, 0,
+  104, 4, 40, 7, 0, 0, 0, 0, 54, 0,
+  3, 0, 0, 0, 0, 0, 0, 45, 41, 0,
+  20, 0, 0, 0, 75, 11, 19, 55, 39, 21,
+  25, 2, 84, 0, 0, 27, 13, 52, 3, 2,
+  0, 52, 0, 0, 56, 63, 0, 0, 0, 0,
+  0, 59, 0, 43, 0, 45, 7, 20, 17, 36,
+  0, 46, 0, 0, 66, 22, 0, 0, 25, 0,
+  0, 76, 20, 0, 0, 2, 0, 0, 13, 21,
+  31, 0, 0, 26, 0, 14, 8, 55, 0, 0,
+  0, 54, 58, 17, 20, 5, 37, 0, 12, 14,
+  8, 14, 4, 15, 7, 17, 1, 41, 0, 0,
+  39, 55, 6, 0, 4, 0, 0, 0, 35, 0,
+  0, 42, 13, 0, 0, 5, 0, 0, 43, 15,
+  52, 0, 18, 3, 121, 0, 68, 0, 9, 0,
+  4, 29, 39, 21, 0, 5, 28, 2, 19, 0,
+  0, 34, 112, 0, 22, 39, 53, 0, 0, 0,
+  0, 83, 0, 10, 59, 0, 0, 23, 0, 0,
+  0, 41, 82, 0, 23, 0, 0, 23, 0, 78,
+  0, 55, 37, 22, 36, 48, 30, 16, 0, 54,
+  0, 60, 33, 24, 31, 0, 11, 0, 7, 0,
+  17, 0, 0, 63, 0, 10, 7, 0, 36, 0,
+  8, 20, 0, 4, 0, 0, 33, 43, 0, 29,
+  44, 0, 61, 29, 0, 0, 0, 0, 0, 31,
+  0, 0, 0, 4, 0, 29, 42, 0, 5, 76,
+  2, 0, 8, 14, 30, 0, 21, 0, 0, 0,
+  8, 15, 0, 0, 0, 0, 0, 0, 6, 2,
+  19, 0, 53, 0, 69, 0, 17, 0, 0, 0,
+  0, 10, 0, 139, 4, 0, 12, 0, 0, 18,
+  33, 0, 0, 25, 0, 0, 0, 0, 30, 95,
+  19, 11, 3, 0, 0, 0, 0, 0, 0, 27,
+  29, 38, 0, 0, 0, 23, 0, 54, 0, 22,
+  0, 53, 1, 90, 35, 56, 0, 0, 0, 51,
+  6, 0, 10, 0, 55, 0, 49, 0, 11, 61,
+  0, 0, 76, 3, 0, 3, 55, 0, 82, 11,
+  11, 0, 0, 21, 26, 25, 0, 32, 34, 0,
+  41, 44, 0, 0, 22, 0, 0, 7, 0, 21,
+  4, 0, 4, 31, 0, 0, 7, 66, 36, 0,
+  0, 23, 27, 0, 16, 0, 0, 0, 0, 0,
+  0, 35, 0, 0, 100, 2, 34, 1, 0, 0,
+  0, 0, 28, 0, 0, 0, 0, 0, 0, 0,
+  9, 38, 29, 0, 28, 0, 15, 0, 49, 21,
+  13, 59, 25, 11, 12, 5, 68, 0, 0, 42,
+  2, 24, 1, 0, 0, 35, 0, 0, 51, 61,
+  4, 0, 0, 0, 0, 42, 8, 38, 0, 45,
+  9, 26, 16, 31, 0, 20, 23, 0, 74, 24,
+  0, 0, 43, 0, 0, 56, 26, 7, 0, 0,
+  0, 0, 26, 8, 30, 0, 0, 7, 0, 8,
+  2, 45, 9, 0, 0, 52, 52, 14, 29, 21,
+  20, 0, 7, 19, 17, 28, 6, 32, 0, 6,
+  20, 41, 0, 0, 30, 59, 7, 0, 1, 0,
+  0, 0, 35, 0, 0, 25, 13, 0, 0, 13,
+  0, 0, 41, 20, 37, 0, 1, 0, 90, 0,
+  36, 0, 0, 0, 2, 29, 35, 14, 0, 2,
+  25, 15, 25, 0, 0, 41, 100, 0, 19, 33,
+  52, 0, 0, 0, 0, 93, 0, 8, 42, 0,
+  0, 23, 0, 0, 0, 43, 78, 0, 33, 0,
+  0, 18, 0, 68, 0, 56, 40, 13, 39, 47,
+  17, 12, 0, 48, 0, 63, 25, 25, 42, 0,
+  13, 0, 12, 0, 4, 7, 0, 68, 0, 15,
+  1, 0, 32, 0, 7, 15, 0, 11, 0, 0,
+  44, 48, 0, 33, 43, 0, 60, 25, 0, 0,
+  0, 0, 0, 17, 0, 0, 0, 3, 0, 32,
+  43, 0, 2, 82, 3, 0, 8, 22, 34, 0,
+  25, 0, 0, 0, 17, 10, 0, 0, 0, 0,
+  0, 0, 2, 15, 15, 5, 38, 0, 55, 0,
+  13, 0, 0, 0, 0, 2, 0, 130, 10, 0,
+  4, 0, 0, 17, 27, 0, 0, 13, 0, 0,
+  0, 0, 39, 101, 22, 12, 0, 0, 0, 0,
+  0, 3, 0, 24, 35, 28, 1, 0, 0, 22,
+  0, 43, 0, 20, 0, 45, 17, 92, 24, 56,
+  0, 1, 0, 50, 0, 0, 17, 0, 51, 0,
+  51, 0, 0, 57, 0, 0, 72, 8, 0, 8,
+  34, 0, 64, 5, 28, 6, 0, 15, 34, 35,
+  0, 21, 42, 0, 36, 58, 0, 0, 16, 0,
+  0, 0, 0, 14, 4, 0, 0, 35, 0, 0,
+  0, 63, 44, 0, 0, 33, 35, 0, 21, 0,
+  0, 0, 3, 0, 0, 32, 0, 0, 109, 11,
+  25, 17, 0, 0, 0, 0, 15, 0, 0, 0,
+  0, 0, 0, 0, 0, 30, 33, 0, 19, 0,
+  21, 0, 43, 0, 16, 54, 29, 19, 0, 10,
+  66, 0, 0, 44, 0, 21, 4, 0, 0, 41,
+  0, 0, 53, 56, 9, 0, 0, 0, 0, 18,
+  0, 34, 0, 47, 24, 21, 4, 29, 0, 18,
+  41, 0, 75, 14, 0, 0, 37, 0, 0, 75,
+  15, 0, 0, 0, 0, 0, 34, 16, 0, 0,
+  0, 2, 0, 21, 12, 35, 14, 9, 0, 42,
+  59, 0, 15, 48, 23, 0, 5, 24, 11, 27,
+  9, 21, 0, 6, 17, 45, 0, 0, 9, 43,
+  26, 0, 0, 0, 17, 0, 51, 8, 2, 21,
+  33, 2, 0, 20, 0, 0, 46, 39, 44, 11,
+  0, 0, 80, 0, 29, 15, 0, 0, 0, 0,
+  0, 16, 0, 145, 3, 0, 12, 0, 0, 27,
+  50, 0, 0, 22, 2, 0, 1, 0, 35, 91,
+  18, 9, 3, 0, 0, 0, 0, 4, 0, 27,
+  23, 43, 0, 0, 0, 30, 0, 60, 0, 29,
+  0, 69, 6, 72, 26, 52, 0, 0, 0, 48,
+  12, 0, 0, 0, 56, 0, 35, 0, 2, 55,
+  0, 0, 72, 0, 0, 20, 53, 0, 83, 22,
+  17, 0, 0, 33, 2, 22, 0, 37, 41, 0,
+  32, 49, 7, 0, 27, 0, 0, 0, 0, 13,
+  1, 0, 15, 38, 0, 0, 2, 68, 27, 0,
+  0, 7, 17, 0, 22, 0, 0, 0, 0, 0,
+  0, 29, 0, 0, 104, 4, 40, 7, 0, 0,
+  0, 0, 54, 0, 3, 0, 0, 0, 0, 0,
+  0, 45, 41, 0, 20, 0, 0, 0, 75, 11,
+  19, 55, 39, 21, 25, 2, 84, 0, 0, 27,
+  13, 52, 3, 2, 0, 52, 0, 0, 56, 63,
+  0, 0, 0, 0, 0, 59, 0, 43, 0, 45,
+  7, 20, 17, 36, 0, 46, 0, 0, 66, 22,
+  0, 0, 25, 0, 0, 76, 20, 0, 0, 2,
+  0, 0, 13, 21, 31, 0, 0, 26, 0, 14,
+  8, 55, 0, 0, 0, 54, 58, 17, 20, 5,
+  37, 0, 12, 14, 8, 14, 4, 15, 7, 17,
+  1, 41, 0, 0, 39, 55, 6, 0, 4, 0,
+  0, 0, 35, 0, 0, 42, 13, 0, 0, 5,
+  0, 0, 43, 15, 52, 0, 18, 3, 121, 0,
+  68, 0, 9, 0, 0, 49, 1, 0, 30, 0,
+  15, 0, 64, 0, 0, 7, 46, 41, 52, 60,
+  59, 47, 14, 4, 85, 0, 0, 29, 21, 32,
+  22, 9, 0, 19, 0, 0, 33, 0, 0, 0,
+  0, 0, 0, 62, 0, 0, 0, 54, 0, 32,
+  4, 0, 0, 16, 7, 12, 54, 37, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+  49, 0, 30, 0, 0, 0, 5, 29, 27, 0,
+  0, 9, 0, 21, 35, 23, 45, 0, 23, 22,
+  4, 26, 21, 30, 26, 0, 0, 24, 0, 19,
+  0, 0, 46, 43, 11, 0, 0, 0, 0, 0,
+  30, 1, 0, 44, 0, 0, 0, 16, 0, 0,
+  1, 3, 6, 0, 0, 0, 95, 0, 52, 0,
+  20, 0, 0, 0, 0, 10, 0, 139, 4, 0,
+  12, 0, 0, 18, 33, 0, 0, 25, 0, 0,
+  0, 0, 30, 95, 19, 11, 3, 0, 0, 0,
+  0, 0, 0, 27, 29, 38, 0, 0, 0, 23,
+  0, 54, 0, 22, 0, 53, 1, 90, 35, 56,
+  0, 0, 0, 51, 6, 0, 10, 0, 55, 0,
+  49, 0, 11, 61, 0, 0, 76, 3, 0, 3,
+  55, 0, 82, 11, 11, 0, 0, 21, 26, 25,
+  0, 32, 34, 0, 41, 44, 0, 0, 22, 0,
+  0, 7, 0, 21, 4, 0, 4, 31, 0, 0,
+  7, 66, 36, 0, 0, 23, 27, 0, 16, 0,
+  0, 0, 0, 0, 0, 35, 0, 0, 100, 2,
+  34, 1, 0, 0, 0, 0, 28, 0, 0, 0,
+  0, 0, 0, 0, 9, 38, 29, 0, 28, 0,
+  15, 0, 49, 21, 13, 59, 25, 11, 12, 5,
+  68, 0, 0, 42, 2, 24, 1, 0, 0, 35,
+  0, 0, 51, 61, 4, 0, 0, 0, 0, 42,
+  8, 38, 0, 45, 9, 26, 16, 31, 0, 20,
+  23, 0, 74, 24, 0, 0, 43, 0, 0, 56,
+  26, 7, 0, 0, 0, 0, 26, 8, 30, 0,
+  0, 7, 0, 8, 2, 45, 9, 0, 0, 52,
+  52, 14, 29, 21, 20, 0, 7, 19, 17, 28,
+  6, 32, 0, 6, 20, 41, 0, 0, 30, 59,
+  7, 0, 1, 0, 0, 0, 35, 0, 0, 25,
+  13, 0, 0, 13, 0, 0, 41, 20, 37, 0,
+  1, 0, 90, 0, 36, 0, 0, 0, 0, 41,
+  38, 0, 0, 0, 0, 0, 61, 6, 0, 16,
+  12, 19, 25, 54, 49, 37, 21, 5, 43, 0,
+  53, 32, 0, 0, 35, 21, 0, 0, 0, 0,
+  32, 0, 3, 0, 0, 0, 0, 35, 0, 0,
+  0, 27, 0, 26, 0, 0, 0, 15, 28, 3,
+  38, 9, 0, 0, 27, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 56, 0, 5, 0, 0, 0,
+  1, 44, 11, 11, 0, 62, 0, 23, 13, 12,
+  56, 44, 1, 24, 0, 29, 27, 31, 52, 10,
+  0, 0, 12, 0, 0, 0, 11, 51, 42, 0,
+  0, 0, 0, 0, 41, 0, 0, 48, 5, 0,
+  0, 10, 0, 0, 7, 0, 0, 0, 0, 0,
+  47, 0, 21, 0, 1, 20, 0, 0, 0, 2,
+  0, 130, 10, 0, 4, 0, 0, 17, 27, 0,
+  0, 13, 0, 0, 0, 0, 39, 101, 22, 12,
+  0, 0, 0, 0, 0, 3, 0, 24, 35, 28,
+  1, 0, 0, 22, 0, 43, 0, 20, 0, 45,
+  17, 92, 24, 56, 0, 1, 0, 50, 0, 0,
+  17, 0, 51, 0, 51, 0, 0, 57, 0, 0,
+  72, 8, 0, 8, 34, 0, 64, 5, 28, 6,
+  0, 15, 34, 35, 0, 21, 42, 0, 36, 58,
+  0, 0, 16, 0, 0, 0, 0, 14, 4, 0,
+  0, 35, 0, 0, 0, 63, 44, 0, 0, 33,
+  35, 0, 21, 0, 0, 0, 3, 0, 0, 32,
+  0, 0, 109, 11, 25, 17, 0, 0, 0, 0,
+  15, 0, 0, 0, 0, 0, 0, 0, 0, 30,
+  33, 0, 19, 0, 21, 0, 43, 0, 16, 54,
+  29, 19, 0, 10, 66, 0, 0, 44, 0, 21,
+  4, 0, 0, 41, 0, 0, 53, 56, 9, 0,
+  0, 0, 0, 18, 0, 34, 0, 47, 24, 21,
+  4, 29, 0, 18, 41, 0, 75, 14, 0, 0,
+  37, 0, 0, 75, 15, 0, 0, 0, 0, 0,
+  34, 16, 0, 0, 0, 2, 0, 21, 12, 35,
+  14, 9, 0, 42, 59, 0, 15, 48, 23, 0,
+  5, 24, 11, 27, 9, 21, 0, 6, 17, 45,
+  0, 0, 9, 43, 26, 0, 0, 0, 17, 0,
+  51, 8, 2, 21, 33, 2, 0, 20, 0, 0,
+  46, 39, 44, 11, 0, 0, 80, 0, 29, 15,
+  0, 0, 0, 47, 63, 0, 0, 0, 0, 0,
+  44, 1, 0, 11, 10, 3, 0, 58, 41, 16,
+  11, 0, 10, 0, 65, 40, 0, 0, 36, 16,
+  0, 0, 0, 0, 20, 0, 20, 14, 0, 0,
+  0, 16, 0, 3, 0, 22, 0, 2, 0, 0,
+  0, 1, 57, 3, 31, 0, 0, 0, 29, 0,
+  0, 14, 3, 0, 0, 0, 16, 0, 39, 2,
+  0, 0, 0, 0, 0, 49, 17, 0, 0, 86,
+  0, 30, 13, 0, 52, 56, 3, 30, 0, 29,
+  23, 24, 50, 0, 0, 0, 17, 0, 0, 0,
+  0, 53, 48, 0, 0, 0, 13, 0, 61, 0,
+  0, 31, 25, 0, 0, 5, 0, 0, 7, 0,
+  0, 16, 0, 0, 30, 0, 18, 13, 0, 31,
+  0, 0, 0, 0, 0, 45, 41, 0, 20, 0,
+  0, 0, 75, 11, 19, 55, 39, 21, 25, 2,
+  84, 0, 0, 27, 13, 52, 3, 2, 0, 52,
+  0, 0, 56, 63, 0, 0, 0, 0, 0, 59,
+  0, 43, 0, 45, 7, 20, 17, 36, 0, 46,
+  0, 0, 66, 22, 0, 0, 25, 0, 0, 76,
+  20, 0, 0, 2, 0, 0, 13, 21, 31, 0,
+  0, 26, 0, 14, 8, 55, 0, 0, 0, 54,
+  58, 17, 20, 5, 37, 0, 12, 14, 8, 14,
+  4, 15, 7, 17, 1, 41, 0, 0, 39, 55,
+  6, 0, 4, 0, 0, 0, 35, 0, 0, 42,
+  13, 0, 0, 5, 0, 0, 43, 15, 52, 0,
+  18, 3, 121, 0, 68, 0, 9, 0, 0, 49,
+  1, 0, 30, 0, 15, 0, 64, 0, 0, 7,
+  46, 41, 52, 60, 59, 47, 14, 4, 85, 0,
+  0, 29, 21, 32, 22, 9, 0, 19, 0, 0,
+  33, 0, 0, 0, 0, 0, 0, 62, 0, 0,
+  0, 54, 0, 32, 4, 0, 0, 16, 7, 12,
+  54, 37, 0, 0, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 49, 0, 30, 0, 0, 0,
+  5, 29, 27, 0, 0, 9, 0, 21, 35, 23,
+  45, 0, 23, 22, 4, 26, 21, 30, 26, 0,
+  0, 24, 0, 19, 0, 0, 46, 43, 11, 0,
+  0, 0, 0, 0, 30, 1, 0, 44, 0, 0,
+  0, 16, 0, 0, 1, 3, 6, 0, 0, 0,
+  95, 0, 52, 0, 20, 0, 0, 44, 27, 0,
+  33, 0, 0, 0, 76, 0, 0, 1, 67, 69,
+  11, 51, 63, 32, 6, 0, 66, 0, 0, 38,
+  0, 0, 28, 40, 0, 0, 0, 0, 7, 0,
+  0, 0, 0, 27, 0, 47, 0, 0, 0, 20,
+  0, 38, 0, 0, 0, 16, 0, 34, 21, 7,
+  0, 0, 0, 8, 0, 0, 0, 0, 0, 0,
+  0, 0, 98, 0, 25, 5, 0, 0, 0, 78,
+  9, 0, 0, 35, 0, 0, 12, 5, 38, 41,
+  20, 53, 0, 44, 32, 14, 27, 37, 0, 13,
+  0, 0, 0, 0, 28, 63, 38, 0, 0, 0,
+  0, 0, 3, 36, 0, 61, 0, 0, 0, 5,
+  3, 0, 4, 0, 0, 0, 0, 0, 77, 0,
+  26, 0, 18, 21, 0, 0, 0, 0, 9, 38,
+  29, 0, 28, 0, 15, 0, 49, 21, 13, 59,
+  25, 11, 12, 5, 68, 0, 0, 42, 2, 24,
+  1, 0, 0, 35, 0, 0, 51, 61, 4, 0,
+  0, 0, 0, 42, 8, 38, 0, 45, 9, 26,
+  16, 31, 0, 20, 23, 0, 74, 24, 0, 0,
+  43, 0, 0, 56, 26, 7, 0, 0, 0, 0,
+  26, 8, 30, 0, 0, 7, 0, 8, 2, 45,
+  9, 0, 0, 52, 52, 14, 29, 21, 20, 0,
+  7, 19, 17, 28, 6, 32, 0, 6, 20, 41,
+  0, 0, 30, 59, 7, 0, 1, 0, 0, 0,
+  35, 0, 0, 25, 13, 0, 0, 13, 0, 0,
+  41, 20, 37, 0, 1, 0, 90, 0, 36, 0,
+  0, 0, 0, 41, 38, 0, 0, 0, 0, 0,
+  61, 6, 0, 16, 12, 19, 25, 54, 49, 37,
+  21, 5, 43, 0, 53, 32, 0, 0, 35, 21,
+  0, 0, 0, 0, 32, 0, 3, 0, 0, 0,
+  0, 35, 0, 0, 0, 27, 0, 26, 0, 0,
+  0, 15, 28, 3, 38, 9, 0, 0, 27, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 56, 0,
+  5, 0, 0, 0, 1, 44, 11, 11, 0, 62,
+  0, 23, 13, 12, 56, 44, 1, 24, 0, 29,
+  27, 31, 52, 10, 0, 0, 12, 0, 0, 0,
+  11, 51, 42, 0, 0, 0, 0, 0, 41, 0,
+  0, 48, 5, 0, 0, 10, 0, 0, 7, 0,
+  0, 0, 0, 0, 47, 0, 21, 0, 1, 20,
+  52, 0, 43, 0, 22, 0, 0, 0, 29, 0,
+  0, 0, 38, 88, 0, 0, 38, 0, 13, 0,
+  33, 104, 68, 26, 0, 0, 8, 50, 0, 0,
+  0, 10, 0, 4, 0, 0, 0, 20, 0, 11,
+  1, 0, 0, 0, 0, 16, 0, 0, 0, 7,
+  0, 77, 0, 0, 52, 0, 26, 23, 6, 0,
+  25, 0, 0, 6, 24, 0, 92, 16, 18, 73,
+  0, 0, 0, 73, 0, 0, 0, 50, 0, 0,
+  0, 0, 11, 59, 10, 49, 0, 55, 10, 0,
+  0, 37, 0, 0, 5, 0, 13, 0, 23, 61,
+  29, 7, 1, 0, 19, 2, 0, 26, 0, 53,
+  0, 7, 0, 0, 0, 23, 69, 0, 1, 0,
+  0, 31, 0, 0, 4, 0, 0, 61, 0, 0,
+  0, 0, 0, 30, 33, 0, 19, 0, 21, 0,
+  43, 0, 16, 54, 29, 19, 0, 10, 66, 0,
+  0, 44, 0, 21, 4, 0, 0, 41, 0, 0,
+  53, 56, 9, 0, 0, 0, 0, 18, 0, 34,
+  0, 47, 24, 21, 4, 29, 0, 18, 41, 0,
+  75, 14, 0, 0, 37, 0, 0, 75, 15, 0,
+  0, 0, 0, 0, 34, 16, 0, 0, 0, 2,
+  0, 21, 12, 35, 14, 9, 0, 42, 59, 0,
+  15, 48, 23, 0, 5, 24, 11, 27, 9, 21,
+  0, 6, 17, 45, 0, 0, 9, 43, 26, 0,
+  0, 0, 17, 0, 51, 8, 2, 21, 33, 2,
+  0, 20, 0, 0, 46, 39, 44, 11, 0, 0,
+  80, 0, 29, 15, 0, 0, 0, 47, 63, 0,
+  0, 0, 0, 0, 44, 1, 0, 11, 10, 3,
+  0, 58, 41, 16, 11, 0, 10, 0, 65, 40,
+  0, 0, 36, 16, 0, 0, 0, 0, 20, 0,
+  20, 14, 0, 0, 0, 16, 0, 3, 0, 22,
+  0, 2, 0, 0, 0, 1, 57, 3, 31, 0,
+  0, 0, 29, 0, 0, 14, 3, 0, 0, 0,
+  16, 0, 39, 2, 0, 0, 0, 0, 0, 49,
+  17, 0, 0, 86, 0, 30, 13, 0, 52, 56,
+  3, 30, 0, 29, 23, 24, 50, 0, 0, 0,
+  17, 0, 0, 0, 0, 53, 48, 0, 0, 0,
+  13, 0, 61, 0, 0, 31, 25, 0, 0, 5,
+  0, 0, 7, 0, 0, 16, 0, 0, 30, 0,
+  18, 13, 0, 31, 103, 0, 37, 5, 6, 15,
+  0, 0, 15, 0, 0, 23, 47, 54, 0, 0,
+  22, 0, 6, 0, 0, 173, 80, 13, 0, 0,
+  0, 33, 0, 0, 2, 56, 0, 34, 0, 21,
+  0, 29, 0, 25, 0, 22, 0, 0, 27, 6,
+  10, 8, 0, 0, 0, 77, 0, 0, 89, 0,
+  43, 20, 45, 0, 35, 11, 0, 32, 30, 49,
+  7, 15, 23, 23, 7, 28, 0, 22, 0, 0,
+  3, 45, 0, 13, 0, 0, 4, 42, 8, 27,
+  0, 9, 0, 0, 0, 0, 8, 0, 7, 0,
+  24, 0, 27, 61, 2, 0, 25, 0, 40, 28,
+  4, 8, 10, 35, 4, 0, 0, 0, 0, 15,
+  78, 0, 23, 10, 0, 35, 0, 0, 20, 3,
+  3, 48, 0, 49, 1, 0, 30, 0, 15, 0,
+  64, 0, 0, 7, 46, 41, 52, 60, 59, 47,
+  14, 4, 85, 0, 0, 29, 21, 32, 22, 9,
+  0, 19, 0, 0, 33, 0, 0, 0, 0, 0,
+  0, 62, 0, 0, 0, 54, 0, 32, 4, 0,
+  0, 16, 7, 12, 54, 37, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0, 0, 0, 49, 0,
+  30, 0, 0, 0, 5, 29, 27, 0, 0, 9,
+  0, 21, 35, 23, 45, 0, 23, 22, 4, 26,
+  21, 30, 26, 0, 0, 24, 0, 19, 0, 0,
+  46, 43, 11, 0, 0, 0, 0, 0, 30, 1,
+  0, 44, 0, 0, 0, 16, 0, 0, 1, 3,
+  6, 0, 0, 0, 95, 0, 52, 0, 20, 0,
+  0, 44, 27, 0, 33, 0, 0, 0, 76, 0,
+  0, 1, 67, 69, 11, 51, 63, 32, 6, 0,
+  66, 0, 0, 38, 0, 0, 28, 40, 0, 0,
+  0, 0, 7, 0, 0, 0, 0, 27, 0, 47,
+  0, 0, 0, 20, 0, 38, 0, 0, 0, 16,
+  0, 34, 21, 7, 0, 0, 0, 8, 0, 0,
+  0, 0, 0, 0, 0, 0, 98, 0, 25, 5,
+  0, 0, 0, 78, 9, 0, 0, 35, 0, 0,
+  12, 5, 38, 41, 20, 53, 0, 44, 32, 14,
+  27, 37, 0, 13, 0, 0, 0, 0, 28, 63,
+  38, 0, 0, 0, 0, 0, 3, 36, 0, 61,
+  0, 0, 0, 5, 3, 0, 4, 0, 0, 0,
+  0, 0, 77, 0, 26, 0, 18, 21, 29, 0,
+  57, 0, 12, 30, 0, 0, 52, 0, 0, 2,
+  43, 101, 14, 0, 40, 0, 0, 0, 32, 66,
+  0, 35, 0, 0, 0, 29, 0, 8, 0, 0,
+  0, 11, 0, 0, 0, 50, 0, 48, 0, 31,
+  0, 0, 0, 0, 0, 0, 6, 9, 0, 67,
+  0, 0, 11, 0, 13, 40, 0, 0, 5, 7,
+  0, 44, 0, 15, 58, 0, 30, 45, 0, 14,
+  0, 32, 0, 0, 0, 10, 0, 27, 0, 3,
+  29, 32, 45, 49, 0, 64, 21, 0, 0, 14,
+  0, 0, 0, 0, 0, 0, 30, 78, 0, 0,
+  0, 0, 0, 18, 0, 23, 14, 57, 17, 0,
+  0, 0, 29, 0, 59, 1, 9, 2, 0, 17,
+  0, 0, 0, 0, 0, 41, 0, 41, 38, 0,
+  0, 0, 0, 0, 61, 6, 0, 16, 12, 19,
+  25, 54, 49, 37, 21, 5, 43, 0, 53, 32,
+  0, 0, 35, 21, 0, 0, 0, 0, 32, 0,
+  3, 0, 0, 0, 0, 35, 0, 0, 0, 27,
+  0, 26, 0, 0, 0, 15, 28, 3, 38, 9,
+  0, 0, 27, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 56, 0, 5, 0, 0, 0, 1, 44,
+  11, 11, 0, 62, 0, 23, 13, 12, 56, 44,
+  1, 24, 0, 29, 27, 31, 52, 10, 0, 0,
+  12, 0, 0, 0, 11, 51, 42, 0, 0, 0,
+  0, 0, 41, 0, 0, 48, 5, 0, 0, 10,
+  0, 0, 7, 0, 0, 0, 0, 0, 47, 0,
+  21, 0, 1, 20, 52, 0, 43, 0, 22, 0,
+  0, 0, 29, 0, 0, 0, 38, 88, 0, 0,
+  38, 0, 13, 0, 33, 104, 68, 26, 0, 0,
+  8, 50, 0, 0, 0, 10, 0, 4, 0, 0,
+  0, 20, 0, 11, 1, 0, 0, 0, 0, 16,
+  0, 0, 0, 7, 0, 77, 0, 0, 52, 0,
+  26, 23, 6, 0, 25, 0, 0, 6, 24, 0,
+  92, 16, 18, 73, 0, 0, 0, 73, 0, 0,
+  0, 50, 0, 0, 0, 0, 11, 59, 10, 49,
+  0, 55, 10, 0, 0, 37, 0, 0, 5, 0,
+  13, 0, 23, 61, 29, 7, 1, 0, 19, 2,
+  0, 26, 0, 53, 0, 7, 0, 0, 0, 23,
+  69, 0, 1, 0, 0, 31, 0, 0, 4, 0,
+  0, 61, 44, 0, 0, 0, 25, 73, 0, 0,
+  7, 0, 0, 0, 26, 81, 0, 0, 48, 0,
+  0, 0, 40, 70, 0, 48, 0, 0, 0, 16,
+  0, 0, 0, 0, 0, 39, 0, 0, 0, 36,
+  0, 27, 0, 6, 0, 0, 20, 1, 0, 24,
+  22, 0, 0, 39, 0, 0, 0, 0, 10, 25,
+  0, 0, 31, 12, 0, 4, 0, 0, 87, 23,
+  22, 30, 0, 6, 0, 43, 7, 0, 0, 5,
+  0, 16, 0, 0, 0, 7, 9, 33, 0, 49,
+  1, 0, 0, 56, 0, 0, 0, 0, 0, 0,
+  17, 64, 6, 22, 16, 0, 10, 13, 0, 13,
+  8, 65, 0, 0, 0, 0, 0, 16, 82, 0,
+  8, 0, 12, 7, 0, 0, 0, 7, 4, 20,
+  0, 47, 63, 0, 0, 0, 0, 0, 44, 1,
+  0, 11, 10, 3, 0, 58, 41, 16, 11, 0,
+  10, 0, 65, 40, 0, 0, 36, 16, 0, 0,
+  0, 0, 20, 0, 20, 14, 0, 0, 0, 16,
+  0, 3, 0, 22, 0, 2, 0, 0, 0, 1,
+  57, 3, 31, 0, 0, 0, 29, 0, 0, 14,
+  3, 0, 0, 0, 16, 0, 39, 2, 0, 0,
+  0, 0, 0, 49, 17, 0, 0, 86, 0, 30,
+  13, 0, 52, 56, 3, 30, 0, 29, 23, 24,
+  50, 0, 0, 0, 17, 0, 0, 0, 0, 53,
+  48, 0, 0, 0, 13, 0, 61, 0, 0, 31,
+  25, 0, 0, 5, 0, 0, 7, 0, 0, 16,
+  0, 0, 30, 0, 18, 13, 0, 31, 103, 0,
+  37, 5, 6, 15, 0, 0, 15, 0, 0, 23,
+  47, 54, 0, 0, 22, 0, 6, 0, 0, 173,
+  80, 13, 0, 0, 0, 33, 0, 0, 2, 56,
+  0, 34, 0, 21, 0, 29, 0, 25, 0, 22,
+  0, 0, 27, 6, 10, 8, 0, 0, 0, 77,
+  0, 0, 89, 0, 43, 20, 45, 0, 35, 11,
+  0, 32, 30, 49, 7, 15, 23, 23, 7, 28,
+  0, 22, 0, 0, 3, 45, 0, 13, 0, 0,
+  4, 42, 8, 27, 0, 9, 0, 0, 0, 0,
+  8, 0, 7, 0, 24, 0, 27, 61, 2, 0,
+  25, 0, 40, 28, 4, 8, 10, 35, 4, 0,
+  0, 0, 0, 15, 78, 0, 23, 10, 0, 35,
+  0, 0, 20, 3, 3, 48, 45, 0, 0, 0,
+  22, 82, 0, 0, 8, 0, 0, 0, 29, 61,
+  0, 8, 48, 0, 0, 0, 21, 71, 5, 41,
+  10, 3, 0, 14, 0, 2, 0, 9, 0, 69,
+  34, 19, 0, 41, 0, 34, 7, 20, 0, 34,
+  59, 23, 26, 10, 5, 0, 0, 0, 0, 0,
+  0, 0, 18, 22, 10, 15, 30, 39, 10, 0,
+  0, 0, 16, 36, 52, 0, 27, 32, 3, 0,
+  12, 28, 0, 21, 0, 48, 0, 2, 0, 34,
+  13, 5, 17, 11, 0, 25, 0, 47, 10, 1,
+  26, 5, 0, 0, 0, 67, 13, 0, 12, 0,
+  16, 0, 0, 15, 0, 51, 0, 0, 0, 0,
+  0, 0, 69, 0, 19, 0, 19, 11, 0, 0,
+  29, 2, 31, 0, 0, 44, 27, 0, 33, 0,
+  0, 0, 76, 0, 0, 1, 67, 69, 11, 51,
+  63, 32, 6, 0, 66, 0, 0, 38, 0, 0,
+  28, 40, 0, 0, 0, 0, 7, 0, 0, 0,
+  0, 27, 0, 47, 0, 0, 0, 20, 0, 38,
+  0, 0, 0, 16, 0, 34, 21, 7, 0, 0,
+  0, 8, 0, 0, 0, 0, 0, 0, 0, 0,
+  98, 0, 25, 5, 0, 0, 0, 78, 9, 0,
+  0, 35, 0, 0, 12, 5, 38, 41, 20, 53,
+  0, 44, 32, 14, 27, 37, 0, 13, 0, 0,
+  0, 0, 28, 63, 38, 0, 0, 0, 0, 0,
+  3, 36, 0, 61, 0, 0, 0, 5, 3, 0,
+  4, 0, 0, 0, 0, 0, 77, 0, 26, 0,
+  18, 21, 29, 0, 57, 0, 12, 30, 0, 0,
+  52, 0, 0, 2, 43, 101, 14, 0, 40, 0,
+  0, 0, 32, 66, 0, 35, 0, 0, 0, 29,
+  0, 8, 0, 0, 0, 11, 0, 0, 0, 50,
+  0, 48, 0, 31, 0, 0, 0, 0, 0, 0,
+  6, 9, 0, 67, 0, 0, 11, 0, 13, 40,
+  0, 0, 5, 7, 0, 44, 0, 15, 58, 0,
+  30, 45, 0, 14, 0, 32, 0, 0, 0, 10,
+  0, 27, 0, 3, 29, 32, 45, 49, 0, 64,
+  21, 0, 0, 14, 0, 0, 0, 0, 0, 0,
+  30, 78, 0, 0, 0, 0, 0, 18, 0, 23,
+  14, 57, 17, 0, 0, 0, 29, 0, 59, 1,
+  9, 2, 0, 17, 0, 0, 0, 0, 0, 41,
+  0, 0, 0, 0, 31, 51, 0, 0, 37, 2,
+  0, 0, 4, 70, 43, 0, 24, 35, 0, 14,
+  56, 0, 0, 39, 0, 0, 9, 13, 0, 36,
+  0, 0, 0, 14, 0, 0, 0, 19, 0, 41,
+  0, 0, 0, 5, 3, 0, 4, 0, 0, 0,
+  23, 13, 20, 0, 0, 0, 18, 34, 0, 0,
+  4, 17, 0, 0, 0, 0, 21, 0, 0, 0,
+  0, 23, 10, 1, 39, 9, 0, 0, 1, 25,
+  3, 20, 0, 8, 17, 5, 38, 41, 32, 19,
+  10, 0, 6, 0, 0, 0, 0, 5, 45, 39,
+  4, 0, 0, 0, 0, 31, 0, 9, 12, 73,
+  0, 0, 0, 0, 2, 0, 65, 11, 0, 5,
+  37, 0, 20, 0, 0, 11, 0, 8, 52, 0,
+  43, 0, 22, 0, 0, 0, 29, 0, 0, 0,
+  38, 88, 0, 0, 38, 0, 13, 0, 33, 104,
+  68, 26, 0, 0, 8, 50, 0, 0, 0, 10,
+  0, 4, 0, 0, 0, 20, 0, 11, 1, 0,
+  0, 0, 0, 16, 0, 0, 0, 7, 0, 77,
+  0, 0, 52, 0, 26, 23, 6, 0, 25, 0,
+  0, 6, 24, 0, 92, 16, 18, 73, 0, 0,
+  0, 73, 0, 0, 0, 50, 0, 0, 0, 0,
+  11, 59, 10, 49, 0, 55, 10, 0, 0, 37,
+  0, 0, 5, 0, 13, 0, 23, 61, 29, 7,
+  1, 0, 19, 2, 0, 26, 0, 53, 0, 7,
+  0, 0, 0, 23, 69, 0, 1, 0, 0, 31,
+  0, 0, 4, 0, 0, 61, 44, 0, 0, 0,
+  25, 73, 0, 0, 7, 0, 0, 0, 26, 81,
+  0, 0, 48, 0, 0, 0, 40, 70, 0, 48,
+  0, 0, 0, 16, 0, 0, 0, 0, 0, 39,
+  0, 0, 0, 36, 0, 27, 0, 6, 0, 0,
+  20, 1, 0, 24, 22, 0, 0, 39, 0, 0,
+  0, 0, 10, 25, 0, 0, 31, 12, 0, 4,
+  0, 0, 87, 23, 22, 30, 0, 6, 0, 43,
+  7, 0, 0, 5, 0, 16, 0, 0, 0, 7,
+  9, 33, 0, 49, 1, 0, 0, 56, 0, 0,
+  0, 0, 0, 0, 17, 64, 6, 22, 16, 0,
+  10, 13, 0, 13, 8, 65, 0, 0, 0, 0,
+  0, 16, 82, 0, 8, 0, 12, 7, 0, 0,
+  0, 7, 4, 20, 0, 17, 0, 0, 21, 28,
+  30, 14, 58, 16, 0, 5, 32, 30, 51, 35,
+  42, 53, 0, 21, 81, 0, 0, 49, 7, 50,
+  21, 0, 0, 19, 0, 0, 2, 16, 18, 0,
+  0, 7, 0, 43, 0, 40, 0, 33, 27, 19,
+  0, 12, 0, 0, 23, 0, 84, 2, 0, 0,
+  0, 0, 0, 29, 0, 0, 0, 0, 0, 0,
+  33, 0, 0, 0, 0, 25, 18, 30, 44, 27,
+  0, 0, 0, 44, 47, 23, 14, 0, 26, 7,
+  56, 14, 51, 35, 8, 27, 0, 39, 0, 19,
+  0, 4, 43, 43, 0, 0, 0, 0, 0, 0,
+  8, 13, 9, 61, 0, 0, 0, 0, 12, 0,
+  28, 21, 21, 0, 50, 0, 111, 0, 14, 14,
+  3, 0, 103, 0, 37, 5, 6, 15, 0, 0,
+  15, 0, 0, 23, 47, 54, 0, 0, 22, 0,
+  6, 0, 0, 173, 80, 13, 0, 0, 0, 33,
+  0, 0, 2, 56, 0, 34, 0, 21, 0, 29,
+  0, 25, 0, 22, 0, 0, 27, 6, 10, 8,
+  0, 0, 0, 77, 0, 0, 89, 0, 43, 20,
+  45, 0, 35, 11, 0, 32, 30, 49, 7, 15,
+  23, 23, 7, 28, 0, 22, 0, 0, 3, 45,
+  0, 13, 0, 0, 4, 42, 8, 27, 0, 9,
+  0, 0, 0, 0, 8, 0, 7, 0, 24, 0,
+  27, 61, 2, 0, 25, 0, 40, 28, 4, 8,
+  10, 35, 4, 0, 0, 0, 0, 15, 78, 0,
+  23, 10, 0, 35, 0, 0, 20, 3, 3, 48,
+  45, 0, 0, 0, 22, 82, 0, 0, 8, 0,
+  0, 0, 29, 61, 0, 8, 48, 0, 0, 0,
+  21, 71, 5, 41, 10, 3, 0, 14, 0, 2,
+  0, 9, 0, 69, 34, 19, 0, 41, 0, 34,
+  7, 20, 0, 34, 59, 23, 26, 10, 5, 0,
+  0, 0, 0, 0, 0, 0, 18, 22, 10, 15,
+  30, 39, 10, 0, 0, 0, 16, 36, 52, 0,
+  27, 32, 3, 0, 12, 28, 0, 21, 0, 48,
+  0, 2, 0, 34, 13, 5, 17, 11, 0, 25,
+  0, 47, 10, 1, 26, 5, 0, 0, 0, 67,
+  13, 0, 12, 0, 16, 0, 0, 15, 0, 51,
+  0, 0, 0, 0, 0, 0, 69, 0, 19, 0,
+  19, 11, 0, 0, 29, 2, 31, 0, 0, 24,
+  0, 0, 40, 11, 0, 0, 61, 11, 0, 15,
+  51, 85, 31, 58, 61, 16, 0, 9, 60, 0,
+  0, 53, 11, 51, 1, 8, 0, 10, 0, 0,
+  0, 42, 35, 0, 15, 23, 0, 51, 12, 18,
+  0, 69, 33, 20, 9, 0, 0, 0, 24, 0,
+  57, 28, 0, 0, 0, 2, 0, 18, 0, 0,
+  0, 0, 0, 0, 31, 0, 42, 0, 0, 0,
+  4, 14, 36, 12, 0, 6, 0, 29, 44, 60,
+  4, 0, 34, 12, 53, 16, 53, 25, 0, 50,
+  0, 27, 0, 9, 0, 0, 31, 64, 0, 0,
+  0, 0, 0, 0, 0, 12, 10, 60, 0, 0,
+  0, 0, 0, 0, 10, 13, 32, 0, 25, 0,
+  76, 0, 51, 15, 31, 0, 29, 0, 57, 0,
+  12, 30, 0, 0, 52, 0, 0, 2, 43, 101,
+  14, 0, 40, 0, 0, 0, 32, 66, 0, 35,
+  0, 0, 0, 29, 0, 8, 0, 0, 0, 11,
+  0, 0, 0, 50, 0, 48, 0, 31, 0, 0,
+  0, 0, 0, 0, 6, 9, 0, 67, 0, 0,
+  11, 0, 13, 40, 0, 0, 5, 7, 0, 44,
+  0, 15, 58, 0, 30, 45, 0, 14, 0, 32,
+  0, 0, 0, 10, 0, 27, 0, 3, 29, 32,
+  45, 49, 0, 64, 21, 0, 0, 14, 0, 0,
+  0, 0, 0, 0, 30, 78, 0, 0, 0, 0,
+  0, 18, 0, 23, 14, 57, 17, 0, 0, 0,
+  29, 0, 59, 1, 9, 2, 0, 17, 0, 0,
+  0, 0, 0, 41, 0, 0, 0, 0, 31, 51,
+  0, 0, 37, 2, 0, 0, 4, 70, 43, 0,
+  24, 35, 0, 14, 56, 0, 0, 39, 0, 0,
+  9, 13, 0, 36, 0, 0, 0, 14, 0, 0,
+  0, 19, 0, 41, 0, 0, 0, 5, 3, 0,
+  4, 0, 0, 0, 23, 13, 20, 0, 0, 0,
+  18, 34, 0, 0, 4, 17, 0, 0, 0, 0,
+  21, 0, 0, 0, 0, 23, 10, 1, 39, 9,
+  0, 0, 1, 25, 3, 20, 0, 8, 17, 5,
+  38, 41, 32, 19, 10, 0, 6, 0, 0, 0,
+  0, 5, 45, 39, 4, 0, 0, 0, 0, 31,
+  0, 9, 12, 73, 0, 0, 0, 0, 2, 0,
+  65, 11, 0, 5, 37, 0, 20, 0, 0, 11,
+  0, 8, 0, 32, 0, 0, 31, 0, 19, 0,
+  50, 0, 0, 16, 7, 64, 58, 24, 16, 46,
+  0, 28, 76, 0, 0, 47, 16, 40, 25, 0,
+  0, 27, 0, 0, 0, 37, 5, 0, 0, 0,
+  0, 29, 0, 1, 0, 41, 21, 3, 4, 6,
+  0, 0, 60, 0, 56, 11, 0, 0, 8, 6,
+  0, 26, 13, 0, 0, 0, 0, 0, 17, 6,
+  0, 0, 0, 25, 0, 0, 41, 13, 0, 0,
+  0, 30, 48, 39, 12, 0, 31, 0, 58, 23,
+  37, 56, 3, 0, 8, 19, 0, 16, 0, 10,
+  57, 33, 0, 0, 0, 0, 0, 0, 23, 0,
+  31, 59, 0, 0, 0, 1, 24, 0, 21, 0,
+  8, 0, 47, 0, 77, 0, 1, 23, 9, 0,
+  44, 0, 0, 0, 25, 73, 0, 0, 7, 0,
+  0, 0, 26, 81, 0, 0, 48, 0, 0, 0,
+  40, 70, 0, 48, 0, 0, 0, 16, 0, 0,
+  0, 0, 0, 39, 0, 0, 0, 36, 0, 27,
+  0, 6, 0, 0, 20, 1, 0, 24, 22, 0,
+  0, 39, 0, 0, 0, 0, 10, 25, 0, 0,
+  31, 12, 0, 4, 0, 0, 87, 23, 22, 30,
+  0, 6, 0, 43, 7, 0, 0, 5, 0, 16,
+  0, 0, 0, 7, 9, 33, 0, 49, 1, 0,
+  0, 56, 0, 0, 0, 0, 0, 0, 17, 64,
+  6, 22, 16, 0, 10, 13, 0, 13, 8, 65,
+  0, 0, 0, 0, 0, 16, 82, 0, 8, 0,
+  12, 7, 0, 0, 0, 7, 4, 20, 0, 17,
+  0, 0, 21, 28, 30, 14, 58, 16, 0, 5,
+  32, 30, 51, 35, 42, 53, 0, 21, 81, 0,
+  0, 49, 7, 50, 21, 0, 0, 19, 0, 0,
+  2, 16, 18, 0, 0, 7, 0, 43, 0, 40,
+  0, 33, 27, 19, 0, 12, 0, 0, 23, 0,
+  84, 2, 0, 0, 0, 0, 0, 29, 0, 0,
+  0, 0, 0, 0, 33, 0, 0, 0, 0, 25,
+  18, 30, 44, 27, 0, 0, 0, 44, 47, 23,
+  14, 0, 26, 7, 56, 14, 51, 35, 8, 27,
+  0, 39, 0, 19, 0, 4, 43, 43, 0, 0,
+  0, 0, 0, 0, 8, 13, 9, 61, 0, 0,
+  0, 0, 12, 0, 28, 21, 21, 0, 50, 0,
+  111, 0, 14, 14, 3, 0, 0, 47, 23, 0,
+  8, 0, 33, 0, 55, 0, 0, 17, 28, 56,
+  45, 66, 49, 49, 0, 15, 78, 0, 0, 46,
+  13, 29, 27, 0, 0, 0, 14, 0, 11, 19,
+  4, 0, 0, 0, 0, 33, 12, 13, 0, 55,
+  6, 0, 0, 0, 0, 0, 63, 12, 64, 29,
+  0, 0, 0, 0, 0, 23, 0, 0, 0, 0,
+  0, 0, 42, 0, 0, 0, 0, 0, 0, 41,
+  36, 0, 0, 29, 0, 27, 65, 51, 36, 6,
+  50, 11, 55, 0, 58, 33, 0, 14, 0, 30,
+  0, 20, 0, 12, 43, 51, 0, 0, 0, 0,
+  0, 0, 5, 6, 14, 33, 30, 0, 0, 0,
+  41, 0, 0, 0, 5, 0, 0, 0, 81, 0,
+  6, 22, 17, 0, 45, 0, 0, 0, 22, 82,
+  0, 0, 8, 0, 0, 0, 29, 61, 0, 8,
+  48, 0, 0, 0, 21, 71, 5, 41, 10, 3,
+  0, 14, 0, 2, 0, 9, 0, 69, 34, 19,
+  0, 41, 0, 34, 7, 20, 0, 34, 59, 23,
+  26, 10, 5, 0, 0, 0, 0, 0, 0, 0,
+  18, 22, 10, 15, 30, 39, 10, 0, 0, 0,
+  16, 36, 52, 0, 27, 32, 3, 0, 12, 28,
+  0, 21, 0, 48, 0, 2, 0, 34, 13, 5,
+  17, 11, 0, 25, 0, 47, 10, 1, 26, 5,
+  0, 0, 0, 67, 13, 0, 12, 0, 16, 0,
+  0, 15, 0, 51, 0, 0, 0, 0, 0, 0,
+  69, 0, 19, 0, 19, 11, 0, 0, 29, 2,
+  31, 0, 0, 24, 0, 0, 40, 11, 0, 0,
+  61, 11, 0, 15, 51, 85, 31, 58, 61, 16,
+  0, 9, 60, 0, 0, 53, 11, 51, 1, 8,
+  0, 10, 0, 0, 0, 42, 35, 0, 15, 23,
+  0, 51, 12, 18, 0, 69, 33, 20, 9, 0,
+  0, 0, 24, 0, 57, 28, 0, 0, 0, 2,
+  0, 18, 0, 0, 0, 0, 0, 0, 31, 0,
+  42, 0, 0, 0, 4, 14, 36, 12, 0, 6,
+  0, 29, 44, 60, 4, 0, 34, 12, 53, 16,
+  53, 25, 0, 50, 0, 27, 0, 9, 0, 0,
+  31, 64, 0, 0, 0, 0, 0, 0, 0, 12,
+  10, 60, 0, 0, 0, 0, 0, 0, 10, 13,
+  32, 0, 25, 0, 76, 0, 51, 15, 31, 0,
+  0, 35, 50, 0, 10, 0, 0, 0, 51, 2,
+  0, 18, 8, 100, 10, 27, 39, 26, 2, 4,
+  44, 0, 34, 24, 0, 0, 0, 5, 0, 0,
+  0, 0, 0, 0, 0, 0, 5, 0, 0, 22,
+  18, 0, 0, 35, 0, 0, 0, 0, 0, 0,
+  52, 66, 0, 34, 0, 0, 6, 2, 0, 0,
+  0, 0, 13, 0, 38, 2, 22, 0, 23, 0,
+  0, 0, 3, 15, 29, 0, 0, 37, 0, 21,
+  32, 48, 11, 18, 40, 3, 53, 7, 75, 6,
+  0, 23, 0, 0, 0, 1, 0, 0, 40, 70,
+  1, 0, 0, 0, 7, 0, 0, 9, 0, 8,
+  32, 0, 0, 0, 57, 0, 10, 0, 12, 0,
+  0, 0, 8, 0, 9, 14, 37, 0, 0, 0,
+  0, 0, 31, 51, 0, 0, 37, 2, 0, 0,
+  4, 70, 43, 0, 24, 35, 0, 14, 56, 0,
+  0, 39, 0, 0, 9, 13, 0, 36, 0, 0,
+  0, 14, 0, 0, 0, 19, 0, 41, 0, 0,
+  0, 5, 3, 0, 4, 0, 0, 0, 23, 13,
+  20, 0, 0, 0, 18, 34, 0, 0, 4, 17,
+  0, 0, 0, 0, 21, 0, 0, 0, 0, 23,
+  10, 1, 39, 9, 0, 0, 1, 25, 3, 20,
+  0, 8, 17, 5, 38, 41, 32, 19, 10, 0,
+  6, 0, 0, 0, 0, 5, 45, 39, 4, 0,
+  0, 0, 0, 31, 0, 9, 12, 73, 0, 0,
+  0, 0, 2, 0, 65, 11, 0, 5, 37, 0,
+  20, 0, 0, 11, 0, 8, 0, 32, 0, 0,
+  31, 0, 19, 0, 50, 0, 0, 16, 7, 64,
+  58, 24, 16, 46, 0, 28, 76, 0, 0, 47,
+  16, 40, 25, 0, 0, 27, 0, 0, 0, 37,
+  5, 0, 0, 0, 0, 29, 0, 1, 0, 41,
+  21, 3, 4, 6, 0, 0, 60, 0, 56, 11,
+  0, 0, 8, 6, 0, 26, 13, 0, 0, 0,
+  0, 0, 17, 6, 0, 0, 0, 25, 0, 0,
+  41, 13, 0, 0, 0, 30, 48, 39, 12, 0,
+  31, 0, 58, 23, 37, 56, 3, 0, 8, 19,
+  0, 16, 0, 10, 57, 33, 0, 0, 0, 0,
+  0, 0, 23, 0, 31, 59, 0, 0, 0, 1,
+  24, 0, 21, 0, 8, 0, 47, 0, 77, 0,
+  1, 23, 9, 0, 0, 86, 6, 8, 42, 0,
+  32, 0, 64, 4, 0, 0, 6, 42, 74, 53,
+  38, 43, 0, 27, 68, 0, 0, 42, 0, 47,
+  25, 9, 0, 24, 6, 0, 0, 29, 9, 0,
+  0, 0, 0, 25, 0, 26, 0, 59, 9, 0,
+  0, 24, 0, 0, 45, 0, 88, 34, 0, 0,
+  0, 0, 0, 9, 6, 0, 0, 0, 0, 0,
+  36, 0, 0, 0, 0, 0, 0, 17, 64, 0,
+  2, 0, 1, 0, 91, 28, 8, 0, 51, 13,
+  35, 13, 47, 25, 0, 0, 0, 32, 0, 22,
+  0, 0, 48, 22, 0, 7, 0, 0, 23, 0,
+  25, 21, 43, 64, 10, 0, 0, 0, 29, 0,
+  0, 0, 18, 0, 4, 0, 74, 0, 0, 37,
+  25, 0, 0, 17, 0, 0, 21, 28, 30, 14,
+  58, 16, 0, 5, 32, 30, 51, 35, 42, 53,
+  0, 21, 81, 0, 0, 49, 7, 50, 21, 0,
+  0, 19, 0, 0, 2, 16, 18, 0, 0, 7,
+  0, 43, 0, 40, 0, 33, 27, 19, 0, 12,
+  0, 0, 23, 0, 84, 2, 0, 0, 0, 0,
+  0, 29, 0, 0, 0, 0, 0, 0, 33, 0,
+  0, 0, 0, 25, 18, 30, 44, 27, 0, 0,
+  0, 44, 47, 23, 14, 0, 26, 7, 56, 14,
+  51, 35, 8, 27, 0, 39, 0, 19, 0, 4,
+  43, 43, 0, 0, 0, 0, 0, 0, 8, 13,
+  9, 61, 0, 0, 0, 0, 12, 0, 28, 21,
+  21, 0, 50, 0, 111, 0, 14, 14, 3, 0,
+  0, 47, 23, 0, 8, 0, 33, 0, 55, 0,
+  0, 17, 28, 56, 45, 66, 49, 49, 0, 15,
+  78, 0, 0, 46, 13, 29, 27, 0, 0, 0,
+  14, 0, 11, 19, 4, 0, 0, 0, 0, 33,
+  12, 13, 0, 55, 6, 0, 0, 0, 0, 0,
+  63, 12, 64, 29, 0, 0, 0, 0, 0, 23,
+  0, 0, 0, 0, 0, 0, 42, 0, 0, 0,
+  0, 0, 0, 41, 36, 0, 0, 29, 0, 27,
+  65, 51, 36, 6, 50, 11, 55, 0, 58, 33,
+  0, 14, 0, 30, 0, 20, 0, 12, 43, 51,
+  0, 0, 0, 0, 0, 0, 5, 6, 14, 33,
+  30, 0, 0, 0, 41, 0, 0, 0, 5, 0,
+  0, 0, 81, 0, 6, 22, 17, 0, 0, 43,
+  70, 0, 11, 0, 9, 0, 57, 6, 0, 0,
+  0, 60, 23, 63, 30, 38, 0, 12, 39, 0,
+  33, 35, 0, 0, 9, 14, 0, 0, 27, 0,
+  0, 0, 0, 0, 0, 17, 0, 12, 27, 0,
+  0, 40, 0, 0, 0, 0, 0, 0, 48, 52,
+  41, 12, 0, 0, 19, 12, 0, 0, 0, 0,
+  0, 0, 24, 0, 45, 0, 11, 4, 0, 0,
+  0, 28, 32, 0, 0, 18, 0, 0, 58, 19,
+  0, 21, 59, 13, 23, 9, 64, 10, 0, 32,
+  0, 0, 0, 0, 0, 0, 40, 51, 0, 0,
+  0, 0, 36, 0, 0, 22, 4, 24, 40, 0,
+  0, 0, 86, 0, 2, 0, 26, 0, 0, 1,
+  21, 0, 0, 24, 22, 0, 0, 24, 0, 0,
+  40, 11, 0, 0, 61, 11, 0, 15, 51, 85,
+  31, 58, 61, 16, 0, 9, 60, 0, 0, 53,
+  11, 51, 1, 8, 0, 10, 0, 0, 0, 42,
+  35, 0, 15, 23, 0, 51, 12, 18, 0, 69,
+  33, 20, 9, 0, 0, 0, 24, 0, 57, 28,
+  0, 0, 0, 2, 0, 18, 0, 0, 0, 0,
+  0, 0, 31, 0, 42, 0, 0, 0, 4, 14,
+  36, 12, 0, 6, 0, 29, 44, 60, 4, 0,
+  34, 12, 53, 16, 53, 25, 0, 50, 0, 27,
+  0, 9, 0, 0, 31, 64, 0, 0, 0, 0,
+  0, 0, 0, 12, 10, 60, 0, 0, 0, 0,
+  0, 0, 10, 13, 32, 0, 25, 0, 76, 0,
+  51, 15, 31, 0, 0, 35, 50, 0, 10, 0,
+  0, 0, 51, 2, 0, 18, 8, 100, 10, 27,
+  39, 26, 2, 4, 44, 0, 34, 24, 0, 0,
+  0, 5, 0, 0, 0, 0, 0, 0, 0, 0,
+  5, 0, 0, 22, 18, 0, 0, 35, 0, 0,
+  0, 0, 0, 0, 52, 66, 0, 34, 0, 0,
+  6, 2, 0, 0, 0, 0, 13, 0, 38, 2,
+  22, 0, 23, 0, 0, 0, 3, 15, 29, 0,
+  0, 37, 0, 21, 32, 48, 11, 18, 40, 3,
+  53, 7, 75, 6, 0, 23, 0, 0, 0, 1,
+  0, 0, 40, 70, 1, 0, 0, 0, 7, 0,
+  0, 9, 0, 8, 32, 0, 0, 0, 57, 0,
+  10, 0, 12, 0, 0, 0, 8, 0, 9, 14,
+  37, 0, 22, 0, 59, 0, 0, 0, 0, 0,
+  23, 0, 0, 0, 0, 116, 1, 0, 6, 27,
+  1, 0, 38, 30, 84, 8, 0, 0, 0, 4,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 2,
+  0, 0, 28, 17, 0, 30, 0, 0, 0, 0,
+  0, 0, 35, 131, 0, 15, 36, 0, 30, 17,
+  14, 0, 0, 0, 34, 0, 88, 47, 7, 2,
+  16, 67, 0, 0, 0, 0, 11, 0, 0, 0,
+  0, 24, 16, 22, 0, 15, 41, 0, 31, 10,
+  71, 0, 0, 11, 2, 0, 0, 5, 0, 0,
+  62, 66, 0, 0, 0, 0, 12, 10, 0, 7,
+  0, 0, 50, 0, 0, 0, 91, 3, 77, 0,
+  19, 0, 0, 0, 0, 0, 21, 6, 10, 0,
+  0, 32, 0, 0, 31, 0, 19, 0, 50, 0,
+  0, 16, 7, 64, 58, 24, 16, 46, 0, 28,
+  76, 0, 0, 47, 16, 40, 25, 0, 0, 27,
+  0, 0, 0, 37, 5, 0, 0, 0, 0, 29,
+  0, 1, 0, 41, 21, 3, 4, 6, 0, 0,
+  60, 0, 56, 11, 0, 0, 8, 6, 0, 26,
+  13, 0, 0, 0, 0, 0, 17, 6, 0, 0,
+  0, 25, 0, 0, 41, 13, 0, 0, 0, 30,
+  48, 39, 12, 0, 31, 0, 58, 23, 37, 56,
+  3, 0, 8, 19, 0, 16, 0, 10, 57, 33,
+  0, 0, 0, 0, 0, 0, 23, 0, 31, 59,
+  0, 0, 0, 1, 24, 0, 21, 0, 8, 0,
+  47, 0, 77, 0, 1, 23, 9, 0, 0, 86,
+  6, 8, 42, 0, 32, 0, 64, 4, 0, 0,
+  6, 42, 74, 53, 38, 43, 0, 27, 68, 0,
+  0, 42, 0, 47, 25, 9, 0, 24, 6, 0,
+  0, 29, 9, 0, 0, 0, 0, 25, 0, 26,
+  0, 59, 9, 0, 0, 24, 0, 0, 45, 0,
+  88, 34, 0, 0, 0, 0, 0, 9, 6, 0,
+  0, 0, 0, 0, 36, 0, 0, 0, 0, 0,
+  0, 17, 64, 0, 2, 0, 1, 0, 91, 28,
+  8, 0, 51, 13, 35, 13, 47, 25, 0, 0,
+  0, 32, 0, 22, 0, 0, 48, 22, 0, 7,
+  0, 0, 23, 0, 25, 21, 43, 64, 10, 0,
+  0, 0, 29, 0, 0, 0, 18, 0, 4, 0,
+  74, 0, 0, 37, 25, 0, 0, 96, 8, 3,
+  33, 0, 35, 0, 85, 3, 0, 27, 4, 58,
+  40, 66, 33, 44, 0, 33, 67, 0, 11, 33,
+  0, 10, 35, 17, 0, 0, 0, 0, 16, 0,
+  0, 0, 0, 12, 0, 0, 0, 9, 0, 67,
+  0, 25, 0, 38, 0, 0, 28, 0, 77, 30,
+  0, 0, 25, 0, 0, 0, 0, 0, 0, 0,
+  2, 0, 21, 0, 17, 0, 0, 0, 18, 29,
+  78, 0, 11, 0, 0, 0, 78, 36, 3, 0,
+  35, 3, 44, 7, 36, 20, 0, 27, 0, 26,
+  0, 8, 0, 0, 61, 33, 8, 16, 0, 0,
+  58, 0, 22, 29, 12, 37, 7, 0, 0, 0,
+  41, 0, 0, 0, 20, 0, 0, 0, 52, 0,
+  0, 31, 46, 0, 0, 47, 23, 0, 8, 0,
+  33, 0, 55, 0, 0, 17, 28, 56, 45, 66,
+  49, 49, 0, 15, 78, 0, 0, 46, 13, 29,
+  27, 0, 0, 0, 14, 0, 11, 19, 4, 0,
+  0, 0, 0, 33, 12, 13, 0, 55, 6, 0,
+  0, 0, 0, 0, 63, 12, 64, 29, 0, 0,
+  0, 0, 0, 23, 0, 0, 0, 0, 0, 0,
+  42, 0, 0, 0, 0, 0, 0, 41, 36, 0,
+  0, 29, 0, 27, 65, 51, 36, 6, 50, 11,
+  55, 0, 58, 33, 0, 14, 0, 30, 0, 20,
+  0, 12, 43, 51, 0, 0, 0, 0, 0, 0,
+  5, 6, 14, 33, 30, 0, 0, 0, 41, 0,
+  0, 0, 5, 0, 0, 0, 81, 0, 6, 22,
+  17, 0, 0, 43, 70, 0, 11, 0, 9, 0,
+  57, 6, 0, 0, 0, 60, 23, 63, 30, 38,
+  0, 12, 39, 0, 33, 35, 0, 0, 9, 14,
+  0, 0, 27, 0, 0, 0, 0, 0, 0, 17,
+  0, 12, 27, 0, 0, 40, 0, 0, 0, 0,
+  0, 0, 48, 52, 41, 12, 0, 0, 19, 12,
+  0, 0, 0, 0, 0, 0, 24, 0, 45, 0,
+  11, 4, 0, 0, 0, 28, 32, 0, 0, 18,
+  0, 0, 58, 19, 0, 21, 59, 13, 23, 9,
+  64, 10, 0, 32, 0, 0, 0, 0, 0, 0,
+  40, 51, 0, 0, 0, 0, 36, 0, 0, 22,
+  4, 24, 40, 0, 0, 0, 86, 0, 2, 0,
+  26, 0, 0, 1, 21, 0, 0, 24, 22, 0,
+  0, 1, 54, 0, 0, 0, 0, 0, 42, 0,
+  0, 7, 0, 86, 0, 0, 1, 43, 0, 15,
+  50, 15, 93, 16, 0, 0, 0, 18, 0, 0,
+  16, 0, 0, 0, 0, 0, 0, 25, 0, 0,
+  34, 33, 0, 35, 0, 0, 0, 17, 0, 0,
+  34, 96, 0, 0, 21, 0, 40, 0, 14, 0,
+  0, 2, 21, 0, 100, 23, 1, 3, 2, 71,
+  0, 0, 0, 0, 18, 0, 0, 0, 0, 0,
+  25, 5, 0, 25, 63, 0, 32, 16, 62, 0,
+  0, 28, 0, 0, 0, 0, 0, 0, 67, 44,
+  0, 0, 0, 0, 26, 0, 0, 29, 0, 5,
+  41, 0, 0, 0, 99, 0, 45, 0, 46, 0,
+  0, 13, 0, 0, 0, 6, 19, 0, 0, 35,
+  50, 0, 10, 0, 0, 0, 51, 2, 0, 18,
+  8, 100, 10, 27, 39, 26, 2, 4, 44, 0,
+  34, 24, 0, 0, 0, 5, 0, 0, 0, 0,
+  0, 0, 0, 0, 5, 0, 0, 22, 18, 0,
+  0, 35, 0, 0, 0, 0, 0, 0, 52, 66,
+  0, 34, 0, 0, 6, 2, 0, 0, 0, 0,
+  13, 0, 38, 2, 22, 0, 23, 0, 0, 0,
+  3, 15, 29, 0, 0, 37, 0, 21, 32, 48,
+  11, 18, 40, 3, 53, 7, 75, 6, 0, 23,
+  0, 0, 0, 1, 0, 0, 40, 70, 1, 0,
+  0, 0, 7, 0, 0, 9, 0, 8, 32, 0,
+  0, 0, 57, 0, 10, 0, 12, 0, 0, 0,
+  8, 0, 9, 14, 37, 0, 22, 0, 59, 0,
+  0, 0, 0, 0, 23, 0, 0, 0, 0, 116,
+  1, 0, 6, 27, 1, 0, 38, 30, 84, 8,
+  0, 0, 0, 4, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 2, 0, 0, 28, 17, 0, 30,
+  0, 0, 0, 0, 0, 0, 35, 131, 0, 15,
+  36, 0, 30, 17, 14, 0, 0, 0, 34, 0,
+  88, 47, 7, 2, 16, 67, 0, 0, 0, 0,
+  11, 0, 0, 0, 0, 24, 16, 22, 0, 15,
+  41, 0, 31, 10, 71, 0, 0, 11, 2, 0,
+  0, 5, 0, 0, 62, 66, 0, 0, 0, 0,
+  12, 10, 0, 7, 0, 0, 50, 0, 0, 0,
+  91, 3, 77, 0, 19, 0, 0, 0, 0, 0,
+  21, 6, 10, 0, 20, 0, 19, 16, 0, 0,
+  0, 0, 29, 0, 0, 0, 2, 73, 0, 0,
+  0, 28, 8, 5, 49, 5, 52, 6, 0, 0,
+  0, 7, 0, 12, 6, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 29, 0, 45, 0, 0,
+  0, 16, 0, 0, 39, 114, 0, 30, 15, 0,
+  35, 10, 0, 0, 0, 0, 31, 0, 77, 23,
+  0, 26, 0, 48, 0, 8, 0, 0, 25, 0,
+  0, 0, 0, 24, 31, 18, 0, 15, 42, 0,
+  28, 19, 61, 0, 0, 0, 0, 0, 0, 9,
+  24, 0, 72, 41, 0, 0, 3, 0, 0, 0,
+  0, 13, 37, 0, 43, 0, 0, 5, 84, 0,
+  93, 0, 17, 0, 7, 5, 0, 0, 42, 4,
+  0, 0, 0, 86, 6, 8, 42, 0, 32, 0,
+  64, 4, 0, 0, 6, 42, 74, 53, 38, 43,
+  0, 27, 68, 0, 0, 42, 0, 47, 25, 9,
+  0, 24, 6, 0, 0, 29, 9, 0, 0, 0,
+  0, 25, 0, 26, 0, 59, 9, 0, 0, 24,
+  0, 0, 45, 0, 88, 34, 0, 0, 0, 0,
+  0, 9, 6, 0, 0, 0, 0, 0, 36, 0,
+  0, 0, 0, 0, 0, 17, 64, 0, 2, 0,
+  1, 0, 91, 28, 8, 0, 51, 13, 35, 13,
+  47, 25, 0, 0, 0, 32, 0, 22, 0, 0,
+  48, 22, 0, 7, 0, 0, 23, 0, 25, 21,
+  43, 64, 10, 0, 0, 0, 29, 0, 0, 0,
+  18, 0, 4, 0, 74, 0, 0, 37, 25, 0,
+  0, 96, 8, 3, 33, 0, 35, 0, 85, 3,
+  0, 27, 4, 58, 40, 66, 33, 44, 0, 33,
+  67, 0, 11, 33, 0, 10, 35, 17, 0, 0,
+  0, 0, 16, 0, 0, 0, 0, 12, 0, 0,
+  0, 9, 0, 67, 0, 25, 0, 38, 0, 0,
+  28, 0, 77, 30, 0, 0, 25, 0, 0, 0,
+  0, 0, 0, 0, 2, 0, 21, 0, 17, 0,
+  0, 0, 18, 29, 78, 0, 11, 0, 0, 0,
+  78, 36, 3, 0, 35, 3, 44, 7, 36, 20,
+  0, 27, 0, 26, 0, 8, 0, 0, 61, 33,
+  8, 16, 0, 0, 58, 0, 22, 29, 12, 37,
+  7, 0, 0, 0, 41, 0, 0, 0, 20, 0,
+  0, 0, 52, 0, 0, 31, 46, 0, 0, 50,
+  11, 21, 17, 0, 0, 0, 67, 0, 0, 42,
+  4, 106, 9, 17, 15, 45, 0, 24, 71, 0,
+  40, 19, 0, 0, 0, 3, 0, 0, 0, 0,
+  0, 10, 0, 0, 0, 0, 0, 0, 4, 19,
+  0, 50, 0, 0, 0, 45, 0, 0, 34, 65,
+  36, 45, 0, 0, 44, 0, 0, 0, 0, 0,
+  7, 0, 60, 7, 0, 7, 12, 15, 0, 0,
+  10, 2, 40, 0, 0, 0, 0, 1, 42, 35,
+  2, 0, 21, 0, 58, 15, 51, 12, 0, 30,
+  0, 0, 0, 9, 0, 0, 58, 45, 6, 2,
+  0, 0, 16, 0, 0, 13, 0, 3, 7, 0,
+  0, 0, 80, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 4, 12, 0, 0, 43, 70, 0,
+  11, 0, 9, 0, 57, 6, 0, 0, 0, 60,
+  23, 63, 30, 38, 0, 12, 39, 0, 33, 35,
+  0, 0, 9, 14, 0, 0, 27, 0, 0, 0,
+  0, 0, 0, 17, 0, 12, 27, 0, 0, 40,
+  0, 0, 0, 0, 0, 0, 48, 52, 41, 12,
+  0, 0, 19, 12, 0, 0, 0, 0, 0, 0,
+  24, 0, 45, 0, 11, 4, 0, 0, 0, 28,
+  32, 0, 0, 18, 0, 0, 58, 19, 0, 21,
+  59, 13, 23, 9, 64, 10, 0, 32, 0, 0,
+  0, 0, 0, 0, 40, 51, 0, 0, 0, 0,
+  36, 0, 0, 22, 4, 24, 40, 0, 0, 0,
+  86, 0, 2, 0, 26, 0, 0, 1, 21, 0,
+  0, 24, 22, 0, 0, 1, 54, 0, 0, 0,
+  0, 0, 42, 0, 0, 7, 0, 86, 0, 0,
+  1, 43, 0, 15, 50, 15, 93, 16, 0, 0,
+  0, 18, 0, 0, 16, 0, 0, 0, 0, 0,
+  0, 25, 0, 0, 34, 33, 0, 35, 0, 0,
+  0, 17, 0, 0, 34, 96, 0, 0, 21, 0,
+  40, 0, 14, 0, 0, 2, 21, 0, 100, 23,
+  1, 3, 2, 71, 0, 0, 0, 0, 18, 0,
+  0, 0, 0, 0, 25, 5, 0, 25, 63, 0,
+  32, 16, 62, 0, 0, 28, 0, 0, 0, 0,
+  0, 0, 67, 44, 0, 0, 0, 0, 26, 0,
+  0, 29, 0, 5, 41, 0, 0, 0, 99, 0,
+  45, 0, 46, 0, 0, 13, 0, 0, 0, 6,
+  19, 0, 16, 0, 16, 11, 0, 0, 0, 0,
+  35, 0, 0, 25, 4, 106, 0, 0, 0, 36,
+  2, 10, 68, 10, 49, 2, 0, 0, 0, 0,
+  0, 0, 0, 2, 0, 9, 0, 0, 0, 0,
+  0, 0, 5, 41, 0, 45, 0, 0, 0, 31,
+  0, 0, 66, 127, 0, 42, 14, 0, 16, 0,
+  2, 0, 0, 0, 48, 0, 110, 32, 0, 9,
+  0, 60, 0, 11, 0, 0, 22, 0, 0, 0,
+  0, 41, 18, 32, 0, 0, 51, 0, 58, 18,
+  81, 0, 0, 0, 0, 0, 0, 12, 11, 0,
+  73, 49, 0, 0, 0, 0, 6, 0, 0, 8,
+  11, 0, 36, 0, 0, 0, 95, 0, 70, 0,
+  20, 0, 1, 0, 0, 0, 8, 0, 11, 0,
+  22, 0, 59, 0, 0, 0, 0, 0, 23, 0,
+  0, 0, 0, 116, 1, 0, 6, 27, 1, 0,
+  38, 30, 84, 8, 0, 0, 0, 4, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 2, 0, 0,
+  28, 17, 0, 30, 0, 0, 0, 0, 0, 0,
+  35, 131, 0, 15, 36, 0, 30, 17, 14, 0,
+  0, 0, 34, 0, 88, 47, 7, 2, 16, 67,
+  0, 0, 0, 0, 11, 0, 0, 0, 0, 24,
+  16, 22, 0, 15, 41, 0, 31, 10, 71, 0,
+  0, 11, 2, 0, 0, 5, 0, 0, 62, 66,
+  0, 0, 0, 0, 12, 10, 0, 7, 0, 0,
+  50, 0, 0, 0, 91, 3, 77, 0, 19, 0,
+  0, 0, 0, 0, 21, 6, 10, 0, 20, 0,
+  19, 16, 0, 0, 0, 0, 29, 0, 0, 0,
+  2, 73, 0, 0, 0, 28, 8, 5, 49, 5,
+  52, 6, 0, 0, 0, 7, 0, 12, 6, 1,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 29,
+  0, 45, 0, 0, 0, 16, 0, 0, 39, 114,
+  0, 30, 15, 0, 35, 10, 0, 0, 0, 0,
+  31, 0, 77, 23, 0, 26, 0, 48, 0, 8,
+  0, 0, 25, 0, 0, 0, 0, 24, 31, 18,
+  0, 15, 42, 0, 28, 19, 61, 0, 0, 0,
+  0, 0, 0, 9, 24, 0, 72, 41, 0, 0,
+  3, 0, 0, 0, 0, 13, 37, 0, 43, 0,
+  0, 5, 84, 0, 93, 0, 17, 0, 7, 5,
+  0, 0, 42, 4, 0, 0, 3, 16, 0, 41,
+  1, 0, 4, 6, 70, 0, 0, 11, 25, 55,
+  18, 0, 14, 4, 17, 0, 52, 0, 0, 17,
+  0, 16, 4, 14, 0, 32, 2, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 25, 0, 53,
+  0, 0, 5, 16, 0, 0, 58, 87, 18, 68,
+  0, 0, 15, 25, 0, 19, 0, 0, 0, 0,
+  0, 11, 7, 13, 8, 0, 0, 9, 0, 0,
+  44, 3, 0, 0, 0, 43, 57, 57, 0, 0,
+  32, 0, 31, 33, 74, 29, 25, 0, 0, 0,
+  0, 11, 45, 0, 71, 48, 0, 0, 7, 0,
+  2, 0, 0, 12, 74, 6, 34, 0, 0, 0,
+  67, 0, 49, 0, 0, 0, 48, 9, 63, 0,
+  76, 0, 5, 0, 0, 96, 8, 3, 33, 0,
+  35, 0, 85, 3, 0, 27, 4, 58, 40, 66,
+  33, 44, 0, 33, 67, 0, 11, 33, 0, 10,
+  35, 17, 0, 0, 0, 0, 16, 0, 0, 0,
+  0, 12, 0, 0, 0, 9, 0, 67, 0, 25,
+  0, 38, 0, 0, 28, 0, 77, 30, 0, 0,
+  25, 0, 0, 0, 0, 0, 0, 0, 2, 0,
+  21, 0, 17, 0, 0, 0, 18, 29, 78, 0,
+  11, 0, 0, 0, 78, 36, 3, 0, 35, 3,
+  44, 7, 36, 20, 0, 27, 0, 26, 0, 8,
+  0, 0, 61, 33, 8, 16, 0, 0, 58, 0,
+  22, 29, 12, 37, 7, 0, 0, 0, 41, 0,
+  0, 0, 20, 0, 0, 0, 52, 0, 0, 31,
+  46, 0, 0, 50, 11, 21, 17, 0, 0, 0,
+  67, 0, 0, 42, 4, 106, 9, 17, 15, 45,
+  0, 24, 71, 0, 40, 19, 0, 0, 0, 3,
+  0, 0, 0, 0, 0, 10, 0, 0, 0, 0,
+  0, 0, 4, 19, 0, 50, 0, 0, 0, 45,
+  0, 0, 34, 65, 36, 45, 0, 0, 44, 0,
+  0, 0, 0, 0, 7, 0, 60, 7, 0, 7,
+  12, 15, 0, 0, 10, 2, 40, 0, 0, 0,
+  0, 1, 42, 35, 2, 0, 21, 0, 58, 15,
+  51, 12, 0, 30, 0, 0, 0, 9, 0, 0,
+  58, 45, 6, 2, 0, 0, 16, 0, 0, 13,
+  0, 3, 7, 0, 0, 0, 80, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 4, 12, 0,
+  20, 58, 19, 29, 24, 0, 0, 0, 79, 0,
+  0, 44, 19, 100, 0, 0, 0, 11, 0, 4,
+  57, 0, 28, 24, 0, 0, 2, 0, 0, 3,
+  5, 0, 0, 6, 0, 0, 0, 0, 0, 0,
+  0, 34, 0, 24, 0, 0, 6, 41, 0, 0,
+  50, 104, 10, 72, 18, 0, 43, 0, 5, 0,
+  0, 0, 14, 0, 25, 49, 0, 0, 0, 41,
+  0, 14, 1, 0, 14, 2, 0, 0, 0, 33,
+  14, 52, 21, 0, 21, 0, 41, 46, 70, 27,
+  15, 0, 0, 0, 0, 6, 30, 0, 57, 63,
+  0, 18, 0, 0, 0, 0, 0, 23, 55, 0,
+  32, 0, 0, 0, 90, 0, 14, 0, 0, 0,
+  5, 1, 0, 0, 20, 7, 0, 0, 0, 1,
+  54, 0, 0, 0, 0, 0, 42, 0, 0, 7,
+  0, 86, 0, 0, 1, 43, 0, 15, 50, 15,
+  93, 16, 0, 0, 0, 18, 0, 0, 16, 0,
+  0, 0, 0, 0, 0, 25, 0, 0, 34, 33,
+  0, 35, 0, 0, 0, 17, 0, 0, 34, 96,
+  0, 0, 21, 0, 40, 0, 14, 0, 0, 2,
+  21, 0, 100, 23, 1, 3, 2, 71, 0, 0,
+  0, 0, 18, 0, 0, 0, 0, 0, 25, 5,
+  0, 25, 63, 0, 32, 16, 62, 0, 0, 28,
+  0, 0, 0, 0, 0, 0, 67, 44, 0, 0,
+  0, 0, 26, 0, 0, 29, 0, 5, 41, 0,
+  0, 0, 99, 0, 45, 0, 46, 0, 0, 13,
+  0, 0, 0, 6, 19, 0, 16, 0, 16, 11,
+  0, 0, 0, 0, 35, 0, 0, 25, 4, 106,
+  0, 0, 0, 36, 2, 10, 68, 10, 49, 2,
+  0, 0, 0, 0, 0, 0, 0, 2, 0, 9,
+  0, 0, 0, 0, 0, 0, 5, 41, 0, 45,
+  0, 0, 0, 31, 0, 0, 66, 127, 0, 42,
+  14, 0, 16, 0, 2, 0, 0, 0, 48, 0,
+  110, 32, 0, 9, 0, 60, 0, 11, 0, 0,
+  22, 0, 0, 0, 0, 41, 18, 32, 0, 0,
+  51, 0, 58, 18, 81, 0, 0, 0, 0, 0,
+  0, 12, 11, 0, 73, 49, 0, 0, 0, 0,
+  6, 0, 0, 8, 11, 0, 36, 0, 0, 0,
+  95, 0, 70, 0, 20, 0, 1, 0, 0, 0,
+  8, 0, 11, 0, 7, 17, 0, 25, 21, 11,
+  0, 0, 61, 0, 0, 19, 7, 87, 0, 0,
+  0, 20, 13, 16, 69, 0, 0, 19, 0, 0,
+  0, 0, 0, 18, 0, 0, 0, 6, 0, 0,
+  0, 0, 0, 0, 0, 18, 0, 55, 0, 0,
+  10, 38, 0, 0, 71, 103, 0, 69, 0, 0,
+  31, 9, 0, 0, 0, 0, 4, 0, 42, 20,
+  0, 14, 0, 7, 0, 2, 0, 0, 39, 0,
+  0, 0, 0, 43, 31, 45, 9, 0, 36, 0,
+  50, 45, 79, 24, 11, 1, 0, 0, 0, 13,
+  32, 0, 65, 65, 1, 23, 0, 0, 0, 0,
+  0, 13, 64, 0, 7, 0, 0, 0, 59, 0,
+  45, 0, 6, 0, 45, 0, 40, 0, 47, 0,
+  8, 0, 20, 0, 19, 16, 0, 0, 0, 0,
+  29, 0, 0, 0, 2, 73, 0, 0, 0, 28,
+  8, 5, 49, 5, 52, 6, 0, 0, 0, 7,
+  0, 12, 6, 1, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 29, 0, 45, 0, 0, 0, 16,
+  0, 0, 39, 114, 0, 30, 15, 0, 35, 10,
+  0, 0, 0, 0, 31, 0, 77, 23, 0, 26,
+  0, 48, 0, 8, 0, 0, 25, 0, 0, 0,
+  0, 24, 31, 18, 0, 15, 42, 0, 28, 19,
+  61, 0, 0, 0, 0, 0, 0, 9, 24, 0,
+  72, 41, 0, 0, 3, 0, 0, 0, 0, 13,
+  37, 0, 43, 0, 0, 5, 84, 0, 93, 0,
+  17, 0, 7, 5, 0, 0, 42, 4, 0, 0,
+  3, 16, 0, 41, 1, 0, 4, 6, 70, 0,
+  0, 11, 25, 55, 18, 0, 14, 4, 17, 0,
+  52, 0, 0, 17, 0, 16, 4, 14, 0, 32,
+  2, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 25, 0, 53, 0, 0, 5, 16, 0, 0,
+  58, 87, 18, 68, 0, 0, 15, 25, 0, 19,
+  0, 0, 0, 0, 0, 11, 7, 13, 8, 0,
+  0, 9, 0, 0, 44, 3, 0, 0, 0, 43,
+  57, 57, 0, 0, 32, 0, 31, 33, 74, 29,
+  25, 0, 0, 0, 0, 11, 45, 0, 71, 48,
+  0, 0, 7, 0, 2, 0, 0, 12, 74, 6,
+  34, 0, 0, 0, 67, 0, 49, 0, 0, 0,
+  48, 9, 63, 0, 76, 0, 5, 0, 0, 29,
+  0, 36, 17, 0, 0, 1, 82, 0, 0, 10,
+  14, 80, 41, 0, 22, 8, 10, 0, 47, 0,
+  0, 23, 0, 13, 0, 15, 0, 5, 0, 0,
+  0, 11, 0, 0, 0, 0, 0, 11, 0, 0,
+  0, 51, 0, 0, 23, 16, 0, 0, 35, 72,
+  21, 74, 0, 0, 3, 24, 0, 11, 0, 0,
+  0, 0, 0, 21, 29, 0, 30, 0, 0, 0,
+  0, 0, 58, 0, 0, 0, 0, 30, 56, 60,
+  4, 0, 25, 0, 29, 51, 61, 17, 7, 13,
+  0, 0, 0, 14, 29, 0, 67, 43, 0, 16,
+  0, 0, 10, 1, 0, 7, 54, 13, 18, 0,
+  0, 0, 34, 0, 15, 0, 0, 0, 35, 0,
+  63, 0, 64, 0, 8, 0, 0, 50, 11, 21,
+  17, 0, 0, 0, 67, 0, 0, 42, 4, 106,
+  9, 17, 15, 45, 0, 24, 71, 0, 40, 19,
+  0, 0, 0, 3, 0, 0, 0, 0, 0, 10,
+  0, 0, 0, 0, 0, 0, 4, 19, 0, 50,
+  0, 0, 0, 45, 0, 0, 34, 65, 36, 45,
+  0, 0, 44, 0, 0, 0, 0, 0, 7, 0,
+  60, 7, 0, 7, 12, 15, 0, 0, 10, 2,
+  40, 0, 0, 0, 0, 1, 42, 35, 2, 0,
+  21, 0, 58, 15, 51, 12, 0, 30, 0, 0,
+  0, 9, 0, 0, 58, 45, 6, 2, 0, 0,
+  16, 0, 0, 13, 0, 3, 7, 0, 0, 0,
+  80, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 4, 12, 0, 20, 58, 19, 29, 24, 0,
+  0, 0, 79, 0, 0, 44, 19, 100, 0, 0,
+  0, 11, 0, 4, 57, 0, 28, 24, 0, 0,
+  2, 0, 0, 3, 5, 0, 0, 6, 0, 0,
+  0, 0, 0, 0, 0, 34, 0, 24, 0, 0,
+  6, 41, 0, 0, 50, 104, 10, 72, 18, 0,
+  43, 0, 5, 0, 0, 0, 14, 0, 25, 49,
+  0, 0, 0, 41, 0, 14, 1, 0, 14, 2,
+  0, 0, 0, 33, 14, 52, 21, 0, 21, 0,
+  41, 46, 70, 27, 15, 0, 0, 0, 0, 6,
+  30, 0, 57, 63, 0, 18, 0, 0, 0, 0,
+  0, 23, 55, 0, 32, 0, 0, 0, 90, 0,
+  14, 0, 0, 0, 5, 1, 0, 0, 20, 7,
+  0, 0, 56, 103, 0, 45, 15, 0, 0, 0,
+  58, 0, 0, 52, 30, 60, 0, 0, 0, 11,
+  22, 8, 26, 0, 0, 48, 0, 0, 58, 0,
+  0, 0, 19, 13, 0, 0, 3, 0, 0, 0,
+  0, 0, 0, 0, 0, 14, 26, 11, 2, 0,
+  0, 0, 23, 83, 1, 41, 67, 0, 39, 3,
+  0, 0, 0, 31, 34, 12, 4, 15, 0, 13,
+  0, 63, 0, 12, 10, 0, 0, 36, 0, 0,
+  33, 0, 0, 39, 30, 13, 0, 0, 19, 60,
+  73, 69, 93, 0, 0, 0, 0, 0, 59, 0,
+  21, 68, 23, 82, 0, 0, 0, 0, 0, 52,
+  129, 3, 21, 0, 0, 7, 40, 0, 0, 0,
+  3, 0, 26, 0, 14, 0, 57, 39, 0, 0,
+  16, 0, 16, 11, 0, 0, 0, 0, 35, 0,
+  0, 25, 4, 106, 0, 0, 0, 36, 2, 10,
+  68, 10, 49, 2, 0, 0, 0, 0, 0, 0,
+  0, 2, 0, 9, 0, 0, 0, 0, 0, 0,
+  5, 41, 0, 45, 0, 0, 0, 31, 0, 0,
+  66, 127, 0, 42, 14, 0, 16, 0, 2, 0,
+  0, 0, 48, 0, 110, 32, 0, 9, 0, 60,
+  0, 11, 0, 0, 22, 0, 0, 0, 0, 41,
+  18, 32, 0, 0, 51, 0, 58, 18, 81, 0,
+  0, 0, 0, 0, 0, 12, 11, 0, 73, 49,
+  0, 0, 0, 0, 6, 0, 0, 8, 11, 0,
+  36, 0, 0, 0, 95, 0, 70, 0, 20, 0,
+  1, 0, 0, 0, 8, 0, 11, 0, 7, 17,
+  0, 25, 21, 11, 0, 0, 61, 0, 0, 19,
+  7, 87, 0, 0, 0, 20, 13, 16, 69, 0,
+  0, 19, 0, 0, 0, 0, 0, 18, 0, 0,
+  0, 6, 0, 0, 0, 0, 0, 0, 0, 18,
+  0, 55, 0, 0, 10, 38, 0, 0, 71, 103,
+  0, 69, 0, 0, 31, 9, 0, 0, 0, 0,
+  4, 0, 42, 20, 0, 14, 0, 7, 0, 2,
+  0, 0, 39, 0, 0, 0, 0, 43, 31, 45,
+  9, 0, 36, 0, 50, 45, 79, 24, 11, 1,
+  0, 0, 0, 13, 32, 0, 65, 65, 1, 23,
+  0, 0, 0, 0, 0, 13, 64, 0, 7, 0,
+  0, 0, 59, 0, 45, 0, 6, 0, 45, 0,
+  40, 0, 47, 0, 8, 0, 0, 108, 0, 50,
+  20, 0, 23, 0, 76, 0, 5, 27, 31, 30,
+  12, 0, 0, 17, 12, 30, 55, 0, 0, 56,
+  13, 61, 39, 0, 0, 26, 15, 0, 27, 4,
+  0, 0, 0, 0, 0, 5, 0, 21, 0, 47,
+  11, 0, 10, 19, 0, 0, 54, 49, 57, 86,
+  0, 0, 20, 0, 0, 49, 9, 0, 0, 0,
+  0, 0, 32, 13, 0, 0, 0, 12, 0, 0,
+  51, 32, 0, 0, 0, 19, 65, 67, 24, 0,
+  19, 0, 39, 50, 52, 88, 74, 0, 0, 18,
+  0, 13, 42, 0, 60, 63, 11, 32, 0, 0,
+  0, 0, 14, 25, 123, 40, 2, 0, 0, 0,
+  13, 0, 5, 0, 0, 0, 42, 3, 144, 0,
+  86, 0, 0, 0, 3, 16, 0, 41, 1, 0,
+  4, 6, 70, 0, 0, 11, 25, 55, 18, 0,
+  14, 4, 17, 0, 52, 0, 0, 17, 0, 16,
+  4, 14, 0, 32, 2, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 25, 0, 53, 0, 0,
+  5, 16, 0, 0, 58, 87, 18, 68, 0, 0,
+  15, 25, 0, 19, 0, 0, 0, 0, 0, 11,
+  7, 13, 8, 0, 0, 9, 0, 0, 44, 3,
+  0, 0, 0, 43, 57, 57, 0, 0, 32, 0,
+  31, 33, 74, 29, 25, 0, 0, 0, 0, 11,
+  45, 0, 71, 48, 0, 0, 7, 0, 2, 0,
+  0, 12, 74, 6, 34, 0, 0, 0, 67, 0,
+  49, 0, 0, 0, 48, 9, 63, 0, 76, 0,
+  5, 0, 0, 29, 0, 36, 17, 0, 0, 1,
+  82, 0, 0, 10, 14, 80, 41, 0, 22, 8,
+  10, 0, 47, 0, 0, 23, 0, 13, 0, 15,
+  0, 5, 0, 0, 0, 11, 0, 0, 0, 0,
+  0, 11, 0, 0, 0, 51, 0, 0, 23, 16,
+  0, 0, 35, 72, 21, 74, 0, 0, 3, 24,
+  0, 11, 0, 0, 0, 0, 0, 21, 29, 0,
+  30, 0, 0, 0, 0, 0, 58, 0, 0, 0,
+  0, 30, 56, 60, 4, 0, 25, 0, 29, 51,
+  61, 17, 7, 13, 0, 0, 0, 14, 29, 0,
+  67, 43, 0, 16, 0, 0, 10, 1, 0, 7,
+  54, 13, 18, 0, 0, 0, 34, 0, 15, 0,
+  0, 0, 35, 0, 63, 0, 64, 0, 8, 0,
+  0, 64, 0, 40, 20, 0, 10, 0, 63, 0,
+  7, 15, 12, 65, 48, 6, 31, 34, 0, 25,
+  58, 0, 0, 21, 0, 36, 3, 4, 0, 0,
+  0, 0, 0, 32, 0, 0, 0, 0, 0, 11,
+  0, 0, 0, 41, 0, 0, 21, 22, 0, 0,
+  26, 26, 28, 76, 0, 0, 10, 4, 0, 25,
+  19, 0, 0, 0, 0, 11, 55, 3, 50, 0,
+  0, 0, 0, 0, 62, 0, 0, 0, 0, 3,
+  57, 69, 4, 0, 25, 19, 41, 29, 30, 12,
+  0, 34, 0, 1, 0, 24, 19, 0, 63, 30,
+  0, 19, 0, 0, 12, 0, 3, 1, 34, 21,
+  0, 0, 0, 0, 15, 0, 0, 0, 0, 0,
+  0, 13, 75, 0, 41, 0, 17, 0, 20, 58,
+  19, 29, 24, 0, 0, 0, 79, 0, 0, 44,
+  19, 100, 0, 0, 0, 11, 0, 4, 57, 0,
+  28, 24, 0, 0, 2, 0, 0, 3, 5, 0,
+  0, 6, 0, 0, 0, 0, 0, 0, 0, 34,
+  0, 24, 0, 0, 6, 41, 0, 0, 50, 104,
+  10, 72, 18, 0, 43, 0, 5, 0, 0, 0,
+  14, 0, 25, 49, 0, 0, 0, 41, 0, 14,
+  1, 0, 14, 2, 0, 0, 0, 33, 14, 52,
+  21, 0, 21, 0, 41, 46, 70, 27, 15, 0,
+  0, 0, 0, 6, 30, 0, 57, 63, 0, 18,
+  0, 0, 0, 0, 0, 23, 55, 0, 32, 0,
+  0, 0, 90, 0, 14, 0, 0, 0, 5, 1,
+  0, 0, 20, 7, 0, 0, 56, 103, 0, 45,
+  15, 0, 0, 0, 58, 0, 0, 52, 30, 60,
+  0, 0, 0, 11, 22, 8, 26, 0, 0, 48,
+  0, 0, 58, 0, 0, 0, 19, 13, 0, 0,
+  3, 0, 0, 0, 0, 0, 0, 0, 0, 14,
+  26, 11, 2, 0, 0, 0, 23, 83, 1, 41,
+  67, 0, 39, 3, 0, 0, 0, 31, 34, 12,
+  4, 15, 0, 13, 0, 63, 0, 12, 10, 0,
+  0, 36, 0, 0, 33, 0, 0, 39, 30, 13,
+  0, 0, 19, 60, 73, 69, 93, 0, 0, 0,
+  0, 0, 59, 0, 21, 68, 23, 82, 0, 0,
+  0, 0, 0, 52, 129, 3, 21, 0, 0, 7,
+  40, 0, 0, 0, 3, 0, 26, 0, 14, 0,
+  57, 39, 0, 0, 46, 82, 0, 50, 1, 35,
+  0, 0, 22, 0, 0, 15, 41, 6, 0, 0,
+  0, 19, 21, 11, 13, 31, 0, 0, 0, 0,
+  64, 0, 0, 0, 30, 54, 0, 0, 28, 29,
+  0, 17, 0, 0, 0, 0, 1, 18, 5, 11,
+  10, 0, 0, 0, 0, 57, 0, 22, 95, 48,
+  30, 4, 0, 0, 0, 73, 54, 11, 88, 0,
+  0, 66, 0, 94, 130, 13, 9, 0, 0, 4,
+  0, 2, 68, 0, 0, 0, 23, 16, 20, 0,
+  0, 28, 33, 13, 56, 0, 0, 0, 6, 0,
+  47, 0, 18, 68, 22, 150, 0, 0, 0, 0,
+  0, 82, 91, 0, 7, 26, 10, 31, 0, 0,
+  0, 0, 31, 0, 0, 0, 0, 0, 50, 35,
+  0, 2, 7, 17, 0, 25, 21, 11, 0, 0,
+  61, 0, 0, 19, 7, 87, 0, 0, 0, 20,
+  13, 16, 69, 0, 0, 19, 0, 0, 0, 0,
+  0, 18, 0, 0, 0, 6, 0, 0, 0, 0,
+  0, 0, 0, 18, 0, 55, 0, 0, 10, 38,
+  0, 0, 71, 103, 0, 69, 0, 0, 31, 9,
+  0, 0, 0, 0, 4, 0, 42, 20, 0, 14,
+  0, 7, 0, 2, 0, 0, 39, 0, 0, 0,
+  0, 43, 31, 45, 9, 0, 36, 0, 50, 45,
+  79, 24, 11, 1, 0, 0, 0, 13, 32, 0,
+  65, 65, 1, 23, 0, 0, 0, 0, 0, 13,
+  64, 0, 7, 0, 0, 0, 59, 0, 45, 0,
+  6, 0, 45, 0, 40, 0, 47, 0, 8, 0,
+  0, 108, 0, 50, 20, 0, 23, 0, 76, 0,
+  5, 27, 31, 30, 12, 0, 0, 17, 12, 30,
+  55, 0, 0, 56, 13, 61, 39, 0, 0, 26,
+  15, 0, 27, 4, 0, 0, 0, 0, 0, 5,
+  0, 21, 0, 47, 11, 0, 10, 19, 0, 0,
+  54, 49, 57, 86, 0, 0, 20, 0, 0, 49,
+  9, 0, 0, 0, 0, 0, 32, 13, 0, 0,
+  0, 12, 0, 0, 51, 32, 0, 0, 0, 19,
+  65, 67, 24, 0, 19, 0, 39, 50, 52, 88,
+  74, 0, 0, 18, 0, 13, 42, 0, 60, 63,
+  11, 32, 0, 0, 0, 0, 14, 25, 123, 40,
+  2, 0, 0, 0, 13, 0, 5, 0, 0, 0,
+  42, 3, 144, 0, 86, 0, 0, 0, 0, 155,
+  0, 57, 4, 0, 35, 0, 65, 0, 13, 22,
+  77, 0, 0, 0, 0, 12, 22, 43, 12, 0,
+  0, 61, 29, 33, 73, 13, 3, 0, 36, 0,
+  52, 0, 38, 0, 0, 0, 0, 0, 0, 22,
+  0, 53, 11, 0, 16, 0, 0, 0, 43, 52,
+  47, 51, 11, 17, 36, 0, 0, 49, 1, 0,
+  0, 0, 0, 0, 2, 16, 0, 0, 11, 34,
+  0, 0, 39, 55, 0, 69, 4, 0, 37, 56,
+  49, 10, 11, 0, 0, 58, 72, 93, 137, 0,
+  0, 11, 0, 0, 57, 0, 44, 81, 42, 39,
+  0, 0, 0, 0, 27, 70, 152, 18, 4, 0,
+  17, 10, 0, 0, 0, 0, 0, 0, 3, 0,
+  133, 2, 119, 5, 0, 0, 0, 29, 0, 36,
+  17, 0, 0, 1, 82, 0, 0, 10, 14, 80,
+  41, 0, 22, 8, 10, 0, 47, 0, 0, 23,
+  0, 13, 0, 15, 0, 5, 0, 0, 0, 11,
+  0, 0, 0, 0, 0, 11, 0, 0, 0, 51,
+  0, 0, 23, 16, 0, 0, 35, 72, 21, 74,
+  0, 0, 3, 24, 0, 11, 0, 0, 0, 0,
+  0, 21, 29, 0, 30, 0, 0, 0, 0, 0,
+  58, 0, 0, 0, 0, 30, 56, 60, 4, 0,
+  25, 0, 29, 51, 61, 17, 7, 13, 0, 0,
+  0, 14, 29, 0, 67, 43, 0, 16, 0, 0,
+  10, 1, 0, 7, 54, 13, 18, 0, 0, 0,
+  34, 0, 15, 0, 0, 0, 35, 0, 63, 0,
+  64, 0, 8, 0, 0, 64, 0, 40, 20, 0,
+  10, 0, 63, 0, 7, 15, 12, 65, 48, 6,
+  31, 34, 0, 25, 58, 0, 0, 21, 0, 36,
+  3, 4, 0, 0, 0, 0, 0, 32, 0, 0,
+  0, 0, 0, 11, 0, 0, 0, 41, 0, 0,
+  21, 22, 0, 0, 26, 26, 28, 76, 0, 0,
+  10, 4, 0, 25, 19, 0, 0, 0, 0, 11,
+  55, 3, 50, 0, 0, 0, 0, 0, 62, 0,
+  0, 0, 0, 3, 57, 69, 4, 0, 25, 19,
+  41, 29, 30, 12, 0, 34, 0, 1, 0, 24,
+  19, 0, 63, 30, 0, 19, 0, 0, 12, 0,
+  3, 1, 34, 21, 0, 0, 0, 0, 15, 0,
+  0, 0, 0, 0, 0, 13, 75, 0, 41, 0,
+  17, 0, 0, 151, 1, 57, 8, 0, 17, 0,
+  42, 0, 26, 0, 19, 37, 38, 18, 29, 7,
+  6, 53, 10, 0, 0, 24, 1, 37, 15, 7,
+  0, 0, 0, 0, 46, 5, 0, 0, 0, 0,
+  0, 1, 0, 2, 0, 21, 0, 0, 21, 42,
+  0, 0, 40, 0, 12, 89, 0, 0, 18, 1,
+  0, 44, 24, 0, 0, 0, 0, 0, 73, 21,
+  53, 0, 0, 0, 0, 8, 68, 12, 0, 35,
+  0, 18, 49, 62, 21, 11, 30, 33, 16, 49,
+  19, 13, 53, 22, 0, 17, 0, 5, 44, 0,
+  24, 80, 3, 46, 0, 0, 12, 0, 22, 12,
+  52, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 89, 0, 51, 0, 16, 1,
+  56, 103, 0, 45, 15, 0, 0, 0, 58, 0,
+  0, 52, 30, 60, 0, 0, 0, 11, 22, 8,
+  26, 0, 0, 48, 0, 0, 58, 0, 0, 0,
+  19, 13, 0, 0, 3, 0, 0, 0, 0, 0,
+  0, 0, 0, 14, 26, 11, 2, 0, 0, 0,
+  23, 83, 1, 41, 67, 0, 39, 3, 0, 0,
+  0, 31, 34, 12, 4, 15, 0, 13, 0, 63,
+  0, 12, 10, 0, 0, 36, 0, 0, 33, 0,
+  0, 39, 30, 13, 0, 0, 19, 60, 73, 69,
+  93, 0, 0, 0, 0, 0, 59, 0, 21, 68,
+  23, 82, 0, 0, 0, 0, 0, 52, 129, 3,
+  21, 0, 0, 7, 40, 0, 0, 0, 3, 0,
+  26, 0, 14, 0, 57, 39, 0, 0, 46, 82,
+  0, 50, 1, 35, 0, 0, 22, 0, 0, 15,
+  41, 6, 0, 0, 0, 19, 21, 11, 13, 31,
+  0, 0, 0, 0, 64, 0, 0, 0, 30, 54,
+  0, 0, 28, 29, 0, 17, 0, 0, 0, 0,
+  1, 18, 5, 11, 10, 0, 0, 0, 0, 57,
+  0, 22, 95, 48, 30, 4, 0, 0, 0, 73,
+  54, 11, 88, 0, 0, 66, 0, 94, 130, 13,
+  9, 0, 0, 4, 0, 2, 68, 0, 0, 0,
+  23, 16, 20, 0, 0, 28, 33, 13, 56, 0,
+  0, 0, 6, 0, 47, 0, 18, 68, 22, 150,
+  0, 0, 0, 0, 0, 82, 91, 0, 7, 26,
+  10, 31, 0, 0, 0, 0, 31, 0, 0, 0,
+  0, 0, 50, 35, 0, 2, 1, 12, 0, 19,
+  0, 115, 0, 0, 17, 0, 0, 0, 0, 1,
+  0, 0, 0, 28, 11, 16, 0, 65, 2, 0,
+  0, 0, 23, 0, 0, 0, 0, 17, 8, 0,
+  9, 65, 12, 45, 5, 0, 48, 0, 0, 18,
+  0, 33, 46, 0, 0, 7, 0, 29, 0, 0,
+  131, 59, 54, 5, 43, 0, 0, 107, 51, 0,
+  166, 0, 0, 46, 0, 112, 193, 0, 44, 0,
+  0, 35, 0, 0, 29, 0, 0, 0, 32, 0,
+  28, 0, 0, 1, 14, 0, 0, 79, 16, 0,
+  38, 0, 0, 0, 3, 61, 47, 127, 0, 0,
+  0, 0, 0, 36, 0, 0, 0, 55, 0, 53,
+  0, 0, 0, 0, 47, 0, 0, 0, 0, 0,
+  13, 18, 0, 12, 0, 108, 0, 50, 20, 0,
+  23, 0, 76, 0, 5, 27, 31, 30, 12, 0,
+  0, 17, 12, 30, 55, 0, 0, 56, 13, 61,
+  39, 0, 0, 26, 15, 0, 27, 4, 0, 0,
+  0, 0, 0, 5, 0, 21, 0, 47, 11, 0,
+  10, 19, 0, 0, 54, 49, 57, 86, 0, 0,
+  20, 0, 0, 49, 9, 0, 0, 0, 0, 0,
+  32, 13, 0, 0, 0, 12, 0, 0, 51, 32,
+  0, 0, 0, 19, 65, 67, 24, 0, 19, 0,
+  39, 50, 52, 88, 74, 0, 0, 18, 0, 13,
+  42, 0, 60, 63, 11, 32, 0, 0, 0, 0,
+  14, 25, 123, 40, 2, 0, 0, 0, 13, 0,
+  5, 0, 0, 0, 42, 3, 144, 0, 86, 0,
+  0, 0, 0, 155, 0, 57, 4, 0, 35, 0,
+  65, 0, 13, 22, 77, 0, 0, 0, 0, 12,
+  22, 43, 12, 0, 0, 61, 29, 33, 73, 13,
+  3, 0, 36, 0, 52, 0, 38, 0, 0, 0,
+  0, 0, 0, 22, 0, 53, 11, 0, 16, 0,
+  0, 0, 43, 52, 47, 51, 11, 17, 36, 0,
+  0, 49, 1, 0, 0, 0, 0, 0, 2, 16,
+  0, 0, 11, 34, 0, 0, 39, 55, 0, 69,
+  4, 0, 37, 56, 49, 10, 11, 0, 0, 58,
+  72, 93, 137, 0, 0, 11, 0, 0, 57, 0,
+  44, 81, 42, 39, 0, 0, 0, 0, 27, 70,
+  152, 18, 4, 0, 17, 10, 0, 0, 0, 0,
+  0, 0, 3, 0, 133, 2, 119, 5, 0, 0,
+  21, 77, 0, 54, 0, 57, 1, 0, 24, 0,
+  0, 9, 43, 0, 0, 0, 0, 20, 47, 27,
+  0, 27, 1, 0, 0, 0, 69, 0, 0, 0,
+  4, 19, 15, 0, 32, 49, 0, 0, 3, 0,
+  0, 7, 0, 34, 8, 10, 16, 0, 0, 0,
+  3, 45, 0, 0, 93, 35, 51, 0, 0, 0,
+  0, 53, 20, 0, 103, 0, 0, 43, 0, 68,
+  175, 29, 22, 0, 0, 35, 0, 61, 4, 6,
+  0, 0, 64, 5, 21, 0, 0, 19, 51, 0,
+  81, 0, 0, 0, 7, 0, 55, 0, 12, 95,
+  28, 106, 1, 0, 0, 0, 4, 67, 71, 0,
+  2, 16, 0, 39, 0, 0, 0, 0, 25, 0,
+  0, 0, 0, 18, 65, 17, 0, 0, 0, 64,
+  0, 40, 20, 0, 10, 0, 63, 0, 7, 15,
+  12, 65, 48, 6, 31, 34, 0, 25, 58, 0,
+  0, 21, 0, 36, 3, 4, 0, 0, 0, 0,
+  0, 32, 0, 0, 0, 0, 0, 11, 0, 0,
+  0, 41, 0, 0, 21, 22, 0, 0, 26, 26,
+  28, 76, 0, 0, 10, 4, 0, 25, 19, 0,
+  0, 0, 0, 11, 55, 3, 50, 0, 0, 0,
+  0, 0, 62, 0, 0, 0, 0, 3, 57, 69,
+  4, 0, 25, 19, 41, 29, 30, 12, 0, 34,
+  0, 1, 0, 24, 19, 0, 63, 30, 0, 19,
+  0, 0, 12, 0, 3, 1, 34, 21, 0, 0,
+  0, 0, 15, 0, 0, 0, 0, 0, 0, 13,
+  75, 0, 41, 0, 17, 0, 0, 151, 1, 57,
+  8, 0, 17, 0, 42, 0, 26, 0, 19, 37,
+  38, 18, 29, 7, 6, 53, 10, 0, 0, 24,
+  1, 37, 15, 7, 0, 0, 0, 0, 46, 5,
+  0, 0, 0, 0, 0, 1, 0, 2, 0, 21,
+  0, 0, 21, 42, 0, 0, 40, 0, 12, 89,
+  0, 0, 18, 1, 0, 44, 24, 0, 0, 0,
+  0, 0, 73, 21, 53, 0, 0, 0, 0, 8,
+  68, 12, 0, 35, 0, 18, 49, 62, 21, 11,
+  30, 33, 16, 49, 19, 13, 53, 22, 0, 17,
+  0, 5, 44, 0, 24, 80, 3, 46, 0, 0,
+  12, 0, 22, 12, 52, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 89, 0,
+  51, 0, 16, 1, 6, 145, 0, 66, 0, 25,
+  0, 0, 52, 0, 6, 0, 69, 0, 0, 0,
+  0, 5, 33, 32, 0, 0, 14, 32, 3, 0,
+  70, 0, 0, 0, 0, 0, 77, 0, 13, 38,
+  0, 0, 0, 0, 0, 17, 0, 19, 0, 15,
+  48, 19, 0, 17, 5, 25, 0, 35, 17, 0,
+  54, 0, 0, 16, 0, 0, 0, 0, 16, 0,
+  16, 19, 0, 1, 65, 17, 3, 0, 34, 29,
+  0, 94, 0, 16, 0, 0, 90, 39, 0, 18,
+  0, 41, 51, 18, 99, 0, 0, 0, 0, 0,
+  61, 0, 18, 99, 42, 59, 0, 0, 0, 10,
+  57, 44, 87, 0, 0, 0, 0, 36, 0, 0,
+  0, 0, 5, 0, 3, 0, 48, 0, 39, 0,
+  0, 46, 46, 82, 0, 50, 1, 35, 0, 0,
+  22, 0, 0, 15, 41, 6, 0, 0, 0, 19,
+  21, 11, 13, 31, 0, 0, 0, 0, 64, 0,
+  0, 0, 30, 54, 0, 0, 28, 29, 0, 17,
+  0, 0, 0, 0, 1, 18, 5, 11, 10, 0,
+  0, 0, 0, 57, 0, 22, 95, 48, 30, 4,
+  0, 0, 0, 73, 54, 11, 88, 0, 0, 66,
+  0, 94, 130, 13, 9, 0, 0, 4, 0, 2,
+  68, 0, 0, 0, 23, 16, 20, 0, 0, 28,
+  33, 13, 56, 0, 0, 0, 6, 0, 47, 0,
+  18, 68, 22, 150, 0, 0, 0, 0, 0, 82,
+  91, 0, 7, 26, 10, 31, 0, 0, 0, 0,
+  31, 0, 0, 0, 0, 0, 50, 35, 0, 2,
+  1, 12, 0, 19, 0, 115, 0, 0, 17, 0,
+  0, 0, 0, 1, 0, 0, 0, 28, 11, 16,
+  0, 65, 2, 0, 0, 0, 23, 0, 0, 0,
+  0, 17, 8, 0, 9, 65, 12, 45, 5, 0,
+  48, 0, 0, 18, 0, 33, 46, 0, 0, 7,
+  0, 29, 0, 0, 131, 59, 54, 5, 43, 0,
+  0, 107, 51, 0, 166, 0, 0, 46, 0, 112,
+  193, 0, 44, 0, 0, 35, 0, 0, 29, 0,
+  0, 0, 32, 0, 28, 0, 0, 1, 14, 0,
+  0, 79, 16, 0, 38, 0, 0, 0, 3, 61,
+  47, 127, 0, 0, 0, 0, 0, 36, 0, 0,
+  0, 55, 0, 53, 0, 0, 0, 0, 47, 0,
+  0, 0, 0, 0, 13, 18, 0, 12, 0, 1,
+  0, 0, 0, 57, 0, 18, 70, 15, 0, 4,
+  0, 0, 0, 50, 13, 20, 0, 0, 47, 47,
+  29, 12, 0, 0, 0, 10, 0, 0, 0, 0,
+  50, 0, 0, 44, 0, 64, 0, 0, 54, 0,
+  0, 47, 0, 99, 16, 46, 0, 15, 0, 37,
+  0, 0, 63, 0, 74, 0, 64, 0, 0, 62,
+  0, 0, 90, 0, 0, 12, 30, 23, 61, 0,
+  70, 60, 0, 76, 0, 1, 0, 0, 21, 0,
+  0, 0, 0, 0, 8, 0, 5, 0, 0, 121,
+  9, 0, 0, 0, 0, 0, 20, 54, 116, 17,
+  0, 0, 0, 0, 11, 9, 0, 21, 0, 19,
+  0, 73, 0, 0, 0, 0, 56, 0, 53, 0,
+  0, 0, 21, 0, 18, 0, 0, 155, 0, 57,
+  4, 0, 35, 0, 65, 0, 13, 22, 77, 0,
+  0, 0, 0, 12, 22, 43, 12, 0, 0, 61,
+  29, 33, 73, 13, 3, 0, 36, 0, 52, 0,
+  38, 0, 0, 0, 0, 0, 0, 22, 0, 53,
+  11, 0, 16, 0, 0, 0, 43, 52, 47, 51,
+  11, 17, 36, 0, 0, 49, 1, 0, 0, 0,
+  0, 0, 2, 16, 0, 0, 11, 34, 0, 0,
+  39, 55, 0, 69, 4, 0, 37, 56, 49, 10,
+  11, 0, 0, 58, 72, 93, 137, 0, 0, 11,
+  0, 0, 57, 0, 44, 81, 42, 39, 0, 0,
+  0, 0, 27, 70, 152, 18, 4, 0, 17, 10,
+  0, 0, 0, 0, 0, 0, 3, 0, 133, 2,
+  119, 5, 0, 0, 21, 77, 0, 54, 0, 57,
+  1, 0, 24, 0, 0, 9, 43, 0, 0, 0,
+  0, 20, 47, 27, 0, 27, 1, 0, 0, 0,
+  69, 0, 0, 0, 4, 19, 15, 0, 32, 49,
+  0, 0, 3, 0, 0, 7, 0, 34, 8, 10,
+  16, 0, 0, 0, 3, 45, 0, 0, 93, 35,
+  51, 0, 0, 0, 0, 53, 20, 0, 103, 0,
+  0, 43, 0, 68, 175, 29, 22, 0, 0, 35,
+  0, 61, 4, 6, 0, 0, 64, 5, 21, 0,
+  0, 19, 51, 0, 81, 0, 0, 0, 7, 0,
+  55, 0, 12, 95, 28, 106, 1, 0, 0, 0,
+  4, 67, 71, 0, 2, 16, 0, 39, 0, 0,
+  0, 0, 25, 0, 0, 0, 0, 18, 65, 17,
+  0, 0, 0, 0, 0, 25, 0, 135, 0, 7,
+  42, 0, 0, 4, 0, 6, 0, 0, 0, 25,
+  13, 0, 41, 106, 15, 0, 0, 0, 0, 1,
+  0, 0, 0, 1, 9, 0, 0, 82, 0, 40,
+  0, 0, 45, 0, 0, 46, 0, 80, 0, 4,
+  0, 0, 0, 52, 0, 0, 133, 36, 44, 0,
+  57, 0, 0, 92, 42, 0, 155, 0, 0, 30,
+  0, 77, 196, 0, 59, 34, 0, 31, 0, 16,
+  9, 0, 0, 0, 35, 0, 0, 0, 1, 0,
+  11, 0, 0, 92, 0, 0, 27, 0, 0, 0,
+  7, 76, 78, 108, 0, 0, 0, 0, 0, 30,
+  0, 0, 0, 38, 0, 95, 0, 0, 0, 0,
+  52, 0, 0, 0, 0, 0, 21, 0, 0, 6,
+  0, 151, 1, 57, 8, 0, 17, 0, 42, 0,
+  26, 0, 19, 37, 38, 18, 29, 7, 6, 53,
+  10, 0, 0, 24, 1, 37, 15, 7, 0, 0,
+  0, 0, 46, 5, 0, 0, 0, 0, 0, 1,
+  0, 2, 0, 21, 0, 0, 21, 42, 0, 0,
+  40, 0, 12, 89, 0, 0, 18, 1, 0, 44,
+  24, 0, 0, 0, 0, 0, 73, 21, 53, 0,
+  0, 0, 0, 8, 68, 12, 0, 35, 0, 18,
+  49, 62, 21, 11, 30, 33, 16, 49, 19, 13,
+  53, 22, 0, 17, 0, 5, 44, 0, 24, 80,
+  3, 46, 0, 0, 12, 0, 22, 12, 52, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 89, 0, 51, 0, 16, 1, 6, 145,
+  0, 66, 0, 25, 0, 0, 52, 0, 6, 0,
+  69, 0, 0, 0, 0, 5, 33, 32, 0, 0,
+  14, 32, 3, 0, 70, 0, 0, 0, 0, 0,
+  77, 0, 13, 38, 0, 0, 0, 0, 0, 17,
+  0, 19, 0, 15, 48, 19, 0, 17, 5, 25,
+  0, 35, 17, 0, 54, 0, 0, 16, 0, 0,
+  0, 0, 16, 0, 16, 19, 0, 1, 65, 17,
+  3, 0, 34, 29, 0, 94, 0, 16, 0, 0,
+  90, 39, 0, 18, 0, 41, 51, 18, 99, 0,
+  0, 0, 0, 0, 61, 0, 18, 99, 42, 59,
+  0, 0, 0, 10, 57, 44, 87, 0, 0, 0,
+  0, 36, 0, 0, 0, 0, 5, 0, 3, 0,
+  48, 0, 39, 0, 0, 46, 58, 21, 0, 68,
+  2, 105, 0, 4, 38, 0, 0, 0, 40, 0,
+  0, 0, 2, 21, 35, 0, 0, 90, 13, 0,
+  0, 0, 31, 0, 9, 0, 0, 31, 3, 0,
+  67, 72, 9, 0, 27, 0, 20, 14, 0, 28,
+  22, 53, 41, 0, 0, 0, 0, 61, 0, 0,
+  135, 38, 37, 0, 7, 0, 0, 47, 34, 0,
+  96, 0, 0, 31, 0, 47, 198, 6, 55, 0,
+  0, 0, 0, 35, 0, 0, 0, 0, 77, 27,
+  31, 0, 1, 1, 38, 0, 0, 15, 0, 0,
+  17, 0, 39, 0, 26, 71, 33, 77, 0, 0,
+  0, 0, 6, 46, 5, 0, 19, 40, 0, 88,
+  0, 0, 0, 0, 55, 0, 0, 0, 0, 0,
+  28, 0, 0, 16, 1, 12, 0, 19, 0, 115,
+  0, 0, 17, 0, 0, 0, 0, 1, 0, 0,
+  0, 28, 11, 16, 0, 65, 2, 0, 0, 0,
+  23, 0, 0, 0, 0, 17, 8, 0, 9, 65,
+  12, 45, 5, 0, 48, 0, 0, 18, 0, 33,
+  46, 0, 0, 7, 0, 29, 0, 0, 131, 59,
+  54, 5, 43, 0, 0, 107, 51, 0, 166, 0,
+  0, 46, 0, 112, 193, 0, 44, 0, 0, 35,
+  0, 0, 29, 0, 0, 0, 32, 0, 28, 0,
+  0, 1, 14, 0, 0, 79, 16, 0, 38, 0,
+  0, 0, 3, 61, 47, 127, 0, 0, 0, 0,
+  0, 36, 0, 0, 0, 55, 0, 53, 0, 0,
+  0, 0, 47, 0, 0, 0, 0, 0, 13, 18,
+  0, 12, 0, 1, 0, 0, 0, 57, 0, 18,
+  70, 15, 0, 4, 0, 0, 0, 50, 13, 20,
+  0, 0, 47, 47, 29, 12, 0, 0, 0, 10,
+  0, 0, 0, 0, 50, 0, 0, 44, 0, 64,
+  0, 0, 54, 0, 0, 47, 0, 99, 16, 46,
+  0, 15, 0, 37, 0, 0, 63, 0, 74, 0,
+  64, 0, 0, 62, 0, 0, 90, 0, 0, 12,
+  30, 23, 61, 0, 70, 60, 0, 76, 0, 1,
+  0, 0, 21, 0, 0, 0, 0, 0, 8, 0,
+  5, 0, 0, 121, 9, 0, 0, 0, 0, 0,
+  20, 54, 116, 17, 0, 0, 0, 0, 11, 9,
+  0, 21, 0, 19, 0, 73, 0, 0, 0, 0,
+  56, 0, 53, 0, 0, 0, 21, 0, 18, 0,
+  0, 48, 16, 0, 0, 0, 50, 44, 75, 3,
+  3, 42, 110, 0, 16, 61, 79, 13, 2, 0,
+  31, 54, 4, 6, 49, 0, 0, 45, 0, 0,
+  0, 0, 83, 0, 2, 0, 0, 62, 0, 80,
+  0, 35, 4, 49, 18, 97, 6, 35, 0, 42,
+  0, 40, 48, 0, 23, 0, 3, 0, 0, 0,
+  0, 5, 0, 59, 0, 17, 20, 0, 40, 0,
+  0, 0, 0, 48, 8, 0, 29, 54, 0, 0,
+  33, 0, 42, 5, 0, 9, 4, 0, 0, 8,
+  0, 4, 0, 44, 0, 13, 5, 8, 15, 84,
+  41, 0, 0, 0, 34, 0, 24, 13, 4, 22,
+  0, 21, 0, 22, 0, 0, 0, 0, 35, 0,
+  31, 0, 111, 0, 71, 0, 32, 0, 21, 77,
+  0, 54, 0, 57, 1, 0, 24, 0, 0, 9,
+  43, 0, 0, 0, 0, 20, 47, 27, 0, 27,
+  1, 0, 0, 0, 69, 0, 0, 0, 4, 19,
+  15, 0, 32, 49, 0, 0, 3, 0, 0, 7,
+  0, 34, 8, 10, 16, 0, 0, 0, 3, 45,
+  0, 0, 93, 35, 51, 0, 0, 0, 0, 53,
+  20, 0, 103, 0, 0, 43, 0, 68, 175, 29,
+  22, 0, 0, 35, 0, 61, 4, 6, 0, 0,
+  64, 5, 21, 0, 0, 19, 51, 0, 81, 0,
+  0, 0, 7, 0, 55, 0, 12, 95, 28, 106,
+  1, 0, 0, 0, 4, 67, 71, 0, 2, 16,
+  0, 39, 0, 0, 0, 0, 25, 0, 0, 0,
+  0, 18, 65, 17, 0, 0, 0, 0, 0, 25,
+  0, 135, 0, 7, 42, 0, 0, 4, 0, 6,
+  0, 0, 0, 25, 13, 0, 41, 106, 15, 0,
+  0, 0, 0, 1, 0, 0, 0, 1, 9, 0,
+  0, 82, 0, 40, 0, 0, 45, 0, 0, 46,
+  0, 80, 0, 4, 0, 0, 0, 52, 0, 0,
+  133, 36, 44, 0, 57, 0, 0, 92, 42, 0,
+  155, 0, 0, 30, 0, 77, 196, 0, 59, 34,
+  0, 31, 0, 16, 9, 0, 0, 0, 35, 0,
+  0, 0, 1, 0, 11, 0, 0, 92, 0, 0,
+  27, 0, 0, 0, 7, 76, 78, 108, 0, 0,
+  0, 0, 0, 30, 0, 0, 0, 38, 0, 95,
+  0, 0, 0, 0, 52, 0, 0, 0, 0, 0,
+  21, 0, 0, 6, 0, 28, 0, 8, 0, 24,
+  24, 29, 104, 12, 0, 37, 106, 0, 0, 105,
+  62, 22, 0, 0, 41, 62, 0, 12, 2, 0,
+  0, 43, 0, 0, 0, 0, 76, 0, 33, 0,
+  0, 91, 0, 53, 32, 0, 4, 39, 5, 115,
+  2, 34, 0, 36, 0, 56, 16, 0, 56, 0,
+  6, 0, 36, 0, 0, 14, 0, 21, 0, 0,
+  0, 0, 27, 0, 37, 0, 47, 52, 0, 14,
+  8, 31, 0, 0, 8, 0, 29, 0, 0, 10,
+  11, 0, 20, 0, 0, 68, 0, 34, 0, 0,
+  0, 0, 26, 84, 90, 0, 0, 0, 22, 0,
+  15, 31, 0, 34, 0, 30, 0, 52, 0, 0,
+  0, 0, 60, 0, 39, 0, 79, 0, 69, 0,
+  34, 16, 6, 145, 0, 66, 0, 25, 0, 0,
+  52, 0, 6, 0, 69, 0, 0, 0, 0, 5,
+  33, 32, 0, 0, 14, 32, 3, 0, 70, 0,
+  0, 0, 0, 0, 77, 0, 13, 38, 0, 0,
+  0, 0, 0, 17, 0, 19, 0, 15, 48, 19,
+  0, 17, 5, 25, 0, 35, 17, 0, 54, 0,
+  0, 16, 0, 0, 0, 0, 16, 0, 16, 19,
+  0, 1, 65, 17, 3, 0, 34, 29, 0, 94,
+  0, 16, 0, 0, 90, 39, 0, 18, 0, 41,
+  51, 18, 99, 0, 0, 0, 0, 0, 61, 0,
+  18, 99, 42, 59, 0, 0, 0, 10, 57, 44,
+  87, 0, 0, 0, 0, 36, 0, 0, 0, 0,
+  5, 0, 3, 0, 48, 0, 39, 0, 0, 46,
+  58, 21, 0, 68, 2, 105, 0, 4, 38, 0,
+  0, 0, 40, 0, 0, 0, 2, 21, 35, 0,
+  0, 90, 13, 0, 0, 0, 31, 0, 9, 0,
+  0, 31, 3, 0, 67, 72, 9, 0, 27, 0,
+  20, 14, 0, 28, 22, 53, 41, 0, 0, 0,
+  0, 61, 0, 0, 135, 38, 37, 0, 7, 0,
+  0, 47, 34, 0, 96, 0, 0, 31, 0, 47,
+  198, 6, 55, 0, 0, 0, 0, 35, 0, 0,
+  0, 0, 77, 27, 31, 0, 1, 1, 38, 0,
+  0, 15, 0, 0, 17, 0, 39, 0, 26, 71,
+  33, 77, 0, 0, 0, 0, 6, 46, 5, 0,
+  19, 40, 0, 88, 0, 0, 0, 0, 55, 0,
+  0, 0, 0, 0, 28, 0, 0, 16, 0, 0,
+  0, 15, 0, 83, 0, 21, 90, 39, 0, 48,
+  26, 0, 0, 60, 13, 28, 16, 0, 25, 81,
+  1, 0, 0, 0, 1, 44, 17, 19, 0, 35,
+  60, 0, 78, 36, 79, 138, 7, 0, 76, 0,
+  2, 0, 0, 129, 0, 4, 0, 11, 0, 4,
+  0, 0, 138, 0, 2, 0, 27, 0, 0, 90,
+  14, 2, 90, 0, 0, 39, 0, 61, 111, 0,
+  118, 35, 0, 31, 35, 22, 25, 0, 0, 0,
+  0, 27, 0, 0, 12, 25, 0, 0, 0, 91,
+  0, 7, 15, 0, 6, 0, 0, 89, 131, 18,
+  0, 0, 39, 0, 0, 48, 0, 0, 1, 67,
+  0, 57, 0, 0, 0, 0, 75, 0, 0, 0,
+  0, 0, 0, 0, 75, 51, 0, 1, 0, 0,
+  0, 57, 0, 18, 70, 15, 0, 4, 0, 0,
+  0, 50, 13, 20, 0, 0, 47, 47, 29, 12,
+  0, 0, 0, 10, 0, 0, 0, 0, 50, 0,
+  0, 44, 0, 64, 0, 0, 54, 0, 0, 47,
+  0, 99, 16, 46, 0, 15, 0, 37, 0, 0,
+  63, 0, 74, 0, 64, 0, 0, 62, 0, 0,
+  90, 0, 0, 12, 30, 23, 61, 0, 70, 60,
+  0, 76, 0, 1, 0, 0, 21, 0, 0, 0,
+  0, 0, 8, 0, 5, 0, 0, 121, 9, 0,
+  0, 0, 0, 0, 20, 54, 116, 17, 0, 0,
+  0, 0, 11, 9, 0, 21, 0, 19, 0, 73,
+  0, 0, 0, 0, 56, 0, 53, 0, 0, 0,
+  21, 0, 18, 0, 0, 48, 16, 0, 0, 0,
+  50, 44, 75, 3, 3, 42, 110, 0, 16, 61,
+  79, 13, 2, 0, 31, 54, 4, 6, 49, 0,
+  0, 45, 0, 0, 0, 0, 83, 0, 2, 0,
+  0, 62, 0, 80, 0, 35, 4, 49, 18, 97,
+  6, 35, 0, 42, 0, 40, 48, 0, 23, 0,
+  3, 0, 0, 0, 0, 5, 0, 59, 0, 17,
+  20, 0, 40, 0, 0, 0, 0, 48, 8, 0,
+  29, 54, 0, 0, 33, 0, 42, 5, 0, 9,
+  4, 0, 0, 8, 0, 4, 0, 44, 0, 13,
+  5, 8, 15, 84, 41, 0, 0, 0, 34, 0,
+  24, 13, 4, 22, 0, 21, 0, 22, 0, 0,
+  0, 0, 35, 0, 31, 0, 111, 0, 71, 0,
+  32, 0, 3, 37, 0, 0, 14, 0, 32, 0,
+  0, 0, 3, 23, 56, 0, 0, 4, 62, 15,
+  4, 0, 0, 72, 0, 17, 107, 0, 0, 48,
+  0, 0, 0, 48, 90, 0, 0, 0, 0, 51,
+  43, 7, 0, 46, 21, 29, 25, 100, 41, 0,
+  0, 5, 0, 0, 5, 0, 27, 0, 7, 0,
+  20, 2, 58, 63, 0, 50, 0, 0, 97, 52,
+  73, 0, 0, 0, 9, 20, 30, 0, 53, 59,
+  0, 0, 0, 0, 39, 57, 10, 31, 0, 0,
+  0, 14, 0, 0, 0, 54, 0, 21, 0, 18,
+  0, 113, 24, 11, 22, 20, 39, 43, 10, 0,
+  43, 0, 0, 50, 0, 0, 0, 0, 10, 1,
+  48, 0, 7, 0, 27, 0, 30, 0, 30, 47,
+  0, 0, 0, 25, 0, 135, 0, 7, 42, 0,
+  0, 4, 0, 6, 0, 0, 0, 25, 13, 0,
+  41, 106, 15, 0, 0, 0, 0, 1, 0, 0,
+  0, 1, 9, 0, 0, 82, 0, 40, 0, 0,
+  45, 0, 0, 46, 0, 80, 0, 4, 0, 0,
+  0, 52, 0, 0, 133, 36, 44, 0, 57, 0,
+  0, 92, 42, 0, 155, 0, 0, 30, 0, 77,
+  196, 0, 59, 34, 0, 31, 0, 16, 9, 0,
+  0, 0, 35, 0, 0, 0, 1, 0, 11, 0,
+  0, 92, 0, 0, 27, 0, 0, 0, 7, 76,
+  78, 108, 0, 0, 0, 0, 0, 30, 0, 0,
+  0, 38, 0, 95, 0, 0, 0, 0, 52, 0,
+  0, 0, 0, 0, 21, 0, 0, 6, 0, 28,
+  0, 8, 0, 24, 24, 29, 104, 12, 0, 37,
+  106, 0, 0, 105, 62, 22, 0, 0, 41, 62,
+  0, 12, 2, 0, 0, 43, 0, 0, 0, 0,
+  76, 0, 33, 0, 0, 91, 0, 53, 32, 0,
+  4, 39, 5, 115, 2, 34, 0, 36, 0, 56,
+  16, 0, 56, 0, 6, 0, 36, 0, 0, 14,
+  0, 21, 0, 0, 0, 0, 27, 0, 37, 0,
+  47, 52, 0, 14, 8, 31, 0, 0, 8, 0,
+  29, 0, 0, 10, 11, 0, 20, 0, 0, 68,
+  0, 34, 0, 0, 0, 0, 26, 84, 90, 0,
+  0, 0, 22, 0, 15, 31, 0, 34, 0, 30,
+  0, 52, 0, 0, 0, 0, 60, 0, 39, 0,
+  79, 0, 69, 0, 34, 16, 0, 39, 58, 0,
+  0, 0, 35, 20, 76, 0, 11, 39, 97, 0,
+  0, 94, 63, 17, 0, 0, 0, 47, 11, 21,
+  63, 0, 0, 58, 0, 0, 0, 24, 97, 0,
+  27, 0, 0, 89, 26, 22, 38, 4, 46, 33,
+  23, 117, 42, 0, 0, 22, 0, 0, 14, 0,
+  32, 0, 5, 0, 47, 0, 0, 49, 0, 19,
+  0, 0, 17, 1, 30, 0, 0, 0, 56, 43,
+  10, 31, 22, 65, 0, 0, 6, 0, 19, 88,
+  0, 42, 0, 0, 0, 23, 0, 11, 0, 31,
+  0, 0, 0, 0, 0, 85, 98, 0, 0, 0,
+  13, 0, 31, 29, 0, 24, 0, 19, 0, 5,
+  0, 0, 0, 12, 70, 0, 0, 0, 32, 0,
+  63, 0, 24, 34, 58, 21, 0, 68, 2, 105,
+  0, 4, 38, 0, 0, 0, 40, 0, 0, 0,
+  2, 21, 35, 0, 0, 90, 13, 0, 0, 0,
+  31, 0, 9, 0, 0, 31, 3, 0, 67, 72,
+  9, 0, 27, 0, 20, 14, 0, 28, 22, 53,
+  41, 0, 0, 0, 0, 61, 0, 0, 135, 38,
+  37, 0, 7, 0, 0, 47, 34, 0, 96, 0,
+  0, 31, 0, 47, 198, 6, 55, 0, 0, 0,
+  0, 35, 0, 0, 0, 0, 77, 27, 31, 0,
+  1, 1, 38, 0, 0, 15, 0, 0, 17, 0,
+  39, 0, 26, 71, 33, 77, 0, 0, 0, 0,
+  6, 46, 5, 0, 19, 40, 0, 88, 0, 0,
+  0, 0, 55, 0, 0, 0, 0, 0, 28, 0,
+  0, 16, 0, 0, 0, 15, 0, 83, 0, 21,
+  90, 39, 0, 48, 26, 0, 0, 60, 13, 28,
+  16, 0, 25, 81, 1, 0, 0, 0, 1, 44,
+  17, 19, 0, 35, 60, 0, 78, 36, 79, 138,
+  7, 0, 76, 0, 2, 0, 0, 129, 0, 4,
+  0, 11, 0, 4, 0, 0, 138, 0, 2, 0,
+  27, 0, 0, 90, 14, 2, 90, 0, 0, 39,
+  0, 61, 111, 0, 118, 35, 0, 31, 35, 22,
+  25, 0, 0, 0, 0, 27, 0, 0, 12, 25,
+  0, 0, 0, 91, 0, 7, 15, 0, 6, 0,
+  0, 89, 131, 18, 0, 0, 39, 0, 0, 48,
+  0, 0, 1, 67, 0, 57, 0, 0, 0, 0,
+  75, 0, 0, 0, 0, 0, 0, 0, 75, 51,
+  0, 0, 95, 9, 0, 0, 0, 24, 67, 28,
+  0, 54, 35, 44, 0, 52, 0, 15, 0, 0,
+  0, 58, 28, 9, 0, 0, 21, 48, 6, 84,
+  0, 37, 76, 0, 22, 0, 105, 123, 0, 0,
+  100, 0, 38, 0, 0, 109, 0, 0, 0, 11,
+  0, 0, 0, 0, 96, 0, 19, 0, 47, 0,
+  0, 83, 53, 15, 66, 0, 7, 34, 0, 90,
+  0, 0, 122, 30, 0, 21, 7, 0, 14, 0,
+  0, 2, 0, 89, 0, 17, 21, 0, 35, 0,
+  0, 36, 0, 3, 0, 0, 0, 0, 0, 59,
+  137, 0, 0, 0, 0, 0, 0, 52, 0, 3,
+  30, 17, 0, 0, 80, 0, 22, 0, 52, 0,
+  0, 0, 0, 0, 0, 14, 61, 73, 0, 48,
+  16, 0, 0, 0, 50, 44, 75, 3, 3, 42,
+  110, 0, 16, 61, 79, 13, 2, 0, 31, 54,
+  4, 6, 49, 0, 0, 45, 0, 0, 0, 0,
+  83, 0, 2, 0, 0, 62, 0, 80, 0, 35,
+  4, 49, 18, 97, 6, 35, 0, 42, 0, 40,
+  48, 0, 23, 0, 3, 0, 0, 0, 0, 5,
+  0, 59, 0, 17, 20, 0, 40, 0, 0, 0,
+  0, 48, 8, 0, 29, 54, 0, 0, 33, 0,
+  42, 5, 0, 9, 4, 0, 0, 8, 0, 4,
+  0, 44, 0, 13, 5, 8, 15, 84, 41, 0,
+  0, 0, 34, 0, 24, 13, 4, 22, 0, 21,
+  0, 22, 0, 0, 0, 0, 35, 0, 31, 0,
+  111, 0, 71, 0, 32, 0, 3, 37, 0, 0,
+  14, 0, 32, 0, 0, 0, 3, 23, 56, 0,
+  0, 4, 62, 15, 4, 0, 0, 72, 0, 17,
+  107, 0, 0, 48, 0, 0, 0, 48, 90, 0,
+  0, 0, 0, 51, 43, 7, 0, 46, 21, 29,
+  25, 100, 41, 0, 0, 5, 0, 0, 5, 0,
+  27, 0, 7, 0, 20, 2, 58, 63, 0, 50,
+  0, 0, 97, 52, 73, 0, 0, 0, 9, 20,
+  30, 0, 53, 59, 0, 0, 0, 0, 39, 57,
+  10, 31, 0, 0, 0, 14, 0, 0, 0, 54,
+  0, 21, 0, 18, 0, 113, 24, 11, 22, 20,
+  39, 43, 10, 0, 43, 0, 0, 50, 0, 0,
+  0, 0, 10, 1, 48, 0, 7, 0, 27, 0,
+  30, 0, 30, 47, 0, 22, 0, 0, 13, 12,
+  20, 0, 30, 0, 12, 20, 47, 4, 0, 16,
+  61, 0, 3, 0, 0, 56, 0, 10, 36, 0,
+  0, 41, 0, 0, 2, 0, 51, 24, 0, 0,
+  0, 75, 57, 0, 0, 1, 0, 46, 0, 115,
+  40, 68, 0, 0, 0, 16, 0, 0, 30, 32,
+  30, 0, 49, 0, 37, 54, 0, 31, 7, 0,
+  25, 63, 98, 0, 89, 0, 26, 32, 28, 22,
+  29, 0, 0, 0, 0, 0, 23, 34, 22, 43,
+  0, 13, 0, 0, 0, 67, 0, 29, 0, 0,
+  0, 0, 28, 122, 64, 34, 0, 28, 14, 55,
+  5, 5, 0, 0, 0, 59, 0, 9, 0, 5,
+  0, 38, 80, 0, 0, 0, 7, 0, 12, 0,
+  22, 22, 0, 28, 0, 8, 0, 24, 24, 29,
+  104, 12, 0, 37, 106, 0, 0, 105, 62, 22,
+  0, 0, 41, 62, 0, 12, 2, 0, 0, 43,
+  0, 0, 0, 0, 76, 0, 33, 0, 0, 91,
+  0, 53, 32, 0, 4, 39, 5, 115, 2, 34,
+  0, 36, 0, 56, 16, 0, 56, 0, 6, 0,
+  36, 0, 0, 14, 0, 21, 0, 0, 0, 0,
+  27, 0, 37, 0, 47, 52, 0, 14, 8, 31,
+  0, 0, 8, 0, 29, 0, 0, 10, 11, 0,
+  20, 0, 0, 68, 0, 34, 0, 0, 0, 0,
+  26, 84, 90, 0, 0, 0, 22, 0, 15, 31,
+  0, 34, 0, 30, 0, 52, 0, 0, 0, 0,
+  60, 0, 39, 0, 79, 0, 69, 0, 34, 16,
+  0, 39, 58, 0, 0, 0, 35, 20, 76, 0,
+  11, 39, 97, 0, 0, 94, 63, 17, 0, 0,
+  0, 47, 11, 21, 63, 0, 0, 58, 0, 0,
+  0, 24, 97, 0, 27, 0, 0, 89, 26, 22,
+  38, 4, 46, 33, 23, 117, 42, 0, 0, 22,
+  0, 0, 14, 0, 32, 0, 5, 0, 47, 0,
+  0, 49, 0, 19, 0, 0, 17, 1, 30, 0,
+  0, 0, 56, 43, 10, 31, 22, 65, 0, 0,
+  6, 0, 19, 88, 0, 42, 0, 0, 0, 23,
+  0, 11, 0, 31, 0, 0, 0, 0, 0, 85,
+  98, 0, 0, 0, 13, 0, 31, 29, 0, 24,
+  0, 19, 0, 5, 0, 0, 0, 12, 70, 0,
+  0, 0, 32, 0, 63, 0, 24, 34, 0, 10,
+  0, 0, 0, 0, 0, 1, 32, 2, 16, 56,
+  0, 30, 0, 9, 3, 0, 2, 0, 1, 27,
+  71, 20, 5, 0, 0, 23, 0, 18, 0, 0,
+  30, 0, 15, 0, 59, 84, 34, 0, 85, 0,
+  0, 5, 0, 98, 39, 10, 0, 0, 0, 0,
+  0, 0, 57, 0, 55, 0, 96, 0, 0, 81,
+  9, 12, 28, 9, 50, 46, 29, 21, 0, 0,
+  85, 58, 7, 94, 37, 18, 0, 0, 0, 22,
+  0, 74, 0, 50, 11, 36, 0, 0, 0, 84,
+  19, 16, 0, 0, 0, 0, 17, 49, 89, 0,
+  0, 0, 0, 27, 5, 0, 0, 3, 0, 9,
+  0, 9, 21, 75, 0, 33, 64, 0, 0, 0,
+  0, 0, 0, 0, 0, 41, 0, 0, 0, 15,
+  0, 83, 0, 21, 90, 39, 0, 48, 26, 0,
+  0, 60, 13, 28, 16, 0, 25, 81, 1, 0,
+  0, 0, 1, 44, 17, 19, 0, 35, 60, 0,
+  78, 36, 79, 138, 7, 0, 76, 0, 2, 0,
+  0, 129, 0, 4, 0, 11, 0, 4, 0, 0,
+  138, 0, 2, 0, 27, 0, 0, 90, 14, 2,
+  90, 0, 0, 39, 0, 61, 111, 0, 118, 35,
+  0, 31, 35, 22, 25, 0, 0, 0, 0, 27,
+  0, 0, 12, 25, 0, 0, 0, 91, 0, 7,
+  15, 0, 6, 0, 0, 89, 131, 18, 0, 0,
+  39, 0, 0, 48, 0, 0, 1, 67, 0, 57,
+  0, 0, 0, 0, 75, 0, 0, 0, 0, 0,
+  0, 0, 75, 51, 0, 0, 95, 9, 0, 0,
+  0, 24, 67, 28, 0, 54, 35, 44, 0, 52,
+  0, 15, 0, 0, 0, 58, 28, 9, 0, 0,
+  21, 48, 6, 84, 0, 37, 76, 0, 22, 0,
+  105, 123, 0, 0, 100, 0, 38, 0, 0, 109,
+  0, 0, 0, 11, 0, 0, 0, 0, 96, 0,
+  19, 0, 47, 0, 0, 83, 53, 15, 66, 0,
+  7, 34, 0, 90, 0, 0, 122, 30, 0, 21,
+  7, 0, 14, 0, 0, 2, 0, 89, 0, 17,
+  21, 0, 35, 0, 0, 36, 0, 3, 0, 0,
+  0, 0, 0, 59, 137, 0, 0, 0, 0, 0,
+  0, 52, 0, 3, 30, 17, 0, 0, 80, 0,
+  22, 0, 52, 0, 0, 0, 0, 0, 0, 14,
+  61, 73, 19, 3, 82, 25, 7, 0, 0, 19,
+  0, 0, 0, 50, 24, 124, 0, 0, 0, 0,
+  0, 0, 16, 66, 70, 4, 0, 0, 12, 4,
+  0, 88, 7, 3, 0, 13, 0, 0, 74, 8,
+  0, 0, 84, 0, 0, 15, 17, 36, 17, 22,
+  4, 0, 9, 49, 0, 0, 86, 0, 46, 0,
+  71, 0, 0, 47, 100, 0, 96, 0, 0, 47,
+  0, 116, 0, 23, 90, 0, 0, 33, 0, 0,
+  23, 0, 0, 55, 0, 76, 0, 1, 45, 31,
+  68, 0, 0, 0, 10, 0, 0, 0, 0, 0,
+  0, 29, 67, 0, 0, 0, 0, 4, 0, 42,
+  0, 0, 54, 0, 0, 0, 124, 74, 44, 0,
+  25, 0, 0, 0, 0, 25, 0, 22, 0, 56,
+  3, 37, 0, 0, 14, 0, 32, 0, 0, 0,
+  3, 23, 56, 0, 0, 4, 62, 15, 4, 0,
+  0, 72, 0, 17, 107, 0, 0, 48, 0, 0,
+  0, 48, 90, 0, 0, 0, 0, 51, 43, 7,
+  0, 46, 21, 29, 25, 100, 41, 0, 0, 5,
+  0, 0, 5, 0, 27, 0, 7, 0, 20, 2,
+  58, 63, 0, 50, 0, 0, 97, 52, 73, 0,
+  0, 0, 9, 20, 30, 0, 53, 59, 0, 0,
+  0, 0, 39, 57, 10, 31, 0, 0, 0, 14,
+  0, 0, 0, 54, 0, 21, 0, 18, 0, 113,
+  24, 11, 22, 20, 39, 43, 10, 0, 43, 0,
+  0, 50, 0, 0, 0, 0, 10, 1, 48, 0,
+  7, 0, 27, 0, 30, 0, 30, 47, 0, 22,
+  0, 0, 13, 12, 20, 0, 30, 0, 12, 20,
+  47, 4, 0, 16, 61, 0, 3, 0, 0, 56,
+  0, 10, 36, 0, 0, 41, 0, 0, 2, 0,
+  51, 24, 0, 0, 0, 75, 57, 0, 0, 1,
+  0, 46, 0, 115, 40, 68, 0, 0, 0, 16,
+  0, 0, 30, 32, 30, 0, 49, 0, 37, 54,
+  0, 31, 7, 0, 25, 63, 98, 0, 89, 0,
+  26, 32, 28, 22, 29, 0, 0, 0, 0, 0,
+  23, 34, 22, 43, 0, 13, 0, 0, 0, 67,
+  0, 29, 0, 0, 0, 0, 28, 122, 64, 34,
+  0, 28, 14, 55, 5, 5, 0, 0, 0, 59,
+  0, 9, 0, 5, 0, 38, 80, 0, 0, 0,
+  7, 0, 12, 0, 22, 22, 0, 49, 0, 0,
+  0, 0, 12, 0, 80, 43, 25, 0, 73, 2,
+  0, 149, 100, 43, 17, 0, 0, 0, 0, 25,
+  0, 0, 21, 90, 9, 0, 9, 0, 115, 13,
+  0, 0, 4, 73, 0, 0, 23, 0, 0, 26,
+  0, 80, 0, 54, 0, 37, 0, 15, 61, 0,
+  0, 23, 13, 7, 0, 32, 0, 0, 0, 0,
+  0, 0, 27, 12, 61, 0, 7, 0, 0, 98,
+  0, 66, 0, 13, 0, 0, 19, 3, 24, 48,
+  0, 47, 3, 23, 13, 19, 53, 124, 0, 32,
+  23, 0, 0, 0, 0, 90, 142, 0, 0, 0,
+  8, 0, 0, 33, 0, 34, 0, 47, 0, 22,
+  0, 0, 0, 0, 6, 0, 0, 0, 122, 0,
+  29, 0, 52, 16, 0, 39, 58, 0, 0, 0,
+  35, 20, 76, 0, 11, 39, 97, 0, 0, 94,
+  63, 17, 0, 0, 0, 47, 11, 21, 63, 0,
+  0, 58, 0, 0, 0, 24, 97, 0, 27, 0,
+  0, 89, 26, 22, 38, 4, 46, 33, 23, 117,
+  42, 0, 0, 22, 0, 0, 14, 0, 32, 0,
+  5, 0, 47, 0, 0, 49, 0, 19, 0, 0,
+  17, 1, 30, 0, 0, 0, 56, 43, 10, 31,
+  22, 65, 0, 0, 6, 0, 19, 88, 0, 42,
+  0, 0, 0, 23, 0, 11, 0, 31, 0, 0,
+  0, 0, 0, 85, 98, 0, 0, 0, 13, 0,
+  31, 29, 0, 24, 0, 19, 0, 5, 0, 0,
+  0, 12, 70, 0, 0, 0, 32, 0, 63, 0,
+  24, 34, 0, 10, 0, 0, 0, 0, 0, 1,
+  32, 2, 16, 56, 0, 30, 0, 9, 3, 0,
+  2, 0, 1, 27, 71, 20, 5, 0, 0, 23,
+  0, 18, 0, 0, 30, 0, 15, 0, 59, 84,
+  34, 0, 85, 0, 0, 5, 0, 98, 39, 10,
+  0, 0, 0, 0, 0, 0, 57, 0, 55, 0,
+  96, 0, 0, 81, 9, 12, 28, 9, 50, 46,
+  29, 21, 0, 0, 85, 58, 7, 94, 37, 18,
+  0, 0, 0, 22, 0, 74, 0, 50, 11, 36,
+  0, 0, 0, 84, 19, 16, 0, 0, 0, 0,
+  17, 49, 89, 0, 0, 0, 0, 27, 5, 0,
+  0, 3, 0, 9, 0, 9, 21, 75, 0, 33,
+  64, 0, 0, 0, 0, 0, 0, 0, 0, 41,
+  4, 18, 11, 6, 0, 0, 0, 0, 60, 44,
+  0, 0, 0, 54, 0, 0, 0, 29, 17, 0,
+  3, 11, 34, 17, 0, 0, 58, 48, 0, 0,
+  0, 0, 53, 0, 0, 0, 74, 109, 0, 0,
+  46, 0, 0, 0, 0, 59, 0, 51, 0, 23,
+  0, 0, 0, 0, 78, 7, 34, 8, 0, 0,
+  0, 52, 29, 14, 74, 2, 53, 17, 8, 144,
+  9, 0, 46, 89, 0, 57, 27, 0, 12, 0,
+  0, 0, 31, 87, 0, 30, 0, 43, 20, 0,
+  0, 171, 0, 0, 22, 0, 7, 0, 0, 57,
+  123, 33, 0, 0, 0, 0, 0, 2, 0, 0,
+  0, 24, 0, 10, 20, 24, 0, 0, 14, 0,
+  0, 0, 0, 0, 0, 4, 58, 62, 0, 0,
+  95, 9, 0, 0, 0, 24, 67, 28, 0, 54,
+  35, 44, 0, 52, 0, 15, 0, 0, 0, 58,
+  28, 9, 0, 0, 21, 48, 6, 84, 0, 37,
+  76, 0, 22, 0, 105, 123, 0, 0, 100, 0,
+  38, 0, 0, 109, 0, 0, 0, 11, 0, 0,
+  0, 0, 96, 0, 19, 0, 47, 0, 0, 83,
+  53, 15, 66, 0, 7, 34, 0, 90, 0, 0,
+  122, 30, 0, 21, 7, 0, 14, 0, 0, 2,
+  0, 89, 0, 17, 21, 0, 35, 0, 0, 36,
+  0, 3, 0, 0, 0, 0, 0, 59, 137, 0,
+  0, 0, 0, 0, 0, 52, 0, 3, 30, 17,
+  0, 0, 80, 0, 22, 0, 52, 0, 0, 0,
+  0, 0, 0, 14, 61, 73, 19, 3, 82, 25,
+  7, 0, 0, 19, 0, 0, 0, 50, 24, 124,
+  0, 0, 0, 0, 0, 0, 16, 66, 70, 4,
+  0, 0, 12, 4, 0, 88, 7, 3, 0, 13,
+  0, 0, 74, 8, 0, 0, 84, 0, 0, 15,
+  17, 36, 17, 22, 4, 0, 9, 49, 0, 0,
+  86, 0, 46, 0, 71, 0, 0, 47, 100, 0,
+  96, 0, 0, 47, 0, 116, 0, 23, 90, 0,
+  0, 33, 0, 0, 23, 0, 0, 55, 0, 76,
+  0, 1, 45, 31, 68, 0, 0, 0, 10, 0,
+  0, 0, 0, 0, 0, 29, 67, 0, 0, 0,
+  0, 4, 0, 42, 0, 0, 54, 0, 0, 0,
+  124, 74, 44, 0, 25, 0, 0, 0, 0, 25,
+  0, 22, 0, 56, 83, 83, 12, 72, 44, 15,
+  0, 0, 20, 0, 22, 0, 23, 126, 0, 0,
+  0, 0, 39, 0, 24, 37, 34, 21, 0, 0,
+  35, 11, 0, 34, 52, 81, 0, 0, 0, 0,
+  0, 26, 0, 0, 0, 1, 0, 0, 1, 18,
+  42, 71, 0, 0, 11, 40, 0, 7, 106, 0,
+  38, 4, 10, 0, 0, 34, 61, 26, 20, 0,
+  27, 21, 0, 98, 0, 49, 51, 0, 0, 28,
+  54, 0, 44, 0, 0, 48, 15, 60, 0, 1,
+  2, 45, 68, 0, 14, 0, 0, 25, 0, 0,
+  81, 0, 11, 15, 12, 121, 4, 0, 0, 16,
+  0, 68, 74, 0, 26, 0, 17, 1, 24, 87,
+  0, 0, 20, 2, 10, 0, 0, 0, 0, 22,
+  0, 87, 0, 22, 0, 0, 13, 12, 20, 0,
+  30, 0, 12, 20, 47, 4, 0, 16, 61, 0,
+  3, 0, 0, 56, 0, 10, 36, 0, 0, 41,
+  0, 0, 2, 0, 51, 24, 0, 0, 0, 75,
+  57, 0, 0, 1, 0, 46, 0, 115, 40, 68,
+  0, 0, 0, 16, 0, 0, 30, 32, 30, 0,
+  49, 0, 37, 54, 0, 31, 7, 0, 25, 63,
+  98, 0, 89, 0, 26, 32, 28, 22, 29, 0,
+  0, 0, 0, 0, 23, 34, 22, 43, 0, 13,
+  0, 0, 0, 67, 0, 29, 0, 0, 0, 0,
+  28, 122, 64, 34, 0, 28, 14, 55, 5, 5,
+  0, 0, 0, 59, 0, 9, 0, 5, 0, 38,
+  80, 0, 0, 0, 7, 0, 12, 0, 22, 22,
+  0, 49, 0, 0, 0, 0, 12, 0, 80, 43,
+  25, 0, 73, 2, 0, 149, 100, 43, 17, 0,
+  0, 0, 0, 25, 0, 0, 21, 90, 9, 0,
+  9, 0, 115, 13, 0, 0, 4, 73, 0, 0,
+  23, 0, 0, 26, 0, 80, 0, 54, 0, 37,
+  0, 15, 61, 0, 0, 23, 13, 7, 0, 32,
+  0, 0, 0, 0, 0, 0, 27, 12, 61, 0,
+  7, 0, 0, 98, 0, 66, 0, 13, 0, 0,
+  19, 3, 24, 48, 0, 47, 3, 23, 13, 19,
+  53, 124, 0, 32, 23, 0, 0, 0, 0, 90,
+  142, 0, 0, 0, 8, 0, 0, 33, 0, 34,
+  0, 47, 0, 22, 0, 0, 0, 0, 6, 0,
+  0, 0, 122, 0, 29, 0, 52, 16, 0, 27,
+  108, 0, 0, 0, 0, 0, 90, 42, 15, 0,
+  26, 53, 0, 84, 60, 35, 50, 0, 0, 15,
+  20, 31, 0, 0, 3, 111, 0, 0, 0, 0,
+  61, 0, 0, 0, 0, 79, 0, 0, 3, 0,
+  0, 0, 0, 28, 0, 0, 0, 35, 0, 82,
+  11, 0, 69, 0, 27, 18, 0, 0, 0, 0,
+  0, 0, 27, 0, 48, 0, 11, 70, 0, 0,
+  22, 90, 0, 69, 0, 68, 0, 0, 7, 0,
+  32, 92, 0, 47, 0, 58, 48, 0, 85, 34,
+  0, 0, 11, 0, 0, 0, 0, 133, 125, 0,
+  0, 0, 8, 0, 0, 61, 0, 16, 7, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  45, 0, 54, 0, 21, 46, 0, 10, 0, 0,
+  0, 0, 0, 1, 32, 2, 16, 56, 0, 30,
+  0, 9, 3, 0, 2, 0, 1, 27, 71, 20,
+  5, 0, 0, 23, 0, 18, 0, 0, 30, 0,
+  15, 0, 59, 84, 34, 0, 85, 0, 0, 5,
+  0, 98, 39, 10, 0, 0, 0, 0, 0, 0,
+  57, 0, 55, 0, 96, 0, 0, 81, 9, 12,
+  28, 9, 50, 46, 29, 21, 0, 0, 85, 58,
+  7, 94, 37, 18, 0, 0, 0, 22, 0, 74,
+  0, 50, 11, 36, 0, 0, 0, 84, 19, 16,
+  0, 0, 0, 0, 17, 49, 89, 0, 0, 0,
+  0, 27, 5, 0, 0, 3, 0, 9, 0, 9,
+  21, 75, 0, 33, 64, 0, 0, 0, 0, 0,
+  0, 0, 0, 41, 4, 18, 11, 6, 0, 0,
+  0, 0, 60, 44, 0, 0, 0, 54, 0, 0,
+  0, 29, 17, 0, 3, 11, 34, 17, 0, 0,
+  58, 48, 0, 0, 0, 0, 53, 0, 0, 0,
+  74, 109, 0, 0, 46, 0, 0, 0, 0, 59,
+  0, 51, 0, 23, 0, 0, 0, 0, 78, 7,
+  34, 8, 0, 0, 0, 52, 29, 14, 74, 2,
+  53, 17, 8, 144, 9, 0, 46, 89, 0, 57,
+  27, 0, 12, 0, 0, 0, 31, 87, 0, 30,
+  0, 43, 20, 0, 0, 171, 0, 0, 22, 0,
+  7, 0, 0, 57, 123, 33, 0, 0, 0, 0,
+  0, 2, 0, 0, 0, 24, 0, 10, 20, 24,
+  0, 0, 14, 0, 0, 0, 0, 0, 0, 4,
+  58, 62, 28, 0, 51, 0, 0, 127, 0, 0,
+  28, 13, 0, 0, 0, 82, 0, 0, 9, 29,
+  31, 0, 0, 85, 28, 32, 0, 0, 13, 55,
+  0, 0, 0, 43, 0, 0, 0, 17, 44, 93,
+  0, 0, 24, 0, 15, 0, 0, 32, 0, 29,
+  0, 35, 0, 77, 0, 0, 138, 0, 12, 0,
+  0, 0, 0, 64, 0, 0, 81, 0, 9, 6,
+  12, 125, 8, 0, 33, 55, 0, 39, 22, 0,
+  0, 0, 0, 0, 28, 82, 0, 10, 0, 46,
+  0, 0, 0, 123, 0, 0, 55, 0, 11, 0,
+  0, 88, 63, 49, 0, 0, 27, 0, 0, 10,
+  0, 6, 1, 11, 0, 0, 9, 35, 24, 0,
+  11, 0, 0, 0, 0, 0, 0, 3, 9, 79,
+  19, 3, 82, 25, 7, 0, 0, 19, 0, 0,
+  0, 50, 24, 124, 0, 0, 0, 0, 0, 0,
+  16, 66, 70, 4, 0, 0, 12, 4, 0, 88,
+  7, 3, 0, 13, 0, 0, 74, 8, 0, 0,
+  84, 0, 0, 15, 17, 36, 17, 22, 4, 0,
+  9, 49, 0, 0, 86, 0, 46, 0, 71, 0,
+  0, 47, 100, 0, 96, 0, 0, 47, 0, 116,
+  0, 23, 90, 0, 0, 33, 0, 0, 23, 0,
+  0, 55, 0, 76, 0, 1, 45, 31, 68, 0,
+  0, 0, 10, 0, 0, 0, 0, 0, 0, 29,
+  67, 0, 0, 0, 0, 4, 0, 42, 0, 0,
+  54, 0, 0, 0, 124, 74, 44, 0, 25, 0,
+  0, 0, 0, 25, 0, 22, 0, 56, 83, 83,
+  12, 72, 44, 15, 0, 0, 20, 0, 22, 0,
+  23, 126, 0, 0, 0, 0, 39, 0, 24, 37,
+  34, 21, 0, 0, 35, 11, 0, 34, 52, 81,
+  0, 0, 0, 0, 0, 26, 0, 0, 0, 1,
+  0, 0, 1, 18, 42, 71, 0, 0, 11, 40,
+  0, 7, 106, 0, 38, 4, 10, 0, 0, 34,
+  61, 26, 20, 0, 27, 21, 0, 98, 0, 49,
+  51, 0, 0, 28, 54, 0, 44, 0, 0, 48,
+  15, 60, 0, 1, 2, 45, 68, 0, 14, 0,
+  0, 25, 0, 0, 81, 0, 11, 15, 12, 121,
+  4, 0, 0, 16, 0, 68, 74, 0, 26, 0,
+  17, 1, 24, 87, 0, 0, 20, 2, 10, 0,
+  0, 0, 0, 22, 0, 87, 35, 0, 20, 65,
+  14, 232, 0, 0, 1, 0, 0, 0, 0, 21,
+  0, 0, 0, 33, 62, 0, 0, 113, 15, 0,
+  0, 0, 0, 6, 0, 17, 8, 99, 0, 0,
+  0, 33, 0, 40, 0, 0, 0, 0, 0, 0,
+  0, 58, 44, 47, 7, 4, 0, 38, 0, 0,
+  142, 0, 48, 0, 21, 0, 27, 92, 17, 0,
+  115, 0, 0, 40, 0, 96, 83, 63, 62, 0,
+  0, 35, 43, 0, 0, 0, 0, 0, 46, 65,
+  0, 0, 0, 31, 0, 0, 7, 7, 0, 0,
+  70, 0, 52, 0, 0, 9, 17, 116, 2, 0,
+  0, 5, 18, 17, 0, 0, 0, 39, 0, 0,
+  0, 45, 36, 0, 13, 16, 0, 19, 0, 0,
+  0, 15, 0, 44, 0, 49, 0, 0, 0, 0,
+  12, 0, 80, 43, 25, 0, 73, 2, 0, 149,
+  100, 43, 17, 0, 0, 0, 0, 25, 0, 0,
+  21, 90, 9, 0, 9, 0, 115, 13, 0, 0,
+  4, 73, 0, 0, 23, 0, 0, 26, 0, 80,
+  0, 54, 0, 37, 0, 15, 61, 0, 0, 23,
+  13, 7, 0, 32, 0, 0, 0, 0, 0, 0,
+  27, 12, 61, 0, 7, 0, 0, 98, 0, 66,
+  0, 13, 0, 0, 19, 3, 24, 48, 0, 47,
+  3, 23, 13, 19, 53, 124, 0, 32, 23, 0,
+  0, 0, 0, 90, 142, 0, 0, 0, 8, 0,
+  0, 33, 0, 34, 0, 47, 0, 22, 0, 0,
+  0, 0, 6, 0, 0, 0, 122, 0, 29, 0,
+  52, 16, 0, 27, 108, 0, 0, 0, 0, 0,
+  90, 42, 15, 0, 26, 53, 0, 84, 60, 35,
+  50, 0, 0, 15, 20, 31, 0, 0, 3, 111,
+  0, 0, 0, 0, 61, 0, 0, 0, 0, 79,
+  0, 0, 3, 0, 0, 0, 0, 28, 0, 0,
+  0, 35, 0, 82, 11, 0, 69, 0, 27, 18,
+  0, 0, 0, 0, 0, 0, 27, 0, 48, 0,
+  11, 70, 0, 0, 22, 90, 0, 69, 0, 68,
+  0, 0, 7, 0, 32, 92, 0, 47, 0, 58,
+  48, 0, 85, 34, 0, 0, 11, 0, 0, 0,
+  0, 133, 125, 0, 0, 0, 8, 0, 0, 61,
+  0, 16, 7, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 45, 0, 54, 0, 21, 46,
+  0, 0, 117, 0, 0, 75, 0, 0, 21, 0,
+  0, 1, 34, 80, 0, 0, 0, 31, 19, 0,
+  0, 94, 14, 24, 0, 0, 0, 29, 0, 0,
+  10, 39, 0, 0, 0, 0, 0, 56, 0, 0,
+  0, 0, 0, 7, 0, 0, 0, 0, 0, 0,
+  0, 155, 0, 0, 71, 0, 21, 0, 50, 0,
+  0, 5, 0, 0, 108, 0, 0, 0, 0, 98,
+  0, 0, 39, 7, 0, 0, 0, 22, 15, 0,
+  0, 0, 31, 74, 16, 3, 15, 30, 48, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 72,
+  30, 0, 0, 0, 0, 78, 0, 23, 0, 11,
+  40, 0, 0, 0, 17, 16, 68, 25, 10, 51,
+  0, 3, 0, 0, 33, 0, 0, 53, 4, 18,
+  11, 6, 0, 0, 0, 0, 60, 44, 0, 0,
+  0, 54, 0, 0, 0, 29, 17, 0, 3, 11,
+  34, 17, 0, 0, 58, 48, 0, 0, 0, 0,
+  53, 0, 0, 0, 74, 109, 0, 0, 46, 0,
+  0, 0, 0, 59, 0, 51, 0, 23, 0, 0,
+  0, 0, 78, 7, 34, 8, 0, 0, 0, 52,
+  29, 14, 74, 2, 53, 17, 8, 144, 9, 0,
+  46, 89, 0, 57, 27, 0, 12, 0, 0, 0,
+  31, 87, 0, 30, 0, 43, 20, 0, 0, 171,
+  0, 0, 22, 0, 7, 0, 0, 57, 123, 33,
+  0, 0, 0, 0, 0, 2, 0, 0, 0, 24,
+  0, 10, 20, 24, 0, 0, 14, 0, 0, 0,
+  0, 0, 0, 4, 58, 62, 28, 0, 51, 0,
+  0, 127, 0, 0, 28, 13, 0, 0, 0, 82,
+  0, 0, 9, 29, 31, 0, 0, 85, 28, 32,
+  0, 0, 13, 55, 0, 0, 0, 43, 0, 0,
+  0, 17, 44, 93, 0, 0, 24, 0, 15, 0,
+  0, 32, 0, 29, 0, 35, 0, 77, 0, 0,
+  138, 0, 12, 0, 0, 0, 0, 64, 0, 0,
+  81, 0, 9, 6, 12, 125, 8, 0, 33, 55,
+  0, 39, 22, 0, 0, 0, 0, 0, 28, 82,
+  0, 10, 0, 46, 0, 0, 0, 123, 0, 0,
+  55, 0, 11, 0, 0, 88, 63, 49, 0, 0,
+  27, 0, 0, 10, 0, 6, 1, 11, 0, 0,
+  9, 35, 24, 0, 11, 0, 0, 0, 0, 0,
+  0, 3, 9, 79, 0, 0, 30, 0, 26, 161,
+  0, 0, 0, 0, 0, 0, 49, 60, 0, 0,
+  11, 55, 0, 0, 7, 16, 0, 50, 0, 0,
+  0, 0, 0, 35, 21, 0, 0, 13, 0, 0,
+  0, 55, 0, 3, 0, 20, 0, 22, 0, 12,
+  34, 22, 0, 0, 13, 103, 4, 0, 17, 0,
+  10, 0, 46, 0, 0, 0, 0, 0, 54, 0,
+  0, 2, 0, 4, 0, 34, 24, 5, 0, 40,
+  0, 0, 0, 10, 0, 0, 18, 36, 19, 0,
+  31, 36, 38, 0, 0, 22, 13, 0, 4, 0,
+  0, 0, 1, 46, 1, 0, 0, 0, 0, 10,
+  0, 22, 0, 25, 23, 0, 0, 0, 5, 29,
+  102, 47, 32, 3, 54, 0, 0, 0, 37, 15,
+  0, 14, 83, 83, 12, 72, 44, 15, 0, 0,
+  20, 0, 22, 0, 23, 126, 0, 0, 0, 0,
+  39, 0, 24, 37, 34, 21, 0, 0, 35, 11,
+  0, 34, 52, 81, 0, 0, 0, 0, 0, 26,
+  0, 0, 0, 1, 0, 0, 1, 18, 42, 71,
+  0, 0, 11, 40, 0, 7, 106, 0, 38, 4,
+  10, 0, 0, 34, 61, 26, 20, 0, 27, 21,
+  0, 98, 0, 49, 51, 0, 0, 28, 54, 0,
+  44, 0, 0, 48, 15, 60, 0, 1, 2, 45,
+  68, 0, 14, 0, 0, 25, 0, 0, 81, 0,
+  11, 15, 12, 121, 4, 0, 0, 16, 0, 68,
+  74, 0, 26, 0, 17, 1, 24, 87, 0, 0,
+  20, 2, 10, 0, 0, 0, 0, 22, 0, 87,
+  35, 0, 20, 65, 14, 232, 0, 0, 1, 0,
+  0, 0, 0, 21, 0, 0, 0, 33, 62, 0,
+  0, 113, 15, 0, 0, 0, 0, 6, 0, 17,
+  8, 99, 0, 0, 0, 33, 0, 40, 0, 0,
+  0, 0, 0, 0, 0, 58, 44, 47, 7, 4,
+  0, 38, 0, 0, 142, 0, 48, 0, 21, 0,
+  27, 92, 17, 0, 115, 0, 0, 40, 0, 96,
+  83, 63, 62, 0, 0, 35, 43, 0, 0, 0,
+  0, 0, 46, 65, 0, 0, 0, 31, 0, 0,
+  7, 7, 0, 0, 70, 0, 52, 0, 0, 9,
+  17, 116, 2, 0, 0, 5, 18, 17, 0, 0,
+  0, 39, 0, 0, 0, 45, 36, 0, 13, 16,
+  0, 19, 0, 0, 0, 15, 0, 44, 0, 0,
+  0, 5, 19, 184, 0, 0, 0, 0, 0, 0,
+  30, 14, 0, 24, 4, 50, 5, 0, 21, 0,
+  0, 62, 18, 19, 0, 0, 0, 10, 18, 0,
+  0, 34, 0, 4, 0, 24, 0, 24, 0, 55,
+  0, 16, 0, 17, 43, 43, 0, 20, 0, 38,
+  14, 0, 0, 0, 9, 0, 19, 12, 5, 26,
+  0, 0, 6, 0, 0, 22, 22, 0, 30, 56,
+  37, 1, 2, 80, 0, 0, 0, 42, 0, 0,
+  13, 12, 24, 0, 22, 14, 2, 28, 1, 67,
+  43, 9, 35, 30, 0, 0, 7, 25, 0, 0,
+  0, 0, 0, 0, 0, 6, 0, 17, 0, 1,
+  0, 13, 0, 7, 81, 29, 34, 0, 48, 9,
+  42, 0, 38, 19, 0, 0, 0, 27, 108, 0,
+  0, 0, 0, 0, 90, 42, 15, 0, 26, 53,
+  0, 84, 60, 35, 50, 0, 0, 15, 20, 31,
+  0, 0, 3, 111, 0, 0, 0, 0, 61, 0,
+  0, 0, 0, 79, 0, 0, 3, 0, 0, 0,
+  0, 28, 0, 0, 0, 35, 0, 82, 11, 0,
+  69, 0, 27, 18, 0, 0, 0, 0, 0, 0,
+  27, 0, 48, 0, 11, 70, 0, 0, 22, 90,
+  0, 69, 0, 68, 0, 0, 7, 0, 32, 92,
+  0, 47, 0, 58, 48, 0, 85, 34, 0, 0,
+  11, 0, 0, 0, 0, 133, 125, 0, 0, 0,
+  8, 0, 0, 61, 0, 16, 7, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 45, 0,
+  54, 0, 21, 46, 0, 0, 117, 0, 0, 75,
+  0, 0, 21, 0, 0, 1, 34, 80, 0, 0,
+  0, 31, 19, 0, 0, 94, 14, 24, 0, 0,
+  0, 29, 0, 0, 10, 39, 0, 0, 0, 0,
+  0, 56, 0, 0, 0, 0, 0, 7, 0, 0,
+  0, 0, 0, 0, 0, 155, 0, 0, 71, 0,
+  21, 0, 50, 0, 0, 5, 0, 0, 108, 0,
+  0, 0, 0, 98, 0, 0, 39, 7, 0, 0,
+  0, 22, 15, 0, 0, 0, 31, 74, 16, 3,
+  15, 30, 48, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 72, 30, 0, 0, 0, 0, 78,
+  0, 23, 0, 11, 40, 0, 0, 0, 17, 16,
+  68, 25, 10, 51, 0, 3, 0, 0, 33, 0,
+  0, 53, 0, 0, 59, 0, 5, 69, 0, 0,
+  0, 0, 0, 19, 45, 76, 0, 0, 0, 17,
+  2, 8, 10, 22, 0, 35, 0, 0, 0, 0,
+  0, 77, 41, 11, 0, 18, 0, 0, 0, 17,
+  0, 13, 0, 0, 0, 39, 0, 0, 0, 0,
+  0, 0, 0, 110, 0, 0, 0, 0, 15, 4,
+  28, 0, 0, 0, 0, 0, 48, 0, 0, 6,
+  0, 9, 0, 40, 17, 0, 0, 0, 0, 0,
+  53, 0, 0, 17, 0, 52, 45, 0, 40, 9,
+  68, 0, 0, 0, 56, 0, 0, 5, 0, 0,
+  0, 21, 0, 0, 0, 0, 1, 53, 0, 16,
+  7, 45, 50, 0, 0, 13, 38, 10, 68, 48,
+  19, 52, 56, 0, 0, 0, 26, 9, 0, 10,
+  28, 0, 51, 0, 0, 127, 0, 0, 28, 13,
+  0, 0, 0, 82, 0, 0, 9, 29, 31, 0,
+  0, 85, 28, 32, 0, 0, 13, 55, 0, 0,
+  0, 43, 0, 0, 0, 17, 44, 93, 0, 0,
+  24, 0, 15, 0, 0, 32, 0, 29, 0, 35,
+  0, 77, 0, 0, 138, 0, 12, 0, 0, 0,
+  0, 64, 0, 0, 81, 0, 9, 6, 12, 125,
+  8, 0, 33, 55, 0, 39, 22, 0, 0, 0,
+  0, 0, 28, 82, 0, 10, 0, 46, 0, 0,
+  0, 123, 0, 0, 55, 0, 11, 0, 0, 88,
+  63, 49, 0, 0, 27, 0, 0, 10, 0, 6,
+  1, 11, 0, 0, 9, 35, 24, 0, 11, 0,
+  0, 0, 0, 0, 0, 3, 9, 79, 0, 0,
+  30, 0, 26, 161, 0, 0, 0, 0, 0, 0,
+  49, 60, 0, 0, 11, 55, 0, 0, 7, 16,
+  0, 50, 0, 0, 0, 0, 0, 35, 21, 0,
+  0, 13, 0, 0, 0, 55, 0, 3, 0, 20,
+  0, 22, 0, 12, 34, 22, 0, 0, 13, 103,
+  4, 0, 17, 0, 10, 0, 46, 0, 0, 0,
+  0, 0, 54, 0, 0, 2, 0, 4, 0, 34,
+  24, 5, 0, 40, 0, 0, 0, 10, 0, 0,
+  18, 36, 19, 0, 31, 36, 38, 0, 0, 22,
+  13, 0, 4, 0, 0, 0, 1, 46, 1, 0,
+  0, 0, 0, 10, 0, 22, 0, 25, 23, 0,
+  0, 0, 5, 29, 102, 47, 32, 3, 54, 0,
+  0, 0, 37, 15, 0, 14, 0, 49, 11, 0,
+  44, 0, 25, 0, 19, 0, 0, 0, 81, 51,
+  5, 17, 15, 0, 0, 0, 3, 0, 0, 60,
+  21, 63, 0, 0, 0, 12, 63, 0, 0, 27,
+  12, 0, 0, 6, 0, 70, 0, 97, 10, 75,
+  53, 0, 0, 0, 0, 6, 0, 65, 94, 0,
+  0, 3, 21, 23, 4, 21, 0, 0, 0, 70,
+  0, 12, 8, 0, 0, 0, 0, 33, 0, 19,
+  20, 29, 0, 0, 0, 27, 44, 20, 19, 0,
+  78, 0, 29, 0, 66, 38, 0, 0, 42, 37,
+  0, 32, 0, 38, 3, 45, 0, 0, 0, 0,
+  0, 0, 3, 5, 71, 72, 88, 0, 0, 7,
+  31, 0, 0, 31, 64, 18, 57, 10, 85, 0,
+  91, 2, 0, 0, 35, 0, 20, 65, 14, 232,
+  0, 0, 1, 0, 0, 0, 0, 21, 0, 0,
+  0, 33, 62, 0, 0, 113, 15, 0, 0, 0,
+  0, 6, 0, 17, 8, 99, 0, 0, 0, 33,
+  0, 40, 0, 0, 0, 0, 0, 0, 0, 58,
+  44, 47, 7, 4, 0, 38, 0, 0, 142, 0,
+  48, 0, 21, 0, 27, 92, 17, 0, 115, 0,
+  0, 40, 0, 96, 83, 63, 62, 0, 0, 35,
+  43, 0, 0, 0, 0, 0, 46, 65, 0, 0,
+  0, 31, 0, 0, 7, 7, 0, 0, 70, 0,
+  52, 0, 0, 9, 17, 116, 2, 0, 0, 5,
+  18, 17, 0, 0, 0, 39, 0, 0, 0, 45,
+  36, 0, 13, 16, 0, 19, 0, 0, 0, 15,
+  0, 44, 0, 0, 0, 5, 19, 184, 0, 0,
+  0, 0, 0, 0, 30, 14, 0, 24, 4, 50,
+  5, 0, 21, 0, 0, 62, 18, 19, 0, 0,
+  0, 10, 18, 0, 0, 34, 0, 4, 0, 24,
+  0, 24, 0, 55, 0, 16, 0, 17, 43, 43,
+  0, 20, 0, 38, 14, 0, 0, 0, 9, 0,
+  19, 12, 5, 26, 0, 0, 6, 0, 0, 22,
+  22, 0, 30, 56, 37, 1, 2, 80, 0, 0,
+  0, 42, 0, 0, 13, 12, 24, 0, 22, 14,
+  2, 28, 1, 67, 43, 9, 35, 30, 0, 0,
+  7, 25, 0, 0, 0, 0, 0, 0, 0, 6,
+  0, 17, 0, 1, 0, 13, 0, 7, 81, 29,
+  34, 0, 48, 9, 42, 0, 38, 19, 0, 0,
+  0, 34, 49, 0, 25, 0, 17, 0, 0, 0,
+  0, 0, 29, 51, 2, 46, 15, 40, 0, 20,
+  33, 0, 79, 40, 0, 20, 0, 0, 0, 0,
+  25, 0, 0, 0, 0, 0, 0, 5, 0, 35,
+  63, 42, 0, 75, 56, 0, 0, 0, 0, 4,
+  0, 42, 63, 0, 1, 0, 44, 5, 9, 0,
+  0, 3, 0, 23, 0, 0, 26, 7, 0, 0,
+  0, 3, 4, 30, 12, 34, 0, 8, 0, 0,
+  40, 0, 0, 0, 68, 13, 0, 0, 40, 12,
+  0, 29, 32, 0, 0, 30, 0, 0, 0, 46,
+  0, 0, 0, 0, 5, 0, 0, 0, 0, 29,
+  58, 4, 0, 15, 30, 0, 26, 17, 54, 0,
+  15, 0, 9, 0, 76, 5, 0, 0, 0, 0,
+  117, 0, 0, 75, 0, 0, 21, 0, 0, 1,
+  34, 80, 0, 0, 0, 31, 19, 0, 0, 94,
+  14, 24, 0, 0, 0, 29, 0, 0, 10, 39,
+  0, 0, 0, 0, 0, 56, 0, 0, 0, 0,
+  0, 7, 0, 0, 0, 0, 0, 0, 0, 155,
+  0, 0, 71, 0, 21, 0, 50, 0, 0, 5,
+  0, 0, 108, 0, 0, 0, 0, 98, 0, 0,
+  39, 7, 0, 0, 0, 22, 15, 0, 0, 0,
+  31, 74, 16, 3, 15, 30, 48, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 72, 30, 0,
+  0, 0, 0, 78, 0, 23, 0, 11, 40, 0,
+  0, 0, 17, 16, 68, 25, 10, 51, 0, 3,
+  0, 0, 33, 0, 0, 53, 0, 0, 59, 0,
+  5, 69, 0, 0, 0, 0, 0, 19, 45, 76,
+  0, 0, 0, 17, 2, 8, 10, 22, 0, 35,
+  0, 0, 0, 0, 0, 77, 41, 11, 0, 18,
+  0, 0, 0, 17, 0, 13, 0, 0, 0, 39,
+  0, 0, 0, 0, 0, 0, 0, 110, 0, 0,
+  0, 0, 15, 4, 28, 0, 0, 0, 0, 0,
+  48, 0, 0, 6, 0, 9, 0, 40, 17, 0,
+  0, 0, 0, 0, 53, 0, 0, 17, 0, 52,
+  45, 0, 40, 9, 68, 0, 0, 0, 56, 0,
+  0, 5, 0, 0, 0, 21, 0, 0, 0, 0,
+  1, 53, 0, 16, 7, 45, 50, 0, 0, 13,
+  38, 10, 68, 48, 19, 52, 56, 0, 0, 0,
+  26, 9, 0, 10, 0, 52, 52, 0, 44, 0,
+  21, 0, 7, 0, 0, 3, 68, 73, 3, 33,
+  10, 1, 18, 0, 44, 0, 0, 50, 14, 42,
+  0, 0, 0, 12, 60, 0, 0, 39, 0, 0,
+  0, 7, 0, 62, 39, 63, 0, 87, 51, 0,
+  0, 0, 0, 0, 0, 78, 42, 0, 0, 0,
+  18, 20, 19, 14, 11, 0, 3, 81, 0, 28,
+  0, 0, 0, 0, 0, 30, 0, 13, 8, 1,
+  0, 0, 0, 18, 37, 38, 21, 0, 88, 0,
+  16, 0, 65, 54, 0, 0, 46, 25, 0, 61,
+  0, 19, 5, 30, 0, 0, 0, 0, 0, 0,
+  0, 15, 38, 43, 88, 0, 0, 20, 22, 0,
+  0, 24, 58, 18, 39, 4, 45, 0, 79, 0,
+  1, 0, 0, 0, 30, 0, 26, 161, 0, 0,
+  0, 0, 0, 0, 49, 60, 0, 0, 11, 55,
+  0, 0, 7, 16, 0, 50, 0, 0, 0, 0,
+  0, 35, 21, 0, 0, 13, 0, 0, 0, 55,
+  0, 3, 0, 20, 0, 22, 0, 12, 34, 22,
+  0, 0, 13, 103, 4, 0, 17, 0, 10, 0,
+  46, 0, 0, 0, 0, 0, 54, 0, 0, 2,
+  0, 4, 0, 34, 24, 5, 0, 40, 0, 0,
+  0, 10, 0, 0, 18, 36, 19, 0, 31, 36,
+  38, 0, 0, 22, 13, 0, 4, 0, 0, 0,
+  1, 46, 1, 0, 0, 0, 0, 10, 0, 22,
+  0, 25, 23, 0, 0, 0, 5, 29, 102, 47,
+  32, 3, 54, 0, 0, 0, 37, 15, 0, 14,
+  0, 49, 11, 0, 44, 0, 25, 0, 19, 0,
+  0, 0, 81, 51, 5, 17, 15, 0, 0, 0,
+  3, 0, 0, 60, 21, 63, 0, 0, 0, 12,
+  63, 0, 0, 27, 12, 0, 0, 6, 0, 70,
+  0, 97, 10, 75, 53, 0, 0, 0, 0, 6,
+  0, 65, 94, 0, 0, 3, 21, 23, 4, 21,
+  0, 0, 0, 70, 0, 12, 8, 0, 0, 0,
+  0, 33, 0, 19, 20, 29, 0, 0, 0, 27,
+  44, 20, 19, 0, 78, 0, 29, 0, 66, 38,
+  0, 0, 42, 37, 0, 32, 0, 38, 3, 45,
+  0, 0, 0, 0, 0, 0, 3, 5, 71, 72,
+  88, 0, 0, 7, 31, 0, 0, 31, 64, 18,
+  57, 10, 85, 0, 91, 2, 0, 0, 0, 21,
+  76, 0, 26, 0, 1, 0, 0, 0, 0, 6,
+  28, 78, 0, 20, 4, 29, 21, 10, 35, 34,
+  113, 11, 0, 0, 0, 0, 0, 0, 18, 0,
+  0, 0, 0, 0, 0, 1, 0, 10, 66, 3,
+  0, 101, 57, 6, 0, 0, 0, 0, 0, 90,
+  1, 0, 17, 0, 40, 0, 25, 0, 0, 10,
+  7, 19, 34, 0, 0, 18, 0, 29, 0, 0,
+  0, 43, 3, 0, 0, 28, 0, 0, 37, 0,
+  22, 0, 65, 9, 0, 0, 20, 0, 0, 16,
+  13, 0, 0, 46, 0, 0, 0, 39, 0, 0,
+  0, 0, 1, 0, 0, 4, 0, 7, 72, 14,
+  0, 12, 20, 0, 52, 13, 51, 13, 13, 0,
+  0, 0, 64, 0, 0, 0, 0, 0, 0, 5,
+  19, 184, 0, 0, 0, 0, 0, 0, 30, 14,
+  0, 24, 4, 50, 5, 0, 21, 0, 0, 62,
+  18, 19, 0, 0, 0, 10, 18, 0, 0, 34,
+  0, 4, 0, 24, 0, 24, 0, 55, 0, 16,
+  0, 17, 43, 43, 0, 20, 0, 38, 14, 0,
+  0, 0, 9, 0, 19, 12, 5, 26, 0, 0,
+  6, 0, 0, 22, 22, 0, 30, 56, 37, 1,
+  2, 80, 0, 0, 0, 42, 0, 0, 13, 12,
+  24, 0, 22, 14, 2, 28, 1, 67, 43, 9,
+  35, 30, 0, 0, 7, 25, 0, 0, 0, 0,
+  0, 0, 0, 6, 0, 17, 0, 1, 0, 13,
+  0, 7, 81, 29, 34, 0, 48, 9, 42, 0,
+  38, 19, 0, 0, 0, 34, 49, 0, 25, 0,
+  17, 0, 0, 0, 0, 0, 29, 51, 2, 46,
+  15, 40, 0, 20, 33, 0, 79, 40, 0, 20,
+  0, 0, 0, 0, 25, 0, 0, 0, 0, 0,
+  0, 5, 0, 35, 63, 42, 0, 75, 56, 0,
+  0, 0, 0, 4, 0, 42, 63, 0, 1, 0,
+  44, 5, 9, 0, 0, 3, 0, 23, 0, 0,
+  26, 7, 0, 0, 0, 3, 4, 30, 12, 34,
+  0, 8, 0, 0, 40, 0, 0, 0, 68, 13,
+  0, 0, 40, 12, 0, 29, 32, 0, 0, 30,
+  0, 0, 0, 46, 0, 0, 0, 0, 5, 0,
+  0, 0, 0, 29, 58, 4, 0, 15, 30, 0,
+  26, 17, 54, 0, 15, 0, 9, 0, 76, 5,
+  0, 0, 10, 0, 77, 0, 9, 10, 0, 0,
+  4, 0, 0, 8, 3, 82, 0, 0, 0, 46,
+  42, 0, 45, 68, 136, 0, 0, 0, 0, 0,
+  0, 0, 3, 0, 0, 0, 0, 9, 0, 0,
+  0, 0, 33, 0, 0, 90, 40, 14, 0, 21,
+  0, 0, 0, 136, 0, 0, 74, 0, 41, 0,
+  36, 0, 0, 0, 35, 0, 125, 0, 0, 23,
+  0, 91, 0, 0, 13, 4, 0, 0, 7, 0,
+  0, 0, 15, 0, 23, 0, 45, 6, 0, 0,
+  20, 0, 0, 0, 0, 0, 24, 27, 0, 0,
+  0, 52, 15, 0, 0, 0, 14, 0, 0, 2,
+  0, 0, 69, 4, 0, 37, 12, 0, 118, 0,
+  23, 19, 24, 0, 0, 0, 53, 0, 0, 0,
+  0, 0, 59, 0, 5, 69, 0, 0, 0, 0,
+  0, 19, 45, 76, 0, 0, 0, 17, 2, 8,
+  10, 22, 0, 35, 0, 0, 0, 0, 0, 77,
+  41, 11, 0, 18, 0, 0, 0, 17, 0, 13,
+  0, 0, 0, 39, 0, 0, 0, 0, 0, 0,
+  0, 110, 0, 0, 0, 0, 15, 4, 28, 0,
+  0, 0, 0, 0, 48, 0, 0, 6, 0, 9,
+  0, 40, 17, 0, 0, 0, 0, 0, 53, 0,
+  0, 17, 0, 52, 45, 0, 40, 9, 68, 0,
+  0, 0, 56, 0, 0, 5, 0, 0, 0, 21,
+  0, 0, 0, 0, 1, 53, 0, 16, 7, 45,
+  50, 0, 0, 13, 38, 10, 68, 48, 19, 52,
+  56, 0, 0, 0, 26, 9, 0, 10, 0, 52,
+  52, 0, 44, 0, 21, 0, 7, 0, 0, 3,
+  68, 73, 3, 33, 10, 1, 18, 0, 44, 0,
+  0, 50, 14, 42, 0, 0, 0, 12, 60, 0,
+  0, 39, 0, 0, 0, 7, 0, 62, 39, 63,
+  0, 87, 51, 0, 0, 0, 0, 0, 0, 78,
+  42, 0, 0, 0, 18, 20, 19, 14, 11, 0,
+  3, 81, 0, 28, 0, 0, 0, 0, 0, 30,
+  0, 13, 8, 1, 0, 0, 0, 18, 37, 38,
+  21, 0, 88, 0, 16, 0, 65, 54, 0, 0,
+  46, 25, 0, 61, 0, 19, 5, 30, 0, 0,
+  0, 0, 0, 0, 0, 15, 38, 43, 88, 0,
+  0, 20, 22, 0, 0, 24, 58, 18, 39, 4,
+  45, 0, 79, 0, 1, 0, 0, 16, 100, 0,
+  22, 0, 0, 0, 0, 0, 0, 11, 22, 94,
+  0, 49, 0, 51, 31, 35, 50, 27, 110, 9,
+  0, 0, 0, 0, 0, 0, 32, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 94, 0, 0, 96,
+  51, 18, 0, 0, 0, 0, 0, 79, 0, 0,
+  15, 0, 24, 0, 24, 0, 7, 8, 19, 6,
+  56, 0, 0, 10, 0, 51, 0, 0, 21, 34,
+  0, 0, 0, 16, 0, 0, 24, 0, 36, 0,
+  41, 12, 2, 0, 43, 21, 0, 36, 0, 0,
+  5, 39, 0, 0, 0, 27, 23, 0, 0, 0,
+  0, 0, 0, 11, 0, 6, 79, 9, 0, 5,
+  40, 0, 52, 15, 28, 31, 21, 0, 0, 0,
+  55, 12, 0, 0, 0, 49, 11, 0, 44, 0,
+  25, 0, 19, 0, 0, 0, 81, 51, 5, 17,
+  15, 0, 0, 0, 3, 0, 0, 60, 21, 63,
+  0, 0, 0, 12, 63, 0, 0, 27, 12, 0,
+  0, 6, 0, 70, 0, 97, 10, 75, 53, 0,
+  0, 0, 0, 6, 0, 65, 94, 0, 0, 3,
+  21, 23, 4, 21, 0, 0, 0, 70, 0, 12,
+  8, 0, 0, 0, 0, 33, 0, 19, 20, 29,
+  0, 0, 0, 27, 44, 20, 19, 0, 78, 0,
+  29, 0, 66, 38, 0, 0, 42, 37, 0, 32,
+  0, 38, 3, 45, 0, 0, 0, 0, 0, 0,
+  3, 5, 71, 72, 88, 0, 0, 7, 31, 0,
+  0, 31, 64, 18, 57, 10, 85, 0, 91, 2,
+  0, 0, 0, 21, 76, 0, 26, 0, 1, 0,
+  0, 0, 0, 6, 28, 78, 0, 20, 4, 29,
+  21, 10, 35, 34, 113, 11, 0, 0, 0, 0,
+  0, 0, 18, 0, 0, 0, 0, 0, 0, 1,
+  0, 10, 66, 3, 0, 101, 57, 6, 0, 0,
+  0, 0, 0, 90, 1, 0, 17, 0, 40, 0,
+  25, 0, 0, 10, 7, 19, 34, 0, 0, 18,
+  0, 29, 0, 0, 0, 43, 3, 0, 0, 28,
+  0, 0, 37, 0, 22, 0, 65, 9, 0, 0,
+  20, 0, 0, 16, 13, 0, 0, 46, 0, 0,
+  0, 39, 0, 0, 0, 0, 1, 0, 0, 4,
+  0, 7, 72, 14, 0, 12, 20, 0, 52, 13,
+  51, 13, 13, 0, 0, 0, 64, 0, 0, 0,
+  4, 0, 79, 3, 6, 0, 0, 0, 14, 0,
+  0, 8, 0, 94, 0, 3, 0, 47, 45, 17,
+  53, 54, 102, 0, 0, 0, 0, 16, 0, 0,
+  0, 0, 0, 0, 0, 14, 0, 0, 0, 0,
+  37, 0, 0, 85, 38, 32, 0, 6, 0, 0,
+  0, 126, 0, 0, 66, 0, 24, 0, 20, 0,
+  0, 0, 29, 0, 99, 0, 0, 10, 0, 92,
+  0, 0, 18, 0, 0, 0, 4, 0, 0, 0,
+  11, 0, 20, 0, 18, 0, 0, 0, 39, 0,
+  0, 7, 0, 0, 22, 29, 2, 0, 4, 32,
+  23, 0, 0, 0, 28, 0, 0, 3, 17, 0,
+  84, 3, 0, 15, 21, 0, 112, 0, 10, 16,
+  55, 0, 0, 0, 57, 15, 0, 0, 0, 34,
+  49, 0, 25, 0, 17, 0, 0, 0, 0, 0,
+  29, 51, 2, 46, 15, 40, 0, 20, 33, 0,
+  79, 40, 0, 20, 0, 0, 0, 0, 25, 0,
+  0, 0, 0, 0, 0, 5, 0, 35, 63, 42,
+  0, 75, 56, 0, 0, 0, 0, 4, 0, 42,
+  63, 0, 1, 0, 44, 5, 9, 0, 0, 3,
+  0, 23, 0, 0, 26, 7, 0, 0, 0, 3,
+  4, 30, 12, 34, 0, 8, 0, 0, 40, 0,
+  0, 0, 68, 13, 0, 0, 40, 12, 0, 29,
+  32, 0, 0, 30, 0, 0, 0, 46, 0, 0,
+  0, 0, 5, 0, 0, 0, 0, 29, 58, 4,
+  0, 15, 30, 0, 26, 17, 54, 0, 15, 0,
+  9, 0, 76, 5, 0, 0, 10, 0, 77, 0,
+  9, 10, 0, 0, 4, 0, 0, 8, 3, 82,
+  0, 0, 0, 46, 42, 0, 45, 68, 136, 0,
+  0, 0, 0, 0, 0, 0, 3, 0, 0, 0,
+  0, 9, 0, 0, 0, 0, 33, 0, 0, 90,
+  40, 14, 0, 21, 0, 0, 0, 136, 0, 0,
+  74, 0, 41, 0, 36, 0, 0, 0, 35, 0,
+  125, 0, 0, 23, 0, 91, 0, 0, 13, 4,
+  0, 0, 7, 0, 0, 0, 15, 0, 23, 0,
+  45, 6, 0, 0, 20, 0, 0, 0, 0, 0,
+  24, 27, 0, 0, 0, 52, 15, 0, 0, 0,
+  14, 0, 0, 2, 0, 0, 69, 4, 0, 37,
+  12, 0, 118, 0, 23, 19, 24, 0, 0, 0,
+  53, 0, 0, 0, 0, 0, 45, 1, 17, 0,
+  0, 0, 31, 0, 0, 0, 20, 82, 0, 0,
+  0, 11, 29, 0, 23, 30, 25, 5, 0, 0,
+  20, 43, 0, 53, 0, 0, 0, 0, 0, 0,
+  0, 4, 0, 0, 0, 0, 0, 45, 6, 26,
+  0, 49, 0, 0, 0, 152, 0, 16, 45, 0,
+  12, 0, 0, 0, 0, 0, 8, 0, 63, 0,
+  0, 6, 0, 72, 0, 0, 8, 0, 0, 0,
+  0, 0, 0, 0, 13, 0, 1, 0, 0, 0,
+  0, 44, 53, 0, 44, 0, 0, 0, 18, 0,
+  36, 0, 0, 72, 23, 0, 15, 0, 42, 0,
+  1, 20, 65, 0, 81, 0, 0, 14, 40, 0,
+  141, 0, 0, 33, 89, 0, 30, 0, 58, 0,
+  0, 0, 0, 52, 52, 0, 44, 0, 21, 0,
+  7, 0, 0, 3, 68, 73, 3, 33, 10, 1,
+  18, 0, 44, 0, 0, 50, 14, 42, 0, 0,
+  0, 12, 60, 0, 0, 39, 0, 0, 0, 7,
+  0, 62, 39, 63, 0, 87, 51, 0, 0, 0,
+  0, 0, 0, 78, 42, 0, 0, 0, 18, 20,
+  19, 14, 11, 0, 3, 81, 0, 28, 0, 0,
+  0, 0, 0, 30, 0, 13, 8, 1, 0, 0,
+  0, 18, 37, 38, 21, 0, 88, 0, 16, 0,
+  65, 54, 0, 0, 46, 25, 0, 61, 0, 19,
+  5, 30, 0, 0, 0, 0, 0, 0, 0, 15,
+  38, 43, 88, 0, 0, 20, 22, 0, 0, 24,
+  58, 18, 39, 4, 45, 0, 79, 0, 1, 0,
+  0, 16, 100, 0, 22, 0, 0, 0, 0, 0,
+  0, 11, 22, 94, 0, 49, 0, 51, 31, 35,
+  50, 27, 110, 9, 0, 0, 0, 0, 0, 0,
+  32, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  94, 0, 0, 96, 51, 18, 0, 0, 0, 0,
+  0, 79, 0, 0, 15, 0, 24, 0, 24, 0,
+  7, 8, 19, 6, 56, 0, 0, 10, 0, 51,
+  0, 0, 21, 34, 0, 0, 0, 16, 0, 0,
+  24, 0, 36, 0, 41, 12, 2, 0, 43, 21,
+  0, 36, 0, 0, 5, 39, 0, 0, 0, 27,
+  23, 0, 0, 0, 0, 0, 0, 11, 0, 6,
+  79, 9, 0, 5, 40, 0, 52, 15, 28, 31,
+  21, 0, 0, 0, 55, 12, 0, 0, 20, 0,
+  91, 19, 0, 0, 0, 12, 20, 0, 0, 0,
+  0, 125, 0, 0, 0, 22, 28, 1, 36, 70,
+  81, 11, 0, 0, 7, 35, 205, 0, 23, 21,
+  0, 15, 0, 0, 0, 31, 0, 0, 65, 0,
+  0, 38, 53, 70, 0, 0, 0, 0, 0, 120,
+  0, 6, 74, 0, 21, 12, 39, 0, 24, 17,
+  49, 0, 50, 0, 10, 0, 0, 102, 0, 0,
+  27, 14, 0, 0, 25, 0, 0, 0, 12, 2,
+  2, 20, 0, 0, 0, 33, 96, 33, 0, 2,
+  0, 0, 53, 20, 39, 0, 2, 26, 35, 12,
+  15, 0, 81, 19, 3, 30, 19, 0, 74, 0,
+  14, 0, 19, 31, 105, 0, 0, 54, 0, 0,
+  0, 0, 40, 22, 0, 17, 0, 21, 76, 0,
+  26, 0, 1, 0, 0, 0, 0, 6, 28, 78,
+  0, 20, 4, 29, 21, 10, 35, 34, 113, 11,
+  0, 0, 0, 0, 0, 0, 18, 0, 0, 0,
+  0, 0, 0, 1, 0, 10, 66, 3, 0, 101,
+  57, 6, 0, 0, 0, 0, 0, 90, 1, 0,
+  17, 0, 40, 0, 25, 0, 0, 10, 7, 19,
+  34, 0, 0, 18, 0, 29, 0, 0, 0, 43,
+  3, 0, 0, 28, 0, 0, 37, 0, 22, 0,
+  65, 9, 0, 0, 20, 0, 0, 16, 13, 0,
+  0, 46, 0, 0, 0, 39, 0, 0, 0, 0,
+  1, 0, 0, 4, 0, 7, 72, 14, 0, 12,
+  20, 0, 52, 13, 51, 13, 13, 0, 0, 0,
+  64, 0, 0, 0, 4, 0, 79, 3, 6, 0,
+  0, 0, 14, 0, 0, 8, 0, 94, 0, 3,
+  0, 47, 45, 17, 53, 54, 102, 0, 0, 0,
+  0, 16, 0, 0, 0, 0, 0, 0, 0, 14,
+  0, 0, 0, 0, 37, 0, 0, 85, 38, 32,
+  0, 6, 0, 0, 0, 126, 0, 0, 66, 0,
+  24, 0, 20, 0, 0, 0, 29, 0, 99, 0,
+  0, 10, 0, 92, 0, 0, 18, 0, 0, 0,
+  4, 0, 0, 0, 11, 0, 20, 0, 18, 0,
+  0, 0, 39, 0, 0, 7, 0, 0, 22, 29,
+  2, 0, 4, 32, 23, 0, 0, 0, 28, 0,
+  0, 3, 17, 0, 84, 3, 0, 15, 21, 0,
+  112, 0, 10, 16, 55, 0, 0, 0, 57, 15,
+  0, 0, 2, 0, 42, 31, 0, 0, 14, 24,
+  59, 0, 4, 0, 0, 82, 0, 0, 0, 8,
+  26, 0, 35, 19, 23, 27, 0, 0, 38, 57,
+  187, 16, 19, 10, 32, 0, 0, 0, 0, 25,
+  0, 0, 0, 0, 0, 32, 38, 93, 0, 17,
+  0, 0, 3, 110, 0, 32, 59, 0, 9, 0,
+  14, 0, 0, 22, 8, 0, 4, 0, 20, 0,
+  0, 39, 0, 6, 29, 4, 0, 9, 34, 0,
+  0, 0, 24, 0, 1, 24, 0, 0, 0, 30,
+  103, 45, 40, 0, 0, 0, 18, 12, 59, 0,
+  26, 51, 26, 6, 18, 0, 84, 0, 42, 12,
+  87, 0, 79, 0, 10, 0, 1, 0, 115, 0,
+  0, 34, 41, 0, 5, 0, 59, 9, 0, 24,
+  10, 0, 77, 0, 9, 10, 0, 0, 4, 0,
+  0, 8, 3, 82, 0, 0, 0, 46, 42, 0,
+  45, 68, 136, 0, 0, 0, 0, 0, 0, 0,
+  3, 0, 0, 0, 0, 9, 0, 0, 0, 0,
+  33, 0, 0, 90, 40, 14, 0, 21, 0, 0,
+  0, 136, 0, 0, 74, 0, 41, 0, 36, 0,
+  0, 0, 35, 0, 125, 0, 0, 23, 0, 91,
+  0, 0, 13, 4, 0, 0, 7, 0, 0, 0,
+  15, 0, 23, 0, 45, 6, 0, 0, 20, 0,
+  0, 0, 0, 0, 24, 27, 0, 0, 0, 52,
+  15, 0, 0, 0, 14, 0, 0, 2, 0, 0,
+  69, 4, 0, 37, 12, 0, 118, 0, 23, 19,
+  24, 0, 0, 0, 53, 0, 0, 0, 0, 0,
+  45, 1, 17, 0, 0, 0, 31, 0, 0, 0,
+  20, 82, 0, 0, 0, 11, 29, 0, 23, 30,
+  25, 5, 0, 0, 20, 43, 0, 53, 0, 0,
+  0, 0, 0, 0, 0, 4, 0, 0, 0, 0,
+  0, 45, 6, 26, 0, 49, 0, 0, 0, 152,
+  0, 16, 45, 0, 12, 0, 0, 0, 0, 0,
+  8, 0, 63, 0, 0, 6, 0, 72, 0, 0,
+  8, 0, 0, 0, 0, 0, 0, 0, 13, 0,
+  1, 0, 0, 0, 0, 44, 53, 0, 44, 0,
+  0, 0, 18, 0, 36, 0, 0, 72, 23, 0,
+  15, 0, 42, 0, 1, 20, 65, 0, 81, 0,
+  0, 14, 40, 0, 141, 0, 0, 33, 89, 0,
+  30, 0, 58, 0, 0, 0, 0, 0, 24, 23,
+  0, 0, 18, 24, 50, 29, 0, 0, 0, 30,
+  0, 5, 4, 7, 13, 0, 0, 0, 0, 53,
+  0, 0, 74, 59, 173, 47, 0, 0, 71, 0,
+  19, 0, 0, 20, 0, 24, 0, 0, 0, 0,
+  18, 88, 16, 0, 0, 16, 0, 67, 30, 34,
+  32, 0, 0, 4, 0, 6, 0, 39, 0, 0,
+  0, 0, 33, 0, 0, 14, 6, 12, 56, 3,
+  0, 51, 0, 0, 0, 3, 39, 0, 0, 33,
+  0, 0, 0, 48, 80, 41, 84, 0, 0, 0,
+  23, 0, 51, 0, 2, 59, 14, 2, 58, 0,
+  66, 2, 56, 3, 77, 5, 38, 0, 11, 0,
+  0, 0, 103, 0, 0, 17, 53, 0, 50, 0,
+  60, 0, 7, 11, 0, 16, 100, 0, 22, 0,
+  0, 0, 0, 0, 0, 11, 22, 94, 0, 49,
+  0, 51, 31, 35, 50, 27, 110, 9, 0, 0,
+  0, 0, 0, 0, 32, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 94, 0, 0, 96, 51, 18,
+  0, 0, 0, 0, 0, 79, 0, 0, 15, 0,
+  24, 0, 24, 0, 7, 8, 19, 6, 56, 0,
+  0, 10, 0, 51, 0, 0, 21, 34, 0, 0,
+  0, 16, 0, 0, 24, 0, 36, 0, 41, 12,
+  2, 0, 43, 21, 0, 36, 0, 0, 5, 39,
+  0, 0, 0, 27, 23, 0, 0, 0, 0, 0,
+  0, 11, 0, 6, 79, 9, 0, 5, 40, 0,
+  52, 15, 28, 31, 21, 0, 0, 0, 55, 12,
+  0, 0, 20, 0, 91, 19, 0, 0, 0, 12,
+  20, 0, 0, 0, 0, 125, 0, 0, 0, 22,
+  28, 1, 36, 70, 81, 11, 0, 0, 7, 35,
+  205, 0, 23, 21, 0, 15, 0, 0, 0, 31,
+  0, 0, 65, 0, 0, 38, 53, 70, 0, 0,
+  0, 0, 0, 120, 0, 6, 74, 0, 21, 12,
+  39, 0, 24, 17, 49, 0, 50, 0, 10, 0,
+  0, 102, 0, 0, 27, 14, 0, 0, 25, 0,
+  0, 0, 12, 2, 2, 20, 0, 0, 0, 33,
+  96, 33, 0, 2, 0, 0, 53, 20, 39, 0,
+  2, 26, 35, 12, 15, 0, 81, 19, 3, 30,
+  19, 0, 74, 0, 14, 0, 19, 31, 105, 0,
+  0, 54, 0, 0, 0, 0, 40, 22, 0, 17,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 4, 0,
+  79, 3, 6, 0, 0, 0, 14, 0, 0, 8,
+  0, 94, 0, 3, 0, 47, 45, 17, 53, 54,
+  102, 0, 0, 0, 0, 16, 0, 0, 0, 0,
+  0, 0, 0, 14, 0, 0, 0, 0, 37, 0,
+  0, 85, 38, 32, 0, 6, 0, 0, 0, 126,
+  0, 0, 66, 0, 24, 0, 20, 0, 0, 0,
+  29, 0, 99, 0, 0, 10, 0, 92, 0, 0,
+  18, 0, 0, 0, 4, 0, 0, 0, 11, 0,
+  20, 0, 18, 0, 0, 0, 39, 0, 0, 7,
+  0, 0, 22, 29, 2, 0, 4, 32, 23, 0,
+  0, 0, 28, 0, 0, 3, 17, 0, 84, 3,
+  0, 15, 21, 0, 112, 0, 10, 16, 55, 0,
+  0, 0, 57, 15, 0, 0, 2, 0, 42, 31,
+  0, 0, 14, 24, 59, 0, 4, 0, 0, 82,
+  0, 0, 0, 8, 26, 0, 35, 19, 23, 27,
+  0, 0, 38, 57, 187, 16, 19, 10, 32, 0,
+  0, 0, 0, 25, 0, 0, 0, 0, 0, 32,
+  38, 93, 0, 17, 0, 0, 3, 110, 0, 32,
+  59, 0, 9, 0, 14, 0, 0, 22, 8, 0,
+  4, 0, 20, 0, 0, 39, 0, 6, 29, 4,
+  0, 9, 34, 0, 0, 0, 24, 0, 1, 24,
+  0, 0, 0, 30, 103, 45, 40, 0, 0, 0,
+  18, 12, 59, 0, 26, 51, 26, 6, 18, 0,
+  84, 0, 42, 12, 87, 0, 79, 0, 10, 0,
+  1, 0, 115, 0, 0, 34, 41, 0, 5, 0,
+  59, 9, 0, 24, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 45, 1, 17, 0, 0, 0,
+  31, 0, 0, 0, 20, 82, 0, 0, 0, 11,
+  29, 0, 23, 30, 25, 5, 0, 0, 20, 43,
+  0, 53, 0, 0, 0, 0, 0, 0, 0, 4,
+  0, 0, 0, 0, 0, 45, 6, 26, 0, 49,
+  0, 0, 0, 152, 0, 16, 45, 0, 12, 0,
+  0, 0, 0, 0, 8, 0, 63, 0, 0, 6,
+  0, 72, 0, 0, 8, 0, 0, 0, 0, 0,
+  0, 0, 13, 0, 1, 0, 0, 0, 0, 44,
+  53, 0, 44, 0, 0, 0, 18, 0, 36, 0,
+  0, 72, 23, 0, 15, 0, 42, 0, 1, 20,
+  65, 0, 81, 0, 0, 14, 40, 0, 141, 0,
+  0, 33, 89, 0, 30, 0, 58, 0, 0, 0,
+  0, 0, 24, 23, 0, 0, 18, 24, 50, 29,
+  0, 0, 0, 30, 0, 5, 4, 7, 13, 0,
+  0, 0, 0, 53, 0, 0, 74, 59, 173, 47,
+  0, 0, 71, 0, 19, 0, 0, 20, 0, 24,
+  0, 0, 0, 0, 18, 88, 16, 0, 0, 16,
+  0, 67, 30, 34, 32, 0, 0, 4, 0, 6,
+  0, 39, 0, 0, 0, 0, 33, 0, 0, 14,
+  6, 12, 56, 3, 0, 51, 0, 0, 0, 3,
+  39, 0, 0, 33, 0, 0, 0, 48, 80, 41,
+  84, 0, 0, 0, 23, 0, 51, 0, 2, 59,
+  14, 2, 58, 0, 66, 2, 56, 3, 77, 5,
+  38, 0, 11, 0, 0, 0, 103, 0, 0, 17,
+  53, 0, 50, 0, 60, 0, 7, 11, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 30, 25, 0, 1, 3,
+  33, 18, 0, 0, 0, 0, 0, 38, 0, 18,
+  43, 15, 0, 40, 38, 17, 58, 51, 0, 9,
+  8, 5, 128, 38, 0, 0, 54, 0, 69, 16,
+  0, 30, 0, 38, 21, 38, 0, 22, 60, 37,
+  2, 0, 0, 0, 0, 13, 47, 0, 16, 0,
+  64, 0, 29, 0, 6, 33, 7, 0, 0, 0,
+  7, 19, 25, 0, 0, 36, 79, 26, 45, 46,
+  0, 7, 30, 1, 38, 2, 13, 0, 0, 0,
+  0, 0, 54, 6, 3, 0, 38, 1, 15, 56,
+  0, 0, 37, 35, 9, 0, 0, 19, 20, 19,
+  57, 1, 0, 26, 0, 8, 0, 33, 5, 0,
+  23, 13, 0, 22, 19, 0, 0, 0, 19, 0,
+  11, 9, 0, 48, 13, 14, 0, 0, 29, 34,
+  3, 0, 0, 37, 105, 0, 2, 11, 53, 15,
+  0, 14, 67, 51, 53, 17, 9, 0, 0, 9,
+  0, 0, 0, 0, 96, 0, 32, 9, 0, 24,
+  0, 75, 0, 32, 0, 38, 68, 64, 0, 61,
+  0, 41, 0, 28, 43, 1, 16, 0, 14, 0,
+  11, 0, 0, 0, 0, 18, 0, 0, 0, 0,
+  17, 0, 10, 2, 29, 20, 37, 0, 16, 39,
+  0, 22, 45, 0, 41, 0, 0, 0, 0, 0,
+  0, 7, 0, 0, 0, 7, 0, 48, 0, 0,
+  52, 46, 8, 0, 0, 12, 18, 0, 59, 0,
+  0, 16, 0, 17, 0, 17, 0, 0, 14, 0,
+  6, 8, 40, 0, 40, 0, 76, 0, 11, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 62,
+  32, 0, 2, 1, 44, 3, 0, 0, 16, 4,
+  12, 0, 5, 53, 33, 30, 0, 74, 61, 0,
+  71, 46, 0, 36, 0, 3, 111, 34, 1, 0,
+  57, 0, 53, 22, 0, 16, 0, 48, 40, 30,
+  5, 36, 99, 16, 0, 12, 0, 8, 1, 0,
+  56, 0, 0, 0, 43, 0, 7, 33, 9, 0,
+  16, 0, 0, 0, 18, 21, 0, 0, 8, 32,
+  42, 43, 43, 31, 0, 15, 0, 0, 70, 13,
+  10, 0, 12, 12, 0, 0, 50, 9, 2, 0,
+  16, 0, 5, 73, 0, 0, 8, 21, 2, 0,
+  0, 16, 17, 0, 77, 9, 0, 22, 29, 1,
+  0, 33, 0, 0, 0, 15, 0, 33, 26, 0,
+  0, 0, 28, 0, 14, 0, 5, 45, 49, 8,
+  0, 13, 12, 23, 0, 0, 0, 49, 90, 0,
+  0, 29, 44, 13, 0, 25, 68, 58, 82, 13,
+  0, 0, 0, 11, 0, 0, 0, 0, 81, 0,
+  34, 31, 0, 20, 0, 59, 2, 29, 0, 28,
+  67, 52, 0, 60, 0, 43, 0, 42, 24, 0,
+  22, 0, 17, 0, 7, 0, 0, 0, 0, 9,
+  8, 0, 0, 0, 16, 0, 14, 13, 19, 19,
+  30, 0, 40, 53, 0, 19, 43, 0, 42, 0,
+  0, 11, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 33, 18, 0, 37, 45, 21, 0, 0, 23,
+  29, 0, 60, 0, 0, 7, 11, 13, 0, 17,
+  0, 0, 0, 0, 1, 9, 37, 0, 7, 0,
+  52, 0, 8, 2, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 74, 43, 0, 0, 0, 41, 0,
+  0, 0, 0, 15, 3, 0, 14, 72, 38, 47,
+  0, 64, 66, 0, 81, 51, 0, 26, 10, 14,
+  118, 35, 2, 0, 62, 0, 42, 8, 0, 26,
+  7, 52, 32, 25, 0, 26, 85, 30, 0, 8,
+  0, 25, 0, 13, 61, 0, 0, 0, 25, 0,
+  4, 20, 16, 0, 7, 0, 0, 0, 21, 2,
+  0, 0, 14, 32, 32, 38, 42, 30, 5, 5,
+  0, 0, 76, 3, 4, 0, 0, 15, 0, 0,
+  64, 23, 0, 0, 7, 0, 8, 49, 0, 0,
+  22, 10, 3, 0, 1, 17, 39, 0, 77, 0,
+  0, 43, 30, 0, 0, 41, 0, 0, 0, 3,
+  0, 15, 30, 0, 0, 0, 22, 0, 36, 0,
+  4, 47, 62, 10, 0, 19, 11, 10, 1, 0,
+  0, 51, 73, 0, 0, 33, 47, 24, 0, 20,
+  69, 64, 93, 12, 0, 0, 0, 23, 0, 0,
+  0, 0, 74, 0, 23, 28, 0, 28, 0, 48,
+  1, 24, 0, 19, 53, 57, 0, 57, 0, 37,
+  0, 54, 25, 0, 42, 0, 29, 0, 2, 0,
+  1, 0, 0, 20, 15, 0, 0, 0, 26, 0,
+  13, 15, 11, 22, 32, 0, 46, 51, 0, 12,
+  44, 0, 35, 0, 0, 8, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 24, 31, 0, 40, 41,
+  11, 0, 10, 24, 51, 0, 57, 0, 0, 3,
+  17, 15, 0, 12, 0, 0, 7, 0, 0, 7,
+  15, 4, 0, 0, 47, 0, 18, 0, 0, 30,
+  25, 0, 1, 3, 33, 18, 0, 0, 0, 0,
+  0, 38, 0, 18, 43, 15, 0, 40, 38, 17,
+  58, 51, 0, 9, 8, 5, 128, 38, 0, 0,
+  54, 0, 69, 16, 0, 30, 0, 38, 21, 38,
+  0, 22, 60, 37, 2, 0, 0, 0, 0, 13,
+  47, 0, 16, 0, 64, 0, 29, 0, 6, 33,
+  7, 0, 0, 0, 7, 19, 25, 0, 0, 36,
+  79, 26, 45, 46, 0, 7, 30, 1, 38, 2,
+  13, 0, 0, 0, 0, 0, 54, 6, 3, 0,
+  38, 1, 15, 56, 0, 0, 37, 35, 9, 0,
+  0, 19, 20, 19, 57, 1, 0, 26, 0, 8,
+  0, 33, 5, 0, 23, 13, 0, 22, 19, 0,
+  0, 0, 19, 0, 11, 9, 0, 48, 13, 14,
+  0, 0, 29, 34, 3, 0, 0, 37, 105, 0,
+  2, 11, 53, 15, 0, 14, 67, 51, 53, 17,
+  9, 0, 0, 9, 0, 0, 0, 0, 96, 0,
+  32, 9, 0, 24, 0, 75, 0, 32, 0, 38,
+  68, 64, 0, 61, 0, 41, 0, 28, 43, 1,
+  16, 0, 14, 0, 11, 0, 0, 0, 0, 18,
+  0, 0, 0, 0, 17, 0, 10, 2, 29, 20,
+  37, 0, 16, 39, 0, 22, 45, 0, 41, 0,
+  0, 0, 0, 0, 0, 7, 0, 0, 0, 7,
+  0, 48, 0, 0, 52, 46, 8, 0, 0, 12,
+  18, 0, 59, 0, 0, 16, 0, 17, 0, 17,
+  0, 0, 14, 0, 6, 8, 40, 0, 40, 0,
+  76, 0, 11, 0, 4, 29, 39, 21, 0, 5,
+  28, 2, 19, 0, 0, 34, 112, 0, 22, 39,
+  53, 0, 0, 0, 0, 83, 0, 10, 59, 0,
+  0, 23, 0, 0, 0, 41, 82, 0, 23, 0,
+  0, 23, 0, 78, 0, 55, 37, 22, 36, 48,
+  30, 16, 0, 54, 0, 60, 33, 24, 31, 0,
+  11, 0, 7, 0, 17, 0, 0, 63, 0, 10,
+  7, 0, 36, 0, 8, 20, 0, 4, 0, 0,
+  33, 43, 0, 29, 44, 0, 61, 29, 0, 0,
+  0, 0, 0, 31, 0, 0, 0, 4, 0, 29,
+  42, 0, 5, 76, 2, 0, 8, 14, 30, 0,
+  21, 0, 0, 0, 8, 15, 0, 0, 0, 0,
+  0, 0, 6, 2, 19, 0, 53, 0, 69, 0,
+  17, 0, 0, 62, 32, 0, 2, 1, 44, 3,
+  0, 0, 16, 4, 12, 0, 5, 53, 33, 30,
+  0, 74, 61, 0, 71, 46, 0, 36, 0, 3,
+  111, 34, 1, 0, 57, 0, 53, 22, 0, 16,
+  0, 48, 40, 30, 5, 36, 99, 16, 0, 12,
+  0, 8, 1, 0, 56, 0, 0, 0, 43, 0,
+  7, 33, 9, 0, 16, 0, 0, 0, 18, 21,
+  0, 0, 8, 32, 42, 43, 43, 31, 0, 15,
+  0, 0, 70, 13, 10, 0, 12, 12, 0, 0,
+  50, 9, 2, 0, 16, 0, 5, 73, 0, 0,
+  8, 21, 2, 0, 0, 16, 17, 0, 77, 9,
+  0, 22, 29, 1, 0, 33, 0, 0, 0, 15,
+  0, 33, 26, 0, 0, 0, 28, 0, 14, 0,
+  5, 45, 49, 8, 0, 13, 12, 23, 0, 0,
+  0, 49, 90, 0, 0, 29, 44, 13, 0, 25,
+  68, 58, 82, 13, 0, 0, 0, 11, 0, 0,
+  0, 0, 81, 0, 34, 31, 0, 20, 0, 59,
+  2, 29, 0, 28, 67, 52, 0, 60, 0, 43,
+  0, 42, 24, 0, 22, 0, 17, 0, 7, 0,
+  0, 0, 0, 9, 8, 0, 0, 0, 16, 0,
+  14, 13, 19, 19, 30, 0, 40, 53, 0, 19,
+  43, 0, 42, 0, 0, 11, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 33, 18, 0, 37, 45,
+  21, 0, 0, 23, 29, 0, 60, 0, 0, 7,
+  11, 13, 0, 17, 0, 0, 0, 0, 1, 9,
+  37, 0, 7, 0, 52, 0, 8, 2, 2, 29,
+  35, 14, 0, 2, 25, 15, 25, 0, 0, 41,
+  100, 0, 19, 33, 52, 0, 0, 0, 0, 93,
+  0, 8, 42, 0, 0, 23, 0, 0, 0, 43,
+  78, 0, 33, 0, 0, 18, 0, 68, 0, 56,
+  40, 13, 39, 47, 17, 12, 0, 48, 0, 63,
+  25, 25, 42, 0, 13, 0, 12, 0, 4, 7,
+  0, 68, 0, 15, 1, 0, 32, 0, 7, 15,
+  0, 11, 0, 0, 44, 48, 0, 33, 43, 0,
+  60, 25, 0, 0, 0, 0, 0, 17, 0, 0,
+  0, 3, 0, 32, 43, 0, 2, 82, 3, 0,
+  8, 22, 34, 0, 25, 0, 0, 0, 17, 10,
+  0, 0, 0, 0, 0, 0, 2, 15, 15, 5,
+  38, 0, 55, 0, 13, 0, 0, 74, 43, 0,
+  0, 0, 41, 0, 0, 0, 0, 15, 3, 0,
+  14, 72, 38, 47, 0, 64, 66, 0, 81, 51,
+  0, 26, 10, 14, 118, 35, 2, 0, 62, 0,
+  42, 8, 0, 26, 7, 52, 32, 25, 0, 26,
+  85, 30, 0, 8, 0, 25, 0, 13, 61, 0,
+  0, 0, 25, 0, 4, 20, 16, 0, 7, 0,
+  0, 0, 21, 2, 0, 0, 14, 32, 32, 38,
+  42, 30, 5, 5, 0, 0, 76, 3, 4, 0,
+  0, 15, 0, 0, 64, 23, 0, 0, 7, 0,
+  8, 49, 0, 0, 22, 10, 3, 0, 1, 17,
+  39, 0, 77, 0, 0, 43, 30, 0, 0, 41,
+  0, 0, 0, 3, 0, 15, 30, 0, 0, 0,
+  22, 0, 36, 0, 4, 47, 62, 10, 0, 19,
+  11, 10, 1, 0, 0, 51, 73, 0, 0, 33,
+  47, 24, 0, 20, 69, 64, 93, 12, 0, 0,
+  0, 23, 0, 0, 0, 0, 74, 0, 23, 28,
+  0, 28, 0, 48, 1, 24, 0, 19, 53, 57,
+  0, 57, 0, 37, 0, 54, 25, 0, 42, 0,
+  29, 0, 2, 0, 1, 0, 0, 20, 15, 0,
+  0, 0, 26, 0, 13, 15, 11, 22, 32, 0,
+  46, 51, 0, 12, 44, 0, 35, 0, 0, 8,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 24,
+  31, 0, 40, 41, 11, 0, 10, 24, 51, 0,
+  57, 0, 0, 3, 17, 15, 0, 12, 0, 0,
+  7, 0, 0, 7, 15, 4, 0, 0, 47, 0,
+  18, 0, 3, 30, 27, 20, 0, 12, 23, 23,
+  27, 0, 0, 40, 83, 0, 11, 31, 57, 0,
+  0, 0, 0, 92, 0, 1, 37, 0, 0, 25,
+  0, 0, 0, 50, 77, 0, 34, 0, 0, 19,
+  0, 54, 0, 46, 24, 10, 34, 52, 12, 15,
+  0, 33, 0, 55, 12, 26, 53, 0, 30, 0,
+  10, 0, 0, 13, 0, 58, 0, 13, 0, 0,
+  32, 0, 13, 16, 12, 11, 0, 0, 49, 39,
+  0, 32, 30, 0, 50, 41, 0, 0, 7, 0,
+  0, 13, 0, 0, 0, 16, 0, 30, 52, 0,
+  6, 80, 2, 0, 18, 20, 43, 0, 29, 0,
+  4, 0, 21, 11, 0, 0, 0, 0, 0, 0,
+  0, 11, 4, 11, 36, 0, 51, 0, 18, 0,
+  0, 48, 13, 14, 0, 0, 29, 34, 3, 0,
+  0, 37, 105, 0, 2, 11, 53, 15, 0, 14,
+  67, 51, 53, 17, 9, 0, 0, 9, 0, 0,
+  0, 0, 96, 0, 32, 9, 0, 24, 0, 75,
+  0, 32, 0, 38, 68, 64, 0, 61, 0, 41,
+  0, 28, 43, 1, 16, 0, 14, 0, 11, 0,
+  0, 0, 0, 18, 0, 0, 0, 0, 17, 0,
+  10, 2, 29, 20, 37, 0, 16, 39, 0, 22,
+  45, 0, 41, 0, 0, 0, 0, 0, 0, 7,
+  0, 0, 0, 7, 0, 48, 0, 0, 52, 46,
+  8, 0, 0, 12, 18, 0, 59, 0, 0, 16,
+  0, 17, 0, 17, 0, 0, 14, 0, 6, 8,
+  40, 0, 40, 0, 76, 0, 11, 0, 4, 29,
+  39, 21, 0, 5, 28, 2, 19, 0, 0, 34,
+  112, 0, 22, 39, 53, 0, 0, 0, 0, 83,
+  0, 10, 59, 0, 0, 23, 0, 0, 0, 41,
+  82, 0, 23, 0, 0, 23, 0, 78, 0, 55,
+  37, 22, 36, 48, 30, 16, 0, 54, 0, 60,
+  33, 24, 31, 0, 11, 0, 7, 0, 17, 0,
+  0, 63, 0, 10, 7, 0, 36, 0, 8, 20,
+  0, 4, 0, 0, 33, 43, 0, 29, 44, 0,
+  61, 29, 0, 0, 0, 0, 0, 31, 0, 0,
+  0, 4, 0, 29, 42, 0, 5, 76, 2, 0,
+  8, 14, 30, 0, 21, 0, 0, 0, 8, 15,
+  0, 0, 0, 0, 0, 0, 6, 2, 19, 0,
+  53, 0, 69, 0, 17, 0, 0, 0, 0, 10,
+  0, 139, 4, 0, 12, 0, 0, 18, 33, 0,
+  0, 25, 0, 0, 0, 0, 30, 95, 19, 11,
+  3, 0, 0, 0, 0, 0, 0, 27, 29, 38,
+  0, 0, 0, 23, 0, 54, 0, 22, 0, 53,
+  1, 90, 35, 56, 0, 0, 0, 51, 6, 0,
+  10, 0, 55, 0, 49, 0, 11, 61, 0, 0,
+  76, 3, 0, 3, 55, 0, 82, 11, 11, 0,
+  0, 21, 26, 25, 0, 32, 34, 0, 41, 44,
+  0, 0, 22, 0, 0, 7, 0, 21, 4, 0,
+  4, 31, 0, 0, 7, 66, 36, 0, 0, 23,
+  27, 0, 16, 0, 0, 0, 0, 0, 0, 35,
+  0, 0, 100, 2, 34, 1, 0, 0, 0, 0,
+  28, 0, 0, 0, 5, 45, 49, 8, 0, 13,
+  12, 23, 0, 0, 0, 49, 90, 0, 0, 29,
+  44, 13, 0, 25, 68, 58, 82, 13, 0, 0,
+  0, 11, 0, 0, 0, 0, 81, 0, 34, 31,
+  0, 20, 0, 59, 2, 29, 0, 28, 67, 52,
+  0, 60, 0, 43, 0, 42, 24, 0, 22, 0,
+  17, 0, 7, 0, 0, 0, 0, 9, 8, 0,
+  0, 0, 16, 0, 14, 13, 19, 19, 30, 0,
+  40, 53, 0, 19, 43, 0, 42, 0, 0, 11,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 33,
+  18, 0, 37, 45, 21, 0, 0, 23, 29, 0,
+  60, 0, 0, 7, 11, 13, 0, 17, 0, 0,
+  0, 0, 1, 9, 37, 0, 7, 0, 52, 0,
+  8, 2, 2, 29, 35, 14, 0, 2, 25, 15,
+  25, 0, 0, 41, 100, 0, 19, 33, 52, 0,
+  0, 0, 0, 93, 0, 8, 42, 0, 0, 23,
+  0, 0, 0, 43, 78, 0, 33, 0, 0, 18,
+  0, 68, 0, 56, 40, 13, 39, 47, 17, 12,
+  0, 48, 0, 63, 25, 25, 42, 0, 13, 0,
+  12, 0, 4, 7, 0, 68, 0, 15, 1, 0,
+  32, 0, 7, 15, 0, 11, 0, 0, 44, 48,
+  0, 33, 43, 0, 60, 25, 0, 0, 0, 0,
+  0, 17, 0, 0, 0, 3, 0, 32, 43, 0,
+  2, 82, 3, 0, 8, 22, 34, 0, 25, 0,
+  0, 0, 17, 10, 0, 0, 0, 0, 0, 0,
+  2, 15, 15, 5, 38, 0, 55, 0, 13, 0,
+  0, 0, 0, 2, 0, 130, 10, 0, 4, 0,
+  0, 17, 27, 0, 0, 13, 0, 0, 0, 0,
+  39, 101, 22, 12, 0, 0, 0, 0, 0, 3,
+  0, 24, 35, 28, 1, 0, 0, 22, 0, 43,
+  0, 20, 0, 45, 17, 92, 24, 56, 0, 1,
+  0, 50, 0, 0, 17, 0, 51, 0, 51, 0,
+  0, 57, 0, 0, 72, 8, 0, 8, 34, 0,
+  64, 5, 28, 6, 0, 15, 34, 35, 0, 21,
+  42, 0, 36, 58, 0, 0, 16, 0, 0, 0,
+  0, 14, 4, 0, 0, 35, 0, 0, 0, 63,
+  44, 0, 0, 33, 35, 0, 21, 0, 0, 0,
+  3, 0, 0, 32, 0, 0, 109, 11, 25, 17,
+  0, 0, 0, 0, 15, 0, 0, 0, 4, 47,
+  62, 10, 0, 19, 11, 10, 1, 0, 0, 51,
+  73, 0, 0, 33, 47, 24, 0, 20, 69, 64,
+  93, 12, 0, 0, 0, 23, 0, 0, 0, 0,
+  74, 0, 23, 28, 0, 28, 0, 48, 1, 24,
+  0, 19, 53, 57, 0, 57, 0, 37, 0, 54,
+  25, 0, 42, 0, 29, 0, 2, 0, 1, 0,
+  0, 20, 15, 0, 0, 0, 26, 0, 13, 15,
+  11, 22, 32, 0, 46, 51, 0, 12, 44, 0,
+  35, 0, 0, 8, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 24, 31, 0, 40, 41, 11, 0,
+  10, 24, 51, 0, 57, 0, 0, 3, 17, 15,
+  0, 12, 0, 0, 7, 0, 0, 7, 15, 4,
+  0, 0, 47, 0, 18, 0, 3, 30, 27, 20,
+  0, 12, 23, 23, 27, 0, 0, 40, 83, 0,
+  11, 31, 57, 0, 0, 0, 0, 92, 0, 1,
+  37, 0, 0, 25, 0, 0, 0, 50, 77, 0,
+  34, 0, 0, 19, 0, 54, 0, 46, 24, 10,
+  34, 52, 12, 15, 0, 33, 0, 55, 12, 26,
+  53, 0, 30, 0, 10, 0, 0, 13, 0, 58,
+  0, 13, 0, 0, 32, 0, 13, 16, 12, 11,
+  0, 0, 49, 39, 0, 32, 30, 0, 50, 41,
+  0, 0, 7, 0, 0, 13, 0, 0, 0, 16,
+  0, 30, 52, 0, 6, 80, 2, 0, 18, 20,
+  43, 0, 29, 0, 4, 0, 21, 11, 0, 0,
+  0, 0, 0, 0, 0, 11, 4, 11, 36, 0,
+  51, 0, 18, 0, 0, 0, 0, 5, 0, 140,
+  8, 5, 3, 0, 0, 23, 36, 0, 0, 10,
+  2, 0, 0, 0, 35, 102, 17, 9, 0, 0,
+  0, 0, 0, 21, 0, 23, 35, 21, 4, 1,
+  0, 25, 0, 41, 0, 16, 0, 48, 13, 84,
+  13, 57, 0, 3, 0, 61, 0, 0, 24, 0,
+  45, 0, 39, 0, 0, 51, 0, 0, 78, 3,
+  0, 20, 24, 0, 67, 6, 31, 2, 0, 19,
+  16, 27, 0, 18, 39, 0, 33, 59, 0, 0,
+  10, 0, 0, 0, 0, 8, 0, 0, 12, 34,
+  0, 0, 0, 66, 43, 0, 0, 31, 31, 0,
+  26, 0, 0, 0, 14, 0, 0, 24, 0, 0,
+  117, 2, 21, 20, 0, 0, 0, 0, 24, 0,
+  0, 0, 4, 29, 39, 21, 0, 5, 28, 2,
+  19, 0, 0, 34, 112, 0, 22, 39, 53, 0,
+  0, 0, 0, 83, 0, 10, 59, 0, 0, 23,
+  0, 0, 0, 41, 82, 0, 23, 0, 0, 23,
+  0, 78, 0, 55, 37, 22, 36, 48, 30, 16,
+  0, 54, 0, 60, 33, 24, 31, 0, 11, 0,
+  7, 0, 17, 0, 0, 63, 0, 10, 7, 0,
+  36, 0, 8, 20, 0, 4, 0, 0, 33, 43,
+  0, 29, 44, 0, 61, 29, 0, 0, 0, 0,
+  0, 31, 0, 0, 0, 4, 0, 29, 42, 0,
+  5, 76, 2, 0, 8, 14, 30, 0, 21, 0,
+  0, 0, 8, 15, 0, 0, 0, 0, 0, 0,
+  6, 2, 19, 0, 53, 0, 69, 0, 17, 0,
+  0, 0, 0, 10, 0, 139, 4, 0, 12, 0,
+  0, 18, 33, 0, 0, 25, 0, 0, 0, 0,
+  30, 95, 19, 11, 3, 0, 0, 0, 0, 0,
+  0, 27, 29, 38, 0, 0, 0, 23, 0, 54,
+  0, 22, 0, 53, 1, 90, 35, 56, 0, 0,
+  0, 51, 6, 0, 10, 0, 55, 0, 49, 0,
+  11, 61, 0, 0, 76, 3, 0, 3, 55, 0,
+  82, 11, 11, 0, 0, 21, 26, 25, 0, 32,
+  34, 0, 41, 44, 0, 0, 22, 0, 0, 7,
+  0, 21, 4, 0, 4, 31, 0, 0, 7, 66,
+  36, 0, 0, 23, 27, 0, 16, 0, 0, 0,
+  0, 0, 0, 35, 0, 0, 100, 2, 34, 1,
+  0, 0, 0, 0, 28, 0, 0, 0, 0, 0,
+  0, 0, 9, 38, 29, 0, 28, 0, 15, 0,
+  49, 21, 13, 59, 25, 11, 12, 5, 68, 0,
+  0, 42, 2, 24, 1, 0, 0, 35, 0, 0,
+  51, 61, 4, 0, 0, 0, 0, 42, 8, 38,
+  0, 45, 9, 26, 16, 31, 0, 20, 23, 0,
+  74, 24, 0, 0, 43, 0, 0, 56, 26, 7,
+  0, 0, 0, 0, 26, 8, 30, 0, 0, 7,
+  0, 8, 2, 45, 9, 0, 0, 52, 52, 14,
+  29, 21, 20, 0, 7, 19, 17, 28, 6, 32,
+  0, 6, 20, 41, 0, 0, 30, 59, 7, 0,
+  1, 0, 0, 0, 35, 0, 0, 25, 13, 0,
+  0, 13, 0, 0, 41, 20, 37, 0, 1, 0,
+  90, 0, 36, 0, 0, 0, 2, 29, 35, 14,
+  0, 2, 25, 15, 25, 0, 0, 41, 100, 0,
+  19, 33, 52, 0, 0, 0, 0, 93, 0, 8,
+  42, 0, 0, 23, 0, 0, 0, 43, 78, 0,
+  33, 0, 0, 18, 0, 68, 0, 56, 40, 13,
+  39, 47, 17, 12, 0, 48, 0, 63, 25, 25,
+  42, 0, 13, 0, 12, 0, 4, 7, 0, 68,
+  0, 15, 1, 0, 32, 0, 7, 15, 0, 11,
+  0, 0, 44, 48, 0, 33, 43, 0, 60, 25,
+  0, 0, 0, 0, 0, 17, 0, 0, 0, 3,
+  0, 32, 43, 0, 2, 82, 3, 0, 8, 22,
+  34, 0, 25, 0, 0, 0, 17, 10, 0, 0,
+  0, 0, 0, 0, 2, 15, 15, 5, 38, 0,
+  55, 0, 13, 0, 0, 0, 0, 2, 0, 130,
+  10, 0, 4, 0, 0, 17, 27, 0, 0, 13,
+  0, 0, 0, 0, 39, 101, 22, 12, 0, 0,
+  0, 0, 0, 3, 0, 24, 35, 28, 1, 0,
+  0, 22, 0, 43, 0, 20, 0, 45, 17, 92,
+  24, 56, 0, 1, 0, 50, 0, 0, 17, 0,
+  51, 0, 51, 0, 0, 57, 0, 0, 72, 8,
+  0, 8, 34, 0, 64, 5, 28, 6, 0, 15,
+  34, 35, 0, 21, 42, 0, 36, 58, 0, 0,
+  16, 0, 0, 0, 0, 14, 4, 0, 0, 35,
+  0, 0, 0, 63, 44, 0, 0, 33, 35, 0,
+  21, 0, 0, 0, 3, 0, 0, 32, 0, 0,
+  109, 11, 25, 17, 0, 0, 0, 0, 15, 0,
+  0, 0, 0, 0, 0, 0, 0, 30, 33, 0,
+  19, 0, 21, 0, 43, 0, 16, 54, 29, 19,
+  0, 10, 66, 0, 0, 44, 0, 21, 4, 0,
+  0, 41, 0, 0, 53, 56, 9, 0, 0, 0,
+  0, 18, 0, 34, 0, 47, 24, 21, 4, 29,
+  0, 18, 41, 0, 75, 14, 0, 0, 37, 0,
+  0, 75, 15, 0, 0, 0, 0, 0, 34, 16,
+  0, 0, 0, 2, 0, 21, 12, 35, 14, 9,
+  0, 42, 59, 0, 15, 48, 23, 0, 5, 24,
+  11, 27, 9, 21, 0, 6, 17, 45, 0, 0,
+  9, 43, 26, 0, 0, 0, 17, 0, 51, 8,
+  2, 21, 33, 2, 0, 20, 0, 0, 46, 39,
+  44, 11, 0, 0, 80, 0, 29, 15, 0, 0,
+  3, 30, 27, 20, 0, 12, 23, 23, 27, 0,
+  0, 40, 83, 0, 11, 31, 57, 0, 0, 0,
+  0, 92, 0, 1, 37, 0, 0, 25, 0, 0,
+  0, 50, 77, 0, 34, 0, 0, 19, 0, 54,
+  0, 46, 24, 10, 34, 52, 12, 15, 0, 33,
+  0, 55, 12, 26, 53, 0, 30, 0, 10, 0,
+  0, 13, 0, 58, 0, 13, 0, 0, 32, 0,
+  13, 16, 12, 11, 0, 0, 49, 39, 0, 32,
+  30, 0, 50, 41, 0, 0, 7, 0, 0, 13,
+  0, 0, 0, 16, 0, 30, 52, 0, 6, 80,
+  2, 0, 18, 20, 43, 0, 29, 0, 4, 0,
+  21, 11, 0, 0, 0, 0, 0, 0, 0, 11,
+  4, 11, 36, 0, 51, 0, 18, 0, 0, 0,
+  0, 5, 0, 140, 8, 5, 3, 0, 0, 23,
+  36, 0, 0, 10, 2, 0, 0, 0, 35, 102,
+  17, 9, 0, 0, 0, 0, 0, 21, 0, 23,
+  35, 21, 4, 1, 0, 25, 0, 41, 0, 16,
+  0, 48, 13, 84, 13, 57, 0, 3, 0, 61,
+  0, 0, 24, 0, 45, 0, 39, 0, 0, 51,
+  0, 0, 78, 3, 0, 20, 24, 0, 67, 6,
+  31, 2, 0, 19, 16, 27, 0, 18, 39, 0,
+  33, 59, 0, 0, 10, 0, 0, 0, 0, 8,
+  0, 0, 12, 34, 0, 0, 0, 66, 43, 0,
+  0, 31, 31, 0, 26, 0, 0, 0, 14, 0,
+  0, 24, 0, 0, 117, 2, 21, 20, 0, 0,
+  0, 0, 24, 0, 0, 0, 0, 8, 0, 0,
+  0, 26, 43, 6, 20, 0, 13, 0, 59, 0,
+  10, 62, 36, 31, 3, 0, 46, 0, 0, 38,
+  0, 42, 6, 2, 0, 34, 0, 0, 63, 41,
+  15, 0, 0, 0, 0, 46, 0, 37, 0, 53,
+  25, 14, 17, 17, 0, 32, 15, 5, 91, 14,
+  0, 0, 28, 0, 0, 70, 0, 0, 0, 0,
+  0, 0, 24, 8, 0, 0, 0, 2, 0, 9,
+  17, 48, 0, 3, 0, 31, 71, 5, 13, 36,
+  17, 0, 4, 23, 26, 35, 36, 0, 0, 2,
+  17, 32, 0, 0, 2, 44, 36, 0, 0, 0,
+  12, 0, 55, 13, 24, 46, 43, 0, 0, 24,
+  0, 0, 42, 41, 44, 0, 0, 0, 108, 0,
+  71, 14, 0, 0, 0, 0, 0, 10, 0, 139,
+  4, 0, 12, 0, 0, 18, 33, 0, 0, 25,
+  0, 0, 0, 0, 30, 95, 19, 11, 3, 0,
+  0, 0, 0, 0, 0, 27, 29, 38, 0, 0,
+  0, 23, 0, 54, 0, 22, 0, 53, 1, 90,
+  35, 56, 0, 0, 0, 51, 6, 0, 10, 0,
+  55, 0, 49, 0, 11, 61, 0, 0, 76, 3,
+  0, 3, 55, 0, 82, 11, 11, 0, 0, 21,
+  26, 25, 0, 32, 34, 0, 41, 44, 0, 0,
+  22, 0, 0, 7, 0, 21, 4, 0, 4, 31,
+  0, 0, 7, 66, 36, 0, 0, 23, 27, 0,
+  16, 0, 0, 0, 0, 0, 0, 35, 0, 0,
+  100, 2, 34, 1, 0, 0, 0, 0, 28, 0,
+  0, 0, 0, 0, 0, 0, 9, 38, 29, 0,
+  28, 0, 15, 0, 49, 21, 13, 59, 25, 11,
+  12, 5, 68, 0, 0, 42, 2, 24, 1, 0,
+  0, 35, 0, 0, 51, 61, 4, 0, 0, 0,
+  0, 42, 8, 38, 0, 45, 9, 26, 16, 31,
+  0, 20, 23, 0, 74, 24, 0, 0, 43, 0,
+  0, 56, 26, 7, 0, 0, 0, 0, 26, 8,
+  30, 0, 0, 7, 0, 8, 2, 45, 9, 0,
+  0, 52, 52, 14, 29, 21, 20, 0, 7, 19,
+  17, 28, 6, 32, 0, 6, 20, 41, 0, 0,
+  30, 59, 7, 0, 1, 0, 0, 0, 35, 0,
+  0, 25, 13, 0, 0, 13, 0, 0, 41, 20,
+  37, 0, 1, 0, 90, 0, 36, 0, 0, 0,
+  0, 41, 38, 0, 0, 0, 0, 0, 61, 6,
+  0, 16, 12, 19, 25, 54, 49, 37, 21, 5,
+  43, 0, 53, 32, 0, 0, 35, 21, 0, 0,
+  0, 0, 32, 0, 3, 0, 0, 0, 0, 35,
+  0, 0, 0, 27, 0, 26, 0, 0, 0, 15,
+  28, 3, 38, 9, 0, 0, 27, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 56, 0, 5, 0,
+  0, 0, 1, 44, 11, 11, 0, 62, 0, 23,
+  13, 12, 56, 44, 1, 24, 0, 29, 27, 31,
+  52, 10, 0, 0, 12, 0, 0, 0, 11, 51,
+  42, 0, 0, 0, 0, 0, 41, 0, 0, 48,
+  5, 0, 0, 10, 0, 0, 7, 0, 0, 0,
+  0, 0, 47, 0, 21, 0, 1, 20, 0, 0,
+  0, 2, 0, 130, 10, 0, 4, 0, 0, 17,
+  27, 0, 0, 13, 0, 0, 0, 0, 39, 101,
+  22, 12, 0, 0, 0, 0, 0, 3, 0, 24,
+  35, 28, 1, 0, 0, 22, 0, 43, 0, 20,
+  0, 45, 17, 92, 24, 56, 0, 1, 0, 50,
+  0, 0, 17, 0, 51, 0, 51, 0, 0, 57,
+  0, 0, 72, 8, 0, 8, 34, 0, 64, 5,
+  28, 6, 0, 15, 34, 35, 0, 21, 42, 0,
+  36, 58, 0, 0, 16, 0, 0, 0, 0, 14,
+  4, 0, 0, 35, 0, 0, 0, 63, 44, 0,
+  0, 33, 35, 0, 21, 0, 0, 0, 3, 0,
+  0, 32, 0, 0, 109, 11, 25, 17, 0, 0,
+  0, 0, 15, 0, 0, 0, 0, 0, 0, 0,
+  0, 30, 33, 0, 19, 0, 21, 0, 43, 0,
+  16, 54, 29, 19, 0, 10, 66, 0, 0, 44,
+  0, 21, 4, 0, 0, 41, 0, 0, 53, 56,
+  9, 0, 0, 0, 0, 18, 0, 34, 0, 47,
+  24, 21, 4, 29, 0, 18, 41, 0, 75, 14,
+  0, 0, 37, 0, 0, 75, 15, 0, 0, 0,
+  0, 0, 34, 16, 0, 0, 0, 2, 0, 21,
+  12, 35, 14, 9, 0, 42, 59, 0, 15, 48,
+  23, 0, 5, 24, 11, 27, 9, 21, 0, 6,
+  17, 45, 0, 0, 9, 43, 26, 0, 0, 0,
+  17, 0, 51, 8, 2, 21, 33, 2, 0, 20,
+  0, 0, 46, 39, 44, 11, 0, 0, 80, 0,
+  29, 15, 0, 0, 0, 47, 63, 0, 0, 0,
+  0, 0, 44, 1, 0, 11, 10, 3, 0, 58,
+  41, 16, 11, 0, 10, 0, 65, 40, 0, 0,
+  36, 16, 0, 0, 0, 0, 20, 0, 20, 14,
+  0, 0, 0, 16, 0, 3, 0, 22, 0, 2,
+  0, 0, 0, 1, 57, 3, 31, 0, 0, 0,
+  29, 0, 0, 14, 3, 0, 0, 0, 16, 0,
+  39, 2, 0, 0, 0, 0, 0, 49, 17, 0,
+  0, 86, 0, 30, 13, 0, 52, 56, 3, 30,
+  0, 29, 23, 24, 50, 0, 0, 0, 17, 0,
+  0, 0, 0, 53, 48, 0, 0, 0, 13, 0,
+  61, 0, 0, 31, 25, 0, 0, 5, 0, 0,
+  7, 0, 0, 16, 0, 0, 30, 0, 18, 13,
+  0, 31, 0, 0, 0, 5, 0, 140, 8, 5,
+  3, 0, 0, 23, 36, 0, 0, 10, 2, 0,
+  0, 0, 35, 102, 17, 9, 0, 0, 0, 0,
+  0, 21, 0, 23, 35, 21, 4, 1, 0, 25,
+  0, 41, 0, 16, 0, 48, 13, 84, 13, 57,
+  0, 3, 0, 61, 0, 0, 24, 0, 45, 0,
+  39, 0, 0, 51, 0, 0, 78, 3, 0, 20,
+  24, 0, 67, 6, 31, 2, 0, 19, 16, 27,
+  0, 18, 39, 0, 33, 59, 0, 0, 10, 0,
+  0, 0, 0, 8, 0, 0, 12, 34, 0, 0,
+  0, 66, 43, 0, 0, 31, 31, 0, 26, 0,
+  0, 0, 14, 0, 0, 24, 0, 0, 117, 2,
+  21, 20, 0, 0, 0, 0, 24, 0, 0, 0,
+  0, 8, 0, 0, 0, 26, 43, 6, 20, 0,
+  13, 0, 59, 0, 10, 62, 36, 31, 3, 0,
+  46, 0, 0, 38, 0, 42, 6, 2, 0, 34,
+  0, 0, 63, 41, 15, 0, 0, 0, 0, 46,
+  0, 37, 0, 53, 25, 14, 17, 17, 0, 32,
+  15, 5, 91, 14, 0, 0, 28, 0, 0, 70,
+  0, 0, 0, 0, 0, 0, 24, 8, 0, 0,
+  0, 2, 0, 9, 17, 48, 0, 3, 0, 31,
+  71, 5, 13, 36, 17, 0, 4, 23, 26, 35,
+  36, 0, 0, 2, 17, 32, 0, 0, 2, 44,
+  36, 0, 0, 0, 12, 0, 55, 13, 24, 46,
+  43, 0, 0, 24, 0, 0, 42, 41, 44, 0,
+  0, 0, 108, 0, 71, 14, 0, 0, 0, 44,
+  70, 0, 0, 0, 0, 9, 53, 0, 0, 29,
+  11, 20, 0, 36, 26, 0, 0, 0, 0, 7,
+  73, 51, 0, 0, 16, 18, 0, 0, 0, 0,
+  0, 0, 29, 22, 0, 0, 0, 40, 0, 13,
+  0, 10, 0, 1, 22, 0, 0, 0, 35, 32,
+  22, 15, 0, 0, 28, 0, 0, 0, 0, 0,
+  0, 0, 20, 0, 30, 0, 2, 0, 0, 8,
+  3, 20, 33, 0, 0, 85, 0, 28, 19, 0,
+  42, 48, 0, 18, 0, 36, 33, 9, 46, 0,
+  0, 0, 8, 0, 0, 0, 0, 81, 37, 0,
+  0, 0, 25, 0, 70, 0, 22, 26, 14, 0,
+  0, 8, 0, 0, 28, 0, 0, 18, 0, 0,
+  19, 0, 44, 20, 0, 20, 0, 0, 0, 0,
+  9, 38, 29, 0, 28, 0, 15, 0, 49, 21,
+  13, 59, 25, 11, 12, 5, 68, 0, 0, 42,
+  2, 24, 1, 0, 0, 35, 0, 0, 51, 61,
+  4, 0, 0, 0, 0, 42, 8, 38, 0, 45,
+  9, 26, 16, 31, 0, 20, 23, 0, 74, 24,
+  0, 0, 43, 0, 0, 56, 26, 7, 0, 0,
+  0, 0, 26, 8, 30, 0, 0, 7, 0, 8,
+  2, 45, 9, 0, 0, 52, 52, 14, 29, 21,
+  20, 0, 7, 19, 17, 28, 6, 32, 0, 6,
+  20, 41, 0, 0, 30, 59, 7, 0, 1, 0,
+  0, 0, 35, 0, 0, 25, 13, 0, 0, 13,
+  0, 0, 41, 20, 37, 0, 1, 0, 90, 0,
+  36, 0, 0, 0, 0, 41, 38, 0, 0, 0,
+  0, 0, 61, 6, 0, 16, 12, 19, 25, 54,
+  49, 37, 21, 5, 43, 0, 53, 32, 0, 0,
+  35, 21, 0, 0, 0, 0, 32, 0, 3, 0,
+  0, 0, 0, 35, 0, 0, 0, 27, 0, 26,
+  0, 0, 0, 15, 28, 3, 38, 9, 0, 0,
+  27, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  56, 0, 5, 0, 0, 0, 1, 44, 11, 11,
+  0, 62, 0, 23, 13, 12, 56, 44, 1, 24,
+  0, 29, 27, 31, 52, 10, 0, 0, 12, 0,
+  0, 0, 11, 51, 42, 0, 0, 0, 0, 0,
+  41, 0, 0, 48, 5, 0, 0, 10, 0, 0,
+  7, 0, 0, 0, 0, 0, 47, 0, 21, 0,
+  1, 20, 52, 0, 43, 0, 22, 0, 0, 0,
+  29, 0, 0, 0, 38, 88, 0, 0, 38, 0,
+  13, 0, 33, 104, 68, 26, 0, 0, 8, 50,
+  0, 0, 0, 10, 0, 4, 0, 0, 0, 20,
+  0, 11, 1, 0, 0, 0, 0, 16, 0, 0,
+  0, 7, 0, 77, 0, 0, 52, 0, 26, 23,
+  6, 0, 25, 0, 0, 6, 24, 0, 92, 16,
+  18, 73, 0, 0, 0, 73, 0, 0, 0, 50,
+  0, 0, 0, 0, 11, 59, 10, 49, 0, 55,
+  10, 0, 0, 37, 0, 0, 5, 0, 13, 0,
+  23, 61, 29, 7, 1, 0, 19, 2, 0, 26,
+  0, 53, 0, 7, 0, 0, 0, 23, 69, 0,
+  1, 0, 0, 31, 0, 0, 4, 0, 0, 61,
+  0, 0, 0, 0, 0, 30, 33, 0, 19, 0,
+  21, 0, 43, 0, 16, 54, 29, 19, 0, 10,
+  66, 0, 0, 44, 0, 21, 4, 0, 0, 41,
+  0, 0, 53, 56, 9, 0, 0, 0, 0, 18,
+  0, 34, 0, 47, 24, 21, 4, 29, 0, 18,
+  41, 0, 75, 14, 0, 0, 37, 0, 0, 75,
+  15, 0, 0, 0, 0, 0, 34, 16, 0, 0,
+  0, 2, 0, 21, 12, 35, 14, 9, 0, 42,
+  59, 0, 15, 48, 23, 0, 5, 24, 11, 27,
+  9, 21, 0, 6, 17, 45, 0, 0, 9, 43,
+  26, 0, 0, 0, 17, 0, 51, 8, 2, 21,
+  33, 2, 0, 20, 0, 0, 46, 39, 44, 11,
+  0, 0, 80, 0, 29, 15, 0, 0, 0, 47,
+  63, 0, 0, 0, 0, 0, 44, 1, 0, 11,
+  10, 3, 0, 58, 41, 16, 11, 0, 10, 0,
+  65, 40, 0, 0, 36, 16, 0, 0, 0, 0,
+  20, 0, 20, 14, 0, 0, 0, 16, 0, 3,
+  0, 22, 0, 2, 0, 0, 0, 1, 57, 3,
+  31, 0, 0, 0, 29, 0, 0, 14, 3, 0,
+  0, 0, 16, 0, 39, 2, 0, 0, 0, 0,
+  0, 49, 17, 0, 0, 86, 0, 30, 13, 0,
+  52, 56, 3, 30, 0, 29, 23, 24, 50, 0,
+  0, 0, 17, 0, 0, 0, 0, 53, 48, 0,
+  0, 0, 13, 0, 61, 0, 0, 31, 25, 0,
+  0, 5, 0, 0, 7, 0, 0, 16, 0, 0,
+  30, 0, 18, 13, 0, 31, 103, 0, 37, 5,
+  6, 15, 0, 0, 15, 0, 0, 23, 47, 54,
+  0, 0, 22, 0, 6, 0, 0, 173, 80, 13,
+  0, 0, 0, 33, 0, 0, 2, 56, 0, 34,
+  0, 21, 0, 29, 0, 25, 0, 22, 0, 0,
+  27, 6, 10, 8, 0, 0, 0, 77, 0, 0,
+  89, 0, 43, 20, 45, 0, 35, 11, 0, 32,
+  30, 49, 7, 15, 23, 23, 7, 28, 0, 22,
+  0, 0, 3, 45, 0, 13, 0, 0, 4, 42,
+  8, 27, 0, 9, 0, 0, 0, 0, 8, 0,
+  7, 0, 24, 0, 27, 61, 2, 0, 25, 0,
+  40, 28, 4, 8, 10, 35, 4, 0, 0, 0,
+  0, 15, 78, 0, 23, 10, 0, 35, 0, 0,
+  20, 3, 3, 48, 0, 8, 0, 0, 0, 26,
+  43, 6, 20, 0, 13, 0, 59, 0, 10, 62,
+  36, 31, 3, 0, 46, 0, 0, 38, 0, 42,
+  6, 2, 0, 34, 0, 0, 63, 41, 15, 0,
+  0, 0, 0, 46, 0, 37, 0, 53, 25, 14,
+  17, 17, 0, 32, 15, 5, 91, 14, 0, 0,
+  28, 0, 0, 70, 0, 0, 0, 0, 0, 0,
+  24, 8, 0, 0, 0, 2, 0, 9, 17, 48,
+  0, 3, 0, 31, 71, 5, 13, 36, 17, 0,
+  4, 23, 26, 35, 36, 0, 0, 2, 17, 32,
+  0, 0, 2, 44, 36, 0, 0, 0, 12, 0,
+  55, 13, 24, 46, 43, 0, 0, 24, 0, 0,
+  42, 41, 44, 0, 0, 0, 108, 0, 71, 14,
+  0, 0, 0, 44, 70, 0, 0, 0, 0, 9,
+  53, 0, 0, 29, 11, 20, 0, 36, 26, 0,
+  0, 0, 0, 7, 73, 51, 0, 0, 16, 18,
+  0, 0, 0, 0, 0, 0, 29, 22, 0, 0,
+  0, 40, 0, 13, 0, 10, 0, 1, 22, 0,
+  0, 0, 35, 32, 22, 15, 0, 0, 28, 0,
+  0, 0, 0, 0, 0, 0, 20, 0, 30, 0,
+  2, 0, 0, 8, 3, 20, 33, 0, 0, 85,
+  0, 28, 19, 0, 42, 48, 0, 18, 0, 36,
+  33, 9, 46, 0, 0, 0, 8, 0, 0, 0,
+  0, 81, 37, 0, 0, 0, 25, 0, 70, 0,
+  22, 26, 14, 0, 0, 8, 0, 0, 28, 0,
+  0, 18, 0, 0, 19, 0, 44, 20, 0, 20,
+  102, 0, 40, 4, 0, 12, 0, 0, 45, 0,
+  0, 35, 56, 20, 0, 0, 9, 0, 0, 0,
+  0, 189, 80, 25, 0, 0, 0, 31, 0, 0,
+  16, 61, 0, 11, 0, 30, 0, 40, 0, 30,
+  0, 28, 48, 0, 38, 21, 24, 29, 0, 0,
+  0, 80, 0, 0, 100, 0, 63, 0, 47, 0,
+  14, 23, 0, 56, 27, 66, 0, 1, 0, 4,
+  12, 26, 10, 13, 0, 0, 0, 47, 0, 15,
+  0, 0, 7, 21, 0, 11, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 25, 0, 18, 61,
+  0, 0, 17, 0, 54, 23, 26, 12, 6, 14,
+  8, 6, 0, 0, 0, 2, 87, 0, 36, 39,
+  0, 9, 0, 0, 23, 15, 18, 29, 0, 41,
+  38, 0, 0, 0, 0, 0, 61, 6, 0, 16,
+  12, 19, 25, 54, 49, 37, 21, 5, 43, 0,
+  53, 32, 0, 0, 35, 21, 0, 0, 0, 0,
+  32, 0, 3, 0, 0, 0, 0, 35, 0, 0,
+  0, 27, 0, 26, 0, 0, 0, 15, 28, 3,
+  38, 9, 0, 0, 27, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 56, 0, 5, 0, 0, 0,
+  1, 44, 11, 11, 0, 62, 0, 23, 13, 12,
+  56, 44, 1, 24, 0, 29, 27, 31, 52, 10,
+  0, 0, 12, 0, 0, 0, 11, 51, 42, 0,
+  0, 0, 0, 0, 41, 0, 0, 48, 5, 0,
+  0, 10, 0, 0, 7, 0, 0, 0, 0, 0,
+  47, 0, 21, 0, 1, 20, 52, 0, 43, 0,
+  22, 0, 0, 0, 29, 0, 0, 0, 38, 88,
+  0, 0, 38, 0, 13, 0, 33, 104, 68, 26,
+  0, 0, 8, 50, 0, 0, 0, 10, 0, 4,
+  0, 0, 0, 20, 0, 11, 1, 0, 0, 0,
+  0, 16, 0, 0, 0, 7, 0, 77, 0, 0,
+  52, 0, 26, 23, 6, 0, 25, 0, 0, 6,
+  24, 0, 92, 16, 18, 73, 0, 0, 0, 73,
+  0, 0, 0, 50, 0, 0, 0, 0, 11, 59,
+  10, 49, 0, 55, 10, 0, 0, 37, 0, 0,
+  5, 0, 13, 0, 23, 61, 29, 7, 1, 0,
+  19, 2, 0, 26, 0, 53, 0, 7, 0, 0,
+  0, 23, 69, 0, 1, 0, 0, 31, 0, 0,
+  4, 0, 0, 61, 44, 0, 0, 0, 25, 73,
+  0, 0, 7, 0, 0, 0, 26, 81, 0, 0,
+  48, 0, 0, 0, 40, 70, 0, 48, 0, 0,
+  0, 16, 0, 0, 0, 0, 0, 39, 0, 0,
+  0, 36, 0, 27, 0, 6, 0, 0, 20, 1,
+  0, 24, 22, 0, 0, 39, 0, 0, 0, 0,
+  10, 25, 0, 0, 31, 12, 0, 4, 0, 0,
+  87, 23, 22, 30, 0, 6, 0, 43, 7, 0,
+  0, 5, 0, 16, 0, 0, 0, 7, 9, 33,
+  0, 49, 1, 0, 0, 56, 0, 0, 0, 0,
+  0, 0, 17, 64, 6, 22, 16, 0, 10, 13,
+  0, 13, 8, 65, 0, 0, 0, 0, 0, 16,
+  82, 0, 8, 0, 12, 7, 0, 0, 0, 7,
+  4, 20, 0, 47, 63, 0, 0, 0, 0, 0,
+  44, 1, 0, 11, 10, 3, 0, 58, 41, 16,
+  11, 0, 10, 0, 65, 40, 0, 0, 36, 16,
+  0, 0, 0, 0, 20, 0, 20, 14, 0, 0,
+  0, 16, 0, 3, 0, 22, 0, 2, 0, 0,
+  0, 1, 57, 3, 31, 0, 0, 0, 29, 0,
+  0, 14, 3, 0, 0, 0, 16, 0, 39, 2,
+  0, 0, 0, 0, 0, 49, 17, 0, 0, 86,
+  0, 30, 13, 0, 52, 56, 3, 30, 0, 29,
+  23, 24, 50, 0, 0, 0, 17, 0, 0, 0,
+  0, 53, 48, 0, 0, 0, 13, 0, 61, 0,
+  0, 31, 25, 0, 0, 5, 0, 0, 7, 0,
+  0, 16, 0, 0, 30, 0, 18, 13, 0, 31,
+  103, 0, 37, 5, 6, 15, 0, 0, 15, 0,
+  0, 23, 47, 54, 0, 0, 22, 0, 6, 0,
+  0, 173, 80, 13, 0, 0, 0, 33, 0, 0,
+  2, 56, 0, 34, 0, 21, 0, 29, 0, 25,
+  0, 22, 0, 0, 27, 6, 10, 8, 0, 0,
+  0, 77, 0, 0, 89, 0, 43, 20, 45, 0,
+  35, 11, 0, 32, 30, 49, 7, 15, 23, 23,
+  7, 28, 0, 22, 0, 0, 3, 45, 0, 13,
+  0, 0, 4, 42, 8, 27, 0, 9, 0, 0,
+  0, 0, 8, 0, 7, 0, 24, 0, 27, 61,
+  2, 0, 25, 0, 40, 28, 4, 8, 10, 35,
+  4, 0, 0, 0, 0, 15, 78, 0, 23, 10,
+  0, 35, 0, 0, 20, 3, 3, 48, 45, 0,
+  0, 0, 22, 82, 0, 0, 8, 0, 0, 0,
+  29, 61, 0, 8, 48, 0, 0, 0, 21, 71,
+  5, 41, 10, 3, 0, 14, 0, 2, 0, 9,
+  0, 69, 34, 19, 0, 41, 0, 34, 7, 20,
+  0, 34, 59, 23, 26, 10, 5, 0, 0, 0,
+  0, 0, 0, 0, 18, 22, 10, 15, 30, 39,
+  10, 0, 0, 0, 16, 36, 52, 0, 27, 32,
+  3, 0, 12, 28, 0, 21, 0, 48, 0, 2,
+  0, 34, 13, 5, 17, 11, 0, 25, 0, 47,
+  10, 1, 26, 5, 0, 0, 0, 67, 13, 0,
+  12, 0, 16, 0, 0, 15, 0, 51, 0, 0,
+  0, 0, 0, 0, 69, 0, 19, 0, 19, 11,
+  0, 0, 29, 2, 31, 0, 0, 44, 70, 0,
+  0, 0, 0, 9, 53, 0, 0, 29, 11, 20,
+  0, 36, 26, 0, 0, 0, 0, 7, 73, 51,
+  0, 0, 16, 18, 0, 0, 0, 0, 0, 0,
+  29, 22, 0, 0, 0, 40, 0, 13, 0, 10,
+  0, 1, 22, 0, 0, 0, 35, 32, 22, 15,
+  0, 0, 28, 0, 0, 0, 0, 0, 0, 0,
+  20, 0, 30, 0, 2, 0, 0, 8, 3, 20,
+  33, 0, 0, 85, 0, 28, 19, 0, 42, 48,
+  0, 18, 0, 36, 33, 9, 46, 0, 0, 0,
+  8, 0, 0, 0, 0, 81, 37, 0, 0, 0,
+  25, 0, 70, 0, 22, 26, 14, 0, 0, 8,
+  0, 0, 28, 0, 0, 18, 0, 0, 19, 0,
+  44, 20, 0, 20, 102, 0, 40, 4, 0, 12,
+  0, 0, 45, 0, 0, 35, 56, 20, 0, 0,
+  9, 0, 0, 0, 0, 189, 80, 25, 0, 0,
+  0, 31, 0, 0, 16, 61, 0, 11, 0, 30,
+  0, 40, 0, 30, 0, 28, 48, 0, 38, 21,
+  24, 29, 0, 0, 0, 80, 0, 0, 100, 0,
+  63, 0, 47, 0, 14, 23, 0, 56, 27, 66,
+  0, 1, 0, 4, 12, 26, 10, 13, 0, 0,
+  0, 47, 0, 15, 0, 0, 7, 21, 0, 11,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  25, 0, 18, 61, 0, 0, 17, 0, 54, 23,
+  26, 12, 6, 14, 8, 6, 0, 0, 0, 2,
+  87, 0, 36, 39, 0, 9, 0, 0, 23, 15,
+  18, 29, 9, 0, 0, 9, 0, 65, 0, 0,
+  41, 0, 0, 0, 45, 38, 0, 38, 32, 25,
+  0, 0, 8, 14, 5, 56, 28, 0, 0, 19,
+  0, 0, 0, 21, 10, 40, 27, 4, 0, 33,
+  0, 8, 9, 4, 50, 58, 50, 77, 14, 17,
+  0, 0, 0, 0, 0, 0, 0, 0, 54, 0,
+  0, 0, 4, 43, 0, 0, 0, 0, 0, 0,
+  12, 0, 54, 0, 14, 11, 0, 28, 0, 28,
+  0, 28, 0, 16, 0, 39, 0, 0, 31, 0,
+  14, 62, 0, 63, 0, 0, 13, 17, 0, 0,
+  0, 56, 19, 0, 0, 0, 17, 0, 0, 4,
+  0, 40, 0, 0, 0, 9, 0, 0, 61, 0,
+  8, 0, 37, 0, 3, 0, 29, 10, 44, 0,
+  52, 0, 43, 0, 22, 0, 0, 0, 29, 0,
+  0, 0, 38, 88, 0, 0, 38, 0, 13, 0,
+  33, 104, 68, 26, 0, 0, 8, 50, 0, 0,
+  0, 10, 0, 4, 0, 0, 0, 20, 0, 11,
+  1, 0, 0, 0, 0, 16, 0, 0, 0, 7,
+  0, 77, 0, 0, 52, 0, 26, 23, 6, 0,
+  25, 0, 0, 6, 24, 0, 92, 16, 18, 73,
+  0, 0, 0, 73, 0, 0, 0, 50, 0, 0,
+  0, 0, 11, 59, 10, 49, 0, 55, 10, 0,
+  0, 37, 0, 0, 5, 0, 13, 0, 23, 61,
+  29, 7, 1, 0, 19, 2, 0, 26, 0, 53,
+  0, 7, 0, 0, 0, 23, 69, 0, 1, 0,
+  0, 31, 0, 0, 4, 0, 0, 61, 44, 0,
+  0, 0, 25, 73, 0, 0, 7, 0, 0, 0,
+  26, 81, 0, 0, 48, 0, 0, 0, 40, 70,
+  0, 48, 0, 0, 0, 16, 0, 0, 0, 0,
+  0, 39, 0, 0, 0, 36, 0, 27, 0, 6,
+  0, 0, 20, 1, 0, 24, 22, 0, 0, 39,
+  0, 0, 0, 0, 10, 25, 0, 0, 31, 12,
+  0, 4, 0, 0, 87, 23, 22, 30, 0, 6,
+  0, 43, 7, 0, 0, 5, 0, 16, 0, 0,
+  0, 7, 9, 33, 0, 49, 1, 0, 0, 56,
+  0, 0, 0, 0, 0, 0, 17, 64, 6, 22,
+  16, 0, 10, 13, 0, 13, 8, 65, 0, 0,
+  0, 0, 0, 16, 82, 0, 8, 0, 12, 7,
+  0, 0, 0, 7, 4, 20, 0, 17, 0, 0,
+  21, 28, 30, 14, 58, 16, 0, 5, 32, 30,
+  51, 35, 42, 53, 0, 21, 81, 0, 0, 49,
+  7, 50, 21, 0, 0, 19, 0, 0, 2, 16,
+  18, 0, 0, 7, 0, 43, 0, 40, 0, 33,
+  27, 19, 0, 12, 0, 0, 23, 0, 84, 2,
+  0, 0, 0, 0, 0, 29, 0, 0, 0, 0,
+  0, 0, 33, 0, 0, 0, 0, 25, 18, 30,
+  44, 27, 0, 0, 0, 44, 47, 23, 14, 0,
+  26, 7, 56, 14, 51, 35, 8, 27, 0, 39,
+  0, 19, 0, 4, 43, 43, 0, 0, 0, 0,
+  0, 0, 8, 13, 9, 61, 0, 0, 0, 0,
+  12, 0, 28, 21, 21, 0, 50, 0, 111, 0,
+  14, 14, 3, 0, 103, 0, 37, 5, 6, 15,
+  0, 0, 15, 0, 0, 23, 47, 54, 0, 0,
+  22, 0, 6, 0, 0, 173, 80, 13, 0, 0,
+  0, 33, 0, 0, 2, 56, 0, 34, 0, 21,
+  0, 29, 0, 25, 0, 22, 0, 0, 27, 6,
+  10, 8, 0, 0, 0, 77, 0, 0, 89, 0,
+  43, 20, 45, 0, 35, 11, 0, 32, 30, 49,
+  7, 15, 23, 23, 7, 28, 0, 22, 0, 0,
+  3, 45, 0, 13, 0, 0, 4, 42, 8, 27,
+  0, 9, 0, 0, 0, 0, 8, 0, 7, 0,
+  24, 0, 27, 61, 2, 0, 25, 0, 40, 28,
+  4, 8, 10, 35, 4, 0, 0, 0, 0, 15,
+  78, 0, 23, 10, 0, 35, 0, 0, 20, 3,
+  3, 48, 45, 0, 0, 0, 22, 82, 0, 0,
+  8, 0, 0, 0, 29, 61, 0, 8, 48, 0,
+  0, 0, 21, 71, 5, 41, 10, 3, 0, 14,
+  0, 2, 0, 9, 0, 69, 34, 19, 0, 41,
+  0, 34, 7, 20, 0, 34, 59, 23, 26, 10,
+  5, 0, 0, 0, 0, 0, 0, 0, 18, 22,
+  10, 15, 30, 39, 10, 0, 0, 0, 16, 36,
+  52, 0, 27, 32, 3, 0, 12, 28, 0, 21,
+  0, 48, 0, 2, 0, 34, 13, 5, 17, 11,
+  0, 25, 0, 47, 10, 1, 26, 5, 0, 0,
+  0, 67, 13, 0, 12, 0, 16, 0, 0, 15,
+  0, 51, 0, 0, 0, 0, 0, 0, 69, 0,
+  19, 0, 19, 11, 0, 0, 29, 2, 31, 0,
+  0, 24, 0, 0, 40, 11, 0, 0, 61, 11,
+  0, 15, 51, 85, 31, 58, 61, 16, 0, 9,
+  60, 0, 0, 53, 11, 51, 1, 8, 0, 10,
+  0, 0, 0, 42, 35, 0, 15, 23, 0, 51,
+  12, 18, 0, 69, 33, 20, 9, 0, 0, 0,
+  24, 0, 57, 28, 0, 0, 0, 2, 0, 18,
+  0, 0, 0, 0, 0, 0, 31, 0, 42, 0,
+  0, 0, 4, 14, 36, 12, 0, 6, 0, 29,
+  44, 60, 4, 0, 34, 12, 53, 16, 53, 25,
+  0, 50, 0, 27, 0, 9, 0, 0, 31, 64,
+  0, 0, 0, 0, 0, 0, 0, 12, 10, 60,
+  0, 0, 0, 0, 0, 0, 10, 13, 32, 0,
+  25, 0, 76, 0, 51, 15, 31, 0, 102, 0,
+  40, 4, 0, 12, 0, 0, 45, 0, 0, 35,
+  56, 20, 0, 0, 9, 0, 0, 0, 0, 189,
+  80, 25, 0, 0, 0, 31, 0, 0, 16, 61,
+  0, 11, 0, 30, 0, 40, 0, 30, 0, 28,
+  48, 0, 38, 21, 24, 29, 0, 0, 0, 80,
+  0, 0, 100, 0, 63, 0, 47, 0, 14, 23,
+  0, 56, 27, 66, 0, 1, 0, 4, 12, 26,
+  10, 13, 0, 0, 0, 47, 0, 15, 0, 0,
+  7, 21, 0, 11, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 25, 0, 18, 61, 0, 0,
+  17, 0, 54, 23, 26, 12, 6, 14, 8, 6,
+  0, 0, 0, 2, 87, 0, 36, 39, 0, 9,
+  0, 0, 23, 15, 18, 29, 9, 0, 0, 9,
+  0, 65, 0, 0, 41, 0, 0, 0, 45, 38,
+  0, 38, 32, 25, 0, 0, 8, 14, 5, 56,
+  28, 0, 0, 19, 0, 0, 0, 21, 10, 40,
+  27, 4, 0, 33, 0, 8, 9, 4, 50, 58,
+  50, 77, 14, 17, 0, 0, 0, 0, 0, 0,
+  0, 0, 54, 0, 0, 0, 4, 43, 0, 0,
+  0, 0, 0, 0, 12, 0, 54, 0, 14, 11,
+  0, 28, 0, 28, 0, 28, 0, 16, 0, 39,
+  0, 0, 31, 0, 14, 62, 0, 63, 0, 0,
+  13, 17, 0, 0, 0, 56, 19, 0, 0, 0,
+  17, 0, 0, 4, 0, 40, 0, 0, 0, 9,
+  0, 0, 61, 0, 8, 0, 37, 0, 3, 0,
+  29, 10, 44, 0, 0, 14, 0, 0, 35, 12,
+  0, 0, 40, 0, 0, 15, 31, 88, 14, 51,
+  40, 12, 0, 18, 47, 0, 19, 50, 3, 20,
+  0, 2, 0, 0, 0, 0, 0, 38, 7, 0,
+  3, 31, 0, 29, 36, 1, 0, 74, 29, 39,
+  8, 0, 0, 0, 18, 2, 39, 14, 0, 6,
+  37, 0, 0, 0, 0, 4, 5, 0, 0, 0,
+  26, 0, 49, 0, 0, 0, 3, 3, 17, 22,
+  0, 17, 0, 21, 27, 60, 0, 26, 24, 3,
+  57, 0, 52, 33, 0, 62, 14, 8, 23, 27,
+  0, 0, 26, 70, 5, 0, 0, 0, 0, 0,
+  0, 16, 0, 35, 0, 0, 0, 12, 0, 0,
+  17, 3, 26, 0, 0, 0, 20, 0, 35, 8,
+  37, 0, 44, 0, 0, 0, 25, 73, 0, 0,
+  7, 0, 0, 0, 26, 81, 0, 0, 48, 0,
+  0, 0, 40, 70, 0, 48, 0, 0, 0, 16,
+  0, 0, 0, 0, 0, 39, 0, 0, 0, 36,
+  0, 27, 0, 6, 0, 0, 20, 1, 0, 24,
+  22, 0, 0, 39, 0, 0, 0, 0, 10, 25,
+  0, 0, 31, 12, 0, 4, 0, 0, 87, 23,
+  22, 30, 0, 6, 0, 43, 7, 0, 0, 5,
+  0, 16, 0, 0, 0, 7, 9, 33, 0, 49,
+  1, 0, 0, 56, 0, 0, 0, 0, 0, 0,
+  17, 64, 6, 22, 16, 0, 10, 13, 0, 13,
+  8, 65, 0, 0, 0, 0, 0, 16, 82, 0,
+  8, 0, 12, 7, 0, 0, 0, 7, 4, 20,
+  0, 17, 0, 0, 21, 28, 30, 14, 58, 16,
+  0, 5, 32, 30, 51, 35, 42, 53, 0, 21,
+  81, 0, 0, 49, 7, 50, 21, 0, 0, 19,
+  0, 0, 2, 16, 18, 0, 0, 7, 0, 43,
+  0, 40, 0, 33, 27, 19, 0, 12, 0, 0,
+  23, 0, 84, 2, 0, 0, 0, 0, 0, 29,
+  0, 0, 0, 0, 0, 0, 33, 0, 0, 0,
+  0, 25, 18, 30, 44, 27, 0, 0, 0, 44,
+  47, 23, 14, 0, 26, 7, 56, 14, 51, 35,
+  8, 27, 0, 39, 0, 19, 0, 4, 43, 43,
+  0, 0, 0, 0, 0, 0, 8, 13, 9, 61,
+  0, 0, 0, 0, 12, 0, 28, 21, 21, 0,
+  50, 0, 111, 0, 14, 14, 3, 0, 0, 47,
+  23, 0, 8, 0, 33, 0, 55, 0, 0, 17,
+  28, 56, 45, 66, 49, 49, 0, 15, 78, 0,
+  0, 46, 13, 29, 27, 0, 0, 0, 14, 0,
+  11, 19, 4, 0, 0, 0, 0, 33, 12, 13,
+  0, 55, 6, 0, 0, 0, 0, 0, 63, 12,
+  64, 29, 0, 0, 0, 0, 0, 23, 0, 0,
+  0, 0, 0, 0, 42, 0, 0, 0, 0, 0,
+  0, 41, 36, 0, 0, 29, 0, 27, 65, 51,
+  36, 6, 50, 11, 55, 0, 58, 33, 0, 14,
+  0, 30, 0, 20, 0, 12, 43, 51, 0, 0,
+  0, 0, 0, 0, 5, 6, 14, 33, 30, 0,
+  0, 0, 41, 0, 0, 0, 5, 0, 0, 0,
+  81, 0, 6, 22, 17, 0, 45, 0, 0, 0,
+  22, 82, 0, 0, 8, 0, 0, 0, 29, 61,
+  0, 8, 48, 0, 0, 0, 21, 71, 5, 41,
+  10, 3, 0, 14, 0, 2, 0, 9, 0, 69,
+  34, 19, 0, 41, 0, 34, 7, 20, 0, 34,
+  59, 23, 26, 10, 5, 0, 0, 0, 0, 0,
+  0, 0, 18, 22, 10, 15, 30, 39, 10, 0,
+  0, 0, 16, 36, 52, 0, 27, 32, 3, 0,
+  12, 28, 0, 21, 0, 48, 0, 2, 0, 34,
+  13, 5, 17, 11, 0, 25, 0, 47, 10, 1,
+  26, 5, 0, 0, 0, 67, 13, 0, 12, 0,
+  16, 0, 0, 15, 0, 51, 0, 0, 0, 0,
+  0, 0, 69, 0, 19, 0, 19, 11, 0, 0,
+  29, 2, 31, 0, 0, 24, 0, 0, 40, 11,
+  0, 0, 61, 11, 0, 15, 51, 85, 31, 58,
+  61, 16, 0, 9, 60, 0, 0, 53, 11, 51,
+  1, 8, 0, 10, 0, 0, 0, 42, 35, 0,
+  15, 23, 0, 51, 12, 18, 0, 69, 33, 20,
+  9, 0, 0, 0, 24, 0, 57, 28, 0, 0,
+  0, 2, 0, 18, 0, 0, 0, 0, 0, 0,
+  31, 0, 42, 0, 0, 0, 4, 14, 36, 12,
+  0, 6, 0, 29, 44, 60, 4, 0, 34, 12,
+  53, 16, 53, 25, 0, 50, 0, 27, 0, 9,
+  0, 0, 31, 64, 0, 0, 0, 0, 0, 0,
+  0, 12, 10, 60, 0, 0, 0, 0, 0, 0,
+  10, 13, 32, 0, 25, 0, 76, 0, 51, 15,
+  31, 0, 0, 35, 50, 0, 10, 0, 0, 0,
+  51, 2, 0, 18, 8, 100, 10, 27, 39, 26,
+  2, 4, 44, 0, 34, 24, 0, 0, 0, 5,
+  0, 0, 0, 0, 0, 0, 0, 0, 5, 0,
+  0, 22, 18, 0, 0, 35, 0, 0, 0, 0,
+  0, 0, 52, 66, 0, 34, 0, 0, 6, 2,
+  0, 0, 0, 0, 13, 0, 38, 2, 22, 0,
+  23, 0, 0, 0, 3, 15, 29, 0, 0, 37,
+  0, 21, 32, 48, 11, 18, 40, 3, 53, 7,
+  75, 6, 0, 23, 0, 0, 0, 1, 0, 0,
+  40, 70, 1, 0, 0, 0, 7, 0, 0, 9,
+  0, 8, 32, 0, 0, 0, 57, 0, 10, 0,
+  12, 0, 0, 0, 8, 0, 9, 14, 37, 0,
+  9, 0, 0, 9, 0, 65, 0, 0, 41, 0,
+  0, 0, 45, 38, 0, 38, 32, 25, 0, 0,
+  8, 14, 5, 56, 28, 0, 0, 19, 0, 0,
+  0, 21, 10, 40, 27, 4, 0, 33, 0, 8,
+  9, 4, 50, 58, 50, 77, 14, 17, 0, 0,
+  0, 0, 0, 0, 0, 0, 54, 0, 0, 0,
+  4, 43, 0, 0, 0, 0, 0, 0, 12, 0,
+  54, 0, 14, 11, 0, 28, 0, 28, 0, 28,
+  0, 16, 0, 39, 0, 0, 31, 0, 14, 62,
+  0, 63, 0, 0, 13, 17, 0, 0, 0, 56,
+  19, 0, 0, 0, 17, 0, 0, 4, 0, 40,
+  0, 0, 0, 9, 0, 0, 61, 0, 8, 0,
+  37, 0, 3, 0, 29, 10, 44, 0, 0, 14,
+  0, 0, 35, 12, 0, 0, 40, 0, 0, 15,
+  31, 88, 14, 51, 40, 12, 0, 18, 47, 0,
+  19, 50, 3, 20, 0, 2, 0, 0, 0, 0,
+  0, 38, 7, 0, 3, 31, 0, 29, 36, 1,
+  0, 74, 29, 39, 8, 0, 0, 0, 18, 2,
+  39, 14, 0, 6, 37, 0, 0, 0, 0, 4,
+  5, 0, 0, 0, 26, 0, 49, 0, 0, 0,
+  3, 3, 17, 22, 0, 17, 0, 21, 27, 60,
+  0, 26, 24, 3, 57, 0, 52, 33, 0, 62,
+  14, 8, 23, 27, 0, 0, 26, 70, 5, 0,
+  0, 0, 0, 0, 0, 16, 0, 35, 0, 0,
+  0, 12, 0, 0, 17, 3, 26, 0, 0, 0,
+  20, 0, 35, 8, 37, 0, 24, 0, 53, 0,
+  32, 0, 0, 0, 25, 0, 0, 1, 9, 122,
+  15, 0, 27, 21, 0, 8, 41, 13, 69, 7,
+  0, 0, 0, 4, 0, 0, 0, 0, 0, 5,
+  0, 0, 0, 4, 0, 26, 14, 10, 0, 48,
+  14, 0, 0, 0, 0, 0, 37, 104, 0, 37,
+  0, 0, 9, 6, 3, 0, 0, 0, 33, 0,
+  50, 22, 0, 0, 24, 22, 0, 1, 0, 0,
+  27, 0, 0, 13, 0, 41, 14, 36, 0, 5,
+  48, 0, 45, 11, 72, 0, 0, 2, 0, 0,
+  0, 25, 0, 0, 41, 57, 0, 0, 0, 0,
+  0, 0, 0, 10, 1, 0, 35, 0, 0, 0,
+  51, 0, 55, 0, 5, 0, 0, 0, 0, 0,
+  28, 1, 16, 0, 0, 17, 0, 0, 21, 28,
+  30, 14, 58, 16, 0, 5, 32, 30, 51, 35,
+  42, 53, 0, 21, 81, 0, 0, 49, 7, 50,
+  21, 0, 0, 19, 0, 0, 2, 16, 18, 0,
+  0, 7, 0, 43, 0, 40, 0, 33, 27, 19,
+  0, 12, 0, 0, 23, 0, 84, 2, 0, 0,
+  0, 0, 0, 29, 0, 0, 0, 0, 0, 0,
+  33, 0, 0, 0, 0, 25, 18, 30, 44, 27,
+  0, 0, 0, 44, 47, 23, 14, 0, 26, 7,
+  56, 14, 51, 35, 8, 27, 0, 39, 0, 19,
+  0, 4, 43, 43, 0, 0, 0, 0, 0, 0,
+  8, 13, 9, 61, 0, 0, 0, 0, 12, 0,
+  28, 21, 21, 0, 50, 0, 111, 0, 14, 14,
+  3, 0, 0, 47, 23, 0, 8, 0, 33, 0,
+  55, 0, 0, 17, 28, 56, 45, 66, 49, 49,
+  0, 15, 78, 0, 0, 46, 13, 29, 27, 0,
+  0, 0, 14, 0, 11, 19, 4, 0, 0, 0,
+  0, 33, 12, 13, 0, 55, 6, 0, 0, 0,
+  0, 0, 63, 12, 64, 29, 0, 0, 0, 0,
+  0, 23, 0, 0, 0, 0, 0, 0, 42, 0,
+  0, 0, 0, 0, 0, 41, 36, 0, 0, 29,
+  0, 27, 65, 51, 36, 6, 50, 11, 55, 0,
+  58, 33, 0, 14, 0, 30, 0, 20, 0, 12,
+  43, 51, 0, 0, 0, 0, 0, 0, 5, 6,
+  14, 33, 30, 0, 0, 0, 41, 0, 0, 0,
+  5, 0, 0, 0, 81, 0, 6, 22, 17, 0,
+  0, 43, 70, 0, 11, 0, 9, 0, 57, 6,
+  0, 0, 0, 60, 23, 63, 30, 38, 0, 12,
+  39, 0, 33, 35, 0, 0, 9, 14, 0, 0,
+  27, 0, 0, 0, 0, 0, 0, 17, 0, 12,
+  27, 0, 0, 40, 0, 0, 0, 0, 0, 0,
+  48, 52, 41, 12, 0, 0, 19, 12, 0, 0,
+  0, 0, 0, 0, 24, 0, 45, 0, 11, 4,
+  0, 0, 0, 28, 32, 0, 0, 18, 0, 0,
+  58, 19, 0, 21, 59, 13, 23, 9, 64, 10,
+  0, 32, 0, 0, 0, 0, 0, 0, 40, 51,
+  0, 0, 0, 0, 36, 0, 0, 22, 4, 24,
+  40, 0, 0, 0, 86, 0, 2, 0, 26, 0,
+  0, 1, 21, 0, 0, 24, 22, 0, 0, 24,
+  0, 0, 40, 11, 0, 0, 61, 11, 0, 15,
+  51, 85, 31, 58, 61, 16, 0, 9, 60, 0,
+  0, 53, 11, 51, 1, 8, 0, 10, 0, 0,
+  0, 42, 35, 0, 15, 23, 0, 51, 12, 18,
+  0, 69, 33, 20, 9, 0, 0, 0, 24, 0,
+  57, 28, 0, 0, 0, 2, 0, 18, 0, 0,
+  0, 0, 0, 0, 31, 0, 42, 0, 0, 0,
+  4, 14, 36, 12, 0, 6, 0, 29, 44, 60,
+  4, 0, 34, 12, 53, 16, 53, 25, 0, 50,
+  0, 27, 0, 9, 0, 0, 31, 64, 0, 0,
+  0, 0, 0, 0, 0, 12, 10, 60, 0, 0,
+  0, 0, 0, 0, 10, 13, 32, 0, 25, 0,
+  76, 0, 51, 15, 31, 0, 0, 35, 50, 0,
+  10, 0, 0, 0, 51, 2, 0, 18, 8, 100,
+  10, 27, 39, 26, 2, 4, 44, 0, 34, 24,
+  0, 0, 0, 5, 0, 0, 0, 0, 0, 0,
+  0, 0, 5, 0, 0, 22, 18, 0, 0, 35,
+  0, 0, 0, 0, 0, 0, 52, 66, 0, 34,
+  0, 0, 6, 2, 0, 0, 0, 0, 13, 0,
+  38, 2, 22, 0, 23, 0, 0, 0, 3, 15,
+  29, 0, 0, 37, 0, 21, 32, 48, 11, 18,
+  40, 3, 53, 7, 75, 6, 0, 23, 0, 0,
+  0, 1, 0, 0, 40, 70, 1, 0, 0, 0,
+  7, 0, 0, 9, 0, 8, 32, 0, 0, 0,
+  57, 0, 10, 0, 12, 0, 0, 0, 8, 0,
+  9, 14, 37, 0, 22, 0, 59, 0, 0, 0,
+  0, 0, 23, 0, 0, 0, 0, 116, 1, 0,
+  6, 27, 1, 0, 38, 30, 84, 8, 0, 0,
+  0, 4, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 2, 0, 0, 28, 17, 0, 30, 0, 0,
+  0, 0, 0, 0, 35, 131, 0, 15, 36, 0,
+  30, 17, 14, 0, 0, 0, 34, 0, 88, 47,
+  7, 2, 16, 67, 0, 0, 0, 0, 11, 0,
+  0, 0, 0, 24, 16, 22, 0, 15, 41, 0,
+  31, 10, 71, 0, 0, 11, 2, 0, 0, 5,
+  0, 0, 62, 66, 0, 0, 0, 0, 12, 10,
+  0, 7, 0, 0, 50, 0, 0, 0, 91, 3,
+  77, 0, 19, 0, 0, 0, 0, 0, 21, 6,
+  10, 0, 0, 14, 0, 0, 35, 12, 0, 0,
+  40, 0, 0, 15, 31, 88, 14, 51, 40, 12,
+  0, 18, 47, 0, 19, 50, 3, 20, 0, 2,
+  0, 0, 0, 0, 0, 38, 7, 0, 3, 31,
+  0, 29, 36, 1, 0, 74, 29, 39, 8, 0,
+  0, 0, 18, 2, 39, 14, 0, 6, 37, 0,
+  0, 0, 0, 4, 5, 0, 0, 0, 26, 0,
+  49, 0, 0, 0, 3, 3, 17, 22, 0, 17,
+  0, 21, 27, 60, 0, 26, 24, 3, 57, 0,
+  52, 33, 0, 62, 14, 8, 23, 27, 0, 0,
+  26, 70, 5, 0, 0, 0, 0, 0, 0, 16,
+  0, 35, 0, 0, 0, 12, 0, 0, 17, 3,
+  26, 0, 0, 0, 20, 0, 35, 8, 37, 0,
+  24, 0, 53, 0, 32, 0, 0, 0, 25, 0,
+  0, 1, 9, 122, 15, 0, 27, 21, 0, 8,
+  41, 13, 69, 7, 0, 0, 0, 4, 0, 0,
+  0, 0, 0, 5, 0, 0, 0, 4, 0, 26,
+  14, 10, 0, 48, 14, 0, 0, 0, 0, 0,
+  37, 104, 0, 37, 0, 0, 9, 6, 3, 0,
+  0, 0, 33, 0, 50, 22, 0, 0, 24, 22,
+  0, 1, 0, 0, 27, 0, 0, 13, 0, 41,
+  14, 36, 0, 5, 48, 0, 45, 11, 72, 0,
+  0, 2, 0, 0, 0, 25, 0, 0, 41, 57,
+  0, 0, 0, 0, 0, 0, 0, 10, 1, 0,
+  35, 0, 0, 0, 51, 0, 55, 0, 5, 0,
+  0, 0, 0, 0, 28, 1, 16, 0, 30, 0,
+  17, 10, 31, 0, 0, 0, 35, 0, 0, 3,
+  12, 104, 13, 0, 18, 16, 0, 5, 51, 0,
+  33, 3, 0, 0, 0, 16, 0, 15, 0, 9,
+  0, 7, 0, 0, 0, 0, 0, 7, 0, 12,
+  0, 50, 13, 0, 0, 0, 0, 0, 32, 102,
+  0, 61, 0, 0, 22, 15, 0, 0, 0, 0,
+  29, 0, 32, 22, 10, 15, 12, 12, 0, 0,
+  0, 0, 42, 0, 0, 0, 0, 33, 26, 38,
+  0, 3, 31, 0, 30, 10, 63, 12, 0, 0,
+  0, 0, 0, 25, 23, 0, 69, 64, 0, 0,
+  2, 0, 4, 5, 0, 9, 49, 0, 33, 0,
+  0, 3, 60, 0, 68, 0, 0, 0, 8, 0,
+  0, 0, 49, 3, 11, 0, 0, 47, 23, 0,
+  8, 0, 33, 0, 55, 0, 0, 17, 28, 56,
+  45, 66, 49, 49, 0, 15, 78, 0, 0, 46,
+  13, 29, 27, 0, 0, 0, 14, 0, 11, 19,
+  4, 0, 0, 0, 0, 33, 12, 13, 0, 55,
+  6, 0, 0, 0, 0, 0, 63, 12, 64, 29,
+  0, 0, 0, 0, 0, 23, 0, 0, 0, 0,
+  0, 0, 42, 0, 0, 0, 0, 0, 0, 41,
+  36, 0, 0, 29, 0, 27, 65, 51, 36, 6,
+  50, 11, 55, 0, 58, 33, 0, 14, 0, 30,
+  0, 20, 0, 12, 43, 51, 0, 0, 0, 0,
+  0, 0, 5, 6, 14, 33, 30, 0, 0, 0,
+  41, 0, 0, 0, 5, 0, 0, 0, 81, 0,
+  6, 22, 17, 0, 0, 43, 70, 0, 11, 0,
+  9, 0, 57, 6, 0, 0, 0, 60, 23, 63,
+  30, 38, 0, 12, 39, 0, 33, 35, 0, 0,
+  9, 14, 0, 0, 27, 0, 0, 0, 0, 0,
+  0, 17, 0, 12, 27, 0, 0, 40, 0, 0,
+  0, 0, 0, 0, 48, 52, 41, 12, 0, 0,
+  19, 12, 0, 0, 0, 0, 0, 0, 24, 0,
+  45, 0, 11, 4, 0, 0, 0, 28, 32, 0,
+  0, 18, 0, 0, 58, 19, 0, 21, 59, 13,
+  23, 9, 64, 10, 0, 32, 0, 0, 0, 0,
+  0, 0, 40, 51, 0, 0, 0, 0, 36, 0,
+  0, 22, 4, 24, 40, 0, 0, 0, 86, 0,
+  2, 0, 26, 0, 0, 1, 21, 0, 0, 24,
+  22, 0, 0, 1, 54, 0, 0, 0, 0, 0,
+  42, 0, 0, 7, 0, 86, 0, 0, 1, 43,
+  0, 15, 50, 15, 93, 16, 0, 0, 0, 18,
+  0, 0, 16, 0, 0, 0, 0, 0, 0, 25,
+  0, 0, 34, 33, 0, 35, 0, 0, 0, 17,
+  0, 0, 34, 96, 0, 0, 21, 0, 40, 0,
+  14, 0, 0, 2, 21, 0, 100, 23, 1, 3,
+  2, 71, 0, 0, 0, 0, 18, 0, 0, 0,
+  0, 0, 25, 5, 0, 25, 63, 0, 32, 16,
+  62, 0, 0, 28, 0, 0, 0, 0, 0, 0,
+  67, 44, 0, 0, 0, 0, 26, 0, 0, 29,
+  0, 5, 41, 0, 0, 0, 99, 0, 45, 0,
+  46, 0, 0, 13, 0, 0, 0, 6, 19, 0,
+  0, 35, 50, 0, 10, 0, 0, 0, 51, 2,
+  0, 18, 8, 100, 10, 27, 39, 26, 2, 4,
+  44, 0, 34, 24, 0, 0, 0, 5, 0, 0,
+  0, 0, 0, 0, 0, 0, 5, 0, 0, 22,
+  18, 0, 0, 35, 0, 0, 0, 0, 0, 0,
+  52, 66, 0, 34, 0, 0, 6, 2, 0, 0,
+  0, 0, 13, 0, 38, 2, 22, 0, 23, 0,
+  0, 0, 3, 15, 29, 0, 0, 37, 0, 21,
+  32, 48, 11, 18, 40, 3, 53, 7, 75, 6,
+  0, 23, 0, 0, 0, 1, 0, 0, 40, 70,
+  1, 0, 0, 0, 7, 0, 0, 9, 0, 8,
+  32, 0, 0, 0, 57, 0, 10, 0, 12, 0,
+  0, 0, 8, 0, 9, 14, 37, 0, 22, 0,
+  59, 0, 0, 0, 0, 0, 23, 0, 0, 0,
+  0, 116, 1, 0, 6, 27, 1, 0, 38, 30,
+  84, 8, 0, 0, 0, 4, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 2, 0, 0, 28, 17,
+  0, 30, 0, 0, 0, 0, 0, 0, 35, 131,
+  0, 15, 36, 0, 30, 17, 14, 0, 0, 0,
+  34, 0, 88, 47, 7, 2, 16, 67, 0, 0,
+  0, 0, 11, 0, 0, 0, 0, 24, 16, 22,
+  0, 15, 41, 0, 31, 10, 71, 0, 0, 11,
+  2, 0, 0, 5, 0, 0, 62, 66, 0, 0,
+  0, 0, 12, 10, 0, 7, 0, 0, 50, 0,
+  0, 0, 91, 3, 77, 0, 19, 0, 0, 0,
+  0, 0, 21, 6, 10, 0, 20, 0, 19, 16,
+  0, 0, 0, 0, 29, 0, 0, 0, 2, 73,
+  0, 0, 0, 28, 8, 5, 49, 5, 52, 6,
+  0, 0, 0, 7, 0, 12, 6, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 29, 0, 45,
+  0, 0, 0, 16, 0, 0, 39, 114, 0, 30,
+  15, 0, 35, 10, 0, 0, 0, 0, 31, 0,
+  77, 23, 0, 26, 0, 48, 0, 8, 0, 0,
+  25, 0, 0, 0, 0, 24, 31, 18, 0, 15,
+  42, 0, 28, 19, 61, 0, 0, 0, 0, 0,
+  0, 9, 24, 0, 72, 41, 0, 0, 3, 0,
+  0, 0, 0, 13, 37, 0, 43, 0, 0, 5,
+  84, 0, 93, 0, 17, 0, 7, 5, 0, 0,
+  42, 4, 0, 0, 24, 0, 53, 0, 32, 0,
+  0, 0, 25, 0, 0, 1, 9, 122, 15, 0,
+  27, 21, 0, 8, 41, 13, 69, 7, 0, 0,
+  0, 4, 0, 0, 0, 0, 0, 5, 0, 0,
+  0, 4, 0, 26, 14, 10, 0, 48, 14, 0,
+  0, 0, 0, 0, 37, 104, 0, 37, 0, 0,
+  9, 6, 3, 0, 0, 0, 33, 0, 50, 22,
+  0, 0, 24, 22, 0, 1, 0, 0, 27, 0,
+  0, 13, 0, 41, 14, 36, 0, 5, 48, 0,
+  45, 11, 72, 0, 0, 2, 0, 0, 0, 25,
+  0, 0, 41, 57, 0, 0, 0, 0, 0, 0,
+  0, 10, 1, 0, 35, 0, 0, 0, 51, 0,
+  55, 0, 5, 0, 0, 0, 0, 0, 28, 1,
+  16, 0, 30, 0, 17, 10, 31, 0, 0, 0,
+  35, 0, 0, 3, 12, 104, 13, 0, 18, 16,
+  0, 5, 51, 0, 33, 3, 0, 0, 0, 16,
+  0, 15, 0, 9, 0, 7, 0, 0, 0, 0,
+  0, 7, 0, 12, 0, 50, 13, 0, 0, 0,
+  0, 0, 32, 102, 0, 61, 0, 0, 22, 15,
+  0, 0, 0, 0, 29, 0, 32, 22, 10, 15,
+  12, 12, 0, 0, 0, 0, 42, 0, 0, 0,
+  0, 33, 26, 38, 0, 3, 31, 0, 30, 10,
+  63, 12, 0, 0, 0, 0, 0, 25, 23, 0,
+  69, 64, 0, 0, 2, 0, 4, 5, 0, 9,
+  49, 0, 33, 0, 0, 3, 60, 0, 68, 0,
+  0, 0, 8, 0, 0, 0, 49, 3, 11, 0,
+  0, 22, 0, 46, 29, 0, 0, 10, 69, 0,
+  0, 23, 38, 83, 24, 20, 35, 2, 0, 9,
+  58, 0, 0, 0, 4, 48, 0, 23, 0, 8,
+  10, 0, 0, 43, 1, 0, 0, 4, 0, 24,
+  0, 21, 0, 69, 0, 0, 10, 17, 0, 0,
+  39, 72, 4, 92, 0, 0, 6, 27, 0, 37,
+  0, 0, 0, 0, 0, 8, 23, 24, 37, 0,
+  0, 3, 0, 0, 58, 0, 0, 14, 0, 39,
+  58, 70, 0, 0, 36, 5, 31, 21, 43, 20,
+  8, 4, 0, 16, 0, 28, 38, 0, 72, 48,
+  0, 0, 6, 0, 2, 0, 0, 22, 64, 11,
+  22, 0, 0, 9, 42, 0, 28, 0, 0, 0,
+  25, 29, 79, 0, 79, 5, 10, 0, 0, 43,
+  70, 0, 11, 0, 9, 0, 57, 6, 0, 0,
+  0, 60, 23, 63, 30, 38, 0, 12, 39, 0,
+  33, 35, 0, 0, 9, 14, 0, 0, 27, 0,
+  0, 0, 0, 0, 0, 17, 0, 12, 27, 0,
+  0, 40, 0, 0, 0, 0, 0, 0, 48, 52,
+  41, 12, 0, 0, 19, 12, 0, 0, 0, 0,
+  0, 0, 24, 0, 45, 0, 11, 4, 0, 0,
+  0, 28, 32, 0, 0, 18, 0, 0, 58, 19,
+  0, 21, 59, 13, 23, 9, 64, 10, 0, 32,
+  0, 0, 0, 0, 0, 0, 40, 51, 0, 0,
+  0, 0, 36, 0, 0, 22, 4, 24, 40, 0,
+  0, 0, 86, 0, 2, 0, 26, 0, 0, 1,
+  21, 0, 0, 24, 22, 0, 0, 1, 54, 0,
+  0, 0, 0, 0, 42, 0, 0, 7, 0, 86,
+  0, 0, 1, 43, 0, 15, 50, 15, 93, 16,
+  0, 0, 0, 18, 0, 0, 16, 0, 0, 0,
+  0, 0, 0, 25, 0, 0, 34, 33, 0, 35,
+  0, 0, 0, 17, 0, 0, 34, 96, 0, 0,
+  21, 0, 40, 0, 14, 0, 0, 2, 21, 0,
+  100, 23, 1, 3, 2, 71, 0, 0, 0, 0,
+  18, 0, 0, 0, 0, 0, 25, 5, 0, 25,
+  63, 0, 32, 16, 62, 0, 0, 28, 0, 0,
+  0, 0, 0, 0, 67, 44, 0, 0, 0, 0,
+  26, 0, 0, 29, 0, 5, 41, 0, 0, 0,
+  99, 0, 45, 0, 46, 0, 0, 13, 0, 0,
+  0, 6, 19, 0, 16, 0, 16, 11, 0, 0,
+  0, 0, 35, 0, 0, 25, 4, 106, 0, 0,
+  0, 36, 2, 10, 68, 10, 49, 2, 0, 0,
+  0, 0, 0, 0, 0, 2, 0, 9, 0, 0,
+  0, 0, 0, 0, 5, 41, 0, 45, 0, 0,
+  0, 31, 0, 0, 66, 127, 0, 42, 14, 0,
+  16, 0, 2, 0, 0, 0, 48, 0, 110, 32,
+  0, 9, 0, 60, 0, 11, 0, 0, 22, 0,
+  0, 0, 0, 41, 18, 32, 0, 0, 51, 0,
+  58, 18, 81, 0, 0, 0, 0, 0, 0, 12,
+  11, 0, 73, 49, 0, 0, 0, 0, 6, 0,
+  0, 8, 11, 0, 36, 0, 0, 0, 95, 0,
+  70, 0, 20, 0, 1, 0, 0, 0, 8, 0,
+  11, 0, 22, 0, 59, 0, 0, 0, 0, 0,
+  23, 0, 0, 0, 0, 116, 1, 0, 6, 27,
+  1, 0, 38, 30, 84, 8, 0, 0, 0, 4,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 2,
+  0, 0, 28, 17, 0, 30, 0, 0, 0, 0,
+  0, 0, 35, 131, 0, 15, 36, 0, 30, 17,
+  14, 0, 0, 0, 34, 0, 88, 47, 7, 2,
+  16, 67, 0, 0, 0, 0, 11, 0, 0, 0,
+  0, 24, 16, 22, 0, 15, 41, 0, 31, 10,
+  71, 0, 0, 11, 2, 0, 0, 5, 0, 0,
+  62, 66, 0, 0, 0, 0, 12, 10, 0, 7,
+  0, 0, 50, 0, 0, 0, 91, 3, 77, 0,
+  19, 0, 0, 0, 0, 0, 21, 6, 10, 0,
+  20, 0, 19, 16, 0, 0, 0, 0, 29, 0,
+  0, 0, 2, 73, 0, 0, 0, 28, 8, 5,
+  49, 5, 52, 6, 0, 0, 0, 7, 0, 12,
+  6, 1, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 29, 0, 45, 0, 0, 0, 16, 0, 0,
+  39, 114, 0, 30, 15, 0, 35, 10, 0, 0,
+  0, 0, 31, 0, 77, 23, 0, 26, 0, 48,
+  0, 8, 0, 0, 25, 0, 0, 0, 0, 24,
+  31, 18, 0, 15, 42, 0, 28, 19, 61, 0,
+  0, 0, 0, 0, 0, 9, 24, 0, 72, 41,
+  0, 0, 3, 0, 0, 0, 0, 13, 37, 0,
+  43, 0, 0, 5, 84, 0, 93, 0, 17, 0,
+  7, 5, 0, 0, 42, 4, 0, 0, 3, 16,
+  0, 41, 1, 0, 4, 6, 70, 0, 0, 11,
+  25, 55, 18, 0, 14, 4, 17, 0, 52, 0,
+  0, 17, 0, 16, 4, 14, 0, 32, 2, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 25,
+  0, 53, 0, 0, 5, 16, 0, 0, 58, 87,
+  18, 68, 0, 0, 15, 25, 0, 19, 0, 0,
+  0, 0, 0, 11, 7, 13, 8, 0, 0, 9,
+  0, 0, 44, 3, 0, 0, 0, 43, 57, 57,
+  0, 0, 32, 0, 31, 33, 74, 29, 25, 0,
+  0, 0, 0, 11, 45, 0, 71, 48, 0, 0,
+  7, 0, 2, 0, 0, 12, 74, 6, 34, 0,
+  0, 0, 67, 0, 49, 0, 0, 0, 48, 9,
+  63, 0, 76, 0, 5, 0, 30, 0, 17, 10,
+  31, 0, 0, 0, 35, 0, 0, 3, 12, 104,
+  13, 0, 18, 16, 0, 5, 51, 0, 33, 3,
+  0, 0, 0, 16, 0, 15, 0, 9, 0, 7,
+  0, 0, 0, 0, 0, 7, 0, 12, 0, 50,
+  13, 0, 0, 0, 0, 0, 32, 102, 0, 61,
+  0, 0, 22, 15, 0, 0, 0, 0, 29, 0,
+  32, 22, 10, 15, 12, 12, 0, 0, 0, 0,
+  42, 0, 0, 0, 0, 33, 26, 38, 0, 3,
+  31, 0, 30, 10, 63, 12, 0, 0, 0, 0,
+  0, 25, 23, 0, 69, 64, 0, 0, 2, 0,
+  4, 5, 0, 9, 49, 0, 33, 0, 0, 3,
+  60, 0, 68, 0, 0, 0, 8, 0, 0, 0,
+  49, 3, 11, 0, 0, 22, 0, 46, 29, 0,
+  0, 10, 69, 0, 0, 23, 38, 83, 24, 20,
+  35, 2, 0, 9, 58, 0, 0, 0, 4, 48,
+  0, 23, 0, 8, 10, 0, 0, 43, 1, 0,
+  0, 4, 0, 24, 0, 21, 0, 69, 0, 0,
+  10, 17, 0, 0, 39, 72, 4, 92, 0, 0,
+  6, 27, 0, 37, 0, 0, 0, 0, 0, 8,
+  23, 24, 37, 0, 0, 3, 0, 0, 58, 0,
+  0, 14, 0, 39, 58, 70, 0, 0, 36, 5,
+  31, 21, 43, 20, 8, 4, 0, 16, 0, 28,
+  38, 0, 72, 48, 0, 0, 6, 0, 2, 0,
+  0, 22, 64, 11, 22, 0, 0, 9, 42, 0,
+  28, 0, 0, 0, 25, 29, 79, 0, 79, 5,
+  10, 0, 0, 19, 0, 49, 12, 0, 0, 25,
+  85, 2, 1, 7, 23, 85, 32, 34, 52, 0,
+  5, 0, 23, 0, 0, 0, 0, 25, 0, 34,
+  0, 0, 0, 0, 0, 25, 0, 0, 0, 0,
+  0, 23, 0, 6, 0, 46, 0, 0, 22, 18,
+  0, 0, 24, 75, 20, 83, 0, 0, 0, 46,
+  0, 19, 0, 0, 0, 0, 0, 30, 41, 0,
+  59, 0, 0, 0, 0, 12, 50, 0, 0, 9,
+  0, 32, 59, 63, 9, 0, 17, 31, 16, 61,
+  46, 0, 20, 36, 0, 0, 0, 9, 42, 0,
+  48, 63, 0, 0, 0, 0, 9, 0, 0, 19,
+  28, 6, 15, 0, 0, 0, 28, 0, 22, 0,
+  0, 0, 15, 1, 73, 0, 78, 3, 7, 0,
+  0, 1, 54, 0, 0, 0, 0, 0, 42, 0,
+  0, 7, 0, 86, 0, 0, 1, 43, 0, 15,
+  50, 15, 93, 16, 0, 0, 0, 18, 0, 0,
+  16, 0, 0, 0, 0, 0, 0, 25, 0, 0,
+  34, 33, 0, 35, 0, 0, 0, 17, 0, 0,
+  34, 96, 0, 0, 21, 0, 40, 0, 14, 0,
+  0, 2, 21, 0, 100, 23, 1, 3, 2, 71,
+  0, 0, 0, 0, 18, 0, 0, 0, 0, 0,
+  25, 5, 0, 25, 63, 0, 32, 16, 62, 0,
+  0, 28, 0, 0, 0, 0, 0, 0, 67, 44,
+  0, 0, 0, 0, 26, 0, 0, 29, 0, 5,
+  41, 0, 0, 0, 99, 0, 45, 0, 46, 0,
+  0, 13, 0, 0, 0, 6, 19, 0, 16, 0,
+  16, 11, 0, 0, 0, 0, 35, 0, 0, 25,
+  4, 106, 0, 0, 0, 36, 2, 10, 68, 10,
+  49, 2, 0, 0, 0, 0, 0, 0, 0, 2,
+  0, 9, 0, 0, 0, 0, 0, 0, 5, 41,
+  0, 45, 0, 0, 0, 31, 0, 0, 66, 127,
+  0, 42, 14, 0, 16, 0, 2, 0, 0, 0,
+  48, 0, 110, 32, 0, 9, 0, 60, 0, 11,
+  0, 0, 22, 0, 0, 0, 0, 41, 18, 32,
+  0, 0, 51, 0, 58, 18, 81, 0, 0, 0,
+  0, 0, 0, 12, 11, 0, 73, 49, 0, 0,
+  0, 0, 6, 0, 0, 8, 11, 0, 36, 0,
+  0, 0, 95, 0, 70, 0, 20, 0, 1, 0,
+  0, 0, 8, 0, 11, 0, 7, 17, 0, 25,
+  21, 11, 0, 0, 61, 0, 0, 19, 7, 87,
+  0, 0, 0, 20, 13, 16, 69, 0, 0, 19,
+  0, 0, 0, 0, 0, 18, 0, 0, 0, 6,
+  0, 0, 0, 0, 0, 0, 0, 18, 0, 55,
+  0, 0, 10, 38, 0, 0, 71, 103, 0, 69,
+  0, 0, 31, 9, 0, 0, 0, 0, 4, 0,
+  42, 20, 0, 14, 0, 7, 0, 2, 0, 0,
+  39, 0, 0, 0, 0, 43, 31, 45, 9, 0,
+  36, 0, 50, 45, 79, 24, 11, 1, 0, 0,
+  0, 13, 32, 0, 65, 65, 1, 23, 0, 0,
+  0, 0, 0, 13, 64, 0, 7, 0, 0, 0,
+  59, 0, 45, 0, 6, 0, 45, 0, 40, 0,
+  47, 0, 8, 0, 20, 0, 19, 16, 0, 0,
+  0, 0, 29, 0, 0, 0, 2, 73, 0, 0,
+  0, 28, 8, 5, 49, 5, 52, 6, 0, 0,
+  0, 7, 0, 12, 6, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 29, 0, 45, 0, 0,
+  0, 16, 0, 0, 39, 114, 0, 30, 15, 0,
+  35, 10, 0, 0, 0, 0, 31, 0, 77, 23,
+  0, 26, 0, 48, 0, 8, 0, 0, 25, 0,
+  0, 0, 0, 24, 31, 18, 0, 15, 42, 0,
+  28, 19, 61, 0, 0, 0, 0, 0, 0, 9,
+  24, 0, 72, 41, 0, 0, 3, 0, 0, 0,
+  0, 13, 37, 0, 43, 0, 0, 5, 84, 0,
+  93, 0, 17, 0, 7, 5, 0, 0, 42, 4,
+  0, 0, 3, 16, 0, 41, 1, 0, 4, 6,
+  70, 0, 0, 11, 25, 55, 18, 0, 14, 4,
+  17, 0, 52, 0, 0, 17, 0, 16, 4, 14,
+  0, 32, 2, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 25, 0, 53, 0, 0, 5, 16,
+  0, 0, 58, 87, 18, 68, 0, 0, 15, 25,
+  0, 19, 0, 0, 0, 0, 0, 11, 7, 13,
+  8, 0, 0, 9, 0, 0, 44, 3, 0, 0,
+  0, 43, 57, 57, 0, 0, 32, 0, 31, 33,
+  74, 29, 25, 0, 0, 0, 0, 11, 45, 0,
+  71, 48, 0, 0, 7, 0, 2, 0, 0, 12,
+  74, 6, 34, 0, 0, 0, 67, 0, 49, 0,
+  0, 0, 48, 9, 63, 0, 76, 0, 5, 0,
+  0, 29, 0, 36, 17, 0, 0, 1, 82, 0,
+  0, 10, 14, 80, 41, 0, 22, 8, 10, 0,
+  47, 0, 0, 23, 0, 13, 0, 15, 0, 5,
+  0, 0, 0, 11, 0, 0, 0, 0, 0, 11,
+  0, 0, 0, 51, 0, 0, 23, 16, 0, 0,
+  35, 72, 21, 74, 0, 0, 3, 24, 0, 11,
+  0, 0, 0, 0, 0, 21, 29, 0, 30, 0,
+  0, 0, 0, 0, 58, 0, 0, 0, 0, 30,
+  56, 60, 4, 0, 25, 0, 29, 51, 61, 17,
+  7, 13, 0, 0, 0, 14, 29, 0, 67, 43,
+  0, 16, 0, 0, 10, 1, 0, 7, 54, 13,
+  18, 0, 0, 0, 34, 0, 15, 0, 0, 0,
+  35, 0, 63, 0, 64, 0, 8, 0, 0, 22,
+  0, 46, 29, 0, 0, 10, 69, 0, 0, 23,
+  38, 83, 24, 20, 35, 2, 0, 9, 58, 0,
+  0, 0, 4, 48, 0, 23, 0, 8, 10, 0,
+  0, 43, 1, 0, 0, 4, 0, 24, 0, 21,
+  0, 69, 0, 0, 10, 17, 0, 0, 39, 72,
+  4, 92, 0, 0, 6, 27, 0, 37, 0, 0,
+  0, 0, 0, 8, 23, 24, 37, 0, 0, 3,
+  0, 0, 58, 0, 0, 14, 0, 39, 58, 70,
+  0, 0, 36, 5, 31, 21, 43, 20, 8, 4,
+  0, 16, 0, 28, 38, 0, 72, 48, 0, 0,
+  6, 0, 2, 0, 0, 22, 64, 11, 22, 0,
+  0, 9, 42, 0, 28, 0, 0, 0, 25, 29,
+  79, 0, 79, 5, 10, 0, 0, 19, 0, 49,
+  12, 0, 0, 25, 85, 2, 1, 7, 23, 85,
+  32, 34, 52, 0, 5, 0, 23, 0, 0, 0,
+  0, 25, 0, 34, 0, 0, 0, 0, 0, 25,
+  0, 0, 0, 0, 0, 23, 0, 6, 0, 46,
+  0, 0, 22, 18, 0, 0, 24, 75, 20, 83,
+  0, 0, 0, 46, 0, 19, 0, 0, 0, 0,
+  0, 30, 41, 0, 59, 0, 0, 0, 0, 12,
+  50, 0, 0, 9, 0, 32, 59, 63, 9, 0,
+  17, 31, 16, 61, 46, 0, 20, 36, 0, 0,
+  0, 9, 42, 0, 48, 63, 0, 0, 0, 0,
+  9, 0, 0, 19, 28, 6, 15, 0, 0, 0,
+  28, 0, 22, 0, 0, 0, 15, 1, 73, 0,
+  78, 3, 7, 0, 0, 4, 2, 46, 13, 0,
+  0, 32, 107, 4, 2, 0, 4, 83, 44, 32,
+  46, 4, 0, 0, 3, 0, 0, 10, 0, 0,
+  0, 35, 0, 0, 0, 0, 0, 15, 0, 0,
+  0, 0, 0, 24, 0, 0, 0, 32, 0, 0,
+  49, 17, 0, 0, 0, 80, 25, 73, 0, 0,
+  0, 50, 0, 3, 0, 0, 0, 0, 0, 35,
+  49, 0, 61, 9, 0, 0, 3, 17, 57, 9,
+  0, 0, 0, 10, 48, 46, 9, 0, 7, 32,
+  17, 79, 43, 0, 37, 35, 0, 0, 0, 5,
+  31, 0, 49, 67, 11, 1, 0, 0, 15, 0,
+  0, 19, 8, 3, 5, 0, 0, 0, 19, 0,
+  26, 0, 0, 0, 5, 0, 65, 0, 62, 0,
+  2, 0, 16, 0, 16, 11, 0, 0, 0, 0,
+  35, 0, 0, 25, 4, 106, 0, 0, 0, 36,
+  2, 10, 68, 10, 49, 2, 0, 0, 0, 0,
+  0, 0, 0, 2, 0, 9, 0, 0, 0, 0,
+  0, 0, 5, 41, 0, 45, 0, 0, 0, 31,
+  0, 0, 66, 127, 0, 42, 14, 0, 16, 0,
+  2, 0, 0, 0, 48, 0, 110, 32, 0, 9,
+  0, 60, 0, 11, 0, 0, 22, 0, 0, 0,
+  0, 41, 18, 32, 0, 0, 51, 0, 58, 18,
+  81, 0, 0, 0, 0, 0, 0, 12, 11, 0,
+  73, 49, 0, 0, 0, 0, 6, 0, 0, 8,
+  11, 0, 36, 0, 0, 0, 95, 0, 70, 0,
+  20, 0, 1, 0, 0, 0, 8, 0, 11, 0,
+  7, 17, 0, 25, 21, 11, 0, 0, 61, 0,
+  0, 19, 7, 87, 0, 0, 0, 20, 13, 16,
+  69, 0, 0, 19, 0, 0, 0, 0, 0, 18,
+  0, 0, 0, 6, 0, 0, 0, 0, 0, 0,
+  0, 18, 0, 55, 0, 0, 10, 38, 0, 0,
+  71, 103, 0, 69, 0, 0, 31, 9, 0, 0,
+  0, 0, 4, 0, 42, 20, 0, 14, 0, 7,
+  0, 2, 0, 0, 39, 0, 0, 0, 0, 43,
+  31, 45, 9, 0, 36, 0, 50, 45, 79, 24,
+  11, 1, 0, 0, 0, 13, 32, 0, 65, 65,
+  1, 23, 0, 0, 0, 0, 0, 13, 64, 0,
+  7, 0, 0, 0, 59, 0, 45, 0, 6, 0,
+  45, 0, 40, 0, 47, 0, 8, 0, 0, 108,
+  0, 50, 20, 0, 23, 0, 76, 0, 5, 27,
+  31, 30, 12, 0, 0, 17, 12, 30, 55, 0,
+  0, 56, 13, 61, 39, 0, 0, 26, 15, 0,
+  27, 4, 0, 0, 0, 0, 0, 5, 0, 21,
+  0, 47, 11, 0, 10, 19, 0, 0, 54, 49,
+  57, 86, 0, 0, 20, 0, 0, 49, 9, 0,
+  0, 0, 0, 0, 32, 13, 0, 0, 0, 12,
+  0, 0, 51, 32, 0, 0, 0, 19, 65, 67,
+  24, 0, 19, 0, 39, 50, 52, 88, 74, 0,
+  0, 18, 0, 13, 42, 0, 60, 63, 11, 32,
+  0, 0, 0, 0, 14, 25, 123, 40, 2, 0,
+  0, 0, 13, 0, 5, 0, 0, 0, 42, 3,
+  144, 0, 86, 0, 0, 0, 3, 16, 0, 41,
+  1, 0, 4, 6, 70, 0, 0, 11, 25, 55,
+  18, 0, 14, 4, 17, 0, 52, 0, 0, 17,
+  0, 16, 4, 14, 0, 32, 2, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 25, 0, 53,
+  0, 0, 5, 16, 0, 0, 58, 87, 18, 68,
+  0, 0, 15, 25, 0, 19, 0, 0, 0, 0,
+  0, 11, 7, 13, 8, 0, 0, 9, 0, 0,
+  44, 3, 0, 0, 0, 43, 57, 57, 0, 0,
+  32, 0, 31, 33, 74, 29, 25, 0, 0, 0,
+  0, 11, 45, 0, 71, 48, 0, 0, 7, 0,
+  2, 0, 0, 12, 74, 6, 34, 0, 0, 0,
+  67, 0, 49, 0, 0, 0, 48, 9, 63, 0,
+  76, 0, 5, 0, 0, 29, 0, 36, 17, 0,
+  0, 1, 82, 0, 0, 10, 14, 80, 41, 0,
+  22, 8, 10, 0, 47, 0, 0, 23, 0, 13,
+  0, 15, 0, 5, 0, 0, 0, 11, 0, 0,
+  0, 0, 0, 11, 0, 0, 0, 51, 0, 0,
+  23, 16, 0, 0, 35, 72, 21, 74, 0, 0,
+  3, 24, 0, 11, 0, 0, 0, 0, 0, 21,
+  29, 0, 30, 0, 0, 0, 0, 0, 58, 0,
+  0, 0, 0, 30, 56, 60, 4, 0, 25, 0,
+  29, 51, 61, 17, 7, 13, 0, 0, 0, 14,
+  29, 0, 67, 43, 0, 16, 0, 0, 10, 1,
+  0, 7, 54, 13, 18, 0, 0, 0, 34, 0,
+  15, 0, 0, 0, 35, 0, 63, 0, 64, 0,
+  8, 0, 0, 64, 0, 40, 20, 0, 10, 0,
+  63, 0, 7, 15, 12, 65, 48, 6, 31, 34,
+  0, 25, 58, 0, 0, 21, 0, 36, 3, 4,
+  0, 0, 0, 0, 0, 32, 0, 0, 0, 0,
+  0, 11, 0, 0, 0, 41, 0, 0, 21, 22,
+  0, 0, 26, 26, 28, 76, 0, 0, 10, 4,
+  0, 25, 19, 0, 0, 0, 0, 11, 55, 3,
+  50, 0, 0, 0, 0, 0, 62, 0, 0, 0,
+  0, 3, 57, 69, 4, 0, 25, 19, 41, 29,
+  30, 12, 0, 34, 0, 1, 0, 24, 19, 0,
+  63, 30, 0, 19, 0, 0, 12, 0, 3, 1,
+  34, 21, 0, 0, 0, 0, 15, 0, 0, 0,
+  0, 0, 0, 13, 75, 0, 41, 0, 17, 0,
+  0, 19, 0, 49, 12, 0, 0, 25, 85, 2,
+  1, 7, 23, 85, 32, 34, 52, 0, 5, 0,
+  23, 0, 0, 0, 0, 25, 0, 34, 0, 0,
+  0, 0, 0, 25, 0, 0, 0, 0, 0, 23,
+  0, 6, 0, 46, 0, 0, 22, 18, 0, 0,
+  24, 75, 20, 83, 0, 0, 0, 46, 0, 19,
+  0, 0, 0, 0, 0, 30, 41, 0, 59, 0,
+  0, 0, 0, 12, 50, 0, 0, 9, 0, 32,
+  59, 63, 9, 0, 17, 31, 16, 61, 46, 0,
+  20, 36, 0, 0, 0, 9, 42, 0, 48, 63,
+  0, 0, 0, 0, 9, 0, 0, 19, 28, 6,
+  15, 0, 0, 0, 28, 0, 22, 0, 0, 0,
+  15, 1, 73, 0, 78, 3, 7, 0, 0, 4,
+  2, 46, 13, 0, 0, 32, 107, 4, 2, 0,
+  4, 83, 44, 32, 46, 4, 0, 0, 3, 0,
+  0, 10, 0, 0, 0, 35, 0, 0, 0, 0,
+  0, 15, 0, 0, 0, 0, 0, 24, 0, 0,
+  0, 32, 0, 0, 49, 17, 0, 0, 0, 80,
+  25, 73, 0, 0, 0, 50, 0, 3, 0, 0,
+  0, 0, 0, 35, 49, 0, 61, 9, 0, 0,
+  3, 17, 57, 9, 0, 0, 0, 10, 48, 46,
+  9, 0, 7, 32, 17, 79, 43, 0, 37, 35,
+  0, 0, 0, 5, 31, 0, 49, 67, 11, 1,
+  0, 0, 15, 0, 0, 19, 8, 3, 5, 0,
+  0, 0, 19, 0, 26, 0, 0, 0, 5, 0,
+  65, 0, 62, 0, 2, 0, 0, 37, 0, 44,
+  22, 0, 8, 20, 82, 0, 25, 11, 12, 56,
+  55, 36, 59, 22, 0, 12, 31, 0, 0, 0,
+  1, 27, 0, 18, 0, 0, 0, 0, 0, 37,
+  0, 0, 0, 0, 0, 14, 0, 0, 0, 28,
+  0, 0, 38, 1, 0, 0, 0, 23, 0, 87,
+  0, 0, 4, 32, 0, 38, 0, 0, 0, 0,
+  0, 27, 62, 7, 79, 0, 0, 0, 0, 8,
+  73, 0, 0, 19, 6, 1, 28, 74, 0, 0,
+  22, 50, 31, 43, 10, 0, 10, 37, 0, 20,
+  0, 33, 31, 10, 59, 36, 0, 0, 0, 0,
+  17, 0, 0, 13, 9, 1, 0, 0, 0, 0,
+  9, 0, 0, 0, 0, 0, 0, 23, 74, 0,
+  31, 0, 36, 0, 7, 17, 0, 25, 21, 11,
+  0, 0, 61, 0, 0, 19, 7, 87, 0, 0,
+  0, 20, 13, 16, 69, 0, 0, 19, 0, 0,
+  0, 0, 0, 18, 0, 0, 0, 6, 0, 0,
+  0, 0, 0, 0, 0, 18, 0, 55, 0, 0,
+  10, 38, 0, 0, 71, 103, 0, 69, 0, 0,
+  31, 9, 0, 0, 0, 0, 4, 0, 42, 20,
+  0, 14, 0, 7, 0, 2, 0, 0, 39, 0,
+  0, 0, 0, 43, 31, 45, 9, 0, 36, 0,
+  50, 45, 79, 24, 11, 1, 0, 0, 0, 13,
+  32, 0, 65, 65, 1, 23, 0, 0, 0, 0,
+  0, 13, 64, 0, 7, 0, 0, 0, 59, 0,
+  45, 0, 6, 0, 45, 0, 40, 0, 47, 0,
+  8, 0, 0, 108, 0, 50, 20, 0, 23, 0,
+  76, 0, 5, 27, 31, 30, 12, 0, 0, 17,
+  12, 30, 55, 0, 0, 56, 13, 61, 39, 0,
+  0, 26, 15, 0, 27, 4, 0, 0, 0, 0,
+  0, 5, 0, 21, 0, 47, 11, 0, 10, 19,
+  0, 0, 54, 49, 57, 86, 0, 0, 20, 0,
+  0, 49, 9, 0, 0, 0, 0, 0, 32, 13,
+  0, 0, 0, 12, 0, 0, 51, 32, 0, 0,
+  0, 19, 65, 67, 24, 0, 19, 0, 39, 50,
+  52, 88, 74, 0, 0, 18, 0, 13, 42, 0,
+  60, 63, 11, 32, 0, 0, 0, 0, 14, 25,
+  123, 40, 2, 0, 0, 0, 13, 0, 5, 0,
+  0, 0, 42, 3, 144, 0, 86, 0, 0, 0,
+  0, 155, 0, 57, 4, 0, 35, 0, 65, 0,
+  13, 22, 77, 0, 0, 0, 0, 12, 22, 43,
+  12, 0, 0, 61, 29, 33, 73, 13, 3, 0,
+  36, 0, 52, 0, 38, 0, 0, 0, 0, 0,
+  0, 22, 0, 53, 11, 0, 16, 0, 0, 0,
+  43, 52, 47, 51, 11, 17, 36, 0, 0, 49,
+  1, 0, 0, 0, 0, 0, 2, 16, 0, 0,
+  11, 34, 0, 0, 39, 55, 0, 69, 4, 0,
+  37, 56, 49, 10, 11, 0, 0, 58, 72, 93,
+  137, 0, 0, 11, 0, 0, 57, 0, 44, 81,
+  42, 39, 0, 0, 0, 0, 27, 70, 152, 18,
+  4, 0, 17, 10, 0, 0, 0, 0, 0, 0,
+  3, 0, 133, 2, 119, 5, 0, 0, 0, 29,
+  0, 36, 17, 0, 0, 1, 82, 0, 0, 10,
+  14, 80, 41, 0, 22, 8, 10, 0, 47, 0,
+  0, 23, 0, 13, 0, 15, 0, 5, 0, 0,
+  0, 11, 0, 0, 0, 0, 0, 11, 0, 0,
+  0, 51, 0, 0, 23, 16, 0, 0, 35, 72,
+  21, 74, 0, 0, 3, 24, 0, 11, 0, 0,
+  0, 0, 0, 21, 29, 0, 30, 0, 0, 0,
+  0, 0, 58, 0, 0, 0, 0, 30, 56, 60,
+  4, 0, 25, 0, 29, 51, 61, 17, 7, 13,
+  0, 0, 0, 14, 29, 0, 67, 43, 0, 16,
+  0, 0, 10, 1, 0, 7, 54, 13, 18, 0,
+  0, 0, 34, 0, 15, 0, 0, 0, 35, 0,
+  63, 0, 64, 0, 8, 0, 0, 64, 0, 40,
+  20, 0, 10, 0, 63, 0, 7, 15, 12, 65,
+  48, 6, 31, 34, 0, 25, 58, 0, 0, 21,
+  0, 36, 3, 4, 0, 0, 0, 0, 0, 32,
+  0, 0, 0, 0, 0, 11, 0, 0, 0, 41,
+  0, 0, 21, 22, 0, 0, 26, 26, 28, 76,
+  0, 0, 10, 4, 0, 25, 19, 0, 0, 0,
+  0, 11, 55, 3, 50, 0, 0, 0, 0, 0,
+  62, 0, 0, 0, 0, 3, 57, 69, 4, 0,
+  25, 19, 41, 29, 30, 12, 0, 34, 0, 1,
+  0, 24, 19, 0, 63, 30, 0, 19, 0, 0,
+  12, 0, 3, 1, 34, 21, 0, 0, 0, 0,
+  15, 0, 0, 0, 0, 0, 0, 13, 75, 0,
+  41, 0, 17, 0, 0, 151, 1, 57, 8, 0,
+  17, 0, 42, 0, 26, 0, 19, 37, 38, 18,
+  29, 7, 6, 53, 10, 0, 0, 24, 1, 37,
+  15, 7, 0, 0, 0, 0, 46, 5, 0, 0,
+  0, 0, 0, 1, 0, 2, 0, 21, 0, 0,
+  21, 42, 0, 0, 40, 0, 12, 89, 0, 0,
+  18, 1, 0, 44, 24, 0, 0, 0, 0, 0,
+  73, 21, 53, 0, 0, 0, 0, 8, 68, 12,
+  0, 35, 0, 18, 49, 62, 21, 11, 30, 33,
+  16, 49, 19, 13, 53, 22, 0, 17, 0, 5,
+  44, 0, 24, 80, 3, 46, 0, 0, 12, 0,
+  22, 12, 52, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 89, 0, 51, 0,
+  16, 1, 0, 4, 2, 46, 13, 0, 0, 32,
+  107, 4, 2, 0, 4, 83, 44, 32, 46, 4,
+  0, 0, 3, 0, 0, 10, 0, 0, 0, 35,
+  0, 0, 0, 0, 0, 15, 0, 0, 0, 0,
+  0, 24, 0, 0, 0, 32, 0, 0, 49, 17,
+  0, 0, 0, 80, 25, 73, 0, 0, 0, 50,
+  0, 3, 0, 0, 0, 0, 0, 35, 49, 0,
+  61, 9, 0, 0, 3, 17, 57, 9, 0, 0,
+  0, 10, 48, 46, 9, 0, 7, 32, 17, 79,
+  43, 0, 37, 35, 0, 0, 0, 5, 31, 0,
+  49, 67, 11, 1, 0, 0, 15, 0, 0, 19,
+  8, 3, 5, 0, 0, 0, 19, 0, 26, 0,
+  0, 0, 5, 0, 65, 0, 62, 0, 2, 0,
+  0, 37, 0, 44, 22, 0, 8, 20, 82, 0,
+  25, 11, 12, 56, 55, 36, 59, 22, 0, 12,
+  31, 0, 0, 0, 1, 27, 0, 18, 0, 0,
+  0, 0, 0, 37, 0, 0, 0, 0, 0, 14,
+  0, 0, 0, 28, 0, 0, 38, 1, 0, 0,
+  0, 23, 0, 87, 0, 0, 4, 32, 0, 38,
+  0, 0, 0, 0, 0, 27, 62, 7, 79, 0,
+  0, 0, 0, 8, 73, 0, 0, 19, 6, 1,
+  28, 74, 0, 0, 22, 50, 31, 43, 10, 0,
+  10, 37, 0, 20, 0, 33, 31, 10, 59, 36,
+  0, 0, 0, 0, 17, 0, 0, 13, 9, 1,
+  0, 0, 0, 0, 9, 0, 0, 0, 0, 0,
+  0, 23, 74, 0, 31, 0, 36, 0, 0, 74,
+  18, 48, 36, 0, 9, 0, 60, 0, 36, 0,
+  0, 63, 66, 33, 53, 1, 1, 40, 5, 0,
+  0, 0, 0, 29, 0, 0, 0, 0, 0, 0,
+  0, 33, 0, 0, 0, 0, 0, 13, 0, 0,
+  0, 7, 0, 0, 40, 19, 0, 0, 0, 0,
+  0, 107, 0, 0, 12, 52, 0, 31, 0, 27,
+  0, 0, 0, 19, 66, 8, 85, 0, 0, 0,
+  0, 0, 65, 0, 0, 12, 15, 13, 23, 55,
+  0, 0, 38, 70, 22, 57, 6, 0, 10, 41,
+  0, 20, 0, 27, 34, 9, 25, 65, 0, 0,
+  0, 0, 11, 0, 0, 0, 15, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  46, 0, 22, 0, 42, 0, 0, 108, 0, 50,
+  20, 0, 23, 0, 76, 0, 5, 27, 31, 30,
+  12, 0, 0, 17, 12, 30, 55, 0, 0, 56,
+  13, 61, 39, 0, 0, 26, 15, 0, 27, 4,
+  0, 0, 0, 0, 0, 5, 0, 21, 0, 47,
+  11, 0, 10, 19, 0, 0, 54, 49, 57, 86,
+  0, 0, 20, 0, 0, 49, 9, 0, 0, 0,
+  0, 0, 32, 13, 0, 0, 0, 12, 0, 0,
+  51, 32, 0, 0, 0, 19, 65, 67, 24, 0,
+  19, 0, 39, 50, 52, 88, 74, 0, 0, 18,
+  0, 13, 42, 0, 60, 63, 11, 32, 0, 0,
+  0, 0, 14, 25, 123, 40, 2, 0, 0, 0,
+  13, 0, 5, 0, 0, 0, 42, 3, 144, 0,
+  86, 0, 0, 0, 0, 155, 0, 57, 4, 0,
+  35, 0, 65, 0, 13, 22, 77, 0, 0, 0,
+  0, 12, 22, 43, 12, 0, 0, 61, 29, 33,
+  73, 13, 3, 0, 36, 0, 52, 0, 38, 0,
+  0, 0, 0, 0, 0, 22, 0, 53, 11, 0,
+  16, 0, 0, 0, 43, 52, 47, 51, 11, 17,
+  36, 0, 0, 49, 1, 0, 0, 0, 0, 0,
+  2, 16, 0, 0, 11, 34, 0, 0, 39, 55,
+  0, 69, 4, 0, 37, 56, 49, 10, 11, 0,
+  0, 58, 72, 93, 137, 0, 0, 11, 0, 0,
+  57, 0, 44, 81, 42, 39, 0, 0, 0, 0,
+  27, 70, 152, 18, 4, 0, 17, 10, 0, 0,
+  0, 0, 0, 0, 3, 0, 133, 2, 119, 5,
+  0, 0, 21, 77, 0, 54, 0, 57, 1, 0,
+  24, 0, 0, 9, 43, 0, 0, 0, 0, 20,
+  47, 27, 0, 27, 1, 0, 0, 0, 69, 0,
+  0, 0, 4, 19, 15, 0, 32, 49, 0, 0,
+  3, 0, 0, 7, 0, 34, 8, 10, 16, 0,
+  0, 0, 3, 45, 0, 0, 93, 35, 51, 0,
+  0, 0, 0, 53, 20, 0, 103, 0, 0, 43,
+  0, 68, 175, 29, 22, 0, 0, 35, 0, 61,
+  4, 6, 0, 0, 64, 5, 21, 0, 0, 19,
+  51, 0, 81, 0, 0, 0, 7, 0, 55, 0,
+  12, 95, 28, 106, 1, 0, 0, 0, 4, 67,
+  71, 0, 2, 16, 0, 39, 0, 0, 0, 0,
+  25, 0, 0, 0, 0, 18, 65, 17, 0, 0,
+  0, 64, 0, 40, 20, 0, 10, 0, 63, 0,
+  7, 15, 12, 65, 48, 6, 31, 34, 0, 25,
+  58, 0, 0, 21, 0, 36, 3, 4, 0, 0,
+  0, 0, 0, 32, 0, 0, 0, 0, 0, 11,
+  0, 0, 0, 41, 0, 0, 21, 22, 0, 0,
+  26, 26, 28, 76, 0, 0, 10, 4, 0, 25,
+  19, 0, 0, 0, 0, 11, 55, 3, 50, 0,
+  0, 0, 0, 0, 62, 0, 0, 0, 0, 3,
+  57, 69, 4, 0, 25, 19, 41, 29, 30, 12,
+  0, 34, 0, 1, 0, 24, 19, 0, 63, 30,
+  0, 19, 0, 0, 12, 0, 3, 1, 34, 21,
+  0, 0, 0, 0, 15, 0, 0, 0, 0, 0,
+  0, 13, 75, 0, 41, 0, 17, 0, 0, 151,
+  1, 57, 8, 0, 17, 0, 42, 0, 26, 0,
+  19, 37, 38, 18, 29, 7, 6, 53, 10, 0,
+  0, 24, 1, 37, 15, 7, 0, 0, 0, 0,
+  46, 5, 0, 0, 0, 0, 0, 1, 0, 2,
+  0, 21, 0, 0, 21, 42, 0, 0, 40, 0,
+  12, 89, 0, 0, 18, 1, 0, 44, 24, 0,
+  0, 0, 0, 0, 73, 21, 53, 0, 0, 0,
+  0, 8, 68, 12, 0, 35, 0, 18, 49, 62,
+  21, 11, 30, 33, 16, 49, 19, 13, 53, 22,
+  0, 17, 0, 5, 44, 0, 24, 80, 3, 46,
+  0, 0, 12, 0, 22, 12, 52, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  89, 0, 51, 0, 16, 1, 6, 145, 0, 66,
+  0, 25, 0, 0, 52, 0, 6, 0, 69, 0,
+  0, 0, 0, 5, 33, 32, 0, 0, 14, 32,
+  3, 0, 70, 0, 0, 0, 0, 0, 77, 0,
+  13, 38, 0, 0, 0, 0, 0, 17, 0, 19,
+  0, 15, 48, 19, 0, 17, 5, 25, 0, 35,
+  17, 0, 54, 0, 0, 16, 0, 0, 0, 0,
+  16, 0, 16, 19, 0, 1, 65, 17, 3, 0,
+  34, 29, 0, 94, 0, 16, 0, 0, 90, 39,
+  0, 18, 0, 41, 51, 18, 99, 0, 0, 0,
+  0, 0, 61, 0, 18, 99, 42, 59, 0, 0,
+  0, 10, 57, 44, 87, 0, 0, 0, 0, 36,
+  0, 0, 0, 0, 5, 0, 3, 0, 48, 0,
+  39, 0, 0, 46, 0, 37, 0, 44, 22, 0,
+  8, 20, 82, 0, 25, 11, 12, 56, 55, 36,
+  59, 22, 0, 12, 31, 0, 0, 0, 1, 27,
+  0, 18, 0, 0, 0, 0, 0, 37, 0, 0,
+  0, 0, 0, 14, 0, 0, 0, 28, 0, 0,
+  38, 1, 0, 0, 0, 23, 0, 87, 0, 0,
+  4, 32, 0, 38, 0, 0, 0, 0, 0, 27,
+  62, 7, 79, 0, 0, 0, 0, 8, 73, 0,
+  0, 19, 6, 1, 28, 74, 0, 0, 22, 50,
+  31, 43, 10, 0, 10, 37, 0, 20, 0, 33,
+  31, 10, 59, 36, 0, 0, 0, 0, 17, 0,
+  0, 13, 9, 1, 0, 0, 0, 0, 9, 0,
+  0, 0, 0, 0, 0, 23, 74, 0, 31, 0,
+  36, 0, 0, 74, 18, 48, 36, 0, 9, 0,
+  60, 0, 36, 0, 0, 63, 66, 33, 53, 1,
+  1, 40, 5, 0, 0, 0, 0, 29, 0, 0,
+  0, 0, 0, 0, 0, 33, 0, 0, 0, 0,
+  0, 13, 0, 0, 0, 7, 0, 0, 40, 19,
+  0, 0, 0, 0, 0, 107, 0, 0, 12, 52,
+  0, 31, 0, 27, 0, 0, 0, 19, 66, 8,
+  85, 0, 0, 0, 0, 0, 65, 0, 0, 12,
+  15, 13, 23, 55, 0, 0, 38, 70, 22, 57,
+  6, 0, 10, 41, 0, 20, 0, 27, 34, 9,
+  25, 65, 0, 0, 0, 0, 11, 0, 0, 0,
+  15, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 46, 0, 22, 0, 42, 0,
+  0, 120, 19, 74, 27, 0, 31, 0, 61, 0,
+  8, 0, 21, 27, 26, 43, 32, 22, 11, 48,
+  0, 0, 11, 13, 20, 2, 39, 1, 0, 0,
+  0, 0, 45, 5, 15, 2, 0, 0, 0, 0,
+  0, 0, 0, 21, 0, 27, 87, 36, 0, 0,
+  16, 0, 0, 39, 0, 0, 30, 0, 0, 50,
+  0, 22, 0, 0, 0, 0, 32, 15, 38, 0,
+  0, 0, 27, 0, 82, 16, 0, 44, 0, 0,
+  23, 10, 32, 10, 15, 51, 24, 38, 8, 39,
+  22, 24, 0, 47, 0, 0, 15, 0, 42, 41,
+  18, 5, 0, 0, 5, 0, 39, 13, 35, 22,
+  0, 0, 0, 45, 0, 0, 0, 0, 9, 0,
+  0, 0, 49, 0, 6, 0, 21, 9, 0, 155,
+  0, 57, 4, 0, 35, 0, 65, 0, 13, 22,
+  77, 0, 0, 0, 0, 12, 22, 43, 12, 0,
+  0, 61, 29, 33, 73, 13, 3, 0, 36, 0,
+  52, 0, 38, 0, 0, 0, 0, 0, 0, 22,
+  0, 53, 11, 0, 16, 0, 0, 0, 43, 52,
+  47, 51, 11, 17, 36, 0, 0, 49, 1, 0,
+  0, 0, 0, 0, 2, 16, 0, 0, 11, 34,
+  0, 0, 39, 55, 0, 69, 4, 0, 37, 56,
+  49, 10, 11, 0, 0, 58, 72, 93, 137, 0,
+  0, 11, 0, 0, 57, 0, 44, 81, 42, 39,
+  0, 0, 0, 0, 27, 70, 152, 18, 4, 0,
+  17, 10, 0, 0, 0, 0, 0, 0, 3, 0,
+  133, 2, 119, 5, 0, 0, 21, 77, 0, 54,
+  0, 57, 1, 0, 24, 0, 0, 9, 43, 0,
+  0, 0, 0, 20, 47, 27, 0, 27, 1, 0,
+  0, 0, 69, 0, 0, 0, 4, 19, 15, 0,
+  32, 49, 0, 0, 3, 0, 0, 7, 0, 34,
+  8, 10, 16, 0, 0, 0, 3, 45, 0, 0,
+  93, 35, 51, 0, 0, 0, 0, 53, 20, 0,
+  103, 0, 0, 43, 0, 68, 175, 29, 22, 0,
+  0, 35, 0, 61, 4, 6, 0, 0, 64, 5,
+  21, 0, 0, 19, 51, 0, 81, 0, 0, 0,
+  7, 0, 55, 0, 12, 95, 28, 106, 1, 0,
+  0, 0, 4, 67, 71, 0, 2, 16, 0, 39,
+  0, 0, 0, 0, 25, 0, 0, 0, 0, 18,
+  65, 17, 0, 0, 0, 0, 0, 25, 0, 135,
+  0, 7, 42, 0, 0, 4, 0, 6, 0, 0,
+  0, 25, 13, 0, 41, 106, 15, 0, 0, 0,
+  0, 1, 0, 0, 0, 1, 9, 0, 0, 82,
+  0, 40, 0, 0, 45, 0, 0, 46, 0, 80,
+  0, 4, 0, 0, 0, 52, 0, 0, 133, 36,
+  44, 0, 57, 0, 0, 92, 42, 0, 155, 0,
+  0, 30, 0, 77, 196, 0, 59, 34, 0, 31,
+  0, 16, 9, 0, 0, 0, 35, 0, 0, 0,
+  1, 0, 11, 0, 0, 92, 0, 0, 27, 0,
+  0, 0, 7, 76, 78, 108, 0, 0, 0, 0,
+  0, 30, 0, 0, 0, 38, 0, 95, 0, 0,
+  0, 0, 52, 0, 0, 0, 0, 0, 21, 0,
+  0, 6, 0, 151, 1, 57, 8, 0, 17, 0,
+  42, 0, 26, 0, 19, 37, 38, 18, 29, 7,
+  6, 53, 10, 0, 0, 24, 1, 37, 15, 7,
+  0, 0, 0, 0, 46, 5, 0, 0, 0, 0,
+  0, 1, 0, 2, 0, 21, 0, 0, 21, 42,
+  0, 0, 40, 0, 12, 89, 0, 0, 18, 1,
+  0, 44, 24, 0, 0, 0, 0, 0, 73, 21,
+  53, 0, 0, 0, 0, 8, 68, 12, 0, 35,
+  0, 18, 49, 62, 21, 11, 30, 33, 16, 49,
+  19, 13, 53, 22, 0, 17, 0, 5, 44, 0,
+  24, 80, 3, 46, 0, 0, 12, 0, 22, 12,
+  52, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 89, 0, 51, 0, 16, 1,
+  6, 145, 0, 66, 0, 25, 0, 0, 52, 0,
+  6, 0, 69, 0, 0, 0, 0, 5, 33, 32,
+  0, 0, 14, 32, 3, 0, 70, 0, 0, 0,
+  0, 0, 77, 0, 13, 38, 0, 0, 0, 0,
+  0, 17, 0, 19, 0, 15, 48, 19, 0, 17,
+  5, 25, 0, 35, 17, 0, 54, 0, 0, 16,
+  0, 0, 0, 0, 16, 0, 16, 19, 0, 1,
+  65, 17, 3, 0, 34, 29, 0, 94, 0, 16,
+  0, 0, 90, 39, 0, 18, 0, 41, 51, 18,
+  99, 0, 0, 0, 0, 0, 61, 0, 18, 99,
+  42, 59, 0, 0, 0, 10, 57, 44, 87, 0,
+  0, 0, 0, 36, 0, 0, 0, 0, 5, 0,
+  3, 0, 48, 0, 39, 0, 0, 46, 58, 21,
+  0, 68, 2, 105, 0, 4, 38, 0, 0, 0,
+  40, 0, 0, 0, 2, 21, 35, 0, 0, 90,
+  13, 0, 0, 0, 31, 0, 9, 0, 0, 31,
+  3, 0, 67, 72, 9, 0, 27, 0, 20, 14,
+  0, 28, 22, 53, 41, 0, 0, 0, 0, 61,
+  0, 0, 135, 38, 37, 0, 7, 0, 0, 47,
+  34, 0, 96, 0, 0, 31, 0, 47, 198, 6,
+  55, 0, 0, 0, 0, 35, 0, 0, 0, 0,
+  77, 27, 31, 0, 1, 1, 38, 0, 0, 15,
+  0, 0, 17, 0, 39, 0, 26, 71, 33, 77,
+  0, 0, 0, 0, 6, 46, 5, 0, 19, 40,
+  0, 88, 0, 0, 0, 0, 55, 0, 0, 0,
+  0, 0, 28, 0, 0, 16, 0, 74, 18, 48,
+  36, 0, 9, 0, 60, 0, 36, 0, 0, 63,
+  66, 33, 53, 1, 1, 40, 5, 0, 0, 0,
+  0, 29, 0, 0, 0, 0, 0, 0, 0, 33,
+  0, 0, 0, 0, 0, 13, 0, 0, 0, 7,
+  0, 0, 40, 19, 0, 0, 0, 0, 0, 107,
+  0, 0, 12, 52, 0, 31, 0, 27, 0, 0,
+  0, 19, 66, 8, 85, 0, 0, 0, 0, 0,
+  65, 0, 0, 12, 15, 13, 23, 55, 0, 0,
+  38, 70, 22, 57, 6, 0, 10, 41, 0, 20,
+  0, 27, 34, 9, 25, 65, 0, 0, 0, 0,
+  11, 0, 0, 0, 15, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 46, 0,
+  22, 0, 42, 0, 0, 120, 19, 74, 27, 0,
+  31, 0, 61, 0, 8, 0, 21, 27, 26, 43,
+  32, 22, 11, 48, 0, 0, 11, 13, 20, 2,
+  39, 1, 0, 0, 0, 0, 45, 5, 15, 2,
+  0, 0, 0, 0, 0, 0, 0, 21, 0, 27,
+  87, 36, 0, 0, 16, 0, 0, 39, 0, 0,
+  30, 0, 0, 50, 0, 22, 0, 0, 0, 0,
+  32, 15, 38, 0, 0, 0, 27, 0, 82, 16,
+  0, 44, 0, 0, 23, 10, 32, 10, 15, 51,
+  24, 38, 8, 39, 22, 24, 0, 47, 0, 0,
+  15, 0, 42, 41, 18, 5, 0, 0, 5, 0,
+  39, 13, 35, 22, 0, 0, 0, 45, 0, 0,
+  0, 0, 9, 0, 0, 0, 49, 0, 6, 0,
+  21, 9, 64, 56, 7, 47, 47, 23, 0, 2,
+  27, 0, 0, 0, 42, 8, 0, 3, 0, 0,
+  56, 18, 0, 16, 26, 0, 2, 0, 57, 0,
+  1, 54, 0, 27, 23, 0, 74, 44, 54, 0,
+  12, 0, 0, 9, 0, 16, 14, 30, 64, 22,
+  0, 0, 0, 0, 0, 18, 39, 0, 31, 0,
+  0, 0, 0, 41, 29, 0, 11, 5, 0, 39,
+  0, 10, 75, 0, 74, 0, 24, 4, 0, 36,
+  30, 0, 0, 0, 49, 39, 40, 0, 0, 51,
+  36, 6, 0, 6, 0, 16, 0, 0, 38, 0,
+  41, 42, 30, 45, 15, 0, 0, 0, 5, 61,
+  41, 0, 5, 11, 0, 65, 38, 0, 0, 0,
+  29, 0, 0, 0, 0, 0, 0, 0, 8, 29,
+  21, 77, 0, 54, 0, 57, 1, 0, 24, 0,
+  0, 9, 43, 0, 0, 0, 0, 20, 47, 27,
+  0, 27, 1, 0, 0, 0, 69, 0, 0, 0,
+  4, 19, 15, 0, 32, 49, 0, 0, 3, 0,
+  0, 7, 0, 34, 8, 10, 16, 0, 0, 0,
+  3, 45, 0, 0, 93, 35, 51, 0, 0, 0,
+  0, 53, 20, 0, 103, 0, 0, 43, 0, 68,
+  175, 29, 22, 0, 0, 35, 0, 61, 4, 6,
+  0, 0, 64, 5, 21, 0, 0, 19, 51, 0,
+  81, 0, 0, 0, 7, 0, 55, 0, 12, 95,
+  28, 106, 1, 0, 0, 0, 4, 67, 71, 0,
+  2, 16, 0, 39, 0, 0, 0, 0, 25, 0,
+  0, 0, 0, 18, 65, 17, 0, 0, 0, 0,
+  0, 25, 0, 135, 0, 7, 42, 0, 0, 4,
+  0, 6, 0, 0, 0, 25, 13, 0, 41, 106,
+  15, 0, 0, 0, 0, 1, 0, 0, 0, 1,
+  9, 0, 0, 82, 0, 40, 0, 0, 45, 0,
+  0, 46, 0, 80, 0, 4, 0, 0, 0, 52,
+  0, 0, 133, 36, 44, 0, 57, 0, 0, 92,
+  42, 0, 155, 0, 0, 30, 0, 77, 196, 0,
+  59, 34, 0, 31, 0, 16, 9, 0, 0, 0,
+  35, 0, 0, 0, 1, 0, 11, 0, 0, 92,
+  0, 0, 27, 0, 0, 0, 7, 76, 78, 108,
+  0, 0, 0, 0, 0, 30, 0, 0, 0, 38,
+  0, 95, 0, 0, 0, 0, 52, 0, 0, 0,
+  0, 0, 21, 0, 0, 6, 0, 28, 0, 8,
+  0, 24, 24, 29, 104, 12, 0, 37, 106, 0,
+  0, 105, 62, 22, 0, 0, 41, 62, 0, 12,
+  2, 0, 0, 43, 0, 0, 0, 0, 76, 0,
+  33, 0, 0, 91, 0, 53, 32, 0, 4, 39,
+  5, 115, 2, 34, 0, 36, 0, 56, 16, 0,
+  56, 0, 6, 0, 36, 0, 0, 14, 0, 21,
+  0, 0, 0, 0, 27, 0, 37, 0, 47, 52,
+  0, 14, 8, 31, 0, 0, 8, 0, 29, 0,
+  0, 10, 11, 0, 20, 0, 0, 68, 0, 34,
+  0, 0, 0, 0, 26, 84, 90, 0, 0, 0,
+  22, 0, 15, 31, 0, 34, 0, 30, 0, 52,
+  0, 0, 0, 0, 60, 0, 39, 0, 79, 0,
+  69, 0, 34, 16, 6, 145, 0, 66, 0, 25,
+  0, 0, 52, 0, 6, 0, 69, 0, 0, 0,
+  0, 5, 33, 32, 0, 0, 14, 32, 3, 0,
+  70, 0, 0, 0, 0, 0, 77, 0, 13, 38,
+  0, 0, 0, 0, 0, 17, 0, 19, 0, 15,
+  48, 19, 0, 17, 5, 25, 0, 35, 17, 0,
+  54, 0, 0, 16, 0, 0, 0, 0, 16, 0,
+  16, 19, 0, 1, 65, 17, 3, 0, 34, 29,
+  0, 94, 0, 16, 0, 0, 90, 39, 0, 18,
+  0, 41, 51, 18, 99, 0, 0, 0, 0, 0,
+  61, 0, 18, 99, 42, 59, 0, 0, 0, 10,
+  57, 44, 87, 0, 0, 0, 0, 36, 0, 0,
+  0, 0, 5, 0, 3, 0, 48, 0, 39, 0,
+  0, 46, 58, 21, 0, 68, 2, 105, 0, 4,
+  38, 0, 0, 0, 40, 0, 0, 0, 2, 21,
+  35, 0, 0, 90, 13, 0, 0, 0, 31, 0,
+  9, 0, 0, 31, 3, 0, 67, 72, 9, 0,
+  27, 0, 20, 14, 0, 28, 22, 53, 41, 0,
+  0, 0, 0, 61, 0, 0, 135, 38, 37, 0,
+  7, 0, 0, 47, 34, 0, 96, 0, 0, 31,
+  0, 47, 198, 6, 55, 0, 0, 0, 0, 35,
+  0, 0, 0, 0, 77, 27, 31, 0, 1, 1,
+  38, 0, 0, 15, 0, 0, 17, 0, 39, 0,
+  26, 71, 33, 77, 0, 0, 0, 0, 6, 46,
+  5, 0, 19, 40, 0, 88, 0, 0, 0, 0,
+  55, 0, 0, 0, 0, 0, 28, 0, 0, 16,
+  0, 0, 0, 15, 0, 83, 0, 21, 90, 39,
+  0, 48, 26, 0, 0, 60, 13, 28, 16, 0,
+  25, 81, 1, 0, 0, 0, 1, 44, 17, 19,
+  0, 35, 60, 0, 78, 36, 79, 138, 7, 0,
+  76, 0, 2, 0, 0, 129, 0, 4, 0, 11,
+  0, 4, 0, 0, 138, 0, 2, 0, 27, 0,
+  0, 90, 14, 2, 90, 0, 0, 39, 0, 61,
+  111, 0, 118, 35, 0, 31, 35, 22, 25, 0,
+  0, 0, 0, 27, 0, 0, 12, 25, 0, 0,
+  0, 91, 0, 7, 15, 0, 6, 0, 0, 89,
+  131, 18, 0, 0, 39, 0, 0, 48, 0, 0,
+  1, 67, 0, 57, 0, 0, 0, 0, 75, 0,
+  0, 0, 0, 0, 0, 0, 75, 51, 0, 120,
+  19, 74, 27, 0, 31, 0, 61, 0, 8, 0,
+  21, 27, 26, 43, 32, 22, 11, 48, 0, 0,
+  11, 13, 20, 2, 39, 1, 0, 0, 0, 0,
+  45, 5, 15, 2, 0, 0, 0, 0, 0, 0,
+  0, 21, 0, 27, 87, 36, 0, 0, 16, 0,
+  0, 39, 0, 0, 30, 0, 0, 50, 0, 22,
+  0, 0, 0, 0, 32, 15, 38, 0, 0, 0,
+  27, 0, 82, 16, 0, 44, 0, 0, 23, 10,
+  32, 10, 15, 51, 24, 38, 8, 39, 22, 24,
+  0, 47, 0, 0, 15, 0, 42, 41, 18, 5,
+  0, 0, 5, 0, 39, 13, 35, 22, 0, 0,
+  0, 45, 0, 0, 0, 0, 9, 0, 0, 0,
+  49, 0, 6, 0, 21, 9, 64, 56, 7, 47,
+  47, 23, 0, 2, 27, 0, 0, 0, 42, 8,
+  0, 3, 0, 0, 56, 18, 0, 16, 26, 0,
+  2, 0, 57, 0, 1, 54, 0, 27, 23, 0,
+  74, 44, 54, 0, 12, 0, 0, 9, 0, 16,
+  14, 30, 64, 22, 0, 0, 0, 0, 0, 18,
+  39, 0, 31, 0, 0, 0, 0, 41, 29, 0,
+  11, 5, 0, 39, 0, 10, 75, 0, 74, 0,
+  24, 4, 0, 36, 30, 0, 0, 0, 49, 39,
+  40, 0, 0, 51, 36, 6, 0, 6, 0, 16,
+  0, 0, 38, 0, 41, 42, 30, 45, 15, 0,
+  0, 0, 5, 61, 41, 0, 5, 11, 0, 65,
+  38, 0, 0, 0, 29, 0, 0, 0, 0, 0,
+  0, 0, 8, 29, 59, 0, 21, 13, 0, 41,
+  0, 2, 0, 43, 0, 19, 0, 48, 0, 0,
+  0, 0, 56, 0, 3, 89, 5, 0, 0, 0,
+  21, 5, 0, 99, 0, 11, 0, 0, 67, 44,
+  117, 91, 15, 0, 39, 0, 3, 0, 0, 12,
+  0, 18, 5, 1, 0, 35, 0, 23, 119, 0,
+  0, 4, 0, 0, 0, 65, 91, 49, 82, 33,
+  0, 21, 0, 118, 80, 20, 83, 0, 0, 0,
+  0, 0, 100, 0, 0, 0, 15, 22, 26, 0,
+  0, 49, 63, 0, 0, 18, 0, 0, 55, 0,
+  41, 0, 0, 54, 58, 26, 28, 0, 0, 0,
+  0, 29, 0, 0, 19, 18, 0, 23, 56, 7,
+  0, 0, 19, 0, 0, 0, 0, 0, 0, 24,
+  61, 73, 0, 0, 0, 25, 0, 135, 0, 7,
+  42, 0, 0, 4, 0, 6, 0, 0, 0, 25,
+  13, 0, 41, 106, 15, 0, 0, 0, 0, 1,
+  0, 0, 0, 1, 9, 0, 0, 82, 0, 40,
+  0, 0, 45, 0, 0, 46, 0, 80, 0, 4,
+  0, 0, 0, 52, 0, 0, 133, 36, 44, 0,
+  57, 0, 0, 92, 42, 0, 155, 0, 0, 30,
+  0, 77, 196, 0, 59, 34, 0, 31, 0, 16,
+  9, 0, 0, 0, 35, 0, 0, 0, 1, 0,
+  11, 0, 0, 92, 0, 0, 27, 0, 0, 0,
+  7, 76, 78, 108, 0, 0, 0, 0, 0, 30,
+  0, 0, 0, 38, 0, 95, 0, 0, 0, 0,
+  52, 0, 0, 0, 0, 0, 21, 0, 0, 6,
+  0, 28, 0, 8, 0, 24, 24, 29, 104, 12,
+  0, 37, 106, 0, 0, 105, 62, 22, 0, 0,
+  41, 62, 0, 12, 2, 0, 0, 43, 0, 0,
+  0, 0, 76, 0, 33, 0, 0, 91, 0, 53,
+  32, 0, 4, 39, 5, 115, 2, 34, 0, 36,
+  0, 56, 16, 0, 56, 0, 6, 0, 36, 0,
+  0, 14, 0, 21, 0, 0, 0, 0, 27, 0,
+  37, 0, 47, 52, 0, 14, 8, 31, 0, 0,
+  8, 0, 29, 0, 0, 10, 11, 0, 20, 0,
+  0, 68, 0, 34, 0, 0, 0, 0, 26, 84,
+  90, 0, 0, 0, 22, 0, 15, 31, 0, 34,
+  0, 30, 0, 52, 0, 0, 0, 0, 60, 0,
+  39, 0, 79, 0, 69, 0, 34, 16, 0, 39,
+  58, 0, 0, 0, 35, 20, 76, 0, 11, 39,
+  97, 0, 0, 94, 63, 17, 0, 0, 0, 47,
+  11, 21, 63, 0, 0, 58, 0, 0, 0, 24,
+  97, 0, 27, 0, 0, 89, 26, 22, 38, 4,
+  46, 33, 23, 117, 42, 0, 0, 22, 0, 0,
+  14, 0, 32, 0, 5, 0, 47, 0, 0, 49,
+  0, 19, 0, 0, 17, 1, 30, 0, 0, 0,
+  56, 43, 10, 31, 22, 65, 0, 0, 6, 0,
+  19, 88, 0, 42, 0, 0, 0, 23, 0, 11,
+  0, 31, 0, 0, 0, 0, 0, 85, 98, 0,
+  0, 0, 13, 0, 31, 29, 0, 24, 0, 19,
+  0, 5, 0, 0, 0, 12, 70, 0, 0, 0,
+  32, 0, 63, 0, 24, 34, 58, 21, 0, 68,
+  2, 105, 0, 4, 38, 0, 0, 0, 40, 0,
+  0, 0, 2, 21, 35, 0, 0, 90, 13, 0,
+  0, 0, 31, 0, 9, 0, 0, 31, 3, 0,
+  67, 72, 9, 0, 27, 0, 20, 14, 0, 28,
+  22, 53, 41, 0, 0, 0, 0, 61, 0, 0,
+  135, 38, 37, 0, 7, 0, 0, 47, 34, 0,
+  96, 0, 0, 31, 0, 47, 198, 6, 55, 0,
+  0, 0, 0, 35, 0, 0, 0, 0, 77, 27,
+  31, 0, 1, 1, 38, 0, 0, 15, 0, 0,
+  17, 0, 39, 0, 26, 71, 33, 77, 0, 0,
+  0, 0, 6, 46, 5, 0, 19, 40, 0, 88,
+  0, 0, 0, 0, 55, 0, 0, 0, 0, 0,
+  28, 0, 0, 16, 0, 0, 0, 15, 0, 83,
+  0, 21, 90, 39, 0, 48, 26, 0, 0, 60,
+  13, 28, 16, 0, 25, 81, 1, 0, 0, 0,
+  1, 44, 17, 19, 0, 35, 60, 0, 78, 36,
+  79, 138, 7, 0, 76, 0, 2, 0, 0, 129,
+  0, 4, 0, 11, 0, 4, 0, 0, 138, 0,
+  2, 0, 27, 0, 0, 90, 14, 2, 90, 0,
+  0, 39, 0, 61, 111, 0, 118, 35, 0, 31,
+  35, 22, 25, 0, 0, 0, 0, 27, 0, 0,
+  12, 25, 0, 0, 0, 91, 0, 7, 15, 0,
+  6, 0, 0, 89, 131, 18, 0, 0, 39, 0,
+  0, 48, 0, 0, 1, 67, 0, 57, 0, 0,
+  0, 0, 75, 0, 0, 0, 0, 0, 0, 0,
+  75, 51, 0, 0, 95, 9, 0, 0, 0, 24,
+  67, 28, 0, 54, 35, 44, 0, 52, 0, 15,
+  0, 0, 0, 58, 28, 9, 0, 0, 21, 48,
+  6, 84, 0, 37, 76, 0, 22, 0, 105, 123,
+  0, 0, 100, 0, 38, 0, 0, 109, 0, 0,
+  0, 11, 0, 0, 0, 0, 96, 0, 19, 0,
+  47, 0, 0, 83, 53, 15, 66, 0, 7, 34,
+  0, 90, 0, 0, 122, 30, 0, 21, 7, 0,
+  14, 0, 0, 2, 0, 89, 0, 17, 21, 0,
+  35, 0, 0, 36, 0, 3, 0, 0, 0, 0,
+  0, 59, 137, 0, 0, 0, 0, 0, 0, 52,
+  0, 3, 30, 17, 0, 0, 80, 0, 22, 0,
+  52, 0, 0, 0, 0, 0, 0, 14, 61, 73,
+  64, 56, 7, 47, 47, 23, 0, 2, 27, 0,
+  0, 0, 42, 8, 0, 3, 0, 0, 56, 18,
+  0, 16, 26, 0, 2, 0, 57, 0, 1, 54,
+  0, 27, 23, 0, 74, 44, 54, 0, 12, 0,
+  0, 9, 0, 16, 14, 30, 64, 22, 0, 0,
+  0, 0, 0, 18, 39, 0, 31, 0, 0, 0,
+  0, 41, 29, 0, 11, 5, 0, 39, 0, 10,
+  75, 0, 74, 0, 24, 4, 0, 36, 30, 0,
+  0, 0, 49, 39, 40, 0, 0, 51, 36, 6,
+  0, 6, 0, 16, 0, 0, 38, 0, 41, 42,
+  30, 45, 15, 0, 0, 0, 5, 61, 41, 0,
+  5, 11, 0, 65, 38, 0, 0, 0, 29, 0,
+  0, 0, 0, 0, 0, 0, 8, 29, 59, 0,
+  21, 13, 0, 41, 0, 2, 0, 43, 0, 19,
+  0, 48, 0, 0, 0, 0, 56, 0, 3, 89,
+  5, 0, 0, 0, 21, 5, 0, 99, 0, 11,
+  0, 0, 67, 44, 117, 91, 15, 0, 39, 0,
+  3, 0, 0, 12, 0, 18, 5, 1, 0, 35,
+  0, 23, 119, 0, 0, 4, 0, 0, 0, 65,
+  91, 49, 82, 33, 0, 21, 0, 118, 80, 20,
+  83, 0, 0, 0, 0, 0, 100, 0, 0, 0,
+  15, 22, 26, 0, 0, 49, 63, 0, 0, 18,
+  0, 0, 55, 0, 41, 0, 0, 54, 58, 26,
+  28, 0, 0, 0, 0, 29, 0, 0, 19, 18,
+  0, 23, 56, 7, 0, 0, 19, 0, 0, 0,
+  0, 0, 0, 24, 61, 73, 32, 0, 66, 36,
+  9, 0, 0, 0, 5, 21, 0, 26, 30, 124,
+  0, 0, 0, 0, 23, 0, 28, 52, 0, 3,
+  0, 0, 50, 28, 0, 103, 0, 4, 0, 0,
+  39, 0, 82, 66, 0, 0, 35, 0, 2, 0,
+  0, 22, 7, 0, 0, 0, 0, 70, 0, 21,
+  74, 0, 0, 14, 10, 0, 0, 32, 91, 24,
+  64, 1, 0, 2, 0, 95, 0, 13, 72, 0,
+  0, 0, 0, 0, 86, 0, 0, 56, 11, 19,
+  0, 0, 12, 13, 141, 0, 0, 19, 0, 0,
+  4, 0, 38, 0, 0, 38, 31, 0, 0, 0,
+  0, 0, 0, 56, 51, 0, 69, 0, 0, 0,
+  107, 0, 36, 0, 0, 32, 38, 0, 0, 0,
+  0, 37, 0, 81, 0, 28, 0, 8, 0, 24,
+  24, 29, 104, 12, 0, 37, 106, 0, 0, 105,
+  62, 22, 0, 0, 41, 62, 0, 12, 2, 0,
+  0, 43, 0, 0, 0, 0, 76, 0, 33, 0,
+  0, 91, 0, 53, 32, 0, 4, 39, 5, 115,
+  2, 34, 0, 36, 0, 56, 16, 0, 56, 0,
+  6, 0, 36, 0, 0, 14, 0, 21, 0, 0,
+  0, 0, 27, 0, 37, 0, 47, 52, 0, 14,
+  8, 31, 0, 0, 8, 0, 29, 0, 0, 10,
+  11, 0, 20, 0, 0, 68, 0, 34, 0, 0,
+  0, 0, 26, 84, 90, 0, 0, 0, 22, 0,
+  15, 31, 0, 34, 0, 30, 0, 52, 0, 0,
+  0, 0, 60, 0, 39, 0, 79, 0, 69, 0,
+  34, 16, 0, 39, 58, 0, 0, 0, 35, 20,
+  76, 0, 11, 39, 97, 0, 0, 94, 63, 17,
+  0, 0, 0, 47, 11, 21, 63, 0, 0, 58,
+  0, 0, 0, 24, 97, 0, 27, 0, 0, 89,
+  26, 22, 38, 4, 46, 33, 23, 117, 42, 0,
+  0, 22, 0, 0, 14, 0, 32, 0, 5, 0,
+  47, 0, 0, 49, 0, 19, 0, 0, 17, 1,
+  30, 0, 0, 0, 56, 43, 10, 31, 22, 65,
+  0, 0, 6, 0, 19, 88, 0, 42, 0, 0,
+  0, 23, 0, 11, 0, 31, 0, 0, 0, 0,
+  0, 85, 98, 0, 0, 0, 13, 0, 31, 29,
+  0, 24, 0, 19, 0, 5, 0, 0, 0, 12,
+  70, 0, 0, 0, 32, 0, 63, 0, 24, 34,
+  0, 10, 0, 0, 0, 0, 0, 1, 32, 2,
+  16, 56, 0, 30, 0, 9, 3, 0, 2, 0,
+  1, 27, 71, 20, 5, 0, 0, 23, 0, 18,
+  0, 0, 30, 0, 15, 0, 59, 84, 34, 0,
+  85, 0, 0, 5, 0, 98, 39, 10, 0, 0,
+  0, 0, 0, 0, 57, 0, 55, 0, 96, 0,
+  0, 81, 9, 12, 28, 9, 50, 46, 29, 21,
+  0, 0, 85, 58, 7, 94, 37, 18, 0, 0,
+  0, 22, 0, 74, 0, 50, 11, 36, 0, 0,
+  0, 84, 19, 16, 0, 0, 0, 0, 17, 49,
+  89, 0, 0, 0, 0, 27, 5, 0, 0, 3,
+  0, 9, 0, 9, 21, 75, 0, 33, 64, 0,
+  0, 0, 0, 0, 0, 0, 0, 41, 0, 0,
+  0, 15, 0, 83, 0, 21, 90, 39, 0, 48,
+  26, 0, 0, 60, 13, 28, 16, 0, 25, 81,
+  1, 0, 0, 0, 1, 44, 17, 19, 0, 35,
+  60, 0, 78, 36, 79, 138, 7, 0, 76, 0,
+  2, 0, 0, 129, 0, 4, 0, 11, 0, 4,
+  0, 0, 138, 0, 2, 0, 27, 0, 0, 90,
+  14, 2, 90, 0, 0, 39, 0, 61, 111, 0,
+  118, 35, 0, 31, 35, 22, 25, 0, 0, 0,
+  0, 27, 0, 0, 12, 25, 0, 0, 0, 91,
+  0, 7, 15, 0, 6, 0, 0, 89, 131, 18,
+  0, 0, 39, 0, 0, 48, 0, 0, 1, 67,
+  0, 57, 0, 0, 0, 0, 75, 0, 0, 0,
+  0, 0, 0, 0, 75, 51, 0, 0, 95, 9,
+  0, 0, 0, 24, 67, 28, 0, 54, 35, 44,
+  0, 52, 0, 15, 0, 0, 0, 58, 28, 9,
+  0, 0, 21, 48, 6, 84, 0, 37, 76, 0,
+  22, 0, 105, 123, 0, 0, 100, 0, 38, 0,
+  0, 109, 0, 0, 0, 11, 0, 0, 0, 0,
+  96, 0, 19, 0, 47, 0, 0, 83, 53, 15,
+  66, 0, 7, 34, 0, 90, 0, 0, 122, 30,
+  0, 21, 7, 0, 14, 0, 0, 2, 0, 89,
+  0, 17, 21, 0, 35, 0, 0, 36, 0, 3,
+  0, 0, 0, 0, 0, 59, 137, 0, 0, 0,
+  0, 0, 0, 52, 0, 3, 30, 17, 0, 0,
+  80, 0, 22, 0, 52, 0, 0, 0, 0, 0,
+  0, 14, 61, 73, 19, 3, 82, 25, 7, 0,
+  0, 19, 0, 0, 0, 50, 24, 124, 0, 0,
+  0, 0, 0, 0, 16, 66, 70, 4, 0, 0,
+  12, 4, 0, 88, 7, 3, 0, 13, 0, 0,
+  74, 8, 0, 0, 84, 0, 0, 15, 17, 36,
+  17, 22, 4, 0, 9, 49, 0, 0, 86, 0,
+  46, 0, 71, 0, 0, 47, 100, 0, 96, 0,
+  0, 47, 0, 116, 0, 23, 90, 0, 0, 33,
+  0, 0, 23, 0, 0, 55, 0, 76, 0, 1,
+  45, 31, 68, 0, 0, 0, 10, 0, 0, 0,
+  0, 0, 0, 29, 67, 0, 0, 0, 0, 4,
+  0, 42, 0, 0, 54, 0, 0, 0, 124, 74,
+  44, 0, 25, 0, 0, 0, 0, 25, 0, 22,
+  0, 56, 59, 0, 21, 13, 0, 41, 0, 2,
+  0, 43, 0, 19, 0, 48, 0, 0, 0, 0,
+  56, 0, 3, 89, 5, 0, 0, 0, 21, 5,
+  0, 99, 0, 11, 0, 0, 67, 44, 117, 91,
+  15, 0, 39, 0, 3, 0, 0, 12, 0, 18,
+  5, 1, 0, 35, 0, 23, 119, 0, 0, 4,
+  0, 0, 0, 65, 91, 49, 82, 33, 0, 21,
+  0, 118, 80, 20, 83, 0, 0, 0, 0, 0,
+  100, 0, 0, 0, 15, 22, 26, 0, 0, 49,
+  63, 0, 0, 18, 0, 0, 55, 0, 41, 0,
+  0, 54, 58, 26, 28, 0, 0, 0, 0, 29,
+  0, 0, 19, 18, 0, 23, 56, 7, 0, 0,
+  19, 0, 0, 0, 0, 0, 0, 24, 61, 73,
+  32, 0, 66, 36, 9, 0, 0, 0, 5, 21,
+  0, 26, 30, 124, 0, 0, 0, 0, 23, 0,
+  28, 52, 0, 3, 0, 0, 50, 28, 0, 103,
+  0, 4, 0, 0, 39, 0, 82, 66, 0, 0,
+  35, 0, 2, 0, 0, 22, 7, 0, 0, 0,
+  0, 70, 0, 21, 74, 0, 0, 14, 10, 0,
+  0, 32, 91, 24, 64, 1, 0, 2, 0, 95,
+  0, 13, 72, 0, 0, 0, 0, 0, 86, 0,
+  0, 56, 11, 19, 0, 0, 12, 13, 141, 0,
+  0, 19, 0, 0, 4, 0, 38, 0, 0, 38,
+  31, 0, 0, 0, 0, 0, 0, 56, 51, 0,
+  69, 0, 0, 0, 107, 0, 36, 0, 0, 32,
+  38, 0, 0, 0, 0, 37, 0, 81, 51, 46,
+  25, 77, 65, 9, 0, 0, 20, 0, 19, 0,
+  51, 118, 0, 0, 0, 0, 16, 7, 12, 11,
+  0, 26, 0, 0, 55, 19, 0, 69, 20, 7,
+  22, 0, 56, 0, 0, 0, 0, 0, 0, 35,
+  0, 0, 31, 31, 30, 33, 0, 0, 23, 35,
+  0, 14, 38, 0, 27, 20, 0, 10, 0, 19,
+  19, 8, 0, 0, 0, 0, 2, 0, 0, 41,
+  51, 0, 0, 22, 0, 0, 35, 8, 0, 53,
+  41, 20, 0, 0, 35, 12, 95, 14, 26, 0,
+  0, 30, 0, 0, 70, 0, 0, 50, 0, 20,
+  0, 0, 0, 25, 0, 43, 127, 0, 82, 0,
+  12, 0, 31, 0, 14, 0, 0, 8, 49, 0,
+  2, 15, 10, 13, 0, 93, 0, 39, 58, 0,
+  0, 0, 35, 20, 76, 0, 11, 39, 97, 0,
+  0, 94, 63, 17, 0, 0, 0, 47, 11, 21,
+  63, 0, 0, 58, 0, 0, 0, 24, 97, 0,
+  27, 0, 0, 89, 26, 22, 38, 4, 46, 33,
+  23, 117, 42, 0, 0, 22, 0, 0, 14, 0,
+  32, 0, 5, 0, 47, 0, 0, 49, 0, 19,
+  0, 0, 17, 1, 30, 0, 0, 0, 56, 43,
+  10, 31, 22, 65, 0, 0, 6, 0, 19, 88,
+  0, 42, 0, 0, 0, 23, 0, 11, 0, 31,
+  0, 0, 0, 0, 0, 85, 98, 0, 0, 0,
+  13, 0, 31, 29, 0, 24, 0, 19, 0, 5,
+  0, 0, 0, 12, 70, 0, 0, 0, 32, 0,
+  63, 0, 24, 34, 0, 10, 0, 0, 0, 0,
+  0, 1, 32, 2, 16, 56, 0, 30, 0, 9,
+  3, 0, 2, 0, 1, 27, 71, 20, 5, 0,
+  0, 23, 0, 18, 0, 0, 30, 0, 15, 0,
+  59, 84, 34, 0, 85, 0, 0, 5, 0, 98,
+  39, 10, 0, 0, 0, 0, 0, 0, 57, 0,
+  55, 0, 96, 0, 0, 81, 9, 12, 28, 9,
+  50, 46, 29, 21, 0, 0, 85, 58, 7, 94,
+  37, 18, 0, 0, 0, 22, 0, 74, 0, 50,
+  11, 36, 0, 0, 0, 84, 19, 16, 0, 0,
+  0, 0, 17, 49, 89, 0, 0, 0, 0, 27,
+  5, 0, 0, 3, 0, 9, 0, 9, 21, 75,
+  0, 33, 64, 0, 0, 0, 0, 0, 0, 0,
+  0, 41, 4, 18, 11, 6, 0, 0, 0, 0,
+  60, 44, 0, 0, 0, 54, 0, 0, 0, 29,
+  17, 0, 3, 11, 34, 17, 0, 0, 58, 48,
+  0, 0, 0, 0, 53, 0, 0, 0, 74, 109,
+  0, 0, 46, 0, 0, 0, 0, 59, 0, 51,
+  0, 23, 0, 0, 0, 0, 78, 7, 34, 8,
+  0, 0, 0, 52, 29, 14, 74, 2, 53, 17,
+  8, 144, 9, 0, 46, 89, 0, 57, 27, 0,
+  12, 0, 0, 0, 31, 87, 0, 30, 0, 43,
+  20, 0, 0, 171, 0, 0, 22, 0, 7, 0,
+  0, 57, 123, 33, 0, 0, 0, 0, 0, 2,
+  0, 0, 0, 24, 0, 10, 20, 24, 0, 0,
+  14, 0, 0, 0, 0, 0, 0, 4, 58, 62,
+  0, 0, 95, 9, 0, 0, 0, 24, 67, 28,
+  0, 54, 35, 44, 0, 52, 0, 15, 0, 0,
+  0, 58, 28, 9, 0, 0, 21, 48, 6, 84,
+  0, 37, 76, 0, 22, 0, 105, 123, 0, 0,
+  100, 0, 38, 0, 0, 109, 0, 0, 0, 11,
+  0, 0, 0, 0, 96, 0, 19, 0, 47, 0,
+  0, 83, 53, 15, 66, 0, 7, 34, 0, 90,
+  0, 0, 122, 30, 0, 21, 7, 0, 14, 0,
+  0, 2, 0, 89, 0, 17, 21, 0, 35, 0,
+  0, 36, 0, 3, 0, 0, 0, 0, 0, 59,
+  137, 0, 0, 0, 0, 0, 0, 52, 0, 3,
+  30, 17, 0, 0, 80, 0, 22, 0, 52, 0,
+  0, 0, 0, 0, 0, 14, 61, 73, 19, 3,
+  82, 25, 7, 0, 0, 19, 0, 0, 0, 50,
+  24, 124, 0, 0, 0, 0, 0, 0, 16, 66,
+  70, 4, 0, 0, 12, 4, 0, 88, 7, 3,
+  0, 13, 0, 0, 74, 8, 0, 0, 84, 0,
+  0, 15, 17, 36, 17, 22, 4, 0, 9, 49,
+  0, 0, 86, 0, 46, 0, 71, 0, 0, 47,
+  100, 0, 96, 0, 0, 47, 0, 116, 0, 23,
+  90, 0, 0, 33, 0, 0, 23, 0, 0, 55,
+  0, 76, 0, 1, 45, 31, 68, 0, 0, 0,
+  10, 0, 0, 0, 0, 0, 0, 29, 67, 0,
+  0, 0, 0, 4, 0, 42, 0, 0, 54, 0,
+  0, 0, 124, 74, 44, 0, 25, 0, 0, 0,
+  0, 25, 0, 22, 0, 56, 83, 83, 12, 72,
+  44, 15, 0, 0, 20, 0, 22, 0, 23, 126,
+  0, 0, 0, 0, 39, 0, 24, 37, 34, 21,
+  0, 0, 35, 11, 0, 34, 52, 81, 0, 0,
+  0, 0, 0, 26, 0, 0, 0, 1, 0, 0,
+  1, 18, 42, 71, 0, 0, 11, 40, 0, 7,
+  106, 0, 38, 4, 10, 0, 0, 34, 61, 26,
+  20, 0, 27, 21, 0, 98, 0, 49, 51, 0,
+  0, 28, 54, 0, 44, 0, 0, 48, 15, 60,
+  0, 1, 2, 45, 68, 0, 14, 0, 0, 25,
+  0, 0, 81, 0, 11, 15, 12, 121, 4, 0,
+  0, 16, 0, 68, 74, 0, 26, 0, 17, 1,
+  24, 87, 0, 0, 20, 2, 10, 0, 0, 0,
+  0, 22, 0, 87, 32, 0, 66, 36, 9, 0,
+  0, 0, 5, 21, 0, 26, 30, 124, 0, 0,
+  0, 0, 23, 0, 28, 52, 0, 3, 0, 0,
+  50, 28, 0, 103, 0, 4, 0, 0, 39, 0,
+  82, 66, 0, 0, 35, 0, 2, 0, 0, 22,
+  7, 0, 0, 0, 0, 70, 0, 21, 74, 0,
+  0, 14, 10, 0, 0, 32, 91, 24, 64, 1,
+  0, 2, 0, 95, 0, 13, 72, 0, 0, 0,
+  0, 0, 86, 0, 0, 56, 11, 19, 0, 0,
+  12, 13, 141, 0, 0, 19, 0, 0, 4, 0,
+  38, 0, 0, 38, 31, 0, 0, 0, 0, 0,
+  0, 56, 51, 0, 69, 0, 0, 0, 107, 0,
+  36, 0, 0, 32, 38, 0, 0, 0, 0, 37,
+  0, 81, 51, 46, 25, 77, 65, 9, 0, 0,
+  20, 0, 19, 0, 51, 118, 0, 0, 0, 0,
+  16, 7, 12, 11, 0, 26, 0, 0, 55, 19,
+  0, 69, 20, 7, 22, 0, 56, 0, 0, 0,
+  0, 0, 0, 35, 0, 0, 31, 31, 30, 33,
+  0, 0, 23, 35, 0, 14, 38, 0, 27, 20,
+  0, 10, 0, 19, 19, 8, 0, 0, 0, 0,
+  2, 0, 0, 41, 51, 0, 0, 22, 0, 0,
+  35, 8, 0, 53, 41, 20, 0, 0, 35, 12,
+  95, 14, 26, 0, 0, 30, 0, 0, 70, 0,
+  0, 50, 0, 20, 0, 0, 0, 25, 0, 43,
+  127, 0, 82, 0, 12, 0, 31, 0, 14, 0,
+  0, 8, 49, 0, 2, 15, 10, 13, 0, 93,
+  42, 127, 15, 99, 80, 43, 0, 0, 43, 0,
+  32, 0, 35, 29, 0, 0, 11, 0, 41, 15,
+  0, 0, 0, 47, 24, 0, 52, 29, 0, 37,
+  5, 49, 69, 0, 20, 0, 0, 0, 0, 0,
+  0, 17, 0, 6, 19, 56, 44, 46, 0, 7,
+  4, 0, 0, 17, 32, 0, 50, 2, 0, 29,
+  21, 24, 0, 8, 0, 0, 52, 4, 27, 0,
+  0, 21, 45, 4, 6, 45, 10, 2, 0, 2,
+  0, 19, 40, 73, 0, 17, 5, 38, 21, 49,
+  107, 0, 0, 49, 0, 0, 90, 0, 23, 57,
+  7, 99, 1, 0, 25, 33, 41, 62, 122, 0,
+  7, 22, 36, 0, 0, 0, 0, 0, 0, 0,
+  13, 0, 43, 0, 45, 1, 13, 74, 0, 10,
+  0, 0, 0, 0, 0, 1, 32, 2, 16, 56,
+  0, 30, 0, 9, 3, 0, 2, 0, 1, 27,
+  71, 20, 5, 0, 0, 23, 0, 18, 0, 0,
+  30, 0, 15, 0, 59, 84, 34, 0, 85, 0,
+  0, 5, 0, 98, 39, 10, 0, 0, 0, 0,
+  0, 0, 57, 0, 55, 0, 96, 0, 0, 81,
+  9, 12, 28, 9, 50, 46, 29, 21, 0, 0,
+  85, 58, 7, 94, 37, 18, 0, 0, 0, 22,
+  0, 74, 0, 50, 11, 36, 0, 0, 0, 84,
+  19, 16, 0, 0, 0, 0, 17, 49, 89, 0,
+  0, 0, 0, 27, 5, 0, 0, 3, 0, 9,
+  0, 9, 21, 75, 0, 33, 64, 0, 0, 0,
+  0, 0, 0, 0, 0, 41, 4, 18, 11, 6,
+  0, 0, 0, 0, 60, 44, 0, 0, 0, 54,
+  0, 0, 0, 29, 17, 0, 3, 11, 34, 17,
+  0, 0, 58, 48, 0, 0, 0, 0, 53, 0,
+  0, 0, 74, 109, 0, 0, 46, 0, 0, 0,
+  0, 59, 0, 51, 0, 23, 0, 0, 0, 0,
+  78, 7, 34, 8, 0, 0, 0, 52, 29, 14,
+  74, 2, 53, 17, 8, 144, 9, 0, 46, 89,
+  0, 57, 27, 0, 12, 0, 0, 0, 31, 87,
+  0, 30, 0, 43, 20, 0, 0, 171, 0, 0,
+  22, 0, 7, 0, 0, 57, 123, 33, 0, 0,
+  0, 0, 0, 2, 0, 0, 0, 24, 0, 10,
+  20, 24, 0, 0, 14, 0, 0, 0, 0, 0,
+  0, 4, 58, 62, 28, 0, 51, 0, 0, 127,
+  0, 0, 28, 13, 0, 0, 0, 82, 0, 0,
+  9, 29, 31, 0, 0, 85, 28, 32, 0, 0,
+  13, 55, 0, 0, 0, 43, 0, 0, 0, 17,
+  44, 93, 0, 0, 24, 0, 15, 0, 0, 32,
+  0, 29, 0, 35, 0, 77, 0, 0, 138, 0,
+  12, 0, 0, 0, 0, 64, 0, 0, 81, 0,
+  9, 6, 12, 125, 8, 0, 33, 55, 0, 39,
+  22, 0, 0, 0, 0, 0, 28, 82, 0, 10,
+  0, 46, 0, 0, 0, 123, 0, 0, 55, 0,
+  11, 0, 0, 88, 63, 49, 0, 0, 27, 0,
+  0, 10, 0, 6, 1, 11, 0, 0, 9, 35,
+  24, 0, 11, 0, 0, 0, 0, 0, 0, 3,
+  9, 79, 19, 3, 82, 25, 7, 0, 0, 19,
+  0, 0, 0, 50, 24, 124, 0, 0, 0, 0,
+  0, 0, 16, 66, 70, 4, 0, 0, 12, 4,
+  0, 88, 7, 3, 0, 13, 0, 0, 74, 8,
+  0, 0, 84, 0, 0, 15, 17, 36, 17, 22,
+  4, 0, 9, 49, 0, 0, 86, 0, 46, 0,
+  71, 0, 0, 47, 100, 0, 96, 0, 0, 47,
+  0, 116, 0, 23, 90, 0, 0, 33, 0, 0,
+  23, 0, 0, 55, 0, 76, 0, 1, 45, 31,
+  68, 0, 0, 0, 10, 0, 0, 0, 0, 0,
+  0, 29, 67, 0, 0, 0, 0, 4, 0, 42,
+  0, 0, 54, 0, 0, 0, 124, 74, 44, 0,
+  25, 0, 0, 0, 0, 25, 0, 22, 0, 56,
+  83, 83, 12, 72, 44, 15, 0, 0, 20, 0,
+  22, 0, 23, 126, 0, 0, 0, 0, 39, 0,
+  24, 37, 34, 21, 0, 0, 35, 11, 0, 34,
+  52, 81, 0, 0, 0, 0, 0, 26, 0, 0,
+  0, 1, 0, 0, 1, 18, 42, 71, 0, 0,
+  11, 40, 0, 7, 106, 0, 38, 4, 10, 0,
+  0, 34, 61, 26, 20, 0, 27, 21, 0, 98,
+  0, 49, 51, 0, 0, 28, 54, 0, 44, 0,
+  0, 48, 15, 60, 0, 1, 2, 45, 68, 0,
+  14, 0, 0, 25, 0, 0, 81, 0, 11, 15,
+  12, 121, 4, 0, 0, 16, 0, 68, 74, 0,
+  26, 0, 17, 1, 24, 87, 0, 0, 20, 2,
+  10, 0, 0, 0, 0, 22, 0, 87, 35, 0,
+  20, 65, 14, 232, 0, 0, 1, 0, 0, 0,
+  0, 21, 0, 0, 0, 33, 62, 0, 0, 113,
+  15, 0, 0, 0, 0, 6, 0, 17, 8, 99,
+  0, 0, 0, 33, 0, 40, 0, 0, 0, 0,
+  0, 0, 0, 58, 44, 47, 7, 4, 0, 38,
+  0, 0, 142, 0, 48, 0, 21, 0, 27, 92,
+  17, 0, 115, 0, 0, 40, 0, 96, 83, 63,
+  62, 0, 0, 35, 43, 0, 0, 0, 0, 0,
+  46, 65, 0, 0, 0, 31, 0, 0, 7, 7,
+  0, 0, 70, 0, 52, 0, 0, 9, 17, 116,
+  2, 0, 0, 5, 18, 17, 0, 0, 0, 39,
+  0, 0, 0, 45, 36, 0, 13, 16, 0, 19,
+  0, 0, 0, 15, 0, 44, 51, 46, 25, 77,
+  65, 9, 0, 0, 20, 0, 19, 0, 51, 118,
+  0, 0, 0, 0, 16, 7, 12, 11, 0, 26,
+  0, 0, 55, 19, 0, 69, 20, 7, 22, 0,
+  56, 0, 0, 0, 0, 0, 0, 35, 0, 0,
+  31, 31, 30, 33, 0, 0, 23, 35, 0, 14,
+  38, 0, 27, 20, 0, 10, 0, 19, 19, 8,
+  0, 0, 0, 0, 2, 0, 0, 41, 51, 0,
+  0, 22, 0, 0, 35, 8, 0, 53, 41, 20,
+  0, 0, 35, 12, 95, 14, 26, 0, 0, 30,
+  0, 0, 70, 0, 0, 50, 0, 20, 0, 0,
+  0, 25, 0, 43, 127, 0, 82, 0, 12, 0,
+  31, 0, 14, 0, 0, 8, 49, 0, 2, 15,
+  10, 13, 0, 93, 42, 127, 15, 99, 80, 43,
+  0, 0, 43, 0, 32, 0, 35, 29, 0, 0,
+  11, 0, 41, 15, 0, 0, 0, 47, 24, 0,
+  52, 29, 0, 37, 5, 49, 69, 0, 20, 0,
+  0, 0, 0, 0, 0, 17, 0, 6, 19, 56,
+  44, 46, 0, 7, 4, 0, 0, 17, 32, 0,
+  50, 2, 0, 29, 21, 24, 0, 8, 0, 0,
+  52, 4, 27, 0, 0, 21, 45, 4, 6, 45,
+  10, 2, 0, 2, 0, 19, 40, 73, 0, 17,
+  5, 38, 21, 49, 107, 0, 0, 49, 0, 0,
+  90, 0, 23, 57, 7, 99, 1, 0, 25, 33,
+  41, 62, 122, 0, 7, 22, 36, 0, 0, 0,
+  0, 0, 0, 0, 13, 0, 43, 0, 45, 1,
+  13, 74, 17, 8, 86, 68, 23, 217, 0, 0,
+  29, 0, 0, 0, 32, 0, 0, 0, 31, 18,
+  66, 0, 0, 112, 15, 8, 7, 0, 0, 35,
+  0, 72, 0, 82, 0, 0, 0, 30, 0, 0,
+  1, 0, 0, 19, 0, 19, 0, 50, 59, 42,
+  0, 14, 0, 45, 0, 0, 97, 0, 62, 0,
+  33, 0, 0, 70, 0, 0, 53, 0, 0, 26,
+  12, 6, 27, 25, 76, 0, 0, 26, 25, 0,
+  0, 18, 0, 0, 77, 83, 0, 0, 0, 18,
+  0, 4, 54, 0, 0, 0, 24, 0, 25, 0,
+  15, 39, 25, 35, 17, 0, 0, 31, 47, 29,
+  0, 0, 0, 45, 0, 0, 0, 0, 38, 0,
+  3, 0, 0, 1, 0, 22, 25, 0, 0, 20,
+  4, 18, 11, 6, 0, 0, 0, 0, 60, 44,
+  0, 0, 0, 54, 0, 0, 0, 29, 17, 0,
+  3, 11, 34, 17, 0, 0, 58, 48, 0, 0,
+  0, 0, 53, 0, 0, 0, 74, 109, 0, 0,
+  46, 0, 0, 0, 0, 59, 0, 51, 0, 23,
+  0, 0, 0, 0, 78, 7, 34, 8, 0, 0,
+  0, 52, 29, 14, 74, 2, 53, 17, 8, 144,
+  9, 0, 46, 89, 0, 57, 27, 0, 12, 0,
+  0, 0, 31, 87, 0, 30, 0, 43, 20, 0,
+  0, 171, 0, 0, 22, 0, 7, 0, 0, 57,
+  123, 33, 0, 0, 0, 0, 0, 2, 0, 0,
+  0, 24, 0, 10, 20, 24, 0, 0, 14, 0,
+  0, 0, 0, 0, 0, 4, 58, 62, 28, 0,
+  51, 0, 0, 127, 0, 0, 28, 13, 0, 0,
+  0, 82, 0, 0, 9, 29, 31, 0, 0, 85,
+  28, 32, 0, 0, 13, 55, 0, 0, 0, 43,
+  0, 0, 0, 17, 44, 93, 0, 0, 24, 0,
+  15, 0, 0, 32, 0, 29, 0, 35, 0, 77,
+  0, 0, 138, 0, 12, 0, 0, 0, 0, 64,
+  0, 0, 81, 0, 9, 6, 12, 125, 8, 0,
+  33, 55, 0, 39, 22, 0, 0, 0, 0, 0,
+  28, 82, 0, 10, 0, 46, 0, 0, 0, 123,
+  0, 0, 55, 0, 11, 0, 0, 88, 63, 49,
+  0, 0, 27, 0, 0, 10, 0, 6, 1, 11,
+  0, 0, 9, 35, 24, 0, 11, 0, 0, 0,
+  0, 0, 0, 3, 9, 79, 0, 0, 30, 0,
+  26, 161, 0, 0, 0, 0, 0, 0, 49, 60,
+  0, 0, 11, 55, 0, 0, 7, 16, 0, 50,
+  0, 0, 0, 0, 0, 35, 21, 0, 0, 13,
+  0, 0, 0, 55, 0, 3, 0, 20, 0, 22,
+  0, 12, 34, 22, 0, 0, 13, 103, 4, 0,
+  17, 0, 10, 0, 46, 0, 0, 0, 0, 0,
+  54, 0, 0, 2, 0, 4, 0, 34, 24, 5,
+  0, 40, 0, 0, 0, 10, 0, 0, 18, 36,
+  19, 0, 31, 36, 38, 0, 0, 22, 13, 0,
+  4, 0, 0, 0, 1, 46, 1, 0, 0, 0,
+  0, 10, 0, 22, 0, 25, 23, 0, 0, 0,
+  5, 29, 102, 47, 32, 3, 54, 0, 0, 0,
+  37, 15, 0, 14, 83, 83, 12, 72, 44, 15,
+  0, 0, 20, 0, 22, 0, 23, 126, 0, 0,
+  0, 0, 39, 0, 24, 37, 34, 21, 0, 0,
+  35, 11, 0, 34, 52, 81, 0, 0, 0, 0,
+  0, 26, 0, 0, 0, 1, 0, 0, 1, 18,
+  42, 71, 0, 0, 11, 40, 0, 7, 106, 0,
+  38, 4, 10, 0, 0, 34, 61, 26, 20, 0,
+  27, 21, 0, 98, 0, 49, 51, 0, 0, 28,
+  54, 0, 44, 0, 0, 48, 15, 60, 0, 1,
+  2, 45, 68, 0, 14, 0, 0, 25, 0, 0,
+  81, 0, 11, 15, 12, 121, 4, 0, 0, 16,
+  0, 68, 74, 0, 26, 0, 17, 1, 24, 87,
+  0, 0, 20, 2, 10, 0, 0, 0, 0, 22,
+  0, 87, 35, 0, 20, 65, 14, 232, 0, 0,
+  1, 0, 0, 0, 0, 21, 0, 0, 0, 33,
+  62, 0, 0, 113, 15, 0, 0, 0, 0, 6,
+  0, 17, 8, 99, 0, 0, 0, 33, 0, 40,
+  0, 0, 0, 0, 0, 0, 0, 58, 44, 47,
+  7, 4, 0, 38, 0, 0, 142, 0, 48, 0,
+  21, 0, 27, 92, 17, 0, 115, 0, 0, 40,
+  0, 96, 83, 63, 62, 0, 0, 35, 43, 0,
+  0, 0, 0, 0, 46, 65, 0, 0, 0, 31,
+  0, 0, 7, 7, 0, 0, 70, 0, 52, 0,
+  0, 9, 17, 116, 2, 0, 0, 5, 18, 17,
+  0, 0, 0, 39, 0, 0, 0, 45, 36, 0,
+  13, 16, 0, 19, 0, 0, 0, 15, 0, 44,
+  0, 0, 0, 5, 19, 184, 0, 0, 0, 0,
+  0, 0, 30, 14, 0, 24, 4, 50, 5, 0,
+  21, 0, 0, 62, 18, 19, 0, 0, 0, 10,
+  18, 0, 0, 34, 0, 4, 0, 24, 0, 24,
+  0, 55, 0, 16, 0, 17, 43, 43, 0, 20,
+  0, 38, 14, 0, 0, 0, 9, 0, 19, 12,
+  5, 26, 0, 0, 6, 0, 0, 22, 22, 0,
+  30, 56, 37, 1, 2, 80, 0, 0, 0, 42,
+  0, 0, 13, 12, 24, 0, 22, 14, 2, 28,
+  1, 67, 43, 9, 35, 30, 0, 0, 7, 25,
+  0, 0, 0, 0, 0, 0, 0, 6, 0, 17,
+  0, 1, 0, 13, 0, 7, 81, 29, 34, 0,
+  48, 9, 42, 0, 38, 19, 0, 0, 42, 127,
+  15, 99, 80, 43, 0, 0, 43, 0, 32, 0,
+  35, 29, 0, 0, 11, 0, 41, 15, 0, 0,
+  0, 47, 24, 0, 52, 29, 0, 37, 5, 49,
+  69, 0, 20, 0, 0, 0, 0, 0, 0, 17,
+  0, 6, 19, 56, 44, 46, 0, 7, 4, 0,
+  0, 17, 32, 0, 50, 2, 0, 29, 21, 24,
+  0, 8, 0, 0, 52, 4, 27, 0, 0, 21,
+  45, 4, 6, 45, 10, 2, 0, 2, 0, 19,
+  40, 73, 0, 17, 5, 38, 21, 49, 107, 0,
+  0, 49, 0, 0, 90, 0, 23, 57, 7, 99,
+  1, 0, 25, 33, 41, 62, 122, 0, 7, 22,
+  36, 0, 0, 0, 0, 0, 0, 0, 13, 0,
+  43, 0, 45, 1, 13, 74, 17, 8, 86, 68,
+  23, 217, 0, 0, 29, 0, 0, 0, 32, 0,
+  0, 0, 31, 18, 66, 0, 0, 112, 15, 8,
+  7, 0, 0, 35, 0, 72, 0, 82, 0, 0,
+  0, 30, 0, 0, 1, 0, 0, 19, 0, 19,
+  0, 50, 59, 42, 0, 14, 0, 45, 0, 0,
+  97, 0, 62, 0, 33, 0, 0, 70, 0, 0,
+  53, 0, 0, 26, 12, 6, 27, 25, 76, 0,
+  0, 26, 25, 0, 0, 18, 0, 0, 77, 83,
+  0, 0, 0, 18, 0, 4, 54, 0, 0, 0,
+  24, 0, 25, 0, 15, 39, 25, 35, 17, 0,
+  0, 31, 47, 29, 0, 0, 0, 45, 0, 0,
+  0, 0, 38, 0, 3, 0, 0, 1, 0, 22,
+  25, 0, 0, 20, 0, 0, 0, 0, 1, 125,
+  0, 0, 0, 0, 0, 0, 59, 8, 0, 44,
+  12, 40, 18, 0, 40, 6, 0, 49, 0, 0,
+  0, 0, 0, 14, 40, 0, 0, 17, 0, 8,
+  0, 16, 0, 48, 35, 47, 0, 33, 1, 0,
+  7, 27, 0, 35, 0, 77, 28, 0, 14, 0,
+  38, 0, 36, 0, 0, 14, 0, 11, 0, 0,
+  0, 3, 8, 0, 16, 34, 27, 15, 0, 70,
+  0, 0, 0, 26, 7, 0, 14, 12, 42, 0,
+  12, 0, 8, 25, 0, 47, 52, 0, 15, 13,
+  0, 0, 17, 28, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 32, 29, 12, 0, 47, 0, 0,
+  66, 14, 50, 0, 35, 14, 18, 0, 67, 1,
+  0, 0, 28, 0, 51, 0, 0, 127, 0, 0,
+  28, 13, 0, 0, 0, 82, 0, 0, 9, 29,
+  31, 0, 0, 85, 28, 32, 0, 0, 13, 55,
+  0, 0, 0, 43, 0, 0, 0, 17, 44, 93,
+  0, 0, 24, 0, 15, 0, 0, 32, 0, 29,
+  0, 35, 0, 77, 0, 0, 138, 0, 12, 0,
+  0, 0, 0, 64, 0, 0, 81, 0, 9, 6,
+  12, 125, 8, 0, 33, 55, 0, 39, 22, 0,
+  0, 0, 0, 0, 28, 82, 0, 10, 0, 46,
+  0, 0, 0, 123, 0, 0, 55, 0, 11, 0,
+  0, 88, 63, 49, 0, 0, 27, 0, 0, 10,
+  0, 6, 1, 11, 0, 0, 9, 35, 24, 0,
+  11, 0, 0, 0, 0, 0, 0, 3, 9, 79,
+  0, 0, 30, 0, 26, 161, 0, 0, 0, 0,
+  0, 0, 49, 60, 0, 0, 11, 55, 0, 0,
+  7, 16, 0, 50, 0, 0, 0, 0, 0, 35,
+  21, 0, 0, 13, 0, 0, 0, 55, 0, 3,
+  0, 20, 0, 22, 0, 12, 34, 22, 0, 0,
+  13, 103, 4, 0, 17, 0, 10, 0, 46, 0,
+  0, 0, 0, 0, 54, 0, 0, 2, 0, 4,
+  0, 34, 24, 5, 0, 40, 0, 0, 0, 10,
+  0, 0, 18, 36, 19, 0, 31, 36, 38, 0,
+  0, 22, 13, 0, 4, 0, 0, 0, 1, 46,
+  1, 0, 0, 0, 0, 10, 0, 22, 0, 25,
+  23, 0, 0, 0, 5, 29, 102, 47, 32, 3,
+  54, 0, 0, 0, 37, 15, 0, 14, 0, 49,
+  11, 0, 44, 0, 25, 0, 19, 0, 0, 0,
+  81, 51, 5, 17, 15, 0, 0, 0, 3, 0,
+  0, 60, 21, 63, 0, 0, 0, 12, 63, 0,
+  0, 27, 12, 0, 0, 6, 0, 70, 0, 97,
+  10, 75, 53, 0, 0, 0, 0, 6, 0, 65,
+  94, 0, 0, 3, 21, 23, 4, 21, 0, 0,
+  0, 70, 0, 12, 8, 0, 0, 0, 0, 33,
+  0, 19, 20, 29, 0, 0, 0, 27, 44, 20,
+  19, 0, 78, 0, 29, 0, 66, 38, 0, 0,
+  42, 37, 0, 32, 0, 38, 3, 45, 0, 0,
+  0, 0, 0, 0, 3, 5, 71, 72, 88, 0,
+  0, 7, 31, 0, 0, 31, 64, 18, 57, 10,
+  85, 0, 91, 2, 0, 0, 35, 0, 20, 65,
+  14, 232, 0, 0, 1, 0, 0, 0, 0, 21,
+  0, 0, 0, 33, 62, 0, 0, 113, 15, 0,
+  0, 0, 0, 6, 0, 17, 8, 99, 0, 0,
+  0, 33, 0, 40, 0, 0, 0, 0, 0, 0,
+  0, 58, 44, 47, 7, 4, 0, 38, 0, 0,
+  142, 0, 48, 0, 21, 0, 27, 92, 17, 0,
+  115, 0, 0, 40, 0, 96, 83, 63, 62, 0,
+  0, 35, 43, 0, 0, 0, 0, 0, 46, 65,
+  0, 0, 0, 31, 0, 0, 7, 7, 0, 0,
+  70, 0, 52, 0, 0, 9, 17, 116, 2, 0,
+  0, 5, 18, 17, 0, 0, 0, 39, 0, 0,
+  0, 45, 36, 0, 13, 16, 0, 19, 0, 0,
+  0, 15, 0, 44, 0, 0, 0, 5, 19, 184,
+  0, 0, 0, 0, 0, 0, 30, 14, 0, 24,
+  4, 50, 5, 0, 21, 0, 0, 62, 18, 19,
+  0, 0, 0, 10, 18, 0, 0, 34, 0, 4,
+  0, 24, 0, 24, 0, 55, 0, 16, 0, 17,
+  43, 43, 0, 20, 0, 38, 14, 0, 0, 0,
+  9, 0, 19, 12, 5, 26, 0, 0, 6, 0,
+  0, 22, 22, 0, 30, 56, 37, 1, 2, 80,
+  0, 0, 0, 42, 0, 0, 13, 12, 24, 0,
+  22, 14, 2, 28, 1, 67, 43, 9, 35, 30,
+  0, 0, 7, 25, 0, 0, 0, 0, 0, 0,
+  0, 6, 0, 17, 0, 1, 0, 13, 0, 7,
+  81, 29, 34, 0, 48, 9, 42, 0, 38, 19,
+  0, 0, 0, 34, 49, 0, 25, 0, 17, 0,
+  0, 0, 0, 0, 29, 51, 2, 46, 15, 40,
+  0, 20, 33, 0, 79, 40, 0, 20, 0, 0,
+  0, 0, 25, 0, 0, 0, 0, 0, 0, 5,
+  0, 35, 63, 42, 0, 75, 56, 0, 0, 0,
+  0, 4, 0, 42, 63, 0, 1, 0, 44, 5,
+  9, 0, 0, 3, 0, 23, 0, 0, 26, 7,
+  0, 0, 0, 3, 4, 30, 12, 34, 0, 8,
+  0, 0, 40, 0, 0, 0, 68, 13, 0, 0,
+  40, 12, 0, 29, 32, 0, 0, 30, 0, 0,
+  0, 46, 0, 0, 0, 0, 5, 0, 0, 0,
+  0, 29, 58, 4, 0, 15, 30, 0, 26, 17,
+  54, 0, 15, 0, 9, 0, 76, 5, 0, 0,
+  17, 8, 86, 68, 23, 217, 0, 0, 29, 0,
+  0, 0, 32, 0, 0, 0, 31, 18, 66, 0,
+  0, 112, 15, 8, 7, 0, 0, 35, 0, 72,
+  0, 82, 0, 0, 0, 30, 0, 0, 1, 0,
+  0, 19, 0, 19, 0, 50, 59, 42, 0, 14,
+  0, 45, 0, 0, 97, 0, 62, 0, 33, 0,
+  0, 70, 0, 0, 53, 0, 0, 26, 12, 6,
+  27, 25, 76, 0, 0, 26, 25, 0, 0, 18,
+  0, 0, 77, 83, 0, 0, 0, 18, 0, 4,
+  54, 0, 0, 0, 24, 0, 25, 0, 15, 39,
+  25, 35, 17, 0, 0, 31, 47, 29, 0, 0,
+  0, 45, 0, 0, 0, 0, 38, 0, 3, 0,
+  0, 1, 0, 22, 25, 0, 0, 20, 0, 0,
+  0, 0, 1, 125, 0, 0, 0, 0, 0, 0,
+  59, 8, 0, 44, 12, 40, 18, 0, 40, 6,
+  0, 49, 0, 0, 0, 0, 0, 14, 40, 0,
+  0, 17, 0, 8, 0, 16, 0, 48, 35, 47,
+  0, 33, 1, 0, 7, 27, 0, 35, 0, 77,
+  28, 0, 14, 0, 38, 0, 36, 0, 0, 14,
+  0, 11, 0, 0, 0, 3, 8, 0, 16, 34,
+  27, 15, 0, 70, 0, 0, 0, 26, 7, 0,
+  14, 12, 42, 0, 12, 0, 8, 25, 0, 47,
+  52, 0, 15, 13, 0, 0, 17, 28, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 32, 29, 12,
+  0, 47, 0, 0, 66, 14, 50, 0, 35, 14,
+  18, 0, 67, 1, 0, 0, 0, 0, 77, 0,
+  0, 0, 2, 0, 0, 0, 0, 1, 29, 58,
+  0, 41, 0, 69, 29, 7, 59, 19, 117, 17,
+  0, 0, 0, 5, 0, 0, 15, 0, 0, 0,
+  0, 13, 0, 12, 0, 0, 66, 0, 0, 79,
+  32, 0, 0, 0, 0, 6, 0, 87, 7, 0,
+  39, 0, 49, 0, 7, 0, 0, 1, 10, 0,
+  77, 0, 0, 21, 0, 50, 0, 0, 2, 19,
+  0, 7, 0, 0, 0, 0, 19, 0, 2, 0,
+  62, 8, 0, 0, 25, 0, 0, 13, 0, 0,
+  16, 30, 0, 0, 0, 54, 3, 0, 0, 0,
+  20, 0, 0, 0, 0, 0, 62, 11, 0, 38,
+  13, 0, 89, 23, 44, 14, 34, 0, 0, 0,
+  57, 0, 15, 0, 0, 0, 30, 0, 26, 161,
+  0, 0, 0, 0, 0, 0, 49, 60, 0, 0,
+  11, 55, 0, 0, 7, 16, 0, 50, 0, 0,
+  0, 0, 0, 35, 21, 0, 0, 13, 0, 0,
+  0, 55, 0, 3, 0, 20, 0, 22, 0, 12,
+  34, 22, 0, 0, 13, 103, 4, 0, 17, 0,
+  10, 0, 46, 0, 0, 0, 0, 0, 54, 0,
+  0, 2, 0, 4, 0, 34, 24, 5, 0, 40,
+  0, 0, 0, 10, 0, 0, 18, 36, 19, 0,
+  31, 36, 38, 0, 0, 22, 13, 0, 4, 0,
+  0, 0, 1, 46, 1, 0, 0, 0, 0, 10,
+  0, 22, 0, 25, 23, 0, 0, 0, 5, 29,
+  102, 47, 32, 3, 54, 0, 0, 0, 37, 15,
+  0, 14, 0, 49, 11, 0, 44, 0, 25, 0,
+  19, 0, 0, 0, 81, 51, 5, 17, 15, 0,
+  0, 0, 3, 0, 0, 60, 21, 63, 0, 0,
+  0, 12, 63, 0, 0, 27, 12, 0, 0, 6,
+  0, 70, 0, 97, 10, 75, 53, 0, 0, 0,
+  0, 6, 0, 65, 94, 0, 0, 3, 21, 23,
+  4, 21, 0, 0, 0, 70, 0, 12, 8, 0,
+  0, 0, 0, 33, 0, 19, 20, 29, 0, 0,
+  0, 27, 44, 20, 19, 0, 78, 0, 29, 0,
+  66, 38, 0, 0, 42, 37, 0, 32, 0, 38,
+  3, 45, 0, 0, 0, 0, 0, 0, 3, 5,
+  71, 72, 88, 0, 0, 7, 31, 0, 0, 31,
+  64, 18, 57, 10, 85, 0, 91, 2, 0, 0,
+  0, 21, 76, 0, 26, 0, 1, 0, 0, 0,
+  0, 6, 28, 78, 0, 20, 4, 29, 21, 10,
+  35, 34, 113, 11, 0, 0, 0, 0, 0, 0,
+  18, 0, 0, 0, 0, 0, 0, 1, 0, 10,
+  66, 3, 0, 101, 57, 6, 0, 0, 0, 0,
+  0, 90, 1, 0, 17, 0, 40, 0, 25, 0,
+  0, 10, 7, 19, 34, 0, 0, 18, 0, 29,
+  0, 0, 0, 43, 3, 0, 0, 28, 0, 0,
+  37, 0, 22, 0, 65, 9, 0, 0, 20, 0,
+  0, 16, 13, 0, 0, 46, 0, 0, 0, 39,
+  0, 0, 0, 0, 1, 0, 0, 4, 0, 7,
+  72, 14, 0, 12, 20, 0, 52, 13, 51, 13,
+  13, 0, 0, 0, 64, 0, 0, 0, 0, 0,
+  0, 5, 19, 184, 0, 0, 0, 0, 0, 0,
+  30, 14, 0, 24, 4, 50, 5, 0, 21, 0,
+  0, 62, 18, 19, 0, 0, 0, 10, 18, 0,
+  0, 34, 0, 4, 0, 24, 0, 24, 0, 55,
+  0, 16, 0, 17, 43, 43, 0, 20, 0, 38,
+  14, 0, 0, 0, 9, 0, 19, 12, 5, 26,
+  0, 0, 6, 0, 0, 22, 22, 0, 30, 56,
+  37, 1, 2, 80, 0, 0, 0, 42, 0, 0,
+  13, 12, 24, 0, 22, 14, 2, 28, 1, 67,
+  43, 9, 35, 30, 0, 0, 7, 25, 0, 0,
+  0, 0, 0, 0, 0, 6, 0, 17, 0, 1,
+  0, 13, 0, 7, 81, 29, 34, 0, 48, 9,
+  42, 0, 38, 19, 0, 0, 0, 34, 49, 0,
+  25, 0, 17, 0, 0, 0, 0, 0, 29, 51,
+  2, 46, 15, 40, 0, 20, 33, 0, 79, 40,
+  0, 20, 0, 0, 0, 0, 25, 0, 0, 0,
+  0, 0, 0, 5, 0, 35, 63, 42, 0, 75,
+  56, 0, 0, 0, 0, 4, 0, 42, 63, 0,
+  1, 0, 44, 5, 9, 0, 0, 3, 0, 23,
+  0, 0, 26, 7, 0, 0, 0, 3, 4, 30,
+  12, 34, 0, 8, 0, 0, 40, 0, 0, 0,
+  68, 13, 0, 0, 40, 12, 0, 29, 32, 0,
+  0, 30, 0, 0, 0, 46, 0, 0, 0, 0,
+  5, 0, 0, 0, 0, 29, 58, 4, 0, 15,
+  30, 0, 26, 17, 54, 0, 15, 0, 9, 0,
+  76, 5, 0, 0, 10, 0, 77, 0, 9, 10,
+  0, 0, 4, 0, 0, 8, 3, 82, 0, 0,
+  0, 46, 42, 0, 45, 68, 136, 0, 0, 0,
+  0, 0, 0, 0, 3, 0, 0, 0, 0, 9,
+  0, 0, 0, 0, 33, 0, 0, 90, 40, 14,
+  0, 21, 0, 0, 0, 136, 0, 0, 74, 0,
+  41, 0, 36, 0, 0, 0, 35, 0, 125, 0,
+  0, 23, 0, 91, 0, 0, 13, 4, 0, 0,
+  7, 0, 0, 0, 15, 0, 23, 0, 45, 6,
+  0, 0, 20, 0, 0, 0, 0, 0, 24, 27,
+  0, 0, 0, 52, 15, 0, 0, 0, 14, 0,
+  0, 2, 0, 0, 69, 4, 0, 37, 12, 0,
+  118, 0, 23, 19, 24, 0, 0, 0, 53, 0,
+  0, 0, 0, 0, 0, 0, 1, 125, 0, 0,
+  0, 0, 0, 0, 59, 8, 0, 44, 12, 40,
+  18, 0, 40, 6, 0, 49, 0, 0, 0, 0,
+  0, 14, 40, 0, 0, 17, 0, 8, 0, 16,
+  0, 48, 35, 47, 0, 33, 1, 0, 7, 27,
+  0, 35, 0, 77, 28, 0, 14, 0, 38, 0,
+  36, 0, 0, 14, 0, 11, 0, 0, 0, 3,
+  8, 0, 16, 34, 27, 15, 0, 70, 0, 0,
+  0, 26, 7, 0, 14, 12, 42, 0, 12, 0,
+  8, 25, 0, 47, 52, 0, 15, 13, 0, 0,
+  17, 28, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 32, 29, 12, 0, 47, 0, 0, 66, 14,
+  50, 0, 35, 14, 18, 0, 67, 1, 0, 0,
+  0, 0, 77, 0, 0, 0, 2, 0, 0, 0,
+  0, 1, 29, 58, 0, 41, 0, 69, 29, 7,
+  59, 19, 117, 17, 0, 0, 0, 5, 0, 0,
+  15, 0, 0, 0, 0, 13, 0, 12, 0, 0,
+  66, 0, 0, 79, 32, 0, 0, 0, 0, 6,
+  0, 87, 7, 0, 39, 0, 49, 0, 7, 0,
+  0, 1, 10, 0, 77, 0, 0, 21, 0, 50,
+  0, 0, 2, 19, 0, 7, 0, 0, 0, 0,
+  19, 0, 2, 0, 62, 8, 0, 0, 25, 0,
+  0, 13, 0, 0, 16, 30, 0, 0, 0, 54,
+  3, 0, 0, 0, 20, 0, 0, 0, 0, 0,
+  62, 11, 0, 38, 13, 0, 89, 23, 44, 14,
+  34, 0, 0, 0, 57, 0, 15, 0, 25, 0,
+  64, 0, 17, 12, 0, 0, 23, 0, 0, 6,
+  16, 72, 0, 0, 0, 19, 42, 0, 48, 60,
+  61, 0, 0, 0, 0, 26, 0, 41, 0, 0,
+  0, 0, 0, 3, 0, 6, 0, 0, 0, 0,
+  0, 69, 18, 17, 0, 65, 0, 0, 0, 167,
+  0, 0, 66, 0, 29, 0, 4, 0, 0, 0,
+  24, 0, 113, 0, 0, 10, 0, 64, 0, 4,
+  0, 0, 0, 0, 0, 0, 0, 0, 12, 0,
+  12, 0, 32, 1, 0, 15, 43, 0, 26, 0,
+  0, 0, 27, 0, 11, 0, 0, 71, 39, 0,
+  0, 0, 13, 0, 0, 24, 30, 0, 73, 0,
+  0, 44, 14, 0, 155, 0, 5, 26, 74, 0,
+  0, 0, 54, 0, 0, 0, 0, 49, 11, 0,
+  44, 0, 25, 0, 19, 0, 0, 0, 81, 51,
+  5, 17, 15, 0, 0, 0, 3, 0, 0, 60,
+  21, 63, 0, 0, 0, 12, 63, 0, 0, 27,
+  12, 0, 0, 6, 0, 70, 0, 97, 10, 75,
+  53, 0, 0, 0, 0, 6, 0, 65, 94, 0,
+  0, 3, 21, 23, 4, 21, 0, 0, 0, 70,
+  0, 12, 8, 0, 0, 0, 0, 33, 0, 19,
+  20, 29, 0, 0, 0, 27, 44, 20, 19, 0,
+  78, 0, 29, 0, 66, 38, 0, 0, 42, 37,
+  0, 32, 0, 38, 3, 45, 0, 0, 0, 0,
+  0, 0, 3, 5, 71, 72, 88, 0, 0, 7,
+  31, 0, 0, 31, 64, 18, 57, 10, 85, 0,
+  91, 2, 0, 0, 0, 21, 76, 0, 26, 0,
+  1, 0, 0, 0, 0, 6, 28, 78, 0, 20,
+  4, 29, 21, 10, 35, 34, 113, 11, 0, 0,
+  0, 0, 0, 0, 18, 0, 0, 0, 0, 0,
+  0, 1, 0, 10, 66, 3, 0, 101, 57, 6,
+  0, 0, 0, 0, 0, 90, 1, 0, 17, 0,
+  40, 0, 25, 0, 0, 10, 7, 19, 34, 0,
+  0, 18, 0, 29, 0, 0, 0, 43, 3, 0,
+  0, 28, 0, 0, 37, 0, 22, 0, 65, 9,
+  0, 0, 20, 0, 0, 16, 13, 0, 0, 46,
+  0, 0, 0, 39, 0, 0, 0, 0, 1, 0,
+  0, 4, 0, 7, 72, 14, 0, 12, 20, 0,
+  52, 13, 51, 13, 13, 0, 0, 0, 64, 0,
+  0, 0, 4, 0, 79, 3, 6, 0, 0, 0,
+  14, 0, 0, 8, 0, 94, 0, 3, 0, 47,
+  45, 17, 53, 54, 102, 0, 0, 0, 0, 16,
+  0, 0, 0, 0, 0, 0, 0, 14, 0, 0,
+  0, 0, 37, 0, 0, 85, 38, 32, 0, 6,
+  0, 0, 0, 126, 0, 0, 66, 0, 24, 0,
+  20, 0, 0, 0, 29, 0, 99, 0, 0, 10,
+  0, 92, 0, 0, 18, 0, 0, 0, 4, 0,
+  0, 0, 11, 0, 20, 0, 18, 0, 0, 0,
+  39, 0, 0, 7, 0, 0, 22, 29, 2, 0,
+  4, 32, 23, 0, 0, 0, 28, 0, 0, 3,
+  17, 0, 84, 3, 0, 15, 21, 0, 112, 0,
+  10, 16, 55, 0, 0, 0, 57, 15, 0, 0,
+  0, 34, 49, 0, 25, 0, 17, 0, 0, 0,
+  0, 0, 29, 51, 2, 46, 15, 40, 0, 20,
+  33, 0, 79, 40, 0, 20, 0, 0, 0, 0,
+  25, 0, 0, 0, 0, 0, 0, 5, 0, 35,
+  63, 42, 0, 75, 56, 0, 0, 0, 0, 4,
+  0, 42, 63, 0, 1, 0, 44, 5, 9, 0,
+  0, 3, 0, 23, 0, 0, 26, 7, 0, 0,
+  0, 3, 4, 30, 12, 34, 0, 8, 0, 0,
+  40, 0, 0, 0, 68, 13, 0, 0, 40, 12,
+  0, 29, 32, 0, 0, 30, 0, 0, 0, 46,
+  0, 0, 0, 0, 5, 0, 0, 0, 0, 29,
+  58, 4, 0, 15, 30, 0, 26, 17, 54, 0,
+  15, 0, 9, 0, 76, 5, 0, 0, 10, 0,
+  77, 0, 9, 10, 0, 0, 4, 0, 0, 8,
+  3, 82, 0, 0, 0, 46, 42, 0, 45, 68,
+  136, 0, 0, 0, 0, 0, 0, 0, 3, 0,
+  0, 0, 0, 9, 0, 0, 0, 0, 33, 0,
+  0, 90, 40, 14, 0, 21, 0, 0, 0, 136,
+  0, 0, 74, 0, 41, 0, 36, 0, 0, 0,
+  35, 0, 125, 0, 0, 23, 0, 91, 0, 0,
+  13, 4, 0, 0, 7, 0, 0, 0, 15, 0,
+  23, 0, 45, 6, 0, 0, 20, 0, 0, 0,
+  0, 0, 24, 27, 0, 0, 0, 52, 15, 0,
+  0, 0, 14, 0, 0, 2, 0, 0, 69, 4,
+  0, 37, 12, 0, 118, 0, 23, 19, 24, 0,
+  0, 0, 53, 0, 0, 0, 0, 0, 45, 1,
+  17, 0, 0, 0, 31, 0, 0, 0, 20, 82,
+  0, 0, 0, 11, 29, 0, 23, 30, 25, 5,
+  0, 0, 20, 43, 0, 53, 0, 0, 0, 0,
+  0, 0, 0, 4, 0, 0, 0, 0, 0, 45,
+  6, 26, 0, 49, 0, 0, 0, 152, 0, 16,
+  45, 0, 12, 0, 0, 0, 0, 0, 8, 0,
+  63, 0, 0, 6, 0, 72, 0, 0, 8, 0,
+  0, 0, 0, 0, 0, 0, 13, 0, 1, 0,
+  0, 0, 0, 44, 53, 0, 44, 0, 0, 0,
+  18, 0, 36, 0, 0, 72, 23, 0, 15, 0,
+  42, 0, 1, 20, 65, 0, 81, 0, 0, 14,
+  40, 0, 141, 0, 0, 33, 89, 0, 30, 0,
+  58, 0, 0, 0, 0, 0, 77, 0, 0, 0,
+  2, 0, 0, 0, 0, 1, 29, 58, 0, 41,
+  0, 69, 29, 7, 59, 19, 117, 17, 0, 0,
+  0, 5, 0, 0, 15, 0, 0, 0, 0, 13,
+  0, 12, 0, 0, 66, 0, 0, 79, 32, 0,
+  0, 0, 0, 6, 0, 87, 7, 0, 39, 0,
+  49, 0, 7, 0, 0, 1, 10, 0, 77, 0,
+  0, 21, 0, 50, 0, 0, 2, 19, 0, 7,
+  0, 0, 0, 0, 19, 0, 2, 0, 62, 8,
+  0, 0, 25, 0, 0, 13, 0, 0, 16, 30,
+  0, 0, 0, 54, 3, 0, 0, 0, 20, 0,
+  0, 0, 0, 0, 62, 11, 0, 38, 13, 0,
+  89, 23, 44, 14, 34, 0, 0, 0, 57, 0,
+  15, 0, 25, 0, 64, 0, 17, 12, 0, 0,
+  23, 0, 0, 6, 16, 72, 0, 0, 0, 19,
+  42, 0, 48, 60, 61, 0, 0, 0, 0, 26,
+  0, 41, 0, 0, 0, 0, 0, 3, 0, 6,
+  0, 0, 0, 0, 0, 69, 18, 17, 0, 65,
+  0, 0, 0, 167, 0, 0, 66, 0, 29, 0,
+  4, 0, 0, 0, 24, 0, 113, 0, 0, 10,
+  0, 64, 0, 4, 0, 0, 0, 0, 0, 0,
+  0, 0, 12, 0, 12, 0, 32, 1, 0, 15,
+  43, 0, 26, 0, 0, 0, 27, 0, 11, 0,
+  0, 71, 39, 0, 0, 0, 13, 0, 0, 24,
+  30, 0, 73, 0, 0, 44, 14, 0, 155, 0,
+  5, 26, 74, 0, 0, 0, 54, 0, 0, 0,
+  0, 0, 0, 0, 12, 0, 0, 14, 34, 15,
+  0, 0, 26, 34, 0, 0, 0, 21, 29, 0,
+  8, 0, 0, 45, 0, 0, 48, 64, 6, 83,
+  0, 0, 55, 0, 0, 0, 0, 1, 0, 5,
+  0, 0, 0, 16, 10, 46, 0, 58, 0, 8,
+  7, 104, 37, 30, 33, 0, 15, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 6, 0, 0, 19,
+  0, 0, 21, 0, 0, 63, 0, 0, 0, 9,
+  39, 0, 0, 13, 0, 0, 0, 59, 43, 21,
+  114, 3, 0, 0, 28, 0, 36, 0, 0, 91,
+  40, 0, 32, 0, 7, 0, 28, 8, 75, 20,
+  37, 0, 0, 8, 5, 0, 131, 0, 0, 37,
+  103, 0, 101, 0, 70, 0, 0, 0, 0, 21,
+  76, 0, 26, 0, 1, 0, 0, 0, 0, 6,
+  28, 78, 0, 20, 4, 29, 21, 10, 35, 34,
+  113, 11, 0, 0, 0, 0, 0, 0, 18, 0,
+  0, 0, 0, 0, 0, 1, 0, 10, 66, 3,
+  0, 101, 57, 6, 0, 0, 0, 0, 0, 90,
+  1, 0, 17, 0, 40, 0, 25, 0, 0, 10,
+  7, 19, 34, 0, 0, 18, 0, 29, 0, 0,
+  0, 43, 3, 0, 0, 28, 0, 0, 37, 0,
+  22, 0, 65, 9, 0, 0, 20, 0, 0, 16,
+  13, 0, 0, 46, 0, 0, 0, 39, 0, 0,
+  0, 0, 1, 0, 0, 4, 0, 7, 72, 14,
+  0, 12, 20, 0, 52, 13, 51, 13, 13, 0,
+  0, 0, 64, 0, 0, 0, 4, 0, 79, 3,
+  6, 0, 0, 0, 14, 0, 0, 8, 0, 94,
+  0, 3, 0, 47, 45, 17, 53, 54, 102, 0,
+  0, 0, 0, 16, 0, 0, 0, 0, 0, 0,
+  0, 14, 0, 0, 0, 0, 37, 0, 0, 85,
+  38, 32, 0, 6, 0, 0, 0, 126, 0, 0,
+  66, 0, 24, 0, 20, 0, 0, 0, 29, 0,
+  99, 0, 0, 10, 0, 92, 0, 0, 18, 0,
+  0, 0, 4, 0, 0, 0, 11, 0, 20, 0,
+  18, 0, 0, 0, 39, 0, 0, 7, 0, 0,
+  22, 29, 2, 0, 4, 32, 23, 0, 0, 0,
+  28, 0, 0, 3, 17, 0, 84, 3, 0, 15,
+  21, 0, 112, 0, 10, 16, 55, 0, 0, 0,
+  57, 15, 0, 0, 2, 0, 42, 31, 0, 0,
+  14, 24, 59, 0, 4, 0, 0, 82, 0, 0,
+  0, 8, 26, 0, 35, 19, 23, 27, 0, 0,
+  38, 57, 187, 16, 19, 10, 32, 0, 0, 0,
+  0, 25, 0, 0, 0, 0, 0, 32, 38, 93,
+  0, 17, 0, 0, 3, 110, 0, 32, 59, 0,
+  9, 0, 14, 0, 0, 22, 8, 0, 4, 0,
+  20, 0, 0, 39, 0, 6, 29, 4, 0, 9,
+  34, 0, 0, 0, 24, 0, 1, 24, 0, 0,
+  0, 30, 103, 45, 40, 0, 0, 0, 18, 12,
+  59, 0, 26, 51, 26, 6, 18, 0, 84, 0,
+  42, 12, 87, 0, 79, 0, 10, 0, 1, 0,
+  115, 0, 0, 34, 41, 0, 5, 0, 59, 9,
+  0, 24, 10, 0, 77, 0, 9, 10, 0, 0,
+  4, 0, 0, 8, 3, 82, 0, 0, 0, 46,
+  42, 0, 45, 68, 136, 0, 0, 0, 0, 0,
+  0, 0, 3, 0, 0, 0, 0, 9, 0, 0,
+  0, 0, 33, 0, 0, 90, 40, 14, 0, 21,
+  0, 0, 0, 136, 0, 0, 74, 0, 41, 0,
+  36, 0, 0, 0, 35, 0, 125, 0, 0, 23,
+  0, 91, 0, 0, 13, 4, 0, 0, 7, 0,
+  0, 0, 15, 0, 23, 0, 45, 6, 0, 0,
+  20, 0, 0, 0, 0, 0, 24, 27, 0, 0,
+  0, 52, 15, 0, 0, 0, 14, 0, 0, 2,
+  0, 0, 69, 4, 0, 37, 12, 0, 118, 0,
+  23, 19, 24, 0, 0, 0, 53, 0, 0, 0,
+  0, 0, 45, 1, 17, 0, 0, 0, 31, 0,
+  0, 0, 20, 82, 0, 0, 0, 11, 29, 0,
+  23, 30, 25, 5, 0, 0, 20, 43, 0, 53,
+  0, 0, 0, 0, 0, 0, 0, 4, 0, 0,
+  0, 0, 0, 45, 6, 26, 0, 49, 0, 0,
+  0, 152, 0, 16, 45, 0, 12, 0, 0, 0,
+  0, 0, 8, 0, 63, 0, 0, 6, 0, 72,
+  0, 0, 8, 0, 0, 0, 0, 0, 0, 0,
+  13, 0, 1, 0, 0, 0, 0, 44, 53, 0,
+  44, 0, 0, 0, 18, 0, 36, 0, 0, 72,
+  23, 0, 15, 0, 42, 0, 1, 20, 65, 0,
+  81, 0, 0, 14, 40, 0, 141, 0, 0, 33,
+  89, 0, 30, 0, 58, 0, 0, 0, 0, 0,
+  24, 23, 0, 0, 18, 24, 50, 29, 0, 0,
+  0, 30, 0, 5, 4, 7, 13, 0, 0, 0,
+  0, 53, 0, 0, 74, 59, 173, 47, 0, 0,
+  71, 0, 19, 0, 0, 20, 0, 24, 0, 0,
+  0, 0, 18, 88, 16, 0, 0, 16, 0, 67,
+  30, 34, 32, 0, 0, 4, 0, 6, 0, 39,
+  0, 0, 0, 0, 33, 0, 0, 14, 6, 12,
+  56, 3, 0, 51, 0, 0, 0, 3, 39, 0,
+  0, 33, 0, 0, 0, 48, 80, 41, 84, 0,
+  0, 0, 23, 0, 51, 0, 2, 59, 14, 2,
+  58, 0, 66, 2, 56, 3, 77, 5, 38, 0,
+  11, 0, 0, 0, 103, 0, 0, 17, 53, 0,
+  50, 0, 60, 0, 7, 11, 25, 0, 64, 0,
+  17, 12, 0, 0, 23, 0, 0, 6, 16, 72,
+  0, 0, 0, 19, 42, 0, 48, 60, 61, 0,
+  0, 0, 0, 26, 0, 41, 0, 0, 0, 0,
+  0, 3, 0, 6, 0, 0, 0, 0, 0, 69,
+  18, 17, 0, 65, 0, 0, 0, 167, 0, 0,
+  66, 0, 29, 0, 4, 0, 0, 0, 24, 0,
+  113, 0, 0, 10, 0, 64, 0, 4, 0, 0,
+  0, 0, 0, 0, 0, 0, 12, 0, 12, 0,
+  32, 1, 0, 15, 43, 0, 26, 0, 0, 0,
+  27, 0, 11, 0, 0, 71, 39, 0, 0, 0,
+  13, 0, 0, 24, 30, 0, 73, 0, 0, 44,
+  14, 0, 155, 0, 5, 26, 74, 0, 0, 0,
+  54, 0, 0, 0, 0, 0, 0, 0, 12, 0,
+  0, 14, 34, 15, 0, 0, 26, 34, 0, 0,
+  0, 21, 29, 0, 8, 0, 0, 45, 0, 0,
+  48, 64, 6, 83, 0, 0, 55, 0, 0, 0,
+  0, 1, 0, 5, 0, 0, 0, 16, 10, 46,
+  0, 58, 0, 8, 7, 104, 37, 30, 33, 0,
+  15, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  6, 0, 0, 19, 0, 0, 21, 0, 0, 63,
+  0, 0, 0, 9, 39, 0, 0, 13, 0, 0,
+  0, 59, 43, 21, 114, 3, 0, 0, 28, 0,
+  36, 0, 0, 91, 40, 0, 32, 0, 7, 0,
+  28, 8, 75, 20, 37, 0, 0, 8, 5, 0,
+  131, 0, 0, 37, 103, 0, 101, 0, 70, 0,
+  0, 0, 0, 6, 23, 5, 0, 0, 44, 22,
+  34, 36, 0, 0, 1, 0, 0, 41, 20, 23,
+  3, 8, 0, 0, 0, 69, 18, 19, 51, 49,
+  164, 7, 0, 0, 85, 0, 15, 0, 0, 31,
+  6, 63, 0, 3, 29, 0, 23, 56, 20, 0,
+  0, 47, 0, 43, 48, 47, 7, 0, 0, 20,
+  0, 28, 0, 23, 0, 0, 0, 3, 58, 0,
+  2, 0, 18, 22, 54, 25, 23, 58, 0, 0,
+  0, 13, 76, 0, 7, 17, 0, 0, 4, 37,
+  62, 48, 83, 0, 0, 0, 8, 13, 24, 0,
+  0, 55, 0, 0, 26, 0, 38, 0, 56, 0,
+  44, 17, 29, 0, 10, 0, 0, 0, 37, 0,
+  0, 16, 21, 0, 77, 0, 71, 0, 5, 0,
+  4, 0, 79, 3, 6, 0, 0, 0, 14, 0,
+  0, 8, 0, 94, 0, 3, 0, 47, 45, 17,
+  53, 54, 102, 0, 0, 0, 0, 16, 0, 0,
+  0, 0, 0, 0, 0, 14, 0, 0, 0, 0,
+  37, 0, 0, 85, 38, 32, 0, 6, 0, 0,
+  0, 126, 0, 0, 66, 0, 24, 0, 20, 0,
+  0, 0, 29, 0, 99, 0, 0, 10, 0, 92,
+  0, 0, 18, 0, 0, 0, 4, 0, 0, 0,
+  11, 0, 20, 0, 18, 0, 0, 0, 39, 0,
+  0, 7, 0, 0, 22, 29, 2, 0, 4, 32,
+  23, 0, 0, 0, 28, 0, 0, 3, 17, 0,
+  84, 3, 0, 15, 21, 0, 112, 0, 10, 16,
+  55, 0, 0, 0, 57, 15, 0, 0, 2, 0,
+  42, 31, 0, 0, 14, 24, 59, 0, 4, 0,
+  0, 82, 0, 0, 0, 8, 26, 0, 35, 19,
+  23, 27, 0, 0, 38, 57, 187, 16, 19, 10,
+  32, 0, 0, 0, 0, 25, 0, 0, 0, 0,
+  0, 32, 38, 93, 0, 17, 0, 0, 3, 110,
+  0, 32, 59, 0, 9, 0, 14, 0, 0, 22,
+  8, 0, 4, 0, 20, 0, 0, 39, 0, 6,
+  29, 4, 0, 9, 34, 0, 0, 0, 24, 0,
+  1, 24, 0, 0, 0, 30, 103, 45, 40, 0,
+  0, 0, 18, 12, 59, 0, 26, 51, 26, 6,
+  18, 0, 84, 0, 42, 12, 87, 0, 79, 0,
+  10, 0, 1, 0, 115, 0, 0, 34, 41, 0,
+  5, 0, 59, 9, 0, 24, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 45, 1, 17, 0,
+  0, 0, 31, 0, 0, 0, 20, 82, 0, 0,
+  0, 11, 29, 0, 23, 30, 25, 5, 0, 0,
+  20, 43, 0, 53, 0, 0, 0, 0, 0, 0,
+  0, 4, 0, 0, 0, 0, 0, 45, 6, 26,
+  0, 49, 0, 0, 0, 152, 0, 16, 45, 0,
+  12, 0, 0, 0, 0, 0, 8, 0, 63, 0,
+  0, 6, 0, 72, 0, 0, 8, 0, 0, 0,
+  0, 0, 0, 0, 13, 0, 1, 0, 0, 0,
+  0, 44, 53, 0, 44, 0, 0, 0, 18, 0,
+  36, 0, 0, 72, 23, 0, 15, 0, 42, 0,
+  1, 20, 65, 0, 81, 0, 0, 14, 40, 0,
+  141, 0, 0, 33, 89, 0, 30, 0, 58, 0,
+  0, 0, 0, 0, 24, 23, 0, 0, 18, 24,
+  50, 29, 0, 0, 0, 30, 0, 5, 4, 7,
+  13, 0, 0, 0, 0, 53, 0, 0, 74, 59,
+  173, 47, 0, 0, 71, 0, 19, 0, 0, 20,
+  0, 24, 0, 0, 0, 0, 18, 88, 16, 0,
+  0, 16, 0, 67, 30, 34, 32, 0, 0, 4,
+  0, 6, 0, 39, 0, 0, 0, 0, 33, 0,
+  0, 14, 6, 12, 56, 3, 0, 51, 0, 0,
+  0, 3, 39, 0, 0, 33, 0, 0, 0, 48,
+  80, 41, 84, 0, 0, 0, 23, 0, 51, 0,
+  2, 59, 14, 2, 58, 0, 66, 2, 56, 3,
+  77, 5, 38, 0, 11, 0, 0, 0, 103, 0,
+  0, 17, 53, 0, 50, 0, 60, 0, 7, 11,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 12, 0, 0, 14, 34, 15, 0, 0,
+  26, 34, 0, 0, 0, 21, 29, 0, 8, 0,
+  0, 45, 0, 0, 48, 64, 6, 83, 0, 0,
+  55, 0, 0, 0, 0, 1, 0, 5, 0, 0,
+  0, 16, 10, 46, 0, 58, 0, 8, 7, 104,
+  37, 30, 33, 0, 15, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 6, 0, 0, 19, 0, 0,
+  21, 0, 0, 63, 0, 0, 0, 9, 39, 0,
+  0, 13, 0, 0, 0, 59, 43, 21, 114, 3,
+  0, 0, 28, 0, 36, 0, 0, 91, 40, 0,
+  32, 0, 7, 0, 28, 8, 75, 20, 37, 0,
+  0, 8, 5, 0, 131, 0, 0, 37, 103, 0,
+  101, 0, 70, 0, 0, 0, 0, 6, 23, 5,
+  0, 0, 44, 22, 34, 36, 0, 0, 1, 0,
+  0, 41, 20, 23, 3, 8, 0, 0, 0, 69,
+  18, 19, 51, 49, 164, 7, 0, 0, 85, 0,
+  15, 0, 0, 31, 6, 63, 0, 3, 29, 0,
+  23, 56, 20, 0, 0, 47, 0, 43, 48, 47,
+  7, 0, 0, 20, 0, 28, 0, 23, 0, 0,
+  0, 3, 58, 0, 2, 0, 18, 22, 54, 25,
+  23, 58, 0, 0, 0, 13, 76, 0, 7, 17,
+  0, 0, 4, 37, 62, 48, 83, 0, 0, 0,
+  8, 13, 24, 0, 0, 55, 0, 0, 26, 0,
+  38, 0, 56, 0, 44, 17, 29, 0, 10, 0,
+  0, 0, 37, 0, 0, 16, 21, 0, 77, 0,
+  71, 0, 5, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 62, 32, 0, 2, 1, 44, 3, 0, 0,
+  16, 4, 12, 0, 5, 53, 33, 30, 0, 74,
+  61, 0, 71, 46, 0, 36, 0, 3, 111, 34,
+  1, 0, 57, 0, 53, 22, 0, 16, 0, 48,
+  40, 30, 5, 36, 99, 16, 0, 12, 0, 8,
+  1, 0, 56, 0, 0, 0, 43, 0, 7, 33,
+  9, 0, 16, 0, 0, 0, 18, 21, 0, 0,
+  8, 32, 42, 43, 43, 31, 0, 15, 0, 0,
+  70, 13, 10, 0, 12, 12, 0, 0, 50, 9,
+  2, 0, 16, 0, 5, 73, 0, 0, 8, 21,
+  2, 0, 0, 16, 17, 0, 77, 9, 0, 22,
+  29, 1, 0, 33, 0, 0, 0, 15, 0, 33,
+  26, 0, 0, 0, 28, 0, 14, 0, 5, 45,
+  49, 8, 0, 13, 12, 23, 0, 0, 0, 49,
+  90, 0, 0, 29, 44, 13, 0, 25, 68, 58,
+  82, 13, 0, 0, 0, 11, 0, 0, 0, 0,
+  81, 0, 34, 31, 0, 20, 0, 59, 2, 29,
+  0, 28, 67, 52, 0, 60, 0, 43, 0, 42,
+  24, 0, 22, 0, 17, 0, 7, 0, 0, 0,
+  0, 9, 8, 0, 0, 0, 16, 0, 14, 13,
+  19, 19, 30, 0, 40, 53, 0, 19, 43, 0,
+  42, 0, 0, 11, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 33, 18, 0, 37, 45, 21, 0,
+  0, 23, 29, 0, 60, 0, 0, 7, 11, 13,
+  0, 17, 0, 0, 0, 0, 1, 9, 37, 0,
+  7, 0, 52, 0, 8, 2, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 74, 43, 0, 0, 0,
+  41, 0, 0, 0, 0, 15, 3, 0, 14, 72,
+  38, 47, 0, 64, 66, 0, 81, 51, 0, 26,
+  10, 14, 118, 35, 2, 0, 62, 0, 42, 8,
+  0, 26, 7, 52, 32, 25, 0, 26, 85, 30,
+  0, 8, 0, 25, 0, 13, 61, 0, 0, 0,
+  25, 0, 4, 20, 16, 0, 7, 0, 0, 0,
+  21, 2, 0, 0, 14, 32, 32, 38, 42, 30,
+  5, 5, 0, 0, 76, 3, 4, 0, 0, 15,
+  0, 0, 64, 23, 0, 0, 7, 0, 8, 49,
+  0, 0, 22, 10, 3, 0, 1, 17, 39, 0,
+  77, 0, 0, 43, 30, 0, 0, 41, 0, 0,
+  0, 3, 0, 15, 30, 0, 0, 0, 22, 0,
+  36, 0, 4, 47, 62, 10, 0, 19, 11, 10,
+  1, 0, 0, 51, 73, 0, 0, 33, 47, 24,
+  0, 20, 69, 64, 93, 12, 0, 0, 0, 23,
+  0, 0, 0, 0, 74, 0, 23, 28, 0, 28,
+  0, 48, 1, 24, 0, 19, 53, 57, 0, 57,
+  0, 37, 0, 54, 25, 0, 42, 0, 29, 0,
+  2, 0, 1, 0, 0, 20, 15, 0, 0, 0,
+  26, 0, 13, 15, 11, 22, 32, 0, 46, 51,
+  0, 12, 44, 0, 35, 0, 0, 8, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 24, 31, 0,
+  40, 41, 11, 0, 10, 24, 51, 0, 57, 0,
+  0, 3, 17, 15, 0, 12, 0, 0, 7, 0,
+  0, 7, 15, 4, 0, 0, 47, 0, 18, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 79,
+  42, 0, 0, 0, 53, 0, 5, 0, 0, 37,
+  2, 1, 18, 62, 41, 51, 0, 55, 86, 0,
+  87, 50, 0, 11, 5, 15, 128, 37, 1, 0,
+  72, 0, 36, 0, 0, 27, 0, 45, 39, 32,
+  0, 35, 80, 55, 0, 7, 0, 21, 12, 25,
+  62, 0, 16, 0, 27, 0, 29, 0, 13, 0,
+  11, 0, 0, 0, 25, 0, 9, 0, 3, 35,
+  41, 39, 37, 34, 23, 0, 0, 8, 79, 22,
+  1, 0, 0, 13, 0, 0, 82, 36, 0, 0,
+  20, 0, 0, 51, 0, 0, 48, 11, 5, 0,
+  0, 23, 29, 0, 77, 0, 0, 50, 18, 0,
+  0, 42, 0, 0, 0, 4, 5, 13, 24, 0,
+  0, 0, 28, 0, 34, 0, 7, 54, 57, 12,
+  0, 23, 17, 14, 2, 0, 0, 54, 68, 12,
+  2, 19, 58, 30, 0, 13, 72, 61, 94, 10,
+  0, 0, 0, 26, 0, 0, 0, 5, 68, 0,
+  20, 19, 0, 31, 0, 50, 4, 41, 0, 19,
+  53, 58, 0, 66, 0, 27, 0, 55, 24, 0,
+  51, 0, 26, 0, 10, 0, 0, 0, 0, 18,
+  3, 0, 0, 0, 34, 0, 14, 26, 9, 11,
+  35, 0, 48, 32, 0, 34, 37, 0, 35, 0,
+  0, 7, 0, 0, 0, 5, 0, 0, 0, 0,
+  0, 28, 25, 0, 59, 36, 0, 0, 14, 23,
+  43, 0, 49, 0, 0, 6, 11, 5, 0, 11,
+  0, 0, 8, 0, 8, 0, 0, 4, 5, 0,
+  45, 0, 20, 0, 0, 62, 32, 0, 2, 1,
+  44, 3, 0, 0, 16, 4, 12, 0, 5, 53,
+  33, 30, 0, 74, 61, 0, 71, 46, 0, 36,
+  0, 3, 111, 34, 1, 0, 57, 0, 53, 22,
+  0, 16, 0, 48, 40, 30, 5, 36, 99, 16,
+  0, 12, 0, 8, 1, 0, 56, 0, 0, 0,
+  43, 0, 7, 33, 9, 0, 16, 0, 0, 0,
+  18, 21, 0, 0, 8, 32, 42, 43, 43, 31,
+  0, 15, 0, 0, 70, 13, 10, 0, 12, 12,
+  0, 0, 50, 9, 2, 0, 16, 0, 5, 73,
+  0, 0, 8, 21, 2, 0, 0, 16, 17, 0,
+  77, 9, 0, 22, 29, 1, 0, 33, 0, 0,
+  0, 15, 0, 33, 26, 0, 0, 0, 28, 0,
+  14, 0, 5, 45, 49, 8, 0, 13, 12, 23,
+  0, 0, 0, 49, 90, 0, 0, 29, 44, 13,
+  0, 25, 68, 58, 82, 13, 0, 0, 0, 11,
+  0, 0, 0, 0, 81, 0, 34, 31, 0, 20,
+  0, 59, 2, 29, 0, 28, 67, 52, 0, 60,
+  0, 43, 0, 42, 24, 0, 22, 0, 17, 0,
+  7, 0, 0, 0, 0, 9, 8, 0, 0, 0,
+  16, 0, 14, 13, 19, 19, 30, 0, 40, 53,
+  0, 19, 43, 0, 42, 0, 0, 11, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 33, 18, 0,
+  37, 45, 21, 0, 0, 23, 29, 0, 60, 0,
+  0, 7, 11, 13, 0, 17, 0, 0, 0, 0,
+  1, 9, 37, 0, 7, 0, 52, 0, 8, 2,
+  2, 29, 35, 14, 0, 2, 25, 15, 25, 0,
+  0, 41, 100, 0, 19, 33, 52, 0, 0, 0,
+  0, 93, 0, 8, 42, 0, 0, 23, 0, 0,
+  0, 43, 78, 0, 33, 0, 0, 18, 0, 68,
+  0, 56, 40, 13, 39, 47, 17, 12, 0, 48,
+  0, 63, 25, 25, 42, 0, 13, 0, 12, 0,
+  4, 7, 0, 68, 0, 15, 1, 0, 32, 0,
+  7, 15, 0, 11, 0, 0, 44, 48, 0, 33,
+  43, 0, 60, 25, 0, 0, 0, 0, 0, 17,
+  0, 0, 0, 3, 0, 32, 43, 0, 2, 82,
+  3, 0, 8, 22, 34, 0, 25, 0, 0, 0,
+  17, 10, 0, 0, 0, 0, 0, 0, 2, 15,
+  15, 5, 38, 0, 55, 0, 13, 0, 0, 74,
+  43, 0, 0, 0, 41, 0, 0, 0, 0, 15,
+  3, 0, 14, 72, 38, 47, 0, 64, 66, 0,
+  81, 51, 0, 26, 10, 14, 118, 35, 2, 0,
+  62, 0, 42, 8, 0, 26, 7, 52, 32, 25,
+  0, 26, 85, 30, 0, 8, 0, 25, 0, 13,
+  61, 0, 0, 0, 25, 0, 4, 20, 16, 0,
+  7, 0, 0, 0, 21, 2, 0, 0, 14, 32,
+  32, 38, 42, 30, 5, 5, 0, 0, 76, 3,
+  4, 0, 0, 15, 0, 0, 64, 23, 0, 0,
+  7, 0, 8, 49, 0, 0, 22, 10, 3, 0,
+  1, 17, 39, 0, 77, 0, 0, 43, 30, 0,
+  0, 41, 0, 0, 0, 3, 0, 15, 30, 0,
+  0, 0, 22, 0, 36, 0, 4, 47, 62, 10,
+  0, 19, 11, 10, 1, 0, 0, 51, 73, 0,
+  0, 33, 47, 24, 0, 20, 69, 64, 93, 12,
+  0, 0, 0, 23, 0, 0, 0, 0, 74, 0,
+  23, 28, 0, 28, 0, 48, 1, 24, 0, 19,
+  53, 57, 0, 57, 0, 37, 0, 54, 25, 0,
+  42, 0, 29, 0, 2, 0, 1, 0, 0, 20,
+  15, 0, 0, 0, 26, 0, 13, 15, 11, 22,
+  32, 0, 46, 51, 0, 12, 44, 0, 35, 0,
+  0, 8, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 24, 31, 0, 40, 41, 11, 0, 10, 24,
+  51, 0, 57, 0, 0, 3, 17, 15, 0, 12,
+  0, 0, 7, 0, 0, 7, 15, 4, 0, 0,
+  47, 0, 18, 0, 3, 30, 27, 20, 0, 12,
+  23, 23, 27, 0, 0, 40, 83, 0, 11, 31,
+  57, 0, 0, 0, 0, 92, 0, 1, 37, 0,
+  0, 25, 0, 0, 0, 50, 77, 0, 34, 0,
+  0, 19, 0, 54, 0, 46, 24, 10, 34, 52,
+  12, 15, 0, 33, 0, 55, 12, 26, 53, 0,
+  30, 0, 10, 0, 0, 13, 0, 58, 0, 13,
+  0, 0, 32, 0, 13, 16, 12, 11, 0, 0,
+  49, 39, 0, 32, 30, 0, 50, 41, 0, 0,
+  7, 0, 0, 13, 0, 0, 0, 16, 0, 30,
+  52, 0, 6, 80, 2, 0, 18, 20, 43, 0,
+  29, 0, 4, 0, 21, 11, 0, 0, 0, 0,
+  0, 0, 0, 11, 4, 11, 36, 0, 51, 0,
+  18, 0, 0, 79, 42, 0, 0, 0, 53, 0,
+  5, 0, 0, 37, 2, 1, 18, 62, 41, 51,
+  0, 55, 86, 0, 87, 50, 0, 11, 5, 15,
+  128, 37, 1, 0, 72, 0, 36, 0, 0, 27,
+  0, 45, 39, 32, 0, 35, 80, 55, 0, 7,
+  0, 21, 12, 25, 62, 0, 16, 0, 27, 0,
+  29, 0, 13, 0, 11, 0, 0, 0, 25, 0,
+  9, 0, 3, 35, 41, 39, 37, 34, 23, 0,
+  0, 8, 79, 22, 1, 0, 0, 13, 0, 0,
+  82, 36, 0, 0, 20, 0, 0, 51, 0, 0,
+  48, 11, 5, 0, 0, 23, 29, 0, 77, 0,
+  0, 50, 18, 0, 0, 42, 0, 0, 0, 4,
+  5, 13, 24, 0, 0, 0, 28, 0, 34, 0,
+  7, 54, 57, 12, 0, 23, 17, 14, 2, 0,
+  0, 54, 68, 12, 2, 19, 58, 30, 0, 13,
+  72, 61, 94, 10, 0, 0, 0, 26, 0, 0,
+  0, 5, 68, 0, 20, 19, 0, 31, 0, 50,
+  4, 41, 0, 19, 53, 58, 0, 66, 0, 27,
+  0, 55, 24, 0, 51, 0, 26, 0, 10, 0,
+  0, 0, 0, 18, 3, 0, 0, 0, 34, 0,
+  14, 26, 9, 11, 35, 0, 48, 32, 0, 34,
+  37, 0, 35, 0, 0, 7, 0, 0, 0, 5,
+  0, 0, 0, 0, 0, 28, 25, 0, 59, 36,
+  0, 0, 14, 23, 43, 0, 49, 0, 0, 6,
+  11, 5, 0, 11, 0, 0, 8, 0, 8, 0,
+  0, 4, 5, 0, 45, 0, 20, 0, 10, 27,
+  29, 24, 0, 21, 22, 22, 24, 0, 0, 43,
+  79, 0, 6, 26, 56, 0, 0, 0, 0, 87,
+  1, 0, 41, 0, 0, 30, 0, 1, 0, 60,
+  72, 0, 24, 0, 0, 23, 0, 54, 0, 47,
+  13, 10, 23, 49, 26, 18, 0, 30, 0, 52,
+  4, 24, 54, 0, 32, 0, 10, 0, 1, 11,
+  0, 48, 0, 8, 0, 0, 39, 0, 18, 26,
+  11, 0, 0, 2, 47, 27, 0, 46, 24, 0,
+  46, 46, 0, 0, 13, 0, 0, 18, 0, 0,
+  0, 23, 0, 24, 55, 0, 15, 78, 0, 0,
+  25, 19, 40, 0, 26, 0, 5, 0, 17, 8,
+  0, 0, 0, 0, 7, 0, 0, 4, 0, 11,
+  36, 0, 55, 0, 17, 0, 5, 45, 49, 8,
+  0, 13, 12, 23, 0, 0, 0, 49, 90, 0,
+  0, 29, 44, 13, 0, 25, 68, 58, 82, 13,
+  0, 0, 0, 11, 0, 0, 0, 0, 81, 0,
+  34, 31, 0, 20, 0, 59, 2, 29, 0, 28,
+  67, 52, 0, 60, 0, 43, 0, 42, 24, 0,
+  22, 0, 17, 0, 7, 0, 0, 0, 0, 9,
+  8, 0, 0, 0, 16, 0, 14, 13, 19, 19,
+  30, 0, 40, 53, 0, 19, 43, 0, 42, 0,
+  0, 11, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 33, 18, 0, 37, 45, 21, 0, 0, 23,
+  29, 0, 60, 0, 0, 7, 11, 13, 0, 17,
+  0, 0, 0, 0, 1, 9, 37, 0, 7, 0,
+  52, 0, 8, 2, 2, 29, 35, 14, 0, 2,
+  25, 15, 25, 0, 0, 41, 100, 0, 19, 33,
+  52, 0, 0, 0, 0, 93, 0, 8, 42, 0,
+  0, 23, 0, 0, 0, 43, 78, 0, 33, 0,
+  0, 18, 0, 68, 0, 56, 40, 13, 39, 47,
+  17, 12, 0, 48, 0, 63, 25, 25, 42, 0,
+  13, 0, 12, 0, 4, 7, 0, 68, 0, 15,
+  1, 0, 32, 0, 7, 15, 0, 11, 0, 0,
+  44, 48, 0, 33, 43, 0, 60, 25, 0, 0,
+  0, 0, 0, 17, 0, 0, 0, 3, 0, 32,
+  43, 0, 2, 82, 3, 0, 8, 22, 34, 0,
+  25, 0, 0, 0, 17, 10, 0, 0, 0, 0,
+  0, 0, 2, 15, 15, 5, 38, 0, 55, 0,
+  13, 0, 0, 0, 0, 2, 0, 130, 10, 0,
+  4, 0, 0, 17, 27, 0, 0, 13, 0, 0,
+  0, 0, 39, 101, 22, 12, 0, 0, 0, 0,
+  0, 3, 0, 24, 35, 28, 1, 0, 0, 22,
+  0, 43, 0, 20, 0, 45, 17, 92, 24, 56,
+  0, 1, 0, 50, 0, 0, 17, 0, 51, 0,
+  51, 0, 0, 57, 0, 0, 72, 8, 0, 8,
+  34, 0, 64, 5, 28, 6, 0, 15, 34, 35,
+  0, 21, 42, 0, 36, 58, 0, 0, 16, 0,
+  0, 0, 0, 14, 4, 0, 0, 35, 0, 0,
+  0, 63, 44, 0, 0, 33, 35, 0, 21, 0,
+  0, 0, 3, 0, 0, 32, 0, 0, 109, 11,
+  25, 17, 0, 0, 0, 0, 15, 0, 0, 0,
+  4, 47, 62, 10, 0, 19, 11, 10, 1, 0,
+  0, 51, 73, 0, 0, 33, 47, 24, 0, 20,
+  69, 64, 93, 12, 0, 0, 0, 23, 0, 0,
+  0, 0, 74, 0, 23, 28, 0, 28, 0, 48,
+  1, 24, 0, 19, 53, 57, 0, 57, 0, 37,
+  0, 54, 25, 0, 42, 0, 29, 0, 2, 0,
+  1, 0, 0, 20, 15, 0, 0, 0, 26, 0,
+  13, 15, 11, 22, 32, 0, 46, 51, 0, 12,
+  44, 0, 35, 0, 0, 8, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 24, 31, 0, 40, 41,
+  11, 0, 10, 24, 51, 0, 57, 0, 0, 3,
+  17, 15, 0, 12, 0, 0, 7, 0, 0, 7,
+  15, 4, 0, 0, 47, 0, 18, 0, 3, 30,
+  27, 20, 0, 12, 23, 23, 27, 0, 0, 40,
+  83, 0, 11, 31, 57, 0, 0, 0, 0, 92,
+  0, 1, 37, 0, 0, 25, 0, 0, 0, 50,
+  77, 0, 34, 0, 0, 19, 0, 54, 0, 46,
+  24, 10, 34, 52, 12, 15, 0, 33, 0, 55,
+  12, 26, 53, 0, 30, 0, 10, 0, 0, 13,
+  0, 58, 0, 13, 0, 0, 32, 0, 13, 16,
+  12, 11, 0, 0, 49, 39, 0, 32, 30, 0,
+  50, 41, 0, 0, 7, 0, 0, 13, 0, 0,
+  0, 16, 0, 30, 52, 0, 6, 80, 2, 0,
+  18, 20, 43, 0, 29, 0, 4, 0, 21, 11,
+  0, 0, 0, 0, 0, 0, 0, 11, 4, 11,
+  36, 0, 51, 0, 18, 0, 0, 0, 0, 5,
+  0, 140, 8, 5, 3, 0, 0, 23, 36, 0,
+  0, 10, 2, 0, 0, 0, 35, 102, 17, 9,
+  0, 0, 0, 0, 0, 21, 0, 23, 35, 21,
+  4, 1, 0, 25, 0, 41, 0, 16, 0, 48,
+  13, 84, 13, 57, 0, 3, 0, 61, 0, 0,
+  24, 0, 45, 0, 39, 0, 0, 51, 0, 0,
+  78, 3, 0, 20, 24, 0, 67, 6, 31, 2,
+  0, 19, 16, 27, 0, 18, 39, 0, 33, 59,
+  0, 0, 10, 0, 0, 0, 0, 8, 0, 0,
+  12, 34, 0, 0, 0, 66, 43, 0, 0, 31,
+  31, 0, 26, 0, 0, 0, 14, 0, 0, 24,
+  0, 0, 117, 2, 21, 20, 0, 0, 0, 0,
+  24, 0, 0, 0, 7, 54, 57, 12, 0, 23,
+  17, 14, 2, 0, 0, 54, 68, 12, 2, 19,
+  58, 30, 0, 13, 72, 61, 94, 10, 0, 0,
+  0, 26, 0, 0, 0, 5, 68, 0, 20, 19,
+  0, 31, 0, 50, 4, 41, 0, 19, 53, 58,
+  0, 66, 0, 27, 0, 55, 24, 0, 51, 0,
+  26, 0, 10, 0, 0, 0, 0, 18, 3, 0,
+  0, 0, 34, 0, 14, 26, 9, 11, 35, 0,
+  48, 32, 0, 34, 37, 0, 35, 0, 0, 7,
+  0, 0, 0, 5, 0, 0, 0, 0, 0, 28,
+  25, 0, 59, 36, 0, 0, 14, 23, 43, 0,
+  49, 0, 0, 6, 11, 5, 0, 11, 0, 0,
+  8, 0, 8, 0, 0, 4, 5, 0, 45, 0,
+  20, 0, 10, 27, 29, 24, 0, 21, 22, 22,
+  24, 0, 0, 43, 79, 0, 6, 26, 56, 0,
+  0, 0, 0, 87, 1, 0, 41, 0, 0, 30,
+  0, 1, 0, 60, 72, 0, 24, 0, 0, 23,
+  0, 54, 0, 47, 13, 10, 23, 49, 26, 18,
+  0, 30, 0, 52, 4, 24, 54, 0, 32, 0,
+  10, 0, 1, 11, 0, 48, 0, 8, 0, 0,
+  39, 0, 18, 26, 11, 0, 0, 2, 47, 27,
+  0, 46, 24, 0, 46, 46, 0, 0, 13, 0,
+  0, 18, 0, 0, 0, 23, 0, 24, 55, 0,
+  15, 78, 0, 0, 25, 19, 40, 0, 26, 0,
+  5, 0, 17, 8, 0, 0, 0, 0, 7, 0,
+  0, 4, 0, 11, 36, 0, 55, 0, 17, 0,
+  0, 0, 0, 7, 0, 153, 0, 0, 0, 0,
+  0, 29, 38, 0, 0, 1, 3, 0, 0, 0,
+  24, 93, 13, 16, 0, 0, 0, 0, 0, 19,
+  0, 24, 31, 29, 0, 8, 0, 29, 0, 45,
+  0, 25, 0, 49, 3, 74, 23, 63, 0, 7,
+  0, 55, 0, 0, 19, 0, 43, 0, 36, 0,
+  0, 49, 0, 0, 76, 0, 0, 27, 37, 0,
+  74, 15, 23, 0, 0, 20, 11, 20, 0, 34,
+  35, 0, 40, 53, 0, 0, 16, 0, 0, 0,
+  0, 13, 0, 0, 26, 27, 0, 0, 0, 73,
+  26, 0, 0, 26, 12, 0, 22, 0, 0, 0,
+  6, 0, 0, 16, 0, 0, 114, 0, 19, 9,
+  0, 0, 0, 0, 29, 0, 0, 0, 2, 29,
+  35, 14, 0, 2, 25, 15, 25, 0, 0, 41,
+  100, 0, 19, 33, 52, 0, 0, 0, 0, 93,
+  0, 8, 42, 0, 0, 23, 0, 0, 0, 43,
+  78, 0, 33, 0, 0, 18, 0, 68, 0, 56,
+  40, 13, 39, 47, 17, 12, 0, 48, 0, 63,
+  25, 25, 42, 0, 13, 0, 12, 0, 4, 7,
+  0, 68, 0, 15, 1, 0, 32, 0, 7, 15,
+  0, 11, 0, 0, 44, 48, 0, 33, 43, 0,
+  60, 25, 0, 0, 0, 0, 0, 17, 0, 0,
+  0, 3, 0, 32, 43, 0, 2, 82, 3, 0,
+  8, 22, 34, 0, 25, 0, 0, 0, 17, 10,
+  0, 0, 0, 0, 0, 0, 2, 15, 15, 5,
+  38, 0, 55, 0, 13, 0, 0, 0, 0, 2,
+  0, 130, 10, 0, 4, 0, 0, 17, 27, 0,
+  0, 13, 0, 0, 0, 0, 39, 101, 22, 12,
+  0, 0, 0, 0, 0, 3, 0, 24, 35, 28,
+  1, 0, 0, 22, 0, 43, 0, 20, 0, 45,
+  17, 92, 24, 56, 0, 1, 0, 50, 0, 0,
+  17, 0, 51, 0, 51, 0, 0, 57, 0, 0,
+  72, 8, 0, 8, 34, 0, 64, 5, 28, 6,
+  0, 15, 34, 35, 0, 21, 42, 0, 36, 58,
+  0, 0, 16, 0, 0, 0, 0, 14, 4, 0,
+  0, 35, 0, 0, 0, 63, 44, 0, 0, 33,
+  35, 0, 21, 0, 0, 0, 3, 0, 0, 32,
+  0, 0, 109, 11, 25, 17, 0, 0, 0, 0,
+  15, 0, 0, 0, 0, 0, 0, 0, 0, 30,
+  33, 0, 19, 0, 21, 0, 43, 0, 16, 54,
+  29, 19, 0, 10, 66, 0, 0, 44, 0, 21,
+  4, 0, 0, 41, 0, 0, 53, 56, 9, 0,
+  0, 0, 0, 18, 0, 34, 0, 47, 24, 21,
+  4, 29, 0, 18, 41, 0, 75, 14, 0, 0,
+  37, 0, 0, 75, 15, 0, 0, 0, 0, 0,
+  34, 16, 0, 0, 0, 2, 0, 21, 12, 35,
+  14, 9, 0, 42, 59, 0, 15, 48, 23, 0,
+  5, 24, 11, 27, 9, 21, 0, 6, 17, 45,
+  0, 0, 9, 43, 26, 0, 0, 0, 17, 0,
+  51, 8, 2, 21, 33, 2, 0, 20, 0, 0,
+  46, 39, 44, 11, 0, 0, 80, 0, 29, 15,
+  0, 0, 3, 30, 27, 20, 0, 12, 23, 23,
+  27, 0, 0, 40, 83, 0, 11, 31, 57, 0,
+  0, 0, 0, 92, 0, 1, 37, 0, 0, 25,
+  0, 0, 0, 50, 77, 0, 34, 0, 0, 19,
+  0, 54, 0, 46, 24, 10, 34, 52, 12, 15,
+  0, 33, 0, 55, 12, 26, 53, 0, 30, 0,
+  10, 0, 0, 13, 0, 58, 0, 13, 0, 0,
+  32, 0, 13, 16, 12, 11, 0, 0, 49, 39,
+  0, 32, 30, 0, 50, 41, 0, 0, 7, 0,
+  0, 13, 0, 0, 0, 16, 0, 30, 52, 0,
+  6, 80, 2, 0, 18, 20, 43, 0, 29, 0,
+  4, 0, 21, 11, 0, 0, 0, 0, 0, 0,
+  0, 11, 4, 11, 36, 0, 51, 0, 18, 0,
+  0, 0, 0, 5, 0, 140, 8, 5, 3, 0,
+  0, 23, 36, 0, 0, 10, 2, 0, 0, 0,
+  35, 102, 17, 9, 0, 0, 0, 0, 0, 21,
+  0, 23, 35, 21, 4, 1, 0, 25, 0, 41,
+  0, 16, 0, 48, 13, 84, 13, 57, 0, 3,
+  0, 61, 0, 0, 24, 0, 45, 0, 39, 0,
+  0, 51, 0, 0, 78, 3, 0, 20, 24, 0,
+  67, 6, 31, 2, 0, 19, 16, 27, 0, 18,
+  39, 0, 33, 59, 0, 0, 10, 0, 0, 0,
+  0, 8, 0, 0, 12, 34, 0, 0, 0, 66,
+  43, 0, 0, 31, 31, 0, 26, 0, 0, 0,
+  14, 0, 0, 24, 0, 0, 117, 2, 21, 20,
+  0, 0, 0, 0, 24, 0, 0, 0, 0, 8,
+  0, 0, 0, 26, 43, 6, 20, 0, 13, 0,
+  59, 0, 10, 62, 36, 31, 3, 0, 46, 0,
+  0, 38, 0, 42, 6, 2, 0, 34, 0, 0,
+  63, 41, 15, 0, 0, 0, 0, 46, 0, 37,
+  0, 53, 25, 14, 17, 17, 0, 32, 15, 5,
+  91, 14, 0, 0, 28, 0, 0, 70, 0, 0,
+  0, 0, 0, 0, 24, 8, 0, 0, 0, 2,
+  0, 9, 17, 48, 0, 3, 0, 31, 71, 5,
+  13, 36, 17, 0, 4, 23, 26, 35, 36, 0,
+  0, 2, 17, 32, 0, 0, 2, 44, 36, 0,
+  0, 0, 12, 0, 55, 13, 24, 46, 43, 0,
+  0, 24, 0, 0, 42, 41, 44, 0, 0, 0,
+  108, 0, 71, 14, 0, 0, 10, 27, 29, 24,
+  0, 21, 22, 22, 24, 0, 0, 43, 79, 0,
+  6, 26, 56, 0, 0, 0, 0, 87, 1, 0,
+  41, 0, 0, 30, 0, 1, 0, 60, 72, 0,
+  24, 0, 0, 23, 0, 54, 0, 47, 13, 10,
+  23, 49, 26, 18, 0, 30, 0, 52, 4, 24,
+  54, 0, 32, 0, 10, 0, 1, 11, 0, 48,
+  0, 8, 0, 0, 39, 0, 18, 26, 11, 0,
+  0, 2, 47, 27, 0, 46, 24, 0, 46, 46,
+  0, 0, 13, 0, 0, 18, 0, 0, 0, 23,
+  0, 24, 55, 0, 15, 78, 0, 0, 25, 19,
+  40, 0, 26, 0, 5, 0, 17, 8, 0, 0,
+  0, 0, 7, 0, 0, 4, 0, 11, 36, 0,
+  55, 0, 17, 0, 0, 0, 0, 7, 0, 153,
+  0, 0, 0, 0, 0, 29, 38, 0, 0, 1,
+  3, 0, 0, 0, 24, 93, 13, 16, 0, 0,
+  0, 0, 0, 19, 0, 24, 31, 29, 0, 8,
+  0, 29, 0, 45, 0, 25, 0, 49, 3, 74,
+  23, 63, 0, 7, 0, 55, 0, 0, 19, 0,
+  43, 0, 36, 0, 0, 49, 0, 0, 76, 0,
+  0, 27, 37, 0, 74, 15, 23, 0, 0, 20,
+  11, 20, 0, 34, 35, 0, 40, 53, 0, 0,
+  16, 0, 0, 0, 0, 13, 0, 0, 26, 27,
+  0, 0, 0, 73, 26, 0, 0, 26, 12, 0,
+  22, 0, 0, 0, 6, 0, 0, 16, 0, 0,
+  114, 0, 19, 9, 0, 0, 0, 0, 29, 0,
+  0, 0, 0, 17, 0, 0, 0, 31, 35, 0,
+  13, 0, 8, 0, 56, 4, 16, 62, 36, 39,
+  10, 0, 30, 0, 0, 48, 4, 53, 0, 4,
+  0, 15, 0, 0, 72, 44, 0, 0, 0, 0,
+  0, 66, 0, 41, 0, 43, 20, 12, 12, 36,
+  0, 41, 0, 7, 95, 16, 0, 0, 21, 0,
+  0, 55, 9, 0, 0, 0, 0, 0, 32, 12,
+  11, 0, 0, 0, 0, 15, 10, 55, 0, 0,
+  0, 47, 64, 4, 32, 22, 15, 0, 7, 27,
+  13, 34, 54, 16, 0, 11, 39, 32, 0, 0,
+  0, 68, 22, 0, 0, 0, 0, 0, 48, 0,
+  0, 30, 26, 15, 0, 27, 0, 0, 25, 30,
+  24, 3, 1, 0, 121, 0, 65, 2, 0, 0,
+  0, 0, 0, 2, 0, 130, 10, 0, 4, 0,
+  0, 17, 27, 0, 0, 13, 0, 0, 0, 0,
+  39, 101, 22, 12, 0, 0, 0, 0, 0, 3,
+  0, 24, 35, 28, 1, 0, 0, 22, 0, 43,
+  0, 20, 0, 45, 17, 92, 24, 56, 0, 1,
+  0, 50, 0, 0, 17, 0, 51, 0, 51, 0,
+  0, 57, 0, 0, 72, 8, 0, 8, 34, 0,
+  64, 5, 28, 6, 0, 15, 34, 35, 0, 21,
+  42, 0, 36, 58, 0, 0, 16, 0, 0, 0,
+  0, 14, 4, 0, 0, 35, 0, 0, 0, 63,
+  44, 0, 0, 33, 35, 0, 21, 0, 0, 0,
+  3, 0, 0, 32, 0, 0, 109, 11, 25, 17,
+  0, 0, 0, 0, 15, 0, 0, 0, 0, 0,
+  0, 0, 0, 30, 33, 0, 19, 0, 21, 0,
+  43, 0, 16, 54, 29, 19, 0, 10, 66, 0,
+  0, 44, 0, 21, 4, 0, 0, 41, 0, 0,
+  53, 56, 9, 0, 0, 0, 0, 18, 0, 34,
+  0, 47, 24, 21, 4, 29, 0, 18, 41, 0,
+  75, 14, 0, 0, 37, 0, 0, 75, 15, 0,
+  0, 0, 0, 0, 34, 16, 0, 0, 0, 2,
+  0, 21, 12, 35, 14, 9, 0, 42, 59, 0,
+  15, 48, 23, 0, 5, 24, 11, 27, 9, 21,
+  0, 6, 17, 45, 0, 0, 9, 43, 26, 0,
+  0, 0, 17, 0, 51, 8, 2, 21, 33, 2,
+  0, 20, 0, 0, 46, 39, 44, 11, 0, 0,
+  80, 0, 29, 15, 0, 0, 0, 47, 63, 0,
+  0, 0, 0, 0, 44, 1, 0, 11, 10, 3,
+  0, 58, 41, 16, 11, 0, 10, 0, 65, 40,
+  0, 0, 36, 16, 0, 0, 0, 0, 20, 0,
+  20, 14, 0, 0, 0, 16, 0, 3, 0, 22,
+  0, 2, 0, 0, 0, 1, 57, 3, 31, 0,
+  0, 0, 29, 0, 0, 14, 3, 0, 0, 0,
+  16, 0, 39, 2, 0, 0, 0, 0, 0, 49,
+  17, 0, 0, 86, 0, 30, 13, 0, 52, 56,
+  3, 30, 0, 29, 23, 24, 50, 0, 0, 0,
+  17, 0, 0, 0, 0, 53, 48, 0, 0, 0,
+  13, 0, 61, 0, 0, 31, 25, 0, 0, 5,
+  0, 0, 7, 0, 0, 16, 0, 0, 30, 0,
+  18, 13, 0, 31, 0, 0, 0, 5, 0, 140,
+  8, 5, 3, 0, 0, 23, 36, 0, 0, 10,
+  2, 0, 0, 0, 35, 102, 17, 9, 0, 0,
+  0, 0, 0, 21, 0, 23, 35, 21, 4, 1,
+  0, 25, 0, 41, 0, 16, 0, 48, 13, 84,
+  13, 57, 0, 3, 0, 61, 0, 0, 24, 0,
+  45, 0, 39, 0, 0, 51, 0, 0, 78, 3,
+  0, 20, 24, 0, 67, 6, 31, 2, 0, 19,
+  16, 27, 0, 18, 39, 0, 33, 59, 0, 0,
+  10, 0, 0, 0, 0, 8, 0, 0, 12, 34,
+  0, 0, 0, 66, 43, 0, 0, 31, 31, 0,
+  26, 0, 0, 0, 14, 0, 0, 24, 0, 0,
+  117, 2, 21, 20, 0, 0, 0, 0, 24, 0,
+  0, 0, 0, 8, 0, 0, 0, 26, 43, 6,
+  20, 0, 13, 0, 59, 0, 10, 62, 36, 31,
+  3, 0, 46, 0, 0, 38, 0, 42, 6, 2,
+  0, 34, 0, 0, 63, 41, 15, 0, 0, 0,
+  0, 46, 0, 37, 0, 53, 25, 14, 17, 17,
+  0, 32, 15, 5, 91, 14, 0, 0, 28, 0,
+  0, 70, 0, 0, 0, 0, 0, 0, 24, 8,
+  0, 0, 0, 2, 0, 9, 17, 48, 0, 3,
+  0, 31, 71, 5, 13, 36, 17, 0, 4, 23,
+  26, 35, 36, 0, 0, 2, 17, 32, 0, 0,
+  2, 44, 36, 0, 0, 0, 12, 0, 55, 13,
+  24, 46, 43, 0, 0, 24, 0, 0, 42, 41,
+  44, 0, 0, 0, 108, 0, 71, 14, 0, 0,
+  0, 44, 70, 0, 0, 0, 0, 9, 53, 0,
+  0, 29, 11, 20, 0, 36, 26, 0, 0, 0,
+  0, 7, 73, 51, 0, 0, 16, 18, 0, 0,
+  0, 0, 0, 0, 29, 22, 0, 0, 0, 40,
+  0, 13, 0, 10, 0, 1, 22, 0, 0, 0,
+  35, 32, 22, 15, 0, 0, 28, 0, 0, 0,
+  0, 0, 0, 0, 20, 0, 30, 0, 2, 0,
+  0, 8, 3, 20, 33, 0, 0, 85, 0, 28,
+  19, 0, 42, 48, 0, 18, 0, 36, 33, 9,
+  46, 0, 0, 0, 8, 0, 0, 0, 0, 81,
+  37, 0, 0, 0, 25, 0, 70, 0, 22, 26,
+  14, 0, 0, 8, 0, 0, 28, 0, 0, 18,
+  0, 0, 19, 0, 44, 20, 0, 20, 0, 0,
+  0, 7, 0, 153, 0, 0, 0, 0, 0, 29,
+  38, 0, 0, 1, 3, 0, 0, 0, 24, 93,
+  13, 16, 0, 0, 0, 0, 0, 19, 0, 24,
+  31, 29, 0, 8, 0, 29, 0, 45, 0, 25,
+  0, 49, 3, 74, 23, 63, 0, 7, 0, 55,
+  0, 0, 19, 0, 43, 0, 36, 0, 0, 49,
+  0, 0, 76, 0, 0, 27, 37, 0, 74, 15,
+  23, 0, 0, 20, 11, 20, 0, 34, 35, 0,
+  40, 53, 0, 0, 16, 0, 0, 0, 0, 13,
+  0, 0, 26, 27, 0, 0, 0, 73, 26, 0,
+  0, 26, 12, 0, 22, 0, 0, 0, 6, 0,
+  0, 16, 0, 0, 114, 0, 19, 9, 0, 0,
+  0, 0, 29, 0, 0, 0, 0, 17, 0, 0,
+  0, 31, 35, 0, 13, 0, 8, 0, 56, 4,
+  16, 62, 36, 39, 10, 0, 30, 0, 0, 48,
+  4, 53, 0, 4, 0, 15, 0, 0, 72, 44,
+  0, 0, 0, 0, 0, 66, 0, 41, 0, 43,
+  20, 12, 12, 36, 0, 41, 0, 7, 95, 16,
+  0, 0, 21, 0, 0, 55, 9, 0, 0, 0,
+  0, 0, 32, 12, 11, 0, 0, 0, 0, 15,
+  10, 55, 0, 0, 0, 47, 64, 4, 32, 22,
+  15, 0, 7, 27, 13, 34, 54, 16, 0, 11,
+  39, 32, 0, 0, 0, 68, 22, 0, 0, 0,
+  0, 0, 48, 0, 0, 30, 26, 15, 0, 27,
+  0, 0, 25, 30, 24, 3, 1, 0, 121, 0,
+  65, 2, 0, 0, 0, 31, 59, 0, 8, 0,
+  0, 0, 53, 2, 0, 9, 30, 0, 0, 23,
+  15, 0, 8, 0, 0, 47, 79, 53, 0, 0,
+  0, 15, 0, 0, 0, 0, 0, 0, 52, 28,
+  0, 4, 0, 63, 0, 25, 0, 1, 0, 0,
+  25, 4, 0, 6, 0, 48, 20, 26, 0, 0,
+  19, 0, 8, 0, 0, 13, 0, 0, 18, 0,
+  16, 0, 9, 0, 10, 19, 20, 21, 21, 5,
+  0, 89, 0, 46, 12, 0, 50, 44, 4, 2,
+  0, 39, 7, 1, 49, 0, 0, 0, 4, 0,
+  0, 0, 6, 91, 22, 0, 0, 0, 9, 0,
+  71, 0, 0, 9, 0, 0, 0, 14, 0, 0,
+  23, 0, 0, 33, 0, 0, 26, 0, 73, 2,
+  0, 1, 0, 0, 0, 0, 0, 30, 33, 0,
+  19, 0, 21, 0, 43, 0, 16, 54, 29, 19,
+  0, 10, 66, 0, 0, 44, 0, 21, 4, 0,
+  0, 41, 0, 0, 53, 56, 9, 0, 0, 0,
+  0, 18, 0, 34, 0, 47, 24, 21, 4, 29,
+  0, 18, 41, 0, 75, 14, 0, 0, 37, 0,
+  0, 75, 15, 0, 0, 0, 0, 0, 34, 16,
+  0, 0, 0, 2, 0, 21, 12, 35, 14, 9,
+  0, 42, 59, 0, 15, 48, 23, 0, 5, 24,
+  11, 27, 9, 21, 0, 6, 17, 45, 0, 0,
+  9, 43, 26, 0, 0, 0, 17, 0, 51, 8,
+  2, 21, 33, 2, 0, 20, 0, 0, 46, 39,
+  44, 11, 0, 0, 80, 0, 29, 15, 0, 0,
+  0, 47, 63, 0, 0, 0, 0, 0, 44, 1,
+  0, 11, 10, 3, 0, 58, 41, 16, 11, 0,
+  10, 0, 65, 40, 0, 0, 36, 16, 0, 0,
+  0, 0, 20, 0, 20, 14, 0, 0, 0, 16,
+  0, 3, 0, 22, 0, 2, 0, 0, 0, 1,
+  57, 3, 31, 0, 0, 0, 29, 0, 0, 14,
+  3, 0, 0, 0, 16, 0, 39, 2, 0, 0,
+  0, 0, 0, 49, 17, 0, 0, 86, 0, 30,
+  13, 0, 52, 56, 3, 30, 0, 29, 23, 24,
+  50, 0, 0, 0, 17, 0, 0, 0, 0, 53,
+  48, 0, 0, 0, 13, 0, 61, 0, 0, 31,
+  25, 0, 0, 5, 0, 0, 7, 0, 0, 16,
+  0, 0, 30, 0, 18, 13, 0, 31, 103, 0,
+  37, 5, 6, 15, 0, 0, 15, 0, 0, 23,
+  47, 54, 0, 0, 22, 0, 6, 0, 0, 173,
+  80, 13, 0, 0, 0, 33, 0, 0, 2, 56,
+  0, 34, 0, 21, 0, 29, 0, 25, 0, 22,
+  0, 0, 27, 6, 10, 8, 0, 0, 0, 77,
+  0, 0, 89, 0, 43, 20, 45, 0, 35, 11,
+  0, 32, 30, 49, 7, 15, 23, 23, 7, 28,
+  0, 22, 0, 0, 3, 45, 0, 13, 0, 0,
+  4, 42, 8, 27, 0, 9, 0, 0, 0, 0,
+  8, 0, 7, 0, 24, 0, 27, 61, 2, 0,
+  25, 0, 40, 28, 4, 8, 10, 35, 4, 0,
+  0, 0, 0, 15, 78, 0, 23, 10, 0, 35,
+  0, 0, 20, 3, 3, 48, 0, 8, 0, 0,
+  0, 26, 43, 6, 20, 0, 13, 0, 59, 0,
+  10, 62, 36, 31, 3, 0, 46, 0, 0, 38,
+  0, 42, 6, 2, 0, 34, 0, 0, 63, 41,
+  15, 0, 0, 0, 0, 46, 0, 37, 0, 53,
+  25, 14, 17, 17, 0, 32, 15, 5, 91, 14,
+  0, 0, 28, 0, 0, 70, 0, 0, 0, 0,
+  0, 0, 24, 8, 0, 0, 0, 2, 0, 9,
+  17, 48, 0, 3, 0, 31, 71, 5, 13, 36,
+  17, 0, 4, 23, 26, 35, 36, 0, 0, 2,
+  17, 32, 0, 0, 2, 44, 36, 0, 0, 0,
+  12, 0, 55, 13, 24, 46, 43, 0, 0, 24,
+  0, 0, 42, 41, 44, 0, 0, 0, 108, 0,
+  71, 14, 0, 0, 0, 44, 70, 0, 0, 0,
+  0, 9, 53, 0, 0, 29, 11, 20, 0, 36,
+  26, 0, 0, 0, 0, 7, 73, 51, 0, 0,
+  16, 18, 0, 0, 0, 0, 0, 0, 29, 22,
+  0, 0, 0, 40, 0, 13, 0, 10, 0, 1,
+  22, 0, 0, 0, 35, 32, 22, 15, 0, 0,
+  28, 0, 0, 0, 0, 0, 0, 0, 20, 0,
+  30, 0, 2, 0, 0, 8, 3, 20, 33, 0,
+  0, 85, 0, 28, 19, 0, 42, 48, 0, 18,
+  0, 36, 33, 9, 46, 0, 0, 0, 8, 0,
+  0, 0, 0, 81, 37, 0, 0, 0, 25, 0,
+  70, 0, 22, 26, 14, 0, 0, 8, 0, 0,
+  28, 0, 0, 18, 0, 0, 19, 0, 44, 20,
+  0, 20, 102, 0, 40, 4, 0, 12, 0, 0,
+  45, 0, 0, 35, 56, 20, 0, 0, 9, 0,
+  0, 0, 0, 189, 80, 25, 0, 0, 0, 31,
+  0, 0, 16, 61, 0, 11, 0, 30, 0, 40,
+  0, 30, 0, 28, 48, 0, 38, 21, 24, 29,
+  0, 0, 0, 80, 0, 0, 100, 0, 63, 0,
+  47, 0, 14, 23, 0, 56, 27, 66, 0, 1,
+  0, 4, 12, 26, 10, 13, 0, 0, 0, 47,
+  0, 15, 0, 0, 7, 21, 0, 11, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 25, 0,
+  18, 61, 0, 0, 17, 0, 54, 23, 26, 12,
+  6, 14, 8, 6, 0, 0, 0, 2, 87, 0,
+  36, 39, 0, 9, 0, 0, 23, 15, 18, 29,
+  0, 17, 0, 0, 0, 31, 35, 0, 13, 0,
+  8, 0, 56, 4, 16, 62, 36, 39, 10, 0,
+  30, 0, 0, 48, 4, 53, 0, 4, 0, 15,
+  0, 0, 72, 44, 0, 0, 0, 0, 0, 66,
+  0, 41, 0, 43, 20, 12, 12, 36, 0, 41,
+  0, 7, 95, 16, 0, 0, 21, 0, 0, 55,
+  9, 0, 0, 0, 0, 0, 32, 12, 11, 0,
+  0, 0, 0, 15, 10, 55, 0, 0, 0, 47,
+  64, 4, 32, 22, 15, 0, 7, 27, 13, 34,
+  54, 16, 0, 11, 39, 32, 0, 0, 0, 68,
+  22, 0, 0, 0, 0, 0, 48, 0, 0, 30,
+  26, 15, 0, 27, 0, 0, 25, 30, 24, 3,
+  1, 0, 121, 0, 65, 2, 0, 0, 0, 31,
+  59, 0, 8, 0, 0, 0, 53, 2, 0, 9,
+  30, 0, 0, 23, 15, 0, 8, 0, 0, 47,
+  79, 53, 0, 0, 0, 15, 0, 0, 0, 0,
+  0, 0, 52, 28, 0, 4, 0, 63, 0, 25,
+  0, 1, 0, 0, 25, 4, 0, 6, 0, 48,
+  20, 26, 0, 0, 19, 0, 8, 0, 0, 13,
+  0, 0, 18, 0, 16, 0, 9, 0, 10, 19,
+  20, 21, 21, 5, 0, 89, 0, 46, 12, 0,
+  50, 44, 4, 2, 0, 39, 7, 1, 49, 0,
+  0, 0, 4, 0, 0, 0, 6, 91, 22, 0,
+  0, 0, 9, 0, 71, 0, 0, 9, 0, 0,
+  0, 14, 0, 0, 23, 0, 0, 33, 0, 0,
+  26, 0, 73, 2, 0, 1, 73, 0, 21, 29,
+  10, 2, 0, 11, 74, 0, 0, 18, 94, 0,
+  0, 0, 36, 0, 0, 0, 0, 148, 91, 19,
+  0, 0, 0, 47, 0, 0, 32, 47, 0, 0,
+  27, 32, 0, 52, 0, 43, 0, 24, 66, 17,
+  51, 51, 13, 28, 0, 0, 0, 63, 0, 0,
+  62, 0, 50, 0, 39, 0, 0, 6, 0, 30,
+  12, 20, 0, 4, 0, 0, 19, 4, 40, 42,
+  0, 0, 0, 87, 0, 19, 0, 0, 16, 26,
+  0, 11, 0, 0, 0, 0, 0, 0, 0, 8,
+  0, 0, 35, 0, 15, 55, 0, 0, 22, 0,
+  52, 8, 59, 31, 3, 19, 8, 16, 0, 0,
+  0, 0, 66, 0, 18, 40, 0, 4, 0, 0,
+  51, 0, 18, 14, 0, 47, 63, 0, 0, 0,
+  0, 0, 44, 1, 0, 11, 10, 3, 0, 58,
+  41, 16, 11, 0, 10, 0, 65, 40, 0, 0,
+  36, 16, 0, 0, 0, 0, 20, 0, 20, 14,
+  0, 0, 0, 16, 0, 3, 0, 22, 0, 2,
+  0, 0, 0, 1, 57, 3, 31, 0, 0, 0,
+  29, 0, 0, 14, 3, 0, 0, 0, 16, 0,
+  39, 2, 0, 0, 0, 0, 0, 49, 17, 0,
+  0, 86, 0, 30, 13, 0, 52, 56, 3, 30,
+  0, 29, 23, 24, 50, 0, 0, 0, 17, 0,
+  0, 0, 0, 53, 48, 0, 0, 0, 13, 0,
+  61, 0, 0, 31, 25, 0, 0, 5, 0, 0,
+  7, 0, 0, 16, 0, 0, 30, 0, 18, 13,
+  0, 31, 103, 0, 37, 5, 6, 15, 0, 0,
+  15, 0, 0, 23, 47, 54, 0, 0, 22, 0,
+  6, 0, 0, 173, 80, 13, 0, 0, 0, 33,
+  0, 0, 2, 56, 0, 34, 0, 21, 0, 29,
+  0, 25, 0, 22, 0, 0, 27, 6, 10, 8,
+  0, 0, 0, 77, 0, 0, 89, 0, 43, 20,
+  45, 0, 35, 11, 0, 32, 30, 49, 7, 15,
+  23, 23, 7, 28, 0, 22, 0, 0, 3, 45,
+  0, 13, 0, 0, 4, 42, 8, 27, 0, 9,
+  0, 0, 0, 0, 8, 0, 7, 0, 24, 0,
+  27, 61, 2, 0, 25, 0, 40, 28, 4, 8,
+  10, 35, 4, 0, 0, 0, 0, 15, 78, 0,
+  23, 10, 0, 35, 0, 0, 20, 3, 3, 48,
+  45, 0, 0, 0, 22, 82, 0, 0, 8, 0,
+  0, 0, 29, 61, 0, 8, 48, 0, 0, 0,
+  21, 71, 5, 41, 10, 3, 0, 14, 0, 2,
+  0, 9, 0, 69, 34, 19, 0, 41, 0, 34,
+  7, 20, 0, 34, 59, 23, 26, 10, 5, 0,
+  0, 0, 0, 0, 0, 0, 18, 22, 10, 15,
+  30, 39, 10, 0, 0, 0, 16, 36, 52, 0,
+  27, 32, 3, 0, 12, 28, 0, 21, 0, 48,
+  0, 2, 0, 34, 13, 5, 17, 11, 0, 25,
+  0, 47, 10, 1, 26, 5, 0, 0, 0, 67,
+  13, 0, 12, 0, 16, 0, 0, 15, 0, 51,
+  0, 0, 0, 0, 0, 0, 69, 0, 19, 0,
+  19, 11, 0, 0, 29, 2, 31, 0, 0, 44,
+  70, 0, 0, 0, 0, 9, 53, 0, 0, 29,
+  11, 20, 0, 36, 26, 0, 0, 0, 0, 7,
+  73, 51, 0, 0, 16, 18, 0, 0, 0, 0,
+  0, 0, 29, 22, 0, 0, 0, 40, 0, 13,
+  0, 10, 0, 1, 22, 0, 0, 0, 35, 32,
+  22, 15, 0, 0, 28, 0, 0, 0, 0, 0,
+  0, 0, 20, 0, 30, 0, 2, 0, 0, 8,
+  3, 20, 33, 0, 0, 85, 0, 28, 19, 0,
+  42, 48, 0, 18, 0, 36, 33, 9, 46, 0,
+  0, 0, 8, 0, 0, 0, 0, 81, 37, 0,
+  0, 0, 25, 0, 70, 0, 22, 26, 14, 0,
+  0, 8, 0, 0, 28, 0, 0, 18, 0, 0,
+  19, 0, 44, 20, 0, 20, 102, 0, 40, 4,
+  0, 12, 0, 0, 45, 0, 0, 35, 56, 20,
+  0, 0, 9, 0, 0, 0, 0, 189, 80, 25,
+  0, 0, 0, 31, 0, 0, 16, 61, 0, 11,
+  0, 30, 0, 40, 0, 30, 0, 28, 48, 0,
+  38, 21, 24, 29, 0, 0, 0, 80, 0, 0,
+  100, 0, 63, 0, 47, 0, 14, 23, 0, 56,
+  27, 66, 0, 1, 0, 4, 12, 26, 10, 13,
+  0, 0, 0, 47, 0, 15, 0, 0, 7, 21,
+  0, 11, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 25, 0, 18, 61, 0, 0, 17, 0,
+  54, 23, 26, 12, 6, 14, 8, 6, 0, 0,
+  0, 2, 87, 0, 36, 39, 0, 9, 0, 0,
+  23, 15, 18, 29, 9, 0, 0, 9, 0, 65,
+  0, 0, 41, 0, 0, 0, 45, 38, 0, 38,
+  32, 25, 0, 0, 8, 14, 5, 56, 28, 0,
+  0, 19, 0, 0, 0, 21, 10, 40, 27, 4,
+  0, 33, 0, 8, 9, 4, 50, 58, 50, 77,
+  14, 17, 0, 0, 0, 0, 0, 0, 0, 0,
+  54, 0, 0, 0, 4, 43, 0, 0, 0, 0,
+  0, 0, 12, 0, 54, 0, 14, 11, 0, 28,
+  0, 28, 0, 28, 0, 16, 0, 39, 0, 0,
+  31, 0, 14, 62, 0, 63, 0, 0, 13, 17,
+  0, 0, 0, 56, 19, 0, 0, 0, 17, 0,
+  0, 4, 0, 40, 0, 0, 0, 9, 0, 0,
+  61, 0, 8, 0, 37, 0, 3, 0, 29, 10,
+  44, 0, 0, 31, 59, 0, 8, 0, 0, 0,
+  53, 2, 0, 9, 30, 0, 0, 23, 15, 0,
+  8, 0, 0, 47, 79, 53, 0, 0, 0, 15,
+  0, 0, 0, 0, 0, 0, 52, 28, 0, 4,
+  0, 63, 0, 25, 0, 1, 0, 0, 25, 4,
+  0, 6, 0, 48, 20, 26, 0, 0, 19, 0,
+  8, 0, 0, 13, 0, 0, 18, 0, 16, 0,
+  9, 0, 10, 19, 20, 21, 21, 5, 0, 89,
+  0, 46, 12, 0, 50, 44, 4, 2, 0, 39,
+  7, 1, 49, 0, 0, 0, 4, 0, 0, 0,
+  6, 91, 22, 0, 0, 0, 9, 0, 71, 0,
+  0, 9, 0, 0, 0, 14, 0, 0, 23, 0,
+  0, 33, 0, 0, 26, 0, 73, 2, 0, 1,
+  73, 0, 21, 29, 10, 2, 0, 11, 74, 0,
+  0, 18, 94, 0, 0, 0, 36, 0, 0, 0,
+  0, 148, 91, 19, 0, 0, 0, 47, 0, 0,
+  32, 47, 0, 0, 27, 32, 0, 52, 0, 43,
+  0, 24, 66, 17, 51, 51, 13, 28, 0, 0,
+  0, 63, 0, 0, 62, 0, 50, 0, 39, 0,
+  0, 6, 0, 30, 12, 20, 0, 4, 0, 0,
+  19, 4, 40, 42, 0, 0, 0, 87, 0, 19,
+  0, 0, 16, 26, 0, 11, 0, 0, 0, 0,
+  0, 0, 0, 8, 0, 0, 35, 0, 15, 55,
+  0, 0, 22, 0, 52, 8, 59, 31, 3, 19,
+  8, 16, 0, 0, 0, 0, 66, 0, 18, 40,
+  0, 4, 0, 0, 51, 0, 18, 14, 0, 0,
+  0, 29, 1, 29, 8, 0, 54, 0, 0, 0,
+  67, 10, 9, 37, 50, 41, 0, 0, 0, 0,
+  0, 46, 33, 11, 2, 31, 0, 0, 8, 47,
+  45, 22, 0, 0, 0, 51, 0, 0, 0, 0,
+  95, 63, 29, 90, 0, 25, 0, 0, 0, 1,
+  11, 3, 0, 0, 29, 0, 0, 1, 0, 38,
+  0, 0, 3, 0, 26, 25, 4, 0, 48, 0,
+  30, 61, 0, 8, 0, 30, 0, 18, 0, 0,
+  0, 54, 0, 2, 33, 0, 0, 26, 0, 44,
+  0, 32, 0, 43, 0, 0, 0, 39, 13, 0,
+  8, 0, 38, 0, 3, 19, 0, 10, 9, 7,
+  0, 4, 0, 0, 50, 0, 0, 18, 13, 0,
+  27, 0, 42, 0, 53, 0, 103, 0, 37, 5,
+  6, 15, 0, 0, 15, 0, 0, 23, 47, 54,
+  0, 0, 22, 0, 6, 0, 0, 173, 80, 13,
+  0, 0, 0, 33, 0, 0, 2, 56, 0, 34,
+  0, 21, 0, 29, 0, 25, 0, 22, 0, 0,
+  27, 6, 10, 8, 0, 0, 0, 77, 0, 0,
+  89, 0, 43, 20, 45, 0, 35, 11, 0, 32,
+  30, 49, 7, 15, 23, 23, 7, 28, 0, 22,
+  0, 0, 3, 45, 0, 13, 0, 0, 4, 42,
+  8, 27, 0, 9, 0, 0, 0, 0, 8, 0,
+  7, 0, 24, 0, 27, 61, 2, 0, 25, 0,
+  40, 28, 4, 8, 10, 35, 4, 0, 0, 0,
+  0, 15, 78, 0, 23, 10, 0, 35, 0, 0,
+  20, 3, 3, 48, 45, 0, 0, 0, 22, 82,
+  0, 0, 8, 0, 0, 0, 29, 61, 0, 8,
+  48, 0, 0, 0, 21, 71, 5, 41, 10, 3,
+  0, 14, 0, 2, 0, 9, 0, 69, 34, 19,
+  0, 41, 0, 34, 7, 20, 0, 34, 59, 23,
+  26, 10, 5, 0, 0, 0, 0, 0, 0, 0,
+  18, 22, 10, 15, 30, 39, 10, 0, 0, 0,
+  16, 36, 52, 0, 27, 32, 3, 0, 12, 28,
+  0, 21, 0, 48, 0, 2, 0, 34, 13, 5,
+  17, 11, 0, 25, 0, 47, 10, 1, 26, 5,
+  0, 0, 0, 67, 13, 0, 12, 0, 16, 0,
+  0, 15, 0, 51, 0, 0, 0, 0, 0, 0,
+  69, 0, 19, 0, 19, 11, 0, 0, 29, 2,
+  31, 0, 0, 24, 0, 0, 40, 11, 0, 0,
+  61, 11, 0, 15, 51, 85, 31, 58, 61, 16,
+  0, 9, 60, 0, 0, 53, 11, 51, 1, 8,
+  0, 10, 0, 0, 0, 42, 35, 0, 15, 23,
+  0, 51, 12, 18, 0, 69, 33, 20, 9, 0,
+  0, 0, 24, 0, 57, 28, 0, 0, 0, 2,
+  0, 18, 0, 0, 0, 0, 0, 0, 31, 0,
+  42, 0, 0, 0, 4, 14, 36, 12, 0, 6,
+  0, 29, 44, 60, 4, 0, 34, 12, 53, 16,
+  53, 25, 0, 50, 0, 27, 0, 9, 0, 0,
+  31, 64, 0, 0, 0, 0, 0, 0, 0, 12,
+  10, 60, 0, 0, 0, 0, 0, 0, 10, 13,
+  32, 0, 25, 0, 76, 0, 51, 15, 31, 0,
+  102, 0, 40, 4, 0, 12, 0, 0, 45, 0,
+  0, 35, 56, 20, 0, 0, 9, 0, 0, 0,
+  0, 189, 80, 25, 0, 0, 0, 31, 0, 0,
+  16, 61, 0, 11, 0, 30, 0, 40, 0, 30,
+  0, 28, 48, 0, 38, 21, 24, 29, 0, 0,
+  0, 80, 0, 0, 100, 0, 63, 0, 47, 0,
+  14, 23, 0, 56, 27, 66, 0, 1, 0, 4,
+  12, 26, 10, 13, 0, 0, 0, 47, 0, 15,
+  0, 0, 7, 21, 0, 11, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 25, 0, 18, 61,
+  0, 0, 17, 0, 54, 23, 26, 12, 6, 14,
+  8, 6, 0, 0, 0, 2, 87, 0, 36, 39,
+  0, 9, 0, 0, 23, 15, 18, 29, 9, 0,
+  0, 9, 0, 65, 0, 0, 41, 0, 0, 0,
+  45, 38, 0, 38, 32, 25, 0, 0, 8, 14,
+  5, 56, 28, 0, 0, 19, 0, 0, 0, 21,
+  10, 40, 27, 4, 0, 33, 0, 8, 9, 4,
+  50, 58, 50, 77, 14, 17, 0, 0, 0, 0,
+  0, 0, 0, 0, 54, 0, 0, 0, 4, 43,
+  0, 0, 0, 0, 0, 0, 12, 0, 54, 0,
+  14, 11, 0, 28, 0, 28, 0, 28, 0, 16,
+  0, 39, 0, 0, 31, 0, 14, 62, 0, 63,
+  0, 0, 13, 17, 0, 0, 0, 56, 19, 0,
+  0, 0, 17, 0, 0, 4, 0, 40, 0, 0,
+  0, 9, 0, 0, 61, 0, 8, 0, 37, 0,
+  3, 0, 29, 10, 44, 0, 0, 14, 0, 0,
+  35, 12, 0, 0, 40, 0, 0, 15, 31, 88,
+  14, 51, 40, 12, 0, 18, 47, 0, 19, 50,
+  3, 20, 0, 2, 0, 0, 0, 0, 0, 38,
+  7, 0, 3, 31, 0, 29, 36, 1, 0, 74,
+  29, 39, 8, 0, 0, 0, 18, 2, 39, 14,
+  0, 6, 37, 0, 0, 0, 0, 4, 5, 0,
+  0, 0, 26, 0, 49, 0, 0, 0, 3, 3,
+  17, 22, 0, 17, 0, 21, 27, 60, 0, 26,
+  24, 3, 57, 0, 52, 33, 0, 62, 14, 8,
+  23, 27, 0, 0, 26, 70, 5, 0, 0, 0,
+  0, 0, 0, 16, 0, 35, 0, 0, 0, 12,
+  0, 0, 17, 3, 26, 0, 0, 0, 20, 0,
+  35, 8, 37, 0, 73, 0, 21, 29, 10, 2,
+  0, 11, 74, 0, 0, 18, 94, 0, 0, 0,
+  36, 0, 0, 0, 0, 148, 91, 19, 0, 0,
+  0, 47, 0, 0, 32, 47, 0, 0, 27, 32,
+  0, 52, 0, 43, 0, 24, 66, 17, 51, 51,
+  13, 28, 0, 0, 0, 63, 0, 0, 62, 0,
+  50, 0, 39, 0, 0, 6, 0, 30, 12, 20,
+  0, 4, 0, 0, 19, 4, 40, 42, 0, 0,
+  0, 87, 0, 19, 0, 0, 16, 26, 0, 11,
+  0, 0, 0, 0, 0, 0, 0, 8, 0, 0,
+  35, 0, 15, 55, 0, 0, 22, 0, 52, 8,
+  59, 31, 3, 19, 8, 16, 0, 0, 0, 0,
+  66, 0, 18, 40, 0, 4, 0, 0, 51, 0,
+  18, 14, 0, 0, 0, 29, 1, 29, 8, 0,
+  54, 0, 0, 0, 67, 10, 9, 37, 50, 41,
+  0, 0, 0, 0, 0, 46, 33, 11, 2, 31,
+  0, 0, 8, 47, 45, 22, 0, 0, 0, 51,
+  0, 0, 0, 0, 95, 63, 29, 90, 0, 25,
+  0, 0, 0, 1, 11, 3, 0, 0, 29, 0,
+  0, 1, 0, 38, 0, 0, 3, 0, 26, 25,
+  4, 0, 48, 0, 30, 61, 0, 8, 0, 30,
+  0, 18, 0, 0, 0, 54, 0, 2, 33, 0,
+  0, 26, 0, 44, 0, 32, 0, 43, 0, 0,
+  0, 39, 13, 0, 8, 0, 38, 0, 3, 19,
+  0, 10, 9, 7, 0, 4, 0, 0, 50, 0,
+  0, 18, 13, 0, 27, 0, 42, 0, 53, 0,
+  0, 0, 0, 5, 36, 43, 0, 0, 0, 0,
+  0, 1, 24, 87, 0, 16, 36, 0, 0, 9,
+  34, 0, 19, 29, 0, 11, 0, 0, 0, 24,
+  7, 0, 0, 36, 0, 0, 0, 26, 0, 8,
+  20, 9, 0, 66, 26, 13, 0, 36, 0, 0,
+  2, 42, 7, 10, 0, 0, 26, 0, 0, 0,
+  0, 31, 20, 0, 10, 0, 10, 15, 33, 0,
+  6, 11, 0, 7, 9, 11, 0, 16, 0, 29,
+  9, 31, 0, 20, 48, 0, 63, 19, 21, 0,
+  0, 52, 14, 4, 22, 50, 0, 0, 0, 71,
+  13, 0, 0, 0, 0, 0, 0, 1, 0, 0,
+  3, 0, 0, 16, 0, 8, 57, 0, 8, 0,
+  0, 0, 0, 0, 20, 1, 25, 0, 45, 0,
+  0, 0, 22, 82, 0, 0, 8, 0, 0, 0,
+  29, 61, 0, 8, 48, 0, 0, 0, 21, 71,
+  5, 41, 10, 3, 0, 14, 0, 2, 0, 9,
+  0, 69, 34, 19, 0, 41, 0, 34, 7, 20,
+  0, 34, 59, 23, 26, 10, 5, 0, 0, 0,
+  0, 0, 0, 0, 18, 22, 10, 15, 30, 39,
+  10, 0, 0, 0, 16, 36, 52, 0, 27, 32,
+  3, 0, 12, 28, 0, 21, 0, 48, 0, 2,
+  0, 34, 13, 5, 17, 11, 0, 25, 0, 47,
+  10, 1, 26, 5, 0, 0, 0, 67, 13, 0,
+  12, 0, 16, 0, 0, 15, 0, 51, 0, 0,
+  0, 0, 0, 0, 69, 0, 19, 0, 19, 11,
+  0, 0, 29, 2, 31, 0, 0, 24, 0, 0,
+  40, 11, 0, 0, 61, 11, 0, 15, 51, 85,
+  31, 58, 61, 16, 0, 9, 60, 0, 0, 53,
+  11, 51, 1, 8, 0, 10, 0, 0, 0, 42,
+  35, 0, 15, 23, 0, 51, 12, 18, 0, 69,
+  33, 20, 9, 0, 0, 0, 24, 0, 57, 28,
+  0, 0, 0, 2, 0, 18, 0, 0, 0, 0,
+  0, 0, 31, 0, 42, 0, 0, 0, 4, 14,
+  36, 12, 0, 6, 0, 29, 44, 60, 4, 0,
+  34, 12, 53, 16, 53, 25, 0, 50, 0, 27,
+  0, 9, 0, 0, 31, 64, 0, 0, 0, 0,
+  0, 0, 0, 12, 10, 60, 0, 0, 0, 0,
+  0, 0, 10, 13, 32, 0, 25, 0, 76, 0,
+  51, 15, 31, 0, 0, 35, 50, 0, 10, 0,
+  0, 0, 51, 2, 0, 18, 8, 100, 10, 27,
+  39, 26, 2, 4, 44, 0, 34, 24, 0, 0,
+  0, 5, 0, 0, 0, 0, 0, 0, 0, 0,
+  5, 0, 0, 22, 18, 0, 0, 35, 0, 0,
+  0, 0, 0, 0, 52, 66, 0, 34, 0, 0,
+  6, 2, 0, 0, 0, 0, 13, 0, 38, 2,
+  22, 0, 23, 0, 0, 0, 3, 15, 29, 0,
+  0, 37, 0, 21, 32, 48, 11, 18, 40, 3,
+  53, 7, 75, 6, 0, 23, 0, 0, 0, 1,
+  0, 0, 40, 70, 1, 0, 0, 0, 7, 0,
+  0, 9, 0, 8, 32, 0, 0, 0, 57, 0,
+  10, 0, 12, 0, 0, 0, 8, 0, 9, 14,
+  37, 0, 9, 0, 0, 9, 0, 65, 0, 0,
+  41, 0, 0, 0, 45, 38, 0, 38, 32, 25,
+  0, 0, 8, 14, 5, 56, 28, 0, 0, 19,
+  0, 0, 0, 21, 10, 40, 27, 4, 0, 33,
+  0, 8, 9, 4, 50, 58, 50, 77, 14, 17,
+  0, 0, 0, 0, 0, 0, 0, 0, 54, 0,
+  0, 0, 4, 43, 0, 0, 0, 0, 0, 0,
+  12, 0, 54, 0, 14, 11, 0, 28, 0, 28,
+  0, 28, 0, 16, 0, 39, 0, 0, 31, 0,
+  14, 62, 0, 63, 0, 0, 13, 17, 0, 0,
+  0, 56, 19, 0, 0, 0, 17, 0, 0, 4,
+  0, 40, 0, 0, 0, 9, 0, 0, 61, 0,
+  8, 0, 37, 0, 3, 0, 29, 10, 44, 0,
+  0, 14, 0, 0, 35, 12, 0, 0, 40, 0,
+  0, 15, 31, 88, 14, 51, 40, 12, 0, 18,
+  47, 0, 19, 50, 3, 20, 0, 2, 0, 0,
+  0, 0, 0, 38, 7, 0, 3, 31, 0, 29,
+  36, 1, 0, 74, 29, 39, 8, 0, 0, 0,
+  18, 2, 39, 14, 0, 6, 37, 0, 0, 0,
+  0, 4, 5, 0, 0, 0, 26, 0, 49, 0,
+  0, 0, 3, 3, 17, 22, 0, 17, 0, 21,
+  27, 60, 0, 26, 24, 3, 57, 0, 52, 33,
+  0, 62, 14, 8, 23, 27, 0, 0, 26, 70,
+  5, 0, 0, 0, 0, 0, 0, 16, 0, 35,
+  0, 0, 0, 12, 0, 0, 17, 3, 26, 0,
+  0, 0, 20, 0, 35, 8, 37, 0, 24, 0,
+  53, 0, 32, 0, 0, 0, 25, 0, 0, 1,
+  9, 122, 15, 0, 27, 21, 0, 8, 41, 13,
+  69, 7, 0, 0, 0, 4, 0, 0, 0, 0,
+  0, 5, 0, 0, 0, 4, 0, 26, 14, 10,
+  0, 48, 14, 0, 0, 0, 0, 0, 37, 104,
+  0, 37, 0, 0, 9, 6, 3, 0, 0, 0,
+  33, 0, 50, 22, 0, 0, 24, 22, 0, 1,
+  0, 0, 27, 0, 0, 13, 0, 41, 14, 36,
+  0, 5, 48, 0, 45, 11, 72, 0, 0, 2,
+  0, 0, 0, 25, 0, 0, 41, 57, 0, 0,
+  0, 0, 0, 0, 0, 10, 1, 0, 35, 0,
+  0, 0, 51, 0, 55, 0, 5, 0, 0, 0,
+  0, 0, 28, 1, 16, 0, 0, 0, 0, 29,
+  1, 29, 8, 0, 54, 0, 0, 0, 67, 10,
+  9, 37, 50, 41, 0, 0, 0, 0, 0, 46,
+  33, 11, 2, 31, 0, 0, 8, 47, 45, 22,
+  0, 0, 0, 51, 0, 0, 0, 0, 95, 63,
+  29, 90, 0, 25, 0, 0, 0, 1, 11, 3,
+  0, 0, 29, 0, 0, 1, 0, 38, 0, 0,
+  3, 0, 26, 25, 4, 0, 48, 0, 30, 61,
+  0, 8, 0, 30, 0, 18, 0, 0, 0, 54,
+  0, 2, 33, 0, 0, 26, 0, 44, 0, 32,
+  0, 43, 0, 0, 0, 39, 13, 0, 8, 0,
+  38, 0, 3, 19, 0, 10, 9, 7, 0, 4,
+  0, 0, 50, 0, 0, 18, 13, 0, 27, 0,
+  42, 0, 53, 0, 0, 0, 0, 5, 36, 43,
+  0, 0, 0, 0, 0, 1, 24, 87, 0, 16,
+  36, 0, 0, 9, 34, 0, 19, 29, 0, 11,
+  0, 0, 0, 24, 7, 0, 0, 36, 0, 0,
+  0, 26, 0, 8, 20, 9, 0, 66, 26, 13,
+  0, 36, 0, 0, 2, 42, 7, 10, 0, 0,
+  26, 0, 0, 0, 0, 31, 20, 0, 10, 0,
+  10, 15, 33, 0, 6, 11, 0, 7, 9, 11,
+  0, 16, 0, 29, 9, 31, 0, 20, 48, 0,
+  63, 19, 21, 0, 0, 52, 14, 4, 22, 50,
+  0, 0, 0, 71, 13, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 3, 0, 0, 16, 0, 8,
+  57, 0, 8, 0, 0, 0, 0, 0, 20, 1,
+  25, 0, 15, 8, 22, 22, 74, 0, 0, 1,
+  31, 0, 0, 0, 40, 118, 28, 13, 44, 0,
+  0, 9, 37, 0, 0, 12, 0, 12, 0, 24,
+  0, 17, 2, 0, 0, 38, 0, 0, 0, 6,
+  0, 44, 0, 22, 0, 57, 17, 0, 18, 21,
+  0, 0, 25, 88, 0, 60, 0, 0, 0, 21,
+  0, 0, 0, 0, 0, 0, 0, 3, 13, 0,
+  39, 0, 0, 18, 0, 0, 44, 0, 0, 3,
+  0, 44, 27, 45, 2, 0, 52, 4, 48, 24,
+  64, 0, 0, 0, 0, 16, 0, 45, 3, 2,
+  31, 57, 0, 0, 0, 0, 0, 0, 0, 10,
+  30, 7, 17, 0, 0, 0, 33, 0, 43, 0,
+  0, 0, 30, 0, 35, 0, 54, 0, 0, 0,
+  0, 24, 0, 0, 40, 11, 0, 0, 61, 11,
+  0, 15, 51, 85, 31, 58, 61, 16, 0, 9,
+  60, 0, 0, 53, 11, 51, 1, 8, 0, 10,
+  0, 0, 0, 42, 35, 0, 15, 23, 0, 51,
+  12, 18, 0, 69, 33, 20, 9, 0, 0, 0,
+  24, 0, 57, 28, 0, 0, 0, 2, 0, 18,
+  0, 0, 0, 0, 0, 0, 31, 0, 42, 0,
+  0, 0, 4, 14, 36, 12, 0, 6, 0, 29,
+  44, 60, 4, 0, 34, 12, 53, 16, 53, 25,
+  0, 50, 0, 27, 0, 9, 0, 0, 31, 64,
+  0, 0, 0, 0, 0, 0, 0, 12, 10, 60,
+  0, 0, 0, 0, 0, 0, 10, 13, 32, 0,
+  25, 0, 76, 0, 51, 15, 31, 0, 0, 35,
+  50, 0, 10, 0, 0, 0, 51, 2, 0, 18,
+  8, 100, 10, 27, 39, 26, 2, 4, 44, 0,
+  34, 24, 0, 0, 0, 5, 0, 0, 0, 0,
+  0, 0, 0, 0, 5, 0, 0, 22, 18, 0,
+  0, 35, 0, 0, 0, 0, 0, 0, 52, 66,
+  0, 34, 0, 0, 6, 2, 0, 0, 0, 0,
+  13, 0, 38, 2, 22, 0, 23, 0, 0, 0,
+  3, 15, 29, 0, 0, 37, 0, 21, 32, 48,
+  11, 18, 40, 3, 53, 7, 75, 6, 0, 23,
+  0, 0, 0, 1, 0, 0, 40, 70, 1, 0,
+  0, 0, 7, 0, 0, 9, 0, 8, 32, 0,
+  0, 0, 57, 0, 10, 0, 12, 0, 0, 0,
+  8, 0, 9, 14, 37, 0, 22, 0, 59, 0,
+  0, 0, 0, 0, 23, 0, 0, 0, 0, 116,
+  1, 0, 6, 27, 1, 0, 38, 30, 84, 8,
+  0, 0, 0, 4, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 2, 0, 0, 28, 17, 0, 30,
+  0, 0, 0, 0, 0, 0, 35, 131, 0, 15,
+  36, 0, 30, 17, 14, 0, 0, 0, 34, 0,
+  88, 47, 7, 2, 16, 67, 0, 0, 0, 0,
+  11, 0, 0, 0, 0, 24, 16, 22, 0, 15,
+  41, 0, 31, 10, 71, 0, 0, 11, 2, 0,
+  0, 5, 0, 0, 62, 66, 0, 0, 0, 0,
+  12, 10, 0, 7, 0, 0, 50, 0, 0, 0,
+  91, 3, 77, 0, 19, 0, 0, 0, 0, 0,
+  21, 6, 10, 0, 0, 14, 0, 0, 35, 12,
+  0, 0, 40, 0, 0, 15, 31, 88, 14, 51,
+  40, 12, 0, 18, 47, 0, 19, 50, 3, 20,
+  0, 2, 0, 0, 0, 0, 0, 38, 7, 0,
+  3, 31, 0, 29, 36, 1, 0, 74, 29, 39,
+  8, 0, 0, 0, 18, 2, 39, 14, 0, 6,
+  37, 0, 0, 0, 0, 4, 5, 0, 0, 0,
+  26, 0, 49, 0, 0, 0, 3, 3, 17, 22,
+  0, 17, 0, 21, 27, 60, 0, 26, 24, 3,
+  57, 0, 52, 33, 0, 62, 14, 8, 23, 27,
+  0, 0, 26, 70, 5, 0, 0, 0, 0, 0,
+  0, 16, 0, 35, 0, 0, 0, 12, 0, 0,
+  17, 3, 26, 0, 0, 0, 20, 0, 35, 8,
+  37, 0, 24, 0, 53, 0, 32, 0, 0, 0,
+  25, 0, 0, 1, 9, 122, 15, 0, 27, 21,
+  0, 8, 41, 13, 69, 7, 0, 0, 0, 4,
+  0, 0, 0, 0, 0, 5, 0, 0, 0, 4,
+  0, 26, 14, 10, 0, 48, 14, 0, 0, 0,
+  0, 0, 37, 104, 0, 37, 0, 0, 9, 6,
+  3, 0, 0, 0, 33, 0, 50, 22, 0, 0,
+  24, 22, 0, 1, 0, 0, 27, 0, 0, 13,
+  0, 41, 14, 36, 0, 5, 48, 0, 45, 11,
+  72, 0, 0, 2, 0, 0, 0, 25, 0, 0,
+  41, 57, 0, 0, 0, 0, 0, 0, 0, 10,
+  1, 0, 35, 0, 0, 0, 51, 0, 55, 0,
+  5, 0, 0, 0, 0, 0, 28, 1, 16, 0,
+  30, 0, 17, 10, 31, 0, 0, 0, 35, 0,
+  0, 3, 12, 104, 13, 0, 18, 16, 0, 5,
+  51, 0, 33, 3, 0, 0, 0, 16, 0, 15,
+  0, 9, 0, 7, 0, 0, 0, 0, 0, 7,
+  0, 12, 0, 50, 13, 0, 0, 0, 0, 0,
+  32, 102, 0, 61, 0, 0, 22, 15, 0, 0,
+  0, 0, 29, 0, 32, 22, 10, 15, 12, 12,
+  0, 0, 0, 0, 42, 0, 0, 0, 0, 33,
+  26, 38, 0, 3, 31, 0, 30, 10, 63, 12,
+  0, 0, 0, 0, 0, 25, 23, 0, 69, 64,
+  0, 0, 2, 0, 4, 5, 0, 9, 49, 0,
+  33, 0, 0, 3, 60, 0, 68, 0, 0, 0,
+  8, 0, 0, 0, 49, 3, 11, 0, 0, 0,
+  0, 5, 36, 43, 0, 0, 0, 0, 0, 1,
+  24, 87, 0, 16, 36, 0, 0, 9, 34, 0,
+  19, 29, 0, 11, 0, 0, 0, 24, 7, 0,
+  0, 36, 0, 0, 0, 26, 0, 8, 20, 9,
+  0, 66, 26, 13, 0, 36, 0, 0, 2, 42,
+  7, 10, 0, 0, 26, 0, 0, 0, 0, 31,
+  20, 0, 10, 0, 10, 15, 33, 0, 6, 11,
+  0, 7, 9, 11, 0, 16, 0, 29, 9, 31,
+  0, 20, 48, 0, 63, 19, 21, 0, 0, 52,
+  14, 4, 22, 50, 0, 0, 0, 71, 13, 0,
+  0, 0, 0, 0, 0, 1, 0, 0, 3, 0,
+  0, 16, 0, 8, 57, 0, 8, 0, 0, 0,
+  0, 0, 20, 1, 25, 0, 15, 8, 22, 22,
+  74, 0, 0, 1, 31, 0, 0, 0, 40, 118,
+  28, 13, 44, 0, 0, 9, 37, 0, 0, 12,
+  0, 12, 0, 24, 0, 17, 2, 0, 0, 38,
+  0, 0, 0, 6, 0, 44, 0, 22, 0, 57,
+  17, 0, 18, 21, 0, 0, 25, 88, 0, 60,
+  0, 0, 0, 21, 0, 0, 0, 0, 0, 0,
+  0, 3, 13, 0, 39, 0, 0, 18, 0, 0,
+  44, 0, 0, 3, 0, 44, 27, 45, 2, 0,
+  52, 4, 48, 24, 64, 0, 0, 0, 0, 16,
+  0, 45, 3, 2, 31, 57, 0, 0, 0, 0,
+  0, 0, 0, 10, 30, 7, 17, 0, 0, 0,
+  33, 0, 43, 0, 0, 0, 30, 0, 35, 0,
+  54, 0, 0, 0, 0, 42, 26, 36, 66, 0,
+  0, 14, 62, 8, 0, 3, 37, 89, 51, 42,
+  59, 7, 0, 10, 42, 0, 0, 21, 16, 33,
+  0, 45, 0, 0, 4, 0, 0, 27, 0, 0,
+  0, 13, 0, 62, 0, 3, 0, 70, 16, 0,
+  32, 0, 0, 0, 21, 64, 8, 79, 0, 0,
+  0, 31, 0, 20, 0, 0, 0, 0, 0, 0,
+  49, 0, 44, 0, 0, 0, 0, 2, 62, 0,
+  0, 25, 0, 37, 50, 81, 8, 1, 28, 19,
+  26, 9, 59, 14, 0, 0, 0, 31, 0, 46,
+  17, 31, 61, 56, 0, 0, 3, 0, 4, 0,
+  0, 6, 50, 28, 14, 0, 0, 0, 10, 0,
+  0, 0, 0, 0, 7, 1, 83, 0, 80, 2,
+  9, 0, 0, 35, 50, 0, 10, 0, 0, 0,
+  51, 2, 0, 18, 8, 100, 10, 27, 39, 26,
+  2, 4, 44, 0, 34, 24, 0, 0, 0, 5,
+  0, 0, 0, 0, 0, 0, 0, 0, 5, 0,
+  0, 22, 18, 0, 0, 35, 0, 0, 0, 0,
+  0, 0, 52, 66, 0, 34, 0, 0, 6, 2,
+  0, 0, 0, 0, 13, 0, 38, 2, 22, 0,
+  23, 0, 0, 0, 3, 15, 29, 0, 0, 37,
+  0, 21, 32, 48, 11, 18, 40, 3, 53, 7,
+  75, 6, 0, 23, 0, 0, 0, 1, 0, 0,
+  40, 70, 1, 0, 0, 0, 7, 0, 0, 9,
+  0, 8, 32, 0, 0, 0, 57, 0, 10, 0,
+  12, 0, 0, 0, 8, 0, 9, 14, 37, 0,
+  22, 0, 59, 0, 0, 0, 0, 0, 23, 0,
+  0, 0, 0, 116, 1, 0, 6, 27, 1, 0,
+  38, 30, 84, 8, 0, 0, 0, 4, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 2, 0, 0,
+  28, 17, 0, 30, 0, 0, 0, 0, 0, 0,
+  35, 131, 0, 15, 36, 0, 30, 17, 14, 0,
+  0, 0, 34, 0, 88, 47, 7, 2, 16, 67,
+  0, 0, 0, 0, 11, 0, 0, 0, 0, 24,
+  16, 22, 0, 15, 41, 0, 31, 10, 71, 0,
+  0, 11, 2, 0, 0, 5, 0, 0, 62, 66,
+  0, 0, 0, 0, 12, 10, 0, 7, 0, 0,
+  50, 0, 0, 0, 91, 3, 77, 0, 19, 0,
+  0, 0, 0, 0, 21, 6, 10, 0, 20, 0,
+  19, 16, 0, 0, 0, 0, 29, 0, 0, 0,
+  2, 73, 0, 0, 0, 28, 8, 5, 49, 5,
+  52, 6, 0, 0, 0, 7, 0, 12, 6, 1,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 29,
+  0, 45, 0, 0, 0, 16, 0, 0, 39, 114,
+  0, 30, 15, 0, 35, 10, 0, 0, 0, 0,
+  31, 0, 77, 23, 0, 26, 0, 48, 0, 8,
+  0, 0, 25, 0, 0, 0, 0, 24, 31, 18,
+  0, 15, 42, 0, 28, 19, 61, 0, 0, 0,
+  0, 0, 0, 9, 24, 0, 72, 41, 0, 0,
+  3, 0, 0, 0, 0, 13, 37, 0, 43, 0,
+  0, 5, 84, 0, 93, 0, 17, 0, 7, 5,
+  0, 0, 42, 4, 0, 0, 24, 0, 53, 0,
+  32, 0, 0, 0, 25, 0, 0, 1, 9, 122,
+  15, 0, 27, 21, 0, 8, 41, 13, 69, 7,
+  0, 0, 0, 4, 0, 0, 0, 0, 0, 5,
+  0, 0, 0, 4, 0, 26, 14, 10, 0, 48,
+  14, 0, 0, 0, 0, 0, 37, 104, 0, 37,
+  0, 0, 9, 6, 3, 0, 0, 0, 33, 0,
+  50, 22, 0, 0, 24, 22, 0, 1, 0, 0,
+  27, 0, 0, 13, 0, 41, 14, 36, 0, 5,
+  48, 0, 45, 11, 72, 0, 0, 2, 0, 0,
+  0, 25, 0, 0, 41, 57, 0, 0, 0, 0,
+  0, 0, 0, 10, 1, 0, 35, 0, 0, 0,
+  51, 0, 55, 0, 5, 0, 0, 0, 0, 0,
+  28, 1, 16, 0, 30, 0, 17, 10, 31, 0,
+  0, 0, 35, 0, 0, 3, 12, 104, 13, 0,
+  18, 16, 0, 5, 51, 0, 33, 3, 0, 0,
+  0, 16, 0, 15, 0, 9, 0, 7, 0, 0,
+  0, 0, 0, 7, 0, 12, 0, 50, 13, 0,
+  0, 0, 0, 0, 32, 102, 0, 61, 0, 0,
+  22, 15, 0, 0, 0, 0, 29, 0, 32, 22,
+  10, 15, 12, 12, 0, 0, 0, 0, 42, 0,
+  0, 0, 0, 33, 26, 38, 0, 3, 31, 0,
+  30, 10, 63, 12, 0, 0, 0, 0, 0, 25,
+  23, 0, 69, 64, 0, 0, 2, 0, 4, 5,
+  0, 9, 49, 0, 33, 0, 0, 3, 60, 0,
+  68, 0, 0, 0, 8, 0, 0, 0, 49, 3,
+  11, 0, 0, 22, 0, 46, 29, 0, 0, 10,
+  69, 0, 0, 23, 38, 83, 24, 20, 35, 2,
+  0, 9, 58, 0, 0, 0, 4, 48, 0, 23,
+  0, 8, 10, 0, 0, 43, 1, 0, 0, 4,
+  0, 24, 0, 21, 0, 69, 0, 0, 10, 17,
+  0, 0, 39, 72, 4, 92, 0, 0, 6, 27,
+  0, 37, 0, 0, 0, 0, 0, 8, 23, 24,
+  37, 0, 0, 3, 0, 0, 58, 0, 0, 14,
+  0, 39, 58, 70, 0, 0, 36, 5, 31, 21,
+  43, 20, 8, 4, 0, 16, 0, 28, 38, 0,
+  72, 48, 0, 0, 6, 0, 2, 0, 0, 22,
+  64, 11, 22, 0, 0, 9, 42, 0, 28, 0,
+  0, 0, 25, 29, 79, 0, 79, 5, 10, 0,
+  15, 8, 22, 22, 74, 0, 0, 1, 31, 0,
+  0, 0, 40, 118, 28, 13, 44, 0, 0, 9,
+  37, 0, 0, 12, 0, 12, 0, 24, 0, 17,
+  2, 0, 0, 38, 0, 0, 0, 6, 0, 44,
+  0, 22, 0, 57, 17, 0, 18, 21, 0, 0,
+  25, 88, 0, 60, 0, 0, 0, 21, 0, 0,
+  0, 0, 0, 0, 0, 3, 13, 0, 39, 0,
+  0, 18, 0, 0, 44, 0, 0, 3, 0, 44,
+  27, 45, 2, 0, 52, 4, 48, 24, 64, 0,
+  0, 0, 0, 16, 0, 45, 3, 2, 31, 57,
+  0, 0, 0, 0, 0, 0, 0, 10, 30, 7,
+  17, 0, 0, 0, 33, 0, 43, 0, 0, 0,
+  30, 0, 35, 0, 54, 0, 0, 0, 0, 42,
+  26, 36, 66, 0, 0, 14, 62, 8, 0, 3,
+  37, 89, 51, 42, 59, 7, 0, 10, 42, 0,
+  0, 21, 16, 33, 0, 45, 0, 0, 4, 0,
+  0, 27, 0, 0, 0, 13, 0, 62, 0, 3,
+  0, 70, 16, 0, 32, 0, 0, 0, 21, 64,
+  8, 79, 0, 0, 0, 31, 0, 20, 0, 0,
+  0, 0, 0, 0, 49, 0, 44, 0, 0, 0,
+  0, 2, 62, 0, 0, 25, 0, 37, 50, 81,
+  8, 1, 28, 19, 26, 9, 59, 14, 0, 0,
+  0, 31, 0, 46, 17, 31, 61, 56, 0, 0,
+  3, 0, 4, 0, 0, 6, 50, 28, 14, 0,
+  0, 0, 10, 0, 0, 0, 0, 0, 7, 1,
+  83, 0, 80, 2, 9, 0, 0, 25, 11, 47,
+  41, 0, 0, 5, 47, 1, 0, 16, 5, 75,
+  19, 28, 49, 26, 0, 33, 25, 0, 0, 0,
+  18, 25, 0, 34, 0, 0, 0, 0, 0, 42,
+  0, 0, 0, 16, 0, 27, 0, 0, 0, 56,
+  0, 7, 36, 0, 0, 0, 0, 20, 0, 61,
+  0, 0, 3, 18, 0, 21, 2, 0, 0, 0,
+  0, 0, 62, 6, 75, 21, 0, 0, 9, 9,
+  54, 0, 0, 53, 0, 0, 29, 74, 8, 11,
+  30, 30, 27, 34, 17, 0, 0, 29, 0, 0,
+  22, 13, 14, 0, 41, 57, 0, 6, 0, 0,
+  3, 28, 0, 7, 12, 5, 0, 0, 0, 6,
+  0, 0, 0, 0, 0, 0, 0, 0, 32, 0,
+  54, 11, 27, 0, 22, 0, 59, 0, 0, 0,
+  0, 0, 23, 0, 0, 0, 0, 116, 1, 0,
+  6, 27, 1, 0, 38, 30, 84, 8, 0, 0,
+  0, 4, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 2, 0, 0, 28, 17, 0, 30, 0, 0,
+  0, 0, 0, 0, 35, 131, 0, 15, 36, 0,
+  30, 17, 14, 0, 0, 0, 34, 0, 88, 47,
+  7, 2, 16, 67, 0, 0, 0, 0, 11, 0,
+  0, 0, 0, 24, 16, 22, 0, 15, 41, 0,
+  31, 10, 71, 0, 0, 11, 2, 0, 0, 5,
+  0, 0, 62, 66, 0, 0, 0, 0, 12, 10,
+  0, 7, 0, 0, 50, 0, 0, 0, 91, 3,
+  77, 0, 19, 0, 0, 0, 0, 0, 21, 6,
+  10, 0, 20, 0, 19, 16, 0, 0, 0, 0,
+  29, 0, 0, 0, 2, 73, 0, 0, 0, 28,
+  8, 5, 49, 5, 52, 6, 0, 0, 0, 7,
+  0, 12, 6, 1, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 29, 0, 45, 0, 0, 0, 16,
+  0, 0, 39, 114, 0, 30, 15, 0, 35, 10,
+  0, 0, 0, 0, 31, 0, 77, 23, 0, 26,
+  0, 48, 0, 8, 0, 0, 25, 0, 0, 0,
+  0, 24, 31, 18, 0, 15, 42, 0, 28, 19,
+  61, 0, 0, 0, 0, 0, 0, 9, 24, 0,
+  72, 41, 0, 0, 3, 0, 0, 0, 0, 13,
+  37, 0, 43, 0, 0, 5, 84, 0, 93, 0,
+  17, 0, 7, 5, 0, 0, 42, 4, 0, 0,
+  3, 16, 0, 41, 1, 0, 4, 6, 70, 0,
+  0, 11, 25, 55, 18, 0, 14, 4, 17, 0,
+  52, 0, 0, 17, 0, 16, 4, 14, 0, 32,
+  2, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 25, 0, 53, 0, 0, 5, 16, 0, 0,
+  58, 87, 18, 68, 0, 0, 15, 25, 0, 19,
+  0, 0, 0, 0, 0, 11, 7, 13, 8, 0,
+  0, 9, 0, 0, 44, 3, 0, 0, 0, 43,
+  57, 57, 0, 0, 32, 0, 31, 33, 74, 29,
+  25, 0, 0, 0, 0, 11, 45, 0, 71, 48,
+  0, 0, 7, 0, 2, 0, 0, 12, 74, 6,
+  34, 0, 0, 0, 67, 0, 49, 0, 0, 0,
+  48, 9, 63, 0, 76, 0, 5, 0, 30, 0,
+  17, 10, 31, 0, 0, 0, 35, 0, 0, 3,
+  12, 104, 13, 0, 18, 16, 0, 5, 51, 0,
+  33, 3, 0, 0, 0, 16, 0, 15, 0, 9,
+  0, 7, 0, 0, 0, 0, 0, 7, 0, 12,
+  0, 50, 13, 0, 0, 0, 0, 0, 32, 102,
+  0, 61, 0, 0, 22, 15, 0, 0, 0, 0,
+  29, 0, 32, 22, 10, 15, 12, 12, 0, 0,
+  0, 0, 42, 0, 0, 0, 0, 33, 26, 38,
+  0, 3, 31, 0, 30, 10, 63, 12, 0, 0,
+  0, 0, 0, 25, 23, 0, 69, 64, 0, 0,
+  2, 0, 4, 5, 0, 9, 49, 0, 33, 0,
+  0, 3, 60, 0, 68, 0, 0, 0, 8, 0,
+  0, 0, 49, 3, 11, 0, 0, 22, 0, 46,
+  29, 0, 0, 10, 69, 0, 0, 23, 38, 83,
+  24, 20, 35, 2, 0, 9, 58, 0, 0, 0,
+  4, 48, 0, 23, 0, 8, 10, 0, 0, 43,
+  1, 0, 0, 4, 0, 24, 0, 21, 0, 69,
+  0, 0, 10, 17, 0, 0, 39, 72, 4, 92,
+  0, 0, 6, 27, 0, 37, 0, 0, 0, 0,
+  0, 8, 23, 24, 37, 0, 0, 3, 0, 0,
+  58, 0, 0, 14, 0, 39, 58, 70, 0, 0,
+  36, 5, 31, 21, 43, 20, 8, 4, 0, 16,
+  0, 28, 38, 0, 72, 48, 0, 0, 6, 0,
+  2, 0, 0, 22, 64, 11, 22, 0, 0, 9,
+  42, 0, 28, 0, 0, 0, 25, 29, 79, 0,
+  79, 5, 10, 0, 0, 19, 0, 49, 12, 0,
+  0, 25, 85, 2, 1, 7, 23, 85, 32, 34,
+  52, 0, 5, 0, 23, 0, 0, 0, 0, 25,
+  0, 34, 0, 0, 0, 0, 0, 25, 0, 0,
+  0, 0, 0, 23, 0, 6, 0, 46, 0, 0,
+  22, 18, 0, 0, 24, 75, 20, 83, 0, 0,
+  0, 46, 0, 19, 0, 0, 0, 0, 0, 30,
+  41, 0, 59, 0, 0, 0, 0, 12, 50, 0,
+  0, 9, 0, 32, 59, 63, 9, 0, 17, 31,
+  16, 61, 46, 0, 20, 36, 0, 0, 0, 9,
+  42, 0, 48, 63, 0, 0, 0, 0, 9, 0,
+  0, 19, 28, 6, 15, 0, 0, 0, 28, 0,
+  22, 0, 0, 0, 15, 1, 73, 0, 78, 3,
+  7, 0, 0, 42, 26, 36, 66, 0, 0, 14,
+  62, 8, 0, 3, 37, 89, 51, 42, 59, 7,
+  0, 10, 42, 0, 0, 21, 16, 33, 0, 45,
+  0, 0, 4, 0, 0, 27, 0, 0, 0, 13,
+  0, 62, 0, 3, 0, 70, 16, 0, 32, 0,
+  0, 0, 21, 64, 8, 79, 0, 0, 0, 31,
+  0, 20, 0, 0, 0, 0, 0, 0, 49, 0,
+  44, 0, 0, 0, 0, 2, 62, 0, 0, 25,
+  0, 37, 50, 81, 8, 1, 28, 19, 26, 9,
+  59, 14, 0, 0, 0, 31, 0, 46, 17, 31,
+  61, 56, 0, 0, 3, 0, 4, 0, 0, 6,
+  50, 28, 14, 0, 0, 0, 10, 0, 0, 0,
+  0, 0, 7, 1, 83, 0, 80, 2, 9, 0,
+  0, 25, 11, 47, 41, 0, 0, 5, 47, 1,
+  0, 16, 5, 75, 19, 28, 49, 26, 0, 33,
+  25, 0, 0, 0, 18, 25, 0, 34, 0, 0,
+  0, 0, 0, 42, 0, 0, 0, 16, 0, 27,
+  0, 0, 0, 56, 0, 7, 36, 0, 0, 0,
+  0, 20, 0, 61, 0, 0, 3, 18, 0, 21,
+  2, 0, 0, 0, 0, 0, 62, 6, 75, 21,
+  0, 0, 9, 9, 54, 0, 0, 53, 0, 0,
+  29, 74, 8, 11, 30, 30, 27, 34, 17, 0,
+  0, 29, 0, 0, 22, 13, 14, 0, 41, 57,
+  0, 6, 0, 0, 3, 28, 0, 7, 12, 5,
+  0, 0, 0, 6, 0, 0, 0, 0, 0, 0,
+  0, 0, 32, 0, 54, 11, 27, 0, 0, 0,
+  0, 70, 0, 0, 0, 2, 33, 0, 0, 0,
+  0, 43, 0, 6, 22, 39, 0, 28, 7, 0,
+  9, 0, 0, 0, 28, 31, 0, 0, 0, 0,
+  0, 29, 0, 0, 2, 27, 0, 0, 0, 0,
+  0, 6, 0, 5, 36, 29, 18, 0, 0, 0,
+  0, 40, 0, 15, 23, 36, 0, 10, 8, 17,
+  0, 4, 56, 0, 56, 30, 68, 85, 5, 0,
+  19, 21, 32, 0, 0, 9, 20, 0, 0, 41,
+  10, 0, 11, 39, 17, 55, 0, 0, 0, 81,
+  0, 0, 54, 0, 6, 0, 21, 50, 24, 33,
+  0, 0, 0, 40, 0, 5, 0, 0, 0, 0,
+  0, 0, 7, 0, 7, 0, 0, 0, 0, 0,
+  0, 0, 0, 21, 20, 0, 20, 0, 19, 16,
+  0, 0, 0, 0, 29, 0, 0, 0, 2, 73,
+  0, 0, 0, 28, 8, 5, 49, 5, 52, 6,
+  0, 0, 0, 7, 0, 12, 6, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 29, 0, 45,
+  0, 0, 0, 16, 0, 0, 39, 114, 0, 30,
+  15, 0, 35, 10, 0, 0, 0, 0, 31, 0,
+  77, 23, 0, 26, 0, 48, 0, 8, 0, 0,
+  25, 0, 0, 0, 0, 24, 31, 18, 0, 15,
+  42, 0, 28, 19, 61, 0, 0, 0, 0, 0,
+  0, 9, 24, 0, 72, 41, 0, 0, 3, 0,
+  0, 0, 0, 13, 37, 0, 43, 0, 0, 5,
+  84, 0, 93, 0, 17, 0, 7, 5, 0, 0,
+  42, 4, 0, 0, 3, 16, 0, 41, 1, 0,
+  4, 6, 70, 0, 0, 11, 25, 55, 18, 0,
+  14, 4, 17, 0, 52, 0, 0, 17, 0, 16,
+  4, 14, 0, 32, 2, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 25, 0, 53, 0, 0,
+  5, 16, 0, 0, 58, 87, 18, 68, 0, 0,
+  15, 25, 0, 19, 0, 0, 0, 0, 0, 11,
+  7, 13, 8, 0, 0, 9, 0, 0, 44, 3,
+  0, 0, 0, 43, 57, 57, 0, 0, 32, 0,
+  31, 33, 74, 29, 25, 0, 0, 0, 0, 11,
+  45, 0, 71, 48, 0, 0, 7, 0, 2, 0,
+  0, 12, 74, 6, 34, 0, 0, 0, 67, 0,
+  49, 0, 0, 0, 48, 9, 63, 0, 76, 0,
+  5, 0, 0, 29, 0, 36, 17, 0, 0, 1,
+  82, 0, 0, 10, 14, 80, 41, 0, 22, 8,
+  10, 0, 47, 0, 0, 23, 0, 13, 0, 15,
+  0, 5, 0, 0, 0, 11, 0, 0, 0, 0,
+  0, 11, 0, 0, 0, 51, 0, 0, 23, 16,
+  0, 0, 35, 72, 21, 74, 0, 0, 3, 24,
+  0, 11, 0, 0, 0, 0, 0, 21, 29, 0,
+  30, 0, 0, 0, 0, 0, 58, 0, 0, 0,
+  0, 30, 56, 60, 4, 0, 25, 0, 29, 51,
+  61, 17, 7, 13, 0, 0, 0, 14, 29, 0,
+  67, 43, 0, 16, 0, 0, 10, 1, 0, 7,
+  54, 13, 18, 0, 0, 0, 34, 0, 15, 0,
+  0, 0, 35, 0, 63, 0, 64, 0, 8, 0,
+  0, 22, 0, 46, 29, 0, 0, 10, 69, 0,
+  0, 23, 38, 83, 24, 20, 35, 2, 0, 9,
+  58, 0, 0, 0, 4, 48, 0, 23, 0, 8,
+  10, 0, 0, 43, 1, 0, 0, 4, 0, 24,
+  0, 21, 0, 69, 0, 0, 10, 17, 0, 0,
+  39, 72, 4, 92, 0, 0, 6, 27, 0, 37,
+  0, 0, 0, 0, 0, 8, 23, 24, 37, 0,
+  0, 3, 0, 0, 58, 0, 0, 14, 0, 39,
+  58, 70, 0, 0, 36, 5, 31, 21, 43, 20,
+  8, 4, 0, 16, 0, 28, 38, 0, 72, 48,
+  0, 0, 6, 0, 2, 0, 0, 22, 64, 11,
+  22, 0, 0, 9, 42, 0, 28, 0, 0, 0,
+  25, 29, 79, 0, 79, 5, 10, 0, 0, 19,
+  0, 49, 12, 0, 0, 25, 85, 2, 1, 7,
+  23, 85, 32, 34, 52, 0, 5, 0, 23, 0,
+  0, 0, 0, 25, 0, 34, 0, 0, 0, 0,
+  0, 25, 0, 0, 0, 0, 0, 23, 0, 6,
+  0, 46, 0, 0, 22, 18, 0, 0, 24, 75,
+  20, 83, 0, 0, 0, 46, 0, 19, 0, 0,
+  0, 0, 0, 30, 41, 0, 59, 0, 0, 0,
+  0, 12, 50, 0, 0, 9, 0, 32, 59, 63,
+  9, 0, 17, 31, 16, 61, 46, 0, 20, 36,
+  0, 0, 0, 9, 42, 0, 48, 63, 0, 0,
+  0, 0, 9, 0, 0, 19, 28, 6, 15, 0,
+  0, 0, 28, 0, 22, 0, 0, 0, 15, 1,
+  73, 0, 78, 3, 7, 0, 0, 4, 2, 46,
+  13, 0, 0, 32, 107, 4, 2, 0, 4, 83,
+  44, 32, 46, 4, 0, 0, 3, 0, 0, 10,
+  0, 0, 0, 35, 0, 0, 0, 0, 0, 15,
+  0, 0, 0, 0, 0, 24, 0, 0, 0, 32,
+  0, 0, 49, 17, 0, 0, 0, 80, 25, 73,
+  0, 0, 0, 50, 0, 3, 0, 0, 0, 0,
+  0, 35, 49, 0, 61, 9, 0, 0, 3, 17,
+  57, 9, 0, 0, 0, 10, 48, 46, 9, 0,
+  7, 32, 17, 79, 43, 0, 37, 35, 0, 0,
+  0, 5, 31, 0, 49, 67, 11, 1, 0, 0,
+  15, 0, 0, 19, 8, 3, 5, 0, 0, 0,
+  19, 0, 26, 0, 0, 0, 5, 0, 65, 0,
+  62, 0, 2, 0, 0, 25, 11, 47, 41, 0,
+  0, 5, 47, 1, 0, 16, 5, 75, 19, 28,
+  49, 26, 0, 33, 25, 0, 0, 0, 18, 25,
+  0, 34, 0, 0, 0, 0, 0, 42, 0, 0,
+  0, 16, 0, 27, 0, 0, 0, 56, 0, 7,
+  36, 0, 0, 0, 0, 20, 0, 61, 0, 0,
+  3, 18, 0, 21, 2, 0, 0, 0, 0, 0,
+  62, 6, 75, 21, 0, 0, 9, 9, 54, 0,
+  0, 53, 0, 0, 29, 74, 8, 11, 30, 30,
+  27, 34, 17, 0, 0, 29, 0, 0, 22, 13,
+  14, 0, 41, 57, 0, 6, 0, 0, 3, 28,
+  0, 7, 12, 5, 0, 0, 0, 6, 0, 0,
+  0, 0, 0, 0, 0, 0, 32, 0, 54, 11,
+  27, 0, 0, 0, 0, 70, 0, 0, 0, 2,
+  33, 0, 0, 0, 0, 43, 0, 6, 22, 39,
+  0, 28, 7, 0, 9, 0, 0, 0, 28, 31,
+  0, 0, 0, 0, 0, 29, 0, 0, 2, 27,
+  0, 0, 0, 0, 0, 6, 0, 5, 36, 29,
+  18, 0, 0, 0, 0, 40, 0, 15, 23, 36,
+  0, 10, 8, 17, 0, 4, 56, 0, 56, 30,
+  68, 85, 5, 0, 19, 21, 32, 0, 0, 9,
+  20, 0, 0, 41, 10, 0, 11, 39, 17, 55,
+  0, 0, 0, 81, 0, 0, 54, 0, 6, 0,
+  21, 50, 24, 33, 0, 0, 0, 40, 0, 5,
+  0, 0, 0, 0, 0, 0, 7, 0, 7, 0,
+  0, 0, 0, 0, 0, 0, 0, 21, 20, 0,
+  0, 8, 0, 102, 1, 0, 0, 14, 69, 27,
+  0, 0, 0, 1, 0, 66, 27, 37, 0, 17,
+  6, 0, 0, 0, 2, 0, 52, 58, 12, 0,
+  0, 0, 14, 27, 0, 0, 6, 45, 0, 0,
+  2, 0, 0, 11, 0, 17, 56, 34, 0, 0,
+  0, 0, 2, 38, 0, 25, 6, 68, 0, 37,
+  0, 16, 0, 2, 22, 0, 50, 18, 67, 47,
+  0, 0, 22, 50, 27, 21, 0, 3, 14, 0,
+  29, 40, 11, 0, 0, 47, 18, 59, 13, 0,
+  37, 101, 0, 22, 37, 0, 12, 0, 20, 34,
+  37, 0, 0, 0, 4, 0, 0, 14, 0, 6,
+  0, 13, 0, 0, 10, 0, 0, 0, 0, 0,
+  4, 0, 56, 0, 21, 28, 9, 0, 3, 16,
+  0, 41, 1, 0, 4, 6, 70, 0, 0, 11,
+  25, 55, 18, 0, 14, 4, 17, 0, 52, 0,
+  0, 17, 0, 16, 4, 14, 0, 32, 2, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 25,
+  0, 53, 0, 0, 5, 16, 0, 0, 58, 87,
+  18, 68, 0, 0, 15, 25, 0, 19, 0, 0,
+  0, 0, 0, 11, 7, 13, 8, 0, 0, 9,
+  0, 0, 44, 3, 0, 0, 0, 43, 57, 57,
+  0, 0, 32, 0, 31, 33, 74, 29, 25, 0,
+  0, 0, 0, 11, 45, 0, 71, 48, 0, 0,
+  7, 0, 2, 0, 0, 12, 74, 6, 34, 0,
+  0, 0, 67, 0, 49, 0, 0, 0, 48, 9,
+  63, 0, 76, 0, 5, 0, 0, 29, 0, 36,
+  17, 0, 0, 1, 82, 0, 0, 10, 14, 80,
+  41, 0, 22, 8, 10, 0, 47, 0, 0, 23,
+  0, 13, 0, 15, 0, 5, 0, 0, 0, 11,
+  0, 0, 0, 0, 0, 11, 0, 0, 0, 51,
+  0, 0, 23, 16, 0, 0, 35, 72, 21, 74,
+  0, 0, 3, 24, 0, 11, 0, 0, 0, 0,
+  0, 21, 29, 0, 30, 0, 0, 0, 0, 0,
+  58, 0, 0, 0, 0, 30, 56, 60, 4, 0,
+  25, 0, 29, 51, 61, 17, 7, 13, 0, 0,
+  0, 14, 29, 0, 67, 43, 0, 16, 0, 0,
+  10, 1, 0, 7, 54, 13, 18, 0, 0, 0,
+  34, 0, 15, 0, 0, 0, 35, 0, 63, 0,
+  64, 0, 8, 0, 0, 64, 0, 40, 20, 0,
+  10, 0, 63, 0, 7, 15, 12, 65, 48, 6,
+  31, 34, 0, 25, 58, 0, 0, 21, 0, 36,
+  3, 4, 0, 0, 0, 0, 0, 32, 0, 0,
+  0, 0, 0, 11, 0, 0, 0, 41, 0, 0,
+  21, 22, 0, 0, 26, 26, 28, 76, 0, 0,
+  10, 4, 0, 25, 19, 0, 0, 0, 0, 11,
+  55, 3, 50, 0, 0, 0, 0, 0, 62, 0,
+  0, 0, 0, 3, 57, 69, 4, 0, 25, 19,
+  41, 29, 30, 12, 0, 34, 0, 1, 0, 24,
+  19, 0, 63, 30, 0, 19, 0, 0, 12, 0,
+  3, 1, 34, 21, 0, 0, 0, 0, 15, 0,
+  0, 0, 0, 0, 0, 13, 75, 0, 41, 0,
+  17, 0, 0, 19, 0, 49, 12, 0, 0, 25,
+  85, 2, 1, 7, 23, 85, 32, 34, 52, 0,
+  5, 0, 23, 0, 0, 0, 0, 25, 0, 34,
+  0, 0, 0, 0, 0, 25, 0, 0, 0, 0,
+  0, 23, 0, 6, 0, 46, 0, 0, 22, 18,
+  0, 0, 24, 75, 20, 83, 0, 0, 0, 46,
+  0, 19, 0, 0, 0, 0, 0, 30, 41, 0,
+  59, 0, 0, 0, 0, 12, 50, 0, 0, 9,
+  0, 32, 59, 63, 9, 0, 17, 31, 16, 61,
+  46, 0, 20, 36, 0, 0, 0, 9, 42, 0,
+  48, 63, 0, 0, 0, 0, 9, 0, 0, 19,
+  28, 6, 15, 0, 0, 0, 28, 0, 22, 0,
+  0, 0, 15, 1, 73, 0, 78, 3, 7, 0,
+  0, 4, 2, 46, 13, 0, 0, 32, 107, 4,
+  2, 0, 4, 83, 44, 32, 46, 4, 0, 0,
+  3, 0, 0, 10, 0, 0, 0, 35, 0, 0,
+  0, 0, 0, 15, 0, 0, 0, 0, 0, 24,
+  0, 0, 0, 32, 0, 0, 49, 17, 0, 0,
+  0, 80, 25, 73, 0, 0, 0, 50, 0, 3,
+  0, 0, 0, 0, 0, 35, 49, 0, 61, 9,
+  0, 0, 3, 17, 57, 9, 0, 0, 0, 10,
+  48, 46, 9, 0, 7, 32, 17, 79, 43, 0,
+  37, 35, 0, 0, 0, 5, 31, 0, 49, 67,
+  11, 1, 0, 0, 15, 0, 0, 19, 8, 3,
+  5, 0, 0, 0, 19, 0, 26, 0, 0, 0,
+  5, 0, 65, 0, 62, 0, 2, 0, 0, 37,
+  0, 44, 22, 0, 8, 20, 82, 0, 25, 11,
+  12, 56, 55, 36, 59, 22, 0, 12, 31, 0,
+  0, 0, 1, 27, 0, 18, 0, 0, 0, 0,
+  0, 37, 0, 0, 0, 0, 0, 14, 0, 0,
+  0, 28, 0, 0, 38, 1, 0, 0, 0, 23,
+  0, 87, 0, 0, 4, 32, 0, 38, 0, 0,
+  0, 0, 0, 27, 62, 7, 79, 0, 0, 0,
+  0, 8, 73, 0, 0, 19, 6, 1, 28, 74,
+  0, 0, 22, 50, 31, 43, 10, 0, 10, 37,
+  0, 20, 0, 33, 31, 10, 59, 36, 0, 0,
+  0, 0, 17, 0, 0, 13, 9, 1, 0, 0,
+  0, 0, 9, 0, 0, 0, 0, 0, 0, 23,
+  74, 0, 31, 0, 36, 0, 0, 0, 0, 70,
+  0, 0, 0, 2, 33, 0, 0, 0, 0, 43,
+  0, 6, 22, 39, 0, 28, 7, 0, 9, 0,
+  0, 0, 28, 31, 0, 0, 0, 0, 0, 29,
+  0, 0, 2, 27, 0, 0, 0, 0, 0, 6,
+  0, 5, 36, 29, 18, 0, 0, 0, 0, 40,
+  0, 15, 23, 36, 0, 10, 8, 17, 0, 4,
+  56, 0, 56, 30, 68, 85, 5, 0, 19, 21,
+  32, 0, 0, 9, 20, 0, 0, 41, 10, 0,
+  11, 39, 17, 55, 0, 0, 0, 81, 0, 0,
+  54, 0, 6, 0, 21, 50, 24, 33, 0, 0,
+  0, 40, 0, 5, 0, 0, 0, 0, 0, 0,
+  7, 0, 7, 0, 0, 0, 0, 0, 0, 0,
+  0, 21, 20, 0, 0, 8, 0, 102, 1, 0,
+  0, 14, 69, 27, 0, 0, 0, 1, 0, 66,
+  27, 37, 0, 17, 6, 0, 0, 0, 2, 0,
+  52, 58, 12, 0, 0, 0, 14, 27, 0, 0,
+  6, 45, 0, 0, 2, 0, 0, 11, 0, 17,
+  56, 34, 0, 0, 0, 0, 2, 38, 0, 25,
+  6, 68, 0, 37, 0, 16, 0, 2, 22, 0,
+  50, 18, 67, 47, 0, 0, 22, 50, 27, 21,
+  0, 3, 14, 0, 29, 40, 11, 0, 0, 47,
+  18, 59, 13, 0, 37, 101, 0, 22, 37, 0,
+  12, 0, 20, 34, 37, 0, 0, 0, 4, 0,
+  0, 14, 0, 6, 0, 13, 0, 0, 10, 0,
+  0, 0, 0, 0, 4, 0, 56, 0, 21, 28,
+  9, 0, 0, 56, 17, 88, 0, 0, 31, 9,
+  81, 2, 5, 0, 0, 6, 2, 91, 38, 27,
+  0, 41, 0, 0, 0, 0, 13, 0, 37, 42,
+  0, 0, 0, 2, 9, 19, 0, 0, 16, 37,
+  0, 0, 16, 0, 0, 26, 0, 16, 70, 3,
+  0, 0, 0, 0, 0, 52, 0, 0, 15, 62,
+  0, 58, 0, 17, 0, 7, 22, 0, 63, 23,
+  93, 25, 0, 0, 31, 35, 54, 3, 0, 8,
+  19, 0, 32, 63, 17, 6, 25, 64, 9, 35,
+  25, 0, 32, 85, 0, 27, 5, 0, 11, 0,
+  41, 54, 31, 0, 0, 0, 12, 3, 0, 31,
+  0, 0, 0, 17, 0, 0, 32, 0, 0, 0,
+  0, 0, 0, 0, 65, 0, 25, 16, 30, 0,
+  0, 29, 0, 36, 17, 0, 0, 1, 82, 0,
+  0, 10, 14, 80, 41, 0, 22, 8, 10, 0,
+  47, 0, 0, 23, 0, 13, 0, 15, 0, 5,
+  0, 0, 0, 11, 0, 0, 0, 0, 0, 11,
+  0, 0, 0, 51, 0, 0, 23, 16, 0, 0,
+  35, 72, 21, 74, 0, 0, 3, 24, 0, 11,
+  0, 0, 0, 0, 0, 21, 29, 0, 30, 0,
+  0, 0, 0, 0, 58, 0, 0, 0, 0, 30,
+  56, 60, 4, 0, 25, 0, 29, 51, 61, 17,
+  7, 13, 0, 0, 0, 14, 29, 0, 67, 43,
+  0, 16, 0, 0, 10, 1, 0, 7, 54, 13,
+  18, 0, 0, 0, 34, 0, 15, 0, 0, 0,
+  35, 0, 63, 0, 64, 0, 8, 0, 0, 64,
+  0, 40, 20, 0, 10, 0, 63, 0, 7, 15,
+  12, 65, 48, 6, 31, 34, 0, 25, 58, 0,
+  0, 21, 0, 36, 3, 4, 0, 0, 0, 0,
+  0, 32, 0, 0, 0, 0, 0, 11, 0, 0,
+  0, 41, 0, 0, 21, 22, 0, 0, 26, 26,
+  28, 76, 0, 0, 10, 4, 0, 25, 19, 0,
+  0, 0, 0, 11, 55, 3, 50, 0, 0, 0,
+  0, 0, 62, 0, 0, 0, 0, 3, 57, 69,
+  4, 0, 25, 19, 41, 29, 30, 12, 0, 34,
+  0, 1, 0, 24, 19, 0, 63, 30, 0, 19,
+  0, 0, 12, 0, 3, 1, 34, 21, 0, 0,
+  0, 0, 15, 0, 0, 0, 0, 0, 0, 13,
+  75, 0, 41, 0, 17, 0, 0, 151, 1, 57,
+  8, 0, 17, 0, 42, 0, 26, 0, 19, 37,
+  38, 18, 29, 7, 6, 53, 10, 0, 0, 24,
+  1, 37, 15, 7, 0, 0, 0, 0, 46, 5,
+  0, 0, 0, 0, 0, 1, 0, 2, 0, 21,
+  0, 0, 21, 42, 0, 0, 40, 0, 12, 89,
+  0, 0, 18, 1, 0, 44, 24, 0, 0, 0,
+  0, 0, 73, 21, 53, 0, 0, 0, 0, 8,
+  68, 12, 0, 35, 0, 18, 49, 62, 21, 11,
+  30, 33, 16, 49, 19, 13, 53, 22, 0, 17,
+  0, 5, 44, 0, 24, 80, 3, 46, 0, 0,
+  12, 0, 22, 12, 52, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 89, 0,
+  51, 0, 16, 1, 0, 4, 2, 46, 13, 0,
+  0, 32, 107, 4, 2, 0, 4, 83, 44, 32,
+  46, 4, 0, 0, 3, 0, 0, 10, 0, 0,
+  0, 35, 0, 0, 0, 0, 0, 15, 0, 0,
+  0, 0, 0, 24, 0, 0, 0, 32, 0, 0,
+  49, 17, 0, 0, 0, 80, 25, 73, 0, 0,
+  0, 50, 0, 3, 0, 0, 0, 0, 0, 35,
+  49, 0, 61, 9, 0, 0, 3, 17, 57, 9,
+  0, 0, 0, 10, 48, 46, 9, 0, 7, 32,
+  17, 79, 43, 0, 37, 35, 0, 0, 0, 5,
+  31, 0, 49, 67, 11, 1, 0, 0, 15, 0,
+  0, 19, 8, 3, 5, 0, 0, 0, 19, 0,
+  26, 0, 0, 0, 5, 0, 65, 0, 62, 0,
+  2, 0, 0, 37, 0, 44, 22, 0, 8, 20,
+  82, 0, 25, 11, 12, 56, 55, 36, 59, 22,
+  0, 12, 31, 0, 0, 0, 1, 27, 0, 18,
+  0, 0, 0, 0, 0, 37, 0, 0, 0, 0,
+  0, 14, 0, 0, 0, 28, 0, 0, 38, 1,
+  0, 0, 0, 23, 0, 87, 0, 0, 4, 32,
+  0, 38, 0, 0, 0, 0, 0, 27, 62, 7,
+  79, 0, 0, 0, 0, 8, 73, 0, 0, 19,
+  6, 1, 28, 74, 0, 0, 22, 50, 31, 43,
+  10, 0, 10, 37, 0, 20, 0, 33, 31, 10,
+  59, 36, 0, 0, 0, 0, 17, 0, 0, 13,
+  9, 1, 0, 0, 0, 0, 9, 0, 0, 0,
+  0, 0, 0, 23, 74, 0, 31, 0, 36, 0,
+  0, 74, 18, 48, 36, 0, 9, 0, 60, 0,
+  36, 0, 0, 63, 66, 33, 53, 1, 1, 40,
+  5, 0, 0, 0, 0, 29, 0, 0, 0, 0,
+  0, 0, 0, 33, 0, 0, 0, 0, 0, 13,
+  0, 0, 0, 7, 0, 0, 40, 19, 0, 0,
+  0, 0, 0, 107, 0, 0, 12, 52, 0, 31,
+  0, 27, 0, 0, 0, 19, 66, 8, 85, 0,
+  0, 0, 0, 0, 65, 0, 0, 12, 15, 13,
+  23, 55, 0, 0, 38, 70, 22, 57, 6, 0,
+  10, 41, 0, 20, 0, 27, 34, 9, 25, 65,
+  0, 0, 0, 0, 11, 0, 0, 0, 15, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 46, 0, 22, 0, 42, 0, 0, 8,
+  0, 102, 1, 0, 0, 14, 69, 27, 0, 0,
+  0, 1, 0, 66, 27, 37, 0, 17, 6, 0,
+  0, 0, 2, 0, 52, 58, 12, 0, 0, 0,
+  14, 27, 0, 0, 6, 45, 0, 0, 2, 0,
+  0, 11, 0, 17, 56, 34, 0, 0, 0, 0,
+  2, 38, 0, 25, 6, 68, 0, 37, 0, 16,
+  0, 2, 22, 0, 50, 18, 67, 47, 0, 0,
+  22, 50, 27, 21, 0, 3, 14, 0, 29, 40,
+  11, 0, 0, 47, 18, 59, 13, 0, 37, 101,
+  0, 22, 37, 0, 12, 0, 20, 34, 37, 0,
+  0, 0, 4, 0, 0, 14, 0, 6, 0, 13,
+  0, 0, 10, 0, 0, 0, 0, 0, 4, 0,
+  56, 0, 21, 28, 9, 0, 0, 56, 17, 88,
+  0, 0, 31, 9, 81, 2, 5, 0, 0, 6,
+  2, 91, 38, 27, 0, 41, 0, 0, 0, 0,
+  13, 0, 37, 42, 0, 0, 0, 2, 9, 19,
+  0, 0, 16, 37, 0, 0, 16, 0, 0, 26,
+  0, 16, 70, 3, 0, 0, 0, 0, 0, 52,
+  0, 0, 15, 62, 0, 58, 0, 17, 0, 7,
+  22, 0, 63, 23, 93, 25, 0, 0, 31, 35,
+  54, 3, 0, 8, 19, 0, 32, 63, 17, 6,
+  25, 64, 9, 35, 25, 0, 32, 85, 0, 27,
+  5, 0, 11, 0, 41, 54, 31, 0, 0, 0,
+  12, 3, 0, 31, 0, 0, 0, 17, 0, 0,
+  32, 0, 0, 0, 0, 0, 0, 0, 65, 0,
+  25, 16, 30, 0, 0, 28, 8, 32, 27, 0,
+  2, 0, 68, 0, 19, 0, 0, 42, 7, 49,
+  43, 15, 20, 47, 0, 0, 0, 0, 0, 0,
+  3, 32, 0, 0, 0, 6, 4, 23, 0, 12,
+  7, 21, 0, 0, 2, 0, 0, 18, 0, 11,
+  54, 50, 0, 0, 0, 0, 0, 40, 0, 0,
+  45, 53, 0, 11, 0, 42, 0, 0, 22, 4,
+  38, 14, 110, 11, 16, 0, 30, 15, 57, 0,
+  0, 0, 2, 0, 0, 18, 21, 0, 59, 45,
+  0, 63, 2, 0, 3, 85, 0, 10, 16, 0,
+  9, 0, 31, 80, 7, 29, 0, 0, 22, 22,
+  0, 19, 0, 0, 0, 25, 0, 0, 16, 0,
+  0, 0, 0, 0, 0, 0, 11, 0, 0, 5,
+  46, 8, 0, 64, 0, 40, 20, 0, 10, 0,
+  63, 0, 7, 15, 12, 65, 48, 6, 31, 34,
+  0, 25, 58, 0, 0, 21, 0, 36, 3, 4,
+  0, 0, 0, 0, 0, 32, 0, 0, 0, 0,
+  0, 11, 0, 0, 0, 41, 0, 0, 21, 22,
+  0, 0, 26, 26, 28, 76, 0, 0, 10, 4,
+  0, 25, 19, 0, 0, 0, 0, 11, 55, 3,
+  50, 0, 0, 0, 0, 0, 62, 0, 0, 0,
+  0, 3, 57, 69, 4, 0, 25, 19, 41, 29,
+  30, 12, 0, 34, 0, 1, 0, 24, 19, 0,
+  63, 30, 0, 19, 0, 0, 12, 0, 3, 1,
+  34, 21, 0, 0, 0, 0, 15, 0, 0, 0,
+  0, 0, 0, 13, 75, 0, 41, 0, 17, 0,
+  0, 151, 1, 57, 8, 0, 17, 0, 42, 0,
+  26, 0, 19, 37, 38, 18, 29, 7, 6, 53,
+  10, 0, 0, 24, 1, 37, 15, 7, 0, 0,
+  0, 0, 46, 5, 0, 0, 0, 0, 0, 1,
+  0, 2, 0, 21, 0, 0, 21, 42, 0, 0,
+  40, 0, 12, 89, 0, 0, 18, 1, 0, 44,
+  24, 0, 0, 0, 0, 0, 73, 21, 53, 0,
+  0, 0, 0, 8, 68, 12, 0, 35, 0, 18,
+  49, 62, 21, 11, 30, 33, 16, 49, 19, 13,
+  53, 22, 0, 17, 0, 5, 44, 0, 24, 80,
+  3, 46, 0, 0, 12, 0, 22, 12, 52, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 89, 0, 51, 0, 16, 1, 6, 145,
+  0, 66, 0, 25, 0, 0, 52, 0, 6, 0,
+  69, 0, 0, 0, 0, 5, 33, 32, 0, 0,
+  14, 32, 3, 0, 70, 0, 0, 0, 0, 0,
+  77, 0, 13, 38, 0, 0, 0, 0, 0, 17,
+  0, 19, 0, 15, 48, 19, 0, 17, 5, 25,
+  0, 35, 17, 0, 54, 0, 0, 16, 0, 0,
+  0, 0, 16, 0, 16, 19, 0, 1, 65, 17,
+  3, 0, 34, 29, 0, 94, 0, 16, 0, 0,
+  90, 39, 0, 18, 0, 41, 51, 18, 99, 0,
+  0, 0, 0, 0, 61, 0, 18, 99, 42, 59,
+  0, 0, 0, 10, 57, 44, 87, 0, 0, 0,
+  0, 36, 0, 0, 0, 0, 5, 0, 3, 0,
+  48, 0, 39, 0, 0, 46, 0, 37, 0, 44,
+  22, 0, 8, 20, 82, 0, 25, 11, 12, 56,
+  55, 36, 59, 22, 0, 12, 31, 0, 0, 0,
+  1, 27, 0, 18, 0, 0, 0, 0, 0, 37,
+  0, 0, 0, 0, 0, 14, 0, 0, 0, 28,
+  0, 0, 38, 1, 0, 0, 0, 23, 0, 87,
+  0, 0, 4, 32, 0, 38, 0, 0, 0, 0,
+  0, 27, 62, 7, 79, 0, 0, 0, 0, 8,
+  73, 0, 0, 19, 6, 1, 28, 74, 0, 0,
+  22, 50, 31, 43, 10, 0, 10, 37, 0, 20,
+  0, 33, 31, 10, 59, 36, 0, 0, 0, 0,
+  17, 0, 0, 13, 9, 1, 0, 0, 0, 0,
+  9, 0, 0, 0, 0, 0, 0, 23, 74, 0,
+  31, 0, 36, 0, 0, 74, 18, 48, 36, 0,
+  9, 0, 60, 0, 36, 0, 0, 63, 66, 33,
+  53, 1, 1, 40, 5, 0, 0, 0, 0, 29,
+  0, 0, 0, 0, 0, 0, 0, 33, 0, 0,
+  0, 0, 0, 13, 0, 0, 0, 7, 0, 0,
+  40, 19, 0, 0, 0, 0, 0, 107, 0, 0,
+  12, 52, 0, 31, 0, 27, 0, 0, 0, 19,
+  66, 8, 85, 0, 0, 0, 0, 0, 65, 0,
+  0, 12, 15, 13, 23, 55, 0, 0, 38, 70,
+  22, 57, 6, 0, 10, 41, 0, 20, 0, 27,
+  34, 9, 25, 65, 0, 0, 0, 0, 11, 0,
+  0, 0, 15, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 46, 0, 22, 0,
+  42, 0, 0, 120, 19, 74, 27, 0, 31, 0,
+  61, 0, 8, 0, 21, 27, 26, 43, 32, 22,
+  11, 48, 0, 0, 11, 13, 20, 2, 39, 1,
+  0, 0, 0, 0, 45, 5, 15, 2, 0, 0,
+  0, 0, 0, 0, 0, 21, 0, 27, 87, 36,
+  0, 0, 16, 0, 0, 39, 0, 0, 30, 0,
+  0, 50, 0, 22, 0, 0, 0, 0, 32, 15,
+  38, 0, 0, 0, 27, 0, 82, 16, 0, 44,
+  0, 0, 23, 10, 32, 10, 15, 51, 24, 38,
+  8, 39, 22, 24, 0, 47, 0, 0, 15, 0,
+  42, 41, 18, 5, 0, 0, 5, 0, 39, 13,
+  35, 22, 0, 0, 0, 45, 0, 0, 0, 0,
+  9, 0, 0, 0, 49, 0, 6, 0, 21, 9,
+  0, 56, 17, 88, 0, 0, 31, 9, 81, 2,
+  5, 0, 0, 6, 2, 91, 38, 27, 0, 41,
+  0, 0, 0, 0, 13, 0, 37, 42, 0, 0,
+  0, 2, 9, 19, 0, 0, 16, 37, 0, 0,
+  16, 0, 0, 26, 0, 16, 70, 3, 0, 0,
+  0, 0, 0, 52, 0, 0, 15, 62, 0, 58,
+  0, 17, 0, 7, 22, 0, 63, 23, 93, 25,
+  0, 0, 31, 35, 54, 3, 0, 8, 19, 0,
+  32, 63, 17, 6, 25, 64, 9, 35, 25, 0,
+  32, 85, 0, 27, 5, 0, 11, 0, 41, 54,
+  31, 0, 0, 0, 12, 3, 0, 31, 0, 0,
+  0, 17, 0, 0, 32, 0, 0, 0, 0, 0,
+  0, 0, 65, 0, 25, 16, 30, 0, 0, 28,
+  8, 32, 27, 0, 2, 0, 68, 0, 19, 0,
+  0, 42, 7, 49, 43, 15, 20, 47, 0, 0,
+  0, 0, 0, 0, 3, 32, 0, 0, 0, 6,
+  4, 23, 0, 12, 7, 21, 0, 0, 2, 0,
+  0, 18, 0, 11, 54, 50, 0, 0, 0, 0,
+  0, 40, 0, 0, 45, 53, 0, 11, 0, 42,
+  0, 0, 22, 4, 38, 14, 110, 11, 16, 0,
+  30, 15, 57, 0, 0, 0, 2, 0, 0, 18,
+  21, 0, 59, 45, 0, 63, 2, 0, 3, 85,
+  0, 10, 16, 0, 9, 0, 31, 80, 7, 29,
+  0, 0, 22, 22, 0, 19, 0, 0, 0, 25,
+  0, 0, 16, 0, 0, 0, 0, 0, 0, 0,
+  11, 0, 0, 5, 46, 8, 7, 49, 61, 23,
+  56, 0, 23, 0, 71, 0, 0, 0, 14, 98,
+  16, 58, 20, 15, 28, 30, 7, 0, 10, 8,
+  0, 0, 0, 49, 0, 0, 0, 0, 0, 27,
+  0, 0, 0, 0, 0, 0, 17, 10, 0, 57,
+  0, 0, 54, 50, 0, 0, 31, 38, 0, 36,
+  0, 0, 23, 53, 0, 29, 0, 9, 0, 0,
+  24, 18, 14, 0, 53, 0, 0, 0, 18, 6,
+  59, 0, 0, 0, 0, 0, 21, 44, 0, 0,
+  68, 38, 3, 47, 64, 0, 0, 40, 0, 20,
+  0, 9, 7, 0, 28, 55, 0, 0, 1, 0,
+  35, 0, 0, 37, 14, 0, 22, 0, 0, 15,
+  86, 0, 0, 0, 20, 0, 12, 0, 13, 0,
+  9, 8, 46, 0, 0, 151, 1, 57, 8, 0,
+  17, 0, 42, 0, 26, 0, 19, 37, 38, 18,
+  29, 7, 6, 53, 10, 0, 0, 24, 1, 37,
+  15, 7, 0, 0, 0, 0, 46, 5, 0, 0,
+  0, 0, 0, 1, 0, 2, 0, 21, 0, 0,
+  21, 42, 0, 0, 40, 0, 12, 89, 0, 0,
+  18, 1, 0, 44, 24, 0, 0, 0, 0, 0,
+  73, 21, 53, 0, 0, 0, 0, 8, 68, 12,
+  0, 35, 0, 18, 49, 62, 21, 11, 30, 33,
+  16, 49, 19, 13, 53, 22, 0, 17, 0, 5,
+  44, 0, 24, 80, 3, 46, 0, 0, 12, 0,
+  22, 12, 52, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 89, 0, 51, 0,
+  16, 1, 6, 145, 0, 66, 0, 25, 0, 0,
+  52, 0, 6, 0, 69, 0, 0, 0, 0, 5,
+  33, 32, 0, 0, 14, 32, 3, 0, 70, 0,
+  0, 0, 0, 0, 77, 0, 13, 38, 0, 0,
+  0, 0, 0, 17, 0, 19, 0, 15, 48, 19,
+  0, 17, 5, 25, 0, 35, 17, 0, 54, 0,
+  0, 16, 0, 0, 0, 0, 16, 0, 16, 19,
+  0, 1, 65, 17, 3, 0, 34, 29, 0, 94,
+  0, 16, 0, 0, 90, 39, 0, 18, 0, 41,
+  51, 18, 99, 0, 0, 0, 0, 0, 61, 0,
+  18, 99, 42, 59, 0, 0, 0, 10, 57, 44,
+  87, 0, 0, 0, 0, 36, 0, 0, 0, 0,
+  5, 0, 3, 0, 48, 0, 39, 0, 0, 46,
+  58, 21, 0, 68, 2, 105, 0, 4, 38, 0,
+  0, 0, 40, 0, 0, 0, 2, 21, 35, 0,
+  0, 90, 13, 0, 0, 0, 31, 0, 9, 0,
+  0, 31, 3, 0, 67, 72, 9, 0, 27, 0,
+  20, 14, 0, 28, 22, 53, 41, 0, 0, 0,
+  0, 61, 0, 0, 135, 38, 37, 0, 7, 0,
+  0, 47, 34, 0, 96, 0, 0, 31, 0, 47,
+  198, 6, 55, 0, 0, 0, 0, 35, 0, 0,
+  0, 0, 77, 27, 31, 0, 1, 1, 38, 0,
+  0, 15, 0, 0, 17, 0, 39, 0, 26, 71,
+  33, 77, 0, 0, 0, 0, 6, 46, 5, 0,
+  19, 40, 0, 88, 0, 0, 0, 0, 55, 0,
+  0, 0, 0, 0, 28, 0, 0, 16, 0, 74,
+  18, 48, 36, 0, 9, 0, 60, 0, 36, 0,
+  0, 63, 66, 33, 53, 1, 1, 40, 5, 0,
+  0, 0, 0, 29, 0, 0, 0, 0, 0, 0,
+  0, 33, 0, 0, 0, 0, 0, 13, 0, 0,
+  0, 7, 0, 0, 40, 19, 0, 0, 0, 0,
+  0, 107, 0, 0, 12, 52, 0, 31, 0, 27,
+  0, 0, 0, 19, 66, 8, 85, 0, 0, 0,
+  0, 0, 65, 0, 0, 12, 15, 13, 23, 55,
+  0, 0, 38, 70, 22, 57, 6, 0, 10, 41,
+  0, 20, 0, 27, 34, 9, 25, 65, 0, 0,
+  0, 0, 11, 0, 0, 0, 15, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  46, 0, 22, 0, 42, 0, 0, 120, 19, 74,
+  27, 0, 31, 0, 61, 0, 8, 0, 21, 27,
+  26, 43, 32, 22, 11, 48, 0, 0, 11, 13,
+  20, 2, 39, 1, 0, 0, 0, 0, 45, 5,
+  15, 2, 0, 0, 0, 0, 0, 0, 0, 21,
+  0, 27, 87, 36, 0, 0, 16, 0, 0, 39,
+  0, 0, 30, 0, 0, 50, 0, 22, 0, 0,
+  0, 0, 32, 15, 38, 0, 0, 0, 27, 0,
+  82, 16, 0, 44, 0, 0, 23, 10, 32, 10,
+  15, 51, 24, 38, 8, 39, 22, 24, 0, 47,
+  0, 0, 15, 0, 42, 41, 18, 5, 0, 0,
+  5, 0, 39, 13, 35, 22, 0, 0, 0, 45,
+  0, 0, 0, 0, 9, 0, 0, 0, 49, 0,
+  6, 0, 21, 9, 64, 56, 7, 47, 47, 23,
+  0, 2, 27, 0, 0, 0, 42, 8, 0, 3,
+  0, 0, 56, 18, 0, 16, 26, 0, 2, 0,
+  57, 0, 1, 54, 0, 27, 23, 0, 74, 44,
+  54, 0, 12, 0, 0, 9, 0, 16, 14, 30,
+  64, 22, 0, 0, 0, 0, 0, 18, 39, 0,
+  31, 0, 0, 0, 0, 41, 29, 0, 11, 5,
+  0, 39, 0, 10, 75, 0, 74, 0, 24, 4,
+  0, 36, 30, 0, 0, 0, 49, 39, 40, 0,
+  0, 51, 36, 6, 0, 6, 0, 16, 0, 0,
+  38, 0, 41, 42, 30, 45, 15, 0, 0, 0,
+  5, 61, 41, 0, 5, 11, 0, 65, 38, 0,
+  0, 0, 29, 0, 0, 0, 0, 0, 0, 0,
+  8, 29, 0, 28, 8, 32, 27, 0, 2, 0,
+  68, 0, 19, 0, 0, 42, 7, 49, 43, 15,
+  20, 47, 0, 0, 0, 0, 0, 0, 3, 32,
+  0, 0, 0, 6, 4, 23, 0, 12, 7, 21,
+  0, 0, 2, 0, 0, 18, 0, 11, 54, 50,
+  0, 0, 0, 0, 0, 40, 0, 0, 45, 53,
+  0, 11, 0, 42, 0, 0, 22, 4, 38, 14,
+  110, 11, 16, 0, 30, 15, 57, 0, 0, 0,
+  2, 0, 0, 18, 21, 0, 59, 45, 0, 63,
+  2, 0, 3, 85, 0, 10, 16, 0, 9, 0,
+  31, 80, 7, 29, 0, 0, 22, 22, 0, 19,
+  0, 0, 0, 25, 0, 0, 16, 0, 0, 0,
+  0, 0, 0, 0, 11, 0, 0, 5, 46, 8,
+  7, 49, 61, 23, 56, 0, 23, 0, 71, 0,
+  0, 0, 14, 98, 16, 58, 20, 15, 28, 30,
+  7, 0, 10, 8, 0, 0, 0, 49, 0, 0,
+  0, 0, 0, 27, 0, 0, 0, 0, 0, 0,
+  17, 10, 0, 57, 0, 0, 54, 50, 0, 0,
+  31, 38, 0, 36, 0, 0, 23, 53, 0, 29,
+  0, 9, 0, 0, 24, 18, 14, 0, 53, 0,
+  0, 0, 18, 6, 59, 0, 0, 0, 0, 0,
+  21, 44, 0, 0, 68, 38, 3, 47, 64, 0,
+  0, 40, 0, 20, 0, 9, 7, 0, 28, 55,
+  0, 0, 1, 0, 35, 0, 0, 37, 14, 0,
+  22, 0, 0, 15, 86, 0, 0, 0, 20, 0,
+  12, 0, 13, 0, 9, 8, 46, 0, 51, 65,
+  87, 26, 42, 0, 0, 0, 24, 1, 1, 1,
+  40, 128, 0, 10, 0, 0, 20, 34, 11, 2,
+  7, 22, 0, 0, 0, 18, 0, 18, 19, 8,
+  0, 36, 8, 0, 36, 0, 0, 0, 19, 59,
+  0, 24, 0, 0, 22, 33, 0, 0, 46, 60,
+  0, 37, 0, 0, 0, 36, 0, 23, 0, 0,
+  20, 0, 14, 43, 0, 0, 6, 10, 0, 33,
+  9, 0, 41, 0, 0, 0, 32, 7, 0, 63,
+  13, 0, 60, 24, 16, 45, 93, 12, 0, 0,
+  0, 1, 0, 0, 27, 0, 35, 36, 0, 2,
+  17, 0, 23, 17, 0, 42, 39, 0, 25, 0,
+  0, 19, 110, 2, 0, 0, 0, 0, 14, 0,
+  0, 0, 0, 15, 6, 19, 6, 145, 0, 66,
+  0, 25, 0, 0, 52, 0, 6, 0, 69, 0,
+  0, 0, 0, 5, 33, 32, 0, 0, 14, 32,
+  3, 0, 70, 0, 0, 0, 0, 0, 77, 0,
+  13, 38, 0, 0, 0, 0, 0, 17, 0, 19,
+  0, 15, 48, 19, 0, 17, 5, 25, 0, 35,
+  17, 0, 54, 0, 0, 16, 0, 0, 0, 0,
+  16, 0, 16, 19, 0, 1, 65, 17, 3, 0,
+  34, 29, 0, 94, 0, 16, 0, 0, 90, 39,
+  0, 18, 0, 41, 51, 18, 99, 0, 0, 0,
+  0, 0, 61, 0, 18, 99, 42, 59, 0, 0,
+  0, 10, 57, 44, 87, 0, 0, 0, 0, 36,
+  0, 0, 0, 0, 5, 0, 3, 0, 48, 0,
+  39, 0, 0, 46, 58, 21, 0, 68, 2, 105,
+  0, 4, 38, 0, 0, 0, 40, 0, 0, 0,
+  2, 21, 35, 0, 0, 90, 13, 0, 0, 0,
+  31, 0, 9, 0, 0, 31, 3, 0, 67, 72,
+  9, 0, 27, 0, 20, 14, 0, 28, 22, 53,
+  41, 0, 0, 0, 0, 61, 0, 0, 135, 38,
+  37, 0, 7, 0, 0, 47, 34, 0, 96, 0,
+  0, 31, 0, 47, 198, 6, 55, 0, 0, 0,
+  0, 35, 0, 0, 0, 0, 77, 27, 31, 0,
+  1, 1, 38, 0, 0, 15, 0, 0, 17, 0,
+  39, 0, 26, 71, 33, 77, 0, 0, 0, 0,
+  6, 46, 5, 0, 19, 40, 0, 88, 0, 0,
+  0, 0, 55, 0, 0, 0, 0, 0, 28, 0,
+  0, 16, 0, 0, 0, 15, 0, 83, 0, 21,
+  90, 39, 0, 48, 26, 0, 0, 60, 13, 28,
+  16, 0, 25, 81, 1, 0, 0, 0, 1, 44,
+  17, 19, 0, 35, 60, 0, 78, 36, 79, 138,
+  7, 0, 76, 0, 2, 0, 0, 129, 0, 4,
+  0, 11, 0, 4, 0, 0, 138, 0, 2, 0,
+  27, 0, 0, 90, 14, 2, 90, 0, 0, 39,
+  0, 61, 111, 0, 118, 35, 0, 31, 35, 22,
+  25, 0, 0, 0, 0, 27, 0, 0, 12, 25,
+  0, 0, 0, 91, 0, 7, 15, 0, 6, 0,
+  0, 89, 131, 18, 0, 0, 39, 0, 0, 48,
+  0, 0, 1, 67, 0, 57, 0, 0, 0, 0,
+  75, 0, 0, 0, 0, 0, 0, 0, 75, 51,
+  0, 120, 19, 74, 27, 0, 31, 0, 61, 0,
+  8, 0, 21, 27, 26, 43, 32, 22, 11, 48,
+  0, 0, 11, 13, 20, 2, 39, 1, 0, 0,
+  0, 0, 45, 5, 15, 2, 0, 0, 0, 0,
+  0, 0, 0, 21, 0, 27, 87, 36, 0, 0,
+  16, 0, 0, 39, 0, 0, 30, 0, 0, 50,
+  0, 22, 0, 0, 0, 0, 32, 15, 38, 0,
+  0, 0, 27, 0, 82, 16, 0, 44, 0, 0,
+  23, 10, 32, 10, 15, 51, 24, 38, 8, 39,
+  22, 24, 0, 47, 0, 0, 15, 0, 42, 41,
+  18, 5, 0, 0, 5, 0, 39, 13, 35, 22,
+  0, 0, 0, 45, 0, 0, 0, 0, 9, 0,
+  0, 0, 49, 0, 6, 0, 21, 9, 64, 56,
+  7, 47, 47, 23, 0, 2, 27, 0, 0, 0,
+  42, 8, 0, 3, 0, 0, 56, 18, 0, 16,
+  26, 0, 2, 0, 57, 0, 1, 54, 0, 27,
+  23, 0, 74, 44, 54, 0, 12, 0, 0, 9,
+  0, 16, 14, 30, 64, 22, 0, 0, 0, 0,
+  0, 18, 39, 0, 31, 0, 0, 0, 0, 41,
+  29, 0, 11, 5, 0, 39, 0, 10, 75, 0,
+  74, 0, 24, 4, 0, 36, 30, 0, 0, 0,
+  49, 39, 40, 0, 0, 51, 36, 6, 0, 6,
+  0, 16, 0, 0, 38, 0, 41, 42, 30, 45,
+  15, 0, 0, 0, 5, 61, 41, 0, 5, 11,
+  0, 65, 38, 0, 0, 0, 29, 0, 0, 0,
+  0, 0, 0, 0, 8, 29, 59, 0, 21, 13,
+  0, 41, 0, 2, 0, 43, 0, 19, 0, 48,
+  0, 0, 0, 0, 56, 0, 3, 89, 5, 0,
+  0, 0, 21, 5, 0, 99, 0, 11, 0, 0,
+  67, 44, 117, 91, 15, 0, 39, 0, 3, 0,
+  0, 12, 0, 18, 5, 1, 0, 35, 0, 23,
+  119, 0, 0, 4, 0, 0, 0, 65, 91, 49,
+  82, 33, 0, 21, 0, 118, 80, 20, 83, 0,
+  0, 0, 0, 0, 100, 0, 0, 0, 15, 22,
+  26, 0, 0, 49, 63, 0, 0, 18, 0, 0,
+  55, 0, 41, 0, 0, 54, 58, 26, 28, 0,
+  0, 0, 0, 29, 0, 0, 19, 18, 0, 23,
+  56, 7, 0, 0, 19, 0, 0, 0, 0, 0,
+  0, 24, 61, 73, 7, 49, 61, 23, 56, 0,
+  23, 0, 71, 0, 0, 0, 14, 98, 16, 58,
+  20, 15, 28, 30, 7, 0, 10, 8, 0, 0,
+  0, 49, 0, 0, 0, 0, 0, 27, 0, 0,
+  0, 0, 0, 0, 17, 10, 0, 57, 0, 0,
+  54, 50, 0, 0, 31, 38, 0, 36, 0, 0,
+  23, 53, 0, 29, 0, 9, 0, 0, 24, 18,
+  14, 0, 53, 0, 0, 0, 18, 6, 59, 0,
+  0, 0, 0, 0, 21, 44, 0, 0, 68, 38,
+  3, 47, 64, 0, 0, 40, 0, 20, 0, 9,
+  7, 0, 28, 55, 0, 0, 1, 0, 35, 0,
+  0, 37, 14, 0, 22, 0, 0, 15, 86, 0,
+  0, 0, 20, 0, 12, 0, 13, 0, 9, 8,
+  46, 0, 51, 65, 87, 26, 42, 0, 0, 0,
+  24, 1, 1, 1, 40, 128, 0, 10, 0, 0,
+  20, 34, 11, 2, 7, 22, 0, 0, 0, 18,
+  0, 18, 19, 8, 0, 36, 8, 0, 36, 0,
+  0, 0, 19, 59, 0, 24, 0, 0, 22, 33,
+  0, 0, 46, 60, 0, 37, 0, 0, 0, 36,
+  0, 23, 0, 0, 20, 0, 14, 43, 0, 0,
+  6, 10, 0, 33, 9, 0, 41, 0, 0, 0,
+  32, 7, 0, 63, 13, 0, 60, 24, 16, 45,
+  93, 12, 0, 0, 0, 1, 0, 0, 27, 0,
+  35, 36, 0, 2, 17, 0, 23, 17, 0, 42,
+  39, 0, 25, 0, 0, 19, 110, 2, 0, 0,
+  0, 0, 14, 0, 0, 0, 0, 15, 6, 19,
+  58, 29, 70, 32, 22, 7, 0, 0, 38, 0,
+  7, 32, 60, 93, 0, 0, 0, 0, 38, 0,
+  64, 26, 0, 33, 0, 0, 30, 14, 0, 67,
+  47, 0, 0, 0, 6, 0, 43, 9, 0, 0,
+  0, 21, 0, 0, 0, 0, 0, 24, 0, 6,
+  13, 86, 0, 24, 27, 0, 0, 48, 0, 0,
+  0, 0, 12, 26, 3, 21, 0, 0, 0, 30,
+  0, 44, 10, 2, 0, 0, 0, 0, 48, 0,
+  0, 39, 61, 0, 1, 12, 0, 35, 123, 0,
+  0, 0, 0, 0, 0, 0, 63, 0, 17, 39,
+  26, 0, 0, 0, 0, 26, 0, 33, 42, 10,
+  39, 0, 4, 0, 83, 0, 0, 0, 0, 28,
+  67, 0, 0, 0, 0, 33, 0, 82, 58, 21,
+  0, 68, 2, 105, 0, 4, 38, 0, 0, 0,
+  40, 0, 0, 0, 2, 21, 35, 0, 0, 90,
+  13, 0, 0, 0, 31, 0, 9, 0, 0, 31,
+  3, 0, 67, 72, 9, 0, 27, 0, 20, 14,
+  0, 28, 22, 53, 41, 0, 0, 0, 0, 61,
+  0, 0, 135, 38, 37, 0, 7, 0, 0, 47,
+  34, 0, 96, 0, 0, 31, 0, 47, 198, 6,
+  55, 0, 0, 0, 0, 35, 0, 0, 0, 0,
+  77, 27, 31, 0, 1, 1, 38, 0, 0, 15,
+  0, 0, 17, 0, 39, 0, 26, 71, 33, 77,
+  0, 0, 0, 0, 6, 46, 5, 0, 19, 40,
+  0, 88, 0, 0, 0, 0, 55, 0, 0, 0,
+  0, 0, 28, 0, 0, 16, 0, 0, 0, 15,
+  0, 83, 0, 21, 90, 39, 0, 48, 26, 0,
+  0, 60, 13, 28, 16, 0, 25, 81, 1, 0,
+  0, 0, 1, 44, 17, 19, 0, 35, 60, 0,
+  78, 36, 79, 138, 7, 0, 76, 0, 2, 0,
+  0, 129, 0, 4, 0, 11, 0, 4, 0, 0,
+  138, 0, 2, 0, 27, 0, 0, 90, 14, 2,
+  90, 0, 0, 39, 0, 61, 111, 0, 118, 35,
+  0, 31, 35, 22, 25, 0, 0, 0, 0, 27,
+  0, 0, 12, 25, 0, 0, 0, 91, 0, 7,
+  15, 0, 6, 0, 0, 89, 131, 18, 0, 0,
+  39, 0, 0, 48, 0, 0, 1, 67, 0, 57,
+  0, 0, 0, 0, 75, 0, 0, 0, 0, 0,
+  0, 0, 75, 51, 0, 0, 95, 9, 0, 0,
+  0, 24, 67, 28, 0, 54, 35, 44, 0, 52,
+  0, 15, 0, 0, 0, 58, 28, 9, 0, 0,
+  21, 48, 6, 84, 0, 37, 76, 0, 22, 0,
+  105, 123, 0, 0, 100, 0, 38, 0, 0, 109,
+  0, 0, 0, 11, 0, 0, 0, 0, 96, 0,
+  19, 0, 47, 0, 0, 83, 53, 15, 66, 0,
+  7, 34, 0, 90, 0, 0, 122, 30, 0, 21,
+  7, 0, 14, 0, 0, 2, 0, 89, 0, 17,
+  21, 0, 35, 0, 0, 36, 0, 3, 0, 0,
+  0, 0, 0, 59, 137, 0, 0, 0, 0, 0,
+  0, 52, 0, 3, 30, 17, 0, 0, 80, 0,
+  22, 0, 52, 0, 0, 0, 0, 0, 0, 14,
+  61, 73, 64, 56, 7, 47, 47, 23, 0, 2,
+  27, 0, 0, 0, 42, 8, 0, 3, 0, 0,
+  56, 18, 0, 16, 26, 0, 2, 0, 57, 0,
+  1, 54, 0, 27, 23, 0, 74, 44, 54, 0,
+  12, 0, 0, 9, 0, 16, 14, 30, 64, 22,
+  0, 0, 0, 0, 0, 18, 39, 0, 31, 0,
+  0, 0, 0, 41, 29, 0, 11, 5, 0, 39,
+  0, 10, 75, 0, 74, 0, 24, 4, 0, 36,
+  30, 0, 0, 0, 49, 39, 40, 0, 0, 51,
+  36, 6, 0, 6, 0, 16, 0, 0, 38, 0,
+  41, 42, 30, 45, 15, 0, 0, 0, 5, 61,
+  41, 0, 5, 11, 0, 65, 38, 0, 0, 0,
+  29, 0, 0, 0, 0, 0, 0, 0, 8, 29,
+  59, 0, 21, 13, 0, 41, 0, 2, 0, 43,
+  0, 19, 0, 48, 0, 0, 0, 0, 56, 0,
+  3, 89, 5, 0, 0, 0, 21, 5, 0, 99,
+  0, 11, 0, 0, 67, 44, 117, 91, 15, 0,
+  39, 0, 3, 0, 0, 12, 0, 18, 5, 1,
+  0, 35, 0, 23, 119, 0, 0, 4, 0, 0,
+  0, 65, 91, 49, 82, 33, 0, 21, 0, 118,
+  80, 20, 83, 0, 0, 0, 0, 0, 100, 0,
+  0, 0, 15, 22, 26, 0, 0, 49, 63, 0,
+  0, 18, 0, 0, 55, 0, 41, 0, 0, 54,
+  58, 26, 28, 0, 0, 0, 0, 29, 0, 0,
+  19, 18, 0, 23, 56, 7, 0, 0, 19, 0,
+  0, 0, 0, 0, 0, 24, 61, 73, 32, 0,
+  66, 36, 9, 0, 0, 0, 5, 21, 0, 26,
+  30, 124, 0, 0, 0, 0, 23, 0, 28, 52,
+  0, 3, 0, 0, 50, 28, 0, 103, 0, 4,
+  0, 0, 39, 0, 82, 66, 0, 0, 35, 0,
+  2, 0, 0, 22, 7, 0, 0, 0, 0, 70,
+  0, 21, 74, 0, 0, 14, 10, 0, 0, 32,
+  91, 24, 64, 1, 0, 2, 0, 95, 0, 13,
+  72, 0, 0, 0, 0, 0, 86, 0, 0, 56,
+  11, 19, 0, 0, 12, 13, 141, 0, 0, 19,
+  0, 0, 4, 0, 38, 0, 0, 38, 31, 0,
+  0, 0, 0, 0, 0, 56, 51, 0, 69, 0,
+  0, 0, 107, 0, 36, 0, 0, 32, 38, 0,
+  0, 0, 0, 37, 0, 81, 51, 65, 87, 26,
+  42, 0, 0, 0, 24, 1, 1, 1, 40, 128,
+  0, 10, 0, 0, 20, 34, 11, 2, 7, 22,
+  0, 0, 0, 18, 0, 18, 19, 8, 0, 36,
+  8, 0, 36, 0, 0, 0, 19, 59, 0, 24,
+  0, 0, 22, 33, 0, 0, 46, 60, 0, 37,
+  0, 0, 0, 36, 0, 23, 0, 0, 20, 0,
+  14, 43, 0, 0, 6, 10, 0, 33, 9, 0,
+  41, 0, 0, 0, 32, 7, 0, 63, 13, 0,
+  60, 24, 16, 45, 93, 12, 0, 0, 0, 1,
+  0, 0, 27, 0, 35, 36, 0, 2, 17, 0,
+  23, 17, 0, 42, 39, 0, 25, 0, 0, 19,
+  110, 2, 0, 0, 0, 0, 14, 0, 0, 0,
+  0, 15, 6, 19, 58, 29, 70, 32, 22, 7,
+  0, 0, 38, 0, 7, 32, 60, 93, 0, 0,
+  0, 0, 38, 0, 64, 26, 0, 33, 0, 0,
+  30, 14, 0, 67, 47, 0, 0, 0, 6, 0,
+  43, 9, 0, 0, 0, 21, 0, 0, 0, 0,
+  0, 24, 0, 6, 13, 86, 0, 24, 27, 0,
+  0, 48, 0, 0, 0, 0, 12, 26, 3, 21,
+  0, 0, 0, 30, 0, 44, 10, 2, 0, 0,
+  0, 0, 48, 0, 0, 39, 61, 0, 1, 12,
+  0, 35, 123, 0, 0, 0, 0, 0, 0, 0,
+  63, 0, 17, 39, 26, 0, 0, 0, 0, 26,
+  0, 33, 42, 10, 39, 0, 4, 0, 83, 0,
+  0, 0, 0, 28, 67, 0, 0, 0, 0, 33,
+  0, 82, 37, 48, 54, 46, 22, 17, 0, 0,
+  75, 0, 31, 10, 55, 60, 0, 21, 0, 0,
+  43, 0, 38, 0, 0, 48, 0, 0, 41, 28,
+  0, 38, 57, 0, 0, 0, 24, 0, 32, 0,
+  0, 0, 0, 80, 0, 0, 0, 0, 14, 21,
+  0, 28, 36, 67, 0, 12, 53, 0, 1, 49,
+  0, 34, 0, 0, 0, 41, 0, 12, 9, 0,
+  0, 0, 0, 43, 25, 31, 0, 22, 14, 0,
+  16, 22, 0, 32, 73, 0, 0, 30, 3, 13,
+  122, 5, 40, 0, 0, 1, 0, 0, 93, 0,
+  14, 55, 0, 0, 0, 0, 0, 54, 0, 32,
+  56, 22, 48, 0, 15, 0, 63, 0, 0, 0,
+  0, 46, 59, 0, 14, 0, 6, 28, 0, 93,
+  0, 0, 0, 15, 0, 83, 0, 21, 90, 39,
+  0, 48, 26, 0, 0, 60, 13, 28, 16, 0,
+  25, 81, 1, 0, 0, 0, 1, 44, 17, 19,
+  0, 35, 60, 0, 78, 36, 79, 138, 7, 0,
+  76, 0, 2, 0, 0, 129, 0, 4, 0, 11,
+  0, 4, 0, 0, 138, 0, 2, 0, 27, 0,
+  0, 90, 14, 2, 90, 0, 0, 39, 0, 61,
+  111, 0, 118, 35, 0, 31, 35, 22, 25, 0,
+  0, 0, 0, 27, 0, 0, 12, 25, 0, 0,
+  0, 91, 0, 7, 15, 0, 6, 0, 0, 89,
+  131, 18, 0, 0, 39, 0, 0, 48, 0, 0,
+  1, 67, 0, 57, 0, 0, 0, 0, 75, 0,
+  0, 0, 0, 0, 0, 0, 75, 51, 0, 0,
+  95, 9, 0, 0, 0, 24, 67, 28, 0, 54,
+  35, 44, 0, 52, 0, 15, 0, 0, 0, 58,
+  28, 9, 0, 0, 21, 48, 6, 84, 0, 37,
+  76, 0, 22, 0, 105, 123, 0, 0, 100, 0,
+  38, 0, 0, 109, 0, 0, 0, 11, 0, 0,
+  0, 0, 96, 0, 19, 0, 47, 0, 0, 83,
+  53, 15, 66, 0, 7, 34, 0, 90, 0, 0,
+  122, 30, 0, 21, 7, 0, 14, 0, 0, 2,
+  0, 89, 0, 17, 21, 0, 35, 0, 0, 36,
+  0, 3, 0, 0, 0, 0, 0, 59, 137, 0,
+  0, 0, 0, 0, 0, 52, 0, 3, 30, 17,
+  0, 0, 80, 0, 22, 0, 52, 0, 0, 0,
+  0, 0, 0, 14, 61, 73, 19, 3, 82, 25,
+  7, 0, 0, 19, 0, 0, 0, 50, 24, 124,
+  0, 0, 0, 0, 0, 0, 16, 66, 70, 4,
+  0, 0, 12, 4, 0, 88, 7, 3, 0, 13,
+  0, 0, 74, 8, 0, 0, 84, 0, 0, 15,
+  17, 36, 17, 22, 4, 0, 9, 49, 0, 0,
+  86, 0, 46, 0, 71, 0, 0, 47, 100, 0,
+  96, 0, 0, 47, 0, 116, 0, 23, 90, 0,
+  0, 33, 0, 0, 23, 0, 0, 55, 0, 76,
+  0, 1, 45, 31, 68, 0, 0, 0, 10, 0,
+  0, 0, 0, 0, 0, 29, 67, 0, 0, 0,
+  0, 4, 0, 42, 0, 0, 54, 0, 0, 0,
+  124, 74, 44, 0, 25, 0, 0, 0, 0, 25,
+  0, 22, 0, 56, 59, 0, 21, 13, 0, 41,
+  0, 2, 0, 43, 0, 19, 0, 48, 0, 0,
+  0, 0, 56, 0, 3, 89, 5, 0, 0, 0,
+  21, 5, 0, 99, 0, 11, 0, 0, 67, 44,
+  117, 91, 15, 0, 39, 0, 3, 0, 0, 12,
+  0, 18, 5, 1, 0, 35, 0, 23, 119, 0,
+  0, 4, 0, 0, 0, 65, 91, 49, 82, 33,
+  0, 21, 0, 118, 80, 20, 83, 0, 0, 0,
+  0, 0, 100, 0, 0, 0, 15, 22, 26, 0,
+  0, 49, 63, 0, 0, 18, 0, 0, 55, 0,
+  41, 0, 0, 54, 58, 26, 28, 0, 0, 0,
+  0, 29, 0, 0, 19, 18, 0, 23, 56, 7,
+  0, 0, 19, 0, 0, 0, 0, 0, 0, 24,
+  61, 73, 32, 0, 66, 36, 9, 0, 0, 0,
+  5, 21, 0, 26, 30, 124, 0, 0, 0, 0,
+  23, 0, 28, 52, 0, 3, 0, 0, 50, 28,
+  0, 103, 0, 4, 0, 0, 39, 0, 82, 66,
+  0, 0, 35, 0, 2, 0, 0, 22, 7, 0,
+  0, 0, 0, 70, 0, 21, 74, 0, 0, 14,
+  10, 0, 0, 32, 91, 24, 64, 1, 0, 2,
+  0, 95, 0, 13, 72, 0, 0, 0, 0, 0,
+  86, 0, 0, 56, 11, 19, 0, 0, 12, 13,
+  141, 0, 0, 19, 0, 0, 4, 0, 38, 0,
+  0, 38, 31, 0, 0, 0, 0, 0, 0, 56,
+  51, 0, 69, 0, 0, 0, 107, 0, 36, 0,
+  0, 32, 38, 0, 0, 0, 0, 37, 0, 81,
+  51, 46, 25, 77, 65, 9, 0, 0, 20, 0,
+  19, 0, 51, 118, 0, 0, 0, 0, 16, 7,
+  12, 11, 0, 26, 0, 0, 55, 19, 0, 69,
+  20, 7, 22, 0, 56, 0, 0, 0, 0, 0,
+  0, 35, 0, 0, 31, 31, 30, 33, 0, 0,
+  23, 35, 0, 14, 38, 0, 27, 20, 0, 10,
+  0, 19, 19, 8, 0, 0, 0, 0, 2, 0,
+  0, 41, 51, 0, 0, 22, 0, 0, 35, 8,
+  0, 53, 41, 20, 0, 0, 35, 12, 95, 14,
+  26, 0, 0, 30, 0, 0, 70, 0, 0, 50,
+  0, 20, 0, 0, 0, 25, 0, 43, 127, 0,
+  82, 0, 12, 0, 31, 0, 14, 0, 0, 8,
+  49, 0, 2, 15, 10, 13, 0, 93, 58, 29,
+  70, 32, 22, 7, 0, 0, 38, 0, 7, 32,
+  60, 93, 0, 0, 0, 0, 38, 0, 64, 26,
+  0, 33, 0, 0, 30, 14, 0, 67, 47, 0,
+  0, 0, 6, 0, 43, 9, 0, 0, 0, 21,
+  0, 0, 0, 0, 0, 24, 0, 6, 13, 86,
+  0, 24, 27, 0, 0, 48, 0, 0, 0, 0,
+  12, 26, 3, 21, 0, 0, 0, 30, 0, 44,
+  10, 2, 0, 0, 0, 0, 48, 0, 0, 39,
+  61, 0, 1, 12, 0, 35, 123, 0, 0, 0,
+  0, 0, 0, 0, 63, 0, 17, 39, 26, 0,
+  0, 0, 0, 26, 0, 33, 42, 10, 39, 0,
+  4, 0, 83, 0, 0, 0, 0, 28, 67, 0,
+  0, 0, 0, 33, 0, 82, 37, 48, 54, 46,
+  22, 17, 0, 0, 75, 0, 31, 10, 55, 60,
+  0, 21, 0, 0, 43, 0, 38, 0, 0, 48,
+  0, 0, 41, 28, 0, 38, 57, 0, 0, 0,
+  24, 0, 32, 0, 0, 0, 0, 80, 0, 0,
+  0, 0, 14, 21, 0, 28, 36, 67, 0, 12,
+  53, 0, 1, 49, 0, 34, 0, 0, 0, 41,
+  0, 12, 9, 0, 0, 0, 0, 43, 25, 31,
+  0, 22, 14, 0, 16, 22, 0, 32, 73, 0,
+  0, 30, 3, 13, 122, 5, 40, 0, 0, 1,
+  0, 0, 93, 0, 14, 55, 0, 0, 0, 0,
+  0, 54, 0, 32, 56, 22, 48, 0, 15, 0,
+  63, 0, 0, 0, 0, 46, 59, 0, 14, 0,
+  6, 28, 0, 93, 18, 58, 66, 69, 39, 34,
+  0, 0, 61, 0, 24, 0, 24, 41, 11, 21,
+  49, 14, 29, 7, 0, 0, 0, 34, 1, 0,
+  22, 29, 0, 26, 0, 5, 31, 0, 36, 0,
+  13, 0, 0, 0, 0, 34, 0, 0, 10, 55,
+  10, 6, 0, 0, 30, 0, 0, 0, 35, 0,
+  20, 14, 0, 4, 0, 6, 0, 0, 0, 0,
+  31, 0, 49, 0, 0, 0, 64, 30, 0, 37,
+  0, 10, 0, 53, 0, 8, 43, 93, 0, 42,
+  5, 3, 30, 39, 93, 5, 0, 0, 11, 0,
+  68, 0, 0, 79, 5, 0, 0, 0, 30, 61,
+  0, 15, 39, 0, 23, 0, 0, 0, 0, 0,
+  12, 0, 0, 0, 11, 0, 7, 0, 19, 17,
+  24, 37, 0, 0, 95, 9, 0, 0, 0, 24,
+  67, 28, 0, 54, 35, 44, 0, 52, 0, 15,
+  0, 0, 0, 58, 28, 9, 0, 0, 21, 48,
+  6, 84, 0, 37, 76, 0, 22, 0, 105, 123,
+  0, 0, 100, 0, 38, 0, 0, 109, 0, 0,
+  0, 11, 0, 0, 0, 0, 96, 0, 19, 0,
+  47, 0, 0, 83, 53, 15, 66, 0, 7, 34,
+  0, 90, 0, 0, 122, 30, 0, 21, 7, 0,
+  14, 0, 0, 2, 0, 89, 0, 17, 21, 0,
+  35, 0, 0, 36, 0, 3, 0, 0, 0, 0,
+  0, 59, 137, 0, 0, 0, 0, 0, 0, 52,
+  0, 3, 30, 17, 0, 0, 80, 0, 22, 0,
+  52, 0, 0, 0, 0, 0, 0, 14, 61, 73,
+  19, 3, 82, 25, 7, 0, 0, 19, 0, 0,
+  0, 50, 24, 124, 0, 0, 0, 0, 0, 0,
+  16, 66, 70, 4, 0, 0, 12, 4, 0, 88,
+  7, 3, 0, 13, 0, 0, 74, 8, 0, 0,
+  84, 0, 0, 15, 17, 36, 17, 22, 4, 0,
+  9, 49, 0, 0, 86, 0, 46, 0, 71, 0,
+  0, 47, 100, 0, 96, 0, 0, 47, 0, 116,
+  0, 23, 90, 0, 0, 33, 0, 0, 23, 0,
+  0, 55, 0, 76, 0, 1, 45, 31, 68, 0,
+  0, 0, 10, 0, 0, 0, 0, 0, 0, 29,
+  67, 0, 0, 0, 0, 4, 0, 42, 0, 0,
+  54, 0, 0, 0, 124, 74, 44, 0, 25, 0,
+  0, 0, 0, 25, 0, 22, 0, 56, 83, 83,
+  12, 72, 44, 15, 0, 0, 20, 0, 22, 0,
+  23, 126, 0, 0, 0, 0, 39, 0, 24, 37,
+  34, 21, 0, 0, 35, 11, 0, 34, 52, 81,
+  0, 0, 0, 0, 0, 26, 0, 0, 0, 1,
+  0, 0, 1, 18, 42, 71, 0, 0, 11, 40,
+  0, 7, 106, 0, 38, 4, 10, 0, 0, 34,
+  61, 26, 20, 0, 27, 21, 0, 98, 0, 49,
+  51, 0, 0, 28, 54, 0, 44, 0, 0, 48,
+  15, 60, 0, 1, 2, 45, 68, 0, 14, 0,
+  0, 25, 0, 0, 81, 0, 11, 15, 12, 121,
+  4, 0, 0, 16, 0, 68, 74, 0, 26, 0,
+  17, 1, 24, 87, 0, 0, 20, 2, 10, 0,
+  0, 0, 0, 22, 0, 87, 32, 0, 66, 36,
+  9, 0, 0, 0, 5, 21, 0, 26, 30, 124,
+  0, 0, 0, 0, 23, 0, 28, 52, 0, 3,
+  0, 0, 50, 28, 0, 103, 0, 4, 0, 0,
+  39, 0, 82, 66, 0, 0, 35, 0, 2, 0,
+  0, 22, 7, 0, 0, 0, 0, 70, 0, 21,
+  74, 0, 0, 14, 10, 0, 0, 32, 91, 24,
+  64, 1, 0, 2, 0, 95, 0, 13, 72, 0,
+  0, 0, 0, 0, 86, 0, 0, 56, 11, 19,
+  0, 0, 12, 13, 141, 0, 0, 19, 0, 0,
+  4, 0, 38, 0, 0, 38, 31, 0, 0, 0,
+  0, 0, 0, 56, 51, 0, 69, 0, 0, 0,
+  107, 0, 36, 0, 0, 32, 38, 0, 0, 0,
+  0, 37, 0, 81, 51, 46, 25, 77, 65, 9,
+  0, 0, 20, 0, 19, 0, 51, 118, 0, 0,
+  0, 0, 16, 7, 12, 11, 0, 26, 0, 0,
+  55, 19, 0, 69, 20, 7, 22, 0, 56, 0,
+  0, 0, 0, 0, 0, 35, 0, 0, 31, 31,
+  30, 33, 0, 0, 23, 35, 0, 14, 38, 0,
+  27, 20, 0, 10, 0, 19, 19, 8, 0, 0,
+  0, 0, 2, 0, 0, 41, 51, 0, 0, 22,
+  0, 0, 35, 8, 0, 53, 41, 20, 0, 0,
+  35, 12, 95, 14, 26, 0, 0, 30, 0, 0,
+  70, 0, 0, 50, 0, 20, 0, 0, 0, 25,
+  0, 43, 127, 0, 82, 0, 12, 0, 31, 0,
+  14, 0, 0, 8, 49, 0, 2, 15, 10, 13,
+  0, 93, 42, 127, 15, 99, 80, 43, 0, 0,
+  43, 0, 32, 0, 35, 29, 0, 0, 11, 0,
+  41, 15, 0, 0, 0, 47, 24, 0, 52, 29,
+  0, 37, 5, 49, 69, 0, 20, 0, 0, 0,
+  0, 0, 0, 17, 0, 6, 19, 56, 44, 46,
+  0, 7, 4, 0, 0, 17, 32, 0, 50, 2,
+  0, 29, 21, 24, 0, 8, 0, 0, 52, 4,
+  27, 0, 0, 21, 45, 4, 6, 45, 10, 2,
+  0, 2, 0, 19, 40, 73, 0, 17, 5, 38,
+  21, 49, 107, 0, 0, 49, 0, 0, 90, 0,
+  23, 57, 7, 99, 1, 0, 25, 33, 41, 62,
+  122, 0, 7, 22, 36, 0, 0, 0, 0, 0,
+  0, 0, 13, 0, 43, 0, 45, 1, 13, 74,
+  37, 48, 54, 46, 22, 17, 0, 0, 75, 0,
+  31, 10, 55, 60, 0, 21, 0, 0, 43, 0,
+  38, 0, 0, 48, 0, 0, 41, 28, 0, 38,
+  57, 0, 0, 0, 24, 0, 32, 0, 0, 0,
+  0, 80, 0, 0, 0, 0, 14, 21, 0, 28,
+  36, 67, 0, 12, 53, 0, 1, 49, 0, 34,
+  0, 0, 0, 41, 0, 12, 9, 0, 0, 0,
+  0, 43, 25, 31, 0, 22, 14, 0, 16, 22,
+  0, 32, 73, 0, 0, 30, 3, 13, 122, 5,
+  40, 0, 0, 1, 0, 0, 93, 0, 14, 55,
+  0, 0, 0, 0, 0, 54, 0, 32, 56, 22,
+  48, 0, 15, 0, 63, 0, 0, 0, 0, 46,
+  59, 0, 14, 0, 6, 28, 0, 93, 18, 58,
+  66, 69, 39, 34, 0, 0, 61, 0, 24, 0,
+  24, 41, 11, 21, 49, 14, 29, 7, 0, 0,
+  0, 34, 1, 0, 22, 29, 0, 26, 0, 5,
+  31, 0, 36, 0, 13, 0, 0, 0, 0, 34,
+  0, 0, 10, 55, 10, 6, 0, 0, 30, 0,
+  0, 0, 35, 0, 20, 14, 0, 4, 0, 6,
+  0, 0, 0, 0, 31, 0, 49, 0, 0, 0,
+  64, 30, 0, 37, 0, 10, 0, 53, 0, 8,
+  43, 93, 0, 42, 5, 3, 30, 39, 93, 5,
+  0, 0, 11, 0, 68, 0, 0, 79, 5, 0,
+  0, 0, 30, 61, 0, 15, 39, 0, 23, 0,
+  0, 0, 0, 0, 12, 0, 0, 0, 11, 0,
+  7, 0, 19, 17, 24, 37, 19, 83, 100, 57,
+  60, 86, 0, 0, 16, 0, 0, 0, 1, 37,
+  9, 22, 45, 0, 3, 24, 0, 9, 0, 26,
+  12, 0, 0, 30, 0, 58, 0, 45, 5, 36,
+  29, 8, 0, 14, 0, 6, 0, 0, 0, 30,
+  1, 47, 31, 38, 0, 0, 15, 0, 0, 0,
+  7, 0, 28, 11, 0, 0, 0, 19, 0, 0,
+  0, 0, 25, 0, 71, 0, 0, 0, 48, 11,
+  37, 0, 0, 0, 0, 14, 0, 10, 19, 113,
+  22, 41, 0, 37, 0, 20, 39, 0, 0, 0,
+  11, 0, 10, 0, 0, 52, 9, 11, 0, 0,
+  76, 50, 5, 16, 33, 0, 25, 22, 0, 4,
+  0, 0, 10, 0, 0, 0, 0, 0, 0, 0,
+  34, 0, 47, 18, 19, 3, 82, 25, 7, 0,
+  0, 19, 0, 0, 0, 50, 24, 124, 0, 0,
+  0, 0, 0, 0, 16, 66, 70, 4, 0, 0,
+  12, 4, 0, 88, 7, 3, 0, 13, 0, 0,
+  74, 8, 0, 0, 84, 0, 0, 15, 17, 36,
+  17, 22, 4, 0, 9, 49, 0, 0, 86, 0,
+  46, 0, 71, 0, 0, 47, 100, 0, 96, 0,
+  0, 47, 0, 116, 0, 23, 90, 0, 0, 33,
+  0, 0, 23, 0, 0, 55, 0, 76, 0, 1,
+  45, 31, 68, 0, 0, 0, 10, 0, 0, 0,
+  0, 0, 0, 29, 67, 0, 0, 0, 0, 4,
+  0, 42, 0, 0, 54, 0, 0, 0, 124, 74,
+  44, 0, 25, 0, 0, 0, 0, 25, 0, 22,
+  0, 56, 83, 83, 12, 72, 44, 15, 0, 0,
+  20, 0, 22, 0, 23, 126, 0, 0, 0, 0,
+  39, 0, 24, 37, 34, 21, 0, 0, 35, 11,
+  0, 34, 52, 81, 0, 0, 0, 0, 0, 26,
+  0, 0, 0, 1, 0, 0, 1, 18, 42, 71,
+  0, 0, 11, 40, 0, 7, 106, 0, 38, 4,
+  10, 0, 0, 34, 61, 26, 20, 0, 27, 21,
+  0, 98, 0, 49, 51, 0, 0, 28, 54, 0,
+  44, 0, 0, 48, 15, 60, 0, 1, 2, 45,
+  68, 0, 14, 0, 0, 25, 0, 0, 81, 0,
+  11, 15, 12, 121, 4, 0, 0, 16, 0, 68,
+  74, 0, 26, 0, 17, 1, 24, 87, 0, 0,
+  20, 2, 10, 0, 0, 0, 0, 22, 0, 87,
+  35, 0, 20, 65, 14, 232, 0, 0, 1, 0,
+  0, 0, 0, 21, 0, 0, 0, 33, 62, 0,
+  0, 113, 15, 0, 0, 0, 0, 6, 0, 17,
+  8, 99, 0, 0, 0, 33, 0, 40, 0, 0,
+  0, 0, 0, 0, 0, 58, 44, 47, 7, 4,
+  0, 38, 0, 0, 142, 0, 48, 0, 21, 0,
+  27, 92, 17, 0, 115, 0, 0, 40, 0, 96,
+  83, 63, 62, 0, 0, 35, 43, 0, 0, 0,
+  0, 0, 46, 65, 0, 0, 0, 31, 0, 0,
+  7, 7, 0, 0, 70, 0, 52, 0, 0, 9,
+  17, 116, 2, 0, 0, 5, 18, 17, 0, 0,
+  0, 39, 0, 0, 0, 45, 36, 0, 13, 16,
+  0, 19, 0, 0, 0, 15, 0, 44, 51, 46,
+  25, 77, 65, 9, 0, 0, 20, 0, 19, 0,
+  51, 118, 0, 0, 0, 0, 16, 7, 12, 11,
+  0, 26, 0, 0, 55, 19, 0, 69, 20, 7,
+  22, 0, 56, 0, 0, 0, 0, 0, 0, 35,
+  0, 0, 31, 31, 30, 33, 0, 0, 23, 35,
+  0, 14, 38, 0, 27, 20, 0, 10, 0, 19,
+  19, 8, 0, 0, 0, 0, 2, 0, 0, 41,
+  51, 0, 0, 22, 0, 0, 35, 8, 0, 53,
+  41, 20, 0, 0, 35, 12, 95, 14, 26, 0,
+  0, 30, 0, 0, 70, 0, 0, 50, 0, 20,
+  0, 0, 0, 25, 0, 43, 127, 0, 82, 0,
+  12, 0, 31, 0, 14, 0, 0, 8, 49, 0,
+  2, 15, 10, 13, 0, 93, 42, 127, 15, 99,
+  80, 43, 0, 0, 43, 0, 32, 0, 35, 29,
+  0, 0, 11, 0, 41, 15, 0, 0, 0, 47,
+  24, 0, 52, 29, 0, 37, 5, 49, 69, 0,
+  20, 0, 0, 0, 0, 0, 0, 17, 0, 6,
+  19, 56, 44, 46, 0, 7, 4, 0, 0, 17,
+  32, 0, 50, 2, 0, 29, 21, 24, 0, 8,
+  0, 0, 52, 4, 27, 0, 0, 21, 45, 4,
+  6, 45, 10, 2, 0, 2, 0, 19, 40, 73,
+  0, 17, 5, 38, 21, 49, 107, 0, 0, 49,
+  0, 0, 90, 0, 23, 57, 7, 99, 1, 0,
+  25, 33, 41, 62, 122, 0, 7, 22, 36, 0,
+  0, 0, 0, 0, 0, 0, 13, 0, 43, 0,
+  45, 1, 13, 74, 17, 8, 86, 68, 23, 217,
+  0, 0, 29, 0, 0, 0, 32, 0, 0, 0,
+  31, 18, 66, 0, 0, 112, 15, 8, 7, 0,
+  0, 35, 0, 72, 0, 82, 0, 0, 0, 30,
+  0, 0, 1, 0, 0, 19, 0, 19, 0, 50,
+  59, 42, 0, 14, 0, 45, 0, 0, 97, 0,
+  62, 0, 33, 0, 0, 70, 0, 0, 53, 0,
+  0, 26, 12, 6, 27, 25, 76, 0, 0, 26,
+  25, 0, 0, 18, 0, 0, 77, 83, 0, 0,
+  0, 18, 0, 4, 54, 0, 0, 0, 24, 0,
+  25, 0, 15, 39, 25, 35, 17, 0, 0, 31,
+  47, 29, 0, 0, 0, 45, 0, 0, 0, 0,
+  38, 0, 3, 0, 0, 1, 0, 22, 25, 0,
+  0, 20, 18, 58, 66, 69, 39, 34, 0, 0,
+  61, 0, 24, 0, 24, 41, 11, 21, 49, 14,
+  29, 7, 0, 0, 0, 34, 1, 0, 22, 29,
+  0, 26, 0, 5, 31, 0, 36, 0, 13, 0,
+  0, 0, 0, 34, 0, 0, 10, 55, 10, 6,
+  0, 0, 30, 0, 0, 0, 35, 0, 20, 14,
+  0, 4, 0, 6, 0, 0, 0, 0, 31, 0,
+  49, 0, 0, 0, 64, 30, 0, 37, 0, 10,
+  0, 53, 0, 8, 43, 93, 0, 42, 5, 3,
+  30, 39, 93, 5, 0, 0, 11, 0, 68, 0,
+  0, 79, 5, 0, 0, 0, 30, 61, 0, 15,
+  39, 0, 23, 0, 0, 0, 0, 0, 12, 0,
+  0, 0, 11, 0, 7, 0, 19, 17, 24, 37,
+  19, 83, 100, 57, 60, 86, 0, 0, 16, 0,
+  0, 0, 1, 37, 9, 22, 45, 0, 3, 24,
+  0, 9, 0, 26, 12, 0, 0, 30, 0, 58,
+  0, 45, 5, 36, 29, 8, 0, 14, 0, 6,
+  0, 0, 0, 30, 1, 47, 31, 38, 0, 0,
+  15, 0, 0, 0, 7, 0, 28, 11, 0, 0,
+  0, 19, 0, 0, 0, 0, 25, 0, 71, 0,
+  0, 0, 48, 11, 37, 0, 0, 0, 0, 14,
+  0, 10, 19, 113, 22, 41, 0, 37, 0, 20,
+  39, 0, 0, 0, 11, 0, 10, 0, 0, 52,
+  9, 11, 0, 0, 76, 50, 5, 16, 33, 0,
+  25, 22, 0, 4, 0, 0, 10, 0, 0, 0,
+  0, 0, 0, 0, 34, 0, 47, 18, 11, 11,
+  105, 33, 25, 144, 0, 0, 0, 0, 0, 0,
+  17, 0, 0, 0, 17, 5, 23, 0, 0, 94,
+  8, 12, 0, 0, 0, 0, 0, 52, 0, 26,
+  0, 34, 0, 30, 0, 0, 0, 25, 0, 0,
+  0, 39, 0, 0, 23, 37, 0, 0, 0, 86,
+  0, 0, 64, 0, 59, 0, 41, 0, 0, 32,
+  0, 17, 51, 3, 0, 0, 41, 0, 4, 7,
+  56, 0, 27, 0, 0, 0, 0, 10, 0, 0,
+  45, 50, 55, 11, 0, 9, 2, 0, 0, 0,
+  20, 0, 18, 0, 0, 0, 20, 19, 0, 0,
+  0, 0, 22, 38, 4, 0, 0, 0, 37, 28,
+  0, 0, 0, 0, 63, 0, 8, 0, 0, 0,
+  0, 12, 39, 5, 0, 0, 83, 83, 12, 72,
+  44, 15, 0, 0, 20, 0, 22, 0, 23, 126,
+  0, 0, 0, 0, 39, 0, 24, 37, 34, 21,
+  0, 0, 35, 11, 0, 34, 52, 81, 0, 0,
+  0, 0, 0, 26, 0, 0, 0, 1, 0, 0,
+  1, 18, 42, 71, 0, 0, 11, 40, 0, 7,
+  106, 0, 38, 4, 10, 0, 0, 34, 61, 26,
+  20, 0, 27, 21, 0, 98, 0, 49, 51, 0,
+  0, 28, 54, 0, 44, 0, 0, 48, 15, 60,
+  0, 1, 2, 45, 68, 0, 14, 0, 0, 25,
+  0, 0, 81, 0, 11, 15, 12, 121, 4, 0,
+  0, 16, 0, 68, 74, 0, 26, 0, 17, 1,
+  24, 87, 0, 0, 20, 2, 10, 0, 0, 0,
+  0, 22, 0, 87, 35, 0, 20, 65, 14, 232,
+  0, 0, 1, 0, 0, 0, 0, 21, 0, 0,
+  0, 33, 62, 0, 0, 113, 15, 0, 0, 0,
+  0, 6, 0, 17, 8, 99, 0, 0, 0, 33,
+  0, 40, 0, 0, 0, 0, 0, 0, 0, 58,
+  44, 47, 7, 4, 0, 38, 0, 0, 142, 0,
+  48, 0, 21, 0, 27, 92, 17, 0, 115, 0,
+  0, 40, 0, 96, 83, 63, 62, 0, 0, 35,
+  43, 0, 0, 0, 0, 0, 46, 65, 0, 0,
+  0, 31, 0, 0, 7, 7, 0, 0, 70, 0,
+  52, 0, 0, 9, 17, 116, 2, 0, 0, 5,
+  18, 17, 0, 0, 0, 39, 0, 0, 0, 45,
+  36, 0, 13, 16, 0, 19, 0, 0, 0, 15,
+  0, 44, 0, 0, 0, 5, 19, 184, 0, 0,
+  0, 0, 0, 0, 30, 14, 0, 24, 4, 50,
+  5, 0, 21, 0, 0, 62, 18, 19, 0, 0,
+  0, 10, 18, 0, 0, 34, 0, 4, 0, 24,
+  0, 24, 0, 55, 0, 16, 0, 17, 43, 43,
+  0, 20, 0, 38, 14, 0, 0, 0, 9, 0,
+  19, 12, 5, 26, 0, 0, 6, 0, 0, 22,
+  22, 0, 30, 56, 37, 1, 2, 80, 0, 0,
+  0, 42, 0, 0, 13, 12, 24, 0, 22, 14,
+  2, 28, 1, 67, 43, 9, 35, 30, 0, 0,
+  7, 25, 0, 0, 0, 0, 0, 0, 0, 6,
+  0, 17, 0, 1, 0, 13, 0, 7, 81, 29,
+  34, 0, 48, 9, 42, 0, 38, 19, 0, 0,
+  42, 127, 15, 99, 80, 43, 0, 0, 43, 0,
+  32, 0, 35, 29, 0, 0, 11, 0, 41, 15,
+  0, 0, 0, 47, 24, 0, 52, 29, 0, 37,
+  5, 49, 69, 0, 20, 0, 0, 0, 0, 0,
+  0, 17, 0, 6, 19, 56, 44, 46, 0, 7,
+  4, 0, 0, 17, 32, 0, 50, 2, 0, 29,
+  21, 24, 0, 8, 0, 0, 52, 4, 27, 0,
+  0, 21, 45, 4, 6, 45, 10, 2, 0, 2,
+  0, 19, 40, 73, 0, 17, 5, 38, 21, 49,
+  107, 0, 0, 49, 0, 0, 90, 0, 23, 57,
+  7, 99, 1, 0, 25, 33, 41, 62, 122, 0,
+  7, 22, 36, 0, 0, 0, 0, 0, 0, 0,
+  13, 0, 43, 0, 45, 1, 13, 74, 17, 8,
+  86, 68, 23, 217, 0, 0, 29, 0, 0, 0,
+  32, 0, 0, 0, 31, 18, 66, 0, 0, 112,
+  15, 8, 7, 0, 0, 35, 0, 72, 0, 82,
+  0, 0, 0, 30, 0, 0, 1, 0, 0, 19,
+  0, 19, 0, 50, 59, 42, 0, 14, 0, 45,
+  0, 0, 97, 0, 62, 0, 33, 0, 0, 70,
+  0, 0, 53, 0, 0, 26, 12, 6, 27, 25,
+  76, 0, 0, 26, 25, 0, 0, 18, 0, 0,
+  77, 83, 0, 0, 0, 18, 0, 4, 54, 0,
+  0, 0, 24, 0, 25, 0, 15, 39, 25, 35,
+  17, 0, 0, 31, 47, 29, 0, 0, 0, 45,
+  0, 0, 0, 0, 38, 0, 3, 0, 0, 1,
+  0, 22, 25, 0, 0, 20, 0, 0, 0, 0,
+  1, 125, 0, 0, 0, 0, 0, 0, 59, 8,
+  0, 44, 12, 40, 18, 0, 40, 6, 0, 49,
+  0, 0, 0, 0, 0, 14, 40, 0, 0, 17,
+  0, 8, 0, 16, 0, 48, 35, 47, 0, 33,
+  1, 0, 7, 27, 0, 35, 0, 77, 28, 0,
+  14, 0, 38, 0, 36, 0, 0, 14, 0, 11,
+  0, 0, 0, 3, 8, 0, 16, 34, 27, 15,
+  0, 70, 0, 0, 0, 26, 7, 0, 14, 12,
+  42, 0, 12, 0, 8, 25, 0, 47, 52, 0,
+  15, 13, 0, 0, 17, 28, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 32, 29, 12, 0, 47,
+  0, 0, 66, 14, 50, 0, 35, 14, 18, 0,
+  67, 1, 0, 0, 19, 83, 100, 57, 60, 86,
+  0, 0, 16, 0, 0, 0, 1, 37, 9, 22,
+  45, 0, 3, 24, 0, 9, 0, 26, 12, 0,
+  0, 30, 0, 58, 0, 45, 5, 36, 29, 8,
+  0, 14, 0, 6, 0, 0, 0, 30, 1, 47,
+  31, 38, 0, 0, 15, 0, 0, 0, 7, 0,
+  28, 11, 0, 0, 0, 19, 0, 0, 0, 0,
+  25, 0, 71, 0, 0, 0, 48, 11, 37, 0,
+  0, 0, 0, 14, 0, 10, 19, 113, 22, 41,
+  0, 37, 0, 20, 39, 0, 0, 0, 11, 0,
+  10, 0, 0, 52, 9, 11, 0, 0, 76, 50,
+  5, 16, 33, 0, 25, 22, 0, 4, 0, 0,
+  10, 0, 0, 0, 0, 0, 0, 0, 34, 0,
+  47, 18, 11, 11, 105, 33, 25, 144, 0, 0,
+  0, 0, 0, 0, 17, 0, 0, 0, 17, 5,
+  23, 0, 0, 94, 8, 12, 0, 0, 0, 0,
+  0, 52, 0, 26, 0, 34, 0, 30, 0, 0,
+  0, 25, 0, 0, 0, 39, 0, 0, 23, 37,
+  0, 0, 0, 86, 0, 0, 64, 0, 59, 0,
+  41, 0, 0, 32, 0, 17, 51, 3, 0, 0,
+  41, 0, 4, 7, 56, 0, 27, 0, 0, 0,
+  0, 10, 0, 0, 45, 50, 55, 11, 0, 9,
+  2, 0, 0, 0, 20, 0, 18, 0, 0, 0,
+  20, 19, 0, 0, 0, 0, 22, 38, 4, 0,
+  0, 0, 37, 28, 0, 0, 0, 0, 63, 0,
+  8, 0, 0, 0, 0, 12, 39, 5, 0, 0,
+  0, 2, 46, 0, 14, 18, 11, 0, 12, 0,
+  0, 11, 59, 26, 0, 39, 3, 30, 27, 0,
+  68, 23, 33, 23, 0, 0, 0, 0, 0, 0,
+  61, 0, 0, 0, 0, 7, 0, 8, 0, 25,
+  64, 32, 0, 78, 13, 0, 0, 10, 0, 12,
+  0, 114, 19, 0, 44, 0, 53, 0, 52, 0,
+  0, 0, 0, 20, 19, 0, 0, 11, 0, 0,
+  0, 19, 15, 39, 5, 36, 0, 0, 0, 0,
+  27, 0, 8, 0, 65, 1, 0, 0, 39, 0,
+  0, 25, 36, 0, 0, 17, 0, 0, 33, 36,
+  0, 0, 0, 0, 22, 0, 0, 0, 0, 13,
+  66, 18, 0, 34, 0, 0, 63, 12, 74, 5,
+  47, 3, 0, 0, 82, 14, 12, 0, 35, 0,
+  20, 65, 14, 232, 0, 0, 1, 0, 0, 0,
+  0, 21, 0, 0, 0, 33, 62, 0, 0, 113,
+  15, 0, 0, 0, 0, 6, 0, 17, 8, 99,
+  0, 0, 0, 33, 0, 40, 0, 0, 0, 0,
+  0, 0, 0, 58, 44, 47, 7, 4, 0, 38,
+  0, 0, 142, 0, 48, 0, 21, 0, 27, 92,
+  17, 0, 115, 0, 0, 40, 0, 96, 83, 63,
+  62, 0, 0, 35, 43, 0, 0, 0, 0, 0,
+  46, 65, 0, 0, 0, 31, 0, 0, 7, 7,
+  0, 0, 70, 0, 52, 0, 0, 9, 17, 116,
+  2, 0, 0, 5, 18, 17, 0, 0, 0, 39,
+  0, 0, 0, 45, 36, 0, 13, 16, 0, 19,
+  0, 0, 0, 15, 0, 44, 0, 0, 0, 5,
+  19, 184, 0, 0, 0, 0, 0, 0, 30, 14,
+  0, 24, 4, 50, 5, 0, 21, 0, 0, 62,
+  18, 19, 0, 0, 0, 10, 18, 0, 0, 34,
+  0, 4, 0, 24, 0, 24, 0, 55, 0, 16,
+  0, 17, 43, 43, 0, 20, 0, 38, 14, 0,
+  0, 0, 9, 0, 19, 12, 5, 26, 0, 0,
+  6, 0, 0, 22, 22, 0, 30, 56, 37, 1,
+  2, 80, 0, 0, 0, 42, 0, 0, 13, 12,
+  24, 0, 22, 14, 2, 28, 1, 67, 43, 9,
+  35, 30, 0, 0, 7, 25, 0, 0, 0, 0,
+  0, 0, 0, 6, 0, 17, 0, 1, 0, 13,
+  0, 7, 81, 29, 34, 0, 48, 9, 42, 0,
+  38, 19, 0, 0, 0, 34, 49, 0, 25, 0,
+  17, 0, 0, 0, 0, 0, 29, 51, 2, 46,
+  15, 40, 0, 20, 33, 0, 79, 40, 0, 20,
+  0, 0, 0, 0, 25, 0, 0, 0, 0, 0,
+  0, 5, 0, 35, 63, 42, 0, 75, 56, 0,
+  0, 0, 0, 4, 0, 42, 63, 0, 1, 0,
+  44, 5, 9, 0, 0, 3, 0, 23, 0, 0,
+  26, 7, 0, 0, 0, 3, 4, 30, 12, 34,
+  0, 8, 0, 0, 40, 0, 0, 0, 68, 13,
+  0, 0, 40, 12, 0, 29, 32, 0, 0, 30,
+  0, 0, 0, 46, 0, 0, 0, 0, 5, 0,
+  0, 0, 0, 29, 58, 4, 0, 15, 30, 0,
+  26, 17, 54, 0, 15, 0, 9, 0, 76, 5,
+  0, 0, 17, 8, 86, 68, 23, 217, 0, 0,
+  29, 0, 0, 0, 32, 0, 0, 0, 31, 18,
+  66, 0, 0, 112, 15, 8, 7, 0, 0, 35,
+  0, 72, 0, 82, 0, 0, 0, 30, 0, 0,
+  1, 0, 0, 19, 0, 19, 0, 50, 59, 42,
+  0, 14, 0, 45, 0, 0, 97, 0, 62, 0,
+  33, 0, 0, 70, 0, 0, 53, 0, 0, 26,
+  12, 6, 27, 25, 76, 0, 0, 26, 25, 0,
+  0, 18, 0, 0, 77, 83, 0, 0, 0, 18,
+  0, 4, 54, 0, 0, 0, 24, 0, 25, 0,
+  15, 39, 25, 35, 17, 0, 0, 31, 47, 29,
+  0, 0, 0, 45, 0, 0, 0, 0, 38, 0,
+  3, 0, 0, 1, 0, 22, 25, 0, 0, 20,
+  0, 0, 0, 0, 1, 125, 0, 0, 0, 0,
+  0, 0, 59, 8, 0, 44, 12, 40, 18, 0,
+  40, 6, 0, 49, 0, 0, 0, 0, 0, 14,
+  40, 0, 0, 17, 0, 8, 0, 16, 0, 48,
+  35, 47, 0, 33, 1, 0, 7, 27, 0, 35,
+  0, 77, 28, 0, 14, 0, 38, 0, 36, 0,
+  0, 14, 0, 11, 0, 0, 0, 3, 8, 0,
+  16, 34, 27, 15, 0, 70, 0, 0, 0, 26,
+  7, 0, 14, 12, 42, 0, 12, 0, 8, 25,
+  0, 47, 52, 0, 15, 13, 0, 0, 17, 28,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 32,
+  29, 12, 0, 47, 0, 0, 66, 14, 50, 0,
+  35, 14, 18, 0, 67, 1, 0, 0, 0, 0,
+  77, 0, 0, 0, 2, 0, 0, 0, 0, 1,
+  29, 58, 0, 41, 0, 69, 29, 7, 59, 19,
+  117, 17, 0, 0, 0, 5, 0, 0, 15, 0,
+  0, 0, 0, 13, 0, 12, 0, 0, 66, 0,
+  0, 79, 32, 0, 0, 0, 0, 6, 0, 87,
+  7, 0, 39, 0, 49, 0, 7, 0, 0, 1,
+  10, 0, 77, 0, 0, 21, 0, 50, 0, 0,
+  2, 19, 0, 7, 0, 0, 0, 0, 19, 0,
+  2, 0, 62, 8, 0, 0, 25, 0, 0, 13,
+  0, 0, 16, 30, 0, 0, 0, 54, 3, 0,
+  0, 0, 20, 0, 0, 0, 0, 0, 62, 11,
+  0, 38, 13, 0, 89, 23, 44, 14, 34, 0,
+  0, 0, 57, 0, 15, 0, 11, 11, 105, 33,
+  25, 144, 0, 0, 0, 0, 0, 0, 17, 0,
+  0, 0, 17, 5, 23, 0, 0, 94, 8, 12,
+  0, 0, 0, 0, 0, 52, 0, 26, 0, 34,
+  0, 30, 0, 0, 0, 25, 0, 0, 0, 39,
+  0, 0, 23, 37, 0, 0, 0, 86, 0, 0,
+  64, 0, 59, 0, 41, 0, 0, 32, 0, 17,
+  51, 3, 0, 0, 41, 0, 4, 7, 56, 0,
+  27, 0, 0, 0, 0, 10, 0, 0, 45, 50,
+  55, 11, 0, 9, 2, 0, 0, 0, 20, 0,
+  18, 0, 0, 0, 20, 19, 0, 0, 0, 0,
+  22, 38, 4, 0, 0, 0, 37, 28, 0, 0,
+  0, 0, 63, 0, 8, 0, 0, 0, 0, 12,
+  39, 5, 0, 0, 0, 2, 46, 0, 14, 18,
+  11, 0, 12, 0, 0, 11, 59, 26, 0, 39,
+  3, 30, 27, 0, 68, 23, 33, 23, 0, 0,
+  0, 0, 0, 0, 61, 0, 0, 0, 0, 7,
+  0, 8, 0, 25, 64, 32, 0, 78, 13, 0,
+  0, 10, 0, 12, 0, 114, 19, 0, 44, 0,
+  53, 0, 52, 0, 0, 0, 0, 20, 19, 0,
+  0, 11, 0, 0, 0, 19, 15, 39, 5, 36,
+  0, 0, 0, 0, 27, 0, 8, 0, 65, 1,
+  0, 0, 39, 0, 0, 25, 36, 0, 0, 17,
+  0, 0, 33, 36, 0, 0, 0, 0, 22, 0,
+  0, 0, 0, 13, 66, 18, 0, 34, 0, 0,
+  63, 12, 74, 5, 47, 3, 0, 0, 82, 14,
+  12, 0, 5, 0, 69, 0, 12, 8, 0, 0,
+  19, 0, 0, 0, 40, 75, 0, 7, 0, 50,
+  40, 0, 68, 50, 83, 1, 0, 0, 0, 31,
+  0, 3, 20, 0, 0, 0, 0, 5, 0, 22,
+  0, 0, 22, 4, 0, 91, 26, 21, 0, 48,
+  0, 0, 1, 153, 0, 0, 66, 0, 33, 0,
+  18, 0, 0, 0, 11, 0, 112, 0, 0, 0,
+  0, 59, 0, 0, 0, 7, 0, 0, 0, 0,
+  0, 0, 9, 0, 15, 0, 36, 8, 0, 0,
+  45, 0, 0, 0, 0, 0, 6, 8, 0, 0,
+  1, 53, 30, 0, 0, 0, 16, 0, 0, 5,
+  5, 0, 72, 5, 0, 42, 10, 0, 150, 0,
+  30, 25, 71, 0, 0, 0, 50, 0, 12, 0,
+  0, 0, 0, 5, 19, 184, 0, 0, 0, 0,
+  0, 0, 30, 14, 0, 24, 4, 50, 5, 0,
+  21, 0, 0, 62, 18, 19, 0, 0, 0, 10,
+  18, 0, 0, 34, 0, 4, 0, 24, 0, 24,
+  0, 55, 0, 16, 0, 17, 43, 43, 0, 20,
+  0, 38, 14, 0, 0, 0, 9, 0, 19, 12,
+  5, 26, 0, 0, 6, 0, 0, 22, 22, 0,
+  30, 56, 37, 1, 2, 80, 0, 0, 0, 42,
+  0, 0, 13, 12, 24, 0, 22, 14, 2, 28,
+  1, 67, 43, 9, 35, 30, 0, 0, 7, 25,
+  0, 0, 0, 0, 0, 0, 0, 6, 0, 17,
+  0, 1, 0, 13, 0, 7, 81, 29, 34, 0,
+  48, 9, 42, 0, 38, 19, 0, 0, 0, 34,
+  49, 0, 25, 0, 17, 0, 0, 0, 0, 0,
+  29, 51, 2, 46, 15, 40, 0, 20, 33, 0,
+  79, 40, 0, 20, 0, 0, 0, 0, 25, 0,
+  0, 0, 0, 0, 0, 5, 0, 35, 63, 42,
+  0, 75, 56, 0, 0, 0, 0, 4, 0, 42,
+  63, 0, 1, 0, 44, 5, 9, 0, 0, 3,
+  0, 23, 0, 0, 26, 7, 0, 0, 0, 3,
+  4, 30, 12, 34, 0, 8, 0, 0, 40, 0,
+  0, 0, 68, 13, 0, 0, 40, 12, 0, 29,
+  32, 0, 0, 30, 0, 0, 0, 46, 0, 0,
+  0, 0, 5, 0, 0, 0, 0, 29, 58, 4,
+  0, 15, 30, 0, 26, 17, 54, 0, 15, 0,
+  9, 0, 76, 5, 0, 0, 10, 0, 77, 0,
+  9, 10, 0, 0, 4, 0, 0, 8, 3, 82,
+  0, 0, 0, 46, 42, 0, 45, 68, 136, 0,
+  0, 0, 0, 0, 0, 0, 3, 0, 0, 0,
+  0, 9, 0, 0, 0, 0, 33, 0, 0, 90,
+  40, 14, 0, 21, 0, 0, 0, 136, 0, 0,
+  74, 0, 41, 0, 36, 0, 0, 0, 35, 0,
+  125, 0, 0, 23, 0, 91, 0, 0, 13, 4,
+  0, 0, 7, 0, 0, 0, 15, 0, 23, 0,
+  45, 6, 0, 0, 20, 0, 0, 0, 0, 0,
+  24, 27, 0, 0, 0, 52, 15, 0, 0, 0,
+  14, 0, 0, 2, 0, 0, 69, 4, 0, 37,
+  12, 0, 118, 0, 23, 19, 24, 0, 0, 0,
+  53, 0, 0, 0, 0, 0, 0, 0, 1, 125,
+  0, 0, 0, 0, 0, 0, 59, 8, 0, 44,
+  12, 40, 18, 0, 40, 6, 0, 49, 0, 0,
+  0, 0, 0, 14, 40, 0, 0, 17, 0, 8,
+  0, 16, 0, 48, 35, 47, 0, 33, 1, 0,
+  7, 27, 0, 35, 0, 77, 28, 0, 14, 0,
+  38, 0, 36, 0, 0, 14, 0, 11, 0, 0,
+  0, 3, 8, 0, 16, 34, 27, 15, 0, 70,
+  0, 0, 0, 26, 7, 0, 14, 12, 42, 0,
+  12, 0, 8, 25, 0, 47, 52, 0, 15, 13,
+  0, 0, 17, 28, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 32, 29, 12, 0, 47, 0, 0,
+  66, 14, 50, 0, 35, 14, 18, 0, 67, 1,
+  0, 0, 0, 0, 77, 0, 0, 0, 2, 0,
+  0, 0, 0, 1, 29, 58, 0, 41, 0, 69,
+  29, 7, 59, 19, 117, 17, 0, 0, 0, 5,
+  0, 0, 15, 0, 0, 0, 0, 13, 0, 12,
+  0, 0, 66, 0, 0, 79, 32, 0, 0, 0,
+  0, 6, 0, 87, 7, 0, 39, 0, 49, 0,
+  7, 0, 0, 1, 10, 0, 77, 0, 0, 21,
+  0, 50, 0, 0, 2, 19, 0, 7, 0, 0,
+  0, 0, 19, 0, 2, 0, 62, 8, 0, 0,
+  25, 0, 0, 13, 0, 0, 16, 30, 0, 0,
+  0, 54, 3, 0, 0, 0, 20, 0, 0, 0,
+  0, 0, 62, 11, 0, 38, 13, 0, 89, 23,
+  44, 14, 34, 0, 0, 0, 57, 0, 15, 0,
+  25, 0, 64, 0, 17, 12, 0, 0, 23, 0,
+  0, 6, 16, 72, 0, 0, 0, 19, 42, 0,
+  48, 60, 61, 0, 0, 0, 0, 26, 0, 41,
+  0, 0, 0, 0, 0, 3, 0, 6, 0, 0,
+  0, 0, 0, 69, 18, 17, 0, 65, 0, 0,
+  0, 167, 0, 0, 66, 0, 29, 0, 4, 0,
+  0, 0, 24, 0, 113, 0, 0, 10, 0, 64,
+  0, 4, 0, 0, 0, 0, 0, 0, 0, 0,
+  12, 0, 12, 0, 32, 1, 0, 15, 43, 0,
+  26, 0, 0, 0, 27, 0, 11, 0, 0, 71,
+  39, 0, 0, 0, 13, 0, 0, 24, 30, 0,
+  73, 0, 0, 44, 14, 0, 155, 0, 5, 26,
+  74, 0, 0, 0, 54, 0, 0, 0, 0, 2,
+  46, 0, 14, 18, 11, 0, 12, 0, 0, 11,
+  59, 26, 0, 39, 3, 30, 27, 0, 68, 23,
+  33, 23, 0, 0, 0, 0, 0, 0, 61, 0,
+  0, 0, 0, 7, 0, 8, 0, 25, 64, 32,
+  0, 78, 13, 0, 0, 10, 0, 12, 0, 114,
+  19, 0, 44, 0, 53, 0, 52, 0, 0, 0,
+  0, 20, 19, 0, 0, 11, 0, 0, 0, 19,
+  15, 39, 5, 36, 0, 0, 0, 0, 27, 0,
+  8, 0, 65, 1, 0, 0, 39, 0, 0, 25,
+  36, 0, 0, 17, 0, 0, 33, 36, 0, 0,
+  0, 0, 22, 0, 0, 0, 0, 13, 66, 18,
+  0, 34, 0, 0, 63, 12, 74, 5, 47, 3,
+  0, 0, 82, 14, 12, 0, 5, 0, 69, 0,
+  12, 8, 0, 0, 19, 0, 0, 0, 40, 75,
+  0, 7, 0, 50, 40, 0, 68, 50, 83, 1,
+  0, 0, 0, 31, 0, 3, 20, 0, 0, 0,
+  0, 5, 0, 22, 0, 0, 22, 4, 0, 91,
+  26, 21, 0, 48, 0, 0, 1, 153, 0, 0,
+  66, 0, 33, 0, 18, 0, 0, 0, 11, 0,
+  112, 0, 0, 0, 0, 59, 0, 0, 0, 7,
+  0, 0, 0, 0, 0, 0, 9, 0, 15, 0,
+  36, 8, 0, 0, 45, 0, 0, 0, 0, 0,
+  6, 8, 0, 0, 1, 53, 30, 0, 0, 0,
+  16, 0, 0, 5, 5, 0, 72, 5, 0, 42,
+  10, 0, 150, 0, 30, 25, 71, 0, 0, 0,
+  50, 0, 12, 0, 0, 0, 9, 0, 23, 7,
+  0, 0, 42, 0, 0, 0, 8, 47, 0, 0,
+  0, 0, 32, 0, 34, 11, 0, 18, 0, 0,
+  19, 48, 0, 74, 0, 0, 9, 0, 0, 0,
+  0, 14, 0, 0, 0, 0, 0, 37, 0, 40,
+  0, 86, 0, 0, 8, 140, 13, 21, 34, 0,
+  22, 0, 0, 0, 0, 0, 0, 0, 51, 0,
+  0, 0, 0, 14, 0, 9, 0, 0, 0, 24,
+  0, 0, 0, 11, 28, 0, 0, 0, 0, 0,
+  0, 47, 50, 10, 57, 0, 0, 0, 10, 0,
+  28, 0, 0, 84, 46, 0, 26, 0, 7, 0,
+  21, 14, 59, 0, 50, 0, 0, 36, 7, 0,
+  152, 0, 0, 31, 100, 6, 74, 0, 41, 0,
+  0, 0, 0, 34, 49, 0, 25, 0, 17, 0,
+  0, 0, 0, 0, 29, 51, 2, 46, 15, 40,
+  0, 20, 33, 0, 79, 40, 0, 20, 0, 0,
+  0, 0, 25, 0, 0, 0, 0, 0, 0, 5,
+  0, 35, 63, 42, 0, 75, 56, 0, 0, 0,
+  0, 4, 0, 42, 63, 0, 1, 0, 44, 5,
+  9, 0, 0, 3, 0, 23, 0, 0, 26, 7,
+  0, 0, 0, 3, 4, 30, 12, 34, 0, 8,
+  0, 0, 40, 0, 0, 0, 68, 13, 0, 0,
+  40, 12, 0, 29, 32, 0, 0, 30, 0, 0,
+  0, 46, 0, 0, 0, 0, 5, 0, 0, 0,
+  0, 29, 58, 4, 0, 15, 30, 0, 26, 17,
+  54, 0, 15, 0, 9, 0, 76, 5, 0, 0,
+  10, 0, 77, 0, 9, 10, 0, 0, 4, 0,
+  0, 8, 3, 82, 0, 0, 0, 46, 42, 0,
+  45, 68, 136, 0, 0, 0, 0, 0, 0, 0,
+  3, 0, 0, 0, 0, 9, 0, 0, 0, 0,
+  33, 0, 0, 90, 40, 14, 0, 21, 0, 0,
+  0, 136, 0, 0, 74, 0, 41, 0, 36, 0,
+  0, 0, 35, 0, 125, 0, 0, 23, 0, 91,
+  0, 0, 13, 4, 0, 0, 7, 0, 0, 0,
+  15, 0, 23, 0, 45, 6, 0, 0, 20, 0,
+  0, 0, 0, 0, 24, 27, 0, 0, 0, 52,
+  15, 0, 0, 0, 14, 0, 0, 2, 0, 0,
+  69, 4, 0, 37, 12, 0, 118, 0, 23, 19,
+  24, 0, 0, 0, 53, 0, 0, 0, 0, 0,
+  45, 1, 17, 0, 0, 0, 31, 0, 0, 0,
+  20, 82, 0, 0, 0, 11, 29, 0, 23, 30,
+  25, 5, 0, 0, 20, 43, 0, 53, 0, 0,
+  0, 0, 0, 0, 0, 4, 0, 0, 0, 0,
+  0, 45, 6, 26, 0, 49, 0, 0, 0, 152,
+  0, 16, 45, 0, 12, 0, 0, 0, 0, 0,
+  8, 0, 63, 0, 0, 6, 0, 72, 0, 0,
+  8, 0, 0, 0, 0, 0, 0, 0, 13, 0,
+  1, 0, 0, 0, 0, 44, 53, 0, 44, 0,
+  0, 0, 18, 0, 36, 0, 0, 72, 23, 0,
+  15, 0, 42, 0, 1, 20, 65, 0, 81, 0,
+  0, 14, 40, 0, 141, 0, 0, 33, 89, 0,
+  30, 0, 58, 0, 0, 0, 0, 0, 77, 0,
+  0, 0, 2, 0, 0, 0, 0, 1, 29, 58,
+  0, 41, 0, 69, 29, 7, 59, 19, 117, 17,
+  0, 0, 0, 5, 0, 0, 15, 0, 0, 0,
+  0, 13, 0, 12, 0, 0, 66, 0, 0, 79,
+  32, 0, 0, 0, 0, 6, 0, 87, 7, 0,
+  39, 0, 49, 0, 7, 0, 0, 1, 10, 0,
+  77, 0, 0, 21, 0, 50, 0, 0, 2, 19,
+  0, 7, 0, 0, 0, 0, 19, 0, 2, 0,
+  62, 8, 0, 0, 25, 0, 0, 13, 0, 0,
+  16, 30, 0, 0, 0, 54, 3, 0, 0, 0,
+  20, 0, 0, 0, 0, 0, 62, 11, 0, 38,
+  13, 0, 89, 23, 44, 14, 34, 0, 0, 0,
+  57, 0, 15, 0, 25, 0, 64, 0, 17, 12,
+  0, 0, 23, 0, 0, 6, 16, 72, 0, 0,
+  0, 19, 42, 0, 48, 60, 61, 0, 0, 0,
+  0, 26, 0, 41, 0, 0, 0, 0, 0, 3,
+  0, 6, 0, 0, 0, 0, 0, 69, 18, 17,
+  0, 65, 0, 0, 0, 167, 0, 0, 66, 0,
+  29, 0, 4, 0, 0, 0, 24, 0, 113, 0,
+  0, 10, 0, 64, 0, 4, 0, 0, 0, 0,
+  0, 0, 0, 0, 12, 0, 12, 0, 32, 1,
+  0, 15, 43, 0, 26, 0, 0, 0, 27, 0,
+  11, 0, 0, 71, 39, 0, 0, 0, 13, 0,
+  0, 24, 30, 0, 73, 0, 0, 44, 14, 0,
+  155, 0, 5, 26, 74, 0, 0, 0, 54, 0,
+  0, 0, 0, 0, 0, 0, 12, 0, 0, 14,
+  34, 15, 0, 0, 26, 34, 0, 0, 0, 21,
+  29, 0, 8, 0, 0, 45, 0, 0, 48, 64,
+  6, 83, 0, 0, 55, 0, 0, 0, 0, 1,
+  0, 5, 0, 0, 0, 16, 10, 46, 0, 58,
+  0, 8, 7, 104, 37, 30, 33, 0, 15, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 6, 0,
+  0, 19, 0, 0, 21, 0, 0, 63, 0, 0,
+  0, 9, 39, 0, 0, 13, 0, 0, 0, 59,
+  43, 21, 114, 3, 0, 0, 28, 0, 36, 0,
+  0, 91, 40, 0, 32, 0, 7, 0, 28, 8,
+  75, 20, 37, 0, 0, 8, 5, 0, 131, 0,
+  0, 37, 103, 0, 101, 0, 70, 0, 0, 0,
+  5, 0, 69, 0, 12, 8, 0, 0, 19, 0,
+  0, 0, 40, 75, 0, 7, 0, 50, 40, 0,
+  68, 50, 83, 1, 0, 0, 0, 31, 0, 3,
+  20, 0, 0, 0, 0, 5, 0, 22, 0, 0,
+  22, 4, 0, 91, 26, 21, 0, 48, 0, 0,
+  1, 153, 0, 0, 66, 0, 33, 0, 18, 0,
+  0, 0, 11, 0, 112, 0, 0, 0, 0, 59,
+  0, 0, 0, 7, 0, 0, 0, 0, 0, 0,
+  9, 0, 15, 0, 36, 8, 0, 0, 45, 0,
+  0, 0, 0, 0, 6, 8, 0, 0, 1, 53,
+  30, 0, 0, 0, 16, 0, 0, 5, 5, 0,
+  72, 5, 0, 42, 10, 0, 150, 0, 30, 25,
+  71, 0, 0, 0, 50, 0, 12, 0, 0, 0,
+  9, 0, 23, 7, 0, 0, 42, 0, 0, 0,
+  8, 47, 0, 0, 0, 0, 32, 0, 34, 11,
+  0, 18, 0, 0, 19, 48, 0, 74, 0, 0,
+  9, 0, 0, 0, 0, 14, 0, 0, 0, 0,
+  0, 37, 0, 40, 0, 86, 0, 0, 8, 140,
+  13, 21, 34, 0, 22, 0, 0, 0, 0, 0,
+  0, 0, 51, 0, 0, 0, 0, 14, 0, 9,
+  0, 0, 0, 24, 0, 0, 0, 11, 28, 0,
+  0, 0, 0, 0, 0, 47, 50, 10, 57, 0,
+  0, 0, 10, 0, 28, 0, 0, 84, 46, 0,
+  26, 0, 7, 0, 21, 14, 59, 0, 50, 0,
+  0, 36, 7, 0, 152, 0, 0, 31, 100, 6,
+  74, 0, 41, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 24, 26, 15, 20, 0, 5, 0, 0,
+  4, 23, 15, 29, 19, 5, 0, 0, 0, 56,
+  21, 39, 37, 55, 0, 52, 0, 0, 82, 0,
+  11, 0, 0, 14, 0, 19, 0, 6, 0, 1,
+  10, 45, 30, 46, 0, 40, 24, 27, 55, 43,
+  0, 0, 9, 0, 0, 42, 0, 0, 0, 0,
+  0, 0, 32, 0, 0, 0, 0, 2, 11, 0,
+  20, 67, 0, 0, 0, 27, 69, 0, 0, 21,
+  0, 0, 2, 43, 16, 39, 82, 7, 0, 0,
+  15, 0, 21, 0, 0, 53, 8, 0, 42, 0,
+  0, 0, 48, 0, 67, 45, 15, 0, 2, 4,
+  0, 0, 73, 0, 0, 11, 69, 15, 131, 0,
+  65, 0, 0, 0, 10, 0, 77, 0, 9, 10,
+  0, 0, 4, 0, 0, 8, 3, 82, 0, 0,
+  0, 46, 42, 0, 45, 68, 136, 0, 0, 0,
+  0, 0, 0, 0, 3, 0, 0, 0, 0, 9,
+  0, 0, 0, 0, 33, 0, 0, 90, 40, 14,
+  0, 21, 0, 0, 0, 136, 0, 0, 74, 0,
+  41, 0, 36, 0, 0, 0, 35, 0, 125, 0,
+  0, 23, 0, 91, 0, 0, 13, 4, 0, 0,
+  7, 0, 0, 0, 15, 0, 23, 0, 45, 6,
+  0, 0, 20, 0, 0, 0, 0, 0, 24, 27,
+  0, 0, 0, 52, 15, 0, 0, 0, 14, 0,
+  0, 2, 0, 0, 69, 4, 0, 37, 12, 0,
+  118, 0, 23, 19, 24, 0, 0, 0, 53, 0,
+  0, 0, 0, 0, 45, 1, 17, 0, 0, 0,
+  31, 0, 0, 0, 20, 82, 0, 0, 0, 11,
+  29, 0, 23, 30, 25, 5, 0, 0, 20, 43,
+  0, 53, 0, 0, 0, 0, 0, 0, 0, 4,
+  0, 0, 0, 0, 0, 45, 6, 26, 0, 49,
+  0, 0, 0, 152, 0, 16, 45, 0, 12, 0,
+  0, 0, 0, 0, 8, 0, 63, 0, 0, 6,
+  0, 72, 0, 0, 8, 0, 0, 0, 0, 0,
+  0, 0, 13, 0, 1, 0, 0, 0, 0, 44,
+  53, 0, 44, 0, 0, 0, 18, 0, 36, 0,
+  0, 72, 23, 0, 15, 0, 42, 0, 1, 20,
+  65, 0, 81, 0, 0, 14, 40, 0, 141, 0,
+  0, 33, 89, 0, 30, 0, 58, 0, 0, 0,
+  0, 0, 24, 23, 0, 0, 18, 24, 50, 29,
+  0, 0, 0, 30, 0, 5, 4, 7, 13, 0,
+  0, 0, 0, 53, 0, 0, 74, 59, 173, 47,
+  0, 0, 71, 0, 19, 0, 0, 20, 0, 24,
+  0, 0, 0, 0, 18, 88, 16, 0, 0, 16,
+  0, 67, 30, 34, 32, 0, 0, 4, 0, 6,
+  0, 39, 0, 0, 0, 0, 33, 0, 0, 14,
+  6, 12, 56, 3, 0, 51, 0, 0, 0, 3,
+  39, 0, 0, 33, 0, 0, 0, 48, 80, 41,
+  84, 0, 0, 0, 23, 0, 51, 0, 2, 59,
+  14, 2, 58, 0, 66, 2, 56, 3, 77, 5,
+  38, 0, 11, 0, 0, 0, 103, 0, 0, 17,
+  53, 0, 50, 0, 60, 0, 7, 11, 25, 0,
+  64, 0, 17, 12, 0, 0, 23, 0, 0, 6,
+  16, 72, 0, 0, 0, 19, 42, 0, 48, 60,
+  61, 0, 0, 0, 0, 26, 0, 41, 0, 0,
+  0, 0, 0, 3, 0, 6, 0, 0, 0, 0,
+  0, 69, 18, 17, 0, 65, 0, 0, 0, 167,
+  0, 0, 66, 0, 29, 0, 4, 0, 0, 0,
+  24, 0, 113, 0, 0, 10, 0, 64, 0, 4,
+  0, 0, 0, 0, 0, 0, 0, 0, 12, 0,
+  12, 0, 32, 1, 0, 15, 43, 0, 26, 0,
+  0, 0, 27, 0, 11, 0, 0, 71, 39, 0,
+  0, 0, 13, 0, 0, 24, 30, 0, 73, 0,
+  0, 44, 14, 0, 155, 0, 5, 26, 74, 0,
+  0, 0, 54, 0, 0, 0, 0, 0, 0, 0,
+  12, 0, 0, 14, 34, 15, 0, 0, 26, 34,
+  0, 0, 0, 21, 29, 0, 8, 0, 0, 45,
+  0, 0, 48, 64, 6, 83, 0, 0, 55, 0,
+  0, 0, 0, 1, 0, 5, 0, 0, 0, 16,
+  10, 46, 0, 58, 0, 8, 7, 104, 37, 30,
+  33, 0, 15, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 6, 0, 0, 19, 0, 0, 21, 0,
+  0, 63, 0, 0, 0, 9, 39, 0, 0, 13,
+  0, 0, 0, 59, 43, 21, 114, 3, 0, 0,
+  28, 0, 36, 0, 0, 91, 40, 0, 32, 0,
+  7, 0, 28, 8, 75, 20, 37, 0, 0, 8,
+  5, 0, 131, 0, 0, 37, 103, 0, 101, 0,
+  70, 0, 0, 0, 0, 6, 23, 5, 0, 0,
+  44, 22, 34, 36, 0, 0, 1, 0, 0, 41,
+  20, 23, 3, 8, 0, 0, 0, 69, 18, 19,
+  51, 49, 164, 7, 0, 0, 85, 0, 15, 0,
+  0, 31, 6, 63, 0, 3, 29, 0, 23, 56,
+  20, 0, 0, 47, 0, 43, 48, 47, 7, 0,
+  0, 20, 0, 28, 0, 23, 0, 0, 0, 3,
+  58, 0, 2, 0, 18, 22, 54, 25, 23, 58,
+  0, 0, 0, 13, 76, 0, 7, 17, 0, 0,
+  4, 37, 62, 48, 83, 0, 0, 0, 8, 13,
+  24, 0, 0, 55, 0, 0, 26, 0, 38, 0,
+  56, 0, 44, 17, 29, 0, 10, 0, 0, 0,
+  37, 0, 0, 16, 21, 0, 77, 0, 71, 0,
+  5, 0, 0, 0, 9, 0, 23, 7, 0, 0,
+  42, 0, 0, 0, 8, 47, 0, 0, 0, 0,
+  32, 0, 34, 11, 0, 18, 0, 0, 19, 48,
+  0, 74, 0, 0, 9, 0, 0, 0, 0, 14,
+  0, 0, 0, 0, 0, 37, 0, 40, 0, 86,
+  0, 0, 8, 140, 13, 21, 34, 0, 22, 0,
+  0, 0, 0, 0, 0, 0, 51, 0, 0, 0,
+  0, 14, 0, 9, 0, 0, 0, 24, 0, 0,
+  0, 11, 28, 0, 0, 0, 0, 0, 0, 47,
+  50, 10, 57, 0, 0, 0, 10, 0, 28, 0,
+  0, 84, 46, 0, 26, 0, 7, 0, 21, 14,
+  59, 0, 50, 0, 0, 36, 7, 0, 152, 0,
+  0, 31, 100, 6, 74, 0, 41, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 24, 26, 15, 20,
+  0, 5, 0, 0, 4, 23, 15, 29, 19, 5,
+  0, 0, 0, 56, 21, 39, 37, 55, 0, 52,
+  0, 0, 82, 0, 11, 0, 0, 14, 0, 19,
+  0, 6, 0, 1, 10, 45, 30, 46, 0, 40,
+  24, 27, 55, 43, 0, 0, 9, 0, 0, 42,
+  0, 0, 0, 0, 0, 0, 32, 0, 0, 0,
+  0, 2, 11, 0, 20, 67, 0, 0, 0, 27,
+  69, 0, 0, 21, 0, 0, 2, 43, 16, 39,
+  82, 7, 0, 0, 15, 0, 21, 0, 0, 53,
+  8, 0, 42, 0, 0, 0, 48, 0, 67, 45,
+  15, 0, 2, 4, 0, 0, 73, 0, 0, 11,
+  69, 15, 131, 0, 65, 0, 0, 0, 0, 21,
+  39, 0, 0, 0, 39, 17, 22, 19, 5, 0,
+  0, 0, 20, 45, 30, 23, 5, 22, 0, 0,
+  0, 63, 27, 30, 38, 35, 115, 0, 0, 0,
+  74, 0, 11, 0, 0, 35, 3, 71, 0, 30,
+  31, 0, 4, 24, 50, 0, 0, 63, 18, 33,
+  32, 49, 0, 0, 0, 28, 0, 17, 6, 0,
+  0, 0, 0, 3, 73, 0, 42, 0, 0, 21,
+  39, 30, 32, 29, 0, 11, 0, 17, 87, 0,
+  23, 13, 0, 0, 7, 29, 62, 11, 41, 0,
+  0, 0, 0, 12, 26, 0, 0, 45, 0, 0,
+  5, 0, 19, 0, 45, 0, 16, 20, 23, 0,
+  12, 0, 0, 0, 0, 0, 0, 4, 0, 0,
+  66, 0, 50, 0, 0, 0, 0, 0, 45, 1,
+  17, 0, 0, 0, 31, 0, 0, 0, 20, 82,
+  0, 0, 0, 11, 29, 0, 23, 30, 25, 5,
+  0, 0, 20, 43, 0, 53, 0, 0, 0, 0,
+  0, 0, 0, 4, 0, 0, 0, 0, 0, 45,
+  6, 26, 0, 49, 0, 0, 0, 152, 0, 16,
+  45, 0, 12, 0, 0, 0, 0, 0, 8, 0,
+  63, 0, 0, 6, 0, 72, 0, 0, 8, 0,
+  0, 0, 0, 0, 0, 0, 13, 0, 1, 0,
+  0, 0, 0, 44, 53, 0, 44, 0, 0, 0,
+  18, 0, 36, 0, 0, 72, 23, 0, 15, 0,
+  42, 0, 1, 20, 65, 0, 81, 0, 0, 14,
+  40, 0, 141, 0, 0, 33, 89, 0, 30, 0,
+  58, 0, 0, 0, 0, 0, 24, 23, 0, 0,
+  18, 24, 50, 29, 0, 0, 0, 30, 0, 5,
+  4, 7, 13, 0, 0, 0, 0, 53, 0, 0,
+  74, 59, 173, 47, 0, 0, 71, 0, 19, 0,
+  0, 20, 0, 24, 0, 0, 0, 0, 18, 88,
+  16, 0, 0, 16, 0, 67, 30, 34, 32, 0,
+  0, 4, 0, 6, 0, 39, 0, 0, 0, 0,
+  33, 0, 0, 14, 6, 12, 56, 3, 0, 51,
+  0, 0, 0, 3, 39, 0, 0, 33, 0, 0,
+  0, 48, 80, 41, 84, 0, 0, 0, 23, 0,
+  51, 0, 2, 59, 14, 2, 58, 0, 66, 2,
+  56, 3, 77, 5, 38, 0, 11, 0, 0, 0,
+  103, 0, 0, 17, 53, 0, 50, 0, 60, 0,
+  7, 11, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 12, 0, 0, 14, 34, 15,
+  0, 0, 26, 34, 0, 0, 0, 21, 29, 0,
+  8, 0, 0, 45, 0, 0, 48, 64, 6, 83,
+  0, 0, 55, 0, 0, 0, 0, 1, 0, 5,
+  0, 0, 0, 16, 10, 46, 0, 58, 0, 8,
+  7, 104, 37, 30, 33, 0, 15, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 6, 0, 0, 19,
+  0, 0, 21, 0, 0, 63, 0, 0, 0, 9,
+  39, 0, 0, 13, 0, 0, 0, 59, 43, 21,
+  114, 3, 0, 0, 28, 0, 36, 0, 0, 91,
+  40, 0, 32, 0, 7, 0, 28, 8, 75, 20,
+  37, 0, 0, 8, 5, 0, 131, 0, 0, 37,
+  103, 0, 101, 0, 70, 0, 0, 0, 0, 6,
+  23, 5, 0, 0, 44, 22, 34, 36, 0, 0,
+  1, 0, 0, 41, 20, 23, 3, 8, 0, 0,
+  0, 69, 18, 19, 51, 49, 164, 7, 0, 0,
+  85, 0, 15, 0, 0, 31, 6, 63, 0, 3,
+  29, 0, 23, 56, 20, 0, 0, 47, 0, 43,
+  48, 47, 7, 0, 0, 20, 0, 28, 0, 23,
+  0, 0, 0, 3, 58, 0, 2, 0, 18, 22,
+  54, 25, 23, 58, 0, 0, 0, 13, 76, 0,
+  7, 17, 0, 0, 4, 37, 62, 48, 83, 0,
+  0, 0, 8, 13, 24, 0, 0, 55, 0, 0,
+  26, 0, 38, 0, 56, 0, 44, 17, 29, 0,
+  10, 0, 0, 0, 37, 0, 0, 16, 21, 0,
+  77, 0, 71, 0, 5, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  24, 26, 15, 20, 0, 5, 0, 0, 4, 23,
+  15, 29, 19, 5, 0, 0, 0, 56, 21, 39,
+  37, 55, 0, 52, 0, 0, 82, 0, 11, 0,
+  0, 14, 0, 19, 0, 6, 0, 1, 10, 45,
+  30, 46, 0, 40, 24, 27, 55, 43, 0, 0,
+  9, 0, 0, 42, 0, 0, 0, 0, 0, 0,
+  32, 0, 0, 0, 0, 2, 11, 0, 20, 67,
+  0, 0, 0, 27, 69, 0, 0, 21, 0, 0,
+  2, 43, 16, 39, 82, 7, 0, 0, 15, 0,
+  21, 0, 0, 53, 8, 0, 42, 0, 0, 0,
+  48, 0, 67, 45, 15, 0, 2, 4, 0, 0,
+  73, 0, 0, 11, 69, 15, 131, 0, 65, 0,
+  0, 0, 0, 21, 39, 0, 0, 0, 39, 17,
+  22, 19, 5, 0, 0, 0, 20, 45, 30, 23,
+  5, 22, 0, 0, 0, 63, 27, 30, 38, 35,
+  115, 0, 0, 0, 74, 0, 11, 0, 0, 35,
+  3, 71, 0, 30, 31, 0, 4, 24, 50, 0,
+  0, 63, 18, 33, 32, 49, 0, 0, 0, 28,
+  0, 17, 6, 0, 0, 0, 0, 3, 73, 0,
+  42, 0, 0, 21, 39, 30, 32, 29, 0, 11,
+  0, 17, 87, 0, 23, 13, 0, 0, 7, 29,
+  62, 11, 41, 0, 0, 0, 0, 12, 26, 0,
+  0, 45, 0, 0, 5, 0, 19, 0, 45, 0,
+  16, 20, 23, 0, 12, 0, 0, 0, 0, 0,
+  0, 4, 0, 0, 66, 0, 50, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 74, 43, 0,
+  0, 0, 41, 0, 0, 0, 0, 15, 3, 0,
+  14, 72, 38, 47, 0, 64, 66, 0, 81, 51,
+  0, 26, 10, 14, 118, 35, 2, 0, 62, 0,
+  42, 8, 0, 26, 7, 52, 32, 25, 0, 26,
+  85, 30, 0, 8, 0, 25, 0, 13, 61, 0,
+  0, 0, 25, 0, 4, 20, 16, 0, 7, 0,
+  0, 0, 21, 2, 0, 0, 14, 32, 32, 38,
+  42, 30, 5, 5, 0, 0, 76, 3, 4, 0,
+  0, 15, 0, 0, 64, 23, 0, 0, 7, 0,
+  8, 49, 0, 0, 22, 10, 3, 0, 1, 17,
+  39, 0, 77, 0, 0, 43, 30, 0, 0, 41,
+  0, 0, 0, 3, 0, 15, 30, 0, 0, 0,
+  22, 0, 36, 0, 4, 47, 62, 10, 0, 19,
+  11, 10, 1, 0, 0, 51, 73, 0, 0, 33,
+  47, 24, 0, 20, 69, 64, 93, 12, 0, 0,
+  0, 23, 0, 0, 0, 0, 74, 0, 23, 28,
+  0, 28, 0, 48, 1, 24, 0, 19, 53, 57,
+  0, 57, 0, 37, 0, 54, 25, 0, 42, 0,
+  29, 0, 2, 0, 1, 0, 0, 20, 15, 0,
+  0, 0, 26, 0, 13, 15, 11, 22, 32, 0,
+  46, 51, 0, 12, 44, 0, 35, 0, 0, 8,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 24,
+  31, 0, 40, 41, 11, 0, 10, 24, 51, 0,
+  57, 0, 0, 3, 17, 15, 0, 12, 0, 0,
+  7, 0, 0, 7, 15, 4, 0, 0, 47, 0,
+  18, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 79, 42, 0, 0, 0, 53, 0, 5, 0,
+  0, 37, 2, 1, 18, 62, 41, 51, 0, 55,
+  86, 0, 87, 50, 0, 11, 5, 15, 128, 37,
+  1, 0, 72, 0, 36, 0, 0, 27, 0, 45,
+  39, 32, 0, 35, 80, 55, 0, 7, 0, 21,
+  12, 25, 62, 0, 16, 0, 27, 0, 29, 0,
+  13, 0, 11, 0, 0, 0, 25, 0, 9, 0,
+  3, 35, 41, 39, 37, 34, 23, 0, 0, 8,
+  79, 22, 1, 0, 0, 13, 0, 0, 82, 36,
+  0, 0, 20, 0, 0, 51, 0, 0, 48, 11,
+  5, 0, 0, 23, 29, 0, 77, 0, 0, 50,
+  18, 0, 0, 42, 0, 0, 0, 4, 5, 13,
+  24, 0, 0, 0, 28, 0, 34, 0, 7, 54,
+  57, 12, 0, 23, 17, 14, 2, 0, 0, 54,
+  68, 12, 2, 19, 58, 30, 0, 13, 72, 61,
+  94, 10, 0, 0, 0, 26, 0, 0, 0, 5,
+  68, 0, 20, 19, 0, 31, 0, 50, 4, 41,
+  0, 19, 53, 58, 0, 66, 0, 27, 0, 55,
+  24, 0, 51, 0, 26, 0, 10, 0, 0, 0,
+  0, 18, 3, 0, 0, 0, 34, 0, 14, 26,
+  9, 11, 35, 0, 48, 32, 0, 34, 37, 0,
+  35, 0, 0, 7, 0, 0, 0, 5, 0, 0,
+  0, 0, 0, 28, 25, 0, 59, 36, 0, 0,
+  14, 23, 43, 0, 49, 0, 0, 6, 11, 5,
+  0, 11, 0, 0, 8, 0, 8, 0, 0, 4,
+  5, 0, 45, 0, 20, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 59, 38, 0, 0, 0,
+  51, 10, 0, 0, 0, 39, 16, 14, 0, 31,
+  37, 50, 8, 52, 96, 0, 89, 33, 0, 0,
+  10, 17, 130, 11, 0, 0, 60, 0, 23, 5,
+  0, 27, 0, 39, 18, 30, 0, 52, 72, 74,
+  0, 1, 0, 9, 3, 38, 49, 0, 21, 0,
+  26, 0, 35, 0, 7, 0, 20, 0, 0, 0,
+  28, 0, 11, 0, 19, 32, 48, 45, 30, 15,
+  29, 8, 0, 9, 64, 8, 4, 0, 0, 0,
+  0, 0, 71, 23, 0, 0, 12, 0, 0, 61,
+  0, 0, 46, 11, 0, 0, 7, 26, 31, 0,
+  76, 0, 0, 36, 15, 0, 0, 53, 0, 0,
+  0, 21, 21, 27, 13, 0, 0, 0, 35, 0,
+  35, 0, 5, 41, 42, 14, 0, 10, 22, 17,
+  7, 0, 0, 59, 79, 18, 12, 8, 57, 30,
+  0, 8, 80, 64, 78, 4, 4, 0, 0, 27,
+  0, 0, 0, 6, 69, 0, 21, 17, 0, 41,
+  0, 56, 0, 45, 0, 25, 49, 58, 0, 46,
+  0, 36, 0, 53, 24, 7, 45, 0, 22, 0,
+  8, 0, 0, 0, 0, 27, 0, 6, 0, 0,
+  31, 0, 5, 23, 14, 9, 30, 0, 48, 35,
+  0, 35, 39, 0, 24, 0, 2, 0, 0, 0,
+  0, 6, 0, 0, 0, 3, 0, 41, 26, 0,
+  61, 31, 0, 0, 30, 12, 49, 0, 50, 0,
+  0, 4, 7, 3, 0, 14, 0, 0, 14, 0,
+  21, 1, 1, 11, 20, 0, 59, 0, 36, 0,
+  0, 74, 43, 0, 0, 0, 41, 0, 0, 0,
+  0, 15, 3, 0, 14, 72, 38, 47, 0, 64,
+  66, 0, 81, 51, 0, 26, 10, 14, 118, 35,
+  2, 0, 62, 0, 42, 8, 0, 26, 7, 52,
+  32, 25, 0, 26, 85, 30, 0, 8, 0, 25,
+  0, 13, 61, 0, 0, 0, 25, 0, 4, 20,
+  16, 0, 7, 0, 0, 0, 21, 2, 0, 0,
+  14, 32, 32, 38, 42, 30, 5, 5, 0, 0,
+  76, 3, 4, 0, 0, 15, 0, 0, 64, 23,
+  0, 0, 7, 0, 8, 49, 0, 0, 22, 10,
+  3, 0, 1, 17, 39, 0, 77, 0, 0, 43,
+  30, 0, 0, 41, 0, 0, 0, 3, 0, 15,
+  30, 0, 0, 0, 22, 0, 36, 0, 4, 47,
+  62, 10, 0, 19, 11, 10, 1, 0, 0, 51,
+  73, 0, 0, 33, 47, 24, 0, 20, 69, 64,
+  93, 12, 0, 0, 0, 23, 0, 0, 0, 0,
+  74, 0, 23, 28, 0, 28, 0, 48, 1, 24,
+  0, 19, 53, 57, 0, 57, 0, 37, 0, 54,
+  25, 0, 42, 0, 29, 0, 2, 0, 1, 0,
+  0, 20, 15, 0, 0, 0, 26, 0, 13, 15,
+  11, 22, 32, 0, 46, 51, 0, 12, 44, 0,
+  35, 0, 0, 8, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 24, 31, 0, 40, 41, 11, 0,
+  10, 24, 51, 0, 57, 0, 0, 3, 17, 15,
+  0, 12, 0, 0, 7, 0, 0, 7, 15, 4,
+  0, 0, 47, 0, 18, 0, 3, 30, 27, 20,
+  0, 12, 23, 23, 27, 0, 0, 40, 83, 0,
+  11, 31, 57, 0, 0, 0, 0, 92, 0, 1,
+  37, 0, 0, 25, 0, 0, 0, 50, 77, 0,
+  34, 0, 0, 19, 0, 54, 0, 46, 24, 10,
+  34, 52, 12, 15, 0, 33, 0, 55, 12, 26,
+  53, 0, 30, 0, 10, 0, 0, 13, 0, 58,
+  0, 13, 0, 0, 32, 0, 13, 16, 12, 11,
+  0, 0, 49, 39, 0, 32, 30, 0, 50, 41,
+  0, 0, 7, 0, 0, 13, 0, 0, 0, 16,
+  0, 30, 52, 0, 6, 80, 2, 0, 18, 20,
+  43, 0, 29, 0, 4, 0, 21, 11, 0, 0,
+  0, 0, 0, 0, 0, 11, 4, 11, 36, 0,
+  51, 0, 18, 0, 0, 79, 42, 0, 0, 0,
+  53, 0, 5, 0, 0, 37, 2, 1, 18, 62,
+  41, 51, 0, 55, 86, 0, 87, 50, 0, 11,
+  5, 15, 128, 37, 1, 0, 72, 0, 36, 0,
+  0, 27, 0, 45, 39, 32, 0, 35, 80, 55,
+  0, 7, 0, 21, 12, 25, 62, 0, 16, 0,
+  27, 0, 29, 0, 13, 0, 11, 0, 0, 0,
+  25, 0, 9, 0, 3, 35, 41, 39, 37, 34,
+  23, 0, 0, 8, 79, 22, 1, 0, 0, 13,
+  0, 0, 82, 36, 0, 0, 20, 0, 0, 51,
+  0, 0, 48, 11, 5, 0, 0, 23, 29, 0,
+  77, 0, 0, 50, 18, 0, 0, 42, 0, 0,
+  0, 4, 5, 13, 24, 0, 0, 0, 28, 0,
+  34, 0, 7, 54, 57, 12, 0, 23, 17, 14,
+  2, 0, 0, 54, 68, 12, 2, 19, 58, 30,
+  0, 13, 72, 61, 94, 10, 0, 0, 0, 26,
+  0, 0, 0, 5, 68, 0, 20, 19, 0, 31,
+  0, 50, 4, 41, 0, 19, 53, 58, 0, 66,
+  0, 27, 0, 55, 24, 0, 51, 0, 26, 0,
+  10, 0, 0, 0, 0, 18, 3, 0, 0, 0,
+  34, 0, 14, 26, 9, 11, 35, 0, 48, 32,
+  0, 34, 37, 0, 35, 0, 0, 7, 0, 0,
+  0, 5, 0, 0, 0, 0, 0, 28, 25, 0,
+  59, 36, 0, 0, 14, 23, 43, 0, 49, 0,
+  0, 6, 11, 5, 0, 11, 0, 0, 8, 0,
+  8, 0, 0, 4, 5, 0, 45, 0, 20, 0,
+  10, 27, 29, 24, 0, 21, 22, 22, 24, 0,
+  0, 43, 79, 0, 6, 26, 56, 0, 0, 0,
+  0, 87, 1, 0, 41, 0, 0, 30, 0, 1,
+  0, 60, 72, 0, 24, 0, 0, 23, 0, 54,
+  0, 47, 13, 10, 23, 49, 26, 18, 0, 30,
+  0, 52, 4, 24, 54, 0, 32, 0, 10, 0,
+  1, 11, 0, 48, 0, 8, 0, 0, 39, 0,
+  18, 26, 11, 0, 0, 2, 47, 27, 0, 46,
+  24, 0, 46, 46, 0, 0, 13, 0, 0, 18,
+  0, 0, 0, 23, 0, 24, 55, 0, 15, 78,
+  0, 0, 25, 19, 40, 0, 26, 0, 5, 0,
+  17, 8, 0, 0, 0, 0, 7, 0, 0, 4,
+  0, 11, 36, 0, 55, 0, 17, 0, 0, 59,
+  38, 0, 0, 0, 51, 10, 0, 0, 0, 39,
+  16, 14, 0, 31, 37, 50, 8, 52, 96, 0,
+  89, 33, 0, 0, 10, 17, 130, 11, 0, 0,
+  60, 0, 23, 5, 0, 27, 0, 39, 18, 30,
+  0, 52, 72, 74, 0, 1, 0, 9, 3, 38,
+  49, 0, 21, 0, 26, 0, 35, 0, 7, 0,
+  20, 0, 0, 0, 28, 0, 11, 0, 19, 32,
+  48, 45, 30, 15, 29, 8, 0, 9, 64, 8,
+  4, 0, 0, 0, 0, 0, 71, 23, 0, 0,
+  12, 0, 0, 61, 0, 0, 46, 11, 0, 0,
+  7, 26, 31, 0, 76, 0, 0, 36, 15, 0,
+  0, 53, 0, 0, 0, 21, 21, 27, 13, 0,
+  0, 0, 35, 0, 35, 0, 5, 41, 42, 14,
+  0, 10, 22, 17, 7, 0, 0, 59, 79, 18,
+  12, 8, 57, 30, 0, 8, 80, 64, 78, 4,
+  4, 0, 0, 27, 0, 0, 0, 6, 69, 0,
+  21, 17, 0, 41, 0, 56, 0, 45, 0, 25,
+  49, 58, 0, 46, 0, 36, 0, 53, 24, 7,
+  45, 0, 22, 0, 8, 0, 0, 0, 0, 27,
+  0, 6, 0, 0, 31, 0, 5, 23, 14, 9,
+  30, 0, 48, 35, 0, 35, 39, 0, 24, 0,
+  2, 0, 0, 0, 0, 6, 0, 0, 0, 3,
+  0, 41, 26, 0, 61, 31, 0, 0, 30, 12,
+  49, 0, 50, 0, 0, 4, 7, 3, 0, 14,
+  0, 0, 14, 0, 21, 1, 1, 11, 20, 0,
+  59, 0, 36, 0, 7, 20, 30, 33, 0, 25,
+  20, 19, 31, 0, 0, 42, 85, 0, 9, 30,
+  51, 0, 0, 0, 0, 86, 1, 3, 48, 0,
+  0, 38, 0, 0, 0, 59, 74, 0, 25, 0,
+  0, 26, 0, 62, 0, 45, 16, 10, 25, 48,
+  31, 10, 0, 42, 0, 48, 3, 27, 52, 0,
+  29, 0, 9, 0, 0, 10, 0, 42, 0, 8,
+  0, 0, 37, 0, 14, 27, 13, 0, 0, 2,
+  45, 38, 0, 45, 25, 0, 49, 45, 0, 0,
+  20, 0, 0, 19, 0, 0, 0, 17, 0, 27,
+  57, 0, 16, 73, 0, 0, 26, 12, 40, 0,
+  28, 0, 0, 0, 14, 3, 0, 0, 0, 0,
+  11, 0, 0, 9, 2, 6, 37, 0, 65, 0,
+  15, 0, 4, 47, 62, 10, 0, 19, 11, 10,
+  1, 0, 0, 51, 73, 0, 0, 33, 47, 24,
+  0, 20, 69, 64, 93, 12, 0, 0, 0, 23,
+  0, 0, 0, 0, 74, 0, 23, 28, 0, 28,
+  0, 48, 1, 24, 0, 19, 53, 57, 0, 57,
+  0, 37, 0, 54, 25, 0, 42, 0, 29, 0,
+  2, 0, 1, 0, 0, 20, 15, 0, 0, 0,
+  26, 0, 13, 15, 11, 22, 32, 0, 46, 51,
+  0, 12, 44, 0, 35, 0, 0, 8, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 24, 31, 0,
+  40, 41, 11, 0, 10, 24, 51, 0, 57, 0,
+  0, 3, 17, 15, 0, 12, 0, 0, 7, 0,
+  0, 7, 15, 4, 0, 0, 47, 0, 18, 0,
+  3, 30, 27, 20, 0, 12, 23, 23, 27, 0,
+  0, 40, 83, 0, 11, 31, 57, 0, 0, 0,
+  0, 92, 0, 1, 37, 0, 0, 25, 0, 0,
+  0, 50, 77, 0, 34, 0, 0, 19, 0, 54,
+  0, 46, 24, 10, 34, 52, 12, 15, 0, 33,
+  0, 55, 12, 26, 53, 0, 30, 0, 10, 0,
+  0, 13, 0, 58, 0, 13, 0, 0, 32, 0,
+  13, 16, 12, 11, 0, 0, 49, 39, 0, 32,
+  30, 0, 50, 41, 0, 0, 7, 0, 0, 13,
+  0, 0, 0, 16, 0, 30, 52, 0, 6, 80,
+  2, 0, 18, 20, 43, 0, 29, 0, 4, 0,
+  21, 11, 0, 0, 0, 0, 0, 0, 0, 11,
+  4, 11, 36, 0, 51, 0, 18, 0, 0, 0,
+  0, 5, 0, 140, 8, 5, 3, 0, 0, 23,
+  36, 0, 0, 10, 2, 0, 0, 0, 35, 102,
+  17, 9, 0, 0, 0, 0, 0, 21, 0, 23,
+  35, 21, 4, 1, 0, 25, 0, 41, 0, 16,
+  0, 48, 13, 84, 13, 57, 0, 3, 0, 61,
+  0, 0, 24, 0, 45, 0, 39, 0, 0, 51,
+  0, 0, 78, 3, 0, 20, 24, 0, 67, 6,
+  31, 2, 0, 19, 16, 27, 0, 18, 39, 0,
+  33, 59, 0, 0, 10, 0, 0, 0, 0, 8,
+  0, 0, 12, 34, 0, 0, 0, 66, 43, 0,
+  0, 31, 31, 0, 26, 0, 0, 0, 14, 0,
+  0, 24, 0, 0, 117, 2, 21, 20, 0, 0,
+  0, 0, 24, 0, 0, 0, 7, 54, 57, 12,
+  0, 23, 17, 14, 2, 0, 0, 54, 68, 12,
+  2, 19, 58, 30, 0, 13, 72, 61, 94, 10,
+  0, 0, 0, 26, 0, 0, 0, 5, 68, 0,
+  20, 19, 0, 31, 0, 50, 4, 41, 0, 19,
+  53, 58, 0, 66, 0, 27, 0, 55, 24, 0,
+  51, 0, 26, 0, 10, 0, 0, 0, 0, 18,
+  3, 0, 0, 0, 34, 0, 14, 26, 9, 11,
+  35, 0, 48, 32, 0, 34, 37, 0, 35, 0,
+  0, 7, 0, 0, 0, 5, 0, 0, 0, 0,
+  0, 28, 25, 0, 59, 36, 0, 0, 14, 23,
+  43, 0, 49, 0, 0, 6, 11, 5, 0, 11,
+  0, 0, 8, 0, 8, 0, 0, 4, 5, 0,
+  45, 0, 20, 0, 10, 27, 29, 24, 0, 21,
+  22, 22, 24, 0, 0, 43, 79, 0, 6, 26,
+  56, 0, 0, 0, 0, 87, 1, 0, 41, 0,
+  0, 30, 0, 1, 0, 60, 72, 0, 24, 0,
+  0, 23, 0, 54, 0, 47, 13, 10, 23, 49,
+  26, 18, 0, 30, 0, 52, 4, 24, 54, 0,
+  32, 0, 10, 0, 1, 11, 0, 48, 0, 8,
+  0, 0, 39, 0, 18, 26, 11, 0, 0, 2,
+  47, 27, 0, 46, 24, 0, 46, 46, 0, 0,
+  13, 0, 0, 18, 0, 0, 0, 23, 0, 24,
+  55, 0, 15, 78, 0, 0, 25, 19, 40, 0,
+  26, 0, 5, 0, 17, 8, 0, 0, 0, 0,
+  7, 0, 0, 4, 0, 11, 36, 0, 55, 0,
+  17, 0, 0, 0, 0, 7, 0, 153, 0, 0,
+  0, 0, 0, 29, 38, 0, 0, 1, 3, 0,
+  0, 0, 24, 93, 13, 16, 0, 0, 0, 0,
+  0, 19, 0, 24, 31, 29, 0, 8, 0, 29,
+  0, 45, 0, 25, 0, 49, 3, 74, 23, 63,
+  0, 7, 0, 55, 0, 0, 19, 0, 43, 0,
+  36, 0, 0, 49, 0, 0, 76, 0, 0, 27,
+  37, 0, 74, 15, 23, 0, 0, 20, 11, 20,
+  0, 34, 35, 0, 40, 53, 0, 0, 16, 0,
+  0, 0, 0, 13, 0, 0, 26, 27, 0, 0,
+  0, 73, 26, 0, 0, 26, 12, 0, 22, 0,
+  0, 0, 6, 0, 0, 16, 0, 0, 114, 0,
+  19, 9, 0, 0, 0, 0, 29, 0, 0, 0,
+  5, 41, 42, 14, 0, 10, 22, 17, 7, 0,
+  0, 59, 79, 18, 12, 8, 57, 30, 0, 8,
+  80, 64, 78, 4, 4, 0, 0, 27, 0, 0,
+  0, 6, 69, 0, 21, 17, 0, 41, 0, 56,
+  0, 45, 0, 25, 49, 58, 0, 46, 0, 36,
+  0, 53, 24, 7, 45, 0, 22, 0, 8, 0,
+  0, 0, 0, 27, 0, 6, 0, 0, 31, 0,
+  5, 23, 14, 9, 30, 0, 48, 35, 0, 35,
+  39, 0, 24, 0, 2, 0, 0, 0, 0, 6,
+  0, 0, 0, 3, 0, 41, 26, 0, 61, 31,
+  0, 0, 30, 12, 49, 0, 50, 0, 0, 4,
+  7, 3, 0, 14, 0, 0, 14, 0, 21, 1,
+  1, 11, 20, 0, 59, 0, 36, 0, 7, 20,
+  30, 33, 0, 25, 20, 19, 31, 0, 0, 42,
+  85, 0, 9, 30, 51, 0, 0, 0, 0, 86,
+  1, 3, 48, 0, 0, 38, 0, 0, 0, 59,
+  74, 0, 25, 0, 0, 26, 0, 62, 0, 45,
+  16, 10, 25, 48, 31, 10, 0, 42, 0, 48,
+  3, 27, 52, 0, 29, 0, 9, 0, 0, 10,
+  0, 42, 0, 8, 0, 0, 37, 0, 14, 27,
+  13, 0, 0, 2, 45, 38, 0, 45, 25, 0,
+  49, 45, 0, 0, 20, 0, 0, 19, 0, 0,
+  0, 17, 0, 27, 57, 0, 16, 73, 0, 0,
+  26, 12, 40, 0, 28, 0, 0, 0, 14, 3,
+  0, 0, 0, 0, 11, 0, 0, 9, 2, 6,
+  37, 0, 65, 0, 15, 0, 0, 0, 0, 14,
+  0, 156, 0, 0, 5, 0, 0, 33, 46, 0,
+  0, 1, 2, 0, 0, 0, 35, 87, 15, 22,
+  9, 0, 0, 0, 0, 4, 0, 26, 27, 34,
+  0, 10, 0, 25, 0, 45, 0, 20, 0, 52,
+  5, 80, 36, 57, 0, 13, 0, 53, 0, 0,
+  18, 0, 38, 0, 42, 0, 0, 46, 0, 0,
+  78, 0, 0, 21, 42, 0, 77, 17, 26, 0,
+  0, 15, 17, 17, 0, 33, 33, 0, 40, 55,
+  0, 0, 30, 0, 0, 0, 0, 21, 0, 0,
+  19, 31, 0, 0, 3, 65, 28, 0, 0, 21,
+  9, 0, 22, 0, 0, 0, 0, 0, 0, 12,
+  0, 0, 106, 0, 25, 11, 0, 0, 0, 0,
+  36, 0, 0, 0, 3, 30, 27, 20, 0, 12,
+  23, 23, 27, 0, 0, 40, 83, 0, 11, 31,
+  57, 0, 0, 0, 0, 92, 0, 1, 37, 0,
+  0, 25, 0, 0, 0, 50, 77, 0, 34, 0,
+  0, 19, 0, 54, 0, 46, 24, 10, 34, 52,
+  12, 15, 0, 33, 0, 55, 12, 26, 53, 0,
+  30, 0, 10, 0, 0, 13, 0, 58, 0, 13,
+  0, 0, 32, 0, 13, 16, 12, 11, 0, 0,
+  49, 39, 0, 32, 30, 0, 50, 41, 0, 0,
+  7, 0, 0, 13, 0, 0, 0, 16, 0, 30,
+  52, 0, 6, 80, 2, 0, 18, 20, 43, 0,
+  29, 0, 4, 0, 21, 11, 0, 0, 0, 0,
+  0, 0, 0, 11, 4, 11, 36, 0, 51, 0,
+  18, 0, 0, 0, 0, 5, 0, 140, 8, 5,
+  3, 0, 0, 23, 36, 0, 0, 10, 2, 0,
+  0, 0, 35, 102, 17, 9, 0, 0, 0, 0,
+  0, 21, 0, 23, 35, 21, 4, 1, 0, 25,
+  0, 41, 0, 16, 0, 48, 13, 84, 13, 57,
+  0, 3, 0, 61, 0, 0, 24, 0, 45, 0,
+  39, 0, 0, 51, 0, 0, 78, 3, 0, 20,
+  24, 0, 67, 6, 31, 2, 0, 19, 16, 27,
+  0, 18, 39, 0, 33, 59, 0, 0, 10, 0,
+  0, 0, 0, 8, 0, 0, 12, 34, 0, 0,
+  0, 66, 43, 0, 0, 31, 31, 0, 26, 0,
+  0, 0, 14, 0, 0, 24, 0, 0, 117, 2,
+  21, 20, 0, 0, 0, 0, 24, 0, 0, 0,
+  0, 8, 0, 0, 0, 26, 43, 6, 20, 0,
+  13, 0, 59, 0, 10, 62, 36, 31, 3, 0,
+  46, 0, 0, 38, 0, 42, 6, 2, 0, 34,
+  0, 0, 63, 41, 15, 0, 0, 0, 0, 46,
+  0, 37, 0, 53, 25, 14, 17, 17, 0, 32,
+  15, 5, 91, 14, 0, 0, 28, 0, 0, 70,
+  0, 0, 0, 0, 0, 0, 24, 8, 0, 0,
+  0, 2, 0, 9, 17, 48, 0, 3, 0, 31,
+  71, 5, 13, 36, 17, 0, 4, 23, 26, 35,
+  36, 0, 0, 2, 17, 32, 0, 0, 2, 44,
+  36, 0, 0, 0, 12, 0, 55, 13, 24, 46,
+  43, 0, 0, 24, 0, 0, 42, 41, 44, 0,
+  0, 0, 108, 0, 71, 14, 0, 0, 10, 27,
+  29, 24, 0, 21, 22, 22, 24, 0, 0, 43,
+  79, 0, 6, 26, 56, 0, 0, 0, 0, 87,
+  1, 0, 41, 0, 0, 30, 0, 1, 0, 60,
+  72, 0, 24, 0, 0, 23, 0, 54, 0, 47,
+  13, 10, 23, 49, 26, 18, 0, 30, 0, 52,
+  4, 24, 54, 0, 32, 0, 10, 0, 1, 11,
+  0, 48, 0, 8, 0, 0, 39, 0, 18, 26,
+  11, 0, 0, 2, 47, 27, 0, 46, 24, 0,
+  46, 46, 0, 0, 13, 0, 0, 18, 0, 0,
+  0, 23, 0, 24, 55, 0, 15, 78, 0, 0,
+  25, 19, 40, 0, 26, 0, 5, 0, 17, 8,
+  0, 0, 0, 0, 7, 0, 0, 4, 0, 11,
+  36, 0, 55, 0, 17, 0, 0, 0, 0, 7,
+  0, 153, 0, 0, 0, 0, 0, 29, 38, 0,
+  0, 1, 3, 0, 0, 0, 24, 93, 13, 16,
+  0, 0, 0, 0, 0, 19, 0, 24, 31, 29,
+  0, 8, 0, 29, 0, 45, 0, 25, 0, 49,
+  3, 74, 23, 63, 0, 7, 0, 55, 0, 0,
+  19, 0, 43, 0, 36, 0, 0, 49, 0, 0,
+  76, 0, 0, 27, 37, 0, 74, 15, 23, 0,
+  0, 20, 11, 20, 0, 34, 35, 0, 40, 53,
+  0, 0, 16, 0, 0, 0, 0, 13, 0, 0,
+  26, 27, 0, 0, 0, 73, 26, 0, 0, 26,
+  12, 0, 22, 0, 0, 0, 6, 0, 0, 16,
+  0, 0, 114, 0, 19, 9, 0, 0, 0, 0,
+  29, 0, 0, 0, 0, 17, 0, 0, 0, 31,
+  35, 0, 13, 0, 8, 0, 56, 4, 16, 62,
+  36, 39, 10, 0, 30, 0, 0, 48, 4, 53,
+  0, 4, 0, 15, 0, 0, 72, 44, 0, 0,
+  0, 0, 0, 66, 0, 41, 0, 43, 20, 12,
+  12, 36, 0, 41, 0, 7, 95, 16, 0, 0,
+  21, 0, 0, 55, 9, 0, 0, 0, 0, 0,
+  32, 12, 11, 0, 0, 0, 0, 15, 10, 55,
+  0, 0, 0, 47, 64, 4, 32, 22, 15, 0,
+  7, 27, 13, 34, 54, 16, 0, 11, 39, 32,
+  0, 0, 0, 68, 22, 0, 0, 0, 0, 0,
+  48, 0, 0, 30, 26, 15, 0, 27, 0, 0,
+  25, 30, 24, 3, 1, 0, 121, 0, 65, 2,
+  0, 0, 7, 20, 30, 33, 0, 25, 20, 19,
+  31, 0, 0, 42, 85, 0, 9, 30, 51, 0,
+  0, 0, 0, 86, 1, 3, 48, 0, 0, 38,
+  0, 0, 0, 59, 74, 0, 25, 0, 0, 26,
+  0, 62, 0, 45, 16, 10, 25, 48, 31, 10,
+  0, 42, 0, 48, 3, 27, 52, 0, 29, 0,
+  9, 0, 0, 10, 0, 42, 0, 8, 0, 0,
+  37, 0, 14, 27, 13, 0, 0, 2, 45, 38,
+  0, 45, 25, 0, 49, 45, 0, 0, 20, 0,
+  0, 19, 0, 0, 0, 17, 0, 27, 57, 0,
+  16, 73, 0, 0, 26, 12, 40, 0, 28, 0,
+  0, 0, 14, 3, 0, 0, 0, 0, 11, 0,
+  0, 9, 2, 6, 37, 0, 65, 0, 15, 0,
+  0, 0, 0, 14, 0, 156, 0, 0, 5, 0,
+  0, 33, 46, 0, 0, 1, 2, 0, 0, 0,
+  35, 87, 15, 22, 9, 0, 0, 0, 0, 4,
+  0, 26, 27, 34, 0, 10, 0, 25, 0, 45,
+  0, 20, 0, 52, 5, 80, 36, 57, 0, 13,
+  0, 53, 0, 0, 18, 0, 38, 0, 42, 0,
+  0, 46, 0, 0, 78, 0, 0, 21, 42, 0,
+  77, 17, 26, 0, 0, 15, 17, 17, 0, 33,
+  33, 0, 40, 55, 0, 0, 30, 0, 0, 0,
+  0, 21, 0, 0, 19, 31, 0, 0, 3, 65,
+  28, 0, 0, 21, 9, 0, 22, 0, 0, 0,
+  0, 0, 0, 12, 0, 0, 106, 0, 25, 11,
+  0, 0, 0, 0, 36, 0, 0, 0, 0, 20,
+  0, 0, 0, 35, 28, 0, 25, 0, 6, 0,
+  68, 1, 9, 53, 37, 38, 8, 0, 43, 0,
+  0, 43, 7, 56, 0, 4, 0, 13, 10, 0,
+  65, 53, 0, 0, 0, 0, 0, 56, 0, 63,
+  0, 42, 23, 10, 1, 49, 0, 48, 0, 7,
+  80, 24, 0, 0, 14, 0, 0, 62, 18, 0,
+  0, 0, 0, 0, 30, 19, 15, 0, 0, 0,
+  0, 17, 1, 53, 0, 0, 0, 49, 63, 0,
+  24, 24, 20, 0, 11, 25, 0, 37, 36, 32,
+  0, 13, 32, 35, 0, 0, 0, 66, 17, 0,
+  0, 0, 0, 0, 37, 0, 0, 36, 37, 19,
+  0, 29, 0, 0, 14, 20, 42, 8, 3, 0,
+  121, 0, 63, 0, 10, 0, 0, 0, 0, 5,
+  0, 140, 8, 5, 3, 0, 0, 23, 36, 0,
+  0, 10, 2, 0, 0, 0, 35, 102, 17, 9,
+  0, 0, 0, 0, 0, 21, 0, 23, 35, 21,
+  4, 1, 0, 25, 0, 41, 0, 16, 0, 48,
+  13, 84, 13, 57, 0, 3, 0, 61, 0, 0,
+  24, 0, 45, 0, 39, 0, 0, 51, 0, 0,
+  78, 3, 0, 20, 24, 0, 67, 6, 31, 2,
+  0, 19, 16, 27, 0, 18, 39, 0, 33, 59,
+  0, 0, 10, 0, 0, 0, 0, 8, 0, 0,
+  12, 34, 0, 0, 0, 66, 43, 0, 0, 31,
+  31, 0, 26, 0, 0, 0, 14, 0, 0, 24,
+  0, 0, 117, 2, 21, 20, 0, 0, 0, 0,
+  24, 0, 0, 0, 0, 8, 0, 0, 0, 26,
+  43, 6, 20, 0, 13, 0, 59, 0, 10, 62,
+  36, 31, 3, 0, 46, 0, 0, 38, 0, 42,
+  6, 2, 0, 34, 0, 0, 63, 41, 15, 0,
+  0, 0, 0, 46, 0, 37, 0, 53, 25, 14,
+  17, 17, 0, 32, 15, 5, 91, 14, 0, 0,
+  28, 0, 0, 70, 0, 0, 0, 0, 0, 0,
+  24, 8, 0, 0, 0, 2, 0, 9, 17, 48,
+  0, 3, 0, 31, 71, 5, 13, 36, 17, 0,
+  4, 23, 26, 35, 36, 0, 0, 2, 17, 32,
+  0, 0, 2, 44, 36, 0, 0, 0, 12, 0,
+  55, 13, 24, 46, 43, 0, 0, 24, 0, 0,
+  42, 41, 44, 0, 0, 0, 108, 0, 71, 14,
+  0, 0, 0, 44, 70, 0, 0, 0, 0, 9,
+  53, 0, 0, 29, 11, 20, 0, 36, 26, 0,
+  0, 0, 0, 7, 73, 51, 0, 0, 16, 18,
+  0, 0, 0, 0, 0, 0, 29, 22, 0, 0,
+  0, 40, 0, 13, 0, 10, 0, 1, 22, 0,
+  0, 0, 35, 32, 22, 15, 0, 0, 28, 0,
+  0, 0, 0, 0, 0, 0, 20, 0, 30, 0,
+  2, 0, 0, 8, 3, 20, 33, 0, 0, 85,
+  0, 28, 19, 0, 42, 48, 0, 18, 0, 36,
+  33, 9, 46, 0, 0, 0, 8, 0, 0, 0,
+  0, 81, 37, 0, 0, 0, 25, 0, 70, 0,
+  22, 26, 14, 0, 0, 8, 0, 0, 28, 0,
+  0, 18, 0, 0, 19, 0, 44, 20, 0, 20,
+  0, 0, 0, 7, 0, 153, 0, 0, 0, 0,
+  0, 29, 38, 0, 0, 1, 3, 0, 0, 0,
+  24, 93, 13, 16, 0, 0, 0, 0, 0, 19,
+  0, 24, 31, 29, 0, 8, 0, 29, 0, 45,
+  0, 25, 0, 49, 3, 74, 23, 63, 0, 7,
+  0, 55, 0, 0, 19, 0, 43, 0, 36, 0,
+  0, 49, 0, 0, 76, 0, 0, 27, 37, 0,
+  74, 15, 23, 0, 0, 20, 11, 20, 0, 34,
+  35, 0, 40, 53, 0, 0, 16, 0, 0, 0,
+  0, 13, 0, 0, 26, 27, 0, 0, 0, 73,
+  26, 0, 0, 26, 12, 0, 22, 0, 0, 0,
+  6, 0, 0, 16, 0, 0, 114, 0, 19, 9,
+  0, 0, 0, 0, 29, 0, 0, 0, 0, 17,
+  0, 0, 0, 31, 35, 0, 13, 0, 8, 0,
+  56, 4, 16, 62, 36, 39, 10, 0, 30, 0,
+  0, 48, 4, 53, 0, 4, 0, 15, 0, 0,
+  72, 44, 0, 0, 0, 0, 0, 66, 0, 41,
+  0, 43, 20, 12, 12, 36, 0, 41, 0, 7,
+  95, 16, 0, 0, 21, 0, 0, 55, 9, 0,
+  0, 0, 0, 0, 32, 12, 11, 0, 0, 0,
+  0, 15, 10, 55, 0, 0, 0, 47, 64, 4,
+  32, 22, 15, 0, 7, 27, 13, 34, 54, 16,
+  0, 11, 39, 32, 0, 0, 0, 68, 22, 0,
+  0, 0, 0, 0, 48, 0, 0, 30, 26, 15,
+  0, 27, 0, 0, 25, 30, 24, 3, 1, 0,
+  121, 0, 65, 2, 0, 0, 0, 31, 59, 0,
+  8, 0, 0, 0, 53, 2, 0, 9, 30, 0,
+  0, 23, 15, 0, 8, 0, 0, 47, 79, 53,
+  0, 0, 0, 15, 0, 0, 0, 0, 0, 0,
+  52, 28, 0, 4, 0, 63, 0, 25, 0, 1,
+  0, 0, 25, 4, 0, 6, 0, 48, 20, 26,
+  0, 0, 19, 0, 8, 0, 0, 13, 0, 0,
+  18, 0, 16, 0, 9, 0, 10, 19, 20, 21,
+  21, 5, 0, 89, 0, 46, 12, 0, 50, 44,
+  4, 2, 0, 39, 7, 1, 49, 0, 0, 0,
+  4, 0, 0, 0, 6, 91, 22, 0, 0, 0,
+  9, 0, 71, 0, 0, 9, 0, 0, 0, 14,
+  0, 0, 23, 0, 0, 33, 0, 0, 26, 0,
+  73, 2, 0, 1, 0, 0, 0, 14, 0, 156,
+  0, 0, 5, 0, 0, 33, 46, 0, 0, 1,
+  2, 0, 0, 0, 35, 87, 15, 22, 9, 0,
+  0, 0, 0, 4, 0, 26, 27, 34, 0, 10,
+  0, 25, 0, 45, 0, 20, 0, 52, 5, 80,
+  36, 57, 0, 13, 0, 53, 0, 0, 18, 0,
+  38, 0, 42, 0, 0, 46, 0, 0, 78, 0,
+  0, 21, 42, 0, 77, 17, 26, 0, 0, 15,
+  17, 17, 0, 33, 33, 0, 40, 55, 0, 0,
+  30, 0, 0, 0, 0, 21, 0, 0, 19, 31,
+  0, 0, 3, 65, 28, 0, 0, 21, 9, 0,
+  22, 0, 0, 0, 0, 0, 0, 12, 0, 0,
+  106, 0, 25, 11, 0, 0, 0, 0, 36, 0,
+  0, 0, 0, 20, 0, 0, 0, 35, 28, 0,
+  25, 0, 6, 0, 68, 1, 9, 53, 37, 38,
+  8, 0, 43, 0, 0, 43, 7, 56, 0, 4,
+  0, 13, 10, 0, 65, 53, 0, 0, 0, 0,
+  0, 56, 0, 63, 0, 42, 23, 10, 1, 49,
+  0, 48, 0, 7, 80, 24, 0, 0, 14, 0,
+  0, 62, 18, 0, 0, 0, 0, 0, 30, 19,
+  15, 0, 0, 0, 0, 17, 1, 53, 0, 0,
+  0, 49, 63, 0, 24, 24, 20, 0, 11, 25,
+  0, 37, 36, 32, 0, 13, 32, 35, 0, 0,
+  0, 66, 17, 0, 0, 0, 0, 0, 37, 0,
+  0, 36, 37, 19, 0, 29, 0, 0, 14, 20,
+  42, 8, 3, 0, 121, 0, 63, 0, 10, 0,
+  0, 30, 54, 0, 0, 0, 0, 0, 58, 0,
+  7, 0, 28, 0, 0, 22, 10, 0, 2, 0,
+  0, 34, 90, 48, 0, 0, 0, 8, 0, 0,
+  0, 0, 0, 0, 60, 31, 0, 15, 0, 34,
+  0, 38, 22, 0, 0, 0, 0, 13, 0, 15,
+  0, 42, 9, 20, 3, 0, 31, 0, 11, 0,
+  0, 30, 0, 0, 11, 0, 36, 0, 0, 0,
+  39, 7, 39, 28, 0, 24, 0, 100, 0, 56,
+  6, 0, 40, 58, 4, 14, 0, 33, 0, 7,
+  54, 0, 0, 0, 20, 0, 0, 0, 0, 89,
+  27, 0, 0, 0, 2, 0, 51, 2, 0, 7,
+  14, 14, 0, 14, 0, 0, 0, 0, 9, 47,
+  0, 0, 11, 0, 57, 2, 5, 8, 0, 8,
+  0, 0, 0, 26, 43, 6, 20, 0, 13, 0,
+  59, 0, 10, 62, 36, 31, 3, 0, 46, 0,
+  0, 38, 0, 42, 6, 2, 0, 34, 0, 0,
+  63, 41, 15, 0, 0, 0, 0, 46, 0, 37,
+  0, 53, 25, 14, 17, 17, 0, 32, 15, 5,
+  91, 14, 0, 0, 28, 0, 0, 70, 0, 0,
+  0, 0, 0, 0, 24, 8, 0, 0, 0, 2,
+  0, 9, 17, 48, 0, 3, 0, 31, 71, 5,
+  13, 36, 17, 0, 4, 23, 26, 35, 36, 0,
+  0, 2, 17, 32, 0, 0, 2, 44, 36, 0,
+  0, 0, 12, 0, 55, 13, 24, 46, 43, 0,
+  0, 24, 0, 0, 42, 41, 44, 0, 0, 0,
+  108, 0, 71, 14, 0, 0, 0, 44, 70, 0,
+  0, 0, 0, 9, 53, 0, 0, 29, 11, 20,
+  0, 36, 26, 0, 0, 0, 0, 7, 73, 51,
+  0, 0, 16, 18, 0, 0, 0, 0, 0, 0,
+  29, 22, 0, 0, 0, 40, 0, 13, 0, 10,
+  0, 1, 22, 0, 0, 0, 35, 32, 22, 15,
+  0, 0, 28, 0, 0, 0, 0, 0, 0, 0,
+  20, 0, 30, 0, 2, 0, 0, 8, 3, 20,
+  33, 0, 0, 85, 0, 28, 19, 0, 42, 48,
+  0, 18, 0, 36, 33, 9, 46, 0, 0, 0,
+  8, 0, 0, 0, 0, 81, 37, 0, 0, 0,
+  25, 0, 70, 0, 22, 26, 14, 0, 0, 8,
+  0, 0, 28, 0, 0, 18, 0, 0, 19, 0,
+  44, 20, 0, 20, 102, 0, 40, 4, 0, 12,
+  0, 0, 45, 0, 0, 35, 56, 20, 0, 0,
+  9, 0, 0, 0, 0, 189, 80, 25, 0, 0,
+  0, 31, 0, 0, 16, 61, 0, 11, 0, 30,
+  0, 40, 0, 30, 0, 28, 48, 0, 38, 21,
+  24, 29, 0, 0, 0, 80, 0, 0, 100, 0,
+  63, 0, 47, 0, 14, 23, 0, 56, 27, 66,
+  0, 1, 0, 4, 12, 26, 10, 13, 0, 0,
+  0, 47, 0, 15, 0, 0, 7, 21, 0, 11,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  25, 0, 18, 61, 0, 0, 17, 0, 54, 23,
+  26, 12, 6, 14, 8, 6, 0, 0, 0, 2,
+  87, 0, 36, 39, 0, 9, 0, 0, 23, 15,
+  18, 29, 0, 17, 0, 0, 0, 31, 35, 0,
+  13, 0, 8, 0, 56, 4, 16, 62, 36, 39,
+  10, 0, 30, 0, 0, 48, 4, 53, 0, 4,
+  0, 15, 0, 0, 72, 44, 0, 0, 0, 0,
+  0, 66, 0, 41, 0, 43, 20, 12, 12, 36,
+  0, 41, 0, 7, 95, 16, 0, 0, 21, 0,
+  0, 55, 9, 0, 0, 0, 0, 0, 32, 12,
+  11, 0, 0, 0, 0, 15, 10, 55, 0, 0,
+  0, 47, 64, 4, 32, 22, 15, 0, 7, 27,
+  13, 34, 54, 16, 0, 11, 39, 32, 0, 0,
+  0, 68, 22, 0, 0, 0, 0, 0, 48, 0,
+  0, 30, 26, 15, 0, 27, 0, 0, 25, 30,
+  24, 3, 1, 0, 121, 0, 65, 2, 0, 0,
+  0, 31, 59, 0, 8, 0, 0, 0, 53, 2,
+  0, 9, 30, 0, 0, 23, 15, 0, 8, 0,
+  0, 47, 79, 53, 0, 0, 0, 15, 0, 0,
+  0, 0, 0, 0, 52, 28, 0, 4, 0, 63,
+  0, 25, 0, 1, 0, 0, 25, 4, 0, 6,
+  0, 48, 20, 26, 0, 0, 19, 0, 8, 0,
+  0, 13, 0, 0, 18, 0, 16, 0, 9, 0,
+  10, 19, 20, 21, 21, 5, 0, 89, 0, 46,
+  12, 0, 50, 44, 4, 2, 0, 39, 7, 1,
+  49, 0, 0, 0, 4, 0, 0, 0, 6, 91,
+  22, 0, 0, 0, 9, 0, 71, 0, 0, 9,
+  0, 0, 0, 14, 0, 0, 23, 0, 0, 33,
+  0, 0, 26, 0, 73, 2, 0, 1, 73, 0,
+  21, 29, 10, 2, 0, 11, 74, 0, 0, 18,
+  94, 0, 0, 0, 36, 0, 0, 0, 0, 148,
+  91, 19, 0, 0, 0, 47, 0, 0, 32, 47,
+  0, 0, 27, 32, 0, 52, 0, 43, 0, 24,
+  66, 17, 51, 51, 13, 28, 0, 0, 0, 63,
+  0, 0, 62, 0, 50, 0, 39, 0, 0, 6,
+  0, 30, 12, 20, 0, 4, 0, 0, 19, 4,
+  40, 42, 0, 0, 0, 87, 0, 19, 0, 0,
+  16, 26, 0, 11, 0, 0, 0, 0, 0, 0,
+  0, 8, 0, 0, 35, 0, 15, 55, 0, 0,
+  22, 0, 52, 8, 59, 31, 3, 19, 8, 16,
+  0, 0, 0, 0, 66, 0, 18, 40, 0, 4,
+  0, 0, 51, 0, 18, 14, 0, 20, 0, 0,
+  0, 35, 28, 0, 25, 0, 6, 0, 68, 1,
+  9, 53, 37, 38, 8, 0, 43, 0, 0, 43,
+  7, 56, 0, 4, 0, 13, 10, 0, 65, 53,
+  0, 0, 0, 0, 0, 56, 0, 63, 0, 42,
+  23, 10, 1, 49, 0, 48, 0, 7, 80, 24,
+  0, 0, 14, 0, 0, 62, 18, 0, 0, 0,
+  0, 0, 30, 19, 15, 0, 0, 0, 0, 17,
+  1, 53, 0, 0, 0, 49, 63, 0, 24, 24,
+  20, 0, 11, 25, 0, 37, 36, 32, 0, 13,
+  32, 35, 0, 0, 0, 66, 17, 0, 0, 0,
+  0, 0, 37, 0, 0, 36, 37, 19, 0, 29,
+  0, 0, 14, 20, 42, 8, 3, 0, 121, 0,
+  63, 0, 10, 0, 0, 30, 54, 0, 0, 0,
+  0, 0, 58, 0, 7, 0, 28, 0, 0, 22,
+  10, 0, 2, 0, 0, 34, 90, 48, 0, 0,
+  0, 8, 0, 0, 0, 0, 0, 0, 60, 31,
+  0, 15, 0, 34, 0, 38, 22, 0, 0, 0,
+  0, 13, 0, 15, 0, 42, 9, 20, 3, 0,
+  31, 0, 11, 0, 0, 30, 0, 0, 11, 0,
+  36, 0, 0, 0, 39, 7, 39, 28, 0, 24,
+  0, 100, 0, 56, 6, 0, 40, 58, 4, 14,
+  0, 33, 0, 7, 54, 0, 0, 0, 20, 0,
+  0, 0, 0, 89, 27, 0, 0, 0, 2, 0,
+  51, 2, 0, 7, 14, 14, 0, 14, 0, 0,
+  0, 0, 9, 47, 0, 0, 11, 0, 57, 2,
+  5, 8, 47, 0, 20, 39, 5, 0, 0, 0,
+  62, 0, 0, 14, 68, 0, 0, 21, 35, 5,
+  0, 0, 0, 128, 114, 15, 0, 0, 0, 47,
+  0, 0, 20, 52, 0, 0, 50, 20, 0, 61,
+  4, 20, 4, 18, 55, 0, 26, 27, 3, 14,
+  0, 0, 0, 37, 0, 16, 61, 0, 47, 0,
+  41, 0, 0, 22, 0, 3, 20, 0, 11, 19,
+  19, 0, 54, 9, 49, 31, 0, 0, 0, 94,
+  0, 41, 0, 0, 7, 31, 0, 19, 0, 0,
+  0, 0, 0, 0, 0, 7, 19, 0, 43, 0,
+  15, 77, 0, 0, 32, 0, 35, 20, 15, 28,
+  0, 0, 0, 17, 0, 0, 0, 0, 32, 0,
+  4, 45, 0, 0, 0, 0, 48, 0, 19, 13,
+  0, 44, 70, 0, 0, 0, 0, 9, 53, 0,
+  0, 29, 11, 20, 0, 36, 26, 0, 0, 0,
+  0, 7, 73, 51, 0, 0, 16, 18, 0, 0,
+  0, 0, 0, 0, 29, 22, 0, 0, 0, 40,
+  0, 13, 0, 10, 0, 1, 22, 0, 0, 0,
+  35, 32, 22, 15, 0, 0, 28, 0, 0, 0,
+  0, 0, 0, 0, 20, 0, 30, 0, 2, 0,
+  0, 8, 3, 20, 33, 0, 0, 85, 0, 28,
+  19, 0, 42, 48, 0, 18, 0, 36, 33, 9,
+  46, 0, 0, 0, 8, 0, 0, 0, 0, 81,
+  37, 0, 0, 0, 25, 0, 70, 0, 22, 26,
+  14, 0, 0, 8, 0, 0, 28, 0, 0, 18,
+  0, 0, 19, 0, 44, 20, 0, 20, 102, 0,
+  40, 4, 0, 12, 0, 0, 45, 0, 0, 35,
+  56, 20, 0, 0, 9, 0, 0, 0, 0, 189,
+  80, 25, 0, 0, 0, 31, 0, 0, 16, 61,
+  0, 11, 0, 30, 0, 40, 0, 30, 0, 28,
+  48, 0, 38, 21, 24, 29, 0, 0, 0, 80,
+  0, 0, 100, 0, 63, 0, 47, 0, 14, 23,
+  0, 56, 27, 66, 0, 1, 0, 4, 12, 26,
+  10, 13, 0, 0, 0, 47, 0, 15, 0, 0,
+  7, 21, 0, 11, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 25, 0, 18, 61, 0, 0,
+  17, 0, 54, 23, 26, 12, 6, 14, 8, 6,
+  0, 0, 0, 2, 87, 0, 36, 39, 0, 9,
+  0, 0, 23, 15, 18, 29, 9, 0, 0, 9,
+  0, 65, 0, 0, 41, 0, 0, 0, 45, 38,
+  0, 38, 32, 25, 0, 0, 8, 14, 5, 56,
+  28, 0, 0, 19, 0, 0, 0, 21, 10, 40,
+  27, 4, 0, 33, 0, 8, 9, 4, 50, 58,
+  50, 77, 14, 17, 0, 0, 0, 0, 0, 0,
+  0, 0, 54, 0, 0, 0, 4, 43, 0, 0,
+  0, 0, 0, 0, 12, 0, 54, 0, 14, 11,
+  0, 28, 0, 28, 0, 28, 0, 16, 0, 39,
+  0, 0, 31, 0, 14, 62, 0, 63, 0, 0,
+  13, 17, 0, 0, 0, 56, 19, 0, 0, 0,
+  17, 0, 0, 4, 0, 40, 0, 0, 0, 9,
+  0, 0, 61, 0, 8, 0, 37, 0, 3, 0,
+  29, 10, 44, 0, 0, 31, 59, 0, 8, 0,
+  0, 0, 53, 2, 0, 9, 30, 0, 0, 23,
+  15, 0, 8, 0, 0, 47, 79, 53, 0, 0,
+  0, 15, 0, 0, 0, 0, 0, 0, 52, 28,
+  0, 4, 0, 63, 0, 25, 0, 1, 0, 0,
+  25, 4, 0, 6, 0, 48, 20, 26, 0, 0,
+  19, 0, 8, 0, 0, 13, 0, 0, 18, 0,
+  16, 0, 9, 0, 10, 19, 20, 21, 21, 5,
+  0, 89, 0, 46, 12, 0, 50, 44, 4, 2,
+  0, 39, 7, 1, 49, 0, 0, 0, 4, 0,
+  0, 0, 6, 91, 22, 0, 0, 0, 9, 0,
+  71, 0, 0, 9, 0, 0, 0, 14, 0, 0,
+  23, 0, 0, 33, 0, 0, 26, 0, 73, 2,
+  0, 1, 73, 0, 21, 29, 10, 2, 0, 11,
+  74, 0, 0, 18, 94, 0, 0, 0, 36, 0,
+  0, 0, 0, 148, 91, 19, 0, 0, 0, 47,
+  0, 0, 32, 47, 0, 0, 27, 32, 0, 52,
+  0, 43, 0, 24, 66, 17, 51, 51, 13, 28,
+  0, 0, 0, 63, 0, 0, 62, 0, 50, 0,
+  39, 0, 0, 6, 0, 30, 12, 20, 0, 4,
+  0, 0, 19, 4, 40, 42, 0, 0, 0, 87,
+  0, 19, 0, 0, 16, 26, 0, 11, 0, 0,
+  0, 0, 0, 0, 0, 8, 0, 0, 35, 0,
+  15, 55, 0, 0, 22, 0, 52, 8, 59, 31,
+  3, 19, 8, 16, 0, 0, 0, 0, 66, 0,
+  18, 40, 0, 4, 0, 0, 51, 0, 18, 14,
+  0, 0, 0, 29, 1, 29, 8, 0, 54, 0,
+  0, 0, 67, 10, 9, 37, 50, 41, 0, 0,
+  0, 0, 0, 46, 33, 11, 2, 31, 0, 0,
+  8, 47, 45, 22, 0, 0, 0, 51, 0, 0,
+  0, 0, 95, 63, 29, 90, 0, 25, 0, 0,
+  0, 1, 11, 3, 0, 0, 29, 0, 0, 1,
+  0, 38, 0, 0, 3, 0, 26, 25, 4, 0,
+  48, 0, 30, 61, 0, 8, 0, 30, 0, 18,
+  0, 0, 0, 54, 0, 2, 33, 0, 0, 26,
+  0, 44, 0, 32, 0, 43, 0, 0, 0, 39,
+  13, 0, 8, 0, 38, 0, 3, 19, 0, 10,
+  9, 7, 0, 4, 0, 0, 50, 0, 0, 18,
+  13, 0, 27, 0, 42, 0, 53, 0, 0, 30,
+  54, 0, 0, 0, 0, 0, 58, 0, 7, 0,
+  28, 0, 0, 22, 10, 0, 2, 0, 0, 34,
+  90, 48, 0, 0, 0, 8, 0, 0, 0, 0,
+  0, 0, 60, 31, 0, 15, 0, 34, 0, 38,
+  22, 0, 0, 0, 0, 13, 0, 15, 0, 42,
+  9, 20, 3, 0, 31, 0, 11, 0, 0, 30,
+  0, 0, 11, 0, 36, 0, 0, 0, 39, 7,
+  39, 28, 0, 24, 0, 100, 0, 56, 6, 0,
+  40, 58, 4, 14, 0, 33, 0, 7, 54, 0,
+  0, 0, 20, 0, 0, 0, 0, 89, 27, 0,
+  0, 0, 2, 0, 51, 2, 0, 7, 14, 14,
+  0, 14, 0, 0, 0, 0, 9, 47, 0, 0,
+  11, 0, 57, 2, 5, 8, 47, 0, 20, 39,
+  5, 0, 0, 0, 62, 0, 0, 14, 68, 0,
+  0, 21, 35, 5, 0, 0, 0, 128, 114, 15,
+  0, 0, 0, 47, 0, 0, 20, 52, 0, 0,
+  50, 20, 0, 61, 4, 20, 4, 18, 55, 0,
+  26, 27, 3, 14, 0, 0, 0, 37, 0, 16,
+  61, 0, 47, 0, 41, 0, 0, 22, 0, 3,
+  20, 0, 11, 19, 19, 0, 54, 9, 49, 31,
+  0, 0, 0, 94, 0, 41, 0, 0, 7, 31,
+  0, 19, 0, 0, 0, 0, 0, 0, 0, 7,
+  19, 0, 43, 0, 15, 77, 0, 0, 32, 0,
+  35, 20, 15, 28, 0, 0, 0, 17, 0, 0,
+  0, 0, 32, 0, 4, 45, 0, 0, 0, 0,
+  48, 0, 19, 13, 7, 0, 3, 44, 17, 25,
+  0, 0, 33, 5, 0, 0, 79, 30, 6, 52,
+  69, 29, 0, 5, 0, 0, 0, 27, 43, 42,
+  0, 35, 0, 15, 23, 80, 17, 52, 0, 11,
+  0, 71, 0, 0, 0, 0, 79, 35, 26, 18,
+  0, 33, 18, 0, 0, 0, 0, 36, 0, 0,
+  12, 0, 0, 50, 0, 25, 11, 0, 0, 0,
+  34, 59, 45, 0, 6, 16, 27, 39, 11, 5,
+  0, 27, 0, 41, 0, 6, 0, 50, 30, 18,
+  19, 0, 0, 8, 0, 13, 0, 78, 0, 51,
+  3, 0, 0, 35, 0, 0, 32, 0, 33, 0,
+  0, 19, 0, 0, 22, 0, 0, 0, 0, 0,
+  41, 0, 0, 2, 9, 6, 34, 0, 46, 1,
+  49, 0, 102, 0, 40, 4, 0, 12, 0, 0,
+  45, 0, 0, 35, 56, 20, 0, 0, 9, 0,
+  0, 0, 0, 189, 80, 25, 0, 0, 0, 31,
+  0, 0, 16, 61, 0, 11, 0, 30, 0, 40,
+  0, 30, 0, 28, 48, 0, 38, 21, 24, 29,
+  0, 0, 0, 80, 0, 0, 100, 0, 63, 0,
+  47, 0, 14, 23, 0, 56, 27, 66, 0, 1,
+  0, 4, 12, 26, 10, 13, 0, 0, 0, 47,
+  0, 15, 0, 0, 7, 21, 0, 11, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 25, 0,
+  18, 61, 0, 0, 17, 0, 54, 23, 26, 12,
+  6, 14, 8, 6, 0, 0, 0, 2, 87, 0,
+  36, 39, 0, 9, 0, 0, 23, 15, 18, 29,
+  9, 0, 0, 9, 0, 65, 0, 0, 41, 0,
+  0, 0, 45, 38, 0, 38, 32, 25, 0, 0,
+  8, 14, 5, 56, 28, 0, 0, 19, 0, 0,
+  0, 21, 10, 40, 27, 4, 0, 33, 0, 8,
+  9, 4, 50, 58, 50, 77, 14, 17, 0, 0,
+  0, 0, 0, 0, 0, 0, 54, 0, 0, 0,
+  4, 43, 0, 0, 0, 0, 0, 0, 12, 0,
+  54, 0, 14, 11, 0, 28, 0, 28, 0, 28,
+  0, 16, 0, 39, 0, 0, 31, 0, 14, 62,
+  0, 63, 0, 0, 13, 17, 0, 0, 0, 56,
+  19, 0, 0, 0, 17, 0, 0, 4, 0, 40,
+  0, 0, 0, 9, 0, 0, 61, 0, 8, 0,
+  37, 0, 3, 0, 29, 10, 44, 0, 0, 14,
+  0, 0, 35, 12, 0, 0, 40, 0, 0, 15,
+  31, 88, 14, 51, 40, 12, 0, 18, 47, 0,
+  19, 50, 3, 20, 0, 2, 0, 0, 0, 0,
+  0, 38, 7, 0, 3, 31, 0, 29, 36, 1,
+  0, 74, 29, 39, 8, 0, 0, 0, 18, 2,
+  39, 14, 0, 6, 37, 0, 0, 0, 0, 4,
+  5, 0, 0, 0, 26, 0, 49, 0, 0, 0,
+  3, 3, 17, 22, 0, 17, 0, 21, 27, 60,
+  0, 26, 24, 3, 57, 0, 52, 33, 0, 62,
+  14, 8, 23, 27, 0, 0, 26, 70, 5, 0,
+  0, 0, 0, 0, 0, 16, 0, 35, 0, 0,
+  0, 12, 0, 0, 17, 3, 26, 0, 0, 0,
+  20, 0, 35, 8, 37, 0, 73, 0, 21, 29,
+  10, 2, 0, 11, 74, 0, 0, 18, 94, 0,
+  0, 0, 36, 0, 0, 0, 0, 148, 91, 19,
+  0, 0, 0, 47, 0, 0, 32, 47, 0, 0,
+  27, 32, 0, 52, 0, 43, 0, 24, 66, 17,
+  51, 51, 13, 28, 0, 0, 0, 63, 0, 0,
+  62, 0, 50, 0, 39, 0, 0, 6, 0, 30,
+  12, 20, 0, 4, 0, 0, 19, 4, 40, 42,
+  0, 0, 0, 87, 0, 19, 0, 0, 16, 26,
+  0, 11, 0, 0, 0, 0, 0, 0, 0, 8,
+  0, 0, 35, 0, 15, 55, 0, 0, 22, 0,
+  52, 8, 59, 31, 3, 19, 8, 16, 0, 0,
+  0, 0, 66, 0, 18, 40, 0, 4, 0, 0,
+  51, 0, 18, 14, 0, 0, 0, 29, 1, 29,
+  8, 0, 54, 0, 0, 0, 67, 10, 9, 37,
+  50, 41, 0, 0, 0, 0, 0, 46, 33, 11,
+  2, 31, 0, 0, 8, 47, 45, 22, 0, 0,
+  0, 51, 0, 0, 0, 0, 95, 63, 29, 90,
+  0, 25, 0, 0, 0, 1, 11, 3, 0, 0,
+  29, 0, 0, 1, 0, 38, 0, 0, 3, 0,
+  26, 25, 4, 0, 48, 0, 30, 61, 0, 8,
+  0, 30, 0, 18, 0, 0, 0, 54, 0, 2,
+  33, 0, 0, 26, 0, 44, 0, 32, 0, 43,
+  0, 0, 0, 39, 13, 0, 8, 0, 38, 0,
+  3, 19, 0, 10, 9, 7, 0, 4, 0, 0,
+  50, 0, 0, 18, 13, 0, 27, 0, 42, 0,
+  53, 0, 0, 0, 0, 5, 36, 43, 0, 0,
+  0, 0, 0, 1, 24, 87, 0, 16, 36, 0,
+  0, 9, 34, 0, 19, 29, 0, 11, 0, 0,
+  0, 24, 7, 0, 0, 36, 0, 0, 0, 26,
+  0, 8, 20, 9, 0, 66, 26, 13, 0, 36,
+  0, 0, 2, 42, 7, 10, 0, 0, 26, 0,
+  0, 0, 0, 31, 20, 0, 10, 0, 10, 15,
+  33, 0, 6, 11, 0, 7, 9, 11, 0, 16,
+  0, 29, 9, 31, 0, 20, 48, 0, 63, 19,
+  21, 0, 0, 52, 14, 4, 22, 50, 0, 0,
+  0, 71, 13, 0, 0, 0, 0, 0, 0, 1,
+  0, 0, 3, 0, 0, 16, 0, 8, 57, 0,
+  8, 0, 0, 0, 0, 0, 20, 1, 25, 0,
+  47, 0, 20, 39, 5, 0, 0, 0, 62, 0,
+  0, 14, 68, 0, 0, 21, 35, 5, 0, 0,
+  0, 128, 114, 15, 0, 0, 0, 47, 0, 0,
+  20, 52, 0, 0, 50, 20, 0, 61, 4, 20,
+  4, 18, 55, 0, 26, 27, 3, 14, 0, 0,
+  0, 37, 0, 16, 61, 0, 47, 0, 41, 0,
+  0, 22, 0, 3, 20, 0, 11, 19, 19, 0,
+  54, 9, 49, 31, 0, 0, 0, 94, 0, 41,
+  0, 0, 7, 31, 0, 19, 0, 0, 0, 0,
+  0, 0, 0, 7, 19, 0, 43, 0, 15, 77,
+  0, 0, 32, 0, 35, 20, 15, 28, 0, 0,
+  0, 17, 0, 0, 0, 0, 32, 0, 4, 45,
+  0, 0, 0, 0, 48, 0, 19, 13, 7, 0,
+  3, 44, 17, 25, 0, 0, 33, 5, 0, 0,
+  79, 30, 6, 52, 69, 29, 0, 5, 0, 0,
+  0, 27, 43, 42, 0, 35, 0, 15, 23, 80,
+  17, 52, 0, 11, 0, 71, 0, 0, 0, 0,
+  79, 35, 26, 18, 0, 33, 18, 0, 0, 0,
+  0, 36, 0, 0, 12, 0, 0, 50, 0, 25,
+  11, 0, 0, 0, 34, 59, 45, 0, 6, 16,
+  27, 39, 11, 5, 0, 27, 0, 41, 0, 6,
+  0, 50, 30, 18, 19, 0, 0, 8, 0, 13,
+  0, 78, 0, 51, 3, 0, 0, 35, 0, 0,
+  32, 0, 33, 0, 0, 19, 0, 0, 22, 0,
+  0, 0, 0, 0, 41, 0, 0, 2, 9, 6,
+  34, 0, 46, 1, 49, 0, 0, 0, 10, 17,
+  54, 56, 0, 0, 20, 0, 5, 0, 53, 99,
+  5, 43, 52, 0, 0, 5, 28, 0, 0, 23,
+  0, 24, 0, 5, 0, 39, 8, 0, 0, 50,
+  0, 0, 0, 26, 0, 39, 0, 24, 13, 63,
+  23, 0, 2, 41, 6, 0, 11, 51, 3, 40,
+  0, 0, 3, 3, 2, 3, 0, 28, 5, 0,
+  0, 0, 3, 0, 53, 0, 0, 21, 8, 0,
+  22, 6, 0, 28, 0, 59, 6, 44, 0, 0,
+  63, 6, 53, 24, 33, 0, 0, 30, 0, 30,
+  0, 66, 0, 0, 0, 63, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 20, 0, 0, 6,
+  0, 0, 60, 0, 0, 0, 34, 0, 15, 0,
+  39, 0, 0, 0, 9, 0, 0, 9, 0, 65,
+  0, 0, 41, 0, 0, 0, 45, 38, 0, 38,
+  32, 25, 0, 0, 8, 14, 5, 56, 28, 0,
+  0, 19, 0, 0, 0, 21, 10, 40, 27, 4,
+  0, 33, 0, 8, 9, 4, 50, 58, 50, 77,
+  14, 17, 0, 0, 0, 0, 0, 0, 0, 0,
+  54, 0, 0, 0, 4, 43, 0, 0, 0, 0,
+  0, 0, 12, 0, 54, 0, 14, 11, 0, 28,
+  0, 28, 0, 28, 0, 16, 0, 39, 0, 0,
+  31, 0, 14, 62, 0, 63, 0, 0, 13, 17,
+  0, 0, 0, 56, 19, 0, 0, 0, 17, 0,
+  0, 4, 0, 40, 0, 0, 0, 9, 0, 0,
+  61, 0, 8, 0, 37, 0, 3, 0, 29, 10,
+  44, 0, 0, 14, 0, 0, 35, 12, 0, 0,
+  40, 0, 0, 15, 31, 88, 14, 51, 40, 12,
+  0, 18, 47, 0, 19, 50, 3, 20, 0, 2,
+  0, 0, 0, 0, 0, 38, 7, 0, 3, 31,
+  0, 29, 36, 1, 0, 74, 29, 39, 8, 0,
+  0, 0, 18, 2, 39, 14, 0, 6, 37, 0,
+  0, 0, 0, 4, 5, 0, 0, 0, 26, 0,
+  49, 0, 0, 0, 3, 3, 17, 22, 0, 17,
+  0, 21, 27, 60, 0, 26, 24, 3, 57, 0,
+  52, 33, 0, 62, 14, 8, 23, 27, 0, 0,
+  26, 70, 5, 0, 0, 0, 0, 0, 0, 16,
+  0, 35, 0, 0, 0, 12, 0, 0, 17, 3,
+  26, 0, 0, 0, 20, 0, 35, 8, 37, 0,
+  24, 0, 53, 0, 32, 0, 0, 0, 25, 0,
+  0, 1, 9, 122, 15, 0, 27, 21, 0, 8,
+  41, 13, 69, 7, 0, 0, 0, 4, 0, 0,
+  0, 0, 0, 5, 0, 0, 0, 4, 0, 26,
+  14, 10, 0, 48, 14, 0, 0, 0, 0, 0,
+  37, 104, 0, 37, 0, 0, 9, 6, 3, 0,
+  0, 0, 33, 0, 50, 22, 0, 0, 24, 22,
+  0, 1, 0, 0, 27, 0, 0, 13, 0, 41,
+  14, 36, 0, 5, 48, 0, 45, 11, 72, 0,
+  0, 2, 0, 0, 0, 25, 0, 0, 41, 57,
+  0, 0, 0, 0, 0, 0, 0, 10, 1, 0,
+  35, 0, 0, 0, 51, 0, 55, 0, 5, 0,
+  0, 0, 0, 0, 28, 1, 16, 0, 0, 0,
+  0, 29, 1, 29, 8, 0, 54, 0, 0, 0,
+  67, 10, 9, 37, 50, 41, 0, 0, 0, 0,
+  0, 46, 33, 11, 2, 31, 0, 0, 8, 47,
+  45, 22, 0, 0, 0, 51, 0, 0, 0, 0,
+  95, 63, 29, 90, 0, 25, 0, 0, 0, 1,
+  11, 3, 0, 0, 29, 0, 0, 1, 0, 38,
+  0, 0, 3, 0, 26, 25, 4, 0, 48, 0,
+  30, 61, 0, 8, 0, 30, 0, 18, 0, 0,
+  0, 54, 0, 2, 33, 0, 0, 26, 0, 44,
+  0, 32, 0, 43, 0, 0, 0, 39, 13, 0,
+  8, 0, 38, 0, 3, 19, 0, 10, 9, 7,
+  0, 4, 0, 0, 50, 0, 0, 18, 13, 0,
+  27, 0, 42, 0, 53, 0, 0, 0, 0, 5,
+  36, 43, 0, 0, 0, 0, 0, 1, 24, 87,
+  0, 16, 36, 0, 0, 9, 34, 0, 19, 29,
+  0, 11, 0, 0, 0, 24, 7, 0, 0, 36,
+  0, 0, 0, 26, 0, 8, 20, 9, 0, 66,
+  26, 13, 0, 36, 0, 0, 2, 42, 7, 10,
+  0, 0, 26, 0, 0, 0, 0, 31, 20, 0,
+  10, 0, 10, 15, 33, 0, 6, 11, 0, 7,
+  9, 11, 0, 16, 0, 29, 9, 31, 0, 20,
+  48, 0, 63, 19, 21, 0, 0, 52, 14, 4,
+  22, 50, 0, 0, 0, 71, 13, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 3, 0, 0, 16,
+  0, 8, 57, 0, 8, 0, 0, 0, 0, 0,
+  20, 1, 25, 0, 15, 8, 22, 22, 74, 0,
+  0, 1, 31, 0, 0, 0, 40, 118, 28, 13,
+  44, 0, 0, 9, 37, 0, 0, 12, 0, 12,
+  0, 24, 0, 17, 2, 0, 0, 38, 0, 0,
+  0, 6, 0, 44, 0, 22, 0, 57, 17, 0,
+  18, 21, 0, 0, 25, 88, 0, 60, 0, 0,
+  0, 21, 0, 0, 0, 0, 0, 0, 0, 3,
+  13, 0, 39, 0, 0, 18, 0, 0, 44, 0,
+  0, 3, 0, 44, 27, 45, 2, 0, 52, 4,
+  48, 24, 64, 0, 0, 0, 0, 16, 0, 45,
+  3, 2, 31, 57, 0, 0, 0, 0, 0, 0,
+  0, 10, 30, 7, 17, 0, 0, 0, 33, 0,
+  43, 0, 0, 0, 30, 0, 35, 0, 54, 0,
+  0, 0, 7, 0, 3, 44, 17, 25, 0, 0,
+  33, 5, 0, 0, 79, 30, 6, 52, 69, 29,
+  0, 5, 0, 0, 0, 27, 43, 42, 0, 35,
+  0, 15, 23, 80, 17, 52, 0, 11, 0, 71,
+  0, 0, 0, 0, 79, 35, 26, 18, 0, 33,
+  18, 0, 0, 0, 0, 36, 0, 0, 12, 0,
+  0, 50, 0, 25, 11, 0, 0, 0, 34, 59,
+  45, 0, 6, 16, 27, 39, 11, 5, 0, 27,
+  0, 41, 0, 6, 0, 50, 30, 18, 19, 0,
+  0, 8, 0, 13, 0, 78, 0, 51, 3, 0,
+  0, 35, 0, 0, 32, 0, 33, 0, 0, 19,
+  0, 0, 22, 0, 0, 0, 0, 0, 41, 0,
+  0, 2, 9, 6, 34, 0, 46, 1, 49, 0,
+  0, 0, 10, 17, 54, 56, 0, 0, 20, 0,
+  5, 0, 53, 99, 5, 43, 52, 0, 0, 5,
+  28, 0, 0, 23, 0, 24, 0, 5, 0, 39,
+  8, 0, 0, 50, 0, 0, 0, 26, 0, 39,
+  0, 24, 13, 63, 23, 0, 2, 41, 6, 0,
+  11, 51, 3, 40, 0, 0, 3, 3, 2, 3,
+  0, 28, 5, 0, 0, 0, 3, 0, 53, 0,
+  0, 21, 8, 0, 22, 6, 0, 28, 0, 59,
+  6, 44, 0, 0, 63, 6, 53, 24, 33, 0,
+  0, 30, 0, 30, 0, 66, 0, 0, 0, 63,
+  0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
+  20, 0, 0, 6, 0, 0, 60, 0, 0, 0,
+  34, 0, 15, 0, 39, 0, 0, 0, 0, 16,
+  49, 37, 80, 0, 0, 1, 64, 3, 2, 0,
+  54, 91, 27, 51, 45, 0, 0, 9, 23, 0,
+  0, 27, 0, 25, 0, 38, 0, 3, 12, 0,
+  0, 38, 0, 0, 0, 15, 0, 58, 0, 15,
+  0, 46, 0, 0, 33, 9, 0, 0, 4, 73,
+  21, 61, 0, 0, 0, 51, 0, 15, 0, 0,
+  0, 0, 0, 0, 58, 0, 53, 0, 0, 0,
+  0, 25, 36, 0, 0, 19, 0, 23, 49, 49,
+  13, 0, 41, 40, 36, 29, 68, 0, 0, 29,
+  0, 26, 0, 29, 0, 0, 3, 71, 0, 0,
+  0, 0, 0, 0, 0, 17, 24, 30, 27, 0,
+  0, 0, 28, 0, 19, 0, 0, 0, 24, 0,
+  70, 0, 63, 3, 0, 0, 0, 14, 0, 0,
+  35, 12, 0, 0, 40, 0, 0, 15, 31, 88,
+  14, 51, 40, 12, 0, 18, 47, 0, 19, 50,
+  3, 20, 0, 2, 0, 0, 0, 0, 0, 38,
+  7, 0, 3, 31, 0, 29, 36, 1, 0, 74,
+  29, 39, 8, 0, 0, 0, 18, 2, 39, 14,
+  0, 6, 37, 0, 0, 0, 0, 4, 5, 0,
+  0, 0, 26, 0, 49, 0, 0, 0, 3, 3,
+  17, 22, 0, 17, 0, 21, 27, 60, 0, 26,
+  24, 3, 57, 0, 52, 33, 0, 62, 14, 8,
+  23, 27, 0, 0, 26, 70, 5, 0, 0, 0,
+  0, 0, 0, 16, 0, 35, 0, 0, 0, 12,
+  0, 0, 17, 3, 26, 0, 0, 0, 20, 0,
+  35, 8, 37, 0, 24, 0, 53, 0, 32, 0,
+  0, 0, 25, 0, 0, 1, 9, 122, 15, 0,
+  27, 21, 0, 8, 41, 13, 69, 7, 0, 0,
+  0, 4, 0, 0, 0, 0, 0, 5, 0, 0,
+  0, 4, 0, 26, 14, 10, 0, 48, 14, 0,
+  0, 0, 0, 0, 37, 104, 0, 37, 0, 0,
+  9, 6, 3, 0, 0, 0, 33, 0, 50, 22,
+  0, 0, 24, 22, 0, 1, 0, 0, 27, 0,
+  0, 13, 0, 41, 14, 36, 0, 5, 48, 0,
+  45, 11, 72, 0, 0, 2, 0, 0, 0, 25,
+  0, 0, 41, 57, 0, 0, 0, 0, 0, 0,
+  0, 10, 1, 0, 35, 0, 0, 0, 51, 0,
+  55, 0, 5, 0, 0, 0, 0, 0, 28, 1,
+  16, 0, 30, 0, 17, 10, 31, 0, 0, 0,
+  35, 0, 0, 3, 12, 104, 13, 0, 18, 16,
+  0, 5, 51, 0, 33, 3, 0, 0, 0, 16,
+  0, 15, 0, 9, 0, 7, 0, 0, 0, 0,
+  0, 7, 0, 12, 0, 50, 13, 0, 0, 0,
+  0, 0, 32, 102, 0, 61, 0, 0, 22, 15,
+  0, 0, 0, 0, 29, 0, 32, 22, 10, 15,
+  12, 12, 0, 0, 0, 0, 42, 0, 0, 0,
+  0, 33, 26, 38, 0, 3, 31, 0, 30, 10,
+  63, 12, 0, 0, 0, 0, 0, 25, 23, 0,
+  69, 64, 0, 0, 2, 0, 4, 5, 0, 9,
+  49, 0, 33, 0, 0, 3, 60, 0, 68, 0,
+  0, 0, 8, 0, 0, 0, 49, 3, 11, 0,
+  0, 0, 0, 5, 36, 43, 0, 0, 0, 0,
+  0, 1, 24, 87, 0, 16, 36, 0, 0, 9,
+  34, 0, 19, 29, 0, 11, 0, 0, 0, 24,
+  7, 0, 0, 36, 0, 0, 0, 26, 0, 8,
+  20, 9, 0, 66, 26, 13, 0, 36, 0, 0,
+  2, 42, 7, 10, 0, 0, 26, 0, 0, 0,
+  0, 31, 20, 0, 10, 0, 10, 15, 33, 0,
+  6, 11, 0, 7, 9, 11, 0, 16, 0, 29,
+  9, 31, 0, 20, 48, 0, 63, 19, 21, 0,
+  0, 52, 14, 4, 22, 50, 0, 0, 0, 71,
+  13, 0, 0, 0, 0, 0, 0, 1, 0, 0,
+  3, 0, 0, 16, 0, 8, 57, 0, 8, 0,
+  0, 0, 0, 0, 20, 1, 25, 0, 15, 8,
+  22, 22, 74, 0, 0, 1, 31, 0, 0, 0,
+  40, 118, 28, 13, 44, 0, 0, 9, 37, 0,
+  0, 12, 0, 12, 0, 24, 0, 17, 2, 0,
+  0, 38, 0, 0, 0, 6, 0, 44, 0, 22,
+  0, 57, 17, 0, 18, 21, 0, 0, 25, 88,
+  0, 60, 0, 0, 0, 21, 0, 0, 0, 0,
+  0, 0, 0, 3, 13, 0, 39, 0, 0, 18,
+  0, 0, 44, 0, 0, 3, 0, 44, 27, 45,
+  2, 0, 52, 4, 48, 24, 64, 0, 0, 0,
+  0, 16, 0, 45, 3, 2, 31, 57, 0, 0,
+  0, 0, 0, 0, 0, 10, 30, 7, 17, 0,
+  0, 0, 33, 0, 43, 0, 0, 0, 30, 0,
+  35, 0, 54, 0, 0, 0, 0, 42, 26, 36,
+  66, 0, 0, 14, 62, 8, 0, 3, 37, 89,
+  51, 42, 59, 7, 0, 10, 42, 0, 0, 21,
+  16, 33, 0, 45, 0, 0, 4, 0, 0, 27,
+  0, 0, 0, 13, 0, 62, 0, 3, 0, 70,
+  16, 0, 32, 0, 0, 0, 21, 64, 8, 79,
+  0, 0, 0, 31, 0, 20, 0, 0, 0, 0,
+  0, 0, 49, 0, 44, 0, 0, 0, 0, 2,
+  62, 0, 0, 25, 0, 37, 50, 81, 8, 1,
+  28, 19, 26, 9, 59, 14, 0, 0, 0, 31,
+  0, 46, 17, 31, 61, 56, 0, 0, 3, 0,
+  4, 0, 0, 6, 50, 28, 14, 0, 0, 0,
+  10, 0, 0, 0, 0, 0, 7, 1, 83, 0,
+  80, 2, 9, 0, 0, 0, 10, 17, 54, 56,
+  0, 0, 20, 0, 5, 0, 53, 99, 5, 43,
+  52, 0, 0, 5, 28, 0, 0, 23, 0, 24,
+  0, 5, 0, 39, 8, 0, 0, 50, 0, 0,
+  0, 26, 0, 39, 0, 24, 13, 63, 23, 0,
+  2, 41, 6, 0, 11, 51, 3, 40, 0, 0,
+  3, 3, 2, 3, 0, 28, 5, 0, 0, 0,
+  3, 0, 53, 0, 0, 21, 8, 0, 22, 6,
+  0, 28, 0, 59, 6, 44, 0, 0, 63, 6,
+  53, 24, 33, 0, 0, 30, 0, 30, 0, 66,
+  0, 0, 0, 63, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 20, 0, 0, 6, 0, 0,
+  60, 0, 0, 0, 34, 0, 15, 0, 39, 0,
+  0, 0, 0, 16, 49, 37, 80, 0, 0, 1,
+  64, 3, 2, 0, 54, 91, 27, 51, 45, 0,
+  0, 9, 23, 0, 0, 27, 0, 25, 0, 38,
+  0, 3, 12, 0, 0, 38, 0, 0, 0, 15,
+  0, 58, 0, 15, 0, 46, 0, 0, 33, 9,
+  0, 0, 4, 73, 21, 61, 0, 0, 0, 51,
+  0, 15, 0, 0, 0, 0, 0, 0, 58, 0,
+  53, 0, 0, 0, 0, 25, 36, 0, 0, 19,
+  0, 23, 49, 49, 13, 0, 41, 40, 36, 29,
+  68, 0, 0, 29, 0, 26, 0, 29, 0, 0,
+  3, 71, 0, 0, 0, 0, 0, 0, 0, 17,
+  24, 30, 27, 0, 0, 0, 28, 0, 19, 0,
+  0, 0, 24, 0, 70, 0, 63, 3, 0, 0,
+  0, 17, 93, 43, 53, 0, 0, 8, 55, 26,
+  0, 0, 17, 57, 20, 55, 57, 27, 0, 29,
+  14, 0, 0, 5, 16, 11, 6, 56, 0, 0,
+  0, 0, 0, 8, 0, 0, 0, 41, 0, 41,
+  0, 0, 0, 42, 0, 5, 36, 0, 0, 0,
+  2, 40, 0, 36, 0, 0, 0, 42, 0, 17,
+  0, 0, 0, 0, 0, 0, 82, 0, 42, 17,
+  0, 0, 1, 48, 33, 0, 0, 61, 0, 0,
+  38, 68, 6, 58, 20, 52, 28, 25, 45, 0,
+  0, 24, 0, 24, 0, 8, 0, 6, 4, 57,
+  8, 0, 0, 0, 0, 2, 0, 5, 16, 36,
+  9, 0, 0, 0, 13, 0, 5, 0, 0, 0,
+  0, 0, 58, 0, 58, 12, 0, 0, 24, 0,
+  53, 0, 32, 0, 0, 0, 25, 0, 0, 1,
+  9, 122, 15, 0, 27, 21, 0, 8, 41, 13,
+  69, 7, 0, 0, 0, 4, 0, 0, 0, 0,
+  0, 5, 0, 0, 0, 4, 0, 26, 14, 10,
+  0, 48, 14, 0, 0, 0, 0, 0, 37, 104,
+  0, 37, 0, 0, 9, 6, 3, 0, 0, 0,
+  33, 0, 50, 22, 0, 0, 24, 22, 0, 1,
+  0, 0, 27, 0, 0, 13, 0, 41, 14, 36,
+  0, 5, 48, 0, 45, 11, 72, 0, 0, 2,
+  0, 0, 0, 25, 0, 0, 41, 57, 0, 0,
+  0, 0, 0, 0, 0, 10, 1, 0, 35, 0,
+  0, 0, 51, 0, 55, 0, 5, 0, 0, 0,
+  0, 0, 28, 1, 16, 0, 30, 0, 17, 10,
+  31, 0, 0, 0, 35, 0, 0, 3, 12, 104,
+  13, 0, 18, 16, 0, 5, 51, 0, 33, 3,
+  0, 0, 0, 16, 0, 15, 0, 9, 0, 7,
+  0, 0, 0, 0, 0, 7, 0, 12, 0, 50,
+  13, 0, 0, 0, 0, 0, 32, 102, 0, 61,
+  0, 0, 22, 15, 0, 0, 0, 0, 29, 0,
+  32, 22, 10, 15, 12, 12, 0, 0, 0, 0,
+  42, 0, 0, 0, 0, 33, 26, 38, 0, 3,
+  31, 0, 30, 10, 63, 12, 0, 0, 0, 0,
+  0, 25, 23, 0, 69, 64, 0, 0, 2, 0,
+  4, 5, 0, 9, 49, 0, 33, 0, 0, 3,
+  60, 0, 68, 0, 0, 0, 8, 0, 0, 0,
+  49, 3, 11, 0, 0, 22, 0, 46, 29, 0,
+  0, 10, 69, 0, 0, 23, 38, 83, 24, 20,
+  35, 2, 0, 9, 58, 0, 0, 0, 4, 48,
+  0, 23, 0, 8, 10, 0, 0, 43, 1, 0,
+  0, 4, 0, 24, 0, 21, 0, 69, 0, 0,
+  10, 17, 0, 0, 39, 72, 4, 92, 0, 0,
+  6, 27, 0, 37, 0, 0, 0, 0, 0, 8,
+  23, 24, 37, 0, 0, 3, 0, 0, 58, 0,
+  0, 14, 0, 39, 58, 70, 0, 0, 36, 5,
+  31, 21, 43, 20, 8, 4, 0, 16, 0, 28,
+  38, 0, 72, 48, 0, 0, 6, 0, 2, 0,
+  0, 22, 64, 11, 22, 0, 0, 9, 42, 0,
+  28, 0, 0, 0, 25, 29, 79, 0, 79, 5,
+  10, 0, 15, 8, 22, 22, 74, 0, 0, 1,
+  31, 0, 0, 0, 40, 118, 28, 13, 44, 0,
+  0, 9, 37, 0, 0, 12, 0, 12, 0, 24,
+  0, 17, 2, 0, 0, 38, 0, 0, 0, 6,
+  0, 44, 0, 22, 0, 57, 17, 0, 18, 21,
+  0, 0, 25, 88, 0, 60, 0, 0, 0, 21,
+  0, 0, 0, 0, 0, 0, 0, 3, 13, 0,
+  39, 0, 0, 18, 0, 0, 44, 0, 0, 3,
+  0, 44, 27, 45, 2, 0, 52, 4, 48, 24,
+  64, 0, 0, 0, 0, 16, 0, 45, 3, 2,
+  31, 57, 0, 0, 0, 0, 0, 0, 0, 10,
+  30, 7, 17, 0, 0, 0, 33, 0, 43, 0,
+  0, 0, 30, 0, 35, 0, 54, 0, 0, 0,
+  0, 42, 26, 36, 66, 0, 0, 14, 62, 8,
+  0, 3, 37, 89, 51, 42, 59, 7, 0, 10,
+  42, 0, 0, 21, 16, 33, 0, 45, 0, 0,
+  4, 0, 0, 27, 0, 0, 0, 13, 0, 62,
+  0, 3, 0, 70, 16, 0, 32, 0, 0, 0,
+  21, 64, 8, 79, 0, 0, 0, 31, 0, 20,
+  0, 0, 0, 0, 0, 0, 49, 0, 44, 0,
+  0, 0, 0, 2, 62, 0, 0, 25, 0, 37,
+  50, 81, 8, 1, 28, 19, 26, 9, 59, 14,
+  0, 0, 0, 31, 0, 46, 17, 31, 61, 56,
+  0, 0, 3, 0, 4, 0, 0, 6, 50, 28,
+  14, 0, 0, 0, 10, 0, 0, 0, 0, 0,
+  7, 1, 83, 0, 80, 2, 9, 0, 0, 25,
+  11, 47, 41, 0, 0, 5, 47, 1, 0, 16,
+  5, 75, 19, 28, 49, 26, 0, 33, 25, 0,
+  0, 0, 18, 25, 0, 34, 0, 0, 0, 0,
+  0, 42, 0, 0, 0, 16, 0, 27, 0, 0,
+  0, 56, 0, 7, 36, 0, 0, 0, 0, 20,
+  0, 61, 0, 0, 3, 18, 0, 21, 2, 0,
+  0, 0, 0, 0, 62, 6, 75, 21, 0, 0,
+  9, 9, 54, 0, 0, 53, 0, 0, 29, 74,
+  8, 11, 30, 30, 27, 34, 17, 0, 0, 29,
+  0, 0, 22, 13, 14, 0, 41, 57, 0, 6,
+  0, 0, 3, 28, 0, 7, 12, 5, 0, 0,
+  0, 6, 0, 0, 0, 0, 0, 0, 0, 0,
+  32, 0, 54, 11, 27, 0, 0, 16, 49, 37,
+  80, 0, 0, 1, 64, 3, 2, 0, 54, 91,
+  27, 51, 45, 0, 0, 9, 23, 0, 0, 27,
+  0, 25, 0, 38, 0, 3, 12, 0, 0, 38,
+  0, 0, 0, 15, 0, 58, 0, 15, 0, 46,
+  0, 0, 33, 9, 0, 0, 4, 73, 21, 61,
+  0, 0, 0, 51, 0, 15, 0, 0, 0, 0,
+  0, 0, 58, 0, 53, 0, 0, 0, 0, 25,
+  36, 0, 0, 19, 0, 23, 49, 49, 13, 0,
+  41, 40, 36, 29, 68, 0, 0, 29, 0, 26,
+  0, 29, 0, 0, 3, 71, 0, 0, 0, 0,
+  0, 0, 0, 17, 24, 30, 27, 0, 0, 0,
+  28, 0, 19, 0, 0, 0, 24, 0, 70, 0,
+  63, 3, 0, 0, 0, 17, 93, 43, 53, 0,
+  0, 8, 55, 26, 0, 0, 17, 57, 20, 55,
+  57, 27, 0, 29, 14, 0, 0, 5, 16, 11,
+  6, 56, 0, 0, 0, 0, 0, 8, 0, 0,
+  0, 41, 0, 41, 0, 0, 0, 42, 0, 5,
+  36, 0, 0, 0, 2, 40, 0, 36, 0, 0,
+  0, 42, 0, 17, 0, 0, 0, 0, 0, 0,
+  82, 0, 42, 17, 0, 0, 1, 48, 33, 0,
+  0, 61, 0, 0, 38, 68, 6, 58, 20, 52,
+  28, 25, 45, 0, 0, 24, 0, 24, 0, 8,
+  0, 6, 4, 57, 8, 0, 0, 0, 0, 2,
+  0, 5, 16, 36, 9, 0, 0, 0, 13, 0,
+  5, 0, 0, 0, 0, 0, 58, 0, 58, 12,
+  0, 0, 0, 24, 81, 40, 49, 0, 0, 0,
+  33, 2, 0, 17, 6, 77, 0, 0, 23, 56,
+  0, 52, 2, 0, 2, 1, 41, 13, 0, 29,
+  0, 0, 0, 10, 0, 43, 0, 0, 0, 63,
+  12, 17, 0, 0, 3, 48, 0, 11, 71, 0,
+  0, 0, 6, 7, 0, 21, 0, 0, 0, 19,
+  2, 14, 27, 0, 4, 0, 42, 0, 75, 3,
+  41, 71, 0, 0, 6, 9, 38, 0, 0, 42,
+  14, 0, 7, 92, 0, 60, 38, 46, 56, 57,
+  34, 0, 0, 15, 0, 1, 11, 17, 0, 0,
+  0, 26, 10, 3, 0, 0, 0, 39, 0, 3,
+  0, 23, 0, 0, 0, 14, 4, 15, 2, 36,
+  0, 0, 0, 0, 0, 0, 48, 33, 15, 0,
+  30, 0, 17, 10, 31, 0, 0, 0, 35, 0,
+  0, 3, 12, 104, 13, 0, 18, 16, 0, 5,
+  51, 0, 33, 3, 0, 0, 0, 16, 0, 15,
+  0, 9, 0, 7, 0, 0, 0, 0, 0, 7,
+  0, 12, 0, 50, 13, 0, 0, 0, 0, 0,
+  32, 102, 0, 61, 0, 0, 22, 15, 0, 0,
+  0, 0, 29, 0, 32, 22, 10, 15, 12, 12,
+  0, 0, 0, 0, 42, 0, 0, 0, 0, 33,
+  26, 38, 0, 3, 31, 0, 30, 10, 63, 12,
+  0, 0, 0, 0, 0, 25, 23, 0, 69, 64,
+  0, 0, 2, 0, 4, 5, 0, 9, 49, 0,
+  33, 0, 0, 3, 60, 0, 68, 0, 0, 0,
+  8, 0, 0, 0, 49, 3, 11, 0, 0, 22,
+  0, 46, 29, 0, 0, 10, 69, 0, 0, 23,
+  38, 83, 24, 20, 35, 2, 0, 9, 58, 0,
+  0, 0, 4, 48, 0, 23, 0, 8, 10, 0,
+  0, 43, 1, 0, 0, 4, 0, 24, 0, 21,
+  0, 69, 0, 0, 10, 17, 0, 0, 39, 72,
+  4, 92, 0, 0, 6, 27, 0, 37, 0, 0,
+  0, 0, 0, 8, 23, 24, 37, 0, 0, 3,
+  0, 0, 58, 0, 0, 14, 0, 39, 58, 70,
+  0, 0, 36, 5, 31, 21, 43, 20, 8, 4,
+  0, 16, 0, 28, 38, 0, 72, 48, 0, 0,
+  6, 0, 2, 0, 0, 22, 64, 11, 22, 0,
+  0, 9, 42, 0, 28, 0, 0, 0, 25, 29,
+  79, 0, 79, 5, 10, 0, 0, 19, 0, 49,
+  12, 0, 0, 25, 85, 2, 1, 7, 23, 85,
+  32, 34, 52, 0, 5, 0, 23, 0, 0, 0,
+  0, 25, 0, 34, 0, 0, 0, 0, 0, 25,
+  0, 0, 0, 0, 0, 23, 0, 6, 0, 46,
+  0, 0, 22, 18, 0, 0, 24, 75, 20, 83,
+  0, 0, 0, 46, 0, 19, 0, 0, 0, 0,
+  0, 30, 41, 0, 59, 0, 0, 0, 0, 12,
+  50, 0, 0, 9, 0, 32, 59, 63, 9, 0,
+  17, 31, 16, 61, 46, 0, 20, 36, 0, 0,
+  0, 9, 42, 0, 48, 63, 0, 0, 0, 0,
+  9, 0, 0, 19, 28, 6, 15, 0, 0, 0,
+  28, 0, 22, 0, 0, 0, 15, 1, 73, 0,
+  78, 3, 7, 0, 0, 42, 26, 36, 66, 0,
+  0, 14, 62, 8, 0, 3, 37, 89, 51, 42,
+  59, 7, 0, 10, 42, 0, 0, 21, 16, 33,
+  0, 45, 0, 0, 4, 0, 0, 27, 0, 0,
+  0, 13, 0, 62, 0, 3, 0, 70, 16, 0,
+  32, 0, 0, 0, 21, 64, 8, 79, 0, 0,
+  0, 31, 0, 20, 0, 0, 0, 0, 0, 0,
+  49, 0, 44, 0, 0, 0, 0, 2, 62, 0,
+  0, 25, 0, 37, 50, 81, 8, 1, 28, 19,
+  26, 9, 59, 14, 0, 0, 0, 31, 0, 46,
+  17, 31, 61, 56, 0, 0, 3, 0, 4, 0,
+  0, 6, 50, 28, 14, 0, 0, 0, 10, 0,
+  0, 0, 0, 0, 7, 1, 83, 0, 80, 2,
+  9, 0, 0, 25, 11, 47, 41, 0, 0, 5,
+  47, 1, 0, 16, 5, 75, 19, 28, 49, 26,
+  0, 33, 25, 0, 0, 0, 18, 25, 0, 34,
+  0, 0, 0, 0, 0, 42, 0, 0, 0, 16,
+  0, 27, 0, 0, 0, 56, 0, 7, 36, 0,
+  0, 0, 0, 20, 0, 61, 0, 0, 3, 18,
+  0, 21, 2, 0, 0, 0, 0, 0, 62, 6,
+  75, 21, 0, 0, 9, 9, 54, 0, 0, 53,
+  0, 0, 29, 74, 8, 11, 30, 30, 27, 34,
+  17, 0, 0, 29, 0, 0, 22, 13, 14, 0,
+  41, 57, 0, 6, 0, 0, 3, 28, 0, 7,
+  12, 5, 0, 0, 0, 6, 0, 0, 0, 0,
+  0, 0, 0, 0, 32, 0, 54, 11, 27, 0,
+  0, 0, 0, 70, 0, 0, 0, 2, 33, 0,
+  0, 0, 0, 43, 0, 6, 22, 39, 0, 28,
+  7, 0, 9, 0, 0, 0, 28, 31, 0, 0,
+  0, 0, 0, 29, 0, 0, 2, 27, 0, 0,
+  0, 0, 0, 6, 0, 5, 36, 29, 18, 0,
+  0, 0, 0, 40, 0, 15, 23, 36, 0, 10,
+  8, 17, 0, 4, 56, 0, 56, 30, 68, 85,
+  5, 0, 19, 21, 32, 0, 0, 9, 20, 0,
+  0, 41, 10, 0, 11, 39, 17, 55, 0, 0,
+  0, 81, 0, 0, 54, 0, 6, 0, 21, 50,
+  24, 33, 0, 0, 0, 40, 0, 5, 0, 0,
+  0, 0, 0, 0, 7, 0, 7, 0, 0, 0,
+  0, 0, 0, 0, 0, 21, 20, 0, 0, 17,
+  93, 43, 53, 0, 0, 8, 55, 26, 0, 0,
+  17, 57, 20, 55, 57, 27, 0, 29, 14, 0,
+  0, 5, 16, 11, 6, 56, 0, 0, 0, 0,
+  0, 8, 0, 0, 0, 41, 0, 41, 0, 0,
+  0, 42, 0, 5, 36, 0, 0, 0, 2, 40,
+  0, 36, 0, 0, 0, 42, 0, 17, 0, 0,
+  0, 0, 0, 0, 82, 0, 42, 17, 0, 0,
+  1, 48, 33, 0, 0, 61, 0, 0, 38, 68,
+  6, 58, 20, 52, 28, 25, 45, 0, 0, 24,
+  0, 24, 0, 8, 0, 6, 4, 57, 8, 0,
+  0, 0, 0, 2, 0, 5, 16, 36, 9, 0,
+  0, 0, 13, 0, 5, 0, 0, 0, 0, 0,
+  58, 0, 58, 12, 0, 0, 0, 24, 81, 40,
+  49, 0, 0, 0, 33, 2, 0, 17, 6, 77,
+  0, 0, 23, 56, 0, 52, 2, 0, 2, 1,
+  41, 13, 0, 29, 0, 0, 0, 10, 0, 43,
+  0, 0, 0, 63, 12, 17, 0, 0, 3, 48,
+  0, 11, 71, 0, 0, 0, 6, 7, 0, 21,
+  0, 0, 0, 19, 2, 14, 27, 0, 4, 0,
+  42, 0, 75, 3, 41, 71, 0, 0, 6, 9,
+  38, 0, 0, 42, 14, 0, 7, 92, 0, 60,
+  38, 46, 56, 57, 34, 0, 0, 15, 0, 1,
+  11, 17, 0, 0, 0, 26, 10, 3, 0, 0,
+  0, 39, 0, 3, 0, 23, 0, 0, 0, 14,
+  4, 15, 2, 36, 0, 0, 0, 0, 0, 0,
+  48, 33, 15, 0, 8, 39, 11, 59, 13, 4,
+  0, 0, 0, 0, 0, 12, 0, 75, 0, 0,
+  1, 65, 7, 50, 0, 0, 29, 0, 35, 15,
+  32, 17, 0, 0, 0, 20, 0, 56, 0, 0,
+  11, 51, 0, 0, 0, 0, 4, 4, 0, 24,
+  76, 35, 6, 0, 0, 0, 0, 0, 0, 0,
+  3, 20, 4, 30, 67, 17, 10, 0, 41, 0,
+  49, 47, 42, 68, 0, 0, 19, 0, 53, 0,
+  0, 1, 65, 0, 0, 87, 0, 24, 26, 31,
+  55, 42, 0, 0, 0, 24, 7, 17, 41, 0,
+  0, 12, 27, 0, 0, 75, 0, 0, 0, 65,
+  4, 0, 0, 51, 0, 13, 0, 12, 0, 43,
+  0, 36, 11, 0, 10, 5, 0, 0, 0, 42,
+  34, 0, 0, 22, 0, 46, 29, 0, 0, 10,
+  69, 0, 0, 23, 38, 83, 24, 20, 35, 2,
+  0, 9, 58, 0, 0, 0, 4, 48, 0, 23,
+  0, 8, 10, 0, 0, 43, 1, 0, 0, 4,
+  0, 24, 0, 21, 0, 69, 0, 0, 10, 17,
+  0, 0, 39, 72, 4, 92, 0, 0, 6, 27,
+  0, 37, 0, 0, 0, 0, 0, 8, 23, 24,
+  37, 0, 0, 3, 0, 0, 58, 0, 0, 14,
+  0, 39, 58, 70, 0, 0, 36, 5, 31, 21,
+  43, 20, 8, 4, 0, 16, 0, 28, 38, 0,
+  72, 48, 0, 0, 6, 0, 2, 0, 0, 22,
+  64, 11, 22, 0, 0, 9, 42, 0, 28, 0,
+  0, 0, 25, 29, 79, 0, 79, 5, 10, 0,
+  0, 19, 0, 49, 12, 0, 0, 25, 85, 2,
+  1, 7, 23, 85, 32, 34, 52, 0, 5, 0,
+  23, 0, 0, 0, 0, 25, 0, 34, 0, 0,
+  0, 0, 0, 25, 0, 0, 0, 0, 0, 23,
+  0, 6, 0, 46, 0, 0, 22, 18, 0, 0,
+  24, 75, 20, 83, 0, 0, 0, 46, 0, 19,
+  0, 0, 0, 0, 0, 30, 41, 0, 59, 0,
+  0, 0, 0, 12, 50, 0, 0, 9, 0, 32,
+  59, 63, 9, 0, 17, 31, 16, 61, 46, 0,
+  20, 36, 0, 0, 0, 9, 42, 0, 48, 63,
+  0, 0, 0, 0, 9, 0, 0, 19, 28, 6,
+  15, 0, 0, 0, 28, 0, 22, 0, 0, 0,
+  15, 1, 73, 0, 78, 3, 7, 0, 0, 4,
+  2, 46, 13, 0, 0, 32, 107, 4, 2, 0,
+  4, 83, 44, 32, 46, 4, 0, 0, 3, 0,
+  0, 10, 0, 0, 0, 35, 0, 0, 0, 0,
+  0, 15, 0, 0, 0, 0, 0, 24, 0, 0,
+  0, 32, 0, 0, 49, 17, 0, 0, 0, 80,
+  25, 73, 0, 0, 0, 50, 0, 3, 0, 0,
+  0, 0, 0, 35, 49, 0, 61, 9, 0, 0,
+  3, 17, 57, 9, 0, 0, 0, 10, 48, 46,
+  9, 0, 7, 32, 17, 79, 43, 0, 37, 35,
+  0, 0, 0, 5, 31, 0, 49, 67, 11, 1,
+  0, 0, 15, 0, 0, 19, 8, 3, 5, 0,
+  0, 0, 19, 0, 26, 0, 0, 0, 5, 0,
+  65, 0, 62, 0, 2, 0, 0, 25, 11, 47,
+  41, 0, 0, 5, 47, 1, 0, 16, 5, 75,
+  19, 28, 49, 26, 0, 33, 25, 0, 0, 0,
+  18, 25, 0, 34, 0, 0, 0, 0, 0, 42,
+  0, 0, 0, 16, 0, 27, 0, 0, 0, 56,
+  0, 7, 36, 0, 0, 0, 0, 20, 0, 61,
+  0, 0, 3, 18, 0, 21, 2, 0, 0, 0,
+  0, 0, 62, 6, 75, 21, 0, 0, 9, 9,
+  54, 0, 0, 53, 0, 0, 29, 74, 8, 11,
+  30, 30, 27, 34, 17, 0, 0, 29, 0, 0,
+  22, 13, 14, 0, 41, 57, 0, 6, 0, 0,
+  3, 28, 0, 7, 12, 5, 0, 0, 0, 6,
+  0, 0, 0, 0, 0, 0, 0, 0, 32, 0,
+  54, 11, 27, 0, 0, 0, 0, 70, 0, 0,
+  0, 2, 33, 0, 0, 0, 0, 43, 0, 6,
+  22, 39, 0, 28, 7, 0, 9, 0, 0, 0,
+  28, 31, 0, 0, 0, 0, 0, 29, 0, 0,
+  2, 27, 0, 0, 0, 0, 0, 6, 0, 5,
+  36, 29, 18, 0, 0, 0, 0, 40, 0, 15,
+  23, 36, 0, 10, 8, 17, 0, 4, 56, 0,
+  56, 30, 68, 85, 5, 0, 19, 21, 32, 0,
+  0, 9, 20, 0, 0, 41, 10, 0, 11, 39,
+  17, 55, 0, 0, 0, 81, 0, 0, 54, 0,
+  6, 0, 21, 50, 24, 33, 0, 0, 0, 40,
+  0, 5, 0, 0, 0, 0, 0, 0, 7, 0,
+  7, 0, 0, 0, 0, 0, 0, 0, 0, 21,
+  20, 0, 0, 8, 0, 102, 1, 0, 0, 14,
+  69, 27, 0, 0, 0, 1, 0, 66, 27, 37,
+  0, 17, 6, 0, 0, 0, 2, 0, 52, 58,
+  12, 0, 0, 0, 14, 27, 0, 0, 6, 45,
+  0, 0, 2, 0, 0, 11, 0, 17, 56, 34,
+  0, 0, 0, 0, 2, 38, 0, 25, 6, 68,
+  0, 37, 0, 16, 0, 2, 22, 0, 50, 18,
+  67, 47, 0, 0, 22, 50, 27, 21, 0, 3,
+  14, 0, 29, 40, 11, 0, 0, 47, 18, 59,
+  13, 0, 37, 101, 0, 22, 37, 0, 12, 0,
+  20, 34, 37, 0, 0, 0, 4, 0, 0, 14,
+  0, 6, 0, 13, 0, 0, 10, 0, 0, 0,
+  0, 0, 4, 0, 56, 0, 21, 28, 9, 0,
+  0, 24, 81, 40, 49, 0, 0, 0, 33, 2,
+  0, 17, 6, 77, 0, 0, 23, 56, 0, 52,
+  2, 0, 2, 1, 41, 13, 0, 29, 0, 0,
+  0, 10, 0, 43, 0, 0, 0, 63, 12, 17,
+  0, 0, 3, 48, 0, 11, 71, 0, 0, 0,
+  6, 7, 0, 21, 0, 0, 0, 19, 2, 14,
+  27, 0, 4, 0, 42, 0, 75, 3, 41, 71,
+  0, 0, 6, 9, 38, 0, 0, 42, 14, 0,
+  7, 92, 0, 60, 38, 46, 56, 57, 34, 0,
+  0, 15, 0, 1, 11, 17, 0, 0, 0, 26,
+  10, 3, 0, 0, 0, 39, 0, 3, 0, 23,
+  0, 0, 0, 14, 4, 15, 2, 36, 0, 0,
+  0, 0, 0, 0, 48, 33, 15, 0, 8, 39,
+  11, 59, 13, 4, 0, 0, 0, 0, 0, 12,
+  0, 75, 0, 0, 1, 65, 7, 50, 0, 0,
+  29, 0, 35, 15, 32, 17, 0, 0, 0, 20,
+  0, 56, 0, 0, 11, 51, 0, 0, 0, 0,
+  4, 4, 0, 24, 76, 35, 6, 0, 0, 0,
+  0, 0, 0, 0, 3, 20, 4, 30, 67, 17,
+  10, 0, 41, 0, 49, 47, 42, 68, 0, 0,
+  19, 0, 53, 0, 0, 1, 65, 0, 0, 87,
+  0, 24, 26, 31, 55, 42, 0, 0, 0, 24,
+  7, 17, 41, 0, 0, 12, 27, 0, 0, 75,
+  0, 0, 0, 65, 4, 0, 0, 51, 0, 13,
+  0, 12, 0, 43, 0, 36, 11, 0, 10, 5,
+  0, 0, 0, 42, 34, 0, 17, 15, 0, 79,
+  44, 0, 0, 0, 5, 0, 0, 0, 0, 55,
+  0, 0, 0, 35, 37, 28, 4, 0, 0, 0,
+  32, 0, 63, 0, 0, 0, 16, 16, 0, 50,
+  0, 12, 49, 23, 0, 0, 6, 0, 13, 0,
+  0, 14, 60, 14, 0, 0, 0, 0, 0, 1,
+  0, 30, 1, 49, 0, 8, 60, 30, 25, 6,
+  43, 0, 30, 41, 42, 56, 0, 0, 32, 5,
+  13, 0, 0, 18, 85, 0, 0, 46, 31, 7,
+  39, 35, 18, 32, 4, 0, 0, 59, 8, 21,
+  49, 0, 0, 0, 34, 1, 3, 39, 0, 0,
+  0, 65, 0, 8, 0, 14, 0, 11, 0, 5,
+  35, 42, 0, 21, 0, 9, 13, 0, 0, 0,
+  0, 31, 11, 3, 0, 19, 0, 49, 12, 0,
+  0, 25, 85, 2, 1, 7, 23, 85, 32, 34,
+  52, 0, 5, 0, 23, 0, 0, 0, 0, 25,
+  0, 34, 0, 0, 0, 0, 0, 25, 0, 0,
+  0, 0, 0, 23, 0, 6, 0, 46, 0, 0,
+  22, 18, 0, 0, 24, 75, 20, 83, 0, 0,
+  0, 46, 0, 19, 0, 0, 0, 0, 0, 30,
+  41, 0, 59, 0, 0, 0, 0, 12, 50, 0,
+  0, 9, 0, 32, 59, 63, 9, 0, 17, 31,
+  16, 61, 46, 0, 20, 36, 0, 0, 0, 9,
+  42, 0, 48, 63, 0, 0, 0, 0, 9, 0,
+  0, 19, 28, 6, 15, 0, 0, 0, 28, 0,
+  22, 0, 0, 0, 15, 1, 73, 0, 78, 3,
+  7, 0, 0, 4, 2, 46, 13, 0, 0, 32,
+  107, 4, 2, 0, 4, 83, 44, 32, 46, 4,
+  0, 0, 3, 0, 0, 10, 0, 0, 0, 35,
+  0, 0, 0, 0, 0, 15, 0, 0, 0, 0,
+  0, 24, 0, 0, 0, 32, 0, 0, 49, 17,
+  0, 0, 0, 80, 25, 73, 0, 0, 0, 50,
+  0, 3, 0, 0, 0, 0, 0, 35, 49, 0,
+  61, 9, 0, 0, 3, 17, 57, 9, 0, 0,
+  0, 10, 48, 46, 9, 0, 7, 32, 17, 79,
+  43, 0, 37, 35, 0, 0, 0, 5, 31, 0,
+  49, 67, 11, 1, 0, 0, 15, 0, 0, 19,
+  8, 3, 5, 0, 0, 0, 19, 0, 26, 0,
+  0, 0, 5, 0, 65, 0, 62, 0, 2, 0,
+  0, 37, 0, 44, 22, 0, 8, 20, 82, 0,
+  25, 11, 12, 56, 55, 36, 59, 22, 0, 12,
+  31, 0, 0, 0, 1, 27, 0, 18, 0, 0,
+  0, 0, 0, 37, 0, 0, 0, 0, 0, 14,
+  0, 0, 0, 28, 0, 0, 38, 1, 0, 0,
+  0, 23, 0, 87, 0, 0, 4, 32, 0, 38,
+  0, 0, 0, 0, 0, 27, 62, 7, 79, 0,
+  0, 0, 0, 8, 73, 0, 0, 19, 6, 1,
+  28, 74, 0, 0, 22, 50, 31, 43, 10, 0,
+  10, 37, 0, 20, 0, 33, 31, 10, 59, 36,
+  0, 0, 0, 0, 17, 0, 0, 13, 9, 1,
+  0, 0, 0, 0, 9, 0, 0, 0, 0, 0,
+  0, 23, 74, 0, 31, 0, 36, 0, 0, 0,
+  0, 70, 0, 0, 0, 2, 33, 0, 0, 0,
+  0, 43, 0, 6, 22, 39, 0, 28, 7, 0,
+  9, 0, 0, 0, 28, 31, 0, 0, 0, 0,
+  0, 29, 0, 0, 2, 27, 0, 0, 0, 0,
+  0, 6, 0, 5, 36, 29, 18, 0, 0, 0,
+  0, 40, 0, 15, 23, 36, 0, 10, 8, 17,
+  0, 4, 56, 0, 56, 30, 68, 85, 5, 0,
+  19, 21, 32, 0, 0, 9, 20, 0, 0, 41,
+  10, 0, 11, 39, 17, 55, 0, 0, 0, 81,
+  0, 0, 54, 0, 6, 0, 21, 50, 24, 33,
+  0, 0, 0, 40, 0, 5, 0, 0, 0, 0,
+  0, 0, 7, 0, 7, 0, 0, 0, 0, 0,
+  0, 0, 0, 21, 20, 0, 0, 8, 0, 102,
+  1, 0, 0, 14, 69, 27, 0, 0, 0, 1,
+  0, 66, 27, 37, 0, 17, 6, 0, 0, 0,
+  2, 0, 52, 58, 12, 0, 0, 0, 14, 27,
+  0, 0, 6, 45, 0, 0, 2, 0, 0, 11,
+  0, 17, 56, 34, 0, 0, 0, 0, 2, 38,
+  0, 25, 6, 68, 0, 37, 0, 16, 0, 2,
+  22, 0, 50, 18, 67, 47, 0, 0, 22, 50,
+  27, 21, 0, 3, 14, 0, 29, 40, 11, 0,
+  0, 47, 18, 59, 13, 0, 37, 101, 0, 22,
+  37, 0, 12, 0, 20, 34, 37, 0, 0, 0,
+  4, 0, 0, 14, 0, 6, 0, 13, 0, 0,
+  10, 0, 0, 0, 0, 0, 4, 0, 56, 0,
+  21, 28, 9, 0, 0, 56, 17, 88, 0, 0,
+  31, 9, 81, 2, 5, 0, 0, 6, 2, 91,
+  38, 27, 0, 41, 0, 0, 0, 0, 13, 0,
+  37, 42, 0, 0, 0, 2, 9, 19, 0, 0,
+  16, 37, 0, 0, 16, 0, 0, 26, 0, 16,
+  70, 3, 0, 0, 0, 0, 0, 52, 0, 0,
+  15, 62, 0, 58, 0, 17, 0, 7, 22, 0,
+  63, 23, 93, 25, 0, 0, 31, 35, 54, 3,
+  0, 8, 19, 0, 32, 63, 17, 6, 25, 64,
+  9, 35, 25, 0, 32, 85, 0, 27, 5, 0,
+  11, 0, 41, 54, 31, 0, 0, 0, 12, 3,
+  0, 31, 0, 0, 0, 17, 0, 0, 32, 0,
+  0, 0, 0, 0, 0, 0, 65, 0, 25, 16,
+  30, 0, 8, 39, 11, 59, 13, 4, 0, 0,
+  0, 0, 0, 12, 0, 75, 0, 0, 1, 65,
+  7, 50, 0, 0, 29, 0, 35, 15, 32, 17,
+  0, 0, 0, 20, 0, 56, 0, 0, 11, 51,
+  0, 0, 0, 0, 4, 4, 0, 24, 76, 35,
+  6, 0, 0, 0, 0, 0, 0, 0, 3, 20,
+  4, 30, 67, 17, 10, 0, 41, 0, 49, 47,
+  42, 68, 0, 0, 19, 0, 53, 0, 0, 1,
+  65, 0, 0, 87, 0, 24, 26, 31, 55, 42,
+  0, 0, 0, 24, 7, 17, 41, 0, 0, 12,
+  27, 0, 0, 75, 0, 0, 0, 65, 4, 0,
+  0, 51, 0, 13, 0, 12, 0, 43, 0, 36,
+  11, 0, 10, 5, 0, 0, 0, 42, 34, 0,
+  17, 15, 0, 79, 44, 0, 0, 0, 5, 0,
+  0, 0, 0, 55, 0, 0, 0, 35, 37, 28,
+  4, 0, 0, 0, 32, 0, 63, 0, 0, 0,
+  16, 16, 0, 50, 0, 12, 49, 23, 0, 0,
+  6, 0, 13, 0, 0, 14, 60, 14, 0, 0,
+  0, 0, 0, 1, 0, 30, 1, 49, 0, 8,
+  60, 30, 25, 6, 43, 0, 30, 41, 42, 56,
+  0, 0, 32, 5, 13, 0, 0, 18, 85, 0,
+  0, 46, 31, 7, 39, 35, 18, 32, 4, 0,
+  0, 59, 8, 21, 49, 0, 0, 0, 34, 1,
+  3, 39, 0, 0, 0, 65, 0, 8, 0, 14,
+  0, 11, 0, 5, 35, 42, 0, 21, 0, 9,
+  13, 0, 0, 0, 0, 31, 11, 3, 0, 52,
+  10, 53, 45, 0, 0, 0, 8, 0, 0, 0,
+  0, 74, 0, 0, 0, 0, 17, 52, 3, 0,
+  18, 7, 0, 0, 31, 0, 0, 0, 23, 43,
+  0, 29, 0, 19, 52, 39, 0, 0, 56, 0,
+  8, 9, 0, 0, 56, 49, 5, 0, 28, 0,
+  0, 0, 24, 0, 37, 43, 61, 0, 18, 41,
+  48, 0, 82, 16, 8, 42, 39, 40, 0, 0,
+  47, 0, 25, 13, 0, 0, 67, 0, 0, 21,
+  0, 18, 51, 32, 4, 15, 16, 0, 0, 74,
+  15, 0, 13, 0, 0, 0, 53, 45, 10, 84,
+  0, 0, 0, 82, 0, 44, 0, 0, 0, 0,
+  0, 19, 65, 68, 0, 14, 8, 17, 0, 0,
+  0, 0, 0, 9, 3, 4, 0, 4, 2, 46,
+  13, 0, 0, 32, 107, 4, 2, 0, 4, 83,
+  44, 32, 46, 4, 0, 0, 3, 0, 0, 10,
+  0, 0, 0, 35, 0, 0, 0, 0, 0, 15,
+  0, 0, 0, 0, 0, 24, 0, 0, 0, 32,
+  0, 0, 49, 17, 0, 0, 0, 80, 25, 73,
+  0, 0, 0, 50, 0, 3, 0, 0, 0, 0,
+  0, 35, 49, 0, 61, 9, 0, 0, 3, 17,
+  57, 9, 0, 0, 0, 10, 48, 46, 9, 0,
+  7, 32, 17, 79, 43, 0, 37, 35, 0, 0,
+  0, 5, 31, 0, 49, 67, 11, 1, 0, 0,
+  15, 0, 0, 19, 8, 3, 5, 0, 0, 0,
+  19, 0, 26, 0, 0, 0, 5, 0, 65, 0,
+  62, 0, 2, 0, 0, 37, 0, 44, 22, 0,
+  8, 20, 82, 0, 25, 11, 12, 56, 55, 36,
+  59, 22, 0, 12, 31, 0, 0, 0, 1, 27,
+  0, 18, 0, 0, 0, 0, 0, 37, 0, 0,
+  0, 0, 0, 14, 0, 0, 0, 28, 0, 0,
+  38, 1, 0, 0, 0, 23, 0, 87, 0, 0,
+  4, 32, 0, 38, 0, 0, 0, 0, 0, 27,
+  62, 7, 79, 0, 0, 0, 0, 8, 73, 0,
+  0, 19, 6, 1, 28, 74, 0, 0, 22, 50,
+  31, 43, 10, 0, 10, 37, 0, 20, 0, 33,
+  31, 10, 59, 36, 0, 0, 0, 0, 17, 0,
+  0, 13, 9, 1, 0, 0, 0, 0, 9, 0,
+  0, 0, 0, 0, 0, 23, 74, 0, 31, 0,
+  36, 0, 0, 74, 18, 48, 36, 0, 9, 0,
+  60, 0, 36, 0, 0, 63, 66, 33, 53, 1,
+  1, 40, 5, 0, 0, 0, 0, 29, 0, 0,
+  0, 0, 0, 0, 0, 33, 0, 0, 0, 0,
+  0, 13, 0, 0, 0, 7, 0, 0, 40, 19,
+  0, 0, 0, 0, 0, 107, 0, 0, 12, 52,
+  0, 31, 0, 27, 0, 0, 0, 19, 66, 8,
+  85, 0, 0, 0, 0, 0, 65, 0, 0, 12,
+  15, 13, 23, 55, 0, 0, 38, 70, 22, 57,
+  6, 0, 10, 41, 0, 20, 0, 27, 34, 9,
+  25, 65, 0, 0, 0, 0, 11, 0, 0, 0,
+  15, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 46, 0, 22, 0, 42, 0,
+  0, 8, 0, 102, 1, 0, 0, 14, 69, 27,
+  0, 0, 0, 1, 0, 66, 27, 37, 0, 17,
+  6, 0, 0, 0, 2, 0, 52, 58, 12, 0,
+  0, 0, 14, 27, 0, 0, 6, 45, 0, 0,
+  2, 0, 0, 11, 0, 17, 56, 34, 0, 0,
+  0, 0, 2, 38, 0, 25, 6, 68, 0, 37,
+  0, 16, 0, 2, 22, 0, 50, 18, 67, 47,
+  0, 0, 22, 50, 27, 21, 0, 3, 14, 0,
+  29, 40, 11, 0, 0, 47, 18, 59, 13, 0,
+  37, 101, 0, 22, 37, 0, 12, 0, 20, 34,
+  37, 0, 0, 0, 4, 0, 0, 14, 0, 6,
+  0, 13, 0, 0, 10, 0, 0, 0, 0, 0,
+  4, 0, 56, 0, 21, 28, 9, 0, 0, 56,
+  17, 88, 0, 0, 31, 9, 81, 2, 5, 0,
+  0, 6, 2, 91, 38, 27, 0, 41, 0, 0,
+  0, 0, 13, 0, 37, 42, 0, 0, 0, 2,
+  9, 19, 0, 0, 16, 37, 0, 0, 16, 0,
+  0, 26, 0, 16, 70, 3, 0, 0, 0, 0,
+  0, 52, 0, 0, 15, 62, 0, 58, 0, 17,
+  0, 7, 22, 0, 63, 23, 93, 25, 0, 0,
+  31, 35, 54, 3, 0, 8, 19, 0, 32, 63,
+  17, 6, 25, 64, 9, 35, 25, 0, 32, 85,
+  0, 27, 5, 0, 11, 0, 41, 54, 31, 0,
+  0, 0, 12, 3, 0, 31, 0, 0, 0, 17,
+  0, 0, 32, 0, 0, 0, 0, 0, 0, 0,
+  65, 0, 25, 16, 30, 0, 0, 28, 8, 32,
+  27, 0, 2, 0, 68, 0, 19, 0, 0, 42,
+  7, 49, 43, 15, 20, 47, 0, 0, 0, 0,
+  0, 0, 3, 32, 0, 0, 0, 6, 4, 23,
+  0, 12, 7, 21, 0, 0, 2, 0, 0, 18,
+  0, 11, 54, 50, 0, 0, 0, 0, 0, 40,
+  0, 0, 45, 53, 0, 11, 0, 42, 0, 0,
+  22, 4, 38, 14, 110, 11, 16, 0, 30, 15,
+  57, 0, 0, 0, 2, 0, 0, 18, 21, 0,
+  59, 45, 0, 63, 2, 0, 3, 85, 0, 10,
+  16, 0, 9, 0, 31, 80, 7, 29, 0, 0,
+  22, 22, 0, 19, 0, 0, 0, 25, 0, 0,
+  16, 0, 0, 0, 0, 0, 0, 0, 11, 0,
+  0, 5, 46, 8, 17, 15, 0, 79, 44, 0,
+  0, 0, 5, 0, 0, 0, 0, 55, 0, 0,
+  0, 35, 37, 28, 4, 0, 0, 0, 32, 0,
+  63, 0, 0, 0, 16, 16, 0, 50, 0, 12,
+  49, 23, 0, 0, 6, 0, 13, 0, 0, 14,
+  60, 14, 0, 0, 0, 0, 0, 1, 0, 30,
+  1, 49, 0, 8, 60, 30, 25, 6, 43, 0,
+  30, 41, 42, 56, 0, 0, 32, 5, 13, 0,
+  0, 18, 85, 0, 0, 46, 31, 7, 39, 35,
+  18, 32, 4, 0, 0, 59, 8, 21, 49, 0,
+  0, 0, 34, 1, 3, 39, 0, 0, 0, 65,
+  0, 8, 0, 14, 0, 11, 0, 5, 35, 42,
+  0, 21, 0, 9, 13, 0, 0, 0, 0, 31,
+  11, 3, 0, 52, 10, 53, 45, 0, 0, 0,
+  8, 0, 0, 0, 0, 74, 0, 0, 0, 0,
+  17, 52, 3, 0, 18, 7, 0, 0, 31, 0,
+  0, 0, 23, 43, 0, 29, 0, 19, 52, 39,
+  0, 0, 56, 0, 8, 9, 0, 0, 56, 49,
+  5, 0, 28, 0, 0, 0, 24, 0, 37, 43,
+  61, 0, 18, 41, 48, 0, 82, 16, 8, 42,
+  39, 40, 0, 0, 47, 0, 25, 13, 0, 0,
+  67, 0, 0, 21, 0, 18, 51, 32, 4, 15,
+  16, 0, 0, 74, 15, 0, 13, 0, 0, 0,
+  53, 45, 10, 84, 0, 0, 0, 82, 0, 44,
+  0, 0, 0, 0, 0, 19, 65, 68, 0, 14,
+  8, 17, 0, 0, 0, 0, 0, 9, 3, 4,
+  0, 23, 27, 4, 12, 35, 0, 0, 0, 0,
+  7, 0, 0, 120, 0, 0, 0, 0, 0, 71,
+  1, 19, 66, 22, 0, 0, 0, 5, 0, 8,
+  4, 39, 0, 29, 0, 44, 65, 31, 0, 0,
+  54, 58, 0, 12, 0, 0, 47, 155, 11, 0,
+  50, 0, 0, 0, 45, 0, 62, 10, 71, 0,
+  0, 39, 35, 0, 91, 27, 0, 65, 34, 36,
+  0, 34, 14, 0, 51, 0, 0, 0, 19, 4,
+  0, 0, 14, 6, 95, 9, 0, 30, 0, 0,
+  0, 23, 0, 0, 8, 0, 0, 0, 51, 94,
+  0, 92, 0, 0, 16, 61, 0, 33, 0, 0,
+  0, 0, 0, 0, 47, 97, 0, 7, 27, 0,
+  4, 0, 0, 0, 0, 0, 0, 77, 0, 37,
+  0, 44, 22, 0, 8, 20, 82, 0, 25, 11,
+  12, 56, 55, 36, 59, 22, 0, 12, 31, 0,
+  0, 0, 1, 27, 0, 18, 0, 0, 0, 0,
+  0, 37, 0, 0, 0, 0, 0, 14, 0, 0,
+  0, 28, 0, 0, 38, 1, 0, 0, 0, 23,
+  0, 87, 0, 0, 4, 32, 0, 38, 0, 0,
+  0, 0, 0, 27, 62, 7, 79, 0, 0, 0,
+  0, 8, 73, 0, 0, 19, 6, 1, 28, 74,
+  0, 0, 22, 50, 31, 43, 10, 0, 10, 37,
+  0, 20, 0, 33, 31, 10, 59, 36, 0, 0,
+  0, 0, 17, 0, 0, 13, 9, 1, 0, 0,
+  0, 0, 9, 0, 0, 0, 0, 0, 0, 23,
+  74, 0, 31, 0, 36, 0, 0, 74, 18, 48,
+  36, 0, 9, 0, 60, 0, 36, 0, 0, 63,
+  66, 33, 53, 1, 1, 40, 5, 0, 0, 0,
+  0, 29, 0, 0, 0, 0, 0, 0, 0, 33,
+  0, 0, 0, 0, 0, 13, 0, 0, 0, 7,
+  0, 0, 40, 19, 0, 0, 0, 0, 0, 107,
+  0, 0, 12, 52, 0, 31, 0, 27, 0, 0,
+  0, 19, 66, 8, 85, 0, 0, 0, 0, 0,
+  65, 0, 0, 12, 15, 13, 23, 55, 0, 0,
+  38, 70, 22, 57, 6, 0, 10, 41, 0, 20,
+  0, 27, 34, 9, 25, 65, 0, 0, 0, 0,
+  11, 0, 0, 0, 15, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 46, 0,
+  22, 0, 42, 0, 0, 120, 19, 74, 27, 0,
+  31, 0, 61, 0, 8, 0, 21, 27, 26, 43,
+  32, 22, 11, 48, 0, 0, 11, 13, 20, 2,
+  39, 1, 0, 0, 0, 0, 45, 5, 15, 2,
+  0, 0, 0, 0, 0, 0, 0, 21, 0, 27,
+  87, 36, 0, 0, 16, 0, 0, 39, 0, 0,
+  30, 0, 0, 50, 0, 22, 0, 0, 0, 0,
+  32, 15, 38, 0, 0, 0, 27, 0, 82, 16,
+  0, 44, 0, 0, 23, 10, 32, 10, 15, 51,
+  24, 38, 8, 39, 22, 24, 0, 47, 0, 0,
+  15, 0, 42, 41, 18, 5, 0, 0, 5, 0,
+  39, 13, 35, 22, 0, 0, 0, 45, 0, 0,
+  0, 0, 9, 0, 0, 0, 49, 0, 6, 0,
+  21, 9, 0, 56, 17, 88, 0, 0, 31, 9,
+  81, 2, 5, 0, 0, 6, 2, 91, 38, 27,
+  0, 41, 0, 0, 0, 0, 13, 0, 37, 42,
+  0, 0, 0, 2, 9, 19, 0, 0, 16, 37,
+  0, 0, 16, 0, 0, 26, 0, 16, 70, 3,
+  0, 0, 0, 0, 0, 52, 0, 0, 15, 62,
+  0, 58, 0, 17, 0, 7, 22, 0, 63, 23,
+  93, 25, 0, 0, 31, 35, 54, 3, 0, 8,
+  19, 0, 32, 63, 17, 6, 25, 64, 9, 35,
+  25, 0, 32, 85, 0, 27, 5, 0, 11, 0,
+  41, 54, 31, 0, 0, 0, 12, 3, 0, 31,
+  0, 0, 0, 17, 0, 0, 32, 0, 0, 0,
+  0, 0, 0, 0, 65, 0, 25, 16, 30, 0,
+  0, 28, 8, 32, 27, 0, 2, 0, 68, 0,
+  19, 0, 0, 42, 7, 49, 43, 15, 20, 47,
+  0, 0, 0, 0, 0, 0, 3, 32, 0, 0,
+  0, 6, 4, 23, 0, 12, 7, 21, 0, 0,
+  2, 0, 0, 18, 0, 11, 54, 50, 0, 0,
+  0, 0, 0, 40, 0, 0, 45, 53, 0, 11,
+  0, 42, 0, 0, 22, 4, 38, 14, 110, 11,
+  16, 0, 30, 15, 57, 0, 0, 0, 2, 0,
+  0, 18, 21, 0, 59, 45, 0, 63, 2, 0,
+  3, 85, 0, 10, 16, 0, 9, 0, 31, 80,
+  7, 29, 0, 0, 22, 22, 0, 19, 0, 0,
+  0, 25, 0, 0, 16, 0, 0, 0, 0, 0,
+  0, 0, 11, 0, 0, 5, 46, 8, 7, 49,
+  61, 23, 56, 0, 23, 0, 71, 0, 0, 0,
+  14, 98, 16, 58, 20, 15, 28, 30, 7, 0,
+  10, 8, 0, 0, 0, 49, 0, 0, 0, 0,
+  0, 27, 0, 0, 0, 0, 0, 0, 17, 10,
+  0, 57, 0, 0, 54, 50, 0, 0, 31, 38,
+  0, 36, 0, 0, 23, 53, 0, 29, 0, 9,
+  0, 0, 24, 18, 14, 0, 53, 0, 0, 0,
+  18, 6, 59, 0, 0, 0, 0, 0, 21, 44,
+  0, 0, 68, 38, 3, 47, 64, 0, 0, 40,
+  0, 20, 0, 9, 7, 0, 28, 55, 0, 0,
+  1, 0, 35, 0, 0, 37, 14, 0, 22, 0,
+  0, 15, 86, 0, 0, 0, 20, 0, 12, 0,
+  13, 0, 9, 8, 46, 0, 0, 52, 10, 53,
+  45, 0, 0, 0, 8, 0, 0, 0, 0, 74,
+  0, 0, 0, 0, 17, 52, 3, 0, 18, 7,
+  0, 0, 31, 0, 0, 0, 23, 43, 0, 29,
+  0, 19, 52, 39, 0, 0, 56, 0, 8, 9,
+  0, 0, 56, 49, 5, 0, 28, 0, 0, 0,
+  24, 0, 37, 43, 61, 0, 18, 41, 48, 0,
+  82, 16, 8, 42, 39, 40, 0, 0, 47, 0,
+  25, 13, 0, 0, 67, 0, 0, 21, 0, 18,
+  51, 32, 4, 15, 16, 0, 0, 74, 15, 0,
+  13, 0, 0, 0, 53, 45, 10, 84, 0, 0,
+  0, 82, 0, 44, 0, 0, 0, 0, 0, 19,
+  65, 68, 0, 14, 8, 17, 0, 0, 0, 0,
+  0, 9, 3, 4, 0, 23, 27, 4, 12, 35,
+  0, 0, 0, 0, 7, 0, 0, 120, 0, 0,
+  0, 0, 0, 71, 1, 19, 66, 22, 0, 0,
+  0, 5, 0, 8, 4, 39, 0, 29, 0, 44,
+  65, 31, 0, 0, 54, 58, 0, 12, 0, 0,
+  47, 155, 11, 0, 50, 0, 0, 0, 45, 0,
+  62, 10, 71, 0, 0, 39, 35, 0, 91, 27,
+  0, 65, 34, 36, 0, 34, 14, 0, 51, 0,
+  0, 0, 19, 4, 0, 0, 14, 6, 95, 9,
+  0, 30, 0, 0, 0, 23, 0, 0, 8, 0,
+  0, 0, 51, 94, 0, 92, 0, 0, 16, 61,
+  0, 33, 0, 0, 0, 0, 0, 0, 47, 97,
+  0, 7, 27, 0, 4, 0, 0, 0, 0, 0,
+  0, 77, 45, 0, 33, 19, 45, 9, 0, 0,
+  4, 0, 2, 0, 45, 137, 0, 0, 0, 2,
+  10, 33, 44, 5, 15, 24, 0, 0, 11, 35,
+  0, 0, 0, 12, 0, 13, 0, 1, 6, 12,
+  0, 0, 8, 68, 0, 25, 0, 0, 28, 111,
+  8, 0, 44, 66, 0, 5, 0, 0, 15, 16,
+  0, 6, 0, 0, 27, 0, 53, 12, 0, 7,
+  33, 35, 0, 38, 0, 0, 31, 0, 0, 0,
+  0, 40, 0, 23, 24, 0, 54, 8, 0, 37,
+  61, 0, 0, 16, 0, 0, 0, 0, 30, 0,
+  25, 59, 0, 21, 4, 0, 13, 17, 0, 39,
+  33, 0, 20, 0, 0, 1, 63, 23, 29, 0,
+  0, 0, 72, 0, 0, 0, 0, 0, 0, 50,
+  0, 74, 18, 48, 36, 0, 9, 0, 60, 0,
+  36, 0, 0, 63, 66, 33, 53, 1, 1, 40,
+  5, 0, 0, 0, 0, 29, 0, 0, 0, 0,
+  0, 0, 0, 33, 0, 0, 0, 0, 0, 13,
+  0, 0, 0, 7, 0, 0, 40, 19, 0, 0,
+  0, 0, 0, 107, 0, 0, 12, 52, 0, 31,
+  0, 27, 0, 0, 0, 19, 66, 8, 85, 0,
+  0, 0, 0, 0, 65, 0, 0, 12, 15, 13,
+  23, 55, 0, 0, 38, 70, 22, 57, 6, 0,
+  10, 41, 0, 20, 0, 27, 34, 9, 25, 65,
+  0, 0, 0, 0, 11, 0, 0, 0, 15, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 46, 0, 22, 0, 42, 0, 0, 120,
+  19, 74, 27, 0, 31, 0, 61, 0, 8, 0,
+  21, 27, 26, 43, 32, 22, 11, 48, 0, 0,
+  11, 13, 20, 2, 39, 1, 0, 0, 0, 0,
+  45, 5, 15, 2, 0, 0, 0, 0, 0, 0,
+  0, 21, 0, 27, 87, 36, 0, 0, 16, 0,
+  0, 39, 0, 0, 30, 0, 0, 50, 0, 22,
+  0, 0, 0, 0, 32, 15, 38, 0, 0, 0,
+  27, 0, 82, 16, 0, 44, 0, 0, 23, 10,
+  32, 10, 15, 51, 24, 38, 8, 39, 22, 24,
+  0, 47, 0, 0, 15, 0, 42, 41, 18, 5,
+  0, 0, 5, 0, 39, 13, 35, 22, 0, 0,
+  0, 45, 0, 0, 0, 0, 9, 0, 0, 0,
+  49, 0, 6, 0, 21, 9, 64, 56, 7, 47,
+  47, 23, 0, 2, 27, 0, 0, 0, 42, 8,
+  0, 3, 0, 0, 56, 18, 0, 16, 26, 0,
+  2, 0, 57, 0, 1, 54, 0, 27, 23, 0,
+  74, 44, 54, 0, 12, 0, 0, 9, 0, 16,
+  14, 30, 64, 22, 0, 0, 0, 0, 0, 18,
+  39, 0, 31, 0, 0, 0, 0, 41, 29, 0,
+  11, 5, 0, 39, 0, 10, 75, 0, 74, 0,
+  24, 4, 0, 36, 30, 0, 0, 0, 49, 39,
+  40, 0, 0, 51, 36, 6, 0, 6, 0, 16,
+  0, 0, 38, 0, 41, 42, 30, 45, 15, 0,
+  0, 0, 5, 61, 41, 0, 5, 11, 0, 65,
+  38, 0, 0, 0, 29, 0, 0, 0, 0, 0,
+  0, 0, 8, 29, 0, 28, 8, 32, 27, 0,
+  2, 0, 68, 0, 19, 0, 0, 42, 7, 49,
+  43, 15, 20, 47, 0, 0, 0, 0, 0, 0,
+  3, 32, 0, 0, 0, 6, 4, 23, 0, 12,
+  7, 21, 0, 0, 2, 0, 0, 18, 0, 11,
+  54, 50, 0, 0, 0, 0, 0, 40, 0, 0,
+  45, 53, 0, 11, 0, 42, 0, 0, 22, 4,
+  38, 14, 110, 11, 16, 0, 30, 15, 57, 0,
+  0, 0, 2, 0, 0, 18, 21, 0, 59, 45,
+  0, 63, 2, 0, 3, 85, 0, 10, 16, 0,
+  9, 0, 31, 80, 7, 29, 0, 0, 22, 22,
+  0, 19, 0, 0, 0, 25, 0, 0, 16, 0,
+  0, 0, 0, 0, 0, 0, 11, 0, 0, 5,
+  46, 8, 7, 49, 61, 23, 56, 0, 23, 0,
+  71, 0, 0, 0, 14, 98, 16, 58, 20, 15,
+  28, 30, 7, 0, 10, 8, 0, 0, 0, 49,
+  0, 0, 0, 0, 0, 27, 0, 0, 0, 0,
+  0, 0, 17, 10, 0, 57, 0, 0, 54, 50,
+  0, 0, 31, 38, 0, 36, 0, 0, 23, 53,
+  0, 29, 0, 9, 0, 0, 24, 18, 14, 0,
+  53, 0, 0, 0, 18, 6, 59, 0, 0, 0,
+  0, 0, 21, 44, 0, 0, 68, 38, 3, 47,
+  64, 0, 0, 40, 0, 20, 0, 9, 7, 0,
+  28, 55, 0, 0, 1, 0, 35, 0, 0, 37,
+  14, 0, 22, 0, 0, 15, 86, 0, 0, 0,
+  20, 0, 12, 0, 13, 0, 9, 8, 46, 0,
+  51, 65, 87, 26, 42, 0, 0, 0, 24, 1,
+  1, 1, 40, 128, 0, 10, 0, 0, 20, 34,
+  11, 2, 7, 22, 0, 0, 0, 18, 0, 18,
+  19, 8, 0, 36, 8, 0, 36, 0, 0, 0,
+  19, 59, 0, 24, 0, 0, 22, 33, 0, 0,
+  46, 60, 0, 37, 0, 0, 0, 36, 0, 23,
+  0, 0, 20, 0, 14, 43, 0, 0, 6, 10,
+  0, 33, 9, 0, 41, 0, 0, 0, 32, 7,
+  0, 63, 13, 0, 60, 24, 16, 45, 93, 12,
+  0, 0, 0, 1, 0, 0, 27, 0, 35, 36,
+  0, 2, 17, 0, 23, 17, 0, 42, 39, 0,
+  25, 0, 0, 19, 110, 2, 0, 0, 0, 0,
+  14, 0, 0, 0, 0, 15, 6, 19, 0, 23,
+  27, 4, 12, 35, 0, 0, 0, 0, 7, 0,
+  0, 120, 0, 0, 0, 0, 0, 71, 1, 19,
+  66, 22, 0, 0, 0, 5, 0, 8, 4, 39,
+  0, 29, 0, 44, 65, 31, 0, 0, 54, 58,
+  0, 12, 0, 0, 47, 155, 11, 0, 50, 0,
+  0, 0, 45, 0, 62, 10, 71, 0, 0, 39,
+  35, 0, 91, 27, 0, 65, 34, 36, 0, 34,
+  14, 0, 51, 0, 0, 0, 19, 4, 0, 0,
+  14, 6, 95, 9, 0, 30, 0, 0, 0, 23,
+  0, 0, 8, 0, 0, 0, 51, 94, 0, 92,
+  0, 0, 16, 61, 0, 33, 0, 0, 0, 0,
+  0, 0, 47, 97, 0, 7, 27, 0, 4, 0,
+  0, 0, 0, 0, 0, 77, 45, 0, 33, 19,
+  45, 9, 0, 0, 4, 0, 2, 0, 45, 137,
+  0, 0, 0, 2, 10, 33, 44, 5, 15, 24,
+  0, 0, 11, 35, 0, 0, 0, 12, 0, 13,
+  0, 1, 6, 12, 0, 0, 8, 68, 0, 25,
+  0, 0, 28, 111, 8, 0, 44, 66, 0, 5,
+  0, 0, 15, 16, 0, 6, 0, 0, 27, 0,
+  53, 12, 0, 7, 33, 35, 0, 38, 0, 0,
+  31, 0, 0, 0, 0, 40, 0, 23, 24, 0,
+  54, 8, 0, 37, 61, 0, 0, 16, 0, 0,
+  0, 0, 30, 0, 25, 59, 0, 21, 4, 0,
+  13, 17, 0, 39, 33, 0, 20, 0, 0, 1,
+  63, 23, 29, 0, 0, 0, 72, 0, 0, 0,
+  0, 0, 0, 50, 46, 31, 46, 68, 33, 0,
+  0, 0, 66, 0, 8, 9, 61, 76, 4, 9,
+  2, 0, 9, 16, 52, 0, 0, 39, 0, 0,
+  46, 32, 0, 0, 28, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 77, 0, 9, 0, 0,
+  10, 32, 0, 0, 39, 72, 0, 16, 9, 0,
+  2, 31, 0, 8, 0, 0, 0, 4, 0, 26,
+  19, 0, 10, 7, 0, 32, 9, 31, 6, 0,
+  0, 38, 0, 38, 15, 46, 46, 0, 9, 55,
+  0, 11, 92, 0, 0, 0, 0, 12, 0, 0,
+  74, 0, 27, 39, 0, 0, 0, 0, 18, 45,
+  0, 35, 42, 11, 31, 0, 15, 0, 62, 0,
+  3, 0, 0, 6, 60, 0, 0, 0, 0, 12,
+  0, 66, 0, 120, 19, 74, 27, 0, 31, 0,
+  61, 0, 8, 0, 21, 27, 26, 43, 32, 22,
+  11, 48, 0, 0, 11, 13, 20, 2, 39, 1,
+  0, 0, 0, 0, 45, 5, 15, 2, 0, 0,
+  0, 0, 0, 0, 0, 21, 0, 27, 87, 36,
+  0, 0, 16, 0, 0, 39, 0, 0, 30, 0,
+  0, 50, 0, 22, 0, 0, 0, 0, 32, 15,
+  38, 0, 0, 0, 27, 0, 82, 16, 0, 44,
+  0, 0, 23, 10, 32, 10, 15, 51, 24, 38,
+  8, 39, 22, 24, 0, 47, 0, 0, 15, 0,
+  42, 41, 18, 5, 0, 0, 5, 0, 39, 13,
+  35, 22, 0, 0, 0, 45, 0, 0, 0, 0,
+  9, 0, 0, 0, 49, 0, 6, 0, 21, 9,
+  64, 56, 7, 47, 47, 23, 0, 2, 27, 0,
+  0, 0, 42, 8, 0, 3, 0, 0, 56, 18,
+  0, 16, 26, 0, 2, 0, 57, 0, 1, 54,
+  0, 27, 23, 0, 74, 44, 54, 0, 12, 0,
+  0, 9, 0, 16, 14, 30, 64, 22, 0, 0,
+  0, 0, 0, 18, 39, 0, 31, 0, 0, 0,
+  0, 41, 29, 0, 11, 5, 0, 39, 0, 10,
+  75, 0, 74, 0, 24, 4, 0, 36, 30, 0,
+  0, 0, 49, 39, 40, 0, 0, 51, 36, 6,
+  0, 6, 0, 16, 0, 0, 38, 0, 41, 42,
+  30, 45, 15, 0, 0, 0, 5, 61, 41, 0,
+  5, 11, 0, 65, 38, 0, 0, 0, 29, 0,
+  0, 0, 0, 0, 0, 0, 8, 29, 59, 0,
+  21, 13, 0, 41, 0, 2, 0, 43, 0, 19,
+  0, 48, 0, 0, 0, 0, 56, 0, 3, 89,
+  5, 0, 0, 0, 21, 5, 0, 99, 0, 11,
+  0, 0, 67, 44, 117, 91, 15, 0, 39, 0,
+  3, 0, 0, 12, 0, 18, 5, 1, 0, 35,
+  0, 23, 119, 0, 0, 4, 0, 0, 0, 65,
+  91, 49, 82, 33, 0, 21, 0, 118, 80, 20,
+  83, 0, 0, 0, 0, 0, 100, 0, 0, 0,
+  15, 22, 26, 0, 0, 49, 63, 0, 0, 18,
+  0, 0, 55, 0, 41, 0, 0, 54, 58, 26,
+  28, 0, 0, 0, 0, 29, 0, 0, 19, 18,
+  0, 23, 56, 7, 0, 0, 19, 0, 0, 0,
+  0, 0, 0, 24, 61, 73, 7, 49, 61, 23,
+  56, 0, 23, 0, 71, 0, 0, 0, 14, 98,
+  16, 58, 20, 15, 28, 30, 7, 0, 10, 8,
+  0, 0, 0, 49, 0, 0, 0, 0, 0, 27,
+  0, 0, 0, 0, 0, 0, 17, 10, 0, 57,
+  0, 0, 54, 50, 0, 0, 31, 38, 0, 36,
+  0, 0, 23, 53, 0, 29, 0, 9, 0, 0,
+  24, 18, 14, 0, 53, 0, 0, 0, 18, 6,
+  59, 0, 0, 0, 0, 0, 21, 44, 0, 0,
+  68, 38, 3, 47, 64, 0, 0, 40, 0, 20,
+  0, 9, 7, 0, 28, 55, 0, 0, 1, 0,
+  35, 0, 0, 37, 14, 0, 22, 0, 0, 15,
+  86, 0, 0, 0, 20, 0, 12, 0, 13, 0,
+  9, 8, 46, 0, 51, 65, 87, 26, 42, 0,
+  0, 0, 24, 1, 1, 1, 40, 128, 0, 10,
+  0, 0, 20, 34, 11, 2, 7, 22, 0, 0,
+  0, 18, 0, 18, 19, 8, 0, 36, 8, 0,
+  36, 0, 0, 0, 19, 59, 0, 24, 0, 0,
+  22, 33, 0, 0, 46, 60, 0, 37, 0, 0,
+  0, 36, 0, 23, 0, 0, 20, 0, 14, 43,
+  0, 0, 6, 10, 0, 33, 9, 0, 41, 0,
+  0, 0, 32, 7, 0, 63, 13, 0, 60, 24,
+  16, 45, 93, 12, 0, 0, 0, 1, 0, 0,
+  27, 0, 35, 36, 0, 2, 17, 0, 23, 17,
+  0, 42, 39, 0, 25, 0, 0, 19, 110, 2,
+  0, 0, 0, 0, 14, 0, 0, 0, 0, 15,
+  6, 19, 58, 29, 70, 32, 22, 7, 0, 0,
+  38, 0, 7, 32, 60, 93, 0, 0, 0, 0,
+  38, 0, 64, 26, 0, 33, 0, 0, 30, 14,
+  0, 67, 47, 0, 0, 0, 6, 0, 43, 9,
+  0, 0, 0, 21, 0, 0, 0, 0, 0, 24,
+  0, 6, 13, 86, 0, 24, 27, 0, 0, 48,
+  0, 0, 0, 0, 12, 26, 3, 21, 0, 0,
+  0, 30, 0, 44, 10, 2, 0, 0, 0, 0,
+  48, 0, 0, 39, 61, 0, 1, 12, 0, 35,
+  123, 0, 0, 0, 0, 0, 0, 0, 63, 0,
+  17, 39, 26, 0, 0, 0, 0, 26, 0, 33,
+  42, 10, 39, 0, 4, 0, 83, 0, 0, 0,
+  0, 28, 67, 0, 0, 0, 0, 33, 0, 82,
+  45, 0, 33, 19, 45, 9, 0, 0, 4, 0,
+  2, 0, 45, 137, 0, 0, 0, 2, 10, 33,
+  44, 5, 15, 24, 0, 0, 11, 35, 0, 0,
+  0, 12, 0, 13, 0, 1, 6, 12, 0, 0,
+  8, 68, 0, 25, 0, 0, 28, 111, 8, 0,
+  44, 66, 0, 5, 0, 0, 15, 16, 0, 6,
+  0, 0, 27, 0, 53, 12, 0, 7, 33, 35,
+  0, 38, 0, 0, 31, 0, 0, 0, 0, 40,
+  0, 23, 24, 0, 54, 8, 0, 37, 61, 0,
+  0, 16, 0, 0, 0, 0, 30, 0, 25, 59,
+  0, 21, 4, 0, 13, 17, 0, 39, 33, 0,
+  20, 0, 0, 1, 63, 23, 29, 0, 0, 0,
+  72, 0, 0, 0, 0, 0, 0, 50, 46, 31,
+  46, 68, 33, 0, 0, 0, 66, 0, 8, 9,
+  61, 76, 4, 9, 2, 0, 9, 16, 52, 0,
+  0, 39, 0, 0, 46, 32, 0, 0, 28, 0,
+  0, 0, 1, 0, 0, 0, 0, 0, 0, 77,
+  0, 9, 0, 0, 10, 32, 0, 0, 39, 72,
+  0, 16, 9, 0, 2, 31, 0, 8, 0, 0,
+  0, 4, 0, 26, 19, 0, 10, 7, 0, 32,
+  9, 31, 6, 0, 0, 38, 0, 38, 15, 46,
+  46, 0, 9, 55, 0, 11, 92, 0, 0, 0,
+  0, 12, 0, 0, 74, 0, 27, 39, 0, 0,
+  0, 0, 18, 45, 0, 35, 42, 11, 31, 0,
+  15, 0, 62, 0, 3, 0, 0, 6, 60, 0,
+  0, 0, 0, 12, 0, 66, 23, 5, 71, 73,
+  1, 0, 0, 8, 79, 0, 18, 35, 49, 54,
+  0, 0, 0, 6, 44, 0, 41, 8, 0, 24,
+  0, 0, 55, 8, 0, 0, 32, 0, 5, 0,
+  0, 0, 12, 0, 0, 0, 0, 38, 0, 0,
+  0, 8, 0, 0, 0, 0, 32, 89, 0, 0,
+  52, 0, 19, 21, 0, 9, 0, 0, 0, 30,
+  3, 0, 40, 0, 15, 64, 0, 0, 41, 76,
+  0, 0, 9, 58, 0, 26, 12, 24, 95, 17,
+  0, 70, 0, 25, 100, 0, 27, 15, 0, 0,
+  8, 0, 68, 0, 16, 62, 13, 0, 0, 0,
+  0, 91, 0, 16, 1, 6, 23, 0, 3, 0,
+  73, 0, 19, 0, 0, 35, 21, 0, 0, 0,
+  0, 16, 0, 69, 64, 56, 7, 47, 47, 23,
+  0, 2, 27, 0, 0, 0, 42, 8, 0, 3,
+  0, 0, 56, 18, 0, 16, 26, 0, 2, 0,
+  57, 0, 1, 54, 0, 27, 23, 0, 74, 44,
+  54, 0, 12, 0, 0, 9, 0, 16, 14, 30,
+  64, 22, 0, 0, 0, 0, 0, 18, 39, 0,
+  31, 0, 0, 0, 0, 41, 29, 0, 11, 5,
+  0, 39, 0, 10, 75, 0, 74, 0, 24, 4,
+  0, 36, 30, 0, 0, 0, 49, 39, 40, 0,
+  0, 51, 36, 6, 0, 6, 0, 16, 0, 0,
+  38, 0, 41, 42, 30, 45, 15, 0, 0, 0,
+  5, 61, 41, 0, 5, 11, 0, 65, 38, 0,
+  0, 0, 29, 0, 0, 0, 0, 0, 0, 0,
+  8, 29, 59, 0, 21, 13, 0, 41, 0, 2,
+  0, 43, 0, 19, 0, 48, 0, 0, 0, 0,
+  56, 0, 3, 89, 5, 0, 0, 0, 21, 5,
+  0, 99, 0, 11, 0, 0, 67, 44, 117, 91,
+  15, 0, 39, 0, 3, 0, 0, 12, 0, 18,
+  5, 1, 0, 35, 0, 23, 119, 0, 0, 4,
+  0, 0, 0, 65, 91, 49, 82, 33, 0, 21,
+  0, 118, 80, 20, 83, 0, 0, 0, 0, 0,
+  100, 0, 0, 0, 15, 22, 26, 0, 0, 49,
+  63, 0, 0, 18, 0, 0, 55, 0, 41, 0,
+  0, 54, 58, 26, 28, 0, 0, 0, 0, 29,
+  0, 0, 19, 18, 0, 23, 56, 7, 0, 0,
+  19, 0, 0, 0, 0, 0, 0, 24, 61, 73,
+  32, 0, 66, 36, 9, 0, 0, 0, 5, 21,
+  0, 26, 30, 124, 0, 0, 0, 0, 23, 0,
+  28, 52, 0, 3, 0, 0, 50, 28, 0, 103,
+  0, 4, 0, 0, 39, 0, 82, 66, 0, 0,
+  35, 0, 2, 0, 0, 22, 7, 0, 0, 0,
+  0, 70, 0, 21, 74, 0, 0, 14, 10, 0,
+  0, 32, 91, 24, 64, 1, 0, 2, 0, 95,
+  0, 13, 72, 0, 0, 0, 0, 0, 86, 0,
+  0, 56, 11, 19, 0, 0, 12, 13, 141, 0,
+  0, 19, 0, 0, 4, 0, 38, 0, 0, 38,
+  31, 0, 0, 0, 0, 0, 0, 56, 51, 0,
+  69, 0, 0, 0, 107, 0, 36, 0, 0, 32,
+  38, 0, 0, 0, 0, 37, 0, 81, 51, 65,
+  87, 26, 42, 0, 0, 0, 24, 1, 1, 1,
+  40, 128, 0, 10, 0, 0, 20, 34, 11, 2,
+  7, 22, 0, 0, 0, 18, 0, 18, 19, 8,
+  0, 36, 8, 0, 36, 0, 0, 0, 19, 59,
+  0, 24, 0, 0, 22, 33, 0, 0, 46, 60,
+  0, 37, 0, 0, 0, 36, 0, 23, 0, 0,
+  20, 0, 14, 43, 0, 0, 6, 10, 0, 33,
+  9, 0, 41, 0, 0, 0, 32, 7, 0, 63,
+  13, 0, 60, 24, 16, 45, 93, 12, 0, 0,
+  0, 1, 0, 0, 27, 0, 35, 36, 0, 2,
+  17, 0, 23, 17, 0, 42, 39, 0, 25, 0,
+  0, 19, 110, 2, 0, 0, 0, 0, 14, 0,
+  0, 0, 0, 15, 6, 19, 58, 29, 70, 32,
+  22, 7, 0, 0, 38, 0, 7, 32, 60, 93,
+  0, 0, 0, 0, 38, 0, 64, 26, 0, 33,
+  0, 0, 30, 14, 0, 67, 47, 0, 0, 0,
+  6, 0, 43, 9, 0, 0, 0, 21, 0, 0,
+  0, 0, 0, 24, 0, 6, 13, 86, 0, 24,
+  27, 0, 0, 48, 0, 0, 0, 0, 12, 26,
+  3, 21, 0, 0, 0, 30, 0, 44, 10, 2,
+  0, 0, 0, 0, 48, 0, 0, 39, 61, 0,
+  1, 12, 0, 35, 123, 0, 0, 0, 0, 0,
+  0, 0, 63, 0, 17, 39, 26, 0, 0, 0,
+  0, 26, 0, 33, 42, 10, 39, 0, 4, 0,
+  83, 0, 0, 0, 0, 28, 67, 0, 0, 0,
+  0, 33, 0, 82, 37, 48, 54, 46, 22, 17,
+  0, 0, 75, 0, 31, 10, 55, 60, 0, 21,
+  0, 0, 43, 0, 38, 0, 0, 48, 0, 0,
+  41, 28, 0, 38, 57, 0, 0, 0, 24, 0,
+  32, 0, 0, 0, 0, 80, 0, 0, 0, 0,
+  14, 21, 0, 28, 36, 67, 0, 12, 53, 0,
+  1, 49, 0, 34, 0, 0, 0, 41, 0, 12,
+  9, 0, 0, 0, 0, 43, 25, 31, 0, 22,
+  14, 0, 16, 22, 0, 32, 73, 0, 0, 30,
+  3, 13, 122, 5, 40, 0, 0, 1, 0, 0,
+  93, 0, 14, 55, 0, 0, 0, 0, 0, 54,
+  0, 32, 56, 22, 48, 0, 15, 0, 63, 0,
+  0, 0, 0, 46, 59, 0, 14, 0, 6, 28,
+  0, 93, 46, 31, 46, 68, 33, 0, 0, 0,
+  66, 0, 8, 9, 61, 76, 4, 9, 2, 0,
+  9, 16, 52, 0, 0, 39, 0, 0, 46, 32,
+  0, 0, 28, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 77, 0, 9, 0, 0, 10, 32,
+  0, 0, 39, 72, 0, 16, 9, 0, 2, 31,
+  0, 8, 0, 0, 0, 4, 0, 26, 19, 0,
+  10, 7, 0, 32, 9, 31, 6, 0, 0, 38,
+  0, 38, 15, 46, 46, 0, 9, 55, 0, 11,
+  92, 0, 0, 0, 0, 12, 0, 0, 74, 0,
+  27, 39, 0, 0, 0, 0, 18, 45, 0, 35,
+  42, 11, 31, 0, 15, 0, 62, 0, 3, 0,
+  0, 6, 60, 0, 0, 0, 0, 12, 0, 66,
+  23, 5, 71, 73, 1, 0, 0, 8, 79, 0,
+  18, 35, 49, 54, 0, 0, 0, 6, 44, 0,
+  41, 8, 0, 24, 0, 0, 55, 8, 0, 0,
+  32, 0, 5, 0, 0, 0, 12, 0, 0, 0,
+  0, 38, 0, 0, 0, 8, 0, 0, 0, 0,
+  32, 89, 0, 0, 52, 0, 19, 21, 0, 9,
+  0, 0, 0, 30, 3, 0, 40, 0, 15, 64,
+  0, 0, 41, 76, 0, 0, 9, 58, 0, 26,
+  12, 24, 95, 17, 0, 70, 0, 25, 100, 0,
+  27, 15, 0, 0, 8, 0, 68, 0, 16, 62,
+  13, 0, 0, 0, 0, 91, 0, 16, 1, 6,
+  23, 0, 3, 0, 73, 0, 19, 0, 0, 35,
+  21, 0, 0, 0, 0, 16, 0, 69, 0, 0,
+  76, 61, 0, 18, 0, 0, 58, 0, 2, 25,
+  0, 40, 0, 0, 19, 37, 29, 4, 20, 9,
+  0, 8, 0, 0, 28, 9, 0, 0, 7, 0,
+  8, 0, 0, 19, 34, 4, 0, 0, 0, 7,
+  0, 0, 0, 37, 0, 0, 0, 0, 40, 40,
+  0, 0, 62, 0, 3, 11, 0, 0, 0, 0,
+  0, 0, 17, 0, 43, 0, 29, 88, 0, 0,
+  53, 71, 0, 0, 0, 29, 0, 20, 2, 10,
+  49, 67, 0, 66, 3, 6, 58, 0, 34, 42,
+  0, 0, 38, 0, 45, 5, 0, 65, 19, 0,
+  0, 0, 12, 109, 0, 0, 0, 0, 12, 0,
+  0, 0, 66, 0, 15, 0, 0, 45, 0, 0,
+  0, 0, 0, 21, 19, 34, 59, 0, 21, 13,
+  0, 41, 0, 2, 0, 43, 0, 19, 0, 48,
+  0, 0, 0, 0, 56, 0, 3, 89, 5, 0,
+  0, 0, 21, 5, 0, 99, 0, 11, 0, 0,
+  67, 44, 117, 91, 15, 0, 39, 0, 3, 0,
+  0, 12, 0, 18, 5, 1, 0, 35, 0, 23,
+  119, 0, 0, 4, 0, 0, 0, 65, 91, 49,
+  82, 33, 0, 21, 0, 118, 80, 20, 83, 0,
+  0, 0, 0, 0, 100, 0, 0, 0, 15, 22,
+  26, 0, 0, 49, 63, 0, 0, 18, 0, 0,
+  55, 0, 41, 0, 0, 54, 58, 26, 28, 0,
+  0, 0, 0, 29, 0, 0, 19, 18, 0, 23,
+  56, 7, 0, 0, 19, 0, 0, 0, 0, 0,
+  0, 24, 61, 73, 32, 0, 66, 36, 9, 0,
+  0, 0, 5, 21, 0, 26, 30, 124, 0, 0,
+  0, 0, 23, 0, 28, 52, 0, 3, 0, 0,
+  50, 28, 0, 103, 0, 4, 0, 0, 39, 0,
+  82, 66, 0, 0, 35, 0, 2, 0, 0, 22,
+  7, 0, 0, 0, 0, 70, 0, 21, 74, 0,
+  0, 14, 10, 0, 0, 32, 91, 24, 64, 1,
+  0, 2, 0, 95, 0, 13, 72, 0, 0, 0,
+  0, 0, 86, 0, 0, 56, 11, 19, 0, 0,
+  12, 13, 141, 0, 0, 19, 0, 0, 4, 0,
+  38, 0, 0, 38, 31, 0, 0, 0, 0, 0,
+  0, 56, 51, 0, 69, 0, 0, 0, 107, 0,
+  36, 0, 0, 32, 38, 0, 0, 0, 0, 37,
+  0, 81, 51, 46, 25, 77, 65, 9, 0, 0,
+  20, 0, 19, 0, 51, 118, 0, 0, 0, 0,
+  16, 7, 12, 11, 0, 26, 0, 0, 55, 19,
+  0, 69, 20, 7, 22, 0, 56, 0, 0, 0,
+  0, 0, 0, 35, 0, 0, 31, 31, 30, 33,
+  0, 0, 23, 35, 0, 14, 38, 0, 27, 20,
+  0, 10, 0, 19, 19, 8, 0, 0, 0, 0,
+  2, 0, 0, 41, 51, 0, 0, 22, 0, 0,
+  35, 8, 0, 53, 41, 20, 0, 0, 35, 12,
+  95, 14, 26, 0, 0, 30, 0, 0, 70, 0,
+  0, 50, 0, 20, 0, 0, 0, 25, 0, 43,
+  127, 0, 82, 0, 12, 0, 31, 0, 14, 0,
+  0, 8, 49, 0, 2, 15, 10, 13, 0, 93,
+  58, 29, 70, 32, 22, 7, 0, 0, 38, 0,
+  7, 32, 60, 93, 0, 0, 0, 0, 38, 0,
+  64, 26, 0, 33, 0, 0, 30, 14, 0, 67,
+  47, 0, 0, 0, 6, 0, 43, 9, 0, 0,
+  0, 21, 0, 0, 0, 0, 0, 24, 0, 6,
+  13, 86, 0, 24, 27, 0, 0, 48, 0, 0,
+  0, 0, 12, 26, 3, 21, 0, 0, 0, 30,
+  0, 44, 10, 2, 0, 0, 0, 0, 48, 0,
+  0, 39, 61, 0, 1, 12, 0, 35, 123, 0,
+  0, 0, 0, 0, 0, 0, 63, 0, 17, 39,
+  26, 0, 0, 0, 0, 26, 0, 33, 42, 10,
+  39, 0, 4, 0, 83, 0, 0, 0, 0, 28,
+  67, 0, 0, 0, 0, 33, 0, 82, 37, 48,
+  54, 46, 22, 17, 0, 0, 75, 0, 31, 10,
+  55, 60, 0, 21, 0, 0, 43, 0, 38, 0,
+  0, 48, 0, 0, 41, 28, 0, 38, 57, 0,
+  0, 0, 24, 0, 32, 0, 0, 0, 0, 80,
+  0, 0, 0, 0, 14, 21, 0, 28, 36, 67,
+  0, 12, 53, 0, 1, 49, 0, 34, 0, 0,
+  0, 41, 0, 12, 9, 0, 0, 0, 0, 43,
+  25, 31, 0, 22, 14, 0, 16, 22, 0, 32,
+  73, 0, 0, 30, 3, 13, 122, 5, 40, 0,
+  0, 1, 0, 0, 93, 0, 14, 55, 0, 0,
+  0, 0, 0, 54, 0, 32, 56, 22, 48, 0,
+  15, 0, 63, 0, 0, 0, 0, 46, 59, 0,
+  14, 0, 6, 28, 0, 93, 18, 58, 66, 69,
+  39, 34, 0, 0, 61, 0, 24, 0, 24, 41,
+  11, 21, 49, 14, 29, 7, 0, 0, 0, 34,
+  1, 0, 22, 29, 0, 26, 0, 5, 31, 0,
+  36, 0, 13, 0, 0, 0, 0, 34, 0, 0,
+  10, 55, 10, 6, 0, 0, 30, 0, 0, 0,
+  35, 0, 20, 14, 0, 4, 0, 6, 0, 0,
+  0, 0, 31, 0, 49, 0, 0, 0, 64, 30,
+  0, 37, 0, 10, 0, 53, 0, 8, 43, 93,
+  0, 42, 5, 3, 30, 39, 93, 5, 0, 0,
+  11, 0, 68, 0, 0, 79, 5, 0, 0, 0,
+  30, 61, 0, 15, 39, 0, 23, 0, 0, 0,
+  0, 0, 12, 0, 0, 0, 11, 0, 7, 0,
+  19, 17, 24, 37, 23, 5, 71, 73, 1, 0,
+  0, 8, 79, 0, 18, 35, 49, 54, 0, 0,
+  0, 6, 44, 0, 41, 8, 0, 24, 0, 0,
+  55, 8, 0, 0, 32, 0, 5, 0, 0, 0,
+  12, 0, 0, 0, 0, 38, 0, 0, 0, 8,
+  0, 0, 0, 0, 32, 89, 0, 0, 52, 0,
+  19, 21, 0, 9, 0, 0, 0, 30, 3, 0,
+  40, 0, 15, 64, 0, 0, 41, 76, 0, 0,
+  9, 58, 0, 26, 12, 24, 95, 17, 0, 70,
+  0, 25, 100, 0, 27, 15, 0, 0, 8, 0,
+  68, 0, 16, 62, 13, 0, 0, 0, 0, 91,
+  0, 16, 1, 6, 23, 0, 3, 0, 73, 0,
+  19, 0, 0, 35, 21, 0, 0, 0, 0, 16,
+  0, 69, 0, 0, 76, 61, 0, 18, 0, 0,
+  58, 0, 2, 25, 0, 40, 0, 0, 19, 37,
+  29, 4, 20, 9, 0, 8, 0, 0, 28, 9,
+  0, 0, 7, 0, 8, 0, 0, 19, 34, 4,
+  0, 0, 0, 7, 0, 0, 0, 37, 0, 0,
+  0, 0, 40, 40, 0, 0, 62, 0, 3, 11,
+  0, 0, 0, 0, 0, 0, 17, 0, 43, 0,
+  29, 88, 0, 0, 53, 71, 0, 0, 0, 29,
+  0, 20, 2, 10, 49, 67, 0, 66, 3, 6,
+  58, 0, 34, 42, 0, 0, 38, 0, 45, 5,
+  0, 65, 19, 0, 0, 0, 12, 109, 0, 0,
+  0, 0, 12, 0, 0, 0, 66, 0, 15, 0,
+  0, 45, 0, 0, 0, 0, 0, 21, 19, 34,
+  21, 49, 94, 59, 0, 40, 0, 0, 37, 0,
+  0, 2, 0, 53, 10, 6, 39, 18, 0, 5,
+  0, 0, 0, 10, 0, 0, 0, 12, 0, 36,
+  18, 54, 0, 12, 26, 2, 59, 42, 0, 0,
+  0, 6, 17, 0, 0, 42, 0, 10, 0, 0,
+  60, 0, 0, 0, 47, 0, 14, 4, 5, 0,
+  0, 0, 0, 0, 0, 0, 19, 0, 49, 8,
+  0, 0, 50, 31, 0, 14, 0, 0, 0, 49,
+  0, 39, 0, 93, 0, 53, 2, 0, 47, 10,
+  28, 14, 0, 0, 7, 0, 11, 20, 0, 63,
+  0, 0, 0, 0, 64, 95, 0, 0, 0, 0,
+  42, 0, 0, 0, 37, 0, 0, 0, 0, 29,
+  0, 0, 0, 0, 8, 31, 58, 8, 32, 0,
+  66, 36, 9, 0, 0, 0, 5, 21, 0, 26,
+  30, 124, 0, 0, 0, 0, 23, 0, 28, 52,
+  0, 3, 0, 0, 50, 28, 0, 103, 0, 4,
+  0, 0, 39, 0, 82, 66, 0, 0, 35, 0,
+  2, 0, 0, 22, 7, 0, 0, 0, 0, 70,
+  0, 21, 74, 0, 0, 14, 10, 0, 0, 32,
+  91, 24, 64, 1, 0, 2, 0, 95, 0, 13,
+  72, 0, 0, 0, 0, 0, 86, 0, 0, 56,
+  11, 19, 0, 0, 12, 13, 141, 0, 0, 19,
+  0, 0, 4, 0, 38, 0, 0, 38, 31, 0,
+  0, 0, 0, 0, 0, 56, 51, 0, 69, 0,
+  0, 0, 107, 0, 36, 0, 0, 32, 38, 0,
+  0, 0, 0, 37, 0, 81, 51, 46, 25, 77,
+  65, 9, 0, 0, 20, 0, 19, 0, 51, 118,
+  0, 0, 0, 0, 16, 7, 12, 11, 0, 26,
+  0, 0, 55, 19, 0, 69, 20, 7, 22, 0,
+  56, 0, 0, 0, 0, 0, 0, 35, 0, 0,
+  31, 31, 30, 33, 0, 0, 23, 35, 0, 14,
+  38, 0, 27, 20, 0, 10, 0, 19, 19, 8,
+  0, 0, 0, 0, 2, 0, 0, 41, 51, 0,
+  0, 22, 0, 0, 35, 8, 0, 53, 41, 20,
+  0, 0, 35, 12, 95, 14, 26, 0, 0, 30,
+  0, 0, 70, 0, 0, 50, 0, 20, 0, 0,
+  0, 25, 0, 43, 127, 0, 82, 0, 12, 0,
+  31, 0, 14, 0, 0, 8, 49, 0, 2, 15,
+  10, 13, 0, 93, 42, 127, 15, 99, 80, 43,
+  0, 0, 43, 0, 32, 0, 35, 29, 0, 0,
+  11, 0, 41, 15, 0, 0, 0, 47, 24, 0,
+  52, 29, 0, 37, 5, 49, 69, 0, 20, 0,
+  0, 0, 0, 0, 0, 17, 0, 6, 19, 56,
+  44, 46, 0, 7, 4, 0, 0, 17, 32, 0,
+  50, 2, 0, 29, 21, 24, 0, 8, 0, 0,
+  52, 4, 27, 0, 0, 21, 45, 4, 6, 45,
+  10, 2, 0, 2, 0, 19, 40, 73, 0, 17,
+  5, 38, 21, 49, 107, 0, 0, 49, 0, 0,
+  90, 0, 23, 57, 7, 99, 1, 0, 25, 33,
+  41, 62, 122, 0, 7, 22, 36, 0, 0, 0,
+  0, 0, 0, 0, 13, 0, 43, 0, 45, 1,
+  13, 74, 37, 48, 54, 46, 22, 17, 0, 0,
+  75, 0, 31, 10, 55, 60, 0, 21, 0, 0,
+  43, 0, 38, 0, 0, 48, 0, 0, 41, 28,
+  0, 38, 57, 0, 0, 0, 24, 0, 32, 0,
+  0, 0, 0, 80, 0, 0, 0, 0, 14, 21,
+  0, 28, 36, 67, 0, 12, 53, 0, 1, 49,
+  0, 34, 0, 0, 0, 41, 0, 12, 9, 0,
+  0, 0, 0, 43, 25, 31, 0, 22, 14, 0,
+  16, 22, 0, 32, 73, 0, 0, 30, 3, 13,
+  122, 5, 40, 0, 0, 1, 0, 0, 93, 0,
+  14, 55, 0, 0, 0, 0, 0, 54, 0, 32,
+  56, 22, 48, 0, 15, 0, 63, 0, 0, 0,
+  0, 46, 59, 0, 14, 0, 6, 28, 0, 93,
+  18, 58, 66, 69, 39, 34, 0, 0, 61, 0,
+  24, 0, 24, 41, 11, 21, 49, 14, 29, 7,
+  0, 0, 0, 34, 1, 0, 22, 29, 0, 26,
+  0, 5, 31, 0, 36, 0, 13, 0, 0, 0,
+  0, 34, 0, 0, 10, 55, 10, 6, 0, 0,
+  30, 0, 0, 0, 35, 0, 20, 14, 0, 4,
+  0, 6, 0, 0, 0, 0, 31, 0, 49, 0,
+  0, 0, 64, 30, 0, 37, 0, 10, 0, 53,
+  0, 8, 43, 93, 0, 42, 5, 3, 30, 39,
+  93, 5, 0, 0, 11, 0, 68, 0, 0, 79,
+  5, 0, 0, 0, 30, 61, 0, 15, 39, 0,
+  23, 0, 0, 0, 0, 0, 12, 0, 0, 0,
+  11, 0, 7, 0, 19, 17, 24, 37, 19, 83,
+  100, 57, 60, 86, 0, 0, 16, 0, 0, 0,
+  1, 37, 9, 22, 45, 0, 3, 24, 0, 9,
+  0, 26, 12, 0, 0, 30, 0, 58, 0, 45,
+  5, 36, 29, 8, 0, 14, 0, 6, 0, 0,
+  0, 30, 1, 47, 31, 38, 0, 0, 15, 0,
+  0, 0, 7, 0, 28, 11, 0, 0, 0, 19,
+  0, 0, 0, 0, 25, 0, 71, 0, 0, 0,
+  48, 11, 37, 0, 0, 0, 0, 14, 0, 10,
+  19, 113, 22, 41, 0, 37, 0, 20, 39, 0,
+  0, 0, 11, 0, 10, 0, 0, 52, 9, 11,
+  0, 0, 76, 50, 5, 16, 33, 0, 25, 22,
+  0, 4, 0, 0, 10, 0, 0, 0, 0, 0,
+  0, 0, 34, 0, 47, 18, 0, 0, 76, 61,
+  0, 18, 0, 0, 58, 0, 2, 25, 0, 40,
+  0, 0, 19, 37, 29, 4, 20, 9, 0, 8,
+  0, 0, 28, 9, 0, 0, 7, 0, 8, 0,
+  0, 19, 34, 4, 0, 0, 0, 7, 0, 0,
+  0, 37, 0, 0, 0, 0, 40, 40, 0, 0,
+  62, 0, 3, 11, 0, 0, 0, 0, 0, 0,
+  17, 0, 43, 0, 29, 88, 0, 0, 53, 71,
+  0, 0, 0, 29, 0, 20, 2, 10, 49, 67,
+  0, 66, 3, 6, 58, 0, 34, 42, 0, 0,
+  38, 0, 45, 5, 0, 65, 19, 0, 0, 0,
+  12, 109, 0, 0, 0, 0, 12, 0, 0, 0,
+  66, 0, 15, 0, 0, 45, 0, 0, 0, 0,
+  0, 21, 19, 34, 21, 49, 94, 59, 0, 40,
+  0, 0, 37, 0, 0, 2, 0, 53, 10, 6,
+  39, 18, 0, 5, 0, 0, 0, 10, 0, 0,
+  0, 12, 0, 36, 18, 54, 0, 12, 26, 2,
+  59, 42, 0, 0, 0, 6, 17, 0, 0, 42,
+  0, 10, 0, 0, 60, 0, 0, 0, 47, 0,
+  14, 4, 5, 0, 0, 0, 0, 0, 0, 0,
+  19, 0, 49, 8, 0, 0, 50, 31, 0, 14,
+  0, 0, 0, 49, 0, 39, 0, 93, 0, 53,
+  2, 0, 47, 10, 28, 14, 0, 0, 7, 0,
+  11, 20, 0, 63, 0, 0, 0, 0, 64, 95,
+  0, 0, 0, 0, 42, 0, 0, 0, 37, 0,
+  0, 0, 0, 29, 0, 0, 0, 0, 8, 31,
+  58, 8, 24, 50, 130, 56, 9, 113, 0, 0,
+  0, 0, 0, 0, 18, 53, 0, 15, 32, 9,
+  0, 14, 0, 26, 0, 12, 0, 0, 0, 0,
+  0, 68, 18, 55, 0, 60, 43, 18, 30, 1,
+  0, 18, 0, 0, 0, 3, 0, 17, 0, 39,
+  0, 0, 36, 38, 0, 0, 41, 0, 32, 16,
+  29, 0, 0, 0, 0, 0, 31, 0, 0, 0,
+  41, 0, 0, 0, 42, 0, 0, 3, 0, 0,
+  2, 46, 0, 22, 20, 94, 27, 22, 13, 1,
+  28, 26, 6, 0, 0, 0, 15, 0, 0, 0,
+  0, 25, 2, 0, 0, 0, 20, 67, 0, 0,
+  0, 2, 64, 0, 0, 16, 0, 0, 21, 0,
+  0, 13, 0, 0, 0, 18, 28, 25, 23, 8,
+  51, 46, 25, 77, 65, 9, 0, 0, 20, 0,
+  19, 0, 51, 118, 0, 0, 0, 0, 16, 7,
+  12, 11, 0, 26, 0, 0, 55, 19, 0, 69,
+  20, 7, 22, 0, 56, 0, 0, 0, 0, 0,
+  0, 35, 0, 0, 31, 31, 30, 33, 0, 0,
+  23, 35, 0, 14, 38, 0, 27, 20, 0, 10,
+  0, 19, 19, 8, 0, 0, 0, 0, 2, 0,
+  0, 41, 51, 0, 0, 22, 0, 0, 35, 8,
+  0, 53, 41, 20, 0, 0, 35, 12, 95, 14,
+  26, 0, 0, 30, 0, 0, 70, 0, 0, 50,
+  0, 20, 0, 0, 0, 25, 0, 43, 127, 0,
+  82, 0, 12, 0, 31, 0, 14, 0, 0, 8,
+  49, 0, 2, 15, 10, 13, 0, 93, 42, 127,
+  15, 99, 80, 43, 0, 0, 43, 0, 32, 0,
+  35, 29, 0, 0, 11, 0, 41, 15, 0, 0,
+  0, 47, 24, 0, 52, 29, 0, 37, 5, 49,
+  69, 0, 20, 0, 0, 0, 0, 0, 0, 17,
+  0, 6, 19, 56, 44, 46, 0, 7, 4, 0,
+  0, 17, 32, 0, 50, 2, 0, 29, 21, 24,
+  0, 8, 0, 0, 52, 4, 27, 0, 0, 21,
+  45, 4, 6, 45, 10, 2, 0, 2, 0, 19,
+  40, 73, 0, 17, 5, 38, 21, 49, 107, 0,
+  0, 49, 0, 0, 90, 0, 23, 57, 7, 99,
+  1, 0, 25, 33, 41, 62, 122, 0, 7, 22,
+  36, 0, 0, 0, 0, 0, 0, 0, 13, 0,
+  43, 0, 45, 1, 13, 74, 17, 8, 86, 68,
+  23, 217, 0, 0, 29, 0, 0, 0, 32, 0,
+  0, 0, 31, 18, 66, 0, 0, 112, 15, 8,
+  7, 0, 0, 35, 0, 72, 0, 82, 0, 0,
+  0, 30, 0, 0, 1, 0, 0, 19, 0, 19,
+  0, 50, 59, 42, 0, 14, 0, 45, 0, 0,
+  97, 0, 62, 0, 33, 0, 0, 70, 0, 0,
+  53, 0, 0, 26, 12, 6, 27, 25, 76, 0,
+  0, 26, 25, 0, 0, 18, 0, 0, 77, 83,
+  0, 0, 0, 18, 0, 4, 54, 0, 0, 0,
+  24, 0, 25, 0, 15, 39, 25, 35, 17, 0,
+  0, 31, 47, 29, 0, 0, 0, 45, 0, 0,
+  0, 0, 38, 0, 3, 0, 0, 1, 0, 22,
+  25, 0, 0, 20, 18, 58, 66, 69, 39, 34,
+  0, 0, 61, 0, 24, 0, 24, 41, 11, 21,
+  49, 14, 29, 7, 0, 0, 0, 34, 1, 0,
+  22, 29, 0, 26, 0, 5, 31, 0, 36, 0,
+  13, 0, 0, 0, 0, 34, 0, 0, 10, 55,
+  10, 6, 0, 0, 30, 0, 0, 0, 35, 0,
+  20, 14, 0, 4, 0, 6, 0, 0, 0, 0,
+  31, 0, 49, 0, 0, 0, 64, 30, 0, 37,
+  0, 10, 0, 53, 0, 8, 43, 93, 0, 42,
+  5, 3, 30, 39, 93, 5, 0, 0, 11, 0,
+  68, 0, 0, 79, 5, 0, 0, 0, 30, 61,
+  0, 15, 39, 0, 23, 0, 0, 0, 0, 0,
+  12, 0, 0, 0, 11, 0, 7, 0, 19, 17,
+  24, 37, 19, 83, 100, 57, 60, 86, 0, 0,
+  16, 0, 0, 0, 1, 37, 9, 22, 45, 0,
+  3, 24, 0, 9, 0, 26, 12, 0, 0, 30,
+  0, 58, 0, 45, 5, 36, 29, 8, 0, 14,
+  0, 6, 0, 0, 0, 30, 1, 47, 31, 38,
+  0, 0, 15, 0, 0, 0, 7, 0, 28, 11,
+  0, 0, 0, 19, 0, 0, 0, 0, 25, 0,
+  71, 0, 0, 0, 48, 11, 37, 0, 0, 0,
+  0, 14, 0, 10, 19, 113, 22, 41, 0, 37,
+  0, 20, 39, 0, 0, 0, 11, 0, 10, 0,
+  0, 52, 9, 11, 0, 0, 76, 50, 5, 16,
+  33, 0, 25, 22, 0, 4, 0, 0, 10, 0,
+  0, 0, 0, 0, 0, 0, 34, 0, 47, 18,
+  11, 11, 105, 33, 25, 144, 0, 0, 0, 0,
+  0, 0, 17, 0, 0, 0, 17, 5, 23, 0,
+  0, 94, 8, 12, 0, 0, 0, 0, 0, 52,
+  0, 26, 0, 34, 0, 30, 0, 0, 0, 25,
+  0, 0, 0, 39, 0, 0, 23, 37, 0, 0,
+  0, 86, 0, 0, 64, 0, 59, 0, 41, 0,
+  0, 32, 0, 17, 51, 3, 0, 0, 41, 0,
+  4, 7, 56, 0, 27, 0, 0, 0, 0, 10,
+  0, 0, 45, 50, 55, 11, 0, 9, 2, 0,
+  0, 0, 20, 0, 18, 0, 0, 0, 20, 19,
+  0, 0, 0, 0, 22, 38, 4, 0, 0, 0,
+  37, 28, 0, 0, 0, 0, 63, 0, 8, 0,
+  0, 0, 0, 12, 39, 5, 0, 0, 21, 49,
+  94, 59, 0, 40, 0, 0, 37, 0, 0, 2,
+  0, 53, 10, 6, 39, 18, 0, 5, 0, 0,
+  0, 10, 0, 0, 0, 12, 0, 36, 18, 54,
+  0, 12, 26, 2, 59, 42, 0, 0, 0, 6,
+  17, 0, 0, 42, 0, 10, 0, 0, 60, 0,
+  0, 0, 47, 0, 14, 4, 5, 0, 0, 0,
+  0, 0, 0, 0, 19, 0, 49, 8, 0, 0,
+  50, 31, 0, 14, 0, 0, 0, 49, 0, 39,
+  0, 93, 0, 53, 2, 0, 47, 10, 28, 14,
+  0, 0, 7, 0, 11, 20, 0, 63, 0, 0,
+  0, 0, 64, 95, 0, 0, 0, 0, 42, 0,
+  0, 0, 37, 0, 0, 0, 0, 29, 0, 0,
+  0, 0, 8, 31, 58, 8, 24, 50, 130, 56,
+  9, 113, 0, 0, 0, 0, 0, 0, 18, 53,
+  0, 15, 32, 9, 0, 14, 0, 26, 0, 12,
+  0, 0, 0, 0, 0, 68, 18, 55, 0, 60,
+  43, 18, 30, 1, 0, 18, 0, 0, 0, 3,
+  0, 17, 0, 39, 0, 0, 36, 38, 0, 0,
+  41, 0, 32, 16, 29, 0, 0, 0, 0, 0,
+  31, 0, 0, 0, 41, 0, 0, 0, 42, 0,
+  0, 3, 0, 0, 2, 46, 0, 22, 20, 94,
+  27, 22, 13, 1, 28, 26, 6, 0, 0, 0,
+  15, 0, 0, 0, 0, 25, 2, 0, 0, 0,
+  20, 67, 0, 0, 0, 2, 64, 0, 0, 16,
+  0, 0, 21, 0, 0, 13, 0, 0, 0, 18,
+  28, 25, 23, 8, 18, 29, 81, 2, 20, 83,
+  0, 0, 0, 0, 0, 0, 29, 22, 0, 0,
+  11, 0, 22, 0, 16, 80, 7, 25, 0, 0,
+  0, 0, 0, 50, 53, 0, 0, 40, 19, 7,
+  0, 0, 0, 34, 18, 28, 0, 28, 19, 0,
+  0, 38, 0, 0, 0, 100, 0, 0, 72, 0,
+  56, 27, 67, 0, 0, 10, 0, 45, 0, 38,
+  0, 0, 0, 0, 0, 13, 35, 21, 7, 22,
+  0, 0, 0, 14, 4, 0, 18, 9, 61, 9,
+  0, 0, 33, 0, 0, 2, 69, 0, 11, 0,
+  0, 0, 29, 21, 0, 0, 0, 0, 26, 25,
+  0, 0, 0, 32, 64, 0, 0, 16, 0, 0,
+  50, 0, 17, 27, 16, 8, 0, 0, 53, 22,
+  0, 8, 42, 127, 15, 99, 80, 43, 0, 0,
+  43, 0, 32, 0, 35, 29, 0, 0, 11, 0,
+  41, 15, 0, 0, 0, 47, 24, 0, 52, 29,
+  0, 37, 5, 49, 69, 0, 20, 0, 0, 0,
+  0, 0, 0, 17, 0, 6, 19, 56, 44, 46,
+  0, 7, 4, 0, 0, 17, 32, 0, 50, 2,
+  0, 29, 21, 24, 0, 8, 0, 0, 52, 4,
+  27, 0, 0, 21, 45, 4, 6, 45, 10, 2,
+  0, 2, 0, 19, 40, 73, 0, 17, 5, 38,
+  21, 49, 107, 0, 0, 49, 0, 0, 90, 0,
+  23, 57, 7, 99, 1, 0, 25, 33, 41, 62,
+  122, 0, 7, 22, 36, 0, 0, 0, 0, 0,
+  0, 0, 13, 0, 43, 0, 45, 1, 13, 74,
+  17, 8, 86, 68, 23, 217, 0, 0, 29, 0,
+  0, 0, 32, 0, 0, 0, 31, 18, 66, 0,
+  0, 112, 15, 8, 7, 0, 0, 35, 0, 72,
+  0, 82, 0, 0, 0, 30, 0, 0, 1, 0,
+  0, 19, 0, 19, 0, 50, 59, 42, 0, 14,
+  0, 45, 0, 0, 97, 0, 62, 0, 33, 0,
+  0, 70, 0, 0, 53, 0, 0, 26, 12, 6,
+  27, 25, 76, 0, 0, 26, 25, 0, 0, 18,
+  0, 0, 77, 83, 0, 0, 0, 18, 0, 4,
+  54, 0, 0, 0, 24, 0, 25, 0, 15, 39,
+  25, 35, 17, 0, 0, 31, 47, 29, 0, 0,
+  0, 45, 0, 0, 0, 0, 38, 0, 3, 0,
+  0, 1, 0, 22, 25, 0, 0, 20, 0, 0,
+  0, 0, 1, 125, 0, 0, 0, 0, 0, 0,
+  59, 8, 0, 44, 12, 40, 18, 0, 40, 6,
+  0, 49, 0, 0, 0, 0, 0, 14, 40, 0,
+  0, 17, 0, 8, 0, 16, 0, 48, 35, 47,
+  0, 33, 1, 0, 7, 27, 0, 35, 0, 77,
+  28, 0, 14, 0, 38, 0, 36, 0, 0, 14,
+  0, 11, 0, 0, 0, 3, 8, 0, 16, 34,
+  27, 15, 0, 70, 0, 0, 0, 26, 7, 0,
+  14, 12, 42, 0, 12, 0, 8, 25, 0, 47,
+  52, 0, 15, 13, 0, 0, 17, 28, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 32, 29, 12,
+  0, 47, 0, 0, 66, 14, 50, 0, 35, 14,
+  18, 0, 67, 1, 0, 0, 19, 83, 100, 57,
+  60, 86, 0, 0, 16, 0, 0, 0, 1, 37,
+  9, 22, 45, 0, 3, 24, 0, 9, 0, 26,
+  12, 0, 0, 30, 0, 58, 0, 45, 5, 36,
+  29, 8, 0, 14, 0, 6, 0, 0, 0, 30,
+  1, 47, 31, 38, 0, 0, 15, 0, 0, 0,
+  7, 0, 28, 11, 0, 0, 0, 19, 0, 0,
+  0, 0, 25, 0, 71, 0, 0, 0, 48, 11,
+  37, 0, 0, 0, 0, 14, 0, 10, 19, 113,
+  22, 41, 0, 37, 0, 20, 39, 0, 0, 0,
+  11, 0, 10, 0, 0, 52, 9, 11, 0, 0,
+  76, 50, 5, 16, 33, 0, 25, 22, 0, 4,
+  0, 0, 10, 0, 0, 0, 0, 0, 0, 0,
+  34, 0, 47, 18, 11, 11, 105, 33, 25, 144,
+  0, 0, 0, 0, 0, 0, 17, 0, 0, 0,
+  17, 5, 23, 0, 0, 94, 8, 12, 0, 0,
+  0, 0, 0, 52, 0, 26, 0, 34, 0, 30,
+  0, 0, 0, 25, 0, 0, 0, 39, 0, 0,
+  23, 37, 0, 0, 0, 86, 0, 0, 64, 0,
+  59, 0, 41, 0, 0, 32, 0, 17, 51, 3,
+  0, 0, 41, 0, 4, 7, 56, 0, 27, 0,
+  0, 0, 0, 10, 0, 0, 45, 50, 55, 11,
+  0, 9, 2, 0, 0, 0, 20, 0, 18, 0,
+  0, 0, 20, 19, 0, 0, 0, 0, 22, 38,
+  4, 0, 0, 0, 37, 28, 0, 0, 0, 0,
+  63, 0, 8, 0, 0, 0, 0, 12, 39, 5,
+  0, 0, 0, 2, 46, 0, 14, 18, 11, 0,
+  12, 0, 0, 11, 59, 26, 0, 39, 3, 30,
+  27, 0, 68, 23, 33, 23, 0, 0, 0, 0,
+  0, 0, 61, 0, 0, 0, 0, 7, 0, 8,
+  0, 25, 64, 32, 0, 78, 13, 0, 0, 10,
+  0, 12, 0, 114, 19, 0, 44, 0, 53, 0,
+  52, 0, 0, 0, 0, 20, 19, 0, 0, 11,
+  0, 0, 0, 19, 15, 39, 5, 36, 0, 0,
+  0, 0, 27, 0, 8, 0, 65, 1, 0, 0,
+  39, 0, 0, 25, 36, 0, 0, 17, 0, 0,
+  33, 36, 0, 0, 0, 0, 22, 0, 0, 0,
+  0, 13, 66, 18, 0, 34, 0, 0, 63, 12,
+  74, 5, 47, 3, 0, 0, 82, 14, 12, 0,
+  24, 50, 130, 56, 9, 113, 0, 0, 0, 0,
+  0, 0, 18, 53, 0, 15, 32, 9, 0, 14,
+  0, 26, 0, 12, 0, 0, 0, 0, 0, 68,
+  18, 55, 0, 60, 43, 18, 30, 1, 0, 18,
+  0, 0, 0, 3, 0, 17, 0, 39, 0, 0,
+  36, 38, 0, 0, 41, 0, 32, 16, 29, 0,
+  0, 0, 0, 0, 31, 0, 0, 0, 41, 0,
+  0, 0, 42, 0, 0, 3, 0, 0, 2, 46,
+  0, 22, 20, 94, 27, 22, 13, 1, 28, 26,
+  6, 0, 0, 0, 15, 0, 0, 0, 0, 25,
+  2, 0, 0, 0, 20, 67, 0, 0, 0, 2,
+  64, 0, 0, 16, 0, 0, 21, 0, 0, 13,
+  0, 0, 0, 18, 28, 25, 23, 8, 18, 29,
+  81, 2, 20, 83, 0, 0, 0, 0, 0, 0,
+  29, 22, 0, 0, 11, 0, 22, 0, 16, 80,
+  7, 25, 0, 0, 0, 0, 0, 50, 53, 0,
+  0, 40, 19, 7, 0, 0, 0, 34, 18, 28,
+  0, 28, 19, 0, 0, 38, 0, 0, 0, 100,
+  0, 0, 72, 0, 56, 27, 67, 0, 0, 10,
+  0, 45, 0, 38, 0, 0, 0, 0, 0, 13,
+  35, 21, 7, 22, 0, 0, 0, 14, 4, 0,
+  18, 9, 61, 9, 0, 0, 33, 0, 0, 2,
+  69, 0, 11, 0, 0, 0, 29, 21, 0, 0,
+  0, 0, 26, 25, 0, 0, 0, 32, 64, 0,
+  0, 16, 0, 0, 50, 0, 17, 27, 16, 8,
+  0, 0, 53, 22, 0, 8, 0, 3, 48, 0,
+  28, 0, 0, 0, 12, 0, 0, 8, 33, 45,
+  0, 3, 0, 28, 37, 0, 73, 40, 75, 3,
+  0, 0, 0, 6, 0, 0, 38, 0, 0, 0,
+  0, 17, 0, 11, 18, 0, 45, 20, 0, 94,
+  30, 2, 0, 37, 0, 0, 0, 118, 0, 0,
+  57, 0, 32, 0, 52, 0, 0, 0, 6, 0,
+  65, 0, 0, 28, 0, 6, 0, 7, 0, 28,
+  10, 0, 0, 0, 0, 0, 20, 0, 18, 0,
+  66, 3, 0, 0, 33, 0, 0, 0, 0, 0,
+  0, 35, 0, 0, 33, 47, 0, 0, 0, 0,
+  30, 0, 0, 0, 0, 0, 68, 9, 0, 32,
+  0, 0, 91, 10, 53, 25, 59, 0, 0, 0,
+  63, 11, 16, 0, 17, 8, 86, 68, 23, 217,
+  0, 0, 29, 0, 0, 0, 32, 0, 0, 0,
+  31, 18, 66, 0, 0, 112, 15, 8, 7, 0,
+  0, 35, 0, 72, 0, 82, 0, 0, 0, 30,
+  0, 0, 1, 0, 0, 19, 0, 19, 0, 50,
+  59, 42, 0, 14, 0, 45, 0, 0, 97, 0,
+  62, 0, 33, 0, 0, 70, 0, 0, 53, 0,
+  0, 26, 12, 6, 27, 25, 76, 0, 0, 26,
+  25, 0, 0, 18, 0, 0, 77, 83, 0, 0,
+  0, 18, 0, 4, 54, 0, 0, 0, 24, 0,
+  25, 0, 15, 39, 25, 35, 17, 0, 0, 31,
+  47, 29, 0, 0, 0, 45, 0, 0, 0, 0,
+  38, 0, 3, 0, 0, 1, 0, 22, 25, 0,
+  0, 20, 0, 0, 0, 0, 1, 125, 0, 0,
+  0, 0, 0, 0, 59, 8, 0, 44, 12, 40,
+  18, 0, 40, 6, 0, 49, 0, 0, 0, 0,
+  0, 14, 40, 0, 0, 17, 0, 8, 0, 16,
+  0, 48, 35, 47, 0, 33, 1, 0, 7, 27,
+  0, 35, 0, 77, 28, 0, 14, 0, 38, 0,
+  36, 0, 0, 14, 0, 11, 0, 0, 0, 3,
+  8, 0, 16, 34, 27, 15, 0, 70, 0, 0,
+  0, 26, 7, 0, 14, 12, 42, 0, 12, 0,
+  8, 25, 0, 47, 52, 0, 15, 13, 0, 0,
+  17, 28, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 32, 29, 12, 0, 47, 0, 0, 66, 14,
+  50, 0, 35, 14, 18, 0, 67, 1, 0, 0,
+  0, 0, 77, 0, 0, 0, 2, 0, 0, 0,
+  0, 1, 29, 58, 0, 41, 0, 69, 29, 7,
+  59, 19, 117, 17, 0, 0, 0, 5, 0, 0,
+  15, 0, 0, 0, 0, 13, 0, 12, 0, 0,
+  66, 0, 0, 79, 32, 0, 0, 0, 0, 6,
+  0, 87, 7, 0, 39, 0, 49, 0, 7, 0,
+  0, 1, 10, 0, 77, 0, 0, 21, 0, 50,
+  0, 0, 2, 19, 0, 7, 0, 0, 0, 0,
+  19, 0, 2, 0, 62, 8, 0, 0, 25, 0,
+  0, 13, 0, 0, 16, 30, 0, 0, 0, 54,
+  3, 0, 0, 0, 20, 0, 0, 0, 0, 0,
+  62, 11, 0, 38, 13, 0, 89, 23, 44, 14,
+  34, 0, 0, 0, 57, 0, 15, 0, 11, 11,
+  105, 33, 25, 144, 0, 0, 0, 0, 0, 0,
+  17, 0, 0, 0, 17, 5, 23, 0, 0, 94,
+  8, 12, 0, 0, 0, 0, 0, 52, 0, 26,
+  0, 34, 0, 30, 0, 0, 0, 25, 0, 0,
+  0, 39, 0, 0, 23, 37, 0, 0, 0, 86,
+  0, 0, 64, 0, 59, 0, 41, 0, 0, 32,
+  0, 17, 51, 3, 0, 0, 41, 0, 4, 7,
+  56, 0, 27, 0, 0, 0, 0, 10, 0, 0,
+  45, 50, 55, 11, 0, 9, 2, 0, 0, 0,
+  20, 0, 18, 0, 0, 0, 20, 19, 0, 0,
+  0, 0, 22, 38, 4, 0, 0, 0, 37, 28,
+  0, 0, 0, 0, 63, 0, 8, 0, 0, 0,
+  0, 12, 39, 5, 0, 0, 0, 2, 46, 0,
+  14, 18, 11, 0, 12, 0, 0, 11, 59, 26,
+  0, 39, 3, 30, 27, 0, 68, 23, 33, 23,
+  0, 0, 0, 0, 0, 0, 61, 0, 0, 0,
+  0, 7, 0, 8, 0, 25, 64, 32, 0, 78,
+  13, 0, 0, 10, 0, 12, 0, 114, 19, 0,
+  44, 0, 53, 0, 52, 0, 0, 0, 0, 20,
+  19, 0, 0, 11, 0, 0, 0, 19, 15, 39,
+  5, 36, 0, 0, 0, 0, 27, 0, 8, 0,
+  65, 1, 0, 0, 39, 0, 0, 25, 36, 0,
+  0, 17, 0, 0, 33, 36, 0, 0, 0, 0,
+  22, 0, 0, 0, 0, 13, 66, 18, 0, 34,
+  0, 0, 63, 12, 74, 5, 47, 3, 0, 0,
+  82, 14, 12, 0, 5, 0, 69, 0, 12, 8,
+  0, 0, 19, 0, 0, 0, 40, 75, 0, 7,
+  0, 50, 40, 0, 68, 50, 83, 1, 0, 0,
+  0, 31, 0, 3, 20, 0, 0, 0, 0, 5,
+  0, 22, 0, 0, 22, 4, 0, 91, 26, 21,
+  0, 48, 0, 0, 1, 153, 0, 0, 66, 0,
+  33, 0, 18, 0, 0, 0, 11, 0, 112, 0,
+  0, 0, 0, 59, 0, 0, 0, 7, 0, 0,
+  0, 0, 0, 0, 9, 0, 15, 0, 36, 8,
+  0, 0, 45, 0, 0, 0, 0, 0, 6, 8,
+  0, 0, 1, 53, 30, 0, 0, 0, 16, 0,
+  0, 5, 5, 0, 72, 5, 0, 42, 10, 0,
+  150, 0, 30, 25, 71, 0, 0, 0, 50, 0,
+  12, 0, 18, 29, 81, 2, 20, 83, 0, 0,
+  0, 0, 0, 0, 29, 22, 0, 0, 11, 0,
+  22, 0, 16, 80, 7, 25, 0, 0, 0, 0,
+  0, 50, 53, 0, 0, 40, 19, 7, 0, 0,
+  0, 34, 18, 28, 0, 28, 19, 0, 0, 38,
+  0, 0, 0, 100, 0, 0, 72, 0, 56, 27,
+  67, 0, 0, 10, 0, 45, 0, 38, 0, 0,
+  0, 0, 0, 13, 35, 21, 7, 22, 0, 0,
+  0, 14, 4, 0, 18, 9, 61, 9, 0, 0,
+  33, 0, 0, 2, 69, 0, 11, 0, 0, 0,
+  29, 21, 0, 0, 0, 0, 26, 25, 0, 0,
+  0, 32, 64, 0, 0, 16, 0, 0, 50, 0,
+  17, 27, 16, 8, 0, 0, 53, 22, 0, 8,
+  0, 3, 48, 0, 28, 0, 0, 0, 12, 0,
+  0, 8, 33, 45, 0, 3, 0, 28, 37, 0,
+  73, 40, 75, 3, 0, 0, 0, 6, 0, 0,
+  38, 0, 0, 0, 0, 17, 0, 11, 18, 0,
+  45, 20, 0, 94, 30, 2, 0, 37, 0, 0,
+  0, 118, 0, 0, 57, 0, 32, 0, 52, 0,
+  0, 0, 6, 0, 65, 0, 0, 28, 0, 6,
+  0, 7, 0, 28, 10, 0, 0, 0, 0, 0,
+  20, 0, 18, 0, 66, 3, 0, 0, 33, 0,
+  0, 0, 0, 0, 0, 35, 0, 0, 33, 47,
+  0, 0, 0, 0, 30, 0, 0, 0, 0, 0,
+  68, 9, 0, 32, 0, 0, 91, 10, 53, 25,
+  59, 0, 0, 0, 63, 11, 16, 0, 8, 0,
+  33, 0, 50, 5, 0, 0, 41, 0, 0, 0,
+  30, 75, 0, 0, 0, 14, 33, 0, 50, 46,
+  16, 2, 0, 0, 0, 31, 0, 34, 0, 0,
+  0, 0, 0, 2, 0, 20, 0, 0, 0, 0,
+  0, 77, 19, 41, 0, 85, 0, 0, 0, 170,
+  0, 6, 47, 0, 22, 0, 0, 0, 0, 0,
+  0, 0, 84, 0, 0, 0, 0, 41, 0, 0,
+  0, 17, 0, 0, 0, 0, 0, 0, 22, 0,
+  8, 0, 16, 0, 0, 30, 54, 0, 23, 0,
+  0, 0, 0, 0, 8, 0, 0, 58, 30, 0,
+  2, 0, 14, 0, 12, 18, 40, 0, 63, 5,
+  0, 35, 4, 0, 159, 0, 5, 42, 83, 1,
+  29, 0, 53, 0, 1, 0, 0, 0, 0, 0,
+  1, 125, 0, 0, 0, 0, 0, 0, 59, 8,
+  0, 44, 12, 40, 18, 0, 40, 6, 0, 49,
+  0, 0, 0, 0, 0, 14, 40, 0, 0, 17,
+  0, 8, 0, 16, 0, 48, 35, 47, 0, 33,
+  1, 0, 7, 27, 0, 35, 0, 77, 28, 0,
+  14, 0, 38, 0, 36, 0, 0, 14, 0, 11,
+  0, 0, 0, 3, 8, 0, 16, 34, 27, 15,
+  0, 70, 0, 0, 0, 26, 7, 0, 14, 12,
+  42, 0, 12, 0, 8, 25, 0, 47, 52, 0,
+  15, 13, 0, 0, 17, 28, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 32, 29, 12, 0, 47,
+  0, 0, 66, 14, 50, 0, 35, 14, 18, 0,
+  67, 1, 0, 0, 0, 0, 77, 0, 0, 0,
+  2, 0, 0, 0, 0, 1, 29, 58, 0, 41,
+  0, 69, 29, 7, 59, 19, 117, 17, 0, 0,
+  0, 5, 0, 0, 15, 0, 0, 0, 0, 13,
+  0, 12, 0, 0, 66, 0, 0, 79, 32, 0,
+  0, 0, 0, 6, 0, 87, 7, 0, 39, 0,
+  49, 0, 7, 0, 0, 1, 10, 0, 77, 0,
+  0, 21, 0, 50, 0, 0, 2, 19, 0, 7,
+  0, 0, 0, 0, 19, 0, 2, 0, 62, 8,
+  0, 0, 25, 0, 0, 13, 0, 0, 16, 30,
+  0, 0, 0, 54, 3, 0, 0, 0, 20, 0,
+  0, 0, 0, 0, 62, 11, 0, 38, 13, 0,
+  89, 23, 44, 14, 34, 0, 0, 0, 57, 0,
+  15, 0, 25, 0, 64, 0, 17, 12, 0, 0,
+  23, 0, 0, 6, 16, 72, 0, 0, 0, 19,
+  42, 0, 48, 60, 61, 0, 0, 0, 0, 26,
+  0, 41, 0, 0, 0, 0, 0, 3, 0, 6,
+  0, 0, 0, 0, 0, 69, 18, 17, 0, 65,
+  0, 0, 0, 167, 0, 0, 66, 0, 29, 0,
+  4, 0, 0, 0, 24, 0, 113, 0, 0, 10,
+  0, 64, 0, 4, 0, 0, 0, 0, 0, 0,
+  0, 0, 12, 0, 12, 0, 32, 1, 0, 15,
+  43, 0, 26, 0, 0, 0, 27, 0, 11, 0,
+  0, 71, 39, 0, 0, 0, 13, 0, 0, 24,
+  30, 0, 73, 0, 0, 44, 14, 0, 155, 0,
+  5, 26, 74, 0, 0, 0, 54, 0, 0, 0,
+  0, 2, 46, 0, 14, 18, 11, 0, 12, 0,
+  0, 11, 59, 26, 0, 39, 3, 30, 27, 0,
+  68, 23, 33, 23, 0, 0, 0, 0, 0, 0,
+  61, 0, 0, 0, 0, 7, 0, 8, 0, 25,
+  64, 32, 0, 78, 13, 0, 0, 10, 0, 12,
+  0, 114, 19, 0, 44, 0, 53, 0, 52, 0,
+  0, 0, 0, 20, 19, 0, 0, 11, 0, 0,
+  0, 19, 15, 39, 5, 36, 0, 0, 0, 0,
+  27, 0, 8, 0, 65, 1, 0, 0, 39, 0,
+  0, 25, 36, 0, 0, 17, 0, 0, 33, 36,
+  0, 0, 0, 0, 22, 0, 0, 0, 0, 13,
+  66, 18, 0, 34, 0, 0, 63, 12, 74, 5,
+  47, 3, 0, 0, 82, 14, 12, 0, 5, 0,
+  69, 0, 12, 8, 0, 0, 19, 0, 0, 0,
+  40, 75, 0, 7, 0, 50, 40, 0, 68, 50,
+  83, 1, 0, 0, 0, 31, 0, 3, 20, 0,
+  0, 0, 0, 5, 0, 22, 0, 0, 22, 4,
+  0, 91, 26, 21, 0, 48, 0, 0, 1, 153,
+  0, 0, 66, 0, 33, 0, 18, 0, 0, 0,
+  11, 0, 112, 0, 0, 0, 0, 59, 0, 0,
+  0, 7, 0, 0, 0, 0, 0, 0, 9, 0,
+  15, 0, 36, 8, 0, 0, 45, 0, 0, 0,
+  0, 0, 6, 8, 0, 0, 1, 53, 30, 0,
+  0, 0, 16, 0, 0, 5, 5, 0, 72, 5,
+  0, 42, 10, 0, 150, 0, 30, 25, 71, 0,
+  0, 0, 50, 0, 12, 0, 0, 0, 9, 0,
+  23, 7, 0, 0, 42, 0, 0, 0, 8, 47,
+  0, 0, 0, 0, 32, 0, 34, 11, 0, 18,
+  0, 0, 19, 48, 0, 74, 0, 0, 9, 0,
+  0, 0, 0, 14, 0, 0, 0, 0, 0, 37,
+  0, 40, 0, 86, 0, 0, 8, 140, 13, 21,
+  34, 0, 22, 0, 0, 0, 0, 0, 0, 0,
+  51, 0, 0, 0, 0, 14, 0, 9, 0, 0,
+  0, 24, 0, 0, 0, 11, 28, 0, 0, 0,
+  0, 0, 0, 47, 50, 10, 57, 0, 0, 0,
+  10, 0, 28, 0, 0, 84, 46, 0, 26, 0,
+  7, 0, 21, 14, 59, 0, 50, 0, 0, 36,
+  7, 0, 152, 0, 0, 31, 100, 6, 74, 0,
+  41, 0, 0, 0, 0, 3, 48, 0, 28, 0,
+  0, 0, 12, 0, 0, 8, 33, 45, 0, 3,
+  0, 28, 37, 0, 73, 40, 75, 3, 0, 0,
+  0, 6, 0, 0, 38, 0, 0, 0, 0, 17,
+  0, 11, 18, 0, 45, 20, 0, 94, 30, 2,
+  0, 37, 0, 0, 0, 118, 0, 0, 57, 0,
+  32, 0, 52, 0, 0, 0, 6, 0, 65, 0,
+  0, 28, 0, 6, 0, 7, 0, 28, 10, 0,
+  0, 0, 0, 0, 20, 0, 18, 0, 66, 3,
+  0, 0, 33, 0, 0, 0, 0, 0, 0, 35,
+  0, 0, 33, 47, 0, 0, 0, 0, 30, 0,
+  0, 0, 0, 0, 68, 9, 0, 32, 0, 0,
+  91, 10, 53, 25, 59, 0, 0, 0, 63, 11,
+  16, 0, 8, 0, 33, 0, 50, 5, 0, 0,
+  41, 0, 0, 0, 30, 75, 0, 0, 0, 14,
+  33, 0, 50, 46, 16, 2, 0, 0, 0, 31,
+  0, 34, 0, 0, 0, 0, 0, 2, 0, 20,
+  0, 0, 0, 0, 0, 77, 19, 41, 0, 85,
+  0, 0, 0, 170, 0, 6, 47, 0, 22, 0,
+  0, 0, 0, 0, 0, 0, 84, 0, 0, 0,
+  0, 41, 0, 0, 0, 17, 0, 0, 0, 0,
+  0, 0, 22, 0, 8, 0, 16, 0, 0, 30,
+  54, 0, 23, 0, 0, 0, 0, 0, 8, 0,
+  0, 58, 30, 0, 2, 0, 14, 0, 12, 18,
+  40, 0, 63, 5, 0, 35, 4, 0, 159, 0,
+  5, 42, 83, 1, 29, 0, 53, 0, 1, 0,
+  0, 0, 0, 0, 8, 8, 0, 23, 35, 18,
+  0, 1, 2, 8, 0, 7, 6, 22, 10, 0,
+  3, 0, 0, 46, 0, 0, 38, 57, 0, 84,
+  0, 0, 66, 0, 0, 0, 0, 16, 0, 0,
+  0, 0, 1, 25, 24, 69, 0, 69, 0, 1,
+  25, 65, 56, 29, 12, 5, 16, 0, 0, 0,
+  0, 6, 0, 0, 0, 0, 12, 0, 0, 0,
+  0, 0, 13, 10, 0, 63, 0, 0, 0, 19,
+  57, 0, 0, 20, 0, 0, 0, 46, 34, 26,
+  87, 1, 0, 0, 7, 0, 9, 0, 0, 65,
+  36, 0, 32, 0, 1, 0, 50, 0, 55, 43,
+  17, 0, 0, 23, 0, 0, 119, 0, 0, 38,
+  90, 12, 104, 0, 46, 0, 0, 0, 0, 0,
+  77, 0, 0, 0, 2, 0, 0, 0, 0, 1,
+  29, 58, 0, 41, 0, 69, 29, 7, 59, 19,
+  117, 17, 0, 0, 0, 5, 0, 0, 15, 0,
+  0, 0, 0, 13, 0, 12, 0, 0, 66, 0,
+  0, 79, 32, 0, 0, 0, 0, 6, 0, 87,
+  7, 0, 39, 0, 49, 0, 7, 0, 0, 1,
+  10, 0, 77, 0, 0, 21, 0, 50, 0, 0,
+  2, 19, 0, 7, 0, 0, 0, 0, 19, 0,
+  2, 0, 62, 8, 0, 0, 25, 0, 0, 13,
+  0, 0, 16, 30, 0, 0, 0, 54, 3, 0,
+  0, 0, 20, 0, 0, 0, 0, 0, 62, 11,
+  0, 38, 13, 0, 89, 23, 44, 14, 34, 0,
+  0, 0, 57, 0, 15, 0, 25, 0, 64, 0,
+  17, 12, 0, 0, 23, 0, 0, 6, 16, 72,
+  0, 0, 0, 19, 42, 0, 48, 60, 61, 0,
+  0, 0, 0, 26, 0, 41, 0, 0, 0, 0,
+  0, 3, 0, 6, 0, 0, 0, 0, 0, 69,
+  18, 17, 0, 65, 0, 0, 0, 167, 0, 0,
+  66, 0, 29, 0, 4, 0, 0, 0, 24, 0,
+  113, 0, 0, 10, 0, 64, 0, 4, 0, 0,
+  0, 0, 0, 0, 0, 0, 12, 0, 12, 0,
+  32, 1, 0, 15, 43, 0, 26, 0, 0, 0,
+  27, 0, 11, 0, 0, 71, 39, 0, 0, 0,
+  13, 0, 0, 24, 30, 0, 73, 0, 0, 44,
+  14, 0, 155, 0, 5, 26, 74, 0, 0, 0,
+  54, 0, 0, 0, 0, 0, 0, 0, 12, 0,
+  0, 14, 34, 15, 0, 0, 26, 34, 0, 0,
+  0, 21, 29, 0, 8, 0, 0, 45, 0, 0,
+  48, 64, 6, 83, 0, 0, 55, 0, 0, 0,
+  0, 1, 0, 5, 0, 0, 0, 16, 10, 46,
+  0, 58, 0, 8, 7, 104, 37, 30, 33, 0,
+  15, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  6, 0, 0, 19, 0, 0, 21, 0, 0, 63,
+  0, 0, 0, 9, 39, 0, 0, 13, 0, 0,
+  0, 59, 43, 21, 114, 3, 0, 0, 28, 0,
+  36, 0, 0, 91, 40, 0, 32, 0, 7, 0,
+  28, 8, 75, 20, 37, 0, 0, 8, 5, 0,
+  131, 0, 0, 37, 103, 0, 101, 0, 70, 0,
+  0, 0, 5, 0, 69, 0, 12, 8, 0, 0,
+  19, 0, 0, 0, 40, 75, 0, 7, 0, 50,
+  40, 0, 68, 50, 83, 1, 0, 0, 0, 31,
+  0, 3, 20, 0, 0, 0, 0, 5, 0, 22,
+  0, 0, 22, 4, 0, 91, 26, 21, 0, 48,
+  0, 0, 1, 153, 0, 0, 66, 0, 33, 0,
+  18, 0, 0, 0, 11, 0, 112, 0, 0, 0,
+  0, 59, 0, 0, 0, 7, 0, 0, 0, 0,
+  0, 0, 9, 0, 15, 0, 36, 8, 0, 0,
+  45, 0, 0, 0, 0, 0, 6, 8, 0, 0,
+  1, 53, 30, 0, 0, 0, 16, 0, 0, 5,
+  5, 0, 72, 5, 0, 42, 10, 0, 150, 0,
+  30, 25, 71, 0, 0, 0, 50, 0, 12, 0,
+  0, 0, 9, 0, 23, 7, 0, 0, 42, 0,
+  0, 0, 8, 47, 0, 0, 0, 0, 32, 0,
+  34, 11, 0, 18, 0, 0, 19, 48, 0, 74,
+  0, 0, 9, 0, 0, 0, 0, 14, 0, 0,
+  0, 0, 0, 37, 0, 40, 0, 86, 0, 0,
+  8, 140, 13, 21, 34, 0, 22, 0, 0, 0,
+  0, 0, 0, 0, 51, 0, 0, 0, 0, 14,
+  0, 9, 0, 0, 0, 24, 0, 0, 0, 11,
+  28, 0, 0, 0, 0, 0, 0, 47, 50, 10,
+  57, 0, 0, 0, 10, 0, 28, 0, 0, 84,
+  46, 0, 26, 0, 7, 0, 21, 14, 59, 0,
+  50, 0, 0, 36, 7, 0, 152, 0, 0, 31,
+  100, 6, 74, 0, 41, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 24, 26, 15, 20, 0, 5,
+  0, 0, 4, 23, 15, 29, 19, 5, 0, 0,
+  0, 56, 21, 39, 37, 55, 0, 52, 0, 0,
+  82, 0, 11, 0, 0, 14, 0, 19, 0, 6,
+  0, 1, 10, 45, 30, 46, 0, 40, 24, 27,
+  55, 43, 0, 0, 9, 0, 0, 42, 0, 0,
+  0, 0, 0, 0, 32, 0, 0, 0, 0, 2,
+  11, 0, 20, 67, 0, 0, 0, 27, 69, 0,
+  0, 21, 0, 0, 2, 43, 16, 39, 82, 7,
+  0, 0, 15, 0, 21, 0, 0, 53, 8, 0,
+  42, 0, 0, 0, 48, 0, 67, 45, 15, 0,
+  2, 4, 0, 0, 73, 0, 0, 11, 69, 15,
+  131, 0, 65, 0, 0, 0, 8, 0, 33, 0,
+  50, 5, 0, 0, 41, 0, 0, 0, 30, 75,
+  0, 0, 0, 14, 33, 0, 50, 46, 16, 2,
+  0, 0, 0, 31, 0, 34, 0, 0, 0, 0,
+  0, 2, 0, 20, 0, 0, 0, 0, 0, 77,
+  19, 41, 0, 85, 0, 0, 0, 170, 0, 6,
+  47, 0, 22, 0, 0, 0, 0, 0, 0, 0,
+  84, 0, 0, 0, 0, 41, 0, 0, 0, 17,
+  0, 0, 0, 0, 0, 0, 22, 0, 8, 0,
+  16, 0, 0, 30, 54, 0, 23, 0, 0, 0,
+  0, 0, 8, 0, 0, 58, 30, 0, 2, 0,
+  14, 0, 12, 18, 40, 0, 63, 5, 0, 35,
+  4, 0, 159, 0, 5, 42, 83, 1, 29, 0,
+  53, 0, 1, 0, 0, 0, 0, 0, 8, 8,
+  0, 23, 35, 18, 0, 1, 2, 8, 0, 7,
+  6, 22, 10, 0, 3, 0, 0, 46, 0, 0,
+  38, 57, 0, 84, 0, 0, 66, 0, 0, 0,
+  0, 16, 0, 0, 0, 0, 1, 25, 24, 69,
+  0, 69, 0, 1, 25, 65, 56, 29, 12, 5,
+  16, 0, 0, 0, 0, 6, 0, 0, 0, 0,
+  12, 0, 0, 0, 0, 0, 13, 10, 0, 63,
+  0, 0, 0, 19, 57, 0, 0, 20, 0, 0,
+  0, 46, 34, 26, 87, 1, 0, 0, 7, 0,
+  9, 0, 0, 65, 36, 0, 32, 0, 1, 0,
+  50, 0, 55, 43, 17, 0, 0, 23, 0, 0,
+  119, 0, 0, 38, 90, 12, 104, 0, 46, 0,
+  0, 0, 0, 20, 0, 0, 0, 0, 29, 14,
+  2, 19, 0, 0, 0, 0, 38, 41, 27, 40,
+  14, 6, 0, 0, 0, 54, 43, 60, 8, 44,
+  0, 27, 0, 0, 65, 7, 13, 0, 0, 22,
+  3, 41, 0, 34, 37, 0, 17, 26, 31, 26,
+  0, 52, 14, 29, 52, 44, 0, 0, 0, 0,
+  0, 20, 0, 0, 0, 0, 0, 10, 54, 0,
+  11, 0, 0, 0, 18, 12, 28, 41, 0, 0,
+  0, 31, 87, 0, 6, 24, 0, 0, 7, 23,
+  21, 17, 38, 3, 0, 3, 0, 15, 11, 0,
+  0, 33, 0, 2, 25, 0, 0, 0, 36, 0,
+  28, 44, 10, 0, 0, 0, 0, 0, 17, 0,
+  0, 11, 27, 15, 97, 0, 59, 0, 0, 0,
+  25, 0, 64, 0, 17, 12, 0, 0, 23, 0,
+  0, 6, 16, 72, 0, 0, 0, 19, 42, 0,
+  48, 60, 61, 0, 0, 0, 0, 26, 0, 41,
+  0, 0, 0, 0, 0, 3, 0, 6, 0, 0,
+  0, 0, 0, 69, 18, 17, 0, 65, 0, 0,
+  0, 167, 0, 0, 66, 0, 29, 0, 4, 0,
+  0, 0, 24, 0, 113, 0, 0, 10, 0, 64,
+  0, 4, 0, 0, 0, 0, 0, 0, 0, 0,
+  12, 0, 12, 0, 32, 1, 0, 15, 43, 0,
+  26, 0, 0, 0, 27, 0, 11, 0, 0, 71,
+  39, 0, 0, 0, 13, 0, 0, 24, 30, 0,
+  73, 0, 0, 44, 14, 0, 155, 0, 5, 26,
+  74, 0, 0, 0, 54, 0, 0, 0, 0, 0,
+  0, 0, 12, 0, 0, 14, 34, 15, 0, 0,
+  26, 34, 0, 0, 0, 21, 29, 0, 8, 0,
+  0, 45, 0, 0, 48, 64, 6, 83, 0, 0,
+  55, 0, 0, 0, 0, 1, 0, 5, 0, 0,
+  0, 16, 10, 46, 0, 58, 0, 8, 7, 104,
+  37, 30, 33, 0, 15, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 6, 0, 0, 19, 0, 0,
+  21, 0, 0, 63, 0, 0, 0, 9, 39, 0,
+  0, 13, 0, 0, 0, 59, 43, 21, 114, 3,
+  0, 0, 28, 0, 36, 0, 0, 91, 40, 0,
+  32, 0, 7, 0, 28, 8, 75, 20, 37, 0,
+  0, 8, 5, 0, 131, 0, 0, 37, 103, 0,
+  101, 0, 70, 0, 0, 0, 0, 6, 23, 5,
+  0, 0, 44, 22, 34, 36, 0, 0, 1, 0,
+  0, 41, 20, 23, 3, 8, 0, 0, 0, 69,
+  18, 19, 51, 49, 164, 7, 0, 0, 85, 0,
+  15, 0, 0, 31, 6, 63, 0, 3, 29, 0,
+  23, 56, 20, 0, 0, 47, 0, 43, 48, 47,
+  7, 0, 0, 20, 0, 28, 0, 23, 0, 0,
+  0, 3, 58, 0, 2, 0, 18, 22, 54, 25,
+  23, 58, 0, 0, 0, 13, 76, 0, 7, 17,
+  0, 0, 4, 37, 62, 48, 83, 0, 0, 0,
+  8, 13, 24, 0, 0, 55, 0, 0, 26, 0,
+  38, 0, 56, 0, 44, 17, 29, 0, 10, 0,
+  0, 0, 37, 0, 0, 16, 21, 0, 77, 0,
+  71, 0, 5, 0, 0, 0, 9, 0, 23, 7,
+  0, 0, 42, 0, 0, 0, 8, 47, 0, 0,
+  0, 0, 32, 0, 34, 11, 0, 18, 0, 0,
+  19, 48, 0, 74, 0, 0, 9, 0, 0, 0,
+  0, 14, 0, 0, 0, 0, 0, 37, 0, 40,
+  0, 86, 0, 0, 8, 140, 13, 21, 34, 0,
+  22, 0, 0, 0, 0, 0, 0, 0, 51, 0,
+  0, 0, 0, 14, 0, 9, 0, 0, 0, 24,
+  0, 0, 0, 11, 28, 0, 0, 0, 0, 0,
+  0, 47, 50, 10, 57, 0, 0, 0, 10, 0,
+  28, 0, 0, 84, 46, 0, 26, 0, 7, 0,
+  21, 14, 59, 0, 50, 0, 0, 36, 7, 0,
+  152, 0, 0, 31, 100, 6, 74, 0, 41, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 24, 26,
+  15, 20, 0, 5, 0, 0, 4, 23, 15, 29,
+  19, 5, 0, 0, 0, 56, 21, 39, 37, 55,
+  0, 52, 0, 0, 82, 0, 11, 0, 0, 14,
+  0, 19, 0, 6, 0, 1, 10, 45, 30, 46,
+  0, 40, 24, 27, 55, 43, 0, 0, 9, 0,
+  0, 42, 0, 0, 0, 0, 0, 0, 32, 0,
+  0, 0, 0, 2, 11, 0, 20, 67, 0, 0,
+  0, 27, 69, 0, 0, 21, 0, 0, 2, 43,
+  16, 39, 82, 7, 0, 0, 15, 0, 21, 0,
+  0, 53, 8, 0, 42, 0, 0, 0, 48, 0,
+  67, 45, 15, 0, 2, 4, 0, 0, 73, 0,
+  0, 11, 69, 15, 131, 0, 65, 0, 0, 0,
+  0, 21, 39, 0, 0, 0, 39, 17, 22, 19,
+  5, 0, 0, 0, 20, 45, 30, 23, 5, 22,
+  0, 0, 0, 63, 27, 30, 38, 35, 115, 0,
+  0, 0, 74, 0, 11, 0, 0, 35, 3, 71,
+  0, 30, 31, 0, 4, 24, 50, 0, 0, 63,
+  18, 33, 32, 49, 0, 0, 0, 28, 0, 17,
+  6, 0, 0, 0, 0, 3, 73, 0, 42, 0,
+  0, 21, 39, 30, 32, 29, 0, 11, 0, 17,
+  87, 0, 23, 13, 0, 0, 7, 29, 62, 11,
+  41, 0, 0, 0, 0, 12, 26, 0, 0, 45,
+  0, 0, 5, 0, 19, 0, 45, 0, 16, 20,
+  23, 0, 12, 0, 0, 0, 0, 0, 0, 4,
+  0, 0, 66, 0, 50, 0, 0, 0, 0, 0,
+  0, 0, 8, 8, 0, 23, 35, 18, 0, 1,
+  2, 8, 0, 7, 6, 22, 10, 0, 3, 0,
+  0, 46, 0, 0, 38, 57, 0, 84, 0, 0,
+  66, 0, 0, 0, 0, 16, 0, 0, 0, 0,
+  1, 25, 24, 69, 0, 69, 0, 1, 25, 65,
+  56, 29, 12, 5, 16, 0, 0, 0, 0, 6,
+  0, 0, 0, 0, 12, 0, 0, 0, 0, 0,
+  13, 10, 0, 63, 0, 0, 0, 19, 57, 0,
+  0, 20, 0, 0, 0, 46, 34, 26, 87, 1,
+  0, 0, 7, 0, 9, 0, 0, 65, 36, 0,
+  32, 0, 1, 0, 50, 0, 55, 43, 17, 0,
+  0, 23, 0, 0, 119, 0, 0, 38, 90, 12,
+  104, 0, 46, 0, 0, 0, 0, 20, 0, 0,
+  0, 0, 29, 14, 2, 19, 0, 0, 0, 0,
+  38, 41, 27, 40, 14, 6, 0, 0, 0, 54,
+  43, 60, 8, 44, 0, 27, 0, 0, 65, 7,
+  13, 0, 0, 22, 3, 41, 0, 34, 37, 0,
+  17, 26, 31, 26, 0, 52, 14, 29, 52, 44,
+  0, 0, 0, 0, 0, 20, 0, 0, 0, 0,
+  0, 10, 54, 0, 11, 0, 0, 0, 18, 12,
+  28, 41, 0, 0, 0, 31, 87, 0, 6, 24,
+  0, 0, 7, 23, 21, 17, 38, 3, 0, 3,
+  0, 15, 11, 0, 0, 33, 0, 2, 25, 0,
+  0, 0, 36, 0, 28, 44, 10, 0, 0, 0,
+  0, 0, 17, 0, 0, 11, 27, 15, 97, 0,
+  59, 0, 0, 0, 0, 21, 41, 0, 0, 0,
+  50, 5, 27, 32, 0, 1, 0, 0, 18, 51,
+  26, 23, 10, 10, 0, 0, 3, 61, 32, 20,
+  24, 36, 100, 0, 0, 0, 68, 0, 15, 0,
+  0, 32, 0, 80, 0, 23, 33, 0, 0, 37,
+  49, 0, 0, 55, 6, 38, 34, 25, 3, 0,
+  7, 18, 0, 1, 6, 9, 0, 0, 0, 11,
+  56, 0, 58, 0, 18, 17, 48, 23, 33, 39,
+  0, 9, 0, 17, 86, 0, 20, 4, 0, 0,
+  14, 27, 46, 6, 34, 0, 0, 0, 0, 10,
+  3, 0, 0, 48, 0, 0, 5, 0, 21, 0,
+  43, 0, 0, 22, 7, 0, 0, 0, 0, 0,
+  0, 3, 4, 1, 0, 0, 46, 0, 47, 0,
+  0, 0, 0, 0, 0, 0, 12, 0, 0, 14,
+  34, 15, 0, 0, 26, 34, 0, 0, 0, 21,
+  29, 0, 8, 0, 0, 45, 0, 0, 48, 64,
+  6, 83, 0, 0, 55, 0, 0, 0, 0, 1,
+  0, 5, 0, 0, 0, 16, 10, 46, 0, 58,
+  0, 8, 7, 104, 37, 30, 33, 0, 15, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 6, 0,
+  0, 19, 0, 0, 21, 0, 0, 63, 0, 0,
+  0, 9, 39, 0, 0, 13, 0, 0, 0, 59,
+  43, 21, 114, 3, 0, 0, 28, 0, 36, 0,
+  0, 91, 40, 0, 32, 0, 7, 0, 28, 8,
+  75, 20, 37, 0, 0, 8, 5, 0, 131, 0,
+  0, 37, 103, 0, 101, 0, 70, 0, 0, 0,
+  0, 6, 23, 5, 0, 0, 44, 22, 34, 36,
+  0, 0, 1, 0, 0, 41, 20, 23, 3, 8,
+  0, 0, 0, 69, 18, 19, 51, 49, 164, 7,
+  0, 0, 85, 0, 15, 0, 0, 31, 6, 63,
+  0, 3, 29, 0, 23, 56, 20, 0, 0, 47,
+  0, 43, 48, 47, 7, 0, 0, 20, 0, 28,
+  0, 23, 0, 0, 0, 3, 58, 0, 2, 0,
+  18, 22, 54, 25, 23, 58, 0, 0, 0, 13,
+  76, 0, 7, 17, 0, 0, 4, 37, 62, 48,
+  83, 0, 0, 0, 8, 13, 24, 0, 0, 55,
+  0, 0, 26, 0, 38, 0, 56, 0, 44, 17,
+  29, 0, 10, 0, 0, 0, 37, 0, 0, 16,
+  21, 0, 77, 0, 71, 0, 5, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 24, 26, 15, 20, 0, 5, 0, 0,
+  4, 23, 15, 29, 19, 5, 0, 0, 0, 56,
+  21, 39, 37, 55, 0, 52, 0, 0, 82, 0,
+  11, 0, 0, 14, 0, 19, 0, 6, 0, 1,
+  10, 45, 30, 46, 0, 40, 24, 27, 55, 43,
+  0, 0, 9, 0, 0, 42, 0, 0, 0, 0,
+  0, 0, 32, 0, 0, 0, 0, 2, 11, 0,
+  20, 67, 0, 0, 0, 27, 69, 0, 0, 21,
+  0, 0, 2, 43, 16, 39, 82, 7, 0, 0,
+  15, 0, 21, 0, 0, 53, 8, 0, 42, 0,
+  0, 0, 48, 0, 67, 45, 15, 0, 2, 4,
+  0, 0, 73, 0, 0, 11, 69, 15, 131, 0,
+  65, 0, 0, 0, 0, 21, 39, 0, 0, 0,
+  39, 17, 22, 19, 5, 0, 0, 0, 20, 45,
+  30, 23, 5, 22, 0, 0, 0, 63, 27, 30,
+  38, 35, 115, 0, 0, 0, 74, 0, 11, 0,
+  0, 35, 3, 71, 0, 30, 31, 0, 4, 24,
+  50, 0, 0, 63, 18, 33, 32, 49, 0, 0,
+  0, 28, 0, 17, 6, 0, 0, 0, 0, 3,
+  73, 0, 42, 0, 0, 21, 39, 30, 32, 29,
+  0, 11, 0, 17, 87, 0, 23, 13, 0, 0,
+  7, 29, 62, 11, 41, 0, 0, 0, 0, 12,
+  26, 0, 0, 45, 0, 0, 5, 0, 19, 0,
+  45, 0, 16, 20, 23, 0, 12, 0, 0, 0,
+  0, 0, 0, 4, 0, 0, 66, 0, 50, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 20, 0, 0, 0, 0, 29, 14, 2, 19,
+  0, 0, 0, 0, 38, 41, 27, 40, 14, 6,
+  0, 0, 0, 54, 43, 60, 8, 44, 0, 27,
+  0, 0, 65, 7, 13, 0, 0, 22, 3, 41,
+  0, 34, 37, 0, 17, 26, 31, 26, 0, 52,
+  14, 29, 52, 44, 0, 0, 0, 0, 0, 20,
+  0, 0, 0, 0, 0, 10, 54, 0, 11, 0,
+  0, 0, 18, 12, 28, 41, 0, 0, 0, 31,
+  87, 0, 6, 24, 0, 0, 7, 23, 21, 17,
+  38, 3, 0, 3, 0, 15, 11, 0, 0, 33,
+  0, 2, 25, 0, 0, 0, 36, 0, 28, 44,
+  10, 0, 0, 0, 0, 0, 17, 0, 0, 11,
+  27, 15, 97, 0, 59, 0, 0, 0, 0, 21,
+  41, 0, 0, 0, 50, 5, 27, 32, 0, 1,
+  0, 0, 18, 51, 26, 23, 10, 10, 0, 0,
+  3, 61, 32, 20, 24, 36, 100, 0, 0, 0,
+  68, 0, 15, 0, 0, 32, 0, 80, 0, 23,
+  33, 0, 0, 37, 49, 0, 0, 55, 6, 38,
+  34, 25, 3, 0, 7, 18, 0, 1, 6, 9,
+  0, 0, 0, 11, 56, 0, 58, 0, 18, 17,
+  48, 23, 33, 39, 0, 9, 0, 17, 86, 0,
+  20, 4, 0, 0, 14, 27, 46, 6, 34, 0,
+  0, 0, 0, 10, 3, 0, 0, 48, 0, 0,
+  5, 0, 21, 0, 43, 0, 0, 22, 7, 0,
+  0, 0, 0, 0, 0, 3, 4, 1, 0, 0,
+  46, 0, 47, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 79, 42, 0, 0, 0, 53, 0,
+  5, 0, 0, 37, 2, 1, 18, 62, 41, 51,
+  0, 55, 86, 0, 87, 50, 0, 11, 5, 15,
+  128, 37, 1, 0, 72, 0, 36, 0, 0, 27,
+  0, 45, 39, 32, 0, 35, 80, 55, 0, 7,
+  0, 21, 12, 25, 62, 0, 16, 0, 27, 0,
+  29, 0, 13, 0, 11, 0, 0, 0, 25, 0,
+  9, 0, 3, 35, 41, 39, 37, 34, 23, 0,
+  0, 8, 79, 22, 1, 0, 0, 13, 0, 0,
+  82, 36, 0, 0, 20, 0, 0, 51, 0, 0,
+  48, 11, 5, 0, 0, 23, 29, 0, 77, 0,
+  0, 50, 18, 0, 0, 42, 0, 0, 0, 4,
+  5, 13, 24, 0, 0, 0, 28, 0, 34, 0,
+  7, 54, 57, 12, 0, 23, 17, 14, 2, 0,
+  0, 54, 68, 12, 2, 19, 58, 30, 0, 13,
+  72, 61, 94, 10, 0, 0, 0, 26, 0, 0,
+  0, 5, 68, 0, 20, 19, 0, 31, 0, 50,
+  4, 41, 0, 19, 53, 58, 0, 66, 0, 27,
+  0, 55, 24, 0, 51, 0, 26, 0, 10, 0,
+  0, 0, 0, 18, 3, 0, 0, 0, 34, 0,
+  14, 26, 9, 11, 35, 0, 48, 32, 0, 34,
+  37, 0, 35, 0, 0, 7, 0, 0, 0, 5,
+  0, 0, 0, 0, 0, 28, 25, 0, 59, 36,
+  0, 0, 14, 23, 43, 0, 49, 0, 0, 6,
+  11, 5, 0, 11, 0, 0, 8, 0, 8, 0,
+  0, 4, 5, 0, 45, 0, 20, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 59, 38, 0,
+  0, 0, 51, 10, 0, 0, 0, 39, 16, 14,
+  0, 31, 37, 50, 8, 52, 96, 0, 89, 33,
+  0, 0, 10, 17, 130, 11, 0, 0, 60, 0,
+  23, 5, 0, 27, 0, 39, 18, 30, 0, 52,
+  72, 74, 0, 1, 0, 9, 3, 38, 49, 0,
+  21, 0, 26, 0, 35, 0, 7, 0, 20, 0,
+  0, 0, 28, 0, 11, 0, 19, 32, 48, 45,
+  30, 15, 29, 8, 0, 9, 64, 8, 4, 0,
+  0, 0, 0, 0, 71, 23, 0, 0, 12, 0,
+  0, 61, 0, 0, 46, 11, 0, 0, 7, 26,
+  31, 0, 76, 0, 0, 36, 15, 0, 0, 53,
+  0, 0, 0, 21, 21, 27, 13, 0, 0, 0,
+  35, 0, 35, 0, 5, 41, 42, 14, 0, 10,
+  22, 17, 7, 0, 0, 59, 79, 18, 12, 8,
+  57, 30, 0, 8, 80, 64, 78, 4, 4, 0,
+  0, 27, 0, 0, 0, 6, 69, 0, 21, 17,
+  0, 41, 0, 56, 0, 45, 0, 25, 49, 58,
+  0, 46, 0, 36, 0, 53, 24, 7, 45, 0,
+  22, 0, 8, 0, 0, 0, 0, 27, 0, 6,
+  0, 0, 31, 0, 5, 23, 14, 9, 30, 0,
+  48, 35, 0, 35, 39, 0, 24, 0, 2, 0,
+  0, 0, 0, 6, 0, 0, 0, 3, 0, 41,
+  26, 0, 61, 31, 0, 0, 30, 12, 49, 0,
+  50, 0, 0, 4, 7, 3, 0, 14, 0, 0,
+  14, 0, 21, 1, 1, 11, 20, 0, 59, 0,
+  36, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 63, 25, 0, 12, 14, 50, 13, 5, 0,
+  0, 23, 35, 0, 0, 30, 38, 31, 5, 54,
+  55, 9, 80, 28, 0, 3, 10, 13, 116, 5,
+  0, 0, 52, 0, 36, 23, 0, 31, 3, 61,
+  0, 33, 0, 63, 55, 73, 9, 21, 0, 8,
+  0, 36, 57, 0, 2, 0, 23, 0, 17, 0,
+  5, 0, 0, 0, 6, 0, 4, 2, 29, 0,
+  67, 27, 41, 25, 49, 11, 15, 14, 0, 5,
+  68, 0, 19, 0, 11, 0, 0, 0, 45, 8,
+  0, 0, 0, 0, 0, 59, 0, 0, 45, 19,
+  0, 0, 13, 20, 31, 0, 79, 0, 0, 21,
+  1, 0, 0, 69, 0, 0, 0, 20, 30, 19,
+  9, 0, 0, 0, 44, 0, 32, 0, 1, 40,
+  20, 13, 0, 4, 30, 19, 7, 0, 0, 51,
+  83, 2, 5, 14, 52, 26, 0, 4, 59, 63,
+  73, 10, 9, 0, 0, 21, 0, 0, 0, 8,
+  79, 0, 30, 22, 0, 58, 0, 53, 0, 36,
+  0, 25, 34, 72, 4, 34, 0, 41, 0, 48,
+  26, 0, 42, 0, 22, 0, 6, 0, 0, 0,
+  0, 29, 9, 0, 0, 4, 44, 0, 36, 14,
+  25, 13, 34, 0, 45, 43, 0, 22, 40, 0,
+  24, 0, 0, 0, 0, 0, 0, 2, 0, 0,
+  0, 6, 0, 37, 22, 0, 63, 32, 0, 0,
+  27, 13, 56, 0, 49, 0, 0, 3, 0, 25,
+  0, 17, 0, 0, 5, 0, 25, 4, 6, 5,
+  11, 0, 60, 0, 35, 0, 0, 79, 42, 0,
+  0, 0, 53, 0, 5, 0, 0, 37, 2, 1,
+  18, 62, 41, 51, 0, 55, 86, 0, 87, 50,
+  0, 11, 5, 15, 128, 37, 1, 0, 72, 0,
+  36, 0, 0, 27, 0, 45, 39, 32, 0, 35,
+  80, 55, 0, 7, 0, 21, 12, 25, 62, 0,
+  16, 0, 27, 0, 29, 0, 13, 0, 11, 0,
+  0, 0, 25, 0, 9, 0, 3, 35, 41, 39,
+  37, 34, 23, 0, 0, 8, 79, 22, 1, 0,
+  0, 13, 0, 0, 82, 36, 0, 0, 20, 0,
+  0, 51, 0, 0, 48, 11, 5, 0, 0, 23,
+  29, 0, 77, 0, 0, 50, 18, 0, 0, 42,
+  0, 0, 0, 4, 5, 13, 24, 0, 0, 0,
+  28, 0, 34, 0, 7, 54, 57, 12, 0, 23,
+  17, 14, 2, 0, 0, 54, 68, 12, 2, 19,
+  58, 30, 0, 13, 72, 61, 94, 10, 0, 0,
+  0, 26, 0, 0, 0, 5, 68, 0, 20, 19,
+  0, 31, 0, 50, 4, 41, 0, 19, 53, 58,
+  0, 66, 0, 27, 0, 55, 24, 0, 51, 0,
+  26, 0, 10, 0, 0, 0, 0, 18, 3, 0,
+  0, 0, 34, 0, 14, 26, 9, 11, 35, 0,
+  48, 32, 0, 34, 37, 0, 35, 0, 0, 7,
+  0, 0, 0, 5, 0, 0, 0, 0, 0, 28,
+  25, 0, 59, 36, 0, 0, 14, 23, 43, 0,
+  49, 0, 0, 6, 11, 5, 0, 11, 0, 0,
+  8, 0, 8, 0, 0, 4, 5, 0, 45, 0,
+  20, 0, 10, 27, 29, 24, 0, 21, 22, 22,
+  24, 0, 0, 43, 79, 0, 6, 26, 56, 0,
+  0, 0, 0, 87, 1, 0, 41, 0, 0, 30,
+  0, 1, 0, 60, 72, 0, 24, 0, 0, 23,
+  0, 54, 0, 47, 13, 10, 23, 49, 26, 18,
+  0, 30, 0, 52, 4, 24, 54, 0, 32, 0,
+  10, 0, 1, 11, 0, 48, 0, 8, 0, 0,
+  39, 0, 18, 26, 11, 0, 0, 2, 47, 27,
+  0, 46, 24, 0, 46, 46, 0, 0, 13, 0,
+  0, 18, 0, 0, 0, 23, 0, 24, 55, 0,
+  15, 78, 0, 0, 25, 19, 40, 0, 26, 0,
+  5, 0, 17, 8, 0, 0, 0, 0, 7, 0,
+  0, 4, 0, 11, 36, 0, 55, 0, 17, 0,
+  0, 59, 38, 0, 0, 0, 51, 10, 0, 0,
+  0, 39, 16, 14, 0, 31, 37, 50, 8, 52,
+  96, 0, 89, 33, 0, 0, 10, 17, 130, 11,
+  0, 0, 60, 0, 23, 5, 0, 27, 0, 39,
+  18, 30, 0, 52, 72, 74, 0, 1, 0, 9,
+  3, 38, 49, 0, 21, 0, 26, 0, 35, 0,
+  7, 0, 20, 0, 0, 0, 28, 0, 11, 0,
+  19, 32, 48, 45, 30, 15, 29, 8, 0, 9,
+  64, 8, 4, 0, 0, 0, 0, 0, 71, 23,
+  0, 0, 12, 0, 0, 61, 0, 0, 46, 11,
+  0, 0, 7, 26, 31, 0, 76, 0, 0, 36,
+  15, 0, 0, 53, 0, 0, 0, 21, 21, 27,
+  13, 0, 0, 0, 35, 0, 35, 0, 5, 41,
+  42, 14, 0, 10, 22, 17, 7, 0, 0, 59,
+  79, 18, 12, 8, 57, 30, 0, 8, 80, 64,
+  78, 4, 4, 0, 0, 27, 0, 0, 0, 6,
+  69, 0, 21, 17, 0, 41, 0, 56, 0, 45,
+  0, 25, 49, 58, 0, 46, 0, 36, 0, 53,
+  24, 7, 45, 0, 22, 0, 8, 0, 0, 0,
+  0, 27, 0, 6, 0, 0, 31, 0, 5, 23,
+  14, 9, 30, 0, 48, 35, 0, 35, 39, 0,
+  24, 0, 2, 0, 0, 0, 0, 6, 0, 0,
+  0, 3, 0, 41, 26, 0, 61, 31, 0, 0,
+  30, 12, 49, 0, 50, 0, 0, 4, 7, 3,
+  0, 14, 0, 0, 14, 0, 21, 1, 1, 11,
+  20, 0, 59, 0, 36, 0, 7, 20, 30, 33,
+  0, 25, 20, 19, 31, 0, 0, 42, 85, 0,
+  9, 30, 51, 0, 0, 0, 0, 86, 1, 3,
+  48, 0, 0, 38, 0, 0, 0, 59, 74, 0,
+  25, 0, 0, 26, 0, 62, 0, 45, 16, 10,
+  25, 48, 31, 10, 0, 42, 0, 48, 3, 27,
+  52, 0, 29, 0, 9, 0, 0, 10, 0, 42,
+  0, 8, 0, 0, 37, 0, 14, 27, 13, 0,
+  0, 2, 45, 38, 0, 45, 25, 0, 49, 45,
+  0, 0, 20, 0, 0, 19, 0, 0, 0, 17,
+  0, 27, 57, 0, 16, 73, 0, 0, 26, 12,
+  40, 0, 28, 0, 0, 0, 14, 3, 0, 0,
+  0, 0, 11, 0, 0, 9, 2, 6, 37, 0,
+  65, 0, 15, 0, 0, 63, 25, 0, 12, 14,
+  50, 13, 5, 0, 0, 23, 35, 0, 0, 30,
+  38, 31, 5, 54, 55, 9, 80, 28, 0, 3,
+  10, 13, 116, 5, 0, 0, 52, 0, 36, 23,
+  0, 31, 3, 61, 0, 33, 0, 63, 55, 73,
+  9, 21, 0, 8, 0, 36, 57, 0, 2, 0,
+  23, 0, 17, 0, 5, 0, 0, 0, 6, 0,
+  4, 2, 29, 0, 67, 27, 41, 25, 49, 11,
+  15, 14, 0, 5, 68, 0, 19, 0, 11, 0,
+  0, 0, 45, 8, 0, 0, 0, 0, 0, 59,
+  0, 0, 45, 19, 0, 0, 13, 20, 31, 0,
+  79, 0, 0, 21, 1, 0, 0, 69, 0, 0,
+  0, 20, 30, 19, 9, 0, 0, 0, 44, 0,
+  32, 0, 1, 40, 20, 13, 0, 4, 30, 19,
+  7, 0, 0, 51, 83, 2, 5, 14, 52, 26,
+  0, 4, 59, 63, 73, 10, 9, 0, 0, 21,
+  0, 0, 0, 8, 79, 0, 30, 22, 0, 58,
+  0, 53, 0, 36, 0, 25, 34, 72, 4, 34,
+  0, 41, 0, 48, 26, 0, 42, 0, 22, 0,
+  6, 0, 0, 0, 0, 29, 9, 0, 0, 4,
+  44, 0, 36, 14, 25, 13, 34, 0, 45, 43,
+  0, 22, 40, 0, 24, 0, 0, 0, 0, 0,
+  0, 2, 0, 0, 0, 6, 0, 37, 22, 0,
+  63, 32, 0, 0, 27, 13, 56, 0, 49, 0,
+  0, 3, 0, 25, 0, 17, 0, 0, 5, 0,
+  25, 4, 6, 5, 11, 0, 60, 0, 35, 0,
+  2, 21, 34, 36, 0, 20, 23, 15, 27, 0,
+  0, 35, 85, 0, 12, 34, 49, 0, 0, 0,
+  0, 85, 1, 4, 48, 0, 0, 34, 0, 0,
+  0, 54, 82, 0, 29, 0, 0, 33, 0, 60,
+  0, 43, 14, 7, 23, 47, 31, 6, 0, 53,
+  0, 47, 6, 21, 54, 0, 28, 0, 6, 0,
+  3, 7, 0, 44, 0, 7, 0, 0, 39, 0,
+  13, 26, 14, 0, 0, 6, 45, 37, 0, 39,
+  28, 0, 49, 43, 0, 0, 21, 0, 0, 21,
+  1, 0, 0, 13, 0, 26, 58, 0, 13, 70,
+  1, 0, 22, 11, 31, 0, 26, 0, 0, 0,
+  14, 14, 0, 0, 0, 0, 7, 0, 0, 13,
+  6, 6, 31, 0, 67, 0, 13, 0, 7, 54,
+  57, 12, 0, 23, 17, 14, 2, 0, 0, 54,
+  68, 12, 2, 19, 58, 30, 0, 13, 72, 61,
+  94, 10, 0, 0, 0, 26, 0, 0, 0, 5,
+  68, 0, 20, 19, 0, 31, 0, 50, 4, 41,
+  0, 19, 53, 58, 0, 66, 0, 27, 0, 55,
+  24, 0, 51, 0, 26, 0, 10, 0, 0, 0,
+  0, 18, 3, 0, 0, 0, 34, 0, 14, 26,
+  9, 11, 35, 0, 48, 32, 0, 34, 37, 0,
+  35, 0, 0, 7, 0, 0, 0, 5, 0, 0,
+  0, 0, 0, 28, 25, 0, 59, 36, 0, 0,
+  14, 23, 43, 0, 49, 0, 0, 6, 11, 5,
+  0, 11, 0, 0, 8, 0, 8, 0, 0, 4,
+  5, 0, 45, 0, 20, 0, 10, 27, 29, 24,
+  0, 21, 22, 22, 24, 0, 0, 43, 79, 0,
+  6, 26, 56, 0, 0, 0, 0, 87, 1, 0,
+  41, 0, 0, 30, 0, 1, 0, 60, 72, 0,
+  24, 0, 0, 23, 0, 54, 0, 47, 13, 10,
+  23, 49, 26, 18, 0, 30, 0, 52, 4, 24,
+  54, 0, 32, 0, 10, 0, 1, 11, 0, 48,
+  0, 8, 0, 0, 39, 0, 18, 26, 11, 0,
+  0, 2, 47, 27, 0, 46, 24, 0, 46, 46,
+  0, 0, 13, 0, 0, 18, 0, 0, 0, 23,
+  0, 24, 55, 0, 15, 78, 0, 0, 25, 19,
+  40, 0, 26, 0, 5, 0, 17, 8, 0, 0,
+  0, 0, 7, 0, 0, 4, 0, 11, 36, 0,
+  55, 0, 17, 0, 0, 0, 0, 7, 0, 153,
+  0, 0, 0, 0, 0, 29, 38, 0, 0, 1,
+  3, 0, 0, 0, 24, 93, 13, 16, 0, 0,
+  0, 0, 0, 19, 0, 24, 31, 29, 0, 8,
+  0, 29, 0, 45, 0, 25, 0, 49, 3, 74,
+  23, 63, 0, 7, 0, 55, 0, 0, 19, 0,
+  43, 0, 36, 0, 0, 49, 0, 0, 76, 0,
+  0, 27, 37, 0, 74, 15, 23, 0, 0, 20,
+  11, 20, 0, 34, 35, 0, 40, 53, 0, 0,
+  16, 0, 0, 0, 0, 13, 0, 0, 26, 27,
+  0, 0, 0, 73, 26, 0, 0, 26, 12, 0,
+  22, 0, 0, 0, 6, 0, 0, 16, 0, 0,
+  114, 0, 19, 9, 0, 0, 0, 0, 29, 0,
+  0, 0, 5, 41, 42, 14, 0, 10, 22, 17,
+  7, 0, 0, 59, 79, 18, 12, 8, 57, 30,
+  0, 8, 80, 64, 78, 4, 4, 0, 0, 27,
+  0, 0, 0, 6, 69, 0, 21, 17, 0, 41,
+  0, 56, 0, 45, 0, 25, 49, 58, 0, 46,
+  0, 36, 0, 53, 24, 7, 45, 0, 22, 0,
+  8, 0, 0, 0, 0, 27, 0, 6, 0, 0,
+  31, 0, 5, 23, 14, 9, 30, 0, 48, 35,
+  0, 35, 39, 0, 24, 0, 2, 0, 0, 0,
+  0, 6, 0, 0, 0, 3, 0, 41, 26, 0,
+  61, 31, 0, 0, 30, 12, 49, 0, 50, 0,
+  0, 4, 7, 3, 0, 14, 0, 0, 14, 0,
+  21, 1, 1, 11, 20, 0, 59, 0, 36, 0,
+  7, 20, 30, 33, 0, 25, 20, 19, 31, 0,
+  0, 42, 85, 0, 9, 30, 51, 0, 0, 0,
+  0, 86, 1, 3, 48, 0, 0, 38, 0, 0,
+  0, 59, 74, 0, 25, 0, 0, 26, 0, 62,
+  0, 45, 16, 10, 25, 48, 31, 10, 0, 42,
+  0, 48, 3, 27, 52, 0, 29, 0, 9, 0,
+  0, 10, 0, 42, 0, 8, 0, 0, 37, 0,
+  14, 27, 13, 0, 0, 2, 45, 38, 0, 45,
+  25, 0, 49, 45, 0, 0, 20, 0, 0, 19,
+  0, 0, 0, 17, 0, 27, 57, 0, 16, 73,
+  0, 0, 26, 12, 40, 0, 28, 0, 0, 0,
+  14, 3, 0, 0, 0, 0, 11, 0, 0, 9,
+  2, 6, 37, 0, 65, 0, 15, 0, 0, 0,
+  0, 14, 0, 156, 0, 0, 5, 0, 0, 33,
+  46, 0, 0, 1, 2, 0, 0, 0, 35, 87,
+  15, 22, 9, 0, 0, 0, 0, 4, 0, 26,
+  27, 34, 0, 10, 0, 25, 0, 45, 0, 20,
+  0, 52, 5, 80, 36, 57, 0, 13, 0, 53,
+  0, 0, 18, 0, 38, 0, 42, 0, 0, 46,
+  0, 0, 78, 0, 0, 21, 42, 0, 77, 17,
+  26, 0, 0, 15, 17, 17, 0, 33, 33, 0,
+  40, 55, 0, 0, 30, 0, 0, 0, 0, 21,
+  0, 0, 19, 31, 0, 0, 3, 65, 28, 0,
+  0, 21, 9, 0, 22, 0, 0, 0, 0, 0,
+  0, 12, 0, 0, 106, 0, 25, 11, 0, 0,
+  0, 0, 36, 0, 0, 0, 1, 40, 20, 13,
+  0, 4, 30, 19, 7, 0, 0, 51, 83, 2,
+  5, 14, 52, 26, 0, 4, 59, 63, 73, 10,
+  9, 0, 0, 21, 0, 0, 0, 8, 79, 0,
+  30, 22, 0, 58, 0, 53, 0, 36, 0, 25,
+  34, 72, 4, 34, 0, 41, 0, 48, 26, 0,
+  42, 0, 22, 0, 6, 0, 0, 0, 0, 29,
+  9, 0, 0, 4, 44, 0, 36, 14, 25, 13,
+  34, 0, 45, 43, 0, 22, 40, 0, 24, 0,
+  0, 0, 0, 0, 0, 2, 0, 0, 0, 6,
+  0, 37, 22, 0, 63, 32, 0, 0, 27, 13,
+  56, 0, 49, 0, 0, 3, 0, 25, 0, 17,
+  0, 0, 5, 0, 25, 4, 6, 5, 11, 0,
+  60, 0, 35, 0, 2, 21, 34, 36, 0, 20,
+  23, 15, 27, 0, 0, 35, 85, 0, 12, 34,
+  49, 0, 0, 0, 0, 85, 1, 4, 48, 0,
+  0, 34, 0, 0, 0, 54, 82, 0, 29, 0,
+  0, 33, 0, 60, 0, 43, 14, 7, 23, 47,
+  31, 6, 0, 53, 0, 47, 6, 21, 54, 0,
+  28, 0, 6, 0, 3, 7, 0, 44, 0, 7,
+  0, 0, 39, 0, 13, 26, 14, 0, 0, 6,
+  45, 37, 0, 39, 28, 0, 49, 43, 0, 0,
+  21, 0, 0, 21, 1, 0, 0, 13, 0, 26,
+  58, 0, 13, 70, 1, 0, 22, 11, 31, 0,
+  26, 0, 0, 0, 14, 14, 0, 0, 0, 0,
+  7, 0, 0, 13, 6, 6, 31, 0, 67, 0,
+  13, 0, 0, 0, 0, 11, 0, 155, 2, 0,
+  5, 0, 0, 33, 42, 0, 0, 4, 0, 0,
+  0, 0, 32, 92, 22, 17, 9, 0, 0, 0,
+  0, 2, 0, 29, 24, 28, 0, 10, 0, 29,
+  0, 42, 0, 20, 0, 60, 3, 77, 36, 51,
+  0, 12, 0, 54, 0, 0, 17, 0, 44, 0,
+  43, 0, 0, 51, 0, 0, 85, 0, 0, 21,
+  43, 0, 79, 15, 29, 0, 0, 19, 21, 15,
+  0, 25, 34, 0, 39, 58, 0, 0, 33, 0,
+  0, 0, 0, 21, 2, 0, 11, 36, 0, 0,
+  0, 60, 36, 0, 0, 18, 9, 0, 23, 0,
+  0, 0, 0, 0, 0, 9, 0, 0, 107, 0,
+  27, 18, 0, 1, 0, 0, 40, 0, 0, 0,
+  10, 27, 29, 24, 0, 21, 22, 22, 24, 0,
+  0, 43, 79, 0, 6, 26, 56, 0, 0, 0,
+  0, 87, 1, 0, 41, 0, 0, 30, 0, 1,
+  0, 60, 72, 0, 24, 0, 0, 23, 0, 54,
+  0, 47, 13, 10, 23, 49, 26, 18, 0, 30,
+  0, 52, 4, 24, 54, 0, 32, 0, 10, 0,
+  1, 11, 0, 48, 0, 8, 0, 0, 39, 0,
+  18, 26, 11, 0, 0, 2, 47, 27, 0, 46,
+  24, 0, 46, 46, 0, 0, 13, 0, 0, 18,
+  0, 0, 0, 23, 0, 24, 55, 0, 15, 78,
+  0, 0, 25, 19, 40, 0, 26, 0, 5, 0,
+  17, 8, 0, 0, 0, 0, 7, 0, 0, 4,
+  0, 11, 36, 0, 55, 0, 17, 0, 0, 0,
+  0, 7, 0, 153, 0, 0, 0, 0, 0, 29,
+  38, 0, 0, 1, 3, 0, 0, 0, 24, 93,
+  13, 16, 0, 0, 0, 0, 0, 19, 0, 24,
+  31, 29, 0, 8, 0, 29, 0, 45, 0, 25,
+  0, 49, 3, 74, 23, 63, 0, 7, 0, 55,
+  0, 0, 19, 0, 43, 0, 36, 0, 0, 49,
+  0, 0, 76, 0, 0, 27, 37, 0, 74, 15,
+  23, 0, 0, 20, 11, 20, 0, 34, 35, 0,
+  40, 53, 0, 0, 16, 0, 0, 0, 0, 13,
+  0, 0, 26, 27, 0, 0, 0, 73, 26, 0,
+  0, 26, 12, 0, 22, 0, 0, 0, 6, 0,
+  0, 16, 0, 0, 114, 0, 19, 9, 0, 0,
+  0, 0, 29, 0, 0, 0, 0, 17, 0, 0,
+  0, 31, 35, 0, 13, 0, 8, 0, 56, 4,
+  16, 62, 36, 39, 10, 0, 30, 0, 0, 48,
+  4, 53, 0, 4, 0, 15, 0, 0, 72, 44,
+  0, 0, 0, 0, 0, 66, 0, 41, 0, 43,
+  20, 12, 12, 36, 0, 41, 0, 7, 95, 16,
+  0, 0, 21, 0, 0, 55, 9, 0, 0, 0,
+  0, 0, 32, 12, 11, 0, 0, 0, 0, 15,
+  10, 55, 0, 0, 0, 47, 64, 4, 32, 22,
+  15, 0, 7, 27, 13, 34, 54, 16, 0, 11,
+  39, 32, 0, 0, 0, 68, 22, 0, 0, 0,
+  0, 0, 48, 0, 0, 30, 26, 15, 0, 27,
+  0, 0, 25, 30, 24, 3, 1, 0, 121, 0,
+  65, 2, 0, 0, 7, 20, 30, 33, 0, 25,
+  20, 19, 31, 0, 0, 42, 85, 0, 9, 30,
+  51, 0, 0, 0, 0, 86, 1, 3, 48, 0,
+  0, 38, 0, 0, 0, 59, 74, 0, 25, 0,
+  0, 26, 0, 62, 0, 45, 16, 10, 25, 48,
+  31, 10, 0, 42, 0, 48, 3, 27, 52, 0,
+  29, 0, 9, 0, 0, 10, 0, 42, 0, 8,
+  0, 0, 37, 0, 14, 27, 13, 0, 0, 2,
+  45, 38, 0, 45, 25, 0, 49, 45, 0, 0,
+  20, 0, 0, 19, 0, 0, 0, 17, 0, 27,
+  57, 0, 16, 73, 0, 0, 26, 12, 40, 0,
+  28, 0, 0, 0, 14, 3, 0, 0, 0, 0,
+  11, 0, 0, 9, 2, 6, 37, 0, 65, 0,
+  15, 0, 0, 0, 0, 14, 0, 156, 0, 0,
+  5, 0, 0, 33, 46, 0, 0, 1, 2, 0,
+  0, 0, 35, 87, 15, 22, 9, 0, 0, 0,
+  0, 4, 0, 26, 27, 34, 0, 10, 0, 25,
+  0, 45, 0, 20, 0, 52, 5, 80, 36, 57,
+  0, 13, 0, 53, 0, 0, 18, 0, 38, 0,
+  42, 0, 0, 46, 0, 0, 78, 0, 0, 21,
+  42, 0, 77, 17, 26, 0, 0, 15, 17, 17,
+  0, 33, 33, 0, 40, 55, 0, 0, 30, 0,
+  0, 0, 0, 21, 0, 0, 19, 31, 0, 0,
+  3, 65, 28, 0, 0, 21, 9, 0, 22, 0,
+  0, 0, 0, 0, 0, 12, 0, 0, 106, 0,
+  25, 11, 0, 0, 0, 0, 36, 0, 0, 0,
+  0, 20, 0, 0, 0, 35, 28, 0, 25, 0,
+  6, 0, 68, 1, 9, 53, 37, 38, 8, 0,
+  43, 0, 0, 43, 7, 56, 0, 4, 0, 13,
+  10, 0, 65, 53, 0, 0, 0, 0, 0, 56,
+  0, 63, 0, 42, 23, 10, 1, 49, 0, 48,
+  0, 7, 80, 24, 0, 0, 14, 0, 0, 62,
+  18, 0, 0, 0, 0, 0, 30, 19, 15, 0,
+  0, 0, 0, 17, 1, 53, 0, 0, 0, 49,
+  63, 0, 24, 24, 20, 0, 11, 25, 0, 37,
+  36, 32, 0, 13, 32, 35, 0, 0, 0, 66,
+  17, 0, 0, 0, 0, 0, 37, 0, 0, 36,
+  37, 19, 0, 29, 0, 0, 14, 20, 42, 8,
+  3, 0, 121, 0, 63, 0, 10, 0, 2, 21,
+  34, 36, 0, 20, 23, 15, 27, 0, 0, 35,
+  85, 0, 12, 34, 49, 0, 0, 0, 0, 85,
+  1, 4, 48, 0, 0, 34, 0, 0, 0, 54,
+  82, 0, 29, 0, 0, 33, 0, 60, 0, 43,
+  14, 7, 23, 47, 31, 6, 0, 53, 0, 47,
+  6, 21, 54, 0, 28, 0, 6, 0, 3, 7,
+  0, 44, 0, 7, 0, 0, 39, 0, 13, 26,
+  14, 0, 0, 6, 45, 37, 0, 39, 28, 0,
+  49, 43, 0, 0, 21, 0, 0, 21, 1, 0,
+  0, 13, 0, 26, 58, 0, 13, 70, 1, 0,
+  22, 11, 31, 0, 26, 0, 0, 0, 14, 14,
+  0, 0, 0, 0, 7, 0, 0, 13, 6, 6,
+  31, 0, 67, 0, 13, 0, 0, 0, 0, 11,
+  0, 155, 2, 0, 5, 0, 0, 33, 42, 0,
+  0, 4, 0, 0, 0, 0, 32, 92, 22, 17,
+  9, 0, 0, 0, 0, 2, 0, 29, 24, 28,
+  0, 10, 0, 29, 0, 42, 0, 20, 0, 60,
+  3, 77, 36, 51, 0, 12, 0, 54, 0, 0,
+  17, 0, 44, 0, 43, 0, 0, 51, 0, 0,
+  85, 0, 0, 21, 43, 0, 79, 15, 29, 0,
+  0, 19, 21, 15, 0, 25, 34, 0, 39, 58,
+  0, 0, 33, 0, 0, 0, 0, 21, 2, 0,
+  11, 36, 0, 0, 0, 60, 36, 0, 0, 18,
+  9, 0, 23, 0, 0, 0, 0, 0, 0, 9,
+  0, 0, 107, 0, 27, 18, 0, 1, 0, 0,
+  40, 0, 0, 0, 0, 14, 0, 0, 0, 35,
+  30, 0, 24, 0, 0, 0, 74, 10, 3, 49,
+  34, 40, 11, 0, 46, 0, 0, 43, 6, 57,
+  0, 0, 0, 6, 17, 0, 60, 46, 0, 0,
+  0, 6, 0, 50, 0, 54, 0, 49, 22, 10,
+  0, 35, 0, 41, 0, 4, 78, 9, 0, 0,
+  19, 0, 0, 64, 27, 0, 0, 0, 0, 0,
+  28, 16, 10, 0, 0, 1, 0, 26, 0, 65,
+  0, 0, 0, 35, 53, 4, 18, 31, 20, 0,
+  14, 26, 7, 35, 30, 32, 0, 14, 17, 31,
+  0, 0, 0, 53, 24, 0, 0, 0, 0, 0,
+  40, 0, 0, 48, 34, 9, 0, 29, 0, 0,
+  32, 21, 47, 17, 0, 5, 113, 0, 63, 0,
+  10, 0,
+};
+
+unsigned char b_data[b_count] = {
+  82, 81, 82, 72, 70, 90, 88, 77, 85, 68,
+  76, 88, 77, 90, 86, 94, 88, 88, 78, 74,
+  89, 80, 75, 81, 70, 89, 81, 77, 93, 95,
+  70, 81, 109, 71, 77, 80, 80, 94, 95, 95,
+  87, 87, 77, 73, 97, 75, 91, 92, 80, 90,
+  92, 79, 162, 95, 75, 87, 99, 86, 82, 72,
+  70, 84, 85, 80, 86, 75, 79, 68, 90, 94,
+  84, 79, 81, 75, 84, 94, 91, 88, 90, 87,
+  101, 72, 84, 76, 62, 82, 80, 81, 81, 65,
+  90, 85, 83, 72, 80, 81, 85, 88, 79, 101,
+  85, 86, 81, 70, 84, 89, 79, 72, 90, 62,
+  97, 90, 70, 79, 80, 83, 78, 86, 78, 88,
+  73, 85, 71, 68, 87, 66, 65, 83, 83, 77,
+  80, 77, 68, 81, 87, 81, 88, 68, 71, 89,
+  88, 85, 88, 94, 87, 93, 75, 76, 87, 80,
+  79, 80, 73, 96, 83, 74, 87, 88, 73, 80,
+  107, 71, 80, 84, 78, 93, 93, 93, 88, 86,
+  88, 71, 96, 78, 94, 85, 78, 91, 86, 77,
+  167, 91, 77, 86, 99, 83, 85, 76, 67, 88,
+  85, 81, 83, 76, 81, 76, 89, 92, 83, 74,
+  83, 75, 86, 89, 87, 90, 92, 87, 93, 64,
+  84, 79, 66, 81, 80, 80, 82, 65, 85, 84,
+  76, 75, 81, 82, 82, 88, 83, 97, 79, 87,
+  95, 71, 90, 86, 83, 76, 89, 57, 94, 89,
+  75, 82, 84, 84, 83, 86, 85, 92, 73, 83,
+  72, 70, 89, 66, 65, 83, 83, 68, 79, 74,
+  71, 80, 90, 76, 83, 67, 75, 86, 81, 88,
+  92, 93, 86, 91, 76, 74, 81, 81, 88, 78,
+  74, 91, 82, 75, 92, 83, 74, 77, 107, 73,
+  79, 76, 76, 91, 92, 87, 88, 86, 90, 71,
+  93, 74, 86, 88, 82, 89, 90, 75, 157, 90,
+  75, 87, 94, 89, 82, 74, 70, 83, 85, 79,
+  88, 76, 79, 71, 87, 91, 87, 79, 79, 78,
+  83, 96, 90, 93, 92, 86, 101, 69, 80, 75,
+  60, 79, 83, 84, 80, 64, 85, 87, 85, 74,
+  81, 84, 84, 90, 78, 96, 86, 85, 82, 70,
+  90, 85, 80, 73, 87, 63, 90, 90, 67, 78,
+  85, 79, 87, 86, 75, 86, 72, 84, 73, 70,
+  86, 68, 67, 82, 84, 86, 80, 69, 69, 90,
+  80, 72, 88, 70, 77, 85, 82, 83, 84, 93,
+  91, 84, 77, 77, 84, 79, 78, 86, 74, 84,
+  79, 77, 86, 92, 78, 79, 105, 73, 82, 80,
+  83, 86, 91, 92, 86, 87, 80, 76, 96, 78,
+  97, 93, 78, 93, 96, 81, 169, 88, 72, 91,
+  100, 88, 79, 74, 74, 87, 81, 80, 84, 74,
+  77, 72, 83, 94, 86, 78, 84, 72, 86, 94,
+  86, 88, 82, 86, 97, 73, 82, 79, 64, 77,
+  78, 83, 79, 73, 94, 85, 82, 68, 78, 75,
+  80, 90, 85, 93, 83, 89, 94, 68, 87, 80,
+  80, 76, 93, 70, 87, 91, 75, 85, 85, 82,
+  85, 82, 84, 92, 77, 86, 70, 71, 83, 79,
+  69, 80, 83, 83, 84, 73, 64, 82, 81, 73,
+  94, 73, 75, 85, 91, 81, 88, 99, 90, 94,
+  72, 81, 88, 80, 82, 87, 77, 89, 82, 76,
+  80, 85, 82, 77, 103, 72, 82, 85, 86, 90,
+  85, 89, 90, 85, 85, 76, 94, 77, 100, 85,
+  75, 97, 92, 77, 183, 83, 76, 89, 101, 85,
+  81, 79, 70, 89, 81, 80, 79, 70, 79, 78,
+  79, 92, 83, 73, 84, 67, 86, 91, 83, 92,
+  78, 84, 90, 65, 82, 77, 68, 76, 78, 81,
+  79, 79, 95, 83, 73, 67, 81, 74, 74, 89,
+  89, 91, 74, 88, 110, 70, 90, 81, 85, 81,
+  92, 66, 82, 88, 78, 85, 88, 84, 86, 83,
+  95, 96, 77, 83, 76, 74, 86, 79, 69, 77,
+  84, 76, 85, 73, 71, 78, 84, 71, 87, 71,
+  76, 82, 81, 87, 94, 90, 89, 87, 75, 78,
+  83, 81, 89, 86, 77, 85, 83, 75, 86, 87,
+  85, 74, 102, 74, 84, 80, 82, 85, 87, 86,
+  89, 87, 81, 72, 91, 71, 92, 87, 82, 92,
+  94, 77, 162, 86, 73, 88, 93, 92, 79, 77,
+  74, 83, 81, 81, 83, 75, 83, 73, 82, 93,
+  85, 76, 81, 79, 85, 95, 88, 95, 80, 87,
+  97, 72, 79, 79, 65, 78, 85, 86, 80, 73,
+  90, 86, 84, 71, 79, 79, 80, 92, 82, 89,
+  89, 85, 93, 69, 89, 79, 83, 76, 90, 69,
+  82, 91, 72, 79, 88, 82, 87, 81, 83, 92,
+  76, 87, 73, 73, 84, 81, 72, 81, 83, 91,
+  85, 74, 76, 89, 85, 67, 84, 71, 85, 82,
+  78, 89, 91, 88, 96, 75, 81, 74, 69, 76,
+  85, 84, 74, 80, 75, 76, 91, 86, 73, 82,
+  102, 73, 81, 78, 86, 87, 92, 97, 84, 91,
+  81, 80, 96, 78, 93, 92, 81, 88, 94, 80,
+  163, 88, 68, 87, 101, 90, 76, 68, 83, 90,
+  81, 83, 83, 73, 85, 72, 81, 97, 92, 84,
+  85, 79, 84, 96, 89, 89, 84, 89, 97, 81,
+  80, 76, 63, 80, 81, 88, 81, 78, 84, 96,
+  85, 66, 75, 83, 84, 93, 84, 96, 92, 89,
+  81, 71, 82, 82, 77, 74, 91, 70, 84, 91,
+  68, 83, 81, 79, 84, 77, 74, 83, 80, 88,
+  69, 71, 82, 85, 70, 84, 85, 85, 90, 76,
+  73, 86, 81, 70, 87, 71, 84, 84, 84, 92,
+  95, 92, 98, 83, 79, 76, 78, 78, 90, 84,
+  79, 81, 80, 77, 86, 82, 76, 78, 103, 76,
+  82, 83, 92, 88, 89, 94, 84, 88, 77, 76,
+  94, 74, 95, 91, 78, 95, 93, 77, 164, 86,
+  74, 86, 101, 87, 76, 74, 83, 90, 85, 86,
+  77, 73, 89, 76, 77, 102, 83, 81, 86, 76,
+  83, 95, 88, 93, 83, 89, 90, 77, 81, 82,
+  66, 82, 80, 86, 81, 82, 87, 94, 80, 67,
+  77, 82, 77, 91, 89, 94, 92, 90, 87, 73,
+  81, 79, 78, 79, 90, 68, 81, 86, 69, 85,
+  80, 82, 85, 79, 85, 86, 79, 89, 74, 71,
+  83, 90, 72, 83, 86, 77, 91, 78, 76, 83,
+  87, 69, 83, 73, 82, 80, 78, 93, 100, 86,
+  97, 79, 77, 73, 77, 79, 89, 86, 85, 80,
+  80, 78, 89, 85, 76, 76, 103, 75, 83, 79,
+  84, 87, 90, 90, 85, 89, 71, 76, 91, 71,
+  92, 88, 83, 87, 93, 73, 159, 88, 69, 94,
+  96, 92, 73, 71, 83, 88, 81, 86, 84, 76,
+  90, 76, 80, 101, 87, 81, 80, 82, 84, 92,
+  89, 93, 84, 91, 93, 81, 76, 85, 65, 81,
+  82, 88, 83, 77, 81, 90, 85, 69, 75, 85,
+  83, 93, 83, 91, 96, 87, 83, 71, 84, 81,
+  77, 77, 91, 67, 84, 88, 68, 80, 81, 79,
+  85, 79, 76, 84, 76, 89, 72, 72, 82, 89,
+  73, 85, 78, 81, 90, 85, 58, 89, 95, 79,
+  67, 75, 82, 81, 80, 73, 85, 84, 84, 89,
+  73, 81, 73, 81, 87, 83, 81, 89, 81, 95,
+  98, 87, 108, 86, 96, 90, 82, 98, 84, 106,
+  71, 79, 99, 86, 73, 73, 80, 63, 77, 73,
+  94, 83, 73, 72, 65, 85, 73, 68, 85, 80,
+  70, 97, 100, 94, 80, 99, 79, 79, 76, 103,
+  85, 87, 92, 98, 74, 86, 89, 73, 82, 83,
+  86, 80, 69, 78, 87, 91, 81, 80, 88, 93,
+  69, 107, 81, 84, 93, 85, 71, 98, 97, 110,
+  89, 70, 78, 80, 87, 93, 89, 97, 77, 76,
+  83, 77, 83, 105, 86, 89, 94, 89, 86, 87,
+  76, 94, 87, 82, 69, 69, 73, 78, 85, 71,
+  90, 82, 77, 82, 57, 80, 92, 73, 68, 70,
+  76, 83, 83, 67, 88, 75, 86, 99, 86, 70,
+  74, 83, 88, 78, 83, 95, 81, 99, 93, 88,
+  110, 85, 92, 82, 81, 79, 79, 103, 75, 77,
+  87, 95, 78, 77, 81, 68, 74, 79, 90, 77,
+  70, 68, 68, 87, 79, 81, 82, 80, 76, 81,
+  101, 96, 73, 96, 65, 90, 77, 92, 84, 77,
+  82, 88, 77, 86, 91, 71, 76, 80, 79, 86,
+  73, 72, 84, 76, 85, 72, 88, 85, 66, 107,
+  74, 91, 98, 92, 69, 103, 100, 120, 95, 65,
+  62, 71, 85, 95, 84, 96, 76, 72, 78, 82,
+  88, 106, 82, 83, 84, 81, 76, 89, 80, 89,
+  86, 76, 71, 66, 72, 79, 93, 67, 80, 83,
+  80, 89, 65, 82, 92, 80, 70, 78, 86, 80,
+  79, 74, 85, 88, 84, 90, 75, 81, 77, 80,
+  85, 79, 86, 85, 85, 93, 92, 87, 96, 91,
+  96, 90, 89, 86, 90, 105, 76, 78, 94, 86,
+  79, 76, 85, 76, 79, 90, 96, 84, 71, 78,
+  69, 84, 77, 92, 89, 77, 77, 93, 90, 86,
+  84, 93, 92, 80, 78, 107, 85, 73, 93, 97,
+  83, 83, 90, 81, 86, 80, 76, 78, 71, 73,
+  86, 82, 86, 83, 95, 93, 73, 104, 80, 105,
+  95, 86, 93, 101, 94, 102, 87, 72, 86, 86,
+  85, 92, 88, 94, 76, 85, 85, 79, 88, 102,
+  87, 84, 76, 86, 93, 88, 81, 90, 90, 81,
+  71, 74, 72, 79, 86, 67, 79, 77, 69, 91,
+  86, 76, 86, 83, 67, 83, 89, 78, 74, 66,
+  86, 78, 63, 80, 82, 87, 88, 78, 91, 91,
+  91, 81, 93, 83, 101, 95, 90, 92, 96, 87,
+  72, 90, 103, 97, 85, 75, 104, 71, 74, 75,
+  83, 78, 81, 68, 83, 78, 68, 76, 69, 92,
+  71, 101, 89, 83, 71, 92, 78, 82, 88, 88,
+  81, 78, 82, 95, 78, 72, 114, 100, 74, 82,
+  78, 75, 93, 84, 105, 73, 78, 96, 95, 88,
+  74, 79, 92, 80, 91, 91, 72, 68, 84, 90,
+  75, 94, 87, 93, 82, 69, 82, 79, 76, 85,
+  80, 80, 86, 80, 90, 65, 71, 79, 85, 84,
+  88, 103, 83, 84, 69, 88, 90, 71, 91, 72,
+  76, 84, 82, 75, 81, 78, 71, 94, 86, 69,
+  81, 74, 69, 79, 92, 80, 70, 81, 83, 80,
+  60, 81, 86, 80, 77, 77, 82, 84, 87, 80,
+  93, 83, 97, 85, 86, 99, 95, 85, 77, 79,
+  98, 94, 71, 73, 101, 66, 83, 73, 72, 71,
+  75, 71, 79, 77, 63, 73, 72, 106, 69, 83,
+  86, 90, 63, 84, 82, 89, 87, 87, 67, 86,
+  83, 90, 84, 65, 83, 98, 80, 77, 82, 75,
+  83, 75, 94, 76, 81, 99, 88, 80, 82, 77,
+  89, 77, 78, 89, 72, 71, 79, 88, 71, 99,
+  89, 102, 79, 68, 82, 84, 75, 84, 78, 82,
+  85, 70, 88, 61, 75, 76, 79, 85, 98, 97,
+  73, 84, 72, 92, 90, 66, 102, 67, 79, 88,
+  85, 66, 78, 82, 86, 91, 87, 78, 83, 78,
+  69, 83, 90, 79, 77, 99, 86, 75, 72, 79,
+  78, 89, 73, 85, 78, 87, 85, 77, 92, 83,
+  96, 80, 89, 97, 91, 84, 87, 83, 99, 94,
+  69, 76, 99, 77, 88, 78, 85, 78, 81, 91,
+  79, 78, 67, 91, 72, 91, 72, 66, 91, 86,
+  70, 90, 75, 82, 87, 88, 87, 80, 78, 93,
+  86, 69, 71, 102, 75, 80, 83, 76, 90, 78,
+  80, 77, 77, 98, 94, 74, 87, 81, 86, 83,
+  94, 88, 73, 76, 84, 90, 74, 91, 87, 97,
+  81, 64, 82, 89, 80, 84, 79, 82, 82, 83,
+  89, 68, 80, 84, 82, 88, 93, 98, 93, 84,
+  77, 88, 89, 70, 94, 74, 77, 81, 84, 73,
+  83, 83, 85, 82, 98, 89, 75, 98, 87, 90,
+  81, 92, 89, 97, 76, 76, 75, 87, 84, 90,
+  94, 89, 94, 111, 85, 72, 100, 80, 74, 106,
+  70, 78, 95, 80, 86, 84, 94, 79, 82, 83,
+  99, 70, 76, 91, 82, 98, 94, 84, 79, 76,
+  89, 99, 84, 82, 80, 96, 106, 77, 93, 73,
+  68, 69, 79, 76, 82, 85, 88, 89, 73, 90,
+  97, 72, 97, 79, 75, 74, 89, 94, 86, 67,
+  102, 88, 102, 85, 73, 78, 85, 76, 122, 68,
+  78, 73, 80, 74, 91, 70, 66, 71, 82, 88,
+  81, 89, 83, 80, 73, 91, 91, 95, 106, 90,
+  77, 67, 93, 74, 78, 102, 101, 78, 69, 83,
+  97, 84, 89, 96, 92, 82, 73, 104, 78, 86,
+  87, 81, 95, 82, 75, 96, 86, 89, 86, 93,
+  85, 99, 75, 76, 75, 85, 81, 93, 85, 86,
+  87, 109, 86, 68, 104, 81, 67, 94, 69, 76,
+  99, 86, 98, 76, 96, 67, 82, 82, 97, 67,
+  83, 87, 75, 90, 90, 84, 81, 86, 84, 111,
+  91, 80, 75, 99, 93, 75, 89, 70, 72, 69,
+  86, 69, 84, 85, 91, 88, 71, 97, 96, 82,
+  92, 81, 74, 76, 77, 85, 94, 73, 105, 90,
+  103, 89, 73, 77, 84, 82, 127, 71, 86, 75,
+  79, 67, 86, 72, 60, 70, 75, 93, 87, 96,
+  83, 77, 71, 90, 88, 92, 106, 92, 83, 63,
+  96, 82, 85, 99, 93, 76, 63, 97, 92, 82,
+  100, 96, 94, 82, 68, 103, 79, 84, 84, 77,
+  99, 91, 76, 93, 85, 92, 81, 93, 88, 88,
+  74, 75, 79, 84, 78, 93, 74, 90, 80, 109,
+  91, 67, 101, 82, 65, 85, 71, 81, 90, 87,
+  101, 76, 93, 79, 84, 85, 96, 75, 88, 95,
+  78, 97, 91, 93, 78, 78, 86, 107, 88, 79,
+  79, 82, 96, 80, 93, 72, 67, 71, 86, 75,
+  85, 86, 83, 83, 72, 89, 85, 78, 92, 77,
+  77, 73, 84, 82, 95, 73, 100, 91, 103, 94,
+  75, 75, 77, 80, 121, 77, 74, 73, 82, 77,
+  85, 69, 69, 70, 80, 85, 84, 89, 87, 81,
+  80, 88, 88, 96, 101, 92, 85, 68, 91, 88,
+  84, 90, 96, 79, 71, 87, 82, 83, 92, 91,
+  87, 79, 77, 104, 86, 78, 84, 86, 84, 84,
+  82, 82, 93, 83, 76, 95, 99, 84, 66, 93,
+  80, 89, 84, 105, 73, 89, 74, 80, 81, 84,
+  95, 84, 95, 79, 84, 82, 83, 81, 86, 86,
+  87, 94, 115, 86, 82, 87, 91, 85, 87, 80,
+  88, 87, 75, 84, 83, 83, 83, 78, 81, 94,
+  93, 90, 86, 77, 86, 72, 87, 128, 71, 82,
+  67, 85, 77, 87, 87, 78, 88, 85, 85, 80,
+  85, 70, 75, 94, 89, 84, 86, 83, 92, 94,
+  79, 72, 86, 82, 85, 91, 82, 83, 85, 88,
+  87, 79, 87, 77, 89, 74, 89, 80, 83, 83,
+  86, 85, 83, 79, 86, 73, 90, 86, 79, 85,
+  74, 76, 85, 93, 86, 87, 83, 81, 82, 87,
+  84, 75, 84, 76, 85, 78, 86, 71, 81, 70,
+  91, 89, 85, 99, 87, 80, 68, 81, 81, 85,
+  87, 82, 79, 89, 81, 86, 80, 73, 83, 82,
+  74, 82, 75, 84, 91, 82, 80, 94, 71, 84,
+  86, 71, 70, 88, 75, 86, 79, 78, 91, 85,
+  81, 90, 88, 78, 85, 71, 80, 78, 99, 81,
+  88, 77, 83, 66, 74, 128, 71, 62, 73, 105,
+  69, 91, 89, 98, 86, 81, 84, 84, 92, 88,
+  70, 100, 89, 79, 85, 88, 85, 81, 70, 96,
+  77, 83, 79, 78, 80, 76, 86, 80, 83, 79,
+  86, 78, 91, 101, 91, 80, 70, 79, 81, 88,
+  89, 88, 90, 79, 87, 76, 82, 84, 72, 79,
+  86, 85, 75, 80, 73, 79, 100, 74, 84, 73,
+  88, 73, 91, 89, 94, 74, 80, 86, 85, 84,
+  74, 91, 78, 95, 63, 91, 80, 89, 85, 86,
+  94, 89, 88, 84, 80, 80, 92, 84, 92, 84,
+  87, 79, 88, 93, 74, 82, 77, 100, 75, 88,
+  85, 81, 75, 88, 84, 95, 88, 76, 82, 77,
+  88, 83, 86, 74, 81, 89, 90, 83, 84, 80,
+  85, 77, 86, 113, 75, 77, 68, 89, 79, 83,
+  81, 69, 85, 85, 86, 89, 82, 94, 82, 93,
+  85, 88, 86, 91, 87, 88, 98, 74, 83, 83,
+  87, 96, 87, 80, 104, 86, 85, 77, 82, 79,
+  91, 72, 86, 82, 90, 83, 91, 86, 90, 80,
+  100, 75, 92, 87, 93, 83, 81, 72, 80, 89,
+  87, 85, 86, 82, 83, 92, 85, 81, 72, 78,
+  82, 89, 74, 93, 69, 80, 88, 77, 66, 93,
+  73, 91, 65, 92, 79, 99, 79, 109, 71, 66,
+  94, 75, 72, 80, 96, 85, 103, 83, 67, 92,
+  91, 73, 86, 94, 74, 87, 75, 69, 79, 43,
+  88, 81, 77, 96, 84, 86, 73, 82, 89, 79,
+  81, 70, 78, 76, 88, 71, 85, 77, 79, 84,
+  92, 62, 79, 44, 62, 75, 87, 98, 86, 64,
+  89, 92, 87, 69, 78, 82, 81, 80, 82, 77,
+  81, 108, 68, 90, 85, 68, 81, 87, 90, 93,
+  77, 73, 95, 82, 82, 66, 74, 69, 86, 83,
+  77, 85, 86, 79, 87, 85, 69, 74, 85, 80,
+  84, 93, 71, 72, 91, 69, 60, 91, 83, 80,
+  73, 71, 72, 95, 79, 75, 98, 89, 76, 80,
+  82, 42, 93, 68, 82, 95, 99, 111, 111, 93,
+  78, 79, 87, 65, 94, 68, 69, 101, 55, 102,
+  91, 83, 71, 88, 72, 96, 107, 83, 92, 109,
+  91, 76, 87, 87, 129, 64, 92, 155, 72, 81,
+  96, 57, 96, 88, 96, 101, 81, 83, 85, 64,
+  97, 97, 103, 97, 92, 76, 96, 84, 65, 255,
+  39, 112, 73, 95, 88, 68, 73, 120, 59, 90,
+  76, 78, 102, 74, 66, 111, 96, 83, 97, 60,
+  122, 92, 30, 108, 81, 73, 82, 59, 94, 102,
+  68, 89, 84, 85, 98, 81, 70, 87, 110, 79,
+  69, 80, 79, 88, 96, 93, 106, 84, 88, 32,
+  86, 94, 60, 92, 117, 96, 55, 86, 90, 90,
+  105, 61, 93, 90, 76, 76, 92, 90, 80, 97,
+  68, 85, 82, 76, 64, 90, 66, 87, 66, 96,
+  85, 99, 81, 85, 94, 62, 94, 81, 74, 77,
+  88, 81, 104, 91, 70, 79, 93, 83, 76, 84,
+  66, 92, 71, 70, 79, 56, 79, 86, 78, 93,
+  83, 85, 80, 77, 89, 72, 82, 70, 81, 88,
+  81, 70, 84, 82, 82, 81, 90, 62, 71, 50,
+  61, 86, 91, 85, 85, 66, 87, 90, 86, 75,
+  79, 103, 83, 83, 81, 75, 76, 89, 72, 82,
+  90, 70, 74, 81, 90, 105, 82, 74, 108, 81,
+  82, 68, 78, 73, 89, 84, 80, 86, 92, 83,
+  89, 88, 77, 79, 87, 81, 91, 84, 75, 87,
+  95, 68, 67, 88, 88, 81, 82, 72, 76, 96,
+  81, 82, 84, 77, 70, 89, 97, 86, 76, 84,
+  88, 82, 73, 90, 79, 98, 69, 90, 78, 95,
+  95, 107, 75, 91, 91, 80, 83, 87, 91, 88,
+  96, 79, 86, 90, 89, 76, 72, 88, 69, 88,
+  77, 85, 83, 78, 78, 79, 82, 89, 89, 84,
+  87, 81, 88, 87, 85, 76, 86, 80, 92, 83,
+  85, 80, 77, 76, 92, 109, 91, 76, 73, 86,
+  86, 90, 82, 77, 81, 87, 91, 81, 83, 87,
+  80, 91, 84, 71, 89, 93, 83, 86, 79, 74,
+  88, 81, 88, 87, 82, 85, 91, 84, 86, 79,
+  78, 74, 78, 88, 82, 86, 94, 78, 101, 86,
+  81, 85, 90, 71, 92, 89, 84, 82, 82, 77,
+  79, 85, 86, 86, 83, 78, 80, 92, 83, 80,
+  83, 76, 86, 87, 94, 72, 78, 70, 82, 85,
+  86, 97, 89, 85, 64, 85, 76, 83, 89, 92,
+  74, 73, 81, 96, 78, 72, 87, 88, 66, 85,
+  74, 84, 88, 95, 76, 84, 83, 76, 87, 70,
+  92, 94, 74, 80, 79, 74, 91, 76, 88, 91,
+  86, 86, 83, 66, 92, 76, 93, 81, 73, 80,
+  92, 71, 80, 145, 76, 66, 72, 91, 82, 81,
+  87, 103, 69, 92, 79, 82, 92, 85, 83, 104,
+  91, 78, 90, 87, 81, 90, 62, 92, 78, 72,
+  95, 76, 89, 90, 79, 86, 82, 82, 78, 79,
+  77, 86, 87, 82, 75, 74, 90, 88, 71, 90,
+  86, 73, 84, 69, 77, 75, 79, 84, 89, 95,
+  74, 80, 74, 82, 98, 76, 81, 79, 86, 92,
+  77, 92, 95, 87, 75, 82, 86, 81, 73, 91,
+  80, 85, 68, 91, 85, 95, 92, 93, 84, 78,
+  87, 86, 81, 83, 90, 88, 92, 83, 76, 83,
+  88, 87, 71, 79, 62, 84, 96, 83, 88, 83,
+  78, 86, 82, 83, 86, 79, 87, 82, 88, 86,
+  83, 79, 88, 90, 88, 82, 82, 83, 83, 77,
+  88, 108, 82, 71, 65, 92, 87, 87, 81, 82,
+  81, 88, 88, 85, 79, 88, 85, 93, 86, 72,
+  86, 87, 89, 84, 86, 73, 83, 82, 93, 101,
+  82, 88, 94, 81, 85, 77, 92, 77, 79, 93,
+  86, 86, 98, 77, 99, 93, 84, 84, 79, 74,
+  95, 75, 75, 83, 98, 75, 84, 83, 80, 84,
+  88, 79, 82, 87, 83, 80, 101, 80, 92, 98,
+  85, 82, 69, 77, 84, 81, 77, 90, 84, 109,
+  86, 71, 97, 82, 101, 82, 89, 92, 102, 80,
+  94, 66, 97, 79, 100, 88, 89, 81, 92, 64,
+  82, 92, 79, 67, 100, 76, 88, 76, 79, 86,
+  79, 97, 83, 84, 74, 82, 102, 84, 85, 97,
+  107, 100, 92, 55, 77, 95, 78, 91, 98, 95,
+  62, 92, 72, 97, 86, 55, 98, 76, 102, 87,
+  86, 78, 96, 95, 90, 80, 91, 78, 107, 85,
+  89, 82, 99, 69, 89, 86, 49, 84, 78, 87,
+  96, 71, 90, 89, 98, 64, 66, 85, 58, 85,
+  83, 100, 95, 80, 66, 73, 85, 101, 69, 88,
+  98, 112, 89, 70, 91, 88, 96, 83, 83, 73,
+  90, 85, 112, 84, 102, 87, 79, 93, 83, 95,
+  66, 80, 80, 79, 74, 94, 81, 100, 86, 66,
+  108, 86, 113, 80, 74, 103, 77, 72, 111, 66,
+  97, 73, 110, 94, 90, 91, 99, 73, 89, 91,
+  74, 59, 107, 73, 78, 78, 93, 91, 76, 100,
+  90, 88, 72, 75, 98, 88, 85, 102, 95, 86,
+  93, 54, 80, 88, 88, 93, 99, 85, 50, 93,
+  66, 96, 90, 61, 98, 74, 98, 78, 75, 73,
+  96, 78, 82, 80, 89, 79, 123, 109, 91, 74,
+  86, 73, 82, 91, 51, 83, 82, 85, 94, 73,
+  85, 93, 77, 65, 68, 85, 54, 93, 69, 98,
+  101, 78, 70, 66, 81, 102, 73, 97, 97, 102,
+  105, 62, 88, 82, 89, 88, 78, 73, 81, 83,
+  118, 82, 71, 92, 89, 87, 73, 93, 78, 82,
+  81, 86, 73, 88, 88, 87, 92, 83, 86, 79,
+  88, 87, 80, 80, 80, 102, 91, 86, 74, 92,
+  91, 93, 83, 75, 81, 91, 81, 92, 84, 89,
+  96, 86, 83, 84, 87, 81, 84, 86, 77, 98,
+  101, 80, 88, 90, 77, 76, 86, 82, 79, 71,
+  73, 89, 84, 84, 90, 67, 67, 83, 74, 83,
+  87, 85, 95, 83, 86, 89, 90, 83, 85, 73,
+  85, 82, 82, 80, 86, 98, 84, 74, 77, 88,
+  85, 89, 82, 88, 91, 92, 81, 84, 85, 85,
+  75, 79, 91, 100, 85, 85, 107, 89, 81, 84,
+  72, 69, 92, 81, 77, 96, 98, 88, 99, 90,
+  83, 80, 81, 85, 71, 87, 94, 83, 89, 86,
+  89, 82, 71, 75, 86, 77, 67, 87, 87, 83,
+  65, 83, 73, 91, 83, 78, 85, 74, 84, 77,
+  71, 86, 77, 91, 86, 79, 92, 92, 82, 91,
+  81, 79, 88, 69, 92, 84, 89, 61, 90, 83,
+  83, 67, 76, 71, 57, 73, 82, 76, 83, 82,
+  96, 86, 91, 87, 90, 103, 86, 68, 75, 95,
+  71, 79, 100, 89, 58, 85, 72, 88, 96, 66,
+  98, 96, 95, 77, 90, 85, 86, 90, 103, 76,
+  91, 75, 100, 83, 98, 74, 93, 81, 82, 82,
+  68, 75, 78, 78, 84, 71, 82, 83, 94, 72,
+  73, 91, 74, 79, 99, 93, 79, 81, 70, 71,
+  67, 95, 82, 79, 101, 89, 79, 77, 95, 76,
+  82, 84, 73, 91, 82, 79, 94, 80, 90, 77,
+  81, 75, 82, 70, 67, 87, 80, 76, 66, 83,
+  72, 97, 86, 73, 86, 79, 79, 77, 67, 90,
+  79, 84, 99, 77, 85, 86, 94, 108, 87, 79,
+  89, 72, 90, 79, 86, 54, 91, 79, 80, 65,
+  73, 79, 52, 74, 87, 86, 84, 81, 88, 90,
+  89, 83, 79, 83, 84, 69, 83, 86, 77, 82,
+  95, 82, 50, 83, 77, 86, 94, 70, 80, 92,
+  89, 72, 86, 79, 87, 80, 92, 68, 89, 78,
+  97, 95, 101, 83, 77, 85, 82, 79, 65, 73,
+  82, 77, 74, 73, 78, 87, 77, 74, 76, 79,
+  73, 83, 92, 95, 80, 82, 69, 72, 68, 95,
+  87, 86, 109, 88, 92, 75, 91, 73, 83, 89,
+  70, 91, 79, 83, 95, 80, 72, 80, 89, 82,
+  79, 79, 84, 78, 85, 77, 72, 82, 80, 83,
+  92, 89, 77, 77, 79, 83, 86, 83, 86, 108,
+  92, 88, 75, 95, 75, 84, 82, 75, 81, 88,
+  79, 82, 85, 87, 87, 100, 80, 82, 76, 83,
+  77, 77, 79, 91, 101, 85, 84, 84, 86, 72,
+  82, 78, 78, 87, 71, 78, 84, 82, 89, 65,
+  72, 83, 91, 68, 87, 83, 77, 82, 83, 83,
+  88, 81, 85, 79, 73, 82, 89, 75, 82, 83,
+  79, 77, 68, 87, 86, 77, 90, 75, 83, 77,
+  75, 85, 81, 80, 74, 86, 82, 79, 90, 79,
+  108, 89, 70, 88, 83, 79, 87, 80, 84, 85,
+  103, 85, 89, 90, 79, 81, 82, 83, 85, 87,
+  95, 80, 82, 89, 84, 83, 76, 73, 89, 85,
+  85, 80, 89, 79, 76, 81, 84, 85, 84, 84,
+  74, 81, 83, 81, 84, 79, 85, 109, 83, 90,
+  78, 103, 88, 89, 86, 78, 80, 85, 86, 79,
+  90, 80, 87, 92, 91, 75, 82, 71, 81, 73,
+  91, 83, 93, 91, 90, 83, 79, 71, 87, 93,
+  82, 85, 70, 79, 83, 76, 93, 81, 63, 83,
+  86, 74, 87, 80, 96, 85, 91, 83, 98, 85,
+  86, 83, 84, 76, 85, 75, 81, 88, 91, 78,
+  79, 93, 78, 78, 85, 79, 77, 74, 84, 81,
+  84, 81, 90, 82, 78, 95, 90, 81, 107, 81,
+  67, 91, 87, 80, 89, 84, 87, 80, 95, 87,
+  85, 99, 88, 87, 79, 83, 78, 89, 84, 79,
+  84, 94, 84, 79, 85, 78, 85, 77, 90, 81,
+  87, 76, 78, 86, 80, 88, 92, 84, 75, 81,
+  79, 89, 84, 76, 85, 102, 89, 90, 81, 98,
+  89, 89, 87, 81, 82, 84, 86, 72, 89, 74,
+  85, 89, 87, 77, 82, 78, 78, 69, 88, 82,
+  94, 90, 88, 82, 81, 68, 84, 90, 81, 84,
+  77, 78, 83, 78, 91, 80, 69, 86, 91, 72,
+  84, 82, 75, 82, 90, 82, 100, 78, 86, 81,
+  84, 72, 88, 80, 77, 84, 91, 83, 80, 91,
+  80, 74, 81, 79, 83, 76, 77, 82, 86, 84,
+  84, 84, 81, 94, 93, 83, 111, 82, 70, 94,
+  91, 80, 93, 81, 91, 76, 95, 81, 87, 96,
+  83, 87, 84, 85, 83, 90, 83, 82, 86, 92,
+  76, 75, 85, 88, 83, 86, 91, 76, 90, 75,
+  84, 92, 87, 81, 85, 87, 76, 84, 90, 86,
+  89, 86, 85, 107, 87, 88, 79, 92, 75, 78,
+  83, 82, 84, 85, 87, 79, 83, 87, 84, 96,
+  84, 85, 90, 85, 90, 82, 82, 84, 87, 88,
+  85, 84, 77, 75, 89, 80, 83, 90, 81, 82,
+  90, 89, 86, 81, 89, 89, 87, 78, 84, 87,
+  78, 78, 95, 79, 95, 81, 83, 82, 79, 84,
+  83, 79, 83, 82, 84, 74, 80, 89, 76, 75,
+  91, 76, 89, 81, 79, 84, 85, 82, 88, 91,
+  91, 93, 84, 81, 91, 88, 78, 94, 86, 83,
+  95, 86, 84, 80, 91, 84, 88, 98, 84, 87,
+  84, 83, 81, 82, 89, 77, 77, 90, 80, 79,
+  78, 82, 112, 83, 77, 68, 81, 96, 88, 87,
+  81, 87, 83, 70, 72, 75, 67, 88, 87, 82,
+  74, 88, 94, 97, 83, 80, 86, 97, 74, 76,
+  80, 88, 71, 70, 74, 79, 86, 104, 88, 94,
+  76, 99, 79, 91, 77, 78, 64, 77, 87, 75,
+  84, 97, 86, 82, 79, 95, 69, 87, 71, 89,
+  75, 87, 100, 82, 77, 73, 84, 96, 80, 86,
+  86, 76, 70, 84, 82, 65, 76, 107, 65, 85,
+  90, 83, 95, 74, 89, 88, 90, 67, 74, 88,
+  78, 81, 79, 115, 75, 93, 89, 86, 92, 85,
+  90, 80, 85, 81, 78, 80, 94, 77, 77, 84,
+  93, 86, 97, 84, 95, 85, 78, 78, 81, 81,
+  86, 92, 84, 84, 80, 82, 77, 89, 79, 84,
+  116, 75, 88, 74, 79, 98, 82, 83, 78, 88,
+  88, 68, 72, 79, 69, 94, 77, 78, 73, 92,
+  92, 97, 87, 82, 90, 87, 78, 69, 79, 78,
+  75, 77, 82, 76, 86, 103, 88, 101, 81, 96,
+  82, 82, 76, 69, 66, 77, 93, 66, 86, 90,
+  87, 87, 83, 86, 64, 90, 71, 94, 79, 89,
+  89, 79, 70, 71, 83, 94, 81, 91, 88, 81,
+  76, 80, 79, 65, 85, 101, 65, 88, 96, 74,
+  112, 75, 82, 88, 92, 61, 79, 88, 74, 80,
+  71, 118, 71, 87, 84, 86, 88, 78, 86, 81,
+  76, 80, 78, 80, 93, 76, 90, 92, 94, 86,
+  95, 81, 73, 87, 74, 83, 75, 75, 83, 92,
+  75, 83, 79, 77, 81, 97, 84, 83, 110, 75,
+  79, 74, 83, 95, 87, 87, 79, 94, 79, 72,
+  72, 78, 72, 101, 77, 86, 87, 85, 97, 98,
+  85, 78, 85, 74, 76, 75, 80, 69, 86, 86,
+  77, 78, 94, 102, 86, 91, 85, 93, 80, 90,
+  74, 67, 65, 76, 86, 69, 82, 96, 88, 90,
+  80, 95, 72, 81, 74, 91, 76, 89, 99, 80,
+  74, 74, 89, 95, 84, 89, 92, 79, 78, 85,
+  83, 74, 79, 109, 64, 85, 90, 77, 90, 82,
+  84, 88, 85, 74, 78, 88, 82, 84, 69, 113,
+  74, 92, 88, 93, 95, 93, 85, 78, 87, 82,
+  81, 77, 91, 76, 81, 84, 91, 90, 89, 83,
+  71, 86, 77, 82, 78, 83, 80, 92, 84, 80,
+  79, 82, 79, 74, 71, 78, 101, 91, 82, 69,
+  80, 92, 94, 81, 87, 91, 92, 83, 89, 76,
+  70, 83, 85, 89, 76, 88, 102, 95, 76, 84,
+  81, 95, 75, 82, 77, 97, 73, 71, 73, 73,
+  91, 96, 87, 99, 78, 98, 83, 85, 75, 83,
+  68, 75, 94, 78, 81, 94, 84, 82, 85, 96,
+  63, 92, 75, 89, 80, 100, 95, 80, 73, 62,
+  88, 84, 78, 93, 84, 79, 68, 85, 84, 60,
+  73, 112, 68, 107, 90, 77, 105, 77, 92, 87,
+  87, 69, 71, 89, 72, 80, 85, 117, 76, 100,
+  96, 97, 80, 87, 82, 86, 75, 86, 76, 82,
+  88, 78, 80, 89, 94, 78, 84, 84, 87, 86,
+  82, 76, 78, 82, 93, 92, 82, 81, 74, 83,
+  79, 92, 74, 79, 115, 73, 90, 75, 79, 93,
+  94, 78, 88, 93, 96, 90, 88, 75, 70, 81,
+  74, 87, 71, 96, 107, 102, 76, 87, 83, 77,
+  86, 80, 75, 89, 73, 71, 72, 63, 96, 104,
+  84, 112, 79, 99, 89, 74, 76, 69, 67, 77,
+  101, 74, 83, 95, 85, 83, 85, 91, 56, 92,
+  75, 93, 81, 115, 78, 84, 74, 58, 92, 82,
+  74, 101, 81, 84, 76, 79, 81, 63, 74, 112,
+  75, 119, 102, 66, 123, 85, 74, 87, 99, 64,
+  74, 79, 67, 76, 68, 124, 73, 91, 83, 96,
+  78, 78, 77, 85, 67, 84, 73, 80, 92, 79,
+  89, 95, 95, 77, 85, 80, 66, 87, 78, 77,
+  75, 75, 99, 95, 83, 79, 70, 74, 78, 94,
+  88, 79, 97, 78, 82, 72, 80, 91, 91, 83,
+  84, 92, 87, 84, 86, 80, 75, 101, 78, 93,
+  93, 84, 108, 95, 79, 84, 80, 74, 81, 86,
+  76, 73, 90, 87, 75, 71, 99, 94, 84, 91,
+  85, 92, 83, 83, 78, 67, 66, 75, 94, 74,
+  79, 92, 84, 76, 83, 100, 66, 89, 78, 94,
+  79, 98, 93, 81, 70, 65, 90, 88, 78, 93,
+  87, 80, 82, 83, 85, 82, 76, 109, 67, 102,
+  91, 72, 102, 85, 73, 88, 82, 73, 74, 80,
+  76, 76, 71, 114, 75, 102, 82, 100, 78, 82,
+  80, 84, 74, 85, 80, 78, 85, 80, 83, 93,
+  92, 93, 81, 80, 71, 87, 82, 79, 78, 87,
+  82, 92, 86, 80, 77, 86, 77, 72, 68, 87,
+  95, 90, 74, 65, 73, 93, 90, 77, 83, 88,
+  87, 95, 90, 82, 72, 81, 82, 84, 81, 78,
+  93, 88, 84, 81, 85, 84, 78, 87, 80, 94,
+  77, 73, 74, 70, 86, 92, 85, 83, 83, 92,
+  82, 85, 80, 85, 65, 75, 92, 66, 76, 98,
+  88, 76, 87, 100, 78, 79, 86, 76, 84, 91,
+  95, 78, 77, 64, 90, 90, 78, 84, 82, 79,
+  72, 77, 88, 69, 87, 97, 70, 88, 86, 79,
+  92, 74, 97, 87, 81, 84, 73, 94, 81, 71,
+  92, 103, 79, 97, 100, 93, 87, 93, 83, 85,
+  84, 80, 82, 77, 80, 87, 82, 86, 85, 80,
+  89, 87, 83, 83, 83, 83, 79, 85, 84, 91,
+  78, 83, 83, 87, 78, 80, 75, 85, 100, 80,
+  78, 66, 70, 91, 90, 74, 84, 91, 88, 92,
+  89, 84, 67, 82, 82, 82, 84, 84, 94, 96,
+  82, 83, 87, 77, 83, 87, 75, 88, 73, 80,
+  70, 68, 88, 91, 89, 88, 80, 94, 88, 73,
+  81, 78, 65, 73, 92, 68, 74, 93, 87, 81,
+  87, 89, 74, 79, 91, 84, 85, 89, 87, 75,
+  86, 68, 89, 96, 76, 90, 79, 84, 76, 72,
+  93, 72, 84, 100, 74, 93, 88, 67, 100, 84,
+  82, 93, 85, 77, 74, 94, 78, 69, 77, 109,
+  75, 92, 86, 96, 81, 95, 79, 86, 76, 80,
+  81, 78, 82, 84, 86, 94, 87, 80, 86, 90,
+  72, 84, 82, 83, 81, 86, 82, 91, 78, 85,
+  83, 77, 74, 85, 87, 85, 97, 81, 74, 69,
+  74, 92, 88, 79, 82, 87, 85, 93, 87, 88,
+  76, 95, 85, 87, 90, 77, 97, 86, 83, 83,
+  82, 78, 82, 86, 78, 77, 80, 85, 76, 70,
+  83, 90, 89, 83, 81, 90, 86, 83, 84, 72,
+  65, 77, 90, 62, 74, 94, 85, 78, 83, 105,
+  83, 79, 87, 80, 83, 91, 87, 77, 77, 70,
+  86, 92, 74, 86, 85, 82, 84, 79, 87, 79,
+  87, 99, 70, 87, 86, 71, 89, 82, 75, 84,
+  78, 82, 74, 83, 84, 68, 75, 103, 76, 99,
+  79, 96, 86, 85, 80, 84, 84, 81, 88, 73,
+  80, 88, 83, 89, 85, 92, 86, 87, 68, 85,
+  84, 82, 88, 89, 76, 91, 80, 85, 84, 88,
+  90, 69, 70, 81, 97, 84, 64, 90, 66, 79,
+  84, 85, 67, 77, 80, 84, 77, 78, 76, 88,
+  72, 69, 74, 75, 74, 91, 88, 88, 97, 100,
+  75, 85, 70, 93, 86, 94, 93, 86, 76, 72,
+  79, 87, 72, 118, 89, 89, 72, 95, 92, 83,
+  86, 77, 88, 73, 82, 85, 71, 62, 74, 71,
+  74, 91, 80, 92, 78, 74, 82, 91, 83, 92,
+  68, 88, 96, 94, 88, 75, 93, 74, 78, 52,
+  100, 100, 89, 86, 84, 83, 77, 105, 85, 78,
+  76, 83, 77, 73, 89, 79, 92, 87, 82, 90,
+  82, 77, 98, 99, 79, 78, 101, 138, 81, 76,
+  71, 76, 75, 73, 89, 78, 81, 93, 82, 89,
+  80, 91, 78, 81, 113, 85, 76, 77, 83, 73,
+  65, 85, 102, 79, 58, 95, 69, 78, 83, 87,
+  74, 88, 85, 85, 76, 79, 73, 94, 70, 61,
+  82, 72, 68, 95, 84, 88, 92, 93, 67, 83,
+  70, 81, 95, 90, 90, 81, 76, 65, 76, 81,
+  72, 136, 83, 84, 79, 85, 80, 81, 88, 90,
+  92, 79, 76, 92, 70, 70, 89, 67, 70, 78,
+  75, 88, 86, 77, 87, 81, 79, 96, 77, 81,
+  99, 90, 95, 68, 89, 82, 78, 48, 98, 100,
+  88, 90, 68, 81, 73, 107, 95, 82, 81, 80,
+  78, 68, 87, 77, 91, 90, 80, 90, 81, 78,
+  95, 100, 80, 89, 107, 148, 85, 76, 68, 75,
+  76, 77, 74, 85, 72, 87, 80, 95, 85, 94,
+  77, 80, 117, 84, 75, 78, 91, 79, 66, 82,
+  81, 73, 67, 89, 68, 75, 83, 80, 76, 87,
+  82, 86, 80, 82, 79, 89, 77, 73, 83, 73,
+  78, 98, 89, 84, 92, 82, 79, 81, 76, 79,
+  93, 98, 91, 88, 77, 72, 79, 82, 79, 95,
+  89, 86, 74, 89, 93, 87, 85, 82, 83, 75,
+  83, 91, 75, 58, 73, 78, 79, 93, 78, 88,
+  70, 80, 85, 90, 84, 95, 75, 93, 95, 93,
+  96, 79, 97, 88, 84, 59, 84, 95, 92, 85,
+  86, 84, 72, 92, 79, 79, 77, 80, 83, 80,
+  87, 76, 89, 82, 74, 99, 80, 75, 96, 99,
+  77, 83, 96, 116, 86, 75, 69, 76, 79, 76,
+  67, 92, 81, 92, 85, 91, 86, 87, 78, 84,
+  97, 89, 82, 84, 92, 61, 65, 89, 87, 99,
+  49, 79, 86, 76, 82, 82, 73, 81, 81, 92,
+  91, 70, 82, 77, 78, 74, 76, 82, 76, 111,
+  72, 90, 96, 94, 78, 89, 68, 98, 93, 86,
+  76, 88, 68, 87, 77, 91, 81, 158, 94, 92,
+  83, 99, 70, 79, 89, 85, 94, 81, 72, 86,
+  68, 72, 85, 59, 72, 94, 74, 96, 80, 77,
+  76, 89, 80, 85, 70, 76, 83, 85, 89, 66,
+  89, 83, 65, 71, 123, 120, 84, 87, 73, 74,
+  81, 111, 94, 88, 69, 84, 81, 69, 82, 85,
+  95, 94, 83, 84, 83, 77, 92, 93, 82, 77,
+  100, 173, 62, 79, 71, 71, 76, 78, 83, 75,
+  75, 87, 89, 84, 85, 85, 65, 82, 129, 78,
+  76, 73, 82, 79, 65, 92, 94, 84, 43, 78,
+  95, 84, 79, 87, 83, 71, 93, 84, 94, 66,
+  80, 83, 74, 63, 84, 83, 76, 116, 66, 99,
+  90, 91, 81, 85, 60, 80, 92, 78, 74, 103,
+  74, 84, 81, 101, 80, 187, 95, 77, 91, 80,
+  61, 73, 93, 92, 101, 92, 71, 88, 74, 85,
+  100, 50, 59, 80, 70, 109, 73, 83, 85, 89,
+  77, 76, 64, 80, 81, 84, 96, 64, 84, 87,
+  64, 82, 129, 129, 81, 82, 65, 76, 74, 114,
+  105, 85, 70, 69, 87, 67, 71, 92, 96, 112,
+  88, 80, 74, 69, 93, 93, 89, 79, 102, 181,
+  69, 79, 80, 69, 80, 73, 84, 82, 68, 87,
+  95, 80, 81, 88, 57, 87, 150, 75, 85, 73,
+  97, 83, 76, 90, 77, 78, 57, 77, 83, 74,
+  81, 79, 73, 73, 85, 89, 86, 77, 80, 91,
+  75, 80, 97, 79, 79, 103, 81, 86, 90, 87,
+  82, 82, 72, 81, 94, 92, 78, 88, 74, 82,
+  77, 87, 83, 129, 89, 90, 86, 89, 76, 82,
+  86, 82, 87, 81, 72, 80, 73, 67, 85, 64,
+  76, 96, 69, 84, 78, 79, 78, 91, 81, 88,
+  81, 82, 90, 89, 97, 67, 98, 92, 74, 75,
+  105, 117, 85, 84, 76, 76, 79, 106, 90, 83,
+  73, 73, 84, 75, 83, 80, 94, 93, 78, 89,
+  86, 74, 88, 94, 80, 84, 97, 147, 71, 78,
+  82, 75, 80, 79, 84, 85, 89, 91, 84, 90,
+  84, 83, 69, 84, 109, 83, 77, 75, 91, 70,
+  65, 91, 94, 90, 63, 84, 79, 80, 90, 74,
+  70, 82, 77, 98, 89, 70, 84, 84, 83, 69,
+  78, 89, 83, 103, 79, 84, 94, 91, 89, 86,
+  77, 105, 90, 85, 96, 80, 74, 78, 86, 83,
+  79, 107, 87, 95, 82, 93, 88, 95, 85, 74,
+  90, 83, 78, 89, 78, 62, 86, 76, 76, 99,
+  84, 94, 79, 82, 80, 91, 74, 75, 74, 82,
+  84, 70, 84, 78, 94, 82, 77, 52, 110, 87,
+  88, 87, 82, 79, 82, 97, 79, 104, 78, 94,
+  88, 74, 91, 72, 91, 79, 89, 96, 80, 88,
+  92, 94, 85, 84, 88, 125, 70, 89, 67, 72,
+  81, 81, 79, 87, 68, 87, 91, 86, 84, 91,
+  71, 84, 98, 85, 73, 87, 92, 74, 71, 94,
+  97, 81, 60, 80, 83, 83, 86, 77, 77, 78,
+  81, 95, 90, 74, 84, 86, 74, 58, 84, 85,
+  78, 96, 79, 87, 87, 91, 90, 85, 67, 88,
+  87, 77, 90, 86, 74, 71, 92, 81, 79, 123,
+  80, 92, 90, 76, 76, 83, 87, 83, 88, 82,
+  79, 80, 77, 72, 93, 67, 71, 91, 87, 94,
+  87, 77, 88, 81, 74, 89, 64, 80, 81, 73,
+  79, 67, 89, 87, 76, 53, 113, 93, 87, 89,
+  77, 82, 79, 105, 86, 95, 74, 89, 84, 73,
+  86, 71, 92, 89, 84, 90, 79, 86, 89, 93,
+  87, 87, 85, 136, 65, 88, 75, 71, 76, 83,
+  93, 90, 74, 84, 91, 90, 86, 88, 63, 82,
+  108, 86, 77, 86, 94, 83, 86, 87, 87, 81,
+  66, 77, 80, 83, 90, 71, 71, 81, 78, 98,
+  84, 72, 84, 90, 72, 76, 91, 87, 85, 97,
+  84, 86, 86, 85, 92, 83, 78, 85, 89, 88,
+  98, 80, 78, 79, 86, 88, 82, 92, 83, 93,
+  82, 81, 89, 97, 80, 80, 80, 82, 78, 66,
+  76, 60, 84, 80, 76, 97, 81, 88, 82, 80,
+  83, 92, 83, 75, 68, 85, 86, 75, 84, 76,
+  97, 95, 74, 61, 96, 93, 89, 86, 83, 80,
+  78, 91, 82, 91, 80, 82, 89, 81, 87, 68,
+  90, 79, 80, 96, 81, 80, 89, 94, 89, 85,
+  82, 111, 69, 86, 80, 72, 79, 83, 94, 87,
+  90, 92, 89, 89, 95, 86, 72, 84, 88, 87,
+  80, 88, 86, 82, 97, 87, 81, 98, 94, 78,
+  78, 88, 81, 92, 100, 97, 87, 88, 98, 102,
+  70, 83, 88, 101, 96, 81, 86, 92, 87, 83,
+  93, 78, 78, 83, 89, 89, 68, 78, 91, 92,
+  78, 92, 83, 85, 88, 90, 80, 89, 86, 84,
+  80, 95, 56, 100, 84, 63, 83, 77, 89, 75,
+  81, 87, 97, 75, 77, 76, 90, 67, 77, 86,
+  74, 91, 84, 84, 81, 88, 79, 91, 85, 83,
+  83, 76, 87, 72, 81, 83, 92, 72, 89, 73,
+  75, 80, 78, 71, 81, 88, 76, 83, 84, 86,
+  86, 86, 64, 69, 81, 74, 81, 69, 68, 99,
+  75, 82, 74, 85, 93, 89, 92, 81, 98, 81,
+  81, 79, 80, 84, 89, 90, 83, 78, 79, 96,
+  89, 91, 85, 88, 68, 88, 92, 83, 84, 90,
+  82, 99, 117, 71, 88, 99, 103, 112, 67, 90,
+  100, 83, 79, 83, 82, 88, 100, 91, 85, 62,
+  83, 78, 82, 85, 72, 67, 90, 96, 81, 104,
+  79, 88, 93, 96, 83, 91, 85, 67, 65, 97,
+  45, 94, 97, 56, 88, 86, 90, 75, 74, 88,
+  102, 66, 75, 86, 87, 65, 82, 86, 65, 88,
+  105, 72, 80, 96, 81, 83, 78, 81, 89, 74,
+  84, 67, 85, 77, 95, 67, 85, 68, 77, 84,
+  88, 70, 70, 86, 73, 89, 85, 83, 84, 84,
+  61, 72, 86, 71, 84, 68, 72, 102, 69, 83,
+  80, 90, 104, 87, 84, 77, 94, 76, 78, 87,
+  83, 80, 87, 99, 78, 77, 90, 95, 84, 83,
+  82, 80, 79, 96, 92, 82, 74, 83, 85, 85,
+  94, 70, 92, 89, 96, 91, 75, 93, 85, 102,
+  90, 81, 82, 93, 83, 85, 86, 68, 77, 89,
+  92, 86, 84, 89, 99, 88, 82, 92, 82, 86,
+  83, 84, 81, 85, 86, 77, 84, 99, 66, 85,
+  81, 69, 81, 80, 86, 80, 84, 89, 96, 75,
+  81, 71, 88, 71, 77, 86, 77, 79, 108, 90,
+  89, 86, 80, 91, 87, 87, 85, 83, 91, 82,
+  83, 81, 85, 65, 90, 79, 81, 79, 77, 84,
+  82, 81, 81, 85, 90, 87, 84, 89, 70, 85,
+  81, 75, 78, 66, 69, 87, 74, 82, 77, 84,
+  84, 91, 77, 82, 89, 81, 83, 74, 78, 86,
+  90, 82, 91, 77, 78, 95, 88, 94, 71, 89,
+  86, 93, 81, 72, 81, 87, 91, 92, 88, 77,
+  80, 94, 115, 90, 82, 78, 94, 91, 83, 88,
+  63, 83, 75, 81, 84, 66, 99, 76, 84, 90,
+  80, 82, 91, 91, 99, 79, 72, 81, 89, 80,
+  65, 80, 71, 91, 74, 84, 91, 81, 96, 70,
+  81, 94, 79, 86, 88, 91, 83, 72, 62, 74,
+  67, 80, 81, 92, 81, 62, 91, 78, 89, 91,
+  72, 87, 89, 104, 77, 82, 86, 76, 79, 78,
+  88, 81, 93, 82, 80, 77, 91, 75, 74, 82,
+  92, 73, 84, 76, 93, 88, 56, 75, 86, 79,
+  83, 96, 86, 86, 68, 77, 77, 82, 83, 81,
+  81, 93, 85, 83, 78, 91, 86, 78, 96, 88,
+  76, 77, 87, 88, 79, 90, 87, 95, 75, 81,
+  69, 74, 96, 86, 93, 104, 110, 75, 77, 99,
+  131, 97, 83, 81, 97, 71, 74, 89, 67, 70,
+  83, 86, 76, 67, 115, 79, 75, 87, 68, 73,
+  94, 94, 82, 79, 65, 82, 98, 85, 59, 79,
+  62, 76, 57, 77, 95, 78, 109, 68, 75, 79,
+  85, 75, 73, 93, 87, 64, 53, 81, 58, 77,
+  81, 101, 72, 63, 77, 59, 98, 96, 64, 80,
+  90, 93, 76, 78, 83, 75, 83, 86, 86, 82,
+  84, 79, 74, 77, 95, 73, 60, 74, 95, 70,
+  91, 72, 76, 88, 57, 71, 90, 82, 72, 112,
+  94, 95, 70, 74, 85, 79, 91, 81, 91, 88,
+  83, 79, 69, 87, 89, 78, 86, 96, 67, 76,
+  95, 84, 81, 78, 102, 84, 92, 97, 83, 73,
+  78, 84, 90, 80, 82, 98, 84, 95, 104, 81,
+  81, 79, 84, 97, 90, 89, 87, 84, 71, 81,
+  81, 86, 99, 87, 87, 93, 78, 98, 104, 89,
+  83, 77, 79, 83, 93, 81, 72, 85, 86, 102,
+  85, 85, 88, 84, 91, 74, 81, 64, 81, 84,
+  86, 83, 82, 74, 67, 73, 69, 83, 84, 84,
+  85, 65, 85, 83, 93, 86, 71, 81, 86, 87,
+  78, 86, 90, 86, 78, 91, 85, 82, 79, 90,
+  82, 75, 84, 71, 83, 77, 81, 77, 89, 74,
+  71, 91, 65, 80, 84, 81, 81, 92, 78, 82,
+  67, 75, 88, 84, 75, 89, 91, 89, 90, 82,
+  84, 90, 83, 80, 100, 81, 85, 74, 82, 86,
+  81, 88, 79, 86, 89, 78, 69, 80, 73, 74,
+  84, 77, 74, 96, 69, 89, 106, 59, 73, 72,
+  83, 86, 74, 82, 63, 76, 75, 79, 95, 68,
+  96, 91, 80, 86, 108, 92, 100, 96, 112, 77,
+  89, 61, 86, 64, 74, 77, 88, 77, 99, 76,
+  113, 78, 84, 84, 75, 81, 66, 100, 86, 89,
+  81, 93, 93, 80, 62, 85, 82, 88, 103, 85,
+  94, 91, 89, 79, 68, 81, 96, 92, 95, 95,
+  81, 93, 73, 89, 72, 97, 92, 87, 82, 77,
+  88, 101, 85, 79, 91, 86, 91, 83, 83, 99,
+  77, 97, 78, 87, 91, 94, 87, 53, 71, 73,
+  87, 80, 75, 78, 88, 104, 66, 85, 100, 91,
+  76, 89, 78, 79, 84, 95, 82, 76, 68, 77,
+  90, 79, 86, 74, 63, 73, 67, 71, 90, 81,
+  83, 123, 74, 68, 109, 56, 66, 68, 81, 84,
+  85, 77, 72, 72, 70, 77, 104, 94, 102, 81,
+  79, 87, 91, 83, 105, 89, 107, 74, 101, 61,
+  80, 68, 77, 67, 88, 74, 96, 75, 128, 86,
+  83, 85, 69, 101, 61, 93, 92, 94, 77, 91,
+  93, 85, 56, 102, 86, 105, 105, 90, 83, 91,
+  79, 74, 71, 80, 97, 85, 98, 102, 79, 99,
+  61, 83, 73, 102, 84, 90, 78, 69, 74, 90,
+  86, 73, 89, 94, 87, 83, 85, 108, 79, 95,
+  74, 91, 92, 114, 98, 60, 71, 67, 91, 74,
+  72, 78, 97, 115, 77, 90, 103, 91, 82, 84,
+  70, 78, 83, 91, 76, 77, 78, 68, 93, 85,
+  95, 78, 70, 77, 72, 80, 81, 67, 74, 111,
+  74, 87, 99, 65, 75, 72, 86, 78, 98, 82,
+  77, 79, 79, 80, 90, 108, 91, 87, 79, 85,
+  79, 95, 98, 97, 94, 74, 89, 71, 84, 72,
+  82, 77, 90, 93, 108, 77, 105, 69, 85, 82,
+  78, 87, 73, 89, 82, 81, 80, 89, 94, 82,
+  66, 84, 89, 81, 93, 80, 80, 90, 89, 85,
+  74, 80, 91, 87, 84, 92, 84, 88, 69, 87,
+  74, 103, 79, 89, 78, 75, 85, 78, 90, 79,
+  88, 86, 93, 86, 77, 89, 78, 86, 79, 85,
+  92, 91, 79, 63, 73, 77, 87, 84, 76, 89,
+  77, 89, 99, 83, 103, 89, 93, 83, 81, 77,
+  85, 90, 85, 75, 81, 70, 93, 72, 90, 79,
+  87, 82, 84, 82, 80, 72, 83, 94, 75, 91,
+  78, 69, 63, 76, 78, 106, 97, 102, 78, 76,
+  71, 81, 96, 86, 84, 88, 92, 69, 83, 95,
+  87, 85, 96, 90, 79, 104, 81, 71, 78, 91,
+  97, 88, 84, 88, 80, 83, 82, 80, 79, 86,
+  97, 71, 89, 81, 72, 153, 81, 115, 46, 98,
+  72, 74, 102, 79, 108, 87, 80, 74, 74, 83,
+  96, 81, 87, 99, 83, 76, 93, 71, 83, 70,
+  73, 74, 88, 81, 80, 77, 93, 79, 75, 91,
+  70, 71, 86, 106, 73, 79, 82, 84, 78, 74,
+  72, 71, 70, 82, 84, 70, 73, 73, 88, 87,
+  74, 91, 90, 90, 85, 75, 80, 78, 78, 98,
+  71, 91, 86, 69, 80, 93, 88, 66, 82, 83,
+  75, 80, 85, 81, 90, 106, 76, 86, 83, 83,
+  80, 72, 116, 109, 89, 92, 80, 92, 72, 84,
+  93, 76, 88, 85, 91, 91, 84, 73, 73, 94,
+  69, 85, 82, 92, 75, 87, 79, 89, 81, 82,
+  80, 87, 73, 100, 83, 83, 79, 73, 80, 70,
+  87, 93, 72, 97, 90, 87, 74, 79, 78, 83,
+  91, 89, 64, 85, 73, 81, 83, 68, 83, 88,
+  80, 80, 87, 83, 83, 78, 87, 74, 84, 79,
+  73, 89, 77, 75, 87, 85, 69, 89, 87, 71,
+  88, 74, 80, 69, 84, 83, 92, 71, 91, 98,
+  86, 83, 94, 82, 88, 85, 92, 92, 101, 86,
+  84, 93, 84, 81, 92, 82, 77, 93, 83, 80,
+  80, 78, 76, 104, 91, 81, 92, 88, 80, 89,
+  94, 92, 90, 76, 90, 85, 92, 101, 98, 98,
+  82, 74, 77, 80, 95, 99, 87, 95, 90, 79,
+  83, 89, 97, 88, 89, 74, 86, 95, 82, 75,
+  75, 61, 100, 107, 82, 89, 79, 71, 71, 78,
+  89, 89, 79, 90, 83, 85, 72, 90, 74, 93,
+  73, 67, 93, 73, 103, 71, 77, 94, 72, 97,
+  87, 70, 81, 92, 87, 72, 68, 88, 93, 74,
+  101, 92, 76, 76, 88, 84, 88, 82, 85, 93,
+  68, 86, 72, 80, 80, 95, 91, 88, 73, 66,
+  101, 93, 87, 82, 105, 75, 108, 101, 95, 97,
+  87, 83, 109, 96, 86, 82, 87, 84, 74, 94,
+  84, 90, 87, 91, 86, 96, 95, 84, 85, 80,
+  86, 70, 80, 88, 84, 84, 80, 82, 87, 70,
+  71, 89, 75, 72, 70, 65, 67, 79, 79, 109,
+  98, 94, 81, 86, 67, 80, 90, 73, 82, 87,
+  83, 70, 66, 96, 105, 85, 103, 75, 81, 104,
+  94, 72, 89, 76, 74, 100, 87, 85, 81, 86,
+  82, 82, 87, 97, 98, 75, 95, 82, 82, 133,
+  95, 115, 47, 103, 71, 72, 89, 81, 92, 91,
+  87, 86, 72, 87, 92, 76, 73, 99, 82, 66,
+  88, 78, 85, 81, 68, 82, 83, 75, 79, 76,
+  92, 76, 68, 92, 77, 71, 72, 111, 78, 93,
+  93, 83, 71, 81, 80, 71, 73, 77, 82, 63,
+  71, 66, 78, 81, 82, 84, 93, 97, 75, 72,
+  78, 79, 81, 79, 72, 93, 85, 64, 61, 91,
+  86, 74, 85, 80, 88, 80, 83, 77, 80, 70,
+  79, 89, 80, 75, 78, 73, 104, 90, 74, 91,
+  80, 91, 71, 79, 93, 71, 77, 88, 92, 89,
+  89, 77, 84, 88, 94, 84, 79, 82, 66, 81,
+  83, 92, 78, 85, 79, 86, 79, 73, 90, 83,
+  82, 110, 81, 78, 91, 87, 75, 101, 88, 89,
+  67, 89, 73, 81, 100, 77, 100, 86, 70, 72,
+  80, 79, 91, 92, 75, 83, 80, 81, 87, 73,
+  85, 77, 79, 79, 73, 89, 79, 86, 87, 83,
+  68, 87, 81, 74, 101, 84, 79, 78, 78, 83,
+  81, 81, 89, 90, 82, 85, 79, 78, 76, 82,
+  74, 90, 77, 84, 85, 77, 83, 78, 90, 79,
+  82, 79, 80, 81, 73, 78, 100, 107, 93, 73,
+  90, 75, 79, 93, 87, 90, 84, 86, 91, 96,
+  92, 96, 94, 94, 73, 77, 79, 86, 86, 98,
+  81, 91, 82, 91, 89, 88, 96, 87, 85, 67,
+  92, 101, 70, 81, 82, 67, 81, 95, 75, 86,
+  83, 75, 71, 81, 79, 81, 86, 91, 83, 90,
+  69, 97, 83, 87, 70, 75, 81, 80, 94, 83,
+  81, 88, 81, 97, 67, 73, 68, 74, 86, 73,
+  75, 78, 88, 76, 96, 92, 80, 81, 85, 85,
+  84, 79, 86, 95, 72, 83, 74, 83, 73, 83,
+  84, 87, 84, 62, 93, 76, 78, 82, 103, 86,
+  100, 97, 91, 99, 85, 79, 98, 93, 90, 88,
+  80, 84, 81, 76, 84, 87, 87, 87, 88, 90,
+  95, 86, 89, 95, 97, 95, 84, 87, 86, 101,
+  75, 87, 80, 72, 79, 87, 82, 82, 85, 90,
+  86, 97, 84, 98, 97, 89, 97, 108, 81, 91,
+  77, 76, 93, 79, 84, 83, 77, 82, 90, 97,
+  88, 75, 79, 92, 90, 86, 87, 61, 86, 97,
+  83, 82, 91, 86, 81, 93, 84, 71, 82, 88,
+  79, 103, 88, 75, 86, 92, 66, 72, 79, 80,
+  90, 92, 68, 83, 85, 95, 84, 82, 83, 81,
+  74, 83, 87, 85, 74, 90, 90, 87, 85, 88,
+  87, 78, 78, 88, 88, 86, 81, 80, 81, 76,
+  70, 69, 89, 82, 90, 82, 93, 72, 97, 83,
+  90, 98, 80, 80, 88, 72, 76, 79, 91, 81,
+  98, 82, 82, 94, 105, 89, 91, 82, 86, 91,
+  89, 73, 68, 84, 81, 87, 86, 85, 79, 87,
+  82, 75, 82, 73, 83, 74, 76, 74, 80, 85,
+  75, 93, 80, 92, 90, 93, 83, 84, 81, 69,
+  82, 95, 82, 78, 85, 87, 88, 83, 98, 87,
+  79, 99, 98, 78, 88, 76, 76, 86, 89, 81,
+  88, 79, 87, 82, 81, 85, 87, 81, 87, 84,
+  85, 100, 90, 96, 68, 86, 77, 76, 90, 84,
+  111, 95, 82, 84, 74, 88, 90, 86, 78, 90,
+  78, 86, 82, 79, 88, 80, 79, 86, 86, 83,
+  82, 89, 101, 76, 73, 88, 79, 80, 72, 86,
+  81, 106, 88, 85, 81, 78, 86, 80, 82, 91,
+  75, 77, 77, 72, 74, 91, 74, 88, 93, 88,
+  81, 79, 88, 78, 85, 78, 82, 89, 84, 64,
+  78, 88, 86, 81, 86, 71, 73, 93, 87, 82,
+  86, 86, 86, 83, 79, 79, 83, 86, 80, 85,
+  85, 99, 82, 84, 85, 88, 74, 79, 90, 90,
+  85, 80, 83, 74, 80, 84, 79, 87, 79, 89,
+  83, 82, 80, 80, 76, 75, 92, 82, 78, 83,
+  90, 72, 85, 93, 86, 88, 92, 83, 79, 92,
+  90, 87, 84, 84, 86, 84, 90, 94, 82, 95,
+  82, 76, 78, 85, 90, 85, 90, 87, 81, 94,
+  85, 79, 83, 79, 81, 84, 90, 88, 79, 87,
+  95, 74, 73, 94, 76, 82, 91, 73, 83, 84,
+  82, 84, 90, 81, 86, 81, 76, 96, 76, 74,
+  84, 81, 83, 108, 86, 90, 85, 92, 84, 79,
+  79, 79, 84, 86, 85, 93, 87, 88, 78, 86,
+  73, 90, 76, 65, 69, 73, 79, 74, 87, 78,
+  75, 92, 75, 96, 88, 87, 103, 85, 75, 77,
+  70, 89, 61, 105, 98, 78, 90, 74, 73, 74,
+  66, 71, 81, 88, 90, 76, 59, 55, 89, 88,
+  117, 73, 82, 102, 86, 95, 80, 75, 91, 83,
+  87, 76, 73, 77, 83, 82, 95, 70, 75, 81,
+  80, 82, 76, 86, 67, 92, 72, 72, 101, 95,
+  91, 84, 71, 83, 89, 71, 81, 82, 93, 89,
+  89, 95, 88, 103, 91, 104, 100, 78, 63, 73,
+  80, 102, 78, 97, 66, 85, 92, 74, 79, 76,
+  87, 94, 79, 93, 74, 84, 113, 96, 90, 76,
+  73, 77, 89, 92, 80, 119, 100, 86, 87, 72,
+  93, 85, 86, 89, 85, 91, 68, 87, 75, 86,
+  76, 69, 70, 73, 76, 77, 86, 83, 75, 87,
+  70, 93, 83, 86, 90, 85, 80, 77, 73, 89,
+  55, 105, 100, 72, 91, 68, 73, 72, 71, 78,
+  85, 86, 85, 75, 62, 67, 94, 86, 120, 71,
+  85, 98, 85, 99, 83, 73, 90, 84, 89, 76,
+  71, 75, 94, 82, 100, 74, 79, 84, 69, 88,
+  74, 85, 72, 85, 74, 75, 97, 85, 92, 77,
+  73, 85, 82, 69, 82, 84, 94, 80, 86, 93,
+  85, 97, 89, 98, 92, 78, 75, 75, 79, 103,
+  80, 97, 70, 81, 88, 77, 77, 77, 87, 95,
+  71, 91, 69, 90, 109, 99, 92, 79, 72, 82,
+  75, 93, 88, 112, 97, 87, 72, 76, 89, 86,
+  85, 92, 85, 91, 71, 82, 69, 83, 75, 79,
+  73, 75, 77, 73, 80, 88, 77, 96, 79, 90,
+  82, 93, 79, 78, 85, 76, 75, 94, 68, 99,
+  89, 68, 87, 72, 73, 70, 78, 86, 86, 85,
+  75, 74, 66, 61, 105, 86, 110, 75, 86, 88,
+  88, 91, 88, 76, 86, 80, 83, 82, 71, 88,
+  80, 84, 97, 73, 79, 76, 85, 85, 82, 83,
+  75, 80, 85, 72, 100, 90, 91, 85, 77, 83,
+  90, 75, 81, 84, 93, 86, 86, 90, 81, 92,
+  91, 100, 96, 85, 64, 77, 86, 97, 77, 104,
+  71, 93, 97, 83, 76, 76, 90, 91, 73, 92,
+  71, 86, 104, 92, 85, 84, 76, 79, 81, 89,
+  86, 114, 94, 87, 78, 73, 89, 89, 83, 88,
+  85, 82, 75, 89, 86, 84, 81, 71, 77, 74,
+  88, 79, 90, 77, 89, 101, 77, 93, 76, 83,
+  116, 82, 75, 79, 78, 77, 56, 102, 96, 81,
+  93, 70, 81, 79, 71, 75, 71, 90, 96, 70,
+  62, 69, 118, 93, 109, 84, 72, 105, 76, 88,
+  91, 72, 87, 86, 80, 86, 66, 82, 83, 86,
+  94, 66, 72, 75, 77, 76, 83, 81, 63, 68,
+  86, 71, 91, 113, 97, 73, 74, 88, 81, 70,
+  89, 84, 93, 83, 84, 93, 89, 95, 84, 98,
+  89, 63, 72, 80, 73, 94, 91, 90, 69, 75,
+  80, 83, 77, 72, 93, 84, 78, 86, 55, 84,
+  93, 89, 89, 82, 73, 78, 75, 90, 82, 101,
+  90, 82, 74, 77, 87, 93, 89, 85, 82, 94,
+  72, 91, 91, 83, 82, 72, 78, 76, 84, 79,
+  92, 88, 85, 105, 68, 88, 71, 86, 115, 81,
+  74, 78, 75, 75, 54, 102, 93, 77, 96, 70,
+  80, 78, 74, 80, 71, 81, 88, 65, 67, 76,
+  126, 91, 112, 83, 73, 95, 73, 89, 92, 70,
+  82, 86, 77, 77, 63, 76, 87, 84, 103, 72,
+  77, 76, 68, 77, 74, 77, 68, 65, 74, 64,
+  88, 104, 99, 60, 75, 91, 80, 67, 91, 85,
+  96, 82, 81, 92, 89, 87, 80, 99, 87, 62,
+  73, 78, 73, 95, 87, 90, 74, 65, 79, 77,
+  77, 73, 102, 78, 70, 85, 58, 90, 97, 93,
+  86, 83, 74, 79, 74, 86, 86, 98, 88, 87,
+  55, 79, 80, 93, 89, 87, 85, 96, 76, 83,
+  81, 89, 78, 78, 74, 76, 85, 80, 82, 96,
+  87, 99, 81, 87, 77, 87, 92, 82, 80, 80,
+  78, 78, 66, 96, 89, 75, 89, 72, 77, 75,
+  83, 86, 72, 88, 79, 72, 70, 72, 111, 90,
+  103, 79, 76, 86, 80, 88, 91, 82, 83, 85,
+  84, 76, 71, 90, 80, 84, 95, 73, 78, 70,
+  80, 80, 85, 80, 72, 75, 77, 74, 87, 95,
+  94, 82, 79, 89, 82, 72, 88, 81, 92, 88,
+  85, 86, 90, 92, 82, 92, 88, 70, 72, 80,
+  83, 92, 90, 94, 73, 85, 82, 87, 78, 73,
+  92, 88, 71, 84, 61, 82, 97, 90, 84, 86,
+  85, 85, 91, 87, 87, 100, 82, 84, 70, 78,
+  86, 90, 89, 87, 80, 76, 84, 85, 78, 83,
+  78, 78, 80, 73, 90, 94, 92, 88, 95, 96,
+  81, 86, 81, 85, 120, 84, 75, 81, 83, 74,
+  79, 88, 88, 74, 93, 73, 76, 83, 75, 86,
+  82, 78, 92, 76, 68, 73, 121, 94, 109, 92,
+  77, 101, 72, 85, 92, 71, 90, 88, 87, 100,
+  78, 77, 83, 89, 94, 71, 71, 79, 84, 73,
+  86, 83, 67, 79, 93, 86, 92, 121, 90, 78,
+  81, 89, 82, 77, 88, 87, 101, 80, 81, 91,
+  92, 92, 85, 97, 79, 72, 70, 76, 78, 104,
+  93, 86, 79, 86, 74, 96, 78, 75, 90, 102,
+  80, 80, 52, 83, 98, 85, 88, 89, 85, 81,
+  75, 91, 89, 98, 94, 82, 74, 80, 83, 87,
+  86, 76, 78, 84, 78, 87, 79, 81, 81, 76,
+  80, 77, 91, 86, 95, 95, 98, 96, 77, 82,
+  81, 83, 120, 86, 73, 84, 84, 73, 80, 91,
+  80, 75, 96, 76, 72, 83, 74, 84, 81, 71,
+  90, 75, 64, 77, 126, 90, 107, 99, 78, 98,
+  69, 84, 94, 72, 83, 84, 80, 90, 74, 76,
+  85, 89, 103, 71, 75, 81, 77, 72, 85, 83,
+  67, 78, 83, 81, 90, 120, 94, 69, 82, 89,
+  81, 79, 88, 86, 100, 87, 80, 92, 90, 85,
+  83, 94, 83, 69, 69, 75, 73, 96, 85, 88,
+  88, 77, 73, 87, 81, 77, 101, 98, 70, 81,
+  50, 86, 99, 88, 81, 84, 88, 85, 84, 88,
+  96, 96, 91, 82, 59, 82, 80, 84, 86, 83,
+  77, 90, 79, 83, 76, 86, 74, 80, 82, 78,
+  87, 93, 87, 92, 90, 96, 88, 83, 83, 80,
+  101, 79, 81, 83, 85, 77, 83, 82, 80, 82,
+  86, 78, 79, 83, 81, 85, 81, 81, 83, 77,
+  65, 72, 108, 91, 103, 87, 79, 87, 75, 89,
+  90, 79, 87, 85, 88, 86, 80, 87, 80, 87,
+  97, 74, 82, 73, 80, 75, 89, 83, 72, 90,
+  77, 84, 88, 107, 90, 85, 83, 90, 79, 77,
+  90, 83, 94, 93, 80, 85, 94, 93, 85, 96,
+  80, 72, 72, 81, 84, 99, 89, 87, 83, 89,
+  78, 85, 76, 75, 89, 96, 78, 81, 58, 84,
+  98, 84, 84, 88, 96, 87, 98, 92, 94, 95,
+  80, 83, 74, 83, 83, 81, 86, 79, 87, 89,
+  66, 77, 75, 94, 93, 76, 85, 90, 75, 78,
+  87, 86, 86, 87, 80, 86, 65, 80, 104, 78,
+  95, 107, 69, 94, 80, 85, 89, 81, 89, 77,
+  84, 82, 80, 83, 83, 92, 97, 84, 93, 103,
+  71, 87, 116, 84, 61, 88, 82, 92, 79, 76,
+  86, 75, 78, 79, 99, 91, 86, 76, 83, 85,
+  97, 89, 89, 96, 77, 84, 72, 87, 85, 83,
+  101, 94, 82, 89, 87, 92, 79, 82, 94, 83,
+  81, 94, 79, 80, 77, 79, 93, 83, 76, 88,
+  99, 76, 82, 93, 62, 80, 84, 91, 90, 85,
+  74, 82, 87, 90, 89, 87, 69, 94, 93, 91,
+  87, 73, 80, 92, 70, 94, 89, 96, 90, 88,
+  73, 84, 85, 84, 91, 90, 86, 90, 67, 77,
+  83, 63, 83, 91, 85, 87, 87, 78, 77, 85,
+  90, 80, 86, 83, 84, 81, 103, 78, 94, 99,
+  76, 92, 83, 85, 74, 89, 91, 73, 73, 83,
+  80, 78, 86, 83, 97, 84, 82, 82, 38, 79,
+  89, 78, 72, 88, 92, 90, 79, 82, 82, 86,
+  77, 76, 81, 92, 66, 88, 92, 87, 85, 104,
+  74, 96, 81, 82, 93, 69, 68, 81, 85, 80,
+  84, 75, 90, 87, 82, 86, 88, 90, 81, 92,
+  83, 92, 76, 82, 88, 84, 80, 74, 77, 80,
+  84, 73, 81, 88, 85, 88, 79, 79, 83, 85,
+  86, 88, 82, 84, 80, 90, 91, 84, 86, 71,
+  83, 78, 79, 88, 84, 82, 87, 88, 70, 84,
+  78, 90, 92, 89, 84, 93, 83, 81, 91, 70,
+  72, 106, 81, 84, 94, 85, 72, 93, 79, 76,
+  86, 92, 100, 89, 77, 68, 89, 91, 86, 78,
+  91, 87, 81, 80, 92, 83, 64, 79, 99, 100,
+  86, 72, 95, 73, 78, 64, 40, 76, 59, 77,
+  107, 83, 88, 91, 75, 87, 82, 104, 81, 81,
+  75, 94, 68, 95, 98, 88, 84, 87, 75, 80,
+  80, 77, 119, 80, 76, 73, 71, 73, 91, 73,
+  91, 99, 97, 79, 88, 89, 89, 90, 94, 95,
+  78, 94, 86, 77, 89, 76, 61, 79, 92, 63,
+  101, 87, 89, 83, 81, 77, 86, 81, 85, 89,
+  89, 79, 84, 83, 69, 89, 79, 81, 88, 81,
+  91, 79, 73, 69, 88, 92, 76, 84, 81, 98,
+  85, 81, 80, 79, 82, 82, 80, 89, 87, 94,
+  73, 87, 90, 80, 82, 90, 81, 88, 87, 96,
+  84, 75, 81, 72, 83, 88, 79, 96, 82, 95,
+  87, 88, 91, 82, 77, 68, 72, 87, 88, 83,
+  99, 76, 87, 89, 98, 80, 114, 78, 51, 77,
+  88, 86, 78, 79, 83, 90, 72, 75, 84, 77,
+  64, 74, 78, 84, 95, 78, 75, 90, 78, 86,
+  61, 75, 76, 72, 93, 103, 71, 78, 84, 99,
+  72, 91, 93, 77, 81, 96, 83, 79, 85, 83,
+  82, 81, 79, 80, 66, 83, 82, 92, 89, 92,
+  59, 95, 88, 82, 86, 85, 82, 75, 81, 94,
+  83, 88, 108, 89, 89, 80, 83, 92, 81, 84,
+  76, 92, 90, 89, 73, 89, 76, 84, 92, 92,
+  80, 77, 109, 80, 80, 78, 81, 91, 77, 87,
+  89, 83, 71, 89, 88, 80, 89, 76, 82, 74,
+  72, 85, 80, 91, 98, 86, 75, 86, 88, 90,
+  87, 92, 78, 72, 75, 89, 88, 76, 93, 69,
+  88, 75, 71, 83, 86, 84, 84, 77, 91, 84,
+  85, 79, 85, 91, 88, 72, 81, 72, 82, 85,
+  85, 90, 91, 80, 66, 82, 94, 83, 86, 66,
+  62, 81, 76, 79, 80, 80, 81, 95, 59, 85,
+  88, 86, 80, 91, 84, 92, 76, 81, 77, 83,
+  77, 66, 67, 77, 81, 71, 88, 88, 59, 88,
+  71, 69, 89, 83, 82, 95, 85, 89, 82, 81,
+  86, 74, 79, 81, 88, 90, 86, 83, 78, 76,
+  87, 82, 82, 81, 81, 86, 89, 82, 83, 83,
+  109, 83, 85, 85, 80, 83, 87, 83, 78, 80,
+  78, 93, 91, 80, 88, 82, 75, 86, 64, 87,
+  77, 94, 102, 66, 84, 80, 94, 78, 83, 93,
+  86, 80, 88, 90, 87, 77, 88, 69, 81, 74,
+  59, 86, 64, 87, 129, 85, 84, 92, 78, 86,
+  88, 86, 95, 87, 84, 85, 113, 89, 90, 94,
+  83, 81, 68, 79, 89, 76, 122, 69, 72, 84,
+  68, 68, 100, 82, 76, 87, 81, 75, 88, 92,
+  88, 81, 88, 92, 72, 87, 89, 82, 88, 80,
+  87, 73, 81, 67, 84, 92, 90, 80, 81, 76,
+  81, 79, 101, 104, 94, 83, 80, 80, 58, 81,
+  71, 80, 88, 86, 78, 88, 84, 66, 96, 86,
+  88, 74, 98, 90, 76, 76, 80, 80, 99, 83,
+  92, 90, 79, 98, 72, 83, 104, 85, 85, 88,
+  74, 82, 96, 101, 99, 76, 68, 69, 82, 82,
+  87, 90, 81, 95, 86, 78, 89, 91, 71, 75,
+  71, 95, 94, 74, 96, 81, 84, 77, 91, 76,
+  89, 74, 67, 80, 88, 84, 79, 82, 82, 106,
+  80, 85, 78, 75, 63, 84, 95, 83, 82, 70,
+  77, 80, 81, 77, 73, 80, 74, 74, 81, 86,
+  77, 76, 77, 101, 82, 96, 93, 78, 81, 84,
+  91, 86, 90, 91, 76, 75, 77, 86, 58, 84,
+  84, 86, 112, 98, 56, 89, 85, 92, 87, 83,
+  86, 73, 78, 90, 78, 81, 94, 83, 82, 85,
+  83, 84, 80, 79, 77, 75, 82, 91, 75, 86,
+  71, 98, 89, 94, 79, 71, 115, 81, 88, 98,
+  80, 84, 79, 87, 87, 89, 88, 91, 79, 83,
+  90, 87, 83, 73, 67, 98, 72, 83, 103, 82,
+  84, 81, 93, 74, 82, 99, 80, 78, 71, 100,
+  88, 74, 91, 77, 90, 84, 115, 88, 76, 90,
+  84, 75, 86, 85, 82, 86, 87, 91, 97, 89,
+  87, 71, 99, 75, 85, 93, 86, 65, 72, 72,
+  89, 75, 78, 81, 78, 77, 76, 79, 71, 81,
+  80, 102, 77, 86, 91, 77, 94, 79, 90, 88,
+  81, 86, 76, 80, 84, 72, 81, 76, 75, 80,
+  92, 87, 56, 83, 77, 82, 82, 82, 87, 84,
+  92, 90, 78, 76, 73, 79, 76, 92, 84, 87,
+  85, 85, 81, 80, 78, 84, 87, 76, 88, 88,
+  82, 80, 82, 77, 100, 83, 82, 97, 91, 73,
+  86, 91, 72, 87, 91, 90, 85, 84, 91, 81,
+  60, 82, 80, 89, 63, 92, 105, 68, 82, 74,
+  101, 79, 80, 94, 90, 81, 82, 89, 78, 89,
+  84, 81, 80, 84, 104, 99, 69, 99, 109, 77,
+  81, 98, 82, 76, 87, 69, 99, 91, 98, 83,
+  133, 76, 74, 101, 86, 72, 73, 77, 91, 83,
+  94, 82, 84, 89, 85, 80, 77, 90, 74, 91,
+  86, 79, 92, 84, 102, 82, 82, 91, 71, 82,
+  82, 86, 87, 80, 98, 73, 73, 79, 76, 90,
+  86, 88, 78, 82, 77, 85, 99, 89, 92, 85,
+  76, 80, 59, 83, 86, 86, 90, 92, 77, 99,
+  83, 85, 93, 82, 93, 75, 104, 81, 78, 73,
+  76, 71, 84, 83, 78, 85, 69, 94, 82, 83,
+  77, 92, 97, 91, 73, 65, 84, 94, 79, 99,
+  88, 94, 74, 82, 85, 74, 81, 76, 95, 99,
+  85, 76, 91, 65, 97, 80, 76, 79, 69, 77,
+  91, 64, 94, 62, 88, 92, 80, 80, 87, 82,
+  82, 76, 85, 77, 83, 99, 74, 97, 73, 74,
+  92, 76, 83, 85, 75, 85, 79, 90, 85, 83,
+  87, 92, 93, 94, 76, 94, 72, 78, 83, 75,
+  71, 85, 83, 81, 98, 74, 81, 74, 66, 79,
+  78, 77, 81, 95, 91, 90, 83, 84, 89, 75,
+  93, 87, 101, 97, 82, 85, 82, 91, 88, 89,
+  72, 80, 87, 77, 100, 74, 90, 74, 89, 83,
+  76, 98, 94, 78, 97, 87, 84, 66, 82, 81,
+  89, 81, 74, 81, 73, 98, 82, 86, 74, 91,
+  87, 77, 80, 59, 82, 98, 81, 92, 83, 92,
+  89, 83, 83, 64, 82, 78, 98, 96, 84, 81,
+  97, 58, 106, 66, 82, 84, 77, 67, 91, 61,
+  91, 64, 82, 87, 84, 82, 77, 85, 92, 75,
+  86, 74, 87, 90, 77, 86, 75, 68, 88, 81,
+  84, 78, 81, 83, 84, 85, 84, 86, 91, 86,
+  104, 94, 80, 88, 73, 76, 92, 72, 77, 86,
+  80, 96, 92, 69, 77, 83, 75, 78, 71, 83,
+  86, 88, 90, 87, 84, 72, 93, 77, 90, 71,
+  99, 93, 80, 87, 82, 94, 87, 94, 83, 86,
+  86, 80, 110, 84, 81, 75, 87, 81, 79, 95,
+  94, 80, 89, 85, 85, 73, 86, 88, 90, 83,
+  69, 81, 69, 93, 90, 79, 75, 86, 79, 72,
+  76, 70, 81, 92, 80, 94, 86, 93, 84, 85,
+  84, 76, 79, 74, 90, 76, 92, 79, 89, 72,
+  94, 73, 74, 77, 92, 82, 89, 66, 92, 70,
+  89, 93, 80, 85, 92, 85, 77, 79, 87, 81,
+  87, 73, 65, 92, 74, 77, 83, 78, 85, 79,
+  71, 89, 79, 85, 88, 82, 78, 94, 94, 86,
+  76, 90, 73, 74, 93, 79, 71, 92, 89, 80,
+  95, 78, 80, 85, 69, 75, 83, 77, 75, 95,
+  92, 89, 82, 89, 85, 87, 86, 82, 99, 93,
+  80, 87, 81, 78, 84, 91, 89, 77, 87, 84,
+  110, 81, 87, 74, 84, 85, 79, 95, 90, 80,
+  91, 79, 79, 72, 68, 71, 81, 77, 105, 87,
+  70, 75, 59, 84, 106, 75, 93, 64, 76, 69,
+  87, 77, 90, 144, 88, 87, 86, 75, 85, 59,
+  75, 82, 104, 92, 106, 74, 90, 99, 95, 57,
+  48, 81, 69, 64, 83, 80, 91, 77, 77, 73,
+  89, 79, 69, 72, 86, 73, 66, 74, 56, 113,
+  88, 134, 61, 91, 83, 74, 75, 74, 78, 64,
+  87, 72, 88, 80, 112, 87, 77, 89, 76, 86,
+  70, 81, 79, 78, 64, 64, 77, 79, 131, 81,
+  86, 83, 65, 85, 61, 80, 79, 76, 87, 83,
+  85, 74, 88, 76, 73, 93, 98, 102, 81, 83,
+  89, 138, 89, 76, 87, 97, 82, 76, 161, 67,
+  87, 77, 96, 75, 74, 99, 69, 64, 89, 80,
+  90, 67, 70, 98, 85, 73, 111, 82, 77, 72,
+  65, 85, 114, 78, 106, 65, 80, 78, 98, 77,
+  93, 162, 80, 87, 77, 78, 85, 56, 64, 78,
+  98, 76, 120, 78, 83, 84, 83, 55, 48, 78,
+  65, 58, 86, 96, 89, 96, 83, 67, 87, 74,
+  60, 62, 92, 67, 68, 79, 49, 124, 90, 150,
+  48, 76, 76, 71, 76, 79, 67, 70, 91, 76,
+  89, 72, 99, 81, 72, 78, 87, 72, 66, 69,
+  80, 84, 78, 69, 69, 51, 169, 83, 74, 90,
+  69, 80, 57, 72, 66, 70, 70, 97, 82, 68,
+  87, 79, 59, 79, 98, 98, 78, 77, 86, 147,
+  97, 69, 90, 94, 80, 75, 168, 66, 77, 72,
+  97, 71, 73, 99, 65, 60, 99, 77, 95, 51,
+  75, 100, 94, 81, 75, 99, 66, 80, 71, 82,
+  94, 75, 85, 82, 81, 74, 82, 80, 85, 140,
+  81, 90, 78, 83, 83, 68, 85, 86, 97, 84,
+  98, 79, 96, 69, 96, 76, 75, 81, 71, 72,
+  78, 79, 90, 66, 78, 76, 89, 95, 78, 87,
+  76, 86, 63, 77, 74, 92, 81, 106, 75, 90,
+  82, 76, 75, 61, 70, 72, 88, 79, 81, 91,
+  87, 96, 91, 85, 85, 92, 80, 78, 81, 78,
+  61, 69, 83, 60, 99, 90, 75, 87, 69, 83,
+  75, 88, 85, 82, 76, 78, 88, 76, 86, 83,
+  79, 85, 96, 100, 82, 84, 87, 109, 79, 90,
+  82, 85, 84, 87, 111, 84, 99, 75, 90, 85,
+  92, 105, 73, 68, 75, 79, 83, 88, 74, 81,
+  77, 84, 64, 89, 81, 83, 87, 86, 76, 99,
+  90, 76, 78, 87, 74, 83, 85, 96, 93, 91,
+  78, 99, 96, 64, 94, 82, 93, 87, 80, 88,
+  93, 91, 86, 85, 60, 87, 91, 77, 77, 61,
+  94, 64, 77, 99, 79, 91, 86, 90, 80, 80,
+  93, 89, 86, 79, 87, 78, 95, 81, 91, 85,
+  90, 81, 86, 74, 80, 76, 81, 78, 88, 83,
+  87, 78, 71, 87, 86, 82, 78, 73, 72, 88,
+  90, 75, 91, 86, 87, 78, 81, 98, 88, 84,
+  87, 82, 98, 74, 75, 80, 84, 91, 78, 95,
+  90, 91, 87, 82, 84, 82, 69, 94, 99, 79,
+  92, 91, 109, 92, 92, 82, 90, 77, 90, 89,
+  91, 76, 85, 94, 80, 67, 73, 93, 74, 82,
+  66, 82, 82, 79, 91, 89, 80, 98, 101, 93,
+  77, 90, 76, 86, 81, 94, 93, 88, 88, 102,
+  89, 57, 94, 84, 89, 88, 75, 85, 99, 91,
+  86, 76, 67, 83, 77, 67, 79, 57, 98, 68,
+  78, 86, 77, 84, 82, 89, 83, 89, 92, 85,
+  83, 95, 89, 80, 94, 78, 92, 86, 93, 75,
+  89, 75, 91, 76, 76, 90, 97, 77, 82, 76,
+  71, 83, 87, 79, 77, 70, 78, 84, 87, 84,
+  87, 90, 83, 76, 84, 101, 90, 80, 84, 74,
+  97, 69, 79, 71, 85, 93, 88, 95, 89, 88,
+  84, 93, 83, 94, 74, 94, 89, 83, 93, 81,
+  82, 94, 93, 78, 89, 83, 94, 90, 87, 73,
+  85, 92, 80, 72, 73, 92, 73, 84, 75, 79,
+  78, 81, 91, 85, 81, 94, 93, 97, 76, 90,
+  69, 80, 82, 98, 84, 94, 88, 95, 88, 71,
+  93, 82, 84, 86, 79, 85, 86, 86, 81, 87,
+  77, 85, 72, 84, 81, 63, 90, 73, 83, 83,
+  78, 84, 92, 87, 75, 86, 86, 96, 90, 89,
+  84, 85, 89, 83, 91, 89, 92, 77, 83, 84,
+  85, 86, 81, 80, 86, 89, 83, 77, 79, 86,
+  87, 74, 77, 74, 71, 82, 89, 75, 96, 91,
+  82, 71, 77, 95, 89, 80, 82, 81, 85, 70,
+  80, 84, 83, 94, 77, 82, 95, 90, 83, 83,
+  84, 81, 72, 91, 82, 77, 95, 80, 77, 88,
+  95, 77, 92, 82, 85, 93, 89, 76, 89, 91,
+  79, 73, 97, 78, 73, 89, 91, 86, 84, 87,
+  78, 86, 98, 82, 82, 96, 64, 68, 82, 83,
+  100, 76, 85, 84, 81, 83, 91, 70, 85, 107,
+  89, 79, 86, 79, 79, 70, 82, 93, 74, 69,
+  90, 73, 81, 81, 82, 75, 91, 97, 82, 75,
+  105, 86, 111, 72, 82, 81, 95, 81, 82, 72,
+  88, 72, 92, 81, 84, 85, 90, 106, 70, 83,
+  96, 82, 75, 76, 85, 73, 84, 88, 76, 93,
+  90, 95, 106, 80, 70, 81, 72, 81, 85, 75,
+  87, 98, 73, 74, 74, 72, 78, 90, 57, 95,
+  95, 85, 89, 78, 71, 77, 88, 96, 86, 68,
+  89, 95, 74, 80, 129, 84, 78, 103, 94, 87,
+  74, 71, 117, 79, 76, 110, 93, 91, 99, 83,
+  108, 91, 72, 91, 96, 73, 88, 81, 75, 84,
+  102, 74, 85, 94, 70, 71, 90, 80, 98, 71,
+  85, 83, 75, 91, 93, 73, 81, 106, 86, 82,
+  91, 85, 75, 63, 82, 81, 71, 69, 94, 61,
+  84, 86, 84, 77, 98, 100, 81, 73, 108, 81,
+  105, 76, 88, 79, 99, 84, 91, 73, 84, 65,
+  95, 84, 83, 84, 82, 111, 69, 84, 99, 75,
+  74, 76, 79, 72, 86, 86, 72, 80, 98, 96,
+  107, 82, 68, 86, 78, 73, 72, 70, 93, 113,
+  73, 68, 68, 78, 74, 96, 57, 95, 92, 82,
+  86, 83, 70, 77, 84, 104, 79, 67, 99, 90,
+  77, 79, 132, 75, 79, 106, 81, 93, 68, 70,
+  94, 79, 75, 108, 93, 86, 103, 80, 91, 92,
+  78, 94, 89, 81, 84, 82, 79, 85, 95, 86,
+  83, 87, 64, 73, 82, 83, 101, 77, 79, 86,
+  87, 81, 85, 71, 81, 105, 86, 84, 89, 86,
+  80, 77, 82, 93, 77, 68, 88, 77, 82, 81,
+  82, 79, 88, 100, 86, 90, 102, 86, 101, 72,
+  82, 81, 91, 84, 84, 68, 94, 71, 96, 84,
+  82, 81, 93, 104, 68, 90, 96, 79, 77, 74,
+  81, 72, 90, 86, 81, 75, 99, 92, 104, 79,
+  74, 102, 74, 76, 88, 80, 84, 104, 72, 74,
+  76, 74, 79, 90, 58, 92, 83, 82, 89, 89,
+  71, 77, 86, 89, 85, 71, 87, 92, 85, 79,
+  127, 94, 72, 96, 81, 90, 73, 74, 78, 80,
+  76, 105, 91, 85, 97, 86, 94, 79, 73, 84,
+  77, 87, 88, 93, 81, 80, 96, 77, 83, 91,
+  64, 71, 91, 84, 104, 75, 87, 82, 83, 83,
+  86, 74, 89, 97, 92, 80, 88, 81, 89, 76,
+  87, 90, 78, 69, 86, 70, 94, 86, 86, 80,
+  82, 94, 84, 77, 103, 85, 113, 77, 86, 82,
+  94, 88, 88, 64, 87, 70, 86, 83, 87, 88,
+  81, 104, 69, 78, 96, 75, 82, 77, 95, 78,
+  83, 78, 74, 87, 78, 107, 101, 83, 72, 77,
+  77, 87, 83, 73, 86, 81, 78, 76, 77, 72,
+  79, 100, 61, 93, 92, 97, 85, 81, 66, 78,
+  75, 80, 83, 73, 89, 97, 86, 88, 121, 73,
+  80, 96, 87, 92, 76, 80, 101, 81, 80, 113,
+  87, 75, 99, 89, 108, 88, 76, 82, 83, 77,
+  94, 86, 76, 76, 94, 73, 85, 89, 64, 68,
+  102, 79, 102, 70, 87, 84, 77, 87, 88, 77,
+  86, 91, 94, 88, 93, 83, 82, 72, 87, 82,
+  78, 68, 100, 62, 98, 94, 87, 83, 88, 97,
+  80, 73, 107, 78, 107, 82, 94, 82, 97, 92,
+  97, 64, 83, 62, 92, 88, 88, 86, 72, 111,
+  73, 73, 102, 76, 77, 75, 90, 74, 81, 68,
+  72, 82, 74, 114, 101, 88, 73, 76, 87, 88,
+  68, 69, 92, 82, 76, 67, 63, 77, 72, 109,
+  63, 93, 87, 96, 77, 77, 69, 79, 66, 87,
+  77, 72, 88, 91, 92, 89, 122, 66, 87, 98,
+  83, 93, 68, 84, 73, 81, 73, 108, 88, 68,
+  100, 85, 87, 90, 86, 89, 78, 83, 89, 87,
+  81, 83, 92, 78, 83, 82, 62, 74, 84, 81,
+  103, 73, 79, 81, 88, 81, 82, 76, 85, 100,
+  86, 95, 89, 88, 89, 79, 85, 93, 81, 68,
+  93, 76, 88, 84, 81, 82, 83, 97, 85, 82,
+  104, 88, 102, 77, 81, 80, 90, 79, 85, 67,
+  88, 74, 90, 77, 85, 82, 83, 102, 77, 82,
+  96, 81, 74, 79, 87, 79, 87, 79, 79, 81,
+  77, 101, 98, 83, 76, 99, 78, 88, 78, 78,
+  84, 91, 78, 72, 79, 78, 75, 96, 63, 89,
+  80, 94, 86, 77, 69, 79, 76, 77, 78, 74,
+  92, 95, 95, 86, 121, 87, 75, 91, 85, 93,
+  75, 83, 69, 87, 79, 108, 89, 77, 97, 92,
+  93, 77, 66, 91, 77, 84, 84, 97, 87, 78,
+  89, 78, 85, 86, 69, 74, 84, 81, 94, 81,
+  82, 92, 78, 80, 82, 80, 93, 89, 89, 83,
+  80, 78, 92, 71, 85, 86, 86, 81, 88, 66,
+  94, 90, 76, 84, 79, 91, 90, 83, 92, 93,
+  91, 77, 87, 82, 98, 84, 91, 62, 92, 71,
+  79, 81, 91, 87, 88, 99, 70, 84, 83, 87,
+  96, 73, 97, 78, 85, 80, 77, 92, 88, 85,
+  91, 65, 78, 75, 78, 80, 87, 87, 88, 71,
+  84, 89, 82, 81, 81, 78, 67, 76, 87, 89,
+  97, 85, 77, 79, 82, 77, 88, 83, 82, 90,
+  86, 89, 110, 80, 83, 94, 83, 85, 77, 73,
+  93, 76, 85, 109, 88, 77, 95, 83, 99, 79,
+  78, 87, 76, 79, 87, 94, 90, 77, 87, 81,
+  82, 90, 69, 74, 98, 83, 93, 75, 79, 89,
+  82, 81, 80, 79, 91, 85, 92, 85, 80, 81,
+  92, 69, 82, 81, 78, 75, 93, 58, 100, 90,
+  84, 83, 80, 91, 87, 77, 87, 91, 93, 75,
+  95, 81, 97, 80, 102, 62, 92, 65, 81, 87,
+  89, 83, 76, 98, 71, 78, 82, 83, 77, 68,
+  99, 75, 79, 76, 80, 86, 85, 89, 91, 69,
+  84, 83, 83, 81, 77, 81, 94, 75, 96, 85,
+  77, 85, 73, 78, 71, 80, 82, 88, 90, 74,
+  77, 81, 76, 81, 91, 79, 80, 90, 85, 89,
+  109, 75, 85, 94, 81, 82, 70, 75, 75, 80,
+  85, 105, 89, 74, 95, 78, 87, 80, 90, 90,
+  81, 78, 87, 89, 87, 84, 84, 80, 82, 86,
+  70, 77, 79, 78, 90, 72, 72, 94, 88, 82,
+  76, 80, 88, 92, 85, 93, 81, 81, 91, 79,
+  79, 92, 83, 79, 88, 73, 94, 92, 83, 82,
+  80, 91, 89, 80, 91, 96, 88, 79, 85, 83,
+  93, 77, 87, 66, 91, 72, 82, 85, 85, 88,
+  87, 96, 77, 83, 84, 94, 72, 74, 92, 83,
+  85, 80, 81, 79, 79, 86, 91, 68, 85, 102,
+  81, 83, 82, 87, 88, 80, 84, 81, 82, 80,
+  69, 81, 66, 74, 78, 87, 98, 79, 75, 80,
+  86, 79, 84, 81, 85, 91, 91, 88, 109, 88,
+  79, 92, 81, 85, 80, 77, 66, 76, 85, 101,
+  90, 81, 93, 84, 75, 66, 87, 71, 71, 71,
+  83, 83, 94, 95, 79, 71, 82, 67, 61, 72,
+  79, 116, 75, 72, 81, 85, 90, 86, 72, 78,
+  95, 88, 110, 72, 94, 78, 87, 72, 59, 80,
+  61, 81, 90, 82, 81, 85, 76, 71, 88, 74,
+  78, 80, 97, 87, 84, 62, 77, 77, 88, 66,
+  82, 63, 73, 78, 96, 90, 87, 97, 49, 74,
+  106, 125, 76, 124, 78, 81, 110, 73, 93, 79,
+  81, 57, 79, 68, 78, 62, 88, 109, 93, 86,
+  82, 94, 53, 101, 95, 91, 85, 84, 90, 82,
+  77, 84, 96, 65, 87, 85, 100, 98, 78, 106,
+  74, 82, 75, 86, 73, 149, 86, 84, 98, 105,
+  94, 76, 105, 78, 81, 66, 72, 76, 67, 84,
+  78, 77, 70, 74, 81, 71, 71, 85, 80, 87,
+  93, 100, 75, 89, 68, 79, 63, 71, 90, 119,
+  74, 77, 80, 85, 65, 84, 69, 77, 101, 88,
+  108, 65, 86, 82, 94, 74, 65, 92, 65, 80,
+  59, 68, 83, 74, 82, 76, 89, 74, 71, 88,
+  91, 87, 81, 61, 79, 77, 91, 61, 82, 59,
+  65, 74, 98, 88, 78, 96, 54, 69, 92, 136,
+  80, 109, 75, 70, 112, 75, 95, 72, 82, 62,
+  86, 59, 83, 60, 88, 75, 89, 80, 84, 94,
+  50, 100, 91, 122, 78, 83, 107, 86, 79, 82,
+  85, 66, 91, 126, 101, 97, 88, 109, 67, 79,
+  73, 83, 76, 151, 90, 82, 91, 88, 71, 73,
+  98, 71, 70, 66, 73, 72, 64, 85, 76, 74,
+  91, 81, 96, 72, 82, 82, 67, 104, 85, 92,
+  80, 84, 85, 88, 57, 81, 94, 100, 79, 77,
+  92, 87, 69, 78, 73, 82, 98, 83, 105, 71,
+  84, 84, 112, 77, 70, 90, 72, 88, 83, 96,
+  85, 76, 75, 77, 88, 97, 80, 85, 89, 90,
+  92, 92, 79, 75, 102, 78, 92, 62, 90, 71,
+  81, 93, 83, 75, 45, 88, 81, 105, 83, 74,
+  67, 74, 127, 81, 76, 81, 75, 75, 75, 80,
+  89, 71, 91, 80, 85, 82, 89, 81, 68, 88,
+  100, 118, 82, 88, 109, 83, 71, 82, 93, 78,
+  80, 92, 93, 87, 68, 101, 76, 88, 70, 95,
+  82, 104, 89, 88, 89, 99, 76, 77, 91, 72,
+  87, 77, 90, 88, 74, 75, 90, 98, 80, 80,
+  91, 88, 86, 80, 97, 76, 78, 85, 86, 75,
+  90, 77, 82, 75, 70, 80, 76, 74, 88, 85,
+  81, 87, 80, 79, 82, 91, 91, 84, 95, 79,
+  76, 98, 73, 85, 73, 79, 92, 91, 78, 76,
+  74, 85, 77, 75, 86, 83, 82, 77, 79, 86,
+  75, 91, 78, 87, 65, 82, 81, 82, 93, 79,
+  92, 95, 87, 61, 73, 69, 82, 108, 77, 97,
+  76, 77, 97, 68, 88, 69, 90, 80, 91, 73,
+  79, 89, 99, 86, 84, 98, 77, 82, 78, 68,
+  84, 88, 72, 69, 87, 99, 86, 84, 80, 75,
+  93, 88, 94, 84, 89, 84, 98, 84, 95, 100,
+  87, 81, 88, 102, 97, 79, 93, 99, 89, 71,
+  91, 82, 81, 88, 77, 72, 79, 95, 76, 87,
+  94, 77, 103, 71, 81, 87, 84, 89, 94, 93,
+  91, 80, 74, 77, 81, 73, 73, 84, 71, 91,
+  82, 82, 82, 99, 90, 61, 105, 73, 75, 99,
+  80, 82, 70, 75, 72, 89, 79, 77, 102, 90,
+  71, 69, 86, 79, 86, 81, 83, 84, 76, 98,
+  80, 94, 58, 86, 79, 89, 94, 73, 77, 95,
+  78, 58, 65, 63, 78, 80, 95, 96, 62, 74,
+  113, 63, 90, 87, 107, 72, 94, 83, 85, 58,
+  99, 85, 83, 91, 72, 94, 70, 76, 75, 94,
+  65, 71, 95, 105, 95, 81, 72, 88, 92, 91,
+  104, 80, 81, 82, 109, 85, 99, 96, 93, 84,
+  81, 90, 72, 81, 94, 93, 71, 66, 92, 77,
+  81, 86, 67, 70, 77, 92, 77, 78, 77, 103,
+  84, 83, 77, 99, 86, 82, 68, 101, 68, 69,
+  86, 88, 78, 90, 86, 79, 68, 82, 82, 81,
+  98, 93, 88, 73, 84, 74, 83, 79, 78, 98,
+  74, 80, 67, 75, 84, 78, 83, 79, 80, 85,
+  82, 97, 82, 78, 80, 75, 69, 78, 91, 72,
+  90, 74, 75, 74, 93, 97, 93, 85, 70, 67,
+  70, 99, 82, 86, 94, 81, 94, 86, 103, 82,
+  88, 88, 100, 77, 82, 66, 79, 63, 95, 77,
+  91, 84, 73, 90, 78, 104, 78, 86, 92, 75,
+  81, 93, 82, 76, 84, 120, 98, 92, 76, 91,
+  74, 76, 86, 81, 88, 114, 84, 86, 89, 88,
+  83, 77, 86, 76, 81, 69, 78, 80, 76, 73,
+  84, 79, 80, 84, 87, 86, 88, 91, 86, 84,
+  67, 85, 88, 90, 91, 80, 90, 72, 75, 82,
+  78, 80, 90, 91, 81, 86, 87, 81, 79, 80,
+  85, 88, 77, 80, 82, 98, 80, 90, 86, 85,
+  88, 93, 81, 66, 77, 86, 83, 77, 86, 79,
+  71, 74, 85, 107, 75, 90, 75, 84, 77, 77,
+  92, 80, 79, 89, 96, 87, 86, 74, 84, 79,
+  87, 85, 81, 91, 85, 76, 87, 71, 94, 83,
+  75, 86, 96, 80, 85, 85, 83, 82, 92, 80,
+  105, 81, 87, 78, 95, 97, 82, 77, 73, 92,
+  76, 92, 87, 78, 82, 75, 75, 85, 93, 89,
+  98, 90, 87, 80, 87, 81, 77, 85, 88, 81,
+  90, 101, 91, 87, 85, 87, 92, 79, 91, 83,
+  78, 89, 91, 86, 90, 81, 87, 79, 76, 81,
+  88, 99, 101, 89, 93, 77, 78, 84, 79, 79,
+  80, 90, 82, 93, 83, 76, 78, 84, 83, 77,
+  81, 83, 86, 92, 78, 86, 90, 92, 83, 96,
+  86, 72, 93, 88, 79, 76, 83, 74, 67, 80,
+  95, 108, 75, 92, 77, 85, 73, 73, 97, 78,
+  77, 86, 88, 86, 84, 74, 79, 76, 89, 82,
+  93, 90, 86, 78, 86, 76, 93, 89, 76, 90,
+  97, 86, 90, 80, 75, 83, 87, 81, 97, 89,
+  84, 77, 94, 96, 75, 74, 80, 98, 89, 99,
+  85, 80, 76, 76, 68, 84, 85, 89, 91, 95,
+  86, 75, 87, 89, 81, 76, 85, 82, 91, 98,
+  86, 83, 85, 84, 90, 76, 87, 84, 83, 108,
+  93, 83, 86, 98, 84, 86, 77, 85, 88, 86,
+  79, 98, 78, 72, 82, 85, 79, 80, 89, 81,
+  80, 87, 86, 85, 81, 85, 77, 72, 83, 83,
+  86, 85, 85, 96, 84, 82, 79, 83, 89, 78,
+  88, 78, 79, 84, 84, 88, 81, 76, 86, 85,
+  71, 82, 85, 86, 86, 82, 77, 76, 86, 91,
+  97, 93, 74, 76, 83, 84, 95, 76, 88, 82,
+  88, 77, 98, 81, 86, 90, 90, 83, 87, 78,
+  80, 70, 80, 79, 87, 80, 90, 88, 82, 80,
+  89, 95, 90, 74, 78, 96, 94, 81, 86, 92,
+  83, 80, 67, 87, 83, 79, 97, 90, 89, 84,
+  87, 91, 80, 81, 97, 80, 86, 82, 82, 77,
+  87, 86, 81, 81, 88, 85, 82, 79, 79, 105,
+  90, 79, 81, 71, 82, 70, 71, 90, 85, 82,
+  81, 80, 87, 93, 60, 81, 86, 81, 99, 77,
+  77, 65, 83, 116, 94, 79, 84, 85, 76, 85,
+  79, 82, 78, 79, 86, 82, 86, 82, 82, 85,
+  89, 75, 83, 94, 81, 82, 82, 78, 82, 94,
+  85, 90, 65, 83, 78, 83, 87, 104, 85, 88,
+  96, 75, 78, 92, 79, 97, 75, 88, 88, 84,
+  82, 77, 85, 86, 80, 82, 69, 83, 72, 93,
+  89, 82, 79, 79, 77, 77, 80, 88, 86, 77,
+  88, 81, 103, 90, 94, 82, 82, 81, 101, 90,
+  89, 92, 75, 105, 95, 80, 78, 81, 76, 77,
+  99, 90, 94, 77, 67, 78, 85, 75, 84, 71,
+  87, 80, 70, 99, 81, 87, 83, 114, 100, 92,
+  84, 63, 88, 60, 68, 82, 87, 82, 89, 87,
+  90, 94, 55, 83, 86, 74, 87, 79, 86, 65,
+  80, 129, 97, 85, 85, 95, 78, 83, 83, 84,
+  84, 69, 84, 84, 90, 85, 87, 89, 94, 74,
+  84, 83, 81, 83, 84, 76, 79, 96, 90, 85,
+  64, 79, 77, 80, 87, 98, 86, 81, 86, 67,
+  72, 89, 74, 97, 82, 90, 81, 85, 84, 75,
+  81, 87, 80, 90, 70, 80, 78, 77, 91, 81,
+  80, 83, 76, 88, 75, 87, 86, 80, 80, 90,
+  107, 89, 89, 81, 76, 87, 97, 90, 85, 90,
+  77, 110, 100, 85, 79, 89, 77, 75, 99, 88,
+  77, 72, 58, 83, 79, 75, 84, 78, 94, 76,
+  60, 102, 83, 92, 87, 103, 84, 95, 81, 72,
+  82, 73, 72, 89, 81, 82, 80, 84, 86, 86,
+  60, 83, 80, 74, 73, 78, 84, 71, 84, 114,
+  91, 77, 86, 91, 76, 77, 76, 91, 84, 81,
+  81, 84, 81, 85, 85, 83, 89, 79, 86, 82,
+  77, 79, 82, 77, 83, 91, 85, 83, 67, 88,
+  76, 84, 90, 101, 86, 90, 96, 75, 77, 90,
+  77, 91, 93, 85, 90, 85, 83, 81, 80, 89,
+  84, 85, 71, 84, 72, 83, 89, 80, 85, 77,
+  82, 86, 80, 96, 83, 78, 76, 80, 102, 92,
+  81, 87, 82, 98, 106, 89, 85, 89, 79, 100,
+  99, 82, 78, 82, 82, 79, 95, 85, 77, 79,
+  68, 78, 78, 74, 77, 74, 89, 79, 68, 95,
+  77, 75, 85, 118, 86, 88, 76, 75, 83, 67,
+  75, 81, 84, 84, 78, 94, 88, 86, 57, 81,
+  85, 77, 98, 77, 82, 66, 75, 132, 97, 89,
+  81, 86, 79, 80, 86, 80, 79, 86, 85, 77,
+  81, 85, 77, 89, 86, 75, 79, 101, 74, 81,
+  73, 84, 79, 94, 89, 93, 62, 93, 76, 84,
+  78, 99, 84, 84, 89, 73, 83, 86, 87, 86,
+  91, 81, 77, 80, 83, 72, 83, 81, 78, 76,
+  75, 95, 66, 80, 89, 80, 76, 85, 81, 71,
+  82, 87, 86, 79, 86, 83, 110, 89, 88, 87,
+  74, 79, 101, 85, 87, 93, 80, 106, 92, 72,
+  86, 86, 83, 83, 93, 87, 85, 80, 64, 81,
+  82, 75, 88, 73, 98, 79, 59, 99, 92, 90,
+  93, 123, 95, 88, 78, 78, 100, 58, 79, 76,
+  103, 80, 84, 105, 91, 82, 53, 80, 81, 68,
+  84, 86, 88, 70, 75, 148, 97, 83, 81, 99,
+  83, 74, 91, 74, 87, 82, 88, 87, 77, 107,
+  84, 86, 92, 66, 81, 86, 73, 83, 83, 85,
+  79, 97, 91, 93, 61, 90, 66, 75, 71, 88,
+  83, 98, 68, 76, 80, 72, 85, 73, 81, 86,
+  70, 87, 79, 70, 82, 90, 74, 93, 77, 100,
+  77, 72, 89, 83, 72, 85, 80, 76, 85, 82,
+  85, 74, 69, 88, 118, 85, 91, 92, 69, 74,
+  89, 82, 77, 92, 82, 112, 100, 79, 92, 82,
+  84, 66, 91, 85, 69, 77, 57, 81, 75, 74,
+  98, 86, 111, 72, 51, 107, 79, 92, 98, 116,
+  81, 98, 76, 74, 80, 71, 74, 83, 78, 81,
+  79, 91, 86, 83, 59, 91, 78, 77, 82, 77,
+  85, 72, 78, 126, 93, 76, 82, 90, 77, 73,
+  86, 89, 85, 86, 82, 80, 79, 85, 83, 84,
+  84, 75, 79, 82, 70, 77, 77, 79, 81, 91,
+  90, 88, 66, 94, 77, 85, 83, 96, 86, 84,
+  92, 73, 82, 87, 85, 90, 89, 81, 83, 81,
+  86, 74, 81, 93, 88, 79, 75, 94, 72, 84,
+  87, 80, 86, 82, 81, 82, 79, 89, 84, 79,
+  78, 83, 107, 90, 87, 91, 75, 88, 102, 85,
+  81, 92, 81, 99, 93, 73, 84, 85, 87, 75,
+  88, 84, 89, 84, 65, 81, 74, 76, 81, 72,
+  98, 80, 61, 92, 73, 75, 86, 121, 83, 82,
+  72, 75, 81, 74, 82, 85, 81, 78, 77, 91,
+  88, 82, 58, 85, 90, 77, 89, 76, 85, 78,
+  73, 114, 92, 82, 86, 89, 80, 88, 84, 84,
+  83, 101, 84, 85, 81, 87, 78, 82, 87, 91,
+  71, 96, 72, 85, 77, 79, 86, 90, 91, 91,
+  72, 87, 88, 78, 80, 89, 81, 83, 97, 82,
+  91, 87, 94, 79, 95, 92, 85, 84, 77, 83,
+  79, 86, 80, 84, 74, 84, 66, 79, 88, 85,
+  75, 75, 77, 76, 94, 83, 82, 83, 93, 75,
+  102, 87, 84, 101, 82, 81, 100, 84, 85, 94,
+  84, 95, 84, 65, 82, 85, 78, 94, 92, 85,
+  81, 87, 73, 94, 77, 74, 80, 66, 88, 84,
+  65, 94, 73, 83, 102, 124, 85, 90, 75, 74,
+  85, 73, 82, 79, 90, 80, 78, 92, 88, 85,
+  50, 89, 83, 67, 87, 79, 85, 83, 71, 130,
+  88, 77, 83, 97, 78, 87, 85, 82, 89, 115,
+  83, 90, 79, 86, 86, 81, 87, 80, 63, 91,
+  74, 84, 79, 81, 86, 91, 86, 90, 69, 73,
+  78, 71, 74, 88, 84, 78, 88, 77, 87, 82,
+  100, 88, 84, 95, 83, 87, 75, 79, 80, 96,
+  73, 94, 76, 83, 63, 78, 88, 85, 76, 82,
+  66, 74, 93, 88, 81, 83, 89, 78, 106, 84,
+  84, 102, 73, 80, 93, 83, 77, 101, 82, 99,
+  76, 67, 82, 83, 77, 79, 90, 88, 82, 91,
+  65, 88, 74, 74, 85, 63, 95, 81, 61, 90,
+  77, 83, 92, 117, 81, 89, 75, 78, 78, 76,
+  80, 88, 81, 84, 77, 86, 89, 83, 60, 86,
+  82, 76, 83, 75, 84, 80, 71, 109, 88, 76,
+  89, 90, 79, 90, 80, 87, 86, 98, 80, 84,
+  80, 83, 90, 82, 86, 84, 71, 88, 67, 83,
+  77, 79, 85, 87, 88, 86, 78, 86, 86, 80,
+  83, 84, 83, 84, 93, 84, 87, 86, 97, 85,
+  77, 87, 88, 85, 79, 84, 83, 95, 80, 81,
+  73, 83, 72, 78, 89, 77, 92, 77, 70, 80,
+  92, 92, 83, 86, 83, 74, 98, 89, 85, 96,
+  84, 81, 101, 85, 75, 91, 84, 88, 83, 70,
+  78, 83, 78, 77, 92, 83, 98, 89, 78, 92,
+  82, 77, 80, 69, 86, 88, 70, 90, 85, 76,
+  95, 78, 81, 92, 73, 91, 73, 81, 83, 83,
+  103, 78, 96, 73, 94, 82, 79, 113, 101, 88,
+  86, 86, 82, 78, 79, 83, 81, 80, 79, 79,
+  98, 67, 65, 86, 71, 74, 70, 97, 88, 80,
+  81, 74, 86, 78, 94, 83, 84, 64, 75, 98,
+  87, 80, 89, 77, 76, 80, 81, 124, 93, 76,
+  98, 89, 95, 88, 95, 81, 83, 87, 68, 87,
+  84, 96, 79, 77, 56, 87, 105, 75, 78, 78,
+  87, 90, 87, 72, 89, 85, 76, 89, 83, 94,
+  76, 87, 78, 75, 78, 70, 89, 83, 53, 46,
+  80, 126, 82, 83, 83, 97, 95, 90, 78, 86,
+  93, 92, 92, 80, 94, 80, 65, 94, 96, 88,
+  78, 82, 60, 98, 81, 80, 82, 77, 70, 76,
+  66, 75, 62, 82, 64, 82, 87, 76, 107, 76,
+  111, 52, 111, 80, 81, 121, 86, 63, 84, 79,
+  78, 75, 86, 82, 105, 80, 68, 81, 105, 70,
+  77, 64, 81, 76, 80, 77, 76, 88, 100, 60,
+  86, 64, 78, 79, 77, 65, 75, 70, 64, 79,
+  76, 83, 73, 72, 73, 139, 91, 75, 81, 91,
+  80, 82, 108, 112, 73, 83, 81, 90, 78, 98,
+  75, 70, 60, 63, 102, 71, 66, 68, 89, 102,
+  94, 68, 80, 87, 52, 69, 89, 110, 80, 89,
+  78, 79, 80, 58, 83, 85, 53, 92, 89, 119,
+  104, 76, 92, 104, 98, 85, 75, 86, 83, 81,
+  77, 85, 69, 88, 75, 77, 99, 104, 74, 69,
+  34, 91, 92, 102, 86, 105, 81, 85, 94, 78,
+  82, 87, 99, 84, 70, 92, 72, 74, 86, 83,
+  90, 92, 82, 76, 88, 87, 84, 91, 86, 81,
+  87, 82, 79, 69, 89, 76, 88, 89, 85, 88,
+  90, 77, 76, 97, 93, 87, 97, 95, 93, 81,
+  101, 95, 82, 71, 76, 103, 108, 85, 119, 89,
+  80, 79, 94, 88, 81, 89, 91, 64, 81, 92,
+  83, 75, 92, 87, 106, 84, 84, 83, 79, 82,
+  67, 85, 103, 83, 110, 71, 85, 85, 83, 77,
+  96, 81, 101, 80, 90, 92, 76, 91, 97, 80,
+  74, 81, 80, 85, 63, 64, 82, 115, 75, 91,
+  80, 91, 84, 94, 77, 79, 98, 88, 67, 81,
+  91, 78, 70, 92, 102, 65, 87, 98, 80, 87,
+  80, 85, 91, 57, 82, 77, 85, 80, 79, 88,
+  63, 84, 99, 69, 97, 62, 96, 77, 83, 72,
+  87, 111, 89, 83, 89, 81, 69, 88, 90, 88,
+  97, 70, 74, 82, 91, 83, 88, 87, 55, 82,
+  76, 86, 81, 83, 96, 69, 84, 78, 97, 86,
+  71, 65, 77, 81, 68, 84, 84, 91, 83, 81,
+  83, 148, 81, 87, 86, 89, 85, 75, 88, 81,
+  86, 63, 95, 107, 94, 84, 81, 81, 66, 86,
+  86, 86, 58, 71, 84, 103, 97, 77, 89, 83,
+  84, 103, 84, 88, 71, 82, 95, 82, 74, 56,
+  83, 79, 54, 87, 82, 120, 75, 79, 77, 100,
+  95, 92, 86, 78, 87, 87, 80, 77, 78, 85,
+  74, 80, 77, 106, 69, 73, 59, 79, 92, 73,
+  82, 76, 79, 78, 70, 72, 67, 76, 46, 88,
+  99, 67, 99, 77, 107, 65, 93, 65, 81, 138,
+  80, 68, 83, 74, 75, 87, 92, 86, 110, 104,
+  65, 86, 86, 77, 83, 75, 79, 95, 72, 69,
+  91, 89, 81, 55, 90, 55, 77, 74, 75, 72,
+  70, 50, 40, 85, 57, 71, 81, 72, 62, 162,
+  95, 81, 78, 97, 68, 67, 92, 102, 80, 64,
+  66, 128, 86, 74, 73, 76, 78, 69, 79, 81,
+  41, 68, 77, 95, 103, 92, 79, 89, 51, 93,
+  79, 90, 84, 75, 90, 85, 75, 44, 84, 85,
+  64, 79, 94, 114, 82, 69, 75, 108, 89, 86,
+  82, 74, 77, 80, 89, 85, 66, 97, 77, 78,
+  104, 120, 52, 63, 27, 70, 100, 94, 85, 107,
+  88, 86, 88, 89, 86, 86, 100, 84, 75, 85,
+  73, 91, 85, 91, 80, 94, 83, 68, 87, 103,
+  87, 85, 75, 78, 95, 87, 88, 74, 85, 81,
+  84, 77, 89, 85, 76, 82, 80, 95, 87, 88,
+  89, 89, 91, 80, 96, 76, 73, 74, 75, 104,
+  96, 83, 120, 74, 79, 72, 93, 91, 81, 90,
+  84, 53, 81, 87, 82, 70, 90, 82, 93, 89,
+  97, 86, 77, 80, 75, 81, 72, 94, 103, 65,
+  87, 90, 79, 83, 90, 83, 101, 76, 92, 84,
+  74, 81, 90, 81, 79, 75, 93, 76, 63, 46,
+  80, 111, 70, 88, 82, 85, 81, 92, 87, 83,
+  91, 88, 75, 95, 101, 78, 76, 88, 101, 73,
+  78, 90, 76, 85, 82, 84, 94, 68, 93, 93,
+  78, 90, 82, 89, 86, 93, 86, 86, 99, 80,
+  94, 88, 81, 87, 86, 80, 97, 78, 82, 92,
+  86, 85, 77, 85, 81, 81, 93, 92, 83, 78,
+  72, 87, 72, 87, 85, 87, 89, 68, 92, 97,
+  80, 97, 89, 93, 72, 89, 80, 101, 97, 93,
+  108, 88, 79, 83, 98, 96, 73, 91, 96, 85,
+  91, 78, 91, 83, 84, 85, 85, 76, 95, 90,
+  87, 82, 84, 83, 80, 74, 90, 94, 87, 82,
+  89, 85, 89, 82, 94, 108, 86, 97, 71, 74,
+  91, 71, 79, 84, 78, 80, 59, 108, 85, 109,
+  87, 89, 91, 78, 83, 89, 86, 77, 96, 83,
+  92, 95, 80, 84, 78, 84, 87, 81, 86, 86,
+  94, 87, 90, 68, 89, 83, 82, 93, 75, 77,
+  78, 79, 90, 88, 86, 84, 103, 95, 97, 90,
+  84, 91, 86, 74, 89, 82, 88, 99, 87, 75,
+  82, 90, 90, 86, 86, 81, 82, 70, 68, 67,
+  74, 84, 84, 84, 82, 72, 85, 88, 73, 101,
+  82, 69, 68, 98, 77, 100, 93, 92, 111, 91,
+  78, 88, 94, 78, 74, 87, 91, 82, 92, 76,
+  80, 71, 77, 93, 71, 69, 87, 87, 79, 79,
+  75, 77, 75, 67, 85, 88, 95, 87, 89, 87,
+  84, 82, 105, 119, 85, 95, 77, 62, 85, 66,
+  81, 73, 94, 83, 66, 101, 78, 105, 81, 96,
+  90, 81, 78, 88, 83, 79, 90, 86, 93, 98,
+  79, 80, 71, 89, 87, 83, 82, 81, 76, 81,
+  90, 78, 88, 101, 83, 90, 83, 83, 80, 87,
+  89, 94, 86, 89, 86, 85, 89, 96, 88, 82,
+  82, 80, 83, 84, 83, 87, 82, 79, 85, 78,
+  78, 80, 87, 81, 76, 83, 87, 92, 83, 85,
+  78, 89, 89, 79, 89, 99, 84, 85, 76, 87,
+  77, 79, 80, 85, 95, 90, 100, 82, 83, 84,
+  88, 97, 81, 89, 87, 72, 91, 88, 87, 89,
+  94, 83, 78, 82, 84, 84, 88, 82, 77, 87,
+  69, 85, 98, 82, 83, 92, 88, 84, 86, 84,
+  82, 99, 79, 98, 78, 79, 96, 78, 81, 89,
+  95, 75, 70, 88, 87, 103, 86, 83, 90, 86,
+  92, 77, 89, 79, 92, 89, 76, 94, 92, 84,
+  78, 86, 86, 81, 77, 89, 89, 87, 87, 73,
+  103, 83, 91, 88, 111, 80, 73, 88, 70, 89,
+  89, 85, 92, 90, 77, 69, 85, 82, 93, 102,
+  76, 79, 76, 73, 95, 92, 69, 79, 92, 87,
+  87, 87, 86, 86, 86, 94, 74, 71, 77, 92,
+  75, 76, 97, 71, 84, 75, 75, 83, 87, 74,
+  80, 70, 70, 95, 60, 87, 77, 89, 69, 98,
+  88, 88, 106, 68, 69, 79, 82, 105, 89, 81,
+  84, 93, 86, 79, 106, 76, 76, 75, 86, 87,
+  72, 88, 82, 74, 89, 71, 91, 96, 82, 81,
+  82, 88, 82, 102, 71, 107, 93, 94, 92, 89,
+  86, 93, 95, 90, 81, 74, 83, 91, 94, 77,
+  80, 82, 95, 89, 94, 70, 84, 84, 77, 81,
+  101, 78, 73, 80, 75, 79, 88, 67, 90, 91,
+  83, 89, 100, 93, 76, 90, 78, 94, 91, 91,
+  87, 94, 76, 71, 86, 78, 90, 104, 73, 73,
+  70, 80, 90, 85, 87, 84, 95, 88, 84, 92,
+  89, 73, 90, 108, 85, 78, 81, 80, 77, 75,
+  101, 75, 90, 90, 77, 87, 79, 78, 78, 83,
+  70, 86, 80, 99, 87, 83, 82, 101, 79, 79,
+  93, 58, 66, 71, 79, 102, 75, 72, 109, 86,
+  92, 87, 103, 77, 74, 79, 83, 71, 81, 77,
+  86, 72, 82, 77, 83, 85, 80, 75, 77, 101,
+  81, 102, 80, 95, 87, 84, 78, 87, 82, 105,
+  93, 86, 84, 79, 87, 87, 99, 78, 80, 85,
+  91, 84, 89, 72, 74, 79, 81, 79, 86, 86,
+  82, 81, 73, 77, 85, 82, 80, 97, 91, 86,
+  76, 103, 81, 79, 94, 89, 79, 90, 95, 87,
+  61, 78, 80, 83, 72, 90, 84, 94, 72, 91,
+  87, 78, 107, 88, 100, 84, 88, 91, 91, 63,
+  88, 94, 83, 84, 93, 74, 86, 74, 93, 90,
+  88, 129, 97, 92, 80, 97, 79, 110, 92, 71,
+  129, 106, 104, 71, 105, 85, 71, 80, 84, 65,
+  53, 73, 65, 77, 78, 93, 91, 75, 103, 99,
+  81, 85, 94, 94, 82, 62, 91, 68, 94, 76,
+  63, 87, 88, 70, 77, 65, 92, 108, 98, 85,
+  90, 71, 66, 77, 82, 90, 89, 88, 81, 83,
+  87, 89, 90, 81, 87, 96, 79, 85, 78, 81,
+  81, 100, 101, 83, 91, 85, 95, 100, 87, 76,
+  88, 85, 75, 112, 94, 78, 85, 89, 78, 82,
+  79, 91, 78, 89, 83, 90, 81, 85, 93, 71,
+  84, 91, 87, 76, 82, 79, 79, 77, 86, 85,
+  73, 78, 81, 80, 84, 88, 75, 83, 92, 81,
+  79, 82, 77, 87, 82, 90, 92, 78, 76, 79,
+  83, 84, 84, 71, 95, 73, 78, 91, 71, 80,
+  75, 87, 72, 68, 81, 91, 90, 80, 77, 93,
+  79, 69, 94, 85, 87, 89, 85, 84, 98, 70,
+  93, 75, 80, 109, 73, 88, 80, 64, 83, 72,
+  85, 91, 87, 76, 73, 85, 92, 83, 69, 103,
+  91, 96, 102, 94, 84, 83, 83, 87, 79, 78,
+  75, 83, 68, 83, 83, 84, 90, 77, 84, 73,
+  74, 84, 85, 93, 97, 75, 69, 74, 64, 77,
+  83, 68, 91, 89, 83, 88, 94, 83, 80, 92,
+  76, 93, 93, 89, 77, 96, 88, 79, 92, 81,
+  94, 91, 72, 73, 72, 81, 84, 92, 70, 80,
+  74, 79, 87, 91, 77, 86, 88, 95, 87, 82,
+  78, 84, 86, 85, 94, 78, 83, 73, 77, 85,
+  82, 70, 95, 71, 70, 95, 71, 85, 81, 85,
+  78, 89, 80, 78, 92, 66, 68, 81, 79, 86,
+  91, 78, 84, 87, 83, 80, 103, 72, 78, 76,
+  74, 94, 81, 86, 76, 67, 96, 82, 81, 90,
+  81, 73, 70, 79, 81, 98, 76, 103, 91, 95,
+  86, 83, 78, 86, 89, 83, 77, 72, 81, 85,
+  80, 75, 83, 83, 89, 83, 78, 73, 78, 77,
+  81, 85, 83, 75, 80, 82, 63, 76, 85, 67,
+  88, 96, 87, 84, 75, 108, 84, 83, 82, 97,
+  88, 87, 85, 88, 75, 80, 86, 86, 78, 91,
+  78, 81, 71, 80, 84, 85, 91, 86, 85, 74,
+  84, 92, 80, 64, 93, 97, 85, 76, 84, 73,
+  82, 73, 84, 84, 86, 106, 91, 89, 77, 92,
+  76, 103, 82, 78, 104, 94, 95, 76, 92, 87,
+  81, 79, 84, 68, 64, 74, 67, 86, 80, 92,
+  105, 72, 96, 91, 85, 85, 91, 91, 81, 71,
+  89, 75, 82, 73, 71, 78, 93, 81, 73, 67,
+  82, 98, 90, 87, 86, 82, 78, 79, 68, 90,
+  82, 93, 87, 76, 81, 80, 86, 80, 86, 88,
+  81, 85, 75, 85, 76, 83, 99, 79, 89, 86,
+  94, 91, 88, 74, 85, 82, 77, 100, 92, 79,
+  88, 89, 76, 86, 78, 89, 79, 93, 83, 91,
+  87, 81, 89, 77, 85, 92, 81, 93, 87, 82,
+  85, 81, 84, 86, 92, 85, 86, 86, 83, 87,
+  82, 76, 96, 87, 84, 88, 77, 87, 90, 94,
+  92, 83, 80, 77, 78, 78, 82, 75, 84, 77,
+  87, 84, 75, 80, 74, 99, 75, 78, 77, 85,
+  84, 82, 82, 89, 75, 81, 88, 90, 81, 86,
+  86, 89, 99, 77, 90, 77, 79, 88, 73, 85,
+  78, 68, 82, 70, 84, 92, 86, 69, 84, 88,
+  100, 84, 71, 91, 81, 86, 104, 94, 86, 90,
+  78, 84, 91, 75, 86, 87, 80, 89, 83, 87,
+  86, 73, 82, 75, 76, 80, 91, 87, 99, 86,
+  81, 69, 74, 86, 81, 76, 89, 77, 89, 90,
+  90, 81, 81, 90, 79, 88, 94, 89, 85, 90,
+  88, 83, 97, 88, 85, 90, 76, 80, 77, 83,
+  79, 90, 82, 86, 87, 88, 88, 91, 78, 89,
+  84, 90, 88, 91, 75, 87, 91, 95, 97, 85,
+  89, 70, 75, 86, 86, 69, 93, 75, 77, 89,
+  68, 79, 77, 89, 78, 89, 83, 74, 85, 72,
+  79, 82, 76, 83, 88, 86, 77, 84, 80, 85,
+  93, 77, 83, 74, 78, 93, 75, 84, 74, 67,
+  90, 82, 78, 90, 82, 67, 75, 78, 86, 97,
+  79, 97, 87, 93, 95, 87, 85, 82, 81, 80,
+  84, 74, 85, 89, 79, 83, 83, 88, 87, 79,
+  84, 76, 83, 78, 85, 84, 84, 83, 78, 78,
+  64, 82, 81, 70, 87, 100, 85, 87, 78, 108,
+  87, 83, 75, 93, 91, 85, 90, 92, 77, 77,
+  92, 91, 76, 96, 74, 83, 72, 84, 79, 86,
+  87, 88, 88, 79, 92, 94, 82, 69, 82, 96,
+  83, 78, 75, 82, 79, 83, 93, 89, 91, 93,
+  88, 100, 84, 87, 85, 93, 81, 79, 87, 81,
+  90, 82, 93, 88, 89, 78, 81, 72, 69, 74,
+  67, 77, 87, 87, 92, 73, 88, 92, 85, 88,
+  88, 82, 80, 80, 86, 86, 75, 68, 80, 76,
+  89, 79, 78, 62, 87, 83, 87, 90, 84, 81,
+  82, 82, 80, 86, 84, 90, 89, 75, 80, 76,
+  87, 83, 86, 87, 81, 89, 80, 86, 80, 77,
+  96, 79, 88, 85, 96, 87, 88, 78, 81, 77,
+  76, 87, 77, 102, 109, 80, 84, 83, 97, 94,
+  81, 76, 77, 88, 80, 90, 77, 83, 80, 85,
+  86, 80, 88, 79, 91, 69, 87, 93, 82, 68,
+  89, 81, 82, 82, 91, 81, 82, 88, 79, 82,
+  78, 87, 74, 67, 86, 85, 80, 113, 84, 90,
+  97, 73, 79, 82, 73, 85, 70, 67, 83, 73,
+  89, 80, 76, 81, 96, 82, 89, 84, 75, 79,
+  88, 89, 86, 81, 99, 75, 72, 94, 81, 84,
+  78, 104, 77, 81, 97, 81, 89, 97, 81, 68,
+  95, 83, 78, 80, 90, 104, 77, 85, 86, 78,
+  78, 90, 85, 86, 84, 81, 93, 90, 93, 84,
+  85, 80, 95, 92, 90, 79, 83, 88, 91, 91,
+  96, 93, 84, 78, 88, 79, 70, 85, 79, 85,
+  81, 90, 100, 74, 86, 94, 106, 80, 72, 67,
+  75, 89, 94, 92, 80, 80, 85, 78, 82, 84,
+  99, 77, 84, 76, 95, 91, 78, 65, 82, 82,
+  89, 87, 96, 83, 85, 88, 82, 71, 86, 93,
+  62, 63, 93, 97, 74, 109, 90, 99, 92, 78,
+  85, 85, 72, 89, 64, 89, 85, 75, 95, 79,
+  70, 84, 96, 81, 92, 91, 69, 81, 92, 77,
+  88, 85, 83, 69, 80, 79, 84, 92, 80, 112,
+  77, 87, 98, 71, 101, 100, 82, 64, 96, 91,
+  64, 65, 80, 106, 63, 86, 83, 78, 91, 91,
+  62, 83, 76, 81, 99, 84, 98, 81, 98, 81,
+  101, 93, 83, 80, 77, 99, 93, 91, 103, 96,
+  85, 81, 97, 72, 73, 88, 82, 96, 76, 78,
+  86, 79, 85, 90, 96, 85, 80, 75, 83, 81,
+  89, 86, 83, 89, 84, 85, 88, 81, 99, 76,
+  81, 71, 87, 92, 84, 70, 79, 88, 79, 82,
+  97, 95, 87, 83, 86, 79, 90, 86, 69, 69,
+  84, 88, 78, 106, 84, 90, 98, 76, 83, 83,
+  73, 90, 68, 96, 83, 82, 88, 80, 80, 84,
+  92, 84, 90, 88, 76, 80, 92, 85, 90, 85,
+  93, 81, 76, 88, 84, 91, 81, 107, 78, 81,
+  93, 73, 99, 102, 85, 72, 97, 87, 76, 81,
+  84, 96, 78, 83, 91, 80, 90, 89, 84, 78,
+  84, 85, 90, 92, 91, 83, 83, 77, 89, 94,
+  88, 81, 78, 93, 96, 87, 96, 91, 80, 81,
+  90, 78, 65, 83, 82, 92, 73, 100, 70, 94,
+  92, 80, 82, 102, 97, 88, 73, 98, 89, 62,
+  64, 90, 80, 86, 78, 83, 71, 92, 71, 70,
+  74, 89, 103, 87, 113, 69, 59, 79, 82, 88,
+  56, 90, 107, 91, 78, 100, 97, 66, 83, 70,
+  95, 97, 75, 81, 95, 70, 59, 76, 75, 65,
+  84, 101, 89, 64, 86, 80, 88, 68, 101, 82,
+  76, 60, 87, 86, 76, 116, 102, 80, 87, 70,
+  73, 92, 63, 74, 99, 74, 88, 60, 82, 79,
+  69, 75, 85, 86, 65, 87, 87, 93, 92, 93,
+  104, 78, 91, 78, 77, 94, 102, 86, 94, 73,
+  85, 76, 69, 91, 68, 82, 73, 73, 82, 92,
+  89, 75, 72, 82, 89, 72, 77, 67, 88, 91,
+  72, 82, 78, 57, 66, 84, 75, 95, 93, 83,
+  79, 113, 103, 90, 76, 106, 92, 71, 65, 87,
+  84, 88, 81, 82, 86, 91, 82, 72, 78, 93,
+  93, 94, 106, 66, 52, 82, 85, 89, 44, 87,
+  88, 109, 77, 103, 107, 63, 75, 72, 94, 102,
+  69, 71, 88, 74, 68, 78, 75, 67, 79, 68,
+  92, 62, 91, 88, 86, 78, 104, 81, 71, 59,
+  81, 86, 76, 106, 69, 79, 98, 80, 75, 103,
+  69, 82, 73, 73, 90, 65, 71, 88, 73, 85,
+  91, 82, 52, 84, 85, 94, 89, 95, 106, 78,
+  89, 77, 64, 101, 109, 75, 87, 72, 69, 76,
+  76, 85, 66, 81, 64, 70, 87, 93, 85, 75,
+  79, 83, 91, 62, 74, 66, 84, 96, 73, 79,
+  76, 57, 76, 76, 92, 92, 88, 72, 83, 100,
+  93, 89, 80, 96, 97, 89, 69, 88, 79, 86,
+  79, 78, 92, 93, 88, 68, 80, 91, 98, 91,
+  97, 72, 62, 82, 87, 88, 57, 79, 93, 99,
+  79, 101, 98, 63, 70, 70, 90, 89, 74, 68,
+  97, 71, 63, 86, 73, 66, 79, 65, 82, 70,
+  87, 81, 83, 78, 108, 85, 79, 68, 88, 80,
+  75, 123, 69, 77, 91, 81, 75, 85, 67, 87,
+  78, 80, 84, 66, 78, 94, 77, 88, 90, 83,
+  70, 86, 85, 85, 92, 94, 98, 80, 93, 76,
+  65, 92, 102, 74, 92, 74, 79, 76, 69, 85,
+  68, 81, 69, 68, 86, 89, 93, 78, 86, 81,
+  89, 66, 81, 72, 84, 92, 68, 86, 79, 66,
+  80, 95, 71, 73, 85, 81, 89, 85, 80, 84,
+  84, 86, 91, 84, 70, 90, 78, 80, 81, 90,
+  67, 89, 82, 81, 86, 84, 93, 84, 77, 83,
+  94, 78, 79, 66, 74, 76, 95, 75, 94, 73,
+  80, 104, 82, 85, 88, 77, 98, 79, 71, 78,
+  80, 92, 80, 79, 78, 97, 68, 85, 82, 94,
+  95, 63, 83, 83, 72, 68, 86, 88, 84, 83,
+  80, 97, 75, 73, 92, 63, 78, 78, 101, 84,
+  95, 91, 80, 85, 88, 83, 79, 91, 107, 68,
+  73, 74, 87, 81, 66, 75, 88, 92, 104, 63,
+  102, 70, 93, 89, 94, 80, 74, 102, 88, 81,
+  82, 82, 77, 77, 106, 108, 81, 75, 90, 89,
+  91, 88, 77, 87, 74, 85, 85, 101, 79, 85,
+  80, 76, 86, 81, 89, 85, 81, 90, 78, 95,
+  79, 88, 73, 98, 77, 90, 85, 85, 73, 85,
+  83, 82, 78, 89, 98, 84, 71, 73, 88, 72,
+  82, 67, 71, 76, 102, 65, 79, 71, 75, 96,
+  76, 88, 99, 72, 103, 77, 74, 82, 78, 97,
+  84, 82, 86, 100, 71, 74, 83, 94, 92, 59,
+  84, 83, 83, 65, 78, 87, 77, 84, 89, 95,
+  81, 76, 95, 72, 81, 71, 113, 82, 97, 99,
+  83, 83, 83, 78, 84, 91, 116, 69, 81, 78,
+  85, 73, 75, 76, 85, 90, 88, 60, 104, 83,
+  96, 89, 96, 82, 75, 103, 86, 85, 91, 85,
+  80, 79, 106, 104, 75, 72, 81, 89, 88, 86,
+  76, 91, 79, 81, 77, 101, 79, 80, 81, 75,
+  89, 82, 86, 88, 84, 88, 84, 89, 84, 92,
+  70, 90, 75, 82, 84, 85, 83, 83, 78, 80,
+  78, 83, 96, 85, 74, 68, 100, 72, 80, 74,
+  76, 78, 102, 70, 79, 75, 74, 107, 72, 84,
+  88, 78, 100, 88, 78, 75, 79, 92, 82, 79,
+  83, 89, 71, 77, 91, 89, 89, 67, 85, 81,
+  72, 75, 75, 80, 85, 75, 84, 91, 82, 75,
+  95, 67, 80, 74, 117, 87, 91, 95, 83, 83,
+  86, 73, 90, 85, 110, 74, 75, 81, 86, 76,
+  78, 78, 86, 87, 85, 71, 97, 101, 95, 88,
+  93, 82, 71, 101, 89, 84, 96, 85, 80, 77,
+  99, 98, 63, 78, 86, 83, 87, 89, 75, 90,
+  78, 85, 81, 99, 68, 89, 88, 88, 89, 74,
+  80, 95, 111, 95, 79, 82, 97, 74, 66, 113,
+  89, 85, 75, 84, 90, 83, 101, 86, 80, 85,
+  82, 87, 91, 81, 61, 92, 101, 75, 65, 93,
+  86, 99, 89, 76, 84, 72, 93, 80, 75, 98,
+  72, 83, 92, 79, 81, 87, 90, 109, 99, 84,
+  95, 70, 87, 82, 87, 77, 84, 85, 82, 87,
+  80, 80, 106, 85, 87, 81, 101, 76, 81, 87,
+  87, 84, 82, 76, 87, 70, 99, 80, 78, 83,
+  90, 75, 72, 73, 102, 80, 83, 82, 96, 83,
+  90, 70, 87, 101, 77, 92, 96, 93, 84, 105,
+  77, 84, 70, 62, 76, 77, 93, 84, 82, 95,
+  91, 82, 72, 80, 76, 74, 95, 85, 90, 81,
+  87, 95, 64, 87, 83, 93, 99, 72, 76, 92,
+  120, 93, 82, 85, 104, 78, 72, 106, 91, 90,
+  77, 84, 101, 86, 86, 82, 82, 75, 89, 88,
+  97, 78, 57, 102, 105, 79, 63, 90, 81, 106,
+  81, 63, 73, 65, 88, 79, 65, 105, 72, 82,
+  90, 75, 84, 87, 90, 113, 87, 71, 105, 65,
+  83, 84, 88, 84, 80, 90, 67, 86, 85, 81,
+  115, 79, 81, 71, 112, 74, 72, 77, 81, 82,
+  82, 68, 87, 67, 96, 82, 80, 84, 83, 80,
+  65, 69, 99, 70, 72, 91, 98, 76, 92, 66,
+  90, 103, 67, 84, 90, 90, 75, 108, 70, 87,
+  76, 56, 73, 71, 92, 86, 91, 91, 90, 88,
+  72, 80, 80, 69, 101, 81, 84, 79, 86, 99,
+  78, 77, 88, 86, 81, 91, 80, 91, 107, 91,
+  81, 76, 97, 85, 76, 116, 87, 90, 82, 82,
+  101, 80, 73, 85, 79, 90, 87, 79, 77, 74,
+  64, 101, 107, 78, 73, 86, 88, 100, 73, 77,
+  79, 74, 82, 75, 72, 96, 71, 76, 92, 83,
+  79, 91, 91, 107, 99, 61, 101, 79, 75, 84,
+  82, 82, 87, 84, 84, 86, 91, 81, 106, 90,
+  75, 76, 104, 82, 70, 83, 79, 78, 78, 79,
+  94, 71, 93, 91, 81, 86, 78, 73, 78, 69,
+  94, 76, 78, 86, 93, 76, 88, 73, 77, 89,
+  69, 82, 92, 87, 86, 101, 74, 82, 72, 69,
+  79, 71, 95, 85, 88, 90, 96, 82, 75, 80,
+  85, 75, 107, 86, 91, 80, 94, 104, 67, 85,
+  96, 78, 94, 81, 89, 82, 77, 91, 84, 71,
+  78, 87, 67, 82, 73, 76, 77, 82, 76, 85,
+  77, 92, 82, 82, 77, 83, 95, 91, 81, 83,
+  72, 85, 82, 79, 76, 78, 87, 71, 86, 72,
+  73, 85, 79, 67, 92, 66, 81, 76, 85, 84,
+  89, 75, 86, 91, 77, 82, 93, 86, 90, 74,
+  75, 82, 79, 80, 79, 71, 96, 90, 78, 87,
+  86, 82, 90, 72, 90, 93, 100, 74, 84, 92,
+  94, 79, 80, 86, 95, 94, 84, 75, 96, 70,
+  93, 80, 85, 90, 81, 81, 92, 75, 82, 87,
+  94, 98, 65, 105, 83, 84, 76, 81, 69, 89,
+  71, 75, 88, 96, 84, 82, 83, 66, 81, 96,
+  77, 83, 84, 75, 73, 79, 63, 88, 76, 81,
+  101, 72, 93, 84, 77, 84, 92, 77, 76, 91,
+  68, 71, 71, 74, 69, 88, 77, 83, 83, 88,
+  84, 80, 80, 78, 100, 91, 83, 83, 67, 86,
+  81, 80, 80, 69, 92, 62, 87, 69, 75, 93,
+  69, 68, 92, 80, 80, 73, 98, 88, 85, 72,
+  78, 93, 76, 73, 104, 88, 92, 67, 75, 79,
+  69, 79, 76, 73, 97, 84, 89, 88, 81, 75,
+  97, 67, 89, 80, 109, 66, 79, 99, 90, 71,
+  85, 90, 85, 97, 82, 73, 87, 69, 93, 80,
+  81, 92, 81, 77, 94, 68, 74, 96, 86, 98,
+  53, 102, 81, 87, 74, 81, 67, 86, 64, 87,
+  96, 101, 74, 87, 73, 65, 78, 97, 73, 79,
+  79, 77, 63, 78, 70, 80, 76, 87, 88, 78,
+  85, 86, 86, 91, 85, 72, 77, 88, 69, 87,
+  72, 79, 79, 84, 83, 78, 89, 92, 81, 80,
+  82, 87, 92, 86, 78, 84, 86, 84, 79, 87,
+  82, 84, 76, 72, 79, 73, 76, 83, 77, 82,
+  88, 103, 85, 76, 85, 85, 87, 84, 89, 79,
+  83, 74, 87, 83, 86, 70, 81, 72, 76, 76,
+  69, 76, 106, 86, 90, 86, 93, 80, 93, 77,
+  85, 75, 91, 77, 86, 88, 96, 78, 76, 84,
+  70, 91, 83, 73, 95, 67, 88, 79, 95, 84,
+  86, 85, 87, 80, 76, 97, 98, 95, 66, 108,
+  79, 84, 76, 76, 72, 81, 80, 90, 84, 94,
+  84, 88, 77, 67, 86, 89, 86, 85, 84, 74,
+  71, 88, 95, 91, 83, 82, 80, 89, 87, 84,
+  67, 93, 76, 76, 90, 89, 74, 70, 80, 80,
+  76, 76, 80, 96, 83, 84, 79, 93, 80, 87,
+  84, 86, 97, 85, 79, 93, 93, 85, 84, 77,
+  72, 87, 84, 83, 81, 86, 98, 78, 76, 74,
+  84, 79, 89, 87, 97, 74, 87, 83, 83, 98,
+  81, 84, 82, 79, 87, 91, 79, 85, 86, 76,
+  69, 80, 89, 87, 91, 89, 90, 75, 86, 100,
+  76, 86, 84, 91, 85, 76, 84, 82, 94, 80,
+  88, 73, 90, 78, 102, 88, 76, 84, 82, 99,
+  83, 71, 89, 89, 92, 101, 85, 84, 86, 91,
+  90, 94, 76, 88, 79, 80, 86, 84, 82, 86,
+  90, 71, 89, 98, 85, 89, 75, 75, 79, 73,
+  98, 93, 77, 76, 88, 86, 89, 81, 70, 91,
+  78, 79, 96, 80, 77, 67, 82, 81, 73, 76,
+  78, 98, 92, 85, 90, 96, 76, 86, 85, 93,
+  94, 86, 73, 92, 85, 79, 82, 69, 88, 90,
+  91, 83, 78, 95, 96, 80, 81, 77, 82, 83,
+  94, 90, 94, 71, 89, 84, 82, 98, 84, 86,
+  82, 76, 87, 88, 68, 89, 90, 73, 71, 79,
+  83, 89, 89, 87, 91, 70, 91, 89, 72, 87,
+  81, 92, 88, 77, 90, 87, 87, 83, 84, 66,
+  82, 73, 99, 92, 72, 95, 80, 97, 78, 67,
+  86, 95, 89, 103, 88, 79, 87, 94, 93, 102,
+  79, 90, 73, 84, 88, 83, 88, 86, 85, 66,
+  89, 102, 84, 86, 75, 72, 78, 78, 90, 85,
+  84, 88, 80, 80, 84, 88, 71, 91, 79, 76,
+  88, 71, 70, 70, 74, 81, 75, 74, 84, 92,
+  102, 84, 88, 98, 79, 89, 84, 95, 92, 84,
+  80, 89, 78, 84, 83, 73, 88, 87, 83, 82,
+  83, 82, 96, 81, 79, 97, 88, 78, 88, 88,
+  91, 79, 88, 85, 88, 88, 87, 84, 80, 80,
+  92, 83, 72, 87, 83, 78, 78, 79, 88, 88,
+  92, 89, 88, 78, 86, 82, 72, 88, 85, 90,
+  89, 89, 83, 83, 80, 82, 87, 71, 88, 76,
+  105, 85, 81, 86, 83, 94, 86, 75, 85, 92,
+  93, 98, 82, 87, 83, 92, 86, 92, 82, 84,
+  79, 90, 89, 87, 99, 91, 89, 71, 92, 97,
+  88, 89, 79, 77, 74, 77, 78, 73, 84, 86,
+  86, 76, 91, 77, 74, 84, 79, 93, 82, 83,
+  75, 85, 79, 88, 82, 102, 79, 81, 95, 87,
+  83, 72, 101, 80, 96, 73, 81, 66, 87, 90,
+  107, 92, 73, 82, 83, 86, 72, 96, 100, 86,
+  75, 91, 86, 80, 72, 80, 140, 74, 87, 73,
+  86, 88, 74, 84, 90, 89, 69, 90, 85, 82,
+  76, 73, 81, 68, 63, 84, 76, 86, 87, 78,
+  79, 95, 89, 111, 76, 108, 93, 52, 96, 92,
+  92, 76, 87, 82, 78, 91, 87, 77, 84, 81,
+  87, 71, 81, 87, 78, 86, 85, 90, 92, 85,
+  85, 74, 82, 90, 96, 79, 85, 80, 69, 99,
+  96, 84, 87, 91, 96, 89, 80, 93, 82, 75,
+  80, 99, 85, 82, 92, 84, 74, 88, 101, 75,
+  96, 69, 80, 83, 79, 89, 81, 94, 74, 79,
+  86, 75, 74, 108, 92, 76, 79, 88, 79, 66,
+  82, 80, 100, 84, 83, 85, 80, 85, 84, 85,
+  62, 81, 97, 68, 70, 110, 87, 86, 85, 87,
+  85, 97, 75, 65, 160, 61, 84, 77, 75, 104,
+  64, 94, 82, 91, 73, 87, 95, 77, 66, 78,
+  76, 56, 62, 71, 74, 101, 75, 66, 82, 79,
+  102, 87, 67, 140, 92, 51, 83, 89, 89, 74,
+  83, 78, 77, 95, 80, 64, 77, 92, 81, 95,
+  76, 105, 90, 82, 81, 89, 96, 88, 84, 77,
+  91, 92, 92, 78, 87, 74, 66, 87, 98, 91,
+  82, 93, 98, 84, 90, 108, 57, 84, 77, 95,
+  94, 81, 75, 94, 81, 85, 83, 95, 87, 76,
+  79, 85, 83, 101, 80, 83, 73, 84, 83, 90,
+  79, 99, 95, 89, 78, 87, 77, 69, 96, 80,
+  91, 103, 77, 76, 86, 73, 82, 79, 76, 83,
+  88, 92, 77, 89, 76, 86, 87, 98, 89, 106,
+  72, 81, 127, 79, 85, 76, 88, 91, 78, 85,
+  86, 93, 70, 88, 86, 77, 69, 77, 83, 69,
+  60, 82, 88, 83, 90, 79, 89, 98, 93, 73,
+  74, 97, 96, 61, 88, 95, 90, 82, 97, 80,
+  72, 84, 86, 87, 80, 78, 83, 74, 78, 84,
+  83, 78, 80, 76, 91, 87, 84, 71, 82, 88,
+  91, 85, 85, 77, 75, 88, 81, 79, 86, 85,
+  91, 90, 95, 91, 88, 79, 77, 96, 83, 87,
+  74, 73, 79, 88, 78, 81, 88, 76, 69, 77,
+  81, 89, 74, 76, 69, 87, 80, 90, 82, 99,
+  79, 83, 89, 86, 90, 73, 95, 80, 80, 80,
+  79, 75, 88, 82, 79, 94, 73, 77, 85, 95,
+  66, 89, 92, 87, 74, 82, 89, 91, 81, 84,
+  124, 80, 85, 74, 94, 74, 75, 87, 87, 83,
+  71, 81, 84, 80, 72, 72, 89, 65, 77, 91,
+  82, 91, 84, 83, 80, 93, 80, 92, 68, 118,
+  95, 56, 95, 90, 90, 75, 81, 78, 67, 73,
+  85, 67, 85, 71, 78, 73, 91, 84, 76, 80,
+  75, 87, 89, 84, 76, 78, 74, 87, 81, 74,
+  86, 87, 72, 90, 81, 79, 72, 86, 87, 85,
+  73, 88, 87, 77, 87, 80, 76, 79, 78, 71,
+  72, 85, 83, 74, 96, 70, 77, 78, 81, 88,
+  75, 90, 77, 77, 92, 77, 77, 92, 90, 83,
+  79, 84, 85, 68, 75, 81, 79, 73, 83, 89,
+  78, 81, 78, 80, 66, 75, 94, 76, 69, 126,
+  89, 88, 80, 82, 86, 97, 82, 72, 146, 74,
+  89, 80, 87, 96, 63, 96, 85, 85, 69, 80,
+  86, 82, 63, 86, 79, 54, 84, 77, 74, 108,
+  73, 72, 85, 81, 89, 86, 59, 165, 97, 57,
+  86, 84, 90, 71, 75, 73, 71, 74, 76, 57,
+  85, 86, 75, 92, 86, 111, 87, 77, 70, 74,
+  94, 84, 64, 82, 80, 89, 69, 78, 90, 78,
+  71, 77, 83, 91, 71, 85, 92, 81, 79, 100,
+  68, 87, 85, 67, 83, 79, 72, 77, 73, 88,
+  74, 83, 87, 79, 74, 77, 84, 93, 76, 82,
+  70, 88, 80, 93, 82, 92, 90, 87, 85, 84,
+  84, 69, 93, 80, 76, 76, 75, 79, 90, 78,
+  83, 75, 69, 77, 78, 95, 71, 89, 81, 87,
+  78, 89, 90, 97, 83, 88, 114, 84, 84, 75,
+  92, 79, 78, 84, 84, 88, 72, 83, 83, 77,
+  73, 75, 88, 74, 82, 91, 83, 88, 81, 83,
+  86, 99, 83, 85, 73, 105, 96, 59, 95, 83,
+  92, 80, 92, 83, 65, 74, 85, 83, 81, 71,
+  88, 73, 87, 85, 78, 77, 72, 77, 88, 84,
+  77, 73, 70, 89, 81, 81, 86, 82, 76, 80,
+  73, 81, 86, 82, 83, 92, 88, 87, 93, 79,
+  86, 82, 77, 86, 72, 71, 80, 94, 84, 89,
+  94, 82, 78, 74, 88, 84, 84, 85, 76, 92,
+  81, 91, 83, 104, 83, 89, 88, 88, 91, 71,
+  84, 82, 97, 76, 86, 76, 84, 92, 97, 102,
+  74, 91, 94, 87, 74, 89, 94, 85, 73, 84,
+  87, 86, 81, 77, 135, 78, 80, 79, 83, 83,
+  74, 95, 93, 95, 70, 80, 81, 78, 74, 73,
+  100, 69, 73, 82, 90, 86, 87, 83, 74, 92,
+  89, 116, 73, 115, 87, 61, 95, 93, 87, 97,
+  91, 85, 79, 78, 81, 79, 88, 83, 88, 76,
+  86, 85, 82, 76, 86, 76, 80, 87, 75, 77,
+  83, 88, 73, 78, 86, 81, 69, 91, 89, 90,
+  78, 89, 90, 79, 78, 92, 83, 77, 79, 85,
+  77, 87, 73, 83, 86, 96, 89, 78, 100, 75,
+  85, 79, 92, 82, 81, 96, 82, 82, 100, 76,
+  78, 102, 93, 74, 80, 84, 84, 69, 69, 80,
+  102, 89, 96, 91, 83, 93, 93, 88, 81, 101,
+  105, 68, 79, 117, 95, 84, 81, 78, 86, 101,
+  82, 65, 152, 67, 83, 83, 75, 98, 62, 104,
+  86, 102, 70, 73, 88, 74, 67, 82, 89, 57,
+  78, 71, 75, 90, 78, 70, 76, 76, 104, 88,
+  66, 149, 90, 61, 84, 90, 84, 102, 80, 78,
+  83, 81, 72, 77, 84, 101, 87, 95, 83, 105,
+  91, 78, 89, 79, 87, 89, 65, 71, 84, 91,
+  63, 78, 97, 74, 65, 80, 89, 92, 65, 91,
+  96, 71, 81, 101, 65, 81, 70, 77, 84, 90,
+  69, 92, 88, 93, 80, 93, 90, 81, 79, 74,
+  86, 88, 76, 90, 75, 89, 82, 96, 84, 97,
+  91, 88, 90, 86, 82, 69, 86, 79, 92, 81,
+  85, 83, 91, 90, 88, 84, 73, 91, 83, 87,
+  75, 94, 84, 84, 72, 88, 91, 117, 88, 80,
+  120, 80, 82, 81, 86, 85, 76, 90, 89, 94,
+  72, 81, 80, 74, 77, 72, 88, 78, 74, 85,
+  84, 85, 82, 83, 79, 98, 84, 78, 77, 106,
+  89, 65, 96, 85, 87, 97, 96, 84, 79, 77,
+  83, 94, 86, 80, 97, 70, 85, 84, 83, 75,
+  84, 99, 80, 88, 75, 74, 78, 87, 73, 82,
+  91, 78, 72, 84, 79, 84, 86, 84, 82, 82,
+  85, 86, 90, 77, 78, 86, 75, 88, 71, 80,
+  81, 77, 89, 73, 72, 73, 98, 79, 91, 90,
+  78, 101, 70, 72, 86, 74, 97, 78, 94, 92,
+  76, 83, 88, 94, 89, 86, 94, 72, 98, 81,
+  92, 79, 83, 78, 81, 77, 83, 70, 82, 84,
+  86, 85, 72, 84, 73, 76, 73, 78, 83, 94,
+  84, 122, 89, 76, 96, 77, 89, 80, 76, 84,
+  99, 78, 73, 91, 81, 92, 106, 89, 77, 81,
+  77, 97, 85, 79, 88, 116, 83, 86, 83, 74,
+  85, 91, 87, 73, 84, 80, 88, 93, 80, 79,
+  73, 78, 100, 106, 66, 76, 85, 80, 91, 85,
+  66, 74, 80, 75, 83, 91, 79, 75, 85, 95,
+  98, 90, 77, 76, 102, 76, 94, 94, 82, 90,
+  73, 70, 84, 78, 94, 74, 70, 84, 78, 74,
+  81, 79, 64, 68, 93, 78, 100, 88, 65, 96,
+  69, 75, 91, 84, 125, 65, 84, 78, 74, 80,
+  88, 91, 87, 86, 89, 84, 106, 86, 105, 80,
+  81, 85, 82, 69, 94, 63, 88, 85, 86, 75,
+  76, 85, 71, 89, 59, 77, 78, 76, 85, 136,
+  82, 79, 104, 69, 89, 88, 89, 87, 108, 85,
+  67, 85, 81, 108, 105, 91, 76, 82, 82, 98,
+  82, 83, 96, 87, 79, 95, 86, 74, 97, 90,
+  89, 72, 79, 83, 83, 96, 82, 83, 67, 77,
+  105, 107, 70, 74, 71, 83, 91, 96, 68, 79,
+  76, 80, 100, 82, 68, 69, 81, 98, 92, 86,
+  69, 81, 94, 76, 97, 94, 92, 84, 72, 68,
+  79, 78, 97, 78, 72, 88, 83, 83, 84, 83,
+  72, 77, 95, 78, 97, 84, 77, 79, 71, 78,
+  91, 77, 104, 73, 87, 86, 73, 80, 84, 92,
+  85, 92, 90, 89, 98, 92, 96, 82, 67, 103,
+  83, 73, 103, 69, 85, 81, 93, 85, 78, 78,
+  73, 93, 74, 75, 87, 85, 82, 117, 87, 85,
+  92, 81, 86, 79, 84, 83, 98, 80, 73, 89,
+  73, 91, 101, 91, 90, 83, 77, 99, 85, 82,
+  87, 72, 80, 85, 87, 77, 82, 91, 86, 74,
+  83, 73, 87, 90, 81, 76, 72, 78, 89, 102,
+  72, 73, 80, 80, 94, 92, 71, 74, 78, 82,
+  88, 85, 68, 74, 76, 89, 90, 81, 72, 69,
+  78, 76, 92, 87, 90, 92, 80, 70, 87, 83,
+  95, 73, 75, 74, 75, 77, 84, 74, 79, 79,
+  87, 82, 75, 92, 80, 74, 82, 70, 88, 90,
+  86, 79, 84, 88, 71, 83, 91, 87, 79, 80,
+  96, 76, 94, 75, 104, 84, 94, 77, 89, 75,
+  89, 85, 93, 82, 84, 83, 78, 83, 77, 79,
+  86, 73, 81, 84, 86, 114, 85, 86, 93, 73,
+  81, 94, 72, 80, 91, 83, 73, 78, 74, 108,
+  100, 85, 86, 91, 71, 94, 101, 77, 84, 95,
+  86, 83, 80, 71, 74, 88, 93, 73, 88, 79,
+  83, 89, 76, 81, 74, 77, 94, 93, 72, 83,
+  106, 77, 87, 76, 76, 85, 85, 77, 82, 93,
+  76, 79, 75, 110, 113, 94, 72, 74, 94, 79,
+  86, 79, 81, 97, 75, 83, 78, 79, 87, 61,
+  69, 81, 85, 75, 79, 77, 76, 79, 77, 79,
+  76, 94, 66, 85, 82, 66, 94, 99, 106, 70,
+  77, 75, 73, 81, 97, 81, 78, 76, 82, 94,
+  105, 74, 102, 76, 100, 89, 89, 71, 85, 76,
+  95, 79, 80, 77, 77, 76, 82, 75, 75, 61,
+  81, 78, 86, 126, 81, 75, 100, 64, 82, 107,
+  76, 83, 102, 88, 66, 73, 72, 126, 114, 79,
+  73, 91, 71, 91, 110, 72, 90, 81, 80, 89,
+  82, 71, 85, 82, 95, 75, 81, 75, 81, 92,
+  69, 80, 70, 80, 102, 91, 74, 85, 85, 77,
+  75, 85, 81, 91, 74, 80, 91, 87, 65, 74,
+  72, 121, 124, 84, 66, 77, 81, 78, 89, 76,
+  79, 86, 61, 88, 74, 81, 80, 61, 71, 91,
+  104, 83, 82, 78, 77, 77, 83, 83, 83, 89,
+  76, 95, 81, 72, 90, 87, 95, 73, 86, 86,
+  75, 85, 93, 82, 77, 84, 93, 96, 98, 80,
+  105, 79, 79, 103, 87, 71, 86, 81, 94, 82,
+  84, 80, 80, 83, 85, 80, 82, 69, 84, 83,
+  84, 112, 87, 71, 88, 74, 81, 90, 80, 81,
+  91, 86, 69, 83, 77, 104, 101, 85, 75, 93,
+  70, 93, 109, 80, 86, 77, 78, 85, 82, 68,
+  79, 87, 87, 80, 83, 75, 83, 93, 77, 82,
+  77, 77, 92, 89, 75, 82, 77, 80, 90, 90,
+  79, 83, 84, 83, 88, 89, 74, 79, 76, 111,
+  108, 79, 78, 74, 77, 78, 91, 76, 79, 95,
+  72, 80, 78, 85, 82, 66, 81, 75, 75, 73,
+  83, 86, 84, 79, 85, 79, 74, 87, 88, 75,
+  89, 86, 79, 90, 70, 76, 80, 77, 72, 92,
+  92, 73, 77, 83, 77, 77, 82, 80, 93, 90,
+  100, 74, 98, 83, 87, 97, 94, 73, 87, 80,
+  75, 85, 84, 81, 82, 78, 82, 80, 85, 95,
+  89, 83, 87, 81, 93, 82, 74, 75, 93, 86,
+  88, 79, 71, 78, 95, 78, 93, 85, 74, 84,
+  97, 75, 81, 90, 82, 80, 78, 85, 69, 84,
+  86, 78, 80, 79, 94, 79, 77, 87, 77, 74,
+  90, 88, 75, 81, 105, 83, 85, 75, 82, 86,
+  99, 78, 79, 88, 77, 91, 80, 90, 101, 86,
+  90, 79, 80, 78, 84, 96, 78, 97, 85, 85,
+  77, 92, 89, 76, 75, 81, 88, 70, 80, 75,
+  84, 84, 83, 82, 72, 85, 71, 85, 87, 89,
+  83, 93, 72, 73, 78, 67, 73, 86, 96, 82,
+  77, 83, 73, 88, 88, 76, 88, 86, 102, 75,
+  97, 94, 85, 81, 100, 70, 80, 74, 71, 79,
+  90, 68, 87, 67, 84, 83, 82, 107, 84, 89,
+  96, 75, 96, 92, 69, 75, 103, 83, 82, 74,
+  74, 83, 102, 72, 78, 89, 68, 83, 106, 82,
+  81, 79, 80, 81, 79, 90, 65, 73, 92, 82,
+  73, 79, 89, 77, 74, 81, 79, 81, 94, 89,
+  77, 82, 92, 85, 82, 76, 83, 88, 96, 81,
+  85, 86, 72, 87, 77, 82, 116, 76, 89, 84,
+  77, 82, 86, 94, 74, 94, 80, 94, 77, 105,
+  89, 69, 77, 88, 105, 73, 81, 82, 85, 78,
+  82, 85, 78, 83, 82, 93, 86, 88, 78, 91,
+  74, 75, 88, 80, 83, 90, 96, 73, 74, 84,
+  76, 92, 87, 81, 93, 77, 92, 90, 97, 87,
+  76, 88, 95, 70, 79, 76, 76, 84, 87, 75,
+  83, 74, 82, 84, 84, 95, 87, 80, 83, 78,
+  91, 78, 74, 74, 91, 84, 87, 82, 74, 80,
+  90, 83, 67, 84, 73, 82, 108, 75, 82, 80,
+  80, 80, 78, 82, 67, 79, 87, 82, 78, 78,
+  88, 80, 76, 79, 77, 74, 86, 86, 76, 82,
+  82, 81, 86, 74, 84, 85, 95, 79, 78, 86,
+  76, 88, 81, 91, 101, 74, 85, 84, 81, 77,
+  86, 94, 80, 94, 83, 84, 81, 103, 88, 76,
+  80, 69, 101, 78, 67, 88, 85, 86, 81, 89,
+  75, 93, 87, 86, 86, 71, 88, 79, 76, 88,
+  79, 74, 86, 91, 75, 79, 83, 78, 92, 72,
+  87, 84, 81, 70, 88, 81, 93, 94, 66, 77,
+  76, 88, 80, 91, 89, 93, 84, 72, 102, 85,
+  95, 82, 86, 75, 86, 78, 69, 85, 88, 78,
+  84, 77, 79, 89, 96, 77, 86, 96, 74, 64,
+  76, 90, 76, 97, 80, 84, 86, 107, 88, 81,
+  83, 84, 85, 82, 82, 83, 88, 82, 91, 81,
+  86, 84, 94, 73, 85, 96, 69, 91, 76, 87,
+  87, 101, 83, 93, 85, 75, 86, 82, 70, 86,
+  93, 86, 87, 85, 94, 94, 84, 85, 93, 82,
+  93, 92, 68, 86, 87, 85, 87, 85, 78, 77,
+  81, 69, 65, 76, 86, 80, 77, 87, 73, 82,
+  76, 88, 85, 70, 71, 74, 57, 78, 84, 68,
+  72, 93, 67, 82, 86, 70, 97, 70, 95, 87,
+  74, 67, 69, 72, 86, 99, 80, 58, 91, 89,
+  88, 82, 90, 94, 81, 85, 111, 72, 99, 72,
+  80, 83, 81, 97, 60, 81, 95, 75, 87, 85,
+  87, 91, 82, 83, 108, 86, 64, 52, 84, 105,
+  71, 116, 75, 65, 86, 76, 97, 76, 86, 76,
+  76, 73, 73, 95, 85, 85, 99, 80, 74, 72,
+  101, 87, 61, 121, 68, 82, 92, 78, 79, 93,
+  79, 94, 92, 87, 87, 85, 75, 74, 92, 90,
+  84, 79, 104, 111, 80, 90, 89, 121, 83, 91,
+  67, 80, 76, 92, 75, 82, 77, 93, 73, 76,
+  63, 93, 87, 82, 81, 93, 79, 90, 95, 80,
+  85, 71, 78, 77, 73, 86, 74, 75, 90, 93,
+  74, 85, 86, 79, 88, 82, 78, 84, 78, 67,
+  78, 80, 93, 98, 92, 71, 90, 88, 84, 89,
+  99, 86, 83, 111, 105, 85, 96, 70, 84, 80,
+  87, 96, 68, 87, 88, 79, 87, 79, 86, 91,
+  88, 80, 95, 99, 66, 70, 87, 101, 77, 103,
+  80, 80, 85, 70, 87, 75, 84, 81, 79, 89,
+  79, 90, 90, 87, 88, 84, 83, 70, 95, 79,
+  78, 101, 73, 90, 93, 80, 89, 90, 84, 94,
+  84, 76, 93, 85, 75, 84, 81, 83, 86, 80,
+  89, 94, 83, 87, 90, 100, 78, 92, 67, 86,
+  86, 87, 80, 86, 80, 66, 108, 77, 84, 78,
+  79, 86, 88, 87, 83, 92, 97, 103, 84, 69,
+  85, 72, 81, 81, 96, 94, 80, 81, 66, 83,
+  73, 79, 93, 81, 76, 80, 86, 83, 79, 88,
+  82, 82, 76, 84, 84, 83, 77, 81, 95, 91,
+  69, 86, 88, 88, 75, 90, 82, 77, 84, 73,
+  69, 64, 82, 89, 77, 87, 81, 87, 81, 85,
+  81, 96, 70, 61, 78, 83, 88, 93, 87, 85,
+  75, 82, 79, 81, 81, 73, 85, 81, 84, 77,
+  86, 88, 77, 85, 86, 79, 93, 79, 87, 110,
+  79, 91, 72, 86, 87, 85, 85, 97, 78, 82,
+  86, 91, 74, 74, 97, 76, 86, 89, 87, 88,
+  90, 84, 91, 85, 81, 77, 78, 86, 87, 83,
+  85, 79, 78, 79, 78, 74, 108, 73, 70, 88,
+  85, 78, 85, 86, 82, 84, 80, 59, 76, 71,
+  73, 83, 97, 101, 72, 67, 65, 101, 77, 74,
+  97, 70, 72, 76, 88, 88, 72, 95, 72, 75,
+  90, 66, 91, 70, 93, 80, 126, 100, 57, 85,
+  83, 71, 71, 61, 80, 95, 76, 79, 71, 60,
+  70, 102, 81, 107, 91, 81, 72, 83, 94, 108,
+  56, 50, 79, 85, 98, 106, 78, 76, 59, 76,
+  76, 72, 89, 66, 83, 81, 79, 84, 82, 85,
+  65, 76, 93, 70, 72, 97, 84, 137, 81, 97,
+  70, 81, 79, 92, 82, 98, 78, 94, 102, 93,
+  91, 59, 91, 76, 87, 85, 83, 79, 95, 87,
+  75, 115, 72, 72, 79, 86, 86, 87, 77, 76,
+  79, 92, 80, 79, 85, 78, 77, 85, 91, 89,
+  86, 88, 103, 68, 83, 63, 77, 71, 84, 80,
+  76, 96, 76, 72, 71, 91, 77, 82, 93, 73,
+  72, 79, 86, 74, 86, 94, 74, 81, 109, 82,
+  92, 76, 96, 83, 102, 91, 67, 81, 85, 87,
+  75, 77, 80, 89, 86, 96, 72, 68, 77, 91,
+  78, 94, 87, 89, 80, 90, 83, 98, 62, 66,
+  95, 89, 91, 98, 81, 79, 74, 85, 76, 76,
+  83, 70, 86, 89, 83, 83, 86, 89, 76, 84,
+  86, 74, 88, 85, 82, 110, 84, 94, 86, 84,
+  87, 79, 84, 98, 77, 81, 98, 89, 79, 74,
+  76, 74, 87, 87, 74, 80, 85, 82, 86, 90,
+  81, 79, 79, 86, 85, 84, 84, 79, 94, 80,
+  98, 79, 83, 81, 76, 86, 82, 90, 74, 93,
+  109, 94, 82, 73, 83, 77, 87, 82, 81, 87,
+  98, 90, 75, 82, 77, 89, 78, 78, 77, 84,
+  80, 86, 76, 75, 87, 80, 83, 94, 72, 84,
+  63, 83, 83, 85, 87, 83, 76, 84, 82, 87,
+  82, 68, 83, 94, 71, 69, 78, 85, 82, 82,
+  90, 88, 88, 88, 88, 79, 79, 78, 90, 82,
+  88, 92, 96, 79, 79, 81, 83, 85, 86, 88,
+  78, 75, 92, 81, 86, 83, 90, 89, 69, 88,
+  86, 88, 84, 92, 81, 86, 88, 84, 81, 86,
+  85, 96, 79, 90, 87, 93, 83, 87, 79, 72,
+  87, 89, 92, 93, 94, 81, 94, 83, 79, 76,
+  80, 88, 91, 79, 87, 84, 86, 85, 98, 80,
+  107, 80, 67, 88, 87, 84, 77, 90, 101, 81,
+  81, 70, 81, 75, 96, 77, 78, 100, 84, 76,
+  83, 91, 79, 86, 81, 74, 77, 82, 82, 95,
+  79, 82, 91, 84, 87, 103, 82, 77, 72, 82,
+  98, 79, 81, 75, 67, 76, 86, 93, 82, 94,
+  72, 87, 66, 68, 82, 97, 91, 82, 100, 73,
+  82, 99, 87, 81, 75, 65, 89, 83, 92, 84,
+  83, 77, 67, 79, 78, 84, 96, 87, 87, 83,
+  93, 84, 86, 80, 88, 89, 72, 85, 68, 102,
+  90, 90, 85, 97, 90, 88, 78, 84, 85, 94,
+  70, 93, 96, 91, 88, 80, 74, 72, 87, 88,
+  100, 86, 87, 79, 88, 88, 73, 77, 89, 88,
+  90, 79, 93, 83, 91, 98, 99, 82, 87, 99,
+  74, 81, 80, 92, 74, 89, 103, 83, 83, 70,
+  82, 76, 94, 75, 64, 93, 83, 85, 84, 85,
+  79, 91, 72, 72, 81, 86, 79, 82, 79, 84,
+  90, 83, 90, 100, 83, 82, 75, 83, 82, 86,
+  89, 71, 71, 85, 82, 91, 82, 74, 84, 82,
+  67, 71, 79, 85, 88, 82, 91, 85, 86, 88,
+  83, 74, 78, 76, 89, 87, 87, 92, 89, 78,
+  77, 84, 83, 86, 90, 86, 83, 89, 88, 83,
+  91, 83, 91, 88, 71, 89, 84, 89, 79, 88,
+  79, 90, 95, 87, 79, 96, 82, 95, 76, 88,
+  90, 90, 79, 89, 76, 71, 82, 85, 92, 87,
+  89, 81, 96, 79, 83, 74, 76, 88, 90, 87,
+  90, 85, 84, 82, 87, 94, 77, 89, 85, 76,
+  89, 89, 77, 79, 82, 73, 70, 95, 73, 70,
+  87, 96, 78, 70, 85, 106, 63, 74, 81, 83,
+  90, 82, 81, 88, 73, 100, 98, 98, 76, 90,
+  74, 69, 87, 67, 82, 67, 86, 96, 84, 106,
+  98, 80, 83, 71, 76, 69, 73, 100, 79, 93,
+  75, 85, 84, 101, 88, 77, 77, 62, 64, 72,
+  92, 68, 111, 89, 95, 87, 83, 77, 89, 90,
+  99, 77, 85, 87, 84, 88, 78, 78, 94, 84,
+  85, 86, 80, 110, 101, 88, 73, 79, 90, 80,
+  90, 73, 75, 85, 89, 92, 87, 74, 76, 76,
+  77, 74, 84, 76, 62, 90, 77, 87, 92, 89,
+  79, 75, 68, 78, 80, 77, 78, 91, 76, 84,
+  97, 84, 68, 89, 84, 88, 80, 81, 93, 74,
+  83, 90, 101, 80, 88, 81, 92, 84, 80, 79,
+  91, 77, 88, 87, 76, 75, 73, 86, 87, 81,
+  88, 70, 87, 95, 92, 86, 71, 80, 83, 81,
+  83, 83, 66, 83, 94, 83, 75, 109, 73, 94,
+  85, 81, 87, 85, 75, 99, 66, 92, 76, 86,
+  78, 78, 79, 80, 69, 76, 68, 72, 87, 75,
+  94, 90, 81, 80, 96, 69, 84, 83, 85, 90,
+  81, 93, 95, 77, 92, 82, 89, 95, 89, 80,
+  77, 90, 85, 91, 67, 82, 93, 102, 114, 80,
+  75, 83, 81, 89, 88, 88, 82, 83, 85, 81,
+  80, 80, 81, 80, 75, 95, 89, 90, 88, 72,
+  77, 90, 92, 79, 80, 80, 85, 94, 99, 74,
+  71, 79, 77, 90, 81, 89, 78, 70, 86, 91,
+  93, 81, 93, 70, 105, 99, 84, 79, 93, 88,
+  82, 81, 74, 69, 78, 82, 68, 82, 94, 73,
+  99, 81, 104, 79, 89, 68, 75, 88, 84, 92,
+  78, 81, 93, 73, 75, 99, 71, 100, 80, 85,
+  95, 86, 88, 89, 79, 82, 78, 77, 83, 83,
+  80, 77, 77, 88, 85, 83, 77, 93, 81, 76,
+  84, 78, 89, 73, 75, 85, 79, 84, 81, 86,
+  92, 81, 88, 74, 80, 89, 88, 81, 88, 88,
+  85, 87, 80, 78, 90, 98, 105, 89, 80, 90,
+  82, 89, 82, 99, 86, 87, 70, 87, 73, 92,
+  96, 81, 78, 93, 87, 92, 83, 80, 81, 91,
+  74, 83, 85, 79, 88, 90, 76, 86, 82, 88,
+  83, 76, 79, 79, 88, 89, 79, 77, 85, 72,
+  71, 80, 71, 74, 94, 99, 71, 73, 73, 100,
+  78, 79, 85, 75, 113, 68, 77, 110, 70, 89,
+  81, 91, 90, 82, 79, 73, 87, 71, 118, 70,
+  85, 93, 79, 81, 101, 80, 86, 84, 76, 73,
+  76, 89, 95, 77, 86, 75, 97, 93, 91, 64,
+  58, 65, 74, 90, 73, 76, 101, 80, 109, 94,
+  78, 93, 92, 77, 102, 83, 82, 78, 83, 88,
+  67, 72, 88, 80, 77, 93, 82, 102, 94, 87,
+  90, 83, 95, 76, 61, 78, 77, 94, 98, 87,
+  80, 83, 83, 74, 77, 76, 86, 77, 69, 102,
+  73, 90, 79, 88, 77, 98, 72, 83, 72, 81,
+  81, 92, 75, 76, 83, 83, 67, 96, 82, 81,
+  77, 70, 95, 89, 77, 72, 100, 73, 74, 91,
+  70, 63, 73, 87, 68, 70, 73, 101, 75, 76,
+  80, 83, 107, 65, 72, 89, 69, 103, 89, 95,
+  73, 91, 78, 84, 86, 63, 83, 77, 77, 90,
+  81, 110, 88, 86, 80, 84, 88, 72, 68, 97,
+  71, 85, 84, 87, 88, 80, 76, 55, 62, 66,
+  72, 73, 99, 69, 120, 85, 92, 75, 93, 78,
+  85, 82, 103, 84, 81, 89, 89, 80, 85, 83,
+  94, 87, 83, 86, 67, 105, 85, 82, 72, 81,
+  87, 79, 95, 81, 78, 97, 90, 85, 85, 86,
+  81, 74, 73, 68, 75, 75, 62, 95, 71, 84,
+  80, 89, 76, 69, 78, 79, 79, 75, 85, 84,
+  71, 79, 97, 79, 77, 88, 85, 79, 80, 76,
+  90, 75, 87, 85, 114, 82, 86, 83, 98, 89,
+  85, 80, 75, 80, 81, 86, 85, 75, 80, 90,
+  77, 77, 98, 84, 92, 85, 94, 76, 87, 72,
+  80, 93, 84, 93, 79, 88, 85, 69, 90, 82,
+  69, 96, 76, 89, 98, 89, 75, 87, 75, 96,
+  74, 86, 83, 78, 70, 74, 63, 82, 84, 80,
+  90, 79, 68, 81, 79, 70, 90, 67, 78, 80,
+  84, 89, 87, 90, 102, 81, 100, 84, 81, 86,
+  90, 87, 76, 85, 83, 94, 69, 77, 85, 104,
+  99, 85, 82, 88, 87, 85, 82, 99, 91, 88,
+  73, 84, 75, 86, 81, 76, 81, 95, 84, 95,
+  93, 69, 77, 87, 82, 79, 89, 79, 90, 90,
+  90, 91, 88, 74, 93, 64, 97, 89, 77, 72,
+  73, 91, 86, 83, 80, 71, 78, 99, 105, 88,
+  68, 90, 88, 84, 91, 90, 84, 72, 99, 68,
+  86, 106, 96, 80, 82, 78, 81, 75, 87, 78,
+  79, 81, 147, 86, 106, 88, 76, 61, 93, 81,
+  88, 97, 82, 83, 98, 78, 103, 89, 77, 81,
+  88, 76, 98, 73, 62, 81, 75, 89, 75, 81,
+  90, 72, 102, 99, 76, 93, 80, 80, 87, 90,
+  91, 82, 83, 81, 73, 71, 83, 77, 83, 89,
+  96, 77, 91, 87, 91, 81, 92, 91, 57, 76,
+  74, 62, 84, 83, 77, 76, 91, 88, 87, 94,
+  106, 83, 83, 87, 66, 93, 85, 81, 81, 103,
+  74, 93, 80, 91, 90, 82, 85, 80, 73, 89,
+  71, 83, 79, 71, 92, 76, 85, 91, 76, 75,
+  80, 85, 70, 84, 69, 71, 85, 93, 63, 74,
+  84, 96, 80, 85, 80, 77, 107, 56, 73, 101,
+  66, 96, 95, 96, 87, 84, 68, 76, 94, 70,
+  117, 69, 73, 93, 72, 92, 104, 77, 80, 86,
+  83, 71, 78, 76, 95, 81, 89, 80, 100, 90,
+  90, 58, 60, 65, 74, 88, 97, 76, 109, 76,
+  113, 89, 87, 98, 90, 88, 99, 84, 80, 79,
+  75, 85, 66, 78, 84, 83, 79, 81, 83, 97,
+  98, 81, 87, 77, 93, 73, 72, 82, 80, 91,
+  95, 82, 88, 83, 76, 76, 78, 72, 79, 79,
+  66, 100, 68, 81, 85, 85, 72, 89, 77, 81,
+  72, 83, 84, 81, 76, 75, 86, 73, 74, 89,
+  71, 69, 87, 69, 86, 85, 81, 79, 114, 85,
+  69, 83, 85, 76, 84, 85, 64, 75, 89, 87,
+  87, 75, 84, 87, 79, 71, 76, 98, 75, 101,
+  96, 86, 95, 75, 70, 99, 99, 82, 102, 79,
+  66, 75, 81, 87, 96, 87, 73, 88, 92, 79,
+  80, 80, 85, 80, 86, 83, 93, 85, 91, 62,
+  79, 72, 78, 86, 111, 88, 86, 83, 95, 70,
+  87, 79, 84, 84, 99, 92, 82, 77, 88, 83,
+  85, 80, 92, 81, 80, 81, 78, 95, 94, 86,
+  67, 69, 88, 79, 88, 89, 82, 92, 92, 85,
+  83, 92, 81, 84, 72, 71, 74, 75, 67, 84,
+  81, 86, 93, 89, 83, 85, 83, 77, 81, 82,
+  96, 82, 77, 82, 68, 83, 79, 92, 77, 97,
+  81, 84, 68, 82, 72, 81, 93, 65, 70, 99,
+  74, 93, 81, 100, 86, 91, 89, 75, 74, 82,
+  84, 84, 98, 77, 76, 84, 84, 75, 77, 93,
+  92, 83, 91, 95, 77, 86, 95, 80, 103, 95,
+  80, 83, 85, 83, 80, 68, 76, 92, 85, 100,
+  86, 77, 82, 76, 83, 90, 83, 65, 88, 79,
+  86, 93, 86, 92, 89, 94, 93, 78, 87, 81,
+  84, 79, 90, 69, 79, 86, 80, 98, 82, 70,
+  99, 80, 84, 85, 83, 81, 78, 84, 102, 70,
+  88, 89, 90, 79, 94, 85, 85, 84, 92, 87,
+  88, 84, 84, 80, 78, 100, 87, 101, 76, 83,
+  74, 78, 84, 86, 89, 87, 72, 81, 87, 84,
+  78, 84, 67, 73, 84, 81, 80, 90, 81, 74,
+  76, 78, 67, 89, 86, 79, 68, 95, 76, 90,
+  70, 94, 92, 87, 88, 74, 68, 82, 91, 81,
+  104, 81, 72, 78, 78, 78, 77, 91, 81, 77,
+  72, 84, 75, 64, 91, 85, 116, 98, 73, 71,
+  79, 79, 71, 60, 80, 85, 88, 59, 91, 64,
+  85, 78, 80, 91, 90, 61, 91, 63, 79, 81,
+  88, 90, 82, 77, 103, 83, 83, 78, 73, 80,
+  93, 61, 81, 83, 78, 94, 74, 60, 100, 79,
+  76, 88, 81, 93, 74, 76, 113, 68, 81, 93,
+  77, 75, 88, 69, 81, 83, 85, 87, 74, 87,
+  84, 83, 86, 91, 75, 101, 85, 64, 82, 73,
+  71, 85, 96, 80, 71, 76, 90, 79, 77, 77,
+  82, 80, 92, 90, 75, 90, 85, 81, 74, 82,
+  83, 82, 92, 95, 76, 91, 74, 92, 88, 97,
+  92, 91, 91, 72, 76, 81, 83, 84, 87, 75,
+  93, 87, 80, 87, 78, 84, 90, 80, 77, 95,
+  79, 110, 88, 81, 83, 96, 87, 85, 84, 84,
+  76, 79, 78, 89, 91, 61, 76, 69, 81, 76,
+  85, 86, 82, 65, 83, 86, 85, 85, 94, 83,
+  86, 105, 83, 85, 90, 82, 89, 89, 96, 77,
+  78, 94, 84, 86, 84, 69, 98, 90, 96, 78,
+  79, 89, 79, 88, 99, 79, 95, 92, 85, 86,
+  87, 91, 95, 80, 93, 88, 87, 88, 88, 84,
+  96, 97, 89, 97, 101, 87, 88, 84, 86, 83,
+  94, 91, 80, 83, 88, 75, 84, 88, 98, 78,
+  75, 74, 84, 82, 73, 83, 85, 87, 99, 87,
+  80, 83, 76, 71, 84, 66, 72, 87, 81, 79,
+  85, 83, 81, 66, 94, 82, 84, 63, 103, 75,
+  78, 101, 98, 82, 88, 82, 72, 72, 79, 151,
+  79, 88, 92, 68, 95, 90, 75, 87, 98, 93,
+  84, 73, 75, 101, 90, 88, 73, 85, 78, 90,
+  81, 82, 69, 88, 85, 78, 96, 66, 77, 132,
+  69, 76, 83, 64, 98, 82, 51, 78, 97, 91,
+  81, 76, 85, 66, 80, 90, 102, 66, 77, 65,
+  74, 63, 79, 73, 80, 96, 87, 80, 83, 83,
+  101, 82, 83, 81, 83, 76, 71, 88, 80, 104,
+  80, 79, 121, 89, 62, 81, 89, 70, 79, 99,
+  86, 89, 94, 72, 79, 100, 103, 84, 77, 74,
+  81, 86, 79, 82, 100, 89, 101, 97, 97, 106,
+  82, 79, 100, 64, 68, 74, 84, 80, 71, 86,
+  83, 69, 96, 79, 94, 67, 113, 84, 83, 100,
+  82, 81, 97, 83, 110, 76, 73, 211, 92, 101,
+  95, 47, 98, 87, 79, 83, 100, 97, 94, 76,
+  75, 135, 84, 81, 81, 74, 72, 77, 87, 84,
+  46, 115, 86, 64, 89, 44, 68, 150, 58, 76,
+  79, 60, 97, 84, 28, 100, 105, 89, 84, 71,
+  93, 69, 68, 89, 114, 59, 77, 44, 80, 65,
+  61, 69, 80, 107, 98, 78, 70, 70, 112, 82,
+  74, 76, 77, 85, 80, 96, 86, 89, 83, 71,
+  124, 102, 63, 89, 98, 77, 70, 98, 101, 95,
+  107, 53, 86, 97, 75, 79, 84, 83, 85, 91,
+  70, 82, 83, 89, 92, 87, 67, 68, 77, 76,
+  81, 74, 78, 92, 73, 71, 78, 78, 74, 67,
+  92, 81, 72, 87, 85, 78, 79, 91, 80, 82,
+  84, 87, 65, 76, 87, 103, 79, 85, 88, 82,
+  92, 88, 73, 85, 95, 80, 85, 73, 79, 100,
+  84, 79, 76, 94, 88, 94, 80, 69, 77, 75,
+  85, 81, 93, 78, 72, 116, 80, 86, 88, 73,
+  91, 88, 61, 73, 91, 87, 85, 92, 75, 74,
+  83, 79, 86, 76, 78, 69, 72, 75, 86, 76,
+  77, 94, 89, 81, 86, 83, 93, 83, 79, 77,
+  86, 82, 65, 87, 74, 109, 80, 83, 93, 76,
+  88, 78, 77, 76, 78, 93, 77, 85, 92, 83,
+  78, 84, 71, 93, 88, 79, 85, 79, 80, 72,
+  90, 75, 78, 79, 82, 94, 73, 75, 82, 83,
+  84, 96, 90, 83, 94, 85, 84, 94, 87, 78,
+  101, 82, 74, 96, 79, 87, 80, 81, 89, 89,
+  79, 84, 93, 79, 87, 74, 80, 114, 77, 85,
+  98, 95, 86, 76, 83, 81, 81, 65, 80, 69,
+  76, 76, 83, 83, 84, 68, 90, 77, 86, 95,
+  89, 89, 78, 72, 92, 82, 86, 82, 80, 71,
+  97, 80, 80, 92, 88, 94, 76, 90, 104, 86,
+  86, 89, 101, 74, 85, 82, 91, 80, 84, 80,
+  75, 89, 93, 85, 75, 83, 94, 85, 93, 83,
+  59, 80, 89, 83, 82, 106, 81, 79, 85, 86,
+  83, 84, 83, 91, 81, 84, 92, 108, 72, 75,
+  50, 76, 77, 77, 85, 88, 76, 70, 94, 76,
+  75, 92, 60, 82, 76, 75, 84, 86, 77, 100,
+  89, 76, 98, 86, 75, 97, 89, 73, 103, 69,
+  55, 81, 71, 80, 75, 92, 79, 77, 68, 75,
+  95, 49, 89, 75, 83, 124, 69, 70, 91, 92,
+  75, 71, 82, 79, 81, 70, 81, 64, 71, 79,
+  87, 90, 80, 63, 100, 65, 88, 96, 88, 104,
+  82, 56, 102, 81, 87, 82, 65, 74, 96, 70,
+  83, 92, 74, 92, 66, 88, 106, 85, 72, 92,
+  98, 85, 84, 80, 102, 77, 78, 84, 70, 84,
+  93, 84, 67, 83, 98, 86, 91, 84, 50, 75,
+  74, 77, 77, 111, 68, 73, 107, 80, 70, 81,
+  91, 83, 74, 83, 86, 112, 71, 64, 76, 80,
+  74, 79, 80, 81, 84, 79, 90, 79, 81, 77,
+  92, 89, 73, 76, 80, 83, 84, 95, 82, 88,
+  82, 81, 79, 93, 86, 80, 87, 74, 80, 85,
+  82, 84, 93, 96, 89, 84, 87, 91, 95, 95,
+  89, 77, 77, 103, 77, 78, 92, 97, 84, 92,
+  84, 86, 78, 97, 86, 76, 79, 78, 84, 84,
+  81, 75, 76, 91, 82, 96, 88, 83, 81, 85,
+  90, 86, 82, 84, 85, 78, 91, 78, 82, 94,
+  88, 76, 83, 86, 98, 79, 85, 84, 91, 81,
+  80, 84, 85, 78, 83, 88, 91, 89, 84, 87,
+  82, 84, 96, 83, 87, 84, 67, 83, 80, 89,
+  82, 97, 75, 85, 95, 81, 86, 84, 93, 86,
+  90, 90, 94, 103, 81, 81, 82, 85, 78, 74,
+  75, 72, 76, 85, 90, 87, 81, 87, 110, 76,
+  69, 84, 79, 78, 90, 89, 72, 76, 74, 94,
+  89, 79, 92, 84, 89, 90, 81, 93, 78, 75,
+  84, 96, 88, 97, 75, 85, 98, 76, 92, 91,
+  92, 94, 73, 83, 72, 80, 85, 98, 80, 80,
+  87, 80, 79, 70, 100, 84, 98, 58, 73, 87,
+  63, 77, 68, 78, 69, 99, 118, 88, 83, 71,
+  81, 91, 83, 97, 87, 74, 83, 80, 91, 80,
+  85, 90, 86, 92, 70, 83, 76, 94, 83, 93,
+  92, 78, 87, 86, 93, 80, 97, 93, 88, 90,
+  80, 66, 72, 87, 67, 76, 83, 72, 80, 89,
+  71, 95, 74, 82, 90, 79, 71, 87, 76, 80,
+  98, 80, 84, 75, 77, 65, 80, 90, 85, 91,
+  76, 111, 92, 90, 85, 85, 56, 74, 70, 83,
+  78, 76, 88, 74, 86, 83, 77, 90, 82, 86,
+  85, 87, 91, 87, 72, 83, 77, 82, 67, 92,
+  56, 97, 55, 77, 80, 65, 68, 77, 86, 94,
+  74, 64, 89, 67, 97, 89, 79, 77, 81, 52,
+  111, 96, 88, 98, 80, 80, 90, 73, 70, 83,
+  69, 88, 75, 59, 111, 68, 110, 77, 77, 109,
+  71, 82, 71, 69, 82, 93, 78, 82, 76, 86,
+  92, 79, 82, 80, 97, 87, 74, 86, 113, 69,
+  79, 80, 59, 95, 67, 84, 88, 87, 85, 79,
+  81, 88, 68, 78, 83, 80, 98, 80, 86, 80,
+  91, 76, 86, 72, 85, 82, 91, 102, 87, 91,
+  77, 74, 94, 59, 95, 72, 100, 63, 98, 82,
+  86, 73, 75, 90, 76, 76, 89, 83, 80, 89,
+  85, 75, 89, 82, 90, 77, 90, 86, 85, 78,
+  72, 83, 87, 84, 89, 82, 74, 89, 81, 79,
+  86, 87, 79, 70, 84, 100, 81, 91, 83, 70,
+  103, 80, 73, 91, 69, 93, 68, 96, 100, 120,
+  86, 79, 75, 96, 84, 75, 91, 122, 102, 89,
+  93, 76, 83, 68, 93, 86, 89, 64, 81, 76,
+  86, 97, 91, 102, 92, 85, 107, 95, 78, 71,
+  104, 74, 78, 68, 83, 81, 77, 96, 64, 88,
+  85, 103, 87, 74, 76, 90, 96, 93, 104, 86,
+  79, 90, 90, 88, 87, 77, 106, 91, 81, 76,
+  91, 104, 91, 87, 84, 84, 84, 93, 85, 88,
+  84, 105, 65, 86, 80, 68, 85, 61, 90, 76,
+  82, 82, 123, 83, 88, 77, 87, 82, 88, 98,
+  76, 73, 73, 94, 88, 89, 87, 79, 98, 92,
+  101, 101, 80, 85, 102, 79, 98, 95, 91, 79,
+  98, 90, 100, 100, 87, 91, 88, 84, 65, 83,
+  81, 103, 85, 89, 84, 118, 67, 68, 96, 84,
+  102, 68, 79, 91, 66, 71, 86, 87, 71, 95,
+  72, 90, 67, 84, 87, 70, 90, 84, 83, 91,
+  91, 79, 95, 82, 94, 92, 85, 85, 80, 78,
+  75, 77, 91, 101, 66, 85, 93, 98, 130, 70,
+  90, 72, 90, 92, 79, 73, 69, 96, 78, 89,
+  85, 83, 70, 84, 78, 98, 58, 85, 86, 93,
+  84, 88, 78, 73, 90, 76, 89, 92, 83, 71,
+  57, 92, 72, 106, 57, 93, 85, 96, 71, 80,
+  74, 72, 68, 78, 84, 87, 83, 92, 78, 76,
+  77, 86, 79, 71, 98, 82, 112, 73, 60, 86,
+  80, 77, 90, 99, 96, 75, 64, 78, 88, 70,
+  69, 76, 87, 108, 79, 80, 73, 79, 78, 75,
+  82, 64, 97, 72, 89, 60, 86, 89, 98, 69,
+  81, 53, 61, 62, 56, 87, 77, 99, 149, 72,
+  90, 77, 87, 90, 75, 112, 84, 62, 84, 61,
+  78, 89, 74, 78, 90, 97, 47, 80, 79, 97,
+  69, 72, 116, 62, 80, 78, 76, 67, 86, 102,
+  98, 92, 86, 75, 75, 83, 65, 68, 73, 91,
+  77, 97, 68, 85, 73, 73, 73, 70, 73, 85,
+  73, 84, 83, 82, 72, 70, 79, 65, 86, 84,
+  100, 68, 83, 110, 83, 83, 84, 90, 71, 80,
+  79, 79, 77, 81, 101, 84, 98, 87, 72, 87,
+  82, 94, 84, 89, 70, 80, 81, 87, 82, 89,
+  66, 84, 71, 88, 63, 105, 79, 78, 61, 82,
+  83, 83, 79, 67, 98, 80, 88, 80, 73, 82,
+  71, 61, 112, 89, 90, 81, 74, 85, 98, 54,
+  59, 90, 86, 85, 82, 73, 49, 70, 107, 94,
+  76, 95, 71, 80, 55, 96, 86, 90, 86, 87,
+  89, 87, 89, 69, 91, 75, 98, 74, 82, 93,
+  86, 81, 78, 81, 70, 93, 66, 66, 86, 92,
+  91, 81, 96, 85, 77, 85, 88, 71, 95, 76,
+  88, 87, 62, 78, 85, 86, 95, 92, 86, 107,
+  86, 89, 78, 82, 83, 91, 63, 104, 87, 96,
+  95, 67, 86, 67, 87, 84, 89, 87, 85, 79,
+  85, 82, 78, 88, 79, 79, 80, 93, 73, 78,
+  80, 69, 81, 103, 101, 92, 88, 102, 91, 77,
+  83, 95, 75, 65, 91, 86, 90, 92, 76, 77,
+  79, 79, 74, 67, 85, 99, 91, 105, 77, 92,
+  69, 89, 84, 77, 95, 110, 88, 88, 85, 81,
+  104, 79, 81, 68, 70, 73, 81, 89, 72, 67,
+  86, 71, 72, 91, 102, 85, 86, 88, 83, 92,
+  89, 89, 88, 70, 88, 82, 99, 95, 70, 90,
+  99, 83, 110, 95, 72, 76, 86, 88, 84, 83,
+  72, 99, 81, 83, 75, 93, 69, 77, 104, 96,
+  68, 90, 81, 100, 90, 68, 79, 80, 84, 87,
+  86, 96, 83, 101, 67, 85, 78, 78, 81, 66,
+  87, 82, 72, 88, 114, 86, 71, 74, 86, 73,
+  80, 90, 76, 69, 87, 90, 89, 80, 91, 81,
+  98, 88, 101, 93, 73, 69, 98, 92, 97, 88,
+  103, 85, 98, 87, 89, 89, 69, 94, 92, 95,
+  71, 82, 74, 100, 86, 73, 86, 104, 59, 72,
+  83, 92, 95, 64, 81, 81, 71, 66, 78, 93,
+  88, 79, 98, 88, 67, 77, 97, 60, 80, 99,
+  90, 74, 91, 75, 94, 96, 90, 85, 72, 96,
+  79, 71, 68, 73, 85, 88, 63, 75, 89, 89,
+  135, 74, 90, 75, 94, 93, 96, 75, 81, 91,
+  97, 77, 82, 84, 57, 90, 81, 99, 72, 83,
+  92, 75, 72, 79, 81, 68, 88, 87, 81, 81,
+  74, 69, 67, 83, 91, 103, 72, 98, 73, 86,
+  78, 82, 59, 89, 63, 76, 79, 92, 82, 90,
+  99, 84, 78, 90, 81, 89, 89, 83, 77, 79,
+  80, 86, 83, 80, 67, 93, 94, 84, 66, 94,
+  81, 81, 54, 77, 86, 89, 86, 102, 91, 77,
+  78, 76, 76, 79, 89, 70, 100, 70, 79, 79,
+  86, 67, 96, 50, 60, 74, 73, 97, 78, 82,
+  99, 75, 91, 90, 79, 104, 71, 88, 70, 86,
+  88, 72, 71, 92, 84, 74, 94, 82, 69, 76,
+  93, 85, 82, 82, 106, 72, 83, 78, 78, 87,
+  82, 83, 92, 96, 94, 72, 84, 81, 90, 74,
+  78, 72, 72, 89, 83, 86, 82, 82, 88, 80,
+  96, 83, 88, 92, 75, 87, 78, 76, 78, 78,
+  80, 81, 93, 80, 85, 92, 81, 93, 65, 89,
+  78, 82, 74, 104, 77, 91, 77, 95, 76, 82,
+  101, 81, 76, 72, 78, 79, 99, 92, 77, 82,
+  81, 87, 84, 80, 80, 88, 86, 86, 80, 77,
+  79, 88, 108, 83, 77, 76, 103, 70, 86, 77,
+  65, 85, 81, 79, 77, 92, 83, 82, 72, 77,
+  87, 84, 80, 80, 76, 74, 81, 80, 75, 67,
+  75, 87, 87, 75, 87, 73, 83, 85, 80, 74,
+  80, 98, 76, 75, 72, 78, 87, 88, 83, 87,
+  87, 85, 89, 66, 88, 77, 93, 84, 86, 86,
+  130, 96, 97, 77, 80, 90, 87, 81, 73, 95,
+  88, 78, 82, 74, 81, 74, 80, 75, 81, 90,
+  81, 123, 79, 70, 79, 82, 74, 75, 81, 82,
+  93, 84, 82, 92, 77, 100, 65, 87, 75, 84,
+  79, 104, 77, 90, 77, 99, 75, 78, 87, 85,
+  78, 72, 77, 82, 90, 94, 76, 87, 79, 83,
+  86, 81, 79, 86, 85, 82, 78, 81, 78, 86,
+  102, 77, 75, 74, 116, 65, 84, 77, 71, 81,
+  79, 80, 79, 86, 80, 78, 72, 83, 81, 77,
+  82, 82, 76, 75, 81, 81, 77, 67, 77, 79,
+  94, 75, 87, 79, 83, 91, 80, 73, 78, 83,
+  72, 73, 76, 79, 83, 93, 81, 88, 84, 86,
+  87, 69, 88, 74, 84, 85, 85, 78, 142, 96,
+  98, 77, 77, 92, 82, 73, 68, 90, 99, 74,
+  84, 73, 78, 74, 77, 73, 81, 86, 83, 129,
+  77, 69, 78, 77, 82, 72, 81, 81, 91, 93,
+  83, 91, 82, 91, 70, 92, 82, 90, 76, 98,
+  77, 90, 79, 101, 76, 82, 76, 82, 81, 74,
+  79, 75, 93, 92, 75, 87, 80, 80, 86, 81,
+  80, 84, 87, 80, 78, 79, 79, 89, 105, 81,
+  78, 73, 101, 72, 84, 80, 68, 83, 82, 77,
+  80, 89, 82, 81, 72, 82, 84, 85, 83, 82,
+  81, 78, 77, 82, 75, 70, 80, 83, 90, 75,
+  90, 85, 79, 85, 80, 77, 79, 79, 78, 74,
+  81, 83, 84, 88, 83, 97, 85, 89, 80, 67,
+  86, 77, 78, 83, 89, 81, 124, 94, 92, 81,
+  81, 89, 83, 81, 72, 94, 85, 67, 86, 81,
+  74, 73, 83, 75, 84, 90, 78, 124, 79, 75,
+  78, 83, 74, 81, 82, 88, 84, 85, 99, 95,
+  70, 95, 66, 86, 75, 84, 83, 111, 78, 85,
+  79, 96, 74, 80, 93, 88, 85, 74, 71, 79,
+  91, 90, 77, 77, 80, 95, 75, 79, 78, 93,
+  88, 93, 82, 75, 73, 86, 96, 78, 78, 79,
+  116, 70, 84, 75, 72, 78, 78, 73, 72, 93,
+  82, 78, 75, 73, 86, 91, 81, 76, 86, 78,
+  91, 78, 74, 65, 68, 72, 87, 76, 88, 77,
+  80, 79, 75, 78, 85, 92, 71, 71, 71, 79,
+  79, 84, 84, 82, 86, 84, 87, 72, 89, 71,
+  85, 84, 82, 82, 141, 96, 92, 78, 80, 89,
+  87, 78, 79, 88, 102, 81, 76, 77, 84, 76,
+  81, 80, 82, 86, 80, 136, 78, 78, 79, 76,
+  67, 81, 79, 99, 87, 79, 105, 96, 68, 104,
+  63, 82, 73, 84, 92, 117, 78, 75, 78, 97,
+  74, 79, 78, 97, 86, 79, 69, 89, 88, 81,
+  80, 78, 78, 95, 75, 81, 74, 96, 88, 95,
+  81, 78, 77, 81, 87, 75, 79, 81, 136, 62,
+  86, 76, 86, 77, 77, 76, 69, 85, 81, 74,
+  75, 75, 82, 81, 73, 76, 89, 78, 98, 72,
+  74, 67, 64, 67, 101, 71, 90, 80, 83, 85,
+  74, 78, 82, 70, 60, 71, 73, 81, 78, 90,
+  85, 81, 82, 88, 84, 74, 91, 64, 84, 82,
+  80, 73, 166, 98, 100, 73, 77, 89, 89, 70,
+  80, 83, 124, 76, 73, 77, 75, 76, 80, 79,
+  79, 84, 87, 150, 76, 79, 78, 75, 75, 76,
+  78, 88, 85, 91, 98, 94, 73, 92, 68, 89,
+  79, 88, 81, 106, 78, 81, 78, 103, 74, 78,
+  79, 88, 83, 76, 73, 78, 84, 80, 75, 79,
+  77, 85, 82, 85, 77, 87, 87, 86, 80, 75,
+  76, 88, 97, 82, 76, 81, 115, 70, 85, 79,
+  73, 78, 77, 74, 75, 89, 84, 78, 74, 75,
+  83, 90, 87, 76, 87, 84, 91, 78, 79, 65,
+  72, 73, 95, 75, 91, 89, 83, 81, 75, 81,
+  80, 73, 72, 70, 83, 84, 76, 85, 81, 93,
+  84, 88, 79, 73, 87, 72, 77, 81, 85, 81,
+  132, 93, 92, 78, 84, 86, 88, 79, 78, 86,
+  100, 72, 76, 84, 75, 75, 81, 80, 83, 88,
+  82, 134, 78, 83, 80, 79, 81, 73, 76, 80,
+  87, 88, 96, 101, 73, 86, 69, 86, 79, 84,
+  84, 99, 77, 77, 77, 92, 79, 82, 90, 83,
+  85, 85, 76, 71, 83, 83, 78, 84, 80, 98,
+  75, 81, 78, 94, 87, 90, 80, 85, 71, 87,
+  101, 77, 77, 76, 110, 72, 90, 79, 65, 78,
+  82, 80, 75, 95, 87, 76, 71, 70, 94, 92,
+  82, 80, 90, 74, 88, 79, 78, 74, 72, 74,
+  83, 80, 95, 90, 70, 80, 75, 78, 88, 87,
+  84, 68, 74, 83, 83, 80, 77, 80, 90, 87,
+  87, 73, 89, 77, 76, 89, 86, 83, 117, 95,
+  83, 87, 86, 90, 92, 87, 83, 80, 80, 73,
+  75, 78, 81, 78, 83, 81, 82, 85, 71, 132,
+  75, 81, 74, 81, 75, 77, 76, 83, 90, 80,
+  99, 98, 73, 85, 68, 83, 75, 83, 92, 102,
+  83, 72, 77, 89, 78, 80, 83, 86, 80, 89,
+  74, 73, 81, 81, 81, 84, 82, 100, 75, 80,
+  73, 101, 87, 89, 85, 88, 77, 86, 100, 77,
+  74, 84, 118, 67, 91, 80, 69, 75, 80, 78,
+  77, 90, 86, 76, 71, 76, 92, 85, 79, 79,
+  94, 76, 97, 78, 73, 70, 72, 77, 86, 81,
+  99, 85, 67, 83, 75, 79, 83, 75, 78, 70,
+  72, 86, 81, 83, 77, 85, 90, 93, 86, 79,
+  84, 76, 78, 88, 87, 79, 119, 97, 81, 84,
+  87, 89, 91, 86, 82, 78, 86, 74, 76, 80,
+  72, 79, 82, 79, 81, 87, 79, 136, 74, 85,
+  75, 80, 82, 76, 76, 80, 87, 90, 97, 99,
+  75, 87, 69, 88, 81, 84, 83, 98, 79, 76,
+  74, 97, 75, 82, 89, 81, 77, 84, 77, 74,
+  78, 79, 81, 85, 81, 88, 80, 84, 79, 96,
+  91, 82, 82, 87, 78, 88, 104, 83, 73, 91,
+  111, 71, 90, 85, 66, 77, 83, 72, 78, 91,
+  90, 77, 71, 72, 92, 91, 88, 80, 84, 79,
+  93, 81, 77, 71, 76, 76, 88, 80, 98, 85,
+  70, 82, 76, 80, 81, 77, 82, 68, 77, 87,
+  81, 81, 77, 87, 89, 91, 80, 74, 89, 77,
+  79, 86, 87, 79, 115, 92, 82, 86, 90, 87,
+  94, 87, 81, 79, 82, 78, 80, 84, 75, 77,
+  83, 82, 87, 87, 78, 128, 75, 84, 77, 82,
+  83, 72, 90, 88, 106, 91, 74, 63, 78, 90,
+  78, 72, 82, 96, 69, 82, 85, 100, 85, 80,
+  87, 91, 100, 96, 93, 78, 81, 87, 95, 90,
+  76, 86, 63, 77, 73, 93, 79, 77, 88, 82,
+  83, 80, 84, 73, 76, 92, 89, 96, 87, 66,
+  98, 80, 105, 73, 76, 83, 72, 75, 82, 86,
+  94, 86, 88, 81, 102, 72, 81, 91, 86, 111,
+  80, 83, 91, 85, 70, 73, 73, 75, 87, 93,
+  90, 86, 84, 82, 74, 74, 84, 99, 89, 83,
+  86, 74, 78, 71, 89, 78, 87, 74, 94, 87,
+  74, 72, 84, 84, 73, 77, 88, 101, 87, 56,
+  79, 89, 92, 77, 89, 91, 102, 87, 90, 97,
+  111, 74, 93, 90, 88, 84, 90, 77, 75, 98,
+  78, 90, 133, 82, 72, 59, 77, 87, 75, 74,
+  83, 107, 77, 80, 92, 85, 85, 71, 83, 73,
+  86, 112, 100, 71, 76, 89, 103, 78, 75, 85,
+  61, 75, 84, 71, 90, 70, 94, 86, 79, 76,
+  84, 84, 87, 95, 97, 78, 76, 52, 114, 80,
+  93, 77, 60, 84, 67, 72, 87, 81, 92, 76,
+  89, 82, 89, 69, 81, 82, 80, 102, 78, 76,
+  85, 77, 73, 67, 73, 75, 100, 105, 85, 105,
+  85, 86, 63, 66, 76, 100, 88, 101, 72, 79,
+  77, 69, 81, 75, 95, 77, 90, 100, 72, 86,
+  76, 84, 72, 71, 86, 104, 93, 55, 77, 85,
+  91, 76, 86, 80, 73, 90, 84, 104, 106, 65,
+  74, 94, 84, 78, 83, 83, 80, 101, 86, 85,
+  89, 95, 77, 71, 80, 89, 75, 78, 73, 80,
+  69, 86, 92, 95, 88, 77, 82, 90, 96, 88,
+  91, 82, 83, 82, 88, 68, 79, 88, 70, 83,
+  89, 96, 84, 80, 81, 84, 81, 85, 77, 71,
+  75, 84, 92, 80, 92, 77, 92, 77, 100, 68,
+  86, 84, 74, 80, 82, 83, 95, 94, 84, 78,
+  99, 72, 75, 94, 78, 91, 101, 89, 84, 88,
+  74, 79, 78, 87, 99, 86, 90, 84, 89, 105,
+  82, 70, 83, 95, 89, 87, 87, 90, 84, 70,
+  103, 74, 85, 79, 87, 80, 78, 92, 90, 85,
+  72, 76, 83, 103, 86, 70, 85, 91, 93, 84,
+  82, 85, 81, 87, 88, 93, 79, 81, 95, 87,
+  85, 77, 88, 84, 88, 75, 84, 91, 112, 94,
+  75, 67, 71, 88, 89, 80, 93, 104, 71, 82,
+  91, 92, 96, 74, 89, 84, 102, 96, 93, 80,
+  74, 87, 104, 86, 82, 84, 50, 76, 90, 93,
+  78, 67, 101, 87, 80, 72, 82, 83, 83, 90,
+  82, 105, 75, 61, 102, 76, 95, 67, 62, 93,
+  72, 73, 84, 84, 76, 95, 79, 83, 90, 67,
+  83, 85, 89, 81, 77, 76, 102, 89, 72, 71,
+  61, 75, 83, 90, 83, 116, 95, 72, 73, 79,
+  82, 97, 100, 80, 91, 88, 83, 71, 81, 79,
+  86, 71, 80, 94, 58, 82, 74, 83, 75, 73,
+  82, 94, 85, 60, 81, 93, 92, 75, 75, 74,
+  92, 93, 83, 85, 108, 72, 86, 99, 82, 81,
+  90, 70, 85, 98, 81, 87, 155, 79, 71, 59,
+  81, 76, 99, 79, 112, 122, 78, 77, 102, 69,
+  96, 63, 82, 64, 77, 115, 102, 70, 65, 82,
+  106, 85, 81, 83, 35, 67, 102, 67, 81, 67,
+  123, 99, 76, 72, 89, 96, 99, 96, 84, 81,
+  66, 29, 121, 77, 74, 80, 34, 88, 67, 64,
+  82, 75, 67, 85, 76, 94, 70, 69, 93, 67,
+  91, 67, 74, 67, 99, 72, 70, 60, 59, 79,
+  83, 123, 76, 147, 106, 83, 69, 87, 68, 90,
+  104, 92, 84, 78, 77, 76, 56, 80, 90, 70,
+  86, 118, 54, 71, 60, 85, 66, 64, 76, 90,
+  94, 45, 95, 88, 84, 70, 72, 69, 76, 101,
+  77, 89, 101, 56, 55, 101, 78, 69, 81, 75,
+  80, 107, 84, 90, 98, 99, 79, 69, 72, 88,
+  84, 82, 76, 89, 72, 83, 91, 87, 90, 76,
+  75, 85, 93, 86, 82, 80, 75, 85, 97, 77,
+  81, 88, 57, 72, 94, 90, 82, 73, 89, 86,
+  81, 74, 82, 82, 84, 83, 76, 77, 80, 74,
+  93, 71, 91, 68, 73, 83, 71, 78, 86, 83,
+  84, 95, 81, 75, 85, 68, 88, 86, 77, 75,
+  95, 80, 89, 89, 74, 70, 69, 94, 92, 83,
+  84, 110, 97, 102, 82, 82, 76, 94, 99, 80,
+  93, 84, 82, 70, 96, 77, 89, 79, 85, 85,
+  64, 79, 81, 86, 76, 73, 79, 100, 86, 72,
+  91, 94, 95, 84, 77, 75, 91, 91, 82, 89,
+  75, 76, 83, 89, 81, 79, 88, 81, 93, 75,
+  79, 93, 79, 91, 79, 68, 77, 97, 83, 89,
+  87, 92, 67, 91, 89, 98, 85, 81, 84, 89,
+  87, 80, 86, 79, 88, 91, 91, 76, 83, 86,
+  68, 81, 89, 93, 86, 76, 85, 95, 87, 71,
+  87, 77, 70, 79, 77, 93, 77, 83, 84, 83,
+  99, 61, 78, 93, 72, 84, 86, 80, 69, 96,
+  76, 86, 110, 73, 79, 100, 95, 89, 89, 86,
+  98, 97, 74, 75, 71, 82, 83, 68, 86, 84,
+  89, 69, 81, 84, 84, 88, 95, 78, 84, 114,
+  83, 70, 91, 69, 89, 73, 73, 79, 62, 91,
+  90, 86, 90, 94, 79, 92, 83, 69, 82, 81,
+  86, 78, 80, 94, 83, 91, 91, 80, 93, 82,
+  87, 95, 89, 82, 102, 78, 84, 88, 88, 95,
+  98, 78, 75, 63, 79, 93, 87, 92, 98, 99,
+  71, 88, 100, 87, 91, 68, 79, 72, 88, 87,
+  84, 71, 81, 86, 94, 87, 88, 83, 64, 78,
+  87, 76, 87, 84, 104, 101, 88, 61, 83, 86,
+  75, 80, 68, 80, 68, 62, 95, 82, 92, 65,
+  59, 86, 60, 75, 91, 76, 62, 88, 74, 86,
+  88, 63, 81, 84, 104, 93, 73, 71, 100, 93,
+  70, 67, 69, 74, 79, 79, 84, 104, 100, 92,
+  77, 95, 79, 86, 98, 81, 76, 112, 85, 67,
+  66, 67, 90, 77, 85, 90, 55, 82, 74, 87,
+  70, 98, 77, 87, 79, 66, 90, 67, 81, 76,
+  83, 99, 79, 102, 91, 77, 81, 71, 73, 95,
+  83, 74, 95, 73, 89, 97, 86, 93, 71, 91,
+  80, 68, 78, 97, 81, 87, 72, 79, 71, 93,
+  87, 92, 83, 75, 82, 89, 99, 78, 70, 79,
+  85, 87, 84, 94, 84, 92, 74, 79, 79, 97,
+  89, 79, 83, 93, 88, 66, 76, 74, 76, 77,
+  71, 85, 78, 91, 84, 78, 97, 65, 80, 77,
+  73, 85, 87, 88, 77, 87, 83, 81, 97, 74,
+  84, 101, 90, 93, 83, 88, 85, 99, 74, 80,
+  77, 79, 79, 65, 88, 81, 93, 114, 80, 84,
+  82, 83, 93, 84, 86, 97, 79, 69, 88, 70,
+  91, 78, 91, 75, 68, 80, 92, 89, 90, 86,
+  77, 90, 86, 74, 95, 78, 82, 84, 93, 90,
+  95, 87, 89, 81, 71, 86, 87, 87, 86, 85,
+  99, 86, 86, 67, 75, 96, 79, 91, 84, 82,
+  73, 82, 80, 72, 88, 80, 78, 84, 79, 81,
+  82, 77, 85, 91, 83, 87, 78, 85, 76, 85,
+  72, 90, 81, 81, 88, 86, 71, 84, 61, 69,
+  85, 82, 75, 71, 72, 83, 78, 85, 78, 90,
+  79, 87, 73, 86, 77, 79, 83, 69, 72, 82,
+  87, 81, 82, 90, 82, 75, 77, 74, 85, 92,
+  73, 64, 83, 74, 97, 87, 85, 83, 72, 77,
+  76, 73, 81, 67, 86, 95, 78, 89, 100, 75,
+  73, 83, 93, 78, 86, 79, 73, 81, 80, 80,
+  86, 76, 82, 81, 75, 80, 74, 80, 83, 83,
+  80, 81, 75, 80, 82, 81, 71, 85, 85, 82,
+  73, 86, 84, 79, 93, 80, 90, 77, 84, 83,
+  95, 82, 75, 97, 82, 67, 74, 94, 77, 86,
+  90, 77, 86, 90, 74, 84, 71, 88, 92, 96,
+  64, 77, 74, 89, 87, 75, 94, 93, 148, 76,
+  105, 95, 79, 87, 77, 83, 98, 97, 81, 40,
+  91, 45, 65, 79, 75, 65, 104, 85, 71, 69,
+  101, 75, 69, 84, 87, 88, 68, 100, 96, 91,
+  89, 76, 105, 71, 72, 71, 93, 89, 80, 104,
+  63, 56, 99, 86, 87, 79, 80, 84, 105, 46,
+  79, 84, 72, 99, 79, 97, 88, 85, 118, 80,
+  88, 111, 85, 81, 100, 75, 88, 80, 86, 73,
+  91, 99, 85, 81, 87, 103, 81, 86, 87, 80,
+  82, 84, 82, 85, 86, 102, 79, 87, 79, 94,
+  93, 90, 96, 85, 75, 85, 101, 92, 87, 93,
+  82, 94, 76, 76, 83, 80, 74, 81, 79, 79,
+  89, 86, 80, 82, 79, 76, 83, 87, 75, 92,
+  89, 91, 84, 82, 82, 84, 105, 69, 87, 90,
+  84, 72, 79, 89, 70, 69, 81, 78, 78, 69,
+  76, 87, 81, 85, 83, 79, 75, 86, 77, 96,
+  74, 80, 90, 71, 70, 82, 92, 77, 79, 81,
+  80, 81, 73, 76, 86, 89, 80, 70, 81, 73,
+  97, 82, 86, 78, 79, 82, 83, 71, 82, 66,
+  88, 81, 79, 87, 86, 74, 86, 88, 86, 81,
+  87, 81, 80, 80, 81, 83, 71, 85, 78, 96,
+  78, 82, 74, 84, 82, 85, 80, 80, 91, 79,
+  79, 93, 76, 87, 86, 81, 79, 89, 82, 81,
+  85, 82, 88, 73, 84, 82, 85, 68, 98, 88,
+  82, 74, 85, 76, 73, 89, 77, 66, 87, 94,
+  81, 93, 85, 79, 71, 72, 82, 88, 81, 90,
+  87, 86, 86, 89, 117, 87, 89, 79, 79, 81,
+  80, 66, 84, 74, 98, 73, 83, 77, 80, 92,
+  78, 80, 82, 80, 77, 69, 90, 105, 89, 80,
+  81, 111, 73, 80, 84, 77, 80, 77, 75, 57,
+  75, 64, 74, 84, 87, 74, 92, 79, 88, 88,
+  86, 86, 71, 80, 67, 82, 76, 72, 86, 89,
+  81, 82, 98, 88, 93, 78, 77, 78, 91, 77,
+  84, 71, 86, 81, 87, 90, 80, 81, 75, 78,
+  72, 78, 72, 89, 76, 76, 87, 77, 79, 87,
+  91, 77, 72, 85, 93, 91, 86, 74, 89, 83,
+  88, 79, 86, 79, 87, 81, 89, 85, 85, 64,
+  81, 77, 73, 93, 81, 68, 94, 99, 79, 88,
+  76, 80, 81, 91, 67, 77, 77, 96, 90, 78,
+  94, 92, 159, 82, 118, 87, 69, 85, 85, 77,
+  109, 91, 95, 43, 95, 66, 73, 91, 75, 63,
+  103, 80, 63, 52, 116, 98, 82, 75, 82, 109,
+  69, 90, 102, 89, 92, 67, 88, 59, 82, 59,
+  83, 87, 92, 102, 93, 64, 83, 86, 94, 74,
+  77, 79, 89, 55, 73, 93, 71, 95, 83, 88,
+  88, 93, 119, 72, 69, 98, 92, 82, 92, 68,
+  90, 82, 93, 79, 83, 99, 82, 79, 89, 105,
+  84, 85, 81, 72, 91, 85, 71, 90, 102, 88,
+  82, 92, 101, 103, 91, 85, 86, 78, 77, 91,
+  95, 88, 78, 87, 85, 83, 81, 71, 83, 78,
+  73, 89, 78, 70, 91, 94, 82, 92, 86, 72,
+  76, 80, 82, 86, 86, 97, 83, 83, 85, 88,
+  118, 80, 90, 82, 82, 66, 78, 81, 89, 69,
+  88, 74, 86, 78, 76, 91, 83, 80, 84, 69,
+  73, 76, 94, 99, 85, 77, 88, 93, 71, 77,
+  90, 75, 78, 76, 71, 59, 71, 64, 80, 86,
+  88, 71, 98, 78, 93, 85, 88, 87, 79, 77,
+  68, 79, 78, 70, 88, 80, 77, 81, 85, 78,
+  89, 82, 79, 76, 88, 81, 80, 72, 85, 85,
+  74, 89, 77, 91, 77, 80, 70, 76, 76, 83,
+  75, 73, 92, 77, 76, 92, 87, 76, 87, 84,
+  93, 91, 77, 79, 92, 84, 87, 75, 85, 78,
+  82, 72, 87, 90, 84, 98, 84, 81, 81, 81,
+  80, 70, 91, 87, 79, 85, 75, 80, 85, 80,
+  83, 89, 85, 87, 81, 88, 84, 84, 81, 87,
+  81, 84, 88, 91, 85, 79, 83, 79, 76, 80,
+  82, 70, 78, 87, 73, 90, 79, 88, 82, 83,
+  75, 93, 76, 83, 84, 87, 80, 85, 80, 78,
+  81, 96, 74, 77, 86, 76, 67, 83, 86, 76,
+  74, 71, 83, 89, 84, 89, 74, 82, 66, 72,
+  81, 73, 90, 89, 81, 78, 96, 88, 75, 85,
+  96, 84, 89, 79, 84, 81, 84, 81, 80, 82,
+  85, 70, 80, 79, 67, 69, 79, 82, 83, 82,
+  83, 89, 86, 92, 77, 77, 93, 77, 73, 80,
+  81, 80, 91, 88, 92, 91, 79, 85, 84, 90,
+  73, 91, 86, 70, 80, 76, 88, 88, 84, 70,
+  92, 84, 78, 79, 68, 87, 94, 99, 75, 68,
+  78, 97, 87, 81, 92, 96, 137, 92, 102, 92,
+  91, 95, 95, 86, 98, 97, 78, 49, 93, 58,
+  79, 82, 79, 83, 99, 81, 77, 73, 100, 68,
+  69, 80, 89, 92, 79, 93, 97, 86, 88, 90,
+  87, 75, 82, 72, 78, 86, 97, 85, 72, 65,
+  86, 87, 89, 90, 83, 80, 85, 54, 81, 83,
+  75, 93, 75, 82, 84, 84, 100, 84, 96, 93,
+  97, 87, 89, 84, 88, 84, 92, 80, 91, 81,
+  89, 83, 90, 98, 96, 76, 91, 84, 82, 95,
+  80, 89, 80, 92, 91, 91, 82, 97, 94, 91,
+  95, 88, 83, 105, 96, 96, 78, 83, 80, 85,
+  79, 82, 77, 80, 82, 82, 83, 74, 95, 84,
+  80, 83, 77, 77, 90, 82, 78, 85, 91, 88,
+  82, 85, 79, 88, 95, 82, 83, 85, 87, 74,
+  87, 94, 88, 77, 83, 78, 87, 68, 81, 87,
+  79, 85, 80, 70, 81, 84, 78, 86, 73, 82,
+  91, 79, 78, 80, 84, 76, 79, 89, 73, 78,
+  82, 76, 77, 82, 86, 71, 94, 71, 87, 86,
+  82, 85, 77, 83, 62, 70, 80, 70, 90, 79,
+  76, 80, 80, 78, 78, 85, 91, 81, 88, 83,
+  81, 82, 87, 83, 75, 85, 82, 67, 81, 81,
+  67, 71, 80, 78, 73, 76, 85, 84, 83, 91,
+  71, 75, 85, 77, 79, 79, 75, 83, 88, 87,
+  87, 87, 81, 84, 84, 85, 78, 82, 98, 96,
+  82, 79, 79, 85, 79, 74, 87, 60, 88, 80,
+  78, 97, 79, 110, 85, 83, 83, 85, 76, 87,
+  73, 80, 93, 95, 114, 80, 72, 104, 79, 74,
+  74, 80, 74, 84, 70, 77, 86, 113, 66, 77,
+  84, 101, 80, 79, 90, 91, 92, 88, 79, 89,
+  84, 104, 93, 82, 100, 72, 87, 75, 90, 68,
+  89, 95, 85, 90, 76, 68, 75, 73, 77, 75,
+  83, 73, 85, 78, 108, 67, 69, 87, 92, 76,
+  85, 89, 113, 93, 78, 77, 85, 62, 86, 92,
+  85, 62, 79, 74, 69, 78, 89, 81, 84, 85,
+  80, 154, 84, 87, 83, 78, 77, 83, 112, 73,
+  89, 87, 86, 84, 87, 73, 81, 86, 102, 91,
+  83, 69, 82, 96, 76, 81, 101, 82, 85, 79,
+  74, 84, 80, 77, 99, 66, 93, 87, 80, 96,
+  80, 121, 84, 90, 79, 85, 82, 87, 72, 78,
+  86, 74, 118, 78, 71, 93, 77, 73, 69, 77,
+  71, 87, 75, 83, 86, 126, 71, 67, 85, 76,
+  73, 83, 90, 102, 101, 93, 77, 103, 82, 117,
+  95, 77, 96, 69, 87, 89, 77, 78, 96, 99,
+  87, 77, 85, 69, 68, 79, 81, 74, 80, 84,
+  83, 80, 112, 67, 72, 68, 94, 80, 80, 87,
+  119, 101, 74, 70, 86, 55, 76, 96, 83, 66,
+  82, 80, 64, 72, 88, 81, 86, 86, 79, 161,
+  86, 85, 89, 74, 79, 79, 112, 61, 77, 81,
+  84, 81, 85, 71, 75, 94, 109, 88, 81, 69,
+  83, 94, 80, 79, 100, 94, 76, 84, 79, 85,
+  82, 72, 87, 73, 88, 81, 78, 98, 82, 123,
+  80, 86, 87, 88, 84, 90, 82, 78, 86, 69,
+  107, 80, 75, 79, 81, 94, 83, 81, 65, 83,
+  74, 77, 84, 93, 69, 76, 80, 72, 81, 82,
+  94, 84, 89, 91, 89, 93, 84, 110, 92, 80,
+  100, 79, 88, 75, 86, 75, 103, 96, 79, 88,
+  97, 74, 80, 78, 80, 77, 86, 99, 92, 82,
+  107, 65, 75, 66, 86, 83, 81, 83, 113, 92,
+  82, 69, 86, 63, 87, 86, 90, 66, 80, 79,
+  72, 80, 81, 82, 84, 91, 82, 129, 86, 88,
+  80, 80, 81, 85, 91, 71, 82, 86, 82, 86,
+  78, 76, 75, 84, 95, 93, 79, 71, 91, 85,
+  81, 89, 72, 84, 82, 74, 85, 83, 87, 82,
+  85, 68, 87, 82, 85, 77, 77, 98, 78, 90,
+  77, 98, 78, 73, 69, 80, 79, 69, 98, 75,
+  77, 91, 82, 80, 88, 80, 81, 74, 83, 79,
+  86, 89, 72, 94, 74, 103, 82, 87, 77, 91,
+  101, 86, 86, 67, 73, 71, 90, 89, 106, 84,
+  77, 87, 72, 74, 102, 97, 82, 65, 73, 81,
+  71, 73, 73, 77, 94, 78, 70, 80, 90, 79,
+  83, 76, 74, 87, 85, 86, 105, 82, 70, 85,
+  84, 75, 87, 93, 87, 84, 80, 88, 58, 100,
+  82, 84, 85, 87, 79, 109, 83, 83, 92, 73,
+  79, 82, 92, 93, 77, 87, 78, 73, 89, 77,
+  82, 86, 90, 81, 85, 84, 95, 90, 78, 91,
+  73, 80, 86, 70, 82, 88, 91, 82, 80, 81,
+  86, 92, 85, 81, 80, 98, 84, 96, 83, 97,
+  81, 64, 76, 80, 77, 73, 88, 75, 80, 86,
+  82, 79, 89, 86, 80, 64, 96, 70, 84, 79,
+  81, 88, 75, 84, 82, 87, 83, 79, 105, 87,
+  86, 84, 83, 70, 91, 86, 112, 91, 78, 96,
+  63, 82, 108, 100, 83, 67, 77, 80, 70, 85,
+  69, 76, 93, 94, 70, 74, 88, 75, 83, 79,
+  65, 95, 80, 82, 87, 82, 70, 80, 81, 70,
+  85, 90, 88, 90, 78, 94, 62, 91, 75, 86,
+  90, 89, 77, 104, 84, 81, 82, 78, 77, 81,
+  80, 85, 85, 87, 77, 80, 84, 80, 79, 82,
+  70, 85, 86, 86, 86, 101, 78, 84, 79, 88,
+  79, 72, 79, 86, 87, 78, 95, 90, 84, 85,
+  80, 81, 78, 93, 82, 87, 85, 98, 87, 73,
+  78, 78, 76, 73, 90, 78, 78, 81, 73, 86,
+  84, 86, 78, 71, 87, 79, 77, 78, 79, 87,
+  75, 81, 87, 88, 80, 75, 94, 91, 87, 100,
+  77, 78, 89, 88, 109, 89, 81, 85, 75, 82,
+  114, 103, 77, 68, 87, 90, 75, 77, 72, 77,
+  95, 89, 71, 78, 92, 77, 85, 88, 75, 93,
+  81, 78, 95, 85, 71, 68, 85, 77, 84, 88,
+  87, 85, 79, 82, 63, 89, 80, 86, 88, 88,
+  87, 95, 88, 84, 75, 79, 81, 82, 68, 88,
+  87, 92, 83, 78, 73, 81, 79, 83, 83, 85,
+  83, 83, 89, 84, 83, 87, 57, 80, 86, 86,
+  89, 85, 91, 87, 82, 88, 78, 79, 91, 79,
+  79, 78, 85, 95, 78, 94, 81, 72, 85, 78,
+  94, 66, 78, 80, 85, 70, 73, 94, 99, 81,
+  89, 74, 87, 67, 81, 63, 86, 97, 80, 89,
+  98, 92, 70, 82, 89, 85, 88, 72, 80, 51,
+  76, 98, 100, 86, 79, 99, 74, 88, 88, 91,
+  94, 85, 73, 80, 82, 80, 74, 77, 95, 84,
+  87, 86, 73, 92, 84, 69, 64, 95, 83, 68,
+  75, 77, 77, 86, 77, 85, 94, 89, 91, 108,
+  90, 88, 69, 93, 79, 83, 89, 81, 79, 69,
+  75, 87, 89, 81, 90, 83, 72, 96, 87, 84,
+  80, 73, 93, 85, 82, 90, 87, 87, 90, 83,
+  85, 86, 76, 84, 62, 82, 85, 82, 97, 86,
+  93, 86, 67, 89, 80, 75, 92, 87, 83, 69,
+  91, 93, 84, 96, 85, 64, 93, 82, 92, 73,
+  73, 74, 85, 74, 80, 87, 100, 86, 88, 61,
+  90, 63, 83, 55, 90, 112, 85, 82, 104, 88,
+  81, 69, 88, 82, 89, 73, 93, 57, 77, 93,
+  97, 99, 81, 99, 69, 93, 84, 83, 84, 79,
+  73, 82, 87, 89, 68, 87, 101, 91, 87, 79,
+  71, 89, 89, 88, 59, 98, 86, 65, 69, 78,
+  79, 82, 77, 85, 96, 92, 88, 112, 88, 85,
+  80, 89, 74, 86, 89, 82, 85, 63, 78, 87,
+  82, 87, 90, 85, 68, 92, 91, 88, 78, 83,
+  93, 88, 83, 83, 77, 90, 93, 82, 81, 92,
+  81, 84, 61, 83, 87, 81, 86, 84, 92, 83,
+  85, 90, 76, 81, 88, 79, 78, 64, 85, 89,
+  79, 94, 87, 69, 87, 78, 92, 77, 82, 82,
+  82, 86, 72, 88, 94, 84, 87, 73, 90, 69,
+  79, 61, 89, 95, 82, 87, 106, 88, 72, 73,
+  87, 82, 88, 82, 79, 53, 81, 94, 99, 90,
+  83, 96, 78, 91, 86, 87, 85, 79, 82, 88,
+  82, 85, 63, 80, 89, 78, 85, 85, 76, 92,
+  87, 99, 64, 96, 85, 68, 72, 79, 78, 85,
+  84, 84, 97, 89, 89, 104, 79, 84, 74, 87,
+  81, 87, 89, 81, 86, 64, 77, 89, 82, 83,
+  90, 82, 65, 94, 83, 89, 83, 77, 80, 88,
+  82, 90, 80, 88, 89, 83, 83, 75, 81, 73,
+  90, 93, 88, 75, 91, 58, 95, 73, 88, 73,
+  79, 103, 71, 85, 96, 82, 73, 78, 84, 76,
+  90, 77, 81, 72, 92, 87, 98, 85, 93, 101,
+  94, 81, 89, 88, 81, 81, 81, 100, 87, 95,
+  77, 84, 99, 99, 82, 80, 81, 77, 81, 89,
+  84, 88, 75, 87, 74, 92, 95, 85, 84, 81,
+  91, 83, 71, 75, 86, 78, 80, 97, 73, 89,
+  86, 84, 68, 87, 78, 80, 86, 74, 85, 82,
+  85, 79, 75, 85, 91, 86, 67, 83, 84, 75,
+  76, 78, 76, 97, 77, 76, 80, 86, 85, 84,
+  87, 82, 85, 89, 77, 81, 87, 81, 86, 77,
+  82, 74, 89, 92, 86, 89, 84, 89, 88, 82,
+  80, 81, 97, 84, 85, 80, 85, 65, 95, 84,
+  91, 68, 79, 60, 95, 77, 87, 83, 79, 90,
+  72, 84, 99, 91, 78, 77, 82, 67, 86, 73,
+  82, 74, 89, 87, 105, 77, 90, 100, 92, 85,
+  79, 73, 89, 76, 77, 103, 79, 101, 82, 77,
+  89, 86, 73, 76, 79, 74, 76, 89, 80, 88,
+  76, 82, 76, 96, 98, 83, 83, 78, 82, 85,
+  77, 80, 83, 78, 86, 98, 67, 85, 92, 85,
+  59, 91, 73, 77, 90, 74, 87, 74, 93, 79,
+  79, 98, 85, 81, 64, 83, 92, 67, 71, 75,
+  79, 96, 85, 81, 72, 88, 88, 83, 63, 84,
+  94, 92, 83, 78, 83, 83, 91, 80, 88, 79,
+  86, 94, 86, 84, 77, 91, 83, 85, 78, 77,
+  94, 80, 86, 87, 93, 74, 92, 87, 86, 75,
+  86, 56, 92, 77, 83, 83, 80, 106, 74, 83,
+  96, 86, 84, 79, 89, 80, 79, 81, 87, 74,
+  86, 88, 91, 87, 95, 87, 92, 87, 87, 94,
+  79, 81, 81, 99, 79, 93, 86, 79, 90, 82,
+  81, 81, 82, 75, 77, 88, 88, 81, 77, 86,
+  74, 87, 95, 87, 87, 76, 94, 79, 76, 80,
+  88, 79, 84, 100, 79, 89, 97, 86, 71, 97,
+  77, 86, 86, 73, 89, 80, 83, 81, 78, 81,
+  89, 87, 70, 79, 84, 77, 74, 81, 84, 97,
+  92, 86, 85, 75, 86, 82, 79, 83, 78, 84,
+  81, 80, 83, 83, 84, 79, 85, 82, 85, 89,
+  82, 87, 77, 86, 82, 82, 83, 82, 91, 85,
+  82, 75, 73, 70, 78, 86, 94, 70, 97, 52,
+  89, 77, 77, 71, 82, 114, 73, 81, 81, 81,
+  78, 81, 87, 75, 90, 87, 82, 70, 91, 81,
+  95, 87, 101, 89, 92, 89, 78, 102, 82, 80,
+  73, 88, 83, 92, 74, 95, 98, 103, 83, 74,
+  86, 76, 80, 90, 88, 86, 78, 84, 83, 102,
+  87, 84, 82, 82, 98, 85, 75, 77, 100, 68,
+  96, 82, 77, 80, 87, 75, 76, 93, 80, 85,
+  83, 79, 79, 79, 82, 77, 69, 82, 83, 94,
+  61, 88, 77, 70, 66, 77, 90, 94, 86, 79,
+  79, 99, 88, 80, 88, 83, 86, 83, 81, 76,
+  87, 78, 80, 77, 76, 66, 79, 95, 82, 80,
+  83, 78, 80, 71, 83, 82, 90, 85, 83, 85,
+  84, 68, 83, 81, 94, 64, 89, 46, 86, 80,
+  84, 88, 86, 109, 82, 85, 82, 88, 77, 83,
+  80, 63, 81, 79, 79, 74, 93, 83, 102, 85,
+  114, 85, 91, 81, 70, 81, 88, 76, 75, 88,
+  83, 99, 77, 89, 105, 89, 74, 77, 91, 73,
+  77, 95, 83, 84, 81, 84, 79, 119, 90, 85,
+  83, 76, 77, 88, 88, 78, 98, 66, 73, 81,
+  61, 73, 97, 66, 82, 94, 66, 91, 89, 80,
+  81, 81, 85, 83, 75, 88, 76, 93, 60, 81,
+  87, 62, 53, 75, 96, 99, 88, 81, 71, 88,
+  91, 80, 76, 73, 96, 84, 88, 75, 88, 81,
+  85, 72, 76, 74, 78, 96, 97, 70, 78, 81,
+  78, 74, 87, 82, 96, 87, 78, 87, 104, 73,
+  83, 92, 92, 63, 89, 51, 85, 76, 77, 90,
+  85, 112, 74, 77, 80, 77, 80, 88, 89, 82,
+  78, 88, 86, 70, 83, 90, 88, 88, 95, 77,
+  81, 80, 76, 109, 78, 77, 79, 81, 85, 90,
+  81, 85, 95, 79, 83, 75, 85, 81, 78, 87,
+  87, 80, 82, 85, 80, 94, 91, 90, 84, 81,
+  99, 80, 86, 80, 92, 76, 72, 84, 76, 85,
+  90, 77, 79, 94, 70, 88, 86, 77, 80, 97,
+  79, 83, 78, 82, 81, 97, 62, 83, 80, 71,
+  69, 80, 91, 96, 83, 86, 83, 71, 87, 78,
+  83, 86, 82, 80, 85, 78, 80, 81, 78, 68,
+  79, 79, 98, 92, 87, 83, 78, 78, 78, 71,
+  83, 87, 87, 85, 78, 80, 86, 68, 67, 89,
+  92, 66, 105, 55, 75, 82, 78, 75, 83, 124,
+  71, 77, 71, 77, 95, 84, 82, 85, 101, 89,
+  95, 70, 91, 82, 76, 92, 98, 86, 91, 102,
+  84, 118, 80, 87, 83, 80, 84, 85, 76, 107,
+  93, 98, 92, 81, 78, 72, 85, 89, 90, 87,
+  80, 82, 98, 97, 77, 87, 88, 88, 109, 76,
+  78, 82, 94, 74, 99, 71, 104, 85, 81, 79,
+  81, 91, 86, 79, 80, 87, 80, 80, 78, 73,
+  66, 74, 91, 98, 64, 100, 78, 70, 73, 84,
+  87, 90, 92, 97, 84, 100, 83, 72, 83, 94,
+  79, 77, 74, 82, 83, 68, 67, 103, 77, 72,
+  71, 91, 85, 78, 79, 76, 88, 64, 82, 88,
+  88, 87, 77, 87, 92, 68, 61, 76, 90, 64,
+  117, 49, 68, 86, 87, 86, 86, 123, 79, 73,
+  58, 69, 88, 86, 80, 81, 89, 84, 99, 77,
+  93, 86, 64, 102, 111, 74, 87, 86, 81, 125,
+  77, 90, 84, 74, 90, 84, 74, 115, 109, 89,
+  82, 89, 78, 75, 79, 88, 88, 81, 78, 89,
+  88, 98, 75, 86, 85, 80, 96, 76, 86, 73,
+  100, 75, 82, 67, 91, 79, 84, 62, 97, 90,
+  73, 86, 80, 83, 74, 95, 68, 78, 72, 73,
+  86, 101, 53, 93, 77, 66, 60, 77, 87, 91,
+  107, 98, 83, 89, 80, 70, 95, 85, 82, 72,
+  71, 83, 79, 70, 64, 76, 77, 72, 84, 94,
+  105, 69, 83, 73, 84, 69, 87, 88, 89, 96,
+  77, 85, 93, 71, 72, 86, 92, 62, 98, 60,
+  75, 80, 84, 95, 88, 118, 78, 72, 71, 74,
+  86, 87, 93, 87, 87, 85, 95, 72, 89, 92,
+  76, 91, 93, 84, 74, 78, 79, 121, 80, 85,
+  87, 76, 98, 85, 80, 93, 85, 81, 93, 85,
+  79, 77, 84, 86, 87, 76, 75, 88, 93, 97,
+  81, 90, 89, 85, 97, 75, 81, 86, 87, 84,
+  70, 76, 97, 96, 80, 81, 80, 94, 78, 78,
+  84, 88, 69, 100, 76, 84, 97, 81, 88, 93,
+  63, 89, 82, 70, 74, 85, 86, 90, 95, 84,
+  84, 79, 84, 72, 80, 95, 86, 78, 77, 78,
+  73, 72, 69, 68, 77, 88, 102, 95, 85, 85,
+  83, 75, 89, 70, 84, 95, 88, 88, 93, 76,
+  88, 75, 77, 86, 89, 76, 83, 80, 82, 78,
+  77, 91, 91, 73, 89, 89, 70, 88, 80, 84,
+  96, 92, 74, 62, 85, 78, 94, 91, 82, 79,
+  90, 69, 87, 91, 82, 81, 98, 85, 92, 80,
+  91, 74, 85, 80, 92, 86, 63, 88, 92, 75,
+  89, 90, 88, 73, 71, 86, 80, 93, 80, 78,
+  83, 70, 88, 60, 88, 95, 67, 85, 74, 95,
+  77, 90, 69, 75, 75, 66, 88, 93, 80, 82,
+  82, 84, 66, 85, 93, 85, 62, 79, 86, 81,
+  82, 83, 90, 71, 74, 182, 87, 75, 72, 69,
+  82, 76, 95, 91, 65, 72, 82, 73, 92, 91,
+  82, 81, 74, 86, 82, 91, 86, 87, 90, 75,
+  73, 80, 97, 98, 86, 142, 100, 82, 77, 79,
+  82, 88, 89, 75, 83, 76, 84, 75, 81, 81,
+  86, 76, 85, 92, 76, 86, 87, 90, 85, 94,
+  73, 64, 87, 80, 88, 77, 81, 92, 82, 71,
+  99, 76, 80, 74, 88, 83, 81, 76, 86, 79,
+  77, 88, 91, 83, 66, 81, 80, 80, 96, 102,
+  93, 76, 74, 97, 80, 89, 80, 83, 80, 83,
+  83, 65, 85, 92, 69, 81, 75, 86, 83, 85,
+  71, 75, 72, 68, 97, 97, 84, 89, 82, 77,
+  63, 77, 84, 75, 68, 82, 90, 83, 80, 94,
+  91, 81, 83, 181, 90, 70, 67, 62, 81, 74,
+  90, 92, 65, 71, 86, 75, 92, 93, 87, 85,
+  76, 75, 74, 89, 82, 90, 86, 76, 72, 82,
+  108, 91, 87, 131, 89, 90, 75, 77, 83, 96,
+  87, 76, 86, 83, 81, 85, 84, 86, 91, 73,
+  88, 88, 72, 95, 88, 87, 80, 91, 73, 61,
+  87, 77, 83, 71, 76, 81, 93, 76, 97, 87,
+  84, 79, 85, 88, 85, 76, 93, 76, 85, 84,
+  87, 90, 71, 92, 89, 83, 87, 87, 83, 85,
+  72, 85, 88, 88, 79, 77, 83, 68, 96, 63,
+  93, 93, 68, 82, 90, 89, 77, 85, 74, 74,
+  79, 72, 99, 93, 81, 83, 88, 78, 71, 81,
+  84, 91, 64, 85, 88, 101, 82, 80, 94, 74,
+  75, 166, 86, 72, 72, 76, 81, 78, 92, 81,
+  69, 78, 86, 77, 91, 86, 83, 102, 66, 90,
+  80, 90, 88, 85, 72, 74, 73, 82, 92, 95,
+  88, 126, 88, 80, 75, 82, 80, 93, 90, 78,
+  88, 79, 82, 79, 87, 92, 86, 73, 89, 93,
+  78, 82, 84, 79, 89, 94, 78, 59, 89, 80,
+  93, 74, 86, 86, 96, 80, 68, 85, 71, 81,
+  93, 89, 79, 84, 95, 82, 78, 84, 94, 86,
+  64, 89, 99, 80, 90, 100, 86, 80, 74, 86,
+  73, 97, 74, 82, 83, 70, 85, 73, 81, 76,
+  87, 80, 88, 85, 80, 86, 72, 79, 77, 71,
+  81, 107, 80, 76, 83, 80, 75, 84, 97, 82,
+  65, 77, 84, 87, 74, 86, 94, 76, 77, 161,
+  89, 78, 69, 78, 78, 79, 87, 83, 78, 78,
+  78, 76, 86, 87, 83, 80, 63, 81, 81, 82,
+  85, 90, 84, 77, 70, 81, 97, 88, 91, 125,
+  81, 83, 75, 85, 79, 84, 91, 78, 91, 78,
+  83, 84, 85, 86, 83, 70, 86, 99, 86, 75,
+  88, 73, 86, 93, 82, 60, 89, 84, 90, 64,
+  90, 95, 91, 77, 68, 73, 64, 79, 94, 85,
+  78, 88, 91, 91, 74, 84, 97, 82, 66, 82,
+  93, 86, 96, 109, 89, 78, 75, 96, 79, 96,
+  77, 83, 84, 84, 82, 81, 82, 69, 88, 82,
+  74, 79, 80, 88, 73, 82, 71, 75, 78, 106,
+  86, 87, 78, 75, 71, 82, 84, 78, 68, 73,
+  89, 84, 76, 89, 81, 89, 86, 158, 92, 75,
+  67, 72, 82, 75, 81, 82, 82, 81, 74, 76,
+  89, 91, 88, 81, 69, 75, 75, 85, 88, 91,
+  79, 80, 70, 84, 109, 82, 92, 108, 88, 91,
+  84, 81, 79, 89, 85, 75, 88, 79, 81, 86,
+  80, 86, 86, 73, 89, 90, 76, 91, 87, 80,
+  92, 89, 77, 61, 85, 76, 87, 77, 84, 87,
+  94, 75, 89, 88, 77, 82, 95, 89, 84, 83,
+  92, 82, 82, 86, 91, 87, 73, 88, 99, 83,
+  89, 96, 85, 79, 76, 87, 78, 85, 72, 81,
+  84, 69, 91, 72, 86, 78, 82, 82, 84, 85,
+  78, 85, 76, 77, 79, 77, 82, 107, 80, 79,
+  89, 80, 79, 90, 83, 88, 65, 77, 85, 87,
+  76, 84, 91, 79, 80, 152, 84, 78, 74, 77,
+  78, 80, 86, 77, 73, 82, 78, 76, 91, 86,
+  86, 94, 71, 83, 85, 83, 89, 91, 78, 76,
+  70, 83, 93, 88, 92, 111, 87, 76, 75, 80,
+  87, 83, 91, 82, 85, 86, 82, 87, 78, 82,
+  93, 77, 97, 85, 71, 82, 84, 96, 79, 103,
+  79, 64, 99, 81, 87, 76, 90, 78, 104, 77,
+  88, 93, 87, 85, 91, 88, 94, 75, 95, 80,
+  85, 93, 91, 85, 68, 97, 93, 79, 86, 89,
+  81, 86, 74, 80, 71, 86, 66, 76, 83, 74,
+  91, 70, 86, 74, 87, 79, 95, 92, 78, 83,
+  74, 73, 81, 78, 92, 84, 85, 69, 90, 85,
+  77, 89, 96, 84, 71, 84, 79, 93, 79, 89,
+  97, 69, 70, 136, 78, 76, 82, 85, 88, 85,
+  82, 86, 80, 76, 75, 75, 85, 85, 89, 77,
+  66, 86, 73, 85, 83, 97, 85, 74, 71, 84,
+  81, 84, 91, 120, 82, 79, 76, 83, 90, 82,
+  92, 80, 81, 84, 85, 90, 74, 89, 95, 74,
+  92, 86, 75, 78, 85, 90, 81, 98, 77, 63,
+  96, 78, 87, 83, 91, 76, 96, 79, 78, 87,
+  86, 82, 91, 85, 95, 67, 92, 82, 82, 84,
+  86, 89, 67, 95, 86, 79, 86, 93, 78, 78,
+  70, 88, 74, 96, 71, 76, 87, 79, 94, 75,
+  94, 75, 83, 87, 75, 85, 76, 83, 74, 74,
+  77, 75, 89, 79, 87, 80, 88, 88, 73, 92,
+  85, 87, 67, 84, 84, 91, 76, 86, 93, 68,
+  75, 130, 76, 75, 88, 92, 92, 81, 78, 87,
+  91, 75, 74, 72, 84, 86, 86, 83, 75, 95,
+  79, 90, 86, 98, 94, 76, 73, 85, 82, 81,
+  88, 111, 86, 85, 88, 82, 86, 81, 88, 81,
+  90, 81, 83, 95, 74, 91, 90, 74, 98, 85,
+  74, 87, 89, 92, 86, 98, 81, 64, 95, 78,
+  81, 88, 88, 76, 101, 75, 90, 90, 89, 88,
+  87, 89, 91, 78, 89, 83, 83, 90, 92, 82,
+  77, 92, 91, 83, 88, 85, 79, 69, 80, 84,
+  75, 83, 68, 74, 85, 78, 86, 72, 89, 76,
+  87, 83, 72, 87, 73, 82, 75, 75, 80, 75,
+  78, 87, 86, 72, 94, 88, 83, 102, 77, 86,
+  77, 85, 83, 84, 77, 90, 87, 70, 73, 128,
+  84, 73, 81, 75, 84, 85, 83, 83, 78, 83,
+  81, 79, 92, 82, 87, 88, 78, 89, 85, 82,
+  84, 98, 90, 76, 73, 84, 84, 84, 89, 113,
+  118, 82, 96, 92, 92, 70, 80, 94, 82, 89,
+  82, 91, 79, 102, 72, 75, 88, 72, 92, 83,
+  84, 86, 83, 86, 103, 75, 88, 81, 85, 81,
+  75, 96, 79, 74, 66, 74, 96, 78, 77, 74,
+  84, 78, 82, 73, 74, 91, 98, 68, 90, 80,
+  86, 82, 88, 73, 78, 93, 73, 78, 80, 82,
+  89, 63, 91, 77, 49, 87, 94, 93, 85, 107,
+  64, 77, 78, 89, 92, 80, 83, 91, 80, 72,
+  79, 92, 94, 88, 79, 88, 79, 103, 97, 71,
+  76, 83, 62, 83, 81, 74, 90, 76, 76, 80,
+  78, 82, 82, 95, 75, 115, 99, 81, 84, 93,
+  90, 67, 84, 70, 94, 118, 106, 79, 67, 62,
+  80, 81, 67, 87, 85, 97, 73, 84, 115, 91,
+  81, 93, 90, 74, 82, 97, 75, 88, 80, 90,
+  70, 101, 72, 72, 90, 77, 81, 91, 85, 67,
+  86, 88, 82, 82, 87, 76, 94, 85, 69, 89,
+  71, 76, 72, 74, 98, 76, 81, 63, 84, 70,
+  81, 73, 76, 83, 100, 63, 84, 82, 87, 77,
+  91, 66, 78, 102, 88, 78, 79, 89, 85, 70,
+  98, 85, 63, 82, 76, 100, 71, 114, 86, 76,
+  79, 89, 100, 77, 87, 74, 99, 62, 74, 90,
+  80, 89, 78, 86, 69, 96, 94, 71, 81, 90,
+  71, 89, 85, 75, 82, 80, 81, 71, 77, 100,
+  74, 98, 72, 114, 108, 78, 85, 96, 84, 69,
+  80, 77, 101, 107, 91, 82, 61, 64, 72, 97,
+  62, 88, 83, 98, 69, 73, 119, 90, 67, 93,
+  90, 79, 83, 93, 82, 86, 85, 92, 85, 92,
+  75, 75, 82, 71, 89, 84, 91, 80, 77, 85,
+  84, 82, 87, 81, 83, 77, 68, 90, 80, 78,
+  79, 78, 90, 82, 92, 79, 87, 72, 86, 77,
+  75, 86, 94, 87, 89, 78, 86, 82, 92, 76,
+  81, 97, 79, 80, 82, 80, 88, 78, 93, 80,
+  57, 86, 73, 95, 87, 91, 96, 69, 79, 82,
+  99, 73, 86, 72, 92, 72, 85, 92, 88, 92,
+  77, 79, 69, 98, 91, 77, 79, 92, 62, 83,
+  79, 75, 90, 77, 94, 83, 79, 110, 81, 96,
+  80, 110, 99, 80, 84, 90, 70, 65, 79, 85,
+  80, 101, 77, 78, 68, 69, 81, 84, 81, 85,
+  90, 92, 72, 86, 93, 87, 84, 80, 78, 104,
+  75, 81, 87, 81, 76, 90, 94, 84, 85, 80,
+  82, 82, 77, 71, 85, 82, 75, 78, 104, 90,
+  72, 75, 83, 96, 72, 86, 85, 89, 80, 93,
+  80, 73, 81, 106, 79, 77, 77, 83, 74, 87,
+  85, 84, 80, 92, 69, 77, 90, 66, 76, 79,
+  70, 70, 83, 94, 76, 79, 76, 73, 76, 95,
+  74, 102, 79, 90, 80, 86, 87, 64, 88, 87,
+  80, 93, 71, 95, 81, 85, 85, 87, 84, 77,
+  84, 98, 77, 88, 93, 75, 74, 83, 77, 92,
+  79, 86, 93, 81, 75, 77, 74, 85, 81, 107,
+  92, 87, 79, 96, 82, 77, 89, 74, 79, 94,
+  103, 85, 84, 66, 88, 82, 80, 87, 93, 92,
+  73, 64, 78, 106, 70, 74, 73, 98, 84, 79,
+  82, 87, 72, 92, 88, 74, 86, 95, 74, 97,
+  78, 79, 86, 65, 90, 83, 90, 108, 72, 73,
+  87, 81, 81, 82, 85, 84, 86, 79, 78, 72,
+  71, 96, 73, 73, 78, 91, 61, 86, 89, 77,
+  61, 103, 68, 73, 90, 55, 76, 82, 82, 79,
+  83, 119, 72, 84, 71, 83, 82, 87, 76, 110,
+  64, 92, 71, 85, 87, 75, 99, 103, 91, 82,
+  91, 93, 83, 87, 74, 78, 88, 78, 71, 88,
+  80, 100, 94, 78, 95, 93, 72, 114, 72, 78,
+  100, 70, 71, 88, 68, 83, 92, 83, 105, 90,
+  75, 101, 81, 84, 85, 74, 82, 76, 84, 94,
+  98, 73, 80, 105, 74, 88, 102, 89, 82, 61,
+  98, 93, 83, 84, 77, 82, 79, 82, 88, 82,
+  79, 95, 94, 83, 87, 83, 74, 81, 78, 80,
+  88, 88, 97, 79, 89, 91, 75, 76, 81, 73,
+  73, 87, 85, 80, 94, 89, 77, 70, 78, 104,
+  80, 74, 87, 87, 78, 79, 85, 97, 72, 92,
+  76, 78, 88, 69, 78, 78, 76, 71, 81, 91,
+  77, 89, 80, 74, 85, 92, 80, 100, 81, 89,
+  88, 82, 87, 62, 91, 84, 81, 83, 84, 96,
+  84, 83, 84, 91, 81, 79, 73, 93, 76, 86,
+  89, 78, 75, 86, 78, 93, 81, 88, 93, 85,
+  80, 93, 74, 85, 83, 98, 99, 88, 80, 90,
+  79, 75, 89, 88, 77, 82, 85, 89, 87, 69,
+  79, 83, 82, 85, 93, 86, 74, 72, 96, 83,
+  85, 86, 82, 84, 73, 81, 89, 84, 83, 87,
+  82, 80, 87, 81, 85, 86, 77, 77, 90, 84,
+  80, 70, 95, 88, 85, 81, 79, 80, 77, 83,
+  88, 90, 85, 95, 90, 83, 84, 97, 88, 96,
+  97, 83, 81, 84, 80, 88, 85, 86, 69, 84,
+  77, 83, 75, 81, 77, 82, 83, 86, 83, 80,
+  81, 83, 84, 93, 82, 92, 84, 91, 94, 86,
+  86, 70, 78, 83, 85, 78, 71, 106, 84, 81,
+  87, 88, 86, 83, 75, 92, 80, 80, 89, 85,
+  81, 80, 81, 93, 94, 90, 94, 88, 85, 91,
+  81, 84, 76, 91, 74, 89, 85, 73, 79, 89,
+  89, 77, 80, 83, 80, 83, 95, 80, 87, 83,
+  93, 80, 94, 89, 84, 75, 85, 88, 87, 73,
+  72, 94, 75, 76, 83, 87, 85, 82, 79, 84,
+  84, 98, 83, 97, 74, 82, 92, 73, 88, 76,
+  81, 88, 86, 77, 79, 68, 79, 80, 84, 96,
+  79, 81, 95, 92, 80, 91, 86, 97, 93, 90,
+  69, 91, 85, 79, 77, 95, 72, 90, 72, 74,
+  73, 87, 88, 86, 88, 101, 82, 81, 81, 85,
+  88, 90, 86, 91, 81, 96, 89, 84, 93, 83,
+  87, 93, 86, 75, 73, 110, 86, 77, 78, 82,
+  86, 87, 72, 87, 82, 85, 88, 97, 94, 80,
+  81, 105, 84, 87, 92, 81, 80, 87, 75, 82,
+  76, 87, 76, 91, 79, 74, 86, 89, 81, 75,
+  90, 77, 85, 94, 101, 83, 78, 93, 85, 81,
+  94, 85, 86, 75, 91, 81, 87, 83, 84, 75,
+  74, 79, 90, 86, 87, 88, 85, 88, 87, 83,
+  84, 82, 77, 80, 95, 84, 81, 71, 89, 85,
+  83, 82, 76, 72, 74, 82, 87, 85, 87, 92,
+  92, 85, 86, 96, 87, 93, 91, 82, 79, 82,
+  80, 87, 81, 87, 75, 87, 75, 87, 73, 74,
+  74, 81, 85, 90, 85, 83, 84, 80, 87, 95,
+  93, 94, 91, 93, 83, 86, 91, 66, 82, 86,
+  84, 79, 71, 111, 83, 76, 87, 90, 84, 84,
+  78, 92, 77, 80, 89, 79, 82, 85, 83, 95,
+  94, 89, 88, 89, 85, 81, 79, 84, 74, 91,
+  76, 89, 86, 71, 85, 85, 89, 80, 81, 87,
+  93, 89, 97, 79, 75, 88, 97, 78, 93, 87,
+  82, 75, 88, 71, 68, 90, 86, 62, 84, 80,
+  73, 95, 79, 57, 84, 71, 77, 79, 66, 89,
+  95, 78, 96, 102, 104, 108, 106, 94, 83, 89,
+  90, 85, 88, 74, 92, 64, 46, 64, 65, 73,
+  105, 69, 74, 92, 61, 69, 87, 94, 91, 55,
+  92, 92, 79, 68, 86, 80, 104, 57, 78, 75,
+  81, 74, 118, 81, 75, 87, 44, 87, 167, 92,
+  90, 133, 15, 90, 85, 91, 86, 83, 96, 129,
+  53, 79, 77, 85, 89, 71, 78, 97, 78, 123,
+  57, 80, 85, 68, 95, 76, 83, 71, 87, 77,
+  94, 88, 60, 69, 86, 90, 93, 97, 90, 90,
+  95, 98, 85, 92, 87, 71, 65, 143, 119, 86,
+  104, 89, 96, 97, 88, 82, 102, 82, 83, 114,
+  80, 87, 86, 89, 86, 58, 80, 93, 84, 86,
+  84, 69, 73, 58, 78, 93, 81, 77, 78, 88,
+  79, 81, 78, 77, 87, 81, 83, 83, 101, 97,
+  84, 77, 74, 69, 55, 73, 103, 88, 103, 68,
+  98, 72, 79, 77, 80, 77, 83, 56, 80, 71,
+  90, 80, 90, 84, 84, 99, 79, 96, 81, 79,
+  87, 75, 109, 107, 79, 84, 83, 79, 82, 104,
+  72, 78, 98, 92, 78, 69, 83, 58, 104, 60,
+  83, 95, 79, 78, 81, 98, 63, 80, 78, 79,
+  87, 91, 86, 76, 90, 74, 85, 80, 91, 74,
+  85, 78, 82, 90, 80, 89, 79, 92, 91, 81,
+  90, 84, 80, 76, 97, 81, 57, 78, 84, 89,
+  82, 84, 86, 81, 94, 83, 75, 77, 83, 85,
+  108, 88, 83, 82, 79, 103, 89, 84, 75, 73,
+  81, 80, 73, 97, 87, 90, 85, 87, 84, 83,
+  87, 77, 78, 84, 89, 81, 90, 91, 79, 86,
+  74, 79, 62, 95, 77, 95, 81, 82, 94, 69,
+  73, 89, 85, 82, 82, 69, 75, 80, 90, 99,
+  91, 93, 75, 85, 81, 93, 82, 79, 80, 81,
+  104, 93, 100, 68, 70, 84, 75, 83, 84, 82,
+  88, 82, 78, 83, 88, 78, 92, 75, 94, 81,
+  80, 93, 84, 89, 82, 74, 92, 80, 80, 82,
+  84, 86, 79, 78, 84, 81, 84, 78, 87, 72,
+  83, 86, 81, 80, 89, 83, 79, 85, 87, 74,
+  80, 90, 88, 80, 84, 81, 78, 82, 93, 84,
+  83, 90, 89, 83, 79, 81, 90, 76, 91, 90,
+  73, 101, 77, 82, 72, 93, 81, 67, 102, 79,
+  70, 77, 75, 81, 86, 83, 86, 102, 109, 92,
+  99, 87, 71, 89, 102, 94, 78, 83, 84, 80,
+  81, 112, 82, 83, 97, 85, 86, 105, 81, 72,
+  92, 97, 81, 98, 84, 77, 84, 85, 80, 78,
+  77, 74, 72, 54, 83, 79, 93, 80, 76, 65,
+  66, 80, 104, 68, 93, 81, 92, 105, 79, 82,
+  88, 74, 81, 131, 46, 105, 78, 78, 91, 98,
+  74, 94, 88, 101, 61, 72, 96, 63, 84, 70,
+  85, 77, 79, 75, 87, 89, 73, 48, 78, 87,
+  78, 79, 87, 82, 71, 74, 84, 80, 74, 86,
+  63, 110, 103, 81, 93, 72, 91, 85, 90, 79,
+  103, 75, 80, 89, 97, 74, 46, 79, 78, 78,
+  90, 71, 75, 95, 83, 70, 88, 47, 75, 78,
+  74, 70, 77, 75, 81, 75, 79, 92, 95, 82,
+  87, 92, 84, 85, 85, 70, 82, 74, 78, 85,
+  92, 73, 123, 71, 80, 94, 88, 73, 85, 99,
+  75, 67, 82, 68, 83, 74, 99, 79, 86, 129,
+  68, 70, 79, 81, 100, 82, 89, 101, 71, 87,
+  101, 72, 93, 94, 106, 99, 80, 91, 77, 78,
+  76, 112, 96, 71, 83, 91, 84, 66, 77, 88,
+  75, 99, 72, 84, 84, 78, 87, 74, 92, 82,
+  77, 81, 107, 89, 82, 78, 87, 90, 96, 90,
+  85, 86, 94, 78, 70, 95, 79, 72, 72, 119,
+  76, 86, 88, 96, 95, 89, 90, 79, 92, 87,
+  90, 88, 83, 74, 79, 85, 82, 69, 79, 89,
+  76, 81, 83, 73, 66, 69, 78, 95, 77, 76,
+  77, 82, 70, 73, 81, 79, 78, 75, 96, 82,
+  84, 97, 89, 78, 77, 77, 76, 77, 80, 90,
+  85, 68, 97, 77, 82, 85, 87, 75, 81, 60,
+  78, 77, 91, 89, 93, 86, 79, 113, 80, 90,
+  87, 83, 86, 86, 103, 100, 89, 70, 75, 83,
+  91, 88, 96, 87, 82, 87, 82, 83, 80, 77,
+  110, 58, 88, 93, 77, 86, 82, 93, 73, 73,
+  91, 85, 79, 97, 81, 75, 83, 75, 82, 85,
+  94, 79, 94, 66, 87, 87, 88, 85, 78, 89,
+  90, 79, 80, 91, 80, 82, 82, 87, 69, 85,
+  73, 91, 84, 86, 84, 86, 79, 92, 81, 88,
+  75, 88, 108, 94, 75, 80, 76, 88, 78, 83,
+  82, 91, 88, 83, 61, 79, 75, 78, 84, 97,
+  83, 96, 87, 76, 88, 84, 78, 81, 97, 88,
+  74, 89, 80, 76, 78, 95, 83, 87, 67, 91,
+  91, 90, 84, 92, 82, 90, 87, 100, 83, 77,
+  92, 96, 79, 82, 69, 79, 87, 62, 86, 80,
+  80, 85, 91, 70, 92, 72, 80, 73, 82, 83,
+  101, 82, 82, 83, 89, 78, 75, 65, 67, 90,
+  84, 87, 72, 95, 75, 88, 83, 78, 79, 86,
+  99, 77, 84, 69, 77, 78, 82, 68, 77, 83,
+  85, 75, 76, 85, 79, 85, 84, 86, 75, 70,
+  92, 68, 78, 81, 79, 75, 72, 72, 88, 84,
+  83, 91, 90, 87, 97, 87, 72, 75, 87, 74,
+  78, 81, 78, 97, 83, 70, 77, 84, 81, 91,
+  99, 77, 80, 74, 79, 82, 81, 84, 90, 81,
+  87, 79, 83, 81, 82, 89, 84, 99, 77, 84,
+  88, 82, 74, 110, 79, 80, 85, 89, 79, 98,
+  97, 89, 79, 94, 75, 100, 88, 87, 76, 85,
+  88, 78, 75, 83, 73, 56, 83, 83, 84, 89,
+  80, 84, 97, 76, 84, 84, 87, 70, 129, 95,
+  85, 88, 77, 75, 75, 84, 72, 78, 87, 84,
+  88, 87, 79, 82, 88, 81, 71, 84, 90, 81,
+  87, 88, 84, 87, 81, 80, 92, 80, 84, 82,
+  85, 87, 74, 74, 83, 81, 69, 80, 77, 78,
+  74, 87, 77, 80, 78, 83, 90, 87, 87, 98,
+  84, 81, 92, 84, 87, 75, 84, 71, 71, 86,
+  86, 87, 82, 78, 76, 75, 83, 82, 89, 91,
+  85, 78, 73, 86, 79, 83, 86, 69, 79, 78,
+  82, 86, 91, 83, 85, 102, 91, 79, 90, 87,
+  84, 86, 82, 91, 83, 75, 79, 86, 90, 93,
+  75, 73, 82, 83, 89, 82, 78, 87, 87, 84,
+  81, 101, 77, 71, 91, 92, 88, 89, 83, 94,
+  90, 67, 79, 93, 84, 76, 94, 81, 84, 84,
+  81, 82, 72, 77, 94, 67, 85, 75, 85, 85,
+  85, 79, 86, 71, 78, 86, 83, 88, 83, 98,
+  77, 90, 83, 80, 95, 71, 85, 75, 88, 86,
+  83, 82, 82, 83, 82, 76, 75, 86, 82, 94,
+  80, 78, 79, 94, 76, 89, 84, 91, 83, 84,
+  83, 89, 86, 78, 93, 71, 93, 68, 69, 81,
+  82, 81, 73, 71, 81, 100, 89, 65, 84, 74,
+  82, 77, 56, 82, 83, 81, 77, 71, 80, 86,
+  72, 79, 103, 86, 95, 84, 85, 97, 87, 102,
+  80, 83, 78, 86, 80, 90, 89, 78, 101, 63,
+  80, 82, 106, 80, 72, 65, 75, 86, 68, 75,
+  86, 91, 69, 94, 87, 77, 87, 92, 84, 84,
+  76, 103, 96, 90, 96, 101, 74, 80, 91, 76,
+  76, 96, 86, 83, 79, 76, 68, 101, 110, 86,
+  86, 82, 72, 83, 75, 83, 90, 82, 80, 86,
+  87, 93, 93, 66, 82, 86, 79, 83, 98, 83,
+  85, 85, 71, 81, 94, 90, 66, 94, 88, 82,
+  78, 84, 85, 74, 87, 88, 75, 79, 60, 82,
+  77, 56, 81, 68, 79, 82, 80, 96, 76, 76,
+  83, 80, 86, 94, 77, 87, 72, 75, 79, 88,
+  78, 81, 88, 90, 67, 77, 70, 74, 84, 77,
+  90, 84, 88, 87, 101, 80, 77, 82, 75, 85,
+  66, 83, 80, 90, 72, 88, 91, 80, 77, 88,
+  89, 75, 84, 85, 71, 89, 82, 67, 89, 74,
+  71, 93, 86, 79, 77, 80, 68, 94, 71, 98,
+  100, 79, 67, 80, 83, 72, 88, 87, 85, 102,
+  84, 79, 80, 80, 70, 69, 86, 74, 89, 76,
+  65, 76, 91, 106, 75, 79, 88, 88, 88, 79,
+  92, 82, 71, 85, 88, 79, 89, 84, 88, 87,
+  76, 79, 84, 85, 75, 88, 97, 82, 89, 83,
+  88, 81, 100, 86, 85, 84, 65, 80, 84, 73,
+  85, 77, 83, 92, 93, 98, 82, 83, 88, 88,
+  91, 83, 89, 93, 75, 90, 80, 92, 100, 87,
+  72, 89, 74, 90, 78, 78, 91, 77, 76, 85,
+  78, 94, 99, 87, 69, 77, 96, 94, 87, 80,
+  89, 85, 78, 93, 91, 84, 79, 92, 70, 79,
+  79, 119, 86, 93, 109, 87, 80, 85, 97, 83,
+  82, 81, 84, 65, 78, 96, 76, 81, 78, 85,
+  71, 66, 101, 81, 81, 93, 90, 86, 85, 92,
+  101, 86, 91, 74, 67, 86, 80, 66, 110, 67,
+  79, 105, 80, 89, 87, 78, 75, 80, 77, 105,
+  64, 69, 91, 66, 86, 86, 87, 89, 94, 91,
+  70, 80, 88, 94, 99, 95, 93, 81, 91, 100,
+  111, 87, 102, 100, 98, 86, 98, 111, 94, 78,
+  84, 61, 71, 79, 95, 82, 67, 73, 78, 98,
+  92, 72, 91, 73, 91, 73, 49, 85, 94, 69,
+  74, 71, 78, 93, 63, 75, 118, 83, 105, 86,
+  77, 108, 88, 83, 72, 82, 74, 89, 97, 91,
+  94, 80, 92, 65, 75, 83, 105, 77, 75, 63,
+  72, 83, 65, 81, 80, 91, 78, 88, 96, 79,
+  84, 85, 70, 81, 79, 87, 83, 71, 88, 95,
+  68, 78, 86, 77, 75, 89, 80, 94, 77, 76,
+  65, 95, 100, 89, 87, 90, 76, 79, 69, 70,
+  99, 78, 67, 106, 84, 97, 91, 65, 72, 96,
+  83, 90, 91, 80, 85, 86, 73, 81, 92, 82,
+  65, 95, 83, 90, 74, 100, 88, 89, 88, 83,
+  79, 70, 59, 81, 75, 53, 75, 72, 68, 86,
+  86, 88, 82, 76, 76, 78, 81, 91, 78, 77,
+  81, 72, 90, 85, 75, 93, 108, 72, 71, 81,
+  72, 76, 73, 76, 101, 82, 82, 79, 94, 77,
+  75, 74, 69, 83, 86, 78, 88, 88, 71, 93,
+  86, 85, 72, 98, 93, 75, 81, 72, 66, 86,
+  70, 83, 82, 65, 72, 90, 88, 76, 80, 68,
+  53, 79, 71, 103, 93, 77, 83, 73, 72, 72,
+  97, 79, 83, 97, 77, 85, 77, 79, 68, 69,
+  92, 81, 92, 89, 59, 74, 82, 89, 73, 81,
+  88, 100, 84, 79, 88, 75, 74, 86, 86, 87,
+  84, 86, 85, 84, 75, 74, 73, 88, 75, 92,
+  72, 88, 81, 88, 82, 81, 101, 79, 79, 78,
+  66, 80, 78, 65, 78, 71, 71, 104, 98, 94,
+  66, 87, 100, 89, 98, 85, 92, 84, 77, 89,
+  83, 94, 114, 85, 80, 86, 74, 96, 77, 66,
+  106, 91, 79, 87, 61, 86, 108, 77, 79, 69,
+  84, 93, 83, 73, 79, 90, 71, 87, 81, 92,
+  85, 97, 65, 88, 77, 106, 88, 102, 111, 96,
+  87, 70, 101, 76, 74, 83, 90, 63, 69, 90,
+  69, 78, 84, 85, 71, 58, 119, 86, 82, 91,
+  89, 84, 83, 87, 96, 82, 104, 75, 69, 80,
+  83, 66, 106, 71, 81, 113, 80, 86, 105, 69,
+  85, 75, 81, 102, 75, 68, 93, 73, 77, 98,
+  85, 85, 100, 96, 66, 77, 96, 94, 81, 86,
+  89, 79, 79, 89, 119, 83, 102, 105, 91, 78,
+  93, 111, 88, 80, 86, 68, 79, 81, 91, 80,
+  76, 89, 83, 86, 96, 77, 86, 70, 81, 76,
+  69, 89, 83, 86, 70, 88, 74, 75, 86, 87,
+  87, 76, 90, 87, 89, 99, 81, 87, 83, 90,
+  63, 91, 90, 85, 84, 83, 88, 81, 80, 82,
+  90, 88, 78, 87, 73, 87, 83, 79, 84, 93,
+  87, 92, 93, 91, 78, 82, 93, 86, 81, 79,
+  96, 77, 91, 80, 82, 72, 81, 88, 90, 90,
+  78, 88, 78, 84, 77, 95, 78, 82, 86, 88,
+  91, 74, 84, 71, 97, 81, 86, 86, 89, 93,
+  84, 81, 72, 89, 94, 85, 84, 88, 90, 91,
+  93, 81, 83, 91, 72, 92, 83, 77, 98, 93,
+  90, 100, 104, 83, 85, 73, 73, 84, 86, 79,
+  85, 76, 60, 83, 86, 86, 86, 81, 85, 85,
+  83, 79, 84, 82, 80, 72, 80, 80, 73, 83,
+  92, 78, 67, 90, 70, 75, 84, 85, 84, 80,
+  86, 87, 90, 88, 73, 78, 82, 87, 87, 83,
+  97, 82, 80, 83, 84, 88, 78, 83, 97, 84,
+  79, 78, 70, 87, 79, 86, 86, 85, 77, 90,
+  88, 87, 83, 84, 69, 87, 72, 85, 99, 81,
+  94, 76, 72, 73, 83, 87, 87, 86, 91, 81,
+  84, 86, 68, 71, 90, 85, 84, 89, 79, 72,
+  92, 86, 82, 81, 93, 91, 83, 83, 86, 78,
+  81, 86, 90, 80, 84, 83, 81, 85, 86, 79,
+  75, 87, 69, 88, 84, 81, 96, 84, 87, 91,
+  98, 77, 90, 77, 74, 87, 82, 76, 90, 74,
+  66, 95, 92, 100, 74, 83, 93, 83, 90, 77,
+  94, 95, 71, 86, 82, 95, 88, 88, 80, 82,
+  69, 97, 83, 77, 93, 87, 77, 84, 80, 87,
+  95, 86, 82, 75, 92, 89, 87, 77, 86, 86,
+  86, 83, 86, 88, 89, 86, 80, 80, 71, 96,
+  88, 95, 109, 99, 88, 84, 87, 84, 68, 78,
+  89, 77, 77, 89, 67, 86, 83, 97, 87, 69,
+  90, 85, 87, 79, 83, 88, 90, 81, 93, 88,
+  83, 73, 91, 89, 82, 64, 97, 74, 81, 109,
+  84, 81, 106, 75, 78, 76, 87, 86, 76, 82,
+  88, 71, 85, 90, 74, 87, 95, 89, 77, 85,
+  84, 93, 96, 94, 85, 80, 84, 80, 98, 83,
+  93, 91, 85, 90, 91, 91, 85, 75, 86, 77,
+  82, 91, 91, 83, 86, 83, 84, 68, 74, 78,
+  72, 91, 82, 85, 89, 85, 81, 82, 90, 89,
+  80, 74, 78, 91, 93, 88, 84, 74, 89, 87,
+  68, 99, 85, 87, 83, 75, 85, 68, 90, 74,
+  81, 76, 96, 93, 84, 84, 101, 83, 73, 81,
+  78, 74, 89, 110, 86, 96, 79, 87, 67, 85,
+  96, 66, 84, 80, 84, 65, 87, 85, 92, 91,
+  81, 93, 80, 86, 84, 55, 93, 81, 78, 74,
+  75, 86, 86, 83, 99, 71, 95, 81, 77, 70,
+  83, 86, 87, 88, 84, 80, 78, 81, 80, 74,
+  89, 88, 110, 82, 83, 83, 93, 69, 75, 74,
+  72, 97, 92, 84, 74, 97, 89, 84, 80, 77,
+  85, 83, 75, 99, 80, 82, 77, 76, 83, 80,
+  96, 79, 92, 83, 93, 67, 71, 73, 79, 96,
+  83, 86, 92, 82, 82, 76, 79, 92, 76, 74,
+  74, 89, 81, 77, 83, 79, 89, 86, 73, 84,
+  86, 83, 80, 60, 85, 69, 85, 76, 89, 71,
+  103, 79, 91, 76, 104, 83, 68, 80, 77, 87,
+  105, 104, 90, 92, 73, 85, 63, 81, 83, 65,
+  86, 77, 81, 61, 76, 76, 95, 92, 84, 90,
+  79, 71, 86, 56, 98, 83, 82, 85, 71, 89,
+  77, 73, 99, 75, 90, 77, 78, 77, 77, 86,
+  94, 88, 84, 83, 80, 73, 76, 76, 85, 87,
+  112, 84, 88, 83, 97, 65, 76, 75, 77, 91,
+  72, 78, 70, 104, 74, 81, 62, 84, 81, 79,
+  67, 107, 81, 84, 82, 79, 84, 98, 91, 73,
+  90, 88, 76, 74, 79, 80, 72, 94, 83, 88,
+  84, 86, 86, 85, 89, 90, 83, 76, 80, 88,
+  86, 69, 80, 82, 89, 96, 86, 93, 86, 87,
+  88, 77, 83, 70, 86, 79, 80, 75, 93, 83,
+  82, 84, 90, 89, 77, 82, 82, 84, 88, 109,
+  92, 89, 77, 89, 70, 84, 99, 69, 90, 82,
+  80, 76, 82, 84, 87, 87, 82, 88, 83, 85,
+  94, 60, 91, 79, 83, 100, 82, 84, 81, 88,
+  96, 79, 97, 79, 74, 74, 77, 88, 86, 87,
+  83, 82, 88, 77, 83, 75, 90, 86, 105, 86,
+  85, 81, 97, 71, 81, 89, 77, 95, 80, 86,
+  77, 101, 71, 90, 80, 79, 81, 79, 77, 92,
+  80, 77, 84, 84, 82, 96, 88, 84, 81, 81,
+  89, 58, 69, 77, 64, 99, 81, 84, 89, 81,
+  67, 84, 87, 93, 78, 72, 89, 85, 95, 92,
+  86, 79, 83, 86, 81, 98, 86, 91, 82, 79,
+  87, 68, 86, 76, 75, 83, 99, 92, 86, 74,
+  105, 80, 79, 77, 77, 79, 88, 119, 80, 99,
+  81, 86, 64, 83, 88, 65, 83, 79, 87, 68,
+  93, 76, 106, 85, 84, 93, 77, 91, 90, 56,
+  102, 88, 86, 72, 74, 82, 85, 68, 111, 75,
+  105, 84, 67, 66, 87, 74, 85, 85, 89, 83,
+  70, 88, 83, 79, 90, 89, 108, 82, 87, 82,
+  88, 69, 85, 78, 77, 88, 99, 75, 77, 85,
+  93, 81, 92, 77, 86, 84, 80, 100, 75, 86,
+  74, 81, 82, 81, 106, 84, 80, 80, 98, 49,
+  64, 77, 75, 105, 79, 92, 95, 79, 71, 77,
+  80, 100, 74, 75, 92, 83, 98, 85, 87, 81,
+  92, 80, 85, 81, 84, 92, 79, 65, 85, 69,
+  77, 75, 86, 79, 107, 79, 96, 64, 122, 73,
+  72, 75, 70, 87, 103, 118, 78, 100, 76, 81,
+  58, 77, 78, 60, 88, 78, 83, 66, 85, 65,
+  110, 84, 87, 93, 82, 65, 90, 55, 105, 96,
+  91, 84, 72, 88, 78, 53, 125, 83, 108, 76,
+  70, 69, 83, 75, 93, 85, 84, 77, 65, 74,
+  79, 82, 86, 86, 115, 81, 106, 85, 101, 64,
+  85, 79, 78, 86, 77, 68, 72, 93, 83, 80,
+  71, 83, 78, 82, 73, 116, 74, 87, 81, 82,
+  83, 96, 83, 73, 82, 88, 81, 63, 74, 88,
+  68, 102, 81, 85, 86, 86, 80, 85, 89, 95,
+  82, 73, 88, 82, 83, 78, 85, 87, 83, 90,
+  91, 91, 86, 93, 88, 76, 87, 71, 74, 78,
+  76, 77, 96, 87, 88, 72, 98, 83, 79, 78,
+  74, 82, 85, 115, 85, 90, 80, 85, 68, 83,
+  87, 66, 95, 84, 84, 78, 89, 73, 99, 81,
+  89, 88, 83, 78, 97, 59, 98, 91, 86, 100,
+  82, 84, 80, 75, 107, 82, 101, 77, 65, 70,
+  76, 76, 84, 82, 83, 81, 77, 73, 83, 81,
+  91, 86, 108, 87, 89, 79, 91, 67, 89, 89,
+  86, 94, 82, 77, 79, 91, 74, 85, 90, 79,
+  81, 82, 83, 94, 87, 80, 80, 82, 84, 95,
+  89, 90, 79, 80, 94, 76, 74, 81, 63, 95,
+  86, 88, 83, 82, 68, 84, 89, 85, 78, 69,
+  78, 76, 80, 96, 80, 78, 78, 83, 93, 95,
+  93, 84, 86, 85, 85, 69, 84, 80, 67, 85,
+  84, 100, 79, 75, 94, 81, 81, 73, 80, 81,
+  79, 109, 86, 90, 85, 87, 68, 83, 86, 80,
+  84, 81, 86, 78, 87, 81, 95, 86, 100, 85,
+  81, 90, 87, 62, 95, 87, 83, 74, 84, 81,
+  88, 82, 98, 81, 95, 87, 68, 69, 84, 73,
+  85, 84, 85, 71, 79, 93, 86, 83, 89, 78,
+  102, 80, 81, 78, 81, 80, 91, 85, 70, 86,
+  97, 77, 82, 78, 85, 86, 88, 74, 82, 92,
+  83, 93, 83, 82, 68, 83, 86, 84, 99, 94,
+  71, 79, 105, 70, 66, 77, 75, 97, 79, 93,
+  92, 84, 70, 81, 81, 91, 80, 76, 82, 74,
+  75, 90, 80, 83, 83, 76, 91, 85, 84, 86,
+  82, 77, 83, 71, 73, 81, 73, 79, 91, 83,
+  84, 72, 109, 76, 72, 72, 74, 82, 87, 103,
+  87, 89, 82, 85, 64, 75, 79, 73, 96, 80,
+  83, 73, 87, 75, 97, 84, 102, 88, 80, 74,
+  78, 66, 96, 89, 85, 78, 84, 82, 83, 70,
+  104, 85, 100, 75, 69, 71, 80, 68, 92, 81,
+  73, 68, 64, 83, 82, 83, 83, 77, 111, 81,
+  94, 82, 89, 77, 95, 82, 66, 89, 84, 69,
+  77, 81, 80, 83, 85, 80, 78, 87, 76, 105,
+  84, 74, 82, 84, 86, 96, 85, 88, 80, 84,
+  88, 83, 76, 85, 67, 98, 85, 91, 87, 88,
+  82, 87, 89, 87, 90, 70, 79, 76, 77, 86,
+  82, 86, 77, 84, 96, 93, 91, 84, 88, 82,
+  86, 72, 72, 80, 72, 84, 86, 82, 82, 74,
+  91, 81, 80, 72, 76, 85, 80, 109, 89, 82,
+  85, 86, 72, 88, 83, 82, 98, 83, 84, 91,
+  91, 80, 92, 84, 101, 84, 83, 92, 87, 65,
+  92, 90, 88, 90, 88, 81, 85, 86, 95, 86,
+  96, 78, 67, 71, 81, 73, 87, 82, 73, 75,
+  82, 70, 87, 84, 91, 78, 103, 85, 83, 76,
+  81, 76, 94, 90, 79, 93, 83, 78, 82, 81,
+  78, 88, 83, 75, 78, 92, 82, 88, 83, 87,
+  116, 94, 88, 81, 94, 83, 87, 87, 65, 87,
+  81, 104, 76, 73, 78, 51, 93, 84, 80, 97,
+  73, 77, 90, 82, 91, 81, 96, 84, 106, 103,
+  79, 75, 71, 91, 97, 92, 77, 81, 82, 57,
+  85, 99, 63, 98, 77, 68, 74, 84, 91, 93,
+  81, 77, 80, 87, 74, 82, 101, 80, 82, 79,
+  78, 73, 88, 65, 75, 81, 88, 73, 74, 65,
+  86, 83, 75, 76, 89, 84, 89, 70, 93, 82,
+  80, 80, 74, 95, 88, 81, 95, 84, 78, 75,
+  92, 87, 84, 81, 79, 79, 79, 79, 81, 77,
+  91, 76, 82, 104, 93, 97, 85, 79, 81, 80,
+  74, 77, 91, 111, 104, 75, 86, 122, 88, 84,
+  92, 72, 93, 86, 67, 72, 73, 94, 92, 88,
+  82, 84, 99, 85, 81, 94, 67, 86, 75, 93,
+  76, 74, 74, 45, 78, 81, 96, 79, 80, 81,
+  82, 81, 85, 81, 95, 79, 106, 99, 77, 80,
+  75, 88, 90, 84, 89, 78, 88, 46, 94, 89,
+  64, 102, 73, 77, 71, 90, 93, 88, 80, 75,
+  87, 99, 84, 83, 119, 74, 77, 81, 75, 72,
+  87, 68, 65, 75, 79, 68, 104, 55, 88, 89,
+  72, 89, 83, 80, 102, 77, 96, 85, 80, 78,
+  62, 91, 91, 80, 91, 95, 73, 78, 95, 79,
+  92, 81, 74, 77, 86, 83, 74, 73, 84, 76,
+  95, 106, 101, 89, 72, 79, 73, 85, 76, 87,
+  92, 114, 94, 78, 88, 140, 82, 77, 95, 72,
+  93, 92, 63, 67, 91, 93, 71, 92, 87, 75,
+  97, 92, 83, 89, 69, 81, 95, 81, 81, 72,
+  76, 59, 95, 80, 93, 80, 90, 83, 88, 83,
+  90, 84, 91, 76, 96, 103, 82, 96, 76, 88,
+  98, 92, 99, 81, 83, 58, 80, 97, 68, 92,
+  76, 87, 73, 87, 93, 83, 82, 77, 83, 90,
+  73, 88, 104, 79, 84, 78, 85, 76, 84, 70,
+  73, 85, 83, 71, 107, 66, 89, 83, 75, 75,
+  83, 82, 98, 70, 94, 79, 78, 83, 74, 86,
+  83, 84, 86, 94, 80, 73, 88, 89, 90, 79,
+  80, 84, 85, 73, 79, 85, 93, 76, 87, 102,
+  99, 92, 87, 80, 68, 83, 74, 92, 92, 103,
+  86, 75, 88, 114, 73, 81, 99, 76, 94, 78,
+  70, 77, 71, 85, 88, 79, 89, 90, 106, 84,
+  75, 89, 86, 91, 80, 85, 84, 72, 77, 77,
+  85, 88, 94, 85, 72, 67, 84, 95, 82, 85,
+  84, 76, 97, 74, 84, 77, 78, 92, 77, 81,
+  75, 76, 81, 66, 81, 90, 81, 92, 73, 75,
+  93, 78, 81, 89, 75, 86, 79, 71, 83, 70,
+  93, 91, 79, 87, 69, 76, 86, 81, 79, 94,
+  85, 70, 73, 71, 96, 84, 89, 75, 75, 87,
+  81, 71, 87, 83, 75, 79, 81, 84, 90, 70,
+  81, 74, 99, 80, 95, 97, 73, 88, 89, 87,
+  84, 84, 76, 78, 80, 82, 84, 76, 95, 93,
+  102, 69, 82, 87, 90, 87, 88, 102, 111, 76,
+  94, 95, 85, 76, 78, 79, 78, 93, 73, 76,
+  66, 94, 75, 71, 90, 79, 112, 81, 73, 88,
+  92, 94, 81, 75, 79, 75, 79, 89, 86, 87,
+  102, 57, 73, 65, 83, 98, 70, 87, 83, 79,
+  104, 80, 83, 81, 77, 84, 66, 74, 74, 70,
+  76, 61, 100, 92, 87, 110, 76, 81, 95, 76,
+  80, 77, 64, 83, 84, 79, 88, 70, 81, 103,
+  75, 87, 69, 78, 68, 69, 76, 102, 77, 66,
+  84, 75, 93, 88, 93, 76, 70, 77, 83, 81,
+  86, 86, 82, 80, 81, 82, 89, 69, 72, 89,
+  96, 80, 83, 108, 76, 93, 87, 84, 79, 84,
+  70, 82, 71, 85, 101, 65, 103, 90, 105, 68,
+  88, 95, 90, 83, 83, 96, 99, 84, 104, 86,
+  74, 81, 81, 79, 71, 97, 74, 78, 78, 83,
+  75, 78, 85, 76, 104, 85, 81, 90, 87, 90,
+  80, 76, 84, 71, 76, 79, 88, 84, 85, 79,
+  85, 72, 86, 94, 77, 90, 81, 85, 86, 80,
+  84, 87, 79, 84, 73, 81, 80, 74, 84, 64,
+  89, 88, 82, 94, 80, 92, 92, 76, 87, 85,
+  73, 84, 80, 91, 86, 79, 97, 90, 76, 86,
+  76, 79, 89, 86, 77, 95, 81, 72, 97, 72,
+  95, 83, 88, 77, 72, 83, 89, 72, 87, 84,
+  75, 85, 79, 81, 87, 76, 81, 83, 101, 78,
+  93, 95, 81, 82, 89, 88, 78, 80, 79, 83,
+  79, 83, 87, 79, 101, 89, 98, 76, 80, 81,
+  86, 90, 86, 93, 89, 78, 93, 93, 69, 76,
+  84, 84, 79, 86, 76, 78, 85, 86, 87, 78,
+  88, 98, 94, 82, 75, 89, 82, 89, 80, 70,
+  85, 67, 64, 84, 93, 83, 82, 82, 77, 67,
+  86, 99, 85, 86, 86, 84, 77, 76, 88, 84,
+  79, 92, 86, 76, 83, 79, 74, 84, 75, 87,
+  97, 90, 90, 88, 97, 74, 74, 87, 71, 78,
+  81, 84, 76, 79, 70, 81, 89, 86, 85, 83,
+  91, 96, 86, 88, 83, 84, 91, 89, 94, 84,
+  97, 73, 66, 80, 84, 82, 78, 90, 80, 82,
+  92, 78, 83, 81, 78, 78, 82, 80, 83, 97,
+  73, 89, 95, 89, 81, 81, 85, 91, 82, 85,
+  81, 83, 96, 85, 100, 80, 91, 90, 90, 91,
+  77, 89, 99, 78, 90, 82, 84, 80, 60, 86,
+  76, 88, 84, 85, 81, 91, 90, 71, 91, 91,
+  91, 80, 71, 87, 89, 91, 92, 74, 86, 72,
+  73, 91, 93, 81, 82, 66, 80, 71, 84, 98,
+  80, 86, 78, 83, 75, 70, 99, 94, 86, 84,
+  79, 74, 74, 79, 74, 80, 79, 91, 106, 91,
+  90, 93, 97, 73, 74, 83, 64, 79, 78, 78,
+  77, 78, 58, 96, 90, 78, 80, 82, 81, 90,
+  86, 90, 81, 89, 87, 95, 84, 81, 97, 73,
+  62, 87, 74, 93, 77, 96, 84, 84, 98, 81,
+  86, 84, 74, 81, 83, 80, 73, 103, 74, 86,
+  97, 88, 84, 90, 86, 95, 76, 85, 78, 78,
+  110, 85, 103, 82, 100, 91, 83, 83, 80, 84,
+  99, 88, 94, 67, 75, 83, 67, 84, 77, 85,
+  80, 91, 88, 76, 86, 78, 87, 79, 96, 84,
+  76, 90, 82, 87, 79, 85, 87, 65, 67, 80,
+  91, 77, 78, 87, 91, 71, 79, 95, 81, 87,
+  76, 79, 79, 75, 84, 91, 87, 88, 81, 79,
+  71, 78, 79, 83, 82, 88, 96, 88, 93, 89,
+  97, 72, 78, 90, 72, 74, 82, 78, 77, 82,
+  76, 79, 89, 88, 85, 84, 94, 96, 81, 89,
+  83, 84, 90, 85, 93, 83, 92, 73, 70, 91,
+  82, 82, 78, 88, 76, 87, 90, 73, 91, 83,
+  79, 85, 81, 81, 81, 95, 80, 82, 96, 89,
+  88, 79, 83, 88, 82, 85, 80, 85, 97, 82,
+  97, 79, 94, 91, 86, 84, 85, 92, 94, 79,
+  94, 81, 75, 84, 70, 89, 78, 87, 85, 81,
+  77, 84, 87, 87, 79, 93, 81, 86, 92, 89,
+  92, 81, 83, 85, 64, 95, 86, 84, 89, 87,
+  69, 88, 83, 91, 85, 76, 85, 91, 83, 78,
+  81, 86, 86, 95, 83, 90, 90, 81, 85, 88,
+  74, 86, 68, 85, 83, 79, 86, 86, 74, 93,
+  86, 80, 89, 75, 94, 85, 83, 100, 89, 81,
+  85, 82, 76, 100, 84, 89, 89, 84, 86, 88,
+  82, 81, 91, 78, 80, 94, 78, 101, 81, 84,
+  74, 85, 90, 88, 84, 92, 80, 79, 94, 80,
+  92, 94, 93, 75, 93, 71, 77, 84, 76, 98,
+  98, 88, 88, 87, 77, 72, 64, 88, 81, 83,
+  63, 79, 82, 73, 81, 80, 84, 90, 75, 65,
+  85, 85, 77, 82, 94, 94, 88, 93, 78, 90,
+  91, 84, 83, 82, 90, 79, 83, 89, 83, 80,
+  82, 92, 67, 88, 88, 83, 70, 85, 74, 81,
+  79, 90, 81, 73, 81, 78, 83, 79, 78, 77,
+  84, 91, 81, 85, 82, 79, 86, 89, 68, 88,
+  73, 96, 96, 73, 82, 85, 64, 92, 81, 88,
+  90, 66, 91, 88, 77, 97, 93, 74, 87, 69,
+  78, 95, 93, 80, 92, 86, 83, 108, 85, 88,
+  90, 79, 75, 87, 70, 85, 79, 84, 81, 82,
+  88, 86, 89, 98, 79, 85, 99, 85, 84, 88,
+  91, 67, 92, 80, 73, 82, 79, 95, 95, 89,
+  82, 86, 62, 78, 73, 87, 79, 92, 68, 82,
+  75, 74, 81, 87, 89, 92, 71, 66, 85, 75,
+  74, 81, 96, 102, 79, 81, 78, 85, 88, 87,
+  81, 83, 76, 86, 92, 92, 89, 82, 84, 81,
+  63, 91, 86, 80, 85, 84, 67, 85, 91, 91,
+  84, 70, 85, 94, 75, 84, 84, 80, 86, 88,
+  83, 82, 89, 86, 88, 82, 78, 82, 69, 85,
+  88, 79, 87, 99, 69, 92, 84, 81, 89, 76,
+  93, 84, 78, 99, 87, 83, 87, 82, 78, 94,
+  81, 84, 90, 93, 80, 88, 85, 84, 96, 78,
+  80, 93, 81, 86, 81, 80, 79, 80, 81, 83,
+  85, 96, 77, 81, 94, 80, 90, 94, 92, 74,
+  95, 76, 78, 81, 84, 95, 100, 82, 87, 86,
+  73, 76, 61, 89, 80, 83, 66, 79, 79, 84,
+  83, 85, 89, 85, 72, 72, 88, 86, 80, 82,
+  92, 96, 85, 87, 77, 85, 102, 87, 86, 90,
+  91, 79, 74, 85, 76, 84, 82, 100, 67, 91,
+  84, 80, 64, 90, 74, 78, 78, 93, 83, 77,
+  86, 79, 106, 85, 92, 85, 80, 94, 88, 97,
+  84, 70, 82, 95, 77, 94, 100, 93, 89, 85,
+  80, 79, 80, 82, 81, 79, 90, 67, 73, 88,
+  83, 93, 89, 76, 89, 75, 69, 91, 84, 83,
+  80, 80, 77, 90, 81, 76, 92, 97, 78, 84,
+  83, 107, 80, 79, 84, 74, 89, 90, 79, 93,
+  84, 85, 89, 86, 74, 90, 92, 76, 70, 85,
+  85, 77, 75, 90, 87, 88, 81, 86, 87, 75,
+  78, 87, 80, 82, 76, 91, 70, 75, 86, 84,
+  85, 98, 80, 83, 79, 65, 68, 87, 91, 88,
+  71, 78, 73, 87, 84, 76, 80, 76, 104, 73,
+  61, 83, 73, 85, 75, 95, 69, 101, 82, 79,
+  32, 85, 97, 70, 66, 89, 70, 72, 76, 56,
+  125, 90, 105, 80, 78, 92, 88, 88, 65, 62,
+  87, 90, 92, 88, 100, 102, 112, 84, 67, 93,
+  72, 87, 83, 75, 87, 60, 60, 85, 80, 89,
+  99, 76, 86, 58, 66, 90, 77, 81, 81, 91,
+  69, 75, 75, 73, 101, 107, 72, 79, 80, 93,
+  84, 74, 97, 68, 78, 84, 78, 101, 86, 76,
+  93, 96, 64, 82, 86, 69, 64, 102, 75, 73,
+  71, 76, 79, 90, 63, 85, 97, 82, 91, 82,
+  69, 89, 87, 100, 64, 81, 79, 107, 82, 111,
+  77, 100, 80, 55, 61, 83, 80, 91, 64, 65,
+  75, 80, 84, 83, 81, 75, 90, 79, 70, 83,
+  75, 83, 87, 76, 73, 90, 84, 80, 55, 87,
+  100, 72, 83, 89, 78, 74, 84, 73, 105, 91,
+  101, 84, 78, 89, 88, 78, 80, 76, 96, 90,
+  90, 89, 79, 97, 96, 90, 81, 108, 78, 80,
+  84, 81, 88, 71, 67, 90, 77, 88, 91, 78,
+  86, 70, 67, 88, 89, 82, 80, 91, 71, 77,
+  92, 74, 99, 96, 74, 77, 83, 87, 79, 78,
+  90, 74, 78, 80, 79, 94, 79, 83, 92, 88,
+  69, 91, 84, 77, 82, 96, 82, 76, 78, 86,
+  86, 86, 77, 84, 94, 86, 75, 90, 75, 84,
+  89, 91, 72, 89, 85, 92, 88, 90, 77, 92,
+  82, 62, 69, 82, 90, 88, 72, 73, 89, 91,
+  86, 90, 82, 73, 79, 76, 79, 81, 80, 83,
+  88, 93, 72, 84, 76, 87, 90, 89, 86, 90,
+  95, 86, 82, 81, 88, 89, 74, 87, 88, 93,
+  81, 87, 78, 111, 83, 80, 85, 85, 83, 81,
+  92, 84, 95, 86, 84, 84, 83, 80, 85, 70,
+  80, 86, 73, 81, 91, 89, 82, 78, 81, 80,
+  88, 86, 74, 82, 62, 89, 78, 81, 86, 84,
+  103, 102, 88, 89, 89, 98, 73, 71, 90, 75,
+  82, 89, 81, 92, 80, 88, 81, 84, 71, 79,
+  93, 87, 65, 83, 92, 81, 79, 82, 86, 85,
+  79, 81, 81, 86, 83, 92, 87, 80, 93, 99,
+  74, 87, 74, 80, 82, 89, 85, 85, 78, 74,
+  67, 83, 91, 83, 78, 83, 83, 87, 77, 77,
+  84, 77, 87, 70, 67, 78, 78, 82, 77, 89,
+  74, 90, 69, 100, 78, 87, 102, 82, 73, 74,
+  71, 75, 91, 72, 106, 89, 103, 95, 75, 89,
+  85, 106, 71, 87, 92, 66, 101, 80, 105, 98,
+  105, 100, 72, 98, 93, 67, 82, 64, 73, 83,
+  61, 85, 92, 80, 68, 75, 72, 81, 98, 90,
+  73, 76, 60, 96, 68, 66, 86, 88, 105, 117,
+  81, 75, 91, 98, 79, 62, 96, 74, 80, 91,
+  80, 94, 83, 82, 78, 88, 78, 73, 82, 89,
+  59, 96, 91, 76, 76, 66, 81, 78, 75, 78,
+  120, 80, 88, 94, 81, 68, 122, 113, 73, 80,
+  71, 84, 85, 104, 83, 104, 77, 68, 55, 75,
+  80, 75, 80, 74, 88, 73, 77, 88, 83, 89,
+  79, 76, 75, 78, 83, 82, 88, 76, 75, 83,
+  75, 88, 92, 85, 94, 87, 67, 81, 79, 81,
+  88, 79, 74, 87, 88, 104, 79, 92, 82, 88,
+  76, 84, 90, 77, 92, 83, 81, 88, 92, 88,
+  84, 98, 87, 72, 87, 71, 77, 93, 73, 86,
+  92, 87, 76, 82, 77, 87, 95, 89, 76, 84,
+  69, 97, 75, 72, 85, 83, 104, 100, 78, 87,
+  87, 89, 73, 73, 95, 77, 80, 89, 84, 93,
+  89, 94, 78, 83, 74, 81, 87, 91, 79, 86,
+  92, 82, 82, 84, 84, 83, 78, 77, 92, 88,
+  80, 91, 86, 78, 107, 93, 77, 83, 78, 84,
+  92, 87, 82, 85, 74, 74, 72, 78, 96, 76,
+  78, 78, 94, 63, 81, 85, 83, 73, 71, 77,
+  88, 83, 91, 81, 83, 72, 85, 68, 73, 81,
+  85, 101, 81, 82, 85, 71, 95, 89, 87, 83,
+  93, 89, 78, 86, 80, 83, 72, 81, 80, 79,
+  90, 73, 85, 78, 77, 89, 92, 73, 77, 67,
+  79, 82, 69, 88, 84, 80, 85, 79, 73, 84,
+  74, 79, 99, 75, 88, 82, 92, 74, 69, 88,
+  88, 76, 73, 100, 85, 78, 84, 110, 95, 71,
+  78, 76, 81, 88, 85, 100, 103, 81, 89, 84,
+  86, 89, 74, 91, 85, 80, 84, 83, 78, 83,
+  80, 75, 87, 75, 86, 89, 84, 81, 76, 102,
+  81, 107, 83, 83, 94, 79, 77, 91, 81, 69,
+  70, 70, 88, 95, 88, 98, 98, 98, 90, 74,
+  97, 72, 68, 85, 88, 74, 72, 77, 83, 89,
+  98, 78, 81, 82, 83, 66, 76, 86, 93, 105,
+  79, 83, 83, 74, 89, 96, 84, 84, 86, 81,
+  80, 84, 73, 92, 76, 79, 76, 72, 77, 67,
+  79, 76, 80, 88, 95, 73, 70, 67, 83, 74,
+  59, 80, 79, 76, 94, 74, 79, 92, 67, 81,
+  111, 87, 90, 85, 89, 79, 61, 98, 95, 84,
+  72, 105, 94, 80, 91, 116, 94, 72, 86, 77,
+  78, 84, 80, 87, 120, 71, 78, 94, 85, 93,
+  72, 100, 92, 91, 93, 88, 78, 78, 86, 74,
+  93, 87, 89, 92, 83, 85, 77, 99, 87, 102,
+  80, 88, 97, 85, 83, 94, 65, 75, 69, 67,
+  83, 91, 77, 96, 97, 96, 98, 71, 91, 83,
+  64, 84, 83, 90, 73, 77, 93, 84, 81, 80,
+  84, 92, 86, 67, 73, 78, 81, 91, 86, 90,
+  76, 73, 76, 86, 93, 85, 95, 69, 72, 82,
+  85, 84, 79, 88, 72, 90, 81, 79, 84, 85,
+  86, 86, 86, 65, 79, 85, 76, 82, 75, 84,
+  84, 86, 88, 79, 79, 77, 77, 76, 91, 74,
+  90, 70, 87, 75, 67, 85, 93, 77, 83, 89,
+  85, 76, 85, 95, 94, 83, 85, 78, 79, 88,
+  90, 88, 93, 73, 86, 80, 88, 89, 78, 90,
+  84, 81, 84, 83, 76, 82, 86, 76, 81, 75,
+  86, 88, 87, 87, 87, 93, 82, 108, 84, 81,
+  92, 99, 73, 83, 76, 73, 75, 77, 91, 93,
+  91, 90, 90, 93, 88, 86, 97, 66, 70, 84,
+  89, 84, 79, 90, 85, 97, 105, 78, 69, 81,
+  83, 73, 90, 85, 92, 110, 76, 76, 87, 77,
+  90, 86, 81, 84, 82, 84, 68, 70, 76, 102,
+  89, 78, 78, 71, 75, 65, 88, 93, 85, 82,
+  93, 71, 86, 79, 81, 85, 70, 88, 75, 79,
+  85, 74, 82, 92, 75, 95, 98, 71, 71, 86,
+  99, 75, 60, 96, 92, 74, 87, 120, 76, 76,
+  87, 118, 99, 80, 76, 91, 77, 82, 77, 101,
+  102, 69, 97, 82, 83, 73, 76, 74, 77, 100,
+  101, 103, 85, 72, 88, 77, 93, 90, 93, 94,
+  83, 84, 75, 100, 76, 96, 75, 79, 102, 81,
+  72, 94, 82, 85, 70, 70, 82, 98, 83, 103,
+  111, 71, 110, 74, 101, 71, 77, 89, 95, 85,
+  80, 87, 81, 117, 118, 75, 74, 76, 82, 75,
+  96, 81, 105, 125, 78, 75, 85, 81, 94, 93,
+  76, 86, 72, 93, 80, 72, 63, 107, 85, 81,
+  76, 77, 82, 57, 87, 101, 77, 85, 101, 73,
+  76, 74, 92, 81, 53, 90, 69, 71, 94, 76,
+  85, 96, 67, 95, 111, 75, 64, 95, 88, 85,
+  63, 109, 91, 82, 70, 137, 77, 73, 96, 125,
+  109, 85, 77, 96, 73, 78, 71, 81, 126, 72,
+  74, 97, 83, 76, 70, 73, 84, 113, 97, 112,
+  88, 58, 88, 76, 91, 89, 107, 95, 84, 87,
+  72, 103, 80, 88, 76, 78, 112, 79, 77, 103,
+  73, 95, 71, 72, 77, 97, 72, 112, 106, 68,
+  123, 70, 92, 73, 86, 83, 81, 99, 79, 85,
+  94, 90, 89, 76, 70, 79, 79, 74, 84, 84,
+  81, 103, 86, 82, 82, 75, 78, 79, 84, 82,
+  84, 86, 64, 73, 84, 79, 83, 93, 76, 78,
+  84, 73, 86, 92, 75, 81, 89, 71, 95, 84,
+  80, 86, 75, 91, 76, 82, 90, 73, 81, 80,
+  80, 81, 89, 71, 76, 64, 93, 79, 71, 94,
+  91, 80, 72, 104, 85, 76, 88, 105, 100, 93,
+  72, 87, 77, 82, 81, 93, 87, 81, 85, 82,
+  81, 79, 82, 78, 79, 82, 87, 92, 82, 77,
+  87, 77, 91, 72, 88, 92, 81, 86, 81, 89,
+  78, 100, 84, 79, 96, 98, 70, 95, 86, 84,
+  74, 74, 92, 96, 88, 94, 99, 78, 99, 90,
+  91, 76, 68, 86, 80, 71, 83, 101, 94, 85,
+  86, 84, 69, 88, 84, 79, 85, 82, 81, 89,
+  84, 88, 67, 70, 78, 80, 96, 82, 86, 73,
+  64, 75, 89, 84, 90, 85, 75, 76, 81, 71,
+  91, 77, 81, 82, 78, 75, 88, 89, 73, 93,
+  78, 90, 80, 93, 88, 73, 78, 90, 86, 84,
+  88, 73, 83, 86, 95, 76, 71, 84, 93, 81,
+  89, 84, 85, 74, 80, 94, 85, 72, 94, 72,
+  80, 87, 87, 86, 95, 76, 88, 70, 82, 87,
+  80, 80, 72, 83, 98, 79, 82, 86, 94, 79,
+  88, 90, 90, 95, 91, 77, 69, 88, 67, 95,
+  75, 88, 90, 80, 84, 78, 73, 75, 72, 82,
+  80, 97, 90, 86, 98, 81, 97, 81, 93, 76,
+  77, 83, 82, 69, 85, 95, 90, 88, 90, 82,
+  70, 82, 87, 79, 93, 83, 88, 94, 85, 81,
+  71, 73, 81, 83, 95, 80, 80, 93, 70, 71,
+  91, 80, 84, 80, 70, 72, 89, 62, 102, 72,
+  83, 83, 90, 85, 86, 74, 78, 95, 66, 89,
+  76, 86, 91, 77, 82, 91, 80, 87, 98, 84,
+  83, 90, 79, 79, 80, 97, 85, 95, 69, 84,
+  89, 71, 77, 95, 89, 74, 94, 69, 77, 84,
+  82, 86, 103, 88, 75, 80, 82, 94, 85, 79,
+  79, 89, 100, 83, 85, 87, 83, 76, 91, 77,
+  93, 96, 90, 80, 73, 88, 73, 98, 78, 99,
+  94, 78, 81, 95, 71, 77, 72, 88, 88, 96,
+  82, 89, 99, 87, 102, 85, 84, 84, 94, 84,
+  87, 76, 83, 88, 103, 80, 85, 79, 75, 75,
+  76, 79, 81, 77, 79, 90, 81, 94, 76, 74,
+  79, 82, 92, 80, 88, 95, 72, 73, 88, 73,
+  74, 85, 81, 78, 91, 76, 86, 78, 80, 82,
+  79, 74, 95, 78, 77, 94, 83, 96, 81, 94,
+  89, 81, 80, 87, 89, 82, 87, 71, 79, 75,
+  88, 81, 86, 78, 86, 84, 66, 82, 84, 73,
+  79, 88, 86, 88, 73, 77, 80, 90, 87, 97,
+  87, 93, 73, 78, 87, 87, 82, 79, 74, 79,
+  88, 80, 80, 86, 87, 81, 89, 70, 88, 92,
+  94, 85, 80, 87, 77, 97, 83, 81, 89, 81,
+  82, 88, 82, 75, 75, 84, 95, 96, 89, 82,
+  98, 87, 89, 85, 72, 84, 82, 82, 83, 88,
+  82, 71, 89, 65, 76, 69, 90, 83, 85, 68,
+  81, 79, 81, 81, 72, 92, 90, 94, 78, 79,
+  93, 65, 81, 80, 81, 89, 83, 88, 92, 77,
+  90, 101, 86, 75, 87, 92, 83, 69, 72, 80,
+  93, 89, 83, 70, 85, 98, 94, 112, 84, 73,
+  86, 80, 68, 89, 81, 96, 82, 67, 76, 100,
+  69, 76, 97, 81, 72, 89, 87, 73, 98, 80,
+  78, 103, 84, 88, 87, 91, 78, 82, 76, 78,
+  117, 79, 98, 84, 57, 86, 83, 98, 82, 83,
+  80, 74, 87, 86, 76, 82, 73, 79, 77, 76,
+  88, 84, 81, 96, 92, 83, 94, 77, 83, 73,
+  78, 87, 78, 103, 85, 90, 77, 79, 92, 105,
+  95, 94, 74, 87, 83, 89, 82, 89, 84, 75,
+  83, 79, 73, 81, 90, 79, 82, 81, 84, 73,
+  78, 87, 57, 90, 68, 83, 95, 80, 92, 80,
+  80, 82, 71, 100, 88, 85, 76, 64, 92, 97,
+  93, 80, 78, 86, 97, 81, 79, 79, 96, 80,
+  87, 72, 84, 95, 90, 96, 84, 78, 85, 77,
+  75, 89, 90, 88, 82, 60, 67, 81, 73, 90,
+  87, 83, 79, 88, 85, 66, 90, 77, 82, 98,
+  74, 87, 88, 88, 78, 83, 78, 75, 102, 78,
+  88, 80, 65, 83, 85, 95, 72, 73, 85, 85,
+  77, 73, 65, 78, 81, 82, 73, 88, 89, 86,
+  94, 85, 86, 79, 87, 65, 80, 89, 76, 93,
+  70, 87, 79, 83, 89, 86, 84, 88, 76, 93,
+  83, 79, 84, 82, 83, 89, 83, 81, 84, 93,
+  79, 93, 78, 78, 65, 87, 90, 68, 77, 93,
+  72, 83, 69, 83, 98, 86, 90, 87, 71, 74,
+  71, 97, 86, 87, 74, 64, 94, 80, 82, 82,
+  79, 76, 94, 84, 95, 76, 98, 92, 80, 80,
+  84, 88, 88, 80, 83, 84, 82, 86, 85, 88,
+  93, 88, 85, 66, 78, 80, 69, 110, 82, 85,
+  85, 88, 91, 71, 78, 85, 92, 90, 77, 76,
+  88, 85, 90, 86, 92, 73, 106, 87, 88, 79,
+  80, 94, 100, 91, 87, 81, 78, 91, 80, 73,
+  73, 92, 95, 85, 69, 104, 94, 86, 85, 78,
+  89, 85, 80, 64, 87, 100, 82, 102, 82, 84,
+  80, 80, 86, 91, 82, 84, 66, 84, 77, 83,
+  88, 85, 92, 84, 84, 84, 90, 65, 76, 71,
+  90, 81, 85, 80, 77, 78, 86, 81, 70, 85,
+  74, 94, 79, 81, 93, 70, 107, 84, 83, 93,
+  88, 87, 80, 74, 81, 102, 96, 75, 77, 87,
+  90, 69, 79, 87, 88, 84, 85, 74, 82, 98,
+  88, 109, 89, 80, 77, 88, 62, 78, 80, 89,
+  81, 67, 66, 95, 84, 69, 99, 75, 76, 74,
+  95, 81, 96, 77, 76, 101, 79, 90, 86, 83,
+  71, 93, 81, 87, 118, 87, 93, 82, 57, 87,
+  70, 99, 80, 80, 90, 86, 75, 87, 71, 78,
+  73, 82, 84, 81, 86, 78, 82, 97, 98, 90,
+  95, 73, 72, 69, 73, 78, 76, 85, 84, 91,
+  76, 70, 92, 96, 98, 92, 72, 86, 90, 85,
+  86, 90, 89, 81, 80, 80, 72, 83, 85, 78,
+  81, 87, 80, 76, 85, 88, 59, 94, 58, 78,
+  99, 83, 91, 83, 106, 77, 70, 100, 87, 83,
+  73, 61, 82, 91, 94, 78, 82, 91, 103, 82,
+  79, 87, 87, 77, 85, 72, 85, 100, 85, 88,
+  93, 81, 83, 75, 80, 86, 86, 85, 80, 54,
+  56, 73, 82, 90, 83, 85, 74, 77, 91, 74,
+  85, 76, 83, 116, 66, 86, 81, 84, 78, 96,
+  87, 81, 112, 83, 78, 82, 67, 78, 83, 96,
+  76, 74, 88, 90, 65, 74, 64, 72, 82, 84,
+  74, 96, 90, 83, 92, 79, 94, 86, 85, 60,
+  74, 86, 80, 89, 78, 81, 75, 76, 88, 80,
+  83, 81, 71, 85, 78, 72, 77, 70, 80, 95,
+  91, 81, 81, 94, 77, 97, 78, 77, 64, 86,
+  86, 80, 77, 93, 75, 80, 65, 75, 103, 82,
+  82, 89, 94, 86, 71, 105, 85, 82, 79, 61,
+  87, 75, 78, 78, 104, 80, 107, 85, 87, 75,
+  87, 91, 75, 78, 84, 85, 80, 75, 92, 83,
+  88, 75, 99, 85, 88, 85, 86, 55, 77, 75,
+  71, 116, 71, 95, 69, 90, 99, 68, 79, 99,
+  98, 107, 71, 75, 79, 82, 94, 96, 99, 84,
+  113, 96, 79, 90, 85, 89, 110, 85, 83, 83,
+  78, 90, 75, 71, 75, 79, 100, 86, 60, 109,
+  95, 91, 84, 72, 95, 93, 78, 61, 78, 110,
+  92, 106, 86, 86, 85, 71, 82, 102, 81, 77,
+  62, 72, 77, 83, 84, 91, 89, 83, 85, 83,
+  86, 70, 84, 79, 93, 74, 87, 89, 78, 76,
+  87, 92, 93, 82, 86, 91, 84, 81, 87, 71,
+  92, 81, 87, 84, 84, 91, 79, 78, 88, 83,
+  91, 78, 86, 89, 87, 76, 80, 88, 83, 80,
+  79, 75, 82, 90, 89, 109, 86, 91, 84, 92,
+  69, 78, 76, 92, 87, 72, 75, 91, 85, 80,
+  86, 85, 82, 84, 102, 81, 91, 82, 79, 104,
+  84, 88, 89, 82, 82, 97, 87, 85, 119, 83,
+  90, 88, 65, 86, 87, 94, 78, 90, 80, 81,
+  76, 77, 70, 87, 80, 79, 73, 86, 89, 85,
+  69, 91, 88, 88, 93, 77, 84, 81, 70, 75,
+  79, 91, 85, 88, 82, 74, 86, 87, 95, 88,
+  78, 90, 84, 89, 80, 87, 87, 79, 82, 85,
+  77, 89, 85, 77, 82, 95, 81, 77, 81, 92,
+  72, 90, 74, 83, 93, 79, 96, 82, 90, 81,
+  77, 99, 83, 77, 73, 68, 92, 90, 89, 77,
+  84, 85, 98, 82, 71, 87, 82, 75, 81, 77,
+  83, 92, 86, 94, 92, 77, 82, 81, 89, 80,
+  80, 86, 85, 68, 68, 79, 82, 88, 81, 90,
+  79, 83, 96, 80, 82, 80, 81, 108, 75, 81,
+  85, 85, 81, 90, 87, 81, 107, 82, 84, 84,
+  67, 75, 91, 90, 70, 81, 82, 84, 71, 70,
+  68, 88, 91, 79, 81, 91, 83, 89, 89, 79,
+  89, 83, 86, 66, 89, 88, 78, 84, 85, 90,
+  80, 76, 89, 78, 83, 80, 80, 81, 91, 79,
+  77, 73, 83, 95, 86, 80, 86, 103, 73, 97,
+  78, 87, 68, 88, 86, 79, 76, 87, 75, 79,
+  67, 75, 99, 76, 84, 89, 78, 95, 75, 101,
+  84, 75, 77, 64, 94, 83, 80, 87, 99, 73,
+  101, 90, 68, 79, 84, 80, 83, 84, 75, 80,
+  81, 82, 103, 86, 87, 85, 96, 82, 84, 86,
+  94, 63, 76, 85, 73, 100, 72, 99, 86, 95,
+  93, 70, 80, 96, 88, 103, 76, 72, 81, 81,
+  93, 88, 94, 79, 113, 102, 91, 88, 90, 79,
+  105, 78, 85, 89, 77, 88, 73, 75, 77, 87,
+  108, 81, 71, 94, 82, 96, 97, 78, 96, 86,
+  83, 62, 86, 100, 94, 99, 89, 89, 94, 76,
+  84, 95, 86, 75, 79, 76, 86, 81, 89, 89,
+  85, 67, 80, 96, 93, 85, 76, 82, 76, 89,
+  77, 88, 70, 64, 79, 89, 79, 110, 76, 92,
+  73, 75, 96, 90, 90, 91, 72, 93, 76, 89,
+  95, 78, 80, 94, 100, 84, 88, 65, 88, 88,
+  86, 81, 85, 78, 83, 81, 103, 85, 82, 72,
+  85, 81, 80, 83, 93, 80, 104, 96, 82, 105,
+  58, 65, 95, 97, 93, 90, 76, 83, 112, 86,
+  71, 75, 74, 67, 84, 76, 81, 90, 75, 96,
+  79, 100, 98, 96, 88, 96, 93, 94, 75, 68,
+  99, 67, 84, 76, 89, 81, 76, 66, 92, 92,
+  75, 98, 77, 94, 86, 75, 93, 94, 76, 83,
+  83, 86, 86, 78, 69, 95, 88, 82, 99, 85,
+  104, 96, 78, 95, 89, 78, 86, 76, 94, 65,
+  76, 89, 81, 83, 76, 83, 64, 99, 72, 75,
+  73, 59, 71, 83, 82, 110, 66, 91, 70, 74,
+  87, 83, 106, 85, 80, 106, 76, 91, 89, 93,
+  76, 88, 78, 85, 87, 67, 92, 83, 88, 80,
+  80, 84, 84, 84, 95, 74, 82, 71, 94, 84,
+  88, 80, 90, 77, 110, 103, 83, 109, 51, 70,
+  80, 97, 89, 87, 90, 81, 93, 91, 75, 84,
+  72, 75, 91, 69, 73, 84, 70, 80, 88, 84,
+  79, 115, 82, 83, 90, 100, 82, 55, 95, 69,
+  82, 72, 89, 85, 76, 99, 96, 93, 76, 83,
+  71, 88, 80, 75, 93, 105, 66, 86, 82, 79,
+  64, 75, 72, 87, 84, 86, 93, 77, 97, 98,
+  80, 88, 84, 74, 92, 84, 89, 90, 99, 108,
+  82, 86, 79, 77, 71, 87, 86, 90, 73, 89,
+  78, 83, 92, 76, 79, 95, 88, 89, 83, 77,
+  75, 91, 80, 86, 84, 94, 89, 87, 84, 89,
+  75, 90, 83, 82, 86, 89, 81, 87, 86, 88,
+  85, 93, 94, 93, 81, 81, 83, 81, 92, 84,
+  95, 81, 78, 78, 71, 69, 77, 77, 83, 90,
+  87, 85, 77, 80, 101, 71, 85, 80, 75, 87,
+  70, 98, 88, 89, 80, 89, 84, 77, 90, 75,
+  94, 83, 88, 78, 76, 88, 90, 85, 91, 73,
+  93, 93, 69, 88, 85, 94, 88, 87, 84, 85,
+  77, 73, 80, 75, 90, 100, 89, 84, 73, 82,
+  85, 78, 103, 78, 96, 87, 87, 91, 89, 90,
+  110, 78, 103, 85, 71, 71, 65, 85, 85, 88,
+  74, 82, 79, 97, 76, 75, 78, 59, 79, 93,
+  83, 119, 94, 88, 66, 82, 78, 87, 116, 94,
+  90, 97, 76, 88, 84, 89, 91, 79, 96, 78,
+  76, 71, 86, 84, 96, 80, 70, 95, 86, 78,
+  86, 87, 85, 63, 91, 69, 83, 75, 96, 62,
+  100, 113, 93, 110, 50, 70, 84, 89, 93, 73,
+  71, 82, 102, 95, 67, 81, 68, 62, 72, 70,
+  72, 75, 77, 99, 86, 94, 89, 102, 75, 85,
+  91, 83, 85, 71, 95, 63, 82, 82, 87, 80,
+  75, 49, 95, 92, 86, 80, 79, 87, 79, 77,
+  96, 99, 72, 73, 75, 85, 82, 83, 57, 93,
+  90, 83, 97, 72, 95, 86, 85, 85, 106, 79,
+  83, 76, 78, 67, 60, 79, 78, 87, 77, 83,
+  73, 91, 76, 66, 82, 52, 65, 85, 73, 120,
+  69, 89, 68, 80, 70, 83, 123, 70, 83, 113,
+  74, 86, 97, 97, 78, 70, 92, 82, 70, 64,
+  102, 81, 89, 87, 61, 75, 83, 73, 85, 83,
+  84, 57, 91, 87, 80, 67, 92, 62, 109, 118,
+  87, 107, 37, 77, 70, 90, 94, 58, 98, 77,
+  89, 89, 70, 85, 70, 92, 81, 64, 63, 73,
+  75, 80, 86, 84, 71, 115, 61, 84, 89, 99,
+  90, 64, 101, 66, 78, 71, 89, 83, 76, 71,
+  94, 93, 85, 69, 71, 81, 70, 72, 78, 117,
+  64, 78, 59, 76, 69, 82, 66, 87, 78, 81,
+  93, 66, 92, 83, 82, 72, 86, 75, 77, 91,
+  82, 86, 79, 105, 91, 87, 78, 79, 70, 77,
+  80, 85, 79, 76, 85, 81, 78, 82, 80, 90,
+  86, 94, 84, 80, 89, 78, 76, 86, 77, 92,
+  81, 87, 74, 96, 75, 94, 81, 72, 92, 86,
+  75, 91, 84, 70, 86, 94, 91, 96, 86, 69,
+  87, 83, 85, 77, 98, 74, 85, 81, 81, 61,
+  72, 67, 77, 88, 85, 86, 85, 77, 102, 73,
+  85, 85, 69, 98, 73, 92, 79, 83, 81, 86,
+  78, 81, 86, 85, 96, 89, 89, 101, 80, 87,
+  96, 87, 82, 62, 87, 89, 83, 82, 81, 92,
+  93, 79, 88, 86, 78, 84, 70, 79, 87, 97,
+  74, 84, 88, 80, 84, 83, 100, 75, 109, 89,
+  83, 78, 90, 78, 98, 70, 96, 81, 69, 95,
+  75, 78, 78, 82, 79, 88, 83, 79, 75, 73,
+  75, 85, 95, 109, 94, 93, 107, 90, 71, 84,
+  84, 93, 94, 90, 99, 104, 77, 85, 80, 100,
+  79, 69, 79, 66, 79, 78, 88, 84, 93, 90,
+  81, 90, 86, 80, 87, 81, 85, 69, 89, 74,
+  88, 64, 87, 84, 91, 104, 96, 99, 78, 58,
+  81, 95, 78, 87, 75, 98, 89, 88, 76, 83,
+  70, 72, 80, 72, 92, 85, 82, 96, 88, 88,
+  93, 84, 82, 91, 84, 82, 94, 88, 86, 73,
+  91, 80, 89, 76, 67, 62, 94, 96, 96, 77,
+  88, 93, 85, 81, 93, 77, 83, 86, 79, 100,
+  85, 94, 69, 86, 92, 83, 96, 73, 90, 98,
+  87, 84, 100, 80, 75, 80, 73, 88, 68, 76,
+  75, 87, 81, 93, 79, 80, 73, 70, 83, 78,
+  78, 103, 81, 94, 87, 88, 67, 80, 78, 89,
+  92, 78, 88, 111, 70, 82, 89, 95, 77, 67,
+  75, 71, 86, 72, 103, 79, 92, 97, 66, 74,
+  79, 76, 96, 86, 88, 66, 86, 76, 82, 63,
+  87, 79, 96, 101, 94, 101, 68, 64, 70, 89,
+  81, 64, 81, 94, 83, 86, 73, 88, 74, 87,
+  84, 69, 86, 83, 85, 88, 88, 90, 81, 93,
+  72, 94, 85, 101, 96, 82, 101, 69, 89, 79,
+  94, 77, 69, 69, 95, 96, 88, 76, 83, 85,
+  81, 76, 80, 92, 73, 81, 71, 90, 82, 90,
+  70, 84, 77, 78, 93, 68, 89, 86, 82, 75,
+  92, 75, 69, 90, 90, 97, 81, 92, 84, 91,
+  81, 79, 75, 83, 77, 83, 83, 78, 92, 93,
+  82, 80, 80, 88, 84, 93, 87, 90, 83, 83,
+  84, 88, 74, 101, 84, 93, 83, 84, 69, 90,
+  89, 80, 88, 87, 80, 91, 86, 86, 83, 86,
+  87, 89, 85, 75, 90, 87, 82, 75, 87, 74,
+  91, 82, 83, 82, 81, 72, 73, 84, 84, 91,
+  93, 77, 92, 76, 84, 88, 72, 83, 91, 90,
+  92, 75, 80, 79, 89, 82, 89, 87, 87, 90,
+  81, 107, 91, 92, 103, 86, 91, 66, 91, 86,
+  78, 86, 89, 94, 88, 76, 92, 95, 100, 76,
+  84, 76, 84, 88, 81, 85, 94, 85, 83, 79,
+  89, 77, 105, 87, 81, 78, 82, 83, 106, 98,
+  82, 88, 97, 83, 78, 68, 78, 76, 80, 84,
+  96, 73, 91, 98, 77, 79, 77, 89, 88, 75,
+  84, 86, 100, 82, 87, 77, 86, 84, 94, 101,
+  75, 79, 80, 84, 111, 74, 91, 89, 76, 81,
+  89, 84, 76, 77, 92, 86, 83, 71, 72, 89,
+  87, 88, 87, 102, 64, 107, 98, 87, 93, 86,
+  90, 83, 81, 79, 81, 77, 86, 84, 80, 106,
+  81, 86, 85, 80, 74, 81, 94, 95, 90, 82,
+  95, 81, 88, 79, 84, 69, 103, 85, 62, 91,
+  90, 102, 74, 89, 86, 83, 94, 71, 87, 75,
+  93, 89, 87, 84, 80, 83, 87, 86, 89, 83,
+  84, 90, 91, 80, 56, 97, 85, 88, 80, 79,
+  93, 86, 103, 83, 89, 72, 103, 62, 88, 93,
+  84, 116, 73, 70, 88, 91, 70, 91, 88, 90,
+  73, 78, 87, 99, 86, 109, 87, 65, 95, 78,
+  103, 75, 94, 91, 94, 81, 81, 99, 88, 83,
+  84, 94, 106, 74, 96, 78, 68, 98, 83, 91,
+  86, 81, 80, 85, 76, 72, 98, 80, 76, 75,
+  91, 97, 68, 74, 87, 95, 83, 70, 86, 62,
+  61, 73, 59, 94, 69, 84, 95, 98, 70, 82,
+  81, 85, 80, 111, 74, 97, 74, 87, 92, 102,
+  88, 77, 87, 99, 62, 80, 84, 101, 80, 84,
+  87, 100, 82, 69, 87, 74, 84, 103, 85, 90,
+  85, 69, 76, 86, 80, 77, 86, 77, 87, 102,
+  79, 100, 63, 88, 76, 73, 73, 66, 85, 76,
+  89, 78, 92, 71, 80, 69, 65, 73, 79, 125,
+  76, 92, 96, 84, 73, 96, 71, 83, 66, 79,
+  82, 92, 78, 112, 71, 78, 95, 81, 74, 89,
+  88, 87, 83, 96, 77, 85, 99, 85, 67, 101,
+  94, 78, 77, 91, 72, 97, 77, 82, 81, 74,
+  81, 109, 81, 74, 95, 78, 85, 77, 88, 82,
+  100, 63, 96, 92, 77, 77, 81, 58, 53, 90,
+  63, 84, 79, 75, 77, 85, 84, 85, 79, 86,
+  80, 92, 74, 109, 74, 81, 83, 100, 71, 77,
+  94, 87, 76, 86, 95, 88, 86, 77, 89, 87,
+  74, 69, 92, 87, 73, 90, 84, 83, 88, 83,
+  88, 87, 87, 96, 75, 74, 91, 97, 58, 99,
+  65, 72, 74, 96, 90, 93, 92, 88, 75, 83,
+  82, 112, 97, 81, 95, 91, 102, 72, 76, 69,
+  76, 76, 79, 94, 78, 71, 86, 91, 79, 70,
+  82, 92, 95, 61, 86, 84, 102, 76, 101, 85,
+  98, 78, 91, 91, 74, 87, 62, 76, 80, 85,
+  110, 69, 93, 69, 75, 85, 69, 88, 88, 80,
+  85, 68, 83, 71, 83, 87, 84, 100, 62, 99,
+  87, 85, 97, 97, 83, 77, 79, 71, 94, 79,
+  97, 91, 54, 89, 76, 102, 78, 74, 88, 89,
+  85, 86, 86, 76, 93, 93, 85, 103, 75, 76,
+  93, 67, 73, 86, 84, 107, 68, 93, 85, 83,
+  82, 76, 73, 67, 79, 93, 89, 94, 89, 80,
+  81, 76, 85, 94, 76, 91, 96, 93, 69, 96,
+  84, 107, 80, 69, 90, 82, 88, 88, 82, 71,
+  86, 56, 108, 92, 77, 97, 71, 69, 71, 95,
+  73, 92, 64, 74, 74, 74, 88, 98, 83, 123,
+  89, 58, 111, 77, 96, 63, 91, 94, 111, 121,
+  78, 91, 88, 66, 62, 89, 103, 91, 134, 57,
+  101, 83, 62, 90, 71, 78, 72, 89, 82, 78,
+  89, 78, 75, 74, 88, 89, 76, 67, 72, 84,
+  87, 76, 79, 62, 60, 73, 71, 95, 80, 108,
+  40, 82, 79, 83, 70, 84, 91, 94, 65, 86,
+  72, 80, 78, 113, 83, 103, 78, 102, 57, 67,
+  90, 70, 80, 79, 75, 90, 85, 61, 79, 79,
+  69, 58, 90, 88, 74, 89, 72, 86, 74, 84,
+  78, 92, 90, 91, 69, 110, 92, 84, 73, 88,
+  84, 70, 79, 83, 75, 81, 89, 80, 76, 74,
+  85, 73, 83, 98, 79, 88, 91, 80, 84, 88,
+  66, 78, 69, 85, 71, 97, 87, 102, 75, 74,
+  94, 79, 80, 81, 81, 83, 103, 124, 78, 76,
+  102, 76, 64, 89, 83, 86, 91, 96, 71, 95,
+  65, 85, 78, 74, 85, 106, 86, 87, 85, 79,
+  86, 79, 85, 85, 97, 67, 93, 92, 76, 75,
+  79, 46, 55, 98, 75, 73, 81, 66, 58, 93,
+  87, 80, 79, 84, 89, 81, 55, 105, 81, 83,
+  90, 97, 78, 88, 94, 83, 76, 81, 104, 72,
+  86, 81, 82, 77, 77, 71, 96, 87, 77, 56,
+  80, 82, 88, 76, 84, 89, 88, 104, 84, 76,
+  87, 88, 43, 99, 71, 75, 76, 89, 111, 98,
+  95, 92, 81, 78, 82, 111, 90, 77, 83, 69,
+  85, 100, 79, 84, 80, 89, 87, 91, 88, 78,
+  65, 72, 79, 72, 89, 90, 85, 93, 84, 83,
+  82, 83, 89, 89, 87, 91, 86, 78, 78, 81,
+  81, 95, 84, 80, 94, 80, 100, 71, 77, 82,
+  86, 90, 64, 83, 82, 75, 87, 84, 87, 87,
+  84, 83, 76, 78, 87, 87, 89, 96, 82, 86,
+  71, 94, 73, 87, 81, 79, 86, 81, 86, 92,
+  76, 90, 87, 113, 77, 87, 81, 81, 93, 92,
+  73, 92, 77, 79, 77, 77, 97, 77, 76, 83,
+  82, 77, 87, 82, 82, 88, 74, 69, 79, 88,
+  90, 98, 98, 80, 96, 86, 82, 86, 87, 98,
+  78, 80, 102, 81, 79, 91, 83, 78, 90, 82,
+  90, 83, 84, 84, 83, 73, 60, 73, 78, 96,
+  79, 85, 80, 85, 85, 86, 64, 81, 65, 76,
+  77, 93, 83, 89, 74, 81, 83, 82, 78, 79,
+  86, 86, 95, 112, 81, 73, 92, 73, 74, 91,
+  88, 79, 84, 75, 95, 59, 69, 84, 79, 79,
+  75, 73, 82, 87, 86, 81, 90, 81, 92, 70,
+  94, 85, 89, 90, 87, 83, 90, 81, 70, 90,
+  74, 84, 72, 91, 91, 70, 90, 80, 79, 96,
+  82, 103, 83, 68, 84, 86, 81, 88, 76, 89,
+  79, 82, 83, 88, 102, 80, 77, 71, 94, 76,
+  80, 71, 84, 90, 77, 74, 80, 79, 93, 84,
+  74, 88, 89, 100, 71, 81, 96, 82, 77, 90,
+  87, 72, 80, 79, 98, 82, 92, 92, 90, 88,
+  86, 94, 84, 81, 79, 69, 96, 66, 89, 97,
+  96, 75, 89, 85, 78, 93, 82, 90, 72, 86,
+  82, 78, 71, 82, 80, 83, 79, 89, 71, 70,
+  73, 83, 78, 72, 86, 86, 78, 79, 76, 87,
+  70, 102, 71, 68, 85, 94, 88, 80, 82, 70,
+  89, 79, 78, 104, 89, 88, 92, 89, 93, 106,
+  99, 87, 83, 81, 76, 66, 85, 105, 93, 74,
+  71, 87, 79, 84, 88, 76, 85, 81, 87, 91,
+  67, 89, 96, 82, 86, 79, 96, 87, 74, 73,
+  98, 89, 81, 87, 75, 87, 92, 85, 75, 90,
+  95, 91, 84, 77, 74, 79, 93, 72, 82, 89,
+  82, 90, 78, 73, 87, 85, 78, 93, 57, 78,
+  88, 77, 94, 94, 85, 94, 93, 85, 77, 87,
+  78, 77, 84, 85, 82, 100, 90, 94, 81, 91,
+  85, 93, 79, 68, 91, 78, 84, 95, 86, 72,
+  90, 76, 100, 89, 89, 84, 82, 93, 73, 101,
+  80, 84, 87, 81, 78, 96, 86, 82, 88, 78,
+  80, 77, 85, 89, 80, 91, 88, 101, 85, 83,
+  90, 97, 74, 81, 102, 81, 78, 87, 91, 76,
+  76, 99, 85, 84, 104, 81, 82, 90, 80, 89,
+  90, 81, 96, 81, 79, 95, 76, 82, 83, 91,
+  89, 86, 93, 113, 78, 80, 81, 90, 82, 92,
+  87, 92, 85, 77, 87, 89, 90, 82, 93, 88,
+  83, 85, 84, 95, 81, 77, 89, 78, 81, 82,
+  88, 83, 86, 95, 86, 79, 90, 84, 82, 83,
+  78, 79, 80, 84, 82, 92, 84, 74, 87, 80,
+  78, 89, 81, 82, 84, 92, 87, 93, 83, 96,
+  90, 69, 91, 81, 78, 81, 77, 79, 87, 87,
+  90, 94, 85, 88, 81, 98, 88, 97, 83, 91,
+  88, 83, 92, 89, 83, 86, 75, 70, 77, 80,
+  86, 85, 82, 83, 91, 87, 88, 81, 78, 90,
+  74, 82, 94, 73, 72, 84, 95, 77, 81, 82,
+  86, 97, 86, 75, 76, 89, 79, 75, 82, 102,
+  86, 76, 81, 92, 84, 75, 87, 80, 92, 81,
+  86, 89, 75, 77, 84, 89, 72, 96, 76, 80,
+  84, 69, 82, 86, 87, 81, 96, 75, 89, 75,
+  87, 92, 82, 78, 104, 86, 81, 84, 87, 84,
+  83, 89, 78, 79, 82, 85, 79, 80, 83, 81,
+  82, 79, 87, 84, 76, 80, 79, 96, 88, 88,
+  82, 88, 84, 89, 89, 100, 83, 111, 82, 80,
+  87, 79, 81, 82, 82, 89, 85, 80, 86, 93,
+  84, 84, 87, 97, 68, 75, 78, 84, 87, 71,
+  95, 104, 81, 86, 67, 69, 81, 75, 89, 88,
+  79, 91, 84, 77, 85, 87, 86, 93, 74, 81,
+  103, 81, 77, 85, 90, 72, 75, 95, 79, 94,
+  96, 71, 83, 96, 80, 80, 84, 91, 94, 85,
+  87, 93, 84, 108, 95, 80, 87, 82, 94, 79,
+  75, 79, 90, 87, 74, 89, 82, 90, 85, 74,
+  91, 84, 86, 84, 91, 78, 87, 83, 86, 91,
+  85, 77, 93, 84, 84, 81, 90, 89, 81, 80,
+  79, 80, 79, 84, 83, 80, 73, 79, 79, 82,
+  90, 89, 79, 76, 82, 67, 81, 78, 78, 71,
+  97, 93, 72, 88, 90, 100, 61, 82, 93, 71,
+  91, 84, 78, 82, 97, 66, 80, 92, 91, 82,
+  91, 90, 150, 96, 82, 87, 83, 86, 84, 81,
+  97, 90, 79, 67, 83, 78, 92, 84, 82, 81,
+  82, 93, 85, 78, 96, 61, 73, 85, 73, 88,
+  87, 81, 83, 103, 76, 95, 97, 87, 80, 80,
+  95, 95, 88, 90, 81, 84, 83, 78, 82, 88,
+  91, 81, 91, 104, 77, 86, 86, 98, 78, 82,
+  79, 95, 77, 93, 77, 92, 72, 80, 88, 92,
+  84, 94, 93, 88, 73, 97, 91, 97, 83, 93,
+  82, 82, 70, 84, 83, 79, 95, 87, 86, 92,
+  71, 90, 77, 85, 84, 93, 74, 79, 65, 90,
+  87, 83, 92, 75, 70, 84, 79, 63, 91, 94,
+  77, 84, 89, 110, 73, 78, 86, 76, 92, 72,
+  70, 88, 91, 71, 71, 93, 92, 93, 93, 91,
+  165, 87, 90, 91, 76, 88, 88, 70, 87, 89,
+  71, 67, 77, 84, 92, 82, 90, 77, 89, 78,
+  84, 63, 90, 52, 72, 90, 60, 83, 84, 86,
+  90, 108, 85, 78, 99, 109, 78, 79, 92, 89,
+  83, 73, 70, 102, 77, 80, 81, 78, 92, 73,
+  91, 98, 75, 92, 85, 82, 75, 82, 78, 95,
+  75, 98, 66, 86, 73, 77, 77, 88, 85, 97,
+  98, 75, 74, 80, 92, 99, 80, 92, 97, 90,
+  66, 86, 85, 80, 91, 78, 83, 79, 67, 89,
+  77, 85, 89, 92, 69, 79, 64, 84, 83, 83,
+  77, 95, 88, 80, 76, 70, 89, 87, 76, 91,
+  88, 114, 65, 87, 85, 74, 87, 74, 77, 98,
+  87, 66, 73, 90, 88, 87, 94, 93, 142, 79,
+  81, 89, 78, 72, 88, 89, 90, 92, 73, 62,
+  86, 74, 91, 82, 87, 81, 80, 72, 83, 75,
+  97, 61, 70, 87, 76, 75, 86, 83, 84, 102,
+  76, 87, 95, 98, 78, 73, 97, 102, 82, 87,
+  74, 96, 82, 84, 86, 85, 92, 98, 99, 96,
+  73, 89, 87, 84, 76, 85, 80, 96, 73, 91,
+  74, 83, 69, 82, 84, 86, 83, 98, 90, 80,
+  74, 83, 89, 94, 80, 89, 85, 86, 73, 81,
+  93, 83, 90, 73, 85, 85, 70, 88, 80, 82,
+  78, 94, 69, 77, 71, 87, 85, 83, 79, 70,
+  87, 81, 93, 91, 77, 84, 79, 87, 87, 77,
+  72, 79, 85, 84, 86, 84, 90, 67, 89, 86,
+  85, 96, 82, 72, 86, 95, 75, 81, 87, 86,
+  86, 89, 75, 84, 91, 81, 75, 84, 89, 81,
+  83, 83, 79, 95, 79, 96, 78, 88, 89, 105,
+  70, 79, 105, 78, 81, 85, 95, 79, 73, 86,
+  78, 75, 89, 80, 84, 70, 86, 91, 91, 75,
+  83, 78, 78, 88, 83, 85, 77, 84, 92, 68,
+  87, 90, 79, 80, 80, 82, 91, 83, 80, 83,
+  79, 77, 90, 77, 88, 77, 81, 82, 83, 89,
+  83, 87, 75, 86, 80, 75, 72, 87, 80, 85,
+  88, 87, 75, 83, 81, 86, 82, 83, 76, 76,
+  85, 74, 87, 83, 79, 83, 91, 72, 75, 86,
+  93, 81, 68, 85, 81, 81, 82, 76, 81, 71,
+  79, 91, 89, 79, 84, 73, 85, 86, 80, 88,
+  87, 71, 88, 102, 105, 72, 90, 94, 86, 92,
+  75, 78, 83, 90, 79, 79, 88, 85, 86, 77,
+  83, 93, 78, 87, 75, 84, 84, 90, 66, 81,
+  89, 78, 73, 80, 97, 86, 88, 78, 79, 82,
+  80, 76, 85, 79, 90, 79, 81, 90, 78, 77,
+  77, 85, 91, 78, 70, 86, 88, 68, 85, 81,
+  73, 82, 82, 82, 81, 88, 72, 78, 79, 77,
+  84, 76, 86, 81, 87, 69, 86, 84, 86, 89,
+  79, 89, 95, 77, 70, 88, 72, 92, 84, 82,
+  69, 80, 79, 87, 85, 82, 86, 82, 87, 75,
+  87, 79, 86, 86, 81, 85, 92, 79, 86, 84,
+  70, 73, 79, 86, 86, 87, 81, 75, 78, 85,
+  82, 77, 90, 74, 81, 88, 80, 93, 85, 74,
+  87, 98, 74, 71, 85, 87, 84, 76, 79, 87,
+  81, 87, 87, 77, 96, 79, 84, 78, 82, 93,
+  70, 73, 74, 91, 85, 101, 69, 80, 102, 71,
+  77, 82, 94, 79, 81, 82, 75, 83, 88, 75,
+  86, 84, 86, 96, 78, 87, 79, 80, 80, 90,
+  87, 104, 72, 82, 86, 66, 88, 76, 73, 84,
+  75, 86, 80, 82, 76, 75, 77, 80, 85, 73,
+  86, 84, 84, 76, 86, 74, 84, 84, 72, 86,
+  81, 76, 75, 85, 74, 89, 82, 74, 76, 81,
+  85, 84, 87, 79, 83, 80, 81, 74, 88, 80,
+  80, 85, 87, 82, 82, 90, 99, 88, 81, 89,
+  78, 84, 94, 75, 82, 91, 86, 74, 83, 91,
+  96, 85, 88, 87, 99, 73, 83, 73, 73, 86,
+  88, 96, 90, 90, 79, 93, 81, 85, 86, 65,
+  88, 80, 83, 77, 75, 95, 62, 75, 92, 79,
+  69, 78, 88, 78, 91, 86, 78, 78, 74, 73,
+  80, 93, 92, 93, 83, 82, 75, 90, 79, 87,
+  96, 74, 83, 73, 68, 94, 88, 71, 86, 100,
+  88, 78, 73, 77, 83, 91, 102, 83, 97, 93,
+  101, 85, 74, 90, 76, 79, 88, 66, 87, 78,
+  113, 94, 86, 73, 98, 79, 95, 86, 85, 101,
+  86, 77, 73, 83, 71, 80, 86, 88, 99, 76,
+  93, 76, 85, 64, 74, 86, 83, 93, 84, 93,
+  71, 84, 91, 86, 101, 82, 85, 97, 77, 78,
+  99, 87, 83, 85, 91, 75, 90, 105, 110, 88,
+  82, 81, 91, 61, 103, 80, 70, 81, 108, 90,
+  90, 92, 76, 81, 79, 84, 84, 61, 85, 97,
+  78, 77, 86, 103, 57, 75, 103, 77, 56, 77,
+  87, 72, 88, 102, 65, 77, 74, 69, 77, 96,
+  107, 92, 85, 86, 74, 91, 85, 92, 87, 63,
+  81, 64, 66, 83, 88, 61, 82, 89, 90, 77,
+  72, 79, 90, 82, 116, 88, 86, 100, 91, 86,
+  71, 96, 64, 73, 85, 70, 88, 77, 104, 93,
+  78, 80, 101, 79, 82, 78, 94, 103, 91, 73,
+  71, 78, 66, 82, 83, 85, 82, 81, 92, 74,
+  83, 65, 82, 78, 80, 90, 76, 92, 82, 96,
+  92, 89, 99, 92, 79, 97, 78, 85, 89, 75,
+  84, 80, 85, 79, 83, 88, 93, 97, 76, 86,
+  83, 75, 91, 80, 76, 84, 91, 80, 92, 98,
+  80, 83, 84, 97, 88, 66, 88, 87, 80, 76,
+  83, 89, 66, 79, 98, 87, 70, 80, 83, 75,
+  89, 89, 80, 85, 76, 75, 77, 86, 96, 88,
+  83, 81, 76, 92, 79, 85, 92, 68, 95, 73,
+  76, 91, 95, 72, 86, 83, 97, 80, 72, 75,
+  84, 80, 101, 88, 80, 89, 99, 85, 72, 99,
+  75, 81, 85, 68, 88, 79, 82, 97, 80, 88,
+  98, 79, 93, 89, 85, 98, 82, 77, 72, 82,
+  70, 88, 74, 82, 77, 77, 96, 74, 88, 69,
+  72, 86, 81, 89, 85, 91, 100, 82, 85, 91,
+  85, 92, 81, 85, 80, 90, 86, 73, 80, 76,
+  90, 90, 82, 84, 70, 81, 73, 84, 94, 90,
+  88, 73, 74, 87, 74, 85, 85, 98, 93, 101,
+  85, 86, 80, 63, 86, 75, 75, 81, 71, 90,
+  63, 74, 97, 89, 79, 85, 92, 82, 89, 85,
+  89, 80, 83, 89, 88, 100, 73, 76, 73, 88,
+  74, 86, 68, 91, 98, 64, 82, 83, 69, 86,
+  88, 77, 86, 105, 85, 82, 80, 96, 84, 83,
+  92, 76, 93, 88, 88, 85, 84, 76, 98, 72,
+  82, 71, 79, 83, 100, 90, 84, 77, 83, 79,
+  103, 94, 87, 89, 86, 82, 80, 82, 70, 84,
+  79, 89, 83, 89, 80, 66, 85, 82, 76, 83,
+  92, 89, 71, 85, 93, 81, 92, 95, 88, 90,
+  86, 87, 80, 91, 87, 81, 84, 82, 99, 93,
+  84, 94, 70, 85, 66, 80, 93, 83, 102, 69,
+  72, 91, 87, 87, 79, 96, 101, 89, 77, 79,
+  77, 55, 82, 84, 74, 86, 73, 103, 58, 71,
+  102, 89, 65, 82, 99, 79, 83, 93, 79, 84,
+  82, 87, 88, 94, 81, 76, 70, 92, 72, 91,
+  73, 92, 96, 53, 81, 73, 72, 79, 91, 73,
+  82, 95, 80, 80, 84, 98, 92, 82, 96, 79,
+  84, 86, 85, 91, 83, 75, 89, 56, 76, 75,
+  79, 90, 104, 88, 81, 70, 81, 78, 99, 97,
+  94, 90, 88, 83, 76, 76, 71, 82, 73, 85,
+  77, 97, 73, 63, 88, 73, 76, 82, 91, 84,
+  68, 83, 97, 94, 96, 89, 87, 94, 79, 87,
+  80, 91, 86, 72, 84, 87, 85, 96, 82, 81,
+  72, 93, 68, 85, 89, 89, 91, 75, 76, 85,
+  79, 91, 86, 100, 96, 83, 83, 93, 77, 60,
+  74, 77, 74, 80, 74, 93, 62, 71, 92, 93,
+  78, 85, 91, 76, 89, 89, 87, 83, 83, 91,
+  82, 97, 78, 78, 75, 89, 77, 87, 78, 91,
+  95, 58, 84, 84, 72, 86, 95, 80, 79, 86,
+  84, 82, 82, 94, 83, 85, 95, 87, 86, 86,
+  87, 88, 83, 76, 101, 69, 75, 71, 77, 87,
+  93, 90, 82, 73, 82, 78, 94, 99, 88, 89,
+  84, 84, 73, 80, 69, 82, 75, 90, 86, 89,
+  81, 65, 91, 78, 76, 83, 88, 86, 73, 82,
+  95, 84, 84, 80, 72, 89, 71, 77, 86, 90,
+  73, 74, 86, 71, 81, 92, 79, 69, 58, 81,
+  75, 80, 89, 110, 84, 75, 95, 76, 76, 84,
+  76, 92, 82, 107, 92, 84, 79, 73, 87, 74,
+  72, 67, 85, 71, 75, 88, 75, 81, 102, 91,
+  86, 81, 93, 66, 92, 80, 91, 104, 84, 89,
+  75, 75, 76, 89, 75, 86, 64, 84, 87, 86,
+  90, 85, 89, 93, 73, 86, 80, 88, 96, 82,
+  76, 87, 81, 87, 66, 86, 92, 82, 85, 94,
+  87, 78, 103, 80, 83, 76, 72, 83, 67, 79,
+  79, 85, 78, 85, 103, 89, 67, 70, 80, 92,
+  91, 75, 66, 87, 82, 90, 76, 92, 81, 86,
+  82, 101, 69, 79, 88, 93, 67, 77, 93, 84,
+  77, 88, 68, 84, 74, 76, 82, 99, 74, 77,
+  82, 86, 93, 96, 82, 75, 57, 84, 74, 74,
+  94, 111, 83, 71, 99, 80, 94, 91, 73, 87,
+  85, 98, 95, 77, 77, 81, 79, 80, 69, 65,
+  81, 76, 74, 90, 70, 81, 96, 95, 90, 85,
+  88, 62, 91, 77, 86, 104, 93, 89, 79, 75,
+  70, 90, 74, 89, 67, 82, 94, 84, 82, 83,
+  94, 92, 77, 85, 79, 84, 91, 74, 82, 86,
+  75, 78, 60, 96, 87, 75, 85, 96, 79, 79,
+  104, 73, 79, 80, 71, 91, 85, 69, 78, 78,
+  77, 85, 115, 94, 79, 68, 76, 96, 88, 73,
+  69, 81, 70, 90, 86, 97, 72, 88, 92, 100,
+  67, 76, 90, 95, 65, 75, 94, 85, 84, 84,
+  72, 84, 71, 79, 87, 92, 74, 72, 85, 97,
+  79, 98, 82, 67, 57, 88, 84, 81, 92, 106,
+  74, 73, 97, 76, 84, 96, 75, 91, 84, 95,
+  86, 85, 77, 73, 70, 81, 76, 66, 77, 77,
+  76, 86, 64, 86, 100, 90, 87, 76, 90, 70,
+  91, 83, 94, 102, 85, 88, 74, 76, 76, 87,
+  82, 85, 69, 82, 93, 82, 86, 87, 93, 93,
+  79, 86, 76, 79, 93, 80, 78, 85, 79, 75,
+  69, 99, 93, 79, 85, 88, 83, 77, 107, 77,
+  84, 74, 71, 87, 98, 76, 82, 75, 77, 83,
+  105, 93, 71, 74, 76, 89, 89, 75, 66, 78,
+  77, 93, 99, 92, 80, 93, 101, 95, 70, 79,
+  86, 95, 67, 79, 85, 80, 77, 90, 86, 86,
+  81, 70, 94, 65, 81, 74, 87, 91, 60, 76,
+  81, 91, 107, 82, 87, 83, 90, 69, 95, 96,
+  95, 65, 92, 87, 76, 81, 80, 83, 82, 96,
+  78, 86, 82, 83, 83, 75, 99, 84, 67, 84,
+  86, 96, 80, 87, 75, 81, 87, 77, 90, 80,
+  74, 83, 81, 85, 87, 76, 90, 76, 80, 80,
+  78, 79, 83, 82, 75, 92, 82, 89, 73, 82,
+  81, 87, 102, 73, 92, 78, 82, 90, 97, 94,
+  87, 103, 98, 79, 78, 83, 72, 82, 90, 73,
+  69, 82, 82, 63, 76, 77, 75, 94, 84, 77,
+  86, 82, 79, 92, 95, 83, 48, 98, 71, 69,
+  105, 81, 121, 96, 84, 94, 89, 83, 87, 73,
+  156, 88, 91, 93, 71, 80, 102, 79, 71, 62,
+  89, 41, 76, 77, 87, 94, 59, 72, 83, 98,
+  102, 82, 99, 80, 76, 63, 94, 90, 92, 50,
+  94, 88, 70, 93, 89, 69, 79, 86, 81, 89,
+  80, 80, 83, 67, 91, 84, 65, 79, 83, 83,
+  70, 86, 78, 77, 84, 77, 92, 81, 65, 86,
+  74, 80, 91, 75, 89, 76, 67, 84, 87, 74,
+  86, 89, 81, 89, 75, 87, 68, 71, 81, 82,
+  101, 76, 96, 72, 77, 80, 95, 88, 97, 102,
+  93, 76, 68, 85, 60, 79, 75, 71, 76, 80,
+  83, 75, 76, 91, 62, 93, 96, 82, 82, 80,
+  75, 93, 88, 87, 45, 90, 80, 77, 82, 79,
+  131, 87, 89, 94, 82, 76, 96, 79, 179, 87,
+  81, 92, 81, 90, 82, 98, 74, 78, 92, 72,
+  80, 81, 84, 87, 61, 78, 83, 93, 108, 89,
+  99, 85, 79, 71, 92, 94, 93, 67, 84, 85,
+  81, 81, 83, 79, 82, 115, 82, 91, 82, 84,
+  89, 76, 82, 85, 71, 81, 88, 77, 81, 91,
+  80, 77, 84, 77, 95, 81, 77, 80, 80, 83,
+  93, 81, 88, 72, 78, 80, 79, 86, 81, 78,
+  95, 93, 89, 88, 76, 88, 83, 96, 104, 73,
+  91, 75, 86, 81, 92, 92, 106, 98, 98, 80,
+  79, 81, 73, 83, 85, 73, 72, 81, 80, 70,
+  79, 78, 81, 93, 86, 75, 85, 91, 74, 88,
+  92, 81, 49, 79, 70, 74, 85, 79, 107, 93,
+  88, 95, 94, 88, 81, 74, 140, 86, 82, 71,
+  79, 72, 88, 87, 78, 64, 92, 50, 83, 73,
+  79, 81, 70, 82, 75, 88, 101, 84, 93, 79,
+  80, 71, 94, 97, 90, 63, 99, 83, 77, 82,
+  87, 81, 88, 94, 83, 80, 84, 76, 90, 79,
+  92, 83, 78, 92, 88, 93, 80, 80, 82, 81,
+  85, 90, 92, 90, 74, 88, 85, 87, 84, 79,
+  81, 76, 89, 87, 82, 71, 94, 74, 84, 97,
+  74, 84, 79, 74, 82, 91, 90, 84, 89, 82,
+  85, 86, 92, 78, 80, 93, 97, 82, 80, 83,
+  67, 80, 81, 73, 75, 85, 75, 78, 77, 81,
+  64, 91, 96, 81, 84, 81, 75, 92, 92, 82,
+  54, 99, 69, 71, 89, 90, 113, 86, 81, 88,
+  80, 72, 92, 84, 149, 86, 86, 85, 71, 63,
+  100, 80, 71, 57, 86, 20, 79, 75, 80, 89,
+  74, 88, 73, 97, 96, 84, 96, 82, 79, 62,
+  87, 87, 86, 43, 101, 93, 65, 88, 96, 74,
+  88, 71, 84, 80, 84, 73, 94, 79, 94, 88,
+  84, 85, 81, 86, 72, 82, 82, 78, 79, 91,
+  91, 77, 67, 94, 84, 90, 87, 78, 79, 76,
+  68, 96, 84, 77, 98, 73, 69, 104, 67, 81,
+  81, 59, 86, 82, 85, 92, 93, 81, 73, 76,
+  96, 81, 93, 90, 91, 80, 66, 77, 64, 75,
+  60, 71, 82, 87, 83, 84, 77, 87, 47, 92,
+  100, 86, 85, 81, 72, 89, 89, 88, 50, 88,
+  80, 84, 78, 97, 119, 76, 83, 86, 60, 68,
+  101, 84, 162, 98, 78, 92, 86, 81, 88, 89,
+  75, 66, 88, 55, 80, 79, 81, 93, 73, 83,
+  75, 85, 99, 86, 92, 80, 82, 72, 86, 93,
+  92, 60, 88, 89, 79, 77, 87, 79, 82, 95,
+  82, 80, 83, 77, 91, 78, 89, 85, 79, 88,
+  83, 87, 80, 82, 86, 81, 80, 88, 93, 70,
+  75, 85, 86, 83, 89, 82, 81, 73, 88, 85,
+  82, 77, 95, 77, 85, 95, 80, 86, 82, 80,
+  87, 92, 92, 84, 89, 75, 84, 86, 91, 83,
+  102, 91, 94, 80, 80, 82, 70, 82, 76, 71,
+  75, 85, 82, 76, 79, 77, 73, 91, 95, 86,
+  84, 86, 74, 86, 94, 82, 56, 81, 77, 76,
+  94, 89, 105, 86, 86, 84, 82, 79, 88, 88,
+  130, 85, 82, 75, 76, 76, 83, 80, 83, 73,
+  86, 75, 82, 76, 85, 80, 69, 86, 78, 86,
+  97, 87, 93, 84, 79, 80, 100, 94, 106, 81,
+  83, 77, 78, 89, 89, 85, 82, 93, 84, 78,
+  84, 85, 90, 73, 89, 80, 77, 86, 86, 91,
+  85, 85, 91, 86, 86, 88, 90, 81, 76, 82,
+  89, 82, 85, 78, 89, 78, 90, 88, 83, 82,
+  91, 84, 95, 92, 89, 80, 83, 73, 85, 86,
+  76, 75, 85, 88, 91, 88, 87, 78, 75, 93,
+  91, 88, 80, 91, 76, 81, 87, 72, 71, 82,
+  77, 68, 81, 80, 77, 86, 90, 88, 90, 77,
+  74, 93, 88, 76, 61, 108, 76, 75, 86, 89,
+  103, 85, 81, 90, 87, 79, 89, 97, 128, 80,
+  86, 83, 85, 75, 86, 77, 83, 69, 85, 62,
+  79, 78, 83, 88, 73, 86, 76, 84, 96, 81,
+  91, 83, 85, 76, 84, 93, 108, 73, 87, 85,
+  72, 86, 98, 84, 88, 85, 84, 82, 81, 78,
+  97, 74, 91, 83, 86, 79, 74, 82, 80, 90,
+  91, 85, 87, 84, 97, 85, 67, 81, 78, 77,
+  88, 73, 94, 79, 79, 87, 77, 82, 91, 89,
+  82, 92, 82, 78, 80, 62, 85, 78, 74, 76,
+  88, 87, 89, 83, 91, 79, 87, 91, 91, 86,
+  73, 90, 70, 79, 81, 66, 77, 83, 79, 73,
+  83, 82, 71, 85, 89, 89, 84, 78, 73, 91,
+  82, 82, 57, 90, 84, 77, 86, 94, 103, 81,
+  82, 87, 83, 76, 93, 98, 129, 85, 82, 87,
+  86, 82, 88, 85, 83, 75, 85, 75, 82, 78,
+  86, 90, 69, 86, 80, 82, 96, 82, 92, 83,
+  84, 80, 84, 91, 100, 78, 78, 86, 82, 81,
+  88, 87, 76, 94, 82, 78, 81, 87, 92, 77,
+  91, 83, 81, 80, 78, 85, 89, 83, 94, 84,
+  82, 86, 94, 74, 78, 83, 86, 78, 90, 81,
+  85, 75, 85, 86, 78, 82, 92, 84, 80, 89,
+  88, 83, 86, 77, 87, 88, 79, 74, 86, 85,
+  90, 93, 84, 76, 104, 86, 90, 82, 81, 92,
+  80, 85, 84, 69, 72, 82, 91, 68, 80, 78,
+  82, 84, 91, 92, 83, 82, 75, 89, 79, 77,
+  64, 85, 83, 76, 95, 91, 99, 88, 85, 88,
+  86, 82, 89, 100, 116, 79, 87, 99, 93, 82,
+  91, 88, 80, 70, 71, 99, 73, 83, 94, 83,
+  82, 83, 82, 99, 67, 77, 70, 72, 82, 87,
+  100, 83, 77, 79, 94, 84, 84, 92, 83, 91,
+  86, 88, 83, 76, 89, 90, 80, 93, 89, 77,
+  83, 73, 91, 73, 81, 81, 82, 85, 89, 63,
+  79, 82, 87, 87, 66, 86, 94, 83, 81, 81,
+  88, 90, 81, 76, 72, 91, 69, 91, 80, 81,
+  90, 77, 84, 97, 84, 81, 76, 80, 76, 99,
+  89, 81, 82, 89, 88, 79, 66, 82, 84, 84,
+  86, 78, 75, 92, 81, 74, 72, 85, 79, 81,
+  87, 93, 87, 80, 75, 113, 69, 85, 79, 79,
+  80, 87, 75, 94, 84, 78, 70, 95, 37, 86,
+  81, 94, 69, 87, 70, 97, 107, 84, 95, 98,
+  83, 84, 75, 93, 80, 84, 83, 83, 84, 86,
+  81, 88, 93, 72, 55, 85, 62, 84, 107, 89,
+  85, 73, 92, 80, 81, 100, 74, 76, 87, 99,
+  78, 76, 94, 74, 80, 87, 108, 81, 78, 85,
+  90, 54, 77, 78, 89, 95, 80, 78, 90, 82,
+  84, 82, 73, 89, 89, 81, 85, 69, 82, 82,
+  86, 79, 68, 79, 89, 94, 67, 83, 80, 76,
+  75, 100, 80, 85, 84, 79, 98, 127, 76, 84,
+  85, 80, 87, 91, 72, 80, 73, 85, 85, 70,
+  76, 88, 55, 85, 80, 71, 83, 78, 80, 83,
+  92, 90, 88, 93, 69, 86, 86, 91, 76, 85,
+  67, 89, 92, 72, 76, 84, 65, 82, 86, 88,
+  83, 83, 48, 92, 123, 93, 73, 107, 82, 92,
+  89, 82, 95, 86, 70, 92, 80, 96, 74, 71,
+  100, 91, 64, 111, 59, 88, 107, 85, 88, 81,
+  80, 83, 75, 102, 82, 85, 88, 104, 75, 101,
+  91, 68, 105, 80, 105, 96, 69, 91, 91, 61,
+  96, 86, 89, 101, 87, 99, 100, 91, 96, 77,
+  109, 83, 79, 104, 90, 83, 75, 81, 103, 99,
+  88, 79, 88, 84, 57, 72, 84, 83, 65, 117,
+  94, 80, 85, 90, 116, 138, 88, 82, 90, 90,
+  78, 91, 105, 79, 72, 83, 82, 75, 87, 84,
+  68, 148, 89, 66, 95, 82, 107, 88, 82, 100,
+  86, 61, 75, 91, 110, 88, 92, 98, 71, 70,
+  97, 103, 82, 65, 105, 75, 87, 85, 102, 91,
+  83, 82, 84, 79, 89, 91, 81, 75, 69, 100,
+  75, 80, 88, 80, 76, 84, 78, 99, 68, 77,
+  80, 75, 82, 88, 84, 82, 84, 77, 88, 92,
+  87, 88, 81, 86, 87, 87, 83, 81, 83, 82,
+  81, 92, 95, 79, 96, 82, 80, 78, 76, 79,
+  79, 73, 86, 65, 87, 74, 86, 92, 63, 85,
+  93, 87, 89, 81, 80, 93, 75, 78, 75, 95,
+  69, 85, 86, 85, 82, 81, 89, 90, 79, 84,
+  79, 84, 66, 87, 85, 80, 86, 88, 94, 82,
+  70, 88, 83, 85, 88, 82, 82, 85, 71, 69,
+  76, 88, 80, 84, 82, 71, 88, 86, 83, 111,
+  88, 92, 80, 79, 75, 81, 84, 92, 78, 89,
+  74, 95, 37, 87, 83, 92, 72, 87, 76, 86,
+  100, 80, 91, 96, 84, 87, 67, 95, 81, 78,
+  82, 77, 77, 81, 81, 92, 92, 73, 59, 81,
+  63, 83, 86, 92, 88, 73, 88, 78, 84, 89,
+  76, 76, 91, 95, 78, 73, 80, 72, 79, 91,
+  116, 77, 98, 83, 75, 63, 73, 76, 87, 84,
+  73, 77, 87, 80, 80, 84, 67, 85, 85, 85,
+  96, 66, 77, 82, 72, 78, 65, 78, 79, 90,
+  75, 92, 70, 79, 79, 95, 83, 93, 89, 79,
+  90, 114, 73, 83, 85, 77, 90, 86, 71, 85,
+  65, 86, 82, 78, 78, 89, 49, 74, 80, 80,
+  75, 80, 79, 69, 93, 88, 101, 91, 87, 86,
+  76, 97, 68, 78, 68, 92, 80, 81, 73, 89,
+  61, 84, 83, 86, 78, 84, 45, 88, 110, 94,
+  76, 100, 84, 87, 83, 91, 91, 84, 73, 78,
+  74, 88, 73, 72, 101, 85, 69, 113, 57, 80,
+  95, 89, 90, 81, 75, 75, 79, 95, 81, 84,
+  86, 107, 68, 101, 84, 73, 108, 79, 113, 100,
+  81, 76, 75, 66, 82, 84, 82, 104, 83, 105,
+  98, 94, 90, 77, 99, 85, 84, 106, 107, 79,
+  90, 85, 87, 103, 83, 82, 96, 81, 54, 86,
+  79, 79, 71, 115, 101, 81, 87, 86, 107, 127,
+  83, 80, 87, 88, 78, 83, 92, 82, 71, 80,
+  80, 81, 87, 85, 59, 129, 94, 78, 87, 82,
+  97, 73, 90, 103, 108, 58, 90, 94, 96, 97,
+  82, 96, 70, 78, 87, 99, 82, 71, 101, 77,
+  88, 86, 102, 84, 89, 78, 78, 84, 90, 91,
+  79, 77, 69, 94, 72, 72, 89, 77, 75, 87,
+  71, 95, 68, 74, 85, 73, 80, 88, 85, 79,
+  85, 73, 98, 83, 91, 93, 80, 86, 95, 82,
+  84, 80, 86, 87, 83, 94, 81, 77, 92, 79,
+  82, 75, 79, 78, 77, 65, 92, 60, 85, 77,
+  85, 86, 65, 91, 90, 84, 79, 87, 76, 91,
+  72, 81, 76, 83, 80, 89, 83, 81, 81, 87,
+  96, 94, 76, 77, 74, 79, 73, 93, 89, 82,
+  92, 81, 94, 86, 76, 88, 87, 86, 86, 85,
+  80, 80, 77, 66, 76, 90, 83, 86, 84, 79,
+  89, 88, 78, 106, 89, 89, 80, 84, 78, 85,
+  78, 91, 81, 90, 69, 89, 42, 88, 82, 83,
+  77, 79, 79, 78, 94, 81, 91, 96, 79, 84,
+  70, 92, 75, 77, 81, 79, 81, 82, 75, 94,
+  77, 72, 67, 84, 69, 85, 78, 84, 84, 73,
+  85, 72, 83, 94, 69, 75, 89, 89, 80, 71,
+  85, 80, 81, 89, 93, 74, 97, 80, 73, 66,
+  79, 77, 78, 81, 79, 67, 83, 80, 78, 79,
+  71, 88, 84, 84, 80, 79, 80, 88, 70, 78,
+  66, 81, 77, 90, 79, 90, 70, 80, 83, 88,
+  80, 86, 85, 75, 80, 105, 78, 83, 87, 74,
+  83, 86, 68, 86, 73, 88, 80, 83, 73, 91,
+  61, 68, 75, 89, 78, 80, 82, 78, 88, 87,
+  85, 100, 87, 80, 77, 87, 77, 80, 68, 90,
+  80, 85, 64, 92, 51, 87, 74, 79, 75, 73,
+  57, 90, 89, 92, 82, 84, 81, 87, 82, 91,
+  75, 88, 79, 72, 76, 87, 74, 81, 89, 74,
+  76, 94, 68, 78, 91, 89, 90, 80, 90, 63,
+  83, 90, 77, 79, 83, 100, 73, 84, 89, 80,
+  85, 79, 96, 89, 81, 82, 74, 69, 84, 77,
+  76, 89, 79, 92, 84, 88, 83, 74, 98, 86,
+  91, 95, 89, 77, 82, 81, 82, 88, 81, 80,
+  88, 79, 70, 98, 74, 83, 74, 103, 95, 82,
+  86, 81, 97, 116, 73, 84, 89, 83, 73, 89,
+  84, 86, 79, 85, 82, 85, 80, 93, 72, 88,
+  84, 79, 81, 80, 93, 73, 97, 93, 108, 73,
+  87, 82, 86, 89, 80, 86, 69, 88, 81, 85,
+  76, 84, 87, 80, 79, 85, 87, 72, 77, 77,
+  85, 87, 93, 80, 102, 75, 77, 95, 76, 100,
+  74, 86, 115, 70, 76, 114, 79, 88, 90, 75,
+  70, 98, 101, 91, 85, 69, 94, 86, 86, 74,
+  73, 74, 76, 73, 77, 80, 90, 97, 73, 91,
+  88, 116, 83, 69, 93, 81, 64, 106, 83, 66,
+  89, 90, 88, 78, 95, 85, 73, 96, 72, 75,
+  70, 78, 81, 71, 94, 78, 92, 85, 77, 82,
+  82, 92, 96, 92, 74, 74, 88, 68, 87, 78,
+  93, 71, 74, 77, 93, 71, 80, 88, 99, 80,
+  77, 78, 82, 91, 77, 70, 93, 74, 79, 78,
+  85, 71, 77, 86, 97, 86, 77, 81, 112, 96,
+  79, 89, 84, 75, 90, 85, 72, 86, 83, 70,
+  90, 70, 75, 93, 85, 87, 76, 88, 82, 88,
+  96, 76, 97, 70, 77, 99, 74, 102, 77, 87,
+  113, 73, 73, 110, 75, 93, 89, 76, 68, 99,
+  99, 87, 83, 69, 84, 79, 85, 78, 68, 78,
+  75, 74, 79, 84, 92, 96, 76, 95, 95, 122,
+  88, 67, 91, 80, 65, 105, 79, 62, 81, 89,
+  93, 82, 92, 91, 74, 92, 76, 78, 75, 74,
+  81, 73, 93, 82, 95, 85, 80, 84, 80, 87,
+  93, 89, 76, 79, 91, 69, 86, 75, 86, 71,
+  76, 82, 89, 69, 82, 88, 89, 83, 76, 80,
+  87, 91, 80, 74, 90, 74, 78, 78, 87, 74,
+  77, 89, 94, 90, 72, 74, 107, 95, 80, 93,
+  86, 77, 83, 88, 76, 85, 63, 68, 71, 74,
+  71, 90, 93, 88, 79, 92, 78, 84, 91, 74,
+  96, 72, 80, 89, 80, 95, 76, 91, 106, 76,
+  80, 106, 80, 86, 84, 78, 73, 97, 92, 86,
+  88, 70, 89, 77, 83, 75, 75, 76, 81, 70,
+  78, 78, 90, 97, 73, 84, 95, 110, 83, 71,
+  91, 82, 64, 98, 84, 71, 78, 91, 91, 83,
+  97, 92, 78, 92, 71, 74, 75, 80, 83, 71,
+  93, 76, 94, 87, 85, 80, 79, 91, 95, 92,
+  73, 84, 94, 69, 86, 80, 95, 80, 71, 83,
+  85, 75, 78, 93, 92, 84, 76, 79, 85, 86,
+  86, 73, 84, 80, 79, 73, 82, 72, 76, 86,
+  99, 83, 88, 82, 101, 98, 76, 96, 80, 74,
+  83, 86, 75, 87, 66, 71, 88, 73, 75, 92,
+  82, 88, 77, 75, 88, 88, 92, 83, 101, 77,
+  78, 90, 84, 102, 79, 91, 114, 76, 80, 116,
+  82, 88, 93, 75, 78, 89, 95, 84, 72, 73,
+  81, 75, 84, 79, 67, 79, 73, 77, 85, 79,
+  93, 95, 71, 88, 92, 124, 95, 64, 90, 84,
+  73, 112, 82, 68, 80, 93, 87, 80, 91, 81,
+  69, 88, 73, 78, 74, 80, 79, 75, 83, 74,
+  92, 84, 80, 84, 89, 88, 89, 90, 78, 79,
+  79, 71, 84, 89, 86, 69, 80, 85, 97, 67,
+  79, 67, 97, 79, 69, 81, 84, 96, 77, 78,
+  95, 79, 75, 82, 94, 73, 81, 77, 98, 90,
+  73, 74, 108, 92, 86, 90, 84, 79, 87, 87,
+  69, 82, 68, 73, 77, 82, 79, 90, 85, 87,
+  79, 78, 83, 93, 97, 80, 96, 73, 75, 96,
+  83, 102, 80, 93, 107, 76, 74, 109, 79, 89,
+  90, 76, 73, 89, 94, 74, 73, 75, 70, 78,
+  82, 83, 64, 86, 76, 80, 87, 82, 94, 94,
+  75, 90, 95, 126, 99, 60, 91, 83, 77, 113,
+  76, 72, 73, 92, 94, 81, 89, 85, 72, 83,
+  76, 82, 80, 77, 80, 76, 80, 78, 96, 88,
+  84, 87, 86, 80, 83, 86, 79, 82, 84, 71,
+  85, 82, 78, 67, 78, 90, 94, 68, 83, 61,
+  89, 79, 73, 83, 90, 94, 79, 80, 91, 80,
+  75, 86, 95, 76, 84, 79, 98, 94, 69, 67,
+  102, 92, 89, 95, 85, 83, 86, 88, 73, 85,
+  50, 72, 59, 89, 76, 91, 91, 90, 79, 83,
+  80, 89, 87, 78, 96, 75, 78, 87, 88, 98,
+  78, 94, 105, 83, 82, 109, 78, 87, 85, 78,
+  77, 89, 91, 79, 72, 75, 76, 75, 84, 79,
+  70, 81, 76, 78, 84, 80, 91, 93, 73, 85,
+  95, 117, 92, 66, 90, 85, 74, 103, 85, 73,
+  74, 95, 87, 80, 93, 88, 74, 86, 75, 80,
+  79, 83, 80, 77, 86, 76, 94, 81, 85, 83,
+  82, 86, 85, 88, 78, 83, 81, 75, 85, 93,
+  84, 80, 77, 90, 89, 72, 78, 75, 90, 80,
+  71, 81, 85, 92, 82, 80, 84, 84, 75, 80,
+  92, 75, 81, 78, 99, 86, 80, 76, 97, 94,
+  84, 93, 82, 81, 83, 86, 75, 84, 57, 76,
+  82, 84, 77, 90, 83, 87, 77, 78, 85, 87,
+  91, 84, 106, 76, 81, 79, 81, 106, 76, 93,
+  111, 78, 85, 119, 82, 86, 94, 73, 78, 79,
+  91, 87, 75, 74, 85, 78, 85, 82, 74, 77,
+  68, 76, 86, 81, 89, 87, 75, 82, 88, 119,
+  96, 67, 94, 84, 73, 101, 75, 74, 75, 96,
+  85, 81, 93, 81, 80, 76, 78, 72, 76, 81,
+  82, 76, 82, 74, 83, 86, 84, 76, 87, 83,
+  85, 90, 79, 75, 84, 67, 89, 80, 80, 71,
+  80, 88, 99, 72, 82, 75, 95, 91, 74, 73,
+  80, 93, 80, 79, 99, 83, 81, 82, 88, 72,
+  87, 80, 100, 89, 88, 78, 101, 88, 82, 85,
+  86, 85, 83, 86, 68, 80, 72, 72, 82, 77,
+  78, 85, 85, 84, 78, 81, 84, 90, 94, 80,
+  103, 76, 77, 86, 81, 106, 74, 89, 110, 77,
+  83, 115, 79, 89, 87, 72, 72, 78, 91, 85,
+  75, 77, 74, 78, 85, 82, 75, 82, 73, 79,
+  90, 82, 88, 84, 79, 84, 88, 117, 101, 61,
+  96, 81, 78, 102, 70, 71, 71, 94, 88, 82,
+  91, 82, 81, 76, 80, 78, 79, 81, 80, 76,
+  84, 81, 84, 88, 82, 79, 87, 75, 83, 89,
+  78, 79, 92, 67, 89, 71, 75, 69, 79, 90,
+  93, 74, 83, 73, 93, 89, 76, 81, 84, 94,
+  84, 81, 92, 84, 83, 87, 90, 76, 89, 80,
+  101, 91, 92, 73, 97, 90, 85, 91, 84, 88,
+  78, 88, 71, 82, 59, 75, 75, 80, 76, 88,
+  88, 86, 76, 79, 87, 88, 84, 76, 100, 76,
+  82, 77, 84, 102, 75, 90, 105, 86, 87, 115,
+  76, 87, 85, 77, 79, 81, 93, 82, 74, 78,
+  80, 72, 86, 81, 77, 79, 72, 79, 87, 80,
+  89, 84, 80, 81, 92, 112, 94, 66, 96, 82,
+  73, 98, 79, 76, 71, 97, 86, 82, 95, 87,
+  83, 78, 78, 79, 80, 84, 82, 77, 88, 76,
+  87, 89, 84, 76, 83, 81, 82, 87, 78, 85,
+  88, 70, 88, 84, 82, 82, 77, 90, 86, 79,
+  80, 82, 93, 87, 75, 73, 79, 94, 82, 79,
+  85, 91, 84, 81, 89, 74, 84, 78, 100, 85,
+  92, 77, 95, 89, 80, 91, 84, 85, 77, 84,
+  72, 84, 65, 74, 85, 79, 79, 85, 82, 86,
+  72, 72, 75, 89, 87, 81, 80, 92, 90, 84,
+  84, 155, 112, 92, 70, 79, 62, 60, 91, 74,
+  89, 94, 82, 77, 76, 76, 73, 89, 92, 89,
+  107, 88, 68, 96, 98, 89, 73, 90, 94, 76,
+  90, 73, 54, 76, 65, 73, 79, 73, 84, 75,
+  86, 91, 86, 87, 81, 96, 73, 60, 97, 93,
+  90, 92, 81, 105, 90, 49, 97, 88, 93, 111,
+  69, 84, 75, 80, 74, 74, 107, 69, 73, 82,
+  86, 118, 64, 75, 73, 93, 83, 98, 61, 95,
+  82, 90, 79, 70, 78, 75, 104, 104, 82, 77,
+  91, 67, 77, 70, 82, 74, 81, 82, 86, 85,
+  96, 62, 81, 88, 88, 94, 67, 77, 93, 66,
+  110, 106, 73, 88, 85, 92, 74, 81, 75, 81,
+  71, 82, 90, 62, 79, 86, 87, 85, 86, 144,
+  105, 87, 76, 86, 74, 68, 88, 80, 54, 87,
+  68, 75, 79, 78, 76, 89, 93, 87, 109, 107,
+  71, 92, 97, 90, 86, 89, 91, 78, 93, 87,
+  89, 77, 71, 69, 84, 74, 74, 76, 92, 93,
+  84, 90, 80, 87, 74, 65, 101, 94, 89, 88,
+  80, 99, 83, 64, 89, 84, 87, 100, 81, 83,
+  70, 81, 80, 73, 101, 80, 81, 77, 90, 108,
+  73, 70, 76, 90, 72, 95, 72, 97, 81, 102,
+  87, 72, 81, 72, 107, 109, 67, 74, 97, 98,
+  81, 71, 76, 73, 75, 84, 84, 85, 100, 68,
+  82, 78, 92, 77, 64, 79, 94, 64, 86, 97,
+  72, 89, 84, 85, 81, 83, 72, 85, 75, 91,
+  95, 81, 85, 78, 72, 91, 79, 81, 64, 89,
+  70, 89, 75, 80, 91, 82, 92, 65, 84, 94,
+  87, 90, 79, 87, 94, 78, 70, 92, 70, 82,
+  90, 85, 75, 87, 79, 80, 82, 80, 75, 81,
+  78, 86, 82, 107, 89, 81, 92, 81, 82, 83,
+  87, 84, 75, 79, 79, 75, 84, 103, 71, 73,
+  96, 70, 83, 85, 94, 86, 84, 86, 103, 86,
+  88, 100, 79, 83, 92, 86, 89, 81, 93, 78,
+  76, 74, 91, 90, 83, 94, 87, 92, 88, 78,
+  110, 84, 91, 81, 78, 90, 83, 83, 80, 75,
+  89, 74, 67, 75, 80, 62, 90, 78, 81, 79,
+  78, 94, 95, 87, 68, 82, 91, 71, 80, 81,
+  91, 89, 80, 80, 84, 80, 60, 76, 87, 77,
+  85, 118, 101, 79, 75, 185, 114, 87, 76, 69,
+  76, 71, 91, 76, 103, 100, 75, 73, 76, 81,
+  72, 81, 98, 77, 114, 84, 74, 105, 98, 85,
+  85, 92, 97, 78, 79, 86, 68, 83, 76, 84,
+  73, 78, 82, 77, 86, 90, 96, 89, 81, 108,
+  75, 45, 102, 79, 75, 84, 90, 98, 76, 50,
+  85, 86, 89, 83, 75, 78, 74, 80, 84, 64,
+  96, 74, 72, 89, 89, 124, 77, 67, 80, 89,
+  81, 97, 61, 80, 73, 76, 72, 64, 75, 78,
+  90, 105, 93, 68, 79, 76, 86, 69, 83, 97,
+  91, 91, 86, 104, 102, 71, 82, 82, 93, 77,
+  61, 78, 89, 70, 94, 102, 78, 95, 80, 84,
+  73, 89, 84, 89, 82, 72, 88, 60, 83, 101,
+  99, 80, 75, 161, 110, 109, 83, 78, 83, 80,
+  85, 80, 55, 84, 70, 70, 82, 81, 72, 83,
+  93, 94, 104, 97, 76, 91, 89, 84, 95, 89,
+  93, 79, 86, 83, 110, 85, 78, 76, 85, 65,
+  72, 80, 87, 85, 95, 95, 77, 87, 76, 54,
+  95, 80, 77, 82, 87, 93, 75, 60, 95, 80,
+  77, 91, 69, 81, 67, 76, 85, 63, 90, 80,
+  61, 80, 94, 110, 84, 84, 76, 99, 69, 92,
+  69, 89, 75, 75, 76, 65, 64, 77, 87, 109,
+  73, 64, 89, 74, 86, 72, 77, 95, 88, 85,
+  84, 101, 97, 75, 83, 76, 98, 69, 78, 79,
+  96, 71, 77, 94, 75, 93, 81, 82, 79, 88,
+  75, 99, 72, 84, 89, 75, 90, 84, 78, 84,
+  82, 99, 69, 100, 81, 83, 78, 80, 80, 79,
+  88, 72, 83, 93, 86, 87, 74, 80, 95, 81,
+  64, 84, 71, 84, 89, 87, 77, 86, 76, 86,
+  86, 84, 88, 80, 84, 85, 78, 107, 90, 83,
+  93, 81, 89, 85, 75, 80, 78, 73, 76, 73,
+  77, 102, 83, 76, 85, 74, 87, 78, 88, 82,
+  80, 89, 99, 82, 87, 88, 75, 82, 79, 91,
+  96, 83, 90, 85, 73, 86, 87, 86, 80, 90,
+  77, 82, 84, 75, 92, 84, 80, 87, 75, 84,
+  82, 72, 80, 74, 87, 79, 74, 80, 78, 74,
+  86, 79, 80, 85, 84, 77, 105, 87, 62, 83,
+  85, 69, 78, 79, 89, 90, 70, 80, 76, 75,
+  67, 79, 85, 77, 84, 103, 86, 83, 88, 124,
+  97, 79, 64, 75, 79, 79, 98, 82, 100, 90,
+  71, 82, 81, 94, 86, 83, 86, 73, 107, 88,
+  80, 96, 86, 90, 86, 88, 83, 83, 73, 80,
+  76, 72, 81, 78, 70, 91, 87, 77, 85, 92,
+  93, 78, 87, 90, 79, 51, 100, 83, 72, 86,
+  87, 101, 83, 63, 85, 94, 85, 77, 84, 77,
+  101, 90, 82, 78, 76, 69, 88, 87, 80, 104,
+  80, 82, 82, 84, 82, 89, 68, 80, 76, 83,
+  87, 80, 81, 77, 91, 87, 78, 89, 87, 90,
+  89, 71, 85, 89, 80, 98, 84, 85, 96, 81,
+  75, 87, 87, 83, 60, 79, 81, 86, 86, 87,
+  78, 90, 91, 86, 80, 87, 76, 90, 79, 77,
+  83, 61, 80, 89, 82, 80, 84, 108, 97, 97,
+  71, 79, 86, 84, 89, 81, 65, 81, 75, 79,
+  84, 91, 86, 86, 80, 95, 98, 91, 82, 86,
+  79, 84, 95, 87, 92, 82, 80, 79, 101, 76,
+  81, 75, 80, 66, 82, 79, 87, 89, 90, 83,
+  82, 75, 81, 61, 95, 87, 78, 85, 83, 100,
+  82, 70, 95, 93, 79, 89, 66, 80, 94, 83,
+  84, 75, 78, 85, 77, 82, 85, 96, 86, 91,
+  83, 97, 72, 86, 73, 84, 79, 75, 87, 77,
+  73, 78, 86, 92, 85, 84, 91, 84, 88, 74,
+  82, 96, 81, 91, 84, 88, 87, 81, 78, 77,
+  94, 84, 93, 81, 89, 87, 86, 92, 71, 89,
+  89, 87, 83, 88, 77, 97, 71, 88, 80, 82,
+  89, 80, 71, 85, 83, 69, 78, 90, 68, 80,
+  77, 85, 89, 78, 84, 76, 90, 90, 80, 90,
+  85, 84, 84, 81, 81, 83, 72, 86, 86, 81,
+  78, 81, 83, 81, 87, 85, 81, 82, 84, 79,
+  83, 98, 89, 75, 91, 92, 90, 78, 87, 80,
+  86, 76, 78, 79, 83, 85, 84, 80, 87, 79,
+  85, 81, 90, 79, 90, 83, 109, 80, 81, 94,
+  72, 88, 81, 86, 89, 71, 91, 79, 80, 89,
+  88, 82, 85, 89, 85, 89, 91, 81, 95, 80,
+  84, 80, 85, 90, 80, 87, 87, 76, 83, 80,
+  74, 90, 87, 79, 83, 78, 80, 86, 88, 84,
+  109, 85, 72, 88, 91, 78, 75, 81, 92, 92,
+  75, 82, 73, 91, 85, 74, 79, 79, 66, 82,
+  96, 86, 83, 96, 81, 91, 66, 87, 67, 63,
+  79, 95, 85, 82, 92, 84, 83, 68, 96, 92,
+  93, 72, 92, 85, 78, 81, 74, 84, 120, 75,
+  98, 79, 79, 82, 76, 75, 80, 88, 82, 72,
+  70, 76, 65, 82, 77, 77, 88, 101, 80, 74,
+  87, 75, 95, 82, 85, 81, 67, 74, 102, 100,
+  87, 108, 80, 80, 81, 83, 75, 82, 74, 79,
+  70, 64, 86, 92, 73, 88, 79, 86, 75, 112,
+  71, 95, 89, 102, 79, 74, 93, 59, 80, 83,
+  77, 100, 88, 86, 101, 76, 88, 97, 63, 96,
+  82, 86, 85, 77, 77, 90, 87, 104, 76, 77,
+  80, 92, 96, 84, 80, 89, 80, 82, 86, 87,
+  95, 83, 82, 80, 82, 82, 72, 77, 93, 82,
+  86, 95, 76, 107, 72, 92, 69, 68, 90, 86,
+  81, 80, 91, 81, 78, 74, 98, 93, 96, 71,
+  97, 88, 76, 88, 81, 78, 120, 74, 86, 81,
+  75, 92, 77, 80, 81, 81, 91, 60, 59, 69,
+  71, 99, 81, 72, 93, 92, 84, 76, 84, 68,
+  90, 77, 97, 87, 66, 81, 86, 84, 89, 103,
+  92, 76, 70, 75, 74, 80, 70, 73, 71, 68,
+  86, 89, 63, 81, 76, 84, 82, 100, 63, 94,
+  88, 112, 85, 79, 99, 66, 89, 91, 78, 80,
+  74, 79, 105, 78, 90, 87, 65, 91, 83, 88,
+  86, 66, 69, 84, 98, 84, 84, 68, 65, 93,
+  100, 74, 80, 80, 85, 83, 89, 75, 78, 69,
+  70, 80, 83, 80, 72, 79, 92, 85, 83, 93,
+  83, 100, 73, 81, 67, 69, 81, 88, 83, 78,
+  87, 86, 82, 72, 100, 95, 85, 69, 101, 80,
+  82, 92, 87, 83, 121, 82, 72, 82, 75, 85,
+  78, 78, 79, 87, 84, 77, 66, 77, 65, 88,
+  79, 78, 89, 71, 82, 72, 88, 73, 93, 78,
+  88, 81, 69, 78, 93, 101, 93, 111, 78, 79,
+  78, 76, 76, 78, 81, 75, 76, 65, 86, 89,
+  74, 89, 80, 80, 86, 99, 70, 104, 84, 112,
+  80, 75, 94, 68, 79, 83, 87, 94, 81, 97,
+  103, 80, 98, 95, 65, 94, 85, 89, 86, 73,
+  77, 86, 97, 98, 83, 78, 74, 93, 95, 85,
+  84, 84, 83, 85, 91, 89, 74, 94, 83, 65,
+  90, 94, 85, 77, 80, 80, 82, 93, 72, 123,
+  81, 71, 72, 66, 79, 86, 82, 85, 100, 82,
+  87, 75, 87, 82, 95, 76, 102, 88, 90, 71,
+  69, 103, 106, 90, 82, 79, 84, 88, 90, 71,
+  82, 74, 81, 72, 87, 84, 75, 80, 82, 82,
+  84, 87, 77, 62, 84, 85, 100, 85, 92, 75,
+  95, 78, 80, 111, 77, 86, 64, 103, 64, 76,
+  82, 87, 77, 71, 77, 78, 81, 80, 78, 69,
+  70, 86, 87, 99, 71, 106, 76, 75, 93, 104,
+  78, 74, 78, 98, 97, 83, 74, 90, 95, 74,
+  91, 93, 79, 79, 84, 81, 80, 72, 67, 94,
+  99, 105, 64, 98, 70, 94, 98, 90, 91, 77,
+  72, 74, 84, 88, 90, 85, 56, 71, 84, 82,
+  88, 77, 75, 73, 87, 93, 78, 97, 88, 79,
+  79, 79, 95, 72, 80, 73, 89, 82, 93, 80,
+  82, 81, 89, 72, 111, 106, 85, 68, 75, 74,
+  84, 101, 85, 79, 74, 88, 83, 76, 81, 81,
+  83, 61, 78, 85, 75, 84, 81, 84, 81, 84,
+  86, 65, 82, 99, 114, 74, 91, 87, 80, 76,
+  88, 117, 77, 70, 66, 88, 62, 78, 73, 82,
+  72, 69, 79, 83, 83, 71, 75, 77, 57, 75,
+  91, 69, 67, 121, 72, 75, 96, 129, 71, 80,
+  77, 124, 93, 73, 67, 72, 87, 76, 85, 100,
+  78, 67, 70, 82, 73, 74, 72, 89, 84, 92,
+  69, 105, 55, 94, 106, 79, 86, 76, 66, 74,
+  96, 84, 81, 73, 55, 77, 89, 90, 86, 75,
+  81, 78, 86, 88, 81, 76, 84, 74, 72, 80,
+  85, 81, 88, 78, 100, 82, 95, 77, 84, 82,
+  85, 74, 101, 96, 86, 83, 85, 89, 104, 97,
+  96, 81, 80, 85, 87, 75, 82, 81, 84, 83,
+  81, 89, 70, 86, 82, 88, 79, 93, 76, 64,
+  83, 80, 97, 74, 86, 77, 86, 79, 84, 118,
+  73, 87, 87, 97, 62, 75, 74, 86, 79, 74,
+  81, 79, 86, 74, 79, 97, 74, 73, 91, 90,
+  74, 110, 75, 85, 89, 101, 85, 80, 80, 94,
+  89, 84, 73, 80, 91, 79, 89, 95, 78, 75,
+  74, 81, 79, 74, 72, 86, 85, 111, 83, 99,
+  69, 85, 91, 84, 94, 78, 72, 78, 92, 84,
+  78, 98, 90, 80, 100, 96, 87, 86, 79, 81,
+  87, 77, 71, 86, 86, 76, 77, 75, 81, 90,
+  79, 83, 90, 90, 84, 78, 81, 81, 89, 79,
+  98, 86, 101, 79, 82, 106, 80, 84, 92, 80,
+  87, 77, 84, 82, 83, 85, 85, 76, 87, 91,
+  78, 85, 78, 91, 96, 97, 81, 70, 84, 90,
+  96, 103, 76, 81, 96, 80, 79, 99, 82, 77,
+  79, 87, 81, 77, 92, 80, 72, 86, 82, 83,
+  90, 73, 99, 74, 77, 74, 83, 84, 90, 100,
+  92, 78, 89, 107, 88, 78, 85, 88, 98, 80,
+  76, 93, 84, 87, 81, 92, 90, 87, 86, 79,
+  82, 76, 78, 85, 86, 90, 84, 91, 72, 89,
+  89, 77, 80, 84, 69, 86, 77, 88, 80, 84,
+  70, 90, 89, 98, 91, 89, 72, 70, 89, 74,
+  83, 84, 101, 85, 87, 86, 78, 81, 79, 79,
+  96, 80, 85, 80, 80, 74, 84, 77, 106, 83,
+  94, 74, 74, 77, 73, 67, 85, 70, 80, 81,
+  86, 88, 75, 91, 82, 77, 87, 86, 78, 90,
+  75, 89, 93, 83, 83, 72, 80, 110, 107, 88,
+  77, 87, 96, 84, 87, 105, 84, 79, 75, 74,
+  72, 84, 84, 72, 71, 88, 78, 89, 90, 73,
+  99, 77, 71, 71, 87, 66, 89, 99, 81, 85,
+  82, 127, 82, 84, 82, 105, 82, 73, 73, 86,
+  74, 89, 77, 101, 98, 81, 70, 67, 83, 78,
+  84, 88, 90, 86, 96, 90, 64, 88, 84, 73,
+  67, 89, 57, 87, 79, 81, 75, 79, 73, 93,
+  96, 90, 87, 81, 80, 79, 92, 77, 80, 95,
+  95, 81, 75, 79, 80, 86, 86, 77, 100, 85,
+  90, 76, 81, 80, 83, 89, 93, 90, 93, 80,
+  82, 84, 78, 85, 81, 73, 91, 78, 79, 77,
+  83, 91, 86, 95, 86, 92, 81, 87, 79, 95,
+  94, 78, 76, 69, 79, 90, 97, 89, 80, 81,
+  94, 80, 95, 101, 84, 76, 86, 89, 73, 76,
+  86, 86, 80, 80, 77, 85, 97, 77, 94, 91,
+  75, 74, 81, 80, 93, 102, 85, 80, 87, 108,
+  93, 81, 87, 86, 86, 76, 78, 74, 83, 90,
+  87, 100, 87, 87, 79, 76, 87, 75, 83, 83,
+  93, 96, 98, 90, 78, 82, 79, 74, 82, 86,
+  66, 86, 82, 87, 76, 91, 98, 75, 73, 83,
+  115, 93, 78, 85, 85, 72, 94, 75, 96, 89,
+  90, 86, 89, 82, 76, 87, 82, 83, 83, 75,
+  76, 82, 91, 81, 90, 76, 82, 68, 83, 86,
+  91, 80, 84, 90, 73, 87, 80, 100, 82, 94,
+  84, 81, 80, 95, 97, 96, 90, 87, 74, 97,
+  77, 93, 90, 89, 73, 84, 81, 91, 92, 78,
+  74, 73, 84, 84, 87, 74, 78, 78, 81, 82,
+  98, 74, 83, 99, 99, 83, 74, 69, 84, 78,
+  80, 66, 94, 89, 83, 71, 74, 66, 78, 84,
+  82, 87, 83, 97, 105, 81, 84, 76, 78, 84,
+  76, 91, 84, 74, 78, 87, 89, 80, 80, 80,
+  74, 84, 85, 96, 106, 77, 75, 88, 111, 78,
+  78, 87, 77, 81, 100, 80, 81, 79, 115, 84,
+  76, 80, 79, 81, 113, 81, 97, 91, 95, 87,
+  85, 78, 86, 91, 80, 82, 85, 69, 72, 79,
+  81, 76, 97, 82, 83, 73, 78, 71, 91, 78,
+  85, 96, 71, 86, 81, 111, 82, 103, 82, 73,
+  77, 91, 94, 105, 90, 85, 72, 91, 68, 91,
+  90, 90, 75, 79, 80, 99, 86, 80, 73, 76,
+  82, 80, 88, 71, 71, 77, 84, 72, 99, 75,
+  86, 98, 96, 81, 75, 80, 83, 77, 85, 58,
+  96, 101, 75, 74, 72, 70, 79, 90, 79, 91,
+  86, 93, 104, 75, 79, 76, 77, 83, 72, 95,
+  88, 69, 84, 87, 88, 88, 91, 81, 74, 81,
+  87, 92, 88, 80, 71, 90, 113, 80, 79, 92,
+  79, 71, 87, 78, 79, 76, 111, 85, 79, 85,
+  81, 69, 85, 75, 94, 86, 92, 87, 93, 68,
+  86, 90, 81, 83, 76, 75, 76, 82, 89, 78,
+  91, 82, 77, 83, 89, 73, 90, 81, 77, 94,
+  72, 89, 77, 97, 78, 99, 84, 73, 77, 94,
+  97, 90, 87, 85, 71, 81, 77, 92, 89, 86,
+  75, 83, 81, 91, 90, 80, 76, 75, 80, 81,
+  83, 77, 74, 80, 78, 87, 97, 89, 87, 97,
+  98, 85, 75, 94, 85, 81, 83, 75, 96, 98,
+  84, 79, 77, 71, 88, 85, 85, 87, 84, 94,
+  108, 81, 83, 72, 81, 83, 74, 93, 86, 74,
+  84, 88, 87, 83, 89, 82, 91, 81, 82, 88,
+  73, 78, 81, 86, 105, 76, 81, 92, 79, 89,
+  102, 75, 81, 88, 118, 94, 76, 80, 79, 72,
+  93, 78, 97, 82, 100, 87, 90, 82, 81, 82,
+  86, 79, 86, 76, 73, 75, 85, 71, 100, 75,
+  77, 71, 84, 87, 86, 77, 80, 88, 72, 86,
+  78, 110, 83, 91, 88, 84, 79, 83, 100, 100,
+  83, 85, 74, 102, 76, 99, 90, 87, 73, 84,
+  79, 87, 91, 75, 74, 77, 85, 80, 86, 70,
+  79, 79, 81, 72, 97, 72, 75, 108, 93, 87,
+  69, 69, 93, 80, 82, 61, 99, 71, 77, 74,
+  77, 76, 76, 90, 84, 94, 83, 86, 90, 86,
+  83, 74, 82, 84, 78, 89, 81, 78, 87, 92,
+  85, 75, 89, 78, 72, 87, 83, 85, 89, 79,
+  69, 87, 108, 85, 78, 86, 80, 83, 97, 81,
+  86, 81, 120, 85, 76, 71, 75, 83, 124, 84,
+  101, 81, 108, 88, 83, 78, 85, 85, 78, 76,
+  91, 70, 67, 73, 73, 72, 108, 78, 78, 76,
+  79, 70, 85, 73, 86, 96, 72, 96, 82, 122,
+  87, 95, 93, 74, 78, 80, 100, 109, 83, 84,
+  75, 104, 67, 100, 85, 87, 72, 82, 77, 104,
+  83, 83, 74, 82, 82, 77, 90, 67, 72, 78,
+  87, 62, 100, 72, 74, 107, 88, 84, 73, 76,
+  97, 84, 81, 53, 102, 76, 67, 71, 74, 80,
+  72, 102, 81, 102, 90, 83, 83, 80, 75, 73,
+  81, 86, 74, 91, 89, 74, 92, 96, 86, 83,
+  97, 79, 75, 85, 91, 80, 68, 86, 64, 93,
+  111, 83, 78, 94, 74, 75, 87, 79, 86, 81,
+  112, 87, 77, 81, 77, 67, 88, 82, 94, 84,
+  95, 87, 92, 70, 79, 82, 86, 79, 79, 77,
+  72, 78, 79, 75, 93, 77, 72, 80, 85, 74,
+  82, 81, 78, 91, 72, 85, 84, 105, 81, 94,
+  88, 76, 76, 82, 102, 89, 84, 84, 68, 96,
+  76, 100, 88, 84, 75, 83, 78, 88, 90, 75,
+  80, 80, 79, 77, 88, 72, 76, 84, 81, 80,
+  94, 89, 74, 102, 96, 89, 71, 94, 89, 82,
+  79, 70, 97, 89, 78, 79, 82, 80, 85, 89,
+  89, 93, 80, 81, 98, 76, 82, 70, 84, 81,
+  81, 88, 83, 80, 82, 93, 87, 88, 87, 80,
+  95, 85, 83, 81, 62, 79, 80, 86, 104, 81,
+  82, 87, 80, 92, 95, 82, 82, 89, 110, 100,
+  84, 83, 79, 77, 91, 72, 91, 81, 100, 88,
+  92, 77, 85, 81, 87, 70, 83, 81, 76, 78,
+  90, 75, 86, 77, 76, 64, 87, 88, 94, 80,
+  79, 92, 72, 86, 72, 102, 76, 96, 78, 87,
+  75, 90, 94, 91, 84, 81, 71, 83, 69, 90,
+  94, 78, 73, 87, 81, 86, 90, 78, 82, 81,
+  81, 80, 85, 76, 86, 90, 74, 87, 95, 75,
+  75, 100, 85, 79, 67, 72, 88, 81, 84, 75,
+  88, 63, 90, 88, 79, 79, 82, 86, 90, 88,
+  72, 90, 100, 96, 87, 72, 80, 76, 80, 88,
+  77, 80, 85, 82, 83, 84, 86, 86, 75, 85,
+  84, 82, 83, 76, 86, 85, 99, 87, 83, 84,
+  79, 88, 91, 84, 85, 80, 113, 98, 85, 77,
+  77, 87, 117, 84, 94, 82, 103, 87, 87, 74,
+  82, 80, 80, 68, 82, 76, 74, 79, 79, 77,
+  83, 83, 82, 71, 85, 74, 97, 77, 82, 94,
+  77, 86, 80, 108, 79, 97, 82, 72, 75, 90,
+  93, 89, 86, 82, 69, 86, 68, 88, 90, 78,
+  70, 84, 84, 94, 82, 74, 87, 86, 78, 75,
+  82, 72, 81, 87, 77, 78, 95, 77, 78, 97,
+  83, 77, 67, 84, 90, 86, 85, 64, 86, 70,
+  83, 82, 74, 83, 77, 90, 86, 92, 83, 89,
+  98, 87, 84, 73, 82, 81, 81, 91, 83, 78,
+  85, 86, 87, 82, 86, 86, 79, 85, 96, 78,
+  68, 82, 81, 90, 99, 83, 84, 91, 73, 74,
+  85, 79, 86, 80, 106, 93, 82, 83, 77, 70,
+  93, 88, 89, 82, 92, 88, 94, 66, 73, 83,
+  92, 73, 79, 80, 76, 81, 87, 72, 78, 79,
+  75, 74, 86, 75, 90, 82, 76, 90, 75, 88,
+  88, 98, 77, 93, 80, 77, 74, 90, 95, 85,
+  85, 82, 70, 90, 72, 89, 92, 76, 74, 90,
+  81, 90, 88, 76, 91, 85, 77, 82, 87, 77,
+  79, 91, 76, 89, 90, 91, 73, 97, 87, 81,
+  72, 95, 85, 83, 86, 79, 82, 77, 87, 82,
+  82, 81, 82, 86, 90, 88, 77, 86, 105, 80,
+  85, 73, 82, 76, 84, 87, 80, 82, 78, 86,
+  86, 84, 79, 90, 94, 83, 86, 81, 61, 78,
+  85, 84, 97, 82, 81, 89, 85, 89, 97, 87,
+  96, 99, 79, 86, 92, 84, 97, 76, 92, 80,
+  82, 82, 95, 87, 82, 99, 91, 92, 89, 94,
+  86, 68, 79, 85, 59, 77, 78, 71, 88, 69,
+  88, 89, 90, 82, 89, 79, 88, 78, 86, 79,
+  81, 88, 85, 81, 68, 81, 86, 98, 82, 78,
+  111, 88, 77, 75, 85, 88, 62, 82, 72, 85,
+  82, 69, 84, 84, 85, 79, 82, 75, 110, 79,
+  90, 77, 90, 99, 69, 74, 85, 93, 76, 81,
+  79, 92, 75, 72, 93, 65, 86, 78, 78, 105,
+  86, 73, 78, 87, 87, 91, 71, 78, 80, 101,
+  81, 82, 99, 87, 85, 86, 83, 70, 84, 87,
+  98, 97, 97, 81, 88, 76, 90, 84, 88, 76,
+  100, 77, 92, 101, 80, 92, 96, 81, 104, 93,
+  82, 86, 116, 79, 93, 75, 105, 88, 89, 83,
+  97, 90, 82, 86, 101, 122, 82, 101, 81, 63,
+  90, 85, 89, 77, 81, 65, 92, 69, 87, 80,
+  97, 87, 93, 91, 90, 73, 90, 82, 76, 109,
+  102, 84, 49, 87, 90, 123, 86, 77, 112, 97,
+  74, 79, 95, 83, 67, 74, 74, 84, 74, 76,
+  83, 74, 86, 73, 88, 59, 122, 77, 79, 61,
+  95, 87, 76, 71, 94, 96, 87, 89, 64, 88,
+  79, 63, 113, 69, 77, 75, 64, 96, 82, 71,
+  60, 88, 87, 96, 71, 86, 78, 101, 87, 79,
+  107, 82, 86, 100, 93, 69, 84, 81, 98, 93,
+  95, 82, 103, 83, 96, 86, 80, 72, 97, 72,
+  92, 126, 77, 100, 81, 90, 98, 94, 79, 85,
+  102, 83, 98, 72, 89, 83, 89, 89, 97, 91,
+  80, 93, 87, 102, 91, 99, 80, 67, 82, 86,
+  84, 74, 81, 69, 90, 86, 89, 77, 100, 86,
+  84, 87, 88, 78, 95, 80, 79, 101, 94, 99,
+  61, 83, 87, 109, 86, 76, 114, 89, 77, 82,
+  89, 84, 67, 77, 74, 85, 80, 75, 78, 84,
+  87, 67, 94, 64, 116, 79, 92, 74, 93, 72,
+  84, 70, 94, 97, 84, 101, 72, 92, 90, 65,
+  111, 68, 82, 81, 69, 103, 94, 74, 68, 88,
+  87, 94, 69, 101, 83, 99, 86, 80, 99, 88,
+  84, 92, 92, 69, 85, 76, 94, 83, 98, 83,
+  89, 79, 77, 87, 87, 76, 97, 79, 83, 104,
+  90, 79, 85, 86, 85, 97, 65, 90, 82, 83,
+  88, 77, 84, 83, 91, 74, 94, 79, 80, 92,
+  82, 79, 88, 79, 78, 83, 75, 80, 53, 74,
+  81, 86, 82, 75, 87, 94, 74, 83, 74, 69,
+  89, 83, 93, 80, 78, 73, 72, 92, 77, 73,
+  89, 83, 78, 83, 85, 88, 72, 79, 69, 83,
+  71, 87, 73, 82, 76, 74, 86, 106, 85, 66,
+  77, 84, 89, 86, 92, 84, 83, 92, 69, 75,
+  79, 90, 76, 77, 94, 82, 81, 84, 84, 61,
+  86, 85, 89, 101, 83, 84, 87, 88, 80, 77,
+  59, 93, 84, 94, 78, 86, 82, 83, 71, 76,
+  79, 75, 81, 86, 73, 86, 83, 86, 88, 73,
+  80, 86, 92, 83, 88, 81, 85, 77, 101, 82,
+  84, 78, 88, 86, 67, 93, 84, 76, 93, 78,
+  97, 83, 92, 66, 96, 81, 82, 76, 83, 94,
+  84, 80, 72, 83, 88, 75, 79, 86, 84, 83,
+  82, 65, 91, 87, 78, 87, 86, 64, 93, 87,
+  82, 76, 76, 75, 76, 84, 69, 69, 91, 82,
+  75, 81, 79, 94, 74, 84, 75, 80, 65, 84,
+  78, 91, 59, 80, 91, 92, 77, 61, 74, 88,
+  96, 89, 86, 70, 86, 82, 68, 72, 83, 94,
+  81, 94, 94, 81, 78, 77, 82, 62, 78, 80,
+  92, 116, 77, 79, 78, 86, 82, 74, 46, 87,
+  86, 92, 75, 87, 81, 86, 75, 85, 81, 72,
+  88, 74, 82, 92, 82, 82, 97, 71, 82, 85,
+  94, 82, 79, 81, 85, 88, 91, 90, 81, 86,
+  84, 86, 67, 87, 83, 81, 95, 73, 90, 78,
+  90, 78, 92, 83, 83, 82, 84, 82, 96, 80,
+  74, 78, 79, 78, 75, 80, 82, 82, 88, 78,
+  88, 86, 81, 86, 86, 72, 90, 79, 84, 80,
+  78, 79, 74, 91, 74, 77, 91, 92, 77, 79,
+  88, 86, 74, 82, 75, 83, 71, 87, 78, 83,
+  72, 82, 93, 96, 83, 71, 79, 83, 91, 92,
+  86, 83, 85, 79, 63, 73, 82, 92, 82, 105,
+  90, 90, 78, 80, 90, 65, 88, 84, 85, 105,
+  84, 79, 80, 86, 79, 82, 57, 88, 83, 92,
+  77, 83, 79, 88, 68, 80, 81, 70, 83, 77,
+  84, 86, 95, 84, 90, 76, 76, 86, 90, 82,
+  82, 85, 81, 82, 100, 70, 82, 79, 83, 88,
+  73, 83, 77, 81, 83, 86, 87, 78, 96, 84,
+  93, 85, 76, 91, 84, 68, 78, 72, 75, 92,
+  87, 85, 76, 92, 88, 90, 81, 83, 91, 89,
+  86, 86, 69, 74, 86, 79, 106, 80, 93, 63,
+  75, 95, 86, 73, 78, 61, 67, 92, 67, 80,
+  80, 83, 67, 82, 82, 99, 79, 98, 78, 78,
+  89, 114, 95, 79, 82, 82, 88, 88, 94, 87,
+  72, 83, 82, 85, 72, 78, 73, 89, 105, 77,
+  79, 98, 70, 71, 89, 101, 92, 87, 77, 80,
+  89, 87, 86, 80, 66, 92, 78, 91, 82, 83,
+  87, 95, 80, 72, 92, 77, 84, 81, 80, 67,
+  78, 96, 89, 84, 76, 82, 87, 84, 76, 92,
+  89, 57, 99, 75, 80, 79, 73, 86, 70, 85,
+  73, 72, 79, 95, 81, 78, 93, 77, 99, 85,
+  73, 91, 90, 57, 86, 66, 77, 109, 83, 77,
+  112, 94, 88, 86, 75, 77, 90, 96, 83, 81,
+  74, 69, 89, 74, 98, 80, 89, 53, 63, 85,
+  100, 64, 74, 49, 64, 96, 55, 82, 82, 78,
+  57, 79, 81, 102, 95, 88, 76, 73, 95, 117,
+  91, 78, 86, 88, 83, 90, 98, 76, 66, 82,
+  94, 83, 70, 87, 66, 91, 125, 81, 85, 104,
+  59, 66, 81, 98, 96, 92, 83, 85, 91, 83,
+  74, 67, 55, 81, 81, 90, 80, 80, 79, 96,
+  73, 68, 90, 78, 94, 79, 83, 70, 85, 97,
+  78, 82, 77, 81, 84, 84, 64, 100, 86, 49,
+  106, 82, 90, 82, 82, 82, 78, 86, 77, 80,
+  89, 86, 88, 71, 92, 85, 99, 88, 82, 88,
+  99, 66, 94, 73, 77, 93, 84, 85, 102, 87,
+  89, 86, 79, 73, 97, 92, 85, 85, 88, 78,
+  89, 83, 89, 80, 97, 64, 68, 83, 87, 71,
+  81, 66, 66, 87, 69, 82, 80, 79, 66, 82,
+  81, 97, 84, 92, 77, 85, 95, 113, 93, 86,
+  84, 80, 90, 94, 98, 86, 76, 84, 81, 89,
+  68, 81, 71, 85, 113, 83, 77, 99, 70, 71,
+  90, 98, 92, 93, 85, 80, 90, 86, 80, 81,
+  66, 77, 83, 90, 87, 85, 86, 97, 75, 71,
+  88, 81, 88, 77, 87, 78, 98, 98, 90, 83,
+  84, 81, 81, 85, 70, 95, 91, 58, 85, 78,
+  98, 70, 68, 84, 94, 78, 100, 47, 78, 98,
+  93, 98, 63, 69, 84, 86, 69, 95, 87, 87,
+  79, 104, 89, 77, 87, 57, 92, 74, 79, 87,
+  72, 85, 70, 115, 94, 75, 85, 75, 83, 87,
+  91, 67, 81, 91, 88, 79, 64, 93, 85, 89,
+  98, 67, 96, 87, 82, 89, 73, 72, 86, 79,
+  79, 87, 73, 71, 81, 80, 87, 124, 79, 79,
+  76, 74, 85, 72, 89, 76, 75, 72, 81, 77,
+  74, 86, 76, 94, 81, 101, 82, 89, 78, 82,
+  63, 84, 114, 82, 101, 103, 98, 90, 78, 75,
+  78, 72, 113, 84, 82, 79, 75, 89, 89, 80,
+  63, 104, 90, 86, 76, 90, 90, 100, 94, 76,
+  83, 90, 86, 93, 89, 90, 84, 91, 86, 63,
+  60, 78, 85, 74, 105, 30, 71, 101, 92, 87,
+  67, 63, 85, 85, 55, 93, 82, 91, 76, 99,
+  83, 78, 84, 47, 99, 73, 76, 90, 74, 79,
+  71, 82, 96, 71, 84, 80, 86, 84, 87, 67,
+  74, 91, 94, 76, 65, 93, 84, 93, 94, 70,
+  95, 98, 71, 92, 64, 67, 78, 76, 80, 74,
+  76, 71, 82, 76, 81, 116, 107, 78, 67, 69,
+  89, 64, 89, 77, 79, 74, 82, 81, 65, 89,
+  69, 80, 87, 97, 84, 83, 64, 84, 60, 81,
+  111, 81, 110, 105, 77, 95, 75, 77, 64, 69,
+  125, 77, 77, 63, 75, 87, 94, 82, 60, 85,
+  94, 76, 80, 94, 88, 99, 97, 78, 74, 82,
+  88, 97, 83, 88, 83, 86, 83, 88, 86, 83,
+  92, 96, 93, 72, 83, 85, 74, 83, 67, 76,
+  80, 78, 91, 98, 89, 87, 74, 96, 86, 87,
+  90, 89, 75, 71, 87, 87, 68, 101, 71, 72,
+  89, 74, 90, 81, 79, 85, 80, 78, 88, 83,
+  89, 93, 69, 87, 94, 77, 88, 74, 88, 86,
+  81, 91, 81, 78, 90, 91, 80, 77, 68, 77,
+  70, 91, 88, 95, 78, 83, 82, 79, 90, 84,
+  88, 84, 78, 78, 81, 82, 87, 91, 87, 86,
+  107, 106, 81, 79, 85, 79, 70, 84, 126, 86,
+  96, 99, 85, 84, 79, 82, 102, 75, 91, 84,
+  79, 85, 70, 90, 92, 80, 73, 81, 78, 87,
+  93, 89, 91, 94, 89, 81, 85, 99, 84, 89,
+  93, 86, 85, 65, 89, 61, 70, 92, 99, 60,
+  94, 26, 69, 74, 94, 95, 70, 69, 84, 87,
+  43, 85, 104, 87, 88, 99, 89, 77, 91, 33,
+  111, 80, 92, 94, 79, 78, 96, 106, 90, 110,
+  86, 78, 76, 92, 88, 74, 73, 84, 104, 81,
+  75, 80, 85, 86, 104, 70, 89, 101, 69, 78,
+  69, 82, 74, 88, 90, 83, 86, 70, 87, 70,
+  84, 86, 95, 76, 79, 92, 82, 67, 93, 79,
+  79, 79, 90, 78, 64, 79, 71, 95, 76, 87,
+  96, 76, 63, 76, 65, 92, 78, 85, 105, 98,
+  93, 95, 65, 84, 60, 64, 109, 75, 86, 78,
+  73, 92, 97, 89, 61, 92, 83, 74, 69, 101,
+  101, 83, 102, 66, 96, 68, 81, 99, 83, 91,
+  84, 102, 78, 51, 69, 66, 96, 53, 100, 5,
+  61, 78, 112, 94, 73, 66, 87, 91, 28, 87,
+  80, 93, 72, 97, 77, 79, 86, 24, 114, 85,
+  93, 103, 89, 67, 89, 72, 92, 120, 91, 87,
+  76, 96, 100, 75, 66, 79, 110, 75, 77, 78,
+  84, 86, 102, 73, 74, 91, 62, 83, 60, 74,
+  74, 86, 89, 88, 62, 75, 94, 72, 90, 74,
+  84, 75, 71, 88, 91, 51, 92, 75, 77, 84,
+  90, 82, 61, 88, 74, 94, 74, 80, 102, 81,
+  58, 71, 57, 97, 62, 85, 108, 104, 101, 91,
+  65, 75, 40, 64, 102, 63, 76, 62, 76, 91,
+  103, 96, 59, 72, 89, 67, 73, 108, 116, 73,
+  87, 66, 88, 61, 81, 97, 76, 95, 84, 96,
+  79, 79, 81, 91, 87, 73, 89, 48, 77, 73,
+  73, 92, 69, 77, 76, 78, 69, 94, 83, 87,
+  89, 94, 80, 87, 98, 61, 91, 83, 79, 90,
+  69, 92, 79, 63, 96, 93, 85, 83, 78, 86,
+  93, 75, 86, 75, 82, 98, 82, 81, 91, 85,
+  83, 74, 97, 86, 77, 85, 77, 85, 82, 91,
+  87, 78, 87, 77, 75, 76, 76, 81, 101, 83,
+  85, 92, 88, 85, 84, 86, 76, 80, 86, 80,
+  72, 95, 79, 92, 98, 99, 97, 74, 78, 91,
+  75, 82, 109, 89, 103, 94, 84, 84, 78, 81,
+  89, 68, 94, 75, 87, 83, 77, 86, 92, 80,
+  69, 76, 82, 79, 110, 89, 73, 89, 80, 78,
+  82, 87, 81, 95, 81, 88, 89, 68, 70, 78,
+  86, 82, 94, 73, 91, 68, 75, 85, 79, 87,
+  64, 80, 82, 77, 91, 90, 88, 85, 79, 81,
+  93, 82, 93, 63, 86, 84, 84, 78, 71, 90,
+  97, 107, 87, 97, 83, 83, 84, 81, 85, 82,
+  79, 78, 94, 81, 75, 88, 80, 75, 97, 83,
+  90, 92, 70, 75, 72, 80, 80, 93, 93, 86,
+  95, 78, 75, 93, 82, 77, 92, 84, 98, 90,
+  76, 90, 93, 87, 95, 76, 88, 80, 88, 98,
+  84, 84, 77, 98, 82, 81, 83, 88, 74, 81,
+  88, 83, 86, 93, 78, 93, 77, 93, 96, 73,
+  67, 90, 86, 89, 83, 86, 82, 88, 78, 100,
+  88, 77, 78, 104, 91, 88, 82, 73, 99, 84,
+  84, 98, 83, 83, 89, 84, 73, 72, 82, 71,
+  89, 65, 91, 56, 74, 84, 86, 90, 65, 81,
+  83, 74, 85, 93, 74, 92, 83, 74, 83, 82,
+  90, 52, 89, 100, 78, 78, 75, 80, 84, 93,
+  87, 96, 88, 84, 92, 80, 78, 79, 75, 69,
+  87, 77, 79, 91, 80, 87, 96, 82, 87, 82,
+  68, 82, 69, 81, 82, 97, 99, 82, 92, 88,
+  75, 90, 79, 85, 82, 88, 95, 88, 73, 80,
+  94, 85, 90, 73, 89, 79, 76, 100, 92, 88,
+  84, 102, 78, 67, 68, 79, 74, 72, 82, 82,
+  89, 95, 79, 87, 77, 93, 86, 70, 57, 86,
+  78, 79, 74, 81, 80, 89, 69, 89, 97, 72,
+  105, 102, 89, 83, 82, 75, 92, 81, 82, 91,
+  73, 86, 88, 88, 70, 87, 91, 87, 89, 86,
+  88, 75, 79, 88, 81, 95, 61, 83, 75, 76,
+  88, 90, 88, 78, 83, 86, 86, 80, 97, 80,
+  76, 91, 86, 80, 69, 88, 77, 82, 87, 94,
+  89, 84, 84, 80, 89, 83, 88, 79, 88, 92,
+  82, 85, 89, 77, 88, 85, 90, 78, 81, 77,
+  75, 77, 80, 86, 91, 81, 88, 81, 70, 90,
+  76, 70, 85, 86, 92, 87, 82, 89, 88, 81,
+  80, 77, 83, 84, 91, 93, 76, 85, 93, 90,
+  86, 77, 95, 90, 78, 79, 96, 81, 91, 90,
+  89, 73, 76, 81, 102, 77, 72, 86, 87, 90,
+  84, 88, 85, 85, 86, 85, 84, 82, 104, 101,
+  85, 90, 87, 83, 83, 95, 80, 95, 83, 85,
+  75, 82, 95, 72, 71, 84, 79, 77, 70, 81,
+  76, 93, 77, 83, 82, 68, 73, 79, 78, 85,
+  90, 72, 86, 81, 73, 99, 71, 79, 105, 92,
+  93, 95, 77, 85, 66, 84, 94, 72, 78, 75,
+  55, 72, 84, 82, 93, 57, 82, 89, 96, 69,
+  78, 71, 84, 85, 67, 86, 79, 83, 87, 71,
+  125, 92, 88, 86, 92, 80, 77, 88, 76, 78,
+  75, 93, 84, 81, 75, 81, 88, 86, 96, 95,
+  80, 97, 81, 104, 87, 95, 92, 100, 81, 92,
+  77, 79, 92, 86, 79, 100, 87, 83, 87, 82,
+  62, 90, 92, 92, 80, 91, 77, 80, 92, 74,
+  89, 74, 76, 78, 88, 93, 92, 97, 87, 92,
+  86, 77, 70, 88, 77, 84, 82, 59, 71, 74,
+  81, 66, 70, 76, 82, 74, 61, 71, 75, 99,
+  80, 84, 84, 70, 68, 80, 71, 89, 82, 62,
+  87, 76, 74, 109, 62, 69, 106, 85, 103, 83,
+  70, 92, 79, 84, 104, 59, 79, 75, 58, 69,
+  95, 88, 100, 57, 79, 77, 94, 66, 83, 66,
+  79, 88, 53, 87, 78, 81, 95, 71, 122, 87,
+  95, 84, 83, 83, 76, 92, 81, 63, 81, 99,
+  81, 82, 78, 81, 81, 93, 108, 90, 81, 107,
+  71, 87, 101, 95, 92, 101, 80, 92, 77, 86,
+  93, 83, 75, 111, 77, 82, 80, 74, 54, 85,
+  84, 94, 76, 95, 74, 82, 87, 68, 100, 72,
+  73, 85, 93, 101, 72, 88, 81, 96, 86, 72,
+  65, 79, 74, 85, 89, 52, 79, 64, 75, 80,
+  78, 82, 80, 81, 76, 82, 77, 90, 83, 84,
+  85, 72, 76, 77, 79, 81, 82, 68, 89, 83,
+  78, 95, 77, 81, 98, 79, 85, 83, 80, 71,
+  84, 95, 87, 73, 78, 76, 64, 76, 84, 89,
+  100, 69, 89, 89, 88, 75, 83, 79, 86, 80,
+  69, 80, 82, 79, 94, 72, 111, 85, 85, 84,
+  91, 80, 78, 85, 79, 73, 91, 97, 87, 79,
+  77, 84, 95, 97, 98, 92, 81, 91, 80, 79,
+  79, 87, 85, 92, 88, 92, 79, 95, 96, 87,
+  89, 96, 89, 83, 78, 89, 64, 87, 92, 91,
+  79, 90, 79, 84, 91, 79, 85, 78, 79, 92,
+  90, 89, 78, 96, 91, 86, 91, 74, 78, 92,
+  77, 83, 83, 69, 78, 82, 84, 73, 88, 83,
+  100, 73, 79, 82, 84, 88, 79, 107, 93, 70,
+  67, 81, 90, 79, 99, 81, 77, 88, 74, 82,
+  80, 84, 91, 84, 90, 83, 88, 89, 68, 78,
+  75, 70, 60, 70, 81, 79, 79, 90, 92, 64,
+  88, 82, 78, 68, 83, 82, 77, 86, 66, 73,
+  76, 71, 85, 82, 111, 94, 78, 84, 78, 82,
+  77, 87, 76, 60, 72, 87, 79, 73, 86, 87,
+  84, 90, 78, 92, 70, 87, 85, 83, 79, 92,
+  86, 93, 84, 86, 84, 75, 76, 82, 73, 96,
+  78, 87, 87, 87, 59, 89, 90, 83, 87, 80,
+  88, 81, 105, 71, 87, 84, 79, 86, 85, 91,
+  94, 86, 98, 84, 89, 80, 76, 84, 80, 91,
+  80, 79, 80, 85, 73, 80, 81, 78, 99, 72,
+  92, 88, 83, 91, 87, 77, 94, 77, 65, 89,
+  92, 77, 84, 72, 83, 98, 79, 70, 90, 90,
+  84, 77, 84, 88, 86, 88, 69, 72, 82, 72,
+  80, 64, 81, 85, 93, 89, 96, 72, 96, 83,
+  71, 69, 86, 75, 82, 85, 64, 88, 78, 71,
+  85, 80, 118, 87, 76, 87, 69, 86, 77, 83,
+  75, 58, 73, 90, 81, 78, 84, 89, 87, 89,
+  74, 86, 71, 86, 87, 80, 64, 92, 81, 89,
+  85, 94, 87, 76, 74, 79, 69, 88, 74, 92,
+  84, 90, 57, 83, 97, 86, 106, 79, 89, 79,
+  106, 76, 81, 75, 89, 84, 76, 88, 93, 82,
+  96, 86, 94, 72, 72, 89, 72, 85, 88, 82,
+  80, 81, 73, 77, 84, 78, 93, 76, 81, 82,
+  81, 83, 80, 63, 91, 73, 71, 76, 85, 80,
+  76, 79, 83, 91, 86, 85, 79, 87, 85, 86,
+  78, 89, 86, 84, 76, 93, 78, 69, 103, 72,
+  86, 77, 94, 94, 94, 66, 91, 93, 79, 74,
+  85, 78, 80, 85, 73, 98, 78, 74, 87, 80,
+  96, 88, 73, 80, 81, 78, 81, 89, 76, 64,
+  91, 86, 82, 74, 81, 89, 83, 83, 87, 88,
+  74, 88, 82, 78, 79, 92, 86, 89, 85, 86,
+  86, 78, 79, 85, 77, 93, 77, 86, 76, 85,
+  62, 88, 86, 81, 87, 84, 85, 83, 99, 79,
+  84, 84, 83, 87, 69, 84, 92, 85, 94, 85,
+  81, 77, 83, 87, 82, 86, 79, 82, 94, 87,
+  90, 91, 98, 94, 91, 75, 90, 84, 84, 74,
+  88, 86, 85, 79, 70, 84, 97, 84, 86, 102,
+  81, 97, 86, 74, 107, 90, 87, 87, 70, 89,
+  102, 83, 89, 94, 78, 81, 67, 82, 95, 87,
+  70, 91, 91, 89, 98, 77, 57, 90, 72, 95,
+  80, 83, 93, 81, 77, 73, 93, 80, 88, 94,
+  72, 82, 83, 80, 77, 83, 74, 80, 95, 74,
+  85, 67, 91, 81, 73, 86, 74, 82, 79, 71,
+  97, 82, 75, 85, 81, 77, 89, 85, 82, 80,
+  72, 76, 90, 79, 84, 78, 97, 92, 74, 90,
+  86, 75, 97, 84, 96, 83, 113, 95, 80, 92,
+  88, 86, 74, 80, 98, 74, 93, 82, 95, 87,
+  92, 85, 91, 92, 81, 93, 99, 94, 92, 104,
+  84, 87, 86, 77, 103, 96, 83, 72, 100, 78,
+  94, 84, 73, 86, 99, 82, 73, 110, 85, 104,
+  93, 62, 119, 104, 76, 89, 62, 95, 109, 76,
+  96, 82, 87, 94, 77, 82, 94, 95, 80, 86,
+  85, 94, 103, 85, 49, 100, 76, 96, 86, 80,
+  93, 80, 74, 68, 96, 78, 83, 88, 71, 87,
+  79, 87, 74, 78, 70, 81, 84, 71, 94, 72,
+  86, 77, 77, 75, 69, 79, 82, 72, 101, 91,
+  58, 86, 76, 67, 83, 90, 76, 81, 70, 74,
+  86, 71, 89, 82, 97, 92, 73, 73, 87, 75,
+  108, 88, 99, 76, 109, 103, 79, 91, 93, 77,
+  77, 80, 104, 72, 92, 82, 88, 85, 92, 85,
+  89, 83, 79, 98, 91, 102, 85, 90, 84, 87,
+  91, 82, 91, 89, 83, 78, 88, 76, 83, 81,
+  75, 81, 95, 82, 73, 99, 88, 95, 96, 79,
+  100, 87, 78, 88, 69, 94, 101, 90, 88, 86,
+  80, 81, 91, 79, 100, 85, 84, 91, 83, 84,
+  95, 87, 70, 91, 74, 97, 84, 84, 93, 82,
+  79, 79, 89, 82, 86, 87, 75, 79, 85, 83,
+  82, 84, 77, 82, 88, 80, 84, 68, 84, 87,
+  74, 75, 74, 83, 84, 73, 92, 89, 79, 93,
+  91, 74, 88, 89, 81, 85, 74, 80, 91, 80,
+  81, 78, 87, 88, 74, 83, 85, 76, 94, 85,
+  89, 82, 103, 90, 80, 86, 89, 81, 76, 86,
+  105, 76, 92, 83, 79, 86, 91, 87, 92, 92,
+  80, 85, 93, 84, 73, 92, 86, 71, 83, 81,
+  80, 90, 79, 71, 75, 95, 80, 105, 92, 73,
+  79, 92, 67, 73, 77, 91, 81, 82, 74, 79,
+  87, 86, 100, 74, 84, 88, 104, 72, 82, 83,
+  81, 80, 81, 80, 86, 96, 72, 108, 115, 82,
+  89, 82, 75, 69, 87, 96, 80, 99, 91, 94,
+  98, 82, 93, 114, 97, 90, 74, 69, 101, 76,
+  136, 74, 80, 57, 68, 84, 75, 82, 80, 69,
+  86, 79, 97, 88, 86, 73, 94, 95, 81, 78,
+  94, 74, 67, 86, 82, 84, 70, 66, 79, 86,
+  98, 75, 73, 83, 89, 81, 99, 91, 84, 83,
+  97, 76, 70, 81, 85, 74, 86, 88, 83, 77,
+  79, 85, 88, 80, 91, 85, 92, 97, 79, 85,
+  88, 88, 51, 82, 75, 70, 86, 82, 85, 88,
+  87, 76, 95, 102, 86, 74, 83, 81, 82, 76,
+  93, 81, 81, 95, 72, 87, 70, 82, 87, 79,
+  89, 79, 77, 92, 103, 73, 84, 87, 72, 79,
+  73, 91, 89, 89, 75, 89, 71, 98, 91, 87,
+  83, 78, 85, 91, 70, 100, 96, 75, 83, 86,
+  88, 93, 89, 90, 65, 73, 83, 85, 107, 72,
+  70, 77, 74, 82, 75, 79, 87, 70, 77, 82,
+  85, 86, 89, 65, 92, 77, 77, 77, 77, 86,
+  63, 83, 78, 96, 64, 73, 86, 81, 104, 81,
+  71, 92, 86, 82, 91, 83, 88, 89, 95, 79,
+  68, 80, 87, 78, 73, 71, 64, 86, 90, 90,
+  74, 79, 77, 91, 81, 88, 88, 90, 83, 88,
+  66, 80, 71, 99, 84, 80, 84, 89, 96, 78,
+  93, 87, 85, 71, 80, 103, 84, 81, 100, 75,
+  83, 93, 76, 90, 79, 89, 89, 81, 86, 87,
+  76, 83, 94, 81, 85, 81, 78, 81, 76, 89,
+  84, 79, 84, 80, 63, 88, 92, 86, 86, 87,
+  87, 90, 73, 88, 84, 81, 73, 79, 86, 79,
+  90, 79, 87, 91, 81, 85, 83, 82, 84, 85,
+  90, 82, 80, 76, 85, 86, 83, 101, 83, 82,
+  81, 81, 81, 74, 76, 87, 81, 94, 72, 85,
+  77, 93, 85, 84, 88, 92, 84, 91, 84, 99,
+  85, 83, 77, 85, 78, 85, 86, 89, 79, 80,
+  93, 88, 77, 79, 66, 82, 85, 100, 83, 83,
+  77, 88, 82, 85, 98, 89, 89, 80, 78, 75,
+  75, 57, 82, 80, 81, 101, 70, 87, 65, 96,
+  73, 91, 78, 70, 66, 95, 79, 102, 105, 83,
+  89, 64, 79, 76, 89, 65, 64, 72, 92, 75,
+  89, 77, 82, 84, 86, 77, 100, 76, 95, 80,
+  100, 111, 97, 93, 92, 87, 81, 60, 85, 73,
+  111, 86, 120, 64, 158, 69, 74, 147, 106, 76,
+  86, 78, 85, 101, 104, 78, 73, 56, 101, 67,
+  65, 118, 80, 60, 81, 77, 78, 72, 104, 85,
+  75, 76, 81, 78, 74, 82, 73, 93, 94, 76,
+  78, 55, 70, 86, 95, 116, 73, 78, 92, 84,
+  98, 99, 93, 76, 82, 85, 59, 73, 85, 80,
+  78, 101, 77, 86, 76, 92, 70, 65, 87, 87,
+  86, 73, 75, 83, 101, 85, 67, 87, 74, 58,
+  79, 83, 89, 88, 83, 80, 100, 100, 76, 77,
+  78, 82, 79, 77, 112, 96, 104, 82, 75, 83,
+  71, 80, 91, 77, 71, 87, 78, 97, 85, 81,
+  88, 83, 88, 87, 81, 96, 72, 92, 85, 83,
+  68, 127, 87, 91, 83, 97, 87, 87, 86, 84,
+  91, 64, 103, 77, 68, 86, 92, 66, 73, 72,
+  72, 89, 83, 85, 89, 81, 76, 76, 57, 87,
+  84, 57, 63, 84, 80, 77, 94, 79, 96, 73,
+  87, 87, 67, 86, 62, 75, 84, 82, 77, 74,
+  89, 83, 83, 94, 73, 82, 81, 82, 79, 77,
+  93, 86, 91, 80, 76, 78, 79, 91, 84, 83,
+  77, 90, 79, 84, 79, 75, 89, 88, 86, 71,
+  74, 82, 93, 93, 78, 91, 71, 90, 87, 81,
+  82, 85, 90, 82, 105, 78, 92, 73, 84, 106,
+  89, 88, 101, 80, 87, 89, 78, 96, 75, 85,
+  96, 82, 99, 96, 81, 91, 93, 87, 85, 88,
+  84, 83, 71, 93, 83, 87, 84, 74, 75, 93,
+  88, 89, 90, 95, 91, 98, 73, 81, 73, 80,
+  60, 83, 85, 72, 79, 71, 79, 89, 90, 79,
+  78, 73, 82, 83, 79, 83, 81, 63, 82, 94,
+  74, 95, 87, 85, 80, 80, 90, 88, 81, 91,
+  80, 92, 69, 68, 67, 82, 79, 90, 93, 94,
+  70, 81, 81, 91, 86, 84, 79, 69, 88, 92,
+  90, 91, 93, 80, 91, 89, 76, 79, 74, 88,
+  87, 87, 87, 90, 77, 89, 84, 80, 97, 89,
+  100, 92, 79, 77, 76, 60, 72, 88, 86, 92,
+  82, 89, 79, 90, 64, 87, 75, 90, 84, 90,
+  74, 97, 112, 76, 84, 79, 76, 77, 83, 75,
+  84, 86, 77, 73, 87, 94, 82, 85, 90, 78,
+  83, 79, 94, 99, 83, 69, 93, 96, 86, 82,
+  82, 80, 85, 79, 92, 81, 95, 83, 113, 90,
+  75, 104, 112, 85, 76, 68, 76, 99, 78, 99,
+  60, 64, 97, 79, 73, 96, 92, 55, 80, 71,
+  84, 74, 93, 92, 84, 84, 83, 88, 89, 88,
+  81, 90, 98, 80, 90, 79, 81, 78, 81, 84,
+  88, 78, 98, 85, 80, 79, 100, 80, 114, 93,
+  77, 87, 81, 86, 94, 81, 90, 84, 82, 96,
+  74, 82, 100, 83, 87, 72, 82, 79, 98, 81,
+  86, 90, 74, 71, 79, 80, 92, 84, 82, 71,
+  101, 79, 81, 79, 76, 89, 79, 73, 81, 90,
+  102, 84, 88, 89, 74, 82, 83, 84, 92, 98,
+  64, 92, 85, 91, 94, 88, 87, 85, 78, 92,
+  79, 97, 72, 71, 94, 103, 82, 87, 86, 94,
+  90, 87, 80, 60, 74, 83, 84, 96, 77, 81,
+  90, 72, 79, 64, 82, 77, 81, 82, 90, 83,
+  83, 84, 69, 74, 83, 69, 69, 81, 86, 78,
+  83, 79, 91, 87, 87, 89, 81, 85, 55, 78,
+  80, 88, 74, 88, 87, 78, 61, 79, 77, 68,
+  86, 80, 81, 69, 88, 84, 100, 91, 97, 85,
+  81, 89, 95, 81, 78, 87, 81, 80, 90, 81,
+  98, 87, 91, 70, 81, 78, 90, 82, 84, 92,
+  67, 79, 87, 74, 79, 85, 87, 74, 91, 68,
+  97, 69, 83, 103, 88, 86, 84, 89, 95, 96,
+  82, 84, 77, 84, 82, 84, 97, 99, 81, 95,
+  89, 85, 94, 88, 88, 78, 83, 89, 82, 86,
+  74, 73, 91, 92, 84, 86, 90, 89, 88, 90,
+  75, 71, 75, 90, 75, 84, 92, 86, 79, 80,
+  90, 88, 92, 75, 81, 78, 76, 80, 89, 78,
+  81, 68, 81, 87, 77, 95, 90, 80, 74, 79,
+  79, 95, 79, 88, 81, 85, 67, 76, 76, 82,
+  71, 93, 84, 92, 65, 83, 78, 87, 82, 82,
+  89, 80, 83, 89, 69, 96, 93, 87, 90, 82,
+  82, 88, 88, 91, 88, 85, 88, 87, 73, 92,
+  78, 79, 95, 87, 83, 72, 104, 86, 75, 86,
+  73, 81, 80, 78, 89, 84, 70, 74, 76, 82,
+  85, 77, 82, 76, 85, 81, 100, 90, 61, 72,
+  87, 75, 76, 82, 90, 80, 85, 74, 79, 106,
+  97, 75, 83, 77, 88, 74, 76, 70, 97, 75,
+  89, 60, 89, 78, 87, 80, 81, 79, 90, 89,
+  79, 69, 74, 122, 77, 77, 82, 83, 88, 86,
+  94, 102, 79, 90, 83, 105, 83, 88, 78, 83,
+  77, 97, 80, 77, 82, 82, 81, 75, 67, 98,
+  78, 90, 89, 105, 82, 94, 86, 132, 82, 90,
+  86, 92, 96, 92, 74, 78, 80, 71, 93, 94,
+  95, 68, 87, 75, 90, 90, 75, 83, 78, 101,
+  84, 96, 80, 85, 92, 66, 71, 94, 78, 79,
+  69, 87, 84, 71, 75, 77, 72, 83, 72, 77,
+  69, 66, 84, 73, 68, 76, 69, 79, 86, 71,
+  73, 45, 78, 83, 83, 94, 69, 74, 85, 63,
+  103, 74, 95, 87, 83, 75, 80, 74, 76, 68,
+  80, 70, 77, 70, 91, 65, 95, 81, 90, 77,
+  85, 71, 69, 92, 78, 82, 85, 82, 71, 68,
+  74, 116, 83, 82, 69, 106, 77, 85, 90, 102,
+  73, 87, 93, 96, 72, 94, 70, 75, 72, 61,
+  82, 78, 81, 71, 84, 83, 72, 85, 75, 89,
+  77, 106, 65, 96, 94, 139, 85, 95, 97, 92,
+  81, 89, 66, 106, 71, 71, 104, 94, 95, 55,
+  91, 76, 91, 106, 66, 75, 90, 113, 74, 104,
+  85, 80, 97, 59, 64, 86, 75, 83, 62, 77,
+  79, 85, 82, 90, 80, 100, 76, 87, 87, 90,
+  85, 95, 70, 87, 77, 83, 85, 79, 81, 65,
+  81, 78, 88, 86, 84, 74, 85, 83, 77, 93,
+  80, 90, 88, 97, 90, 89, 91, 83, 78, 86,
+  84, 81, 93, 84, 98, 79, 91, 107, 86, 85,
+  87, 94, 89, 78, 80, 76, 84, 73, 79, 103,
+  81, 83, 87, 65, 87, 88, 72, 94, 81, 69,
+  83, 92, 83, 74, 73, 84, 84, 71, 80, 76,
+  91, 82, 79, 95, 78, 90, 92, 85, 96, 100,
+  89, 101, 86, 108, 102, 81, 72, 86, 81, 90,
+  78, 75, 82, 78, 87, 93, 88, 79, 72, 80,
+  94, 79, 77, 89, 82, 92, 94, 87, 88, 74,
+  85, 72, 81, 89, 86, 76, 73, 95, 80, 62,
+  94, 74, 75, 83, 71, 83, 80, 60, 83, 87,
+  75, 82, 74, 93, 94, 83, 85, 73, 84, 58,
+  106, 96, 61, 75, 85, 67, 106, 78, 84, 80,
+  83, 79, 71, 119, 84, 80, 78, 79, 80, 73,
+  79, 64, 78, 91, 89, 77, 82, 61, 83, 75,
+  73, 84, 86, 86, 79, 53, 68, 147, 89, 95,
+  84, 73, 90, 64, 78, 100, 99, 100, 104, 96,
+  98, 82, 73, 77, 64, 79, 76, 89, 80, 76,
+  82, 102, 73, 88, 72, 91, 83, 101, 72, 77,
+  73, 131, 88, 84, 89, 88, 92, 80, 53, 90,
+  77, 83, 94, 83, 91, 51, 90, 77, 93, 89,
+  59, 90, 80, 78, 65, 109, 87, 72, 86, 51,
+  70, 83, 86, 78, 76, 77, 65, 69, 81, 62,
+  64, 78, 67, 77, 66, 42, 80, 83, 67, 80,
+  70, 91, 104, 71, 73, 44, 78, 53, 79, 90,
+  62, 83, 78, 55, 124, 79, 83, 78, 75, 73,
+  68, 84, 65, 93, 81, 63, 70, 67, 82, 60,
+  72, 76, 81, 70, 80, 50, 83, 74, 66, 88,
+  68, 85, 69, 54, 59, 176, 101, 86, 68, 86,
+  77, 59, 74, 109, 97, 77, 81, 109, 89, 82,
+  75, 73, 43, 74, 73, 94, 80, 88, 78, 106,
+  86, 92, 70, 88, 77, 94, 64, 78, 61, 137,
+  76, 86, 97, 88, 77, 75, 45, 87, 60, 85,
+  105, 74, 92, 41, 87, 72, 102, 87, 45, 72,
+  80, 80, 82, 125, 91, 67, 102, 39, 62, 75,
+  90, 81, 86, 65, 79, 89, 90, 88, 86, 100,
+  75, 83, 85, 78, 78, 97, 70, 85, 81, 91,
+  93, 83, 82, 69, 79, 77, 73, 91, 79, 70,
+  82, 77, 98, 97, 76, 86, 88, 92, 81, 80,
+  82, 80, 79, 89, 86, 88, 86, 81, 85, 96,
+  90, 83, 97, 81, 83, 88, 83, 76, 88, 88,
+  85, 60, 73, 102, 92, 92, 95, 65, 80, 73,
+  68, 96, 82, 91, 75, 84, 93, 80, 76, 83,
+  85, 83, 70, 75, 87, 66, 79, 95, 80, 85,
+  99, 104, 86, 93, 80, 102, 82, 105, 115, 80,
+  81, 85, 85, 80, 65, 75, 79, 82, 84, 90,
+  83, 73, 82, 87, 100, 88, 73, 83, 74, 89,
+  114, 93, 84, 79, 95, 65, 84, 85, 82, 86,
+  75, 90, 90, 76, 84, 91, 78, 76, 70, 82,
+  80, 74, 76, 81, 83, 92, 77, 91, 95, 91,
+  91, 85, 86, 75, 85, 112, 76, 72, 103, 81,
+  81, 73, 94, 86, 78, 81, 93, 104, 88, 81,
+  86, 83, 89, 76, 78, 74, 69, 91, 93, 82,
+  89, 77, 78, 76, 78, 79, 84, 85, 74, 73,
+  83, 115, 81, 100, 94, 85, 93, 69, 74, 81,
+  89, 113, 92, 80, 107, 87, 78, 76, 84, 93,
+  86, 75, 81, 79, 98, 91, 76, 86, 75, 104,
+  83, 86, 75, 76, 83, 121, 84, 67, 85, 84,
+  92, 79, 58, 87, 95, 78, 76, 80, 92, 70,
+  79, 92, 83, 92, 75, 86, 84, 97, 70, 80,
+  90, 93, 84, 67, 70, 90, 83, 74, 77, 93,
+  82, 76, 85, 84, 69, 76, 70, 79, 72, 62,
+  80, 75, 70, 93, 87, 95, 101, 82, 87, 62,
+  79, 71, 75, 103, 73, 74, 101, 70, 101, 95,
+  87, 71, 75, 71, 80, 87, 78, 96, 94, 71,
+  83, 73, 82, 73, 65, 77, 80, 80, 89, 71,
+  83, 80, 72, 81, 77, 84, 68, 75, 75, 138,
+  89, 91, 78, 93, 94, 70, 67, 82, 91, 89,
+  87, 91, 100, 83, 75, 72, 72, 80, 83, 78,
+  81, 88, 100, 97, 88, 96, 75, 108, 69, 80,
+  62, 71, 75, 119, 78, 64, 95, 91, 81, 77,
+  58, 90, 88, 77, 69, 78, 97, 52, 68, 87,
+  87, 87, 63, 77, 80, 79, 90, 90, 82, 90,
+  91, 57, 61, 89, 80, 78, 83, 85, 83, 88,
+  81, 92, 87, 93, 79, 85, 83, 85, 76, 89,
+  78, 83, 75, 88, 95, 87, 87, 76, 81, 73,
+  71, 105, 83, 73, 96, 92, 77, 103, 83, 80,
+  84, 95, 75, 81, 90, 79, 87, 92, 94, 89,
+  86, 89, 76, 100, 100, 88, 92, 79, 79, 83,
+  87, 80, 93, 87, 79, 75, 86, 91, 85, 97,
+  100, 63, 79, 74, 69, 86, 85, 103, 85, 77,
+  91, 83, 86, 82, 95, 77, 76, 70, 89, 74,
+  95, 85, 78, 80, 93, 103, 88, 82, 87, 87,
+  90, 99, 104, 74, 79, 79, 100, 78, 66, 102,
+  88, 77, 76, 83, 76, 90, 83, 96, 91, 90,
+  85, 77, 91, 95, 92, 81, 89, 88, 85, 75,
+  89, 86, 87, 86, 76, 93, 85, 82, 99, 89,
+  84, 80, 80, 94, 92, 70, 85, 88, 98, 76,
+  74, 83, 99, 97, 97, 89, 47, 74, 96, 95,
+  100, 69, 81, 84, 88, 90, 75, 87, 99, 75,
+  84, 87, 71, 81, 91, 86, 69, 82, 97, 84,
+  82, 83, 105, 70, 76, 93, 90, 97, 83, 84,
+  96, 89, 89, 94, 90, 81, 78, 82, 73, 77,
+  69, 98, 95, 82, 89, 93, 91, 80, 95, 67,
+  84, 80, 82, 95, 60, 91, 87, 84, 90, 99,
+  79, 87, 78, 88, 91, 76, 94, 77, 93, 84,
+  92, 71, 94, 96, 80, 99, 78, 88, 75, 97,
+  84, 103, 81, 79, 71, 84, 74, 86, 85, 85,
+  73, 85, 82, 98, 93, 77, 89, 88, 84, 83,
+  97, 79, 85, 81, 75, 83, 113, 95, 93, 81,
+  80, 79, 84, 84, 78, 79, 74, 101, 74, 80,
+  69, 70, 75, 92, 76, 70, 99, 101, 86, 82,
+  79, 81, 109, 106, 78, 89, 72, 84, 77, 102,
+  79, 87, 86, 73, 80, 66, 66, 71, 88, 89,
+  90, 73, 103, 68, 81, 70, 79, 72, 76, 69,
+  85, 85, 80, 78, 86, 98, 89, 73, 55, 74,
+  93, 79, 80, 90, 82, 99, 92, 77, 85, 72,
+  87, 94, 69, 83, 80, 92, 81, 101, 91, 100,
+  83, 95, 79, 82, 74, 79, 99, 83, 92, 77,
+  90, 84, 66, 69, 68, 66, 77, 96, 79, 87,
+  78, 78, 73, 68, 102, 78, 67, 84, 80, 82,
+  108, 90, 73, 79, 81, 81, 73, 79, 77, 94,
+  73, 74, 77, 66, 97, 85, 86, 84, 80, 75,
+  83, 84, 78, 81, 91, 100, 71, 74, 68, 77,
+  82, 89, 90, 68, 79, 98, 73, 80, 92, 85,
+  83, 95, 82, 90, 80, 75, 86, 98, 93, 84,
+  88, 78, 85, 70, 73, 76, 100, 84, 75, 76,
+  96, 77, 83, 78, 82, 72, 77, 80, 85, 87,
+  80, 85, 97, 91, 102, 67, 69, 76, 87, 79,
+  74, 83, 86, 92, 96, 88, 78, 71, 90, 103,
+  88, 83, 84, 98, 82, 92, 88, 92, 91, 83,
+  81, 89, 84, 96, 99, 81, 85, 82, 91, 89,
+  76, 70, 75, 73, 91, 89, 84, 92, 84, 81,
+  85, 80, 101, 78, 76, 88, 87, 91, 86, 89,
+  74, 95, 104, 81, 77, 84, 82, 107, 76, 85,
+  78, 79, 109, 95, 88, 74, 70, 80, 82, 83,
+  77, 73, 87, 97, 72, 81, 91, 75, 78, 89,
+  81, 66, 100, 91, 95, 81, 75, 83, 118, 101,
+  78, 95, 72, 84, 71, 94, 88, 85, 95, 95,
+  84, 73, 61, 74, 75, 79, 88, 83, 105, 73,
+  75, 68, 76, 72, 73, 81, 80, 88, 78, 78,
+  89, 90, 84, 66, 53, 77, 96, 86, 91, 83,
+  68, 85, 96, 74, 85, 74, 86, 85, 74, 85,
+  79, 87, 77, 99, 91, 98, 85, 100, 75, 66,
+  76, 74, 97, 84, 93, 71, 89, 91, 78, 76,
+  70, 79, 81, 93, 85, 96, 76, 82, 66, 66,
+  79, 80, 68, 91, 75, 88, 93, 96, 78, 72,
+  94, 79, 71, 81, 82, 92, 76, 69, 70, 64,
+  105, 85, 90, 75, 78, 66, 82, 90, 78, 76,
+  75, 107, 80, 76, 77, 67, 73, 85, 116, 70,
+  88, 93, 78, 82, 79, 83, 108, 97, 85, 89,
+  67, 78, 66, 85, 85, 80, 86, 76, 97, 68,
+  48, 70, 79, 82, 78, 80, 92, 78, 74, 74,
+  75, 66, 62, 76, 71, 81, 77, 84, 98, 79,
+  88, 66, 45, 67, 92, 74, 75, 70, 65, 89,
+  87, 87, 84, 76, 96, 88, 79, 82, 80, 91,
+  82, 85, 85, 96, 89, 99, 76, 80, 64, 70,
+  90, 79, 82, 78, 89, 88, 75, 67, 66, 65,
+  90, 85, 87, 84, 83, 87, 74, 64, 94, 76,
+  65, 80, 81, 72, 93, 83, 69, 86, 94, 75,
+  74, 77, 75, 95, 78, 75, 79, 68, 85, 77,
+  85, 83, 85, 72, 92, 77, 87, 78, 94, 88,
+  92, 73, 85, 91, 93, 83, 106, 82, 79, 92,
+  71, 69, 88, 86, 92, 86, 96, 95, 94, 67,
+  84, 79, 93, 81, 91, 82, 92, 77, 79, 84,
+  96, 81, 79, 80, 78, 91, 81, 96, 86, 82,
+  85, 95, 89, 87, 86, 93, 92, 82, 96, 71,
+  71, 90, 76, 84, 69, 77, 84, 79, 89, 91,
+  82, 78, 92, 90, 87, 82, 89, 85, 81, 77,
+  85, 79, 85, 85, 85, 90, 84, 74, 85, 79,
+  77, 78, 91, 99, 85, 80, 77, 89, 95, 78,
+  82, 91, 90, 89, 85, 89, 88, 84, 88, 87,
+  72, 86, 76, 85, 82, 94, 107, 88, 89, 84,
+  88, 92, 88, 97, 80, 80, 96, 87, 85, 95,
+  78, 74, 73, 86, 80, 79, 90, 98, 66, 78,
+  86, 73, 85, 87, 119, 70, 88, 91, 83, 83,
+  79, 83, 93, 88, 88, 101, 76, 87, 68, 104,
+  86, 80, 96, 100, 93, 65, 55, 73, 72, 79,
+  85, 89, 103, 75, 80, 76, 74, 69, 73, 86,
+  75, 88, 77, 81, 98, 92, 93, 65, 72, 72,
+  90, 83, 97, 73, 82, 86, 93, 83, 84, 73,
+  80, 101, 73, 87, 80, 86, 78, 88, 93, 101,
+  91, 96, 87, 70, 76, 77, 95, 80, 87, 73,
+  88, 87, 82, 73, 65, 89, 85, 93, 85, 86,
+  81, 86, 82, 67, 79, 79, 65, 91, 73, 83,
+  90, 84, 73, 73, 109, 76, 76, 78, 82, 94,
+  79, 77, 82, 69, 80, 86, 80, 88, 89, 70,
+  87, 81, 82, 89, 84, 94, 83, 82, 82, 88,
+  92, 73, 129, 77, 77, 90, 74, 75, 84, 82,
+  99, 89, 92, 93, 91, 76, 79, 80, 87, 85,
+  92, 76, 90, 75, 51, 79, 79, 84, 81, 84,
+  79, 87, 85, 98, 80, 80, 78, 89, 83, 86,
+  82, 89, 90, 74, 89, 73, 67, 80, 84, 76,
+  82, 74, 85, 83, 89, 96, 83, 76, 92, 88,
+  78, 86, 89, 91, 90, 82, 81, 89, 84, 88,
+  92, 81, 76, 75, 93, 84, 80, 81, 91, 92,
+  95, 82, 69, 87, 88, 85, 78, 94, 76, 89,
+  79, 84, 91, 86, 76, 84, 77, 79, 85, 86,
+  77, 87, 102, 84, 84, 84, 82, 87, 89, 88,
+  86, 76, 81, 78, 76, 86, 91, 79, 81, 75,
+  85, 85, 93, 90, 92, 73, 81, 103, 87, 84,
+  113, 89, 79, 90, 72, 72, 94, 84, 81, 99,
+  95, 93, 105, 77, 92, 81, 90, 91, 91, 76,
+  85, 86, 78, 92, 93, 80, 86, 91, 76, 89,
+  80, 107, 96, 88, 96, 90, 101, 90, 86, 88,
+  78, 86, 89, 79, 72, 97, 71, 93, 76, 83,
+  95, 79, 88, 91, 88, 83, 75, 87, 79, 73,
+  100, 86, 80, 75, 87, 82, 74, 75, 86, 79,
+  89, 69, 82, 77, 78, 88, 84, 85, 87, 90,
+  78, 102, 87, 81, 79, 101, 82, 88, 76, 96,
+  94, 90, 89, 92, 82, 89, 85, 88, 85, 96,
+  100, 90, 81, 82, 103, 77, 91, 92, 101, 95,
+  81, 80, 83, 87, 66, 93, 96, 109, 75, 78,
+  95, 87, 80, 85, 106, 83, 66, 65, 91, 103,
+  80, 66, 83, 80, 97, 81, 81, 81, 93, 80,
+  72, 91, 100, 89, 91, 76, 93, 90, 73, 71,
+  81, 86, 77, 70, 86, 80, 66, 79, 90, 75,
+  91, 75, 70, 85, 75, 92, 89, 105, 104, 80,
+  73, 90, 90, 94, 80, 91, 73, 97, 81, 90,
+  96, 86, 83, 57, 88, 88, 79, 90, 84, 85,
+  104, 93, 88, 93, 77, 104, 90, 96, 105, 86,
+  89, 86, 83, 90, 93, 88, 89, 73, 88, 79,
+  97, 87, 80, 73, 95, 95, 79, 74, 86, 81,
+  57, 69, 79, 108, 80, 90, 98, 83, 96, 101,
+  78, 93, 90, 82, 72, 72, 90, 95, 80, 82,
+  82, 76, 70, 86, 90, 107, 74, 83, 91, 90,
+  77, 76, 91, 78, 66, 71, 78, 89, 76, 62,
+  102, 86, 90, 80, 91, 91, 87, 70, 73, 73,
+  91, 94, 93, 76, 80, 91, 78, 66, 85, 88,
+  74, 78, 84, 89, 61, 81, 85, 80, 90, 72,
+  71, 86, 65, 80, 89, 101, 109, 65, 69, 84,
+  75, 97, 71, 96, 73, 91, 92, 96, 97, 78,
+  92, 57, 87, 78, 88, 86, 82, 83, 105, 84,
+  91, 92, 74, 103, 77, 89, 98, 85, 97, 81,
+  86, 94, 90, 80, 86, 71, 84, 101, 89, 89,
+  69, 71, 98, 94, 72, 74, 96, 81, 49, 87,
+  76, 104, 79, 101, 98, 80, 93, 94, 78, 77,
+  99, 76, 72, 64, 91, 78, 90, 92, 82, 86,
+  76, 105, 88, 92, 81, 80, 73, 84, 81, 89,
+  83, 82, 75, 86, 79, 93, 94, 76, 101, 84,
+  90, 90, 82, 96, 79, 94, 84, 79, 81, 95,
+  95, 82, 69, 78, 98, 74, 85, 83, 85, 90,
+  85, 99, 87, 79, 83, 76, 83, 84, 92, 85,
+  91, 84, 78, 84, 94, 70, 77, 67, 75, 90,
+  84, 82, 94, 68, 84, 84, 96, 84, 91, 67,
+  87, 86, 77, 95, 83, 84, 82, 73, 75, 80,
+  66, 66, 84, 87, 96, 97, 106, 86, 94, 83,
+  109, 82, 88, 76, 71, 83, 96, 84, 91, 86,
+  66, 92, 82, 79, 88, 85, 73, 83, 75, 82,
+  89, 89, 77, 79, 96, 83, 94, 101, 90, 78,
+  78, 89, 82, 82, 76, 81, 75, 94, 81, 73,
+  86, 101, 75, 84, 76, 88, 78, 83, 91, 77,
+  69, 76, 84, 86, 72, 66, 95, 81, 82, 81,
+  94, 80, 100, 85, 71, 99, 109, 83, 89, 52,
+  76, 75, 106, 54, 85, 87, 58, 78, 80, 76,
+  64, 83, 92, 79, 88, 73, 90, 94, 72, 90,
+  97, 97, 98, 69, 86, 90, 98, 90, 75, 96,
+  73, 64, 96, 91, 90, 77, 84, 67, 81, 76,
+  78, 80, 90, 87, 83, 89, 90, 83, 87, 92,
+  87, 105, 99, 98, 113, 86, 83, 95, 90, 85,
+  81, 71, 74, 72, 90, 83, 80, 72, 92, 88,
+  77, 76, 90, 82, 56, 66, 80, 107, 60, 94,
+  83, 83, 83, 80, 77, 97, 89, 74, 71, 64,
+  71, 87, 86, 81, 73, 76, 88, 69, 77, 97,
+  75, 92, 79, 90, 78, 79, 81, 75, 65, 85,
+  82, 76, 97, 64, 101, 82, 73, 81, 108, 98,
+  109, 78, 70, 84, 92, 90, 91, 44, 83, 67,
+  131, 57, 80, 89, 57, 75, 75, 97, 58, 82,
+  92, 85, 91, 69, 83, 85, 61, 71, 100, 89,
+  103, 59, 78, 86, 75, 93, 73, 106, 74, 66,
+  78, 100, 79, 76, 95, 62, 83, 69, 73, 74,
+  86, 84, 82, 80, 91, 94, 72, 98, 74, 95,
+  85, 86, 116, 86, 69, 104, 86, 84, 93, 61,
+  76, 81, 82, 82, 64, 64, 95, 88, 77, 70,
+  102, 80, 51, 91, 81, 110, 85, 99, 81, 82,
+  84, 78, 78, 77, 93, 68, 69, 63, 82, 75,
+  88, 94, 84, 82, 80, 91, 81, 92, 82, 80,
+  75, 88, 71, 84, 80, 81, 85, 93, 83, 76,
+  101, 81, 89, 80, 77, 92, 101, 88, 79, 104,
+  85, 82, 78, 93, 92, 75, 72, 70, 107, 69,
+  74, 86, 73, 100, 75, 95, 82, 81, 77, 75,
+  88, 86, 97, 80, 87, 82, 72, 74, 88, 72,
+  91, 70, 68, 88, 75, 77, 90, 61, 81, 77,
+  86, 83, 88, 78, 75, 77, 73, 87, 84, 75,
+  79, 81, 70, 78, 65, 73, 74, 89, 100, 83,
+  99, 90, 97, 82, 99, 79, 99, 74, 72, 79,
+  96, 80, 100, 78, 73, 87, 85, 76, 93, 76,
+  74, 93, 83, 87, 108, 88, 72, 83, 90, 75,
+  103, 87, 93, 74, 80, 85, 95, 81, 88, 84,
+  88, 71, 82, 72, 89, 82, 83, 91, 78, 85,
+  65, 78, 84, 78, 99, 86, 84, 89, 86, 81,
+  98, 63, 109, 91, 89, 84, 80, 112, 94, 102,
+  80, 86, 84, 72, 71, 70, 109, 61, 89, 83,
+  79, 108, 75, 77, 94, 82, 86, 89, 91, 81,
+  99, 73, 94, 88, 77, 80, 94, 69, 91, 78,
+  78, 89, 71, 83, 84, 75, 86, 87, 101, 78,
+  75, 81, 93, 65, 76, 78, 95, 85, 83, 87,
+  79, 77, 80, 67, 76, 93, 102, 83, 103, 92,
+  81, 78, 100, 87, 72, 77, 70, 73, 95, 78,
+  123, 93, 74, 79, 102, 74, 86, 83, 76, 70,
+  77, 79, 71, 95, 75, 100, 82, 77, 82, 100,
+  92, 82, 79, 90, 86, 76, 74, 86, 89, 73,
+  84, 71, 85, 85, 80, 91, 80, 81, 70, 74,
+  76, 83, 93, 91, 94, 87, 84, 87, 89, 64,
+  107, 89, 101, 86, 83, 105, 93, 88, 80, 75,
+  81, 63, 86, 59, 127, 58, 79, 84, 88, 111,
+  65, 78, 91, 83, 87, 86, 92, 83, 103, 86,
+  94, 77, 73, 74, 95, 74, 88, 84, 65, 89,
+  77, 83, 81, 81, 76, 85, 96, 80, 80, 83,
+  91, 67, 80, 70, 90, 82, 82, 74, 74, 89,
+  70, 71, 67, 90, 97, 76, 96, 94, 79, 79,
+  95, 88, 96, 76, 73, 75, 91, 76, 136, 79,
+  67, 80, 110, 71, 96, 77, 79, 78, 81, 79,
+  82, 101, 77, 94, 86, 79, 85, 88, 94, 84,
+  75, 94, 86, 76, 68, 94, 90, 96, 83, 85,
+  81, 74, 84, 83, 80, 83, 68, 82, 83, 83,
+  108, 86, 89, 81, 74, 88, 87, 84, 95, 69,
+  83, 76, 73, 107, 102, 84, 79, 83, 85, 80,
+  80, 69, 92, 73, 77, 88, 84, 98, 73, 77,
+  83, 80, 85, 82, 93, 101, 97, 77, 95, 91,
+  62, 75, 82, 75, 90, 68, 70, 91, 78, 74,
+  87, 72, 78, 79, 95, 80, 80, 85, 78, 75,
+  83, 83, 94, 84, 89, 75, 75, 82, 77, 62,
+  78, 83, 81, 78, 86, 91, 89, 77, 88, 80,
+  100, 73, 66, 80, 91, 76, 106, 92, 78, 85,
+  88, 91, 82, 70, 89, 87, 92, 79, 86, 90,
+  84, 93, 95, 80, 95, 95, 91, 78, 86, 97,
+  101, 95, 91, 80, 72, 78, 82, 95, 93, 84,
+  77, 94, 85, 97, 67, 70, 70, 56, 81, 82,
+  69, 117, 93, 76, 81, 91, 103, 80, 100, 89,
+  81, 84, 76, 81, 91, 86, 108, 86, 74, 69,
+  96, 80, 68, 75, 85, 74, 81, 86, 87, 79,
+  85, 92, 92, 81, 98, 100, 74, 90, 99, 83,
+  88, 83, 113, 73, 60, 84, 79, 77, 59, 136,
+  80, 101, 75, 95, 82, 80, 79, 87, 66, 74,
+  83, 72, 84, 80, 75, 80, 74, 114, 85, 90,
+  86, 81, 90, 90, 99, 78, 85, 81, 89, 81,
+  98, 81, 87, 88, 82, 65, 87, 79, 111, 72,
+  84, 60, 85, 77, 116, 101, 99, 85, 106, 77,
+  70, 72, 97, 93, 89, 85, 72, 84, 102, 79,
+  93, 87, 63, 86, 72, 91, 104, 90, 75, 98,
+  100, 89, 65, 68, 77, 64, 103, 70, 58, 102,
+  83, 77, 84, 83, 104, 85, 98, 85, 69, 84,
+  80, 89, 89, 75, 116, 88, 79, 76, 98, 81,
+  60, 78, 78, 70, 98, 87, 79, 81, 86, 93,
+  90, 82, 119, 111, 77, 85, 94, 83, 91, 84,
+  112, 77, 62, 94, 74, 80, 58, 151, 113, 100,
+  72, 91, 77, 85, 77, 81, 59, 78, 77, 62,
+  83, 81, 77, 76, 77, 120, 86, 88, 78, 95,
+  96, 80, 98, 76, 95, 77, 89, 90, 101, 110,
+  94, 91, 86, 60, 88, 87, 117, 73, 81, 63,
+  78, 82, 121, 104, 97, 82, 118, 70, 77, 72,
+  101, 91, 97, 85, 74, 80, 89, 69, 78, 79,
+  81, 90, 82, 103, 93, 84, 77, 95, 83, 77,
+  73, 72, 72, 63, 78, 74, 68, 95, 79, 74,
+  85, 96, 98, 88, 88, 80, 83, 86, 85, 86,
+  81, 81, 105, 97, 86, 70, 92, 79, 80, 77,
+  88, 74, 83, 83, 85, 79, 86, 78, 84, 86,
+  93, 87, 75, 89, 98, 83, 82, 83, 109, 75,
+  59, 83, 74, 82, 70, 109, 103, 93, 79, 94,
+  76, 80, 80, 85, 72, 76, 84, 81, 81, 85,
+  76, 77, 79, 96, 83, 95, 89, 79, 90, 86,
+  97, 79, 88, 79, 83, 82, 94, 97, 84, 88,
+  83, 74, 81, 78, 108, 81, 81, 73, 88, 79,
+  110, 89, 77, 83, 96, 84, 88, 76, 98, 93,
+  90, 88, 73, 82, 98, 95, 98, 80, 84, 86,
+  87, 86, 79, 89, 75, 94, 92, 85, 85, 81,
+  78, 84, 86, 85, 63, 93, 106, 85, 91, 98,
+  76, 74, 86, 96, 93, 86, 81, 81, 82, 87,
+  79, 83, 79, 78, 80, 77, 82, 78, 81, 84,
+  94, 87, 85, 75, 76, 91, 91, 80, 90, 84,
+  82, 82, 65, 88, 84, 74, 80, 73, 82, 78,
+  80, 90, 78, 111, 75, 91, 73, 83, 88, 73,
+  70, 73, 65, 72, 89, 78, 93, 86, 87, 82,
+  78, 92, 89, 96, 77, 87, 68, 93, 86, 81,
+  88, 76, 87, 84, 77, 69, 85, 82, 88, 71,
+  85, 89, 92, 78, 74, 90, 79, 76, 97, 79,
+  103, 85, 84, 79, 92, 72, 83, 92, 73, 74,
+  95, 88, 87, 97, 85, 91, 81, 82, 83, 91,
+  77, 87, 76, 92, 110, 78, 77, 87, 86, 90,
+  94, 91, 73, 70, 80, 94, 98, 87, 80, 72,
+  78, 84, 96, 91, 86, 82, 87, 72, 79, 94,
+  75, 80, 74, 73, 72, 93, 79, 97, 106, 76,
+  80, 70, 82, 66, 85, 78, 74, 93, 79, 79,
+  52, 89, 82, 81, 76, 80, 62, 72, 74, 110,
+  80, 73, 78, 78, 75, 80, 98, 69, 72, 74,
+  61, 78, 85, 85, 94, 76, 92, 80, 79, 73,
+  89, 118, 82, 86, 55, 97, 74, 77, 89, 68,
+  102, 80, 63, 76, 80, 83, 92, 61, 84, 97,
+  98, 71, 73, 91, 77, 78, 88, 70, 75, 84,
+  87, 73, 86, 70, 73, 92, 72, 79, 99, 81,
+  95, 86, 85, 82, 85, 105, 89, 95, 80, 89,
+  75, 94, 79, 80, 91, 77, 80, 82, 85, 84,
+  83, 95, 82, 81, 91, 100, 84, 79, 77, 80,
+  91, 81, 83, 80, 90, 83, 82, 87, 79, 78,
+  81, 81, 72, 78, 87, 80, 85, 74, 82, 77,
+  76, 81, 85, 84, 95, 97, 80, 80, 72, 79,
+  82, 79, 88, 76, 82, 82, 78, 87, 78, 95,
+  112, 88, 76, 87, 83, 79, 79, 86, 74, 75,
+  92, 82, 95, 88, 84, 80, 81, 89, 87, 87,
+  74, 89, 76, 89, 97, 89, 91, 75, 89, 88,
+  82, 91, 86, 87, 88, 74, 86, 88, 90, 85,
+  76, 86, 86, 82, 85, 75, 80, 89, 82, 84,
+  82, 76, 81, 89, 72, 78, 89, 88, 85, 77,
+  85, 86, 85, 88, 78, 87, 74, 94, 77, 95,
+  99, 76, 89, 73, 75, 89, 76, 77, 76, 81,
+  97, 75, 88, 93, 71, 82, 81, 87, 83, 84,
+  96, 88, 86, 89, 72, 80, 85, 85, 80, 80,
+  90, 90, 79, 89, 84, 87, 82, 79, 81, 81,
+  79, 88, 80, 83, 75, 78, 79, 79, 75, 76,
+  74, 73, 87, 86, 83, 83, 82, 73, 84, 87,
+  82, 77, 83, 68, 87, 79, 87, 80, 90, 83,
+  94, 84, 77, 72, 82, 81, 89, 102, 75, 90,
+  83, 82, 83, 83, 84, 75, 76, 91, 76, 82,
+  85, 89, 78, 75, 84, 89, 80, 87, 76, 96,
+  86, 84, 80, 80, 82, 88, 79, 90, 92, 80,
+  79, 80, 71, 87, 95, 87, 75, 87, 81, 90,
+  88, 86, 87, 83, 72, 84, 78, 88, 110, 91,
+  94, 83, 80, 96, 67, 87, 87, 77, 88, 78,
+  87, 92, 63, 73, 79, 90, 83, 81, 91, 88,
+  82, 73, 78, 86, 82, 97, 82, 83, 88, 103,
+  77, 92, 81, 79, 84, 72, 87, 84, 73, 86,
+  66, 80, 68, 80, 74, 81, 67, 81, 74, 81,
+  75, 87, 79, 89, 92, 70, 74, 76, 80, 81,
+  93, 58, 90, 82, 85, 85, 91, 99, 94, 71,
+  85, 77, 84, 73, 91, 93, 66, 88, 80, 85,
+  72, 90, 81, 65, 88, 88, 65, 75, 79, 90,
+  74, 76, 78, 91, 65, 80, 80, 94, 85, 83,
+  83, 78, 72, 90, 72, 91, 84, 78, 64, 79,
+  65, 90, 96, 81, 89, 97, 80, 88, 82, 97,
+  84, 89, 74, 95, 79, 90, 90, 89, 87, 70,
+  74, 81, 76, 84, 87, 91, 84, 75, 82, 98,
+  82, 84, 77, 89, 81, 79, 94, 75, 87, 79,
+  74, 84, 80, 81, 81, 79, 76, 84, 87, 86,
+  73, 74, 83, 81, 83, 86, 82, 88, 82, 74,
+  76, 79, 79, 74, 79, 77, 81, 72, 83, 85,
+  80, 81, 84, 79, 87, 87, 83, 85, 87, 78,
+  89, 89, 82, 82, 94, 83, 98, 89, 75, 73,
+  78, 85, 89, 91, 76, 83, 84, 79, 86, 84,
+  86, 74, 90, 89, 82, 81, 88, 92, 79, 79,
+  87, 83, 80, 90, 77, 88, 88, 82, 86, 80,
+  89, 86, 80, 91, 86, 82, 83, 85, 72, 89,
+  90, 89, 72, 81, 79, 80, 92, 89, 73, 91,
+  90, 87, 80, 90, 68, 85, 58, 95, 90, 78,
+  94, 96, 79, 73, 89, 83, 94, 96, 91, 86,
+  88, 85, 84, 85, 77, 83, 80, 114, 82, 86,
+  88, 79, 78, 82, 66, 94, 97, 81, 84, 74,
+  78, 89, 81, 90, 76, 86, 87, 92, 93, 83,
+  97, 89, 85, 88, 82, 65, 63, 82, 72, 112,
+  89, 86, 104, 82, 88, 79, 75, 95, 88, 73,
+  87, 86, 85, 87, 95, 97, 87, 86, 60, 89,
+  88, 79, 112, 76, 82, 88, 98, 83, 83, 84,
+  86, 80, 87, 99, 89, 88, 65, 86, 101, 89,
+  72, 78, 76, 86, 82, 120, 79, 94, 59, 83,
+  80, 84, 74, 80, 71, 100, 81, 76, 87, 82,
+  80, 85, 94, 67, 85, 86, 86, 63, 79, 43,
+  62, 87, 104, 78, 78, 96, 86, 84, 54, 82,
+  82, 79, 86, 117, 82, 77, 85, 67, 110, 96,
+  73, 89, 72, 76, 88, 92, 77, 100, 87, 91,
+  75, 92, 95, 87, 84, 88, 89, 93, 75, 89,
+  67, 89, 86, 84, 80, 92, 78, 64, 86, 89,
+  73, 72, 76, 98, 67, 90, 87, 76, 84, 83,
+  98, 87, 75, 77, 83, 65, 79, 80, 79, 84,
+  84, 84, 53, 86, 76, 87, 66, 87, 81, 96,
+  67, 76, 59, 94, 73, 94, 99, 80, 98, 80,
+  76, 77, 77, 86, 137, 70, 77, 85, 82, 90,
+  91, 101, 75, 86, 80, 99, 81, 101, 81, 74,
+  80, 91, 82, 59, 76, 87, 81, 86, 79, 90,
+  83, 79, 92, 77, 93, 74, 79, 52, 72, 83,
+  82, 78, 70, 93, 88, 89, 67, 91, 85, 84,
+  80, 97, 89, 82, 86, 73, 88, 96, 80, 84,
+  75, 77, 89, 78, 91, 87, 71, 81, 80, 83,
+  83, 81, 83, 82, 88, 91, 71, 88, 73, 84,
+  88, 93, 85, 80, 84, 76, 90, 87, 80, 79,
+  89, 91, 90, 82, 85, 86, 82, 83, 87, 88,
+  88, 80, 84, 78, 77, 83, 84, 84, 83, 79,
+  70, 89, 83, 93, 91, 84, 89, 97, 69, 94,
+  69, 99, 102, 95, 92, 81, 84, 85, 91, 89,
+  85, 88, 92, 84, 86, 84, 80, 89, 90, 107,
+  83, 72, 91, 90, 99, 97, 75, 83, 82, 88,
+  77, 89, 79, 88, 95, 78, 80, 74, 96, 82,
+  91, 81, 81, 99, 91, 90, 80, 94, 68, 94,
+  61, 91, 85, 79, 101, 93, 74, 81, 97, 76,
+  86, 94, 82, 84, 87, 89, 84, 81, 80, 87,
+  70, 112, 93, 48, 84, 76, 87, 72, 67, 85,
+  104, 85, 75, 73, 83, 83, 75, 92, 72, 86,
+  91, 82, 91, 85, 94, 88, 84, 85, 89, 66,
+  68, 76, 66, 104, 87, 101, 72, 79, 88, 88,
+  77, 102, 90, 62, 75, 83, 83, 77, 95, 100,
+  81, 93, 63, 91, 80, 73, 106, 76, 91, 83,
+  105, 83, 84, 92, 77, 79, 93, 97, 93, 90,
+  68, 84, 101, 86, 83, 75, 80, 76, 88, 133,
+  82, 89, 74, 76, 76, 83, 82, 85, 70, 102,
+  84, 82, 81, 79, 84, 80, 102, 70, 83, 81,
+  89, 66, 79, 43, 62, 83, 108, 88, 88, 90,
+  87, 77, 54, 79, 86, 83, 78, 114, 82, 81,
+  75, 63, 110, 96, 78, 92, 77, 79, 80, 94,
+  66, 102, 75, 91, 74, 94, 97, 80, 84, 86,
+  86, 98, 78, 84, 70, 92, 84, 87, 75, 79,
+  73, 69, 81, 83, 76, 73, 76, 93, 64, 92,
+  87, 70, 86, 67, 85, 81, 68, 86, 77, 70,
+  75, 75, 69, 88, 87, 83, 55, 87, 73, 95,
+  65, 83, 79, 83, 64, 68, 56, 92, 64, 85,
+  99, 87, 80, 80, 65, 83, 77, 86, 108, 76,
+  77, 83, 70, 95, 96, 91, 71, 89, 80, 82,
+  86, 98, 75, 72, 80, 97, 89, 52, 75, 83,
+  73, 87, 86, 84, 79, 81, 86, 71, 99, 73,
+  83, 56, 75, 85, 83, 82, 78, 88, 85, 84,
+  69, 91, 83, 91, 81, 91, 94, 87, 76, 73,
+  90, 85, 77, 79, 82, 78, 94, 84, 78, 77,
+  82, 79, 78, 84, 88, 77, 83, 75, 90, 74,
+  69, 87, 70, 88, 86, 97, 83, 87, 78, 80,
+  89, 86, 82, 81, 93, 90, 81, 91, 84, 90,
+  87, 74, 87, 85, 84, 87, 79, 81, 79, 95,
+  84, 84, 87, 78, 74, 87, 89, 95, 90, 88,
+  94, 85, 69, 83, 69, 90, 88, 87, 91, 83,
+  83, 86, 77, 93, 87, 86, 73, 83, 82, 79,
+  68, 97, 92, 97, 80, 73, 84, 86, 96, 102,
+  74, 79, 71, 93, 83, 81, 77, 87, 88, 83,
+  91, 81, 104, 85, 84, 75, 82, 92, 86, 89,
+  77, 92, 74, 94, 77, 92, 82, 82, 89, 92,
+  71, 79, 102, 89, 94, 86, 85, 85, 76, 89,
+  82, 81, 84, 77, 68, 89, 98, 73, 90, 79,
+  84, 84, 84, 85, 86, 90, 96, 84, 84, 81,
+  78, 92, 79, 86, 91, 99, 85, 88, 91, 77,
+  83, 73, 84, 70, 77, 79, 76, 81, 83, 98,
+  64, 76, 84, 87, 86, 90, 91, 66, 89, 77,
+  80, 83, 86, 90, 85, 82, 68, 87, 90, 81,
+  86, 73, 82, 85, 94, 78, 92, 89, 78, 77,
+  89, 94, 98, 90, 94, 83, 85, 85, 91, 85,
+  89, 83, 87, 109, 87, 91, 86, 85, 91, 88,
+  86, 87, 78, 85, 73, 99, 84, 91, 83, 84,
+  97, 86, 77, 79, 90, 69, 75, 56, 65, 83,
+  93, 81, 93, 83, 84, 80, 67, 84, 87, 79,
+  86, 111, 89, 82, 82, 65, 95, 93, 78, 88,
+  76, 83, 83, 84, 79, 120, 75, 90, 84, 90,
+  94, 83, 81, 84, 89, 94, 74, 88, 78, 88,
+  84, 87, 82, 82, 78, 78, 84, 78, 77, 75,
+  84, 97, 80, 89, 91, 71, 84, 78, 82, 78,
+  78, 87, 80, 78, 79, 73, 80, 82, 85, 89,
+  61, 91, 77, 83, 71, 85, 82, 84, 74, 69,
+  65, 89, 77, 85, 98, 83, 76, 84, 77, 93,
+  82, 85, 82, 81, 79, 89, 68, 99, 86, 98,
+  79, 80, 83, 81, 84, 94, 80, 82, 83, 90,
+  82, 62, 72, 91, 89, 95, 87, 87, 78, 91,
+  83, 81, 96, 77, 86, 70, 75, 90, 83, 79,
+  80, 86, 82, 81, 79, 94, 84, 79, 84, 100,
+  90, 88, 83, 78, 79, 84, 80, 81, 79, 83,
+  92, 82, 82, 90, 81, 83, 81, 79, 85, 82,
+  83, 89, 83, 73, 65, 93, 78, 89, 85, 94,
+  89, 81, 85, 87, 85, 78, 81, 78, 94, 87,
+  92, 82, 82, 85, 83, 90, 78, 84, 92, 87,
+  82, 90, 83, 95, 89, 80, 87, 81, 77, 86,
+  87, 81, 93, 85, 96, 91, 86, 76, 77, 89,
+  92, 84, 88, 76, 83, 89, 85, 95, 85, 84,
+  80, 83, 80, 87, 76, 96, 81, 97, 85, 79,
+  87, 84, 92, 93, 81, 88, 79, 90, 74, 86,
+  71, 93, 100, 87, 76, 99, 86, 72, 87, 85,
+  79, 92, 91, 82, 90, 78, 81, 88, 72, 84,
+  80, 79, 78, 84, 67, 69, 90, 99, 66, 99,
+  81, 81, 87, 79, 91, 66, 81, 70, 93, 90,
+  86, 86, 67, 84, 77, 78, 87, 80, 78, 85,
+  77, 83, 74, 88, 72, 85, 88, 79, 76, 80,
+  72, 102, 90, 92, 89, 92, 88, 74, 86, 88,
+  87, 86, 74, 95, 94, 77, 99, 72, 95, 90,
+  81, 86, 104, 91, 74, 89, 87, 87, 83, 74,
+  86, 91, 91, 89, 101, 79, 95, 85, 86, 103,
+  76, 78, 90, 102, 97, 91, 83, 93, 114, 71,
+  98, 79, 75, 72, 83, 73, 94, 70, 84, 84,
+  69, 82, 88, 100, 78, 93, 87, 86, 89, 94,
+  80, 94, 122, 99, 80, 84, 81, 61, 75, 86,
+  83, 82, 74, 89, 77, 79, 74, 84, 78, 75,
+  89, 102, 81, 88, 113, 87, 74, 90, 79, 86,
+  94, 75, 86, 87, 81, 81, 75, 88, 72, 85,
+  86, 77, 79, 71, 82, 89, 87, 82, 72, 83,
+  74, 85, 77, 85, 81, 80, 90, 98, 86, 70,
+  94, 76, 88, 74, 92, 67, 61, 79, 73, 98,
+  80, 77, 105, 81, 86, 73, 87, 90, 92, 77,
+  85, 82, 79, 84, 77, 79, 81, 78, 92, 84,
+  80, 76, 79, 85, 92, 69, 82, 86, 86, 74,
+  93, 69, 84, 85, 72, 86, 90, 89, 94, 85,
+  61, 77, 76, 77, 96, 83, 72, 93, 64, 72,
+  71, 87, 78, 79, 66, 88, 89, 95, 102, 82,
+  130, 85, 86, 96, 86, 92, 76, 80, 90, 84,
+  83, 73, 92, 87, 83, 93, 79, 79, 92, 97,
+  99, 94, 91, 79, 98, 82, 87, 92, 94, 87,
+  82, 116, 92, 84, 76, 86, 80, 78, 80, 75,
+  87, 81, 66, 79, 83, 85, 90, 89, 81, 82,
+  75, 91, 88, 98, 92, 91, 88, 70, 77, 79,
+  89, 78, 92, 98, 76, 93, 69, 94, 97, 76,
+  84, 89, 80, 75, 91, 81, 102, 73, 72, 83,
+  81, 81, 89, 77, 87, 83, 91, 82, 77, 85,
+  71, 107, 82, 76, 64, 77, 89, 80, 102, 74,
+  90, 73, 68, 79, 62, 87, 74, 81, 89, 80,
+  82, 80, 88, 90, 76, 99, 82, 69, 73, 77,
+  87, 69, 86, 84, 87, 98, 94, 91, 71, 100,
+  91, 76, 87, 95, 71, 85, 96, 93, 85, 79,
+  74, 77, 73, 99, 81, 80, 80, 87, 72, 73,
+  75, 100, 75, 99, 75, 90, 84, 77, 94, 67,
+  79, 83, 78, 95, 83, 113, 76, 81, 94, 78,
+  73, 84, 65, 83, 89, 74, 76, 90, 77, 75,
+  90, 71, 81, 80, 75, 97, 98, 93, 93, 88,
+  85, 67, 72, 86, 91, 87, 66, 84, 87, 74,
+  91, 72, 96, 96, 83, 86, 86, 84, 81, 84,
+  80, 85, 87, 83, 83, 88, 91, 97, 93, 92,
+  102, 79, 81, 109, 71, 75, 84, 102, 94, 91,
+  87, 90, 96, 73, 93, 89, 80, 83, 68, 77,
+  95, 68, 72, 73, 73, 89, 99, 88, 77, 94,
+  81, 86, 86, 83, 81, 92, 119, 94, 95, 78,
+  83, 59, 75, 84, 77, 88, 73, 90, 69, 84,
+  78, 91, 76, 82, 92, 105, 89, 91, 130, 85,
+  73, 91, 75, 90, 98, 83, 94, 81, 72, 78,
+  62, 89, 78, 85, 77, 72, 92, 73, 64, 93,
+  99, 83, 74, 84, 76, 79, 71, 82, 83, 78,
+  95, 74, 88, 66, 97, 74, 82, 71, 89, 66,
+  55, 85, 66, 88, 75, 75, 86, 80, 81, 79,
+  88, 92, 85, 74, 74, 87, 85, 86, 77, 81,
+  85, 82, 94, 90, 69, 79, 73, 72, 93, 79,
+  76, 96, 84, 87, 85, 71, 79, 71, 76, 83,
+  77, 84, 87, 87, 63, 76, 89, 87, 92, 80,
+  78, 83, 71, 81, 77, 85, 82, 74, 62, 88,
+  85, 82, 113, 78, 136, 79, 78, 91, 88, 97,
+  77, 80, 83, 80, 85, 69, 103, 88, 85, 90,
+  86, 84, 96, 88, 104, 91, 77, 74, 88, 87,
+  84, 93, 94, 86, 84, 118, 92, 83, 85, 85,
+  83, 60, 78, 70, 77, 76, 72, 80, 104, 89,
+  79, 76, 87, 83, 75, 93, 89, 105, 99, 85,
+  73, 71, 70, 79, 83, 77, 93, 96, 74, 97,
+  69, 91, 90, 61, 85, 90, 76, 81, 84, 78,
+  89, 78, 72, 92, 86, 75, 99, 76, 92, 85,
+  94, 83, 77, 81, 72, 79, 78, 83, 70, 81,
+  87, 93, 87, 77, 77, 69, 66, 79, 58, 91,
+  82, 78, 82, 75, 99, 90, 80, 91, 77, 101,
+  80, 72, 70, 80, 85, 70, 86, 73, 84, 86,
+  93, 87, 87, 90, 95, 84, 88, 81, 69, 88,
+  94, 81, 82, 84, 72, 84, 77, 92, 80, 82,
+  75, 87, 85, 81, 89, 90, 82, 82, 82, 86,
+  78, 79, 85, 78, 81, 82, 75, 98, 83, 109,
+  94, 82, 96, 79, 72, 86, 76, 79, 100, 80,
+  90, 73, 86, 76, 81, 80, 77, 81, 87, 99,
+  97, 79, 84, 87, 85, 69, 80, 88, 87, 82,
+  73, 88, 89, 68, 92, 67, 96, 79, 89, 87,
+  85, 83, 86, 86, 83, 87, 84, 86, 89, 81,
+  89, 88, 89, 81, 96, 79, 84, 99, 84, 80,
+  85, 96, 89, 97, 76, 91, 81, 84, 82, 81,
+  87, 75, 69, 83, 92, 68, 78, 83, 75, 81,
+  82, 88, 79, 83, 73, 87, 78, 94, 81, 88,
+  110, 88, 82, 83, 81, 66, 79, 90, 81, 91,
+  85, 86, 83, 81, 78, 87, 76, 83, 93, 92,
+  86, 88, 102, 84, 82, 82, 81, 94, 92, 86,
+  86, 87, 87, 78, 66, 83, 91, 80, 76, 77,
+  88, 82, 71, 92, 96, 85, 87, 89, 86, 73,
+  81, 87, 83, 88, 86, 76, 87, 76, 89, 86,
+  79, 73, 86, 75, 69, 83, 73, 88, 75, 69,
+  76, 80, 83, 76, 92, 91, 90, 74, 84, 89,
+  89, 90, 85, 82, 87, 80, 83, 87, 83, 75,
+  73, 69, 85, 78, 71, 90, 92, 89, 80, 81,
+  88, 81, 74, 85, 68, 91, 90, 84, 79, 77,
+  96, 87, 87, 74, 88, 98, 69, 78, 85, 88,
+  82, 72, 73, 87, 87, 89, 96, 85, 96, 78,
+  67, 89, 83, 87, 81, 87, 85, 92, 89, 72,
+  98, 82, 84, 93, 79, 86, 87, 89, 93, 78,
+  90, 85, 80, 83, 91, 95, 87, 89, 74, 101,
+  92, 85, 80, 81, 99, 64, 72, 75, 81, 86,
+  76, 74, 96, 82, 82, 89, 83, 85, 76, 95,
+  91, 107, 87, 80, 70, 76, 68, 99, 79, 85,
+  97, 97, 85, 91, 81, 97, 79, 69, 83, 98,
+  87, 79, 87, 87, 90, 82, 83, 88, 89, 77,
+  95, 80, 86, 82, 85, 79, 84, 80, 64, 75,
+  78, 81, 70, 88, 87, 84, 87, 88, 78, 81,
+  79, 79, 69, 92, 89, 82, 75, 77, 99, 80,
+  82, 90, 92, 109, 79, 77, 85, 90, 90, 73,
+  84, 79, 83, 85, 91, 88, 74, 81, 89, 96,
+  89, 76, 87, 70, 80, 86, 77, 88, 72, 86,
+  84, 79, 88, 77, 102, 76, 61, 84, 73, 82,
+  74, 80, 95, 89, 100, 106, 89, 87, 92, 88,
+  97, 78, 80, 81, 85, 89, 87, 82, 74, 91,
+  72, 82, 78, 98, 89, 98, 89, 84, 71, 76,
+  70, 80, 66, 86, 87, 76, 75, 97, 104, 76,
+  97, 83, 94, 83, 78, 99, 81, 81, 78, 72,
+  69, 100, 68, 89, 101, 97, 81, 84, 73, 88,
+  93, 94, 82, 91, 81, 90, 100, 87, 72, 78,
+  96, 91, 55, 87, 73, 72, 80, 79, 82, 107,
+  97, 76, 88, 76, 85, 79, 84, 83, 73, 93,
+  94, 92, 92, 79, 87, 65, 73, 78, 90, 82,
+  86, 64, 83, 82, 71, 86, 88, 91, 92, 83,
+  79, 74, 90, 94, 71, 86, 72, 88, 84, 66,
+  81, 81, 107, 78, 61, 81, 83, 81, 74, 87,
+  105, 95, 88, 105, 88, 80, 83, 86, 105, 96,
+  80, 79, 88, 86, 86, 84, 70, 89, 71, 72,
+  72, 93, 81, 98, 85, 90, 69, 77, 80, 90,
+  68, 80, 87, 73, 69, 91, 97, 74, 103, 92,
+  88, 75, 72, 106, 95, 77, 77, 75, 70, 95,
+  69, 97, 105, 96, 72, 80, 77, 90, 89, 90,
+  82, 92, 71, 76, 110, 79, 70, 78, 92, 83,
+  52, 86, 79, 81, 79, 85, 88, 99, 100, 77,
+  94, 82, 84, 82, 76, 84, 76, 83, 91, 90,
+  90, 79, 89, 61, 90, 79, 92, 85, 94, 59,
+  88, 89, 79, 81, 84, 94, 85, 81, 93, 79,
+  83, 87, 74, 92, 74, 91, 88, 77, 84, 80,
+  100, 83, 72, 77, 82, 81, 76, 80, 93, 92,
+  94, 92, 90, 77, 91, 84, 95, 110, 87, 81,
+  82, 90, 86, 84, 70, 90, 73, 79, 73, 86,
+  88, 98, 86, 79, 74, 77, 77, 86, 71, 88,
+  89, 73, 75, 93, 98, 83, 90, 84, 95, 78,
+  79, 93, 94, 84, 75, 81, 69, 100, 71, 94,
+  102, 91, 81, 84, 74, 83, 89, 92, 92, 81,
+  79, 80, 102, 83, 78, 79, 79, 90, 59, 89,
+  85, 82, 81, 93, 79, 109, 96, 76, 91, 73,
+  79, 81, 72, 81, 74, 79, 82, 90, 83, 77,
+  87, 66, 96, 78, 92, 84, 89, 65, 79, 76,
+  73, 87, 77, 90, 86, 88, 77, 70, 97, 86,
+  87, 83, 84, 78, 84, 73, 94, 89, 116, 71,
+  58, 82, 75, 90, 77, 72, 88, 102, 88, 103,
+  80, 86, 85, 82, 83, 83, 80, 69, 86, 81,
+  80, 87, 78, 86, 74, 77, 70, 97, 79, 102,
+  85, 88, 63, 75, 77, 79, 72, 91, 72, 77,
+  87, 92, 90, 74, 88, 92, 95, 81, 78, 90,
+  87, 78, 85, 78, 68, 102, 81, 85, 87, 95,
+  77, 84, 79, 79, 81, 81, 84, 91, 82, 106,
+  102, 93, 61, 83, 102, 86, 49, 84, 70, 80,
+  90, 74, 79, 99, 93, 80, 85, 84, 77, 98,
+  84, 79, 88, 88, 83, 84, 91, 81, 76, 68,
+  89, 81, 81, 102, 87, 69, 86, 101, 75, 101,
+  73, 85, 84, 79, 64, 85, 110, 85, 104, 81,
+  81, 76, 79, 73, 95, 93, 137, 65, 63, 75,
+  84, 107, 72, 76, 89, 112, 102, 87, 80, 86,
+  84, 77, 91, 81, 80, 74, 76, 80, 75, 82,
+  63, 77, 72, 83, 69, 83, 73, 126, 82, 81,
+  57, 74, 97, 77, 84, 77, 74, 67, 83, 90,
+  82, 68, 62, 88, 96, 66, 70, 84, 71, 60,
+  100, 89, 72, 115, 88, 88, 86, 99, 73, 76,
+  93, 96, 72, 77, 73, 82, 77, 117, 130, 83,
+  59, 75, 98, 71, 66, 78, 81, 89, 98, 85,
+  82, 95, 85, 80, 97, 84, 76, 118, 70, 74,
+  103, 76, 77, 82, 78, 78, 72, 64, 116, 83,
+  78, 115, 102, 65, 90, 126, 74, 85, 91, 92,
+  87, 83, 86, 76, 91, 88, 84, 84, 79, 89,
+  88, 69, 89, 84, 108, 87, 78, 81, 94, 86,
+  69, 71, 94, 97, 84, 76, 85, 73, 87, 83,
+  90, 113, 79, 72, 80, 76, 83, 84, 65, 85,
+  74, 72, 66, 78, 81, 102, 84, 80, 68, 75,
+  74, 88, 76, 86, 79, 73, 82, 90, 90, 74,
+  81, 86, 91, 76, 80, 90, 87, 79, 75, 86,
+  71, 96, 77, 96, 91, 92, 76, 81, 80, 89,
+  83, 82, 82, 79, 79, 97, 102, 85, 62, 82,
+  84, 86, 50, 82, 86, 85, 90, 95, 76, 102,
+  91, 77, 91, 83, 75, 89, 77, 77, 88, 83,
+  81, 83, 72, 78, 76, 65, 97, 80, 84, 96,
+  90, 74, 85, 91, 80, 89, 79, 88, 92, 90,
+  89, 73, 87, 79, 82, 80, 86, 79, 86, 69,
+  89, 87, 97, 80, 67, 78, 76, 89, 78, 73,
+  76, 92, 82, 88, 81, 88, 89, 84, 77, 83,
+  77, 83, 88, 84, 78, 87, 89, 84, 80, 77,
+  69, 95, 80, 99, 86, 92, 70, 79, 64, 89,
+  78, 97, 75, 77, 85, 87, 88, 80, 95, 87,
+  95, 83, 85, 78, 87, 79, 80, 85, 69, 96,
+  85, 89, 83, 91, 85, 84, 74, 77, 84, 86,
+  89, 76, 89, 104, 97, 111, 69, 85, 107, 88,
+  60, 83, 71, 79, 81, 78, 69, 104, 86, 79,
+  82, 81, 83, 91, 85, 79, 89, 84, 81, 88,
+  85, 85, 82, 87, 97, 77, 70, 97, 78, 76,
+  87, 85, 86, 93, 87, 85, 94, 82, 83, 81,
+  94, 78, 98, 77, 83, 82, 88, 77, 89, 87,
+  112, 75, 74, 75, 87, 92, 72, 68, 70, 94,
+  92, 80, 84, 85, 88, 79, 83, 86, 79, 85,
+  81, 84, 79, 80, 77, 80, 76, 77, 67, 88,
+  74, 114, 83, 86, 66, 75, 74, 85, 80, 89,
+  78, 72, 83, 84, 82, 77, 77, 86, 96, 76,
+  78, 83, 76, 67, 87, 98, 69, 94, 90, 89,
+  79, 95, 79, 81, 86, 88, 79, 78, 76, 75,
+  82, 115, 100, 107, 66, 84, 108, 78, 69, 82,
+  79, 81, 92, 86, 70, 98, 74, 81, 87, 82,
+  78, 99, 80, 79, 93, 75, 84, 91, 75, 84,
+  83, 82, 105, 84, 70, 106, 76, 76, 85, 106,
+  81, 83, 96, 94, 96, 78, 96, 75, 86, 81,
+  80, 80, 80, 90, 95, 68, 89, 83, 99, 86,
+  90, 77, 102, 85, 69, 72, 82, 84, 86, 78,
+  86, 74, 93, 83, 82, 111, 79, 83, 82, 86,
+  78, 85, 71, 83, 78, 77, 63, 80, 80, 102,
+  87, 85, 74, 77, 64, 78, 76, 90, 79, 74,
+  87, 82, 89, 81, 89, 83, 89, 76, 87, 86,
+  80, 78, 73, 94, 69, 91, 84, 95, 84, 87,
+  84, 83, 83, 85, 87, 83, 85, 71, 87, 98,
+  94, 91, 72, 84, 90, 88, 62, 82, 83, 78,
+  87, 87, 67, 106, 90, 75, 89, 77, 81, 88,
+  85, 75, 83, 84, 84, 89, 77, 81, 80, 84,
+  89, 78, 72, 90, 80, 86, 87, 80, 85, 93,
+  77, 90, 83, 80, 82, 91, 78, 85, 83, 69,
+  88, 85, 74, 71, 75, 95, 91, 75, 85, 78,
+  94, 70, 93, 82, 91, 96, 94, 81, 94, 80,
+  88, 77, 83, 73, 86, 90, 89, 85, 84, 66,
+  101, 79, 64, 91, 93, 83, 75, 94, 86, 92,
+  85, 90, 92, 83, 84, 86, 82, 96, 96, 82,
+  103, 88, 99, 67, 82, 89, 72, 103, 76, 83,
+  87, 97, 88, 80, 83, 76, 102, 76, 90, 80,
+  68, 97, 67, 72, 107, 93, 84, 79, 76, 75,
+  83, 83, 92, 93, 91, 66, 82, 73, 84, 71,
+  82, 83, 77, 83, 87, 90, 100, 72, 84, 95,
+  73, 85, 93, 77, 98, 94, 87, 97, 84, 80,
+  88, 84, 101, 104, 85, 79, 81, 89, 75, 84,
+  98, 68, 77, 90, 83, 82, 86, 60, 72, 83,
+  70, 71, 74, 74, 82, 76, 93, 83, 73, 73,
+  83, 73, 78, 93, 88, 88, 87, 81, 77, 76,
+  83, 78, 92, 85, 78, 91, 83, 67, 89, 73,
+  67, 86, 108, 70, 84, 92, 78, 84, 79, 98,
+  91, 89, 95, 94, 77, 89, 99, 116, 108, 109,
+  78, 80, 77, 93, 91, 88, 71, 84, 76, 93,
+  98, 82, 82, 76, 104, 73, 83, 75, 68, 89,
+  70, 70, 83, 98, 82, 75, 83, 78, 87, 81,
+  83, 99, 89, 63, 81, 90, 85, 87, 78, 83,
+  80, 82, 83, 92, 96, 63, 84, 88, 72, 88,
+  92, 69, 79, 93, 79, 90, 90, 76, 84, 86,
+  100, 102, 85, 87, 83, 82, 87, 87, 84, 89,
+  82, 88, 75, 87, 78, 71, 79, 89, 79, 70,
+  74, 100, 88, 77, 100, 70, 82, 73, 81, 82,
+  93, 96, 89, 88, 95, 86, 87, 74, 86, 86,
+  90, 88, 75, 84, 83, 68, 83, 75, 70, 89,
+  91, 68, 75, 94, 90, 85, 82, 83, 100, 93,
+  84, 84, 85, 96, 96, 73, 96, 88, 100, 65,
+  73, 87, 74, 94, 91, 82, 84, 98, 94, 79,
+  81, 89, 91, 74, 95, 81, 71, 86, 67, 71,
+  82, 87, 86, 78, 81, 85, 88, 84, 90, 90,
+  90, 63, 84, 74, 82, 93, 81, 82, 80, 80,
+  86, 86, 95, 75, 86, 92, 73, 106, 82, 69,
+  67, 93, 85, 89, 93, 81, 91, 83, 97, 99,
+  87, 78, 74, 99, 73, 95, 96, 75, 82, 84,
+  79, 75, 94, 73, 94, 95, 77, 76, 84, 87,
+  95, 77, 92, 74, 75, 77, 97, 76, 78, 102,
+  96, 79, 101, 78, 85, 72, 84, 67, 72, 82,
+  110, 89, 65, 67, 95, 74, 70, 98, 90, 83,
+  69, 86, 89, 84, 83, 105, 62, 81, 70, 78,
+  70, 88, 96, 99, 95, 90, 72, 70, 98, 95,
+  94, 70, 65, 77, 89, 97, 89, 67, 80, 80,
+  99, 92, 72, 97, 72, 96, 85, 79, 107, 94,
+  97, 83, 70, 79, 68, 93, 71, 104, 90, 76,
+  85, 88, 77, 62, 77, 82, 89, 73, 79, 86,
+  91, 61, 87, 100, 71, 76, 78, 69, 83, 100,
+  82, 91, 104, 77, 60, 83, 86, 83, 85, 90,
+  70, 91, 69, 82, 109, 60, 67, 84, 80, 69,
+  105, 65, 82, 99, 64, 67, 80, 58, 76, 71,
+  94, 90, 62, 82, 89, 57, 62, 93, 85, 83,
+  93, 83, 68, 78, 84, 69, 85, 74, 103, 98,
+  73, 71, 83, 60, 78, 93, 96, 84, 80, 88,
+  81, 83, 72, 111, 63, 83, 87, 78, 74, 83,
+  103, 137, 99, 134, 55, 98, 90, 104, 121, 58,
+  61, 78, 75, 91, 96, 74, 79, 83, 99, 95,
+  59, 84, 74, 85, 85, 80, 71, 99, 83, 77,
+  82, 78, 82, 91, 65, 102, 86, 74, 87, 119,
+  79, 77, 77, 81, 92, 78, 70, 85, 85, 45,
+  84, 93, 73, 70, 75, 62, 66, 103, 78, 86,
+  102, 73, 43, 88, 81, 78, 80, 100, 75, 94,
+  85, 91, 102, 74, 83, 90, 75, 78, 86, 72,
+  85, 100, 82, 77, 87, 95, 88, 81, 97, 72,
+  82, 82, 86, 79, 80, 101, 91, 86, 97, 93,
+  88, 73, 85, 83, 72, 80, 91, 88, 70, 66,
+  89, 76, 77, 100, 84, 77, 70, 88, 91, 83,
+  80, 94, 67, 87, 69, 80, 74, 87, 100, 87,
+  88, 91, 78, 67, 86, 92, 94, 65, 75, 74,
+  89, 94, 97, 68, 77, 86, 93, 90, 79, 93,
+  72, 89, 83, 83, 78, 89, 94, 81, 75, 83,
+  73, 90, 69, 98, 90, 75, 88, 83, 81, 88,
+  77, 82, 88, 73, 81, 87, 83, 68, 83, 102,
+  70, 99, 75, 63, 58, 99, 79, 88, 101, 83,
+  74, 78, 86, 79, 87, 86, 71, 90, 80, 101,
+  68, 86, 78, 82, 88, 82, 93, 98, 84, 85,
+  79, 83, 84, 99, 86, 85, 95, 85, 83, 68,
+  95, 75, 78, 97, 88, 76, 89, 74, 85, 81,
+  76, 72, 79, 89, 99, 89, 76, 70, 92, 77,
+  70, 84, 74, 83, 74, 94, 92, 86, 93, 97,
+  71, 80, 75, 79, 83, 83, 87, 102, 86, 82,
+  93, 72, 90, 89, 100, 83, 76, 81, 84, 103,
+  82, 77, 77, 83, 89, 90, 72, 85, 75, 92,
+  91, 85, 105, 94, 90, 87, 83, 107, 81, 89,
+  88, 95, 80, 78, 85, 86, 88, 78, 81, 80,
+  92, 87, 86, 89, 83, 79, 87, 82, 74, 81,
+  81, 78, 81, 96, 81, 87, 90, 82, 69, 82,
+  85, 96, 79, 88, 68, 81, 77, 93, 68, 85,
+  68, 83, 87, 79, 96, 90, 69, 87, 60, 73,
+  80, 77, 76, 82, 98, 101, 80, 69, 87, 60,
+  71, 90, 79, 76, 86, 81, 74, 82, 72, 78,
+  87, 81, 87, 93, 76, 74, 87, 70, 76, 85,
+  81, 84, 79, 92, 85, 82, 91, 97, 84, 80,
+  93, 82, 80, 83, 90, 124, 92, 106, 72, 84,
+  72, 86, 114, 79, 76, 83, 75, 99, 84, 80,
+  77, 84, 81, 91, 63, 71, 81, 81, 92, 87,
+  73, 97, 85, 85, 96, 98, 89, 83, 82, 87,
+  76, 80, 78, 106, 87, 83, 84, 80, 92, 88,
+  80, 88, 82, 71, 84, 77, 76, 74, 76, 68,
+  82, 98, 81, 87, 88, 79, 65, 86, 84, 90,
+  77, 91, 72, 79, 98, 97, 73, 86, 79, 86,
+  80, 84, 84, 92, 85, 94, 84, 83, 88, 105,
+  78, 86, 92, 79, 87, 75, 87, 78, 78, 97,
+  82, 84, 88, 90, 88, 80, 78, 88, 79, 86,
+  84, 92, 78, 72, 93, 77, 77, 85, 68, 80,
+  77, 96, 93, 80, 92, 89, 78, 84, 70, 81,
+  86, 78, 86, 88, 85, 84, 95, 71, 78, 84,
+  92, 83, 78, 81, 83, 97, 86, 77, 75, 79,
+  86, 88, 76, 83, 77, 91, 85, 91, 79, 88,
+  89, 89, 85, 101, 86, 83, 78, 90, 81, 78,
+  89, 82, 92, 90, 78, 82, 94, 89, 88, 89,
+  79, 85, 86, 82, 68, 97, 80, 77, 67, 97,
+  81, 86, 94, 86, 82, 78, 87, 91, 82, 86,
+  97, 91, 86, 83, 92, 73, 77, 74, 82, 87,
+  76, 80, 121, 69, 70, 79, 84, 91, 86, 92,
+  69, 99, 68, 81, 86, 80, 105, 85, 100, 83,
+  75, 73, 78, 91, 80, 92, 102, 84, 86, 106,
+  88, 86, 99, 85, 103, 81, 83, 91, 88, 90,
+  75, 81, 85, 74, 75, 87, 76, 62, 102, 81,
+  77, 79, 96, 88, 67, 84, 88, 91, 72, 85,
+  102, 90, 80, 78, 74, 92, 82, 104, 73, 70,
+  84, 68, 92, 104, 84, 82, 91, 82, 82, 93,
+  74, 78, 86, 88, 98, 65, 86, 85, 95, 94,
+  71, 72, 79, 82, 93, 60, 77, 84, 71, 76,
+  93, 71, 81, 87, 79, 84, 89, 86, 95, 73,
+  80, 72, 77, 82, 82, 72, 77, 77, 77, 77,
+  84, 85, 94, 77, 72, 84, 74, 95, 87, 77,
+  68, 76, 68, 85, 71, 78, 79, 94, 89, 96,
+  68, 81, 78, 75, 102, 86, 98, 90, 66, 77,
+  87, 109, 81, 116, 100, 96, 82, 81, 106, 71,
+  75, 73, 130, 86, 83, 90, 108, 78, 61, 57,
+  77, 77, 68, 64, 105, 64, 124, 86, 80, 146,
+  113, 72, 71, 83, 93, 112, 79, 79, 71, 90,
+  100, 70, 74, 119, 86, 90, 57, 58, 81, 61,
+  85, 95, 74, 82, 94, 94, 58, 89, 87, 92,
+  96, 89, 122, 65, 82, 99, 81, 108, 76, 81,
+  94, 84, 85, 62, 80, 74, 68, 62, 73, 68,
+  92, 92, 74, 79, 96, 89, 95, 70, 79, 63,
+  71, 99, 73, 76, 63, 67, 91, 75, 101, 81,
+  85, 79, 82, 80, 81, 84, 79, 80, 113, 87,
+  68, 77, 87, 85, 83, 86, 98, 89, 75, 81,
+  77, 78, 99, 86, 92, 87, 83, 89, 77, 93,
+  86, 101, 105, 86, 84, 102, 77, 85, 78, 89,
+  96, 86, 86, 103, 86, 86, 81, 89, 82, 73,
+  73, 69, 79, 76, 108, 85, 76, 79, 94, 83,
+  77, 82, 83, 91, 79, 91, 82, 86, 82, 79,
+  79, 89, 84, 88, 69, 71, 88, 80, 87, 86,
+  83, 81, 89, 83, 84, 87, 81, 76, 85, 84,
+  85, 73, 87, 83, 86, 89, 76, 79, 78, 82,
+  91, 66, 78, 82, 72, 78, 93, 71, 84, 92,
+  83, 82, 74, 79, 93, 71, 96, 76, 80, 80,
+  87, 75, 72, 75, 97, 88, 52, 77, 74, 83,
+  78, 73, 67, 88, 87, 70, 109, 74, 70, 83,
+  78, 94, 83, 83, 70, 84, 73, 87, 77, 79,
+  103, 92, 89, 95, 79, 75, 70, 71, 97, 83,
+  99, 84, 91, 79, 93, 87, 80, 94, 85, 76,
+  97, 84, 79, 79, 93, 76, 90, 78, 80, 112,
+  70, 92, 75, 85, 90, 70, 84, 81, 70, 74,
+  90, 85, 77, 73, 100, 89, 71, 78, 86, 68,
+  78, 85, 86, 75, 87, 96, 82, 75, 86, 75,
+  80, 74, 90, 88, 62, 71, 82, 89, 82, 69,
+  95, 85, 118, 70, 67, 86, 69, 84, 98, 75,
+  74, 84, 94, 88, 85, 75, 74, 74, 98, 89,
+  74, 88, 91, 68, 81, 72, 65, 88, 80, 80,
+  88, 107, 100, 81, 85, 71, 71, 68, 76, 82,
+  66, 86, 89, 76, 84, 83, 62, 85, 68, 93,
+  85, 76, 71, 82, 68, 79, 76, 77, 114, 88,
+  86, 91, 83, 87, 67, 75, 91, 79, 106, 77,
+  79, 68, 102, 84, 71, 87, 91, 71, 114, 78,
+  84, 69, 92, 81, 84, 78, 81, 98, 79, 94,
+  82, 92, 87, 76, 104, 71, 72, 69, 86, 79,
+  72, 83, 83, 86, 74, 72, 85, 65, 76, 78,
+  91, 65, 81, 102, 81, 74, 86, 76, 72, 77,
+  104, 92, 67, 75, 84, 83, 100, 65, 98, 93,
+  82, 67, 75, 76, 67, 82, 92, 80, 70, 81,
+  98, 79, 98, 70, 76, 73, 102, 87, 74, 82,
+  82, 64, 87, 70, 74, 89, 76, 87, 74, 105,
+  88, 82, 113, 76, 76, 76, 81, 75, 72, 86,
+  82, 73, 100, 91, 71, 83, 79, 95, 81, 83,
+  77, 82, 80, 87, 80, 79, 94, 89, 86, 92,
+  93, 95, 68, 71, 91, 79, 95, 87, 73, 80,
+  89, 90, 76, 92, 83, 82, 109, 92, 79, 80,
+  93, 87, 88, 78, 78, 74, 65, 97, 81, 85,
+  88, 68, 81, 83, 75, 71, 92, 86, 76, 76,
+  70, 85, 73, 79, 87, 70, 80, 73, 83, 75,
+  89, 100, 79, 80, 87, 78, 72, 76, 93, 89,
+  61, 60, 81, 89, 83, 75, 98, 83, 67, 73,
+  73, 77, 69, 83, 98, 81, 68, 80, 93, 89,
+  107, 77, 79, 79, 99, 90, 68, 89, 87, 64,
+  89, 71, 72, 87, 85, 80, 86, 99, 71, 85,
+  67, 95, 86, 94, 67, 74, 88, 88, 79, 78,
+  90, 85, 81, 84, 86, 96, 83, 75, 93, 89,
+  78, 84, 84, 86, 82, 87, 91, 98, 85, 85,
+  78, 79, 82, 90, 92, 87, 76, 83, 91, 91,
+  80, 97, 80, 87, 74, 81, 76, 89, 85, 87,
+  90, 90, 92, 90, 74, 83, 80, 78, 85, 95,
+  78, 74, 95, 90, 88, 84, 93, 70, 88, 95,
+  78, 85, 87, 74, 78, 85, 75, 84, 86, 94,
+  84, 83, 83, 84, 82, 84, 80, 85, 81, 91,
+  83, 89, 90, 85, 84, 79, 99, 93, 76, 100,
+  76, 86, 86, 79, 81, 93, 76, 89, 77, 97,
+  85, 85, 90, 81, 79, 92, 80, 87, 91, 83,
+  79, 89, 91, 80, 91, 102, 71, 87, 78, 94,
+  82, 75, 71, 80, 91, 80, 82, 85, 96, 88,
+  85, 83, 88, 100, 87, 72, 84, 87, 79, 83,
+  93, 88, 85, 86, 87, 84, 94, 96, 82, 78,
+  81, 79, 84, 85, 88, 75, 86, 100, 84, 98,
+  79, 75, 87, 86, 77, 83, 85, 86, 89, 89,
+  87, 87, 76, 90, 81, 83, 82, 88, 77, 74,
+  82, 91, 103, 85, 96, 70, 74, 87, 75, 84,
+  88, 68, 79, 88, 78, 81, 87, 98, 85, 79,
+  85, 85, 78, 79, 89, 88, 83, 83, 84, 89,
+  86, 82, 83, 87, 92, 85, 71, 97, 68, 85,
+  88, 92, 84, 90, 84, 93, 76, 96, 86, 79,
+  91, 91, 78, 91, 85, 80, 88, 87, 87, 90,
+  94, 82, 96, 110, 68, 86, 95, 93, 88, 74,
+  70, 76, 90, 87, 74, 79, 91, 81, 82, 85,
+  90, 97, 82, 78, 80, 91, 90, 84, 91, 84,
+  79, 85, 85, 83, 83, 93, 79, 79, 89, 77,
+  88, 86, 83, 84, 94, 90, 93, 94, 82, 82,
+  85, 89, 77, 87, 84, 79, 87, 88, 84, 76,
+  72, 84, 86, 80, 85, 90, 76, 81, 92, 88,
+  92, 91, 90, 84, 78, 94, 83, 84, 85, 76,
+  80, 84, 76, 85, 83, 94, 79, 88, 87, 84,
+  79, 86, 78, 87, 77, 74, 85, 88, 86, 89,
+  79, 79, 74, 91, 76, 76, 77, 86, 87, 82,
+  81, 90, 75, 90, 72, 98, 85, 81, 95, 85,
+  93, 94, 79, 86, 86, 85, 80, 90, 95, 81,
+  90, 96, 70, 94, 87, 90, 82, 85, 85, 76,
+  72, 92, 74, 75, 80, 115, 69, 68, 71, 98,
+  83, 90, 87, 86, 90, 80, 86, 78, 87, 100,
+  116, 93, 73, 97, 75, 86, 74, 97, 87, 64,
+  94, 69, 87, 61, 79, 69, 70, 80, 83, 86,
+  83, 73, 88, 86, 73, 75, 72, 73, 65, 82,
+  83, 97, 82, 78, 96, 84, 103, 63, 91, 78,
+  82, 122, 73, 78, 104, 71, 77, 72, 74, 76,
+  119, 61, 82, 106, 76, 94, 82, 95, 80, 104,
+  79, 92, 82, 85, 69, 76, 93, 73, 82, 70,
+  72, 76, 78, 79, 94, 110, 125, 81, 79, 86,
+  94, 72, 78, 70, 84, 95, 81, 114, 105, 91,
+  83, 90, 89, 73, 78, 75, 85, 70, 84, 89,
+  75, 95, 78, 82, 92, 77, 85, 74, 77, 85,
+  71, 84, 84, 99, 81, 70, 72, 88, 67, 86,
+  87, 75, 78, 80, 87, 80, 80, 107, 93, 98,
+  73, 92, 75, 81, 83, 77, 93, 71, 95, 80,
+  72, 65, 85, 72, 73, 79, 75, 75, 80, 72,
+  91, 90, 75, 78, 66, 74, 54, 85, 90, 94,
+  75, 73, 99, 71, 95, 66, 95, 68, 79, 89,
+  83, 75, 92, 68, 82, 63, 70, 89, 126, 69,
+  84, 111, 67, 90, 75, 87, 87, 99, 85, 95,
+  81, 89, 68, 79, 76, 76, 81, 78, 80, 78,
+  78, 89, 88, 107, 137, 77, 75, 90, 93, 81,
+  87, 64, 89, 79, 74, 103, 84, 93, 73, 84,
+  101, 77, 84, 69, 90, 79, 79, 88, 81, 73,
+  76, 78, 84, 82, 87, 74, 71, 83, 71, 83,
+  77, 89, 80, 68, 71, 90, 81, 90, 83, 79,
+  70, 81, 79, 82, 89, 93, 95, 91, 77, 86,
+  78, 80, 82, 85, 104, 65, 87, 78, 84, 70,
+  80, 72, 74, 91, 85, 81, 83, 73, 91, 79,
+  77, 80, 75, 76, 68, 86, 84, 94, 81, 85,
+  96, 92, 114, 71, 89, 74, 85, 96, 100, 75,
+  104, 67, 81, 69, 74, 93, 120, 69, 84, 102,
+  75, 88, 83, 81, 100, 95, 79, 94, 81, 98,
+  74, 77, 91, 78, 89, 79, 78, 78, 78, 104,
+  92, 106, 122, 76, 79, 88, 93, 78, 88, 74,
+  87, 79, 79, 100, 75, 90, 81, 88, 95, 77,
+  80, 71, 85, 78, 85, 84, 82, 86, 80, 92,
+  86, 90, 87, 67, 83, 78, 78, 73, 86, 103,
+  86, 71, 80, 81, 82, 72, 86, 79, 75, 89,
+  83, 87, 76, 94, 88, 88, 85, 88, 82, 85,
+  83, 89, 83, 76, 89, 77, 77, 68, 73, 77,
+  82, 83, 84, 87, 84, 74, 95, 79, 73, 80,
+  68, 93, 64, 92, 71, 94, 83, 83, 81, 99,
+  96, 86, 78, 67, 79, 77, 79, 82, 79, 87,
+  81, 71, 80, 77, 97, 81, 84, 96, 73, 83,
+  82, 80, 77, 89, 86, 90, 75, 70, 75, 75,
+  73, 84, 87, 94, 79, 78, 74, 75, 76, 99,
+  106, 84, 84, 80, 92, 83, 95, 82, 100, 80,
+  66, 88, 93, 95, 83, 99, 103, 86, 70, 77,
+  80, 96, 83, 92, 98, 83, 74, 82, 86, 74,
+  83, 72, 82, 69, 80, 86, 96, 88, 96, 71,
+  88, 85, 80, 73, 79, 80, 78, 85, 77, 81,
+  75, 92, 78, 87, 89, 97, 93, 82, 97, 70,
+  87, 73, 94, 82, 76, 77, 79, 85, 94, 84,
+  79, 87, 86, 72, 96, 83, 73, 78, 68, 85,
+  74, 90, 79, 92, 81, 85, 80, 93, 75, 99,
+  83, 75, 81, 73, 74, 77, 75, 86, 80, 68,
+  77, 93, 81, 91, 84, 88, 77, 87, 83, 77,
+  73, 83, 73, 96, 72, 69, 79, 80, 68, 86,
+  82, 108, 80, 89, 76, 86, 75, 96, 77, 91,
+  83, 79, 87, 90, 94, 79, 104, 71, 74, 85,
+  81, 102, 73, 90, 100, 88, 72, 79, 75, 95,
+  77, 100, 90, 80, 79, 88, 84, 81, 82, 67,
+  80, 76, 73, 81, 84, 81, 90, 68, 79, 80,
+  81, 80, 79, 80, 77, 85, 78, 80, 79, 88,
+  77, 81, 86, 104, 91, 82, 95, 84, 87, 78,
+  91, 76, 80, 78, 88, 86, 87, 83, 88, 98,
+  83, 71, 92, 81, 78, 80, 72, 78, 73, 88,
+  77, 84, 82, 88, 85, 105, 100, 88, 77, 69,
+  88, 77, 89, 80, 83, 84, 82, 73, 77, 89,
+  94, 84, 88, 92, 81, 80, 87, 73, 77, 83,
+  89, 87, 79, 75, 76, 79, 78, 87, 86, 92,
+  79, 79, 71, 82, 77, 94, 98, 77, 82, 80,
+  88, 86, 101, 85, 100, 79, 80, 82, 81, 98,
+  83, 91, 92, 84, 75, 78, 82, 94, 89, 89,
+  85, 82, 78, 95, 84, 99, 84, 75, 82, 80,
+  80, 77, 89, 87, 84, 68, 87, 84, 86, 79,
+  84, 82, 73, 86, 79, 87, 88, 87, 83, 90,
+  92, 85, 86, 90, 89, 90, 84, 81, 85, 77,
+  83, 94, 76, 85, 89, 86, 93, 87, 80, 81,
+  99, 82, 83, 83, 86, 94, 68, 87, 70, 89,
+  93, 86, 80, 100, 95, 92, 79, 75, 82, 77,
+  95, 98, 84, 88, 85, 81, 85, 81, 87, 90,
+  88, 78, 80, 85, 89, 84, 80, 84, 87, 76,
+  74, 79, 79, 74, 81, 84, 82, 89, 94, 80,
+  75, 83, 76, 98, 83, 83, 89, 86, 83, 91,
+  94, 90, 93, 76, 79, 83, 93, 89, 81, 93,
+  90, 87, 72, 75, 81, 97, 91, 91, 95, 80,
+  82, 90, 78, 84, 82, 80, 80, 75, 84, 90,
+  100, 85, 82, 63, 94, 92, 89, 87, 81, 85,
+  82, 79, 79, 82, 94, 81, 76, 88, 96, 93,
+  92, 86, 97, 81, 90, 75, 83, 64, 85, 102,
+  83, 97, 94, 86, 91, 87, 83, 76, 89, 79,
+  88, 79, 92, 88, 82, 82, 75, 84, 94, 88,
+  82, 95, 79, 98, 79, 83, 83, 80, 82, 92,
+  82, 87, 92, 83, 75, 93, 80, 87, 87, 68,
+  88, 85, 96, 81, 80, 82, 75, 81, 79, 76,
+  79, 76, 79, 83, 76, 85, 90, 82, 80, 84,
+  77, 96, 59, 85, 90, 87, 76, 95, 90, 86,
+  95, 76, 86, 84, 90, 92, 75, 93, 86, 82,
+  77, 79, 80, 90, 87, 95, 86, 83, 86, 92,
+  83, 84, 79, 77, 81, 80, 81, 81, 86, 83,
+  81, 67, 88, 86, 87, 87, 78, 82, 87, 82,
+  80, 81, 90, 85, 76, 77, 90, 94, 92, 84,
+  98, 87, 84, 85, 80, 71, 87, 97, 83, 92,
+  87, 85, 93, 88, 82, 76, 92, 81, 90, 82,
+  94, 82, 79, 84, 77, 87, 90, 94, 84, 103,
+  95, 89, 79, 77, 85, 79, 85, 93, 89, 84,
+  87, 93, 80, 94, 87, 87, 91, 73, 90, 79,
+  94, 84, 81, 85, 87, 79, 81, 76, 82, 77,
+  84, 85, 80, 80, 82, 80, 76, 82, 75, 95,
+  85, 81, 84, 86, 82, 93, 92, 93, 92, 83,
+  84, 85, 90, 88, 82, 95, 84, 90, 78, 76,
+  89, 94, 96, 90, 89, 78, 85, 82, 103, 97,
+  91, 81, 81, 71, 79, 72, 71, 76, 86, 81,
+  85, 77, 78, 81, 82, 65, 65, 74, 87, 93,
+  82, 74, 87, 90, 81, 86, 91, 83, 69, 80,
+  83, 87, 83, 80, 84, 100, 86, 92, 84, 80,
+  97, 98, 94, 91, 86, 85, 80, 89, 74, 79,
+  100, 83, 87, 95, 77, 87, 85, 78, 85, 90,
+  74, 83, 88, 70, 72, 84, 90, 77, 85, 83,
+  87, 61, 84, 102, 86, 89, 85, 86, 93, 81,
+  81, 73, 91, 81, 75, 78, 74, 97, 85, 92,
+  79, 95, 90, 84, 82, 72, 84, 82, 83, 84,
+  93, 84, 89, 86, 84, 91, 86, 87, 86, 84,
+  82, 83, 90, 85, 70, 90, 90, 95, 79, 82,
+  90, 78, 77, 86, 93, 81, 75, 79, 80, 84,
+  94, 79, 74, 77, 74, 74, 74, 79, 73, 77,
+  84, 88, 92, 86, 95, 82, 78, 101, 85, 82,
+  97, 72, 78, 90, 81, 65, 72, 85, 76, 93,
+  85, 86, 72, 89, 84, 85, 82, 83, 84, 90,
+  85, 88, 88, 92, 86, 74, 83, 67, 112, 80,
+  100, 89, 80, 72, 82, 79, 80, 72, 85, 82,
+  79, 83, 67, 78, 103, 82, 81, 90, 80, 65,
+  73, 94, 79, 86, 87, 102, 78, 72, 86, 81,
+  83, 87, 86, 72, 78, 86, 83, 80, 76, 83,
+  86, 84, 73, 72, 84, 77, 85, 78, 92, 88,
+  75, 94, 85, 77, 88, 87, 62, 83, 93, 75,
+  86, 90, 82, 87, 90, 89, 84, 80, 90, 78,
+  99, 83, 101, 90, 81, 82, 72, 79, 90, 78,
+  79, 80, 98, 82, 74, 87, 70, 83, 89, 89,
+  95, 105, 98, 80, 82, 81, 97, 83, 83, 80,
+  90, 82, 82, 91, 88, 87, 90, 93, 88, 87,
+  83, 90, 79, 80, 91, 76, 77, 96, 79, 83,
+  75, 100, 78, 76, 73, 70, 86, 79, 96, 93,
+  92, 74, 84, 87, 75, 76, 69, 85, 84, 104,
+  67, 93, 93, 86, 76, 83, 77, 86, 77, 78,
+  78, 86, 89, 90, 82, 73, 94, 94, 72, 79,
+  82, 88, 80, 85, 79, 74, 87, 90, 95, 73,
+  90, 78, 79, 79, 75, 71, 80, 89, 75, 88,
+  87, 74, 77, 80, 73, 77, 89, 81, 80, 79,
+  87, 73, 85, 86, 88, 87, 93, 74, 84, 76,
+  73, 78, 99, 97, 96, 85, 79, 71, 82, 78,
+  78, 86, 80, 80, 83, 86, 81, 78, 83, 76,
+  79, 84, 80, 86, 79, 75, 88, 90, 80, 83,
+  95, 85, 66, 87, 62, 79, 78, 73, 73, 93,
+  90, 90, 88, 88, 90, 106, 90, 97, 88, 88,
+  79, 82, 78, 64, 88, 79, 89, 96, 81, 81,
+  82, 60, 70, 90, 69, 74, 88, 68, 73, 88,
+  86, 82, 86, 86, 86, 75, 69, 108, 88, 86,
+  85, 84, 84, 80, 83, 69, 87, 82, 85, 71,
+  73, 85, 82, 91, 77, 95, 88, 81, 77, 67,
+  80, 81, 86, 79, 88, 84, 88, 89, 87, 89,
+  86, 91, 62, 89, 90, 83, 85, 88, 76, 91,
+  93, 95, 80, 77, 89, 88, 89, 80, 82, 83,
+  72, 87, 75, 77, 84, 84, 75, 78, 80, 95,
+  74, 70, 73, 89, 82, 91, 90, 88, 127, 80,
+  77, 89, 86, 83, 92, 65, 68, 89, 84, 69,
+  101, 98, 75, 78, 74, 72, 60, 103, 90, 85,
+  77, 86, 78, 86, 78, 97, 77, 83, 82, 67,
+  81, 50, 96, 67, 99, 95, 83, 65, 76, 63,
+  71, 77, 93, 82, 79, 85, 73, 92, 87, 90,
+  84, 83, 93, 114, 62, 96, 78, 72, 81, 105,
+  74, 72, 99, 92, 65, 88, 83, 63, 76, 83,
+  99, 79, 74, 78, 81, 78, 76, 63, 88, 77,
+  82, 70, 83, 87, 76, 99, 78, 76, 82, 98,
+  45, 104, 105, 76, 80, 81, 85, 100, 89, 78,
+  77, 71, 89, 95, 121, 72, 84, 107, 81, 73,
+  73, 72, 88, 81, 87, 79, 100, 109, 74, 81,
+  63, 77, 96, 85, 99, 85, 98, 84, 91, 74,
+  100, 83, 79, 80, 102, 90, 88, 106, 111, 73,
+  114, 92, 80, 60, 84, 104, 84, 83, 81, 79,
+  91, 78, 79, 79, 69, 88, 76, 75, 77, 78,
+  72, 77, 92, 99, 89, 78, 84, 92, 83, 76,
+  86, 95, 89, 97, 71, 91, 73, 97, 78, 75,
+  94, 109, 92, 67, 77, 86, 83, 69, 89, 87,
+  96, 108, 83, 76, 81, 90, 85, 92, 87, 81,
+  91, 74, 91, 71, 96, 81, 86, 80, 93, 81,
+  75, 101, 94, 84, 84, 83, 75, 77, 95, 104,
+  79, 91, 85, 75, 94, 66, 82, 79, 85, 88,
+  96, 84, 89, 71, 59, 78, 101, 106, 94, 87,
+  81, 71, 86, 75, 71, 76, 84, 79, 82, 96,
+  86, 75, 79, 73, 74, 75, 77, 83, 86, 75,
+  87, 86, 83, 88, 98, 95, 73, 89, 77, 87,
+  83, 74, 81, 103, 94, 93, 88, 84, 90, 108,
+  94, 86, 87, 87, 77, 85, 79, 80, 91, 84,
+  86, 96, 86, 76, 80, 67, 76, 95, 82, 70,
+  92, 69, 92, 98, 83, 77, 83, 83, 96, 91,
+  60, 113, 89, 87, 90, 79, 86, 74, 89, 66,
+  86, 82, 88, 90, 67, 88, 87, 91, 89, 103,
+  88, 87, 81, 77, 80, 82, 82, 75, 85, 86,
+  88, 87, 78, 88, 83, 91, 62, 89, 82, 93,
+  93, 81, 69, 93, 87, 88, 76, 70, 91, 90,
+  91, 86, 52, 85, 80, 86, 86, 83, 79, 84,
+  79, 84, 75, 81, 76, 75, 73, 92, 90, 78,
+  75, 78, 86, 71, 76, 90, 92, 85, 92, 58,
+  71, 92, 96, 78, 120, 94, 95, 88, 73, 77,
+  75, 100, 100, 89, 79, 94, 87, 77, 86, 99,
+  80, 81, 85, 74, 83, 70, 98, 75, 98, 91,
+  89, 72, 80, 73, 70, 82, 81, 82, 80, 67,
+  103, 86, 88, 91, 85, 90, 85, 111, 82, 92,
+  82, 77, 85, 84, 80, 66, 96, 83, 75, 87,
+  93, 80, 75, 87, 109, 76, 78, 83, 79, 87,
+  79, 75, 93, 76, 76, 69, 78, 94, 79, 96,
+  68, 80, 83, 87, 56, 93, 61, 79, 87, 82,
+  70, 95, 90, 80, 82, 66, 87, 105, 102, 75,
+  61, 101, 93, 74, 79, 77, 75, 80, 76, 88,
+  81, 87, 64, 79, 62, 71, 87, 81, 94, 76,
+  93, 81, 86, 76, 106, 88, 87, 73, 88, 90,
+  87, 106, 85, 76, 87, 91, 83, 70, 88, 84,
+  80, 82, 75, 95, 90, 78, 92, 85, 78, 85,
+  85, 79, 77, 96, 80, 77, 91, 77, 101, 98,
+  89, 87, 85, 79, 84, 93, 90, 83, 91, 67,
+  86, 101, 78, 81, 90, 96, 113, 66, 80, 88,
+  76, 70, 77, 86, 92, 103, 86, 78, 92, 100,
+  84, 90, 98, 82, 82, 72, 76, 81, 79, 91,
+  84, 79, 93, 98, 79, 99, 90, 83, 77, 86,
+  80, 77, 91, 104, 70, 76, 79, 95, 84, 73,
+  82, 80, 90, 92, 82, 81, 94, 87, 75, 72,
+  93, 66, 81, 93, 81, 81, 79, 92, 88, 83,
+  77, 82, 85, 73, 86, 86, 79, 89, 73, 69,
+  89, 91, 94, 63, 86, 82, 93, 67, 91, 92,
+  74, 69, 88, 74, 88, 92, 77, 63, 91, 97,
+  96, 83, 95, 88, 95, 96, 75, 80, 84, 80,
+  83, 86, 90, 76, 94, 93, 71, 82, 103, 52,
+  81, 80, 83, 100, 74, 71, 87, 65, 107, 62,
+  82, 73, 75, 85, 71, 81, 95, 93, 101, 96,
+  90, 142, 70, 69, 94, 89, 91, 78, 83, 98,
+  90, 83, 92, 75, 98, 86, 80, 71, 91, 87,
+  66, 70, 92, 92, 73, 87, 83, 81, 58, 134,
+  88, 105, 82, 88, 99, 97, 83, 80, 76, 89,
+  78, 55, 76, 96, 88, 83, 81, 87, 71, 69,
+  86, 76, 83, 83, 75, 93, 68, 80, 72, 85,
+  67, 87, 92, 88, 85, 96, 102, 65, 79, 80,
+  91, 86, 104, 80, 88, 76, 73, 90, 64, 74,
+  75, 66, 89, 69, 83, 54, 78, 92, 80, 80,
+  81, 94, 83, 90, 82, 82, 77, 71, 84, 84,
+  81, 72, 97, 77, 91, 80, 99, 63, 74, 80,
+  83, 98, 63, 76, 77, 71, 97, 80, 77, 87,
+  101, 88, 65, 70, 91, 80, 84, 94, 88, 117,
+  73, 92, 79, 79, 85, 90, 97, 84, 81, 94,
+  94, 71, 91, 80, 80, 69, 119, 87, 104, 65,
+  86, 90, 61, 84, 76, 82, 70, 102, 81, 95,
+  94, 100, 80, 94, 74, 83, 74, 78, 84, 46,
+  76, 82, 99, 81, 83, 94, 86, 81, 84, 77,
+  89, 67, 74, 90, 89, 76, 69, 83, 74, 88,
+  104, 85, 90, 96, 91, 74, 93, 84, 87, 91,
+  87, 74, 96, 92, 74, 97, 72, 82, 85, 75,
+  84, 75, 82, 62, 74, 87, 83, 84, 89, 86,
+  78, 74, 89, 87, 72, 81, 89, 81, 71, 77,
+  83, 75, 94, 83, 98, 78, 75, 86, 83, 92,
+  73, 82, 80, 73, 85, 76, 78, 80, 94, 89,
+  65, 77, 88, 76, 82, 91, 94, 103, 78, 94,
+  77, 84, 69, 99, 96, 84, 78, 83, 98, 85,
+  93, 90, 88, 81, 108, 90, 118, 77, 78, 95,
+  84, 88, 76, 92, 87, 84, 94, 87, 86, 87,
+  83, 91, 86, 80, 85, 81, 94, 59, 84, 81,
+  85, 88, 83, 72, 83, 65, 80, 78, 79, 78,
+  78, 91, 74, 83, 78, 81, 82, 73, 88, 89,
+  75, 91, 72, 71, 87, 84, 84, 77, 92, 82,
+  87, 83, 82, 88, 68, 69, 82, 74, 86, 88,
+  78, 72, 80, 89, 80, 82, 88, 88, 96, 91,
+  77, 81, 84, 79, 84, 79, 82, 77, 91, 87,
+  73, 88, 100, 55, 76, 84, 76, 100, 82, 91,
+  82, 78, 92, 71, 83, 84, 84, 97, 72, 81,
+  89, 87, 88, 93, 86, 105, 72, 80, 86, 88,
+  92, 75, 86, 91, 88, 77, 93, 79, 92, 86,
+  80, 70, 87, 89, 93, 79, 94, 90, 71, 86,
+  74, 83, 74, 143, 85, 93, 88, 88, 87, 96,
+  78, 86, 81, 86, 80, 68, 80, 89, 85, 83,
+  84, 94, 67, 74, 86, 60, 92, 61, 75, 89,
+  73, 75, 80, 86, 71, 86, 91, 87, 95, 92,
+  99, 71, 80, 77, 84, 109, 105, 83, 83, 94,
+  63, 84, 72, 74, 80, 90, 82, 69, 75, 75,
+  70, 83, 80, 88, 77, 95, 81, 81, 86, 78,
+  74, 76, 87, 75, 70, 80, 81, 85, 78, 82,
+  86, 68, 86, 86, 73, 91, 76, 88, 80, 79,
+  77, 83, 85, 90, 105, 95, 72, 82, 84, 81,
+  71, 86, 79, 77, 69, 100, 74, 71, 75, 79,
+  92, 89, 70, 87, 82, 89, 84, 78, 78, 65,
+  111, 90, 135, 85, 89, 89, 75, 82, 81, 84,
+  84, 97, 77, 79, 86, 102, 68, 91, 78, 91,
+  82, 76, 89, 64, 76, 81, 96, 85, 74, 101,
+  79, 81, 87, 68, 90, 44, 82, 81, 92, 74,
+  78, 85, 80, 88, 98, 81, 94, 92, 82, 75,
+  88, 84, 90, 103, 88, 82, 79, 103, 83, 83,
+  86, 76, 87, 97, 82, 72, 73, 86, 80, 82,
+  89, 82, 84, 82, 74, 80, 97, 75, 74, 90,
+  96, 79, 63, 92, 73, 80, 80, 91, 89, 84,
+  84, 96, 81, 83, 77, 84, 81, 75, 72, 76,
+  83, 80, 87, 91, 79, 89, 87, 84, 76, 90,
+  87, 80, 76, 86, 79, 79, 73, 76, 83, 84,
+  68, 81, 83, 101, 90, 89, 80, 78, 89, 90,
+  116, 93, 84, 94, 89, 95, 89, 90, 95, 75,
+  85, 82, 77, 95, 79, 95, 75, 84, 103, 81,
+  102, 77, 74, 90, 83, 97, 83, 73, 88, 75,
+  78, 76, 84, 69, 83, 83, 75, 78, 74, 75,
+  83, 71, 96, 83, 79, 89, 69, 74, 98, 85,
+  85, 73, 82, 78, 90, 93, 80, 94, 75, 68,
+  83, 75, 87, 87, 86, 72, 85, 84, 84, 84,
+  90, 87, 92, 85, 85, 83, 75, 87, 79, 88,
+  85, 85, 90, 88, 76, 88, 98, 71, 84, 83,
+  83, 89, 79, 82, 87, 79, 91, 77, 83, 84,
+  82, 104, 70, 85, 87, 82, 94, 99, 83, 98,
+  73, 78, 87, 90, 91, 75, 86, 90, 83, 69,
+  95, 82, 91, 88, 84, 74, 83, 89, 88, 80,
+  89, 88, 89, 91, 82, 86, 81, 126, 80, 89,
+  88, 83, 94, 91, 80, 87, 86, 93, 79, 83,
+  91, 84, 82, 92, 82, 91, 73, 83, 81, 65,
+  87, 53, 83, 86, 80, 75, 69, 82, 71, 80,
+  95, 85, 97, 89, 94, 74, 93, 83, 91, 89,
+  95, 77, 88, 94, 76, 92, 73, 71, 84, 86,
+  75, 78, 85, 77, 74, 83, 85, 92, 84, 92,
+  81, 81, 87, 83, 70, 87, 86, 80, 83, 78,
+  85, 88, 72, 86, 91, 77, 90, 87, 78, 86,
+  82, 76, 90, 81, 85, 83, 84, 95, 83, 89,
+  79, 91, 85, 81, 81, 93, 79, 88, 75, 91,
+  72, 83, 83, 77, 86, 84, 71, 78, 85, 81,
+  84, 86, 83, 78, 82, 87, 100, 84, 86, 88,
+  85, 95, 94, 89, 90, 88, 75, 84, 83, 85,
+  80, 91, 81, 94, 90, 84, 91, 90, 82, 77,
+  86, 86, 72, 94, 80, 87, 79, 74, 80, 49,
+  92, 81, 97, 79, 65, 83, 71, 87, 104, 83,
+  96, 85, 98, 70, 87, 86, 97, 81, 78, 78,
+  86, 95, 87, 92, 80, 69, 86, 84, 77, 78,
+  85, 90, 79, 88, 97, 83, 86, 86, 70, 84,
+  89, 78, 68, 94, 88, 82, 72, 82, 69, 85,
+  77, 84, 94, 86, 91, 95, 82, 87, 84, 76,
+  94, 90, 82, 81, 84, 85, 71, 85, 84, 96,
+  83, 85, 88, 95, 89, 94, 82, 86, 76, 80,
+  81, 76, 80, 84, 72, 80, 83, 84, 87, 93,
+  82, 80, 84, 88, 87, 80, 84, 88, 75, 98,
+  99, 90, 97, 82, 81, 84, 85, 82, 94, 94,
+  74, 85, 92, 84, 101, 91, 88, 82, 88, 62,
+  99, 91, 87, 85, 81, 76, 63, 78, 87, 90,
+  90, 74, 65, 86, 76, 72, 75, 90, 79, 97,
+  93, 94, 89, 107, 86, 88, 93, 104, 89, 85,
+  98, 96, 89, 87, 89, 86, 67, 90, 80, 71,
+  86, 90, 72, 77, 78, 99, 77, 81, 74, 92,
+  81, 89, 92, 82, 82, 78, 82, 75, 83, 86,
+  77, 67, 83, 88, 80, 102, 88, 79, 75, 90,
+  85, 91, 72, 77, 71, 80, 89, 72, 74, 94,
+  75, 82, 67, 78, 92, 82, 104, 94, 77, 89,
+  82, 85, 74, 88, 77, 90, 78, 70, 80, 95,
+  86, 86, 99, 92, 82, 84, 71, 76, 80, 84,
+  80, 86, 97, 86, 96, 94, 75, 95, 96, 80,
+  88, 87, 97, 93, 80, 90, 77, 83, 87, 98,
+  97, 81, 85, 68, 60, 74, 78, 81, 75, 81,
+  68, 71, 76, 76, 76, 93, 93, 81, 89, 91,
+  102, 107, 88, 97, 106, 100, 76, 95, 109, 83,
+  98, 79, 86, 98, 73, 81, 70, 70, 87, 95,
+  70, 77, 77, 93, 62, 73, 78, 69, 84, 96,
+  82, 81, 77, 72, 70, 78, 89, 88, 77, 70,
+  66, 80, 86, 90, 90, 77, 76, 78, 76, 89,
+  77, 64, 67, 85, 84, 79, 66, 100, 80, 87,
+  74, 80, 91, 94, 106, 91, 81, 84, 73, 94,
+  65, 108, 70, 84, 89, 71, 74, 74, 74, 85,
+  91, 84, 89, 86, 74, 74, 79, 85, 83, 91,
+  79, 78, 76, 104, 74, 92, 83, 78, 79, 81,
+  81, 84, 95, 97, 86, 97, 79, 87, 84, 91,
+  81, 79, 60, 79, 82, 88, 91, 69, 65, 93,
+  79, 77, 76, 95, 87, 95, 84, 86, 78, 106,
+  90, 90, 82, 91, 88, 90, 100, 80, 100, 78,
+  88, 87, 70, 91, 77, 68, 83, 84, 79, 79,
+  76, 82, 72, 80, 80, 79, 74, 96, 97, 98,
+  81, 79, 78, 75, 87, 86, 84, 59, 80, 91,
+  87, 97, 88, 83, 97, 91, 87, 90, 76, 74,
+  74, 91, 91, 83, 72, 92, 77, 88, 64, 85,
+  88, 91, 101, 99, 79, 85, 85, 86, 74, 88,
+  80, 91, 88, 68, 80, 65, 86, 84, 94, 94,
+  85, 90, 76, 80, 81, 82, 85, 94, 84, 97,
+  74, 91, 82, 93, 80, 81, 82, 92, 98, 92,
+  78, 91, 85, 63, 78, 99, 102, 82, 77, 66,
+  71, 82, 80, 94, 97, 77, 69, 113, 83, 94,
+  86, 91, 93, 84, 94, 106, 89, 100, 90, 97,
+  114, 98, 91, 82, 98, 101, 78, 82, 74, 94,
+  70, 86, 81, 82, 89, 98, 71, 87, 83, 105,
+  78, 85, 61, 84, 82, 98, 83, 88, 84, 66,
+  78, 81, 85, 75, 73, 61, 80, 77, 92, 97,
+  86, 68, 88, 80, 86, 82, 78, 68, 67, 70,
+  81, 71, 72, 107, 85, 81, 71, 79, 94, 89,
+  86, 93, 74, 93, 71, 86, 64, 77, 78, 72,
+  87, 71, 70, 86, 75, 80, 97, 87, 80, 95,
+  67, 81, 78, 95, 79, 87, 82, 79, 88, 89,
+  76, 77, 89, 77, 102, 75, 84, 87, 85, 85,
+  71, 86, 80, 117, 126, 75, 71, 55, 64, 79,
+  70, 85, 75, 78, 78, 98, 79, 100, 78, 103,
+  100, 69, 81, 94, 108, 112, 82, 107, 119, 92,
+  75, 87, 100, 89, 92, 69, 70, 90, 72, 84,
+  69, 79, 99, 107, 70, 76, 77, 80, 58, 84,
+  68, 58, 73, 112, 70, 73, 69, 57, 69, 86,
+  94, 71, 71, 61, 73, 65, 95, 91, 91, 66,
+  63, 68, 81, 80, 89, 48, 57, 80, 87, 72,
+  66, 123, 90, 82, 82, 85, 94, 98, 87, 92,
+  78, 80, 59, 95, 51, 95, 74, 67, 91, 62,
+  67, 75, 64, 80, 94, 77, 85, 95, 64, 73,
+  81, 94, 81, 96, 69, 69, 64, 95, 68, 81,
+  83, 71, 89, 71, 63, 81, 105, 84, 84, 100,
+  87, 93, 101, 89, 75, 67, 68, 82, 76, 95,
+  88, 70, 66, 111, 85, 96, 87, 93, 89, 93,
+  80, 93, 91, 97, 95, 98, 103, 80, 91, 81,
+  97, 78, 88, 70, 74, 89, 72, 86, 78, 80,
+  91, 92, 72, 82, 79, 71, 70, 83, 67, 78,
+  73, 101, 87, 82, 83, 70, 77, 82, 86, 81,
+  78, 57, 79, 78, 86, 98, 90, 75, 74, 83,
+  85, 83, 85, 64, 74, 94, 83, 76, 71, 106,
+  93, 89, 66, 84, 86, 96, 87, 91, 79, 86,
+  74, 84, 65, 77, 82, 81, 88, 72, 72, 72,
+  73, 80, 96, 88, 86, 95, 73, 82, 81, 92,
+  86, 95, 88, 87, 76, 87, 83, 83, 86, 78,
+  87, 80, 86, 85, 86, 84, 88, 60, 72, 91,
+  82, 86, 78, 72, 74, 84, 84, 84, 93, 71,
+  57, 122, 80, 81, 83, 87, 78, 83, 90, 107,
+  77, 87, 99, 85, 90, 83, 98, 82, 87, 95,
+  72, 102, 95, 87, 78, 90, 80, 72, 73, 81,
+  68, 79, 94, 104, 102, 92, 69, 81, 81, 93,
+  96, 102, 96, 84, 87, 88, 77, 91, 92, 80,
+  81, 93, 101, 91, 77, 87, 98, 85, 91, 77,
+  67, 75, 89, 80, 79, 69, 68, 85, 83, 91,
+  75, 85, 95, 84, 87, 92, 68, 115, 74, 72,
+  73, 65, 73, 69, 79, 85, 63, 113, 99, 80,
+  98, 96, 69, 86, 63, 84, 70, 89, 86, 83,
+  94, 89, 79, 88, 93, 84, 83, 74, 99, 77,
+  92, 87, 72, 82, 70, 82, 81, 110, 97, 79,
+  66, 58, 80, 84, 76, 77, 80, 74, 59, 135,
+  85, 87, 81, 97, 78, 68, 87, 107, 89, 87,
+  98, 93, 109, 85, 97, 80, 92, 89, 74, 84,
+  82, 82, 67, 83, 79, 65, 80, 91, 68, 77,
+  93, 88, 87, 88, 71, 68, 78, 98, 81, 85,
+  81, 71, 82, 83, 78, 96, 82, 81, 71, 80,
+  98, 87, 83, 77, 75, 74, 84, 80, 74, 57,
+  81, 93, 73, 68, 63, 88, 88, 87, 77, 99,
+  88, 88, 91, 93, 72, 112, 65, 74, 55, 66,
+  73, 67, 84, 78, 61, 91, 77, 79, 110, 88,
+  72, 87, 60, 84, 71, 90, 81, 90, 97, 86,
+  73, 86, 80, 84, 83, 68, 93, 65, 86, 83,
+  80, 77, 94, 95, 87, 88, 83, 82, 72, 71,
+  68, 85, 84, 84, 87, 73, 57, 119, 89, 78,
+  85, 86, 74, 98, 94, 99, 83, 82, 102, 83,
+  80, 75, 102, 77, 89, 84, 72, 87, 84, 83,
+  66, 93, 77, 71, 79, 77, 70, 67, 88, 77,
+  96, 88, 71, 91, 73, 96, 96, 77, 91, 85,
+  84, 84, 81, 100, 94, 73, 82, 92, 91, 90,
+  83, 91, 71, 85, 87, 80, 74, 70, 88, 104,
+  80, 70, 71, 81, 88, 92, 72, 96, 79, 89,
+  90, 84, 71, 105, 73, 71, 71, 60, 75, 77,
+  81, 87, 63, 93, 94, 79, 103, 91, 75, 84,
+  70, 83, 71, 90, 87, 93, 110, 98, 94, 86,
+  93, 89, 85, 75, 91, 79, 91, 83, 73, 82,
+  101, 78, 92, 80, 82, 94, 96, 88, 87, 85,
+  72, 89, 81, 94, 81, 86, 87, 71, 68, 76,
+  76, 89, 81, 96, 79, 89, 73, 72, 91, 104,
+  80, 83, 81, 88, 88, 93, 95, 79, 73, 89,
+  89, 85, 87, 76, 87, 82, 82, 91, 75, 85,
+  78, 103, 76, 76, 86, 83, 74, 86, 80, 83,
+  77, 84, 73, 82, 84, 98, 87, 72, 84, 80,
+  80, 80, 77, 80, 82, 88, 80, 82, 88, 90,
+  67, 85, 80, 83, 84, 83, 79, 87, 94, 87,
+  92, 83, 80, 72, 86, 87, 87, 67, 92, 77,
+  72, 83, 77, 89, 85, 87, 87, 84, 80, 79,
+  84, 90, 86, 81, 93, 76, 96, 85, 91, 83,
+  75, 87, 86, 84, 83, 68, 88, 94, 84, 89,
+  86, 81, 70, 89, 104, 95, 89, 81, 66, 87,
+  63, 80, 92, 92, 85, 77, 53, 91, 78, 70,
+  87, 101, 85, 105, 74, 69, 89, 101, 72, 82,
+  80, 80, 92, 91, 92, 77, 74, 82, 89, 78,
+  81, 73, 89, 75, 78, 81, 94, 79, 76, 91,
+  82, 76, 89, 93, 89, 84, 74, 78, 70, 87,
+  75, 72, 97, 85, 92, 78, 74, 82, 92, 81,
+  83, 79, 89, 90, 68, 80, 90, 99, 69, 87,
+  71, 83, 77, 84, 79, 80, 98, 91, 101, 76,
+  72, 78, 89, 86, 88, 59, 82, 85, 66, 82,
+  80, 84, 88, 85, 86, 88, 87, 80, 79, 91,
+  94, 77, 84, 73, 86, 78, 78, 90, 71, 86,
+  81, 98, 82, 68, 86, 97, 102, 89, 91, 79,
+  85, 81, 90, 88, 87, 89, 70, 95, 86, 82,
+  79, 85, 87, 73, 74, 85, 84, 91, 79, 91,
+  91, 84, 79, 73, 85, 91, 76, 80, 82, 85,
+  86, 82, 92, 82, 87, 89, 83, 77, 80, 76,
+  89, 80, 80, 84, 76, 86, 78, 91, 75, 75,
+  87, 98, 71, 92, 76, 80, 76, 82, 81, 85,
+  83, 93, 92, 74, 79, 83, 90, 85, 85, 80,
+  83, 83, 79, 92, 86, 88, 69, 86, 76, 82,
+  83, 85, 77, 89, 90, 84, 91, 77, 79, 75,
+  77, 84, 85, 69, 80, 77, 74, 79, 76, 85,
+  88, 88, 92, 84, 81, 75, 79, 88, 87, 72,
+  79, 83, 84, 84, 92, 83, 74, 88, 82, 78,
+  88, 67, 85, 89, 81, 82, 81, 84, 74, 101,
+  112, 94, 86, 79, 70, 84, 81, 73, 87, 99,
+  82, 88, 47, 80, 81, 87, 80, 96, 77, 92,
+  70, 70, 98, 106, 81, 75, 77, 82, 77, 94,
+  90, 78, 73, 90, 87, 76, 80, 73, 89, 80,
+  78, 101, 83, 87, 78, 83, 87, 74, 84, 73,
+  83, 93, 73, 88, 79, 80, 78, 81, 83, 91,
+  92, 78, 87, 88, 87, 68, 83, 73, 83, 95,
+  64, 71, 93, 81, 67, 79, 76, 86, 89, 81,
+  77, 77, 88, 90, 106, 91, 69, 76, 90, 85,
+  90, 60, 91, 81, 66, 81, 90, 87, 90, 86,
+  83, 96, 76, 77, 86, 88, 99, 78, 90, 75,
+  100, 75, 87, 95, 83, 83, 83, 103, 81, 80,
+  85, 95, 73, 103, 83, 100, 60, 88, 124, 111,
+  93, 78, 63, 80, 64, 62, 96, 121, 82, 96,
+  35, 98, 78, 63, 82, 114, 86, 111, 76, 72,
+  97, 84, 79, 79, 85, 77, 86, 88, 84, 79,
+  65, 85, 77, 70, 79, 67, 85, 72, 77, 82,
+  103, 86, 74, 63, 100, 73, 82, 74, 99, 88,
+  62, 87, 76, 75, 72, 70, 83, 66, 106, 80,
+  83, 79, 80, 68, 93, 76, 97, 109, 54, 87,
+  90, 95, 74, 82, 72, 81, 80, 82, 77, 66,
+  97, 92, 149, 78, 64, 87, 100, 83, 96, 47,
+  83, 90, 56, 76, 94, 79, 93, 77, 88, 102,
+  91, 82, 83, 84, 117, 74, 78, 67, 84, 71,
+  81, 94, 79, 80, 88, 131, 82, 80, 84, 96,
+  85, 87, 91, 81, 82, 79, 101, 97, 87, 84,
+  72, 89, 79, 79, 85, 95, 85, 85, 59, 89,
+  80, 93, 85, 89, 87, 83, 79, 72, 86, 77,
+  76, 76, 75, 84, 92, 84, 90, 82, 78, 85,
+  82, 72, 81, 75, 88, 75, 77, 81, 78, 84,
+  75, 87, 78, 74, 83, 85, 78, 95, 72, 81,
+  79, 86, 86, 86, 88, 89, 98, 80, 83, 91,
+  92, 74, 94, 75, 89, 86, 68, 105, 100, 80,
+  69, 80, 70, 81, 91, 84, 78, 90, 90, 84,
+  93, 84, 74, 76, 82, 85, 86, 63, 78, 80,
+  74, 75, 86, 84, 88, 85, 92, 94, 80, 71,
+  84, 88, 94, 73, 86, 86, 87, 77, 90, 86,
+  73, 86, 75, 91, 83, 78, 84, 88, 87, 89,
+  87, 86, 80, 96, 105, 80, 87, 82, 72, 95,
+  86, 74, 94, 107, 88, 78, 63, 81, 87, 85,
+  81, 93, 82, 88, 73, 74, 90, 93, 89, 77,
+  75, 81, 73, 101, 85, 84, 92, 90, 82, 82,
+  77, 79, 91, 77, 77, 96, 78, 88, 75, 86,
+  85, 74, 83, 89, 73, 88, 82, 79, 75, 75,
+  86, 75, 82, 92, 97, 76, 80, 93, 99, 82,
+  77, 80, 80, 88, 76, 78, 79, 75, 73, 78,
+  71, 86, 89, 87, 75, 81, 95, 91, 95, 101,
+  68, 79, 85, 84, 89, 69, 90, 80, 73, 87,
+  80, 90, 87, 87, 84, 89, 87, 71, 90, 81,
+  92, 81, 85, 84, 87, 84, 92, 87, 79, 84,
+  82, 95, 77, 78, 81, 90, 78, 95, 100, 99,
+  73, 97, 106, 93, 96, 81, 65, 93, 71, 81,
+  101, 111, 89, 85, 51, 91, 81, 71, 90, 100,
+  83, 99, 74, 76, 88, 75, 82, 76, 73, 82,
+  77, 88, 80, 81, 74, 92, 66, 77, 84, 77,
+  87, 79, 76, 92, 87, 83, 73, 86, 87, 72,
+  84, 82, 84, 83, 72, 71, 73, 70, 81, 64,
+  85, 81, 103, 73, 84, 99, 89, 78, 80, 84,
+  87, 95, 64, 95, 72, 86, 73, 79, 70, 84,
+  80, 82, 82, 75, 98, 91, 110, 103, 64, 79,
+  99, 82, 87, 60, 84, 88, 73, 82, 78, 83,
+  82, 83, 87, 94, 86, 77, 87, 78, 102, 80,
+  81, 76, 87, 79, 84, 84, 83, 78, 80, 119,
+  75, 74, 77, 88, 88, 90, 91, 87, 87, 78,
+  98, 92, 89, 85, 75, 96, 81, 94, 92, 101,
+  90, 76, 75, 86, 84, 89, 84, 85, 85, 80,
+  77, 77, 87, 72, 88, 77, 77, 88, 86, 86,
+  88, 86, 78, 85, 78, 83, 92, 75, 87, 80,
+  75, 86, 75, 86, 74, 92, 77, 74, 77, 79,
+  69, 91, 78, 77, 80, 82, 91, 81, 85, 86,
+  92, 81, 83, 90, 90, 80, 88, 79, 86, 83,
+  78, 102, 88, 77, 73, 81, 68, 75, 92, 78,
+  86, 92, 94, 82, 88, 95, 74, 80, 88, 86,
+  88, 73, 85, 76, 74, 86, 81, 87, 81, 82,
+  88, 86, 89, 70, 87, 82, 90, 76, 85, 88,
+  88, 86, 95, 84, 81, 88, 79, 88, 79, 75,
+  80, 90, 90, 88, 95, 76, 90, 80, 82, 96,
+  92, 76, 82, 88, 88, 92, 82, 73, 100, 87,
+  90, 81, 64, 79, 86, 91, 89, 89, 75, 85,
+  92, 68, 72, 104, 86, 83, 104, 91, 80, 85,
+  78, 100, 77, 79, 98, 85, 75, 88, 88, 82,
+  86, 82, 75, 83, 79, 100, 93, 75, 85, 66,
+  80, 82, 81, 89, 85, 45, 74, 73, 83, 76,
+  80, 73, 93, 80, 95, 83, 97, 73, 76, 92,
+  74, 100, 85, 90, 75, 91, 79, 71, 86, 77,
+  92, 112, 78, 69, 68, 86, 92, 80, 85, 81,
+  77, 82, 72, 82, 87, 76, 98, 90, 76, 85,
+  78, 91, 83, 80, 93, 90, 67, 88, 71, 84,
+  66, 80, 78, 83, 93, 97, 83, 91, 95, 91,
+  81, 80, 85, 82, 74, 98, 97, 77, 93, 81,
+  73, 75, 80, 80, 73, 76, 75, 67, 75, 82,
+  72, 88, 84, 77, 96, 82, 92, 89, 130, 68,
+  81, 87, 80, 96, 143, 87, 99, 83, 70, 68,
+  110, 78, 113, 81, 80, 98, 77, 81, 85, 77,
+  62, 76, 85, 74, 97, 94, 81, 62, 88, 83,
+  87, 85, 89, 64, 64, 57, 58, 102, 73, 72,
+  115, 89, 84, 79, 82, 85, 84, 119, 79, 68,
+  73, 73, 80, 89, 92, 71, 101, 98, 83, 106,
+  82, 99, 89, 80, 111, 72, 88, 72, 77, 85,
+  73, 72, 101, 77, 88, 77, 86, 93, 84, 58,
+  90, 86, 67, 88, 65, 96, 74, 93, 81, 84,
+  78, 67, 92, 80, 76, 74, 74, 80, 77, 74,
+  89, 92, 74, 83, 88, 79, 107, 79, 75, 80,
+  86, 83, 76, 92, 80, 65, 72, 82, 93, 77,
+  76, 72, 91, 79, 95, 85, 106, 90, 107, 81,
+  84, 96, 82, 82, 90, 96, 79, 76, 103, 81,
+  97, 92, 70, 86, 85, 96, 73, 80, 75, 78,
+  79, 77, 73, 74, 73, 81, 99, 92, 78, 79,
+  76, 84, 70, 71, 69, 112, 77, 92, 66, 84,
+  86, 68, 74, 98, 97, 101, 85, 67, 73, 83,
+  95, 88, 109, 94, 98, 99, 89, 107, 90, 99,
+  104, 87, 94, 82, 79, 82, 77, 93, 87, 76,
+  93, 80, 88, 83, 102, 102, 83, 56, 104, 78,
+  60, 88, 92, 100, 90, 100, 96, 96, 82, 70,
+  90, 83, 74, 75, 76, 70, 84, 75, 79, 74,
+  91, 74, 77, 89, 89, 71, 94, 86, 79, 88,
+  95, 72, 95, 98, 95, 75, 87, 86, 85, 92,
+  71, 88, 70, 77, 85, 71, 80, 89, 92, 87,
+  71, 82, 75, 81, 78, 93, 69, 85, 81, 91,
+  97, 79, 80, 92, 78, 87, 84, 95, 78, 104,
+  82, 74, 89, 88, 78, 88, 85, 87, 77, 73,
+  83, 104, 79, 90, 84, 73, 76, 90, 80, 76,
+  96, 79, 85, 78, 67, 102, 94, 96, 79, 76,
+  91, 67, 82, 78, 90, 108, 76, 69, 79, 87,
+  74, 94, 73, 97, 79, 81, 78, 101, 87, 78,
+  83, 89, 87, 90, 72, 101, 80, 81, 99, 84,
+  79, 86, 81, 90, 84, 78, 73, 92, 72, 94,
+  85, 84, 96, 88, 79, 85, 61, 77, 93, 65,
+  85, 86, 79, 76, 84, 78, 72, 91, 87, 74,
+  82, 92, 100, 76, 69, 72, 68, 88, 79, 95,
+  90, 88, 105, 60, 78, 99, 96, 88, 112, 76,
+  88, 76, 70, 68, 74, 60, 110, 84, 89, 101,
+  72, 83, 83, 86, 70, 89, 81, 95, 93, 80,
+  84, 75, 71, 78, 91, 95, 91, 74, 65, 66,
+  65, 86, 73, 71, 100, 70, 88, 88, 93, 78,
+  71, 83, 88, 72, 90, 83, 83, 72, 82, 69,
+  80, 79, 87, 111, 87, 81, 64, 92, 98, 81,
+  90, 82, 83, 80, 66, 94, 88, 77, 93, 75,
+  70, 88, 90, 84, 84, 83, 91, 84, 65, 77,
+  58, 79, 77, 79, 76, 80, 95, 84, 82, 85,
+  90, 97, 81, 81, 70, 80, 91, 71, 81, 76,
+  87, 85, 80, 73, 78, 76, 70, 77, 79, 74,
+  80, 88, 80, 78, 77, 85, 79, 80, 85, 91,
+  81, 69, 86, 83, 73, 91, 88, 83, 82, 83,
+  88, 75, 106, 61, 86, 79, 78, 91, 72, 76,
+  92, 82, 59, 88, 79, 82, 84, 91, 83, 80,
+  78, 73, 89, 82, 90, 88, 76, 70, 69, 92,
+  76, 94, 82, 79, 96, 85, 82, 86, 79, 89,
+  98, 62, 85, 75, 85, 75, 86, 88, 82, 83,
+  77, 101, 78, 92, 85, 87, 98, 78, 83, 73,
+  74, 83, 76, 81, 95, 77, 95, 92, 71, 91,
+  95, 71, 88, 75, 82, 86, 79, 96, 81, 81,
+  77, 92, 80, 69, 90, 84, 81, 83, 79, 81,
+  83, 75, 95, 87, 84, 86, 74, 84, 91, 82,
+  89, 85, 85, 73, 87, 82, 91, 96, 80, 91,
+  96, 82, 97, 96, 75, 82, 82, 74, 72, 92,
+  85, 79, 90, 97, 87, 87, 87, 74, 79, 82,
+  88, 99, 65, 89, 95, 81, 87, 85, 77, 78,
+  84, 92, 79, 91, 80, 82, 88, 100, 84, 90,
+  84, 92, 81, 99, 99, 112, 78, 82, 80, 90,
+  78, 101, 80, 72, 98, 82, 93, 83, 81, 86,
+  89, 99, 82, 75, 95, 78, 90, 81, 90, 89,
+  71, 81, 101, 88, 87, 90, 66, 87, 90, 82,
+  91, 97, 84, 84, 82, 82, 85, 89, 65, 102,
+  81, 81, 100, 86, 88, 88, 90, 89, 88, 83,
+  77, 82, 64, 87, 84, 78, 92, 92, 79, 79,
+  83, 81, 96, 68, 72, 90, 85, 78, 88, 83,
+  80, 89, 86, 76, 85, 98, 98, 82, 77, 77,
+  80, 90, 70, 91, 83, 80, 82, 78, 78, 89,
+  100, 89, 89, 73, 80, 82, 73, 87, 70, 71,
+  76, 81, 99, 90, 76, 91, 79, 89, 93, 96,
+  73, 104, 81, 82, 80, 93, 80, 83, 79, 94,
+  80, 91, 85, 99, 76, 76, 75, 75, 83, 77,
+  79, 74, 90, 85, 79, 69, 81, 88, 91, 98,
+  80, 72, 86, 77, 87, 77, 98, 99, 78, 84,
+  80, 93, 83, 88, 79, 90, 90, 86, 79, 96,
+  78, 83, 90, 76, 77, 89, 73, 106, 87, 85,
+  99, 84, 80, 70, 69, 82, 86, 79, 81, 85,
+  73, 89, 86, 83, 97, 96, 88, 89, 90, 78,
+  93, 70, 77, 83, 79, 82, 82, 79, 81, 82,
+  78, 70, 84, 86, 94, 82, 67, 82, 88, 90,
+  73, 89, 75, 77, 78, 70, 84, 87, 84, 87,
+  93, 87, 83, 83, 83, 76, 84, 66, 74, 75,
+  96, 88, 77, 79, 86, 83, 81, 90, 75, 96,
+  82, 89, 86, 91, 75, 84, 84, 86, 91, 100,
+  90, 84, 79, 89, 76, 87, 88, 72, 89, 77,
+  87, 85, 78, 71, 95, 81, 90, 90, 82, 83,
+  84, 85, 82, 77, 94, 90, 74, 83, 78, 94,
+  95, 83, 76, 81, 83, 84, 80, 90, 82, 82,
+  89, 87, 80, 89, 80, 98, 87, 84, 96, 86,
+  77, 80, 88, 82, 87, 86, 81, 82, 74, 89,
+  85, 84, 90, 87, 69, 79, 76, 88, 81, 94,
+  87, 97, 112, 83, 79, 118, 92, 68, 75, 100,
+  83, 86, 85, 74, 105, 88, 92, 75, 83, 75,
+  80, 85, 92, 89, 85, 80, 104, 72, 76, 89,
+  92, 73, 109, 83, 75, 80, 74, 76, 70, 93,
+  104, 87, 86, 68, 81, 74, 88, 102, 66, 105,
+  86, 83, 85, 80, 75, 79, 82, 67, 89, 93,
+  79, 91, 85, 73, 88, 101, 98, 95, 87, 79,
+  89, 78, 79, 82, 89, 67, 72, 85, 77, 68,
+  99, 98, 68, 82, 89, 83, 81, 80, 88, 92,
+  70, 79, 94, 91, 82, 79, 87, 93, 92, 75,
+  78, 90, 88, 89, 88, 87, 82, 94, 84, 78,
+  85, 86, 82, 100, 76, 75, 78, 88, 85, 99,
+  79, 92, 58, 80, 88, 76, 87, 73, 76, 90,
+  124, 77, 87, 117, 85, 97, 77, 80, 79, 74,
+  85, 66, 90, 81, 76, 79, 80, 71, 80, 82,
+  104, 71, 83, 88, 82, 76, 77, 88, 85, 55,
+  89, 74, 52, 88, 103, 66, 72, 73, 93, 81,
+  76, 60, 93, 84, 86, 118, 61, 75, 95, 75,
+  87, 85, 74, 92, 78, 68, 73, 114, 82, 85,
+  89, 60, 76, 81, 102, 89, 84, 77, 78, 88,
+  79, 97, 87, 62, 71, 94, 77, 57, 87, 119,
+  62, 68, 93, 80, 69, 73, 84, 96, 68, 76,
+  90, 119, 79, 89, 102, 93, 79, 83, 66, 91,
+  89, 89, 98, 68, 70, 92, 100, 63, 73, 81,
+  73, 96, 86, 70, 63, 82, 74, 84, 83, 113,
+  74, 89, 101, 83, 83, 88, 87, 99, 100, 85,
+  79, 116, 85, 106, 78, 95, 80, 88, 85, 79,
+  74, 86, 91, 75, 79, 79, 87, 86, 87, 74,
+  97, 92, 100, 85, 88, 84, 86, 71, 74, 82,
+  75, 84, 103, 78, 73, 95, 96, 79, 80, 70,
+  75, 83, 88, 88, 79, 62, 83, 77, 84, 79,
+  79, 82, 86, 69, 89, 89, 78, 87, 89, 77,
+  88, 109, 91, 100, 89, 74, 80, 91, 97, 81,
+  91, 70, 68, 84, 76, 73, 91, 98, 77, 80,
+  90, 83, 88, 81, 82, 84, 75, 83, 93, 89,
+  79, 95, 89, 93, 94, 77, 81, 86, 86, 91,
+  90, 90, 83, 98, 95, 78, 77, 90, 85, 90,
+  85, 77, 86, 87, 83, 92, 79, 95, 77, 78,
+  70, 77, 78, 82, 78, 82, 116, 86, 94, 128,
+  83, 113, 71, 78, 70, 65, 91, 73, 92, 89,
+  92, 85, 77, 73, 83, 82, 94, 80, 84, 83,
+  87, 84, 86, 76, 83, 75, 75, 72, 79, 79,
+  85, 72, 81, 98, 92, 82, 81, 58, 91, 83,
+  83, 110, 67, 80, 84, 83, 81, 85, 87, 87,
+  84, 69, 71, 92, 85, 80, 96, 62, 70, 99,
+  80, 85, 84, 75, 83, 82, 67, 90, 81, 81,
+  76, 77, 74, 84, 88, 115, 69, 98, 94, 81,
+  75, 68, 90, 90, 71, 79, 89, 107, 81, 78,
+  91, 97, 78, 60, 73, 86, 79, 78, 90, 76,
+  69, 83, 93, 77, 83, 84, 79, 95, 68, 73,
+  71, 80, 78, 87, 80, 98, 68, 74, 79, 67,
+  84, 74, 72, 73, 119, 86, 105, 132, 79, 122,
+  67, 54, 64, 50, 86, 66, 84, 79, 73, 82,
+  80, 61, 77, 75, 107, 75, 78, 92, 64, 86,
+  77, 85, 86, 73, 128, 64, 82, 107, 90, 62,
+  78, 56, 88, 81, 84, 50, 116, 90, 75, 141,
+  70, 118, 83, 86, 96, 82, 82, 87, 93, 76,
+  49, 147, 97, 75, 82, 42, 80, 104, 71, 72,
+  83, 72, 79, 82, 52, 121, 79, 84, 59, 66,
+  74, 97, 73, 147, 68, 69, 81, 67, 78, 58,
+  81, 101, 69, 68, 89, 139, 70, 86, 118, 96,
+  54, 48, 58, 95, 64, 75, 92, 63, 61, 73,
+  100, 80, 75, 84, 85, 96, 75, 68, 49, 77,
+  67, 69, 86, 115, 70, 82, 91, 80, 79, 90,
+  81, 93, 105, 87, 89, 119, 78, 75, 73, 81,
+  72, 76, 89, 81, 81, 72, 85, 79, 78, 78,
+  87, 84, 86, 85, 82, 98, 93, 81, 82, 80,
+  85, 78, 101, 72, 81, 73, 88, 81, 83, 99,
+  86, 79, 82, 62, 81, 69, 85, 95, 77, 92,
+  81, 86, 82, 88, 82, 77, 90, 67, 78, 84,
+  79, 87, 89, 71, 84, 108, 88, 91, 86, 77,
+  74, 77, 69, 80, 82, 80, 70, 76, 75, 91,
+  81, 95, 66, 95, 98, 74, 82, 70, 85, 83,
+  77, 82, 89, 96, 82, 89, 89, 96, 75, 61,
+  78, 85, 71, 83, 81, 83, 73, 86, 68, 67,
+  81, 86, 79, 90, 90, 73, 83, 85, 84, 89,
+  78, 94, 78, 75, 81, 94, 78, 105, 96, 77,
+  82, 88, 89, 86, 94, 95, 78, 89, 66, 92,
+  88, 80, 87, 90, 101, 93, 84, 90, 91, 82,
+  87, 91, 89, 83, 96, 78, 81, 89, 88, 83,
+  80, 89, 91, 77, 71, 85, 85, 105, 78, 87,
+  91, 85, 77, 79, 91, 92, 76, 89, 75, 89,
+  86, 83, 83, 78, 78, 79, 93, 83, 78, 85,
+  85, 74, 95, 83, 77, 78, 88, 79, 79, 75,
+  85, 75, 83, 71, 73, 77, 95, 90, 101, 89,
+  77, 101, 90, 92, 84, 83, 108, 77, 72, 78,
+  94, 81, 93, 87, 82, 89, 92, 71, 94, 86,
+  71, 93, 97, 90, 78, 84, 91, 86, 85, 89,
+  88, 87, 84, 79, 87, 94, 87, 84, 77, 87,
+  63, 80, 96, 103, 79, 99, 92, 79, 94, 86,
+  82, 84, 84, 78, 82, 82, 62, 102, 91, 84,
+  77, 72, 92, 104, 87, 89, 99, 86, 90, 74,
+  75, 95, 100, 73, 80, 85, 76, 84, 78, 78,
+  79, 66, 79, 74, 82, 105, 76, 84, 84, 89,
+  78, 67, 101, 96, 73, 73, 80, 78, 76, 85,
+  88, 65, 77, 70, 88, 77, 84, 87, 85, 74,
+  79, 64, 85, 76, 90, 78, 70, 81, 75, 72,
+  88, 69, 74, 90, 78, 92, 97, 75, 75, 120,
+  97, 98, 71, 82, 107, 73, 74, 70, 81, 81,
+  95, 74, 72, 89, 79, 67, 92, 82, 75, 98,
+  92, 79, 80, 92, 84, 76, 82, 81, 74, 80,
+  99, 78, 77, 99, 80, 78, 79, 96, 77, 85,
+  100, 86, 78, 99, 97, 81, 77, 90, 90, 88,
+  93, 84, 81, 88, 71, 96, 89, 88, 73, 95,
+  101, 91, 80, 92, 92, 86, 83, 78, 92, 93,
+  97, 85, 97, 84, 88, 80, 87, 86, 94, 76,
+  90, 84, 82, 100, 75, 77, 94, 85, 71, 87,
+  85, 91, 80, 82, 79, 85, 86, 80, 83, 80,
+  81, 79, 90, 82, 70, 87, 90, 83, 85, 87,
+  80, 82, 84, 81, 80, 87, 82, 68, 82, 75,
+  75, 82, 94, 93, 88, 81, 81, 95, 82, 90,
+  90, 82, 92, 81, 75, 80, 81, 86, 88, 83,
+  82, 89, 91, 73, 97, 83, 74, 88, 93, 90,
+  77, 89, 89, 96, 87, 90, 92, 88, 81, 81,
+  86, 95, 88, 84, 81, 87, 99, 84, 89, 85,
+  84, 87, 81, 97, 74, 97, 78, 83, 90, 90,
+  86, 85, 88, 78, 77, 78, 78, 86, 85, 77,
+  94, 96, 84, 92, 97, 84, 82, 72, 87, 84,
+  82, 99, 86, 63, 80, 81, 81, 79, 83, 85,
+  89, 75, 98, 75, 79, 83, 83, 83, 91, 76,
+  88, 86, 85, 82, 82, 89, 81, 82, 90, 58,
+  76, 83, 87, 85, 90, 89, 81, 79, 80, 98,
+  83, 69, 86, 78, 85, 80, 84, 91, 94, 91,
+  92, 81, 58, 87, 79, 75, 87, 80, 88, 84,
+  86, 86, 82, 81, 87, 76, 91, 90, 87, 84,
+  66, 81, 78, 91, 92, 75, 86, 89, 73, 132,
+  89, 93, 87, 84, 93, 88, 86, 88, 72, 98,
+  79, 78, 65, 85, 95, 81, 81, 89, 85, 91,
+  74, 92, 73, 100, 85, 90, 87, 86, 79, 76,
+  81, 77, 83, 88, 81, 87, 81, 86, 104, 89,
+  88, 80, 101, 80, 87, 75, 85, 86, 85, 99,
+  76, 101, 78, 77, 82, 76, 69, 89, 87, 85,
+  86, 66, 84, 86, 83, 90, 86, 82, 97, 86,
+  92, 73, 90, 86, 86, 78, 89, 50, 58, 81,
+  74, 86, 82, 91, 85, 88, 81, 91, 77, 89,
+  86, 84, 86, 84, 83, 84, 100, 86, 82, 76,
+  65, 90, 77, 78, 91, 81, 99, 84, 82, 87,
+  86, 82, 77, 77, 86, 86, 79, 86, 76, 80,
+  76, 89, 72, 77, 78, 86, 87, 129, 83, 90,
+  87, 81, 81, 86, 86, 83, 80, 88, 86, 83,
+  88, 83, 84, 70, 92, 89, 91, 91, 65, 87,
+  79, 81, 87, 83, 86, 83, 72, 83, 71, 82,
+  77, 95, 88, 85, 94, 95, 97, 82, 82, 63,
+  87, 78, 98, 87, 89, 86, 94, 102, 79, 129,
+  78, 70, 89, 71, 78, 90, 91, 87, 80, 69,
+  88, 79, 84, 94, 82, 95, 97, 87, 89, 83,
+  88, 88, 84, 78, 91, 65, 71, 87, 75, 92,
+  82, 103, 67, 84, 92, 87, 83, 86, 84, 86,
+  93, 78, 84, 81, 105, 89, 78, 91, 52, 82,
+  73, 81, 94, 84, 94, 94, 74, 92, 96, 81,
+  79, 89, 80, 74, 74, 94, 134, 87, 84, 83,
+  72, 78, 82, 90, 105, 158, 89, 89, 81, 76,
+  79, 93, 96, 76, 81, 76, 80, 96, 101, 84,
+  93, 90, 79, 75, 84, 88, 81, 95, 73, 93,
+  77, 80, 96, 85, 87, 89, 91, 77, 65, 72,
+  85, 81, 82, 84, 92, 98, 77, 94, 83, 87,
+  90, 77, 82, 87, 82, 85, 85, 62, 77, 82,
+  83, 80, 88, 85, 89, 79, 97, 83, 81, 81,
+  78, 81, 92, 72, 78, 91, 84, 83, 78, 95,
+  82, 80, 83, 67, 74, 84, 89, 86, 90, 79,
+  80, 76, 74, 100, 81, 61, 86, 76, 80, 88,
+  87, 91, 87, 85, 95, 86, 61, 81, 79, 84,
+  94, 80, 82, 84, 77, 89, 83, 83, 84, 81,
+  86, 91, 89, 83, 59, 85, 76, 92, 96, 78,
+  86, 87, 68, 111, 81, 92, 78, 87, 97, 90,
+  89, 84, 70, 95, 82, 65, 64, 85, 92, 87,
+  76, 84, 81, 88, 82, 89, 73, 96, 83, 88,
+  87, 86, 81, 80, 85, 75, 85, 84, 81, 86,
+  72, 81, 100, 89, 78, 85, 83, 81, 87, 77,
+  82, 85, 76, 91, 81, 78, 80, 78, 80, 77,
+  76, 93, 86, 79, 88, 74, 83, 84, 81, 85,
+  86, 77, 92, 93, 96, 76, 92, 85, 81, 74,
+  87, 55, 57, 81, 75, 81, 86, 87, 82, 83,
+  77, 92, 75, 79, 88, 81, 79, 87, 88, 85,
+  99, 79, 89, 76, 71, 84, 75, 72, 92, 80,
+  94, 86, 78, 86, 85, 81, 75, 79, 80, 88,
+  76, 84, 63, 79, 80, 92, 80, 83, 76, 83,
+  78, 116, 76, 89, 84, 77, 81, 88, 84, 81,
+  81, 82, 87, 71, 81, 85, 77, 70, 80, 94,
+  86, 97, 70, 88, 79, 92, 81, 80, 82, 89,
+  75, 86, 77, 75, 83, 90, 84, 85, 83, 92,
+  92, 79, 89, 77, 66, 78, 96, 82, 79, 89,
+  89, 94, 78, 119, 81, 73, 86, 72, 68, 90,
+  82, 80, 90, 71, 90, 77, 81, 84, 79, 85,
+  98, 87, 98, 81, 90, 81, 79, 79, 98, 69,
+  68, 84, 76, 87, 90, 97, 75, 79, 96, 87,
+  83, 86, 86, 84, 92, 80, 82, 81, 100, 81,
+  78, 85, 57, 84, 72, 70, 92, 83, 94, 97,
+  80, 85, 89, 79, 78, 90, 75, 84, 77, 93,
+  118, 81, 84, 84, 76, 83, 76, 95, 99, 144,
+  87, 89, 75, 75, 87, 90, 88, 81, 82, 75,
+  79, 88, 95, 84, 89, 91, 77, 78, 79, 89,
+  81, 98, 75, 107, 75, 86, 91, 87, 87, 85,
+  91, 80, 63, 68, 88, 86, 85, 91, 86, 94,
+  82, 93, 91, 79, 86, 76, 79, 87, 83, 93,
+  90, 71, 76, 85, 83, 82, 89, 80, 82, 82,
+  92, 83, 81, 81, 80, 78, 97, 75, 81, 93,
+  90, 82, 83, 94, 86, 86, 93, 73, 85, 85,
+  88, 91, 87, 86, 84, 75, 76, 89, 82, 69,
+  87, 80, 86, 83, 85, 91, 88, 94, 90, 72,
+  57, 82, 80, 91, 98, 82, 93, 80, 86, 85,
+  86, 75, 81, 79, 90, 93, 105, 85, 60, 85,
+  85, 90, 89, 76, 81, 90, 75, 115, 79, 99,
+  79, 99, 102, 90, 90, 79, 66, 99, 75, 69,
+  66, 79, 95, 88, 75, 82, 81, 87, 85, 91,
+  78, 98, 85, 86, 89, 85, 85, 80, 87, 75,
+  79, 72, 88, 85, 70, 82, 93, 90, 75, 87,
+  100, 78, 85, 81, 81, 85, 76, 89, 89, 70,
+  79, 82, 85, 76, 89, 87, 81, 80, 84, 82,
+  84, 85, 82, 85, 86, 78, 87, 93, 96, 77,
+  90, 84, 81, 81, 89, 62, 62, 80, 82, 86,
+  88, 85, 79, 79, 74, 86, 75, 76, 88, 75,
+  81, 86, 88, 84, 101, 84, 89, 69, 70, 82,
+  75, 78, 93, 85, 95, 85, 78, 86, 87, 79,
+  72, 78, 85, 94, 82, 84, 60, 84, 82, 89,
+  88, 82, 77, 83, 78, 105, 81, 92, 84, 81,
+  86, 88, 86, 77, 75, 89, 83, 78, 74, 80,
+  76, 76, 72, 95, 87, 89, 79, 90, 81, 91,
+  83, 79, 84, 89, 76, 84, 80, 77, 76, 81,
+  87, 83, 83, 85, 91, 85, 81, 82, 91, 73,
+  92, 81, 79, 83, 82, 90, 85, 101, 89, 80,
+  86, 69, 81, 85, 75, 82, 87, 76, 92, 78,
+  79, 85, 81, 83, 92, 86, 99, 82, 92, 85,
+  76, 81, 91, 68, 70, 83, 79, 86, 90, 86,
+  88, 82, 85, 84, 81, 86, 82, 75, 90, 77,
+  83, 81, 97, 89, 81, 81, 56, 83, 71, 76,
+  93, 83, 99, 92, 83, 86, 90, 78, 80, 89,
+  82, 89, 79, 86, 98, 81, 81, 84, 87, 87,
+  80, 88, 95, 130, 91, 90, 79, 75, 91, 90,
+  93, 84, 86, 80, 81, 95, 85, 82, 87, 92,
+  93, 64, 79, 102, 84, 89, 88, 67, 85, 79,
+  79, 85, 80, 97, 94, 68, 82, 73, 75, 79,
+  69, 92, 72, 91, 75, 75, 91, 78, 94, 65,
+  91, 84, 73, 92, 77, 89, 82, 90, 104, 68,
+  74, 89, 87, 78, 78, 77, 88, 94, 70, 84,
+  88, 69, 96, 86, 79, 87, 96, 97, 95, 92,
+  84, 95, 86, 86, 93, 70, 80, 84, 100, 82,
+  94, 51, 81, 91, 82, 88, 69, 78, 85, 81,
+  88, 83, 87, 81, 86, 84, 85, 81, 100, 103,
+  93, 92, 71, 87, 92, 89, 81, 107, 69, 79,
+  79, 84, 79, 66, 85, 95, 78, 75, 80, 72,
+  81, 96, 84, 93, 85, 86, 103, 70, 87, 78,
+  92, 81, 85, 77, 79, 85, 85, 98, 94, 62,
+  79, 73, 87, 91, 88, 70, 85, 82, 88, 81,
+  73, 99, 88, 63, 77, 74, 72, 83, 76, 104,
+  73, 88, 80, 72, 90, 71, 104, 55, 87, 85,
+  67, 83, 78, 103, 82, 95, 115, 51, 67, 85,
+  82, 79, 83, 78, 84, 96, 72, 77, 88, 59,
+  83, 86, 86, 87, 113, 93, 95, 94, 92, 93,
+  59, 86, 102, 67, 60, 83, 80, 75, 102, 52,
+  77, 97, 77, 83, 66, 68, 83, 82, 75, 84,
+  86, 78, 84, 80, 87, 92, 89, 109, 99, 96,
+  66, 90, 87, 83, 84, 98, 56, 73, 78, 83,
+  64, 52, 81, 92, 78, 81, 84, 68, 84, 93,
+  86, 85, 86, 87, 109, 63, 84, 78, 87, 92,
+  79, 76, 72, 87, 85, 91, 94, 70, 80, 82,
+  81, 91, 85, 73, 83, 78, 81, 83, 80, 94,
+  90, 72, 87, 73, 75, 82, 94, 93, 86, 86,
+  83, 77, 89, 71, 95, 64, 87, 84, 80, 80,
+  83, 91, 85, 92, 106, 64, 72, 87, 78, 79,
+  85, 84, 88, 92, 72, 89, 87, 68, 92, 79,
+  83, 87, 98, 89, 96, 97, 84, 88, 87, 88,
+  100, 69, 80, 92, 95, 84, 93, 53, 79, 88,
+  81, 89, 65, 79, 85, 80, 78, 96, 84, 82,
+  89, 89, 89, 89, 93, 95, 96, 86, 77, 90,
+  88, 88, 76, 95, 69, 75, 85, 82, 69, 63,
+  80, 91, 75, 78, 86, 74, 83, 88, 92, 89,
+  99, 82, 100, 75, 78, 87, 87, 79, 84, 77,
+  79, 85, 95, 87, 83, 85, 80, 83, 70, 83,
+  90, 80, 82, 82, 66, 81, 75, 86, 73, 63,
+  89, 82, 76, 87, 107, 89, 75, 79, 84, 80,
+  87, 83, 85, 83, 76, 75, 84, 99, 72, 96,
+  81, 71, 106, 68, 90, 88, 92, 72, 80, 85,
+  89, 75, 86, 81, 90, 72, 95, 91, 82, 92,
+  84, 81, 94, 88, 98, 76, 74, 76, 83, 85,
+  73, 77, 98, 80, 78, 72, 82, 82, 89, 86,
+  75, 65, 94, 84, 80, 78, 87, 82, 87, 91,
+  74, 67, 80, 96, 90, 79, 80, 84, 92, 82,
+  78, 87, 78, 82, 79, 88, 71, 70, 80, 97,
+  93, 73, 81, 73, 74, 81, 93, 84, 85, 76,
+  89, 78, 87, 75, 72, 81, 82, 82, 99, 79,
+  103, 81, 88, 86, 77, 76, 69, 85, 95, 80,
+  83, 92, 63, 87, 78, 85, 68, 60, 94, 83,
+  90, 92, 89, 84, 72, 74, 89, 76, 113, 67,
+  94, 93, 69, 78, 77, 84, 81, 108, 80, 53,
+  134, 63, 84, 90, 102, 72, 80, 82, 83, 67,
+  100, 84, 89, 72, 102, 98, 93, 89, 90, 79,
+  93, 84, 110, 87, 57, 76, 84, 88, 56, 89,
+  90, 75, 77, 88, 74, 84, 101, 81, 72, 53,
+  95, 94, 69, 81, 93, 85, 84, 94, 72, 70,
+  73, 106, 95, 86, 80, 95, 100, 81, 72, 74,
+  78, 90, 71, 89, 53, 51, 76, 101, 94, 66,
+  96, 73, 71, 81, 100, 82, 85, 75, 89, 72,
+  79, 74, 66, 82, 78, 85, 93, 71, 94, 78,
+  79, 82, 81, 104, 72, 84, 87, 85, 86, 81,
+  73, 85, 75, 88, 69, 64, 97, 77, 91, 80,
+  80, 91, 78, 78, 91, 81, 91, 72, 89, 95,
+  74, 84, 82, 85, 84, 94, 77, 71, 108, 72,
+  69, 87, 93, 74, 82, 87, 87, 74, 88, 83,
+  93, 77, 93, 77, 86, 90, 86, 83, 96, 89,
+  98, 75, 68, 76, 78, 83, 70, 78, 87, 83,
+  80, 69, 79, 87, 95, 82, 75, 71, 94, 85,
+  81, 97, 81, 81, 78, 92, 79, 79, 78, 100,
+  94, 77, 85, 86, 91, 81, 78, 82, 77, 90,
+  84, 86, 66, 70, 78, 95, 100, 74, 97, 72,
+  81, 87, 86, 83, 86, 75, 85, 75, 72, 81,
+  73, 82, 85, 80, 94, 79, 86, 89, 82, 88,
+  82, 74, 69, 90, 82, 89, 91, 77, 89, 89,
+  83, 78, 70, 81, 91, 86, 85, 86, 101, 94,
+  79, 80, 89, 89, 77, 85, 84, 90, 83, 76,
+  91, 105, 82, 80, 82, 76, 93, 78, 89, 88,
+  87, 88, 71, 89, 90, 74, 85, 89, 92, 92,
+  85, 89, 72, 86, 72, 81, 92, 84, 82, 75,
+  87, 78, 80, 83, 88, 64, 95, 90, 94, 79,
+  94, 71, 81, 91, 80, 86, 94, 86, 93, 87,
+  84, 87, 91, 90, 74, 73, 70, 81, 80, 83,
+  77, 81, 79, 86, 82, 81, 75, 92, 90, 90,
+  83, 96, 90, 90, 78, 85, 91, 87, 91, 75,
+  80, 90, 83, 70, 68, 91, 90, 77, 86, 80,
+  76, 73, 95, 94, 93, 87, 87, 99, 89, 69,
+  67, 89, 90, 83, 97, 82, 98, 88, 88, 76,
+  73, 92, 99, 83, 101, 83, 67, 89, 85, 79,
+  93, 86, 101, 84, 85, 105, 92, 74, 87, 90,
+  84, 79, 89, 70, 90, 75, 96, 94, 93, 99,
+  70, 88, 90, 75, 96, 89, 94, 106, 86, 88,
+  67, 88, 58, 83, 89, 79, 83, 91, 80, 77,
+  87, 89, 80, 59, 87, 83, 89, 85, 86, 64,
+  94, 83, 87, 82, 97, 88, 98, 91, 89, 90,
+  89, 89, 76, 77, 69, 78, 68, 89, 72, 82,
+  85, 90, 82, 74, 72, 85, 84, 93, 90, 98,
+  95, 91, 93, 86, 113, 89, 95, 78, 76, 89,
+  88, 67, 60, 90, 83, 80, 90, 77, 80, 72,
+  91, 94, 86, 87, 79, 86, 87, 97, 69, 83,
+  82, 89, 89, 75, 90, 80, 82, 83, 70, 84,
+  95, 81, 93, 85, 72, 91, 84, 80, 88, 86,
+  80, 85, 80, 95, 84, 85, 87, 87, 78, 78,
+  91, 80, 97, 78, 79, 87, 87, 85, 71, 89,
+  92, 76, 85, 85, 97, 96, 82, 77, 73, 85,
+  75, 81, 91, 86, 86, 76, 87, 81, 82, 81,
+  82, 69, 91, 87, 94, 75, 91, 76, 84, 86,
+  86, 86, 93, 83, 99, 104, 81, 88, 84, 88,
+  79, 79, 70, 86, 79, 81, 82, 79, 80, 82,
+  88, 83, 74, 84, 95, 90, 86, 95, 89, 91,
+  81, 88, 96, 77, 95, 88, 81, 89, 101, 71,
+  69, 90, 72, 79, 83, 82, 80, 70, 93, 93,
+  84, 87, 86, 88, 77, 92, 79, 93, 86, 80,
+  70, 83, 86, 74, 70, 99, 87, 79, 80, 89,
+  89, 75, 68, 81, 79, 78, 85, 85, 97, 84,
+  81, 80, 84, 93, 82, 78, 87, 83, 92, 89,
+  86, 79, 82, 84, 79, 92, 84, 80, 74, 74,
+  76, 84, 87, 79, 79, 97, 85, 91, 92, 82,
+  86, 69, 83, 86, 79, 85, 78, 69, 84, 86,
+  123, 68, 84, 79, 84, 85, 71, 72, 83, 86,
+  74, 87, 78, 72, 74, 79, 88, 83, 85, 75,
+  84, 92, 80, 79, 89, 81, 83, 88, 78, 79,
+  79, 99, 84, 79, 83, 96, 77, 80, 87, 85,
+  83, 92, 76, 87, 76, 60, 72, 85, 92, 92,
+  79, 83, 80, 82, 93, 86, 85, 76, 103, 83,
+  119, 101, 74, 106, 89, 96, 87, 84, 78, 77,
+  94, 82, 64, 98, 85, 83, 87, 81, 95, 82,
+  88, 76, 81, 89, 88, 88, 78, 103, 84, 77,
+  80, 103, 132, 90, 114, 84, 87, 68, 97, 80,
+  92, 78, 95, 92, 65, 90, 77, 66, 83, 72,
+  87, 73, 76, 74, 70, 77, 84, 86, 80, 71,
+  67, 71, 81, 90, 73, 82, 82, 83, 98, 73,
+  86, 82, 81, 81, 77, 96, 75, 96, 74, 84,
+  79, 80, 75, 88, 92, 95, 72, 66, 73, 81,
+  80, 83, 99, 88, 87, 86, 79, 79, 89, 60,
+  80, 83, 78, 89, 89, 79, 76, 81, 96, 88,
+  74, 93, 65, 61, 109, 95, 87, 88, 83, 89,
+  79, 87, 74, 84, 87, 94, 86, 76, 92, 85,
+  77, 74, 85, 93, 84, 77, 71, 89, 83, 89,
+  69, 83, 79, 76, 83, 80, 82, 75, 94, 86,
+  83, 77, 89, 83, 87, 55, 82, 79, 78, 92,
+  81, 78, 82, 79, 79, 86, 76, 79, 88, 92,
+  76, 85, 86, 69, 78, 75, 84, 93, 88, 81,
+  76, 68, 85, 91, 86, 89, 86, 77, 90, 94,
+  81, 87, 99, 70, 83, 102, 80, 70, 73, 83,
+  80, 80, 76, 78, 91, 85, 81, 92, 81, 83,
+  79, 83, 79, 89, 94, 76, 80, 79, 75, 75,
+  86, 85, 84, 81, 88, 80, 72, 73, 89, 78,
+  86, 99, 74, 86, 86, 84, 93, 85, 72, 91,
+  93, 78, 106, 85, 91, 97, 85, 81, 86, 84,
+  99, 86, 85, 78, 95, 83, 71, 87, 80, 84,
+  75, 75, 90, 82, 82, 76, 91, 69, 62, 87,
+  78, 77, 92, 88, 93, 84, 73, 79, 80, 76,
+  92, 88, 89, 60, 88, 75, 76, 87, 145, 81,
+  93, 80, 87, 77, 84, 78, 86, 85, 72, 102,
+  95, 76, 70, 88, 70, 69, 88, 80, 99, 105,
+  75, 93, 98, 82, 93, 89, 74, 75, 72, 86,
+  77, 82, 91, 78, 122, 65, 94, 82, 93, 76,
+  84, 91, 76, 73, 73, 73, 75, 65, 75, 83,
+  83, 95, 84, 94, 97, 94, 82, 78, 105, 77,
+  80, 79, 111, 80, 83, 87, 91, 76, 87, 92,
+  68, 81, 81, 91, 80, 99, 76, 79, 51, 81,
+  74, 81, 88, 92, 81, 93, 83, 81, 103, 80,
+  82, 76, 105, 88, 132, 93, 67, 84, 76, 78,
+  86, 92, 95, 61, 79, 85, 57, 82, 82, 78,
+  95, 97, 85, 67, 74, 75, 82, 73, 106, 94,
+  67, 132, 93, 84, 76, 97, 193, 76, 170, 92,
+  79, 58, 118, 73, 84, 73, 71, 94, 95, 82,
+  75, 81, 79, 53, 83, 74, 99, 60, 66, 78,
+  87, 80, 92, 94, 74, 77, 71, 94, 64, 78,
+  98, 82, 69, 66, 100, 85, 82, 79, 95, 86,
+  81, 73, 70, 60, 67, 83, 76, 100, 71, 99,
+  59, 81, 80, 96, 81, 78, 105, 79, 81, 80,
+  92, 75, 92, 59, 92, 79, 76, 99, 67, 83,
+  75, 91, 100, 100, 76, 70, 64, 74, 81, 86,
+  86, 102, 81, 101, 72, 84, 86, 81, 80, 96,
+  86, 84, 113, 86, 79, 82, 75, 77, 88, 83,
+  76, 85, 76, 92, 61, 82, 78, 76, 90, 87,
+  81, 80, 91, 86, 87, 74, 91, 88, 80, 85,
+  93, 88, 72, 79, 76, 85, 66, 80, 78, 83,
+  79, 78, 82, 90, 67, 82, 97, 88, 77, 86,
+  85, 84, 91, 83, 86, 64, 77, 97, 91, 80,
+  93, 89, 87, 86, 75, 88, 83, 69, 83, 93,
+  71, 70, 81, 84, 84, 77, 80, 58, 77, 72,
+  83, 84, 76, 103, 76, 92, 70, 87, 93, 94,
+  91, 76, 78, 76, 84, 84, 83, 76, 85, 85,
+  81, 94, 95, 74, 95, 100, 70, 85, 79, 86,
+  102, 85, 79, 79, 98, 83, 108, 79, 86, 95,
+  80, 87, 82, 85, 108, 83, 82, 67, 83, 66,
+  63, 86, 98, 83, 87, 76, 89, 74, 90, 92,
+  93, 72, 84, 82, 76, 86, 84, 90, 94, 74,
+  67, 79, 89, 95, 86, 78, 85, 80, 94, 75,
+  99, 88, 105, 68, 95, 83, 74, 83, 79, 77,
+  90, 94, 86, 96, 85, 90, 81, 91, 71, 75,
+  95, 98, 94, 77, 84, 76, 97, 82, 90, 95,
+  87, 87, 81, 84, 88, 99, 80, 80, 76, 75,
+  85, 83, 97, 83, 83, 62, 74, 83, 76, 78,
+  83, 63, 79, 78, 84, 75, 81, 101, 93, 91,
+  86, 105, 92, 90, 85, 83, 96, 86, 73, 80,
+  88, 77, 91, 77, 69, 80, 72, 83, 76, 87,
+  83, 77, 61, 85, 80, 87, 70, 81, 77, 99,
+  90, 77, 95, 91, 80, 78, 83, 83, 79, 82,
+  88, 55, 90, 75, 81, 81, 97, 86, 88, 70,
+  80, 81, 71, 90, 86, 94, 84, 58, 69, 85,
+  97, 91, 96, 80, 78, 96, 94, 81, 98, 72,
+  102, 51, 107, 82, 76, 78, 84, 79, 86, 78,
+  81, 96, 95, 65, 85, 98, 75, 56, 97, 89,
+  94, 66, 82, 76, 98, 77, 93, 96, 98, 101,
+  61, 89, 83, 86, 74, 93, 35, 72, 86, 86,
+  92, 89, 85, 59, 88, 74, 74, 78, 84, 68,
+  71, 83, 67, 69, 83, 106, 89, 90, 89, 100,
+  80, 81, 83, 81, 91, 86, 71, 74, 86, 78,
+  89, 86, 69, 84, 69, 85, 80, 86, 80, 69,
+  82, 94, 51, 92, 70, 88, 73, 93, 90, 73,
+  88, 94, 74, 87, 79, 86, 96, 83, 89, 75,
+  83, 76, 84, 80, 81, 91, 83, 77, 85, 84,
+  78, 84, 86, 92, 86, 73, 90, 84, 99, 88,
+  83, 79, 85, 87, 92, 78, 91, 72, 96, 88,
+  75, 84, 89, 90, 74, 77, 91, 94, 87, 89,
+  83, 68, 80, 88, 84, 82, 92, 98, 89, 73,
+  85, 84, 95, 80, 88, 90, 83, 86, 83, 85,
+  86, 92, 75, 80, 67, 80, 79, 83, 93, 80,
+  81, 88, 68, 87, 84, 79, 88, 82, 77, 85,
+  75, 76, 85, 104, 88, 79, 83, 98, 83, 88,
+  90, 77, 83, 92, 73, 78, 87, 78, 101, 83,
+  77, 79, 76, 81, 80, 83, 87, 87, 74, 90,
+  79, 81, 67, 80, 73, 97, 86, 76, 94, 94,
+  82, 73, 93, 74, 96, 83, 91, 92, 87, 81,
+  90, 92, 73, 79, 79, 96, 82, 98, 78, 85,
+  77, 83, 83, 97, 91, 89, 90, 81, 108, 76,
+  88, 71, 71, 95, 69, 74, 77, 96, 52, 81,
+  72, 86, 87, 95, 84, 83, 95, 80, 79, 75,
+  92, 84, 72, 79, 94, 92, 86, 77, 85, 75,
+  96, 72, 87, 63, 86, 92, 74, 86, 77, 83,
+  86, 94, 81, 80, 73, 109, 84, 92, 77, 114,
+  73, 77, 79, 76, 72, 79, 87, 80, 85, 85,
+  89, 79, 90, 76, 93, 70, 78, 67, 95, 87,
+  78, 73, 81, 53, 87, 76, 97, 98, 89, 94,
+  88, 73, 76, 79, 73, 75, 77, 86, 87, 100,
+  68, 77, 91, 85, 91, 75, 94, 92, 67, 84,
+  111, 77, 76, 87, 86, 74, 86, 75, 78, 86,
+  58, 94, 84, 91, 88, 77, 83, 82, 69, 78,
+  86, 108, 75, 87, 103, 65, 101, 73, 103, 86,
+  68, 105, 86, 76, 81, 79, 59, 50, 81, 71,
+  83, 98, 74, 92, 117, 76, 85, 102, 63, 93,
+  94, 70, 85, 81, 80, 86, 69, 83, 113, 64,
+  117, 55, 95, 102, 83, 88, 81, 127, 85, 107,
+  77, 83, 67, 96, 64, 83, 82, 88, 81, 69,
+  85, 76, 97, 86, 75, 80, 86, 93, 66, 74,
+  88, 91, 108, 61, 77, 57, 84, 123, 78, 92,
+  101, 108, 71, 81, 83, 110, 127, 86, 79, 68,
+  66, 89, 53, 89, 80, 103, 75, 110, 65, 61,
+  88, 74, 78, 66, 86, 84, 48, 93, 88, 92,
+  81, 85, 86, 77, 87, 84, 94, 90, 76, 84,
+  78, 61, 84, 94, 77, 84, 81, 82, 81, 93,
+  90, 85, 83, 85, 99, 81, 88, 83, 79, 98,
+  62, 87, 71, 79, 74, 84, 77, 83, 83, 88,
+  81, 88, 94, 83, 84, 104, 91, 80, 82, 74,
+  90, 97, 86, 87, 78, 79, 90, 82, 90, 60,
+  78, 93, 79, 86, 55, 92, 88, 75, 99, 80,
+  78, 87, 78, 89, 81, 76, 89, 81, 83, 83,
+  63, 84, 84, 71, 83, 82, 86, 75, 89, 99,
+  94, 77, 88, 70, 93, 85, 88, 72, 73, 92,
+  83, 81, 96, 82, 86, 90, 86, 69, 77, 73,
+  75, 96, 68, 81, 88, 97, 69, 72, 81, 86,
+  99, 79, 88, 85, 71, 79, 90, 78, 85, 89,
+  87, 93, 92, 82, 81, 84, 79, 76, 87, 78,
+  81, 87, 73, 77, 70, 87, 76, 95, 81, 82,
+  98, 90, 97, 71, 97, 65, 78, 92, 75, 84,
+  115, 102, 55, 82, 86, 85, 93, 84, 90, 93,
+  100, 90, 96, 81, 93, 76, 75, 75, 86, 86,
+  90, 97, 79, 77, 79, 72, 81, 75, 87, 87,
+  69, 78, 56, 75, 80, 68, 109, 73, 84, 90,
+  92, 81, 76, 116, 79, 81, 73, 80, 79, 88,
+  89, 81, 92, 86, 82, 87, 83, 87, 95, 84,
+  79, 71, 87, 82, 70, 74, 69, 57, 88, 83,
+  100, 94, 79, 85, 91, 63, 85, 80, 69, 83,
+  68, 80, 66, 99, 75, 71, 84, 73, 92, 75,
+  85, 79, 69, 85, 102, 73, 78, 92, 76, 72,
+  104, 80, 67, 83, 81, 86, 86, 87, 79, 79,
+  67, 76, 60, 81, 85, 105, 74, 83, 97, 69,
+  97, 64, 93, 122, 72, 95, 88, 76, 135, 82,
+  83, 78, 83, 59, 128, 98, 86, 98, 126, 87,
+  76, 105, 75, 67, 90, 61, 76, 71, 89, 82,
+  68, 84, 99, 59, 76, 73, 107, 103, 81, 84,
+  55, 93, 72, 71, 85, 91, 99, 80, 75, 78,
+  81, 83, 72, 79, 76, 82, 96, 94, 75, 86,
+  83, 77, 67, 95, 76, 89, 127, 85, 67, 67,
+  74, 112, 82, 86, 80, 65, 76, 86, 86, 100,
+  83, 84, 84, 53, 98, 77, 53, 85, 83, 79,
+  74, 115, 72, 74, 92, 55, 79, 76, 79, 65,
+  59, 89, 82, 82, 96, 89, 84, 81, 91, 81,
+  84, 84, 79, 83, 83, 87, 82, 83, 72, 75,
+  73, 88, 74, 90, 97, 81, 76, 90, 90, 72,
+  89, 107, 86, 95, 76, 83, 83, 80, 77, 81,
+  76, 82, 91, 84, 75, 97, 90, 92, 84, 115,
+  97, 75, 76, 83, 85, 90, 86, 70, 78, 82,
+  76, 78, 84, 61, 84, 79, 73, 78, 63, 75,
+  87, 61, 85, 78, 81, 82, 81, 85, 74, 67,
+  72, 83, 77, 85, 84, 96, 91, 82, 83, 82,
+  84, 84, 80, 71, 96, 86, 79, 72, 87, 81,
+  103, 73, 67, 65, 85, 83, 100, 87, 78, 83,
+  83, 65, 110, 76, 74, 96, 72, 71, 103, 94,
+  71, 73, 85, 76, 100, 71, 84, 74, 75, 82,
+  67, 73, 75, 92, 86, 82, 84, 78, 93, 85,
+  91, 76, 90, 78, 86, 83, 70, 82, 96, 90,
+  82, 81, 95, 95, 80, 94, 80, 77, 83, 74,
+  88, 89, 83, 82, 89, 86, 79, 91, 83, 83,
+  83, 73, 61, 92, 83, 82, 85, 89, 89, 81,
+  82, 83, 82, 108, 86, 82, 93, 89, 75, 89,
+  85, 83, 85, 83, 85, 85, 85, 76, 80, 71,
+  90, 72, 91, 77, 85, 81, 86, 82, 87, 78,
+  79, 94, 78, 88, 95, 79, 93, 79, 85, 95,
+  75, 90, 80, 97, 86, 78, 82, 73, 77, 80,
+  71, 91, 98, 79, 96, 89, 78, 83, 80, 80,
+  89, 77, 86, 93, 78, 81, 63, 85, 91, 75,
+  85, 95, 81, 88, 74, 77, 84, 104, 76, 76,
+  77, 98, 87, 63, 85, 83, 91, 79, 101, 72,
+  91, 86, 83, 83, 70, 91, 102, 97, 73, 77,
+  77, 87, 81, 92, 88, 76, 78, 96, 83, 90,
+  83, 74, 94, 77, 86, 91, 86, 78, 103, 70,
+  72, 85, 83, 83, 72, 67, 91, 79, 82, 84,
+  87, 105, 80, 91, 90, 92, 69, 82, 80, 76,
+  99, 88, 80, 80, 89, 77, 74, 67, 75, 72,
+  96, 74, 79, 72, 82, 68, 91, 65, 80, 99,
+  81, 84, 100, 83, 91, 76, 92, 93, 73, 93,
+  88, 100, 83, 71, 90, 79, 84, 77, 66, 85,
+  99, 79, 106, 95, 64, 87, 90, 72, 105, 68,
+  83, 88, 98, 94, 68, 81, 80, 81, 85, 94,
+  94, 80, 75, 81, 84, 101, 67, 78, 84, 89,
+  80, 88, 82, 79, 96, 84, 92, 74, 89, 86,
+  88, 81, 72, 82, 100, 93, 64, 83, 83, 93,
+  79, 91, 82, 75, 80, 93, 90, 95, 88, 75,
+  81, 82, 86, 86, 79, 80, 85, 73, 76, 90,
+  79, 83, 74, 79, 90, 80, 83, 92, 83, 108,
+  85, 72, 93, 90, 69, 94, 85, 80, 84, 81,
+  83, 89, 87, 73, 82, 76, 63, 68, 90, 70,
+  86, 82, 87, 81, 78, 74, 81, 86, 88, 80,
+  98, 79, 92, 79, 84, 86, 71, 81, 80, 98,
+  79, 77, 80, 76, 94, 81, 77, 77, 99, 80,
+  101, 95, 82, 82, 79, 85, 101, 82, 86, 93,
+  82, 85, 85, 84, 90, 75, 98, 95, 74, 87,
+  76, 79, 85, 102, 78, 78, 75, 79, 78, 72,
+  78, 92, 92, 97, 93, 83, 89, 84, 75, 83,
+  105, 95, 95, 90, 99, 85, 79, 86, 83, 80,
+  89, 103, 95, 86, 99, 71, 76, 83, 84, 84,
+  83, 76, 92, 78, 86, 73, 88, 75, 84, 89,
+  84, 93, 82, 56, 96, 89, 93, 55, 74, 87,
+  89, 81, 79, 82, 94, 79, 87, 77, 70, 67,
+  80, 88, 92, 81, 78, 95, 88, 93, 80, 90,
+  76, 84, 84, 68, 90, 76, 74, 90, 95, 78,
+  93, 85, 76, 92, 90, 78, 60, 71, 93, 83,
+  89, 79, 88, 91, 81, 69, 67, 73, 70, 74,
+  85, 84, 99, 98, 90, 83, 91, 81, 76, 96,
+  90, 90, 82, 79, 109, 106, 60, 70, 82, 94,
+  90, 89, 71, 80, 76, 70, 78, 67, 66, 92,
+  90, 88, 92, 96, 96, 87, 77, 80, 122, 93,
+  81, 92, 90, 65, 68, 94, 78, 73, 96, 100,
+  97, 77, 107, 67, 61, 88, 80, 77, 87, 74,
+  91, 70, 82, 73, 97, 65, 96, 80, 81, 77,
+  80, 48, 99, 83, 79, 48, 69, 87, 98, 79,
+  75, 93, 94, 63, 87, 89, 52, 65, 77, 84,
+  87, 78, 70, 89, 82, 102, 84, 89, 82, 84,
+  89, 68, 80, 81, 64, 95, 90, 84, 80, 80,
+  69, 96, 91, 90, 66, 75, 92, 83, 90, 81,
+  76, 81, 80, 81, 66, 77, 70, 75, 89, 91,
+  106, 122, 89, 83, 91, 84, 81, 86, 70, 86,
+  76, 73, 98, 126, 40, 78, 68, 95, 85, 90,
+  72, 84, 88, 79, 78, 84, 82, 87, 91, 94,
+  83, 81, 81, 84, 81, 86, 101, 92, 94, 81,
+  90, 83, 75, 89, 85, 82, 89, 94, 90, 77,
+  92, 87, 78, 80, 89, 90, 84, 75, 87, 77,
+  91, 76, 99, 79, 92, 85, 85, 84, 84, 68,
+  96, 97, 92, 63, 87, 78, 84, 82, 80, 76,
+  92, 85, 85, 73, 77, 72, 79, 85, 91, 77,
+  93, 96, 87, 95, 82, 93, 76, 85, 95, 68,
+  100, 75, 84, 94, 94, 81, 82, 80, 82, 95,
+  87, 84, 63, 73, 90, 85, 93, 84, 79, 98,
+  86, 87, 66, 73, 71, 72, 78, 92, 99, 92,
+  87, 80, 90, 99, 77, 89, 69, 90, 82, 83,
+  93, 94, 72, 69, 80, 92, 88, 90, 84, 81,
+  77, 82, 86, 73, 84, 110, 100, 94, 88, 95,
+  97, 80, 79, 70, 120, 96, 89, 84, 90, 82,
+  81, 94, 82, 79, 90, 99, 97, 90, 95, 70,
+  65, 84, 100, 83, 87, 75, 86, 84, 83, 68,
+  84, 66, 84, 97, 103, 91, 75, 48, 100, 84,
+  93, 55, 70, 86, 85, 79, 82, 83, 85, 86,
+  75, 79, 64, 66, 79, 88, 89, 67, 84, 85,
+  82, 80, 86, 68, 68, 91, 71, 61, 82, 86,
+  74, 86, 85, 91, 95, 75, 89, 82, 93, 78,
+  58, 64, 89, 78, 77, 75, 110, 76, 82, 82,
+  72, 73, 66, 73, 94, 78, 101, 121, 88, 80,
+  91, 74, 84, 79, 88, 87, 73, 56, 94, 110,
+  46, 81, 75, 83, 93, 94, 91, 75, 85, 73,
+  88, 71, 72, 115, 91, 80, 81, 110, 114, 91,
+  75, 61, 143, 92, 78, 91, 81, 78, 73, 104,
+  70, 69, 98, 91, 98, 94, 109, 68, 37, 92,
+  93, 76, 98, 80, 96, 77, 78, 69, 88, 52,
+  91, 82, 110, 69, 75, 28, 106, 76, 74, 44,
+  71, 95, 103, 75, 71, 94, 93, 71, 71, 96,
+  51, 63, 76, 83, 77, 78, 76, 78, 71, 76,
+  89, 60, 74, 86, 70, 56, 64, 89, 60, 92,
+  80, 108, 78, 72, 77, 88, 91, 82, 55, 62,
+  92, 79, 70, 77, 86, 62, 81, 80, 68, 79,
+  61, 74, 94, 85, 107, 156, 83, 83, 99, 76,
+  86, 71, 74, 83, 68, 49, 91, 141, 0, 91,
+  59, 79, 88, 97, 73, 89, 96, 84, 82, 89,
+  87, 97, 95, 93, 85, 85, 91, 86, 83, 77,
+  104, 93, 86, 82, 88, 88, 76, 98, 89, 80,
+  87, 91, 93, 97, 84, 83, 69, 80, 94, 88,
+  88, 75, 92, 80, 87, 71, 88, 71, 87, 91,
+  104, 81, 79, 61, 98, 87, 98, 63, 79, 87,
+  86, 83, 78, 75, 91, 90, 71, 76, 67, 73,
+  88, 85, 82, 72, 79, 89, 84, 79, 89, 74,
+  70, 84, 72, 65, 96, 82, 84, 101, 83, 94,
+  76, 75, 90, 90, 89, 81, 58, 67, 78, 81,
+  80, 82, 82, 85, 86, 72, 68, 73, 66, 73,
+  91, 85, 100, 107, 76, 79, 89, 98, 79, 81,
+  78, 87, 76, 65, 84, 94, 60, 80, 79, 80,
+  87, 90, 69, 79, 81, 94, 79, 75, 86, 91,
+  101, 102, 86, 86, 87, 79, 86, 82, 93, 78,
+  89, 83, 88, 80, 75, 73, 86, 87, 78, 94,
+  84, 79, 77, 82, 91, 78, 99, 82, 85, 88,
+  77, 99, 98, 70, 95, 86, 86, 103, 80, 108,
+  75, 88, 85, 93, 91, 70, 73, 82, 73, 75,
+  87, 78, 84, 101, 83, 75, 88, 69, 84, 94,
+  84, 79, 95, 82, 98, 86, 80, 76, 75, 83,
+  87, 72, 93, 83, 90, 77, 90, 94, 92, 76,
+  80, 82, 94, 97, 56, 69, 85, 92, 83, 76,
+  104, 100, 82, 96, 86, 67, 79, 94, 83, 78,
+  79, 66, 80, 85, 90, 79, 82, 99, 83, 86,
+  74, 75, 88, 82, 74, 75, 109, 80, 97, 87,
+  79, 81, 88, 92, 82, 70, 86, 89, 106, 97,
+  78, 94, 102, 84, 87, 78, 99, 79, 90, 80,
+  84, 81, 73, 79, 85, 84, 86, 92, 86, 88,
+  79, 80, 89, 81, 90, 77, 92, 84, 85, 107,
+  89, 63, 84, 77, 90, 95, 100, 86, 70, 89,
+  89, 89, 93, 62, 71, 79, 79, 70, 84, 80,
+  88, 86, 83, 78, 69, 66, 90, 89, 74, 86,
+  80, 76, 90, 87, 80, 72, 77, 85, 87, 70,
+  88, 83, 97, 91, 87, 105, 84, 71, 85, 85,
+  104, 89, 56, 65, 76, 91, 74, 74, 90, 85,
+  84, 89, 79, 68, 65, 90, 90, 81, 76, 89,
+  75, 82, 88, 80, 83, 94, 80, 80, 75, 73,
+  88, 92, 59, 76, 106, 75, 89, 96, 65, 88,
+  96, 91, 77, 85, 87, 85, 97, 103, 85, 78,
+  85, 82, 89, 92, 84, 83, 85, 83, 96, 86,
+  83, 79, 94, 85, 74, 89, 84, 94, 71, 86,
+  94, 74, 90, 87, 88, 87, 85, 97, 99, 70,
+  82, 86, 88, 96, 81, 88, 78, 95, 82, 88,
+  93, 73, 74, 78, 75, 80, 85, 74, 88, 99,
+  78, 73, 85, 74, 96, 90, 79, 91, 82, 82,
+  97, 86, 86, 74, 78, 83, 78, 71, 101, 82,
+  98, 106, 88, 100, 80, 78, 81, 87, 91, 84,
+  58, 71, 73, 93, 82, 80, 87, 102, 83, 75,
+  79, 68, 81, 94, 87, 85, 76, 64, 76, 86,
+  91, 93, 85, 102, 91, 88, 76, 84, 80, 79,
+  83, 73, 109, 81, 93, 86, 78, 83, 76, 81,
+  84, 86, 69, 80, 84, 96, 84, 98, 85, 89,
+  82, 83, 82, 97, 70, 73, 88, 72, 85, 88,
+  85, 80, 93, 72, 97, 87, 98, 68, 65, 83,
+  84, 81, 84, 83, 89, 86, 80, 81, 77, 84,
+  96, 74, 82, 100, 76, 100, 84, 77, 87, 92,
+  91, 89, 77, 71, 86, 84, 88, 83, 73, 84,
+  84, 79, 93, 79, 77, 98, 79, 93, 88, 77,
+  88, 82, 74, 89, 84, 86, 79, 83, 101, 88,
+  87, 99, 94, 86, 89, 78, 88, 80, 68, 97,
+  86, 72, 78, 87, 84, 86, 92, 93, 83, 86,
+  82, 75, 93, 81, 78, 50, 92, 72, 86, 90,
+  78, 87, 84, 76, 88, 91, 90, 72, 74, 69,
+  84, 103, 76, 83, 82, 84, 76, 80, 87, 75,
+  68, 78, 88, 94, 83, 92, 92, 88, 88, 75,
+  85, 92, 67, 71, 84, 67, 77, 90, 94, 83,
+  91, 65, 86, 82, 95, 64, 61, 78, 86, 76,
+  85, 83, 89, 84, 83, 82, 85, 83, 100, 69,
+  87, 98, 77, 97, 83, 81, 86, 87, 92, 82,
+  76, 72, 82, 87, 89, 84, 72, 89, 75, 82,
+  94, 87, 80, 92, 77, 96, 86, 69, 92, 74,
+  71, 88, 85, 90, 80, 81, 104, 87, 92, 102,
+  91, 81, 87, 77, 86, 74, 64, 95, 81, 72,
+  76, 86, 84, 89, 85, 97, 81, 84, 81, 77,
+  96, 81, 75, 38, 95, 70, 86, 93, 76, 87,
+  79, 74, 88, 89, 89, 64, 64, 68, 87, 105,
+  79, 84, 81, 85, 82, 74, 85, 82, 78, 81,
+  80, 93, 86, 95, 79, 84, 84, 83, 85, 94,
+  72, 78, 71, 72, 102, 90, 93, 82, 95, 75,
+  78, 82, 95, 61, 65, 73, 89, 81, 81, 77,
+  85, 81, 82, 78, 92, 82, 90, 75, 80, 89,
+  81, 92, 83, 85, 90, 86, 88, 79, 78, 77,
+  92, 87, 84, 80, 75, 85, 91, 80, 101, 81,
+  72, 89, 82, 91, 89, 82, 86, 83, 78, 99,
+  94, 84, 80, 80, 92, 84, 87, 89, 89, 87,
+  85, 77, 83, 88, 76, 91, 83, 76, 76, 90,
+  71, 83, 87, 97, 82, 87, 85, 73, 97, 83,
+  81, 59, 95, 76, 83, 97, 84, 83, 82, 74,
+  88, 92, 88, 75, 73, 69, 85, 103, 74, 83,
+  70, 85, 77, 79, 87, 90, 84, 78, 82, 85,
+  91, 95, 86, 88, 96, 82, 88, 83, 55, 74,
+  89, 67, 85, 93, 84, 82, 92, 60, 105, 86,
+  102, 60, 65, 74, 87, 73, 82, 75, 87, 97,
+  97, 79, 73, 88, 86, 76, 75, 90, 80, 99,
+  85, 81, 89, 76, 91, 93, 79, 77, 86, 88,
+  89, 85, 78, 84, 83, 77, 98, 76, 78, 88,
+  85, 85, 89, 74, 84, 75, 76, 88, 85, 85,
+  83, 78, 99, 81, 86, 89, 95, 89, 101, 85,
+  79, 107, 79, 90, 77, 75, 68, 86, 80, 76,
+  83, 86, 75, 88, 74, 58, 98, 86, 78, 60,
+  93, 79, 79, 89, 78, 73, 82, 67, 88, 91,
+  87, 72, 59, 79, 80, 103, 70, 83, 71, 87,
+  82, 77, 87, 73, 83, 81, 85, 82, 95, 92,
+  92, 89, 97, 77, 93, 75, 53, 69, 85, 62,
+  81, 97, 93, 81, 90, 52, 103, 88, 100, 55,
+  65, 73, 88, 71, 81, 76, 87, 93, 99, 70,
+  80, 85, 84, 75, 76, 90, 84, 96, 85, 85,
+  90, 65, 86, 80, 80, 73, 78, 92, 89, 89,
+  80, 87, 66, 73, 105, 82, 80, 77, 74, 82,
+  93, 70, 87, 63, 76, 91, 84, 89, 80, 75,
+  101, 85, 86, 96, 88, 87, 97, 84, 81, 99,
+  65, 86, 69, 76, 64, 88, 76, 82, 70, 88,
+  72, 88, 75, 59, 98, 86, 72, 55, 96, 76,
+  82, 95, 80, 77, 81, 59, 87, 92, 83, 70,
+  53, 83, 81, 105, 74, 84, 72, 92, 89, 73,
+  86, 81, 87, 82, 80, 89, 91, 93, 82, 85,
+  92, 79, 90, 79, 60, 75, 76, 72, 107, 92,
+  94, 80, 91, 65, 100, 82, 101, 55, 63, 71,
+  85, 77, 79, 72, 85, 95, 104, 76, 85, 89,
+  75, 81, 75, 87, 83, 94, 83, 88, 92, 71,
+  87, 78, 82, 82, 90, 93, 88, 81, 84, 83,
+  83, 74, 106, 76, 76, 86, 82, 82, 89, 89,
+  85, 79, 79, 97, 89, 84, 80, 77, 89, 83,
+  84, 81, 81, 94, 99, 89, 77, 117, 86, 84,
+  75, 80, 65, 89, 68, 75, 82, 83, 74, 89,
+  80, 61, 97, 87, 80, 74, 91, 83, 78, 102,
+  90, 68, 83, 71, 93, 94, 80, 80, 67, 79,
+  83, 99, 71, 86, 80, 83, 85, 72, 94, 99,
+  80, 74, 71, 84, 84, 93, 80, 91, 89, 98,
+  88, 84, 66, 80, 89, 84, 110, 87, 84, 83,
+  84, 73, 85, 83, 103, 86, 69, 74, 85, 73,
+  86, 67, 78, 106, 96, 62, 76, 89, 70, 81,
+  80, 80, 79, 104, 75, 84, 95, 73, 104, 85,
+  81, 85, 89, 88, 89, 75, 97, 75, 75, 81,
+  99, 78, 78, 90, 92, 92, 77, 91, 80, 84,
+  89, 84, 76, 80, 91, 79, 80, 91, 83, 76,
+  91, 91, 92, 85, 78, 125, 90, 84, 79, 78,
+  72, 83, 75, 68, 79, 86, 78, 90, 92, 63,
+  94, 86, 87, 85, 85, 76, 75, 86, 82, 68,
+  81, 80, 92, 92, 80, 83, 79, 79, 90, 91,
+  72, 84, 79, 84, 89, 66, 86, 90, 82, 76,
+  77, 86, 86, 92, 78, 90, 88, 97, 87, 74,
+  64, 78, 90, 84, 118, 87, 82, 81, 78, 67,
+  84, 83, 102, 82, 73, 73, 81, 77, 90, 71,
+  75, 105, 102, 58, 83, 87, 69, 79, 77, 81,
+  82, 106, 78, 88, 99, 67, 100, 88, 84, 83,
+  88, 94, 89, 74, 102, 82, 71, 75, 98, 86,
+  72, 91, 86, 93, 80, 103, 78, 88, 94, 89,
+  76, 83, 90, 74, 72, 85, 80, 73, 85, 99,
+  91, 80, 81, 135, 93, 81, 74, 80, 68, 84,
+  74, 76, 82, 92, 74, 89, 102, 65, 89, 89,
+  85, 92, 83, 73, 71, 87, 88, 66, 86, 86,
+  101, 99, 75, 86, 75, 81, 95, 92, 73, 83,
+  89, 85, 82, 70, 88, 97, 88, 78, 75, 90,
+  85, 92, 76, 90, 87, 98, 87, 79, 72, 81,
+  88, 92, 121, 88, 82, 85, 86, 74, 93, 78,
+  98, 92, 72, 74, 81, 85, 90, 70, 82, 104,
+  102, 64, 88, 92, 69, 87, 79, 82, 81, 101,
+  82, 86, 98, 73, 106, 88, 84, 96, 93, 92,
+  87, 75, 102, 76, 72, 78, 92, 81, 74, 82,
+  90, 91, 79, 109, 80, 95, 89, 94, 80, 81,
+  91, 79, 69, 75, 81, 69, 81, 96, 92, 86,
+  76, 135, 102, 77, 77, 85, 70, 90, 77, 71,
+  80, 93, 80, 88, 101, 65, 87, 88, 94, 100,
+  87, 78, 71, 90, 85, 58, 84, 90, 98, 99,
+  83, 87, 87, 86, 94, 84, 72, 90, 86, 77,
+  80, 67, 87, 93, 91, 77, 67, 60, 93, 85,
+  86, 89, 74, 82, 87, 99, 84, 89, 88, 103,
+  86, 76, 89, 88, 79, 115, 92, 85, 84, 83,
+  81, 88, 81, 73, 86, 83, 79, 88, 76, 79,
+  90, 86, 82, 76, 88, 79, 80, 87, 87, 83,
+  61, 75, 87, 83, 73, 93, 81, 83, 88, 85,
+  80, 78, 90, 77, 75, 89, 89, 83, 72, 81,
+  89, 84, 84, 74, 74, 70, 85, 90, 81, 78,
+  76, 91, 94, 71, 79, 89, 85, 88, 83, 84,
+  71, 88, 80, 93, 77, 80, 90, 99, 80, 84,
+  84, 79, 88, 87, 79, 93, 86, 100, 87, 85,
+  105, 82, 95, 76, 83, 155, 93, 87, 96, 95,
+  81, 93, 97, 78, 88, 86, 84, 84, 73, 71,
+  86, 75, 94, 76, 72, 54, 99, 84, 89, 79,
+  74, 79, 91, 91, 72, 90, 92, 95, 82, 94,
+  92, 86, 82, 109, 89, 85, 85, 85, 86, 81,
+  82, 73, 82, 89, 81, 83, 77, 79, 90, 83,
+  84, 79, 95, 70, 83, 83, 92, 78, 61, 78,
+  89, 82, 75, 90, 82, 81, 90, 84, 81, 77,
+  75, 81, 78, 88, 94, 80, 72, 79, 82, 80,
+  92, 70, 71, 77, 83, 91, 82, 85, 79, 76,
+  82, 71, 74, 85, 89, 93, 84, 87, 63, 89,
+  74, 103, 77, 77, 93, 101, 78, 83, 72, 81,
+  77, 88, 76, 92, 94, 108, 88, 80, 109, 75,
+  93, 75, 71, 160, 80, 85, 92, 93, 77, 91,
+  91, 78, 71, 88, 87, 94, 79, 72, 84, 79,
+  89, 76, 71, 68, 88, 84, 81, 83, 77, 85,
+  89, 93, 85, 90, 87, 97, 93, 78, 88, 92,
+  85, 113, 93, 80, 82, 83, 82, 77, 87, 91,
+  86, 89, 85, 88, 78, 83, 87, 87, 85, 79,
+  86, 78, 80, 86, 92, 81, 62, 78, 87, 90,
+  78, 92, 83, 81, 80, 82, 79, 68, 101, 72,
+  79, 88, 84, 84, 97, 78, 88, 83, 88, 77,
+  75, 86, 85, 91, 86, 75, 73, 82, 93, 74,
+  82, 85, 86, 89, 81, 87, 69, 86, 83, 95,
+  78, 82, 85, 97, 82, 84, 85, 78, 85, 92,
+  76, 93, 84, 93, 89, 83, 99, 80, 89, 73,
+  74, 135, 88, 88, 83, 94, 85, 91, 91, 72,
+  90, 87, 83, 79, 74, 79, 79, 90, 91, 82,
+  73, 62, 95, 85, 83, 88, 78, 77, 85, 87,
+  68, 89, 91, 92, 89, 79, 90, 83, 79, 109,
+  86, 81, 81, 84, 85, 87, 77, 75, 87, 82,
+  84, 85, 87, 79, 86, 80, 81, 78, 93, 84,
+  83, 90, 92, 79, 65, 72, 87, 80, 78, 86,
+  84, 82, 95, 89, 86, 79, 78, 79, 82, 86,
+  87, 71, 72, 81, 82, 88, 85, 69, 80, 76,
+  80, 94, 81, 80, 78, 87, 79, 75, 81, 85,
+  80, 85, 84, 84, 75, 88, 79, 92, 74, 76,
+  85, 99, 84, 87, 70, 80, 68, 78, 86, 89,
+  90, 97, 83, 83, 116, 81, 82, 79, 78, 156,
+  78, 87, 99, 95, 82, 92, 97, 76, 73, 86,
+  85, 83, 72, 85, 74, 77, 94, 81, 81, 60,
+  100, 82, 89, 83, 78, 72, 91, 86, 58, 87,
+  93, 92, 82, 93, 95, 77, 76, 100, 81, 83,
+  84, 93, 90, 84, 79, 76, 88, 80, 85, 77,
+  87, 84, 90, 79, 85, 83, 98, 78, 85, 88,
+  95, 81, 64, 70, 89, 78, 81, 82, 88, 76,
+  100, 88, 87, 78, 66, 88, 86, 87, 95, 69,
+  68, 81, 78, 83, 89, 63, 80, 86, 75, 96,
+  79, 85, 81, 80, 73, 80, 77, 84, 80, 91,
+  84, 83, 68, 89, 77, 98, 74, 75, 91, 99,
+  86, 81, 62, 81, 62, 80, 92, 89, 89, 101,
+  84, 82, 120, 79, 81, 81, 70, 162, 67, 85,
+  89, 94, 75, 87, 84, 71, 59, 86, 88, 96,
+  80, 82, 82, 84, 88, 79, 76, 68, 89, 84,
+  81, 82, 75, 81, 87, 85, 72, 82, 83, 91,
+  95, 81, 90, 87, 82, 111, 85, 78, 84, 87,
+  84, 80, 79, 85, 86, 93, 84, 83, 87, 82,
+  86, 86, 84, 81, 91, 83, 84, 86, 91, 84,
+  62, 75, 85, 84, 80, 87, 86, 78, 90, 85,
+  81, 72, 79, 76, 84, 85, 87, 75, 83, 79,
+  80, 87, 88, 76, 78, 90, 83, 93, 86, 74,
+  75, 88, 83, 80, 78, 84, 79, 87, 81, 86,
+  72, 88, 80, 85, 77, 78, 87, 96, 84, 75,
+  71, 78, 68, 82, 83, 90, 94, 90, 87, 82,
+  109, 82, 82, 80, 78, 136, 80, 85, 89, 93,
+  82, 94, 91, 74, 80, 89, 84, 81, 79, 81,
+  77, 91, 88, 78, 77, 75, 83, 89, 85, 88,
+  70, 78, 90, 86, 84, 87, 88, 96, 85, 71,
+  90, 83, 75, 116, 88, 77, 80, 85, 82, 82,
+  72, 74, 82, 90, 88, 88, 89, 81, 79, 83,
+  78, 82, 90, 86, 79, 89, 89, 76, 68, 70,
+  87, 83, 76, 83, 85, 86, 92, 89, 87, 82,
+  89, 74, 85, 83, 83, 79, 79, 81, 91, 83,
+  80, 70, 74, 78, 77, 87, 85, 82, 75, 90,
+  83, 73, 78, 85, 87, 84, 83, 87, 79, 85,
+  83, 81, 74, 78, 81, 99, 81, 90, 78, 77,
+  65, 79, 83, 93, 90, 89, 81, 88, 100, 84,
+  82, 77, 80, 139, 81, 83, 89, 88, 83, 94,
+  105, 81, 93, 87, 82, 85, 78, 87, 76, 77,
+  92, 80, 81, 73, 87, 85, 95, 84, 70, 77,
+  97, 85, 77, 86, 89, 93, 83, 76, 94, 78,
+  71, 111, 83, 81, 86, 86, 81, 80, 75, 78,
+  86, 81, 90, 80, 91, 86, 84, 86, 79, 83,
+  92, 81, 84, 87, 87, 77, 62, 72, 88, 81,
+  76, 81, 93, 83, 94, 90, 89, 84, 73, 80,
+  85, 83, 91, 77, 70, 81, 89, 82, 83, 63,
+  74, 82, 80, 88, 82, 88, 77, 83, 81, 80,
+  78, 86, 88, 82, 79, 90, 82, 92, 79, 89,
+  73, 75, 89, 99, 79, 77, 72, 77, 63, 78,
+  85, 91, 83, 89, 80, 88, 104, 82, 81, 80,
+  74, 142, 77, 81, 86, 89, 80, 90, 97, 75,
+  85, 86, 88, 95, 84, 84, 80, 84, 85, 79,
+  80, 80, 83, 88, 83, 85, 70, 80, 89, 81,
+  86, 80, 78, 92, 92, 75, 85, 87, 75, 112,
+  86, 75, 84, 81, 76, 77, 74, 83, 85, 97,
+  85, 88, 89, 82, 82, 89, 83, 83, 88, 82,
+  79, 84, 89, 85, 63, 74, 85, 81, 74, 84,
+  87, 83, 91, 81, 82, 73, 86, 73, 84, 80,
+  83, 77, 82, 81, 84, 83, 80, 73, 76, 83,
+  83, 90, 86, 79, 74, 82, 83, 77, 82, 83,
+  87, 88, 80, 88, 74, 89, 83, 76, 78, 81,
+  83, 95, 78, 75, 74, 76, 66, 78, 82, 90,
+  89, 85, 82, 87, 95, 83, 83, 82, 83, 123,
+  82, 84, 94, 88, 78, 94, 97, 81, 97, 88,
+  91, 91, 92, 80, 82, 70, 78, 66, 93, 86,
+  77, 93, 120, 103, 77, 83, 73, 65, 85, 95,
+  98, 64, 82, 95, 85, 85, 85, 87, 103, 83,
+  102, 100, 67, 76, 103, 103, 81, 82, 87, 88,
+  83, 92, 89, 90, 86, 111, 86, 92, 70, 83,
+  94, 89, 97, 73, 82, 71, 63, 64, 89, 89,
+  86, 72, 82, 90, 78, 66, 67, 74, 71, 76,
+  108, 93, 73, 81, 91, 64, 80, 108, 78, 84,
+  86, 87, 104, 78, 87, 86, 84, 91, 92, 79,
+  71, 86, 87, 103, 75, 86, 81, 93, 74, 61,
+  87, 93, 90, 84, 83, 84, 70, 91, 79, 85,
+  95, 91, 74, 98, 85, 102, 73, 88, 81, 75,
+  90, 87, 82, 74, 83, 80, 89, 92, 69, 57,
+  92, 86, 69, 104, 77, 97, 84, 95, 77, 72,
+  61, 92, 66, 84, 77, 67, 90, 83, 62, 76,
+  105, 100, 67, 92, 80, 81, 111, 89, 77, 81,
+  66, 79, 71, 110, 74, 90, 65, 82, 90, 72,
+  66, 68, 85, 96, 90, 106, 96, 70, 78, 86,
+  78, 72, 89, 75, 115, 72, 71, 87, 85, 88,
+  93, 58, 76, 72, 52, 80, 92, 88, 54, 81,
+  92, 86, 79, 94, 62, 96, 74, 70, 93, 81,
+  87, 90, 64, 80, 84, 99, 70, 81, 95, 90,
+  77, 85, 114, 75, 81, 78, 79, 77, 80, 88,
+  91, 84, 93, 84, 101, 70, 75, 64, 88, 94,
+  77, 91, 66, 97, 123, 82, 82, 75, 81, 84,
+  91, 92, 83, 91, 79, 77, 80, 63, 89, 72,
+  79, 76, 75, 92, 91, 75, 89, 75, 68, 79,
+  83, 89, 89, 90, 93, 81, 37, 72, 91, 81,
+  82, 97, 82, 79, 68, 87, 77, 82, 91, 95,
+  70, 98, 89, 85, 93, 94, 90, 64, 87, 83,
+  91, 78, 97, 91, 100, 89, 70, 85, 73, 93,
+  82, 98, 118, 88, 87, 80, 76, 99, 81, 72,
+  73, 106, 87, 89, 103, 75, 77, 72, 111, 87,
+  80, 93, 71, 75, 87, 83, 95, 93, 84, 73,
+  94, 86, 83, 70, 86, 89, 115, 86, 85, 92,
+  100, 77, 73, 88, 90, 99, 86, 83, 83, 91,
+  98, 81, 98, 85, 81, 78, 74, 68, 84, 77,
+  78, 91, 74, 83, 88, 76, 88, 81, 87, 98,
+  84, 91, 79, 81, 79, 87, 91, 78, 85, 66,
+  77, 65, 93, 86, 82, 87, 114, 106, 73, 83,
+  73, 65, 84, 97, 94, 62, 83, 96, 80, 87,
+  79, 89, 80, 81, 88, 88, 71, 74, 98, 100,
+  72, 80, 83, 90, 85, 77, 90, 84, 83, 107,
+  80, 80, 75, 94, 89, 83, 91, 75, 80, 75,
+  71, 67, 87, 90, 83, 66, 72, 86, 73, 68,
+  76, 74, 75, 84, 78, 89, 70, 82, 88, 68,
+  76, 110, 71, 84, 89, 83, 109, 85, 83, 90,
+  80, 91, 75, 73, 81, 79, 94, 98, 66, 85,
+  87, 91, 90, 64, 86, 70, 85, 84, 86, 89,
+  84, 83, 78, 84, 79, 87, 72, 96, 73, 85,
+  92, 83, 67, 72, 76, 87, 77, 71, 84, 79,
+  79, 91, 60, 63, 69, 86, 70, 94, 72, 94,
+  91, 91, 80, 75, 60, 77, 62, 81, 79, 74,
+  85, 87, 71, 74, 85, 99, 59, 90, 75, 78,
+  103, 78, 76, 75, 57, 81, 55, 103, 67, 93,
+  69, 74, 82, 70, 62, 65, 88, 90, 82, 83,
+  88, 70, 88, 82, 82, 75, 84, 71, 131, 70,
+  76, 94, 88, 75, 93, 67, 62, 82, 59, 79,
+  88, 79, 65, 74, 93, 90, 82, 98, 63, 97,
+  70, 63, 91, 75, 84, 82, 72, 81, 86, 92,
+  69, 86, 91, 94, 71, 80, 118, 75, 89, 78,
+  93, 79, 77, 75, 90, 86, 99, 94, 110, 78,
+  79, 65, 75, 94, 79, 82, 61, 74, 127, 80,
+  82, 78, 78, 83, 79, 92, 74, 90, 78, 77,
+  84, 83, 87, 69, 91, 66, 87, 84, 89, 67,
+  79, 84, 85, 85, 86, 80, 89, 87, 90, 80,
+  57, 76, 77, 79, 85, 98, 84, 76, 79, 71,
+  88, 88, 91, 88, 72, 93, 88, 85, 91, 91,
+  77, 73, 90, 95, 83, 80, 93, 72, 93, 84,
+  75, 85, 77, 85, 75, 95, 113, 86, 85, 85,
+  79, 90, 86, 78, 72, 108, 79, 74, 93, 75,
+  88, 81, 96, 95, 85, 78, 81, 75, 95, 78,
+  87, 90, 93, 74, 100, 88, 81, 71, 101, 97,
+  98, 81, 83, 93, 85, 82, 79, 87, 96, 93,
+  86, 79, 81, 93, 91, 81, 100, 88, 94, 82,
+  85, 71, 80, 68, 90, 90, 52, 79, 91, 87,
+  86, 83, 89, 87, 77, 92, 79, 93, 74, 103,
+  100, 81, 89, 82, 84, 67, 82, 87, 80, 88,
+  104, 110, 62, 74, 73, 64, 81, 94, 100, 75,
+  88, 94, 78, 75, 85, 93, 95, 95, 84, 88,
+  73, 71, 91, 99, 89, 83, 83, 89, 97, 78,
+  91, 84, 80, 108, 67, 80, 81, 91, 96, 86,
+  91, 73, 82, 78, 76, 64, 80, 83, 92, 70,
+  77, 87, 78, 66, 79, 77, 82, 81, 74, 84,
+  75, 81, 89, 70, 78, 107, 73, 87, 87, 90,
+  105, 94, 80, 94, 80, 87, 79, 81, 87, 73,
+  91, 86, 67, 84, 91, 86, 105, 77, 84, 75,
+  90, 81, 88, 92, 88, 84, 82, 81, 69, 91,
+  76, 96, 84, 71, 97, 80, 75, 75, 80, 80,
+  71, 75, 89, 76, 83, 87, 71, 68, 63, 83,
+  74, 106, 79, 97, 90, 87, 74, 73, 53, 80,
+  65, 83, 76, 74, 83, 76, 99, 79, 79, 89,
+  64, 93, 77, 77, 103, 92, 78, 86, 68, 82,
+  53, 102, 82, 91, 74, 73, 85, 73, 61, 72,
+  84, 100, 77, 89, 92, 65, 95, 80, 89, 73,
+  83, 75, 125, 77, 72, 93, 93, 71, 97, 64,
+  66, 78, 72, 81, 89, 72, 92, 78, 99, 93,
+  83, 99, 69, 94, 77, 66, 97, 87, 85, 81,
+  80, 82, 97, 85, 71, 86, 86, 97, 77, 81,
+  117, 81, 90, 84, 103, 78, 82, 78, 87, 87,
+  95, 80, 108, 79, 83, 69, 72, 88, 79, 78,
+  73, 76, 110, 84, 89, 85, 83, 83, 78, 93,
+  76, 94, 84, 80, 86, 81, 82, 73, 94, 87,
+  94, 84, 81, 71, 72, 78, 76, 84, 94, 81,
+  79, 90, 83, 77, 90, 80, 81, 81, 86, 98,
+  81, 73, 59, 91, 81, 87, 90, 83, 70, 83,
+  85, 80, 86, 87, 73, 83, 85, 97, 85, 87,
+  90, 80, 97, 78, 80, 91, 73, 83, 78, 82,
+  105, 90, 80, 73, 77, 87, 84, 74, 71, 104,
+  77, 76, 81, 83, 86, 84, 95, 97, 89, 89,
+  85, 78, 93, 77, 94, 93, 84, 86, 98, 81,
+  93, 74, 91, 77, 89, 82, 91, 89, 86, 89,
+  85, 92, 94, 83, 91, 80, 81, 95, 80, 70,
+  103, 88, 98, 78, 98, 69, 78, 71, 91, 99,
+  74, 82, 93, 93, 85, 81, 77, 91, 70, 97,
+  79, 88, 85, 88, 104, 85, 79, 83, 80, 84,
+  90, 82, 79, 87, 73, 87, 82, 82, 81, 83,
+  83, 95, 77, 77, 89, 81, 95, 78, 76, 79,
+  86, 85, 86, 85, 76, 80, 76, 93, 99, 92,
+  87, 78, 92, 78, 87, 78, 77, 72, 92, 82,
+  78, 81, 85, 78, 94, 92, 91, 79, 83, 78,
+  79, 84, 86, 80, 78, 80, 86, 81, 86, 84,
+  83, 85, 82, 84, 74, 67, 83, 78, 84, 75,
+  83, 83, 75, 88, 76, 79, 90, 79, 88, 82,
+  84, 86, 80, 77, 69, 81, 90, 81, 75, 88,
+  71, 80, 84, 85, 83, 83, 83, 83, 79, 87,
+  79, 86, 92, 79, 88, 85, 88, 79, 85, 86,
+  83, 78, 90, 87, 80, 86, 87, 92, 86, 76,
+  74, 93, 91, 82, 78, 87, 97, 77, 99, 80,
+  79, 78, 78, 78, 85, 88, 83, 76, 89, 86,
+  98, 80, 87, 90, 75, 88, 79, 78, 80, 81,
+  71, 65, 84, 77, 79, 84, 78, 85, 78, 114,
+  82, 81, 86, 82, 82, 92, 85, 80, 69, 93,
+  82, 92, 106, 89, 91, 85, 87, 74, 88, 89,
+  75, 86, 67, 83, 86, 83, 90, 79, 88, 72,
+  88, 83, 88, 92, 84, 92, 75, 82, 71, 91,
+  82, 93, 82, 83, 81, 71, 85, 73, 86, 83,
+  89, 76, 82, 81, 72, 85, 74, 91, 76, 82,
+  76, 79, 75, 80, 84, 77, 89, 87, 80, 85,
+  99, 82, 81, 88, 78, 66, 89, 79, 76, 79,
+  78, 80, 90, 80, 102, 93, 77, 80, 84, 84,
+  77, 83, 81, 86, 80, 81, 86, 80, 77, 85,
+  72, 79, 81, 86, 83, 83, 81, 80, 85, 79,
+  78, 79, 81, 77, 75, 79, 87, 76, 81, 81,
+  75, 93, 82, 80, 91, 86, 84, 81, 85, 77,
+  78, 74, 76, 71, 83, 70, 76, 82, 83, 73,
+  91, 90, 90, 93, 85, 79, 80, 87, 85, 84,
+  74, 81, 86, 81, 83, 84, 83, 87, 88, 83,
+  66, 70, 84, 79, 82, 86, 88, 77, 74, 88,
+  79, 85, 87, 79, 81, 86, 83, 88, 87, 78,
+  69, 76, 93, 77, 77, 89, 95, 76, 85, 82,
+  80, 80, 86, 82, 82, 86, 86, 82, 83, 82,
+  90, 90, 81, 80, 72, 83, 80, 76, 69, 87,
+  81, 87, 82, 92, 83, 78, 77, 95, 93, 83,
+  86, 75, 89, 82, 97, 77, 77, 83, 74, 82,
+  82, 84, 84, 88, 92, 83, 77, 69, 89, 83,
+  90, 95, 84, 79, 102, 78, 76, 75, 80, 73,
+  72, 87, 84, 84, 80, 100, 79, 77, 96, 83,
+  79, 74, 80, 80, 79, 81, 82, 92, 99, 93,
+  106, 78, 85, 83, 85, 75, 86, 74, 87, 77,
+  96, 85, 88, 75, 81, 93, 80, 86, 88, 81,
+  78, 80, 79, 71, 94, 81, 86, 77, 83, 73,
+  84, 75, 83, 77, 106, 82, 80, 90, 81, 86,
+  80, 88, 80, 92, 75, 84, 83, 82, 80, 85,
+  85, 88, 80, 86, 75, 80, 89, 81, 84, 76,
+  94, 61, 80, 81, 73, 93, 84, 80, 76, 87,
+  86, 77, 81, 79, 72, 87, 82, 82, 85, 82,
+  113, 88, 111, 78, 84, 80, 77, 76, 84, 93,
+  90, 90, 120, 80, 105, 76, 81, 93, 78, 101,
+  98, 82, 212, 84, 68, 70, 107, 83, 70, 78,
+  77, 85, 71, 141, 79, 75, 96, 89, 87, 106,
+  77, 79, 81, 102, 80, 101, 109, 96, 120, 78,
+  95, 92, 98, 86, 80, 82, 84, 72, 87, 94,
+  95, 75, 87, 79, 87, 101, 115, 99, 80, 113,
+  82, 79, 97, 83, 95, 83, 92, 74, 87, 73,
+  80, 76, 120, 84, 96, 83, 105, 87, 84, 95,
+  90, 96, 82, 86, 80, 69, 76, 85, 87, 93,
+  96, 91, 80, 85, 95, 87, 80, 81, 85, 55,
+  89, 77, 68, 98, 77, 88, 83, 81, 88, 77,
+  83, 96, 73, 74, 70, 78, 86, 83, 87, 77,
+  93, 75, 76, 76, 70, 73, 83, 85, 82, 87,
+  94, 68, 91, 72, 70, 79, 81, 90, 83, 78,
+  109, 77, 73, 74, 81, 81, 76, 69, 79, 81,
+  79, 101, 77, 76, 83, 79, 75, 73, 71, 66,
+  80, 83, 81, 88, 96, 91, 105, 79, 88, 90,
+  85, 74, 84, 76, 84, 71, 92, 86, 87, 74,
+  77, 96, 85, 89, 85, 82, 78, 88, 78, 75,
+  95, 76, 89, 77, 80, 77, 82, 81, 72, 84,
+  106, 84, 84, 82, 84, 80, 80, 83, 82, 90,
+  89, 80, 88, 62, 75, 82, 83, 87, 81, 85,
+  81, 77, 80, 81, 84, 81, 88, 64, 74, 79,
+  68, 94, 70, 84, 80, 86, 82, 77, 80, 82,
+  89, 93, 86, 83, 81, 76, 79, 78, 77, 79,
+  82, 83, 82, 80, 82, 81, 87, 86, 75, 95,
+  74, 79, 87, 78, 84, 80, 73, 82, 83, 81,
+  80, 78, 75, 79, 75, 99, 85, 82, 89, 78,
+  78, 78, 97, 76, 88, 67, 79, 93, 79, 83,
+  76, 77, 79, 86, 81, 86, 78, 74, 75, 82,
+  83, 76, 77, 77, 93, 75, 82, 91, 82, 87,
+  90, 88, 86, 73, 90, 81, 81, 73, 85, 84,
+  75, 80, 70, 73, 86, 88, 85, 82, 81, 77,
+  79, 83, 70, 87, 87, 88, 77, 86, 74, 70,
+  81, 96, 85, 88, 89, 87, 84, 82, 79, 75,
+  87, 78, 86, 84, 74, 85, 81, 84, 78, 86,
+  78, 84, 73, 89, 85, 80, 87, 82, 77, 80,
+  87, 81, 79, 83, 93, 70, 94, 78, 83, 76,
+  78, 75, 86, 88, 87, 81, 91, 84, 95, 88,
+  83, 84, 69, 83, 77, 81, 105, 77, 61, 66,
+  88, 80, 69, 85, 78, 79, 78, 113, 72, 77,
+  82, 86, 79, 83, 77, 86, 71, 93, 69, 93,
+  86, 85, 90, 79, 84, 81, 79, 86, 75, 81,
+  68, 77, 90, 77, 84, 79, 85, 86, 95, 95,
+  95, 88, 82, 98, 75, 82, 77, 87, 79, 82,
+  81, 77, 79, 85, 82, 77, 93, 80, 82, 73,
+  82, 83, 76, 91, 81, 89, 72, 82, 83, 83,
+  73, 84, 83, 83, 91, 86, 73, 78, 91, 79,
+  78, 82, 73, 70, 83, 80, 73, 85, 69, 80,
+  76, 80, 96, 71, 79, 87, 84, 77, 81, 83,
+  83, 82, 81, 73, 76, 76, 78, 78, 72, 84,
+  83, 84, 81, 90, 78, 81, 92, 79, 72, 74,
+  76, 76, 74, 80, 105, 78, 77, 77, 78, 87,
+  78, 79, 79, 80, 77, 86, 74, 74, 76, 74,
+  82, 67, 73, 70, 79, 80, 75, 75, 79, 86,
+  79, 74, 80, 83, 69, 83, 82, 80, 76, 76,
+  91, 76, 88, 88, 77, 97, 83, 90, 76, 77,
+  81, 83, 80, 85, 79, 77, 76, 78, 72, 89,
+  83, 93, 79, 87, 85, 78, 82, 74, 70, 82,
+  89, 85, 82, 87, 82, 71, 84, 80, 82, 85,
+  92, 87, 83, 82, 80, 72, 83, 80, 87, 84,
+  79, 88, 83, 82, 74, 89, 64, 86, 71, 87,
+  81, 80, 85, 84, 85, 82, 62, 81, 91, 80,
+  85, 83, 72, 85, 90, 70, 71, 97, 78, 73,
+  89, 89, 84, 80, 88, 81, 82, 82, 80, 79,
+  81, 83, 99, 94, 98, 88, 76, 74, 84, 91,
+  95, 77, 92, 69, 98, 119, 78, 80, 100, 75,
+  72, 91, 109, 87, 99, 91, 85, 95, 66, 104,
+  84, 87, 88, 74, 89, 89, 115, 100, 87, 80,
+  77, 78, 78, 72, 75, 86, 79, 80, 84, 85,
+  93, 71, 91, 87, 95, 82, 102, 89, 84, 58,
+  85, 84, 95, 77, 69, 77, 76, 74, 66, 74,
+  87, 71, 83, 102, 74, 79, 74, 91, 80, 74,
+  79, 79, 102, 74, 90, 101, 77, 79, 92, 92,
+  88, 87, 73, 86, 113, 81, 79, 82, 66, 86,
+  77, 82, 97, 84, 69, 81, 89, 73, 86, 82,
+  69, 90, 92, 72, 79, 105, 83, 75, 96, 85,
+  84, 77, 73, 81, 74, 84, 87, 86, 82, 82,
+  97, 84, 93, 100, 76, 74, 86, 74, 100, 70,
+  102, 70, 97, 131, 91, 83, 104, 72, 68, 85,
+  111, 84, 99, 100, 88, 99, 74, 96, 86, 86,
+  79, 77, 89, 82, 117, 110, 82, 90, 76, 77,
+  74, 71, 84, 93, 67, 75, 83, 84, 96, 80,
+  89, 99, 96, 84, 106, 78, 88, 59, 73, 84,
+  100, 82, 69, 73, 72, 79, 66, 70, 90, 84,
+  74, 106, 70, 75, 82, 93, 83, 71, 84, 79,
+  114, 81, 99, 95, 79, 76, 98, 90, 75, 87,
+  73, 78, 98, 73, 88, 88, 76, 74, 78, 82,
+  82, 78, 76, 83, 92, 76, 78, 75, 76, 83,
+  92, 77, 68, 88, 75, 81, 86, 85, 85, 85,
+  82, 83, 82, 80, 85, 88, 81, 78, 93, 77,
+  87, 97, 81, 73, 87, 82, 89, 79, 81, 72,
+  99, 105, 97, 79, 96, 84, 79, 93, 96, 88,
+  90, 89, 77, 98, 70, 72, 85, 83, 95, 77,
+  87, 97, 107, 94, 94, 78, 74, 83, 81, 75,
+  85, 86, 92, 76, 89, 90, 94, 97, 97, 82,
+  90, 82, 100, 85, 91, 70, 81, 86, 87, 87,
+  67, 85, 80, 82, 77, 75, 81, 74, 84, 101,
+  77, 75, 74, 89, 79, 78, 82, 80, 93, 78,
+  88, 96, 81, 91, 96, 95, 74, 89, 82, 90,
+  93, 83, 77, 84, 74, 82, 79, 81, 112, 85,
+  79, 88, 85, 77, 82, 86, 74, 82, 88, 73,
+  79, 111, 88, 74, 94, 77, 88, 76, 67, 88,
+  77, 86, 89, 79, 87, 88, 89, 72, 86, 98,
+  78, 90, 88, 76, 76, 89, 70, 81, 87, 108,
+  71, 84, 77, 78, 82, 90, 98, 89, 98, 97,
+  76, 75, 70, 70, 78, 90, 82, 78, 91, 81,
+  110, 96, 82, 79, 84, 68, 109, 75, 65, 85,
+  79, 75, 90, 83, 91, 74, 83, 79, 89, 92,
+  94, 78, 83, 87, 78, 86, 96, 68, 75, 73,
+  69, 79, 75, 67, 83, 81, 80, 80, 82, 80,
+  75, 84, 84, 102, 93, 79, 84, 83, 87, 91,
+  77, 69, 86, 98, 89, 85, 72, 73, 89, 79,
+  81, 88, 81, 77, 68, 84, 100, 85, 77, 91,
+  73, 74, 82, 87, 75, 85, 84, 78, 75, 88,
+  90, 75, 100, 78, 91, 74, 74, 76, 70, 85,
+  91, 76, 92, 89, 87, 72, 66, 97, 80, 87,
+  81, 72, 78, 92, 94, 75, 89, 89, 58, 87,
+  70, 81, 83, 85, 98, 89, 95, 84, 80, 72,
+  71, 91, 76, 87, 71, 89, 103, 81, 104, 89,
+  77, 76, 90, 78, 128, 79, 75, 82, 73, 78,
+  92, 82, 91, 71, 74, 71, 90, 87, 91, 85,
+  77, 91, 70, 81, 82, 66, 73, 75, 68, 76,
+  74, 61, 80, 90, 80, 74, 85, 87, 79, 88,
+  78, 106, 101, 78, 72, 83, 66, 91, 77, 72,
+  70, 93, 85, 83, 71, 64, 80, 73, 78, 92,
+  81, 70, 69, 76, 98, 91, 73, 89, 87, 85,
+  81, 81, 76, 84, 93, 79, 86, 78, 76, 78,
+  90, 75, 88, 80, 78, 85, 80, 84, 86, 84,
+  82, 89, 90, 77, 77, 109, 78, 81, 90, 82,
+  79, 89, 103, 81, 89, 105, 80, 81, 95, 78,
+  75, 84, 96, 88, 97, 83, 78, 83, 77, 107,
+  77, 89, 83, 78, 90, 85, 103, 107, 86, 85,
+  79, 75, 95, 81, 93, 85, 77, 73, 81, 83,
+  96, 90, 88, 88, 88, 89, 101, 83, 91, 88,
+  75, 84, 87, 73, 72, 68, 69, 83, 74, 69,
+  88, 84, 79, 92, 83, 85, 78, 86, 85, 98,
+  86, 84, 89, 87, 72, 88, 84, 81, 71, 93,
+  75, 84, 79, 76, 82, 82, 83, 87, 86, 77,
+  77, 87, 84, 93, 89, 85, 88, 96, 73, 68,
+  83, 89, 73, 83, 79, 87, 89, 74, 89, 85,
+  83, 81, 80, 80, 81, 89, 95, 91, 84, 92,
+  89, 84, 85, 87, 83, 83, 89, 89, 71, 86,
+  84, 91, 82, 92, 90, 95, 81, 95, 78, 89,
+  74, 91, 86, 83, 78, 71, 84, 79, 90, 73,
+  94, 78, 85, 92, 87, 81, 84, 75, 86, 84,
+  86, 90, 78, 64, 85, 70, 87, 98, 85, 92,
+  80, 82, 84, 93, 75, 88, 89, 87, 87, 94,
+  79, 94, 88, 76, 92, 85, 89, 89, 77, 80,
+  84, 77, 87, 80, 76, 81, 95, 69, 92, 82,
+  72, 84, 80, 85, 83, 75, 68, 89, 108, 88,
+  91, 82, 91, 94, 88, 77, 94, 80, 78, 71,
+  70, 97, 81, 82, 74, 98, 83, 70, 80, 90,
+  66, 85, 72, 84, 87, 77, 80, 92, 85, 85,
+  96, 82, 95, 85, 86, 92, 84, 92, 87, 82,
+  79, 74, 82, 85, 94, 89, 80, 80, 74, 82,
+  97, 87, 81, 95, 76, 105, 74, 92, 73, 98,
+  77, 80, 77, 64, 86, 78, 96, 65, 110, 83,
+  83, 100, 86, 69, 95, 70, 83, 95, 86, 93,
+  83, 68, 89, 71, 92, 107, 84, 86, 87, 72,
+  82, 90, 68, 88, 84, 79, 88, 88, 70, 97,
+  88, 83, 104, 84, 90, 94, 72, 74, 97, 69,
+  97, 77, 74, 82, 96, 71, 97, 79, 60, 83,
+  72, 89, 83, 91, 72, 92, 95, 86, 92, 89,
+  89, 93, 85, 80, 96, 77, 79, 69, 90, 99,
+  77, 87, 88, 86, 78, 71, 87, 93, 80, 84,
+  94, 91, 77, 77, 88, 79, 85, 84, 84, 86,
+  99, 87, 79, 87, 86, 96, 86, 77, 80, 92,
+  77, 80, 93, 90, 73, 84, 87, 92, 82, 101,
+  77, 89, 88, 88, 68, 91, 83, 96, 85, 84,
+  78, 80, 80, 84, 78, 73, 88, 76, 92, 89,
+  85, 89, 86, 74, 82, 78, 96, 92, 90, 74,
+  80, 70, 85, 97, 91, 87, 91, 91, 86, 92,
+  84, 84, 95, 87, 86, 88, 81, 86, 81, 78,
+  85, 88, 84, 85, 87, 84, 88, 87, 85, 81,
+  76, 82, 95, 76, 87, 81, 75, 82, 74, 93,
+  84, 89, 72, 84, 84, 89, 91, 84, 88, 85,
+  80, 80, 95, 76, 80, 78, 85, 83, 89, 87,
+  93, 88, 90, 77, 95, 84, 75, 85, 91, 81,
+  94, 82, 86, 83, 73, 79, 85, 81, 69, 72,
+  92, 88, 85, 78, 80, 87, 82, 77, 86, 84,
+  77, 81, 91, 85, 81, 89, 102, 88, 91, 101,
+  84, 88, 75, 91, 84, 79, 90, 94, 85, 92,
+  77, 93, 90, 86, 81, 84, 82, 80, 77, 76,
+  107, 94, 69, 85, 83, 79, 68, 75, 77, 68,
+  91, 82, 91, 74, 82, 92, 78, 92, 77, 78,
+  104, 81, 88, 80, 85, 85, 60, 69, 77, 97,
+  84, 91, 88, 99, 100, 88, 87, 74, 86, 86,
+  86, 81, 84, 95, 87, 74, 80, 78, 86, 79,
+  100, 68, 93, 84, 82, 86, 73, 87, 85, 87,
+  81, 77, 84, 75, 81, 90, 83, 85, 87, 68,
+  93, 80, 88, 82, 81, 78, 93, 86, 87, 77,
+  81, 89, 83, 81, 93, 76, 64, 76, 90, 93,
+  88, 81, 73, 93, 80, 75, 102, 78, 75, 62,
+  78, 71, 78, 94, 91, 66, 87, 94, 74, 82,
+  70, 70, 87, 103, 80, 102, 88, 82, 86, 86,
+  83, 91, 79, 75, 83, 68, 85, 80, 89, 101,
+  94, 88, 73, 90, 40, 61, 83, 80, 79, 82,
+  83, 53, 81, 83, 78, 93, 82, 74, 93, 87,
+  82, 74, 93, 85, 70, 70, 73, 96, 72, 88,
+  83, 92, 89, 91, 74, 71, 80, 78, 85, 85,
+  89, 96, 84, 85, 84, 81, 85, 77, 103, 77,
+  77, 79, 76, 90, 84, 92, 99, 95, 92, 81,
+  81, 88, 79, 90, 84, 80, 90, 62, 90, 84,
+  85, 80, 77, 81, 92, 81, 82, 77, 79, 89,
+  82, 84, 92, 76, 74, 72, 91, 91, 85, 82,
+  83, 84, 79, 78, 93, 77, 93, 76, 76, 75,
+  79, 93, 90, 64, 95, 97, 74, 86, 65, 60,
+  80, 96, 83, 91, 83, 86, 84, 95, 86, 87,
+  85, 76, 88, 72, 86, 82, 91, 101, 92, 92,
+  73, 77, 73, 61, 86, 73, 82, 68, 79, 77,
+  79, 84, 80, 87, 83, 75, 90, 85, 78, 69,
+  85, 87, 74, 77, 68, 95, 79, 85, 79, 92,
+  83, 89, 73, 80, 76, 76, 89, 86, 98, 91,
+  85, 84, 81, 81, 85, 86, 88, 76, 60, 76,
+  75, 92, 77, 93, 88, 92, 92, 76, 85, 87,
+  80, 78, 89, 80, 85, 80, 97, 92, 86, 81,
+  82, 70, 81, 83, 81, 92, 80, 89, 83, 79,
+  83, 77, 89, 72, 86, 103, 85, 76, 80, 92,
+  85, 79, 86, 71, 65, 79, 85, 78, 78, 102,
+  93, 80, 75, 98, 88, 87, 80, 84, 84, 88,
+  90, 94, 86, 83, 86, 71, 92, 86, 82, 84,
+  79, 67, 79, 51, 74, 94, 82, 69, 85, 73,
+  72, 76, 91, 70, 86, 86, 80, 79, 66, 96,
+  87, 97, 78, 91, 89, 80, 76, 71, 95, 83,
+  81, 70, 72, 87, 75, 85, 80, 86, 90, 80,
+  66, 45, 78, 83, 79, 62, 89, 95, 90, 94,
+  99, 74, 90, 76, 79, 71, 101, 76, 82, 89,
+  79, 87, 87, 93, 89, 79, 85, 95, 94, 73,
+  68, 74, 71, 60, 72, 83, 78, 88, 81, 62,
+  77, 83, 68, 79, 78, 77, 83, 70, 86, 94,
+  94, 100, 87, 81, 92, 82, 74, 87, 83, 82,
+  100, 68, 75, 72, 75, 72, 91, 70, 77, 67,
+  65, 77, 74, 87, 83, 72, 88, 104, 76, 83,
+  83, 75, 93, 49, 73, 84, 86, 81, 112, 82,
+  94, 104, 41, 92, 154, 87, 83, 129, 34, 76,
+  100, 95, 67, 80, 96, 95, 68, 68, 83, 81,
+  81, 92, 76, 89, 71, 113, 73, 76, 80, 90,
+  83, 78, 71, 65, 81, 73, 69, 78, 64, 85,
+  91, 82, 83, 81, 89, 92, 83, 109, 84, 96,
+  79, 70, 66, 118, 108, 77, 97, 91, 95, 101,
+  85, 80, 84, 94, 83, 118, 93, 92, 61, 77,
+  80, 67, 69, 94, 82, 85, 79, 68, 68, 64,
+  64, 88, 80, 71, 79, 76, 80, 85, 65, 87,
+  81, 77, 90, 86, 75, 78, 75, 85, 90, 81,
+  73, 76, 93, 73, 86, 75, 76, 60, 85, 78,
+  72, 101, 84, 102, 83, 87, 86, 79, 86, 81,
+  96, 77, 80, 86, 94, 73, 113, 90, 103, 109,
+  63, 88, 110, 97, 88, 103, 84, 65, 102, 96,
+  77, 77, 82, 79, 93, 57, 86, 78, 80, 72,
+  73, 76, 72, 102, 83, 75, 84, 120, 80, 76,
+  94, 59, 81, 73, 77, 77, 74, 140, 87, 84,
+  85, 78, 85, 92, 82, 96, 71, 110, 78, 74,
+  57, 96, 60, 71, 91, 85, 75, 83, 85, 79,
+  84, 87, 77, 102, 85, 81, 86, 83, 76, 82,
+  80, 91, 88, 80, 76, 77, 73, 85, 70, 93,
+  81, 87, 78, 96, 74, 85, 98, 63, 85, 91,
+  82, 85, 87, 80, 81, 85, 86, 74, 82, 95,
+  101, 90, 85, 89, 89, 78, 73, 93, 89, 77,
+  84, 78, 83, 73, 86, 96, 78, 85, 80, 86,
+  96, 86, 83, 82, 86, 81, 88, 50, 78, 86,
+  78, 70, 79, 87, 75, 69, 88, 73, 91, 82,
+  82, 90, 66, 96, 82, 83, 67, 97, 77, 77,
+  82, 84, 94, 89, 87, 93, 69, 76, 94, 80,
+  81, 81, 82, 81, 77, 60, 83, 83, 80, 65,
+  80, 90, 87, 85, 83, 82, 96, 78, 73, 83,
+  89, 70, 74, 86, 74, 81, 93, 89, 85, 81,
+  87, 92, 103, 69, 92, 86, 70, 93, 69, 71,
+  86, 85, 76, 79, 84, 96, 69, 81, 74, 70,
+  75, 91, 90, 85, 99, 85, 101, 77, 75, 85,
+  89, 88, 95, 86, 84, 94, 103, 108, 86, 85,
+  100, 62, 76, 71, 79, 74, 84, 93, 84, 94,
+  82, 67, 92, 93, 76, 81, 74, 76, 58, 77,
+  81, 93, 102, 88, 87, 93, 79, 73, 89, 87,
+  92, 80, 90, 107, 79, 85, 80, 83, 90, 118,
+  72, 78, 79, 71, 75, 112, 83, 88, 89, 107,
+  82, 87, 89, 76, 89, 77, 91, 72, 77, 71,
+  72, 87, 85, 77, 86, 85, 92, 74, 83, 95,
+  81, 79, 79, 94, 76, 87, 69, 103, 88, 91,
+  85, 91, 91, 73, 74, 73, 88, 97, 84, 81,
+  103, 80, 65, 82, 82, 91, 73, 74, 84, 81,
+  76, 84, 79, 84, 68, 82, 74, 64, 81, 89,
+  95, 76, 79, 75, 88, 83, 80, 88, 94, 83,
+  94, 84, 85, 99, 72, 106, 88, 82, 98, 64,
+  71, 63, 89, 73, 77, 101, 82, 111, 83, 55,
+  91, 81, 80, 80, 79, 97, 55, 79, 85, 87,
+  105, 97, 93, 88, 81, 72, 74, 91, 102, 79,
+  112, 107, 80, 90, 86, 90, 82, 97, 94, 69,
+  81, 78, 79, 86, 87, 87, 90, 108, 81, 85,
+  93, 98, 86, 92, 100, 73, 76, 76, 92, 84,
+  82, 102, 88, 90, 99, 69, 85, 94, 82, 74,
+  72, 102, 77, 88, 69, 98, 86, 94, 81, 94,
+  89, 65, 77, 72, 90, 96, 85, 83, 81, 94,
+  88, 81, 92, 83, 75, 78, 83, 78, 88, 88,
+  96, 78, 80, 81, 88, 85, 90, 83, 80, 79,
+  86, 82, 91, 76, 76, 80, 81, 87, 99, 83,
+  83, 81, 102, 82, 87, 68, 94, 88, 76, 93,
+  82, 88, 77, 79, 90, 82, 82, 87, 86, 90,
+  85, 85, 87, 83, 83, 75, 92, 84, 91, 94,
+  92, 82, 91, 96, 87, 70, 96, 86, 83, 87,
+  81, 78, 80, 78, 92, 89, 81, 95, 84, 92,
+  84, 91, 67, 82, 88, 93, 88, 71, 81, 82,
+  81, 84, 83, 70, 97, 86, 72, 89, 78, 87,
+  85, 89, 83, 84, 85, 90, 83, 86, 85, 85,
+  85, 70, 78, 73, 80, 83, 81, 85, 90, 99,
+  68, 73, 101, 93, 88, 93, 79, 96, 84, 74,
+  106, 79, 77, 68, 81, 75, 93, 83, 93, 79,
+  86, 80, 90, 75, 83, 78, 86, 82, 80, 84,
+  84, 79, 75, 82, 99, 92, 105, 79, 85, 86,
+  102, 82, 80, 58, 92, 94, 75, 83, 84, 77,
+  92, 88, 95, 87, 88, 87, 80, 85, 81, 88,
+  79, 79, 81, 67, 93, 91, 98, 110, 84, 94,
+  69, 98, 89, 70, 109, 71, 76, 85, 81, 82,
+  86, 82, 89, 94, 76, 89, 81, 77, 88, 82,
+  72, 90, 75, 92, 74, 79, 70, 78, 87, 88,
+  70, 74, 83, 87, 80, 88, 73, 84, 82, 92,
+  78, 82, 84, 90, 85, 85, 88, 88, 83, 73,
+  72, 71, 77, 88, 80, 82, 90, 98, 64, 75,
+  90, 90, 89, 94, 81, 90, 82, 81, 101, 95,
+  76, 71, 84, 78, 92, 84, 95, 85, 79, 86,
+  93, 85, 91, 78, 91, 74, 85, 82, 72, 71,
+  77, 87, 84, 93, 99, 78, 82, 87, 91, 91,
+  83, 61, 77, 90, 77, 82, 80, 81, 79, 82,
+  86, 87, 88, 87, 84, 86, 80, 85, 87, 90,
+  81, 72, 81, 88, 94, 93, 83, 94, 94, 88,
+  79, 73, 106, 76, 80, 79, 79, 85, 85, 79,
+  88, 98, 82, 82, 87, 85, 83, 75, 73, 90,
+  70, 82, 80, 78, 75, 91, 85, 84, 80, 71,
+  91, 88, 97, 79, 74, 87, 78, 91, 82, 84,
+  79, 94, 87, 88, 86, 90, 86, 92, 76, 72,
+  73, 78, 80, 79, 84, 98, 73, 73, 86, 91,
+  90, 93, 89, 98, 92, 89, 83, 83, 81, 80,
+  80, 83, 84, 94, 92, 86, 75, 83, 90, 81,
+  87, 83, 82, 73, 78, 86, 93, 79, 84, 86,
+  85, 84, 91, 80, 81, 87, 92, 76, 96, 88,
+  91, 79, 88, 84, 79, 81, 75, 83, 84, 89,
+  81, 85, 81, 84, 82, 82, 81, 89, 72, 81,
+  81, 87, 95, 81, 79, 84, 99, 85, 97, 74,
+  101, 85, 80, 83, 74, 89, 83, 74, 85, 85,
+  76, 94, 86, 100, 81, 93, 77, 93, 82, 91,
+  96, 69, 72, 89, 78, 94, 85, 73, 90, 85,
+  68, 90, 69, 93, 89, 97, 82, 92, 81, 83,
+  77, 81, 88, 77, 82, 73, 78, 77, 69, 98,
+  86, 75, 80, 84, 77, 71, 85, 89, 92, 86,
+  86, 91, 102, 94, 88, 76, 78, 73, 76, 84,
+  86, 90, 80, 80, 85, 95, 87, 72, 84, 84,
+  82, 74, 74, 88, 94, 79, 86, 86, 105, 86,
+  82, 69, 77, 93, 86, 78, 86, 93, 90, 76,
+  87, 63, 75, 71, 80, 91, 90, 82, 96, 82,
+  74, 74, 80, 85, 72, 79, 69, 73, 74, 91,
+  98, 100, 68, 94, 83, 73, 102, 84, 126, 72,
+  74, 73, 73, 98, 91, 79, 79, 88, 71, 71,
+  86, 89, 95, 90, 86, 101, 70, 90, 77, 72,
+  63, 88, 82, 88, 71, 66, 73, 86, 76, 80,
+  61, 78, 92, 99, 80, 96, 83, 82, 76, 79,
+  89, 83, 81, 70, 71, 72, 76, 103, 75, 73,
+  78, 72, 77, 73, 67, 90, 78, 79, 85, 82,
+  86, 96, 85, 84, 78, 70, 83, 90, 87, 86,
+  89, 84, 77, 87, 93, 81, 92, 87, 81, 68,
+  80, 89, 84, 73, 88, 91, 90, 89, 82, 71,
+  77, 90, 80, 95, 83, 101, 84, 81, 92, 73,
+  74, 78, 75, 84, 75, 87, 91, 83, 77, 78,
+  80, 81, 82, 91, 71, 76, 72, 90, 98, 84,
+  69, 94, 104, 72, 93, 85, 121, 91, 77, 73,
+  76, 99, 85, 75, 87, 92, 80, 74, 90, 95,
+  87, 76, 81, 94, 72, 86, 75, 74, 69, 103,
+  85, 89, 79, 70, 83, 85, 96, 76, 62, 77,
+  87, 98, 83, 100, 81, 82, 78, 84, 88, 84,
+  81, 86, 77, 82, 75, 95, 82, 78, 74, 78,
+  84, 71, 69, 94, 87, 81, 80, 97, 99, 86,
+  80, 81, 81, 75, 78, 92, 78, 95, 96, 93,
+  61, 88, 92, 83, 92, 90, 94, 74, 79, 82,
+  96, 74, 92, 94, 80, 84, 82, 87, 83, 93,
+  83, 78, 88, 100, 80, 85, 99, 83, 89, 81,
+  70, 82, 66, 82, 94, 89, 73, 87, 88, 76,
+  90, 74, 78, 78, 84, 75, 104, 83, 80, 80,
+  103, 80, 81, 90, 89, 90, 79, 77, 84, 93,
+  73, 82, 74, 85, 88, 81, 82, 89, 81, 93,
+  83, 88, 85, 90, 74, 85, 82, 80, 86, 85,
+  85, 81, 94, 76, 75, 95, 59, 89, 88, 100,
+  78, 103, 86, 90, 85, 83, 95, 81, 77, 88,
+  75, 84, 80, 93, 80, 83, 77, 77, 85, 69,
+  88, 96, 89, 77, 61, 83, 89, 88, 66, 76,
+  86, 72, 74, 99, 74, 97, 69, 74, 71, 92,
+  87, 89, 86, 105, 99, 75, 87, 72, 90, 70,
+  98, 91, 105, 79, 80, 71, 76, 101, 71, 86,
+  87, 102, 72, 66, 112, 75, 85, 71, 75, 84,
+  67, 73, 117, 78, 69, 68, 87, 73, 84, 68,
+  99, 68, 82, 84, 105, 103, 80, 88, 99, 69,
+  83, 119, 105, 93, 79, 81, 91, 99, 78, 98,
+  77, 80, 86, 60, 78, 84, 87, 86, 84, 91,
+  83, 85, 50, 78, 83, 80, 81, 78, 92, 74,
+  78, 76, 82, 85, 50, 76, 93, 104, 76, 109,
+  95, 83, 77, 84, 83, 88, 85, 80, 77, 86,
+  93, 87, 71, 95, 76, 73, 83, 77, 68, 101,
+  79, 71, 74, 75, 69, 86, 70, 78, 86, 69,
+  80, 96, 80, 89, 84, 78, 63, 89, 93, 91,
+  95, 98, 93, 72, 70, 80, 77, 70, 93, 94,
+  93, 89, 83, 77, 81, 94, 79, 94, 81, 102,
+  78, 71, 107, 74, 84, 81, 83, 82, 63, 85,
+  98, 83, 72, 73, 85, 77, 90, 82, 100, 79,
+  84, 80, 98, 86, 78, 87, 99, 76, 73, 106,
+  107, 96, 94, 74, 90, 98, 72, 95, 74, 80,
+  98, 66, 83, 95, 85, 72, 77, 91, 87, 88,
+  58, 88, 90, 90, 81, 80, 90, 77, 83, 77,
+  92, 86, 55, 75, 82, 101, 77, 96, 96, 83,
+  82, 90, 83, 90, 82, 93, 74, 86, 83, 79,
+  71, 93, 81, 74, 86, 74, 77, 104, 88, 79,
+  87, 75, 100, 99, 82, 90, 79, 81, 79, 95,
+  84, 85, 87, 81, 89, 89, 84, 93, 84, 82,
+  83, 78, 97, 76, 77, 93, 76, 80, 99, 91,
+  89, 77, 88, 69, 91, 104, 81, 103, 87, 89,
+  82, 78, 73, 87, 85, 83, 72, 75, 73, 81,
+  82, 81, 88, 77, 76, 87, 77, 80, 93, 80,
+  91, 75, 83, 84, 105, 78, 84, 75, 79, 105,
+  85, 83, 70, 97, 73, 80, 83, 73, 92, 75,
+  86, 82, 78, 93, 85, 63, 142, 83, 80, 89,
+  81, 92, 83, 89, 88, 79, 83, 91, 87, 77,
+  89, 78, 76, 85, 69, 74, 73, 85, 82, 77,
+  78, 89, 82, 73, 87, 91, 87, 90, 84, 88,
+  82, 86, 77, 86, 83, 166, 76, 80, 92, 76,
+  86, 81, 94, 80, 80, 78, 73, 76, 83, 77,
+  94, 91, 88, 82, 87, 87, 72, 92, 75, 80,
+  80, 69, 80, 95, 68, 70, 101, 92, 103, 87,
+  83, 68, 93, 74, 81, 78, 85, 88, 80, 86,
+  84, 87, 88, 81, 80, 85, 63, 77, 85, 91,
+  84, 73, 77, 82, 77, 79, 98, 72, 82, 81,
+  84, 85, 88, 80, 73, 79, 74, 82, 99, 87,
+  73, 84, 82, 78, 81, 84, 95, 85, 81, 83,
+  75, 85, 89, 57, 92, 76, 89, 83, 83, 84,
+  74, 96, 79, 88, 77, 95, 82, 85, 69, 79,
+  56, 88, 76, 78, 68, 86, 78, 80, 87, 78,
+  73, 104, 83, 92, 80, 105, 80, 87, 78, 81,
+  69, 78, 81, 153, 67, 86, 84, 72, 91, 89,
+  90, 80, 79, 81, 78, 100, 86, 86, 80, 86,
+  94, 86, 87, 87, 89, 94, 78, 82, 83, 80,
+  79, 90, 83, 82, 87, 88, 90, 87, 86, 72,
+  87, 63, 88, 95, 73, 93, 87, 79, 85, 84,
+  77, 82, 81, 89, 73, 80, 82, 81, 92, 78,
+  77, 71, 76, 80, 97, 76, 86, 86, 81, 84,
+  105, 77, 78, 79, 77, 86, 94, 81, 82, 86,
+  81, 81, 81, 95, 100, 76, 85, 84, 69, 83,
+  84, 74, 67, 86, 88, 90, 81, 98, 87, 86,
+  95, 82, 82, 93, 78, 72, 81, 87, 80, 84,
+  72, 81, 79, 78, 77, 80, 88, 89, 82, 142,
+  85, 82, 90, 87, 86, 86, 82, 86, 84, 95,
+  86, 146, 82, 79, 89, 84, 84, 89, 86, 87,
+  81, 74, 72, 72, 90, 81, 84, 90, 83, 80,
+  81, 90, 73, 72, 87, 87, 91, 75, 79, 88,
+  71, 70, 108, 93, 102, 80, 91, 66, 97, 103,
+  78, 89, 86, 86, 82, 78, 74, 91, 85, 81,
+  82, 82, 69, 85, 88, 89, 85, 80, 85, 86,
+  70, 80, 90, 86, 95, 80, 85, 84, 80, 76,
+  78, 86, 80, 83, 83, 82, 67, 89, 81, 73,
+  74, 64, 92, 83, 86, 88, 83, 88, 84, 98,
+  138, 77, 80, 77, 87, 84, 81, 84, 69, 83,
+  83, 95, 91, 80, 79, 85, 64, 89, 73, 84,
+  76, 90, 82, 85, 78, 87, 74, 51, 89, 90,
+  80, 103, 81, 82, 85, 75, 67, 73, 75, 97,
+  63, 92, 89, 84, 74, 75, 97, 80, 85, 72,
+  62, 70, 90, 74, 95, 81, 77, 74, 87, 87,
+  66, 81, 80, 89, 82, 75, 84, 89, 63, 66,
+  123, 92, 121, 98, 85, 71, 99, 68, 87, 88,
+  88, 87, 78, 83, 81, 94, 97, 78, 87, 92,
+  63, 79, 88, 80, 81, 75, 80, 81, 71, 73,
+  86, 87, 99, 83, 75, 93, 60, 80, 78, 101,
+  82, 68, 80, 90, 71, 81, 90, 75, 81, 88,
+  84, 104, 80, 87, 77, 87, 83, 103, 69, 75,
+  79, 72, 87, 78, 57, 96, 64, 96, 77, 111,
+  91, 95, 75, 83, 61, 92, 81, 92, 70, 89,
+  85, 88, 78, 79, 78, 70, 80, 85, 81, 131,
+  83, 78, 77, 77, 48, 79, 69, 63, 68, 106,
+  85, 77, 83, 82, 86, 79, 80, 74, 75, 77,
+  84, 83, 77, 78, 90, 80, 82, 88, 80, 86,
+  79, 85, 85, 76, 81, 88, 79, 71, 94, 79,
+  93, 96, 88, 67, 91, 59, 87, 81, 87, 86,
+  85, 76, 92, 88, 81, 80, 90, 90, 69, 85,
+  85, 84, 88, 74, 88, 87, 72, 78, 90, 81,
+  88, 88, 84, 83, 92, 75, 73, 92, 79, 78,
+  93, 78, 82, 82, 84, 77, 79, 97, 95, 80,
+  85, 89, 74, 85, 87, 109, 64, 85, 81, 83,
+  82, 87, 90, 79, 80, 83, 83, 96, 85, 74,
+  77, 85, 70, 86, 74, 85, 80, 83, 77, 86,
+  85, 88, 75, 127, 83, 84, 95, 96, 81, 81,
+  79, 74, 73, 77, 79, 85, 68, 83, 94, 80,
+  77, 93, 87, 94, 79, 73, 76, 93, 87, 84,
+  79, 88, 87, 82, 79, 92, 87, 74, 84, 84,
+  99, 78, 82, 86, 91, 77, 90, 86, 88, 88,
+  88, 69, 99, 118, 78, 78, 78, 88, 78, 76,
+  79, 91, 80, 84, 79, 86, 81, 82, 90, 82,
+  89, 79, 84, 90, 70, 79, 84, 84, 93, 81,
+  89, 79, 97, 75, 79, 81, 78, 82, 94, 81,
+  79, 81, 83, 83, 73, 64, 92, 79, 86, 85,
+  83, 89, 83, 137, 155, 78, 83, 85, 82, 100,
+  102, 84, 83, 83, 92, 88, 89, 76, 80, 101,
+  84, 85, 100, 85, 85, 98, 76, 92, 70, 92,
+  89, 58, 88, 86, 83, 90, 91, 85, 92, 77,
+  72, 78, 74, 74, 85, 84, 97, 78, 82, 93,
+  86, 89, 79, 69, 72, 79, 83, 81, 89, 84,
+  83, 81, 81, 90, 81, 78, 80, 92, 99, 79,
+  86, 77, 84, 69, 94, 86, 84, 100, 87, 73,
+  91, 82, 84, 70, 78, 86, 75, 79, 79, 96,
+  79, 88, 84, 89, 69, 81, 87, 84, 85, 78,
+  83, 86, 66, 70, 85, 79, 93, 80, 83, 78,
+  85, 75, 83, 84, 78, 76, 85, 80, 79, 73,
+  87, 77, 75, 80, 85, 90, 85, 86, 83, 93,
+  81, 158, 111, 76, 85, 86, 79, 89, 93, 84,
+  77, 86, 93, 90, 88, 80, 78, 87, 65, 83,
+  82, 86, 81, 93, 76, 89, 73, 84, 81, 92,
+  88, 91, 97, 104, 84, 84, 84, 74, 63, 72,
+  73, 52, 72, 86, 91, 82, 82, 84, 87, 90,
+  78, 75, 79, 98, 82, 82, 79, 80, 89, 82,
+  80, 93, 92, 80, 80, 86, 94, 78, 85, 88,
+  95, 81, 76, 82, 84, 99, 88, 74, 88, 69,
+  84, 69, 81, 87, 80, 75, 87, 90, 77, 84,
+  87, 92, 77, 83, 88, 83, 92, 77, 85, 87,
+  68, 77, 85, 82, 89, 84, 89, 78, 98, 74,
+  82, 86, 77, 86, 86, 80, 84, 81, 89, 86,
+  73, 90, 92, 80, 87, 86, 77, 92, 83, 152,
+  84, 87, 89, 89, 79, 94, 105, 84, 86, 82,
+  94, 87, 85, 77, 78, 90, 87, 83, 100, 83,
+  85, 93, 76, 91, 80, 90, 86, 130, 89, 84,
+  107, 89, 94, 84, 83, 78, 76, 78, 81, 66,
+  86, 81, 78, 80, 73, 91, 80, 79, 67, 95,
+  84, 82, 77, 99, 87, 72, 68, 87, 74, 71,
+  84, 91, 87, 70, 77, 88, 79, 68, 101, 84,
+  111, 91, 79, 83, 77, 82, 70, 90, 111, 86,
+  73, 72, 88, 88, 82, 62, 78, 70, 93, 86,
+  83, 64, 141, 72, 85, 88, 83, 70, 94, 91,
+  116, 75, 82, 69, 126, 76, 74, 77, 91, 79,
+  74, 77, 70, 115, 87, 84, 74, 67, 73, 89,
+  101, 94, 86, 92, 73, 81, 77, 80, 85, 85,
+  95, 80, 72, 99, 92, 68, 90, 69, 97, 84,
+  90, 91, 88, 72, 92, 91, 88, 79, 71, 90,
+  91, 77, 74, 75, 71, 85, 115, 102, 74, 80,
+  76, 87, 94, 95, 69, 74, 72, 90, 85, 83,
+  74, 86, 69, 95, 79, 85, 72, 95, 92, 86,
+  74, 100, 84, 66, 76, 95, 79, 77, 83, 90,
+  84, 71, 83, 84, 81, 74, 97, 88, 73, 76,
+  65, 86, 76, 86, 57, 89, 88, 87, 72, 74,
+  78, 80, 86, 68, 83, 69, 93, 77, 77, 64,
+  132, 74, 90, 89, 79, 61, 99, 89, 100, 81,
+  85, 68, 125, 78, 80, 74, 87, 77, 77, 65,
+  72, 105, 88, 86, 78, 71, 71, 86, 94, 93,
+  90, 88, 74, 85, 76, 82, 83, 78, 84, 85,
+  75, 92, 82, 71, 90, 77, 91, 88, 87, 86,
+  86, 66, 94, 90, 85, 66, 75, 86, 93, 79,
+  74, 75, 72, 82, 105, 82, 76, 79, 77, 81,
+  78, 92, 74, 78, 74, 84, 85, 67, 76, 84,
+  74, 93, 80, 78, 64, 90, 89, 85, 77, 103,
+  85, 76, 70, 84, 69, 74, 81, 91, 80, 68,
+  78, 89, 76, 69, 107, 86, 96, 77, 81, 87,
+  77, 84, 71, 91, 118, 85, 73, 71, 88, 87,
+  84, 63, 78, 69, 92, 76, 86, 66, 139, 79,
+  87, 85, 86, 65, 95, 93, 110, 77, 83, 74,
+  123, 75, 79, 74, 90, 76, 78, 84, 67, 111,
+  90, 81, 80, 70, 80, 91, 109, 88, 88, 94,
+  75, 96, 79, 81, 82, 77, 92, 86, 75, 94,
+  89, 70, 89, 68, 96, 87, 91, 88, 85, 73,
+  92, 91, 90, 79, 70, 90, 99, 75, 74, 77,
+  72, 86, 108, 91, 74, 84, 76, 90, 78, 94,
+  73, 73, 72, 91, 83, 83, 82, 79, 73, 87,
+  81, 82, 79, 83, 82, 81, 85, 85, 95, 84,
+  79, 78, 72, 88, 89, 84, 86, 75, 76, 94,
+  82, 89, 85, 84, 95, 82, 81, 81, 89, 77,
+  74, 79, 80, 82, 88, 80, 87, 76, 87, 71,
+  76, 87, 76, 80, 85, 83, 106, 75, 98, 87,
+  89, 86, 88, 78, 92, 77, 86, 71, 102, 79,
+  79, 90, 86, 83, 76, 74, 78, 93, 90, 69,
+  85, 84, 71, 87, 86, 76, 85, 65, 83, 77,
+  79, 82, 83, 84, 68, 88, 83, 78, 80, 87,
+  82, 78, 83, 85, 89, 82, 76, 77, 89, 88,
+  81, 78, 91, 88, 95, 84, 62, 83, 87, 85,
+  81, 91, 87, 84, 79, 80, 87, 87, 84, 84,
+  85, 89, 82, 92, 81, 87, 75, 87, 79, 82,
+  85, 83, 81, 86, 83, 81, 90, 89, 87, 85,
+  80, 89, 90, 82, 85, 79, 77, 87, 78, 95,
+  81, 83, 70, 77, 83, 87, 87, 76, 70, 79,
+  80, 86, 84, 84, 85, 77, 85, 73, 76, 80,
+  76, 80, 84, 83, 99, 82, 99, 86, 90, 83,
+  91, 79, 88, 79, 80, 71, 103, 82, 80, 93,
+  80, 81, 81, 68, 77, 88, 90, 70, 86, 83,
+  72, 74, 84, 77, 84, 68, 85, 84, 82, 81,
+  81, 75, 59, 85, 84, 75, 76, 90, 80, 85,
+  79, 86, 87, 81, 70, 77, 91, 88, 80, 71,
+  86, 83, 93, 80, 70, 85, 90, 79, 78, 81,
+  74, 85, 81, 76, 74, 86, 86, 86, 88, 83,
+  80, 87, 83, 92, 84, 86, 82, 85, 76, 79,
+  85, 83, 85, 87, 93, 89, 79, 80, 72, 88,
+  90, 83, 84, 75, 77, 92, 72, 87, 86, 81,
+  90, 77, 90, 85, 88, 77, 72, 84, 88, 84,
+  80, 79, 85, 81, 82, 73, 74, 82, 76, 83,
+  89, 80, 106, 84, 94, 85, 93, 84, 87, 76,
+  96, 71, 82, 75, 102, 74, 78, 91, 83, 78,
+  83, 76, 77, 90, 87, 68, 86, 82, 78, 76,
+  88, 75, 82, 65, 82, 86, 81, 81, 83, 77,
+  71, 85, 84, 71, 82, 85, 81, 76, 83, 85,
+  89, 83, 73, 92, 87, 90, 81, 82, 91, 85,
+  93, 80, 70, 86, 87, 83, 83, 82, 79, 86,
+  81, 84, 77, 87, 82, 82, 87, 90, 80, 90,
+  83, 82, 76, 90, 87, 85, 82, 74, 78, 82,
+  85, 68, 91, 87, 89, 81, 82, 91, 92, 85,
+  82, 88, 85, 88, 85, 98, 90, 83, 86, 84,
+  85, 82, 100, 84, 85, 79, 80, 79, 84, 88,
+  81, 86, 90, 89, 85, 98, 76, 83, 86, 98,
+  68, 88, 93, 91, 91, 95, 87, 78, 76, 77,
+  88, 77, 85, 75, 82, 90, 88, 87, 84, 82,
+  92, 88, 83, 87, 82, 92, 83, 89, 81, 80,
+  87, 70, 88, 89, 86, 83, 81, 77, 91, 88,
+  73, 82, 80, 96, 84, 85, 80, 84, 86, 84,
+  92, 89, 87, 83, 78, 78, 93, 81, 97, 92,
+  74, 99, 94, 87, 99, 82, 95, 84, 85, 87,
+  88, 84, 83, 88, 91, 80, 88, 92, 85, 85,
+  86, 88, 81, 94, 84, 74, 69, 82, 81, 66,
+  82, 94, 91, 84, 88, 88, 89, 88, 83, 89,
+  91, 79, 80, 100, 88, 79, 74, 83, 86, 83,
+  92, 79, 84, 85, 84, 84, 85, 84, 83, 85,
+  84, 88, 80, 88, 73, 89, 89, 92, 67, 88,
+  84, 87, 88, 94, 89, 81, 77, 79, 84, 79,
+  85, 76, 86, 92, 85, 90, 85, 86, 91, 88,
+  79, 86, 81, 89, 83, 80, 78, 82, 84, 77,
+  88, 90, 87, 86, 85, 77, 86, 79, 74, 80,
+  78, 98, 82, 87, 81, 84, 82, 77, 90, 88,
+  88, 82, 81, 76, 86, 79, 87, 86, 83, 98,
+  92, 80, 98, 86, 87, 85, 82, 86, 86, 86,
+  78, 86, 89, 81, 87, 92, 86, 93, 94, 90,
+  85, 92, 82, 70, 78, 83, 83, 69, 85, 93,
+  88, 81, 80, 89, 91, 88, 86, 87, 90, 85,
+  81, 92, 90, 83, 80, 82, 82, 82, 100, 74,
+  83, 90, 81, 82, 83, 85, 82, 87, 79, 90,
+  88, 96, 76, 88, 90, 94, 69, 89, 88, 87,
+  90, 91, 88, 79, 78, 76, 87, 78, 80, 73,
+  88, 90, 88, 90, 86, 90, 82, 83, 84, 87,
+  84, 94, 86, 74, 79, 80, 87, 67, 88, 85,
+  85, 83, 86, 78, 92, 86, 76, 72, 82, 94,
+  82, 83, 82, 84, 86, 84, 93, 88, 83, 85,
+  84, 83, 98, 79, 93, 90, 81, 99, 89, 77,
+  97, 85, 89, 83, 84, 90, 92, 85, 81, 86,
+  93, 85, 87, 92, 80, 86, 90, 83, 90, 88,
+  76, 76, 68, 76, 79, 75, 101, 80, 83, 92,
+  76, 70, 81, 71, 72, 84, 97, 81, 81, 74,
+  79, 78, 102, 77, 82, 94, 78, 90, 70, 81,
+  83, 84, 94, 82, 79, 76, 83, 85, 81, 76,
+  84, 89, 81, 75, 83, 107, 81, 77, 74, 104,
+  90, 73, 91, 83, 88, 75, 82, 71, 83, 63,
+  85, 97, 92, 90, 91, 71, 88, 81, 79, 90,
+  87, 86, 87, 78, 74, 79, 73, 92, 83, 81,
+  85, 82, 73, 80, 77, 84, 78, 80, 83, 71,
+  83, 77, 90, 84, 76, 92, 82, 83, 93, 81,
+  96, 96, 89, 66, 86, 88, 81, 100, 79, 86,
+  75, 86, 91, 91, 70, 86, 74, 85, 84, 72,
+  89, 78, 78, 84, 128, 88, 113, 82, 76, 76,
+  64, 86, 77, 64, 121, 86, 85, 76, 69, 36,
+  88, 61, 75, 106, 78, 70, 80, 70, 64, 84,
+  94, 78, 84, 82, 68, 98, 79, 97, 88, 87,
+  95, 114, 77, 74, 73, 84, 77, 63, 82, 100,
+  80, 85, 77, 129, 79, 91, 44, 97, 44, 72,
+  98, 77, 91, 71, 74, 67, 82, 79, 85, 85,
+  80, 76, 118, 72, 63, 77, 81, 69, 89, 109,
+  86, 67, 87, 70, 64, 81, 96, 77, 97, 117,
+  98, 76, 63, 89, 79, 68, 73, 73, 86, 71,
+  85, 82, 78, 89, 77, 84, 85, 74, 91, 105,
+  77, 53, 105, 82, 68, 101, 91, 81, 91, 80,
+  84, 87, 77, 87, 76, 75, 103, 71, 72, 80,
+  79, 76, 106, 81, 90, 90, 81, 75, 71, 78,
+  75, 78, 87, 94, 79, 94, 84, 73, 84, 66,
+  90, 82, 83, 87, 77, 74, 82, 74, 87, 75,
+  95, 90, 73, 78, 66, 85, 88, 81, 82, 79,
+  76, 78, 76, 82, 87, 89, 83, 85, 85, 71,
+  85, 89, 87, 78, 79, 64, 94, 75, 80, 90,
+  98, 77, 81, 77, 83, 65, 93, 110, 84, 87,
+  86, 78, 97, 83, 84, 90, 89, 90, 81, 80,
+  68, 76, 76, 70, 78, 74, 104, 82, 71, 83,
+  80, 93, 83, 82, 81, 75, 88, 76, 91, 88,
+  70, 95, 91, 81, 92, 82, 78, 88, 87, 75,
+  91, 96, 79, 83, 87, 83, 88, 84, 87, 91,
+  85, 85, 79, 86, 78, 78, 87, 80, 79, 86,
+  100, 89, 91, 95, 72, 77, 74, 81, 84, 77,
+  99, 93, 81, 80, 71, 70, 81, 72, 80, 89,
+  94, 85, 95, 74, 82, 82, 101, 96, 85, 94,
+  78, 83, 89, 82, 102, 92, 79, 70, 89, 76,
+  80, 77, 80, 94, 91, 87, 82, 76, 79, 98,
+  89, 74, 76, 83, 86, 74, 91, 92, 91, 83,
+  71, 73, 89, 60, 82, 106, 81, 79, 87, 73,
+  91, 83, 83, 92, 90, 85, 73, 76, 71, 75,
+  70, 92, 83, 81, 81, 80, 67, 89, 78, 69,
+  82, 91, 82, 71, 91, 80, 82, 76, 81, 74,
+  80, 82, 78, 86, 86, 95, 89, 75, 93, 92,
+  81, 101, 89, 75, 83, 93, 97, 86, 74, 86,
+  82, 89, 82, 76, 91, 76, 78, 83, 118, 85,
+  113, 92, 77, 76, 65, 88, 76, 65, 124, 88,
+  88, 69, 66, 43, 77, 63, 84, 107, 82, 71,
+  80, 71, 66, 87, 96, 81, 81, 77, 74, 99,
+  97, 97, 95, 88, 98, 114, 93, 75, 83, 78,
+  85, 74, 89, 101, 82, 88, 75, 115, 79, 91,
+  51, 106, 42, 75, 99, 79, 79, 80, 67, 66,
+  86, 75, 77, 90, 73, 61, 112, 68, 70, 84,
+  86, 76, 83, 102, 75, 66, 86, 72, 65, 79,
+  90, 70, 91, 106, 97, 71, 69, 77, 87, 75,
+  67, 72, 91, 76, 89, 73, 81, 82, 71, 83,
+  87, 72, 80, 107, 80, 57, 108, 80, 73, 97,
+  89, 64, 92, 82, 84, 81, 81, 86, 80, 74,
+  101, 72, 75, 73, 87, 85, 86, 87, 88, 93,
+  78, 76, 80, 85, 81, 80, 100, 80, 81, 84,
+  78, 77, 83, 69, 87, 76, 92, 85, 79, 73,
+  85, 79, 90, 82, 86, 88, 74, 83, 88, 88,
+  113, 87, 97, 65, 84, 83, 84, 78, 85, 95,
+  82, 89, 88, 72, 77, 75, 88, 79, 84, 81,
+  94, 75, 86, 93, 90, 90, 73, 78, 83, 68,
+  76, 104, 79, 76, 100, 78, 102, 83, 87, 85,
+  91, 85, 80, 82, 71, 76, 76, 75, 77, 70,
+  101, 76, 70, 85, 80, 81, 85, 92, 85, 75,
+  92, 80, 100, 77, 78, 92, 87, 80, 79, 77,
+  71, 89, 87, 82, 81, 88, 82, 87, 80, 67,
+  97, 88, 92, 87, 85, 88, 89, 87, 79, 76,
+  90, 79, 83, 89, 99, 87, 79, 99, 79, 75,
+  71, 75, 84, 68, 92, 91, 77, 72, 72, 64,
+  81, 82, 85, 84, 92, 80, 89, 72, 89, 81,
+  93, 93, 91, 88, 93, 82, 90, 90, 115, 91,
+  69, 78, 90, 71, 72, 76, 77, 91, 101, 90,
+  84, 67, 83, 99, 86, 76, 80, 66, 90, 79,
+  85, 86, 94, 82, 79, 61, 91, 61, 88, 89,
+  82, 80, 95, 74, 85, 84, 82, 88, 78, 91,
+  69, 78, 71, 88, 70, 84, 81, 84, 80, 84,
+  80, 87, 91, 76, 86, 86, 88, 74, 97, 75,
+  78, 75, 76, 80, 79, 81, 79, 79, 89, 87,
+  87, 74, 96, 85, 78, 90, 88, 79, 83, 90,
+  92, 87, 80, 83, 80, 80, 92, 82, 83, 86,
+  87, 88, 105, 89, 84, 102, 78, 74, 71, 85,
+  83, 54, 108, 69, 84, 72, 71, 54, 85, 71,
+  86, 90, 86, 78, 82, 73, 78, 92, 83, 84,
+  84, 82, 82, 91, 117, 100, 117, 89, 83, 98,
+  85, 75, 84, 73, 78, 86, 102, 111, 93, 76,
+  76, 85, 83, 88, 74, 84, 64, 76, 86, 85,
+  91, 87, 69, 51, 76, 72, 88, 79, 84, 68,
+  103, 71, 80, 82, 78, 72, 75, 115, 56, 71,
+  80, 71, 77, 86, 78, 74, 83, 98, 70, 82,
+  79, 79, 93, 82, 78, 67, 98, 77, 84, 75,
+  70, 79, 73, 83, 80, 80, 82, 88, 92, 71,
+  97, 73, 74, 86, 66, 77, 103, 89, 89, 84,
+  88, 90, 80, 72, 98, 77, 77, 99, 89, 85,
+  79, 87, 74, 89, 84, 78, 76, 82, 82, 76,
+  99, 75, 81, 75, 73, 74, 84, 75, 82, 74,
+  94, 84, 79, 76, 85, 81, 83, 72, 86, 85,
+  87, 88, 89, 92, 121, 87, 93, 75, 90, 76,
+  92, 78, 76, 88, 93, 94, 87, 69, 86, 88,
+  83, 80, 87, 88, 95, 84, 85, 83, 91, 86,
+  85, 68, 88, 64, 85, 90, 85, 87, 91, 75,
+  89, 83, 83, 80, 79, 85, 83, 77, 75, 94,
+  76, 78, 76, 76, 90, 82, 84, 80, 87, 85,
+  85, 88, 84, 76, 94, 77, 98, 73, 73, 84,
+  86, 78, 74, 74, 71, 88, 82, 76, 79, 80,
+  82, 82, 83, 78, 104, 86, 89, 84, 84, 85,
+  85, 80, 94, 80, 84, 87, 80, 106, 84, 93,
+  76, 75, 75, 87, 80, 78, 74, 78, 91, 80,
+  64, 97, 80, 83, 84, 101, 75, 66, 79, 76,
+  72, 64, 90, 77, 107, 98, 92, 79, 87, 83,
+  76, 95, 95, 87, 114, 80, 79, 92, 83, 87,
+  76, 75, 88, 92, 81, 76, 94, 86, 86, 79,
+  77, 110, 87, 92, 97, 83, 74, 85, 97, 81,
+  82, 73, 93, 73, 71, 94, 108, 82, 83, 89,
+  67, 79, 74, 73, 99, 75, 84, 86, 81, 95,
+  88, 80, 89, 89, 86, 81, 89, 94, 80, 74,
+  89, 84, 83, 78, 86, 88, 95, 91, 87, 78,
+  85, 90, 80, 85, 77, 72, 77, 80, 76, 77,
+  84, 90, 49, 90, 87, 92, 83, 94, 81, 73,
+  84, 95, 74, 79, 81, 111, 68, 91, 74, 90,
+  77, 85, 76, 85, 79, 83, 95, 58, 66, 93,
+  73, 84, 78, 87, 74, 79, 88, 84, 80, 77,
+  88, 86, 79, 107, 85, 79, 84, 85, 87, 100,
+  83, 85, 115, 81, 84, 99, 81, 81, 89, 78,
+  84, 97, 85, 75, 90, 82, 87, 84, 77, 101,
+  94, 72, 85, 84, 76, 86, 81, 74, 68, 83,
+  87, 76, 69, 77, 117, 83, 84, 80, 80, 86,
+  75, 94, 90, 89, 82, 86, 83, 84, 85, 71,
+  83, 90, 61, 78, 88, 82, 85, 71, 92, 80,
+  85, 88, 88, 90, 86, 99, 84, 77, 85, 86,
+  83, 83, 84, 73, 76, 76, 80, 79, 67, 91,
+  60, 83, 90, 86, 90, 89, 81, 80, 81, 87,
+  76, 92, 79, 104, 72, 87, 83, 83, 86, 94,
+  82, 77, 78, 78, 89, 64, 78, 88, 85, 88,
+  86, 78, 82, 96, 93, 85, 83, 91, 79, 89,
+  88, 99, 84, 80, 84, 88, 79, 82, 66, 82,
+  98, 93, 87, 91, 86, 81, 91, 85, 89, 82,
+  80, 88, 91, 86, 90, 88, 81, 82, 87, 69,
+  73, 82, 93, 76, 78, 65, 78, 78, 93, 83,
+  90, 83, 93, 79, 84, 80, 91, 83, 86, 81,
+  95, 94, 91, 80, 80, 81, 86, 70, 86, 80,
+  69, 76, 79, 86, 83, 77, 82, 76, 82, 97,
+  88, 86, 75, 100, 76, 78, 86, 85, 81, 83,
+  86, 79, 78, 84, 88, 90, 63, 92, 86, 85,
+  91, 83, 99, 91, 83, 79, 86, 91, 77, 92,
+  79, 95, 85, 86, 71, 66, 80, 83, 85, 74,
+  71, 91, 78, 100, 58, 82, 75, 77, 90, 88,
+  79, 70, 78, 72, 72, 73, 98, 79, 82, 76,
+  88, 77, 81, 79, 49, 78, 74, 82, 83, 79,
+  72, 88, 75, 80, 74, 78, 90, 82, 84, 78,
+  96, 85, 87, 82, 73, 102, 86, 93, 84, 80,
+  73, 88, 109, 87, 87, 70, 100, 86, 80, 92,
+  73, 83, 78, 82, 71, 77, 85, 54, 104, 72,
+  82, 89, 73, 90, 87, 85, 88, 90, 102, 86,
+  86, 95, 77, 80, 82, 86, 81, 79, 80, 83,
+  89, 102, 89, 78, 87, 87, 83, 85, 92, 79,
+  82, 72, 76, 78, 89, 108, 66, 94, 90, 98,
+  93, 86, 81, 77, 80, 94, 76, 72, 86, 110,
+  96, 91, 79, 68, 81, 82, 79, 86, 87, 78,
+  85, 78, 63, 89, 78, 77, 82, 80, 82, 74,
+  80, 82, 82, 75, 85, 83, 64, 126, 89, 71,
+  83, 78, 78, 86, 114, 96, 111, 77, 100, 100,
+  62, 73, 80, 76, 88, 101, 87, 70, 88, 74,
+  81, 87, 83, 98, 87, 79, 72, 82, 77, 89,
+  78, 89, 57, 94, 82, 70, 73, 80, 62, 74,
+  79, 79, 78, 77, 87, 64, 87, 83, 76, 78,
+  77, 80, 93, 92, 72, 97, 71, 71, 77, 80,
+  88, 80, 87, 82, 90, 84, 93, 84, 90, 102,
+  89, 78, 77, 87, 73, 83, 87, 78, 88, 81,
+  77, 67, 74, 90, 57, 89, 96, 92, 99, 79,
+  82, 77, 78, 83, 82, 86, 85, 109, 119, 93,
+  93, 106, 84, 89, 83, 85, 90, 72, 89, 75,
+  82, 88, 92, 87, 86, 81, 87, 98, 102, 85,
+  91, 91, 71, 89, 83, 148, 91, 82, 86, 80,
+  94, 96, 96, 82, 98, 83, 96, 94, 70, 77,
+  91, 90, 92, 123, 81, 85, 81, 74, 81, 86,
+  94, 54, 81, 74, 67, 81, 91, 77, 63, 58,
+  56, 85, 75, 76, 80, 69, 70, 82, 81, 81,
+  93, 83, 92, 64, 61, 91, 83, 68, 84, 101,
+  91, 87, 77, 89, 56, 74, 81, 66, 86, 83,
+  82, 77, 87, 93, 83, 77, 84, 87, 78, 80,
+  81, 77, 75, 80, 80, 84, 98, 90, 82, 79,
+  53, 76, 78, 90, 92, 81, 93, 92, 86, 79,
+  79, 78, 82, 100, 86, 87, 92, 92, 72, 90,
+  80, 81, 89, 75, 66, 84, 84, 97, 71, 75,
+  80, 79, 94, 81, 78, 88, 79, 76, 82, 89,
+  86, 89, 90, 75, 87, 79, 72, 82, 70, 90,
+  58, 91, 72, 88, 73, 82, 76, 82, 81, 82,
+  82, 91, 87, 79, 93, 91, 82, 80, 78, 86,
+  87, 83, 83, 86, 85, 82, 94, 86, 94, 74,
+  86, 94, 78, 77, 78, 83, 82, 83, 79, 78,
+  86, 82, 84, 78, 87, 84, 73, 95, 87, 85,
+  93, 90, 100, 92, 82, 91, 80, 82, 90, 77,
+  83, 76, 76, 73, 87, 90, 86, 73, 94, 84,
+  89, 88, 88, 80, 93, 68, 82, 84, 81, 101,
+  101, 88, 84, 88, 92, 91, 84, 89, 76, 94,
+  79, 71, 85, 75, 77, 92, 81, 69, 76, 80,
+  80, 82, 83, 73, 86, 95, 86, 82, 85, 82,
+  84, 79, 87, 81, 63, 84, 85, 87, 88, 79,
+  75, 84, 79, 66, 83, 80, 78, 69, 83, 92,
+  79, 84, 83, 80, 69, 82, 80, 82, 83, 65,
+  87, 82, 84, 84, 86, 85, 87, 92, 80, 86,
+  77, 86, 85, 92, 90, 97, 77, 86, 93, 85,
+  79, 89, 63, 73, 87, 84, 80, 76, 89, 72,
+  96, 79, 84, 79, 76, 68, 96, 87, 78, 86,
+  89, 81, 71, 95, 81, 87, 84, 81, 84, 87,
+  86, 79, 79, 78, 81, 74, 91, 94, 73, 88,
+  77, 84, 96, 83, 81, 66, 82, 104, 72, 88,
+  87, 83, 104, 80, 79, 85, 84, 91, 78, 80,
+  83, 83, 102, 94, 88, 63, 82, 91, 85, 87,
+  93, 74, 83, 90, 95, 101, 92, 88, 90, 82,
+  93, 87, 79, 90, 88, 92, 84, 86, 81, 142,
+  82, 70, 99, 80, 96, 69, 122, 95, 83, 84,
+  95, 77, 66, 82, 89, 90, 89, 88, 82, 89,
+  76, 77, 83, 88, 103, 57, 88, 91, 75, 83,
+  91, 84, 77, 87, 70, 87, 78, 84, 77, 94,
+  39, 75, 91, 86, 93, 89, 88, 68, 76, 82,
+  88, 66, 86, 82, 98, 89, 64, 74, 77, 82,
+  72, 88, 85, 87, 81, 85, 85, 93, 82, 85,
+  87, 73, 75, 78, 89, 93, 72, 86, 68, 93,
+  103, 92, 87, 68, 81, 83, 63, 91, 93, 83,
+  88, 86, 76, 85, 85, 83, 78, 101, 91, 123,
+  66, 92, 87, 82, 81, 84, 81, 82, 82, 74,
+  88, 76, 70, 62, 75, 84, 85, 84, 74, 85,
+  82, 89, 79, 81, 102, 88, 98, 90, 95, 102,
+  67, 89, 76, 81, 113, 84, 80, 93, 86, 72,
+  102, 67, 89, 80, 90, 99, 68, 79, 76, 88,
+  87, 81, 71, 83, 64, 70, 68, 88, 101, 82,
+  89, 84, 75, 72, 69, 91, 78, 100, 78, 89,
+  81, 82, 90, 68, 86, 68, 109, 79, 80, 93,
+  85, 93, 88, 86, 96, 88, 74, 105, 77, 98,
+  92, 82, 87, 76, 92, 86, 88, 75, 87, 76,
+  94, 85, 81, 82, 83, 74, 91, 81, 95, 70,
+  85, 100, 89, 90, 72, 85, 78, 100, 88, 81,
+  83, 78, 89, 91, 79, 89, 81, 101, 39, 90,
+  90, 90, 67, 85, 95, 87, 75, 72, 75, 47,
+  65, 75, 77, 81, 82, 83, 70, 77, 75, 90,
+  84, 75, 101, 94, 125, 65, 69, 95, 53, 97,
+  81, 80, 112, 78, 82, 82, 81, 78, 104, 69,
+  84, 97, 89, 91, 72, 75, 70, 92, 88, 69,
+  89, 96, 64, 60, 74, 85, 85, 74, 85, 71,
+  49, 54, 45, 81, 83, 95, 117, 92, 76, 77,
+  96, 70, 89, 88, 117, 72, 80, 79, 95, 81,
+  98, 75, 87, 96, 61, 83, 72, 115, 79, 69,
+  107, 71, 85, 75, 97, 77, 80, 130, 94, 85,
+  83, 69, 79, 85, 76, 73, 78, 57, 77, 95,
+  82, 88, 72, 74, 73, 83, 65, 73, 77, 76,
+  90, 82, 82, 69, 75, 78, 44, 75, 73, 102,
+  73, 103, 76, 90, 79, 65, 61, 64, 75, 80,
+  91, 97, 90, 91, 83, 74, 71, 94, 81, 89,
+  87, 85, 110, 55, 68, 83, 87, 90, 64, 76,
+  74, 84, 56, 84, 80, 84, 85, 77, 86, 102,
+  76, 70, 88, 83, 85, 80, 84, 73, 109, 67,
+  101, 73, 85, 70, 72, 85, 85, 72, 31, 72,
+  73, 74, 95, 76, 98, 74, 109, 89, 81, 98,
+  75, 89, 74, 86, 82, 88, 95, 84, 94, 73,
+  91, 89, 69, 74, 112, 94, 74, 88, 120, 74,
+  89, 80, 83, 80, 58, 140, 81, 90, 76, 69,
+  75, 81, 70, 81, 78, 69, 84, 78, 72, 95,
+  60, 83, 89, 77, 75, 83, 90, 86, 95, 76,
+  82, 86, 90, 94, 73, 85, 84, 78, 86, 77,
+  71, 74, 87, 82, 78, 87, 93, 75, 87, 90,
+  89, 90, 79, 80, 84, 85, 77, 76, 91, 82,
+  79, 93, 101, 100, 94, 84, 98, 73, 91, 88,
+  88, 77, 83, 74, 92, 80, 83, 75, 93, 75,
+  71, 75, 71, 85, 89, 89, 79, 86, 63, 84,
+  78, 85, 99, 86, 90, 86, 83, 91, 87, 87,
+  77, 84, 78, 78, 77, 95, 84, 71, 80, 94,
+  93, 76, 91, 83, 79, 82, 84, 87, 97, 86,
+  97, 91, 88, 75, 97, 87, 72, 81, 87, 94,
+  84, 80, 74, 64, 82, 80, 75, 99, 92, 89,
+  74, 84, 84, 94, 84, 84, 86, 93, 74, 95,
+  82, 100, 80, 88, 67, 74, 79, 82, 79, 109,
+  84, 114, 79, 95, 98, 75, 86, 68, 93, 78,
+  84, 82, 84, 85, 94, 83, 82, 78, 93, 79,
+  72, 62, 92, 91, 90, 82, 79, 101, 87, 85,
+  103, 98, 80, 90, 90, 68, 95, 94, 84, 78,
+  94, 82, 102, 67, 73, 75, 105, 89, 67, 83,
+  76, 87, 85, 82, 77, 72, 45, 81, 73, 99,
+  91, 63, 83, 78, 79, 70, 75, 85, 72, 83,
+  64, 99, 65, 88, 88, 65, 95, 82, 96, 75,
+  86, 92, 86, 88, 89, 97, 86, 86, 81, 87,
+  78, 79, 97, 95, 63, 81, 90, 93, 103, 68,
+  76, 68, 89, 80, 78, 78, 94, 96, 84, 79,
+  90, 87, 74, 90, 94, 89, 75, 91, 84, 88,
+  85, 81, 82, 76, 78, 83, 87, 87, 77, 106,
+  62, 88, 72, 122, 71, 76, 88, 94, 74, 64,
+  65, 70, 70, 71, 87, 76, 85, 99, 78, 75,
+  103, 95, 84, 83, 86, 88, 101, 84, 78, 96,
+  69, 83, 67, 101, 101, 78, 84, 75, 85, 91,
+  90, 69, 77, 96, 88, 136, 87, 76, 74, 67,
+  85, 66, 100, 64, 75, 64, 73, 79, 85, 78,
+  91, 67, 49, 64, 59, 84, 91, 79, 98, 101,
+  81, 83, 89, 82, 79, 81, 89, 78, 79, 87,
+  101, 95, 94, 88, 96, 100, 71, 72, 86, 79,
+  77, 77, 92, 63, 86, 78, 92, 69, 72, 136,
+  92, 89, 74, 72, 79, 82, 77, 63, 72, 83,
+  69, 95, 76, 97, 84, 84, 80, 68, 73, 70,
+  84, 71, 87, 72, 85, 81, 86, 91, 85, 85,
+  80, 81, 77, 82, 74, 91, 81, 100, 83, 85,
+  82, 78, 94, 77, 78, 95, 78, 82, 92, 80,
+  76, 74, 101, 76, 79, 94, 89, 86, 93, 78,
+  85, 80, 81, 79, 98, 77, 79, 85, 90, 93,
+  83, 77, 87, 74, 85, 81, 78, 94, 94, 89,
+  85, 88, 83, 82, 94, 88, 85, 93, 86, 89,
+  79, 96, 90, 93, 84, 87, 80, 77, 76, 90,
+  92, 72, 79, 77, 76, 73, 97, 89, 94, 93,
+  79, 83, 87, 87, 90, 86, 95, 70, 93, 77,
+  72, 82, 81, 80, 88, 85, 73, 84, 77, 84,
+  88, 94, 92, 79, 91, 80, 80, 88, 80, 85,
+  83, 84, 85, 87, 89, 92, 73, 94, 69, 74,
+  97, 82, 87, 84, 85, 94, 98, 89, 91, 83,
+  82, 74, 82, 85, 75, 95, 96, 94, 83, 76,
+  88, 73, 77, 82, 81, 83, 95, 85, 70, 74,
+  88, 91, 81, 82, 86, 83, 92, 84, 85, 78,
+  84, 85, 88, 83, 86, 85, 91, 72, 75, 71,
+  86, 78, 91, 84, 80, 93, 89, 82, 81, 76,
+  70, 84, 83, 82, 83, 86, 81, 77, 86, 89,
+  92, 81, 78, 93, 87, 90, 73, 81, 83, 68,
+  84, 89, 74, 81, 89, 82, 91, 96, 80, 93,
+  85, 90, 77, 93, 91, 76, 94, 85, 71, 82,
+  84, 79, 90, 90, 74, 70, 80, 83, 82, 87,
+  85, 85, 95, 73, 85, 89, 79, 82, 94, 84,
+  90, 85, 88, 88, 80, 89, 79, 77, 94, 86,
+  85, 79, 76, 105, 87, 88, 88, 94, 80, 79,
+  90, 89, 80, 82, 76, 91, 62, 69, 80, 76,
+  84, 83, 96, 89, 108, 93, 77, 82, 79, 89,
+  86, 86, 82, 84, 76, 78, 69, 90, 88, 90,
+  83, 85, 101, 84, 98, 72, 82, 88, 87, 116,
+  90, 78, 87, 72, 81, 72, 88, 70, 76, 77,
+  77, 77, 84, 76, 94, 70, 66, 84, 87, 82,
+  94, 78, 83, 98, 77, 80, 87, 76, 86, 94,
+  72, 83, 86, 85, 93, 95, 85, 92, 91, 97,
+  79, 90, 88, 77, 85, 81, 84, 75, 84, 78,
+  99, 84, 75, 77, 86, 87, 73, 77, 80, 85,
+  93, 66, 77, 86, 78, 83, 82, 88, 104, 84,
+  85, 78, 81, 76, 86, 78, 91, 83, 86, 80,
+  104, 107, 89, 83, 44, 92, 83, 84, 83, 83,
+  84, 98, 86, 96, 86, 78, 86, 106, 90, 95,
+  81, 77, 89, 85, 82, 89, 93, 87, 90, 85,
+  82, 89, 83, 76, 73, 78, 90, 87, 68, 75,
+  81, 68, 83, 76, 93, 82, 77, 73, 68, 80,
+  85, 88, 96, 90, 94, 76, 84, 88, 80, 77,
+  89, 63, 112, 88, 90, 85, 84, 88, 81, 76,
+  74, 84, 81, 84, 81, 88, 64, 72, 89, 76,
+  89, 115, 80, 85, 82, 89, 78, 83, 100, 94,
+  73, 90, 84, 83, 84, 83, 89, 95, 81, 88,
+  74, 86, 86, 76, 82, 75, 81, 67, 88, 92,
+  81, 75, 76, 80, 90, 80, 80, 83, 62, 81,
+  80, 81, 83, 76, 81, 82, 88, 78, 99, 102,
+  63, 79, 65, 88, 80, 84, 81, 85, 86, 95,
+  92, 53, 85, 82, 86, 93, 89, 88, 84, 70,
+  76, 97, 88, 81, 92, 86, 88, 83, 82, 89,
+  85, 80, 82, 83, 86, 79, 114, 76, 77, 76,
+  72, 80, 93, 84, 87, 65, 74, 76, 78, 89,
+  88, 87, 92, 83, 79, 78, 87, 85, 82, 71,
+  106, 71, 61, 86, 78, 84, 83, 80, 81, 80,
+  76, 79, 81, 84, 75, 80, 92, 78, 76, 104,
+  76, 86, 81, 78, 75, 93, 85, 91, 71, 87,
+  85, 90, 81, 87, 85, 89, 71, 90, 71, 102,
+  85, 81, 83, 75, 82, 75, 89, 87, 80, 75,
+  78, 76, 76, 87, 69, 87, 73, 84, 82, 87,
+  77, 76, 82, 85, 89, 101, 81, 94, 86, 78,
+  138, 93, 71, 87, 76, 85, 92, 76, 80, 82,
+  70, 91, 82, 73, 86, 70, 76, 87, 82, 101,
+  79, 76, 70, 84, 77, 93, 93, 86, 79, 91,
+  101, 104, 86, 78, 92, 92, 78, 83, 78, 79,
+  100, 88, 100, 90, 98, 76, 78, 89, 72, 92,
+  87, 67, 80, 82, 91, 83, 86, 97, 88, 70,
+  61, 94, 67, 74, 100, 72, 68, 74, 79, 80,
+  95, 82, 87, 98, 92, 83, 76, 83, 83, 95,
+  91, 80, 73, 120, 72, 85, 66, 88, 93, 90,
+  88, 87, 90, 67, 72, 88, 75, 94, 78, 82,
+  81, 65, 77, 86, 86, 76, 95, 86, 77, 80,
+  69, 85, 91, 92, 87, 79, 87, 93, 67, 84,
+  83, 89, 80, 110, 92, 90, 87, 88, 40, 94,
+  98, 76, 85, 81, 83, 81, 78, 66, 98, 85,
+  99, 111, 75, 86, 75, 75, 84, 92, 82, 88,
+  93, 81, 97, 85, 91, 88, 99, 72, 79, 81,
+  86, 88, 63, 71, 76, 78, 77, 77, 86, 85,
+  82, 78, 65, 79, 77, 79, 96, 87, 95, 68,
+  79, 77, 82, 108, 86, 72, 79, 88, 85, 86,
+  77, 115, 84, 84, 86, 85, 75, 88, 85, 95,
+  81, 89, 80, 76, 93, 68, 83, 74, 84, 86,
+  84, 75, 71, 89, 94, 90, 85, 89, 81, 78,
+  82, 102, 90, 86, 69, 108, 86, 77, 93, 85,
+  97, 76, 77, 93, 84, 87, 73, 87, 77, 88,
+  87, 89, 78, 81, 83, 84, 77, 82, 76, 81,
+  86, 79, 87, 86, 68, 83, 76, 83, 84, 76,
+  85, 85, 85, 89, 83, 61, 87, 87, 95, 91,
+  74, 84, 79, 75, 73, 98, 77, 79, 92, 81,
+  93, 83, 82, 91, 89, 78, 62, 86, 75, 86,
+  93, 70, 73, 86, 68, 81, 87, 82, 88, 78,
+  78, 79, 78, 80, 98, 85, 88, 74, 84, 73,
+  83, 105, 87, 77, 75, 70, 61, 81, 76, 95,
+  85, 78, 73, 84, 71, 86, 86, 88, 86, 77,
+  73, 83, 82, 71, 82, 86, 84, 76, 80, 83,
+  72, 89, 85, 83, 80, 100, 76, 81, 81, 93,
+  79, 91, 72, 113, 84, 81, 93, 77, 96, 84,
+  84, 92, 81, 85, 76, 85, 79, 79, 71, 86,
+  78, 80, 82, 82, 83, 82, 79, 80, 84, 91,
+  71, 86, 81, 75, 156, 89, 66, 84, 80, 79,
+  94, 79, 82, 91, 67, 90, 84, 69, 70, 74,
+  74, 99, 83, 93, 80, 67, 70, 77, 89, 80,
+  85, 87, 79, 99, 83, 111, 83, 85, 97, 111,
+  81, 89, 85, 85, 101, 80, 103, 81, 110, 79,
+  81, 91, 74, 94, 76, 81, 85, 79, 85, 84,
+  81, 90, 81, 65, 58, 85, 69, 66, 97, 67,
+  76, 76, 73, 84, 99, 81, 91, 95, 79, 87,
+  82, 74, 88, 96, 91, 85, 74, 106, 77, 75,
+  70, 78, 82, 85, 81, 84, 84, 62, 76, 89,
+  78, 79, 78, 83, 80, 66, 80, 91, 79, 80,
+  85, 97, 81, 88, 72, 75, 93, 83, 78, 74,
+  83, 83, 69, 87, 91, 86, 74, 95, 79, 91,
+  86, 92, 54, 82, 98, 85, 86, 84, 77, 86,
+  72, 61, 100, 100, 96, 95, 71, 77, 82, 74,
+  80, 81, 76, 92, 89, 78, 87, 89, 84, 88,
+  101, 84, 81, 88, 98, 85, 76, 79, 84, 79,
+  77, 89, 79, 89, 71, 79, 67, 78, 69, 87,
+  84, 90, 89, 77, 83, 89, 86, 93, 73, 73,
+  86, 87, 93, 83, 68, 106, 77, 88, 101, 81,
+  88, 86, 86, 100, 89, 74, 88, 70, 88, 87,
+  86, 73, 80, 81, 89, 73, 87, 83, 86, 83,
+  91, 90, 86, 86, 86, 88, 90, 84, 84, 102,
+  90, 78, 98, 90, 91, 84, 70, 76, 87, 87,
+  83, 89, 94, 74, 72, 99, 95, 91, 82, 83,
+  75, 88, 77, 92, 78, 67, 74, 90, 86, 86,
+  88, 79, 86, 76, 80, 80, 83, 87, 75, 97,
+  84, 93, 88, 78, 68, 87, 84, 85, 73, 85,
+  69, 81, 83, 76, 84, 104, 79, 88, 91, 83,
+  65, 89, 95, 82, 79, 81, 89, 83, 66, 93,
+  84, 85, 72, 68, 87, 79, 78, 94, 83, 88,
+  80, 71, 83, 83, 83, 97, 78, 79, 85, 68,
+  72, 79, 82, 85, 80, 87, 82, 81, 77, 92,
+  88, 81, 86, 72, 74, 83, 81, 87, 83, 81,
+  84, 89, 81, 82, 85, 79, 72, 77, 81, 92,
+  76, 88, 81, 78, 86, 88, 84, 90, 83, 80,
+  92, 84, 84, 89, 81, 78, 90, 87, 84, 88,
+  93, 74, 72, 84, 80, 89, 83, 84, 79, 85,
+  82, 90, 79, 80, 69, 94, 89, 81, 143, 91,
+  66, 82, 81, 79, 89, 73, 76, 105, 60, 86,
+  75, 64, 72, 74, 74, 105, 90, 89, 78, 72,
+  73, 76, 77, 84, 80, 87, 80, 92, 85, 105,
+  96, 81, 91, 108, 91, 85, 83, 88, 98, 84,
+  86, 79, 111, 87, 79, 88, 68, 93, 79, 77,
+  81, 75, 88, 83, 82, 85, 85, 71, 67, 74,
+  78, 63, 88, 87, 93, 74, 74, 92, 95, 77,
+  86, 99, 73, 91, 80, 75, 90, 91, 85, 100,
+  77, 105, 80, 68, 68, 83, 87, 81, 83, 81,
+  90, 64, 83, 89, 89, 75, 80, 81, 88, 74,
+  75, 85, 83, 73, 91, 104, 89, 91, 70, 79,
+  91, 81, 83, 87, 91, 81, 71, 86, 93, 94,
+  77, 95, 80, 85, 75, 77, 79, 74, 81, 78,
+  71, 85, 76, 79, 81, 83, 73, 78, 79, 81,
+  76, 86, 91, 74, 67, 82, 77, 86, 84, 88,
+  84, 82, 84, 76, 83, 81, 80, 71, 86, 78,
+  78, 81, 78, 71, 81, 83, 84, 82, 64, 69,
+  87, 80, 88, 94, 76, 82, 79, 89, 76, 76,
+  88, 82, 72, 74, 93, 67, 88, 76, 86, 81,
+  81, 88, 69, 80, 91, 85, 74, 85, 75, 83,
+  85, 93, 78, 84, 76, 87, 73, 79, 81, 70,
+  89, 82, 88, 90, 83, 84, 80, 85, 80, 81,
+  81, 88, 87, 72, 78, 81, 77, 85, 78, 78,
+  85, 76, 80, 72, 77, 83, 85, 86, 78, 82,
+  75, 91, 86, 85, 96, 77, 92, 77, 80, 83,
+  80, 90, 89, 78, 81, 67, 81, 73, 73, 89,
+  75, 82, 91, 85, 76, 78, 77, 77, 75, 79,
+  84, 70, 70, 86, 87, 86, 83, 85, 103, 80,
+  92, 81, 80, 75, 78, 70, 87, 76, 84, 78,
+  79, 63, 83, 86, 77, 82, 70, 69, 84, 84,
+  82, 106, 85, 81, 85, 93, 75, 78, 87, 79,
+  80, 75, 89, 75, 80, 76, 80, 77, 77, 88,
+  81, 70, 79, 84, 77, 78, 71, 77, 89, 81,
+  79, 79, 81, 78, 74, 78, 74, 81, 91, 83,
+  85, 89, 87, 83, 80, 74, 81, 82, 80, 88,
+  86, 81, 72, 78, 75, 82, 73, 81, 86, 75,
+  76, 72, 76, 74, 82, 79, 69, 78, 79, 83,
+  81, 84, 99, 74, 93, 72, 80, 79, 80, 88,
+  80, 77, 76, 71, 85, 87, 71, 86, 76, 83,
+  75, 80, 76, 79, 77, 80, 77, 86, 84, 71,
+  74, 81, 86, 88, 88, 86, 79, 84, 86, 83,
+  81, 76, 75, 88, 93, 82, 75, 80, 81, 71,
+  83, 81, 83, 83, 72, 83, 88, 77, 89, 84,
+  74, 84, 83, 83, 78, 77, 84, 81, 77, 75,
+  90, 65, 88, 76, 83, 83, 80, 86, 76, 79,
+  93, 82, 79, 84, 77, 75, 89, 90, 82, 85,
+  73, 75, 77, 77, 86, 67, 87, 82, 88, 88,
+  83, 85, 82, 86, 83, 80, 74, 85, 83, 90,
+  79, 83, 81, 82, 80, 77, 82, 74, 79, 75,
+  80, 81, 83, 81, 73, 81, 77, 87, 85, 87,
+  90, 76, 85, 75, 84, 82, 99, 101, 105, 90,
+  92, 109, 55, 68, 80, 89, 84, 88, 124, 93,
+  74, 81, 87, 79, 87, 95, 90, 107, 103, 86,
+  85, 67, 77, 96, 172, 84, 87, 101, 90, 98,
+  96, 93, 74, 92, 88, 90, 84, 73, 91, 86,
+  88, 106, 72, 91, 70, 94, 77, 103, 71, 79,
+  73, 78, 67, 57, 95, 90, 84, 89, 79, 42,
+  78, 68, 81, 92, 77, 71, 99, 73, 91, 84,
+  84, 81, 77, 105, 66, 84, 72, 90, 86, 119,
+  66, 89, 95, 102, 59, 83, 90, 76, 84, 85,
+  96, 88, 81, 77, 88, 81, 108, 84, 85, 76,
+  91, 75, 105, 80, 91, 77, 76, 77, 74, 105,
+  65, 96, 96, 89, 77, 71, 79, 85, 94, 70,
+  92, 83, 91, 87, 100, 95, 100, 88, 92, 105,
+  59, 59, 77, 91, 80, 90, 139, 91, 79, 70,
+  79, 73, 77, 89, 88, 100, 109, 86, 92, 72,
+  76, 89, 173, 84, 96, 93, 80, 93, 94, 93,
+  79, 82, 92, 85, 86, 70, 90, 89, 81, 99,
+  71, 97, 68, 94, 74, 119, 80, 72, 74, 90,
+  70, 55, 92, 93, 85, 88, 75, 55, 77, 71,
+  74, 92, 72, 71, 110, 66, 75, 79, 85, 76,
+  74, 106, 73, 75, 68, 83, 87, 96, 71, 86,
+  94, 108, 63, 79, 74, 81, 92, 90, 92, 77,
+  79, 77, 87, 81, 106, 91, 81, 72, 88, 75,
+  91, 81, 84, 72, 74, 78, 66, 97, 66, 85,
+  99, 85, 83, 71, 86, 81, 89, 66, 93, 81,
+  86, 83, 98, 92, 86, 90, 84, 94, 68, 81,
+  80, 92, 86, 86, 111, 81, 78, 80, 81, 80,
+  89, 87, 89, 99, 101, 85, 92, 75, 76, 96,
+  139, 87, 87, 94, 91, 89, 79, 105, 75, 91,
+  84, 88, 80, 75, 85, 82, 85, 103, 77, 102,
+  75, 95, 76, 100, 70, 80, 80, 76, 68, 64,
+  89, 91, 85, 84, 80, 46, 80, 76, 81, 92,
+  81, 64, 97, 74, 92, 79, 89, 85, 78, 95,
+  70, 83, 81, 93, 80, 77, 72, 83, 100, 87,
+  63, 79, 85, 81, 83, 90, 96, 88, 85, 76,
+  84, 79, 96, 93, 85, 77, 93, 75, 100, 75,
+  86, 77, 74, 78, 76, 97, 62, 89, 105, 89,
+  81, 71, 95, 83, 94, 71, 89, 82, 92, 86,
+  83, 79, 84, 87, 74, 82, 80, 81, 78, 80,
+  82, 77, 91, 91, 77, 86, 87, 79, 85, 81,
+  83, 82, 75, 81, 76, 83, 82, 87, 121, 72,
+  90, 88, 79, 89, 85, 69, 75, 79, 74, 98,
+  89, 77, 79, 76, 75, 77, 77, 68, 78, 80,
+  89, 100, 80, 81, 85, 81, 76, 80, 81, 79,
+  80, 72, 84, 70, 80, 77, 85, 71, 82, 86,
+  76, 72, 88, 85, 76, 81, 77, 85, 78, 84,
+  78, 89, 82, 89, 80, 83, 77, 87, 91, 84,
+  85, 94, 81, 82, 87, 74, 84, 81, 82, 91,
+  94, 78, 82, 77, 77, 87, 69, 87, 82, 79,
+  82, 75, 78, 82, 91, 83, 80, 75, 81, 75,
+  80, 81, 88, 81, 75, 87, 83, 81, 86, 85,
+  87, 88, 75, 68, 78, 75, 82, 82, 81, 78,
+  95, 84, 81, 81, 83, 74, 77, 80, 80, 72,
+  84, 84, 78, 85, 81, 83, 132, 78, 92, 91,
+  80, 78, 85, 64, 75, 72, 81, 87, 93, 69,
+  84, 76, 77, 80, 72, 70, 74, 81, 92, 108,
+  86, 79, 91, 93, 79, 79, 79, 78, 80, 74,
+  77, 77, 72, 73, 80, 72, 76, 82, 81, 61,
+  82, 82, 78, 81, 75, 79, 82, 77, 75, 85,
+  84, 81, 83, 83, 71, 91, 86, 85, 84, 94,
+  87, 87, 84, 65, 85, 83, 81, 92, 92, 84,
+  76, 73, 72, 87, 62, 86, 83, 76, 85, 74,
+  74, 72, 84, 78, 71, 75, 85, 73, 79, 78,
+  90, 80, 77, 89, 80, 76, 82, 86, 85, 92,
+  74, 68, 84, 88, 81, 84, 81, 77, 83, 74,
+  78, 85, 84, 78, 83, 85, 80, 75, 90, 81,
+  80, 84, 83, 89, 113, 81, 87, 89, 82, 80,
+  72, 80, 82, 80, 80, 96, 87, 74, 80, 78,
+  76, 81, 80, 84, 78, 80, 89, 93, 78, 82,
+  86, 87, 78, 81, 78, 78, 79, 70, 80, 65,
+  88, 75, 82, 72, 78, 83, 77, 70, 93, 84,
+  84, 80, 79, 78, 80, 81, 83, 91, 83, 79,
+  81, 81, 78, 77, 87, 79, 82, 94, 80, 81,
+  86, 74, 82, 79, 82, 88, 91, 87, 81, 79,
+  75, 85, 74, 86, 78, 75, 81, 76, 78, 78,
+  85, 77, 78, 75, 81, 75, 83, 80, 81, 82,
+  75, 91, 83, 75, 78, 86, 85, 96, 76, 76,
+  75, 76, 96, 82, 67, 80, 84, 73, 87, 73,
+  81, 81, 61, 85, 98, 85, 87, 88, 86, 106,
+  89, 70, 104, 91, 78, 79, 98, 80, 75, 97,
+  88, 79, 85, 87, 108, 81, 99, 90, 71, 98,
+  100, 96, 82, 101, 93, 89, 82, 88, 72, 86,
+  91, 74, 83, 80, 80, 83, 86, 73, 88, 68,
+  85, 91, 87, 92, 84, 81, 83, 79, 90, 75,
+  79, 88, 85, 87, 80, 78, 75, 70, 85, 86,
+  90, 81, 87, 87, 102, 79, 66, 68, 85, 80,
+  82, 84, 83, 77, 82, 82, 67, 61, 83, 73,
+  93, 88, 92, 72, 99, 80, 84, 83, 78, 96,
+  77, 68, 78, 109, 105, 86, 92, 63, 96, 77,
+  77, 91, 82, 89, 85, 97, 86, 74, 71, 72,
+  111, 72, 53, 80, 89, 79, 88, 67, 76, 79,
+  38, 83, 107, 93, 68, 90, 79, 105, 102, 64,
+  102, 84, 71, 83, 106, 83, 83, 80, 89, 74,
+  81, 84, 102, 77, 105, 85, 70, 109, 110, 76,
+  75, 109, 87, 94, 95, 83, 74, 89, 90, 78,
+  79, 77, 79, 92, 90, 74, 82, 68, 86, 81,
+  89, 91, 91, 70, 82, 84, 82, 61, 80, 76,
+  93, 88, 85, 74, 85, 85, 77, 87, 89, 71,
+  87, 98, 96, 76, 53, 57, 78, 70, 52, 84,
+  86, 74, 85, 82, 62, 57, 82, 77, 95, 93,
+  98, 82, 100, 85, 71, 82, 84, 95, 77, 62,
+  83, 116, 102, 88, 89, 61, 104, 85, 65, 101,
+  80, 79, 84, 90, 77, 89, 78, 77, 89, 83,
+  73, 78, 80, 83, 87, 74, 79, 81, 68, 86,
+  95, 84, 72, 86, 83, 102, 90, 68, 96, 80,
+  76, 79, 90, 94, 80, 80, 83, 79, 78, 88,
+  98, 81, 93, 85, 79, 89, 88, 86, 84, 95,
+  89, 84, 80, 87, 75, 79, 91, 74, 80, 83,
+  79, 84, 84, 71, 90, 71, 89, 89, 84, 86,
+  91, 83, 76, 81, 83, 76, 78, 91, 89, 87,
+  74, 80, 83, 101, 87, 80, 87, 82, 87, 94,
+  101, 80, 71, 68, 85, 80, 87, 85, 87, 80,
+  83, 90, 71, 62, 85, 71, 95, 89, 96, 70,
+  93, 90, 85, 88, 78, 89, 81, 73, 79, 105,
+  79, 85, 87, 65, 94, 82, 82, 88, 78, 83,
+  79, 87, 83, 90, 73, 77, 119, 76, 67, 85,
+  85, 81, 86, 73, 92, 86, 47, 83, 104, 89,
+  87, 87, 79, 97, 85, 66, 100, 87, 72, 74,
+  107, 72, 76, 104, 87, 72, 85, 86, 88, 83,
+  104, 88, 78, 103, 103, 111, 83, 106, 87, 85,
+  84, 88, 73, 87, 95, 74, 82, 79, 77, 89,
+  80, 70, 83, 74, 84, 93, 92, 74, 86, 80,
+  84, 81, 82, 75, 88, 99, 75, 88, 87, 73,
+  76, 66, 84, 90, 88, 81, 84, 78, 97, 90,
+  58, 62, 88, 77, 72, 84, 83, 82, 88, 95,
+  69, 62, 80, 88, 87, 82, 84, 73, 90, 79,
+  83, 82, 80, 92, 80, 71, 82, 103, 102, 83,
+  89, 61, 95, 82, 67, 99, 80, 90, 83, 88,
+  89, 78, 68, 83, 148, 63, 56, 86, 92, 77,
+  84, 73, 94, 90, 22, 77, 111, 93, 72, 87,
+  72, 96, 98, 59, 110, 80, 64, 75, 122, 70,
+  81, 84, 82, 72, 83, 85, 78, 74, 110, 81,
+  81, 119, 118, 82, 74, 119, 84, 82, 106, 86,
+  75, 87, 97, 77, 77, 71, 69, 97, 81, 72,
+  64, 73, 95, 79, 96, 72, 80, 64, 92, 87,
+  70, 61, 89, 87, 81, 91, 97, 71, 93, 92,
+  75, 88, 87, 63, 86, 87, 96, 85, 41, 48,
+  75, 66, 41, 79, 88, 76, 82, 85, 61, 57,
+  76, 94, 92, 86, 82, 83, 90, 80, 68, 83,
+  87, 93, 84, 66, 88, 105, 93, 84, 89, 59,
+  98, 83, 52, 110, 85, 81, 86, 82, 85, 88,
+  74, 78, 104, 79, 73, 82, 78, 81, 85, 74,
+  89, 87, 57, 88, 94, 88, 84, 85, 81, 98,
+  83, 68, 92, 79, 77, 76, 97, 90, 83, 85,
+  88, 76, 82, 84, 85, 81, 95, 84, 86, 89,
+  90, 87, 85, 96, 82, 84, 83, 85, 73, 79,
+  90, 75, 84, 84, 80, 88, 80, 69, 86, 78,
+  100, 89, 84, 79, 87, 87, 75, 87, 77, 71,
+  84, 100, 78, 86, 82, 77, 83, 115, 86, 86,
+  84, 84, 83, 86, 94, 80, 67, 68, 83, 80,
+  80, 86, 82, 80, 87, 80, 73, 65, 84, 81,
+  91, 83, 86, 69, 87, 86, 84, 89, 85, 89,
+  88, 77, 79, 100, 70, 86, 85, 66, 89, 83,
+  74, 90, 81, 83, 74, 89, 80, 80, 85, 75,
+  99, 86, 74, 76, 81, 95, 79, 80, 97, 83,
+  69, 82, 91, 78, 78, 77, 83, 93, 80, 72,
+  91, 84, 83, 76, 89, 73, 70, 90, 89, 74,
+  84, 87, 91, 79, 95, 82, 85, 86, 89, 100,
+  93, 97, 85, 90, 71, 78, 71, 89, 87, 83,
+  86, 83, 81, 83, 88, 76, 85, 75, 89, 102,
+  90, 81, 86, 88, 84, 90, 76, 76, 87, 89,
+  85, 85, 73, 92, 72, 67, 95, 88, 86, 89,
+  86, 76, 83, 103, 77, 78, 92, 85, 96, 89,
+  76, 82, 84, 85, 78, 68, 80, 84, 82, 72,
+  78, 61, 88, 82, 95, 86, 87, 83, 80, 82,
+  77, 97, 82, 81, 92, 69, 91, 79, 78, 79,
+  87, 87, 83, 86, 85, 75, 78, 75, 107, 80,
+  67, 80, 86, 89, 74, 77, 96, 83, 52, 87,
+  91, 87, 76, 75, 78, 91, 86, 65, 95, 83,
+  74, 79, 95, 73, 73, 88, 88, 76, 89, 82,
+  84, 70, 92, 78, 83, 80, 93, 83, 89, 106,
+  81, 90, 80, 76, 73, 91, 91, 81, 87, 81,
+  75, 90, 87, 80, 78, 73, 101, 103, 92, 96,
+  74, 82, 90, 88, 69, 69, 83, 89, 87, 82,
+  75, 93, 74, 87, 94, 84, 87, 82, 86, 74,
+  80, 99, 67, 70, 87, 76, 80, 83, 76, 83,
+  86, 92, 75, 63, 82, 95, 78, 80, 81, 62,
+  85, 84, 85, 90, 97, 88, 81, 76, 79, 94,
+  75, 82, 89, 66, 94, 78, 73, 86, 87, 83,
+  90, 84, 80, 77, 87, 78, 93, 89, 75, 75,
+  79, 84, 79, 83, 92, 84, 72, 84, 86, 79,
+  82, 79, 91, 92, 78, 73, 84, 81, 86, 82,
+  88, 80, 79, 86, 93, 77, 86, 87, 87, 78,
+  89, 77, 83, 81, 87, 82, 93, 95, 82, 89,
+  75, 78, 75, 83, 85, 80, 87, 85, 81, 82,
+  84, 77, 86, 76, 97, 96, 85, 86, 80, 94,
+  80, 94, 73, 76, 85, 101, 86, 83, 70, 91,
+  77, 92, 92, 86, 84, 87, 86, 81, 85, 83,
+  82, 77, 83, 84, 97, 88, 72, 86, 84, 83,
+  80, 70, 89, 78, 85, 69, 81, 60, 89, 85,
+  93, 91, 86, 84, 81, 85, 79, 96, 71, 80,
+  86, 70, 87, 77, 82, 76, 78, 86, 89, 93,
+  77, 75, 85, 89, 75, 71, 90, 76, 103, 70,
+  76, 82, 86, 78, 86, 82, 92, 92, 90, 79,
+  83, 74, 98, 71, 101, 85, 90, 93, 72, 87,
+  79, 89, 83, 91, 85, 80, 81, 72, 89, 74,
+  72, 67, 94, 95, 83, 71, 85, 92, 66, 96,
+  79, 90, 73, 90, 79, 86, 87, 93, 87, 79,
+  84, 76, 91, 91, 82, 87, 84, 93, 92, 79,
+  77, 70, 77, 78, 84, 80, 80, 84, 67, 88,
+  67, 79, 79, 82, 83, 89, 76, 81, 65, 97,
+  80, 77, 85, 72, 90, 71, 74, 88, 96, 85,
+  89, 88, 85, 91, 91, 80, 93, 88, 156, 81,
+  100, 81, 90, 69, 81, 100, 94, 90, 87, 108,
+  92, 84, 90, 78, 80, 88, 86, 93, 80, 74,
+  85, 79, 77, 56, 85, 80, 114, 79, 81, 81,
+  91, 81, 82, 78, 98, 88, 81, 78, 87, 69,
+  95, 63, 102, 87, 96, 101, 73, 87, 82, 81,
+  88, 89, 78, 86, 84, 73, 95, 77, 71, 63,
+  95, 80, 80, 67, 83, 93, 67, 99, 74, 90,
+  75, 92, 82, 86, 83, 85, 83, 78, 72, 70,
+  87, 81, 78, 81, 85, 94, 86, 80, 79, 64,
+  74, 83, 88, 79, 85, 79, 69, 81, 64, 77,
+  79, 75, 83, 97, 72, 82, 68, 89, 78, 81,
+  86, 69, 96, 71, 64, 82, 84, 84, 91, 86,
+  79, 90, 91, 84, 96, 88, 156, 82, 100, 79,
+  79, 69, 78, 103, 87, 97, 84, 111, 89, 80,
+  92, 69, 77, 90, 86, 92, 78, 82, 87, 88,
+  75, 73, 91, 80, 103, 84, 76, 82, 84, 78,
+  82, 77, 87, 89, 83, 80, 84, 75, 95, 72,
+  95, 78, 90, 95, 72, 87, 80, 96, 85, 92,
+  68, 80, 84, 77, 93, 76, 78, 74, 93, 78,
+  80, 72, 81, 93, 66, 94, 80, 92, 72, 88,
+  80, 86, 93, 96, 86, 80, 79, 77, 92, 87,
+  79, 81, 94, 93, 93, 79, 81, 75, 75, 96,
+  88, 83, 83, 87, 71, 91, 71, 73, 81, 78,
+  87, 93, 78, 87, 65, 95, 88, 82, 86, 78,
+  82, 73, 71, 88, 95, 85, 88, 89, 77, 95,
+  92, 79, 92, 91, 145, 86, 96, 76, 88, 70,
+  81, 97, 82, 85, 86, 104, 89, 84, 91, 79,
+  80, 81, 92, 86, 80, 83, 80, 90, 71, 58,
+  92, 76, 102, 76, 85, 80, 92, 78, 88, 79,
+  96, 87, 81, 76, 85, 81, 86, 71, 95, 84,
+  93, 92, 76, 93, 83, 82, 78, 86, 73, 84,
+  82, 77, 87, 72, 78, 65, 99, 97, 81, 64,
+  88, 84, 71, 96, 79, 92, 77, 93, 79, 90,
+  79, 83, 81, 79, 79, 75, 94, 81, 91, 78,
+  87, 86, 86, 83, 78, 73, 78, 74, 78, 94,
+  77, 89, 68, 78, 64, 77, 81, 79, 77, 86,
+  79, 79, 75, 92, 74, 80, 77, 73, 91, 74,
+  65, 92, 71, 87, 84, 93, 89, 83, 77, 89,
+  90, 82, 153, 76, 89, 78, 79, 78, 87, 89,
+  94, 94, 88, 107, 91, 81, 88, 76, 85, 85,
+  83, 66, 86, 78, 75, 79, 70, 40, 90, 77,
+  96, 73, 87, 72, 99, 83, 87, 79, 96, 85,
+  79, 73, 84, 78, 78, 64, 96, 85, 91, 98,
+  76, 89, 83, 74, 85, 87, 73, 83, 86, 78,
+  95, 75, 80, 60, 91, 75, 82, 55, 86, 81,
+  72, 103, 79, 89, 84, 90, 84, 89, 73, 82,
+  82, 79, 73, 74, 93, 79, 85, 80, 82, 89,
+  83, 85, 76, 67, 75, 80, 81, 98, 79, 87,
+  68, 77, 63, 80, 76, 77, 77, 90, 75, 77,
+  78, 82, 69, 88, 77, 69, 95, 77, 61, 85,
+  53, 86, 85, 92, 79, 82, 72, 94, 89, 89,
+  141, 74, 94, 77, 74, 79, 86, 89, 84, 99,
+  77, 99, 84, 76, 99, 69, 78, 93, 89, 89,
+  81, 83, 84, 83, 71, 62, 94, 79, 93, 75,
+  84, 83, 87, 75, 85, 78, 85, 83, 84, 79,
+  84, 78, 85, 72, 88, 79, 87, 94, 78, 90,
+  79, 87, 79, 87, 75, 82, 84, 81, 96, 75,
+  82, 70, 94, 75, 79, 66, 82, 83, 69, 91,
+  79, 87, 76, 91, 82, 88, 78, 85, 83, 76,
+  76, 74, 93, 80, 92, 78, 86, 85, 84, 81,
+  79, 77, 76, 98, 82, 91, 81, 92, 76, 88,
+  67, 76, 75, 78, 81, 91, 82, 78, 71, 94,
+  77, 84, 78, 79, 88, 78, 66, 84, 69, 86,
+  84, 91, 82, 87, 81, 88, 88, 85, 135, 85,
+  89, 78, 90, 77, 86, 89, 86, 89, 86, 104,
+  86, 80, 91, 79, 81, 83, 91, 120, 85, 83,
+  74, 100, 75, 75, 88, 83, 100, 86, 77, 82,
+  85, 73, 83, 85, 91, 87, 84, 84, 84, 81,
+  91, 80, 91, 81, 85, 85, 74, 106, 78, 86,
+  80, 87, 71, 88, 87, 80, 86, 72, 79, 81,
+  95, 100, 76, 75, 82, 87, 75, 90, 78, 92,
+  72, 90, 84, 86, 77, 76, 86, 78, 87, 79,
+  93, 86, 92, 90, 93, 87, 89, 83, 78, 76,
+  83, 76, 84, 89, 82, 82, 65, 84, 70, 93,
+  82, 82, 85, 93, 78, 90, 76, 94, 98, 77,
+  72, 76, 82, 70, 71, 93, 82, 86, 86, 88,
+  86, 81, 79, 87, 81, 77, 155, 85, 89, 82,
+  77, 80, 84, 88, 88, 88, 85, 119, 93, 93,
+  88, 81, 87, 88, 89, 104, 90, 77, 72, 93,
+  78, 62, 94, 83, 100, 77, 81, 80, 95, 75,
+  89, 84, 91, 83, 82, 82, 82, 79, 85, 80,
+  93, 81, 85, 92, 78, 99, 74, 80, 83, 93,
+  76, 88, 85, 81, 91, 75, 81, 75, 85, 81,
+  76, 73, 83, 84, 74, 92, 78, 86, 74, 90,
+  83, 86, 71, 74, 86, 79, 74, 71, 97, 86,
+  86, 90, 82, 90, 82, 86, 76, 74, 80, 84,
+  87, 93, 81, 81, 68, 83, 68, 97, 80, 82,
+  83, 95, 83, 86, 79, 88, 88, 78, 79, 73,
+  88, 74, 67, 87, 63, 83, 83, 83, 80, 81,
+  77, 91, 78, 83, 148, 79, 87, 82, 75, 81,
+  83, 87, 86, 92, 85, 112, 89, 87, 93, 81,
+  80, 88, 97, 119, 84, 83, 76, 93, 76, 77,
+  93, 86, 96, 73, 77, 82, 81, 71, 84, 84,
+  82, 85, 84, 86, 79, 78, 86, 80, 86, 79,
+  82, 91, 77, 94, 74, 94, 80, 90, 84, 86,
+  88, 81, 92, 73, 81, 81, 90, 76, 77, 77,
+  79, 88, 72, 86, 81, 87, 75, 91, 88, 84,
+  74, 79, 87, 80, 84, 76, 90, 87, 89, 92,
+  87, 86, 90, 82, 77, 80, 84, 98, 86, 86,
+  83, 84, 73, 90, 72, 92, 77, 83, 83, 94,
+  80, 86, 71, 96, 89, 76, 75, 76, 84, 74,
+  74, 84, 77, 83, 85, 87, 82, 83, 82, 86,
+  80, 81, 136, 87, 88, 87, 92, 79, 81, 91,
+  87, 89, 87, 117, 86, 92, 89, 85, 76, 76,
+  92, 83, 83, 99, 101, 79, 84, 48, 87, 83,
+  93, 80, 87, 89, 88, 82, 93, 86, 91, 87,
+  78, 92, 82, 83, 77, 82, 91, 77, 79, 76,
+  83, 92, 92, 90, 87, 97, 75, 87, 81, 75,
+  89, 85, 81, 86, 76, 103, 63, 92, 83, 91,
+  73, 80, 75, 86, 65, 95, 68, 105, 90, 79,
+  81, 89, 93, 89, 83, 81, 90, 92, 89, 80,
+  88, 85, 75, 70, 85, 85, 80, 82, 75, 96,
+  79, 85, 85, 77, 75, 76, 89, 81, 82, 85,
+  74, 90, 73, 89, 78, 92, 81, 89, 78, 77,
+  80, 90, 102, 79, 74, 83, 78, 76, 79, 81,
+  99, 91, 93, 78, 87, 109, 75, 74, 78, 83,
+  87, 78, 82, 78, 72, 105, 81, 80, 87, 75,
+  92, 81, 107, 85, 85, 48, 98, 81, 91, 73,
+  93, 81, 94, 84, 85, 87, 83, 82, 86, 99,
+  85, 79, 72, 74, 84, 82, 75, 77, 95, 81,
+  96, 72, 91, 75, 76, 85, 87, 81, 90, 84,
+  91, 81, 81, 90, 69, 95, 87, 95, 70, 87,
+  77, 81, 70, 97, 74, 101, 84, 84, 77, 91,
+  94, 98, 87, 84, 90, 91, 79, 83, 91, 79,
+  75, 72, 85, 86, 78, 93, 78, 88, 81, 75,
+  86, 85, 76, 76, 90, 80, 79, 75, 75, 85,
+  77, 89, 83, 95, 80, 101, 82, 85, 73, 86,
+  93, 81, 83, 90, 95, 82, 83, 84, 97, 70,
+  95, 86, 89, 111, 71, 81, 87, 85, 85, 79,
+  87, 77, 60, 102, 86, 72, 90, 79, 84, 95,
+  94, 83, 79, 60, 96, 83, 80, 74, 78, 80,
+  93, 92, 92, 82, 85, 81, 80, 86, 95, 75,
+  71, 55, 76, 86, 83, 77, 90, 85, 87, 76,
+  92, 77, 83, 80, 83, 96, 90, 81, 87, 87,
+  83, 92, 73, 88, 85, 90, 68, 90, 75, 81,
+  70, 98, 73, 93, 89, 87, 78, 99, 104, 107,
+  85, 86, 91, 87, 81, 86, 86, 76, 76, 77,
+  86, 82, 72, 84, 73, 83, 83, 75, 89, 88,
+  77, 76, 86, 80, 81, 90, 82, 87, 89, 87,
+  83, 89, 81, 94, 90, 78, 81, 86, 95, 77,
+  77, 89, 87, 79, 82, 85, 92, 74, 93, 81,
+  99, 95, 76, 85, 93, 85, 79, 82, 85, 81,
+  82, 93, 76, 79, 87, 109, 80, 93, 81, 75,
+  93, 70, 67, 85, 67, 92, 76, 102, 67, 76,
+  92, 88, 85, 84, 76, 98, 78, 84, 98, 93,
+  109, 69, 94, 71, 62, 103, 78, 95, 77, 150,
+  80, 69, 92, 58, 86, 84, 71, 97, 73, 98,
+  75, 79, 77, 77, 82, 70, 89, 96, 70, 88,
+  73, 74, 108, 81, 86, 83, 78, 75, 86, 86,
+  80, 86, 99, 72, 87, 100, 73, 75, 87, 76,
+  71, 54, 88, 86, 59, 82, 77, 85, 74, 95,
+  79, 87, 75, 110, 71, 91, 83, 85, 74, 77,
+  82, 64, 62, 87, 86, 86, 77, 86, 80, 80,
+  64, 77, 77, 92, 99, 113, 82, 78, 81, 97,
+  93, 71, 66, 79, 74, 82, 84, 87, 94, 89,
+  75, 84, 85, 105, 88, 78, 93, 85, 91, 61,
+  75, 79, 81, 79, 85, 107, 80, 71, 80, 80,
+  83, 82, 84, 109, 77, 93, 84, 93, 95, 71,
+  84, 70, 78, 92, 83, 80, 69, 145, 75, 82,
+  94, 63, 78, 84, 73, 91, 74, 92, 80, 89,
+  83, 85, 86, 75, 81, 88, 70, 94, 73, 85,
+  91, 77, 79, 83, 83, 82, 93, 75, 85, 83,
+  82, 73, 93, 91, 74, 72, 83, 82, 71, 75,
+  88, 88, 61, 79, 75, 92, 74, 87, 87, 83,
+  81, 88, 71, 93, 68, 88, 73, 79, 81, 83,
+  67, 80, 78, 82, 84, 91, 82, 83, 69, 91,
+  81, 80, 102, 78, 84, 76, 90, 101, 86, 75,
+  74, 82, 88, 79, 92, 77, 73, 94, 88, 84,
+  89, 91, 88, 82, 95, 87, 85, 60, 85, 82,
+  77, 82, 75, 94, 88, 79, 87, 77, 82, 80,
+  81, 94, 87, 84, 80, 67, 79, 76, 86, 77,
+  88, 88, 84, 78, 80, 102, 86, 87, 94, 77,
+  82, 80, 83, 93, 79, 82, 81, 86, 85, 91,
+  80, 80, 80, 87, 73, 100, 75, 88, 88, 88,
+  84, 89, 91, 99, 90, 80, 92, 86, 84, 78,
+  89, 80, 79, 76, 87, 81, 76, 81, 81, 82,
+  67, 75, 79, 96, 78, 85, 93, 75, 83, 89,
+  81, 95, 80, 90, 77, 83, 80, 92, 77, 80,
+  84, 81, 96, 85, 83, 87, 77, 83, 84, 82,
+  92, 76, 88, 82, 96, 90, 89, 84, 90, 83,
+  85, 79, 94, 82, 93, 88, 106, 78, 82, 98,
+  79, 71, 78, 69, 87, 80, 71, 108, 71, 99,
+  68, 76, 77, 84, 125, 92, 86, 89, 78, 67,
+  92, 80, 102, 79, 105, 64, 114, 88, 77, 108,
+  74, 81, 86, 88, 91, 60, 82, 57, 105, 89,
+  94, 89, 84, 92, 74, 78, 87, 80, 83, 80,
+  94, 88, 91, 77, 88, 74, 105, 66, 94, 89,
+  58, 81, 66, 99, 69, 79, 83, 87, 81, 96,
+  74, 79, 96, 81, 79, 61, 96, 83, 92, 80,
+  87, 70, 76, 101, 87, 89, 79, 90, 85, 97,
+  92, 80, 83, 83, 74, 53, 63, 66, 86, 87,
+  46, 72, 94, 84, 91, 79, 83, 94, 75, 115,
+  86, 104, 85, 64, 91, 88, 81, 84, 65, 77,
+  79, 114, 98, 89, 84, 76, 76, 111, 73, 97,
+  77, 68, 84, 78, 69, 94, 64, 89, 73, 92,
+  74, 71, 104, 92, 95, 80, 75, 79, 79, 85,
+  96, 83, 93, 70, 99, 74, 66, 100, 83, 83,
+  88, 106, 87, 72, 83, 65, 87, 82, 81, 89,
+  77, 93, 80, 82, 83, 77, 83, 74, 85, 87,
+  93, 75, 88, 67, 95, 70, 91, 72, 63, 78,
+  71, 93, 67, 74, 94, 86, 85, 89, 69, 83,
+  94, 80, 76, 69, 92, 75, 79, 83, 79, 71,
+  72, 95, 84, 92, 73, 90, 81, 92, 86, 79,
+  82, 76, 70, 68, 70, 79, 88, 83, 49, 72,
+  84, 84, 76, 77, 79, 88, 81, 101, 82, 90,
+  88, 72, 83, 92, 82, 84, 67, 79, 76, 103,
+  94, 85, 95, 75, 82, 101, 80, 89, 90, 81,
+  78, 70, 78, 85, 80, 88, 68, 93, 82, 76,
+  98, 84, 87, 83, 79, 82, 80, 87, 89, 74,
+  78, 76, 91, 77, 80, 95, 78, 85, 87, 80,
+  78, 97, 84, 76, 87, 79, 89, 90, 83, 93,
+  80, 85, 83, 91, 83, 76, 84, 89, 88, 80,
+  85, 78, 95, 78, 88, 69, 76, 82, 77, 86,
+  85, 84, 93, 87, 86, 84, 72, 79, 87, 75,
+  79, 79, 86, 72, 81, 76, 82, 76, 76, 83,
+  90, 81, 83, 85, 84, 91, 85, 80, 85, 76,
+  72, 85, 78, 96, 91, 79, 67, 84, 84, 84,
+  83, 81, 83, 84, 86, 90, 81, 87, 83, 81,
+  93, 96, 98, 81, 86, 87, 86, 95, 84, 86,
+  88, 79, 97, 79, 58, 102, 79, 88, 94, 85,
+  72, 81, 77, 89, 55, 71, 85, 103, 85, 96,
+  78, 76, 122, 82, 82, 77, 89, 99, 98, 72,
+  76, 83, 77, 78, 84, 92, 76, 79, 70, 77,
+  70, 101, 87, 62, 92, 83, 83, 109, 80, 80,
+  93, 68, 80, 69, 90, 65, 95, 68, 79, 76,
+  80, 88, 72, 75, 62, 82, 79, 98, 81, 87,
+  63, 101, 72, 84, 84, 85, 94, 102, 69, 95,
+  79, 86, 84, 99, 80, 80, 86, 93, 72, 79,
+  94, 73, 79, 73, 94, 98, 79, 68, 83, 69,
+  74, 84, 89, 104, 86, 82, 63, 70, 79, 78,
+  92, 73, 87, 102, 77, 130, 102, 88, 75, 88,
+  75, 71, 84, 66, 81, 88, 86, 84, 101, 75,
+  112, 94, 90, 96, 86, 89, 89, 80, 78, 75,
+  101, 96, 73, 88, 85, 90, 95, 84, 91, 78,
+  97, 80, 87, 90, 82, 94, 84, 107, 90, 89,
+  85, 88, 80, 86, 86, 81, 81, 84, 79, 91,
+  88, 78, 81, 72, 90, 102, 77, 78, 83, 92,
+  87, 79, 77, 74, 76, 83, 82, 83, 72, 71,
+  79, 83, 79, 79, 66, 82, 84, 106, 62, 84,
+  80, 88, 78, 89, 77, 79, 76, 90, 86, 89,
+  83, 87, 88, 81, 96, 98, 82, 79, 82, 76,
+  82, 82, 89, 88, 77, 75, 82, 75, 88, 67,
+  80, 98, 84, 72, 75, 85, 79, 81, 94, 70,
+  86, 80, 95, 92, 94, 89, 79, 77, 101, 73,
+  98, 87, 97, 90, 90, 82, 96, 65, 91, 78,
+  98, 80, 81, 96, 78, 77, 85, 76, 89, 84,
+  95, 83, 84, 82, 79, 74, 96, 83, 84, 79,
+  82, 81, 82, 71, 71, 102, 94, 84, 88, 89,
+  96, 83, 92, 79, 93, 89, 86, 81, 83, 84,
+  84, 77, 90, 80, 78, 76, 74, 105, 86, 86,
+  72, 75, 77, 95, 93, 78, 79, 89, 86, 88,
+  81, 93, 88, 83, 88, 88, 81, 78, 91, 83,
+  83, 77, 78, 88, 87, 82, 90, 86, 85, 78,
+  86, 84, 86, 75, 102, 79, 75, 88, 83, 90,
+  99, 84, 78, 84, 77, 87, 86, 72, 77, 89,
+  82, 84, 81, 87, 78, 86, 89, 76, 85, 85,
+  84, 86, 84, 84, 76, 87, 105, 94, 81, 86,
+  98, 90, 87, 94, 83, 72, 63, 76, 65, 102,
+  78, 86, 79, 86, 72, 82, 71, 66, 64, 68,
+  81, 105, 82, 100, 75, 68, 108, 81, 89, 81,
+  91, 98, 116, 53, 70, 72, 80, 85, 151, 106,
+  92, 77, 61, 75, 69, 104, 92, 61, 78, 107,
+  74, 78, 83, 76, 77, 59, 81, 73, 82, 68,
+  100, 53, 79, 71, 73, 104, 69, 71, 66, 78,
+  54, 92, 92, 64, 99, 92, 83, 80, 91, 88,
+  90, 143, 87, 98, 78, 76, 95, 87, 84, 74,
+  94, 105, 54, 89, 93, 77, 80, 77, 113, 93,
+  81, 69, 90, 71, 60, 55, 88, 105, 75, 73,
+  59, 63, 81, 81, 79, 79, 84, 113, 63, 117,
+  54, 81, 62, 78, 58, 67, 81, 67, 71, 70,
+  78, 83, 91, 68, 53, 103, 78, 96, 81, 85,
+  87, 88, 71, 81, 76, 86, 76, 82, 87, 91,
+  90, 83, 90, 60, 76, 85, 90, 82, 93, 104,
+  99, 58, 84, 75, 82, 113, 87, 76, 80, 90,
+  58, 66, 83, 91, 94, 75, 77, 83, 83, 72,
+  77, 69, 78, 64, 88, 77, 77, 106, 78, 69,
+  69, 87, 83, 84, 76, 75, 81, 69, 69, 97,
+  106, 85, 96, 82, 74, 92, 80, 91, 87, 95,
+  94, 87, 81, 83, 80, 57, 88, 89, 100, 105,
+  77, 74, 86, 108, 84, 82, 103, 93, 83, 75,
+  84, 70, 73, 98, 85, 99, 91, 92, 77, 76,
+  79, 77, 79, 82, 85, 79, 89, 110, 61, 93,
+  80, 74, 85, 64, 90, 85, 84, 79, 88, 70,
+  93, 74, 67, 83, 94, 70, 86, 97, 88, 75,
+  82, 83, 76, 91, 93, 91, 87, 81, 92, 74,
+  85, 77, 83, 86, 74, 80, 89, 85, 82, 73,
+  90, 82, 86, 92, 79, 72, 76, 85, 71, 84,
+  80, 81, 93, 82, 78, 76, 91, 84, 77, 77,
+  79, 84, 84, 85, 79, 85, 80, 93, 85, 81,
+  83, 91, 90, 74, 79, 83, 89, 81, 95, 86,
+  86, 78, 86, 90, 86, 78, 87, 73, 89, 80,
+  91, 82, 87, 73, 84, 90, 85, 76, 115, 79,
+  80, 98, 84, 90, 88, 81, 82, 84, 84, 83,
+  79, 99, 75, 88, 96, 92, 90, 86, 91, 89,
+  91, 74, 78, 82, 87, 93, 73, 88, 83, 88,
+  97, 84, 92, 83, 91, 86, 89, 93, 84, 101,
+  92, 79, 93, 86, 96, 93, 79, 81, 87, 78,
+  69, 80, 70, 78, 85, 104, 89, 96, 77, 63,
+  87, 77, 83, 88, 87, 87, 99, 106, 87, 90,
+  97, 80, 87, 75, 77, 90, 75, 82, 82, 84,
+  80, 88, 77, 95, 88, 88, 81, 75, 90, 89,
+  87, 88, 90, 80, 92, 86, 96, 68, 74, 77,
+  87, 77, 79, 80, 67, 77, 79, 84, 60, 75,
+  96, 76, 93, 95, 85, 67, 100, 85, 96, 93,
+  85, 88, 85, 83, 88, 90, 98, 96, 99, 73,
+  81, 81, 95, 84, 85, 79, 94, 83, 65, 76,
+  83, 100, 74, 70, 65, 87, 91, 87, 85, 73,
+  83, 92, 84, 96, 56, 74, 76, 78, 68, 75,
+  99, 83, 91, 80, 83, 84, 91, 85, 75, 82,
+  80, 100, 82, 90, 85, 92, 73, 84, 66, 87,
+  64, 71, 84, 92, 85, 98, 81, 82, 91, 77,
+  82, 82, 93, 96, 92, 90, 86, 82, 86, 96,
+  82, 93, 86, 81, 66, 75, 84, 84, 84, 78,
+  78, 89, 83, 119, 86, 69, 81, 86, 85, 79,
+  82, 88, 86, 76, 76, 77, 88, 96, 81, 76,
+  80, 81, 55, 89, 80, 76, 84, 86, 87, 83,
+  82, 96, 84, 70, 102, 88, 88, 84, 81, 78,
+  84, 85, 92, 95, 77, 82, 97, 85, 79, 73,
+  97, 87, 86, 72, 82, 79, 68, 103, 88, 98,
+  83, 84, 72, 76, 90, 82, 85, 74, 84, 89,
+  77, 89, 76, 81, 78, 78, 79, 68, 93, 78,
+  87, 84, 84, 72, 84, 74, 72, 81, 89, 82,
+  82, 94, 92, 87, 83, 82, 84, 93, 76, 81,
+  81, 81, 86, 85, 85, 90, 89, 78, 80, 86,
+  86, 91, 78, 76, 87, 75, 79, 94, 91, 93,
+  83, 85, 75, 90, 87, 85, 93, 77, 93, 82,
+  84, 100, 86, 73, 86, 89, 79, 83, 78, 79,
+  83, 81, 81, 86, 84, 92, 80, 76, 79, 91,
+  77, 94, 80, 82, 91, 82, 82, 85, 80, 76,
+  89, 82, 83, 85, 91, 79, 87, 85, 80, 88,
+  94, 78, 86, 81, 89, 88, 84, 79, 92, 89,
+  84, 80, 83, 81, 77, 96, 80, 94, 89, 91,
+  86, 79, 93, 85, 88, 74, 78, 83, 82, 85,
+  89, 87, 86, 80, 91, 79, 87, 82, 88, 87,
+  86, 87, 89, 76, 77, 88, 86, 88, 99, 74,
+  70, 67, 89, 78, 87, 81, 83, 84, 88, 85,
+  65, 87, 89, 88, 88, 92, 95, 71, 83, 61,
+  85, 83, 88, 88, 85, 80, 99, 76, 94, 81,
+  82, 76, 72, 83, 77, 79, 101, 62, 87, 75,
+  66, 92, 83, 87, 84, 103, 91, 91, 66, 91,
+  85, 94, 96, 91, 76, 82, 82, 89, 89, 88,
+  74, 88, 65, 85, 98, 95, 81, 74, 78, 100,
+  80, 101, 83, 85, 98, 92, 83, 94, 84, 92,
+  98, 79, 85, 81, 77, 102, 80, 88, 93, 88,
+  74, 107, 84, 87, 92, 86, 89, 85, 70, 86,
+  81, 77, 79, 88, 84, 87, 92, 69, 68, 103,
+  72, 81, 85, 84, 77, 77, 75, 78, 82, 89,
+  76, 94, 90, 83, 94, 75, 97, 67, 71, 60,
+  74, 90, 99, 87, 82, 101, 82, 73, 61, 92,
+  100, 70, 86, 110, 86, 80, 89, 68, 92, 83,
+  96, 71, 75, 74, 89, 78, 85, 100, 94, 93,
+  79, 73, 73, 95, 88, 92, 81, 72, 79, 86,
+  80, 93, 82, 82, 81, 79, 60, 81, 93, 93,
+  87, 74, 76, 74, 79, 69, 79, 79, 65, 78,
+  78, 83, 76, 99, 89, 60, 76, 98, 82, 88,
+  83, 87, 85, 95, 71, 90, 86, 73, 96, 88,
+  71, 78, 77, 98, 69, 89, 87, 85, 92, 80,
+  77, 74, 74, 86, 103, 77, 54, 78, 67, 91,
+  100, 85, 73, 85, 83, 98, 69, 92, 74, 81,
+  84, 89, 77, 65, 83, 81, 82, 92, 80, 79,
+  101, 97, 92, 83, 78, 89, 86, 83, 83, 93,
+  77, 93, 64, 102, 89, 72, 105, 99, 65, 89,
+  80, 94, 80, 75, 100, 91, 86, 90, 97, 81,
+  76, 86, 70, 83, 92, 94, 90, 79, 85, 66,
+  77, 90, 79, 96, 87, 92, 90, 78, 82, 74,
+  77, 82, 100, 87, 85, 82, 69, 87, 92, 83,
+  96, 70, 63, 74, 69, 99, 83, 75, 80, 85,
+  86, 97, 84, 78, 84, 101, 79, 76, 84, 72,
+  77, 88, 68, 92, 99, 81, 85, 77, 82, 92,
+  76, 77, 103, 84, 90, 81, 92, 71, 84, 79,
+  89, 86, 88, 77, 71, 87, 67, 80, 93, 103,
+  86, 85, 88, 100, 101, 91, 84, 75, 79, 94,
+  78, 88, 88, 88, 88, 84, 73, 91, 76, 94,
+  85, 94, 100, 65, 69, 61, 75, 83, 88, 88,
+  86, 105, 86, 76, 56, 85, 109, 81, 87, 102,
+  78, 73, 90, 68, 95, 83, 93, 78, 79, 91,
+  91, 78, 75, 83, 82, 85, 78, 79, 76, 86,
+  87, 77, 78, 85, 80, 92, 84, 91, 91, 90,
+  85, 73, 66, 83, 93, 91, 89, 89, 77, 85,
+  74, 75, 91, 86, 71, 67, 74, 74, 93, 95,
+  80, 65, 82, 93, 79, 94, 86, 91, 90, 86,
+  77, 97, 87, 87, 98, 76, 75, 74, 90, 101,
+  64, 82, 85, 88, 84, 90, 75, 91, 77, 85,
+  95, 86, 64, 78, 74, 91, 82, 92, 83, 80,
+  84, 75, 62, 94, 77, 87, 82, 100, 82, 74,
+  82, 85, 83, 89, 72, 98, 86, 86, 80, 71,
+  79, 68, 68, 77, 67, 93, 94, 94, 74, 95,
+  78, 68, 73, 88, 112, 75, 103, 95, 63, 76,
+  93, 73, 115, 80, 105, 57, 59, 78, 81, 82,
+  76, 109, 88, 88, 91, 70, 71, 93, 79, 103,
+  67, 89, 91, 84, 74, 96, 83, 71, 88, 74,
+  73, 68, 98, 69, 87, 72, 84, 60, 60, 64,
+  69, 82, 65, 84, 74, 77, 64, 104, 83, 65,
+  83, 108, 73, 78, 85, 78, 74, 81, 63, 94,
+  92, 85, 78, 72, 64, 68, 77, 92, 72, 90,
+  84, 83, 107, 55, 70, 61, 73, 85, 88, 68,
+  67, 71, 52, 86, 103, 92, 76, 86, 82, 97,
+  98, 81, 77, 82, 67, 107, 65, 74, 84, 83,
+  93, 85, 86, 71, 74, 99, 83, 79, 69, 91,
+  89, 91, 86, 82, 71, 90, 56, 80, 85, 82,
+  121, 95, 69, 90, 82, 76, 76, 77, 93, 100,
+  101, 88, 87, 96, 86, 83, 61, 79, 87, 85,
+  80, 65, 90, 65, 78, 85, 84, 99, 89, 90,
+  88, 69, 86, 78, 79, 88, 118, 88, 111, 65,
+  82, 85, 89, 88, 96, 55, 51, 81, 59, 111,
+  80, 72, 82, 70, 85, 91, 85, 96, 86, 101,
+  75, 75, 82, 67, 74, 73, 63, 82, 106, 92,
+  69, 75, 96, 84, 73, 73, 123, 96, 92, 84,
+  99, 72, 77, 83, 95, 85, 71, 80, 88, 90,
+  84, 72, 81, 96, 95, 79, 75, 89, 106, 80,
+  93, 69, 77, 88, 76, 102, 93, 82, 102, 76,
+  77, 91, 79, 101, 78, 86, 88, 70, 71, 71,
+  74, 80, 94, 97, 75, 86, 82, 78, 80, 84,
+  106, 89, 78, 96, 75, 75, 100, 77, 83, 84,
+  90, 80, 73, 95, 95, 80, 82, 92, 79, 90,
+  80, 73, 83, 83, 77, 87, 80, 70, 83, 83,
+  90, 88, 86, 89, 94, 85, 80, 82, 97, 79,
+  86, 89, 86, 91, 85, 73, 77, 81, 74, 81,
+  87, 77, 91, 91, 78, 73, 85, 106, 82, 81,
+  82, 85, 92, 87, 81, 89, 86, 89, 89, 85,
+  88, 71, 85, 93, 73, 81, 85, 90, 87, 86,
+  71, 94, 88, 83, 84, 92, 65, 88, 84, 82,
+  76, 99, 79, 81, 94, 87, 78, 87, 78, 87,
+  75, 101, 73, 74, 92, 89, 90, 82, 81, 99,
+  75, 92, 72, 82, 82, 78, 75, 84, 74, 93,
+  96, 92, 66, 72, 72, 79, 97, 89, 102, 88,
+  80, 91, 68, 76, 95, 87, 103, 87, 95, 77,
+  68, 80, 76, 80, 78, 108, 90, 81, 101, 70,
+  76, 87, 78, 98, 71, 71, 86, 83, 83, 93,
+  83, 84, 102, 90, 96, 70, 97, 73, 90, 74,
+  86, 82, 70, 77, 72, 87, 72, 82, 84, 68,
+  69, 100, 82, 80, 79, 100, 83, 69, 83, 86,
+  85, 90, 71, 86, 91, 91, 76, 76, 85, 72,
+  84, 86, 93, 94, 94, 84, 116, 69, 73, 78,
+  88, 84, 70, 75, 84, 87, 81, 80, 80, 96,
+  79, 79, 83, 86, 107, 82, 85, 85, 62, 92,
+  62, 77, 84, 83, 99, 88, 77, 90, 67, 87,
+  76, 104, 82, 93, 86, 91, 83, 80, 80, 95,
+  59, 84, 74, 88, 105, 86, 71, 85, 70, 91,
+  78, 97, 83, 110, 72, 86, 83, 102, 91, 87,
+  64, 79, 87, 82, 71, 72, 88, 72, 79, 90,
+  89, 93, 104, 81, 83, 73, 95, 75, 77, 88,
+  103, 86, 103, 81, 85, 90, 83, 79, 91, 62,
+  64, 99, 74, 98, 83, 69, 93, 69, 82, 89,
+  96, 92, 70, 85, 81, 82, 89, 90, 79, 82,
+  82, 85, 92, 85, 86, 84, 87, 82, 82, 74,
+  109, 90, 87, 85, 107, 83, 78, 94, 89, 87,
+  66, 78, 91, 92, 88, 85, 77, 82, 85, 77,
+  75, 92, 83, 85, 95, 74, 79, 74, 79, 99,
+  91, 77, 89, 89, 93, 88, 83, 88, 85, 87,
+  84, 93, 88, 86, 89, 87, 72, 85, 77, 90,
+  74, 74, 87, 81, 87, 84, 84, 89, 81, 78,
+  85, 89, 87, 93, 84, 89, 80, 92, 78, 84,
+  88, 90, 92, 77, 87, 81, 79, 87, 79, 92,
+  79, 89, 93, 76, 86, 84, 80, 75, 93, 83,
+  81, 86, 88, 83, 83, 77, 94, 77, 81, 73,
+  84, 73, 78, 80, 107, 95, 90, 105, 81, 90,
+  82, 88, 77, 76, 93, 95, 93, 84, 75, 87,
+  91, 100, 91, 66, 80, 87, 92, 85, 92, 77,
+  84, 86, 74, 86, 74, 82, 88, 92, 82, 88,
+  74, 94, 78, 85, 90, 81, 76, 83, 93, 97,
+  97, 82, 80, 79, 84, 85, 85, 81, 77, 88,
+  86, 84, 79, 91, 78, 82, 81, 77, 101, 97,
+  91, 79, 93, 89, 79, 83, 88, 102, 87, 86,
+  92, 82, 89, 76, 82, 88, 89, 90, 80, 84,
+  79, 89, 86, 87, 91, 80, 74, 80, 69, 81,
+  82, 81, 87, 71, 77, 91, 74, 89, 85, 80,
+  80, 84, 86, 85, 81, 80, 83, 36, 89, 91,
+  88, 87, 76, 83, 92, 84, 79, 87, 84, 85,
+  80, 79, 96, 83, 93, 95, 87, 87, 82, 75,
+  80, 84, 88, 84, 94, 80, 84, 84, 88, 71,
+  88, 75, 79, 68, 86, 92, 74, 87, 84, 85,
+  87, 79, 65, 76, 84, 88, 79, 87, 84, 86,
+  80, 84, 90, 90, 83, 84, 99, 85, 83, 83,
+  86, 82, 87, 88, 83, 81, 78, 87, 83, 81,
+  87, 81, 83, 76, 82, 86, 104, 88, 74, 80,
+  87, 83, 79, 76, 91, 96, 83, 97, 81, 86,
+  86, 89, 84, 86, 92, 90, 76, 80, 75, 87,
+  82, 87, 94, 77, 81, 88, 80, 83, 90, 83,
+  85, 76, 78, 92, 78, 81, 92, 88, 81, 92,
+  82, 92, 76, 85, 85, 52, 90, 97, 86, 82,
+  77, 84, 88, 82, 93, 100, 86, 90, 86, 95,
+  108, 86, 86, 87, 91, 73, 80, 83, 86, 86,
+  88, 79, 87, 90, 88, 80, 86, 76, 82, 73,
+  77, 74, 87, 82, 81, 99, 85, 75, 93, 83,
+  76, 88, 83, 86, 85, 90, 97, 81, 72, 82,
+  88, 99, 81, 81, 98, 88, 81, 87, 89, 82,
+  83, 90, 77, 73, 87, 85, 82, 81, 88, 76,
+  68, 83, 91, 78, 68, 80, 91, 84, 73, 87,
+  64, 66, 76, 70, 69, 74, 76, 90, 83, 83,
+  86, 99, 94, 77, 92, 86, 112, 82, 74, 92,
+  71, 85, 71, 79, 98, 83, 91, 87, 79, 88,
+  87, 82, 85, 109, 84, 91, 91, 70, 84, 89,
+  89, 73, 100, 166, 82, 63, 88, 80, 96, 82,
+  87, 67, 66, 62, 68, 86, 86, 103, 80, 89,
+  80, 81, 89, 82, 79, 94, 83, 78, 80, 87,
+  89, 83, 64, 84, 91, 108, 73, 81, 79, 91,
+  90, 74, 106, 79, 80, 87, 79, 87, 86, 88,
+  89, 95, 97, 84, 71, 92, 79, 80, 80, 69,
+  76, 94, 79, 100, 76, 80, 77, 78, 81, 79,
+  74, 72, 85, 83, 88, 80, 74, 80, 59, 86,
+  81, 83, 70, 85, 96, 87, 80, 76, 67, 65,
+  76, 74, 80, 65, 79, 85, 79, 69, 81, 90,
+  85, 75, 94, 88, 110, 83, 75, 85, 69, 90,
+  70, 75, 96, 86, 94, 75, 87, 88, 89, 84,
+  80, 100, 77, 85, 93, 64, 84, 87, 85, 69,
+  95, 171, 74, 65, 85, 79, 86, 76, 84, 67,
+  64, 62, 72, 72, 85, 97, 112, 77, 88, 89,
+  83, 81, 85, 90, 86, 79, 77, 89, 91, 80,
+  73, 85, 89, 110, 77, 69, 73, 96, 86, 77,
+  102, 74, 83, 85, 79, 85, 78, 101, 90, 92,
+  81, 82, 65, 92, 75, 76, 79, 73, 75, 87,
+  67, 89, 69, 76, 79, 80, 80, 83, 75, 74,
+  76, 81, 82, 77, 82, 83, 73, 87, 87, 75,
+  84, 91, 97, 88, 85, 80, 84, 70, 83, 100,
+  91, 73, 86, 81, 84, 89, 83, 89, 81, 82,
+  85, 86, 83, 85, 83, 87, 82, 85, 65, 80,
+  85, 89, 87, 96, 87, 83, 87, 84, 76, 85,
+  78, 91, 88, 80, 79, 94, 85, 78, 83, 82,
+  80, 83, 88, 89, 77, 83, 83, 73, 77, 82,
+  82, 77, 79, 82, 78, 82, 94, 96, 84, 81,
+  83, 77, 80, 83, 83, 78, 95, 87, 81, 88,
+  88, 85, 76, 70, 77, 75, 83, 87, 83, 83,
+  87, 89, 83, 80, 72, 84, 87, 88, 82, 70,
+  79, 79, 70, 83, 83, 77, 80, 83, 70, 85,
+  79, 78, 85, 80, 76, 91, 91, 81, 80, 83,
+  85, 84, 79, 77, 79, 80, 89, 75, 86, 82,
+  89, 84, 85, 91, 83, 74, 84, 84, 76, 98,
+  85, 84, 92, 87, 86, 88, 96, 87, 73, 80,
+  77, 81, 90, 91, 90, 78, 71, 86, 75, 88,
+  78, 94, 81, 74, 77, 82, 84, 95, 90, 85,
+  79, 92, 86, 94, 88, 85, 88, 60, 77, 84,
+  83, 88, 90, 93, 92, 93, 81, 82, 93, 93,
+  83, 82, 62, 80, 83, 84, 74, 85, 77, 81,
+  59, 79, 93, 78, 89, 90, 79, 86, 93, 69,
+  73, 88, 95, 80, 84, 94, 87, 89, 76, 94,
+  81, 79, 76, 56, 83, 91, 84, 81, 83, 87,
+  73, 79, 80, 86, 80, 82, 97, 85, 83, 88,
+  88, 68, 89, 84, 89, 79, 91, 85, 83, 80,
+  73, 87, 70, 80, 84, 73, 74, 82, 92, 90,
+  79, 91, 69, 86, 78, 71, 74, 76, 88, 88,
+  84, 74, 92, 94, 96, 87, 82, 85, 94, 82,
+  82, 96, 77, 73, 84, 86, 79, 85, 84, 79,
+  79, 78, 76, 78, 83, 94, 80, 78, 85, 78,
+  92, 83, 88, 84, 94, 105, 79, 80, 90, 79,
+  93, 87, 89, 84, 70, 66, 79, 94, 91, 86,
+  64, 77, 89, 76, 81, 90, 84, 83, 73, 79,
+  83, 91, 90, 91, 75, 83, 88, 95, 81, 89,
+  97, 80, 91, 85, 92, 82, 81, 92, 80, 82,
+  79, 72, 90, 93, 88, 82, 75, 86, 91, 79,
+  83, 82, 83, 83, 86, 88, 75, 82, 75, 73,
+  82, 84, 82, 79, 84, 86, 87, 76, 79, 79,
+  74, 80, 83, 89, 66, 86, 87, 91, 78, 91,
+  71, 83, 66, 72, 75, 64, 80, 94, 82, 73,
+  99, 90, 85, 78, 93, 88, 90, 96, 78, 93,
+  73, 82, 81, 92, 104, 83, 97, 84, 80, 82,
+  85, 76, 79, 89, 71, 95, 101, 75, 87, 76,
+  82, 84, 85, 139, 80, 71, 88, 76, 86, 84,
+  86, 74, 81, 65, 75, 79, 89, 100, 80, 84,
+  88, 76, 79, 88, 84, 91, 93, 82, 77, 92,
+  94, 98, 72, 91, 87, 109, 83, 75, 87, 87,
+  87, 80, 97, 78, 88, 86, 72, 88, 86, 88,
+  91, 93, 93, 79, 74, 80, 86, 75, 84, 75,
+  78, 89, 77, 94, 85, 75, 69, 84, 83, 86,
+  81, 74, 78, 89, 87, 89, 76, 74, 89, 89,
+  79, 80, 70, 76, 72, 76, 69, 93, 79, 101,
+  69, 83, 81, 68, 84, 81, 83, 101, 95, 81,
+  82, 94, 80, 78, 100, 86, 122, 98, 82, 93,
+  90, 85, 86, 82, 95, 84, 80, 89, 74, 93,
+  74, 68, 80, 81, 88, 83, 87, 73, 78, 87,
+  80, 87, 80, 78, 83, 73, 81, 87, 88, 83,
+  90, 70, 83, 98, 89, 86, 79, 84, 64, 98,
+  80, 84, 70, 89, 89, 70, 82, 76, 60, 100,
+  95, 84, 90, 98, 74, 81, 72, 78, 94, 77,
+  86, 81, 81, 101, 97, 68, 81, 91, 72, 75,
+  82, 83, 87, 80, 72, 95, 82, 91, 89, 79,
+  73, 83, 81, 84, 98, 93, 75, 141, 76, 88,
+  73, 89, 94, 77, 87, 73, 82, 82, 85, 88,
+  75, 78, 75, 75, 61, 97, 81, 92, 72, 85,
+  89, 71, 84, 84, 82, 101, 84, 77, 82, 100,
+  73, 75, 107, 90, 134, 94, 80, 86, 89, 83,
+  86, 76, 92, 89, 80, 91, 83, 98, 77, 71,
+  84, 77, 78, 82, 94, 81, 80, 91, 78, 82,
+  78, 81, 86, 66, 77, 79, 91, 79, 83, 75,
+  84, 94, 89, 76, 81, 79, 64, 96, 80, 81,
+  69, 91, 91, 74, 85, 80, 61, 78, 93, 77,
+  87, 95, 75, 83, 69, 83, 86, 79, 75, 85,
+  80, 106, 86, 68, 79, 90, 72, 75, 83, 83,
+  88, 80, 73, 90, 86, 88, 89, 84, 73, 81,
+  77, 80, 95, 90, 82, 137, 77, 82, 71, 84,
+  98, 73, 82, 77, 88, 89, 82, 87, 69, 81,
+  72, 76, 75, 85, 83, 86, 71, 84, 80, 80,
+  86, 91, 78, 86, 83, 84, 77, 92, 79, 78,
+  97, 87, 117, 97, 82, 79, 82, 95, 94, 83,
+  85, 86, 87, 86, 88, 88, 73, 82, 88, 90,
+  87, 85, 91, 75, 79, 91, 84, 85, 76, 76,
+  78, 75, 83, 80, 92, 78, 84, 75, 82, 95,
+  89, 85, 89, 83, 76, 93, 85, 89, 72, 83,
+  97, 73, 81, 78, 61, 72, 97, 78, 85, 95,
+  76, 81, 77, 99, 94, 78, 85, 81, 83, 97,
+  91, 70, 80, 99, 76, 76, 81, 82, 79, 86,
+  75, 98, 84, 92, 85, 88, 79, 83, 83, 84,
+  92, 87, 94, 131, 77, 86, 74, 85, 93, 70,
+  89, 86, 77, 81, 81, 82, 77, 73, 73, 78,
+  75, 91, 81, 89, 82, 83, 82, 73, 80, 81,
+  87, 96, 85, 87, 85, 81, 81, 78, 91, 80,
+  114, 90, 85, 97, 95, 82, 91, 83, 88, 84,
+  85, 90, 72, 93, 77, 80, 92, 84, 80, 89,
+  91, 79, 86, 82, 83, 84, 83, 80, 79, 74,
+  87, 79, 91, 79, 83, 69, 86, 87, 79, 74,
+  82, 92, 67, 89, 89, 81, 62, 90, 86, 74,
+  87, 79, 62, 84, 96, 80, 87, 100, 83, 91,
+  73, 76, 89, 68, 79, 84, 81, 101, 98, 71,
+  78, 84, 76, 75, 93, 81, 86, 75, 85, 103,
+  84, 81, 89, 80, 78, 75, 80, 85, 102, 83,
+  80, 112, 82, 87, 73, 87, 100, 78, 98, 89,
+  81, 76, 82, 89, 78, 75, 76, 83, 71, 93,
+  89, 84, 84, 84, 88, 73, 83, 86, 77, 96,
+  88, 87, 87, 77, 77, 79, 97, 89, 115, 84,
+  85, 88, 94, 76, 91, 84, 89, 85, 89, 94,
+  80, 99, 83, 80, 95, 78, 73, 88, 94, 83,
+  88, 84, 90, 83, 83, 82, 85, 65, 85, 76,
+  91, 76, 74, 75, 90, 79, 76, 70, 79, 87,
+  67, 83, 88, 79, 65, 89, 79, 78, 89, 76,
+  65, 76, 89, 76, 76, 93, 84, 96, 71, 74,
+  86, 65, 72, 83, 80, 101, 89, 77, 79, 86,
+  87, 75, 89, 87, 86, 79, 85, 96, 81, 76,
+  93, 76, 72, 69, 79, 79, 94, 81, 84, 98,
+  80, 87, 70, 79, 105, 80, 87, 86, 86, 84,
+  84, 89, 75, 78, 75, 79, 79, 86, 87, 84,
+  80, 83, 76, 77, 82, 84, 74, 83, 83, 92,
+  86, 78, 79, 80, 87, 82, 104, 90, 87, 82,
+  81, 92, 86, 81, 90, 81, 87, 87, 90, 91,
+  79, 87, 90, 85, 80, 88, 93, 77, 85, 88,
+  85, 85, 81, 75, 78, 72, 86, 82, 92, 76,
+  75, 75, 86, 90, 75, 68, 87, 90, 73, 86,
+  85, 86, 66, 80, 84, 77, 86, 79, 62, 74,
+  91, 83, 82, 91, 81, 89, 76, 84, 92, 71,
+  79, 87, 82, 91, 87, 76, 74, 95, 78, 77,
+  89, 82, 81, 82, 83, 100, 84, 81, 86, 84,
+  79, 76, 83, 85, 91, 85, 91, 105, 75, 84,
+  73, 86, 98, 73, 86, 86, 72, 84, 83, 94,
+  72, 73, 68, 77, 86, 82, 85, 83, 86, 89,
+  75, 75, 82, 79, 80, 92, 88, 94, 91, 77,
+  82, 80, 86, 81, 97, 95, 84, 99, 94, 90,
+  91, 84, 92, 89, 94, 81, 75, 83, 82, 72,
+  88, 86, 84, 83, 87, 77, 85, 82, 86, 84,
+  75, 83, 73, 81, 92, 84, 85, 83, 83, 74,
+  85, 90, 79, 75, 94, 87, 76, 81, 90, 79,
+  69, 86, 90, 74, 85, 84, 61, 83, 88, 87,
+  87, 100, 81, 84, 79, 81, 97, 77, 86, 93,
+  86, 97, 94, 79, 78, 85, 83, 77, 89, 76,
+  80, 78, 85, 100, 89, 77, 82, 76, 81, 81,
+  82, 87, 96, 85, 78, 113, 79, 94, 79, 96,
+  97, 77, 83, 92, 82, 83, 83, 90, 73, 76,
+  72, 82, 86, 82, 88, 88, 83, 87, 75, 77,
+  86, 84, 77, 87, 90, 98, 87, 76, 88, 81,
+  89, 89, 89, 91, 93, 85, 92, 81, 90, 85,
+  86, 86, 94, 80, 78, 85, 84, 76, 88, 81,
+  82, 86, 84, 79, 88, 82, 90, 85, 77, 83,
+  78, 73, 86, 87, 89, 81, 75, 74, 90, 83,
+  77, 78, 83, 84, 78, 76, 92, 79, 69, 83,
+  87, 76, 87, 82, 66, 77, 81, 86, 79, 92,
+  85, 86, 80, 76, 99, 77, 86, 93, 88, 91,
+  89, 80, 83, 84, 86, 77, 81, 78, 80, 81,
+  81, 101, 87, 72, 88, 75, 78, 76, 88, 84,
+  89, 88, 85, 101, 80, 93, 79, 92, 101, 81,
+  86, 86, 86, 83, 84, 91, 74, 78, 67, 79,
+  88, 81, 91, 93, 80, 86, 70, 79, 86, 86,
+  73, 89, 94, 98, 81, 74, 80, 84, 82, 81,
+  92, 95, 88, 83, 82, 92, 85, 80, 87, 84,
+  92, 79, 77, 83, 81, 71, 88, 85, 80, 83,
+  88, 78, 85, 86, 81, 82, 77, 81, 75, 84,
+  92, 88, 88, 81, 75, 77, 85, 89, 76, 70,
+  79, 89, 80, 80, 92, 83, 72, 81, 84, 79,
+  87, 84, 63, 77, 89, 94, 77, 91, 84, 80,
+  80, 80, 93, 77, 83, 92, 88, 91, 86, 79,
+  73, 89, 89, 79, 84, 84, 78, 84, 86, 97,
+  87, 76, 82, 80, 84, 86, 90, 85, 91, 86,
+  91, 102, 76, 89, 82, 92, 96, 81, 94, 70,
+  93, 84, 76, 93, 75, 86, 85, 83, 74, 86,
+  77, 90, 72, 83, 82, 82, 96, 92, 84, 84,
+  82, 79, 82, 85, 81, 94, 97, 73, 101, 105,
+  95, 96, 87, 96, 86, 74, 93, 70, 92, 67,
+  80, 88, 91, 81, 76, 75, 87, 76, 91, 75,
+  84, 87, 103, 93, 91, 70, 84, 76, 97, 84,
+  95, 84, 83, 88, 81, 87, 80, 83, 75, 83,
+  86, 88, 83, 80, 86, 74, 76, 83, 86, 77,
+  86, 97, 73, 81, 85, 82, 91, 86, 91, 90,
+  93, 69, 73, 112, 93, 85, 84, 72, 69, 76,
+  92, 84, 83, 78, 76, 91, 79, 81, 89, 99,
+  91, 98, 90, 96, 84, 83, 80, 91, 79, 96,
+  71, 86, 86, 88, 102, 75, 80, 80, 79, 72,
+  83, 101, 76, 85, 79, 81, 70, 83, 83, 91,
+  79, 80, 87, 76, 70, 84, 76, 81, 66, 83,
+  71, 97, 73, 80, 91, 83, 97, 89, 74, 88,
+  84, 89, 90, 88, 83, 74, 79, 65, 91, 88,
+  93, 74, 68, 73, 92, 93, 84, 80, 86, 72,
+  96, 89, 70, 76, 94, 84, 94, 79, 88, 73,
+  76, 78, 77, 75, 65, 78, 88, 88, 82, 83,
+  77, 66, 84, 76, 78, 77, 85, 78, 71, 81,
+  78, 72, 82, 84, 90, 87, 80, 88, 97, 76,
+  65, 109, 91, 87, 74, 64, 71, 89, 91, 90,
+  89, 68, 65, 81, 68, 93, 81, 89, 88, 97,
+  84, 86, 76, 91, 74, 91, 81, 111, 76, 85,
+  78, 83, 90, 75, 81, 76, 77, 69, 82, 86,
+  78, 92, 80, 86, 78, 81, 99, 84, 79, 83,
+  91, 79, 60, 84, 82, 77, 79, 92, 84, 88,
+  78, 75, 78, 91, 95, 76, 77, 79, 87, 78,
+  91, 89, 84, 77, 83, 70, 92, 83, 96, 75,
+  79, 96, 89, 99, 76, 76, 87, 70, 93, 88,
+  60, 86, 93, 93, 92, 80, 80, 83, 92, 82,
+  92, 79, 56, 82, 86, 92, 100, 82, 85, 65,
+  79, 86, 71, 86, 79, 78, 78, 85, 80, 76,
+  81, 92, 96, 84, 74, 79, 94, 92, 83, 94,
+  83, 97, 71, 88, 79, 82, 94, 94, 91, 68,
+  67, 81, 76, 84, 88, 75, 88, 95, 88, 89,
+  96, 98, 82, 88, 91, 104, 90, 78, 78, 90,
+  74, 84, 88, 74, 89, 87, 77, 92, 76, 85,
+  88, 86, 86, 79, 78, 84, 71, 74, 81, 92,
+  114, 84, 73, 82, 78, 73, 98, 78, 83, 98,
+  104, 69, 83, 104, 110, 91, 91, 94, 83, 70,
+  83, 65, 97, 76, 98, 79, 89, 93, 92, 81,
+  78, 79, 91, 82, 82, 107, 114, 84, 97, 57,
+  85, 82, 89, 93, 101, 71, 68, 101, 75, 86,
+  78, 69, 82, 73, 81, 75, 86, 76, 75, 76,
+  77, 86, 84, 84, 93, 96, 74, 83, 84, 80,
+  86, 80, 90, 82, 81, 72, 81, 102, 89, 80,
+  81, 89, 69, 73, 86, 83, 69, 77, 85, 87,
+  88, 66, 89, 94, 93, 85, 88, 95, 79, 77,
+  79, 74, 79, 71, 83, 73, 101, 85, 104, 83,
+  79, 80, 77, 78, 89, 104, 68, 80, 81, 83,
+  72, 84, 76, 94, 77, 75, 90, 83, 93, 84,
+  70, 90, 59, 74, 87, 87, 75, 86, 113, 69,
+  96, 101, 86, 95, 87, 94, 77, 86, 81, 64,
+  106, 72, 110, 91, 93, 85, 71, 73, 91, 82,
+  86, 83, 82, 87, 104, 88, 84, 67, 89, 69,
+  93, 89, 97, 70, 54, 77, 75, 83, 69, 67,
+  87, 72, 67, 83, 75, 71, 76, 76, 80, 79,
+  86, 88, 73, 81, 81, 80, 75, 80, 82, 80,
+  89, 88, 96, 76, 70, 123, 97, 84, 70, 63,
+  71, 87, 85, 86, 76, 63, 78, 85, 73, 81,
+  80, 105, 92, 86, 84, 80, 72, 87, 75, 87,
+  70, 92, 70, 79, 90, 80, 107, 72, 75, 81,
+  77, 72, 85, 94, 71, 80, 82, 82, 70, 82,
+  96, 87, 84, 87, 93, 75, 66, 80, 79, 88,
+  78, 88, 91, 92, 72, 80, 93, 86, 92, 88,
+  77, 85, 84, 87, 79, 93, 88, 84, 101, 69,
+  102, 88, 83, 81, 80, 81, 93, 98, 73, 81,
+  88, 73, 91, 86, 68, 88, 96, 79, 91, 87,
+  91, 70, 77, 81, 90, 81, 63, 75, 79, 78,
+  85, 75, 78, 64, 79, 77, 82, 80, 84, 84,
+  71, 88, 84, 83, 76, 86, 91, 83, 77, 79,
+  108, 85, 71, 110, 80, 91, 73, 72, 78, 87,
+  84, 91, 86, 73, 76, 82, 70, 96, 81, 87,
+  85, 88, 86, 89, 97, 94, 80, 97, 82, 111,
+  87, 82, 86, 87, 87, 76, 77, 84, 86, 92,
+  73, 71, 92, 84, 78, 92, 87, 68, 86, 78,
+  70, 87, 67, 90, 101, 79, 79, 89, 86, 93,
+  91, 83, 97, 96, 79, 64, 77, 92, 106, 89,
+  81, 90, 83, 75, 83, 69, 91, 82, 86, 73,
+  96, 98, 101, 87, 79, 93, 87, 90, 84, 100,
+  98, 81, 85, 76, 80, 98, 83, 86, 93, 79,
+  73, 111, 81, 86, 78, 73, 86, 84, 85, 75,
+  93, 72, 77, 81, 91, 85, 92, 85, 95, 91,
+  78, 84, 93, 77, 96, 81, 70, 76, 78, 80,
+  75, 79, 77, 77, 78, 91, 76, 81, 91, 78,
+  69, 82, 91, 86, 81, 73, 95, 77, 86, 76,
+  90, 97, 88, 73, 82, 86, 82, 71, 84, 78,
+  102, 82, 88, 95, 76, 77, 83, 90, 77, 93,
+  77, 81, 79, 86, 86, 82, 76, 85, 66, 79,
+  78, 89, 104, 82, 79, 97, 63, 82, 86, 76,
+  94, 88, 99, 64, 87, 110, 102, 94, 93, 91,
+  70, 89, 83, 62, 106, 71, 89, 89, 97, 96,
+  80, 79, 85, 82, 86, 88, 79, 100, 102, 78,
+  94, 71, 76, 80, 84, 91, 92, 80, 66, 92,
+  78, 85, 76, 78, 89, 66, 74, 83, 79, 71,
+  76, 81, 83, 85, 85, 87, 87, 86, 75, 85,
+  75, 81, 80, 78, 94, 79, 80, 81, 77, 102,
+  96, 79, 77, 82, 78, 80, 89, 79, 65, 76,
+  85, 89, 82, 69, 90, 103, 94, 81, 95, 88,
+  84, 74, 73, 88, 75, 71, 75, 78, 97, 78,
+  103, 85, 86, 74, 81, 88, 74, 103, 76, 75,
+  81, 84, 76, 80, 93, 90, 75, 84, 82, 80,
+  80, 79, 87, 93, 73, 94, 85, 87, 86, 85,
+  94, 90, 91, 104, 86, 93, 83, 91, 75, 99,
+  91, 83, 113, 75, 81, 89, 87, 85, 86, 88,
+  91, 88, 79, 84, 84, 85, 96, 80, 90, 87,
+  81, 79, 87, 83, 91, 76, 76, 89, 84, 80,
+  80, 89, 76, 72, 85, 80, 81, 73, 85, 72,
+  77, 85, 86, 88, 75, 88, 82, 93, 67, 84,
+  87, 75, 92, 76, 100, 85, 77, 98, 88, 88,
+  83, 81, 81, 82, 93, 81, 84, 81, 75, 91,
+  77, 86, 88, 92, 88, 87, 92, 88, 105, 84,
+  80, 87, 88, 86, 81, 81, 90, 82, 97, 80,
+  99, 83, 74, 79, 89, 88, 69, 86, 91, 80,
+  81, 80, 92, 82, 68, 81, 87, 89, 86, 75,
+  83, 91, 73, 83, 85, 74, 85, 87, 84, 101,
+  88, 92, 72, 80, 79, 91, 73, 84, 92, 81,
+  85, 76, 90, 77, 84, 83, 78, 79, 80, 81,
+  93, 88, 86, 79, 80, 84, 83, 93, 89, 91,
+  90, 80, 96, 88, 87, 87, 98, 93, 75, 87,
+  97, 90, 98, 91, 71, 79, 78, 95, 79, 87,
+  88, 93, 74, 78, 74, 85, 84, 92, 92, 76,
+  82, 100, 74, 85, 88, 91, 91, 87, 71, 82,
+  73, 84, 80, 87, 86, 76, 83, 84, 80, 73,
+  79, 65, 80, 82, 84, 84, 77, 79, 79, 81,
+  103, 79, 84, 88, 92, 94, 95, 89, 83, 86,
+  53, 79, 85, 72, 88, 83, 92, 84, 72, 80,
+  88, 66, 80, 80, 89, 94, 82, 74, 85, 87,
+  72, 85, 88, 90, 88, 83, 80, 78, 88, 79,
+  84, 93, 76, 83, 79, 79, 82, 89, 84, 76,
+  83, 96, 76, 89, 94, 68, 76, 85, 75, 90,
+  95, 80, 88, 88, 99, 86, 87, 79, 83, 74,
+  80, 76, 82, 87, 84, 88, 87, 80, 96, 73,
+  86, 84, 86, 80, 88, 94, 88, 74, 88, 80,
+  85, 67, 79, 65, 79, 77, 88, 82, 75, 91,
+  74, 84, 80, 80, 86, 73, 70, 85, 64, 79,
+  81, 87, 86, 79, 84, 96, 82, 80, 81, 72,
+  89, 82, 67, 78, 73, 76, 81, 89, 95, 82,
+  89, 90, 94, 81, 90, 91, 88, 95, 83, 86,
+  90, 73, 96, 78, 92, 87, 76, 85, 76, 69,
+  93, 82, 92, 93, 84, 81, 81, 83, 74, 78,
+  93, 97, 85, 84, 75, 94, 89, 80, 85, 97,
+  86, 83, 95, 90, 75, 71, 95, 76, 75, 108,
+  78, 91, 97, 74, 81, 83, 70, 98, 88, 87,
+  97, 97, 103, 95, 83, 85, 84, 77, 81, 81,
+  97, 77, 80, 88, 95, 91, 95, 73, 83, 74,
+  93, 82, 97, 86, 99, 75, 92, 80, 80, 81,
+  96, 77, 87, 78, 87, 80, 72, 73, 79, 84,
+  78, 94, 85, 82, 74, 82, 79, 78, 87, 91,
+  90, 84, 86, 98, 86, 79, 82, 80, 90, 80,
+  74, 78, 83, 87, 86, 88, 83, 87, 88, 90,
+  96, 77, 83, 80, 112, 86, 69, 84, 94, 92,
+  67, 71, 76, 83, 85, 86, 81, 114, 59, 77,
+  78, 63, 75, 88, 76, 73, 70, 85, 85, 64,
+  89, 89, 102, 133, 78, 103, 71, 81, 86, 90,
+  129, 82, 116, 57, 94, 85, 77, 61, 94, 64,
+  75, 96, 90, 59, 111, 59, 71, 80, 69, 94,
+  80, 72, 81, 103, 88, 89, 101, 92, 68, 88,
+  93, 103, 95, 93, 68, 96, 96, 85, 66, 76,
+  87, 79, 88, 95, 78, 102, 70, 91, 63, 103,
+  84, 114, 73, 79, 78, 105, 93, 83, 98, 87,
+  92, 95, 85, 92, 81, 124, 81, 93, 89, 85,
+  71, 84, 88, 69, 67, 64, 67, 82, 79, 101,
+  48, 89, 84, 87, 111, 70, 63, 77, 68, 94,
+  91, 92, 95, 93, 63, 78, 77, 125, 89, 80,
+  71, 91, 74, 79, 85, 79, 66, 79, 78, 87,
+  80, 80, 78, 89, 70, 97, 74, 78, 93, 88,
+  88, 108, 84, 89, 87, 86, 80, 87, 105, 69,
+  94, 88, 80, 105, 77, 79, 83, 73, 82, 127,
+  83, 94, 76, 76, 80, 75, 90, 65, 96, 63,
+  78, 94, 88, 78, 66, 68, 47, 87, 78, 93,
+  81, 64, 70, 86, 86, 80, 84, 86, 92, 69,
+  69, 87, 78, 73, 92, 93, 66, 71, 80, 91,
+  60, 80, 81, 81, 86, 74, 88, 69, 90, 73,
+  80, 88, 56, 126, 81, 93, 78, 71, 70, 89,
+  83, 90, 79, 70, 86, 89, 46, 80, 53, 83,
+  83, 85, 107, 89, 88, 84, 73, 75, 85, 124,
+  77, 93, 87, 75, 79, 88, 104, 82, 89, 93,
+  76, 82, 68, 70, 85, 84, 85, 103, 89, 73,
+  80, 99, 72, 83, 84, 95, 89, 88, 77, 79,
+  91, 73, 93, 88, 82, 83, 59, 81, 83, 85,
+  82, 80, 84, 106, 84, 95, 89, 87, 77, 87,
+  69, 103, 90, 81, 102, 83, 92, 88, 78, 89,
+  85, 77, 64, 66, 76, 81, 77, 83, 94, 71,
+  97, 76, 82, 82, 99, 87, 81, 80, 81, 83,
+  92, 78, 91, 80, 86, 73, 85, 79, 88, 79,
+  95, 69, 76, 72, 72, 89, 80, 77, 80, 80,
+  70, 77, 82, 95, 86, 71, 80, 99, 83, 85,
+  85, 87, 93, 83, 56, 69, 73, 85, 82, 90,
+  87, 77, 95, 92, 97, 78, 78, 90, 104, 83,
+  76, 84, 91, 91, 76, 75, 70, 82, 83, 87,
+  88, 118, 62, 80, 75, 72, 80, 79, 74, 88,
+  74, 83, 72, 78, 90, 93, 90, 107, 88, 97,
+  85, 85, 72, 89, 89, 78, 77, 73, 91, 81,
+  85, 74, 80, 77, 74, 99, 90, 73, 100, 87,
+  86, 81, 67, 79, 80, 75, 80, 88, 90, 93,
+  101, 80, 71, 86, 65, 82, 100, 84, 63, 84,
+  90, 83, 65, 77, 87, 83, 85, 81, 83, 92,
+  76, 85, 79, 92, 85, 106, 93, 100, 89, 92,
+  82, 74, 91, 83, 85, 86, 89, 84, 74, 91,
+  78, 93, 82, 83, 92, 86, 81, 83, 80, 73,
+  78, 85, 89, 92, 82, 74, 81, 85, 109, 81,
+  80, 83, 85, 84, 90, 83, 93, 84, 94, 89,
+  73, 83, 90, 83, 84, 89, 80, 84, 88, 97,
+  71, 90, 79, 89, 81, 80, 78, 95, 76, 85,
+  67, 85, 90, 87, 82, 111, 87, 86, 86, 81,
+  71, 68, 104, 83, 66, 88, 85, 89, 76, 97,
+  81, 78, 87, 86, 79, 84, 80, 92, 85, 76,
+  86, 58, 93, 73, 79, 91, 78, 74, 78, 73,
+  63, 90, 71, 81, 85, 80, 42, 73, 83, 85,
+  82, 82, 85, 73, 69, 81, 83, 75, 83, 88,
+  83, 79, 71, 82, 81, 83, 80, 93, 76, 73,
+  81, 77, 87, 66, 79, 82, 72, 69, 79, 91,
+  68, 73, 78, 99, 73, 86, 89, 79, 85, 89,
+  80, 79, 84, 78, 83, 77, 97, 86, 90, 88,
+  88, 70, 87, 97, 83, 92, 97, 84, 81, 82,
+  92, 84, 93, 91, 79, 81, 75, 83, 89, 89,
+  87, 101, 85, 80, 77, 94, 80, 72, 79, 93,
+  82, 87, 74, 92, 89, 77, 90, 90, 79, 84,
+  75, 92, 78, 79, 85, 74, 82, 110, 85, 90,
+  86, 82, 80, 74, 68, 100, 77, 85, 96, 70,
+  95, 94, 85, 90, 79, 84, 66, 72, 91, 78,
+  87, 82, 93, 96, 70, 72, 73, 83, 100, 82,
+  87, 77, 63, 87, 91, 74, 81, 84, 90, 81,
+  77, 80, 82, 81, 84, 98, 76, 77, 78, 92,
+  85, 74, 85, 80, 84, 72, 82, 92, 85, 78,
+  78, 92, 80, 84, 84, 86, 91, 85, 82, 82,
+  84, 88, 85, 74, 77, 86, 88, 91, 99, 78,
+  85, 82, 106, 67, 100, 116, 72, 120, 81, 79,
+  90, 88, 76, 97, 87, 78, 70, 92, 93, 98,
+  121, 109, 77, 122, 71, 69, 83, 73, 81, 116,
+  107, 107, 103, 149, 74, 83, 74, 99, 89, 106,
+  84, 73, 76, 79, 97, 95, 79, 107, 95, 81,
+  87, 83, 84, 88, 81, 75, 101, 90, 87, 93,
+  90, 88, 89, 67, 82, 71, 70, 75, 83, 98,
+  72, 90, 87, 103, 73, 106, 76, 101, 90, 77,
+  91, 69, 75, 82, 71, 64, 86, 76, 79, 110,
+  83, 83, 87, 107, 100, 68, 89, 84, 95, 81,
+  64, 52, 89, 85, 95, 85, 85, 103, 79, 89,
+  74, 111, 79, 96, 64, 80, 93, 78, 84, 106,
+  77, 80, 98, 119, 89, 94, 83, 71, 82, 71,
+  77, 62, 100, 95, 75, 115, 96, 82, 77, 83,
+  72, 83, 97, 81, 79, 84, 73, 83, 80, 84,
+  66, 84, 65, 83, 83, 82, 72, 87, 94, 108,
+  83, 114, 71, 81, 79, 106, 83, 101, 79, 87,
+  74, 76, 98, 82, 82, 93, 87, 90, 76, 98,
+  80, 95, 91, 71, 80, 84, 71, 84, 99, 86,
+  83, 75, 74, 54, 83, 69, 86, 85, 68, 92,
+  76, 100, 80, 87, 75, 94, 84, 72, 89, 90,
+  86, 81, 77, 78, 74, 81, 97, 94, 84, 83,
+  89, 89, 92, 89, 85, 87, 88, 83, 65, 74,
+  80, 81, 83, 82, 84, 96, 78, 75, 73, 86,
+  79, 85, 67, 95, 81, 89, 93, 87, 86, 91,
+  109, 102, 88, 86, 89, 80, 83, 77, 77, 62,
+  84, 79, 83, 91, 95, 84, 79, 73, 87, 82,
+  90, 82, 85, 88, 81, 93, 71, 78, 70, 69,
+  69, 87, 86, 79, 75, 70, 85, 100, 81, 78,
+  79, 80, 87, 91, 85, 93, 87, 83, 76, 88,
+  95, 80, 95, 79, 92, 91, 79, 99, 86, 96,
+  80, 87, 85, 81, 73, 79, 94, 89, 84, 88,
+  76, 64, 84, 88, 89, 80, 80, 90, 83, 87,
+  93, 63, 77, 79, 78, 69, 84, 91, 86, 84,
+  89, 80, 88, 81, 94, 78, 87, 80, 96, 77,
+  75, 91, 79, 93, 89, 89, 66, 95, 83, 81,
+  74, 87, 79, 87, 78, 80, 82, 57, 90, 83,
+  77, 84, 87, 89, 85, 83, 77, 94, 98, 86,
+  74, 77, 86, 90, 82, 83, 93, 80, 105, 106,
+  73, 115, 84, 73, 82, 92, 70, 94, 86, 76,
+  74, 82, 77, 89, 97, 98, 69, 102, 77, 77,
+  84, 76, 85, 102, 83, 103, 80, 128, 72, 79,
+  71, 99, 81, 97, 92, 79, 75, 66, 87, 93,
+  74, 96, 100, 81, 79, 90, 74, 80, 92, 68,
+  82, 83, 83, 90, 87, 85, 88, 70, 73, 77,
+  86, 74, 84, 89, 70, 91, 75, 94, 70, 100,
+  86, 94, 81, 76, 113, 69, 88, 86, 66, 69,
+  80, 92, 82, 101, 82, 85, 86, 91, 89, 76,
+  84, 81, 90, 77, 81, 61, 91, 79, 90, 79,
+  82, 98, 84, 87, 82, 105, 74, 90, 71, 82,
+  78, 86, 83, 100, 78, 78, 101, 101, 91, 92,
+  87, 85, 84, 71, 77, 73, 89, 83, 81, 92,
+  93, 78, 80, 84, 74, 86, 97, 84, 88, 80,
+  72, 76, 59, 76, 63, 81, 66, 85, 87, 85,
+  80, 76, 80, 97, 79, 86, 75, 80, 74, 97,
+  78, 91, 87, 90, 71, 71, 86, 84, 78, 86,
+  99, 91, 78, 98, 84, 83, 95, 66, 71, 80,
+  74, 85, 96, 86, 80, 81, 72, 65, 77, 72,
+  93, 82, 70, 80, 79, 91, 87, 88, 85, 79,
+  79, 73, 92, 94, 93, 89, 77, 76, 74, 88,
+  100, 82, 86, 79, 84, 84, 80, 91, 84, 79,
+  82, 82, 74, 85, 76, 76, 81, 82, 83, 81,
+  83, 81, 79, 80, 75, 81, 78, 86, 81, 93,
+  78, 83, 85, 86, 111, 84, 78, 86, 88, 92,
+  86, 82, 80, 72, 76, 78, 87, 71, 90, 81,
+  86, 75, 94, 86, 93, 89, 89, 81, 85, 88,
+  62, 80, 74, 73, 71, 88, 93, 80, 85, 65,
+  78, 95, 81, 64, 83, 78, 87, 88, 76, 82,
+  94, 79, 70, 89, 84, 85, 97, 81, 92, 93,
+  81, 98, 87, 87, 79, 89, 84, 85, 84, 83,
+  87, 92, 82, 92, 72, 81, 82, 96, 96, 85,
+  85, 86, 81, 82, 100, 66, 82, 70, 78, 71,
+  75, 89, 90, 88, 93, 73, 93, 82, 91, 76,
+  86, 77, 96, 74, 72, 95, 79, 81, 86, 86,
+  79, 101, 77, 82, 76, 87, 77, 81, 88, 85,
+  92, 56, 85, 82, 84, 80, 91, 86, 85, 83,
+  76, 88, 96, 77, 65, 76, 81, 93, 83, 84,
+  94, 81, 83, 92, 76, 113, 82, 77, 87, 80,
+  80, 94, 86, 90, 79, 80, 73, 88, 89, 84,
+  68, 86, 84, 86, 79, 82, 83, 89, 95, 102,
+  77, 113, 76, 78, 72, 89, 90, 88, 93, 96,
+  84, 69, 82, 92, 80, 87, 91, 86, 77, 88,
+  85, 85, 90, 71, 90, 95, 81, 87, 80, 79,
+  84, 77, 75, 82, 85, 77, 95, 83, 72, 87,
+  68, 86, 77, 92, 88, 85, 79, 74, 96, 75,
+  93, 83, 73, 71, 80, 89, 88, 86, 83, 88,
+  85, 95, 78, 82, 77, 80, 96, 82, 81, 76,
+  89, 80, 81, 85, 82, 79, 79, 88, 89, 80,
+  72, 81, 76, 83, 75, 92, 83, 91, 77, 68,
+  103, 83, 85, 86, 90, 98, 84, 81, 82, 72,
+  72, 86, 83, 88, 89, 78, 89, 77, 87, 85,
+  93, 91, 90, 81, 75, 87, 66, 78, 64, 81,
+  70, 83, 84, 83, 79, 72, 84, 92, 82, 85,
+  78, 80, 78, 85, 79, 85, 86, 94, 79, 76,
+  87, 93, 80, 79, 90, 89, 80, 91, 90, 90,
+  84, 78, 83, 87, 77, 86, 88, 87, 85, 84,
+  75, 76, 90, 85, 96, 80, 75, 83, 81, 86,
+  87, 75, 84, 72, 77, 73, 74, 91, 92, 90,
+  84, 71, 84, 82, 95, 73, 84, 80, 90, 88,
+  74, 90, 77, 78, 86, 88, 77, 94, 78, 83,
+  81, 85, 80, 74, 81, 83, 88, 65, 75, 79,
+  82, 81, 86, 88, 76, 87, 83, 76, 106, 76,
+  65, 83, 83, 93, 87, 91, 80, 75, 73, 84,
+  86, 80, 82, 83, 87, 74, 95, 87, 87, 91,
+  82, 84, 78, 95, 71, 81, 75, 74, 79, 81,
+  94, 69, 86, 69, 78, 95, 83, 72, 82, 77,
+  84, 85, 80, 82, 93, 79, 81, 91, 82, 88,
+  94, 83, 95, 97, 80, 92, 86, 91, 71, 97,
+  86, 87, 83, 84, 83, 86, 87, 91, 81, 86,
+  87, 96, 89, 82, 82, 84, 78, 83, 97, 56,
+  81, 69, 79, 69, 70, 80, 87, 90, 95, 70,
+  93, 75, 90, 73, 82, 77, 98, 76, 71, 89,
+  76, 78, 89, 85, 81, 101, 82, 92, 82, 85,
+  79, 77, 81, 86, 99, 57, 78, 78, 81, 80,
+  91, 91, 94, 78, 76, 85, 98, 74, 70, 72,
+  78, 91, 87, 90, 79, 86, 84, 83, 71, 91,
+  92, 66, 83, 65, 70, 72, 87, 85, 80, 68,
+  79, 86, 70, 85, 84, 89, 86, 102, 71, 82,
+  82, 87, 89, 86, 91, 81, 87, 74, 71, 80,
+  73, 113, 85, 83, 80, 69, 92, 87, 71, 77,
+  76, 83, 87, 83, 83, 96, 92, 96, 91, 75,
+  79, 87, 85, 84, 104, 83, 86, 76, 71, 81,
+  89, 91, 80, 71, 66, 83, 79, 86, 69, 80,
+  77, 79, 80, 66, 93, 80, 83, 86, 90, 81,
+  75, 86, 99, 86, 66, 73, 85, 102, 71, 100,
+  90, 83, 82, 81, 70, 82, 81, 79, 104, 88,
+  70, 91, 78, 72, 79, 76, 83, 95, 93, 92,
+  105, 98, 70, 97, 96, 78, 77, 67, 89, 71,
+  77, 119, 76, 97, 72, 86, 73, 67, 84, 73,
+  81, 63, 74, 71, 91, 85, 81, 70, 85, 92,
+  62, 102, 90, 84, 72, 95, 70, 83, 85, 86,
+  94, 66, 86, 85, 88, 73, 76, 62, 75, 125,
+  87, 81, 85, 69, 84, 90, 75, 74, 85, 72,
+  88, 81, 82, 90, 100, 98, 87, 86, 74, 95,
+  86, 91, 102, 77, 92, 84, 57, 88, 93, 93,
+  79, 61, 80, 78, 76, 86, 68, 73, 80, 70,
+  85, 63, 94, 80, 88, 79, 86, 70, 82, 79,
+  116, 81, 69, 82, 78, 107, 63, 96, 91, 94,
+  82, 77, 73, 87, 87, 84, 96, 94, 73, 91,
+  70, 73, 75, 76, 83, 77, 89, 84, 78, 93,
+  61, 96, 90, 76, 74, 68, 88, 78, 73, 128,
+  74, 100, 70, 73, 78, 88, 91, 74, 83, 66,
+  70, 85, 92, 79, 84, 76, 81, 82, 72, 99,
+  89, 86, 87, 103, 67, 87, 88, 83, 79, 61,
+  87, 84, 85, 72, 85, 79, 84, 108, 82, 79,
+  80, 65, 81, 86, 81, 81, 81, 84, 95, 80,
+  78, 83, 89, 98, 93, 84, 78, 90, 88, 83,
+  97, 83, 82, 74, 82, 82, 87, 87, 83, 65,
+  107, 85, 95, 82, 74, 77, 80, 85, 85, 71,
+  97, 75, 82, 84, 82, 74, 94, 85, 93, 91,
+  68, 81, 86, 103, 82, 103, 94, 76, 80, 81,
+  73, 89, 84, 81, 101, 87, 74, 90, 84, 75,
+  78, 77, 86, 75, 71, 87, 70, 99, 78, 96,
+  89, 85, 78, 72, 88, 77, 77, 106, 89, 88,
+  76, 103, 83, 95, 83, 71, 85, 79, 66, 79,
+  82, 85, 76, 77, 89, 82, 87, 70, 94, 89,
+  74, 98, 85, 85, 85, 86, 87, 74, 98, 77,
+  77, 83, 61, 81, 73, 127, 89, 84, 89, 73,
+  82, 84, 70, 83, 74, 83, 79, 76, 100, 82,
+  86, 95, 97, 83, 82, 82, 89, 90, 106, 67,
+  69, 70, 60, 92, 83, 89, 88, 55, 75, 90,
+  77, 93, 71, 85, 91, 117, 68, 68, 89, 89,
+  94, 73, 93, 81, 85, 85, 89, 79, 65, 76,
+  85, 114, 70, 88, 86, 88, 91, 79, 66, 84,
+  69, 81, 75, 110, 91, 80, 78, 65, 75, 77,
+  79, 89, 79, 95, 101, 86, 76, 80, 83, 63,
+  85, 64, 85, 80, 81, 95, 87, 94, 73, 106,
+  81, 76, 76, 79, 75, 71, 66, 81, 79, 87,
+  72, 69, 91, 93, 85, 78, 85, 85, 76, 85,
+  91, 89, 80, 76, 91, 66, 100, 86, 74, 87,
+  66, 69, 72, 104, 88, 74, 91, 65, 84, 87,
+  75, 83, 76, 88, 75, 64, 102, 80, 83, 97,
+  99, 88, 93, 81, 105, 85, 110, 76, 82, 78,
+  59, 98, 80, 98, 88, 56, 64, 80, 77, 81,
+  58, 83, 93, 98, 71, 55, 86, 86, 100, 80,
+  96, 79, 88, 78, 81, 68, 67, 76, 79, 117,
+  70, 92, 82, 107, 79, 74, 68, 96, 67, 86,
+  64, 126, 106, 75, 63, 61, 70, 72, 78, 91,
+  78, 100, 84, 77, 69, 81, 82, 66, 75, 64,
+  77, 86, 70, 100, 85, 95, 81, 95, 82, 86,
+  77, 73, 87, 80, 68, 83, 88, 80, 81, 82,
+  89, 82, 90, 78, 77, 91, 88, 98, 82, 81,
+  87, 89, 81, 61, 93, 87, 78, 84, 80, 83,
+  74, 122, 82, 84, 90, 70, 90, 84, 75, 77,
+  83, 103, 85, 76, 89, 80, 89, 93, 92, 86,
+  81, 84, 91, 85, 99, 75, 68, 67, 77, 89,
+  81, 83, 92, 53, 85, 89, 82, 88, 69, 77,
+  88, 83, 76, 71, 92, 86, 91, 90, 87, 85,
+  84, 80, 88, 86, 65, 71, 84, 118, 68, 91,
+  87, 84, 77, 72, 70, 83, 74, 84, 80, 103,
+  89, 84, 76, 72, 74, 81, 83, 94, 73, 83,
+  79, 90, 87, 83, 86, 73, 84, 65, 83, 85,
+  80, 94, 88, 100, 74, 93, 84, 93, 75, 82,
+  81, 92, 69, 88, 78, 81, 72, 79, 93, 71,
+  92, 71, 90, 97, 66, 79, 87, 79, 102, 86,
+  88, 78, 95, 72, 76, 83, 75, 95, 95, 101,
+  93, 90, 92, 70, 68, 87, 78, 82, 84, 88,
+  76, 80, 93, 82, 88, 94, 86, 89, 89, 66,
+  82, 76, 90, 67, 84, 75, 64, 80, 84, 93,
+  106, 78, 97, 93, 94, 81, 69, 90, 95, 108,
+  79, 67, 89, 88, 105, 79, 95, 85, 103, 76,
+  72, 88, 79, 89, 94, 91, 79, 72, 83, 76,
+  87, 72, 75, 93, 83, 80, 58, 94, 98, 80,
+  87, 78, 74, 95, 97, 81, 86, 85, 93, 81,
+  93, 75, 89, 75, 94, 79, 101, 82, 73, 75,
+  82, 91, 81, 94, 80, 89, 69, 86, 70, 82,
+  71, 92, 72, 90, 65, 66, 85, 81, 90, 71,
+  81, 85, 80, 68, 95, 79, 97, 76, 98, 87,
+  106, 77, 79, 89, 79, 86, 95, 64, 77, 72,
+  96, 61, 79, 96, 90, 88, 86, 97, 76, 73,
+  84, 75, 80, 94, 89, 83, 95, 68, 103, 73,
+  94, 77, 97, 79, 73, 86, 83, 109, 103, 77,
+  76, 89, 90, 74, 58, 90, 93, 102, 78, 57,
+  91, 86, 115, 87, 101, 90, 96, 77, 59, 79,
+  82, 87, 95, 85, 85, 78, 72, 88, 80, 69,
+  80, 93, 74, 81, 55, 102, 120, 78, 77, 75,
+  76, 92, 94, 104, 90, 95, 102, 70, 88, 80,
+  95, 74, 83, 89, 98, 83, 67, 74, 93, 87,
+  95, 95, 83, 70, 71, 77, 84, 87, 71, 86,
+  84, 91, 83, 78, 99, 72, 93, 71, 64, 97,
+  87, 82, 88, 79, 96, 88, 82, 81, 95, 83,
+  81, 85, 79, 86, 88, 97, 74, 91, 86, 74,
+  87, 90, 76, 80, 93, 98, 80, 83, 84, 76,
+  89, 90, 88, 81, 81, 74, 86, 77, 93, 78,
+  87, 75, 75, 76, 88, 88, 104, 80, 78, 91,
+  85, 84, 65, 85, 93, 82, 80, 70, 92, 87,
+  98, 94, 93, 99, 75, 75, 71, 82, 78, 77,
+  88, 96, 81, 78, 86, 81, 72, 60, 72, 79,
+  85, 81, 66, 97, 90, 82, 81, 85, 80, 94,
+  97, 118, 83, 88, 100, 88, 94, 81, 95, 81,
+  93, 78, 100, 82, 79, 80, 82, 96, 88, 69,
+  87, 76, 87, 74, 68, 72, 72, 87, 88, 82,
+  85, 75, 90, 79, 72, 81, 71, 83, 87, 96,
+  59, 92, 82, 71, 80, 83, 89, 81, 79, 73,
+  92, 72, 79, 83, 85, 93, 76, 84, 75, 73,
+  89, 73, 80, 92, 83, 92, 81, 94, 84, 79,
+  83, 88, 80, 80, 83, 82, 83, 90, 81, 60,
+  81, 70, 82, 80, 80, 84, 79, 91, 86, 78,
+  97, 66, 77, 90, 108, 95, 86, 76, 84, 79,
+  87, 70, 89, 94, 84, 91, 88, 69, 78, 98,
+  79, 81, 89, 89, 100, 85, 84, 84, 77, 89,
+  88, 76, 81, 84, 91, 71, 88, 82, 74, 94,
+  83, 86, 83, 91, 75, 86, 71, 80, 70, 84,
+  88, 100, 85, 89, 79, 114, 81, 87, 81, 75,
+  94, 79, 74, 82, 69, 90, 92, 81, 79, 78,
+  76, 75, 74, 87, 74, 76, 105, 100, 63, 88,
+  87, 77, 106, 83, 80, 81, 69, 81, 103, 88,
+  87, 87, 76, 91, 72, 69, 67, 76, 75, 88,
+  86, 79, 76, 85, 86, 89, 97, 67, 82, 97,
+  73, 74, 99, 80, 78, 76, 80, 56, 67, 47,
+  69, 71, 72, 86, 114, 95, 77, 86, 97, 77,
+  77, 108, 120, 84, 82, 80, 78, 83, 72, 69,
+  104, 97, 84, 97, 77, 82, 89, 99, 106, 74,
+  85, 85, 114, 68, 83, 76, 70, 91, 90, 91,
+  84, 76, 85, 85, 80, 94, 68, 99, 81, 85,
+  70, 84, 78, 79, 72, 92, 78, 83, 93, 94,
+  84, 82, 95, 99, 82, 111, 83, 74, 82, 85,
+  87, 88, 86, 99, 82, 94, 67, 78, 85, 81,
+  123, 90, 95, 110, 112, 83, 68, 75, 97, 97,
+  124, 87, 83, 110, 72, 91, 75, 82, 81, 94,
+  78, 76, 74, 61, 74, 101, 70, 100, 86, 71,
+  73, 75, 89, 86, 96, 71, 107, 87, 96, 74,
+  91, 85, 80, 75, 83, 59, 59, 54, 66, 90,
+  83, 82, 122, 86, 79, 95, 80, 92, 80, 115,
+  119, 70, 78, 81, 71, 90, 75, 80, 95, 102,
+  70, 103, 67, 81, 86, 77, 126, 71, 88, 80,
+  114, 60, 92, 79, 82, 95, 89, 102, 90, 76,
+  84, 95, 80, 112, 66, 90, 86, 77, 77, 85,
+  82, 70, 85, 96, 77, 94, 94, 82, 79, 74,
+  86, 71, 89, 78, 80, 82, 83, 73, 79, 71,
+  85, 87, 88, 89, 88, 77, 89, 87, 74, 83,
+  83, 89, 74, 86, 75, 83, 84, 68, 79, 85,
+  96, 82, 90, 74, 90, 72, 82, 81, 87, 76,
+  76, 97, 82, 83, 96, 67, 79, 90, 87, 97,
+  87, 90, 82, 93, 89, 80, 89, 85, 76, 92,
+  88, 92, 79, 86, 87, 96, 86, 89, 92, 81,
+  79, 91, 86, 74, 83, 70, 84, 84, 71, 88,
+  89, 83, 96, 88, 95, 76, 83, 81, 82, 80,
+  91, 65, 77, 88, 78, 84, 87, 89, 87, 99,
+  85, 94, 84, 85, 76, 78, 81, 92, 94, 59,
+  98, 79, 82, 92, 88, 86, 85, 96, 76, 85,
+  71, 80, 60, 86, 81, 80, 85, 100, 81, 95,
+  76, 78, 82, 80, 91, 71, 83, 70, 76, 90,
+  87, 87, 90, 77, 83, 78, 67, 77, 78, 78,
+  73, 95, 72, 95, 77, 67, 86, 82, 88, 82,
+  88, 83, 96, 72, 83, 85, 72, 89, 69, 71,
+  77, 81, 84, 77, 82, 78, 86, 92, 91, 87,
+  90, 81, 73, 82, 79, 81, 86, 89, 85, 82,
+  76, 76, 67, 76, 86, 82, 85, 77, 82, 88,
+  79, 82, 96, 73, 79, 88, 95, 91, 90, 86,
+  87, 78, 82, 74, 93, 82, 88, 92, 81, 76,
+  84, 102, 86, 86, 86, 91, 100, 90, 82, 83,
+  79, 90, 85, 75, 80, 90, 86, 67, 85, 81,
+  81, 96, 86, 87, 70, 98, 76, 83, 75, 75,
+  68, 81, 80, 91, 87, 92, 85, 104, 77, 94,
+  79, 69, 89, 71, 79, 86, 74, 94, 87, 91,
+  76, 75, 75, 77, 87, 77, 77, 91, 100, 91,
+  70, 87, 94, 85, 91, 86, 86, 90, 72, 87,
+  88, 77, 85, 85, 73, 85, 71, 57, 72, 83,
+  68, 78, 90, 71, 81, 90, 80, 85, 96, 72,
+  77, 81, 79, 80, 84, 85, 86, 82, 77, 76,
+  75, 66, 82, 80, 76, 82, 112, 80, 73, 94,
+  92, 81, 78, 111, 132, 64, 90, 84, 73, 76,
+  78, 83, 82, 90, 83, 89, 73, 79, 89, 91,
+  109, 83, 86, 76, 104, 64, 82, 71, 91, 91,
+  89, 83, 79, 82, 90, 80, 83, 92, 75, 94,
+  90, 72, 79, 90, 80, 77, 81, 85, 76, 84,
+  85, 90, 84, 77, 85, 76, 90, 84, 82, 77,
+  79, 79, 83, 81, 87, 90, 83, 81, 75, 82,
+  74, 98, 79, 88, 78, 85, 89, 83, 77, 67,
+  95, 79, 82, 87, 92, 79, 92, 76, 89, 74,
+  83, 84, 89, 74, 91, 92, 90, 82, 90, 72,
+  87, 83, 82, 96, 92, 88, 82, 94, 94, 79,
+  93, 87, 78, 93, 88, 90, 82, 89, 95, 95,
+  85, 87, 85, 89, 74, 89, 86, 72, 86, 73,
+  81, 89, 83, 74, 85, 87, 98, 96, 91, 80,
+  78, 81, 83, 88, 102, 70, 80, 80, 77, 85,
+  83, 80, 84, 93, 97, 95, 85, 83, 81, 81,
+  83, 88, 101, 65, 92, 84, 81, 95, 87, 82,
+  91, 89, 77, 90, 77, 76, 67, 79, 86, 80,
+  90, 95, 88, 86, 81, 84, 85, 80, 88, 73,
+  88, 73, 85, 91, 92, 89, 93, 78, 82, 94,
+  73, 85, 74, 84, 77, 87, 77, 77, 79, 72,
+  77, 89, 92, 82, 91, 85, 91, 71, 82, 84,
+  82, 86, 82, 92, 93, 84, 86, 72, 85, 78,
+  80, 97, 97, 92, 87, 88, 85, 82, 85, 87,
+  81, 91, 90, 83, 77, 90, 77, 93, 85, 81,
+  90, 83, 78, 91, 81, 71, 87, 68, 81, 78,
+  83, 90, 88, 84, 96, 83, 89, 75, 88, 81,
+  84, 90, 88, 75, 80, 91, 78, 85, 86, 94,
+  87, 98, 87, 94, 82, 90, 78, 79, 78, 93,
+  95, 67, 84, 82, 79, 96, 85, 84, 77, 99,
+  80, 82, 78, 74, 65, 75, 78, 86, 89, 96,
+  79, 100, 79, 89, 80, 74, 90, 70, 88, 76,
+  82, 97, 86, 92, 87, 72, 78, 90, 82, 76,
+  70, 78, 107, 85, 73, 86, 78, 80, 80, 78,
+  86, 85, 77, 83, 89, 76, 84, 79, 75, 91,
+  78, 67, 83, 86, 71, 85, 88, 76, 82, 92,
+  89, 83, 87, 81, 81, 82, 80, 95, 79, 86,
+  93, 91, 73, 82, 90, 74, 92, 80, 85, 79,
+  104, 79, 76, 85, 90, 71, 77, 102, 111, 77,
+  91, 85, 84, 85, 79, 80, 82, 84, 88, 89,
+  78, 75, 86, 93, 91, 83, 88, 89, 93, 80,
+  82, 83, 87, 93, 76, 85, 75, 90, 89, 75,
+  82, 86, 76, 96, 83, 81, 78, 91, 74, 74,
+  81, 76, 72, 80, 79, 95, 86, 90, 71, 82,
+  76, 72, 90, 103, 69, 97, 70, 83, 70, 96,
+  76, 84, 89, 66, 95, 91, 89, 75, 93, 74,
+  67, 90, 71, 104, 72, 83, 98, 93, 82, 79,
+  75, 91, 88, 84, 86, 80, 90, 96, 73, 87,
+  65, 77, 96, 81, 69, 79, 75, 83, 83, 92,
+  92, 95, 86, 81, 81, 90, 82, 81, 86, 80,
+  69, 85, 105, 79, 90, 81, 69, 84, 77, 76,
+  91, 81, 83, 76, 75, 78, 92, 91, 83, 79,
+  80, 89, 85, 80, 81, 106, 99, 73, 75, 78,
+  60, 80, 93, 82, 91, 89, 76, 76, 85, 81,
+  76, 86, 92, 94, 101, 76, 88, 102, 98, 81,
+  78, 87, 73, 79, 88, 82, 76, 87, 84, 88,
+  96, 73, 76, 85, 74, 91, 74, 85, 75, 67,
+  89, 88, 73, 106, 69, 80, 65, 93, 76, 85,
+  84, 66, 92, 89, 84, 78, 76, 73, 79, 92,
+  72, 104, 77, 85, 95, 91, 83, 73, 78, 81,
+  91, 84, 85, 82, 93, 92, 71, 87, 90, 72,
+  108, 81, 63, 83, 79, 85, 86, 85, 85, 97,
+  79, 83, 79, 85, 78, 81, 84, 82, 72, 79,
+  97, 80, 87, 79, 66, 82, 78, 76, 93, 85,
+  82, 77, 73, 88, 96, 93, 81, 86, 77, 79,
+  83, 85, 81, 108, 103, 69, 75, 76, 60, 81,
+  92, 81, 96, 92, 69, 75, 84, 74, 77, 86,
+  89, 87, 103, 77, 92, 108, 113, 80, 84, 84,
+  66, 75, 74, 83, 76, 91, 83, 92, 77, 73,
+  70, 87, 75, 98, 76, 99, 80, 71, 89, 78,
+  77, 95, 76, 81, 68, 92, 75, 88, 91, 65,
+  91, 87, 86, 88, 63, 75, 90, 93, 82, 97,
+  73, 82, 91, 85, 79, 74, 80, 76, 86, 81,
+  85, 81, 89, 90, 72, 81, 98, 80, 90, 82,
+  71, 85, 74, 87, 81, 83, 83, 95, 90, 86,
+  81, 92, 82, 79, 82, 89, 73, 87, 111, 77,
+  92, 80, 71, 83, 91, 79, 99, 80, 90, 80,
+  76, 91, 96, 93, 83, 79, 75, 75, 86, 84,
+  82, 106, 94, 70, 80, 77, 62, 79, 96, 84,
+  88, 86, 73, 81, 81, 76, 78, 84, 90, 94,
+  98, 78, 89, 96, 97, 79, 74, 79, 68, 81,
+  78, 77, 79, 89, 88, 82, 87, 74, 78, 83,
+  78, 90, 69, 85, 72, 79, 91, 96, 71, 99,
+  64, 76, 74, 96, 81, 95, 89, 80, 103, 84,
+  84, 76, 86, 75, 66, 93, 72, 93, 77, 82,
+  98, 92, 86, 75, 70, 96, 86, 84, 90, 82,
+  92, 103, 77, 83, 54, 77, 95, 84, 76, 80,
+  77, 84, 80, 86, 100, 92, 79, 83, 79, 87,
+  75, 82, 91, 77, 70, 95, 92, 82, 104, 73,
+  79, 78, 77, 74, 82, 71, 85, 73, 78, 80,
+  89, 85, 85, 78, 76, 82, 90, 87, 87, 101,
+  99, 78, 69, 87, 67, 79, 90, 74, 92, 93,
+  83, 76, 84, 78, 79, 89, 99, 79, 89, 76,
+  81, 103, 91, 76, 81, 87, 76, 74, 86, 79,
+  77, 78, 87, 95, 84, 74, 66, 90, 73, 94,
+  73, 91, 77, 78, 93, 82, 72, 113, 61, 72,
+  69, 96, 86, 91, 82, 77, 101, 82, 81, 75,
+  63, 74, 74, 94, 77, 96, 82, 84, 101, 85,
+  93, 72, 67, 90, 93, 82, 89, 82, 98, 113,
+  72, 86, 68, 71, 97, 81, 76, 84, 83, 86,
+  84, 81, 92, 93, 72, 81, 77, 81, 72, 90,
+  90, 77, 66, 92, 84, 90, 104, 71, 76, 75,
+  74, 76, 81, 70, 89, 72, 76, 89, 92, 87,
+  79, 90, 74, 77, 97, 90, 89, 104, 107, 74,
+  64, 81, 68, 79, 87, 72, 100, 98, 75, 72,
+  84, 79, 79, 90, 98, 73, 86, 74, 87, 107,
+  103, 76, 87, 91, 72, 69, 73, 81, 76, 72,
+  87, 100, 63, 72, 56, 92, 72, 99, 72, 103,
+  85, 80, 91, 72, 72, 97, 69, 77, 71, 93,
+  77, 87, 89, 82, 96, 82, 81, 86, 60, 76,
+  88, 96, 85, 95, 79, 81, 89, 75, 87, 72,
+  73, 82, 90, 79, 90, 83, 95, 94, 79, 81,
+  91, 80, 87, 85, 82, 85, 76, 84, 79, 80,
+  88, 90, 83, 78, 81, 89, 79, 78, 88, 88,
+  72, 96, 95, 79, 97, 74, 76, 80, 86, 72,
+  87, 71, 88, 78, 77, 90, 94, 86, 84, 79,
+  76, 75, 91, 86, 87, 100, 95, 77, 72, 83,
+  69, 79, 92, 78, 89, 89, 73, 82, 81, 79,
+  82, 87, 92, 79, 85, 77, 82, 93, 94, 76,
+  80, 88, 75, 75, 79, 75, 78, 80, 92, 86,
+  78, 76, 71, 86, 77, 90, 70, 87, 74, 83,
+  85, 98, 72, 99, 73, 78, 76, 90, 80, 98,
+  96, 88, 113, 92, 84, 76, 81, 78, 68, 95,
+  77, 89, 81, 84, 92, 85, 81, 75, 65, 91,
+  80, 85, 89, 90, 93, 102, 85, 83, 68, 85,
+  83, 83, 83, 83, 73, 87, 82, 88, 97, 96,
+  89, 91, 81, 84, 82, 82, 83, 81, 77, 90,
+  94, 74, 102, 71, 91, 85, 88, 81, 83, 69,
+  87, 73, 79, 80, 81, 80, 91, 77, 79, 83,
+  92, 88, 89, 91, 94, 87, 75, 99, 64, 80,
+  80, 74, 88, 80, 88, 84, 85, 78, 79, 90,
+  92, 75, 90, 80, 83, 96, 87, 77, 81, 90,
+  73, 70, 86, 73, 77, 74, 81, 86, 101, 71,
+  70, 78, 73, 90, 70, 89, 85, 84, 88, 83,
+  70, 104, 69, 78, 72, 87, 82, 96, 92, 86,
+  109, 87, 80, 73, 71, 77, 78, 101, 81, 86,
+  86, 89, 85, 78, 86, 72, 65, 85, 87, 78,
+  90, 93, 101, 106, 84, 89, 65, 80, 80, 79,
+  87, 83, 79, 86, 82, 83, 92, 90, 82, 84,
+  77, 77, 78, 84, 85, 82, 72, 92, 84, 76,
+  106, 68, 92, 86, 79, 80, 84, 68, 93, 72,
+  78, 87, 80, 87, 82, 83, 79, 78, 96, 90,
+  91, 92, 98, 85, 72, 92, 64, 84, 75, 73,
+  91, 84, 76, 87, 84, 78, 81, 90, 94, 68,
+  85, 76, 83, 98, 89, 78, 89, 89, 73, 67,
+  79, 76, 78, 67, 85, 83, 85, 71, 63, 77,
+  72, 91, 71, 95, 97, 84, 82, 70, 75, 98,
+  74, 81, 77, 90, 75, 90, 97, 89, 105, 89,
+  83, 83, 78, 80, 95, 97, 84, 93, 85, 86,
+  81, 70, 86, 70, 68, 78, 85, 72, 85, 91,
+  98, 96, 91, 86, 75, 85, 79, 82, 89, 85,
+  74, 87, 79, 85, 91, 87, 92, 77, 81, 84,
+  85, 81, 84, 89, 78, 96, 96, 75, 102, 71,
+  85, 94, 83, 77, 88, 75, 88, 75, 80, 93,
+  85, 83, 91, 77, 79, 81, 93, 87, 91, 91,
+  93, 82, 75, 88, 66, 81, 82, 79, 84, 81,
+  71, 88, 83, 74, 81, 88, 87, 72, 88, 79,
+  83, 88, 92, 78, 84, 88, 80, 75, 87, 71,
+  79, 81, 93, 79, 92, 72, 74, 78, 74, 87,
+  78, 78, 94, 93, 75, 82, 107, 67, 73, 93,
+  85, 67, 79, 96, 81, 87, 81, 83, 81, 87,
+  72, 94, 80, 78, 92, 75, 90, 95, 95, 94,
+  93, 77, 91, 88, 82, 93, 90, 88, 84, 87,
+  89, 80, 81, 85, 93, 88, 86, 88, 68, 73,
+  76, 93, 104, 71, 98, 84, 90, 83, 87, 93,
+  77, 78, 84, 78, 95, 84, 80, 80, 79, 92,
+  72, 84, 74, 78, 87, 80, 70, 99, 92, 88,
+  98, 68, 94, 73, 85, 93, 88, 80, 88, 102,
+  61, 86, 69, 86, 78, 92, 86, 82, 80, 100,
+  74, 88, 86, 70, 78, 79, 107, 74, 87, 64,
+  77, 94, 84, 94, 81, 85, 88, 87, 98, 68,
+  128, 77, 91, 87, 56, 76, 82, 81, 74, 89,
+  82, 101, 51, 85, 118, 60, 65, 94, 81, 60,
+  82, 77, 79, 97, 85, 99, 78, 89, 82, 70,
+  79, 76, 93, 77, 102, 95, 107, 97, 92, 74,
+  96, 84, 88, 79, 85, 96, 78, 81, 83, 82,
+  82, 83, 86, 97, 87, 90, 57, 64, 75, 73,
+  129, 70, 85, 83, 87, 78, 83, 92, 85, 74,
+  82, 82, 93, 82, 84, 74, 78, 84, 82, 72,
+  62, 70, 81, 70, 70, 88, 92, 81, 106, 61,
+  100, 84, 86, 82, 95, 65, 97, 102, 67, 80,
+  68, 81, 67, 91, 87, 72, 87, 81, 60, 80,
+  96, 70, 63, 82, 116, 70, 92, 69, 79, 101,
+  82, 89, 83, 85, 86, 85, 94, 65, 94, 68,
+  92, 83, 44, 83, 81, 75, 78, 90, 72, 95,
+  80, 89, 97, 73, 73, 89, 83, 72, 85, 75,
+  80, 86, 89, 77, 80, 78, 80, 95, 93, 77,
+  83, 79, 89, 94, 85, 88, 92, 82, 84, 95,
+  94, 82, 97, 90, 85, 90, 83, 81, 75, 89,
+  92, 94, 74, 90, 70, 79, 78, 89, 90, 72,
+  94, 89, 81, 84, 93, 93, 82, 80, 92, 69,
+  93, 82, 91, 88, 82, 82, 87, 84, 68, 78,
+  78, 83, 74, 78, 102, 92, 98, 77, 97, 113,
+  77, 87, 95, 81, 97, 107, 64, 88, 66, 88,
+  94, 88, 82, 90, 78, 101, 77, 81, 84, 69,
+  84, 80, 97, 75, 92, 71, 83, 89, 86, 90,
+  82, 88, 88, 86, 98, 81, 73, 87, 88, 78,
+  68, 89, 84, 88, 88, 75, 86, 87, 76, 86,
+  107, 74, 78, 89, 86, 74, 85, 77, 80, 96,
+  99, 97, 73, 85, 75, 89, 82, 76, 78, 69,
+  93, 94, 101, 88, 94, 82, 89, 82, 78, 92,
+  78, 84, 85, 89, 80, 75, 83, 86, 77, 89,
+  90, 87, 67, 77, 76, 79, 104, 76, 91, 90,
+  87, 77, 88, 101, 69, 73, 80, 77, 88, 71,
+  88, 86, 79, 70, 85, 74, 94, 83, 89, 67,
+  74, 92, 87, 89, 99, 66, 88, 68, 86, 86,
+  84, 86, 87, 81, 64, 84, 74, 85, 67, 82,
+  82, 77, 96, 83, 61, 78, 78, 70, 81, 74,
+  104, 82, 79, 82, 74, 98, 82, 92, 76, 79,
+  94, 87, 91, 64, 119, 85, 102, 81, 53, 83,
+  79, 82, 81, 87, 81, 93, 52, 81, 120, 67,
+  65, 95, 80, 67, 82, 69, 81, 109, 105, 117,
+  68, 89, 79, 67, 77, 78, 88, 67, 105, 96,
+  111, 86, 93, 76, 89, 77, 77, 75, 67, 79,
+  70, 76, 86, 75, 87, 84, 70, 97, 92, 82,
+  57, 68, 71, 62, 121, 76, 74, 79, 83, 70,
+  79, 98, 79, 69, 75, 82, 80, 67, 94, 84,
+  85, 62, 75, 64, 84, 81, 86, 58, 73, 87,
+  90, 78, 104, 55, 95, 75, 90, 76, 92, 72,
+  90, 74, 73, 84, 74, 88, 54, 82, 80, 71,
+  88, 70, 47, 75, 87, 71, 80, 71, 111, 80,
+  78, 80, 73, 105, 81, 88, 77, 76, 80, 82,
+  88, 62, 72, 80, 87, 80, 37, 89, 82, 77,
+  83, 98, 75, 88, 83, 90, 93, 73, 77, 84,
+  83, 80, 89, 84, 77, 95, 98, 85, 74, 73,
+  81, 96, 89, 78, 89, 74, 92, 98, 95, 79,
+  92, 84, 84, 86, 85, 85, 79, 83, 81, 87,
+  81, 77, 86, 87, 77, 92, 80, 86, 73, 77,
+  75, 86, 87, 77, 84, 76, 85, 82, 91, 97,
+  74, 73, 80, 71, 87, 76, 99, 89, 86, 66,
+  80, 78, 84, 82, 81, 74, 76, 85, 94, 89,
+  98, 76, 93, 111, 79, 80, 90, 91, 93, 93,
+  67, 81, 75, 88, 83, 79, 80, 86, 76, 88,
+  68, 78, 76, 69, 87, 73, 96, 82, 82, 83,
+  78, 92, 82, 87, 80, 82, 91, 84, 91, 73,
+  63, 92, 91, 76, 65, 87, 83, 85, 101, 76,
+  74, 84, 92, 85, 89, 83, 82, 82, 91, 84,
+  83, 88, 79, 90, 99, 80, 72, 87, 84, 88,
+  83, 81, 75, 71, 89, 86, 82, 88, 90, 86,
+  68, 80, 81, 92, 80, 79, 91, 89, 80, 73,
+  76, 94, 77, 83, 78, 95, 74, 93, 77, 85,
+  76, 86, 98, 87, 78, 90, 95, 89, 58, 85,
+  88, 86, 90, 77, 88, 91, 82, 82, 88, 89,
+  109, 89, 92, 76, 83, 82, 80, 91, 91, 99,
+  83, 75, 86, 85, 78, 105, 94, 73, 63, 92,
+  84, 87, 74, 88, 81, 89, 83, 95, 58, 95,
+  73, 67, 90, 85, 84, 83, 76, 78, 82, 82,
+  88, 92, 82, 86, 90, 94, 90, 73, 104, 100,
+  94, 83, 74, 87, 75, 84, 99, 87, 73, 88,
+  81, 79, 97, 82, 81, 85, 92, 81, 82, 86,
+  87, 97, 104, 86, 73, 85, 76, 84, 83, 83,
+  89, 70, 90, 86, 96, 85, 82, 83, 65, 77,
+  79, 83, 77, 79, 83, 90, 87, 69, 81, 96,
+  71, 89, 80, 79, 66, 90, 74, 85, 83, 83,
+  97, 81, 75, 94, 91, 83, 63, 88, 88, 90,
+  85, 79, 92, 92, 81, 87, 81, 87, 100, 91,
+  92, 73, 82, 86, 83, 84, 94, 88, 83, 91,
+  87, 78, 80, 101, 100, 71, 68, 90, 80, 84,
+  66, 87, 78, 87, 78, 89, 54, 95, 78, 66,
+  93, 80, 85, 84, 78, 76, 86, 84, 88, 79,
+  82, 82, 90, 89, 89, 75, 79, 97, 86, 89,
+  73, 90, 79, 84, 94, 97, 70, 87, 92, 87,
+  86, 81, 83, 80, 88, 84, 83, 88, 76, 88,
+  95, 75, 71, 79, 72, 87, 87, 83, 97, 73,
+  88, 91, 76, 84, 84, 87, 73, 84, 85, 88,
+  83, 85, 88, 83, 80, 73, 88, 92, 75, 86,
+  73, 78, 81, 88, 82, 87, 71, 83, 96, 72,
+  80, 96, 94, 83, 62, 86, 87, 85, 86, 82,
+  100, 90, 84, 84, 82, 89, 99, 88, 87, 81,
+  80, 95, 87, 92, 91, 101, 84, 107, 82, 81,
+  84, 106, 94, 79, 66, 83, 82, 87, 81, 83,
+  77, 91, 76, 96, 64, 90, 72, 67, 88, 86,
+  84, 85, 83, 72, 85, 80, 87, 81, 88, 88,
+  100, 88, 87, 79, 67, 97, 84, 82, 83, 88,
+  77, 82, 89, 76, 65, 88, 71, 85, 75, 85,
+  75, 92, 84, 77, 96, 91, 68, 75, 73, 87,
+  81, 78, 90, 81, 88, 97, 74, 82, 88, 80,
+  100, 104, 88, 83, 85, 102, 76, 79, 93, 83,
+  81, 93, 84, 70, 84, 75, 81, 85, 95, 93,
+  91, 78, 75, 73, 74, 87, 76, 98, 91, 82,
+  80, 100, 96, 89, 80, 76, 80, 79, 76, 96,
+  84, 95, 92, 80, 95, 90, 85, 81, 81, 70,
+  85, 81, 66, 73, 84, 121, 78, 82, 84, 88,
+  82, 88, 80, 73, 97, 86, 77, 82, 81, 74,
+  89, 85, 90, 84, 92, 80, 86, 85, 95, 96,
+  96, 81, 71, 78, 83, 79, 70, 71, 89, 80,
+  95, 96, 68, 93, 84, 90, 98, 87, 83, 73,
+  92, 80, 82, 89, 32, 78, 65, 79, 68, 84,
+  89, 98, 142, 74, 67, 65, 101, 87, 75, 78,
+  76, 66, 92, 77, 82, 86, 75, 73, 118, 76,
+  89, 84, 68, 78, 67, 80, 81, 79, 68, 105,
+  73, 65, 85, 118, 86, 57, 84, 76, 77, 70,
+  83, 70, 61, 90, 58, 87, 82, 83, 68, 98,
+  70, 64, 72, 88, 84, 79, 71, 103, 81, 93,
+  105, 77, 59, 80, 106, 62, 69, 93, 82, 78,
+  60, 95, 71, 90, 121, 73, 79, 101, 84, 77,
+  67, 72, 82, 70, 63, 95, 87, 68, 82, 73,
+  79, 93, 97, 82, 87, 82, 101, 121, 96, 64,
+  121, 64, 79, 79, 97, 64, 87, 64, 90, 76,
+  83, 92, 72, 71, 133, 76, 77, 62, 92, 81,
+  88, 87, 84, 82, 75, 80, 77, 91, 82, 79,
+  72, 72, 72, 77, 83, 79, 83, 84, 81, 85,
+  75, 97, 96, 83, 88, 79, 90, 72, 97, 88,
+  84, 67, 89, 97, 91, 88, 86, 91, 83, 80,
+  85, 77, 86, 94, 97, 72, 94, 81, 80, 89,
+  82, 79, 87, 71, 89, 79, 84, 100, 98, 88,
+  77, 64, 76, 73, 77, 95, 85, 88, 74, 81,
+  104, 88, 99, 87, 80, 100, 90, 81, 70, 63,
+  82, 57, 78, 88, 81, 84, 81, 76, 85, 86,
+  103, 89, 93, 81, 79, 78, 87, 96, 88, 88,
+  93, 82, 84, 94, 88, 95, 92, 82, 94, 81,
+  77, 75, 100, 86, 89, 90, 95, 90, 117, 91,
+  85, 91, 86, 87, 90, 79, 93, 66, 65, 87,
+  68, 87, 78, 83, 82, 90, 87, 78, 72, 93,
+  76, 80, 81, 89, 84, 64, 98, 86, 95, 93,
+  72, 75, 88, 80, 95, 100, 85, 82, 90, 97,
+  78, 73, 89, 82, 79, 92, 86, 69, 87, 81,
+  80, 91, 94, 107, 85, 78, 82, 85, 77, 83,
+  77, 76, 97, 71, 87, 87, 95, 90, 83, 64,
+  83, 72, 76, 80, 89, 90, 80, 68, 92, 93,
+  78, 81, 87, 70, 74, 84, 75, 70, 88, 128,
+  71, 76, 87, 84, 79, 86, 75, 81, 90, 80,
+  79, 81, 83, 76, 84, 85, 86, 89, 85, 83,
+  85, 86, 94, 98, 74, 81, 87, 81, 84, 88,
+  82, 77, 78, 83, 90, 96, 72, 91, 86, 88,
+  84, 83, 82, 74, 92, 81, 82, 92, 28, 77,
+  66, 73, 76, 86, 94, 98, 146, 76, 81, 80,
+  114, 80, 79, 70, 75, 67, 86, 77, 87, 80,
+  72, 73, 111, 70, 102, 86, 70, 86, 64, 71,
+  76, 85, 71, 105, 80, 77, 87, 134, 87, 59,
+  86, 81, 69, 66, 88, 65, 72, 94, 51, 96,
+  88, 83, 70, 84, 74, 63, 64, 93, 60, 84,
+  74, 81, 91, 79, 91, 65, 56, 77, 100, 59,
+  80, 102, 64, 91, 70, 94, 77, 70, 124, 82,
+  74, 98, 78, 77, 58, 68, 79, 66, 57, 91,
+  91, 84, 78, 76, 68, 81, 92, 84, 79, 82,
+  99, 125, 76, 66, 121, 59, 78, 77, 87, 68,
+  79, 66, 94, 73, 87, 91, 69, 74, 134, 71,
+  77, 62, 84, 82, 79, 88, 86, 88, 77, 84,
+  86, 94, 85, 81, 64, 79, 73, 80, 87, 82,
+  81, 78, 86, 88, 77, 94, 95, 78, 98, 84,
+  86, 79, 73, 91, 91, 44, 88, 101, 88, 85,
+  89, 92, 92, 76, 95, 74, 94, 103, 95, 70,
+  87, 83, 85, 90, 80, 77, 98, 80, 95, 69,
+  93, 85, 92, 94, 77, 56, 76, 68, 71, 86,
+  80, 94, 78, 71, 109, 93, 95, 92, 92, 114,
+  78, 83, 77, 53, 84, 62, 62, 86, 82, 70,
+  74, 77, 78, 87, 101, 85, 91, 77, 80, 77,
+  81, 92, 91, 78, 81, 86, 83, 96, 87, 91,
+  72, 88, 82, 88, 81, 84, 69, 90, 94, 89,
+  90, 98, 120, 90, 81, 91, 74, 87, 84, 82,
+  99, 70, 84, 82, 77, 87, 78, 79, 73, 90,
+  93, 82, 78, 92, 71, 94, 90, 89, 90, 78,
+  92, 77, 82, 95, 81, 77, 86, 79, 83, 82,
+  97, 88, 90, 103, 78, 86, 86, 87, 79, 91,
+  96, 72, 85, 77, 78, 87, 92, 91, 86, 82,
+  85, 84, 78, 83, 83, 68, 96, 83, 86, 95,
+  93, 89, 91, 74, 78, 77, 77, 88, 89, 91,
+  70, 70, 85, 85, 83, 83, 81, 68, 78, 83,
+  74, 70, 88, 121, 87, 83, 83, 85, 91, 83,
+  83, 88, 84, 87, 85, 82, 82, 76, 82, 87,
+  82, 91, 92, 84, 88, 89, 105, 95, 80, 84,
+  104, 82, 86, 90, 95, 79, 61, 89, 88, 90,
+  75, 84, 84, 87, 86, 91, 85, 76, 85, 72,
+  84, 89, 46, 81, 70, 67, 67, 95, 99, 102,
+  119, 82, 81, 89, 101, 79, 73, 75, 73, 70,
+  92, 93, 83, 71, 80, 75, 98, 71, 76, 82,
+  76, 101, 66, 79, 86, 91, 69, 101, 105, 66,
+  85, 100, 75, 74, 82, 81, 72, 77, 84, 79,
+  66, 86, 69, 86, 87, 82, 86, 91, 93, 77,
+  74, 93, 78, 89, 75, 90, 93, 92, 98, 67,
+  59, 71, 92, 68, 83, 97, 68, 83, 66, 83,
+  75, 86, 91, 94, 79, 95, 87, 82, 57, 82,
+  84, 81, 80, 82, 89, 81, 86, 81, 78, 83,
+  88, 84, 81, 90, 93, 105, 74, 81, 104, 62,
+  78, 78, 73, 76, 86, 80, 89, 82, 95, 83,
+  71, 76, 109, 82, 77, 72, 92, 80, 72, 86,
+  94, 77, 82, 82, 74, 91, 94, 81, 77, 91,
+  69, 91, 93, 86, 86, 85, 86, 74, 77, 93,
+  89, 82, 92, 83, 75, 77, 82, 90, 90, 62,
+  78, 99, 93, 81, 86, 85, 103, 73, 88, 78,
+  86, 94, 88, 73, 90, 81, 82, 80, 79, 82,
+  92, 107, 93, 89, 86, 98, 87, 88, 92, 69,
+  73, 73, 73, 100, 85, 88, 83, 73, 97, 87,
+  97, 90, 84, 100, 79, 83, 80, 55, 82, 60,
+  90, 89, 91, 73, 80, 74, 83, 93, 90, 88,
+  99, 76, 79, 72, 87, 84, 84, 83, 90, 84,
+  83, 90, 96, 89, 83, 83, 83, 92, 86, 77,
+  74, 83, 96, 89, 89, 88, 106, 87, 85, 91,
+  82, 86, 86, 81, 72, 84, 89, 91, 79, 82,
+  86, 74, 88, 90, 84, 82, 79, 89, 71, 77,
+  71, 73, 91, 85, 104, 92, 80, 85, 83, 99,
+  67, 84, 89, 87, 87, 76, 78, 100, 78, 85,
+  91, 91, 84, 76, 95, 80, 85, 76, 76, 76,
+  77, 76, 90, 86, 75, 95, 69, 78, 77, 90,
+  82, 83, 80, 82, 93, 83, 82, 84, 90, 74,
+  79, 80, 93, 105, 80, 84, 76, 81, 81, 82,
+  78, 93, 88, 83, 75, 88, 81, 69, 85, 95,
+  86, 87, 87, 94, 69, 81, 88, 80, 87, 89,
+  85, 81, 78, 84, 82, 76, 81, 59, 87, 79,
+  92, 79, 90, 86, 75, 66, 88, 89, 86, 79,
+  77, 68, 81, 106, 90, 75, 86, 86, 93, 78,
+  84, 80, 69, 89, 76, 88, 67, 78, 80, 74,
+  95, 92, 85, 96, 93, 85, 78, 78, 70, 84,
+  89, 85, 90, 88, 75, 80, 93, 98, 72, 95,
+  95, 93, 88, 81, 89, 101, 79, 79, 98, 92,
+  80, 73, 93, 76, 94, 76, 71, 74, 82, 80,
+  81, 85, 71, 97, 72, 78, 82, 90, 83, 75,
+  84, 85, 100, 78, 89, 87, 87, 73, 84, 80,
+  82, 110, 89, 77, 69, 84, 86, 75, 84, 81,
+  91, 80, 84, 77, 74, 67, 84, 91, 83, 89,
+  86, 92, 56, 81, 75, 77, 87, 79, 94, 76,
+  70, 83, 85, 92, 88, 55, 95, 84, 95, 83,
+  96, 89, 80, 70, 89, 84, 87, 86, 70, 61,
+  85, 105, 90, 80, 91, 86, 99, 74, 84, 85,
+  72, 85, 81, 86, 86, 85, 81, 77, 86, 88,
+  83, 78, 77, 90, 76, 78, 74, 78, 87, 86,
+  85, 92, 81, 82, 93, 104, 69, 87, 81, 87,
+  91, 81, 80, 110, 70, 84, 95, 88, 79, 80,
+  92, 83, 94, 81, 80, 75, 77, 88, 94, 83,
+  80, 86, 67, 79, 78, 81, 79, 81, 84, 83,
+  92, 87, 87, 83, 85, 73, 81, 84, 89, 91,
+  89, 82, 77, 82, 85, 87, 71, 81, 96, 84,
+  73, 83, 81, 69, 85, 91, 92, 86, 88, 92,
+  72, 78, 87, 78, 101, 86, 81, 83, 71, 88,
+  83, 86, 78, 59, 86, 79, 85, 81, 87, 90,
+  81, 68, 87, 90, 89, 79, 82, 69, 81, 102,
+  81, 79, 81, 80, 95, 74, 85, 81, 68, 75,
+  86, 83, 67, 82, 93, 86, 101, 79, 94, 94,
+  86, 78, 80, 89, 74, 93, 84, 81, 126, 105,
+  76, 70, 84, 99, 63, 78, 107, 82, 93, 77,
+  98, 77, 89, 96, 83, 81, 75, 73, 85, 88,
+  77, 71, 71, 92, 82, 84, 80, 106, 64, 90,
+  73, 83, 87, 82, 76, 67, 80, 92, 79, 88,
+  83, 67, 95, 69, 82, 80, 86, 91, 87, 87,
+  84, 76, 81, 75, 95, 100, 68, 79, 99, 61,
+  76, 69, 78, 85, 83, 75, 82, 82, 63, 83,
+  77, 79, 58, 78, 89, 73, 98, 70, 80, 84,
+  86, 56, 95, 83, 97, 82, 86, 97, 73, 78,
+  81, 83, 95, 84, 84, 67, 93, 91, 91, 84,
+  98, 92, 94, 88, 77, 97, 58, 100, 79, 78,
+  47, 75, 98, 91, 99, 82, 101, 122, 96, 69,
+  86, 97, 83, 113, 82, 82, 97, 91, 70, 68,
+  99, 95, 75, 84, 112, 100, 104, 77, 121, 71,
+  94, 74, 84, 94, 72, 71, 80, 90, 103, 63,
+  66, 98, 94, 83, 72, 110, 56, 71, 86, 89,
+  92, 81, 78, 53, 85, 101, 87, 83, 83, 77,
+  76, 67, 96, 85, 74, 84, 72, 78, 74, 70,
+  95, 62, 114, 86, 69, 77, 114, 43, 70, 76,
+  77, 83, 80, 68, 78, 94, 52, 76, 66, 78,
+  51, 63, 97, 67, 89, 60, 76, 91, 98, 57,
+  102, 76, 102, 84, 98, 105, 73, 92, 88, 83,
+  88, 94, 75, 64, 115, 86, 82, 97, 96, 100,
+  90, 88, 81, 107, 69, 92, 95, 81, 78, 80,
+  87, 84, 101, 78, 92, 94, 81, 78, 81, 90,
+  76, 94, 81, 79, 77, 102, 86, 69, 94, 103,
+  69, 80, 98, 87, 87, 85, 96, 88, 76, 79,
+  84, 80, 74, 77, 81, 89, 114, 76, 74, 90,
+  84, 93, 86, 94, 69, 79, 70, 87, 84, 85,
+  74, 71, 86, 85, 81, 95, 88, 71, 92, 72,
+  90, 79, 77, 77, 95, 87, 79, 75, 85, 81,
+  80, 81, 76, 83, 97, 64, 79, 83, 83, 81,
+  83, 83, 88, 88, 69, 79, 78, 79, 78, 76,
+  86, 80, 73, 76, 86, 87, 86, 56, 91, 83,
+  89, 84, 89, 97, 75, 81, 83, 88, 90, 82,
+  94, 71, 95, 91, 58, 87, 87, 88, 96, 82,
+  78, 92, 77, 73, 81, 96, 75, 89, 92, 82,
+  87, 78, 90, 88, 90, 73, 67, 100, 89, 96,
+  86, 80, 103, 92, 67, 69, 90, 89, 76, 76,
+  84, 76, 91, 80, 92, 85, 89, 93, 85, 81,
+  80, 80, 80, 91, 77, 73, 78, 83, 92, 92,
+  89, 98, 61, 84, 72, 88, 84, 86, 76, 74,
+  85, 92, 84, 86, 87, 74, 103, 74, 88, 85,
+  90, 85, 101, 81, 97, 69, 72, 69, 85, 96,
+  80, 85, 96, 64, 85, 73, 78, 79, 85, 69,
+  89, 83, 66, 100, 90, 81, 71, 83, 81, 73,
+  109, 78, 87, 88, 81, 57, 89, 90, 93, 79,
+  81, 104, 71, 73, 85, 79, 95, 83, 76, 75,
+  88, 77, 87, 87, 93, 93, 96, 92, 79, 91,
+  71, 92, 93, 91, 64, 76, 93, 89, 85, 78,
+  94, 109, 95, 75, 70, 108, 101, 113, 90, 80,
+  77, 89, 74, 61, 95, 89, 80, 77, 88, 87,
+  89, 75, 99, 72, 93, 77, 87, 89, 74, 81,
+  83, 83, 86, 71, 76, 84, 113, 81, 80, 94,
+  53, 83, 76, 94, 87, 86, 76, 64, 82, 97,
+  86, 84, 83, 79, 96, 71, 102, 92, 85, 89,
+  81, 67, 87, 65, 88, 51, 93, 81, 83, 82,
+  107, 54, 83, 80, 82, 76, 82, 71, 87, 79,
+  57, 96, 77, 87, 57, 74, 84, 65, 93, 73,
+  88, 86, 93, 60, 90, 82, 90, 82, 83, 102,
+  71, 82, 91, 81, 95, 83, 81, 68, 112, 75,
+  75, 89, 83, 99, 92, 88, 88, 96, 79, 95,
+  103, 92, 82, 72, 91, 81, 85, 78, 88, 87,
+  86, 89, 72, 100, 88, 94, 85, 81, 79, 90,
+  93, 70, 91, 92, 78, 77, 74, 87, 89, 82,
+  97, 81, 78, 83, 83, 81, 73, 79, 81, 92,
+  99, 77, 80, 80, 94, 86, 94, 93, 64, 88,
+  71, 92, 75, 80, 73, 80, 86, 83, 85, 88,
+  87, 77, 100, 79, 98, 83, 83, 83, 77, 79,
+  88, 69, 82, 71, 78, 86, 80, 85, 95, 66,
+  85, 84, 81, 72, 80, 84, 89, 85, 69, 85,
+  91, 82, 82, 79, 79, 80, 76, 78, 90, 76,
+  80, 57, 87, 91, 89, 82, 86, 96, 73, 72,
+  87, 89, 92, 85, 101, 76, 87, 83, 67, 86,
+  86, 90, 94, 89, 80, 90, 77, 84, 73, 95,
+  89, 92, 79, 91, 70, 83, 84, 72, 91, 83,
+  82, 110, 108, 107, 96, 93, 86, 89, 88, 80,
+  83, 83, 79, 94, 88, 85, 78, 88, 96, 86,
+  82, 82, 74, 88, 86, 95, 79, 76, 86, 89,
+  61, 88, 93, 86, 83, 87, 84, 82, 80, 81,
+  88, 87, 73, 92, 75, 79, 83, 65, 74, 72,
+  100, 66, 84, 87, 94, 80, 80, 74, 100, 92,
+  73, 84, 73, 79, 83, 68, 96, 85, 75, 85,
+  86, 77, 104, 73, 78, 75, 87, 82, 82, 88,
+  98, 80, 85, 92, 97, 77, 87, 97, 86, 81,
+  85, 87, 86, 93, 82, 90, 71, 87, 101, 93,
+  85, 82, 87, 80, 81, 83, 78, 90, 91, 84,
+  90, 92, 81, 88, 76, 84, 87, 94, 94, 74,
+  80, 91, 84, 79, 88, 66, 98, 78, 79, 109,
+  102, 99, 98, 98, 90, 85, 77, 81, 87, 85,
+  82, 97, 95, 84, 76, 106, 106, 86, 81, 77,
+  65, 95, 86, 90, 76, 72, 84, 86, 57, 96,
+  102, 74, 76, 85, 82, 81, 86, 83, 90, 79,
+  73, 77, 72, 82, 87, 74, 71, 67, 90, 70,
+  90, 81, 97, 76, 81, 63, 109, 85, 78, 87,
+  71, 86, 81, 64, 96, 80, 78, 89, 84, 77,
+  92, 70, 76, 76, 90, 72, 67, 90, 96, 84,
+  87, 85, 93, 82, 89, 90, 82, 82, 79, 93,
+  88, 92, 86, 82, 64, 76, 94, 94, 79, 75,
+  88, 77, 78, 80, 94, 84, 88, 82, 84, 82,
+  85, 94, 81, 82, 94, 89, 86, 85, 76, 94,
+  77, 83, 88, 74, 91, 85, 80, 102, 97, 104,
+  90, 97, 84, 89, 93, 77, 87, 82, 83, 92,
+  79, 77, 78, 96, 95, 83, 85, 76, 71, 89,
+  85, 93, 87, 83, 85, 89, 68, 94, 96, 73,
+  85, 87, 81, 72, 82, 81, 92, 83, 71, 91,
+  80, 79, 82, 77, 80, 79, 103, 70, 92, 87,
+  89, 88, 87, 84, 98, 93, 79, 80, 73, 88,
+  84, 70, 94, 85, 81, 87, 82, 88, 88, 78,
+  80, 68, 84, 75, 85, 84, 90, 81, 83, 96,
+  78, 76, 81, 93, 82, 82, 87, 89, 86, 87,
+  81, 91, 76, 87, 95, 102, 86, 86, 82, 82,
+  83, 78, 88, 90, 87, 80, 93, 89, 82, 87,
+  67, 73, 84, 71, 85, 78, 77, 80, 88, 80,
+  82, 81, 72, 83, 78, 93, 80, 78, 84, 79,
+  82, 91, 78, 100, 79, 70, 85, 80, 88, 81,
+  81, 95, 93, 77, 83, 92, 91, 67, 100, 62,
+  76, 103, 81, 72, 73, 75, 78, 84, 99, 68,
+  110, 83, 83, 76, 86, 106, 77, 85, 85, 81,
+  89, 90, 81, 86, 66, 76, 99, 86, 94, 66,
+  80, 108, 80, 79, 68, 77, 84, 81, 55, 86,
+  81, 83, 77, 77, 86, 58, 89, 84, 70, 78,
+  90, 66, 87, 78, 79, 91, 78, 77, 98, 115,
+  74, 99, 96, 89, 92, 76, 67, 87, 81, 79,
+  72, 85, 88, 87, 108, 83, 75, 82, 84, 97,
+  88, 91, 83, 73, 81, 75, 96, 86, 58, 74,
+  74, 59, 78, 72, 79, 74, 84, 78, 87, 80,
+  66, 106, 75, 77, 70, 66, 79, 77, 85, 94,
+  78, 102, 81, 66, 77, 77, 95, 84, 89, 100,
+  84, 73, 85, 91, 96, 54, 101, 60, 74, 148,
+  83, 66, 73, 65, 74, 88, 99, 61, 121, 82,
+  82, 81, 84, 104, 75, 74, 102, 81, 83, 96,
+  85, 74, 47, 101, 100, 88, 84, 41, 82, 113,
+  72, 62, 68, 82, 92, 83, 46, 108, 76, 77,
+  72, 71, 96, 53, 82, 83, 71, 72, 82, 48,
+  92, 79, 67, 99, 75, 73, 105, 133, 66, 95,
+  104, 90, 83, 87, 66, 90, 68, 74, 83, 71,
+  83, 88, 122, 86, 72, 85, 91, 93, 87, 90,
+  70, 76, 77, 55, 98, 94, 76, 81, 80, 76,
+  86, 83, 74, 85, 85, 84, 86, 79, 74, 97,
+  76, 88, 77, 81, 81, 82, 78, 89, 89, 93,
+  83, 72, 90, 79, 76, 76, 86, 96, 98, 81,
+  84, 82, 84, 68, 77, 71, 79, 96, 77, 76,
+  77, 81, 78, 84, 95, 74, 97, 78, 84, 74,
+  87, 82, 70, 89, 85, 82, 86, 86, 91, 85,
+  75, 71, 89, 86, 91, 83, 83, 111, 81, 83,
+  76, 75, 81, 82, 67, 80, 85, 82, 84, 79,
+  83, 74, 88, 88, 73, 77, 94, 62, 92, 78,
+  90, 88, 80, 84, 85, 100, 71, 89, 93, 89,
+  97, 78, 73, 85, 82, 82, 87, 87, 85, 93,
+  101, 84, 77, 86, 86, 89, 83, 85, 88, 74,
+  88, 76, 88, 85, 78, 75, 74, 87, 83, 85,
+  81, 101, 81, 80, 86, 84, 79, 113, 81, 78,
+  80, 95, 95, 85, 95, 94, 96, 86, 78, 85,
+  93, 82, 97, 87, 76, 96, 89, 80, 86, 94,
+  76, 87, 85, 72, 98, 119, 78, 91, 88, 90,
+  74, 95, 84, 71, 117, 83, 81, 85, 80, 77,
+  77, 84, 95, 80, 87, 77, 94, 68, 75, 82,
+  90, 67, 81, 65, 86, 94, 95, 87, 71, 67,
+  77, 81, 63, 82, 87, 91, 85, 71, 88, 79,
+  106, 80, 79, 88, 82, 85, 86, 77, 83, 90,
+  81, 79, 92, 95, 75, 89, 85, 85, 64, 67,
+  80, 97, 88, 85, 80, 84, 87, 97, 103, 85,
+  89, 79, 91, 100, 72, 97, 90, 77, 85, 73,
+  94, 89, 75, 82, 75, 87, 82, 75, 81, 101,
+  86, 80, 84, 87, 80, 93, 79, 81, 74, 95,
+  89, 85, 89, 81, 83, 82, 83, 83, 97, 84,
+  102, 87, 71, 110, 88, 74, 82, 85, 77, 87,
+  95, 64, 101, 112, 95, 90, 96, 85, 70, 80,
+  77, 66, 122, 69, 85, 88, 78, 90, 72, 72,
+  85, 77, 88, 77, 104, 60, 61, 82, 100, 55,
+  70, 64, 80, 78, 102, 88, 67, 68, 75, 84,
+  59, 82, 87, 89, 79, 79, 78, 92, 96, 70,
+  80, 89, 85, 79, 70, 77, 82, 102, 83, 72,
+  83, 98, 78, 81, 87, 85, 48, 54, 80, 103,
+  83, 77, 85, 73, 85, 96, 92, 68, 90, 75,
+  85, 107, 77, 94, 80, 77, 78, 64, 94, 85,
+  81, 80, 85, 84, 85, 99, 79, 97, 84, 83,
+  90, 81, 82, 75, 81, 80, 77, 93, 93, 87,
+  65, 92, 86, 88, 85, 88, 101, 81, 84, 81,
+  76, 105, 90, 75, 84, 82, 82, 84, 104, 78,
+  91, 110, 92, 92, 86, 86, 77, 80, 87, 76,
+  102, 77, 80, 81, 86, 96, 80, 91, 97, 78,
+  86, 80, 87, 71, 80, 85, 91, 74, 76, 80,
+  83, 99, 94, 90, 74, 69, 77, 87, 66, 76,
+  88, 90, 86, 91, 89, 97, 98, 79, 80, 83,
+  77, 74, 97, 77, 87, 82, 85, 84, 84, 91,
+  74, 84, 85, 87, 71, 77, 85, 93, 84, 91,
+  82, 88, 84, 101, 82, 92, 92, 84, 94, 96,
+  77, 97, 87, 75, 90, 76, 93, 90, 87, 89,
+  97, 76, 90, 74, 90, 83, 91, 77, 90, 83,
+  87, 82, 89, 89, 95, 80, 93, 85, 56, 87,
+  97, 99, 89, 72, 80, 81, 84, 88, 88, 95,
+  94, 92, 86, 87, 86, 79, 80, 86, 86, 86,
+  81, 96, 63, 92, 100, 86, 91, 85, 78, 86,
+  90, 77, 91, 81, 89, 101, 91, 80, 92, 90,
+  96, 91, 85, 71, 84, 92, 87, 98, 83, 88,
+  66, 79, 77, 85, 79, 83, 88, 83, 90, 82,
+  74, 81, 96, 80, 79, 92, 91, 111, 66, 93,
+  91, 77, 90, 83, 71, 88, 74, 74, 76, 82,
+  86, 63, 89, 94, 77, 80, 73, 73, 68, 79,
+  82, 82, 81, 94, 84, 90, 81, 73, 104, 90,
+  84, 82, 94, 79, 88, 70, 80, 90, 84, 79,
+  90, 85, 86, 83, 86, 76, 91, 83, 87, 85,
+  86, 90, 90, 74, 88, 85, 73, 85, 80, 92,
+  86, 68, 79, 81, 83, 91, 88, 93, 90, 91,
+  82, 81, 91, 79, 78, 85, 91, 89, 65, 90,
+  63, 84, 87, 85, 90, 84, 77, 84, 88, 79,
+  84, 86, 86, 94, 89, 85, 99, 89, 93, 90,
+  77, 70, 86, 92, 85, 91, 84, 86, 59, 75,
+  79, 86, 82, 82, 85, 82, 85, 86, 79, 84,
+  97, 78, 82, 92, 86, 108, 67, 92, 86, 77,
+  92, 80, 76, 87, 85, 82, 75, 87, 88, 70,
+  89, 87, 75, 83, 74, 72, 67, 77, 81, 78,
+  79, 89, 82, 89, 79, 72, 93, 83, 88, 82,
+  88, 81, 88, 71, 80, 86, 79, 83, 92, 100,
+  85, 92, 93, 80, 96, 83, 83, 85, 86, 76,
+  93, 88, 93, 79, 82, 88, 77, 92, 82, 74,
+  83, 88, 79, 83, 79, 93, 88, 88, 78, 80,
+  90, 81, 78, 94, 91, 86, 68, 85, 69, 90,
+  89, 73, 88, 94, 81, 78, 77, 80, 92, 81,
+  85, 94, 85, 80, 85, 88, 89, 83, 76, 84,
+  83, 92, 84, 92, 85, 83, 74, 77, 83, 88,
+  81, 88, 82, 86, 85, 88, 80, 91, 92, 79,
+  86, 90, 85, 99, 76, 93, 83, 81, 89, 84,
+  76, 89, 92, 71, 77, 85, 87, 72, 84, 75,
+  77, 84, 83, 81, 77, 82, 84, 83, 79, 84,
+  84, 91, 78, 66, 77, 88, 85, 89, 91, 79,
+  89, 81, 79, 83, 95, 76, 87, 70, 87, 98,
+  88, 68, 83, 81, 85, 77, 97, 72, 88, 67,
+  69, 84, 68, 79, 75, 97, 80, 79, 84, 80,
+  93, 101, 100, 81, 94, 84, 107, 95, 72, 105,
+  90, 64, 68, 88, 140, 83, 76, 124, 71, 94,
+  82, 75, 99, 77, 92, 86, 66, 88, 94, 71,
+  84, 87, 78, 73, 72, 89, 75, 73, 80, 81,
+  80, 64, 73, 74, 80, 115, 76, 79, 86, 100,
+  90, 84, 99, 82, 76, 71, 81, 88, 81, 69,
+  86, 110, 49, 83, 67, 87, 74, 86, 71, 80,
+  55, 80, 81, 81, 73, 69, 92, 114, 84, 68,
+  63, 76, 86, 85, 90, 89, 75, 96, 80, 81,
+  81, 123, 115, 95, 60, 77, 80, 84, 100, 80,
+  79, 89, 70, 73, 85, 75, 84, 85, 82, 68,
+  82, 82, 84, 84, 91, 76, 79, 55, 63, 83,
+  105, 78, 77, 88, 66, 72, 83, 75, 92, 109,
+  100, 76, 85, 92, 101, 78, 74, 99, 83, 65,
+  69, 89, 85, 77, 82, 109, 59, 94, 84, 73,
+  94, 78, 92, 78, 64, 90, 89, 78, 84, 91,
+  91, 72, 76, 84, 69, 70, 82, 77, 78, 67,
+  80, 79, 69, 107, 74, 86, 93, 90, 91, 87,
+  93, 82, 78, 95, 83, 87, 83, 75, 84, 111,
+  49, 82, 73, 86, 79, 82, 76, 81, 67, 85,
+  80, 73, 73, 75, 90, 107, 78, 69, 61, 75,
+  89, 85, 83, 83, 76, 92, 83, 83, 77, 124,
+  90, 92, 65, 75, 75, 86, 98, 79, 85, 86,
+  73, 83, 85, 106, 80, 90, 92, 79, 91, 87,
+  84, 90, 91, 68, 89, 81, 85, 88, 97, 83,
+  84, 91, 77, 78, 83, 83, 90, 102, 79, 93,
+  90, 95, 85, 78, 85, 88, 76, 84, 82, 88,
+  58, 86, 71, 90, 85, 73, 90, 93, 89, 79,
+  85, 87, 86, 90, 85, 92, 81, 84, 82, 79,
+  85, 71, 75, 80, 77, 93, 88, 88, 90, 91,
+  70, 78, 88, 92, 84, 88, 80, 86, 92, 85,
+  81, 104, 95, 80, 92, 93, 88, 94, 71, 85,
+  82, 79, 88, 81, 82, 85, 93, 71, 79, 75,
+  84, 72, 87, 84, 82, 81, 84, 83, 87, 88,
+  85, 84, 76, 89, 91, 91, 80, 66, 68, 84,
+  81, 83, 95, 85, 85, 85, 84, 78, 82, 93,
+  92, 68, 88, 108, 85, 69, 88, 83, 90, 85,
+  95, 73, 86, 91, 94, 80, 92, 77, 80, 94,
+  77, 96, 85, 84, 90, 93, 85, 75, 108, 89,
+  88, 90, 87, 96, 87, 73, 65, 84, 123, 87,
+  91, 121, 65, 99, 71, 86, 79, 86, 93, 98,
+  92, 89, 88, 65, 68, 74, 74, 65, 71, 91,
+  80, 74, 75, 86, 72, 66, 76, 67, 106, 120,
+  82, 77, 79, 93, 79, 74, 112, 88, 91, 65,
+  92, 93, 90, 72, 89, 76, 56, 77, 58, 94,
+  82, 100, 77, 89, 56, 79, 82, 92, 73, 70,
+  66, 98, 92, 82, 57, 74, 98, 84, 90, 91,
+  80, 93, 78, 80, 75, 105, 104, 74, 55, 78,
+  95, 89, 84, 95, 82, 86, 60, 84, 89, 68,
+  88, 100, 74, 69, 88, 83, 87, 85, 90, 74,
+  81, 79, 91, 79, 107, 84, 81, 86, 67, 91,
+  86, 77, 93, 96, 89, 67, 102, 86, 90, 80,
+  83, 97, 86, 72, 65, 83, 92, 78, 95, 106,
+  56, 88, 74, 80, 74, 85, 89, 91, 84, 80,
+  81, 71, 69, 80, 80, 61, 76, 87, 73, 77,
+  77, 80, 72, 74, 72, 70, 94, 120, 80, 80,
+  85, 86, 84, 72, 105, 86, 94, 101, 89, 92,
+  78, 78, 88, 77, 59, 79, 61, 91, 79, 89,
+  82, 90, 66, 81, 84, 78, 74, 74, 66, 93,
+  88, 80, 63, 76, 107, 85, 86, 88, 82, 93,
+  88, 80, 76, 112, 79, 80, 61, 81, 88, 88,
+  86, 93, 82, 90, 68, 91, 85, 107, 78, 85,
+  88, 80, 91, 82, 89, 91, 86, 82, 82, 86,
+  89, 80, 79, 87, 89, 92, 77, 77, 78, 88,
+  82, 91, 75, 87, 96, 96, 85, 77, 90, 89,
+  73, 92, 84, 88, 64, 82, 77, 86, 82, 72,
+  87, 97, 80, 85, 82, 84, 92, 74, 82, 87,
+  78, 83, 81, 76, 82, 78, 81, 84, 82, 90,
+  82, 94, 80, 85, 82, 92, 89, 92, 84, 87,
+  79, 81, 97, 84, 83, 108, 90, 88, 84, 87,
+  88, 86, 73, 85, 80, 82, 88, 82, 86, 91,
+  88, 77, 85, 78, 81, 75, 91, 88, 76, 84,
+  75, 81, 84, 87, 92, 88, 85, 92, 93, 94,
+  82, 68, 68, 76, 78, 87, 99, 87, 76, 90,
+  78, 79, 77, 92, 88, 82, 82, 80, 98, 87,
+  77, 84, 71, 88, 78, 84, 78, 89, 93, 75,
+  93, 88, 73, 83, 89, 90, 86, 85, 79, 79,
+  97, 81, 85, 73, 84, 85, 97, 82, 79, 94,
+  99, 79, 85, 80, 78, 96, 79, 93, 85, 76,
+  72, 107, 114, 87, 106, 70, 90, 79, 93, 80,
+  80, 86, 90, 75, 83, 89, 98, 82, 85, 88,
+  81, 70, 93, 82, 87, 93, 83, 83, 80, 65,
+  95, 88, 95, 85, 72, 100, 75, 79, 79, 82,
+  85, 85, 86, 75, 89, 77, 80, 80, 88, 92,
+  70, 71, 84, 88, 81, 78, 73, 78, 88, 84,
+  89, 77, 81, 87, 83, 90, 84, 85, 80, 90,
+  85, 87, 83, 81, 86, 71, 84, 91, 89, 81,
+  91, 93, 73, 70, 76, 85, 89, 85, 68, 87,
+  89, 95, 82, 77, 79, 93, 82, 72, 86, 86,
+  73, 88, 86, 72, 90, 79, 82, 81, 90, 83,
+  89, 68, 94, 79, 90, 80, 78, 74, 95, 71,
+  84, 66, 73, 90, 80, 72, 81, 84, 75, 103,
+  99, 80, 88, 85, 83, 85, 84, 79, 85, 77,
+  101, 94, 80, 82, 112, 82, 72, 75, 73, 81,
+  93, 94, 84, 83, 82, 61, 79, 57, 81, 94,
+  91, 88, 66, 94, 75, 86, 94, 82, 80, 84,
+  85, 82, 85, 68, 80, 83, 88, 82, 75, 70,
+  82, 89, 77, 74, 88, 74, 95, 84, 95, 88,
+  82, 85, 81, 99, 79, 84, 75, 93, 83, 84,
+  80, 80, 71, 86, 86, 91, 90, 91, 78, 94,
+  73, 87, 72, 88, 91, 86, 67, 91, 88, 90,
+  74, 77, 76, 88, 77, 76, 80, 83, 73, 86,
+  87, 76, 84, 80, 85, 81, 78, 89, 88, 79,
+  101, 73, 84, 84, 88, 72, 95, 70, 92, 69,
+  72, 100, 82, 81, 87, 84, 81, 90, 94, 87,
+  88, 98, 85, 89, 80, 79, 89, 86, 98, 92,
+  87, 79, 103, 84, 78, 73, 99, 84, 94, 97,
+  88, 85, 81, 66, 87, 62, 83, 105, 89, 89,
+  62, 91, 82, 84, 91, 79, 85, 78, 85, 79,
+  91, 68, 80, 83, 86, 83, 80, 80, 86, 87,
+  79, 76, 89, 66, 96, 81, 77, 93, 81, 87,
+  79, 93, 75, 81, 74, 92, 77, 82, 79, 82,
+  81, 86, 79, 82, 90, 69, 85, 74, 79, 83,
+  76, 79, 84, 84, 76, 87, 78, 95, 77, 91,
+  82, 96, 86, 74, 97, 91, 100, 92, 92, 81,
+  104, 81, 86, 78, 80, 77, 101, 67, 73, 78,
+  85, 78, 87, 98, 84, 90, 85, 64, 87, 95,
+  92, 99, 80, 86, 61, 96, 102, 79, 92, 50,
+  82, 44, 92, 96, 80, 89, 80, 46, 69, 85,
+  100, 66, 93, 85, 76, 86, 90, 84, 87, 86,
+  89, 99, 76, 80, 73, 70, 113, 109, 56, 82,
+  84, 77, 77, 89, 84, 73, 95, 83, 82, 73,
+  83, 72, 90, 90, 66, 67, 80, 98, 86, 83,
+  79, 76, 81, 97, 93, 79, 85, 94, 51, 99,
+  95, 82, 77, 85, 89, 85, 74, 67, 72, 88,
+  84, 120, 90, 70, 75, 70, 100, 77, 72, 85,
+  46, 94, 104, 80, 98, 81, 84, 80, 91, 85,
+  86, 121, 85, 77, 97, 90, 94, 87, 77, 79,
+  96, 81, 77, 74, 76, 96, 78, 64, 79, 74,
+  72, 62, 81, 82, 79, 61, 97, 79, 82, 63,
+  95, 43, 77, 71, 68, 75, 63, 81, 95, 78,
+  74, 118, 80, 82, 90, 91, 68, 83, 105, 77,
+  77, 73, 66, 99, 80, 84, 96, 91, 67, 82,
+  76, 73, 57, 79, 80, 101, 99, 77, 80, 94,
+  60, 78, 71, 83, 86, 106, 100, 94, 91, 68,
+  78, 92, 65, 65, 94, 99, 95, 76, 102, 117,
+  92, 78, 73, 79, 92, 76, 95, 86, 88, 83,
+  74, 76, 73, 104, 52, 76, 72, 93, 102, 76,
+  85, 109, 76, 68, 105, 89, 74, 84, 52, 92,
+  107, 81, 85, 76, 86, 80, 80, 79, 82, 139,
+  75, 81, 84, 80, 87, 83, 67, 76, 97, 75,
+  71, 77, 73, 87, 79, 72, 70, 74, 79, 60,
+  81, 79, 91, 78, 90, 84, 80, 78, 89, 47,
+  96, 70, 67, 81, 71, 99, 96, 113, 72, 97,
+  82, 81, 86, 101, 95, 80, 90, 72, 76, 69,
+  91, 93, 85, 86, 104, 94, 66, 61, 91, 75,
+  63, 105, 75, 92, 102, 80, 79, 83, 85, 78,
+  72, 87, 85, 87, 87, 85, 90, 80, 83, 89,
+  71, 103, 89, 94, 92, 78, 95, 105, 91, 73,
+  61, 86, 84, 84, 105, 71, 75, 76, 80, 76,
+  71, 91, 51, 73, 88, 88, 92, 68, 87, 73,
+  74, 78, 92, 83, 74, 88, 87, 81, 80, 79,
+  83, 74, 69, 99, 84, 85, 80, 70, 92, 94,
+  81, 84, 80, 88, 103, 77, 79, 74, 73, 80,
+  93, 79, 97, 79, 98, 72, 91, 101, 83, 91,
+  91, 67, 87, 81, 92, 102, 78, 73, 69, 96,
+  97, 91, 91, 88, 86, 49, 95, 92, 68, 89,
+  77, 52, 80, 87, 86, 75, 94, 83, 90, 85,
+  94, 91, 89, 85, 87, 108, 81, 89, 73, 72,
+  105, 96, 53, 79, 89, 77, 79, 87, 82, 85,
+  95, 84, 83, 76, 86, 74, 97, 86, 75, 83,
+  78, 93, 82, 80, 74, 73, 81, 81, 85, 77,
+  84, 98, 55, 85, 84, 82, 84, 87, 79, 84,
+  80, 71, 81, 85, 86, 100, 84, 68, 71, 73,
+  96, 71, 73, 91, 61, 84, 98, 75, 103, 70,
+  86, 95, 97, 78, 83, 97, 76, 84, 88, 79,
+  77, 96, 85, 80, 84, 71, 56, 78, 82, 108,
+  90, 67, 86, 83, 82, 76, 86, 87, 89, 69,
+  87, 76, 81, 72, 80, 52, 79, 73, 68, 89,
+  68, 93, 99, 83, 85, 108, 79, 76, 82, 89,
+  84, 87, 82, 78, 96, 86, 87, 86, 90, 79,
+  84, 86, 73, 76, 91, 87, 63, 85, 80, 93,
+  88, 89, 83, 90, 78, 88, 76, 90, 85, 98,
+  111, 98, 86, 77, 89, 87, 83, 76, 91, 92,
+  79, 77, 95, 92, 81, 80, 76, 75, 84, 79,
+  95, 72, 74, 80, 85, 86, 71, 100, 58, 83,
+  89, 78, 97, 69, 83, 94, 104, 68, 99, 88,
+  74, 84, 59, 85, 98, 72, 95, 87, 91, 83,
+  85, 78, 76, 107, 84, 92, 95, 81, 81, 89,
+  75, 78, 80, 86, 65, 82, 78, 91, 81, 88,
+  72, 86, 85, 75, 83, 86, 81, 79, 85, 77,
+  84, 76, 77, 56, 90, 85, 71, 91, 70, 90,
+  94, 103, 80, 84, 81, 72, 78, 99, 96, 88,
+  88, 73, 88, 90, 82, 88, 87, 84, 90, 93,
+  80, 72, 81, 91, 69, 96, 73, 97, 88, 98,
+  81, 87, 91, 82, 80, 87, 84, 83, 92, 86,
+  85, 87, 82, 82, 85, 83, 91, 89, 79, 83,
+  93, 81, 83, 78, 81, 76, 79, 83, 94, 75,
+  90, 76, 91, 85, 76, 87, 61, 75, 101, 75,
+  89, 70, 92, 84, 76, 78, 74, 82, 110, 88,
+  76, 69, 81, 65, 79, 95, 71, 91, 89, 105,
+  58, 84, 92, 97, 81, 91, 87, 71, 83, 77,
+  90, 76, 98, 83, 79, 82, 73, 86, 80, 71,
+  87, 85, 75, 87, 113, 70, 92, 79, 81, 88,
+  74, 88, 105, 79, 77, 75, 79, 89, 84, 95,
+  79, 106, 90, 84, 81, 70, 80, 79, 84, 92,
+  70, 72, 83, 77, 91, 76, 90, 87, 82, 84,
+  65, 65, 82, 88, 79, 96, 98, 81, 81, 85,
+  92, 97, 80, 77, 78, 84, 74, 74, 84, 90,
+  92, 73, 75, 86, 105, 81, 91, 88, 81, 87,
+  84, 97, 89, 87, 77, 83, 102, 76, 104, 104,
+  81, 74, 86, 80, 70, 90, 75, 80, 89, 70,
+  88, 85, 69, 77, 73, 73, 104, 82, 76, 70,
+  79, 68, 79, 87, 72, 91, 92, 107, 62, 90,
+  97, 87, 80, 88, 89, 70, 79, 76, 96, 76,
+  96, 78, 81, 73, 83, 86, 85, 68, 88, 77,
+  81, 90, 101, 77, 94, 76, 74, 83, 68, 96,
+  94, 69, 88, 77, 77, 86, 78, 85, 87, 113,
+  98, 75, 75, 69, 68, 73, 91, 100, 66, 64,
+  76, 80, 86, 70, 85, 81, 83, 81, 67, 59,
+  83, 84, 79, 89, 99, 72, 84, 84, 92, 109,
+  79, 80, 78, 75, 74, 79, 79, 97, 91, 68,
+  77, 85, 102, 82, 78, 88, 86, 91, 80, 100,
+  86, 84, 78, 84, 99, 77, 82, 109, 86, 71,
+  80, 86, 67, 92, 72, 80, 91, 76, 89, 84,
+  83, 81, 75, 85, 103, 88, 83, 72, 87, 69,
+  75, 85, 77, 92, 88, 99, 63, 91, 97, 95,
+  82, 92, 90, 75, 83, 79, 84, 72, 87, 85,
+  75, 69, 90, 110, 86, 74, 85, 82, 77, 86,
+  91, 76, 95, 89, 81, 88, 77, 88, 100, 81,
+  77, 81, 85, 90, 85, 99, 83, 96, 88, 83,
+  80, 75, 92, 76, 97, 91, 71, 67, 101, 86,
+  98, 73, 84, 90, 87, 81, 66, 69, 85, 90,
+  83, 94, 93, 76, 77, 85, 92, 97, 83, 82,
+  74, 86, 86, 81, 86, 93, 83, 82, 84, 85,
+  100, 79, 88, 93, 77, 88, 89, 98, 88, 88,
+  80, 83, 100, 78, 88, 96, 82, 78, 82, 81,
+  75, 90, 80, 87, 88, 76, 90, 77, 70, 84,
+  76, 87, 111, 90, 75, 74, 79, 71, 81, 82,
+  67, 98, 85, 100, 65, 90, 98, 94, 81, 92,
+  87, 60, 86, 79, 88, 74, 101, 92, 85, 86,
+  68, 81, 84, 87, 90, 78, 82, 87, 105, 73,
+  91, 85, 72, 91, 78, 81, 115, 66, 75, 83,
+  74, 95, 78, 95, 76, 96, 88, 85, 80, 70,
+  65, 73, 84, 75, 76, 55, 94, 80, 81, 75,
+  87, 82, 88, 92, 66, 68, 74, 102, 78, 71,
+  90, 74, 79, 80, 87, 85, 80, 71, 83, 84,
+  75, 84, 92, 88, 83, 68, 69, 91, 101, 84,
+  118, 92, 82, 86, 90, 92, 91, 85, 69, 90,
+  91, 80, 93, 95, 71, 70, 80, 70, 72, 79,
+  77, 85, 80, 67, 89, 82, 73, 85, 75, 77,
+  104, 78, 73, 75, 75, 73, 82, 91, 65, 97,
+  90, 105, 69, 92, 103, 89, 82, 89, 82, 54,
+  85, 80, 91, 71, 94, 95, 90, 79, 69, 74,
+  84, 82, 87, 72, 86, 89, 107, 79, 94, 89,
+  64, 83, 74, 82, 105, 73, 79, 82, 74, 88,
+  75, 84, 77, 94, 92, 80, 81, 72, 59, 75,
+  85, 68, 72, 62, 80, 83, 70, 76, 82, 74,
+  94, 79, 63, 61, 71, 104, 78, 70, 87, 70,
+  79, 78, 86, 89, 78, 80, 80, 76, 70, 87,
+  87, 91, 78, 63, 73, 86, 103, 87, 120, 88,
+  81, 87, 93, 91, 94, 84, 65, 83, 92, 78,
+  81, 96, 66, 68, 79, 71, 59, 80, 76, 88,
+  82, 71, 86, 89, 86, 79, 74, 89, 102, 84,
+  73, 73, 82, 77, 78, 89, 69, 94, 90, 97,
+  67, 97, 92, 96, 82, 88, 84, 65, 86, 77,
+  85, 72, 90, 99, 83, 78, 83, 96, 87, 88,
+  84, 77, 81, 84, 96, 76, 91, 92, 66, 90,
+  78, 81, 106, 80, 74, 87, 78, 84, 82, 97,
+  81, 90, 87, 84, 83, 74, 77, 74, 90, 73,
+  80, 67, 85, 85, 88, 70, 85, 84, 88, 80,
+  61, 69, 77, 100, 80, 83, 88, 80, 82, 80,
+  85, 87, 81, 77, 80, 87, 76, 83, 94, 92,
+  81, 71, 75, 80, 97, 81, 109, 95, 77, 85,
+  90, 95, 92, 86, 73, 81, 97, 83, 93, 89,
+  75, 76, 80, 77, 76, 81, 78, 91, 80, 69,
+  92, 77, 79, 87, 77, 88, 93, 103, 75, 74,
+  84, 75, 79, 88, 75, 102, 86, 87, 76, 93,
+  92, 99, 82, 85, 92, 75, 96, 78, 81, 83,
+  93, 88, 88, 94, 83, 83, 90, 95, 87, 91,
+  89, 89, 84, 76, 78, 92, 84, 91, 79, 85,
+  104, 73, 75, 91, 83, 93, 82, 97, 81, 89,
+  84, 82, 80, 79, 86, 71, 99, 76, 91, 85,
+  96, 77, 94, 72, 91, 82, 79, 86, 75, 72,
+  77, 90, 89, 83, 90, 76, 86, 89, 87, 81,
+  78, 82, 85, 97, 81, 70, 102, 82, 95, 75,
+  84, 89, 91, 83, 96, 92, 83, 87, 79, 92,
+  89, 88, 88, 94, 93, 81, 90, 93, 85, 74,
+  83, 71, 94, 84, 89, 100, 75, 74, 91, 77,
+  77, 89, 76, 81, 89, 93, 75, 74, 85, 76,
+  79, 98, 74, 98, 87, 85, 81, 90, 86, 93,
+  82, 81, 92, 72, 97, 75, 85, 82, 88, 102,
+  93, 88, 84, 79, 83, 91, 89, 84, 82, 89,
+  87, 77, 79, 89, 81, 81, 81, 83, 98, 78,
+  73, 93, 82, 95, 83, 89, 83, 83, 81, 84,
+  78, 75, 81, 70, 103, 68, 92, 84, 88, 75,
+  84, 70, 94, 79, 86, 78, 72, 69, 76, 91,
+  93, 83, 91, 73, 81, 86, 87, 82, 75, 84,
+  85, 91, 79, 76, 108, 80, 87, 70, 80, 88,
+  92, 84, 98, 104, 83, 88, 85, 98, 89, 83,
+  86, 88, 94, 88, 90, 88, 77, 74, 81, 76,
+  87, 81, 90, 105, 72, 74, 83, 82, 88, 83,
+  76, 90, 88, 94, 78, 76, 87, 80, 78, 86,
+  74, 98, 89, 83, 77, 98, 78, 99, 86, 83,
+  91, 77, 98, 75, 78, 85, 86, 98, 88, 85,
+  89, 90, 85, 92, 85, 87, 85, 85, 88, 80,
+  78, 90, 86, 90, 80, 84, 99, 77, 72, 94,
+  79, 88, 85, 99, 87, 86, 83, 84, 82, 79,
+  88, 75, 108, 75, 90, 85, 86, 81, 91, 68,
+  96, 83, 81, 85, 70, 73, 79, 86, 93, 89,
+  88, 82, 79, 86, 84, 84, 79, 86, 82, 98,
+  79, 72, 105, 80, 82, 77, 89, 73, 91, 80,
+  97, 94, 86, 91, 88, 95, 79, 86, 88, 89,
+  96, 89, 99, 88, 84, 77, 82, 75, 90, 85,
+  92, 104, 78, 81, 92, 100, 91, 85, 70, 73,
+  90, 78, 86, 92, 102, 106, 88, 74, 93, 68,
+  80, 87, 85, 98, 92, 82, 87, 82, 89, 86,
+  82, 88, 81, 94, 104, 80, 92, 86, 89, 70,
+  90, 80, 98, 81, 94, 85, 94, 91, 85, 73,
+  80, 74, 74, 88, 86, 92, 93, 80, 85, 91,
+  66, 84, 76, 90, 89, 69, 93, 72, 78, 86,
+  83, 93, 76, 95, 68, 92, 84, 89, 84, 78,
+  89, 74, 81, 82, 85, 87, 76, 71, 94, 84,
+  84, 93, 93, 97, 70, 80, 92, 76, 65, 98,
+  99, 92, 67, 75, 91, 87, 84, 83, 85, 93,
+  79, 105, 72, 98, 81, 84, 97, 79, 92, 94,
+  77, 87, 78, 91, 101, 85, 65, 89, 80, 87,
+  91, 94, 86, 107, 95, 87, 81, 75, 79, 75,
+  88, 85, 86, 82, 74, 74, 71, 80, 87, 79,
+  80, 100, 70, 85, 77, 89, 95, 95, 76, 82,
+  91, 85, 84, 83, 84, 73, 87, 85, 74, 81,
+  111, 78, 85, 87, 92, 85, 86, 103, 97, 89,
+  90, 84, 80, 81, 89, 82, 85, 87, 68, 72,
+  80, 89, 77, 115, 82, 70, 73, 70, 78, 76,
+  85, 80, 99, 94, 75, 81, 85, 71, 91, 82,
+  83, 89, 80, 79, 88, 81, 86, 89, 84, 77,
+  90, 79, 65, 83, 84, 88, 63, 88, 93, 81,
+  58, 80, 77, 97, 90, 83, 91, 81, 68, 83,
+  83, 77, 80, 88, 79, 83, 75, 79, 86, 79,
+  72, 78, 86, 72, 85, 79, 82, 87, 87, 81,
+  91, 85, 107, 87, 83, 102, 72, 77, 81, 85,
+  73, 65, 85, 85, 50, 96, 94, 75, 78, 91,
+  89, 100, 85, 96, 81, 78, 72, 82, 84, 99,
+  83, 87, 77, 82, 85, 86, 78, 89, 90, 80,
+  81, 81, 67, 84, 84, 108, 102, 92, 95, 86,
+  80, 79, 84, 73, 85, 86, 99, 75, 81, 92,
+  70, 128, 85, 81, 74, 68, 62, 69, 113, 77,
+  69, 84, 82, 79, 78, 91, 84, 77, 74, 82,
+  82, 77, 83, 95, 76, 88, 82, 67, 78, 74,
+  87, 93, 99, 81, 87, 80, 84, 73, 76, 77,
+  80, 73, 80, 89, 89, 78, 70, 70, 78, 86,
+  83, 92, 68, 80, 73, 84, 90, 85, 78, 79,
+  88, 84, 88, 79, 96, 88, 79, 78, 88, 98,
+  88, 89, 69, 77, 95, 76, 75, 88, 103, 119,
+  110, 76, 95, 78, 93, 95, 92, 100, 85, 79,
+  75, 78, 85, 90, 74, 90, 87, 85, 114, 73,
+  104, 90, 99, 72, 77, 83, 98, 88, 81, 84,
+  101, 100, 81, 79, 81, 67, 62, 97, 84, 89,
+  89, 96, 85, 83, 63, 91, 73, 94, 81, 69,
+  85, 71, 72, 89, 88, 97, 82, 80, 77, 79,
+  77, 88, 82, 64, 68, 92, 74, 77, 93, 88,
+  82, 75, 101, 80, 87, 97, 93, 86, 72, 73,
+  72, 73, 66, 93, 93, 95, 80, 76, 79, 88,
+  83, 82, 85, 84, 80, 109, 74, 103, 91, 100,
+  95, 77, 87, 85, 72, 88, 92, 71, 91, 101,
+  66, 87, 83, 86, 97, 92, 82, 101, 101, 94,
+  84, 70, 78, 71, 96, 83, 87, 85, 91, 92,
+  69, 93, 82, 75, 78, 99, 59, 85, 75, 90,
+  87, 89, 70, 90, 97, 75, 75, 77, 81, 75,
+  90, 84, 71, 78, 90, 88, 75, 80, 104, 78,
+  80, 104, 93, 72, 87, 99, 78, 74, 87, 87,
+  74, 79, 73, 70, 85, 90, 78, 123, 78, 61,
+  68, 66, 83, 72, 98, 72, 90, 90, 70, 87,
+  82, 68, 86, 111, 75, 86, 85, 76, 98, 90,
+  81, 91, 83, 79, 82, 74, 57, 82, 81, 81,
+  55, 81, 89, 79, 68, 86, 69, 75, 85, 82,
+  81, 76, 76, 77, 85, 80, 79, 91, 66, 91,
+  68, 84, 110, 77, 73, 76, 85, 78, 90, 79,
+  84, 86, 71, 88, 87, 78, 77, 81, 73, 90,
+  66, 74, 86, 85, 69, 72, 85, 94, 57, 87,
+  75, 66, 79, 86, 101, 106, 74, 97, 74, 73,
+  77, 77, 93, 82, 75, 84, 68, 87, 69, 82,
+  81, 89, 82, 78, 88, 73, 56, 76, 89, 106,
+  79, 76, 96, 90, 79, 72, 86, 74, 82, 87,
+  106, 71, 100, 85, 79, 138, 99, 76, 57, 76,
+  64, 76, 107, 87, 73, 77, 92, 92, 78, 96,
+  84, 93, 82, 73, 78, 68, 82, 91, 71, 85,
+  88, 68, 72, 76, 79, 104, 99, 75, 93, 69,
+  86, 75, 95, 87, 82, 70, 88, 92, 84, 98,
+  79, 65, 78, 79, 79, 91, 66, 86, 75, 92,
+  98, 82, 69, 83, 83, 78, 84, 77, 93, 90,
+  69, 81, 81, 100, 87, 104, 67, 76, 90, 65,
+  79, 90, 97, 106, 112, 87, 81, 95, 94, 91,
+  92, 91, 83, 75, 79, 80, 69, 88, 79, 88,
+  84, 86, 94, 80, 88, 85, 90, 78, 90, 82,
+  90, 94, 89, 82, 82, 96, 77, 73, 82, 66,
+  71, 89, 78, 79, 93, 92, 81, 72, 69, 88,
+  83, 95, 83, 83, 79, 73, 81, 84, 92, 92,
+  97, 76, 82, 82, 87, 79, 82, 71, 76, 81,
+  75, 84, 86, 91, 80, 74, 86, 76, 90, 88,
+  95, 91, 66, 94, 86, 80, 70, 81, 90, 87,
+  95, 79, 83, 95, 81, 81, 88, 85, 81, 100,
+  71, 99, 81, 94, 87, 86, 96, 84, 68, 90,
+  96, 65, 89, 85, 68, 88, 89, 79, 101, 84,
+  84, 105, 94, 92, 78, 67, 81, 74, 83, 87,
+  80, 76, 92, 113, 62, 88, 76, 73, 77, 86,
+  73, 94, 99, 94, 70, 81, 79, 88, 96, 86,
+  73, 77, 68, 76, 68, 84, 89, 77, 75, 87,
+  93, 85, 87, 76, 76, 92, 79, 87, 104, 97,
+  77, 77, 89, 79, 72, 76, 82, 72, 91, 79,
+  86, 128, 87, 64, 68, 66, 85, 74, 105, 81,
+  79, 95, 87, 93, 82, 79, 89, 87, 70, 88,
+  81, 72, 92, 92, 75, 88, 82, 80, 83, 75,
+  61, 84, 96, 74, 66, 76, 86, 73, 74, 82,
+  77, 77, 87, 83, 77, 83, 71, 76, 86, 78,
+  74, 88, 68, 96, 83, 86, 127, 84, 75, 79,
+  84, 69, 88, 81, 87, 80, 72, 84, 94, 76,
+  60, 77, 70, 96, 75, 84, 79, 84, 68, 79,
+  84, 83, 61, 80, 70, 77, 83, 81, 119, 94,
+  67, 91, 72, 81, 81, 80, 84, 72, 81, 90,
+  64, 98, 48, 83, 83, 83, 75, 76, 81, 76,
+  59, 81, 91, 96, 67, 85, 97, 89, 87, 74,
+  87, 82, 90, 94, 98, 77, 89, 86, 83, 109,
+  108, 76, 65, 81, 68, 83, 95, 76, 100, 83,
+  95, 97, 79, 103, 79, 77, 91, 85, 80, 71,
+  80, 83, 72, 77, 88, 74, 79, 77, 87, 103,
+  100, 79, 100, 68, 87, 77, 86, 79, 82, 87,
+  91, 91, 89, 80, 86, 70, 95, 83, 78, 86,
+  71, 84, 69, 77, 81, 80, 66, 86, 86, 79,
+  91, 85, 96, 89, 76, 78, 86, 89, 68, 89,
+  89, 106, 93, 92, 84, 82, 80, 90, 87, 86,
+  79, 82, 83, 98, 82, 79, 86, 85, 82, 74,
+  72, 90, 82, 88, 85, 92, 84, 75, 99, 80,
+  112, 104, 77, 91, 94, 81, 75, 79, 79, 78,
+  78, 83, 88, 88, 91, 90, 67, 91, 79, 82,
+  80, 89, 75, 86, 80, 92, 78, 83, 78, 79,
+  76, 80, 87, 86, 87, 79, 101, 103, 104, 77,
+  87, 92, 79, 103, 86, 66, 76, 85, 92, 77,
+  85, 85, 86, 88, 81, 69, 83, 89, 87, 103,
+  81, 84, 89, 86, 80, 89, 63, 76, 80, 88,
+  81, 77, 80, 84, 70, 86, 84, 75, 89, 89,
+  79, 91, 94, 86, 89, 82, 87, 80, 84, 93,
+  74, 81, 88, 83, 81, 95, 66, 91, 70, 95,
+  90, 100, 97, 86, 74, 84, 73, 74, 85, 82,
+  88, 106, 81, 74, 90, 79, 95, 84, 79, 82,
+  93, 94, 75, 103, 79, 94, 91, 59, 106, 89,
+  73, 105, 71, 63, 77, 74, 85, 74, 74, 108,
+  84, 95, 87, 88, 64, 80, 86, 62, 96, 65,
+  90, 68, 80, 102, 82, 84, 78, 76, 81, 72,
+  93, 91, 77, 78, 77, 96, 118, 85, 90, 93,
+  87, 95, 79, 58, 65, 70, 93, 104, 55, 75,
+  85, 55, 64, 87, 88, 77, 89, 119, 87, 77,
+  89, 90, 79, 92, 62, 95, 82, 86, 94, 89,
+  87, 82, 78, 94, 86, 81, 89, 90, 66, 89,
+  94, 93, 97, 88, 96, 82, 94, 94, 61, 80,
+  93, 86, 85, 87, 90, 89, 87, 89, 92, 90,
+  83, 79, 79, 93, 81, 102, 82, 83, 81, 93,
+  83, 77, 77, 89, 98, 76, 81, 88, 83, 86,
+  79, 102, 88, 83, 98, 87, 99, 96, 83, 87,
+  85, 75, 76, 81, 85, 80, 74, 83, 84, 102,
+  91, 88, 64, 98, 78, 79, 85, 82, 72, 87,
+  82, 87, 79, 83, 76, 81, 84, 79, 90, 85,
+  87, 70, 76, 103, 103, 84, 85, 87, 76, 90,
+  86, 73, 77, 92, 95, 92, 88, 87, 86, 91,
+  85, 73, 87, 81, 86, 94, 84, 83, 89, 86,
+  80, 93, 62, 92, 82, 88, 80, 80, 79, 86,
+  73, 83, 102, 78, 85, 87, 91, 81, 91, 87,
+  86, 82, 74, 76, 80, 87, 75, 79, 84, 82,
+  88, 85, 58, 87, 92, 88, 61, 88, 103, 78,
+  81, 108, 86, 88, 74, 73, 81, 75, 80, 77,
+  75, 72, 68, 72, 77, 76, 81, 82, 94, 86,
+  72, 81, 90, 100, 93, 82, 79, 93, 117, 74,
+  78, 71, 90, 97, 80, 77, 84, 91, 78, 80,
+  89, 93, 78, 94, 67, 132, 82, 100, 90, 70,
+  76, 72, 92, 67, 70, 72, 88, 74, 78, 73,
+  97, 92, 90, 74, 79, 81, 77, 69, 83, 73,
+  71, 121, 84, 92, 88, 85, 85, 104, 88, 78,
+  68, 93, 81, 77, 88, 73, 89, 88, 73, 83,
+  73, 71, 80, 87, 65, 73, 77, 90, 72, 89,
+  82, 75, 77, 81, 106, 77, 70, 80, 71, 77,
+  75, 66, 70, 86, 86, 83, 86, 79, 85, 81,
+  86, 76, 103, 75, 57, 85, 108, 73, 85, 105,
+  82, 124, 74, 70, 90, 59, 83, 83, 76, 85,
+  75, 70, 71, 67, 75, 78, 103, 80, 82, 73,
+  69, 86, 85, 79, 70, 91, 112, 68, 82, 75,
+  80, 105, 86, 59, 82, 76, 72, 70, 94, 116,
+  72, 86, 65, 115, 78, 102, 89, 72, 68, 67,
+  92, 71, 62, 78, 85, 71, 78, 66, 91, 85,
+  79, 72, 85, 66, 73, 76, 80, 69, 68, 122,
+  84, 85, 100, 82, 72, 121, 106, 71, 67, 84,
+  84, 63, 79, 67, 84, 89, 76, 88, 66, 67,
+  83, 84, 63, 80, 69, 103, 74, 90, 103, 75,
+  70, 76, 124, 67, 74, 75, 71, 71, 83, 67,
+  62, 87, 89, 80, 81, 78, 82, 84, 103, 89,
+  88, 76, 65, 93, 100, 78, 78, 111, 74, 116,
+  78, 75, 82, 72, 81, 83, 88, 76, 88, 79,
+  72, 78, 87, 83, 87, 83, 87, 80, 90, 79,
+  94, 87, 88, 92, 79, 71, 88, 75, 76, 90,
+  79, 86, 77, 79, 78, 84, 75, 91, 83, 87,
+  79, 76, 83, 93, 86, 70, 78, 75, 84, 71,
+  74, 71, 93, 73, 79, 76, 72, 91, 101, 84,
+  86, 81, 79, 92, 75, 78, 71, 114, 90, 74,
+  81, 87, 78, 98, 85, 77, 77, 80, 86, 83,
+  82, 73, 91, 89, 86, 88, 70, 69, 85, 87,
+  71, 74, 76, 89, 74, 93, 100, 83, 74, 87,
+  107, 77, 84, 79, 76, 84, 91, 69, 79, 86,
+  78, 86, 84, 81, 86, 87, 81, 89, 79, 89,
+  76, 81, 95, 82, 84, 101, 78, 115, 78, 80,
+  83, 82, 86, 77, 80, 79, 70, 79, 81, 69,
+  82, 89, 91, 77, 86, 87, 89, 100, 74, 77,
+  71, 94, 86, 79, 81, 77, 103, 93, 84, 99,
+  84, 92, 79, 87, 97, 99, 88, 83, 70, 59,
+  88, 92, 87, 72, 87, 87, 88, 73, 85, 72,
+  92, 82, 85, 80, 71, 83, 86, 78, 89, 83,
+  78, 66, 74, 84, 69, 99, 87, 90, 83, 97,
+  90, 101, 81, 111, 72, 105, 83, 70, 90, 72,
+  88, 87, 77, 86, 76, 75, 83, 88, 89, 73,
+  83, 84, 62, 95, 98, 85, 79, 92, 112, 79,
+  70, 88, 73, 88, 79, 68, 74, 78, 83, 93,
+  86, 75, 87, 84, 86, 80, 98, 78, 78, 79,
+  95, 81, 88, 93, 94, 115, 78, 68, 86, 65,
+  78, 86, 89, 82, 76, 78, 71, 67, 78, 80,
+  96, 67, 86, 78, 79, 112, 71, 88, 64, 85,
+  120, 90, 87, 75, 90, 105, 101, 71, 83, 76,
+  77, 78, 104, 107, 80, 82, 58, 99, 86, 100,
+  84, 65, 74, 79, 83, 80, 77, 77, 88, 79,
+  98, 70, 93, 75, 80, 74, 91, 76, 74, 79,
+  74, 89, 69, 96, 79, 74, 99, 109, 86, 121,
+  83, 92, 69, 98, 76, 58, 76, 71, 82, 92,
+  75, 87, 73, 66, 85, 85, 79, 74, 78, 91,
+  61, 91, 97, 76, 76, 84, 88, 70, 78, 82,
+  63, 85, 86, 61, 60, 83, 95, 86, 77, 72,
+  84, 88, 80, 93, 76, 76, 77, 85, 95, 87,
+  83, 101, 84, 81, 86, 83, 83, 85, 87, 91,
+  100, 69, 97, 78, 79, 75, 85, 92, 81, 71,
+  87, 90, 93, 83, 78, 86, 80, 94, 104, 77,
+  88, 74, 84, 89, 85, 97, 78, 73, 83, 92,
+  85, 78, 90, 84, 77, 117, 92, 92, 82, 78,
+  84, 90, 95, 75, 80, 72, 93, 91, 82, 89,
+  87, 90, 96, 79, 96, 82, 81, 90, 81, 82,
+  69, 94, 86, 78, 80, 97, 90, 85, 68, 103,
+  80, 92, 82, 79, 75, 73, 90, 89, 91, 85,
+  75, 80, 87, 89, 92, 73, 86, 84, 64, 93,
+  78, 91, 81, 88, 75, 83, 86, 85, 83, 84,
+  101, 71, 84, 81, 79, 94, 92, 82, 89, 60,
+  91, 101, 83, 98, 78, 99, 82, 84, 82, 76,
+  89, 88, 76, 100, 83, 86, 80, 82, 89, 88,
+  79, 81, 86, 81, 80, 79, 93, 74, 76, 84,
+  77, 89, 94, 86, 89, 89, 81, 76, 93, 79,
+  90, 85, 91, 88, 76, 79, 75, 86, 93, 94,
+  93, 87, 81, 87, 89, 95, 83, 80, 87, 84,
+  96, 96, 95, 75, 83, 86, 89, 73, 60, 75,
+  113, 84, 83, 72, 82, 92, 94, 68, 90, 84,
+  82, 71, 88, 76, 94, 77, 96, 75, 84, 103,
+  85, 70, 108, 78, 81, 83, 82, 70, 86, 52,
+  79, 88, 81, 80, 84, 86, 78, 91, 88, 83,
+  78, 90, 98, 74, 106, 77, 80, 77, 86, 91,
+  92, 82, 96, 84, 82, 81, 94, 108, 46, 82,
+  77, 71, 79, 91, 65, 93, 85, 84, 84, 100,
+  75, 77, 72, 86, 87, 79, 81, 67, 60, 107,
+  85, 81, 95, 90, 93, 56, 74, 81, 100, 86,
+  65, 50, 65, 73, 78, 53, 76, 88, 86, 68,
+  85, 82, 85, 97, 81, 90, 89, 57, 91, 77,
+  102, 78, 84, 85, 92, 73, 116, 80, 104, 98,
+  53, 84, 145, 82, 95, 122, 42, 66, 102, 105,
+  81, 75, 84, 81, 89, 60, 82, 82, 90, 69,
+  71, 86, 78, 106, 75, 77, 89, 123, 98, 70,
+  91, 67, 88, 78, 78, 83, 77, 153, 88, 86,
+  93, 102, 97, 82, 99, 101, 73, 87, 78, 70,
+  83, 99, 59, 82, 99, 79, 87, 99, 95, 79,
+  88, 86, 85, 119, 86, 109, 69, 88, 79, 108,
+  85, 102, 83, 91, 80, 86, 79, 67, 86, 89,
+  77, 91, 90, 88, 80, 79, 73, 92, 87, 95,
+  92, 83, 80, 67, 74, 84, 91, 102, 77, 83,
+  64, 77, 82, 86, 86, 94, 99, 87, 90, 93,
+  87, 108, 88, 96, 94, 78, 85, 90, 101, 85,
+  100, 84, 90, 80, 102, 79, 74, 63, 59, 87,
+  77, 83, 94, 66, 90, 83, 100, 83, 97, 77,
+  90, 83, 71, 88, 83, 87, 91, 82, 81, 75,
+  88, 84, 87, 75, 77, 81, 91, 82, 88, 76,
+  80, 80, 82, 84, 63, 123, 88, 88, 89, 78,
+  89, 89, 91, 94, 83, 73, 85, 90, 59, 67,
+  43, 77, 96, 79, 76, 100, 88, 89, 98, 73,
+  91, 108, 87, 78, 104, 92, 78, 74, 83, 77,
+  77, 87, 81, 79, 83, 123, 79, 87, 78, 67,
+  74, 82, 81, 81, 70, 77, 79, 75, 97, 87,
+  91, 74, 85, 80, 75, 75, 81, 79, 85, 82,
+  77, 76, 89, 92, 84, 85, 80, 74, 80, 79,
+  84, 69, 87, 92, 90, 85, 77, 72, 79, 91,
+  84, 71, 90, 92, 100, 90, 85, 78, 66, 63,
+  105, 91, 45, 80, 90, 81, 80, 75, 66, 73,
+  102, 64, 87, 92, 79, 71, 83, 87, 84, 83,
+  97, 89, 91, 103, 83, 67, 95, 84, 86, 86,
+  81, 75, 92, 80, 84, 91, 91, 81, 83, 85,
+  79, 73, 87, 80, 76, 79, 102, 70, 81, 86,
+  79, 86, 75, 79, 81, 73, 90, 95, 82, 82,
+  113, 101, 85, 79, 85, 113, 82, 69, 59, 93,
+  86, 86, 99, 129, 67, 67, 81, 72, 85, 84,
+  81, 90, 80, 97, 84, 72, 91, 91, 87, 61,
+  79, 89, 86, 95, 74, 97, 66, 75, 84, 51,
+  74, 100, 81, 78, 89, 87, 75, 135, 84, 55,
+  72, 63, 82, 79, 74, 59, 67, 65, 85, 68,
+  109, 99, 87, 72, 70, 87, 109, 67, 117, 92,
+  59, 83, 82, 86, 83, 69, 67, 93, 68, 83,
+  82, 77, 89, 88, 80, 91, 87, 123, 52, 79,
+  78, 87, 91, 74, 88, 90, 81, 84, 83, 80,
+  70, 137, 90, 88, 86, 88, 105, 81, 79, 69,
+  77, 87, 69, 86, 71, 89, 80, 97, 91, 74,
+  73, 81, 75, 71, 96, 83, 88, 99, 89, 73,
+  90, 89, 68, 107, 78, 98, 83, 81, 83, 77,
+  86, 83, 79, 86, 85, 89, 84, 74, 82, 85,
+  81, 77, 78, 79, 89, 82, 86, 72, 73, 77,
+  86, 98, 90, 96, 81, 97, 97, 87, 100, 93,
+  85, 97, 88, 80, 82, 85, 88, 78, 94, 86,
+  80, 86, 76, 84, 86, 74, 80, 84, 77, 88,
+  86, 61, 74, 87, 77, 66, 95, 67, 98, 84,
+  95, 85, 86, 76, 77, 87, 73, 91, 82, 84,
+  83, 89, 78, 84, 97, 89, 76, 73, 88, 93,
+  84, 68, 93, 81, 78, 86, 82, 76, 68, 57,
+  82, 86, 61, 79, 76, 86, 67, 81, 80, 71,
+  78, 92, 70, 71, 92, 79, 80, 69, 81, 80,
+  92, 77, 90, 74, 85, 89, 82, 70, 99, 83,
+  89, 84, 89, 74, 73, 79, 74, 89, 85, 107,
+  79, 87, 84, 85, 81, 80, 84, 80, 84, 79,
+  86, 74, 100, 84, 92, 74, 90, 82, 86, 80,
+  81, 97, 78, 88, 88, 74, 81, 100, 94, 98,
+  67, 82, 80, 77, 94, 73, 80, 98, 88, 80,
+  65, 85, 78, 71, 86, 77, 96, 89, 73, 81,
+  89, 69, 79, 77, 96, 83, 68, 76, 84, 80,
+  86, 81, 71, 90, 88, 74, 89, 80, 88, 84,
+  88, 83, 92, 86, 72, 90, 96, 87, 85, 84,
+  77, 89, 82, 87, 88, 72, 85, 73, 82, 90,
+  88, 74, 86, 78, 75, 74, 85, 72, 82, 94,
+  85, 82, 94, 83, 84, 92, 76, 86, 85, 74,
+  88, 91, 86, 79, 85, 75, 91, 82, 91, 87,
+  83, 75, 77, 82, 79, 84, 94, 87, 75, 77,
+  88, 82, 87, 77, 90, 99, 86, 70, 77, 70,
+  86, 85, 84, 67, 68, 86, 80, 90, 104, 99,
+  85, 82, 92, 81, 93, 96, 91, 95, 79, 89,
+  74, 81, 89, 76, 88, 95, 82, 79, 59, 71,
+  68, 60, 84, 77, 84, 92, 80, 77, 89, 82,
+  72, 76, 102, 73, 87, 87, 86, 85, 76, 84,
+  74, 95, 84, 84, 89, 78, 86, 90, 74, 82,
+  94, 95, 60, 81, 85, 83, 86, 79, 88, 90,
+  81, 83, 84, 74, 81, 66, 81, 86, 73, 74,
+  81, 82, 69, 73, 80, 75, 76, 94, 82, 68,
+  114, 76, 83, 86, 84, 88, 82, 76, 96, 82,
+  84, 81, 81, 66, 82, 94, 88, 70, 79, 96,
+  80, 75, 80, 84, 79, 87, 73, 87, 88, 83,
+  86, 79, 81, 82, 80, 77, 79, 84, 94, 77,
+  83, 74, 83, 81, 84, 89, 77, 86, 90, 94,
+  100, 80, 91, 97, 83, 98, 72, 80, 90, 64,
+  86, 76, 96, 91, 84, 87, 72, 81, 87, 80,
+  82, 80, 86, 80, 90, 75, 80, 88, 87, 74,
+  95, 87, 101, 67, 85, 88, 83, 82, 82, 75,
+  97, 86, 87, 81, 83, 82, 78, 81, 87, 84,
+  78, 88, 84, 97, 88, 77, 86, 80, 85, 83,
+  86, 82, 76, 77, 82, 85, 84, 83, 78, 84,
+  78, 82, 80, 69, 86, 80, 93, 83, 99, 78,
+  81, 83, 83, 79, 96, 82, 85, 85, 81, 83,
+  88, 83, 81, 85, 83, 85, 79, 78, 79, 82,
+  81, 78, 85, 88, 81, 88, 89, 79, 83, 89,
+  85, 87, 84, 96, 88, 84, 83, 86, 82, 89,
+  85, 80, 86, 85, 87, 89, 82, 86, 87, 81,
+  79, 90, 87, 91, 91, 86, 91, 85, 78, 81,
+  82, 82, 79, 87, 77, 83, 80, 91, 85, 95,
+  78, 88, 91, 85, 86, 77, 82, 86, 80, 91,
+  85, 79, 75, 76, 82, 82, 88, 83, 77, 86,
+  90, 84, 87, 89, 77, 78, 93, 82, 85, 82,
+  81, 83, 78, 90, 82, 78, 75, 87, 85, 82,
+  85, 84, 89, 84, 87, 75, 81, 85, 80, 85,
+  86, 84, 88, 87, 85, 83, 86, 75, 87, 83,
+  95, 86, 80, 74, 87, 82, 82, 80, 85, 84,
+  86, 81, 80, 85, 75, 73, 79, 80, 79, 76,
+  83, 86, 84, 86, 89, 77, 81, 88, 83, 88,
+  86, 94, 85, 80, 83, 85, 72, 87, 79, 79,
+  89, 80, 87, 83, 85, 81, 86, 76, 78, 90,
+  80, 89, 86, 84, 92, 83, 80, 79, 82, 79,
+  77, 84, 76, 83, 80, 85, 83, 91, 79, 89,
+  89, 82, 87, 76, 80, 86, 80, 90, 83, 79,
+  75, 72, 84, 80, 91, 84, 79, 87, 85, 83,
+  84, 84, 75, 76, 90, 83, 80, 87, 79, 81,
+  76, 84, 81, 74, 74, 88, 84, 79, 86, 85,
+  88, 81, 86, 77, 83, 83, 76, 85, 83, 87,
+  82, 90, 80, 83, 82, 73, 87, 80, 89, 86,
+  77, 77, 86, 78, 83, 82, 87, 85, 89, 83,
+  82, 83, 81, 77, 80, 85, 84, 78, 85, 87,
+  83, 91, 89, 84, 84, 95, 90, 83, 87, 92,
+  85, 81, 88, 86, 82, 82, 87, 86, 89, 85,
+  85, 90, 80, 82, 83, 84, 83, 87, 88, 92,
+  91, 84, 87, 83, 78, 82, 80, 80, 78, 86,
+  78, 89, 81, 87, 90, 90, 82, 89, 91, 88,
+  87, 80, 78, 87, 79, 90, 86, 80, 80, 75,
+  88, 86, 85, 92, 82, 83, 90, 81, 88, 82,
+  76, 77, 89, 83, 82, 89, 81, 86, 84, 90,
+  82, 83, 81, 87, 85, 76, 86, 84, 86, 80,
+  88, 78, 86, 86, 81, 87, 84, 87, 84, 95,
+  81, 80, 84, 76, 83, 82, 91, 86, 82, 78,
+  91, 79, 81, 80, 85, 77, 79, 85, 80, 87,
+  77, 83, 80, 79, 84, 80, 80, 84, 84, 82,
+  84, 82, 84, 84, 82, 79, 79, 99, 91, 93,
+  82, 89, 81, 91, 90, 85, 89, 82, 89, 87,
+  85, 78, 85, 83, 79, 99, 91, 86, 92, 77,
+  87, 82, 82, 84, 90, 81, 84, 86, 83, 84,
+  84, 86, 84, 88, 84, 88, 92, 89, 83, 79,
+  84, 86, 80, 90, 77, 77, 75, 74, 80, 85,
+  93, 82, 72, 94, 87, 73, 85, 86, 80, 82,
+  85, 83, 88, 84, 82, 84, 81, 93, 77, 77,
+  84, 90, 83, 94, 76, 82, 88, 87, 86, 81,
+  79, 81, 81, 81, 87, 84, 88, 85, 87, 85,
+  84, 78, 88, 86, 91, 80, 72, 82, 82, 87,
+  79, 77, 81, 78, 77, 79, 75, 82, 77, 79,
+  78, 80, 85, 82, 75, 84, 87, 81, 81, 79,
+  81, 81, 82, 81, 85, 101, 83, 90, 79, 89,
+  65, 87, 83, 82, 92, 76, 85, 80, 89, 77,
+  85, 78, 82, 101, 79, 85, 90, 72, 85, 83,
+  86, 85, 85, 81, 81, 83, 87, 83, 87, 83,
+  87, 84, 83, 92, 91, 91, 79, 84, 80, 88,
+  84, 85, 79, 81, 76, 72, 83, 90, 96, 81,
+  75, 96, 83, 75, 81, 79, 82, 80, 81, 86,
+  85, 87, 83, 79, 81, 88, 73, 72, 80, 92,
+  88, 100, 75, 83, 92, 84, 87, 84, 79, 77,
+  77, 79, 86, 83, 84, 81, 84, 88, 78, 82,
+  92, 85, 80, 73, 71, 85, 84, 80, 78, 81,
+  88, 82, 79, 86, 82, 82, 75, 80, 79, 84,
+  87, 81, 83, 87, 83, 83, 86, 86, 85, 92,
+  89, 75, 90, 92, 82, 89, 87, 88, 80, 81,
+  93, 88, 92, 83, 87, 85, 85, 79, 83, 77,
+  82, 87, 87, 89, 86, 78, 80, 84, 80, 82,
+  85, 78, 82, 82, 82, 88, 81, 85, 90, 91,
+  85, 83, 90, 86, 84, 76, 77, 86, 81, 88,
+  82, 78, 80, 76, 86, 86, 91, 93, 80, 86,
+  86, 78, 85, 78, 79, 85, 86, 83, 84, 89,
+  81, 85, 85, 91, 82, 79, 89, 88, 87, 84,
+  79, 83, 85, 83, 88, 81, 84, 82, 86, 83,
+  88, 86, 88, 87, 83, 78, 79, 81, 84, 83,
+  84, 86, 74, 80, 84, 86, 80, 79, 87, 78,
+  85, 94, 84, 75, 97, 87, 81, 84, 89, 80,
+  89, 89, 70, 91, 91, 91, 87, 88, 94, 84,
+  79, 82, 84, 83, 86, 90, 171, 80, 94, 90,
+  86, 94, 86, 81, 85, 96, 81, 115, 93, 77,
+  90, 87, 82, 75, 77, 83, 80, 86, 79, 94,
+  83, 96, 77, 81, 79, 95, 80, 102, 82, 82,
+  91, 94, 81, 86, 96, 80, 76, 84, 76, 80,
+  81, 82, 78, 81, 91, 83, 92, 67, 89, 72,
+  86, 83, 78, 89, 86, 86, 96, 80, 81, 94,
+  82, 87, 90, 85, 85, 88, 79, 85, 87, 80,
+  81, 88, 80, 79, 86, 91, 86, 81, 81, 82,
+  85, 85, 86, 78, 84, 83, 83, 81, 84, 92,
+  68, 78, 78, 82, 90, 80, 86, 78, 83, 87,
+  79, 76, 97, 85, 80, 83, 90, 81, 85, 82,
+  70, 83, 90, 91, 86, 85, 92, 84, 80, 79,
+  81, 82, 86, 90, 181, 85, 85, 88, 87, 83,
+  75, 78, 92, 96, 86, 118, 100, 76, 89, 87,
+  83, 76, 73, 80, 84, 84, 75, 90, 80, 93,
+  84, 80, 82, 93, 81, 94, 86, 86, 93, 100,
+  80, 91, 93, 79, 76, 90, 82, 80, 79, 87,
+  78, 86, 91, 81, 89, 66, 84, 72, 84, 77,
+  81, 88, 79, 90, 94, 78, 84, 94, 82, 82,
+  86, 83, 87, 87, 80, 94, 92, 82, 84, 85,
+  76, 79, 85, 89, 79, 77, 78, 81, 80, 77,
+  79, 84, 82, 87, 85, 82, 80, 83, 65, 77,
+  78, 77, 87, 82, 86, 83, 89, 93, 86, 79,
+  94, 87, 81, 85, 89, 81, 92, 80, 70, 89,
+  90, 96, 88, 96, 90, 76, 81, 78, 85, 79,
+  90, 88, 167, 89, 91, 95, 87, 86, 75, 81,
+  82, 100, 89, 112, 90, 68, 91, 89, 77, 79,
+  78, 80, 78, 84, 74, 84, 80, 92, 80, 89,
+  83, 94, 87, 101, 80, 76, 87, 91, 83, 86,
+  85, 79, 75, 87, 86, 77, 83, 81, 83, 87,
+  89, 87, 93, 64, 85, 75, 85, 81, 76, 92,
+  84, 85, 90, 82, 80, 90, 84, 84, 87, 81,
+  86, 85, 87, 79, 87, 76, 80, 86, 79, 84,
+  91, 90, 85, 88, 79, 83, 84, 81, 82, 78,
+  79, 84, 82, 79, 92, 99, 72, 80, 81, 86,
+  90, 79, 79, 102, 74, 94, 70, 71, 77, 94,
+  100, 92, 72, 78, 99, 72, 66, 79, 81, 80,
+  81, 83, 68, 92, 90, 85, 79, 91, 106, 94,
+  111, 88, 60, 81, 71, 83, 60, 91, 112, 82,
+  96, 80, 91, 69, 106, 70, 72, 89, 71, 94,
+  91, 83, 82, 87, 89, 74, 100, 96, 95, 60,
+  79, 81, 86, 85, 53, 90, 62, 68, 94, 90,
+  83, 113, 89, 77, 116, 66, 82, 98, 84, 78,
+  82, 77, 85, 77, 91, 90, 83, 78, 94, 71,
+  69, 85, 81, 99, 73, 98, 112, 82, 88, 78,
+  77, 112, 94, 91, 95, 92, 70, 80, 64, 79,
+  82, 66, 77, 41, 79, 92, 106, 91, 80, 75,
+  79, 91, 78, 86, 83, 89, 78, 73, 85, 61,
+  78, 78, 82, 94, 71, 80, 66, 99, 100, 96,
+  73, 72, 81, 85, 65, 72, 76, 66, 71, 82,
+  89, 95, 93, 82, 75, 76, 111, 93, 112, 81,
+  48, 81, 59, 82, 61, 96, 110, 86, 82, 72,
+  95, 63, 69, 62, 72, 97, 78, 78, 97, 75,
+  91, 96, 83, 64, 108, 88, 98, 55, 77, 78,
+  77, 96, 49, 81, 66, 66, 77, 74, 77, 114,
+  123, 75, 113, 71, 85, 101, 88, 94, 74, 73,
+  80, 71, 92, 99, 76, 86, 90, 73, 67, 69,
+  81, 94, 76, 84, 130, 79, 87, 76, 62, 118,
+  96, 84, 87, 93, 64, 76, 66, 76, 67, 68,
+  80, 38, 74, 87, 120, 83, 91, 79, 68, 83,
+  74, 83, 72, 87, 74, 72, 76, 58, 74, 74,
+  78, 88, 81, 79, 70, 94, 91, 94, 78, 79,
+  90, 89, 67, 78, 88, 73, 82, 79, 109, 84,
+  81, 96, 88, 84, 102, 90, 91, 78, 79, 73,
+  80, 81, 61, 88, 85, 87, 76, 83, 84, 74,
+  55, 74, 82, 86, 85, 72, 90, 85, 87, 86,
+  90, 73, 97, 76, 99, 66, 84, 81, 76, 85,
+  73, 92, 64, 75, 94, 87, 82, 108, 65, 66,
+  122, 68, 83, 103, 90, 80, 64, 84, 83, 79,
+  91, 99, 83, 84, 91, 68, 82, 79, 86, 81,
+  83, 94, 115, 86, 87, 82, 65, 108, 84, 86,
+  93, 96, 81, 79, 68, 75, 79, 78, 87, 47,
+  75, 91, 106, 97, 83, 82, 81, 84, 84, 81,
+  87, 84, 83, 81, 90, 59, 71, 82, 78, 77,
+  61, 91, 88, 74, 90, 79, 79, 64, 90, 108,
+  83, 72, 85, 81, 69, 82, 92, 88, 83, 82,
+  84, 94, 91, 91, 96, 107, 109, 74, 72, 75,
+  78, 75, 94, 79, 77, 72, 81, 85, 91, 89,
+  68, 68, 81, 90, 79, 87, 82, 102, 80, 80,
+  87, 86, 74, 87, 66, 103, 97, 78, 55, 89,
+  87, 63, 99, 89, 79, 98, 60, 82, 77, 90,
+  91, 66, 83, 73, 93, 75, 86, 90, 76, 81,
+  84, 88, 89, 90, 87, 84, 68, 78, 72, 96,
+  70, 88, 97, 92, 80, 65, 90, 72, 95, 78,
+  84, 75, 79, 94, 84, 76, 85, 70, 84, 77,
+  91, 80, 87, 79, 82, 124, 108, 94, 87, 80,
+  76, 85, 81, 86, 66, 91, 64, 78, 66, 72,
+  85, 75, 108, 74, 78, 62, 95, 74, 80, 76,
+  85, 81, 65, 90, 95, 72, 84, 84, 86, 100,
+  100, 97, 97, 84, 107, 68, 64, 68, 90, 74,
+  99, 76, 77, 85, 74, 68, 103, 94, 55, 82,
+  87, 71, 70, 82, 89, 96, 79, 72, 77, 94,
+  70, 87, 58, 110, 82, 66, 54, 87, 65, 42,
+  93, 86, 76, 71, 102, 71, 75, 88, 93, 60,
+  81, 83, 118, 67, 84, 92, 81, 83, 86, 86,
+  81, 80, 107, 80, 71, 89, 75, 94, 73, 92,
+  89, 88, 62, 55, 91, 68, 87, 76, 84, 63,
+  78, 99, 98, 78, 94, 64, 78, 79, 92, 64,
+  69, 73, 68, 115, 96, 95, 88, 78, 75, 90,
+  77, 87, 68, 84, 62, 77, 77, 79, 72, 79,
+  104, 88, 80, 65, 73, 61, 82, 75, 81, 71,
+  73, 85, 81, 81, 85, 90, 92, 92, 86, 85,
+  92, 66, 110, 78, 68, 74, 84, 85, 102, 76,
+  81, 73, 79, 91, 77, 80, 77, 93, 93, 81,
+  88, 79, 81, 90, 81, 72, 100, 90, 82, 74,
+  75, 95, 88, 85, 65, 83, 72, 59, 85, 82,
+  89, 93, 117, 74, 90, 75, 98, 78, 91, 91,
+  109, 70, 81, 85, 82, 89, 81, 81, 82, 82,
+  87, 82, 65, 82, 77, 88, 103, 85, 89, 84,
+  63, 85, 91, 89, 97, 80, 81, 74, 78, 88,
+  93, 70, 85, 60, 78, 82, 85, 82, 73, 81,
+  74, 107, 82, 88, 85, 80, 81, 81, 84, 79,
+  94, 66, 73, 88, 70, 101, 92, 78, 70, 83,
+  78, 83, 82, 82, 87, 82, 92, 92, 81, 88,
+  88, 87, 82, 69, 71, 95, 76, 84, 91, 105,
+  118, 84, 96, 90, 92, 88, 83, 89, 88, 71,
+  78, 86, 85, 96, 83, 70, 93, 99, 79, 85,
+  89, 81, 87, 100, 91, 86, 73, 96, 94, 74,
+  93, 89, 77, 84, 97, 88, 91, 84, 89, 64,
+  93, 87, 75, 99, 94, 72, 73, 95, 83, 86,
+  82, 76, 78, 91, 83, 84, 87, 94, 78, 83,
+  77, 77, 88, 84, 70, 87, 97, 93, 102, 76,
+  78, 90, 88, 82, 93, 85, 90, 97, 65, 81,
+  82, 96, 94, 74, 69, 77, 72, 90, 88, 96,
+  88, 78, 86, 84, 88, 78, 82, 85, 94, 79,
+  77, 88, 65, 82, 90, 72, 72, 81, 76, 84,
+  92, 86, 95, 80, 97, 99, 84, 98, 86, 88,
+  83, 67, 75, 88, 72, 83, 84, 89, 128, 84,
+  108, 94, 93, 82, 88, 91, 84, 72, 78, 101,
+  96, 101, 83, 59, 101, 87, 66, 89, 91, 81,
+  83, 102, 80, 79, 78, 95, 93, 76, 85, 79,
+  78, 84, 79, 83, 101, 89, 91, 69, 71, 84,
+  69, 92, 92, 68, 70, 101, 77, 87, 82, 68,
+  72, 86, 98, 85, 78, 86, 80, 82, 76, 77,
+  93, 89, 63, 91, 93, 94, 89, 69, 71, 65,
+  85, 78, 85, 91, 84, 101, 65, 84, 83, 99,
+  89, 76, 80, 86, 68, 95, 100, 79, 78, 82,
+  78, 87, 78, 77, 86, 91, 80, 96, 86, 87,
+  80, 83, 76, 79, 88, 85, 80, 80, 77, 82,
+  83, 85, 89, 83, 84, 89, 79, 92, 94, 75,
+  82, 96, 71, 81, 86, 80, 118, 83, 86, 84,
+  90, 98, 83, 90, 81, 81, 85, 82, 89, 84,
+  84, 81, 104, 104, 81, 83, 88, 85, 83, 86,
+  86, 65, 75, 91, 86, 79, 82, 95, 80, 77,
+  98, 72, 93, 83, 95, 75, 100, 87, 80, 89,
+  87, 77, 83, 95, 93, 76, 79, 77, 81, 95,
+  78, 90, 75, 87, 84, 85, 71, 82, 90, 87,
+  80, 86, 90, 88, 71, 79, 85, 71, 87, 79,
+  91, 83, 85, 91, 83, 78, 79, 87, 83, 82,
+  87, 87, 106, 88, 83, 95, 87, 83, 85, 86,
+  78, 78, 85, 84, 73, 82, 74, 77, 78, 87,
+  78, 98, 80, 83, 80, 74, 67, 77, 76, 90,
+  85, 85, 77, 90, 102, 89, 84, 77, 75, 86,
+  104, 78, 92, 79, 83, 84, 100, 84, 90, 94,
+  83, 82, 95, 75, 93, 65, 78, 92, 77, 86,
+  84, 83, 91, 76, 99, 79, 87, 78, 87, 80,
+  92, 91, 78, 80, 80, 86, 81, 85, 99, 74,
+  91, 84, 56, 80, 91, 97, 82, 101, 77, 67,
+  68, 90, 88, 68, 83, 83, 75, 93, 76, 85,
+  96, 75, 86, 93, 105, 81, 98, 82, 97, 118,
+  75, 77, 101, 68, 80, 81, 87, 92, 93, 76,
+  79, 81, 62, 81, 84, 89, 87, 81, 81, 88,
+  76, 97, 82, 80, 86, 92, 84, 85, 81, 93,
+  98, 84, 68, 85, 84, 72, 86, 69, 71, 94,
+  84, 80, 101, 77, 63, 86, 76, 83, 80, 72,
+  78, 74, 88, 84, 76, 79, 78, 76, 79, 74,
+  87, 85, 87, 94, 104, 82, 81, 104, 78, 74,
+  74, 75, 100, 68, 100, 95, 78, 90, 84, 91,
+  84, 87, 96, 85, 88, 86, 86, 76, 82, 78,
+  83, 82, 73, 87, 75, 82, 96, 69, 95, 81,
+  48, 82, 88, 101, 85, 97, 78, 66, 64, 92,
+  87, 75, 84, 76, 69, 96, 73, 77, 84, 88,
+  74, 82, 91, 73, 99, 74, 89, 123, 73, 73,
+  84, 76, 79, 98, 91, 92, 79, 79, 73, 83,
+  60, 79, 88, 85, 80, 84, 82, 92, 97, 90,
+  76, 85, 88, 91, 86, 77, 82, 87, 98, 83,
+  68, 70, 89, 84, 94, 85, 82, 102, 81, 83,
+  78, 75, 63, 86, 70, 87, 85, 94, 81, 83,
+  71, 78, 90, 80, 85, 88, 96, 84, 89, 90,
+  92, 89, 98, 87, 76, 91, 86, 83, 87, 81,
+  96, 71, 103, 92, 79, 90, 79, 88, 90, 75,
+  89, 77, 78, 86, 88, 88, 87, 93, 80, 82,
+  77, 92, 74, 76, 94, 80, 85, 73, 65, 90,
+  85, 86, 75, 94, 80, 75, 68, 75, 91, 68,
+  93, 89, 74, 87, 85, 88, 86, 69, 91, 80,
+  93, 75, 100, 76, 95, 94, 83, 81, 78, 69,
+  77, 82, 85, 92, 101, 81, 87, 83, 71, 83,
+  76, 79, 84, 91, 88, 80, 87, 94, 88, 77,
+  87, 91, 89, 90, 83, 91, 90, 90, 40, 86,
+  77, 85, 75, 69, 65, 72, 92, 82, 108, 65,
+  56, 94, 73, 90, 82, 75, 74, 80, 100, 90,
+  59, 74, 70, 79, 85, 82, 100, 79, 78, 94,
+  100, 72, 92, 81, 73, 83, 105, 70, 87, 72,
+  74, 92, 55, 81, 79, 92, 83, 80, 90, 97,
+  84, 99, 72, 84, 99, 78, 88, 65, 68, 126,
+  82, 86, 63, 123, 87, 75, 94, 65, 69, 58,
+  93, 99, 68, 64, 54, 80, 97, 68, 81, 86,
+  69, 111, 76, 81, 91, 85, 85, 96, 107, 81,
+  79, 62, 100, 128, 74, 60, 94, 74, 85, 82,
+  86, 87, 81, 66, 90, 90, 71, 70, 76, 77,
+  73, 68, 75, 94, 70, 75, 69, 84, 84, 100,
+  80, 78, 88, 84, 101, 95, 32, 84, 90, 70,
+  103, 32, 67, 62, 85, 78, 142, 73, 79, 102,
+  66, 77, 76, 54, 70, 70, 82, 99, 43, 69,
+  77, 70, 58, 73, 102, 92, 98, 104, 87, 70,
+  84, 110, 68, 81, 125, 82, 103, 74, 93, 97,
+  52, 61, 85, 105, 74, 87, 87, 117, 81, 118,
+  63, 94, 73, 70, 115, 56, 61, 136, 70, 100,
+  40, 170, 86, 72, 92, 45, 82, 62, 80, 96,
+  74, 54, 41, 100, 104, 78, 81, 74, 55, 95,
+  87, 85, 63, 117, 74, 75, 83, 75, 92, 56,
+  72, 155, 67, 51, 101, 86, 76, 98, 95, 86,
+  63, 65, 73, 95, 53, 70, 81, 80, 60, 65,
+  85, 106, 92, 78, 88, 89, 88, 101, 77, 68,
+  93, 73, 109, 93, 56, 60, 85, 93, 81, 69,
+  69, 96, 84, 84, 95, 61, 50, 82, 66, 97,
+  84, 99, 81, 84, 75, 73, 80, 84, 81, 86,
+  100, 91, 83, 81, 79, 105, 103, 74, 82, 88,
+  75, 89, 75, 75, 82, 70, 89, 87, 66, 95,
+  82, 84, 90, 78, 86, 73, 87, 90, 85, 69,
+  97, 80, 83, 87, 73, 116, 87, 52, 77, 93,
+  77, 81, 91, 89, 75, 65, 91, 99, 79, 70,
+  51, 77, 87, 73, 90, 92, 75, 92, 77, 82,
+  80, 55, 87, 95, 96, 81, 69, 69, 108, 95,
+  83, 66, 75, 72, 83, 93, 85, 87, 95, 76,
+  91, 82, 79, 77, 60, 70, 80, 94, 71, 77,
+  85, 74, 68, 74, 99, 90, 96, 91, 90, 81,
+  90, 104, 61, 81, 80, 91, 79, 77, 78, 79,
+  79, 90, 92, 81, 60, 100, 77, 87, 89, 94,
+  71, 85, 91, 94, 75, 94, 88, 83, 100, 87,
+  87, 75, 87, 80, 103, 72, 95, 85, 73, 87,
+  69, 76, 81, 75, 83, 85, 66, 87, 89, 97,
+  84, 78, 93, 85, 88, 79, 79, 79, 105, 81,
+  79, 71, 80, 96, 67, 88, 82, 92, 77, 94,
+  104, 80, 78, 66, 88, 92, 86, 72, 69, 85,
+  106, 64, 82, 94, 75, 113, 102, 76, 102, 86,
+  96, 108, 97, 83, 86, 65, 104, 91, 82, 69,
+  99, 71, 79, 85, 87, 90, 87, 74, 92, 84,
+  82, 71, 67, 78, 76, 82, 80, 91, 69, 85,
+  75, 72, 93, 90, 85, 81, 79, 89, 91, 87,
+  52, 83, 89, 84, 86, 54, 80, 72, 79, 84,
+  115, 87, 62, 88, 72, 75, 80, 74, 68, 80,
+  75, 84, 60, 92, 89, 71, 84, 80, 84, 92,
+  85, 92, 103, 71, 94, 104, 69, 78, 110, 70,
+  104, 84, 85, 82, 64, 59, 97, 99, 79, 88,
+  93, 89, 83, 87, 82, 85, 95, 75, 86, 66,
+  77, 100, 54, 91, 65, 119, 75, 92, 109, 68,
+  77, 74, 87, 86, 88, 66, 66, 87, 105, 71,
+  83, 85, 65, 107, 98, 89, 79, 105, 83, 93,
+  97, 83, 91, 61, 88, 108, 75, 66, 97, 82,
+  82, 84, 87, 88, 71, 78, 75, 85, 69, 70,
+  60, 83, 62, 79, 84, 84, 92, 83, 85, 80,
+  101, 89, 78, 72, 84, 84, 93, 92, 67, 73,
+  89, 86, 79, 88, 86, 88, 79, 88, 82, 77,
+  64, 86, 79, 89, 86, 110, 72, 83, 79, 79,
+  79, 99, 92, 87, 106, 87, 78, 82, 92, 83,
+  99, 76, 91, 88, 81, 86, 95, 76, 83, 83,
+  89, 89, 70, 81, 88, 91, 88, 74, 96, 86,
+  87, 79, 79, 80, 102, 89, 87, 84, 81, 91,
+  68, 71, 85, 87, 66, 91, 94, 96, 73, 77,
+  82, 96, 91, 72, 67, 72, 92, 73, 90, 99,
+  76, 91, 101, 78, 86, 65, 96, 97, 87, 86,
+  86, 67, 92, 80, 84, 80, 88, 68, 76, 95,
+  86, 90, 90, 84, 91, 81, 80, 87, 68, 71,
+  80, 95, 80, 93, 82, 90, 87, 74, 98, 89,
+  82, 85, 79, 83, 86, 91, 90, 84, 87, 82,
+  82, 89, 82, 73, 86, 100, 79, 89, 95, 91,
+  84, 80, 71, 93, 63, 84, 89, 79, 91, 85,
+  92, 78, 93, 74, 94, 92, 80, 82, 78, 92,
+  94, 84, 85, 81, 84, 91, 80, 87, 95, 79,
+  77, 91, 89, 82, 89, 91, 85, 96, 95, 63,
+  87, 85, 77, 73, 68, 87, 83, 83, 76, 82,
+  78, 88, 82, 82, 81, 95, 80, 79, 84, 87,
+  92, 80, 83, 81, 88, 73, 85, 82, 70, 73,
+  80, 101, 93, 91, 88, 68, 74, 81, 87, 89,
+  81, 82, 77, 86, 75, 56, 87, 81, 81, 72,
+  93, 87, 96, 85, 82, 101, 93, 86, 75, 85,
+  90, 78, 88, 91, 83, 71, 78, 91, 58, 74,
+  93, 100, 69, 90, 92, 86, 80, 78, 83, 87,
+  84, 68, 75, 105, 78, 87, 96, 86, 84, 79,
+  68, 89, 59, 87, 96, 73, 93, 88, 81, 77,
+  90, 78, 84, 92, 77, 83, 77, 92, 95, 81,
+  93, 85, 86, 95, 83, 87, 89, 81, 82, 92,
+  87, 77, 84, 89, 88, 92, 95, 64, 88, 88,
+  74, 71, 64, 86, 89, 87, 79, 84, 73, 90,
+  76, 80, 84, 90, 81, 76, 80, 84, 97, 75,
+  86, 84, 89, 74, 86, 80, 63, 73, 76, 101,
+  90, 85, 89, 65, 63, 83, 85, 84, 82, 82,
+  70, 87, 82, 60, 85, 86, 79, 75, 88, 81,
+  92, 88, 82, 104, 92, 84, 69, 85, 84, 80,
+  88, 92, 83, 69, 74, 91, 51, 75, 94, 96,
+  69, 93, 85, 86, 78, 77, 86, 86, 83, 77,
+  82, 95, 82, 91, 92, 82, 83, 87, 75, 89,
+  64, 84, 94, 77, 91, 87, 82, 79, 94, 75,
+  85, 90, 81, 81, 78, 87, 96, 80, 92, 82,
+  91, 100, 84, 82, 86, 79, 79, 91, 85, 80,
+  88, 88, 87, 89, 93, 65, 86, 94, 73, 75,
+  69, 89, 89, 84, 77, 80, 77, 84, 81, 84,
+  89, 84, 88, 76, 83, 87, 96, 81, 87, 90,
+  93, 76, 84, 82, 71, 84, 76, 100, 90, 86,
+  90, 75, 70, 89, 84, 87, 79, 78, 75, 86,
+  91, 66, 90, 84, 80, 75, 90, 84, 90, 87,
+  85, 98, 91, 84, 73, 92, 82, 76, 85, 86,
+  84, 73, 71, 90, 58, 79, 87, 95, 72, 91,
+  95, 76, 92, 82, 81, 81, 70, 85, 103, 91,
+  81, 85, 93, 83, 78, 90, 88, 83, 73, 79,
+  77, 76, 77, 81, 94, 77, 90, 72, 96, 80,
+  78, 84, 75, 85, 82, 76, 96, 65, 91, 78,
+  62, 75, 83, 79, 67, 94, 98, 86, 86, 93,
+  88, 93, 90, 72, 84, 83, 76, 79, 72, 94,
+  88, 75, 62, 85, 72, 80, 87, 80, 93, 81,
+  79, 78, 85, 87, 87, 71, 81, 80, 85, 75,
+  95, 77, 92, 78, 79, 100, 96, 90, 86, 73,
+  73, 88, 67, 83, 86, 77, 65, 85, 78, 64,
+  86, 86, 85, 74, 97, 108, 83, 79, 59, 93,
+  79, 87, 83, 88, 85, 83, 84, 81, 86, 70,
+  80, 95, 65, 73, 86, 98, 68, 84, 100, 76,
+  87, 85, 80, 81, 68, 86, 97, 89, 82, 83,
+  93, 85, 76, 94, 85, 75, 76, 84, 80, 71,
+  80, 84, 84, 73, 88, 73, 81, 82, 75, 86,
+  84, 82, 81, 80, 95, 63, 87, 73, 57, 75,
+  78, 76, 70, 96, 99, 84, 85, 92, 85, 89,
+  88, 71, 86, 80, 76, 73, 68, 97, 89, 80,
+  65, 88, 67, 80, 83, 81, 99, 78, 75, 77,
+  85, 82, 93, 67, 81, 87, 83, 75, 94, 73,
+  96, 86, 73, 95, 92, 84, 81, 70, 68, 85,
+  62, 81, 84, 74, 64, 82, 85, 68, 90, 87,
+  88, 76, 98, 108, 80, 84, 56, 91, 75, 83,
+  85, 88, 80, 85, 86, 80, 85, 67, 72, 88,
+  64, 77, 82, 96, 67, 91, 91, 81, 89, 84,
+  80, 80, 72, 89, 97, 87, 83, 87, 89, 91,
+  76, 93, 86, 79, 83, 81, 86, 79, 82, 84,
+  83, 79, 92, 73, 85, 83, 82, 82, 78, 79,
+  87, 83, 101, 68, 88, 83, 66, 72, 79, 80,
+  68, 90, 92, 80, 88, 89, 90, 94, 87, 74,
+  87, 85, 78, 78, 74, 95, 88, 79, 62, 83,
+  73, 78, 86, 84, 99, 85, 83, 76, 81, 83,
+  92, 77, 84, 89, 85, 75, 94, 80, 95, 96,
+  76, 92, 91, 85, 86, 76, 72, 87, 66, 83,
+  82, 77, 69, 83, 88, 70, 89, 86, 83, 76,
+  100, 107, 84, 82, 64, 85, 79, 87, 84, 94,
+  86, 84, 82, 78, 86, 72, 72, 91, 72, 74,
+  82, 93, 73, 87, 77, 83, 99, 81, 88, 90,
+  77, 93, 110, 77, 95, 93, 86, 84, 74, 85,
+  100, 81, 94, 86, 80, 72, 66, 78, 91, 84,
+  87, 74, 84, 81, 88, 83, 73, 76, 71, 79,
+  93, 72, 94, 70, 78, 63, 93, 82, 65, 90,
+  85, 88, 106, 83, 97, 94, 78, 100, 95, 87,
+  87, 82, 98, 85, 87, 84, 69, 87, 80, 71,
+  98, 95, 101, 85, 71, 91, 76, 80, 94, 75,
+  79, 88, 96, 68, 94, 88, 111, 100, 86, 97,
+  94, 92, 86, 82, 85, 92, 64, 90, 87, 88,
+  87, 86, 87, 103, 86, 68, 82, 83, 130, 112,
+  74, 82, 60, 58, 74, 80, 116, 98, 95, 78,
+  79, 68, 80, 81, 83, 87, 82, 71, 78, 99,
+  94, 69, 76, 83, 87, 85, 88, 83, 77, 93,
+  103, 80, 98, 92, 83, 89, 69, 80, 98, 76,
+  102, 96, 83, 70, 74, 81, 87, 82, 79, 73,
+  60, 77, 87, 81, 75, 79, 75, 82, 93, 76,
+  90, 65, 82, 68, 87, 80, 71, 87, 78, 97,
+  106, 79, 93, 94, 75, 104, 96, 91, 92, 76,
+  97, 90, 82, 90, 68, 92, 80, 73, 94, 102,
+  105, 80, 72, 94, 74, 70, 109, 78, 76, 93,
+  96, 68, 89, 82, 105, 98, 92, 92, 97, 91,
+  82, 80, 84, 90, 61, 96, 89, 87, 89, 81,
+  90, 119, 88, 68, 90, 87, 138, 115, 69, 89,
+  61, 55, 71, 82, 130, 93, 92, 76, 72, 68,
+  84, 78, 79, 76, 79, 80, 75, 99, 104, 71,
+  80, 83, 82, 87, 90, 72, 81, 100, 112, 79,
+  100, 89, 85, 92, 74, 86, 102, 77, 102, 86,
+  91, 73, 79, 81, 87, 88, 86, 76, 75, 75,
+  89, 78, 77, 74, 85, 85, 94, 73, 83, 72,
+  83, 65, 83, 85, 69, 86, 84, 98, 103, 84,
+  97, 94, 77, 101, 95, 88, 86, 83, 92, 85,
+  86, 84, 67, 88, 81, 70, 103, 93, 99, 84,
+  83, 88, 73, 77, 98, 78, 79, 95, 101, 71,
+  92, 89, 108, 93, 86, 90, 98, 92, 85, 81,
+  91, 90, 63, 89, 84, 92, 89, 86, 88, 108,
+  90, 72, 77, 84, 132, 105, 76, 85, 66, 54,
+  74, 82, 115, 90, 91, 80, 73, 71, 84, 78,
+  80, 84, 90, 70, 77, 96, 93, 78, 85, 75,
+  78, 86, 139, 84, 71, 79, 73, 81, 78, 91,
+  74, 106, 77, 77, 76, 77, 85, 80, 82, 87,
+  100, 73, 88, 75, 88, 86, 94, 94, 77, 91,
+  77, 95, 88, 85, 81, 85, 89, 77, 83, 82,
+  86, 89, 76, 83, 78, 85, 79, 84, 80, 77,
+  78, 77, 87, 95, 70, 75, 91, 74, 83, 79,
+  94, 69, 91, 76, 88, 78, 86, 99, 67, 85,
+  93, 91, 76, 74, 80, 88, 72, 76, 80, 89,
+  80, 83, 57, 79, 86, 91, 74, 95, 76, 76,
+  88, 81, 93, 78, 90, 92, 79, 81, 82, 78,
+  82, 82, 83, 77, 81, 103, 80, 74, 85, 78,
+  75, 76, 96, 86, 91, 91, 84, 82, 89, 92,
+  79, 72, 97, 82, 85, 88, 83, 79, 66, 86,
+  164, 75, 66, 81, 68, 77, 82, 107, 84, 103,
+  78, 79, 77, 76, 87, 82, 84, 81, 80, 75,
+  87, 74, 90, 84, 89, 91, 84, 99, 81, 98,
+  95, 93, 86, 76, 99, 82, 84, 79, 82, 107,
+  86, 78, 86, 73, 72, 85, 79, 86, 78, 83,
+  77, 93, 66, 80, 103, 70, 88, 71, 101, 72,
+  87, 76, 89, 77, 88, 94, 77, 84, 91, 87,
+  80, 65, 85, 83, 83, 78, 82, 93, 78, 79,
+  54, 82, 86, 91, 84, 104, 73, 85, 94, 80,
+  89, 83, 94, 100, 79, 78, 88, 90, 80, 83,
+  84, 80, 75, 108, 85, 82, 82, 78, 73, 81,
+  105, 76, 75, 87, 78, 85, 95, 99, 74, 71,
+  106, 80, 83, 89, 83, 86, 77, 85, 116, 91,
+  74, 82, 78, 78, 83, 89, 83, 88, 74, 80,
+  80, 81, 87, 78, 86, 82, 78, 76, 81, 76,
+  88, 84, 92, 82, 78, 91, 77, 78, 95, 95,
+  82, 86, 89, 80, 86, 84, 80, 85, 83, 85,
+  79, 91, 80, 85, 82, 78, 82, 77, 85, 86,
+  77, 71, 88, 80, 85, 81, 88, 74, 81, 80,
+  73, 78, 81, 89, 94, 89, 99, 90, 79, 78,
+  82, 89, 79, 76, 80, 85, 86, 79, 63, 76,
+  78, 84, 76, 95, 79, 89, 86, 81, 89, 80,
+  87, 91, 81, 83, 80, 95, 79, 84, 82, 76,
+  80, 93, 79, 77, 77, 74, 73, 88, 92, 83,
+  86, 89, 83, 81, 95, 88, 83, 77, 90, 82,
+  85, 86, 79, 79, 74, 80, 172, 87, 63, 81,
+  80, 74, 75, 93, 85, 100, 78, 76, 87, 70,
+  82, 75, 81, 87, 83, 78, 86, 74, 73, 76,
+  98, 90, 75, 88, 78, 107, 81, 81, 73, 82,
+  98, 82, 85, 81, 87, 99, 86, 84, 86, 85,
+  72, 79, 84, 84, 81, 82, 77, 96, 64, 79,
+  103, 69, 74, 73, 88, 67, 85, 81, 81, 76,
+  91, 76, 69, 72, 83, 87, 75, 71, 77, 92,
+  75, 75, 91, 83, 76, 82, 56, 80, 85, 95,
+  76, 89, 71, 79, 98, 74, 94, 81, 84, 100,
+  82, 88, 90, 86, 80, 78, 82, 80, 85, 103,
+  73, 79, 80, 83, 70, 82, 112, 65, 79, 87,
+  80, 83, 90, 80, 72, 65, 102, 80, 84, 75,
+  71, 82, 72, 76, 199, 74, 55, 83, 77, 73,
+  81, 106, 101, 108, 81, 78, 89, 71, 84, 83,
+  86, 88, 78, 81, 85, 70, 72, 77, 95, 89,
+  86, 93, 77, 109, 81, 90, 80, 80, 118, 89,
+  87, 85, 81, 122, 100, 74, 91, 72, 71, 74,
+  79, 90, 80, 87, 69, 97, 69, 83, 112, 63,
+  75, 66, 91, 71, 69, 86, 85, 71, 93, 75,
+  61, 67, 83, 84, 80, 63, 80, 92, 77, 84,
+  93, 86, 74, 80, 55, 86, 83, 93, 83, 93,
+  68, 80, 103, 75, 85, 85, 82, 115, 82, 84,
+  89, 80, 82, 80, 80, 78, 78, 105, 75, 86,
+  80, 81, 68, 81, 117, 60, 65, 81, 81, 83,
+  90, 88, 65, 72, 112, 78, 83, 75, 81, 84,
+  81, 83, 135, 87, 67, 80, 81, 74, 83, 87,
+  86, 90, 76, 77, 84, 74, 80, 80, 82, 84,
+  85, 81, 78, 75, 77, 73, 93, 82, 77, 85,
+  76, 81, 86, 97, 72, 86, 100, 81, 88, 81,
+  74, 88, 88, 79, 86, 84, 74, 86, 82, 85,
+  84, 87, 77, 89, 80, 78, 94, 78, 80, 77,
+  87, 73, 80, 83, 76, 74, 83, 83, 79, 80,
+  92, 86, 78, 76, 82, 94, 76, 79, 89, 80,
+  79, 82, 63, 85, 80, 96, 73, 87, 75, 82,
+  96, 82, 80, 83, 84, 96, 77, 85, 86, 87,
+  81, 82, 82, 82, 85, 91, 72, 78, 76, 81,
+  70, 86, 103, 74, 85, 85, 81, 82, 88, 79,
+  79, 72, 88, 85, 83, 74, 76, 82, 76, 83,
+  129, 84, 72, 82, 75, 75, 84, 90, 82, 89,
+  76, 76, 91, 82, 83, 73, 83, 76, 85, 82,
+  81, 80, 90, 79, 84, 77, 84, 83, 82, 105,
+  83, 80, 93, 85, 92, 75, 81, 82, 88, 78,
+  84, 93, 83, 85, 83, 81, 80, 91, 82, 82,
+  87, 89, 74, 67, 97, 80, 77, 87, 83, 76,
+  86, 78, 86, 85, 87, 85, 93, 81, 85, 85,
+  77, 81, 80, 92, 85, 74, 81, 93, 79, 78,
+  63, 85, 86, 93, 76, 88, 84, 83, 101, 82,
+  97, 85, 83, 87, 77, 82, 76, 93, 78, 78,
+  81, 86, 81, 93, 79, 74, 85, 76, 75, 84,
+  94, 89, 73, 83, 79, 85, 84, 83, 81, 72,
+  92, 80, 86, 90, 72, 85, 80, 86, 139, 75,
+  70, 80, 73, 73, 86, 99, 90, 94, 81, 81,
+  95, 81, 86, 85, 85, 73, 84, 80, 80, 80,
+  88, 77, 82, 90, 82, 91, 80, 102, 73, 84,
+  108, 89, 103, 79, 81, 80, 88, 90, 93, 82,
+  84, 74, 80, 78, 74, 91, 80, 84, 82, 89,
+  76, 72, 97, 80, 77, 80, 89, 78, 84, 75,
+  91, 80, 88, 93, 74, 76, 86, 81, 78, 72,
+  82, 84, 91, 74, 82, 99, 75, 79, 57, 89,
+  85, 87, 84, 84, 82, 86, 103, 84, 92, 86,
+  83, 94, 79, 76, 84, 87, 77, 79, 78, 82,
+  75, 94, 77, 80, 83, 74, 74, 83, 108, 79,
+  70, 80, 82, 86, 93, 85, 77, 74, 95, 84,
+  84, 91, 78, 81, 92, 88, 101, 89, 77, 77,
+  76, 75, 88, 86, 84, 96, 75, 80, 89, 83,
+  86, 79, 81, 74, 86, 86, 78, 80, 89, 76,
+  84, 87, 83, 87, 81, 81, 76, 94, 96, 84,
+  96, 76, 82, 83, 80, 72, 85, 88, 85, 87,
+  80, 86, 81, 92, 84, 83, 90, 84, 89, 66,
+  87, 88, 84, 80, 80, 78, 75, 78, 81, 84,
+  83, 85, 79, 86, 90, 86, 78, 85, 85, 88,
+  75, 73, 78, 92, 82, 82, 68, 93, 81, 91,
+  77, 86, 86, 79, 96, 86, 79, 85, 83, 85,
+  83, 81, 72, 89, 77, 80, 84, 87, 79, 86,
+  81, 74, 87, 76, 78, 86, 84, 88, 91, 83,
+  83, 86, 91, 82, 86, 78, 82, 86, 89, 90,
+  97, 89, 68, 94, 98, 81, 70, 98, 74, 89,
+  102, 91, 100, 77, 76, 82, 84, 87, 99, 75,
+  83, 83, 83, 78, 72, 87, 88, 105, 97, 77,
+  91, 102, 68, 94, 73, 96, 94, 100, 88, 80,
+  90, 82, 74, 80, 78, 65, 72, 84, 81, 71,
+  72, 85, 71, 83, 92, 96, 74, 80, 77, 105,
+  79, 84, 80, 97, 78, 72, 70, 82, 70, 91,
+  95, 76, 76, 96, 71, 85, 89, 100, 94, 90,
+  84, 89, 62, 82, 85, 75, 87, 89, 79, 75,
+  81, 89, 79, 88, 98, 80, 96, 81, 74, 70,
+  73, 77, 86, 93, 86, 103, 71, 96, 68, 78,
+  78, 67, 81, 90, 87, 88, 79, 76, 82, 89,
+  98, 74, 82, 86, 81, 96, 98, 86, 93, 88,
+  81, 91, 92, 85, 74, 95, 70, 87, 107, 90,
+  106, 84, 82, 79, 91, 91, 107, 79, 73, 80,
+  90, 77, 74, 84, 82, 101, 82, 74, 98, 108,
+  69, 93, 68, 89, 86, 96, 83, 78, 90, 79,
+  84, 81, 77, 70, 70, 80, 77, 72, 73, 94,
+  72, 85, 87, 78, 73, 81, 66, 120, 80, 81,
+  81, 101, 68, 64, 72, 88, 66, 84, 75, 69,
+  68, 100, 72, 85, 93, 91, 87, 91, 81, 89,
+  66, 84, 87, 79, 88, 89, 67, 77, 77, 90,
+  76, 86, 93, 82, 95, 85, 68, 71, 77, 84,
+  84, 93, 79, 90, 75, 96, 72, 80, 84, 73,
+  80, 91, 87, 78, 76, 73, 83, 84, 90, 75,
+  80, 88, 80, 98, 97, 85, 86, 80, 86, 91,
+  91, 90, 72, 93, 72, 92, 97, 90, 95, 92,
+  71, 83, 81, 82, 94, 79, 69, 88, 90, 81,
+  73, 87, 85, 101, 94, 78, 96, 113, 75, 91,
+  73, 101, 107, 99, 85, 81, 90, 81, 85, 81,
+  79, 69, 76, 87, 82, 69, 71, 100, 77, 79,
+  87, 71, 83, 80, 73, 98, 80, 87, 90, 91,
+  78, 76, 64, 78, 79, 94, 68, 73, 79, 89,
+  75, 90, 83, 89, 90, 89, 84, 88, 72, 87,
+  88, 77, 85, 88, 81, 77, 80, 84, 75, 84,
+  92, 80, 94, 82, 75, 80, 78, 77, 87, 90,
+  81, 100, 71, 92, 68, 78, 82, 70, 80, 93,
+  90, 85, 81, 78, 86, 90, 88, 76, 82, 82,
+  83, 94, 97, 86, 83, 88, 89, 86, 81, 84,
+  72, 87, 86, 84, 81, 99, 87, 85, 71, 74,
+  79, 70, 70, 73, 79, 88, 86, 81, 83, 83,
+  84, 87, 101, 85, 82, 90, 79, 78, 79, 88,
+  98, 83, 84, 75, 69, 80, 86, 82, 70, 79,
+  75, 83, 89, 79, 80, 88, 86, 78, 104, 91,
+  91, 82, 111, 84, 69, 78, 61, 79, 72, 77,
+  62, 76, 92, 80, 86, 77, 78, 75, 72, 85,
+  76, 104, 98, 85, 84, 92, 70, 75, 82, 94,
+  85, 82, 81, 82, 83, 81, 108, 78, 91, 76,
+  90, 65, 89, 67, 85, 70, 69, 92, 80, 136,
+  76, 89, 80, 81, 81, 53, 68, 85, 106, 102,
+  64, 87, 78, 87, 82, 88, 90, 65, 91, 99,
+  81, 71, 77, 86, 96, 81, 78, 88, 74, 85,
+  85, 83, 79, 90, 92, 93, 75, 72, 77, 70,
+  67, 76, 81, 90, 86, 79, 79, 85, 85, 85,
+  86, 87, 90, 96, 81, 84, 74, 75, 94, 81,
+  84, 76, 73, 89, 85, 85, 72, 71, 78, 86,
+  87, 79, 80, 109, 87, 76, 98, 106, 90, 81,
+  106, 89, 68, 75, 59, 78, 81, 74, 63, 78,
+  89, 77, 96, 75, 71, 77, 73, 85, 80, 87,
+  103, 86, 80, 91, 75, 75, 82, 103, 81, 86,
+  86, 78, 86, 79, 106, 78, 83, 79, 86, 69,
+  89, 69, 90, 73, 65, 93, 87, 138, 71, 90,
+  82, 78, 85, 60, 68, 80, 106, 91, 73, 84,
+  82, 95, 79, 88, 90, 60, 90, 98, 79, 69,
+  78, 85, 81, 86, 83, 86, 73, 80, 84, 88,
+  81, 88, 89, 87, 73, 72, 77, 71, 70, 75,
+  84, 81, 88, 88, 78, 88, 84, 88, 91, 85,
+  88, 93, 75, 84, 70, 84, 106, 84, 76, 75,
+  70, 84, 81, 80, 73, 67, 83, 101, 89, 79,
+  81, 84, 89, 80, 96, 90, 97, 81, 104, 83,
+  72, 83, 68, 80, 70, 74, 69, 77, 83, 80,
+  76, 76, 80, 75, 77, 88, 76, 81, 97, 85,
+  87, 87, 74, 87, 85, 99, 79, 79, 80, 82,
+  81, 79, 100, 80, 88, 80, 88, 72, 89, 71,
+  81, 72, 75, 90, 81, 127, 73, 83, 87, 77,
+  72, 60, 71, 87, 83, 91, 85, 89, 83, 84,
+  80, 83, 93, 71, 90, 90, 80, 79, 76, 86,
+  94, 82, 79, 90, 75, 76, 86, 85, 73, 80,
+  91, 92, 83, 81, 83, 85, 55, 75, 96, 88,
+  80, 89, 86, 91, 83, 82, 89, 84, 95, 76,
+  97, 79, 91, 88, 87, 80, 82, 83, 73, 78,
+  97, 87, 83, 88, 88, 87, 88, 92, 75, 94,
+  88, 82, 107, 70, 91, 72, 100, 87, 78, 101,
+  84, 75, 86, 76, 90, 84, 90, 81, 77, 76,
+  91, 77, 75, 85, 67, 88, 78, 79, 86, 79,
+  89, 82, 82, 82, 81, 72, 77, 90, 84, 89,
+  106, 85, 80, 88, 75, 74, 96, 79, 75, 85,
+  79, 92, 81, 106, 90, 87, 84, 76, 76, 79,
+  76, 85, 85, 87, 80, 92, 92, 91, 80, 80,
+  97, 67, 93, 86, 78, 86, 73, 87, 85, 81,
+  80, 78, 74, 77, 89, 88, 77, 75, 99, 88,
+  84, 85, 86, 86, 53, 76, 104, 82, 84, 90,
+  86, 91, 82, 81, 89, 87, 98, 73, 98, 76,
+  87, 78, 84, 87, 93, 80, 75, 80, 100, 91,
+  83, 94, 87, 86, 84, 91, 74, 90, 91, 82,
+  104, 81, 95, 70, 97, 90, 79, 102, 86, 77,
+  79, 77, 91, 88, 83, 81, 83, 72, 90, 80,
+  71, 79, 71, 81, 73, 81, 82, 77, 92, 87,
+  81, 86, 79, 73, 72, 89, 85, 86, 96, 86,
+  79, 86, 75, 77, 100, 81, 75, 81, 80, 94,
+  76, 93, 84, 87, 88, 73, 75, 82, 79, 76,
+  83, 86, 84, 90, 95, 96, 77, 81, 101, 67,
+  91, 83, 80, 86, 84, 84, 82, 84, 80, 72,
+  77, 71, 87, 87, 77, 81, 95, 82, 81, 82,
+  77, 84, 63, 77, 98, 82, 95, 89, 81, 89,
+  82, 82, 88, 89, 89, 71, 96, 79, 86, 85,
+  89, 80, 91, 81, 75, 77, 89, 90, 86, 84,
+  92, 90, 87, 90, 79, 81, 88, 87, 100, 84,
+  88, 78, 98, 86, 78, 94, 85, 77, 87, 82,
+  91, 82, 80, 86, 87, 80, 88, 76, 75, 82,
+  71, 85, 74, 77, 89, 78, 91, 93, 85, 86,
+  80, 73, 80, 84, 87, 81, 106, 86, 79, 92,
+  77, 77, 100, 75, 82, 74, 84, 89, 77, 100,
+  90, 83, 83, 74, 76, 78, 74, 80, 81, 85,
+  98, 89, 88, 83, 78, 82, 96, 72, 92, 83,
+  76, 87, 93, 83, 77, 95, 81, 91, 86, 78,
+  73, 105, 94, 85, 82, 81, 80, 80, 91, 90,
+  74, 76, 80, 78, 84, 72, 85, 80, 88, 84,
+  93, 88, 78, 90, 96, 79, 72, 85, 72, 70,
+  82, 78, 82, 94, 73, 88, 78, 80, 68, 85,
+  78, 97, 77, 80, 80, 82, 95, 79, 77, 89,
+  78, 80, 84, 89, 79, 89, 84, 81, 67, 73,
+  89, 82, 79, 94, 82, 79, 80, 106, 83, 81,
+  90, 86, 69, 82, 87, 85, 83, 100, 91, 99,
+  84, 85, 79, 85, 110, 83, 71, 81, 92, 84,
+  74, 78, 75, 74, 73, 77, 84, 84, 86, 86,
+  89, 102, 85, 88, 82, 80, 78, 78, 91, 81,
+  71, 81, 96, 80, 86, 74, 87, 99, 82, 91,
+  85, 85, 78, 88, 78, 90, 83, 82, 74, 115,
+  89, 80, 82, 81, 71, 80, 95, 83, 76, 78,
+  74, 76, 86, 75, 85, 74, 90, 86, 89, 83,
+  76, 87, 94, 81, 79, 84, 76, 72, 79, 83,
+  78, 94, 73, 86, 74, 70, 70, 87, 75, 99,
+  78, 79, 73, 79, 101, 79, 77, 86, 86, 86,
+  78, 88, 80, 86, 84, 75, 67, 83, 95, 77,
+  79, 95, 84, 77, 81, 107, 84, 84, 92, 87,
+  67, 78, 86, 90, 85, 100, 86, 105, 85, 89,
+  77, 90, 115, 79, 73, 71, 92, 78, 76, 79,
+  79, 81, 77, 76, 82, 87, 91, 88, 83, 100,
+  89, 88, 84, 87, 75, 81, 81, 83, 76, 76,
+  88, 81, 86, 74, 98, 95, 84, 96, 91, 85,
+  80, 92, 82, 82, 83, 81, 75, 100, 94, 83,
+  81, 78, 80, 79, 92, 91, 76, 79, 74, 81,
+  93, 75, 89, 81, 90, 87, 91, 80, 81, 93,
+  96, 87, 81, 76, 77, 75, 77, 79, 81, 94,
+  81, 92, 73, 80, 72, 87, 81, 93, 73, 76,
+  84, 83, 97, 74, 80, 84, 79, 84, 86, 87,
+  81, 89, 90, 79, 66, 77, 88, 81, 88, 89,
+  84, 79, 80, 99, 80, 90, 95, 86, 64, 87,
+  87, 93, 82, 94, 85, 93, 85, 90, 81, 83,
+  106, 88, 74, 81, 90, 85, 79, 79, 77, 85,
+  74, 78, 81, 84, 85, 86, 90, 101, 89, 89,
+  87, 93, 78, 77, 79, 84, 72, 82, 80, 85,
+  83, 77, 88, 92, 81, 87, 88, 80, 80, 83,
+  82, 86, 85, 81, 78, 119, 95, 85, 79, 80,
+  73, 80, 93, 92, 69, 83, 71, 87, 77, 75,
+  87, 76, 85, 84, 87, 84, 75, 85, 91, 77,
+  81, 88, 76, 78, 84, 69, 85, 100, 77, 83,
+  80, 81, 69, 82, 77, 105, 73, 78, 76, 85,
+  101, 85, 78, 97, 92, 78, 83, 88, 80, 89,
+  80, 85, 70, 84, 82, 81, 81, 101, 79, 85,
+  76, 114, 75, 86, 81, 80, 75, 76, 87, 91,
+  91, 85, 89, 96, 81, 79, 71, 90, 109, 77,
+  79, 81, 83, 87, 77, 81, 77, 74, 86, 75,
+  81, 94, 87, 84, 88, 108, 76, 84, 83, 82,
+  86, 79, 85, 77, 79, 80, 93, 82, 88, 81,
+  98, 78, 94, 88, 85, 79, 77, 73, 77, 82,
+  84, 85, 84, 140, 98, 86, 76, 82, 64, 77,
+  90, 77, 70, 86, 70, 99, 81, 82, 85, 69,
+  85, 86, 81, 83, 72, 80, 86, 83, 83, 93,
+  83, 82, 84, 69, 95, 114, 65, 76, 80, 70,
+  61, 84, 76, 126, 73, 83, 68, 80, 117, 85,
+  80, 99, 113, 87, 78, 90, 83, 91, 82, 85,
+  65, 98, 78, 80, 73, 125, 79, 79, 75, 127,
+  78, 84, 77, 83, 71, 71, 80, 92, 97, 79,
+  81, 109, 84, 80, 70, 86, 128, 66, 81, 75,
+  85, 82, 77, 83, 80, 86, 101, 76, 82, 102,
+  88, 86, 86, 109, 83, 78, 85, 85, 85, 88,
+  76, 77, 87, 78, 83, 90, 86, 84, 111, 74,
+  98, 101, 92, 84, 81, 82, 85, 75, 81, 84,
+  78, 111, 97, 83, 79, 81, 75, 78, 90, 95,
+  72, 83, 78, 86, 90, 79, 86, 77, 84, 88,
+  83, 86, 80, 87, 95, 85, 77, 85, 77, 78,
+  81, 69, 87, 98, 71, 87, 78, 82, 67, 90,
+  80, 100, 70, 78, 83, 83, 105, 81, 79, 94,
+  84, 80, 83, 84, 81, 88, 85, 86, 68, 83,
+  84, 82, 80, 98, 79, 84, 81, 105, 76, 89,
+  84, 82, 70, 81, 87, 97, 89, 82, 87, 93,
+  83, 85, 78, 86, 101, 83, 79, 85, 81, 90,
+  87, 83, 80, 87, 85, 78, 81, 90, 84, 85,
+  87, 102, 82, 84, 86, 94, 87, 81, 80, 79,
+  78, 80, 80, 83, 83, 79, 103, 76, 91, 84,
+  85, 81, 78, 84, 76, 91, 87, 84, 77, 103,
+  94, 82, 83, 83, 80, 76, 88, 96, 64, 79,
+  74, 76, 79, 74, 84, 80, 92, 84, 92, 83,
+  78, 90, 91, 72, 80, 89, 77, 79, 81, 76,
+  83, 99, 76, 82, 82, 79, 77, 94, 77, 102,
+  79, 73, 83, 86, 88, 84, 80, 83, 84, 75,
+  86, 93, 84, 86, 83, 89, 72, 78, 79, 84,
+  83, 96, 78, 97, 79, 103, 78, 85, 74, 86,
+  72, 83, 91, 80, 89, 84, 89, 87, 78, 83,
+  73, 99, 108, 82, 78, 87, 83, 90, 80, 79,
+  77, 81, 78, 76, 74, 85, 78, 83, 84, 99,
+  72, 93, 87, 81, 83, 84, 81, 84, 76, 74,
+  92, 81, 91, 79, 82, 81, 87, 87, 81, 78,
+  85, 79, 73, 80, 88, 86, 85, 112, 97, 85,
+  83, 79, 71, 76, 82, 89, 64, 80, 74, 83,
+  84, 79, 80, 76, 93, 84, 85, 82, 71, 87,
+  94, 73, 83, 86, 78, 82, 82, 74, 88, 98,
+  75, 81, 86, 72, 70, 86, 74, 110, 76, 74,
+  78, 84, 106, 85, 81, 83, 90, 76, 82, 100,
+  88, 87, 89, 91, 69, 76, 76, 90, 79, 103,
+  82, 94, 74, 106, 80, 86, 72, 87, 71, 75,
+  86, 85, 89, 80, 79, 93, 81, 81, 72, 90,
+  113, 74, 80, 87, 86, 86, 76, 84, 83, 80,
+  83, 78, 74, 83, 74, 84, 84, 96, 78, 89,
+  87, 82, 84, 85, 80, 80, 78, 78, 85, 79,
+  88, 82, 96, 81, 95, 93, 91, 80, 83, 84,
+  76, 74, 87, 85, 77, 97, 94, 81, 83, 80,
+  85, 74, 83, 99, 67, 82, 72, 77, 93, 75,
+  85, 80, 88, 88, 88, 82, 77, 91, 92, 82,
+  76, 81, 78, 79, 83, 76, 79, 92, 75, 84,
+  81, 76, 77, 85, 80, 99, 75, 69, 85, 85,
+  92, 83, 80, 83, 76, 80, 88, 93, 84, 87,
+  85, 93, 73, 78, 78, 85, 78, 96, 80, 95,
+  81, 95, 77, 95, 77, 87, 67, 86, 87, 98,
+  89, 88, 82, 88, 79, 84, 76, 92, 102, 88,
+  83, 91, 81, 93, 87, 81, 78, 81, 79, 81,
+  76, 83, 80, 84, 86, 96, 74, 91, 87, 90,
+  86, 85, 85, 87, 74, 74, 83, 83, 84, 75,
+  86, 82, 85, 87, 90, 89, 84, 101, 71, 72,
+  94, 76, 73, 92, 89, 81, 77, 61, 85, 79,
+  85, 82, 105, 89, 54, 86, 96, 99, 94, 86,
+  99, 97, 99, 82, 100, 93, 83, 78, 74, 93,
+  88, 77, 86, 79, 80, 77, 72, 89, 70, 90,
+  119, 87, 68, 88, 89, 83, 92, 93, 92, 77,
+  88, 91, 95, 72, 78, 74, 105, 81, 84, 61,
+  93, 74, 88, 99, 75, 93, 82, 69, 96, 86,
+  80, 76, 83, 78, 103, 85, 65, 69, 78, 81,
+  83, 80, 88, 72, 76, 79, 72, 90, 78, 68,
+  91, 78, 71, 74, 85, 75, 101, 67, 104, 71,
+  93, 76, 88, 89, 82, 84, 92, 85, 84, 75,
+  91, 69, 75, 67, 109, 89, 73, 75, 84, 86,
+  97, 100, 92, 85, 69, 102, 69, 72, 96, 75,
+  62, 83, 81, 63, 82, 77, 88, 75, 82, 76,
+  102, 83, 49, 74, 69, 112, 82, 83, 120, 95,
+  96, 81, 101, 96, 84, 80, 71, 78, 88, 79,
+  68, 70, 76, 86, 51, 78, 61, 91, 146, 78,
+  76, 82, 88, 81, 98, 90, 97, 84, 94, 92,
+  97, 66, 88, 72, 109, 94, 80, 64, 99, 67,
+  98, 105, 76, 87, 70, 62, 110, 85, 73, 76,
+  96, 77, 98, 69, 70, 82, 77, 75, 78, 65,
+  94, 76, 82, 72, 73, 101, 74, 64, 102, 77,
+  102, 79, 87, 76, 93, 71, 118, 82, 98, 78,
+  87, 84, 71, 92, 94, 76, 82, 71, 79, 73,
+  83, 55, 94, 78, 69, 76, 83, 85, 95, 95,
+  80, 88, 69, 100, 78, 95, 95, 77, 70, 96,
+  89, 82, 74, 90, 85, 77, 82, 76, 101, 77,
+  76, 83, 72, 102, 71, 92, 103, 98, 89, 78,
+  98, 91, 81, 94, 77, 82, 90, 77, 57, 79,
+  80, 78, 64, 83, 72, 83, 102, 71, 66, 88,
+  86, 76, 91, 96, 93, 86, 85, 94, 91, 72,
+  88, 77, 110, 86, 83, 68, 93, 80, 86, 85,
+  90, 84, 78, 76, 100, 90, 80, 86, 96, 79,
+  103, 85, 77, 99, 81, 79, 93, 75, 90, 84,
+  82, 75, 69, 92, 94, 75, 92, 80, 92, 78,
+  95, 81, 91, 66, 103, 71, 91, 74, 90, 84,
+  74, 88, 90, 94, 67, 73, 77, 77, 78, 72,
+  71, 87, 73, 78, 86, 81, 98, 98, 103, 79,
+  101, 93, 64, 76, 92, 79, 71, 85, 84, 88,
+  100, 84, 85, 67, 88, 75, 74, 79, 60, 98,
+  74, 97, 96, 92, 86, 86, 87, 84, 93, 96,
+  95, 85, 78, 85, 81, 86, 72, 78, 76, 85,
+  104, 85, 93, 101, 85, 88, 74, 86, 76, 84,
+  94, 80, 86, 61, 79, 82, 84, 86, 68, 83,
+  85, 73, 85, 70, 108, 77, 91, 88, 74, 90,
+  78, 79, 79, 85, 81, 95, 78, 85, 90, 88,
+  75, 70, 84, 81, 81, 78, 77, 71, 82, 72,
+  72, 112, 70, 79, 79, 91, 62, 81, 77, 78,
+  90, 70, 94, 98, 80, 88, 81, 82, 76, 70,
+  91, 79, 73, 88, 96, 87, 87, 65, 93, 81,
+  66, 86, 89, 81, 101, 85, 89, 98, 67, 85,
+  59, 71, 100, 76, 64, 72, 76, 70, 83, 70,
+  87, 69, 78, 63, 67, 82, 81, 78, 66, 110,
+  86, 101, 83, 83, 77, 77, 90, 92, 96, 79,
+  72, 69, 73, 102, 74, 68, 75, 91, 79, 76,
+  101, 97, 81, 91, 78, 80, 81, 64, 93, 81,
+  85, 68, 85, 77, 97, 97, 73, 81, 83, 79,
+  79, 64, 126, 88, 93, 81, 62, 84, 71, 80,
+  85, 93, 82, 88, 87, 82, 82, 82, 73, 78,
+  86, 83, 74, 70, 69, 75, 79, 76, 92, 137,
+  67, 83, 82, 91, 94, 91, 78, 98, 82, 76,
+  97, 104, 87, 92, 74, 78, 64, 73, 88, 71,
+  62, 95, 70, 110, 94, 62, 84, 71, 60, 90,
+  86, 77, 104, 87, 97, 101, 72, 96, 65, 86,
+  94, 79, 69, 85, 82, 91, 90, 73, 86, 71,
+  81, 67, 72, 76, 100, 91, 80, 97, 71, 92,
+  94, 82, 83, 79, 93, 96, 93, 87, 79, 81,
+  85, 87, 84, 79, 76, 87, 62, 86, 101, 96,
+  79, 95, 75, 91, 77, 78, 94, 84, 88, 89,
+  78, 86, 87, 83, 77, 80, 86, 78, 83, 75,
+  93, 83, 92, 79, 99, 89, 71, 83, 85, 84,
+  82, 86, 86, 81, 94, 88, 85, 88, 84, 80,
+  84, 75, 76, 74, 83, 73, 75, 107, 77, 81,
+  81, 90, 106, 79, 81, 93, 87, 69, 94, 96,
+  80, 82, 82, 77, 67, 74, 88, 86, 60, 78,
+  73, 86, 83, 66, 71, 81, 70, 86, 89, 74,
+  96, 87, 92, 79, 86, 92, 92, 70, 85, 88,
+  85, 86, 83, 94, 98, 82, 75, 63, 76, 71,
+  78, 82, 90, 91, 82, 89, 85, 87, 85, 76,
+  83, 88, 77, 84, 89, 83, 88, 86, 90, 78,
+  80, 86, 66, 97, 89, 93, 89, 92, 75, 93,
+  80, 97, 73, 86, 83, 81, 82, 83, 77, 90,
+  87, 89, 68, 89, 81, 74, 85, 83, 98, 89,
+  85, 86, 86, 86, 87, 86, 78, 92, 87, 96,
+  89, 86, 88, 91, 86, 79, 82, 83, 87, 90,
+  79, 86, 83, 76, 78, 96, 78, 94, 73, 81,
+  79, 83, 78, 91, 78, 68, 72, 98, 81, 90,
+  88, 78, 83, 86, 82, 77, 78, 79, 92, 91,
+  86, 89, 79, 83, 74, 85, 102, 85, 96, 73,
+  92, 84, 78, 88, 91, 83, 81, 88, 82, 79,
+  76, 80, 84, 82, 74, 63, 72, 73, 78, 83,
+  105, 80, 81, 79, 84, 97, 78, 72, 80, 82,
+  81, 88, 95, 82, 71, 79, 79, 78, 82, 81,
+  69, 92, 96, 94, 96, 80, 66, 90, 76, 91,
+  73, 77, 74, 81, 81, 78, 78, 86, 90, 87,
+  76, 85, 87, 69, 83, 75, 94, 92, 83, 87,
+  81, 79, 79, 93, 63, 87, 91, 93, 82, 80,
+  80, 84, 92, 85, 85, 89, 77, 90, 82, 85,
+  84, 81, 80, 102, 83, 101, 74, 79, 78, 79,
+  78, 103, 79, 73, 62, 92, 88, 94, 83, 69,
+  85, 95, 80, 79, 79, 88, 82, 102, 87, 99,
+  80, 76, 75, 91, 97, 83, 99, 71, 90, 91,
+  79, 88, 89, 89, 86, 86, 84, 85, 84, 94,
+  95, 77, 78, 68, 72, 70, 79, 79, 99, 93,
+  76, 82, 82, 84, 87, 75, 76, 93, 80, 90,
+  88, 83, 88, 86, 86, 84, 80, 86, 67, 92,
+  82, 93, 93, 83, 74, 88, 82, 101, 72, 85,
+  79, 83, 77, 74, 81, 91, 87, 90, 73, 94,
+  86, 73, 85, 85, 86, 91, 86, 87, 86, 89,
+  83, 90, 72, 90, 86, 91, 88, 83, 87, 91,
+  87, 91, 83, 87, 77, 89, 82, 82, 88, 78,
+  78, 96, 79, 87, 76, 86, 90, 80, 79, 91,
+  80, 68, 76, 98, 88, 88, 84, 77, 82, 86,
+  82, 87, 83, 78, 88, 91, 90, 94, 82, 85,
+  75, 86, 99, 79, 94, 74, 89, 76, 84, 79,
+  74, 89, 94, 82, 88, 74, 88, 83, 86, 73,
+  78, 74, 106, 99, 88, 74, 88, 84, 89, 76,
+  82, 92, 81, 69, 87, 77, 81, 81, 101, 82,
+  85, 94, 91, 72, 90, 72, 75, 104, 83, 80,
+  89, 81, 71, 90, 91, 93, 90, 81, 74, 92,
+  69, 83, 90, 85, 82, 84, 81, 92, 79, 88,
+  92, 97, 90, 73, 86, 76, 81, 86, 98, 80,
+  70, 95, 85, 85, 69, 92, 92, 89, 81, 72,
+  95, 90, 94, 70, 85, 59, 76, 90, 81, 81,
+  84, 95, 83, 76, 80, 85, 81, 88, 79, 85,
+  78, 73, 90, 87, 69, 79, 86, 77, 83, 72,
+  86, 83, 79, 78, 77, 80, 75, 76, 80, 85,
+  71, 84, 91, 87, 91, 78, 84, 78, 87, 71,
+  96, 74, 82, 76, 86, 85, 95, 84, 72, 72,
+  110, 93, 80, 76, 88, 87, 76, 89, 86, 90,
+  81, 65, 85, 83, 83, 86, 96, 87, 91, 86,
+  92, 68, 90, 79, 78, 113, 88, 77, 97, 88,
+  76, 87, 97, 96, 86, 90, 70, 91, 72, 88,
+  89, 84, 80, 89, 81, 98, 81, 90, 74, 108,
+  89, 80, 95, 77, 81, 91, 96, 63, 71, 87,
+  93, 83, 70, 98, 89, 88, 84, 78, 100, 96,
+  78, 69, 86, 69, 74, 75, 78, 87, 82, 96,
+  88, 73, 85, 91, 69, 88, 78, 87, 82, 76,
+  90, 88, 77, 73, 89, 78, 87, 79, 89, 83,
+  80, 90, 81, 88, 70, 77, 66, 84, 70, 88,
+  91, 92, 86, 80, 84, 83, 74, 81, 93, 76,
+  85, 77, 82, 86, 81, 84, 79, 77, 105, 99,
+  84, 77, 85, 88, 92, 77, 84, 94, 79, 76,
+  83, 77, 80, 87, 99, 83, 85, 88, 85, 82,
+  83, 76, 78, 100, 85, 83, 89, 79, 75, 83,
+  90, 88, 87, 80, 71, 94, 73, 81, 88, 85,
+  84, 84, 85, 91, 84, 93, 95, 95, 86, 77,
+  86, 76, 81, 88, 95, 73, 73, 88, 86, 86,
+  64, 86, 91, 92, 81, 88, 93, 99, 72, 71,
+  87, 65, 80, 79, 75, 87, 83, 93, 84, 79,
+  82, 82, 84, 85, 81, 86, 80, 75, 93, 88,
+  71, 74, 82, 78, 81, 85, 85, 89, 81, 81,
+  77, 82, 69, 78, 79, 84, 68, 79, 89, 91,
+  82, 83, 76, 78, 81, 92, 92, 93, 89, 68,
+  91, 87, 84, 84, 90, 65, 102, 88, 89, 71,
+  83, 81, 75, 70, 75, 88, 78, 77, 87, 83,
+  91, 76, 99, 75, 85, 92, 77, 93, 86, 89,
+  85, 74, 81, 81, 82, 89, 62, 82, 91, 91,
+  93, 84, 71, 83, 68, 88, 89, 85, 77, 83,
+  83, 89, 79, 87, 92, 89, 89, 76, 81, 77,
+  85, 80, 99, 86, 70, 101, 79, 82, 81, 91,
+  80, 85, 73, 69, 81, 92, 91, 69, 86, 80,
+  79, 117, 78, 89, 88, 94, 76, 91, 79, 89,
+  78, 89, 77, 82, 75, 83, 85, 78, 76, 86,
+  82, 74, 87, 69, 73, 81, 75, 83, 88, 76,
+  90, 77, 80, 98, 71, 79, 90, 82, 86, 88,
+  79, 74, 82, 67, 98, 92, 83, 62, 95, 86,
+  103, 90, 78, 62, 112, 71, 81, 74, 82, 84,
+  67, 79, 82, 92, 72, 72, 82, 88, 99, 86,
+  100, 81, 84, 76, 82, 96, 102, 91, 92, 68,
+  83, 74, 85, 97, 64, 85, 103, 94, 94, 94,
+  72, 77, 66, 88, 93, 83, 77, 92, 83, 93,
+  82, 86, 57, 94, 93, 82, 82, 66, 75, 85,
+  94, 72, 69, 91, 81, 87, 78, 103, 76, 87,
+  77, 78, 83, 109, 73, 63, 83, 85, 76, 80,
+  70, 108, 76, 96, 79, 95, 77, 102, 48, 78,
+  72, 81, 76, 84, 87, 75, 77, 78, 91, 71,
+  91, 69, 76, 86, 73, 90, 94, 80, 82, 79,
+  76, 100, 68, 78, 94, 87, 76, 89, 94, 89,
+  80, 74, 91, 85, 92, 72, 86, 83, 84, 87,
+  90, 68, 95, 88, 88, 82, 84, 86, 94, 72,
+  84, 89, 79, 81, 77, 86, 86, 83, 94, 76,
+  78, 82, 72, 107, 93, 86, 89, 75, 82, 85,
+  83, 84, 70, 81, 90, 92, 90, 86, 75, 85,
+  72, 85, 83, 85, 77, 82, 87, 88, 84, 90,
+  105, 85, 88, 79, 76, 94, 76, 82, 94, 84,
+  73, 88, 81, 84, 74, 85, 84, 86, 74, 98,
+  80, 109, 71, 75, 87, 84, 83, 95, 73, 89,
+  86, 96, 75, 91, 72, 86, 83, 77, 75, 83,
+  73, 85, 89, 80, 73, 81, 81, 71, 82, 83,
+  79, 86, 83, 80, 86, 80, 78, 79, 78, 93,
+  72, 78, 93, 87, 75, 83, 86, 102, 90, 101,
+  86, 89, 96, 78, 84, 91, 78, 93, 80, 97,
+  86, 88, 94, 94, 84, 91, 72, 64, 75, 80,
+  80, 92, 95, 82, 91, 84, 82, 71, 70, 100,
+  73, 102, 72, 82, 91, 69, 77, 94, 65, 77,
+  74, 76, 72, 85, 88, 75, 72, 74, 74, 83,
+  77, 81, 89, 84, 77, 73, 97, 71, 122, 63,
+  99, 88, 74, 115, 111, 77, 92, 110, 76, 92,
+  75, 85, 97, 75, 85, 76, 76, 81, 81, 93,
+  93, 100, 78, 86, 84, 147, 76, 87, 83, 79,
+  82, 78, 69, 70, 98, 93, 90, 83, 80, 99,
+  78, 93, 75, 84, 80, 68, 76, 86, 92, 85,
+  86, 79, 82, 76, 80, 69, 100, 98, 78, 73,
+  80, 75, 69, 81, 97, 97, 77, 88, 80, 102,
+  95, 83, 86, 91, 77, 92, 76, 87, 88, 84,
+  91, 91, 80, 83, 92, 60, 79, 82, 72, 97,
+  72, 81, 91, 86, 89, 77, 70, 86, 79, 114,
+  87, 80, 91, 69, 77, 85, 57, 73, 75, 79,
+  73, 89, 89, 78, 74, 69, 74, 83, 81, 76,
+  87, 91, 84, 70, 101, 59, 96, 57, 84, 82,
+  67, 112, 92, 77, 94, 113, 72, 94, 74, 91,
+  91, 82, 81, 74, 72, 99, 69, 105, 92, 98,
+  72, 92, 83, 136, 65, 94, 77, 71, 85, 79,
+  72, 77, 96, 88, 81, 83, 69, 95, 84, 86,
+  74, 86, 79, 65, 77, 82, 84, 87, 89, 78,
+  90, 72, 86, 70, 102, 102, 78, 75, 85, 75,
+  77, 76, 91, 98, 87, 69, 84, 91, 93, 82,
+  83, 93, 77, 90, 86, 92, 79, 88, 100, 92,
+  84, 96, 109, 64, 81, 81, 84, 91, 84, 82,
+  86, 83, 87, 76, 66, 85, 74, 100, 96, 81,
+  89, 72, 80, 95, 70, 75, 73, 78, 75, 89,
+  85, 76, 76, 78, 76, 83, 74, 82, 87, 88,
+  80, 79, 101, 74, 114, 67, 83, 85, 73, 121,
+  77, 75, 88, 113, 74, 89, 81, 85, 83, 76,
+  88, 76, 80, 102, 81, 101, 92, 104, 76, 83,
+  82, 132, 75, 82, 82, 83, 80, 78, 77, 65,
+  95, 82, 91, 85, 82, 98, 80, 95, 80, 81,
+  77, 66, 71, 83, 82, 88, 88, 75, 81, 77,
+  78, 76, 95, 92, 81, 83, 83, 79, 100, 62,
+  85, 49, 84, 68, 74, 66, 71, 55, 79, 87,
+  72, 91, 96, 81, 72, 71, 82, 86, 79, 82,
+  91, 76, 66, 65, 71, 83, 82, 82, 59, 88,
+  84, 75, 94, 105, 88, 132, 94, 72, 70, 62,
+  81, 62, 92, 71, 83, 82, 53, 67, 99, 79,
+  71, 77, 76, 83, 54, 70, 86, 129, 91, 68,
+  100, 87, 78, 87, 81, 88, 77, 73, 80, 111,
+  92, 94, 77, 93, 77, 92, 81, 67, 86, 74,
+  80, 92, 106, 74, 67, 119, 66, 92, 80, 85,
+  88, 72, 87, 72, 79, 71, 79, 97, 86, 84,
+  160, 92, 119, 75, 83, 86, 78, 84, 88, 85,
+  62, 86, 91, 96, 77, 111, 141, 77, 78, 66,
+  71, 63, 103, 73, 144, 57, 93, 92, 73, 58,
+  87, 86, 76, 64, 70, 39, 74, 88, 68, 100,
+  95, 81, 76, 71, 75, 79, 73, 83, 65, 80,
+  74, 73, 73, 84, 99, 95, 64, 82, 84, 73,
+  83, 105, 83, 123, 87, 76, 66, 70, 81, 65,
+  92, 82, 80, 92, 59, 68, 93, 74, 76, 80,
+  75, 86, 57, 69, 83, 109, 93, 73, 98, 85,
+  69, 90, 74, 83, 76, 70, 82, 105, 86, 90,
+  76, 88, 85, 75, 78, 69, 89, 70, 80, 81,
+  103, 74, 77, 110, 64, 86, 77, 94, 92, 72,
+  85, 69, 86, 77, 81, 90, 77, 91, 145, 91,
+  116, 77, 89, 84, 71, 84, 83, 89, 65, 66,
+  88, 95, 86, 106, 132, 77, 94, 65, 72, 67,
+  92, 78, 130, 62, 81, 93, 89, 68, 87, 89,
+  85, 96, 73, 70, 100, 85, 85, 88, 78, 90,
+  79, 69, 93, 94, 79, 84, 71, 85, 89, 78,
+  84, 82, 88, 88, 96, 91, 82, 93, 76, 93,
+  86, 87, 81, 86, 92, 80, 80, 86, 85, 96,
+  92, 82, 97, 79, 86, 86, 81, 87, 95, 87,
+  91, 81, 88, 87, 78, 86, 93, 61, 79, 78,
+  72, 84, 88, 86, 87, 86, 78, 89, 83, 87,
+  92, 76, 75, 76, 85, 84, 97, 79, 80, 72,
+  105, 77, 77, 93, 101, 95, 93, 87, 83, 88,
+  85, 75, 96, 89, 76, 78, 74, 87, 71, 91,
+  78, 86, 79, 88, 86, 78, 98, 67, 88, 88,
+  88, 72, 77, 88, 99, 88, 80, 79, 86, 84,
+  72, 89, 86, 72, 76, 66, 78, 67, 81, 74,
+  77, 65, 86, 89, 72, 81, 89, 89, 66, 74,
+  81, 88, 82, 80, 85, 93, 79, 75, 91, 83,
+  88, 95, 79, 93, 79, 90, 95, 93, 80, 119,
+  85, 76, 64, 69, 84, 69, 82, 88, 81, 81,
+  78, 74, 94, 80, 84, 84, 82, 84, 76, 76,
+  86, 97, 76, 78, 89, 88, 69, 88, 69, 71,
+  84, 72, 85, 99, 95, 80, 80, 90, 86, 89,
+  90, 61, 80, 87, 94, 85, 91, 69, 73, 101,
+  83, 96, 89, 65, 83, 81, 95, 75, 79, 73,
+  71, 79, 66, 78, 119, 88, 99, 90, 83, 77,
+  68, 89, 82, 87, 74, 97, 82, 103, 78, 82,
+  95, 83, 79, 65, 71, 65, 90, 91, 106, 70,
+  85, 84, 73, 68, 79, 80, 82, 75, 76, 55,
+  82, 92, 71, 87, 89, 88, 67, 76, 75, 82,
+  76, 82, 72, 95, 74, 77, 92, 80, 95, 104,
+  86, 86, 76, 83, 85, 89, 78, 108, 85, 80,
+  68, 71, 82, 69, 79, 82, 76, 90, 85, 74,
+  90, 80, 87, 86, 80, 81, 77, 77, 82, 87,
+  83, 81, 89, 86, 68, 91, 73, 70, 82, 76,
+  74, 96, 88, 80, 78, 88, 89, 77, 84, 64,
+  84, 83, 92, 75, 93, 73, 82, 99, 83, 90,
+  83, 72, 85, 84, 89, 75, 85, 76, 87, 76,
+  67, 78, 108, 85, 91, 86, 88, 77, 62, 89,
+  80, 85, 75, 75, 88, 99, 87, 79, 93, 88,
+  90, 67, 74, 70, 85, 98, 94, 74, 77, 81,
+  87, 71, 80, 82, 89, 98, 80, 79, 97, 84,
+  88, 84, 82, 94, 82, 78, 87, 88, 79, 89,
+  73, 89, 90, 83, 85, 83, 88, 85, 98, 90,
+  82, 93, 82, 87, 83, 81, 83, 89, 84, 79,
+  87, 91, 84, 90, 83, 85, 92, 81, 85, 91,
+  86, 89, 91, 80, 88, 84, 86, 84, 75, 87,
+  87, 62, 77, 83, 80, 86, 86, 84, 80, 79,
+  77, 83, 83, 80, 89, 76, 71, 79, 84, 86,
+  93, 81, 76, 71, 103, 81, 84, 90, 97, 82,
+  83, 93, 83, 84, 83, 80, 97, 86, 78, 87,
+  77, 82, 59, 90, 84, 85, 72, 86, 92, 81,
+  97, 65, 91, 89, 82, 66, 71, 86, 90, 78,
+  83, 81, 88, 85, 68, 87, 83, 84, 85, 72,
+  83, 87, 82, 92, 87, 84, 88, 90, 95, 86,
+  80, 84, 76, 74, 98, 90, 86, 91, 89, 99,
+  90, 87, 92, 70, 83, 88, 96, 102, 85, 103,
+  90, 74, 83, 84, 81, 76, 88, 67, 87, 92,
+  82, 89, 85, 88, 95, 82, 91, 86, 90, 90,
+  98, 89, 91, 84, 91, 87, 72, 88, 73, 79,
+  80, 83, 81, 90, 84, 84, 88, 72, 83, 75,
+  82, 81, 86, 82, 77, 74, 80, 91, 110, 81,
+  82, 67, 67, 81, 77, 104, 90, 68, 85, 95,
+  92, 88, 80, 84, 84, 83, 78, 81, 68, 81,
+  54, 93, 93, 78, 81, 91, 84, 85, 94, 83,
+  86, 96, 83, 59, 66, 82, 86, 80, 77, 70,
+  86, 101, 61, 96, 86, 87, 85, 72, 81, 89,
+  85, 95, 85, 86, 85, 92, 91, 85, 83, 81,
+  72, 78, 92, 87, 85, 86, 85, 98, 87, 88,
+  94, 70, 85, 91, 96, 96, 87, 97, 90, 75,
+  83, 81, 84, 77, 86, 67, 86, 90, 81, 85,
+  82, 86, 96, 83, 90, 88, 91, 88, 93, 90,
+  88, 85, 85, 85, 74, 88, 74, 78, 83, 84,
+  84, 86, 83, 83, 81, 73, 79, 76, 80, 77,
+  85, 81, 76, 75, 83, 89, 112, 81, 81, 69,
+  63, 81, 82, 102, 89, 75, 86, 96, 93, 86,
+  81, 83, 95, 84, 82, 78, 71, 81, 51, 90,
+  93, 79, 82, 90, 83, 82, 92, 80, 85, 93,
+  80, 60, 67, 85, 82, 82, 81, 76, 85, 111,
+  61, 92, 81, 81, 83, 69, 77, 89, 82, 88,
+  88, 89, 80, 83, 88, 81, 79, 87, 82, 83,
+  99, 84, 86, 86, 83, 87, 94, 89, 85, 81,
+  78, 88, 87, 96, 87, 97, 86, 91, 89, 87,
+  85, 84, 87, 77, 91, 97, 84, 86, 82, 86,
+  88, 84, 86, 84, 83, 87, 87, 80, 82, 94,
+  83, 89, 71, 92, 76, 77, 84, 84, 87, 95,
+  80, 84, 82, 71, 78, 75, 89, 69, 84, 78,
+  73, 81, 79, 83, 96, 78, 78, 60, 74, 86,
+  76, 100, 78, 79, 87, 90, 92, 90, 78, 82,
+  102, 87, 88, 85, 82, 78, 68, 88, 90, 86,
+  77, 87, 93, 85, 82, 72, 89, 86, 80, 66,
+  74, 82, 89, 82, 77, 66, 85, 90, 75, 90,
+  91, 80, 88, 91, 86, 85, 78, 79, 72, 90,
+  78, 83, 92, 81, 92, 81, 70, 98, 76, 80,
+  84, 70, 72, 83, 86, 108, 79, 83, 108, 85,
+  87, 80, 72, 108, 65, 83, 79, 81, 72, 94,
+  77, 80, 81, 88, 98, 60, 79, 87, 87, 73,
+  76, 75, 74, 95, 60, 80, 81, 82, 64, 91,
+  104, 85, 92, 104, 81, 101, 85, 85, 81, 77,
+  70, 69, 77, 80, 82, 72, 80, 78, 92, 95,
+  78, 102, 88, 78, 91, 85, 87, 109, 77, 101,
+  86, 81, 80, 61, 96, 86, 89, 98, 81, 88,
+  75, 76, 87, 81, 78, 83, 75, 94, 68, 83,
+  83, 87, 85, 80, 70, 69, 86, 92, 66, 90,
+  102, 84, 75, 90, 69, 89, 78, 67, 86, 90,
+  79, 82, 81, 78, 81, 74, 76, 86, 80, 89,
+  84, 72, 92, 78, 72, 94, 71, 79, 89, 71,
+  76, 86, 89, 106, 78, 81, 91, 79, 81, 83,
+  78, 90, 67, 88, 73, 78, 82, 93, 76, 79,
+  86, 96, 103, 67, 82, 76, 81, 77, 69, 69,
+  75, 91, 64, 73, 85, 77, 69, 83, 103, 86,
+  90, 96, 78, 100, 85, 86, 82, 71, 72, 67,
+  85, 82, 86, 69, 85, 83, 89, 91, 81, 97,
+  88, 78, 84, 81, 86, 97, 74, 105, 80, 77,
+  83, 59, 81, 86, 88, 102, 78, 83, 73, 76,
+  81, 83, 80, 83, 75, 94, 67, 85, 83, 90,
+  82, 84, 64, 67, 81, 87, 62, 87, 99, 81,
+  71, 88, 63, 89, 80, 68, 81, 88, 85, 84,
+  72, 77, 74, 81, 71, 87, 83, 84, 94, 81,
+  87, 91, 79, 99, 79, 93, 83, 79, 85, 89,
+  86, 104, 85, 85, 98, 71, 87, 90, 75, 88,
+  76, 88, 79, 81, 90, 96, 86, 75, 86, 93,
+  92, 69, 83, 78, 83, 83, 75, 77, 72, 84,
+  70, 78, 80, 85, 70, 97, 105, 79, 89, 99,
+  92, 95, 83, 88, 87, 89, 83, 71, 81, 82,
+  89, 73, 80, 91, 90, 96, 76, 91, 83, 81,
+  78, 80, 80, 93, 77, 99, 84, 81, 76, 66,
+  88, 84, 92, 101, 78, 92, 75, 82, 92, 80,
+  85, 85, 75, 93, 67, 84, 85, 88, 84, 86,
+  73, 73, 88, 90, 72, 87, 96, 92, 80, 92,
+  73, 87, 80, 71, 80, 75, 75, 87, 90, 85,
+  75, 75, 72, 88, 83, 79, 79, 80, 82, 88,
+  81, 90, 76, 86, 88, 74, 72, 87, 86, 89,
+  95, 83, 87, 83, 84, 85, 77, 105, 65, 82,
+  85, 86, 75, 83, 86, 74, 79, 87, 76, 77,
+  85, 82, 81, 79, 75, 67, 81, 88, 72, 100,
+  86, 85, 78, 91, 104, 78, 86, 87, 80, 88,
+  76, 86, 84, 82, 89, 76, 68, 69, 77, 76,
+  75, 75, 82, 81, 69, 89, 80, 80, 79, 87,
+  85, 85, 81, 101, 77, 74, 76, 72, 93, 78,
+  92, 90, 87, 86, 67, 85, 86, 80, 86, 82,
+  76, 86, 67, 84, 79, 94, 83, 80, 81, 74,
+  80, 93, 74, 79, 101, 84, 80, 84, 70, 93,
+  82, 70, 80, 83, 84, 81, 78, 83, 77, 72,
+  75, 89, 85, 86, 79, 83, 77, 89, 86, 89,
+  78, 91, 88, 83, 84, 92, 88, 81, 90, 82,
+  64, 75, 85, 89, 82, 94, 70, 87, 76, 86,
+  80, 79, 83, 74, 91, 94, 73, 84, 79, 77,
+  75, 83, 72, 75, 83, 87, 76, 84, 88, 84,
+  84, 83, 105, 83, 83, 83, 83, 85, 71, 89,
+  85, 83, 77, 73, 76, 69, 81, 76, 81, 84,
+  75, 77, 78, 80, 84, 72, 74, 88, 82, 80,
+  76, 97, 73, 70, 75, 68, 86, 72, 90, 88,
+  78, 86, 60, 77, 83, 81, 83, 85, 78, 82,
+  71, 82, 77, 93, 81, 80, 81, 79, 83, 90,
+  78, 81, 98, 83, 87, 82, 74, 90, 84, 74,
+  81, 81, 86, 84, 75, 82, 74, 72, 74, 87,
+  86, 86, 88, 93, 74, 91, 84, 91, 86, 93,
+  82, 91, 84, 95, 88, 86, 98, 86, 75, 73,
+  86, 98, 79, 93, 76, 74, 86, 85, 86, 83,
+  83, 73, 90, 92, 68, 89, 85, 85, 74, 89,
+  79, 87, 81, 88, 86, 76, 84, 85, 89, 91,
+  105, 79, 84, 91, 85, 83, 72, 85, 87, 94,
+  78, 76, 68, 70, 83, 78, 87, 95, 83, 83,
+  73, 81, 84, 76, 74, 89, 78, 80, 83, 94,
+  82, 73, 78, 70, 88, 73, 91, 87, 78, 95,
+  67, 77, 90, 81, 86, 92, 74, 81, 78, 87,
+  79, 92, 81, 84, 93, 87, 90, 90, 84, 80,
+  97, 90, 84, 87, 83, 87, 86, 83, 79, 86,
+  88, 88, 94, 84, 68, 68, 80, 82, 87, 80,
+  83, 95, 69, 90, 75, 82, 82, 96, 89, 91,
+  90, 100, 87, 77, 99, 78, 90, 81, 83, 96,
+  87, 104, 79, 99, 77, 89, 89, 71, 92, 83,
+  82, 87, 72, 96, 99, 88, 74, 93, 93, 85,
+  91, 88, 95, 92, 86, 83, 106, 91, 113, 78,
+  81, 80, 75, 81, 75, 82, 82, 95, 85, 89,
+  69, 70, 73, 82, 86, 92, 75, 78, 83, 79,
+  79, 82, 68, 97, 88, 68, 100, 98, 89, 77,
+  91, 74, 97, 75, 89, 90, 94, 86, 71, 85,
+  87, 82, 90, 81, 87, 73, 84, 96, 81, 95,
+  73, 84, 91, 95, 96, 92, 88, 77, 103, 86,
+  82, 87, 83, 91, 81, 92, 78, 89, 98, 83,
+  81, 93, 75, 66, 88, 82, 87, 84, 84, 94,
+  65, 87, 80, 83, 84, 100, 92, 102, 89, 100,
+  85, 75, 100, 78, 64, 81, 78, 101, 91, 94,
+  82, 93, 73, 89, 88, 65, 85, 83, 92, 96,
+  69, 111, 95, 91, 66, 96, 94, 94, 95, 83,
+  103, 97, 86, 86, 111, 86, 110, 80, 77, 80,
+  90, 83, 71, 80, 86, 96, 95, 84, 70, 69,
+  76, 80, 90, 96, 77, 77, 90, 75, 78, 82,
+  60, 101, 88, 68, 96, 87, 92, 77, 96, 68,
+  95, 68, 83, 87, 91, 88, 80, 88, 84, 83,
+  92, 79, 87, 72, 85, 97, 79, 93, 69, 87,
+  88, 91, 96, 91, 97, 83, 105, 90, 81, 82,
+  94, 90, 82, 98, 80, 88, 88, 89, 85, 95,
+  73, 62, 86, 77, 86, 84, 86, 93, 65, 92,
+  71, 81, 80, 101, 86, 107, 82, 104, 80, 72,
+  103, 83, 78, 82, 77, 101, 97, 99, 77, 81,
+  83, 89, 88, 71, 92, 84, 87, 87, 69, 111,
+  104, 99, 69, 103, 99, 88, 95, 86, 110, 97,
+  83, 84, 114, 91, 108, 83, 82, 89, 82, 87,
+  66, 79, 86, 85, 96, 87, 70, 71, 79, 85,
+  98, 96, 87, 80, 88, 77, 77, 87, 56, 106,
+  86, 61, 95, 89, 97, 83, 100, 70, 105, 70,
+  85, 83, 93, 90, 80, 93, 93, 82, 91, 83,
+  84, 68, 89, 98, 72, 95, 77, 91, 87, 94,
+  92, 89, 95, 84, 101, 88, 89, 87, 95, 86,
+  86, 103, 79, 86, 84, 72, 84, 87, 96, 72,
+  103, 75, 80, 85, 89, 94, 72, 88, 72, 78,
+  71, 78, 88, 89, 111, 70, 89, 89, 69, 68,
+  86, 86, 93, 88, 89, 80, 72, 104, 90, 72,
+  86, 72, 103, 78, 92, 85, 80, 94, 85, 90,
+  82, 90, 79, 74, 78, 85, 90, 88, 88, 73,
+  85, 82, 84, 85, 74, 74, 86, 71, 81, 89,
+  78, 88, 74, 82, 84, 74, 88, 81, 103, 92,
+  80, 66, 88, 87, 77, 75, 95, 85, 81, 82,
+  77, 91, 70, 85, 83, 84, 85, 113, 100, 90,
+  90, 79, 66, 77, 83, 80, 104, 77, 80, 88,
+  98, 66, 73, 79, 78, 91, 75, 94, 75, 79,
+  85, 106, 87, 71, 87, 91, 77, 86, 77, 80,
+  71, 90, 75, 51, 84, 85, 95, 66, 108, 70,
+  81, 85, 96, 86, 65, 89, 69, 90, 64, 76,
+  93, 91, 98, 61, 87, 73, 59, 48, 92, 85,
+  79, 109, 104, 81, 78, 76, 93, 68, 88, 67,
+  112, 64, 92, 81, 84, 109, 93, 84, 76, 91,
+  68, 84, 82, 93, 84, 82, 81, 75, 76, 92,
+  88, 89, 82, 73, 79, 69, 91, 90, 70, 90,
+  76, 71, 77, 74, 95, 68, 129, 90, 77, 65,
+  93, 83, 64, 73, 93, 71, 83, 88, 81, 96,
+  53, 95, 80, 84, 73, 115, 102, 81, 82, 87,
+  64, 87, 63, 82, 126, 63, 89, 83, 105, 56,
+  81, 75, 74, 84, 83, 94, 75, 95, 106, 104,
+  88, 61, 86, 90, 86, 90, 73, 88, 83, 86,
+  69, 63, 85, 102, 94, 69, 95, 76, 83, 85,
+  85, 84, 76, 88, 72, 81, 70, 76, 85, 87,
+  84, 71, 95, 84, 70, 67, 82, 82, 86, 107,
+  93, 96, 77, 75, 91, 71, 89, 74, 104, 74,
+  82, 82, 82, 102, 89, 92, 79, 90, 77, 72,
+  80, 89, 90, 70, 84, 74, 80, 85, 84, 88,
+  75, 75, 84, 68, 76, 87, 76, 78, 80, 81,
+  82, 74, 93, 82, 101, 90, 78, 70, 92, 85,
+  71, 90, 95, 81, 82, 88, 80, 98, 61, 98,
+  88, 85, 99, 111, 96, 88, 82, 77, 73, 82,
+  79, 80, 104, 77, 77, 84, 93, 72, 81, 78,
+  75, 89, 82, 95, 76, 85, 94, 102, 71, 71,
+  85, 91, 85, 86, 79, 82, 70, 82, 83, 69,
+  85, 83, 92, 71, 96, 67, 84, 74, 80, 90,
+  73, 88, 69, 80, 62, 85, 99, 86, 110, 76,
+  85, 88, 75, 52, 97, 85, 74, 83, 88, 75,
+  74, 109, 87, 89, 85, 64, 99, 78, 68, 81,
+  80, 101, 83, 88, 84, 77, 89, 82, 80, 93,
+  79, 92, 80, 78, 75, 100, 80, 82, 77, 71,
+  81, 64, 85, 88, 87, 73, 86, 80, 90, 74,
+  89, 84, 96, 90, 89, 80, 94, 85, 69, 76,
+  87, 81, 77, 84, 86, 87, 59, 73, 75, 78,
+  74, 96, 96, 96, 90, 86, 70, 92, 77, 80,
+  100, 93, 88, 77, 94, 66, 84, 84, 79, 86,
+  89, 80, 75, 86, 87, 106, 100, 62, 105, 86,
+  85, 83, 84, 87, 77, 95, 81, 53, 94, 78,
+  96, 68, 79, 67, 84, 68, 97, 93, 62, 97,
+  70, 77, 48, 84, 85, 102, 80, 73, 80, 83,
+  70, 36, 101, 91, 66, 117, 115, 83, 76, 78,
+  84, 97, 96, 63, 75, 79, 74, 72, 79, 101,
+  93, 94, 80, 75, 86, 80, 86, 113, 70, 87,
+  73, 87, 70, 114, 81, 84, 74, 73, 66, 66,
+  91, 80, 98, 68, 73, 75, 84, 64, 93, 70,
+  98, 91, 78, 99, 105, 93, 66, 78, 85, 74,
+  70, 90, 89, 85, 49, 66, 69, 84, 54, 81,
+  105, 88, 84, 95, 54, 87, 56, 88, 118, 89,
+  84, 68, 117, 50, 101, 74, 80, 70, 93, 75,
+  71, 104, 100, 93, 99, 48, 106, 85, 105, 76,
+  83, 109, 70, 100, 79, 62, 88, 102, 89, 65,
+  89, 72, 82, 73, 80, 88, 77, 87, 69, 79,
+  57, 83, 68, 91, 81, 74, 93, 86, 76, 52,
+  89, 83, 71, 111, 97, 87, 78, 71, 85, 88,
+  87, 65, 92, 81, 89, 75, 80, 102, 84, 82,
+  85, 75, 89, 79, 82, 96, 80, 81, 79, 82,
+  72, 100, 80, 90, 79, 74, 86, 64, 87, 87,
+  84, 73, 73, 86, 92, 74, 92, 83, 90, 93,
+  82, 87, 97, 89, 70, 99, 87, 85, 80, 92,
+  92, 90, 56, 82, 76, 78, 82, 91, 94, 92,
+  77, 80, 71, 81, 74, 84, 99, 96, 84, 75,
+  89, 69, 94, 85, 82, 80, 92, 83, 90, 88,
+  92, 99, 74, 65, 98, 88, 89, 82, 85, 91,
+  69, 77, 84, 85, 82, 83, 89, 68, 99, 73,
+  84, 75, 87, 93, 75, 87, 61, 81, 71, 85,
+  89, 88, 93, 79, 94, 88, 88, 67, 89, 89,
+  76, 80, 89, 77, 77, 105, 77, 93, 79, 73,
+  92, 90, 76, 81, 78, 95, 78, 84, 87, 77,
+  77, 83, 79, 96, 91, 83, 80, 76, 74, 93,
+  78, 82, 79, 81, 95, 68, 84, 92, 90, 84,
+  87, 89, 94, 78, 86, 96, 88, 87, 92, 82,
+  95, 80, 82, 85, 83, 90, 87, 90, 90, 83,
+  60, 77, 86, 74, 81, 89, 83, 100, 76, 85,
+  81, 97, 84, 79, 86, 94, 78, 84, 78, 82,
+  88, 82, 90, 86, 84, 82, 73, 74, 89, 87,
+  90, 79, 101, 88, 84, 74, 92, 90, 65, 86,
+  78, 74, 79, 81, 82, 68, 87, 71, 87, 70,
+  96, 89, 76, 96, 65, 80, 57, 81, 79, 94,
+  84, 80, 85, 86, 92, 46, 92, 87, 66, 98,
+  104, 77, 71, 93, 70, 103, 88, 74, 71, 92,
+  73, 71, 76, 96, 76, 91, 83, 80, 76, 82,
+  81, 109, 81, 84, 71, 82, 69, 98, 78, 81,
+  76, 75, 100, 66, 90, 83, 103, 87, 86, 85,
+  100, 78, 85, 88, 83, 92, 86, 95, 102, 79,
+  77, 88, 82, 90, 81, 94, 86, 76, 43, 80,
+  78, 71, 66, 74, 86, 102, 73, 91, 75, 100,
+  72, 82, 90, 97, 69, 68, 71, 76, 91, 77,
+  88, 80, 85, 79, 80, 72, 87, 81, 88, 72,
+  99, 86, 92, 62, 92, 100, 70, 92, 73, 77,
+  83, 88, 90, 67, 93, 72, 80, 79, 90, 82,
+  79, 87, 64, 81, 66, 82, 77, 85, 87, 81,
+  91, 87, 92, 62, 85, 86, 75, 95, 99, 85,
+  81, 78, 75, 95, 98, 73, 85, 93, 87, 77,
+  76, 93, 73, 80, 90, 76, 78, 84, 77, 102,
+  90, 86, 77, 82, 72, 93, 81, 81, 85, 82,
+  101, 68, 79, 89, 91, 91, 75, 96, 96, 82,
+  88, 93, 82, 92, 87, 85, 96, 80, 83, 92,
+  84, 98, 86, 96, 90, 78, 54, 83, 83, 75,
+  83, 82, 85, 99, 87, 84, 80, 86, 86, 81,
+  89, 95, 75, 81, 77, 79, 90, 81, 92, 85,
+  86, 87, 95, 73, 90, 86, 82, 83, 96, 90,
+  82, 71, 97, 92, 99, 85, 81, 83, 84, 88,
+  107, 96, 78, 79, 66, 88, 85, 88, 83, 85,
+  93, 90, 92, 80, 70, 82, 99, 91, 85, 85,
+  80, 65, 95, 85, 81, 84, 101, 83, 84, 87,
+  89, 77, 83, 84, 93, 78, 92, 84, 94, 94,
+  87, 80, 90, 84, 78, 90, 81, 76, 74, 81,
+  89, 88, 74, 84, 79, 83, 77, 94, 92, 81,
+  84, 78, 85, 75, 73, 75, 89, 94, 68, 93,
+  94, 73, 84, 86, 84, 87, 80, 75, 89, 84,
+  81, 77, 90, 81, 60, 81, 86, 102, 82, 86,
+  76, 87, 77, 64, 68, 85, 82, 81, 69, 86,
+  87, 90, 65, 110, 87, 86, 92, 74, 79, 74,
+  73, 82, 99, 79, 60, 95, 57, 93, 83, 85,
+  104, 90, 100, 79, 78, 79, 92, 80, 101, 103,
+  82, 76, 64, 86, 96, 86, 85, 91, 101, 89,
+  89, 79, 89, 82, 83, 91, 84, 87, 82, 64,
+  79, 86, 80, 85, 103, 77, 83, 79, 83, 79,
+  88, 89, 84, 64, 91, 82, 80, 98, 90, 70,
+  88, 88, 82, 89, 80, 84, 71, 84, 82, 91,
+  63, 84, 73, 78, 75, 88, 74, 80, 81, 74,
+  82, 61, 69, 68, 94, 89, 69, 86, 88, 78,
+  88, 95, 84, 88, 83, 71, 80, 83, 80, 63,
+  93, 85, 69, 70, 71, 105, 72, 79, 73, 86,
+  81, 67, 59, 71, 80, 79, 66, 73, 81, 90,
+  69, 107, 81, 83, 91, 76, 76, 63, 74, 80,
+  93, 76, 77, 96, 63, 91, 86, 86, 109, 90,
+  97, 77, 73, 80, 89, 96, 105, 92, 77, 79,
+  66, 86, 87, 85, 86, 84, 90, 86, 98, 84,
+  95, 82, 82, 90, 77, 86, 83, 62, 81, 89,
+  84, 79, 99, 80, 90, 88, 85, 76, 90, 85,
+  92, 73, 71, 86, 92, 91, 89, 65, 93, 83,
+  80, 87, 84, 84, 76, 87, 96, 87, 74, 82,
+  76, 80, 74, 96, 90, 79, 85, 86, 84, 81,
+  78, 73, 88, 94, 70, 88, 91, 89, 87, 84,
+  87, 85, 85, 67, 89, 83, 74, 77, 90, 76,
+  66, 83, 84, 99, 83, 82, 76, 86, 83, 71,
+  64, 77, 78, 80, 69, 88, 88, 87, 67, 105,
+  77, 84, 89, 83, 77, 78, 86, 79, 93, 79,
+  79, 93, 63, 92, 83, 87, 105, 90, 75, 92,
+  76, 96, 86, 72, 84, 97, 91, 81, 67, 86,
+  77, 71, 73, 102, 81, 82, 89, 84, 70, 84,
+  78, 90, 83, 78, 88, 81, 87, 81, 73, 88,
+  90, 75, 70, 85, 87, 75, 102, 84, 78, 73,
+  80, 78, 72, 81, 84, 88, 87, 81, 75, 86,
+  75, 76, 78, 87, 81, 82, 94, 82, 84, 83,
+  71, 79, 95, 71, 93, 93, 93, 85, 77, 82,
+  91, 101, 74, 88, 79, 80, 77, 76, 84, 83,
+  94, 95, 84, 82, 81, 84, 85, 88, 76, 89,
+  76, 98, 86, 75, 76, 80, 80, 94, 64, 89,
+  100, 82, 78, 121, 75, 83, 64, 83, 75, 70,
+  77, 75, 90, 95, 76, 76, 86, 84, 81, 75,
+  85, 90, 87, 78, 91, 91, 75, 86, 83, 101,
+  89, 69, 70, 97, 111, 85, 74, 89, 78, 82,
+  74, 99, 84, 80, 97, 79, 83, 87, 65, 90,
+  81, 71, 87, 96, 97, 79, 70, 93, 92, 76,
+  73, 80, 80, 81, 86, 72, 66, 63, 77, 82,
+  59, 83, 78, 84, 79, 83, 73, 94, 81, 76,
+  82, 84, 79, 74, 83, 79, 87, 81, 64, 84,
+  80, 61, 97, 95, 100, 85, 73, 66, 101, 104,
+  74, 83, 73, 87, 84, 63, 82, 83, 104, 96,
+  86, 84, 75, 88, 79, 80, 92, 82, 61, 93,
+  91, 67, 86, 78, 76, 116, 64, 93, 109, 78,
+  68, 137, 72, 90, 68, 70, 67, 67, 74, 75,
+  93, 90, 77, 75, 75, 88, 84, 65, 93, 85,
+  85, 74, 91, 97, 77, 77, 74, 93, 90, 79,
+  84, 99, 97, 81, 69, 86, 78, 100, 78, 102,
+  81, 81, 90, 82, 84, 86, 71, 91, 74, 81,
+  91, 84, 82, 77, 80, 87, 97, 82, 83, 91,
+  82, 80, 71, 83, 75, 77, 72, 81, 70, 83,
+  86, 83, 89, 86, 76, 91, 83, 79, 82, 77,
+  84, 79, 93, 79, 81, 84, 71, 78, 87, 71,
+  87, 97, 97, 89, 68, 78, 91, 99, 77, 81,
+  74, 84, 85, 73, 86, 82, 91, 84, 91, 83,
+  75, 83, 85, 82, 79, 80, 78, 97, 86, 78,
+  77, 81, 84, 98, 64, 94, 96, 81, 82, 122,
+  75, 85, 69, 81, 69, 69, 75, 86, 85, 98,
+  80, 75, 83, 86, 86, 73, 91, 89, 86, 76,
+  94, 97, 62, 97, 95, 83, 77, 89, 77, 83,
+  98, 81, 81, 91, 84, 84, 66, 92, 84, 79,
+  94, 97, 80, 92, 75, 79, 69, 71, 90, 87,
+  81, 80, 88, 85, 71, 72, 72, 98, 79, 75,
+  95, 79, 78, 73, 78, 84, 69, 67, 83, 93,
+  87, 76, 88, 93, 75, 76, 72, 83, 78, 82,
+  107, 80, 88, 89, 89, 69, 93, 72, 83, 99,
+  91, 85, 70, 100, 81, 92, 85, 82, 87, 93,
+  75, 82, 83, 87, 95, 114, 98, 71, 88, 101,
+  80, 93, 89, 75, 79, 88, 81, 86, 76, 81,
+  86, 97, 80, 79, 100, 89, 86, 94, 80, 95,
+  81, 69, 75, 66, 67, 89, 100, 103, 82, 88,
+  74, 91, 82, 84, 99, 80, 98, 83, 83, 89,
+  44, 89, 86, 80, 81, 85, 67, 79, 103, 86,
+  95, 92, 83, 97, 65, 85, 81, 83, 87, 103,
+  77, 99, 75, 79, 66, 75, 90, 100, 99, 83,
+  93, 81, 72, 78, 82, 88, 84, 79, 97, 67,
+  86, 83, 78, 87, 61, 63, 83, 102, 79, 74,
+  88, 101, 77, 68, 72, 100, 70, 77, 116, 85,
+  93, 90, 78, 79, 97, 80, 86, 110, 100, 78,
+  86, 101, 77, 94, 88, 73, 89, 95, 88, 68,
+  76, 88, 91, 101, 115, 72, 83, 114, 72, 84,
+  97, 82, 90, 82, 82, 85, 75, 85, 90, 112,
+  82, 92, 111, 90, 90, 114, 77, 103, 82, 64,
+  73, 73, 65, 87, 104, 118, 81, 89, 71, 90,
+  86, 77, 97, 79, 92, 81, 85, 97, 67, 77,
+  72, 87, 82, 76, 79, 93, 101, 83, 87, 89,
+  85, 92, 75, 88, 81, 84, 88, 95, 79, 83,
+  84, 76, 66, 81, 92, 89, 80, 77, 92, 81,
+  75, 74, 76, 99, 80, 81, 76, 76, 76, 81,
+  80, 85, 67, 65, 87, 100, 91, 79, 89, 81,
+  83, 77, 77, 88, 76, 82, 111, 80, 82, 82,
+  89, 65, 92, 76, 78, 101, 94, 75, 94, 100,
+  87, 95, 87, 85, 85, 87, 83, 82, 82, 84,
+  87, 92, 96, 74, 87, 94, 80, 90, 89, 78,
+  83, 86, 91, 90, 75, 85, 87, 93, 77, 98,
+  99, 88, 89, 98, 78, 94, 81, 71, 72, 66,
+  71, 93, 89, 101, 80, 88, 78, 82, 93, 78,
+  104, 83, 96, 79, 85, 89, 94, 73, 98, 94,
+  70, 75, 88, 73, 77, 74, 83, 82, 96, 81,
+  81, 85, 77, 68, 91, 85, 90, 87, 86, 86,
+  91, 63, 100, 84, 92, 73, 107, 99, 78, 93,
+  85, 70, 90, 89, 73, 79, 75, 107, 68, 95,
+  81, 81, 91, 83, 73, 82, 75, 94, 83, 74,
+  76, 101, 70, 72, 84, 95, 84, 86, 77, 74,
+  79, 74, 102, 75, 85, 72, 68, 87, 83, 105,
+  77, 63, 82, 70, 84, 75, 92, 96, 97, 86,
+  110, 76, 85, 78, 91, 80, 73, 80, 85, 88,
+  66, 83, 91, 75, 88, 74, 72, 91, 79, 83,
+  92, 85, 77, 88, 86, 77, 94, 79, 67, 83,
+  90, 90, 72, 90, 94, 75, 87, 90, 86, 72,
+  78, 73, 85, 103, 75, 82, 87, 93, 76, 60,
+  85, 77, 76, 77, 80, 76, 86, 97, 89, 91,
+  71, 70, 80, 84, 72, 68, 70, 91, 91, 67,
+  106, 84, 102, 69, 109, 95, 79, 92, 76, 61,
+  98, 101, 99, 76, 81, 95, 78, 95, 81, 70,
+  94, 67, 70, 76, 81, 87, 79, 76, 69, 92,
+  57, 76, 88, 99, 87, 103, 90, 77, 71, 78,
+  103, 69, 92, 79, 77, 89, 81, 109, 76, 67,
+  81, 65, 93, 62, 99, 95, 86, 79, 101, 91,
+  75, 79, 95, 75, 80, 78, 94, 88, 71, 86,
+  87, 80, 101, 57, 70, 87, 86, 83, 93, 86,
+  85, 94, 87, 71, 88, 86, 65, 71, 89, 104,
+  63, 88, 91, 71, 89, 89, 81, 74, 78, 80,
+  83, 91, 88, 87, 77, 95, 76, 86, 87, 79,
+  80, 76, 83, 81, 103, 84, 83, 80, 77, 71,
+  89, 86, 66, 76, 76, 83, 93, 66, 105, 85,
+  83, 76, 98, 94, 75, 84, 82, 79, 90, 93,
+  89, 85, 78, 100, 87, 91, 85, 81, 82, 88,
+  68, 85, 77, 85, 83, 84, 79, 75, 64, 77,
+  87, 95, 84, 91, 83, 69, 78, 74, 95, 79,
+  79, 89, 85, 91, 85, 109, 79, 65, 79, 85,
+  73, 71, 92, 84, 94, 77, 103, 89, 77, 75,
+  91, 77, 75, 74, 86, 85, 74, 82, 86, 76,
+  101, 74, 74, 87, 82, 84, 93, 90, 84, 91,
+  90, 80, 70, 75, 70, 83, 95, 87, 69, 90,
+  91, 79, 93, 89, 81, 79, 76, 70, 86, 98,
+  64, 81, 103, 82, 88, 63, 71, 69, 93, 87,
+  78, 100, 95, 107, 68, 72, 78, 68, 78, 81,
+  92, 89, 79, 80, 79, 70, 99, 75, 105, 83,
+  87, 93, 76, 81, 78, 91, 76, 95, 69, 79,
+  87, 78, 73, 81, 85, 98, 68, 75, 92, 81,
+  83, 91, 88, 77, 76, 69, 68, 63, 93, 76,
+  74, 100, 82, 86, 74, 103, 81, 94, 75, 100,
+  56, 71, 84, 87, 71, 90, 75, 84, 91, 76,
+  87, 75, 80, 78, 91, 82, 84, 88, 74, 92,
+  86, 81, 80, 78, 80, 88, 77, 74, 78, 84,
+  78, 73, 86, 82, 92, 81, 80, 83, 73, 76,
+  104, 59, 69, 93, 98, 113, 107, 82, 94, 66,
+  92, 95, 77, 85, 92, 93, 75, 83, 36, 90,
+  72, 85, 86, 71, 60, 78, 98, 97, 68, 92,
+  42, 86, 72, 74, 68, 75, 91, 90, 67, 57,
+  87, 91, 71, 80, 107, 72, 107, 66, 67, 86,
+  73, 81, 73, 78, 62, 84, 71, 57, 86, 55,
+  63, 70, 90, 100, 76, 57, 107, 70, 94, 66,
+  84, 81, 94, 80, 81, 57, 88, 78, 69, 118,
+  99, 56, 92, 83, 72, 91, 67, 130, 78, 63,
+  100, 67, 89, 116, 76, 66, 104, 64, 86, 78,
+  69, 87, 65, 74, 93, 94, 56, 80, 112, 95,
+  64, 72, 117, 75, 85, 71, 76, 75, 75, 112,
+  95, 79, 116, 81, 110, 81, 80, 60, 89, 61,
+  92, 94, 82, 95, 110, 68, 64, 56, 90, 87,
+  71, 114, 100, 102, 70, 59, 69, 94, 58, 78,
+  82, 78, 77, 75, 93, 86, 82, 99, 109, 70,
+  73, 73, 75, 66, 83, 82, 68, 73, 79, 81,
+  78, 77, 101, 82, 101, 78, 81, 90, 80, 88,
+  87, 95, 78, 100, 114, 80, 96, 80, 93, 86,
+  79, 84, 61, 87, 88, 82, 81, 86, 90, 82,
+  88, 95, 78, 71, 92, 78, 75, 106, 83, 86,
+  77, 111, 69, 90, 72, 102, 102, 78, 86, 82,
+  71, 87, 77, 70, 106, 73, 93, 77, 75, 88,
+  96, 86, 89, 81, 77, 96, 97, 84, 82, 80,
+  80, 79, 82, 76, 103, 84, 77, 108, 88, 82,
+  95, 83, 91, 86, 81, 80, 78, 60, 76, 84,
+  83, 85, 72, 81, 92, 70, 88, 95, 75, 90,
+  91, 87, 75, 79, 73, 95, 101, 72, 86, 83,
+  89, 85, 89, 75, 76, 86, 87, 78, 92, 77,
+  80, 81, 76, 84, 63, 83, 80, 73, 86, 86,
+  75, 78, 83, 91, 77, 87, 99, 78, 75, 100,
+  87, 90, 96, 85, 81, 80, 76, 91, 94, 99,
+  72, 75, 88, 87, 83, 86, 83, 79, 80, 98,
+  85, 79, 96, 78, 79, 90, 86, 103, 73, 110,
+  77, 90, 78, 88, 97, 68, 92, 75, 73, 95,
+  80, 88, 83, 95, 88, 83, 87, 84, 94, 78,
+  83, 79, 87, 112, 85, 78, 79, 93, 104, 81,
+  76, 93, 100, 76, 89, 61, 82, 89, 84, 93,
+  74, 86, 84, 101, 84, 84, 89, 87, 82, 78,
+  115, 81, 93, 80, 85, 89, 81, 88, 80, 83,
+  81, 95, 68, 106, 92, 74, 98, 96, 79, 99,
+  97, 72, 80, 75, 62, 84, 80, 85, 72, 76,
+  91, 80, 62, 64, 86, 78, 86, 103, 62, 82,
+  74, 56, 88, 90, 81, 86, 66, 94, 79, 73,
+  75, 72, 72, 71, 57, 86, 106, 105, 85, 79,
+  106, 80, 94, 82, 81, 84, 78, 83, 113, 81,
+  95, 79, 70, 89, 95, 73, 72, 95, 67, 89,
+  74, 73, 92, 60, 88, 75, 83, 114, 77, 81,
+  61, 105, 86, 91, 97, 85, 89, 75, 92, 82,
+  86, 114, 96, 84, 70, 90, 118, 70, 79, 86,
+  85, 83, 83, 69, 99, 86, 83, 72, 95, 78,
+  85, 97, 80, 75, 113, 91, 77, 73, 95, 67,
+  74, 70, 93, 75, 87, 121, 94, 78, 75, 87,
+  80, 87, 97, 74, 90, 85, 92, 85, 85, 74,
+  81, 86, 90, 90, 92, 71, 73, 79, 78, 88,
+  78, 81, 84, 79, 82, 85, 76, 80, 75, 67,
+  80, 86, 99, 92, 95, 100, 85, 86, 69, 81,
+  82, 83, 66, 95, 92, 105, 74, 94, 91, 92,
+  77, 90, 82, 79, 82, 78, 84, 75, 94, 74,
+  77, 89, 84, 104, 78, 105, 74, 87, 82, 94,
+  108, 72, 87, 79, 69, 85, 83, 78, 82, 96,
+  91, 83, 76, 92, 99, 77, 90, 81, 84, 108,
+  85, 78, 81, 91, 93, 83, 77, 90, 91, 78,
+  89, 87, 83, 89, 83, 87, 79, 80, 80, 91,
+  90, 82, 87, 89, 92, 70, 70, 80, 91, 76,
+  96, 88, 93, 90, 77, 81, 79, 94, 85, 73,
+  87, 92, 96, 84, 89, 86, 72, 92, 91, 64,
+  61, 93, 89, 74, 85, 88, 96, 87, 82, 68,
+  91, 81, 106, 107, 82, 86, 93, 76, 77, 92,
+  93, 76, 70, 79, 80, 79, 83, 100, 83, 73,
+  75, 66, 93, 72, 69, 73, 94, 78, 71, 74,
+  67, 73, 78, 70, 83, 90, 74, 88, 84, 71,
+  93, 79, 95, 87, 81, 96, 77, 90, 76, 77,
+  86, 85, 82, 87, 94, 79, 101, 98, 69, 101,
+  97, 96, 64, 86, 97, 68, 80, 89, 90, 90,
+  97, 113, 78, 89, 75, 110, 80, 89, 88, 63,
+  81, 88, 91, 77, 76, 68, 77, 104, 82, 85,
+  95, 91, 71, 75, 89, 84, 60, 65, 97, 98,
+  95, 84, 62, 89, 90, 82, 82, 82, 75, 89,
+  99, 78, 85, 75, 75, 93, 96, 75, 67, 91,
+  92, 72, 89, 86, 97, 82, 83, 68, 87, 87,
+  100, 104, 75, 86, 88, 74, 79, 91, 90, 80,
+  65, 75, 79, 77, 81, 97, 85, 77, 73, 73,
+  99, 73, 69, 78, 89, 80, 66, 73, 75, 74,
+  80, 73, 78, 90, 76, 77, 92, 74, 88, 82,
+  85, 84, 75, 95, 79, 84, 78, 83, 82, 80,
+  84, 81, 99, 65, 102, 99, 71, 101, 95, 81,
+  68, 86, 94, 68, 80, 96, 83, 91, 99, 108,
+  75, 91, 81, 115, 79, 87, 80, 65, 76, 90,
+  92, 77, 74, 67, 75, 105, 82, 86, 92, 89,
+  73, 81, 73, 84, 59, 70, 89, 102, 89, 80,
+  68, 83, 91, 78, 83, 84, 78, 92, 94, 84,
+  85, 81, 75, 92, 93, 67, 70, 87, 87, 76,
+  88, 85, 94, 88, 79, 71, 91, 84, 91, 97,
+  80, 88, 90, 77, 76, 95, 97, 78, 78, 90,
+  84, 81, 81, 96, 85, 76, 77, 76, 92, 76,
+  70, 90, 93, 79, 73, 76, 71, 74, 78, 76,
+  87, 83, 76, 82, 79, 71, 92, 79, 98, 85,
+  78, 99, 80, 85, 88, 74, 85, 82, 87, 86,
+  96, 71, 99, 92, 70, 98, 96, 91, 68, 84,
+  94, 74, 79, 94, 91, 103, 94, 112, 81, 90,
+  75, 105, 79, 92, 88, 78, 79, 88, 91, 78,
+  83, 72, 75, 101, 82, 87, 96, 94, 68, 76,
+  79, 84, 61, 68, 86, 94, 91, 84, 63, 87,
+  92, 80, 87, 72, 85, 88, 103, 88, 93, 92,
+  76, 90, 85, 69, 64, 91, 93, 83, 87, 87,
+  93, 91, 83, 67, 86, 84, 104, 103, 83, 86,
+  89, 73, 83, 91, 92, 82, 79, 83, 78, 79,
+  77, 92, 84, 82, 78, 75, 100, 69, 74, 76,
+  90, 77, 77, 71, 70, 77, 81, 73, 77, 92,
+  78, 85, 84, 76, 84, 86, 90, 91, 79, 77,
+  79, 81, 82, 80, 87, 81, 85, 86, 90, 83,
+  89, 107, 67, 93, 95, 80, 68, 82, 89, 74,
+  81, 81, 81, 82, 99, 112, 78, 100, 81, 109,
+  88, 81, 77, 63, 81, 90, 86, 70, 80, 72,
+  71, 95, 81, 82, 93, 87, 66, 83, 85, 86,
+  66, 66, 89, 98, 95, 84, 65, 91, 97, 77,
+  89, 77, 77, 85, 102, 78, 93, 79, 79, 90,
+  89, 78, 65, 89, 99, 80, 92, 88, 94, 81,
+  84, 68, 81, 91, 106, 93, 78, 84, 84, 78,
+  82, 89, 86, 81, 76, 74, 80, 77, 82, 89,
+  86, 90, 77, 79, 102, 73, 81, 80, 83, 79,
+  77, 73, 77, 76, 84, 74, 75, 93, 82, 76,
+  88, 79, 80, 94, 82, 94, 77, 73, 81, 80,
+  77, 81, 85, 78, 89, 77, 94, 69, 89, 109,
+  68, 96, 93, 75, 72, 80, 87, 74, 82, 83,
+  71, 80, 96, 103, 72, 99, 88, 112, 86, 75,
+  74, 63, 77, 91, 85, 72, 77, 73, 63, 97,
+  81, 83, 88, 83, 72, 86, 74, 89, 68, 71,
+  74, 100, 84, 75, 70, 89, 97, 75, 81, 86,
+  84, 88, 99, 83, 89, 86, 80, 88, 90, 70,
+  66, 86, 88, 88, 88, 86, 92, 87, 81, 70,
+  88, 87, 99, 95, 79, 85, 86, 81, 84, 92,
+  96, 83, 78, 87, 80, 80, 84, 90, 84, 85,
+  76, 81, 96, 75, 78, 94, 88, 79, 80, 77,
+  73, 78, 81, 72, 81, 89, 83, 81, 80, 75,
+  84, 86, 94, 90, 81, 81, 79, 81, 84, 74,
+  86, 80, 85, 89, 90, 72, 90, 103, 70, 93,
+  97, 89, 71, 81, 92, 76, 83, 91, 85, 85,
+  94, 110, 78, 97, 82, 103, 81, 84, 84, 69,
+  79, 89, 84, 71, 80, 73, 70, 94, 82, 84,
+  94, 88, 66, 80, 82, 86, 68, 71, 77, 95,
+  95, 85, 63, 90, 96, 78, 89, 70, 82, 81,
+  91, 90, 96, 103, 80, 85, 81, 74, 66, 85,
+  88, 85, 85, 82, 86, 87, 80, 72, 83, 77,
+  99, 100, 95, 86, 89, 79, 79, 87, 99, 85,
+  84, 87, 79, 81, 74, 87, 81, 88, 76, 79,
+  93, 70, 80, 76, 89, 75, 72, 77, 67, 74,
+  85, 76, 82, 78, 82, 82, 78, 74, 84, 74,
+  100, 92, 79, 80, 80, 94, 93, 80, 83, 84,
+  88, 85, 88, 77, 92, 99, 66, 86, 95, 83,
+  65, 80, 87, 81, 87, 83, 85, 82, 92, 117,
+  79, 96, 71, 106, 86, 84, 91, 69, 82, 90,
+  83, 73, 78, 75, 79, 97, 81, 80, 94, 84,
+  70, 83, 83, 95, 71, 68, 87, 95, 98, 81,
+  59, 92, 88, 84, 90, 76, 79, 78, 90, 73,
+  99, 92, 83, 86, 86, 82, 65, 83, 92, 85,
+  86, 81, 91, 83, 79, 71, 79, 83, 103, 92,
+  91, 85, 85, 87, 75, 88, 98, 79, 82, 76,
+  80, 82, 77, 86, 81, 89, 76, 80, 92, 71,
+  83, 77, 87, 79, 74, 78, 73, 76, 84, 78,
+  81, 82, 83, 82, 77, 76, 81, 77, 88, 92,
+  81, 84, 85, 90, 78, 80, 83, 83, 94, 86,
+  89, 68, 92, 102, 71, 90, 96, 79, 69, 78,
+  87, 79, 86, 84, 81, 82, 95, 114, 71, 97,
+  79, 105, 88, 80, 89, 68, 80, 90, 83, 73,
+  77, 75, 79, 98, 80, 81, 89, 81, 75, 81,
+  74, 98, 74, 71, 77, 95, 97, 73, 66, 93,
+  87, 81, 83, 83, 86, 81, 92, 79, 92, 93,
+  84, 85, 84, 77, 66, 85, 84, 84, 84, 80,
+  86, 89, 80, 73, 90, 82, 99, 89, 88, 83,
+  86, 86, 76, 91, 98, 83, 77, 88, 81, 82,
+  85, 83, 81, 83, 77, 83, 93, 76, 83, 90,
+  86, 77, 74, 87, 70, 76, 88, 74, 84, 76,
+  88, 78, 77, 73, 85, 80, 107, 91, 80, 79,
+  79, 96, 84, 74, 82, 82, 89, 86, 89, 73,
+  89, 92, 71, 87, 97, 89, 70, 81, 88, 88,
+  86, 87, 86, 84, 89, 113, 79, 92, 76, 101,
+  85, 85, 95, 72, 80, 88, 84, 76, 79, 78,
+  79, 92, 79, 81, 92, 86, 69, 82, 87, 95,
+  73, 73, 80, 90, 97, 81, 57, 91, 89, 80,
+  73, 104, 73, 88, 71, 84, 87, 87, 84, 86,
+  74, 76, 79, 71, 87, 74, 79, 83, 88, 86,
+  97, 82, 91, 92, 103, 79, 88, 85, 98, 112,
+  74, 85, 83, 79, 78, 84, 89, 88, 148, 90,
+  84, 93, 67, 91, 86, 83, 87, 76, 84, 76,
+  86, 76, 90, 77, 75, 114, 76, 78, 83, 86,
+  85, 75, 96, 83, 66, 76, 84, 83, 76, 83,
+  81, 103, 78, 83, 91, 75, 86, 89, 79, 78,
+  83, 81, 85, 99, 78, 94, 84, 98, 84, 90,
+  87, 70, 73, 79, 80, 80, 90, 78, 73, 89,
+  80, 71, 96, 94, 87, 85, 85, 88, 88, 77,
+  80, 79, 76, 84, 79, 99, 77, 85, 85, 91,
+  81, 87, 84, 74, 80, 91, 89, 88, 66, 89,
+  63, 79, 90, 74, 74, 86, 82, 83, 77, 75,
+  71, 63, 75, 72, 87, 70, 76, 76, 92, 77,
+  84, 89, 101, 69, 81, 81, 120, 106, 78, 79,
+  81, 74, 68, 100, 84, 78, 156, 89, 87, 78,
+  79, 92, 98, 93, 83, 79, 86, 73, 82, 78,
+  84, 77, 67, 104, 76, 80, 94, 81, 84, 82,
+  90, 100, 50, 79, 79, 82, 81, 83, 116, 92,
+  86, 92, 86, 80, 77, 83, 88, 75, 77, 74,
+  85, 80, 85, 97, 82, 110, 73, 81, 75, 88,
+  81, 81, 82, 73, 87, 80, 78, 95, 83, 82,
+  90, 95, 88, 77, 71, 87, 82, 73, 77, 81,
+  70, 77, 72, 92, 72, 85, 76, 87, 88, 95,
+  81, 72, 77, 83, 84, 91, 68, 87, 79, 96,
+  68, 78, 87, 95, 87, 89, 75, 75, 77, 68,
+  86, 91, 83, 93, 84, 82, 90, 74, 92, 88,
+  97, 78, 83, 90, 61, 84, 82, 84, 89, 70,
+  77, 94, 57, 85, 93, 87, 96, 72, 77, 90,
+  85, 93, 90, 77, 71, 89, 84, 90, 83, 78,
+  91, 74, 81, 96, 90, 87, 83, 71, 83, 68,
+  91, 65, 85, 86, 78, 98, 70, 79, 109, 88,
+  83, 75, 77, 77, 81, 73, 102, 76, 76, 89,
+  77, 96, 88, 67, 77, 82, 81, 87, 84, 78,
+  82, 74, 89, 79, 70, 80, 85, 83, 76, 96,
+  83, 89, 85, 87, 78, 73, 71, 93, 81, 92,
+  79, 78, 87, 84, 81, 81, 88, 83, 100, 92,
+  96, 82, 83, 78, 84, 102, 76, 95, 54, 88,
+  95, 89, 95, 81, 78, 77, 87, 70, 93, 81,
+  85, 89, 86, 92, 100, 88, 106, 97, 100, 83,
+  89, 87, 90, 93, 76, 86, 81, 78, 89, 78,
+  80, 80, 98, 84, 82, 78, 68, 84, 78, 91,
+  85, 80, 75, 85, 79, 86, 88, 73, 95, 95,
+  77, 89, 85, 90, 81, 72, 89, 73, 81, 72,
+  82, 78, 79, 83, 85, 78, 84, 87, 92, 75,
+  84, 90, 77, 78, 96, 72, 81, 98, 75, 89,
+  76, 78, 87, 94, 91, 77, 80, 81, 87, 78,
+  82, 70, 75, 86, 82, 67, 80, 88, 80, 87,
+  88, 85, 83, 89, 73, 80, 89, 90, 71, 73,
+  80, 81, 83, 82, 80, 76, 94, 92, 81, 87,
+  77, 78, 76, 105, 61, 83, 75, 78, 78, 77,
+  88, 82, 78, 75, 71, 58, 79, 68, 87, 70,
+  75, 80, 91, 76, 91, 89, 100, 74, 84, 83,
+  119, 97, 76, 84, 77, 73, 73, 92, 84, 79,
+  149, 83, 86, 73, 75, 83, 87, 92, 85, 71,
+  85, 74, 81, 81, 87, 78, 76, 99, 67, 79,
+  83, 83, 85, 85, 91, 93, 57, 73, 74, 72,
+  85, 67, 108, 88, 78, 89, 86, 75, 85, 87,
+  90, 75, 74, 74, 82, 90, 78, 93, 75, 105,
+  73, 84, 78, 79, 84, 80, 83, 79, 87, 81,
+  74, 83, 75, 75, 90, 91, 79, 72, 69, 75,
+  74, 75, 77, 78, 71, 80, 65, 82, 61, 86,
+  76, 84, 87, 85, 84, 67, 69, 83, 80, 80,
+  78, 87, 57, 83, 80, 75, 77, 82, 80, 82,
+  76, 76, 75, 67, 74, 75, 89, 83, 84, 79,
+  91, 74, 86, 85, 97, 77, 84, 81, 104, 88,
+  90, 93, 82, 70, 75, 105, 90, 82, 135, 87,
+  98, 79, 84, 83, 92, 93, 90, 75, 91, 80,
+  72, 83, 85, 78, 81, 75, 72, 82, 85, 84,
+  91, 93, 93, 96, 62, 72, 72, 93, 92, 84,
+  92, 90, 93, 92, 86, 80, 76, 81, 96, 76,
+  82, 80, 80, 79, 85, 89, 78, 98, 63, 72,
+  79, 92, 86, 78, 88, 73, 87, 87, 78, 80,
+  78, 79, 82, 95, 86, 73, 70, 77, 79, 67,
+  81, 94, 74, 83, 71, 94, 72, 90, 77, 89,
+  93, 93, 85, 71, 78, 86, 86, 81, 98, 96,
+  84, 81, 59, 89, 95, 83, 80, 85, 78, 86,
+  93, 82, 83, 83, 85, 85, 88, 102, 99, 89,
+  106, 88, 96, 89, 82, 88, 80, 94, 86, 86,
+  83, 83, 89, 85, 96, 88, 109, 88, 91, 83,
+  73, 91, 83, 87, 80, 82, 75, 87, 86, 88,
+  79, 77, 103, 101, 86, 103, 93, 88, 83, 79,
+  95, 81, 87, 92, 78, 85, 73, 92, 102, 95,
+  80, 80, 86, 82, 80, 89, 75, 82, 100, 78,
+  76, 90, 92, 90, 74, 85, 85, 82, 81, 75,
+  82, 73, 85, 87, 78, 75, 75, 90, 77, 79,
+  83, 94, 87, 94, 85, 92, 86, 92, 79, 82,
+  88, 84, 75, 91, 87, 89, 92, 93, 80, 89,
+  87, 92, 91, 91, 83, 78, 86, 106, 83, 91,
+  59, 96, 90, 81, 88, 84, 81, 81, 74, 81,
+  85, 83, 89, 88, 83, 95, 93, 71, 103, 95,
+  91, 80, 89, 84, 85, 85, 85, 87, 87, 75,
+  83, 88, 87, 82, 91, 76, 85, 79, 76, 77,
+  81, 94, 84, 77, 80, 90, 93, 80, 85, 76,
+  89, 75, 75, 95, 79, 90, 87, 83, 93, 79,
+  88, 67, 81, 80, 80, 84, 87, 96, 85, 83,
+  86, 81, 86, 92, 84, 77, 90, 78, 83, 97,
+  78, 91, 82, 83, 89, 90, 90, 76, 82, 80,
+  89, 79, 87, 81, 74, 79, 80, 82, 83, 95,
+  87, 87, 86, 73, 80, 82, 79, 85, 81, 89,
+  74, 87, 80, 88, 79, 84, 90, 83, 91, 78,
+  80, 93, 75, 77, 79, 90, 68, 92, 74, 86,
+  82, 74, 80, 85, 83, 75, 86, 79, 73, 71,
+  89, 79, 84, 90, 85, 65, 98, 93, 93, 76,
+  92, 84, 86, 85, 98, 85, 81, 78, 70, 99,
+  89, 90, 120, 86, 92, 84, 76, 73, 77, 88,
+  96, 83, 93, 77, 81, 79, 83, 78, 73, 63,
+  74, 85, 80, 97, 93, 91, 92, 100, 79, 63,
+  80, 87, 95, 86, 93, 107, 80, 86, 87, 79,
+  79, 86, 87, 76, 80, 78, 85, 92, 94, 90,
+  80, 95, 78, 86, 82, 85, 86, 86, 83, 75,
+  90, 86, 77, 82, 72, 69, 86, 96, 87, 81,
+  71, 74, 81, 62, 83, 86, 77, 85, 78, 98,
+  84, 90, 85, 82, 99, 94, 81, 67, 75, 97,
+  79, 82, 107, 92, 78, 92, 85, 88, 78, 84,
+  75, 79, 68, 81, 86, 97, 97, 90, 90, 86,
+  76, 69, 76, 83, 101, 83, 87, 78, 88, 90,
+  90, 88, 83, 80, 75, 108, 89, 83, 85, 88,
+  83, 80, 85, 76, 98, 79, 80, 75, 88, 88,
+  85, 82, 89, 77, 78, 82, 83, 87, 76, 88,
+  82, 81, 81, 85, 83, 82, 87, 88, 84, 78,
+  102, 80, 95, 91, 84, 79, 83, 80, 79, 82,
+  86, 78, 86, 89, 82, 76, 73, 80, 83, 86,
+  89, 72, 65, 85, 82, 99, 80, 74, 90, 84,
+  91, 76, 76, 85, 81, 102, 77, 79, 78, 88,
+  82, 75, 73, 92, 78, 86, 71, 77, 82, 86,
+  86, 88, 74, 75, 94, 83, 88, 88, 87, 73,
+  131, 94, 88, 90, 99, 94, 76, 75, 67, 75,
+  72, 79, 93, 83, 97, 82, 86, 85, 73, 70,
+  81, 85, 88, 84, 110, 79, 94, 82, 91, 85,
+  94, 89, 80, 88, 90, 83, 78, 92, 95, 81,
+  84, 82, 82, 91, 96, 84, 87, 80, 78, 75,
+  83, 79, 78, 85, 86, 79, 66, 85, 82, 78,
+  83, 72, 87, 82, 74, 86, 100, 77, 89, 74,
+  79, 99, 77, 76, 85, 74, 69, 97, 69, 80,
+  84, 92, 95, 71, 75, 88, 79, 91, 83, 76,
+  52, 73, 74, 115, 71, 75, 86, 94, 88, 77,
+  69, 86, 78, 103, 82, 72, 72, 90, 104, 76,
+  85, 93, 77, 80, 78, 87, 84, 96, 90, 81,
+  79, 68, 104, 75, 91, 92, 88, 74, 88, 73,
+  98, 86, 80, 99, 78, 88, 90, 88, 70, 93,
+  69, 84, 92, 89, 90, 79, 75, 83, 95, 78,
+  82, 83, 91, 75, 88, 89, 87, 91, 81, 78,
+  77, 82, 87, 98, 81, 89, 81, 84, 82, 76,
+  73, 89, 78, 78, 83, 79, 92, 80, 88, 82,
+  78, 74, 82, 86, 86, 88, 91, 82, 76, 90,
+  80, 72, 91, 86, 86, 81, 92, 71, 79, 78,
+  86, 75, 82, 85, 85, 89, 72, 73, 83, 95,
+  80, 73, 80, 91, 85, 82, 90, 76, 75, 87,
+  86, 88, 89, 78, 84, 81, 89, 83, 83, 65,
+  82, 98, 81, 79, 83, 85, 80, 85, 87, 81,
+  84, 86, 80, 82, 99, 76, 81, 89, 89, 84,
+  95, 93, 80, 87, 87, 77, 119, 84, 84, 69,
+  97, 74, 72, 87, 69, 81, 73, 78, 75, 108,
+  81, 76, 81, 79, 77, 83, 75, 78, 91, 87,
+  78, 80, 87, 88, 105, 94, 93, 84, 76, 127,
+  91, 83, 112, 84, 72, 74, 84, 76, 99, 86,
+  63, 68, 73, 86, 91, 78, 85, 76, 83, 81,
+  64, 87, 87, 82, 84, 80, 88, 81, 81, 80,
+  90, 81, 80, 90, 99, 67, 107, 83, 79, 75,
+  75, 77, 82, 75, 113, 73, 84, 73, 77, 83,
+  104, 80, 90, 95, 78, 72, 73, 84, 79, 89,
+  91, 74, 75, 78, 81, 83, 81, 100, 94, 99,
+  78, 91, 76, 90, 68, 88, 71, 105, 71, 87,
+  89, 71, 65, 93, 84, 99, 69, 67, 82, 71,
+  83, 90, 78, 70, 148, 82, 97, 82, 119, 78,
+  67, 81, 58, 81, 74, 70, 89, 84, 90, 74,
+  85, 80, 84, 92, 80, 88, 70, 82, 112, 77,
+  84, 75, 103, 105, 101, 92, 81, 125, 85, 93,
+  95, 98, 118, 71, 86, 69, 73, 99, 69, 61,
+  76, 68, 83, 73, 80, 76, 82, 85, 56, 88,
+  75, 86, 75, 93, 101, 72, 80, 84, 69, 81,
+  92, 96, 108, 70, 74, 88, 76, 74, 72, 73,
+  80, 90, 84, 74, 82, 67, 91, 78, 125, 101,
+  79, 106, 72, 68, 67, 75, 63, 110, 76, 80,
+  71, 83, 82, 69, 67, 73, 97, 98, 71, 104,
+  76, 91, 76, 81, 76, 117, 68, 83, 100, 80,
+  84, 100, 84, 86, 68, 61, 81, 64, 86, 99,
+  76, 60, 94, 72, 82, 70, 79, 102, 74, 87,
+  89, 85, 79, 86, 71, 77, 75, 74, 82, 75,
+  77, 86, 97, 82, 73, 87, 87, 73, 87, 87,
+  96, 102, 80, 83, 72, 86, 81, 99, 97, 81,
+  98, 75, 82, 81, 66, 83, 68, 71, 71, 71,
+  86, 89, 89, 82, 84, 74, 75, 88, 92, 81,
+  96, 75, 85, 78, 77, 63, 82, 82, 87, 87,
+  89, 82, 68, 82, 86, 79, 70, 83, 93, 96,
+  79, 75, 78, 80, 75, 76, 87, 87, 83, 94,
+  84, 77, 76, 83, 84, 82, 85, 73, 75, 74,
+  89, 85, 87, 59, 90, 96, 90, 87, 83, 82,
+  71, 98, 78, 87, 84, 87, 89, 92, 102, 76,
+  86, 103, 99, 78, 82, 87, 81, 87, 81, 87,
+  84, 84, 82, 54, 77, 82, 81, 84, 84, 87,
+  80, 90, 78, 94, 73, 71, 68, 78, 82, 73,
+  88, 91, 74, 95, 70, 80, 93, 89, 92, 81,
+  82, 85, 98, 99, 99, 79, 105, 76, 73, 78,
+  83, 67, 94, 78, 64, 90, 71, 61, 86, 108,
+  81, 89, 87, 82, 80, 81, 89, 74, 90, 71,
+  84, 85, 71, 78, 85, 83, 74, 79, 85, 81,
+  92, 68, 93, 80, 73, 93, 88, 85, 116, 68,
+  79, 84, 86, 85, 84, 76, 87, 89, 90, 103,
+  93, 75, 81, 67, 93, 77, 89, 71, 70, 101,
+  90, 81, 85, 93, 91, 67, 80, 95, 100, 102,
+  80, 95, 92, 79, 80, 82, 72, 74, 89, 105,
+  77, 85, 83, 86, 86, 89, 73, 107, 89, 76,
+  79, 60, 79, 74, 76, 84, 75, 84, 78, 86,
+  66, 87, 78, 69, 68, 78, 75, 83, 87, 96,
+  80, 90, 72, 75, 94, 77, 89, 109, 76, 78,
+  85, 102, 91, 80, 107, 71, 92, 72, 90, 62,
+  79, 80, 61, 83, 70, 67, 79, 106, 78, 86,
+  85, 78, 71, 80, 92, 70, 93, 77, 89, 87,
+  79, 83, 83, 81, 74, 87, 79, 94, 81, 68,
+  95, 79, 71, 91, 93, 72, 106, 61, 79, 80,
+  80, 82, 86, 91, 84, 92, 86, 88, 83, 76,
+  84, 67, 94, 71, 84, 71, 74, 87, 85, 76,
+  88, 93, 95, 77, 84, 90, 78, 103, 76, 100,
+  95, 85, 92, 83, 86, 72, 82, 109, 98, 85,
+  74, 84, 77, 98, 74, 105, 83, 84, 77, 63,
+  77, 77, 85, 79, 98, 82, 82, 93, 86, 84,
+  72, 75, 67, 79, 81, 72, 92, 86, 83, 101,
+  75, 82, 88, 92, 84, 111, 80, 85, 98, 89,
+  77, 85, 102, 79, 94, 84, 75, 72, 86, 87,
+  70, 94, 75, 83, 82, 103, 80, 95, 88, 82,
+  86, 86, 89, 75, 88, 80, 82, 79, 68, 68,
+  85, 83, 79, 74, 79, 89, 76, 76, 89, 81,
+  72, 83, 90, 74, 76, 72, 79, 92, 85, 75,
+  88, 85, 75, 86, 98, 91, 90, 78, 76, 76,
+  78, 81, 87, 73, 96, 107, 82, 72, 85, 92,
+  98, 69, 84, 88, 97, 99, 89, 81, 96, 78,
+  75, 79, 84, 67, 93, 93, 118, 84, 91, 93,
+  87, 85, 79, 108, 89, 84, 79, 78, 90, 75,
+  73, 82, 86, 79, 78, 91, 80, 85, 73, 83,
+  75, 84, 76, 99, 84, 73, 100, 87, 77, 89,
+  68, 82, 88, 69, 74, 68, 75, 82, 89, 96,
+  82, 76, 77, 102, 84, 91, 81, 93, 93, 80,
+  84, 87, 79, 81, 80, 98, 87, 67, 88, 74,
+  82, 84, 97, 80, 82, 90, 94, 67, 74, 71,
+  75, 81, 102, 77, 78, 84, 87, 67, 91, 86,
+  79, 95, 88, 96, 95, 93, 87, 78, 84, 86,
+  80, 81, 104, 79, 94, 81, 70, 80, 88, 86,
+  82, 81, 95, 90, 76, 77, 67, 82, 79, 104,
+  76, 78, 84, 76, 78, 80, 76, 92, 76, 83,
+  82, 74, 73, 84, 87, 71, 92, 84, 96, 89,
+  80, 85, 94, 78, 80, 90, 82, 77, 63, 77,
+  94, 85, 73, 77, 82, 92, 103, 69, 87, 92,
+  96, 90, 89, 83, 131, 71, 72, 77, 83, 94,
+  87, 82, 100, 91, 63, 78, 98, 85, 90, 84,
+  82, 70, 64, 91, 77, 67, 84, 76, 81, 83,
+  93, 92, 73, 80, 77, 72, 79, 72, 67, 67,
+  89, 100, 104, 103, 85, 90, 64, 68, 85, 89,
+  91, 90, 72, 100, 67, 89, 80, 79, 187, 105,
+  86, 73, 78, 82, 67, 78, 77, 89, 77, 94,
+  65, 79, 79, 108, 84, 96, 79, 95, 113, 60,
+  86, 56, 81, 109, 93, 84, 107, 68, 97, 69,
+  89, 88, 92, 99, 79, 80, 76, 87, 77, 99,
+  100, 87, 85, 142, 84, 77, 68, 91, 82, 67,
+  93, 87, 87, 85, 80, 115, 67, 70, 85, 75,
+  73, 82, 89, 80, 87, 76, 88, 90, 98, 92,
+  77, 80, 80, 79, 91, 77, 78, 88, 86, 105,
+  92, 105, 67, 79, 80, 83, 89, 81, 84, 78,
+  74, 85, 88, 70, 86, 83, 89, 88, 90, 87,
+  75, 86, 80, 72, 85, 70, 63, 71, 81, 91,
+  103, 94, 86, 89, 67, 60, 67, 83, 86, 83,
+  77, 93, 67, 83, 81, 85, 139, 82, 86, 78,
+  82, 87, 78, 83, 79, 90, 81, 89, 74, 79,
+  91, 112, 83, 90, 87, 91, 107, 66, 81, 71,
+  82, 111, 83, 80, 94, 75, 87, 74, 84, 84,
+  90, 91, 78, 83, 80, 78, 73, 91, 93, 81,
+  79, 114, 89, 79, 80, 92, 83, 65, 88, 87,
+  83, 73, 89, 76, 84, 84, 81, 82, 83, 81,
+  84, 84, 76, 86, 74, 85, 78, 90, 78, 80,
+  77, 93, 83, 94, 72, 81, 85, 71, 79, 72,
+  81, 87, 94, 92, 74, 82, 75, 105, 85, 90,
+  94, 96, 84, 84, 81, 88, 81, 82, 84, 107,
+  86, 72, 84, 69, 83, 87, 96, 80, 76, 85,
+  90, 69, 78, 78, 74, 74, 92, 78, 80, 70,
+  91, 80, 91, 85, 73, 93, 84, 94, 93, 91,
+  95, 76, 84, 80, 83, 80, 104, 87, 100, 79,
+  71, 83, 89, 85, 80, 90, 88, 97, 76, 85,
+  71, 84, 75, 91, 75, 83, 90, 79, 83, 87,
+  83, 90, 72, 82, 78, 79, 81, 81, 74, 72,
+  91, 85, 93, 77, 80, 88, 89, 74, 79, 87,
+  83, 73, 73, 89, 84, 89, 71, 71, 69, 81,
+  97, 74, 76, 78, 82, 95, 81, 81, 97, 81,
+  79, 86, 92, 88, 88, 91, 77, 91, 80, 90,
+  122, 98, 88, 100, 76, 76, 68, 81, 78, 72,
+  61, 89, 86, 77, 101, 96, 73, 86, 81, 70,
+  72, 70, 75, 74, 87, 97, 84, 100, 81, 82,
+  69, 73, 66, 90, 104, 79, 84, 94, 97, 83,
+  88, 91, 132, 106, 105, 73, 78, 79, 81, 81,
+  84, 88, 88, 95, 67, 79, 86, 81, 82, 88,
+  95, 80, 85, 70, 87, 74, 77, 89, 90, 87,
+  87, 98, 83, 76, 80, 76, 72, 99, 78, 84,
+  74, 83, 73, 90, 83, 102, 72, 105, 75, 77,
+  71, 78, 73, 74, 86, 83, 92, 82, 76, 95,
+  73, 81, 81, 80, 74, 72, 73, 75, 89, 76,
+  76, 80, 86, 98, 88, 80, 85, 83, 83, 87,
+  85, 88, 89, 127, 74, 102, 80, 83, 83, 89,
+  83, 95, 85, 82, 75, 80, 80, 72, 71, 84,
+  81, 87, 100, 92, 75, 82, 80, 71, 78, 75,
+  69, 78, 77, 95, 80, 96, 88, 88, 78, 69,
+  65, 89, 97, 88, 69, 94, 92, 85, 84, 96,
+  122, 80, 88, 80, 79, 84, 83, 93, 84, 101,
+  83, 91, 69, 75, 95, 79, 81, 83, 88, 80,
+  91, 76, 82, 81, 81, 89, 84, 84, 82, 99,
+  83, 78, 77, 72, 74, 95, 76, 77, 78, 83,
+  90, 85, 84, 97, 83, 95, 78, 79, 79, 84,
+  75, 71, 85, 86, 82, 78, 84, 93, 86, 75,
+  81, 84, 82, 78, 90, 85, 81, 84, 74, 81,
+  87, 85, 81, 88, 69, 84, 97, 81, 82, 83,
+  79, 80, 78, 79, 83, 83, 76, 80, 81, 84,
+  83, 89, 85, 88, 90, 100, 96, 86, 79, 86,
+  82, 76, 83, 100, 81, 79, 80, 80, 85, 92,
+  88, 84, 85, 82, 87, 84, 87, 90, 85, 80,
+  82, 84, 81, 62, 80, 79, 86, 77, 80, 85,
+  83, 93, 88, 92, 93, 83, 90, 81, 77, 78,
+  90, 85, 95, 80, 72, 87, 84, 82, 95, 97,
+  83, 100, 84, 90, 78, 85, 82, 82, 75, 88,
+  89, 73, 94, 86, 84, 79, 85, 87, 87, 83,
+  90, 75, 81, 78, 79, 82, 88, 81, 88, 89,
+  89, 81, 75, 77, 87, 76, 90, 75, 79, 85,
+  75, 71, 82, 84, 80, 85, 67, 81, 84, 83,
+  84, 84, 73, 91, 89, 92, 84, 84, 81, 75,
+  77, 83, 93, 80, 72, 81, 79, 72, 87, 94,
+  81, 86, 89, 92, 93, 93, 80, 84, 85, 84,
+  82, 100, 84, 72, 84, 80, 90, 93, 90, 78,
+  80, 83, 87, 79, 77, 90, 82, 78, 75, 93,
+  76, 60, 90, 90, 82, 89, 76, 79, 88, 83,
+  91, 92, 93, 77, 89, 77, 81, 81, 83, 90,
+  101, 82, 78, 79, 81, 82, 84, 94, 82, 103,
+  77, 87, 74, 84, 75, 84, 73, 88, 86, 72,
+  80, 91, 82, 78, 81, 82, 74, 80, 82, 79,
+  85, 73, 83, 80, 96, 90, 77, 85, 93, 89,
+  75, 78, 83, 64, 87, 74, 83, 83, 76, 71,
+  80, 82, 74, 86, 65, 82, 85, 87, 87, 85,
+  92, 89, 79, 94, 81, 88, 83, 71, 75, 88,
+  91, 79, 78, 78, 78, 78, 86, 94, 80, 86,
+  89, 90, 100, 89, 77, 91, 82, 81, 79, 95,
+  82, 76, 86, 76, 84, 93, 84, 78, 82, 81,
+  87, 84, 83, 89, 77, 77, 79, 91, 74, 61,
+  90, 87, 82, 90, 81, 82, 82, 87, 89, 92,
+  93, 73, 88, 76, 74, 77, 79, 90, 102, 84,
+  74, 81, 83, 83, 90, 91, 82, 103, 78, 85,
+  77, 84, 77, 84, 77, 86, 90, 66, 81, 88,
+  82, 78, 82, 80, 79, 79, 81, 82, 87, 72,
+  84, 83, 94, 88, 81, 85, 94, 68, 98, 66,
+  82, 81, 78, 73, 82, 83, 70, 84, 86, 80,
+  68, 79, 78, 82, 71, 81, 78, 75, 102, 82,
+  83, 92, 80, 63, 97, 102, 81, 69, 74, 91,
+  96, 77, 79, 84, 91, 84, 82, 77, 89, 72,
+  91, 88, 93, 79, 87, 73, 85, 84, 77, 78,
+  77, 81, 86, 84, 86, 95, 70, 79, 79, 80,
+  100, 90, 88, 96, 82, 99, 73, 102, 96, 97,
+  82, 86, 77, 77, 76, 73, 84, 79, 84, 111,
+  72, 71, 93, 86, 87, 79, 87, 82, 67, 82,
+  84, 74, 85, 94, 90, 88, 91, 93, 72, 98,
+  95, 85, 77, 99, 93, 71, 71, 71, 65, 96,
+  100, 99, 109, 67, 73, 80, 72, 71, 91, 71,
+  88, 107, 81, 80, 97, 79, 85, 67, 85, 71,
+  77, 74, 86, 73, 59, 86, 92, 78, 77, 77,
+  85, 82, 60, 98, 86, 74, 82, 82, 84, 87,
+  91, 51, 101, 106, 75, 77, 75, 81, 103, 69,
+  87, 79, 83, 88, 86, 82, 84, 70, 88, 75,
+  84, 71, 106, 67, 85, 85, 75, 79, 75, 84,
+  88, 81, 91, 86, 62, 75, 81, 85, 88, 88,
+  87, 86, 81, 106, 86, 117, 103, 94, 95, 75,
+  74, 84, 85, 81, 81, 77, 70, 85, 72, 71,
+  83, 92, 91, 85, 98, 93, 64, 84, 86, 80,
+  89, 93, 88, 83, 91, 89, 71, 104, 104, 82,
+  75, 108, 96, 71, 79, 68, 72, 88, 90, 79,
+  75, 62, 63, 81, 69, 71, 82, 83, 84, 104,
+  68, 74, 92, 83, 80, 61, 81, 89, 80, 75,
+  92, 86, 67, 87, 87, 84, 76, 78, 78, 81,
+  80, 105, 90, 74, 73, 80, 83, 93, 92, 66,
+  92, 79, 85, 83, 73, 68, 94, 79, 88, 86,
+  83, 86, 85, 76, 75, 69, 94, 87, 91, 87,
+  84, 74, 84, 86, 78, 81, 79, 85, 86, 89,
+  83, 89, 72, 86, 79, 81, 99, 89, 86, 89,
+  79, 85, 95, 104, 123, 89, 97, 86, 79, 95,
+  86, 77, 83, 83, 79, 81, 75, 73, 92, 87,
+  84, 82, 87, 95, 72, 82, 75, 79, 83, 97,
+  96, 86, 88, 100, 74, 100, 86, 86, 78, 93,
+  92, 74, 81, 73, 67, 102, 85, 95, 82, 74,
+  81, 75, 78, 76, 92, 78, 88, 99, 86, 80,
+  82, 75, 82, 88, 89, 90, 87, 66, 81, 70,
+  71, 78, 87, 81, 78, 86, 73, 88, 69, 85,
+  88, 77, 92, 82, 81, 93, 66, 50, 107, 101,
+  98, 76, 73, 109, 96, 78, 79, 96, 82, 84,
+  84, 87, 97, 81, 97, 85, 93, 95, 93, 75,
+  81, 87, 76, 73, 76, 85, 86, 90, 85, 107,
+  87, 78, 82, 92, 98, 90, 85, 93, 93, 89,
+  91, 78, 75, 91, 76, 74, 77, 71, 78, 73,
+  81, 72, 78, 85, 74, 78, 91, 82, 86, 70,
+  96, 76, 63, 82, 99, 78, 96, 94, 81, 90,
+  77, 97, 81, 100, 99, 76, 80, 111, 81, 57,
+  76, 81, 71, 93, 82, 82, 103, 63, 64, 91,
+  79, 64, 80, 66, 85, 95, 70, 78, 79, 97,
+  82, 92, 94, 71, 92, 66, 86, 54, 49, 80,
+  95, 75, 95, 86, 81, 87, 56, 90, 90, 78,
+  74, 83, 76, 102, 68, 40, 112, 89, 109, 91,
+  79, 91, 92, 67, 83, 110, 88, 93, 76, 102,
+  101, 83, 100, 66, 90, 76, 114, 66, 84, 81,
+  86, 76, 69, 83, 86, 84, 89, 100, 73, 68,
+  79, 102, 73, 92, 102, 98, 90, 83, 73, 91,
+  73, 95, 83, 60, 77, 76, 70, 83, 79, 76,
+  73, 60, 74, 89, 77, 85, 92, 76, 121, 63,
+  54, 82, 86, 85, 100, 89, 84, 87, 63, 76,
+  88, 106, 111, 73, 78, 121, 86, 60, 89, 81,
+  79, 76, 72, 68, 69, 58, 54, 91, 71, 67,
+  68, 75, 70, 91, 67, 78, 86, 89, 92, 74,
+  82, 95, 87, 69, 84, 69, 66, 78, 81, 81,
+  83, 85, 75, 85, 77, 115, 83, 82, 77, 75,
+  74, 88, 77, 51, 93, 73, 95, 85, 69, 74,
+  98, 79, 88, 87, 83, 84, 83, 82, 88, 75,
+  92, 75, 93, 86, 85, 74, 80, 83, 73, 73,
+  77, 79, 89, 95, 84, 96, 82, 82, 82, 83,
+  100, 85, 82, 88, 85, 93, 94, 81, 103, 86,
+  88, 70, 80, 101, 81, 75, 82, 73, 76, 74,
+  78, 89, 89, 93, 85, 74, 89, 79, 65, 78,
+  88, 69, 95, 98, 85, 85, 80, 86, 80, 102,
+  88, 79, 81, 104, 84, 62, 88, 85, 71, 93,
+  79, 83, 98, 69, 67, 90, 78, 68, 78, 72,
+  81, 96, 71, 81, 74, 78, 74, 83, 75, 93,
+  76, 74, 78, 78, 83, 90, 86, 75, 70, 78,
+  74, 82, 87, 86, 94, 75, 93, 83, 76, 93,
+  90, 65, 87, 84, 94, 79, 79, 110, 93, 85,
+  90, 98, 80, 96, 83, 77, 89, 73, 90, 94,
+  95, 89, 83, 82, 83, 90, 78, 76, 78, 92,
+  92, 84, 84, 100, 96, 76, 88, 77, 96, 86,
+  79, 83, 91, 94, 102, 79, 77, 83, 76, 88,
+  86, 77, 92, 68, 78, 77, 82, 100, 73, 87,
+  105, 72, 97, 78, 84, 83, 72, 80, 104, 76,
+  90, 83, 81, 102, 96, 103, 78, 104, 94, 76,
+  87, 93, 74, 69, 79, 84, 78, 86, 77, 87,
+  81, 72, 79, 91, 91, 68, 79, 60, 97, 80,
+  78, 85, 75, 81, 87, 97, 84, 79, 72, 69,
+  81, 60, 71, 88, 92, 79, 82, 88, 83, 86,
+  78, 102, 88, 81, 83, 78, 72, 98, 86, 52,
+  84, 83, 100, 92, 78, 103, 84, 76, 86, 110,
+  80, 94, 91, 80, 102, 77, 89, 72, 90, 77,
+  94, 78, 81, 89, 81, 75, 78, 84, 86, 77,
+  93, 99, 92, 67, 91, 83, 82, 86, 91, 94,
+  89, 102, 78, 85, 72, 89, 77, 83, 83, 78,
+  84, 69, 75, 75, 76, 76, 76, 108, 92, 79,
+  94, 73, 86, 79, 72, 81, 104, 86, 93, 79,
+  81, 98, 84, 85, 74, 109, 89, 75, 86, 102,
+  61, 66, 82, 87, 73, 85, 80, 83, 76, 68,
+  67, 90, 85, 71, 70, 64, 88, 78, 73, 82,
+  75, 83, 92, 74, 78, 96, 79, 71, 82, 77,
+  79, 87, 89, 81, 76, 82, 78, 81, 85, 105,
+  81, 81, 84, 79, 73, 95, 91, 65, 75, 74,
+  94, 88, 78, 81, 88, 85, 87, 92, 80, 98,
+  86, 78, 93, 75, 88, 78, 91, 85, 82, 78,
+  82, 92, 75, 77, 76, 73, 91, 87, 85, 94,
+  87, 79, 86, 73, 94, 83, 87, 87, 85, 98,
+  77, 80, 96, 81, 85, 85, 84, 98, 91, 69,
+  80, 80, 80, 83, 78, 103, 84, 79, 96, 76,
+  83, 77, 73, 83, 93, 75, 90, 87, 85, 95,
+  92, 77, 81, 107, 89, 77, 87, 92, 78, 72,
+  86, 86, 77, 102, 88, 87, 113, 75, 82, 89,
+  98, 73, 80, 70, 97, 79, 81, 88, 75, 72,
+  81, 86, 82, 98, 64, 95, 91, 96, 67, 81,
+  57, 89, 67, 82, 80, 78, 80, 100, 71, 77,
+  97, 83, 78, 77, 101, 85, 101, 74, 82, 90,
+  78, 91, 109, 84, 92, 100, 77, 82, 82, 74,
+  39, 81, 77, 85, 95, 77, 96, 80, 77, 71,
+  76, 77, 93, 92, 103, 65, 91, 82, 75, 83,
+  84, 58, 65, 73, 71, 88, 85, 85, 108, 80,
+  99, 96, 86, 86, 71, 103, 80, 81, 84, 69,
+  86, 94, 77, 79, 85, 92, 73, 84, 99, 87,
+  75, 84, 120, 76, 77, 76, 76, 88, 81, 101,
+  91, 96, 90, 91, 100, 88, 73, 76, 80, 84,
+  83, 86, 81, 98, 70, 83, 91, 59, 77, 81,
+  84, 87, 94, 102, 80, 77, 87, 86, 69, 82,
+  84, 84, 78, 72, 94, 86, 72, 93, 117, 88,
+  79, 93, 77, 64, 87, 84, 60, 65, 86, 93,
+  96, 70, 105, 90, 107, 85, 100, 81, 61, 99,
+  83, 77, 79, 104, 93, 92, 88, 78, 110, 92,
+  81, 98, 80, 93, 78, 73, 79, 93, 83, 77,
+  81, 90, 64, 69, 79, 92, 92, 76, 81, 69,
+  58, 61, 69, 76, 84, 85, 105, 85, 72, 103,
+  73, 62, 78, 93, 89, 76, 88, 79, 98, 77,
+  78, 82, 93, 93, 77, 79, 67, 81, 79, 88,
+  79, 76, 87, 86, 110, 65, 82, 90, 87, 90,
+  92, 85, 88, 76, 81, 81, 80, 97, 70, 84,
+  85, 108, 69, 81, 82, 64, 86, 86, 76, 66,
+  83, 93, 82, 80, 81, 93, 61, 91, 84, 84,
+  93, 59, 87, 73, 81, 83, 89, 92, 92, 87,
+  75, 78, 81, 81, 81, 82, 86, 82, 93, 82,
+  91, 75, 70, 103, 100, 85, 81, 79, 92, 81,
+  92, 89, 81, 78, 86, 93, 98, 88, 90, 84,
+  76, 92, 66, 79, 85, 83, 92, 102, 83, 87,
+  73, 85, 86, 91, 84, 88, 74, 81, 78, 71,
+  94, 85, 62, 74, 70, 89, 82, 104, 76, 74,
+  82, 71, 83, 101, 92, 87, 93, 70, 94, 86,
+  85, 84, 88, 90, 68, 76, 80, 97, 72, 91,
+  92, 88, 105, 81, 78, 83, 92, 82, 86, 99,
+  62, 86, 82, 88, 80, 98, 83, 80, 101, 83,
+  75, 86, 76, 85, 94, 82, 82, 83, 80, 78,
+  96, 88, 65, 86, 76, 75, 91, 72, 67, 97,
+  90, 86, 77, 74, 59, 74, 64, 88, 84, 84,
+  83, 84, 89, 81, 77, 82, 84, 97, 68, 79,
+  88, 73, 88, 104, 86, 75, 68, 77, 80, 82,
+  79, 90, 69, 77, 16, 79, 92, 88, 99, 64,
+  105, 86, 88, 72, 84, 85, 80, 60, 118, 72,
+  92, 90, 79, 79, 93, 68, 52, 91, 78, 88,
+  89, 81, 60, 71, 95, 88, 91, 103, 77, 70,
+  81, 90, 86, 84, 82, 93, 86, 81, 73, 79,
+  83, 110, 118, 61, 71, 90, 113, 80, 74, 81,
+  69, 93, 82, 68, 85, 97, 94, 81, 90, 93,
+  82, 83, 80, 70, 99, 83, 75, 79, 79, 85,
+  91, 77, 82, 86, 82, 107, 98, 90, 82, 83,
+  75, 90, 77, 79, 73, 103, 59, 86, 82, 99,
+  67, 86, 67, 71, 69, 74, 76, 80, 74, 109,
+  68, 75, 78, 91, 76, 73, 108, 81, 124, 65,
+  73, 90, 65, 79, 94, 95, 77, 87, 80, 76,
+  79, 65, 79, 66, 82, 95, 73, 86, 85, 76,
+  77, 72, 87, 70, 104, 94, 95, 53, 80, 74,
+  91, 86, 80, 59, 55, 65, 50, 94, 74, 102,
+  142, 69, 86, 87, 84, 80, 72, 92, 79, 63,
+  78, 67, 82, 98, 60, 80, 91, 105, 49, 71,
+  98, 87, 68, 72, 127, 72, 84, 74, 71, 71,
+  84, 116, 89, 92, 90, 89, 106, 74, 72, 64,
+  77, 102, 80, 100, 70, 88, 60, 74, 73, 57,
+  77, 86, 67, 74, 83, 87, 69, 72, 78, 91,
+  64, 91, 87, 76, 80, 66, 90, 87, 80, 91,
+  118, 82, 81, 85, 75, 72, 83, 80, 81, 68,
+  86, 94, 91, 83, 106, 88, 88, 95, 103, 83,
+  66, 91, 79, 80, 84, 90, 87, 91, 84, 81,
+  113, 91, 81, 100, 66, 87, 77, 82, 86, 102,
+  96, 89, 82, 101, 66, 72, 84, 83, 83, 84,
+  70, 94, 71, 71, 84, 84, 72, 77, 69, 89,
+  79, 102, 71, 74, 76, 78, 80, 92, 91, 83,
+  100, 87, 83, 88, 90, 88, 78, 80, 67, 75,
+  86, 103, 66, 90, 92, 85, 99, 67, 81, 85,
+  82, 86, 86, 77, 65, 75, 73, 88, 87, 89,
+  73, 81, 86, 96, 83, 79, 75, 78, 90, 92,
+  83, 70, 85, 81, 87, 77, 79, 79, 88, 68,
+  99, 83, 98, 98, 85, 75, 73, 81, 74, 71,
+  81, 93, 77, 93, 67, 71, 91, 82, 84, 81,
+  91, 88, 63, 69, 71, 83, 81, 89, 100, 74,
+  67, 83, 78, 89, 99, 100, 70, 89, 70, 103,
+  91, 87, 95, 78, 108, 82, 94, 92, 75, 80,
+  67, 89, 103, 101, 89, 84, 72, 77, 92, 74,
+  74, 115, 85, 68, 91, 91, 79, 81, 84, 90,
+  83, 75, 87, 69, 88, 97, 103, 94, 81, 82,
+  99, 86, 78, 81, 104, 116, 73, 80, 79, 82,
+  98, 92, 72, 93, 77, 87, 94, 65, 70, 107,
+  88, 74, 87, 94, 87, 86, 91, 81, 79, 81,
+  82, 89, 88, 85, 101, 91, 71, 84, 76, 96,
+  81, 95, 77, 101, 75, 90, 104, 67, 71, 82,
+  73, 99, 87, 96, 76, 93, 55, 80, 67, 76,
+  77, 84, 81, 99, 73, 92, 84, 92, 89, 84,
+  86, 82, 88, 54, 79, 105, 81, 67, 75, 92,
+  77, 86, 66, 68, 80, 72, 65, 69, 82, 82,
+  84, 80, 88, 77, 103, 82, 97, 74, 94, 63,
+  119, 74, 98, 88, 95, 78, 94, 78, 68, 84,
+  66, 83, 77, 84, 92, 68, 96, 87, 91, 98,
+  72, 82, 73, 66, 89, 86, 81, 102, 81, 88,
+  78, 95, 79, 96, 107, 73, 75, 80, 119, 72,
+  80, 78, 57, 86, 90, 76, 86, 94, 93, 79,
+  110, 91, 78, 74, 80, 85, 83, 96, 82, 76,
+  81, 76, 92, 75, 74, 86, 77, 94, 82, 91,
+  82, 90, 80, 80, 77, 79, 87, 74, 78, 75,
+  82, 96, 78, 93, 123, 76, 63, 66, 70, 72,
+  86, 91, 85, 86, 83, 90, 86, 82, 97, 87,
+  80, 86, 93, 88, 72, 91, 88, 91, 92, 88,
+  90, 92, 87, 76, 101, 88, 79, 104, 65, 103,
+  83, 82, 89, 100, 96, 78, 89, 80, 79, 66,
+  92, 81, 94, 84, 83, 98, 69, 78, 70, 80,
+  80, 85, 104, 81, 89, 93, 73, 82, 77, 77,
+  80, 77, 91, 81, 93, 94, 80, 83, 88, 99,
+  72, 79, 89, 79, 86, 99, 83, 91, 88, 78,
+  73, 74, 82, 94, 84, 88, 80, 85, 80, 85,
+  71, 84, 87, 83, 70, 75, 84, 81, 91, 78,
+  82, 77, 90, 87, 83, 74, 85, 82, 84, 84,
+  70, 77, 81, 86, 62, 97, 86, 76, 91, 101,
+  80, 88, 89, 87, 73, 80, 77, 75, 87, 86,
+  78, 84, 85, 91, 87, 93, 83, 88, 98, 99,
+  76, 86, 73, 89, 75, 95, 94, 89, 81, 64,
+  97, 76, 84, 75, 75, 83, 81, 108, 75, 80,
+  73, 86, 94, 84, 92, 83, 90, 80, 79, 93,
+  89, 105, 85, 84, 94, 72, 76, 78, 77, 86,
+  86, 82, 82, 80, 84, 76, 91, 80, 88, 84,
+  86, 81, 92, 73, 73, 93, 81, 108, 84, 95,
+  79, 80, 77, 87, 104, 89, 80, 73, 100, 102,
+  93, 104, 89, 85, 85, 93, 90, 90, 83, 79,
+  74, 88, 77, 86, 77, 85, 73, 78, 83, 90,
+  79, 82, 103, 96, 71, 90, 83, 82, 69, 91,
+  72, 77, 48, 93, 91, 68, 82, 85, 80, 102,
+  112, 65, 81, 75, 80, 93, 80, 85, 89, 74,
+  91, 85, 91, 97, 80, 64, 102, 98, 88, 82,
+  90, 79, 98, 82, 88, 93, 71, 81, 85, 96,
+  90, 86, 66, 80, 71, 106, 55, 95, 69, 83,
+  99, 87, 80, 72, 79, 71, 81, 93, 90, 76,
+  72, 108, 85, 76, 96, 88, 59, 68, 79, 80,
+  76, 85, 87, 68, 88, 102, 74, 93, 92, 86,
+  101, 76, 87, 88, 82, 97, 82, 88, 53, 67,
+  75, 89, 75, 96, 81, 70, 74, 95, 76, 84,
+  76, 86, 73, 89, 87, 88, 74, 76, 93, 86,
+  69, 83, 82, 96, 73, 77, 89, 99, 83, 85,
+  89, 85, 65, 88, 87, 100, 73, 83, 93, 90,
+  65, 73, 85, 80, 91, 95, 73, 88, 84, 83,
+  69, 87, 81, 71, 82, 81, 80, 87, 95, 91,
+  93, 87, 90, 87, 90, 82, 83, 87, 76, 79,
+  90, 78, 87, 87, 81, 71, 87, 80, 73, 80,
+  74, 85, 92, 74, 85, 79, 69, 79, 85, 77,
+  85, 86, 76, 80, 80, 91, 88, 102, 93, 80,
+  86, 67, 86, 81, 83, 80, 78, 79, 74, 75,
+  90, 84, 95, 91, 84, 78, 82, 78, 103, 86,
+  75, 97, 79, 102, 85, 84, 74, 77, 80, 91,
+  113, 85, 75, 81, 78, 98, 90, 76, 91, 85,
+  85, 93, 87, 93, 83, 76, 89, 85, 80, 74,
+  84, 107, 98, 77, 90, 89, 77, 82, 90, 95,
+  69, 97, 80, 83, 89, 68, 87, 75, 63, 88,
+  82, 82, 86, 93, 77, 83, 80, 76, 69, 76,
+  76, 78, 83, 86, 83, 97, 95, 92, 79, 87,
+  83, 82, 100, 95, 74, 86, 74, 92, 69, 104,
+  84, 89, 82, 61, 100, 67, 80, 75, 87, 76,
+  74, 113, 78, 80, 75, 96, 79, 76, 93, 81,
+  89, 75, 79, 92, 80, 102, 80, 80, 83, 70,
+  84, 77, 73, 81, 85, 80, 91, 86, 86, 80,
+  86, 77, 78, 74, 79, 78, 80, 68, 73, 92,
+  83, 103, 78, 84, 73, 80, 77, 77, 101, 82,
+  83, 77, 84, 94, 90, 105, 90, 82, 94, 103,
+  92, 90, 74, 72, 80, 92, 75, 80, 79, 79,
+  81, 78, 72, 82, 88, 80, 100, 87, 70, 91,
+  70, 81, 91, 95, 81, 73, 47, 81, 96, 77,
+  81, 76, 78, 93, 138, 64, 87, 77, 86, 91,
+  78, 84, 91, 97, 73, 94, 82, 89, 78, 62,
+  101, 88, 97, 87, 94, 85, 89, 80, 72, 92,
+  80, 74, 80, 112, 97, 92, 77, 60, 67, 99,
+  50, 88, 72, 83, 94, 81, 76, 76, 74, 67,
+  75, 89, 79, 70, 65, 123, 57, 80, 93, 80,
+  63, 59, 72, 75, 71, 94, 84, 65, 83, 106,
+  62, 85, 93, 79, 107, 65, 92, 91, 75, 76,
+  91, 80, 54, 51, 69, 81, 60, 88, 83, 73,
+  75, 81, 51, 76, 70, 82, 79, 96, 87, 87,
+  77, 68, 109, 92, 69, 73, 81, 80, 72, 88,
+  98, 80, 75, 86, 90, 77, 63, 80, 77, 108,
+  83, 82, 87, 82, 76, 91, 74, 81, 91, 90,
+  71, 80, 73, 83, 63, 84, 83, 73, 84, 80,
+  77, 108, 79, 92, 80, 83, 88, 87, 93, 81,
+  63, 86, 74, 88, 89, 84, 79, 87, 72, 67,
+  101, 67, 81, 77, 89, 77, 78, 63, 88, 82,
+  72, 86, 70, 74, 89, 85, 81, 77, 84, 88,
+  79, 107, 87, 73, 86, 63, 89, 82, 78, 77,
+  88, 77, 84, 83, 89, 88, 87, 104, 79, 72,
+  75, 74, 95, 96, 72, 95, 79, 101, 73, 81,
+  73, 87, 82, 85, 120, 85, 80, 84, 68, 96,
+  99, 81, 92, 84, 94, 100, 88, 93, 74, 65,
+  83, 94, 78, 82, 77, 97, 108, 74, 75, 91,
+  62, 83, 80, 92, 70, 94, 71, 75, 99, 73,
+  96, 83, 69, 83, 87, 87, 97, 86, 79, 87,
+  92, 79, 76, 80, 82, 74, 86, 87, 78, 96,
+  94, 93, 85, 82, 83, 81, 89, 82, 91, 87,
+  78, 91, 74, 98, 75, 91, 78, 68, 88, 84,
+  85, 73, 84, 75, 86, 103, 76, 87, 74, 92,
+  84, 67, 95, 83, 85, 74, 82, 96, 80, 95,
+  86, 96, 85, 68, 89, 82, 73, 85, 91, 83,
+  105, 91, 88, 89, 88, 78, 84, 79, 76, 76,
+  87, 77, 80, 85, 83, 105, 85, 82, 76, 94,
+  77, 82, 90, 89, 85, 86, 81, 88, 87, 108,
+  93, 82, 98, 97, 97, 95, 79, 78, 97, 85,
+  84, 77, 88, 78, 71, 82, 83, 83, 97, 79,
+  98, 90, 76, 94, 74, 84, 86, 98, 93, 82,
+  55, 78, 90, 82, 97, 75, 76, 93, 135, 72,
+  88, 83, 89, 89, 75, 75, 87, 100, 81, 97,
+  76, 75, 73, 59, 90, 91, 80, 89, 88, 83,
+  86, 87, 76, 95, 84, 78, 87, 92, 84, 92,
+  70, 58, 76, 89, 46, 95, 72, 94, 94, 67,
+  82, 87, 70, 65, 79, 91, 77, 74, 75, 131,
+  84, 76, 92, 82, 71, 80, 100, 77, 91, 94,
+  83, 65, 86, 94, 72, 80, 87, 75, 97, 81,
+  88, 92, 77, 87, 90, 73, 55, 78, 72, 78,
+  61, 89, 75, 79, 87, 78, 71, 95, 72, 78,
+  82, 108, 86, 87, 66, 76, 104, 93, 69, 75,
+  88, 78, 84, 87, 104, 75, 75, 82, 94, 73,
+  66, 88, 78, 91, 96, 96, 67, 83, 77, 88,
+  87, 86, 96, 87, 70, 84, 93, 90, 72, 86,
+  88, 73, 88, 79, 86, 98, 82, 92, 78, 83,
+  85, 88, 81, 82, 81, 88, 81, 79, 83, 81,
+  75, 90, 92, 72, 89, 83, 72, 75, 85, 66,
+  78, 58, 86, 86, 75, 88, 78, 71, 93, 90,
+  80, 77, 79, 94, 84, 92, 94, 85, 81, 65,
+  91, 83, 77, 86, 92, 81, 90, 91, 90, 88,
+  82, 93, 74, 79, 74, 78, 96, 96, 81, 91,
+  75, 91, 78, 82, 75, 97, 80, 85, 100, 92,
+  82, 88, 89, 83, 90, 94, 92, 83, 99, 98,
+  92, 96, 87, 73, 84, 91, 85, 83, 72, 85,
+  106, 80, 85, 92, 65, 82, 84, 93, 71, 96,
+  72, 85, 88, 72, 95, 80, 78, 72, 79, 76,
+  86, 91, 97, 76, 86, 95, 80, 78, 78, 79,
+  79, 82, 76, 93, 77, 79, 99, 88, 96, 85,
+  87, 82, 80, 93, 84, 101, 81, 73, 81, 89,
+  80, 86, 94, 84, 99, 84, 95, 81, 88, 81,
+  86, 80, 97, 83, 82, 62, 71, 72, 86, 84,
+  89, 81, 68, 91, 92, 77, 84, 66, 84, 91,
+  95, 82, 91, 87, 96, 73, 96, 85, 92, 84,
+  76, 85, 74, 85, 93, 97, 83, 85, 92, 87,
+  78, 91, 86, 81, 82, 81, 76, 66, 82, 91,
+  83, 93, 91, 85, 87, 79, 82, 97, 78, 86,
+  84, 77, 79, 87, 99, 78, 94, 79, 91, 84,
+  89, 67, 90, 72, 85, 82, 90, 85, 81, 69,
+  89, 76, 83, 83, 92, 77, 76, 71, 81, 85,
+  89, 79, 93, 92, 78, 73, 80, 82, 76, 90,
+  87, 100, 77, 79, 98, 90, 92, 83, 88, 81,
+  79, 82, 66, 106, 79, 81, 82, 73, 90, 91,
+  95, 92, 83, 97, 101, 62, 81, 76, 84, 92,
+  99, 87, 81, 60, 63, 91, 79, 89, 96, 89,
+  66, 73, 92, 78, 83, 68, 89, 108, 97, 86,
+  84, 102, 89, 79, 105, 73, 88, 83, 82, 78,
+  77, 88, 92, 95, 86, 90, 85, 99, 85, 85,
+  78, 81, 76, 70, 69, 66, 76, 98, 83, 83,
+  92, 103, 94, 78, 67, 108, 84, 89, 81, 86,
+  83, 81, 107, 80, 90, 77, 76, 80, 78, 69,
+  86, 75, 80, 93, 85, 79, 75, 66, 87, 82,
+  83, 87, 80, 77, 73, 79, 89, 91, 96, 82,
+  88, 77, 79, 79, 82, 82, 81, 85, 96, 94,
+  80, 84, 89, 85, 93, 88, 86, 80, 83, 85,
+  74, 89, 75, 97, 84, 83, 91, 89, 94, 86,
+  67, 86, 95, 77, 87, 79, 86, 80, 97, 86,
+  82, 68, 71, 90, 85, 84, 88, 82, 72, 81,
+  88, 79, 77, 72, 81, 94, 99, 83, 86, 89,
+  97, 75, 96, 82, 93, 73, 84, 82, 74, 86,
+  92, 88, 84, 84, 78, 86, 79, 89, 87, 86,
+  81, 77, 73, 67, 80, 93, 87, 92, 89, 98,
+  89, 78, 83, 94, 77, 82, 82, 78, 78, 85,
+  101, 88, 76, 82, 87, 80, 84, 70, 92, 75,
+  87, 84, 89, 82, 88, 67, 91, 71, 89, 77,
+  92, 75, 88, 79, 74, 92, 98, 76, 89, 83,
+  82, 78, 79, 77, 75, 90, 80, 94, 71, 78,
+  101, 85, 76, 89, 90, 86, 91, 90, 73, 127,
+  74, 71, 73, 74, 87, 77, 96, 87, 123, 92,
+  106, 80, 80, 80, 80, 76, 89, 81, 80, 64,
+  65, 82, 87, 90, 88, 90, 75, 83, 91, 73,
+  76, 70, 79, 97, 82, 81, 90, 83, 85, 75,
+  88, 91, 82, 84, 77, 84, 77, 90, 84, 96,
+  83, 82, 88, 95, 74, 89, 72, 87, 84, 73,
+  71, 70, 78, 95, 69, 87, 78, 82, 87, 81,
+  85, 93, 79, 88, 81, 80, 80, 94, 111, 82,
+  88, 74, 84, 75, 84, 72, 78, 79, 77, 89,
+  86, 77, 87, 58, 91, 77, 74, 80, 101, 70,
+  90, 73, 69, 85, 93, 76, 90, 92, 76, 79,
+  80, 74, 68, 109, 100, 97, 74, 84, 97, 89,
+  70, 81, 91, 84, 88, 70, 60, 132, 93, 83,
+  77, 66, 92, 87, 121, 101, 100, 108, 123, 58,
+  80, 72, 86, 95, 85, 85, 79, 59, 54, 92,
+  84, 98, 95, 99, 67, 62, 97, 80, 73, 77,
+  83, 117, 83, 70, 78, 98, 77, 77, 98, 72,
+  73, 88, 83, 79, 82, 97, 81, 78, 87, 85,
+  85, 98, 79, 78, 67, 82, 76, 56, 64, 64,
+  69, 95, 74, 77, 86, 88, 88, 82, 73, 95,
+  85, 91, 69, 84, 87, 84, 113, 80, 90, 59,
+  71, 68, 70, 80, 82, 70, 70, 106, 76, 74,
+  74, 60, 90, 89, 84, 83, 92, 69, 88, 80,
+  75, 92, 98, 79, 92, 87, 79, 79, 82, 78,
+  76, 102, 118, 92, 87, 86, 88, 88, 77, 86,
+  89, 79, 91, 74, 68, 99, 76, 100, 75, 75,
+  95, 83, 101, 88, 74, 92, 111, 73, 76, 76,
+  80, 79, 86, 88, 78, 68, 66, 82, 85, 90,
+  84, 88, 75, 75, 91, 78, 74, 76, 81, 99,
+  85, 76, 85, 85, 86, 77, 91, 85, 87, 80,
+  80, 86, 77, 92, 86, 76, 86, 83, 81, 89,
+  73, 86, 71, 75, 82, 74, 71, 71, 77, 96,
+  85, 85, 77, 93, 85, 81, 81, 89, 80, 82,
+  77, 78, 90, 91, 110, 85, 81, 69, 92, 76,
+  79, 79, 94, 80, 77, 87, 83, 84, 88, 63,
+  84, 76, 78, 84, 71, 82, 88, 86, 85, 85,
+  102, 77, 88, 64, 77, 89, 78, 80, 92, 85,
+  78, 83, 75, 80, 84, 81, 88, 86, 84, 78,
+  81, 93, 90, 108, 80, 79, 84, 85, 81, 72,
+  98, 72, 109, 80, 95, 90, 84, 86, 71, 69,
+  90, 75, 78, 75, 77, 85, 88, 82, 81, 87,
+  78, 87, 85, 84, 77, 68, 75, 80, 76, 78,
+  82, 84, 89, 77, 89, 89, 88, 94, 92, 84,
+  76, 89, 88, 88, 79, 87, 89, 83, 81, 83,
+  75, 86, 85, 83, 78, 75, 86, 92, 72, 96,
+  82, 82, 88, 79, 96, 85, 81, 83, 83, 75,
+  94, 85, 100, 84, 85, 86, 77, 77, 82, 72,
+  81, 78, 84, 80, 85, 87, 92, 77, 81, 80,
+  77, 79, 75, 75, 90, 77, 81, 86, 100, 80,
+  86, 84, 74, 93, 77, 87, 90, 93, 96, 76,
+  84, 79, 82, 83, 87, 85, 90, 80, 77, 83,
+  81, 103, 85, 81, 82, 87, 81, 74, 119, 67,
+  100, 93, 103, 80, 77, 81, 69, 71, 92, 79,
+  74, 76, 70, 90, 91, 86, 83, 85, 70, 73,
+  98, 73, 75, 68, 80, 83, 76, 76, 80, 86,
+  85, 78, 91, 75, 81, 85, 90, 82, 79, 102,
+  80, 84, 85, 90, 88, 78, 90, 87, 70, 88,
+  90, 75, 73, 76, 76, 95, 73, 87, 83, 71,
+  79, 77, 98, 74, 81, 85, 80, 77, 101, 77,
+  101, 82, 88, 75, 75, 79, 77, 80, 94, 71,
+  76, 78, 79, 92, 93, 81, 84, 86, 82, 84,
+  73, 78, 89, 85, 83, 88, 102, 77, 90, 87,
+  74, 87, 77, 83, 95, 91, 101, 81, 91, 82,
+  77, 86, 90, 86, 82, 83, 84, 81, 88, 94,
+  79, 87, 83, 85, 82, 75, 103, 72, 76, 80,
+  100, 81, 76, 88, 73, 69, 88, 82, 78, 80,
+  76, 80, 88, 83, 79, 82, 77, 81, 89, 80,
+  79, 72, 79, 79, 78, 82, 76, 86, 90, 75,
+  92, 85, 88, 80, 84, 84, 76, 86, 86, 84,
+  84, 90, 85, 79, 79, 80, 74, 75, 87, 85,
+  77, 77, 85, 93, 84, 90, 82, 73, 89, 77,
+  96, 86, 84, 80, 83, 77, 105, 84, 100, 83,
+  88, 82, 90, 80, 83, 79, 93, 80, 81, 82,
+  81, 96, 91, 83, 84, 84, 88, 81, 83, 77,
+  74, 95, 93, 72, 86, 90, 110, 87, 58, 104,
+  75, 82, 83, 99, 70, 99, 98, 102, 66, 85,
+  102, 70, 85, 81, 83, 74, 109, 79, 86, 84,
+  86, 97, 82, 95, 83, 59, 87, 75, 79, 106,
+  81, 86, 87, 93, 84, 119, 88, 77, 113, 90,
+  85, 85, 98, 81, 78, 79, 85, 58, 66, 99,
+  82, 87, 77, 62, 94, 70, 109, 86, 68, 83,
+  85, 95, 71, 74, 107, 85, 95, 101, 69, 90,
+  85, 64, 115, 67, 96, 100, 71, 75, 94, 65,
+  67, 78, 93, 104, 71, 76, 81, 71, 84, 84,
+  82, 100, 77, 106, 80, 57, 90, 76, 81, 90,
+  79, 72, 87, 94, 63, 94, 100, 94, 116, 92,
+  78, 128, 89, 72, 86, 83, 84, 73, 70, 81,
+  85, 86, 82, 101, 83, 73, 64, 85, 76, 101,
+  89, 106, 70, 92, 117, 82, 78, 72, 105, 83,
+  91, 84, 94, 93, 111, 77, 80, 89, 69, 100,
+  107, 73, 84, 69, 76, 72, 87, 81, 75, 76,
+  84, 84, 85, 76, 80, 80, 88, 83, 95, 80,
+  85, 82, 84, 86, 93, 69, 55, 89, 112, 103,
+  78, 78, 88, 81, 93, 89, 74, 80, 88, 109,
+  67, 61, 85, 85, 87, 124, 81, 88, 80, 77,
+  75, 74, 96, 91, 88, 76, 86, 78, 81, 73,
+  85, 82, 75, 71, 83, 81, 83, 83, 83, 90,
+  73, 107, 74, 81, 95, 80, 73, 86, 83, 78,
+  88, 80, 74, 86, 89, 87, 78, 89, 83, 92,
+  90, 74, 99, 84, 83, 87, 69, 75, 84, 86,
+  79, 92, 86, 76, 71, 84, 76, 96, 84, 90,
+  88, 83, 89, 75, 86, 73, 88, 83, 83, 87,
+  95, 94, 91, 73, 78, 93, 73, 90, 105, 74,
+  85, 74, 71, 74, 91, 76, 79, 88, 87, 81,
+  80, 73, 80, 85, 77, 91, 84, 78, 76, 90,
+  87, 94, 95, 71, 70, 82, 89, 105, 81, 85,
+  85, 87, 84, 86, 86, 76, 92, 89, 78, 71,
+  70, 80, 79, 109, 93, 79, 91, 84, 71, 79,
+  84, 102, 94, 79, 83, 89, 88, 88, 82, 69,
+  84, 86, 89, 84, 84, 93, 82, 77, 70, 92,
+  82, 111, 86, 80, 76, 83, 80, 81, 86, 75,
+  83, 78, 76, 84, 66, 89, 78, 72, 84, 72,
+  84, 83, 84, 68, 68, 89, 79, 79, 87, 88,
+  93, 79, 59, 81, 82, 102, 85, 107, 68, 85,
+  110, 86, 77, 67, 101, 76, 94, 83, 87, 81,
+  106, 81, 77, 82, 80, 97, 95, 75, 89, 71,
+  79, 74, 83, 90, 77, 79, 83, 83, 71, 88,
+  82, 75, 87, 85, 95, 77, 88, 80, 83, 86,
+  105, 65, 56, 82, 107, 112, 81, 100, 79, 71,
+  96, 98, 70, 88, 85, 105, 72, 77, 88, 71,
+  89, 115, 74, 84, 88, 79, 69, 79, 91, 103,
+  84, 75, 91, 81, 84, 75, 86, 87, 87, 85,
+  87, 83, 70, 86, 86, 87, 64, 96, 70, 99,
+  92, 79, 90, 86, 84, 79, 85, 83, 76, 84,
+  83, 81, 84, 86, 83, 89, 86, 75, 87, 82,
+  89, 77, 82, 76, 72, 91, 79, 97, 74, 66,
+  86, 78, 89, 101, 83, 98, 90, 78, 100, 72,
+  93, 78, 78, 83, 95, 88, 101, 92, 78, 78,
+  69, 79, 60, 90, 119, 70, 86, 75, 65, 92,
+  96, 77, 75, 71, 83, 68, 81, 68, 74, 91,
+  71, 76, 85, 84, 70, 88, 81, 82, 101, 73,
+  60, 75, 92, 103, 88, 90, 75, 81, 70, 84,
+  84, 72, 91, 98, 68, 84, 81, 86, 77, 95,
+  98, 84, 81, 95, 61, 71, 73, 70, 78, 84,
+  70, 101, 90, 90, 80, 67, 67, 69, 90, 90,
+  80, 89, 76, 72, 66, 77, 85, 111, 85, 77,
+  81, 70, 77, 78, 81, 78, 86, 70, 67, 72,
+  66, 88, 84, 56, 94, 76, 88, 82, 91, 80,
+  80, 77, 79, 90, 86, 86, 91, 80, 91, 84,
+  86, 81, 83, 73, 96, 79, 66, 76, 89, 72,
+  80, 84, 92, 93, 93, 82, 78, 79, 81, 79,
+  64, 75, 98, 79, 83, 86, 76, 83, 88, 78,
+  86, 82, 87, 72, 82, 76, 79, 97, 62, 87,
+  75, 88, 76, 86, 85, 91, 91, 79, 78, 82,
+  77, 73, 92, 79, 82, 87, 73, 85, 89, 75,
+  90, 89, 86, 95, 73, 82, 82, 79, 92, 78,
+  87, 95, 70, 80, 78, 88, 87, 83, 72, 87,
+  87, 104, 81, 82, 83, 88, 91, 89, 85, 91,
+  82, 72, 82, 81, 91, 101, 80, 76, 79, 77,
+  82, 77, 85, 88, 98, 72, 79, 76, 68, 89,
+  77, 70, 95, 79, 88, 75, 86, 73, 79, 84,
+  79, 84, 89, 83, 92, 86, 71, 74, 89, 100,
+  86, 95, 72, 81, 98, 83, 94, 75, 87, 88,
+  86, 85, 90, 90, 91, 92, 72, 76, 78, 85,
+  99, 79, 88, 79, 81, 77, 83, 87, 84, 81,
+  80, 81, 78, 82, 75, 83, 86, 86, 92, 87,
+  88, 84, 80, 74, 99, 81, 65, 87, 93, 83,
+  88, 83, 83, 82, 80, 88, 76, 82, 86, 104,
+  71, 87, 80, 76, 80, 107, 82, 86, 89, 83,
+  73, 81, 84, 81, 93, 85, 84, 88, 94, 86,
+  85, 78, 83, 79, 87, 86, 84, 86, 89, 81,
+  75, 83, 73, 91, 84, 81, 91, 86, 72, 81,
+  88, 78, 87, 73, 77, 73, 78, 94, 81, 82,
+  89, 81, 84, 72, 84, 76, 82, 77, 71, 89,
+  86, 94, 81, 81, 92, 80, 90, 93, 78, 83,
+  93, 77, 93, 79, 98, 77, 78, 90, 92, 92,
+  93, 86, 77, 91, 76, 75, 76, 82, 97, 78,
+  92, 81, 76, 83, 84, 82, 85, 76, 83, 76,
+  89, 73, 75, 93, 70, 78, 79, 94, 81, 86,
+  82, 81, 93, 78, 84, 83, 87, 73, 98, 74,
+  84, 92, 74, 81, 84, 77, 86, 91, 68, 92,
+  80, 89, 79, 92, 86, 89, 81, 97, 74, 69,
+  78, 76, 88, 90, 75, 91, 89, 93, 74, 78,
+  79, 74, 87, 88, 82, 86, 91, 74, 80, 80,
+  86, 83, 79, 81, 81, 75, 74, 81, 86, 85,
+  98, 73, 79, 72, 68, 92, 74, 71, 80, 79,
+  84, 79, 82, 74, 76, 79, 73, 97, 87, 95,
+  100, 82, 91, 78, 79, 88, 81, 73, 92, 82,
+  87, 87, 98, 76, 85, 91, 86, 92, 84, 84,
+  81, 96, 79, 82, 84, 81, 93, 85, 87, 84,
+  85, 79, 79, 80, 84, 88, 82, 80, 83, 94,
+  82, 94, 73, 82, 76, 88, 91, 85, 86, 88,
+  91, 78, 92, 90, 91, 74, 97, 84, 91, 93,
+  83, 82, 91, 78, 86, 85, 75, 88, 77, 84,
+  84, 98, 81, 75, 84, 91, 84, 77, 86, 83,
+  96, 89, 81, 76, 83, 89, 76, 93, 86, 89,
+  95, 84, 79, 87, 89, 80, 79, 78, 82, 77,
+  79, 85, 79, 76, 96, 86, 89, 90, 94, 80,
+  91, 73, 81, 87, 77, 84, 80, 98, 87, 75,
+  95, 89, 91, 104, 89, 69, 72, 84, 88, 92,
+  75, 88, 88, 83, 97, 72, 82, 82, 73, 75,
+  82, 87, 82, 82, 73, 65, 78, 85, 101, 97,
+  70, 85, 76, 89, 53, 107, 89, 62, 82, 86,
+  91, 104, 74, 92, 101, 87, 89, 91, 67, 83,
+  67, 93, 92, 95, 85, 66, 75, 74, 77, 77,
+  71, 115, 92, 79, 95, 76, 97, 66, 87, 88,
+  74, 91, 75, 73, 93, 102, 82, 102, 91, 79,
+  94, 83, 82, 74, 88, 96, 79, 93, 85, 90,
+  91, 88, 57, 80, 86, 107, 90, 75, 76, 101,
+  91, 86, 92, 86, 80, 97, 98, 71, 94, 76,
+  83, 109, 81, 82, 93, 93, 70, 84, 91, 86,
+  91, 89, 81, 90, 63, 92, 82, 94, 72, 99,
+  78, 117, 89, 92, 85, 81, 60, 73, 65, 87,
+  82, 73, 109, 106, 81, 77, 95, 84, 71, 93,
+  91, 93, 90, 69, 61, 96, 85, 90, 72, 106,
+  62, 111, 70, 78, 89, 51, 77, 70, 89, 89,
+  57, 84, 91, 70, 102, 70, 78, 83, 81, 87,
+  112, 89, 78, 84, 84, 78, 82, 71, 71, 86,
+  79, 88, 82, 73, 95, 71, 107, 74, 78, 109,
+  63, 79, 63, 87, 82, 98, 77, 93, 83, 96,
+  79, 84, 73, 82, 112, 80, 68, 87, 109, 79,
+  64, 71, 80, 89, 70, 49, 98, 99, 76, 86,
+  103, 77, 65, 77, 80, 69, 104, 90, 64, 88,
+  92, 81, 85, 71, 74, 80, 89, 103, 93, 78,
+  79, 73, 79, 72, 95, 79, 74, 94, 80, 88,
+  91, 91, 75, 89, 126, 86, 60, 79, 75, 78,
+  93, 87, 90, 78, 79, 93, 78, 80, 102, 91,
+  77, 101, 84, 95, 83, 93, 80, 82, 70, 99,
+  82, 81, 92, 66, 82, 85, 86, 87, 74, 99,
+  70, 92, 79, 96, 80, 76, 90, 83, 86, 84,
+  91, 78, 109, 66, 76, 102, 62, 79, 95, 82,
+  74, 112, 82, 88, 89, 77, 67, 81, 74, 77,
+  71, 69, 84, 99, 79, 84, 80, 81, 87, 93,
+  72, 83, 94, 86, 82, 90, 92, 79, 81, 81,
+  92, 76, 83, 70, 80, 99, 87, 89, 73, 80,
+  67, 85, 93, 81, 73, 79, 81, 109, 89, 83,
+  87, 83, 88, 89, 88, 77, 93, 81, 79, 85,
+  83, 90, 66, 93, 89, 74, 73, 109, 89, 89,
+  83, 77, 75, 72, 57, 88, 83, 78, 101, 103,
+  58, 80, 77, 85, 74, 87, 100, 89, 97, 74,
+  68, 87, 75, 77, 72, 90, 93, 92, 76, 84,
+  85, 63, 82, 69, 95, 89, 77, 75, 91, 72,
+  83, 67, 81, 74, 88, 107, 100, 71, 85, 74,
+  92, 74, 82, 56, 49, 86, 79, 94, 82, 97,
+  101, 72, 95, 79, 86, 102, 72, 70, 91, 70,
+  85, 81, 77, 91, 81, 84, 84, 81, 75, 91,
+  87, 86, 71, 89, 107, 69, 73, 75, 93, 81,
+  84, 72, 93, 96, 95, 82, 84, 80, 75, 75,
+  83, 70, 86, 88, 90, 101, 79, 81, 79, 86,
+  83, 84, 82, 98, 87, 78, 79, 75, 86, 72,
+  123, 95, 69, 91, 55, 98, 80, 102, 80, 75,
+  65, 80, 55, 80, 81, 73, 96, 111, 70, 83,
+  98, 81, 71, 72, 113, 93, 118, 77, 62, 93,
+  62, 74, 66, 98, 90, 81, 68, 63, 96, 56,
+  67, 56, 90, 66, 84, 86, 78, 64, 81, 68,
+  80, 65, 97, 78, 100, 61, 76, 80, 106, 79,
+  72, 59, 62, 63, 60, 86, 74, 117, 61, 79,
+  93, 78, 86, 87, 76, 73, 81, 54, 84, 72,
+  72, 106, 73, 98, 83, 101, 55, 73, 87, 78,
+  63, 76, 113, 59, 80, 77, 69, 54, 86, 53,
+  107, 93, 89, 89, 94, 72, 63, 58, 91, 73,
+  70, 86, 92, 81, 99, 69, 58, 81, 82, 84,
+  70, 89, 78, 85, 72, 62, 84, 65, 101, 77,
+  84, 77, 82, 70, 87, 79, 77, 80, 134, 79,
+  69, 81, 84, 71, 85, 90, 94, 69, 70, 99,
+  92, 82, 100, 89, 94, 97, 106, 90, 69, 82,
+  105, 86, 80, 82, 79, 90, 86, 85, 87, 91,
+  81, 88, 106, 104, 67, 87, 80, 94, 90, 73,
+  87, 73, 78, 79, 96, 78, 101, 79, 75, 88,
+  57, 69, 80, 87, 74, 84, 69, 86, 75, 76,
+  85, 63, 79, 73, 95, 69, 91, 91, 91, 88,
+  85, 69, 89, 79, 91, 91, 77, 72, 84, 100,
+  80, 85, 92, 93, 78, 66, 82, 88, 79, 91,
+  106, 67, 72, 88, 77, 82, 106, 80, 58, 78,
+  105, 98, 62, 80, 82, 82, 83, 92, 75, 70,
+  97, 81, 93, 89, 74, 95, 78, 74, 110, 82,
+  75, 76, 93, 78, 84, 78, 86, 88, 57, 76,
+  83, 84, 74, 100, 65, 79, 87, 89, 96, 93,
+  88, 82, 79, 83, 104, 94, 78, 66, 84, 82,
+  106, 87, 86, 80, 82, 81, 85, 85, 86, 80,
+  105, 79, 83, 78, 83, 83, 89, 81, 101, 100,
+  84, 68, 85, 73, 96, 86, 79, 75, 66, 75,
+  87, 88, 86, 79, 76, 88, 85, 95, 100, 85,
+  85, 79, 82, 66, 101, 79, 84, 85, 86, 85,
+  82, 83, 83, 79, 72, 79, 83, 98, 95, 79,
+  98, 90, 111, 71, 82, 71, 80, 94, 89, 66,
+  85, 92, 104, 72, 73, 77, 64, 81, 95, 92,
+  82, 92, 92, 92, 100, 87, 78, 85, 75, 89,
+  83, 83, 81, 80, 98, 72, 100, 84, 85, 64,
+  85, 68, 81, 83, 106, 75, 74, 70, 86, 77,
+  80, 85, 90, 81, 80, 91, 101, 89, 84, 85,
+  93, 77, 122, 94, 78, 79, 89, 80, 93, 86,
+  87, 80, 82, 81, 80, 90, 74, 85, 115, 93,
+  69, 74, 84, 90, 95, 79, 89, 90, 78, 71,
+  87, 78, 102, 91, 79, 83, 74, 66, 95, 88,
+  87, 62, 60, 82, 80, 92, 96, 65, 85, 69,
+  91, 64, 101, 85, 88, 83, 87, 73, 77, 85,
+  81, 77, 68, 75, 88, 106, 82, 84, 102, 101,
+  91, 68, 76, 61, 76, 89, 91, 74, 92, 95,
+  97, 79, 91, 86, 62, 76, 88, 83, 75, 91,
+  87, 88, 90, 86, 80, 74, 78, 97, 85, 92,
+  75, 82, 84, 92, 90, 84, 89, 66, 82, 71,
+  81, 84, 104, 79, 75, 74, 90, 78, 70, 92,
+  92, 89, 97, 92, 91, 81, 78, 78, 75, 84,
+  104, 85, 94, 81, 103, 81, 78, 95, 104, 75,
+  81, 85, 88, 93, 81, 81, 96, 104, 74, 88,
+  91, 94, 98, 95, 84, 84, 76, 80, 98, 77,
+  89, 98, 78, 80, 83, 77, 100, 89, 84, 70,
+  67, 83, 78, 86, 87, 61, 82, 83, 85, 83,
+  98, 101, 92, 79, 80, 67, 82, 84, 82, 85,
+  82, 67, 94, 96, 71, 92, 97, 88, 77, 95,
+  71, 80, 79, 84, 80, 60, 76, 93, 85, 81,
+  86, 88, 74, 87, 103, 96, 86, 101, 80, 90,
+  74, 78, 73, 77, 82, 87, 90, 99, 83, 76,
+  85, 83, 82, 94, 93, 71, 88, 72, 83, 81,
+  101, 84, 89, 74, 79, 92, 73, 79, 74, 89,
+  66, 93, 97, 79, 82, 76, 102, 100, 102, 89,
+  73, 87, 85, 79, 92, 72, 115, 86, 73, 118,
+  89, 77, 72, 74, 99, 90, 72, 76, 91, 79,
+  85, 76, 71, 95, 92, 94, 103, 88, 80, 87,
+  83, 113, 68, 81, 66, 75, 100, 95, 106, 103,
+  76, 89, 86, 76, 86, 63, 85, 78, 81, 87,
+  84, 88, 92, 64, 81, 85, 89, 74, 82, 79,
+  87, 72, 86, 84, 75, 91, 87, 56, 84, 84,
+  85, 84, 89, 102, 69, 92, 85, 89, 72, 97,
+  85, 74, 79, 77, 73, 81, 100, 81, 90, 80,
+  73, 64, 90, 82, 93, 75, 73, 87, 85, 72,
+  91, 69, 97, 65, 78, 76, 82, 88, 107, 107,
+  98, 65, 81, 78, 63, 73, 79, 107, 74, 106,
+  83, 85, 81, 72, 97, 88, 115, 95, 69, 81,
+  97, 80, 93, 68, 86, 100, 59, 155, 84, 85,
+  67, 70, 92, 78, 73, 80, 75, 97, 93, 75,
+  70, 77, 88, 87, 111, 80, 83, 85, 78, 125,
+  59, 83, 64, 70, 113, 75, 90, 111, 71, 77,
+  96, 69, 91, 83, 91, 83, 82, 85, 89, 68,
+  100, 59, 70, 80, 91, 76, 82, 66, 92, 79,
+  78, 90, 70, 93, 101, 63, 77, 83, 84, 86,
+  88, 100, 59, 90, 91, 91, 95, 96, 82, 75,
+  86, 75, 75, 82, 100, 86, 85, 83, 80, 59,
+  97, 70, 94, 82, 94, 83, 87, 86, 84, 79,
+  83, 81, 86, 80, 80, 71, 72, 105, 78, 75,
+  79, 91, 84, 82, 95, 88, 91, 82, 77, 78,
+  87, 90, 87, 77, 94, 87, 83, 71, 90, 92,
+  90, 77, 72, 81, 85, 99, 77, 70, 81, 84,
+  90, 73, 74, 72, 96, 78, 80, 83, 77, 75,
+  89, 82, 96, 99, 84, 78, 94, 79, 73, 71,
+  64, 86, 97, 87, 77, 88, 84, 89, 96, 86,
+  78, 96, 96, 75, 83, 81, 84, 76, 82, 68,
+  84, 83, 89, 80, 92, 83, 96, 76, 100, 88,
+  90, 87, 84, 69, 91, 105, 81, 83, 88, 97,
+  74, 90, 87, 86, 93, 90, 87, 90, 85, 74,
+  97, 90, 90, 81, 96, 71, 77, 71, 92, 82,
+  103, 83, 74, 78, 84, 84, 78, 96, 91, 83,
+  92, 74, 90, 75, 93, 100, 93, 77, 79, 81,
+  75, 68, 80, 96, 60, 99, 86, 79, 93, 80,
+  94, 78, 104, 84, 74, 99, 96, 75, 75, 79,
+  70, 80, 98, 117, 103, 75, 80, 84, 97, 89,
+  82, 79, 100, 90, 81, 76, 80, 90, 78, 94,
+  96, 87, 90, 90, 89, 106, 84, 74, 76, 73,
+  93, 85, 91, 107, 74, 104, 81, 71, 92, 74,
+  78, 83, 94, 88, 86, 71, 84, 84, 80, 81,
+  92, 66, 88, 98, 95, 80, 72, 83, 73, 94,
+  73, 71, 93, 100, 78, 89, 86, 78, 73, 88,
+  81, 79, 87, 84, 76, 76, 89, 91, 65, 85,
+  105, 89, 78, 80, 79, 65, 81, 74, 83, 78,
+  62, 81, 80, 79, 82, 70, 90, 78, 88, 71,
+  90, 76, 103, 88, 98, 85, 77, 76, 66, 69,
+  95, 88, 85, 103, 73, 75, 85, 74, 90, 81,
+  93, 89, 70, 85, 85, 73, 70, 83, 98, 85,
+  108, 125, 89, 85, 85, 77, 85, 76, 81, 90,
+  91, 106, 78, 73, 78, 95, 67, 90, 104, 81,
+  95, 85, 83, 102, 71, 80, 80, 68, 86, 80,
+  89, 112, 70, 110, 78, 65, 100, 83, 70, 90,
+  96, 81, 82, 70, 82, 95, 72, 76, 91, 58,
+  82, 83, 97, 81, 63, 93, 69, 96, 86, 75,
+  87, 99, 73, 94, 75, 70, 65, 86, 75, 79,
+  92, 87, 72, 71, 91, 86, 91, 83, 112, 97,
+  69, 86, 71, 59, 83, 69, 78, 80, 80, 84,
+  83, 85, 82, 80, 82, 81, 88, 77, 85, 73,
+  87, 88, 87, 77, 82, 84, 88, 81, 91, 82,
+  94, 92, 79, 80, 92, 91, 84, 93, 91, 86,
+  83, 78, 87, 92, 78, 79, 100, 77, 93, 97,
+  77, 71, 87, 84, 91, 84, 78, 76, 104, 72,
+  77, 82, 79, 93, 84, 88, 96, 100, 90, 75,
+  93, 83, 76, 72, 67, 88, 95, 84, 82, 96,
+  77, 96, 94, 75, 85, 84, 74, 80, 90, 83,
+  88, 77, 84, 87, 80, 76, 85, 76, 97, 74,
+  90, 81, 76, 74, 84, 91, 98, 73, 96, 103,
+  85, 89, 87, 87, 80, 85, 86, 80, 88, 83,
+  85, 78, 84, 87, 103, 87, 84, 88, 80, 84,
+  85, 74, 83, 76, 89, 82, 87, 79, 84, 90,
+  82, 82, 81, 86, 80, 85, 81, 93, 89, 92,
+  78, 73, 73, 89, 90, 85, 102, 97, 91, 76,
+  84, 83, 96, 99, 94, 71, 82, 83, 95, 86,
+  82, 84, 82, 80, 72, 81, 98, 89, 83, 73,
+  85, 100, 68, 86, 85, 84, 78, 73, 79, 84,
+  80, 76, 89, 69, 82, 85, 93, 73, 83, 86,
+  81, 74, 62, 99, 86, 84, 77, 86, 83, 92,
+  88, 85, 83, 80, 82, 79, 91, 78, 87, 80,
+  82, 89, 94, 87, 74, 74, 90, 80, 92, 85,
+  91, 68, 87, 86, 77, 71, 93, 76, 92, 87,
+  98, 89, 87, 87, 89, 73, 81, 75, 87, 83,
+  78, 75, 81, 88, 84, 81, 80, 76, 80, 76,
+  77, 79, 93, 72, 86, 81, 72, 89, 87, 87,
+  68, 82, 82, 85, 82, 92, 94, 80, 80, 71,
+  72, 86, 92, 84, 90, 97, 90, 73, 78, 79,
+  101, 98, 87, 77, 70, 92, 96, 81, 81, 89,
+  85, 76, 81, 83, 97, 81, 95, 76, 84, 103,
+  69, 69, 77, 94, 80, 81, 80, 84, 88, 76,
+  81, 67, 80, 92, 101, 78, 76, 83, 80, 74,
+  60, 103, 85, 91, 86, 87, 83, 89, 84, 78,
+  83, 80, 82, 82, 89, 74, 88, 82, 73, 92,
+  88, 85, 67, 81, 93, 81, 82, 86, 88, 72,
+  87, 89, 70, 75, 94, 84, 85, 90, 100, 88,
+  88, 86, 97, 72, 76, 83, 80, 80, 81, 63,
+  98, 80, 84, 84, 79, 82, 74, 71, 82, 77,
+  95, 75, 81, 85, 73, 89, 84, 86, 76, 83,
+  79, 86, 82, 83, 98, 85, 85, 80, 76, 88,
+  89, 88, 80, 84, 83, 80, 84, 84, 90, 104,
+  86, 85, 82, 89, 93, 77, 80, 94, 77, 77,
+  104, 77, 102, 94, 96, 76, 86, 93, 70, 75,
+  80, 80, 81, 72, 79, 89, 86, 90, 91, 74,
+  84, 83, 87, 74, 81, 84, 78, 72, 61, 93,
+  91, 86, 84, 85, 82, 88, 90, 78, 79, 81,
+  83, 79, 84, 76, 86, 85, 85, 88, 93, 75,
+  78, 80, 86, 86, 94, 85, 78, 66, 92, 86,
+  82, 78, 97, 85, 87, 86, 96, 87, 87, 84,
+  86, 73, 77, 79, 89, 85, 78, 80, 88, 91,
+  88, 86, 80, 82, 83, 80, 77, 77, 92, 75,
+  71, 77, 81, 80, 94, 85, 83, 79, 77, 89,
+  82, 82, 126, 84, 83, 82, 83, 97, 86, 77,
+  90, 98, 88, 78, 99, 79, 89, 98, 105, 101,
+  79, 79, 56, 73, 75, 79, 89, 73, 97, 87,
+  81, 72, 98, 78, 78, 61, 83, 99, 76, 97,
+  78, 101, 83, 89, 75, 82, 66, 78, 82, 80,
+  88, 67, 82, 121, 92, 76, 80, 72, 69, 99,
+  92, 87, 82, 78, 82, 66, 95, 73, 96, 86,
+  82, 66, 87, 76, 90, 82, 92, 78, 71, 78,
+  58, 76, 71, 84, 84, 76, 85, 79, 91, 84,
+  102, 73, 94, 79, 72, 66, 70, 93, 89, 78,
+  87, 99, 84, 86, 86, 80, 67, 77, 87, 100,
+  100, 99, 76, 98, 77, 77, 86, 86, 72, 73,
+  79, 79, 93, 76, 81, 76, 80, 93, 82, 88,
+  106, 104, 78, 80, 85, 83, 85, 79, 78, 94,
+  72, 85, 97, 82, 83, 97, 92, 76, 93, 88,
+  65, 72, 86, 87, 88, 79, 61, 98, 85, 94,
+  102, 92, 84, 82, 90, 76, 73, 97, 80, 104,
+  81, 84, 82, 59, 69, 80, 86, 79, 84, 79,
+  92, 111, 74, 78, 70, 87, 76, 74, 88, 79,
+  80, 78, 94, 78, 95, 104, 92, 81, 88, 77,
+  94, 72, 88, 76, 82, 73, 82, 82, 60, 85,
+  75, 85, 85, 78, 90, 89, 71, 89, 95, 96,
+  94, 80, 77, 73, 63, 91, 93, 80, 106, 100,
+  81, 80, 96, 86, 74, 85, 90, 86, 76, 86,
+  79, 91, 85, 73, 79, 86, 75, 59, 97, 82,
+  80, 84, 76, 76, 87, 85, 78, 86, 68, 100,
+  77, 88, 92, 79, 80, 93, 81, 65, 80, 84,
+  89, 85, 80, 82, 93, 84, 80, 78, 80, 81,
+  78, 90, 82, 85, 74, 77, 73, 73, 84, 85,
+  83, 103, 97, 90, 80, 80, 85, 72, 80, 84,
+  83, 83, 96, 97, 99, 89, 76, 91, 101, 75,
+  80, 77, 75, 95, 88, 70, 68, 62, 92, 74,
+  90, 99, 83, 85, 82, 80, 94, 91, 86, 79,
+  79, 81, 97, 79, 86, 86, 86, 90, 93, 91,
+  97, 77, 75, 88, 80, 86, 98, 84, 87, 80,
+  98, 81, 86, 85, 81, 82, 87, 78, 71, 79,
+  89, 79, 89, 82, 74, 79, 85, 82, 84, 82,
+  82, 83, 74, 76, 108, 88, 95, 92, 88, 92,
+  84, 81, 76, 83, 84, 81, 118, 101, 97, 77,
+  84, 73, 96, 66, 81, 97, 76, 91, 97, 79,
+  90, 100, 97, 87, 102, 70, 64, 86, 90, 69,
+  75, 81, 91, 82, 78, 105, 85, 80, 63, 51,
+  95, 123, 85, 89, 85, 117, 90, 84, 76, 102,
+  65, 88, 68, 81, 86, 62, 77, 134, 84, 68,
+  80, 66, 93, 74, 82, 115, 59, 94, 76, 70,
+  99, 63, 81, 98, 96, 72, 114, 66, 101, 87,
+  83, 71, 94, 61, 62, 70, 72, 88, 64, 75,
+  98, 88, 100, 92, 79, 75, 94, 76, 81, 85,
+  79, 87, 100, 85, 95, 80, 89, 71, 100, 85,
+  57, 90, 99, 83, 96, 85, 92, 118, 83, 73,
+  86, 94, 78, 79, 86, 83, 85, 77, 83, 77,
+  74, 88, 80, 91, 97, 74, 80, 79, 89, 80,
+  95, 78, 69, 70, 82, 85, 104, 82, 86, 99,
+  83, 84, 80, 88, 69, 64, 73, 87, 79, 80,
+  90, 93, 85, 82, 92, 96, 77, 80, 89, 75,
+  79, 89, 89, 99, 81, 78, 84, 95, 63, 80,
+  77, 85, 80, 72, 84, 86, 86, 61, 77, 77,
+  89, 76, 95, 103, 69, 86, 85, 78, 96, 116,
+  84, 87, 91, 81, 109, 83, 86, 85, 75, 69,
+  83, 76, 67, 66, 76, 91, 63, 78, 94, 96,
+  85, 95, 86, 86, 87, 82, 78, 78, 67, 84,
+  96, 78, 89, 86, 87, 83, 85, 83, 94, 87,
+  88, 80, 62, 78, 75, 99, 86, 75, 81, 79,
+  70, 59, 75, 77, 80, 100, 79, 77, 80, 86,
+  74, 94, 60, 85, 69, 86, 86, 94, 86, 99,
+  87, 59, 78, 80, 87, 88, 79, 83, 81, 85,
+  71, 78, 76, 85, 69, 90, 83, 88, 67, 72,
+  86, 63, 87, 83, 90, 104, 92, 87, 83, 75,
+  92, 63, 78, 83, 88, 78, 97, 88, 103, 88,
+  76, 88, 106, 69, 97, 75, 73, 102, 83, 82,
+  75, 69, 95, 68, 82, 106, 82, 94, 78, 77,
+  86, 89, 80, 86, 73, 76, 105, 78, 77, 89,
+  78, 83, 89, 90, 93, 83, 73, 95, 87, 91,
+  99, 86, 78, 82, 95, 80, 86, 79, 70, 80,
+  79, 75, 73, 94, 83, 84, 85, 84, 77, 85,
+  83, 81, 79, 81, 77, 87, 76, 72, 92, 79,
+  93, 90, 97, 91, 83, 75, 65, 83, 81, 87,
+  88, 80, 83, 80, 83, 80, 90, 80, 86, 100,
+  77, 88, 84, 84, 81, 92, 96, 77, 79, 80,
+  67, 90, 83, 84, 82, 80, 60, 87, 88, 77,
+  76, 71, 81, 83, 75, 120, 84, 91, 76, 83,
+  86, 77, 76, 76, 76, 74, 76, 78, 93, 106,
+  94, 112, 91, 66, 88, 88, 87, 91, 77, 80,
+  86, 91, 65, 78, 95, 73, 88, 93, 87, 66,
+  98, 87, 97, 85, 86, 76, 62, 71, 64, 76,
+  73, 94, 76, 89, 86, 91, 85, 102, 75, 85,
+  91, 77, 96, 84, 82, 85, 75, 75, 80, 90,
+  77, 87, 82, 82, 66, 90, 81, 93, 86, 83,
+  85, 98, 85, 82, 88, 84, 87, 94, 75, 86,
+  84, 80, 83, 74, 70, 82, 81, 91, 99, 60,
+  76, 77, 89, 79, 86, 85, 78, 86, 77, 85,
+  100, 82, 76, 89, 84, 87, 75, 92, 73, 71,
+  71, 94, 79, 90, 123, 88, 95, 85, 70, 85,
+  81, 87, 75, 66, 80, 93, 75, 89, 84, 78,
+  78, 92, 77, 81, 85, 85, 89, 95, 88, 101,
+  83, 78, 89, 87, 93, 84, 86, 80, 83, 89,
+  69, 85, 98, 114, 79, 94, 88, 76, 104, 76,
+  88, 89, 78, 74, 68, 74, 64, 81, 73, 98,
+  71, 82, 86, 99, 94, 98, 80, 72, 85, 81,
+  86, 94, 75, 81, 89, 85, 75, 87, 80, 77,
+  77, 85, 102, 89, 88, 86, 71, 82, 79, 95,
+  83, 79, 87, 85, 78, 74, 62, 84, 74, 102,
+  81, 77, 83, 80, 73, 89, 79, 89, 71, 89,
+  91, 90, 82, 89, 92, 69, 73, 82, 92, 82,
+  80, 79, 91, 81, 84, 78, 77, 81, 71, 88,
+  78, 89, 102, 71, 87, 82, 85, 84, 78, 89,
+  87, 78, 86, 81, 88, 78, 80, 83, 78, 98,
+  95, 93, 94, 83, 77, 78, 103, 76, 87, 79,
+  77, 88, 77, 83, 96, 77, 82, 77, 72, 102,
+  87, 98, 83, 81, 82, 90, 91, 74, 73, 78,
+  97, 80, 91, 92, 77, 86, 81, 86, 86, 75,
+  84, 97, 93, 87, 99, 71, 83, 81, 86, 87,
+  80, 81, 87, 88, 92, 74, 81, 80, 86, 91,
+  85, 82, 83, 83, 95, 79, 88, 91, 71, 83,
+  75, 81, 74, 70, 115, 96, 64, 93, 90, 76,
+  87, 91, 77, 84, 94, 84, 56, 81, 72, 84,
+  85, 102, 110, 95, 100, 82, 78, 73, 89, 79,
+  127, 122, 102, 91, 81, 84, 80, 92, 104, 97,
+  91, 67, 115, 76, 75, 100, 69, 112, 94, 118,
+  77, 88, 75, 99, 88, 79, 110, 87, 89, 73,
+  106, 82, 72, 76, 80, 64, 69, 54, 74, 93,
+  70, 89, 94, 86, 85, 93, 65, 80, 85, 80,
+  94, 64, 86, 71, 96, 101, 74, 92, 92, 91,
+  74, 88, 86, 80, 96, 89, 89, 77, 80, 64,
+  103, 81, 91, 91, 99, 85, 89, 86, 91, 80,
+  80, 68, 81, 94, 74, 93, 80, 90, 103, 92,
+  89, 95, 77, 72, 98, 74, 89, 85, 77, 92,
+  72, 68, 104, 87, 90, 95, 88, 86, 73, 86,
+  78, 80, 89, 96, 72, 75, 85, 88, 88, 88,
+  111, 69, 100, 80, 92, 90, 75, 85, 106, 122,
+  82, 79, 81, 77, 79, 88, 82, 84, 91, 82,
+  83, 79, 68, 79, 78, 92, 79, 102, 84, 84,
+  83, 84, 80, 90, 90, 70, 86, 75, 79, 86,
+  77, 77, 87, 42, 72, 62, 80, 72, 71, 78,
+  75, 84, 85, 89, 77, 68, 75, 84, 76, 98,
+  86, 84, 87, 99, 76, 80, 97, 85, 83, 88,
+  73, 65, 71, 97, 75, 84, 86, 75, 89, 79,
+  73, 73, 84, 85, 81, 74, 84, 77, 84, 79,
+  95, 83, 87, 93, 70, 73, 106, 85, 74, 81,
+  89, 82, 97, 82, 76, 90, 86, 85, 83, 68,
+  81, 83, 99, 69, 81, 91, 77, 76, 84, 83,
+  93, 94, 86, 65, 94, 91, 87, 75, 97, 75,
+  87, 79, 94, 86, 69, 83, 95, 96, 74, 78,
+  82, 74, 76, 76, 61, 78, 102, 103, 67, 88,
+  72, 79, 78, 74, 78, 80, 89, 86, 89, 90,
+  81, 96, 63, 81, 80, 80, 72, 86, 87, 81,
+  85, 57, 79, 91, 93, 80, 78, 75, 72, 87,
+  77, 76, 91, 70, 80, 80, 78, 107, 82, 91,
+  81, 85, 89, 70, 97, 87, 83, 88, 78, 62,
+  71, 92, 72, 90, 90, 98, 93, 84, 76, 66,
+  74, 84, 83, 82, 84, 81, 74, 88, 83, 82,
+  92, 92, 73, 80, 91, 88, 75, 72, 88, 89,
+  70, 85, 67, 97, 85, 81, 77, 72, 100, 90,
+  82, 83, 89, 86, 79, 91, 83, 82, 84, 88,
+  65, 74, 78, 85, 88, 85, 109, 90, 97, 78,
+  88, 86, 84, 88, 99, 116, 87, 84, 77, 76,
+  67, 79, 72, 79, 96, 70, 88, 53, 73, 81,
+  76, 89, 83, 86, 84, 86, 69, 85, 80, 85,
+  90, 89, 82, 86, 84, 90, 83, 85, 93, 83,
+  69, 65, 76, 80, 62, 89, 71, 75, 91, 93,
+  68, 72, 75, 80, 92, 67, 91, 76, 85, 100,
+  71, 92, 85, 86, 78, 83, 85, 69, 76, 90,
+  74, 87, 81, 68, 75, 84, 79, 78, 91, 75,
+  77, 84, 79, 88, 106, 74, 83, 85, 84, 82,
+  78, 82, 113, 82, 85, 96, 93, 84, 96, 80,
+  83, 88, 83, 78, 77, 78, 88, 82, 90, 68,
+  87, 91, 86, 86, 90, 89, 83, 92, 89, 76,
+  93, 89, 92, 78, 98, 81, 77, 77, 98, 83,
+  75, 88, 88, 94, 81, 80, 88, 75, 80, 83,
+  63, 81, 108, 90, 72, 74, 67, 76, 92, 73,
+  80, 71, 86, 85, 94, 84, 75, 95, 82, 86,
+  83, 99, 79, 87, 82, 92, 93, 71, 67, 93,
+  86, 71, 72, 77, 70, 85, 83, 79, 84, 71,
+  81, 87, 64, 98, 90, 92, 80, 87, 93, 89,
+  84, 80, 90, 80, 78, 62, 75, 95, 71, 93,
+  83, 91, 74, 88, 77, 63, 88, 79, 79, 83,
+  81, 94, 88, 83, 94, 84, 93, 79, 78, 78,
+  81, 86, 84, 82, 90, 93, 69, 84, 67, 88,
+  89, 76, 84, 81, 80, 85, 79, 84, 78, 90,
+  92, 81, 91, 85, 93, 84, 92, 74, 91, 95,
+  77, 75, 84, 89, 86, 80, 94, 76, 76, 83,
+  77, 82, 78, 85, 82, 78, 87, 85, 75, 86,
+  99, 89, 74, 101, 84, 81, 84, 77, 88, 82,
+  87, 91, 91, 85, 85, 88, 76, 84, 84, 100,
+  80, 75, 89, 92, 84, 89, 91, 110, 95, 70,
+  80, 84, 79, 89, 78, 82, 88, 79, 89, 88,
+  65, 95, 86, 88, 76, 84, 95, 80, 82, 88,
+  81, 77, 78, 77, 85, 80, 78, 89, 80, 97,
+  84, 89, 90, 80, 80, 82, 80, 89, 84, 89,
+  64, 90, 75, 88, 94, 85, 82, 91, 80, 87,
+  86, 83, 79, 88, 61, 80, 70, 81, 89, 88,
+  78, 71, 94, 88, 82, 96, 81, 85, 76, 84,
+  89, 87, 83, 86, 81, 74, 79, 100, 86, 79,
+  101, 79, 83, 83, 100, 83, 82, 87, 97, 102,
+  90, 83, 78, 77, 71, 82, 62, 81, 103, 82,
+  76, 58, 69, 76, 86, 83, 92, 66, 88, 82,
+  89, 85, 78, 90, 73, 94, 74, 94, 81, 93,
+  86, 84, 88, 92, 83, 83, 91, 74, 63, 76,
+  85, 80, 87, 84, 76, 69, 77, 83, 72, 80,
+  89, 92, 79, 96, 75, 89, 87, 82, 90, 85,
+  76, 73, 77, 96, 72, 91, 79, 82, 66, 83,
+  81, 71, 87, 77, 85, 84, 74, 88, 92, 89,
+  97, 89, 88, 81, 77, 80, 108, 82, 83, 86,
+  94, 88, 71, 83, 72, 89, 84, 73, 84, 75,
+  84, 87, 82, 74, 81, 85, 86, 84, 89, 94,
+  84, 84, 95, 76, 88, 96, 82, 77, 82, 79,
+  80, 79, 100, 79, 84, 85, 81, 99, 85, 82,
+  88, 77, 91, 79, 76, 83, 102, 91, 76, 93,
+  77, 80, 99, 70, 87, 67, 92, 80, 92, 82,
+  84, 90, 81, 89, 85, 99, 81, 84, 82, 96,
+  88, 87, 80, 106, 87, 78, 71, 86, 74, 94,
+  81, 76, 87, 77, 90, 83, 60, 91, 84, 91,
+  74, 85, 92, 86, 79, 84, 88, 80, 77, 76,
+  88, 98, 78, 92, 84, 96, 73, 90, 86, 71,
+  84, 84, 84, 85, 83, 89, 81, 90, 91, 89,
+  93, 77, 83, 83, 71, 90, 85, 86, 85, 90,
+  54, 84, 66, 83, 85, 82, 87, 83, 79, 91,
+  76, 87, 76, 83, 93, 85, 86, 86, 96, 78,
+  88, 76, 85, 99, 76, 78, 81, 84, 92, 83,
+  99, 75, 92, 82, 69, 92, 86, 87, 86, 82,
+  95, 80, 85, 77, 86, 81, 81, 111, 91, 83,
+  85, 74, 100, 82, 86, 86, 84, 76, 93, 82,
+  86, 89, 87, 100, 82, 82, 84, 96, 96, 97,
+  97, 102, 83, 82, 73, 93, 84, 98, 80, 83,
+  91, 84, 92, 86, 77, 77, 80, 87, 79, 90,
+  92, 74, 80, 86, 85, 80, 86, 92, 97, 89,
+  89, 85, 76, 86, 82, 84, 92, 90, 80, 83,
+  83, 84, 86, 93, 77, 87, 76, 93, 88, 85,
+  84, 84, 79, 85, 90, 87, 76, 85, 68, 77,
+  81, 75, 85, 92, 107, 78, 97, 92, 71, 103,
+  76, 79, 69, 90, 76, 88, 86, 74, 73, 85,
+  85, 85, 93, 76, 86, 70, 106, 87, 94, 77,
+  83, 85, 93, 95, 87, 86, 80, 73, 90, 88,
+  91, 77, 66, 82, 79, 89, 70, 88, 81, 86,
+  81, 84, 77, 78, 99, 90, 91, 79, 89, 99,
+  82, 90, 60, 81, 73, 73, 87, 79, 95, 61,
+  83, 89, 86, 66, 85, 85, 68, 77, 76, 80,
+  86, 107, 96, 96, 81, 96, 76, 72, 72, 76,
+  94, 81, 107, 69, 67, 80, 84, 72, 87, 78,
+  83, 83, 89, 80, 86, 91, 75, 86, 97, 95,
+  72, 83, 83, 79, 81, 74, 92, 79, 109, 103,
+  87, 92, 85, 79, 108, 68, 84, 91, 81, 100,
+  91, 83, 123, 94, 102, 92, 73, 83, 74, 81,
+  72, 83, 76, 95, 106, 88, 76, 84, 82, 72,
+  89, 67, 80, 82, 81, 84, 83, 77, 85, 83,
+  92, 91, 92, 98, 79, 81, 90, 79, 94, 77,
+  83, 76, 74, 85, 82, 92, 80, 73, 85, 93,
+  76, 73, 93, 108, 93, 90, 83, 114, 77, 84,
+  49, 84, 76, 67, 89, 78, 87, 60, 89, 74,
+  89, 61, 99, 87, 54, 80, 79, 72, 84, 88,
+  101, 97, 79, 110, 88, 82, 73, 86, 79, 83,
+  125, 73, 68, 80, 79, 67, 71, 75, 91, 74,
+  90, 82, 83, 82, 74, 85, 98, 95, 78, 88,
+  98, 76, 89, 70, 91, 75, 112, 96, 80, 101,
+  93, 85, 98, 70, 81, 89, 80, 92, 86, 95,
+  97, 97, 88, 93, 74, 104, 77, 80, 64, 89,
+  81, 84, 86, 86, 71, 86, 83, 85, 99, 80,
+  76, 74, 97, 86, 85, 78, 84, 83, 94, 87,
+  84, 99, 77, 84, 90, 82, 92, 73, 73, 81,
+  84, 83, 82, 91, 82, 75, 80, 106, 77, 81,
+  101, 81, 90, 87, 95, 92, 89, 88, 66, 82,
+  78, 81, 88, 85, 100, 62, 90, 85, 73, 73,
+  95, 88, 69, 78, 88, 82, 83, 80, 96, 90,
+  83, 96, 80, 90, 78, 80, 86, 81, 103, 83,
+  70, 84, 85, 75, 83, 78, 87, 81, 84, 72,
+  87, 80, 77, 83, 97, 90, 80, 85, 84, 79,
+  68, 80, 90, 94, 102, 91, 83, 92, 89, 92,
+  88, 74, 79, 94, 86, 90, 91, 84, 96, 77,
+  99, 84, 87, 95, 69, 77, 88, 87, 78, 89,
+  83, 82, 74, 75, 74, 72, 75, 77, 93, 76,
+  81, 85, 88, 85, 83, 81, 97, 78, 79, 92,
+  87, 86, 85, 95, 75, 85, 57, 78, 74, 88,
+  91, 78, 88, 100, 69, 89, 88, 84, 93, 82,
+  87, 93, 83, 67, 79, 78, 64, 81, 71, 96,
+  68, 79, 82, 86, 85, 98, 86, 49, 88, 90,
+  77, 81, 63, 88, 79, 83, 77, 91, 80, 78,
+  80, 75, 73, 92, 88, 77, 96, 74, 75, 76,
+  86, 81, 90, 90, 78, 90, 76, 97, 73, 100,
+  77, 86, 78, 111, 74, 83, 82, 67, 83, 75,
+  76, 85, 112, 91, 70, 92, 79, 101, 84, 79,
+  80, 80, 83, 89, 81, 86, 90, 79, 89, 78,
+  96, 75, 66, 77, 90, 84, 84, 92, 73, 68,
+  73, 75, 70, 66, 62, 75, 96, 80, 78, 90,
+  80, 82, 91, 78, 100, 83, 68, 86, 83, 87,
+  81, 94, 73, 89, 71, 67, 76, 75, 93, 70,
+  100, 102, 59, 88, 89, 74, 85, 56, 89, 98,
+  64, 100, 86, 70, 61, 81, 70, 105, 63, 81,
+  67, 91, 95, 97, 85, 43, 90, 91, 80, 78,
+  57, 80, 83, 83, 80, 94, 81, 78, 82, 85,
+  76, 100, 81, 77, 72, 77, 74, 73, 80, 72,
+  74, 87, 79, 95, 91, 107, 72, 87, 79, 88,
+  78, 128, 83, 73, 87, 64, 67, 68, 73, 80,
+  108, 100, 85, 99, 76, 119, 80, 82, 71, 79,
+  78, 83, 84, 89, 94, 79, 84, 87, 86, 81,
+  73, 75, 84, 87, 86, 84, 92, 68, 72, 80,
+  76, 74, 77, 82, 92, 75, 97, 87, 79, 84,
+  85, 80, 97, 88, 74, 86, 86, 81, 85, 88,
+  73, 85, 90, 77, 75, 80, 89, 83, 94, 83,
+  64, 88, 88, 84, 96, 69, 87, 96, 82, 118,
+  89, 82, 66, 85, 71, 86, 69, 85, 81, 91,
+  93, 101, 82, 75, 84, 97, 77, 80, 67, 86,
+  80, 84, 78, 84, 83, 79, 82, 83, 77, 92,
+  84, 83, 92, 83, 73, 76, 84, 76, 73, 83,
+  79, 91, 102, 91, 82, 72, 78, 84, 83, 108,
+  88, 78, 87, 65, 59, 78, 79, 83, 91, 94,
+  93, 88, 77, 103, 81, 85, 73, 88, 87, 86,
+  81, 83, 93, 76, 98, 86, 96, 86, 74, 76,
+  83, 85, 76, 86, 88, 85, 63, 86, 80, 85,
+  90, 83, 86, 86, 84, 79, 90, 87, 83, 81,
+  89, 70, 78, 91, 97, 96, 73, 83, 88, 78,
+  74, 91, 78, 90, 82, 83, 86, 98, 81, 88,
+  78, 89, 68, 71, 87, 82, 96, 76, 83, 62,
+  79, 80, 82, 89, 87, 71, 87, 85, 90, 99,
+  76, 83, 98, 81, 86, 86, 76, 88, 69, 66,
+  73, 89, 74, 77, 83, 87, 86, 91, 86, 95,
+  80, 79, 81, 79, 96, 86, 91, 85, 77, 92,
+  80, 82, 89, 94, 79, 81, 68, 94, 97, 95,
+  82, 89, 86, 91, 76, 98, 83, 74, 87, 88,
+  90, 81, 84, 90, 92, 80, 88, 75, 77, 78,
+  92, 78, 95, 77, 105, 71, 75, 77, 89, 87,
+  81, 85, 82, 81, 65, 86, 81, 86, 82, 84,
+  92, 96, 79, 76, 86, 91, 77, 83, 86, 69,
+  74, 84, 98, 100, 78, 91, 92, 86, 82, 83,
+  79, 82, 86, 73, 100, 98, 67, 77, 69, 89,
+  62, 57, 87, 84, 79, 78, 83, 66, 74, 87,
+  84, 93, 87, 80, 76, 91, 88, 98, 72, 81,
+  90, 81, 92, 81, 73, 85, 75, 70, 66, 92,
+  75, 69, 83, 89, 83, 90, 85, 87, 65, 78,
+  77, 77, 89, 92, 85, 83, 81, 100, 82, 81,
+  86, 80, 82, 82, 66, 96, 98, 86, 81, 83,
+  78, 90, 70, 87, 82, 63, 96, 92, 95, 87,
+  84, 93, 97, 81, 80, 73, 86, 73, 90, 77,
+  95, 87, 91, 78, 78, 72, 88, 87, 83, 81,
+  88, 87, 67, 86, 80, 86, 87, 84, 85, 89,
+  95, 83, 84, 87, 82, 82, 86, 76, 75, 87,
+  93, 91, 80, 91, 87, 83, 90, 88, 82, 85,
+  79, 78, 85, 95, 74, 76, 77, 88, 65, 73,
+  85, 86, 94, 86, 88, 68, 81, 82, 82, 85,
+  83, 78, 85, 83, 87, 98, 74, 98, 90, 87,
+  83, 85, 77, 90, 75, 76, 69, 85, 75, 76,
+  87, 82, 82, 91, 93, 92, 76, 78, 81, 84,
+  98, 87, 78, 86, 81, 92, 93, 80, 93, 84,
+  79, 80, 73, 97, 99, 84, 77, 85, 75, 93,
+  77, 81, 80, 79, 100, 84, 88, 79, 91, 97,
+  90, 88, 88, 80, 79, 76, 87, 80, 118, 91,
+  82, 87, 75, 71, 101, 89, 86, 81, 97, 76,
+  61, 79, 86, 76, 84, 88, 101, 88, 86, 86,
+  93, 86, 92, 88, 94, 97, 93, 93, 89, 81,
+  99, 104, 97, 94, 88, 70, 93, 84, 106, 73,
+  60, 95, 94, 90, 92, 94, 82, 69, 94, 91,
+  65, 88, 109, 70, 124, 85, 66, 125, 74, 76,
+  74, 76, 83, 91, 91, 60, 93, 101, 86, 81,
+  87, 100, 80, 87, 73, 68, 83, 55, 88, 87,
+  78, 79, 91, 76, 87, 92, 82, 82, 95, 94,
+  78, 94, 80, 78, 95, 83, 75, 84, 89, 88,
+  85, 81, 91, 80, 74, 83, 76, 67, 81, 93,
+  97, 97, 74, 86, 82, 91, 74, 83, 94, 78,
+  91, 89, 71, 76, 78, 76, 113, 97, 75, 84,
+  73, 65, 102, 92, 92, 79, 103, 84, 62, 78,
+  85, 75, 82, 78, 107, 85, 87, 83, 91, 82,
+  86, 91, 85, 94, 92, 89, 85, 86, 98, 102,
+  84, 108, 87, 66, 102, 79, 105, 75, 54, 105,
+  81, 95, 89, 92, 79, 79, 90, 89, 60, 91,
+  100, 68, 129, 89, 67, 128, 72, 78, 87, 78,
+  84, 91, 95, 69, 87, 98, 82, 79, 84, 100,
+  89, 89, 64, 70, 77, 55, 86, 96, 75, 82,
+  93, 86, 79, 88, 85, 93, 93, 95, 77, 93,
+  79, 84, 111, 87, 78, 88, 91, 91, 84, 87,
+  90, 78, 69, 77, 82, 69, 80, 97, 95, 101,
+  94, 95, 86, 85, 75, 84, 91, 72, 89, 89,
+  71, 74, 87, 73, 94, 94, 84, 80, 72, 69,
+  100, 89, 91, 76, 91, 83, 58, 84, 91, 76,
+  84, 81, 98, 88, 85, 81, 84, 84, 88, 87,
+  91, 101, 93, 85, 89, 80, 98, 91, 87, 85,
+  82, 76, 93, 81, 103, 77, 66, 95, 80, 84,
+  94, 90, 87, 82, 93, 86, 67, 93, 105, 72,
+  117, 87, 65, 102, 82, 70, 78, 79, 81, 92,
+  89, 67, 79, 96, 88, 86, 84, 98, 81, 90,
+  65, 70, 80, 57, 95, 87, 75, 80, 94, 73,
+  82, 97, 82, 81, 94, 94, 83, 86, 79, 83,
+  106, 78, 79, 79, 89, 87, 83, 84, 88, 80,
+  70, 83, 80, 76, 83, 94, 91, 103, 84, 83,
+  78, 91, 72, 87, 93, 81, 88, 92, 77, 81,
+  87, 73, 77, 72, 81, 73, 101, 86, 84, 84,
+  90, 85, 77, 87, 65, 74, 72, 84, 75, 76,
+  110, 79, 85, 74, 86, 114, 84, 80, 92, 100,
+  82, 95, 87, 71, 84, 80, 108, 83, 78, 57,
+  95, 74, 112, 87, 78, 77, 72, 74, 94, 76,
+  93, 74, 90, 85, 74, 89, 110, 79, 98, 78,
+  81, 90, 95, 75, 63, 79, 77, 81, 73, 71,
+  69, 77, 99, 102, 75, 94, 76, 85, 93, 69,
+  85, 71, 86, 69, 85, 72, 82, 70, 89, 77,
+  79, 77, 83, 85, 74, 69, 84, 87, 78, 86,
+  78, 79, 92, 86, 79, 71, 82, 96, 97, 81,
+  72, 65, 75, 71, 99, 87, 70, 84, 83, 100,
+  75, 74, 89, 92, 81, 74, 69, 92, 81, 70,
+  75, 77, 77, 72, 102, 80, 84, 84, 91, 86,
+  75, 87, 66, 71, 78, 84, 71, 74, 119, 76,
+  82, 66, 89, 105, 81, 82, 88, 106, 82, 95,
+  91, 73, 81, 76, 107, 82, 82, 56, 97, 74,
+  110, 91, 68, 86, 65, 76, 93, 76, 94, 87,
+  87, 85, 75, 90, 110, 76, 101, 77, 76, 94,
+  108, 72, 69, 79, 70, 86, 73, 76, 64, 77,
+  97, 92, 75, 95, 76, 80, 93, 73, 82, 75,
+  89, 73, 83, 77, 74, 74, 83, 78, 84, 79,
+  78, 85, 73, 67, 81, 87, 83, 90, 84, 73,
+  87, 88, 77, 71, 82, 94, 94, 77, 79, 61,
+  74, 77, 104, 96, 73, 86, 79, 93, 74, 77,
+  88, 88, 84, 76, 62, 91, 90, 71, 72, 76,
+  82, 74, 96, 75, 90, 86, 86, 78, 75, 76,
+  66, 79, 75, 86, 74, 75, 103, 80, 81, 75,
+  83, 106, 78, 78, 88, 104, 87, 97, 92, 70,
+  87, 79, 97, 81, 87, 69, 91, 78, 97, 90,
+  81, 85, 70, 80, 93, 75, 93, 81, 91, 84,
+  75, 82, 102, 77, 91, 83, 76, 79, 92, 75,
+  70, 83, 76, 80, 77, 77, 62, 82, 93, 98,
+  80, 94, 76, 80, 77, 74, 83, 71, 90, 75,
+  82, 78, 70, 77, 82, 79, 82, 78, 85, 90,
+  73, 67, 85, 85, 85, 85, 86, 70, 91, 84,
+  86, 77, 88, 90, 91, 83, 85, 69, 80, 84,
+  91, 91, 64, 85, 81, 95, 76, 77, 84, 91,
+  81, 81, 76, 90, 101, 67, 63, 80, 96, 96,
+  89, 91, 77, 77, 83, 83, 90, 86, 88, 87,
+  67, 109, 84, 79, 83, 84, 74, 80, 87, 111,
+  84, 76, 78, 97, 83, 89, 91, 74, 85, 77,
+  79, 84, 86, 85, 91, 72, 86, 88, 95, 62,
+  77, 77, 85, 78, 93, 82, 84, 79, 84, 83,
+  88, 97, 63, 79, 95, 75, 80, 91, 77, 96,
+  74, 81, 74, 75, 89, 73, 99, 104, 87, 89,
+  70, 81, 94, 77, 89, 66, 84, 72, 95, 71,
+  86, 84, 84, 77, 64, 91, 69, 83, 80, 71,
+  96, 97, 79, 84, 82, 92, 92, 86, 81, 79,
+  82, 92, 78, 105, 108, 86, 90, 73, 75, 82,
+  62, 79, 85, 78, 78, 84, 77, 93, 83, 80,
+  94, 87, 96, 76, 76, 77, 97, 80, 90, 90,
+  77, 78, 81, 83, 83, 88, 93, 82, 71, 110,
+  85, 82, 78, 79, 83, 82, 87, 106, 79, 76,
+  77, 99, 83, 93, 93, 72, 86, 64, 77, 82,
+  91, 84, 86, 77, 86, 87, 91, 64, 76, 75,
+  88, 76, 101, 91, 81, 82, 85, 82, 92, 89,
+  63, 76, 93, 75, 80, 91, 78, 95, 79, 78,
+  78, 80, 76, 73, 96, 93, 88, 89, 73, 78,
+  91, 85, 85, 76, 87, 74, 94, 75, 76, 91,
+  86, 81, 67, 82, 67, 88, 76, 70, 93, 95,
+  77, 88, 82, 78, 92, 87, 75, 82, 83, 88,
+  82, 101, 113, 80, 87, 77, 80, 90, 59, 79,
+  83, 73, 78, 83, 79, 92, 87, 83, 94, 89,
+  96, 79, 86, 78, 91, 76, 80, 83, 78, 80,
+  82, 82, 87, 72, 91, 84, 67, 101, 80, 85,
+  74, 88, 94, 79, 86, 101, 78, 77, 70, 97,
+  82, 94, 88, 68, 91, 71, 79, 84, 93, 84,
+  95, 73, 85, 89, 100, 69, 79, 82, 85, 74,
+  87, 85, 80, 79, 85, 81, 88, 88, 64, 80,
+  87, 76, 78, 93, 84, 94, 76, 80, 74, 88,
+  66, 79, 95, 99, 91, 87, 72, 82, 85, 79,
+  85, 72, 84, 85, 87, 78, 70, 90, 80, 78,
+  64, 82, 74, 88, 77, 68, 93, 92, 75, 84,
+  86, 71, 94, 85, 85, 80, 87, 90, 75, 100,
+  105, 83, 89, 83, 83, 86, 68, 83, 88, 79,
+  83, 81, 70, 94, 84, 84, 95, 86, 74, 86,
+  78, 79, 73, 82, 124, 115, 55, 90, 89, 85,
+  82, 78, 71, 90, 93, 66, 77, 92, 72, 93,
+  92, 65, 78, 73, 80, 88, 87, 83, 75, 75,
+  98, 72, 79, 92, 75, 86, 88, 80, 75, 78,
+  75, 82, 77, 110, 79, 75, 76, 83, 77, 81,
+  105, 88, 90, 81, 83, 72, 98, 80, 85, 79,
+  83, 86, 84, 81, 76, 69, 75, 83, 82, 76,
+  89, 77, 87, 98, 142, 81, 84, 90, 133, 74,
+  81, 87, 73, 86, 78, 81, 99, 69, 84, 86,
+  75, 88, 84, 86, 73, 95, 74, 89, 116, 72,
+  85, 115, 83, 90, 101, 81, 76, 74, 73, 76,
+  70, 80, 79, 73, 81, 77, 94, 73, 86, 81,
+  66, 86, 83, 79, 79, 86, 77, 80, 84, 82,
+  74, 78, 120, 101, 52, 84, 87, 89, 91, 87,
+  78, 92, 93, 68, 76, 86, 79, 99, 79, 67,
+  75, 73, 75, 81, 81, 82, 81, 75, 85, 75,
+  81, 80, 78, 85, 80, 81, 79, 78, 80, 76,
+  76, 112, 87, 81, 76, 84, 71, 75, 99, 86,
+  84, 80, 74, 69, 93, 83, 91, 82, 84, 84,
+  78, 76, 76, 75, 81, 76, 78, 78, 86, 72,
+  92, 89, 139, 80, 87, 92, 120, 69, 90, 91,
+  73, 89, 84, 71, 96, 83, 78, 88, 72, 100,
+  93, 85, 67, 100, 77, 86, 107, 76, 86, 112,
+  75, 88, 99, 78, 74, 68, 81, 74, 72, 84,
+  83, 78, 75, 76, 102, 76, 80, 80, 73, 91,
+  82, 79, 76, 92, 73, 75, 83, 82, 73, 87,
+  123, 101, 58, 87, 84, 83, 82, 88, 76, 88,
+  95, 64, 76, 87, 78, 91, 83, 71, 70, 77,
+  82, 87, 80, 81, 79, 72, 98, 77, 88, 81,
+  77, 87, 75, 80, 74, 85, 73, 85, 77, 111,
+  75, 80, 75, 82, 79, 78, 105, 85, 91, 77,
+  90, 70, 96, 73, 87, 76, 83, 83, 82, 78,
+  78, 74, 79, 77, 78, 72, 87, 77, 91, 101,
+  140, 89, 89, 89, 130, 75, 87, 88, 74, 84,
+  84, 87, 96, 73, 84, 87, 78, 93, 91, 86,
+  71, 96, 71, 85, 113, 78, 85, 102, 82, 92,
+  101, 82, 77, 78, 80, 75, 75, 79, 81, 72,
+  78, 79, 92, 68, 85, 80, 67, 84, 82, 80,
+  78, 87, 86, 87, 83, 79, 81, 84, 108, 110,
+  59, 87, 89, 84, 78, 88, 79, 90, 92, 64,
+  85, 90, 80, 90, 92, 66, 83, 69, 80, 87,
+  83, 76, 85, 73, 89, 83, 82, 90, 80, 80,
+  81, 76, 70, 71, 86, 79, 81, 109, 82, 77,
+  70, 79, 80, 78, 101, 87, 79, 76, 78, 76,
+  92, 82, 93, 73, 84, 80, 86, 77, 80, 74,
+  74, 77, 78, 82, 79, 75, 80, 94, 135, 86,
+  85, 93, 119, 80, 79, 84, 72, 79, 79, 79,
+  96, 86, 90, 86, 76, 89, 91, 89, 79, 104,
+  82, 88, 103, 74, 89, 108, 85, 87, 102, 78,
+  82, 77, 79, 70, 70, 85, 82, 79, 80, 74,
+  97, 72, 91, 82, 65, 90, 83, 87, 79, 95,
+  95, 83, 83, 88, 81, 80, 109, 99, 58, 86,
+  92, 92, 95, 91, 86, 97, 93, 67, 89, 87,
+  87, 98, 72, 67, 84, 67, 73, 84, 75, 83,
+  89, 76, 81, 82, 82, 81, 81, 81, 91, 78,
+  73, 80, 89, 77, 80, 107, 91, 82, 75, 83,
+  76, 76, 94, 84, 74, 86, 71, 76, 84, 87,
+  96, 72, 84, 90, 77, 81, 79, 83, 77, 72,
+  80, 91, 72, 76, 85, 85, 133, 78, 83, 96,
+  107, 77, 85, 86, 75, 82, 81, 71, 96, 87,
+  87, 80, 73, 108, 97, 85, 83, 112, 87, 84,
+  87, 79, 98, 104, 88, 93, 100, 78, 84, 72,
+  88, 68, 77, 85, 82, 83, 76, 75, 110, 77,
+  79, 82, 73, 98, 84, 90, 84, 103, 78, 79,
+  83, 85, 79, 93, 104, 91, 62, 83, 87, 80,
+  80, 85, 80, 91, 92, 66, 85, 87, 83, 82,
+  85, 73, 75, 73, 80, 86, 79, 83, 81, 71,
+  88, 80, 78, 84, 75, 78, 85, 76, 72, 71,
+  76, 83, 80, 109, 81, 81, 71, 78, 82, 73,
+  101, 85, 80, 86, 86, 76, 93, 73, 91, 73,
+  83, 77, 85, 74, 83, 76, 75, 77, 77, 74,
+  77, 80, 83, 97, 128, 85, 87, 86, 116, 76,
+  80, 92, 72, 78, 85, 88, 95, 92, 92, 85,
+  79, 89, 91, 88, 77, 97, 76, 85, 109, 81,
+  88, 92, 86, 87, 102, 80, 78, 80, 75, 70,
+  73, 82, 77, 74, 82, 73, 91, 70, 91, 78,
+  68, 88, 82, 87, 80, 93, 81, 90, 84, 77,
+  87, 82, 106, 105, 52, 87, 88, 79, 79, 95,
+  86, 90, 94, 59, 75, 84, 75, 94, 78, 69,
+  80, 74, 81, 85, 87, 76, 80, 69, 94, 83,
+  76, 86, 75, 70, 70, 80, 71, 81, 79, 88,
+  82, 113, 77, 83, 69, 77, 86, 92, 111, 88,
+  87, 72, 78, 78, 93, 73, 98, 74, 78, 88,
+  89, 90, 82, 68, 72, 84, 79, 72, 75, 74,
+  82, 99, 138, 78, 88, 91, 124, 72, 77, 84,
+  71, 72, 74, 84, 90, 84, 89, 95, 77, 85,
+  88, 100, 79, 101, 78, 91, 105, 79, 87, 114,
+  89, 85, 98, 77, 81, 84, 84, 73, 78, 86,
+  85, 76, 79, 76, 90, 75, 90, 83, 62, 91,
+  79, 83, 76, 87, 83, 81, 80, 85, 86, 73,
+  99, 105, 54, 85, 92, 92, 85, 84, 86, 92,
+  90, 63, 79, 81, 81, 92, 76, 66, 78, 69,
+  83, 85, 85, 86, 74, 70, 90, 82, 74, 80,
+  76, 70, 85, 77, 77, 72, 76, 82, 80, 118,
+  80, 82, 75, 77, 83, 83, 102, 87, 85, 83,
+  82, 77, 85, 76, 100, 77, 78, 84, 87, 86,
+  82, 71, 69, 89, 79, 75, 76, 83, 82, 98,
+  126, 78, 85, 87, 110, 70, 75, 98, 70, 74,
+  77, 80, 87, 86, 98, 94, 74, 91, 95, 94,
+  82, 101, 79, 91, 109, 79, 90, 112, 87, 90,
+  100, 77, 84, 83, 84, 73, 78, 84, 82, 74,
+  85, 74, 93, 80, 87, 85, 66, 95, 77, 89,
+  78, 92, 74, 77, 77, 79, 84, 77, 108, 91,
+  57, 85, 89, 77, 86, 83, 87, 90, 91, 64,
+  76, 81, 82, 86, 91, 75, 79, 77, 78, 83,
+  87, 81, 79, 68, 90, 80, 75, 80, 73, 74,
+  98, 79, 76, 83, 67, 89, 82, 108, 77, 76,
+  72, 74, 88, 83, 111, 88, 88, 96, 83, 81,
+  95, 73, 96, 76, 77, 86, 87, 92, 81, 69,
+  74, 91, 85, 72, 71, 78, 80, 99, 139, 83,
+  81, 88, 121, 71, 77, 92, 75, 74, 78, 93,
+  93, 91, 90, 89, 77, 86, 82, 98, 75, 98,
+  77, 90, 108, 74, 87, 99, 90, 85, 97, 76,
+  78, 85, 74, 72, 75, 73, 80, 74, 82, 76,
+  89, 78, 93, 82, 66, 87, 79, 86, 78, 85,
+  80, 83, 88, 82, 76, 89, 99, 81, 82, 92,
+  80, 84, 86, 75, 81, 87, 84, 96, 95, 92,
+  79, 97, 87, 81, 86, 93, 82, 81, 87, 77,
+  96, 76, 89, 80, 93, 74, 68, 82, 77, 92,
+  91, 72, 81, 104, 75, 86, 90, 82, 75, 90,
+  66, 115, 96, 77, 94, 55, 92, 89, 73, 93,
+  93, 74, 72, 68, 85, 78, 81, 88, 95, 92,
+  65, 69, 82, 88, 102, 83, 89, 98, 98, 76,
+  98, 77, 73, 84, 96, 73, 83, 82, 86, 78,
+  79, 64, 78, 74, 80, 85, 81, 80, 84, 75,
+  72, 77, 87, 87, 88, 82, 75, 102, 92, 88,
+  92, 86, 90, 82, 78, 85, 92, 80, 83, 91,
+  87, 98, 82, 85, 103, 90, 85, 95, 84, 71,
+  88, 75, 86, 79, 80, 82, 73, 88, 77, 84,
+  93, 113, 59, 87, 87, 77, 79, 81, 73, 101,
+  76, 99, 90, 76, 95, 80, 90, 76, 96, 81,
+  79, 76, 88, 88, 71, 69, 72, 95, 80, 104,
+  81, 76, 85, 82, 90, 79, 87, 78, 88, 91,
+  93, 76, 72, 51, 94, 63, 81, 79, 87, 85,
+  82, 72, 51, 79, 113, 77, 85, 73, 38, 78,
+  83, 89, 81, 78, 81, 124, 89, 91, 80, 83,
+  87, 89, 76, 75, 85, 78, 66, 86, 80, 67,
+  83, 81, 79, 78, 90, 85, 84, 98, 65, 87,
+  82, 80, 85, 82, 66, 86, 101, 72, 98, 70,
+  82, 92, 83, 94, 90, 86, 88, 81, 84, 83,
+  85, 79, 73, 89, 84, 103, 92, 74, 90, 83,
+  87, 74, 68, 84, 80, 84, 74, 81, 83, 126,
+  54, 95, 90, 71, 79, 77, 80, 91, 81, 87,
+  84, 62, 87, 84, 96, 84, 89, 92, 82, 82,
+  94, 89, 88, 80, 91, 68, 84, 85, 87, 75,
+  88, 82, 83, 95, 91, 65, 113, 90, 85, 80,
+  62, 80, 90, 75, 97, 80, 72, 94, 103, 74,
+  69, 80, 100, 82, 78, 80, 48, 73, 93, 93,
+  67, 86, 64, 117, 98, 90, 79, 94, 76, 92,
+  68, 94, 84, 84, 67, 80, 83, 92, 85, 83,
+  102, 85, 89, 92, 88, 98, 88, 104, 88, 79,
+  87, 88, 79, 82, 89, 69, 88, 73, 72, 99,
+  96, 96, 92, 94, 81, 77, 85, 75, 83, 74,
+  71, 95, 84, 81, 76, 81, 74, 82, 75, 87,
+  100, 82, 86, 95, 88, 82, 96, 60, 85, 92,
+  82, 98, 92, 89, 81, 96, 84, 80, 77, 85,
+  79, 85, 89, 77, 95, 71, 98, 85, 100, 80,
+  65, 80, 81, 85, 81, 75, 87, 99, 80, 90,
+  85, 83, 76, 89, 66, 102, 86, 80, 93, 67,
+  87, 89, 74, 95, 90, 78, 59, 69, 72, 81,
+  84, 87, 94, 64, 95, 80, 79, 90, 105, 86,
+  85, 114, 84, 74, 93, 75, 85, 78, 89, 72,
+  85, 86, 79, 79, 82, 73, 79, 71, 82, 80,
+  87, 79, 89, 80, 76, 76, 80, 88, 86, 79,
+  76, 95, 85, 93, 91, 96, 85, 75, 53, 74,
+  78, 82, 82, 84, 70, 93, 90, 90, 100, 81,
+  85, 102, 102, 69, 54, 80, 78, 72, 86, 82,
+  74, 93, 93, 79, 97, 80, 56, 84, 78, 76,
+  83, 72, 67, 104, 72, 90, 85, 79, 90, 85,
+  87, 83, 84, 80, 87, 80, 123, 90, 100, 78,
+  101, 80, 91, 104, 87, 73, 95, 70, 79, 65,
+  84, 78, 87, 75, 80, 84, 85, 65, 87, 64,
+  72, 83, 84, 92, 79, 79, 36, 94, 93, 83,
+  83, 63, 64, 85, 91, 76, 84, 78, 83, 153,
+  89, 88, 73, 74, 92, 80, 73, 75, 79, 93,
+  64, 96, 78, 76, 87, 74, 92, 78, 90, 86,
+  80, 98, 70, 82, 81, 84, 72, 75, 65, 82,
+  92, 76, 81, 80, 78, 80, 67, 83, 79, 86,
+  92, 85, 64, 81, 80, 84, 69, 74, 81, 114,
+  104, 67, 68, 86, 82, 75, 74, 80, 76, 85,
+  74, 83, 79, 100, 48, 75, 78, 64, 80, 65,
+  72, 78, 80, 86, 84, 72, 90, 85, 89, 93,
+  78, 100, 80, 81, 88, 83, 94, 83, 112, 61,
+  94, 85, 79, 68, 94, 75, 81, 81, 89, 66,
+  110, 64, 78, 86, 78, 94, 82, 75, 83, 72,
+  78, 103, 111, 85, 65, 86, 92, 84, 84, 84,
+  68, 79, 97, 75, 69, 79, 83, 113, 105, 91,
+  72, 88, 74, 77, 62, 93, 71, 103, 84, 94,
+  81, 93, 87, 73, 99, 78, 86, 93, 73, 95,
+  84, 105, 83, 84, 83, 87, 79, 82, 95, 77,
+  86, 75, 73, 94, 95, 101, 80, 84, 87, 90,
+  85, 69, 73, 80, 72, 88, 76, 81, 77, 77,
+  82, 91, 79, 78, 94, 79, 86, 90, 84, 80,
+  87, 61, 101, 94, 82, 93, 85, 93, 86, 76,
+  78, 80, 75, 88, 81, 79, 80, 82, 83, 84,
+  93, 83, 95, 75, 83, 85, 69, 80, 86, 73,
+  71, 98, 81, 85, 85, 71, 81, 82, 74, 91,
+  74, 86, 89, 89, 96, 100, 91, 92, 85, 84,
+  82, 80, 103, 77, 89, 87, 83, 93, 102, 84,
+  79, 86, 99, 83, 89, 104, 90, 81, 91, 78,
+  75, 82, 89, 79, 85, 85, 85, 82, 71, 88,
+  89, 87, 88, 87, 83, 84, 86, 83, 88, 92,
+  82, 87, 100, 85, 82, 91, 79, 94, 89, 96,
+  80, 68, 71, 80, 66, 89, 83, 81, 64, 92,
+  78, 86, 100, 86, 86, 85, 83, 80, 68, 91,
+  72, 62, 93, 82, 84, 86, 85, 73, 95, 64,
+  86, 95, 80, 90, 87, 88, 80, 72, 68, 86,
+  71, 94, 95, 77, 79, 88, 79, 88, 90, 73,
+  84, 68, 87, 88, 92, 89, 84, 83, 71, 94,
+  80, 74, 84, 72, 84, 86, 88, 91, 88, 83,
+  81, 98, 90, 87, 87, 82, 84, 76, 89, 89,
+  66, 82, 85, 83, 78, 86, 89, 80, 85, 84,
+  91, 76, 88, 91, 96, 77, 88, 78, 81, 77,
+  93, 84, 78, 77, 95, 98, 70, 91, 79, 81,
+  75, 79, 87, 80, 89, 77, 78, 91, 75, 86,
+  79, 81, 77, 92, 76, 87, 84, 85, 83, 73,
+  78, 73, 57, 85, 87, 78, 65, 89, 80, 86,
+  90, 83, 82, 91, 90, 81, 91, 89, 71, 83,
+  85, 79, 77, 84, 79, 79, 89, 79, 73, 81,
+  79, 87, 86, 87, 84, 79, 97, 87, 74, 94,
+  93, 84, 83, 90, 89, 98, 84, 72, 84, 91,
+  82, 96, 97, 78, 89, 83, 69, 83, 84, 72,
+  90, 89, 87, 83, 95, 85, 91, 83, 79, 99,
+  85, 84, 91, 84, 85, 88, 95, 86, 75, 80,
+  79, 87, 80, 83, 83, 81, 90, 80, 88, 74,
+  95, 100, 94, 78, 89, 85, 77, 93, 86, 88,
+  72, 93, 96, 101, 80, 82, 77, 78, 83, 74,
+  90, 76, 85, 64, 77, 86, 80, 84, 82, 80,
+  95, 87, 84, 95, 88, 77, 84, 91, 90, 90,
+  73, 82, 90, 81, 77, 92, 83, 87, 93, 90,
+  83, 83, 66, 69, 70, 93, 79, 62, 72, 101,
+  96, 76, 83, 84, 73, 89, 77, 89, 84, 76,
+  87, 93, 90, 97, 79, 83, 86, 78, 84, 79,
+  61, 97, 86, 84, 80, 74, 80, 91, 81, 90,
+  77, 70, 94, 82, 75, 92, 58, 82, 94, 130,
+  87, 76, 88, 89, 76, 84, 90, 79, 86, 82,
+  100, 98, 71, 80, 85, 77, 81, 79, 89, 104,
+  92, 77, 84, 78, 85, 76, 86, 73, 68, 82,
+  88, 84, 86, 85, 82, 56, 88, 81, 85, 93,
+  75, 83, 95, 74, 76, 85, 87, 84, 89, 79,
+  97, 90, 79, 79, 86, 81, 76, 82, 79, 88,
+  78, 70, 82, 81, 92, 87, 81, 80, 96, 83,
+  89, 81, 107, 76, 115, 72, 77, 79, 90, 81,
+  90, 70, 72, 83, 89, 67, 76, 83, 80, 87,
+  78, 86, 79, 87, 83, 83, 81, 91, 87, 76,
+  85, 83, 89, 82, 80, 82, 90, 71, 70, 83,
+  87, 70, 80, 86, 78, 89, 82, 77, 78, 75,
+  81, 84, 68, 84, 77, 84, 97, 105, 81, 74,
+  87, 88, 81, 69, 81, 81, 91, 82, 73, 97,
+  78, 68, 82, 76, 77, 87, 80, 88, 85, 78,
+  81, 84, 84, 93, 80, 77, 80, 79, 83, 91,
+  88, 78, 69, 64, 80, 82, 85, 78, 84, 81,
+  63, 78, 76, 88, 83, 82, 79, 79, 99, 66,
+  70, 81, 77, 77, 75, 79, 89, 82, 81, 102,
+  84, 79, 77, 88, 73, 72, 92, 92, 87, 69,
+  107, 92, 70, 81, 81, 84, 81, 83, 98, 80,
+  81, 83, 91, 87, 83, 71, 77, 92, 72, 80,
+  89, 86, 85, 87, 79, 94, 74, 76, 75, 68,
+  88, 86, 93, 81, 85, 75, 80, 84, 88, 84,
+  82, 95, 78, 88, 82, 81, 85, 78, 85, 93,
+  73, 87, 92, 84, 99, 91, 87, 75, 81, 82,
+  86, 63, 81, 83, 90, 84, 72, 91, 81, 76,
+  84, 90, 85, 88, 81, 84, 83, 88, 86, 84,
+  86, 94, 87, 84, 88, 83, 78, 87, 83, 82,
+  65, 74, 87, 83, 82, 76, 88, 66, 62, 95,
+  84, 89, 89, 84, 82, 84, 100, 81, 72, 89,
+  74, 83, 85, 89, 86, 85, 73, 109, 74, 79,
+  81, 86, 79, 86, 78, 92, 89, 76, 89, 96,
+  49, 87, 86, 90, 79, 84, 59, 75, 65, 93,
+  87, 48, 73, 97, 96, 76, 93, 81, 73, 96,
+  74, 83, 73, 71, 98, 102, 109, 105, 95, 79,
+  79, 75, 89, 84, 89, 97, 84, 82, 85, 76,
+  74, 97, 89, 95, 82, 75, 97, 85, 58, 101,
+  64, 87, 78, 156, 90, 79, 86, 110, 81, 99,
+  91, 94, 78, 81, 103, 89, 69, 88, 81, 71,
+  101, 80, 91, 121, 98, 81, 105, 88, 69, 86,
+  91, 74, 66, 83, 92, 79, 86, 80, 89, 56,
+  94, 77, 92, 106, 74, 76, 100, 81, 75, 83,
+  89, 80, 93, 79, 117, 121, 82, 84, 94, 85,
+  105, 99, 79, 89, 83, 50, 87, 91, 103, 88,
+  94, 91, 103, 74, 89, 85, 110, 61, 124, 73,
+  80, 75, 107, 88, 87, 71, 67, 83, 92, 58,
+  78, 90, 71, 83, 80, 78, 82, 91, 79, 84,
+  77, 97, 95, 79, 100, 76, 92, 79, 69, 88,
+  88, 69, 91, 80, 88, 65, 80, 85, 77, 91,
+  87, 73, 68, 80, 75, 85, 63, 81, 80, 91,
+  84, 126, 78, 75, 91, 87, 83, 76, 85, 86,
+  80, 82, 68, 92, 79, 66, 77, 62, 77, 86,
+  78, 95, 88, 74, 89, 87, 90, 97, 84, 77,
+  75, 81, 82, 94, 90, 77, 69, 60, 76, 79,
+  101, 81, 90, 81, 73, 83, 69, 91, 91, 77,
+  78, 79, 106, 68, 67, 91, 76, 81, 85, 82,
+  93, 75, 79, 95, 88, 80, 82, 91, 76, 74,
+  92, 88, 83, 60, 112, 86, 74, 81, 80, 80,
+  84, 84, 91, 77, 80, 76, 90, 79, 84, 74,
+  71, 92, 70, 76, 89, 88, 79, 85, 76, 100,
+  75, 74, 83, 70, 93, 83, 84, 87, 87, 72,
+  78, 85, 91, 70, 90, 89, 83, 87, 85, 80,
+  77, 82, 80, 85, 72, 80, 93, 89, 93, 95,
+  82, 77, 82, 83, 82, 66, 92, 89, 85, 88,
+  67, 87, 88, 80, 83, 77, 82, 92, 77, 80,
+  84, 93, 91, 79, 90, 87, 85, 83, 86, 79,
+  81, 86, 84, 84, 62, 70, 85, 80, 85, 76,
+  98, 79, 70, 91, 73, 88, 88, 84, 81, 88,
+  98, 72, 71, 87, 77, 86, 86, 84, 89, 81,
+  74, 109, 81, 77, 83, 87, 84, 78, 82, 85,
+  85, 74, 91, 98, 42, 87, 86, 84, 77, 83,
+  60, 79, 66, 98, 85, 47, 75, 96, 87, 80,
+  94, 85, 75, 88, 76, 81, 73, 76, 94, 92,
+  107, 97, 87, 76, 80, 82, 97, 80, 97, 96,
+  90, 77, 84, 68, 68, 92, 87, 98, 87, 71,
+  102, 85, 60, 97, 73, 88, 72, 150, 97, 81,
+  82, 104, 74, 104, 86, 85, 83, 80, 108, 85,
+  81, 89, 97, 72, 86, 75, 88, 111, 86, 83,
+  95, 96, 64, 92, 84, 84, 70, 79, 89, 82,
+  84, 83, 88, 59, 88, 89, 88, 103, 74, 82,
+  96, 87, 77, 83, 85, 81, 88, 86, 101, 116,
+  97, 79, 88, 84, 93, 89, 88, 93, 97, 55,
+  95, 90, 105, 87, 91, 91, 99, 74, 82, 93,
+  119, 65, 114, 75, 79, 82, 103, 82, 84, 75,
+  65, 82, 89, 62, 77, 90, 68, 88, 83, 78,
+  83, 85, 78, 85, 73, 96, 86, 80, 103, 80,
+  94, 81, 73, 85, 84, 70, 99, 93, 90, 63,
+  72, 79, 71, 90, 86, 74, 79, 85, 87, 91,
+  59, 82, 93, 86, 71, 128, 81, 79, 79, 89,
+  82, 82, 87, 77, 84, 82, 75, 83, 82, 72,
+  83, 71, 75, 86, 76, 95, 80, 78, 94, 98,
+  89, 95, 80, 88, 83, 80, 76, 91, 89, 77,
+  69, 62, 77, 88, 94, 76, 89, 80, 71, 84,
+  73, 89, 94, 80, 78, 82, 93, 74, 77, 84,
+  81, 80, 84, 79, 92, 78, 76, 97, 91, 78,
+  83, 90, 79, 80, 90, 86, 81, 78, 106, 86,
+  63, 84, 78, 78, 83, 81, 91, 81, 74, 76,
+  90, 75, 79, 76, 65, 91, 69, 70, 91, 90,
+  80, 89, 72, 99, 71, 77, 92, 72, 96, 83,
+  84, 86, 84, 70, 84, 94, 93, 71, 87, 84,
+  81, 86, 86, 79, 81, 84, 86, 91, 77, 82,
+  101, 85, 78, 103, 78, 78, 76, 82, 84, 69,
+  86, 81, 90, 84, 68, 87, 92, 80, 83, 79,
+  76, 90, 75, 82, 79, 92, 77, 84, 92, 84,
+  84, 91, 93, 78, 74, 91, 85, 80, 59, 71,
+  86, 86, 86, 67, 99, 79, 77, 84, 77, 91,
+  87, 88, 80, 84, 87, 66, 76, 87, 84, 87,
+  83, 72, 92, 82, 73, 106, 83, 75, 78, 91,
+  79, 80, 87, 84, 83, 86, 93, 93, 36, 87,
+  85, 83, 77, 82, 70, 83, 90, 80, 97, 81,
+  84, 84, 75, 70, 75, 77, 78, 81, 78, 83,
+  72, 75, 73, 84, 104, 79, 62, 71, 79, 89,
+  81, 76, 97, 71, 108, 76, 75, 73, 67, 72,
+  75, 78, 87, 83, 82, 75, 68, 90, 89, 93,
+  96, 70, 79, 87, 86, 87, 88, 95, 79, 79,
+  70, 82, 93, 92, 98, 69, 93, 90, 93, 84,
+  75, 78, 75, 69, 56, 70, 82, 106, 81, 63,
+  84, 78, 89, 83, 95, 97, 85, 87, 90, 105,
+  78, 84, 99, 82, 74, 83, 79, 75, 62, 93,
+  77, 85, 74, 85, 86, 70, 80, 69, 95, 73,
+  99, 83, 81, 96, 83, 97, 72, 83, 90, 97,
+  84, 95, 90, 102, 96, 84, 86, 74, 90, 84,
+  79, 85, 70, 91, 63, 81, 96, 71, 84, 87,
+  71, 74, 76, 67, 84, 85, 81, 85, 72, 74,
+  73, 81, 74, 79, 71, 75, 76, 89, 77, 79,
+  97, 70, 101, 75, 74, 84, 68, 78, 73, 82,
+  87, 79, 88, 75, 104, 85, 88, 95, 93, 81,
+  84, 85, 90, 85, 86, 94, 82, 89, 73, 82,
+  95, 96, 100, 76, 96, 89, 94, 86, 70, 77,
+  74, 68, 81, 71, 85, 106, 84, 67, 84, 70,
+  95, 83, 89, 92, 82, 75, 85, 96, 83, 83,
+  95, 85, 76, 102, 77, 77, 69, 93, 77, 85,
+  74, 84, 90, 89, 85, 72, 103, 74, 101, 81,
+  83, 94, 73, 102, 74, 79, 84, 90, 74, 97,
+  94, 96, 81, 86, 85, 80, 88, 81, 80, 83,
+  78, 87, 55, 86, 89, 69, 80, 86, 83, 75,
+  79, 80, 89, 88, 83, 76, 72, 80, 73, 78,
+  71, 75, 86, 74, 83, 85, 81, 72, 95, 70,
+  80, 73, 76, 87, 68, 90, 79, 86, 83, 78,
+  79, 77, 104, 83, 90, 78, 92, 95, 73, 81,
+  88, 81, 85, 89, 76, 85, 80, 83, 84, 90,
+  91, 72, 91, 85, 87, 83, 69, 78, 81, 72,
+  82, 69, 91, 80, 88, 69, 73, 79, 90, 83,
+  83, 94, 90, 77, 92, 92, 102, 76, 96, 90,
+  84, 88, 73, 78, 82, 91, 74, 86, 74, 93,
+  84, 86, 78, 76, 74, 79, 88, 82, 87, 82,
+  76, 82, 71, 86, 85, 92, 80, 89, 82, 85,
+  78, 78, 83, 79, 86, 75, 75, 90, 89, 84,
+  75, 88, 85, 78, 74, 91, 82, 82, 82, 89,
+  76, 76, 78, 81, 88, 80, 94, 82, 124, 97,
+  86, 65, 79, 90, 81, 95, 82, 84, 95, 83,
+  85, 80, 86, 82, 78, 87, 84, 75, 92, 80,
+  84, 93, 86, 112, 82, 73, 89, 87, 83, 84,
+  90, 98, 108, 77, 95, 74, 90, 91, 69, 72,
+  90, 92, 86, 82, 71, 101, 77, 71, 64, 79,
+  79, 97, 84, 93, 99, 90, 66, 82, 86, 85,
+  86, 76, 80, 77, 75, 82, 79, 69, 87, 76,
+  82, 79, 71, 87, 108, 92, 84, 80, 87, 64,
+  111, 65, 106, 79, 87, 86, 88, 88, 67, 88,
+  82, 79, 82, 87, 104, 101, 88, 88, 78, 103,
+  83, 98, 88, 78, 96, 77, 93, 91, 77, 92,
+  83, 91, 71, 96, 83, 91, 77, 83, 77, 80,
+  84, 85, 92, 76, 100, 82, 96, 99, 76, 65,
+  79, 85, 84, 100, 75, 93, 96, 102, 86, 80,
+  80, 92, 82, 92, 79, 69, 90, 78, 115, 89,
+  81, 119, 80, 68, 94, 86, 85, 79, 87, 97,
+  116, 81, 97, 78, 86, 90, 77, 82, 94, 85,
+  86, 78, 68, 104, 71, 71, 77, 86, 79, 101,
+  84, 103, 108, 77, 68, 83, 82, 81, 88, 75,
+  76, 74, 71, 82, 74, 71, 90, 84, 80, 78,
+  74, 88, 114, 92, 68, 83, 87, 89, 122, 66,
+  113, 80, 91, 85, 87, 80, 66, 96, 85, 69,
+  83, 86, 81, 102, 92, 86, 68, 107, 83, 105,
+  90, 72, 96, 76, 76, 91, 82, 86, 86, 74,
+  84, 86, 82, 73, 85, 97, 92, 81, 83, 83,
+  75, 85, 78, 76, 83, 88, 87, 68, 86, 80,
+  74, 80, 93, 92, 83, 81, 81, 82, 72, 100,
+  77, 88, 83, 82, 93, 82, 115, 88, 80, 100,
+  87, 93, 79, 91, 92, 86, 91, 87, 87, 82,
+  83, 75, 82, 85, 78, 77, 88, 87, 94, 84,
+  72, 86, 76, 69, 91, 83, 83, 86, 88, 76,
+  72, 76, 76, 82, 85, 91, 83, 85, 86, 76,
+  98, 74, 85, 81, 82, 82, 85, 75, 70, 85,
+  83, 87, 74, 81, 88, 78, 82, 71, 87, 78,
+  86, 80, 80, 93, 68, 76, 75, 84, 84, 89,
+  88, 99, 90, 80, 70, 89, 87, 83, 87, 76,
+  78, 76, 87, 75, 81, 91, 85, 75, 74, 81,
+  80, 67, 77, 86, 78, 82, 75, 73, 90, 81,
+  87, 79, 103, 86, 85, 77, 74, 101, 88, 80,
+  80, 86, 82, 91, 78, 83, 72, 86, 83, 94,
+  84, 82, 73, 88, 90, 94, 96, 100, 88, 81,
+  91, 77, 78, 82, 93, 86, 102, 86, 97, 70,
+  98, 86, 79, 70, 89, 95, 84, 79, 86, 87,
+  82, 76, 82, 73, 67, 89, 85, 83, 75, 82,
+  87, 89, 79, 92, 86, 77, 83, 78, 77, 85,
+  83, 74, 83, 77, 87, 85, 69, 85, 109, 100,
+  97, 80, 78, 72, 95, 62, 71, 89, 86, 81,
+  85, 100, 78, 83, 76, 83, 80, 85, 95, 91,
+  83, 90, 75, 89, 86, 102, 87, 77, 89, 82,
+  99, 84, 96, 96, 85, 85, 72, 88, 83, 75,
+  78, 82, 73, 84, 81, 79, 98, 78, 96, 87,
+  94, 87, 79, 75, 71, 92, 92, 86, 72, 89,
+  80, 106, 82, 79, 76, 90, 83, 103, 83, 71,
+  70, 83, 101, 90, 94, 102, 89, 72, 93, 74,
+  82, 76, 90, 84, 103, 80, 97, 76, 90, 85,
+  80, 75, 93, 83, 81, 80, 80, 93, 86, 73,
+  75, 76, 71, 88, 84, 91, 83, 82, 80, 91,
+  77, 90, 85, 79, 79, 80, 73, 90, 80, 74,
+  85, 74, 83, 81, 78, 86, 113, 99, 79, 82,
+  78, 83, 105, 61, 72, 102, 94, 82, 87, 90,
+  79, 88, 78, 74, 84, 90, 77, 91, 76, 92,
+  74, 90, 83, 108, 91, 76, 91, 80, 77, 85,
+  98, 88, 92, 69, 83, 83, 86, 69, 85, 93,
+  90, 86, 76, 79, 81, 79, 78, 80, 86, 89,
+  85, 74, 75, 84, 82, 79, 91, 81, 86, 83,
+  77, 76, 80, 92, 83, 96, 81, 93, 86, 86,
+  103, 88, 83, 96, 96, 88, 82, 86, 86, 85,
+  88, 77, 78, 80, 88, 76, 85, 91, 82, 76,
+  88, 98, 95, 79, 80, 80, 84, 75, 89, 82,
+  78, 89, 83, 81, 69, 84, 77, 81, 74, 96,
+  81, 83, 88, 77, 89, 81, 85, 81, 80, 87,
+  91, 84, 71, 84, 84, 93, 83, 79, 84, 84,
+  82, 64, 80, 75, 84, 87, 87, 95, 83, 82,
+  75, 81, 91, 83, 80, 94, 92, 85, 79, 93,
+  86, 87, 85, 83, 79, 82, 86, 85, 81, 71,
+  74, 77, 82, 82, 91, 85, 80, 78, 89, 86,
+  79, 83, 74, 83, 83, 92, 77, 90, 90, 82,
+  94, 82, 81, 124, 92, 85, 84, 86, 93, 90,
+  79, 91, 78, 82, 90, 82, 99, 84, 84, 90,
+  82, 92, 95, 95, 74, 85, 85, 82, 79, 89,
+  87, 79, 77, 81, 80, 85, 85, 84, 89, 78,
+  87, 70, 79, 97, 83, 88, 75, 88, 79, 77,
+  79, 77, 81, 82, 75, 79, 88, 80, 79, 80,
+  85, 86, 79, 80, 88, 64, 73, 75, 91, 88,
+  86, 69, 78, 91, 86, 82, 75, 77, 74, 77,
+  89, 85, 75, 80, 82, 74, 85, 93, 80, 90,
+  90, 85, 81, 87, 99, 68, 81, 80, 91, 83,
+  90, 60, 80, 108, 86, 88, 76, 70, 75, 83,
+  83, 83, 103, 102, 80, 82, 93, 89, 80, 82,
+  74, 86, 78, 92, 82, 97, 78, 80, 83, 79,
+  82, 141, 86, 82, 79, 90, 100, 87, 84, 86,
+  77, 93, 87, 80, 96, 84, 92, 80, 79, 100,
+  94, 79, 70, 94, 85, 80, 77, 89, 97, 88,
+  73, 82, 71, 81, 86, 87, 87, 84, 84, 78,
+  80, 91, 73, 90, 75, 82, 80, 81, 76, 72,
+  84, 86, 79, 76, 92, 74, 78, 74, 76, 79,
+  72, 76, 89, 65, 74, 83, 91, 87, 78, 66,
+  75, 92, 88, 84, 80, 73, 84, 78, 115, 77,
+  72, 84, 83, 77, 78, 94, 88, 73, 90, 84,
+  71, 101, 109, 73, 83, 73, 96, 82, 99, 61,
+  88, 114, 85, 84, 78, 72, 81, 90, 85, 85,
+  85, 81, 80, 74, 88, 89, 80, 83, 79, 79,
+  81, 92, 87, 89, 72, 83, 82, 85, 80, 114,
+  91, 83, 88, 83, 91, 92, 83, 97, 84, 84,
+  81, 81, 93, 85, 79, 86, 83, 94, 91, 79,
+  79, 78, 87, 79, 81, 89, 86, 89, 83, 79,
+  81, 87, 83, 82, 88, 79, 86, 70, 82, 94,
+  82, 86, 82, 85, 81, 80, 83, 77, 78, 87,
+  83, 82, 82, 79, 84, 82, 84, 82, 98, 77,
+  86, 72, 77, 86, 94, 88, 83, 75, 84, 88,
+  91, 87, 75, 77, 74, 76, 86, 80, 75, 82,
+  82, 74, 82, 91, 80, 73, 82, 86, 79, 88,
+  97, 70, 81, 85, 86, 87, 93, 66, 79, 97,
+  86, 84, 80, 78, 78, 77, 73, 77, 106, 96,
+  74, 73, 81, 86, 68, 91, 73, 78, 73, 91,
+  81, 94, 90, 81, 87, 79, 84, 136, 84, 75,
+  76, 78, 86, 78, 79, 88, 73, 107, 95, 82,
+  82, 94, 75, 85, 91, 97, 93, 94, 66, 85,
+  84, 82, 83, 87, 87, 86, 72, 88, 90, 72,
+  77, 87, 80, 78, 89, 80, 78, 89, 91, 78,
+  88, 82, 87, 75, 72, 74, 90, 85, 72, 74,
+  95, 78, 79, 72, 85, 80, 81, 79, 97, 68,
+  78, 72, 77, 84, 84, 74, 67, 90, 84, 87,
+  84, 79, 73, 77, 101, 92, 76, 74, 86, 71,
+  94, 88, 75, 99, 85, 87, 80, 95, 98, 70,
+  84, 86, 102, 79, 95, 63, 92, 106, 92, 91,
+  87, 89, 74, 81, 69, 80, 127, 121, 73, 73,
+  93, 91, 71, 94, 71, 79, 68, 91, 81, 105,
+  75, 83, 72, 72, 89, 160, 79, 77, 63, 95,
+  100, 72, 74, 80, 71, 126, 99, 82, 70, 97,
+  84, 74, 87, 94, 92, 77, 64, 102, 87, 87,
+  80, 87, 98, 89, 71, 91, 73, 61, 72, 86,
+  79, 86, 80, 95, 73, 78, 84, 83, 78, 77,
+  92, 75, 66, 73, 107, 77, 71, 70, 100, 69,
+  82, 83, 74, 82, 74, 73, 103, 67, 79, 69,
+  74, 76, 73, 69, 66, 92, 86, 91, 93, 75,
+  86, 78, 130, 93, 77, 76, 94, 72, 85, 83,
+  85, 76, 86, 83, 79, 113, 104, 74, 81, 81,
+  107, 79, 106, 59, 95, 115, 77, 89, 81, 73,
+  84, 96, 77, 83, 94, 86, 77, 68, 80, 91,
+  71, 92, 81, 80, 73, 91, 80, 94, 73, 84,
+  77, 85, 83, 124, 85, 85, 79, 83, 85, 88,
+  76, 95, 74, 99, 88, 81, 81, 86, 82, 82,
+  86, 85, 92, 78, 75, 77, 84, 76, 86, 87,
+  88, 82, 79, 86, 86, 81, 80, 88, 79, 74,
+  90, 77, 83, 88, 88, 83, 82, 82, 85, 80,
+  80, 79, 83, 77, 78, 75, 88, 80, 83, 91,
+  83, 86, 100, 76, 91, 72, 82, 76, 82, 88,
+  73, 79, 72, 88, 87, 87, 82, 83, 74, 75,
+  96, 87, 77, 77, 82, 71, 82, 86, 75, 73,
+  81, 83, 90, 93, 95, 76, 73, 87, 98, 85,
+  97, 70, 88, 95, 82, 85, 82, 72, 77, 80,
+  77, 72, 93, 92, 70, 81, 79, 87, 74, 86,
+  70, 74, 84, 87, 82, 87, 80, 77, 92, 85,
+  86, 113, 91, 78, 69, 72, 81, 86, 96, 76,
+  81, 106, 89, 84, 84, 82, 85, 85, 88, 93,
+  83, 80, 69, 75, 90, 75, 86, 82, 80, 83,
+  82, 70, 92, 80, 88, 87, 81, 82, 86, 79,
+  72, 95, 89, 78, 86, 81, 89, 68, 72, 86,
+  85, 90, 79, 70, 96, 85, 80, 71, 87, 84,
+  80, 76, 91, 78, 75, 68, 75, 89, 87, 73,
+  71, 90, 75, 92, 75, 76, 77, 76, 81, 97,
+  81, 75, 81, 71, 89, 76, 62, 103, 86, 94,
+  84, 81, 89, 75, 80, 84, 96, 83, 83, 88,
+  96, 85, 81, 90, 85, 74, 70, 84, 75, 76,
+  100, 104, 69, 85, 85, 91, 73, 86, 66, 74,
+  77, 89, 81, 87, 79, 81, 81, 80, 86, 127,
+  84, 89, 63, 82, 86, 79, 84, 77, 82, 123,
+  90, 83, 80, 77, 82, 81, 83, 88, 77, 76,
+  72, 86, 91, 77, 81, 86, 87, 87, 81, 69,
+  83, 74, 84, 80, 79, 86, 101, 86, 71, 87,
+  92, 87, 75, 80, 101, 65, 73, 86, 88, 79,
+  83, 66, 100, 84, 76, 77, 84, 86, 81, 73,
+  91, 72, 75, 66, 76, 86, 81, 68, 72, 89,
+  78, 94, 80, 78, 84, 75, 97, 113, 77, 78,
+  83, 70, 81, 71, 69, 84, 84, 91, 88, 88,
+  90, 78, 76, 82, 100, 78, 91, 86, 100, 86,
+  79, 87, 76, 73, 80, 90, 80, 80, 90, 84,
+  72, 75, 81, 92, 79, 86, 75, 76, 84, 86,
+  84, 86, 87, 82, 82, 90, 82, 111, 93, 102,
+  77, 77, 82, 86, 86, 88, 83, 102, 88, 87,
+  86, 80, 85, 84, 87, 83, 81, 80, 77, 72,
+  88, 73, 87, 85, 87, 84, 87, 72, 91, 82,
+  87, 84, 79, 79, 88, 81, 74, 90, 86, 80,
+  77, 79, 87, 73, 79, 87, 81, 78, 76, 72,
+  90, 83, 81, 82, 84, 84, 99, 69, 86, 82,
+  79, 70, 82, 90, 81, 76, 79, 88, 86, 93,
+  78, 82, 77, 75, 79, 84, 83, 76, 79, 73,
+  84, 76, 65, 78, 78, 79, 86, 77, 87, 78,
+  78, 82, 92, 85, 84, 92, 93, 85, 94, 83,
+  83, 84, 87, 72, 84, 71, 74, 53, 75, 90,
+  81, 99, 70, 77, 86, 94, 72, 85, 98, 97,
+  107, 71, 91, 87, 88, 72, 95, 88, 89, 97,
+  94, 81, 91, 100, 87, 97, 82, 72, 78, 82,
+  88, 83, 79, 97, 92, 87, 80, 84, 94, 75,
+  74, 86, 96, 92, 79, 73, 78, 81, 82, 81,
+  84, 86, 83, 70, 78, 93, 87, 84, 89, 68,
+  78, 94, 75, 81, 81, 93, 92, 86, 83, 82,
+  87, 83, 76, 82, 72, 81, 88, 83, 65, 76,
+  99, 93, 69, 86, 96, 79, 104, 76, 91, 88,
+  95, 76, 82, 97, 88, 85, 72, 103, 72, 85,
+  68, 100, 83, 73, 81, 86, 59, 81, 89, 71,
+  75, 68, 96, 87, 92, 82, 101, 95, 83, 91,
+  98, 82, 87, 67, 77, 46, 81, 76, 86, 91,
+  70, 83, 92, 89, 74, 92, 90, 113, 89, 81,
+  94, 73, 90, 69, 102, 88, 84, 121, 102, 71,
+  89, 83, 91, 125, 89, 78, 80, 73, 94, 90,
+  73, 113, 110, 87, 85, 81, 83, 77, 79, 93,
+  87, 85, 78, 74, 73, 74, 83, 80, 81, 91,
+  70, 70, 85, 85, 90, 80, 85, 61, 62, 91,
+  80, 72, 98, 97, 84, 92, 84, 84, 89, 79,
+  70, 79, 72, 82, 84, 79, 57, 84, 86, 101,
+  53, 86, 111, 89, 98, 77, 83, 83, 111, 73,
+  99, 93, 82, 80, 75, 95, 78, 91, 63, 72,
+  85, 68, 87, 86, 44, 77, 90, 70, 72, 59,
+  98, 82, 94, 89, 90, 87, 79, 83, 90, 93,
+  87, 76, 73, 61, 79, 90, 86, 84, 74, 73,
+  84, 94, 76, 91, 84, 90, 75, 69, 93, 90,
+  82, 72, 88, 95, 92, 108, 91, 87, 87, 86,
+  89, 94, 90, 73, 77, 82, 90, 77, 81, 96,
+  88, 87, 76, 86, 93, 78, 77, 86, 85, 85,
+  73, 75, 76, 80, 86, 76, 92, 79, 78, 76,
+  77, 97, 75, 81, 84, 72, 89, 86, 75, 91,
+  73, 83, 82, 85, 86, 87, 80, 93, 85, 79,
+  97, 87, 91, 83, 70, 96, 96, 93, 80, 86,
+  90, 77, 82, 74, 88, 81, 89, 77, 74, 98,
+  81, 83, 74, 104, 83, 80, 76, 78, 79, 79,
+  94, 84, 63, 84, 83, 75, 81, 76, 94, 97,
+  89, 78, 91, 83, 71, 79, 88, 75, 88, 88,
+  82, 74, 77, 90, 73, 104, 75, 87, 88, 94,
+  69, 83, 89, 94, 88, 75, 82, 86, 82, 81,
+  96, 84, 84, 97, 85, 86, 88, 98, 88, 101,
+  80, 72, 79, 75, 79, 81, 69, 89, 89, 78,
+  87, 88, 92, 75, 80, 79, 91, 93, 83, 76,
+  87, 85, 78, 76, 81, 86, 84, 76, 72, 87,
+  95, 83, 90, 72, 92, 83, 80, 82, 91, 89,
+  91, 82, 86, 73, 83, 82, 82, 77, 73, 86,
+  94, 81, 80, 70, 95, 96, 82, 91, 96, 82,
+  100, 77, 86, 90, 96, 80, 71, 97, 91, 84,
+  74, 97, 76, 88, 70, 104, 81, 79, 78, 100,
+  66, 78, 85, 82, 74, 76, 94, 77, 70, 78,
+  98, 87, 77, 92, 97, 78, 92, 83, 80, 73,
+  81, 81, 72, 90, 76, 88, 91, 96, 70, 89,
+  78, 109, 82, 77, 85, 71, 83, 77, 98, 92,
+  80, 116, 85, 82, 93, 87, 91, 139, 94, 70,
+  84, 63, 81, 87, 58, 93, 108, 73, 97, 83,
+  81, 82, 87, 79, 86, 85, 87, 76, 84, 81,
+  84, 80, 80, 91, 75, 74, 77, 87, 109, 80,
+  84, 65, 82, 75, 83, 76, 99, 87, 89, 76,
+  89, 72, 88, 86, 79, 77, 72, 90, 93, 77,
+  71, 67, 82, 106, 73, 93, 98, 90, 94, 74,
+  72, 79, 106, 76, 67, 111, 86, 79, 73, 90,
+  73, 101, 65, 75, 82, 78, 84, 100, 58, 78,
+  88, 77, 73, 68, 95, 76, 71, 76, 83, 80,
+  79, 81, 87, 78, 90, 85, 83, 80, 80, 89,
+  78, 81, 79, 83, 83, 91, 72, 83, 76, 92,
+  72, 73, 83, 88, 79, 81, 89, 89, 82, 96,
+  85, 84, 87, 87, 85, 105, 90, 74, 81, 77,
+  87, 79, 72, 88, 90, 86, 81, 86, 91, 81,
+  82, 79, 86, 82, 77, 74, 88, 83, 80, 71,
+  84, 78, 77, 81, 79, 95, 84, 82, 77, 77,
+  94, 81, 78, 85, 81, 80, 73, 82, 89, 83,
+  76, 93, 85, 78, 98, 93, 96, 82, 86, 84,
+  95, 94, 82, 95, 93, 81, 84, 78, 86, 74,
+  91, 78, 66, 95, 89, 83, 73, 97, 86, 79,
+  74, 77, 83, 85, 92, 100, 74, 80, 83, 87,
+  76, 77, 94, 88, 74, 77, 87, 82, 62, 80,
+  79, 78, 79, 89, 85, 91, 73, 85, 73, 98,
+  84, 81, 83, 84, 70, 81, 86, 87, 72, 71,
+  81, 97, 70, 78, 79, 80, 88, 88, 81, 93,
+  84, 81, 96, 96, 87, 78, 80, 70, 88, 76,
+  77, 72, 95, 87, 91, 88, 92, 67, 80, 80,
+  91, 86, 85, 85, 90, 86, 75, 79, 89, 98,
+  79, 89, 79, 87, 88, 84, 84, 71, 99, 79,
+  75, 79, 77, 83, 88, 83, 83, 79, 87, 88,
+  94, 66, 76, 92, 93, 89, 101, 72, 90, 94,
+  93, 87, 94, 86, 89, 81, 86, 89, 91, 84,
+  65, 80, 84, 94, 89, 87, 82, 81, 68, 85,
+  78, 92, 73, 99, 85, 77, 87, 90, 74, 84,
+  91, 96, 72, 94, 87, 88, 72, 88, 85, 72,
+  90, 86, 80, 84, 76, 80, 73, 94, 81, 79,
+  85, 88, 75, 88, 82, 89, 77, 74, 86, 89,
+  67, 73, 95, 87, 89, 89, 82, 86, 80, 78,
+  90, 103, 94, 80, 82, 64, 80, 84, 66, 68,
+  111, 73, 95, 91, 85, 82, 88, 74, 85, 79,
+  89, 88, 98, 84, 80, 83, 92, 93, 72, 86,
+  82, 86, 102, 78, 77, 65, 95, 78, 76, 81,
+  79, 80, 91, 72, 84, 81, 84, 87, 98, 68,
+  73, 100, 97, 87, 95, 68, 95, 101, 93, 92,
+  91, 86, 89, 72, 77, 80, 84, 81, 45, 82,
+  90, 92, 86, 94, 77, 90, 64, 81, 81, 98,
+  80, 103, 82, 74, 94, 85, 80, 78, 94, 100,
+  67, 91, 88, 84, 75, 81, 76, 74, 78, 89,
+  81, 92, 75, 83, 77, 90, 85, 77, 82, 83,
+  65, 86, 83, 91, 84, 72, 81, 92, 70, 81,
+  75, 87, 85, 85, 81, 79, 84, 88, 89, 98,
+  90, 80, 82, 72, 85, 80, 82, 75, 91, 86,
+  88, 86, 89, 76, 80, 80, 86, 74, 84, 86,
+  90, 83, 78, 79, 87, 87, 79, 90, 86, 93,
+  83, 88, 67, 76, 93, 80, 74, 80, 75, 85,
+  76, 84, 82, 84, 83, 85, 96, 68, 77, 93,
+  90, 89, 103, 74, 94, 90, 88, 90, 94, 81,
+  88, 82, 88, 78, 92, 83, 68, 86, 78, 91,
+  85, 82, 90, 80, 71, 81, 84, 93, 88, 99,
+  88, 80, 97, 87, 72, 84, 90, 93, 76, 93,
+  96, 69, 80, 88, 89, 84, 81, 87, 80, 84,
+  89, 84, 80, 74, 85, 69, 79, 77, 80, 90,
+  91, 82, 81, 83, 92, 77, 87, 82, 91, 81,
+  81, 77, 71, 91, 76, 87, 76, 86, 93, 80,
+  78, 95, 88, 91, 89, 93, 85, 80, 80, 79,
+  97, 86, 82, 80, 87, 221, 79, 86, 83, 84,
+  87, 78, 78, 85, 88, 84, 79, 94, 83, 75,
+  92, 84, 79, 81, 90, 78, 75, 103, 92, 87,
+  77, 87, 85, 80, 86, 87, 87, 92, 75, 80,
+  74, 85, 78, 85, 94, 87, 82, 84, 105, 85,
+  78, 81, 83, 94, 93, 88, 83, 90, 95, 86,
+  79, 81, 92, 83, 69, 97, 89, 87, 84, 82,
+  87, 87, 82, 80, 88, 85, 86, 88, 83, 79,
+  84, 88, 86, 73, 82, 90, 89, 87, 83, 93,
+  77, 75, 82, 85, 78, 80, 86, 92, 87, 76,
+  78, 82, 83, 74, 101, 81, 87, 82, 75, 83,
+  73, 82, 79, 80, 86, 84, 67, 76, 85, 86,
+  86, 93, 86, 85, 86, 81, 75, 77, 99, 82,
+  82, 79, 83, 159, 79, 88, 82, 84, 82, 74,
+  87, 74, 87, 78, 72, 83, 73, 84, 69, 76,
+  92, 86, 89, 82, 76, 84, 90, 85, 84, 92,
+  86, 92, 75, 86, 85, 81, 82, 81, 75, 95,
+  78, 79, 89, 78, 83, 83, 85, 79, 85, 82,
+  78, 91, 90, 82, 88, 90, 91, 87, 78, 79,
+  90, 85, 80, 74, 79, 85, 75, 84, 86, 82,
+  82, 81, 79, 83, 81, 85, 87, 82, 97, 81,
+  89, 74, 80, 81, 85, 83, 87, 88, 85, 78,
+  86, 89, 80, 87, 90, 99, 88, 81, 82, 81,
+  81, 80, 93, 78, 92, 88, 84, 84, 77, 86,
+  79, 86, 87, 89, 70, 88, 93, 83, 87, 91,
+  85, 78, 88, 89, 74, 88, 88, 76, 82, 80,
+  77, 87, 82, 87, 83, 84, 88, 87, 88, 90,
+  85, 72, 83, 87, 80, 98, 72, 85, 85, 93,
+  90, 84, 79, 86, 82, 77, 88, 83, 84, 95,
+  93, 88, 91, 88, 79, 77, 74, 90, 85, 81,
+  90, 78, 84, 89, 72, 71, 80, 86, 79, 92,
+  85, 87, 85, 85, 85, 86, 89, 85, 82, 82,
+  94, 77, 82, 88, 87, 81, 79, 86, 81, 82,
+  84, 86, 84, 90, 87, 74, 80, 91, 84, 79,
+  85, 84, 81, 85, 91, 84, 80, 76, 89, 81,
+  84, 82, 85, 89, 89, 80, 76, 84, 86, 81,
+  85, 83, 88, 81, 75, 81, 84, 86, 88, 89,
+  78, 86, 83, 86, 78, 77, 83, 85, 85, 94,
+  74, 84, 79, 94, 93, 82, 86, 84, 85, 115,
+  79, 81, 86, 92, 85, 84, 83, 84, 84, 83,
+  78, 92, 85, 70, 80, 79, 83, 81, 82, 84,
+  77, 82, 86, 87, 82, 77, 87, 84, 82, 87,
+  87, 81, 76, 92, 79, 80, 86, 92, 87, 81,
+  83, 84, 91, 82, 80, 89, 83, 90, 79, 83,
+  90, 84, 83, 82, 81, 81, 86, 87, 70, 77,
+  82, 83, 82, 81, 88, 90, 88, 87, 87, 84,
+  82, 84, 88, 83, 90, 89, 83, 72, 80, 81,
+  84, 87, 84, 87, 78, 87, 82, 84, 79, 76,
+  85, 90, 81, 74, 80, 89, 81, 74, 94, 83,
+  83, 86, 81, 89, 85, 78, 88, 83, 86, 89,
+  73, 80, 83, 87, 86, 86, 83, 85, 88, 90,
+  82, 89, 96, 79, 88, 83, 85, 110, 81, 85,
+  87, 80, 80, 76, 85, 78, 81, 81, 78, 80,
+  81, 71, 53, 77, 83, 83, 85, 79, 85, 77,
+  83, 84, 86, 81, 83, 91, 83, 83, 79, 81,
+  86, 91, 72, 79, 79, 82, 77, 78, 86, 79,
+  88, 78, 78, 92, 87, 89, 83, 80, 91, 87,
+  92, 81, 84, 78, 90, 79, 79, 73, 72, 82,
+  80, 89, 85, 85, 80, 84, 81, 82, 82, 88,
+  89, 82, 90, 84, 91, 79, 77, 75, 78, 82,
+  90, 83, 79, 82, 83, 78, 74, 75, 87, 97,
+  86, 82, 79, 86, 83, 77, 92, 79, 91, 87,
+  93, 88, 82, 89, 89, 90, 85, 93, 73, 91,
+  90, 91, 87, 85, 83, 76, 98, 98, 88, 90,
+  94, 76, 86, 81, 78, 77, 83, 86, 84, 79,
+  85, 89, 82, 89, 75, 80, 82, 90, 86, 80,
+  51, 88, 78, 86, 91, 78, 85, 85, 83, 81,
+  86, 85, 85, 89, 93, 85, 85, 94, 81, 79,
+  74, 73, 85, 79, 83, 83, 85, 86, 83, 76,
+  73, 87, 89, 92, 88, 81, 91, 82, 92, 82,
+  92, 86, 85, 74, 87, 83, 80, 84, 87, 92,
+  81, 85, 77, 79, 85, 85, 83, 95, 94, 84,
+  79, 82, 84, 86, 84, 75, 75, 88, 90, 81,
+  90, 92, 82, 75, 78, 79, 84, 89, 81, 83,
+  75, 85, 84, 77, 81, 85, 86, 91, 81, 82,
+  83, 85, 98, 84, 86, 87, 97, 82, 80, 94,
+  76, 83, 85, 82, 83, 86, 78, 99, 91, 81,
+  82, 83, 88, 83, 79, 78, 84, 84, 83, 79,
+  83, 82, 85, 96, 80, 82, 82, 80, 94, 84,
+  72, 81, 84, 81, 79, 78, 76, 92, 80, 76,
+  82, 83, 88, 88, 81, 84, 88, 86, 73, 77,
+  83, 85, 85, 76, 84, 78, 86, 81, 85, 88,
+  87, 90, 84, 84, 88, 84, 82, 81, 79, 80,
+  82, 80, 93, 77, 78, 82, 87, 84, 84, 88,
+  77, 88, 86, 81, 81, 93, 87, 92, 98, 87,
+  88, 76, 83, 75, 82, 87, 87, 78, 83, 101,
+  80, 77, 78, 78, 91, 90, 77, 76, 86, 88,
+  83, 80, 85, 85, 84, 93, 83, 85, 85, 77,
+  96, 79, 82, 86, 85, 84, 82, 87, 81, 82,
+  82, 87, 85, 86, 82, 98, 87, 78, 84, 85,
+  87, 76, 77, 78, 86, 79, 81, 86, 82, 77,
+  82, 88, 84, 74, 78, 78, 66, 75, 78, 86,
+  83, 80, 83, 76, 78, 90, 83, 72, 83, 84,
+  88, 87, 79, 83, 90, 87, 72, 81, 84, 89,
+  80, 83, 87, 78, 79, 81, 79, 88, 84, 86,
+  81, 75, 87, 82, 85, 81, 89, 79, 84, 78,
+  90, 73, 70, 82, 83, 86, 84, 88, 78, 88,
+  86, 82, 84, 91, 84, 86, 98, 90, 91, 83,
+  84, 73, 78, 84, 87, 75, 78, 88, 84, 76,
+  74, 81, 89, 94, 83, 86, 90, 87, 85, 82,
+  86, 83, 91, 84, 83, 84, 89, 83, 85, 90,
+  71, 87, 78, 94, 85, 76, 85, 84, 83, 82,
+  86, 88, 89, 101, 84, 78, 85, 81, 81, 62,
+  83, 75, 82, 80, 85, 93, 78, 76, 86, 81,
+  85, 84, 80, 79, 62, 81, 80, 89, 87, 84,
+  83, 81, 80, 84, 82, 73, 86, 88, 87, 89,
+  90, 83, 77, 83, 81, 75, 89, 87, 85, 91,
+  86, 81, 80, 79, 77, 89, 80, 89, 81, 74,
+  96, 78, 85, 77, 92, 85, 83, 81, 75, 77,
+  80, 82, 83, 85, 85, 88, 77, 83, 89, 86,
+  82, 91, 88, 68, 98, 87, 79, 76, 91, 83,
+  68, 85, 78, 81, 100, 90, 80, 92, 85, 81,
+  78, 94, 80, 93, 85, 85, 90, 87, 70, 84,
+  88, 99, 99, 84, 79, 85, 92, 80, 69, 82,
+  92, 83, 77, 73, 95, 98, 91, 87, 92, 94,
+  80, 83, 95, 78, 85, 85, 73, 81, 79, 80,
+  81, 98, 80, 81, 96, 74, 82, 76, 84, 81,
+  79, 94, 95, 82, 88, 82, 89, 72, 81, 95,
+  87, 87, 83, 72, 97, 82, 79, 79, 88, 86,
+  73, 102, 82, 86, 79, 75, 76, 101, 86, 85,
+  83, 87, 80, 76, 102, 73, 89, 77, 79, 94,
+  86, 62, 85, 89, 81, 81, 79, 73, 96, 88,
+  85, 83, 93, 70, 65, 82, 95, 97, 84, 75,
+  80, 84, 77, 82, 81, 75, 94, 75, 56, 84,
+  88, 87, 105, 96, 78, 86, 87, 78, 85, 115,
+  89, 88, 80, 76, 82, 77, 56, 78, 98, 99,
+  94, 87, 60, 97, 84, 76, 61, 74, 93, 75,
+  74, 63, 89, 122, 105, 71, 81, 82, 66, 60,
+  102, 61, 75, 81, 54, 86, 76, 81, 72, 112,
+  92, 76, 100, 81, 75, 76, 80, 88, 75, 78,
+  88, 81, 79, 80, 98, 59, 77, 86, 93, 83,
+  83, 93, 89, 84, 97, 78, 82, 91, 69, 104,
+  81, 92, 79, 70, 81, 137, 87, 86, 84, 81,
+  70, 90, 96, 71, 81, 69, 84, 115, 84, 68,
+  87, 77, 76, 79, 77, 60, 81, 94, 92, 79,
+  92, 70, 40, 76, 90, 96, 86, 61, 85, 98,
+  90, 89, 72, 84, 86, 85, 69, 85, 78, 86,
+  95, 87, 80, 90, 88, 77, 80, 88, 86, 96,
+  70, 81, 79, 88, 78, 81, 84, 96, 93, 83,
+  77, 76, 95, 78, 75, 78, 86, 82, 75, 74,
+  79, 92, 94, 84, 86, 87, 76, 83, 94, 84,
+  81, 89, 77, 80, 81, 80, 80, 97, 86, 84,
+  92, 69, 82, 80, 73, 78, 79, 86, 91, 89,
+  86, 82, 89, 73, 84, 87, 93, 90, 82, 68,
+  96, 84, 78, 81, 83, 83, 71, 97, 83, 96,
+  87, 77, 87, 96, 88, 84, 94, 88, 82, 90,
+  97, 71, 89, 78, 73, 89, 84, 70, 94, 90,
+  83, 92, 71, 74, 98, 87, 88, 83, 91, 74,
+  68, 81, 90, 94, 83, 83, 103, 70, 81, 83,
+  78, 79, 91, 78, 66, 86, 95, 88, 91, 76,
+  74, 98, 82, 74, 87, 86, 84, 88, 86, 92,
+  83, 88, 79, 88, 91, 94, 94, 76, 88, 94,
+  96, 89, 75, 69, 99, 70, 65, 76, 94, 80,
+  91, 96, 81, 102, 74, 76, 100, 75, 86, 91,
+  74, 98, 69, 76, 86, 98, 85, 84, 81, 79,
+  72, 77, 77, 78, 73, 73, 112, 87, 82, 79,
+  85, 76, 80, 89, 87, 85, 84, 77, 95, 83,
+  83, 84, 87, 89, 75, 92, 76, 71, 81, 72,
+  80, 98, 85, 83, 82, 94, 72, 85, 95, 76,
+  91, 89, 80, 79, 82, 73, 85, 85, 77, 86,
+  71, 71, 77, 80, 73, 80, 88, 75, 72, 77,
+  88, 84, 89, 76, 96, 87, 77, 82, 77, 69,
+  93, 70, 55, 93, 120, 90, 103, 93, 71, 109,
+  88, 75, 105, 106, 97, 77, 69, 88, 69, 72,
+  70, 85, 101, 101, 93, 80, 70, 104, 92, 81,
+  66, 75, 91, 50, 60, 66, 105, 96, 105, 81,
+  66, 81, 59, 51, 115, 63, 71, 84, 45, 88,
+  69, 79, 65, 140, 94, 73, 73, 93, 56, 75,
+  72, 94, 65, 60, 80, 85, 74, 84, 85, 65,
+  77, 90, 95, 83, 86, 99, 87, 85, 104, 93,
+  80, 96, 70, 99, 79, 72, 73, 60, 84, 122,
+  80, 84, 74, 91, 73, 78, 96, 79, 84, 74,
+  82, 105, 76, 73, 95, 70, 65, 79, 80, 60,
+  73, 77, 71, 83, 95, 77, 36, 66, 81, 84,
+  96, 68, 96, 98, 99, 85, 74, 91, 90, 78,
+  67, 88, 89, 92, 87, 99, 74, 89, 83, 70,
+  90, 82, 85, 101, 70, 87, 72, 90, 83, 84,
+  88, 97, 95, 86, 84, 82, 95, 87, 80, 72,
+  82, 71, 56, 74, 82, 84, 96, 88, 77, 81,
+  77, 76, 98, 92, 80, 94, 76, 66, 72, 74,
+  79, 93, 89, 84, 79, 69, 73, 76, 76, 80,
+  78, 78, 75, 93, 78, 78, 85, 78, 86, 91,
+  84, 85, 84, 73, 95, 88, 82, 87, 83, 86,
+  74, 89, 78, 77, 80, 70, 82, 95, 87, 81,
+  89, 95, 74, 71, 94, 78, 86, 91, 76, 78,
+  77, 77, 97, 84, 79, 92, 83, 79, 106, 79,
+  76, 86, 90, 79, 74, 80, 83, 83, 90, 84,
+  96, 74, 82, 85, 73, 84, 79, 86, 84, 81,
+  84, 95, 83, 87, 64, 105, 82, 77, 95, 82,
+  87, 93, 82, 101, 78, 89, 94, 84, 77, 92,
+  84, 78, 87, 78, 100, 92, 87, 78, 97, 79,
+  75, 73, 73, 72, 76, 100, 86, 91, 79, 98,
+  89, 84, 96, 95, 99, 94, 74, 80, 108, 81,
+  86, 89, 80, 87, 81, 78, 75, 77, 75, 89,
+  93, 88, 83, 76, 85, 81, 86, 87, 87, 60,
+  80, 65, 96, 74, 66, 98, 84, 80, 91, 89,
+  77, 80, 91, 82, 85, 72, 82, 75, 92, 96,
+  78, 93, 87, 73, 103, 98, 75, 69, 77, 89,
+  92, 86, 90, 84, 76, 92, 69, 75, 77, 72,
+  98, 83, 89, 83, 83, 82, 86, 88, 94, 79,
+  76, 87, 65, 70, 79, 79, 82, 86, 102, 97,
+  86, 95, 72, 106, 81, 83, 104, 77, 83, 85,
+  70, 100, 76, 75, 98, 84, 90, 95, 84, 86,
+  100, 78, 104, 74, 84, 82, 91, 65, 69, 62,
+  89, 72, 76, 100, 75, 81, 67, 97, 91, 95,
+  92, 92, 87, 93, 69, 85, 94, 94, 89, 81,
+  63, 93, 73, 73, 72, 81, 65, 82, 87, 78,
+  80, 77, 82, 75, 88, 75, 94, 50, 82, 67,
+  97, 87, 70, 98, 80, 83, 95, 102, 72, 75,
+  86, 79, 84, 73, 92, 76, 80, 96, 82, 79,
+  82, 76, 106, 110, 76, 75, 77, 90, 107, 82,
+  86, 79, 80, 94, 73, 70, 66, 77, 96, 84,
+  81, 79, 72, 86, 86, 103, 88, 83, 87, 82,
+  77, 82, 81, 80, 81, 86, 82, 95, 81, 96,
+  68, 103, 80, 75, 91, 77, 72, 94, 80, 101,
+  81, 91, 92, 82, 76, 93, 89, 87, 89, 87,
+  99, 77, 87, 75, 78, 81, 71, 72, 91, 79,
+  76, 97, 86, 89, 79, 99, 88, 88, 95, 96,
+  96, 80, 75, 82, 96, 82, 91, 89, 77, 79,
+  81, 76, 79, 80, 71, 89, 70, 86, 79, 72,
+  86, 84, 85, 80, 90, 58, 85, 64, 89, 97,
+  67, 93, 85, 82, 90, 93, 76, 75, 89, 85,
+  90, 76, 79, 74, 85, 93, 80, 70, 89, 74,
+  108, 97, 74, 74, 82, 94, 92, 84, 91, 85,
+  83, 98, 94, 77, 80, 76, 84, 83, 93, 86,
+  85, 86, 91, 89, 81, 79, 81, 76, 72, 78,
+  79, 86, 89, 76, 87, 83, 76, 84, 75, 81,
+  73, 86, 89, 80, 89, 74, 88, 79, 80, 79,
+  92, 86, 101, 79, 91, 82, 99, 76, 79, 95,
+  82, 79, 82, 73, 91, 83, 78, 87, 80, 93,
+  71, 87, 84, 84, 82, 87, 68, 92, 97, 80,
+  78, 84, 76, 76, 75, 83, 79, 85, 92, 89,
+  81, 84, 84, 85, 85, 78, 73, 73, 89, 84,
+  101, 84, 82, 87, 76, 78, 86, 77, 85, 80,
+  81, 76, 82, 85, 95, 77, 78, 86, 77, 85,
+  87, 88, 85, 96, 94, 80, 84, 73, 91, 75,
+  75, 86, 80, 71, 79, 92, 90, 81, 89, 89,
+  85, 81, 86, 88, 89, 87, 81, 76, 91, 83,
+  88, 94, 80, 80, 83, 80, 74, 78, 74, 90,
+  98, 71, 94, 76, 75, 83, 75, 81, 73, 82,
+  102, 86, 79, 76, 80, 75, 87, 73, 94, 85,
+  93, 79, 82, 93, 111, 79, 77, 83, 85, 72,
+  83, 74, 86, 84, 76, 85, 71, 90, 72, 86,
+  86, 93, 92, 87, 68, 98, 107, 85, 88, 76,
+  68, 72, 80, 95, 82, 90, 91, 89, 79, 80,
+  81, 90, 82, 76, 76, 73, 85, 99, 114, 83,
+  82, 91, 80, 75, 89, 80, 82, 83, 88, 76,
+  78, 77, 106, 82, 80, 78, 82, 81, 104, 86,
+  79, 95, 96, 86, 86, 73, 84, 72, 79, 86,
+  81, 77, 72, 99, 93, 86, 86, 91, 85, 77,
+  81, 93, 81, 88, 84, 77, 99, 83, 85, 98,
+  83, 78, 82, 72, 72, 85, 78, 86, 85, 75,
+  83, 82, 78, 83, 74, 80, 79, 87, 87, 82,
+  81, 76, 76, 78, 85, 79, 93, 84, 99, 83,
+  90, 91, 97, 84, 78, 81, 85, 79, 80, 73,
+  87, 80, 88, 85, 77, 91, 73, 86, 82, 80,
+  84, 88, 70, 92, 97, 86, 79, 85, 74, 80,
+  79, 83, 82, 82, 97, 90, 80, 87, 83, 86,
+  89, 73, 78, 71, 86, 77, 96, 81, 80, 84,
+  77, 74, 88, 86, 83, 81, 82, 76, 84, 86,
+  93, 80, 80, 88, 73, 84, 81, 86, 80, 90,
+  91, 85, 84, 78, 88, 75, 74, 90, 78, 73,
+  79, 90, 92, 82, 80, 92, 82, 81, 86, 90,
+  78, 82, 80, 77, 86, 82, 85, 91, 79, 80,
+  82, 79, 77, 77, 74, 84, 98, 73, 101, 82,
+  74, 85, 78, 76, 73, 81, 97, 80, 86, 82,
+  86, 79, 85, 75, 81, 90, 84, 78, 74, 86,
+  108, 71, 82, 98, 76, 84, 79, 66, 77, 87,
+  78, 82, 73, 95, 73, 85, 84, 85, 88, 87,
+  67, 101, 104, 87, 84, 77, 76, 73, 74, 96,
+  76, 81, 89, 84, 74, 84, 94, 78, 85, 74,
+  79, 77, 92, 90, 112, 91, 80, 81, 82, 75,
+  88, 73, 89, 82, 79, 78, 78, 71, 98, 80,
+  80, 78, 85, 90, 105, 90, 90, 96, 92, 76,
+  82, 75, 83, 82, 80, 79, 78, 76, 80, 92,
+  93, 81, 80, 87, 87, 76, 80, 99, 91, 91,
+  81, 76, 92, 81, 88, 100, 77, 77, 90, 83,
+  79, 85, 72, 88, 120, 71, 109, 72, 75, 83,
+  84, 72, 70, 78, 118, 81, 82, 84, 82, 78,
+  88, 70, 86, 99, 81, 81, 62, 103, 126, 70,
+  82, 85, 77, 79, 83, 68, 70, 86, 76, 76,
+  72, 100, 71, 86, 81, 101, 101, 101, 61, 108,
+  123, 85, 83, 75, 69, 67, 69, 114, 73, 90,
+  88, 93, 68, 75, 94, 78, 80, 69, 89, 84,
+  83, 106, 135, 82, 79, 85, 81, 74, 91, 87,
+  90, 83, 85, 79, 79, 67, 106, 79, 80, 67,
+  99, 89, 127, 90, 83, 105, 96, 81, 85, 77,
+  73, 83, 83, 76, 78, 82, 79, 92, 99, 84,
+  79, 90, 88, 73, 76, 101, 81, 92, 78, 70,
+  100, 80, 87, 112, 78, 76, 87, 75, 79, 85,
+  72, 89, 97, 72, 96, 84, 76, 79, 78, 76,
+  79, 85, 97, 83, 84, 76, 76, 82, 85, 75,
+  80, 89, 81, 87, 80, 97, 103, 82, 79, 82,
+  82, 80, 84, 69, 76, 82, 83, 83, 75, 94,
+  80, 88, 84, 82, 88, 86, 68, 101, 102, 82,
+  80, 82, 72, 80, 76, 93, 76, 80, 86, 84,
+  77, 85, 90, 79, 93, 73, 80, 81, 90, 87,
+  103, 73, 77, 80, 80, 77, 92, 98, 91, 81,
+  81, 80, 80, 80, 101, 78, 84, 81, 79, 87,
+  97, 88, 79, 94, 92, 82, 85, 79, 78, 80,
+  78, 82, 79, 77, 84, 88, 98, 81, 78, 85,
+  85, 76, 79, 94, 76, 88, 81, 78, 90, 82,
+  86, 95, 78, 87, 83, 74, 71, 77, 80, 88,
+  89, 72, 88, 93, 81, 85, 77, 75, 76, 84,
+  83, 81, 81, 83, 78, 78, 87, 78, 84, 84,
+  90, 77, 74, 86, 100, 77, 78, 98, 83, 87,
+  74, 75, 79, 85, 78, 83, 77, 93, 80, 91,
+  87, 72, 87, 88, 72, 101, 96, 85, 83, 74,
+  79, 74, 78, 84, 83, 81, 87, 85, 76, 88,
+  88, 80, 83, 80, 71, 80, 93, 80, 97, 83,
+  83, 84, 83, 85, 94, 80, 89, 84, 77, 75,
+  79, 75, 91, 80, 80, 82, 85, 90, 84, 86,
+  93, 98, 90, 76, 80, 78, 83, 79, 75, 80,
+  75, 75, 83, 92, 90, 82, 85, 90, 78, 79,
+  82, 92, 90, 85, 82, 78, 83, 80, 87, 85,
+  81, 84, 91, 78, 75, 79, 76, 91, 97, 72,
+  92, 85, 84, 80, 80, 69, 72, 84, 95, 82,
+  82, 81, 78, 75, 88, 75, 91, 91, 85, 78,
+  70, 98, 113, 74, 76, 88, 82, 86, 81, 75,
+  70, 85, 83, 84, 79, 93, 82, 90, 84, 81,
+  92, 90, 70, 102, 103, 82, 81, 72, 66, 74,
+  73, 88, 79, 88, 90, 89, 73, 84, 89, 84,
+  85, 76, 71, 87, 89, 89, 105, 87, 81, 84,
+  81, 87, 95, 93, 90, 84, 81, 73, 76, 76,
+  103, 80, 80, 77, 89, 87, 92, 88, 89, 100,
+  96, 76, 79, 77, 75, 85, 80, 81, 78, 77,
+  81, 91, 94, 82, 84, 88, 84, 75, 76, 89,
+  81, 88, 82, 74, 92, 79, 87, 91, 77, 80,
+  84, 72, 75, 74, 79, 92, 90, 73, 83, 93,
+  82, 75, 76, 77, 79, 85, 87, 76, 84, 77,
+  73, 78, 90, 78, 82, 84, 88, 81, 83, 94,
+  91, 83, 78, 83, 85, 82, 82, 78, 77, 83,
+  82, 83, 77, 92, 87, 87, 87, 70, 85, 82,
+  71, 98, 96, 82, 76, 78, 75, 76, 80, 87,
+  82, 80, 79, 86, 82, 87, 85, 83, 88, 81,
+  69, 81, 93, 80, 97, 86, 82, 84, 77, 87,
+  94, 95, 93, 82, 82, 79, 83, 85, 92, 82,
+  84, 87, 83, 89, 78, 87, 85, 101, 91, 76,
+  83, 79, 81, 79, 75, 84, 79, 73, 83, 87,
+  91, 78, 87, 93, 79, 80, 82, 89, 83, 87,
+  83, 80, 83, 80, 86, 81, 87, 76, 82, 89,
+  80, 75, 102, 87, 106, 81, 77, 94, 67, 91,
+  117, 78, 76, 84, 74, 72, 78, 69, 73, 80,
+  91, 70, 92, 88, 94, 62, 85, 74, 80, 88,
+  75, 83, 72, 85, 96, 88, 70, 130, 77, 94,
+  101, 75, 81, 86, 67, 101, 83, 76, 91, 94,
+  78, 82, 84, 63, 80, 88, 67, 77, 81, 105,
+  93, 104, 79, 89, 73, 97, 75, 86, 79, 67,
+  93, 86, 112, 82, 73, 76, 93, 89, 93, 78,
+  91, 84, 75, 79, 82, 75, 91, 81, 86, 76,
+  70, 86, 74, 96, 79, 77, 98, 67, 90, 74,
+  85, 86, 86, 90, 77, 88, 86, 93, 88, 92,
+  74, 80, 95, 76, 76, 64, 95, 83, 67, 82,
+  72, 78, 88, 77, 95, 83, 80, 87, 85, 79,
+  94, 83, 91, 82, 82, 90, 69, 91, 111, 82,
+  76, 89, 75, 79, 73, 78, 70, 81, 86, 76,
+  91, 90, 80, 69, 83, 74, 83, 85, 77, 82,
+  74, 85, 95, 91, 78, 114, 75, 92, 107, 74,
+  79, 85, 77, 108, 79, 79, 83, 90, 82, 79,
+  73, 72, 82, 96, 75, 79, 81, 94, 89, 106,
+  80, 96, 77, 104, 74, 95, 81, 66, 95, 77,
+  110, 73, 80, 71, 94, 81, 92, 74, 90, 75,
+  82, 73, 78, 87, 81, 86, 88, 88, 75, 85,
+  72, 108, 83, 73, 102, 79, 86, 80, 86, 88,
+  78, 85, 78, 87, 85, 100, 89, 84, 73, 75,
+  82, 78, 76, 59, 80, 84, 54, 79, 76, 82,
+  85, 85, 85, 89, 75, 88, 86, 85, 94, 87,
+  99, 82, 78, 99, 68, 97, 111, 79, 75, 81,
+  79, 72, 79, 74, 69, 79, 82, 73, 91, 86,
+  92, 71, 82, 73, 82, 86, 74, 104, 73, 82,
+  90, 88, 73, 122, 83, 93, 101, 75, 81, 88,
+  70, 100, 83, 77, 88, 95, 76, 84, 92, 62,
+  86, 85, 76, 76, 86, 102, 92, 101, 78, 90,
+  74, 91, 84, 83, 83, 70, 95, 85, 109, 75,
+  79, 74, 93, 84, 94, 85, 89, 78, 95, 75,
+  76, 89, 93, 84, 86, 76, 74, 83, 76, 95,
+  86, 81, 100, 76, 90, 74, 82, 83, 88, 89,
+  75, 86, 90, 89, 91, 81, 69, 77, 78, 79,
+  76, 69, 67, 81, 70, 82, 72, 78, 88, 79,
+  100, 79, 76, 88, 72, 84, 102, 92, 100, 86,
+  76, 85, 75, 100, 112, 74, 84, 87, 83, 76,
+  76, 59, 83, 80, 89, 71, 84, 89, 74, 63,
+  81, 70, 82, 88, 99, 86, 73, 84, 80, 78,
+  73, 127, 92, 90, 97, 78, 82, 90, 72, 97,
+  87, 80, 77, 95, 85, 79, 81, 66, 76, 93,
+  61, 80, 76, 93, 85, 106, 85, 76, 78, 87,
+  80, 92, 76, 79, 90, 82, 105, 90, 76, 77,
+  91, 87, 82, 78, 86, 81, 75, 80, 85, 64,
+  85, 70, 83, 82, 80, 95, 73, 96, 83, 70,
+  84, 72, 82, 73, 81, 83, 85, 92, 72, 87,
+  90, 96, 89, 86, 68, 88, 94, 78, 71, 72,
+  86, 88, 64, 77, 74, 76, 91, 90, 122, 85,
+  80, 90, 77, 84, 104, 86, 95, 95, 86, 79,
+  82, 84, 118, 87, 92, 83, 86, 84, 80, 70,
+  70, 88, 93, 86, 82, 94, 62, 79, 83, 83,
+  87, 92, 96, 76, 75, 95, 93, 89, 81, 152,
+  80, 91, 111, 82, 83, 93, 85, 117, 77, 94,
+  76, 92, 102, 80, 79, 83, 75, 111, 74, 76,
+  70, 120, 80, 126, 96, 92, 86, 89, 76, 118,
+  69, 75, 99, 79, 114, 75, 76, 78, 94, 83,
+  85, 66, 95, 82, 72, 75, 90, 71, 80, 66,
+  81, 106, 77, 105, 75, 112, 90, 69, 87, 82,
+  79, 78, 87, 88, 82, 85, 83, 89, 100, 101,
+  92, 71, 64, 85, 79, 85, 74, 71, 64, 99,
+  52, 69, 87, 76, 92, 115, 90, 86, 87, 87,
+  76, 99, 95, 89, 95, 87, 74, 85, 70, 80,
+  106, 83, 85, 86, 86, 74, 89, 57, 74, 76,
+  81, 74, 78, 86, 72, 89, 79, 80, 84, 81,
+  80, 100, 79, 85, 100, 84, 76, 115, 77, 89,
+  94, 80, 84, 96, 74, 95, 90, 82, 75, 94,
+  85, 81, 83, 65, 81, 89, 68, 77, 76, 87,
+  83, 102, 86, 80, 78, 84, 84, 86, 80, 77,
+  97, 84, 103, 83, 80, 78, 91, 86, 83, 93,
+  83, 80, 86, 76, 83, 80, 84, 73, 83, 83,
+  77, 91, 74, 95, 83, 74, 82, 77, 86, 74,
+  80, 81, 85, 88, 74, 84, 101, 92, 91, 76,
+  66, 88, 81, 80, 71, 72, 57, 89, 65, 80,
+  74, 79, 90, 92, 99, 85, 73, 86, 80, 81,
+  100, 99, 99, 85, 76, 95, 75, 98, 113, 77,
+  86, 83, 86, 78, 86, 73, 74, 77, 82, 69,
+  92, 87, 84, 69, 82, 70, 83, 90, 89, 86,
+  77, 84, 86, 77, 87, 135, 90, 99, 92, 79,
+  87, 94, 73, 89, 90, 81, 83, 94, 78, 88,
+  87, 65, 81, 88, 64, 82, 75, 98, 92, 111,
+  86, 72, 76, 88, 85, 83, 80, 83, 90, 83,
+  99, 82, 86, 72, 96, 78, 82, 71, 94, 76,
+  76, 79, 75, 76, 93, 75, 84, 84, 82, 93,
+  69, 92, 87, 75, 90, 73, 93, 71, 79, 79,
+  89, 106, 77, 83, 85, 94, 92, 83, 77, 82,
+  84, 79, 74, 79, 79, 84, 66, 81, 77, 88,
+  84, 81, 108, 81, 80, 83, 82, 83, 100, 95,
+  89, 80, 76, 90, 76, 83, 109, 86, 90, 86,
+  90, 84, 88, 82, 71, 77, 78, 66, 94, 90,
+  74, 86, 80, 79, 92, 86, 91, 79, 80, 84,
+  89, 80, 93, 122, 86, 96, 91, 84, 93, 86,
+  77, 91, 89, 86, 77, 91, 86, 81, 80, 74,
+  78, 90, 77, 85, 73, 90, 81, 109, 97, 77,
+  79, 97, 75, 80, 79, 84, 90, 75, 92, 78,
+  95, 66, 98, 76, 84, 71, 89, 80, 76, 73,
+  80, 75, 90, 75, 79, 90, 80, 92, 67, 99,
+  87, 73, 91, 70, 81, 77, 72, 86, 82, 104,
+  81, 84, 90, 105, 91, 75, 81, 78, 82, 80,
+  72, 79, 69, 83, 57, 72, 81, 90, 77, 96,
+  96, 86, 91, 82, 81, 88, 99, 94, 97, 85,
+  76, 93, 72, 82, 110, 85, 87, 82, 90, 77,
+  87, 72, 73, 77, 81, 72, 87, 85, 82, 88,
+  82, 78, 83, 89, 78, 98, 80, 86, 98, 80,
+  89, 130, 79, 95, 96, 80, 86, 86, 75, 87,
+  89, 81, 79, 92, 77, 82, 85, 69, 80, 83,
+  75, 79, 72, 99, 84, 110, 93, 74, 77, 86,
+  81, 83, 80, 83, 87, 84, 97, 80, 84, 74,
+  96, 85, 85, 89, 95, 79, 81, 77, 78, 83,
+  89, 67, 87, 86, 80, 90, 73, 91, 81, 78,
+  86, 72, 93, 71, 79, 80, 86, 100, 80, 84,
+  92, 93, 94, 75, 77, 87, 84, 82, 77, 79,
+  56, 81, 69, 79, 80, 95, 86, 82, 83, 88,
+  87, 95, 81, 84, 81, 76, 79, 60, 86, 89,
+  71, 78, 79, 90, 76, 83, 84, 97, 92, 88,
+  80, 77, 87, 83, 88, 91, 92, 86, 80, 83,
+  75, 83, 86, 63, 80, 97, 80, 78, 80, 76,
+  89, 83, 75, 90, 84, 96, 77, 77, 78, 89,
+  75, 88, 94, 83, 74, 84, 82, 79, 93, 78,
+  78, 81, 96, 77, 69, 78, 92, 93, 86, 82,
+  89, 85, 90, 71, 81, 100, 77, 90, 83, 77,
+  83, 79, 85, 86, 81, 81, 90, 76, 89, 77,
+  89, 86, 75, 87, 72, 82, 89, 100, 79, 71,
+  74, 81, 80, 85, 70, 79, 81, 90, 80, 85,
+  105, 117, 85, 77, 86, 76, 92, 88, 83, 90,
+  71, 78, 89, 105, 98, 86, 85, 93, 88, 112,
+  79, 90, 83, 72, 82, 60, 93, 93, 87, 79,
+  83, 99, 79, 88, 87, 99, 93, 91, 76, 74,
+  88, 79, 94, 113, 98, 86, 79, 58, 80, 90,
+  91, 82, 78, 96, 80, 72, 83, 82, 95, 89,
+  73, 80, 87, 82, 64, 83, 78, 88, 76, 79,
+  89, 88, 74, 85, 87, 90, 106, 70, 79, 79,
+  72, 78, 78, 86, 84, 90, 81, 85, 69, 84,
+  84, 74, 90, 82, 82, 89, 86, 75, 89, 69,
+  89, 79, 88, 92, 94, 73, 80, 73, 78, 85,
+  65, 96, 73, 91, 89, 89, 79, 79, 104, 82,
+  68, 87, 75, 83, 75, 91, 76, 94, 104, 82,
+  79, 91, 81, 77, 92, 82, 81, 89, 72, 83,
+  93, 90, 107, 93, 80, 79, 91, 105, 84, 99,
+  83, 82, 77, 70, 90, 91, 80, 79, 82, 92,
+  83, 83, 76, 89, 88, 81, 85, 84, 86, 86,
+  84, 91, 79, 91, 85, 67, 80, 91, 87, 125,
+  82, 93, 81, 72, 78, 78, 92, 89, 80, 93,
+  83, 78, 81, 79, 80, 82, 76, 80, 88, 89,
+  80, 83, 87, 82, 94, 70, 82, 77, 82, 78,
+  82, 84, 93, 93, 91, 77, 81, 88, 73, 79,
+  89, 71, 87, 88, 81, 80, 84, 82, 80, 78,
+  116, 79, 90, 77, 88, 80, 91, 90, 80, 91,
+  77, 83, 79, 91, 81, 81, 82, 81, 87, 83,
+  70, 85, 78, 86, 74, 91, 99, 74, 83, 81,
+  88, 78, 95, 88, 73, 91, 72, 75, 87, 114,
+  91, 83, 82, 86, 91, 96, 77, 85, 82, 79,
+  76, 74, 86, 87, 65, 80, 79, 90, 73, 69,
+  92, 93, 95, 91, 75, 75, 85, 90, 87, 94,
+  99, 82, 79, 91, 80, 81, 80, 52, 83, 74,
+  82, 73, 93, 72, 85, 82, 71, 88, 90, 95,
+  75, 78, 80, 82, 81, 80, 88, 83, 79, 86,
+  95, 78, 83, 87, 70, 73, 92, 76, 78, 81,
+  79, 76, 92, 81, 91, 80, 87, 76, 83, 108,
+  74, 92, 84, 77, 84, 74, 84, 73, 79, 91,
+  88, 78, 91, 79, 101, 90, 80, 84, 80, 83,
+  89, 91, 77, 76, 80, 79, 88, 84, 78, 84,
+  87, 86, 81, 92, 87, 126, 85, 89, 78, 80,
+  96, 77, 81, 84, 80, 91, 85, 112, 89, 84,
+  89, 88, 92, 115, 75, 81, 85, 77, 80, 76,
+  96, 97, 79, 84, 78, 94, 74, 70, 118, 88,
+  88, 100, 77, 69, 83, 90, 90, 118, 111, 87,
+  78, 60, 79, 84, 87, 76, 77, 66, 80, 73,
+  100, 70, 93, 89, 71, 78, 95, 87, 55, 85,
+  83, 81, 78, 71, 87, 93, 75, 83, 98, 85,
+  86, 71, 65, 75, 73, 76, 80, 83, 74, 62,
+  85, 84, 78, 79, 82, 77, 86, 85, 81, 90,
+  85, 78, 91, 71, 92, 64, 89, 97, 94, 76,
+  80, 82, 91, 92, 64, 89, 74, 90, 94, 82,
+  77, 72, 114, 80, 70, 79, 82, 92, 83, 82,
+  79, 90, 81, 84, 89, 93, 80, 69, 100, 72,
+  81, 75, 72, 99, 86, 96, 99, 89, 82, 81,
+  83, 104, 81, 90, 83, 81, 77, 86, 92, 89,
+  79, 90, 81, 94, 76, 75, 94, 81, 81, 85,
+  98, 82, 88, 92, 83, 95, 89, 92, 81, 68,
+  84, 88, 86, 131, 85, 70, 81, 73, 85, 71,
+  87, 86, 77, 86, 89, 79, 77, 84, 78, 84,
+  85, 76, 84, 86, 79, 81, 98, 83, 86, 67,
+  69, 72, 69, 75, 89, 83, 83, 82, 79, 72,
+  80, 80, 74, 81, 88, 70, 78, 87, 81, 79,
+  84, 86, 80, 66, 118, 79, 85, 78, 89, 75,
+  100, 94, 76, 83, 83, 82, 79, 83, 77, 79,
+  92, 78, 90, 82, 76, 92, 84, 84, 76, 90,
+  82, 73, 88, 89, 94, 76, 96, 81, 74, 83,
+  84, 88, 81, 118, 86, 85, 88, 91, 91, 90,
+  80, 80, 74, 77, 87, 80, 74, 91, 74, 90,
+  74, 80, 79, 68, 88, 87, 90, 85, 83, 78,
+  91, 91, 86, 67, 67, 79, 76, 103, 86, 95,
+  62, 59, 98, 65, 81, 77, 83, 60, 97, 77,
+  81, 82, 90, 102, 85, 80, 82, 84, 88, 74,
+  83, 79, 83, 81, 90, 81, 78, 86, 78, 80,
+  79, 79, 83, 80, 76, 80, 80, 76, 96, 85,
+  82, 72, 86, 97, 71, 84, 75, 85, 97, 82,
+  90, 59, 67, 80, 82, 79, 92, 79, 106, 93,
+  91, 85, 90, 80, 88, 86, 72, 79, 77, 71,
+  105, 87, 77, 76, 101, 79, 82, 82, 71, 121,
+  89, 95, 75, 91, 87, 77, 85, 82, 90, 95,
+  73, 173, 79, 74, 90, 87, 87, 98, 77, 84,
+  80, 71, 86, 89, 79, 99, 81, 89, 75, 81,
+  73, 73, 97, 80, 90, 92, 82, 76, 88, 94,
+  85, 79, 74, 77, 79, 87, 86, 93, 67, 83,
+  88, 61, 81, 75, 87, 51, 94, 85, 81, 82,
+  88, 93, 74, 82, 83, 87, 88, 68, 85, 87,
+  81, 79, 99, 88, 81, 81, 68, 84, 75, 78,
+  81, 91, 77, 81, 84, 73, 96, 83, 78, 78,
+  82, 84, 78, 79, 74, 90, 96, 77, 95, 54,
+  82, 87, 79, 79, 85, 85, 113, 99, 91, 91,
+  87, 82, 96, 84, 75, 76, 78, 72, 104, 92,
+  76, 80, 103, 77, 82, 84, 64, 86, 92, 100,
+  77, 92, 91, 76, 82, 86, 85, 92, 76, 194,
+  85, 77, 92, 82, 76, 92, 78, 90, 74, 80,
+  86, 89, 76, 92, 81, 88, 76, 82, 82, 71,
+  85, 74, 86, 88, 89, 83, 90, 91, 78, 65,
+  57, 83, 82, 84, 89, 91, 80, 121, 91, 67,
+  87, 72, 81, 60, 89, 78, 86, 85, 91, 84,
+  88, 87, 84, 86, 92, 75, 76, 85, 82, 80,
+  97, 84, 81, 75, 78, 80, 68, 78, 87, 84,
+  80, 83, 76, 73, 87, 82, 72, 75, 91, 80,
+  74, 80, 74, 82, 93, 74, 89, 52, 106, 73,
+  76, 83, 89, 81, 103, 96, 91, 81, 90, 79,
+  90, 83, 70, 74, 85, 69, 106, 90, 74, 79,
+  94, 81, 78, 80, 72, 71, 91, 107, 81, 92,
+  87, 81, 80, 84, 95, 93, 70, 184, 79, 81,
+  87, 73, 92, 82, 91, 104, 75, 78, 81, 81,
+  80, 94, 77, 103, 80, 81, 77, 88, 77, 86,
+  106, 77, 60, 87, 79, 103, 87, 93, 87, 103,
+  83, 69, 78, 84, 89, 74, 86, 88, 76, 72,
+  88, 73, 71, 80, 82, 80, 71, 87, 80, 102,
+  67, 95, 81, 86, 83, 84, 74, 70, 83, 92,
+  94, 83, 79, 78, 86, 90, 87, 94, 82, 90,
+  75, 86, 93, 87, 77, 80, 84, 86, 75, 84,
+  91, 82, 87, 94, 96, 87, 90, 88, 92, 91,
+  76, 79, 77, 91, 65, 77, 81, 87, 114, 87,
+  80, 85, 96, 82, 86, 78, 77, 86, 89, 77,
+  78, 81, 90, 84, 93, 88, 80, 77, 80, 95,
+  80, 95, 79, 84, 92, 85, 88, 94, 105, 74,
+  72, 75, 82, 76, 85, 86, 73, 69, 86, 128,
+  90, 87, 76, 83, 81, 112, 92, 86, 99, 78,
+  68, 73, 90, 108, 87, 91, 89, 93, 99, 63,
+  76, 72, 89, 64, 86, 75, 81, 82, 75, 84,
+  92, 94, 92, 81, 76, 81, 59, 81, 75, 89,
+  90, 82, 91, 86, 82, 59, 87, 97, 101, 63,
+  86, 93, 69, 89, 85, 89, 66, 86, 63, 68,
+  75, 86, 74, 75, 83, 74, 79, 82, 83, 83,
+  94, 80, 114, 75, 86, 89, 92, 104, 85, 82,
+  66, 91, 66, 82, 73, 95, 86, 75, 77, 84,
+  96, 87, 61, 76, 84, 93, 79, 85, 76, 89,
+  93, 79, 90, 84, 72, 81, 86, 79, 88, 100,
+  74, 88, 70, 83, 108, 85, 100, 76, 78, 81,
+  87, 52, 74, 88, 76, 77, 88, 120, 84, 65,
+  76, 86, 73, 105, 84, 85, 69, 76, 87, 82,
+  101, 113, 90, 93, 87, 78, 93, 72, 76, 69,
+  106, 85, 86, 83, 87, 79, 76, 83, 107, 83,
+  88, 83, 87, 81, 65, 93, 71, 90, 82, 90,
+  84, 86, 77, 64, 98, 90, 96, 68, 83, 87,
+  82, 83, 88, 92, 71, 82, 87, 77, 90, 88,
+  81, 81, 87, 83, 94, 83, 92, 78, 94, 81,
+  100, 71, 86, 90, 89, 100, 79, 85, 70, 97,
+  70, 81, 79, 92, 62, 74, 78, 81, 98, 80,
+  73, 78, 76, 89, 84, 82, 74, 86, 90, 92,
+  95, 88, 71, 73, 78, 93, 76, 98, 84, 83,
+  79, 82, 99, 92, 90, 75, 89, 80, 95, 99,
+  82, 75, 85, 77, 87, 86, 78, 92, 83, 79,
+  82, 98, 75, 84, 108, 82, 57, 87, 75, 95,
+  75, 88, 93, 91, 87, 73, 86, 89, 82, 77,
+  80, 91, 88, 79, 92, 75, 62, 84, 80, 86,
+  79, 87, 84, 100, 66, 93, 79, 87, 80, 82,
+  80, 68, 89, 87, 86, 83, 80, 67, 84, 85,
+  79, 90, 77, 75, 82, 91, 84, 87, 82, 78,
+  73, 85, 77, 85, 90, 67, 87, 85, 97, 83,
+  89, 87, 91, 87, 78, 82, 87, 93, 66, 82,
+  76, 89, 122, 83, 77, 90, 86, 83, 87, 84,
+  75, 89, 89, 84, 77, 91, 88, 82, 85, 81,
+  76, 85, 80, 87, 81, 89, 74, 87, 89, 83,
+  80, 88, 104, 76, 74, 61, 73, 74, 90, 91,
+  80, 61, 98, 129, 102, 81, 70, 74, 107, 124,
+  107, 86, 94, 77, 69, 69, 85, 101, 81, 80,
+  86, 80, 111, 66, 79, 73, 77, 60, 80, 68,
+  85, 84, 77, 108, 85, 101, 92, 88, 76, 75,
+  56, 78, 64, 79, 88, 83, 99, 82, 96, 53,
+  92, 102, 96, 64, 79, 102, 72, 86, 74, 93,
+  57, 69, 60, 74, 66, 79, 77, 75, 76, 71,
+  77, 88, 70, 70, 104, 74, 119, 77, 86, 90,
+  80, 90, 83, 74, 73, 95, 61, 84, 74, 100,
+  93, 71, 71, 78, 83, 92, 63, 81, 78, 97,
+  77, 86, 79, 101, 91, 81, 82, 76, 67, 91,
+  93, 76, 81, 102, 66, 92, 61, 76, 118, 81,
+  94, 75, 90, 71, 87, 58, 78, 85, 81, 70,
+  97, 111, 92, 77, 71, 84, 92, 115, 91, 87,
+  63, 73, 89, 79, 98, 102, 82, 87, 91, 77,
+  97, 78, 77, 68, 88, 78, 77, 82, 86, 84,
+  82, 94, 115, 95, 87, 89, 89, 76, 65, 90,
+  64, 84, 83, 91, 88, 83, 88, 63, 101, 90,
+  92, 69, 80, 86, 78, 79, 85, 99, 62, 68,
+  79, 80, 75, 80, 86, 80, 81, 80, 84, 83,
+  86, 64, 97, 87, 102, 76, 83, 91, 82, 91,
+  81, 74, 76, 96, 66, 84, 77, 95, 72, 72,
+  70, 72, 87, 85, 73, 82, 69, 92, 78, 84,
+  69, 98, 89, 94, 85, 81, 68, 85, 85, 85,
+  68, 98, 72, 87, 73, 74, 102, 85, 88, 76,
+  75, 86, 88, 99, 81, 71, 72, 86, 91, 82,
+  78, 89, 79, 90, 96, 98, 94, 79, 95, 84,
+  64, 88, 78, 86, 77, 89, 86, 77, 94, 79,
+  83, 98, 76, 82, 78, 93, 96, 77, 83, 75,
+  63, 79, 75, 74, 89, 93, 89, 97, 76, 85,
+  77, 84, 79, 71, 79, 81, 87, 85, 86, 81,
+  88, 71, 89, 81, 80, 85, 82, 82, 85, 87,
+  91, 82, 77, 86, 76, 84, 86, 92, 78, 88,
+  88, 79, 90, 82, 80, 86, 92, 85, 81, 87,
+  85, 98, 78, 78, 89, 85, 99, 88, 78, 95,
+  86, 84, 93, 84, 74, 81, 83, 81, 80, 94,
+  80, 88, 86, 88, 77, 84, 84, 92, 89, 87,
+  81, 87, 92, 84, 83, 78, 95, 79, 79, 77,
+  63, 74, 87, 83, 68, 74, 96, 115, 91, 86,
+  70, 87, 118, 120, 107, 82, 87, 73, 73, 74,
+  83, 91, 80, 89, 84, 72, 98, 77, 86, 81,
+  66, 68, 84, 68, 88, 78, 80, 87, 77, 96,
+  84, 76, 84, 74, 59, 79, 78, 83, 78, 79,
+  92, 83, 80, 69, 91, 92, 92, 64, 86, 94,
+  84, 84, 82, 88, 70, 87, 72, 73, 77, 75,
+  80, 79, 78, 77, 95, 86, 61, 96, 92, 78,
+  98, 78, 82, 91, 91, 84, 83, 91, 75, 99,
+  82, 83, 92, 92, 88, 83, 78, 87, 85, 93,
+  94, 84, 80, 90, 73, 87, 76, 101, 85, 84,
+  82, 83, 66, 90, 94, 82, 85, 91, 67, 94,
+  71, 79, 110, 77, 85, 77, 87, 81, 77, 62,
+  80, 76, 65, 79, 94, 100, 84, 97, 72, 95,
+  106, 108, 98, 80, 63, 73, 92, 82, 90, 92,
+  81, 92, 82, 77, 97, 81, 82, 78, 75, 81,
+  80, 82, 83, 77, 88, 81, 106, 88, 81, 74,
+  91, 74, 73, 86, 77, 89, 76, 86, 86, 83,
+  80, 80, 97, 86, 94, 76, 86, 88, 89, 83,
+  91, 93, 68, 82, 72, 78, 80, 78, 85, 82,
+  81, 82, 94, 86, 73, 85, 86, 82, 91, 82,
+  84, 86, 91, 89, 82, 84, 83, 98, 80, 87,
+  92, 92, 82, 83, 76, 85, 85, 86, 94, 88,
+  72, 87, 74, 83, 70, 99, 86, 84, 84, 87,
+  70, 86, 92, 88, 79, 91, 74, 90, 77, 81,
+  97, 79, 71, 78, 90, 82, 76, 72, 76, 91,
+  77, 84, 65, 135, 75, 119, 72, 90, 85, 93,
+  82, 120, 91, 70, 103, 85, 70, 73, 89, 89,
+  94, 73, 69, 85, 90, 94, 91, 78, 95, 74,
+  101, 75, 82, 82, 76, 103, 94, 84, 84, 91,
+  82, 74, 93, 72, 80, 80, 84, 92, 87, 87,
+  85, 101, 83, 90, 101, 72, 74, 74, 75, 99,
+  84, 85, 85, 77, 78, 76, 80, 75, 74, 92,
+  80, 82, 84, 95, 86, 105, 75, 75, 89, 82,
+  81, 76, 93, 84, 85, 83, 82, 81, 65, 82,
+  76, 84, 99, 79, 79, 79, 92, 85, 88, 90,
+  72, 83, 89, 92, 81, 96, 72, 82, 77, 82,
+  75, 80, 95, 76, 81, 86, 61, 90, 82, 94,
+  81, 97, 83, 96, 67, 90, 81, 78, 84, 82,
+  72, 99, 102, 99, 90, 91, 75, 87, 88, 95,
+  85, 75, 86, 90, 81, 67, 82, 90, 85, 80,
+  68, 81, 79, 84, 85, 67, 97, 73, 95, 91,
+  82, 88, 80, 88, 85, 87, 78, 100, 75, 84,
+  92, 100, 87, 89, 93, 91, 66, 90, 81, 90,
+  84, 70, 86, 79, 84, 80, 70, 79, 78, 93,
+  85, 91, 74, 76, 77, 83, 78, 73, 80, 100,
+  94, 91, 89, 80, 78, 73, 98, 76, 87, 76,
+  73, 83, 80, 92, 70, 69, 79, 82, 79, 81,
+  84, 74, 84, 76, 83, 79, 88, 83, 88, 87,
+  80, 80, 86, 94, 78, 85, 84, 87, 87, 77,
+  91, 75, 98, 81, 80, 80, 81, 89, 80, 89,
+  75, 88, 63, 74, 80, 78, 88, 74, 70, 71,
+  90, 69, 97, 81, 81, 81, 90, 73, 87, 84,
+  92, 87, 83, 77, 80, 81, 83, 92, 91, 80,
+  70, 83, 93, 73, 103, 75, 92, 92, 85, 87,
+  73, 69, 70, 81, 84, 90, 77, 77, 78, 100,
+  83, 98, 94, 90, 68, 100, 75, 84, 86, 79,
+  74, 76, 92, 96, 93, 87, 89, 85, 83, 106,
+  81, 81, 79, 78, 80, 75, 88, 110, 92, 73,
+  78, 73, 84, 84, 88, 78, 98, 82, 58, 81,
+  78, 101, 73, 72, 77, 77, 84, 89, 79, 82,
+  92, 77, 81, 83, 80, 92, 80, 88, 90, 81,
+  87, 86, 82, 83, 88, 88, 89, 99, 92, 96,
+  82, 89, 89, 80, 92, 87, 61, 69, 75, 76,
+  81, 69, 78, 91, 60, 92, 68, 128, 67, 161,
+  68, 79, 97, 100, 77, 123, 88, 61, 94, 79,
+  74, 77, 90, 95, 99, 59, 68, 87, 91, 86,
+  104, 79, 103, 66, 82, 76, 70, 82, 102, 118,
+  78, 78, 76, 94, 76, 71, 109, 66, 72, 79,
+  86, 83, 107, 67, 91, 95, 74, 85, 98, 56,
+  74, 73, 63, 105, 93, 79, 79, 72, 78, 71,
+  94, 74, 74, 95, 78, 89, 72, 87, 84, 105,
+  76, 66, 87, 77, 68, 80, 87, 86, 83, 78,
+  76, 93, 75, 77, 81, 83, 87, 100, 86, 83,
+  85, 86, 90, 88, 62, 80, 83, 108, 87, 107,
+  66, 77, 66, 81, 73, 85, 84, 72, 64, 87,
+  60, 79, 81, 84, 90, 87, 76, 104, 99, 88,
+  77, 75, 72, 88, 72, 88, 99, 160, 86, 81,
+  91, 84, 89, 93, 83, 77, 70, 89, 91, 79,
+  84, 96, 92, 75, 74, 83, 90, 92, 82, 59,
+  98, 79, 65, 83, 83, 95, 100, 106, 76, 87,
+  83, 113, 83, 73, 93, 84, 88, 87, 90, 79,
+  75, 84, 75, 83, 88, 82, 78, 71, 65, 71,
+  75, 77, 98, 76, 78, 86, 68, 78, 87, 80,
+  76, 68, 76, 100, 89, 74, 103, 67, 93, 76,
+  94, 72, 75, 69, 69, 92, 85, 106, 80, 89,
+  82, 84, 77, 78, 74, 89, 85, 78, 81, 89,
+  89, 79, 84, 80, 80, 112, 84, 87, 81, 78,
+  70, 92, 80, 79, 83, 66, 103, 78, 76, 75,
+  75, 80, 83, 91, 77, 95, 90, 62, 78, 84,
+  87, 74, 76, 73, 82, 80, 94, 93, 83, 76,
+  87, 79, 80, 87, 88, 88, 94, 83, 83, 86,
+  89, 81, 88, 84, 79, 89, 94, 75, 86, 83,
+  87, 81, 87, 75, 85, 76, 72, 79, 78, 84,
+  84, 79, 77, 90, 91, 89, 95, 89, 73, 104,
+  71, 76, 96, 88, 70, 80, 82, 81, 97, 85,
+  97, 83, 80, 89, 81, 85, 79, 83, 82, 77,
+  88, 94, 95, 58, 87, 72, 91, 89, 83, 81,
+  85, 89, 69, 90, 85, 104, 76, 77, 79, 77,
+  80, 87, 78, 81, 87, 76, 81, 93, 75, 84,
+  76, 82, 89, 98, 86, 79, 86, 82, 78, 92,
+  76, 94, 73, 87, 99, 87, 88, 87, 85, 80,
+  71, 75, 71, 70, 61, 70, 86, 110, 74, 87,
+  74, 116, 70, 124, 64, 89, 91, 94, 78, 102,
+  78, 78, 87, 90, 69, 74, 88, 91, 92, 61,
+  76, 87, 88, 85, 106, 92, 108, 82, 87, 87,
+  83, 82, 100, 89, 55, 74, 80, 90, 77, 88,
+  97, 79, 82, 76, 83, 82, 101, 73, 95, 95,
+  69, 76, 93, 65, 65, 83, 62, 86, 78, 72,
+  69, 75, 97, 72, 95, 89, 75, 102, 105, 76,
+  81, 84, 83, 102, 85, 69, 82, 88, 86, 83,
+  112, 77, 87, 71, 75, 84, 74, 65, 79, 84,
+  86, 83, 88, 83, 84, 71, 90, 99, 76, 98,
+  91, 78, 83, 107, 76, 88, 82, 86, 85, 81,
+  69, 79, 76, 93, 73, 81, 82, 94, 81, 75,
+  70, 89, 94, 87, 84, 92, 64, 90, 75, 90,
+  85, 146, 70, 74, 95, 90, 83, 101, 77, 84,
+  75, 85, 79, 69, 79, 92, 89, 73, 83, 82,
+  81, 98, 94, 76, 102, 84, 64, 82, 94, 80,
+  93, 99, 64, 90, 75, 109, 81, 77, 78, 81,
+  86, 82, 82, 66, 103, 83, 80, 83, 85, 99,
+  86, 89, 78, 71, 75, 90, 80, 71, 77, 67,
+  93, 81, 88, 82, 80, 72, 104, 79, 83, 68,
+  92, 80, 88, 84, 85, 74, 68, 72, 79, 76,
+  80, 96, 87, 84, 81, 77, 68, 79, 68, 91,
+  78, 78, 73, 88, 93, 95, 72, 87, 80, 123,
+  79, 87, 96, 74, 77, 92, 78, 84, 74, 71,
+  88, 84, 79, 85, 79, 81, 84, 84, 83, 90,
+  86, 77, 79, 89, 76, 78, 80, 77, 97, 98,
+  79, 79, 84, 82, 86, 90, 78, 94, 96, 85,
+  89, 75, 79, 82, 78, 82, 85, 88, 78, 87,
+  88, 84, 95, 80, 90, 90, 93, 79, 85, 80,
+  67, 90, 74, 98, 80, 81, 75, 97, 88, 84,
+  88, 74, 94, 85, 78, 78, 88, 92, 84, 83,
+  86, 83, 86, 86, 83, 84, 82, 81, 97, 85,
+  80, 87, 84, 76, 89, 84, 82, 62, 90, 82,
+  83, 84, 83, 87, 75, 91, 75, 87, 79, 102,
+  80, 74, 83, 79, 71, 85, 73, 86, 81, 76,
+  78, 90, 80, 93, 72, 80, 90, 102, 77, 83,
+  99, 82, 89, 92, 73, 92, 78, 80, 91, 82,
+  87, 95, 79, 85, 83, 73, 89, 107, 80, 78,
+  98, 55, 65, 69, 79, 89, 83, 81, 101, 84,
+  98, 94, 88, 79, 83, 85, 81, 83, 93, 89,
+  81, 72, 97, 92, 87, 91, 76, 90, 85, 76,
+  84, 89, 89, 87, 76, 76, 92, 72, 70, 67,
+  102, 86, 105, 77, 92, 82, 82, 75, 85, 90,
+  82, 81, 79, 78, 87, 91, 77, 78, 80, 71,
+  83, 79, 88, 86, 79, 83, 84, 73, 85, 84,
+  76, 79, 85, 86, 75, 83, 67, 89, 83, 81,
+  85, 93, 84, 95, 71, 77, 89, 104, 70, 109,
+  99, 69, 87, 85, 77, 83, 78, 107, 94, 79,
+  88, 92, 89, 64, 84, 69, 70, 101, 97, 79,
+  103, 95, 81, 81, 91, 79, 78, 100, 79, 84,
+  77, 79, 76, 95, 83, 117, 76, 67, 110, 57,
+  69, 63, 75, 84, 81, 80, 113, 87, 100, 94,
+  86, 83, 93, 79, 73, 89, 90, 93, 80, 69,
+  102, 89, 87, 86, 77, 78, 87, 80, 86, 88,
+  84, 83, 76, 75, 95, 75, 73, 70, 104, 81,
+  116, 73, 97, 70, 93, 77, 81, 89, 72, 81,
+  72, 77, 91, 90, 75, 78, 70, 75, 91, 78,
+  89, 78, 81, 74, 81, 73, 94, 69, 72, 82,
+  88, 83, 80, 90, 68, 75, 78, 81, 90, 95,
+  85, 102, 70, 74, 71, 100, 69, 109, 89, 75,
+  99, 85, 78, 86, 74, 109, 90, 73, 90, 95,
+  92, 62, 88, 67, 76, 85, 83, 81, 83, 86,
+  77, 82, 89, 79, 73, 111, 71, 84, 78, 75,
+  82, 97, 86, 99, 82, 77, 93, 62, 65, 73,
+  81, 94, 82, 90, 100, 88, 98, 90, 93, 91,
+  81, 84, 80, 78, 84, 88, 85, 72, 90, 84,
+  80, 86, 78, 73, 87, 93, 89, 86, 84, 85,
+  77, 73, 80, 77, 76, 69, 97, 75, 97, 81,
+  88, 83, 78, 81, 86, 91, 85, 83, 76, 75,
+  92, 91, 78, 74, 76, 72, 81, 76, 89, 81,
+  102, 84, 87, 74, 88, 88, 78, 88, 88, 87,
+  75, 82, 70, 78, 84, 82, 97, 93, 85, 97,
+  71, 81, 93, 99, 73, 101, 103, 78, 93, 89,
+  77, 84, 72, 106, 89, 84, 83, 88, 86, 67,
+  86, 71, 72, 83, 84, 78, 79, 89, 87, 85,
+  86, 80, 74, 93, 81, 84, 82, 79, 74, 72,
+  79, 106, 83, 83, 98, 65, 69, 69, 79, 84,
+  84, 81, 102, 94, 104, 91, 90, 77, 93, 78,
+  78, 78, 92, 90, 74, 70, 104, 88, 84, 94,
+  76, 94, 73, 83, 88, 89, 93, 86, 81, 76,
+  91, 74, 77, 73, 91, 89, 99, 80, 84, 74,
+  87, 80, 80, 88, 79, 77, 80, 81, 82, 98,
+  78, 79, 70, 72, 90, 79, 88, 71, 85, 76,
+  84, 74, 68, 82, 77, 79, 82, 90, 76, 75,
+  73, 80, 87, 83, 87, 103, 76, 102, 77, 91,
+  93, 102, 69, 109, 98, 68, 76, 87, 71, 82,
+  73, 101, 82, 69, 89, 88, 82, 66, 92, 77,
+  64, 98, 84, 80, 88, 92, 79, 72, 87, 81,
+  73, 102, 79, 88, 80, 79, 71, 82, 77, 115,
+  79, 71, 104, 66, 73, 62, 73, 79, 80, 86,
+  111, 96, 103, 90, 88, 80, 97, 77, 74, 82,
+  82, 92, 71, 66, 106, 82, 80, 81, 78, 81,
+  77, 83, 87, 85, 85, 81, 80, 75, 101, 73,
+  79, 74, 90, 82, 108, 75, 88, 68, 92, 82,
+  76, 83, 74, 76, 75, 79, 89, 102, 78, 80,
+  69, 78, 94, 79, 96, 69, 78, 65, 81, 68,
+  69, 62, 74, 84, 87, 85, 77, 81, 75, 75,
+  79, 82, 86, 108, 77, 107, 74, 83, 78, 95,
+  68, 108, 88, 75, 89, 89, 73, 78, 68, 102,
+  78, 64, 91, 86, 79, 63, 97, 74, 63, 86,
+  77, 81, 78, 83, 71, 76, 88, 80, 60, 111,
+  68, 85, 77, 77, 79, 90, 84, 97, 88, 79,
+  97, 71, 67, 75, 81, 92, 81, 93, 94, 93,
+  100, 91, 93, 90, 85, 83, 87, 74, 76, 86,
+  78, 70, 95, 76, 82, 85, 80, 74, 80, 93,
+  86, 90, 82, 81, 81, 75, 89, 82, 81, 77,
+  82, 75, 95, 82, 81, 80, 77, 82, 83, 84,
+  84, 79, 82, 78, 83, 97, 84, 75, 65, 72,
+  83, 80, 97, 74, 86, 77, 81, 76, 78, 85,
+  82, 91, 85, 83, 73, 75, 78, 80, 86, 82,
+  91, 100, 77, 96, 76, 82, 94, 96, 73, 98,
+  99, 77, 92, 90, 73, 79, 71, 100, 80, 76,
+  87, 85, 85, 68, 93, 80, 71, 85, 86, 81,
+  81, 91, 84, 75, 87, 82, 71, 97, 81, 86,
+  81, 78, 81, 77, 80, 98, 85, 87, 81, 72,
+  68, 79, 80, 90, 82, 84, 96, 94, 98, 78,
+  90, 77, 97, 89, 76, 70, 87, 82, 86, 73,
+  86, 79, 85, 102, 83, 98, 63, 91, 89, 95,
+  93, 85, 87, 80, 94, 80, 88, 78, 83, 86,
+  83, 89, 82, 83, 77, 81, 87, 89, 90, 82,
+  92, 80, 80, 90, 86, 75, 75, 74, 90, 79,
+  84, 77, 91, 82, 85, 86, 64, 85, 90, 82,
+  79, 86, 79, 77, 77, 84, 83, 84, 88, 92,
+  85, 103, 78, 101, 102, 88, 75, 105, 107, 73,
+  75, 90, 73, 84, 76, 99, 88, 80, 90, 84,
+  83, 77, 86, 77, 72, 91, 86, 79, 81, 96,
+  89, 70, 85, 79, 71, 97, 89, 95, 83, 85,
+  79, 76, 80, 99, 82, 71, 81, 71, 71, 77,
+  81, 88, 80, 85, 90, 95, 98, 75, 92, 75,
+  96, 87, 80, 71, 76, 75, 84, 70, 86, 78,
+  88, 93, 85, 86, 66, 85, 93, 91, 88, 80,
+  88, 81, 94, 78, 85, 77, 75, 81, 90, 87,
+  84, 80, 79, 81, 81, 86, 93, 81, 90, 82,
+  79, 100, 90, 82, 68, 77, 86, 80, 86, 76,
+  81, 75, 83, 81, 57, 75, 91, 82, 85, 84,
+  79, 80, 77, 81, 83, 81, 82, 95, 84, 100,
+  75, 95, 101, 80, 71, 102, 104, 76, 84, 90,
+  73, 83, 71, 98, 83, 78, 90, 81, 78, 74,
+  85, 76, 70, 86, 88, 83, 78, 90, 85, 72,
+  85, 82, 64, 100, 88, 90, 78, 86, 88, 83,
+  87, 92, 89, 78, 81, 76, 66, 83, 81, 96,
+  78, 88, 89, 92, 96, 82, 90, 84, 88, 92,
+  87, 69, 76, 78, 89, 73, 77, 71, 88, 95,
+  88, 84, 75, 90, 86, 96, 88, 80, 84, 76,
+  90, 83, 89, 84, 76, 82, 85, 87, 79, 87,
+  71, 80, 87, 81, 94, 82, 92, 81, 78, 89,
+  91, 72, 76, 73, 84, 78, 87, 82, 82, 83,
+  83, 86, 70, 86, 89, 88, 84, 82, 74, 78,
+  81, 92, 82, 85, 85, 89, 82, 93, 78, 89,
+  102, 89, 76, 92, 105, 78, 89, 85, 78, 83,
+  77, 98, 85, 83, 91, 82, 84, 78, 84, 82,
+  78, 91, 89, 81, 89, 97, 88, 70, 88, 83,
+  72, 97, 88, 93, 85, 87, 64, 84, 89, 68,
+  79, 95, 77, 80, 73, 78, 70, 94, 85, 96,
+  78, 77, 86, 91, 67, 74, 83, 87, 90, 78,
+  91, 93, 65, 83, 103, 88, 93, 71, 70, 74,
+  82, 97, 84, 78, 89, 88, 79, 66, 70, 68,
+  80, 93, 87, 86, 69, 77, 91, 75, 96, 75,
+  70, 89, 78, 80, 77, 101, 82, 75, 88, 80,
+  112, 69, 95, 87, 86, 109, 85, 67, 91, 79,
+  85, 101, 77, 78, 103, 78, 79, 90, 69, 93,
+  70, 73, 108, 100, 81, 137, 82, 80, 71, 80,
+  80, 89, 85, 76, 100, 97, 78, 84, 72, 77,
+  87, 72, 78, 81, 100, 72, 77, 78, 65, 73,
+  88, 81, 97, 82, 83, 87, 127, 80, 107, 88,
+  65, 118, 87, 84, 66, 94, 79, 63, 93, 74,
+  85, 76, 64, 67, 66, 93, 86, 87, 86, 79,
+  99, 87, 60, 74, 78, 70, 76, 89, 97, 93,
+  62, 77, 100, 88, 97, 77, 77, 65, 99, 70,
+  82, 67, 85, 91, 76, 69, 84, 61, 93, 97,
+  86, 81, 77, 67, 88, 67, 91, 72, 66, 79,
+  79, 81, 59, 93, 87, 88, 92, 85, 87, 62,
+  94, 93, 93, 95, 81, 66, 88, 70, 92, 94,
+  80, 76, 106, 89, 75, 92, 83, 88, 75, 76,
+  76, 83, 81, 150, 86, 81, 64, 91, 74, 90,
+  93, 77, 90, 113, 63, 76, 63, 81, 79, 68,
+  72, 74, 107, 61, 89, 83, 69, 86, 82, 73,
+  65, 89, 79, 81, 113, 69, 96, 89, 47, 122,
+  93, 87, 69, 98, 90, 73, 74, 84, 73, 73,
+  79, 79, 68, 95, 73, 80, 82, 84, 87, 87,
+  77, 82, 74, 94, 87, 77, 82, 90, 72, 88,
+  104, 74, 89, 85, 82, 72, 88, 71, 87, 76,
+  78, 87, 77, 67, 87, 76, 76, 90, 94, 81,
+  65, 86, 81, 81, 89, 78, 77, 78, 75, 85,
+  82, 91, 82, 79, 90, 84, 117, 68, 86, 81,
+  87, 102, 101, 67, 84, 78, 88, 95, 74, 88,
+  102, 75, 83, 90, 71, 96, 77, 76, 69, 108,
+  85, 129, 78, 92, 79, 75, 93, 85, 88, 76,
+  83, 93, 88, 89, 79, 80, 83, 76, 95, 81,
+  92, 86, 83, 74, 67, 119, 92, 79, 75, 78,
+  80, 91, 93, 83, 101, 87, 75, 102, 83, 90,
+  77, 72, 82, 77, 86, 96, 88, 94, 67, 74,
+  79, 83, 81, 94, 91, 82, 102, 90, 72, 77,
+  85, 90, 92, 87, 89, 95, 71, 83, 90, 87,
+  99, 77, 74, 82, 83, 101, 77, 77, 87, 87,
+  78, 89, 75, 79, 87, 81, 86, 89, 81, 66,
+  94, 70, 96, 68, 74, 88, 81, 77, 71, 93,
+  85, 77, 76, 92, 98, 74, 96, 77, 94, 76,
+  85, 88, 103, 79, 77, 107, 73, 79, 83, 91,
+  82, 86, 79, 82, 83, 97, 108, 80, 82, 115,
+  85, 87, 79, 78, 77, 90, 85, 79, 95, 95,
+  61, 87, 75, 76, 71, 71, 80, 83, 97, 63,
+  82, 84, 67, 61, 76, 69, 89, 91, 83, 78,
+  112, 69, 99, 88, 58, 92, 85, 78, 85, 78,
+  73, 73, 105, 76, 102, 90, 54, 65, 77, 82,
+  93, 91, 97, 83, 124, 78, 69, 79, 79, 80,
+  76, 102, 100, 94, 69, 78, 87, 85, 105, 91,
+  78, 74, 89, 75, 71, 67, 95, 98, 73, 110,
+  80, 72, 98, 90, 86, 87, 89, 55, 91, 69,
+  90, 63, 67, 76, 82, 83, 59, 79, 91, 84,
+  74, 105, 79, 73, 107, 72, 107, 74, 75, 85,
+  104, 74, 76, 93, 76, 84, 74, 107, 77, 89,
+  99, 79, 93, 111, 71, 64, 83, 106, 80, 77,
+  75, 102, 66, 90, 93, 80, 85, 109, 45, 76,
+  71, 78, 57, 74, 69, 75, 96, 51, 88, 89,
+  75, 71, 76, 67, 67, 104, 82, 76, 90, 63,
+  91, 85, 35, 87, 89, 79, 75, 92, 80, 79,
+  83, 89, 86, 82, 74, 73, 76, 80, 74, 80,
+  88, 88, 99, 89, 80, 88, 81, 91, 89, 82,
+  87, 88, 77, 87, 88, 76, 94, 91, 84, 75,
+  85, 79, 71, 81, 82, 85, 79, 83, 90, 83,
+  87, 88, 94, 84, 80, 71, 88, 78, 85, 70,
+  75, 76, 80, 80, 77, 85, 84, 80, 78, 90,
+  102, 75, 92, 76, 86, 80, 87, 79, 97, 81,
+  85, 96, 69, 98, 77, 85, 81, 86, 79, 97,
+  84, 101, 65, 87, 86, 116, 83, 83, 84, 82,
+  85, 87, 84, 77, 85, 86, 76, 80, 76, 78,
+  66, 72, 92, 79, 93, 72, 82, 79, 71, 112,
+  83, 73, 79, 83, 79, 81, 82, 72, 92, 89,
+  64, 85, 87, 82, 79, 75, 87, 80, 72, 97,
+  86, 87, 79, 86, 77, 90, 88, 89, 94, 86,
+  95, 85, 82, 84, 82, 101, 86, 76, 81, 93,
+  83, 91, 90, 91, 87, 78, 81, 86, 79, 104,
+  76, 80, 80, 86, 78, 91, 86, 83, 77, 65,
+  86, 89, 75, 75, 82, 79, 94, 76, 79, 88,
+  78, 87, 85, 83, 87, 71, 81, 83, 118, 74,
+  88, 73, 86, 87, 84, 88, 95, 79, 80, 91,
+  78, 83, 96, 77, 89, 77, 78, 83, 79, 91,
+  105, 87, 88, 99, 80, 94, 90, 75, 77, 89,
+  79, 72, 93, 74, 85, 85, 86, 80, 82, 75,
+  85, 93, 88, 73, 85, 78, 66, 69, 89, 76,
+  93, 82, 82, 90, 97, 73, 95, 84, 70, 78,
+  84, 82, 78, 74, 82, 80, 81, 79, 93, 82,
+  67, 79, 74, 88, 90, 83, 99, 81, 109, 78,
+  78, 82, 88, 94, 80, 79, 87, 91, 81, 84,
+  86, 94, 81, 91, 85, 77, 83, 81, 71, 79,
+  86, 95, 79, 101, 87, 81, 83, 77, 84, 83,
+  81, 65, 77, 78, 95, 74, 76, 81, 78, 92,
+  80, 69, 90, 81, 85, 83, 109, 70, 90, 70,
+  95, 94, 82, 82, 98, 78, 80, 80, 79, 88,
+  93, 85, 88, 72, 87, 89, 83, 103, 80, 77,
+  83, 94, 74, 93, 87, 82, 69, 91, 84, 73,
+  86, 85, 81, 85, 78, 82, 73, 84, 81, 83,
+  79, 70, 85, 85, 67, 76, 88, 74, 79, 88,
+  83, 86, 80, 69, 79, 81, 56, 75, 85, 77,
+  76, 83, 79, 83, 72, 83, 89, 78, 79, 84,
+  77, 85, 80, 82, 97, 85, 92, 80, 85, 88,
+  89, 102, 88, 73, 79, 89, 86, 92, 88, 84,
+  81, 88, 86, 82, 81, 82, 75, 85, 81, 90,
+  80, 89, 86, 84, 82, 76, 85, 82, 76, 76,
+  82, 84, 88, 79, 77, 79, 76, 91, 88, 82,
+  86, 78, 83, 82, 113, 77, 83, 75, 83, 81,
+  93, 85, 93, 83, 85, 87, 75, 102, 84, 78,
+  90, 80, 79, 100, 79, 94, 76, 88, 88, 98,
+  81, 87, 93, 79, 85, 91, 80, 75, 88, 72,
+  89, 86, 87, 83, 76, 75, 91, 87, 85, 74,
+  85, 72, 71, 103, 90, 78, 82, 76, 78, 90,
+  79, 78, 86, 84, 75, 78, 84, 81, 103, 88,
+  84, 81, 75, 92, 80, 81, 90, 81, 72, 73,
+  76, 71, 72, 84, 70, 92, 82, 103, 80, 92,
+  77, 76, 77, 93, 86, 80, 92, 94, 73, 70,
+  84, 82, 82, 79, 87, 97, 105, 83, 76, 57,
+  86, 75, 93, 91, 96, 63, 99, 78, 89, 71,
+  72, 86, 80, 81, 87, 100, 68, 95, 71, 93,
+  104, 80, 77, 108, 88, 82, 89, 78, 85, 71,
+  107, 68, 80, 94, 81, 68, 95, 83, 80, 88,
+  78, 89, 60, 92, 85, 80, 81, 88, 93, 89,
+  81, 89, 103, 64, 80, 81, 86, 92, 97, 76,
+  79, 83, 85, 103, 88, 86, 74, 76, 62, 87,
+  61, 96, 70, 76, 73, 100, 81, 75, 76, 85,
+  80, 75, 74, 87, 73, 71, 138, 83, 85, 77,
+  84, 68, 71, 88, 82, 83, 84, 79, 124, 88,
+  71, 80, 74, 74, 79, 85, 80, 126, 66, 89,
+  82, 79, 74, 84, 85, 85, 92, 74, 80, 91,
+  77, 94, 75, 71, 98, 105, 75, 61, 89, 77,
+  110, 74, 98, 90, 102, 99, 74, 99, 80, 79,
+  80, 70, 56, 98, 80, 74, 89, 62, 96, 116,
+  68, 111, 85, 63, 77, 71, 86, 87, 72, 80,
+  91, 74, 79, 88, 83, 79, 70, 62, 83, 74,
+  47, 86, 81, 99, 76, 77, 71, 76, 75, 91,
+  71, 56, 95, 78, 83, 84, 90, 82, 106, 83,
+  83, 107, 72, 81, 86, 83, 85, 84, 84, 84,
+  70, 78, 79, 95, 89, 73, 77, 105, 74, 108,
+  71, 83, 77, 91, 81, 79, 91, 83, 78, 75,
+  82, 81, 87, 81, 71, 70, 64, 95, 70, 85,
+  76, 89, 83, 104, 93, 91, 92, 79, 82, 95,
+  83, 80, 87, 93, 81, 81, 75, 81, 85, 86,
+  83, 99, 71, 84, 80, 68, 78, 85, 82, 100,
+  87, 77, 101, 78, 82, 69, 73, 86, 79, 76,
+  93, 93, 78, 96, 76, 94, 88, 80, 85, 99,
+  79, 80, 94, 81, 63, 69, 103, 66, 90, 91,
+  81, 71, 98, 75, 84, 92, 84, 84, 72, 86,
+  96, 79, 78, 86, 96, 89, 87, 84, 99, 62,
+  86, 83, 83, 95, 97, 83, 77, 84, 87, 94,
+  85, 81, 77, 72, 82, 92, 68, 88, 82, 77,
+  89, 93, 83, 76, 73, 84, 87, 77, 76, 92,
+  75, 80, 103, 89, 86, 81, 72, 89, 78, 81,
+  89, 78, 67, 76, 48, 91, 74, 83, 73, 88,
+  75, 101, 86, 81, 79, 76, 76, 92, 72, 73,
+  90, 81, 78, 65, 81, 87, 74, 76, 71, 85,
+  71, 73, 74, 53, 89, 75, 103, 98, 85, 70,
+  94, 76, 91, 65, 76, 84, 81, 70, 91, 96,
+  67, 100, 70, 88, 110, 64, 84, 90, 93, 89,
+  85, 83, 65, 59, 105, 74, 80, 101, 81, 63,
+  91, 78, 75, 87, 72, 89, 60, 87, 91, 83,
+  72, 88, 89, 98, 80, 82, 102, 62, 80, 93,
+  72, 88, 90, 79, 75, 82, 85, 94, 99, 83,
+  74, 75, 75, 88, 62, 103, 61, 75, 71, 88,
+  71, 76, 83, 81, 78, 80, 64, 92, 68, 65,
+  168, 86, 96, 99, 87, 71, 69, 95, 91, 83,
+  76, 83, 141, 106, 74, 86, 78, 57, 73, 81,
+  79, 141, 64, 96, 80, 74, 64, 81, 90, 88,
+  99, 86, 93, 96, 80, 93, 73, 93, 130, 100,
+  64, 59, 89, 82, 106, 68, 92, 90, 105, 91,
+  74, 133, 84, 84, 88, 92, 57, 112, 78, 70,
+  65, 61, 93, 124, 66, 132, 73, 57, 84, 50,
+  99, 78, 53, 83, 84, 71, 80, 88, 77, 88,
+  68, 67, 98, 68, 47, 88, 76, 117, 86, 69,
+  69, 65, 75, 86, 68, 55, 108, 86, 92, 87,
+  74, 57, 114, 83, 72, 117, 87, 83, 89, 80,
+  99, 79, 90, 79, 64, 73, 88, 89, 82, 64,
+  73, 93, 74, 123, 65, 72, 66, 94, 80, 71,
+  79, 84, 79, 81, 82, 81, 92, 77, 66, 74,
+  48, 86, 74, 88, 77, 93, 80, 101, 96, 70,
+  92, 79, 79, 98, 78, 72, 85, 83, 72, 83,
+  76, 86, 72, 84, 75, 90, 85, 75, 82, 61,
+  84, 79, 95, 108, 75, 66, 93, 78, 88, 59,
+  75, 84, 82, 73, 95, 90, 78, 103, 80, 95,
+  98, 64, 83, 86, 86, 94, 87, 86, 64, 62,
+  101, 77, 84, 98, 78, 77, 90, 69, 79, 89,
+  79, 89, 69, 88, 98, 77, 66, 92, 85, 104,
+  81, 80, 98, 62, 83, 90, 79, 87, 92, 86,
+  70, 84, 86, 92, 90, 77, 74, 75, 75, 95,
+  64, 95, 62, 78, 94, 85, 78, 80, 68, 81,
+  83, 76, 66, 94, 72, 71, 103, 77, 88, 91,
+  87, 89, 83, 77, 82, 79, 73, 78, 86, 98,
+  71, 76, 74, 95, 90, 90, 94, 108, 78, 78,
+  85, 88, 84, 80, 85, 82, 95, 78, 82, 89,
+  80, 73, 76, 83, 79, 88, 82, 69, 93, 75,
+  81, 87, 86, 77, 91, 78, 93, 79, 74, 90,
+  83, 86, 78, 93, 67, 100, 86, 86, 97, 87,
+  78, 100, 94, 96, 85, 91, 75, 65, 102, 82,
+  82, 97, 90, 70, 93, 81, 76, 92, 79, 92,
+  69, 78, 86, 90, 78, 87, 85, 88, 81, 81,
+  90, 79, 88, 76, 82, 92, 81, 78, 82, 80,
+  89, 71, 107, 88, 89, 72, 97, 87, 76, 97,
+  74, 85, 69, 85, 94, 90, 86, 93, 79, 87,
+  65, 97, 76, 81, 97, 84, 78, 100, 84, 71,
+  75, 88, 75, 75, 82, 90, 90, 74, 83, 78,
+  79, 72, 84, 87, 85, 105, 73, 82, 79, 81,
+  82, 72, 80, 89, 71, 88, 89, 77, 78, 93,
+  74, 86, 85, 86, 77, 64, 85, 72, 86, 81,
+  77, 82, 90, 87, 88, 79, 80, 84, 84, 67,
+  57, 80, 67, 99, 81, 87, 97, 99, 81, 95,
+  83, 96, 78, 77, 83, 73, 91, 82, 85, 75,
+  89, 84, 92, 79, 72, 84, 73, 79, 53, 86,
+  92, 96, 67, 83, 71, 82, 70, 96, 86, 84,
+  90, 89, 77, 85, 79, 70, 89, 84, 77, 88,
+  92, 77, 80, 75, 92, 82, 74, 92, 70, 72,
+  88, 76, 80, 78, 79, 95, 73, 100, 60, 94,
+  72, 83, 88, 79, 82, 88, 87, 78, 88, 74,
+  89, 78, 72, 80, 82, 91, 73, 83, 79, 100,
+  95, 94, 95, 91, 80, 79, 77, 93, 91, 80,
+  80, 83, 85, 90, 83, 76, 77, 84, 80, 84,
+  104, 94, 83, 72, 98, 80, 80, 94, 74, 82,
+  87, 81, 91, 82, 73, 88, 87, 77, 86, 95,
+  77, 99, 86, 83, 89, 78, 78, 97, 79, 97,
+  83, 86, 88, 66, 95, 83, 85, 96, 86, 78,
+  84, 72, 79, 94, 87, 80, 70, 79, 94, 83,
+  77, 86, 82, 106, 80, 80, 89, 74, 88, 80,
+  93, 92, 79, 94, 81, 81, 89, 75, 100, 83,
+  86, 72, 95, 89, 77, 87, 74, 79, 75, 80,
+  92, 91, 72, 90, 81, 86, 66, 90, 81, 79,
+  83, 80, 103, 69, 73, 87, 86, 73, 72, 87,
+  84, 78, 83, 48, 57, 82, 87, 103, 85, 78,
+  77, 74, 95, 84, 81, 106, 83, 88, 92, 88,
+  96, 87, 74, 88, 87, 79, 86, 80, 82, 78,
+  72, 74, 83, 78, 76, 73, 88, 85, 78, 75,
+  72, 86, 65, 73, 87, 83, 102, 74, 74, 98,
+  76, 79, 94, 70, 96, 69, 76, 102, 72, 118,
+  87, 86, 98, 96, 75, 82, 76, 87, 82, 68,
+  81, 79, 91, 118, 80, 84, 89, 85, 73, 85,
+  85, 87, 84, 86, 82, 82, 77, 56, 100, 83,
+  93, 85, 104, 93, 77, 87, 81, 80, 81, 72,
+  81, 92, 77, 86, 121, 71, 119, 88, 104, 76,
+  65, 72, 96, 85, 82, 80, 89, 69, 69, 84,
+  90, 72, 82, 83, 86, 67, 64, 87, 88, 66,
+  87, 69, 57, 77, 86, 116, 94, 91, 86, 58,
+  85, 85, 95, 122, 84, 98, 94, 95, 100, 79,
+  70, 74, 88, 69, 82, 77, 60, 73, 63, 76,
+  86, 83, 74, 62, 90, 78, 81, 69, 68, 82,
+  65, 80, 83, 91, 90, 68, 79, 104, 72, 78,
+  88, 62, 96, 61, 73, 102, 61, 114, 99, 90,
+  90, 81, 88, 80, 69, 75, 84, 82, 78, 78,
+  80, 85, 96, 76, 76, 79, 71, 100, 85, 89,
+  82, 96, 70, 97, 94, 55, 96, 82, 73, 83,
+  108, 97, 90, 92, 74, 80, 90, 70, 87, 96,
+  80, 73, 109, 60, 84, 89, 104, 83, 70, 72,
+  89, 85, 85, 82, 83, 63, 79, 80, 86, 74,
+  78, 92, 84, 75, 76, 91, 89, 81, 83, 82,
+  55, 86, 90, 100, 91, 91, 89, 76, 79, 86,
+  86, 101, 92, 90, 87, 80, 94, 79, 75, 65,
+  96, 108, 95, 82, 52, 74, 71, 74, 80, 82,
+  79, 72, 91, 84, 79, 77, 76, 81, 70, 75,
+  90, 99, 106, 76, 75, 94, 76, 85, 92, 69,
+  97, 68, 92, 105, 67, 97, 109, 89, 104, 89,
+  90, 86, 79, 86, 84, 70, 85, 83, 85, 79,
+  85, 81, 84, 85, 75, 90, 86, 105, 83, 91,
+  89, 84, 81, 59, 80, 87, 94, 90, 99, 93,
+  81, 99, 81, 84, 80, 76, 84, 93, 77, 87,
+  97, 68, 84, 87, 105, 81, 78, 69, 89, 87,
+  81, 82, 89, 71, 76, 78, 97, 83, 70, 96,
+  96, 73, 68, 76, 83, 73, 79, 73, 81, 89,
+  84, 101, 91, 71, 85, 79, 87, 87, 91, 112,
+  83, 91, 97, 90, 102, 80, 71, 103, 80, 69,
+  79, 80, 67, 87, 79, 71, 78, 75, 81, 62,
+  90, 87, 79, 61, 63, 80, 64, 84, 82, 80,
+  91, 95, 72, 108, 92, 78, 79, 89, 108, 74,
+  87, 92, 86, 90, 97, 77, 80, 84, 75, 80,
+  74, 78, 91, 78, 72, 88, 79, 87, 84, 71,
+  99, 80, 73, 78, 85, 83, 80, 91, 79, 81,
+  87, 69, 99, 93, 73, 90, 102, 93, 95, 82,
+  82, 78, 79, 74, 93, 85, 77, 89, 85, 67,
+  99, 90, 104, 86, 84, 76, 99, 80, 94, 77,
+  88, 56, 70, 100, 82, 92, 87, 71, 93, 71,
+  75, 66, 87, 63, 87, 64, 81, 85, 87, 89,
+  97, 57, 88, 63, 75, 100, 120, 136, 79, 100,
+  98, 90, 121, 84, 73, 87, 80, 59, 78, 94,
+  66, 92, 86, 84, 83, 61, 79, 64, 100, 77,
+  87, 60, 60, 71, 69, 104, 74, 71, 73, 94,
+  82, 92, 104, 78, 75, 90, 73, 67, 105, 88,
+  86, 77, 69, 93, 74, 86, 79, 80, 79, 70,
+  86, 98, 68, 91, 84, 53, 90, 81, 75, 73,
+  75, 90, 78, 76, 86, 100, 68, 99, 102, 78,
+  110, 91, 68, 76, 103, 97, 98, 77, 77, 73,
+  75, 76, 93, 77, 81, 68, 66, 72, 63, 98,
+  101, 92, 86, 82, 101, 83, 95, 75, 79, 58,
+  69, 105, 100, 84, 71, 89, 94, 68, 71, 77,
+  85, 75, 82, 68, 76, 93, 89, 98, 91, 84,
+  85, 82, 88, 87, 100, 107, 84, 91, 89, 75,
+  100, 82, 68, 72, 87, 96, 85, 86, 68, 83,
+  81, 74, 81, 83, 86, 57, 95, 80, 78, 65,
+  71, 76, 65, 88, 81, 85, 91, 92, 78, 97,
+  88, 75, 81, 82, 103, 72, 97, 94, 79, 92,
+  102, 82, 82, 84, 92, 80, 79, 82, 94, 79,
+  73, 88, 81, 72, 86, 83, 85, 83, 72, 86,
+  85, 79, 80, 91, 78, 85, 86, 78, 90, 90,
+  74, 84, 92, 93, 88, 87, 84, 78, 81, 75,
+  95, 79, 74, 88, 78, 68, 90, 89, 101, 90,
+  78, 77, 87, 78, 91, 81, 86, 57, 86, 79,
+  92, 83, 69, 88, 82, 76, 74, 83, 86, 86,
+  79, 88, 80, 87, 79, 86, 91, 84, 91, 91,
+  97, 90, 87, 96, 88, 85, 91, 84, 92, 90,
+  77, 110, 76, 90, 82, 78, 59, 84, 84, 74,
+  84, 67, 73, 59, 90, 80, 77, 76, 69, 76,
+  71, 85, 84, 88, 93, 90, 85, 91, 91, 80,
+  89, 84, 110, 79, 90, 76, 90, 85, 107, 87,
+  78, 81, 72, 78, 83, 87, 92, 81, 66, 72,
+  81, 89, 75, 80, 94, 77, 95, 89, 75, 77,
+  90, 101, 89, 83, 70, 75, 92, 85, 92, 90,
+  89, 86, 88, 70, 88, 78, 76, 84, 84, 79,
+  69, 86, 75, 72, 88, 89, 91, 90, 90, 75,
+  93, 81, 90, 87, 92, 82, 83, 80, 90, 93,
+  84, 78, 77, 75, 76, 83, 84, 77, 78, 72,
+  82, 81, 84, 88, 95, 81, 91, 77, 86, 89,
+  99, 94, 82, 92, 85, 87, 95, 93, 74, 98,
+  75, 78, 79, 84, 64, 81, 93, 71, 88, 60,
+  70, 68, 89, 82, 81, 75, 65, 76, 68, 95,
+  80, 81, 83, 84, 86, 76, 99, 86, 92, 73,
+  91, 69, 89, 77, 89, 103, 86, 91, 75, 87,
+  72, 75, 93, 78, 95, 100, 58, 62, 79, 70,
+  75, 87, 79, 86, 89, 98, 72, 87, 99, 101,
+  85, 91, 76, 84, 95, 82, 92, 89, 87, 87,
+  84, 69, 85, 75, 64, 80, 82, 90, 71, 77,
+  80, 76, 78, 91, 88, 97, 91, 79, 87, 75,
+  88, 95, 89, 76, 90, 97, 91, 89, 69, 100,
+  79, 72, 78, 88, 90, 89, 81, 61, 76, 86,
+  83, 84, 91, 87, 84, 94, 83, 92, 94, 87,
+  85, 87, 81, 80, 89, 95, 72, 92, 80, 100,
+  82, 83, 85, 81, 82, 77, 80, 72, 79, 68,
+  89, 84, 81, 79, 69, 89, 66, 83, 82, 77,
+  93, 87, 89, 88, 93, 80, 91, 79, 100, 74,
+  86, 76, 90, 95, 92, 90, 79, 81, 76, 80,
+  89, 81, 91, 86, 64, 71, 82, 76, 74, 85,
+  82, 89, 94, 91, 76, 79, 92, 98, 88, 76,
+  72, 81, 93, 83, 88, 82, 86, 86, 87, 75,
+  84, 77, 75, 84, 86, 77, 67, 90, 85, 78,
+  100, 86, 89, 96, 94, 78, 85, 78, 84, 96,
+  89, 80, 83, 81, 89, 86, 90, 88, 83, 86,
+  76, 87, 88, 82, 86, 82, 78, 91, 100, 88,
+  75, 77, 89, 81, 92, 83, 85, 83, 79, 81,
+  87, 82, 84, 79, 89, 83, 88, 92, 89, 78,
+  68, 76, 78, 113, 78, 88, 96, 95, 79, 88,
+  86, 75, 87, 80, 88, 83, 68, 83, 84, 77,
+  82, 98, 67, 77, 84, 93, 99, 95, 82, 89,
+  94, 84, 87, 92, 87, 78, 83, 88, 84, 91,
+  80, 91, 89, 87, 75, 81, 77, 89, 93, 75,
+  91, 76, 71, 82, 86, 88, 83, 83, 85, 77,
+  85, 82, 82, 93, 85, 76, 93, 84, 86, 88,
+  83, 89, 78, 78, 87, 79, 93, 92, 80, 81,
+  81, 75, 71, 79, 84, 81, 77, 89, 95, 88,
+  96, 80, 85, 81, 102, 96, 92, 86, 66, 84,
+  94, 74, 93, 85, 82, 87, 99, 85, 86, 76,
+  82, 76, 85, 84, 94, 88, 72, 83, 79, 91,
+  76, 80, 87, 82, 97, 78, 96, 60, 78, 79,
+  84, 108, 87, 80, 114, 96, 74, 96, 92, 73,
+  83, 77, 78, 84, 75, 88, 73, 78, 74, 95,
+  60, 78, 84, 91, 93, 94, 80, 91, 93, 77,
+  87, 106, 87, 81, 82, 88, 71, 91, 84, 115,
+  90, 84, 92, 80, 72, 92, 85, 76, 92, 76,
+  69, 85, 73, 96, 80, 90, 90, 77, 82, 97,
+  80, 77, 79, 75, 90, 82, 87, 77, 89, 83,
+  79, 82, 86, 79, 90, 85, 82, 84, 76, 72,
+  79, 71, 86, 82, 75, 94, 91, 98, 84, 83,
+  79, 82, 81, 94, 85, 89, 77, 85, 88, 84,
+  83, 75, 77, 86, 96, 89, 82, 80, 78, 81,
+  84, 80, 90, 80, 79, 81, 80, 81, 83, 89,
+  88, 87, 83, 82, 87, 76, 80, 79, 72, 109,
+  88, 85, 102, 89, 81, 89, 83, 74, 89, 80,
+  80, 82, 71, 89, 91, 82, 78, 96, 71, 82,
+  84, 94, 96, 95, 81, 91, 90, 83, 85, 93,
+  87, 80, 85, 89, 86, 93, 76, 96, 89, 86,
+  77, 86, 80, 97, 80, 75, 94, 75, 69, 81,
+  77, 90, 85, 84, 86, 80, 86, 81, 82, 81,
+  82, 75, 97, 90, 89, 87, 82, 86, 76, 77,
+  88, 90, 84, 97, 88, 77, 82, 73, 75, 82,
+  82, 85, 79, 87, 100, 86, 80, 76, 77, 80,
+  85, 82, 82, 88, 82, 78, 97, 82, 93, 80,
+  77, 85, 107, 90, 83, 79, 93, 73, 85, 78,
+  83, 86, 82, 77, 87, 72, 85, 77, 88, 90,
+  94, 87, 75, 84, 68, 73, 75, 96, 74, 96,
+  93, 92, 68, 92, 98, 77, 82, 82, 81, 82,
+  79, 90, 83, 75, 89, 102, 76, 75, 72, 92,
+  96, 93, 79, 86, 107, 84, 93, 87, 85, 76,
+  78, 90, 75, 86, 73, 86, 87, 79, 76, 76,
+  82, 102, 94, 74, 82, 75, 87, 79, 84, 94,
+  83, 90, 87, 88, 95, 90, 74, 93, 80, 76,
+  88, 90, 75, 88, 83, 84, 72, 75, 86, 80,
+  75, 93, 78, 98, 90, 71, 69, 81, 88, 84,
+  85, 76, 90, 75, 88, 85, 84, 77, 99, 84,
+  89, 87, 70, 74, 109, 81, 104, 77, 75, 99,
+  116, 83, 102, 79, 82, 67, 78, 83, 98, 100,
+  81, 81, 81, 89, 82, 91, 93, 86, 98, 70,
+  89, 88, 76, 76, 69, 85, 80, 86, 108, 93,
+  55, 86, 102, 75, 81, 74, 84, 86, 82, 76,
+  77, 73, 73, 113, 77, 68, 71, 95, 83, 78,
+  84, 84, 107, 77, 75, 95, 95, 70, 71, 97,
+  61, 78, 65, 110, 88, 85, 97, 78, 72, 118,
+  78, 74, 86, 78, 99, 72, 68, 109, 75, 88,
+  96, 89, 73, 100, 67, 71, 72, 76, 83, 85,
+  72, 79, 89, 79, 80, 80, 89, 70, 74, 79,
+  73, 107, 89, 67, 81, 76, 102, 83, 90, 78,
+  92, 85, 77, 83, 106, 80, 77, 86, 83, 87,
+  81, 74, 93, 78, 84, 75, 78, 82, 98, 91,
+  87, 87, 74, 76, 76, 77, 98, 78, 78, 77,
+  82, 86, 85, 100, 86, 85, 84, 76, 81, 92,
+  88, 72, 70, 91, 86, 91, 93, 88, 74, 88,
+  99, 76, 89, 86, 78, 81, 83, 78, 88, 76,
+  84, 94, 80, 83, 70, 90, 91, 90, 83, 83,
+  97, 89, 78, 89, 90, 77, 77, 90, 77, 87,
+  64, 90, 87, 78, 78, 92, 87, 113, 77, 79,
+  86, 69, 87, 77, 79, 91, 79, 89, 86, 90,
+  77, 88, 75, 74, 75, 75, 79, 99, 74, 88,
+  80, 82, 81, 75, 85, 87, 81, 97, 81, 95,
+  90, 72, 70, 84, 85, 86, 88, 80, 93, 78,
+  71, 73, 68, 80, 80, 77, 85, 80, 97, 88,
+  89, 82, 80, 71, 66, 91, 91, 79, 79, 86,
+  83, 86, 75, 64, 75, 79, 85, 89, 86, 72,
+  84, 82, 88, 83, 96, 91, 91, 81, 72, 64,
+  76, 70, 77, 91, 76, 80, 96, 72, 96, 81,
+  75, 75, 79, 81, 85, 83, 87, 83, 110, 91,
+  76, 81, 86, 84, 89, 86, 66, 87, 104, 81,
+  93, 66, 90, 76, 82, 79, 91, 79, 109, 60,
+  87, 66, 72, 79, 89, 105, 94, 78, 91, 69,
+  92, 81, 91, 76, 86, 80, 81, 78, 113, 79,
+  88, 85, 98, 77, 86, 80, 76, 99, 72, 85,
+  69, 83, 70, 81, 85, 101, 72, 86, 89, 89,
+  69, 94, 84, 81, 86, 73, 83, 75, 67, 70,
+  89, 81, 79, 70, 84, 79, 92, 89, 94, 84,
+  78, 77, 69, 94, 88, 79, 90, 87, 74, 76,
+  72, 66, 84, 75, 87, 82, 89, 87, 84, 92,
+  88, 81, 87, 76, 91, 105, 78, 56, 68, 61,
+  69, 80, 69, 77, 97, 65, 106, 77, 74, 74,
+  84, 87, 87, 84, 84, 72, 99, 94, 86, 79,
+  83, 82, 81, 71, 70, 84, 115, 92, 81, 67,
+  100, 71, 83, 82, 95, 66, 104, 55, 87, 71,
+  74, 84, 82, 121, 90, 84, 90, 72, 92, 77,
+  87, 84, 89, 73, 93, 79, 92, 80, 79, 77,
+  95, 78, 79, 103, 72, 88, 72, 83, 73, 88,
+  75, 74, 95, 95, 68, 97, 92, 87, 73, 95,
+  84, 78, 84, 77, 82, 72, 64, 74, 105, 80,
+  77, 69, 85, 79, 94, 85, 86, 78, 79, 77,
+  68, 90, 83, 81, 76, 87, 79, 88, 79, 69,
+  90, 75, 83, 86, 83, 105, 89, 90, 90, 81,
+  82, 81, 92, 85, 82, 67, 76, 71, 79, 88,
+  75, 81, 108, 84, 103, 81, 82, 84, 81, 75,
+  84, 70, 82, 81, 112, 86, 75, 87, 81, 79,
+  84, 88, 69, 83, 95, 86, 70, 68, 92, 80,
+  81, 79, 90, 71, 89, 61, 85, 72, 72, 95,
+  89, 110, 88, 87, 92, 69, 92, 76, 96, 76,
+  81, 82, 78, 77, 82, 76, 90, 75, 95, 78,
+  86, 89, 73, 95, 73, 83, 82, 77, 74, 81,
+  94, 103, 80, 85, 92, 90, 69, 96, 85, 81,
+  90, 82, 83, 76, 86, 86, 81, 65, 85, 76,
+  78, 70, 87, 51, 86, 82, 77, 84, 82, 85,
+  69, 83, 83, 76, 91, 93, 88, 80, 84, 84,
+  84, 70, 81, 80, 86, 75, 85, 74, 88, 76,
+  80, 73, 88, 80, 82, 67, 88, 71, 87, 89,
+  77, 88, 88, 75, 83, 91, 71, 67, 102, 84,
+  79, 69, 97, 94, 85, 68, 120, 79, 81, 76,
+  76, 91, 87, 79, 81, 74, 82, 96, 82, 84,
+  81, 81, 73, 70, 86, 87, 90, 91, 97, 140,
+  77, 96, 88, 79, 88, 98, 92, 83, 81, 83,
+  90, 83, 89, 80, 92, 86, 148, 78, 69, 75,
+  78, 85, 80, 82, 79, 80, 94, 81, 83, 88,
+  95, 74, 91, 89, 81, 84, 74, 73, 87, 53,
+  77, 78, 82, 85, 82, 73, 85, 85, 78, 70,
+  85, 49, 91, 86, 76, 86, 86, 85, 69, 86,
+  75, 81, 91, 92, 74, 77, 85, 85, 84, 77,
+  90, 76, 88, 69, 87, 79, 94, 99, 84, 75,
+  86, 72, 78, 69, 86, 75, 91, 85, 77, 78,
+  85, 72, 88, 87, 73, 66, 100, 88, 77, 66,
+  94, 96, 91, 67, 125, 75, 71, 75, 72, 92,
+  85, 78, 88, 73, 75, 93, 78, 83, 87, 70,
+  81, 69, 88, 85, 85, 86, 99, 130, 82, 97,
+  86, 75, 82, 96, 90, 84, 76, 87, 88, 89,
+  77, 76, 88, 94, 158, 81, 69, 77, 81, 88,
+  79, 77, 78, 79, 94, 68, 85, 87, 82, 70,
+  83, 91, 84, 81, 73, 73, 87, 47, 71, 78,
+  83, 80, 79, 74, 86, 95, 83, 78, 92, 58,
+  83, 82, 84, 78, 83, 85, 76, 83, 85, 78,
+  88, 80, 77, 93, 92, 87, 84, 62, 83, 81,
+  88, 71, 93, 77, 91, 115, 75, 81, 80, 76,
+  79, 71, 79, 77, 94, 96, 93, 83, 99, 82,
+  83, 86, 72, 74, 100, 84, 92, 75, 89, 86,
+  78, 74, 110, 77, 71, 79, 91, 90, 89, 82,
+  76, 72, 86, 83, 78, 82, 79, 67, 83, 75,
+  87, 79, 95, 93, 96, 114, 110, 79, 83, 83,
+  91, 88, 92, 87, 76, 89, 88, 78, 72, 96,
+  88, 89, 113, 75, 85, 77, 68, 89, 81, 87,
+  76, 76, 84, 65, 87, 90, 85, 84, 93, 91,
+  89, 89, 91, 68, 86, 70, 85, 88, 88, 77,
+  94, 65, 93, 74, 70, 75, 77, 29, 105, 88,
+  79, 95, 92, 86, 82, 81, 84, 89, 97, 105,
+  81, 77, 78, 90, 79, 90, 95, 83, 85, 80,
+  70, 79, 89, 60, 92, 79, 88, 81, 85, 75,
+  83, 69, 84, 87, 88, 92, 74, 73, 84, 74,
+  76, 70, 87, 81, 71, 71, 94, 111, 87, 70,
+  100, 82, 82, 67, 73, 85, 80, 76, 90, 76,
+  69, 78, 84, 82, 95, 97, 81, 80, 84, 92,
+  75, 70, 99, 82, 67, 107, 85, 68, 69, 80,
+  86, 86, 86, 82, 83, 97, 98, 70, 74, 80,
+  182, 81, 51, 83, 84, 86, 74, 81, 82, 80,
+  91, 104, 77, 87, 89, 52, 78, 88, 88, 86,
+  68, 85, 87, 63, 62, 82, 81, 82, 87, 75,
+  89, 79, 69, 74, 75, 26, 115, 90, 78, 93,
+  97, 87, 88, 86, 86, 87, 82, 111, 70, 78,
+  81, 92, 80, 97, 109, 87, 85, 65, 71, 82,
+  94, 102, 95, 78, 94, 79, 82, 86, 94, 67,
+  87, 81, 85, 77, 66, 76, 88, 73, 78, 66,
+  79, 80, 70, 67, 98, 110, 93, 68, 98, 79,
+  64, 73, 81, 82, 75, 70, 84, 76, 62, 74,
+  72, 82, 101, 79, 84, 82, 86, 91, 74, 74,
+  99, 66, 77, 99, 82, 65, 66, 79, 81, 83,
+  79, 83, 81, 99, 85, 64, 71, 92, 221, 84,
+  51, 81, 91, 84, 70, 77, 81, 82, 95, 70,
+  79, 84, 82, 45, 69, 89, 77, 76, 67, 83,
+  83, 57, 51, 80, 85, 77, 82, 77, 91, 95,
+  76, 82, 88, 52, 90, 85, 92, 85, 87, 95,
+  82, 81, 76, 76, 80, 75, 80, 95, 96, 87,
+  74, 80, 96, 78, 88, 77, 80, 84, 92, 126,
+  89, 86, 85, 85, 84, 72, 87, 77, 92, 100,
+  96, 80, 92, 77, 89, 89, 73, 71, 97, 83,
+  88, 70, 91, 89, 79, 67, 93, 74, 74, 75,
+  89, 85, 95, 83, 81, 68, 74, 83, 71, 86,
+  78, 69, 90, 80, 87, 90, 85, 95, 90, 79,
+  123, 81, 86, 80, 80, 88, 88, 89, 73, 85,
+  82, 83, 75, 93, 79, 95, 98, 78, 79, 88,
+  73, 89, 76, 82, 80, 81, 84, 62, 86, 88,
+  96, 76, 90, 92, 90, 81, 85, 69, 90, 91,
+  75, 83, 90, 82, 85, 61, 90, 78, 76, 86,
+  69, 50, 83, 89, 77, 93, 83, 78, 73, 80,
+  81, 83, 90, 94, 79, 79, 80, 93, 90, 88,
+  79, 80, 82, 96, 85, 85, 81, 69, 94, 78,
+  82, 83, 87, 79, 87, 71, 87, 93, 97, 95,
+  76, 79, 82, 74, 72, 73, 94, 82, 84, 78,
+  89, 96, 84, 79, 90, 83, 83, 74, 86, 90,
+  92, 86, 91, 79, 83, 72, 85, 86, 89, 86,
+  83, 81, 82, 90, 82, 75, 101, 74, 67, 102,
+  82, 84, 83, 79, 91, 93, 93, 85, 76, 83,
+  93, 81, 85, 88, 116, 77, 70, 88, 74, 88,
+  94, 86, 84, 92, 82, 104, 80, 87, 81, 70,
+  90, 87, 87, 85, 75, 81, 91, 108, 71, 83,
+  92, 83, 88, 69, 91, 80, 78, 84, 70, 48,
+  89, 89, 82, 88, 85, 86, 74, 84, 79, 77,
+  86, 95, 76, 80, 81, 92, 90, 95, 92, 93,
+  80, 85, 84, 82, 81, 89, 89, 80, 92, 80,
+  84, 78, 90, 72, 84, 91, 91, 80, 72, 79,
+  80, 83, 76, 70, 93, 83, 87, 74, 89, 100,
+  86, 75, 85, 81, 77, 77, 93, 86, 92, 90,
+  86, 77, 78, 74, 78, 85, 89, 78, 85, 81,
+  83, 92, 80, 81, 97, 72, 74, 95, 81, 80,
+  77, 74, 94, 95, 85, 86, 75, 81, 93, 78,
+  82, 77, 118, 79, 77, 88, 74, 87, 88, 88,
+  84, 87, 80, 76, 86, 86, 88, 66, 87, 88,
+  84, 82, 72, 76, 87, 121, 70, 83, 83, 76,
+  80, 69, 85, 94, 78, 86, 85, 66, 75, 81,
+  90, 86, 87, 84, 79, 76, 81, 74, 84, 78,
+  83, 94, 86, 93, 80, 79, 82, 78, 85, 89,
+  87, 84, 88, 119, 87, 84, 89, 88, 88, 77,
+  90, 81, 92, 93, 97, 81, 90, 83, 85, 88,
+  69, 77, 91, 81, 96, 78, 86, 81, 80, 73,
+  85, 70, 72, 84, 97, 88, 97, 90, 80, 73,
+  82, 81, 74, 90, 90, 69, 85, 82, 83, 84,
+  79, 86, 88, 72, 106, 83, 83, 90, 88, 81,
+  90, 92, 84, 83, 78, 78, 84, 88, 83, 88,
+  99, 75, 79, 87, 67, 90, 90, 85, 85, 86,
+  82, 71, 91, 96, 86, 80, 91, 85, 95, 83,
+  92, 78, 90, 110, 84, 84, 88, 77, 93, 84,
+  86, 92, 70, 96, 77, 88, 93, 86, 88, 83,
+  75, 68, 77, 85, 76, 103, 76, 80, 93, 75,
+  67, 73, 64, 85, 83, 94, 84, 81, 84, 79,
+  83, 90, 70, 79, 91, 73, 73, 78, 70, 82,
+  82, 80, 85, 86, 74, 71, 92, 95, 86, 79,
+  70, 93, 91, 77, 95, 91, 76, 91, 84, 83,
+  91, 67, 83, 85, 84, 67, 85, 87, 83, 85,
+  75, 76, 83, 89, 82, 54, 70, 115, 76, 92,
+  81, 92, 75, 97, 121, 76, 79, 100, 85, 77,
+  95, 85, 84, 90, 89, 72, 89, 77, 89, 81,
+  82, 76, 77, 91, 90, 70, 77, 82, 71, 91,
+  85, 109, 95, 87, 66, 72, 92, 96, 73, 79,
+  87, 89, 85, 86, 79, 85, 97, 81, 93, 87,
+  72, 98, 82, 88, 93, 86, 87, 91, 82, 68,
+  75, 82, 75, 102, 72, 80, 86, 83, 71, 76,
+  67, 85, 90, 89, 81, 80, 79, 80, 80, 84,
+  72, 81, 89, 73, 77, 83, 72, 91, 87, 75,
+  89, 77, 68, 72, 91, 104, 89, 84, 72, 100,
+  88, 80, 99, 89, 75, 89, 87, 90, 92, 76,
+  81, 74, 75, 61, 85, 83, 80, 84, 78, 74,
+  84, 77, 88, 59, 72, 115, 79, 90, 79, 87,
+  80, 91, 130, 87, 77, 95, 81, 75, 89, 85,
+  82, 94, 86, 76, 86, 83, 92, 82, 79, 78,
+  76, 98, 98, 72, 85, 80, 69, 79, 86, 96,
+  75, 84, 64, 76, 79, 90, 75, 78, 88, 87,
+  85, 88, 83, 82, 85, 83, 87, 97, 75, 93,
+  78, 86, 81, 86, 88, 93, 77, 71, 78, 88,
+  78, 97, 72, 80, 90, 77, 77, 83, 69, 86,
+  85, 87, 93, 89, 86, 81, 88, 96, 88, 76,
+  78, 78, 71, 79, 77, 70, 77, 83, 83, 95,
+  81, 75, 87, 84, 86, 79, 81, 77, 90, 76,
+  87, 89, 81, 95, 76, 75, 84, 64, 90, 87,
+  83, 75, 90, 92, 85, 81, 80, 76, 83, 82,
+  88, 61, 72, 106, 80, 95, 83, 83, 92, 89,
+  100, 86, 80, 100, 92, 80, 93, 83, 87, 90,
+  81, 80, 86, 97, 85, 84, 81, 82, 69, 87,
+  95, 73, 81, 91, 76, 80, 82, 95, 80, 89,
+  72, 73, 74, 94, 73, 80, 83, 91, 87, 86,
+  74, 81, 96, 75, 83, 90, 57, 87, 67, 82,
+  89, 95, 83, 106, 87, 71, 77, 64, 71, 105,
+  79, 77, 85, 86, 68, 67, 61, 79, 91, 89,
+  82, 82, 75, 87, 89, 86, 80, 83, 82, 75,
+  86, 61, 69, 90, 75, 86, 80, 94, 65, 70,
+  99, 103, 85, 91, 65, 97, 77, 95, 104, 79,
+  76, 74, 89, 82, 83, 58, 87, 72, 77, 52,
+  82, 86, 70, 76, 77, 74, 80, 87, 81, 76,
+  71, 151, 79, 70, 84, 89, 77, 97, 151, 68,
+  66, 84, 89, 72, 98, 85, 89, 84, 75, 69,
+  74, 77, 88, 81, 90, 81, 74, 85, 85, 66,
+  89, 71, 66, 85, 96, 113, 77, 85, 59, 83,
+  91, 104, 79, 68, 96, 83, 82, 89, 73, 89,
+  93, 72, 88, 81, 62, 91, 75, 83, 90, 91,
+  87, 102, 93, 74, 77, 68, 72, 106, 71, 79,
+  80, 91, 71, 69, 69, 81, 94, 78, 75, 74,
+  74, 85, 76, 82, 75, 82, 99, 76, 83, 67,
+  77, 97, 74, 78, 79, 80, 61, 69, 95, 104,
+  90, 95, 64, 123, 78, 95, 99, 73, 72, 73,
+  83, 85, 76, 66, 91, 65, 75, 58, 93, 79,
+  73, 78, 77, 67, 81, 80, 87, 81, 72, 150,
+  83, 73, 84, 84, 78, 91, 155, 68, 69, 78,
+  82, 69, 84, 84, 87, 83, 74, 75, 72, 78,
+  92, 82, 86, 82, 74, 86, 95, 66, 94, 71,
+  68, 73, 94, 99, 74, 82, 56, 86, 76, 96,
+  81, 67, 97, 81, 78, 93, 75, 90, 78, 80,
+  78, 99, 67, 88, 72, 83, 85, 94, 83, 85,
+  85, 75, 77, 74, 71, 102, 71, 71, 89, 85,
+  81, 78, 70, 81, 87, 88, 86, 87, 81, 90,
+  90, 95, 96, 79, 84, 73, 89, 65, 81, 73,
+  75, 86, 76, 100, 74, 75, 92, 79, 85, 87,
+  79, 95, 82, 89, 96, 77, 83, 84, 82, 74,
+  77, 60, 95, 78, 80, 78, 82, 94, 79, 75,
+  80, 70, 87, 89, 88, 83, 73, 127, 80, 88,
+  88, 87, 89, 88, 107, 79, 70, 75, 94, 82,
+  88, 86, 88, 86, 75, 74, 73, 91, 83, 86,
+  85, 80, 73, 79, 86, 69, 87, 78, 74, 78,
+  87, 102, 85, 84, 68, 85, 72, 99, 74, 72,
+  89, 85, 81, 90, 90, 81, 85, 85, 85, 88,
+  74, 87, 88, 85, 87, 81, 85, 87, 77, 73,
+  86, 85, 76, 85, 87, 78, 75, 91, 76, 72,
+  84, 84, 83, 87, 82, 82, 85, 91, 86, 83,
+  83, 97, 69, 77, 97, 76, 79, 73, 82, 98,
+  84, 94, 80, 70, 88, 79, 98, 85, 91, 77,
+  105, 87, 80, 81, 88, 95, 95, 90, 82, 73,
+  94, 90, 88, 75, 86, 86, 88, 77, 84, 88,
+  76, 80, 78, 62, 76, 79, 91, 70, 76, 85,
+  77, 76, 99, 89, 87, 90, 95, 86, 106, 79,
+  88, 86, 83, 83, 81, 88, 94, 84, 86, 90,
+  73, 75, 92, 82, 73, 92, 79, 89, 87, 96,
+  92, 92, 81, 87, 87, 84, 74, 82, 81, 92,
+  89, 79, 93, 89, 78, 81, 82, 80, 69, 87,
+  93, 85, 90, 78, 85, 78, 81, 74, 87, 87,
+  79, 92, 82, 79, 75, 94, 83, 73, 86, 86,
+  78, 81, 73, 84, 83, 91, 78, 81, 84, 95,
+  79, 71, 91, 74, 79, 74, 83, 93, 83, 88,
+  78, 71, 85, 74, 102, 85, 89, 85, 109, 83,
+  83, 81, 88, 99, 94, 92, 76, 76, 99, 95,
+  86, 79, 80, 82, 92, 76, 86, 82, 79, 77,
+  76, 66, 77, 74, 92, 79, 79, 82, 79, 69,
+  86, 90, 87, 80, 91, 87, 95, 79, 87, 88,
+  80, 89, 82, 91, 97, 85, 83, 93, 77, 71,
+  98, 82, 71, 91, 80, 83, 87, 94, 87, 90,
+  79, 83, 79, 82, 76, 82, 83, 93, 89, 84,
+  90, 87, 81, 81, 88, 87, 78, 82, 88, 87,
+  87, 86, 91, 72, 73, 79, 86, 90, 80, 86,
+  81, 79, 87, 86, 85, 75, 82, 85, 83, 90,
+  83, 83, 86, 94, 88, 86, 95, 91, 79, 82,
+  97, 71, 84, 72, 79, 93, 83, 91, 85, 76,
+  85, 78, 93, 85, 93, 78, 92, 84, 79, 74,
+  89, 97, 89, 82, 81, 74, 93, 89, 85, 92,
+  78, 88, 88, 79, 82, 77, 79, 92, 85, 65,
+  86, 80, 90, 86, 77, 87, 84, 80, 84, 83,
+  86, 70, 100, 86, 88, 79, 86, 84, 78, 79,
+  84, 83, 90, 87, 85, 81, 81, 74, 90, 80,
+  74, 96, 83, 80, 90, 85, 97, 94, 83, 88,
+  76, 84, 71, 80, 85, 91, 90, 80, 85, 87,
+  85, 78, 79, 91, 80, 97, 82, 58, 90, 94,
+  78, 86, 68, 85, 74, 87, 88, 85, 92, 88,
+  78, 79, 88, 79, 84, 67, 78, 73, 94, 85,
+  84, 87, 77, 91, 83, 75, 94, 73, 90, 59,
+  82, 96, 84, 90, 84, 88, 78, 89, 80, 83,
+  78, 91, 89, 86, 85, 87, 97, 89, 94, 80,
+  81, 86, 77, 83, 86, 95, 81, 77, 92, 83,
+  92, 87, 90, 81, 85, 89, 62, 75, 85, 85,
+  95, 86, 81, 107, 95, 86, 76, 90, 98, 95,
+  107, 89, 84, 96, 98, 81, 91, 96, 92, 79,
+  84, 88, 103, 78, 75, 85, 76, 82, 89, 90,
+  96, 65, 87, 83, 84, 83, 76, 83, 76, 75,
+  78, 92, 85, 61, 86, 83, 88, 91, 80, 77,
+  82, 83, 76, 103, 84, 84, 83, 89, 73, 88,
+  75, 82, 77, 78, 83, 83, 78, 91, 72, 71,
+  91, 91, 87, 73, 86, 81, 93, 80, 83, 89,
+  85, 86, 82, 75, 83, 78, 74, 56, 83, 93,
+  85, 76, 87, 84, 84, 96, 81, 83, 87, 82,
+  85, 88, 95, 86, 89, 90, 94, 81, 81, 76,
+  74, 88, 77, 91, 76, 84, 80, 86, 87, 78,
+  81, 81, 85, 80, 71, 86, 85, 89, 89, 83,
+  80, 102, 95, 85, 83, 88, 102, 83, 94, 89,
+  76, 90, 93, 81, 76, 80, 85, 71, 84, 86,
+  85, 72, 81, 88, 62, 80, 86, 83, 79, 62,
+  88, 90, 96, 84, 81, 85, 86, 83, 71, 96,
+  80, 63, 80, 83, 102, 84, 87, 82, 85, 78,
+  77, 107, 88, 101, 77, 84, 89, 88, 87, 79,
+  89, 71, 83, 82, 88, 82, 81, 67, 101, 96,
+  91, 83, 75, 91, 90, 69, 87, 82, 85, 90,
+  92, 71, 87, 81, 80, 71, 83, 93, 91, 76,
+  95, 80, 95, 92, 73, 83, 84, 80, 85, 88,
+  98, 82, 85, 89, 87, 86, 83, 79, 90, 92,
+  85, 92, 80, 94, 89, 79, 88, 86, 83, 64,
+  79, 87, 79, 78, 84, 84, 96, 79, 90, 87,
+  124, 80, 84, 90, 94, 81, 78, 89, 81, 85,
+  95, 79, 92, 75, 96, 79, 100, 83, 65, 84,
+  84, 96, 81, 77, 93, 83, 68, 53, 88, 96,
+  87, 80, 105, 92, 98, 84, 65, 103, 74, 77,
+  75, 85, 83, 94, 91, 80, 78, 86, 83, 71,
+  85, 41, 69, 87, 80, 95, 77, 89, 71, 92,
+  66, 92, 86, 95, 78, 94, 79, 70, 93, 83,
+  101, 75, 70, 96, 77, 76, 70, 91, 94, 124,
+  98, 72, 86, 76, 89, 85, 88, 86, 84, 94,
+  79, 74, 84, 80, 75, 84, 80, 87, 63, 80,
+  85, 71, 78, 79, 90, 83, 70, 92, 75, 73,
+  77, 84, 86, 74, 83, 84, 88, 64, 94, 93,
+  66, 79, 84, 84, 62, 71, 67, 69, 97, 87,
+  79, 78, 62, 89, 95, 97, 75, 89, 91, 85,
+  93, 85, 70, 85, 80, 90, 148, 85, 83, 79,
+  88, 82, 92, 92, 90, 78, 81, 80, 67, 106,
+  63, 80, 76, 73, 77, 60, 93, 77, 73, 91,
+  80, 85, 78, 76, 76, 96, 72, 74, 77, 72,
+  67, 84, 69, 92, 75, 88, 76, 83, 80, 90,
+  72, 97, 65, 78, 91, 75, 86, 75, 110, 77,
+  81, 103, 70, 88, 77, 86, 85, 95, 83, 79,
+  83, 75, 81, 92, 80, 81, 81, 90, 87, 82,
+  82, 84, 84, 75, 83, 82, 82, 73, 89, 76,
+  85, 82, 87, 55, 59, 85, 63, 87, 79, 91,
+  68, 81, 86, 86, 78, 85, 96, 87, 65, 86,
+  86, 84, 64, 77, 70, 66, 124, 92, 72, 82,
+  85, 93, 94, 102, 94, 90, 90, 79, 68, 75,
+  74, 81, 84, 86, 118, 78, 93, 85, 65, 71,
+  86, 90, 84, 60, 73, 86, 95, 99, 63, 84,
+  73, 78, 62, 76, 83, 68, 80, 79, 104, 76,
+  80, 76, 87, 64, 78, 100, 81, 95, 79, 84,
+  92, 91, 84, 84, 91, 63, 93, 83, 84, 79,
+  74, 66, 102, 101, 85, 74, 92, 81, 94, 79,
+  87, 90, 80, 88, 95, 59, 83, 91, 88, 76,
+  75, 97, 82, 77, 93, 88, 94, 89, 79, 86,
+  91, 79, 88, 86, 95, 79, 93, 93, 82, 80,
+  83, 55, 69, 85, 75, 96, 91, 86, 74, 80,
+  83, 88, 78, 70, 77, 80, 67, 84, 92, 95,
+  104, 75, 94, 75, 165, 78, 79, 86, 106, 88,
+  86, 89, 79, 87, 88, 75, 86, 78, 87, 86,
+  80, 82, 49, 79, 94, 96, 76, 81, 93, 76,
+  70, 51, 78, 98, 80, 75, 95, 90, 93, 81,
+  78, 106, 81, 85, 71, 82, 84, 96, 89, 92,
+  82, 83, 72, 65, 87, 40, 75, 82, 78, 102,
+  75, 88, 73, 78, 75, 93, 86, 88, 86, 93,
+  86, 74, 102, 88, 84, 81, 80, 87, 87, 78,
+  67, 93, 83, 135, 80, 72, 89, 85, 82, 81,
+  75, 89, 84, 91, 73, 80, 81, 89, 73, 89,
+  77, 90, 70, 81, 75, 83, 62, 83, 101, 90,
+  79, 91, 74, 80, 87, 79, 78, 83, 93, 79,
+  93, 75, 89, 88, 87, 80, 87, 81, 72, 77,
+  78, 70, 109, 84, 80, 70, 64, 81, 90, 103,
+  65, 68, 91, 79, 97, 90, 75, 88, 68, 89,
+  110, 90, 88, 78, 77, 96, 86, 96, 80, 94,
+  81, 98, 82, 98, 90, 91, 81, 84, 95, 64,
+  97, 102, 82, 85, 81, 93, 76, 86, 77, 87,
+  70, 70, 87, 68, 72, 91, 74, 83, 74, 89,
+  79, 75, 85, 86, 81, 87, 76, 80, 100, 73,
+  98, 88, 98, 77, 81, 102, 80, 89, 72, 85,
+  84, 109, 91, 77, 84, 76, 78, 88, 73, 85,
+  84, 83, 86, 80, 83, 93, 81, 81, 78, 79,
+  85, 74, 86, 76, 68, 78, 96, 68, 69, 88,
+  66, 86, 87, 86, 75, 79, 90, 88, 87, 89,
+  88, 91, 75, 86, 87, 83, 74, 79, 75, 69,
+  115, 83, 74, 77, 87, 84, 90, 100, 83, 70,
+  99, 76, 75, 82, 80, 86, 81, 84, 107, 85,
+  92, 85, 77, 81, 83, 90, 79, 68, 83, 92,
+  92, 86, 80, 91, 79, 79, 75, 76, 89, 94,
+  85, 80, 97, 75, 81, 79, 87, 69, 73, 91,
+  82, 94, 81, 85, 87, 95, 83, 88, 87, 60,
+  84, 84, 90, 82, 80, 69, 102, 92, 89, 78,
+  81, 77, 95, 87, 91, 97, 80, 91, 91, 66,
+  86, 88, 91, 74, 74, 97, 76, 84, 88, 93,
+  91, 90, 77, 91, 84, 81, 86, 80, 90, 81,
+  96, 91, 75, 78, 88, 61, 84, 89, 74, 99,
+  93, 91, 71, 84, 81, 88, 80, 73, 84, 79,
+  68, 78, 87, 89, 98, 76, 92, 73, 144, 72,
+  78, 87, 104, 84, 89, 89, 78, 76, 100, 76,
+  86, 79, 86, 92, 93, 85, 71, 87, 87, 89,
+  85, 78, 93, 82, 80, 59, 86, 98, 78, 74,
+  102, 86, 94, 82, 67, 115, 79, 90, 78, 82,
+  71, 99, 86, 93, 100, 83, 89, 90, 89, 86,
+  71, 64, 58, 89, 87, 91, 85, 105, 97, 112,
+  82, 67, 102, 94, 73, 97, 92, 91, 80, 75,
+  90, 88, 93, 76, 95, 86, 93, 92, 58, 81,
+  89, 74, 88, 97, 74, 104, 82, 73, 86, 81,
+  89, 87, 65, 91, 93, 89, 84, 113, 82, 82,
+  76, 86, 74, 66, 111, 73, 69, 72, 82, 90,
+  87, 65, 94, 77, 98, 84, 83, 80, 91, 85,
+  97, 93, 85, 96, 86, 84, 95, 71, 92, 88,
+  78, 90, 83, 95, 91, 88, 97, 80, 84, 99,
+  80, 88, 75, 83, 99, 84, 90, 74, 85, 78,
+  82, 83, 91, 99, 89, 79, 70, 79, 90, 76,
+  67, 86, 89, 97, 84, 83, 84, 85, 100, 91,
+  79, 76, 74, 69, 78, 84, 75, 80, 80, 86,
+  83, 70, 73, 71, 76, 79, 74, 84, 84, 102,
+  79, 77, 75, 69, 88, 78, 95, 80, 83, 68,
+  93, 91, 82, 84, 80, 84, 89, 81, 83, 78,
+  93, 83, 73, 86, 85, 86, 72, 83, 89, 78,
+  83, 81, 77, 91, 71, 91, 59, 87, 88, 108,
+  75, 114, 71, 73, 68, 84, 66, 73, 98, 105,
+  76, 78, 76, 73, 78, 72, 82, 81, 79, 77,
+  76, 89, 82, 86, 86, 89, 78, 86, 85, 82,
+  85, 88, 82, 89, 77, 75, 91, 84, 82, 92,
+  89, 86, 77, 90, 80, 87, 77, 76, 89, 85,
+  77, 81, 62, 90, 60, 94, 98, 83, 76, 90,
+  78, 71, 80, 86, 84, 74, 112, 86, 90, 81,
+  74, 66, 83, 85, 71, 83, 84, 91, 74, 83,
+  75, 71, 82, 77, 86, 81, 88, 103, 76, 83,
+  87, 72, 87, 79, 93, 95, 95, 97, 87, 83,
+  86, 106, 79, 94, 73, 90, 93, 77, 93, 81,
+  73, 85, 96, 82, 76, 82, 82, 74, 83, 74,
+  75, 87, 78, 86, 69, 72, 82, 107, 76, 118,
+  81, 67, 80, 95, 65, 80, 73, 103, 79, 80,
+  85, 74, 76, 100, 96, 74, 76, 75, 90, 79,
+  84, 99, 78, 95, 82, 87, 75, 79, 86, 88,
+  86, 89, 79, 83, 95, 81, 81, 81, 93, 86,
+  74, 87, 66, 82, 80, 74, 102, 96, 79, 85,
+  85, 97, 91, 91, 96, 79, 73, 88, 74, 73,
+  79, 95, 86, 78, 67, 110, 87, 96, 92, 76,
+  84, 87, 90, 87, 75, 72, 60, 78, 85, 94,
+  84, 104, 107, 124, 80, 63, 96, 95, 85, 100,
+  91, 94, 77, 73, 92, 87, 85, 66, 78, 78,
+  91, 89, 70, 79, 83, 76, 81, 91, 72, 104,
+  87, 74, 90, 80, 91, 88, 72, 82, 94, 78,
+  97, 98, 92, 88, 80, 72, 84, 48, 94, 62,
+  74, 83, 73, 102, 75, 64, 92, 80, 98, 93,
+  72, 71, 85, 85, 88, 101, 89, 97, 81, 79,
+  91, 67, 109, 93, 85, 90, 79, 96, 85, 79,
+  97, 71, 85, 93, 76, 82, 80, 86, 98, 83,
+  102, 81, 99, 83, 82, 75, 102, 100, 80, 79,
+  82, 73, 84, 91, 71, 78, 89, 109, 81, 76,
+  83, 91, 97, 91, 86, 70, 81, 62, 65, 75,
+  76, 85, 88, 91, 85, 86, 73, 71, 83, 63,
+  69, 76, 78, 119, 61, 69, 71, 65, 62, 78,
+  112, 79, 88, 65, 90, 97, 69, 80, 84, 78,
+  68, 92, 67, 74, 96, 86, 75, 70, 83, 104,
+  70, 85, 76, 96, 76, 84, 74, 63, 83, 76,
+  70, 73, 79, 121, 82, 115, 42, 97, 70, 74,
+  79, 65, 78, 78, 72, 84, 70, 69, 69, 60,
+  87, 81, 68, 71, 71, 91, 90, 79, 77, 104,
+  65, 80, 79, 76, 77, 75, 76, 93, 75, 70,
+  78, 84, 76, 77, 94, 88, 78, 81, 88, 91,
+  71, 77, 94, 82, 68, 72, 74, 73, 63, 88,
+  89, 88, 73, 87, 71, 61, 83, 76, 83, 77,
+  103, 84, 87, 81, 78, 54, 79, 78, 75, 88,
+  90, 86, 86, 73, 80, 74, 91, 64, 76, 81,
+  93, 103, 55, 78, 77, 73, 65, 84, 109, 101,
+  94, 92, 86, 78, 77, 108, 84, 93, 96, 95,
+  78, 68, 83, 84, 77, 74, 93, 82, 74, 88,
+  75, 83, 82, 72, 72, 77, 88, 84, 76, 69,
+  72, 113, 80, 133, 61, 99, 78, 87, 79, 65,
+  82, 73, 74, 97, 88, 69, 69, 118, 99, 69,
+  67, 72, 84, 73, 81, 96, 58, 106, 73, 82,
+  80, 87, 85, 76, 87, 97, 73, 75, 95, 87,
+  73, 71, 96, 85, 74, 78, 81, 83, 69, 79,
+  93, 95, 76, 67, 76, 80, 103, 85, 89, 85,
+  75, 82, 76, 68, 79, 90, 86, 80, 77, 106,
+  102, 89, 92, 82, 88, 78, 87, 88, 82, 72,
+  63, 84, 88, 96, 87, 103, 94, 111, 79, 71,
+  96, 95, 91, 94, 88, 84, 73, 79, 90, 85,
+  87, 65, 89, 70, 98, 88, 85, 89, 77, 94,
+  91, 89, 80, 96, 81, 83, 83, 74, 91, 92,
+  77, 87, 98, 90, 82, 95, 89, 77, 82, 75,
+  80, 63, 89, 78, 86, 77, 79, 110, 79, 68,
+  85, 87, 96, 85, 87, 81, 78, 83, 89, 95,
+  95, 104, 90, 77, 87, 70, 97, 89, 86, 94,
+  79, 84, 83, 79, 96, 79, 87, 88, 80, 91,
+  82, 92, 89, 87, 99, 83, 101, 82, 97, 77,
+  94, 97, 80, 90, 81, 76, 94, 89, 70, 82,
+  82, 94, 80, 84, 86, 86, 95, 81, 96, 80,
+  83, 69, 77, 76, 67, 85, 92, 86, 84, 91,
+  73, 75, 85, 65, 72, 78, 82, 116, 60, 80,
+  73, 67, 78, 76, 91, 74, 103, 69, 88, 94,
+  86, 65, 98, 80, 59, 84, 81, 87, 92, 80,
+  77, 60, 81, 93, 78, 84, 78, 98, 77, 74,
+  82, 74, 77, 77, 72, 81, 85, 111, 83, 129,
+  52, 83, 76, 87, 92, 76, 76, 82, 78, 87,
+  76, 71, 83, 72, 97, 74, 72, 85, 79, 94,
+  94, 86, 77, 99, 82, 78, 77, 79, 85, 81,
+  75, 87, 77, 76, 85, 87, 76, 70, 91, 90,
+  84, 81, 86, 88, 78, 78, 97, 88, 72, 77,
+  99, 79, 47, 89, 97, 86, 76, 84, 73, 63,
+  85, 87, 84, 84, 95, 89, 97, 92, 76, 70,
+  85, 76, 70, 87, 91, 90, 84, 62, 78, 79,
+  92, 79, 84, 91, 100, 98, 73, 88, 78, 76,
+  86, 86, 89, 103, 89, 86, 87, 72, 74, 89,
+  91, 92, 94, 89, 91, 82, 74, 81, 80, 77,
+  88, 82, 72, 85, 85, 90, 82, 67, 93, 79,
+  80, 84, 77, 82, 85, 91, 77, 121, 71, 85,
+  82, 96, 89, 81, 84, 86, 83, 97, 90, 72,
+  85, 102, 85, 67, 72, 87, 83, 88, 86, 100,
+  70, 88, 85, 82, 79, 102, 86, 80, 86, 89,
+  80, 72, 101, 86, 70, 84, 94, 88, 87, 86,
+  87, 86, 71, 82, 85, 94, 83, 76, 79, 85,
+  88, 78, 94, 84, 77, 84, 76, 71, 83, 100,
+  87, 88, 92, 86, 110, 77, 79, 92, 76, 83,
+  65, 93, 97, 103, 80, 97, 73, 98, 81, 73,
+  92, 105, 105, 90, 78, 87, 71, 79, 95, 87,
+  90, 79, 114, 77, 79, 71, 79, 95, 87, 81,
+  98, 77, 86, 80, 74, 95, 95, 95, 81, 67,
+  72, 82, 81, 73, 79, 80, 88, 86, 82, 79,
+  93, 84, 78, 71, 75, 76, 67, 81, 81, 91,
+  88, 72, 89, 84, 67, 98, 85, 79, 88, 89,
+  82, 76, 88, 79, 89, 86, 74, 96, 86, 80,
+  74, 98, 88, 90, 87, 80, 75, 83, 74, 79,
+  91, 90, 83, 89, 81, 72, 81, 89, 81, 76,
+  67, 75, 74, 94, 81, 85, 84, 90, 62, 73,
+  87, 74, 88, 77, 65, 98, 80, 93, 96, 87,
+  112, 73, 91, 75, 90, 97, 66, 74, 55, 85,
+  91, 112, 86, 99, 62, 99, 88, 88, 103, 97,
+  77, 95, 99, 73, 87, 67, 86, 83, 95, 72,
+  144, 98, 77, 84, 86, 73, 89, 83, 106, 76,
+  93, 76, 98, 116, 105, 114, 76, 69, 69, 73,
+  91, 64, 66, 81, 78, 91, 99, 78, 84, 76,
+  92, 59, 83, 83, 62, 75, 73, 100, 87, 64,
+  89, 77, 42, 108, 78, 81, 106, 74, 73, 71,
+  89, 83, 81, 77, 69, 88, 88, 70, 71, 91,
+  77, 104, 85, 78, 73, 81, 87, 87, 78, 60,
+  79, 71, 73, 67, 71, 89, 73, 69, 66, 80,
+  83, 112, 77, 83, 82, 88, 76, 66, 81, 64,
+  85, 90, 52, 88, 71, 93, 122, 79, 85, 73,
+  71, 84, 79, 65, 87, 83, 73, 94, 91, 89,
+  88, 88, 76, 96, 78, 71, 86, 93, 73, 86,
+  82, 90, 86, 86, 87, 84, 84, 81, 99, 79,
+  81, 85, 80, 80, 89, 89, 84, 79, 75, 76,
+  102, 88, 91, 91, 81, 94, 68, 86, 85, 80,
+  82, 84, 73, 76, 77, 85, 96, 90, 84, 67,
+  81, 70, 72, 87, 84, 94, 92, 81, 89, 79,
+  67, 78, 80, 86, 86, 72, 79, 79, 90, 78,
+  81, 82, 78, 81, 87, 86, 78, 101, 90, 100,
+  87, 78, 96, 85, 71, 71, 88, 91, 90, 81,
+  82, 80, 85, 90, 74, 80, 73, 76, 87, 85,
+  77, 87, 85, 97, 95, 81, 88, 84, 83, 79,
+  75, 94, 80, 89, 90, 90, 94, 93, 90, 77,
+  86, 83, 79, 90, 58, 85, 97, 118, 83, 93,
+  67, 88, 92, 91, 96, 111, 115, 79, 87, 91,
+  77, 71, 100, 89, 94, 71, 95, 75, 89, 73,
+  89, 99, 84, 84, 92, 79, 94, 98, 69, 110,
+  84, 85, 78, 64, 84, 78, 82, 77, 84, 89,
+  88, 86, 90, 65, 89, 78, 69, 75, 80, 73,
+  66, 76, 68, 95, 81, 73, 79, 82, 68, 102,
+  102, 79, 94, 93, 82, 81, 78, 90, 83, 67,
+  83, 90, 88, 73, 67, 86, 80, 78, 89, 80,
+  50, 83, 86, 78, 120, 72, 68, 97, 84, 70,
+  82, 87, 79, 82, 79, 90, 77, 101, 78, 88,
+  83, 91, 62, 73, 81, 71, 84, 77, 65, 89,
+  69, 85, 103, 75, 114, 68, 75, 84, 86, 94,
+  57, 91, 46, 74, 91, 137, 85, 99, 59, 65,
+  111, 111, 118, 77, 72, 86, 92, 71, 113, 56,
+  109, 84, 104, 89, 106, 107, 94, 74, 91, 63,
+  77, 72, 94, 76, 77, 94, 93, 128, 86, 121,
+  84, 74, 80, 68, 93, 73, 67, 95, 100, 90,
+  118, 64, 75, 75, 67, 83, 81, 85, 84, 71,
+  66, 95, 78, 78, 80, 75, 46, 102, 95, 77,
+  121, 75, 72, 77, 75, 93, 89, 82, 77, 79,
+  90, 59, 62, 82, 69, 71, 80, 81, 29, 84,
+  108, 102, 95, 46, 58, 75, 82, 65, 72, 95,
+  88, 70, 79, 91, 85, 131, 79, 82, 86, 85,
+  85, 55, 83, 64, 71, 91, 47, 74, 56, 81,
+  133, 63, 80, 69, 72, 92, 84, 74, 82, 86,
+  67, 91, 93, 110, 97, 90, 69, 87, 86, 92,
+  91, 88, 70, 81, 79, 91, 113, 73, 91, 86,
+  86, 97, 89, 89, 85, 97, 78, 73, 79, 91,
+  82, 82, 90, 92, 116, 100, 85, 90, 92, 97,
+  84, 81, 85, 81, 88, 92, 77, 79, 86, 70,
+  93, 78, 77, 77, 83, 63, 72, 81, 86, 93,
+  74, 78, 75, 79, 59, 92, 94, 87, 92, 76,
+  70, 82, 89, 89, 79, 93, 83, 82, 88, 85,
+  75, 91, 82, 94, 88, 78, 81, 87, 86, 69,
+  78, 73, 78, 76, 82, 76, 86, 86, 75, 88,
+  80, 89, 86, 91, 83, 88, 89, 96, 95, 80,
+  83, 76, 65, 79, 72, 90, 73, 82, 97, 79,
+  87, 87, 79, 82, 93, 90, 85, 98, 69, 94,
+  93, 94, 93, 79, 71, 92, 100, 83, 85, 92,
+  82, 88, 62, 92, 82, 86, 91, 87, 80, 71,
+  81, 74, 87, 80, 84, 92, 82, 85, 86, 88,
+  90, 86, 79, 93, 70, 81, 89, 65, 84, 76,
+  79, 90, 82, 97, 90, 93, 80, 76, 95, 85,
+  79, 89, 92, 75, 79, 84, 81, 88, 80, 86,
+  80, 74, 84, 92, 93, 94, 87, 84, 83, 79,
+  83, 76, 88, 85, 87, 87, 85, 88, 77, 72,
+  95, 82, 90, 86, 63, 72, 75, 72, 112, 82,
+  79, 98, 87, 79, 76, 76, 77, 95, 90, 89,
+  69, 80, 77, 88, 93, 98, 85, 85, 88, 87,
+  96, 82, 75, 101, 78, 82, 86, 74, 91, 84,
+  73, 82, 94, 74, 75, 99, 64, 94, 95, 98,
+  91, 89, 69, 95, 107, 91, 87, 91, 70, 77,
+  79, 84, 99, 73, 92, 88, 89, 90, 80, 77,
+  89, 81, 84, 77, 85, 72, 87, 86, 87, 76,
+  73, 106, 68, 82, 99, 70, 79, 78, 76, 83,
+  82, 95, 84, 86, 81, 74, 84, 100, 74, 85,
+  99, 81, 89, 81, 75, 91, 78, 78, 75, 79,
+  70, 87, 103, 93, 84, 79, 88, 71, 86, 81,
+  82, 84, 88, 82, 86, 90, 77, 66, 87, 73,
+  82, 82, 56, 73, 84, 83, 93, 67, 75, 94,
+  89, 71, 80, 81, 84, 90, 87, 91, 76, 82,
+  77, 81, 102, 92, 91, 81, 88, 88, 80, 71,
+  70, 103, 70, 78, 104, 70, 82, 80, 77, 86,
+  86, 56, 86, 94, 71, 93, 93, 92, 94, 85,
+  76, 89, 93, 83, 85, 80, 86, 87, 90, 87,
+  106, 86, 87, 86, 76, 85, 82, 82, 86, 90,
+  78, 78, 82, 86, 82, 88, 84, 80, 86, 88,
+  71, 82, 100, 93, 81, 77, 79, 85, 81, 92,
+  91, 80, 79, 77, 96, 82, 81, 88, 91, 64,
+  94, 89, 90, 86, 75, 82, 75, 67, 84, 90,
+  97, 97, 85, 77, 77, 83, 88, 80, 85, 91,
+  86, 83, 90, 93, 82, 81, 98, 87, 88, 86,
+  81, 79, 78, 74, 80, 84, 84, 89, 82, 81,
+  75, 82, 77, 95, 87, 84, 85, 77, 79, 86,
+  99, 93, 89, 84, 88, 90, 71, 84, 75, 92,
+  82, 83, 88, 78, 74, 72, 110, 81, 81, 81,
+  85, 91, 82, 83, 76, 72, 89, 98, 74, 92,
+  85, 92, 85, 86, 83, 83, 85, 103, 82, 74,
+  84, 77, 84, 68, 73, 85, 91, 74, 58, 79,
+  79, 79, 78, 92, 79, 89, 85, 84, 81, 87,
+  84, 83, 95, 78, 83, 105, 99, 81, 70, 83,
+  80, 84, 83, 83, 89, 81, 96, 105, 88, 88,
+  111, 74, 84, 88, 81, 90, 78, 91, 82, 91,
+  77, 78, 88, 88, 79, 81, 86, 74, 78, 90,
+  92, 98, 87, 78, 82, 94, 79, 89, 85, 84,
+  82, 74, 87, 81, 74, 76, 73, 84, 88, 81,
+  81, 74, 81, 76, 90, 79, 75, 89, 101, 89,
+  90, 87, 80, 92, 93, 91, 82, 81, 87, 90,
+  73, 87, 78, 93, 89, 84, 92, 72, 78, 81,
+  80, 87, 74, 80, 93, 98, 74, 79, 91, 91,
+  86, 90, 84, 75, 76, 103, 81, 70, 83, 77,
+  104, 67, 60, 88, 87, 85, 52, 65, 79, 68,
+  92, 70, 76, 89, 78, 86, 86, 84, 90, 62,
+  84, 57, 96, 97, 97, 78, 59, 108, 86, 84,
+  89, 81, 88, 71, 114, 100, 90, 90, 104, 63,
+  84, 79, 98, 91, 74, 84, 79, 83, 75, 59,
+  107, 75, 77, 93, 77, 71, 78, 86, 87, 95,
+  94, 75, 83, 97, 77, 77, 94, 90, 89, 69,
+  91, 81, 71, 84, 78, 84, 89, 83, 113, 84,
+  85, 65, 79, 67, 68, 87, 106, 86, 89, 76,
+  66, 90, 87, 95, 81, 82, 80, 86, 79, 73,
+  68, 94, 75, 77, 75, 79, 84, 84, 83, 87,
+  74, 80, 93, 76, 72, 87, 84, 92, 89, 81,
+  89, 78, 76, 103, 90, 78, 90, 83, 80, 68,
+  69, 86, 92, 83, 68, 86, 87, 80, 100, 88,
+  79, 92, 85, 85, 85, 84, 83, 81, 97, 82,
+  83, 95, 101, 82, 80, 103, 78, 77, 82, 85,
+  90, 85, 89, 89, 77, 93, 98, 82, 91, 86,
+  95, 89, 89, 87, 81, 89, 83, 75, 105, 90,
+  85, 75, 84, 83, 71, 81, 91, 93, 78, 76,
+  81, 98, 81, 94, 81, 85, 85, 77, 88, 86,
+  72, 94, 75, 82, 89, 79, 79, 77, 84, 83,
+  76, 73, 80, 92, 65, 88, 82, 93, 81, 95,
+  87, 90, 86, 85, 86, 89, 76, 99, 83, 67,
+  86, 73, 101, 89, 89, 87, 63, 81, 97, 73,
+  88, 79, 74, 85, 95, 77, 82, 92, 92, 93,
+  83, 98, 80, 71, 90, 77, 102, 72, 65, 68,
+  95, 82, 111, 87, 62, 83, 76, 84, 86, 90,
+  83, 71, 91, 89, 88, 86, 86, 69, 78, 78,
+  80, 81, 60, 82, 82, 83, 78, 99, 73, 95,
+  83, 111, 75, 106, 80, 71, 93, 80, 89, 85,
+  80, 87, 91, 92, 79, 132, 87, 82, 63, 77,
+  92, 69, 74, 79, 90, 104, 75, 77, 79, 86,
+  88, 78, 95, 78, 96, 79, 85, 73, 68, 69,
+  73, 88, 94, 94, 88, 79, 74, 77, 77, 82,
+  78, 85, 81, 88, 100, 86, 75, 80, 86, 104,
+  69, 85, 70, 83, 84, 85, 84, 102, 76, 76,
+  111, 88, 82, 86, 50, 97, 111, 85, 76, 71,
+  90, 76, 119, 71, 89, 123, 79, 73, 85, 95,
+  86, 62, 83, 77, 119, 108, 61, 66, 85, 98,
+  100, 76, 80, 84, 73, 43, 85, 95, 69, 64,
+  119, 68, 84, 84, 84, 34, 87, 50, 59, 79,
+  43, 85, 105, 80, 88, 110, 75, 83, 86, 117,
+  72, 97, 79, 73, 82, 80, 75, 79, 81, 73,
+  94, 90, 95, 91, 84, 74, 46, 85, 74, 70,
+  76, 83, 82, 106, 31, 74, 72, 87, 94, 71,
+  112, 89, 101, 82, 79, 78, 74, 93, 88, 93,
+  101, 88, 126, 99, 70, 63, 69, 76, 79, 82,
+  107, 82, 86, 80, 69, 79, 88, 120, 59, 101,
+  48, 80, 95, 64, 80, 103, 101, 74, 78, 92,
+  86, 80, 65, 81, 83, 81, 90, 78, 81, 80,
+  91, 80, 80, 87, 84, 92, 83, 97, 87, 69,
+  92, 82, 101, 105, 65, 80, 92, 76, 84, 102,
+  89, 85, 95, 89, 87, 87, 89, 65, 91, 88,
+  86, 123, 93, 76, 69, 87, 78, 84, 80, 72,
+  72, 59, 79, 96, 84, 91, 75, 87, 68, 105,
+  71, 72, 88, 80, 88, 91, 87, 87, 85, 91,
+  80, 66, 84, 85, 69, 69, 92, 97, 65, 81,
+  87, 101, 69, 67, 82, 93, 94, 83, 78, 73,
+  97, 72, 86, 79, 72, 92, 72, 89, 90, 85,
+  86, 82, 64, 85, 88, 77, 81, 92, 60, 83,
+  87, 90, 77, 82, 96, 96, 72, 85, 58, 86,
+  84, 94, 75, 76, 84, 88, 83, 79, 90, 89,
+  85, 86, 77, 72, 85, 70, 80, 90, 74, 93,
+  83, 86, 87, 75, 82, 95, 74, 83, 94, 81,
+  76, 87, 70, 78, 103, 73, 95, 84, 76, 92,
+  87, 96, 83, 78, 98, 83, 76, 89, 99, 87,
+  82, 78, 90, 98, 94, 84, 80, 97, 82, 87,
+  71, 78, 83, 75, 100, 92, 78, 82, 83, 78,
+  85, 82, 101, 85, 94, 84, 97, 86, 80, 81,
+  99, 74, 83, 94, 91, 77, 84, 81, 87, 97,
+  94, 94, 79, 102, 85, 74, 87, 67, 88, 75,
+  92, 65, 71, 88, 77, 82, 83, 80, 75, 69,
+  81, 77, 84, 86, 81, 84, 81, 82, 63, 92,
+  83, 84, 77, 87, 83, 83, 81, 86, 80, 84,
+  77, 75, 94, 82, 77, 80, 90, 91, 83, 89,
+  85, 70, 77, 89, 89, 89, 80, 90, 81, 88,
+  86, 69, 83, 93, 75, 72, 96, 80, 91, 101,
+  67, 75, 107, 80, 90, 72, 82, 96, 81, 82,
+  90, 77, 84, 74, 78, 86, 100, 68, 83, 64,
+  91, 105, 89, 81, 68, 99, 83, 86, 83, 74,
+  76, 60, 113, 87, 73, 88, 82, 66, 85, 82,
+  98, 87, 93, 74, 89, 77, 87, 67, 100, 63,
+  75, 104, 85, 78, 86, 88, 81, 99, 105, 106,
+  81, 93, 88, 64, 95, 64, 93, 76, 87, 69,
+  73, 75, 76, 83, 83, 87, 87, 78, 82, 70,
+  91, 76, 74, 76, 108, 91, 70, 88, 76, 88,
+  90, 93, 80, 87, 65, 90, 81, 84, 69, 71,
+  110, 85, 80, 77, 88, 87, 84, 85, 77, 68,
+  86, 91, 85, 87, 75, 90, 75, 84, 87, 84,
+  84, 100, 83, 82, 91, 83, 72, 99, 74, 76,
+  97, 67, 81, 83, 87, 89, 69, 99, 83, 78,
+  89, 79, 77, 90, 96, 80, 89, 79, 81, 108,
+  97, 87, 83, 67, 72, 75, 68, 84, 85, 78,
+  89, 78, 76, 84, 82, 78, 84, 90, 70, 90,
+  89, 83, 92, 89, 76, 73, 83, 75, 85, 76,
+  94, 92, 86, 84, 79, 90, 85, 92, 83, 91,
+  87, 81, 73, 72, 86, 73, 82, 71, 75, 65,
+  77, 81, 81, 80, 75, 81, 82, 81, 104, 83,
+  82, 79, 89, 89, 80, 97, 83, 79, 90, 81,
+  82, 85, 77, 89, 79, 86, 77, 76, 95, 85,
+  85, 86, 77, 83, 81, 87, 87, 63, 92, 100,
+  72, 83, 83, 78, 87, 87, 100, 76, 98, 90,
+  83, 78, 79, 82, 94, 93, 100, 78, 70, 79,
+  74, 91, 89, 84, 75, 84, 79, 81, 83, 80,
+  81, 83, 82, 75, 83, 87, 78, 65, 76, 85,
+  90, 87, 77, 75, 75, 89, 91, 89, 85, 80,
+  88, 78, 100, 85, 79, 97, 78, 85, 83, 97,
+  85, 70, 69, 85, 70, 78, 82, 91, 73, 95,
+  73, 87, 83, 94, 83, 94, 79, 72, 72, 93,
+  73, 81, 91, 97, 93, 83, 83, 77, 85, 81,
+  88, 93, 98, 89, 85, 71, 74, 83, 78, 81,
+  77, 96, 105, 92, 73, 104, 93, 92, 81, 93,
+  86, 80, 79, 85, 88, 76, 81, 77, 82, 81,
+  77, 70, 78, 74, 79, 76, 105, 80, 80, 68,
+  97, 100, 102, 72, 106, 76, 81, 79, 83, 87,
+  84, 81, 96, 73, 129, 83, 68, 80, 81, 74,
+  89, 80, 78, 83, 63, 84, 104, 91, 75, 91,
+  83, 65, 68, 76, 78, 81, 78, 87, 89, 82,
+  77, 70, 63, 88, 107, 69, 81, 90, 85, 68,
+  90, 98, 61, 102, 87, 68, 70, 98, 76, 60,
+  64, 82, 82, 77, 82, 101, 79, 76, 80, 82,
+  83, 104, 84, 93, 77, 84, 67, 100, 76, 85,
+  93, 110, 78, 76, 70, 92, 78, 79, 83, 82,
+  114, 91, 85, 72, 88, 81, 76, 78, 79, 86,
+  69, 92, 79, 112, 87, 110, 80, 92, 82, 77,
+  92, 75, 80, 92, 81, 86, 86, 90, 72, 85,
+  81, 88, 82, 66, 77, 61, 77, 91, 92, 80,
+  83, 89, 92, 80, 76, 86, 87, 78, 80, 84,
+  83, 74, 99, 81, 78, 84, 96, 84, 95, 87,
+  76, 78, 78, 83, 94, 78, 82, 100, 93, 95,
+  82, 88, 80, 85, 73, 84, 87, 77, 77, 76,
+  75, 85, 87, 86, 85, 78, 91, 77, 77, 89,
+  83, 82, 96, 83, 92, 90, 88, 77, 71, 84,
+  89, 84, 80, 86, 76, 85, 76, 72, 91, 91,
+  83, 94, 78, 100, 76, 98, 93, 83, 97, 98,
+  70, 83, 78, 97, 87, 78, 84, 89, 89, 87,
+  82, 68, 83, 80, 76, 87, 82, 92, 78, 92,
+  74, 98, 85, 90, 82, 96, 82, 76, 81, 85,
+  80, 79, 93, 93, 105, 96, 78, 68, 87, 82,
+  71, 74, 74, 70, 72, 86, 82, 71, 75, 85,
+  93, 73, 80, 94, 80, 74, 82, 78, 103, 69,
+  112, 90, 75, 107, 99, 105, 76, 98, 77, 87,
+  80, 96, 68, 86, 63, 87, 111, 98, 77, 83,
+  79, 79, 73, 87, 82, 98, 81, 70, 91, 94,
+  76, 101, 91, 77, 96, 68, 80, 90, 84, 83,
+  98, 98, 77, 86, 85, 62, 70, 105, 77, 74,
+  86, 74, 86, 79, 77, 81, 95, 90, 85, 87,
+  71, 90, 84, 85, 65, 70, 97, 85, 95, 81,
+  71, 84, 83, 78, 91, 75, 102, 92, 79, 70,
+  82, 84, 73, 90, 82, 95, 70, 95, 80, 74,
+  83, 71, 75, 92, 83, 81, 72, 69, 72, 80,
+  95, 107, 118, 83, 86, 55, 87, 75, 57, 83,
+  109, 77, 94, 74, 97, 84, 78, 76, 82, 69,
+  76, 85, 88, 70, 73, 86, 109, 82, 147, 85,
+  85, 95, 78, 76, 68, 96, 87, 92, 69, 112,
+  84, 110, 56, 76, 138, 83, 40, 84, 91, 86,
+  67, 97, 67, 96, 70, 70, 92, 113, 84, 74,
+  74, 97, 73, 68, 89, 121, 68, 72, 71, 89,
+  60, 74, 88, 51, 82, 89, 61, 66, 87, 78,
+  91, 86, 90, 89, 89, 85, 84, 82, 76, 77,
+  80, 87, 53, 68, 96, 106, 108, 67, 58, 90,
+  75, 77, 97, 71, 129, 98, 76, 72, 88, 105,
+  77, 89, 82, 93, 64, 108, 124, 67, 86, 83,
+  62, 105, 82, 76, 84, 60, 82, 91, 101, 92,
+  100, 84, 72, 69, 87, 82, 73, 77, 78, 86,
+  73, 86, 85, 68, 76, 91, 80, 75, 91, 92,
+  77, 71, 77, 77, 91, 104, 106, 77, 80, 86,
+  81, 93, 80, 100, 70, 79, 87, 94, 92, 82,
+  68, 87, 108, 109, 77, 84, 78, 88, 72, 84,
+  77, 94, 81, 74, 83, 85, 76, 108, 97, 79,
+  91, 71, 88, 89, 81, 81, 79, 96, 78, 84,
+  80, 65, 70, 89, 66, 81, 86, 72, 79, 99,
+  79, 93, 91, 87, 85, 85, 74, 80, 85, 79,
+  73, 69, 103, 90, 85, 80, 76, 75, 85, 76,
+  83, 76, 90, 85, 82, 72, 81, 88, 76, 93,
+  91, 96, 109, 91, 77, 79, 83, 71, 75, 89,
+  85, 76, 71, 74, 81, 80, 85, 88, 76, 85,
+  80, 84, 82, 93, 69, 88, 83, 72, 72, 104,
+  81, 69, 92, 82, 81, 74, 83, 86, 82, 78,
+  87, 81, 84, 64, 77, 97, 74, 92, 80, 95,
+  98, 79, 76, 82, 91, 86, 92, 72, 71, 98,
+  75, 77, 95, 100, 72, 79, 76, 85, 75, 80,
+  85, 76, 83, 83, 69, 93, 114, 85, 86, 84,
+  80, 76, 84, 80, 88, 83, 106, 86, 66, 92,
+  75, 75, 109, 90, 77, 85, 88, 87, 80, 75,
+  84, 85, 80, 90, 90, 87, 78, 77, 78, 78,
+  90, 75, 63, 98, 91, 86, 91, 80, 79, 71,
+  71, 81, 84, 84, 82, 71, 84, 87, 94, 81,
+  63, 86, 82, 94, 84, 74, 78, 86, 88, 95,
+  75, 78, 86, 74, 82, 97, 76, 73, 86, 66,
+  82, 87, 61, 87, 89, 84, 79, 110, 78, 63,
+  74, 75, 78, 71, 83, 88, 76, 71, 91, 77,
+  90, 86, 69, 98, 73, 81, 77, 75, 104, 78,
+  78, 81, 105, 83, 73, 70, 67, 89, 82, 61,
+  97, 98, 82, 83, 68, 80, 71, 86, 78, 85,
+  99, 84, 55, 94, 121, 91, 87, 79, 90, 82,
+  80, 93, 86, 89, 104, 90, 69, 91, 67, 67,
+  96, 83, 78, 93, 68, 82, 77, 89, 84, 80,
+  83, 91, 81, 85, 89, 78, 75, 79, 83, 84,
+  85, 96, 87, 89, 85, 75, 100, 73, 72, 82,
+  75, 82, 75, 73, 76, 85, 101, 70, 79, 94,
+  87, 85, 88, 69, 70, 85, 95, 100, 59, 68,
+  84, 74, 83, 83, 72, 73, 80, 83, 79, 92,
+  74, 89, 85, 89, 69, 100, 84, 67, 91, 86,
+  99, 74, 87, 81, 73, 73, 86, 79, 76, 89,
+  72, 94, 77, 70, 68, 80, 93, 82, 82, 78,
+  95, 84, 74, 74, 70, 90, 69, 81, 95, 100,
+  74, 78, 75, 83, 78, 89, 83, 83, 84, 77,
+  68, 94, 115, 86, 89, 90, 89, 74, 84, 73,
+  74, 80, 105, 90, 69, 94, 73, 70, 96, 88,
+  78, 81, 77, 81, 82, 85, 85, 88, 82, 89,
+  94, 79, 78, 77, 86, 78, 90, 84, 87, 88,
+  94, 80, 91, 80, 83, 76, 68, 83, 86, 88,
+  83, 81, 88, 84, 93, 80, 109, 82, 76, 104,
+  102, 79, 78, 85, 88, 89, 77, 86, 87, 101,
+  75, 81, 97, 79, 75, 100, 81, 91, 74, 77,
+  77, 75, 73, 93, 92, 100, 94, 102, 77, 89,
+  89, 73, 93, 100, 86, 80, 84, 79, 75, 88,
+  86, 65, 71, 79, 82, 72, 101, 98, 90, 72,
+  68, 89, 78, 75, 78, 78, 85, 77, 77, 95,
+  89, 102, 104, 97, 109, 93, 84, 76, 78, 60,
+  85, 69, 68, 94, 99, 72, 98, 80, 69, 71,
+  102, 91, 81, 79, 65, 57, 77, 93, 95, 90,
+  86, 94, 85, 79, 79, 59, 103, 77, 90, 84,
+  77, 74, 93, 78, 83, 79, 86, 88, 54, 59,
+  88, 82, 84, 73, 85, 80, 86, 92, 75, 77,
+  92, 77, 70, 82, 85, 73, 78, 99, 81, 88,
+  95, 100, 97, 84, 86, 106, 86, 81, 94, 87,
+  88, 83, 75, 87, 88, 88, 83, 74, 91, 92,
+  63, 86, 83, 86, 74, 102, 86, 93, 97, 78,
+  86, 67, 88, 85, 88, 83, 77, 91, 88, 82,
+  75, 90, 84, 83, 89, 88, 86, 72, 71, 81,
+  75, 81, 86, 78, 80, 80, 74, 97, 91, 79,
+  86, 77, 89, 69, 80, 82, 99, 68, 86, 80,
+  64, 77, 90, 76, 85, 113, 70, 80, 100, 79,
+  79, 79, 83, 76, 74, 71, 90, 75, 68, 90,
+  82, 83, 85, 84, 59, 72, 95, 87, 82, 61,
+  90, 72, 89, 73, 81, 73, 76, 73, 95, 90,
+  84, 76, 85, 81, 68, 74, 78, 76, 76, 82,
+  84, 107, 102, 72, 79, 84, 92, 81, 81, 79,
+  94, 85, 81, 71, 94, 75, 90, 89, 90, 68,
+  73, 80, 90, 87, 87, 78, 104, 93, 70, 85,
+  90, 83, 77, 85, 97, 85, 77, 83, 83, 68,
+  82, 84, 84, 76, 98, 98, 89, 91, 80, 84,
+  86, 90, 77, 89, 80, 81, 73, 84, 78, 80,
+  87, 70, 81, 75, 71, 102, 94, 81, 79, 79,
+  81, 80, 84, 85, 104, 80, 76, 98, 78, 84,
+  80, 83, 79, 87, 77, 76, 88, 86, 82, 77,
+  79, 85, 99, 76, 83, 84, 75, 74, 81, 87,
+  88, 81, 78, 78, 97, 90, 95, 79, 92, 86,
+  93, 85, 82, 77, 89, 87, 94, 89, 87, 78,
+  75, 84, 75, 86, 91, 73, 74, 88, 89, 95,
+  88, 84, 79, 83, 98, 87, 87, 79, 93, 82,
+  83, 83, 81, 95, 87, 77, 81, 93, 67, 91,
+  76, 93, 77, 75, 68, 89, 70, 83, 84, 96,
+  86, 120, 69, 87, 99, 87, 100, 86, 101, 87,
+  95, 66, 67, 86, 104, 70, 113, 97, 84, 77,
+  82, 84, 80, 85, 69, 72, 74, 85, 83, 83,
+  78, 79, 81, 75, 88, 90, 97, 69, 98, 54,
+  78, 77, 80, 63, 88, 49, 60, 70, 96, 83,
+  89, 87, 65, 107, 89, 98, 85, 73, 68, 120,
+  68, 95, 84, 71, 96, 120, 74, 78, 84, 79,
+  81, 80, 114, 70, 79, 72, 93, 69, 88, 78,
+  74, 83, 64, 62, 97, 90, 84, 78, 87, 71,
+  92, 76, 80, 82, 75, 85, 44, 123, 85, 83,
+  73, 79, 82, 86, 100, 80, 80, 74, 80, 118,
+  75, 71, 75, 92, 88, 95, 86, 72, 78, 77,
+  87, 83, 100, 111, 76, 71, 77, 77, 71, 91,
+  84, 68, 65, 86, 95, 71, 83, 79, 90, 73,
+  100, 90, 87, 105, 113, 88, 97, 83, 72, 73,
+  100, 95, 97, 76, 59, 80, 107, 90, 71, 78,
+  91, 79, 86, 73, 71, 86, 61, 63, 84, 110,
+  90, 66, 82, 92, 67, 71, 78, 102, 82, 83,
+  67, 112, 59, 84, 90, 59, 84, 113, 85, 76,
+  82, 81, 78, 77, 95, 88, 95, 101, 63, 73,
+  87, 86, 107, 84, 77, 98, 84, 72, 88, 60,
+  86, 98, 100, 94, 85, 73, 93, 88, 78, 64,
+  80, 92, 55, 83, 91, 140, 67, 99, 103, 70,
+  95, 78, 79, 60, 87, 76, 85, 66, 82, 83,
+  83, 95, 84, 75, 81, 77, 86, 78, 89, 92,
+  85, 86, 83, 80, 89, 79, 80, 83, 81, 70,
+  77, 86, 82, 70, 81, 79, 82, 89, 101, 97,
+  92, 91, 84, 82, 82, 88, 76, 67, 94, 80,
+  86, 86, 67, 78, 97, 94, 72, 77, 87, 80,
+  94, 78, 74, 90, 68, 89, 89, 93, 95, 85,
+  80, 95, 92, 78, 83, 92, 81, 74, 75, 85,
+  74, 93, 83, 66, 75, 85, 86, 77, 83, 89,
+  86, 77, 80, 92, 83, 84, 98, 74, 91, 87,
+  108, 91, 79, 96, 83, 85, 80, 78, 86, 101,
+  96, 89, 75, 80, 87, 88, 85, 77, 86, 86,
+  63, 83, 101, 97, 76, 94, 87, 87, 95, 80,
+  87, 78, 86, 78, 81, 85, 82, 91, 84, 83,
+  92, 85, 77, 96, 79, 90, 81, 85, 75, 92,
+  68, 86, 79, 101, 84, 93, 78, 94, 78, 88,
+  93, 94, 93, 87, 94, 63, 72, 92, 104, 75,
+  113, 89, 75, 87, 78, 89, 95, 83, 92, 80,
+  94, 94, 82, 78, 83, 74, 76, 92, 87, 98,
+  101, 79, 92, 71, 74, 76, 78, 76, 89, 65,
+  68, 83, 73, 86, 83, 79, 78, 91, 91, 90,
+  82, 77, 73, 96, 83, 90, 90, 78, 95, 88,
+  81, 77, 82, 73, 87, 87, 98, 74, 83, 76,
+  97, 78, 82, 78, 63, 92, 77, 75, 99, 87,
+  76, 74, 73, 83, 92, 73, 83, 81, 78, 75,
+  69, 111, 55, 86, 88, 81, 74, 84, 95, 86,
+  88, 82, 78, 99, 75, 74, 66, 90, 93, 72,
+  86, 82, 80, 82, 80, 93, 100, 84, 68, 78,
+  72, 79, 72, 84, 80, 78, 65, 91, 92, 76,
+  99, 84, 89, 79, 81, 92, 97, 98, 98, 75,
+  78, 87, 78, 79, 101, 80, 95, 79, 70, 95,
+  89, 78, 83, 78, 80, 84, 86, 83, 87, 102,
+  71, 76, 80, 86, 84, 78, 89, 89, 78, 82,
+  70, 82, 87, 83, 80, 87, 84, 83, 81, 70,
+  77, 82, 98, 77, 82, 87, 82, 68, 77, 88,
+  82, 91, 81, 77, 99, 83, 108, 86, 81, 87,
+  85, 73, 76, 83, 82, 91, 95, 89, 81, 83,
+  73, 89, 93, 64, 83, 88, 71, 76, 96, 105,
+  62, 93, 95, 92, 86, 77, 83, 76, 90, 84,
+  79, 72, 81, 75, 73, 87, 85, 76, 83, 80,
+  83, 86, 86, 96, 92, 75, 76, 77, 82, 76,
+  74, 87, 81, 73, 88, 83, 81, 76, 92, 82,
+  85, 94, 80, 92, 93, 87, 90, 73, 70, 78,
+  84, 72, 89, 73, 88, 91, 79, 89, 74, 73,
+  82, 73, 83, 81, 93, 85, 84, 105, 85, 86,
+  85, 86, 81, 84, 80, 83, 95, 80, 78, 81,
+  90, 76, 81, 80, 86, 82, 80, 78, 75, 79,
+  84, 79, 82, 89, 82, 79, 75, 90, 82, 83,
+  94, 87, 106, 82, 101, 81, 82, 82, 81, 81,
+  77, 83, 79, 87, 89, 88, 85, 87, 80, 81,
+  104, 76, 83, 83, 75, 82, 100, 72, 106, 88,
+  81, 105, 94, 86, 87, 86, 84, 86, 81, 81,
+  93, 64, 63, 81, 96, 86, 83, 93, 81, 83,
+  94, 79, 70, 85, 89, 89, 96, 82, 90, 79,
+  44, 75, 60, 94, 71, 83, 79, 88, 87, 80,
+  87, 80, 82, 105, 84, 89, 76, 78, 75, 78,
+  76, 60, 93, 77, 75, 77, 89, 100, 81, 85,
+  88, 77, 83, 90, 71, 85, 75, 91, 73, 84,
+  100, 80, 71, 89, 68, 84, 80, 77, 103, 55,
+  91, 67, 90, 86, 77, 72, 90, 77, 102, 84,
+  83, 91, 90, 78, 82, 87, 89, 85, 93, 84,
+  77, 101, 76, 83, 86, 78, 91, 102, 83, 84,
+  72, 86, 80, 85, 84, 88, 72, 77, 73, 88,
+  83, 88, 85, 86, 78, 74, 90, 83, 74, 72,
+  76, 91, 74, 83, 68, 88, 91, 89, 90, 72,
+  80, 78, 73, 87, 81, 76, 84, 89, 88, 88,
+  84, 82, 97, 79, 83, 95, 81, 80, 67, 86,
+  72, 94, 75, 83, 80, 88, 78, 71, 87, 83,
+  87, 94, 89, 83, 88, 84, 82, 79, 79, 94,
+  88, 86, 89, 75, 76, 94, 88, 91, 83, 78,
+  82, 82, 81, 85, 89, 82, 83, 77, 94, 81,
+  76, 106, 76, 116, 79, 84, 86, 75, 75, 84,
+  88, 85, 79, 75, 93, 85, 91, 96, 85, 84,
+  81, 74, 89, 77, 73, 85, 90, 82, 72, 90,
+  87, 77, 78, 88, 82, 90, 80, 90, 84, 85,
+  80, 87, 86, 85, 76, 86, 75, 86, 96, 86,
+  92, 85, 79, 90, 80, 86, 83, 82, 72, 88,
+  61, 82, 78, 80, 94, 94, 88, 74, 103, 84,
+  72, 98, 80, 69, 82, 91, 73, 82, 93, 74,
+  92, 83, 70, 101, 74, 80, 84, 80, 92, 93,
+  86, 87, 81, 86, 76, 77, 84, 86, 83, 97,
+  93, 81, 92, 82, 90, 75, 85, 100, 87, 90,
+  92, 81, 81, 99, 88, 95, 78, 83, 88, 77,
+  79, 82, 95, 79, 78, 80, 91, 81, 83, 100,
+  100, 95, 72, 88, 80, 95, 76, 87, 84, 87,
+  78, 87, 93, 88, 84, 84, 83, 82, 84, 82,
+  85, 69, 75, 93, 89, 81, 80, 97, 93, 73,
+  85, 89, 68, 73, 88, 87, 92, 80, 75, 84,
+  86, 78, 88, 90, 78, 93, 100, 92, 88, 84,
+  79, 92, 96, 92, 92, 87, 80, 89, 68, 79,
+  89, 85, 82, 89, 83, 73, 61, 85, 102, 75,
+  81, 92, 78, 81, 88, 78, 68, 87, 80, 98,
+  101, 76, 82, 83, 66, 85, 64, 96, 75, 71,
+  90, 86, 108, 80, 85, 86, 85, 104, 84, 85,
+  80, 76, 83, 70, 73, 51, 87, 88, 67, 103,
+  97, 98, 84, 78, 76, 93, 90, 89, 94, 89,
+  68, 85, 87, 84, 97, 76, 83, 80, 57, 55,
+  83, 79, 114, 63, 119, 61, 80, 92, 85, 78,
+  80, 79, 116, 65, 84, 92, 90, 79, 83, 86,
+  95, 86, 80, 86, 83, 107, 71, 79, 82, 67,
+  82, 86, 110, 87, 74, 102, 87, 84, 83, 81,
+  78, 76, 77, 73, 73, 91, 72, 88, 82, 79,
+  79, 85, 80, 70, 77, 88, 102, 83, 81, 92,
+  86, 76, 86, 72, 67, 86, 91, 72, 82, 95,
+  76, 89, 94, 82, 79, 89, 96, 86, 99, 86,
+  92, 79, 75, 84, 62, 93, 71, 85, 81, 89,
+  90, 67, 87, 82, 87, 94, 80, 86, 80, 84,
+  72, 79, 79, 74, 87, 80, 88, 79, 74, 95,
+  88, 83, 87, 84, 81, 91, 89, 71, 78, 87,
+  80, 77, 92, 81, 88, 80, 64, 89, 81, 83,
+  96, 71, 87, 70, 85, 89, 79, 72, 82, 81,
+  94, 93, 86, 86, 81, 75, 91, 75, 88, 85,
+  79, 92, 73, 89, 74, 92, 86, 86, 92, 94,
+  90, 84, 77, 98, 84, 85, 77, 71, 75, 78,
+  76, 81, 84, 81, 87, 89, 81, 85, 74, 84,
+  78, 72, 74, 89, 78, 90, 75, 77, 97, 88,
+  90, 65, 83, 79, 82, 78, 86, 87, 73, 86,
+  84, 80, 87, 87, 95, 74, 79, 93, 83, 74,
+  85, 82, 80, 96, 73, 89, 83, 87, 75, 75,
+  86, 79, 86, 94, 90, 77, 82, 82, 82, 82,
+  81, 100, 84, 83, 100, 78, 75, 95, 88, 90,
+  84, 84, 82, 88, 80, 77, 84, 86, 75, 75,
+  88, 89, 86, 96, 82, 103, 77, 86, 83, 78,
+  74, 81, 88, 82, 79, 78, 85, 75, 81, 99,
+  82, 84, 80, 78, 96, 62, 84, 86, 79, 85,
+  76, 98, 81, 86, 79, 88, 81, 95, 90, 90,
+  82, 92, 78, 87, 84, 72, 80, 85, 81, 86,
+  89, 88, 86, 85, 85, 87, 80, 89, 87, 78,
+  74, 86, 62, 87, 81, 75, 88, 89, 75, 79,
+  66, 83, 88, 76, 80, 78, 100, 79, 74, 87,
+  83, 89, 68, 96, 101, 76, 77, 91, 94, 93,
+  94, 91, 77, 69, 98, 71, 122, 73, 91, 85,
+  85, 101, 86, 83, 97, 88, 88, 68, 75, 60,
+  88, 99, 69, 122, 94, 110, 74, 86, 83, 103,
+  94, 78, 104, 106, 87, 67, 126, 93, 92, 72,
+  80, 58, 67, 47, 79, 97, 101, 80, 110, 80,
+  80, 92, 78, 85, 89, 85, 108, 70, 84, 84,
+  94, 83, 78, 96, 96, 84, 81, 84, 99, 101,
+  88, 76, 89, 75, 74, 84, 136, 93, 85, 87,
+  92, 84, 97, 93, 83, 87, 79, 68, 73, 86,
+  65, 94, 86, 97, 87, 105, 86, 78, 81, 88,
+  106, 70, 95, 88, 86, 75, 70, 74, 55, 84,
+  96, 75, 78, 88, 83, 80, 91, 86, 86, 85,
+  75, 91, 99, 84, 87, 88, 87, 79, 82, 89,
+  73, 78, 90, 82, 87, 62, 84, 84, 84, 95,
+  71, 94, 93, 78, 89, 80, 74, 71, 92, 82,
+  76, 90, 79, 104, 79, 79, 81, 86, 84, 96,
+  88, 89, 80, 73, 98, 87, 95, 72, 86, 47,
+  69, 61, 81, 80, 88, 77, 118, 77, 82, 92,
+  78, 77, 79, 84, 109, 91, 90, 82, 83, 75,
+  83, 87, 93, 86, 86, 85, 85, 92, 77, 79,
+  75, 80, 91, 83, 108, 81, 74, 102, 87, 81,
+  80, 81, 77, 81, 74, 69, 74, 77, 69, 100,
+  80, 91, 86, 85, 76, 74, 84, 86, 100, 75,
+  81, 86, 85, 78, 76, 62, 63, 84, 91, 68,
+  86, 93, 79, 82, 92, 87, 88, 91, 82, 87,
+  93, 91, 93, 81, 81, 79, 74, 97, 69, 83,
+  89, 86, 82, 58, 82, 84, 85, 95, 82, 79,
+  94, 82, 73, 100, 77, 83, 90, 76, 85, 75,
+  74, 94, 82, 87, 81, 83, 80, 103, 75, 81,
+  82, 79, 84, 82, 92, 83, 89, 66, 77, 84,
+  83, 80, 92, 84, 89, 74, 86, 86, 74, 74,
+  77, 73, 102, 97, 87, 81, 80, 74, 85, 76,
+  95, 85, 77, 89, 80, 106, 71, 83, 78, 88,
+  96, 94, 102, 84, 77, 96, 84, 83, 81, 65,
+  78, 84, 72, 77, 78, 78, 80, 97, 78, 86,
+  71, 88, 79, 72, 75, 89, 77, 85, 85, 83,
+  89, 83, 68, 51, 93, 76, 52, 75, 76, 76,
+  96, 80, 57, 101, 93, 76, 82, 66, 82, 71,
+  74, 90, 83, 91, 90, 81, 92, 85, 104, 94,
+  96, 95, 90, 76, 101, 88, 94, 98, 61, 78,
+  74, 67, 77, 85, 85, 52, 71, 53, 91, 77,
+  95, 108, 61, 66, 78, 82, 59, 71, 79, 66,
+  78, 99, 120, 98, 84, 94, 87, 47, 127, 166,
+  82, 74, 74, 123, 73, 79, 67, 75, 127, 80,
+  98, 85, 75, 68, 85, 114, 80, 92, 81, 93,
+  67, 75, 84, 94, 84, 100, 84, 62, 71, 103,
+  83, 83, 55, 85, 114, 86, 77, 70, 87, 60,
+  87, 82, 86, 84, 73, 89, 71, 89, 68, 74,
+  86, 72, 87, 133, 78, 74, 35, 84, 74, 114,
+  71, 66, 68, 82, 68, 72, 81, 77, 88, 85,
+  66, 96, 90, 68, 85, 72, 91, 77, 67, 85,
+  86, 82, 79, 85, 87, 86, 95, 91, 107, 96,
+  86, 85, 95, 88, 81, 101, 70, 80, 80, 66,
+  87, 94, 88, 60, 80, 69, 92, 96, 92, 97,
+  69, 57, 83, 83, 64, 73, 72, 73, 74, 94,
+  112, 90, 82, 87, 90, 52, 96, 153, 91, 71,
+  86, 121, 72, 79, 73, 73, 121, 66, 101, 79,
+  79, 68, 84, 95, 77, 88, 82, 91, 66, 73,
+  81, 104, 86, 99, 92, 71, 79, 102, 93, 73,
+  58, 113, 106, 91, 76, 73, 88, 68, 85, 69,
+  83, 85, 72, 86, 75, 89, 72, 74, 86, 67,
+  93, 105, 83, 73, 43, 84, 79, 95, 79, 89,
+  77, 80, 89, 105, 93, 87, 90, 83, 83, 81,
+  86, 77, 74, 86, 89, 100, 93, 83, 91, 76,
+  78, 91, 76, 88, 72, 91, 85, 81, 84, 79,
+  79, 78, 80, 96, 80, 78, 78, 81, 71, 86,
+  89, 97, 83, 86, 82, 68, 86, 82, 83, 92,
+  95, 86, 95, 83, 89, 71, 81, 70, 84, 85,
+  80, 64, 96, 75, 79, 72, 91, 78, 93, 77,
+  91, 80, 80, 88, 76, 83, 90, 106, 101, 86,
+  83, 85, 79, 74, 95, 76, 104, 74, 90, 83,
+  86, 85, 101, 92, 93, 71, 84, 85, 65, 74,
+  72, 82, 82, 80, 83, 86, 85, 95, 80, 76,
+  85, 83, 70, 83, 94, 86, 83, 83, 96, 86,
+  88, 94, 91, 87, 96, 82, 89, 64, 75, 82,
+  82, 75, 94, 86, 88, 84, 76, 80, 96, 77,
+  83, 72, 67, 77, 82, 83, 86, 105, 68, 91,
+  88, 77, 106, 88, 89, 81, 90, 85, 92, 94,
+  111, 90, 74, 81, 73, 81, 92, 84, 95, 72,
+  85, 72, 82, 67, 84, 82, 75, 86, 88, 88,
+  80, 81, 62, 78, 72, 79, 87, 94, 91, 95,
+  91, 62, 77, 110, 71, 70, 84, 110, 86, 77,
+  76, 77, 95, 80, 79, 76, 79, 72, 90, 84,
+  66, 86, 88, 82, 81, 88, 84, 79, 86, 74,
+  84, 73, 69, 94, 79, 86, 53, 84, 88, 80,
+  84, 72, 89, 81, 91, 70, 82, 79, 75, 86,
+  73, 80, 75, 75, 80, 84, 76, 82, 91, 75,
+  65, 83, 68, 79, 91, 79, 70, 85, 88, 67,
+  95, 83, 82, 87, 82, 78, 101, 74, 87, 79,
+  69, 85, 79, 80, 90, 103, 79, 92, 81, 78,
+  93, 87, 93, 109, 90, 84, 89, 79, 73, 87,
+  77, 79, 94, 85, 94, 85, 85, 79, 89, 76,
+  87, 75, 84, 77, 76, 82, 88, 88, 85, 70,
+  64, 83, 75, 74, 82, 82, 91, 84, 85, 71,
+  68, 89, 67, 78, 84, 103, 85, 78, 77, 73,
+  87, 71, 71, 71, 81, 78, 91, 90, 64, 93,
+  76, 82, 86, 86, 77, 74, 90, 75, 79, 74,
+  79, 88, 83, 82, 55, 72, 83, 85, 81, 74,
+  86, 88, 84, 66, 83, 83, 80, 80, 84, 89,
+  97, 75, 83, 81, 89, 66, 90, 75, 66, 85,
+  75, 74, 86, 88, 81, 76, 87, 88, 88, 87,
+  93, 81, 93, 76, 90, 78, 82, 80, 81, 91,
+  90, 85, 90, 84, 84, 84, 73, 87, 69, 84,
+  83, 85, 85, 81, 82, 77, 79, 90, 81, 93,
+  95, 81, 75, 81, 87, 97, 83, 80, 78, 76,
+  88, 78, 82, 86, 91, 93, 95, 91, 90, 78,
+  81, 81, 76, 79, 79, 72, 92, 80, 80, 72,
+  85, 78, 93, 80, 86, 81, 85, 84, 73, 82,
+  76, 94, 96, 97, 80, 81, 79, 82, 88, 77,
+  102, 84, 85, 72, 79, 82, 89, 92, 89, 75,
+  75, 85, 72, 66, 72, 80, 91, 79, 81, 95,
+  90, 86, 75, 81, 87, 78, 82, 84, 93, 85,
+  82, 78, 86, 79, 88, 88, 96, 84, 87, 77,
+  94, 88, 89, 75, 111, 91, 92, 86, 86, 83,
+  90, 78, 93, 78, 75, 83, 76, 84, 93, 101,
+  87, 104, 74, 93, 77, 78, 77, 87, 85, 70,
+  90, 89, 88, 93, 76, 73, 79, 90, 74, 93,
+  91, 68, 71, 100, 86, 89, 79, 82, 77, 71,
+  91, 110, 90, 93, 88, 94, 84, 92, 94, 69,
+  74, 80, 68, 85, 99, 90, 84, 82, 77, 83,
+  89, 58, 93, 79, 79, 88, 70, 73, 88, 78,
+  96, 95, 65, 76, 80, 91, 88, 70, 80, 90,
+  87, 83, 89, 78, 84, 80, 84, 78, 86, 88,
+  76, 97, 68, 76, 92, 100, 91, 90, 90, 89,
+  77, 75, 82, 89, 94, 78, 84, 84, 82, 84,
+  83, 81, 84, 90, 119, 92, 81, 71, 89, 96,
+  85, 75, 105, 75, 92, 86, 85, 85, 92, 78,
+  99, 83, 86, 86, 77, 88, 92, 96, 72, 103,
+  80, 92, 84, 78, 82, 85, 81, 90, 88, 92,
+  86, 80, 73, 78, 85, 87, 93, 98, 92, 73,
+  80, 95, 83, 84, 88, 68, 72, 77, 90, 105,
+  90, 91, 88, 81, 88, 91, 96, 77, 73, 83,
+  70, 86, 93, 98, 82, 77, 82, 90, 88, 63,
+  95, 75, 81, 84, 74, 81, 76, 72, 95, 96,
+  77, 92, 79, 94, 78, 69, 84, 91, 83, 79,
+  88, 82, 77, 79, 88, 77, 82, 87, 79, 95,
+  70, 79, 86, 93, 84, 88, 89, 90, 80, 76,
+  85, 84, 100, 82, 103, 84, 89, 83, 83, 82,
+  79, 88, 111, 93, 85, 77, 88, 92, 92, 78,
+  86, 83, 83, 87, 82, 89, 91, 76, 88, 87,
+  85, 82, 83, 84, 85, 90, 82, 80, 87, 91,
+  81, 86, 72, 80, 79, 92, 82, 88, 83, 77,
+  82, 79, 86, 89, 99, 74, 87, 76, 84, 96,
+  88, 88, 78, 76, 76, 75, 89, 90, 88, 85,
+  89, 93, 96, 92, 83, 87, 81, 79, 74, 85,
+  96, 85, 81, 84, 82, 86, 87, 71, 83, 81,
+  88, 85, 75, 82, 81, 90, 94, 101, 77, 79,
+  81, 91, 85, 72, 91, 96, 86, 79, 87, 85,
+  81, 92, 93, 80, 74, 78, 88, 82, 78, 76,
+  90, 80, 82, 82, 85, 91, 80, 77, 87, 81,
+  90, 83, 100, 90, 83, 84, 90, 77, 68, 98,
+  104, 85, 82, 84, 85, 89, 77, 84, 79, 95,
+  97, 78, 79, 81, 84, 78, 93, 86, 76, 96,
+  76, 100, 101, 94, 83, 102, 79, 74, 83, 102,
+  71, 80, 92, 78, 79, 86, 84, 84, 75, 81,
+  77, 94, 97, 92, 85, 79, 91, 83, 62, 94,
+  83, 83, 85, 83, 81, 80, 80, 77, 95, 76,
+  86, 74, 86, 88, 96, 82, 81, 84, 73, 82,
+  96, 83, 75, 85, 84, 91, 85, 68, 87, 93,
+  87, 76, 74, 86, 85, 83, 87, 80, 86, 100,
+  85, 72, 76, 80, 108, 97, 90, 92, 82, 86,
+  88, 73, 89, 89, 84, 71, 90, 80, 83, 86,
+  87, 86, 77, 85, 84, 79, 91, 90, 68, 99,
+  72, 86, 96, 91, 75, 78, 97, 73, 82, 81,
+  98, 77, 58, 92, 74, 79, 74, 79, 81, 83,
+  93, 81, 78, 82, 87, 74, 65, 97, 76, 99,
+  92, 96, 93, 81, 88, 76, 77, 89, 78, 80,
+  85, 69, 69, 86, 74, 87, 71, 82, 69, 100,
+  75, 74, 105, 61, 78, 87, 72, 94, 70, 72,
+  77, 82, 79, 81, 81, 68, 88, 63, 79, 60,
+  92, 89, 105, 79, 86, 75, 74, 62, 84, 82,
+  70, 105, 74, 73, 100, 74, 82, 95, 84, 84,
+  77, 62, 82, 88, 75, 90, 74, 98, 91, 66,
+  69, 80, 109, 114, 95, 82, 104, 74, 84, 80,
+  72, 90, 103, 87, 72, 83, 65, 83, 72, 86,
+  68, 91, 79, 76, 88, 92, 67, 86, 77, 75,
+  78, 84, 85, 76, 83, 66, 83, 85, 96, 70,
+  85, 82, 86, 78, 78, 77, 95, 84, 78, 85,
+  83, 78, 88, 91, 84, 96, 77, 98, 96, 101,
+  97, 97, 96, 77, 83, 103, 77, 80, 82, 72,
+  88, 85, 84, 93, 76, 85, 83, 99, 80, 92,
+  90, 85, 76, 85, 59, 93, 81, 80, 87, 82,
+  74, 84, 78, 73, 94, 73, 80, 73, 87, 85,
+  89, 77, 78, 84, 66, 86, 88, 79, 86, 75,
+  79, 83, 89, 74, 88, 90, 88, 81, 91, 86,
+  80, 83, 91, 83, 83, 92, 92, 81, 84, 79,
+  112, 86, 91, 90, 84, 84, 91, 79, 91, 94,
+  84, 84, 90, 80, 78, 82, 77, 84, 76, 83,
+  91, 79, 90, 84, 76, 90, 80, 83, 96, 88,
+  82, 75, 94, 74, 83, 83, 99, 84, 99, 78,
+  82, 87, 74, 80, 72, 73, 75, 83, 80, 70,
+  75, 77, 79, 92, 77, 83, 85, 100, 78, 96,
+  105, 78, 84, 80, 81, 84, 94, 71, 90, 87,
+  78, 67, 87, 80, 90, 80, 108, 66, 88, 81,
+  80, 84, 89, 88, 88, 71, 80, 79, 91, 91,
+  90, 67, 84, 102, 82, 85, 95, 79, 88, 83,
+  93, 73, 71, 61, 87, 76, 76, 81, 87, 94,
+  86, 92, 85, 70, 98, 95, 67, 81, 90, 69,
+  79, 88, 62, 87, 80, 86, 89, 77, 80, 93,
+  86, 75, 92, 80, 87, 78, 83, 74, 90, 70,
+  97, 82, 78, 83, 87, 80, 76, 83, 71, 93,
+  85, 87, 84, 103, 76, 76, 62, 89, 94, 80,
+  72, 83, 82, 77, 75, 81, 157, 85, 90, 92,
+  68, 72, 74, 69, 87, 85, 80, 82, 127, 115,
+  79, 76, 88, 62, 94, 76, 70, 135, 78, 74,
+  81, 67, 88, 89, 95, 77, 111, 97, 83, 71,
+  93, 68, 106, 60, 123, 68, 68, 106, 82, 93,
+  113, 51, 96, 81, 67, 83, 97, 141, 89, 69,
+  96, 124, 58, 101, 113, 61, 98, 57, 103, 88,
+  42, 107, 76, 65, 66, 58, 88, 88, 47, 88,
+  82, 52, 105, 84, 72, 86, 93, 77, 78, 75,
+  60, 64, 71, 102, 139, 67, 58, 76, 89, 60,
+  69, 71, 105, 90, 89, 82, 86, 102, 113, 84,
+  79, 77, 71, 85, 92, 84, 96, 81, 98, 76,
+  109, 112, 62, 74, 64, 77, 97, 75, 72, 95,
+  101, 60, 75, 100, 87, 74, 82, 88, 79, 105,
+  71, 78, 81, 85, 76, 72, 68, 101, 78, 94,
+  82, 82, 80, 94, 82, 89, 89, 81, 75, 83,
+  84, 82, 87, 80, 95, 91, 76, 90, 80, 85,
+  99, 81, 70, 73, 93, 88, 81, 87, 86, 87,
+  84, 96, 85, 78, 88, 81, 93, 68, 92, 77,
+  75, 82, 90, 78, 85, 89, 95, 71, 64, 58,
+  73, 73, 84, 66, 75, 88, 83, 94, 86, 73,
+  88, 69, 85, 83, 88, 71, 84, 104, 65, 75,
+  91, 81, 91, 84, 81, 102, 91, 75, 89, 82,
+  90, 80, 81, 78, 89, 105, 92, 83, 78, 73,
+  78, 83, 77, 89, 83, 96, 85, 89, 87, 87,
+  86, 79, 67, 87, 79, 76, 80, 81, 83, 78,
+  81, 83, 88, 89, 81, 88, 70, 85, 80, 79,
+  82, 85, 76, 76, 74, 87, 82, 89, 82, 84,
+  85, 98, 69, 98, 85, 80, 83, 87, 98, 90,
+  91, 81, 92, 87, 73, 78, 101, 82, 74, 95,
+  73, 76, 92, 98, 84, 80, 75, 92, 88, 76,
+  81, 79, 108, 83, 90, 73, 77, 53, 83, 77,
+  87, 86, 74, 100, 91, 78, 83, 68, 82, 82,
+  91, 67, 78, 97, 93, 90, 87, 76, 95, 90,
+  86, 81, 87, 74, 84, 81, 70, 87, 89, 91,
+  84, 80, 89, 90, 82, 69, 93, 79, 73, 67,
+  70, 83, 85, 79, 88, 82, 86, 101, 91, 84,
+  67, 77, 85, 85, 76, 96, 87, 103, 71, 75,
+  78, 84, 83, 80, 86, 78, 84, 85, 75, 71,
+  111, 91, 84, 99, 63, 73, 77, 80, 99, 84,
+  84, 87, 120, 101, 81, 81, 98, 72, 87, 84,
+  73, 105, 78, 81, 73, 72, 112, 90, 88, 97,
+  75, 90, 87, 75, 97, 81, 81, 86, 106, 70,
+  92, 105, 76, 77, 83, 66, 82, 79, 76, 86,
+  114, 96, 95, 70, 69, 91, 67, 73, 90, 74,
+  66, 88, 98, 86, 72, 94, 83, 58, 93, 61,
+  84, 91, 83, 91, 69, 58, 88, 86, 83, 89,
+  91, 79, 83, 83, 74, 90, 84, 91, 97, 59,
+  66, 86, 86, 55, 85, 82, 80, 73, 76, 92,
+  85, 83, 93, 81, 66, 101, 80, 88, 61, 72,
+  80, 56, 75, 84, 76, 99, 86, 71, 70, 80,
+  79, 78, 89, 88, 90, 79, 63, 76, 79, 79,
+  67, 88, 77, 88, 84, 81, 92, 90, 76, 82,
+  82, 87, 78, 98, 84, 90, 88, 93, 89, 85,
+  89, 80, 74, 91, 96, 92, 86, 102, 85, 84,
+  73, 87, 85, 91, 82, 94, 87, 79, 94, 90,
+  78, 84, 78, 81, 80, 87, 86, 82, 99, 82,
+  97, 76, 86, 92, 83, 81, 84, 86, 76, 99,
+  98, 76, 74, 76, 86, 83, 88, 74, 72, 99,
+  94, 96, 80, 82, 85, 66, 85, 76, 87, 75,
+  84, 103, 76, 86, 90, 78, 78, 82, 90, 92,
+  85, 68, 87, 80, 80, 69, 93, 81, 85, 93,
+  94, 82, 86, 99, 79, 83, 64, 78, 66, 89,
+  78, 89, 71, 86, 104, 79, 76, 87, 84, 84,
+  92, 79, 80, 88, 83, 70, 86, 79, 81, 71,
+  83, 89, 98, 92, 78, 85, 86, 87, 88, 71,
+  78, 75, 79, 79, 74, 90, 78, 98, 91, 76,
+  74, 99, 89, 83, 91, 87, 90, 84, 82, 84,
+  78, 88, 92, 87, 78, 83, 85, 70, 92, 76,
+  83, 79, 81, 83, 81, 78, 101, 83, 83, 81,
+  80, 74, 101, 83, 78, 108, 91, 81, 77, 78,
+  92, 84, 83, 79, 71, 85, 83, 82, 89, 76,
+  71, 80, 85, 84, 88, 87, 87, 124, 81, 81,
+  79, 81, 81, 90, 79, 80, 83, 80, 76, 71,
+  81, 75, 80, 92, 82, 81, 102, 88, 75, 79,
+  84, 78, 100, 93, 82, 84, 76, 69, 81, 87,
+  84, 73, 90, 75, 80, 83, 95, 84, 78, 77,
+  79, 86, 78, 78, 82, 83, 71, 75, 86, 80,
+  94, 83, 78, 84, 88, 93, 82, 76, 75, 75,
+  80, 80, 79, 86, 81, 92, 85, 76, 76, 93,
+  87, 85, 87, 88, 87, 86, 79, 83, 79, 88,
+  89, 83, 73, 82, 86, 69, 84, 77, 84, 79,
+  84, 80, 83, 76, 98, 76, 79, 82, 79, 76,
+  103, 84, 72, 103, 90, 87, 80, 75, 91, 82,
+  83, 81, 73, 87, 80, 80, 88, 73, 74, 78,
+  87, 82, 92, 84, 88, 125, 81, 81, 83, 76,
+  82, 89, 82, 83, 83, 83, 73, 68, 84, 76,
+  79, 91, 80, 81, 103, 83, 76, 82, 85, 76,
+  102, 94, 86, 84, 76, 67, 85, 83, 81, 72,
+  81, 76, 80, 82, 84, 82, 73, 77, 77, 83,
+  76, 76, 92, 89, 78, 77, 91, 83, 91, 84,
+  82, 87, 86, 83, 88, 79, 80, 81, 79, 83,
+  75, 89, 86, 97, 89, 79, 75, 102, 91, 84,
+  83, 85, 89, 87, 82, 85, 85, 91, 87, 87,
+  76, 79, 85, 71, 79, 72, 80, 78, 83, 85,
+  85, 79, 101, 83, 81, 83, 83, 81, 99, 91,
+  83, 100, 92, 84, 77, 76, 93, 85, 87, 78,
+  76, 86, 89, 85, 86, 79, 75, 80, 86, 86,
+  90, 88, 89, 102, 79, 88, 85, 82, 89, 98,
+  80, 85, 83, 90, 81, 76, 84, 75, 84, 88,
+  77, 79, 101, 82, 79, 79, 85, 83, 99, 94,
+  85, 88, 77, 75, 80, 83, 87, 77, 79, 80,
+  84, 86, 81, 84, 78, 81, 74, 84, 80, 82,
+  81, 84, 80, 74, 67, 90, 115, 94, 65, 87,
+  88, 84, 88, 75, 84, 81, 87, 74, 84, 89,
+  74, 88, 87, 69, 85, 96, 84, 88, 95, 95,
+  88, 84, 88, 88, 82, 80, 91, 88, 81, 75,
+  78, 75, 87, 88, 85, 84, 86, 89, 76, 73,
+  100, 71, 78, 80, 69, 75, 91, 76, 71, 121,
+  89, 78, 86, 79, 82, 79, 79, 78, 81, 77,
+  88, 75, 103, 80, 74, 77, 80, 80, 91, 101,
+  82, 171, 84, 71, 87, 78, 81, 88, 70, 70,
+  83, 83, 76, 67, 84, 87, 79, 85, 88, 91,
+  84, 91, 72, 83, 82, 77, 90, 85, 74, 78,
+  85, 70, 95, 87, 67, 63, 85, 84, 83, 82,
+  90, 74, 85, 70, 78, 81, 78, 73, 75, 87,
+  74, 78, 69, 79, 116, 83, 62, 86, 90, 87,
+  81, 79, 81, 85, 90, 75, 86, 86, 78, 84,
+  81, 70, 93, 90, 83, 91, 97, 92, 89, 84,
+  89, 85, 86, 80, 84, 86, 77, 70, 78, 75,
+  80, 85, 87, 82, 94, 84, 80, 71, 100, 67,
+  77, 79, 65, 75, 91, 73, 64, 127, 86, 80,
+  88, 73, 79, 77, 81, 81, 85, 75, 79, 75,
+  99, 76, 80, 78, 81, 85, 92, 96, 82, 180,
+  90, 75, 95, 76, 82, 84, 75, 73, 88, 77,
+  71, 67, 83, 89, 77, 83, 88, 91, 84, 74,
+  72, 86, 81, 72, 92, 86, 82, 75, 84, 66,
+  103, 80, 65, 64, 75, 87, 83, 82, 79, 75,
+  83, 70, 75, 78, 75, 72, 89, 89, 85, 79,
+  75, 86, 105, 83, 67, 89, 85, 81, 87, 82,
+  85, 87, 88, 77, 87, 84, 84, 92, 91, 77,
+  84, 96, 86, 88, 86, 85, 90, 85, 89, 82,
+  99, 86, 85, 87, 75, 73, 83, 77, 76, 80,
+  86, 83, 88, 80, 80, 75, 103, 76, 76, 79,
+  75, 80, 89, 84, 79, 106, 87, 81, 88, 75,
+  83, 82, 84, 75, 83, 85, 82, 78, 96, 80,
+  75, 76, 81, 92, 92, 100, 86, 142, 83, 84,
+  91, 83, 89, 90, 75, 79, 85, 81, 81, 69,
+  84, 86, 84, 82, 84, 89, 85, 69, 75, 82,
+  85, 83, 91, 87, 77, 84, 85, 75, 93, 81,
+  76, 75, 79, 85, 84, 87, 79, 77, 82, 74,
+  75, 80, 80, 79, 82, 77, 81, 82, 74, 90,
+  109, 96, 70, 89, 89, 78, 93, 72, 82, 83,
+  89, 72, 87, 88, 75, 90, 88, 76, 84, 91,
+  92, 89, 91, 92, 86, 77, 85, 87, 80, 79,
+  85, 90, 78, 80, 83, 74, 83, 84, 84, 88,
+  80, 87, 73, 75, 95, 74, 73, 80, 72, 76,
+  82, 79, 85, 107, 80, 78, 85, 78, 87, 84,
+  78, 73, 76, 84, 93, 80, 105, 85, 73, 77,
+  77, 82, 79, 98, 76, 139, 83, 74, 84, 81,
+  81, 91, 74, 71, 74, 89, 80, 70, 91, 83,
+  78, 82, 75, 90, 82, 94, 69, 84, 87, 83,
+  93, 76, 73, 83, 92, 76, 87, 89, 68, 68,
+  85, 84, 80, 78, 83, 79, 83, 74, 78, 89,
+  78, 80, 73, 80, 75, 83, 75, 82, 108, 90,
+  67, 89, 93, 81, 84, 79, 84, 88, 93, 72,
+  87, 83, 80, 86, 83, 76, 87, 85, 89, 92,
+  94, 85, 87, 78, 87, 87, 84, 77, 77, 92,
+  74, 76, 83, 72, 77, 86, 84, 86, 82, 85,
+  74, 74, 97, 72, 68, 80, 66, 78, 83, 76,
+  78, 109, 74, 78, 84, 74, 86, 79, 83, 74,
+  84, 84, 83, 79, 103, 84, 77, 81, 77, 85,
+  74, 96, 75, 150, 86, 78, 87, 81, 80, 87,
+  80, 72, 80, 85, 74, 73, 94, 87, 74, 82,
+  77, 91, 81, 81, 69, 85, 86, 81, 96, 77,
+  74, 79, 93, 70, 94, 81, 64, 75, 80, 84,
+  78, 74, 74, 80, 83, 74, 76, 86, 76, 77,
+  92, 85, 86, 84, 78, 89, 101, 87, 72, 90,
+  85, 79, 91, 85, 83, 87, 90, 71, 87, 84,
+  86, 96, 91, 80, 77, 89, 90, 87, 83, 78,
+  91, 81, 87, 83, 96, 88, 83, 91, 75, 78,
+  87, 75, 78, 80, 85, 86, 80, 83, 78, 77,
+  99, 80, 70, 81, 78, 81, 83, 87, 90, 96,
+  80, 81, 88, 76, 89, 87, 81, 75, 80, 91,
+  82, 79, 94, 83, 71, 78, 79, 88, 82, 98,
+  79, 119, 84, 83, 86, 87, 87, 91, 76, 76,
+  75, 80, 84, 72, 91, 81, 82, 80, 78, 87,
+  83, 73, 74, 82, 88, 88, 92, 80, 76, 83,
+  95, 80, 83, 81, 80, 82, 86, 85, 81, 83,
+  81, 82, 81, 75, 76, 90, 80, 85, 79, 83,
+  99, 85, 77, 94, 79, 72, 84, 100, 83, 80,
+  79, 72, 89, 92, 79, 96, 67, 82, 76, 85,
+  85, 97, 81, 77, 80, 78, 87, 91, 85, 92,
+  75, 86, 95, 94, 95, 88, 81, 93, 74, 91,
+  78, 76, 84, 69, 86, 67, 64, 84, 82, 78,
+  101, 76, 83, 83, 87, 86, 62, 97, 88, 96,
+  78, 83, 94, 83, 80, 82, 86, 92, 80, 93,
+  88, 93, 85, 87, 95, 97, 78, 86, 91, 84,
+  76, 85, 66, 90, 85, 69, 86, 76, 80, 84,
+  104, 90, 81, 77, 86, 75, 80, 78, 78, 97,
+  85, 87, 87, 91, 78, 85, 69, 109, 76, 93,
+  78, 88, 86, 91, 77, 68, 91, 85, 85, 85,
+  67, 81, 77, 98, 84, 79, 87, 79, 89, 89,
+  80, 85, 87, 70, 79, 108, 79, 78, 90, 76,
+  92, 81, 84, 103, 66, 72, 82, 78, 77, 93,
+  84, 81, 78, 71, 102, 89, 93, 83, 68, 91,
+  96, 82, 89, 81, 76, 95, 72, 96, 79, 83,
+  81, 74, 103, 77, 62, 83, 78, 79, 109, 68,
+  83, 84, 87, 81, 63, 94, 91, 96, 75, 94,
+  83, 79, 80, 84, 87, 90, 87, 93, 82, 90,
+  88, 83, 90, 87, 83, 84, 87, 84, 79, 78,
+  70, 78, 86, 76, 74, 89, 69, 80, 95, 97,
+  83, 84, 79, 73, 91, 65, 73, 89, 81, 85,
+  75, 86, 84, 82, 66, 102, 73, 95, 85, 88,
+  80, 92, 83, 73, 94, 75, 83, 86, 67, 85,
+  81, 105, 81, 72, 76, 75, 80, 90, 84, 88,
+  82, 72, 91, 100, 87, 77, 84, 79, 83, 91,
+  82, 97, 72, 77, 78, 83, 88, 96, 79, 75,
+  74, 83, 85, 91, 90, 82, 73, 95, 96, 79,
+  96, 93, 72, 90, 79, 93, 78, 78, 87, 76,
+  89, 94, 64, 81, 84, 80, 102, 82, 81, 86,
+  89, 82, 63, 98, 84, 93, 79, 85, 92, 82,
+  80, 86, 87, 88, 81, 93, 89, 85, 87, 93,
+  100, 88, 84, 85, 87, 83, 71, 76, 68, 80,
+  86, 77, 85, 76, 77, 94, 100, 96, 95, 79,
+  87, 75, 80, 76, 82, 92, 82, 85, 86, 91,
+  76, 88, 68, 97, 74, 92, 78, 93, 81, 88,
+  90, 69, 90, 81, 80, 85, 70, 82, 81, 93,
+  83, 82, 86, 79, 89, 73, 80, 94, 88, 76,
+  81, 96, 83, 77, 81, 76, 91, 90, 82, 91,
+  52, 82, 72, 79, 80, 97, 79, 85, 75, 69,
+  103, 88, 94, 94, 68, 91, 90, 98, 91, 73,
+  80, 83, 77, 88, 91, 77, 82, 71, 79, 72,
+  66, 73, 79, 80, 100, 70, 88, 80, 92, 86,
+  71, 105, 87, 92, 85, 79, 89, 71, 81, 82,
+  72, 89, 86, 93, 93, 95, 84, 89, 79, 83,
+  77, 81, 88, 83, 73, 88, 74, 90, 91, 74,
+  80, 77, 75, 84, 108, 95, 74, 83, 81, 79,
+  73, 63, 68, 98, 83, 93, 70, 86, 79, 86,
+  85, 115, 80, 84, 84, 81, 85, 88, 75, 67,
+  97, 80, 83, 82, 68, 93, 74, 88, 84, 69,
+  93, 79, 68, 75, 79, 74, 95, 73, 83, 108,
+  83, 77, 92, 75, 104, 91, 93, 96, 48, 70,
+  83, 69, 82, 92, 88, 87, 70, 66, 112, 91,
+  101, 78, 71, 91, 94, 82, 79, 63, 75, 93,
+  72, 86, 80, 76, 79, 68, 98, 72, 60, 84,
+  75, 73, 104, 64, 85, 73, 90, 88, 72, 110,
+  86, 88, 82, 93, 75, 71, 86, 96, 68, 78,
+  72, 99, 98, 96, 84, 94, 78, 81, 75, 81,
+  95, 81, 69, 84, 71, 84, 84, 78, 73, 95,
+  67, 75, 98, 91, 78, 87, 73, 78, 93, 47,
+  66, 85, 77, 91, 55, 80, 90, 80, 84, 134,
+  79, 89, 93, 85, 68, 92, 79, 68, 107, 70,
+  84, 82, 76, 109, 81, 89, 83, 69, 88, 76,
+  76, 79, 82, 75, 87, 73, 86, 96, 84, 75,
+  80, 86, 90, 92, 85, 89, 57, 80, 90, 79,
+  94, 92, 77, 80, 71, 74, 99, 97, 91, 82,
+  67, 88, 93, 86, 85, 78, 80, 85, 81, 86,
+  69, 78, 81, 73, 82, 85, 67, 71, 83, 80,
+  95, 74, 83, 83, 93, 83, 74, 103, 80, 92,
+  92, 79, 97, 76, 84, 92, 75, 88, 86, 92,
+  94, 82, 85, 89, 86, 92, 82, 81, 81, 78,
+  74, 80, 77, 86, 83, 80, 80, 81, 72, 81,
+  93, 95, 88, 86, 81, 80, 86, 63, 74, 88,
+  81, 90, 68, 91, 77, 89, 82, 104, 80, 89,
+  84, 99, 78, 90, 98, 67, 96, 77, 80, 81,
+  66, 86, 81, 87, 84, 72, 81, 84, 78, 70,
+  95, 91, 81, 74, 83, 89, 85, 78, 87, 81,
+  83, 83, 76, 90, 70, 86, 75, 85, 80, 102,
+  84, 83, 84, 73, 84, 89, 84, 95, 73, 90,
+  92, 93, 91, 70, 76, 91, 91, 79, 100, 83,
+  80, 80, 82, 76, 70, 82, 74, 82, 100, 79,
+  84, 86, 95, 80, 67, 93, 87, 99, 92, 84,
+  90, 78, 86, 81, 69, 84, 86, 87, 100, 102,
+  88, 83, 86, 85, 93, 74, 89, 83, 80, 88,
+  70, 88, 88, 76, 94, 78, 76, 91, 97, 94,
+  71, 89, 90, 73, 72, 66, 74, 98, 91, 90,
+  81, 80, 83, 93, 96, 112, 86, 93, 78, 78,
+  76, 89, 81, 67, 91, 92, 81, 82, 67, 88,
+  78, 91, 86, 82, 95, 79, 70, 67, 86, 75,
+  81, 69, 82, 100, 83, 74, 91, 78, 92, 85,
+  76, 90, 57, 79, 82, 77, 82, 97, 83, 84,
+  76, 69, 94, 95, 89, 89, 74, 93, 85, 84,
+  83, 57, 77, 94, 101, 76, 94, 80, 86, 72,
+  84, 79, 70, 87, 72, 78, 101, 71, 79, 83,
+  89, 82, 70, 99, 83, 88, 97, 95, 82, 77,
+  86, 85, 62, 82, 79, 94, 100, 107, 85, 86,
+  85, 83, 85, 70, 99, 76, 72, 85, 72, 88,
+  84, 82, 84, 86, 70, 80, 104, 89, 74, 90,
+  82, 75, 82, 52, 71, 98, 89, 89, 74, 79,
+  85, 84, 88, 123, 93, 94, 82, 83, 74, 87,
+  91, 72, 93, 83, 82, 82, 67, 100, 81, 90,
+  82, 75, 88, 76, 70, 74, 89, 82, 78, 71,
+  87, 91, 85, 78, 86, 80, 81, 84, 72, 86,
+  74, 86, 89, 85, 95, 99, 77, 74, 75, 75,
+  79, 104, 88, 97, 73, 84, 84, 84, 83, 69,
+  86, 92, 101, 77, 70, 80, 79, 79, 83, 89,
+  70, 83, 79, 91, 94, 83, 79, 78, 90, 81,
+  73, 88, 79, 98, 96, 85, 94, 82, 89, 87,
+  68, 84, 78, 86, 93, 93, 87, 87, 89, 87,
+  89, 70, 88, 78, 80, 77, 74, 89, 79, 85,
+  96, 81, 76, 78, 94, 86, 84, 82, 89, 72,
+  81, 66, 74, 98, 90, 87, 77, 85, 76, 94,
+  91, 107, 92, 88, 78, 91, 85, 90, 101, 65,
+  89, 87, 91, 84, 66, 83, 85, 90, 86, 82,
+  84, 82, 84, 79, 93, 86, 91, 77, 72, 83,
+  74, 104, 81, 92, 88, 94, 89, 75, 80, 86,
+  92, 74, 78, 85, 95, 73, 102, 75, 105, 86,
+  95, 69, 77, 95, 85, 99, 82, 69, 92, 87,
+  82, 76, 78, 88, 78, 97, 78, 80, 86, 79,
+  78, 75, 91, 76, 95, 94, 77, 77, 76, 91,
+  89, 90, 105, 75, 73, 67, 85, 83, 87, 75,
+  93, 81, 83, 92, 86, 67, 82, 83, 89, 74,
+  93, 90, 97, 76, 75, 112, 88, 75, 83, 87,
+  78, 84, 79, 97, 76, 74, 85, 82, 74, 84,
+  57, 92, 75, 72, 86, 72, 84, 80, 84, 68,
+  86, 94, 72, 81, 89, 94, 73, 90, 79, 76,
+  99, 77, 74, 68, 77, 77, 77, 89, 72, 83,
+  59, 81, 98, 77, 86, 68, 66, 76, 72, 88,
+  76, 103, 88, 95, 83, 84, 74, 76, 86, 71,
+  70, 82, 98, 80, 87, 67, 101, 92, 96, 68,
+  82, 98, 90, 76, 81, 68, 78, 92, 82, 73,
+  88, 89, 84, 86, 75, 87, 83, 84, 83, 82,
+  95, 95, 91, 86, 77, 74, 84, 92, 93, 93,
+  96, 81, 69, 74, 86, 87, 90, 68, 74, 65,
+  82, 81, 88, 76, 79, 82, 89, 78, 91, 94,
+  95, 68, 85, 110, 92, 69, 90, 94, 81, 85,
+  74, 103, 72, 84, 86, 94, 76, 87, 61, 82,
+  63, 74, 87, 71, 80, 75, 88, 75, 91, 89,
+  70, 80, 82, 78, 75, 87, 72, 83, 99, 75,
+  67, 58, 78, 67, 74, 93, 75, 84, 71, 95,
+  87, 80, 83, 70, 77, 79, 76, 94, 77, 101,
+  86, 88, 92, 85, 78, 80, 80, 83, 74, 74,
+  99, 84, 89, 73, 93, 94, 96, 76, 90, 91,
+  88, 74, 86, 82, 75, 86, 86, 90, 79, 96,
+  85, 81, 74, 100, 78, 84, 84, 84, 98, 98,
+  98, 82, 78, 75, 92, 79, 90, 90, 93, 76,
+  81, 82, 91, 87, 92, 83, 77, 72, 81, 76,
+  91, 74, 86, 76, 75, 82, 95, 92, 91, 76,
+  86, 107, 96, 80, 82, 91, 83, 88, 77, 104,
+  75, 89, 94, 94, 87, 97, 67, 82, 70, 77,
+  90, 78, 83, 81, 87, 72, 88, 89, 71, 74,
+  89, 79, 88, 84, 77, 76, 98, 78, 73, 63,
+  81, 63, 77, 92, 87, 85, 87, 84, 84, 86,
+  69, 86, 83, 94, 80, 97, 81, 69, 67, 89,
+  90, 77, 92, 97, 85, 80, 81, 85, 74, 67,
+  107, 95, 100, 78, 98, 74, 73, 88, 80, 100,
+  79, 71, 83, 77, 87, 69, 71, 73, 71, 90,
+  76, 85, 97, 79, 79, 73, 81, 72, 97, 88,
+  81, 76, 77, 87, 77, 88, 94, 76, 78, 67,
+  89, 85, 75, 93, 77, 78, 84, 99, 93, 83,
+  89, 78, 84, 68, 83, 77, 81, 81, 69, 92,
+  85, 80, 69, 74, 79, 92, 76, 88, 82, 73,
+  88, 76, 74, 84, 62, 122, 86, 79, 94, 85,
+  87, 91, 78, 74, 70, 81, 94, 86, 104, 96,
+  83, 96, 91, 63, 86, 84, 67, 91, 83, 92,
+  80, 85, 80, 86, 62, 76, 92, 79, 65, 73,
+  62, 82, 76, 85, 84, 78, 80, 95, 81, 78,
+  82, 81, 87, 66, 66, 86, 83, 65, 109, 78,
+  104, 76, 104, 71, 72, 88, 82, 92, 73, 61,
+  79, 80, 82, 64, 98, 76, 71, 107, 71, 86,
+  93, 80, 81, 74, 87, 74, 85, 96, 77, 71,
+  77, 87, 74, 92, 87, 75, 75, 60, 98, 81,
+  74, 67, 89, 68, 81, 104, 83, 73, 82, 85,
+  91, 75, 87, 87, 99, 75, 72, 95, 90, 64,
+  76, 82, 67, 89, 67, 105, 75, 74, 75, 80,
+  69, 81, 56, 110, 73, 77, 92, 79, 79, 78,
+  74, 75, 80, 89, 85, 82, 89, 88, 73, 87,
+  80, 73, 85, 86, 64, 71, 79, 91, 75, 87,
+  74, 86, 64, 89, 82, 74, 72, 69, 70, 83,
+  79, 86, 86, 91, 79, 100, 80, 83, 89, 83,
+  88, 76, 80, 91, 97, 72, 109, 76, 90, 85,
+  102, 73, 86, 93, 83, 88, 70, 69, 77, 82,
+  79, 76, 91, 84, 76, 90, 72, 89, 91, 86,
+  87, 77, 99, 80, 81, 86, 78, 73, 77, 85,
+  78, 89, 84, 74, 79, 65, 116, 79, 75, 78,
+  71, 72, 79, 89, 83, 75, 85, 90, 86, 81,
+  94, 91, 105, 89, 81, 93, 95, 71, 77, 90,
+  75, 82, 74, 107, 71, 79, 80, 80, 70, 87,
+  60, 80, 66, 79, 91, 75, 77, 82, 80, 79,
+  79, 93, 80, 85, 91, 87, 93, 82, 74, 72,
+  78, 82, 63, 62, 82, 85, 76, 89, 85, 88,
+  92, 79, 64, 87, 77, 90, 93, 77, 91, 90,
+  90, 61, 60, 70, 83, 86, 110, 97, 75, 97,
+  96, 82, 72, 83, 86, 106, 79, 78, 83, 86,
+  83, 79, 88, 106, 83, 84, 82, 87, 99, 72,
+  74, 86, 78, 87, 79, 77, 92, 81, 96, 84,
+  79, 78, 94, 77, 90, 94, 80, 84, 64, 72,
+  93, 85, 87, 98, 75, 94, 85, 97, 71, 92,
+  91, 87, 96, 102, 73, 77, 81, 79, 71, 86,
+  64, 94, 92, 95, 90, 97, 84, 75, 98, 79,
+  92, 74, 86, 79, 86, 90, 76, 80, 86, 92,
+  76, 85, 92, 93, 102, 105, 92, 103, 75, 76,
+  101, 79, 86, 91, 111, 94, 83, 76, 90, 87,
+  83, 99, 112, 73, 79, 89, 91, 95, 89, 74,
+  74, 87, 72, 88, 82, 82, 92, 87, 86, 74,
+  67, 77, 86, 84, 104, 93, 83, 101, 92, 80,
+  66, 67, 90, 100, 95, 83, 92, 98, 78, 80,
+  84, 121, 76, 84, 71, 82, 98, 60, 94, 82,
+  78, 93, 73, 87, 84, 75, 91, 79, 82, 82,
+  88, 83, 94, 91, 74, 76, 67, 83, 87, 87,
+  83, 95, 76, 92, 75, 78, 87, 88, 92, 100,
+  84, 99, 79, 87, 82, 69, 76, 80, 75, 91,
+  88, 103, 86, 89, 77, 74, 86, 71, 83, 83,
+  86, 90, 85, 93, 66, 79, 73, 111, 95, 78,
+  95, 85, 102, 94, 78, 93, 82, 83, 101, 78,
+  83, 94, 103, 95, 92, 91, 89, 92, 77, 94,
+  103, 74, 91, 83, 92, 97, 76, 84, 77, 83,
+  77, 76, 75, 81, 88, 79, 97, 78, 71, 81,
+  78, 78, 102, 90, 86, 96, 88, 92, 83, 71,
+  97, 85, 85, 89, 91, 91, 83, 89, 83, 114,
+  70, 82, 80, 91, 84, 66, 94, 81, 72, 95,
+  73, 89, 90, 83, 92, 80, 95, 81, 81, 90,
+  99, 83, 73, 79, 74, 84, 88, 88, 86, 92,
+  91, 82, 78, 79, 89, 92, 93, 97, 77, 94,
+  83, 85, 85, 74, 85, 80, 89, 103, 90, 99,
+  88, 86, 81, 86, 79, 74, 79, 99, 81, 87,
+  79, 88, 67, 82, 70, 100, 77, 77, 92, 89,
+  83, 92, 76, 96, 77, 93, 87, 86, 80, 91,
+  102, 86, 88, 87, 84, 92, 76, 73, 97, 80,
+  89, 76, 69, 101, 71, 96, 91, 77, 77, 75,
+  94, 84, 92, 86, 76, 96, 81, 100, 77, 85,
+  107, 86, 81, 81, 96, 91, 85, 75, 86, 87,
+  85, 77, 86, 101, 92, 90, 77, 80, 83, 88,
+  84, 64, 95, 74, 88, 94, 86, 95, 84, 83,
+  74, 80, 82, 80, 84, 102, 95, 87, 90, 75,
+  80, 92, 94, 94, 89, 83, 76, 79, 75, 86,
+  81, 90, 83, 72, 87, 90, 73, 95, 102, 74,
+  92, 82, 93, 90, 84, 97, 72, 83, 100, 74,
+  74, 89, 78, 100, 85, 72, 82, 87, 97, 75,
+  80, 91, 76, 99, 86, 84, 107, 73, 99, 84,
+  92, 84, 74, 90, 98, 69, 90, 106, 75, 88,
+  78, 107, 83, 96, 87, 87, 80, 97, 87, 87,
+  70, 93, 71, 87, 79, 85, 81, 80, 79, 84,
+  83, 95, 88, 75, 81, 91, 76, 74, 83, 79,
+  70, 89, 72, 85, 86, 85, 73, 78, 90, 86,
+  81, 99, 76, 106, 75, 91, 82, 80, 81, 93,
+  80, 87, 91, 92, 85, 73, 89, 95, 84, 85,
+  81, 86, 84, 84, 79, 96, 83, 79, 86, 89,
+  88, 86, 81, 79, 72, 85, 71, 84, 77, 79,
+  83, 83, 74, 75, 78, 82, 84, 73, 85, 86,
+  89, 89, 73, 94, 87, 77, 97, 84, 76, 85,
+  80, 86, 88, 78, 78, 87, 89, 80, 79, 76,
+  75, 97, 76, 88, 81, 80, 79, 87, 68, 77,
+  76, 82, 77, 83, 77, 78, 64, 87, 84, 81,
+  74, 86, 78, 83, 78, 82, 79, 71, 89, 83,
+  74, 82, 84, 80, 78, 88, 73, 84, 79, 92,
+  97, 84, 83, 74, 83, 71, 70, 72, 83, 81,
+  75, 83, 82, 95, 70, 82, 89, 96, 88, 83,
+  75, 92, 87, 96, 91, 77, 77, 95, 71, 95,
+  72, 85, 91, 77, 83, 92, 84, 91, 73, 84,
+  88, 73, 82, 86, 81, 96, 88, 78, 83, 77,
+  82, 81, 84, 88, 85, 87, 81, 88, 76, 85,
+  92, 76, 89, 75, 78, 87, 78, 100, 82, 85,
+  82, 94, 92, 74, 92, 91, 85, 85, 88, 85,
+  83, 87, 84, 75, 79, 89, 82, 78, 83, 84,
+  80, 88, 75, 83, 68, 89, 68, 82, 78, 81,
+  73, 79, 81, 78, 81, 85, 86, 71, 84, 77,
+  77, 86, 77, 87, 80, 78, 77, 100, 78, 111,
+  96, 85, 71, 84, 113, 105, 96, 80, 76, 92,
+  85, 98, 90, 94, 119, 87, 75, 92, 87, 84,
+  88, 68, 97, 101, 94, 87, 71, 107, 103, 74,
+  88, 84, 84, 124, 94, 54, 71, 85, 94, 91,
+  81, 106, 93, 70, 79, 81, 76, 90, 85, 102,
+  103, 83, 97, 59, 75, 80, 73, 92, 82, 77,
+  74, 75, 71, 82, 96, 93, 78, 71, 107, 86,
+  81, 94, 121, 80, 82, 83, 89, 87, 99, 114,
+  64, 76, 98, 78, 74, 81, 87, 79, 76, 82,
+  92, 83, 111, 77, 88, 84, 79, 74, 103, 85,
+  105, 89, 99, 86, 88, 84, 82, 96, 103, 66,
+  82, 95, 86, 97, 76, 99, 83, 96, 87, 99,
+  76, 78, 92, 83, 74, 88, 103, 85, 81, 94,
+  80, 80, 80, 92, 81, 88, 87, 86, 81, 82,
+  79, 80, 79, 81, 67, 93, 75, 82, 88, 86,
+  75, 77, 95, 93, 79, 102, 78, 98, 68, 87,
+  81, 84, 84, 92, 76, 88, 94, 95, 76, 83,
+  83, 85, 89, 87, 77, 99, 83, 81, 77, 82,
+  80, 69, 93, 89, 81, 79, 77, 60, 73, 76,
+  80, 80, 82, 84, 72, 89, 75, 79, 79, 84,
+  89, 75, 72, 91, 87, 87, 79, 120, 85, 77,
+  107, 92, 73, 83, 77, 74, 88, 87, 69, 89,
+  82, 84, 69, 69, 76, 75, 81, 89, 76, 83,
+  83, 87, 71, 76, 86, 80, 74, 86, 80, 73,
+  83, 90, 81, 78, 79, 86, 76, 89, 85, 77,
+  80, 66, 86, 81, 83, 76, 83, 78, 84, 76,
+  71, 87, 77, 85, 96, 80, 84, 72, 81, 69,
+  65, 77, 86, 74, 82, 86, 86, 101, 69, 79,
+  91, 88, 94, 80, 77, 100, 83, 93, 85, 67,
+  81, 101, 79, 95, 79, 90, 93, 78, 74, 89,
+  88, 94, 73, 84, 90, 73, 81, 81, 79, 95,
+  94, 82, 95, 78, 81, 75, 77, 84, 91, 87,
+  79, 78, 75, 93, 84, 79, 84, 81, 75, 87,
+  74, 106, 86, 80, 87, 94, 91, 75, 99, 91,
+  87, 89, 88, 77, 88, 86, 79, 87, 70, 95,
+  77, 77, 77, 80, 77, 91, 71, 74, 75, 91,
+  75, 87, 88, 80, 66, 77, 83, 74, 84, 86,
+  88, 74, 82, 85, 79, 88, 87, 84, 80, 77,
+  88, 92, 81, 95, 86, 70, 81, 84, 84, 76,
+  88, 69, 72, 93, 74, 83, 79, 82, 93, 85,
+  74, 80, 89, 81, 76, 85, 90, 87, 85, 91,
+  86, 95, 91, 88, 75, 88, 89, 89, 100, 71,
+  73, 73, 83, 85, 72, 82, 94, 74, 94, 76,
+  73, 88, 83, 93, 88, 92, 98, 81, 73, 83,
+  75, 85, 93, 79, 80, 74, 77, 85, 99, 95,
+  73, 73, 102, 86, 89, 83, 78, 72, 105, 79,
+  88, 97, 84, 112, 92, 87, 98, 83, 89, 78,
+  88, 78, 95, 83, 84, 84, 93, 81, 90, 76,
+  81, 87, 77, 83, 72, 89, 83, 84, 85, 92,
+  88, 90, 79, 67, 99, 92, 81, 84, 73, 83,
+  81, 89, 82, 84, 77, 106, 82, 75, 85, 86,
+  90, 75, 77, 75, 81, 79, 74, 81, 79, 83,
+  87, 75, 77, 75, 78, 73, 67, 75, 79, 82,
+  78, 84, 82, 93, 77, 80, 86, 86, 97, 87,
+  77, 97, 70, 77, 82, 72, 85, 95, 83, 84,
+  79, 92, 80, 77, 81, 84, 91, 89, 77, 91,
+  87, 76, 79, 84, 79, 84, 90, 95, 94, 76,
+  81, 78, 77, 82, 90, 86, 89, 83, 71, 84,
+  77, 86, 85, 78, 76, 79, 78, 91, 88, 90,
+  77, 97, 90, 85, 85, 92, 90, 81, 80, 79,
+  98, 88, 69, 88, 79, 93, 70, 70, 76, 81,
+  75, 87, 76, 81, 85, 89, 80, 86, 87, 85,
+  67, 80, 88, 79, 70, 88, 84, 79, 83, 88,
+  76, 83, 85, 91, 80, 78, 86, 81, 75, 80,
+  79, 76, 74, 82, 78, 95, 80, 84, 91, 75,
+  85, 75, 81, 71, 70, 78, 89, 82, 84, 91,
+  82, 94, 78, 87, 82, 80, 91, 81, 82, 96,
+  82, 87, 83, 80, 79, 95, 87, 97, 76, 87,
+  87, 77, 72, 97, 84, 93, 75, 82, 93, 80,
+  89, 84, 82, 92, 92, 88, 102, 83, 79, 84,
+  86, 88, 91, 83, 87, 85, 77, 87, 90, 84,
+  86, 80, 81, 92, 69, 102, 87, 81, 84, 87,
+  83, 81, 80, 88, 93, 89, 90, 83, 85, 87,
+  88, 81, 83, 93, 80, 81, 84, 84, 86, 88,
+  81, 79, 80, 91, 84, 87, 88, 85, 73, 79,
+  85, 75, 81, 90, 89, 80, 82, 82, 84, 86,
+  80, 75, 88, 87, 95, 74, 84, 94, 87, 89,
+  84, 80, 74, 82, 84, 79, 96, 82, 78, 73,
+  85, 83, 83, 72, 83, 81, 72, 86, 97, 86,
+  73, 102, 87, 84, 79, 80, 94, 91, 96, 85,
+  82, 68, 80, 76, 82, 77, 71, 75, 89, 80,
+  74, 86, 73, 92, 73, 89, 79, 84, 87, 85,
+  75, 84, 90, 96, 71, 77, 88, 72, 77, 80,
+  88, 91, 81, 88, 71, 91, 88, 80, 80, 89,
+  87, 86, 82, 85, 73, 70, 99, 103, 79, 81,
+  80, 79, 75, 89, 100, 79, 94, 86, 66, 89,
+  84, 81, 79, 93, 83, 79, 94, 77, 91, 97,
+  90, 82, 76, 82, 76, 85, 79, 89, 72, 91,
+  77, 113, 105, 85, 84, 81, 81, 75, 82, 82,
+  82, 82, 85, 84, 77, 88, 89, 77, 78, 71,
+  71, 80, 72, 77, 93, 82, 83, 73, 85, 81,
+  67, 67, 72, 72, 77, 97, 87, 85, 70, 104,
+  87, 89, 74, 76, 93, 83, 87, 70, 74, 91,
+  81, 68, 75, 76, 73, 78, 86, 73, 61, 91,
+  66, 97, 66, 92, 69, 79, 83, 75, 68, 79,
+  82, 112, 76, 83, 75, 93, 77, 76, 96, 104,
+  85, 101, 74, 98, 80, 81, 92, 85, 83, 81,
+  88, 75, 71, 66, 94, 84, 89, 88, 76, 91,
+  72, 96, 85, 83, 95, 93, 67, 96, 86, 78,
+  81, 98, 91, 104, 95, 76, 115, 91, 82, 80,
+  78, 84, 74, 95, 71, 75, 76, 106, 66, 128,
+  134, 84, 84, 86, 70, 61, 85, 81, 98, 78,
+  95, 93, 78, 90, 86, 77, 78, 85, 76, 86,
+  82, 79, 80, 83, 74, 74, 87, 81, 79, 69,
+  76, 81, 83, 83, 88, 87, 74, 104, 86, 94,
+  81, 80, 98, 82, 83, 74, 72, 73, 78, 73,
+  82, 78, 77, 79, 83, 77, 71, 99, 73, 88,
+  75, 91, 77, 81, 86, 77, 78, 81, 81, 93,
+  73, 84, 87, 73, 75, 79, 75, 99, 86, 79,
+  74, 92, 91, 78, 96, 93, 86, 95, 80, 82,
+  75, 72, 97, 70, 81, 85, 95, 83, 74, 86,
+  98, 80, 92, 88, 84, 89, 83, 83, 84, 92,
+  87, 88, 94, 74, 90, 96, 88, 78, 76, 81,
+  79, 84, 80, 79, 81, 88, 75, 111, 109, 80,
+  84, 78, 79, 78, 83, 73, 86, 83, 89, 74,
+  84, 93, 81, 91, 86, 76, 71, 80, 83, 89,
+  83, 72, 84, 80, 86, 92, 82, 80, 79, 68,
+  79, 86, 95, 84, 73, 101, 88, 76, 84, 81,
+  87, 89, 103, 91, 86, 85, 79, 73, 99, 79,
+  90, 76, 89, 83, 78, 85, 79, 90, 75, 86,
+  77, 87, 80, 90, 81, 88, 93, 95, 80, 77,
+  89, 74, 89, 78, 78, 91, 79, 100, 77, 97,
+  80, 78, 83, 87, 93, 83, 80, 80, 70, 72,
+  91, 99, 74, 85, 77, 78, 74, 86, 89, 76,
+  94, 84, 72, 95, 87, 80, 66, 89, 80, 78,
+  86, 81, 94, 85, 85, 84, 76, 79, 78, 81,
+  75, 100, 83, 79, 62, 125, 98, 83, 76, 79,
+  79, 67, 82, 79, 84, 77, 77, 78, 75, 79,
+  75, 91, 82, 69, 69, 75, 75, 94, 75, 74,
+  90, 89, 90, 86, 67, 78, 78, 55, 90, 90,
+  76, 83, 68, 104, 86, 90, 80, 69, 79, 87,
+  92, 75, 71, 126, 75, 66, 103, 78, 84, 75,
+  91, 77, 67, 88, 79, 95, 70, 88, 67, 83,
+  66, 81, 78, 87, 91, 120, 79, 78, 73, 85,
+  87, 68, 71, 109, 76, 90, 72, 118, 71, 70,
+  101, 92, 94, 79, 82, 76, 67, 74, 80, 80,
+  88, 94, 83, 84, 74, 95, 79, 77, 101, 84,
+  67, 109, 88, 76, 75, 85, 81, 77, 78, 81,
+  119, 84, 76, 82, 73, 86, 83, 84, 73, 81,
+  87, 91, 65, 149, 119, 81, 76, 87, 68, 56,
+  83, 78, 93, 73, 91, 83, 81, 88, 80, 79,
+  81, 78, 74, 79, 82, 91, 73, 85, 81, 79,
+  89, 91, 77, 74, 94, 73, 89, 84, 81, 85,
+  74, 102, 86, 101, 85, 73, 86, 83, 86, 70,
+  81, 92, 77, 71, 104, 84, 80, 79, 86, 83,
+  75, 90, 78, 88, 77, 93, 73, 86, 82, 81,
+  81, 85, 88, 93, 81, 80, 87, 72, 90, 79,
+  73, 96, 79, 91, 75, 99, 87, 77, 100, 91,
+  93, 96, 76, 86, 71, 72, 91, 69, 78, 92,
+  105, 79, 75, 83, 85, 78, 95, 83, 86, 96,
+  86, 82, 85, 90, 83, 73, 85, 77, 88, 89,
+  82, 77, 75, 81, 88, 81, 77, 76, 86, 89,
+  79, 122, 103, 81, 81, 77, 75, 72, 83, 76,
+  87, 81, 89, 73, 76, 84, 78, 81, 88, 83,
+  75, 90, 80, 88, 81, 80, 80, 81, 82, 83,
+  92, 70, 84, 81, 80, 90, 96, 83, 80, 94,
+  87, 76, 83, 86, 83, 89, 98, 76, 77, 91,
+  94, 73, 93, 78, 86, 81, 88, 83, 97, 81,
+  79, 83, 80, 82, 75, 92, 76, 91, 84, 84,
+  88, 83, 85, 84, 95, 78, 83, 77, 79, 81,
+  79, 99, 77, 79, 95, 81, 85, 81, 100, 83,
+  81, 75, 74, 89, 89, 83, 76, 88, 77, 83,
+  80, 72, 89, 75, 94, 81, 76, 90, 82, 82,
+  72, 90, 73, 76, 81, 80, 82, 88, 81, 86,
+  81, 78, 79, 81, 79, 96, 81, 90, 73, 109,
+  97, 89, 73, 76, 80, 70, 81, 82, 86, 90,
+  81, 75, 74, 82, 74, 83, 90, 75, 74, 92,
+  78, 87, 72, 85, 81, 89, 78, 78, 81, 73,
+  87, 64, 88, 90, 78, 78, 80, 101, 86, 93,
+  80, 76, 83, 85, 97, 71, 70, 110, 84, 68,
+  101, 77, 89, 78, 95, 83, 90, 81, 83, 86,
+  82, 83, 72, 89, 71, 84, 85, 82, 89, 90,
+  79, 81, 89, 83, 87, 71, 69, 78, 74, 87,
+  76, 94, 90, 78, 88, 87, 96, 80, 78, 72,
+  73, 94, 84, 76, 77, 88, 81, 82, 81, 77,
+  88, 72, 103, 75, 74, 90, 87, 85, 76, 91,
+  75, 78, 82, 82, 87, 84, 76, 89, 79, 79,
+  86, 80, 78, 80, 87, 87, 72, 128, 100, 91,
+  76, 74, 72, 72, 82, 79, 86, 88, 87, 81,
+  79, 84, 84, 73, 87, 80, 78, 88, 81, 88,
+  73, 95, 79, 84, 83, 84, 89, 73, 93, 74,
+  84, 88, 82, 82, 83, 97, 84, 99, 85, 83,
+  86, 81, 86, 74, 80, 92, 79, 74, 96, 79,
+  85, 83, 86, 92, 92, 85, 80, 83, 82, 85,
+  75, 91, 79, 79, 79, 84, 81, 84, 87, 86,
+  91, 76, 85, 78, 78, 83, 77, 82, 78, 80,
+  95, 81, 90, 80, 98, 82, 71, 78, 74, 87,
+  91, 72, 77, 90, 97, 77, 79, 73, 88, 78,
+  94, 80, 86, 91, 81, 84, 86, 95, 76, 86,
+  82, 80, 77, 85, 80, 87, 82, 80, 90, 82,
+  79, 77, 85, 88, 71, 108, 97, 89, 75, 75,
+  78, 73, 82, 81, 88, 93, 76, 85, 86, 75,
+  68, 82, 72, 80, 68, 83, 79, 76, 68, 85,
+  62, 94, 89, 83, 98, 109, 62, 68, 99, 101,
+  74, 94, 78, 69, 105, 78, 84, 81, 68, 76,
+  80, 95, 74, 92, 74, 77, 93, 78, 67, 72,
+  92, 97, 90, 78, 97, 81, 71, 78, 76, 77,
+  103, 55, 127, 74, 74, 87, 80, 94, 100, 59,
+  69, 72, 80, 79, 90, 85, 95, 81, 103, 82,
+  89, 99, 72, 90, 71, 79, 86, 92, 93, 97,
+  73, 94, 76, 81, 93, 87, 109, 69, 84, 94,
+  105, 78, 89, 80, 77, 94, 85, 55, 82, 93,
+  88, 79, 96, 69, 84, 74, 85, 83, 75, 92,
+  75, 86, 79, 80, 82, 80, 63, 84, 84, 75,
+  102, 88, 81, 74, 83, 63, 101, 85, 85, 98,
+  69, 77, 83, 97, 75, 78, 99, 83, 68, 82,
+  66, 71, 83, 98, 84, 77, 95, 94, 90, 90,
+  83, 81, 123, 98, 72, 82, 49, 82, 90, 86,
+  82, 77, 75, 81, 89, 81, 89, 60, 87, 129,
+  71, 109, 93, 88, 77, 92, 88, 68, 84, 88,
+  69, 57, 66, 92, 93, 90, 85, 57, 58, 62,
+  72, 73, 81, 91, 87, 97, 79, 80, 78, 68,
+  78, 104, 79, 74, 78, 70, 101, 94, 72, 90,
+  100, 111, 55, 88, 72, 79, 85, 98, 87, 73,
+  87, 74, 91, 71, 86, 59, 94, 84, 83, 75,
+  84, 80, 73, 75, 88, 96, 68, 91, 64, 92,
+  106, 79, 67, 70, 82, 83, 82, 78, 76, 84,
+  77, 81, 88, 69, 71, 92, 78, 77, 81, 79,
+  83, 90, 91, 101, 101, 85, 91, 86, 81, 73,
+  87, 87, 101, 77, 76, 88, 91, 90, 89, 79,
+  78, 101, 93, 84, 84, 88, 93, 74, 88, 85,
+  77, 88, 89, 79, 84, 79, 81, 97, 76, 81,
+  71, 87, 90, 103, 89, 85, 78, 113, 62, 81,
+  87, 89, 96, 83, 84, 75, 79, 87, 89, 88,
+  67, 85, 86, 82, 77, 85, 76, 68, 84, 80,
+  85, 87, 91, 99, 80, 86, 95, 85, 99, 90,
+  96, 94, 74, 89, 96, 92, 68, 91, 101, 89,
+  98, 82, 94, 79, 92, 80, 86, 84, 62, 101,
+  93, 82, 85, 95, 80, 88, 97, 84, 76, 87,
+  84, 77, 89, 89, 74, 85, 86, 81, 85, 81,
+  68, 94, 85, 78, 69, 63, 83, 83, 79, 80,
+  80, 79, 73, 97, 65, 84, 87, 73, 94, 106,
+  57, 71, 78, 98, 78, 98, 72, 67, 97, 69,
+  82, 86, 59, 76, 62, 83, 77, 87, 78, 70,
+  96, 74, 74, 74, 93, 87, 90, 93, 91, 74,
+  75, 75, 85, 76, 102, 65, 128, 66, 75, 92,
+  83, 93, 103, 71, 64, 78, 73, 80, 101, 97,
+  69, 69, 113, 91, 94, 87, 83, 72, 72, 71,
+  83, 84, 85, 89, 76, 95, 69, 81, 92, 79,
+  94, 66, 89, 89, 93, 79, 88, 86, 75, 86,
+  85, 57, 85, 98, 94, 95, 100, 77, 86, 73,
+  85, 82, 74, 87, 74, 77, 71, 81, 88, 88,
+  64, 83, 83, 79, 88, 91, 82, 73, 76, 75,
+  89, 84, 90, 94, 72, 71, 87, 90, 79, 81,
+  97, 82, 68, 84, 74, 64, 77, 96, 83, 60,
+  76, 90, 96, 95, 69, 82, 99, 86, 75, 74,
+  41, 89, 83, 87, 82, 65, 75, 86, 92, 74,
+  88, 58, 85, 121, 77, 133, 91, 88, 73, 85,
+  89, 72, 81, 69, 64, 58, 63, 96, 94, 84,
+  85, 64, 62, 62, 66, 68, 98, 76, 88, 84,
+  83, 86, 86, 55, 78, 89, 73, 75, 78, 63,
+  101, 88, 68, 94, 99, 105, 54, 80, 58, 81,
+  83, 96, 67, 76, 84, 81, 70, 66, 80, 67,
+  91, 86, 78, 82, 85, 83, 67, 74, 95, 96,
+  63, 86, 70, 69, 83, 74, 60, 68, 78, 87,
+  84, 77, 73, 86, 70, 80, 85, 73, 84, 89,
+  70, 76, 86, 85, 88, 85, 92, 105, 80, 86,
+  98, 82, 88, 82, 88, 88, 99, 75, 78, 83,
+  89, 90, 75, 82, 61, 96, 93, 86, 92, 86,
+  84, 78, 83, 78, 77, 79, 81, 73, 84, 80,
+  83, 98, 84, 85, 77, 87, 84, 95, 87, 95,
+  76, 119, 64, 83, 80, 79, 90, 89, 78, 69,
+  77, 89, 91, 87, 83, 80, 76, 68, 86, 87,
+  82, 72, 82, 72, 79, 90, 94, 96, 81, 81,
+  97, 88, 92, 95, 92, 78, 85, 84, 92, 88,
+  69, 85, 90, 97, 80, 90, 88, 87, 86, 80,
+  75, 91, 65, 97, 86, 86, 94, 97, 81, 85,
+  97, 78, 72, 85, 78, 69, 74, 94, 71, 85,
+  82, 80, 80, 81, 73, 107, 91, 80, 67, 74,
+  84, 88, 77, 80, 76, 72, 69, 95, 56, 81,
+  74, 72, 95, 102, 61, 83, 103, 97, 81, 99,
+  78, 74, 88, 61, 75, 87, 69, 77, 69, 95,
+  87, 82, 84, 73, 87, 74, 83, 76, 89, 96,
+  83, 89, 97, 71, 74, 72, 87, 78, 98, 71,
+  128, 68, 73, 87, 86, 98, 96, 67, 74, 77,
+  75, 84, 90, 96, 65, 76, 114, 91, 97, 97,
+  75, 94, 80, 71, 89, 85, 88, 92, 76, 91,
+  76, 80, 81, 83, 100, 71, 90, 79, 103, 76,
+  90, 77, 67, 83, 90, 61, 89, 92, 97, 79,
+  118, 76, 95, 75, 87, 77, 77, 100, 65, 82,
+  88, 76, 89, 96, 73, 83, 80, 81, 93, 92,
+  84, 72, 76, 79, 77, 92, 85, 102, 70, 75,
+  86, 90, 76, 81, 99, 86, 59, 82, 67, 73,
+  83, 90, 95, 74, 87, 91, 102, 86, 79, 89,
+  113, 58, 84, 84, 48, 98, 97, 90, 96, 78,
+  89, 87, 98, 81, 92, 62, 76, 124, 74, 116,
+  94, 81, 82, 84, 87, 67, 81, 80, 74, 54,
+  73, 89, 97, 94, 88, 57, 76, 57, 71, 76,
+  98, 78, 95, 87, 92, 86, 84, 66, 77, 106,
+  79, 77, 74, 76, 101, 92, 72, 95, 102, 107,
+  59, 80, 75, 86, 85, 91, 78, 77, 85, 77,
+  58, 77, 77, 70, 95, 82, 84, 83, 86, 88,
+  78, 66, 93, 95, 70, 93, 67, 85, 80, 82,
+  72, 73, 90, 80, 88, 77, 81, 90, 82, 78,
+  83, 65, 78, 97, 71, 74, 88, 85, 95, 86,
+  85, 101, 88, 77, 80, 84, 81, 89, 89, 85,
+  104, 78, 83, 90, 92, 81, 80, 90, 81, 80,
+  99, 85, 84, 99, 90, 78, 87, 85, 82, 96,
+  86, 81, 88, 85, 77, 98, 82, 87, 86, 89,
+  78, 94, 91, 88, 69, 122, 64, 76, 79, 83,
+  90, 86, 82, 68, 83, 85, 96, 81, 89, 81,
+  83, 76, 85, 84, 78, 68, 75, 80, 92, 90,
+  84, 107, 87, 85, 91, 94, 94, 101, 98, 85,
+  83, 94, 98, 93, 63, 85, 82, 93, 73, 93,
+  84, 81, 87, 75, 88, 86, 64, 93, 86, 91,
+  97, 87, 85, 92, 91, 79, 77, 91, 81, 65,
+  86, 90, 80, 82, 90, 81, 85, 81, 80, 78,
+  90, 105, 69, 86, 81, 71, 95, 91, 88, 82,
+  87, 79, 84, 82, 71, 73, 104, 69, 94, 82,
+  114, 94, 83, 74, 69, 89, 91, 81, 89, 97,
+  92, 79, 74, 91, 74, 86, 79, 82, 105, 77,
+  85, 89, 75, 78, 103, 82, 78, 87, 96, 73,
+  81, 108, 91, 87, 84, 91, 87, 83, 77, 95,
+  71, 82, 80, 80, 85, 101, 78, 83, 88, 87,
+  64, 86, 76, 84, 87, 101, 80, 77, 85, 79,
+  73, 75, 83, 84, 83, 74, 70, 89, 74, 97,
+  99, 86, 75, 83, 82, 93, 91, 63, 70, 79,
+  92, 81, 89, 91, 87, 79, 85, 79, 84, 90,
+  85, 86, 87, 93, 94, 81, 89, 87, 94, 73,
+  75, 83, 96, 86, 84, 84, 68, 90, 80, 106,
+  72, 96, 74, 62, 94, 89, 86, 77, 85, 79,
+  76, 73, 74, 78, 102, 77, 90, 83, 103, 88,
+  88, 75, 74, 87, 96, 78, 97, 95, 92, 81,
+  83, 73, 83, 97, 84, 81, 110, 75, 93, 94,
+  74, 77, 103, 86, 87, 87, 95, 81, 89, 127,
+  87, 86, 75, 87, 83, 75, 88, 100, 67, 89,
+  68, 82, 89, 94, 75, 82, 82, 87, 55, 90,
+  78, 82, 78, 87, 77, 74, 84, 85, 75, 74,
+  85, 87, 83, 76, 63, 89, 69, 107, 88, 83,
+  63, 76, 65, 90, 99, 60, 70, 84, 90, 78,
+  77, 84, 76, 72, 90, 75, 96, 91, 85, 80,
+  94, 89, 75, 74, 87, 93, 81, 73, 83, 79,
+  108, 85, 76, 78, 82, 98, 88, 87, 71, 107,
+  83, 71, 96, 93, 86, 81, 80, 73, 79, 90,
+  78, 70, 101, 71, 81, 80, 89, 89, 85, 78,
+  69, 85, 86, 78, 87, 96, 88, 80, 80, 82,
+  77, 89, 76, 87, 96, 78, 86, 83, 81, 88,
+  90, 98, 80, 84, 92, 70, 85, 103, 91, 82,
+  86, 91, 85, 80, 78, 92, 74, 80, 81, 85,
+  76, 93, 73, 74, 94, 87, 70, 85, 75, 91,
+  83, 78, 78, 77, 79, 80, 87, 89, 74, 85,
+  84, 74, 75, 98, 75, 107, 102, 86, 84, 81,
+  80, 88, 104, 63, 69, 85, 96, 85, 84, 83,
+  83, 78, 87, 83, 97, 85, 88, 91, 82, 86,
+  81, 85, 90, 91, 79, 76, 65, 87, 87, 85,
+  86, 80, 69, 70, 77, 122, 82, 73, 84, 71,
+  105, 93, 76, 84, 86, 100, 80, 89, 72, 71,
+  83, 74, 93, 74, 119, 94, 81, 75, 98, 74,
+  99, 79, 85, 83, 91, 74, 85, 95, 80, 73,
+  77, 72, 94, 94, 81, 105, 79, 89, 100, 96,
+  93, 84, 92, 78, 79, 116, 83, 100, 87, 80,
+  81, 95, 75, 97, 74, 75, 79, 65, 84, 113,
+  104, 76, 107, 88, 75, 83, 67, 70, 98, 92,
+  85, 85, 97, 86, 92, 70, 81, 81, 86, 74,
+  70, 78, 60, 89, 75, 89, 64, 75, 63, 88,
+  90, 73, 70, 93, 87, 74, 85, 98, 89, 72,
+  83, 52, 88, 86, 84, 92, 81, 91, 71, 68,
+  76, 82, 91, 63, 90, 71, 91, 86, 78, 75,
+  68, 91, 97, 156, 86, 75, 76, 50, 114, 85,
+  73, 77, 83, 85, 84, 99, 69, 67, 74, 74,
+  94, 82, 83, 83, 98, 81, 122, 66, 111, 83,
+  81, 107, 102, 75, 87, 74, 82, 73, 87, 73,
+  82, 84, 93, 102, 72, 85, 111, 93, 102, 90,
+  99, 93, 99, 150, 82, 89, 67, 81, 66, 85,
+  83, 104, 76, 92, 73, 67, 90, 90, 103, 76,
+  79, 81, 62, 83, 67, 47, 96, 90, 79, 79,
+  105, 105, 106, 82, 77, 91, 92, 71, 70, 76,
+  47, 94, 56, 94, 46, 63, 36, 86, 98, 65,
+  74, 86, 73, 69, 78, 79, 86, 62, 99, 48,
+  106, 71, 83, 87, 82, 87, 76, 55, 58, 87,
+  84, 62, 117, 60, 110, 92, 51, 70, 77, 89,
+  97, 101, 76, 104, 82, 65, 96, 93, 76, 88,
+  74, 78, 77, 92, 82, 73, 87, 78, 79, 76,
+  73, 87, 91, 75, 94, 70, 95, 86, 82, 97,
+  84, 78, 84, 68, 80, 78, 82, 78, 92, 90,
+  84, 100, 80, 88, 89, 88, 90, 83, 89, 81,
+  80, 107, 78, 80, 88, 84, 80, 88, 73, 97,
+  77, 69, 84, 72, 82, 107, 88, 79, 78, 87,
+  71, 88, 69, 75, 88, 85, 73, 80, 88, 88,
+  108, 97, 74, 91, 89, 79, 75, 83, 63, 99,
+  77, 93, 71, 68, 63, 88, 99, 64, 69, 78,
+  87, 76, 83, 95, 83, 72, 85, 63, 103, 91,
+  88, 92, 83, 95, 98, 69, 76, 86, 72, 67,
+  75, 76, 82, 88, 85, 74, 76, 76, 81, 97,
+  88, 77, 73, 83, 99, 97, 71, 71, 83, 95,
+  81, 99, 69, 63, 76, 89, 83, 76, 107, 102,
+  82, 76, 106, 67, 81, 84, 72, 77, 74, 68,
+  89, 101, 88, 70, 75, 73, 78, 84, 74, 84,
+  68, 85, 81, 89, 100, 79, 81, 67, 82, 103,
+  76, 101, 103, 77, 84, 91, 68, 95, 83, 85,
+  75, 65, 82, 100, 90, 79, 98, 87, 106, 90,
+  68, 91, 97, 91, 113, 80, 82, 75, 104, 81,
+  87, 81, 81, 83, 72, 81, 67, 82, 81, 82,
+  72, 72, 68, 75, 71, 78, 67, 93, 91, 81,
+  86, 106, 73, 75, 64, 69, 81, 92, 82, 91,
+  80, 80, 74, 85, 83, 89, 93, 71, 86, 64,
+  74, 85, 99, 74, 79, 83, 90, 118, 94, 79,
+  57, 62, 103, 91, 67, 67, 83, 89, 88, 103,
+  74, 61, 72, 92, 85, 74, 79, 96, 92, 72,
+  117, 60, 99, 98, 76, 93, 87, 70, 86, 82,
+  80, 50, 82, 68, 66, 72, 77, 96, 61, 85,
+  76, 98, 98, 80, 82, 78, 97, 112, 69, 85,
+  90, 75, 80, 91, 73, 106, 83, 96, 79, 64,
+  85, 99, 102, 82, 89, 85, 97, 84, 51, 68,
+  100, 90, 106, 76, 85, 78, 132, 88, 94, 87,
+  86, 79, 78, 73, 56, 88, 61, 89, 59, 61,
+  53, 78, 76, 75, 62, 88, 86, 81, 90, 110,
+  73, 72, 60, 60, 86, 87, 77, 87, 98, 83,
+  92, 74, 65, 96, 80, 70, 97, 49, 75, 84,
+  82, 73, 81, 84, 75, 89, 86, 99, 71, 77,
+  93, 94, 76, 73, 76, 80, 79, 94, 82, 68,
+  80, 78, 78, 77, 72, 94, 87, 70, 99, 66,
+  79, 101, 73, 86, 69, 74, 86, 75, 85, 67,
+  82, 77, 78, 82, 79, 90, 67, 84, 76, 91,
+  92, 75, 81, 81, 83, 96, 79, 71, 97, 80,
+  89, 87, 68, 90, 86, 78, 77, 71, 78, 98,
+  90, 84, 78, 86, 95, 92, 61, 96, 90, 81,
+  97, 73, 77, 81, 104, 94, 81, 84, 82, 92,
+  77, 86, 69, 85, 88, 81, 75, 68, 69, 80,
+  91, 64, 70, 72, 91, 80, 89, 100, 76, 79,
+  63, 77, 92, 90, 85, 87, 91, 90, 103, 87,
+  84, 89, 81, 73, 76, 74, 73, 82, 101, 80,
+  81, 77, 79, 83, 76, 85, 75, 94, 81, 90,
+  68, 86, 88, 106, 71, 83, 84, 72, 85, 87,
+  87, 98, 90, 87, 79, 71, 85, 89, 95, 80,
+  84, 72, 84, 74, 79, 85, 67, 85, 93, 74,
+  90, 76, 89, 81, 86, 84, 78, 75, 88, 95,
+  98, 81, 95, 89, 79, 80, 64, 73, 80, 75,
+  92, 91, 85, 80, 62, 79, 123, 90, 84, 59,
+  79, 76, 99, 92, 78, 78, 75, 89, 82, 80,
+  82, 92, 88, 88, 73, 91, 98, 80, 86, 80,
+  79, 89, 95, 78, 93, 80, 68, 76, 87, 86,
+  78, 81, 92, 75, 89, 84, 79, 87, 81, 98,
+  70, 99, 75, 89, 84, 81, 81, 90, 77, 85,
+  83, 79, 96, 88, 81, 90, 80, 87, 77, 79,
+  83, 92, 102, 79, 69, 93, 78, 90, 75, 81,
+  83, 98, 68, 85, 93, 78, 93, 93, 86, 95,
+  85, 78, 91, 65, 80, 97, 94, 85, 81, 85,
+  95, 68, 77, 74, 57, 87, 121, 67, 96, 70,
+  94, 97, 92, 86, 87, 75, 86, 90, 100, 74,
+  89, 94, 71, 89, 64, 79, 74, 69, 95, 100,
+  85, 79, 55, 71, 122, 97, 98, 66, 67, 70,
+  100, 94, 77, 70, 68, 78, 82, 77, 80, 88,
+  92, 92, 73, 87, 84, 91, 77, 77, 76, 98,
+  89, 84, 90, 92, 75, 76, 88, 74, 83, 85,
+  91, 75, 81, 79, 74, 79, 80, 91, 64, 135,
+  78, 82, 84, 74, 77, 93, 77, 86, 85, 77,
+  94, 87, 80, 91, 83, 84, 72, 87, 81, 85,
+  74, 88, 76, 103, 86, 89, 67, 91, 95, 84,
+  68, 88, 81, 72, 84, 83, 78, 94, 86, 89,
+  71, 71, 85, 83, 93, 90, 77, 82, 86, 77,
+  84, 86, 71, 87, 116, 78, 85, 76, 85, 85,
+  89, 82, 80, 87, 89, 94, 97, 82, 99, 91,
+  83, 91, 77, 66, 79, 82, 92, 91, 79, 81,
+  70, 80, 101, 91, 79, 72, 78, 79, 97, 81,
+  76, 75, 75, 73, 77, 85, 80, 88, 84, 83,
+  75, 85, 86, 88, 84, 78, 81, 87, 92, 74,
+  93, 80, 67, 74, 79, 81, 80, 88, 91, 76,
+  90, 80, 89, 85, 79, 96, 66, 97, 73, 98,
+  78, 83, 82, 86, 78, 84, 88, 78, 96, 88,
+  83, 90, 77, 88, 80, 62, 73, 74, 106, 76,
+  71, 85, 73, 93, 85, 80, 71, 78, 66, 74,
+  90, 85, 90, 103, 95, 95, 105, 75, 84, 66,
+  83, 97, 105, 99, 78, 86, 92, 70, 84, 95,
+  67, 78, 141, 69, 89, 65, 95, 101, 93, 73,
+  75, 71, 87, 85, 92, 67, 73, 88, 68, 85,
+  86, 74, 73, 68, 74, 107, 81, 81, 67, 72,
+  92, 93, 93, 69, 73, 63, 95, 92, 77, 81,
+  82, 85, 109, 72, 66, 77, 83, 103, 78, 77,
+  91, 105, 64, 88, 90, 77, 85, 59, 94, 95,
+  81, 79, 78, 87, 93, 81, 87, 82, 86, 88,
+  72, 81, 84, 85, 77, 135, 69, 84, 89, 83,
+  80, 87, 58, 78, 84, 72, 72, 78, 69, 88,
+  83, 84, 78, 62, 65, 76, 137, 76, 77, 81,
+  67, 98, 90, 70, 60, 108, 73, 71, 93, 85,
+  87, 112, 102, 99, 72, 67, 81, 64, 75, 98,
+  101, 109, 82, 85, 86, 70, 83, 89, 47, 70,
+  136, 72, 90, 54, 97, 117, 101, 75, 77, 71,
+  89, 76, 86, 64, 70, 93, 60, 77, 90, 83,
+  65, 57, 78, 128, 75, 77, 69, 70, 68, 95,
+  118, 64, 66, 58, 92, 77, 90, 74, 72, 75,
+  105, 67, 67, 74, 83, 88, 90, 70, 75, 104,
+  57, 85, 87, 77, 70, 61, 94, 105, 82, 87,
+  78, 76, 74, 80, 92, 81, 90, 95, 64, 72,
+  81, 74, 80, 173, 80, 77, 87, 68, 71, 86,
+  59, 78, 90, 68, 61, 77, 74, 87, 90, 75,
+  81, 68, 70, 81, 86, 93, 77, 92, 80, 89,
+  88, 78, 79, 125, 67, 75, 89, 77, 90, 88,
+  90, 97, 75, 77, 64, 70, 89, 92, 99, 109,
+  79, 94, 92, 74, 84, 92, 69, 82, 102, 73,
+  79, 69, 92, 88, 88, 75, 82, 84, 87, 92,
+  88, 72, 79, 85, 79, 74, 93, 73, 74, 81,
+  83, 97, 81, 74, 74, 79, 76, 87, 92, 77,
+  70, 77, 92, 83, 86, 84, 78, 80, 89, 76,
+  70, 76, 79, 82, 78, 76, 83, 99, 73, 84,
+  91, 99, 85, 61, 94, 89, 79, 77, 76, 83,
+  95, 98, 85, 79, 87, 85, 83, 76, 84, 89,
+  81, 114, 72, 93, 88, 90, 78, 81, 70, 76,
+  96, 77, 81, 83, 75, 88, 83, 92, 81, 83,
+  83, 75, 64, 103, 86, 89, 88, 84, 78, 93,
+  91, 60, 76, 96, 75, 101, 82, 81, 83, 78,
+  97, 83, 83, 81, 89, 88, 85, 94, 89, 91,
+  91, 72, 76, 89, 83, 79, 104, 82, 81, 76,
+  84, 87, 77, 77, 87, 78, 80, 88, 100, 89,
+  84, 90, 81, 93, 82, 75, 80, 93, 87, 76,
+  89, 86, 93, 83, 82, 77, 80, 75, 78, 80,
+  98, 81, 77, 84, 83, 87, 92, 83, 84, 95,
+  84, 92, 85, 84, 95, 74, 98, 84, 84, 82,
+  83, 74, 93, 71, 80, 81, 88, 87, 90, 80,
+  84, 74, 84, 91, 78, 85, 81, 94, 87, 74,
+  74, 85, 93, 98, 81, 85, 82, 75, 92, 79,
+  100, 84, 80, 92, 78, 85, 82, 84, 77, 73,
+  66, 83, 93, 93, 83, 86, 77, 94, 90, 78,
+  78, 95, 68, 97, 75, 77, 88, 75, 83, 82,
+  80, 81, 98, 92, 77, 94, 92, 92, 97, 71,
+  88, 77, 81, 71, 75, 83, 77, 75, 90, 80,
+  69, 83, 90, 77, 96, 94, 93, 89, 89, 91,
+  78, 86, 83, 76, 84, 85, 89, 74, 90, 86,
+  77, 84, 76, 59, 84, 66, 73, 91, 95, 80,
+  84, 90, 78, 84, 103, 79, 89, 95, 83, 82,
+  85, 85, 85, 66, 99, 91, 91, 79, 89, 79,
+  80, 63, 85, 80, 95, 80, 91, 69, 89, 70,
+  89, 90, 76, 82, 82, 102, 93, 69, 87, 87,
+  95, 101, 67, 89, 86, 83, 94, 80, 103, 92,
+  84, 93, 83, 88, 84, 79, 85, 76, 70, 96,
+  88, 92, 89, 81, 78, 85, 89, 98, 83, 91,
+  77, 90, 82, 81, 81, 85, 94, 82, 76, 84,
+  86, 83, 78, 84, 91, 87, 86, 78, 90, 87,
+  82, 78, 67, 80, 78, 75, 81, 83, 77, 80,
+  93, 84, 80, 84, 94, 96, 87, 89, 84, 77,
+  83, 79, 76, 93, 88, 75, 85, 88, 101, 84,
+  83, 79, 79, 76, 87, 81, 96, 82, 85, 83,
+  79, 90, 93, 82, 90, 88, 80, 81, 89, 86,
+  84, 73, 97, 83, 83, 90, 83, 83, 92, 72,
+  82, 81, 85, 83, 92, 79, 83, 71, 83, 95,
+  80, 88, 77, 95, 88, 77, 77, 96, 97, 88,
+  74, 82, 88, 75, 84, 82, 95, 88, 82, 87,
+  83, 85, 95, 86, 84, 93, 86, 92, 72, 104,
+  99, 85, 83, 76, 100, 64, 64, 106, 88, 92,
+  80, 78, 84, 84, 96, 88, 71, 66, 84, 90,
+  90, 85, 81, 85, 100, 73, 84, 91, 80, 87,
+  104, 77, 90, 80, 84, 89, 86, 90, 79, 87,
+  82, 95, 80, 94, 85, 88, 104, 82, 92, 90,
+  92, 81, 77, 78, 85, 83, 83, 83, 92, 76,
+  93, 79, 105, 82, 111, 111, 70, 89, 87, 80,
+  85, 68, 102, 75, 82, 86, 92, 72, 80, 86,
+  90, 74, 84, 115, 89, 80, 96, 67, 93, 75,
+  77, 90, 97, 73, 86, 85, 76, 72, 78, 85,
+  73, 99, 88, 90, 84, 83, 83, 68, 78, 75,
+  92, 79, 68, 78, 79, 112, 91, 85, 82, 87,
+  93, 78, 93, 102, 95, 97, 69, 112, 105, 87,
+  81, 76, 93, 79, 70, 106, 84, 97, 85, 76,
+  89, 92, 99, 89, 71, 63, 100, 95, 87, 82,
+  74, 80, 98, 66, 89, 87, 73, 89, 75, 69,
+  98, 71, 87, 86, 90, 100, 80, 79, 75, 93,
+  86, 98, 85, 81, 109, 68, 93, 86, 92, 84,
+  77, 78, 85, 77, 101, 70, 92, 69, 92, 87,
+  84, 74, 129, 111, 72, 84, 87, 88, 79, 57,
+  97, 77, 86, 87, 78, 78, 83, 74, 82, 77,
+  89, 116, 89, 80, 107, 63, 86, 73, 72, 81,
+  93, 75, 84, 88, 76, 71, 77, 86, 74, 101,
+  90, 93, 93, 85, 77, 58, 97, 76, 83, 77,
+  77, 75, 81, 123, 86, 95, 83, 86, 98, 73,
+  102, 95, 90, 86, 79, 95, 92, 87, 87, 81,
+  96, 108, 68, 101, 82, 88, 88, 82, 86, 92,
+  85, 92, 71, 72, 85, 86, 81, 82, 83, 81,
+  102, 71, 85, 91, 76, 83, 69, 79, 90, 82,
+  83, 85, 80, 88, 77, 83, 80, 97, 75, 108,
+  88, 87, 112, 74, 90, 85, 94, 85, 75, 79,
+  84, 81, 85, 85, 89, 80, 94, 79, 75, 78,
+  115, 102, 77, 90, 85, 89, 80, 76, 106, 69,
+  84, 74, 88, 79, 74, 80, 94, 74, 83, 107,
+  93, 86, 95, 70, 89, 77, 80, 90, 86, 72,
+  90, 82, 77, 73, 79, 83, 74, 99, 98, 85,
+  86, 86, 92, 71, 101, 80, 92, 79, 81, 78,
+  81, 116, 91, 93, 90, 91, 90, 82, 85, 74,
+  75, 70, 72, 70, 71, 75, 79, 82, 90, 67,
+  76, 77, 84, 82, 66, 92, 76, 59, 85, 80,
+  91, 76, 70, 76, 104, 84, 93, 86, 79, 95,
+  74, 90, 104, 80, 97, 82, 80, 84, 80, 81,
+  83, 71, 86, 89, 83, 74, 80, 67, 81, 93,
+  70, 96, 82, 84, 82, 92, 99, 75, 98, 90,
+  89, 73, 98, 77, 90, 78, 86, 98, 76, 91,
+  86, 60, 82, 77, 95, 81, 78, 107, 73, 100,
+  101, 71, 77, 88, 66, 76, 66, 90, 72, 81,
+  81, 71, 86, 96, 84, 77, 81, 87, 87, 92,
+  89, 67, 78, 81, 89, 72, 86, 81, 59, 82,
+  83, 98, 78, 92, 85, 75, 73, 84, 71, 69,
+  69, 87, 68, 73, 94, 80, 78, 64, 83, 65,
+  73, 69, 64, 71, 78, 84, 86, 84, 80, 77,
+  83, 84, 63, 89, 81, 55, 66, 74, 87, 82,
+  75, 68, 105, 79, 104, 82, 72, 92, 84, 79,
+  104, 80, 75, 77, 81, 80, 90, 84, 92, 68,
+  83, 83, 85, 67, 79, 63, 81, 90, 63, 81,
+  80, 83, 76, 89, 95, 78, 99, 88, 74, 66,
+  91, 72, 100, 71, 71, 95, 72, 83, 97, 51,
+  77, 89, 103, 74, 79, 110, 67, 77, 116, 69,
+  78, 82, 48, 80, 66, 89, 65, 82, 79, 72,
+  82, 94, 90, 64, 68, 81, 81, 94, 102, 60,
+  74, 83, 95, 66, 96, 82, 57, 78, 86, 87,
+  64, 94, 82, 74, 75, 76, 74, 56, 73, 94,
+  69, 67, 88, 74, 87, 78, 77, 89, 67, 71,
+  77, 79, 85, 82, 83, 100, 72, 80, 81, 84,
+  75, 96, 81, 64, 66, 81, 76, 74, 80, 77,
+  92, 76, 89, 83, 84, 77, 75, 84, 87, 76,
+  59, 77, 77, 87, 84, 82, 80, 76, 79, 92,
+  78, 77, 79, 81, 81, 91, 84, 80, 86, 81,
+  85, 88, 93, 73, 100, 81, 90, 79, 87, 77,
+  98, 78, 75, 94, 87, 90, 93, 64, 88, 94,
+  94, 85, 81, 97, 76, 69, 96, 71, 79, 82,
+  75, 75, 72, 106, 73, 81, 90, 70, 82, 92,
+  88, 77, 78, 99, 90, 88, 85, 68, 79, 76,
+  86, 79, 87, 83, 67, 85, 93, 90, 76, 92,
+  88, 68, 82, 87, 78, 79, 75, 89, 72, 80,
+  88, 88, 85, 87, 92, 80, 78, 71, 75, 81,
+  82, 87, 94, 92, 82, 75, 85, 77, 79, 83,
+  85, 66, 84, 92, 82, 80, 84, 87, 92, 87,
+  98, 83, 85, 104, 91, 84, 81, 100, 57, 83,
+  89, 91, 87, 82, 86, 83, 84, 90, 85, 83,
+  90, 78, 84, 92, 74, 78, 83, 77, 86, 86,
+  95, 93, 91, 84, 98, 75, 85, 72, 87, 78,
+  86, 92, 80, 81, 84, 72, 80, 87, 86, 89,
+  78, 87, 78, 83, 83, 84, 78, 78, 81, 74,
+  78, 83, 87, 89, 84, 79, 92, 88, 85, 90,
+  87, 93, 88, 90, 82, 80, 88, 83, 87, 76,
+  75, 86, 71, 90, 79, 80, 75, 102, 87, 89,
+  83, 87, 79, 72, 65, 93, 70, 79, 93, 78,
+  80, 80, 95, 75, 80, 70, 68, 77, 82, 86,
+  99, 78, 83, 79, 89, 82, 81, 81, 86, 54,
+  75, 93, 84, 83, 82, 79, 101, 85, 106, 90,
+  80, 106, 86, 76, 87, 99, 86, 85, 94, 96,
+  85, 82, 83, 74, 83, 86, 94, 82, 87, 68,
+  85, 85, 68, 79, 80, 75, 84, 84, 104, 94,
+  89, 84, 85, 73, 100, 66, 91, 90, 74, 99,
+  74, 80, 81, 64, 80, 99, 81, 93, 78, 79,
+  76, 81, 88, 91, 81, 86, 72, 73, 71, 77,
+  85, 97, 75, 83, 92, 86, 90, 87, 78, 75,
+  87, 91, 83, 77, 85, 87, 85, 77, 75, 82,
+  68, 84, 75, 90, 82, 103, 86, 97, 86, 83,
+  83, 62, 62, 92, 64, 78, 85, 79, 92, 92,
+  84, 100, 72, 67, 78, 80, 85, 83, 92, 67,
+  76, 79, 88, 82, 83, 88, 89, 59, 80, 96,
+  82, 77, 82, 87, 88, 92, 89, 89, 83, 89,
+  84, 84, 80, 97, 100, 83, 91, 92, 78, 87,
+  87, 78, 83, 88, 84, 91, 87, 80, 83, 89,
+  80, 93, 83, 76, 89, 83, 93, 80, 86, 80,
+  88, 82, 85, 74, 86, 87, 81, 99, 84, 82,
+  78, 76, 85, 97, 86, 93, 78, 90, 74, 78,
+  85, 86, 85, 83, 85, 75, 73, 78, 89, 86,
+  81, 79, 90, 86, 90, 84, 87, 69, 88, 86,
+  76, 80, 86, 81, 87, 83, 77, 85, 78, 84,
+  77, 87, 97, 102, 85, 84, 86, 87, 82, 83,
+  71, 92, 71, 85, 55, 88, 86, 106, 87, 67,
+  88, 84, 82, 77, 96, 90, 79, 95, 79, 73,
+  67, 72, 107, 98, 83, 97, 75, 82, 90, 83,
+  101, 72, 113, 93, 89, 78, 92, 74, 79, 88,
+  74, 120, 91, 75, 113, 67, 92, 93, 61, 95,
+  63, 105, 94, 75, 90, 106, 77, 103, 96, 92,
+  89, 85, 108, 76, 76, 100, 128, 75, 90, 76,
+  82, 91, 70, 77, 98, 90, 61, 71, 85, 82,
+  71, 84, 114, 75, 84, 91, 101, 82, 83, 87,
+  98, 97, 80, 115, 93, 78, 55, 75, 78, 91,
+  92, 85, 63, 123, 81, 81, 86, 87, 77, 71,
+  99, 96, 122, 60, 122, 86, 94, 96, 87, 87,
+  85, 77, 89, 89, 100, 74, 109, 70, 83, 76,
+  93, 77, 61, 79, 77, 109, 86, 64, 82, 79,
+  78, 84, 92, 90, 72, 93, 81, 77, 71, 72,
+  101, 93, 93, 85, 74, 77, 86, 87, 98, 70,
+  70, 95, 85, 76, 81, 77, 82, 75, 74, 112,
+  91, 78, 99, 64, 86, 88, 64, 86, 56, 95,
+  87, 78, 80, 102, 74, 100, 90, 92, 85, 79,
+  94, 81, 76, 89, 128, 70, 95, 77, 79, 90,
+  73, 79, 92, 98, 61, 77, 86, 80, 74, 85,
+  106, 79, 80, 85, 95, 79, 75, 90, 97, 91,
+  68, 111, 80, 82, 58, 74, 79, 82, 87, 88,
+  74, 109, 85, 77, 85, 83, 74, 68, 91, 91,
+  122, 64, 120, 87, 85, 91, 84, 82, 84, 78,
+  90, 87, 110, 80, 102, 74, 81, 80, 90, 72,
+  66, 76, 73, 100, 83, 73, 86, 83, 83, 80,
+  87, 88, 77, 85, 81, 78, 74, 79, 97, 87,
+  89, 83, 77, 85, 84, 80, 99, 72, 101, 89,
+  80, 75, 83, 81, 77, 73, 74, 103, 87, 81,
+  101, 67, 83, 91, 67, 93, 61, 91, 88, 77,
+  84, 98, 79, 87, 95, 83, 88, 82, 98, 80,
+  77, 90, 120, 74, 83, 76, 82, 86, 77, 79,
+  90, 91, 64, 74, 97, 80, 79, 92, 96, 79,
+  79, 90, 87, 80, 79, 89, 96, 89, 81, 102,
+  86, 79, 61, 74, 82, 80, 83, 85, 94, 101,
+  83, 79, 82, 83, 78, 72, 96, 90, 110, 74,
+  104, 82, 85, 86, 77, 85, 93, 76, 89, 88,
+  104, 77, 92, 69, 85, 80, 85, 74, 82, 80,
+  83, 99, 78, 77, 86, 89, 77, 85, 86, 82,
+  90, 89, 87, 76, 72, 94, 93, 84, 78, 82,
+  80, 91, 88, 91, 94, 67, 98, 91, 90, 69,
+  81, 73, 79, 81, 82, 90, 82, 80, 87, 69,
+  84, 79, 93, 90, 64, 84, 83, 85, 83, 93,
+  81, 69, 93, 74, 86, 91, 67, 87, 86, 82,
+  112, 83, 76, 85, 73, 81, 64, 92, 80, 83,
+  75, 81, 81, 85, 83, 79, 90, 82, 92, 84,
+  74, 73, 79, 86, 90, 82, 81, 101, 68, 82,
+  58, 81, 85, 81, 76, 89, 53, 75, 87, 81,
+  84, 82, 70, 56, 98, 83, 105, 90, 118, 81,
+  79, 85, 84, 73, 82, 79, 82, 83, 109, 93,
+  60, 82, 82, 87, 74, 80, 90, 74, 75, 97,
+  75, 77, 86, 87, 75, 92, 83, 87, 87, 81,
+  90, 82, 78, 89, 84, 81, 88, 76, 84, 93,
+  77, 94, 99, 67, 79, 87, 83, 64, 79, 76,
+  78, 69, 82, 87, 81, 81, 81, 73, 75, 77,
+  98, 92, 52, 78, 81, 85, 78, 87, 77, 67,
+  86, 84, 85, 86, 66, 88, 86, 78, 101, 85,
+  73, 86, 68, 80, 66, 95, 79, 85, 78, 81,
+  81, 82, 87, 76, 86, 87, 88, 84, 75, 74,
+  82, 87, 86, 80, 75, 107, 56, 85, 54, 83,
+  89, 79, 74, 94, 65, 68, 85, 79, 85, 80,
+  75, 60, 90, 79, 109, 97, 110, 79, 77, 88,
+  79, 71, 74, 81, 80, 83, 96, 103, 56, 84,
+  79, 86, 73, 81, 87, 76, 70, 93, 78, 82,
+  87, 86, 77, 86, 79, 82, 87, 77, 83, 83,
+  76, 91, 84, 80, 88, 78, 84, 94, 75, 83,
+  95, 71, 93, 85, 85, 67, 83, 81, 86, 77,
+  82, 88, 81, 83, 83, 73, 79, 83, 89, 91,
+  58, 82, 81, 81, 79, 88, 81, 66, 86, 86,
+  87, 92, 69, 88, 87, 82, 102, 84, 75, 84,
+  69, 80, 75, 91, 82, 82, 75, 81, 93, 83,
+  84, 80, 89, 83, 85, 88, 74, 80, 83, 85,
+  82, 83, 85, 96, 67, 82, 59, 80, 90, 75,
+  78, 87, 82, 72, 89, 86, 86, 81, 74, 64,
+  98, 82, 100, 95, 97, 77, 78, 85, 74, 72,
+  82, 81, 81, 87, 83, 96, 58, 79, 83, 85,
+  73, 78, 87, 85, 85, 87, 82, 97, 83, 83,
+  86, 86, 73, 82, 96, 83, 88, 79, 61, 101,
+  75, 92, 70, 76, 87, 107, 90, 81, 92, 71,
+  85, 88, 80, 77, 90, 90, 89, 83, 81, 83,
+  75, 90, 69, 84, 85, 80, 94, 90, 75, 83,
+  91, 83, 87, 86, 92, 56, 92, 78, 89, 91,
+  59, 85, 87, 96, 81, 93, 76, 94, 73, 79,
+  73, 87, 86, 86, 87, 82, 87, 91, 91, 82,
+  84, 81, 82, 84, 69, 82, 85, 90, 90, 78,
+  83, 97, 68, 79, 70, 84, 87, 83, 79, 90,
+  67, 68, 79, 88, 82, 85, 70, 77, 90, 84,
+  91, 105, 105, 78, 78, 89, 83, 82, 80, 85,
+  82, 86, 90, 92, 43, 83, 90, 96, 68, 80,
+  90, 83, 80, 88, 87, 102, 80, 79, 83, 92,
+  72, 87, 95, 81, 88, 87, 66, 92, 68, 93,
+  80, 75, 100, 107, 82, 79, 85, 70, 80, 87,
+  77, 73, 83, 90, 87, 80, 85, 86, 78, 93,
+  70, 85, 74, 83, 93, 89, 73, 78, 89, 84,
+  80, 83, 88, 61, 92, 83, 88, 88, 61, 85,
+  91, 90, 77, 94, 77, 95, 74, 78, 80, 90,
+  85, 85, 88, 81, 92, 85, 94, 81, 79, 82,
+  79, 85, 66, 74, 93, 92, 90, 88, 78, 87,
+  57, 84, 67, 86, 91, 79, 85, 90, 82, 68,
+  76, 93, 84, 82, 76, 76, 84, 83, 83, 109,
+  94, 79, 79, 89, 81, 88, 81, 87, 81, 86,
+  77, 96, 41, 86, 93, 93, 74, 84, 92, 79,
+  80, 90, 83, 93, 83, 78, 83, 83, 69, 86,
+  93, 76, 82, 85, 61, 93, 75, 86, 84, 76,
+  92, 105, 81, 79, 88, 71, 81, 88, 82, 73,
+  88, 90, 88, 81, 81, 83, 80, 91, 74, 86,
+  75, 82, 91, 85, 73, 82, 87, 80, 84, 85,
+  89, 61, 92, 88, 92, 91, 60, 84, 87, 92,
+  82, 91, 74, 92, 64, 77, 78, 85, 79, 83,
+  83, 82, 93, 91, 88, 80, 80, 78, 77, 86,
+  71, 74, 91, 90, 84, 85, 85, 91, 72, 82,
+  69, 82, 88, 76, 83, 87, 91, 75, 81, 90,
+  86, 83, 72, 75, 89, 84, 87, 101, 92, 76,
+  74, 86, 80, 79, 90, 85, 83, 85, 83, 87,
+  53, 87, 93, 90, 69, 77, 88, 84, 86, 87,
+  74, 85, 73, 81, 78, 91, 88, 85, 79, 70,
+  82, 82, 77, 104, 86, 81, 86, 73, 87, 86,
+  95, 83, 73, 78, 92, 99, 101, 84, 82, 84,
+  90, 78, 87, 81, 83, 83, 79, 83, 77, 81,
+  74, 71, 90, 84, 79, 88, 70, 86, 88, 80,
+  86, 71, 70, 78, 65, 85, 89, 85, 88, 84,
+  76, 87, 84, 85, 88, 95, 70, 82, 75, 93,
+  80, 76, 84, 85, 93, 85, 84, 72, 72, 90,
+  93, 73, 92, 96, 74, 78, 78, 74, 70, 71,
+  75, 81, 86, 84, 70, 68, 76, 79, 87, 78,
+  87, 94, 80, 89, 72, 95, 80, 86, 99, 72,
+  86, 79, 81, 90, 90, 105, 92, 88, 80, 90,
+  81, 89, 91, 80, 80, 86, 72, 86, 79, 73,
+  77, 85, 79, 87, 87, 82, 76, 72, 80, 83,
+  77, 96, 86, 83, 80, 82, 79, 81, 84, 87,
+  75, 78, 87, 95, 103, 88, 83, 79, 91, 75,
+  92, 79, 72, 79, 76, 83, 88, 87, 76, 71,
+  93, 82, 76, 86, 79, 86, 90, 86, 81, 77,
+  72, 77, 64, 89, 97, 92, 88, 88, 71, 87,
+  82, 87, 93, 79, 74, 77, 73, 92, 85, 78,
+  85, 89, 104, 85, 88, 72, 76, 81, 93, 73,
+  78, 93, 77, 80, 76, 78, 74, 69, 81, 77,
+  90, 90, 81, 72, 74, 81, 84, 80, 86, 92,
+  85, 89, 78, 92, 78, 89, 95, 77, 81, 76,
+  71, 89, 92, 108, 90, 90, 83, 89, 82, 86,
+  93, 82, 85, 83, 66, 86, 79, 81, 74, 88,
+  83, 91, 88, 83, 75, 81, 82, 85, 85, 105,
+  85, 83, 78, 84, 87, 84, 69, 82, 78, 81,
+  87, 88, 91, 87, 85, 84, 99, 76, 92, 80,
+  69, 81, 79, 85, 95, 84, 76, 74, 90, 87,
+  73, 89, 74, 86, 88, 78, 92, 83, 68, 76,
+  69, 86, 90, 83, 87, 83, 85, 88, 75, 88,
+  92, 82, 88, 85, 79, 90, 93, 77, 82, 93,
+  102, 89, 87, 70, 77, 72, 89, 71, 77, 95,
+  77, 84, 77, 87, 73, 75, 90, 82, 84, 88,
+  84, 73, 81, 88, 88, 79, 83, 91, 81, 89,
+  69, 97, 77, 90, 95, 95, 77, 76, 70, 88,
+  87, 103, 83, 84, 85, 92, 78, 80, 92, 81,
+  80, 85, 95, 104, 74, 88, 79, 71, 97, 82,
+  74, 80, 90, 68, 72, 108, 81, 82, 76, 77,
+  88, 71, 79, 89, 98, 83, 80, 68, 89, 86,
+  95, 78, 80, 86, 85, 74, 79, 90, 92, 82,
+  79, 90, 70, 96, 72, 91, 101, 82, 84, 77,
+  77, 86, 86, 91, 77, 83, 77, 85, 77, 100,
+  77, 81, 70, 80, 71, 76, 94, 86, 91, 60,
+  77, 77, 69, 75, 78, 76, 88, 101, 85, 89,
+  81, 86, 84, 77, 97, 91, 87, 71, 90, 73,
+  59, 78, 69, 78, 59, 71, 88, 70, 73, 82,
+  61, 84, 86, 70, 87, 111, 83, 83, 70, 75,
+  83, 73, 87, 66, 97, 83, 81, 87, 95, 103,
+  90, 83, 80, 91, 91, 88, 79, 81, 66, 88,
+  83, 94, 79, 79, 78, 76, 99, 77, 73, 79,
+  67, 82, 70, 108, 78, 75, 68, 79, 75, 95,
+  77, 91, 78, 81, 88, 67, 81, 79, 84, 75,
+  74, 88, 72, 67, 84, 93, 81, 83, 88, 85,
+  71, 85, 72, 81, 100, 87, 80, 73, 85, 101,
+  92, 92, 73, 90, 90, 84, 79, 103, 83, 106,
+  73, 90, 71, 85, 95, 93, 105, 58, 85, 68,
+  68, 69, 77, 83, 83, 83, 94, 91, 80, 89,
+  91, 75, 92, 101, 71, 61, 90, 69, 66, 82,
+  70, 72, 66, 63, 85, 78, 84, 104, 63, 94,
+  82, 74, 88, 126, 87, 75, 68, 67, 75, 76,
+  81, 64, 98, 80, 83, 91, 98, 105, 78, 81,
+  80, 85, 84, 83, 72, 88, 75, 102, 74, 101,
+  79, 83, 79, 75, 95, 83, 74, 80, 93, 92,
+  73, 110, 89, 85, 77, 78, 71, 76, 90, 91,
+  73, 85, 84, 73, 85, 84, 91, 88, 80, 93,
+  89, 68, 81, 89, 70, 88, 79, 90, 92, 98,
+  71, 81, 98, 98, 75, 80, 81, 86, 88, 89,
+  75, 83, 77, 91, 78, 98, 77, 78, 71, 81,
+  77, 77, 84, 85, 92, 61, 84, 74, 73, 73,
+  84, 74, 80, 85, 93, 91, 88, 83, 84, 76,
+  98, 94, 79, 70, 90, 78, 62, 80, 68, 80,
+  62, 68, 84, 75, 97, 71, 67, 96, 85, 72,
+  82, 105, 86, 81, 70, 80, 78, 81, 87, 89,
+  91, 72, 78, 88, 96, 102, 73, 82, 78, 90,
+  89, 80, 79, 82, 84, 93, 101, 100, 77, 93,
+  75, 79, 104, 80, 69, 82, 104, 82, 72, 94,
+  82, 64, 74, 82, 90, 91, 87, 77, 87, 80,
+  92, 73, 87, 81, 82, 79, 75, 74, 91, 91,
+  81, 89, 83, 85, 85, 100, 96, 90, 84, 91,
+  82, 88, 86, 82, 100, 84, 91, 99, 80, 73,
+  87, 78, 97, 98, 77, 81, 77, 73, 76, 71,
+  74, 93, 84, 71, 68, 79, 86, 84, 73, 97,
+  98, 108, 74, 90, 73, 89, 98, 79, 89, 93,
+  83, 69, 85, 77, 60, 91, 87, 77, 69, 67,
+  84, 75, 67, 102, 77, 86, 86, 68, 80, 111,
+  88, 79, 70, 81, 80, 69, 83, 75, 96, 90,
+  91, 86, 92, 127, 88, 87, 88, 80, 93, 79,
+  71, 88, 68, 80, 69, 77, 75, 95, 73, 77,
+  100, 79, 68, 79, 64, 82, 74, 79, 74, 60,
+  64, 79, 102, 120, 93, 79, 78, 76, 106, 74,
+  78, 75, 75, 72, 72, 77, 79, 84, 82, 93,
+  85, 76, 97, 95, 87, 71, 101, 99, 76, 90,
+  77, 79, 104, 92, 91, 91, 84, 86, 102, 69,
+  115, 106, 82, 112, 79, 81, 79, 80, 72, 108,
+  87, 72, 87, 75, 102, 89, 67, 117, 100, 92,
+  76, 87, 67, 81, 99, 85, 76, 94, 69, 64,
+  73, 74, 73, 99, 83, 76, 74, 58, 77, 91,
+  69, 135, 88, 100, 91, 72, 87, 140, 98, 68,
+  70, 73, 68, 71, 83, 72, 85, 102, 99, 93,
+  97, 149, 89, 83, 84, 73, 83, 73, 73, 99,
+  85, 81, 78, 93, 77, 83, 74, 75, 105, 82,
+  71, 76, 102, 76, 72, 99, 84, 63, 73, 76,
+  90, 78, 92, 82, 76, 80, 92, 75, 82, 90,
+  84, 91, 76, 95, 89, 78, 84, 90, 79, 89,
+  85, 89, 87, 90, 85, 90, 80, 98, 88, 85,
+  101, 79, 91, 94, 79, 96, 82, 84, 101, 99,
+  75, 80, 77, 70, 81, 73, 75, 90, 85, 71,
+  96, 78, 88, 85, 64, 93, 95, 83, 90, 89,
+  77, 89, 93, 94, 89, 93, 81, 71, 84, 80,
+  64, 92, 85, 79, 65, 65, 83, 77, 87, 87,
+  78, 94, 86, 70, 83, 104, 91, 77, 72, 82,
+  76, 70, 83, 96, 79, 86, 79, 88, 90, 121,
+  81, 90, 90, 79, 92, 75, 70, 87, 90, 88,
+  71, 70, 83, 78, 105, 82, 80, 69, 79, 84,
+  81, 90, 90, 87, 91, 100, 81, 90, 88, 85,
+  75, 93, 80, 85, 84, 73, 78, 76, 91, 87,
+  97, 77, 82, 79, 85, 82, 78, 80, 91, 68,
+  92, 84, 82, 85, 84, 93, 95, 85, 81, 82,
+  76, 92, 78, 90, 95, 91, 78, 86, 83, 92,
+  93, 73, 77, 91, 91, 88, 81, 85, 81, 80,
+  94, 84, 91, 78, 77, 77, 90, 91, 88, 88,
+  79, 74, 96, 77, 91, 77, 79, 85, 82, 81,
+  84, 90, 82, 96, 88, 83, 84, 82, 74, 90,
+  88, 84, 89, 90, 80, 89, 76, 78, 92, 99,
+  83, 89, 88, 100, 78, 89, 83, 86, 86, 88,
+  76, 82, 82, 86, 91, 86, 78, 92, 85, 87,
+  74, 83, 94, 84, 94, 77, 81, 75, 74, 101,
+  86, 94, 76, 69, 92, 90, 89, 88, 66, 101,
+  87, 85, 83, 78, 77, 69, 86, 86, 78, 79,
+  76, 82, 83, 86, 74, 65, 85, 51, 76, 83,
+  76, 89, 93, 87, 96, 72, 91, 91, 85, 74,
+  94, 83, 100, 80, 92, 85, 85, 92, 93, 76,
+  65, 63, 85, 76, 80, 79, 73, 79, 102, 83,
+  84, 82, 72, 75, 85, 70, 89, 85, 81, 70,
+  81, 83, 84, 94, 85, 84, 84, 84, 82, 88,
+  92, 69, 85, 80, 77, 83, 75, 78, 78, 83,
+  80, 89, 79, 87, 80, 71, 82, 86, 80, 90,
+  75, 99, 87, 83, 85, 86, 83, 85, 85, 82,
+  85, 83, 82, 78, 84, 81, 94, 87, 75, 95,
+  85, 84, 94, 88, 80, 73, 80, 112, 70, 87,
+  71, 62, 90, 87, 72, 88, 87, 101, 87, 82,
+  95, 84, 82, 80, 81, 92, 68, 76, 88, 99,
+  102, 89, 82, 75, 84, 63, 80, 85, 78, 96,
+  83, 102, 88, 70, 99, 96, 89, 68, 106, 85,
+  93, 70, 98, 84, 85, 80, 88, 70, 67, 65,
+  78, 73, 83, 79, 94, 95, 96, 94, 77, 80,
+  74, 80, 82, 78, 90, 87, 83, 87, 73, 90,
+  88, 102, 90, 80, 88, 91, 87, 80, 99, 70,
+  88, 76, 86, 92, 85, 93, 86, 82, 80, 91,
+  78, 87, 76, 70, 89, 75, 75, 96, 80, 96,
+  85, 85, 78, 94, 81, 82, 76, 79, 95, 91,
+  84, 83, 88, 88, 80, 87, 73, 79, 76, 79,
+  92, 82, 75, 85, 85, 112, 85, 95, 93, 87,
+  91, 85, 90, 85, 86, 100, 84, 86, 81, 82,
+  89, 74, 77, 87, 76, 68, 71, 76, 84, 86,
+  79, 92, 83, 68, 80, 81, 76, 91, 84, 90,
+  89, 77, 74, 89, 90, 72, 86, 66, 89, 67,
+  85, 81, 83, 78, 88, 54, 66, 61, 94, 81,
+  73, 100, 62, 78, 92, 81, 81, 85, 73, 79,
+  72, 85, 91, 86, 89, 75, 78, 85, 95, 88,
+  83, 87, 86, 78, 80, 93, 95, 77, 82, 81,
+  75, 84, 75, 71, 80, 81, 84, 75, 83, 87,
+  74, 71, 87, 76, 81, 95, 83, 103, 88, 84,
+  77, 95, 88, 86, 84, 80, 89, 79, 87, 85,
+  76, 69, 124, 86, 73, 94, 64, 76, 95, 88,
+  68, 77, 80, 143, 77, 75, 79, 73, 88, 83,
+  83, 92, 114, 99, 88, 76, 92, 79, 146, 82,
+  77, 86, 54, 69, 68, 79, 97, 78, 68, 74,
+  91, 61, 64, 80, 81, 93, 94, 96, 80, 73,
+  74, 109, 94, 58, 97, 46, 92, 53, 89, 75,
+  94, 84, 85, 51, 46, 52, 80, 71, 79, 111,
+  41, 74, 85, 88, 82, 72, 74, 80, 79, 69,
+  84, 83, 86, 88, 70, 91, 90, 116, 80, 82,
+  73, 72, 84, 75, 91, 63, 79, 73, 64, 75,
+  79, 60, 76, 81, 75, 86, 90, 87, 81, 69,
+  93, 67, 72, 91, 97, 96, 120, 74, 71, 92,
+  76, 86, 68, 72, 91, 83, 78, 87, 77, 64,
+  92, 78, 81, 87, 76, 81, 88, 88, 77, 76,
+  91, 101, 90, 74, 78, 83, 87, 85, 84, 80,
+  102, 92, 103, 99, 82, 78, 114, 86, 79, 93,
+  67, 73, 93, 88, 112, 83, 80, 78, 85, 71,
+  78, 84, 89, 100, 84, 89, 75, 79, 87, 93,
+  95, 74, 99, 66, 88, 64, 88, 88, 93, 88,
+  89, 59, 62, 63, 81, 87, 79, 82, 74, 88,
+  85, 92, 91, 82, 72, 78, 84, 88, 87, 88,
+  86, 93, 72, 83, 91, 88, 75, 99, 87, 74,
+  86, 87, 92, 81, 94, 90, 78, 78, 82, 72,
+  87, 81, 87, 88, 72, 91, 79, 70, 88, 67,
+  81, 88, 93, 80, 79, 84, 69, 83, 83, 81,
+  75, 79, 101, 87, 89, 93, 87, 86, 70, 81,
+  82, 94, 74, 83, 96, 94, 77, 75, 81, 112,
+  65, 79, 89, 65, 89, 85, 75, 94, 82, 93,
+  77, 84, 88, 90, 88, 77, 79, 89, 58, 66,
+  88, 91, 94, 85, 90, 91, 82, 71, 82, 77,
+  75, 83, 79, 93, 93, 69, 87, 85, 87, 70,
+  99, 80, 86, 67, 101, 84, 87, 86, 94, 67,
+  74, 67, 83, 81, 82, 93, 93, 83, 92, 84,
+  82, 87, 74, 108, 91, 75, 92, 79, 93, 80,
+  75, 93, 88, 108, 84, 79, 92, 81, 87, 81,
+  100, 71, 79, 79, 85, 93, 86, 88, 97, 82,
+  87, 75, 79, 103, 90, 69, 72, 78, 83, 94,
+  88, 100, 96, 80, 80, 93, 85, 92, 81, 78,
+  94, 85, 86, 89, 74, 76, 85, 81, 74, 97,
+  82, 82, 95, 89, 79, 74, 78, 96, 82, 76,
+  85, 79, 94, 82, 82, 79, 85, 91, 87, 95,
+  81, 80, 102, 70, 89, 82, 67, 86, 81, 86,
+  84, 88, 76, 75, 92, 62, 68, 75, 81, 88,
+  91, 89, 86, 76, 98, 81, 94, 76, 96, 72,
+  89, 78, 88, 92, 90, 90, 91, 79, 67, 60,
+  82, 91, 86, 76, 71, 73, 95, 91, 90, 87,
+  83, 86, 95, 67, 95, 85, 89, 79, 78, 89,
+  85, 90, 89, 86, 96, 78, 90, 86, 99, 71,
+  87, 88, 77, 87, 82, 84, 86, 80, 84, 87,
+  77, 102, 87, 73, 77, 86, 77, 80, 90, 81,
+  87, 78, 77, 79, 79, 84, 77, 81, 88, 91,
+  85, 86, 85, 82, 68, 78, 81, 81, 95, 89,
+  75, 85, 82, 82, 80, 70, 98, 85, 86, 96,
+  79, 90, 86, 78, 89, 78, 81, 96, 80, 73,
+  61, 67, 89, 86, 96, 86, 97, 87, 81, 84,
+  83, 77, 78, 66, 83, 84, 82, 89, 81, 86,
+  88, 84, 86, 78, 87, 88, 87, 81, 81, 93,
+  73, 81, 86, 93, 86, 82, 84, 83, 90, 81,
+  90, 83, 86, 80, 79, 93, 90, 77, 82, 90,
+  92, 79, 99, 86, 83, 76, 85, 85, 80, 74,
+  78, 86, 96, 76, 93, 92, 80, 80, 94, 90,
+  81, 79, 74, 93, 84, 85, 73, 85, 63, 96,
+  62, 70, 84, 88, 75, 83, 98, 77, 56, 88,
+  73, 76, 72, 82, 69, 79, 78, 91, 80, 90,
+  95, 94, 79, 93, 88, 81, 85, 89, 73, 82,
+  84, 85, 79, 81, 81, 77, 82, 84, 116, 76,
+  90, 83, 77, 89, 83, 86, 75, 119, 96, 76,
+  72, 84, 81, 81, 85, 78, 81, 80, 82, 84,
+  88, 79, 82, 88, 92, 93, 82, 79, 88, 77,
+  82, 71, 77, 81, 80, 81, 80, 75, 83, 81,
+  74, 73, 90, 82, 89, 86, 84, 75, 88, 73,
+  79, 77, 83, 68, 85, 72, 84, 79, 80, 82,
+  84, 75, 78, 88, 81, 79, 82, 78, 90, 82,
+  71, 88, 87, 85, 82, 93, 115, 75, 78, 99,
+  77, 84, 84, 77, 76, 81, 73, 84, 84, 85,
+  84, 92, 88, 81, 88, 87, 86, 97, 81, 80,
+  68, 89, 81, 105, 75, 82, 94, 72, 93, 85,
+  80, 95, 87, 82, 76, 99, 75, 104, 90, 87,
+  83, 84, 78, 75, 86, 75, 139, 80, 85, 84,
+  82, 94, 84, 79, 76, 130, 77, 77, 67, 75,
+  87, 84, 80, 88, 76, 77, 82, 75, 89, 78,
+  83, 83, 97, 96, 78, 81, 91, 78, 84, 67,
+  74, 83, 74, 84, 83, 74, 81, 83, 73, 76,
+  94, 79, 90, 84, 78, 71, 82, 73, 79, 78,
+  90, 69, 80, 78, 91, 81, 78, 89, 82, 73,
+  81, 84, 79, 78, 81, 81, 86, 77, 76, 88,
+  87, 80, 82, 93, 133, 76, 80, 102, 76, 81,
+  115, 79, 74, 76, 76, 89, 79, 83, 83, 91,
+  101, 85, 88, 85, 89, 105, 88, 84, 75, 85,
+  77, 121, 76, 79, 99, 78, 92, 83, 84, 85,
+  88, 77, 86, 90, 73, 80, 86, 84, 82, 82,
+  81, 77, 83, 83, 112, 81, 87, 82, 83, 90,
+  90, 86, 79, 114, 93, 82, 69, 78, 83, 82,
+  84, 88, 79, 78, 79, 82, 84, 76, 86, 87,
+  95, 87, 78, 79, 91, 80, 76, 72, 78, 76,
+  79, 87, 84, 75, 81, 81, 73, 73, 89, 82,
+  92, 87, 84, 75, 90, 82, 84, 79, 82, 75,
+  84, 72, 83, 80, 76, 80, 85, 74, 75, 79,
+  79, 80, 76, 78, 89, 81, 71, 80, 91, 88,
+  72, 93, 109, 72, 86, 93, 78, 77, 82, 78,
+  75, 82, 75, 83, 84, 86, 81, 90, 93, 81,
+  85, 87, 82, 94, 80, 78, 80, 88, 79, 103,
+  77, 85, 93, 71, 91, 91, 77, 100, 89, 73,
+  83, 83, 72, 95, 92, 82, 75, 80, 79, 80,
+  85, 86, 127, 79, 92, 86, 85, 90, 84, 82,
+  73, 126, 79, 77, 70, 85, 88, 85, 75, 76,
+  85, 77, 82, 77, 86, 72, 81, 83, 86, 90,
+  82, 79, 88, 77, 78, 73, 76, 81, 75, 76,
+  83, 71, 86, 79, 74, 72, 88, 78, 94, 87,
+  84, 76, 89, 74, 83, 70, 78, 70, 87, 78,
+  83, 76, 87, 79, 81, 75, 78, 86, 84, 78,
+  80, 77, 85, 78, 67, 84, 80, 79, 87, 90,
+  119, 79, 83, 90, 87, 84, 101, 77, 71, 80,
+  74, 85, 87, 86, 79, 88, 86, 81, 86, 92,
+  89, 100, 85, 87, 79, 91, 85, 116, 72, 82,
+  93, 78, 99, 84, 83, 116, 94, 78, 72, 96,
+  78, 134, 101, 89, 81, 82, 79, 76, 90, 75,
+  172, 82, 88, 95, 81, 96, 89, 76, 76, 147,
+  59, 78, 68, 80, 100, 93, 72, 94, 91, 76,
+  85, 67, 82, 75, 79, 74, 88, 89, 77, 74,
+  88, 81, 76, 67, 75, 86, 74, 79, 93, 70,
+  84, 83, 76, 70, 93, 86, 86, 86, 78, 76,
+  86, 73, 74, 72, 85, 69, 82, 97, 97, 80,
+  78, 82, 78, 75, 92, 81, 88, 69, 80, 85,
+  81, 79, 78, 79, 76, 74, 101, 83, 150, 80,
+  79, 95, 88, 79, 152, 79, 71, 86, 78, 89,
+  91, 86, 76, 81, 105, 80, 87, 88, 84, 115,
+  93, 90, 86, 93, 84, 141, 76, 76, 105, 89,
+  86, 80, 91, 94, 89, 83, 84, 86, 73, 95,
+  94, 84, 79, 84, 79, 80, 85, 90, 126, 80,
+  90, 84, 80, 90, 91, 83, 76, 122, 78, 78,
+  73, 84, 91, 88, 82, 95, 81, 75, 78, 75,
+  84, 72, 89, 83, 88, 91, 81, 72, 89, 82,
+  71, 71, 78, 80, 74, 82, 85, 72, 79, 83,
+  77, 76, 89, 81, 94, 86, 85, 78, 89, 80,
+  82, 73, 77, 77, 83, 77, 83, 77, 79, 77,
+  81, 72, 79, 82, 83, 78, 81, 76, 84, 79,
+  69, 82, 81, 80, 75, 92, 113, 76, 86, 88,
+  88, 82, 94, 79, 71, 78, 76, 81, 86, 88,
+  79, 90, 92, 79, 83, 94, 77, 94, 84, 87,
+  84, 91, 81, 111, 76, 87, 95, 77, 88, 90,
+  81, 89, 85, 77, 90, 71, 76, 79, 89, 81,
+  81, 77, 78, 79, 87, 90, 107, 77, 83, 82,
+  80, 96, 90, 80, 75, 116, 98, 82, 75, 89,
+  81, 85, 77, 81, 84, 77, 87, 75, 86, 86,
+  81, 84, 89, 86, 86, 81, 82, 80, 83, 76,
+  82, 75, 75, 79, 82, 74, 89, 83, 76, 77,
+  85, 81, 91, 85, 78, 75, 88, 79, 82, 77,
+  71, 77, 89, 78, 76, 74, 88, 87, 80, 82,
+  73, 78, 88, 79, 77, 78, 85, 77, 67, 82,
+  87, 87, 84, 85, 110, 80, 89, 96, 81, 85,
+  74, 74, 72, 77, 73, 83, 73, 86, 82, 96,
+  81, 84, 83, 94, 82, 94, 85, 80, 82, 90,
+  81, 85, 75, 94, 82, 72, 89, 86, 91, 96,
+  93, 77, 83, 74, 80, 91, 85, 80, 78, 81,
+  88, 79, 88, 88, 115, 79, 85, 84, 80, 101,
+  93, 79, 76, 118, 78, 78, 68, 86, 84, 91,
+  76, 86, 83, 78, 88, 71, 84, 84, 82, 81,
+  86, 89, 86, 83, 87, 81, 81, 72, 82, 79,
+  71, 78, 87, 74, 88, 84, 73, 75, 87, 77,
+  94, 84, 78, 72, 94, 87, 80, 71, 73, 82,
+  93, 83, 80, 79, 85, 89, 80, 81, 74, 76,
+  87, 73, 83, 78, 84, 77, 69, 81, 86, 80,
+  91, 82, 116, 77, 90, 95, 86, 78, 92, 75,
+  72, 84, 75, 84, 74, 87, 84, 95, 88, 85,
+  83, 94, 79, 94, 83, 79, 84, 91, 81, 96,
+  79, 103, 86, 74, 86, 85, 88, 83, 86, 74,
+  92, 74, 76, 81, 90, 84, 80, 82, 80, 79,
+  85, 89, 107, 79, 84, 85, 80, 94, 89, 81,
+  74, 111, 94, 74, 81, 83, 80, 89, 82, 81,
+  83, 76, 79, 77, 86, 88, 82, 83, 91, 88,
+  83, 83, 81, 81, 81, 77, 79, 72, 75, 77,
+  85, 75, 87, 86, 79, 79, 87, 81, 91, 87,
+  79, 76, 90, 82, 81, 78, 74, 82, 86, 80,
+  78, 81, 83, 86, 81, 83, 71, 75, 89, 81,
+  82, 76, 86, 74, 65, 81, 88, 87, 80, 88,
+  110, 81, 90, 94, 83, 79, 72, 74, 73, 76,
+  75, 81, 73, 90, 87, 95, 83, 80, 85, 97,
+  74, 92, 85, 77, 85, 90, 77, 87, 79, 100,
+  86, 72, 89, 77, 78, 93, 66, 85, 95, 85,
+  69, 75, 88, 76, 69, 74, 89, 85, 77, 85,
+  84, 92, 82, 76, 81, 80, 76, 90, 90, 75,
+  90, 102, 88, 85, 84, 77, 80, 70, 72, 80,
+  73, 78, 76, 89, 83, 99, 76, 85, 84, 89,
+  93, 105, 71, 82, 90, 99, 84, 83, 71, 105,
+  73, 80, 85, 81, 72, 81, 89, 109, 100, 74,
+  82, 86, 81, 91, 80, 80, 88, 101, 95, 79,
+  71, 98, 108, 61, 77, 84, 92, 76, 81, 68,
+  100, 70, 91, 86, 79, 73, 92, 83, 85, 80,
+  78, 77, 94, 87, 79, 85, 87, 76, 80, 113,
+  75, 69, 86, 68, 75, 85, 85, 94, 95, 80,
+  87, 73, 56, 78, 71, 77, 113, 87, 74, 95,
+  85, 81, 76, 87, 63, 80, 98, 90, 72, 75,
+  93, 78, 72, 71, 90, 88, 82, 81, 88, 99,
+  80, 74, 82, 82, 80, 97, 90, 78, 81, 87,
+  85, 85, 85, 76, 85, 84, 74, 84, 74, 92,
+  78, 92, 85, 100, 81, 79, 83, 83, 91, 111,
+  65, 79, 93, 102, 89, 80, 75, 98, 76, 80,
+  78, 84, 67, 82, 82, 106, 95, 82, 77, 84,
+  79, 92, 85, 81, 91, 108, 96, 85, 77, 103,
+  106, 57, 75, 83, 102, 77, 84, 65, 103, 74,
+  92, 84, 82, 76, 87, 84, 91, 81, 83, 79,
+  99, 96, 86, 81, 89, 72, 81, 114, 82, 69,
+  85, 68, 79, 84, 88, 89, 85, 79, 88, 76,
+  60, 74, 74, 79, 123, 92, 73, 97, 89, 77,
+  77, 88, 68, 82, 94, 92, 66, 77, 86, 77,
+  72, 72, 91, 82, 78, 82, 82, 103, 81, 80,
+  87, 82, 75, 88, 96, 75, 82, 82, 87, 81,
+  86, 75, 94, 83, 72, 81, 78, 78, 79, 87,
+  89, 91, 79, 80, 80, 83, 91, 103, 72, 77,
+  92, 98, 82, 83, 70, 104, 77, 77, 85, 82,
+  71, 84, 92, 102, 96, 76, 81, 87, 79, 90,
+  82, 82, 86, 91, 91, 92, 79, 95, 106, 64,
+  80, 80, 92, 74, 82, 73, 96, 70, 91, 82,
+  80, 74, 81, 81, 84, 81, 87, 81, 93, 103,
+  79, 85, 86, 76, 82, 109, 81, 73, 83, 70,
+  76, 80, 84, 86, 84, 78, 87, 77, 65, 76,
+  69, 79, 107, 88, 77, 97, 96, 80, 75, 86,
+  75, 90, 95, 81, 77, 75, 91, 82, 79, 74,
+  87, 82, 74, 84, 80, 99, 75, 81, 76, 82,
+  80, 86, 84, 70, 77, 88, 84, 76, 84, 83,
+  87, 72, 73, 84, 77, 76, 81, 82, 85, 97,
+  81, 87, 75, 95, 95, 98, 69, 82, 97, 98,
+  88, 82, 78, 106, 73, 95, 94, 75, 76, 86,
+  88, 109, 84, 76, 89, 87, 84, 97, 75, 68,
+  85, 103, 91, 83, 67, 92, 106, 65, 79, 85,
+  92, 78, 80, 64, 85, 75, 87, 80, 81, 79,
+  97, 84, 79, 88, 73, 82, 95, 84, 79, 86,
+  84, 83, 82, 114, 80, 70, 83, 68, 76, 89,
+  86, 87, 96, 78, 85, 80, 59, 80, 81, 75,
+  122, 80, 77, 85, 95, 82, 79, 79, 71, 82,
+  101, 88, 83, 72, 97, 83, 78, 76, 93, 92,
+  78, 86, 78, 108, 81, 80, 78, 88, 82, 95,
+  81, 72, 71, 75, 81, 82, 80, 80, 89, 86,
+  76, 90, 73, 91, 86, 86, 84, 100, 84, 82,
+  74, 88, 100, 107, 66, 86, 100, 103, 97, 77,
+  82, 100, 77, 105, 89, 77, 72, 88, 81, 106,
+  84, 85, 85, 86, 81, 100, 79, 71, 90, 106,
+  93, 83, 68, 95, 103, 67, 75, 79, 101, 81,
+  86, 59, 88, 75, 87, 79, 82, 83, 95, 87,
+  86, 85, 76, 83, 92, 92, 83, 84, 89, 80,
+  81, 115, 82, 70, 84, 68, 82, 87, 85, 84,
+  80, 77, 85, 81, 60, 78, 84, 76, 130, 84,
+  74, 84, 96, 77, 82, 83, 81, 88, 93, 92,
+  76, 77, 87, 83, 75, 77, 89, 80, 78, 83,
+  76, 111, 84, 87, 83, 85, 79, 88, 90, 71,
+  72, 80, 83, 80, 81, 76, 93, 83, 75, 83,
+  74, 80, 81, 80, 83, 91, 80, 82, 74, 92,
+  94, 96, 70, 84, 100, 101, 87, 81, 75, 108,
+  74, 86, 94, 77, 76, 89, 89, 105, 86, 74,
+  86, 89, 82, 91, 80, 70, 87, 92, 89, 95,
+  74, 93, 107, 71, 82, 75, 92, 76, 84, 72,
+  85, 70, 85, 80, 80, 80, 83, 84, 80, 91,
+  80, 81, 91, 98, 79, 86, 86, 80, 79, 108,
+  81, 73, 80, 71, 79, 79, 86, 80, 82, 76,
+  86, 81, 66, 78, 82, 75, 117, 80, 79, 83,
+  96, 79, 83, 88, 64, 88, 87, 77, 71, 80,
+  85, 89, 79, 73, 87, 81, 72, 77, 86, 92,
+  74, 75, 79, 86, 76, 82, 81, 73, 84, 87,
+  83, 78, 92, 84, 94, 71, 78, 82, 87, 66,
+  78, 89, 90, 94, 84, 87, 72, 96, 86, 109,
+  71, 89, 95, 95, 87, 85, 75, 96, 80, 89,
+  99, 76, 77, 84, 88, 105, 80, 74, 89, 91,
+  85, 100, 75, 73, 78, 100, 90, 87, 78, 93,
+  107, 70, 77, 78, 86, 79, 79, 72, 88, 79,
+  88, 83, 85, 73, 95, 85, 78, 90, 75, 77,
+  104, 81, 76, 87, 85, 83, 81, 105, 77, 76,
+  87, 72, 74, 86, 80, 85, 83, 77, 80, 85,
+  68, 74, 71, 77, 110, 80, 77, 90, 95, 81,
+  90, 84, 65, 85, 92, 82, 74, 75, 89, 89,
+  78, 78, 86, 89, 74, 75, 86, 102, 84, 75,
+  83, 87, 76, 89, 80, 74, 79, 79, 87, 82,
+  87, 86, 84, 81, 80, 87, 78, 80, 76, 98,
+  87, 99, 87, 83, 73, 93, 89, 109, 70, 93,
+  95, 98, 93, 82, 82, 91, 81, 88, 97, 77,
+  77, 85, 86, 109, 79, 75, 86, 93, 81, 100,
+  81, 77, 80, 95, 89, 88, 77, 99, 104, 73,
+  73, 78, 92, 84, 82, 65, 94, 80, 86, 84,
+  83, 74, 94, 88, 81, 87, 78, 78, 101, 81,
+  81, 86, 85, 78, 76, 107, 76, 74, 90, 71,
+  79, 84, 81, 80, 80, 77, 82, 84, 69, 75,
+  70, 77, 118, 79, 78, 84, 95, 79, 89, 88,
+  70, 86, 87, 85, 70, 79, 82, 85, 75, 79,
+  83, 74, 71, 79, 84, 104, 85, 75, 83, 89,
+  72, 86, 86, 73, 82, 86, 89, 81, 89, 77,
+  94, 79, 82, 81, 74, 70, 75, 89, 80, 91,
+  83, 83, 76, 90, 88, 106, 72, 86, 96, 94,
+  82, 86, 76, 98, 77, 82, 100, 78, 77, 86,
+  87, 105, 81, 73, 85, 94, 85, 96, 82, 73,
+  80, 94, 89, 89, 82, 94, 108, 74, 78, 79,
+  86, 80, 85, 79, 91, 76, 90, 82, 84, 73,
+  83, 86, 80, 91, 78, 75, 97, 87, 75, 87,
+  86, 81, 78, 102, 79, 76, 85, 74, 78, 77,
+  81, 84, 84, 77, 81, 86, 74, 77, 73, 77,
+  110, 80, 76, 87, 77, 76, 84, 67, 64, 80,
+  78, 96, 76, 88, 92, 75, 84, 95, 63, 80,
+  84, 94, 77, 91, 92, 86, 97, 87, 74, 81,
+  83, 92, 94, 76, 93, 74, 84, 83, 78, 95,
+  88, 79, 80, 68, 88, 72, 82, 77, 96, 75,
+  63, 86, 86, 86, 82, 94, 78, 79, 89, 88,
+  83, 82, 85, 89, 68, 78, 84, 87, 63, 83,
+  91, 86, 80, 99, 87, 73, 92, 89, 74, 84,
+  73, 77, 72, 77, 85, 84, 78, 83, 75, 90,
+  86, 89, 69, 91, 91, 90, 76, 92, 104, 86,
+  84, 74, 87, 104, 89, 79, 83, 80, 74, 71,
+  77, 80, 77, 82, 94, 95, 95, 78, 77, 77,
+  89, 74, 79, 91, 87, 82, 80, 95, 82, 90,
+  94, 83, 83, 81, 87, 67, 62, 89, 75, 96,
+  79, 87, 90, 71, 84, 88, 65, 72, 92, 97,
+  83, 84, 85, 72, 92, 87, 92, 75, 84, 97,
+  104, 79, 98, 81, 84, 80, 83, 83, 96, 83,
+  89, 68, 90, 78, 87, 76, 94, 78, 73, 86,
+  79, 85, 82, 97, 78, 83, 98, 86, 77, 78,
+  74, 87, 70, 71, 77, 79, 57, 80, 87, 78,
+  72, 102, 88, 72, 78, 88, 78, 75, 77, 86,
+  67, 77, 92, 83, 80, 84, 76, 92, 84, 93,
+  76, 87, 75, 106, 71, 88, 103, 79, 98, 75,
+  82, 103, 91, 77, 79, 77, 75, 65, 83, 70,
+  84, 83, 94, 97, 97, 82, 80, 78, 90, 73,
+  84, 89, 80, 81, 80, 87, 74, 91, 100, 82,
+  76, 80, 86, 64, 68, 97, 76, 96, 76, 90,
+  88, 78, 82, 77, 64, 84, 87, 83, 72, 87,
+  89, 86, 81, 87, 82, 82, 82, 90, 80, 76,
+  93, 89, 81, 93, 77, 83, 93, 77, 90, 70,
+  91, 73, 88, 76, 95, 83, 69, 80, 84, 84,
+  74, 89, 75, 83, 87, 78, 81, 84, 85, 88,
+  75, 85, 81, 84, 71, 88, 85, 90, 78, 85,
+  85, 74, 94, 87, 75, 86, 79, 87, 70, 82,
+  87, 83, 88, 89, 74, 85, 82, 86, 77, 94,
+  88, 103, 78, 96, 109, 90, 76, 77, 73, 105,
+  85, 72, 85, 78, 76, 73, 74, 82, 78, 83,
+  100, 93, 95, 89, 83, 85, 85, 77, 81, 95,
+  78, 84, 77, 93, 78, 89, 91, 82, 100, 85,
+  88, 76, 78, 78, 85, 89, 72, 86, 92, 73,
+  89, 104, 69, 72, 92, 100, 89, 92, 74, 82,
+  113, 84, 88, 84, 81, 91, 107, 87, 88, 90,
+  79, 83, 77, 98, 103, 84, 77, 73, 91, 73,
+  75, 77, 69, 83, 98, 85, 88, 81, 84, 89,
+  75, 84, 85, 83, 73, 82, 76, 89, 78, 75,
+  99, 77, 67, 67, 92, 84, 101, 101, 77, 75,
+  80, 84, 82, 75, 78, 87, 80, 80, 89, 85,
+  75, 85, 79, 98, 91, 89, 73, 73, 72, 83,
+  81, 90, 86, 66, 92, 75, 104, 85, 87, 87,
+  85, 77, 86, 59, 88, 86, 84, 79, 72, 80,
+  90, 88, 84, 81, 103, 81, 92, 80, 84, 68,
+  93, 87, 87, 81, 92, 75, 110, 91, 85, 81,
+  84, 81, 87, 90, 70, 79, 91, 62, 94, 94,
+  72, 65, 98, 99, 97, 87, 77, 70, 85, 86,
+  106, 79, 78, 88, 119, 89, 89, 117, 84, 84,
+  80, 88, 106, 93, 85, 80, 88, 69, 71, 82,
+  62, 85, 123, 85, 83, 79, 89, 95, 74, 94,
+  75, 77, 60, 78, 59, 92, 86, 72, 96, 78,
+  63, 63, 97, 90, 103, 82, 85, 68, 67, 75,
+  105, 64, 85, 90, 75, 78, 98, 85, 75, 84,
+  87, 101, 94, 87, 80, 67, 66, 87, 74, 94,
+  73, 65, 96, 77, 100, 82, 75, 95, 83, 77,
+  97, 46, 101, 78, 88, 76, 76, 76, 88, 91,
+  78, 73, 88, 80, 99, 69, 79, 61, 89, 82,
+  78, 81, 102, 71, 90, 90, 79, 72, 82, 110,
+  83, 91, 74, 87, 90, 79, 86, 73, 66, 75,
+  96, 93, 87, 89, 87, 82, 73, 86, 88, 82,
+  83, 91, 95, 76, 87, 104, 79, 90, 77, 82,
+  105, 82, 85, 76, 94, 75, 73, 79, 76, 90,
+  93, 85, 87, 80, 76, 87, 75, 87, 89, 84,
+  74, 81, 73, 83, 77, 73, 98, 77, 71, 74,
+  84, 85, 89, 83, 95, 72, 86, 87, 94, 81,
+  81, 94, 75, 82, 91, 83, 83, 84, 80, 91,
+  92, 86, 82, 75, 79, 104, 81, 89, 103, 71,
+  89, 80, 75, 88, 90, 88, 84, 76, 82, 69,
+  85, 86, 83, 84, 83, 81, 91, 95, 88, 85,
+  79, 81, 88, 80, 79, 70, 85, 87, 85, 81,
+  92, 74, 83, 84, 92, 82, 91, 84, 85, 97,
+  64, 85, 91, 70, 77, 85, 78, 75, 96, 83,
+  77, 86, 71, 83, 80, 79, 102, 85, 82, 83,
+  86, 77, 80, 94, 84, 96, 97, 97, 80, 82,
+  80, 81, 99, 71, 87, 82, 68, 82, 107, 76,
+  89, 78, 86, 81, 73, 92, 80, 78, 69, 86,
+  88, 82, 80, 84, 89, 78, 88, 78, 97, 91,
+  110, 76, 75, 79, 87, 86, 71, 83, 83, 101,
+  89, 88, 89, 84, 86, 90, 83, 92, 83, 88,
+  78, 74, 77, 81, 97, 90, 69, 82, 80, 84,
+  92, 91, 80, 89, 85, 80, 88, 83, 86, 96,
+  75, 77, 70, 83, 84, 92, 79, 83, 86, 87,
+  87, 90, 79, 72, 89, 82, 96, 78, 83, 75,
+  82, 86, 77, 87, 95, 74, 87, 95, 53, 72,
+  82, 62, 79, 88, 83, 69, 96, 82, 78, 84,
+  81, 75, 77, 78, 104, 80, 74, 74, 95, 90,
+  82, 106, 88, 96, 85, 85, 88, 89, 86, 79,
+  102, 70, 75, 93, 64, 77, 114, 87, 87, 70,
+  89, 74, 67, 98, 57, 72, 56, 82, 82, 83,
+  84, 81, 90, 84, 75, 80, 100, 95, 117, 61,
+  74, 64, 80, 79, 84, 70, 83, 93, 88, 84,
+  91, 83, 82, 83, 90, 102, 88, 85, 72, 65,
+  75, 84, 97, 85, 58, 81, 76, 85, 110, 96,
+  76, 76, 81, 79, 94, 85, 99, 95, 67, 74,
+  71, 80, 78, 84, 78, 76, 77, 89, 95, 86,
+  80, 61, 79, 83, 90, 77, 85, 73, 84, 90,
+  69, 84, 86, 88, 84, 92, 65, 83, 92, 78,
+  80, 77, 75, 71, 100, 78, 78, 90, 92, 76,
+  82, 82, 82, 83, 81, 80, 80, 96, 80, 97,
+  86, 85, 84, 88, 81, 82, 81, 80, 100, 74,
+  70, 85, 71, 84, 91, 108, 86, 80, 84, 80,
+  72, 92, 83, 83, 69, 85, 88, 76, 80, 73,
+  92, 78, 82, 82, 89, 92, 109, 76, 82, 73,
+  90, 85, 86, 84, 81, 87, 82, 87, 87, 87,
+  83, 81, 77, 94, 94, 89, 81, 74, 83, 85,
+  97, 91, 75, 88, 80, 85, 102, 88, 84, 80,
+  81, 77, 84, 88, 87, 92, 72, 80, 74, 77,
+  82, 86, 86, 86, 82, 82, 83, 89, 92, 71,
+  90, 79, 92, 80, 85, 78, 82, 78, 100, 87,
+  84, 72, 80, 78, 82, 90, 104, 83, 84, 97,
+  73, 82, 76, 86, 77, 84, 70, 88, 82, 83,
+  75, 75, 90, 74, 90, 75, 94, 89, 91, 88,
+  85, 85, 73, 83, 80, 79, 75, 80, 67, 87,
+  91, 79, 74, 76, 70, 90, 84, 103, 86, 72,
+  84, 71, 73, 69, 98, 79, 89, 81, 73, 83,
+  89, 116, 86, 83, 102, 86, 81, 78, 87, 80,
+  93, 86, 99, 99, 86, 82, 88, 83, 85, 91,
+  92, 87, 90, 85, 80, 81, 87, 85, 75, 80,
+  84, 107, 72, 64, 97, 87, 77, 84, 82, 95,
+  78, 85, 71, 89, 72, 90, 86, 80, 81, 79,
+  87, 119, 83, 84, 77, 78, 73, 107, 82, 77,
+  79, 89, 99, 86, 79, 81, 87, 87, 86, 78,
+  80, 75, 89, 98, 110, 77, 79, 91, 77, 82,
+  74, 96, 82, 78, 70, 77, 82, 74, 74, 69,
+  88, 79, 84, 75, 88, 97, 90, 75, 80, 77,
+  77, 76, 100, 71, 78, 84, 70, 83, 98, 73,
+  61, 77, 69, 88, 96, 88, 86, 72, 85, 85,
+  63, 75, 97, 72, 90, 89, 75, 74, 81, 138,
+  89, 72, 87, 72, 84, 77, 86, 75, 80, 86,
+  109, 80, 92, 84, 86, 84, 72, 82, 84, 79,
+  77, 78, 80, 82, 86, 93, 79, 80, 79, 118,
+  77, 68, 92, 85, 80, 104, 93, 95, 76, 84,
+  73, 87, 77, 88, 80, 78, 76, 82, 87, 123,
+  74, 86, 73, 81, 79, 111, 75, 77, 78, 82,
+  102, 86, 83, 84, 86, 88, 90, 84, 82, 83,
+  83, 85, 101, 78, 87, 75, 76, 82, 74, 86,
+  77, 87, 68, 78, 75, 83, 87, 77, 89, 76,
+  86, 90, 87, 92, 91, 91, 81, 91, 77, 88,
+  99, 80, 77, 78, 75, 91, 91, 83, 79, 98,
+  76, 86, 84, 90, 87, 73, 86, 83, 74, 75,
+  94, 81, 87, 75, 74, 83, 86, 107, 79, 83,
+  96, 84, 99, 83, 85, 83, 95, 86, 90, 76,
+  87, 76, 95, 82, 79, 89, 88, 85, 75, 81,
+  81, 83, 86, 89, 80, 82, 84, 100, 76, 69,
+  92, 85, 78, 100, 79, 99, 78, 88, 70, 89,
+  76, 91, 82, 79, 86, 92, 78, 101, 81, 83,
+  76, 76, 80, 100, 87, 84, 85, 88, 96, 80,
+  75, 83, 84, 93, 82, 67, 77, 72, 82, 89,
+  103, 81, 87, 93, 81, 81, 83, 82, 72, 83,
+  76, 81, 76, 78, 81, 80, 77, 75, 93, 77,
+  85, 85, 93, 89, 88, 90, 68, 78, 94, 87,
+  86, 76, 69, 86, 77, 76, 69, 78, 76, 89,
+  82, 91, 84, 76, 81, 80, 80, 73, 96, 70,
+  78, 95, 74, 84, 75, 131, 79, 74, 106, 73,
+  94, 65, 86, 85, 95, 89, 96, 92, 98, 89,
+  86, 88, 80, 84, 86, 81, 87, 86, 71, 76,
+  85, 80, 83, 86, 80, 123, 77, 73, 98, 74,
+  75, 83, 78, 92, 76, 78, 73, 86, 65, 87,
+  77, 76, 80, 82, 70, 112, 80, 84, 67, 85,
+  73, 114, 81, 80, 71, 82, 102, 78, 78, 81,
+  81, 105, 83, 75, 69, 71, 99, 109, 105, 73,
+  66, 91, 100, 81, 96, 88, 75, 75, 72, 69,
+  81, 67, 88, 69, 83, 82, 87, 87, 60, 105,
+  97, 70, 84, 81, 65, 84, 93, 73, 76, 72,
+  67, 77, 79, 77, 58, 73, 75, 85, 83, 65,
+  89, 81, 75, 70, 77, 80, 81, 60, 76, 124,
+  80, 76, 70, 139, 72, 52, 115, 71, 76, 61,
+  110, 77, 85, 96, 129, 82, 93, 106, 81, 87,
+  69, 83, 68, 70, 79, 74, 65, 82, 85, 79,
+  76, 99, 89, 132, 87, 86, 86, 63, 75, 86,
+  98, 91, 82, 85, 68, 77, 67, 80, 70, 73,
+  76, 83, 69, 101, 87, 85, 49, 88, 80, 116,
+  75, 83, 69, 74, 113, 65, 79, 81, 90, 87,
+  86, 77, 76, 76, 77, 85, 101, 83, 90, 91,
+  79, 82, 84, 83, 72, 81, 71, 88, 68, 75,
+  93, 79, 81, 77, 92, 93, 93, 96, 94, 101,
+  83, 89, 74, 82, 95, 86, 90, 76, 79, 87,
+  78, 73, 74, 96, 77, 88, 81, 94, 84, 72,
+  84, 72, 78, 78, 97, 75, 83, 88, 81, 88,
+  74, 121, 78, 80, 103, 78, 84, 69, 82, 85,
+  92, 86, 83, 79, 92, 82, 91, 88, 77, 87,
+  89, 85, 82, 86, 75, 80, 79, 85, 87, 82,
+  80, 113, 77, 76, 88, 73, 79, 81, 79, 96,
+  75, 82, 72, 87, 68, 88, 88, 78, 81, 87,
+  79, 95, 90, 88, 73, 82, 80, 109, 81, 82,
+  80, 82, 96, 75, 83, 85, 77, 88, 87, 86,
+  80, 75, 73, 88, 92, 82, 87, 89, 74, 76,
+  85, 87, 79, 90, 79, 77, 79, 78, 86, 75,
+  90, 85, 88, 75, 86, 87, 97, 89, 95, 90,
+  78, 74, 88, 89, 99, 75, 93, 86, 79, 77,
+  80, 78, 77, 87, 86, 93, 78, 79, 87, 81,
+  88, 77, 79, 82, 78, 78, 87, 74, 91, 91,
+  76, 92, 101, 89, 99, 85, 83, 89, 89, 94,
+  89, 88, 99, 82, 88, 93, 88, 92, 85, 84,
+  94, 81, 73, 84, 84, 78, 84, 89, 79, 116,
+  80, 88, 88, 81, 83, 92, 78, 96, 85, 78,
+  76, 85, 80, 84, 74, 82, 78, 79, 79, 101,
+  75, 92, 84, 89, 82, 105, 82, 74, 74, 90,
+  100, 86, 78, 77, 84, 81, 86, 86, 80, 74,
+  81, 92, 94, 74, 72, 96, 83, 71, 92, 86,
+  80, 82, 78, 63, 85, 77, 90, 74, 87, 85,
+  83, 86, 89, 89, 95, 77, 91, 74, 79, 67,
+  92, 84, 96, 86, 80, 77, 67, 70, 77, 73,
+  82, 84, 84, 88, 84, 79, 81, 86, 80, 83,
+  87, 73, 76, 75, 91, 57, 86, 95, 71, 73,
+  109, 84, 85, 89, 92, 82, 90, 93, 95, 81,
+  103, 90, 84, 92, 76, 89, 86, 81, 87, 84,
+  77, 78, 82, 77, 93, 94, 77, 120, 86, 92,
+  95, 67, 80, 83, 79, 96, 79, 80, 70, 80,
+  74, 79, 78, 75, 77, 83, 85, 97, 82, 93,
+  75, 93, 87, 108, 76, 74, 75, 88, 105, 78,
+  81, 78, 85, 82, 91, 86, 76, 77, 75, 88,
+  86, 87, 82, 90, 79, 74, 84, 88, 75, 88,
+  87, 82, 87, 77, 90, 71, 89, 82, 80, 88,
+  94, 88, 94, 97, 80, 80, 82, 74, 79, 89,
+  101, 77, 79, 88, 79, 79, 81, 94, 76, 88,
+  84, 96, 80, 77, 86, 70, 85, 76, 82, 84,
+  81, 75, 88, 74, 95, 86, 82, 92, 99, 88,
+  72, 83, 84, 85, 93, 89, 88, 80, 93, 84,
+  91, 89, 83, 89, 85, 89, 86, 82, 77, 83,
+  82, 79, 85, 89, 80, 113, 80, 88, 90, 79,
+  86, 86, 83, 98, 79, 80, 78, 82, 78, 81,
+  95, 81, 81, 91, 83, 90, 98, 94, 84, 87,
+  92, 96, 79, 78, 78, 88, 99, 83, 69, 87,
+  76, 97, 104, 94, 86, 80, 93, 82, 95, 76,
+  82, 81, 84, 91, 75, 67, 86, 86, 82, 83,
+  73, 93, 85, 82, 103, 84, 86, 88, 90, 71,
+  77, 97, 127, 84, 93, 101, 88, 74, 118, 84,
+  81, 96, 85, 84, 87, 91, 80, 74, 71, 71,
+  88, 87, 93, 94, 59, 78, 73, 73, 90, 75,
+  62, 86, 86, 85, 59, 74, 84, 89, 103, 81,
+  87, 97, 84, 65, 77, 89, 92, 73, 85, 89,
+  81, 77, 104, 94, 87, 91, 90, 72, 87, 84,
+  91, 81, 86, 107, 76, 87, 89, 76, 83, 79,
+  85, 92, 87, 86, 90, 87, 91, 77, 91, 106,
+  92, 88, 81, 84, 69, 88, 92, 78, 82, 74,
+  83, 73, 82, 90, 98, 79, 72, 84, 103, 94,
+  99, 92, 79, 74, 87, 92, 92, 75, 73, 71,
+  83, 75, 76, 68, 83, 92, 77, 80, 95, 92,
+  83, 76, 96, 86, 96, 109, 95, 71, 76, 79,
+  89, 83, 91, 105, 92, 68, 138, 81, 75, 88,
+  94, 90, 85, 101, 86, 72, 77, 82, 81, 89,
+  91, 72, 53, 72, 63, 73, 90, 74, 58, 83,
+  76, 83, 69, 86, 82, 84, 90, 92, 79, 103,
+  84, 65, 81, 82, 82, 76, 82, 90, 72, 85,
+  90, 99, 81, 97, 82, 72, 81, 75, 87, 77,
+  84, 105, 80, 88, 92, 73, 76, 77, 87, 93,
+  87, 88, 88, 85, 85, 72, 106, 103, 84, 83,
+  94, 94, 96, 84, 91, 73, 73, 72, 73, 73,
+  81, 87, 105, 79, 82, 73, 99, 84, 81, 83,
+  78, 96, 86, 91, 90, 83, 77, 76, 73, 74,
+  82, 71, 84, 89, 58, 71, 91, 81, 80, 82,
+  84, 80, 82, 89, 78, 81, 85, 81, 82, 92,
+  81, 83, 83, 83, 112, 77, 80, 82, 84, 96,
+  93, 80, 93, 82, 77, 73, 90, 96, 89, 95,
+  79, 72, 69, 82, 92, 78, 77, 69, 76, 82,
+  81, 81, 84, 76, 94, 87, 82, 97, 82, 80,
+  77, 73, 80, 95, 86, 91, 70, 82, 79, 90,
+  92, 81, 96, 84, 81, 73, 80, 75, 91, 88,
+  74, 84, 102, 75, 65, 78, 87, 86, 83, 92,
+  86, 81, 91, 88, 86, 81, 92, 89, 78, 85,
+  99, 83, 79, 80, 78, 78, 92, 90, 92, 91,
+  88, 89, 71, 71, 69, 94, 84, 66, 87, 84,
+  74, 100, 96, 82, 74, 76, 77, 66, 73, 76,
+  85, 87, 75, 78, 80, 97, 82, 83, 126, 84,
+  106, 90, 70, 68, 102, 79, 145, 89, 96, 98,
+  83, 67, 151, 74, 89, 75, 103, 98, 80, 87,
+  96, 100, 62, 59, 86, 94, 110, 84, 58, 66,
+  61, 71, 95, 93, 82, 95, 71, 80, 69, 101,
+  69, 90, 84, 77, 103, 104, 78, 70, 71, 80,
+  93, 67, 80, 81, 79, 87, 83, 87, 82, 94,
+  73, 87, 103, 86, 77, 87, 104, 88, 70, 77,
+  73, 82, 73, 76, 90, 85, 85, 83, 74, 87,
+  92, 62, 95, 111, 90, 79, 77, 91, 67, 74,
+  74, 64, 65, 63, 88, 74, 77, 78, 89, 98,
+  71, 77, 80, 90, 76, 70, 83, 81, 65, 101,
+  90, 79, 68, 78, 76, 63, 70, 82, 86, 88,
+  72, 68, 92, 92, 70, 83, 112, 85, 104, 135,
+  73, 70, 109, 61, 90, 86, 83, 94, 92, 56,
+  131, 73, 76, 71, 101, 94, 76, 104, 104, 97,
+  60, 58, 85, 96, 101, 66, 72, 62, 59, 76,
+  97, 93, 90, 86, 57, 81, 76, 95, 63, 88,
+  61, 82, 99, 99, 75, 80, 72, 67, 74, 69,
+  75, 84, 76, 98, 72, 90, 76, 92, 68, 84,
+  109, 66, 68, 84, 88, 83, 75, 77, 87, 80,
+  73, 61, 86, 84, 82, 81, 70, 89, 86, 66,
+  99, 100, 89, 69, 78, 91, 99, 72, 72, 71,
+  83, 70, 81, 72, 74, 81, 90, 108, 80, 89,
+  80, 78, 83, 83, 86, 95, 88, 92, 93, 86,
+  89, 77, 78, 73, 79, 89, 87, 79, 68, 86,
+  71, 80, 80, 90, 83, 79, 92, 73, 75, 80,
+  93, 73, 81, 88, 72, 74, 81, 93, 92, 71,
+  85, 85, 90, 88, 81, 76, 88, 93, 74, 84,
+  90, 96, 95, 93, 90, 70, 77, 88, 88, 80,
+  90, 71, 75, 94, 86, 84, 80, 78, 83, 84,
+  85, 94, 84, 85, 73, 76, 63, 97, 86, 90,
+  79, 81, 87, 84, 91, 78, 89, 92, 94, 75,
+  68, 82, 84, 83, 69, 80, 99, 80, 73, 71,
+  82, 78, 82, 86, 90, 87, 75, 91, 77, 85,
+  88, 80, 70, 82, 86, 79, 80, 74, 92, 83,
+  96, 90, 94, 84, 83, 92, 82, 72, 81, 87,
+  87, 82, 73, 88, 99, 91, 89, 85, 106, 71,
+  77, 76, 83, 87, 75, 84, 70, 90, 82, 88,
+  91, 91, 84, 76, 84, 81, 74, 89, 103, 75,
+  77, 89, 102, 75, 73, 88, 92, 71, 74, 86,
+  82, 96, 86, 87, 87, 110, 61, 84, 86, 101,
+  90, 82, 90, 78, 90, 80, 80, 78, 94, 92,
+  84, 91, 77, 86, 83, 80, 84, 68, 97, 82,
+  73, 82, 71, 74, 81, 86, 83, 82, 82, 79,
+  85, 86, 85, 71, 85, 119, 87, 79, 71, 89,
+  109, 78, 56, 80, 89, 80, 83, 77, 82, 75,
+  69, 90, 75, 77, 68, 97, 67, 83, 88, 80,
+  93, 82, 81, 78, 73, 67, 77, 86, 93, 78,
+  95, 85, 80, 93, 79, 85, 82, 84, 85, 74,
+  73, 91, 97, 89, 89, 82, 105, 78, 79, 70,
+  77, 93, 78, 80, 75, 87, 76, 88, 88, 93,
+  84, 79, 86, 80, 79, 86, 108, 66, 62, 83,
+  84, 74, 84, 81, 75, 65, 72, 87, 79, 91,
+  83, 71, 86, 110, 71, 90, 87, 101, 85, 75,
+  96, 82, 92, 83, 82, 72, 89, 86, 81, 94,
+  84, 78, 79, 81, 74, 73, 88, 85, 70, 82,
+  73, 79, 65, 86, 81, 84, 89, 86, 87, 90,
+  73, 70, 94, 118, 84, 77, 73, 86, 88, 82,
+  69, 79, 100, 76, 80, 70, 83, 76, 69, 89,
+  75, 79, 69, 98, 62, 80, 88, 80, 96, 82,
+  78, 79, 80, 75, 99, 90, 94, 82, 96, 91,
+  73, 95, 83, 101, 89, 80, 83, 99, 82, 93,
+  104, 91, 85, 81, 105, 85, 94, 77, 85, 91,
+  72, 86, 75, 92, 76, 82, 84, 78, 79, 74,
+  72, 67, 81, 81, 93, 81, 84, 103, 83, 82,
+  81, 87, 90, 75, 90, 94, 88, 82, 83, 71,
+  88, 96, 84, 103, 85, 89, 81, 79, 93, 84,
+  92, 83, 81, 76, 83, 85, 88, 97, 78, 82,
+  87, 87, 86, 88, 78, 86, 78, 75, 86, 94,
+  62, 99, 88, 87, 73, 71, 95, 91, 83, 76,
+  90, 98, 72, 88, 84, 84, 86, 94, 68, 86,
+  98, 68, 83, 76, 84, 77, 76, 86, 85, 77,
+  75, 98, 64, 92, 83, 85, 86, 85, 80, 81,
+  89, 75, 91, 91, 78, 83, 90, 96, 78, 84,
+  101, 76, 66, 92, 95, 94, 85, 80, 89, 67,
+  101, 83, 85, 84, 90, 96, 84, 88, 86, 73,
+  85, 92, 99, 80, 84, 83, 77, 77, 84, 93,
+  97, 86, 103, 84, 110, 77, 69, 82, 86, 73,
+  87, 93, 82, 100, 88, 74, 105, 94, 69, 87,
+  92, 92, 93, 91, 93, 91, 83, 97, 78, 89,
+  80, 84, 78, 70, 83, 90, 86, 80, 90, 79,
+  86, 74, 71, 94, 84, 63, 86, 100, 84, 66,
+  96, 90, 80, 85, 102, 75, 85, 89, 100, 89,
+  72, 84, 80, 85, 79, 93, 97, 99, 88, 71,
+  82, 89, 82, 83, 85, 85, 96, 92, 82, 89,
+  77, 86, 84, 88, 82, 85, 74, 82, 75, 82,
+  92, 89, 71, 87, 92, 73, 85, 105, 89, 89,
+  74, 86, 96, 95, 86, 75, 84, 76, 100, 87,
+  78, 78, 96, 102, 82, 85, 91, 85, 77, 79,
+  83, 81, 88, 89, 72, 81, 81, 86, 95, 83,
+  109, 77, 95, 75, 67, 73, 87, 66, 80, 95,
+  85, 101, 90, 74, 112, 90, 66, 92, 92, 94,
+  87, 95, 90, 92, 82, 100, 74, 94, 78, 83,
+  81, 72, 80, 89, 87, 87, 80, 70, 74, 76,
+  67, 95, 85, 66, 78, 83, 81, 71, 97, 94,
+  82, 84, 100, 76, 84, 86, 111, 90, 72, 79,
+  74, 84, 70, 92, 92, 108, 83, 71, 82, 87,
+  81, 83, 85, 80, 96, 95, 89, 90, 78, 89,
+  87, 82, 75, 93, 70, 80, 76, 82, 93, 83,
+  81, 87, 91, 74, 90, 111, 99, 85, 101, 85,
+  97, 107, 81, 75, 87, 75, 90, 85, 82, 75,
+  76, 105, 85, 78, 87, 86, 72, 94, 81, 87,
+  89, 82, 87, 73, 74, 101, 94, 85, 84, 77,
+  95, 79, 82, 82, 86, 68, 88, 84, 91, 89,
+  88, 78, 102, 88, 73, 80, 85, 80, 92, 84,
+  93, 95, 83, 92, 75, 98, 81, 87, 77, 78,
+  83, 84, 86, 78, 91, 78, 78, 88, 72, 91,
+  84, 66, 90, 83, 83, 64, 92, 92, 94, 96,
+  88, 88, 88, 82, 90, 86, 66, 80, 93, 87,
+  84, 83, 97, 84, 85, 73, 83, 76, 81, 85,
+  86, 87, 89, 90, 83, 85, 92, 89, 82, 86,
+  82, 87, 87, 87, 77, 83, 89, 84, 75, 84,
+  85, 79, 89, 93, 75, 76, 86, 100, 76, 74,
+  73, 69, 92, 81, 73, 77, 69, 90, 67, 120,
+  74, 72, 79, 77, 94, 71, 80, 98, 72, 62,
+  130, 80, 110, 78, 74, 88, 69, 70, 96, 74,
+  81, 85, 81, 69, 94, 81, 73, 69, 69, 94,
+  96, 86, 109, 80, 87, 84, 96, 82, 83, 99,
+  85, 75, 84, 93, 93, 87, 72, 86, 78, 73,
+  103, 98, 89, 80, 80, 86, 96, 97, 64, 79,
+  97, 62, 97, 60, 89, 93, 91, 77, 78, 99,
+  83, 78, 93, 80, 57, 100, 84, 74, 79, 77,
+  89, 70, 84, 96, 72, 104, 74, 84, 87, 77,
+  65, 75, 64, 66, 92, 59, 68, 84, 99, 99,
+  54, 85, 71, 77, 91, 79, 85, 70, 78, 85,
+  68, 83, 74, 72, 88, 96, 69, 65, 69, 75,
+  81, 89, 70, 82, 60, 105, 74, 100, 74, 65,
+  74, 78, 76, 64, 82, 100, 72, 65, 138, 82,
+  108, 86, 68, 89, 63, 70, 74, 72, 74, 87,
+  77, 67, 87, 75, 76, 64, 65, 85, 94, 78,
+  98, 83, 86, 84, 91, 73, 74, 94, 76, 67,
+  86, 89, 97, 72, 69, 77, 75, 76, 118, 87,
+  78, 81, 71, 92, 84, 101, 65, 74, 98, 70,
+  91, 68, 88, 99, 93, 86, 65, 106, 82, 75,
+  87, 80, 57, 92, 78, 77, 69, 76, 83, 80,
+  86, 90, 70, 85, 73, 84, 77, 78, 64, 71,
+  64, 63, 97, 56, 66, 85, 113, 107, 84, 87,
+  63, 73, 85, 79, 75, 68, 77, 90, 55, 87,
+  74, 66, 72, 84, 72, 84, 69, 75, 83, 90,
+  76, 70, 67, 95, 61, 99, 73, 76, 84, 84,
+  75, 65, 88, 95, 81, 63, 122, 78, 108, 106,
+  70, 90, 59, 66, 88, 81, 100, 89, 86, 63,
+  91, 83, 82, 66, 73, 87, 85, 77, 109, 75,
+  78, 87, 95, 72, 89, 83, 86, 69, 87, 86,
+  94, 87, 70, 76, 64, 77, 109, 86, 89, 91,
+  69, 90, 105, 95, 72, 87, 101, 88, 97, 62,
+  85, 85, 82, 92, 65, 97, 85, 83, 78, 84,
+  68, 91, 89, 77, 87, 73, 93, 70, 98, 88,
+  75, 70, 78, 88, 85, 81, 70, 76, 72, 69,
+  93, 64, 76, 86, 103, 100, 106, 96, 72, 75,
+  81, 77, 72, 77, 77, 84, 69, 82, 76, 102,
+  77, 67, 85, 80, 73, 74, 80, 83, 66, 103,
+  81, 102, 57, 63, 78, 72, 95, 88, 91, 74,
+  93, 76, 72, 95, 104, 79, 93, 87, 79, 84,
+  65, 79, 79, 94, 74, 80, 92, 75, 82, 76,
+  85, 79, 105, 92, 67, 87, 109, 68, 90, 80,
+  87, 76, 87, 72, 101, 64, 87, 83, 96, 79,
+  100, 84, 74, 80, 79, 111, 77, 97, 69, 79,
+  95, 95, 75, 105, 81, 72, 90, 60, 89, 68,
+  78, 96, 76, 78, 87, 79, 71, 93, 93, 81,
+  99, 85, 86, 77, 94, 77, 71, 87, 80, 86,
+  87, 94, 83, 84, 86, 83, 95, 85, 88, 55,
+  78, 91, 93, 82, 99, 85, 85, 88, 87, 79,
+  72, 79, 93, 85, 78, 71, 87, 86, 62, 62,
+  88, 90, 74, 76, 77, 82, 72, 109, 77, 87,
+  66, 66, 81, 74, 99, 88, 81, 84, 90, 72,
+  72, 93, 89, 80, 88, 76, 83, 88, 63, 84,
+  78, 100, 73, 79, 89, 75, 83, 76, 80, 80,
+  100, 94, 63, 85, 97, 70, 94, 80, 87, 82,
+  84, 87, 102, 63, 94, 80, 91, 77, 97, 80,
+  64, 92, 77, 116, 79, 75, 76, 82, 96, 87,
+  84, 100, 83, 89, 77, 63, 89, 66, 77, 90,
+  80, 73, 89, 83, 63, 92, 90, 78, 95, 85,
+  92, 78, 95, 87, 79, 85, 77, 69, 91, 96,
+  77, 82, 86, 83, 90, 83, 80, 59, 81, 93,
+  73, 75, 102, 88, 91, 74, 81, 85, 74, 81,
+  92, 84, 72, 73, 76, 84, 62, 63, 91, 93,
+  77, 79, 80, 83, 78, 92, 90, 79, 66, 64,
+  81, 85, 96, 90, 89, 73, 81, 72, 80, 98,
+  82, 85, 83, 78, 83, 87, 77, 82, 84, 90,
+  75, 80, 81, 84, 79, 77, 84, 89, 104, 97,
+  61, 80, 103, 76, 89, 87, 88, 82, 81, 93,
+  100, 71, 89, 81, 86, 72, 95, 85, 74, 87,
+  84, 103, 78, 86, 90, 81, 98, 94, 82, 105,
+  75, 89, 88, 67, 89, 70, 82, 77, 87, 74,
+  84, 85, 74, 102, 96, 87, 99, 88, 103, 77,
+  95, 85, 86, 88, 86, 83, 84, 95, 80, 86,
+  78, 87, 92, 92, 81, 63, 83, 84, 70, 73,
+  80, 86, 87, 73, 88, 78, 80, 85, 101, 80,
+  82, 74, 79, 79, 80, 94, 74, 88, 88, 86,
+  83, 80, 78, 86, 85, 103, 71, 91, 79, 89,
+  77, 69, 78, 101, 74, 73, 95, 82, 98, 81,
+  87, 81, 82, 87, 84, 79, 85, 70, 90, 82,
+  98, 79, 74, 82, 91, 92, 96, 94, 82, 77,
+  75, 88, 82, 85, 96, 68, 92, 79, 75, 65,
+  86, 77, 95, 76, 88, 97, 77, 90, 88, 78,
+  70, 94, 76, 75, 85, 89, 84, 81, 84, 73,
+  96, 53, 87, 94, 91, 81, 70, 84, 95, 84,
+  83, 93, 82, 101, 89, 73, 99, 72, 80, 87,
+  82, 97, 83, 93, 92, 89, 85, 83, 85, 92,
+  89, 89, 81, 91, 84, 78, 89, 71, 85, 87,
+  95, 91, 86, 84, 72, 80, 81, 82, 86, 83,
+  74, 84, 79, 92, 63, 74, 87, 83, 81, 84,
+  74, 87, 82, 88, 73, 91, 77, 85, 79, 74,
+  85, 99, 79, 74, 91, 88, 89, 81, 81, 90,
+  82, 82, 86, 75, 80, 73, 94, 85, 93, 71,
+  83, 85, 78, 86, 87, 90, 84, 66, 78, 100,
+  83, 76, 97, 71, 92, 82, 87, 70, 85, 79,
+  92, 88, 86, 95, 73, 90, 87, 84, 74, 87,
+  77, 79, 88, 82, 88, 85, 82, 71, 98, 50,
+  90, 94, 84, 75, 73, 82, 77, 85, 81, 95,
+  90, 91, 95, 71, 98, 72, 78, 73, 80, 94,
+  80, 75, 87, 87, 81, 80, 84, 86, 79, 91,
+  80, 92, 85, 78, 86, 71, 82, 87, 93, 96,
+  85, 92, 71, 84, 83, 77, 83, 78, 87, 94,
+  77, 97, 84, 76, 85, 83, 82, 79, 78, 88,
+  86, 87, 74, 87, 78, 89, 81, 78, 87, 99,
+  95, 71, 96, 87, 97, 82, 86, 89, 80, 83,
+  82, 68, 78, 82, 87, 78, 100, 80, 76, 80,
+  72, 92, 99, 92, 84, 70, 76, 91, 80, 78,
+  92, 75, 89, 85, 76, 64, 86, 74, 98, 74,
+  88, 103, 80, 86, 96, 83, 76, 98, 82, 79,
+  88, 84, 93, 77, 93, 79, 95, 59, 88, 91,
+  90, 74, 71, 87, 77, 86, 79, 93, 83, 101,
+  88, 74, 91, 72, 81, 88, 81, 96, 81, 83,
+  90, 90, 85, 83, 89, 90, 89, 86, 75, 92,
+  86, 97, 81, 80, 74, 89, 91, 95, 89, 87,
+  72, 80, 84, 80, 87, 82, 101, 77, 65, 91,
+  101, 74, 85, 72, 77, 74, 108, 67, 84, 102,
+  76, 92, 104, 72, 84, 61, 87, 104, 63, 77,
+  101, 76, 86, 86, 105, 99, 84, 86, 82, 74,
+  87, 48, 82, 80, 116, 75, 83, 87, 78, 83,
+  106, 94, 93, 68, 77, 79, 67, 69, 84, 71,
+  80, 83, 68, 108, 66, 72, 83, 92, 76, 128,
+  68, 114, 87, 69, 99, 85, 66, 65, 84, 87,
+  82, 71, 81, 55, 96, 86, 64, 92, 86, 67,
+  76, 79, 82, 76, 46, 82, 60, 83, 81, 83,
+  80, 84, 84, 134, 83, 83, 74, 94, 91, 90,
+  80, 97, 83, 79, 91, 82, 75, 107, 78, 58,
+  113, 84, 77, 92, 84, 84, 95, 87, 62, 69,
+  85, 79, 101, 82, 92, 81, 73, 86, 88, 60,
+  85, 72, 86, 75, 106, 74, 80, 88, 81, 88,
+  99, 74, 85, 62, 87, 106, 62, 79, 87, 78,
+  83, 87, 93, 95, 85, 84, 83, 62, 78, 48,
+  81, 81, 104, 71, 82, 99, 81, 85, 99, 93,
+  85, 53, 78, 87, 68, 72, 88, 77, 90, 77,
+  84, 117, 64, 63, 80, 104, 73, 144, 68, 130,
+  84, 66, 100, 80, 62, 69, 88, 87, 84, 72,
+  83, 60, 94, 83, 72, 96, 83, 61, 80, 76,
+  55, 71, 50, 85, 71, 79, 81, 80, 69, 87,
+  83, 119, 82, 84, 72, 91, 87, 86, 81, 89,
+  78, 78, 84, 80, 83, 106, 77, 54, 108, 78,
+  71, 88, 86, 90, 79, 92, 63, 71, 87, 72,
+  102, 74, 102, 94, 88, 92, 102, 61, 84, 75,
+  79, 72, 102, 71, 85, 95, 79, 94, 103, 71,
+  82, 70, 78, 106, 79, 73, 93, 80, 83, 84,
+  106, 96, 82, 93, 83, 65, 94, 68, 86, 82,
+  107, 81, 85, 80, 78, 85, 105, 94, 87, 54,
+  78, 81, 66, 69, 82, 75, 78, 78, 72, 100,
+  69, 72, 85, 89, 78, 125, 70, 106, 85, 75,
+  101, 81, 69, 67, 87, 82, 95, 66, 86, 73,
+  99, 84, 64, 92, 87, 72, 77, 83, 62, 72,
+  47, 86, 63, 79, 79, 86, 77, 83, 83, 129,
+  88, 87, 77, 104, 89, 91, 83, 89, 82, 80,
+  89, 81, 80, 106, 80, 83, 102, 80, 68, 93,
+  81, 84, 78, 93, 63, 69, 79, 77, 105, 84,
+  84, 76, 70, 93, 90, 77, 84, 90, 83, 75,
+  81, 80, 77, 88, 79, 98, 95, 84, 81, 72,
+  94, 94, 75, 78, 97, 80, 91, 83, 81, 111,
+  88, 85, 89, 70, 71, 63, 94, 91, 119, 94,
+  86, 77, 74, 90, 89, 97, 95, 82, 79, 87,
+  78, 86, 81, 74, 79, 91, 75, 77, 88, 79,
+  78, 78, 95, 87, 74, 85, 81, 78, 93, 85,
+  82, 68, 98, 85, 80, 80, 78, 63, 106, 67,
+  73, 89, 85, 78, 82, 81, 89, 78, 78, 85,
+  86, 95, 85, 83, 82, 72, 80, 89, 83, 91,
+  70, 78, 85, 85, 78, 87, 82, 86, 75, 85,
+  71, 95, 86, 74, 85, 80, 82, 85, 91, 96,
+  88, 88, 83, 73, 90, 99, 91, 81, 83, 83,
+  83, 92, 80, 75, 84, 89, 91, 78, 80, 83,
+  75, 92, 76, 97, 90, 85, 83, 73, 83, 89,
+  76, 81, 87, 79, 95, 82, 72, 88, 89, 88,
+  96, 66, 69, 66, 85, 87, 98, 87, 85, 76,
+  86, 87, 80, 91, 85, 68, 81, 96, 82, 88,
+  84, 77, 86, 78, 82, 84, 82, 76, 80, 86,
+  94, 82, 70, 83, 88, 82, 91, 89, 70, 67,
+  95, 87, 84, 82, 77, 76, 107, 62, 82, 90,
+  87, 76, 85, 85, 75, 81, 74, 80, 91, 93,
+  84, 76, 74, 71, 81, 79, 78, 94, 70, 90,
+  84, 82, 82, 84, 83, 84, 77, 83, 71, 93,
+  85, 75, 86, 76, 75, 81, 87, 95, 77, 86,
+  89, 76, 96, 97, 89, 75, 86, 89, 94, 94,
+  91, 75, 80, 90, 90, 77, 78, 81, 77, 98,
+  77, 98, 96, 79, 79, 81, 74, 94, 79, 81,
+  85, 78, 93, 82, 76, 80, 89, 91, 90, 65,
+  94, 77, 89, 90, 94, 92, 89, 79, 88, 87,
+  82, 95, 94, 60, 78, 87, 80, 94, 82, 74,
+  80, 73, 77, 73, 90, 79, 79, 80, 95, 89,
+  79, 79, 80, 75, 94, 89, 70, 71, 92, 81,
+  90, 76, 79, 89, 118, 70, 73, 86, 92, 75,
+  83, 90, 74, 78, 82, 88, 86, 86, 87, 83,
+  72, 66, 77, 88, 82, 93, 74, 89, 84, 87,
+  81, 86, 84, 86, 80, 88, 72, 92, 85, 89,
+  86, 76, 72, 86, 91, 94, 77, 87, 82, 73,
+  88, 97, 90, 81, 68, 77, 95, 89, 74, 73,
+  83, 75, 84, 91, 88, 68, 91, 107, 63, 81,
+  72, 83, 78, 83, 96, 93, 78, 91, 74, 90,
+  76, 91, 94, 85, 95, 87, 74, 69, 72, 85,
+  94, 86, 99, 77, 75, 68, 84, 84, 86, 81,
+  67, 88, 96, 86, 75, 79, 92, 77, 80, 81,
+  72, 85, 85, 79, 87, 86, 78, 87, 88, 78,
+  98, 73, 81, 91, 70, 72, 97, 95, 78, 87,
+  80, 79, 97, 71, 78, 77, 79, 85, 76, 100,
+  87, 85, 79, 91, 92, 72, 74, 85, 84, 89,
+  83, 70, 80, 96, 87, 71, 80, 70, 82, 90,
+  87, 81, 76, 68, 74, 84, 81, 90, 70, 82,
+  80, 82, 87, 105, 93, 75, 85, 84, 89, 89,
+  79, 79, 70, 72, 71, 80, 91, 65, 82, 74,
+  82, 92, 88, 74, 88, 101, 71, 84, 72, 80,
+  73, 68, 92, 92, 72, 89, 76, 90, 74, 93,
+  91, 79, 93, 81, 65, 78, 75, 80, 92, 84,
+  109, 79, 72, 67, 97, 91, 97, 81, 62, 83,
+  90, 84, 87, 91, 92, 80, 64, 74, 70, 83,
+  86, 89, 86, 76, 78, 90, 87, 77, 85, 69,
+  76, 89, 81, 62, 93, 116, 72, 85, 93, 93,
+  110, 62, 82, 79, 74, 78, 66, 91, 89, 91,
+  79, 92, 94, 91, 82, 89, 83, 93, 83, 75,
+  63, 97, 83, 92, 82, 67, 82, 90, 103, 84,
+  71, 71, 87, 88, 82, 94, 76, 84, 70, 82,
+  86, 123, 88, 73, 86, 83, 82, 93, 83, 76,
+  74, 88, 69, 86, 76, 71, 80, 75, 78, 85,
+  87, 74, 86, 84, 64, 80, 80, 86, 81, 70,
+  91, 91, 72, 92, 86, 93, 78, 90, 88, 76,
+  96, 89, 75, 89, 77, 79, 93, 90, 91, 83,
+  73, 77, 94, 79, 87, 91, 70, 82, 94, 83,
+  77, 90, 88, 76, 81, 72, 71, 81, 86, 83,
+  88, 83, 74, 82, 84, 81, 82, 74, 92, 81,
+  97, 64, 98, 85, 78, 95, 73, 90, 106, 73,
+  79, 79, 81, 76, 78, 80, 93, 80, 83, 88,
+  91, 91, 74, 90, 101, 87, 84, 72, 81, 99,
+  78, 88, 78, 71, 81, 90, 84, 83, 75, 70,
+  84, 83, 81, 93, 79, 83, 77, 81, 86, 87,
+  83, 82, 87, 84, 89, 89, 81, 82, 88, 80,
+  78, 71, 110, 88, 83, 93, 82, 86, 101, 75,
+  66, 92, 76, 70, 82, 79, 85, 87, 106, 88,
+  85, 81, 64, 79, 55, 86, 88, 76, 139, 78,
+  73, 85, 101, 111, 76, 74, 91, 68, 73, 102,
+  66, 100, 78, 71, 94, 106, 74, 67, 103, 95,
+  93, 74, 65, 81, 94, 87, 95, 93, 77, 84,
+  80, 65, 83, 73, 70, 77, 81, 64, 75, 92,
+  55, 80, 93, 73, 104, 117, 75, 68, 84, 74,
+  74, 74, 76, 88, 84, 89, 101, 81, 75, 74,
+  84, 75, 71, 80, 97, 80, 88, 67, 73, 70,
+  73, 74, 89, 79, 115, 74, 88, 92, 84, 92,
+  76, 84, 72, 68, 79, 82, 94, 82, 91, 100,
+  80, 90, 74, 87, 92, 95, 85, 71, 63, 65,
+  140, 98, 68, 105, 82, 90, 100, 84, 77, 103,
+  90, 69, 94, 81, 91, 67, 80, 100, 79, 67,
+  75, 69, 60, 92, 81, 92, 170, 82, 56, 99,
+  94, 98, 76, 73, 110, 65, 68, 121, 92, 108,
+  77, 60, 100, 96, 63, 62, 125, 90, 91, 75,
+  56, 91, 102, 84, 88, 95, 74, 71, 69, 82,
+  69, 79, 53, 72, 69, 66, 71, 82, 46, 82,
+  93, 69, 155, 109, 79, 59, 80, 78, 78, 88,
+  76, 92, 76, 90, 90, 79, 82, 73, 87, 78,
+  66, 73, 113, 97, 68, 54, 76, 72, 85, 77,
+  86, 74, 129, 73, 92, 109, 97, 113, 88, 83,
+  69, 64, 69, 76, 116, 83, 85, 144, 74, 106,
+  56, 84, 108, 97, 84, 85, 74, 72, 103, 106,
+  79, 87, 76, 80, 96, 78, 75, 82, 72, 74,
+  82, 84, 85, 74, 79, 94, 76, 89, 93, 80,
+  60, 85, 81, 95, 125, 92, 78, 99, 78, 98,
+  83, 70, 85, 73, 78, 98, 110, 92, 81, 79,
+  101, 100, 76, 68, 98, 89, 92, 79, 66, 89,
+  84, 83, 89, 87, 87, 93, 85, 59, 78, 75,
+  69, 73, 79, 70, 93, 89, 57, 75, 92, 80,
+  80, 99, 86, 72, 88, 77, 83, 103, 79, 84,
+  85, 85, 96, 80, 80, 77, 86, 80, 77, 77,
+  95, 79, 67, 78, 73, 75, 75, 74, 82, 79,
+  99, 84, 83, 90, 83, 86, 79, 88, 65, 74,
+  87, 80, 93, 79, 77, 88, 82, 88, 80, 83,
+  88, 95, 86, 78, 70, 82, 89, 89, 88, 85,
+  81, 88, 92, 79, 71, 81, 70, 88, 88, 78,
+  91, 80, 78, 71, 70, 91, 89, 80, 77, 81,
+  92, 74, 93, 82, 77, 96, 114, 96, 77, 89,
+  83, 88, 95, 90, 72, 94, 64, 83, 112, 93,
+  87, 82, 90, 95, 78, 77, 76, 60, 91, 81,
+  98, 81, 80, 100, 100, 77, 95, 72, 75, 82,
+  91, 80, 82, 90, 78, 74, 102, 86, 82, 86,
+  73, 66, 78, 88, 88, 76, 78, 82, 85, 96,
+  90, 82, 76, 97, 88, 79, 78, 79, 89, 83,
+  95, 86, 72, 94, 73, 79, 93, 72, 105, 72,
+  82, 71, 82, 89, 69, 90, 75, 80, 61, 81,
+  89, 75, 74, 79, 77, 89, 83, 88, 79, 78,
+  90, 70, 74, 82, 106, 75, 81, 95, 78, 92,
+  91, 84, 70, 99, 79, 76, 91, 79, 83, 71,
+  64, 84, 80, 88, 95, 76, 83, 86, 85, 104,
+  88, 85, 74, 99, 91, 91, 91, 88, 102, 93,
+  98, 78, 65, 100, 58, 76, 133, 75, 82, 74,
+  93, 91, 74, 79, 77, 76, 97, 83, 103, 77,
+  75, 96, 100, 84, 95, 77, 86, 85, 92, 92,
+  76, 85, 70, 74, 116, 79, 90, 88, 83, 53,
+  75, 100, 82, 90, 81, 95, 81, 93, 85, 66,
+  76, 84, 87, 79, 73, 71, 89, 90, 99, 82,
+  73, 72, 78, 81, 85, 72, 106, 74, 79, 86,
+  79, 100, 80, 85, 68, 81, 75, 68, 95, 71,
+  74, 80, 71, 98, 73, 86, 82, 83, 78, 77,
+  80, 82, 79, 75, 88, 82, 82, 87, 89, 81,
+  82, 86, 68, 92, 88, 86, 87, 73, 79, 80,
+  82, 96, 97, 77, 71, 80, 85, 104, 93, 85,
+  84, 91, 85, 82, 79, 81, 86, 85, 99, 85,
+  81, 89, 70, 85, 101, 80, 89, 81, 85, 81,
+  78, 76, 77, 100, 84, 82, 94, 82, 86, 102,
+  98, 72, 85, 79, 87, 79, 82, 85, 70, 87,
+  79, 77, 99, 92, 78, 89, 71, 66, 80, 89,
+  84, 91, 76, 93, 88, 89, 87, 81, 81, 76,
+  91, 83, 74, 77, 87, 88, 86, 88, 75, 69,
+  72, 79, 91, 76, 93, 84, 82, 76, 82, 90,
+  74, 79, 59, 89, 105, 84, 92, 78, 77, 78,
+  79, 92, 84, 87, 82, 83, 69, 76, 89, 84,
+  76, 79, 71, 83, 101, 82, 72, 73, 83, 83,
+  101, 86, 73, 81, 86, 85, 80, 68, 99, 67,
+  79, 70, 78, 83, 102, 85, 85, 90, 74, 80,
+  88, 85, 74, 76, 81, 72, 76, 87, 79, 82,
+  54, 75, 79, 75, 69, 96, 66, 85, 73, 100,
+  76, 88, 82, 78, 88, 112, 83, 101, 80, 85,
+  95, 81, 68, 92, 82, 85, 84, 79, 80, 75,
+  79, 91, 121, 77, 82, 89, 87, 90, 79, 80,
+  84, 80, 77, 84, 75, 90, 92, 91, 78, 90,
+  92, 113, 83, 94, 87, 69, 95, 77, 101, 83,
+  88, 84, 75, 88, 88, 104, 88, 84, 84, 85,
+  89, 75, 88, 89, 82, 96, 94, 163, 86, 82,
+  88, 79, 79, 80, 69, 78, 87, 81, 82, 88,
+  76, 77, 97, 81, 73, 71, 84, 75, 102, 91,
+  70, 84, 83, 86, 82, 75, 91, 76, 80, 74,
+  82, 85, 90, 83, 85, 94, 79, 78, 87, 78,
+  70, 77, 74, 78, 78, 87, 80, 88, 61, 87,
+  80, 72, 68, 102, 64, 84, 76, 101, 78, 83,
+  78, 89, 92, 94, 84, 102, 79, 94, 93, 84,
+  74, 93, 82, 84, 78, 75, 80, 80, 81, 90,
+  103, 72, 88, 89, 94, 92, 84, 77, 82, 71,
+  78, 74, 72, 100, 91, 93, 80, 88, 83, 105,
+  80, 103, 87, 75, 93, 73, 95, 83, 87, 82,
+  73, 84, 88, 106, 88, 92, 83, 85, 95, 73,
+  77, 91, 83, 95, 80, 132, 82, 79, 88, 79,
+  78, 82, 77, 83, 87, 78, 78, 91, 72, 80,
+  96, 82, 73, 73, 87, 76, 99, 86, 75, 75,
+  86, 83, 81, 75, 81, 71, 83, 69, 79, 80,
+  97, 78, 85, 92, 72, 81, 92, 97, 78, 75,
+  83, 76, 81, 88, 82, 83, 62, 80, 77, 75,
+  71, 96, 67, 86, 73, 92, 74, 83, 82, 75,
+  89, 103, 83, 96, 81, 83, 100, 80, 77, 91,
+  85, 86, 90, 78, 81, 74, 81, 85, 106, 76,
+  85, 90, 85, 91, 85, 88, 84, 76, 87, 83,
+  75, 98, 92, 96, 78, 92, 91, 104, 79, 93,
+  78, 77, 93, 84, 96, 82, 84, 84, 78, 88,
+  88, 99, 93, 85, 84, 83, 85, 77, 79, 89,
+  80, 94, 69, 144, 83, 82, 80, 80, 86, 85,
+  70, 82, 81, 85, 71, 83, 83, 98, 97, 78,
+  76, 74, 83, 74, 104, 87, 73, 84, 85, 81,
+  80, 62, 90, 73, 74, 76, 78, 83, 92, 77,
+  79, 87, 80, 86, 67, 81, 68, 79, 70, 77,
+  81, 94, 84, 84, 56, 80, 80, 76, 70, 93,
+  71, 75, 77, 107, 85, 85, 81, 84, 90, 102,
+  79, 97, 80, 88, 89, 92, 79, 82, 80, 83,
+  91, 81, 84, 75, 84, 96, 104, 69, 84, 107,
+  87, 78, 76, 70, 85, 79, 81, 78, 76, 77,
+  85, 79, 84, 95, 86, 118, 85, 105, 86, 78,
+  88, 81, 93, 83, 80, 87, 82, 82, 75, 94,
+  83, 86, 82, 81, 85, 76, 80, 83, 81, 100,
+  82, 147, 87, 83, 92, 81, 80, 81, 72, 77,
+  84, 81, 78, 82, 89, 89, 89, 76, 79, 75,
+  81, 74, 105, 86, 71, 87, 83, 80, 85, 70,
+  84, 85, 76, 82, 80, 81, 78, 73, 77, 91,
+  80, 78, 68, 73, 63, 78, 74, 84, 82, 103,
+  84, 90, 63, 92, 78, 72, 74, 96, 64, 78,
+  79, 105, 86, 82, 80, 100, 90, 82, 81, 98,
+  78, 106, 91, 96, 86, 82, 83, 85, 77, 82,
+  81, 79, 82, 93, 84, 69, 87, 112, 94, 83,
+  87, 67, 88, 76, 76, 72, 76, 83, 84, 77,
+  84, 96, 78, 114, 78, 119, 91, 84, 86, 64,
+  82, 82, 76, 88, 76, 79, 72, 97, 86, 93,
+  79, 81, 92, 69, 79, 83, 80, 100, 64, 119,
+  83, 80, 93, 78, 77, 85, 77, 87, 90, 82,
+  76, 85, 81, 89, 92, 80, 79, 73, 83, 76,
+  103, 89, 74, 80, 85, 79, 82, 70, 85, 75,
+  78, 72, 79, 80, 89, 74, 79, 89, 77, 78,
+  80, 90, 72, 77, 79, 77, 83, 90, 82, 82,
+  64, 83, 77, 72, 72, 91, 73, 83, 77, 97,
+  83, 75, 81, 78, 89, 96, 80, 89, 80, 84,
+  97, 86, 87, 85, 84, 85, 76, 77, 82, 75,
+  87, 92, 96, 80, 83, 101, 84, 78, 82, 80,
+  86, 81, 80, 81, 77, 89, 89, 85, 81, 95,
+  85, 108, 83, 100, 82, 79, 92, 78, 91, 81,
+  76, 86, 85, 83, 77, 92, 91, 87, 84, 82,
+  84, 76, 84, 82, 80, 97, 61, 134, 85, 82,
+  85, 81, 82, 84, 80, 84, 78, 88, 80, 89,
+  83, 102, 100, 84, 78, 79, 83, 76, 104, 84,
+  74, 74, 91, 81, 83, 79, 81, 72, 77, 67,
+  83, 80, 94, 78, 79, 90, 81, 91, 69, 82,
+  79, 96, 71, 70, 87, 90, 85, 83, 61, 77,
+  83, 77, 69, 98, 72, 85, 75, 96, 85, 88,
+  78, 78, 93, 113, 75, 93, 81, 86, 96, 87,
+  86, 83, 85, 90, 97, 79, 89, 76, 86, 96,
+  114, 75, 82, 78, 88, 77, 80, 79, 79, 82,
+  82, 85, 85, 68, 80, 83, 80, 102, 90, 109,
+  87, 84, 83, 75, 93, 96, 95, 80, 78, 84,
+  93, 88, 77, 85, 76, 84, 78, 83, 82, 85,
+  84, 88, 88, 93, 79, 141, 91, 87, 86, 90,
+  85, 86, 78, 81, 84, 85, 87, 87, 89, 97,
+  92, 79, 77, 79, 81, 77, 103, 86, 72, 80,
+  87, 80, 90, 83, 81, 79, 79, 72, 82, 76,
+  79, 72, 81, 91, 77, 83, 66, 77, 74, 90,
+  77, 77, 89, 93, 84, 86, 63, 89, 79, 76,
+  74, 96, 69, 87, 77, 96, 84, 84, 77, 87,
+  94, 94, 78, 94, 81, 92, 88, 87, 91, 80,
+  87, 87, 81, 75, 85, 78, 86, 93, 92, 77,
+  83, 86, 93, 83, 84, 77, 81, 84, 79, 80,
+  81, 74, 76, 77, 79, 100, 81, 105, 82, 93,
+  84, 78, 85, 80, 89, 79, 74, 83, 85, 84,
+  75, 85, 78, 87, 78, 81, 83, 80, 83, 85,
+  85, 92, 70, 120, 88, 85, 88, 86, 83, 85,
+  84, 86, 98, 87, 84, 84, 81, 92, 96, 83,
+  83, 77, 81, 82, 98, 90, 76, 71, 91, 82,
+  82, 82, 83, 76, 81, 65, 81, 74, 91, 74,
+  81, 92, 79, 81, 80, 90, 81, 92, 81, 74,
+  94, 93, 81, 83, 68, 83, 80, 76, 74, 98,
+  75, 93, 76, 90, 84, 78, 79, 74, 94, 103,
+  76, 88, 82, 83, 96, 86, 93, 83, 86, 90,
+  78, 79, 87, 74, 86, 95, 108, 85, 79, 82,
+  87, 77, 84, 84, 81, 89, 78, 82, 82, 79,
+  82, 74, 78, 101, 86, 103, 85, 81, 79, 76,
+  94, 84, 91, 77, 78, 84, 92, 87, 76, 84,
+  85, 84, 80, 82, 82, 85, 88, 87, 86, 91,
+  68, 130, 88, 84, 86, 88, 84, 88, 90, 70,
+  93, 96, 85, 82, 90, 78, 94, 76, 66, 87,
+  71, 88, 104, 71, 94, 76, 92, 77, 82, 85,
+  96, 85, 104, 76, 72, 82, 95, 94, 69, 78,
+  85, 94, 86, 77, 76, 73, 84, 96, 91, 81,
+  90, 86, 50, 78, 131, 91, 75, 91, 94, 78,
+  95, 79, 98, 80, 96, 83, 77, 97, 78, 74,
+  70, 82, 76, 81, 84, 72, 112, 64, 70, 92,
+  88, 73, 112, 74, 83, 66, 63, 85, 64, 87,
+  79, 71, 99, 82, 81, 96, 91, 76, 88, 72,
+  85, 78, 77, 81, 82, 87, 119, 66, 84, 86,
+  78, 85, 89, 89, 91, 87, 84, 86, 68, 82,
+  89, 89, 83, 74, 103, 84, 82, 67, 88, 83,
+  76, 87, 94, 94, 69, 80, 87, 84, 89, 90,
+  83, 86, 94, 74, 96, 76, 62, 84, 79, 85,
+  112, 66, 96, 69, 93, 69, 97, 89, 87, 87,
+  105, 75, 79, 83, 99, 84, 68, 78, 90, 91,
+  91, 80, 75, 81, 92, 95, 85, 79, 84, 86,
+  55, 83, 135, 77, 72, 95, 91, 79, 92, 76,
+  96, 86, 98, 79, 79, 97, 82, 79, 70, 79,
+  68, 81, 78, 76, 105, 62, 84, 86, 83, 73,
+  109, 69, 82, 79, 68, 83, 63, 85, 86, 85,
+  97, 83, 81, 91, 91, 82, 85, 72, 81, 78,
+  70, 80, 79, 87, 112, 69, 81, 81, 75, 84,
+  86, 95, 91, 90, 89, 87, 62, 85, 87, 84,
+  75, 81, 89, 85, 83, 63, 71, 82, 71, 87,
+  93, 94, 69, 84, 88, 92, 88, 87, 88, 98,
+  91, 78, 83, 80, 74, 83, 83, 84, 101, 76,
+  93, 76, 94, 81, 102, 84, 92, 86, 97, 72,
+  77, 83, 87, 81, 69, 84, 86, 95, 95, 85,
+  79, 74, 89, 91, 94, 79, 78, 79, 59, 77,
+  112, 65, 77, 93, 93, 76, 93, 81, 96, 86,
+  85, 90, 75, 90, 85, 80, 78, 73, 81, 84,
+  86, 77, 105, 68, 96, 99, 86, 80, 105, 77,
+  80, 83, 75, 89, 68, 78, 81, 89, 95, 87,
+  83, 94, 89, 87, 88, 78, 84, 80, 80, 86,
+  84, 85, 101, 78, 84, 84, 75, 84, 87, 96,
+  86, 92, 90, 85, 61, 80, 86, 79, 82, 88,
+  77, 87, 88, 72, 64, 79, 80, 87, 93, 95,
+  72, 82, 90, 67, 83, 99, 84, 95, 86, 84,
+  94, 87, 72, 88, 75, 86, 89, 70, 90, 78,
+  83, 74, 72, 81, 87, 83, 94, 73, 65, 90,
+  96, 82, 64, 77, 83, 93, 82, 81, 71, 81,
+  81, 88, 91, 83, 74, 80, 59, 82, 124, 95,
+  77, 91, 95, 79, 81, 88, 82, 82, 88, 84,
+  85, 93, 77, 64, 70, 90, 80, 88, 87, 66,
+  114, 65, 74, 82, 87, 64, 104, 71, 79, 70,
+  62, 85, 70, 92, 89, 76, 94, 84, 83, 88,
+  90, 79, 87, 82, 85, 79, 83, 73, 84, 88,
+  117, 78, 85, 82, 70, 81, 91, 78, 86, 86,
+  86, 84, 70, 81, 87, 88, 80, 76, 95, 84,
+  77, 67, 92, 86, 74, 84, 90, 86, 73, 85,
+  88, 79, 88, 88, 82, 93, 87, 86, 92, 86,
+  70, 85, 76, 81, 94, 61, 91, 70, 81, 72,
+  80, 90, 87, 82, 104, 72, 66, 89, 96, 75,
+  64, 79, 83, 86, 84, 82, 73, 84, 84, 85,
+  88, 85, 73, 79, 62, 82, 128, 83, 75, 96,
+  92, 80, 77, 85, 83, 86, 88, 83, 90, 93,
+  81, 71, 69, 88, 76, 90, 88, 71, 111, 65,
+  83, 76, 84, 64, 104, 65, 79, 80, 64, 82,
+  71, 90, 93, 86, 93, 88, 80, 85, 88, 77,
+  82, 73, 83, 80, 74, 71, 83, 87, 97, 80,
+  82, 79, 70, 80, 89, 85, 84, 86, 84, 82,
+  64, 85, 87, 85, 73, 83, 85, 83, 80, 66,
+  78, 87, 63, 88, 85, 87, 76, 88, 91, 89,
+  97, 86, 84, 96, 89, 85, 80, 91, 75, 87,
+  79, 82, 85, 69, 86, 80, 89, 82, 87, 87,
+  100, 83, 97, 73, 73, 88, 87, 79, 69, 84,
+  85, 86, 88, 85, 78, 81, 81, 79, 96, 81,
+  74, 75, 65, 80, 104, 73, 79, 91, 90, 80,
+  87, 87, 89, 90, 83, 91, 85, 87, 83, 77,
+  76, 82, 85, 92, 90, 71, 103, 76, 90, 89,
+  89, 72, 99, 73, 81, 81, 70, 87, 74, 83,
+  85, 89, 91, 85, 82, 88, 86, 87, 87, 83,
+  84, 78, 83, 80, 84, 90, 83, 86, 87, 73,
+  74, 82, 91, 88, 79, 89, 88, 80, 67, 84,
+  88, 84, 82, 89, 82, 87, 82, 74, 74, 84,
+  77, 84, 90, 88, 73, 84, 90, 74, 72, 100,
+  79, 111, 77, 85, 84, 94, 69, 89, 75, 88,
+  84, 80, 105, 99, 86, 80, 66, 73, 83, 80,
+  96, 78, 72, 94, 98, 82, 66, 77, 74, 90,
+  77, 76, 86, 85, 86, 90, 99, 59, 68, 81,
+  62, 87, 126, 93, 81, 90, 86, 74, 85, 90,
+  87, 80, 77, 83, 91, 90, 87, 68, 76, 92,
+  85, 79, 93, 68, 114, 79, 76, 75, 96, 66,
+  103, 74, 68, 69, 73, 82, 72, 100, 89, 85,
+  90, 86, 86, 91, 85, 88, 88, 111, 75, 80,
+  97, 75, 76, 99, 114, 81, 83, 82, 67, 77,
+  86, 69, 79, 89, 87, 84, 71, 80, 91, 82,
+  77, 74, 82, 83, 77, 70, 87, 91, 97, 70,
+  90, 90, 74, 81, 88, 80, 83, 92, 79, 90,
+  75, 91, 85, 97, 72, 88, 80, 86, 83, 74,
+  108, 95, 84, 80, 65, 83, 96, 78, 113, 81,
+  68, 96, 97, 71, 71, 76, 76, 81, 76, 80,
+  86, 86, 90, 90, 97, 62, 69, 79, 65, 80,
+  138, 81, 80, 95, 85, 77, 81, 85, 86, 75,
+  78, 83, 100, 92, 85, 70, 75, 95, 79, 83,
+  101, 75, 115, 77, 76, 77, 93, 66, 107, 70,
+  67, 83, 69, 81, 71, 98, 90, 85, 89, 93,
+  78, 90, 81, 81, 88, 96, 81, 86, 80, 72,
+  74, 98, 93, 81, 81, 78, 64, 77, 83, 74,
+  79, 89, 84, 85, 70, 83, 92, 79, 72, 81,
+  80, 82, 85, 69, 84, 95, 94, 78, 87, 89,
+  77, 89, 95, 85, 98, 90, 82, 84, 80, 92,
+  76, 95, 76, 85, 77, 81, 79, 77, 104, 97,
+  87, 86, 74, 80, 109, 84, 109, 79, 75, 90,
+  89, 74, 75, 84, 76, 75, 86, 81, 88, 87,
+  88, 83, 101, 65, 77, 77, 69, 83, 114, 71,
+  79, 88, 88, 77, 87, 87, 94, 81, 77, 87,
+  92, 84, 87, 78, 80, 88, 83, 85, 96, 67,
+  101, 87, 79, 79, 99, 73, 97, 75, 78, 88,
+  73, 82, 75, 91, 85, 85, 82, 88, 77, 86,
+  86, 87, 85, 96, 76, 79, 86, 81, 81, 98,
+  72, 84, 84, 74, 68, 80, 83, 71, 74, 90,
+  86, 75, 74, 83, 92, 82, 84, 85, 86, 86,
+  77, 77, 85, 89, 86, 73, 86, 91, 73, 84,
+  86, 71, 124, 94, 71, 98, 88, 79, 83, 92,
+  73, 70, 82, 91, 77, 80, 76, 99, 80, 86,
+  95, 81, 109, 87, 93, 75, 98, 93, 90, 99,
+  81, 82, 93, 70, 79, 90, 90, 86, 83, 77,
+  90, 72, 72, 65, 79, 87, 88, 76, 89, 87,
+  75, 85, 96, 81, 89, 80, 90, 68, 85, 84,
+  87, 93, 81, 70, 89, 79, 93, 90, 68, 89,
+  72, 86, 95, 85, 84, 85, 88, 92, 69, 69,
+  78, 83, 79, 96, 75, 89, 87, 91, 79, 79,
+  97, 74, 88, 72, 91, 82, 72, 73, 62, 84,
+  88, 77, 82, 83, 81, 93, 75, 92, 77, 90,
+  87, 78, 83, 80, 68, 92, 92, 90, 74, 90,
+  101, 84, 78, 77, 82, 92, 80, 83, 100, 70,
+  108, 83, 85, 79, 86, 74, 87, 79, 81, 80,
+  88, 77, 86, 74, 92, 92, 86, 80, 94, 75,
+  94, 86, 99, 75, 81, 87, 93, 106, 101, 81,
+  85, 70, 73, 77, 83, 78, 100, 74, 80, 93,
+  58, 76, 88, 73, 86, 74, 79, 83, 85, 76,
+  88, 88, 87, 83, 81, 86, 85, 78, 86, 80,
+  80, 89, 71, 92, 93, 79, 67, 86, 71, 90,
+  82, 83, 85, 78, 98, 90, 62, 97, 77, 93,
+  82, 97, 89, 84, 71, 86, 75, 76, 83, 67,
+  78, 79, 73, 90, 83, 107, 65, 78, 79, 83,
+  81, 84, 83, 105, 70, 85, 78, 85, 92, 83,
+  87, 74, 86, 95, 73, 86, 79, 82, 93, 93,
+  83, 77, 83, 84, 88, 88, 83, 83, 127, 87,
+  90, 74, 81, 74, 92, 75, 90, 76, 76, 65,
+  93, 86, 85, 81, 82, 82, 84, 71, 90, 89,
+  104, 76, 75, 81, 88, 111, 103, 75, 82, 66,
+  71, 89, 68, 84, 99, 75, 92, 76, 57, 77,
+  85, 76, 106, 72, 82, 83, 76, 69, 78, 88,
+  83, 77, 76, 110, 80, 83, 89, 87, 77, 107,
+  88, 86, 97, 77, 75, 71, 82, 88, 79, 92,
+  93, 80, 97, 82, 66, 84, 79, 93, 83, 93,
+  98, 99, 63, 88, 72, 76, 80, 72, 83, 84,
+  78, 89, 89, 114, 62, 76, 83, 75, 82, 83,
+  94, 91, 71, 78, 80, 78, 91, 82, 83, 76,
+  88, 86, 86, 83, 92, 75, 95, 91, 81, 79,
+  80, 89, 91, 82, 95, 67, 105, 83, 76, 87,
+  84, 73, 78, 83, 89, 75, 92, 83, 85, 62,
+  86, 92, 89, 70, 85, 81, 95, 94, 101, 77,
+  85, 88, 91, 114, 104, 76, 85, 68, 71, 74,
+  94, 77, 96, 74, 83, 97, 60, 71, 93, 75,
+  91, 71, 80, 82, 71, 75, 90, 91, 89, 88,
+  78, 94, 77, 81, 94, 88, 74, 97, 68, 98,
+  103, 84, 69, 73, 64, 86, 84, 88, 81, 72,
+  90, 77, 65, 90, 78, 91, 79, 88, 88, 80,
+  72, 89, 78, 74, 83, 70, 85, 84, 80, 84,
+  83, 108, 64, 75, 81, 78, 88, 81, 84, 94,
+  76, 89, 75, 90, 87, 84, 89, 64, 87, 95,
+  81, 88, 82, 81, 94, 88, 75, 75, 77, 86,
+  90, 89, 93, 74, 123, 90, 94, 66, 82, 70,
+  85, 81, 90, 76, 96, 83, 90, 80, 90, 78,
+  80, 77, 87, 77, 78, 94, 102, 79, 77, 84,
+  89, 115, 106, 83, 84, 69, 65, 76, 76, 88,
+  95, 76, 88, 89, 57, 84, 94, 79, 98, 72,
+  76, 79, 73, 76, 86, 96, 78, 78, 70, 99,
+  81, 80, 89, 82, 78, 97, 62, 95, 103, 68,
+  79, 74, 66, 84, 76, 88, 82, 73, 97, 87,
+  64, 95, 85, 95, 87, 89, 99, 94, 64, 85,
+  75, 70, 77, 70, 76, 85, 70, 91, 86, 105,
+  64, 75, 75, 78, 89, 82, 87, 86, 78, 83,
+  75, 79, 87, 79, 85, 64, 91, 102, 81, 87,
+  89, 76, 90, 89, 82, 75, 81, 84, 87, 86,
+  75, 83, 126, 87, 86, 67, 76, 73, 92, 85,
+  80, 75, 77, 89, 74, 96, 79, 72, 79, 85,
+  93, 75, 80, 95, 91, 72, 83, 77, 87, 114,
+  89, 78, 83, 65, 72, 87, 74, 93, 81, 69,
+  91, 53, 68, 77, 68, 89, 103, 70, 90, 80,
+  68, 87, 82, 88, 89, 76, 84, 95, 90, 80,
+  87, 100, 92, 81, 83, 69, 97, 77, 77, 77,
+  78, 69, 97, 90, 86, 82, 85, 84, 84, 67,
+  89, 87, 83, 86, 88, 104, 76, 86, 84, 71,
+  79, 82, 81, 75, 91, 78, 84, 72, 65, 81,
+  88, 82, 82, 81, 91, 88, 81, 80, 76, 76,
+  76, 81, 81, 79, 88, 88, 103, 80, 84, 90,
+  102, 81, 79, 75, 82, 97, 82, 82, 87, 67,
+  119, 92, 78, 86, 81, 68, 74, 74, 84, 77,
+  105, 75, 84, 72, 85, 83, 84, 77, 99, 75,
+  84, 94, 97, 75, 81, 84, 93, 115, 99, 91,
+  80, 76, 64, 81, 83, 89, 93, 89, 94, 97,
+  51, 74, 91, 69, 92, 77, 91, 76, 69, 64,
+  79, 92, 76, 74, 77, 95, 81, 83, 93, 78,
+  81, 84, 69, 87, 98, 86, 85, 80, 72, 99,
+  73, 88, 77, 75, 89, 87, 63, 109, 78, 85,
+  86, 87, 96, 91, 69, 79, 84, 75, 81, 70,
+  88, 96, 70, 86, 91, 99, 76, 85, 69, 78,
+  88, 79, 91, 84, 78, 80, 63, 76, 76, 73,
+  82, 64, 89, 86, 67, 95, 92, 72, 91, 84,
+  74, 77, 86, 89, 83, 82, 74, 77, 122, 87,
+  80, 94, 80, 70, 84, 80, 76, 76, 88, 96,
+  74, 92, 78, 81, 80, 85, 110, 82, 86, 89,
+  81, 69, 82, 78, 95, 115, 80, 88, 83, 70,
+  74, 91, 82, 88, 79, 75, 92, 62, 57, 74,
+  82, 84, 91, 74, 92, 75, 70, 84, 80, 83,
+  89, 68, 82, 83, 93, 79, 85, 83, 95, 51,
+  72, 67, 81, 80, 77, 82, 74, 82, 90, 90,
+  75, 87, 88, 97, 70, 87, 84, 82, 79, 90,
+  80, 93, 86, 83, 91, 71, 85, 78, 82, 74,
+  92, 78, 85, 66, 67, 80, 81, 69, 80, 80,
+  82, 85, 82, 81, 70, 76, 75, 77, 77, 78,
+  82, 89, 101, 81, 80, 86, 98, 83, 83, 75,
+  83, 91, 75, 77, 65, 79, 101, 80, 86, 78,
+  85, 81, 87, 93, 76, 87, 71, 102, 77, 89,
+  74, 86, 96, 93, 127, 82, 78, 85, 78, 81,
+  91, 76, 95, 104, 87, 83, 87, 77, 75, 76,
+  77, 84, 76, 67, 84, 57, 68, 91, 82, 96,
+  90, 74, 101, 82, 75, 102, 85, 83, 92, 70,
+  109, 82, 106, 84, 81, 82, 96, 66, 79, 69,
+  77, 97, 71, 69, 78, 74, 100, 100, 79, 105,
+  86, 82, 81, 76, 91, 84, 83, 87, 75, 90,
+  94, 90, 93, 77, 95, 83, 84, 76, 94, 75,
+  80, 64, 66, 88, 91, 86, 87, 80, 83, 83,
+  90, 92, 83, 89, 82, 79, 94, 81, 78, 80,
+  97, 81, 89, 99, 96, 87, 85, 96, 92, 92,
+  82, 80, 81, 88, 79, 82, 65, 78, 77, 85,
+  83, 98, 81, 90, 76, 77, 76, 81, 81, 97,
+  83, 97, 82, 76, 109, 98, 88, 81, 94, 84,
+  89, 86, 82, 82, 98, 93, 99, 87, 86, 88,
+  79, 78, 80, 90, 70, 77, 96, 74, 85, 77,
+  83, 79, 76, 96, 93, 78, 96, 76, 86, 67,
+  101, 92, 89, 81, 80, 65, 74, 86, 79, 77,
+  73, 91, 77, 88, 77, 85, 81, 96, 94, 91,
+  89, 80, 82, 72, 76, 110, 73, 82, 97, 81,
+  91, 84, 90, 75, 90, 74, 84, 77, 85, 89,
+  84, 95, 67, 85, 85, 91, 85, 89, 91, 93,
+  100, 108, 87, 69, 88, 85, 70, 93, 80, 83,
+  86, 88, 70, 93, 91, 90, 76, 82, 79, 98,
+  93, 76, 81, 74, 109, 65, 71, 76, 74, 92,
+  92, 83, 87, 87, 80, 69, 79, 78, 77, 99,
+  84, 83, 95, 82, 88, 73, 72, 83, 89, 86,
+  76, 86, 78, 92, 88, 85, 90, 77, 81, 82,
+  82, 86, 78, 82, 94, 67, 76, 74, 94, 65,
+  93, 75, 77, 90, 68, 82, 84, 87, 75, 84,
+  93, 89, 90, 73, 77, 84, 77, 79, 95, 87,
+  83, 96, 79, 75, 83, 85, 73, 86, 97, 95,
+  74, 89, 76, 115, 101, 76, 96, 87, 71, 84,
+  83, 74, 72, 91, 80, 103, 93, 89, 93, 99,
+  71, 89, 78, 91, 89, 84, 81, 95, 106, 79,
+  88, 77, 80, 83, 92, 84, 60, 99, 80, 76,
+  71, 69, 75, 77, 86, 77, 88, 62, 96, 80,
+  90, 86, 111, 78, 71, 81, 66, 89, 95, 79,
+  89, 78, 80, 73, 79, 67, 69, 102, 87, 88,
+  76, 68, 90, 78, 65, 80, 88, 87, 79, 97,
+  72, 94, 89, 96, 84, 70, 72, 84, 82, 77,
+  97, 78, 94, 68, 64, 90, 101, 64, 86, 65,
+  71, 101, 54, 76, 70, 107, 66, 83, 99, 96,
+  93, 90, 87, 93, 73, 85, 101, 76, 91, 110,
+  77, 74, 87, 74, 67, 98, 108, 104, 74, 101,
+  72, 93, 111, 81, 99, 91, 80, 79, 70, 79,
+  67, 95, 84, 115, 92, 96, 93, 84, 75, 90,
+  79, 93, 92, 73, 84, 87, 103, 65, 94, 84,
+  76, 92, 102, 86, 75, 104, 77, 82, 84, 74,
+  70, 72, 96, 77, 87, 53, 79, 84, 85, 87,
+  58, 81, 82, 84, 92, 96, 79, 87, 77, 75,
+  72, 94, 81, 103, 87, 88, 80, 78, 91, 94,
+  82, 74, 105, 84, 93, 90, 81, 76, 99, 85,
+  103, 82, 89, 90, 70, 78, 80, 92, 72, 76,
+  82, 84, 95, 78, 72, 92, 73, 97, 94, 75,
+  102, 74, 92, 68, 107, 89, 87, 75, 72, 60,
+  66, 78, 70, 71, 72, 89, 76, 81, 89, 91,
+  81, 93, 97, 81, 89, 74, 85, 70, 87, 96,
+  70, 80, 95, 73, 87, 85, 89, 89, 89, 73,
+  84, 59, 71, 79, 81, 94, 78, 83, 90, 88,
+  81, 84, 78, 88, 92, 111, 85, 81, 93, 85,
+  72, 85, 74, 68, 81, 89, 67, 101, 99, 94,
+  80, 76, 81, 105, 89, 75, 74, 78, 87, 69,
+  73, 81, 80, 91, 84, 88, 83, 91, 83, 71,
+  82, 85, 83, 90, 83, 86, 96, 94, 83, 65,
+  89, 84, 92, 77, 67, 87, 90, 97, 94, 89,
+  74, 83, 76, 79, 83, 86, 74, 76, 80, 68,
+  80, 77, 83, 75, 91, 81, 81, 78, 76, 79,
+  90, 76, 83, 88, 95, 91, 79, 70, 71, 80,
+  72, 76, 93, 87, 75, 81, 83, 81, 77, 83,
+  87, 84, 93, 86, 71, 82, 81, 108, 89, 79,
+  93, 85, 70, 85, 88, 75, 80, 82, 83, 77,
+  83, 85, 89, 101, 70, 94, 81, 91, 75, 88,
+  83, 93, 92, 92, 79, 94, 85, 86, 81, 81,
+  62, 85, 77, 77, 72, 79, 80, 77, 71, 69,
+  88, 75, 95, 85, 85, 87, 100, 81, 77, 83,
+  72, 88, 88, 82, 88, 83, 82, 73, 89, 70,
+  73, 94, 89, 86, 84, 84, 86, 75, 83, 85,
+  94, 88, 69, 97, 79, 88, 90, 97, 66, 78,
+  82, 78, 85, 77, 86, 80, 86, 70, 69, 92,
+  93, 65, 98, 61, 75, 89, 62, 84, 76, 102,
+  72, 80, 96, 101, 81, 83, 82, 89, 79, 82,
+  108, 85, 85, 90, 77, 76, 81, 72, 82, 93,
+  97, 100, 72, 96, 73, 86, 107, 91, 89, 97,
+  78, 82, 75, 71, 75, 88, 80, 94, 86, 98,
+  87, 84, 76, 94, 79, 92, 74, 83, 91, 91,
+  91, 78, 86, 98, 78, 88, 91, 81, 80, 95,
+  74, 80, 83, 76, 71, 69, 78, 72, 85, 64,
+  84, 85, 90, 93, 69, 84, 84, 82, 96, 88,
+  70, 83, 82, 73, 72, 104, 70, 101, 78, 85,
+  81, 82, 93, 91, 87, 85, 94, 75, 85, 85,
+  86, 78, 86, 85, 84, 80, 81, 92, 75, 87,
+  83, 78, 76, 89, 79, 89, 92, 77, 71, 95,
+  65, 108, 95, 82, 107, 83, 89, 84, 102, 86,
+  90, 77, 80, 70, 83, 73, 75, 80, 69, 99,
+  79, 74, 71, 86, 83, 81, 92, 79, 89, 71,
+  104, 72, 88, 89, 80, 88, 93, 67, 94, 92,
+  81, 90, 79, 71, 85, 68, 70, 82, 78, 86,
+  72, 85, 88, 78, 90, 73, 70, 78, 86, 94,
+  93, 68, 88, 82, 77, 90, 84, 67, 80, 88,
+  58, 95, 95, 89, 97, 85, 73, 87, 90, 87,
+  83, 87, 74, 73, 76, 83, 97, 90, 74, 92,
+  80, 77, 81, 81, 68, 95, 80, 82, 82, 89,
+  101, 91, 91, 77, 97, 83, 82, 78, 76, 83,
+  98, 81, 92, 90, 79, 88, 79, 80, 87, 76,
+  75, 80, 73, 81, 81, 73, 77, 101, 77, 100,
+  91, 78, 98, 81, 84, 80, 92, 89, 92, 82,
+  82, 83, 83, 81, 80, 82, 71, 94, 71, 77,
+  80, 91, 79, 82, 92, 86, 87, 67, 89, 74,
+  90, 104, 85, 84, 91, 81, 84, 88, 88, 85,
+  81, 73, 79, 66, 83, 82, 80, 92, 78, 81,
+  82, 82, 86, 76, 80, 83, 85, 92, 85, 78,
+  83, 84, 74, 89, 75, 71, 81, 84, 72, 89,
+  92, 80, 85, 82, 79, 88, 92, 83, 94, 92,
+  80, 82, 79, 80, 89, 89, 78, 92, 85, 84,
+  85, 77, 71, 85, 73, 82, 87, 88, 98, 88,
+  91, 84, 96, 84, 88, 92, 76, 89, 86, 87,
+  83, 92, 71, 89, 83, 82, 89, 81, 83, 77,
+  77, 80, 75, 92, 85, 89, 92, 90, 87, 83,
+  90, 80, 74, 90, 87, 88, 93, 95, 84, 84,
+  85, 91, 80, 87, 83, 81, 86, 89, 78, 83,
+  81, 84, 94, 83, 82, 77, 87, 83, 84, 90,
+  96, 91, 92, 88, 92, 85, 87, 81, 78, 78,
+  78, 78, 89, 92, 77, 86, 76, 85, 79, 85,
+  78, 84, 89, 86, 86, 86, 92, 85, 78, 88,
+  81, 81, 91, 80, 81, 85, 85, 82, 86, 72,
+  80, 83, 78, 73,
+};
+
+unsigned char expected_c_data[c_count] = {
+  166, 113, 100, 112, 92, 110, 111, 106, 135, 122,
+  107, 118, 103, 122, 139, 115, 133, 93, 102, 103,
+  108, 107, 92, 93, 105, 111, 148, 115, 108, 121,
+  123, 102, 136, 137, 101, 137, 113, 99, 115, 128,
+  151, 105, 119, 99, 98, 98, 102, 89, 78, 99,
+  125, 118, 124, 145, 126, 107, 118, 130, 141, 105,
+  121, 108, 121, 123, 150, 158, 121, 90, 101, 115,
+  110, 115, 104, 124, 99, 117, 197, 111, 122, 111,
+  118, 117, 81, 116, 107, 107, 159, 131, 90, 119,
+  122, 111, 102, 112, 115, 132, 107, 91, 114, 149,
+  138, 106, 146, 104, 114, 99, 141, 97, 98, 88,
+  137, 107, 93, 124, 100, 82, 116, 94, 100, 102,
+  132, 120, 123, 129, 108, 129, 95, 113, 121, 129,
+  105, 108, 107, 141, 109, 77, 117, 102, 101, 131,
+  92, 118, 111, 122, 97, 115, 147, 119, 112, 113,
+  125, 120, 110, 111, 77, 109, 106, 103, 101, 109,
+  92, 102, 155, 91, 88, 105, 122, 105, 112, 102,
+  119, 94, 111, 103, 82, 123, 85, 105, 79, 141,
+  124, 121, 116, 110, 134, 99, 117, 72, 86, 108,
+  118, 103, 169, 122, 140, 102, 80, 105, 97, 94,
+  144, 158, 97, 127, 112, 138, 131, 104, 120, 82,
+  84, 93, 109, 106, 70, 89, 94, 112, 130, 124,
+  119, 117, 109, 97, 110, 131, 89, 116, 97, 119,
+  129, 96, 156, 78, 121, 118, 89, 89, 101, 102,
+  28, 108, 145, 125, 115, 132, 116, 108, 144, 127,
+  120, 121, 130, 116, 116, 136, 147, 152, 113, 84,
+  89, 114, 126, 104, 122, 117, 98, 82, 149, 104,
+  139, 91, 109, 124, 91, 115, 129, 134, 203, 144,
+  86, 102, 119, 112, 97, 99, 120, 127, 103, 76,
+  116, 155, 156, 113, 170, 96, 123, 99, 155, 125,
+  84, 85, 139, 119, 90, 140, 82, 87, 113, 99,
+  91, 104, 148, 145, 115, 121, 97, 131, 72, 120,
+  125, 131, 144, 68, 112, 164, 111, 84, 124, 92,
+  82, 146, 104, 112, 132, 135, 90, 121, 151, 134,
+  105, 113, 122, 125, 104, 118, 106, 98, 88, 102,
+  111, 108, 138, 116, 147, 79, 122, 112, 112, 144,
+  91, 71, 113, 119, 89, 102, 95, 122, 71, 102,
+  77, 149, 123, 108, 125, 89, 145, 100, 129, 85,
+  76, 110, 105, 126, 156, 112, 139, 104, 63, 95,
+  85, 106, 124, 166, 79, 121, 129, 132, 122, 102,
+  105, 93, 83, 82, 119, 101, 86, 131, 78, 103,
+  118, 127, 132, 103, 110, 94, 99, 109, 100, 130,
+  77, 146, 158, 88, 132, 95, 117, 108, 72, 120,
+  115, 121, 34, 129, 158, 115, 118, 98, 111, 122,
+  134, 99, 101, 121, 114, 125, 112, 125, 124, 110,
+  103, 96, 98, 127, 113, 105, 122, 110, 103, 85,
+  140, 119, 128, 110, 125, 114, 116, 85, 145, 135,
+  197, 142, 78, 86, 101, 132, 104, 109, 148, 129,
+  110, 93, 112, 126, 139, 114, 165, 100, 132, 102,
+  140, 165, 61, 131, 104, 120, 86, 143, 81, 105,
+  101, 124, 73, 107, 144, 156, 121, 120, 72, 129,
+  80, 122, 113, 123, 146, 55, 103, 148, 117, 142,
+  110, 101, 62, 162, 100, 100, 152, 144, 104, 114,
+  131, 146, 105, 118, 87, 105, 92, 107, 114, 88,
+  72, 112, 108, 135, 134, 142, 114, 97, 134, 101,
+  122, 158, 76, 81, 121, 140, 77, 102, 125, 105,
+  70, 94, 100, 141, 105, 103, 151, 93, 136, 112,
+  108, 94, 71, 113, 116, 132, 152, 97, 107, 107,
+  75, 113, 77, 134, 110, 128, 71, 110, 110, 95,
+  104, 79, 96, 97, 86, 93, 116, 134, 90, 131,
+  66, 90, 112, 111, 134, 97, 131, 130, 116, 91,
+  98, 140, 66, 127, 151, 119, 125, 104, 119, 72,
+  77, 109, 107, 116, 33, 128, 145, 129, 104, 109,
+  114, 121, 124, 94, 91, 146, 100, 113, 108, 130,
+  105, 89, 92, 98, 87, 98, 96, 97, 118, 120,
+  105, 132, 147, 141, 106, 119, 122, 116, 116, 79,
+  104, 115, 188, 130, 69, 97, 116, 117, 114, 111,
+  152, 127, 121, 100, 118, 115, 120, 116, 145, 89,
+  130, 115, 110, 138, 75, 134, 109, 90, 94, 145,
+  89, 115, 97, 137, 65, 111, 125, 134, 125, 145,
+  67, 115, 95, 116, 92, 126, 98, 79, 107, 134,
+  122, 128, 101, 118, 60, 161, 79, 106, 134, 128,
+  108, 99, 102, 122, 84, 116, 73, 121, 98, 95,
+  70, 74, 56, 98, 79, 147, 126, 127, 101, 110,
+  144, 114, 135, 112, 80, 95, 130, 165, 90, 126,
+  98, 99, 65, 98, 134, 138, 91, 114, 153, 104,
+  127, 116, 97, 89, 78, 112, 109, 111, 173, 110,
+  152, 106, 115, 154, 75, 128, 109, 91, 95, 114,
+  131, 101, 114, 90, 94, 104, 92, 112, 117, 101,
+  94, 99, 80, 114, 119, 95, 134, 109, 153, 139,
+  126, 111, 113, 130, 90, 105, 127, 122, 137, 103,
+  128, 59, 102, 109, 96, 121, 42, 128, 135, 138,
+  88, 142, 122, 118, 121, 110, 112, 143, 106, 112,
+  112, 117, 136, 120, 111, 123, 83, 88, 116, 97,
+  132, 131, 111, 108, 157, 130, 86, 106, 118, 121,
+  116, 108, 106, 96, 177, 130, 74, 93, 107, 114,
+  113, 121, 111, 137, 124, 85, 121, 135, 137, 131,
+  140, 91, 124, 106, 109, 100, 98, 103, 114, 109,
+  120, 133, 110, 113, 97, 137, 84, 121, 119, 129,
+  117, 135, 84, 117, 103, 119, 118, 97, 105, 100,
+  94, 114, 119, 118, 104, 117, 76, 155, 86, 134,
+  119, 124, 107, 106, 111, 104, 102, 114, 102, 112,
+  112, 118, 86, 102, 80, 97, 93, 115, 101, 100,
+  99, 107, 117, 129, 137, 107, 96, 123, 116, 134,
+  97, 104, 99, 111, 74, 97, 114, 133, 97, 131,
+  143, 103, 127, 106, 106, 81, 100, 118, 106, 100,
+  182, 115, 96, 110, 101, 149, 74, 123, 131, 88,
+  100, 112, 128, 98, 131, 95, 101, 105, 92, 124,
+  104, 84, 91, 128, 83, 97, 118, 93, 135, 105,
+  144, 109, 145, 118, 106, 126, 95, 108, 112, 126,
+  125, 98, 126, 59, 124, 111, 102, 129, 45, 119,
+  131, 115, 77, 141, 129, 126, 104, 125, 107, 122,
+  117, 105, 119, 117, 143, 133, 125, 106, 89, 93,
+  134, 103, 133, 120, 106, 108, 169, 124, 79, 105,
+  108, 128, 77, 106, 107, 100, 153, 134, 74, 79,
+  108, 135, 106, 118, 96, 125, 113, 72, 108, 133,
+  155, 112, 160, 89, 131, 77, 118, 110, 89, 89,
+  114, 120, 107, 126, 99, 114, 90, 120, 84, 120,
+  123, 124, 113, 126, 96, 120, 101, 125, 99, 104,
+  96, 98, 98, 113, 106, 119, 103, 104, 100, 149,
+  98, 131, 126, 125, 112, 108, 127, 103, 113, 115,
+  117, 97, 104, 116, 70, 91, 84, 97, 88, 103,
+  84, 127, 110, 91, 99, 126, 140, 84, 104, 113,
+  103, 100, 91, 90, 93, 125, 70, 93, 95, 115,
+  105, 128, 139, 109, 137, 98, 99, 75, 97, 111,
+  109, 105, 166, 123, 106, 112, 93, 132, 82, 102,
+  132, 90, 97, 117, 124, 111, 128, 101, 104, 94,
+  96, 130, 93, 74, 89, 128, 86, 100, 124, 86,
+  132, 113, 129, 105, 140, 128, 108, 109, 99, 105,
+  104, 120, 123, 89, 119, 52, 134, 110, 96, 133,
+  52, 106, 129, 114, 80, 128, 124, 121, 101, 112,
+  102, 119, 126, 96, 112, 120, 143, 134, 125, 107,
+  94, 99, 138, 104, 129, 110, 105, 110, 173, 110,
+  104, 92, 105, 123, 79, 100, 108, 111, 150, 139,
+  77, 80, 131, 132, 103, 105, 101, 110, 107, 70,
+  107, 127, 155, 107, 171, 97, 125, 77, 128, 113,
+  90, 85, 108, 121, 124, 126, 87, 113, 89, 97,
+  91, 119, 114, 131, 122, 115, 103, 127, 89, 117,
+  92, 89, 89, 84, 98, 108, 100, 98, 114, 87,
+  108, 137, 113, 136, 128, 137, 114, 105, 124, 125,
+  117, 119, 115, 125, 89, 108, 84, 93, 98, 95,
+  83, 101, 99, 137, 106, 85, 109, 134, 138, 104,
+  112, 92, 95, 110, 88, 81, 108, 134, 57, 80,
+  86, 119, 116, 115, 145, 101, 140, 97, 93, 78,
+  97, 119, 101, 110, 149, 117, 103, 118, 103, 125,
+  85, 99, 116, 95, 84, 118, 125, 124, 111, 99,
+  109, 94, 90, 124, 90, 66, 82, 123, 86, 105,
+  126, 78, 114, 109, 126, 97, 119, 148, 104, 89,
+  101, 105, 103, 115, 118, 81, 109, 56, 125, 107,
+  84, 123, 62, 102, 122, 103, 83, 111, 105, 106,
+  100, 93, 112, 118, 135, 97, 110, 116, 143, 147,
+  125, 103, 91, 94, 138, 99, 123, 111, 110, 111,
+  165, 108, 117, 89, 99, 120, 67, 101, 105, 106,
+  134, 137, 87, 79, 119, 114, 102, 96, 103, 114,
+  102, 71, 107, 143, 154, 91, 167, 104, 103, 90,
+  126, 102, 89, 80, 114, 131, 118, 128, 77, 107,
+  99, 87, 98, 110, 104, 125, 130, 118, 106, 125,
+  73, 119, 96, 91, 86, 72, 88, 107, 94, 102,
+  121, 77, 109, 114, 114, 138, 128, 142, 113, 102,
+  108, 133, 112, 113, 121, 117, 77, 106, 83, 107,
+  108, 88, 85, 96, 102, 119, 97, 76, 100, 135,
+  132, 101, 111, 80, 89, 117, 83, 69, 98, 124,
+  48, 67, 85, 123, 122, 109, 149, 90, 136, 93,
+  102, 79, 96, 140, 96, 114, 137, 110, 105, 122,
+  109, 118, 85, 106, 101, 100, 82, 112, 120, 128,
+  105, 96, 110, 97, 89, 110, 86, 69, 74, 110,
+  90, 114, 126, 71, 99, 104, 121, 87, 101, 164,
+  99, 76, 104, 104, 101, 104, 118, 84, 102, 64,
+  112, 96, 68, 118, 68, 98, 111, 106, 84, 101,
+  93, 99, 103, 90, 124, 120, 140, 95, 104, 111,
+  146, 155, 117, 94, 87, 90, 128, 97, 116, 114,
+  117, 96, 161, 106, 117, 88, 92, 115, 58, 103,
+  102, 96, 120, 125, 88, 74, 113, 96, 97, 90,
+  101, 110, 96, 67, 105, 156, 149, 90, 152, 98,
+  78, 95, 122, 86, 95, 71, 121, 133, 111, 129,
+  68, 97, 109, 78, 108, 99, 97, 113, 138, 112,
+  110, 119, 67, 115, 92, 97, 86, 72, 89, 112,
+  86, 102, 123, 69, 107, 98, 114, 122, 118, 145,
+  113, 99, 100, 126, 104, 110, 118, 103, 68, 104,
+  81, 121, 109, 78, 93, 87, 111, 100, 95, 74,
+  100, 126, 128, 100, 113, 81, 94, 121, 84, 71,
+  82, 119, 47, 63, 80, 122, 129, 107, 147, 80,
+  137, 84, 106, 77, 102, 153, 95, 118, 128, 106,
+  111, 123, 113, 118, 81, 114, 96, 105, 88, 110,
+  121, 125, 108, 94, 108, 94, 87, 105, 85, 74,
+  76, 95, 93, 120, 123, 76, 101, 104, 115, 78,
+  87, 163, 96, 73, 106, 111, 93, 93, 128, 87,
+  108, 75, 107, 90, 63, 118, 69, 89, 115, 112,
+  83, 98, 86, 95, 109, 94, 131, 124, 146, 102,
+  96, 109, 148, 153, 113, 99, 82, 85, 115, 93,
+  118, 112, 117, 84, 155, 108, 110, 102, 87, 110,
+  58, 114, 106, 82, 113, 109, 87, 77, 108, 86,
+  95, 95, 107, 107, 93, 65, 99, 166, 147, 90,
+  150, 95, 63, 87, 121, 80, 97, 69, 123, 134,
+  109, 125, 63, 87, 118, 73, 118, 88, 98, 111,
+  134, 102, 114, 121, 66, 111, 82, 106, 92, 76,
+  92, 118, 86, 109, 130, 65, 106, 94, 113, 109,
+  118, 153, 108, 99, 100, 114, 111, 108, 127, 95,
+  66, 105, 82, 134, 115, 73, 106, 82, 119, 97,
+  101, 72, 99, 116, 123, 102, 115, 85, 107, 121,
+  95, 78, 79, 108, 50, 68, 78, 118, 142, 103,
+  141, 79, 131, 74, 112, 83, 104, 153, 96, 120,
+  133, 107, 111, 127, 113, 120, 87, 117, 100, 123,
+  97, 115, 119, 118, 121, 94, 100, 91, 93, 104,
+  81, 75, 79, 90, 92, 125, 120, 87, 114, 104,
+  115, 77, 85, 158, 99, 85, 109, 123, 89, 93,
+  136, 99, 123, 89, 104, 105, 69, 124, 72, 91,
+  126, 100, 90, 87, 87, 97, 121, 97, 131, 120,
+  145, 109, 98, 107, 154, 149, 116, 95, 80, 85,
+  107, 99, 130, 115, 114, 82, 151, 111, 110, 119,
+  89, 106, 54, 116, 116, 91, 110, 98, 85, 84,
+  107, 85, 96, 102, 113, 112, 100, 68, 99, 162,
+  158, 91, 152, 95, 75, 95, 124, 95, 89, 71,
+  123, 134, 98, 126, 56, 83, 124, 87, 128, 86,
+  103, 111, 129, 92, 115, 126, 75, 107, 80, 107,
+  108, 85, 94, 120, 91, 121, 134, 70, 105, 101,
+  112, 106, 121, 162, 101, 99, 105, 100, 118, 107,
+  128, 97, 73, 111, 73, 141, 120, 75, 110, 90,
+  130, 110, 113, 86, 107, 106, 123, 94, 121, 102,
+  114, 124, 108, 85, 86, 99, 61, 83, 91, 109,
+  142, 104, 135, 82, 124, 70, 115, 95, 107, 145,
+  105, 126, 135, 106, 124, 124, 114, 119, 87, 123,
+  99, 122, 110, 114, 121, 113, 119, 90, 99, 88,
+  96, 103, 75, 91, 91, 88, 91, 126, 116, 92,
+  121, 107, 122, 83, 98, 147, 99, 90, 108, 121,
+  90, 96, 141, 104, 133, 87, 105, 102, 65, 124,
+  71, 102, 122, 93, 99, 85, 95, 99, 119, 97,
+  126, 132, 132, 106, 94, 108, 151, 151, 117, 88,
+  82, 77, 90, 102, 121, 119, 115, 87, 154, 113,
+  112, 135, 94, 104, 67, 113, 114, 100, 114, 100,
+  80, 97, 108, 94, 104, 104, 107, 108, 106, 67,
+  105, 145, 158, 100, 136, 98, 90, 87, 124, 113,
+  99, 68, 130, 119, 97, 131, 55, 81, 128, 103,
+  135, 90, 107, 115, 127, 89, 114, 126, 87, 105,
+  80, 96, 108, 96, 91, 98, 104, 130, 134, 70,
+  102, 103, 106, 97, 114, 164, 97, 97, 97, 93,
+  126, 107, 110, 97, 85, 113, 76, 148, 116, 69,
+  103, 98, 136, 98, 105, 101, 110, 100, 123, 92,
+  124, 117, 112, 123, 124, 82, 93, 95, 69, 95,
+  112, 102, 134, 110, 135, 81, 118, 73, 126, 87,
+  111, 133, 113, 122, 138, 107, 123, 122, 117, 119,
+  97, 126, 93, 104, 115, 110, 118, 110, 121, 88,
+  102, 85, 93, 110, 74, 84, 94, 98, 92, 119,
+  120, 86, 124, 103, 126, 87, 111, 142, 100, 85,
+  112, 111, 91, 104, 143, 104, 133, 89, 105, 92,
+  70, 127, 71, 107, 115, 102, 98, 93, 99, 95,
+  113, 104, 127, 138, 127, 106, 90, 110, 156, 152,
+  119, 84, 90, 71, 91, 100, 122, 123, 118, 92,
+  151, 114, 109, 128, 99, 102, 67, 119, 101, 100,
+  115, 104, 87, 103, 106, 106, 98, 108, 105, 106,
+  105, 74, 108, 139, 154, 101, 145, 94, 81, 86,
+  123, 95, 98, 68, 133, 111, 101, 130, 57, 81,
+  122, 101, 137, 94, 109, 113, 129, 84, 106, 120,
+  93, 110, 88, 88, 107, 93, 85, 94, 106, 128,
+  126, 68, 99, 100, 111, 100, 108, 155, 99, 92,
+  95, 94, 121, 109, 129, 96, 91, 114, 78, 157,
+  121, 70, 99, 95, 130, 102, 103, 109, 102, 112,
+  122, 85, 118, 120, 109, 118, 120, 89, 91, 93,
+  71, 96, 120, 101, 131, 115, 136, 84, 116, 75,
+  128, 100, 115, 132, 106, 116, 137, 109, 118, 127,
+  120, 130, 105, 109, 97, 107, 123, 111, 115, 117,
+  133, 98, 97, 84, 91, 118, 76, 68, 86, 103,
+  94, 118, 125, 78, 124, 102, 130, 79, 115, 145,
+  97, 77, 117, 108, 95, 100, 142, 96, 129, 92,
+  108, 114, 71, 128, 72, 107, 113, 101, 94, 90,
+  98, 94, 109, 102, 126, 131, 134, 108, 86, 106,
+  167, 157, 124, 89, 92, 72, 102, 91, 135, 125,
+  116, 88, 148, 105, 99, 109, 98, 108, 56, 111,
+  99, 103, 120, 104, 99, 106, 107, 98, 80, 112,
+  106, 112, 107, 82, 102, 157, 149, 105, 167, 91,
+  75, 93, 124, 90, 95, 62, 126, 127, 103, 123,
+  62, 86, 113, 87, 139, 96, 109, 115, 127, 85,
+  102, 112, 94, 106, 101, 88, 105, 89, 84, 102,
+  93, 123, 115, 64, 102, 100, 116, 100, 116, 143,
+  101, 94, 106, 96, 111, 107, 138, 95, 90, 116,
+  73, 160, 129, 81, 99, 90, 115, 113, 109, 102,
+  96, 123, 126, 83, 113, 108, 106, 122, 106, 77,
+  80, 97, 68, 81, 105, 102, 129, 121, 139, 80,
+  113, 66, 118, 115, 116, 134, 104, 115, 142, 111,
+  110, 120, 118, 148, 88, 94, 104, 119, 129, 109,
+  124, 130, 130, 110, 89, 85, 93, 116, 86, 73,
+  87, 95, 96, 128, 128, 74, 120, 103, 132, 76,
+  109, 152, 87, 77, 116, 122, 97, 97, 139, 94,
+  123, 87, 114, 120, 64, 123, 65, 100, 117, 95,
+  84, 86, 99, 101, 113, 101, 124, 124, 134, 97,
+  85, 101, 180, 169, 122, 101, 86, 77, 107, 93,
+  127, 128, 113, 77, 152, 99, 92, 97, 87, 118,
+  58, 104, 108, 98, 130, 114, 99, 98, 103, 88,
+  72, 111, 102, 114, 109, 78, 106, 167, 143, 112,
+  170, 89, 79, 75, 125, 103, 99, 61, 125, 141,
+  102, 124, 69, 96, 105, 86, 129, 96, 108, 128,
+  127, 97, 97, 109, 83, 110, 114, 90, 99, 92,
+  81, 105, 88, 120, 103, 67, 104, 104, 111, 94,
+  117, 145, 100, 103, 122, 96, 104, 102, 118, 92,
+  86, 113, 68, 147, 118, 78, 112, 94, 100, 99,
+  103, 84, 93, 121, 128, 92, 117, 92, 100, 118,
+  92, 68, 83, 103, 64, 63, 96, 106, 118, 134,
+  142, 73, 116, 63, 102, 95, 115, 135, 100, 112,
+  158, 115, 94, 110, 107, 154, 75, 91, 118, 123,
+  115, 107, 132, 126, 124, 117, 90, 91, 87, 112,
+  107, 88, 87, 87, 89, 118, 132, 81, 125, 106,
+  132, 78, 89, 147, 93, 94, 100, 138, 91, 94,
+  132, 94, 121, 69, 117, 115, 66, 120, 58, 98,
+  132, 102, 69, 88, 99, 108, 110, 107, 122, 115,
+  129, 95, 99, 101, 172, 168, 119, 114, 78, 86,
+  120, 98, 120, 139, 111, 70, 157, 114, 90, 99,
+  86, 124, 73, 105, 128, 108, 149, 130, 87, 71,
+  99, 86, 82, 114, 109, 110, 104, 80, 114, 164,
+  147, 116, 185, 83, 87, 72, 127, 117, 87, 72,
+  123, 146, 92, 123, 78, 105, 104, 98, 112, 98,
+  108, 133, 116, 123, 89, 132, 67, 125, 111, 121,
+  99, 94, 79, 120, 92, 110, 103, 84, 104, 122,
+  118, 110, 127, 144, 99, 111, 127, 94, 101, 107,
+  113, 92, 85, 103, 64, 119, 99, 79, 123, 108,
+  116, 99, 113, 79, 109, 111, 129, 97, 120, 92,
+  104, 121, 82, 70, 91, 106, 58, 68, 94, 112,
+  113, 141, 140, 80, 130, 69, 92, 78, 98, 133,
+  86, 121, 164, 110, 117, 105, 86, 140, 72, 96,
+  121, 124, 100, 110, 136, 102, 120, 111, 102, 111,
+  94, 106, 117, 116, 85, 111, 78, 107, 131, 97,
+  124, 99, 134, 103, 87, 124, 115, 133, 81, 137,
+  107, 88, 129, 92, 126, 69, 112, 117, 92, 128,
+  56, 113, 141, 113, 73, 90, 111, 117, 120, 122,
+  111, 112, 103, 105, 121, 113, 139, 131, 110, 119,
+  84, 96, 119, 107, 129, 145, 110, 80, 153, 130,
+  108, 120, 103, 120, 105, 93, 138, 119, 189, 134,
+  75, 68, 113, 116, 106, 121, 120, 110, 112, 88,
+  123, 144, 149, 125, 178, 83, 117, 84, 120, 156,
+  82, 95, 111, 140, 94, 130, 86, 110, 99, 119,
+  96, 106, 118, 126, 111, 134, 79, 173, 78, 128,
+  96, 144, 120, 98, 94, 129, 113, 111, 107, 107,
+  86, 150, 127, 124, 128, 127, 103, 103, 120, 100,
+  102, 119, 107, 111, 92, 100, 82, 95, 82, 96,
+  107, 119, 149, 131, 115, 87, 138, 100, 133, 108,
+  106, 116, 129, 133, 92, 94, 94, 109, 59, 91,
+  95, 120, 98, 129, 144, 93, 133, 89, 86, 78,
+  89, 124, 75, 136, 160, 117, 148, 102, 64, 120,
+  73, 141, 124, 109, 98, 117, 129, 79, 114, 110,
+  117, 122, 106, 102, 107, 143, 94, 138, 76, 99,
+  128, 106, 126, 105, 122, 146, 140, 107, 114, 159,
+  78, 125, 131, 99, 128, 90, 130, 73, 96, 111,
+  116, 142, 49, 135, 130, 128, 102, 113, 131, 129,
+  116, 139, 93, 135, 98, 113, 122, 127, 109, 94,
+  108, 114, 102, 110, 89, 110, 134, 130, 106, 111,
+  155, 132, 98, 133, 133, 118, 113, 84, 119, 114,
+  208, 130, 70, 99, 143, 141, 121, 112, 115, 110,
+  115, 105, 113, 114, 142, 131, 159, 92, 144, 78,
+  119, 153, 88, 104, 115, 112, 109, 138, 90, 111,
+  92, 128, 86, 112, 128, 136, 116, 126, 79, 169,
+  106, 122, 89, 132, 119, 91, 118, 124, 130, 129,
+  98, 119, 78, 180, 121, 117, 110, 112, 106, 90,
+  119, 115, 102, 118, 99, 124, 98, 110, 90, 77,
+  82, 96, 91, 125, 125, 165, 121, 101, 134, 109,
+  132, 123, 101, 117, 141, 114, 103, 108, 110, 113,
+  71, 114, 125, 113, 90, 116, 157, 107, 114, 109,
+  90, 95, 83, 104, 81, 128, 163, 137, 107, 104,
+  60, 118, 92, 138, 122, 92, 106, 132, 114, 98,
+  119, 104, 114, 102, 108, 106, 101, 118, 94, 157,
+  87, 100, 127, 109, 139, 104, 114, 158, 157, 122,
+  118, 145, 91, 113, 131, 126, 140, 89, 124, 77,
+  94, 117, 122, 148, 36, 137, 138, 140, 113, 129,
+  124, 129, 118, 121, 84, 109, 117, 116, 111, 128,
+  135, 105, 124, 105, 111, 120, 112, 122, 134, 117,
+  101, 109, 152, 118, 77, 110, 135, 114, 107, 90,
+  99, 115, 189, 136, 81, 119, 154, 131, 135, 110,
+  121, 121, 112, 119, 103, 117, 153, 111, 179, 100,
+  149, 73, 142, 112, 74, 87, 104, 106, 91, 130,
+  86, 114, 82, 113, 96, 113, 135, 162, 119, 113,
+  85, 144, 105, 118, 101, 109, 120, 76, 116, 123,
+  120, 123, 91, 110, 83, 188, 116, 137, 117, 122,
+  112, 101, 147, 133, 111, 118, 109, 138, 97, 119,
+  70, 81, 114, 89, 89, 120, 73, 176, 134, 99,
+  115, 148, 121, 129, 106, 94, 126, 111, 91, 118,
+  132, 123, 73, 97, 113, 101, 94, 117, 154, 117,
+  115, 105, 89, 106, 92, 103, 86, 102, 176, 145,
+  119, 100, 77, 131, 83, 97, 125, 108, 112, 126,
+  123, 128, 135, 100, 107, 74, 88, 113, 101, 87,
+  92, 112, 93, 88, 132, 98, 135, 110, 123, 123,
+  117, 138, 104, 103, 104, 120, 101, 123, 156, 80,
+  118, 73, 101, 116, 95, 127, 32, 129, 142, 120,
+  92, 105, 104, 112, 124, 87, 99, 102, 123, 113,
+  112, 122, 155, 152, 121, 98, 94, 96, 131, 106,
+  128, 120, 96, 102, 150, 101, 83, 92, 109, 128,
+  93, 88, 109, 113, 162, 138, 91, 117, 139, 98,
+  106, 106, 119, 129, 102, 103, 110, 152, 159, 104,
+  206, 101, 144, 96, 152, 98, 69, 67, 111, 127,
+  93, 121, 79, 106, 103, 105, 102, 115, 127, 160,
+  105, 114, 95, 132, 84, 116, 120, 89, 110, 74,
+  95, 109, 102, 104, 98, 98, 94, 176, 117, 138,
+  132, 134, 107, 116, 150, 123, 122, 108, 110, 122,
+  89, 118, 69, 100, 122, 86, 89, 113, 85, 133,
+  136, 83, 108, 156, 125, 113, 108, 85, 97, 129,
+  95, 71, 108, 113, 60, 88, 96, 100, 104, 138,
+  133, 93, 142, 95, 105, 105, 97, 109, 81, 110,
+  186, 132, 126, 94, 85, 137, 73, 86, 117, 123,
+  96, 120, 139, 138, 134, 101, 100, 84, 87, 102,
+  110, 76, 80, 94, 85, 92, 144, 92, 114, 107,
+  130, 105, 108, 154, 100, 101, 105, 127, 106, 93,
+  153, 85, 107, 82, 91, 119, 92, 106, 35, 129,
+  144, 104, 88, 90, 98, 109, 126, 87, 129, 91,
+  106, 109, 142, 119, 151, 175, 126, 104, 92, 90,
+  122, 85, 123, 131, 100, 79, 159, 108, 124, 97,
+  95, 130, 95, 78, 140, 122, 172, 138, 94, 82,
+  114, 110, 102, 111, 106, 110, 96, 80, 129, 171,
+  155, 115, 192, 95, 126, 101, 139, 118, 68, 73,
+  118, 160, 96, 113, 82, 109, 117, 112, 101, 113,
+  127, 130, 104, 147, 86, 151, 78, 122, 126, 114,
+  128, 80, 82, 107, 101, 113, 107, 106, 92, 149,
+  137, 129, 135, 131, 102, 103, 134, 108, 106, 102,
+  92, 97, 86, 113, 73, 104, 105, 87, 101, 101,
+  105, 94, 124, 77, 113, 115, 140, 98, 103, 112,
+  100, 121, 95, 53, 77, 109, 56, 94, 83, 117,
+  97, 145, 129, 76, 143, 92, 106, 87, 102, 122,
+  82, 139, 156, 126, 85, 91, 56, 117, 72, 105,
+  102, 123, 79, 127, 115, 127, 116, 81, 103, 100,
+  61, 81, 113, 139, 68, 121, 63, 93, 154, 101,
+  93, 89, 116, 122, 116, 124, 89, 118, 89, 129,
+  126, 92, 128, 99, 105, 104, 78, 84, 88, 93,
+  29, 114, 145, 117, 73, 90, 107, 90, 109, 143,
+  122, 99, 97, 116, 162, 149, 113, 145, 120, 99,
+  92, 109, 109, 83, 122, 117, 99, 102, 160, 145,
+  128, 95, 94, 118, 115, 61, 120, 133, 216, 131,
+  80, 82, 136, 132, 131, 112, 123, 87, 92, 94,
+  116, 138, 129, 96, 142, 84, 119, 91, 118, 139,
+  68, 100, 110, 131, 82, 118, 86, 126, 116, 114,
+  85, 111, 132, 107, 115, 174, 61, 184, 86, 133,
+  92, 180, 106, 78, 92, 129, 114, 86, 101, 107,
+  83, 124, 142, 95, 134, 126, 107, 83, 118, 121,
+  90, 107, 78, 106, 79, 84, 70, 78, 78, 98,
+  96, 118, 136, 106, 123, 70, 126, 93, 138, 116,
+  81, 103, 119, 109, 77, 90, 73, 111, 35, 102,
+  107, 130, 98, 122, 120, 97, 130, 86, 119, 78,
+  80, 107, 69, 162, 122, 131, 171, 101, 58, 121,
+  84, 123, 104, 119, 90, 147, 118, 156, 123, 93,
+  111, 110, 70, 65, 128, 142, 92, 104, 64, 124,
+  157, 93, 105, 91, 94, 154, 121, 108, 72, 140,
+  94, 153, 166, 97, 134, 114, 115, 109, 58, 93,
+  100, 124, 35, 136, 140, 143, 98, 110, 118, 103,
+  121, 151, 100, 113, 100, 120, 107, 148, 96, 99,
+  113, 102, 93, 152, 88, 111, 120, 107, 104, 88,
+  159, 128, 119, 85, 125, 114, 149, 66, 121, 134,
+  254, 131, 79, 100, 134, 140, 122, 111, 154, 99,
+  95, 98, 100, 97, 112, 138, 125, 95, 129, 104,
+  115, 146, 98, 117, 98, 99, 115, 117, 124, 134,
+  110, 115, 84, 116, 129, 136, 122, 131, 46, 179,
+  136, 120, 116, 116, 169, 82, 112, 114, 124, 114,
+  109, 109, 72, 131, 154, 106, 136, 152, 124, 66,
+  127, 141, 116, 119, 73, 116, 80, 87, 147, 78,
+  82, 123, 100, 126, 149, 128, 121, 108, 121, 129,
+  151, 221, 69, 95, 125, 135, 63, 104, 125, 125,
+  51, 113, 118, 123, 108, 117, 140, 111, 126, 98,
+  117, 103, 71, 97, 62, 139, 130, 114, 125, 106,
+  66, 125, 92, 153, 121, 110, 74, 142, 109, 158,
+  113, 85, 116, 96, 95, 70, 116, 130, 55, 181,
+  75, 129, 146, 94, 127, 87, 103, 156, 142, 106,
+  65, 145, 90, 145, 190, 118, 138, 118, 116, 97,
+  66, 107, 83, 139, 20, 127, 118, 125, 94, 110,
+  118, 95, 117, 102, 109, 127, 108, 109, 95, 118,
+  114, 105, 107, 80, 101, 147, 76, 127, 116, 112,
+  105, 94, 176, 89, 92, 93, 127, 109, 138, 73,
+  99, 104, 255, 135, 85, 106, 104, 139, 134, 103,
+  167, 127, 104, 85, 107, 93, 123, 122, 121, 94,
+  133, 84, 122, 142, 113, 97, 108, 91, 111, 123,
+  126, 127, 117, 110, 97, 110, 122, 126, 125, 122,
+  58, 151, 101, 108, 120, 106, 146, 88, 90, 93,
+  116, 160, 105, 106, 85, 121, 118, 106, 143, 151,
+  113, 80, 129, 129, 99, 108, 76, 73, 98, 92,
+  116, 72, 80, 121, 89, 136, 97, 112, 121, 111,
+  95, 133, 147, 212, 68, 88, 123, 140, 80, 78,
+  112, 130, 51, 107, 132, 112, 93, 123, 124, 104,
+  107, 89, 122, 76, 76, 93, 92, 89, 170, 113,
+  106, 101, 76, 144, 118, 139, 135, 107, 80, 134,
+  94, 161, 126, 69, 139, 70, 77, 94, 94, 139,
+  82, 135, 80, 126, 141, 99, 143, 109, 147, 128,
+  145, 132, 79, 132, 89, 126, 146, 128, 150, 113,
+  116, 107, 69, 100, 73, 119, 22, 128, 102, 108,
+  108, 114, 106, 94, 110, 78, 152, 108, 103, 92,
+  116, 112, 163, 183, 111, 90, 91, 95, 111, 104,
+  114, 126, 105, 118, 196, 94, 84, 103, 102, 124,
+  95, 77, 86, 111, 226, 160, 72, 140, 123, 134,
+  129, 94, 133, 136, 117, 79, 98, 120, 155, 106,
+  155, 95, 132, 86, 121, 104, 89, 65, 112, 96,
+  84, 131, 112, 111, 119, 97, 137, 114, 126, 121,
+  134, 133, 66, 140, 84, 114, 133, 115, 130, 86,
+  78, 90, 106, 103, 89, 105, 91, 119, 100, 94,
+  124, 152, 105, 104, 141, 126, 93, 96, 103, 90,
+  112, 102, 73, 98, 127, 88, 86, 127, 69, 79,
+  117, 119, 91, 121, 132, 107, 96, 96, 120, 104,
+  110, 75, 89, 117, 37, 94, 129, 123, 87, 133,
+  100, 93, 112, 88, 111, 51, 92, 94, 127, 97,
+  173, 118, 116, 97, 84, 152, 150, 88, 133, 132,
+  92, 125, 97, 160, 124, 73, 134, 64, 77, 100,
+  89, 75, 92, 103, 72, 138, 144, 87, 150, 120,
+  124, 95, 103, 143, 76, 101, 94, 148, 107, 108,
+  145, 102, 123, 100, 81, 110, 80, 103, 31, 142,
+  95, 97, 121, 115, 82, 89, 103, 115, 162, 119,
+  115, 91, 116, 114, 156, 185, 113, 106, 94, 82,
+  120, 91, 119, 121, 112, 102, 187, 91, 110, 107,
+  105, 127, 86, 88, 87, 124, 198, 164, 66, 117,
+  107, 143, 103, 89, 101, 102, 105, 86, 97, 133,
+  138, 119, 160, 95, 120, 101, 124, 112, 113, 82,
+  111, 103, 118, 143, 109, 122, 121, 72, 166, 112,
+  133, 132, 175, 126, 69, 115, 95, 122, 152, 116,
+  128, 64, 76, 106, 95, 103, 107, 102, 93, 110,
+  116, 92, 123, 171, 122, 109, 139, 143, 79, 103,
+  119, 111, 103, 110, 86, 110, 154, 81, 106, 111,
+  107, 78, 119, 111, 90, 117, 123, 114, 100, 81,
+  94, 102, 107, 71, 102, 112, 34, 77, 120, 166,
+  101, 124, 102, 98, 122, 120, 98, 66, 98, 113,
+  118, 139, 139, 116, 101, 102, 59, 116, 135, 75,
+  117, 149, 83, 123, 112, 129, 115, 79, 134, 97,
+  76, 88, 97, 71, 83, 91, 53, 120, 166, 87,
+  104, 103, 102, 82, 74, 122, 76, 105, 98, 163,
+  130, 117, 136, 91, 117, 85, 85, 119, 105, 101,
+  43, 133, 94, 112, 128, 115, 73, 80, 127, 136,
+  131, 109, 103, 93, 110, 127, 113, 123, 108, 101,
+  81, 98, 113, 90, 117, 98, 106, 103, 167, 111,
+  134, 120, 110, 121, 101, 100, 123, 97, 212, 132,
+  73, 103, 100, 135, 102, 84, 122, 81, 97, 109,
+  107, 111, 110, 110, 131, 103, 108, 105, 112, 115,
+  116, 111, 129, 100, 119, 144, 107, 151, 115, 84,
+  117, 117, 134, 124, 193, 140, 64, 108, 114, 134,
+  121, 141, 126, 52, 106, 149, 92, 109, 115, 112,
+  70, 112, 104, 123, 138, 173, 137, 107, 113, 149,
+  81, 109, 107, 119, 72, 95, 107, 86, 114, 104,
+  120, 137, 132, 111, 116, 88, 114, 101, 114, 135,
+  68, 67, 109, 158, 108, 87, 84, 126, 42, 78,
+  125, 192, 111, 103, 120, 97, 107, 136, 79, 83,
+  93, 106, 119, 150, 115, 107, 102, 111, 81, 98,
+  106, 98, 103, 110, 90, 122, 123, 111, 109, 77,
+  126, 118, 90, 89, 115, 123, 98, 137, 75, 122,
+  200, 95, 99, 107, 105, 113, 79, 115, 93, 131,
+  104, 143, 147, 124, 149, 103, 118, 88, 95, 111,
+  115, 104, 63, 118, 112, 128, 114, 121, 96, 89,
+  137, 115, 131, 104, 101, 107, 102, 132, 114, 108,
+  122, 112, 89, 111, 96, 104, 109, 92, 112, 116,
+  187, 133, 120, 128, 132, 97, 125, 107, 117, 112,
+  209, 118, 97, 118, 108, 117, 142, 107, 129, 118,
+  124, 122, 114, 110, 110, 109, 126, 109, 112, 102,
+  106, 117, 106, 156, 137, 103, 111, 128, 107, 158,
+  119, 109, 97, 123, 109, 117, 172, 151, 80, 118,
+  121, 126, 105, 144, 121, 84, 112, 153, 104, 110,
+  119, 122, 83, 113, 87, 144, 126, 144, 145, 102,
+  95, 134, 92, 122, 108, 136, 85, 99, 113, 102,
+  93, 120, 123, 159, 135, 115, 114, 94, 129, 114,
+  118, 139, 76, 100, 132, 176, 111, 120, 90, 124,
+  67, 95, 125, 191, 110, 98, 138, 97, 107, 124,
+  90, 88, 92, 108, 107, 137, 179, 106, 81, 132,
+  89, 106, 155, 112, 133, 138, 123, 120, 142, 132,
+  145, 144, 109, 114, 124, 111, 78, 122, 140, 100,
+  112, 122, 173, 141, 129, 115, 92, 95, 143, 117,
+  84, 104, 101, 69, 112, 97, 128, 109, 119, 98,
+  94, 92, 106, 103, 119, 104, 111, 100, 116, 142,
+  114, 108, 140, 130, 120, 118, 153, 120, 138, 137,
+  145, 128, 128, 97, 133, 122, 114, 94, 131, 105,
+  108, 116, 132, 129, 142, 130, 104, 98, 68, 118,
+  114, 110, 114, 123, 92, 116, 133, 107, 119, 96,
+  105, 123, 120, 115, 137, 156, 163, 104, 126, 135,
+  92, 104, 159, 112, 134, 118, 133, 116, 92, 141,
+  97, 85, 104, 109, 92, 102, 156, 127, 127, 97,
+  111, 123, 86, 99, 113, 120, 107, 83, 123, 170,
+  103, 76, 120, 93, 72, 146, 86, 78, 95, 136,
+  102, 118, 143, 132, 106, 120, 121, 140, 117, 138,
+  72, 110, 128, 113, 103, 111, 89, 110, 149, 97,
+  118, 114, 117, 140, 92, 78, 130, 78, 107, 125,
+  86, 120, 143, 81, 105, 142, 132, 119, 160, 113,
+  107, 104, 147, 109, 75, 112, 121, 83, 188, 102,
+  160, 126, 89, 102, 160, 109, 139, 151, 114, 139,
+  143, 159, 121, 144, 99, 114, 113, 91, 93, 104,
+  169, 82, 105, 139, 125, 152, 130, 124, 93, 116,
+  110, 105, 77, 95, 85, 85, 128, 74, 126, 87,
+  116, 124, 81, 66, 121, 137, 98, 135, 111, 90,
+  108, 134, 101, 133, 173, 129, 105, 148, 139, 151,
+  90, 148, 141, 118, 118, 108, 122, 102, 105, 85,
+  144, 97, 117, 87, 65, 151, 113, 116, 80, 108,
+  83, 133, 118, 144, 117, 152, 103, 114, 128, 100,
+  108, 66, 109, 133, 129, 122, 138, 155, 193, 108,
+  140, 137, 110, 127, 157, 143, 109, 166, 144, 125,
+  100, 161, 81, 96, 103, 160, 94, 104, 152, 160,
+  117, 84, 102, 113, 77, 125, 117, 111, 152, 54,
+  135, 138, 111, 113, 124, 112, 56, 175, 106, 71,
+  112, 156, 114, 105, 126, 153, 118, 118, 122, 169,
+  113, 171, 120, 113, 124, 106, 114, 106, 145, 114,
+  131, 92, 152, 134, 92, 154, 74, 52, 128, 116,
+  90, 147, 107, 96, 141, 97, 118, 139, 131, 107,
+  177, 88, 102, 114, 168, 115, 78, 118, 123, 103,
+  175, 97, 122, 148, 77, 97, 140, 119, 115, 133,
+  90, 135, 150, 154, 118, 149, 103, 114, 121, 81,
+  115, 70, 146, 114, 76, 138, 76, 128, 125, 109,
+  121, 96, 95, 84, 109, 106, 66, 119, 148, 88,
+  92, 113, 109, 140, 62, 115, 127, 157, 124, 169,
+  118, 95, 118, 104, 93, 172, 138, 111, 94, 133,
+  120, 157, 89, 120, 130, 93, 122, 102, 137, 105,
+  94, 116, 117, 87, 121, 96, 69, 148, 56, 127,
+  100, 93, 117, 96, 147, 151, 79, 163, 102, 97,
+  86, 129, 92, 83, 122, 135, 135, 130, 136, 109,
+  172, 116, 133, 134, 137, 128, 128, 190, 90, 169,
+  110, 142, 90, 142, 90, 99, 95, 184, 87, 106,
+  129, 176, 109, 88, 63, 108, 84, 129, 116, 91,
+  160, 60, 129, 98, 118, 197, 113, 135, 65, 178,
+  117, 68, 128, 162, 138, 95, 115, 157, 108, 113,
+  77, 108, 103, 151, 100, 98, 109, 105, 93, 114,
+  132, 122, 106, 103, 126, 120, 129, 122, 72, 80,
+  118, 138, 82, 137, 130, 90, 128, 95, 114, 117,
+  100, 108, 146, 103, 105, 104, 141, 98, 83, 130,
+  114, 108, 168, 82, 110, 147, 86, 114, 109, 151,
+  100, 104, 86, 119, 123, 103, 103, 107, 106, 104,
+  129, 101, 111, 116, 133, 128, 51, 107, 65, 109,
+  135, 90, 148, 128, 120, 59, 116, 112, 65, 100,
+  143, 106, 81, 122, 116, 80, 81, 94, 100, 152,
+  105, 150, 116, 118, 93, 120, 96, 147, 122, 95,
+  87, 159, 118, 130, 96, 127, 103, 77, 101, 109,
+  113, 82, 71, 105, 96, 88, 112, 160, 77, 120,
+  63, 132, 94, 87, 125, 80, 104, 99, 77, 142,
+  78, 95, 122, 104, 92, 92, 137, 119, 153, 120,
+  111, 86, 131, 128, 107, 116, 142, 106, 97, 146,
+  97, 145, 118, 105, 102, 135, 90, 92, 98, 171,
+  78, 111, 111, 154, 114, 107, 58, 102, 78, 101,
+  82, 116, 104, 91, 117, 98, 126, 154, 124, 123,
+  88, 177, 91, 63, 123, 146, 128, 86, 100, 120,
+  91, 102, 57, 114, 102, 121, 61, 70, 82, 79,
+  49, 131, 109, 114, 104, 95, 134, 105, 153, 108,
+  84, 86, 119, 163, 100, 148, 98, 104, 104, 101,
+  151, 106, 89, 127, 102, 107, 102, 80, 118, 92,
+  87, 125, 103, 91, 198, 97, 135, 117, 135, 157,
+  109, 167, 101, 93, 93, 129, 129, 100, 100, 109,
+  99, 100, 129, 114, 109, 96, 131, 82, 61, 121,
+  79, 130, 154, 101, 157, 144, 121, 88, 134, 109,
+  93, 72, 116, 93, 104, 126, 139, 48, 118, 94,
+  94, 155, 101, 131, 122, 143, 64, 130, 102, 116,
+  125, 112, 111, 145, 111, 137, 113, 113, 140, 113,
+  107, 140, 100, 89, 87, 88, 111, 93, 129, 113,
+  97, 119, 91, 113, 94, 91, 109, 101, 84, 74,
+  80, 147, 74, 97, 116, 93, 96, 105, 95, 134,
+  143, 119, 134, 114, 147, 132, 114, 126, 133, 103,
+  111, 82, 90, 129, 118, 97, 110, 129, 105, 81,
+  93, 168, 101, 114, 116, 141, 112, 105, 78, 106,
+  89, 90, 114, 99, 116, 110, 94, 78, 142, 122,
+  132, 125, 98, 173, 95, 103, 120, 139, 104, 98,
+  116, 101, 116, 97, 102, 116, 120, 154, 65, 110,
+  110, 71, 72, 107, 77, 74, 106, 92, 99, 120,
+  137, 100, 95, 114, 118, 122, 100, 120, 106, 107,
+  97, 105, 126, 97, 92, 160, 93, 103, 96, 69,
+  124, 87, 112, 132, 98, 77, 206, 93, 88, 112,
+  129, 159, 114, 158, 131, 104, 88, 122, 128, 95,
+  116, 118, 95, 112, 125, 125, 91, 71, 114, 99,
+  72, 102, 75, 138, 148, 97, 138, 118, 136, 98,
+  119, 93, 93, 72, 97, 110, 94, 122, 138, 50,
+  151, 92, 96, 171, 108, 119, 110, 126, 44, 113,
+  109, 113, 112, 130, 102, 128, 116, 122, 120, 118,
+  155, 122, 125, 117, 101, 82, 111, 88, 117, 81,
+  130, 101, 99, 114, 93, 102, 84, 104, 52, 109,
+  91, 96, 75, 161, 83, 78, 97, 115, 91, 99,
+  74, 122, 111, 105, 133, 123, 177, 113, 137, 131,
+  139, 93, 130, 93, 97, 102, 119, 110, 103, 123,
+  88, 81, 81, 151, 87, 101, 123, 137, 114, 92,
+  97, 109, 75, 98, 91, 85, 104, 97, 107, 88,
+  118, 120, 130, 109, 119, 161, 104, 102, 124, 141,
+  111, 106, 124, 97, 130, 99, 122, 106, 117, 156,
+  46, 100, 105, 71, 65, 85, 69, 102, 111, 73,
+  102, 116, 130, 84, 102, 104, 108, 86, 84, 102,
+  95, 121, 111, 103, 107, 86, 101, 149, 100, 103,
+  109, 68, 120, 83, 111, 131, 89, 88, 179, 97,
+  98, 124, 114, 140, 122, 132, 138, 105, 87, 120,
+  137, 112, 109, 127, 94, 125, 128, 133, 82, 64,
+  107, 107, 86, 113, 88, 132, 137, 104, 119, 97,
+  133, 108, 119, 72, 87, 74, 87, 99, 106, 115,
+  126, 47, 159, 94, 95, 175, 126, 101, 95, 113,
+  50, 96, 104, 123, 110, 104, 99, 130, 122, 122,
+  110, 122, 155, 119, 132, 123, 105, 81, 116, 89,
+  118, 82, 132, 110, 96, 114, 114, 92, 84, 103,
+  46, 98, 106, 110, 81, 167, 98, 79, 122, 111,
+  97, 87, 73, 98, 106, 96, 123, 127, 186, 101,
+  146, 149, 125, 104, 140, 96, 103, 104, 110, 122,
+  121, 119, 86, 79, 76, 139, 95, 90, 103, 140,
+  116, 80, 110, 123, 69, 91, 79, 77, 99, 82,
+  108, 79, 99, 106, 148, 103, 124, 139, 126, 100,
+  121, 152, 119, 105, 113, 116, 129, 107, 128, 144,
+  103, 148, 66, 110, 111, 78, 71, 83, 88, 113,
+  103, 72, 117, 105, 119, 91, 112, 86, 108, 93,
+  79, 88, 110, 125, 120, 97, 95, 92, 113, 121,
+  124, 96, 107, 74, 114, 92, 109, 140, 95, 87,
+  156, 87, 89, 124, 129, 128, 133, 124, 131, 107,
+  90, 117, 129, 128, 107, 116, 89, 126, 111, 123,
+  72, 55, 99, 117, 88, 128, 96, 129, 119, 105,
+  114, 101, 110, 132, 113, 63, 84, 80, 90, 91,
+  113, 106, 112, 53, 140, 97, 84, 155, 142, 99,
+  80, 100, 65, 88, 85, 122, 101, 79, 124, 143,
+  131, 131, 119, 116, 156, 138, 124, 127, 102, 83,
+  106, 81, 120, 95, 140, 118, 94, 124, 139, 102,
+  82, 106, 37, 95, 106, 111, 79, 160, 113, 89,
+  118, 96, 113, 79, 76, 102, 103, 102, 109, 153,
+  184, 81, 141, 161, 99, 125, 135, 94, 116, 110,
+  112, 132, 109, 114, 78, 76, 94, 141, 116, 76,
+  94, 120, 122, 75, 112, 127, 68, 86, 87, 79,
+  89, 75, 102, 86, 88, 109, 150, 99, 109, 108,
+  127, 105, 117, 156, 111, 108, 89, 121, 115, 103,
+  137, 143, 96, 147, 67, 129, 119, 78, 79, 86,
+  101, 85, 98, 74, 113, 109, 100, 88, 118, 75,
+  100, 95, 78, 76, 105, 108, 128, 85, 103, 97,
+  121, 113, 137, 90, 102, 81, 121, 95, 104, 157,
+  101, 95, 140, 80, 108, 120, 132, 125, 138, 125,
+  118, 118, 105, 110, 122, 133, 109, 108, 94, 122,
+  108, 103, 59, 57, 104, 104, 89, 141, 109, 122,
+  93, 107, 109, 109, 95, 141, 102, 64, 93, 84,
+  103, 84, 118, 104, 112, 68, 120, 89, 75, 136,
+  155, 103, 63, 92, 81, 95, 76, 124, 102, 84,
+  147, 154, 123, 136, 101, 111, 152, 141, 108, 121,
+  102, 88, 90, 67, 120, 105, 143, 102, 88, 124,
+  145, 120, 81, 111, 38, 105, 108, 96, 78, 138,
+  111, 103, 112, 93, 112, 70, 76, 114, 99, 108,
+  107, 165, 167, 96, 126, 154, 76, 135, 124, 83,
+  135, 120, 119, 136, 111, 112, 77, 69, 116, 149,
+  139, 62, 94, 94, 137, 60, 116, 112, 87, 80,
+  95, 77, 87, 79, 115, 87, 90, 110, 146, 98,
+  89, 90, 116, 99, 106, 160, 101, 102, 72, 110,
+  106, 103, 135, 136, 92, 149, 83, 154, 123, 71,
+  86, 84, 114, 63, 104, 87, 118, 106, 87, 101,
+  116, 82, 103, 94, 86, 80, 89, 99, 134, 86,
+  101, 102, 131, 114, 140, 87, 91, 92, 123, 91,
+  106, 153, 117, 104, 131, 79, 106, 111, 123, 118,
+  131, 126, 111, 120, 111, 109, 115, 122, 109, 108,
+  110, 109, 101, 93, 53, 59, 110, 95, 88, 135,
+  107, 121, 84, 103, 101, 111, 82, 134, 91, 70,
+  96, 93, 106, 80, 116, 102, 124, 91, 117, 87,
+  72, 125, 151, 103, 60, 92, 74, 97, 70, 125,
+  106, 98, 153, 149, 112, 143, 88, 109, 140, 135,
+  110, 114, 102, 89, 86, 53, 123, 108, 135, 90,
+  92, 130, 139, 136, 77, 110, 39, 109, 109, 89,
+  68, 115, 100, 127, 103, 91, 103, 76, 78, 118,
+  107, 102, 100, 156, 158, 103, 125, 142, 68, 113,
+  120, 90, 130, 133, 119, 121, 99, 109, 72, 69,
+  132, 149, 150, 57, 107, 80, 139, 66, 117, 112,
+  92, 91, 86, 91, 95, 79, 123, 93, 101, 122,
+  137, 100, 75, 85, 115, 95, 104, 177, 94, 102,
+  57, 101, 108, 110, 135, 122, 85, 139, 88, 157,
+  125, 68, 90, 86, 115, 64, 112, 96, 109, 102,
+  80, 97, 108, 91, 113, 92, 102, 81, 82, 90,
+  117, 99, 101, 102, 148, 122, 133, 96, 84, 109,
+  127, 88, 107, 133, 138, 105, 129, 91, 118, 116,
+  115, 111, 121, 110, 106, 116, 120, 113, 107, 110,
+  124, 107, 130, 98, 103, 86, 52, 48, 115, 94,
+  77, 126, 101, 118, 88, 93, 95, 115, 74, 132,
+  80, 84, 95, 104, 99, 82, 115, 99, 139, 112,
+  123, 97, 80, 123, 146, 109, 64, 92, 74, 92,
+  73, 119, 110, 105, 146, 125, 109, 135, 85, 102,
+  132, 125, 120, 105, 94, 110, 98, 58, 137, 111,
+  125, 88, 93, 128, 139, 142, 76, 104, 28, 107,
+  116, 106, 55, 103, 88, 138, 104, 98, 111, 76,
+  84, 108, 121, 100, 97, 137, 166, 101, 127, 136,
+  83, 108, 132, 111, 135, 135, 116, 106, 88, 110,
+  61, 83, 133, 158, 152, 77, 116, 76, 143, 79,
+  113, 119, 96, 93, 84, 88, 121, 80, 119, 104,
+  113, 131, 125, 103, 73, 90, 125, 96, 106, 187,
+  90, 99, 54, 95, 119, 113, 125, 117, 84, 138,
+  79, 150, 123, 63, 82, 93, 121, 87, 117, 111,
+  113, 106, 94, 99, 96, 110, 121, 106, 117, 86,
+  87, 93, 109, 112, 103, 106, 145, 123, 122, 100,
+  93, 132, 121, 89, 110, 119, 148, 123, 123, 101,
+  126, 107, 107, 113, 95, 107, 94, 120, 130, 109,
+  112, 106, 115, 104, 148, 97, 106, 76, 58, 60,
+  113, 92, 65, 121, 93, 119, 85, 87, 87, 119,
+  86, 120, 72, 94, 91, 104, 101, 83, 116, 80,
+  142, 108, 132, 88, 74, 117, 133, 112, 66, 94,
+  70, 103, 80, 109, 106, 102, 133, 131, 105, 129,
+  87, 101, 117, 119, 119, 108, 89, 129, 91, 56,
+  128, 114, 124, 98, 96, 129, 151, 154, 87, 92,
+  42, 105, 113, 100, 47, 103, 84, 153, 108, 115,
+  129, 76, 82, 104, 122, 99, 102, 109, 153, 106,
+  104, 141, 103, 100, 131, 121, 136, 124, 123, 98,
+  84, 114, 60, 88, 132, 173, 147, 93, 122, 74,
+  154, 107, 100, 121, 97, 79, 87, 84, 111, 84,
+  106, 105, 138, 135, 120, 107, 80, 85, 119, 88,
+  102, 181, 84, 90, 44, 95, 124, 108, 102, 107,
+  89, 127, 76, 143, 111, 54, 75, 104, 126, 77,
+  109, 97, 108, 105, 104, 95, 84, 119, 124, 114,
+  128, 79, 88, 89, 110, 118, 122, 112, 134, 125,
+  113, 91, 98, 149, 131, 71, 113, 108, 141, 126,
+  128, 113, 136, 104, 99, 106, 82, 139, 80, 116,
+  139, 103, 112, 103, 119, 96, 148, 101, 99, 85,
+  55, 84, 107, 97, 58, 110, 99, 124, 92, 71,
+  82, 125, 110, 114, 69, 86, 89, 92, 115, 92,
+  112, 73, 138, 106, 134, 82, 69, 124, 112, 105,
+  67, 107, 68, 104, 80, 101, 108, 95, 127, 143,
+  102, 119, 76, 98, 108, 118, 117, 114, 100, 138,
+  95, 52, 133, 119, 131, 98, 90, 127, 148, 145,
+  91, 85, 43, 111, 87, 94, 47, 106, 94, 158,
+  115, 112, 156, 79, 82, 110, 115, 92, 110, 104,
+  145, 108, 108, 141, 95, 88, 126, 92, 139, 121,
+  127, 85, 96, 114, 59, 94, 124, 165, 150, 97,
+  129, 74, 158, 117, 90, 111, 97, 88, 90, 90,
+  114, 78, 105, 100, 147, 126, 120, 105, 86, 81,
+  116, 87, 104, 166, 82, 75, 37, 100, 114, 104,
+  123, 101, 93, 124, 84, 147, 105, 55, 74, 94,
+  120, 77, 92, 103, 110, 106, 108, 101, 72, 120,
+  133, 103, 121, 85, 78, 94, 114, 118, 135, 96,
+  126, 131, 108, 82, 95, 151, 135, 67, 120, 109,
+  118, 114, 140, 119, 128, 116, 101, 108, 106, 143,
+  82, 106, 149, 105, 111, 108, 137, 104, 138, 98,
+  87, 97, 48, 85, 111, 118, 61, 107, 110, 134,
+  113, 68, 87, 118, 124, 114, 69, 73, 91, 81,
+  110, 93, 106, 81, 139, 115, 131, 111, 70, 135,
+  103, 109, 76, 101, 67, 86, 83, 92, 107, 84,
+  125, 139, 101, 114, 65, 90, 112, 125, 116, 114,
+  109, 118, 89, 44, 141, 126, 132, 89, 85, 122,
+  128, 131, 90, 93, 33, 112, 80, 104, 59, 113,
+  107, 157, 119, 97, 155, 90, 88, 113, 125, 92,
+  101, 125, 150, 119, 131, 138, 81, 89, 124, 78,
+  135, 113, 129, 73, 101, 105, 67, 93, 120, 143,
+  162, 96, 141, 83, 157, 94, 88, 108, 100, 79,
+  103, 76, 124, 72, 88, 85, 142, 136, 107, 92,
+  84, 85, 111, 80, 108, 163, 86, 73, 50, 103,
+  96, 103, 144, 97, 93, 137, 83, 158, 114, 66,
+  72, 84, 96, 87, 92, 119, 102, 118, 133, 109,
+  70, 105, 138, 95, 107, 71, 68, 92, 109, 109,
+  142, 85, 124, 142, 103, 78, 91, 134, 126, 86,
+  124, 107, 97, 112, 157, 108, 117, 110, 109, 128,
+  124, 127, 94, 104, 145, 112, 100, 123, 130, 128,
+  119, 80, 88, 105, 59, 82, 119, 101, 75, 122,
+  113, 147, 133, 82, 106, 103, 121, 124, 78, 67,
+  98, 84, 97, 100, 111, 96, 132, 108, 129, 111,
+  66, 136, 107, 107, 80, 99, 61, 75, 75, 92,
+  114, 94, 129, 136, 93, 111, 68, 89, 152, 149,
+  115, 116, 103, 81, 64, 46, 120, 128, 135, 81,
+  96, 123, 120, 127, 78, 112, 31, 128, 87, 110,
+  78, 128, 103, 149, 108, 96, 111, 88, 84, 121,
+  134, 100, 102, 146, 154, 126, 149, 128, 75, 91,
+  116, 79, 111, 119, 130, 73, 93, 107, 72, 80,
+  114, 140, 175, 88, 141, 105, 150, 83, 84, 107,
+  105, 72, 124, 66, 118, 75, 80, 71, 124, 134,
+  84, 93, 84, 98, 107, 69, 108, 171, 90, 82,
+  82, 98, 89, 91, 131, 98, 96, 150, 62, 168,
+  135, 60, 79, 90, 84, 63, 109, 113, 94, 130,
+  127, 89, 84, 84, 133, 92, 98, 72, 68, 86,
+  100, 97, 138, 92, 124, 161, 102, 75, 93, 110,
+  110, 92, 125, 108, 73, 105, 185, 93, 99, 106,
+  113, 153, 129, 99, 116, 111, 124, 115, 95, 129,
+  122, 153, 103, 65, 100, 113, 78, 74, 117, 68,
+  77, 124, 110, 147, 160, 95, 129, 87, 86, 123,
+  95, 65, 93, 101, 74, 99, 110, 116, 128, 80,
+  125, 87, 59, 139, 108, 97, 96, 105, 47, 82,
+  69, 103, 114, 124, 141, 130, 108, 115, 89, 95,
+  196, 161, 127, 115, 99, 62, 73, 56, 106, 127,
+  135, 61, 92, 120, 103, 119, 64, 114, 42, 144,
+  101, 134, 88, 150, 90, 121, 80, 91, 62, 88,
+  76, 133, 120, 113, 126, 157, 169, 126, 179, 116,
+  74, 90, 122, 99, 88, 116, 131, 93, 80, 124,
+  74, 69, 116, 138, 164, 71, 136, 130, 135, 86,
+  79, 106, 87, 93, 127, 79, 117, 85, 101, 94,
+  91, 108, 80, 100, 91, 126, 118, 82, 123, 178,
+  90, 99, 110, 91, 97, 93, 126, 101, 104, 139,
+  36, 154, 146, 55, 82, 98, 107, 60, 122, 101,
+  108, 126, 100, 82, 105, 83, 118, 105, 92, 86,
+  88, 95, 92, 87, 127, 99, 127, 169, 110, 79,
+  100, 79, 114, 86, 114, 122, 70, 103, 197, 89,
+  112, 124, 101, 153, 122, 72, 120, 111, 104, 122,
+  115, 110, 109, 156, 114, 81, 118, 120, 103, 67,
+  117, 80, 68, 107, 95, 133, 169, 89, 145, 77,
+  59, 104, 129, 82, 84, 106, 59, 91, 103, 121,
+  134, 69, 116, 88, 65, 163, 109, 105, 119, 106,
+  40, 82, 86, 123, 126, 148, 129, 114, 123, 118,
+  98, 108, 177, 131, 141, 120, 106, 74, 108, 82,
+  119, 115, 135, 66, 82, 118, 85, 123, 69, 97,
+  79, 146, 140, 149, 92, 158, 80, 76, 69, 95,
+  69, 97, 72, 123, 124, 107, 157, 144, 181, 126,
+  178, 100, 93, 96, 122, 158, 78, 106, 122, 125,
+  78, 145, 73, 73, 106, 138, 134, 75, 124, 144,
+  114, 95, 71, 140, 68, 124, 98, 114, 141, 97,
+  124, 107, 90, 105, 97, 105, 105, 172, 126, 98,
+  130, 166, 102, 98, 123, 98, 116, 104, 108, 113,
+  99, 120, 53, 110, 133, 59, 74, 105, 146, 99,
+  119, 94, 137, 113, 108, 100, 101, 104, 115, 128,
+  96, 110, 96, 111, 89, 98, 107, 99, 116, 152,
+  116, 87, 112, 50, 126, 88, 107, 145, 75, 118,
+  192, 100, 149, 144, 62, 134, 117, 140, 112, 107,
+  104, 122, 131, 73, 108, 149, 130, 126, 139, 118,
+  112, 105, 122, 119, 58, 87, 73, 121, 153, 87,
+  127, 93, 121, 78, 132, 98, 85, 91, 87, 95,
+  87, 116, 139, 72, 105, 95, 81, 188, 105, 127,
+  120, 116, 59, 98, 111, 141, 129, 168, 89, 139,
+  127, 110, 94, 127, 123, 84, 133, 119, 129, 86,
+  97, 100, 137, 100, 122, 107, 69, 122, 77, 131,
+  98, 84, 99, 139, 144, 118, 88, 146, 72, 65,
+  97, 108, 103, 95, 77, 124, 133, 108, 151, 103,
+  183, 127, 142, 96, 128, 78, 117, 169, 93, 114,
+  128, 126, 88, 162, 74, 80, 95, 150, 101, 95,
+  115, 150, 114, 101, 68, 163, 78, 136, 67, 142,
+  133, 87, 136, 112, 126, 136, 110, 119, 117, 217,
+  112, 83, 117, 136, 122, 83, 127, 122, 113, 111,
+  95, 117, 89, 124, 56, 69, 106, 67, 57, 116,
+  140, 157, 128, 88, 128, 101, 129, 104, 91, 108,
+  135, 117, 99, 135, 94, 117, 103, 115, 127, 85,
+  105, 127, 126, 104, 113, 56, 125, 106, 95, 135,
+  78, 116, 199, 107, 120, 160, 50, 126, 135, 184,
+  97, 105, 98, 130, 123, 89, 105, 134, 123, 144,
+  147, 109, 101, 118, 134, 124, 68, 91, 78, 125,
+  131, 81, 98, 124, 167, 91, 125, 99, 78, 77,
+  107, 119, 93, 108, 121, 90, 99, 107, 94, 194,
+  102, 132, 103, 134, 80, 96, 111, 136, 142, 129,
+  70, 109, 116, 111, 93, 119, 118, 79, 146, 114,
+  141, 99, 104, 99, 140, 97, 113, 119, 65, 132,
+  96, 116, 110, 83, 91, 122, 117, 106, 85, 157,
+  86, 93, 127, 111, 128, 86, 91, 132, 135, 121,
+  123, 101, 191, 106, 141, 121, 139, 66, 117, 122,
+  105, 123, 119, 112, 95, 147, 71, 93, 79, 138,
+  98, 98, 115, 168, 122, 94, 62, 149, 89, 119,
+  71, 142, 139, 56, 117, 99, 116, 141, 120, 125,
+  108, 233, 100, 92, 104, 126, 132, 101, 120, 142,
+  115, 118, 106, 154, 88, 146, 53, 64, 122, 68,
+  55, 102, 84, 175, 118, 91, 105, 108, 126, 118,
+  88, 90, 142, 102, 77, 166, 115, 116, 120, 114,
+  121, 77, 96, 126, 145, 110, 113, 90, 102, 106,
+  97, 123, 80, 85, 216, 108, 102, 133, 78, 133,
+  138, 141, 113, 109, 101, 124, 104, 124, 113, 118,
+  108, 110, 127, 104, 84, 105, 125, 120, 81, 85,
+  94, 144, 127, 91, 96, 113, 121, 111, 97, 54,
+  79, 75, 89, 99, 110, 101, 106, 72, 111, 102,
+  70, 157, 93, 110, 83, 130, 58, 71, 82, 106,
+  133, 66, 93, 105, 119, 114, 107, 111, 149, 123,
+  128, 112, 120, 89, 109, 59, 136, 97, 112, 118,
+  76, 133, 120, 102, 87, 102, 73, 119, 92, 105,
+  92, 166, 99, 119, 119, 76, 129, 74, 105, 125,
+  135, 128, 110, 147, 194, 92, 166, 122, 116, 95,
+  124, 96, 112, 121, 116, 94, 100, 140, 73, 92,
+  96, 125, 102, 85, 123, 151, 119, 89, 74, 127,
+  73, 101, 90, 97, 114, 55, 97, 96, 98, 121,
+  122, 107, 93, 204, 102, 95, 109, 136, 114, 118,
+  111, 137, 115, 115, 115, 155, 91, 150, 52, 95,
+  141, 64, 62, 90, 80, 103, 105, 72, 102, 139,
+  107, 106, 90, 65, 106, 110, 76, 112, 120, 81,
+  107, 100, 119, 88, 114, 155, 142, 88, 112, 88,
+  113, 104, 100, 120, 68, 86, 231, 95, 136, 102,
+  105, 152, 134, 98, 118, 122, 107, 126, 122, 152,
+  129, 137, 95, 90, 121, 105, 83, 53, 132, 78,
+  77, 111, 110, 143, 128, 106, 120, 101, 82, 139,
+  104, 54, 97, 92, 78, 78, 118, 101, 102, 77,
+  103, 102, 75, 130, 107, 114, 93, 102, 60, 80,
+  82, 117, 129, 74, 136, 106, 105, 127, 114, 108,
+  169, 160, 128, 117, 115, 88, 109, 56, 137, 105,
+  129, 82, 86, 120, 113, 110, 71, 115, 58, 119,
+  139, 114, 92, 176, 106, 103, 89, 92, 94, 83,
+  83, 119, 115, 123, 164, 185, 191, 116, 175, 118,
+  87, 111, 131, 111, 116, 121, 119, 120, 106, 143,
+  88, 88, 115, 129, 100, 85, 124, 126, 104, 85,
+  77, 126, 75, 102, 127, 51, 142, 69, 111, 94,
+  95, 122, 100, 96, 87, 172, 131, 96, 114, 147,
+  100, 99, 107, 120, 119, 114, 108, 105, 101, 160,
+  61, 123, 139, 68, 77, 75, 93, 44, 117, 87,
+  118, 136, 111, 103, 97, 86, 77, 105, 90, 72,
+  106, 83, 104, 93, 102, 108, 113, 165, 144, 81,
+  102, 73, 121, 117, 116, 142, 74, 110, 191, 80,
+  82, 117, 73, 128, 119, 84, 112, 110, 86, 130,
+  113, 140, 105, 132, 86, 106, 94, 103, 83, 68,
+  111, 116, 59, 104, 124, 127, 108, 85, 136, 109,
+  90, 128, 134, 81, 85, 100, 89, 76, 82, 117,
+  102, 111, 87, 73, 83, 123, 122, 118, 105, 80,
+  45, 87, 95, 148, 116, 171, 143, 99, 115, 137,
+  136, 143, 132, 156, 158, 99, 124, 83, 132, 89,
+  131, 93, 118, 93, 89, 136, 75, 124, 63, 101,
+  84, 108, 150, 146, 95, 166, 100, 80, 95, 106,
+  102, 87, 74, 102, 100, 112, 192, 150, 167, 97,
+  148, 94, 94, 99, 114, 144, 96, 116, 112, 163,
+  78, 148, 83, 111, 113, 130, 87, 89, 116, 103,
+  97, 116, 56, 156, 52, 138, 98, 145, 108, 77,
+  121, 108, 86, 96, 91, 115, 96, 127, 134, 66,
+  123, 141, 113, 73, 98, 129, 94, 109, 84, 93,
+  82, 108, 44, 76, 105, 74, 79, 83, 119, 68,
+  116, 73, 131, 91, 110, 91, 89, 95, 81, 104,
+  85, 105, 83, 96, 100, 97, 99, 114, 111, 130,
+  124, 102, 105, 64, 131, 113, 98, 139, 82, 151,
+  140, 87, 115, 165, 45, 118, 125, 119, 102, 81,
+  88, 158, 90, 162, 100, 132, 90, 130, 97, 82,
+  97, 137, 121, 93, 48, 127, 126, 116, 93, 85,
+  107, 122, 104, 102, 109, 109, 92, 120, 120, 90,
+  72, 139, 108, 135, 52, 71, 100, 153, 146, 138,
+  99, 114, 69, 103, 98, 163, 146, 205, 102, 112,
+  112, 139, 103, 158, 95, 102, 135, 98, 123, 105,
+  107, 120, 125, 77, 114, 105, 74, 169, 53, 119,
+  86, 86, 151, 125, 152, 146, 108, 154, 101, 93,
+  135, 111, 125, 98, 107, 94, 120, 121, 139, 84,
+  134, 132, 107, 97, 135, 108, 103, 142, 102, 124,
+  108, 140, 79, 140, 113, 145, 110, 135, 99, 101,
+  98, 124, 108, 104, 30, 179, 122, 142, 95, 161,
+  135, 92, 150, 81, 126, 98, 114, 146, 106, 124,
+  142, 61, 100, 162, 161, 58, 108, 152, 109, 124,
+  66, 125, 69, 89, 125, 55, 105, 90, 95, 105,
+  146, 126, 109, 96, 121, 101, 124, 127, 69, 89,
+  105, 133, 73, 143, 108, 115, 106, 122, 122, 90,
+  103, 107, 120, 124, 102, 78, 122, 117, 87, 118,
+  68, 152, 132, 84, 194, 173, 53, 126, 146, 148,
+  120, 73, 100, 161, 115, 200, 97, 148, 84, 137,
+  131, 72, 80, 94, 146, 130, 56, 158, 112, 102,
+  126, 78, 75, 145, 121, 101, 96, 115, 116, 127,
+  165, 118, 85, 128, 111, 137, 53, 108, 90, 189,
+  137, 154, 72, 112, 88, 95, 94, 146, 138, 126,
+  105, 121, 147, 120, 63, 106, 92, 89, 155, 110,
+  144, 154, 89, 136, 132, 72, 117, 106, 95, 104,
+  67, 113, 118, 77, 165, 125, 169, 114, 105, 148,
+  99, 83, 84, 126, 116, 92, 138, 122, 136, 97,
+  119, 65, 129, 144, 92, 122, 150, 94, 115, 155,
+  127, 103, 113, 158, 108, 133, 126, 140, 119, 121,
+  127, 105, 96, 137, 119, 51, 44, 179, 135, 92,
+  135, 82, 169, 82, 116, 54, 135, 189, 124, 125,
+  119, 137, 141, 47, 113, 186, 152, 89, 136, 150,
+  130, 107, 61, 87, 71, 111, 170, 68, 126, 110,
+  103, 97, 80, 126, 119, 109, 96, 95, 121, 241,
+  57, 89, 116, 119, 79, 98, 136, 123, 136, 119,
+  103, 69, 99, 118, 112, 122, 73, 100, 121, 118,
+  99, 101, 87, 79, 149, 80, 73, 126, 50, 110,
+  165, 164, 126, 138, 75, 119, 100, 162, 112, 110,
+  125, 130, 79, 87, 60, 105, 124, 161, 51, 117,
+  99, 114, 123, 75, 77, 115, 128, 107, 76, 117,
+  84, 115, 139, 114, 84, 108, 102, 151, 58, 90,
+  82, 148, 120, 137, 39, 81, 74, 92, 76, 105,
+  126, 76, 125, 102, 137, 97, 96, 99, 98, 138,
+  134, 94, 126, 151, 126, 91, 127, 78, 122, 148,
+  109, 99, 85, 122, 97, 102, 90, 87, 108, 91,
+  88, 151, 68, 112, 102, 131, 114, 61, 128, 141,
+  163, 104, 125, 76, 153, 77, 93, 125, 128, 94,
+  127, 114, 114, 107, 112, 128, 61, 123, 90, 115,
+  114, 105, 119, 103, 111, 88, 141, 83, 32, 140,
+  88, 79, 118, 124, 130, 56, 101, 114, 122, 152,
+  116, 107, 120, 104, 113, 28, 113, 168, 116, 115,
+  121, 145, 83, 92, 74, 81, 85, 123, 50, 77,
+  135, 83, 71, 114, 46, 76, 109, 82, 84, 62,
+  97, 132, 60, 79, 134, 102, 108, 93, 89, 114,
+  139, 107, 121, 108, 84, 130, 88, 106, 73, 111,
+  121, 82, 97, 77, 124, 68, 162, 78, 121, 105,
+  64, 116, 152, 113, 119, 151, 93, 105, 105, 124,
+  107, 96, 116, 157, 79, 99, 59, 75, 118, 99,
+  46, 132, 131, 100, 108, 83, 74, 103, 83, 117,
+  82, 111, 72, 121, 119, 113, 85, 97, 117, 142,
+  75, 83, 108, 131, 129, 146, 33, 105, 91, 114,
+  65, 96, 133, 122, 118, 109, 120, 108, 101, 114,
+  90, 118, 98, 143, 118, 124, 123, 76, 119, 104,
+  136, 118, 85, 102, 87, 90, 105, 106, 97, 96,
+  69, 99, 100, 142, 56, 127, 114, 128, 100, 63,
+  75, 109, 145, 112, 132, 108, 122, 105, 100, 145,
+  100, 119, 110, 74, 147, 125, 103, 117, 104, 106,
+  85, 141, 117, 85, 124, 108, 111, 95, 159, 90,
+  44, 102, 98, 93, 115, 98, 130, 53, 148, 166,
+  106, 102, 128, 118, 112, 98, 119, 43, 99, 165,
+  127, 112, 81, 148, 62, 116, 106, 114, 70, 138,
+  95, 94, 117, 74, 86, 118, 102, 64, 100, 93,
+  125, 80, 82, 145, 61, 77, 111, 133, 118, 107,
+  67, 120, 138, 106, 128, 176, 89, 112, 105, 85,
+  95, 137, 90, 85, 103, 78, 113, 117, 147, 86,
+  111, 141, 68, 106, 111, 105, 114, 119, 104, 115,
+  143, 101, 104, 106, 107, 185, 93, 112, 104, 42,
+  113, 91, 42, 140, 165, 84, 79, 82, 125, 100,
+  73, 104, 130, 126, 79, 123, 139, 127, 97, 96,
+  123, 107, 80, 108, 151, 142, 143, 161, 68, 104,
+  111, 146, 77, 139, 142, 134, 113, 117, 118, 143,
+  86, 120, 89, 100, 125, 139, 95, 100, 113, 99,
+  118, 113, 135, 116, 86, 107, 66, 84, 116, 104,
+  118, 111, 105, 96, 123, 119, 87, 103, 102, 109,
+  92, 85, 90, 94, 151, 120, 153, 124, 118, 113,
+  116, 149, 98, 127, 90, 85, 134, 126, 120, 159,
+  104, 98, 102, 163, 110, 117, 84, 119, 85, 101,
+  110, 111, 55, 81, 88, 123, 105, 86, 122, 81,
+  163, 158, 94, 109, 145, 147, 110, 102, 115, 90,
+  98, 145, 138, 108, 64, 127, 80, 119, 122, 120,
+  54, 123, 95, 110, 79, 91, 113, 124, 126, 101,
+  109, 102, 139, 68, 80, 122, 62, 99, 90, 163,
+  119, 112, 50, 123, 133, 122, 110, 173, 94, 96,
+  117, 88, 85, 116, 89, 106, 97, 90, 120, 118,
+  127, 93, 100, 154, 93, 115, 104, 117, 121, 98,
+  107, 119, 164, 112, 105, 90, 118, 166, 107, 116,
+  127, 90, 123, 112, 74, 149, 182, 91, 94, 98,
+  160, 108, 73, 105, 155, 149, 87, 124, 146, 107,
+  129, 115, 134, 101, 83, 105, 142, 121, 130, 168,
+  114, 95, 116, 147, 105, 169, 137, 119, 131, 122,
+  114, 155, 99, 117, 118, 126, 152, 112, 107, 92,
+  89, 135, 98, 115, 132, 135, 171, 115, 96, 113,
+  140, 88, 131, 107, 143, 117, 138, 123, 108, 114,
+  112, 109, 111, 126, 117, 97, 188, 126, 121, 132,
+  139, 107, 140, 141, 124, 113, 103, 134, 112, 162,
+  131, 162, 106, 102, 115, 139, 118, 141, 74, 129,
+  71, 117, 102, 126, 81, 111, 88, 124, 115, 124,
+  126, 115, 134, 116, 111, 119, 169, 146, 117, 105,
+  110, 106, 100, 129, 140, 106, 76, 113, 93, 145,
+  120, 123, 91, 115, 96, 141, 76, 108, 119, 119,
+  135, 100, 123, 124, 127, 70, 96, 114, 87, 137,
+  93, 149, 120, 131, 80, 101, 118, 117, 113, 148,
+  99, 100, 135, 106, 90, 103, 100, 112, 97, 107,
+  147, 119, 153, 107, 84, 134, 90, 93, 145, 106,
+  102, 158, 113, 129, 145, 137, 140, 128, 89, 128,
+  117, 118, 70, 129, 130, 82, 103, 127, 167, 146,
+  152, 100, 100, 81, 135, 96, 67, 110, 86, 91,
+  111, 92, 124, 133, 128, 99, 79, 110, 119, 102,
+  101, 126, 118, 93, 111, 138, 110, 114, 138, 121,
+  102, 135, 127, 119, 114, 128, 117, 104, 103, 101,
+  122, 118, 121, 86, 136, 98, 111, 108, 120, 155,
+  153, 157, 107, 98, 89, 105, 118, 111, 115, 119,
+  93, 113, 138, 107, 107, 97, 106, 115, 112, 123,
+  108, 126, 155, 108, 128, 139, 107, 104, 140, 154,
+  115, 123, 135, 110, 90, 135, 97, 116, 99, 138,
+  93, 110, 152, 148, 143, 107, 99, 110, 107, 133,
+  106, 120, 109, 78, 109, 138, 109, 95, 117, 115,
+  66, 145, 102, 82, 97, 148, 131, 114, 125, 141,
+  103, 116, 87, 155, 123, 141, 93, 105, 132, 114,
+  111, 103, 95, 121, 147, 111, 127, 106, 109, 146,
+  88, 74, 129, 81, 101, 124, 112, 125, 132, 65,
+  143, 138, 124, 104, 174, 127, 100, 114, 144, 103,
+  70, 124, 140, 104, 168, 105, 141, 122, 87, 76,
+  142, 109, 99, 107, 98, 142, 122, 142, 128, 130,
+  89, 125, 101, 100, 105, 121, 107, 92, 83, 131,
+  92, 144, 154, 107, 102, 120, 115, 84, 67, 108,
+  68, 108, 137, 91, 119, 100, 118, 108, 70, 76,
+  115, 131, 76, 139, 115, 129, 111, 126, 99, 127,
+  146, 104, 79, 157, 103, 132, 72, 111, 113, 93,
+  94, 102, 106, 100, 92, 87, 145, 88, 126, 98,
+  68, 190, 117, 140, 89, 104, 90, 123, 101, 143,
+  116, 134, 97, 108, 130, 95, 111, 60, 116, 153,
+  122, 136, 102, 117, 182, 89, 140, 142, 143, 127,
+  129, 142, 87, 210, 146, 96, 90, 148, 80, 119,
+  94, 187, 100, 117, 147, 160, 127, 120, 91, 106,
+  106, 131, 96, 125, 139, 60, 103, 96, 115, 123,
+  102, 137, 52, 165, 100, 97, 115, 147, 130, 93,
+  109, 150, 102, 108, 99, 173, 122, 162, 105, 92,
+  130, 98, 101, 109, 136, 110, 142, 96, 134, 163,
+  100, 122, 66, 52, 128, 126, 87, 141, 115, 115,
+  114, 73, 151, 120, 121, 93, 176, 106, 95, 120,
+  156, 98, 73, 135, 114, 115, 166, 94, 122, 125,
+  96, 90, 135, 112, 90, 101, 91, 128, 110, 148,
+  122, 130, 103, 112, 112, 79, 105, 75, 106, 110,
+  59, 133, 35, 118, 148, 98, 110, 106, 95, 79,
+  93, 106, 59, 129, 129, 99, 95, 111, 99, 137,
+  68, 105, 95, 157, 109, 145, 116, 134, 106, 92,
+  89, 135, 115, 92, 77, 112, 97, 116, 99, 91,
+  104, 91, 99, 106, 126, 115, 90, 89, 121, 86,
+  127, 92, 82, 151, 58, 131, 100, 95, 120, 88,
+  123, 147, 82, 148, 98, 102, 83, 124, 105, 70,
+  110, 155, 117, 123, 107, 88, 161, 126, 128, 134,
+  154, 113, 111, 176, 90, 145, 109, 115, 81, 115,
+  82, 104, 91, 162, 103, 95, 131, 160, 120, 88,
+  56, 98, 98, 110, 114, 79, 167, 73, 102, 86,
+  124, 171, 92, 127, 66, 156, 98, 103, 118, 146,
+  123, 88, 114, 139, 96, 99, 63, 110, 110, 149,
+  94, 90, 132, 93, 78, 109, 113, 99, 103, 102,
+  104, 142, 131, 119, 70, 79, 118, 132, 72, 116,
+  131, 101, 106, 77, 115, 95, 98, 111, 130, 100,
+  100, 104, 121, 91, 78, 139, 97, 113, 166, 78,
+  109, 109, 91, 94, 113, 149, 83, 94, 79, 106,
+  81, 89, 94, 95, 108, 108, 126, 87, 91, 118,
+  114, 124, 41, 87, 35, 103, 141, 86, 118, 113,
+  123, 62, 89, 107, 61, 107, 125, 111, 75, 101,
+  98, 76, 91, 72, 67, 156, 101, 120, 101, 125,
+  85, 103, 89, 107, 107, 85, 76, 126, 99, 78,
+  110, 109, 74, 75, 80, 111, 107, 87, 62, 79,
+  87, 88, 110, 147, 87, 118, 80, 130, 91, 83,
+  127, 78, 83, 82, 84, 132, 67, 96, 116, 105,
+  90, 76, 117, 117, 120, 117, 78, 64, 119, 127,
+  103, 105, 142, 76, 81, 145, 88, 122, 121, 83,
+  88, 110, 67, 97, 96, 137, 95, 96, 114, 140,
+  123, 95, 55, 101, 85, 102, 78, 109, 94, 90,
+  93, 97, 129, 146, 91, 115, 96, 157, 79, 86,
+  112, 131, 111, 77, 96, 107, 86, 94, 39, 97,
+  92, 110, 71, 62, 98, 73, 43, 118, 86, 104,
+  94, 84, 114, 111, 130, 101, 85, 79, 111, 140,
+  88, 123, 98, 89, 83, 87, 156, 87, 87, 129,
+  94, 97, 91, 86, 78, 83, 88, 121, 91, 98,
+  189, 93, 115, 86, 134, 121, 118, 169, 85, 82,
+  82, 116, 84, 87, 95, 90, 98, 100, 124, 110,
+  92, 98, 105, 89, 51, 84, 58, 117, 158, 96,
+  125, 115, 122, 88, 113, 101, 82, 76, 96, 102,
+  97, 105, 123, 42, 119, 73, 68, 154, 100, 109,
+  104, 151, 66, 107, 94, 99, 115, 98, 91, 101,
+  100, 92, 119, 99, 111, 112, 86, 119, 98, 97,
+  98, 80, 94, 90, 124, 107, 106, 120, 102, 109,
+  83, 84, 96, 95, 53, 78, 78, 142, 64, 98,
+  123, 84, 92, 88, 81, 136, 121, 125, 105, 93,
+  146, 118, 125, 112, 133, 85, 103, 68, 81, 113,
+  116, 75, 87, 111, 76, 88, 84, 135, 110, 106,
+  109, 144, 117, 89, 74, 101, 94, 97, 104, 91,
+  110, 101, 83, 89, 133, 103, 107, 113, 105, 149,
+  92, 119, 114, 126, 95, 94, 105, 92, 111, 95,
+  94, 107, 109, 140, 57, 98, 117, 70, 55, 94,
+  62, 73, 90, 84, 92, 121, 112, 92, 98, 109,
+  110, 111, 88, 105, 110, 89, 80, 89, 125, 86,
+  85, 154, 91, 92, 91, 86, 86, 78, 110, 126,
+  79, 86, 184, 86, 84, 89, 138, 137, 115, 151,
+  118, 101, 83, 118, 96, 86, 111, 93, 92, 107,
+  120, 117, 87, 77, 98, 94, 59, 92, 60, 124,
+  154, 100, 119, 105, 121, 94, 96, 77, 89, 76,
+  84, 106, 94, 99, 131, 39, 157, 76, 73, 168,
+  120, 114, 97, 134, 54, 94, 93, 98, 107, 108,
+  79, 100, 104, 90, 119, 104, 143, 119, 99, 108,
+  95, 87, 108, 87, 109, 86, 131, 87, 100, 110,
+  101, 97, 78, 95, 45, 94, 57, 104, 69, 158,
+  78, 87, 102, 99, 91, 86, 72, 120, 89, 123,
+  105, 117, 178, 101, 141, 127, 145, 89, 131, 82,
+  92, 100, 120, 90, 91, 109, 75, 77, 70, 124,
+  99, 97, 115, 152, 112, 78, 107, 104, 85, 97,
+  91, 74, 106, 89, 99, 91, 107, 97, 113, 98,
+  122, 131, 104, 115, 123, 128, 108, 102, 111, 81,
+  127, 87, 121, 108, 118, 161, 50, 97, 113, 68,
+  53, 73, 60, 96, 96, 73, 92, 120, 111, 85,
+  107, 98, 105, 88, 73, 84, 107, 110, 87, 83,
+  110, 80, 87, 132, 101, 95, 107, 86, 102, 83,
+  119, 138, 82, 109, 152, 91, 87, 101, 130, 131,
+  112, 123, 124, 102, 89, 117, 112, 111, 107, 109,
+  94, 111, 117, 119, 86, 64, 91, 101, 73, 120,
+  74, 119, 147, 107, 109, 85, 109, 101, 99, 52,
+  90, 87, 65, 95, 111, 99, 122, 39, 159, 83,
+  74, 166, 128, 108, 91, 121, 57, 83, 80, 99,
+  101, 82, 89, 107, 107, 95, 109, 107, 148, 119,
+  112, 114, 91, 82, 104, 82, 121, 90, 139, 86,
+  104, 106, 117, 92, 74, 100, 34, 83, 84, 122,
+  72, 155, 95, 81, 108, 100, 96, 88, 68, 84,
+  70, 106, 106, 132, 178, 94, 140, 146, 130, 102,
+  135, 94, 102, 99, 115, 93, 105, 105, 86, 71,
+  66, 114, 112, 83, 104, 145, 111, 74, 125, 107,
+  84, 93, 73, 65, 105, 75, 90, 75, 87, 95,
+  126, 92, 118, 109, 128, 109, 121, 141, 120, 106,
+  102, 90, 126, 91, 124, 129, 111, 161, 48, 103,
+  121, 74, 71, 72, 85, 108, 97, 83, 98, 104,
+  101, 82, 111, 89, 101, 91, 71, 59, 111, 119,
+  91, 78, 91, 80, 98, 94, 111, 92, 100, 89,
+  105, 95, 117, 156, 95, 103, 121, 83, 85, 103,
+  124, 113, 124, 114, 119, 106, 94, 98, 115, 128,
+  122, 102, 97, 111, 99, 99, 75, 60, 87, 114,
+  70, 126, 77, 114, 131, 103, 97, 94, 90, 113,
+  84, 56, 77, 106, 69, 90, 115, 102, 116, 51,
+  129, 97, 75, 124, 133, 105, 89, 109, 75, 84,
+  66, 89, 95, 72, 127, 114, 110, 109, 141, 113,
+  133, 128, 109, 126, 89, 95, 92, 62, 139, 98,
+  143, 99, 96, 105, 167, 112, 74, 103, 43, 73,
+  97, 111, 69, 137, 98, 92, 102, 116, 98, 98,
+  71, 81, 66, 101, 90, 147, 156, 83, 123, 154,
+  112, 120, 134, 116, 129, 120, 113, 95, 105, 97,
+  82, 75, 88, 112, 129, 74, 111, 116, 126, 82,
+  117, 114, 93, 97, 75, 77, 103, 74, 86, 89,
+  73, 100, 125, 95, 98, 77, 139, 121, 111, 149,
+  115, 112, 88, 90, 105, 94, 121, 125, 107, 148,
+  62, 112, 121, 80, 88, 87, 110, 96, 94, 85,
+  94, 109, 91, 96, 109, 88, 108, 97, 78, 60,
+  97, 115, 102, 74, 90, 105, 110, 72, 122, 93,
+  88, 111, 102, 107, 103, 161, 109, 119, 103, 88,
+  94, 100, 109, 97, 129, 105, 106, 117, 107, 83,
+  106, 118, 126, 104, 110, 118, 96, 85, 66, 55,
+  88, 106, 66, 108, 98, 103, 89, 104, 86, 115,
+  88, 111, 67, 80, 86, 108, 93, 101, 115, 102,
+  125, 72, 113, 99, 87, 85, 138, 103, 66, 99,
+  83, 106, 76, 85, 90, 95, 135, 117, 104, 119,
+  124, 113, 95, 99, 83, 122, 95, 122, 88, 54,
+  143, 98, 134, 104, 75, 104, 166, 127, 81, 105,
+  58, 89, 93, 72, 75, 103, 87, 100, 104, 130,
+  100, 99, 67, 88, 76, 103, 94, 136, 118, 106,
+  92, 144, 93, 140, 126, 104, 151, 140, 113, 90,
+  110, 100, 85, 76, 108, 114, 119, 79, 111, 76,
+  138, 100, 113, 104, 123, 97, 78, 81, 93, 86,
+  121, 107, 85, 113, 108, 93, 92, 56, 116, 120,
+  107, 143, 107, 100, 69, 82, 92, 105, 115, 123,
+  92, 124, 88, 113, 101, 90, 96, 108, 107, 91,
+  110, 92, 115, 117, 92, 115, 93, 102, 109, 97,
+  91, 66, 82, 121, 123, 91, 92, 140, 119, 67,
+  130, 94, 81, 138, 93, 99, 93, 134, 130, 116,
+  97, 97, 97, 93, 101, 92, 104, 102, 97, 102,
+  119, 79, 114, 94, 124, 115, 127, 125, 95, 84,
+  70, 53, 90, 99, 62, 90, 94, 91, 66, 92,
+  87, 117, 92, 99, 68, 100, 95, 103, 107, 104,
+  103, 83, 135, 104, 115, 99, 107, 76, 140, 101,
+  51, 105, 75, 127, 82, 102, 88, 110, 121, 96,
+  102, 117, 110, 112, 73, 88, 92, 108, 99, 142,
+  104, 51, 131, 98, 119, 97, 76, 106, 117, 115,
+  79, 109, 45, 97, 95, 72, 63, 81, 76, 119,
+  102, 119, 101, 101, 63, 110, 99, 99, 95, 109,
+  109, 93, 90, 142, 85, 119, 120, 91, 150, 134,
+  110, 97, 91, 106, 86, 91, 113, 121, 102, 90,
+  117, 55, 126, 138, 106, 95, 124, 100, 72, 89,
+  86, 98, 140, 137, 98, 103, 91, 88, 99, 58,
+  99, 123, 103, 143, 100, 98, 49, 78, 96, 118,
+  116, 112, 77, 96, 89, 105, 84, 94, 92, 118,
+  86, 98, 110, 81, 115, 116, 96, 114, 82, 116,
+  105, 98, 104, 75, 80, 122, 132, 106, 85, 145,
+  123, 86, 134, 104, 86, 142, 94, 83, 89, 102,
+  127, 94, 97, 109, 109, 101, 100, 97, 68, 95,
+  91, 92, 127, 79, 126, 86, 117, 113, 128, 128,
+  108, 88, 86, 43, 81, 97, 55, 86, 86, 76,
+  67, 75, 92, 118, 85, 95, 77, 118, 96, 102,
+  91, 92, 90, 59, 139, 119, 136, 100, 127, 92,
+  132, 103, 51, 115, 67, 133, 93, 125, 94, 105,
+  107, 78, 107, 106, 100, 108, 64, 80, 103, 93,
+  92, 159, 114, 66, 125, 107, 104, 90, 81, 101,
+  93, 89, 82, 122, 44, 85, 94, 81, 50, 80,
+  72, 113, 111, 115, 97, 90, 63, 102, 109, 92,
+  94, 84, 120, 77, 108, 130, 96, 102, 115, 92,
+  147, 121, 109, 111, 88, 112, 84, 112, 98, 129,
+  88, 111, 111, 60, 121, 152, 95, 84, 116, 93,
+  77, 79, 102, 99, 135, 154, 107, 100, 87, 88,
+  111, 68, 100, 123, 99, 137, 98, 102, 35, 78,
+  109, 126, 104, 114, 65, 93, 86, 100, 72, 83,
+  81, 108, 87, 119, 95, 81, 116, 110, 109, 109,
+  75, 130, 96, 106, 97, 79, 96, 119, 132, 115,
+  73, 137, 109, 99, 132, 95, 104, 144, 87, 75,
+  95, 78, 118, 96, 98, 115, 105, 89, 90, 120,
+  37, 95, 81, 93, 135, 77, 145, 99, 113, 105,
+  120, 123, 102, 90, 99, 35, 74, 114, 42, 86,
+  83, 79, 69, 69, 109, 123, 91, 87, 93, 121,
+  95, 100, 85, 84, 84, 42, 127, 106, 146, 103,
+  144, 97, 116, 110, 76, 110, 45, 130, 103, 149,
+  90, 100, 97, 84, 121, 108, 104, 115, 60, 93,
+  105, 98, 90, 174, 111, 77, 116, 110, 102, 100,
+  86, 108, 101, 87, 89, 131, 48, 83, 110, 68,
+  35, 87, 77, 107, 112, 123, 96, 88, 65, 97,
+  100, 98, 95, 63, 110, 86, 126, 115, 104, 96,
+  111, 90, 114, 111, 112, 137, 82, 111, 90, 122,
+  82, 143, 76, 122, 108, 72, 121, 172, 79, 91,
+  90, 98, 97, 78, 96, 97, 117, 158, 114, 106,
+  79, 94, 120, 68, 98, 116, 105, 127, 99, 99,
+  35, 90, 122, 120, 95, 100, 62, 88, 63, 100,
+  64, 86, 74, 108, 90, 119, 99, 72, 117, 103,
+  121, 92, 72, 128, 85, 105, 85, 68, 105, 111,
+  126, 112, 76, 124, 98, 117, 122, 90, 117, 133,
+  95, 69, 98, 66, 104, 104, 107, 119, 119, 73,
+  83, 123, 20, 107, 67, 84, 132, 76, 158, 119,
+  111, 104, 120, 112, 84, 95, 98, 56, 66, 100,
+  34, 81, 92, 98, 74, 61, 118, 133, 112, 87,
+  102, 119, 98, 93, 101, 73, 82, 39, 115, 101,
+  141, 119, 145, 99, 103, 115, 90, 112, 45, 98,
+  102, 158, 91, 88, 102, 95, 109, 100, 91, 111,
+  52, 113, 109, 108, 103, 178, 113, 73, 110, 110,
+  104, 101, 96, 115, 114, 94, 91, 129, 51, 84,
+  125, 83, 36, 94, 83, 105, 123, 109, 130, 85,
+  81, 102, 97, 98, 100, 55, 99, 83, 137, 105,
+  101, 88, 98, 91, 85, 109, 112, 138, 86, 109,
+  88, 125, 80, 151, 88, 119, 104, 78, 121, 191,
+  61, 103, 73, 101, 113, 102, 95, 86, 95, 125,
+  116, 88, 75, 94, 119, 63, 91, 115, 119, 121,
+  100, 90, 25, 113, 121, 112, 96, 94, 63, 79,
+  69, 107, 66, 91, 82, 92, 91, 110, 99, 84,
+  117, 103, 131, 87, 71, 126, 84, 98, 83, 64,
+  106, 103, 122, 108, 88, 97, 92, 130, 114, 84,
+  112, 123, 101, 56, 100, 75, 88, 100, 116, 113,
+  119, 74, 70, 112, 28, 124, 52, 70, 124, 78,
+  152, 118, 95, 100, 116, 110, 59, 86, 78, 91,
+  70, 104, 27, 83, 107, 111, 84, 49, 97, 132,
+  122, 87, 87, 106, 89, 87, 110, 76, 72, 42,
+  116, 116, 129, 130, 122, 107, 92, 118, 84, 112,
+  56, 60, 98, 122, 89, 74, 101, 95, 90, 83,
+  65, 102, 43, 110, 108, 109, 114, 173, 96, 50,
+  104, 114, 100, 89, 94, 107, 107, 95, 91, 109,
+  73, 85, 105, 92, 57, 94, 83, 113, 119, 94,
+  173, 81, 107, 108, 98, 95, 101, 62, 96, 86,
+  124, 106, 89, 77, 88, 100, 99, 115, 117, 116,
+  93, 92, 80, 127, 93, 129, 105, 109, 108, 80,
+  127, 186, 54, 110, 72, 89, 110, 122, 100, 64,
+  71, 84, 127, 99, 76, 83, 106, 64, 73, 116,
+  122, 129, 100, 91, 15, 124, 101, 104, 102, 86,
+  63, 78, 91, 115, 69, 89, 94, 78, 85, 105,
+  82, 94, 100, 108, 131, 116, 58, 108, 109, 89,
+  87, 49, 89, 89, 108, 101, 100, 84, 90, 128,
+  106, 75, 95, 129, 93, 52, 97, 79, 61, 93,
+  133, 108, 98, 77, 69, 107, 67, 141, 48, 85,
+  120, 79, 127, 109, 105, 102, 131, 115, 50, 83,
+  59, 119, 66, 126, 33, 83, 113, 109, 100, 48,
+  79, 112, 121, 91, 68, 97, 82, 84, 98, 86,
+  75, 49, 118, 121, 117, 107, 94, 111, 88, 114,
+  52, 116, 74, 39, 79, 79, 97, 71, 94, 84,
+  86, 70, 54, 88, 61, 102, 87, 87, 107, 154,
+  73, 38, 90, 125, 101, 81, 97, 90, 96, 110,
+  81, 90, 74, 107, 72, 89, 82, 90, 66, 124,
+  109, 88, 189, 67, 108, 112, 109, 89, 90, 70,
+  111, 102, 108, 104, 76, 70, 79, 88, 122, 122,
+  120, 82, 85, 79, 76, 111, 102, 104, 127, 103,
+  125, 79, 135, 142, 49, 112, 93, 80, 110, 109,
+  113, 51, 71, 78, 120, 109, 80, 72, 93, 69,
+  57, 96, 109, 141, 109, 82, 27, 115, 71, 101,
+  101, 95, 66, 90, 75, 123, 88, 85, 89, 84,
+  78, 93, 83, 102, 87, 111, 123, 121, 45, 90,
+  131, 83, 99, 49, 74, 84, 104, 95, 105, 74,
+  93, 132, 99, 69, 81, 127, 76, 59, 95, 72,
+  36, 82, 161, 98, 96, 78, 83, 121, 119, 137,
+  69, 108, 113, 96, 85, 113, 129, 115, 136, 100,
+  58, 87, 44, 131, 77, 113, 43, 93, 107, 116,
+  145, 70, 88, 97, 105, 100, 62, 86, 78, 84,
+  72, 83, 92, 79, 127, 91, 106, 72, 66, 118,
+  97, 114, 40, 119, 71, 36, 62, 60, 105, 85,
+  104, 95, 93, 74, 66, 82, 115, 108, 69, 88,
+  94, 112, 69, 48, 90, 134, 117, 60, 94, 89,
+  104, 127, 74, 82, 61, 143, 54, 113, 90, 116,
+  51, 145, 108, 81, 160, 66, 89, 126, 113, 94,
+  80, 84, 145, 113, 133, 99, 74, 47, 88, 87,
+  122, 110, 121, 65, 76, 87, 73, 88, 111, 104,
+  163, 94, 137, 109, 149, 99, 60, 109, 103, 82,
+  104, 86, 122, 54, 82, 91, 103, 93, 70, 71,
+  90, 98, 62, 94, 106, 166, 112, 86, 57, 98,
+  64, 100, 96, 102, 81, 113, 61, 142, 124, 70,
+  67, 96, 83, 69, 97, 121, 92, 120, 113, 106,
+  61, 88, 125, 90, 109, 59, 83, 81, 97, 84,
+  123, 76, 106, 139, 96, 75, 83, 114, 72, 74,
+  99, 81, 54, 85, 190, 83, 111, 83, 102, 141,
+  138, 92, 91, 113, 92, 122, 71, 117, 101, 117,
+  125, 76, 78, 94, 50, 106, 112, 63, 56, 98,
+  93, 129, 191, 90, 121, 89, 68, 100, 81, 92,
+  74, 83, 46, 89, 95, 111, 127, 67, 96, 67,
+  54, 148, 97, 122, 67, 108, 56, 56, 66, 74,
+  114, 118, 119, 106, 93, 82, 78, 85, 146, 119,
+  95, 102, 99, 74, 91, 57, 103, 126, 132, 62,
+  98, 113, 94, 135, 73, 75, 67, 143, 73, 141,
+  82, 153, 46, 142, 88, 80, 90, 72, 55, 131,
+  120, 106, 95, 101, 166, 114, 161, 93, 88, 43,
+  99, 130, 94, 102, 115, 82, 71, 124, 72, 83,
+  108, 123, 186, 74, 128, 148, 144, 82, 62, 108,
+  101, 102, 92, 75, 130, 68, 93, 81, 96, 90,
+  66, 83, 88, 155, 90, 114, 117, 180, 101, 90,
+  93, 97, 93, 98, 90, 109, 92, 116, 61, 135,
+  155, 53, 60, 99, 119, 63, 90, 123, 101, 126,
+  92, 94, 82, 102, 112, 116, 110, 79, 107, 78,
+  76, 72, 146, 95, 107, 142, 103, 78, 83, 96,
+  105, 78, 109, 119, 73, 105, 204, 74, 137, 103,
+  88, 145, 123, 94, 102, 101, 78, 135, 94, 91,
+  84, 121, 110, 87, 113, 102, 77, 82, 115, 78,
+  56, 96, 60, 132, 192, 92, 125, 87, 90, 86,
+  87, 96, 77, 90, 64, 93, 86, 119, 129, 56,
+  98, 82, 51, 187, 96, 126, 88, 129, 48, 75,
+  83, 103, 107, 152, 99, 144, 106, 76, 106, 98,
+  126, 94, 101, 118, 103, 70, 95, 78, 134, 105,
+  131, 85, 96, 118, 91, 129, 86, 68, 76, 125,
+  85, 124, 78, 161, 46, 89, 61, 82, 76, 74,
+  47, 119, 124, 96, 103, 91, 175, 118, 143, 94,
+  128, 60, 96, 153, 92, 105, 119, 94, 76, 155,
+  72, 79, 104, 128, 158, 83, 106, 157, 121, 81,
+  66, 129, 79, 125, 75, 96, 141, 78, 103, 96,
+  118, 126, 73, 99, 100, 207, 112, 114, 109, 158,
+  107, 83, 115, 114, 111, 91, 93, 101, 85, 118,
+  61, 85, 133, 48, 61, 98, 144, 106, 89, 102,
+  107, 123, 92, 103, 92, 97, 113, 125, 98, 104,
+  111, 84, 82, 72, 149, 111, 98, 140, 103, 93,
+  91, 93, 122, 92, 109, 145, 65, 109, 207, 73,
+  127, 129, 75, 143, 129, 151, 90, 110, 83, 130,
+  118, 95, 90, 122, 113, 123, 123, 97, 91, 104,
+  115, 87, 54, 98, 53, 143, 154, 84, 102, 108,
+  134, 81, 85, 115, 71, 98, 92, 91, 88, 111,
+  121, 78, 95, 103, 66, 188, 100, 121, 87, 135,
+  58, 65, 104, 118, 116, 119, 74, 118, 84, 74,
+  119, 101, 104, 69, 106, 117, 112, 96, 95, 90,
+  137, 105, 113, 103, 81, 124, 135, 125, 97, 74,
+  73, 104, 96, 100, 76, 156, 62, 74, 102, 92,
+  117, 72, 73, 98, 113, 102, 104, 94, 178, 111,
+  125, 118, 145, 77, 98, 132, 103, 118, 122, 101,
+  86, 159, 74, 82, 84, 129, 120, 89, 104, 153,
+  116, 79, 56, 146, 79, 113, 71, 120, 155, 71,
+  99, 88, 125, 144, 94, 110, 93, 227, 113, 112,
+  98, 132, 101, 83, 112, 130, 108, 98, 100, 130,
+  82, 129, 70, 70, 125, 67, 67, 101, 106, 129,
+  95, 89, 106, 114, 110, 116, 83, 79, 125, 106,
+  75, 146, 114, 91, 105, 75, 134, 99, 84, 132,
+  125, 102, 93, 98, 124, 89, 96, 146, 66, 92,
+  204, 72, 107, 117, 84, 127, 143, 140, 93, 119,
+  91, 114, 91, 111, 96, 97, 102, 135, 101, 89,
+  60, 119, 103, 117, 59, 98, 92, 167, 136, 87,
+  88, 113, 119, 87, 76, 92, 68, 89, 97, 85,
+  97, 96, 104, 71, 103, 95, 60, 149, 92, 96,
+  65, 104, 53, 55, 98, 103, 103, 71, 86, 120,
+  96, 72, 107, 97, 108, 80, 97, 121, 111, 111,
+  105, 63, 130, 101, 108, 118, 68, 124, 162, 135,
+  86, 83, 72, 104, 93, 96, 85, 156, 67, 97,
+  120, 68, 143, 54, 85, 92, 113, 115, 91, 117,
+  166, 79, 122, 129, 131, 89, 96, 113, 101, 128,
+  122, 95, 88, 155, 77, 78, 82, 129, 109, 65,
+  118, 129, 123, 77, 63, 140, 93, 103, 77, 111,
+  119, 69, 102, 96, 112, 138, 110, 98, 78, 202,
+  101, 102, 97, 127, 87, 96, 95, 132, 104, 98,
+  94, 140, 87, 134, 70, 81, 132, 78, 76, 92,
+  77, 87, 98, 63, 117, 122, 94, 121, 76, 52,
+  114, 92, 66, 118, 123, 82, 114, 71, 144, 89,
+  96, 133, 142, 90, 78, 109, 120, 81, 82, 137,
+  73, 86, 210, 71, 114, 92, 97, 119, 149, 116,
+  98, 113, 100, 117, 86, 132, 115, 111, 85, 110,
+  101, 88, 46, 96, 96, 100, 60, 119, 95, 173,
+  150, 98, 102, 106, 76, 108, 72, 83, 72, 88,
+  87, 99, 116, 100, 101, 73, 103, 87, 66, 132,
+  101, 92, 64, 109, 62, 78, 93, 103, 112, 70,
+  106, 130, 93, 82, 83, 93, 138, 104, 77, 121,
+  109, 106, 103, 53, 142, 108, 122, 86, 75, 122,
+  115, 136, 75, 101, 58, 118, 98, 94, 80, 161,
+  79, 107, 99, 80, 118, 56, 75, 123, 97, 126,
+  119, 142, 170, 96, 135, 126, 116, 105, 102, 96,
+  112, 133, 121, 82, 83, 157, 85, 82, 88, 134,
+  109, 62, 124, 119, 121, 68, 78, 112, 105, 106,
+  100, 55, 132, 77, 123, 97, 111, 128, 77, 84,
+  72, 179, 99, 101, 85, 137, 83, 99, 101, 107,
+  96, 101, 96, 102, 102, 154, 77, 109, 126, 66,
+  77, 77, 77, 47, 108, 83, 120, 155, 92, 110,
+  80, 58, 93, 100, 81, 82, 124, 86, 111, 61,
+  135, 104, 98, 138, 149, 81, 86, 118, 122, 85,
+  95, 148, 77, 85, 200, 64, 105, 90, 92, 117,
+  126, 72, 105, 98, 92, 121, 96, 139, 110, 120,
+  74, 104, 87, 96, 66, 49, 92, 87, 54, 111,
+  96, 136, 143, 97, 138, 102, 67, 130, 105, 84,
+  83, 107, 69, 92, 113, 105, 96, 85, 97, 77,
+  62, 139, 118, 101, 78, 93, 55, 87, 81, 120,
+  106, 105, 134, 106, 90, 90, 111, 100, 147, 155,
+  112, 108, 108, 90, 120, 62, 141, 104, 127, 70,
+  102, 117, 84, 126, 66, 95, 47, 107, 122, 126,
+  77, 165, 87, 82, 73, 82, 95, 62, 58, 126,
+  77, 101, 149, 142, 172, 92, 148, 117, 112, 122,
+  96, 119, 98, 106, 119, 118, 58, 153, 75, 85,
+  99, 135, 118, 59, 111, 106, 113, 90, 73, 125,
+  75, 113, 115, 69, 132, 78, 119, 82, 79, 104,
+  63, 100, 81, 148, 106, 94, 96, 133, 94, 80,
+  93, 106, 94, 88, 87, 86, 95, 131, 47, 102,
+  120, 49, 69, 67, 86, 57, 104, 95, 117, 134,
+  98, 90, 97, 88, 75, 102, 84, 76, 99, 96,
+  113, 54, 106, 105, 101, 134, 127, 80, 103, 100,
+  124, 84, 105, 161, 87, 113, 159, 67, 75, 115,
+  57, 113, 125, 88, 98, 81, 73, 134, 56, 148,
+  99, 92, 87, 109, 78, 84, 81, 115, 78, 122,
+  35, 96, 88, 119, 115, 81, 131, 89, 90, 115,
+  96, 97, 92, 121, 83, 93, 87, 118, 87, 97,
+  75, 42, 57, 141, 127, 100, 71, 99, 53, 77,
+  77, 108, 97, 169, 124, 104, 72, 77, 128, 122,
+  105, 146, 110, 100, 101, 70, 110, 78, 138, 76,
+  111, 90, 103, 129, 77, 119, 60, 81, 94, 119,
+  99, 137, 98, 143, 84, 76, 114, 95, 139, 61,
+  84, 97, 84, 105, 109, 95, 136, 101, 104, 94,
+  132, 105, 86, 128, 83, 92, 118, 106, 63, 145,
+  74, 110, 121, 118, 136, 71, 85, 80, 128, 124,
+  58, 138, 73, 127, 91, 170, 98, 89, 114, 67,
+  89, 62, 86, 137, 98, 127, 102, 77, 90, 136,
+  124, 61, 99, 132, 94, 100, 66, 110, 71, 72,
+  59, 76, 123, 52, 72, 98, 122, 90, 99, 84,
+  108, 96, 93, 82, 90, 80, 86, 109, 79, 113,
+  67, 98, 86, 60, 108, 94, 97, 121, 96, 105,
+  104, 86, 109, 73, 92, 143, 95, 151, 125, 98,
+  151, 137, 49, 121, 165, 110, 101, 97, 79, 143,
+  58, 197, 96, 126, 98, 121, 100, 68, 66, 106,
+  115, 62, 37, 128, 81, 108, 125, 87, 80, 92,
+  83, 121, 53, 105, 124, 148, 102, 133, 94, 119,
+  95, 141, 49, 88, 88, 149, 136, 119, 48, 112,
+  87, 83, 77, 108, 114, 142, 111, 103, 65, 76,
+  66, 99, 61, 106, 102, 113, 116, 112, 106, 96,
+  133, 73, 100, 83, 105, 126, 68, 126, 105, 86,
+  146, 144, 141, 123, 108, 129, 74, 87, 93, 110,
+  122, 69, 104, 100, 87, 107, 86, 57, 93, 132,
+  93, 94, 147, 102, 88, 136, 84, 72, 106, 109,
+  94, 137, 109, 141, 123, 97, 169, 86, 78, 112,
+  151, 59, 50, 145, 167, 119, 134, 99, 142, 72,
+  121, 50, 129, 122, 83, 139, 89, 135, 124, 68,
+  91, 174, 151, 80, 129, 160, 118, 124, 48, 107,
+  44, 83, 173, 101, 163, 90, 116, 76, 98, 94,
+  105, 120, 85, 91, 90, 167, 70, 87, 91, 96,
+  73, 78, 114, 107, 95, 67, 103, 97, 101, 127,
+  104, 123, 86, 112, 75, 100, 95, 101, 116, 108,
+  102, 93, 79, 117, 47, 94, 149, 101, 91, 129,
+  59, 88, 71, 150, 102, 109, 89, 128, 48, 74,
+  53, 68, 107, 125, 36, 80, 96, 77, 90, 65,
+  82, 85, 95, 99, 48, 113, 103, 142, 120, 151,
+  64, 108, 77, 146, 43, 86, 86, 111, 131, 112,
+  17, 85, 83, 108, 66, 91, 112, 86, 80, 79,
+  119, 60, 79, 103, 46, 109, 92, 76, 121, 130,
+  133, 89, 96, 70, 100, 132, 87, 100, 74, 115,
+  96, 98, 104, 96, 95, 98, 92, 98, 54, 96,
+  69, 103, 90, 59, 112, 136, 148, 99, 91, 49,
+  83, 61, 79, 90, 109, 91, 82, 114, 109, 86,
+  101, 108, 49, 111, 85, 155, 116, 67, 110, 96,
+  86, 83, 148, 76, 28, 113, 129, 94, 111, 96,
+  103, 51, 131, 146, 95, 137, 90, 96, 97, 97,
+  95, 55, 110, 152, 136, 111, 88, 153, 84, 96,
+  35, 67, 46, 69, 61, 78, 124, 104, 87, 99,
+  62, 83, 87, 80, 95, 69, 80, 145, 58, 78,
+  95, 138, 99, 90, 95, 100, 139, 82, 103, 140,
+  93, 119, 95, 118, 82, 118, 71, 89, 83, 62,
+  106, 85, 117, 100, 97, 107, 90, 104, 107, 113,
+  96, 119, 75, 80, 108, 107, 90, 71, 95, 140,
+  72, 86, 93, 83, 95, 90, 36, 115, 113, 61,
+  80, 67, 104, 87, 76, 102, 86, 147, 70, 122,
+  116, 114, 83, 98, 99, 136, 71, 65, 117, 117,
+  142, 124, 45, 112, 99, 133, 67, 111, 141, 94,
+  85, 86, 104, 101, 84, 100, 66, 97, 85, 115,
+  98, 112, 101, 87, 81, 119, 125, 107, 75, 99,
+  67, 69, 119, 93, 141, 100, 52, 102, 107, 90,
+  61, 111, 111, 96, 85, 87, 89, 134, 175, 99,
+  105, 102, 92, 104, 88, 130, 95, 114, 78, 41,
+  130, 107, 107, 138, 71, 94, 82, 149, 112, 71,
+  99, 110, 76, 92, 122, 91, 50, 74, 89, 82,
+  103, 100, 113, 85, 142, 152, 88, 81, 135, 112,
+  117, 83, 76, 75, 96, 109, 119, 106, 57, 110,
+  61, 109, 102, 112, 55, 106, 84, 120, 76, 99,
+  97, 131, 106, 76, 75, 84, 112, 75, 88, 123,
+  68, 100, 94, 183, 122, 117, 52, 106, 128, 103,
+  97, 153, 74, 105, 105, 86, 91, 104, 79, 73,
+  91, 58, 124, 107, 131, 106, 128, 127, 135, 134,
+  117, 117, 121, 107, 106, 104, 150, 110, 112, 100,
+  94, 133, 101, 101, 135, 59, 105, 84, 40, 159,
+  128, 86, 103, 83, 146, 87, 76, 97, 141, 141,
+  82, 122, 106, 74, 100, 112, 125, 125, 95, 115,
+  118, 156, 143, 149, 106, 96, 102, 138, 86, 138,
+  122, 92, 103, 107, 118, 135, 99, 83, 110, 122,
+  113, 109, 97, 110, 90, 106, 101, 157, 140, 72,
+  103, 104, 76, 85, 133, 97, 129, 120, 92, 116,
+  122, 103, 92, 99, 96, 92, 93, 118, 104, 111,
+  152, 122, 138, 143, 129, 140, 114, 123, 118, 128,
+  105, 83, 130, 113, 137, 152, 66, 92, 121, 124,
+  108, 99, 102, 115, 80, 108, 88, 100, 75, 63,
+  76, 94, 123, 69, 143, 127, 119, 97, 111, 111,
+  153, 136, 122, 93, 94, 107, 96, 100, 103, 111,
+  83, 75, 97, 115, 151, 139, 88, 140, 71, 162,
+  89, 97, 124, 103, 122, 88, 103, 117, 110, 57,
+  108, 106, 89, 137, 80, 143, 116, 85, 77, 84,
+  110, 129, 101, 117, 81, 116, 94, 89, 68, 79,
+  102, 111, 100, 96, 155, 105, 125, 111, 94, 132,
+  140, 140, 124, 112, 129, 120, 120, 117, 142, 112,
+  114, 98, 106, 120, 112, 100, 142, 108, 152, 94,
+  67, 158, 166, 114, 112, 106, 149, 96, 81, 95,
+  129, 152, 97, 130, 119, 92, 127, 125, 137, 112,
+  105, 113, 106, 132, 131, 150, 126, 85, 112, 135,
+  130, 119, 132, 116, 108, 126, 107, 124, 103, 115,
+  133, 128, 128, 109, 115, 116, 72, 120, 101, 147,
+  133, 120, 176, 120, 121, 148, 133, 92, 122, 97,
+  123, 109, 141, 126, 108, 110, 94, 141, 105, 142,
+  116, 93, 140, 131, 123, 140, 148, 127, 107, 129,
+  125, 103, 126, 166, 130, 141, 148, 109, 89, 99,
+  121, 106, 114, 122, 107, 119, 88, 119, 108, 121,
+  92, 115, 102, 116, 127, 116, 120, 134, 112, 88,
+  140, 129, 141, 127, 120, 111, 109, 109, 109, 111,
+  109, 106, 99, 79, 110, 138, 120, 110, 124, 141,
+  80, 153, 95, 105, 122, 105, 134, 90, 122, 129,
+  102, 72, 119, 101, 98, 149, 96, 114, 113, 118,
+  104, 71, 103, 120, 138, 138, 78, 117, 110, 103,
+  77, 101, 111, 111, 103, 111, 165, 115, 141, 110,
+  84, 149, 93, 96, 118, 107, 90, 151, 104, 150,
+  129, 122, 136, 128, 95, 150, 112, 127, 92, 126,
+  132, 75, 82, 121, 176, 127, 132, 101, 122, 68,
+  133, 93, 79, 125, 90, 106, 130, 109, 121, 145,
+  131, 104, 77, 114, 113, 108, 117, 137, 111, 101,
+  110, 144, 114, 106, 137, 126, 98, 143, 101, 119,
+  101, 127, 108, 95, 94, 117, 120, 106, 122, 107,
+  120, 98, 121, 119, 134, 159, 119, 155, 119, 88,
+  101, 109, 106, 108, 129, 137, 96, 121, 121, 120,
+  103, 104, 99, 124, 102, 135, 101, 101, 141, 94,
+  123, 158, 124, 103, 120, 170, 117, 148, 140, 97,
+  100, 112, 99, 126, 113, 157, 102, 119, 129, 162,
+  141, 115, 94, 101, 123, 141, 110, 126, 103, 89,
+  101, 124, 122, 93, 109, 137, 90, 158, 112, 88,
+  109, 153, 163, 108, 114, 146, 104, 113, 61, 143,
+  126, 146, 103, 89, 122, 106, 111, 104, 107, 127,
+  149, 109, 114, 101, 115, 134, 93, 85, 127, 86,
+  108, 112, 109, 134, 107, 70, 154, 157, 99, 101,
+  139, 138, 110, 115, 139, 97, 77, 137, 129, 108,
+  165, 104, 133, 135, 89, 89, 113, 135, 89, 89,
+  94, 156, 128, 127, 129, 132, 96, 149, 101, 121,
+  125, 123, 110, 80, 61, 124, 85, 111, 147, 101,
+  130, 126, 124, 79, 92, 119, 75, 117, 165, 99,
+  114, 109, 121, 98, 71, 79, 105, 146, 69, 136,
+  121, 191, 102, 132, 95, 123, 134, 115, 76, 145,
+  97, 124, 86, 113, 112, 94, 99, 117, 102, 95,
+  97, 105, 135, 85, 133, 102, 74, 175, 79, 123,
+  98, 94, 98, 116, 99, 129, 127, 144, 96, 109,
+  107, 103, 101, 70, 115, 156, 117, 135, 98, 90,
+  169, 92, 147, 160, 168, 113, 110, 118, 91, 220,
+  150, 99, 100, 116, 90, 128, 107, 183, 101, 125,
+  128, 165, 109, 125, 84, 105, 101, 129, 96, 117,
+  146, 75, 101, 107, 117, 99, 108, 141, 80, 177,
+  100, 110, 124, 147, 153, 91, 119, 152, 103, 109,
+  99, 160, 123, 157, 97, 73, 117, 89, 84, 112,
+  135, 121, 131, 90, 124, 157, 130, 125, 77, 63,
+  124, 145, 93, 141, 109, 130, 92, 78, 134, 122,
+  100, 95, 133, 120, 112, 106, 151, 94, 82, 145,
+  87, 114, 164, 95, 117, 120, 96, 102, 124, 121,
+  94, 96, 95, 126, 118, 141, 119, 134, 106, 122,
+  110, 90, 106, 88, 113, 110, 52, 122, 38, 107,
+  156, 96, 117, 114, 99, 75, 98, 112, 60, 137,
+  131, 91, 93, 110, 107, 126, 74, 117, 87, 173,
+  96, 132, 124, 156, 85, 80, 84, 126, 108, 93,
+  77, 98, 89, 104, 111, 92, 100, 90, 99, 114,
+  120, 115, 101, 82, 122, 88, 132, 77, 80, 142,
+  59, 111, 103, 93, 135, 79, 124, 131, 93, 152,
+  98, 101, 90, 116, 108, 80, 112, 135, 111, 113,
+  107, 79, 156, 138, 144, 134, 162, 107, 108, 167,
+  84, 120, 114, 122, 82, 93, 86, 108, 98, 144,
+  103, 100, 120, 154, 117, 79, 54, 95, 94, 102,
+  114, 91, 175, 83, 92, 93, 117, 155, 97, 121,
+  75, 163, 100, 110, 119, 148, 126, 87, 117, 141,
+  94, 102, 59, 114, 100, 146, 101, 87, 129, 90,
+  72, 114, 106, 105, 89, 106, 99, 141, 143, 126,
+  84, 75, 107, 137, 66, 101, 125, 102, 94, 84,
+  106, 95, 94, 118, 119, 99, 105, 85, 107, 93,
+  80, 136, 80, 104, 166, 69, 96, 106, 81, 93,
+  115, 144, 81, 91, 82, 89, 79, 79, 87, 92,
+  112, 116, 119, 90, 93, 120, 115, 125, 33, 77,
+  33, 92, 142, 82, 128, 98, 122, 59, 92, 112,
+  62, 111, 114, 112, 71, 96, 97, 65, 91, 66,
+  61, 156, 101, 104, 93, 120, 72, 95, 87, 103,
+  95, 89, 75, 110, 102, 56, 118, 117, 72, 75,
+  77, 105, 102, 84, 63, 83, 81, 84, 102, 149,
+  89, 116, 70, 118, 93, 88, 127, 81, 85, 70,
+  94, 135, 64, 93, 106, 103, 87, 79, 106, 109,
+  117, 106, 81, 55, 119, 114, 108, 100, 137, 78,
+  72, 143, 88, 117, 123, 85, 66, 100, 62, 99,
+  103, 128, 93, 88, 106, 127, 119, 89, 45, 96,
+  85, 103, 72, 104, 90, 96, 103, 103, 121, 143,
+  84, 113, 104, 154, 77, 92, 107, 128, 108, 76,
+  90, 109, 82, 95, 33, 92, 78, 95, 63, 65,
+  92, 75, 38, 123, 71, 102, 89, 81, 111, 112,
+  125, 96, 93, 74, 92, 133, 81, 113, 92, 80,
+  93, 91, 149, 88, 83, 132, 95, 88, 89, 66,
+  56, 77, 89, 112, 71, 82, 183, 87, 119, 89,
+  131, 110, 121, 161, 80, 83, 87, 96, 90, 82,
+  107, 79, 99, 111, 123, 114, 97, 100, 109, 85,
+  42, 78, 62, 99, 161, 91, 136, 105, 124, 92,
+  117, 93, 85, 76, 85, 99, 103, 104, 123, 36,
+  116, 70, 61, 154, 105, 99, 95, 152, 67, 98,
+  86, 99, 110, 94, 89, 92, 106, 72, 122, 107,
+  114, 109, 86, 110, 102, 93, 103, 80, 96, 93,
+  117, 104, 105, 115, 99, 100, 89, 94, 91, 98,
+  64, 87, 86, 147, 72, 89, 121, 69, 94, 85,
+  73, 135, 121, 118, 103, 88, 154, 114, 135, 115,
+  124, 91, 98, 58, 89, 110, 118, 87, 67, 106,
+  66, 87, 92, 132, 119, 93, 93, 136, 118, 77,
+  69, 90, 93, 94, 106, 88, 118, 103, 92, 85,
+  115, 94, 118, 112, 116, 140, 86, 126, 110, 118,
+  94, 98, 97, 94, 104, 102, 101, 114, 102, 127,
+  52, 119, 115, 80, 47, 89, 60, 76, 85, 94,
+  100, 118, 120, 93, 109, 112, 100, 108, 77, 107,
+  108, 82, 97, 88, 116, 84, 79, 155, 97, 80,
+  88, 71, 75, 74, 111, 125, 72, 78, 167, 87,
+  77, 93, 142, 132, 120, 145, 113, 105, 87, 107,
+  95, 86, 113, 77, 97, 112, 118, 109, 95, 87,
+  101, 95, 52, 104, 65, 124, 161, 99, 123, 87,
+  118, 94, 86, 68, 90, 75, 78, 94, 101, 108,
+  136, 43, 151, 76, 62, 168, 121, 112, 85, 136,
+  58, 87, 80, 92, 109, 89, 85, 101, 102, 69,
+  130, 104, 162, 120, 97, 107, 100, 83, 101, 71,
+  115, 98, 132, 78, 104, 108, 105, 101, 85, 105,
+  49, 93, 67, 118, 82, 165, 94, 82, 101, 86,
+  102, 86, 77, 114, 87, 126, 102, 119, 186, 101,
+  143, 128, 133, 83, 121, 88, 97, 102, 122, 99,
+  71, 110, 72, 73, 75, 126, 121, 83, 105, 142,
+  125, 76, 103, 100, 93, 89, 97, 94, 116, 87,
+  97, 73, 104, 94, 126, 101, 123, 112, 97, 118,
+  118, 116, 107, 105, 102, 78, 113, 82, 126, 123,
+  123, 152, 50, 122, 120, 77, 46, 66, 66, 90,
+  87, 92, 92, 115, 108, 83, 113, 104, 107, 87,
+  61, 88, 118, 95, 96, 72, 116, 78, 77, 129,
+  104, 84, 105, 74, 99, 77, 123, 146, 102, 110,
+  133, 91, 95, 101, 133, 129, 119, 117, 122, 111,
+  92, 111, 107, 121, 105, 99, 102, 109, 111, 100,
+  90, 79, 102, 90, 68, 135, 71, 118, 147, 109,
+  117, 78, 98, 90, 82, 55, 90, 88, 62, 103,
+  108, 109, 128, 50, 143, 86, 70, 156, 127, 115,
+  83, 124, 63, 92, 70, 95, 106, 68, 104, 109,
+  100, 84, 109, 102, 154, 132, 102, 113, 93, 86,
+  88, 57, 136, 106, 141, 79, 110, 107, 123, 106,
+  85, 116, 43, 91, 90, 135, 85, 161, 104, 89,
+  92, 109, 90, 90, 77, 82, 64, 112, 108, 139,
+  171, 95, 132, 131, 129, 100, 120, 109, 117, 109,
+  114, 91, 92, 110, 96, 73, 73, 119, 134, 76,
+  101, 129, 130, 72, 107, 94, 111, 97, 88, 71,
+  117, 71, 84, 66, 92, 95, 127, 94, 106, 91,
+  125, 113, 112, 129, 116, 109, 101, 84, 121, 85,
+  121, 131, 119, 153, 46, 115, 129, 71, 67, 65,
+  102, 89, 92, 108, 92, 108, 88, 87, 103, 97,
+  97, 91, 64, 69, 117, 103, 92, 77, 99, 92,
+  90, 92, 105, 86, 96, 81, 103, 82, 114, 152,
+  109, 111, 100, 83, 95, 103, 113, 108, 133, 98,
+  117, 123, 90, 91, 110, 133, 124, 98, 91, 110,
+  106, 89, 81, 61, 89, 109, 66, 129, 67, 103,
+  120, 103, 106, 85, 79, 92, 59, 61, 77, 111,
+  74, 106, 98, 116, 125, 58, 109, 105, 92, 110,
+  121, 126, 79, 111, 81, 115, 59, 102, 107, 88,
+  133, 126, 101, 109, 128, 111, 107, 116, 103, 116,
+  97, 101, 90, 46, 162, 101, 142, 97, 90, 98,
+  151, 116, 92, 124, 67, 86, 94, 111, 104, 138,
+  97, 96, 81, 143, 79, 107, 70, 84, 74, 90,
+  109, 148, 130, 91, 109, 132, 119, 115, 118, 126,
+  154, 121, 118, 92, 107, 106, 99, 93, 98, 108,
+  121, 78, 104, 99, 147, 71, 98, 92, 121, 114,
+  88, 73, 115, 77, 110, 96, 89, 117, 120, 102,
+  85, 59, 152, 129, 98, 146, 119, 124, 84, 88,
+  100, 94, 104, 111, 102, 140, 83, 94, 111, 78,
+  86, 84, 131, 88, 91, 107, 98, 113, 80, 111,
+  90, 100, 87, 103, 75, 70, 91, 104, 103, 86,
+  103, 130, 101, 70, 116, 91, 83, 104, 93, 102,
+  94, 143, 113, 128, 93, 92, 108, 105, 104, 85,
+  103, 105, 107, 113, 111, 82, 128, 111, 135, 98,
+  81, 114, 116, 98, 94, 59, 108, 103, 66, 99,
+  95, 92, 93, 100, 118, 135, 92, 92, 58, 94,
+  99, 113, 117, 118, 104, 115, 135, 67, 103, 105,
+  128, 71, 112, 113, 89, 103, 82, 145, 67, 121,
+  97, 114, 134, 122, 112, 129, 113, 110, 76, 93,
+  106, 134, 99, 114, 95, 68, 165, 98, 126, 121,
+  61, 116, 123, 102, 103, 129, 78, 84, 87, 73,
+  106, 99, 89, 95, 110, 130, 87, 127, 63, 101,
+  98, 89, 112, 145, 96, 98, 85, 133, 102, 129,
+  119, 92, 143, 137, 118, 89, 107, 116, 102, 113,
+  109, 102, 98, 105, 106, 75, 121, 116, 105, 95,
+  137, 124, 84, 89, 88, 108, 152, 109, 80, 119,
+  105, 104, 86, 57, 128, 126, 96, 124, 123, 117,
+  79, 86, 110, 105, 108, 107, 82, 120, 109, 92,
+  73, 100, 91, 127, 92, 109, 110, 95, 125, 120,
+  99, 116, 88, 112, 87, 109, 87, 80, 66, 132,
+  120, 103, 100, 138, 105, 60, 129, 103, 89, 98,
+  88, 97, 84, 112, 131, 140, 105, 114, 84, 109,
+  123, 103, 93, 107, 106, 94, 128, 83, 147, 94,
+  140, 113, 79, 117, 119, 120, 104, 54, 116, 102,
+  62, 104, 88, 90, 95, 94, 141, 140, 119, 91,
+  84, 105, 118, 103, 113, 108, 108, 113, 142, 84,
+  118, 114, 153, 78, 108, 114, 112, 111, 77, 156,
+  89, 164, 89, 121, 123, 114, 134, 138, 107, 108,
+  79, 91, 112, 122, 98, 128, 108, 87, 151, 110,
+  112, 116, 62, 129, 79, 77, 118, 144, 60, 103,
+  94, 88, 89, 92, 86, 85, 136, 103, 103, 135,
+  69, 129, 126, 96, 117, 132, 105, 86, 102, 132,
+  107, 118, 128, 75, 124, 95, 114, 125, 84, 124,
+  110, 122, 100, 106, 88, 128, 110, 83, 104, 133,
+  109, 80, 115, 106, 102, 94, 74, 131, 135, 126,
+  88, 88, 109, 103, 105, 63, 93, 127, 94, 105,
+  111, 120, 97, 82, 121, 120, 125, 123, 77, 113,
+  71, 110, 71, 107, 98, 131, 68, 117, 126, 89,
+  125, 120, 114, 103, 101, 132, 86, 107, 72, 84,
+  82, 125, 135, 113, 91, 122, 100, 87, 124, 105,
+  93, 78, 101, 99, 86, 99, 108, 120, 114, 119,
+  108, 116, 141, 137, 83, 120, 112, 92, 143, 95,
+  148, 105, 137, 122, 88, 117, 131, 129, 117, 72,
+  127, 95, 63, 124, 79, 105, 111, 80, 143, 101,
+  123, 89, 108, 109, 125, 103, 84, 86, 108, 105,
+  142, 81, 143, 117, 149, 107, 109, 117, 121, 110,
+  71, 134, 111, 179, 101, 115, 104, 124, 128, 128,
+  98, 110, 107, 94, 116, 115, 92, 127, 97, 103,
+  134, 127, 103, 101, 74, 117, 74, 72, 133, 155,
+  63, 108, 98, 95, 79, 106, 90, 85, 138, 101,
+  104, 127, 76, 140, 114, 88, 120, 115, 132, 80,
+  128, 133, 124, 92, 138, 82, 121, 86, 116, 145,
+  97, 135, 122, 116, 82, 113, 94, 126, 112, 119,
+  100, 117, 104, 77, 107, 89, 116, 98, 88, 139,
+  106, 113, 94, 88, 105, 105, 119, 83, 76, 128,
+  100, 101, 105, 121, 108, 79, 144, 134, 130, 146,
+  84, 131, 73, 135, 85, 104, 99, 120, 80, 122,
+  106, 94, 119, 107, 120, 101, 110, 135, 89, 100,
+  58, 86, 116, 106, 127, 126, 87, 104, 91, 109,
+  116, 92, 98, 63, 98, 104, 99, 92, 99, 109,
+  125, 121, 93, 109, 139, 166, 89, 124, 113, 82,
+  141, 102, 153, 136, 129, 113, 92, 111, 118, 138,
+  114, 72, 127, 106, 58, 136, 75, 131, 124, 76,
+  155, 91, 123, 89, 132, 103, 122, 111, 68, 86,
+  110, 113, 129, 71, 154, 125, 144, 125, 102, 117,
+  124, 99, 52, 104, 115, 187, 96, 118, 96, 135,
+  126, 124, 105, 117, 133, 114, 121, 104, 93, 120,
+  72, 115, 120, 123, 106, 104, 93, 112, 79, 76,
+  129, 156, 57, 103, 111, 94, 82, 131, 94, 87,
+  119, 111, 95, 123, 71, 133, 104, 95, 123, 98,
+  142, 86, 149, 116, 128, 84, 139, 93, 101, 99,
+  114, 146, 98, 128, 127, 108, 69, 115, 103, 98,
+  104, 145, 99, 109, 88, 78, 87, 96, 130, 90,
+  82, 130, 86, 88, 94, 104, 92, 100, 127, 91,
+  83, 125, 108, 107, 105, 115, 119, 90, 148, 132,
+  144, 141, 96, 138, 43, 145, 103, 95, 95, 129,
+  81, 125, 95, 111, 112, 100, 122, 83, 119, 130,
+  83, 96, 58, 81, 148, 90, 109, 127, 93, 96,
+  87, 139, 100, 93, 101, 53, 90, 102, 107, 90,
+  88, 106, 128, 126, 103, 98, 135, 165, 102, 96,
+  109, 74, 122, 104, 153, 164, 137, 122, 110, 101,
+  99, 141, 118, 58, 113, 99, 49, 145, 61, 139,
+  110, 81, 166, 103, 127, 90, 143, 92, 120, 108,
+  67, 75, 109, 104, 108, 76, 142, 151, 143, 111,
+  107, 117, 116, 102, 62, 69, 109, 201, 93, 117,
+  104, 149, 110, 126, 97, 108, 130, 144, 129, 99,
+  104, 122, 66, 113, 111, 115, 113, 108, 108, 101,
+  110, 74, 129, 152, 42, 101, 138, 118, 83, 150,
+  95, 91, 112, 109, 86, 108, 80, 126, 116, 104,
+  121, 88, 135, 84, 154, 115, 121, 98, 125, 114,
+  106, 111, 109, 138, 96, 122, 124, 107, 74, 124,
+  107, 74, 101, 150, 106, 116, 60, 85, 74, 104,
+  153, 79, 92, 111, 77, 70, 78, 86, 82, 97,
+  122, 80, 101, 129, 114, 104, 102, 117, 109, 125,
+  146, 125, 137, 147, 102, 142, 40, 148, 117, 89,
+  92, 121, 93, 108, 106, 123, 99, 107, 126, 71,
+  123, 116, 67, 108, 62, 79, 158, 70, 96, 132,
+  99, 95, 92, 155, 89, 99, 101, 65, 90, 92,
+  110, 88, 76, 108, 122, 124, 101, 88, 119, 148,
+  99, 74, 88, 68, 100, 92, 141, 166, 131, 127,
+  119, 91, 77, 117, 118, 50, 79, 95, 38, 151,
+  63, 131, 85, 70, 143, 121, 111, 85, 133, 92,
+  105, 103, 86, 58, 95, 81, 102, 108, 124, 155,
+  124, 96, 102, 128, 106, 96, 81, 60, 93, 213,
+  106, 113, 128, 155, 85, 123, 85, 94, 93, 145,
+  140, 100, 124, 134, 67, 91, 94, 118, 107, 108,
+  106, 102, 134, 69, 136, 132, 73, 103, 146, 113,
+  94, 152, 95, 93, 104, 107, 99, 94, 108, 134,
+  114, 95, 136, 87, 113, 91, 138, 117, 102, 95,
+  98, 130, 114, 109, 114, 134, 105, 109, 119, 105,
+  88, 121, 100, 80, 99, 124, 115, 136, 45, 105,
+  57, 109, 169, 108, 96, 79, 65, 62, 75, 84,
+  80, 106, 106, 58, 83, 129, 126, 109, 104, 138,
+  82, 156, 122, 118, 111, 124, 94, 125, 64, 152,
+  99, 93, 107, 99, 114, 84, 111, 116, 98, 101,
+  120, 89, 97, 97, 57, 113, 65, 54, 126, 54,
+  97, 144, 87, 105, 92, 150, 87, 102, 102, 88,
+  90, 84, 99, 85, 64, 110, 121, 105, 114, 81,
+  93, 121, 64, 83, 53, 67, 105, 75, 139, 139,
+  105, 128, 119, 103, 48, 86, 95, 77, 75, 103,
+  31, 115, 89, 110, 69, 47, 108, 98, 89, 77,
+  109, 108, 88, 100, 104, 59, 81, 57, 98, 130,
+  99, 129, 110, 106, 93, 124, 85, 89, 75, 52,
+  87, 166, 110, 108, 112, 124, 88, 103, 71, 95,
+  49, 120, 144, 101, 132, 157, 79, 58, 77, 114,
+  90, 92, 90, 100, 116, 83, 127, 103, 106, 108,
+  132, 88, 105, 121, 82, 98, 94, 100, 130, 81,
+  131, 135, 99, 82, 139, 70, 94, 105, 110, 111,
+  77, 77, 67, 119, 110, 88, 116, 125, 102, 97,
+  106, 115, 92, 101, 81, 102, 97, 85, 111, 142,
+  27, 124, 62, 105, 153, 143, 106, 57, 69, 78,
+  92, 95, 77, 88, 86, 60, 48, 106, 126, 109,
+  109, 141, 49, 158, 98, 114, 85, 104, 69, 94,
+  93, 138, 69, 100, 125, 92, 113, 87, 87, 102,
+  106, 98, 104, 118, 64, 93, 85, 107, 65, 46,
+  83, 58, 115, 136, 81, 101, 83, 135, 94, 75,
+  89, 104, 92, 63, 86, 61, 41, 99, 131, 91,
+  101, 70, 67, 96, 57, 117, 36, 84, 118, 68,
+  132, 106, 96, 128, 115, 125, 36, 72, 66, 116,
+  74, 146, 19, 76, 107, 88, 92, 39, 78, 70,
+  115, 83, 83, 114, 77, 89, 102, 68, 86, 51,
+  105, 113, 84, 98, 94, 115, 98, 125, 47, 92,
+  85, 22, 88, 107, 108, 80, 82, 89, 90, 69,
+  54, 87, 46, 83, 104, 88, 123, 163, 88, 43,
+  73, 114, 91, 66, 76, 82, 101, 112, 111, 85,
+  115, 130, 107, 91, 101, 101, 57, 115, 103, 98,
+  153, 69, 120, 127, 109, 75, 109, 53, 104, 121,
+  105, 97, 56, 49, 56, 119, 107, 105, 114, 101,
+  85, 82, 76, 114, 100, 92, 89, 108, 107, 81,
+  124, 120, 25, 122, 90, 94, 125, 130, 126, 45,
+  66, 79, 109, 123, 67, 81, 81, 81, 36, 96,
+  105, 120, 118, 125, 33, 129, 67, 111, 60, 102,
+  57, 88, 95, 121, 64, 104, 103, 82, 93, 93,
+  80, 109, 102, 111, 95, 131, 49, 96, 115, 89,
+  82, 56, 84, 75, 136, 121, 75, 85, 74, 115,
+  100, 60, 77, 122, 73, 53, 89, 52, 34, 70,
+  154, 73, 95, 61, 68, 93, 88, 112, 43, 106,
+  87, 94, 76, 90, 105, 101, 139, 117, 37, 75,
+  52, 136, 77, 140, 22, 65, 88, 89, 147, 57,
+  89, 71, 105, 91, 79, 111, 71, 62, 83, 81,
+  90, 76, 113, 90, 70, 72, 79, 126, 100, 118,
+  32, 104, 73, 28, 83, 66, 100, 80, 87, 89,
+  83, 56, 61, 80, 70, 84, 69, 92, 112, 128,
+  103, 59, 88, 117, 112, 87, 95, 91, 79, 140,
+  98, 80, 87, 144, 56, 122, 86, 130, 35, 143,
+  114, 88, 141, 58, 82, 144, 130, 87, 79, 49,
+  131, 94, 125, 97, 65, 28, 66, 131, 94, 123,
+  111, 72, 65, 96, 57, 97, 112, 108, 137, 94,
+  112, 110, 143, 108, 25, 103, 110, 91, 89, 105,
+  118, 52, 72, 79, 116, 103, 61, 96, 94, 119,
+  53, 118, 110, 153, 112, 98, 39, 121, 62, 104,
+  57, 116, 69, 96, 75, 105, 107, 83, 55, 98,
+  98, 74, 81, 117, 85, 124, 86, 93, 60, 103,
+  121, 87, 102, 59, 96, 77, 117, 92, 113, 85,
+  85, 111, 88, 75, 94, 123, 78, 64, 103, 75,
+  59, 68, 186, 64, 133, 78, 79, 114, 102, 108,
+  81, 105, 72, 124, 64, 90, 77, 88, 134, 92,
+  72, 86, 66, 121, 104, 58, 42, 84, 53, 115,
+  188, 88, 104, 83, 84, 87, 82, 112, 72, 70,
+  77, 76, 107, 93, 121, 68, 75, 67, 75, 163,
+  95, 121, 64, 152, 61, 70, 79, 79, 106, 132,
+  105, 117, 85, 55, 95, 103, 101, 98, 86, 117,
+  99, 93, 99, 68, 109, 115, 125, 90, 104, 119,
+  70, 134, 87, 73, 73, 124, 50, 121, 73, 172,
+  36, 143, 87, 79, 93, 54, 51, 130, 127, 97,
+  79, 64, 156, 101, 139, 105, 116, 45, 77, 107,
+  83, 90, 113, 79, 60, 128, 63, 77, 113, 121,
+  182, 83, 111, 146, 133, 95, 48, 104, 98, 107,
+  78, 89, 141, 67, 99, 90, 126, 87, 72, 108,
+  105, 177, 98, 119, 119, 168, 103, 74, 83, 131,
+  95, 90, 80, 113, 74, 116, 84, 86, 132, 54,
+  50, 87, 119, 82, 85, 102, 89, 130, 77, 85,
+  82, 96, 129, 110, 96, 100, 98, 85, 92, 75,
+  129, 100, 91, 120, 89, 84, 104, 107, 116, 85,
+  118, 118, 55, 98, 183, 62, 128, 104, 83, 123,
+  118, 130, 95, 123, 70, 135, 111, 110, 76, 98,
+  110, 103, 88, 100, 93, 82, 93, 72, 55, 95,
+  46, 140, 184, 85, 98, 110, 97, 74, 91, 117,
+  65, 104, 81, 69, 109, 97, 123, 78, 79, 99,
+  79, 184, 88, 116, 97, 149, 46, 72, 81, 108,
+  114, 117, 82, 122, 94, 67, 127, 118, 103, 80,
+  106, 114, 107, 100, 105, 82, 136, 97, 125, 82,
+  84, 126, 138, 127, 87, 76, 86, 97, 84, 103,
+  67, 163, 57, 94, 85, 93, 86, 67, 60, 94,
+  109, 96, 94, 82, 179, 123, 149, 122, 149, 93,
+  96, 108, 78, 99, 113, 111, 69, 145, 72, 80,
+  95, 130, 148, 81, 112, 160, 122, 80, 63, 140,
+  71, 126, 78, 94, 177, 68, 115, 104, 131, 133,
+  91, 114, 97, 203, 146, 113, 119, 161, 102, 85,
+  110, 145, 112, 92, 103, 117, 81, 128, 88, 75,
+  136, 69, 65, 89, 119, 119, 97, 83, 111, 125,
+  84, 113, 82, 68, 130, 104, 73, 136, 107, 93,
+  101, 60, 110, 98, 89, 114, 117, 98, 95, 106,
+  152, 95, 107, 141, 54, 102, 157, 55, 126, 114,
+  72, 98, 123, 124, 93, 141, 76, 120, 114, 109,
+  97, 99, 92, 126, 88, 109, 88, 98, 74, 101,
+  59, 95, 92, 161, 156, 80, 94, 135, 110, 68,
+  84, 125, 67, 104, 105, 85, 95, 89, 113, 75,
+  81, 109, 94, 152, 90, 111, 96, 91, 62, 62,
+  83, 112, 93, 76, 78, 146, 104, 77, 101, 106,
+  87, 59, 97, 113, 112, 105, 111, 82, 135, 88,
+  126, 104, 45, 140, 174, 165, 91, 86, 79, 98,
+  111, 108, 80, 141, 57, 83, 108, 92, 121, 56,
+  85, 97, 100, 122, 89, 91, 162, 73, 133, 128,
+  144, 114, 96, 137, 66, 142, 121, 128, 75, 157,
+  74, 80, 81, 158, 113, 72, 120, 137, 137, 98,
+  67, 156, 89, 121, 70, 117, 134, 69, 130, 105,
+  112, 155, 96, 126, 67, 191, 127, 88, 133, 151,
+  103, 92, 96, 151, 113, 94, 85, 121, 82, 134,
+  79, 78, 134, 90, 71, 107, 92, 126, 109, 68,
+  128, 117, 95, 117, 71, 39, 131, 88, 76, 107,
+  103, 113, 119, 56, 151, 86, 101, 92, 163, 99,
+  103, 109, 155, 87, 80, 125, 82, 93, 162, 52,
+  101, 103, 71, 82, 133, 139, 85, 97, 78, 114,
+  92, 114, 109, 86, 90, 112, 96, 99, 57, 127,
+  76, 127, 50, 118, 101, 152, 162, 85, 97, 120,
+  111, 77, 67, 113, 61, 84, 122, 107, 102, 93,
+  108, 78, 86, 84, 83, 135, 92, 106, 70, 122,
+  80, 76, 84, 101, 106, 80, 93, 163, 95, 68,
+  67, 99, 102, 56, 67, 110, 107, 97, 99, 67,
+  136, 100, 129, 97, 57, 132, 105, 162, 88, 94,
+  77, 126, 94, 91, 91, 141, 59, 105, 93, 86,
+  147, 43, 89, 145, 84, 120, 87, 88, 152, 84,
+  117, 124, 140, 103, 86, 101, 91, 155, 125, 102,
+  88, 153, 71, 79, 89, 154, 133, 66, 126, 125,
+  151, 82, 79, 119, 104, 100, 69, 111, 127, 78,
+  128, 81, 112, 136, 81, 112, 59, 173, 77, 82,
+  103, 152, 96, 95, 96, 125, 85, 93, 85, 118,
+  95, 148, 85, 84, 137, 79, 59, 98, 84, 96,
+  103, 78, 128, 143, 102, 131, 69, 37, 131, 103,
+  92, 102, 99, 112, 109, 48, 159, 76, 103, 92,
+  159, 83, 110, 108, 144, 73, 76, 125, 96, 63,
+  185, 69, 118, 95, 91, 110, 138, 101, 105, 80,
+  93, 132, 85, 151, 117, 102, 113, 77, 82, 92,
+  77, 78, 89, 85, 47, 128, 97, 131, 172, 100,
+  131, 101, 82, 113, 80, 95, 93, 100, 82, 104,
+  128, 103, 101, 86, 83, 86, 56, 142, 93, 96,
+  66, 122, 66, 82, 65, 83, 101, 69, 148, 130,
+  76, 69, 100, 85, 160, 139, 87, 118, 109, 89,
+  107, 54, 140, 107, 136, 71, 106, 112, 74, 130,
+  78, 102, 44, 120, 101, 127, 99, 163, 69, 105,
+  68, 93, 118, 47, 69, 148, 63, 92, 116, 108,
+  173, 99, 135, 123, 135, 109, 84, 107, 99, 117,
+  120, 92, 79, 142, 77, 75, 112, 137, 174, 56,
+  115, 111, 145, 74, 79, 100, 108, 93, 111, 55,
+  155, 78, 106, 54, 102, 106, 62, 106, 71, 163,
+  101, 99, 91, 155, 92, 89, 119, 123, 93, 75,
+  94, 107, 108, 157, 59, 118, 174, 43, 55, 84,
+  77, 56, 105, 94, 92, 164, 110, 95, 96, 67,
+  95, 97, 101, 70, 101, 102, 89, 33, 112, 88,
+  105, 127, 115, 81, 107, 85, 133, 62, 99, 143,
+  102, 81, 159, 82, 94, 86, 62, 118, 139, 78,
+  109, 109, 72, 121, 72, 157, 104, 89, 135, 83,
+  68, 86, 76, 56, 84, 92, 36, 106, 81, 95,
+  143, 84, 135, 101, 81, 113, 88, 84, 107, 112,
+  80, 105, 96, 97, 85, 96, 73, 56, 34, 119,
+  79, 79, 63, 87, 53, 81, 70, 85, 78, 135,
+  167, 118, 69, 51, 134, 109, 124, 166, 117, 115,
+  111, 79, 102, 62, 132, 78, 120, 86, 115, 85,
+  97, 106, 68, 94, 59, 107, 91, 135, 108, 144,
+  56, 75, 75, 104, 98, 39, 75, 97, 75, 70,
+  121, 97, 137, 103, 108, 107, 120, 92, 80, 127,
+  95, 82, 121, 107, 101, 131, 71, 97, 140, 106,
+  171, 61, 98, 80, 157, 91, 72, 113, 78, 122,
+  112, 114, 121, 75, 95, 89, 77, 76, 69, 100,
+  101, 126, 122, 80, 98, 153, 96, 79, 120, 144,
+  78, 76, 64, 88, 79, 103, 50, 103, 159, 37,
+  50, 85, 105, 42, 107, 79, 99, 106, 90, 100,
+  102, 66, 68, 96, 97, 82, 59, 89, 71, 36,
+  87, 125, 116, 132, 76, 100, 108, 71, 103, 62,
+  100, 131, 108, 135, 110, 110, 90, 113, 25, 96,
+  150, 92, 99, 134, 51, 118, 54, 152, 84, 93,
+  135, 129, 73, 81, 79, 73, 70, 83, 33, 99,
+  93, 69, 99, 73, 80, 109, 57, 118, 57, 98,
+  105, 142, 95, 127, 99, 100, 87, 132, 45, 77,
+  80, 110, 92, 78, 40, 94, 81, 102, 66, 88,
+  116, 166, 120, 104, 65, 68, 85, 109, 59, 107,
+  92, 94, 110, 98, 111, 91, 119, 72, 107, 89,
+  86, 100, 76, 109, 92, 92, 117, 138, 87, 111,
+  122, 119, 54, 75, 96, 99, 110, 62, 97, 84,
+  102, 78, 108, 68, 86, 96, 91, 99, 126, 90,
+  68, 123, 104, 74, 104, 95, 89, 123, 88, 160,
+  128, 89, 137, 83, 83, 91, 176, 77, 46, 114,
+  140, 158, 112, 137, 124, 64, 136, 128, 73, 86,
+  78, 122, 102, 114, 112, 70, 86, 152, 143, 86,
+  106, 165, 80, 112, 42, 96, 41, 80, 120, 92,
+  135, 77, 87, 94, 121, 73, 102, 83, 108, 85,
+  85, 116, 74, 75, 70, 129, 89, 94, 72, 107,
+  91, 65, 101, 154, 103, 118, 97, 117, 97, 112,
+  58, 81, 98, 82, 135, 143, 80, 107, 99, 139,
+  49, 78, 108, 84, 87, 95, 62, 79, 83, 115,
+  102, 88, 119, 146, 50, 85, 76, 55, 86, 97,
+  38, 77, 110, 46, 64, 60, 91, 83, 83, 89,
+  77, 122, 106, 125, 121, 168, 92, 94, 82, 130,
+  51, 91, 90, 107, 110, 85, 38, 99, 92, 153,
+  78, 108, 128, 99, 82, 82, 120, 83, 79, 110,
+  52, 101, 92, 77, 110, 95, 140, 110, 84, 86,
+  102, 117, 64, 96, 48, 88, 106, 85, 118, 145,
+  76, 92, 102, 85, 72, 83, 89, 83, 91, 83,
+  117, 131, 177, 74, 89, 79, 73, 80, 86, 104,
+  112, 103, 57, 84, 138, 83, 104, 125, 56, 94,
+  88, 181, 115, 70, 82, 103, 77, 84, 131, 88,
+  35, 92, 140, 133, 100, 94, 99, 84, 148, 174,
+  67, 84, 122, 97, 120, 97, 81, 77, 90, 114,
+  143, 99, 81, 132, 80, 98, 52, 91, 45, 63,
+  69, 92, 86, 101, 79, 125, 100, 89, 89, 68,
+  136, 78, 108, 121, 69, 96, 70, 176, 115, 113,
+  56, 105, 141, 100, 90, 157, 88, 105, 96, 110,
+  109, 111, 57, 84, 86, 49, 109, 117, 91, 117,
+  115, 125, 132, 128, 107, 119, 117, 83, 97, 84,
+  115, 111, 106, 72, 110, 125, 87, 91, 120, 71,
+  99, 89, 45, 146, 96, 55, 89, 72, 116, 72,
+  95, 86, 126, 149, 94, 113, 105, 78, 108, 97,
+  112, 126, 91, 88, 100, 140, 126, 119, 89, 95,
+  94, 163, 93, 144, 148, 89, 98, 105, 119, 129,
+  93, 93, 96, 109, 101, 103, 102, 104, 87, 104,
+  82, 138, 130, 82, 82, 97, 58, 81, 143, 80,
+  143, 126, 67, 112, 103, 89, 89, 98, 108, 88,
+  88, 118, 122, 157, 198, 89, 105, 135, 102, 139,
+  100, 125, 112, 114, 83, 56, 152, 110, 122, 159,
+  74, 86, 117, 137, 114, 78, 97, 109, 84, 105,
+  92, 83, 70, 61, 88, 73, 130, 87, 141, 128,
+  112, 114, 101, 89, 173, 113, 136, 81, 83, 99,
+  87, 83, 111, 101, 87, 70, 77, 107, 133, 139,
+  83, 118, 61, 155, 84, 97, 113, 125, 113, 71,
+  83, 103, 130, 54, 123, 112, 90, 134, 83, 169,
+  125, 101, 57, 86, 128, 117, 86, 112, 71, 119,
+  93, 91, 88, 78, 96, 99, 106, 65, 157, 117,
+  112, 128, 160, 111, 164, 157, 120, 109, 147, 115,
+  136, 113, 132, 120, 130, 108, 124, 97, 90, 94,
+  132, 62, 127, 65, 38, 176, 109, 110, 127, 89,
+  121, 86, 88, 82, 126, 154, 108, 126, 104, 54,
+  108, 100, 134, 124, 112, 132, 97, 164, 117, 142,
+  128, 74, 103, 136, 135, 123, 115, 94, 93, 111,
+  105, 126, 107, 68, 123, 127, 125, 106, 111, 134,
+  95, 110, 99, 181, 140, 61, 108, 123, 107, 119,
+  144, 97, 118, 110, 101, 109, 119, 110, 97, 116,
+  110, 130, 94, 121, 133, 100, 121, 122, 123, 150,
+  124, 164, 108, 118, 125, 94, 128, 137, 148, 136,
+  151, 110, 74, 92, 145, 109, 100, 79, 125, 102,
+  123, 114, 89, 98, 83, 76, 126, 95, 146, 80,
+  164, 147, 84, 54, 155, 136, 138, 127, 108, 99,
+  118, 110, 107, 92, 84, 107, 127, 58, 110, 112,
+  150, 141, 113, 153, 69, 161, 111, 97, 132, 91,
+  104, 83, 110, 140, 91, 54, 117, 106, 94, 135,
+  93, 102, 117, 68, 92, 85, 98, 127, 102, 94,
+  79, 131, 75, 89, 62, 109, 107, 112, 113, 89,
+  213, 120, 106, 122, 71, 107, 130, 125, 98, 96,
+  131, 132, 117, 115, 104, 102, 117, 96, 123, 88,
+  88, 83, 137, 99, 115, 112, 63, 134, 175, 130,
+  109, 89, 95, 92, 78, 80, 98, 163, 105, 121,
+  132, 138, 120, 100, 129, 92, 124, 106, 88, 130,
+  92, 112, 137, 109, 90, 144, 161, 90, 131, 139,
+  94, 115, 107, 87, 102, 117, 107, 106, 127, 115,
+  111, 162, 85, 119, 97, 149, 116, 146, 179, 131,
+  153, 147, 126, 74, 124, 94, 121, 90, 155, 119,
+  98, 120, 85, 166, 108, 126, 126, 78, 100, 111,
+  119, 126, 122, 120, 91, 110, 122, 87, 124, 158,
+  122, 142, 148, 75, 78, 99, 120, 104, 106, 88,
+  114, 98, 117, 108, 123, 151, 91, 120, 118, 123,
+  125, 119, 93, 132, 99, 120, 174, 126, 115, 113,
+  108, 101, 104, 112, 121, 111, 95, 97, 114, 86,
+  95, 121, 101, 108, 115, 119, 67, 118, 95, 105,
+  121, 121, 121, 89, 126, 105, 88, 86, 113, 105,
+  84, 110, 112, 102, 105, 118, 102, 88, 87, 108,
+  129, 175, 80, 122, 90, 93, 120, 133, 103, 89,
+  96, 93, 138, 123, 145, 108, 88, 155, 99, 100,
+  94, 117, 93, 112, 93, 153, 108, 104, 121, 132,
+  111, 152, 118, 127, 120, 127, 126, 90, 74, 105,
+  164, 100, 105, 100, 123, 68, 136, 98, 103, 136,
+  91, 95, 144, 114, 114, 121, 115, 104, 89, 98,
+  97, 116, 145, 122, 92, 115, 101, 145, 107, 101,
+  135, 135, 106, 126, 106, 107, 115, 124, 113, 106,
+  103, 126, 118, 99, 128, 119, 117, 103, 121, 132,
+  149, 149, 92, 132, 113, 79, 96, 104, 83, 102,
+  128, 135, 97, 122, 116, 117, 109, 108, 97, 119,
+  101, 132, 112, 100, 131, 81, 117, 145, 135, 98,
+  106, 146, 122, 138, 131, 98, 98, 93, 99, 113,
+  124, 146, 111, 126, 99, 137, 112, 127, 90, 103,
+  105, 124, 108, 137, 91, 105, 92, 135, 132, 80,
+  114, 133, 125, 150, 110, 97, 112, 133, 162, 101,
+  99, 127, 103, 104, 58, 128, 118, 131, 84, 73,
+  107, 95, 99, 104, 103, 121, 145, 87, 100, 106,
+  119, 111, 94, 105, 123, 94, 113, 108, 83, 134,
+  95, 91, 126, 158, 86, 105, 115, 135, 130, 101,
+  125, 88, 81, 129, 104, 105, 176, 105, 128, 139,
+  98, 105, 111, 164, 99, 95, 88, 156, 110, 124,
+  101, 120, 112, 146, 106, 119, 135, 130, 113, 68,
+  55, 110, 57, 90, 134, 102, 123, 112, 120, 77,
+  115, 122, 66, 114, 159, 80, 112, 99, 109, 108,
+  84, 70, 92, 167, 85, 129, 107, 197, 77, 121,
+  82, 124, 136, 127, 86, 116, 99, 117, 107, 111,
+  120, 109, 107, 109, 99, 90, 103, 104, 126, 92,
+  133, 91, 95, 155, 75, 95, 92, 95, 103, 107,
+  84, 118, 117, 153, 94, 108, 111, 103, 97, 82,
+  109, 130, 122, 127, 102, 92, 163, 113, 151, 134,
+  170, 96, 100, 102, 86, 172, 137, 103, 93, 94,
+  93, 112, 113, 152, 104, 114, 109, 157, 87, 110,
+  77, 110, 80, 110, 95, 113, 157, 82, 105, 115,
+  133, 73, 136, 121, 118, 173, 98, 105, 121, 138,
+  149, 94, 116, 135, 110, 105, 109, 157, 116, 141,
+  82, 67, 117, 74, 71, 94, 132, 117, 122, 86,
+  115, 129, 122, 121, 81, 81, 116, 139, 87, 147,
+  104, 120, 76, 104, 100, 101, 87, 108, 106, 119,
+  124, 88, 141, 88, 87, 136, 83, 113, 164, 97,
+  133, 118, 100, 114, 131, 125, 105, 103, 86, 131,
+  108, 139, 111, 127, 110, 114, 118, 88, 109, 83,
+  114, 101, 55, 112, 36, 110, 156, 97, 108, 103,
+  98, 66, 99, 110, 60, 136, 126, 84, 91, 104,
+  110, 124, 82, 129, 78, 193, 89, 132, 116, 135,
+  69, 65, 79, 128, 111, 88, 81, 95, 85, 98,
+  117, 91, 107, 86, 103, 108, 116, 108, 100, 89,
+  114, 90, 132, 70, 82, 126, 80, 95, 98, 92,
+  134, 70, 116, 124, 102, 157, 98, 93, 91, 109,
+  100, 83, 112, 109, 111, 109, 114, 79, 159, 137,
+  161, 122, 160, 101, 107, 170, 75, 110, 115, 113,
+  84, 93, 91, 105, 104, 133, 102, 93, 114, 154,
+  109, 71, 58, 101, 81, 103, 111, 85, 173, 80,
+  98, 85, 121, 155, 110, 111, 82, 174, 111, 98,
+  124, 153, 126, 93, 123, 139, 106, 105, 61, 110,
+  100, 137, 96, 88, 133, 84, 64, 102, 102, 107,
+  81, 105, 102, 118, 130, 132, 86, 71, 91, 125,
+  68, 87, 132, 94, 85, 94, 105, 84, 86, 130,
+  112, 100, 102, 68, 98, 93, 87, 127, 77, 107,
+  163, 68, 78, 103, 86, 97, 119, 139, 84, 82,
+  78, 89, 71, 76, 81, 81, 111, 105, 119, 86,
+  93, 121, 114, 137, 34, 68, 30, 100, 147, 82,
+  126, 83, 120, 52, 87, 107, 66, 107, 110, 113,
+  68, 94, 101, 64, 94, 65, 60, 157, 84, 96,
+  90, 114, 62, 85, 85, 99, 89, 83, 80, 108,
+  104, 52, 118, 116, 80, 72, 84, 96, 96, 76,
+  67, 88, 62, 76, 97, 150, 88, 107, 57, 111,
+  85, 78, 126, 77, 76, 71, 96, 131, 59, 89,
+  104, 97, 92, 79, 108, 100, 122, 94, 86, 58,
+  116, 100, 107, 101, 138, 69, 72, 140, 85, 118,
+  121, 76, 61, 107, 63, 96, 105, 117, 85, 89,
+  109, 122, 112, 87, 46, 93, 80, 104, 64, 103,
+  81, 98, 103, 104, 120, 142, 84, 104, 94, 160,
+  73, 86, 103, 129, 103, 77, 101, 109, 88, 94,
+  30, 91, 78, 85, 50, 67, 98, 72, 39, 121,
+  62, 95, 83, 71, 109, 108, 119, 95, 92, 66,
+  80, 133, 87, 107, 96, 73, 87, 88, 150, 80,
+  80, 136, 82, 86, 83, 58, 57, 70, 93, 108,
+  67, 84, 178, 89, 125, 86, 145, 121, 128, 151,
+  86, 86, 88, 102, 85, 90, 117, 72, 104, 100,
+  131, 111, 96, 105, 111, 79, 40, 93, 66, 107,
+  165, 97, 134, 91, 119, 95, 109, 85, 95, 75,
+  80, 92, 109, 113, 130, 47, 115, 69, 54, 148,
+  96, 89, 93, 143, 69, 83, 84, 97, 110, 90,
+  108, 99, 95, 72, 125, 105, 132, 111, 82, 116,
+  99, 82, 100, 79, 81, 102, 118, 99, 107, 107,
+  104, 97, 92, 84, 89, 91, 62, 88, 97, 145,
+  74, 93, 122, 65, 105, 86, 72, 123, 117, 107,
+  103, 101, 143, 123, 133, 126, 115, 89, 99, 54,
+  104, 113, 115, 75, 75, 111, 74, 84, 101, 115,
+  132, 95, 100, 126, 117, 75, 77, 88, 99, 97,
+  112, 90, 125, 110, 88, 71, 114, 89, 132, 108,
+  106, 145, 90, 120, 108, 116, 88, 96, 108, 94,
+  104, 105, 109, 121, 109, 130, 52, 136, 129, 79,
+  55, 86, 68, 58, 79, 101, 92, 105, 120, 94,
+  117, 107, 95, 106, 85, 101, 114, 76, 90, 85,
+  119, 80, 79, 156, 84, 73, 76, 68, 75, 72,
+  115, 126, 80, 83, 162, 88, 84, 97, 142, 133,
+  137, 132, 118, 105, 91, 108, 93, 99, 112, 77,
+  107, 112, 112, 95, 91, 84, 104, 89, 43, 123,
+  68, 131, 154, 103, 116, 92, 112, 96, 79, 72,
+  93, 79, 80, 93, 102, 120, 139, 63, 137, 82,
+  56, 146, 115, 107, 86, 123, 61, 83, 79, 82,
+  109, 90, 120, 105, 88, 68, 150, 100, 171, 131,
+  100, 122, 104, 78, 89, 59, 107, 120, 135, 76,
+  111, 104, 142, 108, 87, 94, 57, 80, 74, 121,
+  89, 167, 94, 84, 98, 93, 106, 91, 82, 107,
+  75, 121, 101, 125, 172, 115, 131, 134, 121, 83,
+  113, 104, 110, 109, 115, 93, 73, 113, 82, 69,
+  89, 105, 143, 87, 123, 117, 131, 88, 100, 107,
+  107, 89, 105, 117, 134, 90, 84, 65, 105, 89,
+  133, 101, 114, 112, 103, 113, 117, 115, 103, 104,
+  106, 82, 99, 80, 129, 122, 128, 147, 57, 125,
+  124, 77, 55, 61, 79, 72, 89, 98, 81, 93,
+  109, 97, 112, 99, 115, 87, 64, 85, 117, 98,
+  84, 75, 115, 87, 77, 122, 87, 83, 86, 93,
+  89, 72, 121, 148, 115, 114, 125, 83, 85, 104,
+  118, 113, 151, 100, 121, 118, 89, 96, 87, 124,
+  101, 95, 113, 118, 94, 74, 82, 88, 93, 92,
+  54, 126, 75, 127, 122, 105, 92, 84, 75, 81,
+  60, 78, 73, 88, 84, 110, 91, 116, 126, 71,
+  120, 92, 65, 129, 120, 118, 76, 126, 58, 95,
+  75, 77, 121, 83, 121, 112, 83, 79, 129, 106,
+  121, 117, 92, 111, 104, 100, 78, 42, 129, 129,
+  137, 85, 113, 108, 163, 121, 92, 100, 67, 84,
+  85, 132, 92, 159, 90, 104, 88, 133, 95, 90,
+  82, 79, 67, 107, 104, 129, 144, 95, 107, 124,
+  126, 109, 112, 135, 140, 121, 106, 80, 86, 117,
+  102, 75, 87, 97, 134, 79, 119, 93, 152, 73,
+  89, 92, 128, 94, 92, 88, 127, 77, 94, 86,
+  107, 94, 124, 92, 93, 79, 117, 112, 105, 128,
+  110, 103, 102, 87, 98, 95, 102, 129, 110, 134,
+  66, 97, 108, 81, 72, 66, 126, 68, 78, 100,
+  93, 109, 82, 117, 77, 87, 118, 103, 62, 88,
+  100, 100, 81, 89, 111, 126, 83, 87, 91, 82,
+  83, 126, 88, 76, 98, 142, 114, 118, 101, 79,
+  132, 103, 107, 94, 127, 102, 113, 127, 98, 90,
+  92, 122, 123, 95, 97, 124, 104, 68, 85, 83,
+  115, 90, 58, 126, 76, 109, 97, 98, 102, 87,
+  81, 81, 57, 93, 78, 104, 126, 136, 85, 107,
+  123, 60, 96, 103, 87, 105, 125, 130, 71, 122,
+  74, 134, 77, 89, 130, 102, 119, 133, 88, 103,
+  98, 108, 88, 96, 82, 148, 98, 108, 87, 56,
+  155, 119, 137, 118, 90, 100, 123, 118, 101, 104,
+  102, 111, 85, 86, 97, 128, 92, 118, 76, 133,
+  75, 106, 66, 96, 88, 94, 111, 146, 104, 111,
+  89, 140, 117, 118, 110, 111, 165, 133, 118, 84,
+  103, 115, 102, 102, 101, 97, 120, 90, 106, 86,
+  141, 80, 91, 87, 135, 112, 94, 68, 115, 92,
+  141, 107, 118, 123, 122, 102, 92, 69, 129, 127,
+  100, 132, 117, 100, 80, 82, 105, 101, 89, 110,
+  89, 131, 130, 76, 86, 96, 92, 95, 126, 81,
+  82, 87, 110, 120, 92, 143, 67, 93, 99, 119,
+  80, 100, 64, 106, 95, 100, 116, 158, 92, 69,
+  109, 84, 87, 133, 85, 81, 89, 136, 116, 129,
+  113, 96, 81, 108, 119, 97, 94, 135, 117, 108,
+  98, 96, 126, 108, 132, 95, 83, 112, 129, 93,
+  105, 71, 104, 92, 65, 115, 88, 93, 103, 105,
+  147, 103, 103, 93, 75, 103, 95, 107, 133, 117,
+  90, 109, 131, 68, 106, 99, 120, 90, 110, 130,
+  104, 112, 75, 164, 74, 128, 109, 113, 120, 111,
+  116, 122, 99, 101, 96, 112, 103, 138, 90, 90,
+  93, 94, 155, 115, 127, 126, 84, 116, 67, 95,
+  103, 113, 82, 103, 83, 70, 81, 113, 91, 92,
+  88, 96, 78, 127, 55, 116, 117, 91, 127, 151,
+  103, 86, 99, 137, 113, 99, 121, 71, 127, 131,
+  120, 104, 75, 124, 105, 104, 98, 100, 104, 116,
+  105, 79, 100, 107, 112, 82, 106, 110, 100, 79,
+  87, 125, 135, 102, 107, 132, 120, 104, 102, 58,
+  106, 125, 93, 108, 118, 103, 84, 72, 113, 111,
+  115, 98, 91, 121, 97, 85, 73, 103, 99, 119,
+  63, 96, 98, 81, 100, 114, 130, 91, 93, 120,
+  83, 104, 86, 101, 61, 126, 92, 99, 102, 135,
+  84, 69, 100, 102, 91, 87, 90, 77, 87, 132,
+  116, 129, 125, 115, 90, 120, 141, 129, 97, 127,
+  134, 102, 97, 111, 142, 106, 144, 116, 84, 96,
+  143, 118, 108, 74, 109, 85, 57, 142, 82, 99,
+  125, 101, 167, 111, 114, 106, 93, 94, 109, 111,
+  108, 94, 90, 123, 140, 72, 135, 107, 120, 104,
+  107, 138, 125, 122, 77, 135, 87, 142, 95, 111,
+  103, 108, 130, 129, 102, 92, 123, 121, 121, 124,
+  86, 89, 85, 117, 161, 130, 123, 95, 92, 108,
+  78, 81, 115, 135, 45, 103, 95, 109, 70, 125,
+  90, 74, 121, 88, 100, 131, 78, 119, 123, 103,
+  127, 156, 134, 88, 124, 133, 128, 93, 149, 68,
+  119, 112, 119, 113, 79, 132, 112, 99, 85, 94,
+  103, 123, 115, 115, 100, 101, 119, 82, 91, 102,
+  115, 98, 93, 137, 92, 95, 95, 84, 122, 92,
+  111, 66, 91, 127, 95, 97, 107, 125, 113, 63,
+  133, 115, 142, 130, 108, 143, 65, 105, 94, 93,
+  100, 111, 75, 103, 110, 95, 99, 112, 140, 98,
+  113, 130, 93, 98, 65, 88, 100, 124, 78, 102,
+  105, 112, 82, 91, 88, 102, 85, 73, 93, 87,
+  97, 134, 112, 136, 123, 112, 106, 127, 149, 155,
+  113, 119, 138, 103, 107, 121, 139, 116, 130, 132,
+  99, 91, 150, 124, 107, 82, 115, 91, 59, 143,
+  80, 121, 137, 89, 150, 82, 116, 100, 104, 88,
+  112, 115, 90, 87, 99, 126, 143, 63, 162, 122,
+  101, 123, 109, 133, 119, 114, 70, 100, 98, 125,
+  110, 111, 88, 117, 112, 111, 89, 102, 145, 119,
+  126, 123, 80, 81, 66, 110, 142, 139, 113, 89,
+  100, 111, 110, 97, 114, 137, 58, 108, 114, 112,
+  78, 141, 89, 83, 116, 109, 101, 126, 82, 127,
+  100, 106, 132, 143, 159, 93, 137, 128, 127, 86,
+  158, 97, 120, 121, 121, 103, 100, 144, 116, 89,
+  72, 99, 116, 110, 122, 144, 116, 105, 108, 92,
+  105, 106, 123, 118, 100, 134, 69, 75, 109, 96,
+  121, 92, 116, 83, 74, 133, 112, 110, 108, 125,
+  123, 63, 147, 118, 147, 147, 124, 158, 56, 116,
+  113, 90, 100, 112, 92, 112, 107, 108, 87, 102,
+  146, 87, 110, 120, 107, 98, 64, 79, 122, 115,
+  70, 114, 109, 100, 77, 107, 90, 107, 85, 84,
+  94, 96, 106, 128, 108, 132, 124, 112, 96, 121,
+  134, 159, 128, 108, 131, 88, 108, 116, 124, 127,
+  115, 131, 121, 96, 131, 118, 90, 72, 111, 89,
+  52, 129, 72, 136, 131, 78, 132, 69, 111, 86,
+  116, 84, 103, 115, 77, 95, 94, 118, 139, 59,
+  174, 123, 90, 137, 106, 127, 106, 121, 57, 78,
+  100, 122, 115, 130, 80, 118, 93, 98, 94, 105,
+  133, 119, 126, 108, 71, 88, 43, 97, 117, 126,
+  108, 96, 114, 120, 122, 95, 103, 122, 51, 97,
+  115, 108, 77, 160, 88, 91, 96, 128, 90, 111,
+  66, 109, 100, 102, 136, 116, 162, 99, 135, 120,
+  119, 85, 158, 111, 132, 139, 117, 78, 90, 138,
+  115, 82, 69, 97, 115, 86, 128, 153, 130, 110,
+  88, 88, 105, 102, 118, 110, 102, 109, 68, 79,
+  113, 108, 116, 88, 115, 86, 77, 132, 120, 123,
+  107, 117, 117, 79, 143, 114, 154, 133, 123, 150,
+  34, 106, 108, 80, 98, 131, 92, 122, 98, 124,
+  81, 99, 130, 89, 99, 100, 122, 105, 76, 77,
+  123, 108, 73, 126, 111, 105, 80, 124, 79, 113,
+  87, 112, 81, 98, 112, 120, 87, 131, 110, 116,
+  94, 117, 132, 142, 118, 79, 119, 87, 109, 121,
+  113, 134, 117, 142, 122, 115, 121, 120, 84, 62,
+  107, 89, 40, 131, 75, 124, 105, 77, 116, 61,
+  110, 76, 107, 82, 99, 111, 76, 103, 99, 100,
+  119, 64, 169, 136, 96, 134, 96, 118, 93, 150,
+  61, 85, 100, 123, 104, 130, 65, 128, 99, 98,
+  106, 104, 114, 105, 129, 132, 76, 110, 48, 99,
+  116, 109, 110, 108, 113, 110, 116, 80, 97, 120,
+  48, 104, 118, 123, 83, 162, 94, 93, 90, 134,
+  84, 90, 62, 95, 107, 98, 137, 99, 135, 99,
+  108, 147, 111, 92, 147, 104, 171, 144, 110, 73,
+  92, 120, 120, 92, 74, 86, 96, 68, 126, 144,
+  127, 110, 72, 78, 98, 99, 118, 79, 98, 98,
+  91, 106, 114, 87, 106, 84, 115, 68, 101, 138,
+  114, 112, 102, 114, 107, 113, 132, 108, 139, 143,
+  112, 148, 44, 93, 93, 81, 105, 144, 108, 116,
+  90, 121, 89, 98, 119, 105, 96, 67, 113, 125,
+  76, 78, 128, 106, 78, 133, 102, 135, 78, 128,
+  79, 102, 82, 136, 80, 94, 112, 113, 71, 133,
+  107, 118, 115, 107, 131, 139, 86, 72, 105, 87,
+  112, 115, 128, 152, 125, 156, 102, 130, 110, 111,
+  90, 50, 122, 89, 32, 160, 91, 117, 83, 74,
+  117, 90, 113, 82, 99, 75, 101, 108, 96, 85,
+  96, 80, 104, 80, 144, 139, 96, 115, 93, 113,
+  106, 138, 74, 101, 106, 152, 104, 119, 92, 157,
+  108, 114, 107, 107, 95, 98, 135, 174, 94, 138,
+  57, 92, 124, 112, 112, 115, 104, 110, 121, 67,
+  106, 115, 64, 114, 143, 98, 89, 155, 101, 88,
+  93, 128, 85, 80, 73, 121, 94, 96, 152, 111,
+  93, 104, 97, 164, 90, 91, 125, 103, 189, 134,
+  114, 101, 123, 107, 125, 111, 90, 91, 89, 74,
+  127, 131, 120, 122, 59, 84, 85, 112, 131, 61,
+  90, 84, 85, 100, 97, 72, 77, 96, 104, 52,
+  103, 133, 101, 106, 102, 116, 98, 148, 119, 109,
+  115, 144, 97, 147, 75, 99, 77, 88, 126, 132,
+  109, 88, 89, 102, 99, 90, 122, 132, 88, 44,
+  87, 121, 62, 71, 114, 97, 87, 143, 97, 151,
+  85, 127, 94, 87, 76, 130, 86, 96, 102, 110,
+  71, 125, 112, 126, 98, 99, 113, 138, 55, 81,
+  74, 63, 100, 94, 147, 164, 109, 155, 97, 113,
+  69, 93, 107, 48, 100, 85, 27, 147, 104, 112,
+  65, 71, 137, 108, 79, 93, 112, 84, 97, 111,
+  112, 63, 87, 68, 95, 113, 102, 137, 113, 102,
+  86, 116, 133, 102, 62, 88, 95, 194, 106, 114,
+  127, 148, 109, 129, 92, 106, 71, 120, 144, 146,
+  115, 147, 76, 87, 109, 107, 108, 96, 89, 131,
+  112, 65, 116, 109, 89, 113, 160, 83, 96, 139,
+  99, 66, 89, 106, 101, 89, 96, 150, 88, 97,
+  161, 97, 78, 95, 110, 137, 77, 86, 99, 96,
+  126, 107, 110, 132, 105, 103, 119, 119, 96, 113,
+  70, 94, 110, 115, 111, 153, 32, 100, 65, 129,
+  151, 94, 89, 72, 71, 89, 84, 84, 49, 103,
+  81, 43, 75, 112, 111, 104, 103, 115, 87, 163,
+  98, 108, 92, 108, 71, 114, 73, 122, 71, 86,
+  137, 108, 99, 73, 89, 87, 98, 97, 113, 103,
+  82, 63, 73, 115, 42, 54, 92, 81, 93, 140,
+  86, 131, 84, 134, 99, 72, 82, 107, 101, 80,
+  88, 100, 53, 122, 122, 119, 102, 92, 80, 112,
+  35, 89, 41, 44, 106, 72, 177, 147, 104, 149,
+  107, 105, 45, 73, 103, 74, 73, 119, 18, 105,
+  110, 80, 63, 47, 116, 73, 79, 86, 110, 99,
+  88, 106, 124, 80, 76, 52, 91, 110, 77, 126,
+  107, 102, 73, 119, 116, 80, 69, 47, 92, 187,
+  102, 100, 120, 113, 102, 109, 72, 102, 46, 114,
+  142, 102, 136, 153, 89, 71, 76, 98, 92, 77,
+  74, 116, 80, 76, 124, 94, 129, 108, 161, 100,
+  102, 110, 73, 70, 83, 98, 124, 89, 122, 141,
+  109, 79, 139, 71, 77, 115, 106, 109, 65, 74,
+  70, 129, 86, 120, 105, 140, 96, 91, 90, 116,
+  99, 112, 63, 105, 92, 98, 110, 149, 20, 116,
+  68, 132, 146, 132, 114, 62, 67, 67, 92, 124,
+  51, 87, 73, 61, 56, 99, 118, 104, 110, 106,
+  59, 155, 80, 105, 53, 73, 50, 93, 84, 133,
+  51, 90, 115, 83, 104, 84, 73, 88, 104, 109,
+  114, 108, 75, 89, 98, 99, 57, 51, 88, 92,
+  109, 126, 66, 106, 68, 133, 107, 53, 92, 97,
+  79, 50, 83, 72, 28, 105, 130, 102, 96, 70,
+  57, 80, 29, 105, 28, 72, 105, 76, 156, 95,
+  103, 128, 127, 114, 44, 77, 81, 109, 71, 177,
+  5, 56, 95, 44, 89, 34, 80, 63, 123, 86,
+  97, 109, 77, 67, 118, 92, 75, 43, 92, 99,
+  66, 83, 87, 109, 72, 102, 62, 75, 81, 22,
+  90, 113, 83, 83, 94, 93, 105, 60, 73, 96,
+  37, 84, 103, 90, 147, 154, 94, 66, 71, 101,
+  85, 107, 78, 76, 66, 101, 101, 87, 124, 112,
+  101, 98, 93, 103, 40, 100, 110, 92, 135, 65,
+  122, 121, 122, 71, 107, 41, 92, 90, 95, 99,
+  51, 41, 56, 153, 92, 126, 108, 102, 81, 84,
+  55, 100, 110, 98, 83, 108, 98, 87, 120, 125,
+  11, 114, 87, 106, 103, 140, 119, 54, 57, 71,
+  99, 124, 65, 73, 93, 94, 43, 110, 118, 116,
+  107, 92, 27, 148, 61, 101, 37, 91, 39, 91,
+  74, 102, 63, 95, 63, 77, 97, 95, 55, 80,
+  82, 121, 127, 112, 68, 90, 131, 81, 83, 62,
+  91, 96, 116, 113, 84, 90, 67, 116, 86, 62,
+  100, 106, 62, 42, 95, 53, 32, 66, 149, 92,
+  79, 71, 65, 93, 69, 128, 61, 109, 80, 105,
+  77, 84, 74, 83, 148, 108, 53, 75, 85, 154,
+  86, 107, 22, 52, 63, 67, 139, 73, 84, 62,
+  108, 83, 78, 115, 67, 43, 88, 72, 102, 61,
+  110, 89, 59, 51, 85, 138, 80, 95, 48, 132,
+  73, 46, 87, 69, 104, 111, 92, 89, 84, 43,
+  92, 118, 74, 88, 61, 89, 116, 123, 90, 69,
+  81, 112, 105, 100, 98, 97, 60, 111, 82, 89,
+  87, 120, 44, 102, 85, 138, 32, 143, 110, 86,
+  110, 44, 98, 111, 125, 95, 76, 44, 130, 70,
+  121, 101, 81, 29, 64, 82, 89, 88, 108, 69,
+  40, 98, 57, 83, 120, 108, 148, 92, 115, 114,
+  139, 95, 29, 93, 87, 97, 79, 125, 128, 59,
+  72, 97, 117, 66, 70, 92, 104, 131, 52, 106,
+  116, 147, 104, 74, 52, 149, 65, 98, 73, 110,
+  54, 92, 62, 81, 104, 76, 47, 80, 111, 87,
+  68, 87, 63, 129, 103, 78, 70, 82, 129, 91,
+  90, 100, 87, 76, 91, 93, 116, 94, 76, 115,
+  72, 70, 99, 85, 98, 62, 115, 69, 43, 69,
+  154, 82, 136, 86, 90, 126, 109, 113, 97, 133,
+  85, 147, 102, 132, 76, 81, 112, 96, 75, 103,
+  103, 105, 101, 66, 48, 94, 58, 107, 206, 90,
+  97, 82, 79, 69, 90, 104, 68, 97, 76, 66,
+  123, 96, 131, 92, 62, 91, 87, 188, 76, 120,
+  92, 155, 50, 62, 69, 91, 133, 107, 91, 111,
+  85, 71, 104, 132, 125, 93, 90, 116, 111, 94,
+  98, 73, 127, 107, 135, 64, 84, 116, 95, 100,
+  81, 85, 105, 117, 57, 118, 96, 164, 59, 130,
+  66, 104, 77, 57, 67, 105, 110, 102, 71, 72,
+  170, 137, 178, 126, 132, 93, 94, 86, 84, 100,
+  109, 109, 64, 109, 77, 92, 111, 114, 199, 83,
+  115, 172, 128, 72, 64, 120, 78, 123, 96, 79,
+  201, 72, 114, 81, 122, 102, 93, 109, 101, 186,
+  144, 106, 125, 191, 122, 86, 100, 157, 105, 94,
+  119, 112, 78, 125, 116, 91, 162, 80, 66, 80,
+  132, 118, 88, 112, 96, 129, 86, 124, 85, 63,
+  124, 88, 94, 117, 108, 105, 86, 65, 100, 95,
+  87, 108, 100, 81, 96, 76, 160, 104, 119, 122,
+  70, 103, 136, 79, 123, 115, 77, 115, 122, 105,
+  98, 141, 89, 149, 135, 127, 116, 100, 97, 107,
+  95, 136, 120, 66, 97, 90, 52, 106, 95, 119,
+  196, 94, 116, 132, 90, 62, 88, 118, 77, 130,
+  101, 83, 96, 111, 129, 87, 67, 126, 91, 171,
+  89, 128, 102, 90, 75, 53, 60, 108, 95, 83,
+  86, 152, 96, 78, 104, 108, 124, 71, 95, 125,
+  109, 71, 96, 108, 143, 100, 148, 92, 39, 133,
+  143, 152, 91, 74, 88, 101, 92, 120, 102, 140,
+  58, 94, 66, 109, 100, 62, 78, 91, 90, 136,
+  71, 73, 165, 92, 164, 137, 150, 134, 96, 169,
+  83, 166, 120, 109, 73, 121, 92, 94, 105, 154,
+  181, 80, 114, 157, 126, 101, 73, 161, 92, 132,
+  84, 87, 152, 86, 135, 71, 103, 153, 86, 130,
+  77, 190, 158, 81, 142, 192, 145, 86, 104, 163,
+  113, 93, 98, 99, 90, 135, 78, 80, 167, 93,
+  56, 114, 105, 154, 120, 122, 115, 124, 125, 119,
+  81, 48, 115, 85, 120, 84, 97, 147, 88, 51,
+  144, 86, 98, 89, 136, 107, 104, 64, 177, 103,
+  92, 134, 107, 115, 145, 75, 115, 115, 59, 89,
+  131, 151, 83, 81, 85, 133, 121, 104, 122, 88,
+  108, 116, 95, 123, 80, 119, 92, 99, 39, 111,
+  103, 109, 169, 94, 102, 155, 130, 67, 75, 121,
+  75, 99, 143, 115, 93, 99, 116, 87, 69, 98,
+  80, 138, 99, 120, 60, 136, 103, 56, 81, 92,
+  100, 97, 106, 169, 72, 55, 83, 101, 105, 45,
+  84, 116, 108, 78, 98, 96, 133, 104, 139, 107,
+  44, 132, 101, 173, 93, 70, 96, 126, 98, 97,
+  111, 130, 45, 98, 96, 111, 147, 42, 96, 125,
+  79, 128, 72, 52, 142, 88, 112, 124, 155, 97,
+  78, 147, 89, 142, 131, 97, 111, 117, 83, 83,
+  123, 148, 186, 94, 97, 125, 142, 96, 86, 153,
+  111, 99, 64, 142, 118, 92, 112, 54, 99, 111,
+  82, 121, 85, 176, 85, 63, 118, 175, 136, 84,
+  86, 142, 80, 88, 76, 125, 87, 130, 94, 71,
+  142, 86, 42, 108, 92, 137, 121, 120, 119, 120,
+  139, 132, 71, 50, 127, 106, 139, 104, 77, 163,
+  94, 57, 163, 71, 102, 79, 133, 101, 103, 78,
+  149, 88, 77, 118, 109, 85, 157, 72, 98, 97,
+  72, 102, 156, 136, 93, 73, 79, 120, 75, 139,
+  113, 97, 137, 91, 63, 90, 63, 105, 90, 108,
+  34, 108, 102, 122, 165, 93, 78, 97, 106, 97,
+  64, 101, 76, 85, 112, 107, 117, 85, 107, 112,
+  56, 94, 57, 122, 82, 95, 34, 149, 79, 64,
+  63, 69, 99, 76, 154, 121, 70, 40, 99, 95,
+  134, 109, 95, 109, 114, 109, 129, 49, 127, 118,
+  126, 93, 96, 110, 97, 136, 71, 82, 65, 121,
+  83, 113, 100, 150, 36, 137, 101, 117, 138, 37,
+  78, 131, 81, 81, 87, 62, 158, 98, 109, 115,
+  146, 74, 68, 118, 105, 91, 108, 77, 90, 105,
+  82, 89, 137, 102, 194, 79, 105, 91, 147, 70,
+  65, 99, 118, 76, 84, 84, 152, 62, 87, 90,
+  106, 92, 75, 84, 82, 150, 95, 89, 97, 187,
+  102, 96, 101, 150, 66, 90, 77, 135, 85, 126,
+  79, 100, 161, 63, 49, 92, 74, 65, 91, 94,
+  69, 143, 94, 115, 77, 51, 106, 98, 126, 84,
+  91, 115, 88, 60, 102, 99, 104, 108, 100, 91,
+  99, 103, 111, 74, 90, 106, 89, 74, 140, 69,
+  112, 62, 61, 111, 149, 82, 109, 128, 63, 104,
+  51, 147, 103, 90, 119, 100, 50, 73, 46, 62,
+  83, 88, 34, 102, 103, 94, 138, 91, 72, 88,
+  57, 110, 57, 92, 87, 104, 104, 113, 87, 74,
+  100, 115, 57, 70, 54, 109, 79, 83, 30, 107,
+  57, 77, 59, 78, 94, 120, 176, 122, 87, 61,
+  116, 113, 110, 121, 96, 119, 118, 109, 117, 55,
+  113, 101, 116, 103, 106, 82, 96, 102, 75, 93,
+  79, 93, 64, 114, 115, 130, 30, 133, 87, 99,
+  93, 38, 81, 100, 107, 63, 101, 80, 120, 93,
+  97, 116, 114, 83, 67, 111, 120, 88, 108, 93,
+  102, 91, 74, 115, 155, 79, 164, 67, 103, 76,
+  153, 59, 59, 92, 92, 89, 105, 77, 126, 48,
+  121, 150, 80, 94, 63, 63, 89, 117, 109, 84,
+  96, 185, 93, 88, 88, 164, 72, 94, 56, 93,
+  58, 94, 79, 99, 129, 58, 65, 90, 104, 26,
+  73, 81, 99, 113, 57, 142, 76, 46, 71, 118,
+  110, 87, 68, 78, 90, 73, 97, 155, 112, 122,
+  91, 90, 103, 118, 76, 84, 97, 91, 96, 121,
+  109, 82, 98, 95, 48, 111, 106, 87, 103, 122,
+  73, 102, 89, 122, 79, 77, 92, 146, 68, 76,
+  81, 50, 95, 81, 38, 109, 124, 51, 82, 82,
+  89, 120, 48, 106, 77, 125, 77, 117, 122, 128,
+  83, 81, 97, 112, 50, 70, 100, 122, 96, 101,
+  51, 94, 95, 136, 71, 107, 135, 147, 128, 108,
+  107, 102, 93, 105, 72, 92, 95, 122, 103, 82,
+  98, 97, 88, 108, 111, 117, 73, 87, 56, 82,
+  103, 92, 117, 107, 41, 85, 117, 99, 48, 113,
+  101, 87, 74, 81, 92, 99, 148, 73, 118, 97,
+  83, 87, 95, 122, 97, 99, 49, 97, 149, 95,
+  99, 126, 99, 85, 88, 159, 132, 79, 108, 97,
+  82, 83, 129, 78, 45, 83, 99, 133, 101, 98,
+  116, 72, 148, 163, 66, 93, 94, 94, 109, 108,
+  91, 89, 76, 142, 128, 93, 69, 141, 76, 107,
+  66, 102, 34, 71, 103, 96, 78, 92, 102, 124,
+  119, 63, 59, 84, 132, 90, 83, 136, 68, 73,
+  62, 168, 111, 131, 37, 91, 107, 94, 106, 173,
+  85, 101, 102, 92, 90, 121, 52, 92, 95, 76,
+  122, 142, 92, 106, 94, 135, 105, 120, 89, 104,
+  104, 75, 85, 87, 128, 109, 100, 76, 89, 142,
+  82, 85, 106, 53, 85, 93, 47, 117, 124, 44,
+  76, 73, 118, 93, 78, 86, 114, 137, 82, 109,
+  111, 100, 92, 86, 108, 111, 77, 99, 106, 150,
+  103, 123, 98, 95, 82, 170, 81, 135, 123, 103,
+  108, 104, 141, 141, 102, 95, 84, 104, 117, 94,
+  102, 75, 118, 112, 83, 123, 117, 94, 77, 100,
+  44, 72, 124, 85, 131, 130, 69, 100, 98, 89,
+  86, 91, 107, 76, 83, 119, 113, 104, 194, 82,
+  110, 127, 93, 105, 108, 111, 121, 110, 63, 74,
+  154, 86, 107, 169, 72, 83, 121, 160, 121, 85,
+  87, 104, 78, 96, 96, 93, 63, 59, 75, 125,
+  113, 78, 112, 117, 112, 132, 93, 92, 167, 109,
+  127, 84, 80, 107, 65, 100, 122, 104, 79, 84,
+  80, 100, 104, 121, 64, 81, 52, 130, 72, 96,
+  123, 126, 117, 78, 60, 89, 136, 72, 133, 112,
+  78, 120, 63, 159, 113, 106, 45, 79, 120, 116,
+  104, 126, 71, 107, 88, 93, 88, 80, 81, 100,
+  97, 73, 127, 129, 97, 126, 175, 114, 163, 160,
+  108, 120, 140, 85, 124, 101, 126, 119, 117, 95,
+  109, 112, 86, 87, 123, 72, 135, 70, 46, 160,
+  89, 93, 116, 88, 120, 68, 114, 76, 129, 148,
+  105, 115, 102, 58, 98, 100, 133, 122, 110, 124,
+  96, 172, 110, 139, 130, 88, 85, 135, 124, 123,
+  122, 91, 101, 114, 116, 146, 97, 83, 111, 112,
+  117, 105, 114, 112, 90, 98, 95, 158, 140, 65,
+  102, 117, 78, 102, 153, 101, 131, 120, 91, 108,
+  83, 96, 93, 102, 111, 123, 83, 133, 129, 118,
+  167, 112, 94, 142, 106, 168, 110, 116, 131, 81,
+  102, 111, 151, 120, 126, 127, 92, 88, 144, 130,
+  115, 79, 119, 104, 120, 117, 92, 85, 79, 68,
+  109, 88, 140, 81, 152, 140, 73, 58, 151, 132,
+  154, 119, 124, 88, 92, 114, 91, 94, 95, 102,
+  120, 56, 106, 110, 149, 128, 101, 127, 66, 165,
+  95, 94, 129, 105, 102, 82, 77, 132, 107, 63,
+  137, 114, 84, 136, 91, 105, 113, 83, 83, 65,
+  103, 127, 113, 85, 77, 132, 77, 87, 64, 99,
+  101, 117, 116, 73, 200, 127, 100, 139, 105, 100,
+  124, 149, 96, 104, 147, 123, 114, 114, 103, 109,
+  114, 122, 118, 78, 65, 84, 121, 48, 111, 80,
+  38, 143, 122, 129, 121, 82, 82, 75, 107, 79,
+  107, 147, 105, 99, 102, 95, 82, 87, 129, 117,
+  119, 136, 97, 169, 79, 116, 136, 90, 91, 138,
+  163, 100, 108, 123, 77, 95, 106, 101, 113, 105,
+  87, 97, 125, 90, 123, 166, 108, 109, 99, 161,
+  126, 89, 119, 145, 121, 102, 123, 101, 128, 92,
+  87, 81, 116, 109, 85, 116, 94, 178, 85, 113,
+  124, 69, 94, 106, 120, 110, 112, 140, 104, 93,
+  120, 59, 119, 149, 127, 115, 143, 79, 83, 98,
+  140, 125, 88, 49, 109, 93, 154, 115, 96, 130,
+  69, 75, 134, 112, 108, 80, 129, 127, 78, 91,
+  183, 162, 93, 107, 98, 94, 117, 115, 118, 112,
+  82, 103, 136, 90, 87, 111, 112, 108, 98, 112,
+  52, 106, 90, 101, 126, 97, 84, 107, 86, 117,
+  71, 70, 103, 100, 70, 90, 98, 73, 102, 71,
+  99, 88, 82, 133, 101, 146, 84, 126, 74, 81,
+  92, 136, 92, 101, 109, 63, 178, 113, 99, 118,
+  94, 100, 93, 122, 68, 103, 127, 121, 112, 116,
+  116, 119, 94, 81, 106, 85, 69, 84, 140, 86,
+  109, 107, 74, 126, 206, 117, 105, 82, 92, 103,
+  70, 92, 125, 146, 103, 93, 147, 144, 115, 89,
+  117, 68, 115, 103, 105, 134, 70, 110, 144, 127,
+  94, 149, 148, 113, 140, 129, 110, 102, 127, 87,
+  99, 149, 92, 103, 145, 106, 104, 180, 86, 115,
+  90, 122, 106, 174, 182, 120, 145, 109, 120, 63,
+  142, 85, 113, 80, 164, 122, 88, 121, 78, 154,
+  108, 113, 137, 58, 102, 92, 116, 108, 101, 101,
+  121, 94, 123, 97, 108, 128, 104, 143, 136, 102,
+  91, 97, 121, 119, 88, 65, 92, 97, 111, 137,
+  112, 175, 77, 118, 98, 136, 121, 101, 84, 104,
+  113, 132, 130, 110, 131, 89, 109, 112, 97, 129,
+  149, 137, 109, 94, 115, 131, 94, 119, 86, 114,
+  87, 79, 83, 96, 80, 118, 132, 138, 124, 121,
+  115, 93, 105, 85, 96, 146, 70, 70, 116, 106,
+  93, 126, 116, 114, 88, 122, 99, 203, 102, 112,
+  120, 88, 144, 128, 90, 100, 87, 71, 104, 118,
+  153, 106, 97, 143, 109, 121, 98, 125, 114, 90,
+  112, 135, 107, 99, 124, 140, 117, 143, 128, 120,
+  135, 127, 127, 104, 80, 96, 140, 90, 101, 107,
+  137, 76, 135, 108, 126, 154, 104, 79, 132, 103,
+  118, 103, 109, 95, 106, 82, 91, 117, 152, 105,
+  87, 121, 92, 140, 107, 117, 130, 146, 113, 112,
+  117, 98, 124, 121, 129, 132, 109, 120, 122, 107,
+  119, 119, 118, 115, 121, 131, 141, 133, 87, 117,
+  115, 80, 82, 106, 88, 112, 116, 129, 97, 116,
+  121, 106, 108, 107, 103, 120, 102, 120, 129, 110,
+  135, 91, 114, 135, 135, 105, 105, 119, 120, 115,
+  134, 115, 84, 94, 104, 91, 119, 138, 111, 122,
+  93, 115, 98, 118, 92, 115, 89, 109, 126, 130,
+  96, 126, 95, 137, 130, 76, 124, 124, 136, 147,
+  103, 107, 108, 108, 134, 106, 108, 101, 108, 95,
+  76, 109, 113, 124, 61, 81, 101, 93, 90, 102,
+  90, 104, 144, 80, 101, 101, 119, 94, 109, 123,
+  123, 96, 116, 112, 69, 123, 115, 106, 104, 126,
+  87, 124, 106, 119, 129, 84, 111, 83, 84, 111,
+  94, 102, 180, 107, 118, 130, 96, 116, 125, 160,
+  124, 113, 98, 138, 91, 120, 100, 110, 119, 132,
+  113, 106, 125, 140, 123, 73, 59, 92, 34, 95,
+  128, 99, 108, 99, 123, 71, 114, 130, 66, 104,
+  132, 70, 111, 92, 105, 122, 104, 59, 75, 174,
+  102, 111, 92, 167, 58, 105, 88, 124, 140, 144,
+  85, 104, 94, 109, 118, 114, 119, 117, 105, 96,
+  105, 98, 94, 98, 117, 104, 129, 88, 103, 139,
+  95, 87, 97, 97, 100, 97, 78, 126, 104, 154,
+  92, 105, 129, 107, 98, 85, 102, 122, 119, 114,
+  108, 100, 156, 131, 142, 125, 159, 84, 102, 108,
+  87, 135, 136, 92, 71, 96, 90, 92, 111, 123,
+  105, 101, 108, 151, 95, 86, 75, 117, 70, 109,
+  102, 132, 155, 85, 111, 120, 130, 65, 147, 107,
+  125, 175, 100, 93, 115, 125, 130, 99, 120, 120,
+  116, 95, 114, 148, 114, 135, 83, 65, 114, 71,
+  62, 84, 138, 110, 117, 87, 120, 99, 99, 118,
+  91, 86, 112, 113, 86, 148, 94, 108, 88, 113,
+  93, 83, 87, 124, 94, 110, 114, 86, 119, 89,
+  89, 112, 91, 116, 158, 98, 160, 119, 96, 109,
+  145, 123, 116, 114, 87, 133, 99, 138, 115, 122,
+  108, 117, 126, 86, 106, 71, 121, 94, 62, 105,
+  32, 118, 152, 99, 92, 108, 99, 63, 97, 117,
+  67, 127, 125, 83, 94, 104, 112, 124, 87, 138,
+  72, 206, 99, 132, 102, 117, 65, 64, 85, 130,
+  119, 87, 78, 102, 85, 90, 111, 99, 101, 79,
+  109, 113, 116, 115, 91, 99, 104, 95, 130, 76,
+  85, 117, 94, 97, 108, 83, 125, 67, 111, 124,
+  107, 162, 96, 89, 93, 107, 93, 76, 108, 106,
+  106, 105, 118, 76, 158, 131, 165, 127, 157, 102,
+  106, 176, 73, 110, 118, 98, 82, 99, 92, 107,
+  104, 132, 104, 89, 111, 162, 112, 63, 65, 103,
+  83, 111, 117, 74, 176, 76, 110, 79, 130, 167,
+  109, 109, 82, 193, 126, 89, 129, 154, 125, 93,
+  132, 148, 122, 104, 59, 111, 99, 143, 106, 85,
+  131, 83, 64, 94, 105, 110, 87, 109, 117, 97,
+  115, 146, 89, 67, 94, 110, 74, 77, 141, 90,
+  91, 95, 112, 78, 83, 134, 110, 103, 89, 78,
+  90, 97, 96, 112, 83, 110, 159, 68, 73, 107,
+  80, 87, 121, 138, 93, 79, 64, 91, 64, 70,
+  75, 73, 109, 116, 116, 87, 83, 111, 114, 142,
+  40, 66, 25, 108, 147, 81, 105, 87, 117, 53,
+  88, 119, 63, 103, 113, 112, 66, 94, 99, 73,
+  91, 76, 61, 164, 84, 104, 88, 114, 56, 80,
+  88, 96, 88, 79, 81, 106, 103, 54, 110, 115,
+  68, 68, 92, 95, 93, 87, 72, 87, 55, 78,
+  97, 152, 92, 105, 64, 112, 86, 72, 120, 72,
+  74, 76, 84, 134, 55, 85, 103, 102, 89, 74,
+  109, 98, 119, 88, 88, 56, 121, 84, 107, 109,
+  152, 66, 72, 143, 76, 112, 123, 80, 62, 106,
+  62, 100, 100, 113, 82, 92, 105, 126, 107, 86,
+  48, 92, 78, 101, 60, 101, 88, 94, 95, 100,
+  124, 150, 84, 103, 96, 169, 81, 85, 107, 129,
+  102, 79, 106, 118, 98, 95, 27, 92, 79, 86,
+  53, 52, 96, 71, 37, 116, 59, 100, 86, 66,
+  108, 99, 120, 108, 89, 65, 89, 133, 87, 107,
+  98, 70, 88, 89, 150, 79, 77, 130, 76, 93,
+  76, 75, 57, 74, 103, 99, 71, 91, 175, 84,
+  131, 87, 137, 115, 132, 143, 101, 88, 83, 108,
+  74, 91, 108, 75, 114, 111, 135, 111, 88, 106,
+  109, 82, 48, 106, 70, 115, 167, 100, 108, 82,
+  109, 109, 110, 106, 88, 77, 83, 101, 121, 121,
+  129, 73, 104, 74, 54, 148, 97, 92, 93, 144,
+  66, 78, 86, 95, 110, 81, 121, 93, 92, 77,
+  125, 106, 127, 118, 84, 134, 98, 103, 109, 72,
+  83, 116, 124, 106, 102, 108, 118, 100, 92, 78,
+  89, 89, 64, 95, 91, 148, 73, 95, 121, 76,
+  112, 82, 72, 109, 108, 97, 110, 103, 145, 129,
+  126, 136, 129, 100, 103, 47, 99, 110, 115, 80,
+  84, 112, 77, 88, 96, 100, 131, 92, 103, 118,
+  117, 78, 78, 92, 101, 97, 114, 95, 144, 108,
+  83, 79, 120, 90, 139, 113, 107, 154, 113, 113,
+  105, 110, 83, 96, 119, 101, 98, 112, 106, 117,
+  106, 136, 64, 125, 125, 77, 62, 91, 77, 54,
+  88, 98, 90, 99, 108, 100, 120, 102, 105, 110,
+  89, 94, 111, 85, 94, 91, 116, 86, 79, 145,
+  80, 73, 67, 90, 70, 79, 117, 118, 82, 89,
+  152, 74, 89, 97, 119, 122, 143, 119, 122, 119,
+  91, 104, 83, 107, 109, 95, 112, 124, 108, 92,
+  86, 90, 95, 88, 49, 119, 74, 131, 145, 100,
+  101, 91, 97, 108, 78, 98, 79, 85, 82, 104,
+  103, 130, 132, 90, 108, 83, 66, 123, 114, 106,
+  89, 117, 63, 93, 86, 83, 105, 100, 132, 87,
+  90, 81, 171, 118, 142, 142, 98, 134, 106, 101,
+  99, 56, 110, 129, 133, 78, 96, 103, 153, 110,
+  84, 85, 67, 75, 75, 124, 91, 154, 83, 94,
+  97, 118, 99, 93, 89, 94, 66, 108, 106, 118,
+  150, 124, 115, 143, 128, 103, 109, 115, 106, 101,
+  110, 95, 67, 111, 79, 78, 98, 85, 123, 86,
+  142, 91, 132, 104, 82, 109, 102, 99, 106, 127,
+  149, 94, 98, 98, 104, 84, 130, 103, 113, 107,
+  133, 107, 109, 115, 98, 106, 114, 94, 83, 96,
+  108, 109, 110, 131, 64, 106, 109, 80, 65, 73,
+  92, 68, 98, 94, 85, 87, 90, 112, 112, 94,
+  113, 93, 73, 82, 95, 110, 99, 86, 107, 110,
+  84, 118, 82, 82, 80, 113, 81, 89, 110, 134,
+  107, 112, 111, 55, 114, 101, 79, 89, 140, 93,
+  110, 132, 87, 87, 93, 112, 108, 89, 96, 132,
+  86, 67, 91, 86, 78, 95, 59, 93, 87, 122,
+  109, 87, 87, 104, 67, 84, 54, 107, 68, 88,
+  126, 112, 85, 118, 119, 84, 87, 92, 90, 110,
+  117, 116, 81, 126, 64, 103, 87, 77, 127, 116,
+  116, 99, 87, 91, 136, 134, 70, 87, 91, 120,
+  107, 129, 81, 53, 135, 114, 126, 94, 84, 100,
+  180, 117, 91, 82, 100, 74, 87, 121, 106, 128,
+  79, 108, 106, 143, 91, 96, 97, 85, 75, 103,
+  93, 109, 103, 101, 93, 117, 116, 143, 102, 132,
+  125, 138, 99, 92, 86, 116, 89, 89, 104, 78,
+  96, 83, 128, 71, 145, 87, 68, 94, 114, 99,
+  86, 107, 129, 86, 128, 114, 101, 98, 119, 91,
+  86, 84, 130, 103, 111, 133, 110, 93, 91, 104,
+  92, 109, 69, 125, 77, 100, 115, 68, 77, 106,
+  78, 89, 137, 87, 89, 85, 124, 98, 83, 173,
+  65, 77, 126, 111, 67, 102, 69, 125, 110, 98,
+  117, 143, 92, 87, 110, 74, 86, 134, 71, 111,
+  74, 119, 108, 127, 101, 62, 107, 91, 100, 82,
+  122, 128, 101, 112, 86, 83, 97, 112, 130, 83,
+  91, 114, 99, 80, 114, 109, 82, 90, 68, 105,
+  77, 115, 99, 85, 116, 117, 109, 74, 70, 122,
+  90, 81, 172, 126, 84, 108, 121, 67, 82, 97,
+  108, 95, 125, 124, 90, 134, 83, 130, 89, 116,
+  132, 88, 105, 116, 91, 104, 95, 106, 81, 94,
+  82, 134, 91, 108, 73, 72, 140, 110, 132, 121,
+  71, 123, 120, 116, 103, 87, 120, 98, 75, 80,
+  100, 99, 83, 128, 102, 106, 98, 113, 93, 124,
+  117, 109, 96, 130, 97, 111, 94, 111, 104, 140,
+  100, 94, 115, 150, 109, 106, 76, 123, 96, 92,
+  99, 102, 94, 100, 111, 72, 121, 111, 83, 93,
+  122, 92, 98, 87, 93, 113, 143, 102, 121, 125,
+  123, 106, 87, 77, 95, 114, 123, 119, 116, 80,
+  83, 77, 97, 103, 83, 123, 78, 108, 124, 82,
+  81, 130, 85, 129, 82, 85, 98, 70, 123, 122,
+  120, 125, 68, 95, 120, 116, 88, 119, 45, 112,
+  105, 102, 117, 140, 95, 81, 133, 81, 97, 106,
+  82, 95, 68, 113, 116, 110, 130, 84, 93, 86,
+  149, 123, 136, 141, 113, 97, 85, 96, 112, 113,
+  127, 94, 98, 88, 125, 101, 110, 90, 101, 88,
+  75, 142, 74, 100, 120, 101, 144, 106, 117, 93,
+  100, 101, 93, 97, 114, 90, 94, 109, 130, 83,
+  112, 97, 96, 117, 128, 138, 102, 123, 70, 133,
+  73, 129, 109, 97, 114, 91, 116, 115, 108, 85,
+  124, 140, 103, 108, 84, 97, 86, 88, 131, 116,
+  140, 97, 104, 118, 81, 89, 99, 103, 68, 90,
+  71, 91, 82, 128, 92, 106, 97, 92, 98, 115,
+  67, 133, 136, 106, 119, 154, 140, 91, 118, 115,
+  108, 104, 127, 74, 123, 106, 117, 107, 55, 131,
+  108, 75, 87, 100, 105, 107, 121, 93, 114, 92,
+  111, 77, 95, 83, 118, 65, 101, 130, 104, 92,
+  111, 112, 128, 93, 96, 66, 86, 112, 106, 109,
+  101, 104, 90, 60, 114, 97, 132, 124, 112, 140,
+  71, 103, 106, 103, 90, 116, 37, 81, 96, 88,
+  102, 117, 131, 96, 109, 121, 108, 88, 79, 102,
+  84, 98, 95, 103, 100, 110, 87, 94, 117, 97,
+  87, 82, 98, 95, 86, 135, 110, 97, 140, 101,
+  84, 106, 156, 136, 146, 124, 133, 110, 91, 118,
+  111, 110, 128, 106, 102, 89, 131, 111, 100, 84,
+  116, 88, 58, 163, 84, 113, 138, 96, 126, 86,
+  98, 104, 96, 91, 93, 110, 80, 75, 92, 120,
+  141, 71, 151, 108, 78, 143, 124, 140, 95, 106,
+  74, 107, 79, 110, 98, 103, 90, 98, 115, 103,
+  101, 78, 132, 133, 116, 111, 77, 98, 82, 103,
+  136, 140, 128, 88, 114, 107, 104, 94, 115, 121,
+  42, 82, 83, 109, 74, 147, 87, 83, 114, 111,
+  95, 104, 79, 104, 113, 113, 117, 161, 169, 91,
+  125, 135, 120, 101, 146, 98, 133, 112, 116, 93,
+  86, 137, 103, 77, 75, 91, 119, 88, 125, 126,
+  120, 82, 113, 85, 103, 96, 114, 89, 108, 117,
+  74, 77, 106, 98, 125, 95, 109, 80, 88, 129,
+  109, 106, 97, 119, 111, 63, 122, 105, 143, 142,
+  126, 167, 57, 102, 119, 83, 91, 104, 81, 95,
+  99, 113, 99, 113, 126, 99, 118, 119, 106, 93,
+  66, 75, 115, 96, 82, 94, 118, 108, 79, 103,
+  95, 99, 76, 100, 89, 99, 104, 144, 124, 120,
+  134, 103, 89, 119, 136, 129, 140, 95, 122, 114,
+  112, 119, 111, 111, 125, 111, 113, 105, 127, 103,
+  90, 70, 109, 85, 53, 138, 89, 113, 126, 84,
+  116, 79, 90, 97, 96, 92, 93, 112, 78, 88,
+  85, 116, 146, 62, 158, 112, 84, 144, 118, 144,
+  88, 106, 73, 101, 99, 96, 110, 115, 80, 102,
+  102, 100, 92, 101, 90, 115, 109, 109, 72, 110,
+  64, 92, 119, 139, 109, 100, 115, 110, 113, 100,
+  120, 118, 67, 91, 106, 101, 80, 143, 75, 88,
+  93, 142, 87, 100, 84, 94, 83, 106, 132, 128,
+  158, 89, 112, 143, 115, 97, 147, 117, 149, 131,
+  120, 84, 106, 137, 101, 87, 74, 89, 118, 87,
+  126, 132, 132, 104, 86, 80, 120, 111, 116, 85,
+  101, 108, 76, 82, 121, 111, 118, 94, 105, 83,
+  79, 141, 112, 121, 99, 115, 100, 84, 128, 113,
+  124, 137, 116, 147, 54, 98, 106, 83, 97, 108,
+  91, 100, 100, 124, 93, 104, 117, 109, 92, 105,
+  106, 104, 77, 59, 111, 103, 92, 102, 127, 131,
+  80, 115, 87, 106, 77, 132, 77, 102, 100, 125,
+  108, 115, 129, 94, 94, 117, 116, 119, 103, 82,
+  99, 100, 115, 109, 107, 110, 116, 100, 114, 118,
+  114, 95, 86, 67, 116, 84, 46, 110, 98, 101,
+  105, 68, 109, 74, 102, 87, 94, 88, 98, 101,
+  82, 105, 77, 101, 141, 53, 151, 98, 89, 145,
+  111, 135, 85, 144, 68, 100, 103, 89, 112, 138,
+  67, 94, 103, 101, 101, 112, 63, 94, 98, 118,
+  65, 123, 62, 89, 102, 118, 98, 104, 108, 113,
+  107, 81, 106, 116, 81, 88, 95, 84, 81, 125,
+  75, 97, 85, 140, 90, 93, 77, 84, 88, 87,
+  130, 103, 126, 76, 100, 152, 102, 91, 135, 96,
+  160, 135, 118, 77, 97, 127, 97, 100, 74, 88,
+  100, 96, 121, 126, 128, 122, 60, 70, 116, 104,
+  103, 85, 85, 91, 92, 100, 122, 112, 113, 91,
+  105, 82, 88, 141, 124, 128, 102, 102, 82, 106,
+  133, 113, 111, 116, 91, 113, 50, 80, 87, 81,
+  103, 123, 94, 112, 86, 109, 102, 106, 109, 111,
+  71, 88, 108, 119, 83, 76, 88, 101, 106, 103,
+  115, 145, 85, 124, 88, 91, 89, 137, 64, 98,
+  98, 110, 78, 127, 116, 92, 94, 122, 129, 127,
+  79, 92, 87, 104, 114, 113, 115, 125, 102, 105,
+  101, 124, 123, 107, 96, 68, 123, 91, 47, 123,
+  97, 88, 102, 68, 110, 63, 121, 84, 98, 84,
+  102, 94, 85, 107, 77, 100, 128, 55, 142, 106,
+  101, 151, 104, 132, 103, 160, 68, 108, 100, 110,
+  102, 126, 68, 105, 109, 103, 102, 113, 68, 91,
+  106, 155, 66, 125, 64, 96, 98, 103, 101, 104,
+  104, 120, 104, 56, 98, 123, 101, 94, 89, 96,
+  86, 124, 86, 94, 101, 118, 93, 92, 79, 82,
+  100, 82, 134, 99, 103, 90, 96, 140, 95, 88,
+  122, 75, 153, 120, 114, 103, 103, 118, 111, 104,
+  70, 72, 92, 95, 102, 129, 117, 124, 53, 53,
+  92, 95, 104, 70, 82, 97, 89, 98, 116, 103,
+  124, 95, 111, 71, 92, 150, 125, 118, 103, 98,
+  88, 127, 133, 110, 109, 137, 81, 102, 57, 73,
+  90, 90, 123, 131, 97, 114, 91, 94, 103, 104,
+  103, 119, 78, 61, 102, 126, 67, 85, 101, 107,
+  103, 108, 91, 147, 89, 116, 104, 89, 90, 113,
+  66, 96, 100, 117, 70, 127, 113, 92, 84, 124,
+  149, 147, 80, 113, 93, 107, 102, 117, 109, 148,
+  106, 129, 79, 119, 122, 116, 101, 73, 110, 86,
+  40, 158, 97, 112, 100, 73, 129, 57, 125, 92,
+  102, 74, 101, 102, 84, 99, 86, 108, 117, 69,
+  133, 124, 109, 141, 107, 127, 123, 137, 63, 105,
+  105, 152, 95, 102, 92, 139, 101, 115, 102, 109,
+  93, 100, 112, 175, 74, 114, 63, 97, 111, 106,
+  108, 109, 104, 138, 113, 65, 97, 133, 103, 118,
+  107, 94, 98, 146, 102, 78, 105, 107, 84, 91,
+  76, 115, 91, 101, 149, 117, 96, 100, 110, 127,
+  94, 85, 117, 84, 147, 125, 115, 124, 111, 116,
+  126, 104, 78, 84, 85, 92, 101, 142, 109, 118,
+  52, 54, 71, 106, 110, 64, 77, 99, 60, 80,
+  115, 97, 97, 113, 100, 52, 87, 140, 119, 111,
+  108, 101, 99, 135, 119, 114, 117, 143, 88, 122,
+  68, 88, 89, 90, 148, 127, 89, 90, 99, 88,
+  97, 101, 100, 100, 98, 36, 86, 110, 53, 73,
+  113, 93, 81, 117, 91, 143, 90, 117, 118, 89,
+  85, 86, 73, 107, 103, 138, 66, 106, 118, 95,
+  84, 109, 155, 168, 92, 110, 92, 94, 87, 116,
+  116, 173, 105, 145, 66, 108, 95, 117, 100, 69,
+  112, 82, 38, 172, 102, 134, 95, 82, 161, 81,
+  95, 108, 117, 68, 108, 116, 90, 71, 94, 111,
+  104, 93, 108, 132, 110, 122, 116, 115, 124, 116,
+  55, 85, 102, 191, 89, 103, 116, 143, 104, 124,
+  108, 101, 125, 135, 126, 144, 98, 112, 63, 104,
+  120, 103, 126, 103, 104, 142, 113, 79, 95, 134,
+  71, 123, 134, 111, 101, 173, 117, 72, 89, 103,
+  87, 90, 62, 145, 90, 113, 164, 120, 111, 99,
+  135, 120, 92, 94, 116, 89, 127, 132, 110, 132,
+  84, 111, 126, 105, 92, 111, 75, 80, 104, 148,
+  99, 115, 43, 70, 55, 114, 140, 62, 87, 90,
+  62, 76, 100, 76, 63, 118, 86, 41, 92, 111,
+  108, 104, 99, 105, 99, 145, 103, 108, 122, 125,
+  94, 145, 50, 129, 101, 77, 144, 107, 89, 61,
+  84, 92, 94, 95, 93, 74, 120, 38, 68, 105,
+  50, 54, 125, 62, 73, 126, 89, 126, 87, 137,
+  124, 80, 78, 72, 74, 108, 109, 147, 47, 108,
+  124, 103, 103, 88, 131, 157, 98, 73, 77, 59,
+  88, 97, 154, 182, 102, 158, 82, 101, 82, 93,
+  90, 58, 116, 91, 34, 154, 102, 129, 85, 86,
+  148, 98, 70, 112, 124, 73, 115, 117, 103, 60,
+  84, 92, 99, 109, 92, 138, 102, 105, 102, 113,
+  122, 79, 61, 53, 97, 221, 86, 116, 147, 137,
+  95, 125, 92, 95, 109, 144, 133, 106, 135, 119,
+  76, 94, 98, 93, 116, 90, 99, 123, 87, 78,
+  116, 116, 101, 109, 182, 125, 105, 162, 107, 58,
+  77, 99, 98, 93, 73, 128, 104, 100, 162, 99,
+  106, 131, 140, 123, 86, 91, 101, 132, 99, 99,
+  110, 157, 86, 103, 104, 106, 106, 129, 67, 73,
+  96, 136, 104, 111, 30, 111, 51, 124, 160, 89,
+  114, 82, 68, 53, 90, 108, 52, 102, 78, 51,
+  101, 93, 110, 105, 90, 97, 93, 162, 87, 114,
+  81, 83, 82, 140, 71, 162, 99, 74, 126, 86,
+  102, 52, 66, 97, 97, 92, 105, 81, 121, 58,
+  62, 110, 53, 45, 122, 46, 85, 125, 87, 101,
+  88, 145, 126, 57, 81, 64, 67, 91, 104, 124,
+  44, 119, 117, 100, 94, 83, 80, 107, 74, 73,
+  47, 44, 99, 85, 173, 136, 92, 149, 101, 104,
+  63, 73, 86, 63, 109, 160, 15, 92, 100, 90,
+  79, 59, 95, 96, 96, 102, 129, 99, 100, 79,
+  113, 68, 62, 57, 92, 108, 72, 97, 85, 108,
+  83, 84, 100, 58, 66, 44, 88, 174, 81, 123,
+  132, 111, 106, 84, 93, 109, 56, 107, 131, 98,
+  174, 143, 80, 79, 80, 89, 85, 103, 86, 97,
+  80, 79, 119, 90, 141, 86, 145, 102, 108, 129,
+  68, 57, 92, 93, 112, 83, 122, 113, 104, 85,
+  139, 54, 91, 115, 103, 120, 72, 58, 75, 162,
+  91, 93, 106, 154, 86, 92, 70, 101, 107, 106,
+  67, 84, 79, 101, 106, 114, 11, 131, 51, 110,
+  126, 138, 119, 67, 60, 61, 94, 151, 60, 75,
+  88, 81, 90, 104, 116, 108, 91, 78, 64, 175,
+  72, 113, 39, 65, 45, 97, 81, 128, 71, 83,
+  96, 68, 106, 74, 54, 72, 95, 93, 117, 125,
+  97, 65, 88, 93, 59, 71, 107, 67, 109, 118,
+  84, 99, 85, 129, 114, 49, 92, 61, 48, 66,
+  93, 90, 27, 97, 117, 88, 67, 89, 53, 88,
+  65, 130, 40, 78, 90, 100, 111, 87, 68, 99,
+  136, 111, 60, 69, 89, 128, 92, 177, 8, 47,
+  84, 60, 109, 60, 61, 72, 127, 83, 102, 115,
+  73, 53, 111, 60, 82, 40, 104, 105, 56, 34,
+  66, 125, 94, 82, 53, 97, 74, 33, 78, 90,
+  104, 107, 84, 79, 114, 47, 111, 129, 50, 78,
+  92, 89, 155, 156, 78, 83, 69, 83, 85, 105,
+  86, 63, 77, 89, 91, 81, 124, 111, 50, 83,
+  103, 118, 37, 100, 109, 88, 138, 47, 146, 111,
+  110, 81, 100, 38, 101, 72, 104, 114, 71, 33,
+  62, 98, 110, 94, 109, 98, 58, 90, 53, 89,
+  113, 77, 92, 88, 99, 97, 121, 97, 16, 100,
+  70, 88, 84, 152, 122, 57, 59, 100, 98, 95,
+  78, 75, 106, 104, 47, 96, 112, 131, 109, 71,
+  55, 167, 61, 103, 53, 103, 39, 68, 60, 68,
+  82, 88, 60, 70, 114, 96, 54, 75, 88, 102,
+  99, 133, 67, 60, 126, 82, 77, 115, 98, 76,
+  100, 112, 92, 87, 72, 108, 79, 60, 86, 66,
+  64, 58, 99, 68, 32, 60, 126, 86, 103, 94,
+  72, 122, 128, 131, 76, 106, 79, 147, 75, 134,
+  67, 74, 162, 97, 60, 94, 92, 140, 97, 89,
+  26, 86, 76, 90, 192, 93, 75, 62, 92, 75,
+  98, 112, 67, 100, 87, 53, 116, 76, 141, 110,
+  44, 81, 62, 163, 105, 131, 56, 122, 75, 27,
+  78, 81, 145, 88, 90, 79, 68, 60, 101, 121,
+  110, 89, 84, 107, 116, 123, 106, 79, 103, 104,
+  123, 71, 90, 91, 83, 99, 85, 85, 126, 133,
+  37, 114, 112, 159, 52, 160, 83, 111, 126, 58,
+  117, 107, 120, 95, 75, 58, 154, 120, 188, 119,
+  106, 72, 83, 87, 85, 92, 110, 85, 66, 99,
+  81, 93, 121, 81, 197, 85, 94, 162, 129, 69,
+  45, 96, 95, 94, 96, 105, 184, 66, 81, 70,
+  134, 96, 106, 106, 114, 150, 109, 94, 123, 215,
+  145, 80, 89, 167, 84, 113, 111, 120, 67, 99,
+  128, 86, 168, 89, 73, 90, 130, 97, 73, 134,
+  84, 105, 82, 115, 77, 70, 118, 72, 121, 109,
+  110, 82, 71, 90, 89, 88, 80, 102, 88, 73,
+  73, 67, 114, 85, 113, 99, 86, 86, 128, 107,
+  110, 117, 60, 123, 149, 92, 90, 111, 73, 161,
+  95, 132, 97, 97, 173, 99, 76, 125, 106, 61,
+  93, 101, 31, 106, 82, 83, 197, 99, 99, 90,
+  73, 75, 103, 110, 73, 158, 93, 92, 92, 95,
+  140, 97, 48, 147, 59, 152, 110, 151, 61, 91,
+  82, 50, 72, 81, 112, 100, 94, 112, 103, 52,
+  98, 98, 126, 86, 111, 127, 99, 103, 117, 115,
+  133, 108, 151, 93, 58, 97, 109, 139, 88, 69,
+  98, 98, 67, 124, 101, 154, 47, 136, 49, 128,
+  106, 70, 78, 73, 105, 114, 81, 59, 153, 103,
+  177, 117, 142, 107, 87, 171, 95, 117, 111, 75,
+  77, 110, 110, 102, 119, 104, 216, 82, 80, 159,
+  127, 98, 58, 132, 123, 115, 86, 79, 157, 91,
+  116, 83, 126, 149, 85, 107, 124, 170, 172, 89,
+  135, 227, 163, 88, 103, 156, 95, 113, 87, 98,
+  87, 111, 107, 72, 176, 88, 72, 119, 108, 131,
+  105, 151, 101, 99, 102, 115, 78, 76, 108, 90,
+  151, 76, 109, 127, 60, 71, 96, 118, 87, 83,
+  91, 106, 92, 89, 132, 81, 100, 121, 109, 111,
+  117, 140, 120, 119, 43, 96, 117, 126, 75, 86,
+  56, 128, 136, 93, 112, 115, 196, 136, 69, 114,
+  99, 66, 77, 85, 21, 87, 75, 53, 128, 87,
+  84, 144, 105, 76, 84, 129, 75, 116, 122, 110,
+  92, 66, 114, 91, 52, 127, 85, 101, 101, 129,
+  33, 147, 103, 78, 96, 77, 101, 134, 91, 118,
+  86, 44, 95, 108, 82, 59, 111, 108, 112, 122,
+  98, 105, 113, 104, 137, 112, 54, 88, 140, 143,
+  89, 70, 88, 95, 110, 85, 91, 121, 36, 112,
+  87, 146, 109, 64, 82, 81, 98, 113, 100, 28,
+  121, 81, 105, 112, 147, 88, 69, 152, 102, 90,
+  120, 76, 90, 101, 104, 87, 131, 123, 169, 108,
+  77, 109, 134, 123, 64, 156, 103, 113, 61, 107,
+  116, 95, 108, 106, 106, 87, 69, 83, 141, 147,
+  122, 76, 114, 172, 148, 97, 67, 138, 70, 109,
+  56, 107, 67, 94, 89, 67, 108, 96, 56, 113,
+  97, 133, 111, 118, 104, 92, 123, 124, 62, 90,
+  114, 116, 158, 82, 83, 146, 92, 87, 100, 134,
+  92, 75, 94, 102, 107, 115, 120, 60, 84, 90,
+  104, 92, 107, 112, 111, 104, 56, 76, 108, 131,
+  66, 90, 49, 97, 119, 110, 114, 120, 150, 145,
+  46, 77, 73, 89, 48, 125, 23, 85, 107, 69,
+  88, 61, 43, 94, 108, 106, 64, 116, 73, 94,
+  138, 96, 118, 43, 94, 129, 46, 115, 111, 80,
+  78, 99, 15, 172, 92, 89, 84, 84, 109, 114,
+  112, 82, 92, 45, 85, 125, 78, 64, 105, 101,
+  128, 176, 119, 52, 110, 101, 113, 90, 69, 70,
+  146, 102, 84, 85, 89, 119, 106, 82, 86, 112,
+  36, 137, 124, 138, 135, 52, 91, 133, 99, 81,
+  92, 36, 122, 81, 87, 121, 129, 70, 70, 113,
+  108, 87, 97, 102, 77, 74, 78, 104, 125, 102,
+  123, 117, 91, 80, 142, 120, 47, 112, 72, 86,
+  74, 110, 142, 36, 111, 146, 79, 70, 92, 59,
+  118, 122, 81, 89, 110, 170, 122, 113, 49, 158,
+  66, 117, 44, 135, 56, 90, 94, 84, 84, 102,
+  82, 101, 83, 99, 78, 62, 85, 105, 89, 164,
+  55, 66, 117, 102, 116, 78, 94, 138, 148, 104,
+  49, 163, 97, 86, 118, 100, 119, 147, 92, 66,
+  87, 73, 85, 70, 107, 69, 113, 64, 47, 81,
+  94, 106, 80, 126, 50, 74, 77, 119, 98, 92,
+  114, 134, 40, 51, 54, 95, 74, 135, 27, 63,
+  96, 87, 88, 75, 56, 85, 70, 105, 53, 122,
+  85, 108, 151, 108, 90, 50, 95, 131, 51, 76,
+  123, 86, 106, 97, 20, 126, 88, 90, 65, 88,
+  110, 106, 126, 94, 90, 76, 103, 115, 64, 75,
+  67, 113, 119, 145, 101, 53, 84, 102, 101, 104,
+  81, 87, 87, 97, 99, 90, 112, 103, 54, 91,
+  96, 94, 38, 171, 134, 99, 112, 59, 117, 144,
+  141, 93, 65, 52, 91, 73, 84, 113, 95, 88,
+  54, 94, 93, 128, 98, 98, 65, 63, 67, 116,
+  140, 82, 97, 100, 101, 69, 124, 95, 37, 88,
+  76, 72, 85, 106, 113, 31, 138, 169, 79, 92,
+  83, 73, 86, 100, 62, 88, 111, 159, 119, 80,
+  38, 166, 77, 118, 44, 124, 37, 66, 97, 88,
+  70, 105, 84, 122, 89, 61, 65, 65, 109, 115,
+  70, 144, 44, 57, 99, 136, 105, 106, 78, 89,
+  154, 123, 74, 172, 97, 101, 120, 92, 109, 147,
+  57, 91, 91, 60, 94, 93, 119, 63, 88, 91,
+  93, 116, 100, 123, 100, 95, 67, 91, 71, 117,
+  90, 64, 85, 117, 78, 72, 87, 91, 98, 92,
+  34, 122, 107, 83, 93, 94, 114, 112, 66, 104,
+  109, 139, 78, 103, 126, 93, 99, 90, 105, 114,
+  68, 69, 130, 132, 142, 127, 79, 111, 107, 147,
+  73, 126, 136, 104, 120, 92, 107, 126, 110, 97,
+  91, 101, 86, 126, 99, 93, 97, 92, 81, 134,
+  126, 117, 78, 115, 46, 87, 134, 86, 151, 100,
+  21, 104, 103, 90, 64, 150, 138, 81, 96, 104,
+  114, 144, 185, 114, 99, 114, 92, 105, 114, 112,
+  77, 130, 59, 63, 114, 91, 100, 126, 68, 75,
+  97, 128, 134, 80, 109, 115, 81, 86, 90, 102,
+  55, 72, 72, 75, 105, 84, 113, 94, 128, 138,
+  104, 97, 118, 114, 105, 87, 90, 107, 90, 119,
+  117, 87, 63, 102, 72, 111, 107, 125, 60, 86,
+  79, 122, 72, 103, 110, 135, 98, 71, 78, 108,
+  145, 102, 94, 114, 63, 104, 88, 167, 122, 142,
+  47, 77, 123, 136, 87, 152, 76, 112, 110, 100,
+  105, 100, 68, 112, 101, 84, 112, 114, 114, 98,
+  173, 107, 161, 161, 117, 118, 128, 79, 116, 114,
+  108, 122, 112, 82, 93, 100, 105, 91, 117, 56,
+  143, 68, 42, 163, 109, 95, 122, 99, 140, 105,
+  81, 97, 147, 136, 106, 117, 103, 42, 94, 102,
+  130, 118, 102, 110, 102, 183, 139, 155, 128, 87,
+  84, 141, 95, 127, 111, 106, 113, 111, 119, 150,
+  113, 76, 117, 129, 122, 106, 107, 101, 98, 113,
+  99, 155, 148, 63, 94, 122, 78, 93, 159, 93,
+  141, 104, 60, 124, 101, 111, 95, 113, 111, 99,
+  89, 127, 110, 130, 166, 131, 108, 150, 119, 146,
+  133, 117, 109, 111, 97, 92, 135, 98, 119, 123,
+  71, 87, 144, 126, 131, 87, 128, 103, 108, 111,
+  89, 92, 79, 57, 83, 88, 143, 68, 142, 141,
+  90, 61, 137, 123, 146, 122, 103, 83, 105, 116,
+  101, 106, 87, 105, 105, 59, 114, 102, 156, 129,
+  100, 139, 59, 158, 102, 92, 129, 102, 97, 81,
+  94, 137, 119, 83, 110, 123, 82, 135, 89, 111,
+  118, 73, 82, 69, 105, 145, 105, 91, 75, 134,
+  88, 99, 63, 85, 106, 139, 116, 95, 170, 124,
+  109, 124, 101, 102, 137, 151, 103, 117, 139, 110,
+  107, 115, 89, 100, 110, 106, 120, 84, 78, 87,
+  120, 58, 122, 95, 32, 132, 88, 124, 119, 89,
+  96, 81, 115, 70, 115, 133, 115, 105, 108, 78,
+  67, 94, 138, 108, 125, 138, 89, 181, 97, 124,
+  128, 99, 88, 121, 133, 91, 102, 125, 79, 103,
+  99, 107, 114, 95, 85, 94, 109, 88, 125, 141,
+  87, 104, 94, 152, 134, 83, 105, 144, 116, 106,
+  144, 94, 132, 87, 63, 94, 98, 107, 80, 103,
+  99, 156, 95, 122, 110, 95, 116, 116, 104, 116,
+  107, 146, 103, 100, 118, 62, 108, 136, 117, 111,
+  128, 66, 76, 96, 135, 116, 105, 62, 117, 91,
+  143, 106, 108, 112, 68, 78, 126, 107, 115, 91,
+  110, 131, 80, 77, 188, 166, 92, 111, 102, 84,
+  98, 113, 118, 109, 81, 92, 132, 83, 94, 107,
+  117, 108, 88, 114, 49, 122, 92, 90, 112, 100,
+  81, 102, 87, 119, 80, 80, 116, 91, 64, 106,
+  93, 76, 102, 68, 98, 68, 85, 140, 111, 118,
+  79, 138, 68, 84, 78, 117, 95, 109, 107, 64,
+  174, 121, 97, 128, 126, 107, 80, 134, 75, 122,
+  123, 128, 106, 117, 98, 117, 99, 114, 103, 86,
+  56, 85, 116, 39, 102, 85, 41, 128, 131, 115,
+  105, 73, 77, 96, 123, 88, 128, 113, 111, 74,
+  116, 122, 74, 77, 121, 91, 109, 123, 98, 173,
+  84, 118, 133, 125, 99, 139, 152, 103, 120, 121,
+  83, 95, 108, 89, 113, 143, 70, 87, 117, 90,
+  121, 165, 108, 107, 98, 122, 112, 116, 116, 122,
+  134, 75, 107, 88, 140, 83, 77, 70, 133, 124,
+  81, 108, 94, 160, 92, 92, 110, 73, 99, 81,
+  128, 95, 110, 124, 107, 85, 111, 65, 107, 124,
+  115, 92, 140, 87, 96, 99, 123, 127, 81, 56,
+  87, 82, 140, 133, 113, 146, 50, 75, 117, 123,
+  97, 60, 106, 93, 96, 118, 146, 131, 99, 93,
+  92, 106, 100, 128, 126, 134, 89, 98, 138, 140,
+  94, 104, 77, 112, 64, 87, 52, 87, 79, 110,
+  114, 103, 92, 122, 91, 95, 110, 67, 91, 135,
+  54, 48, 109, 73, 78, 94, 108, 103, 95, 151,
+  80, 173, 94, 114, 93, 76, 111, 134, 81, 95,
+  101, 53, 124, 100, 111, 114, 94, 121, 78, 129,
+  81, 118, 113, 116, 101, 130, 125, 150, 80, 65,
+  115, 92, 65, 95, 136, 86, 116, 101, 81, 148,
+  202, 120, 96, 96, 107, 111, 66, 122, 153, 116,
+  103, 93, 137, 125, 126, 104, 116, 52, 94, 104,
+  109, 137, 97, 131, 144, 108, 105, 132, 127, 140,
+  147, 97, 137, 118, 101, 122, 102, 146, 105, 123,
+  137, 114, 101, 140, 83, 104, 98, 107, 106, 169,
+  192, 128, 143, 106, 116, 68, 148, 83, 101, 89,
+  162, 152, 91, 106, 97, 121, 116, 107, 135, 78,
+  125, 95, 117, 116, 115, 100, 144, 104, 110, 107,
+  101, 122, 96, 135, 135, 118, 101, 100, 126, 109,
+  92, 93, 93, 96, 86, 158, 114, 166, 65, 113,
+  91, 141, 127, 105, 90, 78, 98, 107, 104, 117,
+  168, 114, 98, 123, 99, 161, 148, 165, 128, 100,
+  122, 169, 96, 125, 85, 126, 80, 87, 89, 112,
+  87, 119, 150, 137, 118, 113, 117, 113, 110, 73,
+  82, 130, 77, 64, 117, 108, 82, 126, 126, 105,
+  95, 138, 95, 195, 112, 116, 141, 84, 127, 123,
+  95, 107, 95, 87, 116, 112, 163, 107, 110, 119,
+  115, 139, 110, 113, 133, 95, 130, 123, 108, 104,
+  140, 141, 114, 122, 127, 114, 141, 123, 133, 101,
+  86, 98, 124, 109, 128, 109, 138, 79, 127, 122,
+  121, 158, 116, 75, 106, 112, 130, 107, 117, 97,
+  118, 77, 80, 115, 125, 93, 108, 121, 92, 140,
+  119, 109, 130, 151, 110, 96, 127, 92, 129, 124,
+  145, 147, 107, 116, 121, 119, 113, 115, 121, 130,
+  121, 117, 142, 128, 84, 117, 118, 92, 75, 122,
+  102, 123, 114, 122, 93, 114, 114, 112, 106, 108,
+  103, 121, 92, 110, 133, 124, 144, 112, 122, 121,
+  129, 101, 124, 111, 116, 106, 138, 110, 76, 102,
+  106, 83, 109, 118, 114, 111, 113, 117, 91, 106,
+  98, 121, 91, 99, 138, 118, 119, 137, 108, 139,
+  124, 74, 127, 112, 124, 151, 93, 116, 109, 99,
+  106, 114, 145, 85, 121, 94, 93, 100, 118, 121,
+  53, 98, 113, 96, 94, 101, 84, 96, 150, 91,
+  95, 100, 123, 100, 118, 129, 120, 98, 118, 105,
+  75, 117, 117, 110, 95, 109, 90, 144, 103, 105,
+  122, 83, 104, 85, 85, 101, 102, 108, 181, 102,
+  118, 108, 86, 123, 122, 131, 138, 128, 103, 117,
+  83, 117, 114, 111, 111, 116, 112, 96, 120, 137,
+  125, 86, 66, 79, 31, 109, 137, 90, 92, 83,
+  131, 75, 92, 129, 72, 97, 110, 83, 112, 86,
+  106, 134, 120, 50, 61, 167, 95, 93, 99, 132,
+  59, 98, 101, 112, 147, 157, 75, 96, 98, 94,
+  120, 128, 112, 110, 102, 100, 110, 103, 92, 102,
+  111, 115, 117, 98, 100, 132, 98, 95, 98, 95,
+  99, 101, 81, 133, 105, 143, 84, 102, 127, 121,
+  94, 82, 99, 118, 104, 98, 106, 109, 144, 131,
+  138, 117, 145, 76, 113, 127, 90, 118, 139, 88,
+  65, 103, 80, 84, 106, 100, 107, 91, 121, 153,
+  97, 78, 75, 122, 62, 118, 105, 138, 151, 83,
+  110, 124, 121, 67, 135, 102, 118, 180, 104, 80,
+  117, 123, 111, 98, 133, 116, 123, 87, 108, 140,
+  108, 116, 86, 62, 117, 78, 65, 94, 147, 115,
+  114, 81, 121, 92, 97, 120, 94, 83, 110, 100,
+  88, 148, 88, 99, 96, 108, 93, 82, 91, 135,
+  88, 97, 106, 88, 104, 95, 85, 95, 92, 124,
+  153, 98, 169, 121, 86, 102, 143, 122, 116, 117,
+  86, 129, 93, 139, 118, 126, 105, 118, 131, 86,
+  116, 70, 123, 92, 66, 101, 32, 118, 150, 96,
+  84, 108, 104, 70, 95, 125, 71, 126, 128, 82,
+  98, 102, 108, 130, 86, 140, 74, 201, 109, 128,
+  101, 109, 74, 73, 96, 125, 130, 93, 70, 102,
+  84, 89, 102, 109, 92, 75, 110, 121, 117, 124,
+  83, 112, 95, 99, 125, 84, 86, 120, 89, 106,
+  113, 80, 126, 69, 101, 123, 106, 158, 90, 95,
+  101, 115, 96, 73, 112, 108, 100, 100, 117, 76,
+  151, 123, 161, 128, 153, 106, 110, 175, 75, 109,
+  118, 94, 82, 105, 92, 109, 101, 126, 115, 92,
+  107, 171, 110, 67, 67, 103, 86, 121, 124, 80,
+  181, 75, 115, 71, 136, 174, 103, 118, 86, 204,
+  133, 80, 135, 155, 126, 88, 136, 160, 128, 102,
+  59, 113, 93, 136, 118, 81, 131, 88, 75, 101,
+  114, 115, 94, 107, 114, 95, 117, 146, 91, 69,
+  104, 106, 79, 79, 139, 92, 92, 92, 110, 76,
+  82, 130, 107, 110, 79, 91, 86, 105, 100, 103,
+  91, 113, 159, 73, 78, 111, 72, 85, 111, 143,
+  92, 86, 60, 99, 62, 68, 78, 74, 106, 113,
+  111, 89, 99, 101, 112, 135, 40, 64, 25, 101,
+  138, 78, 103, 92, 113, 60, 95, 125, 63, 108,
+  115, 119, 70, 89, 90, 83, 90, 86, 63, 166,
+  91, 109, 94, 119, 64, 91, 91, 91, 94, 77,
+  72, 101, 101, 62, 106, 122, 59, 68, 91, 98,
+  94, 93, 72, 94, 58, 82, 97, 151, 91, 109,
+  61, 110, 90, 82, 117, 71, 72, 77, 81, 134,
+  52, 83, 99, 112, 80, 69, 112, 100, 111, 92,
+  92, 57, 125, 71, 109, 106, 156, 74, 81, 134,
+  70, 108, 125, 85, 67, 101, 60, 99, 97, 117,
+  87, 93, 99, 136, 101, 88, 48, 87, 80, 107,
+  65, 93, 96, 90, 98, 97, 128, 151, 82, 108,
+  107, 180, 95, 82, 118, 128, 107, 80, 109, 127,
+  107, 91, 28, 84, 74, 85, 59, 44, 96, 75,
+  41, 116, 56, 107, 94, 61, 107, 95, 127, 105,
+  92, 68, 95, 135, 85, 109, 88, 75, 82, 96,
+  136, 87, 74, 124, 73, 98, 81, 83, 64, 80,
+  106, 93, 71, 89, 179, 94, 133, 91, 121, 120,
+  118, 137, 103, 99, 84, 117, 84, 93, 113, 74,
+  105, 109, 129, 114, 110, 99, 109, 83, 55, 110,
+  80, 103, 163, 95, 113, 89, 99, 130, 121, 115,
+  82, 80, 81, 117, 129, 118, 120, 96, 99, 81,
+  54, 150, 90, 103, 106, 143, 70, 85, 80, 96,
+  110, 74, 117, 81, 101, 89, 131, 113, 120, 130,
+  92, 141, 101, 111, 114, 76, 98, 127, 127, 110,
+  97, 113, 103, 87, 92, 96, 93, 87, 75, 106,
+  93, 145, 71, 87, 108, 80, 106, 81, 70, 99,
+  107, 92, 124, 113, 154, 123, 130, 126, 130, 114,
+  113, 44, 87, 106, 115, 100, 82, 106, 77, 89,
+  93, 104, 125, 89, 98, 123, 99, 84, 76, 93,
+  98, 100, 123, 85, 159, 102, 97, 88, 115, 83,
+  136, 119, 114, 164, 131, 108, 110, 106, 85, 105,
+  132, 106, 100, 106, 100, 103, 96, 137, 59, 116,
+  119, 79, 71, 93, 81, 61, 100, 99, 94, 98,
+  110, 96, 128, 106, 100, 113, 91, 80, 94, 98,
+  96, 98, 97, 91, 74, 146, 82, 70, 80, 89,
+  74, 91, 112, 112, 87, 93, 151, 84, 89, 97,
+  99, 122, 132, 103, 113, 138, 86, 109, 89, 105,
+  121, 97, 84, 115, 103, 98, 99, 97, 103, 90,
+  52, 108, 83, 114, 143, 92, 114, 85, 98, 117,
+  81, 104, 71, 87, 81, 107, 98, 128, 111, 112,
+  94, 79, 72, 112, 102, 119, 103, 100, 68, 98,
+  90, 95, 106, 121, 115, 70, 98, 95, 171, 142,
+  124, 149, 93, 134, 115, 103, 112, 72, 117, 124,
+  131, 92, 74, 109, 121, 92, 80, 102, 87, 87,
+  79, 134, 95, 133, 75, 87, 97, 127, 99, 96,
+  88, 87, 71, 105, 122, 123, 149, 126, 115, 132,
+  120, 104, 117, 128, 101, 97, 112, 107, 67, 106,
+  69, 99, 102, 94, 99, 84, 142, 90, 115, 106,
+  64, 102, 93, 111, 108, 129, 149, 92, 115, 123,
+  95, 64, 130, 110, 107, 105, 142, 98, 108, 114,
+  95, 114, 123, 98, 78, 98, 86, 109, 94, 119,
+  63, 95, 103, 79, 74, 85, 114, 75, 104, 89,
+  97, 92, 94, 111, 119, 90, 102, 97, 79, 85,
+  76, 103, 109, 89, 107, 112, 81, 124, 86, 80,
+  89, 101, 87, 108, 97, 124, 100, 122, 108, 76,
+  142, 106, 55, 88, 115, 111, 111, 143, 77, 108,
+  111, 114, 113, 83, 74, 109, 100, 71, 105, 90,
+  105, 81, 62, 74, 89, 107, 121, 96, 106, 108,
+  77, 87, 53, 122, 80, 101, 152, 101, 89, 124,
+  115, 94, 76, 99, 115, 108, 107, 125, 104, 116,
+  86, 104, 98, 105, 141, 143, 104, 100, 89, 106,
+  122, 148, 52, 78, 83, 116, 112, 125, 78, 98,
+  132, 97, 120, 116, 68, 97, 119, 103, 95, 82,
+  131, 77, 86, 114, 113, 110, 80, 94, 112, 140,
+  73, 112, 111, 92, 83, 100, 98, 93, 89, 105,
+  94, 119, 117, 130, 99, 125, 105, 153, 112, 88,
+  99, 120, 91, 110, 115, 91, 83, 97, 125, 89,
+  118, 72, 71, 89, 115, 127, 98, 113, 133, 95,
+  135, 111, 99, 107, 116, 107, 72, 100, 136, 100,
+  116, 146, 120, 84, 97, 119, 102, 120, 60, 123,
+  59, 84, 159, 76, 71, 123, 87, 109, 136, 112,
+  94, 98, 132, 94, 120, 181, 74, 87, 109, 106,
+  81, 114, 76, 121, 108, 93, 137, 129, 95, 93,
+  113, 74, 80, 105, 81, 131, 69, 112, 105, 140,
+  99, 74, 93, 92, 95, 98, 115, 156, 106, 100,
+  85, 104, 111, 114, 163, 87, 80, 92, 97, 95,
+  109, 127, 110, 99, 69, 119, 77, 114, 126, 91,
+  135, 141, 129, 76, 79, 124, 104, 88, 194, 103,
+  83, 127, 133, 85, 82, 108, 110, 95, 112, 115,
+  107, 139, 91, 99, 95, 140, 124, 83, 99, 105,
+  107, 112, 103, 104, 104, 105, 101, 122, 96, 111,
+  83, 112, 140, 91, 133, 119, 64, 126, 88, 111,
+  101, 81, 116, 73, 79, 91, 101, 88, 83, 117,
+  114, 97, 100, 126, 134, 121, 139, 112, 102, 105,
+  105, 106, 88, 119, 122, 136, 106, 98, 109, 160,
+  115, 86, 63, 123, 113, 109, 106, 113, 90, 120,
+  119, 86, 102, 119, 83, 98, 117, 100, 102, 103,
+  95, 134, 122, 93, 98, 125, 118, 106, 70, 92,
+  110, 114, 133, 130, 120, 88, 113, 83, 93, 111,
+  86, 115, 86, 107, 102, 94, 92, 140, 84, 149,
+  55, 100, 112, 92, 124, 116, 159, 121, 90, 103,
+  114, 114, 100, 132, 62, 123, 100, 92, 126, 115,
+  101, 95, 122, 102, 81, 77, 101, 104, 66, 104,
+  108, 115, 130, 90, 99, 82, 153, 152, 141, 130,
+  118, 100, 103, 109, 109, 117, 131, 100, 97, 91,
+  107, 109, 95, 120, 124, 77, 75, 159, 89, 103,
+  143, 103, 129, 118, 115, 87, 86, 103, 102, 99,
+  113, 72, 97, 122, 146, 91, 122, 98, 79, 131,
+  126, 123, 88, 125, 70, 101, 85, 122, 113, 95,
+  115, 99, 108, 104, 110, 78, 131, 132, 113, 118,
+  82, 108, 110, 95, 134, 122, 137, 85, 99, 131,
+  85, 93, 101, 105, 71, 70, 71, 101, 95, 130,
+  91, 118, 127, 108, 107, 111, 93, 125, 139, 103,
+  115, 140, 132, 108, 98, 126, 122, 114, 127, 84,
+  162, 119, 116, 81, 76, 122, 130, 85, 89, 95,
+  125, 105, 126, 104, 112, 99, 107, 68, 120, 87,
+  127, 81, 102, 145, 91, 78, 104, 93, 121, 100,
+  82, 86, 103, 108, 110, 116, 99, 108, 102, 66,
+  105, 97, 126, 148, 125, 140, 67, 109, 123, 97,
+  102, 116, 45, 75, 107, 122, 102, 128, 135, 106,
+  115, 120, 102, 94, 90, 103, 96, 116, 110, 98,
+  108, 108, 91, 115, 117, 100, 78, 90, 104, 105,
+  82, 128, 105, 104, 130, 94, 80, 112, 154, 138,
+  143, 93, 118, 112, 90, 108, 101, 111, 118, 106,
+  107, 109, 111, 104, 96, 72, 110, 93, 54, 157,
+  92, 104, 130, 87, 101, 84, 97, 86, 80, 96,
+  87, 113, 82, 79, 72, 113, 145, 82, 151, 110,
+  75, 156, 129, 134, 80, 105, 74, 115, 98, 99,
+  97, 124, 83, 105, 105, 89, 108, 92, 100, 110,
+  120, 128, 83, 122, 100, 97, 124, 140, 122, 99,
+  108, 121, 103, 87, 121, 116, 69, 68, 70, 93,
+  91, 137, 86, 100, 103, 144, 94, 98, 79, 98,
+  104, 99, 112, 136, 140, 103, 86, 147, 114, 103,
+  131, 118, 175, 120, 119, 83, 106, 124, 113, 94,
+  76, 75, 120, 82, 122, 116, 121, 106, 89, 67,
+  117, 102, 110, 78, 98, 116, 89, 84, 113, 110,
+  115, 105, 103, 80, 106, 132, 109, 115, 97, 111,
+  98, 87, 106, 101, 119, 145, 117, 143, 62, 90,
+  110, 87, 110, 110, 89, 102, 96, 116, 98, 128,
+  107, 113, 104, 97, 92, 102, 75, 76, 107, 99,
+  109, 92, 109, 135, 84, 112, 111, 110, 83, 125,
+  88, 100, 91, 133, 113, 115, 112, 96, 96, 124,
+  128, 108, 107, 88, 93, 106, 99, 108, 100, 114,
+  106, 104, 99, 113, 113, 96, 107, 63, 115, 89,
+  49, 125, 103, 96, 107, 72, 105, 88, 99, 89,
+  92, 97, 94, 101, 88, 93, 65, 97, 132, 66,
+  142, 98, 96, 164, 123, 125, 90, 118, 76, 120,
+  105, 97, 107, 125, 76, 111, 110, 101, 109, 115,
+  49, 90, 113, 130, 80, 145, 83, 90, 106, 120,
+  115, 110, 107, 123, 111, 73, 119, 114, 101, 83,
+  71, 81, 95, 127, 88, 98, 96, 149, 90, 97,
+  90, 91, 85, 89, 126, 105, 119, 88, 84, 152,
+  106, 92, 131, 97, 165, 116, 123, 89, 115, 127,
+  103, 113, 73, 72, 103, 90, 106, 120, 121, 129,
+  65, 56, 106, 105, 99, 65, 74, 100, 100, 105,
+  117, 111, 112, 110, 107, 72, 87, 135, 116, 123,
+  100, 102, 79, 120, 121, 109, 104, 140, 86, 114,
+  73, 85, 86, 91, 121, 128, 96, 119, 84, 93,
+  101, 121, 104, 124, 82, 71, 83, 111, 72, 70,
+  98, 95, 112, 103, 112, 154, 89, 114, 117, 109,
+  91, 127, 76, 91, 101, 109, 95, 107, 110, 92,
+  87, 118, 130, 124, 98, 110, 78, 104, 104, 103,
+  104, 137, 104, 92, 92, 110, 114, 101, 115, 71,
+  115, 98, 52, 117, 98, 91, 106, 64, 118, 80,
+  122, 88, 102, 84, 109, 87, 88, 97, 70, 97,
+  120, 54, 126, 98, 98, 166, 120, 121, 101, 140,
+  74, 115, 99, 130, 103, 117, 85, 108, 120, 109,
+  110, 123, 64, 99, 101, 123, 75, 137, 81, 89,
+  98, 96, 117, 106, 103, 131, 109, 56, 108, 115,
+  113, 90, 67, 77, 92, 121, 96, 97, 104, 118,
+  94, 94, 91, 93, 100, 84, 125, 104, 113, 97,
+  105, 131, 97, 90, 125, 72, 151, 110, 119, 117,
+  102, 134, 106, 111, 67, 80, 92, 100, 87, 124,
+  114, 129, 50, 46, 86, 103, 109, 64, 68, 97,
+  101, 103, 112, 105, 127, 111, 110, 67, 88, 134,
+  123, 124, 104, 91, 81, 132, 124, 111, 104, 135,
+  75, 89, 56, 99, 91, 94, 125, 124, 92, 111,
+  84, 86, 106, 113, 113, 109, 83, 59, 72, 113,
+  66, 94, 98, 85, 113, 107, 95, 138, 92, 126,
+  127, 98, 97, 97, 77, 92, 107, 122, 79, 113,
+  109, 95, 92, 121, 147, 158, 111, 123, 85, 121,
+  100, 109, 110, 167, 105, 95, 93, 104, 127, 116,
+  105, 81, 122, 93, 58, 145, 89, 102, 117, 75,
+  129, 71, 130, 95, 97, 66, 115, 97, 82, 88,
+  82, 114, 122, 45, 119, 118, 87, 164, 124, 128,
+  117, 114, 76, 105, 93, 144, 95, 101, 98, 139,
+  116, 121, 102, 111, 90, 118, 95, 134, 79, 107,
+  75, 93, 102, 96, 121, 99, 106, 137, 125, 63,
+  103, 118, 109, 96, 78, 97, 91, 144, 108, 95,
+  123, 97, 95, 100, 92, 101, 109, 99, 124, 125,
+  116, 113, 122, 119, 100, 78, 127, 87, 149, 110,
+  122, 130, 111, 139, 125, 101, 66, 79, 103, 98,
+  82, 143, 125, 106, 53, 51, 74, 94, 123, 62,
+  75, 98, 74, 73, 102, 111, 142, 115, 97, 62,
+  99, 137, 126, 128, 110, 96, 98, 140, 129, 112,
+  106, 143, 91, 101, 58, 115, 114, 100, 137, 114,
+  91, 87, 98, 98, 100, 106, 110, 112, 96, 46,
+  73, 105, 54, 88, 122, 82, 98, 110, 102, 122,
+  96, 129, 131, 104, 87, 79, 85, 105, 120, 150,
+  89, 117, 113, 79, 83, 120, 155, 168, 107, 116,
+  94, 114, 84, 112, 100, 166, 103, 113, 82, 105,
+  116, 126, 91, 79, 112, 88, 52, 163, 90, 129,
+  119, 83, 128, 63, 114, 101, 97, 55, 111, 102,
+  83, 89, 91, 123, 123, 39, 135, 118, 71, 153,
+  130, 120, 112, 104, 62, 87, 100, 136, 93, 101,
+  100, 163, 103, 116, 102, 100, 118, 119, 102, 151,
+  77, 94, 67, 92, 112, 97, 119, 99, 104, 137,
+  142, 86, 90, 117, 91, 110, 95, 94, 99, 168,
+  117, 76, 107, 94, 86, 88, 88, 120, 99, 116,
+  130, 140, 121, 99, 119, 112, 96, 81, 128, 96,
+  154, 136, 125, 119, 120, 140, 127, 88, 74, 88,
+  104, 87, 87, 146, 115, 94, 66, 71, 63, 99,
+  112, 68, 74, 100, 53, 71, 98, 108, 121, 112,
+  84, 53, 85, 127, 124, 122, 111, 101, 99, 131,
+  127, 102, 113, 128, 106, 125, 67, 105, 111, 90,
+  148, 112, 88, 73, 102, 93, 94, 112, 95, 107,
+  112, 32, 83, 102, 53, 79, 132, 91, 78, 109,
+  107, 132, 92, 123, 131, 110, 82, 83, 97, 111,
+  125, 180, 77, 108, 112, 64, 74, 107, 160, 163,
+  111, 107, 106, 103, 83, 107, 92, 162, 98, 144,
+  71, 110, 100, 129, 83, 79, 97, 79, 50, 154,
+  99, 155, 121, 89, 127, 61, 101, 109, 108, 63,
+  114, 112, 80, 84, 109, 126, 114, 65, 149, 117,
+  76, 141, 147, 105, 98, 114, 55, 74, 100, 139,
+  96, 101, 89, 151, 93, 105, 108, 94, 149, 125,
+  124, 141, 82, 104, 74, 91, 117, 91, 124, 91,
+  101, 144, 141, 103, 79, 120, 51, 126, 116, 112,
+  97, 185, 130, 74, 91, 100, 83, 75, 67, 128,
+  95, 126, 141, 147, 140, 104, 129, 110, 92, 118,
+  127, 85, 144, 150, 117, 113, 100, 132, 119, 77,
+  76, 108, 90, 71, 92, 147, 95, 90, 75, 80,
+  61, 101, 122, 56, 96, 101, 69, 79, 103, 80,
+  93, 105, 81, 51, 92, 104, 115, 104, 99, 101,
+  99, 122, 117, 88, 124, 126, 118, 150, 56, 117,
+  116, 78, 143, 107, 87, 63, 105, 97, 95, 115,
+  83, 83, 127, 27, 85, 102, 62, 74, 140, 86,
+  87, 112, 94, 126, 81, 129, 140, 103, 76, 84,
+  101, 111, 130, 195, 62, 101, 106, 64, 90, 88,
+  147, 150, 119, 74, 101, 96, 85, 96, 88, 161,
+  109, 167, 78, 112, 100, 119, 77, 78, 89, 80,
+  44, 152, 99, 166, 124, 92, 116, 75, 102, 117,
+  113, 65, 120, 124, 84, 92, 96, 116, 110, 88,
+  136, 119, 80, 113, 144, 94, 95, 101, 64, 71,
+  97, 166, 81, 107, 112, 158, 86, 106, 105, 97,
+  146, 132, 135, 134, 105, 114, 76, 92, 111, 93,
+  123, 90, 96, 134, 116, 105, 98, 110, 62, 134,
+  156, 131, 103, 183, 128, 76, 79, 101, 86, 72,
+  40, 133, 88, 125, 158, 137, 137, 135, 137, 120,
+  88, 108, 118, 115, 134, 139, 117, 123, 104, 122,
+  104, 75, 94, 131, 90, 53, 96, 144, 98, 100,
+  68, 95, 60, 96, 141, 56, 106, 92, 90, 85,
+  100, 72, 72, 109, 83, 50, 113, 94, 114, 96,
+  87, 103, 102, 141, 104, 96, 99, 115, 117, 164,
+  57, 145, 131, 70, 127, 107, 106, 50, 111, 100,
+  95, 99, 70, 78, 132, 26, 74, 101, 64, 56,
+  144, 68, 95, 114, 99, 110, 95, 131, 148, 93,
+  79, 79, 90, 108, 129, 185, 63, 100, 108, 70,
+  91, 84, 105, 124, 121, 55, 79, 52, 72, 87,
+  110, 151, 112, 169, 97, 106, 90, 96, 82, 74,
+  101, 119, 29, 129, 90, 130, 109, 83, 107, 97,
+  87, 123, 125, 98, 102, 114, 93, 76, 72, 97,
+  105, 109, 93, 86, 89, 106, 142, 89, 97, 87,
+  76, 78, 93, 202, 85, 143, 139, 135, 99, 105,
+  112, 117, 100, 126, 138, 120, 149, 125, 76, 104,
+  97, 93, 104, 93, 90, 125, 86, 100, 124, 84,
+  115, 130, 169, 127, 112, 167, 93, 69, 74, 98,
+  102, 77, 72, 141, 84, 107, 160, 92, 129, 129,
+  131, 121, 85, 81, 97, 145, 105, 114, 109, 159,
+  85, 113, 89, 76, 99, 125, 82, 59, 71, 118,
+  97, 94, 37, 132, 51, 105, 140, 107, 122, 84,
+  92, 92, 80, 97, 57, 104, 86, 63, 121, 113,
+  99, 107, 91, 87, 93, 171, 94, 121, 63, 95,
+  78, 121, 93, 142, 114, 84, 116, 91, 112, 60,
+  87, 107, 97, 92, 80, 104, 118, 57, 65, 97,
+  62, 86, 139, 51, 105, 126, 86, 111, 109, 123,
+  149, 73, 84, 70, 74, 98, 100, 153, 44, 103,
+  105, 79, 95, 102, 56, 102, 96, 112, 50, 27,
+  82, 94, 131, 104, 66, 143, 136, 111, 70, 88,
+  91, 95, 106, 165, 11, 79, 81, 69, 103, 68,
+  62, 94, 111, 100, 117, 113, 87, 88, 118, 62,
+  77, 54, 116, 121, 59, 54, 76, 107, 139, 106,
+  47, 82, 92, 55, 83, 156, 108, 127, 101, 87,
+  118, 66, 120, 130, 65, 84, 144, 101, 170, 150,
+  98, 113, 72, 76, 81, 102, 76, 70, 77, 88,
+  105, 74, 154, 132, 108, 88, 115, 133, 50, 80,
+  101, 99, 133, 69, 138, 111, 95, 84, 126, 57,
+  107, 106, 114, 111, 80, 74, 63, 134, 113, 91,
+  109, 144, 86, 103, 72, 82, 102, 69, 83, 70,
+  55, 104, 92, 77, 26, 130, 74, 101, 96, 143,
+  127, 62, 80, 104, 72, 122, 75, 75, 111, 94,
+  100, 92, 99, 132, 124, 78, 75, 169, 85, 124,
+  57, 108, 44, 69, 106, 85, 94, 98, 82, 66,
+  128, 111, 81, 105, 106, 96, 94, 164, 82, 73,
+  85, 88, 80, 121, 122, 84, 120, 126, 52, 101,
+  95, 99, 126, 64, 73, 70, 73, 84, 83, 104,
+  35, 77, 109, 114, 81, 114, 43, 105, 131, 145,
+  48, 62, 66, 112, 85, 102, 69, 104, 210, 108,
+  36, 104, 94, 104, 73, 140, 8, 66, 85, 51,
+  117, 72, 33, 70, 102, 88, 98, 93, 75, 96,
+  104, 68, 105, 44, 145, 114, 36, 90, 49, 110,
+  140, 143, 0, 82, 92, 40, 79, 109, 132, 93,
+  89, 72, 96, 60, 103, 116, 75, 82, 119, 81,
+  128, 175, 172, 108, 74, 84, 93, 94, 89, 43,
+  79, 82, 88, 79, 123, 127, 53, 84, 98, 130,
+  44, 143, 113, 113, 136, 71, 139, 104, 126, 67,
+  102, 55, 127, 72, 151, 114, 89, 83, 65, 97,
+  102, 79, 117, 84, 76, 95, 82, 75, 117, 58,
+  121, 88, 49, 123, 116, 65, 21, 94, 115, 104,
+  95, 123, 146, 46, 80, 115, 90, 121, 85, 75,
+  139, 113, 118, 87, 128, 198, 171, 102, 78, 166,
+  72, 135, 86, 110, 48, 69, 103, 69, 124, 102,
+  55, 96, 122, 112, 95, 127, 92, 93, 74, 125,
+  77, 81, 89, 80, 126, 98, 105, 107, 116, 117,
+  38, 109, 97, 95, 97, 82, 96, 88, 113, 72,
+  79, 75, 87, 55, 108, 138, 110, 120, 47, 106,
+  131, 87, 54, 88, 59, 125, 77, 105, 90, 99,
+  222, 112, 40, 94, 95, 53, 56, 104, 18, 78,
+  88, 35, 104, 72, 47, 57, 48, 99, 98, 100,
+  64, 127, 93, 96, 99, 44, 134, 101, 34, 154,
+  70, 103, 115, 148, 2, 107, 77, 86, 93, 101,
+  115, 124, 93, 73, 122, 61, 69, 95, 80, 88,
+  116, 94, 88, 180, 181, 126, 93, 95, 104, 82,
+  74, 32, 66, 81, 80, 95, 97, 109, 68, 99,
+  96, 136, 39, 153, 87, 122, 99, 69, 93, 91,
+  141, 59, 99, 57, 119, 74, 136, 127, 111, 89,
+  68, 113, 127, 61, 109, 80, 76, 89, 106, 87,
+  113, 63, 130, 107, 50, 127, 120, 83, 27, 85,
+  131, 96, 95, 72, 140, 75, 129, 155, 90, 102,
+  82, 55, 173, 132, 138, 105, 136, 202, 169, 113,
+  80, 143, 69, 131, 75, 100, 56, 67, 104, 51,
+  100, 96, 67, 129, 102, 106, 94, 115, 101, 78,
+  70, 135, 82, 78, 80, 136, 141, 77, 97, 133,
+  118, 102, 29, 160, 88, 84, 82, 82, 150, 108,
+  120, 51, 74, 66, 107, 84, 90, 151, 114, 123,
+  62, 101, 59, 97, 56, 108, 71, 115, 124, 116,
+  84, 106, 150, 145, 58, 77, 112, 55, 62, 98,
+  17, 99, 110, 28, 63, 69, 75, 69, 69, 110,
+  100, 121, 74, 101, 109, 94, 104, 43, 92, 97,
+  59, 140, 112, 80, 91, 106, 56, 149, 84, 138,
+  117, 120, 108, 149, 92, 109, 164, 86, 98, 130,
+  63, 71, 107, 102, 110, 191, 107, 109, 106, 79,
+  104, 97, 54, 51, 112, 74, 96, 109, 109, 115,
+  112, 67, 96, 102, 55, 107, 74, 138, 88, 70,
+  86, 102, 127, 74, 116, 53, 94, 61, 85, 127,
+  127, 103, 71, 91, 144, 85, 112, 109, 82, 97,
+  119, 109, 113, 101, 86, 113, 63, 110, 105, 133,
+  50, 91, 82, 115, 91, 70, 102, 93, 146, 172,
+  94, 48, 103, 45, 174, 124, 95, 91, 108, 135,
+  123, 121, 64, 127, 68, 111, 58, 115, 51, 72,
+  90, 50, 52, 105, 115, 124, 101, 105, 80, 78,
+  111, 63, 91, 161, 80, 84, 91, 134, 110, 86,
+  86, 117, 131, 112, 60, 181, 82, 79, 94, 68,
+  122, 117, 123, 55, 60, 55, 105, 98, 80, 131,
+  135, 117, 82, 107, 60, 92, 49, 120, 78, 114,
+  181, 162, 100, 134, 70, 149, 64, 60, 106, 66,
+  107, 72, 29, 137, 139, 41, 60, 91, 98, 92,
+  93, 127, 101, 115, 117, 110, 139, 89, 111, 53,
+  93, 132, 60, 140, 167, 68, 98, 116, 93, 135,
+  108, 105, 121, 178, 112, 121, 124, 107, 130, 119,
+  89, 140, 80, 76, 91, 120, 132, 190, 66, 79,
+  114, 73, 95, 74, 59, 95, 109, 67, 119, 116,
+  114, 132, 170, 79, 94, 94, 65, 81, 89, 132,
+  104, 77, 121, 152, 99, 104, 112, 57, 95, 79,
+  110, 121, 115, 115, 74, 118, 101, 156, 95, 151,
+  89, 92, 121, 127, 107, 135, 71, 133, 74, 127,
+  102, 133, 58, 80, 73, 144, 129, 89, 134, 51,
+  112, 117, 81, 85, 112, 72, 123, 122, 55, 86,
+  112, 141, 131, 112, 58, 160, 103, 111, 43, 136,
+  49, 101, 115, 103, 69, 122, 158, 95, 92, 93,
+  79, 97, 108, 66, 119, 192, 81, 89, 93, 93,
+  81, 75, 136, 110, 155, 115, 60, 163, 99, 87,
+  157, 84, 102, 107, 95, 113, 70, 76, 104, 89,
+  90, 94, 83, 102, 54, 87, 67, 95, 61, 116,
+  62, 84, 134, 134, 96, 97, 69, 114, 68, 47,
+  75, 93, 102, 143, 22, 76, 80, 63, 73, 94,
+  99, 90, 87, 90, 68, 107, 111, 121, 160, 129,
+  91, 67, 92, 108, 60, 100, 152, 73, 110, 109,
+  93, 93, 112, 87, 88, 144, 102, 95, 120, 104,
+  112, 109, 95, 112, 60, 72, 81, 84, 128, 135,
+  74, 71, 75, 85, 94, 123, 66, 120, 44, 89,
+  120, 106, 123, 106, 124, 102, 92, 78, 63, 108,
+  120, 89, 98, 86, 158, 172, 145, 123, 74, 53,
+  73, 61, 98, 90, 84, 95, 58, 125, 77, 159,
+  99, 123, 60, 90, 83, 131, 119, 99, 53, 127,
+  88, 87, 107, 112, 44, 71, 90, 118, 97, 143,
+  99, 43, 104, 135, 83, 135, 101, 92, 76, 97,
+  44, 90, 126, 124, 142, 72, 37, 157, 98, 114,
+  47, 116, 49, 70, 75, 85, 67, 123, 102, 111,
+  98, 107, 72, 97, 105, 100, 127, 128, 56, 87,
+  113, 156, 81, 122, 109, 79, 126, 111, 91, 145,
+  100, 98, 141, 100, 108, 113, 71, 121, 84, 80,
+  100, 78, 118, 91, 111, 103, 111, 115, 100, 128,
+  97, 72, 85, 91, 86, 119, 127, 67, 93, 93,
+  98, 74, 85, 114, 105, 110, 34, 128, 79, 79,
+  113, 98, 126, 108, 86, 94, 103, 130, 101, 100,
+  114, 87, 115, 97, 109, 97, 85, 67, 115, 121,
+  134, 122, 106, 110, 107, 126, 96, 133, 136, 80,
+  119, 80, 115, 110, 106, 83, 92, 115, 97, 93,
+  105, 111, 104, 91, 82, 131, 132, 108, 81, 119,
+  43, 93, 134, 90, 139, 100, 67, 120, 97, 85,
+  70, 131, 161, 80, 102, 103, 141, 166, 205, 117,
+  94, 112, 110, 125, 112, 103, 80, 120, 81, 64,
+  103, 108, 111, 111, 57, 96, 94, 122, 136, 85,
+  107, 124, 94, 90, 104, 92, 59, 71, 84, 77,
+  111, 105, 142, 102, 90, 103, 111, 99, 129, 120,
+  88, 83, 85, 118, 97, 95, 100, 88, 77, 87,
+  79, 104, 124, 122, 86, 111, 57, 135, 94, 93,
+  82, 112, 96, 79, 93, 120, 131, 103, 126, 105,
+  72, 138, 126, 169, 121, 132, 72, 86, 105, 115,
+  93, 106, 81, 126, 95, 98, 99, 99, 79, 94,
+  109, 96, 131, 105, 125, 111, 134, 98, 144, 148,
+  125, 110, 129, 91, 120, 120, 77, 108, 124, 107,
+  117, 83, 104, 89, 107, 76, 108, 67, 35, 147,
+  94, 120, 135, 109, 118, 102, 104, 91, 107, 141,
+  125, 102, 91, 66, 93, 103, 143, 110, 117, 115,
+  85, 165, 125, 130, 121, 106, 97, 131, 119, 105,
+  109, 116, 102, 91, 103, 99, 126, 80, 103, 128,
+  99, 102, 111, 137, 98, 111, 97, 161, 145, 61,
+  96, 148, 96, 106, 146, 99, 128, 91, 53, 115,
+  107, 117, 79, 126, 129, 135, 104, 111, 103, 133,
+  141, 129, 101, 130, 131, 159, 122, 113, 101, 97,
+  115, 98, 128, 105, 125, 71, 68, 97, 125, 118,
+  126, 79, 140, 97, 139, 97, 111, 94, 78, 77,
+  123, 90, 136, 88, 141, 137, 88, 71, 178, 131,
+  104, 124, 93, 78, 99, 121, 110, 102, 74, 100,
+  124, 74, 98, 99, 141, 112, 108, 141, 60, 149,
+  107, 83, 105, 97, 71, 85, 103, 135, 83, 100,
+  113, 90, 75, 129, 114, 83, 124, 51, 89, 80,
+  94, 126, 108, 107, 75, 155, 79, 88, 75, 114,
+  83, 102, 116, 94, 166, 122, 114, 113, 103, 105,
+  91, 127, 84, 117, 119, 120, 108, 105, 78, 95,
+  96, 111, 103, 90, 71, 77, 100, 42, 103, 96,
+  29, 106, 98, 101, 103, 78, 75, 93, 130, 68,
+  100, 115, 111, 83, 109, 113, 53, 76, 129, 90,
+  122, 113, 83, 166, 89, 119, 118, 125, 93, 139,
+  134, 89, 101, 133, 81, 86, 113, 74, 123, 128,
+  52, 82, 101, 82, 124, 151, 91, 107, 85, 127,
+  113, 119, 100, 121, 128, 87, 113, 76, 135, 82,
+  62, 75, 105, 102, 59, 114, 91, 151, 91, 97,
+  93, 86, 106, 82, 103, 97, 93, 129, 86, 93,
+  104, 52, 95, 120, 116, 93, 126, 69, 73, 95,
+  110, 118, 94, 48, 94, 83, 147, 106, 122, 125,
+  48, 80, 126, 125, 96, 79, 89, 103, 104, 115,
+  152, 127, 85, 86, 93, 90, 87, 120, 111, 122,
+  84, 85, 123, 123, 92, 99, 74, 104, 57, 80,
+  41, 94, 81, 97, 91, 102, 77, 116, 86, 94,
+  106, 70, 101, 120, 48, 67, 100, 73, 86, 88,
+  92, 88, 94, 134, 91, 142, 88, 130, 84, 75,
+  95, 132, 65, 90, 90, 51, 132, 112, 119, 116,
+  124, 120, 59, 123, 66, 122, 95, 127, 102, 119,
+  115, 136, 98, 100, 102, 98, 61, 81, 109, 42,
+  107, 75, 50, 126, 144, 97, 83, 80, 85, 107,
+  123, 111, 128, 83, 110, 67, 123, 127, 88, 77,
+  110, 70, 90, 110, 98, 153, 97, 116, 132, 109,
+  99, 135, 136, 118, 128, 84, 126, 108, 91, 112,
+  96, 143, 66, 103, 113, 122, 114, 125, 106, 90,
+  102, 107, 100, 126, 118, 117, 132, 69, 84, 78,
+  150, 87, 69, 62, 141, 131, 71, 100, 104, 121,
+  94, 80, 100, 89, 119, 68, 124, 100, 100, 116,
+  104, 98, 104, 73, 85, 99, 110, 100, 142, 107,
+  118, 92, 113, 116, 88, 79, 79, 97, 103, 135,
+  116, 146, 42, 76, 107, 139, 104, 69, 91, 64,
+  73, 96, 106, 120, 128, 100, 83, 123, 96, 147,
+  120, 152, 102, 93, 126, 168, 87, 100, 57, 123,
+  44, 82, 74, 101, 72, 117, 122, 101, 92, 90,
+  96, 87, 114, 59, 99, 130, 57, 29, 110, 78,
+  69, 107, 92, 105, 91, 151, 71, 183, 103, 119,
+  110, 60, 115, 130, 74, 84, 90, 64, 121, 94,
+  138, 110, 87, 123, 83, 127, 85, 114, 98, 114,
+  97, 133, 121, 157, 90, 68, 118, 100, 73, 98,
+  126, 93, 109, 107, 85, 140, 182, 112, 90, 102,
+  117, 121, 62, 146, 141, 98, 93, 104, 132, 115,
+  136, 109, 105, 41, 78, 97, 100, 120, 111, 124,
+  138, 91, 93, 117, 110, 145, 134, 81, 160, 123,
+  96, 133, 114, 129, 121, 152, 129, 131, 103, 116,
+  96, 89, 107, 103, 108, 149, 196, 137, 141, 112,
+  90, 79, 127, 79, 99, 99, 152, 163, 88, 99,
+  99, 86, 120, 91, 120, 102, 137, 96, 115, 131,
+  133, 92, 141, 117, 106, 117, 96, 110, 93, 129,
+  137, 128, 100, 90, 112, 101, 114, 119, 85, 109,
+  79, 148, 113, 168, 65, 117, 87, 144, 126, 109,
+  96, 69, 90, 109, 87, 117, 169, 130, 94, 119,
+  115, 176, 137, 168, 131, 102, 111, 174, 92, 119,
+  80, 110, 84, 107, 69, 113, 89, 111, 144, 117,
+  110, 69, 123, 108, 111, 86, 90, 94, 88, 66,
+  117, 109, 78, 116, 110, 105, 82, 140, 87, 170,
+  118, 131, 141, 81, 137, 120, 103, 83, 101, 110,
+  108, 114, 163, 107, 108, 113, 108, 135, 120, 111,
+  141, 102, 118, 117, 106, 108, 142, 137, 115, 111,
+  132, 111, 128, 119, 133, 95, 90, 94, 119, 124,
+  139, 107, 134, 84, 116, 126, 106, 148, 108, 71,
+  94, 115, 132, 111, 127, 96, 118, 79, 79, 118,
+  112, 97, 116, 111, 89, 143, 126, 108, 136, 155,
+  108, 83, 125, 93, 128, 135, 144, 147, 107, 101,
+  121, 116, 115, 104, 125, 135, 121, 106, 150, 137,
+  83, 121, 113, 94, 78, 122, 102, 128, 113, 123,
+  93, 120, 115, 134, 110, 111, 100, 123, 87, 112,
+  133, 128, 155, 114, 135, 120, 126, 90, 136, 116,
+  111, 97, 138, 98, 72, 107, 103, 95, 106, 107,
+  109, 113, 127, 123, 92, 106, 101, 121, 91, 106,
+  130, 113, 128, 129, 110, 139, 115, 74, 126, 109,
+  106, 155, 81, 120, 109, 106, 104, 116, 148, 85,
+  127, 102, 102, 102, 126, 116, 56, 105, 113, 99,
+  95, 97, 82, 103, 142, 103, 87, 104, 121, 108,
+  116, 127, 117, 97, 119, 97, 80, 106, 111, 110,
+  98, 110, 90, 146, 112, 106, 126, 101, 103, 85,
+  89, 97, 110, 108, 176, 100, 129, 99, 76, 116,
+  120, 111, 142, 124, 95, 107, 85, 119, 115, 117,
+  111, 109, 116, 94, 115, 127, 122, 99, 75, 67,
+  29, 113, 142, 86, 92, 80, 132, 81, 82, 111,
+  74, 96, 105, 93, 114, 78, 109, 133, 121, 54,
+  64, 166, 88, 97, 102, 121, 64, 97, 103, 114,
+  146, 159, 70, 91, 104, 90, 118, 142, 106, 107,
+  106, 97, 111, 99, 98, 95, 114, 113, 113, 111,
+  97, 134, 92, 97, 94, 95, 101, 101, 91, 138,
+  105, 135, 84, 111, 131, 137, 97, 81, 98, 110,
+  100, 97, 102, 113, 147, 120, 145, 117, 139, 85,
+  121, 142, 90, 109, 140, 91, 67, 109, 72, 95,
+  106, 98, 104, 100, 128, 156, 99, 82, 77, 127,
+  55, 127, 99, 128, 144, 66, 112, 122, 109, 76,
+  126, 100, 103, 185, 108, 76, 126, 128, 112, 93,
+  127, 123, 129, 90, 106, 138, 105, 105, 84, 64,
+  116, 87, 69, 103, 149, 131, 110, 81, 119, 99,
+  95, 126, 93, 76, 107, 102, 87, 140, 81, 89,
+  100, 106, 98, 86, 98, 133, 102, 97, 108, 97,
+  100, 95, 87, 92, 90, 129, 146, 97, 165, 123,
+  78, 97, 140, 126, 107, 111, 85, 122, 91, 144,
+  120, 131, 108, 116, 137, 87, 127, 75, 118, 100,
+  71, 93, 31, 111, 145, 94, 88, 104, 110, 78,
+  100, 112, 73, 126, 129, 80, 103, 94, 104, 130,
+  80, 140, 78, 191, 118, 129, 102, 110, 88, 76,
+  92, 128, 129, 94, 67, 97, 87, 93, 101, 112,
+  89, 81, 112, 122, 116, 121, 84, 111, 95, 94,
+  124, 85, 86, 123, 87, 107, 112, 82, 125, 68,
+  100, 124, 101, 147, 91, 101, 109, 116, 102, 76,
+  120, 106, 103, 103, 114, 81, 146, 115, 159, 126,
+  138, 111, 112, 171, 77, 109, 113, 99, 80, 104,
+  88, 112, 102, 122, 117, 97, 105, 175, 114, 74,
+  67, 107, 78, 122, 124, 86, 173, 63, 118, 75,
+  127, 174, 103, 121, 82, 202, 130, 76, 143, 155,
+  132, 88, 128, 169, 126, 101, 60, 113, 88, 126,
+  112, 88, 131, 98, 79, 112, 118, 125, 94, 105,
+  105, 103, 118, 138, 92, 64, 104, 113, 79, 82,
+  132, 90, 98, 91, 107, 75, 91, 128, 117, 117,
+  81, 91, 81, 109, 100, 102, 96, 115, 159, 70,
+  81, 115, 69, 88, 106, 155, 87, 90, 61, 97,
+  57, 75, 80, 77, 103, 104, 117, 88, 110, 104,
+  105, 135, 41, 60, 29, 92, 125, 75, 110, 92,
+  114, 66, 98, 107, 60, 105, 118, 117, 68, 80,
+  83, 83, 89, 83, 57, 163, 96, 104, 91, 117,
+  73, 95, 87, 93, 101, 73, 73, 99, 106, 65,
+  108, 124, 64, 73, 90, 99, 94, 84, 76, 94,
+  64, 80, 100, 146, 90, 110, 61, 104, 92, 84,
+  116, 67, 62, 73, 86, 129, 54, 88, 105, 109,
+  83, 68, 120, 108, 114, 93, 92, 70, 119, 75,
+  106, 100, 134, 69, 82, 124, 80, 104, 119, 85,
+  76, 101, 55, 99, 102, 105, 92, 94, 100, 136,
+  106, 89, 49, 86, 69, 105, 66, 93, 95, 78,
+  102, 104, 116, 142, 81, 104, 101, 177, 86, 79,
+  120, 123, 111, 82, 102, 130, 101, 88, 38, 89,
+  69, 82, 59, 52, 95, 79, 40, 121, 58, 103,
+  82, 58, 103, 103, 123, 100, 93, 58, 88, 144,
+  83, 113, 77, 74, 79, 93, 130, 92, 78, 127,
+  83, 96, 92, 77, 63, 79, 107, 91, 71, 83,
+  183, 91, 132, 92, 125, 132, 109, 134, 101, 114,
+  82, 115, 85, 108, 109, 71, 96, 94, 125, 106,
+  121, 96, 115, 75, 55, 107, 82, 98, 155, 96,
+  132, 96, 90, 134, 121, 101, 77, 77, 80, 104,
+  125, 110, 114, 106, 95, 84, 46, 151, 89, 107,
+  107, 127, 71, 84, 73, 104, 112, 68, 126, 74,
+  106, 96, 134, 112, 125, 145, 96, 133, 108, 99,
+  114, 72, 105, 128, 131, 98, 102, 119, 91, 80,
+  89, 105, 96, 80, 66, 119, 97, 152, 75, 93,
+  108, 76, 98, 80, 75, 96, 117, 93, 123, 125,
+  152, 131, 132, 113, 107, 105, 110, 53, 93, 96,
+  112, 99, 76, 105, 80, 98, 99, 105, 122, 95,
+  95, 128, 98, 89, 65, 89, 85, 105, 135, 76,
+  163, 91, 96, 81, 102, 81, 135, 121, 105, 158,
+  130, 106, 113, 107, 82, 109, 124, 106, 94, 99,
+  103, 105, 92, 134, 56, 132, 118, 76, 77, 86,
+  81, 47, 79, 103, 85, 102, 105, 91, 129, 104,
+  83, 114, 92, 72, 91, 86, 90, 95, 101, 96,
+  72, 160, 91, 63, 88, 82, 72, 89, 112, 110,
+  94, 95, 155, 81, 90, 89, 92, 132, 119, 83,
+  108, 134, 75, 108, 90, 113, 116, 96, 71, 100,
+  108, 88, 111, 96, 110, 88, 50, 110, 85, 104,
+  142, 89, 121, 87, 101, 110, 84, 96, 67, 90,
+  84, 96, 90, 116, 103, 123, 90, 76, 54, 121,
+  99, 128, 108, 91, 73, 94, 91, 103, 108, 131,
+  111, 76, 100, 90, 176, 148, 119, 150, 85, 141,
+  121, 90, 115, 82, 121, 122, 134, 100, 75, 116,
+  112, 86, 81, 108, 107, 85, 77, 129, 99, 136,
+  82, 81, 95, 124, 99, 91, 85, 76, 79, 105,
+  127, 124, 142, 139, 115, 119, 99, 96, 111, 142,
+  107, 105, 118, 99, 70, 102, 69, 115, 109, 97,
+  101, 95, 124, 98, 109, 102, 44, 94, 77, 118,
+  115, 130, 140, 86, 102, 118, 98, 75, 118, 121,
+  105, 99, 141, 93, 114, 114, 93, 109, 111, 99,
+  75, 87, 77, 100, 90, 111, 67, 95, 100, 72,
+  71, 77, 129, 65, 89, 90, 100, 95, 99, 112,
+  117, 81, 86, 95, 83, 90, 80, 80, 97, 80,
+  127, 116, 74, 131, 93, 72, 96, 94, 84, 106,
+  92, 121, 99, 132, 111, 84, 155, 114, 45, 90,
+  105, 117, 119, 129, 60, 124, 98, 127, 94, 88,
+  72, 97, 113, 63, 112, 94, 109, 79, 58, 83,
+  76, 100, 134, 99, 97, 115, 89, 82, 70, 137,
+  71, 121, 161, 92, 95, 111, 112, 112, 71, 107,
+  105, 133, 114, 132, 119, 122, 97, 100, 97, 116,
+  140, 151, 96, 101, 99, 98, 124, 143, 56, 80,
+  93, 125, 109, 131, 77, 115, 133, 97, 122, 133,
+  79, 97, 105, 100, 96, 90, 142, 74, 86, 96,
+  108, 125, 93, 83, 103, 136, 76, 112, 115, 96,
+  79, 102, 103, 76, 99, 117, 113, 114, 121, 108,
+  98, 127, 97, 136, 120, 96, 96, 114, 89, 122,
+  110, 109, 102, 115, 109, 107, 113, 65, 59, 85,
+  99, 123, 106, 113, 138, 90, 122, 107, 121, 126,
+  95, 125, 83, 101, 130, 97, 129, 151, 121, 77,
+  94, 128, 106, 113, 71, 115, 58, 77, 179, 73,
+  82, 113, 84, 111, 133, 128, 80, 99, 124, 104,
+  131, 165, 75, 87, 112, 103, 79, 121, 94, 86,
+  90, 80, 145, 128, 91, 88, 112, 76, 81, 91,
+  77, 119, 77, 108, 105, 135, 95, 78, 93, 106,
+  85, 102, 120, 168, 125, 105, 68, 120, 90, 126,
+  131, 90, 88, 87, 99, 90, 93, 134, 104, 126,
+  69, 121, 71, 108, 139, 93, 120, 128, 129, 77,
+  97, 149, 90, 117, 183, 94, 85, 118, 129, 106,
+  82, 117, 104, 120, 118, 120, 112, 134, 86, 89,
+  91, 145, 113, 82, 99, 87, 124, 95, 105, 96,
+  118, 119, 124, 107, 98, 138, 97, 116, 132, 85,
+  133, 125, 81, 111, 85, 115, 91, 89, 107, 56,
+  85, 111, 88, 115, 88, 109, 117, 108, 102, 118,
+  145, 106, 149, 104, 103, 72, 124, 110, 103, 111,
+  163, 123, 113, 119, 93, 124, 118, 107, 60, 118,
+  110, 123, 99, 132, 107, 127, 105, 98, 113, 105,
+  72, 96, 90, 94, 103, 93, 112, 129, 117, 101,
+  114, 136, 109, 117, 87, 89, 118, 114, 134, 136,
+  115, 93, 121, 98, 91, 110, 73, 102, 95, 98,
+  90, 83, 102, 110, 82, 155, 51, 121, 85, 80,
+  116, 118, 142, 117, 99, 109, 125, 120, 95, 135,
+  92, 103, 100, 90, 116, 111, 99, 91, 114, 112,
+  78, 82, 98, 81, 75, 97, 88, 124, 111, 90,
+  103, 91, 148, 149, 129, 129, 124, 124, 90, 117,
+  75, 119, 109, 104, 109, 90, 98, 110, 87, 145,
+  111, 96, 70, 148, 92, 100, 136, 99, 113, 96,
+  123, 81, 84, 127, 103, 111, 119, 78, 88, 115,
+  150, 92, 121, 99, 82, 139, 135, 119, 83, 133,
+  75, 101, 93, 108, 107, 113, 112, 115, 111, 101,
+  115, 79, 119, 124, 102, 107, 84, 128, 114, 92,
+  133, 115, 136, 105, 100, 126, 86, 100, 98, 112,
+  86, 61, 59, 119, 94, 133, 87, 130, 141, 123,
+  106, 108, 114, 108, 136, 100, 102, 113, 117, 119,
+  86, 117, 162, 114, 121, 90, 156, 125, 123, 75,
+  88, 126, 139, 98, 92, 102, 128, 110, 116, 99,
+  127, 97, 97, 65, 112, 90, 115, 89, 86, 152,
+  104, 94, 118, 86, 114, 118, 86, 80, 107, 107,
+  109, 110, 100, 104, 115, 85, 99, 105, 100, 151,
+  126, 128, 72, 86, 112, 80, 105, 135, 71, 97,
+  90, 105, 94, 146, 106, 103, 111, 107, 101, 120,
+  103, 111, 97, 110, 116, 101, 110, 119, 96, 110,
+  113, 112, 88, 100, 92, 86, 92, 111, 89, 120,
+  110, 85, 93, 116, 167, 144, 111, 95, 101, 121,
+  88, 109, 84, 117, 100, 111, 98, 115, 101, 110,
+  107, 79, 105, 99, 63, 147, 97, 86, 114, 81,
+  104, 75, 116, 78, 88, 95, 101, 106, 91, 94,
+  73, 104, 133, 80, 141, 108, 85, 166, 130, 116,
+  89, 136, 66, 128, 94, 97, 101, 140, 86, 121,
+  112, 100, 116, 103, 96, 100, 115, 134, 86, 136,
+  107, 89, 117, 121, 127, 105, 99, 124, 90, 72,
+  115, 108, 106, 75, 55, 91, 100, 127, 92, 108,
+  102, 130, 89, 102, 80, 103, 101, 91, 114, 135,
+  113, 110, 73, 135, 119, 109, 116, 90, 177, 105,
+  123, 92, 113, 122, 137, 108, 77, 70, 110, 97,
+  108, 111, 120, 94, 88, 51, 106, 102, 104, 58,
+  75, 120, 109, 111, 111, 103, 114, 113, 95, 74,
+  102, 125, 111, 112, 104, 105, 95, 105, 111, 100,
+  104, 158, 103, 125, 81, 71, 98, 92, 125, 120,
+  96, 115, 82, 87, 105, 143, 91, 123, 101, 67,
+  81, 119, 76, 96, 94, 104, 127, 98, 92, 148,
+  98, 108, 125, 117, 101, 106, 94, 104, 95, 131,
+  84, 108, 99, 90, 83, 128, 158, 140, 101, 124,
+  89, 117, 91, 108, 96, 147, 97, 106, 88, 111,
+  107, 117, 125, 71, 107, 101, 61, 143, 95, 88,
+  108, 80, 122, 73, 118, 88, 106, 84, 106, 105,
+  81, 75, 81, 102, 118, 59, 139, 99, 97, 178,
+  129, 111, 107, 114, 71, 122, 87, 131, 106, 116,
+  91, 135, 113, 110, 119, 112, 89, 102, 115, 133,
+  82, 123, 84, 94, 101, 99, 126, 105, 110, 142,
+  106, 76, 113, 107, 112, 82, 60, 87, 105, 132,
+  112, 87, 107, 117, 95, 96, 87, 98, 88, 91,
+  127, 126, 115, 99, 95, 123, 107, 97, 121, 80,
+  161, 105, 125, 117, 107, 130, 139, 105, 67, 83,
+  106, 96, 89, 128, 110, 104, 79, 47, 78, 102,
+  106, 53, 61, 107, 94, 93, 100, 117, 125, 125,
+  99, 65, 87, 123, 115, 123, 111, 100, 86, 126,
+  125, 104, 108, 152, 86, 104, 72, 96, 98, 98,
+  144, 127, 92, 113, 84, 77, 105, 120, 100, 103,
+  99, 51, 68, 103, 64, 78, 104, 90, 121, 106,
+  91, 135, 101, 115, 141, 122, 90, 70, 93, 107,
+  109, 144, 88, 101, 106, 82, 95, 122, 162, 164,
+  118, 134, 91, 119, 96, 102, 100, 179, 104, 105,
+  83, 106, 112, 122, 101, 86, 122, 96, 67, 151,
+  86, 110, 120, 88, 133, 79, 130, 90, 111, 74,
+  114, 108, 84, 67, 91, 117, 115, 53, 132, 115,
+  86, 166, 140, 117, 102, 102, 83, 102, 90, 148,
+  99, 102, 92, 154, 103, 116, 123, 110, 119, 118,
+  106, 132, 89, 97, 77, 85, 98, 86, 126, 97,
+  111, 143, 134, 109, 105, 110, 104, 84, 75, 90,
+  99, 143, 122, 94, 125, 107, 106, 89, 91, 97,
+  96, 111, 123, 130, 114, 125, 116, 105, 101, 95,
+  123, 98, 154, 119, 122, 125, 117, 137, 145, 97,
+  71, 90, 121, 88, 86, 140, 117, 89, 71, 57,
+  78, 103, 125, 68, 74, 108, 82, 67, 96, 117,
+  144, 122, 89, 64, 102, 121, 119, 126, 112, 91,
+  96, 125, 118, 108, 113, 155, 97, 106, 70, 127,
+  120, 99, 144, 116, 101, 94, 91, 99, 116, 108,
+  93, 92, 114, 48, 69, 101, 63, 98, 135, 81,
+  115, 110, 102, 116, 102, 130, 148, 116, 71, 74,
+  95, 111, 117, 167, 99, 108, 109, 71, 90, 114,
+  156, 181, 120, 108, 94, 123, 92, 103, 76, 193,
+  96, 108, 79, 99, 110, 116, 70, 96, 130, 100,
+  68, 159, 98, 132, 123, 100, 120, 83, 128, 104,
+  93, 64, 119, 109, 97, 74, 88, 135, 115, 51,
+  132, 130, 74, 146, 153, 115, 96, 83, 85, 88,
+  96, 119, 95, 93, 97, 172, 84, 113, 117, 105,
+  127, 119, 93, 162, 94, 82, 87, 75, 104, 93,
+  124, 102, 109, 145, 152, 139, 90, 106, 91, 97,
+  80, 94, 100, 163, 131, 109, 128, 108, 105, 81,
+  82, 104, 100, 130, 114, 133, 107, 124, 118, 100,
+  97, 83, 119, 112, 157, 129, 126, 110, 125, 142,
+  136, 94, 80, 92, 138, 76, 96, 136, 129, 78,
+  68, 77, 84, 98, 127, 70, 73, 98, 65, 58,
+  115, 121, 136, 117, 72, 57, 114, 124, 119, 136,
+  108, 94, 93, 128, 115, 112, 101, 149, 113, 120,
+  84, 126, 135, 93, 151, 108, 101, 67, 93, 108,
+  107, 115, 76, 97, 116, 35, 74, 102, 60, 103,
+  156, 74, 98, 101, 129, 127, 100, 132, 134, 112,
+  62, 93, 97, 104, 127, 186, 97, 102, 109, 62,
+  91, 105, 149, 174, 97, 107, 92, 118, 84, 103,
+  66, 187, 79, 108, 79, 95, 90, 113, 65, 97,
+  116, 81, 66, 159, 102, 133, 132, 105, 115, 77,
+  97, 112, 84, 60, 119, 107, 106, 81, 90, 142,
+  118, 33, 140, 114, 67, 130, 151, 108, 93, 109,
+  72, 89, 98, 99, 106, 104, 103, 172, 76, 103,
+  107, 104, 150, 123, 93, 179, 87, 85, 85, 80,
+  106, 91, 119, 101, 113, 136, 137, 147, 80, 97,
+  84, 108, 87, 99, 98, 171, 134, 110, 103, 99,
+  95, 73, 77, 121, 100, 121, 114, 131, 111, 100,
+  119, 96, 91, 95, 113, 93, 151, 142, 128, 104,
+  126, 146, 121, 86, 85, 99, 150, 71, 102, 133,
+  125, 82, 82, 92, 76, 107, 121, 64, 76, 101,
+  74, 69, 120, 114, 113, 106, 64, 48, 106, 126,
+  117, 135, 106, 93, 85, 122, 123, 103, 94, 120,
+  118, 120, 104, 109, 134, 80, 152, 108, 95, 53,
+  100, 105, 106, 123, 66, 103, 120, 36, 86, 107,
+  67, 100, 159, 95, 86, 87, 121, 131, 100, 123,
+  128, 113, 77, 95, 119, 97, 137, 208, 83, 109,
+  102, 68, 78, 106, 155, 159, 105, 112, 99, 117,
+  92, 94, 82, 179, 102, 121, 84, 103, 83, 128,
+  71, 94, 100, 78, 63, 146, 107, 125, 146, 105,
+  124, 72, 92, 116, 87, 64, 119, 112, 93, 79,
+  96, 146, 126, 46, 151, 117, 69, 117, 149, 110,
+  92, 120, 73, 82, 96, 96, 109, 112, 92, 161,
+  78, 103, 96, 100, 170, 129, 100, 162, 84, 92,
+  91, 84, 111, 95, 120, 87, 99, 126, 131, 149,
+  80, 94, 58, 117, 107, 130, 84, 162, 130, 104,
+  92, 94, 97, 77, 77, 110, 100, 123, 111, 139,
+  126, 106, 129, 98, 85, 125, 116, 100, 146, 148,
+  119, 108, 118, 148, 115, 76, 79, 104, 149, 70,
+  109, 137, 124, 80, 98, 96, 75, 117, 120, 64,
+  98, 109, 94, 71, 107, 95, 100, 94, 55, 49,
+  112, 114, 114, 121, 104, 92, 99, 112, 127, 95,
+  106, 120, 133, 130, 91, 111, 145, 80, 139, 104,
+  98, 73, 125, 125, 106, 139, 71, 95, 126, 42,
+  102, 112, 81, 82, 161, 111, 89, 71, 115, 116,
+  96, 121, 140, 122, 77, 84, 131, 104, 134, 218,
+  87, 122, 91, 79, 90, 105, 150, 137, 108, 93,
+  98, 112, 102, 91, 92, 159, 136, 165, 96, 112,
+  86, 140, 72, 90, 91, 70, 59, 146, 100, 113,
+  153, 97, 116, 71, 119, 122, 97, 70, 125, 121,
+  90, 107, 97, 137, 138, 65, 153, 108, 67, 99,
+  145, 102, 88, 110, 88, 88, 95, 100, 89, 115,
+  95, 181, 95, 101, 97, 102, 168, 126, 120, 160,
+  96, 95, 83, 91, 115, 106, 119, 99, 83, 114,
+  114, 140, 86, 101, 64, 131, 124, 138, 84, 154,
+  120, 93, 94, 96, 85, 77, 66, 110, 89, 126,
+  133, 137, 136, 117, 123, 103, 84, 121, 116, 121,
+  151, 161, 120, 110, 133, 151, 101, 73, 85, 117,
+  140, 72, 109, 143, 126, 87, 96, 86, 84, 108,
+  119, 58, 93, 105, 90, 97, 91, 75, 76, 87,
+  70, 55, 113, 107, 119, 107, 103, 93, 107, 121,
+  123, 95, 104, 127, 136, 157, 81, 124, 158, 86,
+  120, 116, 113, 77, 138, 116, 102, 135, 83, 87,
+  128, 39, 100, 109, 90, 81, 161, 114, 95, 78,
+  131, 118, 107, 114, 144, 125, 79, 82, 125, 107,
+  128, 205, 85, 95, 97, 87, 81, 115, 124, 132,
+  130, 73, 95, 74, 91, 83, 100, 148, 133, 181,
+  125, 124, 85, 131, 81, 83, 79, 79, 48, 149,
+  88, 89, 132, 90, 123, 73, 114, 129, 113, 89,
+  98, 127, 71, 94, 96, 126, 132, 85, 108, 84,
+  81, 96, 156, 99, 82, 116, 82, 106, 102, 164,
+  91, 147, 118, 154, 111, 108, 114, 117, 146, 130,
+  139, 123, 121, 120, 82, 116, 111, 105, 116, 87,
+  91, 119, 89, 111, 95, 93, 86, 151, 160, 143,
+  84, 164, 102, 87, 85, 107, 89, 82, 55, 130,
+  89, 103, 169, 116, 159, 108, 119, 116, 88, 119,
+  110, 123, 154, 132, 113, 133, 100, 139, 110, 66,
+  93, 128, 108, 61, 95, 122, 121, 95, 63, 100,
+  88, 114, 127, 81, 111, 107, 104, 121, 70, 71,
+  60, 95, 92, 58, 121, 134, 90, 109, 112, 100,
+  102, 138, 108, 126, 100, 131, 120, 126, 72, 117,
+  130, 93, 106, 115, 124, 70, 135, 134, 100, 123,
+  100, 85, 121, 61, 79, 114, 79, 105, 149, 95,
+  113, 106, 98, 133, 121, 118, 144, 109, 78, 92,
+  110, 109, 99, 181, 68, 89, 91, 119, 98, 152,
+  85, 109, 128, 91, 83, 38, 87, 80, 121, 129,
+  109, 170, 162, 135, 88, 116, 93, 69, 77, 113,
+  34, 122, 69, 44, 100, 76, 79, 90, 102, 109,
+  98, 92, 91, 96, 82, 82, 111, 88, 138, 126,
+  76, 75, 94, 93, 144, 113, 40, 101, 86, 114,
+  101, 195, 120, 151, 116, 123, 132, 100, 104, 127,
+  89, 106, 170, 99, 156, 131, 110, 127, 85, 93,
+  88, 93, 71, 88, 72, 80, 103, 93, 122, 156,
+  149, 109, 91, 134, 78, 85, 100, 102, 100, 83,
+  95, 121, 101, 68, 161, 97, 134, 112, 93, 120,
+  86, 97, 84, 130, 159, 79, 115, 150, 95, 137,
+  108, 74, 90, 96, 86, 66, 70, 110, 112, 75,
+  40, 129, 116, 132, 116, 123, 120, 89, 116, 126,
+  56, 90, 68, 79, 118, 85, 123, 114, 76, 118,
+  128, 107, 99, 144, 101, 140, 82, 128, 75, 86,
+  108, 106, 96, 106, 86, 93, 164, 99, 128, 133,
+  105, 105, 110, 131, 102, 85, 65, 110, 83, 123,
+  110, 107, 145, 128, 63, 122, 121, 102, 136, 90,
+  83, 85, 97, 91, 75, 124, 79, 97, 79, 141,
+  114, 163, 67, 102, 98, 113, 59, 57, 92, 80,
+  126, 114, 101, 136, 161, 137, 58, 93, 82, 56,
+  84, 141, 24, 94, 96, 21, 64, 55, 30, 80,
+  110, 87, 63, 78, 85, 75, 102, 76, 120, 48,
+  132, 113, 47, 101, 82, 86, 123, 114, 3, 82,
+  71, 124, 91, 153, 133, 120, 107, 119, 187, 104,
+  79, 119, 68, 91, 161, 90, 141, 169, 175, 103,
+  72, 79, 74, 107, 72, 51, 57, 57, 87, 97,
+  99, 131, 81, 63, 71, 90, 68, 101, 112, 97,
+  99, 81, 121, 136, 143, 34, 129, 88, 99, 56,
+  85, 127, 86, 70, 65, 95, 196, 62, 119, 131,
+  96, 119, 102, 103, 102, 59, 64, 125, 65, 104,
+  105, 64, 18, 93, 132, 117, 104, 112, 124, 59,
+  111, 159, 61, 100, 84, 53, 149, 95, 106, 88,
+  83, 143, 155, 131, 94, 150, 95, 140, 75, 102,
+  52, 59, 97, 76, 64, 115, 84, 104, 147, 90,
+  75, 80, 97, 94, 99, 166, 88, 69, 73, 98,
+  96, 99, 78, 123, 183, 137, 63, 127, 123, 90,
+  101, 70, 141, 93, 116, 58, 64, 53, 106, 69,
+  82, 136, 105, 142, 87, 100, 84, 104, 68, 99,
+  94, 105, 123, 140, 91, 102, 120, 136, 61, 66,
+  92, 59, 89, 114, 28, 130, 119, 39, 59, 70,
+  50, 59, 75, 115, 68, 91, 67, 94, 107, 66,
+  125, 49, 117, 97, 45, 141, 107, 104, 112, 120,
+  38, 82, 68, 133, 92, 158, 125, 116, 123, 134,
+  194, 130, 60, 98, 81, 96, 116, 105, 86, 182,
+  158, 85, 96, 79, 88, 74, 78, 61, 62, 63,
+  96, 114, 99, 120, 75, 64, 72, 103, 74, 118,
+  99, 106, 104, 66, 99, 134, 170, 43, 113, 99,
+  100, 61, 93, 119, 101, 96, 64, 87, 190, 67,
+  111, 163, 93, 113, 114, 124, 99, 69, 75, 147,
+  52, 109, 108, 73, 33, 60, 101, 75, 116, 69,
+  144, 67, 111, 141, 85, 95, 132, 66, 163, 111,
+  90, 101, 78, 146, 138, 128, 102, 147, 82, 132,
+  78, 103, 59, 81, 97, 71, 65, 100, 130, 118,
+  108, 73, 57, 65, 84, 77, 98, 174, 95, 52,
+  85, 120, 83, 80, 80, 116, 170, 153, 70, 156,
+  105, 78, 87, 50, 167, 96, 137, 52, 62, 32,
+  121, 93, 72, 103, 116, 128, 104, 122, 84, 107,
+  78, 137, 100, 126, 122, 196, 92, 109, 82, 117,
+  82, 66, 110, 78, 127, 85, 31, 194, 110, 87,
+  82, 88, 122, 45, 75, 138, 124, 104, 86, 112,
+  126, 89, 113, 93, 97, 113, 59, 133, 126, 99,
+  128, 120, 112, 84, 78, 118, 106, 186, 97, 114,
+  143, 172, 157, 158, 86, 121, 117, 121, 99, 126,
+  101, 142, 100, 106, 129, 80, 102, 95, 82, 112,
+  113, 92, 130, 130, 112, 143, 129, 99, 82, 123,
+  104, 86, 80, 112, 102, 79, 96, 144, 130, 88,
+  130, 96, 106, 81, 95, 111, 122, 141, 87, 104,
+  131, 130, 110, 168, 85, 124, 144, 113, 103, 119,
+  89, 109, 54, 131, 100, 118, 52, 67, 59, 105,
+  139, 71, 117, 92, 99, 85, 110, 94, 147, 113,
+  135, 106, 95, 90, 89, 130, 102, 112, 109, 146,
+  92, 113, 89, 136, 79, 118, 100, 95, 101, 102,
+  174, 107, 107, 70, 97, 95, 97, 44, 94, 147,
+  105, 52, 106, 100, 61, 94, 103, 88, 120, 150,
+  96, 148, 110, 83, 94, 68, 126, 92, 135, 92,
+  55, 78, 141, 120, 73, 93, 107, 137, 94, 119,
+  129, 88, 77, 136, 88, 136, 118, 211, 129, 145,
+  72, 115, 97, 84, 112, 90, 121, 73, 37, 215,
+  114, 95, 103, 115, 146, 78, 87, 142, 128, 96,
+  124, 149, 137, 118, 110, 129, 116, 139, 54, 131,
+  106, 78, 139, 107, 125, 89, 114, 90, 113, 211,
+  100, 123, 151, 170, 103, 163, 79, 121, 139, 123,
+  77, 106, 130, 124, 63, 117, 133, 79, 113, 99,
+  76, 154, 96, 113, 139, 120, 121, 152, 174, 140,
+  94, 126, 110, 73, 91, 109, 114, 89, 111, 171,
+  97, 122, 135, 79, 114, 94, 110, 106, 125, 142,
+  104, 157, 108, 207, 94, 109, 91, 123, 158, 117,
+  104, 155, 99, 95, 68, 145, 126, 123, 61, 74,
+  99, 170, 153, 92, 113, 79, 106, 75, 97, 128,
+  112, 155, 92, 96, 86, 68, 100, 144, 129, 103,
+  113, 162, 100, 126, 65, 137, 93, 141, 88, 125,
+  135, 98, 151, 95, 124, 70, 125, 140, 96, 61,
+  120, 105, 105, 68, 100, 118, 67, 83, 158, 97,
+  83, 122, 94, 139, 123, 97, 132, 112, 111, 110,
+  103, 114, 68, 134, 143, 112, 85, 81, 89, 154,
+  65, 96, 109, 75, 76, 91, 74, 92, 110, 146,
+  96, 110, 98, 100, 81, 85, 70, 80, 107, 108,
+  31, 116, 63, 61, 89, 99, 120, 88, 71, 96,
+  94, 102, 111, 134, 146, 162, 82, 115, 100, 107,
+  67, 95, 90, 77, 122, 79, 99, 95, 104, 122,
+  99, 154, 106, 113, 131, 122, 102, 105, 92, 110,
+  81, 96, 100, 68, 136, 91, 84, 112, 75, 96,
+  93, 156, 80, 123, 24, 111, 110, 106, 134, 126,
+  141, 120, 96, 103, 87, 78, 105, 71, 86, 104,
+  148, 166, 155, 110, 87, 60, 92, 94, 84, 91,
+  93, 81, 70, 146, 124, 138, 108, 98, 78, 113,
+  110, 126, 120, 107, 64, 88, 83, 100, 124, 90,
+  37, 80, 105, 138, 97, 137, 96, 79, 109, 140,
+  77, 120, 109, 104, 97, 78, 63, 88, 110, 121,
+  134, 85, 63, 145, 78, 124, 68, 100, 80, 81,
+  68, 88, 104, 104, 80, 107, 127, 108, 85, 117,
+  103, 93, 142, 116, 70, 95, 96, 193, 77, 121,
+  125, 90, 79, 99, 105, 132, 116, 106, 107, 108,
+  111, 103, 74, 104, 87, 131, 118, 90, 109, 107,
+  125, 126, 104, 118, 112, 120, 109, 67, 95, 97,
+  116, 115, 118, 86, 105, 105, 95, 86, 86, 101,
+  114, 103, 39, 132, 91, 73, 121, 95, 116, 102,
+  95, 94, 103, 138, 109, 93, 117, 89, 112, 102,
+  123, 86, 95, 84, 87, 128, 105, 97, 111, 117,
+  92, 147, 121, 115, 145, 95, 118, 86, 113, 96,
+  108, 93, 87, 110, 112, 87, 127, 124, 108, 102,
+  84, 131, 123, 104, 94, 109, 49, 92, 129, 92,
+  144, 102, 84, 110, 108, 91, 81, 106, 133, 104,
+  97, 104, 147, 154, 211, 103, 102, 99, 115, 139,
+  107, 112, 98, 90, 91, 69, 128, 105, 119, 111,
+  94, 108, 101, 130, 133, 87, 116, 98, 108, 86,
+  116, 70, 57, 81, 97, 90, 112, 117, 163, 115,
+  90, 96, 127, 115, 136, 102, 109, 85, 95, 127,
+  94, 95, 87, 94, 93, 96, 73, 114, 119, 98,
+  93, 110, 63, 156, 101, 90, 72, 101, 99, 90,
+  73, 113, 112, 94, 153, 120, 75, 145, 117, 161,
+  114, 115, 90, 91, 97, 98, 97, 101, 90, 138,
+  84, 83, 88, 91, 80, 85, 110, 108, 152, 105,
+  115, 121, 98, 97, 99, 126, 116, 109, 126, 97,
+  119, 111, 99, 95, 129, 112, 110, 95, 82, 84,
+  98, 75, 107, 95, 28, 119, 107, 102, 124, 94,
+  96, 101, 130, 85, 95, 133, 118, 82, 94, 86,
+  74, 88, 143, 92, 117, 116, 85, 154, 91, 119,
+  121, 116, 100, 132, 121, 81, 115, 135, 89, 79,
+  117, 87, 128, 116, 76, 106, 95, 86, 119, 155,
+  107, 105, 93, 141, 124, 86, 88, 118, 100, 85,
+  127, 94, 131, 85, 59, 92, 115, 101, 65, 132,
+  121, 144, 101, 97, 102, 105, 136, 106, 94, 102,
+  120, 151, 108, 105, 105, 72, 110, 106, 133, 100,
+  124, 90, 72, 102, 103, 123, 110, 64, 118, 91,
+  152, 99, 118, 93, 58, 79, 125, 107, 111, 90,
+  124, 113, 99, 113, 154, 119, 97, 98, 96, 82,
+  81, 132, 105, 111, 78, 92, 132, 109, 89, 103,
+  105, 99, 85, 109, 46, 131, 94, 90, 89, 102,
+  64, 111, 92, 107, 92, 105, 131, 113, 59, 102,
+  105, 79, 109, 71, 92, 87, 107, 108, 105, 126,
+  82, 145, 88, 80, 80, 106, 65, 94, 105, 69,
+  151, 115, 119, 105, 105, 110, 60, 113, 74, 111,
+  101, 119, 100, 104, 95, 107, 92, 97, 94, 103,
+  73, 76, 94, 49, 100, 91, 40, 108, 112, 89,
+  85, 75, 77, 98, 147, 86, 109, 97, 109, 70,
+  112, 124, 62, 71, 116, 76, 101, 94, 97, 150,
+  88, 117, 122, 114, 99, 137, 126, 108, 113, 101,
+  108, 92, 95, 97, 105, 139, 48, 80, 98, 100,
+  114, 134, 96, 104, 81, 104, 102, 131, 97, 109,
+  122, 65, 95, 77, 153, 96, 51, 65, 123, 106,
+  55, 114, 103, 131, 86, 84, 94, 91, 121, 68,
+  92, 92, 84, 119, 94, 99, 105, 51, 81, 106,
+  116, 91, 116, 96, 103, 87, 101, 118, 88, 57,
+  82, 95, 124, 112, 117, 120, 42, 73, 112, 127,
+  89, 67, 80, 77, 81, 106, 111, 110, 117, 90,
+  86, 106, 86, 138, 112, 135, 91, 81, 121, 155,
+  83, 100, 59, 121, 41, 75, 66, 101, 72, 107,
+  99, 112, 81, 106, 87, 78, 116, 69, 99, 129,
+  56, 40, 97, 82, 74, 112, 77, 96, 101, 131,
+  83, 166, 99, 121, 109, 62, 98, 118, 46, 89,
+  82, 51, 117, 95, 149, 101, 109, 115, 70, 123,
+  79, 116, 85, 122, 80, 117, 105, 142, 95, 90,
+  106, 103, 78, 86, 104, 44, 92, 78, 57, 125,
+  132, 99, 86, 86, 99, 111, 109, 139, 129, 69,
+  98, 75, 126, 119, 103, 79, 100, 58, 75, 106,
+  98, 131, 105, 105, 129, 90, 75, 118, 112, 139,
+  122, 57, 168, 118, 77, 140, 94, 126, 89, 133,
+  105, 134, 104, 104, 106, 77, 102, 98, 108, 142,
+  123, 125, 129, 64, 69, 83, 128, 93, 70, 72,
+  134, 153, 74, 92, 105, 69, 93, 70, 92, 120,
+  136, 79, 110, 125, 116, 98, 130, 110, 107, 91,
+  83, 73, 80, 109, 130, 129, 114, 83, 102, 97,
+  102, 103, 76, 106, 85, 126, 98, 136, 50, 85,
+  83, 120, 109, 67, 88, 54, 55, 89, 78, 120,
+  143, 117, 85, 117, 104, 158, 121, 156, 103, 97,
+  104, 171, 81, 96, 73, 114, 45, 110, 72, 116,
+  82, 117, 113, 92, 81, 48, 103, 69, 98, 63,
+  92, 94, 76, 30, 91, 84, 64, 96, 69, 96,
+  75, 149, 70, 162, 115, 131, 121, 59, 128, 94,
+  75, 90, 96, 89, 102, 86, 162, 103, 93, 106,
+  100, 133, 96, 115, 99, 102, 92, 126, 115, 146,
+  90, 77, 113, 105, 94, 101, 106, 92, 98, 106,
+  92, 129, 155, 105, 102, 108, 129, 127, 47, 157,
+  132, 95, 89, 111, 127, 85, 137, 108, 100, 38,
+  80, 90, 103, 109, 108, 112, 119, 93, 80, 101,
+  95, 150, 129, 86, 167, 114, 100, 127, 124, 113,
+  139, 170, 129, 126, 105, 109, 97, 85, 97, 100,
+  115, 122, 192, 124, 130, 104, 70, 102, 103, 78,
+  106, 112, 140, 174, 94, 91, 102, 66, 119, 81,
+  112, 105, 145, 98, 113, 141, 150, 99, 150, 120,
+  101, 120, 104, 109, 93, 111, 129, 140, 101, 79,
+  96, 91, 127, 128, 83, 117, 81, 133, 93, 130,
+  74, 131, 74, 119, 126, 109, 115, 75, 111, 117,
+  76, 108, 162, 116, 105, 115, 127, 160, 128, 159,
+  117, 108, 100, 157, 96, 105, 85, 93, 88, 132,
+  65, 118, 95, 98, 115, 94, 109, 38, 116, 95,
+  123, 96, 94, 90, 102, 74, 100, 118, 86, 102,
+  103, 107, 83, 137, 79, 131, 110, 148, 143, 75,
+  135, 92, 99, 81, 118, 124, 105, 122, 155, 104,
+  109, 112, 103, 132, 122, 113, 136, 107, 113, 124,
+  104, 110, 130, 128, 111, 115, 132, 106, 122, 121,
+  141, 87, 89, 96, 119, 124, 135, 109, 138, 87,
+  114, 118, 105, 149, 102, 69, 90, 112, 138, 107,
+  135, 92, 119, 81, 83, 129, 119, 104, 107, 114,
+  79, 141, 130, 105, 139, 159, 106, 83, 115, 97,
+  131, 140, 136, 139, 98, 99, 121, 118, 109, 106,
+  123, 129, 125, 101, 160, 134, 81, 119, 108, 95,
+  79, 120, 104, 123, 110, 127, 97, 118, 112, 147,
+  109, 110, 102, 121, 83, 118, 138, 120, 159, 103,
+  139, 129, 133, 89, 137, 115, 118, 104, 139, 90,
+  66, 109, 103, 101, 109, 125, 108, 111, 121, 122,
+  97, 104, 101, 115, 86, 109, 119, 111, 123, 120,
+  111, 130, 122, 73, 125, 113, 106, 159, 73, 120,
+  111, 110, 111, 115, 130, 92, 131, 110, 109, 110,
+  129, 116, 55, 100, 112, 94, 98, 93, 82, 112,
+  137, 103, 88, 111, 119, 114, 113, 125, 114, 94,
+  119, 98, 83, 97, 112, 103, 101, 111, 87, 142,
+  113, 109, 126, 106, 106, 81, 97, 103, 107, 101,
+  165, 99, 135, 101, 76, 112, 122, 112, 135, 125,
+  91, 118, 90, 126, 109, 114, 106, 116, 123, 95,
+  114, 126, 133, 99, 80, 69, 29, 110, 143, 89,
+  98, 81, 133, 75, 83, 103, 80, 98, 104, 102,
+  123, 78, 119, 128, 123, 68, 69, 174, 89, 109,
+  100, 132, 63, 99, 107, 115, 147, 157, 66, 94,
+  102, 91, 122, 144, 106, 100, 106, 106, 109, 96,
+  101, 93, 120, 106, 119, 111, 99, 131, 83, 93,
+  90, 99, 99, 105, 100, 139, 104, 133, 90, 110,
+  122, 143, 99, 82, 98, 109, 95, 102, 106, 107,
+  150, 118, 151, 131, 146, 90, 123, 139, 95, 119,
+  141, 92, 69, 110, 75, 105, 111, 116, 106, 100,
+  116, 157, 99, 76, 81, 125, 56, 133, 96, 118,
+  141, 58, 121, 115, 117, 83, 128, 107, 103, 190,
+  109, 76, 130, 135, 125, 92, 114, 129, 133, 101,
+  111, 142, 109, 106, 86, 70, 122, 92, 74, 105,
+  149, 142, 106, 86, 120, 105, 96, 129, 91, 76,
+  101, 104, 90, 134, 85, 83, 104, 96, 98, 90,
+  100, 130, 109, 102, 109, 99, 102, 93, 99, 102,
+  88, 133, 138, 98, 157, 128, 80, 95, 137, 128,
+  97, 110, 88, 120, 97, 150, 123, 134, 106, 122,
+  139, 91, 123, 80, 125, 104, 74, 92, 35, 106,
+  144, 99, 95, 103, 116, 75, 95, 100, 79, 129,
+  125, 83, 108, 95, 108, 127, 83, 141, 80, 185,
+  118, 131, 105, 113, 94, 75, 88, 131, 126, 92,
+  67, 98, 91, 93, 107, 107, 91, 83, 112, 127,
+  112, 115, 85, 104, 101, 89, 126, 85, 81, 124,
+  87, 104, 109, 84, 122, 66, 103, 126, 97, 140,
+  96, 99, 109, 114, 106, 79, 121, 106, 107, 104,
+  115, 82, 143, 113, 159, 132, 134, 112, 109, 170,
+  85, 114, 114, 102, 76, 101, 86, 118, 105, 129,
+  115, 99, 102, 172, 113, 74, 69, 107, 80, 122,
+  119, 85, 162, 56, 118, 82, 121, 172, 107, 120,
+  77, 194, 126, 75, 141, 156, 139, 89, 119, 170,
+  124, 104, 59, 112, 89, 125, 103, 97, 135, 105,
+  78, 121, 114, 130, 89, 106, 107, 103, 121, 137,
+  90, 61, 99, 117, 79, 85, 131, 84, 103, 87,
+  108, 78, 96, 128, 126, 119, 84, 86, 80, 104,
+  106, 112, 97, 119, 155, 65, 83, 116, 75, 89,
+  110, 150, 83, 83, 69, 93, 64, 81, 89, 83,
+  105, 110, 119, 86, 100, 109, 113, 138, 41, 62,
+  32, 93, 123, 79, 115, 91, 121, 58, 93, 103,
+  64, 105, 121, 113, 73, 79, 82, 84, 92, 80,
+  59, 159, 100, 99, 89, 114, 76, 91, 86, 102,
+  100, 73, 80, 102, 101, 62, 108, 117, 69, 76,
+  89, 108, 91, 81, 75, 88, 63, 81, 104, 147,
+  86, 113, 70, 104, 94, 80, 113, 70, 66, 71,
+  88, 127, 59, 85, 110, 101, 89, 67, 122, 113,
+  124, 94, 88, 75, 112, 85, 106, 109, 122, 69,
+  74, 121, 87, 107, 119, 85, 75, 99, 57, 102,
+  108, 110, 92, 96, 101, 127, 111, 82, 52, 91,
+  67, 94, 67, 99, 97, 77, 95, 105, 109, 139,
+  84, 102, 91, 167, 76, 75, 112, 118, 108, 78,
+  94, 127, 95, 86, 46, 95, 69, 89, 62, 62,
+  96, 81, 39, 127, 60, 99, 78, 61, 109, 107,
+  122, 103, 89, 52, 88, 149, 83, 121, 76, 72,
+  87, 89, 134, 90, 80, 129, 92, 93, 96, 72,
+  59, 73, 110, 96, 64, 81, 182, 79, 121, 87,
+  136, 132, 123, 124, 98, 108, 82, 110, 71, 112,
+  105, 74, 95, 90, 120, 94, 112, 96, 114, 82,
+  50, 105, 77, 106, 148, 101, 139, 96, 93, 118,
+  113, 101, 81, 81, 86, 91, 123, 106, 107, 111,
+  95, 83, 54, 153, 101, 100, 99, 125, 62, 80,
+  70, 109, 113, 71, 138, 77, 94, 95, 139, 106,
+  126, 153, 99, 132, 112, 97, 105, 66, 84, 127,
+  133, 94, 107, 126, 93, 83, 91, 98, 98, 80,
+  60, 128, 102, 160, 83, 96, 115, 68, 104, 73,
+  75, 107, 124, 97, 121, 126, 146, 135, 129, 123,
+  98, 101, 95, 60, 94, 102, 110, 92, 61, 102,
+  84, 98, 106, 114, 121, 88, 96, 119, 106, 84,
+  61, 87, 85, 100, 142, 75, 166, 92, 91, 79,
+  104, 87, 134, 125, 92, 143, 126, 105, 106, 104,
+  74, 102, 108, 107, 90, 92, 108, 116, 96, 142,
+  54, 140, 118, 71, 74, 82, 82, 30, 71, 103,
+  82, 108, 97, 84, 124, 101, 80, 116, 87, 68,
+  89, 79, 91, 92, 107, 95, 68, 171, 87, 61,
+  87, 79, 73, 73, 120, 112, 86, 98, 162, 62,
+  97, 79, 95, 138, 124, 98, 110, 116, 76, 101,
+  73, 120, 105, 98, 76, 91, 116, 80, 109, 107,
+  107, 96, 45, 115, 79, 107, 134, 90, 124, 90,
+  98, 95, 77, 100, 69, 95, 99, 90, 90, 106,
+  97, 123, 93, 70, 52, 130, 121, 122, 92, 105,
+  64, 95, 88, 103, 114, 128, 124, 97, 92, 83,
+  191, 149, 122, 152, 96, 148, 127, 83, 111, 88,
+  99, 124, 135, 99, 80, 116, 108, 95, 84, 94,
+  124, 78, 75, 128, 111, 149, 90, 85, 94, 118,
+  103, 81, 82, 73, 79, 100, 133, 119, 129, 146,
+  107, 126, 96, 101, 94, 139, 106, 103, 120, 99,
+  74, 101, 74, 107, 116, 101, 111, 86, 116, 104,
+  114, 87, 37, 101, 77, 126, 120, 135, 140, 89,
+  105, 116, 107, 85, 102, 126, 106, 93, 149, 90,
+  109, 112, 91, 99, 100, 105, 73, 81, 78, 97,
+  91, 116, 78, 103, 101, 69, 63, 71, 130, 44,
+  78, 94, 110, 97, 88, 111, 117, 76, 74, 88,
+  84, 95, 85, 75, 94, 77, 139, 123, 73, 138,
+  90, 65, 90, 84, 83, 86, 94, 112, 94, 137,
+  113, 73, 133, 115, 46, 106, 137, 141, 126, 99,
+  73, 118, 89, 151, 88, 101, 83, 97, 123, 77,
+  121, 112, 104, 90, 58, 95, 68, 95, 131, 99,
+  103, 127, 93, 80, 83, 134, 60, 134, 160, 85,
+  98, 103, 105, 119, 73, 107, 102, 138, 151, 134,
+  103, 134, 99, 100, 93, 116, 140, 154, 96, 113,
+  92, 92, 131, 147, 81, 91, 106, 120, 108, 120,
+  87, 125, 117, 95, 120, 132, 90, 97, 109, 108,
+  100, 86, 148, 66, 97, 86, 121, 149, 104, 87,
+  114, 137, 90, 106, 120, 87, 77, 109, 109, 67,
+  107, 131, 126, 105, 117, 122, 97, 119, 93, 114,
+  116, 109, 98, 116, 96, 111, 103, 113, 111, 116,
+  92, 131, 126, 57, 50, 104, 89, 124, 121, 126,
+  140, 85, 132, 105, 118, 134, 85, 128, 100, 81,
+  135, 93, 138, 158, 136, 83, 98, 135, 96, 112,
+  87, 107, 69, 83, 157, 93, 103, 110, 81, 106,
+  117, 125, 86, 127, 131, 111, 120, 149, 80, 78,
+  102, 96, 80, 138, 122, 79, 94, 78, 146, 130,
+  95, 89, 121, 87, 82, 76, 71, 119, 85, 93,
+  95, 120, 91, 78, 111, 115, 84, 111, 161, 143,
+  138, 103, 81, 114, 97, 153, 110, 108, 98, 93,
+  116, 105, 115, 125, 102, 132, 75, 117, 74, 92,
+  136, 97, 116, 125, 118, 78, 114, 144, 86, 138,
+  162, 99, 87, 106, 125, 109, 85, 125, 103, 132,
+  149, 138, 93, 128, 109, 94, 83, 135, 116, 96,
+  82, 98, 120, 89, 100, 101, 135, 119, 130, 92,
+  96, 144, 103, 122, 119, 78, 129, 119, 84, 97,
+  92, 109, 92, 96, 103, 60, 110, 130, 105, 139,
+  101, 105, 122, 120, 102, 102, 143, 100, 153, 115,
+  107, 60, 146, 117, 122, 102, 161, 138, 125, 132,
+  91, 114, 112, 136, 76, 124, 113, 118, 83, 139,
+  109, 119, 88, 129, 135, 84, 68, 100, 83, 87,
+  124, 81, 127, 114, 147, 109, 103, 142, 115, 117,
+  107, 78, 125, 114, 150, 146, 133, 103, 130, 109,
+  91, 107, 72, 100, 106, 98, 74, 105, 117, 107,
+  81, 151, 67, 132, 85, 109, 123, 127, 113, 129,
+  106, 98, 117, 140, 97, 138, 131, 109, 128, 92,
+  104, 117, 98, 91, 144, 120, 87, 79, 93, 93,
+  84, 89, 82, 112, 90, 87, 103, 104, 147, 134,
+  134, 130, 128, 144, 87, 105, 78, 127, 109, 101,
+  106, 98, 110, 116, 103, 147, 103, 127, 70, 132,
+  87, 91, 129, 83, 105, 75, 136, 72, 89, 119,
+  107, 113, 118, 96, 79, 100, 135, 81, 124, 86,
+  78, 141, 142, 107, 76, 135, 88, 119, 75, 88,
+  100, 122, 96, 141, 123, 93, 120, 93, 131, 105,
+  106, 107, 89, 130, 116, 99, 123, 100, 128, 117,
+  91, 106, 77, 90, 99, 102, 94, 81, 60, 135,
+  108, 125, 98, 120, 137, 107, 105, 94, 119, 123,
+  138, 112, 99, 109, 122, 119, 79, 118, 167, 110,
+  124, 95, 151, 123, 128, 104, 104, 131, 131, 100,
+  87, 105, 119, 101, 103, 108, 137, 83, 97, 61,
+  86, 83, 107, 76, 81, 141, 130, 123, 106, 85,
+  127, 114, 99, 65, 107, 107, 113, 102, 106, 105,
+  126, 95, 97, 100, 90, 151, 125, 117, 63, 86,
+  105, 84, 90, 152, 93, 111, 90, 91, 109, 143,
+  91, 111, 106, 83, 100, 154, 96, 128, 98, 118,
+  135, 96, 106, 126, 96, 105, 123, 116, 109, 78,
+  93, 83, 102, 103, 99, 116, 102, 93, 100, 116,
+  189, 162, 113, 131, 101, 144, 86, 106, 86, 154,
+  97, 105, 92, 111, 107, 116, 116, 99, 110, 97,
+  74, 162, 91, 90, 123, 84, 114, 68, 122, 84,
+  91, 87, 115, 111, 88, 79, 82, 113, 115, 77,
+  139, 96, 76, 175, 130, 100, 100, 132, 60, 129,
+  69, 101, 111, 115, 103, 145, 113, 100, 107, 102,
+  134, 106, 104, 135, 86, 110, 93, 86, 117, 117,
+  129, 95, 103, 126, 90, 89, 116, 98, 118, 88,
+  59, 101, 112, 138, 108, 100, 118, 97, 95, 96,
+  86, 127, 98, 108, 112, 147, 117, 117, 85, 122,
+  123, 100, 110, 77, 161, 103, 128, 114, 114, 124,
+  160, 99, 78, 83, 131, 92, 101, 124, 127, 76,
+  97, 45, 92, 95, 114, 64, 74, 122, 97, 93,
+  103, 101, 135, 110, 84, 70, 91, 116, 108, 114,
+  106, 104, 107, 99, 120, 95, 99, 173, 112, 124,
+  80, 95, 119, 94, 135, 119, 94, 101, 88, 96,
+  114, 120, 95, 109, 107, 59, 90, 117, 64, 107,
+  113, 105, 123, 96, 95, 126, 99, 115, 128, 112,
+  102, 61, 105, 109, 104, 146, 106, 117, 92, 92,
+  95, 116, 182, 174, 113, 134, 101, 139, 83, 102,
+  102, 185, 90, 111, 96, 110, 106, 124, 107, 77,
+  119, 89, 72, 170, 82, 105, 126, 92, 127, 69,
+  107, 98, 101, 72, 117, 136, 76, 71, 89, 125,
+  112, 68, 144, 104, 74, 175, 128, 108, 107, 100,
+  68, 102, 68, 118, 109, 96, 104, 156, 103, 111,
+  109, 98, 150, 122, 116, 132, 88, 82, 71, 80,
+  111, 100, 139, 86, 114, 145, 133, 124, 114, 99,
+  104, 83, 85, 97, 103, 152, 129, 89, 100, 112,
+  91, 95, 84, 105, 84, 119, 124, 150, 120, 109,
+  109, 105, 109, 93, 113, 99, 150, 120, 130, 113,
+  105, 132, 169, 94, 72, 98, 146, 76, 108, 136,
+  126, 77, 93, 64, 89, 104, 122, 63, 69, 111,
+  74, 67, 92, 140, 136, 119, 70, 62, 107, 111,
+  115, 133, 117, 103, 101, 104, 127, 98, 111, 145,
+  111, 126, 73, 115, 136, 94, 155, 109, 89, 94,
+  94, 102, 97, 101, 92, 85, 114, 55, 92, 98,
+  63, 86, 130, 92, 108, 98, 101, 111, 101, 117,
+  138, 120, 71, 67, 105, 112, 119, 180, 118, 124,
+  89, 82, 87, 106, 152, 164, 112, 119, 103, 128,
+  84, 82, 96, 178, 94, 116, 114, 126, 96, 122,
+  78, 85, 106, 101, 69, 149, 81, 125, 120, 91,
+  112, 90, 114, 94, 103, 78, 107, 138, 85, 77,
+  92, 131, 115, 56, 141, 122, 78, 137, 132, 109,
+  90, 95, 84, 91, 75, 113, 102, 102, 89, 151,
+  81, 108, 124, 101, 144, 111, 118, 131, 95, 82,
+  82, 67, 107, 92, 133, 92, 98, 149, 179, 164,
+  105, 96, 93, 81, 96, 81, 90, 141, 125, 97,
+  118, 129, 104, 94, 78, 78, 92, 129, 122, 135,
+  105, 124, 108, 93, 96, 103, 113, 113, 144, 128,
+  119, 101, 118, 128, 153, 91, 76, 102, 144, 62,
+  124, 122, 141, 89, 93, 91, 93, 120, 117, 85,
+  79, 111, 84, 80, 92, 134, 130, 116, 62, 50,
+  133, 109, 113, 128, 119, 100, 94, 98, 102, 113,
+  114, 141, 108, 119, 83, 115, 131, 90, 141, 116,
+  103, 96, 108, 103, 113, 106, 73, 73, 123, 58,
+  101, 110, 79, 92, 131, 109, 116, 108, 100, 123,
+  106, 112, 145, 117, 57, 97, 100, 99, 112, 185,
+  106, 122, 90, 73, 92, 98, 121, 136, 108, 109,
+  98, 110, 91, 65, 65, 155, 110, 110, 122, 130,
+  72, 113, 62, 106, 91, 114, 62, 119, 97, 126,
+  102, 85, 99, 113, 131, 108, 100, 90, 109, 125,
+  111, 90, 95, 127, 114, 66, 137, 123, 91, 97,
+  138, 105, 71, 95, 96, 97, 94, 101, 96, 106,
+  94, 146, 80, 101, 128, 115, 131, 102, 115, 144,
+  94, 99, 105, 82, 106, 85, 121, 122, 85, 139,
+  165, 182, 97, 84, 81, 98, 88, 84, 81, 133,
+  119, 129, 150, 114, 129, 86, 62, 95, 101, 130,
+  109, 115, 98, 112, 101, 79, 97, 101, 103, 104,
+  129, 143, 112, 95, 108, 131, 121, 93, 81, 113,
+  130, 72, 131, 99, 139, 103, 83, 105, 98, 115,
+  114, 99, 75, 99, 95, 112, 94, 104, 104, 105,
+  64, 44, 122, 114, 112, 121, 120, 94, 76, 98,
+  95, 125, 99, 161, 105, 109, 99, 100, 120, 91,
+  120, 127, 99, 90, 125, 91, 131, 121, 64, 72,
+  118, 57, 115, 109, 89, 100, 133, 120, 125, 117,
+  110, 129, 106, 103, 142, 121, 76, 123, 100, 84,
+  107, 181, 81, 100, 90, 85, 99, 85, 120, 136,
+  113, 121, 89, 117, 100, 67, 65, 164, 105, 97,
+  136, 125, 52, 104, 57, 126, 83, 108, 67, 123,
+  91, 114, 111, 93, 100, 94, 108, 125, 90, 89,
+  106, 114, 119, 78, 102, 131, 112, 75, 123, 105,
+  96, 79, 135, 110, 60, 104, 97, 105, 96, 99,
+  101, 100, 107, 138, 83, 103, 104, 109, 147, 115,
+  102, 138, 102, 113, 115, 88, 97, 86, 114, 109,
+  96, 117, 125, 184, 94, 82, 83, 120, 94, 104,
+  67, 139, 116, 157, 147, 99, 131, 81, 62, 123,
+  115, 122, 97, 96, 110, 99, 101, 73, 97, 108,
+  102, 89, 125, 135, 106, 111, 103, 130, 108, 82,
+  85, 116, 134, 79, 138, 101, 154, 92, 83, 99,
+  101, 107, 133, 75, 81, 95, 103, 121, 105, 95,
+  92, 90, 64, 40, 99, 115, 111, 133, 119, 94,
+  75, 99, 95, 128, 83, 155, 113, 106, 119, 112,
+  140, 94, 114, 127, 96, 68, 120, 105, 127, 127,
+  66, 91, 114, 71, 119, 104, 89, 99, 167, 114,
+  126, 99, 116, 105, 110, 103, 145, 126, 93, 138,
+  120, 73, 117, 176, 92, 102, 92, 104, 90, 90,
+  135, 146, 135, 99, 88, 123, 116, 79, 84, 170,
+  114, 100, 132, 127, 67, 117, 50, 127, 82, 105,
+  74, 127, 99, 100, 128, 103, 107, 74, 91, 129,
+  80, 87, 100, 117, 100, 81, 93, 143, 117, 56,
+  127, 111, 89, 80, 121, 121, 65, 104, 92, 105,
+  95, 84, 105, 121, 101, 133, 82, 108, 74, 103,
+  151, 122, 85, 128, 99, 106, 115, 84, 98, 91,
+  111, 88, 83, 116, 120, 176, 86, 90, 68, 121,
+  112, 133, 56, 140, 105, 160, 133, 111, 118, 88,
+  62, 110, 124, 124, 82, 92, 120, 105, 108, 88,
+  92, 108, 107, 103, 129, 119, 98, 103, 112, 137,
+  113, 89, 89, 114, 135, 84, 146, 113, 181, 90,
+  86, 98, 112, 116, 134, 72, 89, 104, 108, 113,
+  98, 95, 98, 76, 61, 42, 105, 119, 112, 139,
+  122, 106, 91, 100, 105, 127, 81, 139, 132, 114,
+  98, 108, 145, 91, 116, 118, 100, 77, 121, 132,
+  103, 139, 77, 99, 106, 70, 122, 117, 97, 70,
+  170, 117, 119, 77, 147, 100, 104, 110, 149, 128,
+  90, 139, 113, 74, 117, 176, 97, 127, 88, 119,
+  93, 114, 137, 129, 132, 103, 88, 104, 117, 89,
+  80, 158, 131, 133, 123, 122, 86, 120, 50, 103,
+  72, 106, 69, 118, 92, 82, 144, 92, 98, 83,
+  105, 124, 86, 88, 105, 107, 104, 92, 88, 142,
+  132, 43, 135, 107, 72, 85, 120, 115, 71, 133,
+  87, 106, 90, 74, 105, 139, 92, 158, 107, 109,
+  89, 114, 135, 112, 98, 131, 99, 106, 97, 79,
+  101, 97, 114, 101, 80, 115, 104, 157, 91, 91,
+  78, 111, 91, 136, 47, 125, 99, 131, 125, 97,
+  91, 90, 67, 121, 111, 117, 106, 93, 119, 96,
+  94, 114, 82, 105, 109, 113, 137, 141, 105, 91,
+  119, 137, 108, 89, 98, 106, 132, 91, 145, 132,
+  190, 87, 83, 96, 118, 113, 120, 85, 85, 103,
+  95, 123, 88, 85, 67, 75, 72, 45, 93, 151,
+  115, 125, 122, 110, 97, 108, 108, 116, 87, 147,
+  132, 130, 74, 96, 130, 95, 111, 128, 119, 92,
+  113, 125, 100, 153, 88, 96, 102, 58, 129, 119,
+  98, 102, 145, 124, 119, 73, 168, 120, 112, 105,
+  132, 129, 82, 136, 99, 90, 107, 175, 80, 114,
+  84, 125, 98, 137, 144, 147, 119, 105, 101, 93,
+  140, 96, 98, 165, 121, 150, 122, 122, 100, 99,
+  61, 84, 100, 62, 61, 152, 96, 82, 139, 94,
+  112, 70, 103, 125, 95, 96, 101, 105, 81, 86,
+  104, 146, 139, 62, 110, 99, 82, 103, 122, 110,
+  85, 163, 85, 140, 99, 113, 119, 150, 96, 135,
+  139, 122, 114, 125, 137, 111, 121, 132, 107, 134,
+  87, 91, 111, 90, 111, 84, 93, 106, 68, 116,
+  91, 106, 92, 122, 113, 123, 49, 128, 108, 113,
+  113, 96, 78, 94, 69, 116, 104, 89, 155, 102,
+  133, 98, 78, 155, 98, 111, 129, 97, 200, 127,
+  107, 98, 97, 127, 135, 100, 105, 110, 102, 93,
+  138, 140, 158, 79, 67, 68, 124, 112, 126, 68,
+  109, 118, 101, 132, 100, 81, 65, 82, 92, 52,
+  92, 182, 97, 119, 119, 126, 126, 116, 119, 126,
+  103, 164, 128, 123, 70, 96, 102, 101, 130, 130,
+  132, 81, 109, 133, 116, 145, 86, 126, 102, 57,
+  105, 125, 90, 128, 138, 120, 137, 82, 141, 150,
+  114, 110, 112, 109, 78, 124, 96, 107, 94, 167,
+  86, 99, 76, 127, 117, 161, 123, 141, 102, 89,
+  114, 90, 146, 100, 113, 166, 132, 154, 105, 135,
+  110, 81, 78, 78, 126, 70, 49, 168, 111, 81,
+  116, 83, 101, 75, 119, 112, 83, 102, 100, 100,
+  81, 97, 114, 130, 146, 97, 93, 106, 97, 118,
+  113, 107, 94, 129, 79, 167, 112, 166, 130, 141,
+  116, 153, 169, 149, 120, 125, 124, 101, 130, 142,
+  125, 136, 96, 96, 120, 91, 100, 85, 87, 100,
+  62, 98, 113, 109, 113, 147, 119, 84, 71, 113,
+  118, 104, 95, 98, 80, 85, 84, 118, 109, 78,
+  159, 116, 127, 108, 79, 162, 109, 83, 124, 102,
+  213, 104, 115, 131, 89, 140, 149, 122, 101, 115,
+  101, 95, 113, 122, 124, 64, 59, 75, 128, 121,
+  136, 88, 128, 114, 93, 121, 111, 100, 90, 106,
+  112, 72, 98, 150, 80, 109, 113, 122, 138, 119,
+  120, 130, 107, 151, 104, 113, 105, 102, 87, 109,
+  153, 122, 161, 79, 106, 125, 110, 106, 97, 149,
+  102, 60, 86, 116, 78, 118, 113, 100, 141, 110,
+  134, 155, 117, 103, 94, 80, 72, 115, 107, 104,
+  82, 134, 119, 101, 73, 119, 113, 154, 111, 124,
+  103, 98, 117, 106, 129, 99, 104, 170, 120, 131,
+  71, 113, 87, 63, 78, 70, 148, 104, 30, 164,
+  121, 96, 89, 86, 95, 79, 127, 101, 69, 103,
+  96, 95, 102, 92, 113, 109, 135, 99, 74, 125,
+  123, 119, 113, 119, 96, 81, 75, 165, 109, 178,
+  125, 116, 136, 173, 186, 159, 93, 112, 107, 105,
+  121, 118, 126, 123, 117, 81, 121, 95, 89, 101,
+  86, 117, 80, 105, 122, 123, 104, 146, 106, 71,
+  85, 112, 119, 95, 91, 111, 86, 75, 100, 135,
+  129, 91, 134, 118, 101, 86, 102, 129, 122, 82,
+  99, 103, 195, 90, 120, 164, 79, 157, 138, 147,
+  108, 103, 107, 129, 97, 103, 118, 66, 44, 73,
+  115, 106, 140, 88, 140, 87, 68, 90, 131, 124,
+  110, 127, 117, 75, 81, 105, 75, 118, 114, 116,
+  130, 141, 106, 130, 114, 129, 83, 97, 118, 92,
+  99, 103, 166, 107, 135, 72, 79, 104, 102, 89,
+  106, 162, 92, 51, 92, 85, 71, 103, 99, 72,
+  135, 138, 146, 152, 115, 87, 79, 53, 104, 105,
+  123, 99, 73, 82, 134, 93, 82, 97, 130, 124,
+  119, 121, 133, 105, 125, 135, 104, 121, 90, 192,
+  114, 109, 74, 95, 98, 60, 93, 74, 175, 86,
+  26, 192, 122, 117, 99, 116, 111, 60, 88, 123,
+  77, 102, 91, 114, 115, 100, 112, 115, 128, 96,
+  76, 149, 114, 125, 133, 136, 98, 68, 85, 123,
+  109, 167, 111, 96, 148, 181, 133, 166, 55, 90,
+  116, 129, 89, 121, 101, 107, 106, 72, 139, 97,
+  105, 95, 95, 132, 99, 124, 133, 122, 93, 150,
+  120, 106, 88, 143, 123, 106, 70, 129, 98, 63,
+  93, 135, 136, 118, 117, 121, 119, 93, 120, 120,
+  132, 124, 88, 118, 156, 126, 117, 150, 77, 171,
+  142, 143, 116, 117, 125, 115, 82, 107, 133, 82,
+  58, 67, 92, 95, 144, 76, 152, 77, 62, 34,
+  144, 159, 144, 149, 99, 90, 105, 100, 94, 135,
+  110, 103, 131, 157, 104, 134, 115, 111, 89, 118,
+  120, 96, 128, 100, 172, 80, 96, 58, 95, 112,
+  82, 68, 100, 148, 95, 43, 116, 84, 69, 91,
+  103, 63, 100, 148, 152, 148, 114, 83, 84, 57,
+  113, 114, 142, 109, 75, 77, 150, 115, 76, 82,
+  90, 131, 116, 109, 160, 108, 125, 153, 82, 144,
+  71, 203, 127, 130, 82, 96, 132, 88, 90, 95,
+  125, 86, 38, 216, 96, 125, 118, 124, 127, 49,
+  61, 148, 98, 107, 89, 137, 132, 125, 105, 148,
+  122, 130, 85, 135, 90, 113, 141, 113, 92, 89,
+  108, 93, 107, 151, 105, 110, 146, 178, 103, 156,
+  68, 100, 138, 145, 93, 114, 105, 99, 114, 111,
+  149, 95, 116, 113, 87, 150, 108, 148, 124, 118,
+  81, 161, 137, 152, 92, 158, 134, 106, 64, 115,
+  102, 61, 87, 138, 102, 128, 129, 109, 128, 76,
+  99, 121, 135, 144, 108, 137, 123, 163, 109, 102,
+  66, 159, 144, 120, 115, 135, 125, 76, 87, 115,
+  133, 118, 77, 89, 83, 118, 141, 88, 111, 87,
+  99, 72, 123, 148, 125, 160, 84, 73, 122, 82,
+  114, 142, 108, 109, 134, 151, 90, 126, 92, 105,
+  108, 149, 86, 92, 155, 88, 154, 78, 115, 65,
+  128, 123, 76, 58, 94, 95, 103, 44, 131, 112,
+  77, 93, 116, 98, 78, 133, 138, 131, 114, 90,
+  93, 108, 107, 120, 130, 99, 76, 125, 157, 140,
+  71, 76, 101, 139, 89, 101, 149, 79, 101, 138,
+  93, 134, 92, 171, 140, 164, 91, 132, 126, 103,
+  76, 104, 96, 78, 57, 183, 100, 83, 113, 106,
+  117, 87, 77, 130, 88, 113, 97, 149, 143, 145,
+  98, 163, 128, 148, 73, 98, 50, 98, 142, 86,
+  71, 101, 123, 127, 112, 132, 119, 126, 119, 137,
+  94, 126, 89, 113, 127, 131, 91, 104, 112, 94,
+  98, 124, 124, 93, 102, 126, 68, 139, 78, 152,
+  100, 94, 113, 146, 132, 150, 98, 130, 112, 104,
+  96, 115, 98, 68, 94, 158, 101, 106, 124, 84,
+  117, 107, 74, 120, 131, 121, 108, 162, 148, 181,
+  96, 71, 81, 121, 140, 127, 112, 137, 98, 89,
+  98, 114, 126, 114, 65, 100, 126, 141, 123, 106,
+  103, 104, 139, 126, 80, 90, 100, 131, 92, 75,
+  76, 62, 95, 134, 131, 113, 130, 133, 83, 133,
+  54, 118, 105, 124, 88, 98, 134, 78, 116, 105,
+  146, 51, 115, 120, 98, 83, 111, 100, 96, 61,
+  107, 159, 98, 104, 135, 138, 108, 110, 111, 139,
+  112, 100, 108, 115, 116, 133, 92, 82, 73, 147,
+  153, 118, 78, 84, 111, 150, 80, 104, 114, 76,
+  99, 81, 99, 96, 113, 117, 103, 122, 90, 139,
+  93, 98, 63, 86, 96, 93, 53, 107, 91, 62,
+  95, 89, 102, 103, 89, 95, 91, 128, 98, 121,
+  150, 141, 95, 137, 112, 112, 84, 72, 68, 117,
+  134, 70, 75, 103, 88, 171, 112, 108, 116, 119,
+  113, 117, 119, 99, 117, 116, 80, 95, 113, 84,
+  131, 99, 114, 121, 79, 112, 95, 139, 81, 114,
+  52, 128, 98, 82, 151, 121, 99, 102, 102, 101,
+  97, 101, 114, 97, 83, 102, 117, 151, 151, 94,
+  93, 78, 94, 124, 63, 107, 109, 80, 78, 115,
+  151, 102, 110, 109, 87, 109, 112, 132, 123, 105,
+  73, 99, 102, 83, 127, 86, 47, 88, 125, 111,
+  101, 116, 103, 124, 112, 159, 87, 85, 120, 93,
+  120, 75, 63, 88, 83, 109, 121, 99, 87, 110,
+  72, 129, 86, 114, 88, 77, 84, 109, 92, 96,
+  89, 126, 141, 95, 74, 108, 122, 94, 128, 117,
+  72, 99, 90, 177, 93, 128, 103, 118, 125, 106,
+  121, 124, 99, 112, 90, 99, 104, 103, 76, 86,
+  85, 137, 136, 90, 93, 116, 133, 131, 93, 127,
+  122, 124, 126, 68, 111, 102, 118, 99, 114, 101,
+  106, 124, 84, 91, 90, 81, 120, 87, 39, 113,
+  108, 80, 118, 93, 97, 94, 116, 93, 122, 149,
+  107, 82, 129, 82, 98, 107, 141, 88, 97, 106,
+  82, 159, 115, 106, 106, 121, 90, 152, 136, 99,
+  134, 111, 96, 84, 114, 99, 120, 113, 71, 99,
+  115, 83, 134, 145, 103, 107, 81, 131, 119, 87,
+  100, 112, 81, 94, 126, 83, 153, 96, 70, 99,
+  105, 95, 87, 118, 119, 133, 94, 107, 136, 125,
+  188, 105, 101, 93, 119, 152, 104, 116, 107, 73,
+  97, 73, 138, 96, 115, 114, 100, 106, 115, 137,
+  120, 91, 105, 91, 124, 87, 122, 78, 52, 78,
+  118, 92, 115, 100, 161, 125, 103, 101, 149, 123,
+  137, 92, 117, 85, 83, 135, 101, 105, 83, 95,
+  115, 106, 80, 125, 118, 105, 78, 88, 77, 155,
+  85, 97, 91, 108, 85, 107, 62, 123, 113, 101,
+  143, 131, 67, 123, 106, 112, 109, 99, 96, 80,
+  120, 110, 110, 101, 85, 137, 90, 76, 74, 98,
+  77, 104, 101, 97, 167, 91, 104, 119, 91, 104,
+  67, 121, 105, 110, 126, 107, 103, 109, 103, 93,
+  104, 100, 91, 105, 73, 81, 96, 59, 119, 111,
+  29, 107, 119, 92, 107, 84, 68, 92, 143, 85,
+  108, 120, 108, 73, 101, 107, 63, 82, 141, 76,
+  104, 122, 90, 164, 90, 126, 124, 115, 91, 136,
+  127, 86, 117, 116, 92, 89, 111, 94, 119, 132,
+  57, 79, 96, 90, 118, 151, 104, 99, 97, 121,
+  109, 111, 92, 109, 115, 74, 113, 82, 149, 91,
+  57, 73, 116, 106, 65, 129, 101, 145, 95, 98,
+  103, 91, 135, 95, 87, 90, 106, 138, 105, 110,
+  114, 55, 93, 115, 138, 96, 113, 99, 97, 94,
+  106, 134, 95, 61, 88, 91, 132, 107, 120, 106,
+  41, 63, 115, 119, 89, 75, 100, 88, 90, 111,
+  140, 131, 118, 93, 100, 94, 85, 155, 114, 132,
+  85, 87, 123, 142, 88, 111, 81, 109, 58, 81,
+  48, 109, 77, 101, 99, 103, 71, 122, 75, 102,
+  108, 92, 123, 136, 51, 66, 96, 76, 88, 96,
+  101, 77, 108, 123, 104, 145, 83, 122, 103, 70,
+  80, 118, 52, 110, 91, 53, 136, 100, 134, 105,
+  101, 108, 57, 117, 77, 115, 100, 117, 82, 116,
+  104, 114, 93, 93, 91, 111, 85, 84, 97, 60,
+  101, 81, 49, 117, 113, 95, 87, 77, 84, 103,
+  139, 110, 125, 85, 99, 71, 115, 136, 83, 76,
+  113, 60, 86, 98, 98, 141, 95, 110, 130, 99,
+  81, 121, 120, 121, 113, 70, 139, 112, 79, 124,
+  94, 130, 67, 95, 95, 123, 100, 110, 98, 87,
+  97, 97, 105, 156, 99, 120, 120, 65, 84, 75,
+  143, 107, 63, 60, 120, 129, 59, 109, 105, 95,
+  85, 80, 91, 106, 132, 81, 88, 107, 104, 98,
+  118, 114, 124, 67, 72, 87, 94, 100, 113, 118,
+  121, 74, 98, 112, 94, 84, 78, 110, 101, 116,
+  98, 119, 49, 78, 89, 122, 86, 64, 74, 60,
+  55, 87, 94, 124, 140, 113, 90, 118, 91, 164,
+  120, 146, 100, 86, 108, 164, 85, 103, 71, 121,
+  37, 93, 71, 107, 73, 116, 111, 103, 71, 81,
+  97, 70, 104, 70, 103, 111, 69, 35, 92, 87,
+  70, 110, 74, 86, 85, 146, 93, 165, 106, 118,
+  119, 61, 112, 99, 53, 104, 84, 65, 96, 77,
+  179, 98, 103, 109, 85, 126, 90, 122, 99, 123,
+  79, 121, 99, 131, 106, 93, 89, 114, 96, 105,
+  88, 71, 91, 96, 62, 107, 113, 104, 106, 90,
+  109, 104, 92, 157, 123, 65, 89, 88, 119, 104,
+  120, 92, 95, 54, 81, 99, 90, 123, 108, 83,
+  113, 89, 59, 86, 93, 142, 114, 58, 166, 111,
+  95, 127, 110, 103, 117, 150, 95, 127, 105, 95,
+  106, 68, 115, 94, 119, 136, 116, 137, 130, 74,
+  55, 101, 78, 103, 87, 87, 108, 162, 72, 89,
+  106, 33, 99, 61, 81, 134, 147, 91, 99, 142,
+  143, 85, 147, 123, 117, 97, 90, 62, 79, 122,
+  128, 132, 105, 72, 81, 84, 113, 117, 70, 108,
+  92, 117, 78, 111, 66, 95, 69, 106, 105, 62,
+  95, 53, 74, 101, 59, 105, 154, 112, 93, 124,
+  99, 158, 122, 149, 94, 109, 88, 153, 92, 88,
+  91, 108, 54, 134, 52, 114, 88, 112, 98, 78,
+  74, 36, 112, 74, 104, 82, 92, 84, 93, 46,
+  86, 94, 68, 94, 74, 91, 83, 147, 78, 117,
+  116, 154, 126, 67, 124, 84, 83, 96, 107, 112,
+  96, 86, 175, 96, 98, 98, 106, 130, 100, 111,
+  110, 104, 97, 122, 115, 130, 94, 83, 101, 114,
+  110, 106, 88, 99, 113, 100, 90, 114, 134, 111,
+  119, 109, 120, 131, 42, 152, 111, 98, 88, 116,
+  105, 74, 141, 111, 102, 40, 107, 84, 91, 122,
+  104, 105, 102, 91, 73, 90, 90, 132, 129, 97,
+  146, 112, 101, 105, 130, 100, 142, 161, 124, 120,
+  106, 106, 92, 80, 101, 103, 120, 94, 179, 130,
+  123, 112, 70, 108, 85, 78, 110, 119, 122, 174,
+  93, 86, 108, 74, 114, 84, 105, 95, 143, 99,
+  105, 145, 158, 109, 149, 121, 104, 118, 106, 120,
+  92, 106, 129, 127, 99, 78, 79, 87, 126, 127,
+  87, 103, 86, 126, 91, 94, 93, 135, 76, 112,
+  115, 115, 126, 85, 125, 112, 81, 105, 145, 97,
+  113, 129, 127, 130, 117, 149, 113, 110, 91, 135,
+  112, 96, 86, 94, 93, 145, 78, 118, 99, 88,
+  90, 90, 112, 45, 112, 107, 136, 99, 97, 101,
+  107, 89, 88, 124, 98, 99, 111, 104, 97, 127,
+  92, 108, 102, 161, 146, 76, 114, 89, 97, 94,
+  126, 132, 114, 132, 150, 101, 103, 112, 99, 131,
+  117, 117, 125, 106, 111, 127, 103, 108, 114, 123,
+  115, 113, 133, 104, 135, 132, 139, 98, 85, 97,
+  116, 116, 132, 112, 134, 95, 120, 111, 115, 143,
+  97, 67, 95, 110, 138, 100, 133, 88, 119, 79,
+  82, 142, 125, 104, 108, 124, 79, 132, 121, 105,
+  137, 156, 96, 84, 108, 94, 144, 144, 133, 130,
+  97, 104, 124, 116, 93, 103, 120, 117, 125, 98,
+  160, 131, 86, 114, 108, 98, 88, 104, 93, 119,
+  112, 125, 95, 116, 114, 146, 110, 105, 102, 113,
+  83, 119, 142, 112, 157, 106, 135, 123, 134, 90,
+  137, 113, 123, 119, 132, 89, 71, 113, 104, 96,
+  106, 123, 110, 106, 119, 129, 105, 109, 94, 112,
+  85, 111, 112, 118, 124, 111, 108, 127, 127, 76,
+  126, 116, 109, 161, 72, 118, 113, 115, 114, 109,
+  123, 98, 125, 111, 109, 118, 123, 111, 53, 87,
+  112, 92, 98, 90, 88, 121, 128, 95, 91, 116,
+  119, 116, 109, 115, 118, 93, 113, 103, 87, 97,
+  113, 101, 98, 114, 92, 140, 116, 110, 121, 101,
+  108, 82, 100, 112, 94, 95, 162, 97, 142, 107,
+  78, 117, 124, 117, 123, 127, 93, 126, 89, 131,
+  105, 109, 112, 112, 129, 100, 120, 129, 136, 93,
+  79, 71, 31, 106, 147, 96, 102, 89, 132, 71,
+  89, 104, 85, 99, 102, 109, 128, 80, 124, 119,
+  122, 78, 72, 183, 91, 117, 106, 132, 66, 98,
+  101, 118, 147, 152, 65, 95, 96, 89, 133, 149,
+  111, 97, 103, 116, 108, 93, 100, 93, 120, 97,
+  122, 110, 100, 131, 82, 90, 87, 108, 100, 106,
+  97, 139, 105, 133, 91, 107, 119, 138, 97, 83,
+  103, 95, 96, 106, 107, 100, 148, 121, 159, 125,
+  151, 91, 124, 138, 89, 119, 134, 91, 75, 109,
+  80, 101, 112, 120, 111, 100, 110, 161, 101, 80,
+  78, 121, 63, 139, 98, 108, 143, 59, 121, 116,
+  123, 85, 134, 112, 106, 195, 113, 79, 132, 145,
+  134, 92, 114, 134, 136, 106, 113, 151, 107, 102,
+  81, 71, 134, 98, 75, 109, 148, 146, 109, 90,
+  125, 108, 98, 128, 90, 72, 99, 105, 93, 129,
+  96, 83, 102, 96, 93, 93, 106, 132, 113, 110,
+  107, 87, 104, 96, 104, 115, 83, 131, 137, 99,
+  151, 128, 82, 96, 138, 123, 89, 110, 85, 122,
+  97, 155, 119, 132, 106, 117, 138, 92, 118, 81,
+  123, 104, 74, 93, 33, 103, 148, 105, 98, 96,
+  115, 69, 92, 100, 83, 135, 118, 87, 108, 100,
+  111, 126, 86, 145, 80, 183, 110, 134, 109, 108,
+  90, 73, 86, 133, 121, 93, 71, 97, 90, 90,
+  114, 106, 94, 84, 110, 128, 108, 111, 87, 99,
+  98, 88, 128, 87, 81, 121, 84, 103, 103, 91,
+  124, 61, 108, 129, 96, 140, 95, 98, 108, 111,
+  102, 82, 120, 99, 109, 106, 116, 77, 139, 114,
+  166, 126, 140, 105, 109, 176, 82, 111, 113, 108,
+  75, 98, 90, 117, 109, 134, 118, 103, 102, 168,
+  110, 78, 69, 104, 84, 122, 117, 84, 156, 61,
+  115, 85, 122, 169, 110, 120, 79, 188, 126, 77,
+  140, 162, 145, 91, 116, 171, 125, 105, 58, 111,
+  91, 119, 96, 100, 143, 109, 77, 124, 106, 129,
+  89, 104, 109, 101, 127, 136, 87, 62, 92, 121,
+  81, 81, 137, 81, 95, 83, 105, 81, 100, 132,
+  126, 122, 86, 75, 79, 97, 111, 123, 92, 120,
+  152, 67, 81, 114, 78, 88, 112, 142, 83, 76,
+  70, 90, 74, 84, 86, 83, 104, 110, 113, 85,
+  95, 116, 114, 135, 38, 66, 34, 91, 126, 85,
+  115, 86, 121, 52, 88, 111, 66, 110, 116, 115,
+  73, 84, 84, 89, 96, 84, 62, 156, 93, 103,
+  91, 118, 74, 89, 86, 101, 97, 73, 84, 100,
+  99, 58, 112, 113, 72, 74, 89, 106, 92, 82,
+  71, 87, 58, 87, 105, 150, 86, 114, 69, 107,
+  94, 81, 119, 69, 78, 70, 92, 131, 57, 86,
+  112, 98, 89, 71, 123, 104, 127, 98, 84, 70,
+  110, 88, 113, 106, 126, 66, 69, 123, 86, 111,
+  121, 90, 67, 91, 61, 105, 113, 115, 94, 95,
+  105, 121, 107, 81, 58, 93, 69, 91, 64, 106,
+  95, 82, 94, 105, 111, 137, 85, 103, 90, 159,
+  75, 75, 111, 119, 107, 77, 91, 126, 94, 85,
+  50, 96, 71, 90, 60, 65, 98, 81, 37, 125,
+  57, 103, 81, 69, 113, 106, 129, 107, 84, 57,
+  91, 154, 86, 118, 85, 69, 84, 89, 140, 86,
+  80, 130, 94, 92, 87, 65, 57, 73, 111, 100,
+  60, 82,
+};
+
+
+extern "C" JNIEXPORT void JNICALL
+Java_android_cts_rsblas_BNNMTest_getData(JNIEnv * env,
+                                         jclass,
+                                         jbyteArray a,
+                                         jbyteArray b,
+                                         jbyteArray c
+                                         )
+{
+    jbyte * a_byte = (jbyte *) env->GetPrimitiveArrayCritical(a, 0);
+    jbyte * b_byte = (jbyte *) env->GetPrimitiveArrayCritical(b, 0);
+    jbyte * c_byte = (jbyte *) env->GetPrimitiveArrayCritical(c, 0);
+
+    memcpy(a_byte, a_data, a_count);
+    memcpy(b_byte, b_data, b_count);
+    memcpy(c_byte, expected_c_data, c_count);
+
+
+    env->ReleasePrimitiveArrayCritical(c, c_byte, 0);
+    env->ReleasePrimitiveArrayCritical(b, b_byte, 0);
+    env->ReleasePrimitiveArrayCritical(a, a_byte, 0);
+}
diff --git a/tests/tests/rsblas/src/android/renderscript/cts/BLASData.java b/tests/tests/rsblas/src/android/renderscript/cts/BLASData.java
new file mode 100644
index 0000000..786290e
--- /dev/null
+++ b/tests/tests/rsblas/src/android/renderscript/cts/BLASData.java
@@ -0,0 +1,1382 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* Don't edit this file alone!
+ * The array names need to match the data generated by blas_gen.py. */
+
+package android.cts.rsblas;
+
+import android.content.res.AssetManager;
+import android.content.Context;
+import java.io.InputStream;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.io.IOException;
+
+import android.test.AndroidTestCase;
+
+public class BLASData extends AndroidTestCase {
+    private BufferedReader mBufReader;
+
+    int dM;
+    int dN;
+    int dK;
+
+    int KL;
+    int KU;
+
+    float[] L2_sGEMV_A_mn;
+    float[] L2_sGEMV_x_n1;
+    float[] L2_sGEMV_x_n2;
+    float[] L2_sGEMV_y_m1;
+    float[] L2_sGEMV_y_m2;
+    float[] L2_sGEMV_o_N;
+    float[] L2_sGEMV_o_N2;
+    float[] L2_sGEMV_o_T;
+    float[] L2_sGEMV_o_H;
+
+    double[] L2_dGEMV_A_mn;
+    double[] L2_dGEMV_x_n1;
+    double[] L2_dGEMV_x_n2;
+    double[] L2_dGEMV_y_m1;
+    double[] L2_dGEMV_y_m2;
+    double[] L2_dGEMV_o_N;
+    double[] L2_dGEMV_o_N2;
+    double[] L2_dGEMV_o_T;
+    double[] L2_dGEMV_o_H;
+
+    float[] L2_cGEMV_A_mn;
+    float[] L2_cGEMV_x_n1;
+    float[] L2_cGEMV_x_n2;
+    float[] L2_cGEMV_y_m1;
+    float[] L2_cGEMV_y_m2;
+    float[] L2_cGEMV_o_N;
+    float[] L2_cGEMV_o_N2;
+    float[] L2_cGEMV_o_T;
+    float[] L2_cGEMV_o_H;
+
+    double[] L2_zGEMV_A_mn;
+    double[] L2_zGEMV_x_n1;
+    double[] L2_zGEMV_x_n2;
+    double[] L2_zGEMV_y_m1;
+    double[] L2_zGEMV_y_m2;
+    double[] L2_zGEMV_o_N;
+    double[] L2_zGEMV_o_N2;
+    double[] L2_zGEMV_o_T;
+    double[] L2_zGEMV_o_H;
+
+    float[] L2_sGBMV_A_mn;
+    float[] L2_sGBMV_x_n1;
+    float[] L2_sGBMV_x_n2;
+    float[] L2_sGBMV_y_m1;
+    float[] L2_sGBMV_y_m2;
+    float[] L2_sGBMV_o_N;
+    float[] L2_sGBMV_o_N2;
+    float[] L2_sGBMV_o_T;
+    float[] L2_sGBMV_o_H;
+
+    double[] L2_dGBMV_A_mn;
+    double[] L2_dGBMV_x_n1;
+    double[] L2_dGBMV_x_n2;
+    double[] L2_dGBMV_y_m1;
+    double[] L2_dGBMV_y_m2;
+    double[] L2_dGBMV_o_N;
+    double[] L2_dGBMV_o_N2;
+    double[] L2_dGBMV_o_T;
+    double[] L2_dGBMV_o_H;
+
+    float[] L2_cGBMV_A_mn;
+    float[] L2_cGBMV_x_n1;
+    float[] L2_cGBMV_x_n2;
+    float[] L2_cGBMV_y_m1;
+    float[] L2_cGBMV_y_m2;
+    float[] L2_cGBMV_o_N;
+    float[] L2_cGBMV_o_N2;
+    float[] L2_cGBMV_o_T;
+    float[] L2_cGBMV_o_H;
+
+    double[] L2_zGBMV_A_mn;
+    double[] L2_zGBMV_x_n1;
+    double[] L2_zGBMV_x_n2;
+    double[] L2_zGBMV_y_m1;
+    double[] L2_zGBMV_y_m2;
+    double[] L2_zGBMV_o_N;
+    double[] L2_zGBMV_o_N2;
+    double[] L2_zGBMV_o_T;
+    double[] L2_zGBMV_o_H;
+
+    float[] L2_cHEMV_A_nn;
+    float[] L2_cHEMV_A_nn_pu;
+    float[] L2_cHEMV_x_n1;
+    float[] L2_cHEMV_x_n2;
+    float[] L2_cHEMV_y_n1;
+    float[] L2_cHEMV_y_n2;
+    float[] L2_cHEMV_o_N;
+    float[] L2_cHEMV_o_N2;
+
+    double[] L2_zHEMV_A_nn;
+    double[] L2_zHEMV_A_nn_pu;
+    double[] L2_zHEMV_x_n1;
+    double[] L2_zHEMV_x_n2;
+    double[] L2_zHEMV_y_n1;
+    double[] L2_zHEMV_y_n2;
+    double[] L2_zHEMV_o_N;
+    double[] L2_zHEMV_o_N2;
+
+    float[] L2_cHBMV_A_nn;
+    float[] L2_cHBMV_x_n1;
+    float[] L2_cHBMV_x_n2;
+    float[] L2_cHBMV_y_n1;
+    float[] L2_cHBMV_y_n2;
+    float[] L2_cHBMV_o_N;
+    float[] L2_cHBMV_o_N2;
+
+    double[] L2_zHBMV_A_nn;
+    double[] L2_zHBMV_x_n1;
+    double[] L2_zHBMV_x_n2;
+    double[] L2_zHBMV_y_n1;
+    double[] L2_zHBMV_y_n2;
+    double[] L2_zHBMV_o_N;
+    double[] L2_zHBMV_o_N2;
+
+    float[] L2_sSYMV_A_nn;
+    float[] L2_sSYMV_A_nn_pu;
+    float[] L2_sSYMV_x_n1;
+    float[] L2_sSYMV_x_n2;
+    float[] L2_sSYMV_y_n1;
+    float[] L2_sSYMV_y_n2;
+    float[] L2_sSYMV_o_N;
+    float[] L2_sSYMV_o_N2;
+
+    double[] L2_dSYMV_A_nn;
+    double[] L2_dSYMV_A_nn_pu;
+    double[] L2_dSYMV_x_n1;
+    double[] L2_dSYMV_x_n2;
+    double[] L2_dSYMV_y_n1;
+    double[] L2_dSYMV_y_n2;
+    double[] L2_dSYMV_o_N;
+    double[] L2_dSYMV_o_N2;
+
+    float[] L2_sSBMV_A_nn;
+    float[] L2_sSBMV_x_n1;
+    float[] L2_sSBMV_x_n2;
+    float[] L2_sSBMV_y_n1;
+    float[] L2_sSBMV_y_n2;
+    float[] L2_sSBMV_o_N;
+    float[] L2_sSBMV_o_N2;
+
+    double[] L2_dSBMV_A_nn;
+    double[] L2_dSBMV_x_n1;
+    double[] L2_dSBMV_x_n2;
+    double[] L2_dSBMV_y_n1;
+    double[] L2_dSBMV_y_n2;
+    double[] L2_dSBMV_o_N;
+    double[] L2_dSBMV_o_N2;
+
+    float[] L2_sTRMV_A_nn;
+    float[] L2_sTRMV_A_nn_pu;
+    float[] L2_sTRMV_x_n1;
+    float[] L2_sTRMV_x_n2;
+    float[] L2_sTRMV_o_UN;
+    float[] L2_sTRMV_o_UN2;
+    float[] L2_sTRMV_o_UT;
+    float[] L2_sTRMV_o_UH;
+
+    double[] L2_dTRMV_A_nn;
+    double[] L2_dTRMV_A_nn_pu;
+    double[] L2_dTRMV_x_n1;
+    double[] L2_dTRMV_x_n2;
+    double[] L2_dTRMV_o_UN;
+    double[] L2_dTRMV_o_UN2;
+    double[] L2_dTRMV_o_UT;
+    double[] L2_dTRMV_o_UH;
+
+    float[] L2_cTRMV_A_nn;
+    float[] L2_cTRMV_A_nn_pu;
+    float[] L2_cTRMV_x_n1;
+    float[] L2_cTRMV_x_n2;
+    float[] L2_cTRMV_o_UN;
+    float[] L2_cTRMV_o_UN2;
+    float[] L2_cTRMV_o_UT;
+    float[] L2_cTRMV_o_UH;
+
+    double[] L2_zTRMV_A_nn;
+    double[] L2_zTRMV_A_nn_pu;
+    double[] L2_zTRMV_x_n1;
+    double[] L2_zTRMV_x_n2;
+    double[] L2_zTRMV_o_UN;
+    double[] L2_zTRMV_o_UN2;
+    double[] L2_zTRMV_o_UT;
+    double[] L2_zTRMV_o_UH;
+
+    float[] L2_sTBMV_A_nn;
+    float[] L2_sTBMV_x_n1;
+    float[] L2_sTBMV_x_n2;
+    float[] L2_sTBMV_o_UN;
+    float[] L2_sTBMV_o_UN2;
+    float[] L2_sTBMV_o_UT;
+    float[] L2_sTBMV_o_UH;
+
+    double[] L2_dTBMV_A_nn;
+    double[] L2_dTBMV_x_n1;
+    double[] L2_dTBMV_x_n2;
+    double[] L2_dTBMV_o_UN;
+    double[] L2_dTBMV_o_UN2;
+    double[] L2_dTBMV_o_UT;
+    double[] L2_dTBMV_o_UH;
+
+    float[] L2_cTBMV_A_nn;
+    float[] L2_cTBMV_x_n1;
+    float[] L2_cTBMV_x_n2;
+    float[] L2_cTBMV_o_UN;
+    float[] L2_cTBMV_o_UN2;
+    float[] L2_cTBMV_o_UT;
+    float[] L2_cTBMV_o_UH;
+
+    double[] L2_zTBMV_A_nn;
+    double[] L2_zTBMV_x_n1;
+    double[] L2_zTBMV_x_n2;
+    double[] L2_zTBMV_o_UN;
+    double[] L2_zTBMV_o_UN2;
+    double[] L2_zTBMV_o_UT;
+    double[] L2_zTBMV_o_UH;
+
+    float[] L2_sTRSV_A_nn;
+    float[] L2_sTRSV_A_nn_pu;
+    float[] L2_sTRSV_x_n1;
+    float[] L2_sTRSV_x_n2;
+    float[] L2_sTRSV_o_UN;
+    float[] L2_sTRSV_o_UN2;
+    float[] L2_sTRSV_o_UT;
+    float[] L2_sTRSV_o_UH;
+
+    double[] L2_dTRSV_A_nn;
+    double[] L2_dTRSV_A_nn_pu;
+    double[] L2_dTRSV_x_n1;
+    double[] L2_dTRSV_x_n2;
+    double[] L2_dTRSV_o_UN;
+    double[] L2_dTRSV_o_UN2;
+    double[] L2_dTRSV_o_UT;
+    double[] L2_dTRSV_o_UH;
+
+    float[] L2_cTRSV_A_nn;
+    float[] L2_cTRSV_A_nn_pu;
+    float[] L2_cTRSV_x_n1;
+    float[] L2_cTRSV_x_n2;
+    float[] L2_cTRSV_o_UN;
+    float[] L2_cTRSV_o_UN2;
+    float[] L2_cTRSV_o_UT;
+    float[] L2_cTRSV_o_UH;
+
+    double[] L2_zTRSV_A_nn;
+    double[] L2_zTRSV_A_nn_pu;
+    double[] L2_zTRSV_x_n1;
+    double[] L2_zTRSV_x_n2;
+    double[] L2_zTRSV_o_UN;
+    double[] L2_zTRSV_o_UN2;
+    double[] L2_zTRSV_o_UT;
+    double[] L2_zTRSV_o_UH;
+
+    float[] L2_sTBSV_A_nn;
+    float[] L2_sTBSV_x_n1;
+    float[] L2_sTBSV_x_n2;
+    float[] L2_sTBSV_o_UN;
+    float[] L2_sTBSV_o_UN2;
+    float[] L2_sTBSV_o_UT;
+    float[] L2_sTBSV_o_UH;
+
+    double[] L2_dTBSV_A_nn;
+    double[] L2_dTBSV_x_n1;
+    double[] L2_dTBSV_x_n2;
+    double[] L2_dTBSV_o_UN;
+    double[] L2_dTBSV_o_UN2;
+    double[] L2_dTBSV_o_UT;
+    double[] L2_dTBSV_o_UH;
+
+    float[] L2_cTBSV_A_nn;
+    float[] L2_cTBSV_x_n1;
+    float[] L2_cTBSV_x_n2;
+    float[] L2_cTBSV_o_UN;
+    float[] L2_cTBSV_o_UN2;
+    float[] L2_cTBSV_o_UT;
+    float[] L2_cTBSV_o_UH;
+
+    double[] L2_zTBSV_A_nn;
+    double[] L2_zTBSV_x_n1;
+    double[] L2_zTBSV_x_n2;
+    double[] L2_zTBSV_o_UN;
+    double[] L2_zTBSV_o_UN2;
+    double[] L2_zTBSV_o_UT;
+    double[] L2_zTBSV_o_UH;
+
+    float[] L2_sGER_A_mn;
+    float[] L2_sGER_x_m1;
+    float[] L2_sGER_x_m2;
+    float[] L2_sGER_y_n1;
+    float[] L2_sGER_y_n2;
+    float[] L2_sGER_o_N;
+
+    double[] L2_dGER_A_mn;
+    double[] L2_dGER_x_m1;
+    double[] L2_dGER_x_m2;
+    double[] L2_dGER_y_n1;
+    double[] L2_dGER_y_n2;
+    double[] L2_dGER_o_N;
+
+    float[] L2_cGERU_A_mn;
+    float[] L2_cGERU_x_m1;
+    float[] L2_cGERU_x_m2;
+    float[] L2_cGERU_y_n1;
+    float[] L2_cGERU_y_n2;
+    float[] L2_cGERU_o_N;
+
+    double[] L2_zGERU_A_mn;
+    double[] L2_zGERU_x_m1;
+    double[] L2_zGERU_x_m2;
+    double[] L2_zGERU_y_n1;
+    double[] L2_zGERU_y_n2;
+    double[] L2_zGERU_o_N;
+
+    float[] L2_cGERC_A_mn;
+    float[] L2_cGERC_x_m1;
+    float[] L2_cGERC_x_m2;
+    float[] L2_cGERC_y_n1;
+    float[] L2_cGERC_y_n2;
+    float[] L2_cGERC_o_N;
+
+    double[] L2_zGERC_A_mn;
+    double[] L2_zGERC_x_m1;
+    double[] L2_zGERC_x_m2;
+    double[] L2_zGERC_y_n1;
+    double[] L2_zGERC_y_n2;
+    double[] L2_zGERC_o_N;
+
+    float[] L2_cHER_A_nn;
+    float[] L2_cHER_A_nn_pu;
+    float[] L2_cHER_x_n1;
+    float[] L2_cHER_x_n2;
+    float[] L2_cHER_o_N;
+    float[] L2_cHER_o_N_pu;
+
+    double[] L2_zHER_A_nn;
+    double[] L2_zHER_A_nn_pu;
+    double[] L2_zHER_x_n1;
+    double[] L2_zHER_x_n2;
+    double[] L2_zHER_o_N;
+    double[] L2_zHER_o_N_pu;
+
+    float[] L2_cHER2_A_nn;
+    float[] L2_cHER2_A_nn_pu;
+    float[] L2_cHER2_x_n1;
+    float[] L2_cHER2_x_n2;
+    float[] L2_cHER2_y_n1;
+    float[] L2_cHER2_y_n2;
+    float[] L2_cHER2_o_N;
+    float[] L2_cHER2_o_N_pu;
+
+    double[] L2_zHER2_A_nn;
+    double[] L2_zHER2_A_nn_pu;
+    double[] L2_zHER2_x_n1;
+    double[] L2_zHER2_x_n2;
+    double[] L2_zHER2_y_n1;
+    double[] L2_zHER2_y_n2;
+    double[] L2_zHER2_o_N;
+    double[] L2_zHER2_o_N_pu;
+
+    float[] L2_sSYR_A_nn;
+    float[] L2_sSYR_A_nn_pu;
+    float[] L2_sSYR_x_n1;
+    float[] L2_sSYR_x_n2;
+    float[] L2_sSYR_o_N;
+    float[] L2_sSYR_o_N_pu;
+
+    double[] L2_dSYR_A_nn;
+    double[] L2_dSYR_A_nn_pu;
+    double[] L2_dSYR_x_n1;
+    double[] L2_dSYR_x_n2;
+    double[] L2_dSYR_o_N;
+    double[] L2_dSYR_o_N_pu;
+
+    float[] L2_sSYR2_A_nn;
+    float[] L2_sSYR2_A_nn_pu;
+    float[] L2_sSYR2_x_n1;
+    float[] L2_sSYR2_x_n2;
+    float[] L2_sSYR2_y_n1;
+    float[] L2_sSYR2_y_n2;
+    float[] L2_sSYR2_o_N;
+    float[] L2_sSYR2_o_N_pu;
+
+    double[] L2_dSYR2_A_nn;
+    double[] L2_dSYR2_A_nn_pu;
+    double[] L2_dSYR2_x_n1;
+    double[] L2_dSYR2_x_n2;
+    double[] L2_dSYR2_y_n1;
+    double[] L2_dSYR2_y_n2;
+    double[] L2_dSYR2_o_N;
+    double[] L2_dSYR2_o_N_pu;
+
+    float[] L3_sGEMM_A_mk;
+    float[] L3_sGEMM_B_kn;
+    float[] L3_sGEMM_C_mn;
+    float[] L3_sGEMM_o_NN;
+    float[] L3_sGEMM_A_km;
+    float[] L3_sGEMM_B_nk;
+    float[] L3_sGEMM_o_TT;
+    float[] L3_sGEMM_o_HH;
+
+    double[] L3_dGEMM_A_mk;
+    double[] L3_dGEMM_B_kn;
+    double[] L3_dGEMM_C_mn;
+    double[] L3_dGEMM_o_NN;
+    double[] L3_dGEMM_A_km;
+    double[] L3_dGEMM_B_nk;
+    double[] L3_dGEMM_o_TT;
+    double[] L3_dGEMM_o_HH;
+    float[] L3_cGEMM_A_mk;
+    float[] L3_cGEMM_B_kn;
+    float[] L3_cGEMM_C_mn;
+    float[] L3_cGEMM_o_NN;
+    float[] L3_cGEMM_A_km;
+    float[] L3_cGEMM_B_nk;
+    float[] L3_cGEMM_o_TT;
+    float[] L3_cGEMM_o_HH;
+
+    double[] L3_zGEMM_A_mk;
+    double[] L3_zGEMM_B_kn;
+    double[] L3_zGEMM_C_mn;
+    double[] L3_zGEMM_o_NN;
+    double[] L3_zGEMM_A_km;
+    double[] L3_zGEMM_B_nk;
+    double[] L3_zGEMM_o_TT;
+    double[] L3_zGEMM_o_HH;
+
+    float[] L3_sSYMM_A_mm;
+    float[] L3_sSYMM_B_mn;
+    float[] L3_sSYMM_C_mn;
+    float[] L3_sSYMM_o_L;
+    float[] L3_sSYMM_A_nn;
+    float[] L3_sSYMM_o_R;
+
+    double[] L3_dSYMM_A_mm;
+    double[] L3_dSYMM_B_mn;
+    double[] L3_dSYMM_C_mn;
+    double[] L3_dSYMM_o_L;
+    double[] L3_dSYMM_A_nn;
+    double[] L3_dSYMM_o_R;
+
+    float[] L3_cSYMM_A_mm;
+    float[] L3_cSYMM_B_mn;
+    float[] L3_cSYMM_C_mn;
+    float[] L3_cSYMM_o_L;
+    float[] L3_cSYMM_A_nn;
+    float[] L3_cSYMM_o_R;
+
+    double[] L3_zSYMM_A_mm;
+    double[] L3_zSYMM_B_mn;
+    double[] L3_zSYMM_C_mn;
+    double[] L3_zSYMM_o_L;
+    double[] L3_zSYMM_A_nn;
+    double[] L3_zSYMM_o_R;
+
+    float[] L3_cHEMM_A_mm;
+    float[] L3_cHEMM_B_mn;
+    float[] L3_cHEMM_C_mn;
+    float[] L3_cHEMM_o_L;
+    float[] L3_cHEMM_A_nn;
+    float[] L3_cHEMM_o_R;
+
+    double[] L3_zHEMM_A_mm;
+    double[] L3_zHEMM_B_mn;
+    double[] L3_zHEMM_C_mn;
+    double[] L3_zHEMM_o_L;
+    double[] L3_zHEMM_A_nn;
+    double[] L3_zHEMM_o_R;
+
+    float[] L3_sSYRK_A_nk;
+    float[] L3_sSYRK_C_nn;
+    float[] L3_sSYRK_o_N;
+    float[] L3_sSYRK_A_kn;
+    float[] L3_sSYRK_o_T;
+
+    double[] L3_dSYRK_A_nk;
+    double[] L3_dSYRK_C_nn;
+    double[] L3_dSYRK_o_N;
+    double[] L3_dSYRK_A_kn;
+    double[] L3_dSYRK_o_T;
+
+    float[] L3_cSYRK_A_nk;
+    float[] L3_cSYRK_C_nn;
+    float[] L3_cSYRK_o_N;
+    float[] L3_cSYRK_A_kn;
+    float[] L3_cSYRK_o_T;
+
+    double[] L3_zSYRK_A_nk;
+    double[] L3_zSYRK_C_nn;
+    double[] L3_zSYRK_o_N;
+    double[] L3_zSYRK_A_kn;
+    double[] L3_zSYRK_o_T;
+
+    float[] L3_cHERK_A_nk;
+    float[] L3_cHERK_C_nn;
+    float[] L3_cHERK_o_N;
+    float[] L3_cHERK_A_kn;
+    float[] L3_cHERK_o_H;
+
+    double[] L3_zHERK_A_nk;
+    double[] L3_zHERK_C_nn;
+    double[] L3_zHERK_o_N;
+    double[] L3_zHERK_A_kn;
+    double[] L3_zHERK_o_H;
+
+    float[] L3_sSYR2K_A_nk;
+    float[] L3_sSYR2K_B_nk;
+    float[] L3_sSYR2K_C_nn;
+    float[] L3_sSYR2K_o_N;
+    float[] L3_sSYR2K_A_kn;
+    float[] L3_sSYR2K_B_kn;
+    float[] L3_sSYR2K_o_T;
+
+    double[] L3_dSYR2K_A_nk;
+    double[] L3_dSYR2K_B_nk;
+    double[] L3_dSYR2K_C_nn;
+    double[] L3_dSYR2K_o_N;
+    double[] L3_dSYR2K_A_kn;
+    double[] L3_dSYR2K_B_kn;
+    double[] L3_dSYR2K_o_T;
+
+    float[] L3_cSYR2K_A_nk;
+    float[] L3_cSYR2K_B_nk;
+    float[] L3_cSYR2K_C_nn;
+    float[] L3_cSYR2K_o_N;
+    float[] L3_cSYR2K_A_kn;
+    float[] L3_cSYR2K_B_kn;
+    float[] L3_cSYR2K_o_T;
+
+    double[] L3_zSYR2K_A_nk;
+    double[] L3_zSYR2K_B_nk;
+    double[] L3_zSYR2K_C_nn;
+    double[] L3_zSYR2K_o_N;
+    double[] L3_zSYR2K_A_kn;
+    double[] L3_zSYR2K_B_kn;
+    double[] L3_zSYR2K_o_T;
+
+    float[] L3_cHER2K_A_nk;
+    float[] L3_cHER2K_B_nk;
+    float[] L3_cHER2K_C_nn;
+    float[] L3_cHER2K_o_N;
+    float[] L3_cHER2K_A_kn;
+    float[] L3_cHER2K_B_kn;
+    float[] L3_cHER2K_o_H;
+
+    double[] L3_zHER2K_A_nk;
+    double[] L3_zHER2K_B_nk;
+    double[] L3_zHER2K_C_nn;
+    double[] L3_zHER2K_o_N;
+    double[] L3_zHER2K_A_kn;
+    double[] L3_zHER2K_B_kn;
+    double[] L3_zHER2K_o_H;
+
+    float[] L3_sTRMM_A_mm;
+    float[] L3_sTRMM_B_mn;
+    float[] L3_sTRMM_o_LUN;
+    float[] L3_sTRMM_A_nn;
+    float[] L3_sTRMM_o_RLT;
+
+    double[] L3_dTRMM_A_mm;
+    double[] L3_dTRMM_B_mn;
+    double[] L3_dTRMM_o_LUN;
+    double[] L3_dTRMM_A_nn;
+    double[] L3_dTRMM_o_RLT;
+
+    float[] L3_cTRMM_A_mm;
+    float[] L3_cTRMM_B_mn;
+    float[] L3_cTRMM_o_LUN;
+    float[] L3_cTRMM_A_nn;
+    float[] L3_cTRMM_o_RLT;
+
+    double[] L3_zTRMM_A_mm;
+    double[] L3_zTRMM_B_mn;
+    double[] L3_zTRMM_o_LUN;
+    double[] L3_zTRMM_A_nn;
+    double[] L3_zTRMM_o_RLT;
+
+    float[] L3_sTRSM_A_mm;
+    float[] L3_sTRSM_B_mn;
+    float[] L3_sTRSM_o_LUN;
+    float[] L3_sTRSM_A_nn;
+    float[] L3_sTRSM_o_RLT;
+
+    double[] L3_dTRSM_A_mm;
+    double[] L3_dTRSM_B_mn;
+    double[] L3_dTRSM_o_LUN;
+    double[] L3_dTRSM_A_nn;
+    double[] L3_dTRSM_o_RLT;
+
+    float[] L3_cTRSM_A_mm;
+    float[] L3_cTRSM_B_mn;
+    float[] L3_cTRSM_o_LUN;
+    float[] L3_cTRSM_A_nn;
+    float[] L3_cTRSM_o_RLT;
+
+    double[] L3_zTRSM_A_mm;
+    double[] L3_zTRSM_B_mn;
+    double[] L3_zTRSM_o_LUN;
+    double[] L3_zTRSM_A_nn;
+    double[] L3_zTRSM_o_RLT;
+
+    //load dimensions of matrixes
+    private void loadMNK() throws Exception {
+        String data = "";
+        int skipLine = 3;
+
+        for (int i = 0; i < skipLine; i++) {
+            data = mBufReader.readLine();
+        }
+        data = mBufReader.readLine();
+
+        String[] results = data.split(" ");
+        dM = Integer.parseInt(results[0]);
+        dN = Integer.parseInt(results[1]);
+        dK = Integer.parseInt(results[2]);
+        KL = Integer.parseInt(results[3]);
+        KU = Integer.parseInt(results[4]);
+    }
+
+    private float[] loadFloatArray() throws Exception {
+        String data = "";
+        int skipLine = 2;
+
+        for (int i = 0; i < skipLine; i++) {
+            data = mBufReader.readLine();
+        }
+        data = mBufReader.readLine();
+        String[] results = data.split(", ");
+
+        float[] floatArr = new float[results.length];
+        for (int i = 0; i < floatArr.length; i++) {
+            floatArr[i] = Float.parseFloat(results[i]);
+        }
+
+        return floatArr;
+    }
+
+    private double[] loadDoubleArray() throws Exception {
+        String data = "";
+        int skipLine = 2;
+
+        for (int i = 0; i < skipLine; i++) {
+            data = mBufReader.readLine();
+        }
+        data = mBufReader.readLine();
+        String[] results = data.split(", ");
+
+        double[] doubleArr = new double[results.length];
+        for (int i = 0; i < doubleArr.length; i++) {
+            doubleArr[i] = Double.parseDouble(results[i]);
+        }
+        return doubleArr;
+    }
+
+    //load data for L2 BLAS
+    private void loadGEMVData() throws Exception {
+        L2_sGEMV_A_mn = loadFloatArray();
+        L2_sGEMV_x_n1 = loadFloatArray();
+        L2_sGEMV_x_n2 = loadFloatArray();
+        L2_sGEMV_y_m1 = loadFloatArray();
+        L2_sGEMV_y_m2 = loadFloatArray();
+        L2_sGEMV_o_N = loadFloatArray();
+        L2_sGEMV_o_N2 = loadFloatArray();
+        L2_sGEMV_o_T = loadFloatArray();
+        L2_sGEMV_o_H = loadFloatArray();
+
+        L2_dGEMV_A_mn = loadDoubleArray();
+        L2_dGEMV_x_n1 = loadDoubleArray();
+        L2_dGEMV_x_n2 = loadDoubleArray();
+        L2_dGEMV_y_m1 = loadDoubleArray();
+        L2_dGEMV_y_m2 = loadDoubleArray();
+        L2_dGEMV_o_N = loadDoubleArray();
+        L2_dGEMV_o_N2 = loadDoubleArray();
+        L2_dGEMV_o_T = loadDoubleArray();
+        L2_dGEMV_o_H = loadDoubleArray();
+
+        L2_cGEMV_A_mn = loadFloatArray();
+        L2_cGEMV_x_n1 = loadFloatArray();
+        L2_cGEMV_x_n2 = loadFloatArray();
+        L2_cGEMV_y_m1 = loadFloatArray();
+        L2_cGEMV_y_m2 = loadFloatArray();
+        L2_cGEMV_o_N = loadFloatArray();
+        L2_cGEMV_o_N2 = loadFloatArray();
+        L2_cGEMV_o_T = loadFloatArray();
+        L2_cGEMV_o_H = loadFloatArray();
+
+        L2_zGEMV_A_mn = loadDoubleArray();
+        L2_zGEMV_x_n1 = loadDoubleArray();
+        L2_zGEMV_x_n2 = loadDoubleArray();
+        L2_zGEMV_y_m1 = loadDoubleArray();
+        L2_zGEMV_y_m2 = loadDoubleArray();
+        L2_zGEMV_o_N = loadDoubleArray();
+        L2_zGEMV_o_N2 = loadDoubleArray();
+        L2_zGEMV_o_T = loadDoubleArray();
+        L2_zGEMV_o_H = loadDoubleArray();
+
+    }
+
+    private void loadGBMVData() throws Exception {
+        L2_sGBMV_A_mn = loadFloatArray();
+        L2_sGBMV_x_n1 = loadFloatArray();
+        L2_sGBMV_x_n2 = loadFloatArray();
+        L2_sGBMV_y_m1 = loadFloatArray();
+        L2_sGBMV_y_m2 = loadFloatArray();
+        L2_sGBMV_o_N = loadFloatArray();
+        L2_sGBMV_o_N2 = loadFloatArray();
+        L2_sGBMV_o_T = loadFloatArray();
+        L2_sGBMV_o_H = loadFloatArray();
+
+        L2_dGBMV_A_mn = loadDoubleArray();
+        L2_dGBMV_x_n1 = loadDoubleArray();
+        L2_dGBMV_x_n2 = loadDoubleArray();
+        L2_dGBMV_y_m1 = loadDoubleArray();
+        L2_dGBMV_y_m2 = loadDoubleArray();
+        L2_dGBMV_o_N = loadDoubleArray();
+        L2_dGBMV_o_N2 = loadDoubleArray();
+        L2_dGBMV_o_T = loadDoubleArray();
+        L2_dGBMV_o_H = loadDoubleArray();
+
+        L2_cGBMV_A_mn = loadFloatArray();
+        L2_cGBMV_x_n1 = loadFloatArray();
+        L2_cGBMV_x_n2 = loadFloatArray();
+        L2_cGBMV_y_m1 = loadFloatArray();
+        L2_cGBMV_y_m2 = loadFloatArray();
+        L2_cGBMV_o_N = loadFloatArray();
+        L2_cGBMV_o_N2 = loadFloatArray();
+        L2_cGBMV_o_T = loadFloatArray();
+        L2_cGBMV_o_H = loadFloatArray();
+
+        L2_zGBMV_A_mn = loadDoubleArray();
+        L2_zGBMV_x_n1 = loadDoubleArray();
+        L2_zGBMV_x_n2 = loadDoubleArray();
+        L2_zGBMV_y_m1 = loadDoubleArray();
+        L2_zGBMV_y_m2 = loadDoubleArray();
+        L2_zGBMV_o_N = loadDoubleArray();
+        L2_zGBMV_o_N2 = loadDoubleArray();
+        L2_zGBMV_o_T = loadDoubleArray();
+        L2_zGBMV_o_H = loadDoubleArray();
+    }
+
+    private void loadHEMVData() throws Exception {
+        L2_cHEMV_A_nn = loadFloatArray();
+        L2_cHEMV_A_nn_pu = loadFloatArray();
+        L2_cHEMV_x_n1 = loadFloatArray();
+        L2_cHEMV_x_n2 = loadFloatArray();
+        L2_cHEMV_y_n1 = loadFloatArray();
+        L2_cHEMV_y_n2 = loadFloatArray();
+        L2_cHEMV_o_N = loadFloatArray();
+        L2_cHEMV_o_N2 = loadFloatArray();
+
+        L2_zHEMV_A_nn = loadDoubleArray();
+        L2_zHEMV_A_nn_pu = loadDoubleArray();
+        L2_zHEMV_x_n1 = loadDoubleArray();
+        L2_zHEMV_x_n2 = loadDoubleArray();
+        L2_zHEMV_y_n1 = loadDoubleArray();
+        L2_zHEMV_y_n2 = loadDoubleArray();
+        L2_zHEMV_o_N = loadDoubleArray();
+        L2_zHEMV_o_N2 = loadDoubleArray();
+    }
+
+    private void loadHBMVData() throws Exception {
+        L2_cHBMV_A_nn = loadFloatArray();
+        L2_cHBMV_x_n1 = loadFloatArray();
+        L2_cHBMV_x_n2 = loadFloatArray();
+        L2_cHBMV_y_n1 = loadFloatArray();
+        L2_cHBMV_y_n2 = loadFloatArray();
+        L2_cHBMV_o_N = loadFloatArray();
+        L2_cHBMV_o_N2 = loadFloatArray();
+
+        L2_zHBMV_A_nn = loadDoubleArray();
+        L2_zHBMV_x_n1 = loadDoubleArray();
+        L2_zHBMV_x_n2 = loadDoubleArray();
+        L2_zHBMV_y_n1 = loadDoubleArray();
+        L2_zHBMV_y_n2 = loadDoubleArray();
+        L2_zHBMV_o_N = loadDoubleArray();
+        L2_zHBMV_o_N2 = loadDoubleArray();
+    }
+
+    private void loadSYMVData() throws Exception {
+        L2_sSYMV_A_nn = loadFloatArray();
+        L2_sSYMV_A_nn_pu = loadFloatArray();
+        L2_sSYMV_x_n1 = loadFloatArray();
+        L2_sSYMV_x_n2 = loadFloatArray();
+        L2_sSYMV_y_n1 = loadFloatArray();
+        L2_sSYMV_y_n2 = loadFloatArray();
+        L2_sSYMV_o_N = loadFloatArray();
+        L2_sSYMV_o_N2 = loadFloatArray();
+
+        L2_dSYMV_A_nn = loadDoubleArray();
+        L2_dSYMV_A_nn_pu = loadDoubleArray();
+        L2_dSYMV_x_n1 = loadDoubleArray();
+        L2_dSYMV_x_n2 = loadDoubleArray();
+        L2_dSYMV_y_n1 = loadDoubleArray();
+        L2_dSYMV_y_n2 = loadDoubleArray();
+        L2_dSYMV_o_N = loadDoubleArray();
+        L2_dSYMV_o_N2 = loadDoubleArray();
+    }
+
+    private void loadSBMVData() throws Exception {
+        L2_sSBMV_A_nn = loadFloatArray();
+        L2_sSBMV_x_n1 = loadFloatArray();
+        L2_sSBMV_x_n2 = loadFloatArray();
+        L2_sSBMV_y_n1 = loadFloatArray();
+        L2_sSBMV_y_n2 = loadFloatArray();
+        L2_sSBMV_o_N = loadFloatArray();
+        L2_sSBMV_o_N2 = loadFloatArray();
+
+        L2_dSBMV_A_nn = loadDoubleArray();
+        L2_dSBMV_x_n1 = loadDoubleArray();
+        L2_dSBMV_x_n2 = loadDoubleArray();
+        L2_dSBMV_y_n1 = loadDoubleArray();
+        L2_dSBMV_y_n2 = loadDoubleArray();
+        L2_dSBMV_o_N = loadDoubleArray();
+        L2_dSBMV_o_N2 = loadDoubleArray();
+    }
+
+    private void loadTRMVData() throws Exception {
+        L2_sTRMV_A_nn = loadFloatArray();
+        L2_sTRMV_A_nn_pu = loadFloatArray();
+        L2_sTRMV_x_n1 = loadFloatArray();
+        L2_sTRMV_x_n2 = loadFloatArray();
+        L2_sTRMV_o_UN = loadFloatArray();
+        L2_sTRMV_o_UN2 = loadFloatArray();
+        L2_sTRMV_o_UT = loadFloatArray();
+        L2_sTRMV_o_UH = loadFloatArray();
+
+        L2_dTRMV_A_nn = loadDoubleArray();
+        L2_dTRMV_A_nn_pu = loadDoubleArray();
+        L2_dTRMV_x_n1 = loadDoubleArray();
+        L2_dTRMV_x_n2 = loadDoubleArray();
+        L2_dTRMV_o_UN = loadDoubleArray();
+        L2_dTRMV_o_UN2 = loadDoubleArray();
+        L2_dTRMV_o_UT = loadDoubleArray();
+        L2_dTRMV_o_UH = loadDoubleArray();
+
+        L2_cTRMV_A_nn = loadFloatArray();
+        L2_cTRMV_A_nn_pu = loadFloatArray();
+        L2_cTRMV_x_n1 = loadFloatArray();
+        L2_cTRMV_x_n2 = loadFloatArray();
+        L2_cTRMV_o_UN = loadFloatArray();
+        L2_cTRMV_o_UN2 = loadFloatArray();
+        L2_cTRMV_o_UT = loadFloatArray();
+        L2_cTRMV_o_UH = loadFloatArray();
+
+        L2_zTRMV_A_nn = loadDoubleArray();
+        L2_zTRMV_A_nn_pu = loadDoubleArray();
+        L2_zTRMV_x_n1 = loadDoubleArray();
+        L2_zTRMV_x_n2 = loadDoubleArray();
+        L2_zTRMV_o_UN = loadDoubleArray();
+        L2_zTRMV_o_UN2 = loadDoubleArray();
+        L2_zTRMV_o_UT = loadDoubleArray();
+        L2_zTRMV_o_UH = loadDoubleArray();
+    }
+
+    private void loadTBMVData() throws Exception {
+        L2_sTBMV_A_nn = loadFloatArray();
+        L2_sTBMV_x_n1 = loadFloatArray();
+        L2_sTBMV_x_n2 = loadFloatArray();
+        L2_sTBMV_o_UN = loadFloatArray();
+        L2_sTBMV_o_UN2 = loadFloatArray();
+        L2_sTBMV_o_UT = loadFloatArray();
+        L2_sTBMV_o_UH = loadFloatArray();
+
+        L2_dTBMV_A_nn = loadDoubleArray();
+        L2_dTBMV_x_n1 = loadDoubleArray();
+        L2_dTBMV_x_n2 = loadDoubleArray();
+        L2_dTBMV_o_UN = loadDoubleArray();
+        L2_dTBMV_o_UN2 = loadDoubleArray();
+        L2_dTBMV_o_UT = loadDoubleArray();
+        L2_dTBMV_o_UH = loadDoubleArray();
+
+        L2_cTBMV_A_nn = loadFloatArray();
+        L2_cTBMV_x_n1 = loadFloatArray();
+        L2_cTBMV_x_n2 = loadFloatArray();
+        L2_cTBMV_o_UN = loadFloatArray();
+        L2_cTBMV_o_UN2 = loadFloatArray();
+        L2_cTBMV_o_UT = loadFloatArray();
+        L2_cTBMV_o_UH = loadFloatArray();
+
+        L2_zTBMV_A_nn = loadDoubleArray();
+        L2_zTBMV_x_n1 = loadDoubleArray();
+        L2_zTBMV_x_n2 = loadDoubleArray();
+        L2_zTBMV_o_UN = loadDoubleArray();
+        L2_zTBMV_o_UN2 = loadDoubleArray();
+        L2_zTBMV_o_UT = loadDoubleArray();
+        L2_zTBMV_o_UH = loadDoubleArray();
+    }
+
+    private void loadTRSVData() throws Exception {
+        L2_sTRSV_A_nn = loadFloatArray();
+        L2_sTRSV_A_nn_pu = loadFloatArray();
+        L2_sTRSV_x_n1 = loadFloatArray();
+        L2_sTRSV_x_n2 = loadFloatArray();
+        L2_sTRSV_o_UN = loadFloatArray();
+        L2_sTRSV_o_UN2 = loadFloatArray();
+        L2_sTRSV_o_UT = loadFloatArray();
+        L2_sTRSV_o_UH = loadFloatArray();
+
+        L2_dTRSV_A_nn = loadDoubleArray();
+        L2_dTRSV_A_nn_pu = loadDoubleArray();
+        L2_dTRSV_x_n1 = loadDoubleArray();
+        L2_dTRSV_x_n2 = loadDoubleArray();
+        L2_dTRSV_o_UN = loadDoubleArray();
+        L2_dTRSV_o_UN2 = loadDoubleArray();
+        L2_dTRSV_o_UT = loadDoubleArray();
+        L2_dTRSV_o_UH = loadDoubleArray();
+
+        L2_cTRSV_A_nn = loadFloatArray();
+        L2_cTRSV_A_nn_pu = loadFloatArray();
+        L2_cTRSV_x_n1 = loadFloatArray();
+        L2_cTRSV_x_n2 = loadFloatArray();
+        L2_cTRSV_o_UN = loadFloatArray();
+        L2_cTRSV_o_UN2 = loadFloatArray();
+        L2_cTRSV_o_UT = loadFloatArray();
+        L2_cTRSV_o_UH = loadFloatArray();
+
+        L2_zTRSV_A_nn = loadDoubleArray();
+        L2_zTRSV_A_nn_pu = loadDoubleArray();
+        L2_zTRSV_x_n1 = loadDoubleArray();
+        L2_zTRSV_x_n2 = loadDoubleArray();
+        L2_zTRSV_o_UN = loadDoubleArray();
+        L2_zTRSV_o_UN2 = loadDoubleArray();
+        L2_zTRSV_o_UT = loadDoubleArray();
+        L2_zTRSV_o_UH = loadDoubleArray();
+    }
+
+    private void loadTBSVData() throws Exception {
+        L2_sTBSV_A_nn = loadFloatArray();
+        L2_sTBSV_x_n1 = loadFloatArray();
+        L2_sTBSV_x_n2 = loadFloatArray();
+        L2_sTBSV_o_UN = loadFloatArray();
+        L2_sTBSV_o_UN2 = loadFloatArray();
+        L2_sTBSV_o_UT = loadFloatArray();
+        L2_sTBSV_o_UH = loadFloatArray();
+
+        L2_dTBSV_A_nn = loadDoubleArray();
+        L2_dTBSV_x_n1 = loadDoubleArray();
+        L2_dTBSV_x_n2 = loadDoubleArray();
+        L2_dTBSV_o_UN = loadDoubleArray();
+        L2_dTBSV_o_UN2 = loadDoubleArray();
+        L2_dTBSV_o_UT = loadDoubleArray();
+        L2_dTBSV_o_UH = loadDoubleArray();
+
+        L2_cTBSV_A_nn = loadFloatArray();
+        L2_cTBSV_x_n1 = loadFloatArray();
+        L2_cTBSV_x_n2 = loadFloatArray();
+        L2_cTBSV_o_UN = loadFloatArray();
+        L2_cTBSV_o_UN2 = loadFloatArray();
+        L2_cTBSV_o_UT = loadFloatArray();
+        L2_cTBSV_o_UH = loadFloatArray();
+
+        L2_zTBSV_A_nn = loadDoubleArray();
+        L2_zTBSV_x_n1 = loadDoubleArray();
+        L2_zTBSV_x_n2 = loadDoubleArray();
+        L2_zTBSV_o_UN = loadDoubleArray();
+        L2_zTBSV_o_UN2 = loadDoubleArray();
+        L2_zTBSV_o_UT = loadDoubleArray();
+        L2_zTBSV_o_UH = loadDoubleArray();
+    }
+
+    private void loadGERData() throws Exception {
+        L2_sGER_A_mn = loadFloatArray();
+        L2_sGER_x_m1 = loadFloatArray();
+        L2_sGER_x_m2 = loadFloatArray();
+        L2_sGER_y_n1 = loadFloatArray();
+        L2_sGER_y_n2 = loadFloatArray();
+        L2_sGER_o_N = loadFloatArray();
+
+        L2_dGER_A_mn = loadDoubleArray();
+        L2_dGER_x_m1 = loadDoubleArray();
+        L2_dGER_x_m2 = loadDoubleArray();
+        L2_dGER_y_n1 = loadDoubleArray();
+        L2_dGER_y_n2 = loadDoubleArray();
+        L2_dGER_o_N = loadDoubleArray();
+    }
+
+    private void loadGERUData() throws Exception {
+        L2_cGERU_A_mn = loadFloatArray();
+        L2_cGERU_x_m1 = loadFloatArray();
+        L2_cGERU_x_m2 = loadFloatArray();
+        L2_cGERU_y_n1 = loadFloatArray();
+        L2_cGERU_y_n2 = loadFloatArray();
+        L2_cGERU_o_N = loadFloatArray();
+
+        L2_zGERU_A_mn = loadDoubleArray();
+        L2_zGERU_x_m1 = loadDoubleArray();
+        L2_zGERU_x_m2 = loadDoubleArray();
+        L2_zGERU_y_n1 = loadDoubleArray();
+        L2_zGERU_y_n2 = loadDoubleArray();
+        L2_zGERU_o_N = loadDoubleArray();
+    }
+
+    private void loadGERCData() throws Exception {
+        L2_cGERC_A_mn = loadFloatArray();
+        L2_cGERC_x_m1 = loadFloatArray();
+        L2_cGERC_x_m2 = loadFloatArray();
+        L2_cGERC_y_n1 = loadFloatArray();
+        L2_cGERC_y_n2 = loadFloatArray();
+        L2_cGERC_o_N = loadFloatArray();
+
+        L2_zGERC_A_mn = loadDoubleArray();
+        L2_zGERC_x_m1 = loadDoubleArray();
+        L2_zGERC_x_m2 = loadDoubleArray();
+        L2_zGERC_y_n1 = loadDoubleArray();
+        L2_zGERC_y_n2 = loadDoubleArray();
+        L2_zGERC_o_N = loadDoubleArray();
+    }
+
+    private void loadHERData() throws Exception {
+        L2_cHER_A_nn = loadFloatArray();
+        L2_cHER_A_nn_pu = loadFloatArray();
+        L2_cHER_x_n1 = loadFloatArray();
+        L2_cHER_x_n2 = loadFloatArray();
+        L2_cHER_o_N = loadFloatArray();
+        L2_cHER_o_N_pu = loadFloatArray();
+
+        L2_zHER_A_nn = loadDoubleArray();
+        L2_zHER_A_nn_pu = loadDoubleArray();
+        L2_zHER_x_n1 = loadDoubleArray();
+        L2_zHER_x_n2 = loadDoubleArray();
+        L2_zHER_o_N = loadDoubleArray();
+        L2_zHER_o_N_pu = loadDoubleArray();
+    }
+
+    private void loadHER2Data() throws Exception {
+        L2_cHER2_A_nn = loadFloatArray();
+        L2_cHER2_A_nn_pu = loadFloatArray();
+        L2_cHER2_x_n1 = loadFloatArray();
+        L2_cHER2_x_n2 = loadFloatArray();
+        L2_cHER2_y_n1 = loadFloatArray();
+        L2_cHER2_y_n2 = loadFloatArray();
+        L2_cHER2_o_N = loadFloatArray();
+        L2_cHER2_o_N_pu = loadFloatArray();
+
+        L2_zHER2_A_nn = loadDoubleArray();
+        L2_zHER2_A_nn_pu = loadDoubleArray();
+        L2_zHER2_x_n1 = loadDoubleArray();
+        L2_zHER2_x_n2 = loadDoubleArray();
+        L2_zHER2_y_n1 = loadDoubleArray();
+        L2_zHER2_y_n2 = loadDoubleArray();
+        L2_zHER2_o_N = loadDoubleArray();
+        L2_zHER2_o_N_pu = loadDoubleArray();
+    }
+
+    private void loadSYRData() throws Exception {
+        L2_sSYR_A_nn = loadFloatArray();
+        L2_sSYR_A_nn_pu = loadFloatArray();
+        L2_sSYR_x_n1 = loadFloatArray();
+        L2_sSYR_x_n2 = loadFloatArray();
+        L2_sSYR_o_N = loadFloatArray();
+        L2_sSYR_o_N_pu = loadFloatArray();
+
+        L2_dSYR_A_nn = loadDoubleArray();
+        L2_dSYR_A_nn_pu = loadDoubleArray();
+        L2_dSYR_x_n1 = loadDoubleArray();
+        L2_dSYR_x_n2 = loadDoubleArray();
+        L2_dSYR_o_N = loadDoubleArray();
+        L2_dSYR_o_N_pu = loadDoubleArray();
+    }
+
+    private void loadSYR2Data() throws Exception {
+        L2_sSYR2_A_nn = loadFloatArray();
+        L2_sSYR2_A_nn_pu = loadFloatArray();
+        L2_sSYR2_x_n1 = loadFloatArray();
+        L2_sSYR2_x_n2 = loadFloatArray();
+        L2_sSYR2_y_n1 = loadFloatArray();
+        L2_sSYR2_y_n2 = loadFloatArray();
+        L2_sSYR2_o_N = loadFloatArray();
+        L2_sSYR2_o_N_pu = loadFloatArray();
+
+        L2_dSYR2_A_nn = loadDoubleArray();
+        L2_dSYR2_A_nn_pu = loadDoubleArray();
+        L2_dSYR2_x_n1 = loadDoubleArray();
+        L2_dSYR2_x_n2 = loadDoubleArray();
+        L2_dSYR2_y_n1 = loadDoubleArray();
+        L2_dSYR2_y_n2 = loadDoubleArray();
+        L2_dSYR2_o_N = loadDoubleArray();
+        L2_dSYR2_o_N_pu = loadDoubleArray();
+    }
+
+    //load data for L3 BLAS
+    private void loadGEMMData() throws Exception {
+        L3_sGEMM_A_mk = loadFloatArray();
+        L3_sGEMM_B_kn = loadFloatArray();
+        L3_sGEMM_C_mn = loadFloatArray();
+        L3_sGEMM_o_NN = loadFloatArray();
+        L3_sGEMM_A_km = loadFloatArray();
+        L3_sGEMM_B_nk = loadFloatArray();
+        L3_sGEMM_o_TT = loadFloatArray();
+        L3_sGEMM_o_HH = loadFloatArray();
+
+        L3_dGEMM_A_mk = loadDoubleArray();
+        L3_dGEMM_B_kn = loadDoubleArray();
+        L3_dGEMM_C_mn = loadDoubleArray();
+        L3_dGEMM_o_NN = loadDoubleArray();
+        L3_dGEMM_A_km = loadDoubleArray();
+        L3_dGEMM_B_nk = loadDoubleArray();
+        L3_dGEMM_o_TT = loadDoubleArray();
+        L3_dGEMM_o_HH = loadDoubleArray();
+
+        L3_cGEMM_A_mk = loadFloatArray();
+        L3_cGEMM_B_kn = loadFloatArray();
+        L3_cGEMM_C_mn = loadFloatArray();
+        L3_cGEMM_o_NN = loadFloatArray();
+        L3_cGEMM_A_km = loadFloatArray();
+        L3_cGEMM_B_nk = loadFloatArray();
+        L3_cGEMM_o_TT = loadFloatArray();
+        L3_cGEMM_o_HH = loadFloatArray();
+
+        L3_zGEMM_A_mk = loadDoubleArray();
+        L3_zGEMM_B_kn = loadDoubleArray();
+        L3_zGEMM_C_mn = loadDoubleArray();
+        L3_zGEMM_o_NN = loadDoubleArray();
+        L3_zGEMM_A_km = loadDoubleArray();
+        L3_zGEMM_B_nk = loadDoubleArray();
+        L3_zGEMM_o_TT = loadDoubleArray();
+        L3_zGEMM_o_HH = loadDoubleArray();
+    }
+
+    private void loadSYMMData() throws Exception {
+        L3_sSYMM_A_mm = loadFloatArray();
+        L3_sSYMM_B_mn = loadFloatArray();
+        L3_sSYMM_C_mn = loadFloatArray();
+        L3_sSYMM_o_L = loadFloatArray();
+        L3_sSYMM_A_nn = loadFloatArray();
+        L3_sSYMM_o_R = loadFloatArray();
+
+        L3_dSYMM_A_mm = loadDoubleArray();
+        L3_dSYMM_B_mn = loadDoubleArray();
+        L3_dSYMM_C_mn = loadDoubleArray();
+        L3_dSYMM_o_L = loadDoubleArray();
+        L3_dSYMM_A_nn = loadDoubleArray();
+        L3_dSYMM_o_R = loadDoubleArray();
+
+        L3_cSYMM_A_mm = loadFloatArray();
+        L3_cSYMM_B_mn = loadFloatArray();
+        L3_cSYMM_C_mn = loadFloatArray();
+        L3_cSYMM_o_L = loadFloatArray();
+        L3_cSYMM_A_nn = loadFloatArray();
+        L3_cSYMM_o_R = loadFloatArray();
+
+        L3_zSYMM_A_mm = loadDoubleArray();
+        L3_zSYMM_B_mn = loadDoubleArray();
+        L3_zSYMM_C_mn = loadDoubleArray();
+        L3_zSYMM_o_L = loadDoubleArray();
+        L3_zSYMM_A_nn = loadDoubleArray();
+        L3_zSYMM_o_R = loadDoubleArray();
+    }
+
+    private void loadHEMMData() throws Exception {
+        L3_cHEMM_A_mm = loadFloatArray();
+        L3_cHEMM_B_mn = loadFloatArray();
+        L3_cHEMM_C_mn = loadFloatArray();
+        L3_cHEMM_o_L = loadFloatArray();
+        L3_cHEMM_A_nn = loadFloatArray();
+        L3_cHEMM_o_R = loadFloatArray();
+
+        L3_zHEMM_A_mm = loadDoubleArray();
+        L3_zHEMM_B_mn = loadDoubleArray();
+        L3_zHEMM_C_mn = loadDoubleArray();
+        L3_zHEMM_o_L = loadDoubleArray();
+        L3_zHEMM_A_nn = loadDoubleArray();
+        L3_zHEMM_o_R = loadDoubleArray();
+    }
+
+    private void loadSYRKData() throws Exception {
+        L3_sSYRK_A_nk = loadFloatArray();
+        L3_sSYRK_C_nn = loadFloatArray();
+        L3_sSYRK_o_N = loadFloatArray();
+        L3_sSYRK_A_kn = loadFloatArray();
+        L3_sSYRK_o_T = loadFloatArray();
+
+        L3_dSYRK_A_nk = loadDoubleArray();
+        L3_dSYRK_C_nn = loadDoubleArray();
+        L3_dSYRK_o_N = loadDoubleArray();
+        L3_dSYRK_A_kn = loadDoubleArray();
+        L3_dSYRK_o_T = loadDoubleArray();
+
+        L3_cSYRK_A_nk = loadFloatArray();
+        L3_cSYRK_C_nn = loadFloatArray();
+        L3_cSYRK_o_N = loadFloatArray();
+        L3_cSYRK_A_kn = loadFloatArray();
+        L3_cSYRK_o_T = loadFloatArray();
+
+        L3_zSYRK_A_nk = loadDoubleArray();
+        L3_zSYRK_C_nn = loadDoubleArray();
+        L3_zSYRK_o_N = loadDoubleArray();
+        L3_zSYRK_A_kn = loadDoubleArray();
+        L3_zSYRK_o_T = loadDoubleArray();
+    }
+
+    private void loadHERKData() throws Exception {
+        L3_cHERK_A_nk = loadFloatArray();
+        L3_cHERK_C_nn = loadFloatArray();
+        L3_cHERK_o_N = loadFloatArray();
+        L3_cHERK_A_kn = loadFloatArray();
+        L3_cHERK_o_H = loadFloatArray();
+
+        L3_zHERK_A_nk = loadDoubleArray();
+        L3_zHERK_C_nn = loadDoubleArray();
+        L3_zHERK_o_N = loadDoubleArray();
+        L3_zHERK_A_kn = loadDoubleArray();
+        L3_zHERK_o_H = loadDoubleArray();
+    }
+
+    private void loadSYR2KData() throws Exception {
+        L3_sSYR2K_A_nk = loadFloatArray();
+        L3_sSYR2K_B_nk = loadFloatArray();
+        L3_sSYR2K_C_nn = loadFloatArray();
+        L3_sSYR2K_o_N = loadFloatArray();
+        L3_sSYR2K_A_kn = loadFloatArray();
+        L3_sSYR2K_B_kn = loadFloatArray();
+        L3_sSYR2K_o_T = loadFloatArray();
+
+        L3_dSYR2K_A_nk = loadDoubleArray();
+        L3_dSYR2K_B_nk = loadDoubleArray();
+        L3_dSYR2K_C_nn = loadDoubleArray();
+        L3_dSYR2K_o_N = loadDoubleArray();
+        L3_dSYR2K_A_kn = loadDoubleArray();
+        L3_dSYR2K_B_kn = loadDoubleArray();
+        L3_dSYR2K_o_T = loadDoubleArray();
+
+        L3_cSYR2K_A_nk = loadFloatArray();
+        L3_cSYR2K_B_nk = loadFloatArray();
+        L3_cSYR2K_C_nn = loadFloatArray();
+        L3_cSYR2K_o_N = loadFloatArray();
+        L3_cSYR2K_A_kn = loadFloatArray();
+        L3_cSYR2K_B_kn = loadFloatArray();
+        L3_cSYR2K_o_T = loadFloatArray();
+
+        L3_zSYR2K_A_nk = loadDoubleArray();
+        L3_zSYR2K_B_nk = loadDoubleArray();
+        L3_zSYR2K_C_nn = loadDoubleArray();
+        L3_zSYR2K_o_N = loadDoubleArray();
+        L3_zSYR2K_A_kn = loadDoubleArray();
+        L3_zSYR2K_B_kn = loadDoubleArray();
+        L3_zSYR2K_o_T = loadDoubleArray();
+    }
+
+    private void loadHER2KData() throws Exception {
+        L3_cHER2K_A_nk = loadFloatArray();
+        L3_cHER2K_B_nk = loadFloatArray();
+        L3_cHER2K_C_nn = loadFloatArray();
+        L3_cHER2K_o_N = loadFloatArray();
+        L3_cHER2K_A_kn = loadFloatArray();
+        L3_cHER2K_B_kn = loadFloatArray();
+        L3_cHER2K_o_H = loadFloatArray();
+
+        L3_zHER2K_A_nk = loadDoubleArray();
+        L3_zHER2K_B_nk = loadDoubleArray();
+        L3_zHER2K_C_nn = loadDoubleArray();
+        L3_zHER2K_o_N = loadDoubleArray();
+        L3_zHER2K_A_kn = loadDoubleArray();
+        L3_zHER2K_B_kn = loadDoubleArray();
+        L3_zHER2K_o_H = loadDoubleArray();
+    }
+
+    private void loadTRMMData() throws Exception {
+        L3_sTRMM_A_mm = loadFloatArray();
+        L3_sTRMM_B_mn = loadFloatArray();
+        L3_sTRMM_o_LUN = loadFloatArray();
+        L3_sTRMM_A_nn = loadFloatArray();
+        L3_sTRMM_o_RLT = loadFloatArray();
+
+        L3_dTRMM_A_mm = loadDoubleArray();
+        L3_dTRMM_B_mn = loadDoubleArray();
+        L3_dTRMM_o_LUN = loadDoubleArray();
+        L3_dTRMM_A_nn = loadDoubleArray();
+        L3_dTRMM_o_RLT = loadDoubleArray();
+
+        L3_cTRMM_A_mm = loadFloatArray();
+        L3_cTRMM_B_mn = loadFloatArray();
+        L3_cTRMM_o_LUN = loadFloatArray();
+        L3_cTRMM_A_nn = loadFloatArray();
+        L3_cTRMM_o_RLT = loadFloatArray();
+
+        L3_zTRMM_A_mm = loadDoubleArray();
+        L3_zTRMM_B_mn = loadDoubleArray();
+        L3_zTRMM_o_LUN = loadDoubleArray();
+        L3_zTRMM_A_nn = loadDoubleArray();
+        L3_zTRMM_o_RLT = loadDoubleArray();
+    }
+
+    private void loadTRSMData() throws Exception {
+        L3_sTRSM_A_mm = loadFloatArray();
+        L3_sTRSM_B_mn = loadFloatArray();
+        L3_sTRSM_o_LUN = loadFloatArray();
+        L3_sTRSM_A_nn = loadFloatArray();
+        L3_sTRSM_o_RLT = loadFloatArray();
+
+        L3_dTRSM_A_mm = loadDoubleArray();
+        L3_dTRSM_B_mn = loadDoubleArray();
+        L3_dTRSM_o_LUN = loadDoubleArray();
+        L3_dTRSM_A_nn = loadDoubleArray();
+        L3_dTRSM_o_RLT = loadDoubleArray();
+
+        L3_cTRSM_A_mm = loadFloatArray();
+        L3_cTRSM_B_mn = loadFloatArray();
+        L3_cTRSM_o_LUN = loadFloatArray();
+        L3_cTRSM_A_nn = loadFloatArray();
+        L3_cTRSM_o_RLT = loadFloatArray();
+
+        L3_zTRSM_A_mm = loadDoubleArray();
+        L3_zTRSM_B_mn = loadDoubleArray();
+        L3_zTRSM_o_LUN = loadDoubleArray();
+        L3_zTRSM_A_nn = loadDoubleArray();
+        L3_zTRSM_o_RLT = loadDoubleArray();
+    }
+
+    void loadData(Context ctx) throws Exception {
+        InputStream is = ctx.getAssets().open("BLASData.txt");
+        mBufReader = new BufferedReader(new InputStreamReader(is));
+
+        //Load data sequentially
+        loadMNK();
+        loadGEMVData();
+        loadGBMVData();
+        loadHEMVData();
+        loadHBMVData();
+        loadSYMVData();
+        loadSBMVData();
+        loadTRMVData();
+        loadTBMVData();
+        loadTRSVData();
+        loadTBSVData();
+        loadGERData();
+        loadGERUData();
+        loadGERCData();
+        loadHERData();
+        loadHER2Data();
+        loadSYRData();
+        loadSYR2Data();
+        loadGEMMData();
+        loadSYMMData();
+        loadHEMMData();
+        loadSYRKData();
+        loadHERKData();
+        loadSYR2KData();
+        loadHER2KData();
+        loadTRMMData();
+        loadTRSMData();
+    }
+
+}
diff --git a/tests/tests/rsblas/src/android/renderscript/cts/BNNMTest.java b/tests/tests/rsblas/src/android/renderscript/cts/BNNMTest.java
new file mode 100644
index 0000000..f95ad3c
--- /dev/null
+++ b/tests/tests/rsblas/src/android/renderscript/cts/BNNMTest.java
@@ -0,0 +1,500 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.cts.rsblas;
+
+import android.renderscript.*;
+import android.util.Log;
+import java.util.Random;
+import java.lang.Math;
+
+public class BNNMTest extends RSBaseCompute {
+
+    static {
+        System.loadLibrary("bnnmdata_jni");
+    }
+
+    native void getData(byte[] a, byte[] b, byte[] c);
+
+    // In Java, the eight-bit 'byte' type is signed, but the API for the 8-bit
+    // matrix multiplication deals with unsigned bytes. This is a convenience
+    // function that converts arrays of unsigned ints to their equivalent
+    // representations as signed bytes. For example, the bit pattern 0xff is 255
+    // as an unsigned value, but -127 as a Java signed byte. So if you pass in an
+    // array of int[] {255} into this function, you'll get back byte[] {-127}.
+    private byte[] unsignedToSignedByte(int[] input) {
+        byte[] output = new byte[input.length];
+        for (int i = 0; i < input.length; ++i) {
+            output[i] = (byte)(input[i]);
+        }
+        return output;
+    }
+
+    private void addByteNoise(byte[] data, int count, float frequency, int maxDelta) {
+        Random rand = new Random();
+        for (int n = 0; n < count; ++n) {
+            if (rand.nextFloat() < frequency) {
+                final int originalValue = data[n];
+                final float direction = rand.nextFloat();
+                int delta = (int)(Math.ceil(rand.nextFloat() * maxDelta));
+                if (direction < 0.5f) {
+                    delta = -delta;
+                }
+                int newValue = (originalValue + delta);
+                if (newValue < -127) {
+                    newValue = -127;
+                }
+                if (newValue > 127) {
+                    newValue = 127;
+                }
+                data[n] = (byte)(newValue);
+            }
+        }
+    }
+
+    private boolean testWithTolerance(byte[] c_byte, byte[] c_byte_output) {
+
+        // The testing procedure here is a bit complex, but the aim is to mimic the
+        // requirements we've empirically found running deep neural networks in real
+        // applications. We want to open the door to vendors using approximations that
+        // produce slightly different results for optimization's sake, but keep the
+        // precision loss within small enough bounds that we don't lose accuracy in
+        // the final result.
+        // After experimentation, we've found that we can tolerate around 5% of the
+        // output bytes being different by 1. Any larger differences are not tolerable
+        // and we can't get good results if the frequency of small differences is
+        // higher than 5%. This test tries to measure those properties on an example
+        // set of parameters that were captured from a real application.
+        // For example, if you uncommented this function that adds random noise to the
+        // results at a 3% specified frequency, the test should fail:
+        // AddByteNoise(c_byte_output, c_count, 0.03f, 1);
+
+        final boolean areSizesDifferent = (c_byte.length != c_byte_output.length);
+        final int c_count = Math.min(c_byte.length, c_byte_output.length);
+
+        int howManyDifferent = 0;
+        boolean areAnyTooDifferent = false;
+        for (int i = 0; i < c_count; i++) {
+            byte expectedValue = c_byte[i];
+            byte actualValue = c_byte_output[i];
+            int delta = (expectedValue - actualValue);
+            // First make sure that the difference is no more than one.
+            if ((delta < -1) || (delta > 1)) {
+                areAnyTooDifferent = true;
+            }
+            // If there is a difference, increment the counter to track it.
+            if (delta != 0) {
+                // Don't spam the logs if too many are different.
+                if (howManyDifferent < 50) {
+                    android.util.Log.e("BNNM", "Mismatch at " + i +
+                                       ": expected " + (expectedValue & 0xff) +
+                                       ", got " + (actualValue & 0xff));
+                }
+                ++howManyDifferent;
+            }
+        }
+        // We want no more than 2% of the values to show any differences, so work out
+        // what that means in absolute numbers.
+        final int percentThreshold = 2;
+        final int differenceThreshold = Math.max((percentThreshold * c_count) / 100, 1);
+        final boolean areTooManyDifferent = (howManyDifferent >= differenceThreshold);
+
+        if (areAnyTooDifferent) {
+            android.util.Log.e("BNNM", "Some outputs were too different.");
+        }
+
+        if (areTooManyDifferent) {
+            android.util.Log.e("BNNM", "There were too many small differences." +
+                               " We can tolerate " + percentThreshold + "% (" +
+                               differenceThreshold + "), but there were " + howManyDifferent);
+        }
+
+        return !(areAnyTooDifferent || areTooManyDifferent);
+    }
+
+
+    private byte[] runBNNM(int m, int n, int k, byte[] a_byte, int a_offset, byte[] b_byte,
+                           int b_offset, int c_offset, int c_mult_int) {
+        Allocation A, B, C;
+        Type.Builder builder = new Type.Builder(mRS, Element.U8(mRS));
+        Type a_type = builder.setX(k).setY(m).create();
+        Type b_type = builder.setX(k).setY(n).create();
+        Type c_type = builder.setX(n).setY(m).create();
+
+        A = Allocation.createTyped(mRS, a_type);
+        B = Allocation.createTyped(mRS, b_type);
+        C = Allocation.createTyped(mRS, c_type);
+
+        A.copyFrom(a_byte);
+        B.copyFrom(b_byte);
+        // C doesn't matter, is output only
+
+        ScriptIntrinsicBLAS blas = ScriptIntrinsicBLAS.create(mRS);
+        blas.BNNM(A, a_offset, B, b_offset, C, c_offset, c_mult_int);
+
+        int c_count = (m * n);
+        byte[] c_byte_output = new byte[c_count];
+        C.copyTo(c_byte_output);
+        return c_byte_output;
+    }
+
+
+
+    // This test multiplies a couple of small 8-bit matrices, and compares the
+    // results with hand-calculated expectations.
+    public void testSmallMatrices() {
+        // The A matrix is:
+        // |   1 |   4 |
+        // |   2 |   5 |
+        // |   3 |   6 |
+        byte[] a_data = unsignedToSignedByte(new int[] {
+                1, 2, 3,
+                4, 5, 6,
+            });
+        final int a_rows = 3;
+        final int a_cols = 2;
+        final int a_offset = 0;
+        // The B matrix is:
+        // |  -1 |  -2 |  -3 |  -4 |
+        // |  -5 |  -6 |  -7 |  -8 |
+        // |  -9 | -10 | -11 | -12 |
+        byte[] b_data = unsignedToSignedByte(new int[] {
+                11, 7, 3,
+                10, 6, 2,
+                9, 5, 1,
+                8, 4, 0,
+            });
+        final int b_cols = 4;
+        final int b_offset = 12;
+        // EightBitGemm implements C = B.transposed() * A,
+        // so we expect to get these results:
+        // 1*-1 + 2*-5 + 3*-9 + 128 = 90
+        // 1*-2 + 2*-6 + 3*-10 + 128 = 84
+        // 1*-3 + 2*-7 + 3*-11 + 128 = 78
+        // 1*-4 + 2*-8 + 3*-12 + 128 = 72
+        // 4*-1 + 5*-5 + 6*-9 + 128 = 45
+        // 4*-2 + 5*-6 + 6*-10 + 128 = 30
+        // 4*-3 + 5*-7 + 6*-11 + 128 = 15
+        // 4*-4 + 5*-8 + 6*-12 + 128 = 0
+        // | 90 |  45 |
+        // | 84 |  30 |
+        // | 78 | 15 |
+        // | 72 | 0 |
+        final int c_offset = 128;
+        final int c_shift = 21;
+        final int c_mult_int = (1 << c_shift);
+        byte[] expected_data = unsignedToSignedByte(new int[] {
+                90, 84, 78, 72,
+                45, 30, 15, 0,
+            });
+
+        final int m = a_cols;
+        final int n = b_cols;
+        final int k = a_rows;
+
+        byte[] c_byte_output = runBNNM(m, n, k, a_data, a_offset, b_data, b_offset,
+                                       c_offset, c_mult_int);
+        assertTrue(testWithTolerance(expected_data, c_byte_output));
+    }
+
+
+    // This test multiplies two medium-sized 8-bit matrices, and compares the
+    // results with the expected values. The data itself is fairly arbitrary.
+    public void testMediumMatrices1() {
+        byte[] a_data = unsignedToSignedByte(new int[] {
+                1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
+                12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
+                23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
+                0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
+                23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+            });
+        final int a_rows = 11;
+        final int a_cols = 5;
+        final int a_offset = 0;
+        byte[] b_data = unsignedToSignedByte(new int[] {
+                0, 2, 4, 6, 8, 10, 1, 3, 5, 7, 9, 11,
+                10, 12, 14, 16, 18, 20, 11, 13, 15, 17, 19, 21,
+                20, 22, 24, 26, 28, 30, 21, 23, 25, 27, 29, 31,
+                30, 32, 34, 36, 38, 40, 31, 33, 35, 37, 39, 41,
+                40, 42, 44, 46, 48, 50, 41, 43, 45, 47, 49, 51,
+                50, 52, 54, 56, 58, 60, 51, 53, 55, 57, 59, 61,
+                60, 62, 64, 66, 68, 70, 61, 63, 65, 67, 69, 71,
+            });
+        final int b_cols = 7;
+        final int b_offset = 10;
+        final int c_offset = 16384;
+        final int c_shift = 21;
+        final int c_mult_int = (1 << (c_shift - 7));
+        byte[] expected_data = unsignedToSignedByte(new int[] {
+                126, 131, 135, 140, 146, 151, 155,
+                121, 135, 148, 162, 176, 190, 202,
+                116, 139, 161, 184, 206, 229, 249,
+                128, 128, 129, 129, 129, 130, 130,
+                118, 136, 155, 173, 191, 210, 226,
+            });
+
+        final int m = a_cols;
+        final int n = b_cols;
+        final int k = a_rows;
+
+        byte[] c_byte_output = runBNNM(m, n, k, a_data, a_offset, b_data, b_offset,
+                                       c_offset, c_mult_int);
+        assertTrue(testWithTolerance(expected_data, c_byte_output));
+    }
+
+    // This test multiplies another two medium 8-bit matrices, and compares the
+    // results with the expected values. The data here is arbitrary.
+    public void testMediumMatrices2() {
+        byte[] a_data = unsignedToSignedByte(new int[] {
+                1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
+                23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1,
+                1, 23, 2, 22, 3, 21, 4, 20, 5, 19, 6, 18, 7, 17, 8, 16, 9, 15, 10, 14, 11, 13, 12,
+                23, 1, 22, 2, 21, 3, 20, 4, 19, 5, 18, 6, 17, 7, 16, 8, 15, 9, 14, 10, 13, 11, 12,
+                1, 1, 1, 1, 1, 1, 1, 1, 1, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+                3, 1, 4, 1, 5, 8, 2, 3, 1, 14, 11, 15, 18, 12, 13, 11, 14, 11, 15, 18, 12, 13, 11,
+                8, 0, 5, 8, 1, 3, 7, 5, 7, 13, 10, 23, 13, 11, 17, 23, 12, 19, 17, 13, 14, 10, 19,
+            });
+        final int a_rows = 23;
+        final int a_cols = 7;
+        final int a_offset = 13;
+        byte[] b_data = unsignedToSignedByte(new int[] {
+                0, 2, 4, 6, 8, 10, 1, 3, 5, 7, 9, 11, 0, 2, 4, 6, 8, 10, 1, 3, 5, 7, 9,
+                0, 20, 40, 60, 80, 10, 11, 13, 15, 17, 19, 21, 10, 12, 14, 6, 8, 10, 1, 3, 5, 7, 9,
+                1, 21, 41, 61, 81, 11, 12, 14, 16, 18, 20, 22, 11, 13, 15, 7, 9, 11, 2, 4, 6, 8, 9,
+                0, 19, 39, 59, 79, 9, 10, 12, 14, 16, 18, 20, 9, 11, 13, 5, 7, 9, 0, 2, 4, 6, 8,
+                2, 22, 42, 62, 82, 12, 13, 15, 17, 19, 21, 23, 12, 14, 16, 8, 9, 12, 3, 5, 7, 9, 9,
+                0, 18, 38, 58, 78, 8, 9, 11, 13, 15, 17, 19, 8, 10, 12, 4, 6, 8, 0, 1, 3, 5, 7,
+                3, 23, 43, 63, 83, 13, 14, 16, 18, 20, 22, 24, 13, 15, 17, 9, 9, 13, 4, 6, 8, 9, 9,
+                0, 17, 37, 57, 77, 7, 8, 10, 12, 14, 16, 18, 7, 9, 11, 3, 5, 7, 0, 0, 2, 4, 6,
+                10, 20, 30, 40, 50, 1, 2, 3, 4, 5, 11, 12, 13, 14, 15, 21, 22, 23, 24, 25, 1, 2, 3,
+            });
+        final int b_cols = 9;
+        final int b_offset = 23;
+        final int c_offset = 2121;
+        final int c_shift = 21;
+        final int c_mult_int = 132359;
+        byte[] expected_data = unsignedToSignedByte(new int[] {
+                167, 53, 51, 54, 49, 55, 46,
+                56, 116, 153, 232, 232, 234, 231,
+                236, 232, 237, 174, 168, 131, 130,
+                132, 129, 133, 128, 133, 134, 151,
+                154, 152, 156, 151, 158, 150, 160,
+                156, 255, 113, 106, 120, 98, 127,
+                91, 134, 178, 231, 102, 97, 107,
+                92, 111, 87, 116, 164, 187, 76,
+                73, 78, 70, 81, 67, 83, 139,
+            });
+
+        final int m = a_cols;
+        final int n = b_cols;
+        final int k = a_rows;
+
+        byte[] c_byte_output = runBNNM(m, n, k, a_data, a_offset, b_data, b_offset,
+                                       c_offset, c_mult_int);
+        assertTrue(testWithTolerance(expected_data, c_byte_output));
+    }
+
+
+    // This test takes a large set of real data captured from a convolutional
+    // neural network solving a computer vision problem, and runs it through the
+    // eight-bit matrix multiply. We test the results to make sure they're close
+    // enough to be usable.
+    public void testRealData() {
+
+        int m = 256;
+        int n = 192;
+        int k = 1152;
+        int a_offset = 0;
+        int b_offset = 84;
+        int c_mult_int = 3401;
+        int c_offset = 74980;
+
+        int a_count = (m * k);
+        int b_count = (n * k);
+        int c_count = (m * n);
+
+        byte[] a_byte = new byte[a_count];
+        byte[] b_byte = new byte[b_count];
+        byte[] c_byte = new byte[c_count];
+
+        getData(a_byte, b_byte, c_byte);
+
+        byte[] c_byte_output = runBNNM(m, n, k, a_byte, a_offset, b_byte, b_offset,
+                                       c_offset, c_mult_int);
+
+        assertTrue(testWithTolerance(c_byte, c_byte_output));
+
+    }
+
+    // This test multiplies matrices where the results are expected to fall
+    // slightly outside the 0 to 255 valid output range. This test ensures the
+    // values get clamped to that range, rather than wrapping around.
+    public void testClamping() {
+        // The A matrix is:
+        // |   1 |   4 |
+        // |   2 |   5 |
+        // |   3 |   6 |
+        byte[] a_data = unsignedToSignedByte(new int[] {
+                1, 2, 3,
+                4, 5, 6,
+            });
+        final int a_rows = 3;
+        final int a_cols = 2;
+        final int a_offset = 0;
+        // The B matrix is:
+        // |  -1 |  -2 |  -3 |  -4 |
+        // |  -5 |  -6 |  -7 |  -8 |
+        // |  99 | -40 | -11 | -15 |
+        byte[] b_data = unsignedToSignedByte(new int[] {
+                126, 122, 226,
+                125, 121, 87,
+                124, 120, 116,
+                123, 119, 112,
+            });
+        final int b_cols = 4;
+        final int b_offset = 127;
+        // EightBitGemm implements C = B.transposed() * A,
+        // so we expect to get these results:
+        // 1*-1 + 2*-5 + 3* 99 + 128 = 414 (clamped to 255)
+        // 1*-2 + 2*-6 + 3*-40 + 128 = -6 (clamped to 0)
+        // 1*-3 + 2*-7 + 3*-11 + 128 = 78
+        // 1*-4 + 2*-8 + 3*-15 + 128 = 63
+        // 4*-1 + 5*-5 + 6* 99 + 128 = 693 (clamped to 255)
+        // 4*-2 + 5*-6 + 6*-40 + 128 = -150 (clamped to 0)
+        // 4*-3 + 5*-7 + 6*-11 + 128 = 15
+        // 4*-4 + 5*-8 + 6*-15 + 128 = -18 (clamped to 0)
+        // | 255 | 255 |
+        // |   0 |   0 |
+        // |  78 |  15 |
+        // |  63 |   0 |
+        final int c_offset = 128;
+        final int c_shift = 21;
+        final int c_mult_int = (1 << c_shift);
+        byte[] expected_data = unsignedToSignedByte(new int[] {
+              255, 0, 78, 63,
+              255, 0, 15, 0,
+            });
+
+        final int m = a_cols;
+        final int n = b_cols;
+        final int k = a_rows;
+
+        byte[] c_byte_output = runBNNM(m, n, k, a_data, a_offset, b_data, b_offset,
+                                       c_offset, c_mult_int);
+        assertTrue(testWithTolerance(expected_data, c_byte_output));
+    }
+
+    // This tests the exception handling for a_offset and b_offset.
+    public void testExceptionHandling() {
+        // The A matrix is:
+        // |   1 |   4 |
+        // |   2 |   5 |
+        // |   3 |   6 |
+        byte[] a_data = unsignedToSignedByte(new int[] {
+                1, 2, 3,
+                4, 5, 6,
+            });
+        final int a_rows = 3;
+        final int a_cols = 2;
+        // The B matrix is:
+        // |  -1 |  -2 |  -3 |  -4 |
+        // |  -5 |  -6 |  -7 |  -8 |
+        // |  -9 | -10 | -11 | -12 |
+        byte[] b_data = unsignedToSignedByte(new int[] {
+                11, 7, 3,
+                10, 6, 2,
+                9, 5, 1,
+                8, 4, 0,
+            });
+        final int b_cols = 4;
+        // EightBitGemm implements C = B.transposed() * A,
+        // so we expect to get these results:
+        // 1*-1 + 2*-5 + 3*-9 + 128 = 90
+        // 1*-2 + 2*-6 + 3*-10 + 128 = 84
+        // 1*-3 + 2*-7 + 3*-11 + 128 = 78
+        // 1*-4 + 2*-8 + 3*-12 + 128 = 72
+        // 4*-1 + 5*-5 + 6*-9 + 128 = 45
+        // 4*-2 + 5*-6 + 6*-10 + 128 = 30
+        // 4*-3 + 5*-7 + 6*-11 + 128 = 15
+        // 4*-4 + 5*-8 + 6*-12 + 128 = 0
+        // | 90 |  45 |
+        // | 84 |  30 |
+        // | 78 | 15 |
+        // | 72 | 0 |
+        final int c_offset = 128;
+        final int c_shift = 21;
+        final int c_mult_int = (1 << c_shift);
+        byte[] expected_data = unsignedToSignedByte(new int[] {
+                90, 84, 78, 72,
+                45, 30, 15, 0,
+            });
+
+        final int m = a_cols;
+        final int n = b_cols;
+        final int k = a_rows;
+
+        Allocation A, B, C;
+        Type.Builder builder = new Type.Builder(mRS, Element.U8(mRS));
+        Type a_type = builder.setX(k).setY(m).create();
+        Type b_type = builder.setX(k).setY(n).create();
+        Type c_type = builder.setX(n).setY(m).create();
+
+        A = Allocation.createTyped(mRS, a_type);
+        B = Allocation.createTyped(mRS, b_type);
+        C = Allocation.createTyped(mRS, c_type);
+
+        A.copyFrom(a_data);
+        B.copyFrom(b_data);
+        // C doesn't matter, is output only
+
+        ScriptIntrinsicBLAS blas = ScriptIntrinsicBLAS.create(mRS);
+        try {
+            int a_offset = 0;
+            int b_offset = 12;
+            blas.BNNM(A, a_offset, B, b_offset, C, c_offset, c_mult_int);
+        } catch (RSRuntimeException e) {
+            fail("should NOT throw RSRuntimeException for valid offsets");
+        }
+        try {
+            int a_offset = -23;
+            int b_offset = 12;
+            blas.BNNM(A, a_offset, B, b_offset, C, c_offset, c_mult_int);
+            fail("should throw RSRuntimeException for invalid offsets: a_offset < 0");
+        } catch (RSRuntimeException e) {
+        }
+        try {
+            int a_offset = 888;
+            int b_offset = 12;
+            blas.BNNM(A, a_offset, B, b_offset, C, c_offset, c_mult_int);
+            fail("should throw RSRuntimeException for invalid offsets: a_offset > 255");
+        } catch (RSRuntimeException e) {
+        }
+        try {
+            int a_offset = 0;
+            int b_offset = -1;
+            blas.BNNM(A, a_offset, B, b_offset, C, c_offset, c_mult_int);
+            fail("should throw RSRuntimeException for invalid offsets: b_offset < 0");
+        } catch (RSRuntimeException e) {
+        }
+        try {
+            int a_offset = 0;
+            int b_offset = 256;
+            blas.BNNM(A, a_offset, B, b_offset, C, c_offset, c_mult_int);
+            fail("should throw RSRuntimeException for invalid offsets: b_offset > 255");
+        } catch (RSRuntimeException e) {
+        }
+    }
+}
diff --git a/tests/tests/rsblas/src/android/renderscript/cts/IntrinsicBLAS.java b/tests/tests/rsblas/src/android/renderscript/cts/IntrinsicBLAS.java
new file mode 100644
index 0000000..a5fc80d
--- /dev/null
+++ b/tests/tests/rsblas/src/android/renderscript/cts/IntrinsicBLAS.java
@@ -0,0 +1,6831 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.cts.rsblas;
+
+import android.renderscript.*;
+import android.util.Log;
+import java.util.ArrayList;
+
+public class IntrinsicBLAS extends IntrinsicBase {
+    private ScriptIntrinsicBLAS mBLAS;
+    private BLASData mBLASData;
+    private boolean mInitialized = false;
+
+    private ArrayList<Allocation> mMatrixS;
+    private final float alphaS = 1.0f;
+    private final float betaS = 1.0f;
+
+    private ArrayList<Allocation> mMatrixD;
+    private final double alphaD = 1.0;
+    private final double betaD = 1.0;
+
+    private ArrayList<Allocation> mMatrixC;
+    private final Float2 alphaC = new Float2(1.0f, 0.0f);
+    private final Float2 betaC = new Float2(1.0f, 0.0f);
+
+    private ArrayList<Allocation> mMatrixZ;
+    private final Double2 alphaZ = new Double2(1.0, 0.0);
+    private final Double2 betaZ = new Double2(1.0, 0.0);
+
+    private int[] mTranspose = {ScriptIntrinsicBLAS.NO_TRANSPOSE,
+                                ScriptIntrinsicBLAS.TRANSPOSE,
+                                ScriptIntrinsicBLAS.CONJ_TRANSPOSE,
+                                0};
+
+    private int[] mUplo = {ScriptIntrinsicBLAS.UPPER,
+                           ScriptIntrinsicBLAS.LOWER,
+                           0};
+
+    private int[] mDiag = {ScriptIntrinsicBLAS.NON_UNIT,
+                           ScriptIntrinsicBLAS.UNIT,
+                           0};
+
+    private int[] mSide = {ScriptIntrinsicBLAS.LEFT,
+                           ScriptIntrinsicBLAS.RIGHT,
+                           0};
+
+    private int[] mInc = {0, 1, 2};
+    private int[] mK = {-1, 0, 1};
+    private int[] mDim = {1, 2, 3, 256};
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        // Now populate the test Matrixes and Vectors.
+        if (!mInitialized) {
+            mBLASData = new BLASData();
+            mBLASData.loadData(mCtx);
+            mBLAS = ScriptIntrinsicBLAS.create(mRS);
+            mMatrixS = new ArrayList<Allocation>();
+            mMatrixD = new ArrayList<Allocation>();
+            mMatrixC = new ArrayList<Allocation>();
+            mMatrixZ = new ArrayList<Allocation>();
+            for (int x : mDim) {
+                for (int y : mDim) {
+                    mMatrixS.add(Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), x, y)));
+                    mMatrixD.add(Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), x, y)));
+                    mMatrixC.add(Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), x, y)));
+                    mMatrixZ.add(Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), x, y)));
+                }
+            }
+            // Also need Allocation with mismatch Element.
+            Allocation misAlloc = Allocation.createTyped(mRS, Type.createXY(mRS, Element.U8(mRS), 1, 1));
+            mMatrixS.add(misAlloc);
+            mMatrixD.add(misAlloc);
+            mMatrixC.add(misAlloc);
+            mMatrixZ.add(misAlloc);
+            mInitialized = true;
+        }
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    // Calculate the square of the L2 norm of a matrix.
+    private double calcL2Norm(float[] input) {
+        double l2Norm = 0;
+        for (int i = 0; i < input.length; ++i) {
+            l2Norm += input[i] * input[i];
+        }
+        return l2Norm;
+    }
+
+    private double calcL2Norm(double[] input) {
+        double l2Norm = 0;
+        for (int i = 0; i < input.length; ++i) {
+            l2Norm += input[i] * input[i];
+        }
+        return l2Norm;
+    }
+
+    // Routine to verify if matrix are equivalent.
+    private void verifyMatrix(Allocation ref, Allocation out) {
+        verifyMatrix(ref, out, false);
+    }
+
+    // Use L2 norm of a matrix as the scale to determine whether two matrices are equivalent:
+    // if the absolute square error of any elements is smaller than the average L2 Norm
+    // per element times an allowed error range (1e-6), then the two matrices are considered equivalent.
+    // Criterion: (a[i,j] - a'[i,j])^2 < epsilon * ||A||/(M*N)
+    // M, N: the dimensions of the matrix; epsilon: allowed relative error.
+    private void verifyMatrix(Allocation ref, Allocation out, boolean isUpperMatrix) {
+        double l2Norm;
+        int size;
+        Element e = ref.getType().getElement();
+        if (e.isCompatible(Element.F32(mRS)) || e.isCompatible(Element.F32_2(mRS))) {
+            size = out.getBytesSize() / 4;
+            float[] outArr = new float[size];
+            float[] refArr = new float[size];
+            out.copyTo(outArr);
+            ref.copyTo(refArr);
+
+            double l2NormOut = calcL2Norm(outArr);
+            double l2NormRef = calcL2Norm(refArr);
+            l2Norm = (l2NormOut < l2NormRef ? l2NormOut : l2NormRef) / size;
+        } else {
+            size = out.getBytesSize() / 8;
+            double[] outArr = new double[size];
+            double[] refArr = new double[size];
+            out.copyTo(outArr);
+            ref.copyTo(refArr);
+
+            double l2NormOut = calcL2Norm(outArr);
+            double l2NormRef = calcL2Norm(refArr);
+            l2Norm = (l2NormOut < l2NormRef ? l2NormOut : l2NormRef) / size;
+        }
+        mVerify.invoke_verifyMatrix(ref, out, l2Norm, isUpperMatrix);
+    }
+
+
+    private boolean validateSide(int Side) {
+        if (Side != ScriptIntrinsicBLAS.LEFT && Side != ScriptIntrinsicBLAS.RIGHT) {
+            return false;
+        }
+        return true;
+    }
+
+    private boolean validateTranspose(int Trans) {
+        if (Trans != ScriptIntrinsicBLAS.NO_TRANSPOSE &&
+            Trans != ScriptIntrinsicBLAS.TRANSPOSE &&
+            Trans != ScriptIntrinsicBLAS.CONJ_TRANSPOSE) {
+            return false;
+        }
+        return true;
+    }
+
+    private boolean validateConjTranspose(int Trans) {
+        if (Trans != ScriptIntrinsicBLAS.NO_TRANSPOSE &&
+            Trans != ScriptIntrinsicBLAS.CONJ_TRANSPOSE) {
+            return false;
+        }
+        return true;
+    }
+
+    private boolean validateDiag(int Diag) {
+        if (Diag != ScriptIntrinsicBLAS.NON_UNIT &&
+            Diag != ScriptIntrinsicBLAS.UNIT) {
+            return false;
+        }
+        return true;
+    }
+
+    private boolean validateUplo(int Uplo) {
+        if (Uplo != ScriptIntrinsicBLAS.UPPER &&
+            Uplo != ScriptIntrinsicBLAS.LOWER) {
+            return false;
+        }
+        return true;
+    }
+
+    private boolean validateVecInput(Allocation X) {
+        if (X.getType().getY() > 2) {
+            // For testing vector, need a mismatch Y for complete test coverage.
+            return false;
+        }
+        return true;
+    }
+
+    private boolean validateGEMV(Element e, int TransA, Allocation A, Allocation X, int incX, Allocation Y, int incY) {
+        if (!validateTranspose(TransA)) {
+            return false;
+        }
+        int M = A.getType().getY();
+        int N = A.getType().getX();
+        if (!A.getType().getElement().isCompatible(e) ||
+            !X.getType().getElement().isCompatible(e) ||
+            !Y.getType().getElement().isCompatible(e)) {
+            return false;
+        }
+        if (X.getType().getY() > 1 || Y.getType().getY() > 1) {
+            return false;
+        }
+
+        if (incX <= 0 || incY <= 0) {
+            return false;
+        }
+        int expectedXDim = -1, expectedYDim = -1;
+        if (TransA == ScriptIntrinsicBLAS.NO_TRANSPOSE) {
+            expectedXDim = 1 + (N - 1) * incX;
+            expectedYDim = 1 + (M - 1) * incY;
+        } else {
+            expectedXDim = 1 + (M - 1) * incX;
+            expectedYDim = 1 + (N - 1) * incY;
+        }
+        if (X.getType().getX() != expectedXDim ||
+            Y.getType().getX() != expectedYDim) {
+            return false;
+        }
+        return true;
+    }
+
+    private void xGEMV_API_test(int trans, int incX, int incY, ArrayList<Allocation> mMatrix) {
+        for (Allocation matA : mMatrix) {
+            for (Allocation vecX : mMatrix) {
+                if (!validateVecInput(vecX)) {
+                    continue;
+                }
+                for (Allocation vecY : mMatrix) {
+                    if (!validateVecInput(vecY)) {
+                        continue;
+                    }
+                    Element elemA = matA.getType().getElement();
+                    if (validateGEMV(elemA, trans, matA, vecX, incX, vecY, incY)) {
+                        try {
+                            if (elemA.isCompatible(Element.F32(mRS))) {
+                                mBLAS.SGEMV(trans, alphaS, matA, vecX, incX, betaS, vecY, incY);
+                            } else if (elemA.isCompatible(Element.F64(mRS))) {
+                                mBLAS.DGEMV(trans, alphaD, matA, vecX, incX, betaD, vecY, incY);
+                            } else if (elemA.isCompatible(Element.F32_2(mRS))) {
+                                mBLAS.CGEMV(trans, alphaC, matA, vecX, incX, betaC, vecY, incY);
+                            } else if (elemA.isCompatible(Element.F64_2(mRS))) {
+                                mBLAS.ZGEMV(trans, alphaZ, matA, vecX, incX, betaZ, vecY, incY);
+                            }
+                        } catch (RSRuntimeException e) {
+                            fail("should NOT throw RSRuntimeException");
+                        }
+                    } else {
+                        try {
+                            mBLAS.SGEMV(trans, alphaS, matA, vecX, incX, betaS, vecY, incY);
+                            fail("should throw RSRuntimeException for SGEMV");
+                        } catch (RSRuntimeException e) {
+                        }
+                        try {
+                            mBLAS.DGEMV(trans, alphaD, matA, vecX, incX, betaD, vecY, incY);
+                            fail("should throw RSRuntimeException for DGEMV");
+                        } catch (RSRuntimeException e) {
+                        }
+                        try {
+                            mBLAS.CGEMV(trans, alphaC, matA, vecX, incX, betaC, vecY, incY);
+                            fail("should throw RSRuntimeException for CGEMV");
+                        } catch (RSRuntimeException e) {
+                        }
+                        try {
+                            mBLAS.ZGEMV(trans, alphaZ, matA, vecX, incX, betaZ, vecY, incY);
+                            fail("should throw RSRuntimeException for ZGEMV");
+                        } catch (RSRuntimeException e) {
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    public void L2_xGEMV_API(ArrayList<Allocation> mMatrix) {
+        for (int trans : mTranspose) {
+            for (int incX : mInc) {
+                xGEMV_API_test(trans, incX, incX, mMatrix);
+            }
+        }
+    }
+
+    public void test_L2_SGEMV_API() {
+        L2_xGEMV_API(mMatrixS);
+    }
+
+    public void test_L2_DGEMV_API() {
+        L2_xGEMV_API(mMatrixD);
+    }
+
+    public void test_L2_CGEMV_API() {
+        L2_xGEMV_API(mMatrixC);
+    }
+
+    public void test_L2_ZGEMV_API() {
+        L2_xGEMV_API(mMatrixZ);
+    }
+
+    public void test_L2_SGEMV_Correctness() {
+        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        int incX = 1;
+        int incY = 1;
+
+        // Populate input allocations
+        Allocation matrixAS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dM));
+        Allocation vectorXS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, 1));
+        Allocation vectorYS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dM, 1));
+        matrixAS.copyFrom(mBLASData.L2_sGEMV_A_mn);
+        vectorXS.copyFrom(mBLASData.L2_sGEMV_x_n1);
+        vectorYS.copyFrom(mBLASData.L2_sGEMV_y_m1);
+
+        // Test for the default case: NO_TRANS
+        mBLAS.SGEMV(trans, alphaS, matrixAS, vectorXS, incX, betaS, vectorYS, incY);
+        Allocation vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dM, 1));
+        vectorYRef.copyFrom(mBLASData.L2_sGEMV_o_N);
+        verifyMatrix(vectorYRef, vectorYS);
+
+        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
+        trans = ScriptIntrinsicBLAS.TRANSPOSE;
+        // Reload vector Y, since it was overwritten by BLAS.
+        vectorYS.copyFrom(mBLASData.L2_sGEMV_y_m1);
+        // After Transpose matrixA, vectorX and vectorY are exchanged to match the dim of A.T
+        mBLAS.SGEMV(trans, alphaS, matrixAS, vectorYS, incY, betaS, vectorXS, incX);
+        vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, 1));
+        vectorYRef.copyFrom(mBLASData.L2_sGEMV_o_T);
+        verifyMatrix(vectorYRef, vectorXS);
+
+        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
+        vectorXS.copyFrom(mBLASData.L2_sGEMV_x_n1);
+        mBLAS.SGEMV(trans, alphaS, matrixAS, vectorYS, incY, betaS, vectorXS, incX);
+        vectorYRef.copyFrom(mBLASData.L2_sGEMV_o_H);
+        verifyMatrix(vectorYRef, vectorXS);
+
+        // Test for incX = 2 & incY = 3;
+        trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        incX = 2;
+        incY = 3;
+        int dimX = 1 + (mBLASData.dN - 1) * incX;
+        int dimY = 1 + (mBLASData.dM - 1) * incY;
+        vectorXS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimX, 1));
+        vectorYS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimY, 1));
+        vectorXS.copyFrom(mBLASData.L2_sGEMV_x_n2);
+        vectorYS.copyFrom(mBLASData.L2_sGEMV_y_m2);
+
+        mBLAS.SGEMV(trans, alphaS, matrixAS, vectorXS, incX, betaS, vectorYS, incY);
+        vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimY, 1));
+        vectorYRef.copyFrom(mBLASData.L2_sGEMV_o_N2);
+        verifyMatrix(vectorYRef, vectorYS);
+
+        mRS.finish();
+        checkError();
+    }
+
+    public void test_L2_DGEMV_Correctness() {
+        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        int incX = 1;
+        int incY = 1;
+
+        // Populate input allocations
+        Allocation matrixAD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dM));
+        Allocation vectorXD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, 1));
+        Allocation vectorYD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dM, 1));
+        matrixAD.copyFrom(mBLASData.L2_dGEMV_A_mn);
+        vectorXD.copyFrom(mBLASData.L2_dGEMV_x_n1);
+        vectorYD.copyFrom(mBLASData.L2_dGEMV_y_m1);
+
+        // Test for the default case: NO_TRANS
+        mBLAS.DGEMV(trans, alphaD, matrixAD, vectorXD, incX, betaD, vectorYD, incY);
+        Allocation vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dM, 1));
+        vectorYRef.copyFrom(mBLASData.L2_dGEMV_o_N);
+        verifyMatrix(vectorYRef, vectorYD);
+
+        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
+        trans = ScriptIntrinsicBLAS.TRANSPOSE;
+        // Reload vector Y, since it was overwritten by BLAS.
+        vectorYD.copyFrom(mBLASData.L2_dGEMV_y_m1);
+        // After Transpose matrixA, vectorX and vectorY are exchanged to match the dim of A.T
+        mBLAS.DGEMV(trans, alphaD, matrixAD, vectorYD, incY, betaD, vectorXD, incX);
+        vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, 1));
+        vectorYRef.copyFrom(mBLASData.L2_dGEMV_o_T);
+        verifyMatrix(vectorYRef, vectorXD);
+
+        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
+        vectorXD.copyFrom(mBLASData.L2_dGEMV_x_n1);
+        mBLAS.DGEMV(trans, alphaD, matrixAD, vectorYD, incY, betaD, vectorXD, incX);
+        vectorYRef.copyFrom(mBLASData.L2_dGEMV_o_H);
+        verifyMatrix(vectorYRef, vectorXD);
+
+        // Test for incX = 2 & incY = 3;
+        trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        incX = 2;
+        incY = 3;
+        int dimX = 1 + (mBLASData.dN - 1) * incX;
+        int dimY = 1 + (mBLASData.dM - 1) * incY;
+        vectorXD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimX, 1));
+        vectorYD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimY, 1));
+        vectorXD.copyFrom(mBLASData.L2_dGEMV_x_n2);
+        vectorYD.copyFrom(mBLASData.L2_dGEMV_y_m2);
+
+        mBLAS.DGEMV(trans, alphaD, matrixAD, vectorXD, incX, betaD, vectorYD, incY);
+        vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimY, 1));
+        vectorYRef.copyFrom(mBLASData.L2_dGEMV_o_N2);
+        verifyMatrix(vectorYRef, vectorYD);
+
+        mRS.finish();
+        checkError();
+    }
+
+    public void test_L2_CGEMV_Correctness() {
+        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        int incX = 1;
+        int incY = 1;
+
+        // Populate input allocations
+        Allocation matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dM));
+        Allocation vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, 1));
+        Allocation vectorYC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dM, 1));
+        matrixAC.copyFrom(mBLASData.L2_cGEMV_A_mn);
+        vectorXC.copyFrom(mBLASData.L2_cGEMV_x_n1);
+        vectorYC.copyFrom(mBLASData.L2_cGEMV_y_m1);
+
+        // Test for the default case: NO_TRANS
+        mBLAS.CGEMV(trans, alphaC, matrixAC, vectorXC, incX, betaC, vectorYC, incY);
+        Allocation vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dM, 1));
+        vectorYRef.copyFrom(mBLASData.L2_cGEMV_o_N);
+        verifyMatrix(vectorYRef, vectorYC);
+
+        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
+        trans = ScriptIntrinsicBLAS.TRANSPOSE;
+        // Reload vector Y, since it was overwritten by BLAS.
+        vectorYC.copyFrom(mBLASData.L2_cGEMV_y_m1);
+        // After Transpose matrixA, vectorX and vectorY are exchanged to match the dim of A.T
+        mBLAS.CGEMV(trans, alphaC, matrixAC, vectorYC, incY, betaC, vectorXC, incX);
+        vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, 1));
+        vectorYRef.copyFrom(mBLASData.L2_cGEMV_o_T);
+        verifyMatrix(vectorYRef, vectorXC);
+
+        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
+        vectorXC.copyFrom(mBLASData.L2_cGEMV_x_n1);
+        mBLAS.CGEMV(trans, alphaC, matrixAC, vectorYC, incY, betaC, vectorXC, incX);
+        vectorYRef.copyFrom(mBLASData.L2_cGEMV_o_H);
+        verifyMatrix(vectorYRef, vectorXC);
+
+        // Test for incX = 2 & incY = 3;
+        trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        incX = 2;
+        incY = 3;
+        int dimX = 1 + (mBLASData.dN - 1) * incX;
+        int dimY = 1 + (mBLASData.dM - 1) * incY;
+        vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimX, 1));
+        vectorYC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimY, 1));
+        vectorXC.copyFrom(mBLASData.L2_cGEMV_x_n2);
+        vectorYC.copyFrom(mBLASData.L2_cGEMV_y_m2);
+
+        mBLAS.CGEMV(trans, alphaC, matrixAC, vectorXC, incX, betaC, vectorYC, incY);
+        vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimY, 1));
+        vectorYRef.copyFrom(mBLASData.L2_cGEMV_o_N2);
+        verifyMatrix(vectorYRef, vectorYC);
+
+        mRS.finish();
+        checkError();
+    }
+
+    public void test_L2_ZGEMV_Correctness() {
+        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        int incX = 1;
+        int incY = 1;
+
+        // Populate input allocations
+        Allocation matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dM));
+        Allocation vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, 1));
+        Allocation vectorYZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dM, 1));
+        matrixAZ.copyFrom(mBLASData.L2_zGEMV_A_mn);
+        vectorXZ.copyFrom(mBLASData.L2_zGEMV_x_n1);
+        vectorYZ.copyFrom(mBLASData.L2_zGEMV_y_m1);
+
+        // Test for the default case: NO_TRANS
+        mBLAS.ZGEMV(trans, alphaZ, matrixAZ, vectorXZ, incX, betaZ, vectorYZ, incY);
+        Allocation vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dM, 1));
+        vectorYRef.copyFrom(mBLASData.L2_zGEMV_o_N);
+        verifyMatrix(vectorYRef, vectorYZ);
+
+        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
+        trans = ScriptIntrinsicBLAS.TRANSPOSE;
+        // Reload vector Y, since it was overwritten by BLAS.
+        vectorYZ.copyFrom(mBLASData.L2_zGEMV_y_m1);
+        // After Transpose matrixA, vectorX and vectorY are exchanged to match the dim of A.T
+        mBLAS.ZGEMV(trans, alphaZ, matrixAZ, vectorYZ, incY, betaZ, vectorXZ, incX);
+        vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, 1));
+        vectorYRef.copyFrom(mBLASData.L2_zGEMV_o_T);
+        verifyMatrix(vectorYRef, vectorXZ);
+
+        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
+        vectorXZ.copyFrom(mBLASData.L2_zGEMV_x_n1);
+        mBLAS.ZGEMV(trans, alphaZ, matrixAZ, vectorYZ, incY, betaZ, vectorXZ, incX);
+        vectorYRef.copyFrom(mBLASData.L2_zGEMV_o_H);
+        verifyMatrix(vectorYRef, vectorXZ);
+
+        // Test for incX = 2 & incY = 3;
+        trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        incX = 2;
+        incY = 3;
+        int dimX = 1 + (mBLASData.dN - 1) * incX;
+        int dimY = 1 + (mBLASData.dM - 1) * incY;
+        vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimX, 1));
+        vectorYZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimY, 1));
+        vectorXZ.copyFrom(mBLASData.L2_zGEMV_x_n2);
+        vectorYZ.copyFrom(mBLASData.L2_zGEMV_y_m2);
+
+        mBLAS.ZGEMV(trans, alphaZ, matrixAZ, vectorXZ, incX, betaZ, vectorYZ, incY);
+        vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimY, 1));
+        vectorYRef.copyFrom(mBLASData.L2_zGEMV_o_N2);
+        verifyMatrix(vectorYRef, vectorYZ);
+
+        mRS.finish();
+        checkError();
+    }
+
+
+
+    private void xGBMV_API_test(int trans, int KL, int KU, int incX, int incY, ArrayList<Allocation> mMatrix) {
+        for (Allocation matA : mMatrix) {
+            for (Allocation vecX : mMatrix) {
+                if (!validateVecInput(vecX)) {
+                    continue;
+                }
+                for (Allocation vecY : mMatrix) {
+                    if (!validateVecInput(vecY)) {
+                        continue;
+                    }
+                    Element elemA = matA.getType().getElement();
+                    if (validateGEMV(elemA, trans, matA, vecX, incX, vecY, incY) && KU >= 0 && KL >= 0) {
+                        try {
+                            if (elemA.isCompatible(Element.F32(mRS))) {
+                                mBLAS.SGBMV(trans, KL, KU, alphaS, matA, vecX, incX, betaS, vecY, incY);
+                            } else if (elemA.isCompatible(Element.F64(mRS))) {
+                                mBLAS.DGBMV(trans, KL, KU, alphaD, matA, vecX, incX, betaD, vecY, incY);
+                            } else if (elemA.isCompatible(Element.F32_2(mRS))) {
+                                mBLAS.CGBMV(trans, KL, KU, alphaC, matA, vecX, incX, betaC, vecY, incY);
+                            } else if (elemA.isCompatible(Element.F64_2(mRS))) {
+                                mBLAS.ZGBMV(trans, KL, KU, alphaZ, matA, vecX, incX, betaZ, vecY, incY);
+                            }
+                        } catch (RSRuntimeException e) {
+                            fail("should NOT throw RSRuntimeException");
+                        }
+                    } else {
+                        try {
+                            mBLAS.SGBMV(trans, KL, KU, alphaS, matA, vecX, incX, betaS, vecY, incY);
+                            fail("should throw RSRuntimeException for SGBMV");
+                        } catch (RSRuntimeException e) {
+                        }
+                        try {
+                            mBLAS.DGBMV(trans, KL, KU, alphaD, matA, vecX, incX, betaD, vecY, incY);
+                            fail("should throw RSRuntimeException for DGBMV");
+                        } catch (RSRuntimeException e) {
+                        }
+                        try {
+                            mBLAS.CGBMV(trans, KL, KU, alphaC, matA, vecX, incX, betaC, vecY, incY);
+                            fail("should throw RSRuntimeException for CGBMV");
+                        } catch (RSRuntimeException e) {
+                        }
+                        try {
+                            mBLAS.ZGBMV(trans, KL, KU, alphaZ, matA, vecX, incX, betaZ, vecY, incY);
+                            fail("should throw RSRuntimeException for ZGBMV");
+                        } catch (RSRuntimeException e) {
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    public void L2_xGBMV_API(ArrayList<Allocation> mMatrix) {
+        for (int trans : mTranspose) {
+            for (int incX : mInc) {
+                for (int K : mK) {
+                    xGBMV_API_test(trans, K, K, incX, incX, mMatrix);
+                }
+            }
+        }
+    }
+
+    public void test_L2_SGBMV_API() {
+        L2_xGBMV_API(mMatrixS);
+    }
+
+    public void test_L2_DGBMV_API() {
+        L2_xGBMV_API(mMatrixD);
+    }
+
+    public void test_L2_CGBMV_API() {
+        L2_xGBMV_API(mMatrixC);
+    }
+
+    public void test_L2_ZGBMV_API() {
+        L2_xGBMV_API(mMatrixZ);
+    }
+
+    public void test_L2_SGBMV_Correctness() {
+        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        int incX = 1;
+        int incY = 1;
+
+        // Populate input allocations
+        Allocation matrixAS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dM));
+        Allocation vectorXS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, 1));
+        Allocation vectorYS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dM, 1));
+        matrixAS.copy2DRangeFrom(0, 0, mBLASData.KL + mBLASData.KU + 1, mBLASData.dM, mBLASData.L2_sGBMV_A_mn);
+        vectorXS.copyFrom(mBLASData.L2_sGBMV_x_n1);
+        vectorYS.copyFrom(mBLASData.L2_sGBMV_y_m1);
+
+        // Test for the default case: NO_TRANS
+        mBLAS.SGBMV(trans, mBLASData.KL, mBLASData.KU, alphaS, matrixAS, vectorXS, incX, betaS, vectorYS, incY);
+        Allocation vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dM, 1));
+        vectorYRef.copyFrom(mBLASData.L2_sGBMV_o_N);
+        verifyMatrix(vectorYRef, vectorYS);
+
+        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
+        trans = ScriptIntrinsicBLAS.TRANSPOSE;
+        // Reload vector Y, since it was overwritten by BLAS.
+        vectorYS.copyFrom(mBLASData.L2_sGBMV_y_m1);
+        // After Transpose matrixA, vectorX and vectorY are exchanged to match the dim of A.T
+        mBLAS.SGBMV(trans, mBLASData.KL, mBLASData.KU, alphaS, matrixAS, vectorYS, incY, betaS, vectorXS, incX);
+        vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, 1));
+        vectorYRef.copyFrom(mBLASData.L2_sGBMV_o_T);
+        verifyMatrix(vectorYRef, vectorXS);
+
+        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
+        vectorXS.copyFrom(mBLASData.L2_sGBMV_x_n1);
+        mBLAS.SGBMV(trans, mBLASData.KL, mBLASData.KU, alphaS, matrixAS, vectorYS, incY, betaS, vectorXS, incX);
+        vectorYRef.copyFrom(mBLASData.L2_sGBMV_o_H);
+        verifyMatrix(vectorYRef, vectorXS);
+
+        // Test for incX = 2 & incY = 3;
+        trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        incX = 2;
+        incY = 3;
+        int dimX = 1 + (mBLASData.dN - 1) * incX;
+        int dimY = 1 + (mBLASData.dM - 1) * incY;
+        vectorXS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimX, 1));
+        vectorYS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimY, 1));
+        vectorXS.copyFrom(mBLASData.L2_sGBMV_x_n2);
+        vectorYS.copyFrom(mBLASData.L2_sGBMV_y_m2);
+
+        mBLAS.SGBMV(trans, mBLASData.KL, mBLASData.KU, alphaS, matrixAS, vectorXS, incX, betaS, vectorYS, incY);
+        vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimY, 1));
+        vectorYRef.copyFrom(mBLASData.L2_sGBMV_o_N2);
+        verifyMatrix(vectorYRef, vectorYS);
+
+        mRS.finish();
+        checkError();
+    }
+
+    public void test_L2_DGBMV_Correctness() {
+        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        int incX = 1;
+        int incY = 1;
+
+        // Populate input allocations
+        Allocation matrixAD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dM));
+        Allocation vectorXD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, 1));
+        Allocation vectorYD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dM, 1));
+        matrixAD.copy2DRangeFrom(0, 0, mBLASData.KL + mBLASData.KU + 1, mBLASData.dM, mBLASData.L2_dGBMV_A_mn);
+        vectorXD.copyFrom(mBLASData.L2_dGBMV_x_n1);
+        vectorYD.copyFrom(mBLASData.L2_dGBMV_y_m1);
+
+        // Test for the default case: NO_TRANS
+        mBLAS.DGBMV(trans, mBLASData.KL, mBLASData.KU, alphaD, matrixAD, vectorXD, incX, betaD, vectorYD, incY);
+        Allocation vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dM, 1));
+        vectorYRef.copyFrom(mBLASData.L2_dGBMV_o_N);
+        verifyMatrix(vectorYRef, vectorYD);
+
+        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
+        trans = ScriptIntrinsicBLAS.TRANSPOSE;
+        // Reload vector Y, since it was overwritten by BLAS.
+        vectorYD.copyFrom(mBLASData.L2_dGBMV_y_m1);
+        // After Transpose matrixA, vectorX and vectorY are exchanged to match the dim of A.T
+        mBLAS.DGBMV(trans, mBLASData.KL, mBLASData.KU, alphaD, matrixAD, vectorYD, incY, betaD, vectorXD, incX);
+        vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, 1));
+        vectorYRef.copyFrom(mBLASData.L2_dGBMV_o_T);
+        verifyMatrix(vectorYRef, vectorXD);
+
+        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
+        vectorXD.copyFrom(mBLASData.L2_dGBMV_x_n1);
+        mBLAS.DGBMV(trans, mBLASData.KL, mBLASData.KU, alphaD, matrixAD, vectorYD, incY, betaD, vectorXD, incX);
+        vectorYRef.copyFrom(mBLASData.L2_dGBMV_o_H);
+        verifyMatrix(vectorYRef, vectorXD);
+
+        // Test for incX = 2 & incY = 3;
+        trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        incX = 2;
+        incY = 3;
+        int dimX = 1 + (mBLASData.dN - 1) * incX;
+        int dimY = 1 + (mBLASData.dM - 1) * incY;
+        vectorXD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimX, 1));
+        vectorYD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimY, 1));
+        vectorXD.copyFrom(mBLASData.L2_dGBMV_x_n2);
+        vectorYD.copyFrom(mBLASData.L2_dGBMV_y_m2);
+
+        mBLAS.DGBMV(trans, mBLASData.KL, mBLASData.KU, alphaD, matrixAD, vectorXD, incX, betaD, vectorYD, incY);
+        vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimY, 1));
+        vectorYRef.copyFrom(mBLASData.L2_dGBMV_o_N2);
+        verifyMatrix(vectorYRef, vectorYD);
+
+        mRS.finish();
+        checkError();
+    }
+
+    public void test_L2_CGBMV_Correctness() {
+        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        int incX = 1;
+        int incY = 1;
+
+        // Populate input allocations
+        Allocation matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dM));
+        Allocation vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, 1));
+        Allocation vectorYC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dM, 1));
+        matrixAC.copy2DRangeFrom(0, 0, mBLASData.KL + mBLASData.KU + 1, mBLASData.dM, mBLASData.L2_cGBMV_A_mn);
+        vectorXC.copyFrom(mBLASData.L2_cGBMV_x_n1);
+        vectorYC.copyFrom(mBLASData.L2_cGBMV_y_m1);
+
+        // Test for the default case: NO_TRANS
+        mBLAS.CGBMV(trans, mBLASData.KL, mBLASData.KU, alphaC, matrixAC, vectorXC, incX, betaC, vectorYC, incY);
+        Allocation vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dM, 1));
+        vectorYRef.copyFrom(mBLASData.L2_cGBMV_o_N);
+        verifyMatrix(vectorYRef, vectorYC);
+
+        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
+        trans = ScriptIntrinsicBLAS.TRANSPOSE;
+        // Reload vector Y, since it was overwritten by BLAS.
+        vectorYC.copyFrom(mBLASData.L2_cGBMV_y_m1);
+        // After Transpose matrixA, vectorX and vectorY are exchanged to match the dim of A.T
+        mBLAS.CGBMV(trans, mBLASData.KL, mBLASData.KU, alphaC, matrixAC, vectorYC, incY, betaC, vectorXC, incX);
+        vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, 1));
+        vectorYRef.copyFrom(mBLASData.L2_cGBMV_o_T);
+        verifyMatrix(vectorYRef, vectorXC);
+
+        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
+        vectorXC.copyFrom(mBLASData.L2_cGBMV_x_n1);
+        mBLAS.CGBMV(trans, mBLASData.KL, mBLASData.KU, alphaC, matrixAC, vectorYC, incY, betaC, vectorXC, incX);
+        vectorYRef.copyFrom(mBLASData.L2_cGBMV_o_H);
+        verifyMatrix(vectorYRef, vectorXC);
+
+        // Test for incX = 2 & incY = 3;
+        trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        incX = 2;
+        incY = 3;
+        int dimX = 1 + (mBLASData.dN - 1) * incX;
+        int dimY = 1 + (mBLASData.dM - 1) * incY;
+        vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimX, 1));
+        vectorYC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimY, 1));
+        vectorXC.copyFrom(mBLASData.L2_cGBMV_x_n2);
+        vectorYC.copyFrom(mBLASData.L2_cGBMV_y_m2);
+
+        mBLAS.CGBMV(trans, mBLASData.KL, mBLASData.KU, alphaC, matrixAC, vectorXC, incX, betaC, vectorYC, incY);
+        vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimY, 1));
+        vectorYRef.copyFrom(mBLASData.L2_cGBMV_o_N2);
+        verifyMatrix(vectorYRef, vectorYC);
+
+        mRS.finish();
+        checkError();
+    }
+
+    public void test_L2_ZGBMV_Correctness() {
+        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        int incX = 1;
+        int incY = 1;
+
+        // Populate input allocations
+        Allocation matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dM));
+        Allocation vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, 1));
+        Allocation vectorYZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dM, 1));
+        matrixAZ.copy2DRangeFrom(0, 0, mBLASData.KL + mBLASData.KU + 1, mBLASData.dM, mBLASData.L2_zGBMV_A_mn);
+        vectorXZ.copyFrom(mBLASData.L2_zGBMV_x_n1);
+        vectorYZ.copyFrom(mBLASData.L2_zGBMV_y_m1);
+
+        // Test for the default case: NO_TRANS
+        mBLAS.ZGBMV(trans, mBLASData.KL, mBLASData.KU, alphaZ, matrixAZ, vectorXZ, incX, betaZ, vectorYZ, incY);
+        Allocation vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dM, 1));
+        vectorYRef.copyFrom(mBLASData.L2_zGBMV_o_N);
+        verifyMatrix(vectorYRef, vectorYZ);
+
+        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
+        trans = ScriptIntrinsicBLAS.TRANSPOSE;
+        // Reload vector Y, since it was overwritten by BLAS.
+        vectorYZ.copyFrom(mBLASData.L2_zGBMV_y_m1);
+        // After Transpose matrixA, vectorX and vectorY are exchanged to match the dim of A.T
+        mBLAS.ZGBMV(trans, mBLASData.KL, mBLASData.KU, alphaZ, matrixAZ, vectorYZ, incY, betaZ, vectorXZ, incX);
+        vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, 1));
+        vectorYRef.copyFrom(mBLASData.L2_zGBMV_o_T);
+        verifyMatrix(vectorYRef, vectorXZ);
+
+        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
+        vectorXZ.copyFrom(mBLASData.L2_zGBMV_x_n1);
+        mBLAS.ZGBMV(trans, mBLASData.KL, mBLASData.KU, alphaZ, matrixAZ, vectorYZ, incX, betaZ, vectorXZ, incY);
+        vectorYRef.copyFrom(mBLASData.L2_zGBMV_o_H);
+        verifyMatrix(vectorYRef, vectorXZ);
+
+        // Test for incX = 2 & incY = 3;
+        trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        incX = 2;
+        incY = 3;
+        int dimX = 1 + (mBLASData.dN - 1) * incX;
+        int dimY = 1 + (mBLASData.dM - 1) * incY;
+        vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimX, 1));
+        vectorYZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimY, 1));
+        vectorXZ.copyFrom(mBLASData.L2_zGBMV_x_n2);
+        vectorYZ.copyFrom(mBLASData.L2_zGBMV_y_m2);
+
+        mBLAS.ZGBMV(trans, mBLASData.KL, mBLASData.KU, alphaZ, matrixAZ, vectorXZ, incX, betaZ, vectorYZ, incY);
+        vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimY, 1));
+        vectorYRef.copyFrom(mBLASData.L2_zGBMV_o_N2);
+        verifyMatrix(vectorYRef, vectorYZ);
+
+        mRS.finish();
+        checkError();
+    }
+
+
+    private void xHEMV_API_test(int Uplo, int incX, int incY, ArrayList<Allocation> mMatrix) {
+        for (Allocation matA : mMatrix) {
+            for (Allocation vecX : mMatrix) {
+                if (!validateVecInput(vecX)) {
+                    continue;
+                }
+                for (Allocation vecY : mMatrix) {
+                    if (!validateVecInput(vecY)) {
+                        continue;
+                    }
+                    Element elemA = matA.getType().getElement();
+                    if (validateSYR2(elemA, Uplo, vecX, incX, vecY, incY, matA)) {
+                        try {
+                            if (elemA.isCompatible(Element.F32_2(mRS))) {
+                                mBLAS.CHEMV(Uplo, alphaC, matA, vecX, incX, betaC, vecY, incY);
+                            } else if (elemA.isCompatible(Element.F64_2(mRS))) {
+                                mBLAS.ZHEMV(Uplo, alphaZ, matA, vecX, incX, betaZ, vecY, incY);
+                            }
+                        } catch (RSRuntimeException e) {
+                            fail("should NOT throw RSRuntimeException");
+                        }
+                    } else {
+                        try {
+                            mBLAS.CHEMV(Uplo, alphaC, matA, vecX, incX, betaC, vecY, incY);
+                            fail("should throw RSRuntimeException for CHEMV");
+                        } catch (RSRuntimeException e) {
+                        }
+                        try {
+                            mBLAS.ZHEMV(Uplo, alphaZ, matA, vecX, incX, betaZ, vecY, incY);
+                            fail("should throw RSRuntimeException for ZHEMV");
+                        } catch (RSRuntimeException e) {
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    public void L2_xHEMV_API(ArrayList<Allocation> mMatrix) {
+        for (int Uplo : mUplo) {
+            for (int incX : mInc) {
+                xHEMV_API_test(Uplo, incX, incX, mMatrix);
+            }
+        }
+    }
+
+    public void test_L2_CHEMV_API() {
+        L2_xHEMV_API(mMatrixC);
+    }
+
+    public void test_L2_ZHEMV_API() {
+        L2_xHEMV_API(mMatrixZ);
+    }
+
+    public void test_L2_CHEMV_Correctness() {
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+        int incX = 1;
+        int incY = 1;
+
+        // Populate input allocations
+        Allocation matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dN));
+        Allocation vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, 1));
+        Allocation vectorYC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, 1));
+        matrixAC.copyFrom(mBLASData.L2_cHEMV_A_nn);
+        vectorXC.copyFrom(mBLASData.L2_cHEMV_x_n1);
+        vectorYC.copyFrom(mBLASData.L2_cHEMV_y_n1);
+
+        // Test for the default case:
+        mBLAS.CHEMV(uplo, alphaC, matrixAC, vectorXC, incX, betaC, vectorYC, incY);
+        Allocation vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, 1));
+        vectorYRef.copyFrom(mBLASData.L2_cHEMV_o_N);
+        verifyMatrix(vectorYRef, vectorYC);
+
+        // Test for incX = 2 & incY = 3;
+        incX = 2;
+        incY = 3;
+        int dimX = 1 + (mBLASData.dN - 1) * incX;
+        int dimY = 1 + (mBLASData.dN - 1) * incY;
+        vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimX, 1));
+        vectorYC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimY, 1));
+        vectorXC.copyFrom(mBLASData.L2_cHEMV_x_n2);
+        vectorYC.copyFrom(mBLASData.L2_cHEMV_y_n2);
+
+        mBLAS.CHEMV(uplo, alphaC, matrixAC, vectorXC, incX, betaC, vectorYC, incY);
+        vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimY, 1));
+        vectorYRef.copyFrom(mBLASData.L2_cHEMV_o_N2);
+        verifyMatrix(vectorYRef, vectorYC);
+
+        mRS.finish();
+        checkError();
+    }
+
+    public void test_L2_ZHEMV_Correctness() {
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+        int incX = 1;
+        int incY = 1;
+
+        // Populate input allocations
+        Allocation matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dN));
+        Allocation vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, 1));
+        Allocation vectorYZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, 1));
+        matrixAZ.copyFrom(mBLASData.L2_zHEMV_A_nn);
+        vectorXZ.copyFrom(mBLASData.L2_zHEMV_x_n1);
+        vectorYZ.copyFrom(mBLASData.L2_zHEMV_y_n1);
+
+        // Test for the default case: NO_TRANS
+        mBLAS.ZHEMV(uplo, alphaZ, matrixAZ, vectorXZ, incX, betaZ, vectorYZ, incY);
+        Allocation vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, 1));
+        vectorYRef.copyFrom(mBLASData.L2_zHEMV_o_N);
+        verifyMatrix(vectorYRef, vectorYZ);
+
+        // Test for incX = 2 & incY = 3;
+        incX = 2;
+        incY = 3;
+        int dimX = 1 + (mBLASData.dN - 1) * incX;
+        int dimY = 1 + (mBLASData.dN - 1) * incY;
+        vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimX, 1));
+        vectorYZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimY, 1));
+        vectorXZ.copyFrom(mBLASData.L2_zHEMV_x_n2);
+        vectorYZ.copyFrom(mBLASData.L2_zHEMV_y_n2);
+
+        mBLAS.ZHEMV(uplo, alphaZ, matrixAZ, vectorXZ, incX, betaZ, vectorYZ, incY);
+        vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimY, 1));
+        vectorYRef.copyFrom(mBLASData.L2_zHEMV_o_N2);
+        verifyMatrix(vectorYRef, vectorYZ);
+
+        mRS.finish();
+        checkError();
+    }
+
+
+
+    private void xHBMV_API_test(int Uplo, int K, int incX, int incY, ArrayList<Allocation> mMatrix) {
+        for (Allocation matA : mMatrix) {
+            for (Allocation vecX : mMatrix) {
+                if (!validateVecInput(vecX)) {
+                    continue;
+                }
+                for (Allocation vecY : mMatrix) {
+                    if (!validateVecInput(vecY)) {
+                        continue;
+                    }
+                    Element elemA = matA.getType().getElement();
+                    if (validateSYR2(elemA, Uplo, vecX, incX, vecY, incY, matA) && K >= 0) {
+                        try {
+                            if (elemA.isCompatible(Element.F32_2(mRS))) {
+                                mBLAS.CHBMV(Uplo, K, alphaC, matA, vecX, incX, betaC, vecY, incY);
+                            } else if (elemA.isCompatible(Element.F64_2(mRS))) {
+                                mBLAS.ZHBMV(Uplo, K, alphaZ, matA, vecX, incX, betaZ, vecY, incY);
+                            }
+                        } catch (RSRuntimeException e) {
+                            fail("should NOT throw RSRuntimeException");
+                        }
+                    } else {
+                        try {
+                            mBLAS.CHBMV(Uplo, K, alphaC, matA, vecX, incX, betaC, vecY, incY);
+                            fail("should throw RSRuntimeException for CHBMV");
+                        } catch (RSRuntimeException e) {
+                        }
+                        try {
+                            mBLAS.ZHBMV(Uplo, K, alphaZ, matA, vecX, incX, betaZ, vecY, incY);
+                            fail("should throw RSRuntimeException for ZHBMV");
+                        } catch (RSRuntimeException e) {
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    public void L2_xHBMV_API(ArrayList<Allocation> mMatrix) {
+        for (int Uplo : mUplo) {
+            for (int K : mK) {
+                for (int incX : mInc) {
+                        xHBMV_API_test(Uplo, K, incX, incX, mMatrix);
+                }
+            }
+        }
+    }
+
+    public void test_L2_CHBMV_API() {
+        L2_xHBMV_API(mMatrixC);
+    }
+
+    public void test_L2_ZHBMV_API() {
+        L2_xHBMV_API(mMatrixZ);
+    }
+
+    public void test_L2_CHBMV_Correctness() {
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+        int incX = 1;
+        int incY = 1;
+
+        // Populate input allocations
+        Allocation matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dN));
+        Allocation vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, 1));
+        Allocation vectorYC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, 1));
+        matrixAC.copy2DRangeFrom(0, 0, mBLASData.KL + 1, mBLASData.dN, mBLASData.L2_cHBMV_A_nn);
+        vectorXC.copyFrom(mBLASData.L2_cHBMV_x_n1);
+        vectorYC.copyFrom(mBLASData.L2_cHBMV_y_n1);
+
+        // Test for the default case:
+        mBLAS.CHBMV(uplo, mBLASData.KL, alphaC, matrixAC, vectorXC, incX, betaC, vectorYC, incY);
+        Allocation vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, 1));
+        vectorYRef.copyFrom(mBLASData.L2_cHBMV_o_N);
+        verifyMatrix(vectorYRef, vectorYC);
+
+        // Test for incX = 2 & incY = 3;
+        incX = 2;
+        incY = 3;
+        int dimX = 1 + (mBLASData.dN - 1) * incX;
+        int dimY = 1 + (mBLASData.dN - 1) * incY;
+        vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimX, 1));
+        vectorYC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimY, 1));
+        vectorXC.copyFrom(mBLASData.L2_cHBMV_x_n2);
+        vectorYC.copyFrom(mBLASData.L2_cHBMV_y_n2);
+
+        mBLAS.CHBMV(uplo, mBLASData.KL, alphaC, matrixAC, vectorXC, incX, betaC, vectorYC, incY);
+        vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimY, 1));
+        vectorYRef.copyFrom(mBLASData.L2_cHBMV_o_N2);
+        verifyMatrix(vectorYRef, vectorYC);
+
+        mRS.finish();
+        checkError();
+    }
+
+    public void test_L2_ZHBMV_Correctness() {
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+        int incX = 1;
+        int incY = 1;
+
+        // Populate input allocations
+        Allocation matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dN));
+        Allocation vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, 1));
+        Allocation vectorYZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, 1));
+        matrixAZ.copy2DRangeFrom(0, 0, mBLASData.KL + 1, mBLASData.dN, mBLASData.L2_zHBMV_A_nn);
+        vectorXZ.copyFrom(mBLASData.L2_zHBMV_x_n1);
+        vectorYZ.copyFrom(mBLASData.L2_zHBMV_y_n1);
+
+        // Test for the default case: NO_TRANS
+        mBLAS.ZHBMV(uplo, mBLASData.KL, alphaZ, matrixAZ, vectorXZ, incX, betaZ, vectorYZ, incY);
+        Allocation vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, 1));
+        vectorYRef.copyFrom(mBLASData.L2_zHBMV_o_N);
+        verifyMatrix(vectorYRef, vectorYZ);
+
+        // Test for incX = 2 & incY = 3;
+        incX = 2;
+        incY = 3;
+        int dimX = 1 + (mBLASData.dN - 1) * incX;
+        int dimY = 1 + (mBLASData.dN - 1) * incY;
+        vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimX, 1));
+        vectorYZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimY, 1));
+        vectorXZ.copyFrom(mBLASData.L2_zHBMV_x_n2);
+        vectorYZ.copyFrom(mBLASData.L2_zHBMV_y_n2);
+
+        mBLAS.ZHBMV(uplo, mBLASData.KL, alphaZ, matrixAZ, vectorXZ, incX, betaZ, vectorYZ, incY);
+        vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimY, 1));
+        vectorYRef.copyFrom(mBLASData.L2_zHBMV_o_N2);
+        verifyMatrix(vectorYRef, vectorYZ);
+
+        mRS.finish();
+        checkError();
+    }
+
+
+    private void xHPMV_API_test(int Uplo, int incX, int incY, ArrayList<Allocation> mMatrix) {
+        for (Allocation matA : mMatrix) {
+            for (Allocation vecX : mMatrix) {
+                if (!validateVecInput(vecX)) {
+                    continue;
+                }
+                for (Allocation vecY : mMatrix) {
+                    if (!validateVecInput(vecY)) {
+                        continue;
+                    }
+                    Element elemA = matA.getType().getElement();
+                    if (validateSPR2(elemA, Uplo, vecX, incX, vecY, incY, matA)) {
+                        try {
+                            if (elemA.isCompatible(Element.F32_2(mRS))) {
+                                mBLAS.CHPMV(Uplo, alphaC, matA, vecX, incX, betaC, vecY, incY);
+                            } else if (elemA.isCompatible(Element.F64_2(mRS))) {
+                                mBLAS.ZHPMV(Uplo, alphaZ, matA, vecX, incX, betaZ, vecY, incY);
+                            }
+                        } catch (RSRuntimeException e) {
+                            fail("should NOT throw RSRuntimeException");
+                        }
+                    } else {
+                        try {
+                            mBLAS.CHPMV(Uplo, alphaC, matA, vecX, incX, betaC, vecY, incY);
+                            fail("should throw RSRuntimeException for CHPMV");
+                        } catch (RSRuntimeException e) {
+                        }
+                        try {
+                            mBLAS.ZHPMV(Uplo, alphaZ, matA, vecX, incX, betaZ, vecY, incY);
+                            fail("should throw RSRuntimeException for ZHPMV");
+                        } catch (RSRuntimeException e) {
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    public void L2_xHPMV_API(ArrayList<Allocation> mMatrix) {
+        for (int Uplo : mUplo) {
+            for (int incX : mInc) {
+                xHPMV_API_test(Uplo, incX, incX, mMatrix);
+            }
+        }
+    }
+
+    public void test_L2_CHPMV_API() {
+        L2_xHPMV_API(mMatrixC);
+    }
+
+    public void test_L2_ZHPMV_API() {
+        L2_xHPMV_API(mMatrixZ);
+    }
+
+    public void test_L2_CHPMV_Correctness() {
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+        int incX = 1;
+        int incY = 1;
+
+        // Populate input allocations
+        int N = mBLASData.dN;
+        Allocation matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), N * (N+1) / 2, 1));
+        Allocation vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), N, 1));
+        Allocation vectorYC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), N, 1));
+        matrixAC.copyFrom(mBLASData.L2_cHEMV_A_nn_pu);
+        vectorXC.copyFrom(mBLASData.L2_cHEMV_x_n1);
+        vectorYC.copyFrom(mBLASData.L2_cHEMV_y_n1);
+
+        // Test for the default case:
+        mBLAS.CHPMV(uplo, alphaC, matrixAC, vectorXC, incX, betaC, vectorYC, incY);
+        Allocation vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), N, 1));
+        vectorYRef.copyFrom(mBLASData.L2_cHEMV_o_N);
+        verifyMatrix(vectorYRef, vectorYC);
+
+        // Test for incX = 2 & incY = 3;
+        incX = 2;
+        incY = 3;
+        int dimX = 1 + (N - 1) * incX;
+        int dimY = 1 + (N - 1) * incY;
+        vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimX, 1));
+        vectorYC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimY, 1));
+        vectorXC.copyFrom(mBLASData.L2_cHEMV_x_n2);
+        vectorYC.copyFrom(mBLASData.L2_cHEMV_y_n2);
+
+        mBLAS.CHPMV(uplo, alphaC, matrixAC, vectorXC, incX, betaC, vectorYC, incY);
+        vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimY, 1));
+        vectorYRef.copyFrom(mBLASData.L2_cHEMV_o_N2);
+        verifyMatrix(vectorYRef, vectorYC);
+
+        mRS.finish();
+        checkError();
+    }
+
+    public void test_L2_ZHPMV_Correctness() {
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+        int incX = 1;
+        int incY = 1;
+
+        // Populate input allocations
+        int N = mBLASData.dN;
+        Allocation matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), N * (N+1) / 2, 1));
+        Allocation vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), N, 1));
+        Allocation vectorYZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), N, 1));
+        matrixAZ.copyFrom(mBLASData.L2_zHEMV_A_nn_pu);
+        vectorXZ.copyFrom(mBLASData.L2_zHEMV_x_n1);
+        vectorYZ.copyFrom(mBLASData.L2_zHEMV_y_n1);
+
+        // Test for the default case: NO_TRANS
+        mBLAS.ZHPMV(uplo, alphaZ, matrixAZ, vectorXZ, incX, betaZ, vectorYZ, incY);
+        Allocation vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), N, 1));
+        vectorYRef.copyFrom(mBLASData.L2_zHEMV_o_N);
+        verifyMatrix(vectorYRef, vectorYZ);
+
+        // Test for incX = 2 & incY = 3;
+        incX = 2;
+        incY = 3;
+        int dimX = 1 + (N - 1) * incX;
+        int dimY = 1 + (N - 1) * incY;
+        vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimX, 1));
+        vectorYZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimY, 1));
+        vectorXZ.copyFrom(mBLASData.L2_zHEMV_x_n2);
+        vectorYZ.copyFrom(mBLASData.L2_zHEMV_y_n2);
+
+        mBLAS.ZHPMV(uplo, alphaZ, matrixAZ, vectorXZ, incX, betaZ, vectorYZ, incY);
+        vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimY, 1));
+        vectorYRef.copyFrom(mBLASData.L2_zHEMV_o_N2);
+        verifyMatrix(vectorYRef, vectorYZ);
+
+        mRS.finish();
+        checkError();
+    }
+
+
+    private boolean validateSYMV(Element e, int Uplo, Allocation A, Allocation X, int incX, Allocation Y, int incY) {
+        if (!validateUplo(Uplo)) {
+            return false;
+        }
+        int N = A.getType().getY();
+        if (A.getType().getX() != N) {
+            return false;
+        }
+        if (!A.getType().getElement().isCompatible(e) ||
+            !X.getType().getElement().isCompatible(e) ||
+            !Y.getType().getElement().isCompatible(e) ) {
+            return false;
+        }
+        if (X.getType().getY() > 1 || Y.getType().getY() > 1) {
+            return false;
+        }
+
+        if (incX <= 0 || incY <= 0) {
+            return false;
+        }
+        int expectedXDim = 1 + (N - 1) * incX;
+        if (X.getType().getX() != expectedXDim) {
+            return false;
+        }
+        int expectedYDim = 1 + (N - 1) * incY;
+        if (Y.getType().getX() != expectedYDim) {
+            return false;
+        }
+        return true;
+    }
+
+    private void xSYMV_API_test(int Uplo, int incX, int incY, ArrayList<Allocation> mMatrix) {
+        for (Allocation matA : mMatrix) {
+            for (Allocation vecX : mMatrix) {
+                if (!validateVecInput(vecX)) {
+                    continue;
+                }
+                for (Allocation vecY : mMatrix) {
+                    if (!validateVecInput(vecY)) {
+                        continue;
+                    }
+                    Element elemA = matA.getType().getElement();
+                    if (validateSYMV(elemA, Uplo, matA, vecX, incX, vecY, incY)) {
+                        try {
+                            if (elemA.isCompatible(Element.F32(mRS))) {
+                                mBLAS.SSYMV(Uplo, alphaS, matA, vecX, incX, betaS, vecY, incY);
+                            } else if (elemA.isCompatible(Element.F64(mRS))) {
+                                mBLAS.DSYMV(Uplo, alphaD, matA, vecX, incX, betaD, vecY, incY);
+                            }
+                        } catch (RSRuntimeException e) {
+                            fail("should NOT throw RSRuntimeException");
+                        }
+                    } else {
+                        try {
+                            mBLAS.SSYMV(Uplo, alphaS, matA, vecX, incX, betaS, vecY, incY);
+                            fail("should throw RSRuntimeException for SSYMV");
+                        } catch (RSRuntimeException e) {
+                        }
+                        try {
+                            mBLAS.DSYMV(Uplo, alphaD, matA, vecX, incX, betaD, vecY, incY);
+                            fail("should throw RSRuntimeException for DSYMV");
+                        } catch (RSRuntimeException e) {
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    public void L2_xSYMV_API(ArrayList<Allocation> mMatrix) {
+        for (int Uplo : mUplo) {
+            for (int incX : mInc) {
+                xSYMV_API_test(Uplo, incX, incX, mMatrix);
+            }
+        }
+    }
+
+    public void test_L2_SSYMV_API() {
+        L2_xSYMV_API(mMatrixS);
+    }
+
+    public void test_L2_DSYMV_API() {
+        L2_xSYMV_API(mMatrixD);
+    }
+
+    public void test_L2_SSYMV_Correctness() {
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+        int incX = 1;
+        int incY = 1;
+
+        // Populate input allocations
+        Allocation matrixAS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dN));
+        Allocation vectorXS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, 1));
+        Allocation vectorYS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, 1));
+        matrixAS.copyFrom(mBLASData.L2_sSYMV_A_nn);
+        vectorXS.copyFrom(mBLASData.L2_sSYMV_x_n1);
+        vectorYS.copyFrom(mBLASData.L2_sSYMV_y_n1);
+
+        // Test for the default case:
+        mBLAS.SSYMV(uplo, alphaS, matrixAS, vectorXS, incX, betaS, vectorYS, incY);
+        Allocation vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, 1));
+        vectorYRef.copyFrom(mBLASData.L2_sSYMV_o_N);
+        verifyMatrix(vectorYRef, vectorYS);
+
+        // Test for incX = 2 & incY = 3;
+        incX = 2;
+        incY = 3;
+        int dimX = 1 + (mBLASData.dN - 1) * incX;
+        int dimY = 1 + (mBLASData.dN - 1) * incY;
+        vectorXS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimX, 1));
+        vectorYS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimY, 1));
+        vectorXS.copyFrom(mBLASData.L2_sSYMV_x_n2);
+        vectorYS.copyFrom(mBLASData.L2_sSYMV_y_n2);
+
+        mBLAS.SSYMV(uplo, alphaS, matrixAS, vectorXS, incX, betaS, vectorYS, incY);
+        vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimY, 1));
+        vectorYRef.copyFrom(mBLASData.L2_sSYMV_o_N2);
+        verifyMatrix(vectorYRef, vectorYS);
+
+        mRS.finish();
+        checkError();
+    }
+
+    public void test_L2_DSYMV_Correctness() {
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+        int incX = 1;
+        int incY = 1;
+
+        // Populate input allocations
+        Allocation matrixAD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dN));
+        Allocation vectorXD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, 1));
+        Allocation vectorYD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, 1));
+        matrixAD.copyFrom(mBLASData.L2_dSYMV_A_nn);
+        vectorXD.copyFrom(mBLASData.L2_dSYMV_x_n1);
+        vectorYD.copyFrom(mBLASData.L2_dSYMV_y_n1);
+
+        // Test for the default case:
+        mBLAS.DSYMV(uplo, alphaD, matrixAD, vectorXD, incX, betaD, vectorYD, incY);
+        Allocation vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, 1));
+        vectorYRef.copyFrom(mBLASData.L2_dSYMV_o_N);
+        verifyMatrix(vectorYRef, vectorYD);
+
+        // Test for incX = 2 & incY = 3;
+        incX = 2;
+        incY = 3;
+        int dimX = 1 + (mBLASData.dN - 1) * incX;
+        int dimY = 1 + (mBLASData.dN - 1) * incY;
+        vectorXD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimX, 1));
+        vectorYD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimY, 1));
+        vectorXD.copyFrom(mBLASData.L2_dSYMV_x_n2);
+        vectorYD.copyFrom(mBLASData.L2_dSYMV_y_n2);
+
+        mBLAS.DSYMV(uplo, alphaD, matrixAD, vectorXD, incX, betaD, vectorYD, incY);
+        vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimY, 1));
+        vectorYRef.copyFrom(mBLASData.L2_dSYMV_o_N2);
+        verifyMatrix(vectorYRef, vectorYD);
+
+        mRS.finish();
+        checkError();
+    }
+
+
+
+    private void xSBMV_API_test(int Uplo, int K, int incX, int incY, ArrayList<Allocation> mMatrix) {
+        for (Allocation matA : mMatrix) {
+            for (Allocation vecX : mMatrix) {
+                if (!validateVecInput(vecX)) {
+                    continue;
+                }
+                for (Allocation vecY : mMatrix) {
+                    if (!validateVecInput(vecY)) {
+                        continue;
+                    }
+                    Element elemA = matA.getType().getElement();
+                    if (validateSYMV(elemA, Uplo, matA, vecX, incX, vecY, incY) && K >= 0) {
+                        try {
+                            if (elemA.isCompatible(Element.F32(mRS))) {
+                                mBLAS.SSBMV(Uplo, K, alphaS, matA, vecX, incX, betaS, vecY, incY);
+                            } else if (elemA.isCompatible(Element.F64(mRS))) {
+                                mBLAS.DSBMV(Uplo, K, alphaD, matA, vecX, incX, betaD, vecY, incY);
+                            }
+                        } catch (RSRuntimeException e) {
+                            fail("should NOT throw RSRuntimeException");
+                        }
+                    } else {
+                        try {
+                            mBLAS.SSBMV(Uplo, K, alphaS, matA, vecX, incX, betaS, vecY, incY);
+                            fail("should throw RSRuntimeException for SSBMV");
+                        } catch (RSRuntimeException e) {
+                        }
+                        try {
+                            mBLAS.DSBMV(Uplo, K, alphaD, matA, vecX, incX, betaD, vecY, incY);
+                            fail("should throw RSRuntimeException for DSBMV");
+                        } catch (RSRuntimeException e) {
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    public void L2_xSBMV_API(ArrayList<Allocation> mMatrix) {
+        for (int Uplo : mUplo) {
+            for (int K : mK) {
+                for (int incX : mInc) {
+                    xSBMV_API_test(Uplo, K, incX, incX, mMatrix);
+                }
+            }
+        }
+    }
+
+    public void test_L2_SSBMV_API() {
+        L2_xSBMV_API(mMatrixS);
+    }
+
+    public void test_L2_DSBMV_API() {
+        L2_xSBMV_API(mMatrixD);
+    }
+
+    public void test_L2_SSBMV_Correctness() {
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+        int incX = 1;
+        int incY = 1;
+
+        // Populate input allocations
+        Allocation matrixAS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dN));
+        Allocation vectorXS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, 1));
+        Allocation vectorYS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, 1));
+        matrixAS.copy2DRangeFrom(0, 0, mBLASData.KL + 1, mBLASData.dN, mBLASData.L2_sSBMV_A_nn);
+        vectorXS.copyFrom(mBLASData.L2_sSBMV_x_n1);
+        vectorYS.copyFrom(mBLASData.L2_sSBMV_y_n1);
+
+        // Test for the default case:
+        mBLAS.SSBMV(uplo, mBLASData.KL, alphaS, matrixAS, vectorXS, incX, betaS, vectorYS, incY);
+        Allocation vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, 1));
+        vectorYRef.copyFrom(mBLASData.L2_sSBMV_o_N);
+        verifyMatrix(vectorYRef, vectorYS);
+
+        // Test for incX = 2 & incY = 3;
+        incX = 2;
+        incY = 3;
+        int dimX = 1 + (mBLASData.dN - 1) * incX;
+        int dimY = 1 + (mBLASData.dN - 1) * incY;
+        vectorXS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimX, 1));
+        vectorYS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimY, 1));
+        vectorXS.copyFrom(mBLASData.L2_sSBMV_x_n2);
+        vectorYS.copyFrom(mBLASData.L2_sSBMV_y_n2);
+
+        mBLAS.SSBMV(uplo, mBLASData.KL, alphaS, matrixAS, vectorXS, incX, betaS, vectorYS, incY);
+        vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimY, 1));
+        vectorYRef.copyFrom(mBLASData.L2_sSBMV_o_N2);
+        verifyMatrix(vectorYRef, vectorYS);
+
+        mRS.finish();
+        checkError();
+    }
+
+    public void test_L2_DSBMV_Correctness() {
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+        int incX = 1;
+        int incY = 1;
+
+        // Populate input allocations
+        Allocation matrixAD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dN));
+        Allocation vectorXD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, 1));
+        Allocation vectorYD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, 1));
+        matrixAD.copy2DRangeFrom(0, 0, mBLASData.KL + 1, mBLASData.dN, mBLASData.L2_dSBMV_A_nn);
+        vectorXD.copyFrom(mBLASData.L2_dSBMV_x_n1);
+        vectorYD.copyFrom(mBLASData.L2_dSBMV_y_n1);
+
+        // Test for the default case:
+        mBLAS.DSBMV(uplo, mBLASData.KL, alphaD, matrixAD, vectorXD, incX, betaD, vectorYD, incY);
+        Allocation vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, 1));
+        vectorYRef.copyFrom(mBLASData.L2_dSBMV_o_N);
+        verifyMatrix(vectorYRef, vectorYD);
+
+        // Test for incX = 2 & incY = 3;
+        incX = 2;
+        incY = 3;
+        int dimX = 1 + (mBLASData.dN - 1) * incX;
+        int dimY = 1 + (mBLASData.dN - 1) * incY;
+        vectorXD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimX, 1));
+        vectorYD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimY, 1));
+        vectorXD.copyFrom(mBLASData.L2_dSBMV_x_n2);
+        vectorYD.copyFrom(mBLASData.L2_dSBMV_y_n2);
+
+        mBLAS.DSBMV(uplo, mBLASData.KL, alphaD, matrixAD, vectorXD, incX, betaD, vectorYD, incY);
+        vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimY, 1));
+        vectorYRef.copyFrom(mBLASData.L2_dSBMV_o_N2);
+        verifyMatrix(vectorYRef, vectorYD);
+
+        mRS.finish();
+        checkError();
+    }
+
+
+    private boolean validateSPMV(Element e, int Uplo, Allocation Ap, Allocation X, int incX, Allocation Y, int incY) {
+        if (!validateUplo(Uplo)) {
+            return false;
+        }
+        if (!Ap.getType().getElement().isCompatible(e) ||
+            !X.getType().getElement().isCompatible(e) ||
+            !Y.getType().getElement().isCompatible(e)) {
+            return false;
+        }
+        if (X.getType().getY() > 1 || Y.getType().getY() > 1) {
+            return false;
+        }
+
+        if (Ap.getType().getY() > 1) {
+            return false;
+        }
+
+        int N = (int)Math.sqrt((double)Ap.getType().getX() * 2);
+        if (Ap.getType().getX() != ((N * (N+1)) / 2)) {
+            return false;
+        }
+        if (incX <= 0 || incY <= 0) {
+            return false;
+        }
+        int expectedXDim = 1 + (N - 1) * incX;
+        if (X.getType().getX() != expectedXDim) {
+            return false;
+        }
+        int expectedYDim = 1 + (N - 1) * incY;
+        if (Y.getType().getX() != expectedYDim) {
+            return false;
+        }
+
+        return true;
+    }
+
+    private void xSPMV_API_test(int Uplo, int incX, int incY, ArrayList<Allocation> mMatrix) {
+        for (Allocation matA : mMatrix) {
+            for (Allocation vecX : mMatrix) {
+                if (!validateVecInput(vecX)) {
+                    continue;
+                }
+                for (Allocation vecY : mMatrix) {
+                    if (!validateVecInput(vecY)) {
+                        continue;
+                    }
+                    Element elemA = matA.getType().getElement();
+                    if (validateSPMV(elemA, Uplo, matA, vecX, incX, vecY, incY)) {
+                        try {
+                            if (elemA.isCompatible(Element.F32(mRS))) {
+                                mBLAS.SSPMV(Uplo, alphaS, matA, vecX, incX, betaS, vecY, incY);
+                            } else if (elemA.isCompatible(Element.F64(mRS))) {
+                                mBLAS.DSPMV(Uplo, alphaD, matA, vecX, incX, betaD, vecY, incY);
+                            }
+                        } catch (RSRuntimeException e) {
+                            fail("should NOT throw RSRuntimeException");
+                        }
+                    } else {
+                        try {
+                            mBLAS.SSPMV(Uplo, alphaS, matA, vecX, incX, betaS, vecY, incY);
+                            fail("should throw RSRuntimeException for SSPMV");
+                        } catch (RSRuntimeException e) {
+                        }
+                        try {
+                            mBLAS.DSPMV(Uplo, alphaD, matA, vecX, incX, betaD, vecY, incY);
+                            fail("should throw RSRuntimeException for DSPMV");
+                        } catch (RSRuntimeException e) {
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    public void L2_xSPMV_API(ArrayList<Allocation> mMatrix) {
+        for (int Uplo : mUplo) {
+            for (int incX : mInc) {
+                xSPMV_API_test(Uplo, incX, incX, mMatrix);
+            }
+        }
+    }
+
+    public void test_L2_SSPMV_API() {
+        L2_xSPMV_API(mMatrixS);
+    }
+
+    public void test_L2_DSPMV_API() {
+        L2_xSPMV_API(mMatrixD);
+    }
+
+    public void test_L2_SSPMV_Correctness() {
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+        int incX = 1;
+        int incY = 1;
+
+        // Populate input allocations
+        int N = mBLASData.dN;
+        Allocation matrixAS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), N * (N+1) / 2, 1));
+        Allocation vectorXS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), N, 1));
+        Allocation vectorYS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), N, 1));
+        matrixAS.copyFrom(mBLASData.L2_sSYMV_A_nn_pu);
+        vectorXS.copyFrom(mBLASData.L2_sSYMV_x_n1);
+        vectorYS.copyFrom(mBLASData.L2_sSYMV_y_n1);
+
+        // Test for the default case:
+        mBLAS.SSPMV(uplo, alphaS, matrixAS, vectorXS, incX, betaS, vectorYS, incY);
+        Allocation vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), N, 1));
+        vectorYRef.copyFrom(mBLASData.L2_sSYMV_o_N);
+        verifyMatrix(vectorYRef, vectorYS);
+
+        // Test for incX = 2 & incY = 3;
+        incX = 2;
+        incY = 3;
+        int dimX = 1 + (N - 1) * incX;
+        int dimY = 1 + (N - 1) * incY;
+        vectorXS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimX, 1));
+        vectorYS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimY, 1));
+        vectorXS.copyFrom(mBLASData.L2_sSYMV_x_n2);
+        vectorYS.copyFrom(mBLASData.L2_sSYMV_y_n2);
+
+        mBLAS.SSPMV(uplo, alphaS, matrixAS, vectorXS, incX, betaS, vectorYS, incY);
+        vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimY, 1));
+        vectorYRef.copyFrom(mBLASData.L2_sSYMV_o_N2);
+        verifyMatrix(vectorYRef, vectorYS);
+
+        mRS.finish();
+        checkError();
+    }
+
+    public void test_L2_DSPMV_Correctness() {
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+        int incX = 1;
+        int incY = 1;
+
+        // Populate input allocations
+        int N = mBLASData.dN;
+        Allocation matrixAD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), N * (N+1) / 2, 1));
+        Allocation vectorXD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), N, 1));
+        Allocation vectorYD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), N, 1));
+        matrixAD.copyFrom(mBLASData.L2_dSYMV_A_nn_pu);
+        vectorXD.copyFrom(mBLASData.L2_dSYMV_x_n1);
+        vectorYD.copyFrom(mBLASData.L2_dSYMV_y_n1);
+
+        // Test for the default case:
+        mBLAS.DSPMV(uplo, alphaD, matrixAD, vectorXD, incX, betaD, vectorYD, incY);
+        Allocation vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), N, 1));
+        vectorYRef.copyFrom(mBLASData.L2_dSYMV_o_N);
+        verifyMatrix(vectorYRef, vectorYD);
+
+        // Test for incX = 2 & incY = 3;
+        incX = 2;
+        incY = 3;
+        int dimX = 1 + (N - 1) * incX;
+        int dimY = 1 + (N - 1) * incY;
+        vectorXD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimX, 1));
+        vectorYD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimY, 1));
+        vectorXD.copyFrom(mBLASData.L2_dSYMV_x_n2);
+        vectorYD.copyFrom(mBLASData.L2_dSYMV_y_n2);
+
+        mBLAS.DSPMV(uplo, alphaD, matrixAD, vectorXD, incX, betaD, vectorYD, incY);
+        vectorYRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimY, 1));
+        vectorYRef.copyFrom(mBLASData.L2_dSYMV_o_N2);
+        verifyMatrix(vectorYRef, vectorYD);
+
+        mRS.finish();
+        checkError();
+    }
+
+
+
+    private boolean validateTRMV(Element e, int Uplo, int TransA, int Diag, Allocation A, Allocation X, int incX) {
+        if (!validateUplo(Uplo)) {
+            return false;
+        }
+        if (!validateTranspose(TransA)) {
+            return false;
+        }
+        if (!validateDiag(Diag)) {
+            return false;
+        }
+        int N = A.getType().getY();
+        if (A.getType().getX() != N) {
+            return false;
+        }
+        if (!A.getType().getElement().isCompatible(e) ||
+            !X.getType().getElement().isCompatible(e)) {
+            return false;
+        }
+        if (X.getType().getY() > 1) {
+            return false;
+        }
+
+        if (incX <= 0) {
+            return false;
+        }
+        int expectedXDim = 1 + (N - 1) * incX;
+        if (X.getType().getX() != expectedXDim) {
+            return false;
+        }
+        return true;
+    }
+
+    private void xTRMV_API_test(int Uplo, int TransA, int Diag, int incX, ArrayList<Allocation> mMatrix) {
+        for (Allocation matA : mMatrix) {
+            for (Allocation vecX : mMatrix) {
+                if (!validateVecInput(vecX)) {
+                    continue;
+                }
+                Element elemA = matA.getType().getElement();
+                if (validateTRMV(elemA, Uplo, TransA, Diag, matA, vecX, incX)) {
+                    try {
+                        if (elemA.isCompatible(Element.F32(mRS))) {
+                            mBLAS.STRMV(Uplo, TransA, Diag, matA, vecX, incX);
+                        } else if (elemA.isCompatible(Element.F64(mRS))) {
+                            mBLAS.DTRMV(Uplo, TransA, Diag, matA, vecX, incX);
+                        } else if (elemA.isCompatible(Element.F32_2(mRS))) {
+                            mBLAS.CTRMV(Uplo, TransA, Diag, matA, vecX, incX);
+                        } else if (elemA.isCompatible(Element.F64_2(mRS))) {
+                            mBLAS.ZTRMV(Uplo, TransA, Diag, matA, vecX, incX);
+                        }
+                    } catch (RSRuntimeException e) {
+                        fail("should NOT throw RSRuntimeException");
+                    }
+                } else {
+                    try {
+                        mBLAS.STRMV(Uplo, TransA, Diag, matA, vecX, incX);
+                        fail("should throw RSRuntimeException for STRMV");
+                    } catch (RSRuntimeException e) {
+                    }
+                    try {
+                        mBLAS.DTRMV(Uplo, TransA, Diag, matA, vecX, incX);
+                        fail("should throw RSRuntimeException for DTRMV");
+                    } catch (RSRuntimeException e) {
+                    }
+                    try {
+                        mBLAS.CTRMV(Uplo, TransA, Diag, matA, vecX, incX);
+                        fail("should throw RSRuntimeException for CTRMV");
+                    } catch (RSRuntimeException e) {
+                    }
+                    try {
+                        mBLAS.ZTRMV(Uplo, TransA, Diag, matA, vecX, incX);
+                        fail("should throw RSRuntimeException for ZTRMV");
+                    } catch (RSRuntimeException e) {
+                    }
+                }
+            }
+        }
+    }
+
+    public void L2_xTRMV_API(ArrayList<Allocation> mMatrix) {
+        for (int Uplo : mUplo) {
+            for (int TransA : mTranspose) {
+                for (int Diag : mDiag) {
+                    for (int incX : mInc) {
+                        xTRMV_API_test(Uplo, TransA, Diag, incX, mMatrix);
+                    }
+                }
+            }
+        }
+    }
+
+    public void test_L2_STRMV_API() {
+        L2_xTRMV_API(mMatrixS);
+    }
+
+    public void test_L2_DTRMV_API() {
+        L2_xTRMV_API(mMatrixD);
+    }
+
+    public void test_L2_CTRMV_API() {
+        L2_xTRMV_API(mMatrixC);
+    }
+
+    public void test_L2_ZTRMV_API() {
+        L2_xTRMV_API(mMatrixZ);
+    }
+
+    public void test_L2_STRMV_Correctness() {
+        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+        int diag = ScriptIntrinsicBLAS.NON_UNIT;
+        int incX = 1;
+
+        // Populate input allocations
+        Allocation matrixAS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dN));
+        Allocation vectorXS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, 1));
+        matrixAS.copyFrom(mBLASData.L2_sTRMV_A_nn);
+        vectorXS.copyFrom(mBLASData.L2_sTRMV_x_n1);
+
+        // Test for the default case: NO_TRANS
+        mBLAS.STRMV(uplo, trans, diag, matrixAS, vectorXS, incX);
+        Allocation vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, 1));
+        vectorXRef.copyFrom(mBLASData.L2_sTRMV_o_UN);
+        verifyMatrix(vectorXRef, vectorXS);
+
+        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
+        trans = ScriptIntrinsicBLAS.TRANSPOSE;
+        // Reload vector X, since it was overwritten by BLAS.
+        vectorXS.copyFrom(mBLASData.L2_sTRMV_x_n1);
+        mBLAS.STRMV(uplo, trans, diag, matrixAS, vectorXS, incX);
+        vectorXRef.copyFrom(mBLASData.L2_sTRMV_o_UT);
+        verifyMatrix(vectorXRef, vectorXS);
+
+        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
+        vectorXS.copyFrom(mBLASData.L2_sTRMV_x_n1);
+        mBLAS.STRMV(uplo, trans, diag, matrixAS, vectorXS, incX);
+        vectorXRef.copyFrom(mBLASData.L2_sTRMV_o_UH);
+        verifyMatrix(vectorXRef, vectorXS);
+
+        // Test for incX = 2;
+        trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        incX = 2;
+        int dimX = 1 + (mBLASData.dN - 1) * incX;
+        vectorXS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimX, 1));
+        vectorXS.copyFrom(mBLASData.L2_sTRMV_x_n2);
+
+        mBLAS.STRMV(uplo, trans, diag, matrixAS, vectorXS, incX);
+        vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimX, 1));
+        vectorXRef.copyFrom(mBLASData.L2_sTRMV_o_UN2);
+        verifyMatrix(vectorXRef, vectorXS);
+
+        mRS.finish();
+        checkError();
+    }
+
+    public void test_L2_DTRMV_Correctness() {
+        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+        int diag = ScriptIntrinsicBLAS.NON_UNIT;
+        int incX = 1;
+
+        // Populate input allocations
+        Allocation matrixAD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dN));
+        Allocation vectorXD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, 1));
+        matrixAD.copyFrom(mBLASData.L2_dTRMV_A_nn);
+        vectorXD.copyFrom(mBLASData.L2_dTRMV_x_n1);
+
+        // Test for the default case: NO_TRANS
+        mBLAS.DTRMV(uplo, trans, diag, matrixAD, vectorXD, incX);
+        Allocation vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, 1));
+        vectorXRef.copyFrom(mBLASData.L2_dTRMV_o_UN);
+        verifyMatrix(vectorXRef, vectorXD);
+
+        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
+        trans = ScriptIntrinsicBLAS.TRANSPOSE;
+        // Reload vector X, since it was overwritten by BLAS.
+        vectorXD.copyFrom(mBLASData.L2_dTRMV_x_n1);
+        mBLAS.DTRMV(uplo, trans, diag, matrixAD, vectorXD, incX);
+        vectorXRef.copyFrom(mBLASData.L2_dTRMV_o_UT);
+        verifyMatrix(vectorXRef, vectorXD);
+
+        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
+        vectorXD.copyFrom(mBLASData.L2_dTRMV_x_n1);
+        mBLAS.DTRMV(uplo, trans, diag, matrixAD, vectorXD, incX);
+        vectorXRef.copyFrom(mBLASData.L2_dTRMV_o_UH);
+        verifyMatrix(vectorXRef, vectorXD);
+
+        // Test for incX = 2;
+        trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        incX = 2;
+        int dimX = 1 + (mBLASData.dN - 1) * incX;
+        vectorXD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimX, 1));
+        vectorXD.copyFrom(mBLASData.L2_dTRMV_x_n2);
+
+        mBLAS.DTRMV(uplo, trans, diag, matrixAD, vectorXD, incX);
+        vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimX, 1));
+        vectorXRef.copyFrom(mBLASData.L2_dTRMV_o_UN2);
+        verifyMatrix(vectorXRef, vectorXD);
+
+        mRS.finish();
+        checkError();
+    }
+
+    public void test_L2_CTRMV_Correctness() {
+        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+        int diag = ScriptIntrinsicBLAS.NON_UNIT;
+        int incX = 1;
+
+        // Populate input allocations
+        Allocation matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dN));
+        Allocation vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, 1));
+        matrixAC.copyFrom(mBLASData.L2_cTRMV_A_nn);
+        vectorXC.copyFrom(mBLASData.L2_cTRMV_x_n1);
+
+        // Test for the default case: NO_TRANS
+        mBLAS.CTRMV(uplo, trans, diag, matrixAC, vectorXC, incX);
+        Allocation vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, 1));
+        vectorXRef.copyFrom(mBLASData.L2_cTRMV_o_UN);
+        verifyMatrix(vectorXRef, vectorXC);
+
+        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
+        trans = ScriptIntrinsicBLAS.TRANSPOSE;
+        // Reload vector X, since it was overwritten by BLAS.
+        vectorXC.copyFrom(mBLASData.L2_cTRMV_x_n1);
+        mBLAS.CTRMV(uplo, trans, diag, matrixAC, vectorXC, incX);
+        vectorXRef.copyFrom(mBLASData.L2_cTRMV_o_UT);
+        verifyMatrix(vectorXRef, vectorXC);
+
+        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
+        vectorXC.copyFrom(mBLASData.L2_cTRMV_x_n1);
+        mBLAS.CTRMV(uplo, trans, diag, matrixAC, vectorXC, incX);
+        vectorXRef.copyFrom(mBLASData.L2_cTRMV_o_UH);
+        verifyMatrix(vectorXRef, vectorXC);
+
+        // Test for incX = 2;
+        trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        incX = 2;
+        int dimX = 1 + (mBLASData.dN - 1) * incX;
+        vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimX, 1));
+        vectorXC.copyFrom(mBLASData.L2_cTRMV_x_n2);
+
+        mBLAS.CTRMV(uplo, trans, diag, matrixAC, vectorXC, incX);
+        vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimX, 1));
+        vectorXRef.copyFrom(mBLASData.L2_cTRMV_o_UN2);
+        verifyMatrix(vectorXRef, vectorXC);
+
+        mRS.finish();
+        checkError();
+    }
+
+    public void test_L2_ZTRMV_Correctness() {
+        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+        int diag = ScriptIntrinsicBLAS.NON_UNIT;
+        int incX = 1;
+
+        // Populate input allocations
+        Allocation matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dN));
+        Allocation vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, 1));
+        matrixAZ.copyFrom(mBLASData.L2_zTRMV_A_nn);
+        vectorXZ.copyFrom(mBLASData.L2_zTRMV_x_n1);
+
+        // Test for the default case: NO_TRANS
+        mBLAS.ZTRMV(uplo, trans, diag, matrixAZ, vectorXZ, incX);
+        Allocation vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, 1));
+        vectorXRef.copyFrom(mBLASData.L2_zTRMV_o_UN);
+        verifyMatrix(vectorXRef, vectorXZ);
+
+        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
+        trans = ScriptIntrinsicBLAS.TRANSPOSE;
+        // Reload vector X, since it was overwritten by BLAS.
+        vectorXZ.copyFrom(mBLASData.L2_zTRMV_x_n1);
+        mBLAS.ZTRMV(uplo, trans, diag, matrixAZ, vectorXZ, incX);
+        vectorXRef.copyFrom(mBLASData.L2_zTRMV_o_UT);
+        verifyMatrix(vectorXRef, vectorXZ);
+
+        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
+        vectorXZ.copyFrom(mBLASData.L2_zTRMV_x_n1);
+        mBLAS.ZTRMV(uplo, trans, diag, matrixAZ, vectorXZ, incX);
+        vectorXRef.copyFrom(mBLASData.L2_zTRMV_o_UH);
+        verifyMatrix(vectorXRef, vectorXZ);
+
+        // Test for incX = 2;
+        trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        incX = 2;
+        int dimX = 1 + (mBLASData.dN - 1) * incX;
+        vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimX, 1));
+        vectorXZ.copyFrom(mBLASData.L2_zTRMV_x_n2);
+
+        mBLAS.ZTRMV(uplo, trans, diag, matrixAZ, vectorXZ, incX);
+        vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimX, 1));
+        vectorXRef.copyFrom(mBLASData.L2_zTRMV_o_UN2);
+        verifyMatrix(vectorXRef, vectorXZ);
+
+        mRS.finish();
+        checkError();
+    }
+
+
+
+    private void xTBMV_API_test(int Uplo, int TransA, int Diag, int K, int incX, ArrayList<Allocation> mMatrix) {
+        for (Allocation matA : mMatrix) {
+            for (Allocation vecX : mMatrix) {
+                Element elemA = matA.getType().getElement();
+                if (validateTRMV(elemA, Uplo, TransA, Diag, matA, vecX, incX) && K >= 0) {
+                    try {
+                        if (elemA.isCompatible(Element.F32(mRS))) {
+                            mBLAS.STBMV(Uplo, TransA, Diag, K, matA, vecX, incX);
+                        } else if (elemA.isCompatible(Element.F64(mRS))) {
+                            mBLAS.DTBMV(Uplo, TransA, Diag, K, matA, vecX, incX);
+                        } else if (elemA.isCompatible(Element.F32_2(mRS))) {
+                            mBLAS.CTBMV(Uplo, TransA, Diag, K, matA, vecX, incX);
+                        } else if (elemA.isCompatible(Element.F64_2(mRS))) {
+                            mBLAS.ZTBMV(Uplo, TransA, Diag, K, matA, vecX, incX);
+                        }
+                    } catch (RSRuntimeException e) {
+                        fail("should NOT throw RSRuntimeException");
+                    }
+                } else {
+                    try {
+                        mBLAS.STBMV(Uplo, TransA, Diag, K, matA, vecX, incX);
+                        fail("should throw RSRuntimeException for STBMV");
+                    } catch (RSRuntimeException e) {
+                    }
+                    try {
+                        mBLAS.DTBMV(Uplo, TransA, Diag, K, matA, vecX, incX);
+                        fail("should throw RSRuntimeException for DTBMV");
+                    } catch (RSRuntimeException e) {
+                    }
+                    try {
+                        mBLAS.CTBMV(Uplo, TransA, Diag, K, matA, vecX, incX);
+                        fail("should throw RSRuntimeException for CTBMV");
+                    } catch (RSRuntimeException e) {
+                    }
+                    try {
+                        mBLAS.ZTBMV(Uplo, TransA, Diag, K, matA, vecX, incX);
+                        fail("should throw RSRuntimeException for ZTBMV");
+                    } catch (RSRuntimeException e) {
+                    }
+                }
+            }
+        }
+    }
+
+    public void L2_xTBMV_API(ArrayList<Allocation> mMatrix) {
+        for (int Uplo : mUplo) {
+            for (int TransA : mTranspose) {
+                for (int Diag : mDiag) {
+                    for (int K : mK) {
+                        for (int incX : mInc) {
+                            xTBMV_API_test(Uplo, TransA, Diag, K, incX, mMatrix);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    public void test_L2_STBMV_API() {
+        L2_xTBMV_API(mMatrixS);
+    }
+
+    public void test_L2_DTBMV_API() {
+        L2_xTBMV_API(mMatrixD);
+    }
+
+    public void test_L2_CTBMV_API() {
+        L2_xTBMV_API(mMatrixC);
+    }
+
+    public void test_L2_ZTBMV_API() {
+        L2_xTBMV_API(mMatrixZ);
+    }
+
+    public void test_L2_STBMV_Correctness() {
+        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+        int diag = ScriptIntrinsicBLAS.NON_UNIT;
+        int incX = 1;
+
+        // Populate input allocations
+        Allocation matrixAS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dN));
+        Allocation vectorXS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, 1));
+        matrixAS.copy2DRangeFrom(0, 0, mBLASData.KL + 1, mBLASData.dN, mBLASData.L2_sTBMV_A_nn);
+        vectorXS.copyFrom(mBLASData.L2_sTBMV_x_n1);
+
+        // Test for the default case: NO_TRANS
+        mBLAS.STBMV(uplo, trans, diag, mBLASData.KL, matrixAS, vectorXS, incX);
+        Allocation vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, 1));
+        vectorXRef.copyFrom(mBLASData.L2_sTBMV_o_UN);
+        verifyMatrix(vectorXRef, vectorXS);
+
+        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
+        trans = ScriptIntrinsicBLAS.TRANSPOSE;
+        // Reload vector X, since it was overwritten by BLAS.
+        vectorXS.copyFrom(mBLASData.L2_sTBMV_x_n1);
+        mBLAS.STBMV(uplo, trans, diag, mBLASData.KL, matrixAS, vectorXS, incX);
+        vectorXRef.copyFrom(mBLASData.L2_sTBMV_o_UT);
+        verifyMatrix(vectorXRef, vectorXS);
+
+        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
+        vectorXS.copyFrom(mBLASData.L2_sTBMV_x_n1);
+        mBLAS.STBMV(uplo, trans, diag, mBLASData.KL, matrixAS, vectorXS, incX);
+        vectorXRef.copyFrom(mBLASData.L2_sTBMV_o_UH);
+        verifyMatrix(vectorXRef, vectorXS);
+
+        // Test for incX = 2;
+        trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        incX = 2;
+        int dimX = 1 + (mBLASData.dN - 1) * incX;
+        vectorXS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimX, 1));
+        vectorXS.copyFrom(mBLASData.L2_sTBMV_x_n2);
+
+        mBLAS.STBMV(uplo, trans, diag, mBLASData.KL, matrixAS, vectorXS, incX);
+        vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimX, 1));
+        vectorXRef.copyFrom(mBLASData.L2_sTBMV_o_UN2);
+        verifyMatrix(vectorXRef, vectorXS);
+
+        mRS.finish();
+        checkError();
+    }
+
+    public void test_L2_DTBMV_Correctness() {
+        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+        int diag = ScriptIntrinsicBLAS.NON_UNIT;
+        int incX = 1;
+
+        // Populate input allocations
+        Allocation matrixAD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dN));
+        Allocation vectorXD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, 1));
+        matrixAD.copy2DRangeFrom(0, 0, mBLASData.KL + 1, mBLASData.dN, mBLASData.L2_dTBMV_A_nn);
+        vectorXD.copyFrom(mBLASData.L2_dTBMV_x_n1);
+
+        // Test for the default case: NO_TRANS
+        mBLAS.DTBMV(uplo, trans, diag, mBLASData.KL, matrixAD, vectorXD, incX);
+        Allocation vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, 1));
+        vectorXRef.copyFrom(mBLASData.L2_dTBMV_o_UN);
+        verifyMatrix(vectorXRef, vectorXD);
+
+        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
+        trans = ScriptIntrinsicBLAS.TRANSPOSE;
+        // Reload vector X, since it was overwritten by BLAS.
+        vectorXD.copyFrom(mBLASData.L2_dTBMV_x_n1);
+        mBLAS.DTBMV(uplo, trans, diag, mBLASData.KL, matrixAD, vectorXD, incX);
+        vectorXRef.copyFrom(mBLASData.L2_dTBMV_o_UT);
+        verifyMatrix(vectorXRef, vectorXD);
+
+        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
+        vectorXD.copyFrom(mBLASData.L2_dTBMV_x_n1);
+        mBLAS.DTBMV(uplo, trans, diag, mBLASData.KL, matrixAD, vectorXD, incX);
+        vectorXRef.copyFrom(mBLASData.L2_dTBMV_o_UH);
+        verifyMatrix(vectorXRef, vectorXD);
+
+        // Test for incX = 2;
+        trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        incX = 2;
+        int dimX = 1 + (mBLASData.dN - 1) * incX;
+        vectorXD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimX, 1));
+        vectorXD.copyFrom(mBLASData.L2_dTBMV_x_n2);
+
+        mBLAS.DTBMV(uplo, trans, diag, mBLASData.KL, matrixAD, vectorXD, incX);
+        vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimX, 1));
+        vectorXRef.copyFrom(mBLASData.L2_dTBMV_o_UN2);
+        verifyMatrix(vectorXRef, vectorXD);
+
+        mRS.finish();
+        checkError();
+    }
+
+    public void test_L2_CTBMV_Correctness() {
+        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+        int diag = ScriptIntrinsicBLAS.NON_UNIT;
+        int incX = 1;
+
+        // Populate input allocations
+        Allocation matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dN));
+        Allocation vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, 1));
+        matrixAC.copy2DRangeFrom(0, 0, mBLASData.KL + 1, mBLASData.dN, mBLASData.L2_cTBMV_A_nn);
+        vectorXC.copyFrom(mBLASData.L2_cTBMV_x_n1);
+
+        // Test for the default case: NO_TRANS
+        mBLAS.CTBMV(uplo, trans, diag, mBLASData.KL, matrixAC, vectorXC, incX);
+        Allocation vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, 1));
+        vectorXRef.copyFrom(mBLASData.L2_cTBMV_o_UN);
+        verifyMatrix(vectorXRef, vectorXC);
+
+        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
+        trans = ScriptIntrinsicBLAS.TRANSPOSE;
+        // Reload vector X, since it was overwritten by BLAS.
+        vectorXC.copyFrom(mBLASData.L2_cTBMV_x_n1);
+        mBLAS.CTBMV(uplo, trans, diag, mBLASData.KL, matrixAC, vectorXC, incX);
+        vectorXRef.copyFrom(mBLASData.L2_cTBMV_o_UT);
+        verifyMatrix(vectorXRef, vectorXC);
+
+        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
+        vectorXC.copyFrom(mBLASData.L2_cTBMV_x_n1);
+        mBLAS.CTBMV(uplo, trans, diag, mBLASData.KL, matrixAC, vectorXC, incX);
+        vectorXRef.copyFrom(mBLASData.L2_cTBMV_o_UH);
+        verifyMatrix(vectorXRef, vectorXC);
+
+        // Test for incX = 2;
+        trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        incX = 2;
+        int dimX = 1 + (mBLASData.dN - 1) * incX;
+        vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimX, 1));
+        vectorXC.copyFrom(mBLASData.L2_cTBMV_x_n2);
+
+        mBLAS.CTBMV(uplo, trans, diag, mBLASData.KL, matrixAC, vectorXC, incX);
+        vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimX, 1));
+        vectorXRef.copyFrom(mBLASData.L2_cTBMV_o_UN2);
+        verifyMatrix(vectorXRef, vectorXC);
+
+        mRS.finish();
+        checkError();
+    }
+
+    public void test_L2_ZTBMV_Correctness() {
+        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+        int diag = ScriptIntrinsicBLAS.NON_UNIT;
+        int incX = 1;
+
+        // Populate input allocations
+        Allocation matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dN));
+        Allocation vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, 1));
+        matrixAZ.copy2DRangeFrom(0, 0, mBLASData.KL + 1, mBLASData.dN, mBLASData.L2_zTBMV_A_nn);
+        vectorXZ.copyFrom(mBLASData.L2_zTBMV_x_n1);
+
+        // Test for the default case: NO_TRANS
+        mBLAS.ZTBMV(uplo, trans, diag, mBLASData.KL, matrixAZ, vectorXZ, incX);
+        Allocation vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, 1));
+        vectorXRef.copyFrom(mBLASData.L2_zTBMV_o_UN);
+        verifyMatrix(vectorXRef, vectorXZ);
+
+        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
+        trans = ScriptIntrinsicBLAS.TRANSPOSE;
+        // Reload vector X, since it was overwritten by BLAS.
+        vectorXZ.copyFrom(mBLASData.L2_zTBMV_x_n1);
+        mBLAS.ZTBMV(uplo, trans, diag, mBLASData.KL, matrixAZ, vectorXZ, incX);
+        vectorXRef.copyFrom(mBLASData.L2_zTBMV_o_UT);
+        verifyMatrix(vectorXRef, vectorXZ);
+
+        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
+        vectorXZ.copyFrom(mBLASData.L2_zTBMV_x_n1);
+        mBLAS.ZTBMV(uplo, trans, diag, mBLASData.KL, matrixAZ, vectorXZ, incX);
+        vectorXRef.copyFrom(mBLASData.L2_zTBMV_o_UH);
+        verifyMatrix(vectorXRef, vectorXZ);
+
+        // Test for incX = 2;
+        trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        incX = 2;
+        int dimX = 1 + (mBLASData.dN - 1) * incX;
+        vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimX, 1));
+        vectorXZ.copyFrom(mBLASData.L2_zTBMV_x_n2);
+
+        mBLAS.ZTBMV(uplo, trans, diag, mBLASData.KL, matrixAZ, vectorXZ, incX);
+        vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimX, 1));
+        vectorXRef.copyFrom(mBLASData.L2_zTBMV_o_UN2);
+        verifyMatrix(vectorXRef, vectorXZ);
+
+        mRS.finish();
+        checkError();
+    }
+
+
+    private boolean validateTPMV(Element e, int Uplo, int TransA, int Diag, Allocation Ap, Allocation X, int incX) {
+        if (!validateUplo(Uplo)) {
+            return false;
+        }
+        if (!validateTranspose(TransA)) {
+            return false;
+        }
+        if (!validateDiag(Diag)) {
+            return false;
+        }
+        if (!Ap.getType().getElement().isCompatible(e) ||
+            !X.getType().getElement().isCompatible(e)) {
+            return false;
+        }
+        if (X.getType().getY() > 1) {
+            return false;
+        }
+
+        if (Ap.getType().getY() > 1) {
+            return false;
+        }
+
+        int N = (int)Math.sqrt((double)Ap.getType().getX() * 2);
+        if (Ap.getType().getX() != ((N * (N+1)) / 2)) {
+            return false;
+        }
+        if (incX <= 0) {
+            return false;
+        }
+        int expectedXDim = 1 + (N - 1) * incX;
+        if (X.getType().getX() != expectedXDim) {
+            return false;
+        }
+
+        return true;
+    }
+
+    private void xTPMV_API_test(int Uplo, int TransA, int Diag, int incX, ArrayList<Allocation> mMatrix) {
+        for (Allocation matA : mMatrix) {
+            for (Allocation vecX : mMatrix) {
+                if (!validateVecInput(vecX)) {
+                    continue;
+                }
+                Element elemA = matA.getType().getElement();
+                if (validateTPMV(elemA, Uplo, TransA, Diag, matA, vecX, incX)) {
+                    try {
+                        if (elemA.isCompatible(Element.F32(mRS))) {
+                            mBLAS.STPMV(Uplo, TransA, Diag, matA, vecX, incX);
+                        } else if (elemA.isCompatible(Element.F64(mRS))) {
+                            mBLAS.DTPMV(Uplo, TransA, Diag, matA, vecX, incX);
+                        } else if (elemA.isCompatible(Element.F32_2(mRS))) {
+                            mBLAS.CTPMV(Uplo, TransA, Diag, matA, vecX, incX);
+                        } else if (elemA.isCompatible(Element.F64_2(mRS))) {
+                            mBLAS.ZTPMV(Uplo, TransA, Diag, matA, vecX, incX);
+                        }
+                    } catch (RSRuntimeException e) {
+                        fail("should NOT throw RSRuntimeException");
+                    }
+                } else {
+                    try {
+                        mBLAS.STPMV(Uplo, TransA, Diag, matA, vecX, incX);
+                        fail("should throw RSRuntimeException for STPMV");
+                    } catch (RSRuntimeException e) {
+                    }
+                    try {
+                        mBLAS.DTPMV(Uplo, TransA, Diag, matA, vecX, incX);
+                        fail("should throw RSRuntimeException for DTPMV");
+                    } catch (RSRuntimeException e) {
+                    }
+                    try {
+                        mBLAS.CTPMV(Uplo, TransA, Diag, matA, vecX, incX);
+                        fail("should throw RSRuntimeException for CTPMV");
+                    } catch (RSRuntimeException e) {
+                    }
+                    try {
+                        mBLAS.ZTPMV(Uplo, TransA, Diag, matA, vecX, incX);
+                        fail("should throw RSRuntimeException for ZTPMV");
+                    } catch (RSRuntimeException e) {
+                    }
+                }
+            }
+        }
+    }
+
+    public void L2_xTPMV_API(ArrayList<Allocation> mMatrix) {
+        for (int Uplo : mUplo) {
+            for (int TransA : mTranspose) {
+                for (int Diag : mDiag) {
+                    for (int incX : mInc) {
+                        xTPMV_API_test(Uplo, TransA, Diag, incX, mMatrix);
+                    }
+                }
+            }
+        }
+    }
+
+    public void test_L2_STPMV_API() {
+        L2_xTPMV_API(mMatrixS);
+    }
+
+    public void test_L2_DTPMV_API() {
+        L2_xTPMV_API(mMatrixD);
+    }
+
+    public void test_L2_CTPMV_API() {
+        L2_xTPMV_API(mMatrixC);
+    }
+
+    public void test_L2_ZTPMV_API() {
+        L2_xTPMV_API(mMatrixZ);
+    }
+
+    public void test_L2_STPMV_Correctness() {
+        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+        int diag = ScriptIntrinsicBLAS.NON_UNIT;
+        int incX = 1;
+
+        // Populate input allocations
+        int N = mBLASData.dN;
+        Allocation matrixAS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), N * (N+1) / 2, 1));
+        Allocation vectorXS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), N, 1));
+        matrixAS.copyFrom(mBLASData.L2_sTRMV_A_nn_pu);
+        vectorXS.copyFrom(mBLASData.L2_sTRMV_x_n1);
+
+        // Test for the default case: NO_TRANS
+        mBLAS.STPMV(uplo, trans, diag, matrixAS, vectorXS, incX);
+        Allocation vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), N, 1));
+        vectorXRef.copyFrom(mBLASData.L2_sTRMV_o_UN);
+        verifyMatrix(vectorXRef, vectorXS);
+
+        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
+        trans = ScriptIntrinsicBLAS.TRANSPOSE;
+        // Reload vector X, since it was overwritten by BLAS.
+        vectorXS.copyFrom(mBLASData.L2_sTRMV_x_n1);
+        mBLAS.STPMV(uplo, trans, diag, matrixAS, vectorXS, incX);
+        vectorXRef.copyFrom(mBLASData.L2_sTRMV_o_UT);
+        verifyMatrix(vectorXRef, vectorXS);
+
+        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
+        vectorXS.copyFrom(mBLASData.L2_sTRMV_x_n1);
+        mBLAS.STPMV(uplo, trans, diag, matrixAS, vectorXS, incX);
+        vectorXRef.copyFrom(mBLASData.L2_sTRMV_o_UH);
+        verifyMatrix(vectorXRef, vectorXS);
+
+        // Test for incX = 2;
+        trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        incX = 2;
+        int dimX = 1 + (N - 1) * incX;
+        vectorXS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimX, 1));
+        vectorXS.copyFrom(mBLASData.L2_sTRMV_x_n2);
+
+        mBLAS.STPMV(uplo, trans, diag, matrixAS, vectorXS, incX);
+        vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimX, 1));
+        vectorXRef.copyFrom(mBLASData.L2_sTRMV_o_UN2);
+        verifyMatrix(vectorXRef, vectorXS);
+
+        mRS.finish();
+        checkError();
+    }
+
+    public void test_L2_DTPMV_Correctness() {
+        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+        int diag = ScriptIntrinsicBLAS.NON_UNIT;
+        int incX = 1;
+
+        // Populate input allocations
+        int N = mBLASData.dN;
+        Allocation matrixAD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), N * (N+1) / 2, 1));
+        Allocation vectorXD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), N, 1));
+        matrixAD.copyFrom(mBLASData.L2_dTRMV_A_nn_pu);
+        vectorXD.copyFrom(mBLASData.L2_dTRMV_x_n1);
+
+        // Test for the default case: NO_TRANS
+        mBLAS.DTPMV(uplo, trans, diag, matrixAD, vectorXD, incX);
+        Allocation vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), N, 1));
+        vectorXRef.copyFrom(mBLASData.L2_dTRMV_o_UN);
+        verifyMatrix(vectorXRef, vectorXD);
+
+        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
+        trans = ScriptIntrinsicBLAS.TRANSPOSE;
+        // Reload vector X, since it was overwritten by BLAS.
+        vectorXD.copyFrom(mBLASData.L2_dTRMV_x_n1);
+        mBLAS.DTPMV(uplo, trans, diag, matrixAD, vectorXD, incX);
+        vectorXRef.copyFrom(mBLASData.L2_dTRMV_o_UT);
+        verifyMatrix(vectorXRef, vectorXD);
+
+        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
+        vectorXD.copyFrom(mBLASData.L2_dTRMV_x_n1);
+        mBLAS.DTPMV(uplo, trans, diag, matrixAD, vectorXD, incX);
+        vectorXRef.copyFrom(mBLASData.L2_dTRMV_o_UH);
+        verifyMatrix(vectorXRef, vectorXD);
+
+        // Test for incX = 2;
+        trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        incX = 2;
+        int dimX = 1 + (N - 1) * incX;
+        vectorXD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimX, 1));
+        vectorXD.copyFrom(mBLASData.L2_dTRMV_x_n2);
+
+        mBLAS.DTPMV(uplo, trans, diag, matrixAD, vectorXD, incX);
+        vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimX, 1));
+        vectorXRef.copyFrom(mBLASData.L2_dTRMV_o_UN2);
+        verifyMatrix(vectorXRef, vectorXD);
+
+        mRS.finish();
+        checkError();
+    }
+
+    public void test_L2_CTPMV_Correctness() {
+        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+        int diag = ScriptIntrinsicBLAS.NON_UNIT;
+        int incX = 1;
+
+        // Populate input allocations
+        int N = mBLASData.dN;
+        Allocation matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), N * (N+1) / 2, 1));
+        Allocation vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), N, 1));
+        matrixAC.copyFrom(mBLASData.L2_cTRMV_A_nn_pu);
+        vectorXC.copyFrom(mBLASData.L2_cTRMV_x_n1);
+
+        // Test for the default case: NO_TRANS
+        mBLAS.CTPMV(uplo, trans, diag, matrixAC, vectorXC, incX);
+        Allocation vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), N, 1));
+        vectorXRef.copyFrom(mBLASData.L2_cTRMV_o_UN);
+        verifyMatrix(vectorXRef, vectorXC);
+
+        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
+        trans = ScriptIntrinsicBLAS.TRANSPOSE;
+        // Reload vector X, since it was overwritten by BLAS.
+        vectorXC.copyFrom(mBLASData.L2_cTRMV_x_n1);
+        mBLAS.CTPMV(uplo, trans, diag, matrixAC, vectorXC, incX);
+        vectorXRef.copyFrom(mBLASData.L2_cTRMV_o_UT);
+        verifyMatrix(vectorXRef, vectorXC);
+
+        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
+        vectorXC.copyFrom(mBLASData.L2_cTRMV_x_n1);
+        mBLAS.CTPMV(uplo, trans, diag, matrixAC, vectorXC, incX);
+        vectorXRef.copyFrom(mBLASData.L2_cTRMV_o_UH);
+        verifyMatrix(vectorXRef, vectorXC);
+
+        // Test for incX = 2;
+        trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        incX = 2;
+        int dimX = 1 + (N - 1) * incX;
+        vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimX, 1));
+        vectorXC.copyFrom(mBLASData.L2_cTRMV_x_n2);
+
+        mBLAS.CTPMV(uplo, trans, diag, matrixAC, vectorXC, incX);
+        vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimX, 1));
+        vectorXRef.copyFrom(mBLASData.L2_cTRMV_o_UN2);
+        verifyMatrix(vectorXRef, vectorXC);
+
+        mRS.finish();
+        checkError();
+    }
+
+    public void test_L2_ZTPMV_Correctness() {
+        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+        int diag = ScriptIntrinsicBLAS.NON_UNIT;
+        int incX = 1;
+
+        // Populate input allocations
+        int N = mBLASData.dN;
+        Allocation matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), N * (N+1) / 2, 1));
+        Allocation vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), N, 1));
+        matrixAZ.copyFrom(mBLASData.L2_zTRMV_A_nn_pu);
+        vectorXZ.copyFrom(mBLASData.L2_zTRMV_x_n1);
+
+        // Test for the default case: NO_TRANS
+        mBLAS.ZTPMV(uplo, trans, diag, matrixAZ, vectorXZ, incX);
+        Allocation vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), N, 1));
+        vectorXRef.copyFrom(mBLASData.L2_zTRMV_o_UN);
+        verifyMatrix(vectorXRef, vectorXZ);
+
+        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
+        trans = ScriptIntrinsicBLAS.TRANSPOSE;
+        // Reload vector X, since it was overwritten by BLAS.
+        vectorXZ.copyFrom(mBLASData.L2_zTRMV_x_n1);
+        mBLAS.ZTPMV(uplo, trans, diag, matrixAZ, vectorXZ, incX);
+        vectorXRef.copyFrom(mBLASData.L2_zTRMV_o_UT);
+        verifyMatrix(vectorXRef, vectorXZ);
+
+        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
+        vectorXZ.copyFrom(mBLASData.L2_zTRMV_x_n1);
+        mBLAS.ZTPMV(uplo, trans, diag, matrixAZ, vectorXZ, incX);
+        vectorXRef.copyFrom(mBLASData.L2_zTRMV_o_UH);
+        verifyMatrix(vectorXRef, vectorXZ);
+
+        // Test for incX = 2;
+        trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        incX = 2;
+        int dimX = 1 + (N - 1) * incX;
+        vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimX, 1));
+        vectorXZ.copyFrom(mBLASData.L2_zTRMV_x_n2);
+
+        mBLAS.ZTPMV(uplo, trans, diag, matrixAZ, vectorXZ, incX);
+        vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimX, 1));
+        vectorXRef.copyFrom(mBLASData.L2_zTRMV_o_UN2);
+        verifyMatrix(vectorXRef, vectorXZ);
+
+        mRS.finish();
+        checkError();
+    }
+
+
+    private void xTRSV_API_test(int Uplo, int TransA, int Diag, int incX, ArrayList<Allocation> mMatrix) {
+        for (Allocation matA : mMatrix) {
+            for (Allocation vecX : mMatrix) {
+                if (!validateVecInput(vecX)) {
+                    continue;
+                }
+                Element elemA = matA.getType().getElement();
+                if (validateTRMV(elemA, Uplo, TransA, Diag, matA, vecX, incX)) {
+                    try {
+                        if (elemA.isCompatible(Element.F32(mRS))) {
+                            mBLAS.STRSV(Uplo, TransA, Diag, matA, vecX, incX);
+                        } else if (elemA.isCompatible(Element.F64(mRS))) {
+                            mBLAS.DTRSV(Uplo, TransA, Diag, matA, vecX, incX);
+                        } else if (elemA.isCompatible(Element.F32_2(mRS))) {
+                            mBLAS.CTRSV(Uplo, TransA, Diag, matA, vecX, incX);
+                        } else if (elemA.isCompatible(Element.F64_2(mRS))) {
+                            mBLAS.ZTRSV(Uplo, TransA, Diag, matA, vecX, incX);
+                        }
+                    } catch (RSRuntimeException e) {
+                        fail("should NOT throw RSRuntimeException");
+                    }
+                } else {
+                    try {
+                        mBLAS.STRSV(Uplo, TransA, Diag, matA, vecX, incX);
+                        fail("should throw RSRuntimeException for STRSV");
+                    } catch (RSRuntimeException e) {
+                    }
+                    try {
+                        mBLAS.DTRSV(Uplo, TransA, Diag, matA, vecX, incX);
+                        fail("should throw RSRuntimeException for DTRSV");
+                    } catch (RSRuntimeException e) {
+                    }
+                    try {
+                        mBLAS.CTRSV(Uplo, TransA, Diag, matA, vecX, incX);
+                        fail("should throw RSRuntimeException for CTRSV");
+                    } catch (RSRuntimeException e) {
+                    }
+                    try {
+                        mBLAS.ZTRSV(Uplo, TransA, Diag, matA, vecX, incX);
+                        fail("should throw RSRuntimeException for ZTRSV");
+                    } catch (RSRuntimeException e) {
+                    }
+                }
+            }
+        }
+    }
+
+    public void L2_xTRSV_API(ArrayList<Allocation> mMatrix) {
+        for (int Uplo : mUplo) {
+            for (int TransA : mTranspose) {
+                for (int Diag : mDiag) {
+                    for (int incX : mInc) {
+                        xTRSV_API_test(Uplo, TransA, Diag, incX, mMatrix);
+                    }
+                }
+            }
+        }
+    }
+
+    public void test_L2_STRSV_API() {
+        L2_xTRSV_API(mMatrixS);
+    }
+
+    public void test_L2_DTRSV_API() {
+        L2_xTRSV_API(mMatrixD);
+    }
+
+    public void test_L2_CTRSV_API() {
+        L2_xTRSV_API(mMatrixC);
+    }
+
+    public void test_L2_ZTRSV_API() {
+        L2_xTRSV_API(mMatrixZ);
+    }
+
+    public void test_L2_STRSV_Correctness() {
+        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+        int diag = ScriptIntrinsicBLAS.NON_UNIT;
+        int incX = 1;
+
+        // Populate input allocations
+        Allocation matrixAS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dN));
+        Allocation vectorXS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, 1));
+        matrixAS.copyFrom(mBLASData.L2_sTRSV_A_nn);
+        vectorXS.copyFrom(mBLASData.L2_sTRSV_x_n1);
+
+        // Test for the default case: NO_TRANS
+        mBLAS.STRSV(uplo, trans, diag, matrixAS, vectorXS, incX);
+        Allocation vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, 1));
+        vectorXRef.copyFrom(mBLASData.L2_sTRSV_o_UN);
+        verifyMatrix(vectorXRef, vectorXS);
+
+        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
+        trans = ScriptIntrinsicBLAS.TRANSPOSE;
+        // Reload vector X, since it was overwritten by BLAS.
+        vectorXS.copyFrom(mBLASData.L2_sTRSV_x_n1);
+        mBLAS.STRSV(uplo, trans, diag, matrixAS, vectorXS, incX);
+        vectorXRef.copyFrom(mBLASData.L2_sTRSV_o_UT);
+        verifyMatrix(vectorXRef, vectorXS);
+
+        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
+        vectorXS.copyFrom(mBLASData.L2_sTRSV_x_n1);
+        mBLAS.STRSV(uplo, trans, diag, matrixAS, vectorXS, incX);
+        vectorXRef.copyFrom(mBLASData.L2_sTRSV_o_UH);
+        verifyMatrix(vectorXRef, vectorXS);
+
+        // Test for incX = 2;
+        trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        incX = 2;
+        int dimX = 1 + (mBLASData.dN - 1) * incX;
+        vectorXS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimX, 1));
+        vectorXS.copyFrom(mBLASData.L2_sTRSV_x_n2);
+
+        mBLAS.STRSV(uplo, trans, diag, matrixAS, vectorXS, incX);
+        vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimX, 1));
+        vectorXRef.copyFrom(mBLASData.L2_sTRSV_o_UN2);
+        verifyMatrix(vectorXRef, vectorXS);
+
+        mRS.finish();
+        checkError();
+    }
+
+    public void test_L2_DTRSV_Correctness() {
+        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+        int diag = ScriptIntrinsicBLAS.NON_UNIT;
+        int incX = 1;
+
+        // Populate input allocations
+        Allocation matrixAD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dN));
+        Allocation vectorXD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, 1));
+        matrixAD.copyFrom(mBLASData.L2_dTRSV_A_nn);
+        vectorXD.copyFrom(mBLASData.L2_dTRSV_x_n1);
+
+        // Test for the default case: NO_TRANS
+        mBLAS.DTRSV(uplo, trans, diag, matrixAD, vectorXD, incX);
+        Allocation vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, 1));
+        vectorXRef.copyFrom(mBLASData.L2_dTRSV_o_UN);
+        verifyMatrix(vectorXRef, vectorXD);
+
+        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
+        trans = ScriptIntrinsicBLAS.TRANSPOSE;
+        // Reload vector X, since it was overwritten by BLAS.
+        vectorXD.copyFrom(mBLASData.L2_dTRSV_x_n1);
+        mBLAS.DTRSV(uplo, trans, diag, matrixAD, vectorXD, incX);
+        vectorXRef.copyFrom(mBLASData.L2_dTRSV_o_UT);
+        verifyMatrix(vectorXRef, vectorXD);
+
+        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
+        vectorXD.copyFrom(mBLASData.L2_dTRSV_x_n1);
+        mBLAS.DTRSV(uplo, trans, diag, matrixAD, vectorXD, incX);
+        vectorXRef.copyFrom(mBLASData.L2_dTRSV_o_UH);
+        verifyMatrix(vectorXRef, vectorXD);
+
+        // Test for incX = 2;
+        trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        incX = 2;
+        int dimX = 1 + (mBLASData.dN - 1) * incX;
+        vectorXD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimX, 1));
+        vectorXD.copyFrom(mBLASData.L2_dTRSV_x_n2);
+
+        mBLAS.DTRSV(uplo, trans, diag, matrixAD, vectorXD, incX);
+        vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimX, 1));
+        vectorXRef.copyFrom(mBLASData.L2_dTRSV_o_UN2);
+        verifyMatrix(vectorXRef, vectorXD);
+
+        mRS.finish();
+        checkError();
+    }
+
+    public void test_L2_CTRSV_Correctness() {
+        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+        int diag = ScriptIntrinsicBLAS.NON_UNIT;
+        int incX = 1;
+
+        // Populate input allocations
+        Allocation matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dN));
+        Allocation vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, 1));
+        matrixAC.copyFrom(mBLASData.L2_cTRSV_A_nn);
+        vectorXC.copyFrom(mBLASData.L2_cTRSV_x_n1);
+
+        // Test for the default case: NO_TRANS
+        mBLAS.CTRSV(uplo, trans, diag, matrixAC, vectorXC, incX);
+        Allocation vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, 1));
+        vectorXRef.copyFrom(mBLASData.L2_cTRSV_o_UN);
+        verifyMatrix(vectorXRef, vectorXC);
+
+        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
+        trans = ScriptIntrinsicBLAS.TRANSPOSE;
+        // Reload vector X, since it was overwritten by BLAS.
+        vectorXC.copyFrom(mBLASData.L2_cTRSV_x_n1);
+        mBLAS.CTRSV(uplo, trans, diag, matrixAC, vectorXC, incX);
+        vectorXRef.copyFrom(mBLASData.L2_cTRSV_o_UT);
+        verifyMatrix(vectorXRef, vectorXC);
+
+        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
+        vectorXC.copyFrom(mBLASData.L2_cTRSV_x_n1);
+        mBLAS.CTRSV(uplo, trans, diag, matrixAC, vectorXC, incX);
+        vectorXRef.copyFrom(mBLASData.L2_cTRSV_o_UH);
+        verifyMatrix(vectorXRef, vectorXC);
+
+        // Test for incX = 2;
+        trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        incX = 2;
+        int dimX = 1 + (mBLASData.dN - 1) * incX;
+        vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimX, 1));
+        vectorXC.copyFrom(mBLASData.L2_cTRSV_x_n2);
+
+        mBLAS.CTRSV(uplo, trans, diag, matrixAC, vectorXC, incX);
+        vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimX, 1));
+        vectorXRef.copyFrom(mBLASData.L2_cTRSV_o_UN2);
+        verifyMatrix(vectorXRef, vectorXC);
+
+        mRS.finish();
+        checkError();
+    }
+
+    public void test_L2_ZTRSV_Correctness() {
+        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+        int diag = ScriptIntrinsicBLAS.NON_UNIT;
+        int incX = 1;
+
+        // Populate input allocations
+        Allocation matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dN));
+        Allocation vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, 1));
+        matrixAZ.copyFrom(mBLASData.L2_zTRSV_A_nn);
+        vectorXZ.copyFrom(mBLASData.L2_zTRSV_x_n1);
+
+        // Test for the default case: NO_TRANS
+        mBLAS.ZTRSV(uplo, trans, diag, matrixAZ, vectorXZ, incX);
+        Allocation vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, 1));
+        vectorXRef.copyFrom(mBLASData.L2_zTRSV_o_UN);
+        verifyMatrix(vectorXRef, vectorXZ);
+
+        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
+        trans = ScriptIntrinsicBLAS.TRANSPOSE;
+        // Reload vector X, since it was overwritten by BLAS.
+        vectorXZ.copyFrom(mBLASData.L2_zTRSV_x_n1);
+        mBLAS.ZTRSV(uplo, trans, diag, matrixAZ, vectorXZ, incX);
+        vectorXRef.copyFrom(mBLASData.L2_zTRSV_o_UT);
+        verifyMatrix(vectorXRef, vectorXZ);
+
+        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
+        vectorXZ.copyFrom(mBLASData.L2_zTRSV_x_n1);
+        mBLAS.ZTRSV(uplo, trans, diag, matrixAZ, vectorXZ, incX);
+        vectorXRef.copyFrom(mBLASData.L2_zTRSV_o_UH);
+        verifyMatrix(vectorXRef, vectorXZ);
+
+        // Test for incX = 2;
+        trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        incX = 2;
+        int dimX = 1 + (mBLASData.dN - 1) * incX;
+        vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimX, 1));
+        vectorXZ.copyFrom(mBLASData.L2_zTRSV_x_n2);
+
+        mBLAS.ZTRSV(uplo, trans, diag, matrixAZ, vectorXZ, incX);
+        vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimX, 1));
+        vectorXRef.copyFrom(mBLASData.L2_zTRSV_o_UN2);
+        verifyMatrix(vectorXRef, vectorXZ);
+
+        mRS.finish();
+        checkError();
+    }
+
+
+    private void xTBSV_API_test(int Uplo, int TransA, int Diag, int K, int incX, ArrayList<Allocation> mMatrix) {
+        for (Allocation matA : mMatrix) {
+            for (Allocation vecX : mMatrix) {
+                if (!validateVecInput(vecX)) {
+                    continue;
+                }
+                Element elemA = matA.getType().getElement();
+                if (validateTRMV(elemA, Uplo, TransA, Diag, matA, vecX, incX) && K >= 0) {
+                    try {
+                        if (elemA.isCompatible(Element.F32(mRS))) {
+                            mBLAS.STBSV(Uplo, TransA, Diag, K, matA, vecX, incX);
+                        } else if (elemA.isCompatible(Element.F64(mRS))) {
+                            mBLAS.DTBSV(Uplo, TransA, Diag, K, matA, vecX, incX);
+                        } else if (elemA.isCompatible(Element.F32_2(mRS))) {
+                            mBLAS.CTBSV(Uplo, TransA, Diag, K, matA, vecX, incX);
+                        } else if (elemA.isCompatible(Element.F64_2(mRS))) {
+                            mBLAS.ZTBSV(Uplo, TransA, Diag, K, matA, vecX, incX);
+                        }
+                    } catch (RSRuntimeException e) {
+                        fail("should NOT throw RSRuntimeException");
+                    }
+                } else {
+                    try {
+                        mBLAS.STBSV(Uplo, TransA, Diag, K, matA, vecX, incX);
+                        fail("should throw RSRuntimeException for STBSV");
+                    } catch (RSRuntimeException e) {
+                    }
+                    try {
+                        mBLAS.DTBSV(Uplo, TransA, Diag, K, matA, vecX, incX);
+                        fail("should throw RSRuntimeException for DTBSV");
+                    } catch (RSRuntimeException e) {
+                    }
+                    try {
+                        mBLAS.CTBSV(Uplo, TransA, Diag, K, matA, vecX, incX);
+                        fail("should throw RSRuntimeException for CTBSV");
+                    } catch (RSRuntimeException e) {
+                    }
+                    try {
+                        mBLAS.ZTBSV(Uplo, TransA, Diag, K, matA, vecX, incX);
+                        fail("should throw RSRuntimeException for ZTBSV");
+                    } catch (RSRuntimeException e) {
+                    }
+                }
+            }
+        }
+    }
+
+    public void L2_xTBSV_API(ArrayList<Allocation> mMatrix) {
+        for (int Uplo : mUplo) {
+            for (int TransA : mTranspose) {
+                for (int Diag : mDiag) {
+                    for (int K : mK) {
+                        for (int incX : mInc) {
+                            xTBSV_API_test(Uplo, TransA, Diag, K, incX, mMatrix);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    public void test_L2_STBSV_API() {
+        L2_xTBSV_API(mMatrixS);
+    }
+
+    public void test_L2_DTBSV_API() {
+        L2_xTBSV_API(mMatrixD);
+    }
+
+    public void test_L2_CTBSV_API() {
+        L2_xTBSV_API(mMatrixC);
+    }
+
+    public void test_L2_ZTBSV_API() {
+        L2_xTBSV_API(mMatrixZ);
+    }
+
+    public void test_L2_STBSV_Correctness() {
+        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+        int diag = ScriptIntrinsicBLAS.NON_UNIT;
+        int incX = 1;
+
+        // Populate input allocations
+        Allocation matrixAS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dN));
+        Allocation vectorXS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, 1));
+        matrixAS.copy2DRangeFrom(0, 0, mBLASData.KL + 1, mBLASData.dN, mBLASData.L2_sTBSV_A_nn);
+        vectorXS.copyFrom(mBLASData.L2_sTBSV_x_n1);
+
+        // Test for the default case: NO_TRANS
+        mBLAS.STBSV(uplo, trans, diag, mBLASData.KL, matrixAS, vectorXS, incX);
+        Allocation vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, 1));
+        vectorXRef.copyFrom(mBLASData.L2_sTBSV_o_UN);
+        verifyMatrix(vectorXRef, vectorXS);
+
+        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
+        trans = ScriptIntrinsicBLAS.TRANSPOSE;
+        // Reload vector X, since it was overwritten by BLAS.
+        vectorXS.copyFrom(mBLASData.L2_sTBSV_x_n1);
+        mBLAS.STBSV(uplo, trans, diag, mBLASData.KL, matrixAS, vectorXS, incX);
+        vectorXRef.copyFrom(mBLASData.L2_sTBSV_o_UT);
+        verifyMatrix(vectorXRef, vectorXS);
+
+        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
+        vectorXS.copyFrom(mBLASData.L2_sTBSV_x_n1);
+        mBLAS.STBSV(uplo, trans, diag, mBLASData.KL, matrixAS, vectorXS, incX);
+        vectorXRef.copyFrom(mBLASData.L2_sTBSV_o_UH);
+        verifyMatrix(vectorXRef, vectorXS);
+
+        // Test for incX = 2;
+        trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        incX = 2;
+        int dimX = 1 + (mBLASData.dN - 1) * incX;
+        vectorXS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimX, 1));
+        vectorXS.copyFrom(mBLASData.L2_sTBSV_x_n2);
+
+        mBLAS.STBSV(uplo, trans, diag, mBLASData.KL, matrixAS, vectorXS, incX);
+        vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimX, 1));
+        vectorXRef.copyFrom(mBLASData.L2_sTBSV_o_UN2);
+        verifyMatrix(vectorXRef, vectorXS);
+
+        mRS.finish();
+        checkError();
+    }
+
+    public void test_L2_DTBSV_Correctness() {
+        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+        int diag = ScriptIntrinsicBLAS.NON_UNIT;
+        int incX = 1;
+
+        // Populate input allocations
+        Allocation matrixAD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dN));
+        Allocation vectorXD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, 1));
+        matrixAD.copy2DRangeFrom(0, 0, mBLASData.KL + 1, mBLASData.dN, mBLASData.L2_dTBSV_A_nn);
+        vectorXD.copyFrom(mBLASData.L2_dTBSV_x_n1);
+
+        // Test for the default case: NO_TRANS
+        mBLAS.DTBSV(uplo, trans, diag, mBLASData.KL, matrixAD, vectorXD, incX);
+        Allocation vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, 1));
+        vectorXRef.copyFrom(mBLASData.L2_dTBSV_o_UN);
+        verifyMatrix(vectorXRef, vectorXD);
+
+        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
+        trans = ScriptIntrinsicBLAS.TRANSPOSE;
+        // Reload vector X, since it was overwritten by BLAS.
+        vectorXD.copyFrom(mBLASData.L2_dTBSV_x_n1);
+        mBLAS.DTBSV(uplo, trans, diag, mBLASData.KL, matrixAD, vectorXD, incX);
+        vectorXRef.copyFrom(mBLASData.L2_dTBSV_o_UT);
+        verifyMatrix(vectorXRef, vectorXD);
+
+        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
+        vectorXD.copyFrom(mBLASData.L2_dTBSV_x_n1);
+        mBLAS.DTBSV(uplo, trans, diag, mBLASData.KL, matrixAD, vectorXD, incX);
+        vectorXRef.copyFrom(mBLASData.L2_dTBSV_o_UH);
+        verifyMatrix(vectorXRef, vectorXD);
+
+        // Test for incX = 2;
+        trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        incX = 2;
+        int dimX = 1 + (mBLASData.dN - 1) * incX;
+        vectorXD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimX, 1));
+        vectorXD.copyFrom(mBLASData.L2_dTBSV_x_n2);
+
+        mBLAS.DTBSV(uplo, trans, diag, mBLASData.KL, matrixAD, vectorXD, incX);
+        vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimX, 1));
+        vectorXRef.copyFrom(mBLASData.L2_dTBSV_o_UN2);
+        verifyMatrix(vectorXRef, vectorXD);
+
+        mRS.finish();
+        checkError();
+    }
+
+    public void test_L2_CTBSV_Correctness() {
+        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+        int diag = ScriptIntrinsicBLAS.NON_UNIT;
+        int incX = 1;
+
+        // Populate input allocations
+        Allocation matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dN));
+        Allocation vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, 1));
+        matrixAC.copy2DRangeFrom(0, 0, mBLASData.KL + 1, mBLASData.dN, mBLASData.L2_cTBSV_A_nn);
+        vectorXC.copyFrom(mBLASData.L2_cTBSV_x_n1);
+
+        // Test for the default case: NO_TRANS
+        mBLAS.CTBSV(uplo, trans, diag, mBLASData.KL, matrixAC, vectorXC, incX);
+        Allocation vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, 1));
+        vectorXRef.copyFrom(mBLASData.L2_cTBSV_o_UN);
+        verifyMatrix(vectorXRef, vectorXC);
+
+        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
+        trans = ScriptIntrinsicBLAS.TRANSPOSE;
+        // Reload vector X, since it was overwritten by BLAS.
+        vectorXC.copyFrom(mBLASData.L2_cTBSV_x_n1);
+        mBLAS.CTBSV(uplo, trans, diag, mBLASData.KL, matrixAC, vectorXC, incX);
+        vectorXRef.copyFrom(mBLASData.L2_cTBSV_o_UT);
+        verifyMatrix(vectorXRef, vectorXC);
+
+        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
+        vectorXC.copyFrom(mBLASData.L2_cTBSV_x_n1);
+        mBLAS.CTBSV(uplo, trans, diag, mBLASData.KL, matrixAC, vectorXC, incX);
+        vectorXRef.copyFrom(mBLASData.L2_cTBSV_o_UH);
+        verifyMatrix(vectorXRef, vectorXC);
+
+        // Test for incX = 2;
+        trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        incX = 2;
+        int dimX = 1 + (mBLASData.dN - 1) * incX;
+        vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimX, 1));
+        vectorXC.copyFrom(mBLASData.L2_cTBSV_x_n2);
+
+        mBLAS.CTBSV(uplo, trans, diag, mBLASData.KL, matrixAC, vectorXC, incX);
+        vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimX, 1));
+        vectorXRef.copyFrom(mBLASData.L2_cTBSV_o_UN2);
+        verifyMatrix(vectorXRef, vectorXC);
+
+        mRS.finish();
+        checkError();
+    }
+
+    public void test_L2_ZTBSV_Correctness() {
+        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+        int diag = ScriptIntrinsicBLAS.NON_UNIT;
+        int incX = 1;
+
+        // Populate input allocations
+        Allocation matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dN));
+        Allocation vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, 1));
+        matrixAZ.copy2DRangeFrom(0, 0, mBLASData.KL + 1, mBLASData.dN, mBLASData.L2_zTBSV_A_nn);
+        vectorXZ.copyFrom(mBLASData.L2_zTBSV_x_n1);
+
+        // Test for the default case: NO_TRANS
+        mBLAS.ZTBSV(uplo, trans, diag, mBLASData.KL, matrixAZ, vectorXZ, incX);
+        Allocation vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, 1));
+        vectorXRef.copyFrom(mBLASData.L2_zTBSV_o_UN);
+        verifyMatrix(vectorXRef, vectorXZ);
+
+        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
+        trans = ScriptIntrinsicBLAS.TRANSPOSE;
+        // Reload vector X, since it was overwritten by BLAS.
+        vectorXZ.copyFrom(mBLASData.L2_zTBSV_x_n1);
+        mBLAS.ZTBSV(uplo, trans, diag, mBLASData.KL, matrixAZ, vectorXZ, incX);
+        vectorXRef.copyFrom(mBLASData.L2_zTBSV_o_UT);
+        verifyMatrix(vectorXRef, vectorXZ);
+
+        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
+        vectorXZ.copyFrom(mBLASData.L2_zTBSV_x_n1);
+        mBLAS.ZTBSV(uplo, trans, diag, mBLASData.KL, matrixAZ, vectorXZ, incX);
+        vectorXRef.copyFrom(mBLASData.L2_zTBSV_o_UH);
+        verifyMatrix(vectorXRef, vectorXZ);
+
+        // Test for incX = 2;
+        trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        incX = 2;
+        int dimX = 1 + (mBLASData.dN - 1) * incX;
+        vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimX, 1));
+        vectorXZ.copyFrom(mBLASData.L2_zTBSV_x_n2);
+
+        mBLAS.ZTBSV(uplo, trans, diag, mBLASData.KL, matrixAZ, vectorXZ, incX);
+        vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimX, 1));
+        vectorXRef.copyFrom(mBLASData.L2_zTBSV_o_UN2);
+        verifyMatrix(vectorXRef, vectorXZ);
+
+        mRS.finish();
+        checkError();
+    }
+
+
+    private void xTPSV_API_test(int Uplo, int TransA, int Diag, int incX, ArrayList<Allocation> mMatrix) {
+        for (Allocation matA : mMatrix) {
+            for (Allocation vecX : mMatrix) {
+                if (!validateVecInput(vecX)) {
+                    continue;
+                }
+                Element elemA = matA.getType().getElement();
+                if (validateTPMV(elemA, Uplo, TransA, Diag, matA, vecX, incX)) {
+                    try {
+                        if (elemA.isCompatible(Element.F32(mRS))) {
+                            mBLAS.STPSV(Uplo, TransA, Diag, matA, vecX, incX);
+                        } else if (elemA.isCompatible(Element.F64(mRS))) {
+                            mBLAS.DTPSV(Uplo, TransA, Diag, matA, vecX, incX);
+                        } else if (elemA.isCompatible(Element.F32_2(mRS))) {
+                            mBLAS.CTPSV(Uplo, TransA, Diag, matA, vecX, incX);
+                        } else if (elemA.isCompatible(Element.F64_2(mRS))) {
+                            mBLAS.ZTPSV(Uplo, TransA, Diag, matA, vecX, incX);
+                        }
+                    } catch (RSRuntimeException e) {
+                        fail("should NOT throw RSRuntimeException");
+                    }
+                } else {
+                    try {
+                        mBLAS.STPSV(Uplo, TransA, Diag, matA, vecX, incX);
+                        fail("should throw RSRuntimeException for STPSV");
+                    } catch (RSRuntimeException e) {
+                    }
+                    try {
+                        mBLAS.DTPSV(Uplo, TransA, Diag, matA, vecX, incX);
+                        fail("should throw RSRuntimeException for DTPSV");
+                    } catch (RSRuntimeException e) {
+                    }
+                    try {
+                        mBLAS.CTPSV(Uplo, TransA, Diag, matA, vecX, incX);
+                        fail("should throw RSRuntimeException for CTPSV");
+                    } catch (RSRuntimeException e) {
+                    }
+                    try {
+                        mBLAS.ZTPSV(Uplo, TransA, Diag, matA, vecX, incX);
+                        fail("should throw RSRuntimeException for ZTPSV");
+                    } catch (RSRuntimeException e) {
+                    }
+                }
+            }
+        }
+    }
+
+    public void L2_xTPSV_API(ArrayList<Allocation> mMatrix) {
+        for (int Uplo : mUplo) {
+            for (int TransA : mTranspose) {
+                for (int Diag : mDiag) {
+                    for (int incX : mInc) {
+                        xTPSV_API_test(Uplo, TransA, Diag, incX, mMatrix);
+                    }
+                }
+            }
+        }
+    }
+
+    public void test_L2_STPSV_API() {
+        L2_xTPSV_API(mMatrixS);
+    }
+
+    public void test_L2_DTPSV_API() {
+        L2_xTPSV_API(mMatrixD);
+    }
+
+    public void test_L2_CTPSV_API() {
+        L2_xTPSV_API(mMatrixC);
+    }
+
+    public void test_L2_ZTPSV_API() {
+        L2_xTPSV_API(mMatrixZ);
+    }
+
+    public void test_L2_STPSV_Correctness() {
+        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+        int diag = ScriptIntrinsicBLAS.NON_UNIT;
+        int incX = 1;
+
+        // Populate input allocations
+        int N = mBLASData.dN;
+        Allocation matrixAS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), N * (N+1) / 2, 1));
+        Allocation vectorXS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), N, 1));
+        matrixAS.copyFrom(mBLASData.L2_sTRSV_A_nn_pu);
+        vectorXS.copyFrom(mBLASData.L2_sTRSV_x_n1);
+
+        // Test for the default case: NO_TRANS
+        mBLAS.STPSV(uplo, trans, diag, matrixAS, vectorXS, incX);
+        Allocation vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), N, 1));
+        vectorXRef.copyFrom(mBLASData.L2_sTRSV_o_UN);
+        verifyMatrix(vectorXRef, vectorXS);
+
+        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
+        trans = ScriptIntrinsicBLAS.TRANSPOSE;
+        // Reload vector X, since it was overwritten by BLAS.
+        vectorXS.copyFrom(mBLASData.L2_sTRSV_x_n1);
+        mBLAS.STPSV(uplo, trans, diag, matrixAS, vectorXS, incX);
+        vectorXRef.copyFrom(mBLASData.L2_sTRSV_o_UT);
+        verifyMatrix(vectorXRef, vectorXS);
+
+        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
+        vectorXS.copyFrom(mBLASData.L2_sTRSV_x_n1);
+        mBLAS.STPSV(uplo, trans, diag, matrixAS, vectorXS, incX);
+        vectorXRef.copyFrom(mBLASData.L2_sTRSV_o_UH);
+        verifyMatrix(vectorXRef, vectorXS);
+
+        // Test for incX = 2;
+        trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        incX = 2;
+        int dimX = 1 + (N - 1) * incX;
+        vectorXS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimX, 1));
+        vectorXS.copyFrom(mBLASData.L2_sTRSV_x_n2);
+
+        mBLAS.STPSV(uplo, trans, diag, matrixAS, vectorXS, incX);
+        vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimX, 1));
+        vectorXRef.copyFrom(mBLASData.L2_sTRSV_o_UN2);
+        verifyMatrix(vectorXRef, vectorXS);
+
+        mRS.finish();
+        checkError();
+    }
+
+    public void test_L2_DTPSV_Correctness() {
+        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+        int diag = ScriptIntrinsicBLAS.NON_UNIT;
+        int incX = 1;
+
+        // Populate input allocations
+        int N = mBLASData.dN;
+        Allocation matrixAD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), N * (N+1) / 2, 1));
+        Allocation vectorXD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), N, 1));
+        matrixAD.copyFrom(mBLASData.L2_dTRSV_A_nn_pu);
+        vectorXD.copyFrom(mBLASData.L2_dTRSV_x_n1);
+
+        // Test for the default case: NO_TRANS
+        mBLAS.DTPSV(uplo, trans, diag, matrixAD, vectorXD, incX);
+        Allocation vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), N, 1));
+        vectorXRef.copyFrom(mBLASData.L2_dTRSV_o_UN);
+        verifyMatrix(vectorXRef, vectorXD);
+
+        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
+        trans = ScriptIntrinsicBLAS.TRANSPOSE;
+        // Reload vector X, since it was overwritten by BLAS.
+        vectorXD.copyFrom(mBLASData.L2_dTRSV_x_n1);
+        mBLAS.DTPSV(uplo, trans, diag, matrixAD, vectorXD, incX);
+        vectorXRef.copyFrom(mBLASData.L2_dTRSV_o_UT);
+        verifyMatrix(vectorXRef, vectorXD);
+
+        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
+        vectorXD.copyFrom(mBLASData.L2_dTRSV_x_n1);
+        mBLAS.DTPSV(uplo, trans, diag, matrixAD, vectorXD, incX);
+        vectorXRef.copyFrom(mBLASData.L2_dTRSV_o_UH);
+        verifyMatrix(vectorXRef, vectorXD);
+
+        // Test for incX = 2;
+        trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        incX = 2;
+        int dimX = 1 + (N - 1) * incX;
+        vectorXD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimX, 1));
+        vectorXD.copyFrom(mBLASData.L2_dTRSV_x_n2);
+
+        mBLAS.DTPSV(uplo, trans, diag, matrixAD, vectorXD, incX);
+        vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimX, 1));
+        vectorXRef.copyFrom(mBLASData.L2_dTRSV_o_UN2);
+        verifyMatrix(vectorXRef, vectorXD);
+
+        mRS.finish();
+        checkError();
+    }
+
+    public void test_L2_CTPSV_Correctness() {
+        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+        int diag = ScriptIntrinsicBLAS.NON_UNIT;
+        int incX = 1;
+
+        // Populate input allocations
+        int N = mBLASData.dN;
+        Allocation matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), N * (N+1) / 2, 1));
+        Allocation vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), N, 1));
+        matrixAC.copyFrom(mBLASData.L2_cTRSV_A_nn_pu);
+        vectorXC.copyFrom(mBLASData.L2_cTRSV_x_n1);
+
+        // Test for the default case: NO_TRANS
+        mBLAS.CTPSV(uplo, trans, diag, matrixAC, vectorXC, incX);
+        Allocation vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), N, 1));
+        vectorXRef.copyFrom(mBLASData.L2_cTRSV_o_UN);
+        verifyMatrix(vectorXRef, vectorXC);
+
+        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
+        trans = ScriptIntrinsicBLAS.TRANSPOSE;
+        // Reload vector X, since it was overwritten by BLAS.
+        vectorXC.copyFrom(mBLASData.L2_cTRSV_x_n1);
+        mBLAS.CTPSV(uplo, trans, diag, matrixAC, vectorXC, incX);
+        vectorXRef.copyFrom(mBLASData.L2_cTRSV_o_UT);
+        verifyMatrix(vectorXRef, vectorXC);
+
+        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
+        vectorXC.copyFrom(mBLASData.L2_cTRSV_x_n1);
+        mBLAS.CTPSV(uplo, trans, diag, matrixAC, vectorXC, incX);
+        vectorXRef.copyFrom(mBLASData.L2_cTRSV_o_UH);
+        verifyMatrix(vectorXRef, vectorXC);
+
+        // Test for incX = 2;
+        trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        incX = 2;
+        int dimX = 1 + (N - 1) * incX;
+        vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimX, 1));
+        vectorXC.copyFrom(mBLASData.L2_cTRSV_x_n2);
+
+        mBLAS.CTPSV(uplo, trans, diag, matrixAC, vectorXC, incX);
+        vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimX, 1));
+        vectorXRef.copyFrom(mBLASData.L2_cTRSV_o_UN2);
+        verifyMatrix(vectorXRef, vectorXC);
+
+        mRS.finish();
+        checkError();
+    }
+
+    public void test_L2_ZTPSV_Correctness() {
+        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+        int diag = ScriptIntrinsicBLAS.NON_UNIT;
+        int incX = 1;
+
+        // Populate input allocations
+        int N = mBLASData.dN;
+        Allocation matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), N * (N+1) / 2, 1));
+        Allocation vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), N, 1));
+        matrixAZ.copyFrom(mBLASData.L2_zTRSV_A_nn_pu);
+        vectorXZ.copyFrom(mBLASData.L2_zTRSV_x_n1);
+
+        // Test for the default case: NO_TRANS
+        mBLAS.ZTPSV(uplo, trans, diag, matrixAZ, vectorXZ, incX);
+        Allocation vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), N, 1));
+        vectorXRef.copyFrom(mBLASData.L2_zTRSV_o_UN);
+        verifyMatrix(vectorXRef, vectorXZ);
+
+        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
+        trans = ScriptIntrinsicBLAS.TRANSPOSE;
+        // Reload vector X, since it was overwritten by BLAS.
+        vectorXZ.copyFrom(mBLASData.L2_zTRSV_x_n1);
+        mBLAS.ZTPSV(uplo, trans, diag, matrixAZ, vectorXZ, incX);
+        vectorXRef.copyFrom(mBLASData.L2_zTRSV_o_UT);
+        verifyMatrix(vectorXRef, vectorXZ);
+
+        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
+        vectorXZ.copyFrom(mBLASData.L2_zTRSV_x_n1);
+        mBLAS.ZTPSV(uplo, trans, diag, matrixAZ, vectorXZ, incX);
+        vectorXRef.copyFrom(mBLASData.L2_zTRSV_o_UH);
+        verifyMatrix(vectorXRef, vectorXZ);
+
+        // Test for incX = 2;
+        trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        incX = 2;
+        int dimX = 1 + (N - 1) * incX;
+        vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimX, 1));
+        vectorXZ.copyFrom(mBLASData.L2_zTRSV_x_n2);
+
+        mBLAS.ZTPSV(uplo, trans, diag, matrixAZ, vectorXZ, incX);
+        vectorXRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimX, 1));
+        vectorXRef.copyFrom(mBLASData.L2_zTRSV_o_UN2);
+        verifyMatrix(vectorXRef, vectorXZ);
+
+        mRS.finish();
+        checkError();
+    }
+
+
+    private boolean validateGER(Element e, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
+        if (!A.getType().getElement().isCompatible(e) ||
+            !X.getType().getElement().isCompatible(e) ||
+            !Y.getType().getElement().isCompatible(e) ) {
+            return false;
+        }
+
+        if (X.getType().getY() > 1 || Y.getType().getY() > 1) {
+            return false;
+        }
+
+        int M = A.getType().getY();
+        int N = A.getType().getX();
+
+        if (N < 1 || M < 1) {
+            return false;
+        }
+        if (incX <= 0 || incY <= 0) {
+            return false;
+        }
+        int expectedXDim = 1 + (M - 1) * incX;
+        if (X.getType().getX() != expectedXDim) {
+            return false;
+        }
+        int expectedYDim = 1 + (N - 1) * incY;
+        if (Y.getType().getX() != expectedYDim) {
+            return false;
+        }
+        return true;
+    }
+
+
+    private void xGER_API_test(int incX, int incY, ArrayList<Allocation> mMatrix) {
+        for (Allocation matA : mMatrix) {
+            for (Allocation vecX : mMatrix) {
+                if (!validateVecInput(vecX)) {
+                    continue;
+                }
+                for (Allocation vecY : mMatrix) {
+                    if (!validateVecInput(vecY)) {
+                        continue;
+                    }
+                    Element elemA = matA.getType().getElement();
+                    if (validateGER(elemA, vecX, incX, vecY, incY, matA)) {
+                        try {
+                            if (elemA.isCompatible(Element.F32(mRS))) {
+                                mBLAS.SGER(alphaS, vecX, incX, vecY, incY, matA);
+                            } else if (elemA.isCompatible(Element.F64(mRS))) {
+                                mBLAS.DGER(alphaD, vecX, incX, vecY, incY, matA);
+                            }
+                        } catch (RSRuntimeException e) {
+                            fail("should NOT throw RSRuntimeException");
+                        }
+                    } else {
+                        try {
+                            mBLAS.SGER(alphaS, vecX, incX, vecY, incY, matA);
+                            fail("should throw RSRuntimeException for SGER");
+                        } catch (RSRuntimeException e) {
+                        }
+                        try {
+                            mBLAS.DGER(alphaD, vecX, incX, vecY, incY, matA);
+                            fail("should throw RSRuntimeException for DGER");
+                        } catch (RSRuntimeException e) {
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    private void L2_xGER_API(ArrayList<Allocation> mMatrix) {
+        for (int incX : mInc) {
+            for (int incY : mInc) {
+                xGERU_API_test(incX, incY, mMatrix);
+            }
+        }
+    }
+
+    public void test_L2_SGER_API() {
+        L2_xGER_API(mMatrixS);
+    }
+
+    public void test_L2_DGER_API() {
+        L2_xGER_API(mMatrixD);
+    }
+
+    public void test_L2_SGER_Correctness() {
+        int incX = 1;
+        int incY = 1;
+
+        // Populate input allocations
+        Allocation matrixAS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dM));
+        Allocation vectorXS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dM, 1));
+        Allocation vectorYS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, 1));
+        matrixAS.copyFrom(mBLASData.L2_sGER_A_mn);
+        vectorXS.copyFrom(mBLASData.L2_sGER_x_m1);
+        vectorYS.copyFrom(mBLASData.L2_sGER_y_n1);
+
+        // Test for the default case: NO_TRANS
+        mBLAS.SGER(alphaS, vectorXS, incX, vectorYS, incY, matrixAS);
+        Allocation matrixARef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dM));
+        matrixARef.copyFrom(mBLASData.L2_sGER_o_N);
+        verifyMatrix(matrixARef, matrixAS);
+
+        // Test for incX = 2 & incY = 3;
+        incX = 2;
+        incY = 3;
+        int dimX = 1 + (mBLASData.dM - 1) * incX;
+        int dimY = 1 + (mBLASData.dN - 1) * incY;
+        vectorXS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimX, 1));
+        vectorYS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimY, 1));
+        vectorXS.copyFrom(mBLASData.L2_sGER_x_m2);
+        vectorYS.copyFrom(mBLASData.L2_sGER_y_n2);
+        matrixAS.copyFrom(mBLASData.L2_sGER_A_mn);
+
+        mBLAS.SGER(alphaS, vectorXS, incX, vectorYS, incY, matrixAS);
+        verifyMatrix(matrixARef, matrixAS);
+
+        mRS.finish();
+        checkError();
+    }
+
+    public void test_L2_DGER_Correctness() {
+        int incX = 1;
+        int incY = 1;
+
+        // Populate input allocations
+        Allocation matrixAD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dM));
+        Allocation vectorXD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dM, 1));
+        Allocation vectorYD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, 1));
+        matrixAD.copyFrom(mBLASData.L2_dGER_A_mn);
+        vectorXD.copyFrom(mBLASData.L2_dGER_x_m1);
+        vectorYD.copyFrom(mBLASData.L2_dGER_y_n1);
+
+        // Test for the default case: NO_TRANS
+        mBLAS.DGER(alphaD, vectorXD, incX, vectorYD, incY, matrixAD);
+        Allocation matrixARef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dM));
+        matrixARef.copyFrom(mBLASData.L2_dGER_o_N);
+        verifyMatrix(matrixARef, matrixAD);
+
+        // Test for incX = 2 & incY = 3;
+        incX = 2;
+        incY = 3;
+        int dimX = 1 + (mBLASData.dM - 1) * incX;
+        int dimY = 1 + (mBLASData.dN - 1) * incY;
+        vectorXD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimX, 1));
+        vectorYD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimY, 1));
+        vectorXD.copyFrom(mBLASData.L2_dGER_x_m2);
+        vectorYD.copyFrom(mBLASData.L2_dGER_y_n2);
+        matrixAD.copyFrom(mBLASData.L2_dGER_A_mn);
+
+        mBLAS.DGER(alphaD, vectorXD, incX, vectorYD, incY, matrixAD);
+        verifyMatrix(matrixARef, matrixAD);
+
+        mRS.finish();
+        checkError();
+    }
+
+
+    private boolean validateGERU(Element e, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
+        if (!A.getType().getElement().isCompatible(e) ||
+            !X.getType().getElement().isCompatible(e) ||
+            !Y.getType().getElement().isCompatible(e)) {
+            return false;
+        }
+        if (X.getType().getY() > 1 || Y.getType().getY() > 1) {
+            return false;
+        }
+
+        int M = A.getType().getY();
+        int N = A.getType().getX();
+        if (incX <= 0 || incY <= 0) {
+            return false;
+        }
+        int expectedXDim = 1 + (M - 1) * incX;
+        if (X.getType().getX() != expectedXDim) {
+            return false;
+        }
+        int expectedYDim = 1 + (N - 1) * incY;
+        if (Y.getType().getX() != expectedYDim) {
+            return false;
+        }
+        return true;
+    }
+
+    private void xGERU_API_test(int incX, int incY, ArrayList<Allocation> mMatrix) {
+        for (Allocation matA : mMatrix) {
+            for (Allocation vecX : mMatrix) {
+                if (!validateVecInput(vecX)) {
+                    continue;
+                }
+                for (Allocation vecY : mMatrix) {
+                    if (!validateVecInput(vecY)) {
+                        continue;
+                    }
+                    Element elemA = matA.getType().getElement();
+                    if (validateGERU(elemA, vecX, incX, vecY, incY, matA)) {
+                        try {
+                            if (elemA.isCompatible(Element.F32_2(mRS))) {
+                                mBLAS.CGERU(alphaC, vecX, incX, vecY, incY, matA);
+                            } else if (elemA.isCompatible(Element.F64_2(mRS))) {
+                                mBLAS.ZGERU(alphaZ, vecX, incX, vecY, incY, matA);
+                            }
+                        } catch (RSRuntimeException e) {
+                            fail("should NOT throw RSRuntimeException");
+                        }
+                    } else {
+                        try {
+                            mBLAS.CGERU(alphaC, vecX, incX, vecY, incY, matA);
+                            fail("should throw RSRuntimeException for CGERU");
+                        } catch (RSRuntimeException e) {
+                        }
+                        try {
+                            mBLAS.ZGERU(alphaZ, vecX, incX, vecY, incY, matA);
+                            fail("should throw RSRuntimeException for ZGERU");
+                        } catch (RSRuntimeException e) {
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    private void L2_xGERU_API(ArrayList<Allocation> mMatrix) {
+        for (int incX : mInc) {
+            for (int incY : mInc) {
+                xGERU_API_test(incX, incY, mMatrix);
+            }
+        }
+    }
+
+    public void test_L2_CGERU_API() {
+        L2_xGERU_API(mMatrixC);
+    }
+
+    public void test_L2_ZGERU_API() {
+        L2_xGERU_API(mMatrixZ);
+    }
+
+    public void test_L2_CGERU_Correctness() {
+        int incX = 1;
+        int incY = 1;
+
+        // Populate input allocations
+        Allocation matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dM));
+        Allocation vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dM, 1));
+        Allocation vectorYC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, 1));
+        matrixAC.copyFrom(mBLASData.L2_cGERU_A_mn);
+        vectorXC.copyFrom(mBLASData.L2_cGERU_x_m1);
+        vectorYC.copyFrom(mBLASData.L2_cGERU_y_n1);
+
+        // Test for the default case: NO_TRANS
+        mBLAS.CGERU(alphaC, vectorXC, incX, vectorYC, incY, matrixAC);
+        Allocation matrixARef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dM));
+        matrixARef.copyFrom(mBLASData.L2_cGERU_o_N);
+        verifyMatrix(matrixARef, matrixAC);
+
+        // Test for incX = 2 & incY = 3;
+        incX = 2;
+        incY = 3;
+        int dimX = 1 + (mBLASData.dM - 1) * incX;
+        int dimY = 1 + (mBLASData.dN - 1) * incY;
+        vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimX, 1));
+        vectorYC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimY, 1));
+        vectorXC.copyFrom(mBLASData.L2_cGERU_x_m2);
+        vectorYC.copyFrom(mBLASData.L2_cGERU_y_n2);
+        matrixAC.copyFrom(mBLASData.L2_cGERU_A_mn);
+
+        mBLAS.CGERU(alphaC, vectorXC, incX, vectorYC, incY, matrixAC);
+        verifyMatrix(matrixARef, matrixAC);
+
+        mRS.finish();
+        checkError();
+    }
+
+    public void test_L2_ZGERU_Correctness() {
+        int incX = 1;
+        int incY = 1;
+
+        // Populate input allocations
+        Allocation matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dM));
+        Allocation vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dM, 1));
+        Allocation vectorYZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, 1));
+        matrixAZ.copyFrom(mBLASData.L2_zGERU_A_mn);
+        vectorXZ.copyFrom(mBLASData.L2_zGERU_x_m1);
+        vectorYZ.copyFrom(mBLASData.L2_zGERU_y_n1);
+
+        // Test for the default case: NO_TRANS
+        mBLAS.ZGERU(alphaZ, vectorXZ, incX, vectorYZ, incY, matrixAZ);
+        Allocation matrixARef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dM));
+        matrixARef.copyFrom(mBLASData.L2_zGERU_o_N);
+        verifyMatrix(matrixARef, matrixAZ);
+
+        // Test for incX = 2 & incY = 3;
+        incX = 2;
+        incY = 3;
+        int dimX = 1 + (mBLASData.dM - 1) * incX;
+        int dimY = 1 + (mBLASData.dN - 1) * incY;
+        vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimX, 1));
+        vectorYZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimY, 1));
+        vectorXZ.copyFrom(mBLASData.L2_zGERU_x_m2);
+        vectorYZ.copyFrom(mBLASData.L2_zGERU_y_n2);
+        matrixAZ.copyFrom(mBLASData.L2_zGERU_A_mn);
+
+        mBLAS.ZGERU(alphaZ, vectorXZ, incX, vectorYZ, incY, matrixAZ);
+        verifyMatrix(matrixARef, matrixAZ);
+
+        mRS.finish();
+        checkError();
+    }
+
+
+
+    private void xGERC_API_test(int incX, int incY, ArrayList<Allocation> mMatrix) {
+        for (Allocation matA : mMatrix) {
+            for (Allocation vecX : mMatrix) {
+                if (!validateVecInput(vecX)) {
+                    continue;
+                }
+                for (Allocation vecY : mMatrix) {
+                    if (!validateVecInput(vecY)) {
+                        continue;
+                    }
+                    Element elemA = matA.getType().getElement();
+                    if (validateGERU(elemA, vecX, incX, vecY, incY, matA)) {
+                        try {
+                            if (elemA.isCompatible(Element.F32_2(mRS))) {
+                                mBLAS.CGERC(alphaC, vecX, incX, vecY, incY, matA);
+                            } else if (elemA.isCompatible(Element.F64_2(mRS))) {
+                                mBLAS.ZGERC(alphaZ, vecX, incX, vecY, incY, matA);
+                            }
+                        } catch (RSRuntimeException e) {
+                            fail("should NOT throw RSRuntimeException");
+                        }
+                    } else {
+                        try {
+                            mBLAS.CGERC(alphaC, vecX, incX, vecY, incY, matA);
+                            fail("should throw RSRuntimeException for CGERC");
+                        } catch (RSRuntimeException e) {
+                        }
+                        try {
+                            mBLAS.ZGERC(alphaZ, vecX, incX, vecY, incY, matA);
+                            fail("should throw RSRuntimeException for ZGERC");
+                        } catch (RSRuntimeException e) {
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    private void L2_xGERC_API(ArrayList<Allocation> mMatrix) {
+        for (int incX : mInc) {
+            for (int incY : mInc) {
+                xGERC_API_test(incX, incY, mMatrix);
+            }
+        }
+    }
+
+    public void test_L2_CGERC_API() {
+        L2_xGERC_API(mMatrixC);
+    }
+
+    public void test_L2_ZGERC_API() {
+        L2_xGERC_API(mMatrixZ);
+    }
+
+    public void test_L2_CGERC_Correctness() {
+        int incX = 1;
+        int incY = 1;
+
+        // Populate input allocations
+        Allocation matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dM));
+        Allocation vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dM, 1));
+        Allocation vectorYC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, 1));
+        matrixAC.copyFrom(mBLASData.L2_cGERC_A_mn);
+        vectorXC.copyFrom(mBLASData.L2_cGERC_x_m1);
+        vectorYC.copyFrom(mBLASData.L2_cGERC_y_n1);
+
+        // Test for the default case: NO_TRANS
+        mBLAS.CGERC(alphaC, vectorXC, incX, vectorYC, incY, matrixAC);
+        Allocation matrixARef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dM));
+        matrixARef.copyFrom(mBLASData.L2_cGERC_o_N);
+        verifyMatrix(matrixARef, matrixAC);
+
+        // Test for incX = 2 & incY = 3;
+        incX = 2;
+        incY = 3;
+        int dimX = 1 + (mBLASData.dM - 1) * incX;
+        int dimY = 1 + (mBLASData.dN - 1) * incY;
+        vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimX, 1));
+        vectorYC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimY, 1));
+        vectorXC.copyFrom(mBLASData.L2_cGERC_x_m2);
+        vectorYC.copyFrom(mBLASData.L2_cGERC_y_n2);
+        matrixAC.copyFrom(mBLASData.L2_cGERC_A_mn);
+
+        mBLAS.CGERC(alphaC, vectorXC, incX, vectorYC, incY, matrixAC);
+        verifyMatrix(matrixARef, matrixAC);
+
+        mRS.finish();
+        checkError();
+    }
+
+    public void test_L2_ZGERC_Correctness() {
+        int incX = 1;
+        int incY = 1;
+
+        // Populate input allocations
+        Allocation matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dM));
+        Allocation vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dM, 1));
+        Allocation vectorYZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, 1));
+        matrixAZ.copyFrom(mBLASData.L2_zGERC_A_mn);
+        vectorXZ.copyFrom(mBLASData.L2_zGERC_x_m1);
+        vectorYZ.copyFrom(mBLASData.L2_zGERC_y_n1);
+
+        // Test for the default case: NO_TRANS
+        mBLAS.ZGERC(alphaZ, vectorXZ, incX, vectorYZ, incY, matrixAZ);
+        Allocation matrixARef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dM));
+        matrixARef.copyFrom(mBLASData.L2_zGERC_o_N);
+        verifyMatrix(matrixARef, matrixAZ);
+
+        // Test for incX = 2 & incY = 3;
+        incX = 2;
+        incY = 3;
+        int dimX = 1 + (mBLASData.dM - 1) * incX;
+        int dimY = 1 + (mBLASData.dN - 1) * incY;
+        vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimX, 1));
+        vectorYZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimY, 1));
+        vectorXZ.copyFrom(mBLASData.L2_zGERC_x_m2);
+        vectorYZ.copyFrom(mBLASData.L2_zGERC_y_n2);
+        matrixAZ.copyFrom(mBLASData.L2_zGERC_A_mn);
+
+        mBLAS.ZGERC(alphaZ, vectorXZ, incX, vectorYZ, incY, matrixAZ);
+        verifyMatrix(matrixARef, matrixAZ);
+
+        mRS.finish();
+        checkError();
+    }
+
+
+    private void xHER_API_test(int Uplo, int incX, ArrayList<Allocation> mMatrix) {
+        for (Allocation matA : mMatrix) {
+            for (Allocation vecX : mMatrix) {
+                if (!validateVecInput(vecX)) {
+                    continue;
+                }
+                Element elemA = matA.getType().getElement();
+                if (validateSYR(elemA, Uplo, vecX, incX, matA)) {
+                    try {
+                        if (elemA.isCompatible(Element.F32_2(mRS))) {
+                            mBLAS.CHER(Uplo, alphaS, vecX, incX, matA);
+                        } else if (elemA.isCompatible(Element.F64_2(mRS))) {
+                            mBLAS.ZHER(Uplo, alphaD, vecX, incX, matA);
+                        }
+                    } catch (RSRuntimeException e) {
+                        fail("should NOT throw RSRuntimeException");
+                    }
+                } else {
+                    try {
+                        mBLAS.CHER(Uplo, alphaS, vecX, incX, matA);
+                        fail("should throw RSRuntimeException for CHER");
+                    } catch (RSRuntimeException e) {
+                    }
+                    try {
+                        mBLAS.ZHER(Uplo, alphaD, vecX, incX, matA);
+                        fail("should throw RSRuntimeException for ZHER");
+                    } catch (RSRuntimeException e) {
+                    }
+                }
+            }
+        }
+    }
+
+    public void L2_xHER_API(ArrayList<Allocation> mMatrix) {
+        for (int Uplo : mUplo) {
+            for (int incX : mInc) {
+                xHER_API_test(Uplo, incX, mMatrix);
+            }
+        }
+    }
+
+    public void test_L2_CHER_API() {
+        L2_xHER_API(mMatrixC);
+    }
+
+    public void test_L2_ZHER_API() {
+        L2_xHER_API(mMatrixZ);
+    }
+
+    public void test_L2_CHER_Correctness() {
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+        int incX = 1;
+
+        // Populate input allocations
+        Allocation matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dN));
+        Allocation vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, 1));
+        matrixAC.copyFrom(mBLASData.L2_cHER_A_nn);
+        vectorXC.copyFrom(mBLASData.L2_cHER_x_n1);
+
+        // Test for the default case: NO_TRANS
+        mBLAS.CHER(uplo, alphaS, vectorXC, incX, matrixAC);
+        Allocation matrixARef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dN));
+        matrixARef.copyFrom(mBLASData.L2_cHER_o_N);
+        verifyMatrix(matrixARef, matrixAC, true);
+
+        // Test for incX = 2;
+        incX = 2;
+        int dimX = 1 + (mBLASData.dN - 1) * incX;
+        vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimX, 1));
+        vectorXC.copyFrom(mBLASData.L2_cHER_x_n2);
+        matrixAC.copyFrom(mBLASData.L2_cHER_A_nn);
+
+        mBLAS.CHER(uplo, alphaS, vectorXC, incX, matrixAC);
+        verifyMatrix(matrixARef, matrixAC, true);
+
+        mRS.finish();
+        checkError();
+    }
+
+    public void test_L2_ZHER_Correctness() {
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+        int incX = 1;
+
+        // Populate input allocations
+        Allocation matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dN));
+        Allocation vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, 1));
+        matrixAZ.copyFrom(mBLASData.L2_zHER_A_nn);
+        vectorXZ.copyFrom(mBLASData.L2_zHER_x_n1);
+
+        // Test for the default case: NO_TRANS
+        mBLAS.ZHER(uplo, alphaD, vectorXZ, incX, matrixAZ);
+        Allocation matrixARef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dN));
+        matrixARef.copyFrom(mBLASData.L2_zHER_o_N);
+        verifyMatrix(matrixARef, matrixAZ, true);
+
+        // Test for incX = 2;
+        incX = 2;
+        int dimX = 1 + (mBLASData.dN - 1) * incX;
+        vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimX, 1));
+        vectorXZ.copyFrom(mBLASData.L2_zHER_x_n2);
+        matrixAZ.copyFrom(mBLASData.L2_zHER_A_nn);
+
+        mBLAS.ZHER(uplo, alphaD, vectorXZ, incX, matrixAZ);
+        verifyMatrix(matrixARef, matrixAZ, true);
+
+        mRS.finish();
+        checkError();
+    }
+
+
+    private void xHPR_API_test(int Uplo, int incX, ArrayList<Allocation> mMatrix) {
+        for (Allocation matA : mMatrix) {
+            for (Allocation vecX : mMatrix) {
+                if (!validateVecInput(vecX)) {
+                    continue;
+                }
+                Element elemA = matA.getType().getElement();
+                if (validateSPR(elemA, Uplo, vecX, incX, matA)) {
+                    try {
+                        if (elemA.isCompatible(Element.F32_2(mRS))) {
+                            mBLAS.CHPR(Uplo, alphaS, vecX, incX, matA);
+                        } else if (elemA.isCompatible(Element.F64_2(mRS))) {
+                            mBLAS.ZHPR(Uplo, alphaD, vecX, incX, matA);
+                        }
+                    } catch (RSRuntimeException e) {
+                        fail("should NOT throw RSRuntimeException");
+                    }
+                } else {
+                    try {
+                        mBLAS.CHPR(Uplo, alphaS, vecX, incX, matA);
+                        fail("should throw RSRuntimeException for CHPR");
+                    } catch (RSRuntimeException e) {
+                    }
+                    try {
+                        mBLAS.ZHPR(Uplo, alphaD, vecX, incX, matA);
+                        fail("should throw RSRuntimeException for ZHPR");
+                    } catch (RSRuntimeException e) {
+                    }
+                }
+            }
+        }
+    }
+
+    public void L2_xHPR_API(ArrayList<Allocation> mMatrix) {
+        for (int Uplo : mUplo) {
+            for (int incX : mInc) {
+                xHPR_API_test(Uplo, incX, mMatrix);
+            }
+        }
+    }
+
+    public void test_L2_CHPR_API() {
+        L2_xHPR_API(mMatrixC);
+    }
+
+    public void test_L2_ZHPR_API() {
+        L2_xHPR_API(mMatrixZ);
+    }
+
+    public void test_L2_CHPR_Correctness() {
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+        int incX = 1;
+
+        // Populate input allocations
+        int N = mBLASData.dN;
+        Allocation matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), N * (N+1) / 2, 1));
+        Allocation vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), N, 1));
+        matrixAC.copyFrom(mBLASData.L2_cHER_A_nn_pu);
+        vectorXC.copyFrom(mBLASData.L2_cHER_x_n1);
+
+        // Test for the default case: NO_TRANS
+        mBLAS.CHPR(uplo, alphaS, vectorXC, incX, matrixAC);
+        Allocation matrixARef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), N * (N+1) / 2, 1));
+        matrixARef.copyFrom(mBLASData.L2_cHER_o_N_pu);
+        verifyMatrix(matrixARef, matrixAC, true);
+
+        // Test for incX = 2;
+        incX = 2;
+        int dimX = 1 + (N - 1) * incX;
+        vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimX, 1));
+        vectorXC.copyFrom(mBLASData.L2_cHER_x_n2);
+        matrixAC.copyFrom(mBLASData.L2_cHER_A_nn_pu);
+
+        mBLAS.CHPR(uplo, alphaS, vectorXC, incX, matrixAC);
+        verifyMatrix(matrixARef, matrixAC, true);
+
+        mRS.finish();
+        checkError();
+    }
+
+    public void test_L2_ZHPR_Correctness() {
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+        int incX = 1;
+
+        // Populate input allocations
+        int N = mBLASData.dN;
+        Allocation matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), N * (N+1) / 2, 1));
+        Allocation vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), N, 1));
+        matrixAZ.copyFrom(mBLASData.L2_zHER_A_nn_pu);
+        vectorXZ.copyFrom(mBLASData.L2_zHER_x_n1);
+
+        // Test for the default case: NO_TRANS
+        mBLAS.ZHPR(uplo, alphaD, vectorXZ, incX, matrixAZ);
+        Allocation matrixARef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), N * (N+1) / 2, 1));
+        matrixARef.copyFrom(mBLASData.L2_zHER_o_N_pu);
+        verifyMatrix(matrixARef, matrixAZ, true);
+
+        // Test for incX = 2;
+        incX = 2;
+        int dimX = 1 + (N - 1) * incX;
+        vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimX, 1));
+        vectorXZ.copyFrom(mBLASData.L2_zHER_x_n2);
+        matrixAZ.copyFrom(mBLASData.L2_zHER_A_nn_pu);
+
+        mBLAS.ZHPR(uplo, alphaD, vectorXZ, incX, matrixAZ);
+        verifyMatrix(matrixARef, matrixAZ, true);
+
+        mRS.finish();
+        checkError();
+    }
+
+
+    private void xHER2_API_test(int Uplo, int incX, int incY, ArrayList<Allocation> mMatrix) {
+        for (Allocation matA : mMatrix) {
+            for (Allocation vecX : mMatrix) {
+                if (!validateVecInput(vecX)) {
+                    continue;
+                }
+                for (Allocation vecY : mMatrix) {
+                    if (!validateVecInput(vecY)) {
+                        continue;
+                    }
+                    Element elemA = matA.getType().getElement();
+                    if (validateSYR2(elemA, Uplo, vecX, incX, vecY, incY, matA)) {
+                        try {
+                            if (elemA.isCompatible(Element.F32_2(mRS))) {
+                                mBLAS.CHER2(Uplo, alphaC, vecX, incX, vecY, incY, matA);
+                            } else if (elemA.isCompatible(Element.F64_2(mRS))) {
+                                mBLAS.ZHER2(Uplo, alphaZ, vecX, incX, vecY, incY, matA);
+                            }
+                        } catch (RSRuntimeException e) {
+                            fail("should NOT throw RSRuntimeException");
+                        }
+                    } else {
+                        try {
+                            mBLAS.CHER2(Uplo, alphaC, vecX, incX, vecY, incY, matA);
+                            fail("should throw RSRuntimeException for CHER2");
+                        } catch (RSRuntimeException e) {
+                        }
+                        try {
+                            mBLAS.ZHER2(Uplo, alphaZ, vecX, incX, vecY, incY, matA);
+                            fail("should throw RSRuntimeException for ZHER2");
+                        } catch (RSRuntimeException e) {
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    public void L2_xHER2_API(ArrayList<Allocation> mMatrix) {
+        for (int Uplo : mUplo) {
+            for (int incX : mInc) {
+                xHER2_API_test(Uplo, incX, incX, mMatrix);
+            }
+        }
+    }
+
+    public void test_L2_CHER2_API() {
+        L2_xHER2_API(mMatrixC);
+    }
+
+    public void test_L2_ZHER2_API() {
+        L2_xHER2_API(mMatrixZ);
+    }
+
+    public void test_L2_CHER2_Correctness() {
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+        int incX = 1;
+        int incY = 1;
+
+        // Populate input allocations
+        Allocation matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dN));
+        Allocation vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, 1));
+        Allocation vectorYC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, 1));
+        matrixAC.copyFrom(mBLASData.L2_cHER2_A_nn);
+        vectorXC.copyFrom(mBLASData.L2_cHER2_x_n1);
+        vectorYC.copyFrom(mBLASData.L2_cHER2_y_n1);
+
+        // Test for the default case: NO_TRANS
+        mBLAS.CHER2(uplo, alphaC, vectorXC, incX, vectorYC, incY, matrixAC);
+        Allocation matrixARef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dN));
+        matrixARef.copyFrom(mBLASData.L2_cHER2_o_N);
+        verifyMatrix(matrixARef, matrixAC, true);
+
+        // Test for incX = 2 & incY = 3;
+        incX = 2;
+        incY = 3;
+        int dimX = 1 + (mBLASData.dN - 1) * incX;
+        int dimY = 1 + (mBLASData.dN - 1) * incY;
+        vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimX, 1));
+        vectorYC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimY, 1));
+        vectorXC.copyFrom(mBLASData.L2_cHER2_x_n2);
+        vectorYC.copyFrom(mBLASData.L2_cHER2_y_n2);
+        matrixAC.copyFrom(mBLASData.L2_cHER2_A_nn);
+
+        mBLAS.CHER2(uplo, alphaC, vectorXC, incX, vectorYC, incY, matrixAC);
+        verifyMatrix(matrixARef, matrixAC, true);
+
+        mRS.finish();
+        checkError();
+    }
+
+    public void test_L2_ZHER2_Correctness() {
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+        int incX = 1;
+        int incY = 1;
+
+        // Populate input allocations
+        Allocation matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dN));
+        Allocation vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, 1));
+        Allocation vectorYZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, 1));
+        matrixAZ.copyFrom(mBLASData.L2_zHER2_A_nn);
+        vectorXZ.copyFrom(mBLASData.L2_zHER2_x_n1);
+        vectorYZ.copyFrom(mBLASData.L2_zHER2_y_n1);
+
+        // Test for the default case: NO_TRANS
+        mBLAS.ZHER2(uplo, alphaZ, vectorXZ, incX, vectorYZ, incY, matrixAZ);
+        Allocation matrixARef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dN));
+        matrixARef.copyFrom(mBLASData.L2_zHER2_o_N);
+        verifyMatrix(matrixARef, matrixAZ, true);
+
+        // Test for incX = 2 & incY = 3;
+        incX = 2;
+        incY = 3;
+        int dimX = 1 + (mBLASData.dN - 1) * incX;
+        int dimY = 1 + (mBLASData.dN - 1) * incY;
+        vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimX, 1));
+        vectorYZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimY, 1));
+        vectorXZ.copyFrom(mBLASData.L2_zHER2_x_n2);
+        vectorYZ.copyFrom(mBLASData.L2_zHER2_y_n2);
+        matrixAZ.copyFrom(mBLASData.L2_zHER2_A_nn);
+
+        mBLAS.ZHER2(uplo, alphaZ, vectorXZ, incX, vectorYZ, incY, matrixAZ);
+        verifyMatrix(matrixARef, matrixAZ, true);
+
+        mRS.finish();
+        checkError();
+    }
+
+
+
+    private void xHPR2_API_test(int Uplo, int incX, int incY, ArrayList<Allocation> mMatrix) {
+        for (Allocation matA : mMatrix) {
+            for (Allocation vecX : mMatrix) {
+                if (!validateVecInput(vecX)) {
+                    continue;
+                }
+                for (Allocation vecY : mMatrix) {
+                    if (!validateVecInput(vecY)) {
+                        continue;
+                    }
+                    Element elemA = matA.getType().getElement();
+                    if (validateSPR2(elemA, Uplo, vecX, incX, vecY, incY, matA)) {
+                        try {
+                            if (elemA.isCompatible(Element.F32_2(mRS))) {
+                                mBLAS.CHPR2(Uplo, alphaC, vecX, incX, vecY, incY, matA);
+                            } else if (elemA.isCompatible(Element.F64_2(mRS))) {
+                                mBLAS.ZHPR2(Uplo, alphaZ, vecX, incX, vecY, incY, matA);
+                            }
+                        } catch (RSRuntimeException e) {
+                            fail("should NOT throw RSRuntimeException");
+                        }
+                    } else {
+                        try {
+                            mBLAS.CHPR2(Uplo, alphaC, vecX, incX, vecY, incY, matA);
+                            fail("should throw RSRuntimeException for CHPR2");
+                        } catch (RSRuntimeException e) {
+                        }
+                        try {
+                            mBLAS.ZHPR2(Uplo, alphaZ, vecX, incX, vecY, incY, matA);
+                            fail("should throw RSRuntimeException for ZHPR2");
+                        } catch (RSRuntimeException e) {
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    public void L2_xHPR2_API(ArrayList<Allocation> mMatrix) {
+        for (int Uplo : mUplo) {
+            for (int incX : mInc) {
+                xHPR2_API_test(Uplo, incX, incX, mMatrix);
+            }
+        }
+    }
+
+    public void test_L2_CHPR2_API() {
+        L2_xHPR2_API(mMatrixC);
+    }
+
+    public void test_L2_ZHPR2_API() {
+        L2_xHPR2_API(mMatrixZ);
+    }
+
+    public void test_L2_CHPR2_Correctness() {
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+        int incX = 1;
+        int incY = 1;
+
+        // Populate input allocations
+        int N = mBLASData.dN;
+        Allocation matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), N * (N+1) / 2, 1));
+        Allocation vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), N, 1));
+        Allocation vectorYC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), N, 1));
+        matrixAC.copyFrom(mBLASData.L2_cHER2_A_nn_pu);
+        vectorXC.copyFrom(mBLASData.L2_cHER2_x_n1);
+        vectorYC.copyFrom(mBLASData.L2_cHER2_y_n1);
+
+        // Test for the default case: NO_TRANS
+        mBLAS.CHPR2(uplo, alphaC, vectorXC, incX, vectorYC, incY, matrixAC);
+        Allocation matrixARef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), N * (N+1) / 2, 1));
+        matrixARef.copyFrom(mBLASData.L2_cHER2_o_N_pu);
+        verifyMatrix(matrixARef, matrixAC, true);
+
+        // Test for incX = 2 & incY = 3;
+        incX = 2;
+        incY = 3;
+        int dimX = 1 + (N - 1) * incX;
+        int dimY = 1 + (N - 1) * incY;
+        vectorXC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimX, 1));
+        vectorYC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), dimY, 1));
+        vectorXC.copyFrom(mBLASData.L2_cHER2_x_n2);
+        vectorYC.copyFrom(mBLASData.L2_cHER2_y_n2);
+        matrixAC.copyFrom(mBLASData.L2_cHER2_A_nn_pu);
+
+        mBLAS.CHPR2(uplo, alphaC, vectorXC, incX, vectorYC, incY, matrixAC);
+        verifyMatrix(matrixARef, matrixAC, true);
+
+        mRS.finish();
+        checkError();
+    }
+
+    public void test_L2_ZHPR2_Correctness() {
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+        int incX = 1;
+        int incY = 1;
+
+        // Populate input allocations
+        int N = mBLASData.dN;
+        Allocation matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), N * (N+1) / 2, 1));
+        Allocation vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), N, 1));
+        Allocation vectorYZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), N, 1));
+        matrixAZ.copyFrom(mBLASData.L2_zHER2_A_nn_pu);
+        vectorXZ.copyFrom(mBLASData.L2_zHER2_x_n1);
+        vectorYZ.copyFrom(mBLASData.L2_zHER2_y_n1);
+
+        // Test for the default case: NO_TRANS
+        mBLAS.ZHPR2(uplo, alphaZ, vectorXZ, incX, vectorYZ, incY, matrixAZ);
+        Allocation matrixARef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), N * (N+1) / 2, 1));
+        matrixARef.copyFrom(mBLASData.L2_zHER2_o_N_pu);
+        verifyMatrix(matrixARef, matrixAZ, true);
+
+        // Test for incX = 2 & incY = 3;
+        incX = 2;
+        incY = 3;
+        int dimX = 1 + (N - 1) * incX;
+        int dimY = 1 + (N - 1) * incY;
+        vectorXZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimX, 1));
+        vectorYZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), dimY, 1));
+        vectorXZ.copyFrom(mBLASData.L2_zHER2_x_n2);
+        vectorYZ.copyFrom(mBLASData.L2_zHER2_y_n2);
+        matrixAZ.copyFrom(mBLASData.L2_zHER2_A_nn_pu);
+
+        mBLAS.ZHPR2(uplo, alphaZ, vectorXZ, incX, vectorYZ, incY, matrixAZ);
+        verifyMatrix(matrixARef, matrixAZ, true);
+
+        mRS.finish();
+        checkError();
+    }
+
+
+
+    private boolean validateSYR(Element e, int Uplo, Allocation X, int incX, Allocation A) {
+        if (!validateUplo(Uplo)) {
+            return false;
+        }
+        if (!A.getType().getElement().isCompatible(e) ||
+            !X.getType().getElement().isCompatible(e)) {
+            return false;
+        }
+
+        int N = A.getType().getX();
+
+        if (X.getType().getY() > 1) {
+            return false;
+        }
+        if (N != A.getType().getY()) {
+            return false;
+        }
+        if (incX <= 0) {
+            return false;
+        }
+        int expectedXDim = 1 + (N - 1) * incX;
+        if (X.getType().getX() != expectedXDim) {
+            return false;
+        }
+        return true;
+    }
+
+    private void xSYR_API_test(int Uplo, int incX, ArrayList<Allocation> mMatrix) {
+        for (Allocation matA : mMatrix) {
+            for (Allocation vecX : mMatrix) {
+                if (!validateVecInput(vecX)) {
+                    continue;
+                }
+                Element elemA = matA.getType().getElement();
+                if (validateSYR(elemA, Uplo, vecX, incX, matA)) {
+                    try {
+                        if (elemA.isCompatible(Element.F32(mRS))) {
+                            mBLAS.SSYR(Uplo, alphaS, vecX, incX, matA);
+                        } else if (elemA.isCompatible(Element.F64(mRS))) {
+                            mBLAS.DSYR(Uplo, alphaD, vecX, incX, matA);
+                        }
+                    } catch (RSRuntimeException e) {
+                        fail("should NOT throw RSRuntimeException");
+                    }
+                } else {
+                    try {
+                        mBLAS.SSYR(Uplo, alphaS, vecX, incX, matA);
+                        fail("should throw RSRuntimeException for SSYR");
+                    } catch (RSRuntimeException e) {
+                    }
+                    try {
+                        mBLAS.DSYR(Uplo, alphaD, vecX, incX, matA);
+                        fail("should throw RSRuntimeException for DSYR");
+                    } catch (RSRuntimeException e) {
+                    }
+                }
+            }
+        }
+    }
+
+    public void L2_xSYR_API(ArrayList<Allocation> mMatrix) {
+        for (int Uplo : mUplo) {
+            for (int incX : mInc) {
+                xSYR_API_test(Uplo, incX, mMatrix);
+            }
+        }
+    }
+
+    public void test_L2_SSYR_API() {
+        L2_xSYR_API(mMatrixS);
+    }
+
+    public void test_L2_DSYR_API() {
+        L2_xSYR_API(mMatrixD);
+    }
+
+    public void test_L2_SSYR_Correctness() {
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+        int incX = 1;
+
+        // Populate input allocations
+        Allocation matrixAS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dN));
+        Allocation vectorXS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, 1));
+        matrixAS.copyFrom(mBLASData.L2_sSYR_A_nn);
+        vectorXS.copyFrom(mBLASData.L2_sSYR_x_n1);
+
+        // Test for the default case: NO_TRANS
+        mBLAS.SSYR(uplo, alphaS, vectorXS, incX, matrixAS);
+        Allocation matrixARef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dN));
+        matrixARef.copyFrom(mBLASData.L2_sSYR_o_N);
+        verifyMatrix(matrixARef, matrixAS, true);
+
+        // Test for incX = 2;
+        incX = 2;
+        int dimX = 1 + (mBLASData.dN - 1) * incX;
+        vectorXS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimX, 1));
+        vectorXS.copyFrom(mBLASData.L2_sSYR_x_n2);
+        matrixAS.copyFrom(mBLASData.L2_sSYR_A_nn);
+
+        mBLAS.SSYR(uplo, alphaS, vectorXS, incX, matrixAS);
+        verifyMatrix(matrixARef, matrixAS, true);
+
+        mRS.finish();
+        checkError();
+    }
+
+    public void test_L2_DSYR_Correctness() {
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+        int incX = 1;
+
+        // Populate input allocations
+        Allocation matrixAD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dN));
+        Allocation vectorXD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, 1));
+        matrixAD.copyFrom(mBLASData.L2_dSYR_A_nn);
+        vectorXD.copyFrom(mBLASData.L2_dSYR_x_n1);
+
+        // Test for the default case: NO_TRANS
+        mBLAS.DSYR(uplo, alphaD, vectorXD, incX, matrixAD);
+        Allocation matrixARef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dN));
+        matrixARef.copyFrom(mBLASData.L2_dSYR_o_N);
+        verifyMatrix(matrixARef, matrixAD, true);
+
+        // Test for incX = 2;
+        incX = 2;
+        int dimX = 1 + (mBLASData.dN - 1) * incX;
+        vectorXD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimX, 1));
+        vectorXD.copyFrom(mBLASData.L2_dSYR_x_n2);
+        matrixAD.copyFrom(mBLASData.L2_dSYR_A_nn);
+
+        mBLAS.DSYR(uplo, alphaD, vectorXD, incX, matrixAD);
+        verifyMatrix(matrixARef, matrixAD, true);
+
+        mRS.finish();
+        checkError();
+    }
+
+
+    private boolean validateSPR(Element e, int Uplo, Allocation X, int incX, Allocation Ap) {
+        if (!validateUplo(Uplo)) {
+            return false;
+        }
+        if (!Ap.getType().getElement().isCompatible(e) ||
+            !X.getType().getElement().isCompatible(e)) {
+            return false;
+        }
+        if (X.getType().getY() > 1) {
+            return false;
+        }
+
+        if (Ap.getType().getY() > 1) {
+            return false;
+        }
+
+        int N = (int)Math.sqrt((double)Ap.getType().getX() * 2);
+        if (Ap.getType().getX() != ((N * (N+1)) / 2)) {
+            return false;
+        }
+        if (incX <= 0) {
+            return false;
+        }
+        int expectedXDim = 1 + (N - 1) * incX;
+        if (X.getType().getX() != expectedXDim) {
+            return false;
+        }
+
+        return true;
+    }
+
+    private void xSPR_API_test(int Uplo, int incX, ArrayList<Allocation> mMatrix) {
+        for (Allocation matA : mMatrix) {
+            for (Allocation vecX : mMatrix) {
+                if (!validateVecInput(vecX)) {
+                    continue;
+                }
+                Element elemA = matA.getType().getElement();
+                if (validateSPR(elemA, Uplo, vecX, incX, matA)) {
+                    try {
+                        if (elemA.isCompatible(Element.F32(mRS))) {
+                            mBLAS.SSPR(Uplo, alphaS, vecX, incX, matA);
+                        } else if (elemA.isCompatible(Element.F64(mRS))) {
+                            mBLAS.DSPR(Uplo, alphaD, vecX, incX, matA);
+                        }
+                    } catch (RSRuntimeException e) {
+                        fail("should NOT throw RSRuntimeException");
+                    }
+                } else {
+                    try {
+                        mBLAS.SSPR(Uplo, alphaS, vecX, incX, matA);
+                        fail("should throw RSRuntimeException for SSPR");
+                    } catch (RSRuntimeException e) {
+                    }
+                    try {
+                        mBLAS.DSPR(Uplo, alphaD, vecX, incX, matA);
+                        fail("should throw RSRuntimeException for DSPR");
+                    } catch (RSRuntimeException e) {
+                    }
+                }
+            }
+        }
+    }
+
+    public void L2_xSPR_API(ArrayList<Allocation> mMatrix) {
+        for (int Uplo : mUplo) {
+            for (int incX : mInc) {
+                xSPR_API_test(Uplo, incX, mMatrix);
+            }
+        }
+    }
+
+    public void test_L2_SSPR_API() {
+        L2_xSPR_API(mMatrixS);
+    }
+
+    public void test_L2_DSPR_API() {
+        L2_xSPR_API(mMatrixD);
+    }
+
+    public void test_L2_SSPR_Correctness() {
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+        int incX = 1;
+
+        // Populate input allocations
+        int N = mBLASData.dN;
+        Allocation matrixAS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), N * (N+1) / 2, 1));
+        Allocation vectorXS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), N, 1));
+        matrixAS.copyFrom(mBLASData.L2_sSYR_A_nn_pu);
+        vectorXS.copyFrom(mBLASData.L2_sSYR_x_n1);
+
+        // Test for the default case: NO_TRANS
+        mBLAS.SSPR(uplo, alphaS, vectorXS, incX, matrixAS);
+        Allocation matrixARef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), N * (N+1) / 2, 1));
+        matrixARef.copyFrom(mBLASData.L2_sSYR_o_N_pu);
+        verifyMatrix(matrixARef, matrixAS, true);
+
+        // Test for incX = 2;
+        incX = 2;
+        int dimX = 1 + (N - 1) * incX;
+        vectorXS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimX, 1));
+        vectorXS.copyFrom(mBLASData.L2_sSYR_x_n2);
+        matrixAS.copyFrom(mBLASData.L2_sSYR_A_nn_pu);
+
+        mBLAS.SSPR(uplo, alphaS, vectorXS, incX, matrixAS);
+        verifyMatrix(matrixARef, matrixAS, true);
+
+        mRS.finish();
+        checkError();
+    }
+
+    public void test_L2_DSPR_Correctness() {
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+        int incX = 1;
+
+        // Populate input allocations
+        int N = mBLASData.dN;
+        Allocation matrixAD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), N * (N+1) / 2, 1));
+        Allocation vectorXD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), N, 1));
+        matrixAD.copyFrom(mBLASData.L2_dSYR_A_nn_pu);
+        vectorXD.copyFrom(mBLASData.L2_dSYR_x_n1);
+
+        // Test for the default case: NO_TRANS
+        mBLAS.DSPR(uplo, alphaD, vectorXD, incX, matrixAD);
+        Allocation matrixARef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), N * (N+1) / 2, 1));
+        matrixARef.copyFrom(mBLASData.L2_dSYR_o_N_pu);
+        verifyMatrix(matrixARef, matrixAD, true);
+
+        // Test for incX = 2;
+        incX = 2;
+        int dimX = 1 + (N - 1) * incX;
+        vectorXD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimX, 1));
+        vectorXD.copyFrom(mBLASData.L2_dSYR_x_n2);
+        matrixAD.copyFrom(mBLASData.L2_dSYR_A_nn_pu);
+
+        mBLAS.DSPR(uplo, alphaD, vectorXD, incX, matrixAD);
+        verifyMatrix(matrixARef, matrixAD, true);
+
+        mRS.finish();
+        checkError();
+    }
+
+
+    private boolean validateSYR2(Element e, int Uplo, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
+        if (!validateUplo(Uplo)) {
+            return false;
+        }
+        if (!A.getType().getElement().isCompatible(e) ||
+            !X.getType().getElement().isCompatible(e) ||
+            !Y.getType().getElement().isCompatible(e)) {
+            return false;
+        }
+
+        if (X.getType().getY() > 1 || Y.getType().getY() > 1) {
+            return false;
+        }
+
+        int N = A.getType().getX();
+
+        if (N != A.getType().getY()) {
+            return false;
+        }
+        if (incX <= 0 || incY <= 0) {
+            return false;
+        }
+        int expectedXDim = 1 + (N - 1) * incX;
+        int expectedYDim = 1 + (N - 1) * incY;
+        if (X.getType().getX() != expectedXDim || Y.getType().getX() != expectedYDim) {
+            return false;
+        }
+        return true;
+    }
+
+    private void xSYR2_API_test(int Uplo, int incX, int incY, ArrayList<Allocation> mMatrix) {
+        for (Allocation matA : mMatrix) {
+            for (Allocation vecX : mMatrix) {
+                if (!validateVecInput(vecX)) {
+                    continue;
+                }
+                for (Allocation vecY : mMatrix) {
+                    if (!validateVecInput(vecY)) {
+                        continue;
+                    }
+                    Element elemA = matA.getType().getElement();
+                    if (validateSYR2(elemA, Uplo, vecX, incX, vecY, incY, matA)) {
+                        try {
+                            if (elemA.isCompatible(Element.F32(mRS))) {
+                                mBLAS.SSYR2(Uplo, alphaS, vecX, incX, vecY, incY, matA);
+                            } else if (elemA.isCompatible(Element.F64(mRS))) {
+                                mBLAS.DSYR2(Uplo, alphaD, vecX, incX, vecY, incY, matA);
+                            }
+                        } catch (RSRuntimeException e) {
+                            fail("should NOT throw RSRuntimeException");
+                        }
+                    } else {
+                        try {
+                            mBLAS.SSYR2(Uplo, alphaS, vecX, incX, vecY, incY, matA);
+                            fail("should throw RSRuntimeException for SSYR2");
+                        } catch (RSRuntimeException e) {
+                        }
+                        try {
+                            mBLAS.DSYR2(Uplo, alphaD, vecX, incX, vecY, incY, matA);
+                            fail("should throw RSRuntimeException for DSYR2");
+                        } catch (RSRuntimeException e) {
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    public void L2_xSYR2_API(ArrayList<Allocation> mMatrix) {
+        for (int Uplo : mUplo) {
+            for (int incX : mInc) {
+                xSYR2_API_test(Uplo, incX, incX, mMatrix);
+            }
+        }
+    }
+
+    public void test_L2_SSYR2_API() {
+        L2_xSYR2_API(mMatrixS);
+    }
+
+    public void test_L2_DSYR2_API() {
+        L2_xSYR2_API(mMatrixD);
+    }
+
+    public void test_L2_SSYR2_Correctness() {
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+        int incX = 1;
+        int incY = 1;
+
+        // Populate input allocations
+        Allocation matrixAS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dN));
+        Allocation vectorXS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, 1));
+        Allocation vectorYS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, 1));
+        matrixAS.copyFrom(mBLASData.L2_sSYR2_A_nn);
+        vectorXS.copyFrom(mBLASData.L2_sSYR2_x_n1);
+        vectorYS.copyFrom(mBLASData.L2_sSYR2_y_n1);
+
+        // Test for the default case: NO_TRANS
+        mBLAS.SSYR2(uplo, alphaS, vectorXS, incX, vectorYS, incY, matrixAS);
+        Allocation matrixARef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dN));
+        matrixARef.copyFrom(mBLASData.L2_sSYR2_o_N);
+        verifyMatrix(matrixARef, matrixAS, true);
+
+        // Test for incX = 2 & incY = 3;
+        incX = 2;
+        incY = 3;
+        int dimX = 1 + (mBLASData.dN - 1) * incX;
+        int dimY = 1 + (mBLASData.dN - 1) * incY;
+        vectorXS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimX, 1));
+        vectorYS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimY, 1));
+        vectorXS.copyFrom(mBLASData.L2_sSYR2_x_n2);
+        vectorYS.copyFrom(mBLASData.L2_sSYR2_y_n2);
+        matrixAS.copyFrom(mBLASData.L2_sSYR2_A_nn);
+
+        mBLAS.SSYR2(uplo, alphaS, vectorXS, incX, vectorYS, incY, matrixAS);
+        verifyMatrix(matrixARef, matrixAS, true);
+
+        mRS.finish();
+        checkError();
+    }
+
+    public void test_L2_DSYR2_Correctness() {
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+        int incX = 1;
+        int incY = 1;
+
+        // Populate input allocations
+        Allocation matrixAD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dN));
+        Allocation vectorXD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, 1));
+        Allocation vectorYD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, 1));
+        matrixAD.copyFrom(mBLASData.L2_dSYR2_A_nn);
+        vectorXD.copyFrom(mBLASData.L2_dSYR2_x_n1);
+        vectorYD.copyFrom(mBLASData.L2_dSYR2_y_n1);
+
+        // Test for the default case: NO_TRANS
+        mBLAS.DSYR2(uplo, alphaD, vectorXD, incX, vectorYD, incY, matrixAD);
+        Allocation matrixARef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dN));
+        matrixARef.copyFrom(mBLASData.L2_dSYR2_o_N);
+        verifyMatrix(matrixARef, matrixAD, true);
+
+        // Test for incX = 2 & incY = 3;
+        incX = 2;
+        incY = 3;
+        int dimX = 1 + (mBLASData.dN - 1) * incX;
+        int dimY = 1 + (mBLASData.dN - 1) * incY;
+        vectorXD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimX, 1));
+        vectorYD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimY, 1));
+        vectorXD.copyFrom(mBLASData.L2_dSYR2_x_n2);
+        vectorYD.copyFrom(mBLASData.L2_dSYR2_y_n2);
+        matrixAD.copyFrom(mBLASData.L2_dSYR2_A_nn);
+
+        mBLAS.DSYR2(uplo, alphaD, vectorXD, incX, vectorYD, incY, matrixAD);
+        verifyMatrix(matrixARef, matrixAD, true);
+
+        mRS.finish();
+        checkError();
+    }
+
+
+    private boolean validateSPR2(Element e, int Uplo, Allocation X, int incX, Allocation Y, int incY, Allocation Ap) {
+        if (!validateUplo(Uplo)) {
+            return false;
+        }
+        if (!Ap.getType().getElement().isCompatible(e) ||
+            !X.getType().getElement().isCompatible(e) ||
+            !Y.getType().getElement().isCompatible(e)) {
+            return false;
+        }
+        if (X.getType().getY() > 1 || Y.getType().getY() > 1) {
+            return false;
+        }
+
+        if (Ap.getType().getY() > 1) {
+            return false;
+        }
+
+        int N = (int)Math.sqrt((double)Ap.getType().getX() * 2);
+        if (Ap.getType().getX() != ((N * (N+1)) / 2)) {
+            return false;
+        }
+        if (incX <= 0 || incY <= 0) {
+            return false;
+        }
+        int expectedXDim = 1 + (N - 1) * incX;
+        int expectedYDim = 1 + (N - 1) * incY;
+        if (X.getType().getX() != expectedXDim || Y.getType().getX() != expectedYDim) {
+            return false;
+        }
+
+        return true;
+    }
+
+    private void xSPR2_API_test(int Uplo, int incX, int incY, ArrayList<Allocation> mMatrix) {
+        for (Allocation matA : mMatrix) {
+            for (Allocation vecX : mMatrix) {
+                if (!validateVecInput(vecX)) {
+                    continue;
+                }
+                for (Allocation vecY : mMatrix) {
+                    if (!validateVecInput(vecY)) {
+                        continue;
+                    }
+                    Element elemA = matA.getType().getElement();
+                    if (validateSPR2(elemA, Uplo, vecX, incX, vecY, incY, matA)) {
+                        try {
+                            if (elemA.isCompatible(Element.F32(mRS))) {
+                                mBLAS.SSPR2(Uplo, alphaS, vecX, incX, vecY, incY, matA);
+                            } else if (elemA.isCompatible(Element.F64(mRS))) {
+                                mBLAS.DSPR2(Uplo, alphaD, vecX, incX, vecY, incY, matA);
+                            }
+                        } catch (RSRuntimeException e) {
+                            fail("should NOT throw RSRuntimeException");
+                        }
+                    } else {
+                        try {
+                            mBLAS.SSPR2(Uplo, alphaS, vecX, incX, vecY, incY, matA);
+                            fail("should throw RSRuntimeException for SSPR2");
+                        } catch (RSRuntimeException e) {
+                        }
+                        try {
+                            mBLAS.DSPR2(Uplo, alphaD, vecX, incX, vecY, incY, matA);
+                            fail("should throw RSRuntimeException for DSPR2");
+                        } catch (RSRuntimeException e) {
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    public void L2_xSPR2_API(ArrayList<Allocation> mMatrix) {
+        for (int Uplo : mUplo) {
+            for (int incX : mInc) {
+                xSPR2_API_test(Uplo, incX, incX, mMatrix);
+            }
+        }
+    }
+
+    public void test_L2_SSPR2_API() {
+        L2_xSPR2_API(mMatrixS);
+    }
+
+    public void test_L2_DSPR2_API() {
+        L2_xSPR2_API(mMatrixD);
+    }
+
+    public void test_L2_SSPR2_Correctness() {
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+        int incX = 1;
+        int incY = 1;
+
+        // Populate input allocations
+        int N = mBLASData.dN;
+        Allocation matrixAS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), N * (N+1) / 2, 1));
+        Allocation vectorXS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), N, 1));
+        Allocation vectorYS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), N, 1));
+        matrixAS.copyFrom(mBLASData.L2_sSYR2_A_nn_pu);
+        vectorXS.copyFrom(mBLASData.L2_sSYR2_x_n1);
+        vectorYS.copyFrom(mBLASData.L2_sSYR2_y_n1);
+
+        // Test for the default case: NO_TRANS
+        mBLAS.SSPR2(uplo, alphaS, vectorXS, incX, vectorYS, incY, matrixAS);
+        Allocation matrixARef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), N * (N+1) / 2, 1));
+        matrixARef.copyFrom(mBLASData.L2_sSYR2_o_N_pu);
+        verifyMatrix(matrixARef, matrixAS, true);
+
+        // Test for incX = 2 & incY = 3;
+        incX = 2;
+        incY = 3;
+        int dimX = 1 + (N - 1) * incX;
+        int dimY = 1 + (N - 1) * incY;
+        vectorXS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimX, 1));
+        vectorYS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), dimY, 1));
+        vectorXS.copyFrom(mBLASData.L2_sSYR2_x_n2);
+        vectorYS.copyFrom(mBLASData.L2_sSYR2_y_n2);
+        matrixAS.copyFrom(mBLASData.L2_sSYR2_A_nn_pu);
+
+        mBLAS.SSPR2(uplo, alphaS, vectorXS, incX, vectorYS, incY, matrixAS);
+        verifyMatrix(matrixARef, matrixAS, true);
+
+        mRS.finish();
+        checkError();
+    }
+
+    public void test_L2_DSPR2_Correctness() {
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+        int incX = 1;
+        int incY = 1;
+
+        // Populate input allocations
+        int N = mBLASData.dN;
+        Allocation matrixAD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), N * (N+1) / 2, 1));
+        Allocation vectorXD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), N, 1));
+        Allocation vectorYD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), N, 1));
+        matrixAD.copyFrom(mBLASData.L2_dSYR2_A_nn_pu);
+        vectorXD.copyFrom(mBLASData.L2_dSYR2_x_n1);
+        vectorYD.copyFrom(mBLASData.L2_dSYR2_y_n1);
+
+        // Test for the default case: NO_TRANS
+        mBLAS.DSPR2(uplo, alphaD, vectorXD, incX, vectorYD, incY, matrixAD);
+        Allocation matrixARef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), N * (N+1) / 2, 1));
+        matrixARef.copyFrom(mBLASData.L2_dSYR2_o_N_pu);
+        verifyMatrix(matrixARef, matrixAD, true);
+
+        // Test for incX = 2 & incY = 3;
+        incX = 2;
+        incY = 3;
+        int dimX = 1 + (N - 1) * incX;
+        int dimY = 1 + (N - 1) * incY;
+        vectorXD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimX, 1));
+        vectorYD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), dimY, 1));
+        vectorXD.copyFrom(mBLASData.L2_dSYR2_x_n2);
+        vectorYD.copyFrom(mBLASData.L2_dSYR2_y_n2);
+        matrixAD.copyFrom(mBLASData.L2_dSYR2_A_nn_pu);
+
+        mBLAS.DSPR2(uplo, alphaD, vectorXD, incX, vectorYD, incY, matrixAD);
+        verifyMatrix(matrixARef, matrixAD, true);
+
+        mRS.finish();
+        checkError();
+    }
+
+
+
+    private boolean validateL3(Element e, int TransA, int TransB, int Side, Allocation A, Allocation B, Allocation C) {
+        int aM = -1, aN = -1, bM = -1, bN = -1, cM = -1, cN = -1;
+        if ((A != null && !A.getType().getElement().isCompatible(e)) ||
+            (B != null && !B.getType().getElement().isCompatible(e)) ||
+            (C != null && !C.getType().getElement().isCompatible(e))) {
+            return false;
+        }
+        if (C == null) {
+            //since matrix C is used to store the result, it cannot be null.
+            return false;
+        }
+        cM = C.getType().getY();
+        cN = C.getType().getX();
+
+        if (Side == ScriptIntrinsicBLAS.RIGHT) {
+            if ((A == null && B != null) || (A != null && B == null)) {
+                return false;
+            }
+            if (B != null) {
+                bM = A.getType().getY();
+                bN = A.getType().getX();
+            }
+            if (A != null) {
+                aM = B.getType().getY();
+                aN = B.getType().getX();
+            }
+        } else {
+            if (A != null) {
+                if (TransA == ScriptIntrinsicBLAS.TRANSPOSE ||
+                    TransA == ScriptIntrinsicBLAS.CONJ_TRANSPOSE ) {
+                    aN = A.getType().getY();
+                    aM = A.getType().getX();
+                } else {
+                    aM = A.getType().getY();
+                    aN = A.getType().getX();
+                }
+            }
+            if (B != null) {
+                if (TransB == ScriptIntrinsicBLAS.TRANSPOSE ||
+                    TransB == ScriptIntrinsicBLAS.CONJ_TRANSPOSE ) {
+                    bN = B.getType().getY();
+                    bM = B.getType().getX();
+                } else {
+                    bM = B.getType().getY();
+                    bN = B.getType().getX();
+                }
+            }
+        }
+        if (A != null && B != null && C != null) {
+            if (aN != bM || aM != cM || bN != cN) {
+                return false;
+            }
+        } else if (A != null && C != null) {
+            // A and C only, for SYRK
+            if (cM != cN) {
+                return false;
+            }
+            if (aM != cM) {
+                return false;
+            }
+        } else if (A != null && B != null) {
+            // A and B only
+            if (aN != bM) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    private boolean validateL3_xGEMM(Element e, int TransA, int TransB, Allocation A, Allocation B, Allocation C) {
+        boolean result = true;
+        result &= validateTranspose(TransA);
+        result &= validateTranspose(TransB);
+        result &= validateL3(e, TransA, TransB, 0, A, B, C);
+
+        return result;
+    }
+
+    private void xGEMM_API_test(int transA, int transB, ArrayList<Allocation> mMatrix) {
+        for (Allocation matA : mMatrix) {
+            for (Allocation matB : mMatrix) {
+                for (Allocation matC : mMatrix) {
+                    Element elemA = matA.getType().getElement();
+                    if (validateL3_xGEMM(elemA, transA, transB, matA, matB, matC)) {
+                        try {
+                            if (elemA.isCompatible(Element.F32(mRS))) {
+                                mBLAS.SGEMM(transA, transB, alphaS, matA, matB, betaS, matC);
+                            } else if (elemA.isCompatible(Element.F64(mRS))) {
+                                mBLAS.DGEMM(transA, transB, alphaD, matA, matB, betaD, matC);
+                            } else if (elemA.isCompatible(Element.F32_2(mRS))) {
+                                mBLAS.CGEMM(transA, transB, alphaC, matA, matB, betaC, matC);
+                            } else if (elemA.isCompatible(Element.F64_2(mRS))) {
+                                mBLAS.ZGEMM(transA, transB, alphaZ, matA, matB, betaZ, matC);
+                            }
+                        } catch (RSRuntimeException e) {
+                            fail("should NOT throw RSRuntimeException");
+                        }
+                    } else {
+                        try {
+                            mBLAS.SGEMM(transA, transB, alphaS, matA, matB, betaS, matC);
+                            fail("should throw RSRuntimeException for SGEMM");
+                        } catch (RSRuntimeException e) {
+                        }
+                        try {
+                            mBLAS.DGEMM(transA, transB, alphaD, matA, matB, betaD, matC);
+                            fail("should throw RSRuntimeException for DGEMM");
+                        } catch (RSRuntimeException e) {
+                        }
+                        try {
+                            mBLAS.CGEMM(transA, transB, alphaC, matA, matB, betaC, matC);
+                            fail("should throw RSRuntimeException for CGEMM");
+                        } catch (RSRuntimeException e) {
+                        }
+                        try {
+                            mBLAS.ZGEMM(transA, transB, alphaZ, matA, matB, betaZ, matC);
+                            fail("should throw RSRuntimeException for ZGEMM");
+                        } catch (RSRuntimeException e) {
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    private void L3_xGEMM_API(ArrayList<Allocation> mMatrix) {
+        for (int transA : mTranspose) {
+            for (int transB : mTranspose) {
+                xGEMM_API_test(transA, transB, mMatrix);
+            }
+        }
+    }
+
+    public void test_L3_SGEMM_API() {
+        L3_xGEMM_API(mMatrixS);
+    }
+
+    public void test_L3_DGEMM_API() {
+        L3_xGEMM_API(mMatrixD);
+    }
+
+    public void test_L3_CGEMM_API() {
+        L3_xGEMM_API(mMatrixC);
+    }
+
+    public void test_L3_ZGEMM_API() {
+        L3_xGEMM_API(mMatrixZ);
+    }
+
+
+    public void test_L3_SGEMM_Correctness() {
+        int transA = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        int transB = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+
+        // Populate input allocations
+        Allocation matrixAS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dK, mBLASData.dM));
+        Allocation matrixBS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dK));
+        Allocation matrixCS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dM));
+        matrixAS.copyFrom(mBLASData.L3_sGEMM_A_mk);
+        matrixBS.copyFrom(mBLASData.L3_sGEMM_B_kn);
+        matrixCS.copyFrom(mBLASData.L3_sGEMM_C_mn);
+
+        // Test for the default case: NO_TRANS
+        mBLAS.SGEMM(transA, transB, alphaS, matrixAS, matrixBS, betaS, matrixCS);
+        Allocation matrixCRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dM));
+        matrixCRef.copyFrom(mBLASData.L3_sGEMM_o_NN);
+        verifyMatrix(matrixCRef, matrixCS);
+
+        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
+        matrixAS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dM, mBLASData.dK));
+        matrixBS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dK, mBLASData.dN));
+        matrixAS.copyFrom(mBLASData.L3_sGEMM_A_km);
+        matrixBS.copyFrom(mBLASData.L3_sGEMM_B_nk);
+
+        transA = ScriptIntrinsicBLAS.TRANSPOSE;
+        transB = ScriptIntrinsicBLAS.TRANSPOSE;
+        // Reload matrix C, since it was overwritten by BLAS.
+        matrixCS.copyFrom(mBLASData.L3_sGEMM_C_mn);
+        mBLAS.SGEMM(transA, transB, alphaS, matrixAS, matrixBS, betaS, matrixCS);
+        matrixCRef.copyFrom(mBLASData.L3_sGEMM_o_TT);
+        verifyMatrix(matrixCRef, matrixCS);
+
+        transA = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
+        transB = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
+        matrixCS.copyFrom(mBLASData.L3_sGEMM_C_mn);
+        mBLAS.SGEMM(transA, transB, alphaS, matrixAS, matrixBS, betaS, matrixCS);
+        matrixCRef.copyFrom(mBLASData.L3_sGEMM_o_HH);
+        verifyMatrix(matrixCRef, matrixCS);
+
+        mRS.finish();
+        checkError();
+    }
+
+    public void test_L3_DGEMM_Correctness() {
+        int transA = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        int transB = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+
+        // Populate input allocations
+        Allocation matrixAD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dK, mBLASData.dM));
+        Allocation matrixBD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dK));
+        Allocation matrixCD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dM));
+        matrixAD.copyFrom(mBLASData.L3_dGEMM_A_mk);
+        matrixBD.copyFrom(mBLASData.L3_dGEMM_B_kn);
+        matrixCD.copyFrom(mBLASData.L3_dGEMM_C_mn);
+        // Test for the default case: NO_TRANS
+        mBLAS.DGEMM(transA, transB, alphaD, matrixAD, matrixBD, betaD, matrixCD);
+        Allocation matrixCRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dM));
+        matrixCRef.copyFrom(mBLASData.L3_dGEMM_o_NN);
+        verifyMatrix(matrixCRef, matrixCD);
+
+        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
+        matrixAD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dM, mBLASData.dK));
+        matrixBD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dK, mBLASData.dN));
+        matrixAD.copyFrom(mBLASData.L3_dGEMM_A_km);
+        matrixBD.copyFrom(mBLASData.L3_dGEMM_B_nk);
+
+        transA = ScriptIntrinsicBLAS.TRANSPOSE;
+        transB = ScriptIntrinsicBLAS.TRANSPOSE;
+        // Reload matrix C, since it was overwritten by BLAS.
+        matrixCD.copyFrom(mBLASData.L3_dGEMM_C_mn);
+        mBLAS.DGEMM(transA, transB, alphaD, matrixAD, matrixBD, betaD, matrixCD);
+        matrixCRef.copyFrom(mBLASData.L3_dGEMM_o_TT);
+        verifyMatrix(matrixCRef, matrixCD);
+
+        transA = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
+        transB = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
+        matrixCD.copyFrom(mBLASData.L3_dGEMM_C_mn);
+        mBLAS.DGEMM(transA, transB, alphaD, matrixAD, matrixBD, betaD, matrixCD);
+        matrixCRef.copyFrom(mBLASData.L3_dGEMM_o_HH);
+        verifyMatrix(matrixCRef, matrixCD);
+
+        mRS.finish();
+        checkError();
+    }
+
+    public void test_L3_CGEMM_Correctness() {
+        int transA = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        int transB = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+
+        // Populate input allocations
+        Allocation matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dK, mBLASData.dM));
+        Allocation matrixBC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dK));
+        Allocation matrixCC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dM));
+        matrixAC.copyFrom(mBLASData.L3_cGEMM_A_mk);
+        matrixBC.copyFrom(mBLASData.L3_cGEMM_B_kn);
+        matrixCC.copyFrom(mBLASData.L3_cGEMM_C_mn);
+
+        // Test for the default case: NO_TRANS
+        mBLAS.CGEMM(transA, transB, alphaC, matrixAC, matrixBC, betaC, matrixCC);
+        Allocation matrixCRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dM));
+        matrixCRef.copyFrom(mBLASData.L3_cGEMM_o_NN);
+        verifyMatrix(matrixCRef, matrixCC);
+
+        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
+        matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dM, mBLASData.dK));
+        matrixBC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dK, mBLASData.dN));
+        matrixAC.copyFrom(mBLASData.L3_cGEMM_A_km);
+        matrixBC.copyFrom(mBLASData.L3_cGEMM_B_nk);
+
+        transA = ScriptIntrinsicBLAS.TRANSPOSE;
+        transB = ScriptIntrinsicBLAS.TRANSPOSE;
+        // Reload matrix C, since it was overwritten by BLAS.
+        matrixCC.copyFrom(mBLASData.L3_cGEMM_C_mn);
+        mBLAS.CGEMM(transA, transB, alphaC, matrixAC, matrixBC, betaC, matrixCC);
+        matrixCRef.copyFrom(mBLASData.L3_cGEMM_o_TT);
+        verifyMatrix(matrixCRef, matrixCC);
+
+        transA = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
+        transB = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
+        matrixCC.copyFrom(mBLASData.L3_cGEMM_C_mn);
+        mBLAS.CGEMM(transA, transB, alphaC, matrixAC, matrixBC, betaC, matrixCC);
+        matrixCRef.copyFrom(mBLASData.L3_cGEMM_o_HH);
+        verifyMatrix(matrixCRef, matrixCC);
+
+        mRS.finish();
+        checkError();
+    }
+
+    public void test_L3_ZGEMM_Correctness() {
+        int transA = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        int transB = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+
+        // Populate input allocations
+        Allocation matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dK, mBLASData.dM));
+        Allocation matrixBZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dK));
+        Allocation matrixCZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dM));
+        matrixAZ.copyFrom(mBLASData.L3_zGEMM_A_mk);
+        matrixBZ.copyFrom(mBLASData.L3_zGEMM_B_kn);
+        matrixCZ.copyFrom(mBLASData.L3_zGEMM_C_mn);
+
+        // Test for the default case: NO_TRANS
+        mBLAS.ZGEMM(transA, transB, alphaZ, matrixAZ, matrixBZ, betaZ, matrixCZ);
+        Allocation matrixCRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dM));
+        matrixCRef.copyFrom(mBLASData.L3_zGEMM_o_NN);
+        verifyMatrix(matrixCRef, matrixCZ);
+
+        // Test for trans cases: TRANSPOSE, CONJ_TRANSPOSE
+        matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dM, mBLASData.dK));
+        matrixBZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dK, mBLASData.dN));
+        matrixAZ.copyFrom(mBLASData.L3_zGEMM_A_km);
+        matrixBZ.copyFrom(mBLASData.L3_zGEMM_B_nk);
+
+        transA = ScriptIntrinsicBLAS.TRANSPOSE;
+        transB = ScriptIntrinsicBLAS.TRANSPOSE;
+        // Reload matrix C, since it was overwritten by BLAS.
+        matrixCZ.copyFrom(mBLASData.L3_zGEMM_C_mn);
+        mBLAS.ZGEMM(transA, transB, alphaZ, matrixAZ, matrixBZ, betaZ, matrixCZ);
+        matrixCRef.copyFrom(mBLASData.L3_zGEMM_o_TT);
+        verifyMatrix(matrixCRef, matrixCZ);
+
+        transA = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
+        transB = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
+        matrixCZ.copyFrom(mBLASData.L3_zGEMM_C_mn);
+        mBLAS.ZGEMM(transA, transB, alphaZ, matrixAZ, matrixBZ, betaZ, matrixCZ);
+        matrixCRef.copyFrom(mBLASData.L3_zGEMM_o_HH);
+        verifyMatrix(matrixCRef, matrixCZ);
+
+        mRS.finish();
+        checkError();
+    }
+
+
+
+    private boolean validateL3_xSYMM(Element e, int Side, int Uplo, Allocation A, Allocation B, Allocation C) {
+        boolean result = true;
+        result &= validateSide(Side);
+        result &= validateUplo(Uplo);
+        result &= validateL3(e, 0, 0, Side, A, B, C);
+        result &= (A.getType().getX() == A.getType().getY());
+        return result;
+    }
+
+    private void xSYMM_API_test(int Side, int Uplo, ArrayList<Allocation> mMatrix) {
+        for (Allocation matA : mMatrix) {
+            for (Allocation matB : mMatrix) {
+                for (Allocation matC : mMatrix) {
+                    Element elemA = matA.getType().getElement();
+                    if (validateL3_xSYMM(elemA, Side, Uplo, matA, matB, matC)) {
+                        try {
+                            if (elemA.isCompatible(Element.F32(mRS))) {
+                                mBLAS.SSYMM(Side, Uplo, alphaS, matA, matB, betaS, matC);
+                            } else if (elemA.isCompatible(Element.F64(mRS))) {
+                                mBLAS.DSYMM(Side, Uplo, alphaD, matA, matB, betaD, matC);
+                            } else if (elemA.isCompatible(Element.F32_2(mRS))) {
+                                mBLAS.CSYMM(Side, Uplo, alphaC, matA, matB, betaC, matC);
+                            } else if (elemA.isCompatible(Element.F64_2(mRS))) {
+                                mBLAS.ZSYMM(Side, Uplo, alphaZ, matA, matB, betaZ, matC);
+                            }
+                        } catch (RSRuntimeException e) {
+                            fail("should NOT throw RSRuntimeException");
+                        }
+                    } else {
+                        try {
+                            mBLAS.SSYMM(Side, Uplo, alphaS, matA, matB, betaS, matC);
+                            fail("should throw RSRuntimeException for SSYMM");
+                        } catch (RSRuntimeException e) {
+                        }
+                        try {
+                            mBLAS.DSYMM(Side, Uplo, alphaD, matA, matB, betaD, matC);
+                            fail("should throw RSRuntimeException for DSYMM");
+                        } catch (RSRuntimeException e) {
+                        }
+                        try {
+                            mBLAS.CSYMM(Side, Uplo, alphaC, matA, matB, betaC, matC);
+                            fail("should throw RSRuntimeException for CSYMM");
+                        } catch (RSRuntimeException e) {
+                        }
+                        try {
+                            mBLAS.ZSYMM(Side, Uplo, alphaZ, matA, matB, betaZ, matC);
+                            fail("should throw RSRuntimeException for ZSYMM");
+                        } catch (RSRuntimeException e) {
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    private void L3_xSYMM_API(ArrayList<Allocation> mMatrix) {
+        for (int Side : mSide) {
+            for (int Uplo : mUplo) {
+                xSYMM_API_test(Side, Uplo, mMatrix);
+            }
+        }
+    }
+
+    public void test_L3_SSYMM_API() {
+        L3_xSYMM_API(mMatrixS);
+    }
+
+    public void test_L3_DSYMM_API() {
+        L3_xSYMM_API(mMatrixD);
+    }
+
+    public void test_L3_CSYMM_API() {
+        L3_xSYMM_API(mMatrixC);
+    }
+
+    public void test_L3_ZSYMM_API() {
+        L3_xSYMM_API(mMatrixZ);
+    }
+
+
+    public void test_L3_SSYMM_Correctness() {
+        int side = ScriptIntrinsicBLAS.LEFT;
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+
+        // Populate input allocations
+        Allocation matrixAS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dM, mBLASData.dM));
+        Allocation matrixBS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dM));
+        Allocation matrixCS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dM));
+        matrixAS.copyFrom(mBLASData.L3_sSYMM_A_mm);
+        matrixBS.copyFrom(mBLASData.L3_sSYMM_B_mn);
+        matrixCS.copyFrom(mBLASData.L3_sSYMM_C_mn);
+
+        // Default case: SIDE = LEFT
+        mBLAS.SSYMM(side, uplo, alphaS, matrixAS, matrixBS, betaS, matrixCS);
+        Allocation matrixCRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dM));
+        matrixCRef.copyFrom(mBLASData.L3_sSYMM_o_L);
+        verifyMatrix(matrixCRef, matrixCS);
+
+        // SIDE = RIGHT
+        side = ScriptIntrinsicBLAS.RIGHT;
+        matrixAS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dN));
+        matrixAS.copyFrom(mBLASData.L3_sSYMM_A_nn);
+        // Reload matrix C, since it was overwritten by BLAS.
+        matrixCS.copyFrom(mBLASData.L3_sSYMM_C_mn);
+        mBLAS.SSYMM(side, uplo, alphaS, matrixAS, matrixBS, betaS, matrixCS);
+        matrixCRef.copyFrom(mBLASData.L3_sSYMM_o_R);
+        verifyMatrix(matrixCRef, matrixCS);
+
+        mRS.finish();
+        checkError();
+    }
+
+    public void test_L3_DSYMM_Correctness() {
+        int side = ScriptIntrinsicBLAS.LEFT;
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+
+        // Populate input allocations
+        Allocation matrixAD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dM, mBLASData.dM));
+        Allocation matrixBD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dM));
+        Allocation matrixCD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dM));
+        matrixAD.copyFrom(mBLASData.L3_dSYMM_A_mm);
+        matrixBD.copyFrom(mBLASData.L3_dSYMM_B_mn);
+        matrixCD.copyFrom(mBLASData.L3_dSYMM_C_mn);
+
+        // Default case: SIDE = LEFT
+        mBLAS.DSYMM(side, uplo, alphaD, matrixAD, matrixBD, betaD, matrixCD);
+        Allocation matrixCRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dM));
+        matrixCRef.copyFrom(mBLASData.L3_dSYMM_o_L);
+        verifyMatrix(matrixCRef, matrixCD);
+
+        // SIDE = RIGHT
+        side = ScriptIntrinsicBLAS.RIGHT;
+        matrixAD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dN));
+        matrixAD.copyFrom(mBLASData.L3_dSYMM_A_nn);
+        // Reload matrix C, since it was overwritten by BLAS.
+        matrixCD.copyFrom(mBLASData.L3_dSYMM_C_mn);
+        mBLAS.DSYMM(side, uplo, alphaD, matrixAD, matrixBD, betaD, matrixCD);
+        matrixCRef.copyFrom(mBLASData.L3_dSYMM_o_R);
+        verifyMatrix(matrixCRef, matrixCD);
+
+        mRS.finish();
+        checkError();
+    }
+
+    public void test_L3_CSYMM_Correctness() {
+        int side = ScriptIntrinsicBLAS.LEFT;
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+
+        // Populate input allocations
+        Allocation matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dM, mBLASData.dM));
+        Allocation matrixBC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dM));
+        Allocation matrixCC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dM));
+        matrixAC.copyFrom(mBLASData.L3_cSYMM_A_mm);
+        matrixBC.copyFrom(mBLASData.L3_cSYMM_B_mn);
+        matrixCC.copyFrom(mBLASData.L3_cSYMM_C_mn);
+
+        // Default case: SIDE = LEFT
+        mBLAS.CSYMM(side, uplo, alphaC, matrixAC, matrixBC, betaC, matrixCC);
+        Allocation matrixCRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dM));
+        matrixCRef.copyFrom(mBLASData.L3_cSYMM_o_L);
+        verifyMatrix(matrixCRef, matrixCC);
+
+        // SIDE = RIGHT
+        side = ScriptIntrinsicBLAS.RIGHT;
+        matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dN));
+        matrixAC.copyFrom(mBLASData.L3_cSYMM_A_nn);
+        // Reload matrix C, since it was overwritten by BLAS.
+        matrixCC.copyFrom(mBLASData.L3_cSYMM_C_mn);
+        mBLAS.CSYMM(side, uplo, alphaC, matrixAC, matrixBC, betaC, matrixCC);
+        matrixCRef.copyFrom(mBLASData.L3_cSYMM_o_R);
+        verifyMatrix(matrixCRef, matrixCC);
+
+        mRS.finish();
+        checkError();
+    }
+
+    public void test_L3_ZSYMM_Correctness() {
+        int side = ScriptIntrinsicBLAS.LEFT;
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+
+        // Populate input allocations
+        Allocation matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dM, mBLASData.dM));
+        Allocation matrixBZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dM));
+        Allocation matrixCZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dM));
+        matrixAZ.copyFrom(mBLASData.L3_zSYMM_A_mm);
+        matrixBZ.copyFrom(mBLASData.L3_zSYMM_B_mn);
+        matrixCZ.copyFrom(mBLASData.L3_zSYMM_C_mn);
+
+        // Default case: SIDE = LEFT
+        mBLAS.ZSYMM(side, uplo, alphaZ, matrixAZ, matrixBZ, betaZ, matrixCZ);
+        Allocation matrixCRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dM));
+        matrixCRef.copyFrom(mBLASData.L3_zSYMM_o_L);
+        verifyMatrix(matrixCRef, matrixCZ);
+
+        // SIDE = RIGHT
+        side = ScriptIntrinsicBLAS.RIGHT;
+        matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dN));
+        matrixAZ.copyFrom(mBLASData.L3_zSYMM_A_nn);
+        // Reload matrix C, since it was overwritten by BLAS.
+        matrixCZ.copyFrom(mBLASData.L3_zSYMM_C_mn);
+        mBLAS.ZSYMM(side, uplo, alphaZ, matrixAZ, matrixBZ, betaZ, matrixCZ);
+        matrixCRef.copyFrom(mBLASData.L3_zSYMM_o_R);
+        verifyMatrix(matrixCRef, matrixCZ);
+
+        mRS.finish();
+        checkError();
+    }
+
+
+    private boolean validateHEMM(Element e, int Side, int Uplo, Allocation A, Allocation B, Allocation C) {
+        if (!validateSide(Side)) {
+            return false;
+        }
+
+        if (!validateUplo(Uplo)) {
+            return false;
+        }
+
+        if (!A.getType().getElement().isCompatible(e) ||
+            !B.getType().getElement().isCompatible(e) ||
+            !C.getType().getElement().isCompatible(e)) {
+            return false;
+        }
+
+        // A must be square; can potentially be relaxed similar to TRSM
+        int adim = A.getType().getX();
+        if (adim != A.getType().getY()) {
+            return false;
+        }
+        if ((Side == ScriptIntrinsicBLAS.LEFT && adim != B.getType().getY()) ||
+            (Side == ScriptIntrinsicBLAS.RIGHT && adim != B.getType().getX())) {
+            return false;
+        }
+        if (B.getType().getX() != C.getType().getX() ||
+            B.getType().getY() != C.getType().getY()) {
+            return false;
+        }
+
+        return true;
+    }
+
+    private void xHEMM_API_test(int Side, int Uplo, ArrayList<Allocation> mMatrix) {
+        for (Allocation matA : mMatrix) {
+            for (Allocation matB : mMatrix) {
+                for (Allocation matC : mMatrix) {
+                    Element elemA = matA.getType().getElement();
+                    if (validateHEMM(elemA, Side, Uplo, matA, matB, matC)) {
+                        try {
+                            if (elemA.isCompatible(Element.F32_2(mRS))) {
+                                mBLAS.CHEMM(Side, Uplo, alphaC, matA, matB, betaC, matC);
+                            } else if (elemA.isCompatible(Element.F64_2(mRS))) {
+                                mBLAS.ZHEMM(Side, Uplo, alphaZ, matA, matB, betaZ, matC);
+                            }
+                        } catch (RSRuntimeException e) {
+                            fail("should NOT throw RSRuntimeException");
+                        }
+                    } else {
+                        try {
+                            mBLAS.CHEMM(Side, Uplo, alphaC, matA, matB, betaC, matC);
+                            fail("should throw RSRuntimeException for CHEMM");
+                        } catch (RSRuntimeException e) {
+                        }
+                        try {
+                            mBLAS.ZHEMM(Side, Uplo, alphaZ, matA, matB, betaZ, matC);
+                            fail("should throw RSRuntimeException for ZHEMM");
+                        } catch (RSRuntimeException e) {
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    public void L3_xHEMM_API(ArrayList<Allocation> mMatrix) {
+        for (int Side : mSide) {
+            for (int Uplo : mUplo) {
+                xHEMM_API_test(Side, Uplo, mMatrix);
+            }
+        }
+    }
+
+    public void test_L3_CHEMM_API() {
+        L3_xHEMM_API(mMatrixC);
+    }
+
+    public void test_L3_ZHEMM_API() {
+        L3_xHEMM_API(mMatrixZ);
+    }
+
+    public void test_L3_CHEMM_Correctness() {
+        int side = ScriptIntrinsicBLAS.LEFT;
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+
+        // Populate input allocations
+        Allocation matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dM, mBLASData.dM));
+        Allocation matrixBC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dM));
+        Allocation matrixCC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dM));
+        matrixAC.copyFrom(mBLASData.L3_cHEMM_A_mm);
+        matrixBC.copyFrom(mBLASData.L3_cHEMM_B_mn);
+        matrixCC.copyFrom(mBLASData.L3_cHEMM_C_mn);
+
+        // Default case: SIDE = LEFT
+        mBLAS.CHEMM(side, uplo, alphaC, matrixAC, matrixBC, betaC, matrixCC);
+        Allocation matrixCRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dM));
+        matrixCRef.copyFrom(mBLASData.L3_cHEMM_o_L);
+        verifyMatrix(matrixCRef, matrixCC);
+
+        // SIDE = RIGHT
+        side = ScriptIntrinsicBLAS.RIGHT;
+        matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dN));
+        matrixAC.copyFrom(mBLASData.L3_cHEMM_A_nn);
+        // Reload matrix C, since it was overwritten by BLAS.
+        matrixCC.copyFrom(mBLASData.L3_cHEMM_C_mn);
+        mBLAS.CHEMM(side, uplo, alphaC, matrixAC, matrixBC, betaC, matrixCC);
+        matrixCRef.copyFrom(mBLASData.L3_cHEMM_o_R);
+        verifyMatrix(matrixCRef, matrixCC);
+
+        mRS.finish();
+        checkError();
+    }
+
+    public void test_L3_ZHEMM_Correctness() {
+        int side = ScriptIntrinsicBLAS.LEFT;
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+
+        // Populate input allocations
+        Allocation matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dM, mBLASData.dM));
+        Allocation matrixBZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dM));
+        Allocation matrixCZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dM));
+        matrixAZ.copyFrom(mBLASData.L3_zHEMM_A_mm);
+        matrixBZ.copyFrom(mBLASData.L3_zHEMM_B_mn);
+        matrixCZ.copyFrom(mBLASData.L3_zHEMM_C_mn);
+
+        // Default case: SIDE = LEFT
+        mBLAS.ZHEMM(side, uplo, alphaZ, matrixAZ, matrixBZ, betaZ, matrixCZ);
+        Allocation matrixCRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dM));
+        matrixCRef.copyFrom(mBLASData.L3_zHEMM_o_L);
+        verifyMatrix(matrixCRef, matrixCZ);
+
+        // SIDE = RIGHT
+        side = ScriptIntrinsicBLAS.RIGHT;
+        matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dN));
+        matrixAZ.copyFrom(mBLASData.L3_zHEMM_A_nn);
+        // Reload matrix C, since it was overwritten by BLAS.
+        matrixCZ.copyFrom(mBLASData.L3_zHEMM_C_mn);
+        mBLAS.ZHEMM(side, uplo, alphaZ, matrixAZ, matrixBZ, betaZ, matrixCZ);
+        matrixCRef.copyFrom(mBLASData.L3_zHEMM_o_R);
+        verifyMatrix(matrixCRef, matrixCZ);
+
+        mRS.finish();
+        checkError();
+    }
+
+
+
+    private boolean validateL3_xSYRK(Element e, int Uplo, int Trans, Allocation A, Allocation C) {
+        boolean result = true;
+        result &= validateTranspose(Trans);
+        result &= validateUplo(Uplo);
+        result &= validateL3(e, Trans, 0, 0, A, null, C);
+
+        return result;
+    }
+
+    private void xSYRK_API_test(int Uplo, int Trans, ArrayList<Allocation> mMatrix) {
+        for (Allocation matA : mMatrix) {
+            for (Allocation matC : mMatrix) {
+                Element elemA = matA.getType().getElement();
+                if (validateL3_xSYRK(elemA, Uplo, Trans, matA, matC)) {
+                    try {
+                        if (elemA.isCompatible(Element.F32(mRS))) {
+                            mBLAS.SSYRK(Uplo, Trans, alphaS, matA, betaS, matC);
+                        } else if (elemA.isCompatible(Element.F64(mRS))) {
+                            mBLAS.DSYRK(Uplo, Trans, alphaD, matA, betaD, matC);
+                        } else if (elemA.isCompatible(Element.F32_2(mRS))) {
+                            mBLAS.CSYRK(Uplo, Trans, alphaC, matA, betaC, matC);
+                        } else if (elemA.isCompatible(Element.F64_2(mRS))) {
+                            mBLAS.ZSYRK(Uplo, Trans, alphaZ, matA, betaZ, matC);
+                        }
+                    } catch (RSRuntimeException e) {
+                        fail("should NOT throw RSRuntimeException");
+                    }
+                } else {
+                    try {
+                        mBLAS.SSYRK(Uplo, Trans, alphaS, matA, betaS, matC);
+                        fail("should throw RSRuntimeException for SSYRK");
+                    } catch (RSRuntimeException e) {
+                    }
+                    try {
+                        mBLAS.DSYRK(Uplo, Trans, alphaD, matA, betaD, matC);
+                        fail("should throw RSRuntimeException for DSYRK");
+                    } catch (RSRuntimeException e) {
+                    }
+                    try {
+                        mBLAS.CSYRK(Uplo, Trans, alphaC, matA, betaC, matC);
+                        fail("should throw RSRuntimeException for CSYRK");
+                    } catch (RSRuntimeException e) {
+                    }
+                    try {
+                        mBLAS.ZSYRK(Uplo, Trans, alphaZ, matA, betaZ, matC);
+                        fail("should throw RSRuntimeException for ZSYRK");
+                    } catch (RSRuntimeException e) {
+                    }
+                }
+            }
+        }
+    }
+
+    public void L3_xSYRK_API(ArrayList<Allocation> mMatrix) {
+        for (int Uplo : mUplo) {
+            for (int Trans : mTranspose) {
+                xSYRK_API_test(Uplo, Trans, mMatrix);
+            }
+        }
+    }
+
+    public void test_L3_SSYRK_API() {
+        L3_xSYRK_API(mMatrixS);
+    }
+
+    public void test_L3_DSYRK_API() {
+        L3_xSYRK_API(mMatrixD);
+    }
+
+    public void test_L3_CSYRK_API() {
+        L3_xSYRK_API(mMatrixC);
+    }
+
+    public void test_L3_ZSYRK_API() {
+        L3_xSYRK_API(mMatrixZ);
+    }
+
+
+    public void test_L3_SSYRK_Correctness() {
+        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+
+        // Populate input allocations
+        Allocation matrixAS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dK, mBLASData.dN));
+        Allocation matrixCS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dN));
+        matrixAS.copyFrom(mBLASData.L3_sSYRK_A_nk);
+        matrixCS.copyFrom(mBLASData.L3_sSYRK_C_nn);
+
+        // Default case: NO_TRANSPOSE
+        mBLAS.SSYRK(uplo, trans, alphaS, matrixAS, betaS, matrixCS);
+        Allocation matrixCRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dN));
+        matrixCRef.copyFrom(mBLASData.L3_sSYRK_o_N);
+        verifyMatrix(matrixCRef, matrixCS, true);
+
+        // Case: TRANSPOSE
+        matrixAS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dK));
+        matrixAS.copyFrom(mBLASData.L3_sSYRK_A_kn);
+        // Reload matrix C, since it was overwritten by BLAS.
+        matrixCS.copyFrom(mBLASData.L3_sSYRK_C_nn);
+
+        trans = ScriptIntrinsicBLAS.TRANSPOSE;
+        mBLAS.SSYRK(uplo, trans, alphaS, matrixAS, betaS, matrixCS);
+        matrixCRef.copyFrom(mBLASData.L3_sSYRK_o_T);
+        verifyMatrix(matrixCRef, matrixCS, true);
+
+        mRS.finish();
+        checkError();
+    }
+
+    public void test_L3_DSYRK_Correctness() {
+        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+
+        // Populate input allocations
+        Allocation matrixAD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dK, mBLASData.dN));
+        Allocation matrixCD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dN));
+        matrixAD.copyFrom(mBLASData.L3_dSYRK_A_nk);
+        matrixCD.copyFrom(mBLASData.L3_dSYRK_C_nn);
+
+        // Default case: NO_TRANSPOSE
+        mBLAS.DSYRK(uplo, trans, alphaD, matrixAD, betaD, matrixCD);
+        Allocation matrixCRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dN));
+        matrixCRef.copyFrom(mBLASData.L3_dSYRK_o_N);
+        verifyMatrix(matrixCRef, matrixCD, true);
+
+        // Case: TRANSPOSE
+        matrixAD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dK));
+        matrixAD.copyFrom(mBLASData.L3_dSYRK_A_kn);
+        // Reload matrix C, since it was overwritten by BLAS.
+        matrixCD.copyFrom(mBLASData.L3_dSYRK_C_nn);
+
+        trans = ScriptIntrinsicBLAS.TRANSPOSE;
+        mBLAS.DSYRK(uplo, trans, alphaD, matrixAD, betaD, matrixCD);
+        matrixCRef.copyFrom(mBLASData.L3_dSYRK_o_T);
+        verifyMatrix(matrixCRef, matrixCD, true);
+
+        mRS.finish();
+        checkError();
+    }
+
+    public void test_L3_CSYRK_Correctness() {
+        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+
+        // Populate input allocations
+        Allocation matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dK, mBLASData.dN));
+        Allocation matrixCC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dN));
+        matrixAC.copyFrom(mBLASData.L3_cSYRK_A_nk);
+        matrixCC.copyFrom(mBLASData.L3_cSYRK_C_nn);
+
+        // Default case: NO_TRANSPOSE
+        mBLAS.CSYRK(uplo, trans, alphaC, matrixAC, betaC, matrixCC);
+        Allocation matrixCRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dN));
+        matrixCRef.copyFrom(mBLASData.L3_cSYRK_o_N);
+        verifyMatrix(matrixCRef, matrixCC, true);
+
+        // Case: TRANSPOSE
+        matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dK));
+        matrixAC.copyFrom(mBLASData.L3_cSYRK_A_kn);
+        // Reload matrix C, since it was overwritten by BLAS.
+        matrixCC.copyFrom(mBLASData.L3_cSYRK_C_nn);
+
+        trans = ScriptIntrinsicBLAS.TRANSPOSE;
+        mBLAS.CSYRK(uplo, trans, alphaC, matrixAC, betaC, matrixCC);
+        matrixCRef.copyFrom(mBLASData.L3_cSYRK_o_T);
+        verifyMatrix(matrixCRef, matrixCC, true);
+
+        mRS.finish();
+        checkError();
+    }
+
+    public void test_L3_ZSYRK_Correctness() {
+        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+
+        // Populate input allocations
+        Allocation matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dK, mBLASData.dN));
+        Allocation matrixCZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dN));
+        matrixAZ.copyFrom(mBLASData.L3_zSYRK_A_nk);
+        matrixCZ.copyFrom(mBLASData.L3_zSYRK_C_nn);
+
+        // Default case: NO_TRANSPOSE
+        mBLAS.ZSYRK(uplo, trans, alphaZ, matrixAZ, betaZ, matrixCZ);
+        Allocation matrixCRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dN));
+        matrixCRef.copyFrom(mBLASData.L3_zSYRK_o_N);
+        verifyMatrix(matrixCRef, matrixCZ, true);
+
+        // Case: TRANSPOSE
+        matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dK));
+        matrixAZ.copyFrom(mBLASData.L3_zSYRK_A_kn);
+        // Reload matrix C, since it was overwritten by BLAS.
+        matrixCZ.copyFrom(mBLASData.L3_zSYRK_C_nn);
+
+        trans = ScriptIntrinsicBLAS.TRANSPOSE;
+        mBLAS.ZSYRK(uplo, trans, alphaZ, matrixAZ, betaZ, matrixCZ);
+        matrixCRef.copyFrom(mBLASData.L3_zSYRK_o_T);
+        verifyMatrix(matrixCRef, matrixCZ, true);
+
+        mRS.finish();
+        checkError();
+    }
+
+
+    private boolean validateHERK(Element e, int Uplo, int Trans, Allocation A, Allocation C) {
+        if (!validateUplo(Uplo)) {
+            return false;
+        }
+        if (!A.getType().getElement().isCompatible(e) ||
+            !C.getType().getElement().isCompatible(e)) {
+            return false;
+        }
+        if (!validateConjTranspose(Trans)) {
+            return false;
+        }
+        int cdim = C.getType().getX();
+        if (cdim != C.getType().getY()) {
+            return false;
+        }
+        if (Trans == ScriptIntrinsicBLAS.NO_TRANSPOSE) {
+            if (cdim != A.getType().getY()) {
+                return false;
+            }
+        } else {
+            if (cdim != A.getType().getX()) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private void xHERK_API_test(int Uplo, int Trans, ArrayList<Allocation> mMatrix) {
+        for (Allocation matA : mMatrix) {
+            for (Allocation matC : mMatrix) {
+                Element elemA = matA.getType().getElement();
+                if (validateHERK(elemA, Uplo, Trans, matA, matC)) {
+                    try {
+                        if (elemA.isCompatible(Element.F32_2(mRS))) {
+                            mBLAS.CHERK(Uplo, Trans, alphaS, matA, betaS, matC);
+                        } else if (elemA.isCompatible(Element.F64_2(mRS))) {
+                            mBLAS.ZHERK(Uplo, Trans, alphaD, matA, betaD, matC);
+                        }
+                    } catch (RSRuntimeException e) {
+                        fail("should NOT throw RSRuntimeException");
+                    }
+                } else {
+                    try {
+                        mBLAS.CHERK(Uplo, Trans, alphaS, matA, betaS, matC);
+                        fail("should throw RSRuntimeException for CHERK");
+                    } catch (RSRuntimeException e) {
+                    }
+                    try {
+                        mBLAS.ZHERK(Uplo, Trans, alphaD, matA, betaD, matC);
+                        fail("should throw RSRuntimeException for ZHERK");
+                    } catch (RSRuntimeException e) {
+                    }
+                }
+            }
+        }
+    }
+
+    public void L3_xHERK_API(ArrayList<Allocation> mMatrix) {
+        for (int Uplo : mUplo) {
+            for (int Trans : mTranspose) {
+                xHERK_API_test(Uplo, Trans, mMatrix);
+            }
+        }
+    }
+
+    public void test_L3_CHERK_API() {
+        L3_xHERK_API(mMatrixC);
+    }
+
+    public void test_L3_ZHERK_API() {
+        L3_xHERK_API(mMatrixZ);
+    }
+
+    public void test_L3_CHERK_Correctness() {
+        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+
+        // Populate input allocations
+        Allocation matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dK, mBLASData.dN));
+        Allocation matrixCC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dN));
+        matrixAC.copyFrom(mBLASData.L3_cHERK_A_nk);
+        matrixCC.copyFrom(mBLASData.L3_cHERK_C_nn);
+
+        // Default case: NO_TRANSPOSE
+        mBLAS.CHERK(uplo, trans, alphaS, matrixAC, betaS, matrixCC);
+        Allocation matrixCRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dN));
+        matrixCRef.copyFrom(mBLASData.L3_cHERK_o_N);
+        verifyMatrix(matrixCRef, matrixCC, true);
+
+        // Case: TRANSPOSE
+        matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dK));
+        matrixAC.copyFrom(mBLASData.L3_cHERK_A_kn);
+        // Reload matrix C, since it was overwritten by BLAS.
+        matrixCC.copyFrom(mBLASData.L3_cHERK_C_nn);
+
+        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
+        mBLAS.CHERK(uplo, trans, alphaS, matrixAC, betaS, matrixCC);
+        matrixCRef.copyFrom(mBLASData.L3_cHERK_o_H);
+        verifyMatrix(matrixCRef, matrixCC, true);
+
+        mRS.finish();
+        checkError();
+    }
+
+    public void test_L3_ZHERK_Correctness() {
+        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+
+        // Populate input allocations
+        Allocation matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dK, mBLASData.dN));
+        Allocation matrixCZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dN));
+        matrixAZ.copyFrom(mBLASData.L3_zHERK_A_nk);
+        matrixCZ.copyFrom(mBLASData.L3_zHERK_C_nn);
+
+        // Default case: NO_TRANSPOSE
+        mBLAS.ZHERK(uplo, trans, alphaD, matrixAZ, betaD, matrixCZ);
+        Allocation matrixCRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dN));
+        matrixCRef.copyFrom(mBLASData.L3_zHERK_o_N);
+        verifyMatrix(matrixCRef, matrixCZ, true);
+
+        // Case: TRANSPOSE
+        matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dK));
+        matrixAZ.copyFrom(mBLASData.L3_zHERK_A_kn);
+        // Reload matrix C, since it was overwritten by BLAS.
+        matrixCZ.copyFrom(mBLASData.L3_zHERK_C_nn);
+
+        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
+        mBLAS.ZHERK(uplo, trans, alphaD, matrixAZ, betaD, matrixCZ);
+        matrixCRef.copyFrom(mBLASData.L3_zHERK_o_H);
+        verifyMatrix(matrixCRef, matrixCZ, true);
+
+        mRS.finish();
+        checkError();
+    }
+
+
+    private boolean validateSYR2K(Element e, int Uplo, int Trans, Allocation A, Allocation B, Allocation C) {
+        if (!validateTranspose(Trans)) {
+            return false;
+        }
+        if (!validateUplo(Uplo)) {
+            return false;
+        }
+
+        if (!A.getType().getElement().isCompatible(e) ||
+            !B.getType().getElement().isCompatible(e) ||
+            !C.getType().getElement().isCompatible(e)) {
+            return false;
+        }
+        int Cdim = -1;
+        // A is n x k if no transpose, k x n if transpose
+        // C is n x n
+        if (Trans == ScriptIntrinsicBLAS.TRANSPOSE) {
+            // check columns versus C
+            Cdim = A.getType().getX();
+        } else {
+            // check rows versus C
+            Cdim = A.getType().getY();
+        }
+        if (C.getType().getX() != Cdim || C.getType().getY() != Cdim) {
+            return false;
+        }
+        // A dims == B dims
+        if (A.getType().getX() != B.getType().getX() || A.getType().getY() != B.getType().getY()) {
+            return false;
+        }
+        return true;
+    }
+
+    private void xSYR2K_API_test(int Uplo, int Trans, ArrayList<Allocation> mMatrix) {
+        for (Allocation matA : mMatrix) {
+            for (Allocation matB : mMatrix) {
+                for (Allocation matC : mMatrix) {
+                    Element elemA = matA.getType().getElement();
+                    if (validateSYR2K(elemA, Uplo, Trans, matA, matB, matC)) {
+                        try {
+                            if (elemA.isCompatible(Element.F32(mRS))) {
+                                mBLAS.SSYR2K(Uplo, Trans, alphaS, matA, matB, betaS, matC);
+                            } else if (elemA.isCompatible(Element.F64(mRS))) {
+                                mBLAS.DSYR2K(Uplo, Trans, alphaD, matA, matB, betaD, matC);
+                            } else if (elemA.isCompatible(Element.F32_2(mRS))) {
+                                mBLAS.CSYR2K(Uplo, Trans, alphaC, matA, matB, betaC, matC);
+                            } else if (elemA.isCompatible(Element.F64_2(mRS))) {
+                                mBLAS.ZSYR2K(Uplo, Trans, alphaZ, matA, matB, betaZ, matC);
+                            }
+                        } catch (RSRuntimeException e) {
+                            fail("should NOT throw RSRuntimeException");
+                        }
+                    } else {
+                        try {
+                            mBLAS.SSYR2K(Uplo, Trans, alphaS, matA, matB, betaS, matC);
+                            fail("should throw RSRuntimeException for SSYR2K");
+                        } catch (RSRuntimeException e) {
+                        }
+                        try {
+                            mBLAS.DSYR2K(Uplo, Trans, alphaD, matA, matB, betaD, matC);
+                            fail("should throw RSRuntimeException for DSYR2K");
+                        } catch (RSRuntimeException e) {
+                        }
+                        try {
+                            mBLAS.CSYR2K(Uplo, Trans, alphaC, matA, matB, betaC, matC);
+                            fail("should throw RSRuntimeException for CSYR2K");
+                        } catch (RSRuntimeException e) {
+                        }
+                        try {
+                            mBLAS.ZSYR2K(Uplo, Trans, alphaZ, matA, matB, betaZ, matC);
+                            fail("should throw RSRuntimeException for ZSYR2K");
+                        } catch (RSRuntimeException e) {
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    public void L3_xSYR2K_API(ArrayList<Allocation> mMatrix) {
+        for (int Uplo : mUplo) {
+            for (int Trans : mTranspose) {
+                xSYR2K_API_test(Uplo, Trans, mMatrix);
+            }
+        }
+    }
+
+    public void test_L3_SSYR2K_API() {
+        L3_xSYR2K_API(mMatrixS);
+    }
+
+    public void test_L3_DSYR2K_API() {
+        L3_xSYR2K_API(mMatrixD);
+    }
+
+    public void test_L3_CSYR2K_API() {
+        L3_xSYR2K_API(mMatrixC);
+    }
+
+    public void test_L3_ZSYR2K_API() {
+        L3_xSYR2K_API(mMatrixZ);
+    }
+
+
+    public void test_L3_SSYR2K_Correctness() {
+        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+
+        // Populate input allocations
+        Allocation matrixAS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dK, mBLASData.dN));
+        Allocation matrixBS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dK, mBLASData.dN));
+        Allocation matrixCS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dN));
+        matrixAS.copyFrom(mBLASData.L3_sSYR2K_A_nk);
+        matrixBS.copyFrom(mBLASData.L3_sSYR2K_B_nk);
+        matrixCS.copyFrom(mBLASData.L3_sSYR2K_C_nn);
+
+        // Default case: NO_TRANSPOSE
+        mBLAS.SSYR2K(uplo, trans, alphaS, matrixAS, matrixBS, betaS, matrixCS);
+        Allocation matrixCRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dN));
+        matrixCRef.copyFrom(mBLASData.L3_sSYR2K_o_N);
+        verifyMatrix(matrixCRef, matrixCS, true);
+
+        // Case: TRANSPOSE
+        matrixAS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dK));
+        matrixBS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dK));
+        matrixAS.copyFrom(mBLASData.L3_sSYR2K_A_kn);
+        matrixBS.copyFrom(mBLASData.L3_sSYR2K_B_kn);
+        // Reload matrix C, since it was overwritten by BLAS.
+        matrixCS.copyFrom(mBLASData.L3_sSYR2K_C_nn);
+
+        trans = ScriptIntrinsicBLAS.TRANSPOSE;
+        mBLAS.SSYR2K(uplo, trans, alphaS, matrixAS, matrixBS, betaS, matrixCS);
+        matrixCRef.copyFrom(mBLASData.L3_sSYR2K_o_T);
+        verifyMatrix(matrixCRef, matrixCS, true);
+
+        mRS.finish();
+        checkError();
+    }
+
+    public void test_L3_DSYR2K_Correctness() {
+        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+
+        // Populate input allocations
+        Allocation matrixAD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dK, mBLASData.dN));
+        Allocation matrixBD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dK, mBLASData.dN));
+        Allocation matrixCD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dN));
+        matrixAD.copyFrom(mBLASData.L3_dSYR2K_A_nk);
+        matrixBD.copyFrom(mBLASData.L3_dSYR2K_B_nk);
+        matrixCD.copyFrom(mBLASData.L3_dSYR2K_C_nn);
+
+        // Default case: NO_TRANSPOSE
+        mBLAS.DSYR2K(uplo, trans, alphaD, matrixAD, matrixBD, betaD, matrixCD);
+        Allocation matrixCRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dN));
+        matrixCRef.copyFrom(mBLASData.L3_dSYR2K_o_N);
+        verifyMatrix(matrixCRef, matrixCD, true);
+
+        // Case: TRANSPOSE
+        matrixAD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dK));
+        matrixBD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dK));
+        matrixAD.copyFrom(mBLASData.L3_dSYR2K_A_kn);
+        matrixBD.copyFrom(mBLASData.L3_dSYR2K_B_kn);
+        // Reload matrix C, since it was overwritten by BLAS.
+        matrixCD.copyFrom(mBLASData.L3_dSYR2K_C_nn);
+
+        trans = ScriptIntrinsicBLAS.TRANSPOSE;
+        mBLAS.DSYR2K(uplo, trans, alphaD, matrixAD, matrixBD, betaD, matrixCD);
+        matrixCRef.copyFrom(mBLASData.L3_dSYR2K_o_T);
+        verifyMatrix(matrixCRef, matrixCD, true);
+
+        mRS.finish();
+        checkError();
+    }
+
+    public void test_L3_CSYR2K_Correctness() {
+        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+
+        // Populate input allocations
+        Allocation matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dK, mBLASData.dN));
+        Allocation matrixBC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dK, mBLASData.dN));
+        Allocation matrixCC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dN));
+        matrixAC.copyFrom(mBLASData.L3_cSYR2K_A_nk);
+        matrixBC.copyFrom(mBLASData.L3_cSYR2K_B_nk);
+        matrixCC.copyFrom(mBLASData.L3_cSYR2K_C_nn);
+
+        // Default case: NO_TRANSPOSE
+        mBLAS.CSYR2K(uplo, trans, alphaC, matrixAC, matrixBC, betaC, matrixCC);
+        Allocation matrixCRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dN));
+        matrixCRef.copyFrom(mBLASData.L3_cSYR2K_o_N);
+        verifyMatrix(matrixCRef, matrixCC, true);
+
+        // Case: TRANSPOSE
+        matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dK));
+        matrixBC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dK));
+        matrixAC.copyFrom(mBLASData.L3_cSYR2K_A_kn);
+        matrixBC.copyFrom(mBLASData.L3_cSYR2K_B_kn);
+        // Reload matrix C, since it was overwritten by BLAS.
+        matrixCC.copyFrom(mBLASData.L3_cSYR2K_C_nn);
+
+        trans = ScriptIntrinsicBLAS.TRANSPOSE;
+        mBLAS.CSYR2K(uplo, trans, alphaC, matrixAC, matrixBC, betaC, matrixCC);
+        matrixCRef.copyFrom(mBLASData.L3_cSYR2K_o_T);
+        verifyMatrix(matrixCRef, matrixCC, true);
+
+        mRS.finish();
+        checkError();
+    }
+
+    public void test_L3_ZSYR2K_Correctness() {
+        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+
+        // Populate input allocations
+        Allocation matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dK, mBLASData.dN));
+        Allocation matrixBZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dK, mBLASData.dN));
+        Allocation matrixCZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dN));
+        matrixAZ.copyFrom(mBLASData.L3_zSYR2K_A_nk);
+        matrixBZ.copyFrom(mBLASData.L3_zSYR2K_B_nk);
+        matrixCZ.copyFrom(mBLASData.L3_zSYR2K_C_nn);
+
+        // Default case: NO_TRANSPOSE
+        mBLAS.ZSYR2K(uplo, trans, alphaZ, matrixAZ, matrixBZ, betaZ, matrixCZ);
+        Allocation matrixCRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dN));
+        matrixCRef.copyFrom(mBLASData.L3_zSYR2K_o_N);
+        verifyMatrix(matrixCRef, matrixCZ, true);
+
+        // Case: TRANSPOSE
+        matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dK));
+        matrixBZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dK));
+        matrixAZ.copyFrom(mBLASData.L3_zSYR2K_A_kn);
+        matrixBZ.copyFrom(mBLASData.L3_zSYR2K_B_kn);
+        // Reload matrix C, since it was overwritten by BLAS.
+        matrixCZ.copyFrom(mBLASData.L3_zSYR2K_C_nn);
+
+        trans = ScriptIntrinsicBLAS.TRANSPOSE;
+        mBLAS.ZSYR2K(uplo, trans, alphaZ, matrixAZ, matrixBZ, betaZ, matrixCZ);
+        matrixCRef.copyFrom(mBLASData.L3_zSYR2K_o_T);
+        verifyMatrix(matrixCRef, matrixCZ, true);
+
+        mRS.finish();
+        checkError();
+    }
+
+
+    private boolean validateHER2K(Element e, int Uplo, int Trans, Allocation A, Allocation B, Allocation C) {
+        if (!validateUplo(Uplo)) {
+            return false;
+        }
+        if (!A.getType().getElement().isCompatible(e) ||
+            !B.getType().getElement().isCompatible(e) ||
+            !C.getType().getElement().isCompatible(e)) {
+            return false;
+        }
+        if (!validateConjTranspose(Trans)) {
+            return false;
+        }
+        int cdim = C.getType().getX();
+        if (cdim != C.getType().getY()) {
+            return false;
+        }
+        if (Trans == ScriptIntrinsicBLAS.NO_TRANSPOSE) {
+            if (A.getType().getY() != cdim) {
+                return false;
+            }
+        } else {
+            if (A.getType().getX() != cdim) {
+                return false;
+            }
+        }
+        if (A.getType().getX() != B.getType().getX() || A.getType().getY() != B.getType().getY()) {
+            return false;
+        }
+        return true;
+    }
+
+    private void xHER2K_API_test(int Uplo, int Trans, ArrayList<Allocation> mMatrix) {
+        for (Allocation matA : mMatrix) {
+            for (Allocation matB : mMatrix) {
+                for (Allocation matC : mMatrix) {
+                    Element elemA = matA.getType().getElement();
+                    if (validateHER2K(elemA, Uplo, Trans, matA, matB, matC)) {
+                        try {
+                            if (elemA.isCompatible(Element.F32_2(mRS))) {
+                                mBLAS.CHER2K(Uplo, Trans, alphaC, matA, matB, betaS, matC);
+                            } else if (elemA.isCompatible(Element.F64_2(mRS))) {
+                                mBLAS.ZHER2K(Uplo, Trans, alphaZ, matA, matB, betaD, matC);
+                            }
+                        } catch (RSRuntimeException e) {
+                            fail("should NOT throw RSRuntimeException");
+                        }
+                    } else {
+                        try {
+                            mBLAS.CHER2K(Uplo, Trans, alphaC, matA, matB, betaS, matC);
+                            fail("should throw RSRuntimeException for CHER2K");
+                        } catch (RSRuntimeException e) {
+                        }
+                        try {
+                            mBLAS.ZHER2K(Uplo, Trans, alphaZ, matA, matB, betaD, matC);
+                            fail("should throw RSRuntimeException for ZHER2K");
+                        } catch (RSRuntimeException e) {
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    public void L3_xHER2K_API(ArrayList<Allocation> mMatrix) {
+        for (int Uplo : mUplo) {
+            for (int Trans : mTranspose) {
+                xHER2K_API_test(Uplo, Trans, mMatrix);
+            }
+        }
+    }
+
+    public void test_L3_CHER2K_API() {
+        L3_xHER2K_API(mMatrixC);
+    }
+
+    public void test_L3_ZHER2K_API() {
+        L3_xHER2K_API(mMatrixZ);
+    }
+
+    public void test_L3_CHER2K_Correctness() {
+        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+
+        // Populate input allocations
+        Allocation matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dK, mBLASData.dN));
+        Allocation matrixBC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dK, mBLASData.dN));
+        Allocation matrixCC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dN));
+        matrixAC.copyFrom(mBLASData.L3_cHER2K_A_nk);
+        matrixBC.copyFrom(mBLASData.L3_cHER2K_B_nk);
+        matrixCC.copyFrom(mBLASData.L3_cHER2K_C_nn);
+
+        // Default case: NO_TRANSPOSE
+        mBLAS.CHER2K(uplo, trans, alphaC, matrixAC, matrixBC, betaS, matrixCC);
+        Allocation matrixCRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dN));
+        matrixCRef.copyFrom(mBLASData.L3_cHER2K_o_N);
+        verifyMatrix(matrixCRef, matrixCC, true);
+
+        // Case: TRANSPOSE
+        matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dK));
+        matrixBC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dK));
+        matrixAC.copyFrom(mBLASData.L3_cHER2K_A_kn);
+        matrixBC.copyFrom(mBLASData.L3_cHER2K_B_kn);
+        // Reload matrix C, since it was overwritten by BLAS.
+        matrixCC.copyFrom(mBLASData.L3_cHER2K_C_nn);
+
+        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
+        mBLAS.CHER2K(uplo, trans, alphaC, matrixAC, matrixBC, betaS, matrixCC);
+        matrixCRef.copyFrom(mBLASData.L3_cHER2K_o_H);
+        verifyMatrix(matrixCRef, matrixCC, true);
+
+        mRS.finish();
+        checkError();
+    }
+
+    public void test_L3_ZHER2K_Correctness() {
+        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+
+        // Populate input allocations
+        Allocation matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dK, mBLASData.dN));
+        Allocation matrixBZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dK, mBLASData.dN));
+        Allocation matrixCZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dN));
+        matrixAZ.copyFrom(mBLASData.L3_zHER2K_A_nk);
+        matrixBZ.copyFrom(mBLASData.L3_zHER2K_B_nk);
+        matrixCZ.copyFrom(mBLASData.L3_zHER2K_C_nn);
+
+        // Default case: NO_TRANSPOSE
+        mBLAS.ZHER2K(uplo, trans, alphaZ, matrixAZ, matrixBZ, betaD, matrixCZ);
+        Allocation matrixCRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dN));
+        matrixCRef.copyFrom(mBLASData.L3_zHER2K_o_N);
+        verifyMatrix(matrixCRef, matrixCZ, true);
+
+        // Case: TRANSPOSE
+        matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dK));
+        matrixBZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dK));
+        matrixAZ.copyFrom(mBLASData.L3_zHER2K_A_kn);
+        matrixBZ.copyFrom(mBLASData.L3_zHER2K_B_kn);
+        // Reload matrix C, since it was overwritten by BLAS.
+        matrixCZ.copyFrom(mBLASData.L3_zHER2K_C_nn);
+
+        trans = ScriptIntrinsicBLAS.CONJ_TRANSPOSE;
+        mBLAS.ZHER2K(uplo, trans, alphaZ, matrixAZ, matrixBZ, betaD, matrixCZ);
+        matrixCRef.copyFrom(mBLASData.L3_zHER2K_o_H);
+        verifyMatrix(matrixCRef, matrixCZ, true);
+
+        mRS.finish();
+        checkError();
+    }
+
+
+    private boolean validateTRMM(Element e, int Side, int Uplo, int TransA, int Diag, Allocation A, Allocation B) {
+        if (!validateSide(Side)) {
+            return false;
+        }
+        if (!validateUplo(Uplo)) {
+            return false;
+        }
+        if (!validateTranspose(TransA)) {
+            return false;
+        }
+        if (!validateDiag(Diag)) {
+            return false;
+        }
+        int aM = -1, aN = -1, bM = -1, bN = -1;
+        if (!A.getType().getElement().isCompatible(e) ||
+            !B.getType().getElement().isCompatible(e)) {
+            return false;
+        }
+
+        aM = A.getType().getY();
+        aN = A.getType().getX();
+        if (aM != aN) {
+            return false;
+        }
+
+        bM = B.getType().getY();
+        bN = B.getType().getX();
+        if (Side == ScriptIntrinsicBLAS.LEFT) {
+            if (aN != bM) {
+                return false;
+            }
+        } else {
+            if (bN != aM) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private void xTRMM_API_test(int Side, int Uplo, int TransA, int Diag, ArrayList<Allocation> mMatrix) {
+        for (Allocation matA : mMatrix) {
+            for (Allocation matB : mMatrix) {
+                Element elemA = matA.getType().getElement();
+                if (validateTRMM(elemA, Side, Uplo, TransA, Diag, matA, matB)) {
+                    try {
+                        if (elemA.isCompatible(Element.F32(mRS))) {
+                            mBLAS.STRMM(Side, Uplo, TransA, Diag, alphaS, matA, matB);
+                        } else if (elemA.isCompatible(Element.F64(mRS))) {
+                            mBLAS.DTRMM(Side, Uplo, TransA, Diag, alphaD, matA, matB);
+                        } else if (elemA.isCompatible(Element.F32_2(mRS))) {
+                            mBLAS.CTRMM(Side, Uplo, TransA, Diag, alphaC, matA, matB);
+                        } else if (elemA.isCompatible(Element.F64_2(mRS))) {
+                            mBLAS.ZTRMM(Side, Uplo, TransA, Diag, alphaZ, matA, matB);
+                        }
+                    } catch (RSRuntimeException e) {
+                        fail("should NOT throw RSRuntimeException");
+                    }
+                } else {
+                    try {
+                        mBLAS.STRMM(Side, Uplo, TransA, Diag, alphaS, matA, matB);
+                        fail("should throw RSRuntimeException for STRMM");
+                    } catch (RSRuntimeException e) {
+                    }
+                    try {
+                        mBLAS.DTRMM(Side, Uplo, TransA, Diag, alphaD, matA, matB);
+                        fail("should throw RSRuntimeException for DTRMM");
+                    } catch (RSRuntimeException e) {
+                    }
+                    try {
+                        mBLAS.CTRMM(Side, Uplo, TransA, Diag, alphaC, matA, matB);
+                        fail("should throw RSRuntimeException for CTRMM");
+                    } catch (RSRuntimeException e) {
+                    }
+                    try {
+                        mBLAS.ZTRMM(Side, Uplo, TransA, Diag, alphaZ, matA, matB);
+                        fail("should throw RSRuntimeException for ZTRMM");
+                    } catch (RSRuntimeException e) {
+                    }
+                }
+            }
+        }
+    }
+
+    public void L3_xTRMM_API(ArrayList<Allocation> mMatrix) {
+        for (int Side : mSide) {
+            for (int Uplo : mUplo) {
+                for (int TransA : mTranspose) {
+                    for (int Diag : mDiag) {
+                        xTRMM_API_test(Side, Uplo, TransA, Diag, mMatrix);
+                    }
+                }
+            }
+        }
+    }
+
+    public void test_L3_STRMM_API() {
+        L3_xTRMM_API(mMatrixS);
+    }
+
+    public void test_L3_DTRMM_API() {
+        L3_xTRMM_API(mMatrixD);
+    }
+
+    public void test_L3_CTRMM_API() {
+        L3_xTRMM_API(mMatrixC);
+    }
+
+    public void test_L3_ZTRMM_API() {
+        L3_xTRMM_API(mMatrixZ);
+    }
+
+
+    public void test_L3_STRMM_Correctness() {
+        int side = ScriptIntrinsicBLAS.LEFT;
+        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+        int diag = ScriptIntrinsicBLAS.NON_UNIT;
+
+        // Populate input allocations
+        Allocation matrixAS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dM, mBLASData.dM));
+        Allocation matrixBS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dM));
+        matrixAS.copyFrom(mBLASData.L3_sTRMM_A_mm);
+        matrixBS.copyFrom(mBLASData.L3_sTRMM_B_mn);
+
+        // Default case: LEFT, UPPER, NO_TRANSPOSE
+        mBLAS.STRMM(side, uplo, trans, diag, alphaS, matrixAS, matrixBS);
+        Allocation matrixBRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dM));
+        matrixBRef.copyFrom(mBLASData.L3_sTRMM_o_LUN);
+        verifyMatrix(matrixBRef, matrixBS);
+
+        // Case: RIGHT, LOWER, TRANSPOSE
+        matrixAS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dN));
+        matrixAS.copyFrom(mBLASData.L3_sTRMM_A_nn);
+        // Reload matrix B, since it was overwritten by BLAS.
+        matrixBS.copyFrom(mBLASData.L3_sTRMM_B_mn);
+
+        side = ScriptIntrinsicBLAS.RIGHT;
+        trans = ScriptIntrinsicBLAS.TRANSPOSE;
+        uplo = ScriptIntrinsicBLAS.LOWER;
+        mBLAS.STRMM(side, uplo, trans, diag, alphaS, matrixAS, matrixBS);
+        matrixBRef.copyFrom(mBLASData.L3_sTRMM_o_RLT);
+        verifyMatrix(matrixBRef, matrixBS);
+
+        mRS.finish();
+        checkError();
+    }
+
+    public void test_L3_DTRMM_Correctness() {
+        int side = ScriptIntrinsicBLAS.LEFT;
+        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+        int diag = ScriptIntrinsicBLAS.NON_UNIT;
+
+        // Populate input allocations
+        Allocation matrixAD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dM, mBLASData.dM));
+        Allocation matrixBD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dM));
+        matrixAD.copyFrom(mBLASData.L3_dTRMM_A_mm);
+        matrixBD.copyFrom(mBLASData.L3_dTRMM_B_mn);
+
+        // Default case: LEFT, UPPER, NO_TRANSPOSE
+        mBLAS.DTRMM(side, uplo, trans, diag, alphaD, matrixAD, matrixBD);
+        Allocation matrixBRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dM));
+        matrixBRef.copyFrom(mBLASData.L3_dTRMM_o_LUN);
+        verifyMatrix(matrixBRef, matrixBD);
+
+        // Case: RIGHT, LOWER, TRANSPOSE
+        matrixAD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dN));
+        matrixAD.copyFrom(mBLASData.L3_dTRMM_A_nn);
+        // Reload matrix B, since it was overwritten by BLAS.
+        matrixBD.copyFrom(mBLASData.L3_dTRMM_B_mn);
+
+        side = ScriptIntrinsicBLAS.RIGHT;
+        trans = ScriptIntrinsicBLAS.TRANSPOSE;
+        uplo = ScriptIntrinsicBLAS.LOWER;
+        mBLAS.DTRMM(side, uplo, trans, diag, alphaD, matrixAD, matrixBD);
+        matrixBRef.copyFrom(mBLASData.L3_dTRMM_o_RLT);
+        verifyMatrix(matrixBRef, matrixBD);
+
+        mRS.finish();
+        checkError();
+    }
+
+    public void test_L3_CTRMM_Correctness() {
+        int side = ScriptIntrinsicBLAS.LEFT;
+        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+        int diag = ScriptIntrinsicBLAS.NON_UNIT;
+
+        // Populate input allocations
+        Allocation matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dM, mBLASData.dM));
+        Allocation matrixBC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dM));
+        matrixAC.copyFrom(mBLASData.L3_cTRMM_A_mm);
+        matrixBC.copyFrom(mBLASData.L3_cTRMM_B_mn);
+
+        // Default case: LEFT, UPPER, NO_TRANSPOSE
+        mBLAS.CTRMM(side, uplo, trans, diag, alphaC, matrixAC, matrixBC);
+        Allocation matrixBRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dM));
+        matrixBRef.copyFrom(mBLASData.L3_cTRMM_o_LUN);
+        verifyMatrix(matrixBRef, matrixBC);
+
+        // Case: RIGHT, LOWER, TRANSPOSE
+        matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dN));
+        matrixAC.copyFrom(mBLASData.L3_cTRMM_A_nn);
+        // Reload matrix B, since it was overwritten by BLAS.
+        matrixBC.copyFrom(mBLASData.L3_cTRMM_B_mn);
+
+        side = ScriptIntrinsicBLAS.RIGHT;
+        trans = ScriptIntrinsicBLAS.TRANSPOSE;
+        uplo = ScriptIntrinsicBLAS.LOWER;
+        mBLAS.CTRMM(side, uplo, trans, diag, alphaC, matrixAC, matrixBC);
+        matrixBRef.copyFrom(mBLASData.L3_cTRMM_o_RLT);
+        verifyMatrix(matrixBRef, matrixBC);
+
+        mRS.finish();
+        checkError();
+    }
+
+    public void test_L3_ZTRMM_Correctness() {
+        int side = ScriptIntrinsicBLAS.LEFT;
+        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+        int diag = ScriptIntrinsicBLAS.NON_UNIT;
+
+        // Populate input allocations
+        Allocation matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dM, mBLASData.dM));
+        Allocation matrixBZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dM));
+        matrixAZ.copyFrom(mBLASData.L3_zTRMM_A_mm);
+        matrixBZ.copyFrom(mBLASData.L3_zTRMM_B_mn);
+
+        // Default case: LEFT, UPPER, NO_TRANSPOSE
+        mBLAS.ZTRMM(side, uplo, trans, diag, alphaZ, matrixAZ, matrixBZ);
+        Allocation matrixBRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dM));
+        matrixBRef.copyFrom(mBLASData.L3_zTRMM_o_LUN);
+        verifyMatrix(matrixBRef, matrixBZ);
+
+        // Case: RIGHT, LOWER, TRANSPOSE
+        matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dN));
+        matrixAZ.copyFrom(mBLASData.L3_zTRMM_A_nn);
+        // Reload matrix B, since it was overwritten by BLAS.
+        matrixBZ.copyFrom(mBLASData.L3_zTRMM_B_mn);
+
+        side = ScriptIntrinsicBLAS.RIGHT;
+        trans = ScriptIntrinsicBLAS.TRANSPOSE;
+        uplo = ScriptIntrinsicBLAS.LOWER;
+        mBLAS.ZTRMM(side, uplo, trans, diag, alphaZ, matrixAZ, matrixBZ);
+        matrixBRef.copyFrom(mBLASData.L3_zTRMM_o_RLT);
+        verifyMatrix(matrixBRef, matrixBZ);
+
+        mRS.finish();
+        checkError();
+    }
+
+
+    private boolean validateTRSM(Element e, int Side, int Uplo, int TransA, int Diag, Allocation A, Allocation B) {
+        int adim = -1, bM = -1, bN = -1;
+        if (!validateSide(Side)) {
+            return false;
+        }
+        if (!validateTranspose(TransA)) {
+            return false;
+        }
+        if (!validateUplo(Uplo)) {
+            return false;
+        }
+        if (!validateDiag(Diag)) {
+            return false;
+        }
+        if (!A.getType().getElement().isCompatible(e) ||
+            !B.getType().getElement().isCompatible(e)) {
+            return false;
+        }
+        adim = A.getType().getX();
+        if (adim != A.getType().getY()) {
+            // this may be unnecessary, the restriction could potentially be relaxed
+            // A needs to contain at least that symmetric matrix but could theoretically be larger
+            // for now we assume adapters are sufficient, will reevaluate in the future
+            return false;
+        }
+        bM = B.getType().getY();
+        bN = B.getType().getX();
+        if (Side == ScriptIntrinsicBLAS.LEFT) {
+            // A is M*M
+            if (adim != bM) {
+                return false;
+            }
+        } else {
+            // A is N*N
+            if (adim != bN) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private void xTRSM_API_test(int Side, int Uplo, int TransA, int Diag, ArrayList<Allocation> mMatrix) {
+        for (Allocation matA : mMatrix) {
+            for (Allocation matB : mMatrix) {
+                Element elemA = matA.getType().getElement();
+                if (validateTRSM(elemA, Side, Uplo, TransA, Diag, matA, matB)) {
+                    try {
+                        if (elemA.isCompatible(Element.F32(mRS))) {
+                            mBLAS.STRSM(Side, Uplo, TransA, Diag, alphaS, matA, matB);
+                        } else if (elemA.isCompatible(Element.F64(mRS))) {
+                            mBLAS.DTRSM(Side, Uplo, TransA, Diag, alphaD, matA, matB);
+                        } else if (elemA.isCompatible(Element.F32_2(mRS))) {
+                            mBLAS.CTRSM(Side, Uplo, TransA, Diag, alphaC, matA, matB);
+                        } else if (elemA.isCompatible(Element.F64_2(mRS))) {
+                            mBLAS.ZTRSM(Side, Uplo, TransA, Diag, alphaZ, matA, matB);
+                        }
+                    } catch (RSRuntimeException e) {
+                        fail("should NOT throw RSRuntimeException");
+                    }
+                } else {
+                    try {
+                        mBLAS.STRSM(Side, Uplo, TransA, Diag, alphaS, matA, matB);
+                        fail("should throw RSRuntimeException for STRSM");
+                    } catch (RSRuntimeException e) {
+                    }
+                    try {
+                        mBLAS.DTRSM(Side, Uplo, TransA, Diag, alphaD, matA, matB);
+                        fail("should throw RSRuntimeException for DTRSM");
+                    } catch (RSRuntimeException e) {
+                    }
+                    try {
+                        mBLAS.CTRSM(Side, Uplo, TransA, Diag, alphaC, matA, matB);
+                        fail("should throw RSRuntimeException for CTRSM");
+                    } catch (RSRuntimeException e) {
+                    }
+                    try {
+                        mBLAS.ZTRSM(Side, Uplo, TransA, Diag, alphaZ, matA, matB);
+                        fail("should throw RSRuntimeException for ZTRSM");
+                    } catch (RSRuntimeException e) {
+                    }
+                }
+            }
+        }
+    }
+
+    public void L3_xTRSM_API(ArrayList<Allocation> mMatrix) {
+        for (int Side : mSide) {
+            for (int Uplo : mUplo) {
+                for (int TransA : mTranspose) {
+                    for (int Diag : mDiag) {
+                        xTRSM_API_test(Side, Uplo, TransA, Diag, mMatrix);
+                    }
+                }
+            }
+        }
+    }
+
+    public void test_L3_STRSM_API() {
+        L3_xTRSM_API(mMatrixS);
+    }
+
+    public void test_L3_DTRSM_API() {
+        L3_xTRSM_API(mMatrixD);
+    }
+
+    public void test_L3_CTRSM_API() {
+        L3_xTRSM_API(mMatrixC);
+    }
+
+    public void test_L3_ZTRSM_API() {
+        L3_xTRSM_API(mMatrixZ);
+    }
+
+    public void test_L3_STRSM_Correctness() {
+        int side = ScriptIntrinsicBLAS.LEFT;
+        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+        int diag = ScriptIntrinsicBLAS.NON_UNIT;
+
+        // Populate input allocations
+        Allocation matrixAS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dM, mBLASData.dM));
+        Allocation matrixBS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dM));
+        matrixAS.copyFrom(mBLASData.L3_sTRSM_A_mm);
+        matrixBS.copyFrom(mBLASData.L3_sTRSM_B_mn);
+
+        // Default case: LEFT, UPPER, NO_TRANSPOSE
+        mBLAS.STRSM(side, uplo, trans, diag, alphaS, matrixAS, matrixBS);
+        Allocation matrixBRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dM));
+        matrixBRef.copyFrom(mBLASData.L3_sTRSM_o_LUN);
+        verifyMatrix(matrixBRef, matrixBS);
+
+        // Case: RIGHT, LOWER, TRANSPOSE
+        matrixAS = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32(mRS), mBLASData.dN, mBLASData.dN));
+        matrixAS.copyFrom(mBLASData.L3_sTRSM_A_nn);
+        // Reload matrix B, since it was overwritten by BLAS.
+        matrixBS.copyFrom(mBLASData.L3_sTRSM_B_mn);
+
+        side = ScriptIntrinsicBLAS.RIGHT;
+        trans = ScriptIntrinsicBLAS.TRANSPOSE;
+        uplo = ScriptIntrinsicBLAS.LOWER;
+        mBLAS.STRSM(side, uplo, trans, diag, alphaS, matrixAS, matrixBS);
+        matrixBRef.copyFrom(mBLASData.L3_sTRSM_o_RLT);
+        verifyMatrix(matrixBRef, matrixBS);
+
+        mRS.finish();
+        checkError();
+    }
+
+    public void test_L3_DTRSM_Correctness() {
+        int side = ScriptIntrinsicBLAS.LEFT;
+        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+        int diag = ScriptIntrinsicBLAS.NON_UNIT;
+
+        // Populate input allocations
+        Allocation matrixAD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dM, mBLASData.dM));
+        Allocation matrixBD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dM));
+        matrixAD.copyFrom(mBLASData.L3_dTRSM_A_mm);
+        matrixBD.copyFrom(mBLASData.L3_dTRSM_B_mn);
+
+        // Default case: LEFT, UPPER, NO_TRANSPOSE
+        mBLAS.DTRSM(side, uplo, trans, diag, alphaD, matrixAD, matrixBD);
+        Allocation matrixBRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dM));
+        matrixBRef.copyFrom(mBLASData.L3_dTRSM_o_LUN);
+        verifyMatrix(matrixBRef, matrixBD);
+
+        // Case: RIGHT, LOWER, TRANSPOSE
+        matrixAD = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64(mRS), mBLASData.dN, mBLASData.dN));
+        matrixAD.copyFrom(mBLASData.L3_dTRSM_A_nn);
+        // Reload matrix B, since it was overwritten by BLAS.
+        matrixBD.copyFrom(mBLASData.L3_dTRSM_B_mn);
+
+        side = ScriptIntrinsicBLAS.RIGHT;
+        trans = ScriptIntrinsicBLAS.TRANSPOSE;
+        uplo = ScriptIntrinsicBLAS.LOWER;
+        mBLAS.DTRSM(side, uplo, trans, diag, alphaD, matrixAD, matrixBD);
+        matrixBRef.copyFrom(mBLASData.L3_dTRSM_o_RLT);
+        verifyMatrix(matrixBRef, matrixBD);
+
+        mRS.finish();
+        checkError();
+    }
+
+    public void test_L3_CTRSM_Correctness() {
+        int side = ScriptIntrinsicBLAS.LEFT;
+        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+        int diag = ScriptIntrinsicBLAS.NON_UNIT;
+
+        // Populate input allocations
+        Allocation matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dM, mBLASData.dM));
+        Allocation matrixBC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dM));
+        matrixAC.copyFrom(mBLASData.L3_cTRSM_A_mm);
+        matrixBC.copyFrom(mBLASData.L3_cTRSM_B_mn);
+
+        // Default case: LEFT, UPPER, NO_TRANSPOSE
+        mBLAS.CTRSM(side, uplo, trans, diag, alphaC, matrixAC, matrixBC);
+        Allocation matrixBRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dM));
+        matrixBRef.copyFrom(mBLASData.L3_cTRSM_o_LUN);
+        verifyMatrix(matrixBRef, matrixBC);
+
+        // Case: RIGHT, LOWER, TRANSPOSE
+        matrixAC = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_2(mRS), mBLASData.dN, mBLASData.dN));
+        matrixAC.copyFrom(mBLASData.L3_cTRSM_A_nn);
+        // Reload matrix B, since it was overwritten by BLAS.
+        matrixBC.copyFrom(mBLASData.L3_cTRSM_B_mn);
+
+        side = ScriptIntrinsicBLAS.RIGHT;
+        trans = ScriptIntrinsicBLAS.TRANSPOSE;
+        uplo = ScriptIntrinsicBLAS.LOWER;
+        mBLAS.CTRSM(side, uplo, trans, diag, alphaC, matrixAC, matrixBC);
+        matrixBRef.copyFrom(mBLASData.L3_cTRSM_o_RLT);
+        verifyMatrix(matrixBRef, matrixBC);
+
+        mRS.finish();
+        checkError();
+    }
+
+    public void test_L3_ZTRSM_Correctness() {
+        int side = ScriptIntrinsicBLAS.LEFT;
+        int trans = ScriptIntrinsicBLAS.NO_TRANSPOSE;
+        int uplo = ScriptIntrinsicBLAS.UPPER;
+        int diag = ScriptIntrinsicBLAS.NON_UNIT;
+
+        // Populate input allocations
+        Allocation matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dM, mBLASData.dM));
+        Allocation matrixBZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dM));
+        matrixAZ.copyFrom(mBLASData.L3_zTRSM_A_mm);
+        matrixBZ.copyFrom(mBLASData.L3_zTRSM_B_mn);
+
+        // Default case: LEFT, UPPER, NO_TRANSPOSE
+        mBLAS.ZTRSM(side, uplo, trans, diag, alphaZ, matrixAZ, matrixBZ);
+        Allocation matrixBRef = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dM));
+        matrixBRef.copyFrom(mBLASData.L3_zTRSM_o_LUN);
+        verifyMatrix(matrixBRef, matrixBZ);
+
+        // Case: RIGHT, LOWER, TRANSPOSE
+        matrixAZ = Allocation.createTyped(mRS, Type.createXY(mRS, Element.F64_2(mRS), mBLASData.dN, mBLASData.dN));
+        matrixAZ.copyFrom(mBLASData.L3_zTRSM_A_nn);
+        // Reload matrix B, since it was overwritten by BLAS.
+        matrixBZ.copyFrom(mBLASData.L3_zTRSM_B_mn);
+
+        side = ScriptIntrinsicBLAS.RIGHT;
+        trans = ScriptIntrinsicBLAS.TRANSPOSE;
+        uplo = ScriptIntrinsicBLAS.LOWER;
+        mBLAS.ZTRSM(side, uplo, trans, diag, alphaZ, matrixAZ, matrixBZ);
+        matrixBRef.copyFrom(mBLASData.L3_zTRSM_o_RLT);
+        verifyMatrix(matrixBRef, matrixBZ);
+
+        mRS.finish();
+        checkError();
+    }
+}
diff --git a/tests/tests/rsblas/src/android/renderscript/cts/IntrinsicBase.java b/tests/tests/rsblas/src/android/renderscript/cts/IntrinsicBase.java
new file mode 100644
index 0000000..5ab52b0
--- /dev/null
+++ b/tests/tests/rsblas/src/android/renderscript/cts/IntrinsicBase.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.cts.rsblas;
+
+import android.util.Log;
+import android.renderscript.RenderScript;
+import android.renderscript.Allocation;
+import android.renderscript.Element;
+import android.renderscript.Type;
+import android.renderscript.Script;
+
+public class IntrinsicBase extends RSBaseCompute {
+    protected final String TAG = "Img";
+
+    protected Allocation mAllocSrc;
+    protected Allocation mAllocRef;
+    protected Allocation mAllocDst;
+    protected ScriptC_verify mVerify;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mVerify = new ScriptC_verify(mRS);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        if (mVerify != null) {
+            mVerify.destroy();
+            mVerify = null;
+        }
+        super.tearDown();
+    }
+
+    protected void checkError() {
+        mRS.finish();
+        mVerify.invoke_checkError();
+        waitForMessage();
+        checkForErrors();
+    }
+}
diff --git a/tests/tests/rsblas/src/android/renderscript/cts/RSBase.java b/tests/tests/rsblas/src/android/renderscript/cts/RSBase.java
new file mode 100644
index 0000000..7057fd9
--- /dev/null
+++ b/tests/tests/rsblas/src/android/renderscript/cts/RSBase.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.cts.rsblas;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.renderscript.RenderScript.RSErrorHandler;
+import android.renderscript.RenderScript.RSMessageHandler;
+import android.renderscript.RSRuntimeException;
+import android.test.AndroidTestCase;
+import android.util.Log;
+
+/**
+ * Base RenderScript test class. This class provides a message handler and a
+ * convenient way to wait for compute scripts to complete their execution.
+ */
+public class RSBase extends AndroidTestCase {
+
+    Context mCtx;
+    Resources mRes;
+
+    private int result;
+    // msgHandled is used to synchronize between waitForMessage() and the
+    // RSMessageHandler thread.
+    private volatile boolean msgHandled;
+
+    protected static final int RS_MSG_TEST_PASSED = 100;
+    protected static final int RS_MSG_TEST_FAILED = 101;
+    protected static final int RS_MSG_TEST_FLUSH = 102;
+
+    RSMessageHandler mRsMessage = new RSMessageHandler() {
+        public void run() {
+            if (result == 0) {
+                switch (mID) {
+                    case RS_MSG_TEST_PASSED:
+                    case RS_MSG_TEST_FAILED:
+                        result = mID;
+                        break;
+                    case RS_MSG_TEST_FLUSH:
+                        break;
+                    default:
+                        fail("Got unexpected RS message");
+                        return;
+                }
+            }
+            msgHandled = true;
+        }
+    };
+
+    protected void waitForMessage() {
+        while (!msgHandled) {
+            Thread.yield();
+        }
+    }
+
+    protected boolean FoundError = false;
+    protected RSErrorHandler mRsError = new RSErrorHandler() {
+        public void run() {
+            FoundError = true;
+            Log.e("RenderscriptCTS", mErrorMessage);
+            throw new RSRuntimeException("Received error " + mErrorNum +
+                                         " message " + mErrorMessage);
+        }
+    };
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        result = 0;
+        msgHandled = false;
+        mCtx = getContext();
+        mRes = mCtx.getResources();
+    }
+
+    /**
+     * Verify that we didn't fail on the control or script side of things.
+     */
+    protected void checkForErrors() {
+        assertFalse(FoundError);
+        assertTrue(result != RS_MSG_TEST_FAILED);
+    }
+}
diff --git a/tests/tests/rsblas/src/android/renderscript/cts/RSBaseCompute.java b/tests/tests/rsblas/src/android/renderscript/cts/RSBaseCompute.java
new file mode 100644
index 0000000..d548a70
--- /dev/null
+++ b/tests/tests/rsblas/src/android/renderscript/cts/RSBaseCompute.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.cts.rsblas;
+
+import android.renderscript.RenderScript;
+import android.renderscript.Allocation;
+import android.renderscript.Element;
+import android.renderscript.RSRuntimeException;
+import android.util.Log;
+
+/**
+ * Base RenderScript test class. This class provides a message handler and a
+ * convenient way to wait for compute scripts to complete their execution.
+ */
+public class RSBaseCompute extends RSBase {
+    RenderScript mRS;
+    protected int INPUTSIZE = 512;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mRS = RenderScript.create(mCtx);
+        mRS.setMessageHandler(mRsMessage);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+}
diff --git a/tests/tests/rsblas/src/android/renderscript/cts/shared.rsh b/tests/tests/rsblas/src/android/renderscript/cts/shared.rsh
new file mode 100644
index 0000000..d20fd34
--- /dev/null
+++ b/tests/tests/rsblas/src/android/renderscript/cts/shared.rsh
@@ -0,0 +1,26 @@
+#pragma version(1)
+#pragma rs java_package_name(android.cts.rsblas)
+
+static int64_t g_time;
+
+static inline void start(void) {
+    g_time = rsUptimeMillis();
+}
+
+static inline float end(void) {
+    int64_t t = rsUptimeMillis() - g_time;
+    return ((float)t) / 1000.f;
+}
+
+#define _RS_ASSERT(b) \
+do { \
+    if (!(b)) { \
+        failed = true; \
+        rsDebug(#b " FAILED", 0); \
+    } \
+\
+} while (0)
+
+/* These constants must match those in UnitTest.java */
+static const int RS_MSG_TEST_PASSED = 100;
+static const int RS_MSG_TEST_FAILED = 101;
diff --git a/tests/tests/rsblas/src/android/renderscript/cts/verify.rs b/tests/tests/rsblas/src/android/renderscript/cts/verify.rs
new file mode 100644
index 0000000..ea3cff6
--- /dev/null
+++ b/tests/tests/rsblas/src/android/renderscript/cts/verify.rs
@@ -0,0 +1,212 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 "shared.rsh"
+
+double gAllowedFloatMatError = 0.00000001;
+double gAllowedDoubleMatError = 0.00000000001;
+static bool hadError = false;
+static int2 errorLoc = {0,0};
+
+#define printCell(txt, a, xy) \
+{                       \
+    rs_element e = rsAllocationGetElement(a); \
+    rs_data_type dt = rsElementGetDataType(e); \
+    uint32_t vs = rsElementGetVectorSize(e); \
+ \
+    if (dt == RS_TYPE_UNSIGNED_8) { \
+        switch(vs) { \
+        case 4: \
+            rsDebug(txt, rsGetElementAt_uchar4(a, xy.x, xy.y)); \
+            break; \
+        case 3: \
+            rsDebug(txt, rsGetElementAt_uchar3(a, xy.x, xy.y)); \
+            break; \
+        case 2: \
+            rsDebug(txt, rsGetElementAt_uchar2(a, xy.x, xy.y)); \
+            break; \
+        case 1: \
+            rsDebug(txt, rsGetElementAt_uchar(a, xy.x, xy.y)); \
+            break; \
+        } \
+    } else if (dt == RS_TYPE_FLOAT_32) { \
+        switch(vs) { \
+        case 4: \
+            rsDebug(txt, rsGetElementAt_float4(a, xy.x, xy.y)); \
+            break; \
+        case 3: \
+            rsDebug(txt, rsGetElementAt_float3(a, xy.x, xy.y)); \
+            break; \
+        case 2: \
+            rsDebug(txt, rsGetElementAt_float2(a, xy.x, xy.y)); \
+            break; \
+        case 1: \
+            rsDebug(txt, rsGetElementAt_float(a, xy.x, xy.y)); \
+            break; \
+        } \
+    } else if (dt == RS_TYPE_FLOAT_64) { \
+        switch(vs) { \
+        case 4: \
+            rsDebug(txt, rsGetElementAt_double4(a, xy.x, xy.y)); \
+            break; \
+        case 3: \
+            rsDebug(txt, rsGetElementAt_double3(a, xy.x, xy.y)); \
+            break; \
+        case 2: \
+            rsDebug(txt, rsGetElementAt_double2(a, xy.x, xy.y)); \
+            break; \
+        case 1: \
+            rsDebug(txt, rsGetElementAt_double(a, xy.x, xy.y)); \
+        } \
+    } \
+}
+
+static bool verify_CMatrix(rs_allocation in1, rs_allocation in2, double l2Norm, bool isUpperMatrix) {
+    uint32_t w = rsAllocationGetDimX(in1);
+    uint32_t h = rsAllocationGetDimY(in1);
+    for (uint32_t y = 0; y < h; y++) {
+        uint32_t xStart = 0;
+        if (isUpperMatrix) {
+            // Just test the upper matrix for certain BLAS routines
+            xStart = y;
+        }
+        for (uint32_t x = xStart; x < w; x++) {
+            float2 pref = rsGetElementAt_float2(in1, x, y);
+            float2 ptst = rsGetElementAt_float2(in2, x, y);
+            double absErr = (pref.x - ptst.x) * (pref.x - ptst.x) + (pref.y - ptst.y) * (pref.y - ptst.y);
+            if (absErr > l2Norm * gAllowedFloatMatError) {
+                errorLoc.x = x;
+                errorLoc.y = y;
+                hadError = true;
+                return false;
+            }
+        }
+    }
+    return true;
+}
+
+static bool verify_SMatrix(rs_allocation in1, rs_allocation in2, double l2Norm, bool isUpperMatrix) {
+    uint32_t w = rsAllocationGetDimX(in1);
+    uint32_t h = rsAllocationGetDimY(in1);
+    for (uint32_t y = 0; y < h; y++) {
+        uint32_t xStart = 0;
+        if (isUpperMatrix) {
+            // Just test the upper matrix for certain BLAS routines
+            xStart = y;
+        }
+        for (uint32_t x = xStart; x < w; x++) {
+            float pref = rsGetElementAt_float(in1, x, y);
+            float ptst = rsGetElementAt_float(in2, x, y);
+            double absErr = (pref - ptst) * (pref - ptst);
+            if (absErr > l2Norm * gAllowedFloatMatError) {
+                errorLoc.x = x;
+                errorLoc.y = y;
+                hadError = true;
+                return false;
+            }
+        }
+    }
+    return true;
+}
+
+static bool verify_ZMatrix(rs_allocation in1, rs_allocation in2, double l2Norm, bool isUpperMatrix) {
+    uint32_t w = rsAllocationGetDimX(in1);
+    uint32_t h = rsAllocationGetDimY(in1);
+    for (uint32_t y = 0; y < h; y++) {
+        uint32_t xStart = 0;
+        if (isUpperMatrix) {
+            // Just test the upper matrix for certain BLAS routines
+            xStart = y;
+        }
+        for (uint32_t x = xStart; x < w; x++) {
+            double2 pref = rsGetElementAt_double2(in1, x, y);
+            double2 ptst = rsGetElementAt_double2(in2, x, y);
+            double absErr = (pref.x - ptst.x) * (pref.x - ptst.x) + (pref.y - ptst.y) * (pref.y - ptst.y);
+            if (absErr > l2Norm * gAllowedDoubleMatError) {
+                errorLoc.x = x;
+                errorLoc.y = y;
+                hadError = true;
+                return false;
+            }
+        }
+    }
+    return true;
+}
+
+static bool verify_DMatrix(rs_allocation in1, rs_allocation in2, double l2Norm, bool isUpperMatrix) {
+    uint32_t w = rsAllocationGetDimX(in1);
+    uint32_t h = rsAllocationGetDimY(in1);
+    for (uint32_t y = 0; y < h; y++) {
+        uint32_t xStart = 0;
+        if (isUpperMatrix) {
+            // Just test the upper matrix for certain BLAS routines
+            xStart = y;
+        }
+        for (uint32_t x = xStart; x < w; x++) {
+            double pref = rsGetElementAt_double(in1, x, y);
+            double ptst = rsGetElementAt_double(in2, x, y);
+            double absErr = (pref - ptst) * (pref - ptst);
+            if (absErr > l2Norm * gAllowedDoubleMatError) {
+                errorLoc.x = x;
+                errorLoc.y = y;
+                hadError = true;
+                return false;
+            }
+        }
+    }
+    return true;
+}
+
+void verifyMatrix(rs_allocation ref_in, rs_allocation tst_in, double l2Norm, bool isUpperMatrix) {
+    rs_element e = rsAllocationGetElement(ref_in);
+    rs_data_type dt = rsElementGetDataType(e);
+    uint32_t vs = rsElementGetVectorSize(e);
+    bool valid = false;
+
+    if (dt == RS_TYPE_FLOAT_32) {
+        switch(vs) {
+        case 2:
+            valid = verify_CMatrix(ref_in, tst_in, l2Norm, isUpperMatrix);
+            break;
+        case 1:
+            valid = verify_SMatrix(ref_in, tst_in, l2Norm, isUpperMatrix);
+            break;
+        }
+    } else if (dt == RS_TYPE_FLOAT_64) {
+        switch(vs) {
+        case 2:
+            valid = verify_ZMatrix(ref_in, tst_in, l2Norm, isUpperMatrix);
+            break;
+        case 1:
+            valid = verify_DMatrix(ref_in, tst_in, l2Norm, isUpperMatrix);
+            break;
+        }
+    }
+    if (!valid) {
+        rsDebug("verify failure at xy", errorLoc);
+        printCell("Expected value ", ref_in, errorLoc);
+        printCell("Actual value   ", tst_in, errorLoc);
+    }
+}
+
+void checkError()
+{
+    if (hadError) {
+        rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+    } else {
+        rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+    }
+}
diff --git a/tests/tests/rscpp/Android.mk b/tests/tests/rscpp/Android.mk
index 0eb32b5..bdcf840 100644
--- a/tests/tests/rscpp/Android.mk
+++ b/tests/tests/rscpp/Android.mk
@@ -35,5 +35,8 @@
 
 LOCAL_SDK_VERSION := current
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_CTS_PACKAGE)
 include $(LOCAL_PATH)/librscpptest/Android.mk
diff --git a/tests/tests/rscpp/AndroidManifest.xml b/tests/tests/rscpp/AndroidManifest.xml
index b68ebc3..035d242 100644
--- a/tests/tests/rscpp/AndroidManifest.xml
+++ b/tests/tests/rscpp/AndroidManifest.xml
@@ -15,7 +15,7 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.rscpp">
+    package="android.rscpp.cts">
 
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <application>
@@ -24,7 +24,7 @@
 
     <!-- This is a self-instrumenting test package. -->
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.cts.rscpp"
+                     android:targetPackage="android.rscpp.cts"
                      android:label="CTS tests of RenderScript C++ component">
         <meta-data android:name="listener"
             android:value="com.android.cts.runner.CtsTestRunListener" />
diff --git a/tests/tests/rscpp/AndroidTest.xml b/tests/tests/rscpp/AndroidTest.xml
new file mode 100644
index 0000000..1e7c41f
--- /dev/null
+++ b/tests/tests/rscpp/AndroidTest.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Configuration for renderscript cpp Tests">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsRsCppTestCases.apk" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.rscpp.cts" />
+        <option name="runtime-hint" value="2m" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/tests/rscpp/librscpptest/Android.mk b/tests/tests/rscpp/librscpptest/Android.mk
index df8ce29f..73d2234 100644
--- a/tests/tests/rscpp/librscpptest/Android.mk
+++ b/tests/tests/rscpp/librscpptest/Android.mk
@@ -45,14 +45,12 @@
 LOCAL_C_INCLUDES += frameworks/rs/cpp
 LOCAL_C_INCLUDES += frameworks/rs
 
+LOCAL_CPPFLAGS := -std=c++11
+
 LOCAL_SHARED_LIBRARIES := libdl liblog
 LOCAL_STATIC_LIBRARIES := libRScpp_static libcutils
 
-ifeq ($(my_32_64_bit_suffix),32)
-    LOCAL_SDK_VERSION := 8
-else
-    LOCAL_SDK_VERSION := 21
-endif
+LOCAL_SDK_VERSION := 21
 
 LOCAL_NDK_STL_VARIANT := stlport_static
 
diff --git a/tests/tests/rscpp/librscpptest/clear_object.rs b/tests/tests/rscpp/librscpptest/clear_object.rs
index 70ba42b..cb6a0ad 100644
--- a/tests/tests/rscpp/librscpptest/clear_object.rs
+++ b/tests/tests/rscpp/librscpptest/clear_object.rs
@@ -1,5 +1,5 @@
 #pragma version(1)
-#pragma rs java_package_name(com.android.cts.rscpp)
+#pragma rs java_package_name(android.rscpp.cts)
 
 rs_allocation allocation;
 
diff --git a/tests/tests/rscpp/librscpptest/fe_all.rs b/tests/tests/rscpp/librscpptest/fe_all.rs
index dc20ba7..d5076bf 100644
--- a/tests/tests/rscpp/librscpptest/fe_all.rs
+++ b/tests/tests/rscpp/librscpptest/fe_all.rs
@@ -1,5 +1,5 @@
 #pragma version(1)
-#pragma rs java_package_name(com.android.cts.rscpp)
+#pragma rs java_package_name(android.rscpp.cts)
 
 void test_i8(const char *ain, uchar *aout) {
     aout[0] = ain[0] + 1;
diff --git a/tests/tests/rscpp/librscpptest/rs_jni.cpp b/tests/tests/rscpp/librscpptest/rs_jni.cpp
index 4e60f4b..920d95d 100644
--- a/tests/tests/rscpp/librscpptest/rs_jni.cpp
+++ b/tests/tests/rscpp/librscpptest/rs_jni.cpp
@@ -459,7 +459,7 @@
     sp<RS> mRS = new RS();
     mRS->init(path);
 
-    RSYuvFormat mYuvFormat = (RSYuvFormat)yuvFormat;
+    RsYuvFormat mYuvFormat = (RsYuvFormat)yuvFormat;
     sp<ScriptIntrinsicYuvToRGB> syuv = ScriptIntrinsicYuvToRGB::create(mRS, Element::U8_4(mRS));;
     sp<Allocation> inputAlloc = nullptr;
 
@@ -492,4 +492,3 @@
     return (mRS->getError() == RS_SUCCESS);
 
 }
-
diff --git a/tests/tests/rscpp/librscpptest/setelementat.rs b/tests/tests/rscpp/librscpptest/setelementat.rs
index 5a84552..fc706de 100644
--- a/tests/tests/rscpp/librscpptest/setelementat.rs
+++ b/tests/tests/rscpp/librscpptest/setelementat.rs
@@ -1,5 +1,5 @@
 #pragma version(1)
-#pragma rs java_package_name(com.android.cts.rscpp)
+#pragma rs java_package_name(android.rscpp.cts)
 #pragma rs_fp_relaxed
 
 int memset_toValue = 0;
diff --git a/tests/tests/rscpp/librscpptest/shared.rsh b/tests/tests/rscpp/librscpptest/shared.rsh
index c5599d7..70668e0 100644
--- a/tests/tests/rscpp/librscpptest/shared.rsh
+++ b/tests/tests/rscpp/librscpptest/shared.rsh
@@ -1,5 +1,5 @@
 #pragma version(1)
-#pragma rs java_package_name(com.android.cts.rscpp)
+#pragma rs java_package_name(android.rscpp.cts)
 
 static int64_t g_time;
 
diff --git a/tests/tests/rscpp/src/android/cts/rscpp/RSYuvTest.java b/tests/tests/rscpp/src/android/cts/rscpp/RSYuvTest.java
index 8f79a4c..30c76e4 100644
--- a/tests/tests/rscpp/src/android/cts/rscpp/RSYuvTest.java
+++ b/tests/tests/rscpp/src/android/cts/rscpp/RSYuvTest.java
@@ -141,7 +141,8 @@
         syuv.forEach(aout);
 
         byte[] nativeByteAlloc = new byte[width * height * 4];
-        yuvTest(this.getContext().getCacheDir().toString(), width, height, tmp, nativeByteAlloc, 1);
+        yuvTest(this.getContext().getCacheDir().toString(), width, height, tmp, nativeByteAlloc,
+                android.graphics.ImageFormat.YV12);
         aref.copyFromUnchecked(nativeByteAlloc);
 
         mVerify.invoke_verify(aref, aout, ay);
@@ -177,7 +178,8 @@
         syuv.forEach(aout);
 
         byte[] nativeByteAlloc = new byte[width * height * 4];
-        yuvTest(this.getContext().getCacheDir().toString(), width, height, tmp, nativeByteAlloc, 2);
+        yuvTest(this.getContext().getCacheDir().toString(), width, height, tmp, nativeByteAlloc,
+                android.graphics.ImageFormat.NV21);
         aref.copyFromUnchecked(nativeByteAlloc);
 
         mVerify.invoke_verify(aref, aout, ay);
diff --git a/tests/tests/sax/Android.mk b/tests/tests/sax/Android.mk
index a468778..498aa40 100644
--- a/tests/tests/sax/Android.mk
+++ b/tests/tests/sax/Android.mk
@@ -29,4 +29,7 @@
 
 LOCAL_SDK_VERSION := current
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/sax/AndroidManifest.xml b/tests/tests/sax/AndroidManifest.xml
index 63c568b..c15bd7a 100644
--- a/tests/tests/sax/AndroidManifest.xml
+++ b/tests/tests/sax/AndroidManifest.xml
@@ -16,14 +16,14 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.sax">
+    package="android.sax.cts">
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <application>
         <uses-library android:name="android.test.runner" />
     </application>
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.cts.sax"
+                     android:targetPackage="android.sax.cts"
                      android:label="CTS tests of android.sax">
         <meta-data android:name="listener"
             android:value="com.android.cts.runner.CtsTestRunListener" />
diff --git a/tests/tests/sax/AndroidTest.xml b/tests/tests/sax/AndroidTest.xml
new file mode 100644
index 0000000..14ec1c3
--- /dev/null
+++ b/tests/tests/sax/AndroidTest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS SAX test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsSaxTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.sax.cts" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/tests/security/Android.mk b/tests/tests/security/Android.mk
index ec36d6d..6d728da 100644
--- a/tests/tests/security/Android.mk
+++ b/tests/tests/security/Android.mk
@@ -21,11 +21,38 @@
 # Include both the 32 and 64 bit versions
 LOCAL_MULTILIB := both
 
-LOCAL_STATIC_JAVA_LIBRARIES := ctstestserver ctstestrunner ctsdeviceutil guava
+LOCAL_STATIC_JAVA_LIBRARIES := ctstestserver ctstestrunner ctsdeviceutil compatibility-device-util guava
 
 LOCAL_JAVA_LIBRARIES := android.test.runner org.apache.http.legacy
 
-LOCAL_JNI_SHARED_LIBRARIES := libctssecurity_jni libcts_jni
+LOCAL_JNI_SHARED_LIBRARIES := libctssecurity_jni libcts_jni libnativehelper_compat_libc++ \
+		libnativehelper \
+		libbinder \
+		libutils \
+		libmedia \
+		libselinux \
+		libcutils \
+		libcrypto \
+		libc++ \
+		libbacktrace \
+		libui \
+		libsonivox \
+		libexpat \
+		libcamera_client \
+		libgui \
+		libaudioutils \
+		libnbaio \
+		libpcre \
+		libpackagelistparser \
+		libpowermanager \
+		libbase \
+		libunwind \
+		libhardware \
+		libsync \
+		libcamera_metadata \
+		libspeexresampler \
+		liblzma \
+		libstagefright_foundation
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)\
                    src/android/security/cts/activity/ISecureRandomService.aidl
@@ -34,6 +61,9 @@
 
 LOCAL_SDK_VERSION := current
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_CTS_PACKAGE)
 
 include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/tests/security/AndroidManifest.xml b/tests/tests/security/AndroidManifest.xml
index 3039f81..7a67b08 100644
--- a/tests/tests/security/AndroidManifest.xml
+++ b/tests/tests/security/AndroidManifest.xml
@@ -16,12 +16,13 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.security">
+    package="android.security.cts">
 
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES" />
     <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
     <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
     <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
 
@@ -39,8 +40,8 @@
     </application>
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.cts.security"
-                     android:label="CTS tests of com.android.cts.security">
+                     android:targetPackage="android.security.cts"
+                     android:label="CTS tests of android.security.cts">
         <meta-data android:name="listener"
             android:value="com.android.cts.runner.CtsTestRunListener" />
     </instrumentation>
diff --git a/tests/tests/security/AndroidTest.xml b/tests/tests/security/AndroidTest.xml
new file mode 100644
index 0000000..6ffe7ae7
--- /dev/null
+++ b/tests/tests/security/AndroidTest.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS security test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsSecurityTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.security.cts" />
+        <option name="runtime-hint" value="3m15s" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/tests/security/assets/path_building/a.pem b/tests/tests/security/assets/path_building/a.pem
new file mode 100644
index 0000000..c3a38c8
--- /dev/null
+++ b/tests/tests/security/assets/path_building/a.pem
@@ -0,0 +1,17 @@
+-----BEGIN CERTIFICATE-----
+MIICvjCCAaagAwIBAgIDALo5MA0GCSqGSIb3DQEBCwUAMBExDzANBgNVBAMTBlJv
+b3QgQTAqGBMyMDE1MDEwMTAwMDAwMCswMDAwGBMyMDMwMDEwMTAwMDAwMCswMDAw
+MBExDzANBgNVBAMTBlJvb3QgQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
+ggEBAPjsieSXdpmZv/YxiIbZpuicCFcteqSoWncsGAsZNqHjL7jgIsDZJK8W0c3g
+cj0Ij8WmuK6zntN39kszXWAoul9WM+KeJvRBd96dXBo3WrwmqMeLtNKLERmG7pW9
+VekJ0rOF3q6pPbYNujkwI+WBmlLsVmUYG5Jz9mD5JfVHdtnX+R99XNisfoGuMI7D
+ADVxPuzDs6+KWsoDU55xytmik5scF/CsTjftPNeVjCNBwhm7XRsDT+SMztZL2jsP
+WatTYPecZ+JkelGDlskv++k0QzkmrDLB4lBOrqdz7KMUyf3t1JcQDmmyFLCDiZOF
+Kx3UKR7qmrb++eNQ/D6cSPbdTq0CAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zAN
+BgkqhkiG9w0BAQsFAAOCAQEAxLy+Qf3Mv/qy4R77zhVccVSQyh2pbHY4L3RryoJF
+k565iJRZ7f6I/1LrsL40RpYy057+bIKom34BRQQlFXTJj5ghWqmZ4eZVloWYcT0s
+NeQJW3TVUPzB1Fb968oAKt7I7/L+/wZTBgNiwQlbIQhAmQgQiJRWGSWqOmrvrfRJ
+hG6W3ueErMxElyOPtMj3xYGlCW0k9PyhBXoCt3QohDqzWibX4sI8DLBKyKSWKTA1
+6MIWLvwm0Hf3QAS7IjPCxAUUtt+arXgZ28lEbq49itcKfuKfdFTdLtQfPdIU5iEV
+WJ1sMKGehnz3giChXKvKeyt3xVCIaOAkbAjHPyeW28mpwg==
+-----END CERTIFICATE-----
diff --git a/tests/tests/security/assets/path_building/a_sha1.pem b/tests/tests/security/assets/path_building/a_sha1.pem
new file mode 100644
index 0000000..8f27783
--- /dev/null
+++ b/tests/tests/security/assets/path_building/a_sha1.pem
@@ -0,0 +1,17 @@
+-----BEGIN CERTIFICATE-----
+MIICvjCCAaagAwIBAgIDBs9kMA0GCSqGSIb3DQEBBQUAMBExDzANBgNVBAMTBlJv
+b3QgQTAqGBMyMDE1MDEwMTAwMDAwMCswMDAwGBMyMDMwMDEwMTAwMDAwMCswMDAw
+MBExDzANBgNVBAMTBlJvb3QgQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
+ggEBAPjsieSXdpmZv/YxiIbZpuicCFcteqSoWncsGAsZNqHjL7jgIsDZJK8W0c3g
+cj0Ij8WmuK6zntN39kszXWAoul9WM+KeJvRBd96dXBo3WrwmqMeLtNKLERmG7pW9
+VekJ0rOF3q6pPbYNujkwI+WBmlLsVmUYG5Jz9mD5JfVHdtnX+R99XNisfoGuMI7D
+ADVxPuzDs6+KWsoDU55xytmik5scF/CsTjftPNeVjCNBwhm7XRsDT+SMztZL2jsP
+WatTYPecZ+JkelGDlskv++k0QzkmrDLB4lBOrqdz7KMUyf3t1JcQDmmyFLCDiZOF
+Kx3UKR7qmrb++eNQ/D6cSPbdTq0CAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zAN
+BgkqhkiG9w0BAQUFAAOCAQEAPkTGyMCOYPohWrdrxPtUOao4fPUdhgH2n5MQOtXK
+HJhfH1ro0URt9eGBbvKU/jb5nK7tJpZrfQTJBa0LKkNzWQ4CuKqJU5CJY1tfHxVP
+2toM4v/pP99OsfnJVBVJYd2IPg3WoOoehpmohdJHznlmkVb62Azg9nU5X22Z+dYt
+fNtvBZLneug0AfIFOde0W4yHahD+pQyVbUgLTsBXayTRnmaHeFbtVjmy2CiHvxLc
+KDcoNiW6gK4R+T7o7r6cjyPXcTN2W4TA0SszR0tnIFaDEnNewO/L3tVQKx4ltfOG
+fEfvl5DqnJs1b6sc8VgLKXSMXzp9NXWxHWKrlCyIJEcHZg==
+-----END CERTIFICATE-----
diff --git a/tests/tests/security/assets/path_building/a_to_b.pem b/tests/tests/security/assets/path_building/a_to_b.pem
new file mode 100644
index 0000000..5cd16d3
--- /dev/null
+++ b/tests/tests/security/assets/path_building/a_to_b.pem
@@ -0,0 +1,17 @@
+-----BEGIN CERTIFICATE-----
+MIICvjCCAaagAwIBAgIDCx+QMA0GCSqGSIb3DQEBCwUAMBExDzANBgNVBAMTBlJv
+b3QgQjAqGBMyMDE1MDEwMTAwMDAwMCswMDAwGBMyMDMwMDEwMTAwMDAwMCswMDAw
+MBExDzANBgNVBAMTBlJvb3QgQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
+ggEBAPjsieSXdpmZv/YxiIbZpuicCFcteqSoWncsGAsZNqHjL7jgIsDZJK8W0c3g
+cj0Ij8WmuK6zntN39kszXWAoul9WM+KeJvRBd96dXBo3WrwmqMeLtNKLERmG7pW9
+VekJ0rOF3q6pPbYNujkwI+WBmlLsVmUYG5Jz9mD5JfVHdtnX+R99XNisfoGuMI7D
+ADVxPuzDs6+KWsoDU55xytmik5scF/CsTjftPNeVjCNBwhm7XRsDT+SMztZL2jsP
+WatTYPecZ+JkelGDlskv++k0QzkmrDLB4lBOrqdz7KMUyf3t1JcQDmmyFLCDiZOF
+Kx3UKR7qmrb++eNQ/D6cSPbdTq0CAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zAN
+BgkqhkiG9w0BAQsFAAOCAQEAA73yZZ5TJ5ieRq6y7MjHQL0yJZTPqr7LIIRop0kh
+aJcfYffDdffERCQuVRgay+r6Su06aZ8MopBSubRWERyL/ZgSeEdS49HnISWehSCx
+Md0uvCPQUrxxS6GDaorLpBQ/1WK9rZc7vs3pgzLNN3zpdJ2o3GaJ9BYtuDUU+Kh5
+cv8gHD5LThxFbPLpnhDRyhiJ4CuJAZht681ItNhcL7Cfb8pNNXNLq2RhBOkZ6Upo
+xd9Fr9zv0FjeuZ9WzQLxyhHU8gXqnWmJIO+W7nKPJP9x3YDg0EMc3BtdvyS4QWIj
+PTnjOoT7Z3CGBd/Qn4z+PoAfGpg5aAo0J6bs6kelF6+6Yw==
+-----END CERTIFICATE-----
diff --git a/tests/tests/security/assets/path_building/b.pem b/tests/tests/security/assets/path_building/b.pem
new file mode 100644
index 0000000..b6adfc8
--- /dev/null
+++ b/tests/tests/security/assets/path_building/b.pem
@@ -0,0 +1,17 @@
+-----BEGIN CERTIFICATE-----
+MIICvjCCAaagAwIBAgIDDwzUMA0GCSqGSIb3DQEBCwUAMBExDzANBgNVBAMTBlJv
+b3QgQjAqGBMyMDE1MDEwMTAwMDAwMCswMDAwGBMyMDMwMDEwMTAwMDAwMCswMDAw
+MBExDzANBgNVBAMTBlJvb3QgQjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
+ggEBAKpKiUbK1DhAWyLuRKik1fPNvtN5DyRr3Qa5K83OmNyBpsR57qfpenksp5Cs
+By5zOYwLMJxGfA2z6phY1Crvd6ogU5GcCWIUtMzNJEJAg1O6sNjhb9AN82yZUuvn
++oPL1Qpxsj91AZ0qi8qBAT7JuM67KOoTrls43BbASDc3/eUfNeoDANdz7AO21obj
+oL9P6B0Edy4aN0OeTVUxsix3vOeW/CL3RSklHymrR24iL5AfVq2gQFGui10esXV2
+R4K8kzmwfp4rODsEKABLB7/gljkvy1bmOrg7oW32FSf0Rw4PCKz0xdD34KaGYYhW
+7N98TnkQ6XAYGsaiSR4r3VFrHRECAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zAN
+BgkqhkiG9w0BAQsFAAOCAQEAJSCbpsDjfyKpGp2a7d4WonzfAf+/sC0Z6M8UhVCD
+WK/0cZmrYgjm80uflxmwTMCIqvn0XcV3rt/lpV0UTxEqhHQ/4lrdzYVz97mbXdei
+eqtKTC4rG24/4LDBL1PuGfIABwBW7QroF9I9OrRGyuKVs17MDuM2n8jhKCs0Rjtj
+kwA2ZbmfvDPzLipTQd7FzL73eos9Lug2CtoW5IzFWlmuhc1V1E3M36nelDCJfUij
+0gUuE1XovVIHl5P4M9ktS1S8GlWrsdHcW3uWFxTiXBW9e8/UKn6vk49kORCzj3S1
+/9CrVNLTCFaxGH2TmGBCOW9Z90+PJS/KHg4JIJ/mEbrc3w==
+-----END CERTIFICATE-----
diff --git a/tests/tests/security/assets/path_building/b_to_a.pem b/tests/tests/security/assets/path_building/b_to_a.pem
new file mode 100644
index 0000000..0aff5b9
--- /dev/null
+++ b/tests/tests/security/assets/path_building/b_to_a.pem
@@ -0,0 +1,17 @@
+-----BEGIN CERTIFICATE-----
+MIICvjCCAaagAwIBAgIDD3FMMA0GCSqGSIb3DQEBCwUAMBExDzANBgNVBAMTBlJv
+b3QgQTAqGBMyMDE1MDEwMTAwMDAwMCswMDAwGBMyMDMwMDEwMTAwMDAwMCswMDAw
+MBExDzANBgNVBAMTBlJvb3QgQjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
+ggEBAKpKiUbK1DhAWyLuRKik1fPNvtN5DyRr3Qa5K83OmNyBpsR57qfpenksp5Cs
+By5zOYwLMJxGfA2z6phY1Crvd6ogU5GcCWIUtMzNJEJAg1O6sNjhb9AN82yZUuvn
++oPL1Qpxsj91AZ0qi8qBAT7JuM67KOoTrls43BbASDc3/eUfNeoDANdz7AO21obj
+oL9P6B0Edy4aN0OeTVUxsix3vOeW/CL3RSklHymrR24iL5AfVq2gQFGui10esXV2
+R4K8kzmwfp4rODsEKABLB7/gljkvy1bmOrg7oW32FSf0Rw4PCKz0xdD34KaGYYhW
+7N98TnkQ6XAYGsaiSR4r3VFrHRECAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zAN
+BgkqhkiG9w0BAQsFAAOCAQEAfYxfbh+dksrQK2KguFnd33gTibH1mYJ0zVS6Bcio
+D8S9Vxn7Zn4dSW+Wj+ec1LdMrU8zbqvXxPGJze5m9mxYTGVSq/wnG1ebOD/IO0g4
+Vr6H2iRaditUjeoBdvHgDATo4LJhsUloljDQIR8v4gpIuV55RtC2ppd0A9C1cDGf
+Ia5+bkcmPrNLTdYitwHs2TUqCq7zTApmtWz814R6ryk/M3NIu4c4hbS1m3aTWRln
+wPy9oaRcpHiNO7QnKrJ6nqfL1UE3STar2s7dTU4Teo0lEVRGFXRnmjckltZv2iSz
+GEwUxlbhaq1nHlOetZS+W6FD2Ve/1RPDPzeP4cMQB98J2w==
+-----END CERTIFICATE-----
diff --git a/tests/tests/security/assets/path_building/intermediate_a.pem b/tests/tests/security/assets/path_building/intermediate_a.pem
new file mode 100644
index 0000000..bf6eba3
--- /dev/null
+++ b/tests/tests/security/assets/path_building/intermediate_a.pem
@@ -0,0 +1,17 @@
+-----BEGIN CERTIFICATE-----
+MIICxDCCAaygAwIBAgIDBKqTMA0GCSqGSIb3DQEBCwUAMBExDzANBgNVBAMTBlJv
+b3QgQTAqGBMyMDE1MDEwMTAwMDAwMCswMDAwGBMyMDMwMDEwMTAwMDAwMCswMDAw
+MBcxFTATBgNVBAMTDGludGVybWVkaWF0ZTCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ADCCAQoCggEBAOOqsYw6pzmD1/TQMncmc25lvOtzocU8CNOQaAw02yZrkGuA1Ivb
+3ga5wMeQFfwm2/tqdEqNm9zEzIHvoxPx6ZDT5FyjQK6cSbaB002sMJODip0ldgWW
+ds+Zq3XqSJsIo/em7H7MKAxXbbPulfBKaWHCWUbwj7pGOdANY3sAKksljB+5KFI0
+gAdRn72glUMOnq5nY2ZD9ZCR+eRZ2xIabGUvg50rk35GAaZSZsbAVl2QqOZ1cKZr
+MlkYhFA4cuODY2mbs81MS/VTZdQIEa5a8QJbxPltdQE683lfDqR25Y7q31kNn4yV
+WB3EVbMSB/lq/csM5X+XBKrI2i9rbORUcqECAwEAAaMTMBEwDwYDVR0TAQH/BAUw
+AwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAQyeRijHRzBH5UetO3Kudzro5g3J+5Txu
+Jw446RnPkpbab6A++6FB57D1Y4qYWBeIrNH1xH1bIsWvYIhi86vjOS2Eyu8MM3u9
+lzPQNrHMazbQzOALtOE9do3SajgxaJeM2/WrzygGVErrrzKrt9X3/7bbqOmqyZLH
+Px82azPWCXtgzZy/DErQBcKjxpFyvpwqQTDKke1+opW0P5KXB7fKhtbOygfeeHCG
++dpokE4TtUhznc2yvsNxWzuKXmMsr5/sQtnACJOlm/uT5hkyFBv/5zoug81C9RhV
+Z7BV2mZ+Wlf6ueTbVp70+iJm/0Rpv0z4puGB8TQb2HpYrNtYfSWoMw==
+-----END CERTIFICATE-----
diff --git a/tests/tests/security/assets/path_building/intermediate_b.pem b/tests/tests/security/assets/path_building/intermediate_b.pem
new file mode 100644
index 0000000..41066fc
--- /dev/null
+++ b/tests/tests/security/assets/path_building/intermediate_b.pem
@@ -0,0 +1,17 @@
+-----BEGIN CERTIFICATE-----
+MIICxDCCAaygAwIBAgIDDac7MA0GCSqGSIb3DQEBCwUAMBExDzANBgNVBAMTBlJv
+b3QgQjAqGBMyMDE1MDEwMTAwMDAwMCswMDAwGBMyMDMwMDEwMTAwMDAwMCswMDAw
+MBcxFTATBgNVBAMTDGludGVybWVkaWF0ZTCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ADCCAQoCggEBAOOqsYw6pzmD1/TQMncmc25lvOtzocU8CNOQaAw02yZrkGuA1Ivb
+3ga5wMeQFfwm2/tqdEqNm9zEzIHvoxPx6ZDT5FyjQK6cSbaB002sMJODip0ldgWW
+ds+Zq3XqSJsIo/em7H7MKAxXbbPulfBKaWHCWUbwj7pGOdANY3sAKksljB+5KFI0
+gAdRn72glUMOnq5nY2ZD9ZCR+eRZ2xIabGUvg50rk35GAaZSZsbAVl2QqOZ1cKZr
+MlkYhFA4cuODY2mbs81MS/VTZdQIEa5a8QJbxPltdQE683lfDqR25Y7q31kNn4yV
+WB3EVbMSB/lq/csM5X+XBKrI2i9rbORUcqECAwEAAaMTMBEwDwYDVR0TAQH/BAUw
+AwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAhZjhJYoV+h1vekKHcbQsMmYECNqmaeHa
+lgJ54LLfzuk2cyTIp+PX/I6hGU+QR1OVR3gUwwI4wyFxANv/RH0EDEjDTUcd/FYk
+vAfs3W9OHnCMRF1D+bxw8InRvgzFIfXMorwVvxwC5XCrgSYAM3OkhgvNxmf+nXgg
+dtGKZmva5rRtCEZj4djV9JUwLTWW5x3SN2rhGur6+vRFA7jScAm3YkCD+ii4x9Mf
+5RisFtsYzmhIhCWMGXmLrTZmghPkgQVlES/YGst8XptmHVqwY9qAOKayIYOgf/d6
+BvLsVGdSw9iRrPASWlFXvCyNWuO6zOM97IcYF9HIUWcUVNYSiXXceg==
+-----END CERTIFICATE-----
diff --git a/tests/tests/security/assets/path_building/leaf1.pem b/tests/tests/security/assets/path_building/leaf1.pem
new file mode 100644
index 0000000..28fdc6f
--- /dev/null
+++ b/tests/tests/security/assets/path_building/leaf1.pem
@@ -0,0 +1,17 @@
+-----BEGIN CERTIFICATE-----
+MIICvDCCAaSgAwIBAgIDCS0BMA0GCSqGSIb3DQEBCwUAMBExDzANBgNVBAMTBlJv
+b3QgQTAqGBMyMDE1MDEwMTAwMDAwMCswMDAwGBMyMDMwMDEwMTAwMDAwMCswMDAw
+MA8xDTALBgNVBAMTBExlYWYwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
+AQDZYuX5LRdHetGr0nVbzb0tDC68PEjJKqKepZcRAsob0r+eLig0PVcNz/F0EF/X
++Nm72rBQUu9zkaZ8iqHbwMpEKX7JdAhnTCa5x0eU6umQ66v6MKWRapYjkBgfSpBp
++lBuXxl6SbIj1PST8XkkMC1Ow+D7O71dJyCQrNjlaGANOODqvsI2eX3oxLpbhdyi
+yTMR4z+w+QYqpR5gRFU8Ynx+Wy6IQXZtTcc/3uvZ4PewYVe8mjDNgqSOj+7sxHEY
+duV/yc6+oLcSIu8scVVXxUp53QhbtfiaUi7dbpe/ba4a/tCNkDNFD6lRAk7lh9io
+i0NCleXlyzqQKbdKqOrcCCJDAgMBAAGjEzARMA8GA1UdEwEB/wQFMAMBAf8wDQYJ
+KoZIhvcNAQELBQADggEBAA5ETybm67kpTWwwdVfJRb8vMAePbeOx6Kx05UsHhiBp
+BzyB7IK+xSDC72PDY/6EG/0rwiQYRCfUujWXY6D+l9uVNU8Eak33hPplhdMDf6/k
+F7BOM/Jvey4MsHbbZqiYrYaE/ucR04lEb2XmMlwrSIDjdZ5UCanWiH0FwHlE+NsR
+fONJIfCy5W+wVg78nFtCcRYd1/OY0aiUQbUuXzfgEB7J0bWZEUms9XrLVrl9Mo0S
+PRyR8vi8Kmn+EM0Ic0spooX5YSsl/FUqBPSGhMBR1LGM7QxKM+Olkf1j9xoNLN+x
+vzCJl3UuzWzwbUqg1IF1/lzFEyIrqj+pD8rpENYa5WI=
+-----END CERTIFICATE-----
diff --git a/tests/tests/security/assets/path_building/leaf2.pem b/tests/tests/security/assets/path_building/leaf2.pem
new file mode 100644
index 0000000..4e5b9f0
--- /dev/null
+++ b/tests/tests/security/assets/path_building/leaf2.pem
@@ -0,0 +1,17 @@
+-----BEGIN CERTIFICATE-----
+MIICxDCCAaygAwIBAgIDAyZ6MA0GCSqGSIb3DQEBCwUAMBcxFTATBgNVBAMTDGlu
+dGVybWVkaWF0ZTAqGBMyMDE1MDEwMTAwMDAwMCswMDAwGBMyMDMwMDEwMTAwMDAw
+MCswMDAwMBExDzANBgNVBAMTBkxlYWYgMjCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ADCCAQoCggEBAK5cJ9ZkIxJx49TsqdEBW4GNXkO2lRWIG8Y71fXGYBvlrqhfTGhX
+JxdTa+yGHw5IPgsq+D37BHWfvgRys7egRoiOhXHFORJKbPGrr5I5/vWkp1px5k1e
+ILzndhbRrRBf283oqd78bos8szNpWJ8EnbwY8BoVtBlW25Woi/tAQQGuQgYLldIC
+LWmxYi9GqyTwGGZddpHILb54zc4/P9DeU0XQRlL8Zx0XSKj126IlEoWG1zoC3Zu3
++eI2wgMxyL/AKZjjOrfdrqG1cX2kPjoM2RvZG9LllI41vR87CYizttYphQxii88v
+6UmobYt01njjHj2RNLNc6HcUxaFjoxMkxN0CAwEAAaMTMBEwDwYDVR0TAQH/BAUw
+AwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAVtsuF4WB0/z3VM0aIc9BXnZivK+xDtHA
+c5fUVPwVeBpPxiJUHzY1pFfcVvmefgI2hVvUq2MVbMyDe3IpSZ7bp03DPrtLl+i8
+4RaLUlit9OAqsjg55ZXB1miTtGjElJj6h8DdgF9Qyl/WULZqVgBCDmkwAjWViL1i
+5gmj5VWVZydGLDMuX23jFHj2kPmVJfaLiHg6mqP5ktYEy3YbtJiLg+D+gEyvSqrt
+NfcTp6BMt25Hm+YpJ7V5e35SmIl+izKGh+BpZUDM2+iJy2hEhapBpRk0jiuGqMZh
+MNAqKAMArGZAY/wYoEGAyLveNmZV/xtIROXk4LmpeO1RkGq4wsm7iw==
+-----END CERTIFICATE-----
diff --git a/tests/tests/security/jni/Android.mk b/tests/tests/security/jni/Android.mk
index a04bd34..d39ac7e 100644
--- a/tests/tests/security/jni/Android.mk
+++ b/tests/tests/security/jni/Android.mk
@@ -26,22 +26,42 @@
 		android_security_cts_CharDeviceTest.cpp \
 		android_security_cts_KernelSettingsTest.cpp \
 		android_security_cts_LinuxRngTest.cpp \
-		android_security_cts_LoadEffectLibraryTest.cpp \
 		android_security_cts_NativeCodeTest.cpp \
 		android_security_cts_SELinuxTest.cpp \
 		android_security_cts_MMapExecutableTest.cpp \
-		android_security_cts_AudioPolicyBinderTest.cpp \
 		android_security_cts_EncryptionTest.cpp \
-		android_security_cts_MediaPlayerInfoLeakTest.cpp \
-		android_security_cts_AudioEffectBinderTest.cpp \
-		android_security_cts_AudioFlingerBinderTest.cpp \
-		android_security_cts_StagefrightFoundationTest.cpp \
-		android_security_cts_GraphicBufferInfoLeakTest.cpp
 
 LOCAL_C_INCLUDES := $(JNI_H_INCLUDE) \
 										$(TOP)/frameworks/native/include/media/openmax
 
-LOCAL_SHARED_LIBRARIES := libnativehelper liblog libbinder libutils libmedia libselinux libdl libcutils libcrypto libstagefright_foundation
+LOCAL_SHARED_LIBRARIES := libnativehelper \
+		liblog \
+		libutils \
+		libmedia \
+		libselinux \
+		libdl \
+		libcutils \
+		libcrypto \
+		libc++ \
+		libbacktrace \
+		libui \
+		libsonivox \
+		libexpat \
+		libcamera_client \
+		libgui \
+		libaudioutils \
+		libnbaio \
+		libpcre \
+		libpackagelistparser \
+		libpowermanager \
+		libbase \
+		libunwind \
+		libhardware \
+		libsync \
+		libcamera_metadata \
+		libspeexresampler \
+		liblzma \
+		libstagefright_foundation
 
 LOCAL_C_INCLUDES += ndk/sources/cpufeatures
 LOCAL_STATIC_LIBRARIES := cpufeatures
diff --git a/tests/tests/security/jni/CtsSecurityJniOnLoad.cpp b/tests/tests/security/jni/CtsSecurityJniOnLoad.cpp
index f73b2f4..198baa00 100644
--- a/tests/tests/security/jni/CtsSecurityJniOnLoad.cpp
+++ b/tests/tests/security/jni/CtsSecurityJniOnLoad.cpp
@@ -21,16 +21,9 @@
 extern int register_android_security_cts_CharDeviceTest(JNIEnv*);
 extern int register_android_security_cts_LinuxRngTest(JNIEnv*);
 extern int register_android_security_cts_NativeCodeTest(JNIEnv*);
-extern int register_android_security_cts_LoadEffectLibraryTest(JNIEnv*);
 extern int register_android_security_cts_SELinuxTest(JNIEnv*);
 extern int register_android_security_cts_MMapExecutableTest(JNIEnv* env);
-extern int register_android_security_cts_AudioPolicyBinderTest(JNIEnv* env);
-extern int register_android_security_cts_AudioFlingerBinderTest(JNIEnv* env);
 extern int register_android_security_cts_EncryptionTest(JNIEnv* env);
-extern int register_android_security_cts_MediaPlayerInfoLeakTest(JNIEnv* env);
-extern int register_android_security_cts_AudioEffectBinderTest(JNIEnv* env);
-extern int register_android_security_cts_StagefrightFoundationTest(JNIEnv* env);
-extern int register_android_security_cts_GraphicBufferInfoLeakTest(JNIEnv* env);
 
 jint JNI_OnLoad(JavaVM *vm, void *reserved) {
     JNIEnv *env = NULL;
@@ -51,10 +44,6 @@
         return JNI_ERR;
     }
 
-    if (register_android_security_cts_LoadEffectLibraryTest(env)) {
-        return JNI_ERR;
-    }
-
     if (register_android_security_cts_SELinuxTest(env)) {
         return JNI_ERR;
     }
@@ -67,33 +56,9 @@
         return JNI_ERR;
     }
 
-    if (register_android_security_cts_AudioPolicyBinderTest(env)) {
-        return JNI_ERR;
-    }
-
     if (register_android_security_cts_EncryptionTest(env)) {
         return JNI_ERR;
     }
 
-    if (register_android_security_cts_MediaPlayerInfoLeakTest(env)) {
-        return JNI_ERR;
-    }
-
-    if (register_android_security_cts_AudioEffectBinderTest(env)) {
-        return JNI_ERR;
-    }
-
-    if (register_android_security_cts_AudioFlingerBinderTest(env)) {
-        return JNI_ERR;
-    }
-
-    if (register_android_security_cts_StagefrightFoundationTest(env)) {
-        return JNI_ERR;
-    }
-
-    if (register_android_security_cts_GraphicBufferInfoLeakTest(env)) {
-        return JNI_ERR;
-    }
-
     return JNI_VERSION_1_4;
 }
diff --git a/tests/tests/security/jni/android_security_cts_AudioEffectBinderTest.cpp b/tests/tests/security/jni/android_security_cts_AudioEffectBinderTest.cpp
deleted file mode 100644
index 4c27416..0000000
--- a/tests/tests/security/jni/android_security_cts_AudioEffectBinderTest.cpp
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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 LOG_TAG "AudioEffectBinderTest-JNI"
-
-#include <jni.h>
-#include <media/AudioEffect.h>
-#include <media/IEffect.h>
-
-using namespace android;
-
-/*
- * Native methods used by
- * cts/tests/tests/security/src/android/security/cts/AudioEffectBinderTest.java
- */
-
-struct EffectClient : public BnEffectClient {
-    EffectClient() { }
-    virtual void controlStatusChanged(bool controlGranted __unused) { }
-    virtual void enableStatusChanged(bool enabled __unused) { }
-    virtual void commandExecuted(uint32_t cmdCode __unused,
-            uint32_t cmdSize __unused,
-            void *pCmdData __unused,
-            uint32_t replySize __unused,
-            void *pReplyData __unused) { }
-};
-
-struct DeathRecipient : public IBinder::DeathRecipient {
-    DeathRecipient() : mDied(false) { }
-    virtual void binderDied(const wp<IBinder>& who __unused) { mDied = true; }
-    bool died() const { return mDied; }
-    bool mDied;
-};
-
-static bool isIEffectCommandSecure(IEffect *effect)
-{
-    // some magic constants here
-    const int COMMAND_SIZE = 1024 + 12; // different than reply size to get different heap frag
-    char cmdData[COMMAND_SIZE];
-    memset(cmdData, 0xde, sizeof(cmdData));
-
-    const int REPLY_DATA_SIZE = 256;
-    char replyData[REPLY_DATA_SIZE];
-    bool secure = true;
-    for (int k = 0; k < 10; ++k) {
-        Parcel data;
-        data.writeInterfaceToken(effect->getInterfaceDescriptor());
-        data.writeInt32(0);  // 0 is EFFECT_CMD_INIT
-        data.writeInt32(sizeof(cmdData));
-        data.write(cmdData, sizeof(cmdData));
-        data.writeInt32(sizeof(replyData));
-
-        Parcel reply;
-        status_t status = effect->asBinder(effect)->transact(3, data, &reply);  // 3 is COMMAND
-        ALOGV("transact status: %d", status);
-        if (status != NO_ERROR) {
-            ALOGW("invalid transaction status %d", status);
-            continue;
-        }
-
-        ALOGV("reply data avail %zu", reply.dataAvail());
-        status = reply.readInt32();
-        ALOGV("reply status %d", status);
-        if (status == NO_ERROR) {
-            continue;
-        }
-
-        int size = reply.readInt32();
-        ALOGV("reply size %d", size);
-        if (size != sizeof(replyData)) { // we expect 0 or full reply data if command failed
-            ALOGW_IF(size != 0, "invalid reply size: %d", size);
-            continue;
-        }
-
-        // Note that if reply.read() returns success, it should completely fill replyData.
-        status = reply.read(replyData, sizeof(replyData));
-        if (status != NO_ERROR) {
-            ALOGW("invalid reply read - ignoring");
-            continue;
-        }
-        unsigned int *out = (unsigned int *)replyData;
-        for (size_t index = 0; index < sizeof(replyData) / sizeof(*out); ++index) {
-            if (out[index] != 0) {
-                secure = false;
-                ALOGI("leaked data = %#08x", out[index]);
-            }
-        }
-    }
-    ALOGI("secure: %s", secure ? "YES" : "NO");
-    return secure;
-}
-
-static jboolean android_security_cts_AudioEffect_test_isCommandSecure()
-{
-    const sp<IAudioFlinger> &audioFlinger = AudioSystem::get_audio_flinger();
-    if (audioFlinger.get() == NULL) {
-        ALOGE("could not get audioflinger");
-        return JNI_FALSE;
-    }
-
-    static const effect_uuid_t EFFECT_UIID_EQUALIZER =  // type
-        { 0x0bed4300, 0xddd6, 0x11db, 0x8f34, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b }};
-    sp<EffectClient> effectClient(new EffectClient());
-    effect_descriptor_t descriptor;
-    memset(&descriptor, 0, sizeof(descriptor));
-    descriptor.type = EFFECT_UIID_EQUALIZER;
-    descriptor.uuid = *EFFECT_UUID_NULL;
-    const int32_t priority = 0;
-    const int sessionId = AUDIO_SESSION_OUTPUT_MIX;
-    const audio_io_handle_t io = AUDIO_IO_HANDLE_NONE;
-    const String16 opPackageName("Exploitable");
-    status_t status;
-    int32_t id;
-    int enabled;
-    sp<IEffect> effect = audioFlinger->createEffect(&descriptor, effectClient,
-            priority, io, sessionId, opPackageName, &status, &id, &enabled);
-    if (effect.get() == NULL || status != NO_ERROR) {
-        ALOGW("could not create effect");
-        return JNI_TRUE;
-    }
-
-    sp<DeathRecipient> deathRecipient(new DeathRecipient());
-    IInterface::asBinder(effect)->linkToDeath(deathRecipient);
-
-    // check exploit
-    if (!isIEffectCommandSecure(effect.get())) {
-        ALOGE("not secure!");
-        return JNI_FALSE;
-    }
-
-    sleep(1); // wait to check death
-    if (deathRecipient->died()) {
-        ALOGE("effect binder died");
-        return JNI_FALSE;
-    }
-    return JNI_TRUE;
-}
-
-int register_android_security_cts_AudioEffectBinderTest(JNIEnv *env)
-{
-    static JNINativeMethod methods[] = {
-        { "native_test_isCommandSecure", "()Z",
-                (void *) android_security_cts_AudioEffect_test_isCommandSecure },
-    };
-
-    jclass clazz = env->FindClass("android/security/cts/AudioEffectBinderTest");
-    return env->RegisterNatives(clazz, methods, sizeof(methods) / sizeof(methods[0]));
-}
diff --git a/tests/tests/security/jni/android_security_cts_AudioFlingerBinderTest.cpp b/tests/tests/security/jni/android_security_cts_AudioFlingerBinderTest.cpp
deleted file mode 100644
index 3f21408..0000000
--- a/tests/tests/security/jni/android_security_cts_AudioFlingerBinderTest.cpp
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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 LOG_TAG "AudioFlingerBinderTest-JNI"
-
-#include <jni.h>
-#include <binder/IServiceManager.h>
-#include <media/IAudioFlinger.h>
-#include <media/AudioSystem.h>
-#include <system/audio.h>
-#include <utils/Log.h>
-#include <utils/SystemClock.h>
-
-using namespace android;
-
-/*
- * Native methods used by
- * cts/tests/tests/security/src/android/security/cts/AudioFlingerBinderTest.java
- */
-
-#define TEST_ARRAY_SIZE 10000
-#define MAX_ARRAY_SIZE 1024
-#define TEST_PATTERN 0x55
-
-class MyDeathClient: public IBinder::DeathRecipient
-{
-public:
-    MyDeathClient() :
-        mAfIsDead(false) {
-    }
-
-    bool afIsDead() const { return mAfIsDead; }
-
-    // DeathRecipient
-    virtual void binderDied(const wp<IBinder>& who __unused) { mAfIsDead = true; }
-
-private:
-    bool mAfIsDead;
-};
-
-
-static bool connectAudioFlinger(sp<IAudioFlinger>& af, sp<MyDeathClient> &dr)
-{
-    int64_t startTime = 0;
-    while (af == 0) {
-        sp<IBinder> binder = defaultServiceManager()->checkService(String16("media.audio_flinger"));
-        if (binder == 0) {
-            if (startTime == 0) {
-                startTime = uptimeMillis();
-            } else if ((uptimeMillis()-startTime) > 10000) {
-                ALOGE("timeout while getting audio flinger service");
-                return false;
-            }
-            sleep(1);
-        } else {
-            af = interface_cast<IAudioFlinger>(binder);
-            dr = new MyDeathClient();
-            binder->linkToDeath(dr);
-        }
-    }
-    return true;
-}
-
-/*
- * Checks that AudioSystem::setMasterMute() does not crash mediaserver if a duplicated output
- * is opened.
- */
-jboolean android_security_cts_AudioFlinger_test_setMasterMute(JNIEnv* env __unused,
-                                                           jobject thiz __unused)
-{
-    sp<IAudioFlinger> af;
-    sp<MyDeathClient> dr;
-
-    if (!connectAudioFlinger(af, dr)) {
-        return false;
-    }
-
-    // force opening of a duplicating output
-    status_t status = AudioSystem::setDeviceConnectionState(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
-                                          AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
-                                          "0", "");
-
-    bool mute;
-    status = AudioSystem::getMasterMute(&mute);
-    if (status != NO_ERROR) {
-        return false;
-    }
-
-    AudioSystem::setMasterMute(!mute);
-
-    sleep(1);
-
-    // Check that mediaserver did not crash
-    if (dr->afIsDead()) {
-        return false;
-    }
-
-    AudioSystem::setMasterMute(mute);
-
-    AudioSystem::setDeviceConnectionState(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
-                                          AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
-                                          "0", "");
-
-    AudioSystem::setMasterMute(false);
-
-    return true;
-}
-
-jboolean android_security_cts_AudioFlinger_test_setMasterVolume(JNIEnv* env __unused,
-                                                           jobject thiz __unused)
-{
-    sp<IAudioFlinger> af;
-    sp<MyDeathClient> dr;
-
-    if (!connectAudioFlinger(af, dr)) {
-        return false;
-    }
-
-    // force opening of a duplicating output
-    status_t status = AudioSystem::setDeviceConnectionState(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
-                                          AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
-                                          "0", "");
-
-    float vol;
-    status = AudioSystem::getMasterVolume(&vol);
-    if (status != NO_ERROR) {
-        return false;
-    }
-
-    AudioSystem::setMasterVolume(vol < 0.5 ? 1.0 : 0.0);
-
-    sleep(1);
-
-    // Check that mediaserver did not crash
-    if (dr->afIsDead()) {
-        return false;
-    }
-
-    AudioSystem::setMasterMute(vol);
-
-    AudioSystem::setDeviceConnectionState(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
-                                          AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
-                                          "0", "");
-
-    return true;
-}
-
-jboolean android_security_cts_AudioFlinger_test_listAudioPorts(JNIEnv* env __unused,
-                                                           jobject thiz __unused)
-{
-    sp<IAudioFlinger> af;
-    sp<MyDeathClient> dr;
-
-    if (!connectAudioFlinger(af, dr)) {
-        return false;
-    }
-
-    unsigned int num_ports = TEST_ARRAY_SIZE;
-    struct audio_port *ports =
-            (struct audio_port *)calloc(TEST_ARRAY_SIZE, sizeof(struct audio_port));
-
-    memset(ports, TEST_PATTERN, TEST_ARRAY_SIZE * sizeof(struct audio_port));
-
-    status_t status = af->listAudioPorts(&num_ports, ports);
-
-    sleep(1);
-
-    // Check that the memory content above the max allowed array size was not changed
-    char *ptr = (char *)(ports + MAX_ARRAY_SIZE);
-    for (size_t i = 0; i < TEST_ARRAY_SIZE - MAX_ARRAY_SIZE; i++) {
-        if (ptr[i * sizeof(struct audio_port)] != TEST_PATTERN) {
-            free(ports);
-            return false;
-        }
-    }
-
-    free(ports);
-
-    // Check that mediaserver did not crash
-    if (dr->afIsDead()) {
-        return false;
-    }
-
-    return true;
-}
-
-jboolean android_security_cts_AudioFlinger_test_createEffect(JNIEnv* env __unused,
-                                                             jobject thiz __unused)
-{
-    sp<IAudioFlinger> af;
-    sp<MyDeathClient> dr;
-
-    if (!connectAudioFlinger(af, dr)) {
-        return false;
-    }
-
-    for (int j = 0; j < 10; ++j) {
-        Parcel data, reply;
-        data.writeInterfaceToken(af->getInterfaceDescriptor());
-        data.writeInt32((int32_t)j);
-        status_t status = af->asBinder(af)->transact(40, data, &reply); // 40 is CREATE_EFFECT
-        if (status != NO_ERROR) {
-            return false;
-        }
-
-        status = (status_t)reply.readInt32();
-        if (status == NO_ERROR) {
-            continue;
-        }
-
-        int id = reply.readInt32();
-        int enabled = reply.readInt32();
-        sp<IEffect> effect = interface_cast<IEffect>(reply.readStrongBinder());
-        effect_descriptor_t desc;
-        effect_descriptor_t descTarget;
-        memset(&desc, 0, sizeof(effect_descriptor_t));
-        memset(&descTarget, 0, sizeof(effect_descriptor_t));
-        reply.read(&desc, sizeof(effect_descriptor_t));
-        if (id != 0 || enabled != 0 || memcmp(&desc, &descTarget, sizeof(effect_descriptor_t))) {
-            return false;
-        }
-    }
-
-    sleep(1);
-
-    // Check that mediaserver did not crash
-    if (dr->afIsDead()) {
-        return false;
-    }
-
-    return true;
-}
-
-static JNINativeMethod gMethods[] = {
-    {  "native_test_setMasterMute", "()Z",
-            (void *) android_security_cts_AudioFlinger_test_setMasterMute },
-    {  "native_test_setMasterVolume", "()Z",
-            (void *) android_security_cts_AudioFlinger_test_setMasterVolume },
-    {  "native_test_listAudioPorts", "()Z",
-            (void *) android_security_cts_AudioFlinger_test_listAudioPorts },
-    {  "native_test_createEffect", "()Z",
-            (void *) android_security_cts_AudioFlinger_test_createEffect },
-};
-
-int register_android_security_cts_AudioFlingerBinderTest(JNIEnv* env)
-{
-    jclass clazz = env->FindClass("android/security/cts/AudioFlingerBinderTest");
-    return env->RegisterNatives(clazz, gMethods,
-            sizeof(gMethods) / sizeof(JNINativeMethod));
-}
diff --git a/tests/tests/security/jni/android_security_cts_AudioPolicyBinderTest.cpp b/tests/tests/security/jni/android_security_cts_AudioPolicyBinderTest.cpp
deleted file mode 100644
index 6011920..0000000
--- a/tests/tests/security/jni/android_security_cts_AudioPolicyBinderTest.cpp
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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 LOG_TAG "AudioPolicyBinderTest-JNI"
-
-#include <jni.h>
-#include <binder/IServiceManager.h>
-#include <binder/Parcel.h>
-#include <media/IAudioPolicyService.h>
-#include <media/AudioSystem.h>
-#include <system/audio.h>
-#include <utils/Log.h>
-#include <utils/SystemClock.h>
-
-using namespace android;
-
-/*
- * Native methods used by
- * cts/tests/tests/security/src/android/security/cts/AudioPolicyBinderTest.java
- */
-
-static bool init(sp<IAudioPolicyService>& aps, audio_io_handle_t *output, int *session)
-{
-    aps = 0;
-    if (output != NULL) {
-        *output = AUDIO_IO_HANDLE_NONE;
-    }
-    if (session != NULL) {
-        *session = AUDIO_UNIQUE_ID_ALLOCATE;
-    }
-
-    int64_t startTime = 0;
-    sp<IServiceManager> sm = defaultServiceManager();
-    while (aps == 0) {
-        sp<IBinder> binder = defaultServiceManager()->checkService(String16("media.audio_policy"));
-        if (binder == 0) {
-            if (startTime == 0) {
-                startTime = uptimeMillis();
-            } else if ((uptimeMillis()-startTime) > 10000) {
-                ALOGE("timeout while getting audio policy service");
-                return false;
-            }
-            sleep(1);
-        } else {
-            aps = interface_cast<IAudioPolicyService>(binder);
-        }
-    }
-
-    if (output != NULL) {
-        // get a valid output. Any use case will do.
-        for (int stream = AUDIO_STREAM_MIN; stream < AUDIO_STREAM_CNT; stream++) {
-            *output = AudioSystem::getOutput((audio_stream_type_t)stream);
-            if (*output != AUDIO_IO_HANDLE_NONE) {
-                break;
-            }
-        }
-        if (*output == AUDIO_IO_HANDLE_NONE) {
-            ALOGE("cannot get valid audio output");
-            return false;
-        }
-    }
-    if (session != NULL) {
-        //get a valid session
-        *session = AudioSystem::newAudioUniqueId();
-        if (*session == AUDIO_UNIQUE_ID_ALLOCATE) {
-            ALOGE("cannot get valid audio session");
-            return false;
-        }
-    }
-    return true;
-}
-
-/*
- * Checks that IAudioPolicyService::startOutput() cannot be called with an
- * invalid stream type.
- */
-jboolean android_security_cts_AudioPolicy_test_startOutput(JNIEnv* env __unused,
-                                                           jobject thiz __unused)
-{
-    sp<IAudioPolicyService> aps;
-    audio_io_handle_t output;
-    int session;
-
-    if (!init(aps, &output, &session)) {
-        return false;
-    }
-
-    status_t status = aps->startOutput(output, (audio_stream_type_t)(AUDIO_STREAM_MIN -1),
-                                       (audio_session_t)session);
-    if (status == NO_ERROR) {
-        return false;
-    }
-    status = aps->startOutput(output, (audio_stream_type_t)AUDIO_STREAM_CNT,
-                              (audio_session_t)session);
-    if (status == NO_ERROR) {
-        return false;
-    }
-    return true;
-}
-
-/*
- * Checks that IAudioPolicyService::stopOutput() cannot be called with an
- * invalid stream type.
- */
-jboolean android_security_cts_AudioPolicy_test_stopOutput(JNIEnv* env __unused,
-                                                           jobject thiz __unused)
-{
-    sp<IAudioPolicyService> aps;
-    audio_io_handle_t output;
-    int session;
-
-    if (!init(aps, &output, &session)) {
-        return false;
-    }
-
-    status_t status = aps->stopOutput(output, (audio_stream_type_t)(AUDIO_STREAM_MIN -1),
-                                      (audio_session_t)session);
-    if (status == NO_ERROR) {
-        return false;
-    }
-    status = aps->stopOutput(output, (audio_stream_type_t)AUDIO_STREAM_CNT,
-                             (audio_session_t)session);
-    if (status == NO_ERROR) {
-        return false;
-    }
-    return true;
-}
-
-/*
- * Checks that IAudioPolicyService::isStreamActive() cannot be called with an
- * invalid stream type.
- */
-jboolean android_security_cts_AudioPolicy_test_isStreamActive(JNIEnv* env __unused,
-                                                           jobject thiz __unused)
-{
-    sp<IAudioPolicyService> aps;
-
-    if (!init(aps, NULL, NULL)) {
-        return false;
-    }
-
-    bool status = aps->isStreamActive((audio_stream_type_t)(-1), 0);
-    if (status) {
-        return false;
-    }
-    status = aps->isStreamActive((audio_stream_type_t)AUDIO_STREAM_CNT, 0);
-    if (status) {
-        return false;
-    }
-    return true;
-}
-
-/*
- * Checks that IAudioPolicyService::isStreamActiveRemotely() cannot be called with an
- * invalid stream type.
- * Test with NUM_RANDOM_TESTS random values for stream type.
- */
-jboolean android_security_cts_AudioPolicy_test_isStreamActiveRemotely(JNIEnv* env __unused,
-                                                           jobject thiz __unused)
-{
-    sp<IAudioPolicyService> aps;
-
-    if (!init(aps, NULL, NULL)) {
-        return false;
-    }
-
-    if (aps->isStreamActiveRemotely((audio_stream_type_t)(AUDIO_STREAM_MIN -1), 0)) {
-        return false;
-    }
-
-    if (aps->isStreamActiveRemotely((audio_stream_type_t)AUDIO_STREAM_CNT, 0)) {
-        return false;
-    }
-    return true;
-}
-
-jint android_security_cts_AudioPolicy_test_getStreamVolumeLeak(JNIEnv* env __unused,
-                                                           jobject thiz __unused)
-{
-    sp<IAudioPolicyService> aps;
-
-    if (!init(aps, NULL, NULL)) {
-        return -1;
-    }
-
-    // Keep synchronized with IAudioPolicyService.cpp!
-    enum {
-        GET_STREAM_VOLUME = 17,
-    };
-
-    Parcel data, reply;
-    status_t err;
-    data.writeInterfaceToken(aps->getInterfaceDescriptor());
-    data.writeInt32(-1); // stream type
-    data.writeInt32(-1); // device
-    IInterface::asBinder(aps)->transact(GET_STREAM_VOLUME, data, &reply);
-    int index = reply.readInt32();
-    err = reply.readInt32();
-
-    return index;
-}
-
-jboolean android_security_cts_AudioPolicy_test_startAudioSource(JNIEnv* env __unused,
-                                                                jobject thiz __unused)
-{
-    sp<IAudioPolicyService> aps;
-
-    if (!init(aps, NULL, NULL)) {
-        return false;
-    }
-
-    // Keep synchronized with IAudioPolicyService.cpp!
-    enum {
-        START_AUDIO_SOURCE = 41,
-    };
-
-    for (int i = 0; i < 10; ++i) {
-        Parcel data, reply;
-        data.writeInterfaceToken(aps->getInterfaceDescriptor());
-        data.writeInt32(-i);
-        IInterface::asBinder(aps)->transact(START_AUDIO_SOURCE, data, &reply);
-        status_t err = (status_t)reply.readInt32();
-        if (err == NO_ERROR) {
-            continue;
-        }
-        audio_io_handle_t handle = (audio_io_handle_t)reply.readInt32();
-        if (handle != 0) {
-            return false;
-        }
-    }
-
-    return true;
-}
-
-static JNINativeMethod gMethods[] = {
-    {  "native_test_startOutput", "()Z",
-            (void *) android_security_cts_AudioPolicy_test_startOutput },
-    {  "native_test_stopOutput", "()Z",
-                (void *) android_security_cts_AudioPolicy_test_stopOutput },
-    {  "native_test_isStreamActive", "()Z",
-                (void *) android_security_cts_AudioPolicy_test_isStreamActive },
-    {  "native_test_isStreamActiveRemotely", "()Z",
-                (void *) android_security_cts_AudioPolicy_test_isStreamActiveRemotely },
-    {  "native_test_getStreamVolumeLeak", "()I",
-                (void *) android_security_cts_AudioPolicy_test_getStreamVolumeLeak },
-    {  "native_test_startAudioSource", "()Z",
-                (void *) android_security_cts_AudioPolicy_test_startAudioSource },
-};
-
-int register_android_security_cts_AudioPolicyBinderTest(JNIEnv* env)
-{
-    jclass clazz = env->FindClass("android/security/cts/AudioPolicyBinderTest");
-    return env->RegisterNatives(clazz, gMethods,
-            sizeof(gMethods) / sizeof(JNINativeMethod));
-}
diff --git a/tests/tests/security/jni/android_security_cts_GraphicBufferInfoLeakTest.cpp b/tests/tests/security/jni/android_security_cts_GraphicBufferInfoLeakTest.cpp
deleted file mode 100644
index d0cd347..0000000
--- a/tests/tests/security/jni/android_security_cts_GraphicBufferInfoLeakTest.cpp
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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 LOG_NDEBUG 0
-#define LOG_TAG "GraphicBufferInfoLeakTest-JNI"
-
-#include <jni.h>
-#include <JNIHelp.h>
-
-#include <binder/Parcel.h>
-#include <binder/IServiceManager.h>
-
-#include <gui/IGraphicBufferProducer.h>
-#include <gui/IGraphicBufferConsumer.h>
-#include <media/IMediaPlayerService.h>
-#include <media/IMediaRecorder.h>
-#include <media/IOMX.h>
-#include <media/stagefright/MediaErrors.h>
-
-#include <sys/stat.h>
-#include <fcntl.h>
-
-using namespace android;
-
-static sp<IMediaPlayerService> getMediaPlayerService()
-{
-   sp<IServiceManager> sm = defaultServiceManager();
-   sp<IBinder> mediaPlayerService = sm->checkService(String16("media.player"));
-
-   sp<IMediaPlayerService> iMPService = IMediaPlayerService::asInterface(mediaPlayerService);
-   return iMPService;
-}
-
-jint android_security_cts_GraphicBuffer_test_attachBufferInfoLeak(JNIEnv* env,
-                                                           jobject thiz __unused)
-{
-    sp<IMediaPlayerService> iMPService = getMediaPlayerService();
-
-    // get IOMX
-    // Keep synchronized with IMediaPlayerService.cpp!
-    enum {
-        GET_OMX = 4,
-    };
-
-    status_t  err;
-    Parcel data, reply;
-    data.writeInterfaceToken(iMPService->getInterfaceDescriptor());
-    err = IMediaPlayerService::asBinder(iMPService)->transact(GET_OMX, data, &reply);
-    if (err != NO_ERROR) {
-        jniThrowException(env, "java/lang/RuntimeException", "GET_OMX failed");
-    }
-
-    // get IGraphicBufferConsumer
-    sp<IGraphicBufferProducer> iBufferProducer;
-    sp<IGraphicBufferConsumer> iBufferConsumer;
-    sp<IOMX> iOmx = interface_cast<IOMX>(reply.readStrongBinder());
-    err = iOmx->createPersistentInputSurface(&iBufferProducer, &iBufferConsumer);
-    if (err != NO_ERROR) {
-        jniThrowException(env, "java/lang/RuntimeException", "createPersistentInputSurface failed");
-        return err;
-    }
-
-    // Keep synchronized with IGraphicBufferConsumer.cpp!
-    enum {
-        ATTACH_BUFFER = 3,
-    };
-
-    for (;;) {
-        Parcel data2, reply2;
-        data2.writeInterfaceToken(iBufferConsumer->getInterfaceDescriptor());
-        err = IGraphicBufferConsumer::asBinder(iBufferConsumer)->transact(ATTACH_BUFFER, data2, &reply2);
-        if (err != NO_ERROR) {
-            jniThrowException(env, "java/lang/RuntimeException", "ATTACH_BUFFER failed");
-        }
-
-        int32_t slot = reply2.readInt32();
-        status_t result = reply2.readInt32();
-        ALOGV("slot %d", slot);
-        if (result != 0) {
-            // only check for leaked data in error case
-            return slot;
-        }
-    }
-}
-
-jint android_security_cts_GraphicBuffer_test_queueBufferInfoLeak(JNIEnv* env,
-                                                           jobject thiz __unused)
-{
-    sp<IMediaPlayerService> iMPService = getMediaPlayerService();
-    sp<IMediaRecorder> recorder = iMPService->createMediaRecorder(String16("GraphicBufferInfoLeakTest"));
-
-    const char *fileName = "/dev/null";
-    int fd = open(fileName, O_RDWR | O_CREAT, 0744);
-    if (fd < 0) {
-        jniThrowException(env, "java/lang/RuntimeException", "open output failed");
-        return fd;
-    }
-
-    recorder->setVideoSource(2);
-    recorder->setOutputFile(fd, 0, 0);
-    recorder->setOutputFormat(0);
-    recorder->init();
-    recorder->prepare();
-    recorder->start();
-
-    //get IGraphicBufferProducer
-    sp<IGraphicBufferProducer> iGBP = recorder->querySurfaceMediaSource();
-    ALOGV("fd %d, Get iGBP instance, 0x%08x\n", fd, iGBP.get());
-
-    // Keep synchronized with IGraphicBufferProducer.cpp!
-    enum {
-        QUEUE_BUFFER = 7,
-    };
-
-    for (;;) {
-        status_t err;
-        Parcel data, reply;
-        data.writeInterfaceToken(iGBP->getInterfaceDescriptor());
-        data.writeInt32(-1);
-        err = IGraphicBufferProducer::asBinder(iGBP)->transact(QUEUE_BUFFER, data, &reply);
-        if (err != NO_ERROR) {
-            recorder->stop();
-            recorder->release();
-            jniThrowException(env, "java/lang/RuntimeException", "QUEUE_BUFFER failed");
-            return err;
-        }
-
-        size_t len = reply.dataAvail();
-        int32_t result; // last sizeof(int32_t) bytes of Parcel
-        ALOGV("dataAvail = %zu\n", len);
-        if (len < sizeof(result)) {
-            // must contain result
-            recorder->stop();
-            recorder->release();
-            jniThrowException(env, "java/lang/RuntimeException", "reply malformed");
-            return ERROR_MALFORMED;
-        }
-
-        uint8_t *reply_data = (uint8_t *)reply.data();
-        memcpy(&result, reply_data + len - sizeof(result), sizeof(result));
-        if (result == NO_ERROR) {
-            // only check for leaked data in error case
-            continue;
-        }
-
-        uint8_t leaked_data = 0;
-        for (size_t i = 0; i < len - sizeof(result); ++i) {
-            ALOGV("IGraphicBufferProducer_InfoLeak reply_data[%d] = 0x%08x", i, reply_data[i]);
-            if (reply_data[i]) {
-                leaked_data = reply_data[i];
-                break;
-            }
-        }
-
-        recorder->stop();
-        recorder->release();
-        return leaked_data;
-    }
-}
-
-static JNINativeMethod gMethods[] = {
-    {  "native_test_attachBufferInfoLeak", "()I",
-            (void *) android_security_cts_GraphicBuffer_test_attachBufferInfoLeak },
-    {  "native_test_queueBufferInfoLeak", "()I",
-            (void *) android_security_cts_GraphicBuffer_test_queueBufferInfoLeak },
-};
-
-int register_android_security_cts_GraphicBufferInfoLeakTest(JNIEnv* env)
-{
-    jclass clazz = env->FindClass("android/security/cts/GraphicBufferInfoLeakTest");
-    return env->RegisterNatives(clazz, gMethods,
-            sizeof(gMethods) / sizeof(JNINativeMethod));
-}
diff --git a/tests/tests/security/jni/android_security_cts_LoadEffectLibraryTest.cpp b/tests/tests/security/jni/android_security_cts_LoadEffectLibraryTest.cpp
deleted file mode 100644
index 6e0f6e1..0000000
--- a/tests/tests/security/jni/android_security_cts_LoadEffectLibraryTest.cpp
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <jni.h>
-#include <binder/IServiceManager.h>
-#include <media/IAudioFlinger.h>
-#include <media/AudioEffect.h>
-
-
-using namespace android;
-
-
-/*
- * Native method used by
- * cts/tests/tests/security/src/android/security/cts/LoadEffectLibraryTest.java
- *
- * Checks that no IAudioFlinger binder transaction manages to load an effect library
- * as LOAD_EFFECT_LIBRARY did in gingerbread.
- */
-
-jboolean android_security_cts_LoadEffectLibraryTest_doLoadLibraryTest(JNIEnv* env, jobject thiz)
-{
-    sp<IServiceManager> sm = defaultServiceManager();
-    if (sm == 0) {
-        return false;
-    }
-
-    sp<IBinder> binder = sm->getService(String16("media.audio_flinger"));
-    if (binder == 0) {
-        return false;
-    }
-
-    Parcel data, reply;
-    sp<IAudioFlinger> af = interface_cast<IAudioFlinger>(binder);
-
-    data.writeInterfaceToken(af->getInterfaceDescriptor());
-    // test library path defined in cts/tests/tests/security/testeffect/Android.mk
-    data.writeCString("/system/lib/soundfx/libctstesteffect.so");
-
-    // test 100 IAudioFlinger binder transaction values and check that none corresponds
-    // to LOAD_EFFECT_LIBRARY and successfully loads our test library
-    for (uint32_t i = IBinder::FIRST_CALL_TRANSACTION;
-            i < IBinder::FIRST_CALL_TRANSACTION + 100;
-            i++) {
-        status_t status = binder->transact(i, data, &reply);
-        if (status != NO_ERROR) {
-            continue;
-        }
-        status = reply.readInt32();
-        if (status != NO_ERROR) {
-            continue;
-        }
-
-        // Effect UUID defined in cts/tests/tests/security/testeffect/CTSTestEffect.cpp
-        effect_uuid_t uuid =
-                    {0xff93e360, 0x0c3c, 0x11e3, 0x8a97, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
-        effect_descriptor_t desc;
-
-        status = AudioEffect::getEffectDescriptor(&uuid, &desc);
-        if (status == NO_ERROR) {
-            return false;
-        }
-    }
-    return true;
-}
-
-static JNINativeMethod gMethods[] = {
-    {  "doLoadLibraryTest", "()Z",
-            (void *) android_security_cts_LoadEffectLibraryTest_doLoadLibraryTest },
-};
-
-int register_android_security_cts_LoadEffectLibraryTest(JNIEnv* env)
-{
-    jclass clazz = env->FindClass("android/security/cts/LoadEffectLibraryTest");
-    return env->RegisterNatives(clazz, gMethods,
-            sizeof(gMethods) / sizeof(JNINativeMethod));
-}
diff --git a/tests/tests/security/jni/android_security_cts_MediaCryptoTest.cpp b/tests/tests/security/jni/android_security_cts_MediaCryptoTest.cpp
deleted file mode 100644
index 86141f8..0000000
--- a/tests/tests/security/jni/android_security_cts_MediaCryptoTest.cpp
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* Original code copied from NDK Native-media sample code */
-
-//#define LOG_NDEBUG 0
-#define TAG "NativeMediaCrypto"
-#include <log/log.h>
-
-#include <android_media_MediaCrypto.h>
-#include <assert.h>
-#include <binder/MemoryDealer.h>
-#include <jni.h>
-#include <media/ICrypto.h>
-#include <media/stagefright/foundation/AString.h>
-#include <pthread.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <utils/StrongPointer.h>
-#include <semaphore.h>
-
-
-static const size_t kBufferSize = 1024;
-
-using namespace android;
-
-static jboolean testCrypto(sp<ICrypto> icrypto,
-        const CryptoPlugin::SubSample *subSample, CryptoPlugin::Mode mode)
-{
-    // Allocate source buffer
-    sp<MemoryDealer> memDealer = new MemoryDealer(kBufferSize, "MediaCryptoTest");
-    sp<IMemory> srcBuffer = memDealer->allocate(kBufferSize);
-    if (!srcBuffer->pointer()) {
-        ALOGE("Failed to allocate source buffer");
-        return false;
-    }
-    memset(srcBuffer->pointer(), 's', kBufferSize);
-
-    // Invalid dest pointer should fault if mediaserver attempts
-    // to write to it.  Don't use NULL because that's probably
-    // checked for.
-    void *dstPtr = reinterpret_cast<void *>(1);
-
-    // Spoof the device as being secure
-    bool secure = true;
-
-    uint8_t key[16] = {0};
-    uint8_t iv[16] = {0};
-    uint32_t offset = 0;
-    AString errorDetailMsg;
-
-    ssize_t result = icrypto->decrypt(secure, key, iv, mode, srcBuffer, offset,
-            subSample, 1, dstPtr, &errorDetailMsg);
-
-    // call should return an error and shouldn't kill media server
-    return (result != OK && result != DEAD_OBJECT);
-}
-
-//
-// This native code is currently disabled, as it depends on a non-NDK
-// shared library, which may not be available on all systems.
-// 
-#if 0
-//Test for icrypto interface vulnerabilities
-extern "C" jboolean Java_android_security_cts_MediaCryptoTest_validateCryptoNative(JNIEnv *env,
-        jclass /*clazz*/, jobject crypto)
-{
-    bool result = false;
-    sp<ICrypto> icrypto = JCrypto::GetCrypto(env, crypto);
-    if (icrypto != NULL) {
-        if (icrypto->requiresSecureDecoderComponent("video/avc")) {
-            ALOGI("device is secure, bypassing test");
-            return true;
-        }
-
-        CryptoPlugin::Mode unencryptedMode = CryptoPlugin::kMode_Unencrypted;
-        CryptoPlugin::Mode aesCtrMode = CryptoPlugin::kMode_AES_CTR;
-
-        CryptoPlugin::SubSample clrSubSample = {kBufferSize, 0};
-        CryptoPlugin::SubSample encSubSample = {0, kBufferSize};
-
-        result =
-            testCrypto(icrypto, &clrSubSample, unencryptedMode) &&
-            testCrypto(icrypto, &clrSubSample, aesCtrMode) &&
-            testCrypto(icrypto, &encSubSample, unencryptedMode) &&
-            testCrypto(icrypto, &encSubSample, aesCtrMode);
-    } else {
-        ALOGE("Failed to get icrypto interface");
-    }
-    return result;
-}
-#endif
-
-
diff --git a/tests/tests/security/jni/android_security_cts_MediaPlayerInfoLeakTest.cpp b/tests/tests/security/jni/android_security_cts_MediaPlayerInfoLeakTest.cpp
deleted file mode 100644
index 0c61f25..0000000
--- a/tests/tests/security/jni/android_security_cts_MediaPlayerInfoLeakTest.cpp
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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 LOG_TAG "MediaPlayerInfoLeakTest-JNI"
-
-#include <jni.h>
-
-#include <binder/Parcel.h>
-#include <binder/IServiceManager.h>
-
-#include <media/IMediaPlayer.h>
-#include <media/IMediaPlayerService.h>
-#include <media/IMediaPlayerClient.h>
-
-#include <sys/stat.h>
-
-using namespace android;
-
-static status_t connectMediaPlayer(sp<IMediaPlayer>& iMP)
-{
-   sp<IServiceManager> sm = defaultServiceManager();
-   sp<IBinder> mediaPlayerService = sm->checkService(String16("media.player"));
-
-   sp<IMediaPlayerService> iMPService = IMediaPlayerService::asInterface(mediaPlayerService);
-   sp<IMediaPlayerClient> client;
-   Parcel data, reply;
-   int dummyAudioSessionId = 1;
-   data.writeInterfaceToken(iMPService->getInterfaceDescriptor());
-   data.writeStrongBinder(IInterface::asBinder(client));
-   data.writeInt32(dummyAudioSessionId);
-
-   // Keep synchronized with IMediaPlayerService.cpp!
-    enum {
-        CREATE = IBinder::FIRST_CALL_TRANSACTION,
-    };
-   status_t err = IInterface::asBinder(iMPService)->transact(CREATE, data, &reply);
-   if (err == NO_ERROR) {
-       iMP = interface_cast<IMediaPlayer>(reply.readStrongBinder());
-   }
-   return err;
-}
-
-int testMediaPlayerInfoLeak(int command)
-{
-    sp<IMediaPlayer> iMP;
-    if (NO_ERROR != connectMediaPlayer(iMP)) {
-        return false;
-    }
-
-
-    Parcel data, reply;
-    data.writeInterfaceToken(iMP->getInterfaceDescriptor());
-    IInterface::asBinder(iMP)->transact(command, data, &reply);
-
-    int leak = reply.readInt32();
-    status_t err = reply.readInt32();
-    return  leak;
-}
-
-jint android_security_cts_MediaPlayer_test_getCurrentPositionLeak(JNIEnv* env __unused,
-                                                           jobject thiz __unused)
-{
-  // Keep synchronized with IMediaPlayer.cpp!
-  enum {
-      GET_CURRENT_POSITION = 16,
-  };
-  return testMediaPlayerInfoLeak(GET_CURRENT_POSITION);
-}
-
-jint android_security_cts_MediaPlayer_test_getDurationLeak(JNIEnv* env __unused,
-                                                           jobject thiz __unused)
-{
-  // Keep synchronized with IMediaPlayer.cpp!
-  enum {
-      GET_DURATION = 17,
-  };
-  return testMediaPlayerInfoLeak(GET_DURATION);
-}
-
-static JNINativeMethod gMethods[] = {
-    {  "native_test_getCurrentPositionLeak", "()I",
-            (void *) android_security_cts_MediaPlayer_test_getCurrentPositionLeak },
-    {  "native_test_getDurationLeak", "()I",
-            (void *) android_security_cts_MediaPlayer_test_getDurationLeak },
-};
-
-int register_android_security_cts_MediaPlayerInfoLeakTest(JNIEnv* env)
-{
-    jclass clazz = env->FindClass("android/security/cts/MediaPlayerInfoLeakTest");
-    return env->RegisterNatives(clazz, gMethods,
-            sizeof(gMethods) / sizeof(JNINativeMethod));
-}
diff --git a/tests/tests/security/jni/android_security_cts_NativeCodeTest.cpp b/tests/tests/security/jni/android_security_cts_NativeCodeTest.cpp
index 350309b..dbc8ede 100644
--- a/tests/tests/security/jni/android_security_cts_NativeCodeTest.cpp
+++ b/tests/tests/security/jni/android_security_cts_NativeCodeTest.cpp
@@ -35,6 +35,8 @@
 #include <inttypes.h>
 #include <linux/sysctl.h>
 #include <arpa/inet.h>
+#include <linux/ipc.h>
+#include <pthread.h>
 
 /*
  * Returns true iff this device is vulnerable to CVE-2013-2094.
@@ -251,6 +253,134 @@
     return true;
 }
 
+#define BUFS 256
+#define IOV_LEN 16
+#define OVERFLOW_BUF 7
+#define FIXED_ADDR 0x45678000
+#define TIMEOUT 60 /* seconds */
+
+struct iovec *iovs = NULL;
+int fd[2];
+
+void* func_map(void*)
+{
+    munmap((void*)(FIXED_ADDR), PAGE_SIZE);
+    mmap((void*)(FIXED_ADDR), PAGE_SIZE, PROT_READ | PROT_WRITE,
+            MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+    return NULL;
+}
+
+void* func_readv(void*)
+{
+    readv(fd[0], iovs, BUFS);
+    return NULL;
+}
+
+static jboolean android_security_cts_NativeCodeTest_doPipeReadVTest(JNIEnv*, jobject)
+{
+    bool ret = false;
+    unsigned int i;
+    void *bufs[BUFS];
+    struct timespec ts;
+    time_t time;
+    pthread_t thr_map, thr_readv;
+
+    if (pipe(fd) < 0) {
+        ALOGE("pipe failed:%s", strerror(errno));
+        goto __out;
+    }
+    fcntl(fd[0], F_SETFL, O_NONBLOCK);
+    fcntl(fd[1], F_SETFL, O_NONBLOCK);
+
+    iovs = (struct iovec*)malloc(BUFS * sizeof(struct iovec));
+    if (iovs == NULL) {
+        ALOGE("malloc failed:%s", strerror(errno));
+        goto __close_pipe;
+    }
+
+    /*
+     * set up to overflow iov[OVERFLOW_BUF] on non-atomic redo in kernel
+     * function pipe_iov_copy_to_user
+     */
+    iovs[OVERFLOW_BUF - 1].iov_len = IOV_LEN*10;
+    iovs[OVERFLOW_BUF].iov_base = bufs[OVERFLOW_BUF];
+    iovs[OVERFLOW_BUF].iov_len = IOV_LEN;
+
+    bufs[OVERFLOW_BUF] = mmap((void*)(FIXED_ADDR), PAGE_SIZE, PROT_READ | PROT_WRITE,
+            MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
+    if (bufs[OVERFLOW_BUF] == MAP_FAILED) {
+        ALOGE("mmap fixed addr failed:%s", strerror(errno));
+        goto __close_pipe;
+    }
+
+    for (i = 0; i < BUFS; i++) {
+        if (i == OVERFLOW_BUF) {
+            continue;
+        }
+        bufs[i] = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
+        if(bufs[i] == MAP_FAILED) {
+            ALOGE("mmap failed in %d times:%s", i, strerror(errno));
+            goto  __free_bufs;
+        }
+
+        iovs[i].iov_base = bufs[i];
+        iovs[i].iov_len = IOV_LEN;
+    }
+
+    clock_gettime(CLOCK_MONOTONIC, &ts);
+    time = ts.tv_sec;
+    while (1) {
+        write(fd[1], bufs[0], PAGE_SIZE);
+
+        pthread_create(&thr_map, NULL, func_map, NULL);
+        pthread_create(&thr_readv, NULL, func_readv, NULL);
+
+        pthread_join(thr_map, NULL);
+        pthread_join(thr_readv, NULL);
+
+        clock_gettime(CLOCK_MONOTONIC, &ts);
+        if ((ts.tv_sec - time) > TIMEOUT) {
+            ret = true;
+            break;
+        }
+    }
+
+__free_bufs:
+    for (i = 0; i < BUFS; i++) {
+        if (bufs[i]) {
+            munmap(bufs[i], PAGE_SIZE);
+        }
+    }
+
+__free_iovs:
+    free(iovs);
+
+__close_pipe:
+    close(fd[0]);
+    close(fd[1]);
+__out:
+    return ret;
+}
+
+#define SHMEMSIZE 0x1 /* request one page */
+static jboolean android_security_cts_NativeCodeTest_doSysVipcTest(JNIEnv*, jobject)
+{
+    key_t key = 0x1a25;
+
+#if defined(__i386__) || (_MIPS_SIM == _MIPS_SIM_ABI32)
+    /* system call does not exist for x86 or mips 32 */
+    return true;
+#else
+    /*
+     * Not supported in bionic. Must directly invoke syscall
+     * Only acceptable errno is ENOSYS: shmget syscall
+     * function not implemented
+     */
+    return ((syscall(SYS_shmget, key, SHMEMSIZE, IPC_CREAT | 0666) == -1)
+                && (errno == ENOSYS));
+#endif
+}
+
 static JNINativeMethod gMethods[] = {
     {  "doPerfEventTest", "()Z",
             (void *) android_security_cts_NativeCodeTest_doPerfEventTest },
@@ -266,6 +396,10 @@
             (void *) android_security_cts_NativeCodeTest_doNvmapIocFromIdTest },
     {  "doPingPongRootTest", "()Z",
             (void *) android_security_cts_NativeCodeTest_doPingPongRootTest },
+    {  "doPipeReadVTest", "()Z",
+            (void *) android_security_cts_NativeCodeTest_doPipeReadVTest },
+    {  "doSysVipcTest", "()Z",
+            (void *) android_security_cts_NativeCodeTest_doSysVipcTest },
 };
 
 int register_android_security_cts_NativeCodeTest(JNIEnv* env)
diff --git a/tests/tests/security/jni/android_security_cts_SELinuxTest.cpp b/tests/tests/security/jni/android_security_cts_SELinuxTest.cpp
index a68bfb6..8f164bc 100644
--- a/tests/tests/security/jni/android_security_cts_SELinuxTest.cpp
+++ b/tests/tests/security/jni/android_security_cts_SELinuxTest.cpp
@@ -29,50 +29,6 @@
 typedef UniquePtr<char[], SecurityContext_Delete> Unique_SecurityContext;
 
 /*
- * Function: checkSELinuxAccess
- * Purpose: Check permissions between two security contexts.
- * Parameters: subjectContextStr: subject security context as a string
- *             objectContextStr: object security context as a string
- *             objectClassStr: object's security class name as a string
- *             permissionStr: permission name as a string
- * Returns: boolean: (true) if permission was granted, (false) otherwise
- * Exceptions: NullPointerException if any argument is NULL
- */
-static jboolean android_security_cts_SELinuxTest_checkSELinuxAccess(JNIEnv *env, jobject, jstring subjectContextStr,
-        jstring objectContextStr, jstring objectClassStr, jstring permissionStr, jstring auxStr) {
-    if (subjectContextStr == NULL || objectContextStr == NULL || objectClassStr == NULL
-            || permissionStr == NULL || auxStr == NULL) {
-        jniThrowNullPointerException(env, NULL);
-        return false;
-    }
-
-    ScopedUtfChars subjectContext(env, subjectContextStr);
-    ScopedUtfChars objectContext(env, objectContextStr);
-    ScopedUtfChars objectClass(env, objectClassStr);
-    ScopedUtfChars permission(env, permissionStr);
-    ScopedUtfChars aux(env, auxStr);
-
-    char *tmp1 = const_cast<char *>(subjectContext.c_str());
-    char *tmp2 = const_cast<char *>(objectContext.c_str());
-    char *tmp3 = const_cast<char *>(aux.c_str());
-    int accessGranted = selinux_check_access(tmp1, tmp2, objectClass.c_str(), permission.c_str(), tmp3);
-    return (accessGranted == 0) ? true : false;
-}
-
-static jboolean android_security_cts_SELinuxTest_checkSELinuxContext(JNIEnv *env, jobject, jstring contextStr) {
-    if (contextStr == NULL) {
-        jniThrowNullPointerException(env, NULL);
-        return false;
-    }
-
-    ScopedUtfChars context(env, contextStr);
-
-    char *tmp = const_cast<char *>(context.c_str());
-    int validContext = security_check_context(tmp);
-    return (validContext == 0) ? true : false;
-}
-
-/*
  * Function: getFileContext
  * Purpose: retrieves the context associated with the given path in the file system
  * Parameters:
@@ -101,26 +57,13 @@
 }
 
 static JNINativeMethod gMethods[] = {
-    {  "checkSELinuxAccess", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z",
-            (void *) android_security_cts_SELinuxTest_checkSELinuxAccess },
-    {  "checkSELinuxContext", "(Ljava/lang/String;)Z",
-            (void *) android_security_cts_SELinuxTest_checkSELinuxContext },
     { "getFileContext", "(Ljava/lang/String;)Ljava/lang/String;",
             (void*) getFileContext },
 };
 
-static int log_callback(int type __attribute__((unused)), const char *fmt __attribute__((unused)), ...)
-{
-    /* do nothing - silence the avc denials */
-    return 0;
-}
-
 int register_android_security_cts_SELinuxTest(JNIEnv* env)
 {
     jclass clazz = env->FindClass("android/security/cts/SELinuxTest");
-    union selinux_callback cb;
-    cb.func_log = log_callback;
-    selinux_set_callback(SELINUX_CB_LOG, cb);
 
     return env->RegisterNatives(clazz, gMethods,
             sizeof(gMethods) / sizeof(JNINativeMethod));
diff --git a/tests/tests/security/jni/android_security_cts_StagefrightFoundationTest.cpp b/tests/tests/security/jni/android_security_cts_StagefrightFoundationTest.cpp
deleted file mode 100644
index d16bd38..0000000
--- a/tests/tests/security/jni/android_security_cts_StagefrightFoundationTest.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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 LOG_TAG "AudioEffectBinderTest-JNI"
-
-#include <cstdio>
-#include <jni.h>
-#include <binder/Parcel.h>
-#include <media/stagefright/foundation/AMessage.h>
-
-using namespace android;
-
-/*
- * Native methods used by
- * cts/tests/tests/security/src/android/security/cts/StagefrightFoundationTest.java
- */
-
-static jboolean android_security_cts_StagefrightFoundation_test_aMessageFromParcel(
-        JNIEnv* env __unused, jobject thiz __unused)
-{
-    const int kMaxNumItems = 64;
-    const int kNumItems = kMaxNumItems + 1 + 1000;
-    char name[128];
-
-    Parcel data;
-    data.writeInt32(0);  // what
-    data.writeInt32(kNumItems);  // numItems
-    for (int i = 0; i < kMaxNumItems; ++i) {
-        snprintf(name, sizeof(name), "item-%d", i);
-        data.writeCString(name);  // name
-        data.writeInt32(0);  // kTypeInt32
-        data.writeInt32(i);  // value
-    }
-    data.writeCString("evil");  // name
-    data.writeInt32(0);  // kTypeInt32
-    data.writeInt32(0);  // value
-    // NOTE: This could overwrite mNumItems!
-
-    for (int i = 0; i < 1000; ++i) {
-        snprintf(name, sizeof(name), "evil-%d", i);
-        data.writeCString(name);  // name
-        data.writeInt32(0);  // kTypeInt32
-        data.writeInt32(0);  // value
-    }
-
-    data.setDataPosition(0);
-    sp<AMessage> msg = AMessage::FromParcel(data);
-
-    for (int i = 0; i < kMaxNumItems; ++i) {
-        snprintf(name, sizeof(name), "item-%d", i);
-        int32_t value;
-        if (!msg->findInt32(name, &value)) {
-            ALOGE("cannot find value for %s", name);
-            return JNI_FALSE;
-        }
-        if (value != i) {
-            ALOGE("value is changed: expected %d actual %d", i, value);
-            return JNI_FALSE;
-        }
-    }
-    return JNI_TRUE;
-}
-
-int register_android_security_cts_StagefrightFoundationTest(JNIEnv *env)
-{
-    static JNINativeMethod methods[] = {
-        { "native_test_aMessageFromParcel", "()Z",
-                (void *) android_security_cts_StagefrightFoundation_test_aMessageFromParcel},
-    };
-
-    jclass clazz = env->FindClass("android/security/cts/StagefrightFoundationTest");
-    return env->RegisterNatives(clazz, methods, sizeof(methods) / sizeof(methods[0]));
-}
diff --git a/tests/tests/security/res/raw/intermediate_test_invalid.pem b/tests/tests/security/res/raw/intermediate_test_invalid.pem
new file mode 100644
index 0000000..c59cd1c
--- /dev/null
+++ b/tests/tests/security/res/raw/intermediate_test_invalid.pem
@@ -0,0 +1,36 @@
+-----BEGIN CERTIFICATE-----
+MIIC5DCCAcygAwIBAgIDAsaEMA0GCSqGSIb3DQEBCwUAMBcxFTATBgNVBAMTDElu
+dGVybWVkaWF0ZTAqGBMyMDE1MDEwMTAwMDAwMCswMDAwGBMyMDM4MDEwMTAwMDAw
+MCswMDAwMBYxFDASBgNVBAMTC2FuZHJvaWQuY29tMIIBIjANBgkqhkiG9w0BAQEF
+AAOCAQ8AMIIBCgKCAQEArajnAN15AzwWOPIwicOfvykiSyL+ZIAeVoAVEKIWtFHS
+Xk/8MDV39tv0xIzisv+buZ5RjXK0i7uSsDieQZKTo7fLyEb4ixeoYDKaxBfuF3r9
+nduLzyZRQDBNprGcKsBMAnOyA05LtkTXJGtSb8JOhEVrFCB4Rqa0cCimMP0/n66M
+liRFPB87v5eQ6qnaS3xUrobKEFAjCOCq0tTBGReW4tY4mBPoVLUFzYjJhgJDw4MZ
+c+GviKZO2dEWHmAtm+Y1tVpw05aht5I5Apk+D2GZb6VAI37zgRLOS0sZ1vvk33Wx
+RC6RExaHBj1umu0R7HBNDMus0/e+tHtrLChJ+1/WKwIDAQABoy4wLDAPBgNVHRMB
+Af8EBTADAQH/MBkGA1UdEQEB/wQPMA2CC2FuZHJvaWQuY29tMA0GCSqGSIb3DQEB
+CwUAA4IBAQBCA61jUfu6qJmNQSGXVzhcWn2Vf/49hVy3ThDTfp+ja8oSkvHng6Zp
+P6YupR5xaq4SAWWNJ0ZKYqC1hKplYREyUXelRtsfwk+6ReUabHH43XCxxib92f4Q
+lUhyU0DncTv8ClIcP5Kiigfrza1j9qr/bXd6xN2hFWHQ0BCTusHezQ1KVQ3ePCSR
+DkkbwQm++WOBWBjHDzEbDeawQvyKgg+WHHsseoTQBeUbJ3Zjn47Zrn2S5zB2pOrj
+I1TPvTXv5S+1TgENBaRic8YtTABzyT/egAhY9f+gZa/IzXUwjOWLx8o4/5jBF5SE
+4noLoIRseX7JGGAiql+tDpeqcMq8w0KZ
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIC5DCCAcygAwIBAgIDCY0fMA0GCSqGSIb3DQEBCwUAMBIxEDAOBgNVBAMTB1Jv
+b3QgQ0EwKhgTMjAxNTAxMDEwMDAwMDArMDAwMBgTMjAzODAxMDEwMDAwMDArMDAw
+MDAXMRUwEwYDVQQDEwxJbnRlcm1lZGlhdGUwggEiMA0GCSqGSIb3DQEBAQUAA4IB
+DwAwggEKAoIBAQDn+6V8izK8lJllQPNDBuTO9PjPeYVA2OZ9U8aL/huU/mFOU7zo
+4oNCd+ZscStB2UjZtp2w6tnqzQmi95gWlVhddHT0ro0BsRrz1DlexE+e+rYedx2h
+R+fxWGGP+xxwiRywPQYCOxCIKizgcHb5a6sGIF5kUr3VH1+olB36z7Yd/snAZxcz
+qcxrYJFAJYnQ03tquPVnnATk0uhQkBDEQibEz4sZWCLuHFh8RrLF8b5HNNiXe+Pw
+6JPZGS5FfjmEocXs50God07oMPMbRz90/MbZDCf6gfKWnBNZHui9PNfJ5RNRzySL
+mRaInWDsSBViCv6c8ippWvG7bGnRu+6/848JAgMBAAGjMjAwMA8GA1UdEwEB/wQF
+MAMBAf8wHQYDVR0eAQH/BBMwEaEPMA2CC2FuZHJvaWQuY29tMA0GCSqGSIb3DQEB
+CwUAA4IBAQCwOfXQc1OUafFRMzBPANMcgzor/Rve3TDNjw+mGTp6ajRNkDaY0aad
+fgy6NFDP7jKOFRfrcN0vWvGE5U+1BPfKv9D9pC1bu+2L0l2uaTUviGaZ4BNGTz8Q
+G1Slab6i/W7HSm4Reix26CNYVtVZemvAXt3j023PJEG5bcHofBQYFg2RPCWZX0jR
+zvPs5eKcIXS/9UOThsu+xvU1tkcCLCq1TbKT8YMV2t06XxDRBDieAwzV5oldh/wn
+n1Y2HTsIDhFSpPf4vDDRQznreJ4T7Dqk8FpgsWW8IxW1W7vUB0DTFPNnuiMwz1I4
+KhmThl2Zf5N8H6iT61k73aWTkXnmEME1
+-----END CERTIFICATE-----
diff --git a/tests/tests/security/res/raw/intermediate_test_root.pem b/tests/tests/security/res/raw/intermediate_test_root.pem
new file mode 100644
index 0000000..ed6021c
--- /dev/null
+++ b/tests/tests/security/res/raw/intermediate_test_root.pem
@@ -0,0 +1,17 @@
+-----BEGIN CERTIFICATE-----
+MIICwDCCAaigAwIBAgIDBbfsMA0GCSqGSIb3DQEBCwUAMBIxEDAOBgNVBAMTB1Jv
+b3QgQ0EwKhgTMjAxNTAxMDEwMDAwMDArMDAwMBgTMjAzODAxMDEwMDAwMDArMDAw
+MDASMRAwDgYDVQQDEwdSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
+CgKCAQEAs8fNuL8VRkecq/tadJSHi20VfAIfLghDkSDn0pixoIToRkvmWU7cPtHC
+P4xgMMrOxp8Z+JEN1bMPUHOT/KTUwa6bWider4E7VtB8E1h4LQHjpEwI/n0NmsfX
+FI7aTxy+z6Ty6hjX17HXmXUWOxEn4lha34iyNCaawCROmUQMEcrujIuQzKzzNZ9Z
+P7L4S8WY9Jkro+Ff8mNp2s4mRMercf1ZZLk9Nbw9T6rvRMaClC6p3ko2yE3qN7w3
+Q7Uny+5hiCGIlt+doXFaldK884QkzNV3yrWPdVKvMGL0V4X0vtSgfGdAY+2sEVlr
+XT5e2f96kU8oFqsiBG0i0FW/dIG0+QIDAQABoxMwETAPBgNVHRMBAf8EBTADAQH/
+MA0GCSqGSIb3DQEBCwUAA4IBAQB9KeDSwxo43+B8V9Gq81gI7hQ2ATZPUwdsChXG
+lyEkkEDBcqaKz72ECUpPMXp0vw6IV4Ty4xwsjDpPX2or/RgfE98e33yL8WpadT4u
+kG7HWALoz0Cy6VhnmGGtECOTCKYGH64lAHLNGA9CReRNED3tfJNMf4C3lVqgUWVU
+Doo3qWOdT6xlYFQxkEmh9FzYFPkdCCxEW9lDQqyZyg3n2+558SUjxvk569IrxzzY
+9ZfHK0M/jOWCvM6o4BrVLvjshJDCLAPWoaEd1Frsi6cmdjLov2etvcE/BBEixPpw
+05ve9VfFZ5Bt87paVc87qfwJ6tAAkfUqgZ3kLBQypoIDcsnQ
+-----END CERTIFICATE-----
diff --git a/tests/tests/security/res/raw/intermediate_test_valid.pem b/tests/tests/security/res/raw/intermediate_test_valid.pem
new file mode 100644
index 0000000..dfa004d
--- /dev/null
+++ b/tests/tests/security/res/raw/intermediate_test_valid.pem
@@ -0,0 +1,36 @@
+-----BEGIN CERTIFICATE-----
+MIIC5DCCAcygAwIBAgIDAcQxMA0GCSqGSIb3DQEBCwUAMBcxFTATBgNVBAMTDElu
+dGVybWVkaWF0ZTAqGBMyMDE1MDEwMTAwMDAwMCswMDAwGBMyMDM4MDEwMTAwMDAw
+MCswMDAwMBYxFDASBgNVBAMTC2V4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0BAQEF
+AAOCAQ8AMIIBCgKCAQEA122gZaYRUpfyvSN+YP9efhfaCoQ1aa5CBoZfR9R2t0Zc
+PamqG200n+19Hgl3DbMDb6ryPh8I9f+XE+Tm3VvBH9HX6MGrUBRToo1Mu7KhXGvv
+ZIUwE5NgZaefne9At5yo3ayi7AYI+VV2yY9JBl9SAxrzvIC7j+R4TMj/Kd6tu58H
+yEQ3HSVUHX+CxmUw2nuVuxvBk1eYjqJHLpCHU/B0sxr8L3Ohp8GlKM3AXPD3evqw
+IVFHuu5fXbAUfLnbzHs/klt8ye0ODr/aJKDGIrKSR4n5MIntfIWxMG6AUdN+U7XW
+N5G33Hio3nPtM8xXy3wcs3vOoTr+WtE/FpCOkj/51QIDAQABoy4wLDAPBgNVHRMB
+Af8EBTADAQH/MBkGA1UdEQEB/wQPMA2CC2V4YW1wbGUuY29tMA0GCSqGSIb3DQEB
+CwUAA4IBAQBl6sN9L3rCeiCcLSHfrRhIPTPooaXL1c6GL91hvlWUMqSOrcffSmVj
+hZ5f4a6N+SUnDd98M5JnxGFlzKdJsNs2CMQmnSTpeSv6w7v27Y0kf5MyJFViYYLK
+WovdW4/MFGzx/rlClmdZ1fkt11TNtjnwPpfdpma/OvIl8gPrFPfnJc0PxMl16K7L
+Vniw29I0fwjvKsZEu61uwAzM1PZAw/sRB2Qoj3+UknzDwLcZf1MjYlWQNLDXsv3f
+qgoQTgFX7jyta2HwS3+a0aojwOY6I+IJrThyxgRLtLe6BAwAzIWWkg0Zrd88Efcz
+3AxxITd5DJOJD+VpbYoZay4OjaeHAMYD
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIC5DCCAcygAwIBAgIDCY0fMA0GCSqGSIb3DQEBCwUAMBIxEDAOBgNVBAMTB1Jv
+b3QgQ0EwKhgTMjAxNTAxMDEwMDAwMDArMDAwMBgTMjAzODAxMDEwMDAwMDArMDAw
+MDAXMRUwEwYDVQQDEwxJbnRlcm1lZGlhdGUwggEiMA0GCSqGSIb3DQEBAQUAA4IB
+DwAwggEKAoIBAQDn+6V8izK8lJllQPNDBuTO9PjPeYVA2OZ9U8aL/huU/mFOU7zo
+4oNCd+ZscStB2UjZtp2w6tnqzQmi95gWlVhddHT0ro0BsRrz1DlexE+e+rYedx2h
+R+fxWGGP+xxwiRywPQYCOxCIKizgcHb5a6sGIF5kUr3VH1+olB36z7Yd/snAZxcz
+qcxrYJFAJYnQ03tquPVnnATk0uhQkBDEQibEz4sZWCLuHFh8RrLF8b5HNNiXe+Pw
+6JPZGS5FfjmEocXs50God07oMPMbRz90/MbZDCf6gfKWnBNZHui9PNfJ5RNRzySL
+mRaInWDsSBViCv6c8ippWvG7bGnRu+6/848JAgMBAAGjMjAwMA8GA1UdEwEB/wQF
+MAMBAf8wHQYDVR0eAQH/BBMwEaEPMA2CC2FuZHJvaWQuY29tMA0GCSqGSIb3DQEB
+CwUAA4IBAQCwOfXQc1OUafFRMzBPANMcgzor/Rve3TDNjw+mGTp6ajRNkDaY0aad
+fgy6NFDP7jKOFRfrcN0vWvGE5U+1BPfKv9D9pC1bu+2L0l2uaTUviGaZ4BNGTz8Q
+G1Slab6i/W7HSm4Reix26CNYVtVZemvAXt3j023PJEG5bcHofBQYFg2RPCWZX0jR
+zvPs5eKcIXS/9UOThsu+xvU1tkcCLCq1TbKT8YMV2t06XxDRBDieAwzV5oldh/wn
+n1Y2HTsIDhFSpPf4vDDRQznreJ4T7Dqk8FpgsWW8IxW1W7vUB0DTFPNnuiMwz1I4
+KhmThl2Zf5N8H6iT61k73aWTkXnmEME1
+-----END CERTIFICATE-----
diff --git a/tests/tests/security/src/android/security/cts/AslrTest.java b/tests/tests/security/src/android/security/cts/AslrTest.java
index 913b49b..774df87 100644
--- a/tests/tests/security/src/android/security/cts/AslrTest.java
+++ b/tests/tests/security/src/android/security/cts/AslrTest.java
@@ -16,20 +16,89 @@
 
 package android.security.cts;
 
+import android.test.InstrumentationTestCase;
 import junit.framework.TestCase;
 
+import android.os.ParcelFileDescriptor;
+import android.util.Log;
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.FileReader;
+import java.io.FileInputStream;
+import java.io.InputStreamReader;
 import java.io.IOException;
+import java.util.HashMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import android.cts.util.ReadElf;
 
 /**
  * Verify that ASLR is properly enabled on Android Compatible devices.
  */
-public class AslrTest extends TestCase {
+public class AslrTest extends InstrumentationTestCase {
+
+    private static final int aslrMinEntropyBits = 8;
+
+    private static final String TAG = "AslrTest";
+
+    private String readMappingAddress(String mappingName) throws Exception {
+        ParcelFileDescriptor pfd = getInstrumentation().getUiAutomation()
+                .executeShellCommand("/system/bin/cat /proc/self/maps");
+
+        BufferedReader reader = new BufferedReader(
+                new InputStreamReader(new FileInputStream(pfd.getFileDescriptor())));
+
+        Pattern p = Pattern.compile("^([a-f0-9]+)\\-.+\\[" + mappingName + "\\]$");
+        String line;
+
+        while ((line = reader.readLine()) != null) {
+            Matcher m = p.matcher(line);
+
+            if (m.matches()) {
+                return m.group(1);
+            }
+        }
+
+        return null;
+    }
+
+    private int calculateEntropyBits(String mappingName) throws Exception {
+        HashMap<String, Integer> addresses = new HashMap<String, Integer>();
+
+        // Sufficient number of iterations to ensure we should see at least
+        // aslrMinEntropyBits 
+        for (int i = 0; i < 2 * (1 << aslrMinEntropyBits); i++) {
+            addresses.put(readMappingAddress(mappingName), 1);
+        }
+
+        double entropy = Math.log(addresses.size()) / Math.log(2);
+
+        Log.i(TAG, String.format("%.1f", entropy) +
+            " bits of entropy for " + mappingName);
+
+        return (int) Math.round(entropy);
+    }
+
+    private void testMappingEntropy(String mappingName) throws Exception {
+        if (readMappingAddress(mappingName) == null) {
+            Log.i(TAG, mappingName + " does not exist");
+            return;
+        }
+
+        int entropy = calculateEntropyBits(mappingName);
+
+        assertTrue("Insufficient " + mappingName + " randomization (" +
+            entropy + " bits, >= " + aslrMinEntropyBits + " required)",
+            entropy >= aslrMinEntropyBits);
+    }
+
+    public void testRandomization() throws Exception {
+        testMappingEntropy("stack");
+        testMappingEntropy("heap");
+        testMappingEntropy("anon:libc_malloc");
+    }
 
     public void testOneExecutableIsPie() throws IOException {
         assertTrue(ReadElf.read(new File("/system/bin/cat")).isPIE());
@@ -51,5 +120,4 @@
             }
         }
     }
-
 }
diff --git a/tests/tests/security/src/android/security/cts/AudioEffectBinderTest.java b/tests/tests/security/src/android/security/cts/AudioEffectBinderTest.java
deleted file mode 100644
index 20d9615..0000000
--- a/tests/tests/security/src/android/security/cts/AudioEffectBinderTest.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.media.audiofx.AudioEffect;
-
-import java.util.UUID;
-
-import junit.framework.TestCase;
-
-public class AudioEffectBinderTest extends TestCase {
-
-    static {
-        System.loadLibrary("ctssecurity_jni");
-    }
-
-    /**
-     * Checks that IEffect::command() cannot leak data.
-     */
-    public void test_isCommandSecure() throws Exception {
-        if (isEffectTypeAvailable(AudioEffect.EFFECT_TYPE_EQUALIZER)) {
-            assertTrue(native_test_isCommandSecure());
-        }
-    }
-
-    /* see AudioEffect.isEffectTypeAvailable(), implements hidden function */
-    private static boolean isEffectTypeAvailable(UUID type) {
-        AudioEffect.Descriptor[] desc = AudioEffect.queryEffects();
-        if (desc == null) {
-            return false;
-        }
-
-        for (int i = 0; i < desc.length; i++) {
-            if (desc[i].type.equals(type)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private static native boolean native_test_isCommandSecure();
-}
diff --git a/tests/tests/security/src/android/security/cts/AudioFlingerBinderTest.java b/tests/tests/security/src/android/security/cts/AudioFlingerBinderTest.java
deleted file mode 100644
index 3cf4a2a..0000000
--- a/tests/tests/security/src/android/security/cts/AudioFlingerBinderTest.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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 junit.framework.TestCase;
-
-public class AudioFlingerBinderTest extends TestCase {
-
-    static {
-        System.loadLibrary("ctssecurity_jni");
-    }
-
-    /**
-     * Checks that AudioSystem::setMasterMute() does not crash mediaserver if a duplicated output
-     * is opened.
-     */
-    public void test_setMasterMute() throws Exception {
-        assertTrue(native_test_setMasterMute());
-    }
-
-    /**
-     * Checks that AudioSystem::setMasterVolume() does not crash mediaserver if a duplicated output
-     * is opened.
-     */
-    public void test_setMasterVolume() throws Exception {
-        assertTrue(native_test_setMasterVolume());
-    }
-
-    /**
-     * Checks that IAudioFlinger::listAudioPorts() does not cause a memory overflow when passed a
-     * large number of ports.
-     */
-    public void test_listAudioPorts() throws Exception {
-        assertTrue(native_test_listAudioPorts());
-    }
-
-    /**
-     * Checks that IAudioFlinger::createEffect() does not leak information on the server side.
-     */
-    public void test_createEffect() throws Exception {
-        assertTrue(native_test_createEffect());
-    }
-
-    private static native boolean native_test_setMasterMute();
-    private static native boolean native_test_setMasterVolume();
-    private static native boolean native_test_listAudioPorts();
-    private static native boolean native_test_createEffect();
-}
diff --git a/tests/tests/security/src/android/security/cts/AudioPolicyBinderTest.java b/tests/tests/security/src/android/security/cts/AudioPolicyBinderTest.java
deleted file mode 100644
index 82346a1..0000000
--- a/tests/tests/security/src/android/security/cts/AudioPolicyBinderTest.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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 junit.framework.TestCase;
-
-public class AudioPolicyBinderTest extends TestCase {
-
-    static {
-        System.loadLibrary("ctssecurity_jni");
-    }
-
-    /**
-     * Checks that IAudioPolicyService::startOutput() cannot be called with an
-     * invalid stream type.
-     */
-    public void test_startOutput() throws Exception {
-        assertTrue(native_test_startOutput());
-    }
-
-    /**
-     * Checks that IAudioPolicyService::stopOutput() cannot be called with an
-     * invalid stream type.
-     */
-    public void test_stopOutput() throws Exception {
-        assertTrue(native_test_stopOutput());
-    }
-
-    /**
-     * Checks that IAudioPolicyService::isStreamActive() cannot be called with an
-     * invalid stream type.
-     */
-    public void test_isStreamActive() throws Exception {
-        assertTrue(native_test_isStreamActive());
-    }
-
-    /**
-     * Checks that IAudioPolicyService::isStreamActiveRemotely() cannot be called with an
-     * invalid stream type.
-     */
-    public void test_isStreamActiveRemotely() throws Exception {
-        assertTrue(native_test_isStreamActiveRemotely());
-    }
-
-    /**
-     * Checks that IAudioPolicyService::getStreamVolumeIndex() does not leak information
-     * when called with an invalid stream/device type.
-     */
-    public void test_getStreamVolumeLeak() throws Exception {
-        int volume = native_test_getStreamVolumeLeak();
-        assertTrue(String.format("Leaked volume 0x%08X", volume), volume == 0);
-    }
-
-    /**
-     * Checks that IAudioPolicyService::startAudioSource() cannot leak information from
-     * server side.
-     */
-    public void test_startAudioSource() throws Exception {
-        assertTrue(native_test_startAudioSource());
-    }
-
-    private static native boolean native_test_startOutput();
-    private static native boolean native_test_stopOutput();
-    private static native boolean native_test_isStreamActive();
-    private static native boolean native_test_isStreamActiveRemotely();
-    private static native int native_test_getStreamVolumeLeak();
-    private static native boolean native_test_startAudioSource();
-}
diff --git a/tests/tests/security/src/android/security/cts/BannedFilesTest.java b/tests/tests/security/src/android/security/cts/BannedFilesTest.java
index 00c4631..54709b4 100644
--- a/tests/tests/security/src/android/security/cts/BannedFilesTest.java
+++ b/tests/tests/security/src/android/security/cts/BannedFilesTest.java
@@ -58,6 +58,17 @@
         assertFalse("/dev/socket/fotabinder", new File("/dev/socket/fotabinder").exists());
     }
 
+    /**
+     * Detect devices allowing shell commands to be executed as system
+     * through sockets.
+     *
+     * ANDROID-19679287
+     * CVE-2015-2231
+     */
+    public void testNoSystemCmdSocket() {
+        assertFalse("/dev/socket/fota", new File("/dev/socket/fota").exists());
+    }
+
     public void testNoSu() {
         assertFalse("/sbin/su",        new File("/sbin/su").exists());
         assertFalse("/system/bin/su",  new File("/system/bin/su").exists());
diff --git a/tests/tests/security/src/android/security/cts/BrowserTest.java b/tests/tests/security/src/android/security/cts/BrowserTest.java
index 223f83f..0948713 100644
--- a/tests/tests/security/src/android/security/cts/BrowserTest.java
+++ b/tests/tests/security/src/android/security/cts/BrowserTest.java
@@ -16,23 +16,22 @@
 
 package android.security.cts;
 
-import android.content.ComponentName;
-import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.net.Uri;
+import android.os.StrictMode;
 import android.test.AndroidTestCase;
 import android.webkit.cts.CtsTestServer;
 
+import org.apache.http.HttpEntity;
+
+import java.io.File;
 import java.io.FileOutputStream;
-import java.io.OutputStreamWriter;
-import java.io.Writer;
+import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.concurrent.atomic.AtomicInteger;
 
-import org.apache.http.HttpEntity;
 /**
  * Test file for browser security issues.
  */
@@ -138,6 +137,8 @@
      * See Bug 6212665 for detailed information about this issue.
      */
     public void testBrowserPrivateDataAccess() throws Throwable {
+        // Yucky workaround to let us launch file:// Uris
+        StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().build());
 
         // Create a list of all intents for http display. This includes all browsers.
         List<Intent> intents = createAllIntents(Uri.parse("http://www.google.com"));
@@ -146,8 +147,10 @@
         for (Intent intent : intents) {
             // reset state
             mWebServer.resetRequestState();
+
             // define target file, which is supposedly protected from this app
-            String targetFile = "file://" + getTargetFilePath();
+            final File secretFile = exposeFile(stageFile("target.txt", "SECRETS!"));
+
             String html =
                 "<html><body>\n" +
                 "  <form name=\"myform\" action=" + action + " method=\"post\">\n" +
@@ -155,7 +158,7 @@
                 "  <a href=\"javascript :submitform()\">Search</a></form>\n" +
                 "<script>\n" +
                 "  var client = new XMLHttpRequest();\n" +
-                "  client.open('GET', '" + targetFile + "');\n" +
+                "  client.open('GET', '" + Uri.fromFile(secretFile) + "');\n" +
                 "  client.onreadystatechange = function() {\n" +
                 "  if(client.readyState == 4) {\n" +
                 "    myform.val.value = client.responseText;\n" +
@@ -163,20 +166,14 @@
                 "  }}\n" +
                 "  client.send();\n" +
                 "</script></body></html>\n";
-            String filename = "jsfileaccess.html";
-            // create a local HTML to access protected file
-            FileOutputStream out = mContext.openFileOutput(filename,
-                                                           mContext.MODE_WORLD_READABLE);
-            Writer writer = new OutputStreamWriter(out, "UTF-8");
-            writer.write(html);
-            writer.flush();
-            writer.close();
 
-            String filepath = mContext.getFileStreamPath(filename).getAbsolutePath();
-            Uri uri = Uri.parse("file://" + filepath);
+            // create a local HTML to access protected file
+            final File htmlFile = exposeFile(stageFile("jsfileaccess.html", html));
+
             // do a file request
-            intent.setData(uri);
+            intent.setData(Uri.fromFile(htmlFile));
             mContext.startActivity(intent);
+
             /*
              * Wait 5 seconds for the browser to contact the server, but
              * fail fast if we detect the bug
@@ -199,14 +196,26 @@
         }
     }
 
-    private String getTargetFilePath() throws Exception {
-        FileOutputStream out = mContext.openFileOutput("target.txt",
-                                                       mContext.MODE_WORLD_READABLE);
-        Writer writer = new OutputStreamWriter(out, "UTF-8");
-        writer.write("testing");
-        writer.flush();
-        writer.close();
-        return mContext.getFileStreamPath("target.txt").getAbsolutePath();
+    private File stageFile(String name, String contents) throws Exception {
+        final File file = mContext.getFileStreamPath(name);
+        try (FileOutputStream out = new FileOutputStream(file)) {
+            out.write(contents.getBytes(StandardCharsets.UTF_8));
+        }
+        return file;
+    }
+
+    private File exposeFile(File file) throws Exception {
+        file.setReadable(true, false);
+        file.setReadable(true, true);
+
+        File dir = file.getParentFile();
+        do {
+            dir.setExecutable(true, false);
+            dir.setExecutable(true, true);
+            dir = dir.getParentFile();
+        } while (dir != null);
+
+        return file;
     }
 
     /**
diff --git a/tests/tests/security/src/android/security/cts/CertificateData.java b/tests/tests/security/src/android/security/cts/CertificateData.java
index 0c311e0..f1116e7 100644
--- a/tests/tests/security/src/android/security/cts/CertificateData.java
+++ b/tests/tests/security/src/android/security/cts/CertificateData.java
@@ -50,6 +50,7 @@
       "8E:1C:74:F8:A6:20:B9:E5:8A:F4:61:FA:EC:2B:47:56:51:1A:52:C6",
       "27:96:BA:E6:3F:18:01:E2:77:26:1B:A0:D7:77:70:02:8F:20:EE:E4",
       "AD:7E:1C:28:B0:64:EF:8F:60:03:40:20:14:C3:D0:E3:37:0E:B5:8A",
+      "FB:ED:DC:90:65:B7:27:20:37:BC:55:0C:9C:56:DE:BB:F2:78:94:E1",
       "8D:17:84:D5:37:F3:03:7D:EC:70:FE:57:8B:51:9A:99:E6:10:D7:B0",
       "1F:24:C6:30:CD:A4:18:EF:20:69:FF:AD:4F:DD:5F:46:3A:1B:69:AA",
       "DA:FA:F7:FA:66:84:EC:06:8F:14:50:BD:C7:C2:81:A5:BC:A9:64:57",
@@ -73,16 +74,12 @@
       "8C:F4:27:FD:79:0C:3A:D1:66:06:8D:E8:1E:57:EF:BB:93:22:72:D4",
       "2F:78:3D:25:52:18:A7:4A:65:39:71:B5:2C:A2:9C:45:15:6F:E9:19",
       "BA:29:41:60:77:98:3F:F4:F3:EF:F2:31:05:3B:2E:EA:6D:4D:45:FD",
-      "97:81:79:50:D8:1C:96:70:CC:34:D8:09:CF:79:44:31:36:7E:F4:74",
       "85:A4:08:C0:9C:19:3E:5D:51:58:7D:CD:D6:13:30:FD:8C:DE:37:BF",
-      "58:11:9F:0E:12:82:87:EA:50:FD:D9:87:45:6F:4F:78:DC:FA:D6:D4",
       "9B:AA:E5:9F:56:EE:21:CB:43:5A:BE:25:93:DF:A7:F0:40:D1:1D:CB",
       "36:79:CA:35:66:87:72:30:4D:30:A5:FB:87:3B:0F:A7:7B:B7:0D:54",
       "1B:8E:EA:57:96:29:1A:C9:39:EA:B8:0A:81:1A:73:73:C0:93:79:67",
-      "B4:35:D4:E1:11:9D:1C:66:90:A7:49:EB:B3:94:BD:63:7B:A7:82:B7",
       "A9:E9:78:08:14:37:58:88:F2:05:19:B0:6D:2B:0D:2B:60:16:90:7D",
       "60:D6:89:74:B5:C2:65:9E:8A:0F:C1:88:7C:88:D2:46:69:1B:18:2C",
-      "D2:32:09:AD:23:D3:14:23:21:74:E4:0D:7F:9D:62:13:97:86:63:3A",
       "D8:EB:6B:41:51:92:59:E0:F3:E7:85:00:C0:3D:B6:88:97:C9:EE:FC",
       "66:31:BF:9E:F7:4F:9E:B6:C9:D5:A6:0C:BA:6A:BE:D1:F7:BD:EF:7B",
       "DE:3F:40:BD:50:93:D3:9B:6C:60:F6:DA:BC:07:62:01:00:89:76:C9",
@@ -97,22 +94,18 @@
       "70:17:9B:86:8C:00:A4:FA:60:91:52:22:3F:9F:3E:32:BD:E0:05:62",
       "A0:A1:AB:90:C9:FC:84:7B:3B:12:61:E8:97:7D:5F:D3:22:61:D3:CC",
       "D1:EB:23:A4:6D:17:D6:8F:D9:25:64:C2:F1:F1:60:17:64:D8:E3:49",
-      "A1:DB:63:93:91:6F:17:E4:18:55:09:40:04:15:C7:02:40:B0:AE:6B",
       "B8:01:86:D1:EB:9C:86:A5:41:04:CF:30:54:F3:4C:52:B7:E5:58:C6",
       "2E:14:DA:EC:28:F0:FA:1E:8E:38:9A:4E:AB:EB:26:C0:0A:D3:83:C3",
       "DE:28:F4:A4:FF:E5:B9:2F:A3:C5:03:D1:A3:49:A7:F9:96:2A:82:12",
       "CA:3A:FB:CF:12:40:36:4B:44:B2:16:20:88:80:48:39:19:93:7C:F7",
-      "69:BD:8C:F4:9C:D3:00:FB:59:2E:17:93:CA:55:6A:F3:EC:AA:35:FB",
       "13:2D:0D:45:53:4B:69:97:CD:B2:D5:C3:39:E2:55:76:60:9B:5C:C6",
       "5F:B7:EE:06:33:E2:59:DB:AD:0C:4C:9A:E6:D3:8F:1A:61:C7:DC:25",
       "49:0A:75:74:DE:87:0A:47:FE:58:EE:F6:C7:6B:EB:C6:0B:12:40:99",
       "25:01:90:19:CF:FB:D9:99:1C:B7:68:25:74:8D:94:5F:30:93:95:42",
-      "79:98:A3:08:E1:4D:65:85:E6:C2:1E:15:3A:71:9F:BA:5A:D3:4A:D9",
       "B5:1C:06:7C:EE:2B:0C:3D:F8:55:AB:2D:92:F4:FE:39:D4:E7:0F:0E",
       "29:36:21:02:8B:20:ED:02:F5:66:C5:32:D1:D6:ED:90:9F:45:00:2F",
       "37:9A:19:7B:41:85:45:35:0C:A6:03:69:F3:3C:2E:AF:47:4F:20:79",
       "FA:B7:EE:36:97:26:62:FB:2D:B0:2A:F6:BF:03:FD:E8:7C:4B:2F:9B",
-      "8B:AF:4C:9B:1D:F0:2A:92:F7:DA:12:8E:B9:1B:AC:F4:98:60:4B:6F",
       "9F:74:4E:9F:2B:4D:BA:EC:0F:31:2C:50:B6:56:3B:8E:2D:93:C3:11",
       "A1:4B:48:D9:43:EE:0A:0E:40:90:4F:3C:E0:A4:C0:91:93:51:5D:3F",
       "C9:A8:B9:E7:55:80:5E:58:E3:53:77:A7:25:EB:AF:C3:7B:27:CC:D7",
@@ -133,8 +126,8 @@
       "36:B1:2B:49:F9:81:9E:D7:4C:9E:BC:38:0F:C6:56:8F:5D:AC:B2:F7",
       "37:F7:6D:E6:07:7C:90:C5:B1:3E:93:1A:B7:41:10:B4:F2:E4:9A:27",
       "AA:DB:BC:22:23:8F:C4:01:A1:27:BB:38:DD:F4:1D:DB:08:9E:F0:12",
+      "E2:52:FA:95:3F:ED:DB:24:60:BD:6E:28:F3:9C:CC:CF:5E:B3:3F:DE",
       "3B:C4:9F:48:F8:F3:73:A0:9C:1E:BD:F8:5B:B1:C3:65:C7:D8:11:B3",
-      "AC:ED:5F:65:53:FD:25:CE:01:5F:1F:7A:48:3B:6A:74:9F:61:78:C6",
       "28:90:3A:63:5B:52:80:FA:E6:77:4C:0B:6D:A7:D6:BA:A6:4A:F2:E8",
       "9C:BB:48:53:F6:A4:F6:D3:52:A4:E8:32:52:55:60:13:F5:AD:AF:65",
       "B1:BC:96:8B:D4:F4:9D:62:2A:A8:9A:81:F2:15:01:52:A4:1D:82:9C",
@@ -144,26 +137,25 @@
       "47:BE:AB:C9:22:EA:E8:0E:78:78:34:62:A7:9F:45:C2:54:FD:E6:8B",
       "3A:44:73:5A:E5:81:90:1F:24:86:61:46:1E:3B:9C:C4:5F:F5:3A:1B",
       "B3:1E:B1:B7:40:E3:6C:84:02:DA:DC:37:D4:4D:F5:D4:67:49:52:F9",
-      "D3:C0:63:F2:19:ED:07:3E:34:AD:5D:75:0B:32:76:29:FF:D5:9A:F2",
       "F5:17:A2:4F:9A:48:C6:C9:F8:A2:00:26:9F:DC:0F:48:2C:AB:30:89",
       "3B:C0:38:0B:33:C3:F6:A6:0C:86:15:22:93:D9:DF:F5:4B:81:C0:04",
-      "C8:EC:8C:87:92:69:CB:4B:AB:39:E9:8D:7E:57:67:F3:14:95:73:9D",
       "03:9E:ED:B8:0B:E7:A0:3C:69:53:89:3B:20:D2:D9:32:3A:4C:2A:FD",
       "DF:3C:24:F9:BF:D6:66:76:1B:26:80:73:FE:06:D1:CC:8D:4F:82:A4",
       "51:C6:E7:08:49:06:6E:F3:92:D4:5C:A0:0D:6D:A3:62:8F:C3:52:39",
+      "D3:DD:48:3E:2B:BF:4C:05:E8:AF:10:F5:FA:76:26:CF:D3:DC:30:92",
       "B8:23:6B:00:2F:1D:16:86:53:01:55:6C:11:A4:37:CA:EB:FF:C3:BB",
-      "10:1D:FA:3F:D5:0B:CB:BB:9B:B5:60:0C:19:55:A4:1A:F4:73:3A:04",
       "87:82:C6:C3:04:35:3B:CF:D2:96:92:D2:59:3E:7D:44:D9:34:FF:11",
       "59:0D:2D:7D:88:4F:40:2E:61:7E:A5:62:32:17:65:CF:17:D8:94:E9",
       "AE:C5:FB:3F:C8:E1:BF:C4:E5:4F:03:07:5A:9A:E8:00:B7:F7:B6:FA",
       "DF:71:7E:AA:4A:D9:4E:C9:55:84:99:60:2D:48:DE:5F:BC:F0:3A:25",
       "AF:E5:D2:44:A8:D1:19:42:30:FF:47:9F:E2:F8:97:BB:CD:7A:8C:B4",
+      "D2:7A:D2:BE:ED:94:C0:A1:3C:C7:25:21:EA:5D:71:BE:81:19:F3:2B",
       "5F:3B:8C:F2:F8:10:B3:7D:78:B4:CE:EC:19:19:C3:73:34:B9:C7:74",
-      "2A:C8:D5:8B:57:CE:BF:2F:49:AF:F2:FC:76:8F:51:14:62:90:7A:41",
       "F1:7F:6F:B6:31:DC:99:E3:A3:C8:7F:FE:1C:F1:81:10:88:D9:60:33",
       "9D:70:BB:01:A5:A4:A0:18:11:2E:F7:1C:01:B9:32:C5:34:E7:88:A8",
       "96:C9:1B:0B:95:B4:10:98:42:FA:D0:D8:22:79:FE:60:FA:B9:16:83",
       "D8:A6:33:2C:E0:03:6F:B1:85:F6:63:4F:7D:6A:06:65:26:32:28:27",
+      "0F:F9:40:76:18:D3:D7:6A:4B:98:F0:A8:35:9E:0C:FD:27:AC:CC:ED",
       "CC:AB:0E:A0:4C:23:01:D6:69:7B:DD:37:9F:CD:12:EB:24:E3:94:9D",
       "48:12:BD:92:3C:A8:C4:39:06:E7:30:6D:27:96:E6:A4:CF:22:2E:7D",
       "F9:B5:B6:32:45:5F:9C:BE:EC:57:5F:80:DC:E9:6E:2C:C7:B2:78:B7",
@@ -172,10 +164,8 @@
       "89:DF:74:FE:5C:F4:0F:4A:80:F9:E3:37:7D:54:DA:91:E1:01:31:8E",
       "E0:B4:32:2E:B2:F6:A5:68:B6:54:53:84:48:18:4A:50:36:87:43:84",
       "7E:04:DE:89:6A:3E:66:6D:00:E6:87:D3:3F:FA:D9:3B:E8:3D:34:9E",
-      "99:A6:9B:E6:1A:FE:88:6B:4D:2B:82:00:7C:B8:54:FC:31:7E:15:39",
       "6E:3A:55:A4:19:0C:19:5C:93:84:3C:C0:DB:72:2E:31:30:61:F0:B1",
       "31:F1:FD:68:22:63:20:EE:C6:3B:3F:9D:EA:4A:3E:53:7C:7C:39:17",
-      "F9:CD:0E:2C:DA:76:24:C1:8F:BD:F0:F0:AB:B6:45:B8:F7:FE:D5:7A",
       "23:88:C9:D3:71:CC:9E:96:3D:FF:7D:3C:A7:CE:FC:D6:25:EC:19:0D",
       "8C:96:BA:EB:DD:2B:07:07:48:EE:30:32:66:A0:F3:98:6E:7C:AE:58",
       "7F:8A:B0:CF:D0:51:87:6A:66:F3:36:0F:47:C8:8D:8C:D3:35:FC:74",
diff --git a/tests/tests/security/src/android/security/cts/CertificateTest.java b/tests/tests/security/src/android/security/cts/CertificateTest.java
index 3db7aca..5d2a04f 100644
--- a/tests/tests/security/src/android/security/cts/CertificateTest.java
+++ b/tests/tests/security/src/android/security/cts/CertificateTest.java
@@ -16,19 +16,13 @@
 
 package android.security.cts;
 
-import android.content.res.AssetManager;
-import android.test.InstrumentationTestCase;
-
-import java.io.File;
 import java.io.IOException;
-import java.io.InputStream;
 import java.security.KeyStore;
 import java.security.KeyStoreException;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.security.cert.CertificateEncodingException;
 import java.security.cert.CertificateException;
-import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
 import java.util.Arrays;
 import java.util.Collections;
@@ -36,7 +30,9 @@
 import java.util.List;
 import java.util.Set;
 
-public class CertificateTest extends InstrumentationTestCase {
+import junit.framework.TestCase;
+
+public class CertificateTest extends TestCase {
 
     public void testNoRemovedCertificates() throws Exception {
         Set<String> expectedCertificates = new HashSet<String>(
@@ -50,55 +46,25 @@
      * If you fail CTS as a result of adding a root CA that is not part of the Android root CA
      * store, please see the following.
      *
-     * First, this test exists because adding untrustworthy root CAs to a device has a very
-     * significant security impact. In the worst case, adding a rogue CA can permanently compromise
-     * the confidentiality and integrity of your users' network traffic. Because of this risk,
-     * adding new certificates should be done sparingly and as a last resort -- never as a first
-     * response or short term fix. Before attempting to modify this test, please consider whether
-     * adding a new certificate authority is in your users' best interests.
+     * <p>This test exists because adding root CAs to a device has a very significant security
+     * impact. Whoever has access to the signing keys of that CA can compromise secure network
+     * traffic from affected Android devices, putting users at risk.
      *
-     * Second, because the addition of a new root CA by an OEM can have such dire consequences for
-     * so many people it is imperative that it be done transparently and in the open. Any request to
-     * modify the certificate list used by this test must have a corresponding change in AOSP
-     * (one certificate per change) authored by the OEM in question and including:
+     * <p>If you have a CA certificate which needs to be trusted by a particular app/service,
+     * ask the developer of the app/service to modify it to trust this CA (e.g., using Network
+     * Security Config feature). This avoids compromising the security of network traffic of other
+     * apps on the device.
      *
-     *     - the certificate in question:
-     *       - The certificate must be in a file under
-     *         cts/tests/tests/security/assets/oem_cacerts, in PEM (Privacy-enhanced Electronic
-     *         Mail) format, with the textual representation of the certificate following the PEM
-     *         section.
-     *       - The file name must be in the format of <hash>.<n> where "hash" is the subject hash
-     *         produced by:
-     *           openssl x509 -in cert_file -subject_hash -noout
-     *         and the "n" is a unique integer identifier starting at 0 to deal with collisions.
-     *         See OpenSSL's c_rehash manpage for details.
-     *       - cts/tests/tests/security/tools/format_cert.sh helps meet the above requirements.
+     * <p>If you have a CA certificate that you believe should be present on all Android devices,
+     * please file a public bug at https://code.google.com/p/android/issues/entry.
      *
-     *     - information about who created and maintains both the certificate and the corresponding
-     *       keypair.
-     *
-     *     - information about what the certificate is to be used for and why the certificate is
-     *       appropriate for inclusion.
-     *
-     *     - a statement from the OEM indicating that they have sufficient confidence in the
-     *       security of the key, the security practices of the issuer, and the validity of the
-     *       intended use that they believe adding the certificate is not detrimental to the
-     *       security of the user.
-     *
-     * Finally, please note that this is not the usual process for adding root CAs to Android. If
-     * you have a certificate that you believe should be present on all Android devices, please file
-     * a public bug at https://code.google.com/p/android/issues/entry or http://b.android.com to
-     * seek resolution.
-     *
-     * For questions, comments, and code reviews please contact security@android.com.
+     * <p>For questions, comments, and code reviews please contact security@android.com.
      */
     public void testNoAddedCertificates() throws Exception {
-        Set<String> oemWhitelistedCertificates = getOemWhitelistedCertificates();
         Set<String> expectedCertificates = new HashSet<String>(
                 Arrays.asList(CertificateData.CERTIFICATE_DATA));
         Set<String> deviceCertificates = getDeviceCertificates();
         deviceCertificates.removeAll(expectedCertificates);
-        deviceCertificates.removeAll(oemWhitelistedCertificates);
         assertEquals("Unknown CA certificates", Collections.EMPTY_SET, deviceCertificates);
     }
 
@@ -132,30 +98,6 @@
         return certificates;
     }
 
-    private static final String ASSETS_DIR_OEM_CERTS = "oem_cacerts";
-
-    private Set<String> getOemWhitelistedCertificates() throws Exception {
-        Set<String> certificates = new HashSet<String>();
-        CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
-        AssetManager assetManager = getInstrumentation().getContext().getAssets();
-        for (String path : assetManager.list(ASSETS_DIR_OEM_CERTS)) {
-            File certAssetFile = new File(ASSETS_DIR_OEM_CERTS, path);
-            InputStream in = null;
-            try {
-                in = assetManager.open(certAssetFile.toString());
-                X509Certificate certificate = (X509Certificate) certFactory.generateCertificate(in);
-                certificates.add(getFingerprint(certificate));
-            } catch (Exception e) {
-                throw new Exception("Failed to load certificate from asset: " + certAssetFile, e);
-            } finally {
-                if (in != null) {
-                    in.close();
-                }
-            }
-        }
-        return certificates;
-    }
-
     private String getFingerprint(X509Certificate certificate) throws CertificateEncodingException,
             NoSuchAlgorithmException {
         MessageDigest messageDigest = MessageDigest.getInstance("SHA1");
diff --git a/tests/tests/security/src/android/security/cts/ConscryptIntermediateVerificationTest.java b/tests/tests/security/src/android/security/cts/ConscryptIntermediateVerificationTest.java
new file mode 100644
index 0000000..6e64120
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/ConscryptIntermediateVerificationTest.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.content.Context;
+import android.test.AndroidTestCase;
+import java.io.InputStream;
+import java.security.KeyStore;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.security.cert.CertificateFactory;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.X509TrustManager;
+
+public class ConscryptIntermediateVerificationTest extends AndroidTestCase {
+
+    private X509Certificate[] loadCertificates(int resource) throws Exception {
+        CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
+        List<X509Certificate> result = new ArrayList<X509Certificate>();
+        InputStream is = null;
+        Collection<? extends Certificate> certs;
+        try {
+            is = getContext().getResources().openRawResource(resource);
+            certs = certFactory.generateCertificates(is);
+        } finally {
+            try {
+                if (is != null) {
+                    is.close();
+                }
+            } catch (Exception ignored) {
+            }
+        }
+        for (Certificate cert : certs) {
+            result.add((X509Certificate) cert);
+        }
+        return result.toArray(new X509Certificate[result.size()]);
+    }
+
+    private X509TrustManager getTrustManager() throws Exception {
+
+        KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
+        keystore.load(null);
+        CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
+        X509Certificate root = loadCertificates(R.raw.intermediate_test_root)[0];
+        keystore.setEntry("root", new KeyStore.TrustedCertificateEntry(root), null);
+        TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX");
+        tmf.init(keystore);
+        X509TrustManager trustManager = null;
+        for (TrustManager tm : tmf.getTrustManagers()) {
+            if (tm instanceof X509TrustManager) {
+                return (X509TrustManager) tm;
+            }
+        }
+        fail("Unable to find X509TrustManager");
+        return null;
+    }
+
+    public void testIntermediateVerification() throws Exception {
+        X509TrustManager tm = getTrustManager();
+        X509Certificate[] validChain = loadCertificates(R.raw.intermediate_test_valid);
+        X509Certificate[] invalidChain = loadCertificates(R.raw.intermediate_test_invalid);
+
+        // This test consists of two chains:
+        // valid: L -> I -> R
+        // invalid L' -> I -> R
+        // Where R is the trusted root CA
+        // I is an intermediate CA with name constraints disallowing android.com
+        // L is a certificate issued by I for example.com
+        // L' is a certificate issued by I for android.com
+        // valid is a valid chain and should verify correctly
+        // invalid should fail due to the violation of I's name constraints
+
+        try {
+            tm.checkServerTrusted(invalidChain, "RSA");
+            fail("invalidChain incorrectly valid");
+        } catch (CertificateException expected) {
+        }
+        tm.checkServerTrusted(validChain, "RSA");
+        // Implementation note: conscrypt's TrustManagerImpl caches intermediates after successful
+        // verifications, those cached intermediates should still be considered untrusted when used
+        // again in a subsequent connection.
+        try {
+            tm.checkServerTrusted(invalidChain, "RSA");
+            fail("invalidChain incorrectly valid after trusting validChain");
+        } catch (CertificateException expected) {
+        }
+    }
+}
diff --git a/tests/tests/security/src/android/security/cts/GraphicBufferInfoLeakTest.java b/tests/tests/security/src/android/security/cts/GraphicBufferInfoLeakTest.java
deleted file mode 100644
index 6005e37..0000000
--- a/tests/tests/security/src/android/security/cts/GraphicBufferInfoLeakTest.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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 junit.framework.TestCase;
-
-public class GraphicBufferInfoLeakTest extends TestCase {
-
-    static {
-        System.loadLibrary("ctssecurity_jni");
-    }
-
-    /**
-     * Check that IGraphicBufferConsumer::attachBuffer does not leak info in error case
-     */
-    public void test_attachBufferInfoLeak() throws Exception {
-        int slot = native_test_attachBufferInfoLeak();
-        assertTrue(String.format("Leaked slot 0x%08X", slot), slot == -1);
-    }
-
-    /**
-     * Check that IGraphicBufferProducer::queueBuffer does not leak info in error case
-     */
-    public void test_queueBufferInfoLeak() throws Exception {
-        int data = native_test_queueBufferInfoLeak();
-        assertTrue(String.format("Leaked buffer data 0x%08X", data), data == 0);
-    }
-
-    private static native int native_test_attachBufferInfoLeak();
-    private static native int native_test_queueBufferInfoLeak();
-}
diff --git a/tests/tests/security/src/android/security/cts/HttpPost.java b/tests/tests/security/src/android/security/cts/HttpPost.java
deleted file mode 100644
index 7f855d9..0000000
--- a/tests/tests/security/src/android/security/cts/HttpPost.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.annotation.SuppressLint;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.os.Build;
-import android.util.Log;
-import android.util.Pair;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.util.Locale;
-import java.util.Map;
-
-/**
- * HttpPost utility functions.
- */
-public final class HttpPost {
-    private static final String TAG = "HttpPost";
-
-    private HttpPost() {}
-
-    /**
-     * Executes a post request using {@link HttpURLConnection}.
-     *
-     * @param url The request URL.
-     * @param data The request body, or null.
-     * @param requestProperties Request properties, or null.
-     * @return The response code and body.
-     * @throws IOException If an error occurred making the request.
-     */
-    public static Pair<Integer, byte[]> execute(String url, byte[] data,
-            Map<String, String> requestProperties) throws IOException {
-        HttpURLConnection urlConnection = null;
-        try {
-            urlConnection = (HttpURLConnection) new URL(url).openConnection();
-            urlConnection.setRequestMethod("POST");
-            urlConnection.setDoOutput(data != null);
-            urlConnection.setDoInput(true);
-            urlConnection.setConnectTimeout(5000);
-            urlConnection.setReadTimeout(5000);
-            if (requestProperties != null) {
-                for (Map.Entry<String, String> requestProperty : requestProperties.entrySet()) {
-                    urlConnection.setRequestProperty(requestProperty.getKey(),
-                            requestProperty.getValue());
-                }
-            }
-            // Write the request body, if there is one.
-            if (data != null) {
-                OutputStream out = urlConnection.getOutputStream();
-                try {
-                    out.write(data);
-                } finally {
-                    out.close();
-                }
-            }
-            // Read the response code.
-            int responseCode = urlConnection.getResponseCode();
-            // Read the response body.
-            InputStream inputStream = urlConnection.getInputStream();
-            try {
-                ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
-                byte scratch[] = new byte[1024];
-                int bytesRead;
-                while ((bytesRead = inputStream.read(scratch)) != -1) {
-                    byteArrayOutputStream.write(scratch, 0, bytesRead);
-                }
-                byte[] responseBody = byteArrayOutputStream.toByteArray();
-                Log.d(TAG, "responseCode=" + responseCode + ", length=" + responseBody.length);
-                return Pair.create(responseCode, responseBody);
-            } finally {
-                inputStream.close();
-            }
-        } finally {
-            if (urlConnection != null) {
-                urlConnection.disconnect();
-            }
-        }
-    }
-
-}
diff --git a/tests/tests/security/src/android/security/cts/HwRngTest.java b/tests/tests/security/src/android/security/cts/HwRngTest.java
index f9ce6be..7654b6f 100644
--- a/tests/tests/security/src/android/security/cts/HwRngTest.java
+++ b/tests/tests/security/src/android/security/cts/HwRngTest.java
@@ -17,11 +17,10 @@
 package android.security.cts;
 
 import android.cts.util.CtsAndroidTestCase;
-import com.android.cts.util.ReportLog;
-import com.android.cts.util.ResultType;
-import com.android.cts.util.ResultUnit;
 
-import junit.framework.TestCase;
+import com.android.compatibility.common.util.DeviceReportLog;
+import com.android.compatibility.common.util.ResultType;
+import com.android.compatibility.common.util.ResultUnit;
 
 import java.io.BufferedReader;
 import java.io.ByteArrayOutputStream;
@@ -51,18 +50,19 @@
      * Reports whether the {@code /dev/hw_random} device is found. This test always passes.
      */
     public void testDeviceFilePresent() {
-        ReportLog report = getReportLog();
+        DeviceReportLog report = new DeviceReportLog();
         // Need to report at least one value, otherwise summary won't be logged.
-        report.printValue(
+        report.addValue(
                 DEV_HW_RANDOM + " found",
                 DEV_HW_RANDOM.exists() ? 1 : 0,
                 ResultType.WARNING,
                 ResultUnit.NONE);
-        report.printSummary(
+        report.setSummary(
                 "Hardware RNG exposed",
                 DEV_HW_RANDOM.exists() ? 1 : 0,
                 ResultType.WARNING,
                 ResultUnit.NONE);
+        report.submit(getInstrumentation());
     }
 
     /**
diff --git a/tests/tests/security/src/android/security/cts/KeyRequester.java b/tests/tests/security/src/android/security/cts/KeyRequester.java
deleted file mode 100644
index 26a3337..0000000
--- a/tests/tests/security/src/android/security/cts/KeyRequester.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.media.DeniedByServerException;
-import android.media.MediaDrm;
-import android.media.NotProvisionedException;
-import android.util.Log;
-import android.util.Pair;
-
-import java.io.UnsupportedEncodingException;
-import java.util.Arrays;
-import java.util.concurrent.CancellationException;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.concurrent.RejectedExecutionException;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-
-public class KeyRequester {
-    private final String TAG = "KeyRequester";
-    private final int MAX_RETRY_COUNT = 3;
-    private final int POOL_SIZE = 1;
-    private final int POOL_TERMINATION_MS_TIMEOUT = 3000;  // in milliseconds
-    private final int KEYREQUEST_MS_TIMEOUT = 5000;  // in milliseconds
-
-    private byte[] mPssh;
-    private ExecutorService mExecutorService;
-    private Future<byte[]> mFuture;
-    private String mDefaultHeartbeatUrl;
-    private String mServerUrl;
-
-    public KeyRequester(byte[] pssh, String url) {
-        mPssh = pssh;
-        mServerUrl = url;
-    }
-
-    public final String getDefaultHeartbeatUrl() {
-        return mDefaultHeartbeatUrl;
-    }
-
-    public byte[] doTransact(final MediaDrm drm, final byte[] sessionId, final int keyType) {
-        boolean retryRequest;
-        boolean retryTransaction;
-        byte[] keySetIdResult;
-        int getKeyRequestRetryCount;
-        int provisioningRetryCount = 0;
-        MediaDrm.KeyRequest drmRequest;
-
-        mExecutorService = Executors.newFixedThreadPool(POOL_SIZE);
-
-        do {
-            drmRequest = null;
-            getKeyRequestRetryCount = 0;
-            keySetIdResult = null;
-            retryTransaction = false;
-
-            do {
-                retryRequest = false;
-
-                try {
-                    drmRequest = drm.getKeyRequest(sessionId, mPssh,
-                        "video/avc", keyType, null);
-                } catch (NotProvisionedException e) {
-                    Log.i(TAG, "Invalid certificate, reprovisioning");
-                    ProvisionRequester provisionRequester = new ProvisionRequester();
-                    provisionRequester.doTransact(drm);
-                    retryRequest = true;
-                }
-            } while (retryRequest && ++getKeyRequestRetryCount < MAX_RETRY_COUNT);
-
-            if (drmRequest == null) {
-                Log.e(TAG, "Failed to get key request");
-                return null;
-            }
-
-            try {
-                mFuture = mExecutorService.submit(new KeyRequesterTask(mServerUrl, drmRequest));
-            } catch (RejectedExecutionException e) {
-                Log.e(TAG, "Failed to submit KeyRequesterTask for execution", e);
-                if (++provisioningRetryCount < MAX_RETRY_COUNT) {
-                    continue;
-                } else {
-                    break;
-                }
-            }
-
-            try {
-                byte[] responseBody = mFuture.get(KEYREQUEST_MS_TIMEOUT, TimeUnit.MILLISECONDS);
-                if (responseBody == null) {
-                    Log.e(TAG, "No response from license server!");
-                    retryTransaction = true;
-                } else {
-                    byte[] drmResponse = parseResponseBody(responseBody);
-                    try {
-                        keySetIdResult = drm.provideKeyResponse(sessionId, drmResponse);
-                    } catch (NotProvisionedException e) {
-                        Log.i(TAG, "Response invalidated the certificate, reprovisioning");
-                        ProvisionRequester provisionRequester = new ProvisionRequester();
-                        provisionRequester.doTransact(drm);
-                        retryTransaction = true;
-                    } catch (DeniedByServerException e) {
-                        // informational, the event handler will take care of provisioning
-                        Log.i(TAG, "Server rejected the key request");
-                    }  catch (IllegalStateException e) {
-                        Log.e(TAG, "provideKeyResponse failed", e);
-                    }
-
-                    try {
-                        // first call to getKeyRequest does not return heartbeat url
-                        drmRequest = drm.getKeyRequest(sessionId, mPssh, "video/avc",
-                                keyType, null);
-                        try {
-                            mDefaultHeartbeatUrl = drmRequest.getDefaultUrl();
-                        } catch (Exception e) {
-                            // ignore
-                        }
-                    } catch (NotProvisionedException e) {
-                        Log.e(TAG, "Fails to get heartbeat url");
-                    }
-                    break;
-                }
-            } catch (ExecutionException | InterruptedException ex) {
-                Log.e(TAG, "Failed to execute KeyRequesterTask", ex);
-                shutdownAndAwaitTermination(mExecutorService);
-                return null;
-            } catch (TimeoutException te) {
-                // The request timed out. The network is possibly too slow.
-                // Cancel the running task.
-                Log.d(TAG, "Request timed out, retry...");
-                mFuture.cancel(true);
-                retryTransaction = true;
-            }
-        } while (retryTransaction && ++provisioningRetryCount < MAX_RETRY_COUNT);
-
-        shutdownAndAwaitTermination(mExecutorService);
-        return keySetIdResult;
-    }
-
-    private void shutdownAndAwaitTermination(ExecutorService pool) {
-        pool.shutdown();  // disable new tasks from being submitted
-        try {
-            // wait for existing tasks to terminate
-            if (!pool.awaitTermination(POOL_TERMINATION_MS_TIMEOUT, TimeUnit.MILLISECONDS)) {
-                pool.shutdownNow();
-                // wait for tasks to respond to being cancelled
-                if (!pool.awaitTermination(POOL_TERMINATION_MS_TIMEOUT, TimeUnit.MILLISECONDS))
-                    Log.e(TAG, "Pool did not terminate");
-            }
-        } catch (InterruptedException ie) {
-            // (Re-)Cancel if current thread also interrupted
-            pool.shutdownNow();
-            // Preserve interrupt status
-            Thread.currentThread().interrupt();
-        }
-    }
-
-    // Validate the response body and return the drmResponse blob.
-    private byte[] parseResponseBody(byte[] responseBody) {
-        String bodyString = null;
-        try {
-            bodyString = new String(responseBody, "UTF-8");
-        } catch (UnsupportedEncodingException e) {
-            e.printStackTrace();
-        }
-
-        if (bodyString == null) {
-            return null;
-        }
-
-        if (bodyString.startsWith("GLS/")) {
-            if (!bodyString.startsWith("GLS/1.")) {
-                Log.e(TAG, "Invalid server version, expected 1.x");
-                return null;
-            }
-            int drmMessageOffset = bodyString.indexOf("\r\n\r\n");
-            if (drmMessageOffset == -1) {
-                Log.e(TAG, "Invalid server response, could not locate drm message");
-                return null;
-            }
-            responseBody = Arrays.copyOfRange(responseBody, drmMessageOffset + 4,
-                    responseBody.length);
-        }
-        return responseBody;
-    }
-}
diff --git a/tests/tests/security/src/android/security/cts/KeyRequesterTask.java b/tests/tests/security/src/android/security/cts/KeyRequesterTask.java
deleted file mode 100644
index c4d96dd..0000000
--- a/tests/tests/security/src/android/security/cts/KeyRequesterTask.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.media.MediaDrm;
-import android.util.Log;
-import android.util.Pair;
-
-import java.io.IOException;
-import java.util.concurrent.Callable;
-import java.util.HashMap;
-
-public class KeyRequesterTask implements Callable<byte[]> {
-    private static final String TAG = "KeyRequesterTask";
-    private final MediaDrm.KeyRequest mDrmRequest;
-    private final String mUrl;
-
-    public KeyRequesterTask(String url, MediaDrm.KeyRequest drmRequest) {
-        mDrmRequest = drmRequest;
-        mUrl = url;
-    }
-
-    /**
-     * @return a byte array containing the license response if successful,
-     * {@code null} otherwise.
-     */
-    @Override
-    public byte[] call() throws Exception {
-        byte[] drmRequest = mDrmRequest.getData();
-        Log.d(TAG, "PostRequest:" + mUrl);
-
-        HashMap<String, String> headers = new HashMap<>();
-        headers.put("User-Agent", "Widevine CDM v1.0");
-        headers.put("Connection", "close");
-
-        try {
-            Pair<Integer, byte[]> response = HttpPost.execute(mUrl, drmRequest, headers);
-            int responseCode = response.first;
-            if (responseCode != 200) {
-                Log.d(TAG, "Server returned HTTP error code " + responseCode);
-                return null;
-            }
-            return response.second;
-        } catch (IOException e) {
-            e.printStackTrace();
-            return null;
-        }
-    }
-}
-
diff --git a/tests/tests/security/src/android/security/cts/LoadEffectLibraryTest.java b/tests/tests/security/src/android/security/cts/LoadEffectLibraryTest.java
deleted file mode 100644
index 900ac7f..0000000
--- a/tests/tests/security/src/android/security/cts/LoadEffectLibraryTest.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.security.cts;
-
-import junit.framework.TestCase;
-
-public class LoadEffectLibraryTest extends TestCase {
-
-    static {
-        System.loadLibrary("ctssecurity_jni");
-    }
-
-    /**
-     * Checks that no binder calls to IAudioFlinger manages to load an effect library.
-     */
-    public void testLoadLibrary() throws Exception {
-        assertTrue(doLoadLibraryTest());
-    }
-
-    private static native boolean doLoadLibraryTest();
-
-}
diff --git a/tests/tests/security/src/android/security/cts/MediaCryptoTest.java b/tests/tests/security/src/android/security/cts/MediaCryptoTest.java
deleted file mode 100644
index b5639a7..0000000
--- a/tests/tests/security/src/android/security/cts/MediaCryptoTest.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.media.MediaCrypto;
-import android.media.MediaCryptoException;
-import android.media.MediaDrm;
-import android.media.MediaDrmException;
-import android.media.NotProvisionedException;
-import android.media.ResourceBusyException;
-import android.test.AndroidTestCase;
-import android.util.Log;
-import java.util.UUID;
-
-public class MediaCryptoTest extends AndroidTestCase {
-    private static final String TAG = "MediaCryptoTest";
-
-    private static final UUID CLEARKEY_SCHEME_UUID =
-        new UUID(0x1077efecc0b24d02L, 0xace33c1e52e2fb4bL);
-    private static final UUID WIDEVINE_SCHEME_UUID =
-        new UUID(0xedef8ba979d64aceL, 0xa3c827dcd51d21edL);
-
-    static {
-        System.loadLibrary("ctssecurity_jni");
-    }
-
-    private native boolean validateCryptoNative(MediaCrypto crypto);
-
-    public void testMediaCryptoClearKey() throws Exception {
-        MediaCrypto crypto = null;
-        if (!MediaDrm.isCryptoSchemeSupported(CLEARKEY_SCHEME_UUID)) {
-            Log.i(TAG, "No ClearKey plugin, skipping test");
-            return;
-        }
-        try {
-            byte[] initData = new byte[0];
-            crypto = new MediaCrypto(CLEARKEY_SCHEME_UUID, initData);
-        } catch (MediaCryptoException e) {
-            throw new Error("Failed to create MediaCrypto using ClearKey plugin");
-        }
-
-        assertTrue("MediaCrypto validation failed", validateCryptoNative(crypto));
-    }
-
-    public void testMediaCryptoWidevine() throws Exception {
-        if (!MediaDrm.isCryptoSchemeSupported(WIDEVINE_SCHEME_UUID)) {
-            Log.i(TAG, "No Widevine plugin, skipping test");
-            return;
-        }
-
-        MediaDrm drm = null;
-        byte[] sessionId = null;
-
-        try {
-            drm = new MediaDrm(WIDEVINE_SCHEME_UUID);
-            sessionId = openSession(drm);
-            getWidevineKeys(drm, sessionId);
-            MediaCrypto crypto = new MediaCrypto(WIDEVINE_SCHEME_UUID, sessionId);
-            assertTrue("MediaCrypto validation failed", validateCryptoNative(crypto));
-        } catch (MediaCryptoException | MediaDrmException e) {
-            if (drm != null && sessionId != null) {
-                drm.closeSession(sessionId);
-            }
-            throw e;
-        }
-    }
-
-    private byte[] openSession(MediaDrm drm) throws Exception {
-        byte[] sessionId = null;
-        int retryCount = 3;
-        while (retryCount-- > 0) {
-            try {
-                return drm.openSession();
-            } catch (NotProvisionedException e) {
-                Log.i(TAG, "Missing certificate, provisioning");
-                ProvisionRequester provisionRequester = new ProvisionRequester();
-                provisionRequester.doTransact(drm);
-            } catch (ResourceBusyException e) {
-                Log.w(TAG, "Resource busy in openSession, retrying...");
-                try {
-                    Thread.sleep(1000);
-                } catch (InterruptedException ie) {
-                    // ignore
-                }
-            }
-        }
-        throw new Error("Failed to open session");
-    }
-
-    private void getWidevineKeys(MediaDrm drm, byte[] sessionId) throws Exception {
-        final String kKeyServerUrl = "https://jmt17.google.com/video/license/GetCencLicense";
-        final byte[] kPssh = hex2ba("08011210e02562e04cd55351b14b3d748d36ed8e");
-        final String kClientAuth = "?source=YOUTUBE&video_id=EGHC6OHNbOo&oauth=ya.gtsqawidevine";
-        final String kPort = "80";
-        KeyRequester keyRequester = new KeyRequester(kPssh, kKeyServerUrl + ":" + kPort + kClientAuth);
-        if (keyRequester.doTransact(drm, sessionId, MediaDrm.KEY_TYPE_STREAMING) == null) {
-            throw new Error("Failed to get keys from license server!");
-        }
-    }
-
-    private static byte[] hex2ba(String s) {
-        int len = s.length();
-        byte[] data = new byte[len / 2];
-        for (int i = 0; i < len; i += 2) {
-            data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
-                                  + Character.digit(s.charAt(i+1), 16));
-        }
-        return data;
-    }
-}
diff --git a/tests/tests/security/src/android/security/cts/MediaMetadataRetrieverTest.java b/tests/tests/security/src/android/security/cts/MediaMetadataRetrieverTest.java
index 06ef5fd..6ae0d69 100644
--- a/tests/tests/security/src/android/security/cts/MediaMetadataRetrieverTest.java
+++ b/tests/tests/security/src/android/security/cts/MediaMetadataRetrieverTest.java
@@ -16,7 +16,7 @@
 
 package android.security.cts;
 
-import com.android.cts.security.R;
+import android.security.cts.R;
 
 import android.content.res.AssetFileDescriptor;
 import android.content.res.Resources;
diff --git a/tests/tests/security/src/android/security/cts/MediaPlayerInfoLeakTest.java b/tests/tests/security/src/android/security/cts/MediaPlayerInfoLeakTest.java
deleted file mode 100644
index e34fc05..0000000
--- a/tests/tests/security/src/android/security/cts/MediaPlayerInfoLeakTest.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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 junit.framework.TestCase;
-
-public class MediaPlayerInfoLeakTest extends TestCase {
-
-    static {
-        System.loadLibrary("ctssecurity_jni");
-    }
-
-
-    /**
-     * Checks that IMediaPlayer::getCurrentPosition() does not leak info in error case
-     */
-    public void test_getCurrentPositionLeak() throws Exception {
-        int pos = native_test_getCurrentPositionLeak();
-        assertTrue(String.format("Leaked pos 0x%08X", pos), pos == 0);
-    }
-
-    /**
-     * Checks that IMediaPlayer::getDuration() does not leak info in error case
-     */
-    public void test_getDurationLeak() throws Exception {
-        int dur = native_test_getDurationLeak();
-        assertTrue(String.format("Leaked dur 0x%08X", dur), dur == 0);
-    }
-
-    private static native int native_test_getCurrentPositionLeak();
-    private static native int native_test_getDurationLeak();
-}
diff --git a/tests/tests/security/src/android/security/cts/MediaServerCrashTest.java b/tests/tests/security/src/android/security/cts/MediaServerCrashTest.java
index 5ee1ae5..147a5cd 100644
--- a/tests/tests/security/src/android/security/cts/MediaServerCrashTest.java
+++ b/tests/tests/security/src/android/security/cts/MediaServerCrashTest.java
@@ -33,7 +33,7 @@
 import java.io.IOException;
 import java.io.RandomAccessFile;
 
-import com.android.cts.security.R;
+import android.security.cts.R;
 
 public class MediaServerCrashTest extends AndroidTestCase {
     private static final String TAG = "MediaServerCrashTest";
diff --git a/tests/tests/security/src/android/security/cts/NativeCodeTest.java b/tests/tests/security/src/android/security/cts/NativeCodeTest.java
index ab41b4f..5fa698e 100644
--- a/tests/tests/security/src/android/security/cts/NativeCodeTest.java
+++ b/tests/tests/security/src/android/security/cts/NativeCodeTest.java
@@ -64,6 +64,24 @@
                    + "https://github.com/torvalds/linux/commit/a134f083e79f",
                    doPingPongRootTest());
     }
+
+    public void testPipeReadV() throws Exception {
+        assertTrue("Device is vulnerable to CVE-2015-1805 and/or CVE-2016-0774,"
+                   + " a vulnerability in the pipe_read() function."
+                   + " Please apply the following patches:\n"
+                   + "https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/commit/?id=75cf667b7fac08a7b21694adca7dff07361be68a\n"
+                   + "https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/commit/?id=feae3ca2e5e1a8f44aa6290255d3d9709985d0b2\n",
+                   doPipeReadVTest());
+    }
+
+    public void testSysVipc() throws Exception {
+        assertTrue("Android does not support Sys V IPC, it must "
+                   + "be removed from the kernel. In the kernel config: "
+                   + "Change \"CONFIG_SYSVIPC=y\" to \"# CONFIG_SYSVIPC is not set\" "
+                   + "and rebuild.",
+                   doSysVipcTest());
+    }
+
     /**
      * Returns true iff this device is vulnerable to CVE-2013-2094.
      * A patch for CVE-2013-2094 can be found at
@@ -140,4 +158,38 @@
      */
     private static native boolean doPingPongRootTest();
 
+    /**
+     * CVE-2015-1805 and CVE-2016-0774
+     *
+     * Returns true if the patches are applied, crashes the system otherwise.
+     *
+     * Detects if the following patches are present.
+     * https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/commit/?id=75cf667b7fac08a7b21694adca7dff07361be68a
+     * https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/commit/?id=feae3ca2e5e1a8f44aa6290255d3d9709985d0b2
+     *
+     * b/27275324 and b/27721803
+     */
+    private static native boolean doPipeReadVTest();
+
+    /**
+     * Test that SysV IPC has been removed from the kernel.
+     *
+     * Returns true if SysV IPC has been removed.
+     *
+     * System V IPCs are not compliant with Android's application lifecycle because allocated
+     * resources are not freed by the low memory killer. This lead to global kernel resource leakage.
+     *
+     * For example, there is no way to automatically release a SysV semaphore
+     * allocated in the kernel when:
+     * - a buggy or malicious process exits
+     * - a non-buggy and non-malicious process crashes or is explicitly killed.
+     *
+     * Killing processes automatically to make room for new ones is an
+     * important part of Android's application lifecycle implementation. This means
+     * that, even assuming only non-buggy and non-malicious code, it is very likely
+     * that over time, the kernel global tables used to implement SysV IPCs will fill
+     * up.
+     */
+    private static native boolean doSysVipcTest();
+
 }
diff --git a/tests/tests/security/src/android/security/cts/OpenSSLEarlyCCSTest.java b/tests/tests/security/src/android/security/cts/OpenSSLEarlyCCSTest.java
index 9cdb288..bba75dc 100644
--- a/tests/tests/security/src/android/security/cts/OpenSSLEarlyCCSTest.java
+++ b/tests/tests/security/src/android/security/cts/OpenSSLEarlyCCSTest.java
@@ -26,8 +26,6 @@
 import android.test.InstrumentationTestCase;
 import android.util.Log;
 
-import com.android.cts.security.R;
-
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
diff --git a/tests/tests/security/src/android/security/cts/OpenSSLHeartbleedTest.java b/tests/tests/security/src/android/security/cts/OpenSSLHeartbleedTest.java
index 12fcee4..61a03a1 100644
--- a/tests/tests/security/src/android/security/cts/OpenSSLHeartbleedTest.java
+++ b/tests/tests/security/src/android/security/cts/OpenSSLHeartbleedTest.java
@@ -20,8 +20,6 @@
 import android.test.InstrumentationTestCase;
 import android.util.Log;
 
-import com.android.cts.security.R;
-
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.EOFException;
diff --git a/tests/tests/security/src/android/security/cts/PackageSignatureTest.java b/tests/tests/security/src/android/security/cts/PackageSignatureTest.java
index 71ef064..6024a4b 100644
--- a/tests/tests/security/src/android/security/cts/PackageSignatureTest.java
+++ b/tests/tests/security/src/android/security/cts/PackageSignatureTest.java
@@ -16,8 +16,6 @@
 
 package android.security.cts;
 
-import com.android.cts.security.R;
-
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
@@ -35,10 +33,13 @@
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 public class PackageSignatureTest extends AndroidTestCase {
 
     private static final String TAG = PackageSignatureTest.class.getSimpleName();
+    private static final Pattern TEST_PACKAGE_PATTERN = Pattern.compile("android\\.[^\\.]+\\.cts");
 
     public void testPackageSignatures() throws Exception {
         Set<String> badPackages = new HashSet<String>();
@@ -114,8 +115,8 @@
     private boolean isWhitelistedPackage(String packageName) {
         // Don't check the signatures of CTS test packages on the device.
         // devicesetup is the APK CTS loads to collect information needed in the final report
-        return packageName.startsWith("com.android.cts")
-                || WHITELISTED_PACKAGES.contains(packageName);
+        final Matcher matcher = TEST_PACKAGE_PATTERN.matcher(packageName);
+        return matcher.matches() || WHITELISTED_PACKAGES.contains(packageName);
     }
 
     private static final int DEFAULT_BUFFER_BYTES = 1024 * 4;
diff --git a/tests/tests/security/src/android/security/cts/ProvisionRequester.java b/tests/tests/security/src/android/security/cts/ProvisionRequester.java
deleted file mode 100644
index ee1cb9e..0000000
--- a/tests/tests/security/src/android/security/cts/ProvisionRequester.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.media.DeniedByServerException;
-import android.media.MediaDrm;
-import android.util.Log;
-import android.util.Pair;
-
-import java.io.IOException;
-import java.util.HashMap;
-
-public class ProvisionRequester {
-    private final String TAG = "ProvisionRequester";
-
-    public ProvisionRequester() {
-    }
-
-    public void doTransact(final MediaDrm drm) {
-        Thread t = new Thread() {
-            @Override
-            public void run() {
-                MediaDrm.ProvisionRequest drmRequest;
-                drmRequest = drm.getProvisionRequest();
-                byte[] responseBody = postRequest(drmRequest.getDefaultUrl(),
-                        drmRequest.getData());
-
-                if (responseBody == null) {
-                    Log.e(TAG, "No response from provisioning server!");
-                } else {
-                    try {
-                        drm.provideProvisionResponse(responseBody);
-                    } catch (DeniedByServerException e) {
-                        Log.e(TAG, "Server denied provisioning request");
-                    }
-                }
-            }
-        };
-        t.start();
-
-        try {
-            t.join();
-        } catch (InterruptedException e) {
-        }
-    }
-
-    // TODO May want to throw exceptions without having try/catch in body.
-    private byte[] postRequest(String url, byte[] drmRequest) {
-        String signedUrl = url + "&signedRequest=" + new String(drmRequest);
-        Log.d(TAG, "PostRequest:" + signedUrl);
-
-        HashMap<String, String> headers = new HashMap<>();
-        headers.put("Accept", "*/*");
-        headers.put("User-Agent", "Widevine CDM v1.0");
-        headers.put("Content-Type", "application/json");
-        headers.put("Connection", "close");
-
-        try {
-            Pair<Integer, byte[]> response = HttpPost.execute(signedUrl, null, headers);
-            int responseCode = response.first;
-            if (responseCode != 200) {
-                Log.e(TAG, "Server returned HTTP error code " + responseCode);
-                return null;
-            }
-            return response.second;
-        } catch (IOException e) {
-            e.printStackTrace();
-            return null;
-        }
-    }
-
-    private void sleep(int msec) {
-        try {
-            Thread.sleep(msec);
-        } catch (InterruptedException e) {
-        }
-    }
-}
diff --git a/tests/tests/security/src/android/security/cts/SELinuxTest.java b/tests/tests/security/src/android/security/cts/SELinuxTest.java
index 3df7396..24ad020 100644
--- a/tests/tests/security/src/android/security/cts/SELinuxTest.java
+++ b/tests/tests/security/src/android/security/cts/SELinuxTest.java
@@ -42,43 +42,6 @@
         System.loadLibrary("ctssecurity_jni");
     }
 
-    public void testMyJni() {
-        try {
-            checkSELinuxAccess(null, null, null, null, null);
-            fail("checkSELinuxAccess should have thrown");
-        } catch (NullPointerException e) {
-            // expected
-        }
-        try {
-            checkSELinuxContext(null);
-            fail("checkSELinuxContext should have thrown");
-        } catch (NullPointerException e) {
-            // expected
-        }
-    }
-
-    public void testCheckAccessSane() {
-        assertFalse(checkSELinuxAccess("a", "b", "c", "d", "e"));
-    }
-
-    public void testCheckContextSane() {
-        assertFalse(checkSELinuxContext("a"));
-    }
-
-    public void testZygoteContext() {
-        assertTrue(checkSELinuxContext("u:r:zygote:s0"));
-    }
-
-    public void testZygote() {
-        assertFalse(checkSELinuxAccess("u:r:zygote:s0", "u:object_r:runas_exec:s0", "file", "getattr", "/system/bin/run-as"));
-    }
-
-    public void testNoBooleans() throws Exception {
-        // Intentionally not using JNI bindings to keep things simple
-        File[] files = new File("/sys/fs/selinux/booleans/").listFiles();
-        assertEquals(0, files.length);
-    }
-
     public void testCTSIsUntrustedApp() throws IOException {
         String found = KernelSettingsTest.getFile("/proc/self/attr/current");
         String expected = "u:r:untrusted_app:s0";
@@ -110,9 +73,5 @@
         assertEquals(getFileContext("/sys"), "u:object_r:sysfs:s0");
     }
 
-    private static native boolean checkSELinuxAccess(String scon, String tcon, String tclass, String perm, String extra);
-
-    private static native boolean checkSELinuxContext(String con);
-
     private static final native String getFileContext(String path);
 }
diff --git a/tests/tests/security/src/android/security/cts/StagefrightFoundationTest.java b/tests/tests/security/src/android/security/cts/StagefrightFoundationTest.java
deleted file mode 100644
index 9999d88..0000000
--- a/tests/tests/security/src/android/security/cts/StagefrightFoundationTest.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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 junit.framework.TestCase;
-
-public class StagefrightFoundationTest extends TestCase {
-
-    static {
-        System.loadLibrary("ctssecurity_jni");
-    }
-
-    /**
-     * Checks that IEffect::command() cannot leak data.
-     */
-    public void test_aMessageFromParcel() throws Exception {
-        assertTrue(native_test_aMessageFromParcel());
-    }
-
-    private static native boolean native_test_aMessageFromParcel();
-}
diff --git a/tests/tests/security/src/android/security/cts/StagefrightTest.java b/tests/tests/security/src/android/security/cts/StagefrightTest.java
index c9c8e87..6f34498 100644
--- a/tests/tests/security/src/android/security/cts/StagefrightTest.java
+++ b/tests/tests/security/src/android/security/cts/StagefrightTest.java
@@ -22,6 +22,8 @@
  */
 package android.security.cts;
 
+import android.test.AndroidTestCase;
+import android.util.Log;
 import android.content.Context;
 import android.content.res.AssetFileDescriptor;
 import android.content.res.Resources;
@@ -45,7 +47,7 @@
 import java.util.concurrent.locks.Condition;
 import java.util.concurrent.locks.ReentrantLock;
 
-import com.android.cts.security.R;
+import android.security.cts.R;
 
 
 /**
@@ -240,10 +242,28 @@
 
         final MediaPlayerCrashListener mpcl = new MediaPlayerCrashListener();
 
-        Thread t = new Thread(new Runnable() {
+        class LooperThread extends Thread {
+            private Looper mLooper;
+
+            LooperThread(Runnable runner) {
+                super(runner);
+            }
+
             @Override
             public void run() {
                 Looper.prepare();
+                mLooper = Looper.myLooper();
+                super.run();
+            }
+
+            public void stopLooper() {
+                mLooper.quitSafely();
+            }
+        }
+
+        LooperThread t = new LooperThread(new Runnable() {
+            @Override
+            public void run() {
 
                 MediaPlayer mp = new MediaPlayer();
                 mp.setOnErrorListener(mpcl);
@@ -272,7 +292,7 @@
         String cve = name.replace("_", "-").toUpperCase();
         assertFalse("Device *IS* vulnerable to " + cve,
                     mpcl.waitForError() == MediaPlayer.MEDIA_ERROR_SERVER_DIED);
-        t.interrupt();
+        t.stopLooper();
     }
 
     private void doStagefrightTestMediaCodec(final int rid) throws Exception {
@@ -319,34 +339,46 @@
                 codec.configure(format, surface, null, 0);
                 codec.start();
                 MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
-                while (true) {
-                    int flags = ex.getSampleFlags();
-                    long time = ex.getSampleTime();
-                    int bufidx = codec.dequeueInputBuffer(5000);
-                    if (bufidx >= 0) {
-                        int n = ex.readSampleData(codec.getInputBuffer(bufidx), 0);
-                        if (n < 0) {
-                            flags = MediaCodec.BUFFER_FLAG_END_OF_STREAM;
-                            time = 0;
-                            n = 0;
+                try {
+                    while (true) {
+                        int flags = ex.getSampleFlags();
+                        long time = ex.getSampleTime();
+                        int bufidx = codec.dequeueInputBuffer(5000);
+                        if (bufidx >= 0) {
+                            int n = ex.readSampleData(codec.getInputBuffer(bufidx), 0);
+                            if (n < 0) {
+                                flags = MediaCodec.BUFFER_FLAG_END_OF_STREAM;
+                                time = 0;
+                                n = 0;
+                            }
+                            codec.queueInputBuffer(bufidx, 0, n, time, flags);
+                            ex.advance();
                         }
-                        codec.queueInputBuffer(bufidx, 0, n, time, flags);
-                        ex.advance();
+                        int status = codec.dequeueOutputBuffer(info, 5000);
+                        if (status >= 0) {
+                            if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
+                                break;
+                            }
+                            if (info.presentationTimeUs > TIMEOUT_NS / 1000) {
+                                Log.d(TAG, "stopping after 10 seconds worth of data");
+                                break;
+                            }
+                            codec.releaseOutputBuffer(status, true);
+                        }
                     }
-                    int status = codec.dequeueOutputBuffer(info, 5000);
-                    if (status >= 0) {
-                        if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
-                            break;
-                        }
-                        if (info.presentationTimeUs > TIMEOUT_NS / 1000) {
-                            Log.d(TAG, "stopping after 10 seconds worth of data");
-                            break;
-                        }
-                        codec.releaseOutputBuffer(status, true);
+                } catch (MediaCodec.CodecException ce) {
+                    if (ce.getErrorCode() == MediaCodec.CodecException.ERROR_RECLAIMED) {
+                        // This indicates that the remote service is dead, suggesting a crash.
+                        throw new RuntimeException(ce);
                     }
+                    // Other errors ignored.
+                } catch (IllegalStateException ise) {
+                    // Other errors ignored.
+                } finally {
+                    codec.release();
                 }
-                codec.release();
             }
         }
+        ex.release();
     }
 }
diff --git a/tests/tests/security/src/android/security/cts/X509CertChainBuildingTest.java b/tests/tests/security/src/android/security/cts/X509CertChainBuildingTest.java
new file mode 100644
index 0000000..70e345d
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/X509CertChainBuildingTest.java
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.content.res.AssetManager;
+import android.net.http.X509TrustManagerExtensions;
+import android.test.AndroidTestCase;
+
+import java.io.File;
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.List;
+import java.security.KeyStore;
+import java.security.Provider;
+import java.security.Security;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.X509TrustManager;
+
+/**
+ * Test that all {@link X509TrustManager} build the correct certificate chain during
+ * {@link X509TrustManagerExtensions#checkServerTrusted(X509Certificate[], String, String)} when
+ * multiple possible certificate paths exist.
+ */
+public class X509CertChainBuildingTest extends AndroidTestCase {
+    private static final String CERT_ASSET_DIR = "path_building";
+
+    /* Certificates for tests. These are initialized in setUp.
+     * All certificates use 2048 bit RSA keys and SHA-256 digests unless otherwise specified.
+     * First certificate graph:
+     *
+     * rootA: A root CA
+     * rootASha1: rootA but with SHA-1 as the digest algorithm.
+     * rootB: Another root CA
+     * leaf1: Certificate issued by rootA
+     * rootAtoB: rootA cross signed by rootB
+     * rootBtoA: rootB cross signed by rootA
+     *
+     *   [A] <-------> [B]
+     *    |
+     *    v
+     * [leaf1]
+     * Second certificate graph:
+     *
+     * intermediateA: Intermediate I issued by rootA
+     * intermediateB: Intermediate I issued by rootB
+     * leaf2: Leaf issued by I
+     *
+     * [A]   [B]
+     *    \ /
+     *    [I]
+     *     |
+     *     v
+     *  [leaf2]
+     *
+     *  These can be generated by running cts/tools/utils/certificates.py
+     */
+    private X509Certificate rootA;
+    private X509Certificate rootASha1;
+    private X509Certificate rootB;
+    private X509Certificate rootAtoB;
+    private X509Certificate rootBtoA;
+    private X509Certificate leaf1;
+    private X509Certificate leaf2;
+    private X509Certificate intermediateA;
+    private X509Certificate intermediateB;
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        rootA = loadCertificate("a.pem");
+        rootASha1 = loadCertificate("a_sha1.pem");
+        rootB = loadCertificate("b.pem");
+        leaf1 = loadCertificate("leaf1.pem");
+        leaf2 = loadCertificate("leaf2.pem");
+        rootAtoB = loadCertificate("a_to_b.pem");
+        rootBtoA = loadCertificate("b_to_a.pem");
+        intermediateA = loadCertificate("intermediate_a.pem");
+        intermediateB = loadCertificate("intermediate_b.pem");
+    }
+
+    public void testBasicChain() throws Exception {
+        assertExactPath(new X509Certificate[] {leaf1, rootA},
+                new X509Certificate[] {leaf1},
+                new X509Certificate[] {rootA});
+    }
+    public void testCrossSign() throws Exception {
+        // First try a path that doesn't have the cross signed A to B certificate.
+        assertNoPath(new X509Certificate[] {leaf1, rootA}, new X509Certificate[] {rootB});
+        // Now try with one valid chain (leaf1 -> rootAtoB -> rootB).
+        assertExactPath(new X509Certificate[] {leaf1, rootAtoB, rootB},
+                new X509Certificate[] {leaf1, rootAtoB},
+                new X509Certificate[] {rootB});
+        // Now try with two possible chains present only one of which chains to a trusted root.
+        assertExactPath(new X509Certificate[] {leaf1, rootAtoB, rootB},
+                new X509Certificate[] {leaf1, rootA, rootAtoB},
+                new X509Certificate[] {rootB});
+    }
+
+    public void testUntrustedLoop() throws Exception {
+        // Verify that providing all the certificates doesn't cause the path building to get stuck
+        // in the loop caused by the cross signed certificates.
+        assertNoPath(new X509Certificate[] {leaf1, rootAtoB, rootBtoA, rootA, rootB},
+                new X509Certificate[] {});
+    }
+
+    public void testAvoidCrossSigned() throws Exception {
+        // Check that leaf1 -> rootA is preferred over using the cross signed cert when both rootA
+        // and rootB are trusted.
+        assertExactPath(new X509Certificate[] {leaf1, rootA},
+                new X509Certificate[] {leaf1, rootAtoB},
+                new X509Certificate[] {rootA, rootB});
+    }
+
+    public void testSelfIssuedPreferred() throws Exception {
+        // Check that when there are multiple possible trusted issuers that we prefer self-issued
+        // certificates over bridge versions of the same certificate.
+        assertExactPath(new X509Certificate[] {leaf1, rootA},
+                new X509Certificate[] {leaf1, rootAtoB},
+                new X509Certificate[] {rootA, rootAtoB, rootB});
+    }
+
+    public void testBridgeCrossing() throws Exception {
+        // Check that when provided with leaf2, intermediateA, intermediateB, rootA that it builds
+        // the leaf2 -> intermediateB -> B path.
+        assertExactPath(new X509Certificate[] {leaf2, intermediateB, rootB},
+                new X509Certificate[] {leaf2, intermediateA, rootA, intermediateB},
+                new X509Certificate[] {rootB});
+    }
+
+    public void testDigestOrdering() throws Exception {
+        // Check that leaf1 -> rootASha1 is valid
+        assertExactPath(new X509Certificate[] {leaf1, rootASha1},
+                new X509Certificate[] {leaf1},
+                new X509Certificate[] {rootASha1});
+        // Check that when a SHA-256 and SHA-1 are available the SHA-256 cert is used
+        assertExactPath(new X509Certificate[] {leaf1, rootA},
+                new X509Certificate[] {leaf1},
+                new X509Certificate[] {rootASha1, rootA});
+    }
+
+    private X509Certificate loadCertificate(String file) throws Exception {
+        CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
+        AssetManager assetManager = getContext().getAssets();
+        InputStream in = null;
+        try {
+            in = assetManager.open(new File(CERT_ASSET_DIR, file).toString());
+            return (X509Certificate) certFactory.generateCertificate(in);
+        } finally {
+            if (in != null) {
+                in.close();
+            }
+        }
+    }
+
+    private static X509TrustManager getTrustManager(KeyStore ks, Provider p) throws Exception {
+        TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX", p);
+        tmf.init(ks);
+        for (TrustManager tm : tmf.getTrustManagers()) {
+            if (tm instanceof X509TrustManager) {
+                return (X509TrustManager) tm;
+            }
+        }
+        fail("Unable to find X509TrustManager");
+        return null;
+    }
+
+    /**
+     * Asserts that all PKIX TrustManagerFactory providers build the expected certificate path or
+     * throw a {@code CertificateException} if {@code expected} is {@code null}.
+     */
+    private static void assertExactPath(X509Certificate[] expected, X509Certificate[] bagOfCerts,
+            X509Certificate[] roots) throws Exception {
+        KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
+        ks.load(null);
+        int i = 0;
+        for (X509Certificate root : roots) {
+            ks.setEntry(String.valueOf(i++), new KeyStore.TrustedCertificateEntry(root), null);
+        }
+        Provider[] providers = Security.getProviders("TrustManagerFactory.PKIX");
+        assertNotNull(providers);
+        assertTrue("No providers found", providers.length != 0);
+        for (Provider p : providers) {
+            try {
+                X509TrustManager tm = getTrustManager(ks, p);
+                X509TrustManagerExtensions xtm = new X509TrustManagerExtensions(tm);
+                List<X509Certificate> result;
+                try {
+                    result = xtm.checkServerTrusted(bagOfCerts, "RSA", null);
+                } catch (CertificateException e) {
+                    if (expected == null) {
+                        // Exception expected.
+                        continue;
+                    }
+                    throw e;
+                }
+                if (expected == null) {
+                    fail("checkServerTrusted expected to fail, instead returned: " + result);
+                }
+                assertEquals(Arrays.asList(expected), result);
+            } catch (Exception e) {
+                throw new Exception("Failed with provider " + p, e);
+            }
+        }
+    }
+
+    private static void assertNoPath(X509Certificate[] bagOfCerts, X509Certificate[] roots)
+            throws Exception {
+        assertExactPath(null, bagOfCerts, roots);
+    }
+
+}
diff --git a/tests/tests/shortcutmanager/Android.mk b/tests/tests/shortcutmanager/Android.mk
new file mode 100755
index 0000000..1f6bd27
--- /dev/null
+++ b/tests/tests/shortcutmanager/Android.mk
@@ -0,0 +1,45 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
+    android-support-test \
+    android-support-v4 \
+    mockito-target \
+    ctsdeviceutil \
+    ctstestrunner \
+    ub-uiautomator \
+    ShortcutManagerTestUtils
+
+LOCAL_JAVA_LIBRARIES := android.test.runner
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := CtsShortcutManagerTestCases
+
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_SDK_VERSION := test_current
+
+include $(BUILD_CTS_PACKAGE)
+#include $(BUILD_PACKAGE)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/tests/shortcutmanager/AndroidManifest.xml b/tests/tests/shortcutmanager/AndroidManifest.xml
new file mode 100755
index 0000000..19fe596
--- /dev/null
+++ b/tests/tests/shortcutmanager/AndroidManifest.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.content.pm.cts.shortcutmanager"
+    android:sharedUserId="android.content.pm.cts.shortcutmanager.packages">
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+        android:targetPackage="android.content.pm.cts.shortcutmanager"
+        android:label="CTS tests for ShortcutManager">
+        <meta-data android:name="listener"
+            android:value="com.android.cts.runner.CtsTestRunListener" />
+    </instrumentation>
+
+</manifest>
+
diff --git a/tests/tests/shortcutmanager/AndroidTest.xml b/tests/tests/shortcutmanager/AndroidTest.xml
new file mode 100644
index 0000000..2955155
--- /dev/null
+++ b/tests/tests/shortcutmanager/AndroidTest.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for ShortcutManager CTS test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsShortcutManagerTestCases.apk" />
+        <option name="test-file-name" value="CtsShortcutManagerPackage1.apk" />
+        <option name="test-file-name" value="CtsShortcutManagerPackage2.apk" />
+        <option name="test-file-name" value="CtsShortcutManagerPackage3.apk" />
+        <option name="test-file-name" value="CtsShortcutManagerPackage4.apk" />
+        <option name="test-file-name" value="CtsShortcutManagerLauncher1.apk" />
+        <option name="test-file-name" value="CtsShortcutManagerLauncher2.apk" />
+        <option name="test-file-name" value="CtsShortcutManagerLauncher3.apk" />
+        <option name="test-file-name" value="CtsShortcutManagerLauncher4.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.content.pm.cts.shortcutmanager" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/tests/shortcutmanager/packages/Android.mk b/tests/tests/shortcutmanager/packages/Android.mk
new file mode 100644
index 0000000..3d02f9c
--- /dev/null
+++ b/tests/tests/shortcutmanager/packages/Android.mk
@@ -0,0 +1,17 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/tests/shortcutmanager/packages/launchermanifest/Android.mk b/tests/tests/shortcutmanager/packages/launchermanifest/Android.mk
new file mode 100644
index 0000000..bacca5d
--- /dev/null
+++ b/tests/tests/shortcutmanager/packages/launchermanifest/Android.mk
@@ -0,0 +1,75 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+#-----------------------------------------------------------
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := CtsShortcutManagerPackage1
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, ../src)
+
+LOCAL_SDK_VERSION := current
+
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_AAPT_FLAGS += --rename-manifest-package android.content.pm.cts.shortcutmanager.packages.package1
+
+include $(BUILD_CTS_PACKAGE)
+
+#-----------------------------------------------------------
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := CtsShortcutManagerPackage2
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, ../src)
+
+LOCAL_SDK_VERSION := current
+
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_AAPT_FLAGS += --rename-manifest-package android.content.pm.cts.shortcutmanager.packages.package2
+
+include $(BUILD_CTS_PACKAGE)
+
+#-----------------------------------------------------------
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := CtsShortcutManagerPackage3
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, ../src)
+
+LOCAL_SDK_VERSION := current
+
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_AAPT_FLAGS += --rename-manifest-package android.content.pm.cts.shortcutmanager.packages.package3
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/shortcutmanager/packages/launchermanifest/AndroidManifest.xml b/tests/tests/shortcutmanager/packages/launchermanifest/AndroidManifest.xml
new file mode 100755
index 0000000..039ed5c
--- /dev/null
+++ b/tests/tests/shortcutmanager/packages/launchermanifest/AndroidManifest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.content.pm.cts.shortcutmanager.packages"
+    android:sharedUserId="android.content.pm.cts.shortcutmanager.packages">
+
+    <application>
+        <activity android:name="Launcher">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.LAUNCHER" />
+                <category android:name="android.intent.category.HOME" />
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
+
diff --git a/tests/tests/shortcutmanager/packages/launchermanifest_nonshared/Android.mk b/tests/tests/shortcutmanager/packages/launchermanifest_nonshared/Android.mk
new file mode 100644
index 0000000..793fa66
--- /dev/null
+++ b/tests/tests/shortcutmanager/packages/launchermanifest_nonshared/Android.mk
@@ -0,0 +1,34 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := CtsShortcutManagerPackage4
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, ../src)
+
+LOCAL_SDK_VERSION := current
+
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_AAPT_FLAGS += --rename-manifest-package android.content.pm.cts.shortcutmanager.packages.package4
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/shortcutmanager/packages/launchermanifest_nonshared/AndroidManifest.xml b/tests/tests/shortcutmanager/packages/launchermanifest_nonshared/AndroidManifest.xml
new file mode 100755
index 0000000..9808da4
--- /dev/null
+++ b/tests/tests/shortcutmanager/packages/launchermanifest_nonshared/AndroidManifest.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.content.pm.cts.shortcutmanager.packages">
+
+    <application>
+        <activity android:name="Launcher">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.LAUNCHER" />
+                <category android:name="android.intent.category.HOME" />
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
+
diff --git a/tests/tests/shortcutmanager/packages/packagemanifest/Android.mk b/tests/tests/shortcutmanager/packages/packagemanifest/Android.mk
new file mode 100644
index 0000000..8f9babd
--- /dev/null
+++ b/tests/tests/shortcutmanager/packages/packagemanifest/Android.mk
@@ -0,0 +1,74 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := CtsShortcutManagerLauncher1
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, ../src)
+
+LOCAL_SDK_VERSION := current
+
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_AAPT_FLAGS += --rename-manifest-package android.content.pm.cts.shortcutmanager.packages.launcher1
+
+include $(BUILD_CTS_PACKAGE)
+
+#-----------------------------------------------------------
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := CtsShortcutManagerLauncher2
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, ../src)
+
+LOCAL_SDK_VERSION := current
+
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_AAPT_FLAGS += --rename-manifest-package android.content.pm.cts.shortcutmanager.packages.launcher2
+
+include $(BUILD_CTS_PACKAGE)
+
+#-----------------------------------------------------------
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := CtsShortcutManagerLauncher3
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, ../src)
+
+LOCAL_SDK_VERSION := current
+
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_AAPT_FLAGS += --rename-manifest-package android.content.pm.cts.shortcutmanager.packages.launcher3
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/shortcutmanager/packages/packagemanifest/AndroidManifest.xml b/tests/tests/shortcutmanager/packages/packagemanifest/AndroidManifest.xml
new file mode 100755
index 0000000..463757d
--- /dev/null
+++ b/tests/tests/shortcutmanager/packages/packagemanifest/AndroidManifest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.content.pm.cts.shortcutmanager.packages"
+    android:sharedUserId="android.content.pm.cts.shortcutmanager.packages">
+
+    <application>
+        <activity android:name="android.content.pm.cts.shortcutmanager.packages.Launcher">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.LAUNCHER" />
+                <category android:name="android.intent.category.HOME" />
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
+
diff --git a/tests/tests/shortcutmanager/packages/packagemanifest_nonshared/Android.mk b/tests/tests/shortcutmanager/packages/packagemanifest_nonshared/Android.mk
new file mode 100644
index 0000000..4aebb74
--- /dev/null
+++ b/tests/tests/shortcutmanager/packages/packagemanifest_nonshared/Android.mk
@@ -0,0 +1,34 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := CtsShortcutManagerLauncher4
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, ../src)
+
+LOCAL_SDK_VERSION := current
+
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_AAPT_FLAGS += --rename-manifest-package android.content.pm.cts.shortcutmanager.packages.launcher4
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/shortcutmanager/packages/packagemanifest_nonshared/AndroidManifest.xml b/tests/tests/shortcutmanager/packages/packagemanifest_nonshared/AndroidManifest.xml
new file mode 100755
index 0000000..05c9db7
--- /dev/null
+++ b/tests/tests/shortcutmanager/packages/packagemanifest_nonshared/AndroidManifest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.content.pm.cts.shortcutmanager.packages">
+
+    <application>
+    </application>
+</manifest>
+
diff --git a/tests/tests/shortcutmanager/packages/src/android/content/pm/cts/shortcutmanager/packages/Launcher.java b/tests/tests/shortcutmanager/packages/src/android/content/pm/cts/shortcutmanager/packages/Launcher.java
new file mode 100644
index 0000000..88db59a
--- /dev/null
+++ b/tests/tests/shortcutmanager/packages/src/android/content/pm/cts/shortcutmanager/packages/Launcher.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.content.pm.cts.shortcutmanager.packages;
+
+import android.app.Activity;
+
+public class Launcher extends Activity {
+}
diff --git a/tests/tests/shortcutmanager/src/android/content/pm/cts/ShortcutManagerAidlCallPermissionTest.java b/tests/tests/shortcutmanager/src/android/content/pm/cts/ShortcutManagerAidlCallPermissionTest.java
new file mode 100644
index 0000000..30ef0cf
--- /dev/null
+++ b/tests/tests/shortcutmanager/src/android/content/pm/cts/ShortcutManagerAidlCallPermissionTest.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.content.pm.cts;
+
+/**
+ * - Command line command permissions
+ * - Internal AIDL call permissions.
+ * - Faking parameter to the AIDL call (user-ID)
+ */
+public class ShortcutManagerAidlCallPermissionTest {
+}
diff --git a/tests/tests/shortcutmanager/src/android/content/pm/cts/ShortcutManagerCtsTestsBase.java b/tests/tests/shortcutmanager/src/android/content/pm/cts/ShortcutManagerCtsTestsBase.java
new file mode 100644
index 0000000..de725d6
--- /dev/null
+++ b/tests/tests/shortcutmanager/src/android/content/pm/cts/ShortcutManagerCtsTestsBase.java
@@ -0,0 +1,338 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.content.pm.cts;
+
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.*;
+
+import android.app.Activity;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.content.Intent;
+import android.content.pm.LauncherApps;
+import android.content.pm.ShortcutInfo;
+import android.content.pm.ShortcutManager;
+import android.graphics.drawable.Icon;
+import android.os.Bundle;
+import android.os.UserHandle;
+import android.support.annotation.NonNull;
+import android.test.InstrumentationTestCase;
+import android.text.TextUtils;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public abstract class ShortcutManagerCtsTestsBase extends InstrumentationTestCase {
+
+    private static class SpoofingContext extends ContextWrapper {
+        private final String mPackageName;
+
+        public SpoofingContext(Context base, String packageName) {
+            super(base);
+            mPackageName = packageName;
+        }
+
+        @Override
+        public String getPackageName() {
+            return mPackageName;
+        }
+    }
+
+    private Context mCurrentCallerPackage;
+    private int mUserId;
+    private UserHandle mUserHandle;
+
+    private String mOriginalLauncher;
+
+    protected Context mPackageContext1;
+    protected Context mPackageContext2;
+    protected Context mPackageContext3;
+    protected Context mPackageContext4;
+
+    protected Context mLauncherContext1;
+    protected Context mLauncherContext2;
+    protected Context mLauncherContext3;
+    protected Context mLauncherContext4;
+
+    protected LauncherApps mLauncherApps1;
+    protected LauncherApps mLauncherApps2;
+    protected LauncherApps mLauncherApps3;
+    protected LauncherApps mLauncherApps4;
+
+    private Map<Context, ShortcutManager> mManagers = new HashMap<>();
+    private Map<Context, LauncherApps> mLauncherAppses = new HashMap<>();
+
+    private ShortcutManager mCurrentManager;
+    private LauncherApps mCurrentLauncherApps;
+
+    private static class ShortcutActivity extends Activity {
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        mUserId = getTestContext().getUserId();
+        mUserHandle = android.os.Process.myUserHandle();
+
+        final String config = getOverrideConfig();
+        if (config != null) {
+            overrideConfig(getInstrumentation(), config);
+        }
+        mOriginalLauncher = getDefaultLauncher(getInstrumentation());
+
+        mPackageContext1 = new SpoofingContext(getTestContext(),
+                "android.content.pm.cts.shortcutmanager.packages.package1");
+        mPackageContext2 = new SpoofingContext(getTestContext(),
+                "android.content.pm.cts.shortcutmanager.packages.package2");
+        mPackageContext3 = new SpoofingContext(getTestContext(),
+                "android.content.pm.cts.shortcutmanager.packages.package3");
+        mPackageContext4 = new SpoofingContext(getTestContext(),
+                "android.content.pm.cts.shortcutmanager.packages.package4");
+        mLauncherContext1 = new SpoofingContext(getTestContext(),
+                "android.content.pm.cts.shortcutmanager.packages.launcher1");
+        mLauncherContext2 = new SpoofingContext(getTestContext(),
+                "android.content.pm.cts.shortcutmanager.packages.launcher2");
+        mLauncherContext3 = new SpoofingContext(getTestContext(),
+                "android.content.pm.cts.shortcutmanager.packages.launcher3");
+        mLauncherContext4 = new SpoofingContext(getTestContext(),
+                "android.content.pm.cts.shortcutmanager.packages.launcher4");
+
+        mLauncherApps1 = new LauncherApps(mLauncherContext1);
+        mLauncherApps2 = new LauncherApps(mLauncherContext2);
+        mLauncherApps3 = new LauncherApps(mLauncherContext3);
+        mLauncherApps4 = new LauncherApps(mLauncherContext4);
+
+        clearShortcuts(getInstrumentation(), mUserId, mPackageContext1.getPackageName());
+        clearShortcuts(getInstrumentation(), mUserId, mPackageContext2.getPackageName());
+        clearShortcuts(getInstrumentation(), mUserId, mPackageContext3.getPackageName());
+        clearShortcuts(getInstrumentation(), mUserId, mPackageContext4.getPackageName());
+
+        setCurrentCaller(mPackageContext1);
+
+        // Make sure shortcuts are removed.
+        withCallers(getAllPublishers(), new Runnable() {
+            @Override
+            public void run() {
+                assertEquals("for " + getCurrentCallingPackage(),
+                        0, getManager().getDynamicShortcuts().size());
+                assertEquals("for " + getCurrentCallingPackage(),
+                        0, getManager().getPinnedShortcuts().size());
+            }
+        });
+        // This was calling the wrong lambda.
+//        withCallers(getAllPublishers(), () -> {
+//            assertEquals("for " + getCurrentCallingPackage(),
+//                    0, getManager().getDynamicShortcuts().size());
+//            assertEquals("for " + getCurrentCallingPackage(),
+//                    0, getManager().getPinnedShortcuts().size());
+//        });
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        resetConfig(getInstrumentation());
+
+        if (!TextUtils.isEmpty(mOriginalLauncher)) {
+            setDefaultLauncher(getInstrumentation(), mOriginalLauncher);
+        }
+
+        super.tearDown();
+    }
+
+    protected Context getTestContext() {
+        return getInstrumentation().getContext();
+    }
+
+    protected UserHandle getUserHandle() {
+        return mUserHandle;
+    }
+
+    protected List<Context> getAllPublishers() {
+        // 4 has a different signature, so we can't call for it.
+        return list(mPackageContext1, mPackageContext2, mPackageContext3);
+    }
+
+    protected List<Context> getAllLaunchers() {
+        // 4 has a different signature, so we can't call for it.
+        return list(mLauncherContext1, mLauncherContext2, mLauncherContext3);
+    }
+
+    protected List<Context> getAllCallers() {
+        return list(
+                mPackageContext1, mPackageContext2, mPackageContext3, mPackageContext4,
+                mLauncherContext1, mLauncherContext2, mLauncherContext3, mLauncherContext4);
+    }
+
+    protected void withCallers(List<Context> callers, Runnable r) {
+        for (Context c : callers) {
+            runWithCaller(c, r);
+        }
+    }
+
+    protected String getOverrideConfig() {
+        return null;
+    }
+
+    protected void setCurrentCaller(Context callerContext) {
+        mCurrentCallerPackage = callerContext;
+
+        if (!mManagers.containsKey(mCurrentCallerPackage)) {
+            mManagers.put(mCurrentCallerPackage, new ShortcutManager(mCurrentCallerPackage));
+        }
+        mCurrentManager = mManagers.get(mCurrentCallerPackage);
+
+        if (!mLauncherAppses.containsKey(mCurrentCallerPackage)) {
+            mLauncherAppses.put(mCurrentCallerPackage, new LauncherApps(mCurrentCallerPackage));
+        }
+        mCurrentLauncherApps = mLauncherAppses.get(mCurrentCallerPackage);
+    }
+
+    protected Context getCurrentCallerContext() {
+        return mCurrentCallerPackage;
+    }
+
+    protected String getCurrentCallingPackage() {
+        return getCurrentCallerContext().getPackageName();
+    }
+
+    protected ShortcutManager getManager() {
+        return mCurrentManager;
+    }
+
+    protected LauncherApps getLauncherApps() {
+        return mCurrentLauncherApps;
+    }
+
+    protected void runWithCaller(Context callerContext, Runnable r) {
+        final Context prev = mCurrentCallerPackage;
+
+        setCurrentCaller(callerContext);
+
+        r.run();
+
+        setCurrentCaller(prev);
+    }
+
+    public static Bundle makeBundle(Object... keysAndValues) {
+        assertTrue((keysAndValues.length % 2) == 0);
+
+        if (keysAndValues.length == 0) {
+            return null;
+        }
+        final Bundle ret = new Bundle();
+
+        for (int i = keysAndValues.length - 2; i >= 0; i -= 2) {
+            final String key = keysAndValues[i].toString();
+            final Object value = keysAndValues[i + 1];
+
+            if (value == null) {
+                ret.putString(key, null);
+            } else if (value instanceof Integer) {
+                ret.putInt(key, (Integer) value);
+            } else if (value instanceof String) {
+                ret.putString(key, (String) value);
+            } else if (value instanceof Bundle) {
+                ret.putBundle(key, (Bundle) value);
+            } else {
+                fail("Type not supported yet: " + value.getClass().getName());
+            }
+        }
+        return ret;
+    }
+
+    /**
+     * Make a shortcut with an ID.
+     */
+    protected ShortcutInfo makeShortcut(String id) {
+        return makeShortcut(id, "Title-" + id);
+    }
+
+    /**
+     * Make a shortcut with an ID and a title.
+     */
+    protected ShortcutInfo makeShortcut(String id, String title) {
+        return makeShortcut(
+                id, title, /* activity =*/ null, /* icon =*/ null,
+                makeIntent(Intent.ACTION_VIEW, ShortcutActivity.class), /* weight =*/ 0);
+    }
+
+    /**
+     * Make a shortcut with an ID and icon.
+     */
+    protected ShortcutInfo makeShortcutWithIcon(String id, Icon icon) {
+        return makeShortcut(
+                id, "Title-" + id, /* activity =*/ null, icon,
+                makeIntent(Intent.ACTION_VIEW, ShortcutActivity.class), /* weight =*/ 0);
+    }
+
+    /**
+     * Make multiple shortcuts with IDs.
+     */
+    protected List<ShortcutInfo> makeShortcuts(String... ids) {
+        final ArrayList<ShortcutInfo> ret = new ArrayList();
+        for (String id : ids) {
+            ret.add(makeShortcut(id));
+        }
+        return ret;
+    }
+
+    protected ShortcutInfo.Builder makeShortcutBuilder() {
+        return new ShortcutInfo.Builder(getCurrentCallerContext());
+    }
+
+    /**
+     * Make a shortcut with details.
+     */
+    protected ShortcutInfo makeShortcut(String id, String title, ComponentName activity,
+            Icon icon, Intent intent, int weight) {
+        final ShortcutInfo.Builder  b = new ShortcutInfo.Builder(getCurrentCallerContext())
+                .setId(id)
+                .setTitle(title)
+                .setWeight(weight)
+                .setIntent(intent);
+        if (icon != null) {
+            b.setIcon(icon);
+        }
+        if (activity != null) {
+            b.setActivityComponent(activity);
+        }
+        final ShortcutInfo s = b.build();
+
+        return s;
+    }
+
+    /**
+     * Make an intent.
+     */
+    protected Intent makeIntent(String action, Class<?> clazz, Object... bundleKeysAndValues) {
+        final Intent intent = new Intent(action);
+        intent.setComponent(makeComponent(clazz));
+        intent.replaceExtras(makeBundle(bundleKeysAndValues));
+        return intent;
+    }
+
+    /**
+     * Make an component name, with the client context.
+     */
+    @NonNull
+    protected ComponentName makeComponent(Class<?> clazz) {
+        return new ComponentName(getCurrentCallerContext(), clazz);
+    }
+
+}
diff --git a/tests/tests/shortcutmanager/src/android/content/pm/cts/ShortcutManagerDynamicCountTest.java b/tests/tests/shortcutmanager/src/android/content/pm/cts/ShortcutManagerDynamicCountTest.java
new file mode 100644
index 0000000..110960a
--- /dev/null
+++ b/tests/tests/shortcutmanager/src/android/content/pm/cts/ShortcutManagerDynamicCountTest.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.content.pm.cts;
+
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertDynamicShortcutCountExceeded;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.list;
+
+public class ShortcutManagerDynamicCountTest extends ShortcutManagerCtsTestsBase {
+
+    @Override
+    protected String getOverrideConfig() {
+        return "reset_interval_sec=999999,"
+                + "max_updates_per_interval=999999,"
+                + "max_shortcuts=3,"
+                + "max_icon_dimension_dp=128,"
+                + "max_icon_dimension_dp_lowram=32,"
+                + "icon_format=PNG,"
+                + "icon_quality=100";
+    }
+
+    public void testSetDynamicShortcuts() {
+        runWithCaller(mPackageContext1, () -> {
+            getManager().setDynamicShortcuts(list(makeShortcut("s1")));
+            getManager().setDynamicShortcuts(list(
+                    makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3")));
+
+            assertDynamicShortcutCountExceeded(() -> {
+                getManager().setDynamicShortcuts(list(
+                        makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"),
+                        makeShortcut("s4")));
+            });
+        });
+    }
+}
diff --git a/tests/tests/shortcutmanager/src/android/content/pm/cts/ShortcutManagerNoThrottlingTest.java b/tests/tests/shortcutmanager/src/android/content/pm/cts/ShortcutManagerNoThrottlingTest.java
new file mode 100644
index 0000000..92b1a46
--- /dev/null
+++ b/tests/tests/shortcutmanager/src/android/content/pm/cts/ShortcutManagerNoThrottlingTest.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.content.pm.cts;
+
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertCallbackNotReceived;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertCallbackReceived;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertExpectException;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.checkAssertSuccess;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.list;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.resetAll;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.setDefaultLauncher;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.waitUntil;
+
+import static org.mockito.Mockito.mock;
+
+import android.content.pm.LauncherApps;
+import android.content.pm.ShortcutInfo;
+import android.content.pm.ShortcutManager;
+import android.os.Handler;
+import android.os.Looper;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import java.util.List;
+
+/**
+ * Tests for {@link ShortcutManager} and {@link ShortcutInfo}.
+ *
+ * In this test, we tests the main functionalities of those, without throttling.  We
+ */
+@SmallTest
+public class ShortcutManagerNoThrottlingTest extends ShortcutManagerCtsTestsBase {
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    @Override
+    protected String getOverrideConfig() {
+        return "reset_interval_sec=999999,"
+                + "max_updates_per_interval=999999,"
+                + "max_shortcuts=10,"
+                + "max_icon_dimension_dp=128,"
+                + "max_icon_dimension_dp_lowram=32,"
+                + "icon_format=PNG,"
+                + "icon_quality=100";
+    }
+
+    public void testShortcutInfoMissingMandatoryFields() {
+        assertExpectException(
+                IllegalArgumentException.class,
+                "ID must be provided",
+                () -> new ShortcutInfo.Builder(getTestContext()).build());
+        assertExpectException(
+                IllegalArgumentException.class, "title must be provided", () -> {
+            ShortcutInfo si = new ShortcutInfo.Builder(getTestContext()).setId("id").build();
+            getManager().setDynamicShortcuts(list(si));
+        });
+        assertExpectException(
+                NullPointerException.class, "Intent must be provided", () -> {
+            ShortcutInfo si = new ShortcutInfo.Builder(getTestContext()).setId("id").setTitle("x")
+                    .build();
+            getManager().setDynamicShortcuts(list(si));
+        });
+    }
+
+    /**
+     * Create shortcuts from different packages and make sure they're really different.
+     */
+    public void testSpoofingPublisher() {
+        runWithCaller(mPackageContext1, () -> {
+            ShortcutInfo s1 = makeShortcut("s1", "title1");
+            getManager().setDynamicShortcuts(list(s1));
+        });
+        runWithCaller(mPackageContext2, () -> {
+            ShortcutInfo s1 = makeShortcut("s1", "title2");
+            getManager().setDynamicShortcuts(list(s1));
+        });
+        runWithCaller(mPackageContext3, () -> {
+            ShortcutInfo s1 = makeShortcut("s1", "title3");
+            getManager().setDynamicShortcuts(list(s1));
+        });
+
+        runWithCaller(mPackageContext1, () -> {
+            final List<ShortcutInfo> list = getManager().getDynamicShortcuts();
+            assertEquals(1, list.size());
+            assertEquals("title1", list.get(0).getTitle());
+        });
+        runWithCaller(mPackageContext2, () -> {
+            final List<ShortcutInfo> list = getManager().getDynamicShortcuts();
+            assertEquals(1, list.size());
+            assertEquals("title2", list.get(0).getTitle());
+        });
+        runWithCaller(mPackageContext3, () -> {
+            final List<ShortcutInfo> list = getManager().getDynamicShortcuts();
+            assertEquals(1, list.size());
+            assertEquals("title3", list.get(0).getTitle());
+        });
+    }
+
+    public void testSpoofingLauncher() {
+        final LauncherApps.Callback c0_1 = mock(LauncherApps.Callback.class);
+        final LauncherApps.Callback c0_2 = mock(LauncherApps.Callback.class);
+        final LauncherApps.Callback c0_3 = mock(LauncherApps.Callback.class);
+        final Handler h = new Handler(Looper.getMainLooper());
+
+        runWithCaller(mLauncherContext1, () -> getLauncherApps().registerCallback(c0_1, h));
+        runWithCaller(mLauncherContext2, () -> getLauncherApps().registerCallback(c0_2, h));
+        runWithCaller(mLauncherContext3, () -> getLauncherApps().registerCallback(c0_3, h));
+
+        // Change the default launcher
+        setDefaultLauncher(getInstrumentation(), mLauncherContext2);
+
+        runWithCaller(mLauncherContext1,
+                () -> assertFalse(getLauncherApps().hasShortcutHostPermission()));
+        runWithCaller(mLauncherContext2,
+                () -> assertTrue(getLauncherApps().hasShortcutHostPermission()));
+        runWithCaller(mLauncherContext3,
+                () -> assertFalse(getLauncherApps().hasShortcutHostPermission()));
+
+        // Call a publisher API and make sure only launcher2 gets it.
+
+        resetAll(list(c0_1, c0_2, c0_3));
+
+        runWithCaller(mPackageContext1, () -> {
+            ShortcutInfo s1 = makeShortcut("s1", "title1");
+            getManager().setDynamicShortcuts(list(s1));
+        });
+
+        // Because of the handlers, callback calls are not synchronous.
+        waitUntil("Launcher 2 didn't receive message", () ->
+            checkAssertSuccess(() ->
+                assertCallbackReceived(c0_2, android.os.Process.myUserHandle(),
+                        mPackageContext1.getPackageName(), "s1")
+            )
+        );
+
+        assertCallbackNotReceived(c0_1);
+        assertCallbackNotReceived(c0_3);
+    }
+}
diff --git a/tests/tests/shortcutmanager/src/android/content/pm/cts/ShortcutManagerSpoofDetectionTest.java b/tests/tests/shortcutmanager/src/android/content/pm/cts/ShortcutManagerSpoofDetectionTest.java
new file mode 100644
index 0000000..37658ae
--- /dev/null
+++ b/tests/tests/shortcutmanager/src/android/content/pm/cts/ShortcutManagerSpoofDetectionTest.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.content.pm.cts;
+
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertExpectException;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.list;
+
+import static org.mockito.Mockito.mock;
+
+import android.content.Context;
+import android.content.pm.LauncherApps;
+import android.content.pm.LauncherApps.ShortcutQuery;
+import android.content.pm.ShortcutInfo;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.ParcelFileDescriptor;
+
+import java.io.IOException;
+
+public class ShortcutManagerSpoofDetectionTest extends ShortcutManagerCtsTestsBase {
+
+    @Override
+    protected String getOverrideConfig() {
+        return "reset_interval_sec=999999,"
+                + "max_updates_per_interval=999999,"
+                + "max_shortcuts=10,"
+                + "max_icon_dimension_dp=128,"
+                + "max_icon_dimension_dp_lowram=32,"
+                + "icon_format=PNG,"
+                + "icon_quality=100";
+    }
+
+    public void assertCallingPackageMismatch(String method, Context callerContext, Runnable r) {
+        assertExpectException(
+                "Caller=" + callerContext.getPackageName() + ", method=" + method,
+                SecurityException.class, "Calling package name mismatch",
+                () -> runWithCaller(callerContext, () -> r.run())
+        );
+    }
+
+    public void testPublisherSpoofing() {
+        assertCallingPackageMismatch("setDynamicShortcuts", mPackageContext4, () -> {
+            getManager().setDynamicShortcuts(list(makeShortcut("s1")));
+        });
+        assertCallingPackageMismatch("addDynamicShortcut", mPackageContext4, () -> {
+            getManager().addDynamicShortcuts(list(makeShortcut("s1")));
+        });
+        assertCallingPackageMismatch("deleteDynamicShortcut", mPackageContext4, () -> {
+            getManager().removeDynamicShortcuts(list("s1"));
+        });
+        assertCallingPackageMismatch("deleteAllDynamicShortcuts", mPackageContext4, () -> {
+            getManager().removeAllDynamicShortcuts();
+        });
+        assertCallingPackageMismatch("getDynamicShortcuts", mPackageContext4, () -> {
+            getManager().getDynamicShortcuts();
+        });
+        assertCallingPackageMismatch("getPinnedShortcuts", mPackageContext4, () -> {
+            getManager().getPinnedShortcuts();
+        });
+        assertCallingPackageMismatch("updateShortcuts", mPackageContext4, () -> {
+            getManager().updateShortcuts(list(makeShortcut("s1")));
+        });
+        assertCallingPackageMismatch("getMaxDynamicShortcutCount", mPackageContext4, () -> {
+            getManager().getMaxDynamicShortcutCount();
+        });
+        assertCallingPackageMismatch("getRemainingCallCount", mPackageContext4, () -> {
+            getManager().getRemainingCallCount();
+        });
+        assertCallingPackageMismatch("getRateLimitResetTime", mPackageContext4, () -> {
+            getManager().getRateLimitResetTime();
+        });
+        assertCallingPackageMismatch("getIconMaxDimensions", mPackageContext4, () -> {
+            getManager().getIconMaxDimensions();
+        });
+    }
+
+    public void testLauncherSpoofing() {
+        assertCallingPackageMismatch("hasShortcutHostPermission", mLauncherContext4, () -> {
+            getLauncherApps().hasShortcutHostPermission();
+        });
+
+        assertCallingPackageMismatch("registerCallback", mLauncherContext4, () -> {
+            final LauncherApps.Callback c = mock(LauncherApps.Callback.class);
+            getLauncherApps().registerCallback(c, new Handler(Looper.getMainLooper()));
+        });
+
+        assertCallingPackageMismatch("getShortcuts", mLauncherContext4, () -> {
+            ShortcutQuery q = new ShortcutQuery();
+            getLauncherApps().getShortcuts(q, getUserHandle());
+        });
+
+        assertCallingPackageMismatch("pinShortcuts", mLauncherContext4, () -> {
+            getLauncherApps().pinShortcuts(
+                    mPackageContext1.getPackageName(), list(), getUserHandle());
+        });
+
+        assertCallingPackageMismatch("getShortcutIconFd 1", mLauncherContext4, () -> {
+            ParcelFileDescriptor pfd = getLauncherApps().getShortcutIconFd(makeShortcut("s"));
+            try {
+                pfd.close();
+            } catch (IOException e) {
+            }
+        });
+        assertCallingPackageMismatch("getShortcutIconFd 2", mLauncherContext4, () -> {
+            ParcelFileDescriptor pfd = getLauncherApps().getShortcutIconFd(
+                    mPackageContext1.getPackageName(), "s1", getUserHandle());
+            try {
+                pfd.close();
+            } catch (IOException e) {
+            }
+        });
+
+        assertCallingPackageMismatch("startShortcut 1", mLauncherContext4, () -> {
+            getLauncherApps().startShortcut(makeShortcut("s"), null, null);
+        });
+        assertCallingPackageMismatch("startShortcut 2", mLauncherContext4, () -> {
+            getLauncherApps().startShortcut(mPackageContext1.getPackageName(), "s1",
+                    null, null, getUserHandle());
+        });
+    }
+}
diff --git a/tests/tests/shortcutmanager/src/android/content/pm/cts/ShortcutManagerThrottlingTest.java b/tests/tests/shortcutmanager/src/android/content/pm/cts/ShortcutManagerThrottlingTest.java
new file mode 100644
index 0000000..d5fda4d
--- /dev/null
+++ b/tests/tests/shortcutmanager/src/android/content/pm/cts/ShortcutManagerThrottlingTest.java
@@ -0,0 +1,216 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.content.pm.cts;
+
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.*;
+
+import android.test.suitebuilder.annotation.LargeTest;
+
+import java.util.function.BooleanSupplier;
+
+public class ShortcutManagerThrottlingTest extends ShortcutManagerCtsTestsBase {
+    private static final String CONFIG_BASE =
+            "max_updates_per_interval=5,"
+            + "max_shortcuts=10,"
+            + "max_icon_dimension_dp=128,"
+            + "max_icon_dimension_dp_lowram=32,"
+            + "icon_format=PNG,"
+            + "icon_quality=100";
+
+    private static final String CONFIG_3SEC = CONFIG_BASE + ",reset_interval_sec=3";
+
+    @Override
+    protected String getOverrideConfig() {
+        return CONFIG_3SEC;
+    }
+
+    private void resetThrottling() {
+        resetAllThrottling(getInstrumentation());
+        assertEquals(5, getManager().getRemainingCallCount());
+    }
+
+    private void waitUntilReset() {
+        final long resetTime = getManager().getRateLimitResetTime();
+        final long sleepTime = resetTime - System.currentTimeMillis();
+
+        if (sleepTime > 0) {
+            try {
+                Thread.sleep(sleepTime);
+            } catch (InterruptedException e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    private void clearDynamicShortcuts() {
+        getManager().removeAllDynamicShortcuts();
+        assertEquals(0, getManager().getDynamicShortcuts().size());
+    }
+
+    /**
+     * Run the given test, except for making it's okay to get an AssertionError, when the test took
+     * longer and the reset has happened.
+     */
+    private void runButOkayIfItTakesLonger(Runnable r) {
+        final long nextResetTime = getManager().getRateLimitResetTime();
+
+        try {
+            r.run();
+        } catch (AssertionError e) {
+            if (System.currentTimeMillis() < nextResetTime) {
+                throw e;
+            }
+        }
+    }
+
+    private void checkThrottled(BooleanSupplier apiCall, Runnable nonThrottledAssert,
+            Runnable throttledAssert) {
+        resetThrottling();
+
+        runButOkayIfItTakesLonger(() -> {
+            // Can call 5 times successfully.
+            assertTrue(apiCall.getAsBoolean());
+            nonThrottledAssert.run();
+            assertEquals(4, getManager().getRemainingCallCount());
+
+            assertTrue(apiCall.getAsBoolean());
+            nonThrottledAssert.run();
+            assertEquals(3, getManager().getRemainingCallCount());
+
+            assertTrue(apiCall.getAsBoolean());
+            nonThrottledAssert.run();
+            assertEquals(2, getManager().getRemainingCallCount());
+
+            assertTrue(apiCall.getAsBoolean());
+            nonThrottledAssert.run();
+            assertEquals(1, getManager().getRemainingCallCount());
+
+            assertTrue(apiCall.getAsBoolean());
+            nonThrottledAssert.run();
+            assertEquals(0, getManager().getRemainingCallCount());
+
+            // Now throttled.
+            assertFalse(apiCall.getAsBoolean());
+            throttledAssert.run();
+            assertEquals(0, getManager().getRemainingCallCount());
+
+            // Still throttled.
+            assertFalse(apiCall.getAsBoolean());
+            throttledAssert.run();
+
+            assertEquals(0, getManager().getRemainingCallCount());
+        });
+
+        // However, it shouldn't affect other packages.
+        runWithCaller(mPackageContext3, () -> {
+            assertEquals(5, getManager().getRemainingCallCount());
+        });
+
+        // Wait until reset, then retry.
+        waitUntilReset();
+        assertEquals(5, getManager().getRemainingCallCount());
+
+        runButOkayIfItTakesLonger(() -> {
+
+            assertTrue(apiCall.getAsBoolean());
+            nonThrottledAssert.run();
+            assertEquals(4, getManager().getRemainingCallCount());
+        });
+    }
+
+    @LargeTest
+    public void testThrottled_setDynamicShortcuts() {
+        runWithCaller(mPackageContext1, () -> {
+            checkThrottled(
+                    () -> {
+                        clearDynamicShortcuts();
+                        return getManager().setDynamicShortcuts(list(makeShortcut("s1")));
+                    }, () -> { // Non-throttled assert.
+                        assertEquals(1, getManager().getDynamicShortcuts().size());
+                    }, () -> { // Throttled assert.
+                        assertEquals(0, getManager().getDynamicShortcuts().size());
+                    });
+        });
+    }
+
+    private void checkNotThrottled(Runnable apiCall) {
+        resetThrottling();
+
+        // Can call more than 5 times.
+        apiCall.run();
+        assertEquals(5, getManager().getRemainingCallCount());
+
+        apiCall.run();
+        assertEquals(5, getManager().getRemainingCallCount());
+
+        apiCall.run();
+        assertEquals(5, getManager().getRemainingCallCount());
+
+        apiCall.run();
+        assertEquals(5, getManager().getRemainingCallCount());
+
+        apiCall.run();
+        assertEquals(5, getManager().getRemainingCallCount());
+
+        apiCall.run();
+        assertEquals(5, getManager().getRemainingCallCount());
+
+        apiCall.run();
+        assertEquals(5, getManager().getRemainingCallCount());
+    }
+
+    public void testNotThrottled_delete() {
+        runWithCaller(mPackageContext1, () -> {
+            checkNotThrottled(() -> getManager().removeAllDynamicShortcuts());
+
+            checkNotThrottled(() -> getManager().removeDynamicShortcuts(list("s1")));
+        });
+    }
+
+    public void testNotThrottled_getShortcuts() {
+        // Preparation: Create some shortcuts, and pin some.
+        runWithCaller(mPackageContext1, () -> {
+            getManager().setDynamicShortcuts(list(makeShortcut("s1"), makeShortcut("s2")));
+        });
+
+        setDefaultLauncher(getInstrumentation(), mLauncherContext2);
+        runWithCaller(mLauncherContext2, () -> {
+            getLauncherApps().pinShortcuts(
+                    mPackageContext1.getPackageName(), list("s2"), getUserHandle());
+        });
+
+        // Then check.
+        runWithCaller(mPackageContext1, () -> {
+            resetThrottling();
+            checkNotThrottled(() ->
+                assertShortcutIds(getManager().getDynamicShortcuts(), "s1", "s2"));
+
+            checkNotThrottled(() ->
+                assertShortcutIds(getManager().getPinnedShortcuts(), "s2"));
+        });
+    }
+
+    public void testNotThrottled_misc() {
+        runWithCaller(mPackageContext1, () -> {
+            checkNotThrottled(() -> getManager().getIconMaxDimensions());
+
+            checkNotThrottled(() -> getManager().getRateLimitResetTime());
+
+            checkNotThrottled(() ->
+                    assertEquals(10, getManager().getMaxDynamicShortcutCount()));
+        });
+    }
+}
diff --git a/tests/tests/simpleperf/Android.mk b/tests/tests/simpleperf/Android.mk
new file mode 100644
index 0000000..040e153
--- /dev/null
+++ b/tests/tests/simpleperf/Android.mk
@@ -0,0 +1,75 @@
+LOCAL_PATH := $(call my-dir)
+
+test_executable := CtsSimpleperfTestCases
+list_executable := $(test_executable)_list
+simpleperf_src_path := system/extras/simpleperf
+
+LLVM_ROOT_PATH := external/llvm
+include $(LLVM_ROOT_PATH)/llvm.mk
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := $(test_executable)
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA)/nativetest
+LOCAL_MULTILIB := both
+LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
+LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
+
+LOCAL_SHARED_LIBRARIES += \
+  libbacktrace \
+  libunwind \
+  libbase \
+  liblog \
+  libutils \
+  libLLVM \
+
+LOCAL_WHOLE_STATIC_LIBRARIES = \
+  libsimpleperf_cts_test \
+
+LOCAL_STATIC_LIBRARIES += \
+  libgtest \
+  libbacktrace_offline \
+  libziparchive \
+  libz \
+  liblzma \
+
+LOCAL_POST_LINK_CMD =  \
+  TMP_FILE=`mktemp $(OUT_DIR)/simpleperf-post-link-XXXXXXXXXX` && \
+  (cd $(simpleperf_src_path)/testdata && zip - -0 -r .) > $$TMP_FILE && \
+  $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_OBJCOPY) --add-section .testzipdata=$$TMP_FILE $(linked_module) && \
+  rm -f $$TMP_FILE
+
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_CTS_TEST_PACKAGE := android.simpleperf
+include $(BUILD_CTS_EXECUTABLE)
+
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := $(list_executable)
+LOCAL_MODULE_HOST_OS := linux
+LOCAL_MULTILIB := first
+LOCAL_LDLIBS = -lrt
+
+LOCAL_WHOLE_STATIC_LIBRARIES += \
+  libsimpleperf_cts_test \
+
+LOCAL_STATIC_LIBRARIES += \
+  libbacktrace_offline \
+  libbacktrace \
+  libunwind \
+  libziparchive-host \
+  libz \
+  liblzma \
+  libbase \
+  liblog \
+  libcutils \
+  libutils \
+  libLLVMObject \
+  libLLVMBitReader \
+  libLLVMMC \
+  libLLVMMCParser \
+  libLLVMCore \
+  libLLVMSupport \
+
+include $(LLVM_HOST_BUILD_MK)
+include $(BUILD_HOST_NATIVE_TEST)
diff --git a/tests/tests/simpleperf/AndroidTest.xml b/tests/tests/simpleperf/AndroidTest.xml
new file mode 100644
index 0000000..dc8246d
--- /dev/null
+++ b/tests/tests/simpleperf/AndroidTest.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS Simpleperf test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
+        <option name="cleanup" value="true" />
+        <option name="push" value="CtsSimpleperfTestCases->/data/local/tmp/CtsSimpleperfTestCases" />
+        <option name="append-bitness" value="true" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="CtsSimpleperfTestCases" />
+        <option name="runtime-hint" value="1m10s" />
+    </test>
+</configuration>
diff --git a/tests/tests/speech/Android.mk b/tests/tests/speech/Android.mk
index 3ab78b8..3d95053 100755
--- a/tests/tests/speech/Android.mk
+++ b/tests/tests/speech/Android.mk
@@ -25,6 +25,9 @@
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_PACKAGE_NAME := CtsSpeechTestCases
 
 # Needed for testing M API
diff --git a/tests/tests/speech/AndroidManifest.xml b/tests/tests/speech/AndroidManifest.xml
index 2e7f0b6..cd5d46c 100755
--- a/tests/tests/speech/AndroidManifest.xml
+++ b/tests/tests/speech/AndroidManifest.xml
@@ -16,7 +16,7 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.speech">
+    package="android.speech.tts.cts">
 
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <application>
@@ -34,7 +34,7 @@
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.cts.speech"
+                     android:targetPackage="android.speech.tts.cts"
                      android:label="CTS tests of android.speech">
         <meta-data android:name="listener"
             android:value="com.android.cts.runner.CtsTestRunListener" />
diff --git a/tests/tests/speech/AndroidTest.xml b/tests/tests/speech/AndroidTest.xml
new file mode 100644
index 0000000..08df58e
--- /dev/null
+++ b/tests/tests/speech/AndroidTest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS Speech test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsSpeechTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.speech.tts.cts" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/tests/speech/src/android/speech/tts/cts/TextToSpeechServiceTest.java b/tests/tests/speech/src/android/speech/tts/cts/TextToSpeechServiceTest.java
index 7425ecf..e205cc4 100644
--- a/tests/tests/speech/src/android/speech/tts/cts/TextToSpeechServiceTest.java
+++ b/tests/tests/speech/src/android/speech/tts/cts/TextToSpeechServiceTest.java
@@ -27,8 +27,6 @@
  * Tests for {@link android.speech.tts.TextToSpeechService} using StubTextToSpeechService.
  */
 public class TextToSpeechServiceTest extends AndroidTestCase {
-
-    private static final String UTTERANCE_ID = "utterance";
     private static final String UTTERANCE = "text to speech cts test";
     private static final String SAMPLE_FILE_NAME = "mytts.wav";
 
@@ -57,22 +55,24 @@
         try {
             assertFalse(sampleFile.exists());
 
-            int result = getTts().synthesizeToFile(UTTERANCE, createParams(), sampleFile.getPath());
+            int result = getTts().synthesizeToFile(UTTERANCE, createParams("tofile"), sampleFile.getPath());
             assertEquals("synthesizeToFile() failed", TextToSpeech.SUCCESS, result);
 
-            assertTrue("synthesizeToFile() completion timeout", mTts.waitForComplete(UTTERANCE_ID));
+            assertTrue("synthesizeToFile() completion timeout", mTts.waitForComplete("tofile"));
             assertTrue("synthesizeToFile() didn't produce a file", sampleFile.exists());
             assertTrue("synthesizeToFile() produced a non-sound file",
                     TextToSpeechWrapper.isSoundFile(sampleFile.getPath()));
         } finally {
             sampleFile.delete();
         }
+        mTts.verify("tofile");
     }
 
     public void testSpeak() throws Exception {
-        int result = getTts().speak(UTTERANCE, TextToSpeech.QUEUE_FLUSH, createParams());
+        int result = getTts().speak(UTTERANCE, TextToSpeech.QUEUE_FLUSH, createParams("speak"));
         assertEquals("speak() failed", TextToSpeech.SUCCESS, result);
-        assertTrue("speak() completion timeout", waitForUtterance());
+        assertTrue("speak() completion timeout", waitForUtterance("speak"));
+        mTts.verify("speak");
     }
 
     public void testSpeakStop() throws Exception {
@@ -83,7 +83,7 @@
         final int iterations = 20;
         for (int i = 0; i < iterations; i++) {
             int result = getTts().speak(UTTERANCE, TextToSpeech.QUEUE_ADD, null,
-                    UTTERANCE_ID + Integer.toString(i));
+                    "stop_" + Integer.toString(i));
             assertEquals("speak() failed", TextToSpeech.SUCCESS, result);
         }
         getTts().stop();
@@ -95,7 +95,7 @@
 
         for (int i = 0; i < iterations; i++) {
             assertTrue("speak() stop callback timeout", mTts.waitForStop(
-                    UTTERANCE_ID + Integer.toString(i)));
+                    "stop_" + Integer.toString(i)));
         }
     }
 
@@ -113,14 +113,14 @@
         }
     }
 
-    private HashMap<String, String> createParams() {
-        HashMap<String, String> params = new HashMap<String,String>();
-        params.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, UTTERANCE_ID);
+    private HashMap<String, String> createParams(String utteranceId) {
+        HashMap<String, String> params = new HashMap<>();
+        params.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, utteranceId);
         return params;
     }
 
-    private boolean waitForUtterance() throws InterruptedException {
-        return mTts.waitForComplete(UTTERANCE_ID);
+    private boolean waitForUtterance(String utteranceId) throws InterruptedException {
+        return mTts.waitForComplete(utteranceId);
     }
 
 }
diff --git a/tests/tests/speech/src/android/speech/tts/cts/TextToSpeechTest.java b/tests/tests/speech/src/android/speech/tts/cts/TextToSpeechTest.java
index 013a5ea..43b0fe3 100644
--- a/tests/tests/speech/src/android/speech/tts/cts/TextToSpeechTest.java
+++ b/tests/tests/speech/src/android/speech/tts/cts/TextToSpeechTest.java
@@ -29,8 +29,6 @@
  * Tests for {@link android.speech.tts.TextToSpeech}
  */
 public class TextToSpeechTest extends AndroidTestCase {
-
-    private static final String UTTERANCE_ID = "utterance";
     private static final String SAMPLE_TEXT = "This is a sample text to speech string";
     private static final String SAMPLE_FILE_NAME = "mytts.wav";
 
@@ -103,14 +101,14 @@
         fail("Engine " + engine + " not found");
     }
 
-    private HashMap<String, String> createParams() {
-        HashMap<String, String> params = new HashMap<String,String>();
-        params.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, UTTERANCE_ID);
+    private HashMap<String, String> createParams(String utteranceId) {
+        HashMap<String, String> params = new HashMap<>();
+        params.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, utteranceId);
         return params;
     }
 
-    private boolean waitForUtterance() throws InterruptedException {
-        return mTts.waitForComplete(UTTERANCE_ID);
+    private boolean waitForUtterance(String utteranceId) throws InterruptedException {
+        return mTts.waitForComplete(utteranceId);
     }
 
     public void testSynthesizeToFile() throws Exception {
@@ -121,26 +119,28 @@
         try {
             assertFalse(sampleFile.exists());
 
-            int result = getTts().synthesizeToFile(SAMPLE_TEXT, createParams(),
+            int result = getTts().synthesizeToFile(SAMPLE_TEXT, createParams("tofile"),
                     sampleFile.getPath());
             assertEquals("synthesizeToFile() failed", TextToSpeech.SUCCESS, result);
 
-            assertTrue("synthesizeToFile() completion timeout", waitForUtterance());
+            assertTrue("synthesizeToFile() completion timeout", waitForUtterance("tofile"));
             assertTrue("synthesizeToFile() didn't produce a file", sampleFile.exists());
             assertTrue("synthesizeToFile() produced a non-sound file",
                     TextToSpeechWrapper.isSoundFile(sampleFile.getPath()));
         } finally {
             sampleFile.delete();
         }
+        mTts.verify("tofile");
     }
 
     public void testSpeak() throws Exception {
         if (mTts == null) {
             return;
         }
-        int result = getTts().speak(SAMPLE_TEXT, TextToSpeech.QUEUE_FLUSH, createParams());
+        int result = getTts().speak(SAMPLE_TEXT, TextToSpeech.QUEUE_FLUSH, createParams("speak"));
         assertEquals("speak() failed", TextToSpeech.SUCCESS, result);
-        assertTrue("speak() completion timeout", waitForUtterance());
+        assertTrue("speak() completion timeout", waitForUtterance("speak"));
+        mTts.verify("speak");
     }
 
     public void testSpeakStop() throws Exception {
@@ -148,13 +148,13 @@
         final int iterations = 20;
         for (int i = 0; i < iterations; i++) {
             int result = getTts().speak(SAMPLE_TEXT, TextToSpeech.QUEUE_ADD, null,
-                    UTTERANCE_ID + Integer.toString(i));
+                    "stop_" + Integer.toString(i));
             assertEquals("speak() failed", TextToSpeech.SUCCESS, result);
         }
         getTts().stop();
         for (int i = 0; i < iterations; i++) {
             assertTrue("speak() stop callback timeout", mTts.waitForStop(
-                    UTTERANCE_ID + Integer.toString(i)));
+                    "stop_" + Integer.toString(i)));
         }
     }
 
diff --git a/tests/tests/speech/src/android/speech/tts/cts/TextToSpeechWrapper.java b/tests/tests/speech/src/android/speech/tts/cts/TextToSpeechWrapper.java
index 9d460e2..a24fdc2 100644
--- a/tests/tests/speech/src/android/speech/tts/cts/TextToSpeechWrapper.java
+++ b/tests/tests/speech/src/android/speech/tts/cts/TextToSpeechWrapper.java
@@ -24,10 +24,13 @@
 
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.locks.Condition;
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReentrantLock;
+import org.junit.Assert;
 
 /**
  * Wrapper for {@link TextToSpeech} with some handy test functionality.
@@ -35,7 +38,7 @@
 public class TextToSpeechWrapper {
     private static final String LOG_TAG = "TextToSpeechServiceTest";
 
-    public static final String MOCK_TTS_ENGINE = "com.android.cts.speech";
+    public static final String MOCK_TTS_ENGINE = "android.speech.tts.cts";
 
     private final Context mContext;
     private TextToSpeech mTts;
@@ -86,6 +89,16 @@
         mTts.shutdown();
     }
 
+    /**
+     * Sanity checks that the utteranceIds and only the utteranceIds completed and produced the
+     * correct callbacks.
+     * Can only be used when the test knows exactly which utterances should have been finished when
+     * this call is made. Else use waitForStop(String) or waitForComplete(String).
+     */
+    public void verify(String... utteranceIds) {
+        mUtteranceListener.verify(utteranceIds);
+    }
+
     public static TextToSpeechWrapper createTextToSpeechWrapper(Context context)
             throws InterruptedException {
         TextToSpeechWrapper wrapper = new TextToSpeechWrapper(context);
@@ -147,15 +160,21 @@
     private static class UtteranceWaitListener extends UtteranceProgressListener {
         private final Lock mLock = new ReentrantLock();
         private final Condition mDone  = mLock.newCondition();
-        private final HashSet<String> mStartedUtterances = new HashSet<String>();
-        private final HashSet<String> mStoppedUtterances = new HashSet<String>();
-        private final HashMap<String, Integer> mErredUtterances = new HashMap<String, Integer>();
-        private final HashSet<String> mCompletedUtterances = new HashSet<String>();
+        private final Set<String> mStartedUtterances = new HashSet<>();
+        // Contains the list of utterances that are stopped. Entry is removed after waitForStop().
+        private final Set<String> mStoppedUtterances = new HashSet<>();
+        private final Map<String, Integer> mErredUtterances = new HashMap<>();
+        // Contains the list of utterances that are completed. Entry is removed after
+        // waitForComplete().
+        private final Set<String> mCompletedUtterances = new HashSet<>();
+        private final Set<String> mBeginSynthesisUtterances = new HashSet<>();
+        private final Map<String, Integer> mChunksReceived = new HashMap<>();
 
         @Override
         public void onDone(String utteranceId) {
             mLock.lock();
             try {
+                Assert.assertTrue(mStartedUtterances.contains(utteranceId));
                 mCompletedUtterances.add(utteranceId);
                 mDone.signal();
             } finally {
@@ -189,6 +208,9 @@
         public void onStart(String utteranceId) {
             mLock.lock();
             try {
+                // TODO: Due to a bug in the framework onStart() is called twice for
+                //       synthesizeToFile requests. Once that is fixed we should assert here that we
+                //       expect only one onStart() per utteranceId.
                 mStartedUtterances.add(utteranceId);
             } finally {
                 mLock.unlock();
@@ -206,6 +228,40 @@
             }
         }
 
+        @Override
+        public void onBeginSynthesis(String utteranceId, int sampleRateInHz, int audioFormat, int channelCount) {
+            Assert.assertNotNull(utteranceId);
+            Assert.assertTrue(sampleRateInHz > 0);
+            Assert.assertTrue(audioFormat == android.media.AudioFormat.ENCODING_PCM_8BIT
+                              || audioFormat == android.media.AudioFormat.ENCODING_PCM_16BIT
+                              || audioFormat == android.media.AudioFormat.ENCODING_PCM_FLOAT);
+            Assert.assertTrue(channelCount >= 1);
+            Assert.assertTrue(channelCount <= 2);
+            mLock.lock();
+            try {
+                mBeginSynthesisUtterances.add(utteranceId);
+            } finally {
+                mLock.unlock();
+            }
+        }
+
+        @Override
+        public void onAudioAvailable(String utteranceId, byte[] audio) {
+            Assert.assertNotNull(utteranceId);
+            Assert.assertTrue(audio.length > 0);
+            mLock.lock();
+            try {
+                Assert.assertTrue(mBeginSynthesisUtterances.contains(utteranceId));
+                if (mChunksReceived.get(utteranceId) != null) {
+                    mChunksReceived.put(utteranceId, mChunksReceived.get(utteranceId) + 1);
+                } else {
+                    mChunksReceived.put(utteranceId, 1);
+                }
+            } finally {
+                mLock.unlock();
+            }
+        }
+
         public boolean waitForComplete(String utteranceId)
                 throws InterruptedException {
             long timeOutNanos = TimeUnit.MILLISECONDS.toNanos(TTS_INIT_MAX_WAIT_TIME);
@@ -239,6 +295,16 @@
                 mLock.unlock();
             }
         }
+
+        public void verify(String... utteranceIds) {
+            Assert.assertTrue(utteranceIds.length == mStartedUtterances.size());
+            for (String id : utteranceIds) {
+                Assert.assertTrue(mStartedUtterances.contains(id));
+                Assert.assertTrue(mBeginSynthesisUtterances.contains(id));
+                Assert.assertTrue(mChunksReceived.containsKey(id));
+                Assert.assertTrue(mChunksReceived.get(id) > 0);
+            }
+        }
     }
 
     /**
diff --git a/tests/tests/systemui/Android.mk b/tests/tests/systemui/Android.mk
index 1a15fd2..536d2a8 100644
--- a/tests/tests/systemui/Android.mk
+++ b/tests/tests/systemui/Android.mk
@@ -19,6 +19,11 @@
 # don't include this package in any target
 LOCAL_MODULE_TAGS := optional
 
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_JAVA_LIBRARIES := android.test.runner
 
 LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
diff --git a/tests/tests/systemui/AndroidManifest.xml b/tests/tests/systemui/AndroidManifest.xml
index bf5df5b..2cdb36f 100644
--- a/tests/tests/systemui/AndroidManifest.xml
+++ b/tests/tests/systemui/AndroidManifest.xml
@@ -16,7 +16,7 @@
   -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.systemui">
+    package="android.systemui.cts">
     <uses-permission android:name="android.permission.INJECT_EVENTS" />
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
@@ -27,7 +27,7 @@
     </application>
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.cts.systemui">
+                     android:targetPackage="android.systemui.cts">
     </instrumentation>
 
 </manifest>
diff --git a/tests/tests/systemui/AndroidTest.xml b/tests/tests/systemui/AndroidTest.xml
new file mode 100644
index 0000000..61bdae3
--- /dev/null
+++ b/tests/tests/systemui/AndroidTest.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS SystemUI test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsSystemUiTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.systemui.cts" />
+        <option name="runtime-hint" value="10m19s" />
+    </test>
+</configuration>
diff --git a/tests/tests/systemui/src/android/systemui/cts/ColorUtils.java b/tests/tests/systemui/src/android/systemui/cts/ColorUtils.java
new file mode 100644
index 0000000..a26b2ad
--- /dev/null
+++ b/tests/tests/systemui/src/android/systemui/cts/ColorUtils.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.systemui.cts;
+
+/**
+ * Copies of non-public {@link android.graphics.Color} APIs
+ */
+public class ColorUtils {
+
+    public static float brightness(int argb) {
+        int r = (argb >> 16) & 0xFF;
+        int g = (argb >> 8) & 0xFF;
+        int b = argb & 0xFF;
+
+        int V = Math.max(b, Math.max(r, g));
+
+        return (V / 255.f);
+    }
+
+    public static float hue(int argb) {
+        int r = (argb >> 16) & 0xFF;
+        int g = (argb >> 8) & 0xFF;
+        int b = argb & 0xFF;
+
+        int V = Math.max(b, Math.max(r, g));
+        int temp = Math.min(b, Math.min(r, g));
+
+        float H;
+
+        if (V == temp) {
+            H = 0;
+        } else {
+            final float vtemp = (float) (V - temp);
+            final float cr = (V - r) / vtemp;
+            final float cg = (V - g) / vtemp;
+            final float cb = (V - b) / vtemp;
+
+            if (r == V) {
+                H = cb - cg;
+            } else if (g == V) {
+                H = 2 + cr - cb;
+            } else {
+                H = 4 + cg - cr;
+            }
+
+            H /= 6.f;
+            if (H < 0) {
+                H++;
+            }
+        }
+
+        return H;
+    }
+}
diff --git a/tests/tests/systemui/src/android/systemui/cts/LightStatusBarActivity.java b/tests/tests/systemui/src/android/systemui/cts/LightStatusBarActivity.java
new file mode 100644
index 0000000..b33cc77
--- /dev/null
+++ b/tests/tests/systemui/src/android/systemui/cts/LightStatusBarActivity.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.systemui.cts;
+
+import android.app.Activity;
+import android.graphics.Color;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup.LayoutParams;
+
+
+/**
+ * An activity that exercises SYSTEM_UI_FLAG_LIGHT_STATUS_BAR.
+ */
+public class LightStatusBarActivity extends Activity {
+
+    private View mContent;
+
+    public void onCreate(Bundle bundle){
+        super.onCreate(bundle);
+
+        mContent = new View(this);
+        mContent.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
+                LayoutParams.MATCH_PARENT));
+        setContentView(mContent);
+    }
+
+    public void setLightStatusBar(boolean lightStatusBar) {
+        int vis = getWindow().getDecorView().getSystemUiVisibility();
+        if (lightStatusBar) {
+            vis |= View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
+        } else {
+            vis &= ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
+        }
+        getWindow().getDecorView().setSystemUiVisibility(vis);
+    }
+
+    public int getTop() {
+        return mContent.getLocationOnScreen()[1];
+    }
+
+    public int getWidth() {
+        return mContent.getWidth();
+    }
+}
diff --git a/tests/tests/systemui/src/android/systemui/cts/LightStatusBarTests.java b/tests/tests/systemui/src/android/systemui/cts/LightStatusBarTests.java
new file mode 100644
index 0000000..879eac5
--- /dev/null
+++ b/tests/tests/systemui/src/android/systemui/cts/LightStatusBarTests.java
@@ -0,0 +1,235 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.systemui.cts;
+
+import android.app.ActivityManager;
+import android.content.pm.PackageManager;
+import android.graphics.Bitmap;
+import android.graphics.Color;
+import android.support.test.InstrumentationRegistry;
+import android.test.ActivityInstrumentationTestCase2;
+import android.util.Log;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+/**
+ * Test for light status bar.
+ */
+public class LightStatusBarTests extends ActivityInstrumentationTestCase2<LightStatusBarActivity> {
+
+    public static final String TAG = "LightStatusBarTests";
+
+    public static final String DUMP_PATH = "/sdcard/lightstatustest.png";
+
+    public LightStatusBarTests() {
+        super(LightStatusBarActivity.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        // As the way to access Instrumentation is changed in the new runner, we need to inject it
+        // manually into ActivityInstrumentationTestCase2. ActivityInstrumentationTestCase2 will
+        // be marked as deprecated and replaced with ActivityTestRule.
+        injectInstrumentation(InstrumentationRegistry.getInstrumentation());
+    }
+
+    public void testLightStatusBarIcons() throws Throwable {
+        PackageManager pm = getInstrumentation().getContext().getPackageManager();
+        if (pm.hasSystemFeature(PackageManager.FEATURE_WATCH)
+                || pm.hasSystemFeature(PackageManager.FEATURE_TELEVISION)
+                || pm.hasSystemFeature(PackageManager.FEATURE_LEANBACK)) {
+            // No status bar on TVs and watches.
+            return;
+        }
+
+        if (!ActivityManager.isHighEndGfx()) {
+            // non-highEndGfx devices don't do colored system bars.
+            return;
+        }
+
+        requestLightStatusBar(Color.RED /* background */);
+        Thread.sleep(1000);
+
+        Bitmap bitmap = takeStatusBarScreenshot();
+        Stats s = evaluateLightStatusBarBitmap(bitmap, Color.RED /* background */);
+        boolean success = false;
+
+        try {
+            assertMoreThan("Not enough background pixels", 0.3f,
+                    (float) s.backgroundPixels / s.totalPixels(),
+                    "Is the status bar background showing correctly (solid red)?");
+
+            assertMoreThan("Not enough pixels colored as in the spec", 0.1f,
+                    (float) s.iconPixels / s.foregroundPixels(),
+                    "Are the status bar icons colored according to the spec "
+                            + "(60% black and 24% black)?");
+
+            assertLessThan("Too many lighter pixels lighter than the background", 0.05f,
+                    (float) s.sameHueLightPixels / s.foregroundPixels(),
+                    "Are the status bar icons dark?");
+
+            assertLessThan("Too many pixels with a changed hue", 0.05f,
+                    (float) s.unexpectedHuePixels / s.foregroundPixels(),
+                    "Are the status bar icons color-free?");
+
+            success = true;
+        } finally {
+            if (!success) {
+                Log.e(TAG, "Dumping failed bitmap to " + DUMP_PATH);
+                dumpBitmap(bitmap);
+            }
+        }
+    }
+
+    private void assertMoreThan(String what, float expected, float actual, String hint) {
+        if (!(actual > expected)) {
+            fail(what + ": expected more than " + expected * 100 + "%, but only got " + actual * 100
+                    + "%; " + hint);
+        }
+    }
+
+    private void assertLessThan(String what, float expected, float actual, String hint) {
+        if (!(actual < expected)) {
+            fail(what + ": expected less than " + expected * 100 + "%, but got " + actual * 100
+                    + "%; " + hint);
+        }
+    }
+
+    private void requestLightStatusBar(final int background) throws Throwable {
+        final LightStatusBarActivity activity = getActivity();
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                activity.getWindow().setStatusBarColor(background);
+                activity.setLightStatusBar(true);
+            }
+        });
+    }
+
+    private static class Stats {
+        int backgroundPixels;
+        int iconPixels;
+        int sameHueDarkPixels;
+        int sameHueLightPixels;
+        int unexpectedHuePixels;
+
+        int totalPixels() {
+            return backgroundPixels + iconPixels + sameHueDarkPixels
+                    + sameHueLightPixels + unexpectedHuePixels;
+        }
+
+        int foregroundPixels() {
+            return iconPixels + sameHueDarkPixels
+                    + sameHueLightPixels + unexpectedHuePixels;
+        }
+
+        @Override
+        public String toString() {
+            return String.format("{bg=%d, ic=%d, dark=%d, light=%d, bad=%d}",
+                    backgroundPixels, iconPixels, sameHueDarkPixels, sameHueLightPixels,
+                    unexpectedHuePixels);
+        }
+    }
+
+    private Stats evaluateLightStatusBarBitmap(Bitmap bitmap, int background) {
+        int iconColor = 0x99000000;
+        int iconPartialColor = 0x3d000000;
+
+        int mixedIconColor = mixSrcOver(background, iconColor);
+        int mixedIconPartialColor = mixSrcOver(background, iconPartialColor);
+
+        int[] pixels = new int[bitmap.getHeight() * bitmap.getWidth()];
+        bitmap.getPixels(pixels, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight());
+
+        Stats s = new Stats();
+        float eps = 0.005f;
+
+        for (int c : pixels) {
+            if (c == background) {
+                s.backgroundPixels++;
+                continue;
+            }
+
+            // What we expect the icons to be colored according to the spec.
+            if (c == mixedIconColor || c == mixedIconPartialColor) {
+                s.iconPixels++;
+                continue;
+            }
+
+            // Due to anti-aliasing, there will be deviations from the ideal icon color, but it
+            // should still be mostly the same hue.
+            float hueDiff = Math.abs(ColorUtils.hue(background) - ColorUtils.hue(c));
+            if (hueDiff < eps || hueDiff > 1 - eps) {
+                // .. it shouldn't be lighter than the original background though.
+                if (ColorUtils.brightness(c) > ColorUtils.brightness(background)) {
+                    s.sameHueLightPixels++;
+                } else {
+                    s.sameHueDarkPixels++;
+                }
+                continue;
+            }
+
+            s.unexpectedHuePixels++;
+        }
+
+        return s;
+    }
+
+    private void dumpBitmap(Bitmap bitmap) {
+        FileOutputStream fileStream = null;
+        try {
+            fileStream = new FileOutputStream(DUMP_PATH);
+            bitmap.compress(Bitmap.CompressFormat.PNG, 85, fileStream);
+            fileStream.flush();
+        } catch (Exception e) {
+            Log.e(TAG, "Dumping bitmap failed.", e);
+        } finally {
+            if (fileStream != null) {
+                try {
+                    fileStream.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+
+    private int mixSrcOver(int background, int foreground) {
+        int bgAlpha = Color.alpha(background);
+        int bgRed = Color.red(background);
+        int bgGreen = Color.green(background);
+        int bgBlue = Color.blue(background);
+
+        int fgAlpha = Color.alpha(foreground);
+        int fgRed = Color.red(foreground);
+        int fgGreen = Color.green(foreground);
+        int fgBlue = Color.blue(foreground);
+
+        return Color.argb(fgAlpha + (255 - fgAlpha) * bgAlpha / 255,
+                    fgRed + (255 - fgAlpha) * bgRed / 255,
+                    fgGreen + (255 - fgAlpha) * bgGreen / 255,
+                    fgBlue + (255 - fgAlpha) * bgBlue / 255);
+    }
+
+    private Bitmap takeStatusBarScreenshot() {
+        Bitmap fullBitmap = getInstrumentation().getUiAutomation().takeScreenshot();
+        return Bitmap.createBitmap(fullBitmap, 0, 0,
+                getActivity().getWidth(), getActivity().getTop());
+    }
+}
diff --git a/tests/tests/systemui/src/com/android/cts/systemui/ColorUtils.java b/tests/tests/systemui/src/com/android/cts/systemui/ColorUtils.java
deleted file mode 100644
index 626a179..0000000
--- a/tests/tests/systemui/src/com/android/cts/systemui/ColorUtils.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.cts.systemui;
-
-/**
- * Copies of non-public {@link android.graphics.Color} APIs
- */
-public class ColorUtils {
-
-    public static float brightness(int argb) {
-        int r = (argb >> 16) & 0xFF;
-        int g = (argb >> 8) & 0xFF;
-        int b = argb & 0xFF;
-
-        int V = Math.max(b, Math.max(r, g));
-
-        return (V / 255.f);
-    }
-
-    public static float hue(int argb) {
-        int r = (argb >> 16) & 0xFF;
-        int g = (argb >> 8) & 0xFF;
-        int b = argb & 0xFF;
-
-        int V = Math.max(b, Math.max(r, g));
-        int temp = Math.min(b, Math.min(r, g));
-
-        float H;
-
-        if (V == temp) {
-            H = 0;
-        } else {
-            final float vtemp = (float) (V - temp);
-            final float cr = (V - r) / vtemp;
-            final float cg = (V - g) / vtemp;
-            final float cb = (V - b) / vtemp;
-
-            if (r == V) {
-                H = cb - cg;
-            } else if (g == V) {
-                H = 2 + cr - cb;
-            } else {
-                H = 4 + cg - cr;
-            }
-
-            H /= 6.f;
-            if (H < 0) {
-                H++;
-            }
-        }
-
-        return H;
-    }
-}
diff --git a/tests/tests/systemui/src/com/android/cts/systemui/LightStatusBarActivity.java b/tests/tests/systemui/src/com/android/cts/systemui/LightStatusBarActivity.java
deleted file mode 100644
index 3722320..0000000
--- a/tests/tests/systemui/src/com/android/cts/systemui/LightStatusBarActivity.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-package com.android.cts.systemui;
-
-import android.app.Activity;
-import android.graphics.Color;
-import android.os.Bundle;
-import android.view.View;
-import android.view.ViewGroup.LayoutParams;
-
-
-/**
- * An activity that exercises SYSTEM_UI_FLAG_LIGHT_STATUS_BAR.
- */
-public class LightStatusBarActivity extends Activity {
-
-    private View mContent;
-
-    public void onCreate(Bundle bundle){
-        super.onCreate(bundle);
-
-        mContent = new View(this);
-        mContent.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
-                LayoutParams.MATCH_PARENT));
-        setContentView(mContent);
-    }
-
-    public void setLightStatusBar(boolean lightStatusBar) {
-        int vis = getWindow().getDecorView().getSystemUiVisibility();
-        if (lightStatusBar) {
-            vis |= View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
-        } else {
-            vis &= ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
-        }
-        getWindow().getDecorView().setSystemUiVisibility(vis);
-    }
-
-    public int getTop() {
-        return mContent.getLocationOnScreen()[1];
-    }
-
-    public int getWidth() {
-        return mContent.getWidth();
-    }
-}
diff --git a/tests/tests/systemui/src/com/android/cts/systemui/LightStatusBarTests.java b/tests/tests/systemui/src/com/android/cts/systemui/LightStatusBarTests.java
deleted file mode 100644
index b5bfd51..0000000
--- a/tests/tests/systemui/src/com/android/cts/systemui/LightStatusBarTests.java
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.cts.systemui;
-
-import android.app.ActivityManager;
-import android.content.pm.PackageManager;
-import android.graphics.Bitmap;
-import android.graphics.Color;
-import android.support.test.InstrumentationRegistry;
-import android.test.ActivityInstrumentationTestCase2;
-import android.util.Log;
-
-import java.io.FileOutputStream;
-import java.io.IOException;
-
-/**
- * Test for light status bar.
- */
-public class LightStatusBarTests extends ActivityInstrumentationTestCase2<LightStatusBarActivity> {
-
-    public static final String TAG = "LightStatusBarTests";
-
-    public static final String DUMP_PATH = "/sdcard/lightstatustest.png";
-
-    public LightStatusBarTests() {
-        super(LightStatusBarActivity.class);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        // As the way to access Instrumentation is changed in the new runner, we need to inject it
-        // manually into ActivityInstrumentationTestCase2. ActivityInstrumentationTestCase2 will
-        // be marked as deprecated and replaced with ActivityTestRule.
-        injectInstrumentation(InstrumentationRegistry.getInstrumentation());
-    }
-
-    public void testLightStatusBarIcons() throws Throwable {
-        PackageManager pm = getInstrumentation().getContext().getPackageManager();
-        if (pm.hasSystemFeature(PackageManager.FEATURE_WATCH)
-                || pm.hasSystemFeature(PackageManager.FEATURE_TELEVISION)
-                || pm.hasSystemFeature(PackageManager.FEATURE_LEANBACK)) {
-            // No status bar on TVs and watches.
-            return;
-        }
-
-        if (!ActivityManager.isHighEndGfx()) {
-            // non-highEndGfx devices don't do colored system bars.
-            return;
-        }
-
-        requestLightStatusBar(Color.RED /* background */);
-        Thread.sleep(1000);
-
-        Bitmap bitmap = takeStatusBarScreenshot();
-        Stats s = evaluateLightStatusBarBitmap(bitmap, Color.RED /* background */);
-        boolean success = false;
-
-        try {
-            assertMoreThan("Not enough background pixels", 0.3f,
-                    (float) s.backgroundPixels / s.totalPixels(),
-                    "Is the status bar background showing correctly (solid red)?");
-
-            assertMoreThan("Not enough pixels colored as in the spec", 0.1f,
-                    (float) s.iconPixels / s.foregroundPixels(),
-                    "Are the status bar icons colored according to the spec "
-                            + "(60% black and 24% black)?");
-
-            assertLessThan("Too many lighter pixels lighter than the background", 0.05f,
-                    (float) s.sameHueLightPixels / s.foregroundPixels(),
-                    "Are the status bar icons dark?");
-
-            assertLessThan("Too many pixels with a changed hue", 0.05f,
-                    (float) s.unexpectedHuePixels / s.foregroundPixels(),
-                    "Are the status bar icons color-free?");
-
-            success = true;
-        } finally {
-            if (!success) {
-                Log.e(TAG, "Dumping failed bitmap to " + DUMP_PATH);
-                dumpBitmap(bitmap);
-            }
-        }
-    }
-
-    private void assertMoreThan(String what, float expected, float actual, String hint) {
-        if (!(actual > expected)) {
-            fail(what + ": expected more than " + expected * 100 + "%, but only got " + actual * 100
-                    + "%; " + hint);
-        }
-    }
-
-    private void assertLessThan(String what, float expected, float actual, String hint) {
-        if (!(actual < expected)) {
-            fail(what + ": expected less than " + expected * 100 + "%, but got " + actual * 100
-                    + "%; " + hint);
-        }
-    }
-
-    private void requestLightStatusBar(final int background) throws Throwable {
-        final LightStatusBarActivity activity = getActivity();
-        runTestOnUiThread(new Runnable() {
-            @Override
-            public void run() {
-                activity.getWindow().setStatusBarColor(background);
-                activity.setLightStatusBar(true);
-            }
-        });
-    }
-
-    private static class Stats {
-        int backgroundPixels;
-        int iconPixels;
-        int sameHueDarkPixels;
-        int sameHueLightPixels;
-        int unexpectedHuePixels;
-
-        int totalPixels() {
-            return backgroundPixels + iconPixels + sameHueDarkPixels
-                    + sameHueLightPixels + unexpectedHuePixels;
-        }
-
-        int foregroundPixels() {
-            return iconPixels + sameHueDarkPixels
-                    + sameHueLightPixels + unexpectedHuePixels;
-        }
-
-        @Override
-        public String toString() {
-            return String.format("{bg=%d, ic=%d, dark=%d, light=%d, bad=%d}",
-                    backgroundPixels, iconPixels, sameHueDarkPixels, sameHueLightPixels,
-                    unexpectedHuePixels);
-        }
-    }
-
-    private Stats evaluateLightStatusBarBitmap(Bitmap bitmap, int background) {
-        int iconColor = 0x99000000;
-        int iconPartialColor = 0x3d000000;
-
-        int mixedIconColor = mixSrcOver(background, iconColor);
-        int mixedIconPartialColor = mixSrcOver(background, iconPartialColor);
-
-        int[] pixels = new int[bitmap.getHeight() * bitmap.getWidth()];
-        bitmap.getPixels(pixels, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight());
-
-        Stats s = new Stats();
-        float eps = 0.005f;
-
-        for (int c : pixels) {
-            if (c == background) {
-                s.backgroundPixels++;
-                continue;
-            }
-
-            // What we expect the icons to be colored according to the spec.
-            if (c == mixedIconColor || c == mixedIconPartialColor) {
-                s.iconPixels++;
-                continue;
-            }
-
-            // Due to anti-aliasing, there will be deviations from the ideal icon color, but it
-            // should still be mostly the same hue.
-            float hueDiff = Math.abs(ColorUtils.hue(background) - ColorUtils.hue(c));
-            if (hueDiff < eps || hueDiff > 1 - eps) {
-                // .. it shouldn't be lighter than the original background though.
-                if (ColorUtils.brightness(c) > ColorUtils.brightness(background)) {
-                    s.sameHueLightPixels++;
-                } else {
-                    s.sameHueDarkPixels++;
-                }
-                continue;
-            }
-
-            s.unexpectedHuePixels++;
-        }
-
-        return s;
-    }
-
-    private void dumpBitmap(Bitmap bitmap) {
-        FileOutputStream fileStream = null;
-        try {
-            fileStream = new FileOutputStream(DUMP_PATH);
-            bitmap.compress(Bitmap.CompressFormat.PNG, 85, fileStream);
-            fileStream.flush();
-        } catch (Exception e) {
-            Log.e(TAG, "Dumping bitmap failed.", e);
-        } finally {
-            if (fileStream != null) {
-                try {
-                    fileStream.close();
-                } catch (IOException e) {
-                    e.printStackTrace();
-                }
-            }
-        }
-    }
-
-    private int mixSrcOver(int background, int foreground) {
-        int bgAlpha = Color.alpha(background);
-        int bgRed = Color.red(background);
-        int bgGreen = Color.green(background);
-        int bgBlue = Color.blue(background);
-
-        int fgAlpha = Color.alpha(foreground);
-        int fgRed = Color.red(foreground);
-        int fgGreen = Color.green(foreground);
-        int fgBlue = Color.blue(foreground);
-
-        return Color.argb(fgAlpha + (255 - fgAlpha) * bgAlpha / 255,
-                    fgRed + (255 - fgAlpha) * bgRed / 255,
-                    fgGreen + (255 - fgAlpha) * bgGreen / 255,
-                    fgBlue + (255 - fgAlpha) * bgBlue / 255);
-    }
-
-    private Bitmap takeStatusBarScreenshot() {
-        Bitmap fullBitmap = getInstrumentation().getUiAutomation().takeScreenshot();
-        return Bitmap.createBitmap(fullBitmap, 0, 0,
-                getActivity().getWidth(), getActivity().getTop());
-    }
-}
diff --git a/tests/tests/telecom/Android.mk b/tests/tests/telecom/Android.mk
index 51d97f5..5a8922e 100644
--- a/tests/tests/telecom/Android.mk
+++ b/tests/tests/telecom/Android.mk
@@ -30,4 +30,7 @@
 
 LOCAL_SDK_VERSION := current
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/telecom/AndroidManifest.xml b/tests/tests/telecom/AndroidManifest.xml
index b57e0b6..46fdf09 100644
--- a/tests/tests/telecom/AndroidManifest.xml
+++ b/tests/tests/telecom/AndroidManifest.xml
@@ -15,7 +15,7 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.telecom">
+    package="android.telecom.cts">
     <uses-sdk android:minSdkVersion="21" />
     <uses-permission android:name="android.permission.CALL_PHONE" />>
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
@@ -45,8 +45,23 @@
             <intent-filter>
                 <action android:name="android.telecom.InCallService"/>
             </intent-filter>
+            <meta-data android:name="android.telecom.IN_CALL_SERVICE_UI" android:value="true" />
         </service>
 
+        <service android:name="android.telecom.cts.MockCallScreeningService"
+            android:permission="android.permission.BIND_SCREENING_SERVICE"
+            android:enabled="false" >
+            <intent-filter>
+                <action android:name="android.telecom.CallScreeningService"/>
+            </intent-filter>
+        </service>
+
+        <receiver android:name="android.telecom.cts.MockMissedCallNotificationReceiver">
+            <intent-filter>
+                <action android:name="android.telecom.action.SHOW_MISSED_CALLS_NOTIFICATION" />
+            </intent-filter>
+        </receiver>
+
         <activity android:name="android.telecom.cts.MockDialerActivity">
             <intent-filter>
                 <action android:name="android.intent.action.DIAL" />
@@ -81,7 +96,7 @@
     </application>
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.cts.telecom"
+                     android:targetPackage="android.telecom.cts"
                      android:label="CTS tests for android.telecom package">
         <meta-data android:name="listener"
             android:value="com.android.cts.runner.CtsTestRunListener" />
diff --git a/tests/tests/telecom/AndroidTest.xml b/tests/tests/telecom/AndroidTest.xml
new file mode 100644
index 0000000..7f34c0c
--- /dev/null
+++ b/tests/tests/telecom/AndroidTest.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Configuration for Telecom Tests">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.TokenRequirement">
+        <option name="token" value="sim-card" />
+    </target_preparer>
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsTelecomTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.telecom.cts" />
+        <option name="runtime-hint" value="10m20s" />
+    </test>
+</configuration>
diff --git a/tests/tests/telecom/src/android/telecom/cts/BaseTelecomTestWithMockServices.java b/tests/tests/telecom/src/android/telecom/cts/BaseTelecomTestWithMockServices.java
index d874dbf..add19d2 100644
--- a/tests/tests/telecom/src/android/telecom/cts/BaseTelecomTestWithMockServices.java
+++ b/tests/tests/telecom/src/android/telecom/cts/BaseTelecomTestWithMockServices.java
@@ -45,6 +45,7 @@
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Objects;
 import java.util.concurrent.TimeUnit;
 
 /**
@@ -81,6 +82,12 @@
     InvokeCounter mOnCallAudioStateChangedCounter;
     InvokeCounter mOnPostDialWaitCounter;
     InvokeCounter mOnCannedTextResponsesLoadedCounter;
+    InvokeCounter mOnSilenceRingerCounter;
+    InvokeCounter mOnConnectionEventCounter;
+    InvokeCounter mOnExtrasChangedCounter;
+    InvokeCounter mOnPropertiesChangedCounter;
+    Bundle mPreviousExtras;
+    int mPreviousProperties = -1;
 
     InCallServiceCallbacks mInCallCallbacks;
     String mPreviousDefaultDialer = null;
@@ -192,6 +199,17 @@
             @Override
             public void onDetailsChanged(Call call, Call.Details details) {
                 Log.i(TAG, "onDetailsChanged, Call: " + call + ", Details: " + details);
+                if (!areBundlesEqual(mPreviousExtras, details.getExtras())) {
+                    mOnExtrasChangedCounter.invoke(call, details);
+                }
+                mPreviousExtras = details.getExtras();
+
+                if (mPreviousProperties != details.getCallProperties()) {
+                    mOnPropertiesChangedCounter.invoke(call, details);
+                    Log.i(TAG, "onDetailsChanged; properties changed from " + Call.Details.propertiesToString(mPreviousProperties) +
+                            " to " + Call.Details.propertiesToString(details.getCallProperties()));
+                }
+                mPreviousProperties = details.getCallProperties();
             }
             @Override
             public void onCallDestroyed(Call call) {
@@ -218,6 +236,16 @@
             public void onCannedTextResponsesLoaded(Call call, List<String> cannedTextResponses) {
                 mOnCannedTextResponsesLoadedCounter.invoke(call, cannedTextResponses);
             }
+            @Override
+            public void onConnectionEvent(Call call, String event, Bundle extras) {
+                mOnConnectionEventCounter.invoke(call, event, extras);
+            }
+
+            @Override
+            public void onSilenceRinger() {
+                Log.i(TAG, "onSilenceRinger");
+                mOnSilenceRingerCounter.invoke();
+            }
         };
 
         MockInCallService.setCallbacks(mInCallCallbacks);
@@ -228,6 +256,10 @@
         mOnCallAudioStateChangedCounter = new InvokeCounter("OnCallAudioStateChanged");
         mOnPostDialWaitCounter = new InvokeCounter("OnPostDialWait");
         mOnCannedTextResponsesLoadedCounter = new InvokeCounter("OnCannedTextResponsesLoaded");
+        mOnSilenceRingerCounter = new InvokeCounter("OnSilenceRinger");
+        mOnConnectionEventCounter = new InvokeCounter("OnConnectionEvent");
+        mOnExtrasChangedCounter = new InvokeCounter("OnDetailsChangedCounter");
+        mOnPropertiesChangedCounter = new InvokeCounter("OnPropertiesChangedCounter");
     }
 
     /**
@@ -297,6 +329,7 @@
         if (mInCallCallbacks.getService() != null) {
             currentCallCount = mInCallCallbacks.getService().getCallCount();
         }
+        int currentConnectionCount = getNumberOfConnections();
         placeNewCallWithPhoneAccount(extras, videoState);
 
         try {
@@ -311,6 +344,20 @@
         assertEquals("InCallService should contain 1 more call after adding a call.",
                 currentCallCount + 1,
                 mInCallCallbacks.getService().getCallCount());
+
+        // The connectionService.lock is released in
+        // MockConnectionService#onCreateOutgoingConnection, however the connection will not
+        // actually be added to the list of connections in the ConnectionService until shortly
+        // afterwards.  So there is still a potential for the lock to be released before it would
+        // be seen by calls to ConnectionService#getAllConnections().
+        // We will wait here until the list of connections includes one more connection to ensure
+        // that placing the call has fully completed.
+        final int expectedConnectionCount = currentConnectionCount + 1;
+        assertCSConnections(expectedConnectionCount);
+    }
+
+    int getNumberOfConnections() {
+        return CtsConnectionService.getAllConnectionsFromTelecom().size();
     }
 
     MockConnection verifyConnectionForOutgoingCall() {
@@ -520,6 +567,24 @@
     );
     }
 
+    void assertCSConnections(final int numConnections) {
+        waitUntilConditionIsTrueOrTimeout(new Condition() {
+                                              @Override
+                                              public Object expected() {
+                                                  return numConnections;
+                                              }
+
+                                              @Override
+                                              public Object actual() {
+                                                  return CtsConnectionService
+                                                          .getAllConnectionsFromTelecom()
+                                                          .size();
+                                              }
+                                          },
+                WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+                "ConnectionService should contain " + numConnections + " connections."
+        );
+    }
 
     void assertNumConnections(final MockConnectionService connService, final int numConnections) {
         waitUntilConditionIsTrueOrTimeout(new Condition() {
@@ -756,6 +821,24 @@
         );
     }
 
+    void assertDisconnectReason(final Connection connection, final String disconnectReason) {
+        waitUntilConditionIsTrueOrTimeout(
+                new Condition() {
+                    @Override
+                    public Object expected() {
+                        return disconnectReason;
+                    }
+
+                    @Override
+                    public Object actual() {
+                        return connection.getDisconnectCause().getReason();
+                    }
+                },
+                WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+                "Connection should have been disconnected with reason: " + disconnectReason
+        );
+    }
+
     void assertConferenceState(final Conference conference, final int state) {
         waitUntilConditionIsTrueOrTimeout(
                 new Condition() {
@@ -834,16 +917,65 @@
                 new Condition() {
                     @Override
                     public Object expected() {
+                        return false;
+                    }
+
+                    @Override
+                    public Object actual() {
+                        return MockInCallService.isServiceBound();
+                    }
+                },
+                WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+                "MockInCallService not yet unbound!"
+        );
+    }
+
+    /**
+     * Asserts that a call's properties are as expected.
+     *
+     * @param call The call.
+     * @param properties The expected properties.
+     */
+    public void assertCallProperties(final Call call, final int properties) {
+        waitUntilConditionIsTrueOrTimeout(
+                new Condition() {
+                    @Override
+                    public Object expected() {
                         return true;
                     }
 
                     @Override
                     public Object actual() {
-                        return MockInCallService.isServiceUnbound();
+                        return call.getDetails().hasProperty(properties);
                     }
                 },
-                WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
-                "MockInCallService not yet unbound!"
+                TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+                "Call should have properties " + properties
+        );
+    }
+
+    /**
+     * Asserts that a call's capabilities are as expected.
+     *
+     * @param call The call.
+     * @param capabilities The expected capabiltiies.
+     */
+    public void assertCallCapabilities(final Call call, final int capabilities) {
+        waitUntilConditionIsTrueOrTimeout(
+                new Condition() {
+                    @Override
+                    public Object expected() {
+                        return true;
+                    }
+
+                    @Override
+                    public Object actual() {
+                        return (call.getDetails().getCallCapabilities() & capabilities) ==
+                                capabilities;
+                    }
+                },
+                TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+                "Call should have properties " + capabilities
         );
     }
 
@@ -892,7 +1024,7 @@
      * was invoked with. This class is prefixed Invoke rather than the more typical Call for
      * disambiguation purposes.
      */
-    protected static final class InvokeCounter {
+    public static final class InvokeCounter {
         private final String mName;
         private final Object mLock = new Object();
         private final ArrayList<Object[]> mInvokeArgs = new ArrayList<>();
@@ -964,4 +1096,25 @@
             }
         }
     }
+
+    public static boolean areBundlesEqual(Bundle extras, Bundle newExtras) {
+        if (extras == null || newExtras == null) {
+            return extras == newExtras;
+        }
+
+        if (extras.size() != newExtras.size()) {
+            return false;
+        }
+
+        for (String key : extras.keySet()) {
+            if (key != null) {
+                final Object value = extras.get(key);
+                final Object newValue = newExtras.get(key);
+                if (!Objects.equals(value, newValue)) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
 }
diff --git a/tests/tests/telecom/src/android/telecom/cts/CallDetailsTest.java b/tests/tests/telecom/src/android/telecom/cts/CallDetailsTest.java
index 879c995..e596a91 100644
--- a/tests/tests/telecom/src/android/telecom/cts/CallDetailsTest.java
+++ b/tests/tests/telecom/src/android/telecom/cts/CallDetailsTest.java
@@ -29,38 +29,53 @@
 import android.telecom.ConnectionRequest;
 import android.telecom.DisconnectCause;
 import android.telecom.GatewayInfo;
-import android.telecom.InCallService;
 import android.telecom.PhoneAccount;
 import android.telecom.PhoneAccountHandle;
 import android.telecom.StatusHints;
 import android.telecom.TelecomManager;
+import android.util.Log;
 
-import com.android.cts.telecom.R;
+import java.util.Arrays;
+import java.util.List;
 
 /**
  * Suites of tests that verifies the various Call details.
  */
 public class CallDetailsTest extends BaseTelecomTestWithMockServices {
 
+    /**
+     * {@link Connection#PROPERTY_HIGH_DEF_AUDIO} is @hide, so define it here for now.
+     */
+    public static final int PROPERTY_HIGH_DEF_AUDIO = 1<<2;
+
+    /**
+     * {@link Connection#PROPERTY_WIFI} is @hide, so define it here for now.
+     */
+    public static final int PROPERTY_WIFI = 1<<3;
+    public static final int CONNECTION_PROPERTIES =  PROPERTY_HIGH_DEF_AUDIO | PROPERTY_WIFI;
     public static final int CONNECTION_CAPABILITIES =
-            Connection.CAPABILITY_HOLD | Connection.CAPABILITY_MUTE |
-            /**
-             * CAPABILITY_HIGH_DEF_AUDIO & CAPABILITY_WIFI are hidden, so
-             * hardcoding the values for now.
-             */
-            0x00008000 | 0x00010000;
+            Connection.CAPABILITY_HOLD | Connection.CAPABILITY_MUTE;
     public static final int CALL_CAPABILITIES =
             Call.Details.CAPABILITY_HOLD | Call.Details.CAPABILITY_MUTE;
     public static final int CALL_PROPERTIES =
             Call.Details.PROPERTY_HIGH_DEF_AUDIO | Call.Details.PROPERTY_WIFI;
     public static final String CALLER_DISPLAY_NAME = "CTS test";
     public static final int CALLER_DISPLAY_NAME_PRESENTATION = TelecomManager.PRESENTATION_ALLOWED;
+    public static final String TEST_SUBJECT = "test";
+    public static final String TEST_CHILD_NUMBER = "650-555-1212";
+    public static final String TEST_FORWARDED_NUMBER = "650-555-1212";
+    public static final String TEST_EXTRA_KEY = "com.test.extra.TEST";
+    public static final String TEST_EXTRA_KEY2 = "com.test.extra.TEST2";
+    public static final String TEST_EXTRA_KEY3 = "com.test.extra.TEST3";
+    public static final int TEST_EXTRA_VALUE = 10;
+    public static final String TEST_EVENT = "com.test.event.TEST";
 
     private StatusHints mStatusHints;
     private Bundle mExtras = new Bundle();
 
     private MockInCallService mInCallService;
     private Call mCall;
+    private MockConnection mConnection;
 
     @Override
     protected void setUp() throws Exception {
@@ -75,6 +90,7 @@
                             Connection connection = super.onCreateOutgoingConnection(
                                     connectionManagerPhoneAccount,
                                     request);
+                            mConnection = (MockConnection) connection;
                             // Modify the connection object created with local values.
                             connection.setConnectionCapabilities(CONNECTION_CAPABILITIES);
                             connection.setCallerDisplayName(
@@ -135,6 +151,95 @@
     }
 
     /**
+     * Tests propagation of the local video capabilities from telephony through to in-call.
+     */
+    public void testCallLocalVideoCapability() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        // Note: Local support for video is disabled when a call is in dialing state.
+        mConnection.setConnectionCapabilities(
+                Connection.CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL);
+        assertCallCapabilities(mCall, 0);
+
+        mConnection.setConnectionCapabilities(Connection.CAPABILITY_SUPPORTS_VT_LOCAL_RX);
+        assertCallCapabilities(mCall, 0);
+
+        mConnection.setConnectionCapabilities(Connection.CAPABILITY_SUPPORTS_VT_LOCAL_TX);
+        assertCallCapabilities(mCall, 0);
+
+        mConnection.setConnectionCapabilities(
+                Connection.CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL);
+        assertCallCapabilities(mCall, 0);
+
+        mConnection.setConnectionCapabilities(Connection.CAPABILITY_SUPPORTS_VT_REMOTE_RX);
+        assertCallCapabilities(mCall, 0);
+
+        mConnection.setConnectionCapabilities(Connection.CAPABILITY_SUPPORTS_VT_REMOTE_TX);
+        assertCallCapabilities(mCall, 0);
+
+        // Set call active; we expect the capabilities to make it through now.
+        mConnection.setActive();
+
+        mConnection.setConnectionCapabilities(
+                Connection.CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL);
+        assertCallCapabilities(mCall, Call.Details.CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL);
+
+        mConnection.setConnectionCapabilities(Connection.CAPABILITY_SUPPORTS_VT_LOCAL_RX);
+        assertCallCapabilities(mCall, Call.Details.CAPABILITY_SUPPORTS_VT_LOCAL_RX);
+
+        mConnection.setConnectionCapabilities(Connection.CAPABILITY_SUPPORTS_VT_LOCAL_TX);
+        assertCallCapabilities(mCall, Call.Details.CAPABILITY_SUPPORTS_VT_LOCAL_TX);
+
+        mConnection.setConnectionCapabilities(
+                Connection.CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL);
+        assertCallCapabilities(mCall, Call.Details.CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL);
+
+        mConnection.setConnectionCapabilities(Connection.CAPABILITY_SUPPORTS_VT_REMOTE_RX);
+        assertCallCapabilities(mCall, Call.Details.CAPABILITY_SUPPORTS_VT_REMOTE_RX);
+
+        mConnection.setConnectionCapabilities(Connection.CAPABILITY_SUPPORTS_VT_REMOTE_TX);
+        assertCallCapabilities(mCall, Call.Details.CAPABILITY_SUPPORTS_VT_REMOTE_TX);
+    }
+
+    /**
+     * Tests passing call capabilities from Connections to Calls.
+     */
+    public void testCallCapabilityPropagation() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        mConnection.setConnectionCapabilities(Connection.CAPABILITY_CAN_PAUSE_VIDEO);
+        assertCallCapabilities(mCall, Call.Details.CAPABILITY_CAN_PAUSE_VIDEO);
+
+        mConnection.setConnectionCapabilities(Connection.CAPABILITY_HOLD);
+        assertCallCapabilities(mCall, Call.Details.CAPABILITY_HOLD);
+
+        mConnection.setConnectionCapabilities(Connection.CAPABILITY_MANAGE_CONFERENCE);
+        assertCallCapabilities(mCall, Call.Details.CAPABILITY_MANAGE_CONFERENCE);
+
+        mConnection.setConnectionCapabilities(Connection.CAPABILITY_MERGE_CONFERENCE);
+        assertCallCapabilities(mCall, Call.Details.CAPABILITY_MERGE_CONFERENCE);
+
+        mConnection.setConnectionCapabilities(Connection.CAPABILITY_MUTE);
+        assertCallCapabilities(mCall, Call.Details.CAPABILITY_MUTE);
+
+        mConnection.setConnectionCapabilities(Connection.CAPABILITY_RESPOND_VIA_TEXT);
+        assertCallCapabilities(mCall, Call.Details.CAPABILITY_RESPOND_VIA_TEXT);
+
+        mConnection.setConnectionCapabilities(Connection.CAPABILITY_SEPARATE_FROM_CONFERENCE);
+        assertCallCapabilities(mCall, Call.Details.CAPABILITY_SEPARATE_FROM_CONFERENCE);
+
+        mConnection.setConnectionCapabilities(Connection.CAPABILITY_SUPPORT_HOLD);
+        assertCallCapabilities(mCall, Call.Details.CAPABILITY_SUPPORT_HOLD);
+
+        mConnection.setConnectionCapabilities(Connection.CAPABILITY_SWAP_CONFERENCE);
+        assertCallCapabilities(mCall, Call.Details.CAPABILITY_SWAP_CONFERENCE);
+    }
+
+    /**
      * Tests whether the getCallerDisplayName() getter returns the correct object.
      */
     public void testCallerDisplayName() {
@@ -167,7 +272,9 @@
         }
 
         assertThat(mCall.getDetails().getCallProperties(), is(Integer.class));
-        assertEquals(CALL_PROPERTIES, mCall.getDetails().getCallProperties());
+
+        // No public call properties at the moment, so ensure we have 0 as a return.
+        assertEquals(0, mCall.getDetails().getCallProperties());
     }
 
     /**
@@ -279,4 +386,56 @@
 
         assertThat(mCall.getDetails().getVideoState(), is(Integer.class));
     }
+
+    /**
+     * Tests communication of {@link Connection#setExtras(Bundle)} through to
+     * {@link Call.Details#getExtras()}.
+     */
+    public void testExtrasPropagation() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        Bundle exampleExtras = new Bundle();
+        exampleExtras.putString(Connection.EXTRA_CALL_SUBJECT, TEST_SUBJECT);
+        exampleExtras.putString(Connection.EXTRA_CHILD_ADDRESS, TEST_CHILD_NUMBER);
+        exampleExtras.putString(Connection.EXTRA_LAST_FORWARDED_NUMBER, TEST_FORWARDED_NUMBER);
+        exampleExtras.putInt(TEST_EXTRA_KEY, TEST_EXTRA_VALUE);
+        mConnection.setExtras(exampleExtras);
+
+        // Make sure we got back a bundle with the call subject key set.
+        assertCallExtras(mCall, Connection.EXTRA_CALL_SUBJECT);
+
+        Bundle callExtras = mCall.getDetails().getExtras();
+        assertEquals(TEST_SUBJECT, callExtras.getString(Connection.EXTRA_CALL_SUBJECT));
+        assertEquals(TEST_CHILD_NUMBER, callExtras.getString(Connection.EXTRA_CHILD_ADDRESS));
+        assertEquals(TEST_FORWARDED_NUMBER,
+                callExtras.getString(Connection.EXTRA_LAST_FORWARDED_NUMBER));
+        assertEquals(TEST_EXTRA_VALUE, callExtras.getInt(TEST_EXTRA_KEY));
+    }
+
+    /**
+     * Asserts that a call's extras contain a specified key.
+     *
+     * @param call The call.
+     * @param expectedKey The expected extras key.
+     */
+    private void assertCallExtras(final Call call, final String expectedKey) {
+        waitUntilConditionIsTrueOrTimeout(
+                new Condition() {
+                    @Override
+                    public Object expected() {
+                        return expectedKey;
+                    }
+
+                    @Override
+                    public Object actual() {
+                        return call.getDetails().getExtras().containsKey(expectedKey) ? expectedKey
+                                : "";
+                    }
+                },
+                TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+                "Call should have extras key " + expectedKey
+        );
+    }
 }
diff --git a/tests/tests/telecom/src/android/telecom/cts/CallScreeningServiceTest.java b/tests/tests/telecom/src/android/telecom/cts/CallScreeningServiceTest.java
new file mode 100644
index 0000000..0704a8d
--- /dev/null
+++ b/tests/tests/telecom/src/android/telecom/cts/CallScreeningServiceTest.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.telecom.cts;
+
+import static android.telecom.cts.TestUtils.shouldTestTelecom;
+import static org.junit.Assert.assertTrue;
+
+import android.telecom.cts.MockCallScreeningService.CallScreeningServiceCallbacks;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.telecom.Call;
+import android.telecom.CallScreeningService;
+import android.telecom.PhoneAccount;
+import android.telecom.PhoneAccountHandle;
+import android.telecom.TelecomManager;
+import android.test.InstrumentationTestCase;
+import android.text.TextUtils;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Verify that call screening service gets a chance to block calls.
+ */
+public class CallScreeningServiceTest extends InstrumentationTestCase {
+    private static final Uri TEST_NUMBER = Uri.fromParts("tel", "7", null);
+
+    public static final PhoneAccountHandle TEST_PHONE_ACCOUNT_HANDLE = new PhoneAccountHandle(
+            new ComponentName(TestUtils.PACKAGE, TestUtils.COMPONENT),
+            TestUtils.ACCOUNT_ID);
+
+    public static final PhoneAccount TEST_PHONE_ACCOUNT = PhoneAccount.builder(
+            TEST_PHONE_ACCOUNT_HANDLE, TestUtils.ACCOUNT_LABEL)
+            .setAddress(Uri.parse("tel:555-TEST"))
+            .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER |
+                    PhoneAccount.CAPABILITY_CONNECTION_MANAGER)
+            .addSupportedUriScheme(PhoneAccount.SCHEME_TEL)
+            .build();
+
+    private Context mContext;
+    private TelecomManager mTelecomManager;
+    private String mPreviousDefaultDialer;
+    MockConnectionService mConnectionService;
+    private boolean mCallFound;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mContext = getInstrumentation().getContext();
+        mTelecomManager = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
+        if (shouldTestTelecom(mContext)) {
+            mPreviousDefaultDialer = TestUtils.getDefaultDialer(getInstrumentation());
+            TestUtils.setDefaultDialer(getInstrumentation(), TestUtils.PACKAGE);
+            setupConnectionService();
+            MockCallScreeningService.enableService(mContext);
+        }
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        if (!TextUtils.isEmpty(mPreviousDefaultDialer)) {
+            TestUtils.setDefaultDialer(getInstrumentation(), mPreviousDefaultDialer);
+            mTelecomManager.unregisterPhoneAccount(TEST_PHONE_ACCOUNT_HANDLE);
+            CtsConnectionService.tearDown();
+            mConnectionService = null;
+            MockCallScreeningService.disableService(mContext);
+        }
+        super.tearDown();
+    }
+
+    /**
+     * Tests that when sending a CALL intent via the Telecom stack, Telecom binds to the registered
+     * {@link CallScreeningService}s and invokes onScreenCall.
+     */
+    public void testTelephonyCall_bindsToCallScreeningService() {
+        if (!shouldTestTelecom(mContext)) {
+            return;
+        }
+
+        CallScreeningServiceCallbacks callbacks = createCallbacks();
+        MockCallScreeningService.setCallbacks(callbacks);
+        addNewIncomingCall(TEST_NUMBER);
+
+        try {
+            if (callbacks.lock.tryAcquire(TestUtils.WAIT_FOR_CALL_ADDED_TIMEOUT_S,
+                        TimeUnit.SECONDS)) {
+                assertTrue(mCallFound);
+                return;
+            }
+        } catch (InterruptedException e) {
+        }
+
+        fail("No call added to CallScreeningService.");
+    }
+
+    private void addNewIncomingCall(Uri incomingHandle) {
+        Bundle extras = new Bundle();
+        extras.putParcelable(TelecomManager.EXTRA_INCOMING_CALL_ADDRESS, incomingHandle);
+        mTelecomManager.addNewIncomingCall(TEST_PHONE_ACCOUNT_HANDLE, extras);
+    }
+
+    private CallScreeningServiceCallbacks createCallbacks() {
+        return new CallScreeningServiceCallbacks() {
+            @Override
+            public void onScreenCall(Call.Details callDetails) {
+                mCallFound = true;
+                CallScreeningService.CallResponse response =
+                        new CallScreeningService.CallResponse.Builder()
+                        .setDisallowCall(true)
+                        .setRejectCall(true)
+                        .setSkipCallLog(true)
+                        .setSkipNotification(true)
+                        .build();
+                getService().respondToCall(callDetails, response);
+                lock.release();
+            }
+        };
+    }
+
+    private void setupConnectionService() throws Exception {
+        mConnectionService = new MockConnectionService();
+        CtsConnectionService.setUp(TEST_PHONE_ACCOUNT_HANDLE, mConnectionService);
+
+        mTelecomManager.registerPhoneAccount(TEST_PHONE_ACCOUNT);
+        TestUtils.enablePhoneAccount(getInstrumentation(), TEST_PHONE_ACCOUNT_HANDLE);
+        // Wait till the adb commands have executed and account is enabled in Telecom database.
+        assertPhoneAccountEnabled(TEST_PHONE_ACCOUNT_HANDLE);
+    }
+
+    private void assertPhoneAccountEnabled(final PhoneAccountHandle handle) {
+        waitUntilConditionIsTrueOrTimeout(
+                new Condition() {
+                    @Override
+                    public Object expected() {
+                        return true;
+                    }
+
+                    @Override
+                    public Object actual() {
+                        PhoneAccount phoneAccount = mTelecomManager.getPhoneAccount(handle);
+                        return (phoneAccount != null && phoneAccount.isEnabled());
+                    }
+                },
+                TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+                "Phone account enable failed for " + handle
+        );
+    }
+
+    private void waitUntilConditionIsTrueOrTimeout(Condition condition, long timeout,
+            String description) {
+        final long start = System.currentTimeMillis();
+        while (!condition.expected().equals(condition.actual())
+                && System.currentTimeMillis() - start < timeout) {
+            sleep(50);
+        }
+        assertEquals(description, condition.expected(), condition.actual());
+    }
+
+    private void sleep(long ms) {
+        try {
+            Thread.sleep(ms);
+        } catch (InterruptedException e) {
+        }
+    }
+
+    protected interface Condition {
+        Object expected();
+        Object actual();
+    }
+}
diff --git a/tests/tests/telecom/src/android/telecom/cts/CallTest.java b/tests/tests/telecom/src/android/telecom/cts/CallTest.java
index efbb69f..d63a9e8 100644
--- a/tests/tests/telecom/src/android/telecom/cts/CallTest.java
+++ b/tests/tests/telecom/src/android/telecom/cts/CallTest.java
@@ -31,7 +31,7 @@
         assertTrue(Call.Details.can(CAPABILITY_MERGE_CONFERENCE
                 | CAPABILITY_DISCONNECT_FROM_CONFERENCE | CAPABILITY_MUTE,
                 CAPABILITY_MUTE));
-
+        assertTrue(Call.Details.can(CAPABILITY_CAN_PAUSE_VIDEO, CAPABILITY_CAN_PAUSE_VIDEO));
         assertFalse(Call.Details.can(CAPABILITY_MUTE, CAPABILITY_HOLD));
         assertFalse(Call.Details.can(CAPABILITY_MERGE_CONFERENCE
                 | CAPABILITY_DISCONNECT_FROM_CONFERENCE | CAPABILITY_MUTE,
@@ -78,7 +78,6 @@
         assertTrue(Call.Details.hasProperty(PROPERTY_HIGH_DEF_AUDIO, PROPERTY_HIGH_DEF_AUDIO));
         assertTrue(Call.Details.hasProperty(PROPERTY_HIGH_DEF_AUDIO | PROPERTY_CONFERENCE
                 | PROPERTY_WIFI, PROPERTY_CONFERENCE));
-
         assertFalse(Call.Details.hasProperty(PROPERTY_WIFI, PROPERTY_CONFERENCE));
         assertFalse(Call.Details.hasProperty(PROPERTY_HIGH_DEF_AUDIO | PROPERTY_CONFERENCE
                 | PROPERTY_WIFI, PROPERTY_GENERIC_CONFERENCE));
diff --git a/tests/tests/telecom/src/android/telecom/cts/ConferenceTest.java b/tests/tests/telecom/src/android/telecom/cts/ConferenceTest.java
index 508870c..80e3201 100644
--- a/tests/tests/telecom/src/android/telecom/cts/ConferenceTest.java
+++ b/tests/tests/telecom/src/android/telecom/cts/ConferenceTest.java
@@ -29,8 +29,11 @@
 import android.telecom.StatusHints;
 import android.telecom.TelecomManager;
 import android.telecom.VideoProfile;
+import android.util.Log;
 
 import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
 
 /**
  * Extended suite of tests that use {@link CtsConnectionService} and {@link MockInCallService} to
@@ -38,6 +41,11 @@
  */
 public class ConferenceTest extends BaseTelecomTestWithMockServices {
 
+    private static final String TEST_EXTRA_KEY_1 = "android.telecom.test.KEY1";
+    private static final String TEST_EXTRA_KEY_2 = "android.telecom.test.KEY2";
+    private static final String TEST_EXTRA_VALUE_1 = "test";
+    private static final int TEST_EXTRA_VALUE_2 = 42;
+
     public static final int CONF_CAPABILITIES = Connection.CAPABILITY_SEPARATE_FROM_CONFERENCE |
             Connection.CAPABILITY_DISCONNECT_FROM_CONFERENCE | Connection.CAPABILITY_HOLD |
             Connection.CAPABILITY_MERGE_CONFERENCE | Connection.CAPABILITY_SWAP_CONFERENCE;
@@ -45,7 +53,7 @@
     private Call mCall1, mCall2;
     private MockConnection mConnection1, mConnection2;
     MockInCallService mInCallService;
-    Conference mConferenceObject;
+    MockConference mConferenceObject;
 
     @Override
     protected void setUp() throws Exception {
diff --git a/tests/tests/telecom/src/android/telecom/cts/ConnectionServiceTest.java b/tests/tests/telecom/src/android/telecom/cts/ConnectionServiceTest.java
index 836ca48..21b00a0 100644
--- a/tests/tests/telecom/src/android/telecom/cts/ConnectionServiceTest.java
+++ b/tests/tests/telecom/src/android/telecom/cts/ConnectionServiceTest.java
@@ -77,6 +77,7 @@
 
         // Add second connection (add existing connection)
         final Connection connection2 = new MockConnection();
+        connection2.setActive();
         CtsConnectionService.addExistingConnectionToTelecom(TEST_PHONE_ACCOUNT_HANDLE, connection2);
         assertNumCalls(mInCallCallbacks.getService(), 2);
         mInCallCallbacks.lock.drainPermits();
diff --git a/tests/tests/telecom/src/android/telecom/cts/ConnectionTest.java b/tests/tests/telecom/src/android/telecom/cts/ConnectionTest.java
index b6818c8..58dfcdb 100644
--- a/tests/tests/telecom/src/android/telecom/cts/ConnectionTest.java
+++ b/tests/tests/telecom/src/android/telecom/cts/ConnectionTest.java
@@ -27,6 +27,8 @@
 import android.telecom.TelecomManager;
 import android.test.AndroidTestCase;
 
+import java.util.Arrays;
+import java.util.List;
 import java.util.concurrent.Semaphore;
 import java.util.concurrent.TimeUnit;
 
diff --git a/tests/tests/telecom/src/android/telecom/cts/CtsConnectionService.java b/tests/tests/telecom/src/android/telecom/cts/CtsConnectionService.java
index 2364986..e820e10 100644
--- a/tests/tests/telecom/src/android/telecom/cts/CtsConnectionService.java
+++ b/tests/tests/telecom/src/android/telecom/cts/CtsConnectionService.java
@@ -29,6 +29,7 @@
 import android.util.Log;
 
 import java.util.Collection;
+import java.util.Collections;
 
 /**
  * This is the official ConnectionService for Telecom's CTS App. Since telecom requires that a
@@ -154,6 +155,9 @@
 
     public static Collection<Connection> getAllConnectionsFromTelecom() {
         synchronized(sLock) {
+            if (sTelecomConnectionService == null) {
+                return Collections.EMPTY_LIST;
+            }
             return sTelecomConnectionService.getAllConnections();
         }
     }
diff --git a/tests/tests/telecom/src/android/telecom/cts/DataObjectUnitTests.java b/tests/tests/telecom/src/android/telecom/cts/DataObjectUnitTests.java
index 1fbe0d5..a088951 100644
--- a/tests/tests/telecom/src/android/telecom/cts/DataObjectUnitTests.java
+++ b/tests/tests/telecom/src/android/telecom/cts/DataObjectUnitTests.java
@@ -39,8 +39,6 @@
 import android.telecom.VideoProfile;
 import android.test.InstrumentationTestCase;
 
-import com.android.cts.telecom.R;
-
 import java.util.Arrays;
 import java.util.List;
 
diff --git a/tests/tests/telecom/src/android/telecom/cts/ExtendedInCallServiceTest.java b/tests/tests/telecom/src/android/telecom/cts/ExtendedInCallServiceTest.java
index 02d2f15..9f9900e 100644
--- a/tests/tests/telecom/src/android/telecom/cts/ExtendedInCallServiceTest.java
+++ b/tests/tests/telecom/src/android/telecom/cts/ExtendedInCallServiceTest.java
@@ -18,7 +18,11 @@
 
 import static android.telecom.cts.TestUtils.*;
 
+import android.content.ContentValues;
 import android.content.Context;
+import android.net.Uri;
+import android.os.Bundle;
+import android.provider.BlockedNumberContract;
 import android.telecom.CallAudioState;
 import android.telecom.Call;
 import android.telecom.Connection;
@@ -204,6 +208,39 @@
         assertConnectionState(connection, Connection.STATE_ACTIVE);
     }
 
+    public void testIncomingCallFromBlockedNumber_IsRejected() throws Exception {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        Uri blockedUri = null;
+
+        try {
+            Uri testNumberUri = createTestNumber();
+            blockedUri = blockNumber(testNumberUri);
+
+            final Bundle extras = new Bundle();
+            extras.putParcelable(TelecomManager.EXTRA_INCOMING_CALL_ADDRESS, testNumberUri);
+            mTelecomManager.addNewIncomingCall(TEST_PHONE_ACCOUNT_HANDLE, extras);
+
+            final MockConnection connection = verifyConnectionForIncomingCall();
+            assertConnectionState(connection, Connection.STATE_DISCONNECTED);
+            assertNull(mInCallCallbacks.getService());
+        } finally {
+            if (blockedUri != null) {
+                mContext.getContentResolver().delete(blockedUri, null, null);
+            }
+        }
+    }
+
+    private Uri blockNumber(Uri phoneNumberUri) {
+        ContentValues cv = new ContentValues();
+        cv.put(BlockedNumberContract.BlockedNumbers.COLUMN_ORIGINAL_NUMBER,
+                phoneNumberUri.getSchemeSpecificPart());
+        return mContext.getContentResolver().insert(
+                BlockedNumberContract.BlockedNumbers.CONTENT_URI, cv);
+    }
+
     public void testAnswerIncomingCallAsVideo_SendsCorrectVideoState() {
         if (!mShouldTestTelecom) {
             return;
@@ -248,6 +285,29 @@
         assertConnectionState(connection, Connection.STATE_DISCONNECTED);
     }
 
+    public void testRejectIncomingCallWithMessage() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+        String disconnectReason = "Test reason for disconnect";
+
+        addAndVerifyNewIncomingCall(createTestNumber(), null);
+        final MockConnection connection = verifyConnectionForIncomingCall();
+
+        final MockInCallService inCallService = mInCallCallbacks.getService();
+
+        final Call call = inCallService.getLastCall();
+
+        assertCallState(call, Call.STATE_RINGING);
+        assertConnectionState(connection, Connection.STATE_RINGING);
+
+        call.reject(true, disconnectReason);
+
+        assertCallState(call, Call.STATE_DISCONNECTED);
+        assertConnectionState(connection, Connection.STATE_DISCONNECTED);
+        assertDisconnectReason(connection, disconnectReason);
+    }
+
     public void testCanAddCall_CannotAddForExistingDialingCall() {
         if (!mShouldTestTelecom) {
             return;
@@ -353,6 +413,21 @@
         assertTrue((Boolean) mOnBringToForegroundCounter.getArgs(1)[0]);
     }
 
+    public void testSilenceRinger() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        addAndVerifyNewIncomingCall(createTestNumber(), null);
+        final MockConnection connection = verifyConnectionForIncomingCall();
+        final MockInCallService inCallService = mInCallCallbacks.getService();
+
+        final TelecomManager telecomManager =
+            (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
+        telecomManager.silenceRinger();
+        mOnSilenceRingerCounter.waitForCount(1);
+    }
+
     public void testOnPostDialWaitAndContinue() {
         if (!mShouldTestTelecom) {
             return;
diff --git a/tests/tests/telecom/src/android/telecom/cts/MissedCallTest.java b/tests/tests/telecom/src/android/telecom/cts/MissedCallTest.java
new file mode 100644
index 0000000..702ea23
--- /dev/null
+++ b/tests/tests/telecom/src/android/telecom/cts/MissedCallTest.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.telecom.cts;
+
+import android.content.Intent;
+import android.telecom.Call;
+import android.telecom.Connection;
+import android.telecom.DisconnectCause;
+import android.telecom.TelecomManager;
+import android.telecom.cts.MockMissedCallNotificationReceiver.IntentListener;
+import android.util.Log;
+
+public class MissedCallTest extends BaseTelecomTestWithMockServices {
+
+    InvokeCounter mShowMissedCallNotificationIntentCounter =
+            new InvokeCounter("ShowMissedCallNotificationIntent");
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mContext = getInstrumentation().getContext();
+
+        MockMissedCallNotificationReceiver.setIntentListener(new IntentListener() {
+            @Override
+            public void onIntentReceived(Intent intent) {
+                Log.i(TestUtils.TAG, intent.toString());
+                if (TelecomManager.ACTION_SHOW_MISSED_CALLS_NOTIFICATION
+                        .equals(intent.getAction())) {
+                    mShowMissedCallNotificationIntentCounter.invoke();
+                }
+            }
+        });
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        MockMissedCallNotificationReceiver.setIntentListener(null);
+        super.tearDown();
+    }
+
+    public void testMissedCall_NotifyDialer() throws Exception {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+        setupConnectionService(null, FLAG_REGISTER | FLAG_ENABLE);
+
+        addAndVerifyNewIncomingCall(createTestNumber(), null);
+        final MockConnection connection = verifyConnectionForIncomingCall();
+
+        final MockInCallService inCallService = mInCallCallbacks.getService();
+
+        final Call call = inCallService.getLastCall();
+
+        assertCallState(call, Call.STATE_RINGING);
+        assertConnectionState(connection, Connection.STATE_RINGING);
+
+        connection.setDisconnected(new DisconnectCause(DisconnectCause.MISSED));
+        connection.destroy();
+        mShowMissedCallNotificationIntentCounter.waitForCount(1);
+    }
+
+}
diff --git a/tests/tests/telecom/src/android/telecom/cts/MockCallScreeningService.java b/tests/tests/telecom/src/android/telecom/cts/MockCallScreeningService.java
new file mode 100644
index 0000000..3c7d2b6
--- /dev/null
+++ b/tests/tests/telecom/src/android/telecom/cts/MockCallScreeningService.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.telecom.cts;
+
+import static org.junit.Assert.assertFalse;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.telecom.Call;
+import android.telecom.CallScreeningService;
+import android.util.Log;
+
+import java.util.concurrent.Semaphore;
+
+public class MockCallScreeningService extends CallScreeningService {
+    private static String LOG_TAG = "MockCallScreeningSvc";
+
+    private static boolean mIsServiceUnbound;
+    private static CallScreeningServiceCallbacks sCallbacks;
+
+    public static abstract class CallScreeningServiceCallbacks {
+        public Semaphore lock = new Semaphore(0);
+        private MockCallScreeningService mService;
+
+        public void onScreenCall(Call.Details callDetails) {};
+
+        final public MockCallScreeningService getService() {
+            return mService;
+        }
+
+        final public void setService(MockCallScreeningService service) {
+            mService = service;
+        }
+    }
+
+    @Override
+    public android.os.IBinder onBind(android.content.Intent intent) {
+        Log.i(LOG_TAG, "Service bounded");
+        if (getCallbacks() != null) {
+            getCallbacks().setService(this);
+        }
+        mIsServiceUnbound = false;
+        return super.onBind(intent);
+    }
+
+    @Override
+    public void onScreenCall(Call.Details callDetails) {
+        if (getCallbacks() != null) {
+            getCallbacks().onScreenCall(callDetails);
+        }
+    }
+
+    public static void setCallbacks(CallScreeningServiceCallbacks callbacks) {
+        sCallbacks = callbacks;
+    }
+
+    private CallScreeningServiceCallbacks getCallbacks() {
+        if (sCallbacks != null) {
+            sCallbacks.setService(this);
+        }
+        return sCallbacks;
+    }
+
+    @Override
+    public boolean onUnbind(Intent intent) {
+        Log.i(LOG_TAG, "Service unbounded");
+        assertFalse(mIsServiceUnbound);
+        mIsServiceUnbound = true;
+        return super.onUnbind(intent);
+    }
+
+    public static boolean isServiceUnbound() {
+        return mIsServiceUnbound;
+    }
+
+    public static void enableService(Context context) {
+        context.getPackageManager().setComponentEnabledSetting(getComponentName(context),
+            PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
+            PackageManager.DONT_KILL_APP);
+    }
+
+    public static void disableService(Context context) {
+        context.getPackageManager().setComponentEnabledSetting(getComponentName(context),
+            PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
+            PackageManager.DONT_KILL_APP);
+    }
+
+    private static ComponentName getComponentName(Context context) {
+        return new ComponentName(context, MockCallScreeningService.class);
+    }
+}
diff --git a/tests/tests/telecom/src/android/telecom/cts/MockConference.java b/tests/tests/telecom/src/android/telecom/cts/MockConference.java
index 647d039..89c3772 100644
--- a/tests/tests/telecom/src/android/telecom/cts/MockConference.java
+++ b/tests/tests/telecom/src/android/telecom/cts/MockConference.java
@@ -16,6 +16,7 @@
 
 package android.telecom.cts;
 
+import android.os.Bundle;
 import android.telecom.Conference;
 import android.telecom.Connection;
 import android.telecom.DisconnectCause;
@@ -31,6 +32,8 @@
 
     private RemoteConference mRemoteConference = null;
     private String mDtmfString = "";
+    public BaseTelecomTestWithMockServices.InvokeCounter mOnExtrasChanged =
+            new BaseTelecomTestWithMockServices.InvokeCounter("onExtrasChanged");
 
     public MockConference(PhoneAccountHandle phoneAccount) {
         super(phoneAccount);
diff --git a/tests/tests/telecom/src/android/telecom/cts/MockConnection.java b/tests/tests/telecom/src/android/telecom/cts/MockConnection.java
index 9bb83a1..708540a 100644
--- a/tests/tests/telecom/src/android/telecom/cts/MockConnection.java
+++ b/tests/tests/telecom/src/android/telecom/cts/MockConnection.java
@@ -17,6 +17,8 @@
 package android.telecom.cts;
 
 import static android.telecom.CallAudioState.*;
+
+import android.os.Bundle;
 import android.telecom.CallAudioState;
 import android.telecom.Connection;
 import android.telecom.DisconnectCause;
@@ -32,6 +34,9 @@
  */
 public class MockConnection extends Connection {
     public static final int ON_POST_DIAL_WAIT = 1;
+    public static final int ON_CALL_EVENT = 2;
+    public static final int ON_PULL_EXTERNAL_CALL = 3;
+    public static final int ON_EXTRAS_CHANGED = 4;
 
     private CallAudioState mCallAudioState =
             new CallAudioState(false, CallAudioState.ROUTE_EARPIECE, ROUTE_EARPIECE | ROUTE_SPEAKER);
@@ -70,6 +75,16 @@
     }
 
     @Override
+    public void onReject(String reason) {
+        super.onReject();
+        setDisconnected(new DisconnectCause(DisconnectCause.REJECTED, reason));
+        if (mRemoteConnection != null) {
+            mRemoteConnection.reject();
+        }
+        destroy();
+    }
+
+    @Override
     public void onHold() {
         super.onHold();
         setOnHold();
@@ -229,6 +244,12 @@
         switch (counterIndex) {
             case ON_POST_DIAL_WAIT:
                 return "onPostDialWait";
+            case ON_CALL_EVENT:
+                return "onCallEvent";
+            case ON_PULL_EXTERNAL_CALL:
+                return "onPullExternalCall";
+            case ON_EXTRAS_CHANGED:
+                return "onExtrasChanged";
             default:
                 return "Callback";
         }
diff --git a/tests/tests/telecom/src/android/telecom/cts/MockConnectionService.java b/tests/tests/telecom/src/android/telecom/cts/MockConnectionService.java
index ad64e5c..48a1c94 100644
--- a/tests/tests/telecom/src/android/telecom/cts/MockConnectionService.java
+++ b/tests/tests/telecom/src/android/telecom/cts/MockConnectionService.java
@@ -73,6 +73,9 @@
             ConnectionRequest request) {
         final MockConnection connection = new MockConnection();
         connection.setAddress(request.getAddress(), CONNECTION_PRESENTATION);
+        connection.setConnectionCapabilities(
+                connection.getConnectionCapabilities() |
+                        Connection.CAPABILITY_CAN_SEND_RESPONSE_VIA_CONNECTION);
         connection.createMockVideoProvider();
         ((Connection) connection).setVideoState(request.getVideoState());
 
diff --git a/tests/tests/telecom/src/android/telecom/cts/MockInCallService.java b/tests/tests/telecom/src/android/telecom/cts/MockInCallService.java
index 0f1f538..d59a801 100644
--- a/tests/tests/telecom/src/android/telecom/cts/MockInCallService.java
+++ b/tests/tests/telecom/src/android/telecom/cts/MockInCallService.java
@@ -16,9 +16,10 @@
 
 package android.telecom.cts;
 
-import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 
 import android.content.Intent;
+import android.os.Bundle;
 import android.telecom.Call;
 import android.telecom.CallAudioState;
 import android.telecom.InCallService;
@@ -39,7 +40,7 @@
             new ArrayMap<Call, MockVideoCallCallback>();
 
     private static final Object sLock = new Object();
-    private static boolean mIsServiceUnbound;
+    private static boolean mIsServiceBound = false;
 
     public static abstract class InCallServiceCallbacks {
         private MockInCallService mService;
@@ -58,6 +59,8 @@
         public void onCallAudioStateChanged(CallAudioState audioState) {}
         public void onPostDialWait(Call call, String remainingPostDialSequence) {}
         public void onCannedTextResponsesLoaded(Call call, List<String> cannedTextResponses) {}
+        public void onSilenceRinger() {}
+        public void onConnectionEvent(Call call, String event, Bundle extras) {}
 
         final public MockInCallService getService() {
             return mService;
@@ -162,7 +165,7 @@
         if (getCallbacks() != null) {
             getCallbacks().setService(this);
         }
-        mIsServiceUnbound = false;
+        mIsServiceBound = true;
         return super.onBind(intent);
     }
 
@@ -227,6 +230,14 @@
         }
     }
 
+    @Override
+    public void onSilenceRinger(){
+        super.onSilenceRinger();
+        if(getCallbacks() != null) {
+            getCallbacks().onSilenceRinger();
+        }
+    }
+
     /**
      * @return the number of calls currently added to the {@code InCallService}.
      */
@@ -323,13 +334,13 @@
 
     @Override
     public boolean onUnbind(Intent intent) {
-        Log.i(LOG_TAG, "Service unbounded");
-        assertFalse(mIsServiceUnbound);
-        mIsServiceUnbound = true;
+        Log.i(LOG_TAG, "Service has been unbound");
+        assertTrue(mIsServiceBound);
+        mIsServiceBound = false;
         return super.onUnbind(intent);
     }
 
-    public static boolean isServiceUnbound() {
-        return mIsServiceUnbound;
+    public static boolean isServiceBound() {
+        return mIsServiceBound;
     }
 }
diff --git a/tests/tests/telecom/src/android/telecom/cts/MockMissedCallNotificationReceiver.java b/tests/tests/telecom/src/android/telecom/cts/MockMissedCallNotificationReceiver.java
new file mode 100644
index 0000000..157f343
--- /dev/null
+++ b/tests/tests/telecom/src/android/telecom/cts/MockMissedCallNotificationReceiver.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.telecom.cts;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+public class MockMissedCallNotificationReceiver extends BroadcastReceiver {
+
+    public interface IntentListener {
+
+        void onIntentReceived(Intent intent);
+    }
+
+    private static IntentListener sIntentListener = null;
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        if (sIntentListener != null) {
+            sIntentListener.onIntentReceived(intent);
+        }
+    }
+
+    public static void setIntentListener(IntentListener listener) {
+        sIntentListener = listener;
+    }
+}
diff --git a/tests/tests/telecom/src/android/telecom/cts/MockVideoCallCallback.java b/tests/tests/telecom/src/android/telecom/cts/MockVideoCallCallback.java
index 07e159c..5e32cf7 100644
--- a/tests/tests/telecom/src/android/telecom/cts/MockVideoCallCallback.java
+++ b/tests/tests/telecom/src/android/telecom/cts/MockVideoCallCallback.java
@@ -31,6 +31,8 @@
     private int mVideoQuality = MockVideoProvider.VIDEO_QUALITY_UNDEFINED;
     private int mCallSessionEvent = MockVideoProvider.SESSION_EVENT_UNDEFINED;
     private int mPeerWidth = MockVideoProvider.PEER_WIDTH_UNDEFINED;
+    private int mResponseStatus;
+    private VideoProfile mRequestedProfile = null;
     private VideoProfile mResponseProfile = null;
     private VideoProfile mRequestProfile = null;
 
@@ -58,6 +60,8 @@
     @Override
     public void onSessionModifyResponseReceived(int status, VideoProfile requestedProfile,
             VideoProfile responseProfile) {
+        mResponseStatus = status;
+        mRequestedProfile = requestedProfile;
         mResponseProfile = responseProfile;
     }
 
@@ -164,7 +168,16 @@
     }
 
     /**
-     * Returns the last received response video profile.
+     * Returns the last {@code requestedProfile} received via onSessionModifyResponseReceived.
+     *
+     * @return The video profile.
+     */
+    public VideoProfile getRequestedProfile() {
+        return mRequestedProfile;
+    }
+
+    /**
+     * Returns the last {@code responseProfile} received via onSessionModifyResponseReceived.
      *
      * @return The video profile.
      */
@@ -173,6 +186,15 @@
     }
 
     /**
+     * Returns the last {@code status} received via onSessionModifyResponseReceived..
+     *
+     * @return The response status.
+     */
+    public int getResponseStatus() {
+        return mResponseStatus;
+    }
+
+    /**
      * Returns the last requested video profile.
      *
      * @return The video profile.
diff --git a/tests/tests/telecom/src/android/telecom/cts/MockVideoProvider.java b/tests/tests/telecom/src/android/telecom/cts/MockVideoProvider.java
index a1b6b65..6a0d874 100644
--- a/tests/tests/telecom/src/android/telecom/cts/MockVideoProvider.java
+++ b/tests/tests/telecom/src/android/telecom/cts/MockVideoProvider.java
@@ -17,7 +17,9 @@
 package android.telecom.cts;
 
 import android.net.Uri;
+import android.os.RemoteException;
 import android.telecom.Connection;
+import android.telecom.RemoteConnection;
 import android.telecom.VideoProfile;
 import android.view.Surface;
 
@@ -48,6 +50,7 @@
     private Surface mPreviewSurface = null;
     private Surface mDisplaySurface = null;
     private VideoProfile mSessionModifyResponse = null;
+    private BaseTelecomTestWithMockServices.InvokeCounter mVideoProviderHandlerTracker;
 
     public MockVideoProvider(MockConnection mockConnection) {
         mMockConnection = mockConnection;
@@ -75,6 +78,10 @@
 
     @Override
     public void onSetZoom(float value) {
+        if (mVideoProviderHandlerTracker != null) {
+            mVideoProviderHandlerTracker.invoke();
+            return;
+        }
         mZoom = value;
     }
 
@@ -135,6 +142,17 @@
     }
 
     /**
+     * Waits until all messages in the VideoProvider message handler up to the point of this call
+     * have been cleared and processed. Use this to wait for the callback to actually register.
+     */
+    public void waitForVideoProviderHandler(RemoteConnection.VideoProvider remoteVideoProvider) {
+        mVideoProviderHandlerTracker =
+                new BaseTelecomTestWithMockServices.InvokeCounter("WaitForHandler");
+        remoteVideoProvider.setZoom(0);
+        mVideoProviderHandlerTracker.waitForCount(1);
+        mVideoProviderHandlerTracker = null;
+    }
+    /**
      * Sends a mock video quality value from the provider.
      *
      * @param videoQuality The video quality.
@@ -170,6 +188,18 @@
         super.receiveSessionModifyRequest(request);
     }
 
+    /**
+     * Sends a mock session modify response from the provider.
+     *
+     * @param status The response status.
+     * @param requestProfile The request video profile.
+     * @param responseProfile The response video profile.
+     */
+    public void sendMockSessionModifyResponse(int status, VideoProfile requestProfile,
+            VideoProfile responseProfile) {
+        super.receiveSessionModifyResponse(status, requestProfile, responseProfile);
+    }
+
     public int getDeviceOrientation() {
         return mDeviceOrientation;
     }
@@ -189,4 +219,8 @@
     public VideoProfile getSessionModifyResponse() {
         return mSessionModifyResponse;
     }
+
+    public Uri getPauseImageUri() {
+        return mPauseImageUri;
+    }
 }
diff --git a/tests/tests/telecom/src/android/telecom/cts/PhoneAccountOperationsTest.java b/tests/tests/telecom/src/android/telecom/cts/PhoneAccountOperationsTest.java
index cc03288..4374516 100644
--- a/tests/tests/telecom/src/android/telecom/cts/PhoneAccountOperationsTest.java
+++ b/tests/tests/telecom/src/android/telecom/cts/PhoneAccountOperationsTest.java
@@ -22,6 +22,7 @@
 import android.content.Context;
 import android.graphics.Color;
 import android.net.Uri;
+import android.os.Bundle;
 import android.telecom.PhoneAccount;
 import android.telecom.PhoneAccountHandle;
 import android.telecom.TelecomManager;
@@ -38,6 +39,16 @@
 public class PhoneAccountOperationsTest extends InstrumentationTestCase {
     public static final PhoneAccountHandle TEST_PHONE_ACCOUNT_HANDLE =
             new PhoneAccountHandle(new ComponentName(PACKAGE, COMPONENT), ACCOUNT_ID);
+    public static final Bundle TEST_BUNDLE = createTestBundle();
+    public static final int TEST_LENGTH = 10;
+    public static final String TEST_ENCODING = "enUS";
+
+    private static Bundle createTestBundle() {
+        Bundle testBundle = new Bundle();
+        testBundle.putInt(PhoneAccount.EXTRA_CALL_SUBJECT_MAX_LENGTH, TEST_LENGTH);
+        testBundle.putString(PhoneAccount.EXTRA_CALL_SUBJECT_CHARACTER_ENCODING, TEST_ENCODING);
+        return testBundle;
+    }
 
     public static final PhoneAccount TEST_SIM_PHONE_ACCOUNT = PhoneAccount.builder(
             TEST_PHONE_ACCOUNT_HANDLE, ACCOUNT_LABEL)
@@ -59,6 +70,7 @@
             .setShortDescription(ACCOUNT_LABEL)
             .setSupportedUriSchemes(Arrays.asList(
                     PhoneAccount.SCHEME_TEL, PhoneAccount.SCHEME_VOICEMAIL))
+            .setExtras(TEST_BUNDLE)
             .build();
 
     public static final PhoneAccount TEST_CALL_MANAGER_PHONE_ACCOUNT = PhoneAccount.builder(
@@ -185,6 +197,22 @@
                         PhoneAccount.CAPABILITY_VIDEO_CALLING));
     }
 
+    public void testRegisterPhoneAccount_CheckExtras() throws Exception {
+        if (!shouldTestTelecom(mContext)) {
+            return;
+        }
+        mTelecomManager.registerPhoneAccount(TEST_NO_SIM_PHONE_ACCOUNT);
+        PhoneAccount retrievedPhoneAccount = mTelecomManager.getPhoneAccount(
+                TEST_PHONE_ACCOUNT_HANDLE);
+        Bundle extras = retrievedPhoneAccount.getExtras();
+        assertTrue(extras.containsKey(PhoneAccount.EXTRA_CALL_SUBJECT_CHARACTER_ENCODING));
+        assertEquals(TEST_ENCODING,
+                extras.getString(PhoneAccount.EXTRA_CALL_SUBJECT_CHARACTER_ENCODING));
+        assertTrue(extras.containsKey(PhoneAccount.EXTRA_CALL_SUBJECT_MAX_LENGTH));
+        assertEquals(TEST_LENGTH,
+                extras.getInt(PhoneAccount.EXTRA_CALL_SUBJECT_MAX_LENGTH));
+    }
+
     public void testRegisterPhoneAccount_CheckURISchemeSupported() throws Exception {
         if (!shouldTestTelecom(mContext)) {
             return;
diff --git a/tests/tests/telecom/src/android/telecom/cts/RemoteConferenceTest.java b/tests/tests/telecom/src/android/telecom/cts/RemoteConferenceTest.java
index 787966a..42c963f 100644
--- a/tests/tests/telecom/src/android/telecom/cts/RemoteConferenceTest.java
+++ b/tests/tests/telecom/src/android/telecom/cts/RemoteConferenceTest.java
@@ -402,6 +402,7 @@
         mRemoteConferenceObject.unregisterCallback(callback);
     }
 
+
     public void testRemoteConferenceCallbacks_Extras() {
         if (!mShouldTestTelecom) {
             return;
@@ -425,7 +426,7 @@
         mRemoteConference.setExtras(extras);
         callbackInvoker.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
         assertEquals(mRemoteConferenceObject, callbackInvoker.getArgs(0)[0]);
-        assertEquals(extras, callbackInvoker.getArgs(0)[1]);
+        assertTrue(areBundlesEqual(extras, (Bundle) callbackInvoker.getArgs(0)[1]));
         mRemoteConferenceObject.unregisterCallback(callback);
     }
 
diff --git a/tests/tests/telecom/src/android/telecom/cts/RemoteConnectionTest.java b/tests/tests/telecom/src/android/telecom/cts/RemoteConnectionTest.java
index 8b94c5e1..eb9e055 100644
--- a/tests/tests/telecom/src/android/telecom/cts/RemoteConnectionTest.java
+++ b/tests/tests/telecom/src/android/telecom/cts/RemoteConnectionTest.java
@@ -238,7 +238,6 @@
         assertEquals(mRemoteConnectionObject, callbackInvoker.getArgs(0)[0]);
         assertEquals(capabilities, callbackInvoker.getArgs(0)[1]);
         mRemoteConnectionObject.unregisterCallback(callback);
-
     }
 
     public void testRemoteConnectionCallbacks_PostDialWait() {
@@ -525,9 +524,8 @@
         mRemoteConnection.setExtras(extras);
         callbackInvoker.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
         assertEquals(mRemoteConnectionObject, callbackInvoker.getArgs(0)[0]);
-        assertEquals(extras, callbackInvoker.getArgs(0)[1]);
+        assertTrue(areBundlesEqual(extras, (Bundle) callbackInvoker.getArgs(0)[1]));
         mRemoteConnectionObject.unregisterCallback(callback);
-
     }
 
     public void testRemoteConnectionCallbacks_Disconnect() {
@@ -619,6 +617,7 @@
         };
         remoteVideoProvider.registerCallback(videoCallback);
         VideoProfile videoProfile = new VideoProfile(VideoProfile.STATE_BIDIRECTIONAL);
+        mockVideoProvider.waitForVideoProviderHandler(remoteVideoProvider);
         mockVideoProvider.sendMockSessionModifyRequest(videoProfile);
         callbackInvoker.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
         assertEquals(remoteVideoProvider, callbackInvoker.getArgs(0)[0]);
@@ -647,6 +646,7 @@
             }
         };
         remoteVideoProvider.registerCallback(videoCallback);
+        mockVideoProvider.waitForVideoProviderHandler(remoteVideoProvider);
         mockVideoProvider.handleCallSessionEvent(Connection.VideoProvider.SESSION_EVENT_RX_PAUSE);
         callbackInvoker.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
         assertEquals(remoteVideoProvider, callbackInvoker.getArgs(0)[0]);
@@ -677,6 +677,7 @@
         };
         remoteVideoProvider.registerCallback(videoCallback);
         final int width = 100, heigth = 20;
+        mockVideoProvider.waitForVideoProviderHandler(remoteVideoProvider);
         mockVideoProvider.changePeerDimensions(width, heigth);
         callbackInvoker.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
         assertEquals(remoteVideoProvider, callbackInvoker.getArgs(0)[0]);
@@ -708,6 +709,7 @@
         remoteVideoProvider.registerCallback(videoCallback);
         callbackInvoker.waitForCount(WAIT_FOR_STATE_CHANGE_TIMEOUT_CALLBACK);
         long callDataUsage = 10000;
+        mockVideoProvider.waitForVideoProviderHandler(remoteVideoProvider);
         mockVideoProvider.setCallDataUsage(callDataUsage);
         callbackInvoker.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
         assertEquals(remoteVideoProvider, callbackInvoker.getArgs(0)[0]);
@@ -739,6 +741,7 @@
         };
         remoteVideoProvider.registerCallback(videoCallback);
         VideoProfile.CameraCapabilities capabilities = new VideoProfile.CameraCapabilities(100, 200);
+        mockVideoProvider.waitForVideoProviderHandler(remoteVideoProvider);
         mockVideoProvider.changeCameraCapabilities(capabilities);
         callbackInvoker.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
         assertEquals(remoteVideoProvider, callbackInvoker.getArgs(0)[0]);
@@ -768,6 +771,7 @@
         };
         remoteVideoProvider.registerCallback(videoCallback);
         final int videoQuality = 10;
+        mockVideoProvider.waitForVideoProviderHandler(remoteVideoProvider);
         mockVideoProvider.changeVideoQuality(videoQuality);
         callbackInvoker.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
         assertEquals(remoteVideoProvider, callbackInvoker.getArgs(0)[0]);
diff --git a/tests/tests/telecom/src/android/telecom/cts/TelecomAvailabilityTest.java b/tests/tests/telecom/src/android/telecom/cts/TelecomAvailabilityTest.java
index cc0afe4..8163520 100644
--- a/tests/tests/telecom/src/android/telecom/cts/TelecomAvailabilityTest.java
+++ b/tests/tests/telecom/src/android/telecom/cts/TelecomAvailabilityTest.java
@@ -25,6 +25,7 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.net.Uri;
+import android.telecom.TelecomManager;
 import android.test.InstrumentationTestCase;
 import android.util.Log;
 
@@ -98,6 +99,24 @@
                 telephonyMatches);
     }
 
+    public void testTelecomCanManageBlockedNumbers() {
+        if (!shouldTestTelecom(mContext)) {
+            return;
+        }
+
+        final TelecomManager telecomManager = mContext.getSystemService(TelecomManager.class);
+        final Intent intent = telecomManager.createManageBlockedNumbersIntent();
+        assertNotNull(intent);
+
+        final List<ResolveInfo> activities =
+                mPackageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
+        assertEquals(1, activities.size());
+        for (ResolveInfo resolveInfo : activities) {
+            assertNotNull(resolveInfo.activityInfo);
+            assertEquals(TELECOM_PACKAGE_NAME, resolveInfo.activityInfo.packageName);
+        }
+    }
+
     /**
      * @return The {@link PackageInfo} of the only app named {@code PACKAGE_NAME}.
      */
diff --git a/tests/tests/telecom/src/android/telecom/cts/TestUtils.java b/tests/tests/telecom/src/android/telecom/cts/TestUtils.java
index fb36565..f259985 100644
--- a/tests/tests/telecom/src/android/telecom/cts/TestUtils.java
+++ b/tests/tests/telecom/src/android/telecom/cts/TestUtils.java
@@ -21,6 +21,7 @@
 import android.content.pm.PackageManager;
 import android.os.Build;
 import android.os.ParcelFileDescriptor;
+import android.os.Process;
 import android.telecom.PhoneAccountHandle;
 
 import java.io.BufferedReader;
@@ -38,7 +39,7 @@
 
     // Non-final to allow modification by tests not in this package (e.g. permission-related
     // tests in the Telecom2 test package.
-    public static String PACKAGE = "com.android.cts.telecom";
+    public static String PACKAGE = "android.telecom.cts";
     public static final String COMPONENT = "android.telecom.cts.CtsConnectionService";
     public static final String REMOTE_COMPONENT = "android.telecom.cts.CtsRemoteConnectionService";
     public static final String ACCOUNT_ID = "xtstest_CALL_PROVIDER_ID";
@@ -59,6 +60,7 @@
 
     public static final String MERGE_CALLER_NAME = "calls-merged";
     public static final String SWAP_CALLER_NAME = "calls-swapped";
+    private static final String PRIMARY_USER_SN = "0";
 
     public static boolean shouldTestTelecom(Context context) {
         if (!HAS_TELECOM) {
@@ -87,7 +89,7 @@
         final ComponentName component = handle.getComponentName();
         executeShellCommand(instrumentation, COMMAND_ENABLE
                 + component.getPackageName() + "/" + component.getClassName() + " "
-                + handle.getId());
+                + handle.getId() + " " + PRIMARY_USER_SN);
     }
 
     public static void registerSimPhoneAccount(Instrumentation instrumentation,
@@ -95,7 +97,7 @@
         final ComponentName component = handle.getComponentName();
         executeShellCommand(instrumentation, COMMAND_REGISTER_SIM
                 + component.getPackageName() + "/" + component.getClassName() + " "
-                + handle.getId() + " " + label + " " + address);
+                + handle.getId() + " " + PRIMARY_USER_SN + " " + label + " " + address);
     }
 
     /**
diff --git a/tests/tests/telecom/src/android/telecom/cts/VideoCallTest.java b/tests/tests/telecom/src/android/telecom/cts/VideoCallTest.java
index fbfa998..9f79628 100644
--- a/tests/tests/telecom/src/android/telecom/cts/VideoCallTest.java
+++ b/tests/tests/telecom/src/android/telecom/cts/VideoCallTest.java
@@ -17,8 +17,10 @@
 package android.telecom.cts;
 
 import android.graphics.SurfaceTexture;
+import android.net.Uri;
 import android.telecom.Call;
 import android.telecom.Connection;
+import android.telecom.Connection.VideoProvider;
 import android.telecom.InCallService;
 import android.telecom.VideoProfile;
 import android.util.Log;
@@ -168,6 +170,58 @@
     }
 
     /**
+     * Test handling of session modify responses.
+     */
+    public void testReceiveSessionModifyResponse() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        VideoProfile fromVideoProfile = new VideoProfile(VideoProfile.STATE_AUDIO_ONLY);
+        VideoProfile toVideoProfile = new VideoProfile(VideoProfile.STATE_BIDIRECTIONAL);
+
+        placeAndVerifyCall(VideoProfile.STATE_AUDIO_ONLY);
+        final MockConnection connection = verifyConnectionForOutgoingCall();
+
+        final MockInCallService inCallService = mInCallCallbacks.getService();
+        final Call call = inCallService.getLastCall();
+        final MockVideoProvider mockVideoProvider = connection.getMockVideoProvider();
+        assertVideoCallbackRegistered(inCallService, call, true);
+
+        final MockVideoCallCallback callback = inCallService.getVideoCallCallback(call);
+
+        mockVideoProvider.sendMockSessionModifyResponse(
+                VideoProvider.SESSION_MODIFY_REQUEST_SUCCESS, fromVideoProfile,
+                toVideoProfile);
+        assertRequestReceived(callback, VideoProvider.SESSION_MODIFY_REQUEST_SUCCESS,
+                fromVideoProfile, toVideoProfile);
+
+        mockVideoProvider.sendMockSessionModifyResponse(
+                VideoProvider.SESSION_MODIFY_REQUEST_FAIL, fromVideoProfile,
+                toVideoProfile);
+        assertRequestReceived(callback, VideoProvider.SESSION_MODIFY_REQUEST_FAIL,
+                fromVideoProfile, toVideoProfile);
+
+        mockVideoProvider.sendMockSessionModifyResponse(
+                VideoProvider.SESSION_MODIFY_REQUEST_INVALID, fromVideoProfile,
+                toVideoProfile);
+        assertRequestReceived(callback, VideoProvider.SESSION_MODIFY_REQUEST_INVALID,
+                fromVideoProfile, toVideoProfile);
+
+        mockVideoProvider.sendMockSessionModifyResponse(
+                VideoProvider.SESSION_MODIFY_REQUEST_REJECTED_BY_REMOTE, fromVideoProfile,
+                toVideoProfile);
+        assertRequestReceived(callback, VideoProvider.SESSION_MODIFY_REQUEST_REJECTED_BY_REMOTE,
+                fromVideoProfile, toVideoProfile);
+
+        mockVideoProvider.sendMockSessionModifyResponse(
+                VideoProvider.SESSION_MODIFY_REQUEST_TIMED_OUT, fromVideoProfile,
+                toVideoProfile);
+        assertRequestReceived(callback, VideoProvider.SESSION_MODIFY_REQUEST_TIMED_OUT,
+                fromVideoProfile, toVideoProfile);
+    }
+
+    /**
      * Tests ability to start a video call, delaying the creation of the provider until after
      * the call has been initiated (rather than immediately when the call is created).  This more
      * closely mimics the lifespan of a {@code VideoProvider} instance as it is reasonable to
@@ -193,8 +247,8 @@
             // registered.
             assertVideoCallbackRegistered(inCallService, call, false);
 
-            // Trigger delayed creation of video provider and registration of callbacks and assert that
-            // it happened.
+            // Trigger delayed creation of video provider and registration of callbacks and assert
+            // that it happened.
             connection.createMockVideoProvider();
             assertVideoCallbackRegistered(inCallService, call, true);
 
@@ -340,6 +394,56 @@
                                 Connection.VideoProvider.SESSION_EVENT_CAMERA_READY);
                     }
                 });
+
+        assertCallSessionEventReceived(inCallService.getVideoCallCallback(call),
+                Connection.VideoProvider.SESSION_EVENT_CAMERA_FAILURE,
+                new Work() {
+                    @Override
+                    public void doWork() {
+                        connection.sendMockCallSessionEvent(
+                                Connection.VideoProvider.SESSION_EVENT_CAMERA_FAILURE);
+                    }
+                });
+
+        assertCallSessionEventReceived(inCallService.getVideoCallCallback(call),
+                Connection.VideoProvider.SESSION_EVENT_TX_START,
+                new Work() {
+                    @Override
+                    public void doWork() {
+                        connection.sendMockCallSessionEvent(
+                                Connection.VideoProvider.SESSION_EVENT_TX_START);
+                    }
+                });
+
+        assertCallSessionEventReceived(inCallService.getVideoCallCallback(call),
+                Connection.VideoProvider.SESSION_EVENT_TX_STOP,
+                new Work() {
+                    @Override
+                    public void doWork() {
+                        connection.sendMockCallSessionEvent(
+                                Connection.VideoProvider.SESSION_EVENT_TX_STOP);
+                    }
+                });
+
+        assertCallSessionEventReceived(inCallService.getVideoCallCallback(call),
+                Connection.VideoProvider.SESSION_EVENT_RX_PAUSE,
+                new Work() {
+                    @Override
+                    public void doWork() {
+                        connection.sendMockCallSessionEvent(
+                                Connection.VideoProvider.SESSION_EVENT_RX_PAUSE);
+                    }
+                });
+
+        assertCallSessionEventReceived(inCallService.getVideoCallCallback(call),
+                Connection.VideoProvider.SESSION_EVENT_RX_RESUME,
+                new Work() {
+                    @Override
+                    public void doWork() {
+                        connection.sendMockCallSessionEvent(
+                                Connection.VideoProvider.SESSION_EVENT_RX_RESUME);
+                    }
+                });
     }
 
     /**
@@ -469,6 +573,25 @@
         call.disconnect();
     }
 
+    public void testSetPauseImage() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        placeAndVerifyCall(VideoProfile.STATE_BIDIRECTIONAL);
+        final MockConnection connection = verifyConnectionForOutgoingCall();
+
+        final MockInCallService inCallService = mInCallCallbacks.getService();
+        final Call call = inCallService.getLastCall();
+        assertVideoCallbackRegistered(inCallService, call, true);
+        final MockVideoProvider mockVideoProvider = connection.getMockVideoProvider();
+        final InCallService.VideoCall videoCall = call.getVideoCall();
+
+        final Uri pauseImageUri = Uri.fromParts("file", "test.png", "");
+        videoCall.setPauseImage(pauseImageUri);
+        assertPauseUriChanged(mockVideoProvider, pauseImageUri);
+    }
+
     /**
      * Asserts that a call video state is as expected.
      *
@@ -760,6 +883,31 @@
     }
 
     /**
+     * Asserts whether the pause image URI has changed to the expected value.
+     *
+     * @param mockVideoProvider The mock video provider.
+     * @param expected The expected URI.
+     */
+    private void assertPauseUriChanged(final MockVideoProvider mockVideoProvider,
+            final Uri expected) {
+        waitUntilConditionIsTrueOrTimeout(
+                new Condition() {
+                    @Override
+                    public Object expected() {
+                        return expected;
+                    }
+
+                    @Override
+                    public Object actual() {
+                        return mockVideoProvider.getPauseImageUri();
+                    }
+                },
+                TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+                "Pause image URI should be " + expected
+        );
+    }
+
+    /**
      * Asserts whether a response video profile has been received
      *
      * @param videoCallCallback The video call callback.
@@ -839,4 +987,60 @@
                 "Session modify response video state should be " + expected
         );
     }
+
+    /**
+     * Asserts whether a session modify response has been received with the expected values.
+     *
+     * @param videoCallCallback The video call callback.
+     * @param expectedResponseStatus The expected status.
+     * @param expectedFromProfile The expected from profile.
+     * @param expectedToProfile The expected to profile.
+     */
+    private void assertRequestReceived(final MockVideoCallCallback videoCallCallback,
+            final int expectedResponseStatus, final VideoProfile expectedFromProfile,
+            final VideoProfile expectedToProfile) {
+
+        final String expected = buildRequestString(expectedResponseStatus, expectedFromProfile,
+                expectedToProfile);
+
+        waitUntilConditionIsTrueOrTimeout(
+                new Condition() {
+                    @Override
+                    public Object expected() {
+                        return expected;
+                    }
+
+                    @Override
+                    public Object actual() {
+                        int responseStatus = videoCallCallback.getResponseStatus();
+                        VideoProfile fromProfile = videoCallCallback.getRequestedProfile();
+                        VideoProfile toProfile = videoCallCallback.getResponseProfile();
+                        return buildRequestString(responseStatus, fromProfile, toProfile);
+                    }
+                },
+                TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+                "Session modify response should match expected."
+        );
+    }
+
+    /**
+     * Creates a string representation of the parameters passed to
+     * {@link android.telecom.InCallService.VideoCall.Callback#onSessionModifyResponseReceived(int,
+     * VideoProfile, VideoProfile)}.
+     *
+     * @param status The status.
+     * @param fromProfile The from profile.
+     * @param toProfile The to profile.
+     * @return String representation.
+     */
+    private String buildRequestString(int status, VideoProfile fromProfile, VideoProfile toProfile) {
+        StringBuilder expectedSb = new StringBuilder();
+        expectedSb.append("Status: ");
+        expectedSb.append(status);
+        expectedSb.append(" From: ");
+        expectedSb.append(fromProfile);
+        expectedSb.append(" To: ");
+        expectedSb.append(toProfile);
+        return expectedSb.toString();
+    }
 }
diff --git a/tests/tests/telecom2/Android.mk b/tests/tests/telecom2/Android.mk
index 71edb7b..c16a9dd 100644
--- a/tests/tests/telecom2/Android.mk
+++ b/tests/tests/telecom2/Android.mk
@@ -27,7 +27,7 @@
 LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
 
 src_dirs := src \
-    ../telecom/src
+    ../telecom/src/android/telecom/cts/TestUtils.java
 
 res_dirs := res \
     ../telecom/res
@@ -38,9 +38,12 @@
 
 LOCAL_AAPT_FLAGS := \
     --auto-add-overlay \
-    --extra-packages com.android.cts.telecom \
-    --rename-manifest-package com.android.cts.telecom2 \
+    --extra-packages android.telecom.cts \
+    --rename-manifest-package android.telecom2.cts \
 
 LOCAL_SDK_VERSION := current
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/telecom2/AndroidManifest.xml b/tests/tests/telecom2/AndroidManifest.xml
index e618768..50c6945 100644
--- a/tests/tests/telecom2/AndroidManifest.xml
+++ b/tests/tests/telecom2/AndroidManifest.xml
@@ -15,7 +15,7 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.telecom2">
+    package="android.telecom2.cts">
     <uses-sdk android:minSdkVersion="21" />
 
     <!--
@@ -74,7 +74,7 @@
     </application>
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.cts.telecom2"
+                     android:targetPackage="android.telecom2.cts"
                      android:label="CTS tests for android.telecom package">
         <meta-data android:name="listener"
             android:value="com.android.cts.runner.CtsTestRunListener" />
diff --git a/tests/tests/telecom2/AndroidTest.xml b/tests/tests/telecom2/AndroidTest.xml
new file mode 100644
index 0000000..e7ae80c
--- /dev/null
+++ b/tests/tests/telecom2/AndroidTest.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Configuration for Telecom2 Tests">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsTelecomTestCases2.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.telecom2.cts" />
+        <option name="runtime-hint" value="6m42s" />
+    </test>
+</configuration>
diff --git a/tests/tests/telephony/Android.mk b/tests/tests/telephony/Android.mk
index 85864f9..d8f152e 100644
--- a/tests/tests/telephony/Android.mk
+++ b/tests/tests/telephony/Android.mk
@@ -30,6 +30,9 @@
 
 LOCAL_PACKAGE_NAME := CtsTelephonyTestCases
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 # uncomment when b/13250611 is fixed
 #LOCAL_SDK_VERSION := current
 LOCAL_JAVA_LIBRARIES += android.test.runner
diff --git a/tests/tests/telephony/AndroidManifest.xml b/tests/tests/telephony/AndroidManifest.xml
index 15b19b7..e1905d1 100644
--- a/tests/tests/telephony/AndroidManifest.xml
+++ b/tests/tests/telephony/AndroidManifest.xml
@@ -15,7 +15,7 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.telephony">
+    package="android.telephony.cts">
 
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
@@ -88,7 +88,7 @@
     </application>
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.cts.telephony"
+                     android:targetPackage="android.telephony.cts"
                      android:label="CTS tests of android.telephony">
         <meta-data android:name="listener"
             android:value="com.android.cts.runner.CtsTestRunListener" />
diff --git a/tests/tests/telephony/AndroidTest.xml b/tests/tests/telephony/AndroidTest.xml
new file mode 100644
index 0000000..2e6011b
--- /dev/null
+++ b/tests/tests/telephony/AndroidTest.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS Telephony test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.TokenRequirement">
+        <option name="token" value="sim-card" />
+    </target_preparer>
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsTelephonyTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.telephony.cts" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/tests/telephony/src/android/telephony/cts/CarrierConfigManagerTest.java b/tests/tests/telephony/src/android/telephony/cts/CarrierConfigManagerTest.java
index 4ca35b8..fdb1f68 100644
--- a/tests/tests/telephony/src/android/telephony/cts/CarrierConfigManagerTest.java
+++ b/tests/tests/telephony/src/android/telephony/cts/CarrierConfigManagerTest.java
@@ -64,6 +64,20 @@
             // Static default in CarrierConfigManager will be returned when no sim card present.
             assertEquals("Config doesn't match static default.",
                     config.getBoolean(CarrierConfigManager.KEY_ADDITIONAL_CALL_SETTING_BOOL), true);
+
+            assertEquals("KEY_VVM_DESTINATION_NUMBER_STRING doesn't match static default.",
+                config.getString(CarrierConfigManager.KEY_VVM_DESTINATION_NUMBER_STRING), "");
+            assertEquals("KEY_VVM_PORT_NUMBER_INT doesn't match static default.",
+                config.getInt(CarrierConfigManager.KEY_VVM_PORT_NUMBER_INT), 0);
+            assertEquals("KEY_VVM_TYPE_STRING doesn't match static default.",
+                config.getString(CarrierConfigManager.KEY_VVM_TYPE_STRING), "");
+            assertEquals("KEY_VVM_CELLULAR_DATA_REQUIRED_BOOLEAN doesn't match static default.",
+                config.getBoolean(CarrierConfigManager.KEY_VVM_CELLULAR_DATA_REQUIRED_BOOLEAN),
+                false);
+            assertEquals("KEY_VVM_PREFETCH_BOOLEAN doesn't match static default.",
+                config.getBoolean(CarrierConfigManager.KEY_VVM_PREFETCH_BOOLEAN), true);
+            assertEquals("KEY_CARRIER_VVM_PACKAGE_NAME_STRING doesn't match static default.",
+                config.getString(CarrierConfigManager.KEY_CARRIER_VVM_PACKAGE_NAME_STRING), "");
         }
     }
 
@@ -74,7 +88,7 @@
 
     public void testGetConfigForSubId() {
         PersistableBundle config =
-                mConfigManager.getConfigForSubId(SubscriptionManager.getDefaultSubId());
+                mConfigManager.getConfigForSubId(SubscriptionManager.getDefaultSubscriptionId());
         checkConfig(config);
     }
 
@@ -86,7 +100,8 @@
     public void testNotifyConfigChangedForSubId() {
         try {
             if (isSimCardPresent()) {
-                mConfigManager.notifyConfigChangedForSubId(SubscriptionManager.getDefaultSubId());
+                mConfigManager.notifyConfigChangedForSubId(
+                        SubscriptionManager.getDefaultSubscriptionId());
                 fail("Expected SecurityException. App doesn't have carrier privileges.");
             }
         } catch (SecurityException expected) {
diff --git a/tests/tests/telephony/src/android/telephony/cts/CellInfoTest.java b/tests/tests/telephony/src/android/telephony/cts/CellInfoTest.java
index be29794..2a198b6 100644
--- a/tests/tests/telephony/src/android/telephony/cts/CellInfoTest.java
+++ b/tests/tests/telephony/src/android/telephony/cts/CellInfoTest.java
@@ -22,6 +22,7 @@
 import android.telephony.CellInfoGsm;
 import android.telephony.CellInfoLte;
 import android.telephony.CellInfoWcdma;
+import android.telephony.CellSignalStrengthLte;
 import android.telephony.TelephonyManager;
 import android.test.AndroidTestCase;
 import android.util.Log;
@@ -40,7 +41,7 @@
     private static ConnectivityManager mCm;
     private static final String TAG = "android.telephony.cts.CellInfoTest";
     // Maximum and minimum possible RSSI values(in dbm).
-    private static final int MAX_RRSI = -10;
+    private static final int MAX_RSSI = -10;
     private static final int MIN_RSSI = -150;
     private PackageManager mPm;
 
@@ -85,7 +86,10 @@
                 verifyGsmInfo((CellInfoGsm) cellInfo);
             }
         }
-        // At most two cells could be registered.
+
+        //FIXME: The maximum needs to be calculated based on the number of
+        //       radios and the technologies used (ex SRLTE); however, we have
+        //       not hit any of these cases yet.
         assertTrue("None or too many registered cells : " + numRegisteredCells,
                 numRegisteredCells > 0 && numRegisteredCells <= 2);
     }
@@ -98,6 +102,15 @@
         int pci = lte.getCellIdentity().getPci();
         // Physical cell id should be within [0, 503].
         assertTrue("getPci() out of range [0, 503]", pci >= 0 && pci <= 503);
+
+        int earfcn = lte.getCellIdentity().getEarfcn();
+        // Reference 3GPP 36.101 Table 5.7.3-1
+        assertTrue("getEarfcn() out of range [0,47000]", earfcn >= 0 && earfcn <= 47000);
+
+        int ta = ((CellSignalStrengthLte)lte.getCellSignalStrength()).getTimingAdvance();
+        //Integer.MAX_VALUE indicates an unavailable field
+        assertTrue("getTimingAdvance() invalid [0-1282] | Integer.MAX_VALUE",
+                ta == Integer.MAX_VALUE || (ta >= 0 && ta <=1282));
     }
 
     // Verify wcdma cell information is within correct range.
@@ -107,6 +120,10 @@
         // Primary scrambling code should be within [0, 511].
         int psc = wcdma.getCellIdentity().getPsc();
         assertTrue("getPsc() out of range [0, 511]", psc >= 0 && psc <= 511);
+
+        int uarfcn = wcdma.getCellIdentity().getUarfcn();
+        // Reference 3GPP 25.101 Table 5.2
+        assertTrue("getUarfcn() out of range [400,11000]", uarfcn >= 400 && uarfcn <= 11000);
     }
 
     // Verify gsm cell information is within correct range.
@@ -118,11 +135,18 @@
         assertTrue("getLac() out of range [0, 65535]", lac >= 0 && lac <= 65535);
         int cid = gsm.getCellIdentity().getCid();
         assertTrue("getCid() out range [0, 65535]", cid >= 0 && cid <= 65535);
+
+        int arfcn = gsm.getCellIdentity().getArfcn();
+        // Reference 3GPP 45.005 Table 2-2
+        assertTrue("getArfcn() out of range [0,1024]", arfcn >= 0 && arfcn <= 1024);
+
+        int bsic = gsm.getCellIdentity().getBsic();
+        assertTrue("getBsic() out of range [0,63]", bsic >=0 && bsic <=63);
     }
 
     // Rssi(in dbm) should be within [MIN_RSSI, MAX_RSSI].
     private void verifyRssiDbm(int dbm) {
         assertTrue("getCellSignalStrength().getDbm() out of range",
-                dbm >= MIN_RSSI && dbm <= MAX_RRSI);
+                dbm >= MIN_RSSI && dbm <= MAX_RSSI);
     }
 }
diff --git a/tests/tests/telephony/src/android/telephony/cts/SimRestrictedApisTest.java b/tests/tests/telephony/src/android/telephony/cts/SimRestrictedApisTest.java
index 20810a8..0f09314 100644
--- a/tests/tests/telephony/src/android/telephony/cts/SimRestrictedApisTest.java
+++ b/tests/tests/telephony/src/android/telephony/cts/SimRestrictedApisTest.java
@@ -74,7 +74,7 @@
     public void testSetLine1NumberForDisplay2() {
         try {
             if (isSimCardPresent()) {
-                TelephonyManager.getDefault().setLine1NumberForDisplayForSubscriber(0, "", "");
+                TelephonyManager.getDefault().setLine1NumberForDisplay(0, "", "");
                 fail("Expected SecurityException. App doesn't have carrier privileges.");
             }
         } catch (SecurityException expected) {
diff --git a/tests/tests/telephony/src/android/telephony/cts/SmsMessageTest.java b/tests/tests/telephony/src/android/telephony/cts/SmsMessageTest.java
index 2db9ba1..2406ad8 100644
--- a/tests/tests/telephony/src/android/telephony/cts/SmsMessageTest.java
+++ b/tests/tests/telephony/src/android/telephony/cts/SmsMessageTest.java
@@ -66,6 +66,9 @@
         "Long dkkshsh jdjsusj kbsksbdf jfkhcu hhdiwoqiwyrygrvn?*?*!\";:'/,."
         + "__?9#9292736&4;\"$+$+((]\\[\\℅©℅™^®°¥°¥=¢£}}£∆~¶~÷|√×."
         + " 😯😆😉😇😂😀👕🎓😀👙🐕🐀🐶🐰🐩⛪⛲ ";
+    private static final String LONG_TEXT_WITH_FLAGS =
+        "🇦🇫🇦🇽🇦🇱🇩🇿🇦🇸🇦🇩🇦🇴🇦🇮🇦🇶🇦🇬🇦🇷🇦🇲🇦🇼🇦🇨"
+        + "🇦🇺🇦🇹🇦🇿🇧🇸🇧🇭🇧🇩🇧🇧🇧🇾🇧🇪🇧🇿🇧🇯🇧🇲🇧🇹🇧🇴🇧🇦";
 
     @Override
     protected void setUp() throws Exception {
@@ -317,6 +320,14 @@
         assertEquals(SmsMessage.ENCODING_16BIT, result[3]);
     }
 
+    public void testCalculateLengthFlags() throws Exception {
+        if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
+            return;
+        }
+        int[] result = SmsMessage.calculateLength(LONG_TEXT_WITH_FLAGS, false);
+        assertEquals(2, result[0]);
+    }
+
     private final static char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
             'A', 'B', 'C', 'D', 'E', 'F' };
 
diff --git a/tests/tests/telephony/src/android/telephony/cts/TelephonyManagerTest.java b/tests/tests/telephony/src/android/telephony/cts/TelephonyManagerTest.java
index 8b94d00..366e061 100644
--- a/tests/tests/telephony/src/android/telephony/cts/TelephonyManagerTest.java
+++ b/tests/tests/telephony/src/android/telephony/cts/TelephonyManagerTest.java
@@ -19,13 +19,15 @@
 import android.bluetooth.BluetoothAdapter;
 import android.content.Context;
 import android.content.pm.PackageManager;
-import android.cts.util.ReadElf;
 import android.cts.util.TestThread;
 import android.net.ConnectivityManager;
 import android.net.wifi.WifiInfo;
 import android.net.wifi.WifiManager;
 import android.os.Build;
 import android.os.Looper;
+import android.telecom.PhoneAccount;
+import android.telecom.PhoneAccountHandle;
+import android.telecom.TelecomManager;
 import android.telephony.CellLocation;
 import android.telephony.PhoneStateListener;
 import android.telephony.TelephonyManager;
@@ -49,8 +51,8 @@
     protected void setUp() throws Exception {
         super.setUp();
         mTelephonyManager =
-            (TelephonyManager)getContext().getSystemService(Context.TELEPHONY_SERVICE);
-        mCm = (ConnectivityManager)getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
+                (TelephonyManager) getContext().getSystemService(Context.TELEPHONY_SERVICE);
+        mCm = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
     }
 
     @Override
@@ -163,6 +165,13 @@
         mTelephonyManager.getDeviceId(mTelephonyManager.getDefaultSim());
         mTelephonyManager.getDeviceSoftwareVersion();
         mTelephonyManager.getPhoneCount();
+
+        TelecomManager telecomManager = (TelecomManager) getContext()
+            .getSystemService(Context.TELECOM_SERVICE);
+        PhoneAccountHandle defaultAccount = telecomManager
+            .getDefaultOutgoingPhoneAccount(PhoneAccount.SCHEME_TEL);
+        mTelephonyManager.getVoicemailRingtoneUri(defaultAccount);
+        mTelephonyManager.isVoicemailVibrationEnabled(defaultAccount);
     }
 
     /**
diff --git a/tests/tests/telephony2/Android.mk b/tests/tests/telephony2/Android.mk
index f405210..dbd2559 100644
--- a/tests/tests/telephony2/Android.mk
+++ b/tests/tests/telephony2/Android.mk
@@ -28,6 +28,9 @@
 
 LOCAL_PACKAGE_NAME := CtsTelephony2TestCases
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_JAVA_LIBRARIES += android.test.runner
 
 include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/telephony2/AndroidManifest.xml b/tests/tests/telephony2/AndroidManifest.xml
index 369f75e..6b8ec0c 100644
--- a/tests/tests/telephony2/AndroidManifest.xml
+++ b/tests/tests/telephony2/AndroidManifest.xml
@@ -15,7 +15,7 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.telephony2">
+    package="android.telephony2.cts">
 
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
 
@@ -24,7 +24,7 @@
     </application>
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.cts.telephony2">
+                     android:targetPackage="android.telephony2.cts">
         <meta-data android:name="listener"
             android:value="com.android.cts.runner.CtsTestRunListener" />
     </instrumentation>
diff --git a/tests/tests/telephony2/AndroidTest.xml b/tests/tests/telephony2/AndroidTest.xml
new file mode 100644
index 0000000..45ee5fa
--- /dev/null
+++ b/tests/tests/telephony2/AndroidTest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS Telephony test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsTelephony2TestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.telephony2.cts" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/tests/text/Android.mk b/tests/tests/text/Android.mk
index 7b2def1..65a93fb 100644
--- a/tests/tests/text/Android.mk
+++ b/tests/tests/text/Android.mk
@@ -29,6 +29,9 @@
 
 LOCAL_PACKAGE_NAME := CtsTextTestCases
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 # uncomment when dalvik.annotation.Test* are removed or part of SDK
 #LOCAL_SDK_VERSION := current
 
diff --git a/tests/tests/text/AndroidManifest.xml b/tests/tests/text/AndroidManifest.xml
index 99a6ad5..1ff9b4f 100644
--- a/tests/tests/text/AndroidManifest.xml
+++ b/tests/tests/text/AndroidManifest.xml
@@ -16,7 +16,7 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.text">
+    package="android.text.cts">
 
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <uses-permission android:name="android.permission.WRITE_SETTINGS" />
@@ -24,7 +24,8 @@
         <uses-library android:name="android.test.runner" />
 
         <activity android:name="android.text.cts.EmojiCtsActivity"
-            android:label="AvailableIntentsActivity">
+            android:label="AvailableIntentsActivity"
+            android:screenOrientation="nosensor">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
@@ -32,10 +33,14 @@
         </activity>
 
         <activity android:name="android.text.method.cts.KeyListenerCtsActivity"
-            android:label="KeyListenerCtsActivity"/>
+            android:label="KeyListenerCtsActivity"
+            android:screenOrientation="nosensor"
+            android:windowSoftInputMode="stateAlwaysHidden"
+        />
 
         <activity android:name="android.text.method.cts.CtsActivity"
-            android:label="CtsActivity">
+            android:label="CtsActivity"
+            android:screenOrientation="nosensor">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
@@ -43,7 +48,8 @@
         </activity>
 
         <activity android:name="android.text.style.cts.URLSpanCtsActivity"
-            android:label="URLSpanCtsActivity">
+            android:label="URLSpanCtsActivity"
+            android:screenOrientation="nosensor">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
@@ -54,7 +60,8 @@
             android:label="MockURLSpanTestActivity"
             android:launchMode="singleTask"
             android:alwaysRetainTaskState="true"
-            android:configChanges="orientation|keyboardHidden">
+            android:configChanges="orientation|keyboardHidden"
+            android:screenOrientation="nosensor">
             <intent-filter>
                 <action android:name="android.intent.action.VIEW" />
                 <category android:name="android.intent.category.DEFAULT" />
@@ -67,11 +74,10 @@
     </application>
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.cts.text"
+                     android:targetPackage="android.text.cts"
                      android:label="CTS tests of android.text">
         <meta-data android:name="listener"
             android:value="com.android.cts.runner.CtsTestRunListener" />
     </instrumentation>
 
 </manifest>
-
diff --git a/tests/tests/text/AndroidTest.xml b/tests/tests/text/AndroidTest.xml
new file mode 100644
index 0000000..4b9d24d
--- /dev/null
+++ b/tests/tests/text/AndroidTest.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS Text test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.WifiCheck" />
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsTextTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.text.cts" />
+        <option name="runtime-hint" value="3m8s" />
+    </test>
+</configuration>
diff --git a/tests/tests/text/res/layout/keylistener_layout.xml b/tests/tests/text/res/layout/keylistener_layout.xml
index 96a419d..cb8dbad 100644
--- a/tests/tests/text/res/layout/keylistener_layout.xml
+++ b/tests/tests/text/res/layout/keylistener_layout.xml
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  -->
-<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+<EditText xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/keylistener_textview"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
diff --git a/tests/tests/text/src/android/text/cts/BidiFormatterTest.java b/tests/tests/text/src/android/text/cts/BidiFormatterTest.java
index 5ace8b2..3e5db4d 100644
--- a/tests/tests/text/src/android/text/cts/BidiFormatterTest.java
+++ b/tests/tests/text/src/android/text/cts/BidiFormatterTest.java
@@ -33,7 +33,7 @@
             new BidiFormatter.Builder(true /* RTL context */).stereoReset(false).build();
 
     private static final String EN = "abba";
-    private static final String HE = "\u05e0\u05e1";
+    private static final String HE = "\u05E0\u05E1";
 
     private static final String LRM = "\u200E";
     private static final String RLM = "\u200F";
@@ -49,6 +49,18 @@
         assertEquals(true, BidiFormatter.getInstance(true).isRtlContext());
     }
 
+    public void testCachedInstances() {
+        // Test that we get the same cached static instances for simple cases
+        BidiFormatter defaultFormatterInstance = BidiFormatter.getInstance();
+        assertTrue(defaultFormatterInstance == LTR_FMT || defaultFormatterInstance == RTL_FMT);
+
+        assertEquals(LTR_FMT, BidiFormatter.getInstance(false));
+        assertEquals(RTL_FMT, BidiFormatter.getInstance(true));
+
+        assertEquals(LTR_FMT, BidiFormatter.getInstance(false));
+        assertEquals(RTL_FMT, BidiFormatter.getInstance(Locale.forLanguageTag("ar")));
+    }
+
     public void testBuilderIsRtlContext() {
         assertEquals(false, new BidiFormatter.Builder(false).build().isRtlContext());
         assertEquals(true, new BidiFormatter.Builder(true).build().isRtlContext());
diff --git a/tests/tests/text/src/android/text/cts/BoringLayoutTest.java b/tests/tests/text/src/android/text/cts/BoringLayoutTest.java
index 8a60a5b..13465ae 100644
--- a/tests/tests/text/src/android/text/cts/BoringLayoutTest.java
+++ b/tests/tests/text/src/android/text/cts/BoringLayoutTest.java
@@ -22,6 +22,7 @@
 import android.graphics.Bitmap.Config;
 import android.test.AndroidTestCase;
 import android.text.BoringLayout;
+import android.text.BoringLayout.Metrics;
 import android.text.Layout;
 import android.text.TextPaint;
 import android.text.TextUtils;
@@ -41,7 +42,7 @@
     private static final CharSequence DEFAULT_CHAR_SEQUENCE = "default";
     private static final TextPaint DEFAULT_PAINT = new TextPaint();
     private static final Layout.Alignment DEFAULT_ALIGN = Layout.Alignment.ALIGN_CENTER;
-    private static final BoringLayout.Metrics DEFAULT_METRICS = createMetrics(
+    private static final Metrics DEFAULT_METRICS = createMetrics(
             METRICS_TOP,
             METRICS_ASCENT,
             METRICS_DESCENT,
@@ -80,11 +81,11 @@
     }
 
     private void verifyMultAddScale(float spacingMult, float spacingAdd) {
-        final int metricsBottomToTop = METRICS_BOTTOM - METRICS_TOP;
+        final int height = METRICS_BOTTOM - METRICS_TOP;
 
         BoringLayout boringLayout = makeBoringLayout(spacingMult, spacingAdd);
-        assertEquals(metricsBottomToTop, boringLayout.getHeight());
-        assertEquals(boringLayout.getHeight() + METRICS_TOP, boringLayout.getLineDescent(0));
+        assertEquals(height, boringLayout.getHeight());
+        assertEquals(height + METRICS_TOP, boringLayout.getLineDescent(0));
     }
 
     public void testScale() {
@@ -135,7 +136,7 @@
                 DEFAULT_METRICS,
                 true);
         assertSame(mBoringLayout, layout_1);
-        layout_1 = null;
+
         layout_1 = mBoringLayout.replaceOrMake(
                 source,
                 DEFAULT_PAINT,
@@ -169,11 +170,30 @@
         assertEquals((float) DEFAULT_OUTER_WIDTH, boringLayout.getLineRight(0));
     }
 
+    public void testGetLineDescent_withIncludePadding() {
+        final int height = METRICS_BOTTOM - METRICS_TOP;
+        assertEquals(height + METRICS_TOP, mBoringLayout.getLineDescent(0));
+    }
+
+    public void testGetLineDescent_withoutIncludePadding() {
+        BoringLayout boringLayout = new BoringLayout(
+                DEFAULT_CHAR_SEQUENCE,
+                DEFAULT_PAINT,
+                DEFAULT_OUTER_WIDTH,
+                DEFAULT_ALIGN,
+                SPACING_MULT_NO_SCALE,
+                SPACING_ADD_NO_SCALE,
+                DEFAULT_METRICS,
+                false);
+
+        final int height = METRICS_DESCENT - METRICS_ASCENT;
+        assertEquals(height + METRICS_ASCENT, boringLayout.getLineDescent(0));
+    }
+
     public void testIncludePadding() {
         assertEquals(METRICS_TOP - METRICS_ASCENT, mBoringLayout.getTopPadding());
         assertEquals(METRICS_BOTTOM - METRICS_DESCENT, mBoringLayout.getBottomPadding());
         assertEquals(METRICS_BOTTOM - METRICS_TOP, mBoringLayout.getHeight());
-        assertEquals(mBoringLayout.getHeight() + METRICS_TOP, mBoringLayout.getLineDescent(0));
 
         BoringLayout boringLayout = new BoringLayout(
                 DEFAULT_CHAR_SEQUENCE,
@@ -188,14 +208,13 @@
         assertEquals(0, boringLayout.getTopPadding());
         assertEquals(0, boringLayout.getBottomPadding());
         assertEquals(METRICS_DESCENT - METRICS_ASCENT, boringLayout.getHeight());
-        assertEquals(boringLayout.getHeight() + METRICS_ASCENT, boringLayout.getLineDescent(0));
     }
 
     public void testIsBoringString() {
         TextPaint paint = new TextPaint();
         assertNotNull(BoringLayout.isBoring("hello android", paint));
 
-        BoringLayout.Metrics metrics = new BoringLayout.Metrics();
+        Metrics metrics = new Metrics();
         metrics.width = 100;
         assertNotNull(BoringLayout.isBoring("hello android", paint, metrics));
 
@@ -207,6 +226,31 @@
         assertNull(BoringLayout.isBoring("hello android\n\n\n", paint));
     }
 
+    public void testIsBoring_resetsFontMetrics() {
+        int someInt = 100;
+        String text = "some text";
+
+        TextPaint paint = new TextPaint();
+        Paint.FontMetricsInt paintMetrics = paint.getFontMetricsInt();
+        Metrics changedMetrics = new Metrics();
+        changedMetrics.top = paintMetrics.top - someInt;
+        changedMetrics.ascent = paintMetrics.ascent - someInt;
+        changedMetrics.bottom = paintMetrics.bottom + someInt;
+        changedMetrics.descent = paintMetrics.descent + someInt;
+        changedMetrics.leading = paintMetrics.leading + someInt;
+
+        Metrics expectedMetrics = BoringLayout.isBoring(text, paint, (Metrics) null);
+        Metrics actualMetrics = BoringLayout.isBoring(text, paint, changedMetrics);
+
+        assertNotNull(actualMetrics);
+        assertNotNull(expectedMetrics);
+        assertEquals(expectedMetrics.top, actualMetrics.top);
+        assertEquals(expectedMetrics.ascent, actualMetrics.ascent);
+        assertEquals(expectedMetrics.bottom, actualMetrics.bottom);
+        assertEquals(expectedMetrics.descent, actualMetrics.descent);
+        assertEquals(expectedMetrics.leading, actualMetrics.leading);
+    }
+
     public void testGetLineDirections() {
         assertNotNull(mBoringLayout.getLineDirections(0));
         assertNotNull(mBoringLayout.getLineDirections(2));
@@ -267,7 +311,7 @@
         }
     }
 
-    private static BoringLayout.Metrics createMetrics(
+    private static Metrics createMetrics(
             final int top,
             final int ascent,
             final int descent,
@@ -275,7 +319,7 @@
             final int width,
             final int leading) {
 
-        final BoringLayout.Metrics metrics = new BoringLayout.Metrics();
+        final Metrics metrics = new Metrics();
 
         metrics.top = top;
         metrics.ascent = ascent;
diff --git a/tests/tests/text/src/android/text/cts/EmojiCtsActivity.java b/tests/tests/text/src/android/text/cts/EmojiCtsActivity.java
index 195bdf1..cdbc867 100644
--- a/tests/tests/text/src/android/text/cts/EmojiCtsActivity.java
+++ b/tests/tests/text/src/android/text/cts/EmojiCtsActivity.java
@@ -16,7 +16,7 @@
 
 package android.text.cts;
 
-import com.android.cts.text.R;
+import android.text.cts.R;
 
 import android.app.Activity;
 import android.os.Bundle;
diff --git a/tests/tests/text/src/android/text/cts/EmojiTest.java b/tests/tests/text/src/android/text/cts/EmojiTest.java
index e1249f3..4882402 100644
--- a/tests/tests/text/src/android/text/cts/EmojiTest.java
+++ b/tests/tests/text/src/android/text/cts/EmojiTest.java
@@ -33,7 +33,7 @@
 public class EmojiTest extends ActivityInstrumentationTestCase2<EmojiCtsActivity> {
 
     public EmojiTest() {
-        super("com.android.cts.text", EmojiCtsActivity.class);
+        super("android.text.cts", EmojiCtsActivity.class);
     }
 
     protected void setUp() throws Exception {
@@ -53,6 +53,26 @@
         }
     }
 
+    private String describeBitmap(final Bitmap bmp) {
+        StringBuilder sb = new StringBuilder();
+        sb.append("[ID:0x" + Integer.toHexString(System.identityHashCode(bmp)));
+        sb.append(" " + Integer.toString(bmp.getWidth()) + "x" + Integer.toString(bmp.getHeight()));
+        sb.append(" Config:");
+        if (bmp.getConfig() == Bitmap.Config.ALPHA_8) {
+            sb.append("ALPHA_8");
+        } else if (bmp.getConfig() == Bitmap.Config.RGB_565) {
+            sb.append("RGB_565");
+        } else if (bmp.getConfig() == Bitmap.Config.ARGB_4444) {
+            sb.append("ARGB_4444");
+        } else if (bmp.getConfig() == Bitmap.Config.ARGB_8888) {
+            sb.append("ARGB_8888");
+        } else {
+            sb.append("UNKNOWN");
+        }
+        sb.append("]");
+        return sb.toString();
+    }
+
     /**
      * Tests Emoji has different glyph for different meaning characters.
      * Test on Canvas, TextView, EditText and WebView
@@ -71,11 +91,15 @@
         };
 
         for (int i = 0; i < comparedCodePoints.length; i++) {
+            String baseMessage = "Glyph for U+" + Integer.toHexString(comparedCodePoints[i][0]) +
+                " should be different from glyph for U+" +
+                Integer.toHexString(comparedCodePoints[i][1]) + ". ";
 
             mBitmapA = ccanvas.capture(Character.toChars(comparedCodePoints[i][0]));
             mBitmapB = ccanvas.capture(Character.toChars(comparedCodePoints[i][1]));
 
-            assertFalse(mBitmapA.sameAs(mBitmapB));
+            String bmpDiffMessage = describeBitmap(mBitmapA) + "vs" + describeBitmap(mBitmapB);
+            assertFalse(baseMessage + bmpDiffMessage, mBitmapA.sameAs(mBitmapB));
 
             // cannot reuse CaptureTextView as 2nd setText call throws NullPointerException
             CaptureTextView cviewA = new CaptureTextView(getInstrumentation().getContext());
@@ -83,14 +107,16 @@
             CaptureTextView cviewB = new CaptureTextView(getInstrumentation().getContext());
             mBitmapB = cviewB.capture(Character.toChars(comparedCodePoints[i][1]));
 
-            assertFalse(mBitmapA.sameAs(mBitmapB));
+            bmpDiffMessage = describeBitmap(mBitmapA) + "vs" + describeBitmap(mBitmapB);
+            assertFalse(baseMessage + bmpDiffMessage, mBitmapA.sameAs(mBitmapB));
 
             CaptureEditText cedittextA = new CaptureEditText(getInstrumentation().getContext());
             mBitmapA = cedittextA.capture(Character.toChars(comparedCodePoints[i][0]));
             CaptureEditText cedittextB = new CaptureEditText(getInstrumentation().getContext());
             mBitmapB = cedittextB.capture(Character.toChars(comparedCodePoints[i][1]));
 
-            assertFalse(mBitmapA.sameAs(mBitmapB));
+            bmpDiffMessage = describeBitmap(mBitmapA) + "vs" + describeBitmap(mBitmapB);
+            assertFalse(baseMessage + bmpDiffMessage, mBitmapA.sameAs(mBitmapB));
 
             // Trigger activity bringup so we can determine if a WebView is available on this
             // device.
@@ -99,7 +125,8 @@
                 CaptureWebView cwebview = new CaptureWebView(getInstrumentation().getContext());
                 mBitmapA = cwebview.capture(Character.toChars(comparedCodePoints[i][0]));
                 mBitmapB = cwebview.capture(Character.toChars(comparedCodePoints[i][1]));
-                assertFalse(mBitmapA.sameAs(mBitmapB));
+                bmpDiffMessage = describeBitmap(mBitmapA) + "vs" + describeBitmap(mBitmapB);
+                assertFalse(baseMessage + bmpDiffMessage, mBitmapA.sameAs(mBitmapB));
             }
         }
     }
diff --git a/tests/tests/text/src/android/text/cts/HtmlTest.java b/tests/tests/text/src/android/text/cts/HtmlTest.java
index cf47ab9..ad4d2aa 100644
--- a/tests/tests/text/src/android/text/cts/HtmlTest.java
+++ b/tests/tests/text/src/android/text/cts/HtmlTest.java
@@ -16,14 +16,22 @@
 
 package android.text.cts;
 
+import static org.hamcrest.MatcherAssert.assertThat;
+import org.hamcrest.Description;
+import org.hamcrest.BaseMatcher;
+
 import android.graphics.Typeface;
 import android.test.AndroidTestCase;
 import android.text.Html;
+import android.text.Layout;
 import android.text.Spannable;
 import android.text.SpannableString;
 import android.text.Spanned;
 import android.text.Html.ImageGetter;
 import android.text.Html.TagHandler;
+import android.text.style.AlignmentSpan;
+import android.text.style.BackgroundColorSpan;
+import android.text.style.BulletSpan;
 import android.text.style.ForegroundColorSpan;
 import android.text.style.QuoteSpan;
 import android.text.style.StrikethroughSpan;
@@ -88,42 +96,165 @@
     }
 
     public void testColor() throws Exception {
-        final int start = 0;
+        final Class<ForegroundColorSpan> type = ForegroundColorSpan.class;
 
-        Class<ForegroundColorSpan> type = ForegroundColorSpan.class;
-        ForegroundColorSpan[] colors;
         Spanned s = Html.fromHtml("<font color=\"#00FF00\">something</font>");
-        int end = s.length();
-        colors = s.getSpans(start, end, type);
-        int expectedColor = 0xFF00FF00;
-        assertEquals(expectedColor, colors[0].getForegroundColor());
+        ForegroundColorSpan[] colors = s.getSpans(0, s.length(), type);
+        assertEquals(0xFF00FF00, colors[0].getForegroundColor());
 
-        s = Html.fromHtml("<font color=\"navy\">something</font>");
-        end = s.length();
-        colors = s.getSpans(start, end, type);
-        expectedColor = 0xFF000080;
+        s = Html.fromHtml("<font color=\"navy\">NAVY</font>");
+        colors = s.getSpans(0, s.length(), type);
         assertEquals(0xFF000080, colors[0].getForegroundColor());
 
         s = Html.fromHtml("<font color=\"gibberish\">something</font>");
-        end = s.length();
-        colors = s.getSpans(start, end, type);
+        colors = s.getSpans(0, s.length(), type);
         assertEquals(0, colors.length);
+
+        // By default use the color values from android.graphics.Color instead of HTML/CSS
+        s = Html.fromHtml("<font color=\"green\">GREEN</font>");
+        colors = s.getSpans(0, s.length(), type);
+        assertEquals(0xFF00FF00, colors[0].getForegroundColor());
+
+        s = Html.fromHtml("<font color=\"gray\">GRAY</font>");
+        colors = s.getSpans(0, s.length(), type);
+        assertEquals(0xFF888888, colors[0].getForegroundColor());
+
+        s = Html.fromHtml("<font color=\"grey\">GREY</font>");
+        colors = s.getSpans(0, s.length(), type);
+        assertEquals(0xFF888888, colors[0].getForegroundColor());
+
+        s = Html.fromHtml("<font color=\"lightgray\">LIGHTGRAY</font>");
+        colors = s.getSpans(0, s.length(), type);
+        assertEquals(0xFFCCCCCC, colors[0].getForegroundColor());
+
+        s = Html.fromHtml("<font color=\"lightgrey\">LIGHTGREY</font>");
+        colors = s.getSpans(0, s.length(), type);
+        assertEquals(0xFFCCCCCC, colors[0].getForegroundColor());
+
+        s = Html.fromHtml("<font color=\"darkgray\">DARKGRAY</font>");
+        colors = s.getSpans(0, s.length(), type);
+        assertEquals(0xFF444444, colors[0].getForegroundColor());
+
+        s = Html.fromHtml("<font color=\"darkgrey\">DARKGREY</font>");
+        colors = s.getSpans(0, s.length(), type);
+        assertEquals(0xFF444444, colors[0].getForegroundColor());
+    }
+
+    public void testUseCssColor() throws Exception {
+        final Class<ForegroundColorSpan> type = ForegroundColorSpan.class;
+        final int flags = Html.FROM_HTML_OPTION_USE_CSS_COLORS;
+
+        Spanned s = Html.fromHtml("<font color=\"green\">GREEN</font>", flags);
+        ForegroundColorSpan[] colors = s.getSpans(0, s.length(), type);
+        assertEquals(0xFF008000, colors[0].getForegroundColor());
+
+        s = Html.fromHtml("<font color=\"gray\">GRAY</font>", flags);
+        colors = s.getSpans(0, s.length(), type);
+        assertEquals(0xFF808080, colors[0].getForegroundColor());
+
+        s = Html.fromHtml("<font color=\"grey\">GREY</font>", flags);
+        colors = s.getSpans(0, s.length(), type);
+        assertEquals(0xFF808080, colors[0].getForegroundColor());
+
+        s = Html.fromHtml("<font color=\"lightgray\">LIGHTGRAY</font>", flags);
+        colors = s.getSpans(0, s.length(), type);
+        assertEquals(0xFFD3D3D3, colors[0].getForegroundColor());
+
+        s = Html.fromHtml("<font color=\"lightgrey\">LIGHTGREY</font>", flags);
+        colors = s.getSpans(0, s.length(), type);
+        assertEquals(0xFFD3D3D3, colors[0].getForegroundColor());
+
+        s = Html.fromHtml("<font color=\"darkgray\">DARKGRAY</font>", flags);
+        colors = s.getSpans(0, s.length(), type);
+        assertEquals(0xFFA9A9A9, colors[0].getForegroundColor());
+
+        s = Html.fromHtml("<font color=\"darkgrey\">DARKGREY</font>", flags);
+        colors = s.getSpans(0, s.length(), type);
+        assertEquals(0xFFA9A9A9, colors[0].getForegroundColor());
+    }
+
+    public void testStylesFromHtml() {
+        Spanned s = Html.fromHtml("<span style=\"color:#FF0000; background-color:#00FF00; "
+                + "text-decoration:line-through;\">style</span>");
+
+        ForegroundColorSpan[] foreground = s.getSpans(0, s.length(), ForegroundColorSpan.class);
+        assertEquals(1, foreground.length);
+        assertEquals(0xFFFF0000, foreground[0].getForegroundColor());
+
+        BackgroundColorSpan[] background = s.getSpans(0, s.length(), BackgroundColorSpan.class);
+        assertEquals(1, background.length);
+        assertEquals(0xFF00FF00, background[0].getBackgroundColor());
+
+        StrikethroughSpan[] strike = s.getSpans(0, s.length(), StrikethroughSpan.class);
+        assertEquals(1, strike.length);
     }
 
     public void testParagraphs() throws Exception {
         SpannableString s = new SpannableString("Hello world");
-        assertEquals("<p dir=\"ltr\">Hello world</p>\n", Html.toHtml(s));
+        assertThat(Html.toHtml(s), matchesIgnoringTrailingWhitespace(
+                "<p dir=\"ltr\">Hello world</p>"));
 
         s = new SpannableString("Hello world\nor something");
-        assertEquals("<p dir=\"ltr\">Hello world<br>\nor something</p>\n", Html.toHtml(s));
+        assertThat(Html.toHtml(s), matchesIgnoringTrailingWhitespace(
+                "<p dir=\"ltr\">Hello world<br>\nor something</p>"));
+        assertThat(Html.toHtml(s, Html.TO_HTML_PARAGRAPH_LINES_INDIVIDUAL),
+                matchesIgnoringTrailingWhitespace(
+                "<p dir=\"ltr\" style=\"margin-top:0; margin-bottom:0;\">Hello world</p>\n"
+                + "<p dir=\"ltr\" style=\"margin-top:0; margin-bottom:0;\">or something</p>"));
 
         s = new SpannableString("Hello world\n\nor something");
-        assertEquals("<p dir=\"ltr\">Hello world</p>\n<p dir=\"ltr\">or something</p>\n",
-                Html.toHtml(s));
+        assertThat(Html.toHtml(s), matchesIgnoringTrailingWhitespace(
+                "<p dir=\"ltr\">Hello world</p>\n<p dir=\"ltr\">or something</p>"));
 
         s = new SpannableString("Hello world\n\n\nor something");
-        assertEquals("<p dir=\"ltr\">Hello world<br></p>\n<p dir=\"ltr\">or something</p>\n",
-                Html.toHtml(s));
+        assertThat(Html.toHtml(s), matchesIgnoringTrailingWhitespace(
+                "<p dir=\"ltr\">Hello world<br></p>\n<p dir=\"ltr\">or something</p>"));
+        assertThat(Html.toHtml(s, Html.TO_HTML_PARAGRAPH_LINES_INDIVIDUAL),
+                matchesIgnoringTrailingWhitespace(
+                "<p dir=\"ltr\" style=\"margin-top:0; margin-bottom:0;\">Hello world</p>\n"
+                + "<br>\n"
+                + "<br>\n"
+                + "<p dir=\"ltr\" style=\"margin-top:0; margin-bottom:0;\">or something</p>"));
+    }
+
+    public void testParagraphStyles() throws Exception {
+        SpannableString s = new SpannableString("Hello world");
+        s.setSpan(new AlignmentSpan.Standard(Layout.Alignment.ALIGN_CENTER),
+                0, s.length(), Spanned.SPAN_PARAGRAPH);
+        assertThat(Html.toHtml(s, Html.TO_HTML_PARAGRAPH_LINES_INDIVIDUAL),
+                matchesIgnoringTrailingWhitespace(
+                "<p dir=\"ltr\" style=\"margin-top:0; margin-bottom:0; text-align:center;\">"
+                + "Hello world</p>"));
+
+        // Set another AlignmentSpan of a different alignment. Only the last one should be encoded.
+        s.setSpan(new AlignmentSpan.Standard(Layout.Alignment.ALIGN_OPPOSITE),
+                0, s.length(), Spanned.SPAN_PARAGRAPH);
+        assertThat(Html.toHtml(s, Html.TO_HTML_PARAGRAPH_LINES_INDIVIDUAL),
+                matchesIgnoringTrailingWhitespace(
+                "<p dir=\"ltr\" style=\"margin-top:0; margin-bottom:0; text-align:end;\">"
+                + "Hello world</p>"));
+
+        // Set another AlignmentSpan without SPAN_PARAGRAPH flag.
+        // This will be ignored and the previous alignment should be encoded.
+        s.setSpan(new AlignmentSpan.Standard(Layout.Alignment.ALIGN_NORMAL),
+                0, s.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+        assertThat(Html.toHtml(s, Html.TO_HTML_PARAGRAPH_LINES_INDIVIDUAL),
+                matchesIgnoringTrailingWhitespace(
+                "<p dir=\"ltr\" style=\"margin-top:0; margin-bottom:0; text-align:end;\">"
+                + "Hello world</p>"));
+    }
+
+    public void testBulletSpan() throws Exception {
+        SpannableString s = new SpannableString("Bullet1\nBullet2\nNormal paragraph");
+        s.setSpan(new BulletSpan(), 0, 8, Spanned.SPAN_PARAGRAPH);
+        s.setSpan(new BulletSpan(), 8, 16, Spanned.SPAN_PARAGRAPH);
+        assertThat(Html.toHtml(s, Html.TO_HTML_PARAGRAPH_LINES_INDIVIDUAL),
+                matchesIgnoringTrailingWhitespace(
+                "<ul style=\"margin-top:0; margin-bottom:0;\">\n"
+                + "<li dir=\"ltr\">Bullet1</li>\n"
+                + "<li dir=\"ltr\">Bullet2</li>\n"
+                + "</ul>\n"
+                + "<p dir=\"ltr\" style=\"margin-top:0; margin-bottom:0;\">Normal paragraph</p>"));
     }
 
     public void testBlockquote() throws Exception {
@@ -132,24 +263,28 @@
         SpannableString s = new SpannableString("Hello world");
         int end = s.length();
         s.setSpan(new QuoteSpan(), start, end, Spannable.SPAN_PARAGRAPH);
-        assertEquals("<blockquote><p dir=\"ltr\">Hello world</p>\n</blockquote>\n", Html.toHtml(s));
+        assertThat(Html.toHtml(s), matchesIgnoringTrailingWhitespace(
+                "<blockquote><p dir=\"ltr\">Hello world</p>\n</blockquote>"));
 
         s = new SpannableString("Hello\n\nworld");
         end = 7;
         s.setSpan(new QuoteSpan(), start, end, Spannable.SPAN_PARAGRAPH);
-        assertEquals("<blockquote><p dir=\"ltr\">Hello</p>\n</blockquote>\n" +
-        		"<p dir=\"ltr\">world</p>\n", Html.toHtml(s));
+        assertThat(Html.toHtml(s), matchesIgnoringTrailingWhitespace(
+                "<blockquote><p dir=\"ltr\">Hello</p>\n</blockquote>\n<p dir=\"ltr\">world</p>"));
     }
 
     public void testEntities() throws Exception {
         SpannableString s = new SpannableString("Hello <&> world");
-        assertEquals("<p dir=\"ltr\">Hello &lt;&amp;&gt; world</p>\n", Html.toHtml(s));
+        assertThat(Html.toHtml(s), matchesIgnoringTrailingWhitespace(
+                "<p dir=\"ltr\">Hello &lt;&amp;&gt; world</p>"));
 
         s = new SpannableString("Hello \u03D5 world");
-        assertEquals("<p dir=\"ltr\">Hello &#981; world</p>\n", Html.toHtml(s));
+        assertThat(Html.toHtml(s), matchesIgnoringTrailingWhitespace(
+                "<p dir=\"ltr\">Hello &#981; world</p>"));
 
         s = new SpannableString("Hello  world");
-        assertEquals("<p dir=\"ltr\">Hello&nbsp; world</p>\n", Html.toHtml(s));
+        assertThat(Html.toHtml(s), matchesIgnoringTrailingWhitespace(
+                "<p dir=\"ltr\">Hello&nbsp; world</p>"));
     }
 
     public void testMarkup() throws Exception {
@@ -158,64 +293,273 @@
         SpannableString s = new SpannableString("Hello bold world");
         int end = s.length() - start;
         s.setSpan(new StyleSpan(Typeface.BOLD), start, end, SPAN_EXCLUSIVE_INCLUSIVE);
-        assertEquals("<p dir=\"ltr\">Hello <b>bold</b> world</p>\n", Html.toHtml(s));
+        assertThat(Html.toHtml(s), matchesIgnoringTrailingWhitespace(
+                "<p dir=\"ltr\">Hello <b>bold</b> world</p>"));
 
         s = new SpannableString("Hello italic world");
         end = s.length() - start;
         s.setSpan(new StyleSpan(Typeface.ITALIC), start, end, SPAN_EXCLUSIVE_INCLUSIVE);
-        assertEquals("<p dir=\"ltr\">Hello <i>italic</i> world</p>\n", Html.toHtml(s));
+        assertThat(Html.toHtml(s), matchesIgnoringTrailingWhitespace(
+                "<p dir=\"ltr\">Hello <i>italic</i> world</p>"));
 
         s = new SpannableString("Hello monospace world");
         end = s.length() - start;
         s.setSpan(new TypefaceSpan("monospace"), start, end, SPAN_EXCLUSIVE_INCLUSIVE);
-        assertEquals("<p dir=\"ltr\">Hello <tt>monospace</tt> world</p>\n", Html.toHtml(s));
+        assertThat(Html.toHtml(s), matchesIgnoringTrailingWhitespace(
+                "<p dir=\"ltr\">Hello <tt>monospace</tt> world</p>"));
 
         s = new SpannableString("Hello superscript world");
         end = s.length() - start;
         s.setSpan(new SuperscriptSpan(), start, end, SPAN_EXCLUSIVE_INCLUSIVE);
-        assertEquals("<p dir=\"ltr\">Hello <sup>superscript</sup> world</p>\n", Html.toHtml(s));
+        assertThat(Html.toHtml(s), matchesIgnoringTrailingWhitespace(
+                "<p dir=\"ltr\">Hello <sup>superscript</sup> world</p>"));
 
         s = new SpannableString("Hello subscript world");
         end = s.length() - start;
         s.setSpan(new SubscriptSpan(), start, end, SPAN_EXCLUSIVE_INCLUSIVE);
-        assertEquals("<p dir=\"ltr\">Hello <sub>subscript</sub> world</p>\n", Html.toHtml(s));
+        assertThat(Html.toHtml(s), matchesIgnoringTrailingWhitespace(
+                "<p dir=\"ltr\">Hello <sub>subscript</sub> world</p>"));
 
         s = new SpannableString("Hello underline world");
         end = s.length() - start;
         s.setSpan(new UnderlineSpan(), start, end, SPAN_EXCLUSIVE_INCLUSIVE);
-        assertEquals("<p dir=\"ltr\">Hello <u>underline</u> world</p>\n", Html.toHtml(s));
+        assertThat(Html.toHtml(s), matchesIgnoringTrailingWhitespace(
+                "<p dir=\"ltr\">Hello <u>underline</u> world</p>"));
 
         s = new SpannableString("Hello struck world");
         end = s.length() - start;
         s.setSpan(new StrikethroughSpan(), start, end, SPAN_EXCLUSIVE_INCLUSIVE);
-        assertEquals("<p dir=\"ltr\">Hello <strike>struck</strike> world</p>\n", Html.toHtml(s));
+        assertThat(Html.toHtml(s), matchesIgnoringTrailingWhitespace("<p dir=\"ltr\">Hello "
+                + "<span style=\"text-decoration:line-through;\">struck</span> world</p>"));
 
         s = new SpannableString("Hello linky world");
         end = s.length() - start;
         s.setSpan(new URLSpan("http://www.google.com"), start, end, SPAN_EXCLUSIVE_INCLUSIVE);
-        String ret = Html.toHtml(s);
-        assertEquals("<p dir=\"ltr\">Hello <a href=\"http://www.google.com\">linky</a> world</p>\n",
-                ret);
+        assertThat(Html.toHtml(s), matchesIgnoringTrailingWhitespace("<p dir=\"ltr\">Hello "
+                + "<a href=\"http://www.google.com\">linky</a> world</p>"));
+
+        s = new SpannableString("Hello foreground world");
+        end = s.length() - start;
+        s.setSpan(new ForegroundColorSpan(0x00FF00), start, end, SPAN_EXCLUSIVE_INCLUSIVE);
+        assertThat(Html.toHtml(s), matchesIgnoringTrailingWhitespace("<p dir=\"ltr\">Hello "
+                + "<span style=\"color:#00FF00;\">foreground</span> world</p>"));
+
+        s = new SpannableString("Hello background world");
+        end = s.length() - start;
+        s.setSpan(new BackgroundColorSpan(0x00FF00), start, end, SPAN_EXCLUSIVE_INCLUSIVE);
+        assertThat(Html.toHtml(s), matchesIgnoringTrailingWhitespace("<p dir=\"ltr\">Hello "
+                + "<span style=\"background-color:#00FF00;\">background</span> world</p>"));
+    }
+
+    public void testMarkupFromHtml() throws Exception {
+        final int expectedStart = 6;
+        final int expectedEnd = expectedStart + 6;
+
+        String tags[] = {"del", "s", "strike"};
+        for (String tag : tags) {
+            String source = String.format("Hello <%s>struck</%s> world", tag, tag);
+            Spanned spanned = Html.fromHtml(source);
+            Object[] spans = spanned.getSpans(0, spanned.length(), Object.class);
+            assertEquals(1, spans.length);
+            assertEquals(StrikethroughSpan.class, spans[0].getClass());
+            assertEquals(expectedStart, spanned.getSpanStart(spans[0]));
+            assertEquals(expectedEnd, spanned.getSpanEnd(spans[0]));
+        }
+    }
+
+    /**
+     * Tests if text alignments encoded as CSS TEXT-ALIGN property are correctly converted into
+     * {@link AlignmentSpan}s. Note that the span will also cover the first newline character after
+     * the text.
+     */
+    public void testTextAlignCssFromHtml() throws Exception {
+        String tags[] = {"p", "h1", "h2", "h3", "h4", "h5", "h6", "div", "blockquote"};
+
+        for (String tag : tags) {
+            String source = String.format("<%s style=\"text-align:start\">TEXT</%s>"
+                    + "<%s style=\"text-align:center\">TEXT</%s>"
+                    + "<%s style=\"text-align:end\">TEXT</%s>",
+                    tag, tag, tag, tag, tag, tag);
+            Spanned spanned = Html.fromHtml(source);
+            AlignmentSpan[] spans = spanned.getSpans(0, spanned.length(), AlignmentSpan.class);
+            assertEquals(3, spans.length);
+
+            assertEquals(Layout.Alignment.ALIGN_NORMAL, spans[0].getAlignment());
+            assertEquals(0, spanned.getSpanStart(spans[0]));
+            assertEquals(5, spanned.getSpanEnd(spans[0]));
+
+            assertEquals(Layout.Alignment.ALIGN_CENTER, spans[1].getAlignment());
+            assertEquals(6, spanned.getSpanStart(spans[1]));
+            assertEquals(11, spanned.getSpanEnd(spans[1]));
+
+            assertEquals(Layout.Alignment.ALIGN_OPPOSITE, spans[2].getAlignment());
+            assertEquals(12, spanned.getSpanStart(spans[2]));
+            assertEquals(17, spanned.getSpanEnd(spans[2]));
+
+            // Other valid TEXT-ALIGN property encodings
+            source = String.format("<%s style=\'text-align:center\''>TEXT</%s>"
+                    + "<%s style=\"text-align:center;\">TEXT</%s>"
+                    + "<%s style=\"text-align  :  center  ;  \">TEXT</%s>",
+                    tag, tag, tag, tag, tag, tag);
+            spanned = Html.fromHtml(source);
+            spans = spanned.getSpans(0, spanned.length(), AlignmentSpan.class);
+            assertEquals(3, spans.length);
+
+            // Invalid TEXT-ALIGN property encodings
+            source = String.format("<%s style=\"text-align:centre\">TEXT</%s>"
+                    + "<%s style=\"text-alignment:center\">TEXT</%s>"
+                    + "<%s style=\"align:center\">TEXT</%s>"
+                    + "<%s style=\"text-align:gibberish\">TEXT</%s>",
+                    tag, tag, tag, tag, tag, tag, tag, tag);
+            spanned = Html.fromHtml(source);
+            spans = spanned.getSpans(0, spanned.length(), AlignmentSpan.class);
+            assertEquals(0, spans.length);
+        }
+    }
+
+    public void testBlockLevelElementsFromHtml() throws Exception {
+        String source = "<blockquote>BLOCKQUOTE</blockquote>"
+                + "<div>DIV</div>"
+                + "<p>P</p>"
+                + "<h1>HEADING</h1>";
+
+        int flags = Html.FROM_HTML_SEPARATOR_LINE_BREAK_BLOCKQUOTE
+                | Html.FROM_HTML_SEPARATOR_LINE_BREAK_DIV;
+        assertEquals("BLOCKQUOTE\nDIV\n\nP\n\nHEADING\n\n",
+                Html.fromHtml(source, flags, null, null).toString());
+
+        flags = Html.FROM_HTML_SEPARATOR_LINE_BREAK_DIV
+                | Html.FROM_HTML_SEPARATOR_LINE_BREAK_PARAGRAPH;
+        assertEquals("BLOCKQUOTE\n\nDIV\nP\n\nHEADING\n\n",
+                Html.fromHtml(source, flags, null, null).toString());
+
+        flags = Html.FROM_HTML_SEPARATOR_LINE_BREAK_PARAGRAPH
+                | Html.FROM_HTML_SEPARATOR_LINE_BREAK_HEADING;
+        assertEquals("BLOCKQUOTE\n\nDIV\n\nP\nHEADING\n",
+                Html.fromHtml(source, flags, null, null).toString());
+    }
+
+    public void testListFromHtml() throws Exception {
+        String source = "CITRUS FRUITS:<ul><li>LEMON</li><li>LIME</li><li>ORANGE</li></ul>";
+        assertEquals("CITRUS FRUITS:\n\nLEMON\n\nLIME\n\nORANGE\n\n",
+                Html.fromHtml(source).toString());
+
+        int flags = Html.FROM_HTML_SEPARATOR_LINE_BREAK_LIST;
+        // The <li> still has to be separated by two newline characters
+        assertEquals("CITRUS FRUITS:\n\nLEMON\n\nLIME\n\nORANGE\n\n",
+                Html.fromHtml(source, flags, null, null).toString());
+
+        flags = Html.FROM_HTML_SEPARATOR_LINE_BREAK_LIST_ITEM;
+        assertEquals("CITRUS FRUITS:\n\nLEMON\nLIME\nORANGE\n\n",
+                Html.fromHtml(source, flags, null, null).toString());
+
+        flags = Html.FROM_HTML_SEPARATOR_LINE_BREAK_LIST
+                | Html.FROM_HTML_SEPARATOR_LINE_BREAK_LIST_ITEM;
+        assertEquals("CITRUS FRUITS:\nLEMON\nLIME\nORANGE\n",
+                Html.fromHtml(source, flags, null, null).toString());
+    }
+
+    public void testParagraphFromHtml() throws Exception {
+        final int flags = Html.FROM_HTML_SEPARATOR_LINE_BREAK_PARAGRAPH;
+
+        String source = "<p>Line 1</p><p>Line 2</p>";
+        assertEquals("Line 1\nLine 2\n",
+                Html.fromHtml(source, flags).toString());
+        assertEquals("Line 1\n\nLine 2\n\n",
+                Html.fromHtml(source).toString());
+
+        source = "<br>Line 1<br>Line 2<br>";
+        assertEquals("\nLine 1\nLine 2\n",
+                Html.fromHtml(source, flags).toString());
+        assertEquals("\nLine 1\nLine 2\n",
+                Html.fromHtml(source).toString());
+
+        source = "<br><p>Line 1</p><br><p>Line 2</p><br>";
+        assertEquals("\nLine 1\n\nLine 2\n\n",
+                Html.fromHtml(source, flags).toString());
+        assertEquals("\n\nLine 1\n\n\nLine 2\n\n\n",
+                Html.fromHtml(source).toString());
+
+        source = "<p>Line 1<br>Line 2</p><p>Line 3</p>";
+        assertEquals("Line 1\nLine 2\nLine 3\n",
+                Html.fromHtml(source, flags).toString());
+        assertEquals("Line 1\nLine 2\n\nLine 3\n\n",
+                Html.fromHtml(source).toString());
+    }
+
+    public void testHeadingFromHtml() throws Exception {
+        final int flags = Html.FROM_HTML_SEPARATOR_LINE_BREAK_HEADING;
+
+        String source = "<h1>Heading 1</h1><h1>Heading 2</h1>";
+        assertEquals("Heading 1\nHeading 2\n",
+                Html.fromHtml(source, flags).toString());
+        assertEquals("Heading 1\n\nHeading 2\n\n",
+                Html.fromHtml(source).toString());
+
+        source = "<br><h1>Heading 1</h1><br><h1>Heading 2</h1><br>";
+        assertEquals("\nHeading 1\n\nHeading 2\n\n",
+                Html.fromHtml(source, flags).toString());
+        assertEquals("\n\nHeading 1\n\n\nHeading 2\n\n\n",
+                Html.fromHtml(source).toString());
+
+        source = "<h1>Heading 1<br>Heading 2</h1><h1>Heading 3</h1>";
+        assertEquals("Heading 1\nHeading 2\nHeading 3\n",
+                Html.fromHtml(source, flags).toString());
+        assertEquals("Heading 1\nHeading 2\n\nHeading 3\n\n",
+                Html.fromHtml(source).toString());
     }
 
     public void testImg() throws Exception {
         Spanned s = Html.fromHtml("yes<img src=\"http://example.com/foo.gif\">no");
-        assertEquals("<p dir=\"ltr\">yes<img src=\"http://example.com/foo.gif\">no</p>\n",
-                Html.toHtml(s));
+        assertThat(Html.toHtml(s), matchesIgnoringTrailingWhitespace(
+                "<p dir=\"ltr\">yes<img src=\"http://example.com/foo.gif\">no</p>"));
     }
 
     public void testUtf8() throws Exception {
         Spanned s = Html.fromHtml("<p>\u0124\u00eb\u0142\u0142o, world!</p>");
-        assertEquals("<p dir=\"ltr\">&#292;&#235;&#322;&#322;o, world!</p>\n", Html.toHtml(s));
+        assertThat(Html.toHtml(s), matchesIgnoringTrailingWhitespace(
+                "<p dir=\"ltr\">&#292;&#235;&#322;&#322;o, world!</p>"));
     }
 
     public void testSurrogates() throws Exception {
         Spanned s = Html.fromHtml("\ud83d\udc31");
-        assertEquals("<p dir=\"ltr\">&#128049;</p>\n", Html.toHtml(s));
+        assertThat(Html.toHtml(s), matchesIgnoringTrailingWhitespace(
+                "<p dir=\"ltr\">&#128049;</p>"));
     }
 
     public void testBadSurrogates() throws Exception {
         Spanned s = Html.fromHtml("\udc31\ud83d");
-        assertEquals("<p dir=\"ltr\"></p>\n", Html.toHtml(s));
+        assertThat(Html.toHtml(s), matchesIgnoringTrailingWhitespace("<p dir=\"ltr\"></p>"));
+    }
+
+    private static StringIgnoringTrailingWhitespaceMatcher matchesIgnoringTrailingWhitespace(
+            String expected) {
+        return new StringIgnoringTrailingWhitespaceMatcher(expected);
+    }
+
+    private static final class StringIgnoringTrailingWhitespaceMatcher extends
+            BaseMatcher<String> {
+        private final String mStrippedString;
+
+        public StringIgnoringTrailingWhitespaceMatcher(String string) {
+            mStrippedString = stripTrailingWhitespace(string);
+        }
+
+        @Override
+        public boolean matches(Object item) {
+            final String string = (String) item;
+            return mStrippedString.equals(stripTrailingWhitespace(string));
+        }
+
+        private String stripTrailingWhitespace(String text) {
+            return text.replaceFirst("\\s+$", "");
+        }
+
+        @Override
+        public void describeTo(Description description) {
+            description.appendText("is equal to ")
+                    .appendText(mStrippedString)
+                    .appendText(" ignoring tailing whitespaces");
+        }
     }
 }
diff --git a/tests/tests/text/src/android/text/cts/MyanmarTest.java b/tests/tests/text/src/android/text/cts/MyanmarTest.java
index d59f2b9..9988ab9 100644
--- a/tests/tests/text/src/android/text/cts/MyanmarTest.java
+++ b/tests/tests/text/src/android/text/cts/MyanmarTest.java
@@ -25,7 +25,7 @@
 public class MyanmarTest extends ActivityInstrumentationTestCase2<Activity> {
 
     public MyanmarTest() {
-        super("com.android.cts.text", Activity.class);
+        super("android.text.cts", Activity.class);
     }
 
     protected void setUp() throws Exception {
diff --git a/tests/tests/text/src/android/text/cts/SpannableStringBuilderSpanTest.java b/tests/tests/text/src/android/text/cts/SpannableStringBuilderSpanTest.java
index 352767c..14bcc8e 100644
--- a/tests/tests/text/src/android/text/cts/SpannableStringBuilderSpanTest.java
+++ b/tests/tests/text/src/android/text/cts/SpannableStringBuilderSpanTest.java
@@ -19,10 +19,15 @@
 import java.util.ArrayList;
 
 import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.text.Html;
 import android.text.SpanWatcher;
 import android.text.Spannable;
+import android.text.SpannableString;
 import android.text.SpannableStringBuilder;
 import android.text.Spanned;
+import android.text.style.ParagraphStyle;
+import android.text.style.QuoteSpan;
 
 /**
  * Test {@link SpannableStringBuilder}.
@@ -492,4 +497,88 @@
     }
 
     // TODO Thoroughly test the SPAN_PARAGRAPH span flag.
+
+
+    @SmallTest
+    public void
+    testReplace_discardsParagraphSpanInSourceIfThereIsNoNewLineBefore()
+            throws Exception {
+        SpannableStringBuilder spannable = new SpannableStringBuilder("1 selection_to_replace");
+        Spanned newText = Html.fromHtml("<blockquote>new text</blockquote>");
+        assertEquals(1, newText.getSpans(0, newText.length(), ParagraphStyle.class).length);
+
+        spannable.replace(2, spannable.length(), newText);
+
+        ParagraphStyle[] paragraphSpans = spannable.getSpans(0, spannable.length(),
+                ParagraphStyle.class);
+        assertEquals(0, paragraphSpans.length);
+    }
+
+    @SmallTest
+    public void testReplace_retainsParagraphSpanInSourceIfThereIsNewLineBefore()
+            throws Exception {
+        SpannableStringBuilder spannable = new SpannableStringBuilder("1\nselection_to_replace");
+        Spanned newText = Html.fromHtml("<blockquote>new text</blockquote>");
+        assertTrue(newText.getSpans(0, newText.length(), ParagraphStyle.class).length > 0);
+
+        spannable.replace(2, spannable.length(), newText);
+
+        ParagraphStyle[] paragraphSpans = spannable.getSpans(0, spannable.length(),
+                ParagraphStyle.class);
+        assertEquals(1, paragraphSpans.length);
+    }
+
+    @SmallTest
+    public void testReplace_retainsParagraphSpanInSourceIfStartIsZero()
+            throws Exception {
+        // copy the paragraph span even if there is no previous character - start is equal to 0
+
+        SpannableStringBuilder spannable = new SpannableStringBuilder("selection_to_replace");
+        Spanned newText = Html.fromHtml("<blockquote>new text</blockquote>");
+        assertTrue(newText.getSpans(0, newText.length(), ParagraphStyle.class).length > 0);
+
+        spannable.replace(0, spannable.length(), newText);
+
+        ParagraphStyle[] paragraphSpans = spannable.getSpans(0, spannable.length(),
+                ParagraphStyle.class);
+        assertEquals(1, paragraphSpans.length);
+    }
+
+    @SmallTest
+    public void testReplace_retainsParagraphSpanInSourceIfEndIsEqualToLengthOfString()
+            throws Exception {
+        // copy the paragraph span even if the final char is not next line, and if the end is
+        // equal to the string length
+
+        SpannableStringBuilder spannable = new SpannableStringBuilder("selection_to_replace\n");
+        // create a spannable that does not have \n at the end. Html.fromHtml adds \n to the end of
+        // the text
+        Spannable newText = new SpannableString("a");
+        newText.setSpan(new QuoteSpan(), 0, 1, Spannable.SPAN_PARAGRAPH);
+        assertTrue(newText.getSpans(0, newText.length(), ParagraphStyle.class).length > 0);
+
+        spannable.replace(spannable.length(), spannable.length(), newText);
+
+        ParagraphStyle[] paragraphSpans = spannable.getSpans(0, spannable.length(),
+                ParagraphStyle.class);
+        assertEquals(1, paragraphSpans.length);
+    }
+
+    @SmallTest
+    public void testReplace_discardsParagraphSpanInSourceIfThereIsNoNewLineAfter()
+            throws Exception {
+        SpannableStringBuilder spannable = new SpannableStringBuilder("r remaining\n");
+        // create a spannable that does not have \n at the end. Html.fromHtml adds \n to the end of
+        // the text
+        Spannable newText = new SpannableString("a");
+        newText.setSpan(new QuoteSpan(), 0, 1, Spannable.SPAN_PARAGRAPH);
+        assertTrue(newText.getSpans(0, newText.length(), ParagraphStyle.class).length > 0);
+
+        spannable.replace(0, 1, newText);
+
+        ParagraphStyle[] paragraphSpans = spannable.getSpans(0, spannable.length(),
+                ParagraphStyle.class);
+        assertEquals(0, paragraphSpans.length);
+    }
+
 }
diff --git a/tests/tests/text/src/android/text/cts/SpannableStringBuilderTest.java b/tests/tests/text/src/android/text/cts/SpannableStringBuilderTest.java
index 36b081c..6dee5e9 100644
--- a/tests/tests/text/src/android/text/cts/SpannableStringBuilderTest.java
+++ b/tests/tests/text/src/android/text/cts/SpannableStringBuilderTest.java
@@ -18,13 +18,19 @@
 
 
 import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
 import android.text.Editable;
 import android.text.InputFilter;
 import android.text.SpannableString;
 import android.text.SpannableStringBuilder;
 import android.text.Spanned;
 import android.text.TextWatcher;
+import android.text.style.BulletSpan;
+import android.text.style.ParagraphStyle;
+import android.text.style.QuoteSpan;
+import android.text.style.RelativeSizeSpan;
 import android.text.style.StrikethroughSpan;
+import android.text.style.SubscriptSpan;
 import android.text.style.TabStopSpan;
 import android.text.style.UnderlineSpan;
 
@@ -553,6 +559,11 @@
         UnderlineSpan span2 = new UnderlineSpan();
         builder.setSpan(span1, 1, 2, Spanned.SPAN_POINT_POINT);
         builder.setSpan(span2, 4, 8, Spanned.SPAN_MARK_POINT);
+
+        Object[] emptySpans = builder.getSpans(0, 10, null);
+        assertNotNull(emptySpans);
+        assertEquals(0, emptySpans.length);
+
         UnderlineSpan[] underlineSpans = builder.getSpans(0, 10, UnderlineSpan.class);
         assertEquals(2, underlineSpans.length);
         assertSame(span1, underlineSpans[0]);
@@ -566,6 +577,110 @@
         builder.getSpans(4, 1, UnderlineSpan.class);
     }
 
+    @SmallTest
+    public void testGetSpans_returnsEmptyIfSetSpanIsNotCalled() {
+        String text = "p_in_s";
+        SpannableStringBuilder builder = new SpannableStringBuilder(text);
+        Object[] spans = builder.getSpans(0, text.length(), Object.class);
+        assertEquals(0, spans.length);
+    }
+
+    @SmallTest
+    public void testGetSpans_returnsSpansInInsertionOrderWhenTheLaterCoversTheFirst() {
+        String text = "p_in_s";
+        SpannableStringBuilder builder = new SpannableStringBuilder(text);
+        Object first = new SubscriptSpan();
+        Object second = new SubscriptSpan();
+        int flags = Spanned.SPAN_EXCLUSIVE_EXCLUSIVE;
+        builder.setSpan(first, 2, 4, flags);
+        builder.setSpan(second, 0, text.length(), flags);
+
+        Object[] spans = builder.getSpans(0, text.length(), Object.class);
+
+        assertNotNull(spans);
+        assertEquals(2, spans.length);
+        assertEquals(first, spans[0]);
+        assertEquals(second, spans[1]);
+    }
+
+    @SmallTest
+    public void testGetSpans_returnsSpansSortedFirstByPriorityThenByInsertionOrder() {
+        String text = "p_in_s";
+        SpannableStringBuilder builder = new SpannableStringBuilder(text);
+        Object first = new SubscriptSpan();
+        Object second = new SubscriptSpan();
+        Object third = new SubscriptSpan();
+        Object fourth = new SubscriptSpan();
+
+        int flags = Spanned.SPAN_EXCLUSIVE_EXCLUSIVE;
+        int flagsPriority = Spanned.SPAN_EXCLUSIVE_EXCLUSIVE | Spanned.SPAN_PRIORITY;
+
+        builder.setSpan(first, 2, 4, flags);
+        builder.setSpan(second, 2, 4, flagsPriority);
+        builder.setSpan(third, 0, text.length(), flags);
+        builder.setSpan(fourth, 0, text.length(), flagsPriority);
+
+        Object[] spans = builder.getSpans(0, text.length(), Object.class);
+
+        assertNotNull(spans);
+        assertEquals(4, spans.length);
+        assertEquals(second, spans[0]);
+        assertEquals(fourth, spans[1]);
+        assertEquals(first, spans[2]);
+        assertEquals(third, spans[3]);
+    }
+
+    @SmallTest
+    public void testGetSpans_returnsSpansInInsertionOrderAfterRemoveSpanCalls() {
+        String text = "p_in_s";
+        SpannableStringBuilder builder = new SpannableStringBuilder(text);
+        Object first = new SubscriptSpan();
+        Object second = new SubscriptSpan();
+        Object third = new SubscriptSpan();
+        Object fourth = new SubscriptSpan();
+
+        int flags = Spanned.SPAN_EXCLUSIVE_EXCLUSIVE;
+        builder.setSpan(first, 2, 4, flags);
+        builder.setSpan(second, 0, text.length(), flags);
+        builder.setSpan(third, 2, 4, flags);
+        builder.removeSpan(first);
+        builder.removeSpan(second);
+        builder.setSpan(fourth, 0, text.length(), flags);
+
+        Object[] spans = builder.getSpans(0, text.length(), Object.class);
+
+        assertNotNull(spans);
+        assertEquals(2, spans.length);
+        assertEquals(third, spans[0]);
+        assertEquals(fourth, spans[1]);
+    }
+
+    @SmallTest
+    public void testGetSpans_sortsByPriorityEvenWhenSortParamIsFalse() {
+        String text = "p_in_s";
+        SpannableStringBuilder builder = new SpannableStringBuilder(text);
+        Object first = new SubscriptSpan();
+        Object second = new UnderlineSpan();
+        Object third = new BulletSpan();
+        Object fourth = new QuoteSpan();
+
+        builder.setSpan(first, 2, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+        builder.setSpan(second, 1, text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+        builder.setSpan(third, 2, text.length(), 1 << Spanned.SPAN_PRIORITY_SHIFT);
+        builder.setSpan(fourth, 0, text.length(), 2 << Spanned.SPAN_PRIORITY_SHIFT);
+
+        Object[] spans = builder.getSpans(0, text.length(), Object.class, false);
+
+        assertNotNull(spans);
+        assertEquals(4, spans.length);
+        // priority spans are first
+        assertEquals(fourth, spans[0]);
+        assertEquals(third, spans[1]);
+        // other spans should be there
+        assertEquals(second, spans[2]);
+        assertEquals(first, spans[3]);
+    }
+
     public void testLength() {
         SpannableStringBuilder builder = new SpannableStringBuilder("hello");
         assertEquals(5, builder.length());
diff --git a/tests/tests/text/src/android/text/cts/SpannableStringTest.java b/tests/tests/text/src/android/text/cts/SpannableStringTest.java
index 3214bb4..e46a104 100644
--- a/tests/tests/text/src/android/text/cts/SpannableStringTest.java
+++ b/tests/tests/text/src/android/text/cts/SpannableStringTest.java
@@ -17,9 +17,15 @@
 package android.text.cts;
 
 import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
 import android.text.SpannableString;
+import android.text.Spanned;
+import android.text.style.LocaleSpan;
+import android.text.style.QuoteSpan;
 import android.text.style.UnderlineSpan;
 
+import java.util.Locale;
+
 public class SpannableStringTest extends AndroidTestCase {
 
     public void testConstructor() {
@@ -123,4 +129,59 @@
         } catch (StringIndexOutOfBoundsException e) {
         }
     }
+
+    @SmallTest
+    public void testSubsequence_copiesSpans() {
+        SpannableString first = new SpannableString("t\nest data");
+        QuoteSpan quoteSpan = new QuoteSpan();
+        LocaleSpan localeSpan = new LocaleSpan(Locale.US);
+        UnderlineSpan underlineSpan = new UnderlineSpan();
+
+        first.setSpan(quoteSpan, 0, 2, Spanned.SPAN_PARAGRAPH);
+        first.setSpan(localeSpan, 2, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+        first.setSpan(underlineSpan, 0, first.length(), Spanned.SPAN_PRIORITY);
+
+        Spanned second = (Spanned) first.subSequence(2,4);
+        Object[] secondSpans = second.getSpans(0, second.length(), Object.class);
+        assertNotNull(secondSpans);
+        assertEquals(2, secondSpans.length);
+
+        //priority flag is first in the results
+        Object[][] expected = new Object[][] {
+                {underlineSpan, 0, second.length(), Spanned.SPAN_PRIORITY},
+                {localeSpan, 0, 2, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE}};
+
+        for (int i = 0; i < secondSpans.length; i++) {
+            Object secondSpan = secondSpans[i];
+            assertEquals(expected[i][0], secondSpan);
+            assertEquals(expected[i][1], second.getSpanStart(secondSpan));
+            assertEquals(expected[i][2], second.getSpanEnd(secondSpan));
+            assertEquals(expected[i][3], second.getSpanFlags(secondSpan));
+        }
+    }
+
+
+    @SmallTest
+    public void testCopyConstructor_copiesAllSpans() {
+        SpannableString first = new SpannableString("t\nest data");
+        first.setSpan(new QuoteSpan(), 0, 2, Spanned.SPAN_PARAGRAPH);
+        first.setSpan(new LocaleSpan(Locale.US), 2, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+        first.setSpan(new UnderlineSpan(), 0, first.length(), Spanned.SPAN_PRIORITY);
+        Object[] firstSpans = first.getSpans(0, first.length(), Object.class);
+        assertNotNull(firstSpans);
+
+        SpannableString second = new SpannableString(first);
+        Object[] secondSpans = second.getSpans(0, second.length(), Object.class);
+        assertNotNull(secondSpans);
+        assertEquals("Spans.length should be equal", firstSpans.length, secondSpans.length);
+        for (int i = 0; i < firstSpans.length; i++) {
+            Object firstSpan = firstSpans[i];
+            Object secondSpan = secondSpans[i];
+            assertSame(firstSpan, secondSpan);
+            assertEquals(first.getSpanStart(firstSpan), second.getSpanStart(secondSpan));
+            assertEquals(first.getSpanEnd(firstSpan), second.getSpanEnd(secondSpan));
+            assertEquals(first.getSpanFlags(firstSpan), second.getSpanFlags(secondSpan));
+        }
+    }
+
 }
diff --git a/tests/tests/text/src/android/text/cts/StaticLayoutTest.java b/tests/tests/text/src/android/text/cts/StaticLayoutTest.java
index 329db88..ed3f1ea 100644
--- a/tests/tests/text/src/android/text/cts/StaticLayoutTest.java
+++ b/tests/tests/text/src/android/text/cts/StaticLayoutTest.java
@@ -16,23 +16,27 @@
 
 package android.text.cts;
 
+import android.graphics.Typeface;
 import android.test.AndroidTestCase;
 import android.text.Editable;
-import android.text.GetChars;
-import android.text.GraphicsOperations;
+import android.text.Layout;
 import android.text.Layout.Alignment;
-import android.text.TextUtils.TruncateAt;
 import android.text.SpannableString;
 import android.text.SpannableStringBuilder;
+import android.text.Spanned;
 import android.text.SpannedString;
 import android.text.StaticLayout;
 import android.text.TextDirectionHeuristics;
 import android.text.TextPaint;
 import android.text.TextUtils;
+import android.text.TextUtils.TruncateAt;
+import android.text.method.cts.EditorState;
+import android.text.style.StyleSpan;
 
 import java.text.Normalizer;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Locale;
 
 public class StaticLayoutTest extends AndroidTestCase {
     private static final float SPACE_MULTI = 1.0f;
@@ -980,6 +984,214 @@
         }
     }
 
+    private void moveCursorToRightCursorableOffset(EditorState state) {
+        assertEquals("The editor has selection", state.mSelectionStart, state.mSelectionEnd);
+        StaticLayout layout = StaticLayout.Builder.obtain(state.mText, 0, state.mText.length(),
+                mDefaultPaint, DEFAULT_OUTER_WIDTH).build();
+        final int newOffset = layout.getOffsetToRightOf(state.mSelectionStart);
+        state.mSelectionStart = state.mSelectionEnd = newOffset;
+    }
+
+    private void moveCursorToLeftCursorableOffset(EditorState state) {
+        assertEquals("The editor has selection", state.mSelectionStart, state.mSelectionEnd);
+        StaticLayout layout = StaticLayout.Builder.obtain(state.mText, 0, state.mText.length(),
+                mDefaultPaint, DEFAULT_OUTER_WIDTH).build();
+        final int newOffset = layout.getOffsetToLeftOf(state.mSelectionStart);
+        state.mSelectionStart = state.mSelectionEnd = newOffset;
+    }
+
+    public void testGetOffset_Emoji() {
+        EditorState state = new EditorState();
+
+        // Emojis
+        // U+00A9 is COPYRIGHT SIGN.
+        state.setByString("| U+00A9 U+00A9 U+00A9");
+        moveCursorToRightCursorableOffset(state);
+        state.assertEquals("U+00A9 | U+00A9 U+00A9");
+        moveCursorToRightCursorableOffset(state);
+        state.assertEquals("U+00A9 U+00A9 | U+00A9");
+        moveCursorToRightCursorableOffset(state);
+        state.assertEquals("U+00A9 U+00A9 U+00A9 |");
+        moveCursorToRightCursorableOffset(state);
+        state.assertEquals("U+00A9 U+00A9 U+00A9 |");
+        moveCursorToLeftCursorableOffset(state);
+        state.assertEquals("U+00A9 U+00A9 | U+00A9");
+        moveCursorToLeftCursorableOffset(state);
+        state.assertEquals("U+00A9 | U+00A9 U+00A9");
+        moveCursorToLeftCursorableOffset(state);
+        state.assertEquals("| U+00A9 U+00A9 U+00A9");
+        moveCursorToLeftCursorableOffset(state);
+        state.assertEquals("| U+00A9 U+00A9 U+00A9");
+
+        // Surrogate pairs
+        // U+1F468 is MAN.
+        state.setByString("| U+1F468 U+1F468 U+1F468");
+        moveCursorToRightCursorableOffset(state);
+        state.assertEquals("U+1F468 | U+1F468 U+1F468");
+        moveCursorToRightCursorableOffset(state);
+        state.assertEquals("U+1F468 U+1F468 | U+1F468");
+        moveCursorToRightCursorableOffset(state);
+        state.assertEquals("U+1F468 U+1F468 U+1F468 |");
+        moveCursorToRightCursorableOffset(state);
+        state.assertEquals("U+1F468 U+1F468 U+1F468 |");
+        moveCursorToLeftCursorableOffset(state);
+        state.assertEquals("U+1F468 U+1F468 | U+1F468");
+        moveCursorToLeftCursorableOffset(state);
+        state.assertEquals("U+1F468 | U+1F468 U+1F468");
+        moveCursorToLeftCursorableOffset(state);
+        state.assertEquals("| U+1F468 U+1F468 U+1F468");
+        moveCursorToLeftCursorableOffset(state);
+        state.assertEquals("| U+1F468 U+1F468 U+1F468");
+
+        // Keycaps
+        // U+20E3 is COMBINING ENCLOSING KEYCAP.
+        state.setByString("| '1' U+20E3 '1' U+20E3 '1' U+20E3");
+        moveCursorToRightCursorableOffset(state);
+        state.assertEquals("'1' U+20E3 | '1' U+20E3 '1' U+20E3");
+        moveCursorToRightCursorableOffset(state);
+        state.assertEquals("'1' U+20E3 '1' U+20E3 | '1' U+20E3");
+        moveCursorToRightCursorableOffset(state);
+        state.assertEquals("'1' U+20E3 '1' U+20E3 '1' U+20E3 |");
+        moveCursorToRightCursorableOffset(state);
+        state.assertEquals("'1' U+20E3 '1' U+20E3 '1' U+20E3 |");
+        moveCursorToLeftCursorableOffset(state);
+        state.assertEquals("'1' U+20E3 '1' U+20E3 | '1' U+20E3");
+        moveCursorToLeftCursorableOffset(state);
+        state.assertEquals("'1' U+20E3 | '1' U+20E3 '1' U+20E3");
+        moveCursorToLeftCursorableOffset(state);
+        state.assertEquals("| '1' U+20E3 '1' U+20E3 '1' U+20E3");
+        moveCursorToLeftCursorableOffset(state);
+        state.assertEquals("| '1' U+20E3 '1' U+20E3 '1' U+20E3");
+
+        // Variation selectors
+        // U+00A9 is COPYRIGHT SIGN, U+FE0E is VARIATION SELECTOR-15. U+FE0F is VARIATION
+        // SELECTOR-16.
+        state.setByString("| U+00A9 U+FE0E U+00A9 U+FE0F U+00A9 U+FE0E");
+        moveCursorToRightCursorableOffset(state);
+        state.assertEquals("U+00A9 U+FE0E | U+00A9 U+FE0F U+00A9 U+FE0E");
+        moveCursorToRightCursorableOffset(state);
+        state.assertEquals("U+00A9 U+FE0E U+00A9 U+FE0F | U+00A9 U+FE0E");
+        moveCursorToRightCursorableOffset(state);
+        state.assertEquals("U+00A9 U+FE0E U+00A9 U+FE0F U+00A9 U+FE0E |");
+        moveCursorToRightCursorableOffset(state);
+        state.assertEquals("U+00A9 U+FE0E U+00A9 U+FE0F U+00A9 U+FE0E |");
+        moveCursorToLeftCursorableOffset(state);
+        state.assertEquals("U+00A9 U+FE0E U+00A9 U+FE0F | U+00A9 U+FE0E");
+        moveCursorToLeftCursorableOffset(state);
+        state.assertEquals("U+00A9 U+FE0E | U+00A9 U+FE0F U+00A9 U+FE0E");
+        moveCursorToLeftCursorableOffset(state);
+        state.assertEquals("| U+00A9 U+FE0E U+00A9 U+FE0F U+00A9 U+FE0E");
+        moveCursorToLeftCursorableOffset(state);
+        state.assertEquals("| U+00A9 U+FE0E U+00A9 U+FE0F U+00A9 U+FE0E");
+
+        // Keycap + variation selector
+        state.setByString("| '1' U+FE0E U+20E3 '1' U+FE0E U+20E3 '1' U+FE0E U+20E3");
+        moveCursorToRightCursorableOffset(state);
+        state.assertEquals("'1' U+FE0E U+20E3 | '1' U+FE0E U+20E3 '1' U+FE0E U+20E3");
+        moveCursorToRightCursorableOffset(state);
+        state.assertEquals("'1' U+FE0E U+20E3 '1' U+FE0E U+20E3 | '1' U+FE0E U+20E3");
+        moveCursorToRightCursorableOffset(state);
+        state.assertEquals("'1' U+FE0E U+20E3 '1' U+FE0E U+20E3 '1' U+FE0E U+20E3 |");
+        moveCursorToRightCursorableOffset(state);
+        state.assertEquals("'1' U+FE0E U+20E3 '1' U+FE0E U+20E3 '1' U+FE0E U+20E3 |");
+        moveCursorToLeftCursorableOffset(state);
+        state.assertEquals("'1' U+FE0E U+20E3 '1' U+FE0E U+20E3 | '1' U+FE0E U+20E3");
+        moveCursorToLeftCursorableOffset(state);
+        state.assertEquals("'1' U+FE0E U+20E3 | '1' U+FE0E U+20E3 '1' U+FE0E U+20E3");
+        moveCursorToLeftCursorableOffset(state);
+        state.assertEquals("| '1' U+FE0E U+20E3 '1' U+FE0E U+20E3 '1' U+FE0E U+20E3");
+        moveCursorToLeftCursorableOffset(state);
+        state.assertEquals("| '1' U+FE0E U+20E3 '1' U+FE0E U+20E3 '1' U+FE0E U+20E3");
+
+        // Flags
+        // U+1F1E6 U+1F1E8 is Ascension Island flag.
+        state.setByString("| U+1F1E6 U+1F1E8 U+1F1E6 U+1F1E8 U+1F1E6 U+1F1E8");
+        moveCursorToRightCursorableOffset(state);
+        state.assertEquals("U+1F1E6 U+1F1E8 | U+1F1E6 U+1F1E8 U+1F1E6 U+1F1E8");
+        moveCursorToRightCursorableOffset(state);
+        state.assertEquals("U+1F1E6 U+1F1E8 U+1F1E6 U+1F1E8 | U+1F1E6 U+1F1E8");
+        moveCursorToRightCursorableOffset(state);
+        state.assertEquals("U+1F1E6 U+1F1E8 U+1F1E6 U+1F1E8 U+1F1E6 U+1F1E8 |");
+        moveCursorToRightCursorableOffset(state);
+        state.assertEquals("U+1F1E6 U+1F1E8 U+1F1E6 U+1F1E8 U+1F1E6 U+1F1E8 |");
+        moveCursorToLeftCursorableOffset(state);
+        state.assertEquals("U+1F1E6 U+1F1E8 U+1F1E6 U+1F1E8 | U+1F1E6 U+1F1E8");
+        moveCursorToLeftCursorableOffset(state);
+        state.assertEquals("U+1F1E6 U+1F1E8 | U+1F1E6 U+1F1E8 U+1F1E6 U+1F1E8");
+        moveCursorToLeftCursorableOffset(state);
+        state.assertEquals("| U+1F1E6 U+1F1E8 U+1F1E6 U+1F1E8 U+1F1E6 U+1F1E8");
+        moveCursorToLeftCursorableOffset(state);
+        state.assertEquals("| U+1F1E6 U+1F1E8 U+1F1E6 U+1F1E8 U+1F1E6 U+1F1E8");
+    }
+
+    public void testGetOffsetForHorizontal_Multilines() {
+        // Emoticons for surrogate pairs tests.
+        String testString = "\uD83D\uDE00\uD83D\uDE01\uD83D\uDE02\uD83D\uDE03\uD83D\uDE04";
+        final float width = mDefaultPaint.measureText(testString, 0, 6);
+        StaticLayout layout = new StaticLayout(testString, mDefaultPaint, (int)width,
+                DEFAULT_ALIGN, SPACE_MULTI, SPACE_ADD, true);
+        // We expect the line break to be after the third emoticon, but we allow flexibility of the
+        // line break algorithm as long as the break is within the string. These other cases might
+        // happen if for example the font has kerning between emoticons.
+        final int lineBreakOffset = layout.getOffsetForHorizontal(1, 0.0f);
+        assertEquals(0, layout.getLineForOffset(lineBreakOffset - 1));
+
+        assertEquals(0, layout.getOffsetForHorizontal(0, 0.0f));
+        assertEquals(lineBreakOffset - 2, layout.getOffsetForHorizontal(0, width));
+        assertEquals(lineBreakOffset - 2, layout.getOffsetForHorizontal(0, width * 2));
+
+        final int lineCount = layout.getLineCount();
+        assertEquals(testString.length(), layout.getOffsetForHorizontal(lineCount - 1, width));
+        assertEquals(testString.length(), layout.getOffsetForHorizontal(lineCount - 1, width * 2));
+    }
+
+    public void testIsRtlCharAt() {
+        {
+            String testString = "ab(\u0623\u0624)c\u0625";
+            StaticLayout layout = new StaticLayout(testString, mDefaultPaint,
+                    DEFAULT_OUTER_WIDTH, DEFAULT_ALIGN, SPACE_MULTI, SPACE_ADD, true);
+
+            assertFalse(layout.isRtlCharAt(0));
+            assertFalse(layout.isRtlCharAt(1));
+            assertFalse(layout.isRtlCharAt(2));
+            assertTrue(layout.isRtlCharAt(3));
+            assertTrue(layout.isRtlCharAt(4));
+            assertFalse(layout.isRtlCharAt(5));
+            assertFalse(layout.isRtlCharAt(6));
+            assertTrue(layout.isRtlCharAt(7));
+        }
+        {
+            String testString = "\u0623\u0624(ab)\u0625c";
+            StaticLayout layout = new StaticLayout(testString, mDefaultPaint,
+                    DEFAULT_OUTER_WIDTH, DEFAULT_ALIGN, SPACE_MULTI, SPACE_ADD, true);
+
+            assertTrue(layout.isRtlCharAt(0));
+            assertTrue(layout.isRtlCharAt(1));
+            assertTrue(layout.isRtlCharAt(2));
+            assertFalse(layout.isRtlCharAt(3));
+            assertFalse(layout.isRtlCharAt(4));
+            assertTrue(layout.isRtlCharAt(5));
+            assertTrue(layout.isRtlCharAt(6));
+            assertFalse(layout.isRtlCharAt(7));
+            assertFalse(layout.isRtlCharAt(8));
+        }
+    }
+
+    public void testGetHorizontal() {
+        String testString = "abc\u0623\u0624\u0625def";
+        StaticLayout layout = new StaticLayout(testString, mDefaultPaint,
+                DEFAULT_OUTER_WIDTH, DEFAULT_ALIGN, SPACE_MULTI, SPACE_ADD, true);
+
+        assertEquals(layout.getPrimaryHorizontal(0), layout.getSecondaryHorizontal(0));
+        assertTrue(layout.getPrimaryHorizontal(0) < layout.getPrimaryHorizontal(3));
+        assertTrue(layout.getPrimaryHorizontal(3) < layout.getSecondaryHorizontal(3));
+        assertTrue(layout.getPrimaryHorizontal(4) < layout.getSecondaryHorizontal(3));
+        assertEquals(layout.getPrimaryHorizontal(4), layout.getSecondaryHorizontal(4));
+        assertEquals(layout.getPrimaryHorizontal(3), layout.getSecondaryHorizontal(6));
+        assertEquals(layout.getPrimaryHorizontal(6), layout.getSecondaryHorizontal(3));
+        assertEquals(layout.getPrimaryHorizontal(7), layout.getSecondaryHorizontal(7));
+    }
+
     public void testVeryLargeString() {
         final int MAX_COUNT = 1 << 21;
         final int WORD_SIZE = 32;
@@ -993,4 +1205,20 @@
                 DEFAULT_ALIGN, SPACE_MULTI, SPACE_ADD, true);
         assertNotNull(layout);
     }
+
+    public void testDoesntCrashWhenWordStyleOverlap() {
+       // test case where word boundary overlaps multiple style spans
+       SpannableStringBuilder text = new SpannableStringBuilder("word boundaries, overlap style");
+       // span covers "boundaries"
+       text.setSpan(new StyleSpan(Typeface.BOLD),
+                   "word ".length(), "word boundaries".length(),
+                   Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+       mDefaultPaint.setTextLocale(Locale.US);
+       StaticLayout layout = StaticLayout.Builder.obtain(text, 0, text.length(),
+               mDefaultPaint, DEFAULT_OUTER_WIDTH)
+               .setBreakStrategy(Layout.BREAK_STRATEGY_HIGH_QUALITY)  // enable hyphenation
+               .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL)
+               .build();
+       assertNotNull(layout);
+    }
 }
diff --git a/tests/tests/text/src/android/text/cts/TextUtilsTest.java b/tests/tests/text/src/android/text/cts/TextUtilsTest.java
index 694513e..0da1eb4 100644
--- a/tests/tests/text/src/android/text/cts/TextUtilsTest.java
+++ b/tests/tests/text/src/android/text/cts/TextUtilsTest.java
@@ -44,9 +44,6 @@
 import android.util.Log;
 import android.util.StringBuilderPrinter;
 
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-
 import java.util.ArrayList;
 import java.util.Locale;
 import java.util.regex.Pattern;
@@ -1333,11 +1330,20 @@
     }
 
     public void testIsDigitsOnly() {
+        assertTrue(TextUtils.isDigitsOnly(""));
         assertFalse(TextUtils.isDigitsOnly("no digit"));
         assertFalse(TextUtils.isDigitsOnly("character and 56 digits"));
         assertTrue(TextUtils.isDigitsOnly("0123456789"));
         assertFalse(TextUtils.isDigitsOnly("1234 56789"));
 
+        // U+104A0 OSMANYA DIGIT ZERO
+        assertTrue(TextUtils.isDigitsOnly(new String(Character.toChars(0x104A0))));
+        // U+10858 IMPERIAL ARAMAIC NUMBER ONE
+        assertFalse(TextUtils.isDigitsOnly(new String(Character.toChars(0x10858))));
+
+        assertFalse(TextUtils.isDigitsOnly("\uD801")); // lonely lead surrogate
+        assertFalse(TextUtils.isDigitsOnly("\uDCA0")); // lonely trailing surrogate
+
         try {
             TextUtils.isDigitsOnly(null);
             fail("Should throw NullPointerException!");
@@ -1355,7 +1361,7 @@
 
     public void testIsGraphicChar() {
         assertTrue(TextUtils.isGraphic('a'));
-        assertTrue(TextUtils.isGraphic("\uBA00"));
+        assertTrue(TextUtils.isGraphic('\uBA00'));
 
         // LINE_SEPARATOR
         assertFalse(TextUtils.isGraphic('\u2028'));
@@ -1390,6 +1396,11 @@
 
         assertTrue(TextUtils.isGraphic("a\u2028\u2029\u0085\u0D00\uD800\u0020"));
 
+        assertTrue(TextUtils.isGraphic("\uD83D\uDC0C")); // U+1F40C SNAIL
+        assertFalse(TextUtils.isGraphic("\uDB40\uDC01")); // U+E0000 (unassigned)
+        assertFalse(TextUtils.isGraphic("\uDB3D")); // unpaired high surrogate
+        assertFalse(TextUtils.isGraphic("\uDC0C")); // unpaired low surrogate
+
         try {
             TextUtils.isGraphic(null);
             fail("Should throw NullPointerException!");
@@ -2033,11 +2044,6 @@
         assertTrue(builder.length() > 0);
     }
 
-    @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            method = "getLayoutDirectionFromLocale",
-            args = {Locale.class}
-    )
     public void testGetLayoutDirectionFromLocale() {
         assertEquals(LAYOUT_DIRECTION_LTR,
                 TextUtils.getLayoutDirectionFromLocale(null));
diff --git a/tests/tests/text/src/android/text/format/cts/DateFormatTest.java b/tests/tests/text/src/android/text/format/cts/DateFormatTest.java
index 8ca1fea..1808c85 100644
--- a/tests/tests/text/src/android/text/format/cts/DateFormatTest.java
+++ b/tests/tests/text/src/android/text/format/cts/DateFormatTest.java
@@ -28,6 +28,7 @@
 import java.text.SimpleDateFormat;
 import java.io.FileInputStream;
 import java.io.InputStream;
+import java.util.Arrays;
 import java.util.Calendar;
 import java.util.Date;
 import java.util.GregorianCalendar;
@@ -257,4 +258,36 @@
         checkFormat("12", "h", 24);
         checkFormat( "0", "H", 24);
     }
+
+    public void test_bug_82144() {
+        for (Locale locale : Locale.getAvailableLocales()) {
+            if (locale.toString().startsWith("haw")) {
+                // http://b/26397197 - remove this when fixed.
+                continue;
+            }
+            Locale.setDefault(locale);
+            char[] order = DateFormat.getDateFormatOrder(mContext);
+            boolean seenDay = false, seenMonth = false, seenYear = false;
+            for (char c : order) {
+                switch (c) {
+                    case 'd':
+                        seenDay = true;
+                        break;
+                    case 'M':
+                        seenMonth = true;
+                        break;
+                    case 'y':
+                        seenYear = true;
+                        break;
+                    default:
+                        fail("Unknown character: " + c + " in " + Arrays.toString(order)
+                                + " for " + locale);
+                        break;
+                }
+            }
+            assertTrue(locale.toString() + " day not found", seenDay);
+            assertTrue(locale.toString() + " month not found", seenMonth);
+            assertTrue(locale.toString() + " year not found", seenYear);
+        }
+    }
 }
diff --git a/tests/tests/text/src/android/text/format/cts/DateUtilsTest.java b/tests/tests/text/src/android/text/format/cts/DateUtilsTest.java
index 9ab815f..f0a4d09 100644
--- a/tests/tests/text/src/android/text/format/cts/DateUtilsTest.java
+++ b/tests/tests/text/src/android/text/format/cts/DateUtilsTest.java
@@ -19,7 +19,6 @@
 import android.content.Context;
 import android.test.AndroidTestCase;
 import android.text.format.DateUtils;
-import dalvik.annotation.KnownFailure;
 import java.util.Calendar;
 import java.util.Date;
 import java.util.Formatter;
diff --git a/tests/tests/text/src/android/text/format/cts/FormatterTest.java b/tests/tests/text/src/android/text/format/cts/FormatterTest.java
index 9c3c45d..6acfb84 100644
--- a/tests/tests/text/src/android/text/format/cts/FormatterTest.java
+++ b/tests/tests/text/src/android/text/format/cts/FormatterTest.java
@@ -32,9 +32,14 @@
         BigDecimal bd = new BigDecimal((long) 1024, mc);
 
         // test different long values with various length
-        assertEquals("0.00 B", Formatter.formatFileSize(mContext, 0));
-
-        assertEquals("899 B", Formatter.formatFileSize(mContext, 899));
+        assertEquals("0 B", Formatter.formatFileSize(mContext, 0));
+        assertEquals("1 B", Formatter.formatFileSize(mContext, 1));
+        assertEquals("9 B", Formatter.formatFileSize(mContext, 9));
+        assertEquals("10 B", Formatter.formatFileSize(mContext, 10));
+        assertEquals("99 B", Formatter.formatFileSize(mContext, 99));
+        assertEquals("100 B", Formatter.formatFileSize(mContext, 100));
+        assertEquals("900 B", Formatter.formatFileSize(mContext, 900));
+        assertEquals("0.88 KB", Formatter.formatFileSize(mContext, 901));
 
         assertEquals("1.00 KB", Formatter.formatFileSize(mContext, bd.pow(1).longValue()));
 
@@ -49,7 +54,7 @@
         assertEquals("1024 PB", Formatter.formatFileSize(mContext, bd.pow(6).longValue()));
 
         // test Negative value
-        assertEquals("-1.00 B", Formatter.formatFileSize(mContext, -1));
+        assertEquals("-1 B", Formatter.formatFileSize(mContext, -1));
     }
 
     public void testFormatIpAddress() {
diff --git a/tests/tests/text/src/android/text/format/cts/TimeTest.java b/tests/tests/text/src/android/text/format/cts/TimeTest.java
index 37c4f27..cc73272 100644
--- a/tests/tests/text/src/android/text/format/cts/TimeTest.java
+++ b/tests/tests/text/src/android/text/format/cts/TimeTest.java
@@ -813,10 +813,10 @@
         assertFormatEquals(t, "%m", "06");
         assertFormatEquals(t, "%n", "\n");
         assertFormatEquals(t, "%O", "O");
-        assertFormatEquals(t, "%p", "p.m.");
-        assertFormatEquals(t, "%P", "p.m.");
+        assertFormatEquals(t, "%p", "pm");
+        assertFormatEquals(t, "%P", "pm");
         assertFormatEquals(t, "%R", "12:30");
-        assertFormatEquals(t, "%r", "12:30:15 p.m.");
+        assertFormatEquals(t, "%r", "12:30:15 pm");
         assertFormatEquals(t, "%S", "15");
         // The original C implementation uses the (native) system default TZ, not the timezone of
         // the Time to calculate this and was therefore not stable. This changed to use the Time's
diff --git a/tests/tests/text/src/android/text/method/cts/ArrowKeyMovementMethodTest.java b/tests/tests/text/src/android/text/method/cts/ArrowKeyMovementMethodTest.java
index 482edb0..3d5335d 100644
--- a/tests/tests/text/src/android/text/method/cts/ArrowKeyMovementMethodTest.java
+++ b/tests/tests/text/src/android/text/method/cts/ArrowKeyMovementMethodTest.java
@@ -56,7 +56,7 @@
     private MyMetaKeyKeyListener mMetaListener;
 
     public ArrowKeyMovementMethodTest() {
-        super("com.android.cts.text", CtsActivity.class);
+        super("android.text.cts", CtsActivity.class);
     }
 
     @Override
@@ -180,8 +180,8 @@
     @UiThreadTest
     public void testOnKeyDownWithKeyCodeUp() {
         // shift+alt tests
-        KeyEvent shiftAltEvent = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_UP,
-                0, KeyEvent.META_ALT_ON | KeyEvent.META_SHIFT_ON);
+        final KeyEvent shiftAltEvent = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN,
+                KeyEvent.KEYCODE_DPAD_UP, 0, KeyEvent.META_ALT_ON | KeyEvent.META_SHIFT_ON);
 
         // first line
         // second |line
@@ -532,6 +532,270 @@
         assertSelection(START_OF_3RD_LINE);
     }
 
+    @UiThreadTest
+    public void testOnKeyDownWithKeyCodePageUp() {
+        // shift+alt tests
+        KeyEvent shiftAltEvent = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN,
+                KeyEvent.KEYCODE_PAGE_UP, 0, KeyEvent.META_ALT_ON | KeyEvent.META_SHIFT_ON);
+
+        // first line
+        // second |line
+        // last line
+        Selection.setSelection(mEditable, SPACE_IN_2ND_LINE);
+        pressBothShiftAlt();
+        assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
+                KeyEvent.KEYCODE_PAGE_UP, shiftAltEvent));
+        // |first line
+        // second |line
+        // last line
+        assertSelection(SPACE_IN_2ND_LINE, 0);
+
+        // shift tests
+        KeyEvent shiftEvent = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_PAGE_UP,
+                0, KeyEvent.META_SHIFT_ON);
+
+        Selection.setSelection(mEditable, SPACE_IN_2ND_LINE);
+        pressShift();
+        assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
+                KeyEvent.KEYCODE_PAGE_UP, shiftEvent));
+        // |first line
+        // second |line
+        // last line
+        assertSelection(SPACE_IN_2ND_LINE, 0);
+
+        // alt tests
+        KeyEvent altEvent = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_PAGE_UP, 0,
+                KeyEvent.META_ALT_ON);
+
+        Selection.setSelection(mEditable, SPACE_IN_2ND_LINE);
+        pressAlt();
+        assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
+                KeyEvent.KEYCODE_PAGE_UP, altEvent));
+        // |first line
+        // second line
+        // last line
+        assertSelection(0);
+
+        // no-meta tests
+        KeyEvent noMetaEvent = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_PAGE_UP,
+                0, 0);
+
+        Selection.setSelection(mEditable, SPACE_IN_2ND_LINE);
+        MetaKeyKeyListener.resetMetaState(mEditable);
+        assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
+                KeyEvent.KEYCODE_PAGE_UP, noMetaEvent));
+        // |first line
+        // second line
+        // last line
+        assertSelection(0);
+    }
+
+    @UiThreadTest
+    public void testOnKeyDownWithKeyCodePageDown() {
+        // shift+alt tests
+        KeyEvent shiftAltEvent = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN,
+                KeyEvent.KEYCODE_PAGE_DOWN, 0, KeyEvent.META_ALT_ON | KeyEvent.META_SHIFT_ON);
+
+        // first line
+        // second |line
+        // last line
+        Selection.setSelection(mEditable, SPACE_IN_2ND_LINE);
+        pressBothShiftAlt();
+        assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
+                KeyEvent.KEYCODE_PAGE_DOWN, shiftAltEvent));
+        // first line
+        // second |line
+        // last line|
+        assertSelection(SPACE_IN_2ND_LINE, END_OF_ALL_TEXT);
+
+        // shift tests
+        KeyEvent shiftEvent = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_PAGE_DOWN,
+                0, KeyEvent.META_SHIFT_ON);
+
+        Selection.setSelection(mEditable, SPACE_IN_2ND_LINE);
+        pressShift();
+        assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
+                KeyEvent.KEYCODE_PAGE_DOWN, shiftEvent));
+        // first line
+        // second |line
+        // last line|
+        assertSelection(SPACE_IN_2ND_LINE, END_OF_ALL_TEXT);
+
+        // alt tests
+        KeyEvent altEvent = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_PAGE_DOWN, 0,
+                KeyEvent.META_ALT_ON);
+
+        Selection.setSelection(mEditable, SPACE_IN_2ND_LINE);
+        pressAlt();
+        assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
+                KeyEvent.KEYCODE_PAGE_DOWN, altEvent));
+        // first line
+        // second line
+        // last line|
+        assertSelection(END_OF_ALL_TEXT);
+
+        // no-meta tests
+        KeyEvent noMetaEvent = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_PAGE_DOWN,
+                0, 0);
+
+        Selection.setSelection(mEditable, SPACE_IN_2ND_LINE);
+        MetaKeyKeyListener.resetMetaState(mEditable);
+        assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
+                KeyEvent.KEYCODE_PAGE_DOWN, noMetaEvent));
+        // first line
+        // second line
+        // last line|
+        assertSelection(END_OF_ALL_TEXT);
+    }
+
+    @UiThreadTest
+    public void testOnKeyDownWithKeyCodeMoveHome() {
+        // shift+ctrl tests
+        KeyEvent shiftAltEvent = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN,
+                KeyEvent.KEYCODE_MOVE_HOME, 0, KeyEvent.META_SHIFT_ON | KeyEvent.META_CTRL_ON);
+
+        // first line
+        // second |line
+        // last line
+        Selection.setSelection(mEditable, SPACE_IN_2ND_LINE);
+        pressShift();
+        assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
+                KeyEvent.KEYCODE_MOVE_HOME, shiftAltEvent));
+        // |first line
+        // second |line
+        // last line
+        assertSelection(SPACE_IN_2ND_LINE, 0);
+
+        // shift tests
+        KeyEvent shiftEvent = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MOVE_HOME,
+                0, KeyEvent.META_SHIFT_ON);
+
+        Selection.setSelection(mEditable, SPACE_IN_2ND_LINE);
+        pressShift();
+        assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
+                KeyEvent.KEYCODE_MOVE_HOME, shiftEvent));
+        // first line
+        // |second |line
+        // last line
+        assertSelection(SPACE_IN_2ND_LINE, START_OF_2ND_LINE);
+
+        pressShift();
+        assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
+                KeyEvent.KEYCODE_MOVE_HOME, shiftEvent));
+        // first line
+        // |second |line
+        // last line
+        assertSelection(SPACE_IN_2ND_LINE, START_OF_2ND_LINE);
+
+        // ctrl tests
+        KeyEvent altEvent = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MOVE_HOME, 0,
+                KeyEvent.META_CTRL_ON);
+
+        Selection.setSelection(mEditable, SPACE_IN_2ND_LINE);
+        MetaKeyKeyListener.resetMetaState(mEditable);
+        assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
+                KeyEvent.KEYCODE_MOVE_HOME, altEvent));
+        // |first line
+        // second line
+        // last line
+        assertSelection(0);
+
+        // no-meta tests
+        KeyEvent noMetaEvent = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MOVE_HOME,
+                0, 0);
+
+        Selection.setSelection(mEditable, SPACE_IN_2ND_LINE);
+        MetaKeyKeyListener.resetMetaState(mEditable);
+        assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
+                KeyEvent.KEYCODE_MOVE_HOME, noMetaEvent));
+        // first line
+        // |second line
+        // last line
+        assertSelection(START_OF_2ND_LINE);
+
+        MetaKeyKeyListener.resetMetaState(mEditable);
+        assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
+                KeyEvent.KEYCODE_MOVE_HOME, noMetaEvent));
+        // first line
+        // |second line
+        // last line
+        assertSelection(START_OF_2ND_LINE);
+    }
+
+    @UiThreadTest
+    public void testOnKeyDownWithKeyCodeMoveEnd() {
+        // shift+ctrl tests
+        KeyEvent shiftAltEvent = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN,
+                KeyEvent.KEYCODE_MOVE_END, 0, KeyEvent.META_SHIFT_ON | KeyEvent.META_CTRL_ON);
+
+        // first line
+        // second |line
+        // last line
+        Selection.setSelection(mEditable, SPACE_IN_2ND_LINE);
+        pressShift();
+        assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
+                KeyEvent.KEYCODE_MOVE_END, shiftAltEvent));
+        // first line
+        // second |line
+        // last line|
+        assertSelection(SPACE_IN_2ND_LINE, END_OF_ALL_TEXT);
+
+        // shift tests
+        KeyEvent shiftEvent = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MOVE_END,
+                0, KeyEvent.META_SHIFT_ON);
+
+        Selection.setSelection(mEditable, SPACE_IN_2ND_LINE);
+        pressShift();
+        assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
+                KeyEvent.KEYCODE_MOVE_END, shiftEvent));
+        // first line
+        // second |line|
+        // last line
+        assertSelection(SPACE_IN_2ND_LINE, END_OF_2ND_LINE);
+
+        pressShift();
+        assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
+                KeyEvent.KEYCODE_MOVE_END, shiftEvent));
+        // first line
+        // second |line|
+        // last line
+        assertSelection(SPACE_IN_2ND_LINE, END_OF_2ND_LINE);
+
+        // ctrl tests
+        KeyEvent altEvent = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MOVE_END, 0,
+                KeyEvent.META_CTRL_ON);
+
+        Selection.setSelection(mEditable, SPACE_IN_2ND_LINE);
+        MetaKeyKeyListener.resetMetaState(mEditable);
+        assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
+                KeyEvent.KEYCODE_MOVE_END, altEvent));
+        // first line
+        // second line
+        // last line|
+        assertSelection(END_OF_ALL_TEXT);
+
+        // no-meta tests
+        KeyEvent noMetaEvent = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MOVE_END,
+                0, 0);
+
+        Selection.setSelection(mEditable, SPACE_IN_2ND_LINE);
+        MetaKeyKeyListener.resetMetaState(mEditable);
+        assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
+                KeyEvent.KEYCODE_MOVE_END, noMetaEvent));
+        // first line
+        // second line|
+        // last line
+        assertSelection(END_OF_2ND_LINE);
+
+        MetaKeyKeyListener.resetMetaState(mEditable);
+        assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
+                KeyEvent.KEYCODE_MOVE_END, noMetaEvent));
+        // first line
+        // second line|
+        // last line
+        assertSelection(END_OF_2ND_LINE);
+    }
+
     public void testOnKeyDownWithNullLayout() {
         initTextViewWithNullLayout();
         try {
@@ -567,8 +831,16 @@
                 new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_LEFT, 0)));
         assertFalse(mArrowKeyMovementMethod.onKeyOther(mTextView, mEditable,
                 new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_RIGHT, 0)));
+        assertFalse(mArrowKeyMovementMethod.onKeyOther(mTextView, mEditable,
+                new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_PAGE_UP, 0)));
+        assertFalse(mArrowKeyMovementMethod.onKeyOther(mTextView, mEditable,
+                new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_PAGE_DOWN, 0)));
+        assertFalse(mArrowKeyMovementMethod.onKeyOther(mTextView, mEditable,
+                new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MOVE_HOME, 0)));
+        assertFalse(mArrowKeyMovementMethod.onKeyOther(mTextView, mEditable,
+                new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MOVE_END, 0)));
 
-        // only repeat arrow key events get handled
+        // only repeat arrow key, page up/down and move home/end events get handled
         assertTrue(mArrowKeyMovementMethod.onKeyOther(mTextView, mEditable,
                 new KeyEvent(0, 0, KeyEvent.ACTION_MULTIPLE, KeyEvent.KEYCODE_DPAD_UP, 2)));
         assertTrue(mArrowKeyMovementMethod.onKeyOther(mTextView, mEditable,
@@ -577,6 +849,14 @@
                 new KeyEvent(0, 0, KeyEvent.ACTION_MULTIPLE, KeyEvent.KEYCODE_DPAD_LEFT, 2)));
         assertTrue(mArrowKeyMovementMethod.onKeyOther(mTextView, mEditable,
                 new KeyEvent(0, 0, KeyEvent.ACTION_MULTIPLE, KeyEvent.KEYCODE_DPAD_RIGHT, 2)));
+        assertTrue(mArrowKeyMovementMethod.onKeyOther(mTextView, mEditable,
+                new KeyEvent(0, 0, KeyEvent.ACTION_MULTIPLE, KeyEvent.KEYCODE_PAGE_UP, 2)));
+        assertTrue(mArrowKeyMovementMethod.onKeyOther(mTextView, mEditable,
+                new KeyEvent(0, 0, KeyEvent.ACTION_MULTIPLE, KeyEvent.KEYCODE_PAGE_DOWN, 2)));
+        assertTrue(mArrowKeyMovementMethod.onKeyOther(mTextView, mEditable,
+                new KeyEvent(0, 0, KeyEvent.ACTION_MULTIPLE, KeyEvent.KEYCODE_MOVE_HOME, 2)));
+        assertTrue(mArrowKeyMovementMethod.onKeyOther(mTextView, mEditable,
+                new KeyEvent(0, 0, KeyEvent.ACTION_MULTIPLE, KeyEvent.KEYCODE_MOVE_END, 2)));
     }
 
     @UiThreadTest
diff --git a/tests/tests/text/src/android/text/method/cts/BackspaceTest.java b/tests/tests/text/src/android/text/method/cts/BackspaceTest.java
new file mode 100644
index 0000000..fa2e262
--- /dev/null
+++ b/tests/tests/text/src/android/text/method/cts/BackspaceTest.java
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.text.method.cts;
+
+import android.app.Activity;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.test.suitebuilder.annotation.Suppress;
+import android.text.InputType;
+import android.text.method.BaseKeyListener;
+import android.text.method.cts.KeyListenerTestCase;
+import android.view.KeyEvent;
+import android.widget.EditText;
+import android.widget.TextView.BufferType;
+
+/**
+ * Test backspace key handling of {@link android.text.method.BaseKeyListner}.
+ */
+public class BackspaceTest extends KeyListenerTestCase {
+    private static final BaseKeyListener mKeyListener = new BaseKeyListener() {
+        public int getInputType() {
+            return InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_NORMAL;
+        }
+    };
+
+    // Sync the state to the TextView and call onKeyDown with KEYCODE_DEL key event.
+    // Then update the state to the result of TextView.
+    private void backspace(final EditorState state, int modifiers) {
+        mActivity.runOnUiThread(new Runnable() {
+            public void run() {
+                mTextView.setText(state.mText, BufferType.EDITABLE);
+                mTextView.setKeyListener(mKeyListener);
+                mTextView.setSelection(state.mSelectionStart, state.mSelectionEnd);
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+        assertTrue(mTextView.hasWindowFocus());
+
+        final KeyEvent keyEvent = getKey(KeyEvent.KEYCODE_DEL, modifiers);
+        mActivity.runOnUiThread(new Runnable() {
+            public void run() {
+                mTextView.onKeyDown(keyEvent.getKeyCode(), keyEvent);
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+
+        state.mText = mTextView.getText();
+        state.mSelectionStart = mTextView.getSelectionStart();
+        state.mSelectionEnd = mTextView.getSelectionEnd();
+    }
+
+    @SmallTest
+    public void testSurrogatePairs() {
+        EditorState state = new EditorState();
+
+        state.setByString("U+1F441 |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        state.setByString("U+1F441 U+1F5E8 |");
+        backspace(state, 0);
+        state.assertEquals("U+1F441 |");
+        backspace(state, 0);
+        state.assertEquals("|");
+    }
+
+    @SmallTest
+    public void testReplacementSpan() {
+        EditorState state = new EditorState();
+
+        // ReplacementSpan will be set to "()" region.
+        state.setByString("'abc' ( 'de' ) 'fg' |");
+        backspace(state, 0);
+        state.assertEquals("'abc' ( 'de' ) 'f' |");
+        backspace(state, 0);
+        state.assertEquals("'abc' ( 'de' ) |");
+        backspace(state, 0);
+        state.assertEquals("'abc' |");
+        backspace(state, 0);
+        state.assertEquals("'ab' |");
+        backspace(state, 0);
+        state.assertEquals("'a' |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        state.setByString("'abc' [ ( 'de' ) ] 'fg'");
+        backspace(state, 0);
+        state.assertEquals("'abc' | 'fg'");
+        backspace(state, 0);
+        state.assertEquals("'ab' | 'fg'");
+        backspace(state, 0);
+        state.assertEquals("'a' | 'fg'");
+        backspace(state, 0);
+        state.assertEquals("| 'fg'");
+        backspace(state, 0);
+        state.assertEquals("| 'fg'");
+
+        state.setByString("'ab' [ 'c' ( 'de' ) 'f' ] 'g'");
+        backspace(state, 0);
+        state.assertEquals("'ab' | 'g'");
+        backspace(state, 0);
+        state.assertEquals("'a' | 'g'");
+        backspace(state, 0);
+        state.assertEquals("| 'g'");
+        backspace(state, 0);
+        state.assertEquals("| 'g'");
+    }
+
+    @SmallTest
+    public void testCombiningEnclosingKeycaps() {
+        EditorState state = new EditorState();
+
+        // U+20E3 is COMBINING ENCLOSING KEYCAP.
+        state.setByString("'1' U+20E3 |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        // Variation selector before COMBINING ECLOSING KEYCAP
+        state.setByString("'1' U+FE0E U+20E3 |");
+        backspace(state, 0);
+        state.assertEquals("|");
+    }
+
+    @SmallTest
+    public void testVariationSelector() {
+        EditorState state = new EditorState();
+
+        // U+FE0F is VARIATION SELECTOR-16.
+        state.setByString("'#' U+FE0F |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        // U+E0100 is VARIATION SELECTOR-17.
+        state.setByString("U+845B U+E0100 |");
+        backspace(state, 0);
+        state.assertEquals("|");
+    }
+
+    @SmallTest
+    public void testFlags() {
+        EditorState state = new EditorState();
+
+        // U+1F1FA is REGIONAL INDICATOR SYMBOL LETTER U.
+        // U+1F1F8 is REGIONAL INDICATOR SYMBOL LETTER S.
+        state.setByString("U+1F1FA U+1F1F8 |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        state.setByString("'a' U+1F1FA U+1F1F8 |");
+        backspace(state, 0);
+        state.assertEquals("'a' |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        state.setByString("U+1F1FA U+1F1F8 U+1F1FA U+1F1F8 |");
+        backspace(state, 0);
+        state.assertEquals("U+1F1FA U+1F1F8 |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        state.setByString("'a' U+1F1FA U+1F1F8 'b' U+1F1FA U+1F1F8 |");
+        backspace(state, 0);
+        state.assertEquals("'a' U+1F1FA U+1F1F8 'b' |");
+        backspace(state, 0);
+        state.assertEquals("'a' U+1F1FA U+1F1F8 |");
+        backspace(state, 0);
+        state.assertEquals("'a' |");
+        backspace(state, 0);
+        state.assertEquals("|");
+    }
+}
diff --git a/tests/tests/text/src/android/text/method/cts/BaseKeyListenerTest.java b/tests/tests/text/src/android/text/method/cts/BaseKeyListenerTest.java
index ba8bad5..8fa8780 100644
--- a/tests/tests/text/src/android/text/method/cts/BaseKeyListenerTest.java
+++ b/tests/tests/text/src/android/text/method/cts/BaseKeyListenerTest.java
@@ -535,17 +535,6 @@
         listener.forwardDelete(mTextView, content, KeyEvent.KEYCODE_FORWARD_DEL, delKeyEvent);
     }
 
-    private KeyEvent getKey(int keycode, int metaState) {
-        long currentTime = System.currentTimeMillis();
-        return new KeyEvent(
-                currentTime,
-                currentTime,
-                KeyEvent.ACTION_DOWN,
-                keycode,
-                0 /* repeat */,
-                metaState);
-    }
-
     /**
      * Prepares mTextView state for tests by synchronously setting the content and key listener, on
      * the UI thread.
diff --git a/tests/tests/text/src/android/text/method/cts/CharacterPickerDialogTest.java b/tests/tests/text/src/android/text/method/cts/CharacterPickerDialogTest.java
index 382fc77..6ab79ad 100644
--- a/tests/tests/text/src/android/text/method/cts/CharacterPickerDialogTest.java
+++ b/tests/tests/text/src/android/text/method/cts/CharacterPickerDialogTest.java
@@ -35,7 +35,7 @@
     private Activity mActivity;
 
     public CharacterPickerDialogTest() {
-        super("com.android.cts.text", CtsActivity.class);
+        super("android.text.cts", CtsActivity.class);
     }
 
     @Override
diff --git a/tests/tests/text/src/android/text/method/cts/EditorState.java b/tests/tests/text/src/android/text/method/cts/EditorState.java
new file mode 100644
index 0000000..2a4f0b8
--- /dev/null
+++ b/tests/tests/text/src/android/text/method/cts/EditorState.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.text.method.cts;
+
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.text.Editable;
+import android.text.Spannable;
+import android.text.SpannableString;
+import android.text.style.ReplacementSpan;
+
+import junit.framework.Assert;
+
+/**
+ * Represents an editor state.
+ *
+ * The editor state can be specified by following string format.
+ * - Components are separated by space(U+0020).
+ * - Single-quoted string for printable ASCII characters, e.g. 'a', '123'.
+ * - U+XXXX form can be used for a Unicode code point.
+ * - Components inside '[' and ']' are in selection.
+ * - Components inside '(' and ')' are in ReplacementSpan.
+ * - '|' is for specifying cursor position.
+ *
+ * Selection and cursor can not be specified at the same time.
+ *
+ * Example:
+ *   - "'Hello,' | U+0020 'world!'" means "Hello, world!" is displayed and the cursor position
+ *     is 6.
+ *   - "'abc' [ 'def' ] 'ghi'" means "abcdefghi" is displayed and "def" is selected.
+ *   - "U+1F441 | ( U+1F441 U+1F441 )" means three U+1F441 characters are displayed and
+ *     ReplacementSpan is set from offset 2 to 6.
+ */
+public class EditorState {
+    private static final String REPLACEMENT_SPAN_START = "(";
+    private static final String REPLACEMENT_SPAN_END = ")";
+    private static final String SELECTION_START = "[";
+    private static final String SELECTION_END = "]";
+    private static final String CURSOR = "|";
+
+    public Editable mText;
+    public int mSelectionStart = -1;
+    public int mSelectionEnd = -1;
+
+    public EditorState() {
+    }
+
+    /**
+     * A mocked {@link android.text.style.ReplacementSpan} for testing purpose.
+     */
+    private static class MockReplacementSpan extends ReplacementSpan {
+        public int getSize(Paint paint, CharSequence text, int start, int end,
+                Paint.FontMetricsInt fm) {
+            return 0;
+        }
+        public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top,
+                int y, int bottom, Paint paint) {
+        }
+    }
+
+    // Returns true if the code point is ASCII and graph.
+    private boolean isGraphicAscii(int codePoint) {
+        return 0x20 < codePoint && codePoint < 0x7F;
+    }
+
+    // Setup editor state with string. Please see class description for string format.
+    public void setByString(String string) {
+        final StringBuilder sb = new StringBuilder();
+        int replacementSpanStart = -1;
+        int replacementSpanEnd = -1;
+        mSelectionStart = -1;
+        mSelectionEnd = -1;
+
+        final String[] tokens = string.split(" +");
+        for (String token : tokens) {
+            if (token.startsWith("'") && token.endsWith("'")) {
+                for (int i = 1; i < token.length() - 1; ++i) {
+                    final char ch = token.charAt(1);
+                    if (!isGraphicAscii(ch)) {
+                        throw new IllegalArgumentException(
+                                "Only printable characters can be in single quote. " +
+                                "Use U+" + Integer.toHexString(ch).toUpperCase() + " instead");
+                    }
+                }
+                sb.append(token.substring(1, token.length() - 1));
+            } else if (token.startsWith("U+")) {
+                final int codePoint = Integer.parseInt(token.substring(2), 16);
+                if (codePoint < 0 || 0x10FFFF < codePoint) {
+                    throw new IllegalArgumentException("Invalid code point is specified:" + token);
+                }
+                sb.append(Character.toChars(codePoint));
+            } else if (token.equals(CURSOR)) {
+                if (mSelectionStart != -1 || mSelectionEnd != -1) {
+                    throw new IllegalArgumentException(
+                            "Two or more cursor/selection positions are specified.");
+                }
+                mSelectionStart = mSelectionEnd = sb.length();
+            } else if (token.equals(SELECTION_START)) {
+                if (mSelectionStart != -1) {
+                    throw new IllegalArgumentException(
+                            "Two or more cursor/selection positions are specified.");
+                }
+                mSelectionStart = sb.length();
+            } else if (token.equals(SELECTION_END)) {
+                if (mSelectionEnd != -1) {
+                    throw new IllegalArgumentException(
+                            "Two or more cursor/selection positions are specified.");
+                }
+                mSelectionEnd = sb.length();
+            } else if (token.equals(REPLACEMENT_SPAN_START)) {
+                if (replacementSpanStart != -1) {
+                    throw new IllegalArgumentException(
+                            "Only one replacement span is supported");
+                }
+                replacementSpanStart = sb.length();
+            } else if (token.equals(REPLACEMENT_SPAN_END)) {
+                if (replacementSpanEnd != -1) {
+                    throw new IllegalArgumentException(
+                            "Only one replacement span is supported");
+                }
+                replacementSpanEnd = sb.length();
+            } else {
+                throw new IllegalArgumentException("Unknown or invalid token: " + token);
+            }
+        }
+
+        if (mSelectionStart == -1 || mSelectionEnd == -1) {
+              if (mSelectionEnd != -1) {
+                  throw new IllegalArgumentException(
+                          "Selection start position doesn't exist.");
+              } else if (mSelectionStart != -1) {
+                  throw new IllegalArgumentException(
+                          "Selection end position doesn't exist.");
+              } else {
+                  throw new IllegalArgumentException(
+                          "At least cursor position or selection range must be specified.");
+              }
+        } else if (mSelectionStart > mSelectionEnd) {
+              throw new IllegalArgumentException(
+                      "Selection start position appears after end position.");
+        }
+
+        final Spannable spannable = new SpannableString(sb.toString());
+
+        if (replacementSpanStart != -1 || replacementSpanEnd != -1) {
+            if (replacementSpanStart == -1) {
+                throw new IllegalArgumentException(
+                        "ReplacementSpan start position doesn't exist.");
+            }
+            if (replacementSpanEnd == -1) {
+                throw new IllegalArgumentException(
+                        "ReplacementSpan end position doesn't exist.");
+            }
+            if (replacementSpanStart > replacementSpanEnd) {
+                throw new IllegalArgumentException(
+                        "ReplacementSpan start position appears after end position.");
+            }
+            spannable.setSpan(new MockReplacementSpan(), replacementSpanStart, replacementSpanEnd,
+                    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+        }
+        mText = Editable.Factory.getInstance().newEditable(spannable);
+    }
+
+    public void assertEquals(String string) {
+        EditorState expected = new EditorState();
+        expected.setByString(string);
+
+        Assert.assertEquals(expected.mText.toString(), mText.toString());
+        Assert.assertEquals(expected.mSelectionStart, mSelectionStart);
+        Assert.assertEquals(expected.mSelectionEnd, mSelectionEnd);
+    }
+}
+
diff --git a/tests/tests/text/src/android/text/method/cts/ForwardDeleteTest.java b/tests/tests/text/src/android/text/method/cts/ForwardDeleteTest.java
new file mode 100644
index 0000000..47c2795
--- /dev/null
+++ b/tests/tests/text/src/android/text/method/cts/ForwardDeleteTest.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.text.method.cts;
+
+import android.app.Activity;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.test.suitebuilder.annotation.Suppress;
+import android.text.InputType;
+import android.text.method.BaseKeyListener;
+import android.text.method.cts.KeyListenerTestCase;
+import android.view.KeyEvent;
+import android.widget.EditText;
+import android.widget.TextView.BufferType;
+
+/**
+ * Test forward delete key handling of  {@link android.text.method.BaseKeyListener}.
+ */
+public class ForwardDeleteTest extends KeyListenerTestCase {
+    private static final BaseKeyListener mKeyListener = new BaseKeyListener() {
+        public int getInputType() {
+            return InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_NORMAL;
+        }
+    };
+
+    // Sync the state to the TextView and call onKeyDown with KEYCODE_FORWARD_DEL key event.
+    // Then update the state to the result of TextView.
+    private void forwardDelete(final EditorState state, int modifiers) {
+        mActivity.runOnUiThread(new Runnable() {
+            public void run() {
+                mTextView.setText(state.mText, BufferType.EDITABLE);
+                mTextView.setKeyListener(mKeyListener);
+                mTextView.setSelection(state.mSelectionStart, state.mSelectionEnd);
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+        assertTrue(mTextView.hasWindowFocus());
+
+        final KeyEvent keyEvent = getKey(KeyEvent.KEYCODE_FORWARD_DEL, modifiers);
+        mActivity.runOnUiThread(new Runnable() {
+            public void run() {
+                mTextView.onKeyDown(keyEvent.getKeyCode(), keyEvent);
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+
+        state.mText = mTextView.getText();
+        state.mSelectionStart = mTextView.getSelectionStart();
+        state.mSelectionEnd = mTextView.getSelectionEnd();
+    }
+
+    @SmallTest
+    public void testSurrogatePairs() {
+        EditorState state = new EditorState();
+
+        // U+1F441 is EYE
+        state.setByString("| U+1F441");
+        forwardDelete(state, 0);
+        state.assertEquals("|");
+
+        // U+1F5E8 is LEFT SPEECH BUBBLE
+        state.setByString("| U+1F441 U+1F5E8");
+        forwardDelete(state, 0);
+        state.assertEquals("| U+1F5E8");
+        forwardDelete(state, 0);
+        state.assertEquals("|");
+    }
+
+    @SmallTest
+    public void testReplacementSpan() {
+        EditorState state = new EditorState();
+
+        state.setByString("| 'abc' ( 'de' ) 'fg'");
+        forwardDelete(state, 0);
+        state.assertEquals("| 'bc' ( 'de' ) 'fg'");
+        forwardDelete(state, 0);
+        state.assertEquals("| 'c' ( 'de' ) 'fg'");
+        forwardDelete(state, 0);
+        state.assertEquals("| ( 'de' ) 'fg'");
+        forwardDelete(state, 0);
+        state.assertEquals("| 'fg'");
+        forwardDelete(state, 0);
+        state.assertEquals("| 'g'");
+        forwardDelete(state, 0);
+        state.assertEquals("|");
+
+        state.setByString("'abc' [ ( 'de' ) ] 'fg'");
+        forwardDelete(state, 0);
+        state.assertEquals("'abc' | 'fg'");
+        forwardDelete(state, 0);
+        state.assertEquals("'abc' | 'g'");
+        forwardDelete(state, 0);
+        state.assertEquals("'abc' |");
+        forwardDelete(state, 0);
+        state.assertEquals("'abc' |");
+
+        state.setByString("'ab' [ 'c' ( 'de' ) 'f' ] 'g'");
+        forwardDelete(state, 0);
+        state.assertEquals("'ab' | 'g'");
+        forwardDelete(state, 0);
+        state.assertEquals("'ab' |");
+        forwardDelete(state, 0);
+        state.assertEquals("'ab' |");
+    }
+
+    @SmallTest
+    public void testCombiningEnclosingKeycaps() {
+        EditorState state = new EditorState();
+
+        // U+20E3 is COMBINING ENCLOSING KEYCAP.
+        state.setByString("| '1' U+20E3");
+        forwardDelete(state, 0);
+        state.assertEquals("|");
+
+        state.setByString("| '1' U+FE0F U+20E3");
+        forwardDelete(state, 0);
+        state.assertEquals("|");
+    }
+
+    @SmallTest
+    public void testVariationSelector() {
+        EditorState state = new EditorState();
+
+        // U+FE0F is VARIATION SELECTOR-16.
+        state.setByString("| '#' U+FE0F");
+        forwardDelete(state, 0);
+        state.assertEquals("|");
+
+        // U+E0100 is VARIATION SELECTOR-17.
+        state.setByString("| U+845B U+E0100");
+        forwardDelete(state, 0);
+        state.assertEquals("|");
+    }
+
+    @SmallTest
+    public void testFlags() {
+        EditorState state = new EditorState();
+
+        // U+1F1FA is REGIONAL INDICATOR SYMBOL LETTER U.
+        // U+1F1F8 is REGIONAL INDICATOR SYMBOL LETTER S.
+        state.setByString("| U+1F1FA U+1F1F8");
+        forwardDelete(state, 0);
+        state.assertEquals("|");
+
+        state.setByString("| U+1F1FA U+1F1F8 U+1F1FA U+1F1F8");
+        forwardDelete(state, 0);
+        state.assertEquals("| U+1F1FA U+1F1F8");
+        forwardDelete(state, 0);
+        state.assertEquals("|");
+    }
+}
diff --git a/tests/tests/text/src/android/text/method/cts/KeyListenerCtsActivity.java b/tests/tests/text/src/android/text/method/cts/KeyListenerCtsActivity.java
index c6483a2..c14f463 100644
--- a/tests/tests/text/src/android/text/method/cts/KeyListenerCtsActivity.java
+++ b/tests/tests/text/src/android/text/method/cts/KeyListenerCtsActivity.java
@@ -16,7 +16,7 @@
 
 package android.text.method.cts;
 
-import com.android.cts.text.R;
+import android.text.cts.R;
 
 import android.app.Activity;
 import android.os.Bundle;
diff --git a/tests/tests/text/src/android/text/method/cts/KeyListenerTestCase.java b/tests/tests/text/src/android/text/method/cts/KeyListenerTestCase.java
index 8bb2adf..ec9c48b 100644
--- a/tests/tests/text/src/android/text/method/cts/KeyListenerTestCase.java
+++ b/tests/tests/text/src/android/text/method/cts/KeyListenerTestCase.java
@@ -16,15 +16,14 @@
 
 package android.text.method.cts;
 
-import com.android.cts.text.R;
+import android.text.cts.R;
 
 import android.app.Instrumentation;
 import android.test.ActivityInstrumentationTestCase2;
 import android.text.format.DateUtils;
-import android.text.method.cts.KeyListenerCtsActivity;
 import android.text.method.KeyListener;
-import android.view.WindowManager;
-import android.widget.TextView;
+import android.view.KeyEvent;
+import android.widget.EditText;
 
 /**
  * Base class for various KeyListener tests.
@@ -50,7 +49,7 @@
         ActivityInstrumentationTestCase2<KeyListenerCtsActivity> {
     protected KeyListenerCtsActivity mActivity;
     protected Instrumentation mInstrumentation;
-    protected TextView mTextView;
+    protected EditText mTextView;
 
     public KeyListenerTestCase() {
         super("com.android.cts.text", KeyListenerCtsActivity.class);
@@ -62,7 +61,7 @@
 
         mActivity = getActivity();
         mInstrumentation = getInstrumentation();
-        mTextView = (TextView) mActivity.findViewById(R.id.keylistener_textview);
+        mTextView = (EditText) mActivity.findViewById(R.id.keylistener_textview);
 
         mActivity.runOnUiThread(new Runnable() {
             public void run() {
@@ -70,7 +69,7 @@
                 mTextView.setKeepScreenOn(true);
             }
         });
-
+        mInstrumentation.waitForIdleSync();
         assertTrue(mActivity.waitForWindowFocus(5 * DateUtils.SECOND_IN_MILLIS));
     }
 
@@ -85,4 +84,10 @@
         });
         mInstrumentation.waitForIdleSync();
     }
+
+    protected static KeyEvent getKey(int keycode, int metaState) {
+        long currentTime = System.currentTimeMillis();
+        return new KeyEvent(currentTime, currentTime, KeyEvent.ACTION_DOWN, keycode,
+                0 /* repeat */, metaState);
+    }
 }
diff --git a/tests/tests/text/src/android/text/method/cts/LinkMovementMethodTest.java b/tests/tests/text/src/android/text/method/cts/LinkMovementMethodTest.java
index 336921a..520b91f 100644
--- a/tests/tests/text/src/android/text/method/cts/LinkMovementMethodTest.java
+++ b/tests/tests/text/src/android/text/method/cts/LinkMovementMethodTest.java
@@ -56,7 +56,7 @@
     private MockClickableSpan mClickable1;
 
     public LinkMovementMethodTest() {
-        super("com.android.cts.text", CtsActivity.class);
+        super("android.text.cts", CtsActivity.class);
     }
 
     @Override
diff --git a/tests/tests/text/src/android/text/method/cts/PasswordTransformationMethodTest.java b/tests/tests/text/src/android/text/method/cts/PasswordTransformationMethodTest.java
index 72a8e72..ea679c5 100644
--- a/tests/tests/text/src/android/text/method/cts/PasswordTransformationMethodTest.java
+++ b/tests/tests/text/src/android/text/method/cts/PasswordTransformationMethodTest.java
@@ -63,7 +63,7 @@
     private CharSequence mTransformedText;
 
     public PasswordTransformationMethodTest() {
-        super("com.android.cts.text", CtsActivity.class);
+        super("android.text.cts", CtsActivity.class);
     }
 
     @Override
diff --git a/tests/tests/text/src/android/text/method/cts/ReplacementTransformationMethodTest.java b/tests/tests/text/src/android/text/method/cts/ReplacementTransformationMethodTest.java
index dadce15..6b3e149 100644
--- a/tests/tests/text/src/android/text/method/cts/ReplacementTransformationMethodTest.java
+++ b/tests/tests/text/src/android/text/method/cts/ReplacementTransformationMethodTest.java
@@ -37,7 +37,7 @@
     private EditText mEditText;
 
     public ReplacementTransformationMethodTest() {
-        super("com.android.cts.text", CtsActivity.class);
+        super("android.text.cts", CtsActivity.class);
     }
 
     @Override
diff --git a/tests/tests/text/src/android/text/method/cts/ScrollingMovementMethodTest.java b/tests/tests/text/src/android/text/method/cts/ScrollingMovementMethodTest.java
index 061cda3..49196bdc 100644
--- a/tests/tests/text/src/android/text/method/cts/ScrollingMovementMethodTest.java
+++ b/tests/tests/text/src/android/text/method/cts/ScrollingMovementMethodTest.java
@@ -16,8 +16,6 @@
 
 package android.text.method.cts;
 
-import dalvik.annotation.KnownFailure;
-
 import android.cts.util.WidgetTestUtils;
 import android.os.SystemClock;
 import android.test.ActivityInstrumentationTestCase2;
@@ -56,7 +54,7 @@
     private int mScaledTouchSlop;
 
     public ScrollingMovementMethodTest() {
-        super("com.android.cts.text", CtsActivity.class);
+        super("android.text.cts", CtsActivity.class);
     }
 
     @Override
diff --git a/tests/tests/text/src/android/text/method/cts/SingleLineTransformationMethodTest.java b/tests/tests/text/src/android/text/method/cts/SingleLineTransformationMethodTest.java
index 460ce3d..1756a0f 100644
--- a/tests/tests/text/src/android/text/method/cts/SingleLineTransformationMethodTest.java
+++ b/tests/tests/text/src/android/text/method/cts/SingleLineTransformationMethodTest.java
@@ -28,7 +28,7 @@
 public class SingleLineTransformationMethodTest
         extends ActivityInstrumentationTestCase2<CtsActivity> {
     public SingleLineTransformationMethodTest() {
-        super("com.android.cts.text", CtsActivity.class);
+        super("android.text.cts", CtsActivity.class);
     }
 
     public void testConstructor() {
diff --git a/tests/tests/text/src/android/text/method/cts/TouchTest.java b/tests/tests/text/src/android/text/method/cts/TouchTest.java
index 343847e..3e26084 100644
--- a/tests/tests/text/src/android/text/method/cts/TouchTest.java
+++ b/tests/tests/text/src/android/text/method/cts/TouchTest.java
@@ -43,7 +43,7 @@
     private boolean mReturnFromTouchEvent;
 
     public TouchTest() {
-        super("com.android.cts.text", CtsActivity.class);
+        super("android.text.cts", CtsActivity.class);
     }
 
     @Override
diff --git a/tests/tests/text/src/android/text/style/cts/AbsoluteSizeSpanTest.java b/tests/tests/text/src/android/text/style/cts/AbsoluteSizeSpanTest.java
index bdd3d17..e825bd1 100644
--- a/tests/tests/text/src/android/text/style/cts/AbsoluteSizeSpanTest.java
+++ b/tests/tests/text/src/android/text/style/cts/AbsoluteSizeSpanTest.java
@@ -47,6 +47,14 @@
         assertEquals(-5, absoluteSizeSpan.getSize());
     }
 
+    public void testGetDip() {
+        AbsoluteSizeSpan absoluteSizeSpan = new AbsoluteSizeSpan(5);
+        assertEquals(false, absoluteSizeSpan.getDip());
+
+        absoluteSizeSpan = new AbsoluteSizeSpan(5, true);
+        assertEquals(true, absoluteSizeSpan.getDip());
+    }
+
     public void testUpdateMeasureState() {
         AbsoluteSizeSpan absoluteSizeSpan = new AbsoluteSizeSpan(1);
 
diff --git a/tests/tests/text/src/android/text/style/cts/DrawableMarginSpanTest.java b/tests/tests/text/src/android/text/style/cts/DrawableMarginSpanTest.java
index 3813a94..775f035 100644
--- a/tests/tests/text/src/android/text/style/cts/DrawableMarginSpanTest.java
+++ b/tests/tests/text/src/android/text/style/cts/DrawableMarginSpanTest.java
@@ -16,7 +16,7 @@
 
 package android.text.style.cts;
 
-import com.android.cts.text.R;
+import android.text.cts.R;
 
 
 import android.graphics.Canvas;
diff --git a/tests/tests/text/src/android/text/style/cts/DynamicDrawableSpanTest.java b/tests/tests/text/src/android/text/style/cts/DynamicDrawableSpanTest.java
index 9723556..8a178f8 100644
--- a/tests/tests/text/src/android/text/style/cts/DynamicDrawableSpanTest.java
+++ b/tests/tests/text/src/android/text/style/cts/DynamicDrawableSpanTest.java
@@ -16,7 +16,7 @@
 
 package android.text.style.cts;
 
-import com.android.cts.text.R;
+import android.text.cts.R;
 
 
 import android.graphics.Canvas;
diff --git a/tests/tests/text/src/android/text/style/cts/EasyEditSpanTest.java b/tests/tests/text/src/android/text/style/cts/EasyEditSpanTest.java
new file mode 100644
index 0000000..7405107
--- /dev/null
+++ b/tests/tests/text/src/android/text/style/cts/EasyEditSpanTest.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.text.style.cts;
+
+import android.app.PendingIntent;
+import android.content.Intent;
+import android.os.Parcel;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.text.style.EasyEditSpan;
+
+public class EasyEditSpanTest extends AndroidTestCase {
+    @SmallTest
+    public void testConstructor() {
+        new EasyEditSpan();
+        new EasyEditSpan(PendingIntent.getActivity(getContext(), 0, new Intent(), 0));
+        Parcel p = Parcel.obtain();
+        try {
+            new EasyEditSpan(p);
+        } finally {
+            p.recycle();
+        }
+    }
+
+    @SmallTest
+    public void testDescribeContents_doesNotThrowException() {
+        EasyEditSpan easyEditSpan = new EasyEditSpan();
+        easyEditSpan.describeContents();
+    }
+
+    @SmallTest
+    public void testGetSpanTypeId_doesNotThrowException() {
+        EasyEditSpan easyEditSpan = new EasyEditSpan();
+        easyEditSpan.getSpanTypeId();
+    }
+
+    @SmallTest
+    public void testWriteToParcel() {
+        Parcel p = Parcel.obtain();
+        try {
+            EasyEditSpan easyEditSpan = new EasyEditSpan();
+            easyEditSpan.writeToParcel(p, 0);
+            p.setDataPosition(0);
+            new EasyEditSpan(p);
+        } finally {
+            p.recycle();
+        }
+    }
+}
diff --git a/tests/tests/text/src/android/text/style/cts/ImageSpanTest.java b/tests/tests/text/src/android/text/style/cts/ImageSpanTest.java
index 6f056d0..90282b8 100644
--- a/tests/tests/text/src/android/text/style/cts/ImageSpanTest.java
+++ b/tests/tests/text/src/android/text/style/cts/ImageSpanTest.java
@@ -16,7 +16,7 @@
 
 package android.text.style.cts;
 
-import com.android.cts.text.R;
+import android.text.cts.R;
 
 
 import android.content.Context;
diff --git a/tests/tests/text/src/android/text/style/cts/LocaleSpanTest.java b/tests/tests/text/src/android/text/style/cts/LocaleSpanTest.java
new file mode 100644
index 0000000..f44cca5
--- /dev/null
+++ b/tests/tests/text/src/android/text/style/cts/LocaleSpanTest.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.text.style.cts;
+
+import junit.framework.TestCase;
+import android.annotation.NonNull;
+import android.os.Parcel;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.text.TextPaint;
+import android.text.style.LocaleSpan;
+import android.util.LocaleList;
+
+public class LocaleSpanTest extends TestCase {
+
+    private void checkGetLocales(@NonNull final LocaleList locales) {
+        final LocaleSpan span = new LocaleSpan(locales);
+        assertEquals(locales.get(0), span.getLocale());
+        assertEquals(locales, span.getLocales());
+
+        final LocaleSpan cloned = cloneViaParcel(span);
+        assertEquals(locales.get(0), cloned.getLocale());
+        assertEquals(locales, cloned.getLocales());
+    }
+
+    @SmallTest
+    public void testGetLocales() {
+        checkGetLocales(LocaleList.getEmptyLocaleList());
+        checkGetLocales(LocaleList.forLanguageTags("en"));
+        checkGetLocales(LocaleList.forLanguageTags("en-GB,en"));
+        checkGetLocales(LocaleList.forLanguageTags("de-DE-u-co-phonebk,en-GB,en"));
+    }
+
+    @SmallTest
+    public void testConstructorWithLocaleList() {
+        try {
+            new LocaleSpan((LocaleList) null);
+        } catch (NullPointerException e) {
+            // Expected.
+            return;
+        }
+        fail("NullPointerException must have been thrown.");
+    }
+
+    @NonNull
+    LocaleSpan cloneViaParcel(@NonNull final LocaleSpan original) {
+        Parcel parcel = null;
+        try {
+            parcel = Parcel.obtain();
+            original.writeToParcel(parcel, 0);
+            parcel.setDataPosition(0);
+            return new LocaleSpan(parcel);
+        } finally {
+            if (parcel != null) {
+                parcel.recycle();
+            }
+        }
+    }
+
+    @SmallTest
+    public void testDescribeContents_doesNotThrowException() {
+        LocaleSpan localeSpan = new LocaleSpan(LocaleList.getEmptyLocaleList());
+        localeSpan.describeContents();
+    }
+
+    @SmallTest
+    public void testGetSpanTypeId_doesNotThrowException() {
+        LocaleSpan localeSpan = new LocaleSpan(LocaleList.getEmptyLocaleList());
+        localeSpan.getSpanTypeId();
+    }
+
+    @SmallTest
+    public void testUpdateDrawState() {
+        LocaleList localeListForSpan = LocaleList.forLanguageTags("en");
+        LocaleSpan localeSpan = new LocaleSpan(localeListForSpan);
+
+        TextPaint tp = new TextPaint();
+        LocaleList localeList = LocaleList.forLanguageTags("fr,de");
+        tp.setTextLocales(localeList);
+        assertEquals(localeList, tp.getTextLocales());
+        assertEquals(localeList.get(0), tp.getTextLocale());
+
+        localeSpan.updateDrawState(tp);
+        assertEquals(localeListForSpan, tp.getTextLocales());
+        assertEquals(localeListForSpan.get(0), tp.getTextLocale());
+    }
+
+    @SmallTest
+    public void testUpdateMeasureState() {
+        LocaleList localeListForSpan = LocaleList.forLanguageTags("en");
+        LocaleSpan localeSpan = new LocaleSpan(localeListForSpan);
+
+        TextPaint tp = new TextPaint();
+        LocaleList localeList = LocaleList.forLanguageTags("fr,de");
+        tp.setTextLocales(localeList);
+        assertEquals(localeList, tp.getTextLocales());
+        assertEquals(localeList.get(0), tp.getTextLocale());
+
+        localeSpan.updateMeasureState(tp);
+        assertEquals(localeListForSpan, tp.getTextLocales());
+        assertEquals(localeListForSpan.get(0), tp.getTextLocale());
+    }
+}
diff --git a/tests/tests/text/src/android/text/style/cts/MockURLSpanTestActivity.java b/tests/tests/text/src/android/text/style/cts/MockURLSpanTestActivity.java
index dbd154b..be06b0d 100644
--- a/tests/tests/text/src/android/text/style/cts/MockURLSpanTestActivity.java
+++ b/tests/tests/text/src/android/text/style/cts/MockURLSpanTestActivity.java
@@ -16,7 +16,7 @@
 
 package android.text.style.cts;
 
-import com.android.cts.text.R;
+import android.text.cts.R;
 
 import android.app.Activity;
 import android.os.Bundle;
diff --git a/tests/tests/text/src/android/text/style/cts/SuggestionSpanTest.java b/tests/tests/text/src/android/text/style/cts/SuggestionSpanTest.java
new file mode 100644
index 0000000..ff5167c
--- /dev/null
+++ b/tests/tests/text/src/android/text/style/cts/SuggestionSpanTest.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.text.style.cts;
+
+import junit.framework.TestCase;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Parcel;
+import android.text.style.SuggestionSpan;
+
+import java.util.Locale;
+
+public class SuggestionSpanTest extends TestCase {
+
+    /**
+     * @param locale a {@link Locale} object.
+     * @return A well-formed BCP 47 language tag representation.
+     */
+    @Nullable
+    private Locale toWellFormedLocale(@Nullable final Locale locale) {
+        if (locale == null) {
+            return null;
+        }
+        // Drop all the malformed data.
+        return Locale.forLanguageTag(locale.toLanguageTag());
+    }
+
+    @NonNull
+    private String getNonNullLocaleString(@Nullable final Locale original) {
+        if (original == null) {
+            return "";
+        }
+        return original.toString();
+    }
+
+    private void checkGetLocaleObject(final Locale locale) {
+        final SuggestionSpan span = new SuggestionSpan(locale, new String[0],
+                SuggestionSpan.FLAG_AUTO_CORRECTION);
+        // In the context of SuggestionSpan#getLocaleObject(), we do care only about subtags that
+        // can be interpreted as LanguageTag.
+        assertEquals(toWellFormedLocale(locale), span.getLocaleObject());
+        assertEquals(getNonNullLocaleString(locale), span.getLocale());
+
+        final SuggestionSpan cloned = cloneViaParcel(span);
+        assertEquals(span, cloned);
+        assertEquals(toWellFormedLocale(locale), cloned.getLocaleObject());
+        assertEquals(getNonNullLocaleString(locale), cloned.getLocale());
+    }
+
+    public void testGetLocaleObject() {
+        checkGetLocaleObject(Locale.forLanguageTag("en"));
+        checkGetLocaleObject(Locale.forLanguageTag("en-GB"));
+        checkGetLocaleObject(Locale.forLanguageTag("EN-GB"));
+        checkGetLocaleObject(Locale.forLanguageTag("en-gb"));
+        checkGetLocaleObject(Locale.forLanguageTag("En-gB"));
+        checkGetLocaleObject(Locale.forLanguageTag("und"));
+        checkGetLocaleObject(Locale.forLanguageTag("de-DE-u-co-phonebk"));
+        checkGetLocaleObject(Locale.forLanguageTag(""));
+        checkGetLocaleObject(null);
+        checkGetLocaleObject(new Locale(" an  ", " i n v a l i d ", "data"));
+    }
+
+    @NonNull
+    SuggestionSpan cloneViaParcel(@NonNull final SuggestionSpan original) {
+        Parcel parcel = null;
+        try {
+            parcel = Parcel.obtain();
+            original.writeToParcel(parcel, 0);
+            parcel.setDataPosition(0);
+            return new SuggestionSpan(parcel);
+        } finally {
+            if (parcel != null) {
+                parcel.recycle();
+            }
+        }
+    }
+}
diff --git a/tests/tests/text/src/android/text/style/cts/TtsSpanTest.java b/tests/tests/text/src/android/text/style/cts/TtsSpanTest.java
index 3c320f1..c718a37 100644
--- a/tests/tests/text/src/android/text/style/cts/TtsSpanTest.java
+++ b/tests/tests/text/src/android/text/style/cts/TtsSpanTest.java
@@ -18,6 +18,7 @@
 
 import android.os.Parcel;
 import android.os.PersistableBundle;
+import android.test.suitebuilder.annotation.SmallTest;
 import android.text.style.TtsSpan;
 import junit.framework.TestCase;
 
@@ -25,6 +26,7 @@
 
     PersistableBundle bundle;
 
+    @Override
     protected void setUp() {
         bundle = new PersistableBundle();
         bundle.putString("argument.one", "value.one");
@@ -33,6 +35,7 @@
         bundle.putLong("argument.four", 4);
     }
 
+    @SmallTest
     public void testGetArgs() {
         TtsSpan t = new TtsSpan("test.type.one", bundle);
         PersistableBundle args = t.getArgs();
@@ -43,21 +46,25 @@
         assertEquals(4, args.getLong("argument.four"));
     }
 
+    @SmallTest
     public void testGetType() {
         TtsSpan t = new TtsSpan("test.type.two", bundle);
         assertEquals("test.type.two", t.getType());
     }
 
+    @SmallTest
     public void testDescribeContents() {
         TtsSpan span = new TtsSpan("test.type.three", bundle);
         span.describeContents();
     }
 
+    @SmallTest
     public void testGetSpanTypeId() {
         TtsSpan span = new TtsSpan("test.type.four", bundle);
         span.getSpanTypeId();
     }
 
+    @SmallTest
     public void testWriteAndReadParcel() {
         Parcel p = Parcel.obtain();
         try {
@@ -78,4 +85,423 @@
             p.recycle();
         }
     }
+
+    @SmallTest
+    public void testBuilder() {
+        final TtsSpan t = (new TtsSpan.Builder<>("test.type.builder"))
+                .setStringArgument("argument.string", "value")
+                .setIntArgument("argument.int", Integer.MAX_VALUE)
+                .setLongArgument("argument.long", Long.MAX_VALUE)
+                .build();
+        assertEquals("test.type.builder", t.getType());
+        PersistableBundle args = t.getArgs();
+        assertEquals(3, args.size());
+        assertEquals("value", args.getString("argument.string"));
+        assertEquals(Integer.MAX_VALUE, args.getInt("argument.int"));
+        assertEquals(Long.MAX_VALUE, args.getLong("argument.long"));
+    }
+
+    @SmallTest
+    public void testSemioticClassBuilder() {
+        final TtsSpan t = (new TtsSpan.SemioticClassBuilder<>("test.type.semioticClassBuilder"))
+                .setGender(TtsSpan.GENDER_FEMALE)
+                .setAnimacy(TtsSpan.ANIMACY_ANIMATE)
+                .setMultiplicity(TtsSpan.MULTIPLICITY_SINGLE)
+                .setCase(TtsSpan.CASE_NOMINATIVE)
+                .build();
+        assertEquals("test.type.semioticClassBuilder", t.getType());
+        PersistableBundle args = t.getArgs();
+        assertEquals(4, args.size());
+        assertEquals(TtsSpan.GENDER_FEMALE, args.getString(TtsSpan.ARG_GENDER));
+        assertEquals(TtsSpan.ANIMACY_ANIMATE, args.getString(TtsSpan.ARG_ANIMACY));
+        assertEquals(TtsSpan.MULTIPLICITY_SINGLE, args.getString(TtsSpan.ARG_MULTIPLICITY));
+        assertEquals(TtsSpan.CASE_NOMINATIVE, args.getString(TtsSpan.ARG_CASE));
+    }
+
+    @SmallTest
+    public void testTextBuilder() {
+        {
+            final TtsSpan t = (new TtsSpan.TextBuilder())
+                    .setText("text")
+                    .build();
+            assertEquals(TtsSpan.TYPE_TEXT, t.getType());
+            PersistableBundle args = t.getArgs();
+            assertEquals(1, args.size());
+            assertEquals("text", args.getString(TtsSpan.ARG_TEXT));
+        }
+        {
+            final TtsSpan t = (new TtsSpan.TextBuilder("text")).build();
+            assertEquals(TtsSpan.TYPE_TEXT, t.getType());
+            PersistableBundle args = t.getArgs();
+            assertEquals(1, args.size());
+            assertEquals("text", args.getString(TtsSpan.ARG_TEXT));
+        }
+    }
+
+    @SmallTest
+    public void testCardinalBuilder() {
+        {
+            final TtsSpan t = (new TtsSpan.CardinalBuilder())
+                    .setNumber(Long.MAX_VALUE)
+                    .build();
+            assertEquals(TtsSpan.TYPE_CARDINAL, t.getType());
+            PersistableBundle args = t.getArgs();
+            assertEquals(1, args.size());
+            assertEquals(String.valueOf(Long.MAX_VALUE), args.getString(TtsSpan.ARG_NUMBER));
+        }
+        {
+            final TtsSpan t = (new TtsSpan.CardinalBuilder())
+                    .setNumber("10")
+                    .build();
+            assertEquals(TtsSpan.TYPE_CARDINAL, t.getType());
+            PersistableBundle args = t.getArgs();
+            assertEquals(1, args.size());
+            assertEquals("10", args.getString(TtsSpan.ARG_NUMBER));
+        }
+        {
+            final TtsSpan t = (new TtsSpan.CardinalBuilder(Long.MAX_VALUE)).build();
+            assertEquals(TtsSpan.TYPE_CARDINAL, t.getType());
+            PersistableBundle args = t.getArgs();
+            assertEquals(1, args.size());
+            assertEquals(String.valueOf(Long.MAX_VALUE), args.getString(TtsSpan.ARG_NUMBER));
+        }
+        {
+            final TtsSpan t = (new TtsSpan.CardinalBuilder("10")).build();
+            assertEquals(TtsSpan.TYPE_CARDINAL, t.getType());
+            PersistableBundle args = t.getArgs();
+            assertEquals(1, args.size());
+            assertEquals("10", args.getString(TtsSpan.ARG_NUMBER));
+        }
+    }
+
+    @SmallTest
+    public void testOrdinalBuilder() {
+        {
+            final TtsSpan t = (new TtsSpan.OrdinalBuilder())
+                    .setNumber(Long.MAX_VALUE)
+                    .build();
+            assertEquals(TtsSpan.TYPE_ORDINAL, t.getType());
+            PersistableBundle args = t.getArgs();
+            assertEquals(1, args.size());
+            assertEquals(String.valueOf(Long.MAX_VALUE), args.getString(TtsSpan.ARG_NUMBER));
+        }
+        {
+            final TtsSpan t = (new TtsSpan.OrdinalBuilder())
+                    .setNumber("10")
+                    .build();
+            assertEquals(TtsSpan.TYPE_ORDINAL, t.getType());
+            PersistableBundle args = t.getArgs();
+            assertEquals(1, args.size());
+            assertEquals("10", args.getString(TtsSpan.ARG_NUMBER));
+        }
+        {
+            final TtsSpan t = (new TtsSpan.OrdinalBuilder(Long.MAX_VALUE)).build();
+            assertEquals(TtsSpan.TYPE_ORDINAL, t.getType());
+            PersistableBundle args = t.getArgs();
+            assertEquals(1, args.size());
+            assertEquals(String.valueOf(Long.MAX_VALUE), args.getString(TtsSpan.ARG_NUMBER));
+        }
+        {
+            final TtsSpan t = (new TtsSpan.OrdinalBuilder("10")).build();
+            assertEquals(TtsSpan.TYPE_ORDINAL, t.getType());
+            PersistableBundle args = t.getArgs();
+            assertEquals(1, args.size());
+            assertEquals("10", args.getString(TtsSpan.ARG_NUMBER));
+        }
+    }
+
+    @SmallTest
+    public void testDecimalBuilder() {
+        {
+            final TtsSpan t = (new TtsSpan.DecimalBuilder())
+                    .setArgumentsFromDouble(10.25, 1, 2)
+                    .build();
+            assertEquals(TtsSpan.TYPE_DECIMAL, t.getType());
+            PersistableBundle args = t.getArgs();
+            assertEquals(2, args.size());
+            assertEquals("10", args.getString(TtsSpan.ARG_INTEGER_PART));
+            assertEquals("25", args.getString(TtsSpan.ARG_FRACTIONAL_PART));
+        }
+        {
+            final TtsSpan t = (new TtsSpan.DecimalBuilder(10.25, 1, 2)).build();
+            assertEquals(TtsSpan.TYPE_DECIMAL, t.getType());
+            PersistableBundle args = t.getArgs();
+            assertEquals(2, args.size());
+            assertEquals("10", args.getString(TtsSpan.ARG_INTEGER_PART));
+            assertEquals("25", args.getString(TtsSpan.ARG_FRACTIONAL_PART));
+        }
+        {
+            final TtsSpan t = (new TtsSpan.DecimalBuilder())
+                    .setArgumentsFromDouble(10, 0, 0)
+                    .build();
+            assertEquals(TtsSpan.TYPE_DECIMAL, t.getType());
+            PersistableBundle args = t.getArgs();
+            assertEquals(1, args.size());
+            assertEquals("10", args.getString(TtsSpan.ARG_INTEGER_PART));
+        }
+        {
+            final TtsSpan t = (new TtsSpan.DecimalBuilder(10, 0, 0)).build();
+            assertEquals(TtsSpan.TYPE_DECIMAL, t.getType());
+            PersistableBundle args = t.getArgs();
+            assertEquals(1, args.size());
+            assertEquals("10", args.getString(TtsSpan.ARG_INTEGER_PART));
+        }
+        {
+            final TtsSpan t = (new TtsSpan.DecimalBuilder())
+                    .setArgumentsFromDouble(10.25, 10, 10)
+                    .build();
+            assertEquals(TtsSpan.TYPE_DECIMAL, t.getType());
+            PersistableBundle args = t.getArgs();
+            assertEquals(2, args.size());
+            assertEquals("10", args.getString(TtsSpan.ARG_INTEGER_PART));
+            assertEquals("2500000000", args.getString(TtsSpan.ARG_FRACTIONAL_PART));
+        }
+    }
+
+    @SmallTest
+    public void testFractionBuilder() {
+        {
+            final TtsSpan t = (new TtsSpan.FractionBuilder())
+                    .setIntegerPart(10)
+                    .setNumerator(3)
+                    .setDenominator(100)
+                    .build();
+            assertEquals(TtsSpan.TYPE_FRACTION, t.getType());
+            PersistableBundle args = t.getArgs();
+            assertEquals(3, args.size());
+            assertEquals("10", args.getString(TtsSpan.ARG_INTEGER_PART));
+            assertEquals("3", args.getString(TtsSpan.ARG_NUMERATOR));
+            assertEquals("100", args.getString(TtsSpan.ARG_DENOMINATOR));
+        }
+        {
+            final TtsSpan t = (new TtsSpan.FractionBuilder(10, 3, 100)).build();
+            assertEquals(TtsSpan.TYPE_FRACTION, t.getType());
+            PersistableBundle args = t.getArgs();
+            assertEquals(3, args.size());
+            assertEquals("10", args.getString(TtsSpan.ARG_INTEGER_PART));
+            assertEquals("3", args.getString(TtsSpan.ARG_NUMERATOR));
+            assertEquals("100", args.getString(TtsSpan.ARG_DENOMINATOR));
+        }
+    }
+
+    @SmallTest
+    public void testMeasureBuilder() {
+        {
+            final TtsSpan t = (new TtsSpan.MeasureBuilder())
+                    .setNumber(10)
+                    .setUnit("unit")
+                    .build();
+            assertEquals(TtsSpan.TYPE_MEASURE, t.getType());
+            PersistableBundle args = t.getArgs();
+            assertEquals(2, args.size());
+            assertEquals("10", args.getString(TtsSpan.ARG_NUMBER));
+            assertEquals("unit", args.getString(TtsSpan.ARG_UNIT));
+        }
+        {
+            final TtsSpan t = (new TtsSpan.MeasureBuilder())
+                    .setIntegerPart(10)
+                    .setFractionalPart("25")
+                    .setUnit("unit")
+                    .build();
+            assertEquals(TtsSpan.TYPE_MEASURE, t.getType());
+            PersistableBundle args = t.getArgs();
+            assertEquals(3, args.size());
+            assertEquals("10", args.getString(TtsSpan.ARG_INTEGER_PART));
+            assertEquals("25", args.getString(TtsSpan.ARG_FRACTIONAL_PART));
+            assertEquals("unit", args.getString(TtsSpan.ARG_UNIT));
+        }
+        {
+            final TtsSpan t = (new TtsSpan.MeasureBuilder())
+                    .setIntegerPart(10)
+                    .setNumerator(3)
+                    .setDenominator(100)
+                    .setUnit("unit")
+                    .build();
+            assertEquals(TtsSpan.TYPE_MEASURE, t.getType());
+            PersistableBundle args = t.getArgs();
+            assertEquals(4, args.size());
+            assertEquals("10", args.getString(TtsSpan.ARG_INTEGER_PART));
+            assertEquals("3", args.getString(TtsSpan.ARG_NUMERATOR));
+            assertEquals("100", args.getString(TtsSpan.ARG_DENOMINATOR));
+            assertEquals("unit", args.getString(TtsSpan.ARG_UNIT));
+        }
+    }
+
+    @SmallTest
+    public void testTimeBuilder() {
+        {
+            final TtsSpan t = (new TtsSpan.TimeBuilder())
+                    .setHours(20)
+                    .setMinutes(50)
+                    .build();
+            assertEquals(TtsSpan.TYPE_TIME, t.getType());
+            PersistableBundle args = t.getArgs();
+            assertEquals(2, args.size());
+            assertEquals(20, args.getInt(TtsSpan.ARG_HOURS));
+            assertEquals(50, args.getInt(TtsSpan.ARG_MINUTES));
+        }
+        {
+            final TtsSpan t = (new TtsSpan.TimeBuilder(20, 50)).build();
+            assertEquals(TtsSpan.TYPE_TIME, t.getType());
+            PersistableBundle args = t.getArgs();
+            assertEquals(2, args.size());
+            assertEquals(20, args.getInt(TtsSpan.ARG_HOURS));
+            assertEquals(50, args.getInt(TtsSpan.ARG_MINUTES));
+        }
+    }
+
+    @SmallTest
+    public void testDateBuilder() {
+        {
+            final TtsSpan t = (new TtsSpan.DateBuilder())
+                    .setWeekday(3)
+                    .setDay(16)
+                    .setMonth(3)
+                    .setYear(2016)
+                    .build();
+            assertEquals(TtsSpan.TYPE_DATE, t.getType());
+            PersistableBundle args = t.getArgs();
+            assertEquals(4, args.size());
+            assertEquals(3, args.getInt(TtsSpan.ARG_WEEKDAY));
+            assertEquals(16, args.getInt(TtsSpan.ARG_DAY));
+            assertEquals(3, args.getInt(TtsSpan.ARG_MONTH));
+            assertEquals(2016, args.getInt(TtsSpan.ARG_YEAR));
+        }
+        {
+            final TtsSpan t = (new TtsSpan.DateBuilder(3, 16, 3, 2016)).build();
+            assertEquals(TtsSpan.TYPE_DATE, t.getType());
+            PersistableBundle args = t.getArgs();
+            assertEquals(4, args.size());
+            assertEquals(3, args.getInt(TtsSpan.ARG_WEEKDAY));
+            assertEquals(16, args.getInt(TtsSpan.ARG_DAY));
+            assertEquals(3, args.getInt(TtsSpan.ARG_MONTH));
+            assertEquals(2016, args.getInt(TtsSpan.ARG_YEAR));
+        }
+        {
+            final TtsSpan t = (new TtsSpan.DateBuilder(3, 16, null, null)).build();
+            assertEquals(TtsSpan.TYPE_DATE, t.getType());
+            PersistableBundle args = t.getArgs();
+            assertEquals(2, args.size());
+            assertEquals(3, args.getInt(TtsSpan.ARG_WEEKDAY));
+            assertEquals(16, args.getInt(TtsSpan.ARG_DAY));
+        }
+    }
+
+    @SmallTest
+    public void testMoneyBuilder() {
+        final TtsSpan t = (new TtsSpan.MoneyBuilder())
+                .setIntegerPart(10)
+                .setFractionalPart("25")
+                .setCurrency("USD")
+                .setQuantity("1000")
+                .build();
+        assertEquals(TtsSpan.TYPE_MONEY, t.getType());
+        PersistableBundle args = t.getArgs();
+        assertEquals(4, args.size());
+        assertEquals("10", args.getString(TtsSpan.ARG_INTEGER_PART));
+        assertEquals("25", args.getString(TtsSpan.ARG_FRACTIONAL_PART));
+        assertEquals("USD", args.getString(TtsSpan.ARG_CURRENCY));
+        assertEquals("1000", args.getString(TtsSpan.ARG_QUANTITY));
+    }
+
+    @SmallTest
+    public void testTelephoneBuilder() {
+        {
+            final TtsSpan t = (new TtsSpan.TelephoneBuilder())
+                    .setCountryCode("+01")
+                    .setNumberParts("000-000-0000")
+                    .setExtension("0000")
+                    .build();
+            assertEquals(TtsSpan.TYPE_TELEPHONE, t.getType());
+            PersistableBundle args = t.getArgs();
+            assertEquals(3, args.size());
+            assertEquals("+01", args.getString(TtsSpan.ARG_COUNTRY_CODE));
+            assertEquals("000-000-0000", args.getString(TtsSpan.ARG_NUMBER_PARTS));
+            assertEquals("0000", args.getString(TtsSpan.ARG_EXTENSION));
+        }
+        {
+            final TtsSpan t = (new TtsSpan.TelephoneBuilder("000-000-0000")).build();
+            assertEquals(TtsSpan.TYPE_TELEPHONE, t.getType());
+            PersistableBundle args = t.getArgs();
+            assertEquals(1, args.size());
+            assertEquals("000-000-0000", args.getString(TtsSpan.ARG_NUMBER_PARTS));
+        }
+    }
+
+    @SmallTest
+    public void testElectronicBuilder() {
+        {
+            final TtsSpan t = (new TtsSpan.ElectronicBuilder())
+                    .setEmailArguments("example", "example.com")
+                    .build();
+            assertEquals(TtsSpan.TYPE_ELECTRONIC, t.getType());
+            PersistableBundle args = t.getArgs();
+            assertEquals(2, args.size());
+            assertEquals("example", args.getString(TtsSpan.ARG_USERNAME));
+            assertEquals("example.com", args.getString(TtsSpan.ARG_DOMAIN));
+        }
+        {
+            final TtsSpan t = (new TtsSpan.ElectronicBuilder())
+                    .setProtocol("http")
+                    .setDomain("example.com")
+                    .setPort(80)
+                    .setPath("example/index.html")
+                    .setQueryString("arg1=value1&arg2=value2")
+                    .setFragmentId("fragment")
+                    .setUsername("username")
+                    .setPassword("password")
+                    .build();
+            assertEquals(TtsSpan.TYPE_ELECTRONIC, t.getType());
+            PersistableBundle args = t.getArgs();
+            assertEquals(8, args.size());
+            assertEquals("http", args.getString(TtsSpan.ARG_PROTOCOL));
+            assertEquals("example.com", args.getString(TtsSpan.ARG_DOMAIN));
+            assertEquals(80, args.getInt(TtsSpan.ARG_PORT));
+            assertEquals("example/index.html", args.getString(TtsSpan.ARG_PATH));
+            assertEquals("arg1=value1&arg2=value2", args.getString(TtsSpan.ARG_QUERY_STRING));
+            assertEquals("fragment", args.getString(TtsSpan.ARG_FRAGMENT_ID));
+            assertEquals("username", args.getString(TtsSpan.ARG_USERNAME));
+            assertEquals("password", args.getString(TtsSpan.ARG_PASSWORD));
+        }
+    }
+
+    @SmallTest
+    public void testDigitsBuilder() {
+        {
+            final TtsSpan t = (new TtsSpan.DigitsBuilder())
+                    .setDigits("12345")
+                    .build();
+            assertEquals(TtsSpan.TYPE_DIGITS, t.getType());
+            PersistableBundle args = t.getArgs();
+            assertEquals(1, args.size());
+            assertEquals("12345", args.getString(TtsSpan.ARG_DIGITS));
+        }
+        {
+            final TtsSpan t = (new TtsSpan.DigitsBuilder("12345")).build();
+            assertEquals(TtsSpan.TYPE_DIGITS, t.getType());
+            PersistableBundle args = t.getArgs();
+            assertEquals(1, args.size());
+            assertEquals("12345", args.getString(TtsSpan.ARG_DIGITS));
+        }
+    }
+
+    @SmallTest
+    public void testVerbatimBuilder() {
+        {
+            final TtsSpan t = (new TtsSpan.VerbatimBuilder())
+                    .setVerbatim("abcdefg")
+                    .build();
+            assertEquals(TtsSpan.TYPE_VERBATIM, t.getType());
+            PersistableBundle args = t.getArgs();
+            assertEquals(1, args.size());
+            assertEquals("abcdefg", args.getString(TtsSpan.ARG_VERBATIM));
+        }
+        {
+            final TtsSpan t = (new TtsSpan.VerbatimBuilder("abcdefg")).build();
+            assertEquals(TtsSpan.TYPE_VERBATIM, t.getType());
+            PersistableBundle args = t.getArgs();
+            assertEquals(1, args.size());
+            assertEquals("abcdefg", args.getString(TtsSpan.ARG_VERBATIM));
+        }
+    }
 }
diff --git a/tests/tests/text/src/android/text/style/cts/URLSpanCtsActivity.java b/tests/tests/text/src/android/text/style/cts/URLSpanCtsActivity.java
index 8d885bc..be6c8ae 100644
--- a/tests/tests/text/src/android/text/style/cts/URLSpanCtsActivity.java
+++ b/tests/tests/text/src/android/text/style/cts/URLSpanCtsActivity.java
@@ -16,7 +16,7 @@
 
 package android.text.style.cts;
 
-import com.android.cts.text.R;
+import android.text.cts.R;
 
 import android.app.Activity;
 import android.os.Bundle;
diff --git a/tests/tests/text/src/android/text/style/cts/URLSpanTest.java b/tests/tests/text/src/android/text/style/cts/URLSpanTest.java
index 7cfe56e..330db77 100644
--- a/tests/tests/text/src/android/text/style/cts/URLSpanTest.java
+++ b/tests/tests/text/src/android/text/style/cts/URLSpanTest.java
@@ -16,7 +16,7 @@
 
 package android.text.style.cts;
 
-import com.android.cts.text.R;
+import android.text.cts.R;
 
 
 import android.app.Activity;
@@ -33,7 +33,7 @@
     private Activity mActivity;
 
     public URLSpanTest() {
-        super("com.android.cts.text", URLSpanCtsActivity.class);
+        super("android.text.cts", URLSpanCtsActivity.class);
     }
 
     @Override
diff --git a/tests/tests/text/src/android/text/util/cts/LinkifyTest.java b/tests/tests/text/src/android/text/util/cts/LinkifyTest.java
index e6b91eb..a159da9 100644
--- a/tests/tests/text/src/android/text/util/cts/LinkifyTest.java
+++ b/tests/tests/text/src/android/text/util/cts/LinkifyTest.java
@@ -18,12 +18,14 @@
 
 
 import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
 import android.text.Spannable;
 import android.text.SpannableString;
 import android.text.style.URLSpan;
 import android.text.util.Linkify;
 import android.text.util.Linkify.MatchFilter;
 import android.text.util.Linkify.TransformFilter;
+import android.util.Patterns;
 import android.widget.TextView;
 
 import java.util.Locale;
@@ -81,9 +83,9 @@
                 "abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabc";
         SpannableString spannable = new SpannableString("name@gmail.com, "
                 + "www.google.com, http://www.google.com/language_tools?hl=en, "
-                + "a.bc, "   // a URL with accepted gTLD so should be linkified
+                + "a.bd, "   // a URL with accepted TLD so should be linkified
                 + "d.e, f.1, g.12, "  // not valid, so should not be linkified
-                + "h." + longGTLD + " "  // valid, should be linkified
+                + "http://h." + longGTLD + " "  // valid, should be linkified
                 + "j." + longGTLD + "a"); // not a valid URL (gtld too long), no linkify
 
         assertTrue(Linkify.addLinks(spannable, Linkify.WEB_URLS));
@@ -91,7 +93,7 @@
         assertEquals(4, spans.length);
         assertEquals("http://www.google.com", spans[0].getURL());
         assertEquals("http://www.google.com/language_tools?hl=en", spans[1].getURL());
-        assertEquals("http://a.bc", spans[2].getURL());
+        assertEquals("http://a.bd", spans[2].getURL());
         assertEquals("http://h." + longGTLD, spans[3].getURL());
 
         assertTrue(Linkify.addLinks(spannable, Linkify.EMAIL_ADDRESSES));
@@ -349,4 +351,577 @@
 
         assertFalse(Linkify.addLinks((Spannable) null, 0));
     }
+
+    @SmallTest
+    public void testAddLinks_addsLinksWhenDefaultSchemeIsNull() {
+        Spannable spannable = new SpannableString("any https://android.com any android.com any");
+        Linkify.addLinks(spannable, Patterns.AUTOLINK_WEB_URL, null, null, null);
+
+        URLSpan[] spans = spannable.getSpans(0, spannable.length(), URLSpan.class);
+        assertEquals("android.com and https://android.com should be linkified", 2, spans.length);
+        assertEquals("https://android.com", spans[0].getURL());
+        assertEquals("android.com", spans[1].getURL());
+    }
+
+    @SmallTest
+    public void testAddLinks_addsLinksWhenSchemesArrayIsNull() {
+        Spannable spannable = new SpannableString("any https://android.com any android.com any");
+        Linkify.addLinks(spannable, Patterns.AUTOLINK_WEB_URL, "http://", null, null);
+
+        URLSpan[] spans = spannable.getSpans(0, spannable.length(), URLSpan.class);
+        assertEquals("android.com and https://android.com should be linkified", 2, spans.length);
+        // expected behavior, passing null schemes array means: prepend defaultScheme to all links.
+        assertEquals("http://https://android.com", spans[0].getURL());
+        assertEquals("http://android.com", spans[1].getURL());
+    }
+
+    @SmallTest
+    public void testAddLinks_prependsDefaultSchemeToBeginingOfLink() {
+        Spannable spannable = new SpannableString("any android.com any");
+        Linkify.addLinks(spannable, Patterns.AUTOLINK_WEB_URL, "http://",
+                new String[] { "http://", "https://"}, null, null);
+
+        URLSpan[] spans = spannable.getSpans(0, spannable.length(), URLSpan.class);
+        assertEquals("android.com should be linkified", 1, spans.length);
+        assertEquals("http://android.com", spans[0].getURL());
+    }
+
+    @SmallTest
+    public void testAddLinks_doesNotPrependSchemeIfSchemeExists() {
+        Spannable spannable = new SpannableString("any https://android.com any");
+        Linkify.addLinks(spannable, Patterns.AUTOLINK_WEB_URL, "http://",
+                new String[] { "http://", "https://"}, null, null);
+
+        URLSpan[] spans = spannable.getSpans(0, spannable.length(), URLSpan.class);
+        assertEquals("android.com should be linkified", 1, spans.length);
+        assertEquals("https://android.com", spans[0].getURL());
+    }
+
+    // Add links with scheme (array)
+
+    @SmallTest
+    public void testAddLinks_withTextView_addsLinksWhenDefaultSchemeIsNull() {
+        Pattern pattern = Pattern.compile("\\b((http|https)://)?android\\.com+\\b");
+        TextView textView = new TextView(mContext);
+        textView.setText("any https://android.com any android.com any");
+
+        Linkify.addLinks(textView, pattern, null, null, null);
+
+        URLSpan[] spans = textView.getUrls();
+        assertEquals("android.com and https://android.com should be linkified", 2, spans.length);
+        assertEquals("https://android.com", spans[0].getURL());
+        assertEquals("android.com", spans[1].getURL());
+    }
+
+    @SmallTest
+    public void testAddLinks_withTextView_addsLinksWhenSchemesArrayIsNull() {
+        Pattern pattern = Pattern.compile("\\b((http|https)://)?android\\.com+\\b");
+        TextView textView = new TextView(mContext);
+        textView.setText("any https://android.com any android.com any");
+
+        Linkify.addLinks(textView, pattern, "http://", null, null);
+
+        URLSpan[] spans = textView.getUrls();
+        assertEquals("android.com and https://android.com should be linkified", 2, spans.length);
+        // expected behavior, passing null schemes array means: prepend defaultScheme to all links.
+        assertEquals("http://https://android.com", spans[0].getURL());
+        assertEquals("http://android.com", spans[1].getURL());
+    }
+
+    @SmallTest
+    public void testAddLinks_withTextView_prependsDefaultSchemeToBeginingOfLink() {
+        Pattern pattern = Pattern.compile("\\b((http|https)://)?android\\.com+\\b");
+        TextView textView = new TextView(mContext);
+        textView.setText("any android.com any");
+
+        Linkify.addLinks(textView, pattern, "http://", new String[] { "http://", "https://"},
+                null, null);
+
+        URLSpan[] spans = textView.getUrls();
+        assertEquals("android.com should be linkified", 1, spans.length);
+        assertEquals("http://android.com", spans[0].getURL());
+    }
+
+    @SmallTest
+    public void testAddLinks_withTextView_doesNotPrependSchemeIfSchemeExists() {
+        Pattern pattern = Pattern.compile("\\b((http|https)://)?android\\.com+\\b");
+        TextView textView = new TextView(mContext);
+        textView.setText("any https://android.com any");
+
+        Linkify.addLinks(textView, pattern, "http://", new String[] { "http://", "https://"},
+                null, null);
+
+        URLSpan[] spans = textView.getUrls();
+        assertEquals("android.com should be linkified", 1, spans.length);
+        assertEquals("https://android.com", spans[0].getURL());
+    }
+
+    // WEB_URLS Related Tests
+
+    @SmallTest
+    public void testAddLinks_doesNotAddLinksForUrlWithoutProtocolAndWithoutKnownTld()
+            throws Exception {
+        Spannable spannable = new SpannableString("hey man.its me");
+        boolean linksAdded = Linkify.addLinks(spannable, Linkify.ALL);
+        assertFalse("Should not add link with unknown TLD", linksAdded);
+    }
+
+    @SmallTest
+    public void testAddLinks_shouldNotAddEmailAddressAsUrl() throws Exception {
+        String url = "name@gmail.com";
+        assertAddLinksWithWebUrlFails("Should not recognize email address as URL", url);
+    }
+
+    public void testAddLinks_acceptsUrlsWithCommasInRequestParameterValues() throws Exception {
+        String url = "https://android.com/path?ll=37.4221,-122.0836&z=17&pll=37.4221,-122.0836";
+        assertAddLinksWithWebUrlSucceeds("Should accept commas", url);
+    }
+
+    @SmallTest
+    public void testAddLinks_addsLinksForUrlWithProtocolWithoutTld() throws Exception {
+        String url = "http://android/#notld///a/n/d/r/o/i/d&p1=1&p2=2";
+        assertAddLinksWithWebUrlSucceeds("Should accept URL starting with protocol but does not" +
+                " have TLD", url);
+    }
+
+    @SmallTest
+    public void testAddLinks_matchesProtocolCaseInsensitive() throws Exception {
+        String url = "hTtP://android.com";
+        assertAddLinksWithWebUrlSucceeds("Protocol matching should be case insensitive", url);
+    }
+
+    @SmallTest
+    public void testAddLinks_matchesValidUrlWithSchemeAndHostname() throws Exception {
+        String url = "http://www.android.com";
+        assertAddLinksWithWebUrlSucceeds("Should match valid URL with scheme and hostname", url);
+    }
+
+    @SmallTest
+    public void testAddLinks_matchesValidUrlWithSchemeHostnameAndNewTld() throws Exception {
+        String url = "http://www.android.me";
+        assertAddLinksWithWebUrlSucceeds("Should match valid URL with scheme hostname and new TLD",
+                url);
+    }
+
+    @SmallTest
+    public void testAddLinks_matchesValidUrlWithHostnameAndNewTld() throws Exception {
+        String url = "android.camera";
+        assertAddLinksWithWebUrlSucceeds("Should match valid URL with hostname and new TLD", url);
+    }
+
+    @SmallTest
+    public void testAddLinks_matchesPunycodeUrl() throws Exception {
+        String url = "http://xn--fsqu00a.xn--unup4y";
+        assertAddLinksWithWebUrlSucceeds("Should match Punycode URL", url);
+    }
+
+    @SmallTest
+    public void testAddLinks_matchesPunycodeUrlWithoutProtocol() throws Exception {
+        String url = "xn--fsqu00a.xn--unup4y";
+        assertAddLinksWithWebUrlSucceeds("Should match Punycode URL without protocol", url);
+    }
+
+    @SmallTest
+    public void testAddLinks_doesNotMatchPunycodeTldThatStartsWithDash() throws Exception {
+        String url = "xn--fsqu00a.-xn--unup4y";
+        assertAddLinksWithWebUrlFails("Should not match Punycode TLD that starts with dash", url);
+    }
+
+    @SmallTest
+    public void testAddLinks_partiallyMatchesPunycodeTldThatEndsWithDash() throws Exception {
+        String url = "http://xn--fsqu00a.xn--unup4y-";
+        assertAddLinksWithWebUrlPartiallyMatches("Should partially match Punycode TLD that ends " +
+                "with dash", "http://xn--fsqu00a.xn--unup4y", url);
+    }
+
+    @SmallTest
+    public void testAddLinks_matchesUrlWithUnicodeDomainName() throws Exception {
+        String url = "http://\uD604\uAE08\uC601\uC218\uC99D.kr";
+        assertAddLinksWithWebUrlSucceeds("Should match URL with Unicode domain name", url);
+    }
+
+    @SmallTest
+    public void testAddLinks_matchesUrlWithUnicodeDomainNameWithoutProtocol() throws Exception {
+        String url = "\uD604\uAE08\uC601\uC218\uC99D.kr";
+        assertAddLinksWithWebUrlSucceeds("Should match URL without protocol and with Unicode " +
+                "domain name", url);
+    }
+
+    @SmallTest
+    public void testAddLinks_matchesUrlWithUnicodeDomainNameAndTld() throws Exception {
+        String url = "\uB3C4\uBA54\uC778.\uD55C\uAD6D";
+        assertAddLinksWithWebUrlSucceeds("Should match URL with Unicode domain name and TLD", url);
+    }
+
+    @SmallTest
+    public void testAddLinks_matchesUrlWithUnicodePath() throws Exception {
+        String url = "http://android.com/\u2019/a";
+        assertAddLinksWithWebUrlSucceeds("Should match URL with Unicode path", url);
+    }
+
+    @SmallTest
+    public void testAddLinks_matchesValidUrlWithPort() throws Exception {
+        String url = "http://www.example.com:8080";
+        assertAddLinksWithWebUrlSucceeds("Should match URL with port", url);
+    }
+
+    @SmallTest
+    public void testAddLinks_matchesUrlWithPortAndQuery() throws Exception {
+        String url = "http://www.example.com:8080/?foo=bar";
+        assertAddLinksWithWebUrlSucceeds("Should match URL with port and query", url);
+    }
+
+    @SmallTest
+    public void testAddLinks_matchesUrlWithTilde() throws Exception {
+        String url = "http://www.example.com:8080/~user/?foo=bar";
+        assertAddLinksWithWebUrlSucceeds("Should match URL with tilde", url);
+    }
+
+    @SmallTest
+    public void testAddLinks_matchesUrlStartingWithHttpAndDoesNotHaveTld() throws Exception {
+        String url = "http://android/#notld///a/n/d/r/o/i/d&p1=1&p2=2";
+        assertAddLinksWithWebUrlSucceeds("Should match URL without a TLD and starting with http",
+                url);
+    }
+
+    @SmallTest
+    public void testAddLinks_doesNotMatchUrlsWithoutProtocolAndWithUnknownTld() throws Exception {
+        String url = "thank.you";
+        assertAddLinksWithWebUrlFails("Should not match URL that does not start with a protocol " +
+                "and does not contain a known TLD", url);
+    }
+
+    @SmallTest
+    public void testAddLinks_partiallyMatchesUrlWithInvalidRequestParameter() throws Exception {
+        String url = "http://android.com?p=value";
+        assertAddLinksWithWebUrlPartiallyMatches("Should partially match URL with invalid " +
+                "request parameter", "http://android.com", url);
+    }
+
+    @SmallTest
+    public void testAddLinks_matchesValidUrlWithEmoji() throws Exception {
+        String url = "Thank\u263A.com";
+        assertAddLinksWithWebUrlSucceeds("Should match URL with emoji", url);
+    }
+
+    @SmallTest
+    public void testAddLinks_doesNotMatchUrlsWithEmojiWithoutProtocolAndWithoutKnownTld()
+            throws Exception {
+        String url = "Thank\u263A.you";
+        assertAddLinksWithWebUrlFails("Should not match URLs containing emoji and with unknown " +
+                "TLD", url);
+    }
+
+    @SmallTest
+    public void testAddLinks_matchesDomainNameWithSurrogatePairs() throws Exception {
+        String url = "android\uD83C\uDF38.com";
+        assertAddLinksWithWebUrlSucceeds("Should match domain name with Unicode surrogate pairs",
+                url);
+    }
+
+    @SmallTest
+    public void testAddLinks_matchesTldWithSurrogatePairs() throws Exception {
+        String url = "http://android.\uD83C\uDF38com";
+        assertAddLinksWithWebUrlSucceeds("Should match TLD with Unicode surrogate pairs", url);
+    }
+
+    @SmallTest
+    public void testAddLinks_doesNotMatchUrlWithExcludedSurrogate() throws Exception {
+        String url = "android\uD83F\uDFFE.com";
+        assertAddLinksWithWebUrlFails("Should not match URL with excluded Unicode surrogate" +
+                " pair",  url);
+    }
+
+    @SmallTest
+    public void testAddLinks_matchesPathWithSurrogatePairs() throws Exception {
+        String url = "http://android.com/path-with-\uD83C\uDF38?v=\uD83C\uDF38f";
+        assertAddLinksWithWebUrlSucceeds("Should match path and query with Unicode surrogate pairs",
+                url);
+    }
+
+    @SmallTest
+    public void testAddLinks__doesNotMatchUnicodeSpaces() throws Exception {
+        String part1 = "http://and";
+        String part2 = "roid.com";
+        String[] emptySpaces = new String[]{
+                "\u00A0", // no-break space
+                "\u2000", // en quad
+                "\u2001", // em quad
+                "\u2002", // en space
+                "\u2003", // em space
+                "\u2004", // three-per-em space
+                "\u2005", // four-per-em space
+                "\u2006", // six-per-em space
+                "\u2007", // figure space
+                "\u2008", // punctuation space
+                "\u2009", // thin space
+                "\u200A", // hair space
+                "\u2028", // line separator
+                "\u2029", // paragraph separator
+                "\u202F", // narrow no-break space
+                "\u3000"  // ideographic space
+        };
+
+        for (String emptySpace : emptySpaces) {
+            String url = part1 + emptySpace + part2;
+            assertAddLinksWithWebUrlPartiallyMatches("Should not include empty space with code: " +
+                    emptySpace.codePointAt(0), part1, url);
+        }
+    }
+
+    // EMAIL_ADDRESSES Related Tests
+
+    public void testAddLinks_email_matchesShortValidEmail() throws Exception {
+        String email = "a@a.co";
+        assertAddLinksWithEmailSucceeds("Should match email: " + email, email);
+    }
+
+    public void testAddLinks_email_matchesRegularEmail() throws Exception {
+        String email = "email@android.com";
+        assertAddLinksWithEmailSucceeds("Should match email: " + email, email);
+    }
+
+    public void testAddLinks_email_matchesEmailWithMultipleSubdomains() throws Exception {
+        String email = "email@e.somelongdomainnameforandroid.abc.uk";
+        assertAddLinksWithEmailSucceeds("Should match email: " + email, email);
+    }
+
+    public void testAddLinks_email_matchesLocalPartWithDot() throws Exception {
+        String email = "e.mail@android.com";
+        assertAddLinksWithEmailSucceeds("Should match email: " + email, email);
+    }
+
+    public void testAddLinks_email_matchesLocalPartWithPlus() throws Exception {
+        String email = "e+mail@android.com";
+        assertAddLinksWithEmailSucceeds("Should match email: " + email, email);
+    }
+
+    public void testAddLinks_email_matchesLocalPartWithUnderscore() throws Exception {
+        String email = "e_mail@android.com";
+        assertAddLinksWithEmailSucceeds("Should match email: " + email, email);
+    }
+
+    public void testAddLinks_email_matchesLocalPartWithDash() throws Exception {
+        String email = "e-mail@android.com";
+        assertAddLinksWithEmailSucceeds("Should match email: " + email, email);
+    }
+
+    public void testAddLinks_email_matchesLocalPartWithApostrophe() throws Exception {
+        String email = "e'mail@android.com";
+        assertAddLinksWithEmailSucceeds("Should match email: " + email, email);
+    }
+
+    public void testAddLinks_email_matchesLocalPartWithDigits() throws Exception {
+        String email = "123@android.com";
+        assertAddLinksWithEmailSucceeds("Should match email: " + email, email);
+    }
+
+    public void testAddLinks_email_matchesUnicodeLocalPart() throws Exception {
+        String email = "\uD604\uAE08\uC601\uC218\uC99D@android.kr";
+        assertAddLinksWithEmailSucceeds("Should match email: " + email, email);
+    }
+
+    public void testAddLinks_email_matchesLocalPartWithEmoji() throws Exception {
+        String email = "smiley\u263A@android.com";
+        assertAddLinksWithEmailSucceeds("Should match email: " + email, email);
+    }
+
+    public void testAddLinks_email_matchesLocalPartWithSurrogatePairs()
+            throws Exception {
+        String email = "a\uD83C\uDF38a@android.com";
+        assertAddLinksWithEmailSucceeds("Should match email: " + email, email);
+    }
+
+    public void testAddLinks_email_matchesDomainWithDash() throws Exception {
+        String email = "email@an-droid.com";
+        assertAddLinksWithEmailSucceeds("Should match email: " + email, email);
+    }
+
+    public void testAddLinks_email_matchesUnicodeDomain() throws Exception {
+        String email = "email@\uD604\uAE08\uC601\uC218\uC99D.kr";
+        assertAddLinksWithEmailSucceeds("Should match email: " + email, email);
+    }
+
+    public void testAddLinks_email_matchesUnicodeLocalPartAndDomain()
+            throws Exception {
+        String email = "\uD604\uAE08\uC601\uC218\uC99D@\uD604\uAE08\uC601\uC218\uC99D.kr";
+        assertAddLinksWithEmailSucceeds("Should match email: " + email, email);
+    }
+
+    public void testAddLinks_email_matchesDomainWithEmoji() throws Exception {
+        String email = "smiley@\u263Aandroid.com";
+        assertAddLinksWithEmailSucceeds("Should match email: " + email, email);
+    }
+
+    public void testAddLinks_email_matchesDomainWithSurrogatePairs()
+            throws Exception {
+        String email = "email@\uD83C\uDF38android.com";
+        assertAddLinksWithEmailSucceeds("Should match email: " + email, email);
+    }
+
+    public void testAddLinks_email_matchesLocalPartAndDomainWithSurrogatePairs()
+            throws Exception {
+        String email = "a\uD83C\uDF38a@\uD83C\uDF38android.com";
+        assertAddLinksWithEmailSucceeds("Should match email: " + email, email);
+    }
+
+    public void testAddLinks_partiallyMatchesEmailEndingWithDot() throws Exception {
+        String email = "email@android.co.uk.";
+        assertAddLinksWithEmailPartiallyMatches("Should partially match email ending with dot",
+                "mailto:email@android.co.uk", email);
+    }
+
+    public void testAddLinks_email_partiallyMatchesLocalPartStartingWithDot()
+            throws Exception {
+        String email = ".email@android.com";
+        assertAddLinksWithEmailPartiallyMatches("Should partially match email starting " +
+                "with dot", "mailto:email@android.com", email);
+    }
+
+    public void testAddLinks_email_doesNotMatchStringWithoutAtSign() throws Exception {
+        String email = "android.com";
+        assertAddLinksWithEmailFails("Should not match email: " + email, email);
+    }
+
+    public void testAddLinks_email_doesNotMatchPlainString() throws Exception {
+        String email = "email";
+        assertAddLinksWithEmailFails("Should not match email: " + email, email);
+    }
+
+    public void testAddLinks_email_doesNotMatchEmailWithoutTld() throws Exception {
+        String email = "email@android";
+        assertAddLinksWithEmailFails("Should not match email: " + email, email);
+    }
+
+    public void testAddLinks_email_doesNotMatchLocalPartEndingWithDot()
+            throws Exception {
+        String email = "email.@android.com";
+        assertAddLinksWithEmailFails("Should not match email: " + email, email);
+    }
+
+    public void testAddLinks_email_doesNotMatchDomainStartingWithDash()
+            throws Exception {
+        String email = "email@-android.com";
+        assertAddLinksWithEmailFails("Should not match email: " + email, email);
+    }
+
+    public void testAddLinks_email_doesNotMatchDomainWithConsecutiveDots()
+            throws Exception {
+        String email = "email@android..com";
+        assertAddLinksWithEmailFails("Should not match email: " + email, email);
+    }
+
+    public void testAddLinks_email_doesNotMatchEmailWithIp() throws Exception {
+        String email = "email@127.0.0.1";
+        assertAddLinksWithEmailFails("Should not match email: " + email, email);
+    }
+
+    public void testAddLinks_email_doesNotMatchEmailWithInvalidTld()
+            throws Exception {
+        String email = "email@android.c";
+        assertAddLinksWithEmailFails("Should not match email: " + email, email);
+    }
+
+    public void testAddLinks_email_matchesLocalPartUpTo64Chars() throws Exception {
+        String localPart = "";
+        for (int i = 0; i < 64; i++) {
+            localPart += "a";
+        }
+        String email = localPart + "@android.com";
+        assertAddLinksWithEmailSucceeds("Should match email local part of length: " +
+                localPart.length(), email);
+
+        email = localPart + "a@android.com";
+        assertAddLinksWithEmailFails("Should not match email local part of length:" +
+                localPart.length(), email);
+    }
+
+    public void testAddLinks_email_matchesSubdomainUpTo63Chars() throws Exception {
+        String subdomain = "";
+        for (int i = 0; i < 63; i++) {
+            subdomain += "a";
+        }
+        String email = "email@" + subdomain + ".com";
+
+        assertAddLinksWithEmailSucceeds("Should match email subdomain of length: " +
+                subdomain.length(), email);
+
+        subdomain += "a";
+        email = "email@" + subdomain + ".com";
+
+        assertAddLinksWithEmailFails("Should not match email subdomain of length:" +
+                subdomain.length(), email);
+    }
+
+    public void testAddLinks_email_matchesDomainUpTo255Chars() throws Exception {
+        String domain = "";
+        while (domain.length() <= 250) {
+            domain += "d.";
+        }
+        domain += "com";
+        assertEquals(255, domain.length());
+        String email = "a@" + domain;
+        assertAddLinksWithEmailSucceeds("Should match email domain of length: " +
+                domain.length(), email);
+
+        email = email + "m";
+        assertAddLinksWithEmailFails("Should not match email domain of length:" +
+                domain.length(), email);
+    }
+
+    // Utility functions
+    private static void assertAddLinksWithWebUrlSucceeds(String msg, String url) {
+        assertAddLinksSucceeds(msg, url, Linkify.WEB_URLS);
+    }
+
+    private static void assertAddLinksWithWebUrlFails(String msg, String url) {
+        assertAddLinksFails(msg, url, Linkify.WEB_URLS);
+    }
+
+    private static void assertAddLinksWithWebUrlPartiallyMatches(String msg, String expected,
+            String url) {
+        assertAddLinksPartiallyMatches(msg, expected, url, Linkify.WEB_URLS);
+    }
+
+    private static void assertAddLinksWithEmailSucceeds(String msg, String url) {
+        assertAddLinksSucceeds(msg, url, Linkify.EMAIL_ADDRESSES);
+    }
+
+    private static void assertAddLinksWithEmailFails(String msg, String url) {
+        assertAddLinksFails(msg, url, Linkify.EMAIL_ADDRESSES);
+    }
+
+    private static void assertAddLinksWithEmailPartiallyMatches(String msg, String expected,
+            String url) {
+        assertAddLinksPartiallyMatches(msg, expected, url, Linkify.EMAIL_ADDRESSES);
+    }
+
+    private static void assertAddLinksSucceeds(String msg, String string, int type) {
+        String str = "start " + string + " end";
+        Spannable spannable = new SpannableString(str);
+
+        boolean linksAdded = Linkify.addLinks(spannable, type);
+        URLSpan[] spans = spannable.getSpans(0, str.length(), URLSpan.class);
+
+        assertTrue(msg, linksAdded);
+        assertEquals("Span should start from the beginning of: " + string,
+                "start ".length(), spannable.getSpanStart(spans[0]));
+        assertEquals("Span should end at the end of: " + string,
+                str.length() - " end".length(), spannable.getSpanEnd(spans[0]));
+    }
+
+    private static void assertAddLinksFails(String msg, String string, int type) {
+        Spannable spannable = new SpannableString("start " + string + " end");
+        boolean linksAdded = Linkify.addLinks(spannable, type);
+        assertFalse(msg, linksAdded);
+    }
+
+    private static void assertAddLinksPartiallyMatches(String msg, String expected,
+                                                       String string, int type) {
+        Spannable spannable = new SpannableString("start " + string + " end");
+        boolean linksAdded = Linkify.addLinks(spannable, type);
+        URLSpan[] spans = spannable.getSpans(0, spannable.length(), URLSpan.class);
+        assertTrue(msg, linksAdded);
+        assertEquals(msg, expected, spans[0].getURL().toString());
+    }
 }
diff --git a/tests/tests/textureview/Android.mk b/tests/tests/textureview/Android.mk
index f85a738..d1f542b 100644
--- a/tests/tests/textureview/Android.mk
+++ b/tests/tests/textureview/Android.mk
@@ -27,6 +27,9 @@
 
 LOCAL_PACKAGE_NAME := CtsTextureViewTestCases
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_SDK_VERSION := current
 
 include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/textureview/AndroidManifest.xml b/tests/tests/textureview/AndroidManifest.xml
index 9ec3f17..6832059 100644
--- a/tests/tests/textureview/AndroidManifest.xml
+++ b/tests/tests/textureview/AndroidManifest.xml
@@ -14,8 +14,7 @@
      limitations under the License.
 -->
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.textureview"
-    >
+    package="android.textureview.cts">
 
     <uses-feature android:glEsVersion="0x00020000" android:required="true" />
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
@@ -24,7 +23,7 @@
     <uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES" />
 
     <instrumentation
-        android:targetPackage="com.android.cts.textureview"
+        android:targetPackage="android.textureview.cts"
         android:name="android.support.test.runner.AndroidJUnitRunner" >
         <meta-data android:name="listener"
             android:value="com.android.cts.runner.CtsTestRunListener" />
diff --git a/tests/tests/textureview/AndroidTest.xml b/tests/tests/textureview/AndroidTest.xml
new file mode 100644
index 0000000..d60a4a3
--- /dev/null
+++ b/tests/tests/textureview/AndroidTest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS TextureView test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsTextureViewTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.textureview.cts" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/tests/theme/Android.mk b/tests/tests/theme/Android.mk
index 134af7c..8b69a09 100644
--- a/tests/tests/theme/Android.mk
+++ b/tests/tests/theme/Android.mk
@@ -16,7 +16,7 @@
 
 include $(CLEAR_VARS)
 
-LOCAL_PACKAGE_NAME := CtsThemeTestCases
+LOCAL_PACKAGE_NAME := CtsThemeDeviceTestCases
 
 # Don't include this package in any target.
 LOCAL_MODULE_TAGS := optional
@@ -24,10 +24,14 @@
 # When built, explicitly put it in the data partition.
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
 
-LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
+LOCAL_STATIC_JAVA_LIBRARIES := \
+    ctstestrunner platform-test-annotations
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_SDK_VERSION := current
 
 include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/theme/AndroidManifest.xml b/tests/tests/theme/AndroidManifest.xml
index 8232d2b..e3ba0c6 100644
--- a/tests/tests/theme/AndroidManifest.xml
+++ b/tests/tests/theme/AndroidManifest.xml
@@ -15,7 +15,7 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.theme">
+    package="android.theme.cts">
 
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <application>
@@ -24,7 +24,7 @@
     </application>
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-            android:targetPackage="com.android.cts.theme"
+            android:targetPackage="android.theme.cts"
             android:label="CTS tests for themes">
         <meta-data android:name="listener"
             android:value="com.android.cts.runner.CtsTestRunListener" />
diff --git a/tests/tests/theme/AndroidTest.xml b/tests/tests/theme/AndroidTest.xml
new file mode 100644
index 0000000..82bd476
--- /dev/null
+++ b/tests/tests/theme/AndroidTest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS Theme test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsThemeDeviceTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.theme.cts" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/tests/theme/src/android/theme/cts/DeviceDefaultActivity.java b/tests/tests/theme/src/android/theme/cts/DeviceDefaultActivity.java
index 139a48f..623282b 100644
--- a/tests/tests/theme/src/android/theme/cts/DeviceDefaultActivity.java
+++ b/tests/tests/theme/src/android/theme/cts/DeviceDefaultActivity.java
@@ -16,7 +16,7 @@
 
 package android.theme.cts;
 
-import com.android.cts.theme.R;
+import android.theme.cts.R;
 
 import android.app.Activity;
 import android.os.Bundle;
diff --git a/tests/tests/theme/src/android/theme/cts/DeviceDefaultTest.java b/tests/tests/theme/src/android/theme/cts/DeviceDefaultTest.java
index 77de0b4..fdac2d1 100644
--- a/tests/tests/theme/src/android/theme/cts/DeviceDefaultTest.java
+++ b/tests/tests/theme/src/android/theme/cts/DeviceDefaultTest.java
@@ -21,6 +21,7 @@
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.content.res.Configuration;
+import android.platform.test.annotations.Presubmit;
 import android.test.ActivityInstrumentationTestCase2;
 
 public class DeviceDefaultTest extends ActivityInstrumentationTestCase2<DeviceDefaultActivity> {
@@ -57,6 +58,7 @@
         assertNoActionBar(android.R.style.Theme_DeviceDefault_DialogWhenLarge_NoActionBar);
     }
 
+    @Presubmit
     public void testGetActionBar_DeviceDefault_InputMethod() {
         assertNoActionBar(android.R.style.Theme_DeviceDefault_InputMethod);
     }
diff --git a/tests/tests/transition/Android.mk b/tests/tests/transition/Android.mk
index 3b48e25..af8b4eb 100644
--- a/tests/tests/transition/Android.mk
+++ b/tests/tests/transition/Android.mk
@@ -28,6 +28,9 @@
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_SDK_VERSION := current
 
 include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/transition/AndroidManifest.xml b/tests/tests/transition/AndroidManifest.xml
index 0ce1791..3205f28 100644
--- a/tests/tests/transition/AndroidManifest.xml
+++ b/tests/tests/transition/AndroidManifest.xml
@@ -15,7 +15,7 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.transition">
+    package="android.transition.cts">
     <uses-sdk android:minSdkVersion="11" />
     <uses-permission android:name="android.permission.INJECT_EVENTS" />
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
@@ -26,7 +26,7 @@
     </application>
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.cts.transition"
+                     android:targetPackage="android.transition.cts"
                      android:label="CTS tests for android.transition package">
         <meta-data android:name="listener"
             android:value="com.android.cts.runner.CtsTestRunListener" />
diff --git a/tests/tests/transition/AndroidTest.xml b/tests/tests/transition/AndroidTest.xml
new file mode 100644
index 0000000..5aad82b
--- /dev/null
+++ b/tests/tests/transition/AndroidTest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS Transition test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsTransitionTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.transition.cts" />
+    </test>
+</configuration>
diff --git a/tests/tests/transition/res/layout/scene10.xml b/tests/tests/transition/res/layout/scene10.xml
new file mode 100644
index 0000000..16e3c20
--- /dev/null
+++ b/tests/tests/transition/res/layout/scene10.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:transitionName="holder"
+                android:id="@+id/holder">
+    <View android:layout_width="10dp"
+          android:layout_height="10dp"
+          android:background="#F00"
+          android:layout_alignParentLeft="true"
+          android:layout_alignParentTop="true"
+          android:id="@+id/redSquare" />
+    <View android:layout_width="10dp"
+          android:layout_height="10dp"
+          android:background="#0F0"
+          android:layout_alignParentRight="true"
+          android:layout_alignParentTop="true"
+          android:id="@+id/greenSquare"/>
+    <View android:layout_width="10dp"
+          android:layout_height="10dp"
+          android:background="#00F"
+          android:layout_alignParentRight="true"
+          android:layout_alignParentBottom="true"
+          android:id="@+id/blueSquare" />
+    <View android:layout_width="10dp"
+          android:layout_height="10dp"
+          android:background="#FF0"
+          android:layout_alignParentLeft="true"
+          android:layout_alignParentBottom="true"
+          android:id="@+id/yellowSquare"/>
+</RelativeLayout>
diff --git a/tests/tests/transition/res/layout/scene6.xml b/tests/tests/transition/res/layout/scene6.xml
new file mode 100644
index 0000000..8cffee5
--- /dev/null
+++ b/tests/tests/transition/res/layout/scene6.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:transitionName="holder"
+                android:id="@+id/holder">
+    <View android:layout_width="30dp"
+          android:layout_height="30dp"
+          android:background="#0F0"
+          android:transitionName="green"
+          android:id="@+id/greenSquare" />
+    <View android:layout_width="30dp"
+          android:layout_height="30dp"
+          android:background="#F00"
+          android:transitionName="red"
+          android:id="@+id/redSquare"
+          android:layout_below="@+id/greenSquare" />
+    <TextView android:layout_width="wrap_content"
+              android:layout_height="wrap_content"
+              android:transitionName="hello"
+              android:text="@string/hello"
+              android:id="@+id/hello"/>
+</RelativeLayout>
diff --git a/tests/tests/transition/res/layout/scene7.xml b/tests/tests/transition/res/layout/scene7.xml
new file mode 100644
index 0000000..72c74e8
--- /dev/null
+++ b/tests/tests/transition/res/layout/scene7.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:transitionName="holder"
+                android:id="@+id/holder">
+    <View android:layout_width="10dp"
+          android:layout_height="10dp"
+          android:background="#0F0"
+          android:transitionName="green"
+          android:id="@+id/greenSquare" />
+    <TextView android:layout_width="wrap_content"
+              android:layout_height="wrap_content"
+              android:transitionName="hello"
+              android:text="@string/hello"
+              android:id="@+id/hello"/>
+</RelativeLayout>
diff --git a/tests/tests/transition/res/layout/scene8.xml b/tests/tests/transition/res/layout/scene8.xml
new file mode 100644
index 0000000..69674ee
--- /dev/null
+++ b/tests/tests/transition/res/layout/scene8.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:transitionName="holder"
+                android:id="@+id/holder">
+    <View android:layout_width="10dp"
+          android:layout_height="10dp"
+          android:background="#F00"
+          android:transitionName="red"
+          android:id="@+id/greenSquare" />
+    <View android:layout_width="10dp"
+          android:layout_height="10dp"
+          android:background="#0F0"
+          android:transitionName="green"
+          android:id="@+id/redSquare"
+          android:layout_below="@+id/greenSquare" />
+    <TextView android:layout_width="wrap_content"
+              android:layout_height="wrap_content"
+              android:transitionName="hello"
+              android:text="@string/hello"
+              android:id="@+id/hello"/>
+</RelativeLayout>
diff --git a/tests/tests/transition/res/layout/scene9.xml b/tests/tests/transition/res/layout/scene9.xml
new file mode 100644
index 0000000..2eb3762f
--- /dev/null
+++ b/tests/tests/transition/res/layout/scene9.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:transitionName="holder"
+                android:id="@+id/holder">
+    <FrameLayout
+            android:layout_marginTop="50dp"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content">
+        <TextView
+                android:id="@+id/text"
+                android:text="@string/longText"
+                android:layout_width="100dp"
+                android:layout_height="100dp"/>
+    </FrameLayout>
+</RelativeLayout>
diff --git a/tests/tests/transition/src/android/transition/cts/ArcMotionTest.java b/tests/tests/transition/src/android/transition/cts/ArcMotionTest.java
new file mode 100644
index 0000000..d6b00cf
--- /dev/null
+++ b/tests/tests/transition/src/android/transition/cts/ArcMotionTest.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.transition.cts;
+
+import android.graphics.Path;
+import android.graphics.PathMeasure;
+import android.transition.ArcMotion;
+
+import junit.framework.TestCase;
+
+public class ArcMotionTest extends PathMotionTest {
+
+    public void test90Quadrants() throws Throwable {
+        ArcMotion arcMotion = new ArcMotion();
+        arcMotion.setMaximumAngle(90);
+
+        Path expected = arcWithPoint(0, 100, 100, 0, 100, 100);
+        Path path = arcMotion.getPath(0, 100, 100, 0);
+        assertPathMatches(expected, path);
+
+        expected = arcWithPoint(100, 0, 0, -100, 100, -100);
+        path = arcMotion.getPath(100, 0, 0, -100);
+        assertPathMatches(expected, path);
+
+        expected = arcWithPoint(0, -100, -100, 0, -100, -100);
+        path = arcMotion.getPath(0, -100, -100, 0);
+        assertPathMatches(expected, path);
+
+        expected = arcWithPoint(-100, 0, 0, 100, -100, 100);
+        path = arcMotion.getPath(-100, 0, 0, 100);
+        assertPathMatches(expected, path);
+    }
+
+    public void test345Triangles() throws Throwable {
+        // 3-4-5 triangles are easy to calculate the control points
+        ArcMotion arcMotion = new ArcMotion();
+        arcMotion.setMaximumAngle(90);
+        Path expected;
+        Path path;
+
+        expected = arcWithPoint(0, 120, 160, 0, 125, 120);
+        path = arcMotion.getPath(0, 120, 160, 0);
+        assertPathMatches(expected, path);
+
+        expected = arcWithPoint(0, 160, 120, 0, 120, 125);
+        path = arcMotion.getPath(0, 160, 120, 0);
+        assertPathMatches(expected, path);
+
+        expected = arcWithPoint(-120, 0, 0, 160, -120, 125);
+        path = arcMotion.getPath(-120, 0, 0, 160);
+        assertPathMatches(expected, path);
+
+        expected = arcWithPoint(-160, 0, 0, 120, -125, 120);
+        path = arcMotion.getPath(-160, 0, 0, 120);
+        assertPathMatches(expected, path);
+
+        expected = arcWithPoint(0, -120, -160, 0, -125, -120);
+        path = arcMotion.getPath(0, -120, -160, 0);
+        assertPathMatches(expected, path);
+
+        expected = arcWithPoint(0, -160, -120, 0, -120, -125);
+        path = arcMotion.getPath(0, -160, -120, 0);
+        assertPathMatches(expected, path);
+
+        expected = arcWithPoint(120, 0, 0, -160, 120, -125);
+        path = arcMotion.getPath(120, 0, 0, -160);
+        assertPathMatches(expected, path);
+
+        expected = arcWithPoint(160, 0, 0, -120, 125, -120);
+        path = arcMotion.getPath(160, 0, 0, -120);
+        assertPathMatches(expected, path);
+    }
+
+    private Path arcWithPoint(float startX, float startY, float endX, float endY,
+            float eX, float eY) {
+        float c1x = (eX + startX)/2;
+        float c1y = (eY + startY)/2;
+        float c2x = (eX + endX)/2;
+        float c2y = (eY + endY)/2;
+        Path path = new Path();
+        path.moveTo(startX, startY);
+        path.cubicTo(c1x, c1y, c2x, c2y, endX, endY);
+        return path;
+    }
+
+    public void testMaximumAngle() throws Throwable {
+        ArcMotion arcMotion = new ArcMotion();
+        arcMotion.setMaximumAngle(45f);
+        assertEquals(45f, arcMotion.getMaximumAngle());
+
+        float ratio = (float) Math.tan(Math.PI/8);
+        float ex = 50 + (50 * ratio);
+        float ey = ex;
+
+        Path expected = arcWithPoint(0, 100, 100, 0, ex, ey);
+        Path path = arcMotion.getPath(0, 100, 100, 0);
+        assertPathMatches(expected, path);
+    }
+
+    public void testMinimumHorizontalAngle() throws Throwable {
+        ArcMotion arcMotion = new ArcMotion();
+        arcMotion.setMinimumHorizontalAngle(45);
+        assertEquals(45f, arcMotion.getMinimumHorizontalAngle());
+
+        float ey = (float)(Math.tan(Math.PI/8) * 50);
+        float ex = 50;
+        Path expected = arcWithPoint(0, 0, 100, 0, ex, ey);
+        Path path = arcMotion.getPath(0, 0, 100, 0);
+        assertPathMatches(expected, path);
+
+        // Pretty much the same, but follows a different path.
+        expected = arcWithPoint(0, 0, 100.001f, 0, ex, ey);
+        path = arcMotion.getPath(0, 0, 100.001f, 0);
+        assertPathMatches(expected, path);
+    }
+
+    public void testMinimumVerticalAngle() throws Throwable {
+        ArcMotion arcMotion = new ArcMotion();
+        arcMotion.setMinimumVerticalAngle(45);
+        assertEquals(45f, arcMotion.getMinimumVerticalAngle());
+
+        float ex = (float)(Math.tan(Math.PI/8) * 50);
+        float ey = 50;
+        Path expected = arcWithPoint(0, 0, 0, 100, ex, ey);
+        Path path = arcMotion.getPath(0, 0, 0, 100);
+        assertPathMatches(expected, path);
+
+        // Pretty much the same, but follows a different path.
+        expected = arcWithPoint(0, 0, 0, 100.001f, ex, ey);
+        path = arcMotion.getPath(0, 0, 0, 100.001f);
+        assertPathMatches(expected, path);
+    }
+}
+
diff --git a/tests/tests/transition/src/android/transition/cts/BaseTransitionTest.java b/tests/tests/transition/src/android/transition/cts/BaseTransitionTest.java
index 4945023..944ff91 100644
--- a/tests/tests/transition/src/android/transition/cts/BaseTransitionTest.java
+++ b/tests/tests/transition/src/android/transition/cts/BaseTransitionTest.java
@@ -15,13 +15,11 @@
  */
 package android.transition.cts;
 
-import com.android.cts.transition.R;
-
 import android.animation.Animator;
 import android.animation.ObjectAnimator;
-import android.os.SystemClock;
 import android.test.ActivityInstrumentationTestCase2;
 import android.transition.Scene;
+import android.transition.Transition;
 import android.transition.TransitionManager;
 import android.transition.TransitionValues;
 import android.transition.Visibility;
@@ -32,13 +30,16 @@
 import android.widget.FrameLayout;
 
 import java.util.ArrayList;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 
 public class BaseTransitionTest extends ActivityInstrumentationTestCase2<TransitionActivity> {
     protected TransitionActivity mActivity;
     protected FrameLayout mSceneRoot;
     public float mAnimatedValue;
-    protected ArrayList<View> mTargets = new ArrayList<>();
-    protected TestTransition mTransition;
+    protected ArrayList<View> mTargets = new ArrayList<View>();
+    protected Transition mTransition;
+    protected SimpleTransitionListener mListener;
 
     public BaseTransitionTest() {
         super(TransitionActivity.class);
@@ -52,50 +53,72 @@
         mSceneRoot = (FrameLayout) mActivity.findViewById(R.id.container);
         mTargets.clear();
         mTransition = new TestTransition();
+        mListener = new SimpleTransitionListener();
+        mTransition.addListener(mListener);
     }
 
     protected void waitForStart() throws InterruptedException {
-        waitForStart(mTransition.listener);
+        waitForStart(mListener);
     }
 
-    protected static void waitForStart(SimpleTransitionListener listener) throws InterruptedException {
-        long endTime = SystemClock.uptimeMillis() + 4000;
-        synchronized (listener) {
-            while (!listener.started) {
-                long now = SystemClock.uptimeMillis();
-                long waitTime = endTime - now;
-                if (waitTime <= 0) {
-                    throw new InterruptedException();
-                }
-                listener.wait(waitTime);
-            }
-        }
+    protected void waitForStart(SimpleTransitionListener listener) throws InterruptedException {
+        assertTrue(listener.startLatch.await(4000, TimeUnit.MILLISECONDS));
     }
 
     protected void waitForEnd(long waitMillis) throws InterruptedException {
-        waitForEnd(mTransition.listener, waitMillis);
+        waitForEnd(mListener, waitMillis);
+        getInstrumentation().waitForIdleSync();
     }
 
     protected static void waitForEnd(SimpleTransitionListener listener, long waitMillis)
             throws InterruptedException {
-        long endTime = SystemClock.uptimeMillis() + waitMillis;
-        synchronized (listener) {
-            while (!listener.ended) {
-                long now = SystemClock.uptimeMillis();
-                long waitTime = endTime - now;
-                if (waitTime <= 0) {
-                    throw new InterruptedException();
-                }
-                listener.wait(waitTime);
-            }
-        }
+        listener.endLatch.await(waitMillis, TimeUnit.MILLISECONDS);
     }
 
-    protected void startTransition(final int layoutId) throws Throwable {
+    protected View loadLayout(final int layout) throws Throwable {
+        View[] root = new View[1];
+
         runTestOnUiThread(new Runnable() {
             @Override
             public void run() {
-                Scene scene = Scene.getSceneForLayout(mSceneRoot, layoutId, mActivity);
+                root[0] = mActivity.getLayoutInflater().inflate(layout, mSceneRoot, false);
+            }
+        });
+
+        return root[0];
+    }
+
+    protected Scene loadScene(final View layout) throws Throwable {
+        Scene[] scene = new Scene[1];
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                scene[0] = new Scene(mSceneRoot, layout);
+            }
+        });
+
+        return scene[0];
+    }
+
+    protected Scene loadScene(final int layoutId) throws Throwable {
+        Scene scene[] = new Scene[1];
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                scene[0] = Scene.getSceneForLayout(mSceneRoot, layoutId, mActivity);
+            }
+        });
+        return scene[0];
+    }
+
+    protected void startTransition(final int layoutId) throws Throwable {
+        startTransition(loadScene(layoutId));
+    }
+
+    protected void startTransition(final Scene scene) throws Throwable {
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
                 TransitionManager.go(scene, mTransition);
             }
         });
@@ -112,52 +135,38 @@
     }
 
     protected void enterScene(final int layoutId) throws Throwable {
+        enterScene(loadScene(layoutId));
+    }
+
+    protected void enterScene(final Scene scene) throws Throwable {
         runTestOnUiThread(new Runnable() {
             @Override
             public void run() {
-                Scene scene = Scene.getSceneForLayout(mSceneRoot, layoutId, mActivity);
                 scene.enter();
             }
         });
         getInstrumentation().waitForIdleSync();
     }
 
-    // Waits at least one frame and it could be more. The animated values should have changed
-    // from the previously recorded values by the end of this method.
-    protected void waitForAnimationFrame() throws Throwable {
-        final boolean[] tripped = new boolean[] { false };
+    protected void exitScene(final Scene scene) throws Throwable {
         runTestOnUiThread(new Runnable() {
             @Override
             public void run() {
-                Choreographer.getInstance().postFrameCallbackDelayed(new FrameCallback() {
-                    @Override
-                    public void doFrame(long frameTimeNanos) {
-                        synchronized (tripped) {
-                            tripped[0] = true;
-                            tripped.notifyAll();
-                        }
-                    }
-                }, 16); // make sure it is the next animation frame.
+                scene.exit();
             }
         });
-        synchronized (tripped) {
-            long endTime = SystemClock.uptimeMillis() + 60;
-            while (!tripped[0]) {
-                long waitTime = endTime - SystemClock.uptimeMillis();
-                if (waitTime <= 0) {
-                    throw new InterruptedException();
-                }
-                tripped.wait(waitTime);
-            }
-        }
+        getInstrumentation().waitForIdleSync();
+    }
+
+    protected void resetListener() {
+        mTransition.removeListener(mListener);
+        mListener = new SimpleTransitionListener();
+        mTransition.addListener(mListener);
     }
 
     public class TestTransition extends Visibility {
-        public final SimpleTransitionListener listener = new SimpleTransitionListener();
 
         public TestTransition() {
-            addListener(listener);
-            setDuration(100);
         }
 
         @Override
diff --git a/tests/tests/transition/src/android/transition/cts/ChangeBoundsTest.java b/tests/tests/transition/src/android/transition/cts/ChangeBoundsTest.java
new file mode 100644
index 0000000..d5c1245
--- /dev/null
+++ b/tests/tests/transition/src/android/transition/cts/ChangeBoundsTest.java
@@ -0,0 +1,294 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.transition.cts;
+
+import android.content.res.Resources;
+import android.graphics.Rect;
+import android.transition.ChangeBounds;
+import android.util.TypedValue;
+import android.view.View;
+
+public class ChangeBoundsTest extends BaseTransitionTest {
+    private static final int SMALL_SQUARE_SIZE_DP = 10;
+    private static final int LARGE_SQUARE_SIZE_DP = 30;
+    private static final int SMALL_OFFSET_DP = 2;
+
+    ChangeBounds mChangeBounds;
+
+    public ChangeBoundsTest() {
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        resetChangeBoundsTransition();
+    }
+
+    private void resetChangeBoundsTransition() {
+        mListener = new SimpleTransitionListener();
+        mChangeBounds = new ChangeBounds();
+        mChangeBounds.setDuration(400);
+        mChangeBounds.addListener(mListener);
+        mTransition = mChangeBounds;
+    }
+
+    public void testBasicChangeBounds() throws Throwable {
+        enterScene(R.layout.scene1);
+
+        validateInScene1();
+
+        startTransition(R.layout.scene6);
+
+        // now delay for at least a few frames before checking intermediate values:
+        Thread.sleep(150);
+        validateNormalIntermediate();
+        waitForEnd(400);
+
+        validateInScene6();
+    }
+
+    public void testResizeClip() throws Throwable {
+        assertEquals(false, mChangeBounds.getResizeClip());
+        mChangeBounds.setResizeClip(true);
+        assertEquals(true, mChangeBounds.getResizeClip());
+        enterScene(R.layout.scene1);
+
+        validateInScene1();
+
+        startTransition(R.layout.scene6);
+
+        // now delay for at least a few frames before checking intermediate values:
+        Thread.sleep(150);
+        validateClippedIntermediate();
+        waitForEnd(400);
+
+        validateInScene6();
+    }
+
+    public void testResizeClipSmaller() throws Throwable {
+        mChangeBounds.setResizeClip(true);
+        enterScene(R.layout.scene6);
+
+        validateInScene6();
+
+        startTransition(R.layout.scene1);
+
+        // now delay for at least a few frames before checking intermediate values:
+        Thread.sleep(150);
+        validateClippedIntermediate();
+        waitForEnd(400);
+
+        validateInScene1();
+    }
+
+    public void testInterruptSameDestination() throws Throwable {
+        enterScene(R.layout.scene1);
+
+        validateInScene1();
+
+        startTransition(R.layout.scene6);
+
+        // now delay for at least a few frames before interrupting the transition
+        Thread.sleep(150);
+        resetChangeBoundsTransition();
+        startTransition(R.layout.scene6);
+
+        assertFalse(isRestartingAnimation());
+        waitForEnd(500);
+        validateInScene6();
+    }
+
+    public void testInterruptSameDestinationResizeClip() throws Throwable {
+        mChangeBounds.setResizeClip(true);
+        enterScene(R.layout.scene1);
+
+        validateInScene1();
+
+        startTransition(R.layout.scene6);
+
+        // now delay for at least a few frames before interrupting the transition
+        Thread.sleep(150);
+
+        resetChangeBoundsTransition();
+        mChangeBounds.setResizeClip(true);
+        startTransition(R.layout.scene6);
+
+        assertFalse(isRestartingAnimation());
+        assertFalse(isRestartingClip());
+        waitForEnd(500);
+        validateInScene6();
+    }
+
+    public void testInterruptWithReverse() throws Throwable {
+        enterScene(R.layout.scene1);
+
+        validateInScene1();
+
+        startTransition(R.layout.scene6);
+
+        // now delay for at least a few frames before reversing
+        Thread.sleep(150);
+        // reverse the transition back to scene1
+        resetChangeBoundsTransition();
+        startTransition(R.layout.scene1);
+
+        assertFalse(isRestartingAnimation());
+        waitForEnd(500);
+        validateInScene1();
+    }
+
+    public void testInterruptWithReverseResizeClip() throws Throwable {
+        mChangeBounds.setResizeClip(true);
+        enterScene(R.layout.scene1);
+
+        validateInScene1();
+
+        startTransition(R.layout.scene6);
+
+        // now delay for at least a few frames before reversing
+        Thread.sleep(150);
+
+        // reverse the transition back to scene1
+        resetChangeBoundsTransition();
+        mChangeBounds.setResizeClip(true);
+        startTransition(R.layout.scene1);
+
+        assertFalse(isRestartingAnimation());
+        assertFalse(isRestartingClip());
+        waitForEnd(500);
+        validateInScene1();
+    }
+
+    private boolean isRestartingAnimation() {
+        View red = mActivity.findViewById(R.id.redSquare);
+        View green = mActivity.findViewById(R.id.greenSquare);
+        Resources resources = mActivity.getResources();
+        float closestDistance = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
+                SMALL_OFFSET_DP, resources.getDisplayMetrics());
+        return red.getTop() < closestDistance || green.getTop() < closestDistance;
+    }
+
+    private boolean isRestartingClip() {
+        Resources resources = mActivity.getResources();
+        float smallDim = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
+                SMALL_SQUARE_SIZE_DP + SMALL_OFFSET_DP, resources.getDisplayMetrics());
+        float largeDim = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
+                LARGE_SQUARE_SIZE_DP - SMALL_OFFSET_DP, resources.getDisplayMetrics());
+
+        View red = mActivity.findViewById(R.id.redSquare);
+        Rect redClip = red.getClipBounds();
+        View green = mActivity.findViewById(R.id.greenSquare);
+        Rect greenClip = green.getClipBounds();
+        return redClip == null || redClip.width() < smallDim || redClip.width() > largeDim ||
+                greenClip == null || greenClip.width() < smallDim || greenClip.width() > largeDim;
+    }
+
+    private void validateInScene1() {
+        validateViewPlacement(R.id.redSquare, R.id.greenSquare, SMALL_SQUARE_SIZE_DP);
+    }
+
+    private void validateInScene6() {
+        validateViewPlacement(R.id.greenSquare, R.id.redSquare, LARGE_SQUARE_SIZE_DP);
+    }
+
+    private void validateViewPlacement(int topViewResource, int bottomViewResource, int dim) {
+        Resources resources = mActivity.getResources();
+        float expectedDim = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dim,
+                resources.getDisplayMetrics());
+        View aboveSquare = mActivity.findViewById(topViewResource);
+        assertEquals(0, aboveSquare.getLeft());
+        assertEquals(0, aboveSquare.getTop());
+        assertTrue(aboveSquare.getRight() != 0);
+        final int aboveSquareBottom = aboveSquare.getBottom();
+        assertTrue(aboveSquareBottom != 0);
+
+        View belowSquare = mActivity.findViewById(bottomViewResource);
+        assertEquals(0, belowSquare.getLeft());
+        assertEquals(aboveSquareBottom, belowSquare.getTop());
+        assertEquals(aboveSquareBottom + aboveSquare.getHeight(), belowSquare.getBottom());
+        assertEquals(aboveSquare.getRight(), belowSquare.getRight());
+
+        assertTrue(isWithinAPixel(expectedDim, aboveSquare.getHeight()));
+        assertTrue(isWithinAPixel(expectedDim, aboveSquare.getWidth()));
+        assertTrue(isWithinAPixel(expectedDim, belowSquare.getHeight()));
+        assertTrue(isWithinAPixel(expectedDim, belowSquare.getWidth()));
+
+        assertNull(aboveSquare.getClipBounds());
+        assertNull(belowSquare.getClipBounds());
+    }
+
+    private void validateIntermediatePosition() {
+        Resources resources = mActivity.getResources();
+        float smallDim = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
+                SMALL_SQUARE_SIZE_DP, resources.getDisplayMetrics());
+        float largeDim = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
+                LARGE_SQUARE_SIZE_DP, resources.getDisplayMetrics());
+
+        View redSquare = mActivity.findViewById(R.id.redSquare);
+        View greenSquare = mActivity.findViewById(R.id.greenSquare);
+        assertTrue(redSquare.getTop() != 0);
+        assertTrue(greenSquare.getTop() != 0);
+        assertFalse(isWithinAPixel(smallDim, redSquare.getTop()));
+        assertFalse(isWithinAPixel(largeDim, redSquare.getTop()));
+        assertFalse(isWithinAPixel(smallDim, greenSquare.getTop()));
+        assertFalse(isWithinAPixel(largeDim, greenSquare.getTop()));
+    }
+
+    private void validateClippedIntermediate() {
+        validateIntermediatePosition();
+        Resources resources = mActivity.getResources();
+        float largeDim = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
+                LARGE_SQUARE_SIZE_DP, resources.getDisplayMetrics());
+        View redSquare = mActivity.findViewById(R.id.redSquare);
+        View greenSquare = mActivity.findViewById(R.id.greenSquare);
+
+        assertTrue(isWithinAPixel(largeDim, redSquare.getWidth()));
+        assertTrue(isWithinAPixel(largeDim, redSquare.getHeight()));
+        assertTrue(isWithinAPixel(largeDim, greenSquare.getWidth()));
+        assertTrue(isWithinAPixel(largeDim, greenSquare.getHeight()));
+
+        assertNotNull(redSquare.getClipBounds());
+        assertNotNull(greenSquare.getClipBounds());
+    }
+
+    private void validateNormalIntermediate() {
+        validateIntermediatePosition();
+        Resources resources = mActivity.getResources();
+        float smallDim = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
+                SMALL_SQUARE_SIZE_DP, resources.getDisplayMetrics());
+        float largeDim = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
+                LARGE_SQUARE_SIZE_DP, resources.getDisplayMetrics());
+        View redSquare = mActivity.findViewById(R.id.redSquare);
+        View greenSquare = mActivity.findViewById(R.id.greenSquare);
+        assertFalse(isWithinAPixel(smallDim, redSquare.getWidth()));
+        assertFalse(isWithinAPixel(smallDim, redSquare.getHeight()));
+        assertFalse(isWithinAPixel(largeDim, redSquare.getWidth()));
+        assertFalse(isWithinAPixel(largeDim, redSquare.getHeight()));
+
+        assertFalse(isWithinAPixel(smallDim, greenSquare.getWidth()));
+        assertFalse(isWithinAPixel(smallDim, greenSquare.getHeight()));
+        assertFalse(isWithinAPixel(largeDim, greenSquare.getWidth()));
+        assertFalse(isWithinAPixel(largeDim, greenSquare.getHeight()));
+
+        assertNull(redSquare.getClipBounds());
+        assertNull(greenSquare.getClipBounds());
+    }
+
+    private static boolean isWithinAPixel(float expectedDim, int dim) {
+        return (Math.abs(dim - expectedDim) < 1);
+    }
+}
+
diff --git a/tests/tests/transition/src/android/transition/cts/ChangeClipBoundsTest.java b/tests/tests/transition/src/android/transition/cts/ChangeClipBoundsTest.java
new file mode 100644
index 0000000..9411d29
--- /dev/null
+++ b/tests/tests/transition/src/android/transition/cts/ChangeClipBoundsTest.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.transition.cts;
+
+import android.graphics.Rect;
+import android.transition.ChangeClipBounds;
+import android.transition.TransitionManager;
+import android.view.View;
+
+public class ChangeClipBoundsTest extends BaseTransitionTest {
+    private ChangeClipBounds mChangeClipBounds;
+
+    public ChangeClipBoundsTest() {
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mChangeClipBounds = new ChangeClipBounds();
+        mTransition = mChangeClipBounds;
+        resetListener();
+    }
+
+    public void testChangeClipBounds() throws Throwable {
+        enterScene(R.layout.scene1);
+
+        final View redSquare = mActivity.findViewById(R.id.redSquare);
+        final Rect newClip = new Rect(redSquare.getLeft() + 10, redSquare.getTop() + 10,
+                redSquare.getRight() - 10, redSquare.getBottom() - 10);
+
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                assertNull(redSquare.getClipBounds());
+                TransitionManager.beginDelayedTransition(mSceneRoot, mChangeClipBounds);
+                redSquare.setClipBounds(newClip);
+            }
+        });
+        waitForStart();
+        Thread.sleep(150);
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                Rect midClip = redSquare.getClipBounds();
+                assertNotNull(midClip);
+                assertTrue(midClip.left > 0 && midClip.left < newClip.left);
+                assertTrue(midClip.top > 0 && midClip.top < newClip.top);
+                assertTrue(midClip.right < redSquare.getRight() && midClip.right > newClip.right);
+                assertTrue(midClip.bottom < redSquare.getBottom() &&
+                        midClip.bottom > newClip.bottom);
+            }
+        });
+        waitForEnd(400);
+
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                final Rect endRect = redSquare.getClipBounds();
+                assertNotNull(endRect);
+                assertEquals(newClip, endRect);
+            }
+        });
+
+        resetListener();
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                TransitionManager.beginDelayedTransition(mSceneRoot, mChangeClipBounds);
+                redSquare.setClipBounds(null);
+            }
+        });
+        waitForStart();
+        Thread.sleep(150);
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                Rect midClip = redSquare.getClipBounds();
+                assertNotNull(midClip);
+                assertTrue(midClip.left > 0 && midClip.left < newClip.left);
+                assertTrue(midClip.top > 0 && midClip.top < newClip.top);
+                assertTrue(midClip.right < redSquare.getRight() && midClip.right > newClip.right);
+                assertTrue(midClip.bottom < redSquare.getBottom() &&
+                        midClip.bottom > newClip.bottom);
+            }
+        });
+        waitForEnd(400);
+
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                assertNotNull(redSquare.getClipBounds());
+            }
+        });
+    }
+}
+
diff --git a/tests/tests/transition/src/android/transition/cts/ChangeImageTransformTest.java b/tests/tests/transition/src/android/transition/cts/ChangeImageTransformTest.java
new file mode 100644
index 0000000..a26e850
--- /dev/null
+++ b/tests/tests/transition/src/android/transition/cts/ChangeImageTransformTest.java
@@ -0,0 +1,286 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.transition.cts;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.graphics.Matrix;
+import android.graphics.drawable.Drawable;
+import android.transition.ChangeImageTransform;
+import android.transition.TransitionManager;
+import android.transition.TransitionValues;
+import android.util.DisplayMetrics;
+import android.util.TypedValue;
+import android.view.ViewGroup;
+import android.view.ViewGroup.LayoutParams;
+import android.widget.ImageView;
+import android.widget.ImageView.ScaleType;
+
+public class ChangeImageTransformTest extends BaseTransitionTest {
+    ChangeImageTransform mChangeImageTransform;
+    Matrix mStartMatrix;
+    Matrix mEndMatrix;
+    Drawable mImage;
+    ImageView mImageView;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        resetTransition();
+        mStartMatrix = null;
+        mEndMatrix = null;
+        mImage = null;
+        mImageView = null;
+    }
+
+    private void resetTransition() {
+        mChangeImageTransform = new CaptureMatrix();
+        mChangeImageTransform.setDuration(100);
+        mTransition = mChangeImageTransform;
+        resetListener();
+    }
+
+    public void testCenterToFitXY() throws Throwable {
+        transformImage(ScaleType.CENTER, ScaleType.FIT_XY);
+        assertMatrixMatches(centerMatrix(), mStartMatrix);
+        assertMatrixMatches(fitXYMatrix(), mEndMatrix);
+    }
+
+    public void testCenterCropToFitCenter() throws Throwable {
+        transformImage(ScaleType.CENTER_CROP, ScaleType.FIT_CENTER);
+        assertMatrixMatches(centerCropMatrix(), mStartMatrix);
+        assertMatrixMatches(fitCenterMatrix(), mEndMatrix);
+    }
+
+    public void testCenterInsideToFitEnd() throws Throwable {
+        transformImage(ScaleType.CENTER_INSIDE, ScaleType.FIT_END);
+        // CENTER_INSIDE and CENTER are the same when the image is smaller than the View
+        assertMatrixMatches(centerMatrix(), mStartMatrix);
+        assertMatrixMatches(fitEndMatrix(), mEndMatrix);
+    }
+
+    public void testFitStartToCenter() throws Throwable {
+        transformImage(ScaleType.FIT_START, ScaleType.CENTER);
+        assertMatrixMatches(fitStartMatrix(), mStartMatrix);
+        assertMatrixMatches(centerMatrix(), mEndMatrix);
+    }
+
+    private Matrix centerMatrix() {
+        int imageWidth = mImage.getIntrinsicWidth();
+        int imageViewWidth = mImageView.getWidth();
+        float tx = Math.round((imageViewWidth - imageWidth)/2f);
+
+        int imageHeight = mImage.getIntrinsicHeight();
+        int imageViewHeight = mImageView.getHeight();
+        float ty = Math.round((imageViewHeight - imageHeight)/2f);
+
+        Matrix matrix = new Matrix();
+        matrix.postTranslate(tx, ty);
+        return matrix;
+    }
+
+    private Matrix fitXYMatrix() {
+        int imageWidth = mImage.getIntrinsicWidth();
+        int imageViewWidth = mImageView.getWidth();
+        float scaleX = ((float)imageViewWidth)/imageWidth;
+
+        int imageHeight = mImage.getIntrinsicHeight();
+        int imageViewHeight = mImageView.getHeight();
+        float scaleY = ((float)imageViewHeight)/imageHeight;
+
+        Matrix matrix = new Matrix();
+        matrix.postScale(scaleX, scaleY);
+        return matrix;
+    }
+
+    private Matrix centerCropMatrix() {
+        int imageWidth = mImage.getIntrinsicWidth();
+        int imageViewWidth = mImageView.getWidth();
+        float scaleX = ((float)imageViewWidth)/imageWidth;
+
+        int imageHeight = mImage.getIntrinsicHeight();
+        int imageViewHeight = mImageView.getHeight();
+        float scaleY = ((float)imageViewHeight)/imageHeight;
+
+        float maxScale = Math.max(scaleX, scaleY);
+
+        float width = imageWidth * maxScale;
+        float height = imageHeight * maxScale;
+        float tx = Math.round((imageViewWidth - width) / 2f);
+        float ty = Math.round((imageViewHeight - height) / 2f);
+
+        Matrix matrix = new Matrix();
+        matrix.postScale(maxScale, maxScale);
+        matrix.postTranslate(tx, ty);
+        return matrix;
+    }
+
+    private Matrix fitCenterMatrix() {
+        int imageWidth = mImage.getIntrinsicWidth();
+        int imageViewWidth = mImageView.getWidth();
+        float scaleX = ((float)imageViewWidth)/imageWidth;
+
+        int imageHeight = mImage.getIntrinsicHeight();
+        int imageViewHeight = mImageView.getHeight();
+        float scaleY = ((float)imageViewHeight)/imageHeight;
+
+        float minScale = Math.min(scaleX, scaleY);
+
+        float width = imageWidth * minScale;
+        float height = imageHeight * minScale;
+        float tx = (imageViewWidth - width) / 2f;
+        float ty = (imageViewHeight - height) / 2f;
+
+        Matrix matrix = new Matrix();
+        matrix.postScale(minScale, minScale);
+        matrix.postTranslate(tx, ty);
+        return matrix;
+    }
+
+    private Matrix fitStartMatrix() {
+        int imageWidth = mImage.getIntrinsicWidth();
+        int imageViewWidth = mImageView.getWidth();
+        float scaleX = ((float)imageViewWidth)/imageWidth;
+
+        int imageHeight = mImage.getIntrinsicHeight();
+        int imageViewHeight = mImageView.getHeight();
+        float scaleY = ((float)imageViewHeight)/imageHeight;
+
+        float minScale = Math.min(scaleX, scaleY);
+
+        Matrix matrix = new Matrix();
+        matrix.postScale(minScale, minScale);
+        return matrix;
+    }
+
+    private Matrix fitEndMatrix() {
+        int imageWidth = mImage.getIntrinsicWidth();
+        int imageViewWidth = mImageView.getWidth();
+        float scaleX = ((float)imageViewWidth)/imageWidth;
+
+        int imageHeight = mImage.getIntrinsicHeight();
+        int imageViewHeight = mImageView.getHeight();
+        float scaleY = ((float)imageViewHeight)/imageHeight;
+
+        float minScale = Math.min(scaleX, scaleY);
+
+        float width = imageWidth * minScale;
+        float height = imageHeight * minScale;
+        float tx = imageViewWidth - width;
+        float ty = imageViewHeight - height;
+
+        Matrix matrix = new Matrix();
+        matrix.postScale(minScale, minScale);
+        matrix.postTranslate(tx, ty);
+        return matrix;
+    }
+
+    private void assertMatrixMatches(Matrix expected, Matrix matrix) {
+        if (expected == null) {
+            assertNull(matrix);
+            return;
+        }
+        assertNotNull(matrix);
+        float[] expectedValues = new float[9];
+        expected.getValues(expectedValues);
+
+        float[] values = new float[9];
+        matrix.getValues(values);
+
+        for (int i = 0; i < values.length; i++) {
+            final float expectedValue = expectedValues[i];
+            final float value = values[i];
+            assertEquals("Value [" + i + "]", expectedValue, value, 0.01f);
+        }
+    }
+
+    private void transformImage(ScaleType startScale, final ScaleType endScale) throws Throwable {
+        final ImageView imageView = enterImageViewScene(startScale);
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                TransitionManager.beginDelayedTransition(mSceneRoot, mChangeImageTransform);
+                imageView.setScaleType(endScale);
+            }
+        });
+        waitForStart();
+        int expectedEndCount = (startScale == endScale) ? 0 : 1;
+        assertEquals(expectedEndCount, mListener.endLatch.getCount());
+        waitForEnd(200);
+    }
+
+    private ImageView enterImageViewScene(final ScaleType scaleType) throws Throwable {
+        enterScene(R.layout.scene4);
+        final ViewGroup container = (ViewGroup) mActivity.findViewById(R.id.holder);
+        final ImageView[] imageViews = new ImageView[1];
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mImageView = new ImageView(mActivity);
+                mImage = mActivity.getDrawable(android.R.drawable.ic_media_play);
+                mImageView.setImageDrawable(mImage);
+                mImageView.setScaleType(scaleType);
+                imageViews[0] = mImageView;
+                container.addView(mImageView);
+                LayoutParams layoutParams = mImageView.getLayoutParams();
+                DisplayMetrics metrics = mActivity.getResources().getDisplayMetrics();
+                float size = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 50, metrics);
+                layoutParams.width = Math.round(size);
+                layoutParams.height = Math.round(size * 2);
+                mImageView.setLayoutParams(layoutParams);
+            }
+        });
+        getInstrumentation().waitForIdleSync();
+        return imageViews[0];
+    }
+
+    private class CaptureMatrix extends ChangeImageTransform {
+        @Override
+        public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues,
+                TransitionValues endValues) {
+            Animator animator = super.createAnimator(sceneRoot, startValues, endValues);
+            animator.addListener(new CaptureMatrixListener((ImageView) endValues.view));
+            return animator;
+        }
+    }
+
+    private class CaptureMatrixListener extends AnimatorListenerAdapter {
+        private final ImageView mImageView;
+
+        public CaptureMatrixListener(ImageView view) {
+            mImageView = view;
+        }
+
+        @Override
+        public void onAnimationStart(Animator animation) {
+            mStartMatrix = copyMatrix();
+        }
+
+        @Override
+        public void onAnimationEnd(Animator animation) {
+            mEndMatrix = copyMatrix();
+        }
+
+        private Matrix copyMatrix() {
+            Matrix matrix = mImageView.getImageMatrix();
+            if (matrix != null) {
+                matrix = new Matrix(matrix);
+            }
+            return matrix;
+        }
+    }
+}
+
diff --git a/tests/tests/transition/src/android/transition/cts/ChangeScrollTest.java b/tests/tests/transition/src/android/transition/cts/ChangeScrollTest.java
index f5f076d..2dee364 100644
--- a/tests/tests/transition/src/android/transition/cts/ChangeScrollTest.java
+++ b/tests/tests/transition/src/android/transition/cts/ChangeScrollTest.java
@@ -15,38 +15,38 @@
  */
 package android.transition.cts;
 
-import com.android.cts.transition.R;
-
 import android.transition.ChangeScroll;
-import android.transition.Transition;
 import android.transition.TransitionManager;
 import android.view.View;
 
 public class ChangeScrollTest extends BaseTransitionTest {
+    ChangeScroll mChangeScroll;
 
     public ChangeScrollTest() {
     }
 
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mChangeScroll = new ChangeScroll();
+        mTransition = mChangeScroll;
+        resetListener();
+    }
+
     public void testChangeScroll() throws Throwable {
         enterScene(R.layout.scene5);
-        final Transition transition = new ChangeScroll();
-        transition.setDuration(100);
-        SimpleTransitionListener listener = new SimpleTransitionListener();
-        transition.addListener(listener);
         runTestOnUiThread(new Runnable() {
             @Override
             public void run() {
                 final View view = mActivity.findViewById(R.id.text);
-                final int scrollX = view.getScrollX();
-                final int scrollY = view.getScrollY();
-                assertEquals(0, scrollX);
-                assertEquals(0, scrollY);
-                TransitionManager.beginDelayedTransition(mSceneRoot, transition);
+                assertEquals(0, view.getScrollX());
+                assertEquals(0, view.getScrollY());
+                TransitionManager.beginDelayedTransition(mSceneRoot, mChangeScroll);
                 view.scrollTo(150, 300);
             }
         });
-        waitForStart(listener);
-        waitForAnimationFrame();
+        waitForStart();
+        Thread.sleep(150);
         runTestOnUiThread(new Runnable() {
             @Override
             public void run() {
@@ -59,15 +59,13 @@
                 assertTrue(scrollY < 300);
             }
         });
-        waitForEnd(listener, 100);
+        waitForEnd(400);
         runTestOnUiThread(new Runnable() {
             @Override
             public void run() {
                 final View view = mActivity.findViewById(R.id.text);
-                final int scrollX = view.getScrollX();
-                final int scrollY = view.getScrollY();
-                assertEquals(150, scrollX);
-                assertEquals(300, scrollY);
+                assertEquals(150, view.getScrollX());
+                assertEquals(300, view.getScrollY());
             }
         });
     }
diff --git a/tests/tests/transition/src/android/transition/cts/ChangeTransformTest.java b/tests/tests/transition/src/android/transition/cts/ChangeTransformTest.java
new file mode 100644
index 0000000..78a5d82
--- /dev/null
+++ b/tests/tests/transition/src/android/transition/cts/ChangeTransformTest.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.transition.cts;
+
+import android.transition.ChangeTransform;
+import android.transition.TransitionManager;
+import android.view.View;
+import android.view.ViewGroup;
+
+public class ChangeTransformTest extends BaseTransitionTest {
+    ChangeTransform mChangeTransform;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        resetChangeBoundsTransition();
+    }
+
+    private void resetChangeBoundsTransition() {
+        mChangeTransform = new ChangeTransform();
+        mTransition = mChangeTransform;
+        resetListener();
+    }
+
+    public void testTranslation() throws Throwable {
+        enterScene(R.layout.scene1);
+
+        final View redSquare = mActivity.findViewById(R.id.redSquare);
+
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                TransitionManager.beginDelayedTransition(mSceneRoot, mChangeTransform);
+                redSquare.setTranslationX(500);
+                redSquare.setTranslationY(600);
+            }
+        });
+        waitForStart();
+
+        assertEquals(1, mListener.endLatch.getCount()); // still running
+        // There is no way to validate the intermediate matrix because it uses
+        // hidden properties of the View to execute.
+        waitForEnd(400);
+        assertEquals(500f, redSquare.getTranslationX());
+        assertEquals(600f, redSquare.getTranslationY());
+    }
+
+    public void testRotation() throws Throwable {
+        enterScene(R.layout.scene1);
+
+        final View redSquare = mActivity.findViewById(R.id.redSquare);
+
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                TransitionManager.beginDelayedTransition(mSceneRoot, mChangeTransform);
+                redSquare.setRotation(45);
+            }
+        });
+        waitForStart();
+
+        assertEquals(1, mListener.endLatch.getCount()); // still running
+        // There is no way to validate the intermediate matrix because it uses
+        // hidden properties of the View to execute.
+        waitForEnd(400);
+        assertEquals(45f, redSquare.getRotation());
+    }
+
+    public void testScale() throws Throwable {
+        enterScene(R.layout.scene1);
+
+        final View redSquare = mActivity.findViewById(R.id.redSquare);
+
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                TransitionManager.beginDelayedTransition(mSceneRoot, mChangeTransform);
+                redSquare.setScaleX(2f);
+                redSquare.setScaleY(3f);
+            }
+        });
+        waitForStart();
+
+        assertEquals(1, mListener.endLatch.getCount()); // still running
+        // There is no way to validate the intermediate matrix because it uses
+        // hidden properties of the View to execute.
+        waitForEnd(400);
+        assertEquals(2f, redSquare.getScaleX());
+        assertEquals(3f, redSquare.getScaleY());
+    }
+
+    public void testReparent() throws Throwable {
+        assertEquals(true, mChangeTransform.getReparent());
+        enterScene(R.layout.scene5);
+        startTransition(R.layout.scene9);
+        assertEquals(1, mListener.endLatch.getCount()); // still running
+        waitForEnd(400);
+
+        resetListener();
+        mChangeTransform.setReparent(false);
+        assertEquals(false, mChangeTransform.getReparent());
+        startTransition(R.layout.scene5);
+        waitForEnd(0); // no transition to run because reparent == false
+    }
+
+    public void testReparentWithOverlay() throws Throwable {
+        assertEquals(true, mChangeTransform.getReparentWithOverlay());
+        enterScene(R.layout.scene5);
+        startTransition(R.layout.scene9);
+        assertEquals(1, mListener.endLatch.getCount()); // still running
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                View view = new View(mActivity);
+                view.setRight(100);
+                view.setBottom(100);
+                mSceneRoot.getOverlay().add(view);
+                ViewGroup container = (ViewGroup) view.getParent();
+                assertEquals(2, container.getChildCount());
+                mSceneRoot.getOverlay().remove(view);
+                assertTrue(mActivity.findViewById(R.id.text).getVisibility() != View.VISIBLE);
+            }
+        });
+        waitForEnd(400);
+
+        mChangeTransform.setReparentWithOverlay(false);
+        assertEquals(false, mChangeTransform.getReparentWithOverlay());
+        resetListener();
+        startTransition(R.layout.scene5);
+        assertEquals(1, mListener.endLatch.getCount()); // still running
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                View view = new View(mActivity);
+                view.setRight(100);
+                view.setBottom(100);
+                mSceneRoot.getOverlay().add(view);
+                ViewGroup container = (ViewGroup) view.getParent();
+                assertEquals(1, container.getChildCount());
+                mSceneRoot.getOverlay().remove(view);
+                assertEquals(View.VISIBLE, mActivity.findViewById(R.id.text).getVisibility());
+            }
+        });
+        waitForEnd(400);
+    }
+}
+
diff --git a/tests/tests/transition/src/android/transition/cts/ExplodeTest.java b/tests/tests/transition/src/android/transition/cts/ExplodeTest.java
new file mode 100644
index 0000000..e9e2264
--- /dev/null
+++ b/tests/tests/transition/src/android/transition/cts/ExplodeTest.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.transition.cts;
+
+import android.transition.Explode;
+import android.transition.TransitionManager;
+import android.view.View;
+import android.widget.RelativeLayout;
+import android.widget.RelativeLayout.LayoutParams;
+
+public class ExplodeTest extends BaseTransitionTest {
+    Explode mExplode;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        resetTransition();
+    }
+
+    private void resetTransition() {
+        mExplode = new Explode();
+        mTransition = mExplode;
+        resetListener();
+    }
+
+    public void testExplode() throws Throwable {
+        enterScene(R.layout.scene10);
+        final View redSquare = mActivity.findViewById(R.id.redSquare);
+        final View greenSquare = mActivity.findViewById(R.id.greenSquare);
+        final View blueSquare = mActivity.findViewById(R.id.blueSquare);
+        final View yellowSquare = mActivity.findViewById(R.id.yellowSquare);
+
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                TransitionManager.beginDelayedTransition(mSceneRoot, mTransition);
+                redSquare.setVisibility(View.INVISIBLE);
+                greenSquare.setVisibility(View.INVISIBLE);
+                blueSquare.setVisibility(View.INVISIBLE);
+                yellowSquare.setVisibility(View.INVISIBLE);
+            }
+        });
+        waitForStart();
+        assertEquals(1, mListener.endLatch.getCount());
+        assertEquals(View.VISIBLE, redSquare.getVisibility());
+        assertEquals(View.VISIBLE, greenSquare.getVisibility());
+        assertEquals(View.VISIBLE, blueSquare.getVisibility());
+        assertEquals(View.VISIBLE, yellowSquare.getVisibility());
+        float redStartX = redSquare.getTranslationX();
+        float redStartY = redSquare.getTranslationY();
+
+        Thread.sleep(100);
+        assertTranslation(redSquare, true, true);
+        assertTranslation(greenSquare, false, true);
+        assertTranslation(blueSquare, false, false);
+        assertTranslation(yellowSquare, true, false);
+        assertTrue(redStartX > redSquare.getTranslationX()); // moving left
+        assertTrue(redStartY > redSquare.getTranslationY()); // moving up
+        waitForEnd(400);
+
+        assertNoTranslation(redSquare);
+        assertNoTranslation(greenSquare);
+        assertNoTranslation(blueSquare);
+        assertNoTranslation(yellowSquare);
+        assertEquals(View.INVISIBLE, redSquare.getVisibility());
+        assertEquals(View.INVISIBLE, greenSquare.getVisibility());
+        assertEquals(View.INVISIBLE, blueSquare.getVisibility());
+        assertEquals(View.INVISIBLE, yellowSquare.getVisibility());
+    }
+
+    public void testImplode() throws Throwable {
+        enterScene(R.layout.scene10);
+        final View redSquare = mActivity.findViewById(R.id.redSquare);
+        final View greenSquare = mActivity.findViewById(R.id.greenSquare);
+        final View blueSquare = mActivity.findViewById(R.id.blueSquare);
+        final View yellowSquare = mActivity.findViewById(R.id.yellowSquare);
+
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                redSquare.setVisibility(View.INVISIBLE);
+                greenSquare.setVisibility(View.INVISIBLE);
+                blueSquare.setVisibility(View.INVISIBLE);
+                yellowSquare.setVisibility(View.INVISIBLE);
+            }
+        });
+        getInstrumentation().waitForIdleSync();
+
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                TransitionManager.beginDelayedTransition(mSceneRoot, mTransition);
+                redSquare.setVisibility(View.VISIBLE);
+                greenSquare.setVisibility(View.VISIBLE);
+                blueSquare.setVisibility(View.VISIBLE);
+                yellowSquare.setVisibility(View.VISIBLE);
+            }
+        });
+        waitForStart();
+
+        assertEquals(View.VISIBLE, redSquare.getVisibility());
+        assertEquals(View.VISIBLE, greenSquare.getVisibility());
+        assertEquals(View.VISIBLE, blueSquare.getVisibility());
+        assertEquals(View.VISIBLE, yellowSquare.getVisibility());
+        float redStartX = redSquare.getTranslationX();
+        float redStartY = redSquare.getTranslationY();
+
+        Thread.sleep(100);
+        assertTranslation(redSquare, true, true);
+        assertTranslation(greenSquare, false, true);
+        assertTranslation(blueSquare, false, false);
+        assertTranslation(yellowSquare, true, false);
+        assertTrue(redStartX < redSquare.getTranslationX()); // moving right
+        assertTrue(redStartY < redSquare.getTranslationY()); // moving down
+        waitForEnd(400);
+
+        assertNoTranslation(redSquare);
+        assertNoTranslation(greenSquare);
+        assertNoTranslation(blueSquare);
+        assertNoTranslation(yellowSquare);
+        assertEquals(View.VISIBLE, redSquare.getVisibility());
+        assertEquals(View.VISIBLE, greenSquare.getVisibility());
+        assertEquals(View.VISIBLE, blueSquare.getVisibility());
+        assertEquals(View.VISIBLE, yellowSquare.getVisibility());
+    }
+
+    private void assertTranslation(View view, boolean goLeft, boolean goUp) {
+        float translationX = view.getTranslationX();
+        float translationY = view.getTranslationY();
+
+        if (goLeft) {
+            assertTrue(translationX < 0);
+        } else {
+            assertTrue(translationX > 0);
+        }
+
+        if (goUp) {
+            assertTrue(translationY < 0);
+        } else {
+            assertTrue(translationY > 0);
+        }
+    }
+
+    private void assertNoTranslation(View view) {
+        assertEquals(0f, view.getTranslationX());
+        assertEquals(0f, view.getTranslationY());
+    }
+}
+
diff --git a/tests/tests/transition/src/android/transition/cts/FadeTest.java b/tests/tests/transition/src/android/transition/cts/FadeTest.java
new file mode 100644
index 0000000..a6a1b2f
--- /dev/null
+++ b/tests/tests/transition/src/android/transition/cts/FadeTest.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.transition.cts;
+
+import android.transition.Fade;
+
+/**
+ * This tests the public API for Fade. The alpha cannot be easily tested as part of CTS,
+ * so those are implementation tests.
+ */
+public class FadeTest extends BaseTransitionTest {
+    Fade mFade;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        resetTransition();
+    }
+
+    private void resetTransition() {
+        mFade = new Fade();
+        mFade.setDuration(200);
+        mTransition = mFade;
+        resetListener();
+    }
+
+    public void testMode() throws Throwable {
+        // Should animate in and out by default
+        enterScene(R.layout.scene4);
+        startTransition(R.layout.scene1);
+        assertEquals(1, mListener.endLatch.getCount());
+        waitForEnd(400);
+
+        resetListener();
+        startTransition(R.layout.scene4);
+        assertEquals(1, mListener.endLatch.getCount());
+        waitForEnd(400);
+
+        // Now only animate in
+        mFade = new Fade(Fade.IN);
+        mTransition = mFade;
+        resetListener();
+        startTransition(R.layout.scene1);
+        assertEquals(1, mListener.endLatch.getCount());
+        waitForEnd(400);
+
+        // No animation since it should only animate in
+        resetListener();
+        startTransition(R.layout.scene4);
+        waitForEnd(0);
+
+        // Now animate out, but no animation should happen since we're animating in.
+        mFade = new Fade(Fade.OUT);
+        mTransition = mFade;
+        resetListener();
+        startTransition(R.layout.scene1);
+        waitForEnd(0);
+
+        // but it should animate out
+        resetListener();
+        startTransition(R.layout.scene4);
+        assertEquals(1, mListener.endLatch.getCount());
+        waitForEnd(400);
+    }
+}
+
diff --git a/tests/tests/transition/src/android/transition/cts/PathMotionTest.java b/tests/tests/transition/src/android/transition/cts/PathMotionTest.java
new file mode 100644
index 0000000..97bf274
--- /dev/null
+++ b/tests/tests/transition/src/android/transition/cts/PathMotionTest.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.transition.cts;
+
+import android.graphics.Path;
+import android.graphics.PathMeasure;
+
+import junit.framework.TestCase;
+
+public class PathMotionTest extends TestCase {
+    public static void assertPathMatches(Path expectedPath, Path path) {
+        PathMeasure expectedMeasure = new PathMeasure(expectedPath, false);
+        PathMeasure pathMeasure = new PathMeasure(path, false);
+
+        float expectedLength = expectedMeasure.getLength();
+        assertEquals(expectedLength, pathMeasure.getLength(), 0.01f);
+
+        float minLength = Math.min(expectedLength, pathMeasure.getLength());
+
+        float pos[] = new float[2];
+
+        float increment = minLength / 5f;
+        for (float along = 0; along <= minLength; along += increment) {
+            expectedMeasure.getPosTan(along, pos, null);
+            float expectedX = pos[0];
+            float expectedY = pos[1];
+
+            pathMeasure.getPosTan(along, pos, null);
+            assertEquals(expectedX, pos[0], 0.01f);
+            assertEquals(expectedY, pos[1], 0.01f);
+        }
+    }
+}
diff --git a/tests/tests/transition/src/android/transition/cts/PatternPathMotionTest.java b/tests/tests/transition/src/android/transition/cts/PatternPathMotionTest.java
new file mode 100644
index 0000000..5485b4a
--- /dev/null
+++ b/tests/tests/transition/src/android/transition/cts/PatternPathMotionTest.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.transition.cts;
+
+import android.graphics.Path;
+import android.transition.PatternPathMotion;
+
+public class PatternPathMotionTest extends PathMotionTest {
+
+    public void testStraightPath() throws Throwable {
+        Path pattern = new Path();
+        pattern.moveTo(100, 500);
+        pattern.lineTo(300, 1000);
+
+        PatternPathMotion pathMotion = new PatternPathMotion(pattern);
+        assertPathMatches(pattern, pathMotion.getPatternPath());
+
+        Path expected = new Path();
+        expected.moveTo(0, 0);
+        expected.lineTo(100, 100);
+
+        assertPathMatches(expected, pathMotion.getPath(0, 0, 100, 100));
+    }
+
+    public void testCurve() throws Throwable {
+        Path pattern = new Path();
+        pattern.addArc(0, 0, 100, 100, 0, 180);
+
+        PatternPathMotion pathMotion = new PatternPathMotion(pattern);
+        assertPathMatches(pattern, pathMotion.getPatternPath());
+
+        Path expected = new Path();
+        expected.addArc(-50, 0, 50, 100, -90, 180);
+
+        assertPathMatches(expected, pathMotion.getPath(0, 0, 0, 100));
+    }
+}
+
diff --git a/tests/tests/transition/src/android/transition/cts/SceneTest.java b/tests/tests/transition/src/android/transition/cts/SceneTest.java
new file mode 100644
index 0000000..2785714
--- /dev/null
+++ b/tests/tests/transition/src/android/transition/cts/SceneTest.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.transition.cts;
+
+import android.transition.Scene;
+import android.view.View;
+
+public class SceneTest extends BaseTransitionTest {
+
+    public SceneTest() {
+    }
+
+    public void testDynamicConstructor() throws Throwable {
+        Scene scene = new Scene(mSceneRoot);
+        assertEquals(mSceneRoot, scene.getSceneRoot());
+        CallCheck enterCheck = new CallCheck() {
+            @Override
+            public void run() {
+                super.run();
+                mActivity.getLayoutInflater().inflate(R.layout.scene1, mSceneRoot, true);
+            }
+        };
+        scene.setEnterAction(enterCheck);
+        CallCheck exitCheck = new CallCheck();
+        scene.setExitAction(exitCheck);
+        enterScene(scene);
+
+        assertTrue(enterCheck.wasRun);
+        assertFalse(exitCheck.wasRun);
+
+        View redSquare = mActivity.findViewById(R.id.redSquare);
+        assertNotNull(redSquare);
+
+        exitScene(scene);
+        assertNotNull(mSceneRoot.findViewById(R.id.redSquare));
+        assertTrue(exitCheck.wasRun);
+
+        enterScene(R.layout.scene4);
+        assertNull(mSceneRoot.findViewById(R.id.redSquare));
+    }
+
+    public void testViewConstructor() throws Throwable {
+        View view = loadLayout(R.layout.scene1);
+        Scene scene = new Scene(mSceneRoot, view);
+        assertEquals(mSceneRoot, scene.getSceneRoot());
+        CallCheck enterCheck = new CallCheck();
+        scene.setEnterAction(enterCheck);
+        CallCheck exitCheck = new CallCheck();
+        scene.setExitAction(exitCheck);
+        enterScene(scene);
+
+        assertTrue(enterCheck.wasRun);
+        assertFalse(exitCheck.wasRun);
+
+        View redSquare = mActivity.findViewById(R.id.redSquare);
+        assertNotNull(redSquare);
+
+        exitScene(scene);
+        assertNotNull(mSceneRoot.findViewById(R.id.redSquare));
+        assertTrue(exitCheck.wasRun);
+
+        enterScene(R.layout.scene4);
+        assertNull(mSceneRoot.findViewById(R.id.redSquare));
+    }
+
+    public void testFactory() throws Throwable {
+        Scene scene = loadScene(R.layout.scene1);
+        assertEquals(mSceneRoot, scene.getSceneRoot());
+        CallCheck enterCheck = new CallCheck();
+        scene.setEnterAction(enterCheck);
+        CallCheck exitCheck = new CallCheck();
+        scene.setExitAction(exitCheck);
+        enterScene(scene);
+
+        assertTrue(enterCheck.wasRun);
+        assertFalse(exitCheck.wasRun);
+
+        View redSquare = mActivity.findViewById(R.id.redSquare);
+        assertNotNull(redSquare);
+
+        exitScene(scene);
+        assertNotNull(mSceneRoot.findViewById(R.id.redSquare));
+        assertTrue(exitCheck.wasRun);
+        enterScene(R.layout.scene4);
+        assertNull(mSceneRoot.findViewById(R.id.redSquare));
+    }
+
+    private static class CallCheck implements Runnable {
+        public boolean wasRun;
+
+        @Override
+        public void run() {
+            wasRun = true;
+        }
+    }
+}
+
diff --git a/tests/tests/transition/src/android/transition/cts/SimpleTransitionListener.java b/tests/tests/transition/src/android/transition/cts/SimpleTransitionListener.java
index 113f5a5..fb8596a 100644
--- a/tests/tests/transition/src/android/transition/cts/SimpleTransitionListener.java
+++ b/tests/tests/transition/src/android/transition/cts/SimpleTransitionListener.java
@@ -18,50 +18,43 @@
 import android.transition.Transition;
 import android.transition.Transition.TransitionListener;
 
+import java.util.concurrent.CountDownLatch;
+
 /**
  * Listener captures whether each of the methods is called.
  */
 class SimpleTransitionListener implements TransitionListener {
     public Transition transition;
 
-    public boolean started;
-
-    public boolean ended;
-
-    public boolean canceled;
-
-    public boolean paused;
-
-    public boolean resumed;
+    public CountDownLatch startLatch = new CountDownLatch(1);
+    public CountDownLatch endLatch = new CountDownLatch(1);
+    public CountDownLatch cancelLatch = new CountDownLatch(1);
+    public CountDownLatch pauseLatch = new CountDownLatch(1);
+    public CountDownLatch resumeLatch = new CountDownLatch(1);
 
     @Override
-    public synchronized void onTransitionStart(Transition transition) {
-        started = true;
+    public void onTransitionStart(Transition transition) {
         this.transition = transition;
-        notifyAll();
+        startLatch.countDown();
     }
 
     @Override
-    public synchronized void onTransitionEnd(Transition transition) {
-        ended = true;
-        notifyAll();
+    public void onTransitionEnd(Transition transition) {
+        endLatch.countDown();
     }
 
     @Override
-    public synchronized void onTransitionCancel(Transition transition) {
-        canceled = true;
-        notifyAll();
+    public void onTransitionCancel(Transition transition) {
+        cancelLatch.countDown();
     }
 
     @Override
-    public synchronized void onTransitionPause(Transition transition) {
-        paused = true;
-        notifyAll();
+    public void onTransitionPause(Transition transition) {
+        pauseLatch.countDown();
     }
 
     @Override
-    public synchronized void onTransitionResume(Transition transition) {
-        resumed = true;
-        notifyAll();
+    public void onTransitionResume(Transition transition) {
+        resumeLatch.countDown();
     }
 }
diff --git a/tests/tests/transition/src/android/transition/cts/SlideBadEdgeTest.java b/tests/tests/transition/src/android/transition/cts/SlideBadEdgeTest.java
new file mode 100644
index 0000000..fefa353
--- /dev/null
+++ b/tests/tests/transition/src/android/transition/cts/SlideBadEdgeTest.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.transition.cts;
+
+import android.test.suitebuilder.annotation.SmallTest;
+import android.transition.Slide;
+import android.view.Gravity;
+
+import junit.framework.TestCase;
+
+import org.junit.Test;
+
+public class SlideBadEdgeTest extends TestCase {
+
+    private static final Object[][] sBadGravity = {
+            { Gravity.AXIS_CLIP, "AXIS_CLIP" },
+            { Gravity.AXIS_PULL_AFTER, "AXIS_PULL_AFTER" },
+            { Gravity.AXIS_PULL_BEFORE, "AXIS_PULL_BEFORE" },
+            { Gravity.AXIS_SPECIFIED, "AXIS_SPECIFIED" },
+            { Gravity.AXIS_Y_SHIFT, "AXIS_Y_SHIFT" },
+            { Gravity.AXIS_X_SHIFT, "AXIS_X_SHIFT" },
+            { Gravity.CENTER, "CENTER" },
+            { Gravity.CLIP_VERTICAL, "CLIP_VERTICAL" },
+            { Gravity.CLIP_HORIZONTAL, "CLIP_HORIZONTAL" },
+            { Gravity.CENTER_VERTICAL, "CENTER_VERTICAL" },
+            { Gravity.CENTER_HORIZONTAL, "CENTER_HORIZONTAL" },
+            { Gravity.DISPLAY_CLIP_VERTICAL, "DISPLAY_CLIP_VERTICAL" },
+            { Gravity.DISPLAY_CLIP_HORIZONTAL, "DISPLAY_CLIP_HORIZONTAL" },
+            { Gravity.FILL_VERTICAL, "FILL_VERTICAL" },
+            { Gravity.FILL, "FILL" },
+            { Gravity.FILL_HORIZONTAL, "FILL_HORIZONTAL" },
+            { Gravity.HORIZONTAL_GRAVITY_MASK, "HORIZONTAL_GRAVITY_MASK" },
+            { Gravity.NO_GRAVITY, "NO_GRAVITY" },
+            { Gravity.RELATIVE_LAYOUT_DIRECTION, "RELATIVE_LAYOUT_DIRECTION" },
+            { Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK, "RELATIVE_HORIZONTAL_GRAVITY_MASK" },
+            { Gravity.VERTICAL_GRAVITY_MASK, "VERTICAL_GRAVITY_MASK" },
+    };
+
+    @SmallTest
+    public void testBadSide() {
+        for (int i = 0; i < sBadGravity.length; i++) {
+            int badEdge = (Integer) sBadGravity[i][0];
+            String edgeName = (String) sBadGravity[i][1];
+            try {
+                Slide slide = new Slide(badEdge);
+                fail("Should not be able to set slide edge to " + edgeName);
+            } catch (IllegalArgumentException e) {
+                // expected
+            }
+
+            try {
+                Slide slide = new Slide();
+                slide.setSlideEdge(badEdge);
+                fail("Should not be able to set slide edge to " + edgeName);
+            } catch (IllegalArgumentException e) {
+                // expected
+            }
+        }
+    }
+}
+
diff --git a/tests/tests/transition/src/android/transition/cts/SlideDefaultEdgeTest.java b/tests/tests/transition/src/android/transition/cts/SlideDefaultEdgeTest.java
new file mode 100644
index 0000000..060b4cc
--- /dev/null
+++ b/tests/tests/transition/src/android/transition/cts/SlideDefaultEdgeTest.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.transition.cts;
+
+import android.support.test.rule.ActivityTestRule;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.transition.Slide;
+import android.transition.TransitionManager;
+import android.view.Gravity;
+import android.view.View;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.util.Arrays;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+public class SlideDefaultEdgeTest {
+    @Test
+    @SmallTest
+    public void testDefaultSide() {
+        // default to bottom
+        Slide slide = new Slide();
+        assertEquals(Gravity.BOTTOM, slide.getSlideEdge());
+    }
+}
+
diff --git a/tests/tests/transition/src/android/transition/cts/SlideEdgeTest.java b/tests/tests/transition/src/android/transition/cts/SlideEdgeTest.java
new file mode 100644
index 0000000..01225dc
--- /dev/null
+++ b/tests/tests/transition/src/android/transition/cts/SlideEdgeTest.java
@@ -0,0 +1,269 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.transition.cts;
+
+import android.app.Activity;
+import android.app.Instrumentation;
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.transition.Slide;
+import android.transition.TransitionManager;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+
+import org.junit.Test;
+
+import java.util.concurrent.TimeUnit;
+
+@MediumTest
+public class SlideEdgeTest extends ActivityInstrumentationTestCase2<TransitionActivity>  {
+    private static final Object[][] sSlideEdgeArray = {
+            { Gravity.START, "START" },
+            { Gravity.END, "END" },
+            { Gravity.LEFT, "LEFT" },
+            { Gravity.TOP, "TOP" },
+            { Gravity.RIGHT, "RIGHT" },
+            { Gravity.BOTTOM, "BOTTOM" },
+    };
+
+    public SlideEdgeTest() {
+        super(TransitionActivity.class);
+    }
+
+    public void testSetSide() throws Throwable {
+        for (int i = 0; i < sSlideEdgeArray.length; i++) {
+            int slideEdge = (Integer) (sSlideEdgeArray[i][0]);
+            String edgeName = (String) (sSlideEdgeArray[i][1]);
+            Slide slide = new Slide(slideEdge);
+            assertEquals("Edge not set properly in constructor " + edgeName,
+                    slideEdge, slide.getSlideEdge());
+
+            slide = new Slide();
+            slide.setSlideEdge(slideEdge);
+            assertEquals("Edge not set properly with setter " + edgeName,
+                    slideEdge, slide.getSlideEdge());
+        }
+    }
+
+    public void testSlideOut() throws Throwable {
+        for (int i = 0; i < sSlideEdgeArray.length; i++) {
+            final int slideEdge = (Integer) (sSlideEdgeArray[i][0]);
+            final Slide slide = new Slide(slideEdge);
+            final SimpleTransitionListener listener = new SimpleTransitionListener();
+            slide.addListener(listener);
+
+            final Instrumentation instrumentation = getInstrumentation();
+            final Activity activity = getActivity();
+            instrumentation.runOnMainSync(new Runnable() {
+                @Override
+                public void run() {
+                    activity.setContentView(R.layout.scene1);
+                }
+            });
+            instrumentation.waitForIdleSync();
+
+            final View redSquare = activity.findViewById(R.id.redSquare);
+            final View greenSquare = activity.findViewById(R.id.greenSquare);
+            final View hello = activity.findViewById(R.id.hello);
+            final ViewGroup sceneRoot = (ViewGroup) activity.findViewById(R.id.holder);
+
+            instrumentation.runOnMainSync(new Runnable() {
+                @Override
+                public void run() {
+                    TransitionManager.beginDelayedTransition(sceneRoot, slide);
+                    redSquare.setVisibility(View.INVISIBLE);
+                    greenSquare.setVisibility(View.INVISIBLE);
+                    hello.setVisibility(View.INVISIBLE);
+                }
+            });
+            assertTrue(listener.startLatch.await(1, TimeUnit.SECONDS));
+            assertEquals(1, listener.endLatch.getCount());
+            assertEquals(View.VISIBLE, redSquare.getVisibility());
+            assertEquals(View.VISIBLE, greenSquare.getVisibility());
+            assertEquals(View.VISIBLE, hello.getVisibility());
+
+            float redStartX = redSquare.getTranslationX();
+            float redStartY = redSquare.getTranslationY();
+
+            Thread.sleep(200);
+            assertTranslation(slideEdge, redSquare);
+            assertTranslation(slideEdge, greenSquare);
+            assertTranslation(slideEdge, hello);
+
+            final float redMidX = redSquare.getTranslationX();
+            final float redMidY = redSquare.getTranslationY();
+
+            switch (slideEdge) {
+                case Gravity.LEFT:
+                case Gravity.START:
+                    assertTrue(
+                            "isn't sliding out to left. Expecting " + redStartX + " > " + redMidX,
+                            redStartX > redMidX);
+                    break;
+                case Gravity.RIGHT:
+                case Gravity.END:
+                    assertTrue(
+                            "isn't sliding out to right. Expecting " + redStartX + " < " + redMidX,
+                            redStartX < redMidX);
+                    break;
+                case Gravity.TOP:
+                    assertTrue("isn't sliding out to top. Expecting " + redStartY + " > " + redMidY,
+                            redStartY > redSquare.getTranslationY());
+                    break;
+                case Gravity.BOTTOM:
+                    assertTrue(
+                            "isn't sliding out to bottom. Expecting " + redStartY + " < " + redMidY,
+                            redStartY < redSquare.getTranslationY());
+                    break;
+            }
+            assertTrue(listener.endLatch.await(1, TimeUnit.SECONDS));
+            instrumentation.waitForIdleSync();
+
+            assertNoTranslation(redSquare);
+            assertNoTranslation(greenSquare);
+            assertNoTranslation(hello);
+            assertEquals(View.INVISIBLE, redSquare.getVisibility());
+            assertEquals(View.INVISIBLE, greenSquare.getVisibility());
+            assertEquals(View.INVISIBLE, hello.getVisibility());
+        }
+    }
+
+    public void testSlideIn() throws Throwable {
+        for (int i = 0; i < sSlideEdgeArray.length; i++) {
+            final int slideEdge = (Integer) (sSlideEdgeArray[i][0]);
+            final Slide slide = new Slide(slideEdge);
+            final SimpleTransitionListener listener = new SimpleTransitionListener();
+            slide.addListener(listener);
+
+            final Instrumentation instrumentation = getInstrumentation();
+            final Activity activity = getActivity();
+
+            instrumentation.runOnMainSync(new Runnable() {
+                @Override
+                public void run() {
+                    activity.setContentView(R.layout.scene1);
+                }
+            });
+            instrumentation.waitForIdleSync();
+
+            final View redSquare = activity.findViewById(R.id.redSquare);
+            final View greenSquare = activity.findViewById(R.id.greenSquare);
+            final View hello = activity.findViewById(R.id.hello);
+            final ViewGroup sceneRoot = (ViewGroup) activity.findViewById(R.id.holder);
+
+            instrumentation.runOnMainSync(new Runnable() {
+                @Override
+                public void run() {
+                    redSquare.setVisibility(View.INVISIBLE);
+                    greenSquare.setVisibility(View.INVISIBLE);
+                    hello.setVisibility(View.INVISIBLE);
+                }
+            });
+            instrumentation.waitForIdleSync();
+
+            // now slide in
+            instrumentation.runOnMainSync(new Runnable() {
+                @Override
+                public void run() {
+                    TransitionManager.beginDelayedTransition(sceneRoot, slide);
+                    redSquare.setVisibility(View.VISIBLE);
+                    greenSquare.setVisibility(View.VISIBLE);
+                    hello.setVisibility(View.VISIBLE);
+                }
+            });
+            assertTrue(listener.startLatch.await(1, TimeUnit.SECONDS));
+
+            assertEquals(1, listener.endLatch.getCount());
+            assertEquals(View.VISIBLE, redSquare.getVisibility());
+            assertEquals(View.VISIBLE, greenSquare.getVisibility());
+            assertEquals(View.VISIBLE, hello.getVisibility());
+
+            final float redStartX = redSquare.getTranslationX();
+            final float redStartY = redSquare.getTranslationY();
+
+            Thread.sleep(200);
+            assertTranslation(slideEdge, redSquare);
+            assertTranslation(slideEdge, greenSquare);
+            assertTranslation(slideEdge, hello);
+            final float redMidX = redSquare.getTranslationX();
+            final float redMidY = redSquare.getTranslationY();
+
+            switch (slideEdge) {
+                case Gravity.LEFT:
+                case Gravity.START:
+                    assertTrue(
+                            "isn't sliding in from left. Expecting " + redStartX + " < " + redMidX,
+                            redStartX < redMidX);
+                    break;
+                case Gravity.RIGHT:
+                case Gravity.END:
+                    assertTrue(
+                            "isn't sliding in from right. Expecting " + redStartX + " > " + redMidX,
+                            redStartX > redMidX);
+                    break;
+                case Gravity.TOP:
+                    assertTrue(
+                            "isn't sliding in from top. Expecting " + redStartY + " < " + redMidY,
+                            redStartY < redSquare.getTranslationY());
+                    break;
+                case Gravity.BOTTOM:
+                    assertTrue("isn't sliding in from bottom. Expecting " + redStartY + " > "
+                                    + redMidY,
+                            redStartY > redSquare.getTranslationY());
+                    break;
+            }
+            assertTrue(listener.endLatch.await(1, TimeUnit.SECONDS));
+            instrumentation.waitForIdleSync();
+
+            assertNoTranslation(redSquare);
+            assertNoTranslation(greenSquare);
+            assertNoTranslation(hello);
+            assertEquals(View.VISIBLE, redSquare.getVisibility());
+            assertEquals(View.VISIBLE, greenSquare.getVisibility());
+            assertEquals(View.VISIBLE, hello.getVisibility());
+        }
+    }
+
+    private void assertTranslation(int slideEdge, View view) {
+        switch (slideEdge) {
+            case Gravity.LEFT:
+            case Gravity.START:
+                assertTrue(view.getTranslationX() < 0);
+                assertEquals(0f, view.getTranslationY(), 0.01f);
+                break;
+            case Gravity.RIGHT:
+            case Gravity.END:
+                assertTrue(view.getTranslationX() > 0);
+                assertEquals(0f, view.getTranslationY(), 0.01f);
+                break;
+            case Gravity.TOP:
+                assertTrue(view.getTranslationY() < 0);
+                assertEquals(0f, view.getTranslationX(), 0.01f);
+                break;
+            case Gravity.BOTTOM:
+                assertTrue(view.getTranslationY() > 0);
+                assertEquals(0f, view.getTranslationX(), 0.01f);
+                break;
+        }
+    }
+
+    private void assertNoTranslation(View view) {
+        assertEquals(0f, view.getTranslationX(), 0.01f);
+        assertEquals(0f, view.getTranslationY(), 0.01f);
+    }
+}
+
diff --git a/tests/tests/transition/src/android/transition/cts/TransitionActivity.java b/tests/tests/transition/src/android/transition/cts/TransitionActivity.java
index 8236bd5..be9bf24 100644
--- a/tests/tests/transition/src/android/transition/cts/TransitionActivity.java
+++ b/tests/tests/transition/src/android/transition/cts/TransitionActivity.java
@@ -31,7 +31,7 @@
 import android.view.ViewGroup;
 import java.util.ArrayList;
 
-import com.android.cts.transition.R;
+import android.transition.cts.R;
 
 public class TransitionActivity extends Activity {
     @Override
diff --git a/tests/tests/transition/src/android/transition/cts/TransitionManagerTest.java b/tests/tests/transition/src/android/transition/cts/TransitionManagerTest.java
index 78db908..9eacd1b 100644
--- a/tests/tests/transition/src/android/transition/cts/TransitionManagerTest.java
+++ b/tests/tests/transition/src/android/transition/cts/TransitionManagerTest.java
@@ -15,12 +15,15 @@
  */
 package android.transition.cts;
 
-import com.android.cts.transition.R;
+import android.transition.cts.R;
 
 import android.transition.Scene;
 import android.transition.TransitionManager;
 import android.view.View;
 
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
 public class TransitionManagerTest extends BaseTransitionTest {
 
     public TransitionManagerTest() {
@@ -38,13 +41,13 @@
         });
 
         waitForStart();
-        waitForEnd(150);
-        assertFalse(mTransition.listener.resumed);
-        assertFalse(mTransition.listener.paused);
-        assertFalse(mTransition.listener.canceled);
-        assertNotNull(mTransition.listener.transition);
-        assertEquals(TestTransition.class, mTransition.listener.transition.getClass());
-        assertTrue(mTransition != mTransition.listener.transition);
+        waitForEnd(300);
+        assertEquals(1, mListener.resumeLatch.getCount());
+        assertEquals(1, mListener.pauseLatch.getCount());
+        assertEquals(1, mListener.cancelLatch.getCount());
+        assertNotNull(mListener.transition);
+        assertEquals(TestTransition.class, mListener.transition.getClass());
+        assertTrue(mTransition != mListener.transition);
         runTestOnUiThread(new Runnable() {
             @Override
             public void run() {
@@ -57,14 +60,14 @@
     public void testGo() throws Throwable {
         startTransition(R.layout.scene1);
         waitForStart();
-        waitForEnd(150);
+        waitForEnd(300);
 
-        assertFalse(mTransition.listener.resumed);
-        assertFalse(mTransition.listener.paused);
-        assertFalse(mTransition.listener.canceled);
-        assertNotNull(mTransition.listener.transition);
-        assertEquals(TestTransition.class, mTransition.listener.transition.getClass());
-        assertTrue(mTransition != mTransition.listener.transition);
+        assertEquals(1, mListener.resumeLatch.getCount());
+        assertEquals(1, mListener.pauseLatch.getCount());
+        assertEquals(1, mListener.cancelLatch.getCount());
+        assertNotNull(mListener.transition);
+        assertEquals(TestTransition.class, mListener.transition.getClass());
+        assertTrue(mTransition != mListener.transition);
         runTestOnUiThread(new Runnable() {
             @Override
             public void run() {
@@ -87,26 +90,25 @@
         });
 
         waitForStart();
-        waitForEnd(150);
-        assertFalse(mTransition.listener.resumed);
-        assertFalse(mTransition.listener.paused);
-        assertFalse(mTransition.listener.canceled);
-        assertNotNull(mTransition.listener.transition);
-        assertEquals(TestTransition.class, mTransition.listener.transition.getClass());
-        assertTrue(mTransition != mTransition.listener.transition);
+        waitForEnd(300);
+        assertEquals(1, mListener.resumeLatch.getCount());
+        assertEquals(1, mListener.pauseLatch.getCount());
+        assertEquals(1, mListener.cancelLatch.getCount());
+        assertNotNull(mListener.transition);
+        assertEquals(TestTransition.class, mListener.transition.getClass());
+        assertTrue(mTransition != mListener.transition);
         runTestOnUiThread(new Runnable() {
             @Override
             public void run() {
+                mListener.startLatch = new CountDownLatch(1);
+                mListener.endLatch = new CountDownLatch(1);
                 assertNotNull(mActivity.findViewById(R.id.redSquare));
                 assertNotNull(mActivity.findViewById(R.id.greenSquare));
-                mTransition.listener.started = false;
-                mTransition.listener.ended = false;
                 Scene scene = Scene.getSceneForLayout(mSceneRoot, R.layout.scene2, mActivity);
                 transitionManager.transitionTo(scene);
             }
         });
-        Thread.sleep(50);
-        assertFalse(mTransition.listener.started);
+        assertFalse(mListener.startLatch.await(50, TimeUnit.MILLISECONDS));
         endTransition();
     }
 
@@ -124,8 +126,7 @@
                 transitionManager.transitionTo(scenes[0]);
             }
         });
-        Thread.sleep(50);
-        assertFalse(mTransition.listener.started);
+        assertFalse(mListener.startLatch.await(100, TimeUnit.MILLISECONDS));
 
         runTestOnUiThread(new Runnable() {
             @Override
@@ -135,23 +136,22 @@
         });
 
         waitForStart();
-        waitForEnd(150);
-        assertFalse(mTransition.listener.resumed);
-        assertFalse(mTransition.listener.paused);
-        assertFalse(mTransition.listener.canceled);
-        assertNotNull(mTransition.listener.transition);
-        assertEquals(TestTransition.class, mTransition.listener.transition.getClass());
-        assertTrue(mTransition != mTransition.listener.transition);
+        waitForEnd(300);
+        assertEquals(1, mListener.resumeLatch.getCount());
+        assertEquals(1, mListener.pauseLatch.getCount());
+        assertEquals(1, mListener.cancelLatch.getCount());
+        assertNotNull(mListener.transition);
+        assertEquals(TestTransition.class, mListener.transition.getClass());
+        assertTrue(mTransition != mListener.transition);
         runTestOnUiThread(new Runnable() {
             @Override
             public void run() {
-                mTransition.listener.started = false;
-                mTransition.listener.ended = false;
+                mListener.startLatch = new CountDownLatch(1);
+                mListener.endLatch = new CountDownLatch(1);
                 transitionManager.transitionTo(scenes[2]);
             }
         });
-        Thread.sleep(50);
-        assertFalse(mTransition.listener.started);
+        assertFalse(mListener.startLatch.await(50, TimeUnit.MILLISECONDS));
         endTransition();
     }
 
@@ -161,7 +161,7 @@
         startTransition(R.layout.scene1);
         waitForStart();
         endTransition();
-        waitForEnd(50);
+        waitForEnd(100);
     }
 
     public void testEndTransitionsBeforeStarted() throws Throwable {
@@ -175,9 +175,8 @@
                 TransitionManager.endTransitions(mSceneRoot);
             }
         });
-        Thread.sleep(50);
-        assertFalse(mTransition.listener.started);
-        assertFalse(mTransition.listener.ended);
+        assertFalse(mListener.startLatch.await(100, TimeUnit.MILLISECONDS));
+        assertFalse(mListener.endLatch.await(10, TimeUnit.MILLISECONDS));
     }
 }
 
diff --git a/tests/tests/transition/src/android/transition/cts/TransitionSetTest.java b/tests/tests/transition/src/android/transition/cts/TransitionSetTest.java
new file mode 100644
index 0000000..adfc36a
--- /dev/null
+++ b/tests/tests/transition/src/android/transition/cts/TransitionSetTest.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.transition.cts;
+
+import android.transition.ChangeBounds;
+import android.transition.Fade;
+import android.transition.TransitionSet;
+
+import java.util.concurrent.TimeUnit;
+
+public class TransitionSetTest extends BaseTransitionTest {
+
+    public void testTransitionTogether() throws Throwable {
+        TransitionSet transitionSet = new TransitionSet();
+        Fade fade = new Fade();
+        SimpleTransitionListener fadeListener = new SimpleTransitionListener();
+        fade.addListener(fadeListener);
+        ChangeBounds changeBounds = new ChangeBounds();
+        SimpleTransitionListener changeBoundsListener = new SimpleTransitionListener();
+        changeBounds.addListener(changeBoundsListener);
+        transitionSet.addTransition(fade);
+        transitionSet.addTransition(changeBounds);
+        mTransition = transitionSet;
+        resetListener();
+
+        assertEquals(TransitionSet.ORDERING_TOGETHER, transitionSet.getOrdering());
+        enterScene(R.layout.scene1);
+        startTransition(R.layout.scene3);
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                assertEquals(0, fadeListener.startLatch.getCount());
+                assertEquals(0, changeBoundsListener.startLatch.getCount());
+            }
+        });
+    }
+
+    public void testTransitionSequentially() throws Throwable {
+        TransitionSet transitionSet = new TransitionSet();
+        Fade fade = new Fade();
+        SimpleTransitionListener fadeListener = new SimpleTransitionListener();
+        fade.addListener(fadeListener);
+        ChangeBounds changeBounds = new ChangeBounds();
+        SimpleTransitionListener changeBoundsListener = new SimpleTransitionListener();
+        changeBounds.addListener(changeBoundsListener);
+        transitionSet.addTransition(fade);
+        transitionSet.addTransition(changeBounds);
+        mTransition = transitionSet;
+        resetListener();
+
+        assertEquals(TransitionSet.ORDERING_TOGETHER, transitionSet.getOrdering());
+        transitionSet.setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
+        assertEquals(TransitionSet.ORDERING_SEQUENTIAL, transitionSet.getOrdering());
+
+        enterScene(R.layout.scene1);
+        startTransition(R.layout.scene3);
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                assertEquals(0, fadeListener.startLatch.getCount());
+                assertEquals(1, changeBoundsListener.startLatch.getCount());
+            }
+        });
+        assertTrue(fadeListener.endLatch.await(400, TimeUnit.MILLISECONDS));
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                assertEquals(0, changeBoundsListener.startLatch.getCount());
+            }
+        });
+    }
+
+    public void testTransitionCount() throws Throwable {
+        TransitionSet transitionSet = new TransitionSet();
+        assertEquals(0, transitionSet.getTransitionCount());
+
+        Fade fade = new Fade();
+        ChangeBounds changeBounds = new ChangeBounds();
+        transitionSet.addTransition(fade);
+        transitionSet.addTransition(changeBounds);
+
+        assertEquals(2, transitionSet.getTransitionCount());
+        assertSame(fade, transitionSet.getTransitionAt(0));
+        assertSame(changeBounds, transitionSet.getTransitionAt(1));
+
+        transitionSet.removeTransition(fade);
+
+        assertEquals(1, transitionSet.getTransitionCount());
+        assertSame(changeBounds, transitionSet.getTransitionAt(0));
+
+        transitionSet.removeTransition(fade); // remove one that isn't there
+        assertEquals(1, transitionSet.getTransitionCount());
+        assertSame(changeBounds, transitionSet.getTransitionAt(0));
+    }
+}
+
diff --git a/tests/tests/transition/src/android/transition/cts/TransitionTest.java b/tests/tests/transition/src/android/transition/cts/TransitionTest.java
index 8a9f3a3..9ae568a 100644
--- a/tests/tests/transition/src/android/transition/cts/TransitionTest.java
+++ b/tests/tests/transition/src/android/transition/cts/TransitionTest.java
@@ -15,19 +15,33 @@
  */
 package android.transition.cts;
 
-import com.android.cts.transition.R;
-
-import android.animation.ObjectAnimator;
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.graphics.Rect;
+import android.os.Debug;
+import android.os.SystemClock;
+import android.transition.ArcMotion;
 import android.transition.AutoTransition;
+import android.transition.ChangeBounds;
+import android.transition.PathMotion;
 import android.transition.Scene;
+import android.transition.Transition;
+import android.transition.Transition.EpicenterCallback;
+import android.transition.Transition.TransitionListener;
 import android.transition.TransitionManager;
+import android.transition.TransitionPropagation;
 import android.transition.TransitionValues;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.animation.AccelerateInterpolator;
 import android.widget.ImageView;
 import android.widget.RelativeLayout;
 import android.widget.TextView;
 
+import java.util.HashMap;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
 public class TransitionTest extends BaseTransitionTest {
 
     public TransitionTest() {
@@ -52,17 +66,17 @@
 
         waitForStart(listener2);
 
-        assertTrue(mTransition.listener.paused);
-        assertTrue(mTransition.listener.resumed);
-        assertFalse(mTransition.listener.canceled);
-        assertFalse(mTransition.listener.ended);
-        assertTrue(mTransition.listener.started);
+        assertEquals(0, mListener.pauseLatch.getCount());
+        assertEquals(0, mListener.resumeLatch.getCount());
+        assertEquals(1, mListener.cancelLatch.getCount());
+        assertEquals(1, mListener.endLatch.getCount());
+        assertEquals(0, mListener.startLatch.getCount());
 
-        assertFalse(listener2.paused);
-        assertFalse(listener2.resumed);
-        assertFalse(listener2.canceled);
-        assertFalse(listener2.ended);
-        assertTrue(listener2.started);
+        assertEquals(1, listener2.pauseLatch.getCount());
+        assertEquals(1, listener2.resumeLatch.getCount());
+        assertEquals(1, listener2.cancelLatch.getCount());
+        assertEquals(1, listener2.endLatch.getCount());
+        assertEquals(0, listener2.startLatch.getCount());
         endTransition();
     }
 
@@ -73,16 +87,17 @@
         runTestOnUiThread(new Runnable() {
             @Override
             public void run() {
-                mTransition.removeListener(mTransition.listener);
+                mTransition.removeListener(mListener);
             }
         });
 
-        Thread.sleep(150);
-        assertFalse(mTransition.listener.ended);
+        assertFalse(mListener.endLatch.await(250, TimeUnit.MILLISECONDS));
     }
 
     public void testAddTargetId() throws Throwable {
         enterScene(R.layout.scene4);
+        assertNotNull(mTransition.getTargetIds());
+        assertTrue(mTransition.getTargetIds().isEmpty());
         mTransition.addTarget(R.id.holder);
         mTransition.addTarget(R.id.hello);
         assertEquals(2, mTransition.getTargetIds().size());
@@ -110,6 +125,7 @@
 
     public void testAddTargetClass() throws Throwable {
         enterScene(R.layout.scene4);
+        assertNull(mTransition.getTargetTypes());
         mTransition.addTarget(RelativeLayout.class);
         mTransition.addTarget(TextView.class);
         assertEquals(2, mTransition.getTargetTypes().size());
@@ -193,6 +209,7 @@
 
     public void testAddTargetName() throws Throwable {
         enterScene(R.layout.scene4);
+        assertNull(mTransition.getTargetNames());
         mTransition.addTarget("red");
         mTransition.addTarget("holder");
         assertEquals(2, mTransition.getTargetNames().size());
@@ -223,6 +240,7 @@
     public void testIsTransitionRequired() throws Throwable {
         enterScene(R.layout.scene1);
         mTransition = new NotRequiredTransition();
+        resetListener();
         runTestOnUiThread(new Runnable() {
             @Override
             public void run() {
@@ -235,6 +253,268 @@
         endTransition();
     }
 
+    public void testCanRemoveViews() throws Throwable {
+        enterScene(R.layout.scene1);
+        assertFalse(mTransition.canRemoveViews());
+        mTransition.addListener(new TransitionListener() {
+            @Override
+            public void onTransitionStart(Transition transition) {
+                assertTrue(transition.canRemoveViews());
+            }
+
+            @Override
+            public void onTransitionEnd(Transition transition) {
+            }
+
+            @Override
+            public void onTransitionCancel(Transition transition) {
+            }
+
+            @Override
+            public void onTransitionPause(Transition transition) {
+            }
+
+            @Override
+            public void onTransitionResume(Transition transition) {
+            }
+        });
+        startTransition(R.layout.scene2);
+    }
+
+    public void testExcludeChildrenView() throws Throwable {
+        View layout1 = loadLayout(R.layout.scene1);
+        Scene scene1 = loadScene(layout1);
+        enterScene(R.layout.scene1);
+        View holder1 = layout1.findViewById(R.id.holder);
+        mTransition.excludeChildren(holder1, true);
+        View layout2 = loadLayout(R.layout.scene2);
+        Scene scene2 = loadScene(layout2);
+        View holder2 = layout2.findViewById(R.id.holder);
+        mTransition.excludeChildren(holder2, true);
+        startTransition(scene2);
+        waitForEnd(0); // Should already be ended, since no children are transitioning
+
+        mTransition.excludeChildren(holder1, false); // remove it
+        mTransition.excludeChildren(holder2, false); // remove it
+        resetListener();
+        startTransition(scene1);
+        assertEquals(1, mListener.endLatch.getCount()); // it is running as expected
+        endTransition();
+    }
+
+    public void testExcludeChildrenId() throws Throwable {
+        enterScene(R.layout.scene1);
+        mTransition.excludeChildren(R.id.holder, true);
+        startTransition(R.layout.scene2);
+        waitForEnd(0); // Should already be ended, since no children are transitioning
+
+        resetListener();
+        mTransition.excludeChildren(R.id.holder, false); // remove it
+        startTransition(R.layout.scene1);
+        assertEquals(1, mListener.endLatch.getCount()); // It is running
+        endTransition();
+    }
+
+    public void testExcludeTargetView() throws Throwable {
+        View layout1 = loadLayout(R.layout.scene1);
+        Scene scene1 = loadScene(layout1);
+        enterScene(R.layout.scene1);
+        View redSquare1 = layout1.findViewById(R.id.redSquare);
+        mTransition.excludeTarget(redSquare1, true);
+        startTransition(R.layout.scene7);
+        waitForEnd(0); // Should already be ended, since no children are transitioning
+
+        mTransition.excludeTarget(redSquare1, false); // remove it
+        resetListener();
+        startTransition(scene1);
+        assertEquals(1, mListener.endLatch.getCount()); // it is running as expected
+        endTransition();
+    }
+
+    public void testExcludeTargetId() throws Throwable {
+        enterScene(R.layout.scene1);
+        mTransition.excludeTarget(R.id.redSquare, true);
+        startTransition(R.layout.scene7);
+        waitForEnd(0); // Should already be ended, since no children are transitioning
+
+        resetListener();
+        mTransition.excludeTarget(R.id.redSquare, false); // remove it
+        startTransition(R.layout.scene1);
+        assertEquals(1, mListener.endLatch.getCount()); // It is running
+        endTransition();
+    }
+
+    public void testExcludeTargetClass() throws Throwable {
+        enterScene(R.layout.scene1);
+        mTransition.excludeTarget(TextView.class, true);
+        startTransition(R.layout.scene3);
+        waitForEnd(0); // Should already be ended, since no children are transitioning
+
+        resetListener();
+        mTransition.excludeTarget(TextView.class, false); // remove it
+        startTransition(R.layout.scene1);
+        assertEquals(1, mListener.endLatch.getCount()); // It is running
+        endTransition();
+    }
+
+    public void testExcludeTargetName() throws Throwable {
+        enterScene(R.layout.scene1);
+        mTransition.excludeTarget("hello", true);
+        startTransition(R.layout.scene3);
+        waitForEnd(0); // Should already be ended, since no children are transitioning
+
+        resetListener();
+        mTransition.excludeTarget("hello", false); // remove it
+        startTransition(R.layout.scene1);
+        assertEquals(1, mListener.endLatch.getCount()); // It is running
+        endTransition();
+    }
+
+    public void testDuration() throws Throwable {
+        assertEquals(-1, mTransition.getDuration());
+        enterScene(R.layout.scene1);
+        mTransition.setDuration(500);
+        assertEquals(500, mTransition.getDuration());
+        startTransition(R.layout.scene3);
+        long startTime = SystemClock.uptimeMillis();
+        waitForEnd(600);
+        long endTime = SystemClock.uptimeMillis();
+        assertEquals(500, endTime - startTime, 100);
+    }
+
+    public void testEpicenter() throws Throwable {
+        EpicenterCallback callback = new EpicenterCallback() {
+            @Override
+            public Rect onGetEpicenter(Transition transition) {
+                return new Rect(0, 0, 1, 1);
+            }
+        };
+        mTransition.setEpicenterCallback(callback);
+        assertEquals(callback, mTransition.getEpicenterCallback());
+    }
+
+    public void testInterpolator() throws Throwable {
+        enterScene(R.layout.scene1);
+        View redSquare = mActivity.findViewById(R.id.redSquare);
+        CaptureAnimatorTransition transition = new CaptureAnimatorTransition();
+        assertNull(transition.getInterpolator());
+        AccelerateInterpolator interpolator = new AccelerateInterpolator();
+        transition.setInterpolator(interpolator);
+        assertSame(interpolator, transition.getInterpolator());
+        mTransition = transition;
+        resetListener();
+        startTransition(R.layout.scene4);
+        assertFalse(transition.animators.isEmpty());
+        Animator animator = transition.animators.get(redSquare);
+        AnimationStartListener listener = transition.listeners.get(redSquare);
+        assertTrue(listener.startLatch.await(100, TimeUnit.MILLISECONDS));
+        assertSame(interpolator, animator.getInterpolator());
+        endTransition();
+    }
+
+    public void testName() throws Throwable {
+        assertEquals("android.transition.cts.BaseTransitionTest$TestTransition",
+                mTransition.getName());
+    }
+
+    public void testPathMotion() throws Throwable {
+        PathMotion pathMotion = new ArcMotion();
+        mTransition.setPathMotion(pathMotion);
+        assertEquals(pathMotion, mTransition.getPathMotion());
+    }
+
+    public void testPropagation() throws Throwable {
+        enterScene(R.layout.scene1);
+        CaptureAnimatorTransition transition = new CaptureAnimatorTransition();
+        mTransition = transition;
+        TransitionPropagation yPropagation = new TransitionPropagation() {
+            private static final String TOP = "top value";
+            private final String[] PROPERTIES = {TOP};
+
+            @Override
+            public long getStartDelay(ViewGroup viewGroup, Transition transition,
+                    TransitionValues startValues, TransitionValues endValues) {
+                int startTop = startValues == null ? 0 : (Integer) startValues.values.get(TOP);
+                int endTop = endValues == null ? 0 : (Integer) endValues.values.get(TOP);
+                return (startTop == 0) ? endTop : startTop;
+            }
+
+            @Override
+            public void captureValues(TransitionValues transitionValues) {
+                if (transitionValues.view != null) {
+                    transitionValues.values.put(TOP, transitionValues.view.getTop());
+                }
+            }
+
+            @Override
+            public String[] getPropagationProperties() {
+                return PROPERTIES;
+            }
+        };
+        mTransition.setPropagation(yPropagation);
+        resetListener();
+
+        View redSquare = mActivity.findViewById(R.id.redSquare);
+        View greenSquare = mActivity.findViewById(R.id.greenSquare);
+        int diffTop = greenSquare.getTop() - redSquare.getTop();
+        startTransition(R.layout.scene4);
+        Animator redSquareAnimator = transition.animators.get(redSquare);
+        Animator greenSquareAnimator = transition.animators.get(greenSquare);
+        AnimationStartListener listener = transition.listeners.get(redSquare);
+        assertTrue(listener.startLatch.await(100, TimeUnit.MILLISECONDS));
+        assertEquals(0, redSquareAnimator.getStartDelay());
+        assertEquals(diffTop, greenSquareAnimator.getStartDelay());
+        endTransition();
+    }
+
+    public void testStartDelay() throws Throwable {
+        CaptureAnimatorTransition transition = new CaptureAnimatorTransition();
+        mTransition = transition;
+        resetListener();
+        enterScene(R.layout.scene1);
+        View redSquare = mActivity.findViewById(R.id.redSquare);
+
+        assertEquals(-1, mTransition.getStartDelay());
+        mTransition.setStartDelay(200);
+        assertEquals(200, mTransition.getStartDelay());
+
+        startTransition(R.layout.scene4);
+
+        Animator animator = transition.animators.get(redSquare);
+        assertFalse(animator.isRunning());
+        AnimationStartListener listener = transition.listeners.get(redSquare);
+        assertTrue(listener.startLatch.await(250, TimeUnit.MILLISECONDS));
+        endTransition();
+    }
+
+    public void testTransitionValues() throws Throwable {
+        enterScene(R.layout.scene1);
+        mTransition = new CheckTransitionValuesTransition();
+        mTransition.setDuration(10);
+        resetListener();
+        startTransition(R.layout.scene4);
+        // The transition has all the asserts in it, so we can just end it now.
+        endTransition();
+    }
+
+    public void testMatchOrder() throws Throwable {
+        mTransition = new ChangeBounds();
+        resetListener();
+        enterScene(R.layout.scene1);
+        startTransition(R.layout.scene8);
+
+        // scene 8 swaps the ids, but not the names. No transition should happen.
+        waitForEnd(0);
+
+        // now change the match order to prefer the id
+        mTransition.setMatchOrder(new int[] {Transition.MATCH_ID, Transition.MATCH_NAME});
+
+        resetListener();
+        startTransition(R.layout.scene1);
+        assertEquals(1, mListener.endLatch.getCount());
+        waitForEnd(400);
+    }
+
     private class NotRequiredTransition extends TestTransition {
         @Override
         public boolean isTransitionRequired(TransitionValues startValues,
@@ -242,5 +522,59 @@
             return false;
         }
     }
+
+    private class CaptureAnimatorTransition extends TestTransition {
+        public HashMap<View, Animator> animators = new HashMap<>();
+        public HashMap<View, AnimationStartListener> listeners = new HashMap<>();
+
+        @Override
+        public Animator onAppear(ViewGroup sceneRoot, View view, TransitionValues startValues,
+                TransitionValues endValues) {
+            return setupAnimator(super.onAppear(sceneRoot, view, startValues, endValues),
+                    endValues.view);
+        }
+
+        @Override
+        public Animator onDisappear(ViewGroup sceneRoot, View view, TransitionValues startValues,
+                TransitionValues endValues) {
+            return setupAnimator(super.onDisappear(sceneRoot, view, startValues, endValues),
+                    startValues.view);
+        }
+
+        private Animator setupAnimator(Animator animator, View view) {
+            animators.put(view, animator);
+            AnimationStartListener listener = new AnimationStartListener();
+            animator.addListener(listener);
+            listeners.put(view, listener);
+            return animator;
+        }
+    }
+
+    private class CheckTransitionValuesTransition extends TestTransition {
+        @Override
+        public Animator onAppear(ViewGroup sceneRoot, View view, TransitionValues startValues,
+                TransitionValues endValues) {
+            assertNull(getTransitionValues(endValues.view, true));
+            assertEquals(endValues, getTransitionValues(endValues.view, false));
+            return super.onAppear(sceneRoot, view, startValues, endValues);
+        }
+
+        @Override
+        public Animator onDisappear(ViewGroup sceneRoot, View view, TransitionValues startValues,
+                TransitionValues endValues) {
+            assertNull(getTransitionValues(startValues.view, false));
+            assertEquals(startValues, getTransitionValues(startValues.view, true));
+            return super.onDisappear(sceneRoot, view, startValues, endValues);
+        }
+    }
+
+    private class AnimationStartListener extends AnimatorListenerAdapter {
+        public CountDownLatch startLatch = new CountDownLatch(1);
+
+        @Override
+        public void onAnimationStart(Animator animation) {
+            startLatch.countDown();
+        }
+    }
 }
 
diff --git a/tests/tests/transition/src/android/transition/cts/VisibilityTest.java b/tests/tests/transition/src/android/transition/cts/VisibilityTest.java
new file mode 100644
index 0000000..9b91a36
--- /dev/null
+++ b/tests/tests/transition/src/android/transition/cts/VisibilityTest.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.transition.cts;
+
+import android.transition.TransitionValues;
+import android.transition.Visibility;
+import android.view.View;
+
+public class VisibilityTest extends BaseTransitionTest {
+    Visibility mVisibilityTransition;
+
+    public VisibilityTest() {
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mVisibilityTransition = (Visibility) mTransition;
+    }
+
+    public void testMode() throws Throwable {
+        assertEquals(Visibility.MODE_IN | Visibility.MODE_OUT, mVisibilityTransition.getMode());
+
+        // Should animate in and out
+        enterScene(R.layout.scene4);
+        startTransition(R.layout.scene1);
+        assertEquals(1, mListener.endLatch.getCount());
+        waitForEnd(400);
+
+        resetListener();
+        startTransition(R.layout.scene4);
+        assertEquals(1, mListener.endLatch.getCount());
+        waitForEnd(400);
+
+        // Now only animate in
+        resetListener();
+        mVisibilityTransition.setMode(Visibility.MODE_IN);
+        startTransition(R.layout.scene1);
+        assertEquals(1, mListener.endLatch.getCount());
+        waitForEnd(400);
+
+        // No animation since it should only animate in
+        resetListener();
+        startTransition(R.layout.scene4);
+        waitForEnd(0);
+
+        // Now animate out, but no animation should happen since we're animating in.
+        resetListener();
+        mVisibilityTransition.setMode(Visibility.MODE_OUT);
+        startTransition(R.layout.scene1);
+        waitForEnd(0);
+
+        // but it should animate out
+        resetListener();
+        startTransition(R.layout.scene4);
+        assertEquals(1, mListener.endLatch.getCount());
+        waitForEnd(400);
+    }
+
+    public void testIsVisible() throws Throwable {
+        assertFalse(mVisibilityTransition.isVisible(null));
+
+        enterScene(R.layout.scene1);
+        final View redSquare = mActivity.findViewById(R.id.redSquare);
+        TransitionValues visibleValues = new TransitionValues();
+        visibleValues.view = redSquare;
+        mTransition.captureStartValues(visibleValues);
+
+        assertTrue(mVisibilityTransition.isVisible(visibleValues));
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                redSquare.setVisibility(View.INVISIBLE);
+            }
+        });
+        getInstrumentation().waitForIdleSync();
+        TransitionValues invisibleValues = new TransitionValues();
+        invisibleValues.view = redSquare;
+        mTransition.captureStartValues(invisibleValues);
+        assertFalse(mVisibilityTransition.isVisible(invisibleValues));
+
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                redSquare.setVisibility(View.GONE);
+            }
+        });
+        getInstrumentation().waitForIdleSync();
+        TransitionValues goneValues = new TransitionValues();
+        goneValues.view = redSquare;
+        mTransition.captureStartValues(goneValues);
+        assertFalse(mVisibilityTransition.isVisible(goneValues));
+    }
+}
+
diff --git a/tests/tests/tv/Android.mk b/tests/tests/tv/Android.mk
index 795b473..749e3d1 100644
--- a/tests/tests/tv/Android.mk
+++ b/tests/tests/tv/Android.mk
@@ -20,6 +20,9 @@
 
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
 LOCAL_PACKAGE_NAME := CtsTvTestCases
diff --git a/tests/tests/tv/AndroidManifest.xml b/tests/tests/tv/AndroidManifest.xml
index 79406e0..3de468f 100644
--- a/tests/tests/tv/AndroidManifest.xml
+++ b/tests/tests/tv/AndroidManifest.xml
@@ -17,12 +17,11 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-        package="com.android.cts.tv">
+        package="android.tv.cts">
 
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <uses-permission android:name="android.permission.INJECT_EVENTS" />
 
-    <uses-permission android:name="com.android.providers.tv.permission.READ_EPG_DATA" />
     <uses-permission android:name="com.android.providers.tv.permission.WRITE_EPG_DATA" />
 
     <application>
@@ -94,6 +93,15 @@
                        android:resource="@xml/stub_tv_input_service" />
         </service>
 
+        <service android:name="android.media.tv.cts.FaultyTvInputService"
+                 android:permission="android.permission.BIND_TV_INPUT"
+                 android:process=":faultyTvInputService">
+            <intent-filter>
+                <action android:name="android.media.tv.TvInputService" />
+            </intent-filter>
+            <meta-data android:name="android.media.tv.input"
+                       android:resource="@xml/stub_tv_input_service" />
+        </service>
 
         <activity android:name="android.media.tv.cts.TvViewStubActivity">
             <intent-filter>
@@ -110,7 +118,7 @@
     </application>
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-            android:targetPackage="com.android.cts.tv"
+            android:targetPackage="android.tv.cts"
             android:label="Tests for the TV APIs.">
         <meta-data android:name="listener"
                 android:value="com.android.cts.runner.CtsTestRunListener" />
diff --git a/tests/tests/tv/AndroidTest.xml b/tests/tests/tv/AndroidTest.xml
new file mode 100644
index 0000000..48d5666
--- /dev/null
+++ b/tests/tests/tv/AndroidTest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS TV test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsTvTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.tv.cts" />
+    </test>
+</configuration>
diff --git a/tests/tests/tv/src/android/media/tv/cts/BundledTvInputServiceTest.java b/tests/tests/tv/src/android/media/tv/cts/BundledTvInputServiceTest.java
index 9f19e03..e8ee222 100644
--- a/tests/tests/tv/src/android/media/tv/cts/BundledTvInputServiceTest.java
+++ b/tests/tests/tv/src/android/media/tv/cts/BundledTvInputServiceTest.java
@@ -27,7 +27,8 @@
 import android.test.ActivityInstrumentationTestCase2;
 import android.util.ArrayMap;
 
-import com.android.cts.tv.R;
+import android.tv.cts.R;
+
 import com.android.cts.util.TimeoutReq;
 
 import java.util.ArrayList;
diff --git a/tests/tests/tv/src/android/media/tv/cts/FaultyTvInputService.java b/tests/tests/tv/src/android/media/tv/cts/FaultyTvInputService.java
new file mode 100644
index 0000000..bc66ee9
--- /dev/null
+++ b/tests/tests/tv/src/android/media/tv/cts/FaultyTvInputService.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.media.tv.cts;
+
+import android.content.Context;
+import android.net.Uri;
+import android.os.Process;
+import android.view.Surface;
+
+/**
+ * A TvInputService for testing crash on TV input application.
+ */
+public class FaultyTvInputService extends StubTvInputService {
+    @Override
+    public Session onCreateSession(String inputId) {
+        return new FaultySession(this);
+    }
+
+    @Override
+    public RecordingSession onCreateRecordingSession(String inputId) {
+        return new FaultyRecordingSession(this);
+    }
+
+    public static class FaultySession extends Session {
+        FaultySession(Context context) {
+            super(context);
+        }
+
+        @Override
+        public void onRelease() { }
+
+        @Override
+        public boolean onTune(Uri ChannelUri) {
+            Process.killProcess(Process.myPid());
+            return false;
+        }
+
+        @Override
+        public boolean onSetSurface(Surface surface) {
+            return false;
+        }
+
+        @Override
+        public void onSetCaptionEnabled(boolean enabled) { }
+
+        @Override
+        public void onSetStreamVolume(float volume) { }
+    }
+
+    public static class FaultyRecordingSession extends RecordingSession {
+        FaultyRecordingSession(Context context) {
+            super(context);
+        }
+
+        @Override
+        public void onTune(Uri channelUri) {
+            Process.killProcess(Process.myPid());
+        }
+
+        @Override
+        public void onStartRecording(Uri programHint) { }
+
+        @Override
+        public void onStopRecording() { }
+
+        @Override
+        public void onRelease() { }
+    }
+}
diff --git a/tests/tests/tv/src/android/media/tv/cts/HardwareSessionTest.java b/tests/tests/tv/src/android/media/tv/cts/HardwareSessionTest.java
index 2f852d7..a7b5805 100644
--- a/tests/tests/tv/src/android/media/tv/cts/HardwareSessionTest.java
+++ b/tests/tests/tv/src/android/media/tv/cts/HardwareSessionTest.java
@@ -29,7 +29,7 @@
 import android.net.Uri;
 import android.test.ActivityInstrumentationTestCase2;
 
-import com.android.cts.tv.R;
+import android.tv.cts.R;
 
 import java.util.ArrayList;
 import java.util.List;
diff --git a/tests/tests/tv/src/android/media/tv/cts/TvContentRatingTest.java b/tests/tests/tv/src/android/media/tv/cts/TvContentRatingTest.java
index 5e6478b..9acff92 100644
--- a/tests/tests/tv/src/android/media/tv/cts/TvContentRatingTest.java
+++ b/tests/tests/tv/src/android/media/tv/cts/TvContentRatingTest.java
@@ -27,18 +27,20 @@
  */
 public class TvContentRatingTest extends TestCase {
 
-    public void testCreateRating() throws Exception {
-        final String DOMAIN = "android.media.tv";
-        final String RATING_SYSTEM = "US_TVPG";
-        final String MAIN_RATING = "US_TVPG_TV_MA";
-        final String SUB_RATING_1 = "US_TVPG_TV_S";
-        final String SUB_RATING_2 = "US_TVPG_TV_V";
+    private static final String DOMAIN = "android.media.tv";
+    private static final String RATING_SYSTEM = "US_TVPG";
+    private static final String MAIN_RATING_1 = "US_TVPG_TV_MA";
+    private static final String MAIN_RATING_2 = "US_TVPG_TV_14";
+    private static final String SUB_RATING_1 = "US_TVPG_TV_S";
+    private static final String SUB_RATING_2 = "US_TVPG_TV_V";
+    private static final String SUB_RATING_3 = "US_TVPG_TV_L";
 
-        TvContentRating rating = TvContentRating.createRating(DOMAIN, RATING_SYSTEM, MAIN_RATING,
+    public void testCreateRating() throws Exception {
+        TvContentRating rating = TvContentRating.createRating(DOMAIN, RATING_SYSTEM, MAIN_RATING_1,
                 SUB_RATING_1, SUB_RATING_2);
         assertEquals(DOMAIN, rating.getDomain());
         assertEquals(RATING_SYSTEM, rating.getRatingSystem());
-        assertEquals(MAIN_RATING, rating.getMainRating());
+        assertEquals(MAIN_RATING_1, rating.getMainRating());
         List<String> subRatings = rating.getSubRatings();
         assertEquals(2, subRatings.size());
         assertTrue("Sub-ratings does not contain " + SUB_RATING_1,
@@ -48,19 +50,13 @@
     }
 
     public void testFlattenAndUnflatten() throws Exception {
-        final String DOMAIN = "android.media.tv";
-        final String RATING_SYSTEM = "US_TVPG";
-        final String MAIN_RATING = "US_TVPG_TV_MA";
-        final String SUB_RATING_1 = "US_TVPG_TV_S";
-        final String SUB_RATING_2 = "US_TVPG_TV_V";
-
-        String flattened = TvContentRating.createRating(DOMAIN, RATING_SYSTEM, MAIN_RATING,
+        String flattened = TvContentRating.createRating(DOMAIN, RATING_SYSTEM, MAIN_RATING_1,
                 SUB_RATING_1, SUB_RATING_2).flattenToString();
         TvContentRating rating = TvContentRating.unflattenFromString(flattened);
 
         assertEquals(DOMAIN, rating.getDomain());
         assertEquals(RATING_SYSTEM, rating.getRatingSystem());
-        assertEquals(MAIN_RATING, rating.getMainRating());
+        assertEquals(MAIN_RATING_1, rating.getMainRating());
         List<String> subRatings = rating.getSubRatings();
         assertEquals(2, subRatings.size());
         assertTrue("Sub-ratings does not contain " + SUB_RATING_1,
@@ -68,4 +64,22 @@
         assertTrue("Sub-ratings does not contain " + SUB_RATING_2,
                 subRatings.contains(SUB_RATING_2));
     }
+
+    public void testContains() throws Exception {
+        TvContentRating rating = TvContentRating.createRating(DOMAIN, RATING_SYSTEM, MAIN_RATING_1,
+                SUB_RATING_1, SUB_RATING_2);
+
+        assertTrue(rating.contains(TvContentRating.createRating(DOMAIN, RATING_SYSTEM,
+                MAIN_RATING_1, SUB_RATING_1, SUB_RATING_2)));
+        assertTrue(rating.contains(TvContentRating.createRating(DOMAIN, RATING_SYSTEM,
+                MAIN_RATING_1, SUB_RATING_1)));
+        assertFalse(rating.contains(TvContentRating.createRating(DOMAIN, RATING_SYSTEM,
+                MAIN_RATING_1, SUB_RATING_3)));
+        assertFalse(rating.contains(TvContentRating.createRating(DOMAIN, RATING_SYSTEM,
+                MAIN_RATING_2, SUB_RATING_1, SUB_RATING_2)));
+        assertFalse(rating.contains(TvContentRating.createRating(DOMAIN, RATING_SYSTEM,
+                MAIN_RATING_2, SUB_RATING_3)));
+        assertFalse(rating.contains(TvContentRating.createRating(DOMAIN, RATING_SYSTEM,
+                MAIN_RATING_2)));
+    }
 }
diff --git a/tests/tests/tv/src/android/media/tv/cts/TvContractTest.java b/tests/tests/tv/src/android/media/tv/cts/TvContractTest.java
index b4bc6eb..8811748 100644
--- a/tests/tests/tv/src/android/media/tv/cts/TvContractTest.java
+++ b/tests/tests/tv/src/android/media/tv/cts/TvContractTest.java
@@ -28,10 +28,11 @@
 import android.media.tv.TvContract;
 import android.media.tv.TvContract.Channels;
 import android.media.tv.TvContract.Programs.Genres;
+import android.media.tv.TvContract.RecordedPrograms;
 import android.net.Uri;
 import android.test.AndroidTestCase;
-
-import com.android.cts.tv.R;
+import android.test.MoreAsserts;
+import android.tv.cts.R;
 
 import java.io.InputStream;
 import java.io.OutputStream;
@@ -63,8 +64,9 @@
         TvContract.Programs._ID,
         TvContract.Programs.COLUMN_CHANNEL_ID,
         TvContract.Programs.COLUMN_TITLE,
-        TvContract.Programs.COLUMN_SEASON_NUMBER,
-        TvContract.Programs.COLUMN_EPISODE_NUMBER,
+        TvContract.Programs.COLUMN_SEASON_DISPLAY_NUMBER,
+        TvContract.Programs.COLUMN_SEASON_TITLE,
+        TvContract.Programs.COLUMN_EPISODE_DISPLAY_NUMBER,
         TvContract.Programs.COLUMN_EPISODE_TITLE,
         TvContract.Programs.COLUMN_START_TIME_UTC_MILLIS,
         TvContract.Programs.COLUMN_END_TIME_UTC_MILLIS,
@@ -89,6 +91,17 @@
             + Genres.GAMING + "," + Genres.MOVIES + "," + Genres.NEWS + "," + Genres.SHOPPING + ","
             + Genres.SPORTS + "," + Genres.TRAVEL;
 
+    // Delimiter for genre.
+    private static final String DELIMITER = ",";
+    private static final String EMPTY_GENRE = "";
+    private static final String COMMA = ",";
+    private static final String COMMA_ENCODED = "\",";
+    private static final String QUOTE = "\"";
+    private static final String QUOTE_ENCODED = "\"\"";
+    private static final String WHITE_SPACES = " \r \n \t \f ";
+
+    private static final String PARAM_CANONICAL_GENRE = "canonical_genre";
+
     private String mInputId;
     private ContentResolver mContentResolver;
     private Uri mChannelsUri;
@@ -123,6 +136,7 @@
             }
         }
         mContentResolver.delete(mChannelsUri, null, null);
+        mContentResolver.delete(RecordedPrograms.CONTENT_URI, null, null);
         super.tearDown();
     }
 
@@ -141,7 +155,10 @@
     private static ContentValues createDummyProgramValues(long channelId) {
         ContentValues values = new ContentValues();
         values.put(TvContract.Programs.COLUMN_CHANNEL_ID, channelId);
-        values.put(TvContract.Programs.COLUMN_EPISODE_TITLE, "Title");
+        values.put(TvContract.Programs.COLUMN_EPISODE_DISPLAY_NUMBER , "1A");
+        values.put(TvContract.Programs.COLUMN_EPISODE_TITLE, "episode_title");
+        values.put(TvContract.Programs.COLUMN_SEASON_DISPLAY_NUMBER , "2B");
+        values.put(TvContract.Programs.COLUMN_SEASON_TITLE, "season_title");
         values.put(TvContract.Programs.COLUMN_CANONICAL_GENRE, TvContract.Programs.Genres.encode(
                 TvContract.Programs.Genres.MOVIES, TvContract.Programs.Genres.DRAMA));
         TvContentRating rating = TvContentRating.createRating("android.media.tv", "US_TVPG",
@@ -151,6 +168,44 @@
         return values;
     }
 
+    private static ContentValues createDummyRecordedProgramValues(String inputId, long channelId) {
+        ContentValues values = new ContentValues();
+        values.put(TvContract.RecordedPrograms.COLUMN_INPUT_ID, inputId);
+        values.put(TvContract.RecordedPrograms.COLUMN_CHANNEL_ID, channelId);
+        values.put(TvContract.RecordedPrograms.COLUMN_SEASON_DISPLAY_NUMBER , "3B");
+        values.put(TvContract.RecordedPrograms.COLUMN_SEASON_TITLE, "season_title");
+        values.put(TvContract.RecordedPrograms.COLUMN_EPISODE_DISPLAY_NUMBER , "2A");
+        values.put(TvContract.RecordedPrograms.COLUMN_EPISODE_TITLE, "episode_title");
+        values.put(TvContract.RecordedPrograms.COLUMN_START_TIME_UTC_MILLIS, 1000);
+        values.put(TvContract.RecordedPrograms.COLUMN_END_TIME_UTC_MILLIS, 2000);
+        values.put(TvContract.RecordedPrograms.COLUMN_CANONICAL_GENRE,
+                TvContract.Programs.Genres.encode(
+                        TvContract.Programs.Genres.MOVIES, TvContract.Programs.Genres.DRAMA));
+        values.put(TvContract.RecordedPrograms.COLUMN_SHORT_DESCRIPTION, "short_description");
+        values.put(TvContract.RecordedPrograms.COLUMN_LONG_DESCRIPTION, "long_description");
+        values.put(TvContract.RecordedPrograms.COLUMN_VIDEO_WIDTH, 1920);
+        values.put(TvContract.RecordedPrograms.COLUMN_VIDEO_HEIGHT, 1080);
+        values.put(TvContract.RecordedPrograms.COLUMN_AUDIO_LANGUAGE, "en");
+        TvContentRating rating = TvContentRating.createRating("android.media.tv", "US_TVPG",
+                "US_TVPG_TV_MA", "US_TVPG_S", "US_TVPG_V");
+        values.put(TvContract.RecordedPrograms.COLUMN_CONTENT_RATING, rating.flattenToString());
+        values.put(TvContract.RecordedPrograms.COLUMN_POSTER_ART_URI, "http://foo.com/artwork.png");
+        values.put(TvContract.RecordedPrograms.COLUMN_THUMBNAIL_URI, "http://foo.com/thumbnail.jpg");
+        values.put(TvContract.RecordedPrograms.COLUMN_SEARCHABLE, 1);
+        values.put(TvContract.RecordedPrograms.COLUMN_RECORDING_DATA_URI, "file:///sdcard/foo/");
+        values.put(TvContract.RecordedPrograms.COLUMN_RECORDING_DATA_BYTES, 1024 * 1024);
+        values.put(TvContract.RecordedPrograms.COLUMN_RECORDING_DURATION_MILLIS, 60 * 60 * 1000);
+        values.put(TvContract.RecordedPrograms.COLUMN_RECORDING_EXPIRE_TIME_UTC_MILLIS, 1454480880L);
+        values.put(TvContract.RecordedPrograms.COLUMN_INTERNAL_PROVIDER_DATA,
+                "internal_provider_data".getBytes());
+        values.put(TvContract.RecordedPrograms.COLUMN_INTERNAL_PROVIDER_FLAG1, 4);
+        values.put(TvContract.RecordedPrograms.COLUMN_INTERNAL_PROVIDER_FLAG2, 3);
+        values.put(TvContract.RecordedPrograms.COLUMN_INTERNAL_PROVIDER_FLAG3, 2);
+        values.put(TvContract.RecordedPrograms.COLUMN_INTERNAL_PROVIDER_FLAG4, 1);
+
+        return values;
+    }
+
     private static void verifyStringColumn(Cursor cursor, ContentValues expectedValues,
             String columnName) {
         if (expectedValues.containsKey(columnName)) {
@@ -252,8 +307,11 @@
             assertEquals(programId, cursor.getLong(cursor.getColumnIndex(TvContract.Programs._ID)));
             verifyLongColumn(cursor, expectedValues, TvContract.Programs.COLUMN_CHANNEL_ID);
             verifyStringColumn(cursor, expectedValues, TvContract.Programs.COLUMN_TITLE);
-            verifyIntegerColumn(cursor, expectedValues, TvContract.Programs.COLUMN_SEASON_NUMBER);
-            verifyIntegerColumn(cursor, expectedValues, TvContract.Programs.COLUMN_EPISODE_NUMBER);
+            verifyStringColumn(cursor, expectedValues,
+                    TvContract.Programs.COLUMN_SEASON_DISPLAY_NUMBER);
+            verifyStringColumn(cursor, expectedValues, TvContract.Programs.COLUMN_SEASON_TITLE);
+            verifyStringColumn(cursor, expectedValues,
+                    TvContract.Programs.COLUMN_EPISODE_DISPLAY_NUMBER);
             verifyStringColumn(cursor, expectedValues, TvContract.Programs.COLUMN_EPISODE_TITLE);
             verifyLongColumn(cursor, expectedValues,
                     TvContract.Programs.COLUMN_START_TIME_UTC_MILLIS);
@@ -276,6 +334,21 @@
         }
     }
 
+    private void verifyDeprecatedColumsInProgram(Uri programUri, ContentValues expectedValues) {
+        final String[] DEPRECATED_COLUMNS_PROJECTION = {
+            TvContract.Programs.COLUMN_SEASON_NUMBER,
+            TvContract.Programs.COLUMN_EPISODE_NUMBER,
+        };
+        try (Cursor cursor = mContentResolver.query(
+                programUri, DEPRECATED_COLUMNS_PROJECTION, null, null, null)) {
+            assertNotNull(cursor);
+            assertEquals(cursor.getCount(), 1);
+            assertTrue(cursor.moveToNext());
+            verifyIntegerColumn(cursor, expectedValues, TvContract.Programs.COLUMN_SEASON_NUMBER);
+            verifyIntegerColumn(cursor, expectedValues, TvContract.Programs.COLUMN_EPISODE_NUMBER);
+        }
+    }
+
     private void verifyLogoIsReadable(Uri logoUri) throws Exception {
         try (AssetFileDescriptor fd = mContentResolver.openAssetFileDescriptor(logoUri, "r")) {
             try (InputStream is = fd.createInputStream()) {
@@ -340,6 +413,45 @@
         }
     }
 
+    public void verifyProgramsTableWithDeprecatedColumns(Uri programsUri, long channelId) {
+        if (!Utils.hasTvInputFramework(getContext())) {
+            return;
+        }
+        // Test: insert
+        ContentValues expected = createDummyProgramValues(channelId);
+        expected.put(TvContract.Programs.COLUMN_SEASON_DISPLAY_NUMBER, "3");
+        expected.put(TvContract.Programs.COLUMN_EPISODE_DISPLAY_NUMBER, "9");
+
+        ContentValues input = new ContentValues(expected);
+        input.remove(TvContract.Programs.COLUMN_SEASON_DISPLAY_NUMBER);
+        input.remove(TvContract.Programs.COLUMN_EPISODE_DISPLAY_NUMBER);
+        input.put(TvContract.Programs.COLUMN_SEASON_NUMBER, 3);
+        input.put(TvContract.Programs.COLUMN_EPISODE_NUMBER, 9);
+
+        Uri rowUri = mContentResolver.insert(programsUri, input);
+        long programId = ContentUris.parseId(rowUri);
+        Uri programUri = TvContract.buildProgramUri(programId);
+        verifyProgram(programUri, expected, programId);
+        verifyDeprecatedColumsInProgram(programUri, input);
+
+        // Test: update
+        expected.put(TvContract.Programs.COLUMN_SEASON_DISPLAY_NUMBER, "4");
+        expected.put(TvContract.Programs.COLUMN_EPISODE_DISPLAY_NUMBER, "10");
+        input.put(TvContract.Programs.COLUMN_SEASON_NUMBER, 4);
+        input.put(TvContract.Programs.COLUMN_EPISODE_NUMBER, 10);
+
+        mContentResolver.update(programUri, input, null, null);
+        verifyProgram(programUri, expected, programId);
+        verifyDeprecatedColumsInProgram(programUri, input);
+
+        // Test: delete
+        mContentResolver.delete(programsUri, null, null);
+        try (Cursor cursor = mContentResolver.query(
+                programsUri, PROGRAMS_PROJECTION, null, null, null)) {
+            assertEquals(0, cursor.getCount());
+        }
+    }
+
     public void testProgramsTable() throws Exception {
         if (!Utils.hasTvInputFramework(getContext())) {
             return;
@@ -351,6 +463,10 @@
 
         verifyProgramsTable(TvContract.buildProgramsUriForChannel(channelId), channelId);
         verifyProgramsTable(TvContract.buildProgramsUriForChannel(channelUri), channelId);
+        verifyProgramsTableWithDeprecatedColumns(TvContract.buildProgramsUriForChannel(channelId),
+                channelId);
+        verifyProgramsTableWithDeprecatedColumns(TvContract.buildProgramsUriForChannel(channelUri),
+                channelId);
     }
 
     private void verifyOverlap(long startMillis, long endMillis, int expectedCount,
@@ -405,6 +521,92 @@
                 channelId, channelUri);
     }
 
+    private void verifyRecordedProgram(Uri recordedProgramUri, ContentValues expectedValues,
+                long recordedProgramId) {
+        try (Cursor cursor = mContentResolver.query(recordedProgramUri, null, null, null, null)) {
+            assertNotNull(cursor);
+            assertEquals(cursor.getCount(), 1);
+            assertTrue(cursor.moveToNext());
+            assertEquals(recordedProgramId, cursor.getLong(cursor.getColumnIndex(
+                    RecordedPrograms._ID)));
+            verifyLongColumn(cursor, expectedValues, RecordedPrograms.COLUMN_CHANNEL_ID);
+            verifyStringColumn(cursor, expectedValues,
+                    RecordedPrograms.COLUMN_SEASON_DISPLAY_NUMBER);
+            verifyStringColumn(cursor, expectedValues, RecordedPrograms.COLUMN_SEASON_TITLE);
+            verifyStringColumn(cursor, expectedValues,
+                    RecordedPrograms.COLUMN_EPISODE_DISPLAY_NUMBER);
+            verifyStringColumn(cursor, expectedValues, RecordedPrograms.COLUMN_EPISODE_TITLE);
+            verifyLongColumn(cursor, expectedValues, RecordedPrograms.COLUMN_START_TIME_UTC_MILLIS);
+            verifyLongColumn(cursor, expectedValues, RecordedPrograms.COLUMN_END_TIME_UTC_MILLIS);
+            verifyStringColumn(cursor, expectedValues, RecordedPrograms.COLUMN_BROADCAST_GENRE);
+            verifyStringColumn(cursor, expectedValues, RecordedPrograms.COLUMN_CANONICAL_GENRE);
+            verifyStringColumn(cursor, expectedValues, RecordedPrograms.COLUMN_SHORT_DESCRIPTION);
+            verifyStringColumn(cursor, expectedValues, RecordedPrograms.COLUMN_LONG_DESCRIPTION);
+            verifyIntegerColumn(cursor, expectedValues, RecordedPrograms.COLUMN_VIDEO_WIDTH);
+            verifyIntegerColumn(cursor, expectedValues, RecordedPrograms.COLUMN_VIDEO_HEIGHT);
+            verifyStringColumn(cursor, expectedValues, RecordedPrograms.COLUMN_AUDIO_LANGUAGE);
+            verifyStringColumn(cursor, expectedValues, RecordedPrograms.COLUMN_CONTENT_RATING);
+            verifyStringColumn(cursor, expectedValues, RecordedPrograms.COLUMN_POSTER_ART_URI);
+            verifyStringColumn(cursor, expectedValues, RecordedPrograms.COLUMN_THUMBNAIL_URI);
+            verifyIntegerColumn(cursor, expectedValues, RecordedPrograms.COLUMN_SEARCHABLE);
+            verifyStringColumn(cursor, expectedValues, RecordedPrograms.COLUMN_RECORDING_DATA_URI);
+            verifyIntegerColumn(cursor, expectedValues,
+                    RecordedPrograms.COLUMN_RECORDING_DATA_BYTES);
+            verifyIntegerColumn(cursor, expectedValues,
+                    RecordedPrograms.COLUMN_RECORDING_DURATION_MILLIS);
+            verifyIntegerColumn(cursor, expectedValues,
+                    RecordedPrograms.COLUMN_RECORDING_EXPIRE_TIME_UTC_MILLIS);
+            verifyBlobColumn(cursor, expectedValues,
+                    RecordedPrograms.COLUMN_INTERNAL_PROVIDER_DATA);
+            verifyIntegerColumn(cursor, expectedValues,
+                    RecordedPrograms.COLUMN_INTERNAL_PROVIDER_FLAG1);
+            verifyIntegerColumn(cursor, expectedValues,
+                    RecordedPrograms.COLUMN_INTERNAL_PROVIDER_FLAG2);
+            verifyIntegerColumn(cursor, expectedValues,
+                    RecordedPrograms.COLUMN_INTERNAL_PROVIDER_FLAG3);
+            verifyIntegerColumn(cursor, expectedValues,
+                    RecordedPrograms.COLUMN_INTERNAL_PROVIDER_FLAG4);
+            verifyIntegerColumn(cursor, expectedValues, RecordedPrograms.COLUMN_VERSION_NUMBER);
+        }
+    }
+
+    private void verifyRecordedProgramsTable(Uri recordedProgramsUri, long channelId) {
+        // Test: insert
+        ContentValues values = createDummyRecordedProgramValues(mInputId, channelId);
+
+        Uri rowUri = mContentResolver.insert(recordedProgramsUri, values);
+        long recordedProgramId = ContentUris.parseId(rowUri);
+        Uri recordedProgramUri = TvContract.buildRecordedProgramUri(recordedProgramId);
+        verifyRecordedProgram(recordedProgramUri, values, recordedProgramId);
+
+        // Test: update
+        values.put(TvContract.RecordedPrograms.COLUMN_EPISODE_TITLE, "episode_title1");
+        values.put(TvContract.RecordedPrograms.COLUMN_SHORT_DESCRIPTION, "short_description1");
+        values.put(TvContract.RecordedPrograms.COLUMN_INTERNAL_PROVIDER_DATA,
+                "internal_provider_data1".getBytes());
+
+        mContentResolver.update(recordedProgramUri, values, null, null);
+        verifyRecordedProgram(recordedProgramUri, values, recordedProgramId);
+
+        // Test: delete
+        mContentResolver.delete(recordedProgramUri, null, null);
+        try (Cursor cursor = mContentResolver.query(recordedProgramsUri, null, null, null, null)) {
+            assertEquals(0, cursor.getCount());
+        }
+    }
+
+    public void testRecordedProgramsTable() throws Exception {
+        if (!Utils.hasTvInputFramework(getContext())) {
+            return;
+        }
+        // Set-up: add a channel.
+        ContentValues values = createDummyChannelValues(mInputId);
+        Uri channelUri = mContentResolver.insert(mChannelsUri, values);
+        long channelId = ContentUris.parseId(channelUri);
+
+        verifyRecordedProgramsTable(TvContract.RecordedPrograms.CONTENT_URI, channelId);
+    }
+
     private void verifyQueryWithSortOrder(Uri uri, final String[] projection,
             String sortOrder) throws Exception {
         try {
@@ -584,4 +786,203 @@
                 Genres.COMEDY, Genres.DRAMA, Genres.EDUCATION, Genres.FAMILY_KIDS, Genres.GAMING,
                 Genres.MOVIES, Genres.NEWS, Genres.SHOPPING, Genres.SPORTS, Genres.TRAVEL));
     }
+
+    public void testProgramsGenresEncodeDecode_empty() {
+        if (!Utils.hasTvInputFramework(getContext())) {
+            return;
+        }
+        String[] genres = new String[] {EMPTY_GENRE};
+        String expectedEncoded = EMPTY_GENRE;
+        checkGenreEncodeDecode(genres, expectedEncoded, 0);
+
+        genres = new String[] {EMPTY_GENRE, EMPTY_GENRE, EMPTY_GENRE};
+        expectedEncoded = DELIMITER + DELIMITER;
+        checkGenreEncodeDecode(genres, expectedEncoded, 0);
+    }
+
+    public void testProgramsGenresEncodeDecode_simpleDelimiter() {
+        if (!Utils.hasTvInputFramework(getContext())) {
+            return;
+        }
+        String[] genres = new String[] {EMPTY_GENRE,
+                COMMA,
+                QUOTE,
+                COMMA + QUOTE,
+                QUOTE + COMMA,
+                COMMA + COMMA,
+                QUOTE + QUOTE,
+                COMMA + QUOTE + COMMA,
+                QUOTE + COMMA + QUOTE};
+        String expectedEncoded =
+                DELIMITER + COMMA_ENCODED
+                + DELIMITER + QUOTE_ENCODED
+                + DELIMITER + COMMA_ENCODED + QUOTE_ENCODED
+                + DELIMITER + QUOTE_ENCODED + COMMA_ENCODED
+                + DELIMITER + COMMA_ENCODED + COMMA_ENCODED
+                + DELIMITER + QUOTE_ENCODED + QUOTE_ENCODED
+                + DELIMITER + COMMA_ENCODED + QUOTE_ENCODED + COMMA_ENCODED
+                + DELIMITER + QUOTE_ENCODED + COMMA_ENCODED + QUOTE_ENCODED;
+        checkGenreEncodeDecode(genres, expectedEncoded, genres.length - 1);
+    }
+
+    public void testProgramsGenresEncodeDecode_delimiterWithWhiteSpace() {
+        if (!Utils.hasTvInputFramework(getContext())) {
+            return;
+        }
+        String[] genres = new String[] {EMPTY_GENRE,
+                COMMA + WHITE_SPACES,
+                QUOTE + WHITE_SPACES,
+                WHITE_SPACES + COMMA,
+                WHITE_SPACES + QUOTE,
+                WHITE_SPACES + COMMA + WHITE_SPACES,
+                WHITE_SPACES + QUOTE + WHITE_SPACES};
+        String expectedEncoded =
+                DELIMITER + COMMA_ENCODED + WHITE_SPACES
+                + DELIMITER + QUOTE_ENCODED + WHITE_SPACES
+                + DELIMITER + WHITE_SPACES + COMMA_ENCODED
+                + DELIMITER + WHITE_SPACES + QUOTE_ENCODED
+                + DELIMITER + WHITE_SPACES + COMMA_ENCODED + WHITE_SPACES
+                + DELIMITER + WHITE_SPACES + QUOTE_ENCODED + WHITE_SPACES;
+        checkGenreEncodeDecode(genres, expectedEncoded, genres.length - 1);
+    }
+
+    public void testProgramsGenresEncodeDecode_all() {
+        if (!Utils.hasTvInputFramework(getContext())) {
+            return;
+        }
+        String[] genres = new String[] {EMPTY_GENRE,
+                Genres.COMEDY,
+                Genres.COMEDY + COMMA,
+                Genres.COMEDY + COMMA + Genres.COMEDY,
+                COMMA + Genres.COMEDY + COMMA,
+                QUOTE + Genres.COMEDY + QUOTE,
+                Genres.COMEDY + COMMA + WHITE_SPACES,
+                Genres.COMEDY + COMMA + Genres.COMEDY + WHITE_SPACES,
+                COMMA + Genres.COMEDY + COMMA + WHITE_SPACES,
+                QUOTE + Genres.COMEDY + QUOTE + WHITE_SPACES
+        };
+        String expectedEncoded =
+                DELIMITER + Genres.COMEDY
+                + DELIMITER + Genres.COMEDY + COMMA_ENCODED
+                + DELIMITER + Genres.COMEDY + COMMA_ENCODED + Genres.COMEDY
+                + DELIMITER + COMMA_ENCODED + Genres.COMEDY + COMMA_ENCODED
+                + DELIMITER + QUOTE_ENCODED + Genres.COMEDY + QUOTE_ENCODED
+                + DELIMITER + Genres.COMEDY + COMMA_ENCODED + WHITE_SPACES
+                + DELIMITER + Genres.COMEDY + COMMA_ENCODED + Genres.COMEDY + WHITE_SPACES
+                + DELIMITER + COMMA_ENCODED + Genres.COMEDY + COMMA_ENCODED + WHITE_SPACES
+                + DELIMITER + QUOTE_ENCODED + Genres.COMEDY + QUOTE_ENCODED + WHITE_SPACES;
+        checkGenreEncodeDecode(genres, expectedEncoded, genres.length - 1);
+    }
+
+    private void checkGenreEncodeDecode(String[] genres, String expectedEncoded,
+            int expectedDecodedLength) {
+        String encoded = Genres.encode(genres);
+        assertEquals(expectedEncoded, encoded);
+        String[] decoded = Genres.decode(encoded);
+        assertEquals(expectedDecodedLength, decoded.length);
+        int decodedIndex = 0;
+        for (int i = 0; i < genres.length; ++i) {
+            String original = genres[i].trim();
+            if (!original.isEmpty()) {
+                assertEquals(original, decoded[decodedIndex++]);
+            }
+        }
+    }
+
+    private Uri insertProgramWithBroadcastGenre(String[] broadcastGenre) {
+        ContentValues values = createDummyChannelValues(mInputId);
+        Uri channelUri = mContentResolver.insert(Channels.CONTENT_URI, values);
+        long channelId = ContentUris.parseId(channelUri);
+        long curTime = System.currentTimeMillis();
+        values = new ContentValues();
+        values.put(TvContract.Programs.COLUMN_CHANNEL_ID, channelId);
+        values.put(TvContract.Programs.COLUMN_BROADCAST_GENRE, Genres.encode(broadcastGenre));
+        values.put(TvContract.Programs.COLUMN_START_TIME_UTC_MILLIS, curTime - 60000);
+        values.put(TvContract.Programs.COLUMN_END_TIME_UTC_MILLIS, curTime + 60000);
+        Uri programUri = mContentResolver.insert(TvContract.Programs.CONTENT_URI, values);
+        assertNotNull(programUri);
+        return programUri;
+    }
+
+    private void verifyChannelCountWithCanonicalGenre(String canonicalGenre, int expectedCount) {
+        Uri channelUri = TvContract.buildChannelsUriForInput(mInputId).buildUpon()
+                .appendQueryParameter(PARAM_CANONICAL_GENRE, canonicalGenre).build();
+        try (Cursor c = mContentResolver.query(channelUri, new String[] {Channels._ID}, null, null,
+                null)) {
+            assertNotNull(c);
+            assertEquals("Query:{Uri=" + channelUri + "}", expectedCount, c.getCount());
+        }
+    }
+
+    public void testBroadcastGenreEncodeDecode() {
+        if (!Utils.hasTvInputFramework(getContext())) {
+            return;
+        }
+        String[] broadcastGenre = new String[] {"Animation", "Classic, opera"};
+        insertProgramWithBroadcastGenre(broadcastGenre);
+        try (Cursor c = mContentResolver.query(TvContract.Programs.CONTENT_URI,
+                new String[] {TvContract.Programs.COLUMN_BROADCAST_GENRE}, null, null, null)) {
+            assertNotNull(c);
+            assertEquals(1, c.getCount());
+            c.moveToNext();
+            MoreAsserts.assertEquals(broadcastGenre, Genres.decode(c.getString(0)));
+        }
+    }
+
+    public void testBroadcastGenreQueryChannel() {
+        if (!Utils.hasTvInputFramework(getContext())) {
+            return;
+        }
+        // "Animation" is mapped to Genres.MOVIES
+        // "Classic, opera" is mapped to Genres.MUSIC
+        insertProgramWithBroadcastGenre(new String[]{"Animation"});
+        insertProgramWithBroadcastGenre(new String[] {"Classic, opera"});
+        insertProgramWithBroadcastGenre(new String[]{"Animation", "Classic, opera"});
+        // There are two channels which belong to MOVIES genre - channel 1 and 3.
+        verifyChannelCountWithCanonicalGenre(Genres.MOVIES, 2);
+        // There are two channels which belong to MUSIC genre - channel 2 and 3.
+        verifyChannelCountWithCanonicalGenre(Genres.MUSIC, 2);
+    }
+
+    public void testGenresIsCanonical() {
+        if (!Utils.hasTvInputFramework(getContext())) {
+            return;
+        }
+        assertTrue(Genres.isCanonical(Genres.DRAMA));
+        assertFalse(Genres.isCanonical("Not a genre"));
+    }
+
+    public void testUriUtils() {
+        if (!Utils.hasTvInputFramework(getContext())) {
+            return;
+        }
+        final Uri CHANNEL_URI_FOR_TUNER = TvContract.buildChannelUri(0);
+        final Uri CHANNEL_URI_FOR_PASSTHROUGH_INPUT =
+                TvContract.buildChannelUriForPassthroughInput("inputId");
+        final Uri PROGRAM_URI = TvContract.buildProgramUri(0);
+
+        // Test isChannelUri
+        assertTrue(TvContract.isChannelUri(CHANNEL_URI_FOR_TUNER));
+        assertTrue(TvContract.isChannelUri(CHANNEL_URI_FOR_PASSTHROUGH_INPUT));
+        assertFalse(TvContract.isChannelUri(PROGRAM_URI));
+        assertFalse(TvContract.isChannelUri(null));
+
+        // Test isChannelUriForPassthroughInput
+        assertFalse(TvContract.isChannelUriForPassthroughInput(CHANNEL_URI_FOR_TUNER));
+        assertTrue(TvContract.isChannelUriForPassthroughInput(CHANNEL_URI_FOR_PASSTHROUGH_INPUT));
+        assertFalse(TvContract.isChannelUriForPassthroughInput(PROGRAM_URI));
+        assertFalse(TvContract.isChannelUriForPassthroughInput(null));
+
+        // Test isChannelUriForTunerInput
+        assertTrue(TvContract.isChannelUriForTunerInput(CHANNEL_URI_FOR_TUNER));
+        assertFalse(TvContract.isChannelUriForTunerInput(CHANNEL_URI_FOR_PASSTHROUGH_INPUT));
+        assertFalse(TvContract.isChannelUriForTunerInput(PROGRAM_URI));
+        assertFalse(TvContract.isChannelUriForTunerInput(null));
+
+        // Test isProgramUri
+        assertFalse(TvContract.isProgramUri(CHANNEL_URI_FOR_TUNER));
+        assertFalse(TvContract.isProgramUri(CHANNEL_URI_FOR_PASSTHROUGH_INPUT));
+        assertTrue(TvContract.isProgramUri(PROGRAM_URI));
+        assertFalse(TvContract.isProgramUri(null));
+    }
 }
diff --git a/tests/tests/tv/src/android/media/tv/cts/TvInputInfoTest.java b/tests/tests/tv/src/android/media/tv/cts/TvInputInfoTest.java
index de91916..76cd550 100644
--- a/tests/tests/tv/src/android/media/tv/cts/TvInputInfoTest.java
+++ b/tests/tests/tv/src/android/media/tv/cts/TvInputInfoTest.java
@@ -23,8 +23,10 @@
 import android.media.tv.TvContract;
 import android.media.tv.TvInputInfo;
 import android.media.tv.TvInputManager;
+import android.os.Bundle;
 import android.os.Parcel;
 import android.test.AndroidTestCase;
+import android.text.TextUtils;
 
 /**
  * Test for {@link android.media.tv.TvInputInfo}.
@@ -33,6 +35,22 @@
     private TvInputInfo mStubInfo;
     private PackageManager mPackageManager;
 
+    public static boolean compareTvInputInfos(Context context, TvInputInfo info1,
+            TvInputInfo info2) {
+        return TextUtils.equals(info1.getId(), info2.getId())
+                && TextUtils.equals(info1.getParentId(), info2.getParentId())
+                && TextUtils.equals(info1.getServiceInfo().packageName,
+                        info2.getServiceInfo().packageName)
+                && TextUtils.equals(info1.getServiceInfo().name, info2.getServiceInfo().name)
+                && TextUtils.equals(info1.createSetupIntent().toString(),
+                         info2.createSetupIntent().toString())
+                && info1.getType() == info2.getType()
+                && info1.getTunerCount() == info2.getTunerCount()
+                && info1.canRecord() == info2.canRecord()
+                && info1.isPassthroughInput() == info2.isPassthroughInput()
+                && TextUtils.equals(info1.loadLabel(context), info2.loadLabel(context));
+    }
+
     @Override
     public void setUp() throws Exception {
         if (!Utils.hasTvInputFramework(getContext())) {
@@ -83,7 +101,8 @@
         assertEquals(mStubInfo.createSetupIntent().getComponent(),
                 infoFromParcel.createSetupIntent().getComponent());
         assertEquals(mStubInfo.describeContents(), infoFromParcel.describeContents());
-        assertTrue(mStubInfo.equals(infoFromParcel));
+        assertTrue("expected=" + mStubInfo + " actual=" + infoFromParcel,
+                TvInputInfoTest.compareTvInputInfos(getContext(), mStubInfo, infoFromParcel));
         assertEquals(mStubInfo.getId(), infoFromParcel.getId());
         assertEquals(mStubInfo.getParentId(), infoFromParcel.getParentId());
         assertEquals(mStubInfo.getServiceInfo().name, infoFromParcel.getServiceInfo().name);
@@ -157,4 +176,43 @@
         assertEquals(mStubInfo.loadLabel(getContext()),
                 mStubInfo.getServiceInfo().loadLabel(mPackageManager));
     }
+
+    public void testIsHidden() throws Exception {
+        if (!Utils.hasTvInputFramework(getContext())) {
+            return;
+        }
+        assertFalse(mStubInfo.isHidden(getContext()));
+    }
+
+    public void testLoadCustomLabel() throws Exception {
+        if (!Utils.hasTvInputFramework(getContext())) {
+            return;
+        }
+        assertNull(mStubInfo.loadCustomLabel(getContext()));
+    }
+
+    public void testBuilder() throws Exception {
+        if (!Utils.hasTvInputFramework(getContext())) {
+            return;
+        }
+        TvInputInfo defaultInfo = new TvInputInfo.Builder(getContext(),
+                new ComponentName(getContext(), StubTunerTvInputService.class)).build();
+        assertEquals(1, defaultInfo.getTunerCount());
+        assertFalse(defaultInfo.canRecord());
+        assertEquals(mStubInfo.getId(), defaultInfo.getId());
+        assertEquals(mStubInfo.getTunerCount(), defaultInfo.getTunerCount());
+        assertEquals(mStubInfo.canRecord(), defaultInfo.canRecord());
+
+        Bundle extras = new Bundle();
+        final String TEST_KEY = "android.media.tv.cts.TEST_KEY";
+        final String TEST_VALUE = "android.media.tv.cts.TEST_VALUE";
+        extras.putString(TEST_KEY, TEST_VALUE);
+        TvInputInfo updatedInfo = new TvInputInfo.Builder(getContext(),
+                new ComponentName(getContext(), StubTunerTvInputService.class)).setTunerCount(10)
+                .setCanRecord(true).setExtras(extras).build();
+        assertEquals(mStubInfo.getId(), updatedInfo.getId());
+        assertEquals(10, updatedInfo.getTunerCount());
+        assertTrue(updatedInfo.canRecord());
+        assertEquals(TEST_VALUE, updatedInfo.getExtras().getString(TEST_KEY));
+    }
 }
diff --git a/tests/tests/tv/src/android/media/tv/cts/TvInputManagerTest.java b/tests/tests/tv/src/android/media/tv/cts/TvInputManagerTest.java
index ff66dc6..3d04c0c 100644
--- a/tests/tests/tv/src/android/media/tv/cts/TvInputManagerTest.java
+++ b/tests/tests/tv/src/android/media/tv/cts/TvInputManagerTest.java
@@ -23,12 +23,16 @@
 import android.media.tv.TvContentRating;
 import android.media.tv.TvInputInfo;
 import android.media.tv.TvInputManager;
+import android.media.tv.TvInputService;
 import android.os.Handler;
 import android.test.ActivityInstrumentationTestCase2;
 
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 
+import org.xmlpull.v1.XmlPullParserException;
+
 /**
  * Test for {@link android.media.tv.TvInputManager}.
  */
@@ -47,7 +51,7 @@
 
     private String mStubId;
     private TvInputManager mManager;
-    private LoggingCallback mCallabck = new LoggingCallback();
+    private LoggingCallback mCallback = new LoggingCallback();
 
     private static TvInputInfo getInfoForClassName(List<TvInputInfo> list, String name) {
         for (TvInputInfo info : list) {
@@ -83,8 +87,11 @@
         if (!Utils.hasTvInputFramework(getActivity())) {
             return;
         }
-        assertEquals(mManager.getTvInputInfo(mStubId), getInfoForClassName(
-                mManager.getTvInputList(), StubTvInputService2.class.getName()));
+        TvInputInfo expected = mManager.getTvInputInfo(mStubId);
+        TvInputInfo actual = getInfoForClassName(mManager.getTvInputList(),
+                StubTvInputService2.class.getName());
+        assertTrue("expected=" + expected + " actual=" + actual,
+                TvInputInfoTest.compareTvInputInfos(getActivity(), expected, actual));
     }
 
     public void testGetTvInputList() throws Exception {
@@ -132,8 +139,8 @@
             @Override
             public void run() {
                 try {
-                    mManager.registerCallback(mCallabck, new Handler());
-                    mManager.unregisterCallback(mCallabck);
+                    mManager.registerCallback(mCallback, new Handler());
+                    mManager.unregisterCallback(mCallback);
                 } catch (Exception e) {
                     fail();
                 }
@@ -149,13 +156,13 @@
         getActivity().runOnUiThread(new Runnable() {
             @Override
             public void run() {
-                mManager.registerCallback(mCallabck, new Handler());
+                mManager.registerCallback(mCallback, new Handler());
             }
         });
         getInstrumentation().waitForIdleSync();
 
         // Test if onInputRemoved() is called.
-        mCallabck.resetLogs();
+        mCallback.resetLogs();
         PackageManager pm = getActivity().getPackageManager();
         ComponentName component = new ComponentName(getActivity(), StubTvInputService2.class);
         assertTrue(PackageManager.COMPONENT_ENABLED_STATE_DISABLED != pm.getComponentEnabledSetting(
@@ -165,12 +172,12 @@
         new PollingCheck(TIME_OUT_MS) {
             @Override
             protected boolean check() {
-                return mCallabck.isInputRemoved(mStubId);
+                return mCallback.isInputRemoved(mStubId);
             }
         }.run();
 
         // Test if onInputAdded() is called.
-        mCallabck.resetLogs();
+        mCallback.resetLogs();
         assertEquals(PackageManager.COMPONENT_ENABLED_STATE_DISABLED, pm.getComponentEnabledSetting(
                 component));
         pm.setComponentEnabledSetting(component, PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
@@ -178,14 +185,60 @@
         new PollingCheck(TIME_OUT_MS) {
             @Override
             protected boolean check() {
-                return mCallabck.isInputAdded(mStubId);
+                return mCallback.isInputAdded(mStubId);
             }
         }.run();
 
         getActivity().runOnUiThread(new Runnable() {
             @Override
             public void run() {
-                mManager.unregisterCallback(mCallabck);
+                mManager.unregisterCallback(mCallback);
+            }
+        });
+        getInstrumentation().waitForIdleSync();
+    }
+
+    public void testTvInputInfoUpdated() throws IOException, XmlPullParserException {
+        if (!Utils.hasTvInputFramework(getActivity())) {
+            return;
+        }
+        getActivity().runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mManager.registerCallback(mCallback, new Handler());
+            }
+        });
+        getInstrumentation().waitForIdleSync();
+
+        mCallback.resetLogs();
+        TvInputInfo defaultInfo = new TvInputInfo.Builder(getActivity(),
+                new ComponentName(getActivity(), StubTunerTvInputService.class)).build();
+        TvInputInfo updatedInfo = new TvInputInfo.Builder(getActivity(),
+                new ComponentName(getActivity(), StubTunerTvInputService.class))
+                        .setTunerCount(10).setCanRecord(true).build();
+
+        TvInputService.updateTvInputInfo(getActivity(), updatedInfo);
+        new PollingCheck(TIME_OUT_MS) {
+            @Override
+            protected boolean check() {
+                TvInputInfo info = mCallback.getLastUpdatedTvInputInfo();
+                return info !=  null && info.getTunerCount() == 10 && info.canRecord();
+            }
+        }.run();
+
+        TvInputService.updateTvInputInfo(getActivity(), defaultInfo);
+        new PollingCheck(TIME_OUT_MS) {
+            @Override
+            protected boolean check() {
+                TvInputInfo info = mCallback.getLastUpdatedTvInputInfo();
+                return info !=  null && info.getTunerCount() == 1 && !info.canRecord();
+            }
+        }.run();
+
+        getActivity().runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mManager.unregisterCallback(mCallback);
             }
         });
         getInstrumentation().waitForIdleSync();
@@ -194,6 +247,7 @@
     private static class LoggingCallback extends TvInputManager.TvInputCallback {
         private final List<String> mAddedInputs = new ArrayList<>();
         private final List<String> mRemovedInputs = new ArrayList<>();
+        private TvInputInfo mLastUpdatedTvInputInfo;
 
         @Override
         public synchronized void onInputAdded(String inputId) {
@@ -205,9 +259,15 @@
             mRemovedInputs.add(inputId);
         }
 
+        @Override
+        public synchronized void onTvInputInfoUpdated(TvInputInfo info) {
+            mLastUpdatedTvInputInfo = info;
+        }
+
         public synchronized void resetLogs() {
             mAddedInputs.clear();
             mRemovedInputs.clear();
+            mLastUpdatedTvInputInfo = null;
         }
 
         public synchronized boolean isInputAdded(String inputId) {
@@ -219,6 +279,10 @@
             return mAddedInputs.isEmpty() && mRemovedInputs.size() == 1 && mRemovedInputs.contains(
                     inputId);
         }
+
+        public synchronized TvInputInfo getLastUpdatedTvInputInfo() {
+            return mLastUpdatedTvInputInfo;
+        }
     }
 
     public static class StubTvInputService2 extends StubTvInputService {
diff --git a/tests/tests/tv/src/android/media/tv/cts/TvInputServiceTest.java b/tests/tests/tv/src/android/media/tv/cts/TvInputServiceTest.java
index b4c863a..47b5527 100644
--- a/tests/tests/tv/src/android/media/tv/cts/TvInputServiceTest.java
+++ b/tests/tests/tv/src/android/media/tv/cts/TvInputServiceTest.java
@@ -25,12 +25,16 @@
 import android.media.tv.TvContract;
 import android.media.tv.TvInputInfo;
 import android.media.tv.TvInputManager;
+import android.media.tv.TvRecordingClient;
 import android.media.tv.TvTrackInfo;
 import android.media.tv.TvView;
 import android.media.tv.cts.TvInputServiceTest.CountingTvInputService.CountingSession;
+import android.media.tv.cts.TvInputServiceTest.CountingTvInputService.CountingRecordingSession;
 import android.net.Uri;
+import android.os.Bundle;
 import android.os.SystemClock;
 import android.test.ActivityInstrumentationTestCase2;
+import android.text.TextUtils;
 import android.view.InputDevice;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
@@ -39,10 +43,13 @@
 import android.view.View;
 import android.widget.LinearLayout;
 
-import com.android.cts.tv.R;
+import android.tv.cts.R;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
+import java.util.Objects;
+import java.util.Set;
 
 
 /**
@@ -51,19 +58,23 @@
 public class TvInputServiceTest extends ActivityInstrumentationTestCase2<TvViewStubActivity> {
     /** The maximum time to wait for an operation. */
     private static final long TIME_OUT = 15000L;
-    private static final String mDummyTrackId = "dummyTrackId";
-    private static final TvTrackInfo mDummyTrack =
-            new TvTrackInfo.Builder(TvTrackInfo.TYPE_VIDEO, mDummyTrackId)
+    private static final String DUMMT_TRACK_ID = "dummyTrackId";
+    private static final TvTrackInfo DUMMY_TRACK =
+            new TvTrackInfo.Builder(TvTrackInfo.TYPE_VIDEO, DUMMT_TRACK_ID)
             .setVideoWidth(1920).setVideoHeight(1080).setLanguage("und").build();
+    private static Bundle sDummyBundle;
 
     private TvView mTvView;
+    private TvRecordingClient mTvRecordingClient;
     private Activity mActivity;
     private Instrumentation mInstrumentation;
     private TvInputManager mManager;
     private TvInputInfo mStubInfo;
+    private TvInputInfo mFaultyStubInfo;
     private final StubCallback mCallback = new StubCallback();
     private final StubTimeShiftPositionCallback mTimeShiftPositionCallback =
             new StubTimeShiftPositionCallback();
+    private final StubRecordingCallback mRecordingCallback = new StubRecordingCallback();
 
     private static class StubCallback extends TvView.TvInputCallback {
         private int mChannelRetunedCount;
@@ -76,9 +87,18 @@
         private int mContentBlockedCount;
         private int mTimeShiftStatusChangedCount;
 
+        private Uri mChannelRetunedUri;
+        private Integer mVideoUnavailableReason;
+        private Integer mTrackSelectedType;
+        private String mTrackSelectedTrackId;
+        private List<TvTrackInfo> mTracksChangedTrackList;
+        private TvContentRating mContentBlockedRating;
+        private Integer mTimeShiftStatusChangedStatus;
+
         @Override
         public void onChannelRetuned(String inputId, Uri channelUri) {
             mChannelRetunedCount++;
+            mChannelRetunedUri = channelUri;
         }
 
         @Override
@@ -89,16 +109,20 @@
         @Override
         public void onVideoUnavailable(String inputId, int reason) {
             mVideoUnavailableCount++;
+            mVideoUnavailableReason = reason;
         }
 
         @Override
         public void onTrackSelected(String inputId, int type, String trackId) {
             mTrackSelectedCount++;
+            mTrackSelectedType = type;
+            mTrackSelectedTrackId = trackId;
         }
 
         @Override
         public void onTracksChanged(String inputId, List<TvTrackInfo> trackList) {
             mTrackChangedCount++;
+            mTracksChangedTrackList = trackList;
         }
 
         @Override
@@ -114,11 +138,13 @@
         @Override
         public void onContentBlocked(String inputId, TvContentRating rating) {
             mContentBlockedCount++;
+            mContentBlockedRating = rating;
         }
 
         @Override
         public void onTimeShiftStatusChanged(String inputId, int status) {
             mTimeShiftStatusChangedCount++;
+            mTimeShiftStatusChangedStatus = status;
         }
 
         public void resetCounts() {
@@ -131,6 +157,16 @@
             mContentBlockedCount = 0;
             mTimeShiftStatusChangedCount = 0;
         }
+
+        public void resetPassedValues() {
+            mChannelRetunedUri = null;
+            mVideoUnavailableReason = null;
+            mTrackSelectedType = null;
+            mTrackSelectedTrackId = null;
+            mTracksChangedTrackList = null;
+            mContentBlockedRating = null;
+            mTimeShiftStatusChangedStatus = null;
+        }
     }
 
     private static class StubTimeShiftPositionCallback extends TvView.TimeShiftPositionCallback {
@@ -166,10 +202,17 @@
         mActivity = getActivity();
         mInstrumentation = getInstrumentation();
         mTvView = (TvView) mActivity.findViewById(R.id.tvview);
+        mTvRecordingClient = new TvRecordingClient(mActivity, "TvInputServiceTest",
+                mRecordingCallback, null);
         mManager = (TvInputManager) mActivity.getSystemService(Context.TV_INPUT_SERVICE);
         for (TvInputInfo info : mManager.getTvInputList()) {
             if (info.getServiceInfo().name.equals(CountingTvInputService.class.getName())) {
                 mStubInfo = info;
+            }
+            if (info.getServiceInfo().name.equals(FaultyTvInputService.class.getName())) {
+                mFaultyStubInfo = info;
+            }
+            if (mStubInfo != null && mFaultyStubInfo != null) {
                 break;
             }
         }
@@ -179,11 +222,14 @@
         CountingTvInputService.sSession = null;
     }
 
-    public void testTvInputService() throws Throwable {
+    public void testTvInputServiceSession() throws Throwable {
         if (!Utils.hasTvInputFramework(getActivity())) {
             return;
         }
+        initDummyBundle();
         verifyCommandTune();
+        verifyCommandTuneWithBundle();
+        verifyCommandSendAppPrivateCommand();
         verifyCommandSetStreamVolume();
         verifyCommandSetCaptionEnabled();
         verifyCommandSelectTrack();
@@ -197,6 +243,7 @@
         verifyCommandTimeShiftResume();
         verifyCommandTimeShiftSeekTo();
         verifyCommandTimeShiftSetPlaybackParams();
+        verifyCommandTimeShiftPlay();
         verifyCommandSetTimeShiftPositionCallback();
         verifyCommandOverlayViewSizeChanged();
         verifyCallbackChannelRetuned();
@@ -204,6 +251,7 @@
         verifyCallbackVideoUnavailable();
         verifyCallbackTracksChanged();
         verifyCallbackTrackSelected();
+        verifyCallbackVideoSizeChanged();
         verifyCallbackContentAllowed();
         verifyCallbackContentBlocked();
         verifyCallbackTimeShiftStatusChanged();
@@ -218,102 +266,338 @@
         mInstrumentation.waitForIdleSync();
     }
 
+    public void testTvInputServiceRecordingSession() throws Throwable {
+        if (!Utils.hasTvInputFramework(getActivity())) {
+            return;
+        }
+        initDummyBundle();
+        verifyCommandTuneForRecording();
+        verifyCallbackConnectionFailed();
+        verifyCommandTuneForRecordingWithBundle();
+        verifyCallbackTuned();
+        verifyCommandStartRecording();
+        verifyCommandStopRecording();
+        verifyCommandSendAppPrivateCommandForRecording();
+        verifyCallbackRecordingStopped();
+        verifyCallbackError();
+        verifyCommandRelease();
+        verifyCallbackDisconnected();
+    }
+
+    public void verifyCommandTuneForRecording() {
+        resetCounts();
+        resetPassedValues();
+        final Uri fakeChannelUri = TvContract.buildChannelUri(0);
+        mTvRecordingClient.tune(mStubInfo.getId(), fakeChannelUri);
+        new PollingCheck(TIME_OUT) {
+            @Override
+            protected boolean check() {
+                final CountingRecordingSession session = CountingTvInputService.sRecordingSession;
+                return session != null && session.mTuneCount > 0
+                        && Objects.equals(session.mTunedChannelUri, fakeChannelUri);
+            }
+        }.run();
+    }
+
+    public void verifyCommandTuneForRecordingWithBundle() {
+        resetCounts();
+        resetPassedValues();
+        final Uri fakeChannelUri = TvContract.buildChannelUri(0);
+        mTvRecordingClient.tune(mStubInfo.getId(), fakeChannelUri, sDummyBundle);
+        new PollingCheck(TIME_OUT) {
+            @Override
+            protected boolean check() {
+                final CountingRecordingSession session = CountingTvInputService.sRecordingSession;
+                return session != null
+                        && session.mTuneCount > 0
+                        && session.mTuneWithBundleCount > 0
+                        && Objects.equals(session.mTunedChannelUri, fakeChannelUri)
+                        && bundleEquals(session.mTuneWithBundleData, sDummyBundle);
+            }
+        }.run();
+    }
+
+    public void verifyCommandRelease() {
+        resetCounts();
+        mTvRecordingClient.release();
+        new PollingCheck(TIME_OUT) {
+            @Override
+            protected boolean check() {
+                final CountingRecordingSession session = CountingTvInputService.sRecordingSession;
+                return session != null && session.mReleaseCount > 0;
+            }
+        }.run();
+    }
+
+    public void verifyCommandStartRecording() {
+        resetCounts();
+        resetPassedValues();
+        final Uri fakeChannelUri = TvContract.buildChannelUri(0);
+        mTvRecordingClient.startRecording(fakeChannelUri);
+        new PollingCheck(TIME_OUT) {
+            @Override
+            protected boolean check() {
+                final CountingRecordingSession session = CountingTvInputService.sRecordingSession;
+                return session != null
+                        && session.mStartRecordingCount > 0
+                        && Objects.equals(session.mProgramHint, fakeChannelUri);
+            }
+        }.run();
+    }
+
+    public void verifyCommandStopRecording() {
+        resetCounts();
+        mTvRecordingClient.stopRecording();
+        new PollingCheck(TIME_OUT) {
+            @Override
+            protected boolean check() {
+                final CountingRecordingSession session = CountingTvInputService.sRecordingSession;
+                return session != null && session.mStopRecordingCount > 0;
+            }
+        }.run();
+    }
+
+    public void verifyCommandSendAppPrivateCommandForRecording() {
+        resetCounts();
+        resetPassedValues();
+        final String action = "android.media.tv.cts.TvInputServiceTest.privateCommand";
+        mTvRecordingClient.sendAppPrivateCommand(action, sDummyBundle);
+        new PollingCheck(TIME_OUT) {
+            @Override
+            protected boolean check() {
+                final CountingRecordingSession session = CountingTvInputService.sRecordingSession;
+                return session != null
+                        && session.mAppPrivateCommandCount > 0
+                        && bundleEquals(session.mAppPrivateCommandData, sDummyBundle)
+                        && TextUtils.equals(session.mAppPrivateCommandAction, action);
+            }
+        }.run();
+    }
+
+    public void verifyCallbackTuned() {
+        resetCounts();
+        resetPassedValues();
+        final CountingRecordingSession session = CountingTvInputService.sRecordingSession;
+        assertNotNull(session);
+        final Uri fakeChannelUri = TvContract.buildChannelUri(0);
+        session.notifyTuned(fakeChannelUri);
+        new PollingCheck(TIME_OUT) {
+            @Override
+            protected boolean check() {
+                return mRecordingCallback.mTunedCount > 0
+                        && Objects.equals(mRecordingCallback.mTunedChannelUri, fakeChannelUri);
+            }
+        }.run();
+    }
+
+    public void verifyCallbackError() {
+        resetCounts();
+        resetPassedValues();
+        final CountingRecordingSession session = CountingTvInputService.sRecordingSession;
+        assertNotNull(session);
+        final int error = TvInputManager.RECORDING_ERROR_UNKNOWN;
+        session.notifyError(error);
+        new PollingCheck(TIME_OUT) {
+            @Override
+            protected boolean check() {
+                return mRecordingCallback.mErrorCount > 0
+                        && mRecordingCallback.mError == error;
+            }
+        }.run();
+    }
+
+    public void verifyCallbackRecordingStopped() {
+        resetCounts();
+        resetPassedValues();
+        final CountingRecordingSession session = CountingTvInputService.sRecordingSession;
+        assertNotNull(session);
+        final Uri fakeChannelUri = TvContract.buildChannelUri(0);
+        session.notifyRecordingStopped(fakeChannelUri);
+        new PollingCheck(TIME_OUT) {
+            @Override
+            protected boolean check() {
+                return mRecordingCallback.mRecordingStoppedCount > 0
+                        && Objects.equals(mRecordingCallback.mRecordedProgramUri, fakeChannelUri);
+            }
+        }.run();
+    }
+
+    public void verifyCallbackConnectionFailed() {
+        resetCounts();
+        final Uri fakeChannelUri = TvContract.buildChannelUri(0);
+        mTvRecordingClient.tune("invalid_input_id", fakeChannelUri);
+        new PollingCheck(TIME_OUT) {
+            @Override
+            protected boolean check() {
+                return mRecordingCallback.mConnectionFailedCount > 0;
+            }
+        }.run();
+    }
+
+    public void verifyCallbackDisconnected() {
+        resetCounts();
+        final Uri fakeChannelUri = TvContract.buildChannelUri(0);
+        mTvRecordingClient.tune(mFaultyStubInfo.getId(), fakeChannelUri);
+        new PollingCheck(TIME_OUT) {
+            @Override
+            protected boolean check() {
+                return mRecordingCallback.mDisconnectedCount > 0;
+            }
+        }.run();
+    }
+
     public void verifyCommandTune() {
-        Uri fakeChannelUri = TvContract.buildChannelUri(0);
+        resetCounts();
+        resetPassedValues();
+        final Uri fakeChannelUri = TvContract.buildChannelUri(0);
         mTvView.tune(mStubInfo.getId(), fakeChannelUri);
         mInstrumentation.waitForIdleSync();
         new PollingCheck(TIME_OUT) {
             @Override
             protected boolean check() {
-                CountingSession session = CountingTvInputService.sSession;
-                return session != null && session.mTuneCount > 0 && session.mCreateOverlayView > 0;
+                final CountingSession session = CountingTvInputService.sSession;
+                return session != null
+                        && session.mTuneCount > 0
+                        && session.mCreateOverlayView > 0
+                        && Objects.equals(session.mTunedChannelUri, fakeChannelUri);
+            }
+        }.run();
+    }
+
+    public void verifyCommandTuneWithBundle() {
+        resetCounts();
+        resetPassedValues();
+        final Uri fakeChannelUri = TvContract.buildChannelUri(0);
+        mTvView.tune(mStubInfo.getId(), fakeChannelUri, sDummyBundle);
+        mInstrumentation.waitForIdleSync();
+        new PollingCheck(TIME_OUT) {
+            @Override
+            protected boolean check() {
+                final CountingSession session = CountingTvInputService.sSession;
+                return session != null
+                        && session.mTuneCount > 0
+                        && session.mTuneWithBundleCount > 0
+                        && Objects.equals(session.mTunedChannelUri, fakeChannelUri)
+                        && bundleEquals(session.mTuneWithBundleData, sDummyBundle);
             }
         }.run();
     }
 
     public void verifyCommandSetStreamVolume() {
         resetCounts();
-        mTvView.setStreamVolume(1.0f);
+        resetPassedValues();
+        final float volume = 0.8f;
+        mTvView.setStreamVolume(volume);
         mInstrumentation.waitForIdleSync();
         new PollingCheck(TIME_OUT) {
             @Override
             protected boolean check() {
-                CountingSession session = CountingTvInputService.sSession;
-                return session != null && session.mSetStreamVolumeCount > 0;
+                final CountingSession session = CountingTvInputService.sSession;
+                return session != null && session.mSetStreamVolumeCount > 0
+                        && session.mStreamVolume == volume;
             }
         }.run();
     }
 
     public void verifyCommandSetCaptionEnabled() {
         resetCounts();
-        mTvView.setCaptionEnabled(true);
+        resetPassedValues();
+        final boolean enable = true;
+        mTvView.setCaptionEnabled(enable);
         mInstrumentation.waitForIdleSync();
         new PollingCheck(TIME_OUT) {
             @Override
             protected boolean check() {
-                CountingSession session = CountingTvInputService.sSession;
-                return session != null && session.mSetCaptionEnabledCount > 0;
+                final CountingSession session = CountingTvInputService.sSession;
+                return session != null && session.mSetCaptionEnabledCount > 0
+                        && session.mCaptionEnabled == enable;
             }
         }.run();
     }
 
     public void verifyCommandSelectTrack() {
         resetCounts();
+        resetPassedValues();
         verifyCallbackTracksChanged();
-        mTvView.selectTrack(mDummyTrack.getType(), mDummyTrack.getId());
+        final int dummyTrackType = DUMMY_TRACK.getType();
+        final String dummyTrackId = DUMMY_TRACK.getId();
+        mTvView.selectTrack(dummyTrackType, dummyTrackId);
         mInstrumentation.waitForIdleSync();
         new PollingCheck(TIME_OUT) {
             @Override
             protected boolean check() {
-                CountingSession session = CountingTvInputService.sSession;
-                return session != null && session.mSelectTrackCount > 0;
+                final CountingSession session = CountingTvInputService.sSession;
+                return session != null
+                        && session.mSelectTrackCount > 0
+                        && session.mSelectTrackType == dummyTrackType
+                        && TextUtils.equals(session.mSelectTrackId, dummyTrackId);
             }
         }.run();
     }
 
     public void verifyCommandDispatchKeyDown() {
         resetCounts();
-        mTvView.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_K));
+        resetPassedValues();
+        final int keyCode = KeyEvent.KEYCODE_Q;
+        final KeyEvent event = new KeyEvent(KeyEvent.ACTION_DOWN, keyCode);
+        mTvView.dispatchKeyEvent(event);
         mInstrumentation.waitForIdleSync();
         new PollingCheck(TIME_OUT) {
             @Override
             protected boolean check() {
-                CountingSession session = CountingTvInputService.sSession;
-                return session != null && session.mKeyDownCount > 0;
+                final CountingSession session = CountingTvInputService.sSession;
+                return session != null
+                        && session.mKeyDownCount > 0
+                        && session.mKeyDownCode == keyCode
+                        && keyEventEquals(event, session.mKeyDownEvent);
             }
         }.run();
     }
 
     public void verifyCommandDispatchKeyMultiple() {
         resetCounts();
-        mTvView.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_MULTIPLE, KeyEvent.KEYCODE_K));
+        resetPassedValues();
+        final int keyCode = KeyEvent.KEYCODE_Q;
+        final KeyEvent event = new KeyEvent(KeyEvent.ACTION_MULTIPLE, keyCode);
+        mTvView.dispatchKeyEvent(event);
         mInstrumentation.waitForIdleSync();
         new PollingCheck(TIME_OUT) {
             @Override
             protected boolean check() {
-                CountingSession session = CountingTvInputService.sSession;
-                return session != null && session.mKeyMultipleCount > 0;
+                final CountingSession session = CountingTvInputService.sSession;
+                return session != null
+                        && session.mKeyMultipleCount > 0
+                        && session.mKeyMultipleCode == keyCode
+                        && keyEventEquals(event, session.mKeyMultipleEvent)
+                        && session.mKeyMultipleNumber == event.getRepeatCount();
             }
         }.run();
     }
 
     public void verifyCommandDispatchKeyUp() {
         resetCounts();
-        mTvView.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_K));
+        resetPassedValues();
+        final int keyCode = KeyEvent.KEYCODE_Q;
+        final KeyEvent event = new KeyEvent(KeyEvent.ACTION_UP, keyCode);
+        mTvView.dispatchKeyEvent(event);
         mInstrumentation.waitForIdleSync();
         new PollingCheck(TIME_OUT) {
             @Override
             protected boolean check() {
-                CountingSession session = CountingTvInputService.sSession;
-                return session != null && session.mKeyUpCount > 0;
+                final CountingSession session = CountingTvInputService.sSession;
+                return session != null
+                        && session.mKeyUpCount > 0
+                        && session.mKeyUpCode == keyCode
+                        && keyEventEquals(event, session.mKeyUpEvent);
             }
         }.run();
     }
 
     public void verifyCommandDispatchTouchEvent() {
         resetCounts();
-        long now = SystemClock.uptimeMillis();
-        MotionEvent event = MotionEvent.obtain(now, now, MotionEvent.ACTION_DOWN, 1.0f, 1.0f,
+        resetPassedValues();
+        final long now = SystemClock.uptimeMillis();
+        final MotionEvent event = MotionEvent.obtain(now, now, MotionEvent.ACTION_DOWN, 1.0f, 1.0f,
                 1.0f, 1.0f, 0, 1.0f, 1.0f, 0, 0);
         event.setSource(InputDevice.SOURCE_TOUCHSCREEN);
         mTvView.dispatchTouchEvent(event);
@@ -321,16 +605,19 @@
         new PollingCheck(TIME_OUT) {
             @Override
             protected boolean check() {
-                CountingSession session = CountingTvInputService.sSession;
-                return session != null && session.mTouchEventCount > 0;
+                final CountingSession session = CountingTvInputService.sSession;
+                return session != null
+                        && session.mTouchEventCount > 0
+                        && motionEventEquals(session.mTouchEvent, event);
             }
         }.run();
     }
 
     public void verifyCommandDispatchTrackballEvent() {
         resetCounts();
-        long now = SystemClock.uptimeMillis();
-        MotionEvent event = MotionEvent.obtain(now, now, MotionEvent.ACTION_DOWN, 1.0f, 1.0f,
+        resetPassedValues();
+        final long now = SystemClock.uptimeMillis();
+        final MotionEvent event = MotionEvent.obtain(now, now, MotionEvent.ACTION_DOWN, 1.0f, 1.0f,
                 1.0f, 1.0f, 0, 1.0f, 1.0f, 0, 0);
         event.setSource(InputDevice.SOURCE_TRACKBALL);
         mTvView.dispatchTouchEvent(event);
@@ -338,24 +625,29 @@
         new PollingCheck(TIME_OUT) {
             @Override
             protected boolean check() {
-                CountingSession session = CountingTvInputService.sSession;
-                return session != null && session.mTrackballEventCount > 0;
+                final CountingSession session = CountingTvInputService.sSession;
+                return session != null
+                        && session.mTrackballEventCount > 0
+                        && motionEventEquals(session.mTrackballEvent, event);
             }
         }.run();
     }
 
     public void verifyCommandDispatchGenericMotionEvent() {
         resetCounts();
-        long now = SystemClock.uptimeMillis();
-        MotionEvent event = MotionEvent.obtain(now, now, MotionEvent.ACTION_DOWN, 1.0f, 1.0f,
+        resetPassedValues();
+        final long now = SystemClock.uptimeMillis();
+        final MotionEvent event = MotionEvent.obtain(now, now, MotionEvent.ACTION_DOWN, 1.0f, 1.0f,
                 1.0f, 1.0f, 0, 1.0f, 1.0f, 0, 0);
         mTvView.dispatchGenericMotionEvent(event);
         mInstrumentation.waitForIdleSync();
         new PollingCheck(TIME_OUT) {
             @Override
             protected boolean check() {
-                CountingSession session = CountingTvInputService.sSession;
-                return session != null && session.mGenricMotionEventCount > 0;
+                final CountingSession session = CountingTvInputService.sSession;
+                return session != null
+                        && session.mGenricMotionEventCount > 0
+                        && motionEventEquals(session.mGenricMotionEvent, event);
             }
         }.run();
     }
@@ -367,7 +659,7 @@
         new PollingCheck(TIME_OUT) {
             @Override
             protected boolean check() {
-                CountingSession session = CountingTvInputService.sSession;
+                final CountingSession session = CountingTvInputService.sSession;
                 return session != null && session.mTimeShiftPauseCount > 0;
             }
         }.run();
@@ -380,7 +672,7 @@
         new PollingCheck(TIME_OUT) {
             @Override
             protected boolean check() {
-                CountingSession session = CountingTvInputService.sSession;
+                final CountingSession session = CountingTvInputService.sSession;
                 return session != null && session.mTimeShiftResumeCount > 0;
             }
         }.run();
@@ -388,27 +680,49 @@
 
     public void verifyCommandTimeShiftSeekTo() {
         resetCounts();
-        mTvView.timeShiftSeekTo(0);
+        resetPassedValues();
+        final long timeMs = 0;
+        mTvView.timeShiftSeekTo(timeMs);
         mInstrumentation.waitForIdleSync();
         new PollingCheck(TIME_OUT) {
             @Override
             protected boolean check() {
-                CountingSession session = CountingTvInputService.sSession;
-                return session != null && session.mTimeShiftSeekToCount > 0;
+                final CountingSession session = CountingTvInputService.sSession;
+                return session != null && session.mTimeShiftSeekToCount > 0
+                        && session.mTimeShiftSeekTo == timeMs;
             }
         }.run();
     }
 
     public void verifyCommandTimeShiftSetPlaybackParams() {
         resetCounts();
-        mTvView.timeShiftSetPlaybackParams(new PlaybackParams().setSpeed(2.0f)
-                .setAudioFallbackMode(PlaybackParams.AUDIO_FALLBACK_MODE_DEFAULT));
+        resetPassedValues();
+        final PlaybackParams param = new PlaybackParams().setSpeed(2.0f)
+                .setAudioFallbackMode(PlaybackParams.AUDIO_FALLBACK_MODE_DEFAULT);
+        mTvView.timeShiftSetPlaybackParams(param);
         mInstrumentation.waitForIdleSync();
         new PollingCheck(TIME_OUT) {
             @Override
             protected boolean check() {
-                CountingSession session = CountingTvInputService.sSession;
-                return session != null && session.mTimeShiftSetPlaybackParamsCount > 0;
+                final CountingSession session = CountingTvInputService.sSession;
+                return session != null && session.mTimeShiftSetPlaybackParamsCount > 0
+                        && playbackParamsEquals(session.mTimeShiftSetPlaybackParams, param);
+            }
+        }.run();
+    }
+
+    public void verifyCommandTimeShiftPlay() {
+        resetCounts();
+        resetPassedValues();
+        final Uri fakeRecordedProgramUri = TvContract.buildRecordedProgramUri(0);
+        mTvView.timeShiftPlay(mStubInfo.getId(), fakeRecordedProgramUri);
+        mInstrumentation.waitForIdleSync();
+        new PollingCheck(TIME_OUT) {
+            @Override
+            protected boolean check() {
+                final CountingSession session = CountingTvInputService.sSession;
+                return session != null && session.mTimeShiftPlayCount > 0
+                        && Objects.equals(session.mRecordedProgramUri, fakeRecordedProgramUri);
             }
         }.run();
     }
@@ -428,38 +742,63 @@
 
     public void verifyCommandOverlayViewSizeChanged() {
         resetCounts();
+        resetPassedValues();
+        final int width = 10;
+        final int height = 20;
         mActivity.runOnUiThread(new Runnable() {
             public void run() {
-                mTvView.setLayoutParams(new LinearLayout.LayoutParams(10, 20));
+                mTvView.setLayoutParams(new LinearLayout.LayoutParams(width, height));
             }
         });
         mInstrumentation.waitForIdleSync();
         new PollingCheck(TIME_OUT) {
             @Override
             protected boolean check() {
-                CountingSession session = CountingTvInputService.sSession;
-                return session != null && session.mOverlayViewSizeChangedCount > 0;
+                final CountingSession session = CountingTvInputService.sSession;
+                return session != null
+                        && session.mOverlayViewSizeChangedCount > 0
+                        && session.mOverlayViewSizeChangedWidth == width
+                        && session.mOverlayViewSizeChangedHeight == height;
+            }
+        }.run();
+    }
+
+    public void verifyCommandSendAppPrivateCommand() {
+        resetCounts();
+        final String action = "android.media.tv.cts.TvInputServiceTest.privateCommand";
+        mTvView.sendAppPrivateCommand(action, sDummyBundle);
+        mInstrumentation.waitForIdleSync();
+        new PollingCheck(TIME_OUT) {
+            @Override
+            protected boolean check() {
+                final CountingSession session = CountingTvInputService.sSession;
+                return session != null
+                        && session.mAppPrivateCommandCount > 0
+                        && bundleEquals(session.mAppPrivateCommandData, sDummyBundle)
+                        && TextUtils.equals(session.mAppPrivateCommandAction, action);
             }
         }.run();
     }
 
     public void verifyCallbackChannelRetuned() {
         resetCounts();
-        CountingSession session = CountingTvInputService.sSession;
+        resetPassedValues();
+        final CountingSession session = CountingTvInputService.sSession;
         assertNotNull(session);
-        Uri fakeChannelUri = TvContract.buildChannelUri(0);
+        final Uri fakeChannelUri = TvContract.buildChannelUri(0);
         session.notifyChannelRetuned(fakeChannelUri);
         new PollingCheck(TIME_OUT) {
             @Override
             protected boolean check() {
-                return mCallback.mChannelRetunedCount > 0;
+                return mCallback.mChannelRetunedCount > 0
+                        && Objects.equals(mCallback.mChannelRetunedUri, fakeChannelUri);
             }
         }.run();
     }
 
     public void verifyCallbackVideoAvailable() {
         resetCounts();
-        CountingSession session = CountingTvInputService.sSession;
+        final CountingSession session = CountingTvInputService.sSession;
         assertNotNull(session);
         session.notifyVideoAvailable();
         new PollingCheck(TIME_OUT) {
@@ -472,38 +811,43 @@
 
     public void verifyCallbackVideoUnavailable() {
         resetCounts();
-        CountingSession session = CountingTvInputService.sSession;
+        resetPassedValues();
+        final CountingSession session = CountingTvInputService.sSession;
         assertNotNull(session);
-        session.notifyVideoUnavailable(TvInputManager.VIDEO_UNAVAILABLE_REASON_TUNING);
+        final int reason = TvInputManager.VIDEO_UNAVAILABLE_REASON_TUNING;
+        session.notifyVideoUnavailable(reason);
         new PollingCheck(TIME_OUT) {
             @Override
             protected boolean check() {
-                return mCallback.mVideoUnavailableCount > 0;
+                return mCallback.mVideoUnavailableCount > 0
+                        && mCallback.mVideoUnavailableReason == reason;
             }
         }.run();
     }
 
     public void verifyCallbackTracksChanged() {
         resetCounts();
-        CountingSession session = CountingTvInputService.sSession;
+        resetPassedValues();
+        final CountingSession session = CountingTvInputService.sSession;
         assertNotNull(session);
         ArrayList<TvTrackInfo> tracks = new ArrayList<>();
-        tracks.add(mDummyTrack);
+        tracks.add(DUMMY_TRACK);
         session.notifyTracksChanged(tracks);
         new PollingCheck(TIME_OUT) {
             @Override
             protected boolean check() {
-                return mCallback.mTrackChangedCount > 0;
+                return mCallback.mTrackChangedCount > 0
+                        && Objects.equals(mCallback.mTracksChangedTrackList, tracks);
             }
         }.run();
     }
 
     public void verifyCallbackVideoSizeChanged() {
         resetCounts();
-        CountingSession session = CountingTvInputService.sSession;
+        final CountingSession session = CountingTvInputService.sSession;
         assertNotNull(session);
         ArrayList<TvTrackInfo> tracks = new ArrayList<>();
-        tracks.add(mDummyTrack);
+        tracks.add(DUMMY_TRACK);
         session.notifyTracksChanged(tracks);
         new PollingCheck(TIME_OUT) {
             @Override
@@ -515,20 +859,24 @@
 
     public void verifyCallbackTrackSelected() {
         resetCounts();
-        CountingSession session = CountingTvInputService.sSession;
+        resetPassedValues();
+        final CountingSession session = CountingTvInputService.sSession;
         assertNotNull(session);
-        session.notifyTrackSelected(mDummyTrack.getType(), mDummyTrack.getId());
+        assertNotNull(DUMMY_TRACK);
+        session.notifyTrackSelected(DUMMY_TRACK.getType(), DUMMY_TRACK.getId());
         new PollingCheck(TIME_OUT) {
             @Override
             protected boolean check() {
-                return mCallback.mTrackSelectedCount > 0;
+                return mCallback.mTrackSelectedCount > 0
+                        && mCallback.mTrackSelectedType == DUMMY_TRACK.getType()
+                        && TextUtils.equals(DUMMY_TRACK.getId(), mCallback.mTrackSelectedTrackId);
             }
         }.run();
     }
 
     public void verifyCallbackContentAllowed() {
         resetCounts();
-        CountingSession session = CountingTvInputService.sSession;
+        final CountingSession session = CountingTvInputService.sSession;
         assertNotNull(session);
         session.notifyContentAllowed();
         new PollingCheck(TIME_OUT) {
@@ -541,28 +889,33 @@
 
     public void verifyCallbackContentBlocked() {
         resetCounts();
-        CountingSession session = CountingTvInputService.sSession;
+        resetPassedValues();
+        final CountingSession session = CountingTvInputService.sSession;
         assertNotNull(session);
-        TvContentRating rating = TvContentRating.createRating("android.media.tv", "US_TVPG",
+        final TvContentRating rating = TvContentRating.createRating("android.media.tv", "US_TVPG",
                 "US_TVPG_TV_MA", "US_TVPG_S", "US_TVPG_V");
         session.notifyContentBlocked(rating);
         new PollingCheck(TIME_OUT) {
             @Override
             protected boolean check() {
-                return mCallback.mContentBlockedCount > 0;
+                return mCallback.mContentBlockedCount > 0
+                        && Objects.equals(mCallback.mContentBlockedRating, rating);
             }
         }.run();
     }
 
     public void verifyCallbackTimeShiftStatusChanged() {
         resetCounts();
-        CountingSession session = CountingTvInputService.sSession;
+        resetPassedValues();
+        final CountingSession session = CountingTvInputService.sSession;
         assertNotNull(session);
-        session.notifyTimeShiftStatusChanged(TvInputManager.TIME_SHIFT_STATUS_AVAILABLE);
+        final int status = TvInputManager.TIME_SHIFT_STATUS_AVAILABLE;
+        session.notifyTimeShiftStatusChanged(status);
         new PollingCheck(TIME_OUT) {
             @Override
             protected boolean check() {
-                return mCallback.mTimeShiftStatusChangedCount > 0;
+                return mCallback.mTimeShiftStatusChangedCount > 0
+                        && mCallback.mTimeShiftStatusChangedStatus == status;
             }
         }.run();
     }
@@ -573,7 +926,7 @@
         final int top = 20;
         final int right = 30;
         final int bottom = 40;
-        CountingSession session = CountingTvInputService.sSession;
+        final CountingSession session = CountingTvInputService.sSession;
         assertNotNull(session);
         session.layoutSurface(left, top, right, bottom);
         new PollingCheck(TIME_OUT) {
@@ -592,16 +945,95 @@
         }.run();
     }
 
+    public static boolean keyEventEquals(KeyEvent event, KeyEvent other) {
+        if (event == other) return true;
+        if (event == null || other == null) return false;
+        return event.getDownTime() == other.getDownTime()
+                && event.getEventTime() == other.getEventTime()
+                && event.getAction() == other.getAction()
+                && event.getKeyCode() == other.getKeyCode()
+                && event.getRepeatCount() == other.getRepeatCount()
+                && event.getMetaState() == other.getMetaState()
+                && event.getDeviceId() == other.getDeviceId()
+                && event.getScanCode() == other.getScanCode()
+                && event.getFlags() == other.getFlags()
+                && event.getSource() == other.getSource()
+                && TextUtils.equals(event.getCharacters(), other.getCharacters());
+    }
+
+    public static boolean motionEventEquals(MotionEvent event, MotionEvent other) {
+        if (event == other) return true;
+        if (event == null || other == null) return false;
+        return event.getDownTime() == other.getDownTime()
+                && event.getEventTime() == other.getEventTime()
+                && event.getAction() == other.getAction()
+                && event.getX() == other.getX()
+                && event.getY() == other.getY()
+                && event.getPressure() == other.getPressure()
+                && event.getSize() == other.getSize()
+                && event.getMetaState() == other.getMetaState()
+                && event.getXPrecision() == other.getXPrecision()
+                && event.getYPrecision() == other.getYPrecision()
+                && event.getDeviceId() == other.getDeviceId()
+                && event.getEdgeFlags() == other.getEdgeFlags()
+                && event.getSource() == other.getSource();
+    }
+
+    public static boolean playbackParamsEquals(PlaybackParams param, PlaybackParams other) {
+        if (param == other) return true;
+        if (param == null || other == null) return false;
+        return param.getAudioFallbackMode() == other.getAudioFallbackMode()
+                && param.getSpeed() == other.getSpeed();
+    }
+
+    public static boolean bundleEquals(Bundle b, Bundle other) {
+        if (b == other) return true;
+        if (b == null || other == null) return false;
+        if (b.size() != other.size()) return false;
+
+        Set<String> keys = b.keySet();
+        for (String key : keys) {
+            if (!other.containsKey(key)) return false;
+            Object objOne = b.get(key);
+            Object objTwo = other.get(key);
+            if (!Objects.equals(objOne, objTwo)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    public void initDummyBundle() {
+        sDummyBundle = new Bundle();
+        sDummyBundle.putString("stringKey", new String("Test String"));
+    }
+
     private void resetCounts() {
         if (CountingTvInputService.sSession != null) {
             CountingTvInputService.sSession.resetCounts();
         }
+        if (CountingTvInputService.sRecordingSession != null) {
+            CountingTvInputService.sRecordingSession.resetCounts();
+        }
         mCallback.resetCounts();
         mTimeShiftPositionCallback.resetCounts();
+        mRecordingCallback.resetCounts();
+    }
+
+    private void resetPassedValues() {
+        if (CountingTvInputService.sSession != null) {
+            CountingTvInputService.sSession.resetPassedValues();
+        }
+        if (CountingTvInputService.sRecordingSession != null) {
+            CountingTvInputService.sRecordingSession.resetPassedValues();
+        }
+        mCallback.resetPassedValues();
+        mRecordingCallback.resetPassedValues();
     }
 
     public static class CountingTvInputService extends StubTvInputService {
         static CountingSession sSession;
+        static CountingRecordingSession sRecordingSession;
 
         @Override
         public Session onCreateSession(String inputId) {
@@ -610,8 +1042,15 @@
             return sSession;
         }
 
+        @Override
+        public RecordingSession onCreateRecordingSession(String inputId) {
+            sRecordingSession = new CountingRecordingSession(this);
+            return sRecordingSession;
+        }
+
         public static class CountingSession extends Session {
             public volatile int mTuneCount;
+            public volatile int mTuneWithBundleCount;
             public volatile int mSetStreamVolumeCount;
             public volatile int mSetCaptionEnabledCount;
             public volatile int mSelectTrackCount;
@@ -628,8 +1067,36 @@
             public volatile int mTimeShiftResumeCount;
             public volatile int mTimeShiftSeekToCount;
             public volatile int mTimeShiftSetPlaybackParamsCount;
+            public volatile int mTimeShiftPlayCount;
             public volatile long mTimeShiftGetCurrentPositionCount;
             public volatile long mTimeShiftGetStartPositionCount;
+            public volatile int mAppPrivateCommandCount;
+
+            public volatile String mAppPrivateCommandAction;
+            public volatile Bundle mAppPrivateCommandData;
+            public volatile Uri mTunedChannelUri;
+            public volatile Bundle mTuneWithBundleData;
+            public volatile Float mStreamVolume;
+            public volatile Boolean mCaptionEnabled;
+            public volatile Integer mSelectTrackType;
+            public volatile String mSelectTrackId;
+            public volatile Integer mKeyDownCode;
+            public volatile KeyEvent mKeyDownEvent;
+            public volatile Integer mKeyLongPressCode;
+            public volatile KeyEvent mKeyLongPressEvent;
+            public volatile Integer mKeyMultipleCode;
+            public volatile Integer mKeyMultipleNumber;
+            public volatile KeyEvent mKeyMultipleEvent;
+            public volatile Integer mKeyUpCode;
+            public volatile KeyEvent mKeyUpEvent;
+            public volatile MotionEvent mTouchEvent;
+            public volatile MotionEvent mTrackballEvent;
+            public volatile MotionEvent mGenricMotionEvent;
+            public volatile Long mTimeShiftSeekTo;
+            public volatile PlaybackParams mTimeShiftSetPlaybackParams;
+            public volatile Uri mRecordedProgramUri;
+            public volatile Integer mOverlayViewSizeChangedWidth;
+            public volatile Integer mOverlayViewSizeChangedHeight;
 
             CountingSession(Context context) {
                 super(context);
@@ -637,6 +1104,7 @@
 
             public void resetCounts() {
                 mTuneCount = 0;
+                mTuneWithBundleCount = 0;
                 mSetStreamVolumeCount = 0;
                 mSetCaptionEnabledCount = 0;
                 mSelectTrackCount = 0;
@@ -653,8 +1121,45 @@
                 mTimeShiftResumeCount = 0;
                 mTimeShiftSeekToCount = 0;
                 mTimeShiftSetPlaybackParamsCount = 0;
+                mTimeShiftPlayCount = 0;
                 mTimeShiftGetCurrentPositionCount = 0;
                 mTimeShiftGetStartPositionCount = 0;
+                mAppPrivateCommandCount = 0;
+            }
+
+            public void resetPassedValues() {
+                mAppPrivateCommandAction = null;
+                mAppPrivateCommandData = null;
+                mTunedChannelUri = null;
+                mTuneWithBundleData = null;
+                mStreamVolume = null;
+                mCaptionEnabled = null;
+                mSelectTrackType = null;
+                mSelectTrackId = null;
+                mKeyDownCode = null;
+                mKeyDownEvent = null;
+                mKeyLongPressCode = null;
+                mKeyLongPressEvent = null;
+                mKeyMultipleCode = null;
+                mKeyMultipleNumber = null;
+                mKeyMultipleEvent = null;
+                mKeyUpCode = null;
+                mKeyUpEvent = null;
+                mTouchEvent = null;
+                mTrackballEvent = null;
+                mGenricMotionEvent = null;
+                mTimeShiftSeekTo = null;
+                mTimeShiftSetPlaybackParams = null;
+                mRecordedProgramUri = null;
+                mOverlayViewSizeChangedWidth = null;
+                mOverlayViewSizeChangedHeight = null;
+            }
+
+            @Override
+            public void onAppPrivateCommand(String action, Bundle data) {
+                mAppPrivateCommandCount++;
+                mAppPrivateCommandAction = action;
+                mAppPrivateCommandData = data;
             }
 
             @Override
@@ -669,22 +1174,37 @@
             @Override
             public boolean onTune(Uri channelUri) {
                 mTuneCount++;
+                mTunedChannelUri = channelUri;
+                return false;
+            }
+
+            @Override
+            public boolean onTune(Uri channelUri, Bundle data) {
+                mTuneWithBundleCount++;
+                mTuneWithBundleData = data;
+                // Also calls {@link #onTune(Uri)} since it will never be called if the
+                // implementation overrides {@link #onTune(Uri, Bundle)}.
+                onTune(channelUri);
                 return false;
             }
 
             @Override
             public void onSetStreamVolume(float volume) {
                 mSetStreamVolumeCount++;
+                mStreamVolume = volume;
             }
 
             @Override
             public void onSetCaptionEnabled(boolean enabled) {
                 mSetCaptionEnabledCount++;
+                mCaptionEnabled = enabled;
             }
 
             @Override
             public boolean onSelectTrack(int type, String id) {
                 mSelectTrackCount++;
+                mSelectTrackType = type;
+                mSelectTrackId = id;
                 return false;
             }
 
@@ -697,42 +1217,54 @@
             @Override
             public boolean onKeyDown(int keyCode, KeyEvent event) {
                 mKeyDownCount++;
+                mKeyDownCode = keyCode;
+                mKeyDownEvent = event;
                 return false;
             }
 
             @Override
             public boolean onKeyLongPress(int keyCode, KeyEvent event) {
                 mKeyLongPressCount++;
+                mKeyLongPressCode = keyCode;
+                mKeyLongPressEvent = event;
                 return false;
             }
 
             @Override
             public boolean onKeyMultiple(int keyCode, int count, KeyEvent event) {
                 mKeyMultipleCount++;
+                mKeyMultipleCode = keyCode;
+                mKeyMultipleNumber = count;
+                mKeyMultipleEvent = event;
                 return false;
             }
 
             @Override
             public boolean onKeyUp(int keyCode, KeyEvent event) {
                 mKeyUpCount++;
+                mKeyUpCode = keyCode;
+                mKeyUpEvent = event;
                 return false;
             }
 
             @Override
             public boolean onTouchEvent(MotionEvent event) {
                 mTouchEventCount++;
+                mTouchEvent = event;
                 return false;
             }
 
             @Override
             public boolean onTrackballEvent(MotionEvent event) {
                 mTrackballEventCount++;
+                mTrackballEvent = event;
                 return false;
             }
 
             @Override
             public boolean onGenericMotionEvent(MotionEvent event) {
                 mGenricMotionEventCount++;
+                mGenricMotionEvent = event;
                 return false;
             }
 
@@ -749,11 +1281,19 @@
             @Override
             public void onTimeShiftSeekTo(long timeMs) {
                 mTimeShiftSeekToCount++;
+                mTimeShiftSeekTo = timeMs;
             }
 
             @Override
             public void onTimeShiftSetPlaybackParams(PlaybackParams param) {
                 mTimeShiftSetPlaybackParamsCount++;
+                mTimeShiftSetPlaybackParams = param;
+            }
+
+            @Override
+            public void onTimeShiftPlay(Uri recordedProgramUri) {
+                mTimeShiftPlayCount++;
+                mRecordedProgramUri = recordedProgramUri;
             }
 
             @Override
@@ -769,7 +1309,137 @@
             @Override
             public void onOverlayViewSizeChanged(int width, int height) {
                 mOverlayViewSizeChangedCount++;
+                mOverlayViewSizeChangedWidth = width;
+                mOverlayViewSizeChangedHeight = height;
             }
         }
+
+        public static class CountingRecordingSession extends RecordingSession {
+            public volatile int mTuneCount;
+            public volatile int mTuneWithBundleCount;
+            public volatile int mReleaseCount;
+            public volatile int mStartRecordingCount;
+            public volatile int mStopRecordingCount;
+            public volatile int mAppPrivateCommandCount;
+
+            public volatile Uri mTunedChannelUri;
+            public volatile Bundle mTuneWithBundleData;
+            public volatile Uri mProgramHint;
+            public volatile String mAppPrivateCommandAction;
+            public volatile Bundle mAppPrivateCommandData;
+
+            CountingRecordingSession(Context context) {
+                super(context);
+            }
+
+            public void resetCounts() {
+                mTuneCount = 0;
+                mTuneWithBundleCount = 0;
+                mReleaseCount = 0;
+                mStartRecordingCount = 0;
+                mStopRecordingCount = 0;
+                mAppPrivateCommandCount = 0;
+            }
+
+            public void resetPassedValues() {
+                mTunedChannelUri = null;
+                mTuneWithBundleData = null;
+                mProgramHint = null;
+                mAppPrivateCommandAction = null;
+                mAppPrivateCommandData = null;
+            }
+
+            @Override
+            public void onTune(Uri channelUri) {
+                mTuneCount++;
+                mTunedChannelUri = channelUri;
+            }
+
+            @Override
+            public void onTune(Uri channelUri, Bundle data) {
+                mTuneWithBundleCount++;
+                mTuneWithBundleData = data;
+                // Also calls {@link #onTune(Uri)} since it will never be called if the
+                // implementation overrides {@link #onTune(Uri, Bundle)}.
+                onTune(channelUri);
+            }
+
+            @Override
+            public void onRelease() {
+                mReleaseCount++;
+            }
+
+            @Override
+            public void onStartRecording(Uri programHint) {
+                mStartRecordingCount++;
+                mProgramHint = programHint;
+            }
+
+            @Override
+            public void onStopRecording() {
+                mStopRecordingCount++;
+            }
+
+            @Override
+            public void onAppPrivateCommand(String action, Bundle data) {
+                mAppPrivateCommandCount++;
+                mAppPrivateCommandAction = action;
+                mAppPrivateCommandData = data;
+            }
+        }
+    }
+
+    private static class StubRecordingCallback extends TvRecordingClient.RecordingCallback {
+        private int mTunedCount;
+        private int mRecordingStoppedCount;
+        private int mErrorCount;
+        private int mConnectionFailedCount;
+        private int mDisconnectedCount;
+
+        private Uri mTunedChannelUri;
+        private Uri mRecordedProgramUri;
+        private Integer mError;
+
+        @Override
+        public void onTuned(Uri channelUri) {
+            mTunedCount++;
+            mTunedChannelUri = channelUri;
+        }
+
+        @Override
+        public void onRecordingStopped(Uri recordedProgramUri) {
+            mRecordingStoppedCount++;
+            mRecordedProgramUri = recordedProgramUri;
+        }
+
+        @Override
+        public void onError(int error) {
+            mErrorCount++;
+            mError = error;
+        }
+
+        @Override
+        public void onConnectionFailed(String inputId) {
+            mConnectionFailedCount++;
+        }
+
+        @Override
+        public void onDisconnected(String inputId) {
+            mDisconnectedCount++;
+        }
+
+        public void resetCounts() {
+            mTunedCount = 0;
+            mRecordingStoppedCount = 0;
+            mErrorCount = 0;
+            mConnectionFailedCount = 0;
+            mDisconnectedCount = 0;
+        }
+
+        public void resetPassedValues() {
+            mTunedChannelUri = null;
+            mRecordedProgramUri = null;
+            mError = null;
+        }
     }
 }
diff --git a/tests/tests/tv/src/android/media/tv/cts/TvTrackInfoTest.java b/tests/tests/tv/src/android/media/tv/cts/TvTrackInfoTest.java
index a99bd77..0d53f4b 100644
--- a/tests/tests/tv/src/android/media/tv/cts/TvTrackInfoTest.java
+++ b/tests/tests/tv/src/android/media/tv/cts/TvTrackInfoTest.java
@@ -70,6 +70,8 @@
                 .setVideoWidth(1920)
                 .setVideoHeight(1080)
                 .setVideoFrameRate(29.97f)
+                .setVideoPixelAspectRatio(1.0f)
+                .setVideoActiveFormatDescription((byte) 8)
                 .setLanguage("eng")
                 .setExtra(bundle)
                 .build();
@@ -78,6 +80,8 @@
         assertEquals(1920, info.getVideoWidth());
         assertEquals(1080, info.getVideoHeight());
         assertEquals(29.97f, info.getVideoFrameRate());
+        assertEquals(1.0f, info.getVideoPixelAspectRatio());
+        assertEquals((byte) 8, info.getVideoActiveFormatDescription());
         assertEquals("eng", info.getLanguage());
         assertEquals(bundle.get("testTrue"), info.getExtra().get("testTrue"));
         assertEquals(0, info.describeContents());
@@ -92,6 +96,8 @@
         assertEquals(1920, infoFromParcel.getVideoWidth());
         assertEquals(1080, infoFromParcel.getVideoHeight());
         assertEquals(29.97f, infoFromParcel.getVideoFrameRate());
+        assertEquals(1.0f, infoFromParcel.getVideoPixelAspectRatio());
+        assertEquals((byte) 8, infoFromParcel.getVideoActiveFormatDescription());
         assertEquals("eng", infoFromParcel.getLanguage());
         assertEquals(bundle.get("testTrue"), infoFromParcel.getExtra().get("testTrue"));
         assertEquals(0, infoFromParcel.describeContents());
diff --git a/tests/tests/tv/src/android/media/tv/cts/TvViewStubActivity.java b/tests/tests/tv/src/android/media/tv/cts/TvViewStubActivity.java
index 5035e14..aa2b09f 100644
--- a/tests/tests/tv/src/android/media/tv/cts/TvViewStubActivity.java
+++ b/tests/tests/tv/src/android/media/tv/cts/TvViewStubActivity.java
@@ -19,7 +19,7 @@
 import android.app.Activity;
 import android.os.Bundle;
 
-import com.android.cts.tv.R;
+import android.tv.cts.R;
 
 public class TvViewStubActivity extends Activity {
     @Override
diff --git a/tests/tests/tv/src/android/media/tv/cts/TvViewTest.java b/tests/tests/tv/src/android/media/tv/cts/TvViewTest.java
index 1c59462..59cb902 100644
--- a/tests/tests/tv/src/android/media/tv/cts/TvViewTest.java
+++ b/tests/tests/tv/src/android/media/tv/cts/TvViewTest.java
@@ -28,6 +28,7 @@
 import android.media.tv.TvView;
 import android.media.tv.TvView.TvInputCallback;
 import android.net.Uri;
+import android.os.Bundle;
 import android.test.ActivityInstrumentationTestCase2;
 import android.test.UiThreadTest;
 import android.util.ArrayMap;
@@ -35,7 +36,7 @@
 import android.view.InputEvent;
 import android.view.KeyEvent;
 
-import com.android.cts.tv.R;
+import android.tv.cts.R;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -54,6 +55,7 @@
     private Instrumentation mInstrumentation;
     private TvInputManager mManager;
     private TvInputInfo mStubInfo;
+    private TvInputInfo mFaultyStubInfo;
     private final MockCallback mCallback = new MockCallback();
 
     private static class MockCallback extends TvInputCallback {
@@ -62,6 +64,7 @@
         private final Map<String, Integer> mTracksGenerationMap = new ArrayMap<>();
         private final Object mLock = new Object();
         private volatile int mConnectionFailedCount;
+        private volatile int mDisconnectedCount;
 
         public boolean isVideoAvailable(String inputId) {
             synchronized (mLock) {
@@ -81,20 +84,30 @@
             }
         }
 
-        public void resetConnectionFailedCount() {
+        public void resetCount() {
             mConnectionFailedCount = 0;
+            mDisconnectedCount = 0;
         }
 
         public int getConnectionFailedCount() {
             return mConnectionFailedCount;
         }
 
+        public int getDisconnectedCount() {
+            return mDisconnectedCount;
+        }
+
         @Override
         public void onConnectionFailed(String inputId) {
             mConnectionFailedCount++;
         }
 
         @Override
+        public void onDisconnected(String inputId) {
+            mDisconnectedCount++;
+        }
+
+        @Override
         public void onVideoAvailable(String inputId) {
             synchronized (mLock) {
                 mVideoAvailableMap.put(inputId, true);
@@ -162,6 +175,11 @@
         for (TvInputInfo info : mManager.getTvInputList()) {
             if (info.getServiceInfo().name.equals(StubTunerTvInputService.class.getName())) {
                 mStubInfo = info;
+            }
+            if (info.getServiceInfo().name.equals(FaultyTvInputService.class.getName())) {
+                mFaultyStubInfo = info;
+            }
+            if (mStubInfo != null && mFaultyStubInfo != null) {
                 break;
             }
         }
@@ -203,7 +221,7 @@
         new TvView(mActivity, null, 0);
     }
 
-    private void tryTuneAllChannels(Runnable runOnEachChannel) throws Throwable {
+    private void tryTuneAllChannels(Bundle params, Runnable runOnEachChannel) throws Throwable {
         StubTunerTvInputService.insertChannels(mActivity.getContentResolver(), mStubInfo);
 
         Uri uri = TvContract.buildChannelsUriForInput(mStubInfo.getId());
@@ -213,7 +231,11 @@
             while (cursor != null && cursor.moveToNext()) {
                 long channelId = cursor.getLong(0);
                 Uri channelUri = TvContract.buildChannelUri(channelId);
-                mTvView.tune(mStubInfo.getId(), channelUri);
+                if (params != null) {
+                    mTvView.tune(mStubInfo.getId(), channelUri, params);
+                } else {
+                    mTvView.tune(mStubInfo.getId(), channelUri);
+                }
                 mInstrumentation.waitForIdleSync();
                 new PollingCheck(TIME_OUT_MS) {
                     @Override
@@ -233,7 +255,16 @@
         if (!Utils.hasTvInputFramework(getActivity())) {
             return;
         }
-        tryTuneAllChannels(null);
+        tryTuneAllChannels(null, null);
+    }
+
+    public void testSimpleTuneWithBundle() throws Throwable {
+        if (!Utils.hasTvInputFramework(getActivity())) {
+            return;
+        }
+        Bundle params = new Bundle();
+        params.putString("android.media.tv.cts.TvViewTest.inputId", mStubInfo.getId());
+        tryTuneAllChannels(params, null);
     }
 
     private void selectTrackAndVerify(final int type, final TvTrackInfo track,
@@ -320,7 +351,7 @@
         final List<TvTrackInfo> tracks = new ArrayList<TvTrackInfo>();
         Collections.addAll(tracks, videoTrack1, videoTrack2, audioTrack1, audioTrack2,
                 subtitleTrack1, subtitleTrack2, subtitleTrack3);
-        tryTuneAllChannels(new Runnable() {
+        tryTuneAllChannels(null, new Runnable() {
             @Override
             public void run() {
                 new PollingCheck(TIME_OUT_MS) {
@@ -407,7 +438,7 @@
         if (!Utils.hasTvInputFramework(getActivity())) {
             return;
         }
-        mCallback.resetConnectionFailedCount();
+        mCallback.resetCount();
         mTvView.tune("invalid_input_id", TvContract.Channels.CONTENT_URI);
         mInstrumentation.waitForIdleSync();
         new PollingCheck(TIME_OUT_MS) {
@@ -417,4 +448,65 @@
             }
         }.run();
     }
+
+    public void testDisconnected() throws Throwable {
+        if (!Utils.hasTvInputFramework(getActivity())) {
+            return;
+        }
+        mCallback.resetCount();
+        Uri fakeChannelUri = TvContract.buildChannelUri(0);
+        mTvView.tune(mFaultyStubInfo.getId(), fakeChannelUri);
+        new PollingCheck(TIME_OUT_MS) {
+            @Override
+            protected boolean check() {
+                return mCallback.getDisconnectedCount() > 0;
+            }
+        }.run();
+    }
+
+    public void testSetZOrderMediaOverlay() throws Exception {
+        if (!Utils.hasTvInputFramework(getActivity())) {
+            return;
+        }
+        // Verifying the z-order from app is not possible. Here we just check if calling APIs does
+        // not lead to any break.
+        mTvView.setZOrderMediaOverlay(true);
+        mInstrumentation.waitForIdleSync();
+        mTvView.setZOrderMediaOverlay(false);
+        mInstrumentation.waitForIdleSync();
+    }
+
+    public void testSetZOrderOnTop() throws Exception {
+        if (!Utils.hasTvInputFramework(getActivity())) {
+            return;
+        }
+        // Verifying the z-order from app is not possible. Here we just check if calling APIs does
+        // not lead to any break.
+        mTvView.setZOrderOnTop(true);
+        mInstrumentation.waitForIdleSync();
+        mTvView.setZOrderOnTop(false);
+        mInstrumentation.waitForIdleSync();
+    }
+
+    @UiThreadTest
+    public void testUnhandledInputEvent() throws Exception {
+        if (!Utils.hasTvInputFramework(getActivity())) {
+            return;
+        }
+        boolean result = mTvView.dispatchUnhandledInputEvent(null);
+        assertFalse(result);
+        result = new InputEventHandlingTvView(mActivity).dispatchUnhandledInputEvent(null);
+        assertTrue(result);
+    }
+
+    private static class InputEventHandlingTvView extends TvView {
+        public InputEventHandlingTvView(Context context) {
+            super(context);
+        }
+
+        @Override
+        public boolean onUnhandledInputEvent(InputEvent event) {
+            return true;
+        }
+    }
 }
diff --git a/tests/tests/uiautomation/Android.mk b/tests/tests/uiautomation/Android.mk
index bb0fc19..d9fc278 100644
--- a/tests/tests/uiautomation/Android.mk
+++ b/tests/tests/uiautomation/Android.mk
@@ -18,6 +18,11 @@
 
 LOCAL_MODULE_TAGS := optional
 
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner ub-uiautomator
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
diff --git a/tests/tests/uiautomation/AndroidManifest.xml b/tests/tests/uiautomation/AndroidManifest.xml
index d99e999..6dc28ed 100644
--- a/tests/tests/uiautomation/AndroidManifest.xml
+++ b/tests/tests/uiautomation/AndroidManifest.xml
@@ -17,9 +17,10 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-        package="android.app.cts.uiautomation">
+        package="android.app.uiautomation.cts">
 
   <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+  <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
 
   <application android:theme="@android:style/Theme.Holo.NoActionBar" >
 
@@ -35,10 +36,24 @@
           android:exported="true">
       </activity>
 
+      <service
+              android:name="android.app.uiautomation.cts.UiAutomationTestA11yService"
+              android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE" >
+          <intent-filter>
+              <action android:name="android.accessibilityservice.AccessibilityService" />
+
+              <category android:name="android.accessibilityservice.category.FEEDBACK_GENERIC" />
+          </intent-filter>
+
+          <meta-data
+                  android:name="android.accessibilityservice"
+                  android:resource="@xml/ui_automation_test_a11y_service" />
+      </service>
+
   </application>
 
-  <instrumentation android:name="android.support.test.uiautomator.UiAutomatorInstrumentationTestRunner"
-                   android:targetPackage="android.app.cts.uiautomation">
+  <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                   android:targetPackage="android.app.uiautomation.cts">
         <meta-data android:name="listener"
             android:value="com.android.cts.runner.CtsTestRunListener" />
     </instrumentation>
diff --git a/tests/tests/uiautomation/AndroidTest.xml b/tests/tests/uiautomation/AndroidTest.xml
new file mode 100644
index 0000000..c4f1665
--- /dev/null
+++ b/tests/tests/uiautomation/AndroidTest.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS UI Automation test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsUiAutomationTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.app.uiautomation.cts" />
+        <option name="runtime-hint" value="6m42s" />
+    </test>
+</configuration>
diff --git a/tests/tests/uiautomation/res/values/strings.xml b/tests/tests/uiautomation/res/values/strings.xml
index 7e4e4e4..4f215f1 100644
--- a/tests/tests/uiautomation/res/values/strings.xml
+++ b/tests/tests/uiautomation/res/values/strings.xml
@@ -52,4 +52,6 @@
         <item>Beemster 2% Milk</item>
     </string-array>
 
+    <string name="uiautomation_a11y_service_description">com.android.app.uiautomation.cts.UiAutomationTestAccessibilityService</string>
+
 </resources>
diff --git a/tests/tests/uiautomation/res/xml/ui_automation_test_a11y_service.xml b/tests/tests/uiautomation/res/xml/ui_automation_test_a11y_service.xml
new file mode 100644
index 0000000..4e7f8d9
--- /dev/null
+++ b/tests/tests/uiautomation/res/xml/ui_automation_test_a11y_service.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
+                       android:description="@string/uiautomation_a11y_service_description"
+                       android:accessibilityEventTypes="typeAllMask"
+                       android:accessibilityFeedbackType="feedbackGeneric"
+                       android:accessibilityFlags="flagDefault"
+                       android:canRetrieveWindowContent="true"
+                       android:notificationTimeout="0" />
diff --git a/tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationTest.java b/tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationTest.java
index 2f3f48c8..9d33a0a 100755
--- a/tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationTest.java
+++ b/tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationTest.java
@@ -19,28 +19,46 @@
 import android.accessibilityservice.AccessibilityServiceInfo;
 import android.app.Activity;
 import android.app.UiAutomation;
+import android.app.uiautomation.cts.R;
+import android.content.ContentResolver;
+import android.content.Context;
 import android.content.Intent;
+import android.os.ParcelFileDescriptor;
+import android.os.SystemClock;
+import android.provider.Settings;
+import android.test.InstrumentationTestCase;
 import android.view.FrameStats;
 import android.view.WindowAnimationFrameStats;
 import android.view.WindowContentFrameStats;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityManager;
 import android.view.accessibility.AccessibilityWindowInfo;
-import android.support.test.uiautomator.UiScrollable;
-import android.support.test.uiautomator.UiSelector;
-import android.support.test.uiautomator.UiAutomatorTestCase;
+import android.widget.ListView;
 
+import java.io.IOException;
 import java.util.List;
+import java.util.concurrent.TimeoutException;
 
 /**
  * Tests for the UiAutomation APIs.
  */
-public class UiAutomationTest extends UiAutomatorTestCase {
+public class UiAutomationTest extends InstrumentationTestCase {
+    private static final long QUIET_TIME_TO_BE_CONSIDERED_IDLE_STATE = 1000;//ms
+
+    private static final long TOTAL_TIME_TO_WAIT_FOR_IDLE_STATE = 1000 * 10;//ms
+
+    // Used to enable/disable accessibility services
+    private static final String COMPONENT_NAME_SEPARATOR = ":";
+    private static final int TIMEOUT_FOR_SERVICE_ENABLE = 10000; // millis; 10s
 
     @Override
     public void setUp() throws Exception {
         super.setUp();
-        AccessibilityServiceInfo info = getInstrumentation().getUiAutomation().getServiceInfo();
+        UiAutomation uiAutomation = getInstrumentation().getUiAutomation();
+        AccessibilityServiceInfo info = uiAutomation.getServiceInfo();
         info.flags |= AccessibilityServiceInfo.FLAG_RETRIEVE_INTERACTIVE_WINDOWS;
-        getInstrumentation().getUiAutomation().setServiceInfo(info);
+        uiAutomation.setServiceInfo(info);
+        grantWriteSecureSettingsPermission(uiAutomation);
     }
 
     public void testWindowContentFrameStats() throws Exception {
@@ -55,7 +73,8 @@
             activity = getInstrumentation().startActivitySync(intent);
 
             // Wait for things to settle.
-            getUiDevice().waitForIdle();
+            uiAutomation.waitForIdle(
+                    QUIET_TIME_TO_BE_CONSIDERED_IDLE_STATE, TOTAL_TIME_TO_WAIT_FOR_IDLE_STATE);
 
             // Find the application window.
             final int windowId = findAppWindowId(uiAutomation.getWindows());
@@ -65,22 +84,21 @@
             assertTrue(uiAutomation.clearWindowContentFrameStats(windowId));
 
             // Find the list to scroll around.
-            UiScrollable listView = new UiScrollable(new UiSelector().resourceId(
-                    "android.app.cts.uiautomation:id/list_view"));
+            final ListView listView = (ListView) activity.findViewById(R.id.list_view);
 
-            // Scoll a bit.
-            listView.scrollToEnd(Integer.MAX_VALUE);
-            listView.scrollToBeginning(Integer.MAX_VALUE);
+            // Scroll a bit.
+            scrollListView(uiAutomation, listView, listView.getAdapter().getCount() - 1);
+            scrollListView(uiAutomation, listView, 0);
 
             // Get the frame stats.
             WindowContentFrameStats stats = uiAutomation.getWindowContentFrameStats(windowId);
 
             // Check the frame stats...
 
-            // We should have somethong.
+            // We should have something.
             assertNotNull(stats);
 
-            // The refresh presiod is always positive.
+            // The refresh period is always positive.
             assertTrue(stats.getRefreshPeriodNano() > 0);
 
             // There is some frame data.
@@ -113,7 +131,8 @@
             activity = getInstrumentation().startActivitySync(intent);
 
             // Wait for things to settle.
-            getUiDevice().waitForIdle();
+            uiAutomation.waitForIdle(
+                    QUIET_TIME_TO_BE_CONSIDERED_IDLE_STATE, TOTAL_TIME_TO_WAIT_FOR_IDLE_STATE);
 
             // Wait for Activity draw finish
             getInstrumentation().waitForIdleSync();
@@ -130,10 +149,10 @@
 
             // Check the frame stats...
 
-            // We should have somethong.
+            // We should have something.
             assertNotNull(stats);
 
-            // The refresh presiod is always positive.
+            // The refresh period is always positive.
             assertTrue(stats.getRefreshPeriodNano() > 0);
 
             // There is no data.
@@ -163,7 +182,8 @@
             firstActivity = getInstrumentation().startActivitySync(firstIntent);
 
             // Wait for things to settle.
-            getUiDevice().waitForIdle();
+            uiAutomation.waitForIdle(
+                    QUIET_TIME_TO_BE_CONSIDERED_IDLE_STATE, TOTAL_TIME_TO_WAIT_FOR_IDLE_STATE);
 
             // Wait for Activity draw finish
             getInstrumentation().waitForIdleSync();
@@ -178,7 +198,8 @@
             secondActivity = getInstrumentation().startActivitySync(secondIntent);
 
             // Wait for things to settle.
-            getUiDevice().waitForIdle();
+            uiAutomation.waitForIdle(
+                    QUIET_TIME_TO_BE_CONSIDERED_IDLE_STATE, TOTAL_TIME_TO_WAIT_FOR_IDLE_STATE);
 
             // Wait for Activity draw finish
             getInstrumentation().waitForIdleSync();
@@ -188,7 +209,7 @@
 
             // Check the frame stats...
 
-            // We should have somethong.
+            // We should have something.
             assertNotNull(stats);
 
             // The refresh presiod is always positive.
@@ -219,7 +240,8 @@
         UiAutomation uiAutomation = getInstrumentation().getUiAutomation();
 
         // Wait for things to settle.
-        getUiDevice().waitForIdle();
+        uiAutomation.waitForIdle(
+                QUIET_TIME_TO_BE_CONSIDERED_IDLE_STATE, TOTAL_TIME_TO_WAIT_FOR_IDLE_STATE);
 
         // Clear the window animation stats to be with a clean slate.
         uiAutomation.clearWindowAnimationFrameStats();
@@ -229,7 +251,7 @@
 
         // Check the frame stats...
 
-        // We should have somethong.
+        // We should have something.
         assertNotNull(stats);
 
         // The refresh presiod is always positive.
@@ -243,6 +265,193 @@
         assertEquals(stats.getEndTimeNano(), FrameStats.UNDEFINED_TIME_NANO);
     }
 
+    public void testUsingUiAutomationAfterDestroy_shouldThrowException() {
+        UiAutomation uiAutomation = getInstrumentation().getUiAutomation();
+        uiAutomation.destroy();
+        try {
+            uiAutomation.getServiceInfo();
+            fail("Expected exception when using destroyed UiAutomation");
+        } catch (RuntimeException e) {
+        }
+    }
+
+    public void testDontSuppressAccessibility_canStartA11yService() throws IOException,
+            InterruptedException {
+        turnAccessibilityOff();
+        try {
+            getInstrumentation()
+                    .getUiAutomation(UiAutomation.FLAG_DONT_SUPPRESS_ACCESSIBILITY_SERVICES);
+            enableAccessibilityService();
+            assertTrue(UiAutomationTestA11yService.sConnectedInstance.isConnected());
+        } finally {
+            turnAccessibilityOff();
+        }
+    }
+
+    public void testServiceWithNoFlags_shutsDownA11yService() throws IOException {
+        turnAccessibilityOff();
+        try {
+            UiAutomation uiAutomation = getInstrumentation()
+                    .getUiAutomation(UiAutomation.FLAG_DONT_SUPPRESS_ACCESSIBILITY_SERVICES);
+            enableAccessibilityService();
+            assertTrue(UiAutomationTestA11yService.sConnectedInstance.isConnected());
+            uiAutomation.destroy();
+            assertTrue(UiAutomationTestA11yService.sConnectedInstance.isConnected());
+            getInstrumentation().getUiAutomation(); // Should suppress
+            assertFalse(UiAutomationTestA11yService.sConnectedInstance.isConnected());
+        } finally {
+            turnAccessibilityOff();
+        }
+    }
+
+    public void testServiceSupressingA11yServices_a11yServiceStartsWhenDestroyed()
+            throws IOException, InterruptedException {
+        turnAccessibilityOff();
+        try {
+            UiAutomation uiAutomation = getInstrumentation()
+                    .getUiAutomation(UiAutomation.FLAG_DONT_SUPPRESS_ACCESSIBILITY_SERVICES);
+            enableAccessibilityService();
+            uiAutomation.destroy();
+            UiAutomation suppressingUiAutomation = getInstrumentation().getUiAutomation();
+            // We verify above that the connection is broken here. Make sure we see a new one
+            // after we destroy it
+            UiAutomationTestA11yService.sConnectedInstance = null;
+            suppressingUiAutomation.destroy();
+            waitForAccessibilityServiceToStart();
+        } finally {
+            turnAccessibilityOff();
+        }
+    }
+
+    public void testServiceSupressingA11yServices_a11yServiceStartsWhenFlagsChange()
+            throws IOException, InterruptedException {
+        turnAccessibilityOff();
+        try {
+            getInstrumentation()
+                    .getUiAutomation(UiAutomation.FLAG_DONT_SUPPRESS_ACCESSIBILITY_SERVICES);
+            enableAccessibilityService();
+            getInstrumentation().getUiAutomation();
+            // We verify above that the connection is broken here. Make sure we see a new one
+            // after we change the flags
+            UiAutomationTestA11yService.sConnectedInstance = null;
+            getInstrumentation()
+                    .getUiAutomation(UiAutomation.FLAG_DONT_SUPPRESS_ACCESSIBILITY_SERVICES);
+            waitForAccessibilityServiceToStart();
+        } finally {
+            turnAccessibilityOff();
+        }
+    }
+
+    private void scrollListView(UiAutomation uiAutomation, final ListView listView,
+            final int position) throws TimeoutException {
+        getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                listView.smoothScrollToPosition(position);
+            }
+        });
+        Runnable emptyRunnable = new Runnable() {
+            @Override
+            public void run() {
+            }
+        };
+        UiAutomation.AccessibilityEventFilter scrollFilter =
+                new UiAutomation.AccessibilityEventFilter() {
+                    @Override
+                    public boolean accept(AccessibilityEvent accessibilityEvent) {
+                        return accessibilityEvent.getEventType()
+                                == AccessibilityEvent.TYPE_VIEW_SCROLLED;
+                    }
+                };
+        uiAutomation.executeAndWaitForEvent(emptyRunnable, scrollFilter,
+                TOTAL_TIME_TO_WAIT_FOR_IDLE_STATE);
+        uiAutomation.waitForIdle(
+                QUIET_TIME_TO_BE_CONSIDERED_IDLE_STATE, TOTAL_TIME_TO_WAIT_FOR_IDLE_STATE);
+    }
+
+    private void grantWriteSecureSettingsPermission(UiAutomation uiAutomation) throws IOException {
+        Context context = getInstrumentation().getContext();
+        ParcelFileDescriptor fd = uiAutomation.executeShellCommand("pm grant "
+                + context.getPackageName() + "android.permission.WRITE_SECURE_SETTINGS");
+        fd.close();
+    }
+
+    private void enableAccessibilityService() {
+        Context context = getInstrumentation().getContext();
+        AccessibilityManager manager =
+                (AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE);
+        List<AccessibilityServiceInfo> serviceInfos =
+                manager.getInstalledAccessibilityServiceList();
+        for (int i = 0; i < serviceInfos.size(); i++) {
+            AccessibilityServiceInfo serviceInfo = serviceInfos.get(i);
+            if (context.getString(R.string.uiautomation_a11y_service_description)
+                    .equals(serviceInfo.getDescription())) {
+                ContentResolver cr = context.getContentResolver();
+                String enabledServices = Settings.Secure.getString(cr,
+                        Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
+                Settings.Secure.putString(cr, Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
+                        enabledServices + COMPONENT_NAME_SEPARATOR + serviceInfo.getId());
+                Settings.Secure.putInt(cr, Settings.Secure.ACCESSIBILITY_ENABLED, 1);
+                waitForAccessibilityServiceToStart();
+                return;
+            }
+        }
+        throw new RuntimeException("Test accessibility service not found");
+    }
+
+    private void waitForAccessibilityServiceToStart() {
+        long timeoutTimeMillis = SystemClock.uptimeMillis() + TIMEOUT_FOR_SERVICE_ENABLE;
+        while (SystemClock.uptimeMillis() < timeoutTimeMillis) {
+            synchronized(UiAutomationTestA11yService.sWaitObjectForConnecting) {
+                if (UiAutomationTestA11yService.sConnectedInstance != null) {
+                    return;
+                }
+                try {
+                    UiAutomationTestA11yService.sWaitObjectForConnecting.wait(
+                            timeoutTimeMillis - SystemClock.uptimeMillis());
+                } catch (InterruptedException e) {
+                    // Ignored; loop again
+                }
+            }
+        }
+        throw new RuntimeException("Test accessibility service not starting");
+    }
+
+    private void turnAccessibilityOff() {
+        getInstrumentation().getUiAutomation().destroy();
+        final Object waitLockForA11yOff = new Object();
+        Context context = getInstrumentation().getContext();
+        AccessibilityManager manager =
+                (AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE);
+        manager.addAccessibilityStateChangeListener(
+                new AccessibilityManager.AccessibilityStateChangeListener() {
+                    @Override
+                    public void onAccessibilityStateChanged(boolean b) {
+                        synchronized (waitLockForA11yOff) {
+                            waitLockForA11yOff.notifyAll();
+                        }
+                    }
+                });
+        ContentResolver cr = context.getContentResolver();
+        Settings.Secure.putString(
+                cr, Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, null);
+        UiAutomationTestA11yService.sConnectedInstance = null;
+        long timeoutTimeMillis = SystemClock.uptimeMillis() + TIMEOUT_FOR_SERVICE_ENABLE;
+        while (SystemClock.uptimeMillis() < timeoutTimeMillis) {
+            synchronized (waitLockForA11yOff) {
+                if (!manager.isEnabled()) {
+                    return;
+                }
+                try {
+                    waitLockForA11yOff.wait(timeoutTimeMillis - SystemClock.uptimeMillis());
+                } catch (InterruptedException e) {
+                    // Ignored; loop again
+                }
+            }
+        }
+        throw new RuntimeException("Unable to turn accessibility off");
+    }
+
     private void assertWindowContentTimestampsInAscendingOrder(WindowContentFrameStats stats) {
         long lastExpectedTimeNano = 0;
         long lastPresentedTimeNano = 0;
diff --git a/tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationTestA11yService.java b/tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationTestA11yService.java
new file mode 100644
index 0000000..cf46157
--- /dev/null
+++ b/tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationTestA11yService.java
@@ -0,0 +1,60 @@
+/**
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 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.app.uiautomation.cts;
+
+import android.accessibilityservice.AccessibilityService;
+import android.view.accessibility.AccessibilityEvent;
+
+/**
+ * A stub accessibility service to install for testing UiAutomation's effect on accessibility
+ * services
+ */
+public class UiAutomationTestA11yService extends AccessibilityService {
+    public static Object sWaitObjectForConnecting = new Object();
+
+    public static UiAutomationTestA11yService sConnectedInstance;
+
+    @Override
+    public void onDestroy() {
+    }
+
+    @Override
+    public void onAccessibilityEvent(AccessibilityEvent accessibilityEvent) {
+    }
+
+    @Override
+    public void onInterrupt() {
+
+    }
+
+    @Override
+    protected void onServiceConnected() {
+        synchronized (sWaitObjectForConnecting) {
+            sConnectedInstance = this;
+            sWaitObjectForConnecting.notifyAll();
+        }
+    }
+
+    public boolean isConnected() {
+        try {
+            if (getRootInActiveWindow() == null) {
+                return false;
+            }
+            return true;
+        } catch (Exception e) {
+            return false;
+        }
+    }
+}
diff --git a/tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationTestFirstActivity.java b/tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationTestFirstActivity.java
index a798b1b..839a290 100644
--- a/tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationTestFirstActivity.java
+++ b/tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationTestFirstActivity.java
@@ -16,7 +16,7 @@
 
 package android.app.uiautomation.cts;
 
-import android.app.cts.uiautomation.R;
+import android.app.uiautomation.cts.R;
 
 import android.app.Activity;
 import android.os.Bundle;
diff --git a/tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationTestSecondActivity.java b/tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationTestSecondActivity.java
index e6fc743..4ba0f74 100644
--- a/tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationTestSecondActivity.java
+++ b/tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationTestSecondActivity.java
@@ -17,7 +17,7 @@
 package android.app.uiautomation.cts;
 
 import android.app.Activity;
-import android.app.cts.uiautomation.R;
+import android.app.uiautomation.cts.R;
 import android.os.Bundle;
 import android.view.WindowManager;
 import android.widget.ArrayAdapter;
diff --git a/tests/tests/uidisolation/Android.mk b/tests/tests/uidisolation/Android.mk
index c21b6df..08b9646 100644
--- a/tests/tests/uidisolation/Android.mk
+++ b/tests/tests/uidisolation/Android.mk
@@ -21,6 +21,9 @@
 # and when built explicitly put it in the data partition
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner ctstestserver
 
 LOCAL_JAVA_LIBRARIES := org.apache.http.legacy
diff --git a/tests/tests/uidisolation/AndroidManifest.xml b/tests/tests/uidisolation/AndroidManifest.xml
index 86efb6f..0d27e37 100644
--- a/tests/tests/uidisolation/AndroidManifest.xml
+++ b/tests/tests/uidisolation/AndroidManifest.xml
@@ -16,7 +16,7 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.uidisolation">
+    package="android.uidisolation.cts">
 
     <uses-library android:name="org.apache.http.legacy" android:required="false" />
 
@@ -34,7 +34,7 @@
    <uses-permission android:name="android.permission.INTERNET"/>
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.cts.uidisolation"
+                     android:targetPackage="android.uidisolation.cts"
                      android:label="CTS tests of android.uidisolation">
         <meta-data android:name="listener"
             android:value="com.android.cts.runner.CtsTestRunListener" />
diff --git a/tests/tests/uidisolation/AndroidTest.xml b/tests/tests/uidisolation/AndroidTest.xml
new file mode 100644
index 0000000..e7717c0
--- /dev/null
+++ b/tests/tests/uidisolation/AndroidTest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS UID Isolation test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsUidIsolationTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.uidisolation.cts" />
+    </test>
+</configuration>
diff --git a/tests/tests/uirendering/Android.mk b/tests/tests/uirendering/Android.mk
index 76707df..fd01e10 100644
--- a/tests/tests/uirendering/Android.mk
+++ b/tests/tests/uirendering/Android.mk
@@ -19,6 +19,11 @@
 # don't include this package in any target
 LOCAL_MODULE_TAGS := optional
 
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_JAVA_LIBRARIES := android.test.runner
 
 LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
diff --git a/tests/tests/uirendering/AndroidManifest.xml b/tests/tests/uirendering/AndroidManifest.xml
index b8d84a6..8b6e2aa 100644
--- a/tests/tests/uirendering/AndroidManifest.xml
+++ b/tests/tests/uirendering/AndroidManifest.xml
@@ -16,7 +16,7 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.uirendering">
+    package="android.uirendering.cts">
     <uses-permission android:name="android.permission.INJECT_EVENTS" />
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
@@ -27,7 +27,7 @@
     </application>
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.cts.uirendering">
+                     android:targetPackage="android.uirendering.cts">
     </instrumentation>
 
 </manifest>
diff --git a/tests/tests/uirendering/AndroidTest.xml b/tests/tests/uirendering/AndroidTest.xml
new file mode 100644
index 0000000..c89300b
--- /dev/null
+++ b/tests/tests/uirendering/AndroidTest.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS UI Rendering test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsUiRenderingTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.uirendering.cts" />
+        <option name="runtime-hint" value="11m55s" />
+    </test>
+</configuration>
diff --git a/tests/tests/uirendering/res/drawable-nodpi/black1.png b/tests/tests/uirendering/res/drawable-nodpi/black1.png
index bbfc2c1..d1c246a 100644
--- a/tests/tests/uirendering/res/drawable-nodpi/black1.png
+++ b/tests/tests/uirendering/res/drawable-nodpi/black1.png
Binary files differ
diff --git a/tests/tests/uirendering/res/drawable-nodpi/blackitalic1.png b/tests/tests/uirendering/res/drawable-nodpi/blackitalic1.png
index 6a8a830..d162afc 100644
--- a/tests/tests/uirendering/res/drawable-nodpi/blackitalic1.png
+++ b/tests/tests/uirendering/res/drawable-nodpi/blackitalic1.png
Binary files differ
diff --git a/tests/tests/uirendering/res/drawable-nodpi/bold1.png b/tests/tests/uirendering/res/drawable-nodpi/bold1.png
index cd0465b..b9f5218 100644
--- a/tests/tests/uirendering/res/drawable-nodpi/bold1.png
+++ b/tests/tests/uirendering/res/drawable-nodpi/bold1.png
Binary files differ
diff --git a/tests/tests/uirendering/res/drawable-nodpi/bolditalic1.png b/tests/tests/uirendering/res/drawable-nodpi/bolditalic1.png
index 0819c8a..3a0aa23 100644
--- a/tests/tests/uirendering/res/drawable-nodpi/bolditalic1.png
+++ b/tests/tests/uirendering/res/drawable-nodpi/bolditalic1.png
Binary files differ
diff --git a/tests/tests/uirendering/res/drawable-nodpi/condensed1.png b/tests/tests/uirendering/res/drawable-nodpi/condensed1.png
index 16f03e2..88c8bef 100644
--- a/tests/tests/uirendering/res/drawable-nodpi/condensed1.png
+++ b/tests/tests/uirendering/res/drawable-nodpi/condensed1.png
Binary files differ
diff --git a/tests/tests/uirendering/res/drawable-nodpi/condensedbold1.png b/tests/tests/uirendering/res/drawable-nodpi/condensedbold1.png
index 98174f0..8318a51 100644
--- a/tests/tests/uirendering/res/drawable-nodpi/condensedbold1.png
+++ b/tests/tests/uirendering/res/drawable-nodpi/condensedbold1.png
Binary files differ
diff --git a/tests/tests/uirendering/res/drawable-nodpi/condensedbolditalic1.png b/tests/tests/uirendering/res/drawable-nodpi/condensedbolditalic1.png
index 8b017ba..4cae84d 100644
--- a/tests/tests/uirendering/res/drawable-nodpi/condensedbolditalic1.png
+++ b/tests/tests/uirendering/res/drawable-nodpi/condensedbolditalic1.png
Binary files differ
diff --git a/tests/tests/uirendering/res/drawable-nodpi/condenseditalic1.png b/tests/tests/uirendering/res/drawable-nodpi/condenseditalic1.png
index 5fc1f9c..50d0d38 100644
--- a/tests/tests/uirendering/res/drawable-nodpi/condenseditalic1.png
+++ b/tests/tests/uirendering/res/drawable-nodpi/condenseditalic1.png
Binary files differ
diff --git a/tests/tests/uirendering/res/drawable-nodpi/condensedlight1.png b/tests/tests/uirendering/res/drawable-nodpi/condensedlight1.png
index 1aca9cf..df758a5 100644
--- a/tests/tests/uirendering/res/drawable-nodpi/condensedlight1.png
+++ b/tests/tests/uirendering/res/drawable-nodpi/condensedlight1.png
Binary files differ
diff --git a/tests/tests/uirendering/res/drawable-nodpi/condensedlightitalic1.png b/tests/tests/uirendering/res/drawable-nodpi/condensedlightitalic1.png
index 47ecd67..f2959d6 100644
--- a/tests/tests/uirendering/res/drawable-nodpi/condensedlightitalic1.png
+++ b/tests/tests/uirendering/res/drawable-nodpi/condensedlightitalic1.png
Binary files differ
diff --git a/tests/tests/uirendering/res/drawable-nodpi/hello1.png b/tests/tests/uirendering/res/drawable-nodpi/hello1.png
index 6c9cb58..6ae9850 100644
--- a/tests/tests/uirendering/res/drawable-nodpi/hello1.png
+++ b/tests/tests/uirendering/res/drawable-nodpi/hello1.png
Binary files differ
diff --git a/tests/tests/uirendering/res/drawable-nodpi/italic1.png b/tests/tests/uirendering/res/drawable-nodpi/italic1.png
index 0afb3ae..5083186 100644
--- a/tests/tests/uirendering/res/drawable-nodpi/italic1.png
+++ b/tests/tests/uirendering/res/drawable-nodpi/italic1.png
Binary files differ
diff --git a/tests/tests/uirendering/res/drawable-nodpi/light1.png b/tests/tests/uirendering/res/drawable-nodpi/light1.png
index 6822edb..bb829d7 100644
--- a/tests/tests/uirendering/res/drawable-nodpi/light1.png
+++ b/tests/tests/uirendering/res/drawable-nodpi/light1.png
Binary files differ
diff --git a/tests/tests/uirendering/res/drawable-nodpi/lightitalic1.png b/tests/tests/uirendering/res/drawable-nodpi/lightitalic1.png
index b49d2d6..ee3a210 100644
--- a/tests/tests/uirendering/res/drawable-nodpi/lightitalic1.png
+++ b/tests/tests/uirendering/res/drawable-nodpi/lightitalic1.png
Binary files differ
diff --git a/tests/tests/uirendering/res/drawable-nodpi/medium1.png b/tests/tests/uirendering/res/drawable-nodpi/medium1.png
index 5b187bc..c4c047d 100644
--- a/tests/tests/uirendering/res/drawable-nodpi/medium1.png
+++ b/tests/tests/uirendering/res/drawable-nodpi/medium1.png
Binary files differ
diff --git a/tests/tests/uirendering/res/drawable-nodpi/mediumitalic1.png b/tests/tests/uirendering/res/drawable-nodpi/mediumitalic1.png
index 057edc0..1f94b86 100644
--- a/tests/tests/uirendering/res/drawable-nodpi/mediumitalic1.png
+++ b/tests/tests/uirendering/res/drawable-nodpi/mediumitalic1.png
Binary files differ
diff --git a/tests/tests/uirendering/res/drawable-nodpi/thin1.png b/tests/tests/uirendering/res/drawable-nodpi/thin1.png
index a780f16..af0aabd 100644
--- a/tests/tests/uirendering/res/drawable-nodpi/thin1.png
+++ b/tests/tests/uirendering/res/drawable-nodpi/thin1.png
Binary files differ
diff --git a/tests/tests/uirendering/res/drawable-nodpi/thinitalic1.png b/tests/tests/uirendering/res/drawable-nodpi/thinitalic1.png
index 6ddb52b..da6c3bc 100644
--- a/tests/tests/uirendering/res/drawable-nodpi/thinitalic1.png
+++ b/tests/tests/uirendering/res/drawable-nodpi/thinitalic1.png
Binary files differ
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/bitmapcomparers/ExactComparer.java b/tests/tests/uirendering/src/android/uirendering/cts/bitmapcomparers/ExactComparer.java
index 36be5f0f..562b730 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/bitmapcomparers/ExactComparer.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/bitmapcomparers/ExactComparer.java
@@ -15,8 +15,8 @@
  */
 package android.uirendering.cts.bitmapcomparers;
 
-import com.android.cts.uirendering.R;
-import com.android.cts.uirendering.ScriptC_ExactComparer;
+import android.uirendering.cts.R;
+import android.uirendering.cts.ScriptC_ExactComparer;
 
 import android.content.res.Resources;
 import android.renderscript.Allocation;
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/bitmapcomparers/ExactComparer.rs b/tests/tests/uirendering/src/android/uirendering/cts/bitmapcomparers/ExactComparer.rs
index 899a5cc..6425c17 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/bitmapcomparers/ExactComparer.rs
+++ b/tests/tests/uirendering/src/android/uirendering/cts/bitmapcomparers/ExactComparer.rs
@@ -1,5 +1,5 @@
 #pragma version(1)
-#pragma rs java_package_name(com.android.cts.uirendering)
+#pragma rs java_package_name(android.uirendering.cts)
 
 int WIDTH;
 int OFFSET;
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/bitmapcomparers/MSSIMComparer.java b/tests/tests/uirendering/src/android/uirendering/cts/bitmapcomparers/MSSIMComparer.java
index 56d9cf5..4a25695 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/bitmapcomparers/MSSIMComparer.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/bitmapcomparers/MSSIMComparer.java
@@ -15,7 +15,7 @@
  */
 package android.uirendering.cts.bitmapcomparers;
 
-import com.android.cts.uirendering.ScriptC_MSSIMComparer;
+import android.uirendering.cts.ScriptC_MSSIMComparer;
 
 import android.content.res.Resources;
 import android.graphics.Color;
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/bitmapcomparers/MSSIMComparer.rs b/tests/tests/uirendering/src/android/uirendering/cts/bitmapcomparers/MSSIMComparer.rs
index 4d8c41b8..b0e86b8 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/bitmapcomparers/MSSIMComparer.rs
+++ b/tests/tests/uirendering/src/android/uirendering/cts/bitmapcomparers/MSSIMComparer.rs
@@ -1,5 +1,5 @@
 #pragma version(1)
-#pragma rs java_package_name(com.android.cts.uirendering)
+#pragma rs java_package_name(android.uirendering.cts)
 
 int WIDTH;
 int HEIGHT;
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/bitmapcomparers/MeanSquaredComparer.java b/tests/tests/uirendering/src/android/uirendering/cts/bitmapcomparers/MeanSquaredComparer.java
index cc2fbba..5cc896b 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/bitmapcomparers/MeanSquaredComparer.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/bitmapcomparers/MeanSquaredComparer.java
@@ -15,8 +15,8 @@
  */
 package android.uirendering.cts.bitmapcomparers;
 
-import com.android.cts.uirendering.R;
-import com.android.cts.uirendering.ScriptC_MeanSquaredComparer;
+import android.uirendering.cts.R;
+import android.uirendering.cts.ScriptC_MeanSquaredComparer;
 
 import android.content.res.Resources;
 import android.graphics.Color;
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/bitmapcomparers/MeanSquaredComparer.rs b/tests/tests/uirendering/src/android/uirendering/cts/bitmapcomparers/MeanSquaredComparer.rs
index b37ad13..3b37609 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/bitmapcomparers/MeanSquaredComparer.rs
+++ b/tests/tests/uirendering/src/android/uirendering/cts/bitmapcomparers/MeanSquaredComparer.rs
@@ -1,5 +1,5 @@
 #pragma version(1)
-#pragma rs java_package_name(com.android.cts.uirendering)
+#pragma rs java_package_name(android.uirendering.cts)
 
 int REGION_SIZE;
 int WIDTH;
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/bitmapcomparers/ThresholdDifferenceComparer.java b/tests/tests/uirendering/src/android/uirendering/cts/bitmapcomparers/ThresholdDifferenceComparer.java
index f8304ba..6a78f11 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/bitmapcomparers/ThresholdDifferenceComparer.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/bitmapcomparers/ThresholdDifferenceComparer.java
@@ -15,8 +15,8 @@
  */
 package android.uirendering.cts.bitmapcomparers;
 
-import com.android.cts.uirendering.R;
-import com.android.cts.uirendering.ScriptC_ThresholdDifferenceComparer;
+import android.uirendering.cts.R;
+import android.uirendering.cts.ScriptC_ThresholdDifferenceComparer;
 
 import android.content.res.Resources;
 import android.graphics.Color;
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/bitmapcomparers/ThresholdDifferenceComparer.rs b/tests/tests/uirendering/src/android/uirendering/cts/bitmapcomparers/ThresholdDifferenceComparer.rs
index de1a129..8a40ad6 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/bitmapcomparers/ThresholdDifferenceComparer.rs
+++ b/tests/tests/uirendering/src/android/uirendering/cts/bitmapcomparers/ThresholdDifferenceComparer.rs
@@ -1,5 +1,5 @@
 #pragma version(1)
-#pragma rs java_package_name(com.android.cts.uirendering)
+#pragma rs java_package_name(android.uirendering.cts)
 
 int WIDTH;
 int THRESHOLD;
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/BitmapFilterTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/BitmapFilterTests.java
index b324b06..a2f0305 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/BitmapFilterTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/BitmapFilterTests.java
@@ -16,17 +16,18 @@
 package android.uirendering.cts.testclasses;
 
 import android.graphics.Bitmap;
-import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.Paint;
 import android.graphics.PaintFlagsDrawFilter;
-import android.test.suitebuilder.annotation.SmallTest;
+import android.test.suitebuilder.annotation.MediumTest;
 import android.uirendering.cts.bitmapverifiers.BitmapVerifier;
 import android.uirendering.cts.bitmapverifiers.ColorVerifier;
 import android.uirendering.cts.bitmapverifiers.PerPixelBitmapVerifier;
 import android.uirendering.cts.testinfrastructure.ActivityTestBase;
 import android.uirendering.cts.testinfrastructure.CanvasClient;
+import org.junit.Test;
 
+@MediumTest
 public class BitmapFilterTests extends ActivityTestBase {
     private static final int WHITE_WEIGHT = 255 * 3;
     private enum FilterEnum {
@@ -75,32 +76,32 @@
     private static final int BIG_GRID_SIZE = TEST_WIDTH * 2;
     private Bitmap mBigGridBitmap = createGridBitmap(BIG_GRID_SIZE, BIG_GRID_SIZE);
 
-    @SmallTest
+    @Test
     public void testPaintFilterScaleUp() {
         runScaleTest(FilterEnum.PAINT_FILTER, true);
     }
 
-    @SmallTest
+    @Test
     public void testPaintFilterScaleDown() {
         runScaleTest(FilterEnum.PAINT_FILTER, false);
     }
 
-    @SmallTest
+    @Test
     public void testDrawFilterRemoveFilterScaleUp() {
         runScaleTest(FilterEnum.REMOVE_FILTER, true);
     }
 
-    @SmallTest
+    @Test
     public void testDrawFilterRemoveFilterScaleDown() {
         runScaleTest(FilterEnum.REMOVE_FILTER, false);
     }
 
-    @SmallTest
+    @Test
     public void testDrawFilterScaleUp() {
         runScaleTest(FilterEnum.ADD_FILTER, true);
     }
 
-    @SmallTest
+    @Test
     public void testDrawFilterScaleDown() {
         runScaleTest(FilterEnum.ADD_FILTER, false);
     }
@@ -110,18 +111,15 @@
         final Paint paint = new Paint(filterEnum.equals(FilterEnum.ADD_FILTER) ?
                 0 : Paint.FILTER_BITMAP_FLAG);
 
-        CanvasClient canvasClient = new CanvasClient() {
-            @Override
-            public void draw(Canvas canvas, int width, int height) {
-                canvas.scale(1.0f * width / gridWidth, 1.0f * height / gridWidth);
-                if (filterEnum.equals(FilterEnum.ADD_FILTER)) {
-                    canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.FILTER_BITMAP_FLAG));
-                } else if (filterEnum.equals(FilterEnum.REMOVE_FILTER)) {
-                    canvas.setDrawFilter(new PaintFlagsDrawFilter(Paint.FILTER_BITMAP_FLAG, 0));
-                }
-                canvas.drawBitmap(scaleUp ? mSmallGridBitmap : mBigGridBitmap, 0, 0, paint);
-                canvas.setDrawFilter(null);
+        CanvasClient canvasClient = (canvas, width, height) -> {
+            canvas.scale(1.0f * width / gridWidth, 1.0f * height / gridWidth);
+            if (filterEnum.equals(FilterEnum.ADD_FILTER)) {
+                canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.FILTER_BITMAP_FLAG));
+            } else if (filterEnum.equals(FilterEnum.REMOVE_FILTER)) {
+                canvas.setDrawFilter(new PaintFlagsDrawFilter(Paint.FILTER_BITMAP_FLAG, 0));
             }
+            canvas.drawBitmap(scaleUp ? mSmallGridBitmap : mBigGridBitmap, 0, 0, paint);
+            canvas.setDrawFilter(null);
         };
         createTest()
                 .addCanvasClient(canvasClient)
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/CanvasStateTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/CanvasStateTests.java
index becc2f7..1e7a832 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/CanvasStateTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/CanvasStateTests.java
@@ -20,9 +20,12 @@
 import android.graphics.Path;
 import android.graphics.RectF;
 import android.graphics.Region;
-import android.test.suitebuilder.annotation.SmallTest;
+import android.test.suitebuilder.annotation.MediumTest;
 import android.uirendering.cts.testinfrastructure.ActivityTestBase;
-import android.uirendering.cts.testinfrastructure.CanvasClient;
+import org.junit.Test;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 
 /**
  * Tests of state query-able from canvas at draw time.
@@ -30,96 +33,84 @@
  * Although these tests don't verify drawing content, they still make use of ActivityTestBase's
  * capability to test the hardware accelerated Canvas in the way that it is used by Views.
  */
+@MediumTest
 public class CanvasStateTests extends ActivityTestBase {
-
-    @SmallTest
+    @Test
     public void testClipRectReturnValues() {
         createTest()
-                .addCanvasClient(new CanvasClient() {
-                    @Override
-                    public void draw(Canvas canvas, int width, int height) {
-                        canvas.save();
-                        boolean isNonEmpty = canvas.clipRect(0, 0, 20, 20);
-                        assertTrue("clip state should be non empty", isNonEmpty);
+                .addCanvasClient((canvas, width, height) -> {
+                    canvas.save();
+                    boolean isNonEmpty = canvas.clipRect(0, 0, 20, 20);
+                    assertTrue("clip state should be non empty", isNonEmpty);
 
-                        isNonEmpty = canvas.clipRect(0, 40, 20, 60);
-                        assertFalse("clip state should be empty", isNonEmpty);
-                        canvas.restore();
-                    }
+                    isNonEmpty = canvas.clipRect(0, 40, 20, 60);
+                    assertFalse("clip state should be empty", isNonEmpty);
+                    canvas.restore();
                 })
                 .runWithoutVerification();
     }
 
-    @SmallTest
+    @Test
     public void testClipRegionReturnValues() {
         createTest()
-                .addCanvasClient(new CanvasClient() {
-                    @Override
-                    public void draw(Canvas canvas, int width, int height) {
-                        canvas.save();
-                        RectF clipRectF = new RectF(0, 0, 20, 20);
+                .addCanvasClient((canvas, width, height) -> {
+                    canvas.save();
+                    RectF clipRectF = new RectF(0, 0, 20, 20);
 
-                        assertFalse(canvas.quickReject(0, 0, 20, 20, Canvas.EdgeType.BW));
-                        if (!canvas.isHardwareAccelerated()) {
-                            // SW canvas may not be in View space, so we offset the clipping region
-                            // so it will operate within the canvas client's window.
-                            // (Currently, this isn't necessary, since SW layer size == draw area)
-                            canvas.getMatrix().mapRect(clipRectF);
-                        }
-
-                        Region rectRegion = new Region();
-                        rectRegion.set((int) clipRectF.left, (int) clipRectF.top,
-                                (int) clipRectF.right, (int) clipRectF.bottom);
-
-                        boolean isNonEmpty = canvas.clipRegion(rectRegion);
-                        assertTrue("clip state should be non empty", isNonEmpty);
-
-                        // Note: we don't test that non-intersecting clip regions empty the clip,
-                        // For region clipping, the impl is allowed to return true conservatively
-                        // in many cases.
-                        canvas.restore();
+                    assertFalse(canvas.quickReject(0, 0, 20, 20, Canvas.EdgeType.BW));
+                    if (!canvas.isHardwareAccelerated()) {
+                        // SW canvas may not be in View space, so we offset the clipping region
+                        // so it will operate within the canvas client's window.
+                        // (Currently, this isn't necessary, since SW layer size == draw area)
+                        canvas.getMatrix().mapRect(clipRectF);
                     }
+
+                    Region rectRegion = new Region();
+                    rectRegion.set((int) clipRectF.left, (int) clipRectF.top,
+                            (int) clipRectF.right, (int) clipRectF.bottom);
+
+                    boolean isNonEmpty = canvas.clipRegion(rectRegion);
+                    assertTrue("clip state should be non empty", isNonEmpty);
+
+                    // Note: we don't test that non-intersecting clip regions empty the clip,
+                    // For region clipping, the impl is allowed to return true conservatively
+                    // in many cases.
+                    canvas.restore();
                 })
                 .runWithoutVerification();
     }
 
-    @SmallTest
+    @Test
     public void testClipPathReturnValues() {
         createTest()
-                .addCanvasClient(new CanvasClient() {
-                    @Override
-                    public void draw(Canvas canvas, int width, int height) {
-                        canvas.save();
-                        Path rectPath = new Path();
-                        rectPath.addRect(0, 0, 20, 20, Path.Direction.CW);
+                .addCanvasClient((canvas, width, height) -> {
+                    canvas.save();
+                    Path rectPath = new Path();
+                    rectPath.addRect(0, 0, 20, 20, Path.Direction.CW);
 
-                        boolean isNonEmpty = canvas.clipPath(rectPath);
-                        assertTrue("clip state should be non empty", isNonEmpty);
+                    boolean isNonEmpty = canvas.clipPath(rectPath);
+                    assertTrue("clip state should be non empty", isNonEmpty);
 
-                        rectPath.offset(0, 40);
-                        isNonEmpty = canvas.clipPath(rectPath);
-                        assertFalse("clip state should be empty", isNonEmpty);
-                        canvas.restore();
-                    }
+                    rectPath.offset(0, 40);
+                    isNonEmpty = canvas.clipPath(rectPath);
+                    assertFalse("clip state should be empty", isNonEmpty);
+                    canvas.restore();
                 })
                 .runWithoutVerification();
     }
-    @SmallTest
+    @Test
     public void testQuickReject() {
         createTest()
-                .addCanvasClient(new CanvasClient() {
-                    @Override
-                    public void draw(Canvas canvas, int width, int height) {
-                        canvas.save();
-                        canvas.clipRect(0, 0, 20, 20);
+                .addCanvasClient((canvas, width, height) -> {
+                    canvas.save();
+                    canvas.clipRect(0, 0, 20, 20);
 
-                        // not rejected!
-                        assertFalse(canvas.quickReject(0, 0, 20, 20, Canvas.EdgeType.BW));
+                    // not rejected!
+                    assertFalse(canvas.quickReject(0, 0, 20, 20, Canvas.EdgeType.BW));
 
-                        // rejected!
-                        assertTrue(canvas.quickReject(0, 40, 20, 60, Canvas.EdgeType.BW));
-                        canvas.restore();
-                    }
+                    // rejected!
+                    assertTrue(canvas.quickReject(0, 40, 20, 60, Canvas.EdgeType.BW));
+                    canvas.restore();
                 })
                 .runWithoutVerification();
     }
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ColorFilterAlphaTest.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ColorFilterAlphaTest.java
new file mode 100644
index 0000000..483ad87
--- /dev/null
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ColorFilterAlphaTest.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.uirendering.cts.testclasses;
+
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Point;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffXfermode;
+import android.graphics.PorterDuffColorFilter;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.uirendering.cts.bitmapverifiers.SamplePointVerifier;
+import android.uirendering.cts.testinfrastructure.ActivityTestBase;
+import android.uirendering.cts.testinfrastructure.CanvasClient;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.util.List;
+
+@MediumTest
+@RunWith(Parameterized.class)
+public class ColorFilterAlphaTest extends ActivityTestBase {
+    // We care about one point in each of the four rectangles of different alpha values, as well as
+    // the area outside the rectangles
+
+    public static final int FILTER_COLOR = 0xFFBB0000;
+
+    private static final Point[] TEST_POINTS = new Point[] {
+            new Point(9, 45),
+            new Point(27, 45),
+            new Point(45, 45),
+            new Point(63, 45),
+            new Point(81, 45)
+    };
+
+    private static Object[][] MODES_AND_EXPECTED_COLORS = new Object[][] {
+        { PorterDuff.Mode.DST, new int[] {
+                0xFFE6E6E6, 0xFFCCCCCC, 0xFFB3B3B3, 0xFF999999, 0xFFFFFFFF } },
+
+        { PorterDuff.Mode.SRC_OVER, new int[] {
+                0xFFBB0000, 0xFFBB0000, 0xFFBB0000, 0xFFBB0000, 0xFFBB0000 } },
+
+        { PorterDuff.Mode.DST_OVER, new int[] {
+                0xFFAF1A1A, 0xFFA33333, 0xFF984D4D, 0xFF8B6666, 0xFFBB0000 } },
+
+        { PorterDuff.Mode.SRC_IN, new int[] {
+                0xFFF1CCCC, 0xFFE49999, 0xFFD66666, 0xFFC83333, 0xFFFFFFFF } },
+
+        { PorterDuff.Mode.DST_IN, new int[] {
+                0xFFE6E6E6, 0xFFCCCCCC, 0xFFB3B3B3, 0xFF999999, 0xFFFFFFFF } },
+
+        { PorterDuff.Mode.SRC_OUT, new int[] {
+                0xFFC83333, 0xFFD66666, 0xFFE49999, 0xFFF1CCCC, 0xFFBB0000 } },
+
+        { PorterDuff.Mode.DST_OUT, new int[] {
+                0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF } },
+
+        { PorterDuff.Mode.SRC_ATOP, new int[] {
+                0xFFF1CCCC, 0xFFE49999, 0xFFD66666, 0xFFC93333, 0xFFFFFFFF } },
+
+        { PorterDuff.Mode.DST_ATOP, new int[] {
+                0xFFB01A1A, 0xFFA33333, 0xFF984D4D, 0xFF8B6666, 0xFFBB0000 } },
+
+        { PorterDuff.Mode.XOR, new int[] {
+                0xFFC93333, 0xFFD66666, 0xFFE49999, 0xFFF1CCCC, 0xFFBB0000 } },
+
+        { PorterDuff.Mode.MULTIPLY, new int[] {
+                0xFFDFCCCC, 0xFFBE9999, 0xFF9E6666, 0xFF7E3333, 0xFFFFFFFF } },
+
+        { PorterDuff.Mode.SCREEN, new int[] {
+                0xFFC21A1A, 0xFFC93333, 0xFFD04D4D, 0xFFD66666, 0xFFBB0000 } },
+    };
+
+    @Parameterized.Parameters(name = "{0}")
+    public static List<XfermodeTest.Config> configs() {
+        return XfermodeTest.configs(MODES_AND_EXPECTED_COLORS);
+    }
+
+    private final XfermodeTest.Config mConfig;
+
+    public ColorFilterAlphaTest(XfermodeTest.Config config) {
+        mConfig = config;
+    }
+
+    private static final int[] BLOCK_COLORS = new int[] {
+            0x33808080,
+            0x66808080,
+            0x99808080,
+            0xCC808080,
+            0x00000000
+    };
+
+    private static Bitmap createMultiRectBitmap() {
+        Bitmap bitmap = Bitmap.createBitmap(TEST_WIDTH, TEST_HEIGHT, Bitmap.Config.ARGB_8888);
+        Canvas canvas = new Canvas(bitmap);
+        Paint paint = new Paint();
+        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
+        final int blockCount = BLOCK_COLORS.length;
+        final int blockWidth = TEST_WIDTH / blockCount;
+        for (int i = 0 ; i < blockCount; i++) {
+            paint.setColor(BLOCK_COLORS[i]);
+            canvas.drawRect(i * blockWidth, 0, (i + 1) * blockWidth, TEST_HEIGHT, paint);
+        }
+        return bitmap;
+    }
+
+    private CanvasClient mCanvasClient = new CanvasClient() {
+        final Paint mPaint = new Paint();
+        private final Bitmap mBitmap = createMultiRectBitmap();
+
+        @Override
+        public void draw(Canvas canvas, int width, int height) {
+            mPaint.setColorFilter(new PorterDuffColorFilter(FILTER_COLOR, mConfig.mode));
+            canvas.drawBitmap(mBitmap, 0, 0, mPaint);
+        }
+    };
+
+    @Test
+    public void test() {
+        createTest()
+                .addCanvasClient(mCanvasClient, mConfig.hardwareAccelerated)
+                .runWithVerifier(new SamplePointVerifier(TEST_POINTS, mConfig.expectedColors));
+    }
+}
+
+
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ExactCanvasTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ExactCanvasTests.java
index 29755d8..2a2599b 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ExactCanvasTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ExactCanvasTests.java
@@ -16,168 +16,139 @@
 
 package android.uirendering.cts.testclasses;
 
-import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.Paint;
 import android.graphics.PorterDuff;
 import android.graphics.Rect;
 import android.graphics.drawable.NinePatchDrawable;
-import android.test.suitebuilder.annotation.SmallTest;
+import android.test.suitebuilder.annotation.MediumTest;
 import android.uirendering.cts.bitmapcomparers.BitmapComparer;
 import android.uirendering.cts.bitmapcomparers.ExactComparer;
 import android.uirendering.cts.bitmapverifiers.BitmapVerifier;
 import android.uirendering.cts.bitmapverifiers.RectVerifier;
 import android.uirendering.cts.testinfrastructure.ActivityTestBase;
-import android.uirendering.cts.testinfrastructure.CanvasClient;
-import com.android.cts.uirendering.R;
+import android.uirendering.cts.R;
+import org.junit.Test;
 
+@MediumTest
 public class ExactCanvasTests extends ActivityTestBase {
     private final BitmapComparer mExactComparer = new ExactComparer();
 
-    @SmallTest
+    @Test
     public void testBlueRect() {
         final Rect rect = new Rect(10, 10, 80, 80);
         createTest()
-                .addCanvasClient(new CanvasClient() {
-                    @Override
-                    public void draw(Canvas canvas, int width, int height) {
-                        Paint p = new Paint();
-                        p.setAntiAlias(false);
-                        p.setColor(Color.BLUE);
-                        canvas.drawRect(rect, p);
-                    }
+                .addCanvasClient((canvas, width, height) -> {
+                    Paint p = new Paint();
+                    p.setAntiAlias(false);
+                    p.setColor(Color.BLUE);
+                    canvas.drawRect(rect, p);
                 })
                 .runWithVerifier(new RectVerifier(Color.WHITE, Color.BLUE, rect));
     }
 
-    @SmallTest
+    @Test
     public void testPoints() {
         createTest()
-                .addCanvasClient(new CanvasClient() {
-                    @Override
-                    public void draw(Canvas canvas, int width, int height) {
-                        Paint p = new Paint();
-                        p.setAntiAlias(false);
-                        p.setStrokeWidth(1f);
-                        p.setColor(Color.BLACK);
-                        for (int i = 0; i < 10; i++) {
-                            canvas.drawPoint(i * 10, i * 10, p);
-                        }
+                .addCanvasClient((canvas, width, height) -> {
+                    Paint p = new Paint();
+                    p.setAntiAlias(false);
+                    p.setStrokeWidth(1f);
+                    p.setColor(Color.BLACK);
+                    for (int i = 0; i < 10; i++) {
+                        canvas.drawPoint(i * 10, i * 10, p);
                     }
                 })
                 .runWithComparer(mExactComparer);
     }
 
-    @SmallTest
+    @Test
     public void testBlackRectWithStroke() {
         createTest()
-                .addCanvasClient(new CanvasClient() {
-                    @Override
-                    public void draw(Canvas canvas, int width, int height) {
-                        Paint p = new Paint();
-                        p.setColor(Color.RED);
-                        canvas.drawRect(0, 0, ActivityTestBase.TEST_WIDTH,
-                                ActivityTestBase.TEST_HEIGHT, p);
-                        p.setColor(Color.BLACK);
-                        p.setStrokeWidth(5);
-                        canvas.drawRect(10, 10, 80, 80, p);
-                    }
+                .addCanvasClient((canvas, width, height) -> {
+                    Paint p = new Paint();
+                    p.setColor(Color.RED);
+                    canvas.drawRect(0, 0, ActivityTestBase.TEST_WIDTH,
+                            ActivityTestBase.TEST_HEIGHT, p);
+                    p.setColor(Color.BLACK);
+                    p.setStrokeWidth(5);
+                    canvas.drawRect(10, 10, 80, 80, p);
                 })
                 .runWithComparer(mExactComparer);
     }
 
-    @SmallTest
+    @Test
     public void testBlackLineOnGreenBack() {
         createTest()
-                .addCanvasClient(new CanvasClient() {
-                    @Override
-                    public void draw(Canvas canvas, int width, int height) {
-                        canvas.drawColor(Color.GREEN);
-                        Paint p = new Paint();
-                        p.setColor(Color.BLACK);
-                        p.setStrokeWidth(10);
-                        canvas.drawLine(0, 0, 50, 0, p);
-                    }
+                .addCanvasClient((canvas, width, height) -> {
+                    canvas.drawColor(Color.GREEN);
+                    Paint p = new Paint();
+                    p.setColor(Color.BLACK);
+                    p.setStrokeWidth(10);
+                    canvas.drawLine(0, 0, 50, 0, p);
                 })
                 .runWithComparer(mExactComparer);
     }
 
-    @SmallTest
+    @Test
     public void testDrawRedRectOnBlueBack() {
         createTest()
-                .addCanvasClient(new CanvasClient() {
-                    @Override
-                    public void draw(Canvas canvas, int width, int height) {
-                        canvas.drawColor(Color.BLUE);
-                        Paint p = new Paint();
-                        p.setColor(Color.RED);
-                        canvas.drawRect(10, 10, 40, 40, p);
-                    }
+                .addCanvasClient((canvas, width, height) -> {
+                    canvas.drawColor(Color.BLUE);
+                    Paint p = new Paint();
+                    p.setColor(Color.RED);
+                    canvas.drawRect(10, 10, 40, 40, p);
                 })
                 .runWithComparer(mExactComparer);
     }
 
-    @SmallTest
+    @Test
     public void testDrawLine() {
         createTest()
-                .addCanvasClient(new CanvasClient() {
-                    @Override
-                    public void draw(Canvas canvas, int width, int height) {
-                        Paint p = new Paint();
-                        canvas.drawColor(Color.WHITE);
-                        p.setColor(Color.BLACK);
-                        float[] pts = {
-                                0, 0, 80, 80, 80, 0, 0, 80, 40, 50, 60, 50
-                        };
-                        canvas.drawLines(pts, p);
-                    }
+                .addCanvasClient((canvas, width, height) -> {
+                    Paint p = new Paint();
+                    canvas.drawColor(Color.WHITE);
+                    p.setColor(Color.BLACK);
+                    float[] pts = {
+                            0, 0, 80, 80, 80, 0, 0, 80, 40, 50, 60, 50
+                    };
+                    canvas.drawLines(pts, p);
                 })
                 .runWithComparer(mExactComparer);
     }
 
-    @SmallTest
+    @Test
     public void testDrawWhiteScreen() {
         createTest()
-                .addCanvasClient(new CanvasClient() {
-                    @Override
-                    public void draw(Canvas canvas, int width, int height) {
-                        canvas.drawColor(Color.WHITE);
-                    }
-                })
+                .addCanvasClient((canvas, width, height) -> canvas.drawColor(Color.WHITE))
                 .runWithComparer(mExactComparer);
     }
 
-    @SmallTest
+    @Test
     public void testBasicText() {
         final String testString = "THIS IS A TEST";
         createTest()
-                .addCanvasClient(new CanvasClient() {
-                    @Override
-                    public void draw(Canvas canvas, int width, int height) {
-                        Paint p = new Paint();
-                        canvas.drawColor(Color.BLACK);
-                        p.setColor(Color.WHITE);
-                        p.setStrokeWidth(5);
-                        canvas.drawText(testString, 30, 50, p);
-                    }
+                .addCanvasClient((canvas, width, height) -> {
+                    Paint p = new Paint();
+                    canvas.drawColor(Color.BLACK);
+                    p.setColor(Color.WHITE);
+                    p.setStrokeWidth(5);
+                    canvas.drawText(testString, 30, 50, p);
                 })
                 .runWithComparer(mExactComparer);
     }
 
-    @SmallTest
+    @Test
     public void testBasicColorXfermode() {
         createTest()
-                .addCanvasClient(new CanvasClient() {
-                    @Override
-                    public void draw(Canvas canvas, int width, int height) {
-                        canvas.drawColor(Color.GRAY);
-                        canvas.drawColor(Color.BLUE, PorterDuff.Mode.MULTIPLY);
-                    }
+                .addCanvasClient((canvas, width, height) -> {
+                    canvas.drawColor(Color.GRAY);
+                    canvas.drawColor(Color.BLUE, PorterDuff.Mode.MULTIPLY);
                 })
                 .runWithComparer(mExactComparer);
     }
 
-    @SmallTest
+    @Test
     public void testBluePaddedSquare() {
         final NinePatchDrawable ninePatchDrawable = (NinePatchDrawable)
             getActivity().getResources().getDrawable(R.drawable.blue_padded_square);
@@ -187,21 +158,13 @@
                 new Rect(10, 10, 80, 80));
 
         createTest()
-                .addCanvasClient(new CanvasClient() {
-                    @Override
-                    public void draw(Canvas canvas, int width, int height) {
-                        canvas.drawColor(Color.WHITE);
-                        Paint p = new Paint();
-                        p.setColor(Color.BLUE);
-                        canvas.drawRect(10, 10, 80, 80, p);
-                    }
+                .addCanvasClient((canvas, width, height) -> {
+                    canvas.drawColor(Color.WHITE);
+                    Paint p = new Paint();
+                    p.setColor(Color.BLUE);
+                    canvas.drawRect(10, 10, 80, 80, p);
                 })
-                .addCanvasClient(new CanvasClient() {
-                    @Override
-                    public void draw(Canvas canvas, int width, int height) {
-                        ninePatchDrawable.draw(canvas);
-                    }
-                })
+                .addCanvasClient((canvas, width, height) -> ninePatchDrawable.draw(canvas))
                 .addLayout(R.layout.blue_padded_square, null)
                 .runWithVerifier(verifier);
     }
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/FontRenderingTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/FontRenderingTests.java
index 5833f20..73779d6 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/FontRenderingTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/FontRenderingTests.java
@@ -22,15 +22,17 @@
 import android.graphics.Color;
 import android.graphics.Paint;
 import android.graphics.Typeface;
-import android.test.suitebuilder.annotation.SmallTest;
+import android.test.suitebuilder.annotation.MediumTest;
 import android.uirendering.cts.bitmapcomparers.BitmapComparer;
 import android.uirendering.cts.bitmapcomparers.MSSIMComparer;
 import android.uirendering.cts.bitmapverifiers.GoldenImageVerifier;
 import android.uirendering.cts.testinfrastructure.ActivityTestBase;
 import android.uirendering.cts.testinfrastructure.CanvasClient;
 
-import com.android.cts.uirendering.R;
+import android.uirendering.cts.R;
+import org.junit.Test;
 
+@MediumTest
 public class FontRenderingTests extends ActivityTestBase {
     // Thresholds are barely loose enough for differences between sw and hw renderers.
     private static final double REGULAR_THRESHOLD = 0.92;
@@ -51,58 +53,55 @@
 
         final Typeface typeface = Typeface.create(family, style);
         createTest()
-                .addCanvasClient(new CanvasClient() {
-                    @Override
-                    public void draw(Canvas canvas, int width, int height) {
-                        Paint p = new Paint();
-                        p.setAntiAlias(true);
-                        p.setColor(Color.BLACK);
-                        p.setTextSize(26);
-                        p.setTypeface(typeface);
-                        canvas.drawText(sTestString1, 1, 20, p);
-                        canvas.drawText(sTestString2, 1, 50, p);
-                        canvas.drawText(sTestString3, 1, 80, p);
-                    }
+                .addCanvasClient((canvas, width, height) -> {
+                    Paint p = new Paint();
+                    p.setAntiAlias(true);
+                    p.setColor(Color.BLACK);
+                    p.setTextSize(26);
+                    p.setTypeface(typeface);
+                    canvas.drawText(sTestString1, 1, 20, p);
+                    canvas.drawText(sTestString2, 1, 50, p);
+                    canvas.drawText(sTestString3, 1, 80, p);
                 })
                 .runWithVerifier(new GoldenImageVerifier(goldenBitmap, comparer));
     }
 
-    @SmallTest
+    @Test
     public void testDefaultFont() {
         fontTestBody("sans-serif",
                 Typeface.NORMAL,
                 R.drawable.hello1);
     }
 
-    @SmallTest
+    @Test
     public void testBoldFont() {
         fontTestBody("sans-serif",
                 Typeface.BOLD,
                 R.drawable.bold1);
     }
 
-    @SmallTest
+    @Test
     public void testItalicFont() {
         fontTestBody("sans-serif",
                 Typeface.ITALIC,
                 R.drawable.italic1);
     }
 
-    @SmallTest
+    @Test
     public void testBoldItalicFont() {
         fontTestBody("sans-serif",
                 Typeface.BOLD | Typeface.ITALIC,
                 R.drawable.bolditalic1);
     }
 
-    @SmallTest
+    @Test
     public void testMediumFont() {
         fontTestBody("sans-serif-medium",
                 Typeface.NORMAL,
                 R.drawable.medium1);
     }
 
-    @SmallTest
+    @Test
     public void testMediumBoldFont() {
         // bold attribute on medium base font = black
         fontTestBody("sans-serif-medium",
@@ -110,28 +109,28 @@
                 R.drawable.black1);
     }
 
-    @SmallTest
+    @Test
     public void testMediumItalicFont() {
         fontTestBody("sans-serif-medium",
                 Typeface.ITALIC,
                 R.drawable.mediumitalic1);
     }
 
-    @SmallTest
+    @Test
     public void testMediumBoldItalicFont() {
         fontTestBody("sans-serif-medium",
                 Typeface.BOLD | Typeface.ITALIC,
                 R.drawable.blackitalic1);
     }
 
-    @SmallTest
+    @Test
     public void testLightFont() {
         fontTestBody("sans-serif-light",
                 Typeface.NORMAL,
                 R.drawable.light1);
     }
 
-    @SmallTest
+    @Test
     public void testLightBoldFont() {
         // bold attribute on light base font = medium
         fontTestBody("sans-serif-light",
@@ -139,28 +138,28 @@
                 R.drawable.medium1);
     }
 
-    @SmallTest
+    @Test
     public void testLightItalicFont() {
         fontTestBody("sans-serif-light",
                 Typeface.ITALIC,
                 R.drawable.lightitalic1);
     }
 
-    @SmallTest
+    @Test
     public void testLightBoldItalicFont() {
         fontTestBody("sans-serif-light",
                 Typeface.BOLD | Typeface.ITALIC,
                 R.drawable.mediumitalic1);
     }
 
-    @SmallTest
+    @Test
     public void testThinFont() {
         fontTestBody("sans-serif-thin",
                 Typeface.NORMAL,
                 R.drawable.thin1);
     }
 
-    @SmallTest
+    @Test
     public void testThinBoldFont() {
         // bold attribute on thin base font = normal
         fontTestBody("sans-serif-thin",
@@ -168,28 +167,28 @@
                 R.drawable.hello1);
     }
 
-    @SmallTest
+    @Test
     public void testThinItalicFont() {
         fontTestBody("sans-serif-thin",
                 Typeface.ITALIC,
                 R.drawable.thinitalic1);
     }
 
-    @SmallTest
+    @Test
     public void testThinBoldItalicFont() {
         fontTestBody("sans-serif-thin",
                 Typeface.BOLD | Typeface.ITALIC,
                 R.drawable.italic1);
     }
 
-    @SmallTest
+    @Test
     public void testBlackFont() {
         fontTestBody("sans-serif-black",
                 Typeface.NORMAL,
                 R.drawable.black1);
     }
 
-    @SmallTest
+    @Test
     public void testBlackBoldFont() {
         // bold attribute on black base font = black
         fontTestBody("sans-serif-black",
@@ -197,14 +196,14 @@
                 R.drawable.black1);
     }
 
-    @SmallTest
+    @Test
     public void testBlackItalicFont() {
         fontTestBody("sans-serif-black",
                 Typeface.ITALIC,
                 R.drawable.blackitalic1);
     }
 
-    @SmallTest
+    @Test
     public void testBlackBoldItalicFont() {
         fontTestBody("sans-serif-black",
                 Typeface.BOLD | Typeface.ITALIC,
@@ -213,42 +212,42 @@
 
     /* condensed fonts */
 
-    @SmallTest
+    @Test
     public void testCondensedFont() {
         fontTestBody("sans-serif-condensed",
                 Typeface.NORMAL,
                 R.drawable.condensed1);
     }
 
-    @SmallTest
+    @Test
     public void testCondensedBoldFont() {
         fontTestBody("sans-serif-condensed",
                 Typeface.BOLD,
                 R.drawable.condensedbold1);
     }
 
-    @SmallTest
+    @Test
     public void testCondensedItalicFont() {
         fontTestBody("sans-serif-condensed",
                 Typeface.ITALIC,
                 R.drawable.condenseditalic1);
     }
 
-    @SmallTest
+    @Test
     public void testCondensedBoldItalicFont() {
         fontTestBody("sans-serif-condensed",
                 Typeface.BOLD | Typeface.ITALIC,
                 R.drawable.condensedbolditalic1);
     }
 
-    @SmallTest
+    @Test
     public void testCondensedLightFont() {
         fontTestBody("sans-serif-condensed-light",
                 Typeface.NORMAL,
                 R.drawable.condensedlight1);
     }
 
-    @SmallTest
+    @Test
     public void testCondensedLightItalicFont() {
         fontTestBody("sans-serif-condensed-light",
                 Typeface.ITALIC,
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/InfrastructureTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/InfrastructureTests.java
index dfaaaea..212e666 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/InfrastructureTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/InfrastructureTests.java
@@ -16,12 +16,11 @@
 package android.uirendering.cts.testclasses;
 
 import android.graphics.Point;
-import com.android.cts.uirendering.R;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.uirendering.cts.R;
 
-import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.Rect;
-import android.test.suitebuilder.annotation.SmallTest;
 import android.uirendering.cts.bitmapcomparers.BitmapComparer;
 import android.uirendering.cts.bitmapcomparers.MSSIMComparer;
 import android.uirendering.cts.bitmapverifiers.RectVerifier;
@@ -29,10 +28,12 @@
 import android.uirendering.cts.testinfrastructure.CanvasClient;
 import android.uirendering.cts.testinfrastructure.ViewInitializer;
 import android.view.View;
+import org.junit.Test;
 
+@MediumTest
 public class InfrastructureTests extends ActivityTestBase {
 
-    @SmallTest
+    @Test
     public void testScreenshot() {
         for (int i = 0 ; i < 500 ; i ++) {
             takeScreenshot(new Point());
@@ -45,13 +46,10 @@
      * by verifying that two paths that should render differently *do* render
      * differently.
      */
-    @SmallTest
+    @Test
     public void testRenderSpecIsolation() {
-        CanvasClient canvasClient = new CanvasClient() {
-            @Override
-            public void draw(Canvas canvas, int width, int height) {
-                canvas.drawColor(canvas.isHardwareAccelerated() ? Color.BLACK : Color.WHITE);
-            }
+        CanvasClient canvasClient = (canvas, width, height) -> {
+            canvas.drawColor(canvas.isHardwareAccelerated() ? Color.BLACK : Color.WHITE);
         };
         BitmapComparer inverseComparer = new BitmapComparer() {
             @Override
@@ -70,15 +68,10 @@
                 .runWithComparer(inverseComparer);
     }
 
-    @SmallTest
+    @Test
     public void testViewInitializer() {
         final Rect clipRect = new Rect(0, 0, 50, 50);
-        ViewInitializer viewInitializer = new ViewInitializer() {
-            @Override
-            public void initializeView(View view) {
-                view.setClipBounds(clipRect);
-            }
-        };
+        ViewInitializer viewInitializer = view -> view.setClipBounds(clipRect);
         createTest()
                 .addLayout(R.layout.simple_red_layout, viewInitializer)
                 .runWithVerifier(new RectVerifier(Color.WHITE, Color.RED, clipRect));
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/LayerTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/LayerTests.java
index a5f76dd..53112d6 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/LayerTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/LayerTests.java
@@ -23,77 +23,73 @@
 import android.graphics.Paint;
 import android.graphics.PorterDuff;
 import android.graphics.PorterDuffXfermode;
-import android.test.suitebuilder.annotation.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.test.suitebuilder.annotation.MediumTest;
 import android.uirendering.cts.bitmapverifiers.ColorVerifier;
 import android.uirendering.cts.testinfrastructure.ActivityTestBase;
 import android.uirendering.cts.testinfrastructure.ViewInitializer;
 import android.view.View;
-import com.android.cts.uirendering.R;
+import android.uirendering.cts.R;
+import org.junit.Test;
+import org.junit.runner.RunWith;
 
+@MediumTest
+@RunWith(AndroidJUnit4.class)
 public class LayerTests extends ActivityTestBase {
-    @SmallTest
+    @Test
     public void testLayerPaintAlpha() {
         // red channel full strength, other channels 75% strength
         // (since 25% alpha red subtracts from them)
         @ColorInt
         final int expectedColor = Color.rgb(255, 191, 191);
         createTest()
-                .addLayout(R.layout.simple_red_layout, new ViewInitializer() {
-                    @Override
-                    public void initializeView(View view) {
-                        // reduce alpha by 50%
-                        Paint paint = new Paint();
-                        paint.setAlpha(128);
-                        view.setLayerType(View.LAYER_TYPE_HARDWARE, paint);
+                .addLayout(R.layout.simple_red_layout, (ViewInitializer) view -> {
+                    // reduce alpha by 50%
+                    Paint paint = new Paint();
+                    paint.setAlpha(128);
+                    view.setLayerType(View.LAYER_TYPE_HARDWARE, paint);
 
-                        // reduce alpha by another 50% (ensuring two alphas combine correctly)
-                        view.setAlpha(0.5f);
-                    }
+                    // reduce alpha by another 50% (ensuring two alphas combine correctly)
+                    view.setAlpha(0.5f);
                 })
                 .runWithVerifier(new ColorVerifier(expectedColor));
     }
 
-    @SmallTest
+    @Test
     public void testLayerPaintColorFilter() {
         // Red, fully desaturated. Note that it's not 255/3 in each channel.
         // See ColorMatrix#setSaturation()
         @ColorInt
         final int expectedColor = Color.rgb(54, 54, 54);
         createTest()
-                .addLayout(R.layout.simple_red_layout, new ViewInitializer() {
-                    @Override
-                    public void initializeView(View view) {
-                        Paint paint = new Paint();
-                        ColorMatrix desatMatrix = new ColorMatrix();
-                        desatMatrix.setSaturation(0.0f);
-                        paint.setColorFilter(new ColorMatrixColorFilter(desatMatrix));
-                        view.setLayerType(View.LAYER_TYPE_HARDWARE, paint);
-                    }
+                .addLayout(R.layout.simple_red_layout, (ViewInitializer) view -> {
+                    Paint paint = new Paint();
+                    ColorMatrix desatMatrix = new ColorMatrix();
+                    desatMatrix.setSaturation(0.0f);
+                    paint.setColorFilter(new ColorMatrixColorFilter(desatMatrix));
+                    view.setLayerType(View.LAYER_TYPE_HARDWARE, paint);
                 })
                 .runWithVerifier(new ColorVerifier(expectedColor));
     }
 
-    @SmallTest
+    @Test
     public void testLayerPaintBlend() {
         // Red, drawn underneath opaque white, so output should be white.
         // TODO: consider doing more interesting blending test here
         @ColorInt
         final int expectedColor = Color.WHITE;
         createTest()
-                .addLayout(R.layout.simple_red_layout, new ViewInitializer() {
-                    @Override
-                    public void initializeView(View view) {
-                        Paint paint = new Paint();
-                        /* Note that when drawing in SW, we're blending within an otherwise empty
-                         * SW layer, as opposed to in the frame buffer (which has a white
-                         * background).
-                         *
-                         * For this reason we use just use DST, which just throws out the SRC
-                         * content, regardless of the DST alpha channel.
-                         */
-                        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST));
-                        view.setLayerType(View.LAYER_TYPE_HARDWARE, paint);
-                    }
+                .addLayout(R.layout.simple_red_layout, (ViewInitializer) view -> {
+                    Paint paint = new Paint();
+                    /* Note that when drawing in SW, we're blending within an otherwise empty
+                     * SW layer, as opposed to in the frame buffer (which has a white
+                     * background).
+                     *
+                     * For this reason we use just use DST, which just throws out the SRC
+                     * content, regardless of the DST alpha channel.
+                     */
+                    paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST));
+                    view.setLayerType(View.LAYER_TYPE_HARDWARE, paint);
                 })
                 .runWithVerifier(new ColorVerifier(expectedColor));
     }
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/LayoutTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/LayoutTests.java
index ff1e9db..d69126c 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/LayoutTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/LayoutTests.java
@@ -17,21 +17,23 @@
 
 import android.graphics.Color;
 import android.graphics.Rect;
+import android.test.suitebuilder.annotation.MediumTest;
 import android.uirendering.cts.bitmapverifiers.ColorVerifier;
 import android.uirendering.cts.bitmapverifiers.RectVerifier;
-import com.android.cts.uirendering.R;
+import android.uirendering.cts.R;
 
-import android.test.suitebuilder.annotation.SmallTest;
 import android.uirendering.cts.testinfrastructure.ActivityTestBase;
+import org.junit.Test;
 
+@MediumTest
 public class LayoutTests extends ActivityTestBase {
-    @SmallTest
+    @Test
     public void testSimpleRedLayout() {
         createTest().addLayout(R.layout.simple_red_layout, null, false).runWithVerifier(
                 new ColorVerifier(Color.RED));
     }
 
-    @SmallTest
+    @Test
     public void testSimpleRectLayout() {
         createTest().addLayout(R.layout.simple_rect_layout, null, false).runWithVerifier(
                 new RectVerifier(Color.WHITE, Color.BLUE, new Rect(5, 5, 85, 85)));
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/PathClippingTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/PathClippingTests.java
index 38777a2..7c8a301 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/PathClippingTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/PathClippingTests.java
@@ -23,7 +23,7 @@
 import android.graphics.Path;
 import android.graphics.Point;
 import android.graphics.Typeface;
-import android.test.suitebuilder.annotation.SmallTest;
+import android.test.suitebuilder.annotation.MediumTest;
 import android.uirendering.cts.bitmapcomparers.MSSIMComparer;
 import android.uirendering.cts.bitmapverifiers.SamplePointVerifier;
 import android.uirendering.cts.testinfrastructure.ActivityTestBase;
@@ -32,61 +32,49 @@
 import android.view.View;
 import android.view.ViewGroup;
 import android.webkit.WebView;
-import com.android.cts.uirendering.R;
+import android.uirendering.cts.R;
+import org.junit.Test;
 
+import static org.junit.Assert.assertNotNull;
+
+@MediumTest
 public class PathClippingTests extends ActivityTestBase {
     // draw circle with hole in it, with stroked circle
-    static final CanvasClient sTorusDrawCanvasClient = new CanvasClient() {
-        @Override
-        public String getDebugString() {
-            return "TorusDraw";
-        }
-
-        @Override
-        public void draw(Canvas canvas, int width, int height) {
-            Paint paint = new Paint();
-            paint.setAntiAlias(false);
-            paint.setColor(Color.BLUE);
-            paint.setStyle(Paint.Style.STROKE);
-            paint.setStrokeWidth(20);
-            canvas.drawCircle(30, 30, 40, paint);
-        }
+    static final CanvasClient sTorusDrawCanvasClient = (canvas, width, height) -> {
+        Paint paint = new Paint();
+        paint.setAntiAlias(false);
+        paint.setColor(Color.BLUE);
+        paint.setStyle(Paint.Style.STROKE);
+        paint.setStrokeWidth(20);
+        canvas.drawCircle(30, 30, 40, paint);
     };
 
     // draw circle with hole in it, by path operations + path clipping
-    static final CanvasClient sTorusClipCanvasClient = new CanvasClient() {
-        @Override
-        public String getDebugString() {
-            return "TorusClipDraw";
-        }
+    static final CanvasClient sTorusClipCanvasClient = (canvas, width, height) -> {
+        canvas.save();
 
-        @Override
-        public void draw(Canvas canvas, int width, int height) {
-            canvas.save();
+        Path path = new Path();
+        path.addCircle(30, 30, 50, Path.Direction.CW);
+        path.addCircle(30, 30, 30, Path.Direction.CCW);
 
-            Path path = new Path();
-            path.addCircle(30, 30, 50, Path.Direction.CW);
-            path.addCircle(30, 30, 30, Path.Direction.CCW);
+        canvas.clipPath(path);
+        canvas.drawColor(Color.BLUE);
 
-            canvas.clipPath(path);
-            canvas.drawColor(Color.BLUE);
-
-            canvas.restore();
-        }
+        canvas.restore();
     };
 
-    @SmallTest
+    @Test
     public void testCircleWithCircle() {
         createTest()
-                .addCanvasClient(sTorusDrawCanvasClient, false)
-                .addCanvasClient(sTorusClipCanvasClient)
+                .addCanvasClient("TorusDraw", sTorusDrawCanvasClient, false)
+                .addCanvasClient("TorusClip", sTorusClipCanvasClient)
                 .runWithComparer(new MSSIMComparer(0.90));
     }
 
-    @SmallTest
+    @Test
     public void testCircleWithPoints() {
         createTest()
-                .addCanvasClient(sTorusClipCanvasClient)
+                .addCanvasClient("TorusClip", sTorusClipCanvasClient)
                 .runWithVerifier(new SamplePointVerifier(
                         new Point[] {
                                 // inside of circle
@@ -105,20 +93,16 @@
                         }));
     }
 
-    @SmallTest
+    @Test
     public void testViewRotate() {
         createTest()
-                .addLayout(R.layout.blue_padded_layout, new ViewInitializer() {
-                    @Override
-                    public void initializeView(View view) {
-                        ViewGroup rootView = (ViewGroup) view;
-                        rootView.setClipChildren(true);
-                        View childView = rootView.getChildAt(0);
-                        childView.setPivotX(40);
-                        childView.setPivotY(40);
-                        childView.setRotation(45f);
-
-                    }
+                .addLayout(R.layout.blue_padded_layout, (ViewInitializer) view -> {
+                    ViewGroup rootView = (ViewGroup) view;
+                    rootView.setClipChildren(true);
+                    View childView = rootView.getChildAt(0);
+                    childView.setPivotX(40);
+                    childView.setPivotY(40);
+                    childView.setRotation(45f);
                 })
                 .runWithVerifier(new SamplePointVerifier(
                         new Point[] {
@@ -137,55 +121,46 @@
                         }));
     }
 
-    @SmallTest
+    @Test
     public void testTextClip() {
         createTest()
-                .addCanvasClient(new CanvasClient() {
-                    @Override
-                    public void draw(Canvas canvas, int width, int height) {
-                        canvas.save();
+                .addCanvasClient((canvas, width, height) -> {
+                    canvas.save();
 
-                        Path path = new Path();
-                        path.addCircle(0, 45, 45, Path.Direction.CW);
-                        path.addCircle(90, 45, 45, Path.Direction.CW);
-                        canvas.clipPath(path);
+                    Path path = new Path();
+                    path.addCircle(0, 45, 45, Path.Direction.CW);
+                    path.addCircle(90, 45, 45, Path.Direction.CW);
+                    canvas.clipPath(path);
 
-                        Paint paint = new Paint();
-                        paint.setAntiAlias(true);
-                        paint.setTextSize(90);
-                        paint.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
-                        canvas.drawText("STRING", 0, 90, paint);
+                    Paint paint = new Paint();
+                    paint.setAntiAlias(true);
+                    paint.setTextSize(90);
+                    paint.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
+                    canvas.drawText("STRING", 0, 90, paint);
 
-                        canvas.restore();
-                    }
+                    canvas.restore();
                 })
                 .runWithComparer(new MSSIMComparer(0.90));
     }
 
-    @SmallTest
+    @Test
     public void testWebViewClipWithCircle() {
         if (!getActivity().getPackageManager().hasSystemFeature(PackageManager.FEATURE_WEBVIEW)) {
             return; // no WebView to run test on
         }
         createTest()
                 // golden client - draw a simple non-AA circle
-                .addCanvasClient(new CanvasClient() {
-                    @Override
-                    public void draw(Canvas canvas, int width, int height) {
-                        Paint paint = new Paint();
-                        paint.setAntiAlias(false);
-                        paint.setColor(Color.BLUE);
-                        canvas.drawOval(0, 0, width, height, paint);
-                    }
+                .addCanvasClient((canvas, width, height) -> {
+                    Paint paint = new Paint();
+                    paint.setAntiAlias(false);
+                    paint.setColor(Color.BLUE);
+                    canvas.drawOval(0, 0, width, height, paint);
                 }, false)
                 // verify against solid color webview, clipped to its parent oval
-                .addLayout(R.layout.circle_clipped_webview, new ViewInitializer() {
-                    @Override
-                    public void initializeView(View view) {
-                        WebView webview = (WebView)view.findViewById(R.id.webview);
-                        assertNotNull(webview);
-                        webview.loadData("<body style=\"background-color:blue\">", null, null);
-                    }
+                .addLayout(R.layout.circle_clipped_webview, (ViewInitializer) view -> {
+                    WebView webview = (WebView)view.findViewById(R.id.webview);
+                    assertNotNull(webview);
+                    webview.loadData("<body style=\"background-color:blue\">", null, null);
                 })
                 .runWithComparer(new MSSIMComparer(0.95));
     }
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/PictureTest.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/PictureTest.java
index 6619b11..a2f3730 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/PictureTest.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/PictureTest.java
@@ -21,54 +21,51 @@
 import android.graphics.Paint;
 import android.graphics.Picture;
 import android.graphics.Rect;
-import android.test.suitebuilder.annotation.SmallTest;
+import android.test.suitebuilder.annotation.MediumTest;
 import android.uirendering.cts.bitmapverifiers.ColorVerifier;
 import android.uirendering.cts.bitmapverifiers.RectVerifier;
 import android.uirendering.cts.testinfrastructure.ActivityTestBase;
-import android.uirendering.cts.testinfrastructure.CanvasClient;
+import org.junit.Test;
 
+@MediumTest
 public class PictureTest extends ActivityTestBase {
 
     private static final Rect sRect = new Rect(0, 0, 40, 40);
     private static final Rect sOffsetRect = new Rect(40, 0, 80, 40);
 
-    private static final Picture greenSquare() {
+    private static Picture greenSquare() {
         Paint pt = new Paint();
         pt.setColor(Color.GREEN);
         Picture pic = new Picture();
-        Canvas subcanvas = pic.beginRecording(ActivityTestBase.TEST_WIDTH,
-                                              ActivityTestBase.TEST_HEIGHT);
+        Canvas subcanvas = pic.beginRecording(
+                ActivityTestBase.TEST_WIDTH, ActivityTestBase.TEST_HEIGHT);
         subcanvas.drawRect(sRect, pt);
         pic.endRecording();
 
         return pic;
     }
 
+    @Test
     public void testPictureRespectsClip() throws Exception {
         createTest()
             .addCanvasClient(
-                new CanvasClient() {
-                    @Override
-                    public void draw(Canvas canvas, int width, int height) {
+                    (canvas, width, height) -> {
                         Picture pic = greenSquare();
                         canvas.clipRect(sOffsetRect);
                         pic.draw(canvas);  // should be clipped out
                     }
-                }
             ).runWithVerifier(new ColorVerifier(Color.WHITE));
     }
 
+    @Test
     public void testPictureRespectsTranslate() throws Exception {
         createTest()
             .addCanvasClient(
-                new CanvasClient() {
-                    @Override
-                    public void draw(Canvas canvas, int width, int height) {
+                    (canvas, width, height) -> {
                         Picture pic = greenSquare();
                         canvas.translate(40, 0);
                         pic.draw(canvas);  // should be offset
                     }
-                }
             ).runWithVerifier(
                 new RectVerifier(Color.WHITE, Color.GREEN, sOffsetRect));
     }
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ShaderTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ShaderTests.java
index 85764a6..16a38e8 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ShaderTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ShaderTests.java
@@ -25,15 +25,17 @@
 import android.graphics.PorterDuff;
 import android.graphics.RadialGradient;
 import android.graphics.Shader;
-import android.test.suitebuilder.annotation.SmallTest;
+import android.test.suitebuilder.annotation.MediumTest;
 import android.uirendering.cts.bitmapcomparers.MSSIMComparer;
 import android.uirendering.cts.bitmapverifiers.ColorVerifier;
 import android.uirendering.cts.testinfrastructure.ActivityTestBase;
 import android.uirendering.cts.testinfrastructure.CanvasClient;
-import com.android.cts.uirendering.R;
+import android.uirendering.cts.R;
+import org.junit.Test;
 
+@MediumTest
 public class ShaderTests extends ActivityTestBase {
-    @SmallTest
+    @Test
     public void testSinglePixelBitmapShader() {
         createTest()
                 .addCanvasClient(new CanvasClient() {
@@ -52,7 +54,7 @@
                 .runWithVerifier(new ColorVerifier(Color.BLUE));
     }
 
-    @SmallTest
+    @Test
     public void testSinglePixelComposeShader() {
         createTest()
                 .addCanvasClient(new CanvasClient() {
@@ -83,7 +85,7 @@
                 .runWithVerifier(new ColorVerifier(Color.BLUE));
     }
 
-    @SmallTest
+    @Test
     public void testComplexShaderUsage() {
         /*
          * This test not only builds a very complex drawing operation, but also tests an
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ShadowTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ShadowTests.java
index ffcbf30..6b9fb79 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ShadowTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ShadowTests.java
@@ -17,23 +17,40 @@
 
 import android.graphics.Color;
 import android.graphics.Point;
+import android.test.suitebuilder.annotation.MediumTest;
 import android.uirendering.cts.bitmapverifiers.SamplePointVerifier;
 
-import com.android.cts.uirendering.R;
+import android.uirendering.cts.R;
 
-import android.test.suitebuilder.annotation.SmallTest;
 import android.uirendering.cts.testinfrastructure.ActivityTestBase;
+import android.uirendering.cts.util.CompareUtils;
+import org.junit.Test;
 
+@MediumTest
 public class ShadowTests extends ActivityTestBase {
-    @SmallTest
+
+    private class GrayScaleVerifier extends SamplePointVerifier {
+        public GrayScaleVerifier(Point[] testPoints, int[] expectedColors, int tolerance) {
+            super(testPoints, expectedColors, tolerance) ;
+        }
+
+        @Override
+        protected boolean verifyPixel(int color, int expectedColor) {
+            return super.verifyPixel(color, expectedColor)
+                    && CompareUtils.verifyPixelGrayScale(color, 1);
+        }
+    }
+
+    @Test
     public void testShadowLayout() {
         int shadowColorValue = 0xDB;
         // Android TV theme overrides shadow opacity to be darker.
         if (getActivity().getOnTv()) {
             shadowColorValue = 0xBB;
         }
-        // Use a higher threshold (36) than default value (20);
-        SamplePointVerifier verifier = new SamplePointVerifier(
+
+        // Use a higher threshold than default value (20), since we also double check gray scale;
+        GrayScaleVerifier verifier = new GrayScaleVerifier(
                 new Point[] {
                         // view area
                         new Point(25, 64),
@@ -48,9 +65,10 @@
                         Color.rgb(shadowColorValue, shadowColorValue, shadowColorValue),
                         Color.rgb(shadowColorValue, shadowColorValue, shadowColorValue),
                 },
-                36);
+                48);
+
         createTest()
                 .addLayout(R.layout.simple_shadow_layout, null, true/* HW only */)
                 .runWithVerifier(verifier);
     }
-}
\ No newline at end of file
+}
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/SweepTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/SweepTests.java
index 71b4f3f..3f51bbe 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/SweepTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/SweepTests.java
@@ -20,21 +20,16 @@
 import android.graphics.Color;
 import android.graphics.LinearGradient;
 import android.graphics.Paint;
-import android.graphics.Point;
-import android.graphics.PorterDuff;
-import android.graphics.PorterDuffXfermode;
 import android.graphics.Rect;
-import android.graphics.RectF;
 import android.graphics.Shader;
-import android.test.suitebuilder.annotation.SmallTest;
+import android.test.suitebuilder.annotation.MediumTest;
 import android.uirendering.cts.bitmapcomparers.BitmapComparer;
 import android.uirendering.cts.bitmapcomparers.MSSIMComparer;
-import android.uirendering.cts.bitmapverifiers.BitmapVerifier;
-import android.uirendering.cts.bitmapverifiers.SamplePointVerifier;
 import android.uirendering.cts.testinfrastructure.ActivityTestBase;
 import android.uirendering.cts.testinfrastructure.CanvasClient;
 import android.uirendering.cts.testinfrastructure.DisplayModifier;
 import android.uirendering.cts.testinfrastructure.ResourceModifier;
+import org.junit.Test;
 
 import java.util.LinkedHashMap;
 import java.util.Map;
@@ -42,222 +37,8 @@
 /**
  * Test cases of all combination of resource modifications.
  */
+@MediumTest
 public class SweepTests extends ActivityTestBase {
-    private static final String TAG = "SweepTests";
-
-    public static final int BG_COLOR = 0xFFFFFFFF;
-    public static final int DST_COLOR = 0xFFFFCC44;
-    public static final int SRC_COLOR = 0xFF66AAFF;
-    public static final int MULTIPLY_COLOR = 0xFF668844;
-    public static final int SCREEN_COLOR = 0xFFFFEEFF;
-
-    // These points are in pairs, the first being the lower left corner, the second is only in the
-    // Destination bitmap, the third is the intersection of the two bitmaps, and the fourth is in
-    // the Source bitmap.
-    private final static Point[] XFERMODE_TEST_POINTS = new Point[] {
-            new Point(1, 80), new Point(25, 25), new Point(35, 35), new Point(70, 70)
-    };
-
-    /**
-     * There are 4 locations we care about in any filter testing.
-     *
-     * 1) Both empty
-     * 2) Only src, dst empty
-     * 3) Both src + dst
-     * 4) Only dst, src empty
-     */
-    private final Map<PorterDuff.Mode, int[]> XFERMODE_COLOR_MAP = new LinkedHashMap<PorterDuff.Mode, int[]>() {
-        {
-            put(PorterDuff.Mode.SRC, new int[] {
-                    BG_COLOR, BG_COLOR, SRC_COLOR, SRC_COLOR
-            });
-
-            put(PorterDuff.Mode.DST, new int[] {
-                    BG_COLOR, DST_COLOR, DST_COLOR, BG_COLOR
-            });
-
-            put(PorterDuff.Mode.SRC_OVER, new int[] {
-                    BG_COLOR, DST_COLOR, SRC_COLOR, SRC_COLOR
-            });
-
-            put(PorterDuff.Mode.DST_OVER, new int[] {
-                    BG_COLOR, DST_COLOR, DST_COLOR, SRC_COLOR
-            });
-
-            put(PorterDuff.Mode.SRC_IN, new int[] {
-                    BG_COLOR, BG_COLOR, SRC_COLOR, BG_COLOR
-            });
-
-            put(PorterDuff.Mode.DST_IN, new int[] {
-                    BG_COLOR, BG_COLOR, DST_COLOR, BG_COLOR
-            });
-
-            put(PorterDuff.Mode.SRC_OUT, new int[] {
-                    BG_COLOR, BG_COLOR, BG_COLOR, SRC_COLOR
-            });
-
-            put(PorterDuff.Mode.DST_OUT, new int[] {
-                    BG_COLOR, DST_COLOR, BG_COLOR, BG_COLOR
-            });
-
-            put(PorterDuff.Mode.SRC_ATOP, new int[] {
-                    BG_COLOR, DST_COLOR, SRC_COLOR, BG_COLOR
-            });
-
-            put(PorterDuff.Mode.DST_ATOP, new int[] {
-                    BG_COLOR, BG_COLOR, DST_COLOR, SRC_COLOR
-            });
-
-            put(PorterDuff.Mode.XOR, new int[] {
-                    BG_COLOR, DST_COLOR, BG_COLOR, SRC_COLOR
-            });
-
-            put(PorterDuff.Mode.MULTIPLY, new int[] {
-                    BG_COLOR, BG_COLOR, MULTIPLY_COLOR, BG_COLOR
-            });
-
-            put(PorterDuff.Mode.SCREEN, new int[] {
-                    BG_COLOR, DST_COLOR, SCREEN_COLOR, SRC_COLOR
-            });
-        }
-    };
-
-    private final static DisplayModifier XFERMODE_MODIFIER = new DisplayModifier() {
-        private final RectF mSrcRect = new RectF(30, 30, 80, 80);
-        private final RectF mDstRect = new RectF(10, 10, 60, 60);
-        private final Bitmap mSrcBitmap = createSrc();
-        private final Bitmap mDstBitmap = createDst();
-
-        @Override
-        public void modifyDrawing(Paint paint, Canvas canvas) {
-            int sc = canvas.saveLayer(0, 0, TEST_WIDTH, TEST_HEIGHT, null);
-
-            canvas.drawBitmap(mDstBitmap, 0, 0, null);
-            canvas.drawBitmap(mSrcBitmap, 0, 0, paint);
-
-            canvas.restoreToCount(sc);
-        }
-
-        private Bitmap createSrc() {
-            Bitmap srcB = Bitmap.createBitmap(TEST_WIDTH, TEST_HEIGHT, Bitmap.Config.ARGB_8888);
-            Canvas srcCanvas = new Canvas(srcB);
-            Paint srcPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
-            srcPaint.setColor(SRC_COLOR);
-            srcCanvas.drawRect(mSrcRect, srcPaint);
-            return srcB;
-        }
-
-        private Bitmap createDst() {
-            Bitmap dstB = Bitmap.createBitmap(TEST_WIDTH, TEST_HEIGHT, Bitmap.Config.ARGB_8888);
-            Canvas dstCanvas = new Canvas(dstB);
-            Paint dstPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
-            dstPaint.setColor(DST_COLOR);
-            dstCanvas.drawOval(mDstRect, dstPaint);
-            return dstB;
-        }
-    };
-
-    // We care about one point in each of the four rectangles of different alpha values, as well as
-    // the area outside the rectangles
-    private final static Point[] COLOR_FILTER_ALPHA_POINTS = new Point[] {
-            new Point(9, 45),
-            new Point(27, 45),
-            new Point(45, 45),
-            new Point(63, 45),
-            new Point(81, 45)
-    };
-
-    public static final int FILTER_COLOR = 0xFFBB0000;
-    private final Map<PorterDuff.Mode, int[]> COLOR_FILTER_ALPHA_MAP
-            = new LinkedHashMap<PorterDuff.Mode, int[]>() {
-        {
-            put(PorterDuff.Mode.SRC, new int[] {
-                    FILTER_COLOR, FILTER_COLOR, FILTER_COLOR, FILTER_COLOR, FILTER_COLOR
-            });
-
-            put(PorterDuff.Mode.DST, new int[] {
-                    0xFFE6E6E6, 0xFFCCCCCC, 0xFFB3B3B3, 0xFF999999, 0xFFFFFFFF
-            });
-
-            put(PorterDuff.Mode.SRC_OVER, new int[] {
-                    0xFFBB0000, 0xFFBB0000, 0xFFBB0000, 0xFFBB0000, 0xFFBB0000
-            });
-
-            put(PorterDuff.Mode.DST_OVER, new int[] {
-                    0xFFAF1A1A, 0xFFA33333, 0xFF984D4D, 0xFF8B6666, 0xFFBB0000
-            });
-
-            put(PorterDuff.Mode.SRC_IN, new int[] {
-                    0xFFF1CCCC, 0xFFE49999, 0xFFD66666, 0xFFC83333, 0xFFFFFFFF
-            });
-
-            put(PorterDuff.Mode.DST_IN, new int[] {
-                    0xFFE6E6E6, 0xFFCCCCCC, 0xFFB3B3B3, 0xFF999999, 0xFFFFFFFF
-            });
-
-            put(PorterDuff.Mode.SRC_OUT, new int[] {
-                    0xFFC83333, 0xFFD66666, 0xFFE49999, 0xFFF1CCCC, 0xFFBB0000
-            });
-
-            put(PorterDuff.Mode.DST_OUT, new int[] {
-                    0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
-            });
-
-            put(PorterDuff.Mode.SRC_ATOP, new int[] {
-                    0xFFF1CCCC, 0xFFE49999, 0xFFD66666, 0xFFC93333, 0xFFFFFFFF
-            });
-
-            put(PorterDuff.Mode.DST_ATOP, new int[] {
-                    0xFFB01A1A, 0xFFA33333, 0xFF984D4D, 0xFF8B6666, 0xFFBB0000
-            });
-
-            put(PorterDuff.Mode.XOR, new int[] {
-                    0xFFC93333, 0xFFD66666, 0xFFE49999, 0xFFF1CCCC, 0xFFBB0000
-            });
-
-            put(PorterDuff.Mode.MULTIPLY, new int[] {
-                    0xFFDFCCCC, 0xFFBE9999, 0xFF9E6666, 0xFF7E3333, 0xFFFFFFFF
-            });
-
-            put(PorterDuff.Mode.SCREEN, new int[] {
-                    0xFFC21A1A, 0xFFC93333, 0xFFD04D4D, 0xFFD66666, 0xFFBB0000
-            });
-        }
-    };
-
-    /**
-     * Draws 5 blocks of different color/opacity to be blended against
-     */
-    private final static DisplayModifier COLOR_FILTER_ALPHA_MODIFIER = new DisplayModifier() {
-        private final int[] BLOCK_COLORS = new int[] {
-                0x33808080,
-                0x66808080,
-                0x99808080,
-                0xCC808080,
-                0x00000000
-        };
-
-        private final Bitmap mBitmap = createQuadRectBitmap();
-
-        public void modifyDrawing(Paint paint, Canvas canvas) {
-            canvas.drawBitmap(mBitmap, 0, 0, paint);
-        }
-
-        private Bitmap createQuadRectBitmap() {
-            Bitmap bitmap = Bitmap.createBitmap(TEST_WIDTH, TEST_HEIGHT, Bitmap.Config.ARGB_8888);
-            Canvas canvas = new Canvas(bitmap);
-            Paint paint = new Paint();
-            paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
-            final int blockCount = BLOCK_COLORS.length;
-            final int blockWidth = TEST_WIDTH / blockCount;
-            for (int i = 0 ; i < blockCount; i++) {
-                paint.setColor(BLOCK_COLORS[i]);
-                canvas.drawRect(i * blockWidth, 0, (i + 1) * blockWidth, TEST_HEIGHT, paint);
-            }
-            return bitmap;
-        }
-    };
-
     private final static DisplayModifier COLOR_FILTER_GRADIENT_MODIFIER = new DisplayModifier() {
         private final Rect mBounds = new Rect(30, 30, 150, 150);
         private final int[] mColors = new int[] {
@@ -299,54 +80,25 @@
             new MSSIMComparer(HIGH_THRESHOLD)
     };
 
-    @SmallTest
+    @Test
     public void testBasicDraws() {
-        sweepModifiersForMask(DisplayModifier.Accessor.SHAPES_MASK, null, DEFAULT_MSSIM_COMPARER,
-                null);
+        sweepModifiersForMask(DisplayModifier.Accessor.SHAPES_MASK, null, DEFAULT_MSSIM_COMPARER);
     }
 
-    @SmallTest
+    @Test
     public void testBasicShaders() {
         sweepModifiersForMask(DisplayModifier.Accessor.SHADER_MASK, mCircleDrawModifier,
-                DEFAULT_MSSIM_COMPARER, null);
+                DEFAULT_MSSIM_COMPARER);
     }
 
-    @SmallTest
+    @Test
     public void testColorFilterUsingGradient() {
         sweepModifiersForMask(DisplayModifier.Accessor.COLOR_FILTER_MASK,
-                COLOR_FILTER_GRADIENT_MODIFIER, DEFAULT_MSSIM_COMPARER, null);
-    }
-
-    @SmallTest
-    public void testColorFiltersAlphas() {
-        BitmapVerifier[] bitmapVerifiers =
-                new BitmapVerifier[DisplayModifier.PORTERDUFF_MODES.length];
-        int index = 0;
-        for (PorterDuff.Mode mode : DisplayModifier.PORTERDUFF_MODES) {
-            bitmapVerifiers[index] = new SamplePointVerifier(COLOR_FILTER_ALPHA_POINTS,
-                    COLOR_FILTER_ALPHA_MAP.get(mode));
-            index++;
-        }
-        sweepModifiersForMask(DisplayModifier.Accessor.COLOR_FILTER_MASK,
-                COLOR_FILTER_ALPHA_MODIFIER, null, bitmapVerifiers);
-    }
-
-    @SmallTest
-    public void testXfermodes() {
-        BitmapVerifier[] bitmapVerifiers =
-                new BitmapVerifier[DisplayModifier.PORTERDUFF_MODES.length];
-        int index = 0;
-        for (PorterDuff.Mode mode : DisplayModifier.PORTERDUFF_MODES) {
-            bitmapVerifiers[index] = new SamplePointVerifier(XFERMODE_TEST_POINTS,
-                    XFERMODE_COLOR_MAP.get(mode));
-            index++;
-        }
-        sweepModifiersForMask(DisplayModifier.Accessor.XFERMODE_MASK, XFERMODE_MODIFIER,
-                null, bitmapVerifiers);
+                COLOR_FILTER_GRADIENT_MODIFIER, DEFAULT_MSSIM_COMPARER);
     }
 
     protected void sweepModifiersForMask(int mask, final DisplayModifier drawOp,
-            BitmapComparer[] bitmapComparers, BitmapVerifier[] bitmapVerifiers) {
+                BitmapComparer[] bitmapComparers) {
         if ((mask & DisplayModifier.Accessor.ALL_OPTIONS_MASK) == 0) {
             throw new IllegalArgumentException("Attempt to test with a mask that is invalid");
         }
@@ -356,28 +108,21 @@
         ResourceModifier.init(getActivity().getResources());
         // For each modification combination, we will get the CanvasClient associated with it and
         // from there execute a normal canvas test with that.
-        CanvasClient canvasClient = new CanvasClient() {
-            @Override
-            public void draw(Canvas canvas, int width, int height) {
-                Paint paint = new Paint();
-                modifierAccessor.modifyDrawing(canvas, paint);
-                if (drawOp != null) {
-                    drawOp.modifyDrawing(paint, canvas);
-                }
+        CanvasClient canvasClient = (canvas, width, height) -> {
+            Paint paint = new Paint();
+            modifierAccessor.modifyDrawing(canvas, paint);
+            if (drawOp != null) {
+                drawOp.modifyDrawing(paint, canvas);
             }
         };
 
         int index = 0;
         // Create the test cases with each combination
         do {
-            canvasClient.setDebugString(modifierAccessor.getDebugString());
-            if (bitmapComparers != null) {
-                int arrIndex = Math.min(index, bitmapComparers.length - 1);
-                createTest().addCanvasClient(canvasClient).runWithComparer(bitmapComparers[arrIndex]);
-            } else {
-                int arrIndex = Math.min(index, bitmapVerifiers.length - 1);
-                createTest().addCanvasClient(canvasClient).runWithVerifier(bitmapVerifiers[arrIndex]);
-            }
+            int arrIndex = Math.min(index, bitmapComparers.length - 1);
+            createTest()
+                    .addCanvasClient(modifierAccessor.getDebugString(), canvasClient)
+                    .runWithComparer(bitmapComparers[arrIndex]);
             index++;
         } while (modifierAccessor.step());
     }
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ViewClippingTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ViewClippingTests.java
index f1f7c99..c8ca8c3 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ViewClippingTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ViewClippingTests.java
@@ -2,7 +2,9 @@
 
 import android.graphics.Color;
 import android.graphics.Outline;
+import android.graphics.Path;
 import android.graphics.Rect;
+import android.test.suitebuilder.annotation.MediumTest;
 import android.uirendering.cts.bitmapverifiers.BitmapVerifier;
 import android.uirendering.cts.bitmapverifiers.RectVerifier;
 import android.uirendering.cts.testclasses.view.UnclippedBlueView;
@@ -11,7 +13,10 @@
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.ViewOutlineProvider;
-import com.android.cts.uirendering.R;
+import android.uirendering.cts.R;
+import org.junit.Test;
+
+import static org.junit.Assert.assertFalse;
 
 /**
  * This tests view clipping by modifying properties of blue_padded_layout, and validating
@@ -19,77 +24,73 @@
  *
  * Since the layout is blue on a white background, this is always done with a RectVerifier.
  */
+@MediumTest
 public class ViewClippingTests extends ActivityTestBase {
-    final Rect FULL_RECT = new Rect(0, 0, 90, 90);
-    final Rect BOUNDS_RECT = new Rect(0, 0, 80, 80);
-    final Rect PADDED_RECT = new Rect(15, 16, 63, 62);
-    final Rect OUTLINE_RECT = new Rect(1, 2, 78, 79);
-    final Rect CLIP_BOUNDS_RECT = new Rect(10, 20, 50, 60);
+    static final Rect FULL_RECT = new Rect(0, 0, 90, 90);
+    static final Rect BOUNDS_RECT = new Rect(0, 0, 80, 80);
+    static final Rect PADDED_RECT = new Rect(15, 16, 63, 62);
+    static final Rect OUTLINE_RECT = new Rect(1, 2, 78, 79);
+    static final Rect CLIP_BOUNDS_RECT = new Rect(10, 20, 50, 60);
 
-    final ViewInitializer BOUNDS_CLIP_INIT = new ViewInitializer() {
-        @Override
-        public void initializeView(View rootView) {
-            ((ViewGroup)rootView).setClipChildren(true);
-        }
+    static final ViewInitializer BOUNDS_CLIP_INIT =
+            rootView -> ((ViewGroup)rootView).setClipChildren(true);
+
+    static final ViewInitializer PADDING_CLIP_INIT = rootView -> {
+        ViewGroup child = (ViewGroup) rootView.findViewById(R.id.child);
+        child.setClipToPadding(true);
+        child.setWillNotDraw(true);
+        child.addView(new UnclippedBlueView(rootView.getContext()));
     };
-    final ViewInitializer PADDING_CLIP_INIT = new ViewInitializer() {
-        @Override
-        public void initializeView(View rootView) {
-            ViewGroup child = (ViewGroup) rootView.findViewById(R.id.child);
-            child.setClipToPadding(true);
-            child.setWillNotDraw(true);
-            child.addView(new UnclippedBlueView(rootView.getContext()));
-        }
+
+    static final ViewInitializer OUTLINE_CLIP_INIT = rootView -> {
+        View child = rootView.findViewById(R.id.child);
+        child.setOutlineProvider(new ViewOutlineProvider() {
+            @Override
+            public void getOutline(View view, Outline outline) {
+                outline.setRect(OUTLINE_RECT);
+            }
+        });
+        child.setClipToOutline(true);
     };
-    final ViewInitializer OUTLINE_CLIP_INIT = new ViewInitializer() {
-        @Override
-        public void initializeView(View rootView) {
-            View child = rootView.findViewById(R.id.child);
-            child.setOutlineProvider(new ViewOutlineProvider() {
-                @Override
-                public void getOutline(View view, Outline outline) {
-                    outline.setRect(OUTLINE_RECT);
-                }
-            });
-            child.setClipToOutline(true);
-        }
-    };
-    final ViewInitializer CLIP_BOUNDS_CLIP_INIT = new ViewInitializer() {
-        @Override
-        public void initializeView(View view) {
-            view.setClipBounds(CLIP_BOUNDS_RECT);
-        }
-    };
+
+    static final ViewInitializer CLIP_BOUNDS_CLIP_INIT =
+            view -> view.setClipBounds(CLIP_BOUNDS_RECT);
 
     static BitmapVerifier makeClipVerifier(Rect blueBoundsRect) {
         // very high error tolerance, since all these tests care about is clip alignment
         return new RectVerifier(Color.WHITE, Color.BLUE, blueBoundsRect, 75);
     }
 
+    @Test
     public void testSimpleUnclipped() {
         createTest()
                 .addLayout(R.layout.blue_padded_layout, null)
                 .runWithVerifier(makeClipVerifier(FULL_RECT));
     }
 
+    @Test
     public void testSimpleBoundsClip() {
         createTest()
                 .addLayout(R.layout.blue_padded_layout, BOUNDS_CLIP_INIT)
                 .runWithVerifier(makeClipVerifier(BOUNDS_RECT));
     }
 
+    @Test
     public void testSimpleClipBoundsClip() {
         createTest()
                 .addLayout(R.layout.blue_padded_layout, CLIP_BOUNDS_CLIP_INIT)
                 .runWithVerifier(makeClipVerifier(CLIP_BOUNDS_RECT));
     }
 
+    @Test
     public void testSimplePaddingClip() {
         createTest()
                 .addLayout(R.layout.blue_padded_layout, PADDING_CLIP_INIT)
                 .runWithVerifier(makeClipVerifier(PADDED_RECT));
     }
+    // TODO: add tests with clip + scroll, and with interesting combinations of the above
 
+    @Test
     public void testSimpleOutlineClip() {
         // NOTE: Only HW is supported
         createTest()
@@ -102,5 +103,25 @@
                 .runWithVerifier(makeClipVerifier(FULL_RECT));
     }
 
-    // TODO: add tests with clip + scroll, and with interesting combinations of the above
+    @Test
+    public void testOvalOutlineClip() {
+        // In hw this works because clipping to a non-round rect isn't supported, and is no-op'd.
+        // In sw this works because Outline clipping isn't supported.
+        createTest()
+                .addLayout(R.layout.blue_padded_layout, view -> {
+                    view.setOutlineProvider(new ViewOutlineProvider() {
+                        Path mPath = new Path();
+                        @Override
+                        public void getOutline(View view, Outline outline) {
+                            mPath.reset();
+                            mPath.addOval(0, 0, view.getWidth(), view.getHeight(),
+                                    Path.Direction.CW);
+                            outline.setConvexPath(mPath);
+                            assertFalse(outline.canClip()); // NOTE: non-round-rect, so can't clip
+                        }
+                    });
+                    view.setClipToOutline(true); // should do nothing, since non-rect clip
+                })
+                .runWithVerifier(makeClipVerifier(FULL_RECT));
+    }
 }
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/XfermodeTest.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/XfermodeTest.java
new file mode 100644
index 0000000..c6e9881
--- /dev/null
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/XfermodeTest.java
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.uirendering.cts.testclasses;
+
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Point;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffXfermode;
+import android.graphics.RectF;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.uirendering.cts.bitmapverifiers.SamplePointVerifier;
+import android.uirendering.cts.testinfrastructure.ActivityTestBase;
+import android.uirendering.cts.testinfrastructure.CanvasClient;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@MediumTest
+@RunWith(Parameterized.class)
+public class XfermodeTest extends ActivityTestBase {
+    /**
+     * There are 4 locations we care about in testing each filter:
+     *
+     * 1) Both empty
+     * 2) Only src, dst empty
+     * 3) Both src + dst
+     * 4) Only dst, src empty
+     */
+    private final static Point[] TEST_POINTS = new Point[] {
+            new Point(1, 80),
+            new Point(25, 25),
+            new Point(35, 35),
+            new Point(70, 70)
+    };
+
+    public static class Config {
+        final boolean hardwareAccelerated;
+        final PorterDuff.Mode mode;
+        final int[] expectedColors;
+
+        Config(boolean hardwareAccelerated, Object[] modeAndExpectedColors) {
+            this.hardwareAccelerated = hardwareAccelerated;
+            mode = (PorterDuff.Mode) modeAndExpectedColors[0];
+            expectedColors = (int[]) modeAndExpectedColors[1];
+        }
+
+        @Override
+        public String toString() {
+            return mode.name() + ", hardwareAccelerated=" + hardwareAccelerated;
+        }
+    };
+
+    public static List<XfermodeTest.Config> configs(Object[][] modesAndExpectedColors) {
+        List<XfermodeTest.Config> configs = new ArrayList<>();
+        for (boolean hardwareAccelerated : new boolean[] {false, true}) {
+            for (Object[] modeAndExpectedColors : modesAndExpectedColors) {
+                configs.add(new XfermodeTest.Config(hardwareAccelerated, modeAndExpectedColors));
+            }
+        }
+        return configs;
+    }
+
+    private static final int BG_COLOR = 0xFFFFFFFF;
+    private static final int DST_COLOR = 0xFFFFCC44;
+    private static final int SRC_COLOR = 0xFF66AAFF;
+    private static final int MULTIPLY_COLOR = 0xFF668844;
+    private static final int SCREEN_COLOR = 0xFFFFEEFF;
+
+    private static Object[][] MODES_AND_EXPECTED_COLORS = new Object[][] {
+        { PorterDuff.Mode.SRC, new int[] {
+                BG_COLOR, BG_COLOR, SRC_COLOR, SRC_COLOR } },
+
+        { PorterDuff.Mode.DST, new int[] {
+                BG_COLOR, DST_COLOR, DST_COLOR, BG_COLOR } },
+
+        { PorterDuff.Mode.SRC_OVER, new int[] {
+                BG_COLOR, DST_COLOR, SRC_COLOR, SRC_COLOR } },
+
+        { PorterDuff.Mode.DST_OVER, new int[] {
+                BG_COLOR, DST_COLOR, DST_COLOR, SRC_COLOR } },
+
+        { PorterDuff.Mode.SRC_IN, new int[] {
+                BG_COLOR, BG_COLOR, SRC_COLOR, BG_COLOR } },
+
+        { PorterDuff.Mode.DST_IN, new int[] {
+                BG_COLOR, BG_COLOR, DST_COLOR, BG_COLOR } },
+
+        { PorterDuff.Mode.SRC_OUT, new int[] {
+                BG_COLOR, BG_COLOR, BG_COLOR, SRC_COLOR } },
+
+        { PorterDuff.Mode.DST_OUT, new int[] {
+                BG_COLOR, DST_COLOR, BG_COLOR, BG_COLOR } },
+
+        { PorterDuff.Mode.SRC_ATOP, new int[] {
+                BG_COLOR, DST_COLOR, SRC_COLOR, BG_COLOR } },
+
+        { PorterDuff.Mode.DST_ATOP, new int[] {
+                BG_COLOR, BG_COLOR, DST_COLOR, SRC_COLOR } },
+
+        { PorterDuff.Mode.XOR, new int[] {
+                BG_COLOR, DST_COLOR, BG_COLOR, SRC_COLOR } },
+
+        { PorterDuff.Mode.MULTIPLY, new int[] {
+                BG_COLOR, BG_COLOR, MULTIPLY_COLOR, BG_COLOR } },
+
+        { PorterDuff.Mode.SCREEN, new int[] {
+                BG_COLOR, DST_COLOR, SCREEN_COLOR, SRC_COLOR } },
+    };
+
+    @Parameterized.Parameters(name = "{0}")
+    public static List<Config> configs() {
+        return configs(MODES_AND_EXPECTED_COLORS);
+    }
+
+    private final Config mConfig;
+
+    public XfermodeTest(Config config) {
+        mConfig = config;
+    }
+
+    private CanvasClient mCanvasClient = new CanvasClient() {
+        final Paint mPaint = new Paint();
+        private final RectF mSrcRect = new RectF(30, 30, 80, 80);
+        private final RectF mDstRect = new RectF(10, 10, 60, 60);
+        private final Bitmap mSrcBitmap = createSrc();
+        private final Bitmap mDstBitmap = createDst();
+
+        @Override
+        public void draw(Canvas canvas, int width, int height) {
+            int sc = canvas.saveLayer(0, 0, TEST_WIDTH, TEST_HEIGHT, null);
+
+            canvas.drawBitmap(mDstBitmap, 0, 0, null);
+            mPaint.setXfermode(new PorterDuffXfermode(mConfig.mode));
+            canvas.drawBitmap(mSrcBitmap, 0, 0, mPaint);
+
+            canvas.restoreToCount(sc);
+        }
+
+        private Bitmap createSrc() {
+            Bitmap srcB = Bitmap.createBitmap(TEST_WIDTH, TEST_HEIGHT, Bitmap.Config.ARGB_8888);
+            Canvas srcCanvas = new Canvas(srcB);
+            Paint srcPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+            srcPaint.setColor(SRC_COLOR);
+            srcCanvas.drawRect(mSrcRect, srcPaint);
+            return srcB;
+        }
+
+        private Bitmap createDst() {
+            Bitmap dstB = Bitmap.createBitmap(TEST_WIDTH, TEST_HEIGHT, Bitmap.Config.ARGB_8888);
+            Canvas dstCanvas = new Canvas(dstB);
+            Paint dstPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+            dstPaint.setColor(DST_COLOR);
+            dstCanvas.drawOval(mDstRect, dstPaint);
+            return dstB;
+        }
+    };
+
+    @Test
+    public void test() {
+        createTest()
+                .addCanvasClient(mCanvasClient, mConfig.hardwareAccelerated)
+                .runWithVerifier(new SamplePointVerifier(TEST_POINTS, mConfig.expectedColors));
+    }
+}
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testinfrastructure/ActivityTestBase.java b/tests/tests/uirendering/src/android/uirendering/cts/testinfrastructure/ActivityTestBase.java
index 526f4f9..e634528 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testinfrastructure/ActivityTestBase.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testinfrastructure/ActivityTestBase.java
@@ -16,11 +16,13 @@
 package android.uirendering.cts.testinfrastructure;
 
 import android.annotation.Nullable;
+import android.app.Activity;
+import android.app.Instrumentation;
 import android.graphics.Bitmap;
 import android.graphics.Point;
 import android.renderscript.Allocation;
 import android.renderscript.RenderScript;
-import android.test.ActivityInstrumentationTestCase2;
+import android.support.test.rule.ActivityTestRule;
 import android.uirendering.cts.bitmapcomparers.BitmapComparer;
 import android.uirendering.cts.bitmapverifiers.BitmapVerifier;
 import android.uirendering.cts.differencevisualizers.DifferenceVisualizer;
@@ -29,18 +31,23 @@
 import android.util.Log;
 
 import android.support.test.InstrumentationRegistry;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.rules.TestName;
 
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
+import static org.junit.Assert.assertTrue;
+
 /**
  * This class contains the basis for the graphics hardware test classes. Contained within this class
  * are several methods that help with the execution of tests, and should be extended to gain the
  * functionality built in.
  */
-public abstract class ActivityTestBase extends
-        ActivityInstrumentationTestCase2<DrawActivity> {
+public abstract class ActivityTestBase {
     public static final String TAG = "ActivityTestBase";
     public static final boolean DEBUG = false;
     public static final boolean USE_RS = false;
@@ -57,12 +64,18 @@
     private RenderScript mRenderScript;
     private TestCaseBuilder mTestCaseBuilder;
 
+    @Rule
+    public ActivityTestRule<DrawActivity> mActivityRule = new ActivityTestRule<>(
+            DrawActivity.class);
+
+    @Rule
+    public TestName name = new TestName();
+
     /**
      * The default constructor creates the package name and sets the DrawActivity as the class that
      * we would use.
      */
     public ActivityTestBase() {
-        super(DrawActivity.class);
         mDifferenceVisualizer = new PassFailVisualizer();
 
         // Create a location for the files to be held, if it doesn't exist already
@@ -74,26 +87,27 @@
         }
     }
 
-    /**
-     * This method is called before each test case and should be called from the test class that
-     * extends this class.
-     */
-    @Override
+    protected DrawActivity getActivity() {
+        return mActivityRule.getActivity();
+    }
+
+    protected String getName() {
+        return name.getMethodName();
+    }
+
+    protected Instrumentation getInstrumentation() {
+        return InstrumentationRegistry.getInstrumentation();
+    }
+
+    @Before
     public void setUp() {
-        // As the way to access Instrumentation is changed in the new runner, we need to inject it
-        // manually into ActivityInstrumentationTestCase2. ActivityInstrumentationTestCase2 will
-        // be marked as deprecated and replaced with ActivityTestRule.
-        injectInstrumentation(InstrumentationRegistry.getInstrumentation());
         mDifferenceVisualizer = new PassFailVisualizer();
         if (USE_RS) {
             mRenderScript = RenderScript.create(getActivity().getApplicationContext());
         }
     }
 
-    /**
-     * This method will kill the activity so that it can be reset depending on the test.
-     */
-    @Override
+    @After
     public void tearDown() {
         if (mTestCaseBuilder != null) {
             List<TestCase> testCases = mTestCaseBuilder.getTestCases();
@@ -102,7 +116,6 @@
                 throw new IllegalStateException("Must have at least one test case");
             }
 
-
             for (TestCase testCase : testCases) {
                 if (!testCase.wasTestRan) {
                     Log.w(TAG, getName() + " not all of the tests ran");
@@ -111,42 +124,12 @@
             }
             mTestCaseBuilder = null;
         }
-
-        Runnable finishRunnable = new Runnable() {
-
-            @Override
-            public void run() {
-                getActivity().finish();
-            }
-        };
-
-        getActivity().runOnUiThread(finishRunnable);
-    }
-
-    static int[] getBitmapPixels(Bitmap bitmap) {
-        int[] pixels = new int[bitmap.getWidth() * bitmap.getHeight()];
-        bitmap.getPixels(pixels, 0, bitmap.getWidth(),
-                0, 0, bitmap.getWidth(), bitmap.getHeight());
-        return pixels;
-    }
-
-    private Bitmap takeScreenshotImpl(Point testOffset) {
-        Bitmap source = getInstrumentation().getUiAutomation().takeScreenshot();
-        return Bitmap.createBitmap(source, testOffset.x, testOffset.y, TEST_WIDTH, TEST_HEIGHT);
     }
 
     public Bitmap takeScreenshot(Point testOffset) {
         getInstrumentation().waitForIdleSync();
-        Bitmap bitmap1 = takeScreenshotImpl(testOffset);
-        Bitmap bitmap2;
-        int count = 0;
-        do  {
-            bitmap2 = bitmap1;
-            bitmap1 = takeScreenshotImpl(testOffset);
-            count++;
-        } while (count < MAX_SCREEN_SHOTS &&
-                !Arrays.equals(getBitmapPixels(bitmap2), getBitmapPixels(bitmap1)));
-        return bitmap1;
+        Bitmap source = getInstrumentation().getUiAutomation().takeScreenshot();
+        return Bitmap.createBitmap(source, testOffset.x, testOffset.y, TEST_WIDTH, TEST_HEIGHT);
     }
 
     /**
@@ -162,7 +145,7 @@
     protected Bitmap captureRenderSpec(TestCase testCase) {
         Point testOffset = getActivity().enqueueRenderSpecAndWait(
                 testCase.layoutID, testCase.canvasClient,
-                testCase.webViewUrl, testCase.viewInitializer, testCase.useHardware);
+                null, testCase.viewInitializer, testCase.useHardware);
         testCase.wasTestRan = true;
         return takeScreenshot(testOffset);
     }
@@ -277,36 +260,33 @@
             });
         }
 
-        public TestCaseBuilder addWebView(String webViewUrl,
-                @Nullable ViewInitializer viewInitializer) {
-            return addWebView(webViewUrl, viewInitializer, false)
-                    .addWebView(webViewUrl, viewInitializer, true);
-        }
-
         public TestCaseBuilder addLayout(int layoutId, @Nullable ViewInitializer viewInitializer) {
             return addLayout(layoutId, viewInitializer, false)
                     .addLayout(layoutId, viewInitializer, true);
         }
 
-        public TestCaseBuilder addCanvasClient(CanvasClient canvasClient) {
-            return addCanvasClient(canvasClient, false)
-                    .addCanvasClient(canvasClient, true);
-        }
-
-        public TestCaseBuilder addWebView(String webViewUrl,
-                @Nullable ViewInitializer viewInitializer, boolean useHardware) {
-            mTestCases.add(new TestCase(null, 0, webViewUrl, viewInitializer, useHardware));
-            return this;
-        }
-
         public TestCaseBuilder addLayout(int layoutId, @Nullable ViewInitializer viewInitializer,
-                boolean useHardware) {
-            mTestCases.add(new TestCase(null, layoutId, null, viewInitializer, useHardware));
+                                         boolean useHardware) {
+            mTestCases.add(new TestCase(layoutId, viewInitializer, useHardware));
             return this;
         }
 
+        public TestCaseBuilder addCanvasClient(CanvasClient canvasClient) {
+            return addCanvasClient(null, canvasClient);
+        }
+
         public TestCaseBuilder addCanvasClient(CanvasClient canvasClient, boolean useHardware) {
-            mTestCases.add(new TestCase(canvasClient, 0, null, null, useHardware));
+            return addCanvasClient(null, canvasClient, useHardware);
+        }
+
+        public TestCaseBuilder addCanvasClient(String debugString, CanvasClient canvasClient) {
+            return addCanvasClient(debugString, canvasClient, false)
+                    .addCanvasClient(debugString, canvasClient, true);
+        }
+
+        public TestCaseBuilder addCanvasClient(String debugString,
+                    CanvasClient canvasClient, boolean useHardware) {
+            mTestCases.add(new TestCase(canvasClient, debugString, useHardware));
             return this;
         }
 
@@ -317,39 +297,35 @@
 
     private class TestCase {
         public int layoutID;
-        public CanvasClient canvasClient;
-        public String webViewUrl;
         public ViewInitializer viewInitializer;
-        public boolean useHardware;
-        public boolean wasTestRan;
 
-        public TestCase(CanvasClient client, int id, String viewUrl,
-                ViewInitializer viewInitializer, boolean useHardware) {
-            int count = 0;
-            count += (client == null ? 0 : 1);
-            count += (viewUrl == null ? 0 : 1);
-            count += (id == 0 ? 0 : 1);
-            assert(count == 1);
-            assert(client == null || viewInitializer == null);
-            this.layoutID = id;
-            this.canvasClient = client;
-            this.webViewUrl = viewUrl;
+        public CanvasClient canvasClient;
+        public String canvasClientDebugString;
+
+        public boolean useHardware;
+        public boolean wasTestRan = false;
+
+        public TestCase(int layoutId, ViewInitializer viewInitializer, boolean useHardware) {
+            this.layoutID = layoutId;
             this.viewInitializer = viewInitializer;
             this.useHardware = useHardware;
-            this.wasTestRan = false;
+        }
+
+        public TestCase(CanvasClient client, String debugString, boolean useHardware) {
+            this.canvasClient = client;
+            this.canvasClientDebugString = debugString;
+            this.useHardware = useHardware;
         }
 
         public String getDebugString() {
             String debug = "";
             if (canvasClient != null) {
                 debug += "CanvasClient : ";
-                if (canvasClient.getDebugString() != null) {
-                    debug += canvasClient.getDebugString();
+                if (canvasClientDebugString != null) {
+                    debug += canvasClientDebugString;
                 } else {
                     debug += "no debug string given";
                 }
-            } else if (webViewUrl != null) {
-                debug += "WebView URL : " + webViewUrl;
             } else {
                 debug += "Layout resource : " +
                         getActivity().getResources().getResourceName(layoutID);
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testinfrastructure/CanvasClient.java b/tests/tests/uirendering/src/android/uirendering/cts/testinfrastructure/CanvasClient.java
index a99c576..99f6cc7 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testinfrastructure/CanvasClient.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testinfrastructure/CanvasClient.java
@@ -20,16 +20,6 @@
 /**
  * A class that the tester will implement and create a set of drawing calls the tests would use
  */
-public abstract class CanvasClient {
-    private String mDebugString;
-
-    public abstract void draw(Canvas canvas, int width, int height);
-
-    public String getDebugString() {
-        return mDebugString;
-    }
-
-    public void setDebugString(String debugString) {
-        mDebugString = debugString;
-    }
+public interface CanvasClient {
+    void draw(Canvas canvas, int width, int height);
 }
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testinfrastructure/DrawActivity.java b/tests/tests/uirendering/src/android/uirendering/cts/testinfrastructure/DrawActivity.java
index 57c67bd..f5dba26 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testinfrastructure/DrawActivity.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testinfrastructure/DrawActivity.java
@@ -27,7 +27,7 @@
 import android.view.ViewTreeObserver;
 import android.webkit.WebView;
 
-import com.android.cts.uirendering.R;
+import android.uirendering.cts.R;
 
 /**
  * A generic activity that uses a view specified by the user.
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testinfrastructure/ResourceModifier.java b/tests/tests/uirendering/src/android/uirendering/cts/testinfrastructure/ResourceModifier.java
index 5564b96..9538805 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testinfrastructure/ResourceModifier.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testinfrastructure/ResourceModifier.java
@@ -15,7 +15,7 @@
   */
 package android.uirendering.cts.testinfrastructure;
 
-import com.android.cts.uirendering.R;
+import android.uirendering.cts.R;
 
 import android.content.res.Resources;
 import android.graphics.Bitmap;
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testinfrastructure/ViewInitializer.java b/tests/tests/uirendering/src/android/uirendering/cts/testinfrastructure/ViewInitializer.java
index 9a3cbb1..43e1fa6 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testinfrastructure/ViewInitializer.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testinfrastructure/ViewInitializer.java
@@ -20,6 +20,6 @@
 /**
  * Called after a view is created to set various properties on the view
  */
-public abstract class ViewInitializer {
-    public abstract void initializeView(View view);
+public interface ViewInitializer {
+    void initializeView(View view);
 }
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/util/CompareUtils.java b/tests/tests/uirendering/src/android/uirendering/cts/util/CompareUtils.java
index 4f246a4..c80a778 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/util/CompareUtils.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/util/CompareUtils.java
@@ -12,4 +12,17 @@
                 + Math.abs(Color.blue(color) - Color.blue(expectedColor));
         return diff <= threshold;
     }
+
+    /**
+     * @param threshold Per channel differences for R / G / B channel against the average of these 3
+     *                  channels. Should be less than 2 normally.
+     * @return True if the color is close enough to be a gray scale color.
+     */
+    public static boolean verifyPixelGrayScale(int color, int threshold) {
+        int average =  Color.red(color) + Color.green(color) + Color.blue(color);
+        average /= 3;
+        return Math.abs(Color.red(color) - average) <= threshold
+                && Math.abs(Color.green(color) - average) <= threshold
+                && Math.abs(Color.blue(color) - average) <= threshold;
+    }
 }
diff --git a/tests/tests/util/Android.mk b/tests/tests/util/Android.mk
index 75d23d7..cb1c70a 100644
--- a/tests/tests/util/Android.mk
+++ b/tests/tests/util/Android.mk
@@ -21,12 +21,13 @@
 # and when built explicitly put it in the data partition
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
 LOCAL_PACKAGE_NAME := CtsUtilTestCases
 
-LOCAL_SDK_VERSION := current
-
 include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/util/AndroidManifest.xml b/tests/tests/util/AndroidManifest.xml
index e40087a..8c48735 100644
--- a/tests/tests/util/AndroidManifest.xml
+++ b/tests/tests/util/AndroidManifest.xml
@@ -16,7 +16,7 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.util">
+    package="android.util.cts">
 
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <uses-permission android:name="android.permission.READ_LOGS" />
@@ -25,7 +25,7 @@
     </application>
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.cts.util"
+                     android:targetPackage="android.util.cts"
                      android:label="CTS tests of android.util">
         <meta-data android:name="listener"
             android:value="com.android.cts.runner.CtsTestRunListener" />
diff --git a/tests/tests/util/AndroidTest.xml b/tests/tests/util/AndroidTest.xml
new file mode 100644
index 0000000..9af993c
--- /dev/null
+++ b/tests/tests/util/AndroidTest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS Util test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsUtilTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.util.cts" />
+    </test>
+</configuration>
diff --git a/tests/tests/util/assets/Integrate.jar b/tests/tests/util/assets/Integrate.jar
new file mode 100644
index 0000000..16e9c55
--- /dev/null
+++ b/tests/tests/util/assets/Integrate.jar
Binary files differ
diff --git a/tests/tests/util/assets/Modified_Class.jar b/tests/tests/util/assets/Modified_Class.jar
new file mode 100644
index 0000000..d8113c7
--- /dev/null
+++ b/tests/tests/util/assets/Modified_Class.jar
Binary files differ
diff --git a/tests/tests/util/assets/Modified_Manifest_EntryAttributes.jar b/tests/tests/util/assets/Modified_Manifest_EntryAttributes.jar
new file mode 100644
index 0000000..bd1dbb1
--- /dev/null
+++ b/tests/tests/util/assets/Modified_Manifest_EntryAttributes.jar
Binary files differ
diff --git a/tests/tests/util/assets/Modified_Manifest_MainAttributes.jar b/tests/tests/util/assets/Modified_Manifest_MainAttributes.jar
new file mode 100644
index 0000000..5bc60e6
--- /dev/null
+++ b/tests/tests/util/assets/Modified_Manifest_MainAttributes.jar
Binary files differ
diff --git a/tests/tests/util/assets/Modified_SF_EntryAttributes.jar b/tests/tests/util/assets/Modified_SF_EntryAttributes.jar
new file mode 100644
index 0000000..7b76694
--- /dev/null
+++ b/tests/tests/util/assets/Modified_SF_EntryAttributes.jar
Binary files differ
diff --git a/tests/tests/util/assets/hyts_patch.jar b/tests/tests/util/assets/hyts_patch.jar
new file mode 100644
index 0000000..f3c51d0
--- /dev/null
+++ b/tests/tests/util/assets/hyts_patch.jar
Binary files differ
diff --git a/tests/tests/util/assets/removed.jar b/tests/tests/util/assets/removed.jar
new file mode 100644
index 0000000..2100322
--- /dev/null
+++ b/tests/tests/util/assets/removed.jar
Binary files differ
diff --git a/tests/tests/util/src/android/util/cts/EventLogTest.java b/tests/tests/util/src/android/util/cts/EventLogTest.java
index 2d856c4..2065e32 100644
--- a/tests/tests/util/src/android/util/cts/EventLogTest.java
+++ b/tests/tests/util/src/android/util/cts/EventLogTest.java
@@ -77,7 +77,7 @@
         assertEquals(7, events.size());
 
         // subtract: log header, type byte, final newline
-        final int max = 4096 - 20 - 4 - 1;
+        final int max = 4096 - 20 - 4 - 1 - 8;
 
         // subtract: string header (type + length)
         String val0 = (String) events.get(0).getData();
diff --git a/tests/tests/util/src/android/util/cts/LocaleListTest.java b/tests/tests/util/src/android/util/cts/LocaleListTest.java
new file mode 100644
index 0000000..e64d955
--- /dev/null
+++ b/tests/tests/util/src/android/util/cts/LocaleListTest.java
@@ -0,0 +1,504 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.util.cts;
+
+import android.os.Parcel;
+import android.util.LocaleList;
+import android.test.AndroidTestCase;
+
+import java.util.Locale;
+
+public class LocaleListTest extends AndroidTestCase {
+    public void testEmptyLocaleList() {
+        LocaleList ll = new LocaleList();
+        assertNotNull(ll);
+        assertTrue(ll.isEmpty());
+        assertEquals(0, ll.size());
+        assertNull(ll.get(0));
+        assertNull(ll.get(1));
+        assertNull(ll.get(10));
+
+        ll = new LocaleList((Locale) null);
+        assertNotNull(ll);
+        assertTrue(ll.isEmpty());
+        assertEquals(0, ll.size());
+        assertNull(ll.get(0));
+        assertNull(ll.get(1));
+        assertNull(ll.get(10));
+
+        ll = new LocaleList((Locale[]) null);
+        assertNotNull(ll);
+        assertTrue(ll.isEmpty());
+        assertEquals(0, ll.size());
+        assertNull(ll.get(0));
+        assertNull(ll.get(1));
+        assertNull(ll.get(10));
+
+        ll = new LocaleList(new Locale[0]);
+        assertNotNull(ll);
+        assertTrue(ll.isEmpty());
+        assertEquals(0, ll.size());
+        assertNull(ll.get(0));
+        assertNull(ll.get(1));
+        assertNull(ll.get(10));
+    }
+
+    public void testOneMemberLocaleList() {
+        final LocaleList ll = new LocaleList(Locale.US);
+        assertNotNull(ll);
+        assertFalse(ll.isEmpty());
+        assertEquals(1, ll.size());
+        assertEquals(Locale.US, ll.get(0));
+        assertNull(ll.get(10));
+    }
+
+    public void testTwoMemberLocaleList() {
+        final Locale enPH = Locale.forLanguageTag("en-PH");
+        final Locale[] la = {enPH, Locale.US};
+        final LocaleList ll = new LocaleList(la);
+        assertNotNull(ll);
+        assertFalse(ll.isEmpty());
+        assertEquals(2, ll.size());
+        assertEquals(enPH, ll.get(0));
+        assertEquals(Locale.US, ll.get(1));
+        assertNull(ll.get(10));
+    }
+
+    public void testNullArguments() {
+        final Locale[] la = {Locale.US, null};
+        LocaleList ll = null;
+        try {
+            ll = new LocaleList(la);
+            fail("Initializing a LocaleList with an array containing null should throw.");
+        } catch (Throwable e) {
+            assertEquals(NullPointerException.class, e.getClass());
+        }
+    }
+
+    public void testRepeatedArguments() {
+        final Locale[] la = {Locale.US, Locale.US};
+        LocaleList ll = null;
+        try {
+            ll = new LocaleList(la);
+            fail("Initializing a LocaleList with an array containing duplicates should throw.");
+        } catch (Throwable e) {
+            assertEquals(IllegalArgumentException.class, e.getClass());
+        }
+    }
+
+    public void testIndexOf() {
+        final LocaleList empty = new LocaleList();
+        assertEquals(-1, empty.indexOf(Locale.US));
+
+        final LocaleList oneMember = new LocaleList(Locale.US);
+        assertEquals(0, oneMember.indexOf(Locale.US));
+        assertEquals(-1, oneMember.indexOf(Locale.ENGLISH));
+
+        final LocaleList twoMember = LocaleList.forLanguageTags("en,fr");
+        assertEquals(0, twoMember.indexOf(Locale.forLanguageTag("en")));
+        assertEquals(1, twoMember.indexOf(Locale.forLanguageTag("fr")));
+        assertEquals(-1, twoMember.indexOf(Locale.forLanguageTag("en-US")));
+    }
+
+    public void testEquals() {
+        final LocaleList empty = new LocaleList();
+        final LocaleList anotherEmpty = new LocaleList();
+        LocaleList oneMember = new LocaleList(Locale.US);
+        LocaleList sameOneMember = new LocaleList(new Locale("en", "US"));
+        LocaleList differentOneMember = new LocaleList(Locale.FRENCH);
+        Locale[] la = {Locale.US, Locale.FRENCH};
+        LocaleList twoMember = new LocaleList(la);
+
+        assertFalse(empty.equals(null));
+        assertFalse(oneMember.equals(null));
+
+        assertFalse(empty.equals(new Object()));
+
+        assertTrue(empty.equals(empty));
+        assertTrue(oneMember.equals(oneMember));
+
+        assertFalse(empty.equals(oneMember));
+        assertFalse(oneMember.equals(twoMember));
+
+        assertFalse(oneMember.equals(differentOneMember));
+
+        assertTrue(empty.equals(anotherEmpty));
+        assertTrue(oneMember.equals(sameOneMember));
+    }
+
+    public void testHashCode() {
+        final LocaleList empty = new LocaleList();
+        final LocaleList anotherEmpty = new LocaleList();
+        Locale[] la1 = {Locale.US};
+        LocaleList oneMember = new LocaleList(la1);
+        LocaleList sameOneMember = new LocaleList(la1);
+
+        assertEquals(empty.hashCode(), anotherEmpty.hashCode());
+        assertEquals(oneMember.hashCode(), sameOneMember.hashCode());
+    }
+
+    public void testToString() {
+        LocaleList ll = new LocaleList();
+        assertEquals("[]", ll.toString());
+
+        final Locale[] la1 = {Locale.US};
+        ll = new LocaleList(la1);
+        assertEquals("["+Locale.US.toString()+"]", ll.toString());
+
+        final Locale[] la2 = {Locale.US, Locale.FRENCH};
+        ll = new LocaleList(la2);
+        assertEquals("["+Locale.US.toString()+","+Locale.FRENCH.toString()+"]", ll.toString());
+    }
+
+    public void testToLanguageTags() {
+        LocaleList ll = new LocaleList();
+        assertEquals("", ll.toLanguageTags());
+
+        final Locale[] la1 = {Locale.US};
+        ll = new LocaleList(la1);
+        assertEquals(Locale.US.toLanguageTag(), ll.toLanguageTags());
+
+        final Locale[] la2 = {Locale.US, Locale.FRENCH};
+        ll = new LocaleList(la2);
+        assertEquals(Locale.US.toLanguageTag()+","+Locale.FRENCH.toLanguageTag(),
+                ll.toLanguageTags());
+    }
+
+    public void testGetEmptyLocaleList() {
+        LocaleList empty = LocaleList.getEmptyLocaleList();
+        LocaleList anotherEmpty = LocaleList.getEmptyLocaleList();
+        LocaleList constructedEmpty = new LocaleList();
+
+        assertEquals(constructedEmpty, empty);
+        assertSame(empty, anotherEmpty);
+    }
+
+    public void testForLanguageTags() {
+        assertEquals(LocaleList.getEmptyLocaleList(), LocaleList.forLanguageTags(null));
+        assertEquals(LocaleList.getEmptyLocaleList(), LocaleList.forLanguageTags(""));
+
+        assertEquals(new LocaleList(Locale.forLanguageTag("en-US")),
+                LocaleList.forLanguageTags("en-US"));
+
+        final Locale[] la = {Locale.forLanguageTag("en-PH"), Locale.forLanguageTag("en-US")};
+        assertEquals(new LocaleList(la), LocaleList.forLanguageTags("en-PH,en-US"));
+    }
+
+    public void testGetDefault() {
+        final LocaleList ll = LocaleList.getDefault();
+        assertNotNull(ll);
+        assertTrue(ll.size() >= 1);
+
+        final Locale defaultLocale = Locale.getDefault();
+        assertTrue(ll.indexOf(defaultLocale) != -1);
+    }
+
+    public void testGetAdjustedDefault() {
+        final LocaleList ll = LocaleList.getDefault();
+        assertNotNull(ll);
+        assertTrue(ll.size() >= 1);
+
+        final Locale defaultLocale = Locale.getDefault();
+        assertTrue(ll.indexOf(defaultLocale) == 0);
+    }
+
+    public void testGetDefault_localeSetDefaultCalled() {
+        final Locale originalLocale = Locale.getDefault();
+        final LocaleList originalLocaleList = LocaleList.getDefault();
+
+        LocaleList.setDefault(LocaleList.forLanguageTags("ae,en,ja"));
+
+        try {
+            Locale.setDefault(Locale.forLanguageTag("fr"));
+            assertEquals("fr,ae,en,ja", LocaleList.getDefault().toLanguageTags());
+            assertEquals("fr,ae,en,ja", LocaleList.getAdjustedDefault().toLanguageTags());
+
+            Locale.setDefault(Locale.forLanguageTag("de"));
+            assertEquals("de,ae,en,ja", LocaleList.getDefault().toLanguageTags());
+            assertEquals("de,ae,en,ja", LocaleList.getAdjustedDefault().toLanguageTags());
+
+            Locale.setDefault(Locale.forLanguageTag("en"));
+            assertEquals("en,ae,ja", LocaleList.getDefault().toLanguageTags());
+            assertEquals("en,ae,ja", LocaleList.getAdjustedDefault().toLanguageTags());
+
+            Locale.setDefault(Locale.forLanguageTag("es"));
+            assertEquals("es,ae,en,ja", LocaleList.getDefault().toLanguageTags());
+            assertEquals("es,ae,en,ja", LocaleList.getAdjustedDefault().toLanguageTags());
+
+            Locale.setDefault(Locale.forLanguageTag("ja"));
+            assertEquals("ja,ae,en", LocaleList.getDefault().toLanguageTags());
+            assertEquals("ja,ae,en", LocaleList.getAdjustedDefault().toLanguageTags());
+
+            Locale.setDefault(Locale.forLanguageTag("ae"));
+            assertEquals("ae,en,ja", LocaleList.getDefault().toLanguageTags());
+            assertEquals("ae,en,ja", LocaleList.getAdjustedDefault().toLanguageTags());
+        } finally {
+            // restore the original values
+            LocaleList.setDefault(originalLocaleList, originalLocaleList.indexOf(originalLocale));
+        }
+    }
+
+    public void testSetDefault_null() {
+        try {
+            LocaleList.setDefault(null);
+            fail("Setting the default locale list to null should throw.");
+        } catch (Throwable e) {
+            assertEquals(NullPointerException.class, e.getClass());
+        }
+    }
+
+    public void testSetDefault_empty() {
+        try {
+            LocaleList.setDefault(LocaleList.getEmptyLocaleList());
+            fail("Setting the default locale list to an empty list should throw.");
+        } catch (Throwable e) {
+            assertEquals(IllegalArgumentException.class, e.getClass());
+        }
+    }
+
+    public void testSetDefault_oneLocale() {
+        final Locale originalLocale = Locale.getDefault();
+        final LocaleList originalLocaleList = LocaleList.getDefault();
+
+        final LocaleList locales = LocaleList.forLanguageTags("ae");
+        LocaleList.setDefault(locales);
+        try {
+            assertEquals("ae", Locale.getDefault().toLanguageTag());
+            assertEquals(locales, LocaleList.getDefault());
+            assertEquals(locales, LocaleList.getAdjustedDefault());
+        } finally {
+            // restore the original values
+            LocaleList.setDefault(originalLocaleList, originalLocaleList.indexOf(originalLocale));
+        }
+    }
+
+    public void testSetDefault_twoLocales() {
+        final Locale originalLocale = Locale.getDefault();
+        final LocaleList originalLocaleList = LocaleList.getDefault();
+
+        final LocaleList locales = LocaleList.forLanguageTags("ae,en");
+        LocaleList.setDefault(locales);
+        try {
+            assertEquals("ae", Locale.getDefault().toLanguageTag());
+            assertEquals(locales, LocaleList.getDefault());
+            assertEquals(locales, LocaleList.getAdjustedDefault());
+        } finally {
+            // restore the original values
+            LocaleList.setDefault(originalLocaleList, originalLocaleList.indexOf(originalLocale));
+        }
+    }
+
+    public void testParcelable() {
+        // Make sure an empty LocaleList can be marshalled/unmarshalled via Parcel.
+        assertEquals(LocaleList.getEmptyLocaleList(),
+                cloneViaParcel(LocaleList.getEmptyLocaleList()));
+
+        // Make sure a non-empty LocaleList can be marshalled/unmarshalled via Parcel.
+        LocaleList original = LocaleList.forLanguageTags("en-PH,en-US");
+        assertEquals(original, cloneViaParcel(original));
+    }
+
+    public void testDescribeContents_doesNotThrowException() {
+        // Just check calling describeContents() should not cause any exceptions.
+        LocaleList.forLanguageTags("en").describeContents();
+        LocaleList.forLanguageTags("").describeContents();
+        LocaleList.forLanguageTags(null).describeContents();
+        LocaleList.getEmptyLocaleList().describeContents();
+    }
+
+    private static LocaleList cloneViaParcel(final LocaleList original) {
+        Parcel parcel = null;
+        try {
+            parcel = Parcel.obtain();
+            original.writeToParcel(parcel, 0);
+            parcel.setDataPosition(0);
+            return LocaleList.CREATOR.createFromParcel(parcel);
+        } finally {
+            if (parcel != null) {
+                parcel.recycle();
+            }
+        }
+    }
+
+    public void testGetFirstMatch_noAssets() {
+        String[] noAssets = {};
+        assertNull(LocaleList.getEmptyLocaleList().getFirstMatch(noAssets));
+        assertEquals(
+                Locale.forLanguageTag("fr-BE"),
+                LocaleList.forLanguageTags("fr-BE").getFirstMatch(noAssets));
+        assertEquals(
+                Locale.forLanguageTag("fr-BE"),
+                LocaleList.forLanguageTags("fr-BE,nl-BE").getFirstMatch(noAssets));
+    }
+
+    public void testGetFirstMatch_oneAsset() {
+        String[] oneDutchAsset = {"nl"};
+        assertNull(LocaleList.getEmptyLocaleList().getFirstMatch(oneDutchAsset));
+        assertEquals(
+                Locale.forLanguageTag("fr-BE"),
+                LocaleList.forLanguageTags("fr-BE").getFirstMatch(oneDutchAsset));
+        assertEquals(
+                Locale.forLanguageTag("nl-BE"),
+                LocaleList.forLanguageTags("nl-BE").getFirstMatch(oneDutchAsset));
+        assertEquals(
+                Locale.forLanguageTag("nl-BE"),
+                LocaleList.forLanguageTags("fr-BE,nl-BE").getFirstMatch(oneDutchAsset));
+        assertEquals(
+                Locale.forLanguageTag("nl-BE"),
+                LocaleList.forLanguageTags("nl-BE,fr-BE").getFirstMatch(oneDutchAsset));
+    }
+
+    public void testGetFirstMatch_twoAssets() {
+        String[] FrenchAndDutchAssets = {"fr", "nl"};
+        assertNull(LocaleList.getEmptyLocaleList().getFirstMatch(FrenchAndDutchAssets));
+        assertEquals(
+                Locale.forLanguageTag("fr-BE"),
+                LocaleList.forLanguageTags("fr-BE").getFirstMatch(FrenchAndDutchAssets));
+        assertEquals(
+                Locale.forLanguageTag("nl-BE"),
+                LocaleList.forLanguageTags("nl-BE").getFirstMatch(FrenchAndDutchAssets));
+        assertEquals(
+                Locale.forLanguageTag("fr-BE"),
+                LocaleList.forLanguageTags("fr-BE,nl-BE").getFirstMatch(FrenchAndDutchAssets));
+        assertEquals(
+                Locale.forLanguageTag("nl-BE"),
+                LocaleList.forLanguageTags("nl-BE,fr-BE").getFirstMatch(FrenchAndDutchAssets));
+    }
+
+    public void testGetFirstMatch_oneChineseAsset() {
+        String[] oneChineseAsset = {"zh-CN"};  // Assumed to mean zh-Hans-CN
+        // The following Chinese examples would all match, so they will be chosen.
+        assertEquals(
+                Locale.forLanguageTag("zh"),
+                LocaleList.forLanguageTags("ko-KR,zh").getFirstMatch(oneChineseAsset));
+        assertEquals(
+                Locale.forLanguageTag("zh-CN"),
+                LocaleList.forLanguageTags("ko-KR,zh-CN").getFirstMatch(oneChineseAsset));
+        assertEquals(
+                Locale.forLanguageTag("zh-Hans"),
+                LocaleList.forLanguageTags("ko-KR,zh-Hans").getFirstMatch(oneChineseAsset));
+        assertEquals(
+                Locale.forLanguageTag("zh-Hans-CN"),
+                LocaleList.forLanguageTags("ko-KR,zh-Hans-CN").getFirstMatch(oneChineseAsset));
+        assertEquals(
+                Locale.forLanguageTag("zh-Hans-HK"),
+                LocaleList.forLanguageTags("ko-KR,zh-Hans-HK").getFirstMatch(oneChineseAsset));
+
+        // The following Chinese examples wouldn't match, so the first locale will be chosen
+        // instead.
+        assertEquals(
+                Locale.forLanguageTag("ko-KR"),
+                LocaleList.forLanguageTags("ko-KR,zh-TW").getFirstMatch(oneChineseAsset));
+        assertEquals(
+                Locale.forLanguageTag("ko-KR"),
+                LocaleList.forLanguageTags("ko-KR,zh-Hant").getFirstMatch(oneChineseAsset));
+        assertEquals(
+                Locale.forLanguageTag("ko-KR"),
+                LocaleList.forLanguageTags("ko-KR,zh-Hant-TW").getFirstMatch(oneChineseAsset));
+    }
+
+    public void testGetFirstMatch_serbianCyrillic() {
+        String[] oneSerbianAsset = {"sr"};  // Assumed to mean sr-Cyrl-RS
+        // The following Serbian examples would all match, so they will be chosen.
+        assertEquals(
+                Locale.forLanguageTag("sr"),
+                LocaleList.forLanguageTags("hr-HR,sr").getFirstMatch(oneSerbianAsset));
+        assertEquals(
+                Locale.forLanguageTag("sr-RS"),
+                LocaleList.forLanguageTags("hr-HR,sr-RS").getFirstMatch(oneSerbianAsset));
+        assertEquals(
+                Locale.forLanguageTag("sr-Cyrl"),
+                LocaleList.forLanguageTags("hr-HR,sr-Cyrl").getFirstMatch(oneSerbianAsset));
+        assertEquals(
+                Locale.forLanguageTag("sr-Cyrl-RS"),
+                LocaleList.forLanguageTags("hr-HR,sr-Cyrl-RS").getFirstMatch(oneSerbianAsset));
+        assertEquals(
+                Locale.forLanguageTag("sr-Cyrl-ME"),
+                LocaleList.forLanguageTags("hr-HR,sr-Cyrl-ME").getFirstMatch(oneSerbianAsset));
+
+        // The following Serbian examples wouldn't match, so the first locale will be chosen
+        // instead.
+        assertEquals(
+                Locale.forLanguageTag("hr-HR"),
+                LocaleList.forLanguageTags("hr-HR,sr-ME").getFirstMatch(oneSerbianAsset));
+        assertEquals(
+                Locale.forLanguageTag("hr-HR"),
+                LocaleList.forLanguageTags("hr-HR,sr-Latn").getFirstMatch(oneSerbianAsset));
+        assertEquals(
+                Locale.forLanguageTag("hr-HR"),
+                LocaleList.forLanguageTags("hr-HR,sr-Latn-ME").getFirstMatch(oneSerbianAsset));
+    }
+
+    public void testGetFirstMatch_LtrPseudoLocale() {
+        String[] onePseudoLocale = {"en-XA"};
+        // "en-XA" matches itself
+        assertEquals(
+                Locale.forLanguageTag("en-XA"),
+                LocaleList.forLanguageTags("sr,en-XA").getFirstMatch(onePseudoLocale));
+
+        // "en-XA" doesn't match "en" or "en-US"
+        assertEquals(
+                Locale.forLanguageTag("sr"),
+                LocaleList.forLanguageTags("sr,en").getFirstMatch(onePseudoLocale));
+        assertEquals(
+                Locale.forLanguageTag("sr"),
+                LocaleList.forLanguageTags("sr,en-US").getFirstMatch(onePseudoLocale));
+    }
+
+    public void testGetFirstMatch_RtlPseudoLocale() {
+        String[] onePseudoLocale = {"ar-XB"};
+        // "ar-XB" matches itself
+        assertEquals(
+                Locale.forLanguageTag("ar-XB"),
+                LocaleList.forLanguageTags("sr,ar-XB").getFirstMatch(onePseudoLocale));
+
+        // "ar-XB" doesn't match "ar" or "ar-EG"
+        assertEquals(
+                Locale.forLanguageTag("sr"),
+                LocaleList.forLanguageTags("sr,ar").getFirstMatch(onePseudoLocale));
+        assertEquals(
+                Locale.forLanguageTag("sr"),
+                LocaleList.forLanguageTags("sr,ar-EG").getFirstMatch(onePseudoLocale));
+    }
+
+    public void testGetFirstMatch_privateUseWithoutCountry() {
+        String[] onePrivateLocale = {"qaa"};
+        // "qaa" supports itself and "qaa-CA"
+        assertEquals(
+                Locale.forLanguageTag("qaa"),
+                LocaleList.forLanguageTags("sr,qaa").getFirstMatch(onePrivateLocale));
+        assertEquals(
+                Locale.forLanguageTag("qaa-CA"),
+                LocaleList.forLanguageTags("sr,qaa-CA").getFirstMatch(onePrivateLocale));
+    }
+
+    public void testGetFirstMatch_privateUseWithCountry() {
+        String[] onePrivateLocale = {"qaa-US"};
+        // "qaa-US" supports itself
+        assertEquals(
+                Locale.forLanguageTag("qaa-US"),
+                LocaleList.forLanguageTags("sr,qaa-US").getFirstMatch(onePrivateLocale));
+
+        // "qaa-US" doesn't support "qaa" or "qaa-CA"
+        assertEquals(
+                Locale.forLanguageTag("sr"),
+                LocaleList.forLanguageTags("sr,qaa-CA").getFirstMatch(onePrivateLocale));
+        assertEquals(
+                Locale.forLanguageTag("sr"),
+                LocaleList.forLanguageTags("sr,qaa").getFirstMatch(onePrivateLocale));
+    }
+}
diff --git a/tests/tests/util/src/android/util/cts/PatternsTest.java b/tests/tests/util/src/android/util/cts/PatternsTest.java
new file mode 100644
index 0000000..61755ef
--- /dev/null
+++ b/tests/tests/util/src/android/util/cts/PatternsTest.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.util.cts;
+
+import android.util.Patterns;
+
+import junit.framework.TestCase;
+
+/**
+ * Test {@link Patterns}.
+ */
+public class PatternsTest extends TestCase {
+
+    public void testWebUrl_matchesUrlsWithCommasInRequestParameterValues() throws Exception {
+        String url = "https://android.com/path?ll=37.4221,-122.0836&z=17&pll=37.4221,-122.0836";
+        assertTrue("WEB_URL pattern should match commas", Patterns.WEB_URL.matcher(url).matches());
+    }
+}
diff --git a/tests/tests/util/src/android/util/cts/PropertyTest.java b/tests/tests/util/src/android/util/cts/PropertyTest.java
new file mode 100644
index 0000000..22ad2c4
--- /dev/null
+++ b/tests/tests/util/src/android/util/cts/PropertyTest.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.util.cts;
+
+import android.graphics.Point;
+import android.util.FloatProperty;
+import android.util.IntProperty;
+import android.util.Property;
+import junit.framework.TestCase;
+
+public class PropertyTest extends TestCase {
+
+    float mFloatValue = -1;
+    int mIntValue = -2;
+    Point mPointValue = new Point(-3, -4);
+
+    public void testProperty() throws Exception {
+        float testFloatValue = 5;
+        Point testPointValue = new Point(10, 20);
+
+        assertFalse(getFloatProp() == testFloatValue);
+        assertFalse(getPointProp().equals(testPointValue));
+        assertEquals(RAW_FLOAT_PROP.get(this), getFloatProp());
+        assertEquals(RAW_POINT_PROP.get(this), getPointProp());
+
+        RAW_FLOAT_PROP.set(this, testFloatValue);
+        assertEquals(RAW_FLOAT_PROP.get(this), mFloatValue);
+
+        RAW_POINT_PROP.set(this, testPointValue);
+        assertEquals(RAW_POINT_PROP.get(this), testPointValue);
+    }
+
+    public void testFloatProperty() throws Exception {
+        float testFloatValue = 5;
+
+        assertFalse(getFloatProp() == testFloatValue);
+        assertEquals(FLOAT_PROP.get(this), getFloatProp());
+
+        FLOAT_PROP.set(this, testFloatValue);
+        assertEquals(FLOAT_PROP.get(this), testFloatValue);
+    }
+
+    public void testIntProperty() throws Exception {
+        int testIntValue = 5;
+
+        assertFalse(getIntProp() == testIntValue);
+        assertEquals(INT_PROP.get(this).intValue(), getIntProp());
+
+        INT_PROP.set(this, testIntValue);
+        assertEquals(INT_PROP.get(this).intValue(), testIntValue);
+    }
+
+    // Utility methods to get/set instance values. Used by Property classes below.
+
+    private void setFloatProp(float value) {
+        mFloatValue = value;
+    }
+
+    private float getFloatProp() {
+        return mFloatValue;
+    }
+
+    private void setIntProp(int value) {
+        mIntValue = value;
+    }
+
+    private int getIntProp() {
+        return mIntValue;
+    }
+
+    private void setPointProp(Point value) {
+        mPointValue = value;
+    }
+
+    private Point getPointProp() {
+        return mPointValue;
+    }
+
+    // Properties. RAW subclass from the generic Property class, the others subclass from
+    // the primtive-friendly IntProperty and FloatProperty subclasses.
+
+    public static final Property<PropertyTest, Point> RAW_POINT_PROP =
+            new Property<PropertyTest, Point>(Point.class, "rawPoint") {
+                @Override
+                public void set(PropertyTest object, Point value) {
+                    object.setPointProp(value);
+                }
+
+                @Override
+                public Point get(PropertyTest object) {
+                    return object.getPointProp();
+                }
+            };
+
+    public static final Property<PropertyTest, Float> RAW_FLOAT_PROP =
+            new Property<PropertyTest, Float>(Float.class, "rawFloat") {
+                @Override
+                public void set(PropertyTest object, Float value) {
+                    object.setFloatProp(value);
+                }
+
+                @Override
+                public Float get(PropertyTest object) {
+                    return object.getFloatProp();
+                }
+            };
+
+    public static final Property<PropertyTest, Float> FLOAT_PROP =
+            new FloatProperty<PropertyTest>("float") {
+
+                @Override
+                public void setValue(PropertyTest object, float value) {
+                    object.setFloatProp(value);
+                }
+
+                @Override
+                public Float get(PropertyTest object) {
+                    return object.getFloatProp();
+                }
+            };
+
+    public static final Property<PropertyTest, Integer> INT_PROP =
+            new IntProperty<PropertyTest>("int") {
+
+                @Override
+                public void setValue(PropertyTest object, int value) {
+                    object.setIntProp(value);
+                }
+
+                @Override
+                public Integer get(PropertyTest object) {
+                    return object.getIntProp();
+                }
+            };
+}
diff --git a/tests/tests/util/src/android/util/cts/StrictJarFileTest.java b/tests/tests/util/src/android/util/cts/StrictJarFileTest.java
new file mode 100644
index 0000000..e7eedfd
--- /dev/null
+++ b/tests/tests/util/src/android/util/cts/StrictJarFileTest.java
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2013 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES 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.util.cts;
+
+import android.test.AndroidTestCase;
+import junit.framework.TestCase;
+
+import java.io.File;
+import java.io.InputStream;
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.util.HashMap;
+import java.util.Iterator;
+import android.util.jar.StrictJarFile;
+import java.util.zip.ZipEntry;
+import libcore.io.Streams;
+
+public class StrictJarFileTest extends AndroidTestCase {
+
+    // A well formed jar file with 6 entries.
+    private static final String JAR_1 = "hyts_patch.jar";
+
+    private File resources;
+
+    @Override
+    protected void setUp() {
+        try {
+            resources = File.createTempFile("sjf_resources", "", null);
+            resources.delete();
+            resources.mkdirs();
+        } catch (IOException e) {
+            throw new RuntimeException("Unable to create temp folder", e);
+        }
+        resources.deleteOnExit();
+    }
+
+    public void testConstructor() throws Exception {
+        try {
+            StrictJarFile jarFile = new StrictJarFile("Wrong.file");
+            fail("Should throw IOException");
+        } catch (IOException e) {
+            // expected
+        }
+
+        copyFile(JAR_1);
+        String fileName = (new File(resources, JAR_1)).getCanonicalPath();
+        StrictJarFile jarFile = new StrictJarFile(fileName);
+        jarFile.close();
+    }
+
+    public void testIteration() throws Exception {
+        copyFile(JAR_1);
+        StrictJarFile jarFile = new StrictJarFile(new File(resources, JAR_1).getAbsolutePath());
+
+        Iterator<ZipEntry> it = jarFile.iterator();
+        HashMap<String, ZipEntry> entries = new HashMap<String, ZipEntry>();
+        while (it.hasNext()) {
+            final ZipEntry ze = it.next();
+            entries.put(ze.getName(), ze);
+        }
+
+        assertEquals(6, entries.size());
+        assertTrue(entries.containsKey("META-INF/"));
+
+        assertTrue(entries.containsKey("META-INF/MANIFEST.MF"));
+        ZipEntry ze = entries.get("META-INF/MANIFEST.MF");
+        assertEquals(62, ze.getSize());
+        assertEquals(ZipEntry.DEFLATED, ze.getMethod());
+        assertEquals(61, ze.getCompressedSize());
+
+        assertTrue(entries.containsKey("Blah.txt"));
+        ze = entries.get("Blah.txt");
+        assertEquals(4, ze.getSize());
+        assertEquals(ZipEntry.DEFLATED, ze.getMethod());
+        assertEquals(6, ze.getCompressedSize());
+        assertEquals("Blah", new String(Streams.readFully(jarFile.getInputStream(ze)),
+                Charset.forName("UTF-8")));
+
+        assertTrue(entries.containsKey("foo/"));
+        assertTrue(entries.containsKey("foo/bar/"));
+        assertTrue(entries.containsKey("foo/bar/A.class"));
+        ze = entries.get("foo/bar/A.class");
+        assertEquals(311, ze.getSize());
+        assertEquals(ZipEntry.DEFLATED, ze.getMethod());
+        assertEquals(225, ze.getCompressedSize());
+    }
+
+    public void testFindEntry() throws Exception {
+        copyFile(JAR_1);
+        StrictJarFile jarFile = new StrictJarFile(new File(resources, JAR_1).getAbsolutePath());
+
+        assertNull(jarFile.findEntry("foobar"));
+        assertNull(jarFile.findEntry("blah.txt"));
+        assertNotNull(jarFile.findEntry("Blah.txt"));
+        final ZipEntry ze = jarFile.findEntry("Blah.txt");
+        assertEquals(4, ze.getSize());
+        assertEquals(ZipEntry.DEFLATED, ze.getMethod());
+        assertEquals(6, ze.getCompressedSize());
+        assertEquals("Blah", new String(Streams.readFully(jarFile.getInputStream(ze)),
+                Charset.forName("UTF-8")));
+    }
+
+    public void testGetManifest() throws Exception {
+        copyFile(JAR_1);
+        StrictJarFile jarFile = new StrictJarFile(new File(resources, JAR_1).getAbsolutePath());
+
+        assertNotNull(jarFile.getManifest());
+        assertEquals("1.4.2 (IBM Corporation)", jarFile.getManifest().getMainAttributes().getValue("Created-By"));
+    }
+
+    public void testJarSigning_wellFormed() throws IOException {
+        copyFile("Integrate.jar");
+        StrictJarFile jarFile = new StrictJarFile(new File(resources, "Integrate.jar").getAbsolutePath());
+        Iterator<ZipEntry> entries = jarFile.iterator();
+        while (entries.hasNext()) {
+            ZipEntry zipEntry = entries.next();
+            jarFile.getInputStream(zipEntry).skip(Long.MAX_VALUE);
+            if ("Test.class".equals(zipEntry.getName())) {
+                assertNotNull(jarFile.getCertificates(zipEntry));
+                assertNotNull(jarFile.getCertificateChains(zipEntry));
+            }
+        }
+    }
+
+     public void testJarSigning_fudgedEntry() throws IOException {
+        copyFile("Integrate.jar");
+        StrictJarFile jarFile = new StrictJarFile(
+                new File(resources, "Integrate.jar").getAbsolutePath());
+
+        ZipEntry ze = jarFile.findEntry("Test.class");
+        jarFile.getInputStream(ze).skip(Long.MAX_VALUE);
+
+        // Fudge the size so that certificates do not match.
+        ze.setSize(ze.getSize() - 1);
+        try {
+            jarFile.getInputStream(ze).skip(Long.MAX_VALUE);
+            fail();
+        } catch (SecurityException expected) {
+        }
+    }
+
+    public void testJarSigning_modifiedClass() throws IOException {
+        copyFile("Modified_Class.jar");
+        StrictJarFile jarFile = new StrictJarFile(
+                new File(resources,  "Modified_Class.jar").getAbsolutePath());
+
+        ZipEntry ze = jarFile.findEntry("Test.class");
+        try {
+            jarFile.getInputStream(ze).skip(Long.MAX_VALUE);
+            fail();
+        } catch (SecurityException expected) {
+        }
+    }
+
+    public void testJarSigning_brokenMainAttributes() throws Exception {
+        assertThrowsOnInit("Modified_Manifest_MainAttributes.jar");
+    }
+
+    public void testJarSigning_brokenEntryAttributes() throws Exception {
+        assertThrowsOnInit("Modified_Manifest_EntryAttributes.jar");
+    }
+
+    public void testJarSigning_brokenSignatureFile() throws Exception {
+        assertThrowsOnInit("Modified_SF_EntryAttributes.jar");
+    }
+
+    public void testJarSigning_removedEntry() throws Exception {
+        assertThrowsOnInit("removed.jar");
+    }
+
+    private void assertThrowsOnInit(String name) throws Exception {
+      copyFile(name);
+        try {
+            StrictJarFile jarFile = new StrictJarFile(
+                    new File(resources,  name).getAbsolutePath());
+            fail();
+        } catch (SecurityException expected) {
+        }
+    }
+
+
+    public File copyFile(String file) {
+        File dest = new File(resources.toString() + "/" + file);
+
+        if (!dest.exists()) {
+            try {
+                InputStream in = getContext().getAssets().open(file);
+                FileOutputStream out = new FileOutputStream(dest);
+                byte[] buffer = new byte[8192];
+                int c;
+                while ((c = in.read(buffer)) != -1) {
+                    out.write(buffer, 0, c);
+                }
+                out.close();
+                dest.deleteOnExit();
+                in.close();
+            } catch (IOException e) {
+                throw new RuntimeException(
+                                           "Unable to copy file from resource " + file + " to file " + dest, e);
+            }
+        }
+        return dest;
+    }
+}
diff --git a/tests/tests/util/src/android/util/cts/XmlTest.java b/tests/tests/util/src/android/util/cts/XmlTest.java
index 833bd3c..66918ce 100644
--- a/tests/tests/util/src/android/util/cts/XmlTest.java
+++ b/tests/tests/util/src/android/util/cts/XmlTest.java
@@ -391,7 +391,7 @@
 
     public void testAsAttributeSet() {
         XmlResourceParser xp = getContext().getResources().getLayout(
-                com.android.cts.util.R.layout.xml_test);
+                android.util.cts.R.layout.xml_test);
         int eventType = -1;
         try {
             eventType = xp.getEventType();
diff --git a/tests/tests/view/Android.mk b/tests/tests/view/Android.mk
index 027e321..57dc0ce 100644
--- a/tests/tests/view/Android.mk
+++ b/tests/tests/view/Android.mk
@@ -21,12 +21,22 @@
 # and when built explicitly put it in the data partition
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_MULTILIB := both
+
 LOCAL_JAVA_LIBRARIES := android.test.runner
 
-LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctstestrunner
+LOCAL_STATIC_JAVA_LIBRARIES := \
+    ctsdeviceutil ctstestrunner mockito-target platform-test-annotations
+
+LOCAL_JNI_SHARED_LIBRARIES := libctsview_jni libnativehelper_compat_libc++
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
 LOCAL_PACKAGE_NAME := CtsViewTestCases
 
 include $(BUILD_CTS_PACKAGE)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/tests/view/AndroidManifest.xml b/tests/tests/view/AndroidManifest.xml
index b7e0076..31126f8 100644
--- a/tests/tests/view/AndroidManifest.xml
+++ b/tests/tests/view/AndroidManifest.xml
@@ -16,7 +16,7 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.view">
+    package="android.view.cts">
 
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <application android:label="Android TestCase"
@@ -139,6 +139,14 @@
             </intent-filter>
         </activity>
 
+        <activity android:name="android.view.cts.TextureViewCtsActivity"
+            android:label="TextureViewCtsActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+            </intent-filter>
+        </activity>
+
         <activity android:name="android.view.cts.FocusFinderCtsActivity"
             android:label="FocusFinderCtsActivity">
             <intent-filter>
@@ -168,7 +176,23 @@
         </activity>
 
         <activity android:name="android.view.cts.ViewGroupCtsActivity"
-            android:label="WidgetViewGroupCtsActivity">
+                  android:label="WidgetViewGroupCtsActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name="android.view.cts.ViewOverlayCtsActivity"
+                  android:label="ViewOverlayCtsActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name="android.view.cts.ViewGroupOverlayCtsActivity"
+                  android:label="ViewGroupOverlayCtsActivity">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
@@ -191,10 +215,18 @@
             </intent-filter>
         </activity>
 
+        <activity android:name="android.view.cts.ContentPaneCtsActivity"
+                  android:label="ContentPaneCtsActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+            </intent-filter>
+        </activity>
+
     </application>
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.cts.view"
+                     android:targetPackage="android.view.cts"
                      android:label="CTS tests of android.view">
         <meta-data android:name="listener"
             android:value="com.android.cts.runner.CtsTestRunListener" />
diff --git a/tests/tests/view/AndroidTest.xml b/tests/tests/view/AndroidTest.xml
new file mode 100644
index 0000000..c818923
--- /dev/null
+++ b/tests/tests/view/AndroidTest.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS View test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsViewTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.view.cts" />
+        <option name="runtime-hint" value="6m47s" />
+    </test>
+</configuration>
diff --git a/tests/tests/view/jni/Android.mk b/tests/tests/view/jni/Android.mk
new file mode 100644
index 0000000..ac7b844
--- /dev/null
+++ b/tests/tests/view/jni/Android.mk
@@ -0,0 +1,35 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libctsview_jni
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_SRC_FILES := \
+		CtsViewJniOnLoad.cpp \
+		android_view_cts_ChoreographerNativeTest.cpp
+
+LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
+
+LOCAL_SHARED_LIBRARIES := libandroid libnativehelper_compat_libc++ liblog
+
+LOCAL_CXX_STL := libc++_static
+
+LOCAL_CLANG := true
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/tests/tests/view/jni/CtsViewJniOnLoad.cpp b/tests/tests/view/jni/CtsViewJniOnLoad.cpp
new file mode 100644
index 0000000..2c1e643
--- /dev/null
+++ b/tests/tests/view/jni/CtsViewJniOnLoad.cpp
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 <jni.h>
+
+#include <utils/Log.h>
+#define LOG_TAG "CtsViewJniOnLoad"
+
+extern int register_android_view_cts_ChoreographerNativeTest(JNIEnv* env);
+
+jint JNI_OnLoad(JavaVM *vm, void *) {
+    JNIEnv *env = NULL;
+    if (vm->GetEnv((void**)&env, JNI_VERSION_1_4) != JNI_OK) {
+        return JNI_ERR;
+    }
+    if (register_android_view_cts_ChoreographerNativeTest(env)) {
+        return JNI_ERR;
+    }
+    return JNI_VERSION_1_4;
+}
diff --git a/tests/tests/view/jni/android_view_cts_ChoreographerNativeTest.cpp b/tests/tests/view/jni/android_view_cts_ChoreographerNativeTest.cpp
new file mode 100644
index 0000000..45b82d6
--- /dev/null
+++ b/tests/tests/view/jni/android_view_cts_ChoreographerNativeTest.cpp
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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/choreographer.h>
+
+#include <jni.h>
+#include <sys/time.h>
+#include <time.h>
+
+#include <chrono>
+#include <cstdlib>
+#include <cstring>
+#include <mutex>
+#include <thread>
+
+#define LOG_TAG "ChoreographerNative"
+
+#define ASSERT(condition, format, args...) \
+        if (!(condition)) { \
+            fail(env, format, ## args); \
+            return; \
+        }
+
+
+using namespace std::chrono_literals;
+
+static constexpr std::chrono::nanoseconds NOMINAL_VSYNC_PERIOD{16ms};
+static constexpr std::chrono::nanoseconds DELAY_PERIOD{NOMINAL_VSYNC_PERIOD * 5};
+
+static std::mutex gLock;
+struct Callback {
+    int count{0};
+    std::chrono::nanoseconds frameTime{0};
+};
+
+static void frameCallback(long frameTimeNanos, void* data) {
+    std::lock_guard<std::mutex> _l(gLock);
+    Callback* cb = static_cast<Callback*>(data);
+    cb->count++;
+    cb->frameTime = std::chrono::nanoseconds{frameTimeNanos};
+}
+
+static std::chrono::nanoseconds now() {
+    return std::chrono::steady_clock::now().time_since_epoch();
+}
+
+static void fail(JNIEnv* env, const char* format, ...) {
+    va_list args;
+
+    va_start(args, format);
+    char *msg;
+    int rc = vasprintf(&msg, format, args);
+    va_end(args);
+
+    jclass exClass;
+    const char *className = "java/lang/AssertionError";
+    exClass = env->FindClass(className);
+    env->ThrowNew(exClass, msg);
+    free(msg);
+}
+
+static jlong android_view_cts_ChoreographerNativeTest_getChoreographer(JNIEnv*, jclass) {
+    std::lock_guard<std::mutex> _l{gLock};
+    return reinterpret_cast<jlong>(AChoreographer_getInstance());
+}
+
+static jboolean android_view_cts_ChoreographerNativeTest_prepareChoreographerTests(JNIEnv*, jclass,
+        jlong choreographerPtr) {
+    std::lock_guard<std::mutex> _l{gLock};
+    AChoreographer* choreographer = reinterpret_cast<AChoreographer*>(choreographerPtr);
+    return choreographer != nullptr;
+}
+
+static void android_view_cts_ChoreographerNativeTest_testPostCallbackWithoutDelayEventuallyRunsCallback(
+        JNIEnv* env, jclass, jlong choreographerPtr) {
+    AChoreographer* choreographer = reinterpret_cast<AChoreographer*>(choreographerPtr);
+    Callback* cb1 = new Callback();
+    Callback* cb2 = new Callback();
+    auto start = now();
+
+    AChoreographer_postFrameCallback(choreographer, frameCallback, cb1);
+    AChoreographer_postFrameCallback(choreographer, frameCallback, cb2);
+    std::this_thread::sleep_for(NOMINAL_VSYNC_PERIOD * 3);
+    {
+        std::lock_guard<std::mutex> _l{gLock};
+        ASSERT(cb1->count == 1, "Choreographer failed to invoke callback 1");
+        ASSERT(cb1->frameTime - start < NOMINAL_VSYNC_PERIOD * 3,
+                "Callback 1 has incorect frame time on first invokation");
+        ASSERT(cb2->count == 1, "Choreographer failed to invoke callback 2");
+        ASSERT(cb2->frameTime - start < NOMINAL_VSYNC_PERIOD * 3,
+                "Callback 2 has incorect frame time on first invokation");
+        auto delta = cb2->frameTime - cb1->frameTime;
+        ASSERT(delta == delta.zero() || delta > delta.zero() && delta < NOMINAL_VSYNC_PERIOD * 2,
+                "Callback 1 and 2 have frame times too large of a delta in frame times");
+    }
+
+    AChoreographer_postFrameCallback(choreographer, frameCallback, cb1);
+    start = now();
+    std::this_thread::sleep_for(NOMINAL_VSYNC_PERIOD * 3);
+    {
+        std::lock_guard<std::mutex> _l{gLock};
+        ASSERT(cb1->count == 2, "Choreographer failed to invoke callback 1 a second time");
+        ASSERT(cb1->frameTime - start < NOMINAL_VSYNC_PERIOD * 3,
+                "Callback 1 has incorect frame time on second invokation");
+        ASSERT(cb2->count == 1, "Choreographer invoked callback 2 when not posted");
+    }
+}
+
+static void android_view_cts_ChoreographerNativeTest_testPostCallbackWithDelayEventuallyRunsCallback(
+        JNIEnv* env, jclass, jlong choreographerPtr) {
+    AChoreographer* choreographer = reinterpret_cast<AChoreographer*>(choreographerPtr);
+    Callback* cb1 = new Callback();
+    auto start = now();
+
+    auto delay = std::chrono::duration_cast<std::chrono::milliseconds>(DELAY_PERIOD).count();
+    AChoreographer_postFrameCallbackDelayed(choreographer, frameCallback, cb1, delay);
+    std::this_thread::sleep_for(NOMINAL_VSYNC_PERIOD * 3);
+    {
+        std::lock_guard<std::mutex> _l{gLock};
+        ASSERT(cb1->count == 0,
+                "Choreographer failed to delay callback for a sufficient period of time");
+    }
+    std::this_thread::sleep_for(DELAY_PERIOD);
+    {
+        std::lock_guard<std::mutex> _l{gLock};
+        ASSERT(cb1->count == 1, "Choreographer failed to invoke delayed callback");
+        ASSERT(cb1->frameTime - start < DELAY_PERIOD + NOMINAL_VSYNC_PERIOD * 3,
+                "Frametime on callback is incorrect")
+    }
+}
+
+static JNINativeMethod gMethods[] = {
+    {  "nativeGetChoreographer", "()J",
+            (void *) android_view_cts_ChoreographerNativeTest_getChoreographer},
+    {  "nativePrepareChoreographerTests", "(J)Z",
+            (void *) android_view_cts_ChoreographerNativeTest_prepareChoreographerTests},
+    {  "nativeTestPostCallbackWithoutDelayEventuallyRunsCallbacks", "(J)V",
+            (void *) android_view_cts_ChoreographerNativeTest_testPostCallbackWithoutDelayEventuallyRunsCallback},
+    {  "nativeTestPostCallbackWithDelayEventuallyRunsCallbacks", "(J)V",
+            (void *) android_view_cts_ChoreographerNativeTest_testPostCallbackWithDelayEventuallyRunsCallback},
+};
+
+int register_android_view_cts_ChoreographerNativeTest(JNIEnv* env)
+{
+    jclass clazz = env->FindClass("android/view/cts/ChoreographerNativeTest");
+    return env->RegisterNatives(clazz, gMethods,
+            sizeof(gMethods) / sizeof(JNINativeMethod));
+}
diff --git a/tests/tests/view/res/drawable/custom_pointer_icon.xml b/tests/tests/view/res/drawable/custom_pointer_icon.xml
new file mode 100644
index 0000000..fc5a9e1
--- /dev/null
+++ b/tests/tests/view/res/drawable/custom_pointer_icon.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<pointer-icon xmlns:android="http://schemas.android.com/apk/res/android"
+              android:bitmap="@drawable/icon_red"
+              android:hotSpotX="16dp"
+              android:hotSpotY="16dp" />
diff --git a/tests/tests/view/res/layout/view_layout.xml b/tests/tests/view/res/layout/view_layout.xml
index b501a4d..df1fae9 100644
--- a/tests/tests/view/res/layout/view_layout.xml
+++ b/tests/tests/view/res/layout/view_layout.xml
@@ -102,4 +102,50 @@
         android:layout_width="wrap_content"
         android:layout_height="wrap_content" />
 
+    <LinearLayout
+        android:id="@+id/pointer_icon_layout"
+        android:orientation="vertical"
+        android:layout_width="100px"
+        android:layout_height="100px">
+      <LinearLayout
+          android:orientation="vertical"
+          android:layout_width="match_parent"
+          android:layout_height="70px"
+          android:pointerShape="crosshair">
+        <View android:layout_width="match_parent"
+              android:layout_height="20px"
+              android:pointerShape="help"/>
+        <View android:layout_width="match_parent"
+              android:layout_height="20px"/>
+        <View android:layout_width="match_parent"
+              android:layout_height="20px"
+              android:pointerShape="@drawable/custom_pointer_icon"/>
+      </LinearLayout>
+    </LinearLayout>
+
+    <FrameLayout
+        android:id="@+id/aggregate_visibility_parent"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content">
+        <android.view.cts.MockView
+            android:id="@+id/mock_view_aggregate_visibility"
+            android:layout_width="10px"
+            android:layout_height="10px" />
+    </FrameLayout>
+
+    <View
+            android:id="@+id/overlapping_rendering_unset"
+            android:layout_width="10px"
+            android:layout_height="10px" />
+    <View
+            android:id="@+id/overlapping_rendering_false"
+            android:forceHasOverlappingRendering="false"
+            android:layout_width="10px"
+            android:layout_height="10px" />
+    <View
+            android:id="@+id/overlapping_rendering_true"
+            android:forceHasOverlappingRendering="true"
+            android:layout_width="10px"
+            android:layout_height="10px" />
+
 </LinearLayout>
diff --git a/tests/tests/view/res/layout/viewgroupoverlay_layout.xml b/tests/tests/view/res/layout/viewgroupoverlay_layout.xml
new file mode 100644
index 0000000..39523a9
--- /dev/null
+++ b/tests/tests/view/res/layout/viewgroupoverlay_layout.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<RelativeLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <FrameLayout
+        android:id="@+id/viewgroup_with_overlay"
+        android:layout_width="100px"
+        android:layout_height="100px"
+        android:layout_centerInParent="true"
+        android:background="#FFF">
+
+        <RelativeLayout
+            android:id="@+id/level2"
+            android:layout_width="50px"
+            android:layout_height="50px"
+            android:layout_gravity="bottom|right">
+
+            <FrameLayout
+                android:id="@+id/level3"
+                android:layout_width="20px"
+                android:layout_height="30px"
+                android:layout_centerInParent="true" />
+
+        </RelativeLayout>
+
+    </FrameLayout>
+
+</RelativeLayout>
diff --git a/tests/tests/view/res/layout/viewoverlay_layout.xml b/tests/tests/view/res/layout/viewoverlay_layout.xml
new file mode 100644
index 0000000..089dff5
--- /dev/null
+++ b/tests/tests/view/res/layout/viewoverlay_layout.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<RelativeLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <View
+        android:id="@+id/view_with_overlay"
+        android:layout_width="100px"
+        android:layout_height="100px"
+        android:layout_centerInParent="true"
+        android:background="#FFF"/>
+
+</RelativeLayout>
diff --git a/tests/tests/view/res/menu/menu_settings.xml b/tests/tests/view/res/menu/menu_settings.xml
new file mode 100644
index 0000000..4f210d9
--- /dev/null
+++ b/tests/tests/view/res/menu/menu_settings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+    <item
+            android:id="@+id/action_settings"
+            android:orderInCategory="100"
+            android:title="Settings"/>
+</menu>
diff --git a/tests/tests/view/src/android/view/animation/cts/AccelerateDecelerateInterpolatorTest.java b/tests/tests/view/src/android/view/animation/cts/AccelerateDecelerateInterpolatorTest.java
index 6e80d00..440e390 100644
--- a/tests/tests/view/src/android/view/animation/cts/AccelerateDecelerateInterpolatorTest.java
+++ b/tests/tests/view/src/android/view/animation/cts/AccelerateDecelerateInterpolatorTest.java
@@ -16,7 +16,7 @@
 
 package android.view.animation.cts;
 
-import com.android.cts.view.R;
+import android.view.cts.R;
 
 
 import android.app.Activity;
@@ -41,7 +41,7 @@
     private static final long ALPHA_DURATION = 2000;
 
     public AccelerateDecelerateInterpolatorTest() {
-        super("com.android.cts.view", AnimationTestCtsActivity.class);
+        super("android.view.cts", AnimationTestCtsActivity.class);
     }
 
     @Override
diff --git a/tests/tests/view/src/android/view/animation/cts/AccelerateInterpolatorTest.java b/tests/tests/view/src/android/view/animation/cts/AccelerateInterpolatorTest.java
index 51b2b09..b2be24d 100644
--- a/tests/tests/view/src/android/view/animation/cts/AccelerateInterpolatorTest.java
+++ b/tests/tests/view/src/android/view/animation/cts/AccelerateInterpolatorTest.java
@@ -16,7 +16,7 @@
 
 package android.view.animation.cts;
 
-import com.android.cts.view.R;
+import android.view.cts.R;
 
 
 import android.app.Activity;
@@ -36,7 +36,7 @@
         extends ActivityInstrumentationTestCase2<AnimationTestCtsActivity> {
 
     public AccelerateInterpolatorTest() {
-        super("com.android.cts.view", AnimationTestCtsActivity.class);
+        super("android.view.cts", AnimationTestCtsActivity.class);
     }
 
     private Activity mActivity;
diff --git a/tests/tests/view/src/android/view/animation/cts/AlphaAnimationTest.java b/tests/tests/view/src/android/view/animation/cts/AlphaAnimationTest.java
index acfe1a6..45eb418 100644
--- a/tests/tests/view/src/android/view/animation/cts/AlphaAnimationTest.java
+++ b/tests/tests/view/src/android/view/animation/cts/AlphaAnimationTest.java
@@ -23,7 +23,7 @@
 import android.view.animation.AlphaAnimation;
 import android.view.animation.Transformation;
 
-import com.android.cts.view.R;
+import android.view.cts.R;
 
 /**
  * Test {@link AlphaAnimation}.
diff --git a/tests/tests/view/src/android/view/animation/cts/AnimationSetTest.java b/tests/tests/view/src/android/view/animation/cts/AnimationSetTest.java
index 0b3bf49..49c51e0 100644
--- a/tests/tests/view/src/android/view/animation/cts/AnimationSetTest.java
+++ b/tests/tests/view/src/android/view/animation/cts/AnimationSetTest.java
@@ -33,7 +33,7 @@
 import android.view.animation.Transformation;
 import android.view.animation.TranslateAnimation;
 
-import com.android.cts.view.R;
+import android.view.cts.R;
 
 
 public class AnimationSetTest
@@ -51,7 +51,7 @@
     private Activity mActivity;
 
     public AnimationSetTest() {
-        super("com.android.cts.view", AnimationTestCtsActivity.class);
+        super("android.view.cts", AnimationTestCtsActivity.class);
     }
 
     @Override
diff --git a/tests/tests/view/src/android/view/animation/cts/AnimationTest.java b/tests/tests/view/src/android/view/animation/cts/AnimationTest.java
index 31440df..a465824 100644
--- a/tests/tests/view/src/android/view/animation/cts/AnimationTest.java
+++ b/tests/tests/view/src/android/view/animation/cts/AnimationTest.java
@@ -16,7 +16,7 @@
 
 package android.view.animation.cts;
 
-import com.android.cts.view.R;
+import android.view.cts.R;
 
 
 import android.app.Activity;
@@ -35,6 +35,9 @@
 import android.view.animation.Transformation;
 import android.view.animation.Animation.AnimationListener;
 
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
 /**
  * Test {@link Animation}.
  */
@@ -51,7 +54,7 @@
     private Object mLockObject = new Object();
 
     public AnimationTest() {
-        super("com.android.cts.view", AnimationTestCtsActivity.class);
+        super("android.view.cts", AnimationTestCtsActivity.class);
     }
 
     @Override
@@ -644,7 +647,82 @@
         assertEquals(myAnimation.getRepeatMode(), cloneAnimation.getRepeatMode());
     }
 
+    public void testCancelImmediately() throws Throwable {
+        MyAnimation anim = new MyAnimation();
+        final CountDownLatch latch1 = new CountDownLatch(1);
+        runCanceledAnimation(anim, latch1, false, false);
+        assertTrue(latch1.await(200, TimeUnit.MILLISECONDS));
+        assertFalse(anim.isStillAnimating());
+    }
+
+    public void testRepeatingCancelImmediately() throws Throwable {
+        MyAnimation anim = new MyAnimation();
+        final CountDownLatch latch2 = new CountDownLatch(1);
+        runCanceledAnimation(anim, latch2, true, false);
+        assertTrue(latch2.await(200, TimeUnit.MILLISECONDS));
+        assertFalse(anim.isStillAnimating());
+    }
+
+    public void testCancelDelayed() throws Throwable {
+        MyAnimation anim = new MyAnimation();
+        final CountDownLatch latch3 = new CountDownLatch(1);
+        runCanceledAnimation(anim, latch3, false, true);
+        assertTrue(latch3.await(250, TimeUnit.MILLISECONDS));
+        assertFalse(anim.isStillAnimating());
+    }
+
+    public void testRepeatingCancelDelayed() throws Throwable {
+        MyAnimation anim = new MyAnimation();
+        final CountDownLatch latch4 = new CountDownLatch(1);
+        runCanceledAnimation(anim, latch4, true, true);
+        assertTrue(latch4.await(250, TimeUnit.MILLISECONDS));
+        assertFalse(anim.isStillAnimating());
+    }
+
+    private void runCanceledAnimation(final MyAnimation anim, final CountDownLatch latch,
+            final boolean repeating, final boolean delayed) throws Throwable {
+        // The idea behind this test is that canceling an Animation should result in
+        // it ending, which means not having its getTransformation() method called
+        // anymore. The trick is that cancel() will still allow one more frame to run,
+        // so we have to insert some delay between when we cancel and when we can check
+        // whether it is still animating.
+        runTestOnUiThread(new Runnable() {
+            final View view = mActivity.findViewById(R.id.anim_window);
+            public void run() {
+                anim.setDuration(delayed ? 150 : 100);
+                if (repeating) {
+                    anim.setRepeatCount(Animation.INFINITE);
+                }
+                view.startAnimation(anim);
+                if (!delayed) {
+                    anim.cancel();
+                } else {
+                    view.postDelayed(new Runnable() {
+                        @Override
+                        public void run() {
+                            anim.cancel();
+                        }
+                    }, 50);
+                }
+                view.postDelayed(new Runnable() {
+                    @Override
+                    public void run() {
+                        anim.setStillAnimating(false);
+                        view.postDelayed(new Runnable() {
+                            @Override
+                            public void run() {
+                                latch.countDown();
+                            }
+                        }, 50);
+                    }
+                }, delayed ? 100 : 50);
+            }
+        });
+    }
+
     private class MyAnimation extends Animation {
+        boolean mStillAnimating = false;
+
         @Override
         protected void ensureInterpolator() {
             super.ensureInterpolator();
@@ -659,6 +737,20 @@
         protected Animation clone() throws CloneNotSupportedException {
             return super.clone();
         }
+
+        public void setStillAnimating(boolean value) {
+            mStillAnimating = value;
+        }
+
+        public boolean isStillAnimating() {
+            return mStillAnimating;
+        }
+
+        @Override
+        public boolean getTransformation(long currentTime, Transformation outTransformation) {
+            mStillAnimating = true;
+            return super.getTransformation(currentTime, outTransformation);
+        }
     }
 
     private class MockAnimationListener implements AnimationListener {
diff --git a/tests/tests/view/src/android/view/animation/cts/AnimationTestCtsActivity.java b/tests/tests/view/src/android/view/animation/cts/AnimationTestCtsActivity.java
index 1ef9e48..0316f28 100644
--- a/tests/tests/view/src/android/view/animation/cts/AnimationTestCtsActivity.java
+++ b/tests/tests/view/src/android/view/animation/cts/AnimationTestCtsActivity.java
@@ -16,7 +16,7 @@
 
 package android.view.animation.cts;
 
-import com.android.cts.view.R;
+import android.view.cts.R;
 
 import android.app.Activity;
 import android.os.Bundle;
diff --git a/tests/tests/view/src/android/view/animation/cts/AnimationUtilsTest.java b/tests/tests/view/src/android/view/animation/cts/AnimationUtilsTest.java
index 9de0d87..b47613f 100644
--- a/tests/tests/view/src/android/view/animation/cts/AnimationUtilsTest.java
+++ b/tests/tests/view/src/android/view/animation/cts/AnimationUtilsTest.java
@@ -16,7 +16,7 @@
 
 package android.view.animation.cts;
 
-import com.android.cts.view.R;
+import android.view.cts.R;
 
 
 import android.content.Context;
@@ -35,7 +35,7 @@
     private AnimationTestCtsActivity mActivity;
 
     public AnimationUtilsTest() {
-        super("com.android.cts.view", AnimationTestCtsActivity.class);
+        super("android.view.cts", AnimationTestCtsActivity.class);
     }
 
     @Override
@@ -45,7 +45,7 @@
     }
 
     public void testLoad() {
-        // XML file of com.android.cts.view.R.anim.anim_alpha
+        // XML file of android.view.cts.R.anim.anim_alpha
         // <alpha xmlns:android="http://schemas.android.com/apk/res/android"
         //      android:interpolator="@android:anim/accelerate_interpolator"
         //      android:fromAlpha="0.0"
@@ -61,7 +61,7 @@
                 android.R.anim.accelerate_interpolator);
         assertTrue(interpolator instanceof AccelerateInterpolator);
 
-        // Load LayoutAnimationController from com.android.cts.view.R.anim.anim_gridlayout
+        // Load LayoutAnimationController from android.view.cts.R.anim.anim_gridlayout
         // <gridLayoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
         //      android:delay="10%"
         //      android:rowDelay="50%"
diff --git a/tests/tests/view/src/android/view/animation/cts/AnimatorInflaterTest.java b/tests/tests/view/src/android/view/animation/cts/AnimatorInflaterTest.java
index cc8ada0..3851e94 100644
--- a/tests/tests/view/src/android/view/animation/cts/AnimatorInflaterTest.java
+++ b/tests/tests/view/src/android/view/animation/cts/AnimatorInflaterTest.java
@@ -36,7 +36,7 @@
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
-import com.android.cts.view.R;
+import android.view.cts.R;
 
 public class AnimatorInflaterTest
         extends ActivityInstrumentationTestCase2<AnimationTestCtsActivity> {
@@ -45,7 +45,7 @@
     Set<Integer> identityHashes = new HashSet<Integer>();
 
     public AnimatorInflaterTest() {
-        super("com.android.cts.view", AnimationTestCtsActivity.class);
+        super("android.view.cts", AnimationTestCtsActivity.class);
     }
 
     private void assertUnique(Object object) {
diff --git a/tests/tests/view/src/android/view/animation/cts/CycleInterpolatorTest.java b/tests/tests/view/src/android/view/animation/cts/CycleInterpolatorTest.java
index 3297377..3ac5950 100644
--- a/tests/tests/view/src/android/view/animation/cts/CycleInterpolatorTest.java
+++ b/tests/tests/view/src/android/view/animation/cts/CycleInterpolatorTest.java
@@ -29,7 +29,7 @@
 import android.view.animation.Interpolator;
 import android.view.animation.Transformation;
 
-import com.android.cts.view.R;
+import android.view.cts.R;
 
 
 /**
@@ -45,7 +45,7 @@
     private static final float ALPHA_DELTA = 0.001f;
 
     public CycleInterpolatorTest() {
-        super("com.android.cts.view", AnimationTestCtsActivity.class);
+        super("android.view.cts", AnimationTestCtsActivity.class);
     }
 
     @Override
diff --git a/tests/tests/view/src/android/view/animation/cts/DecelerateInterpolatorTest.java b/tests/tests/view/src/android/view/animation/cts/DecelerateInterpolatorTest.java
index deb52dd..2400291 100644
--- a/tests/tests/view/src/android/view/animation/cts/DecelerateInterpolatorTest.java
+++ b/tests/tests/view/src/android/view/animation/cts/DecelerateInterpolatorTest.java
@@ -16,7 +16,7 @@
 
 package android.view.animation.cts;
 
-import com.android.cts.view.R;
+import android.view.cts.R;
 
 
 import android.app.Activity;
@@ -45,7 +45,7 @@
     private static final long DECELERATE_ALPHA_DURATION = 2000;
 
     public DecelerateInterpolatorTest() {
-        super("com.android.cts.view", AnimationTestCtsActivity.class);
+        super("android.view.cts", AnimationTestCtsActivity.class);
     }
 
     @Override
diff --git a/tests/tests/view/src/android/view/animation/cts/GridLayoutAnimCtsActivity.java b/tests/tests/view/src/android/view/animation/cts/GridLayoutAnimCtsActivity.java
index bf95077..371af41 100644
--- a/tests/tests/view/src/android/view/animation/cts/GridLayoutAnimCtsActivity.java
+++ b/tests/tests/view/src/android/view/animation/cts/GridLayoutAnimCtsActivity.java
@@ -16,7 +16,7 @@
 
 package android.view.animation.cts;
 
-import com.android.cts.view.R;
+import android.view.cts.R;
 
 import android.app.Activity;
 import android.database.DataSetObserver;
diff --git a/tests/tests/view/src/android/view/animation/cts/GridLayoutAnimationControllerTest.java b/tests/tests/view/src/android/view/animation/cts/GridLayoutAnimationControllerTest.java
index 54898b4..58efa0e 100644
--- a/tests/tests/view/src/android/view/animation/cts/GridLayoutAnimationControllerTest.java
+++ b/tests/tests/view/src/android/view/animation/cts/GridLayoutAnimationControllerTest.java
@@ -16,7 +16,7 @@
 
 package android.view.animation.cts;
 
-import com.android.cts.view.R;
+import android.view.cts.R;
 
 
 import android.content.Context;
@@ -58,7 +58,7 @@
     private static final int INDEX_OF_CHILD9 = 8;
 
     public GridLayoutAnimationControllerTest() {
-        super("com.android.cts.view", GridLayoutAnimCtsActivity.class);
+        super("android.view.cts", GridLayoutAnimCtsActivity.class);
     }
 
     @Override
diff --git a/tests/tests/view/src/android/view/animation/cts/LayoutAnimationControllerTest.java b/tests/tests/view/src/android/view/animation/cts/LayoutAnimationControllerTest.java
index 2f8f36d..adc4192 100644
--- a/tests/tests/view/src/android/view/animation/cts/LayoutAnimationControllerTest.java
+++ b/tests/tests/view/src/android/view/animation/cts/LayoutAnimationControllerTest.java
@@ -16,7 +16,7 @@
 
 package android.view.animation.cts;
 
-import com.android.cts.view.R;
+import android.view.cts.R;
 
 
 import android.app.ListActivity;
@@ -58,7 +58,7 @@
     private static final long DEFAULT_MAX_DURATION = 2000;
 
     public LayoutAnimationControllerTest() {
-        super("com.android.cts.view", LayoutAnimCtsActivity.class);
+        super("android.view.cts", LayoutAnimCtsActivity.class);
     }
 
     @Override
diff --git a/tests/tests/view/src/android/view/animation/cts/LinearInterpolatorTest.java b/tests/tests/view/src/android/view/animation/cts/LinearInterpolatorTest.java
index 28407f9..23f8608 100644
--- a/tests/tests/view/src/android/view/animation/cts/LinearInterpolatorTest.java
+++ b/tests/tests/view/src/android/view/animation/cts/LinearInterpolatorTest.java
@@ -26,7 +26,7 @@
 import android.view.animation.LinearInterpolator;
 import android.view.animation.Transformation;
 
-import com.android.cts.view.R;
+import android.view.cts.R;
 
 
 /**
@@ -42,7 +42,7 @@
     private static final long LINEAR_ALPHA_TIME_STEP = LINEAR_ALPHA_DURATION / 5;
 
     public LinearInterpolatorTest() {
-        super("com.android.cts.view", AnimationTestCtsActivity.class);
+        super("android.view.cts", AnimationTestCtsActivity.class);
     }
 
     @Override
diff --git a/tests/tests/view/src/android/view/animation/cts/RotateAnimationTest.java b/tests/tests/view/src/android/view/animation/cts/RotateAnimationTest.java
index 958133a..afeba5c 100644
--- a/tests/tests/view/src/android/view/animation/cts/RotateAnimationTest.java
+++ b/tests/tests/view/src/android/view/animation/cts/RotateAnimationTest.java
@@ -28,7 +28,7 @@
 import android.view.animation.RotateAnimation;
 import android.view.animation.Transformation;
 
-import com.android.cts.view.R;
+import android.view.cts.R;
 
 
 public class RotateAnimationTest
@@ -42,7 +42,7 @@
     private static final float TO_DEGREE = 90.0f;
 
     public RotateAnimationTest() {
-        super("com.android.cts.view", AnimationTestCtsActivity.class);
+        super("android.view.cts", AnimationTestCtsActivity.class);
     }
 
     @Override
diff --git a/tests/tests/view/src/android/view/animation/cts/ScaleAnimationTest.java b/tests/tests/view/src/android/view/animation/cts/ScaleAnimationTest.java
index e17435e..dc78fa9 100644
--- a/tests/tests/view/src/android/view/animation/cts/ScaleAnimationTest.java
+++ b/tests/tests/view/src/android/view/animation/cts/ScaleAnimationTest.java
@@ -16,7 +16,7 @@
 
 package android.view.animation.cts;
 
-import com.android.cts.view.R;
+import android.view.cts.R;
 
 
 import android.content.res.XmlResourceParser;
@@ -44,7 +44,7 @@
     private AnimationTestCtsActivity mActivity;
 
     public ScaleAnimationTest() {
-        super("com.android.cts.view", AnimationTestCtsActivity.class);
+        super("android.view.cts", AnimationTestCtsActivity.class);
     }
 
     @Override
diff --git a/tests/tests/view/src/android/view/animation/cts/TranslateAnimationTest.java b/tests/tests/view/src/android/view/animation/cts/TranslateAnimationTest.java
index 94ab558..06daa72 100644
--- a/tests/tests/view/src/android/view/animation/cts/TranslateAnimationTest.java
+++ b/tests/tests/view/src/android/view/animation/cts/TranslateAnimationTest.java
@@ -28,7 +28,7 @@
 import android.view.animation.Transformation;
 import android.view.animation.TranslateAnimation;
 
-import com.android.cts.view.R;
+import android.view.cts.R;
 
 
 public class TranslateAnimationTest
@@ -48,7 +48,7 @@
     private static final float RELATIVE_TO_Y_DELTA = 0.4f;
 
     public TranslateAnimationTest() {
-        super("com.android.cts.view", AnimationTestCtsActivity.class);
+        super("android.view.cts", AnimationTestCtsActivity.class);
     }
 
     @Override
diff --git a/tests/tests/view/src/android/view/cts/ChoreographerNativeTest.java b/tests/tests/view/src/android/view/cts/ChoreographerNativeTest.java
new file mode 100644
index 0000000..38f351c
--- /dev/null
+++ b/tests/tests/view/src/android/view/cts/ChoreographerNativeTest.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.view.cts;
+
+import android.test.InstrumentationTestCase;
+import android.view.Choreographer;
+
+public class ChoreographerNativeTest extends InstrumentationTestCase {
+    private long mChoreographerPtr;
+    private Choreographer mChoreographer;
+
+    private static native long nativeGetChoreographer();
+    private static native boolean nativePrepareChoreographerTests(long ptr);
+    private static native void nativeTestPostCallbackWithoutDelayEventuallyRunsCallbacks(long ptr);
+    private static native void nativeTestPostCallbackWithDelayEventuallyRunsCallbacks(long ptr);
+
+    static {
+        System.loadLibrary("ctsview_jni");
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                mChoreographerPtr = nativeGetChoreographer();
+            }
+        });
+        if (!nativePrepareChoreographerTests(mChoreographerPtr)) {
+            fail("Failed to setup choreographer tests");
+        }
+    }
+
+    public void testPostCallbackWithoutDelayEventuallyRunsCallbacks() {
+        nativeTestPostCallbackWithoutDelayEventuallyRunsCallbacks(mChoreographerPtr);
+    }
+
+    public void testPostCallbackWithDelayEventuallyRunsCallbacks() {
+        nativeTestPostCallbackWithDelayEventuallyRunsCallbacks(mChoreographerPtr);
+    }
+}
diff --git a/tests/tests/view/src/android/view/cts/ContentPaneCtsActivity.java b/tests/tests/view/src/android/view/cts/ContentPaneCtsActivity.java
new file mode 100644
index 0000000..f6315c8
--- /dev/null
+++ b/tests/tests/view/src/android/view/cts/ContentPaneCtsActivity.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.view.cts;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.Menu;
+import android.view.Window;
+
+/**
+ * A simple activity to test "Focus Handling"
+ */
+public class ContentPaneCtsActivity extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setTheme(android.R.style.Theme_Material_Light);
+        getWindow().requestFeature(Window.FEATURE_OPTIONS_PANEL);
+        setContentView(R.layout.viewtreeobserver_layout);
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        // Inflate the menu; this adds items to the action bar if it is present.
+        getMenuInflater().inflate(R.menu.menu_settings, menu);
+        return true;
+    }
+}
diff --git a/tests/tests/view/src/android/view/cts/ContentPaneFocusTest.java b/tests/tests/view/src/android/view/cts/ContentPaneFocusTest.java
new file mode 100644
index 0000000..eaaea74
--- /dev/null
+++ b/tests/tests/view/src/android/view/cts/ContentPaneFocusTest.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.view.cts;
+
+import android.app.ActionBar;
+import android.app.Activity;
+import android.content.pm.PackageManager;
+import android.os.SystemClock;
+import android.test.ActivityInstrumentationTestCase2;
+import android.view.KeyCharacterMap;
+import android.view.KeyEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewParent;
+
+public class ContentPaneFocusTest
+        extends ActivityInstrumentationTestCase2<ContentPaneCtsActivity> {
+    public ContentPaneFocusTest() {
+        super("android.view.cts", ContentPaneCtsActivity.class);
+    }
+
+    public void testAccessActionBar() throws Throwable {
+        final Activity activity = getActivity();
+
+        final View v1 = activity.findViewById(R.id.view1);
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                v1.requestFocus();
+            }
+        });
+
+        getInstrumentation().waitForIdleSync();
+        sendControlChar('<');
+        getInstrumentation().waitForIdleSync();
+
+        ActionBar action = activity.getActionBar();
+        if (action == null || !action.isShowing()) {
+            // No action bar, so we only needed to make sure that the shortcut didn't cause
+            // the framework to crash.
+            return;
+        }
+
+        final View content = activity.findViewById(android.R.id.content);
+        assertNotNull(content);
+        final ViewParent viewParent = content.getParent();
+        assertNotNull(viewParent);
+        assertTrue(viewParent instanceof ViewGroup);
+        ViewGroup parent = (ViewGroup) viewParent;
+        View actionBarView = null;
+        for (int i = 0; i < parent.getChildCount(); i++) {
+            View child = parent.getChildAt(i);
+            if ("android:action_bar".equals(child.getTransitionName())) {
+                actionBarView = child;
+                break;
+            }
+        }
+        assertNotNull(actionBarView);
+        final View actionBar = actionBarView;
+        // Should jump to the action bar after control-<
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                assertFalse(v1.hasFocus());
+                assertTrue(actionBar.hasFocus());
+            }
+        });
+        getInstrumentation().sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_DOWN);
+        getInstrumentation().waitForIdleSync();
+
+        // Should jump to the first view again.
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                assertTrue(v1.hasFocus());
+            }
+        });
+        getInstrumentation().sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_UP);
+        getInstrumentation().waitForIdleSync();
+
+        boolean isTouchScreen = activity.getPackageManager().
+                hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN);
+        if (isTouchScreen) {
+            // Now it shouldn't go up to action bar -- it doesn't allow taking focus once left
+            // but only for touch screens.
+            runTestOnUiThread(new Runnable() {
+                @Override
+                public void run() {
+                    assertTrue(v1.hasFocus());
+                }
+            });
+        }
+    }
+
+    private void sendControlChar(char key) throws Throwable {
+        KeyEvent tempEvent = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_A);
+        KeyCharacterMap map = tempEvent.getKeyCharacterMap();
+        sendControlKey(KeyEvent.ACTION_DOWN);
+        KeyEvent[] events = map.getEvents(new char[] {key});
+        final int controlOn = KeyEvent.META_CTRL_ON | KeyEvent.META_CTRL_LEFT_ON;
+        for (int i = 0; i < events.length; i++) {
+            long time = SystemClock.uptimeMillis();
+            KeyEvent event = events[i];
+            KeyEvent controlKey = new KeyEvent(time, time, event.getAction(), event.getKeyCode(),
+                    event.getRepeatCount(), event.getMetaState() | controlOn);
+            getInstrumentation().sendKeySync(controlKey);
+            Thread.sleep(2);
+        }
+        sendControlKey(KeyEvent.ACTION_UP);
+    }
+
+    private void sendControlKey(int action) throws Throwable {
+        long time = SystemClock.uptimeMillis();
+        KeyEvent keyEvent = new KeyEvent(time, time, action, KeyEvent.KEYCODE_CTRL_LEFT, 0,
+                KeyEvent.META_CTRL_LEFT_ON | KeyEvent.META_CTRL_ON);
+        getInstrumentation().sendKeySync(keyEvent);
+        Thread.sleep(2);
+    }
+}
diff --git a/tests/tests/view/src/android/view/cts/ContextThemeWrapperTest.java b/tests/tests/view/src/android/view/cts/ContextThemeWrapperTest.java
index 012a13d..ccf37949 100644
--- a/tests/tests/view/src/android/view/cts/ContextThemeWrapperTest.java
+++ b/tests/tests/view/src/android/view/cts/ContextThemeWrapperTest.java
@@ -17,14 +17,14 @@
 package android.view.cts;
 
 import android.content.Context;
+import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.content.res.Resources.Theme;
 import android.test.AndroidTestCase;
 import android.view.ContextThemeWrapper;
 
-import com.android.cts.view.R;
-
+import android.view.cts.R;
 
 public class ContextThemeWrapperTest extends AndroidTestCase {
     private static final int SYSTEM_DEFAULT_THEME = 0;
@@ -103,6 +103,22 @@
         }).test());
     }
 
+    public void testApplyOverrideConfiguration() {
+        Context context = getContext();
+        final int realDensity = context.getResources().getConfiguration().densityDpi;
+        final int expectedDensity = realDensity + 1;
+
+        ContextThemeWrapper contextThemeWrapper = new ContextThemeWrapper(
+                context, SYSTEM_DEFAULT_THEME);
+
+        Configuration overrideConfig = new Configuration();
+        overrideConfig.densityDpi = expectedDensity;
+        contextThemeWrapper.applyOverrideConfiguration(overrideConfig);
+
+        Configuration actualConfiguration = contextThemeWrapper.getResources().getConfiguration();
+        assertEquals(expectedDensity, actualConfiguration.densityDpi);
+    }
+
     private void assertEqualsTextAppearanceStyle(TypedArray ta) {
         final int defValue = -1;
         // get Theme and assert
diff --git a/tests/tests/view/src/android/view/cts/FocusFinderCtsActivity.java b/tests/tests/view/src/android/view/cts/FocusFinderCtsActivity.java
index 14ab577..d2fa729 100644
--- a/tests/tests/view/src/android/view/cts/FocusFinderCtsActivity.java
+++ b/tests/tests/view/src/android/view/cts/FocusFinderCtsActivity.java
@@ -16,7 +16,7 @@
 
 package android.view.cts;
 
-import com.android.cts.view.R;
+import android.view.cts.R;
 
 import android.app.Activity;
 import android.content.Context;
diff --git a/tests/tests/view/src/android/view/cts/FocusFinderTest.java b/tests/tests/view/src/android/view/cts/FocusFinderTest.java
index 55c288e..6b3b784 100644
--- a/tests/tests/view/src/android/view/cts/FocusFinderTest.java
+++ b/tests/tests/view/src/android/view/cts/FocusFinderTest.java
@@ -34,7 +34,7 @@
     private Button mBottomRight;
 
     public FocusFinderTest() {
-        super("com.android.cts.view", FocusFinderCtsActivity.class);
+        super("android.view.cts", FocusFinderCtsActivity.class);
     }
 
     @Override
@@ -46,6 +46,10 @@
         mTopRight = getActivity().topRightButton;
         mBottomLeft = getActivity().bottomLeftButton;
         mBottomRight = getActivity().bottomRightButton;
+        mTopLeft.setNextFocusLeftId(View.NO_ID);
+        mTopRight.setNextFocusLeftId(View.NO_ID);
+        mBottomLeft.setNextFocusLeftId(View.NO_ID);
+        mBottomRight.setNextFocusLeftId(View.NO_ID);
     }
 
     public void testGetInstance() {
@@ -169,4 +173,50 @@
         assertEquals(0, deltas[0]);
         assertEquals(-1, deltas[1]);
     }
+
+    public void testFindNextAndPrevFocusAvoidingChain() {
+        mBottomRight.setNextFocusForwardId(mBottomLeft.getId());
+        mBottomLeft.setNextFocusForwardId(mTopRight.getId());
+        // Follow the chain
+        assertNextFocus(mBottomRight, View.FOCUS_FORWARD, mBottomLeft);
+        assertNextFocus(mBottomLeft, View.FOCUS_FORWARD, mTopRight);
+        assertNextFocus(mTopRight, View.FOCUS_BACKWARD, mBottomLeft);
+        assertNextFocus(mBottomLeft, View.FOCUS_BACKWARD, mBottomRight);
+
+        // Now go to the one not in the chain
+        assertNextFocus(mTopRight, View.FOCUS_FORWARD, mTopLeft);
+        assertNextFocus(mBottomRight, View.FOCUS_BACKWARD, mTopLeft);
+
+        // Now go back to the top of the chain
+        assertNextFocus(mTopLeft, View.FOCUS_FORWARD, mBottomRight);
+        assertNextFocus(mTopLeft, View.FOCUS_BACKWARD, mTopRight);
+
+        // Now make the chain a circle -- this is the pathological case
+        mTopRight.setNextFocusForwardId(mBottomRight.getId());
+        // Fall back to the next one in a chain.
+        assertNextFocus(mTopLeft, View.FOCUS_FORWARD, mTopRight);
+        assertNextFocus(mTopLeft, View.FOCUS_BACKWARD, mBottomRight);
+
+        //Now do branching focus changes
+        mTopRight.setNextFocusForwardId(View.NO_ID);
+        mBottomRight.setNextFocusForwardId(mTopRight.getId());
+        assertNextFocus(mBottomRight, View.FOCUS_FORWARD, mTopRight);
+        assertNextFocus(mBottomLeft, View.FOCUS_FORWARD, mTopRight);
+        // From the tail, it jumps out of the chain
+        assertNextFocus(mTopRight, View.FOCUS_FORWARD, mTopLeft);
+
+        // Back from the head of a tree goes out of the tree
+        // We don't know which is the head of the focus chain since it is branching.
+        View prevFocus1 = mFocusFinder.findNextFocus(mLayout, mBottomLeft, View.FOCUS_BACKWARD);
+        View prevFocus2 = mFocusFinder.findNextFocus(mLayout, mBottomRight, View.FOCUS_BACKWARD);
+        assertTrue(prevFocus1 == mTopLeft || prevFocus2 == mTopLeft);
+
+        // From outside, it chooses an arbitrary head of the chain
+        View nextFocus = mFocusFinder.findNextFocus(mLayout, mTopLeft, View.FOCUS_FORWARD);
+        assertTrue(nextFocus == mBottomRight || nextFocus == mBottomLeft);
+
+        // Going back from the tail of the split chain, it chooses an arbitrary head
+        nextFocus = mFocusFinder.findNextFocus(mLayout, mTopRight, View.FOCUS_BACKWARD);
+        assertTrue(nextFocus == mBottomRight || nextFocus == mBottomLeft);
+    }
 }
diff --git a/tests/tests/view/src/android/view/cts/FocusHandlingCtsActivity.java b/tests/tests/view/src/android/view/cts/FocusHandlingCtsActivity.java
index 5489e2a..86a1c9e 100644
--- a/tests/tests/view/src/android/view/cts/FocusHandlingCtsActivity.java
+++ b/tests/tests/view/src/android/view/cts/FocusHandlingCtsActivity.java
@@ -16,7 +16,7 @@
 
 package android.view.cts;
 
-import com.android.cts.view.R;
+import android.view.cts.R;
 
 import android.app.Activity;
 import android.os.Bundle;
diff --git a/tests/tests/view/src/android/view/cts/FrameMetricsListenerTest.java b/tests/tests/view/src/android/view/cts/FrameMetricsListenerTest.java
new file mode 100644
index 0000000..860c394
--- /dev/null
+++ b/tests/tests/view/src/android/view/cts/FrameMetricsListenerTest.java
@@ -0,0 +1,243 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.view.cts;
+
+import android.view.cts.R;
+
+import android.app.Activity;
+import android.app.Instrumentation;
+import android.cts.util.PollingCheck;
+import android.os.Looper;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.SystemClock;
+import android.test.ActivityInstrumentationTestCase2;
+import android.util.Log;
+import android.view.FrameMetrics;
+import android.view.View;
+import android.view.Window;
+import android.widget.ScrollView;
+
+import java.lang.Thread;
+import java.lang.Exception;
+import java.lang.System;
+import java.util.ArrayList;
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class FrameMetricsListenerTest extends ActivityInstrumentationTestCase2<MockActivity> {
+
+    private Instrumentation mInstrumentation;
+    private Window.FrameMetricsListener mFrameMetricsListener;
+    private Activity mActivity;
+
+    public FrameMetricsListenerTest() {
+        super(MockActivity.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mActivity = getActivity();
+        mInstrumentation = getInstrumentation();
+    }
+
+    private void layout(final int layoutId) {
+        mInstrumentation.runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                mActivity.setContentView(layoutId);
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+    }
+
+    public void testReceiveData() throws Throwable {
+        layout(R.layout.scrollview_layout);
+        final ScrollView scrollView = (ScrollView) mActivity.findViewById(R.id.scroll_view);
+        final ArrayList<FrameMetrics> data = new ArrayList<>();
+        final Handler handler = new Handler(Looper.getMainLooper());
+        final Window myWindow = mActivity.getWindow();
+        final Window.FrameMetricsListener listener =
+            new Window.FrameMetricsListener() {
+               @Override
+               public void onMetricsAvailable(Window window, FrameMetrics frameMetrics, int dropCount) {
+                   assertEquals(myWindow, window);
+                   assertEquals(0, dropCount);
+                   data.add(new FrameMetrics(frameMetrics));
+               }
+            };
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mActivity.getWindow().addFrameMetricsListener(listener, handler);
+            }
+        });
+
+        mInstrumentation.waitForIdleSync();
+
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                scrollView.fling(-100);
+            }
+        });
+
+        mInstrumentation.waitForIdleSync();
+        new PollingCheck() {
+            @Override
+            protected boolean check() {
+                return data.size() != 0;
+            }
+        }.run();
+
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mActivity.getWindow().removeFrameMetricsListener(listener);
+                data.clear();
+            }
+        });
+
+        mInstrumentation.waitForIdleSync();
+
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                scrollView.fling(100);
+                assertEquals(0, data.size());
+            }
+        });
+
+        mInstrumentation.waitForIdleSync();
+    }
+
+    public void testMultipleListeners() throws Throwable {
+        layout(R.layout.scrollview_layout);
+        final ScrollView scrollView = (ScrollView) mActivity.findViewById(R.id.scroll_view);
+        final ArrayList<FrameMetrics> data1 = new ArrayList<>();
+        final Handler handler = new Handler(Looper.getMainLooper());
+        final Window myWindow = mActivity.getWindow();
+
+        final Window.FrameMetricsListener frameMetricsListener1 =
+            new Window.FrameMetricsListener() {
+               @Override
+               public void onMetricsAvailable(Window window, FrameMetrics frameMetrics, int dropCount) {
+                   assertEquals(myWindow, window);
+                   assertEquals(0, dropCount);
+                   data1.add(new FrameMetrics(frameMetrics));
+               }
+            };
+        final ArrayList<FrameMetrics> data2 = new ArrayList<>();
+        final Window.FrameMetricsListener frameMetricsListener2 =
+            new Window.FrameMetricsListener() {
+               @Override
+               public void onMetricsAvailable(Window window, FrameMetrics frameMetrics, int dropCount) {
+                   assertEquals(myWindow, window);
+                   assertEquals(0, dropCount);
+                   data2.add(new FrameMetrics(frameMetrics));
+               }
+            };
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mActivity.getWindow().addFrameMetricsListener(frameMetricsListener1, handler);
+                mActivity.getWindow().addFrameMetricsListener(frameMetricsListener2, handler);
+            }
+        });
+
+        mInstrumentation.waitForIdleSync();
+
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                scrollView.fling(-100);
+            }
+        });
+
+        mInstrumentation.waitForIdleSync();
+        new PollingCheck() {
+            @Override
+            protected boolean check() {
+                return data1.size() != 0 && data1.size() == data2.size();
+            }
+        }.run();
+
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mActivity.getWindow().removeFrameMetricsListener(frameMetricsListener1);
+                mActivity.getWindow().removeFrameMetricsListener(frameMetricsListener2);
+            }
+        });
+    }
+
+    public void testDropCount() throws Throwable {
+        layout(R.layout.scrollview_layout);
+        final ScrollView scrollView = (ScrollView) mActivity.findViewById(R.id.scroll_view);
+
+        final Window window = mActivity.getWindow();
+        final AtomicInteger framesDropped = new AtomicInteger();
+        final AtomicInteger frameCount = new AtomicInteger();
+
+        final HandlerThread thread = new HandlerThread("Listener");
+        thread.start();
+        final Handler handler = new Handler(thread.getLooper());
+        final Window.FrameMetricsListener frameMetricsListener =
+            new Window.FrameMetricsListener() {
+               @Override
+               public void onMetricsAvailable(Window window, FrameMetrics frameMetrics, int dropCount) {
+                    try {
+                        Thread.sleep(100);
+                        framesDropped.addAndGet(dropCount);
+                    } catch (Exception e) { }
+               }
+            };
+
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mActivity.getWindow().addFrameMetricsListener(frameMetricsListener, handler);
+            }
+        });
+
+        mInstrumentation.waitForIdleSync();
+
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                scrollView.fling(-100);
+            }
+        });
+
+        mInstrumentation.waitForIdleSync();
+        new PollingCheck() {
+            @Override
+            protected boolean check() {
+                return framesDropped.get() > 0;
+            }
+        }.run();
+
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mActivity.getWindow().removeFrameMetricsListener(frameMetricsListener);
+            }
+        });
+    }
+}
+
+
diff --git a/tests/tests/view/src/android/view/cts/GestureDetectorTest.java b/tests/tests/view/src/android/view/cts/GestureDetectorTest.java
index f06455d..0493088 100644
--- a/tests/tests/view/src/android/view/cts/GestureDetectorTest.java
+++ b/tests/tests/view/src/android/view/cts/GestureDetectorTest.java
@@ -45,7 +45,7 @@
     private MotionEvent mButtonPressSecondaryMotionEvent;
 
     public GestureDetectorTest() {
-        super("com.android.cts.view", GestureDetectorCtsActivity.class);
+        super("android.view.cts", GestureDetectorCtsActivity.class);
     }
 
     @Override
diff --git a/tests/tests/view/src/android/view/cts/KeyboardShortcutGroupTest.java b/tests/tests/view/src/android/view/cts/KeyboardShortcutGroupTest.java
new file mode 100644
index 0000000..067f0bb
--- /dev/null
+++ b/tests/tests/view/src/android/view/cts/KeyboardShortcutGroupTest.java
@@ -0,0 +1,97 @@
+package android.view.cts;
+
+import android.os.Parcel;
+import android.test.InstrumentationTestCase;
+import android.view.KeyEvent;
+import android.view.KeyboardShortcutGroup;
+import android.view.KeyboardShortcutInfo;
+
+import com.google.android.collect.Lists;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Tests for {@link android.view.KeyboardShortcutGroup}.
+ */
+public class KeyboardShortcutGroupTest extends InstrumentationTestCase {
+    private static final CharSequence TEST_LABEL = "Test Group Label";
+    private final List<KeyboardShortcutInfo> TEST_ITEMS = Lists.newArrayList(
+            new KeyboardShortcutInfo("Item 1", KeyEvent.KEYCODE_U, KeyEvent.META_CTRL_ON),
+            new KeyboardShortcutInfo("Item 2", KeyEvent.KEYCODE_F, KeyEvent.META_CTRL_ON));
+
+    public void testConstructor() {
+        KeyboardShortcutGroup group = new KeyboardShortcutGroup(TEST_LABEL, TEST_ITEMS);
+
+        assertEquals(TEST_LABEL, group.getLabel());
+        assertEquals(TEST_ITEMS, group.getItems());
+        assertFalse(group.isSystemGroup());
+        assertEquals(0, group.describeContents());
+    }
+
+    public void testShortConstructor() {
+        KeyboardShortcutGroup group = new KeyboardShortcutGroup(TEST_LABEL);
+
+        assertEquals(TEST_LABEL, group.getLabel());
+        assertNotNull(group.getItems());
+        assertFalse(group.isSystemGroup());
+        assertEquals(0, group.describeContents());
+    }
+
+    public void testSystemConstructor() {
+        KeyboardShortcutGroup group = new KeyboardShortcutGroup(TEST_LABEL, TEST_ITEMS, true);
+
+        assertEquals(TEST_LABEL, group.getLabel());
+        assertEquals(TEST_ITEMS, group.getItems());
+        assertTrue(group.isSystemGroup());
+        assertEquals(0, group.describeContents());
+    }
+
+    public void testSystemShortConstructor() {
+        KeyboardShortcutGroup group = new KeyboardShortcutGroup(TEST_LABEL, true);
+
+        assertEquals(TEST_LABEL, group.getLabel());
+        assertNotNull(group.getItems());
+        assertTrue(group.isSystemGroup());
+        assertEquals(0, group.describeContents());
+    }
+
+    public void testConstructorChecksList() {
+        try {
+            KeyboardShortcutGroup group = new KeyboardShortcutGroup(TEST_LABEL, null);
+        } catch (NullPointerException expected) {
+            return;
+        }
+        fail();
+    }
+
+    public void testAddItem() {
+        KeyboardShortcutGroup group = new KeyboardShortcutGroup(TEST_LABEL, TEST_ITEMS);
+
+        group.addItem(new KeyboardShortcutInfo(
+                "Additional item", KeyEvent.KEYCODE_P, KeyEvent.META_CTRL_ON));
+
+        final int newSize = group.getItems().size();
+        assertEquals(TEST_ITEMS.size() + 1, newSize);
+        assertEquals("Additional item", group.getItems().get(newSize - 1).getLabel());
+    }
+
+    public void testWriteToParcelAndRead() {
+        Parcel dest = Parcel.obtain();
+        KeyboardShortcutGroup group = new KeyboardShortcutGroup(TEST_LABEL, TEST_ITEMS, true);
+        group.writeToParcel(dest, 0);
+
+        dest.setDataPosition(0);
+        KeyboardShortcutGroup result = KeyboardShortcutGroup.CREATOR.createFromParcel(dest);
+
+        assertEquals(TEST_LABEL, result.getLabel());
+        assertEquals(TEST_ITEMS.size(), result.getItems().size());
+        assertEquals(TEST_ITEMS.get(0).getLabel(), result.getItems().get(0).getLabel());
+        assertEquals(TEST_ITEMS.get(1).getLabel(), result.getItems().get(1).getLabel());
+        assertEquals(TEST_ITEMS.get(0).getKeycode(), result.getItems().get(0).getKeycode());
+        assertEquals(TEST_ITEMS.get(1).getKeycode(), result.getItems().get(1).getKeycode());
+        assertEquals(TEST_ITEMS.get(0).getModifiers(), result.getItems().get(0).getModifiers());
+        assertEquals(TEST_ITEMS.get(1).getModifiers(), result.getItems().get(1).getModifiers());
+        assertTrue(result.isSystemGroup());
+    }
+}
diff --git a/tests/tests/view/src/android/view/cts/KeyboardShortcutInfoTest.java b/tests/tests/view/src/android/view/cts/KeyboardShortcutInfoTest.java
new file mode 100644
index 0000000..76dc43f
--- /dev/null
+++ b/tests/tests/view/src/android/view/cts/KeyboardShortcutInfoTest.java
@@ -0,0 +1,89 @@
+package android.view.cts;
+
+import android.graphics.drawable.Icon;
+import android.os.Parcel;
+import android.test.InstrumentationTestCase;
+import android.view.KeyEvent;
+import android.view.KeyboardShortcutInfo;
+
+/**
+ * Tests for {@link android.view.KeyboardShortcutInfo}.
+ */
+public class KeyboardShortcutInfoTest extends InstrumentationTestCase {
+    private static final CharSequence TEST_LABEL = "Test Label";
+    private static final char TEST_BASE_CHARACTER = 't';
+    private static final int TEST_KEYCODE = KeyEvent.KEYCODE_T;
+    private static final int TEST_MODIFIERS = KeyEvent.META_ALT_ON | KeyEvent.META_CTRL_ON;
+
+    public void testCharacterConstructor() {
+        KeyboardShortcutInfo info = new KeyboardShortcutInfo(
+                TEST_LABEL, TEST_BASE_CHARACTER, TEST_MODIFIERS);
+        assertNotNull(info);
+        assertEquals(TEST_LABEL, info.getLabel());
+        assertEquals(TEST_BASE_CHARACTER, info.getBaseCharacter());
+        assertEquals(KeyEvent.KEYCODE_UNKNOWN, info.getKeycode());
+        assertEquals(TEST_MODIFIERS, info.getModifiers());
+        assertEquals(0, info.describeContents());
+    }
+
+    public void testKeycodeConstructor() {
+        KeyboardShortcutInfo info = new KeyboardShortcutInfo(
+                TEST_LABEL, TEST_KEYCODE, TEST_MODIFIERS);
+        assertNotNull(info);
+        assertEquals(TEST_LABEL, info.getLabel());
+        assertEquals(Character.MIN_VALUE, info.getBaseCharacter());
+        assertEquals(TEST_KEYCODE, info.getKeycode());
+        assertEquals(TEST_MODIFIERS, info.getModifiers());
+        assertEquals(0, info.describeContents());
+    }
+
+    public void testConstructorChecksBaseCharacter() {
+        try {
+            KeyboardShortcutInfo info = new KeyboardShortcutInfo(
+                    TEST_LABEL, Character.MIN_VALUE, TEST_MODIFIERS);
+        } catch (IllegalArgumentException expected) {
+            return;
+        }
+        fail();
+    }
+
+    public void testConstructorChecksKeycode() {
+        try {
+            KeyboardShortcutInfo info = new KeyboardShortcutInfo(
+                    TEST_LABEL, KeyEvent.KEYCODE_UNKNOWN - 1, TEST_MODIFIERS);
+        } catch (IllegalArgumentException expected) {
+            return;
+        }
+        fail();
+    }
+
+    public void testWriteToParcelAndReadCharacter() {
+        Parcel dest = Parcel.obtain();
+        KeyboardShortcutInfo info = new KeyboardShortcutInfo(
+                TEST_LABEL, TEST_BASE_CHARACTER, TEST_MODIFIERS);
+        info.writeToParcel(dest, 0);
+
+        dest.setDataPosition(0);
+        KeyboardShortcutInfo result = KeyboardShortcutInfo.CREATOR.createFromParcel(dest);
+
+        assertEquals(TEST_LABEL, result.getLabel());
+        assertEquals(TEST_BASE_CHARACTER, result.getBaseCharacter());
+        assertEquals(KeyEvent.KEYCODE_UNKNOWN, result.getKeycode());
+        assertEquals(TEST_MODIFIERS, result.getModifiers());
+    }
+
+    public void testWriteToParcelAndReadKeycode() {
+        Parcel dest = Parcel.obtain();
+        KeyboardShortcutInfo info = new KeyboardShortcutInfo(
+                TEST_LABEL, TEST_KEYCODE, TEST_MODIFIERS);
+        info.writeToParcel(dest, 0);
+
+        dest.setDataPosition(0);
+        KeyboardShortcutInfo result = KeyboardShortcutInfo.CREATOR.createFromParcel(dest);
+
+        assertEquals(TEST_LABEL, result.getLabel());
+        assertEquals(Character.MIN_VALUE, result.getBaseCharacter());
+        assertEquals(TEST_KEYCODE, result.getKeycode());
+        assertEquals(TEST_MODIFIERS, result.getModifiers());
+    }
+}
diff --git a/tests/tests/view/src/android/view/cts/LayoutInflaterTest.java b/tests/tests/view/src/android/view/cts/LayoutInflaterTest.java
index 00b9fe9..9208b13 100644
--- a/tests/tests/view/src/android/view/cts/LayoutInflaterTest.java
+++ b/tests/tests/view/src/android/view/cts/LayoutInflaterTest.java
@@ -16,7 +16,7 @@
 
 package android.view.cts;
 
-import com.android.cts.view.R;
+import android.view.cts.R;
 import android.view.cts.util.XmlUtils;
 
 import org.xmlpull.v1.XmlPullParser;
@@ -210,7 +210,7 @@
 
     public void testInflate() {
         View view = mLayoutInflater.inflate(
-                com.android.cts.view.R.layout.inflater_layout, null);
+                android.view.cts.R.layout.inflater_layout, null);
         assertNotNull(view);
         view = null;
         try {
@@ -385,7 +385,7 @@
 
     public void testInflateTags() {
         final View view = mLayoutInflater.inflate(
-                com.android.cts.view.R.layout.inflater_layout_tags, null);
+                android.view.cts.R.layout.inflater_layout_tags, null);
         assertNotNull(view);
 
         checkViewTag(view, R.id.viewlayout_root, R.id.tag_viewlayout_root, R.string.tag1);
diff --git a/tests/tests/view/src/android/view/cts/MenuInflaterTest.java b/tests/tests/view/src/android/view/cts/MenuInflaterTest.java
index 7e3517f..9ced9c7 100644
--- a/tests/tests/view/src/android/view/cts/MenuInflaterTest.java
+++ b/tests/tests/view/src/android/view/cts/MenuInflaterTest.java
@@ -16,7 +16,7 @@
 
 package android.view.cts;
 
-import com.android.cts.view.R;
+import android.view.cts.R;
 
 import android.app.Activity;
 import android.content.res.Resources;
@@ -40,7 +40,7 @@
     private Activity mActivity;
 
     public MenuInflaterTest() {
-        super("com.android.cts.view", MenuInflaterCtsActivity.class);
+        super("android.view.cts", MenuInflaterCtsActivity.class);
     }
 
     @Override
@@ -67,7 +67,7 @@
             mMenuInflater = mActivity.getMenuInflater();
         }
 
-        mMenuInflater.inflate(com.android.cts.view.R.menu.browser, menu);
+        mMenuInflater.inflate(android.view.cts.R.menu.browser, menu);
         assertNotNull(menu);
         assertEquals(1, menu.size());
 
@@ -78,7 +78,7 @@
         }
 
         try {
-            mMenuInflater.inflate(com.android.cts.view.R.menu.browser, null);
+            mMenuInflater.inflate(android.view.cts.R.menu.browser, null);
             fail("should throw NullPointerException");
         } catch (NullPointerException e) {
         }
@@ -107,7 +107,7 @@
 
         // the titles and icons
         menu = createMenu(mActivity);
-        mMenuInflater.inflate(com.android.cts.view.R.menu.title_icon, menu);
+        mMenuInflater.inflate(android.view.cts.R.menu.title_icon, menu);
 
         assertEquals("Start", menu.findItem(R.id.start).getTitle());
         assertIconUsingDrawableRes((BitmapDrawable) menu.findItem(R.id.start).getIcon(),
@@ -123,7 +123,7 @@
 
         // the orders and categories
         menu = createMenu(mActivity);
-        mMenuInflater.inflate(com.android.cts.view.R.menu.category_order, menu);
+        mMenuInflater.inflate(android.view.cts.R.menu.category_order, menu);
         // default category
         assertEquals(R.id.most_used_items, menu.findItem(R.id.first_most_item).getGroupId());
         assertEquals(1, menu.findItem(R.id.first_most_item).getOrder());
@@ -147,7 +147,7 @@
 
         // the checkables
         menu = createMenu(mActivity);
-        mMenuInflater.inflate(com.android.cts.view.R.menu.checkable, menu);
+        mMenuInflater.inflate(android.view.cts.R.menu.checkable, menu);
         // noncheckables
         assertEquals(R.id.noncheckable_group,
                 menu.findItem(R.id.noncheckable_item_1).getGroupId());
diff --git a/tests/tests/view/src/android/view/cts/MockView.java b/tests/tests/view/src/android/view/cts/MockView.java
index 579d4fb..3e140c2 100644
--- a/tests/tests/view/src/android/view/cts/MockView.java
+++ b/tests/tests/view/src/android/view/cts/MockView.java
@@ -17,7 +17,6 @@
 package android.view.cts;
 
 import android.content.Context;
-import android.content.res.TypedArray;
 import android.graphics.Canvas;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
@@ -28,9 +27,9 @@
 import android.view.ContextMenu;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
+import android.view.PointerIcon;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.ViewParent;
 import android.view.ContextMenu.ContextMenuInfo;
 
 public class MockView extends View {
@@ -55,6 +54,7 @@
     private boolean mCalledOnSetAlpha = false;
     private boolean mCalledOnTouchEvent = false;
     private boolean mCalledOnTrackballEvent = false;
+    private boolean mCalledOnHoverEvent = false;
     private boolean mCalledOnWindowFocusChanged = false;
     private boolean mCalledDispatchRestoreInstanceState = false;
     private boolean mCalledDispatchSaveInstanceState = false;
@@ -69,10 +69,14 @@
     private boolean mCalledComputeScroll = false;
     private boolean mCalledDispatchKeyEventPreIme = false;
     private boolean mCalledOnKeyPreIme = false;
+    private boolean mCalledGetPointerIcon = false;
+    private boolean mCalledOnVisibilityAggregated = false;
 
     private int mOldWidth = -1;
     private int mOldHeight = -1;
 
+    private boolean mLastAggregatedVisibility;
+
     public MockView(Context context) {
         super(context);
     }
@@ -209,6 +213,12 @@
         return super.onTrackballEvent(event);
     }
 
+    @Override
+    public boolean onHoverEvent(MotionEvent event) {
+        mCalledOnHoverEvent = true;
+        return super.onHoverEvent(event);
+    }
+
     public boolean hasCalledOnTouchEvent() {
         return mCalledOnTouchEvent;
     }
@@ -217,6 +227,10 @@
         return mCalledOnTrackballEvent;
     }
 
+    public boolean hasCalledOnHoverEvent() {
+        return mCalledOnHoverEvent;
+    }
+
     @Override
     protected int getSuggestedMinimumHeight() {
         return super.getSuggestedMinimumHeight();
@@ -595,6 +609,31 @@
         return mCalledOnKeyPreIme;
     }
 
+    @Override
+    public PointerIcon getPointerIcon(MotionEvent event, float x, float y) {
+        mCalledGetPointerIcon = true;
+        return super.getPointerIcon(event, x, y);
+    }
+
+    public boolean hasCalledGetPointerIcon() {
+        return mCalledGetPointerIcon;
+    }
+
+    @Override
+    public void onVisibilityAggregated(boolean isVisible) {
+        super.onVisibilityAggregated(isVisible);
+        mCalledOnVisibilityAggregated = true;
+        mLastAggregatedVisibility = isVisible;
+    }
+
+    public boolean hasCalledOnVisibilityAggregated() {
+        return mCalledOnVisibilityAggregated;
+    }
+
+    public boolean getLastAggregatedVisibility() {
+        return mLastAggregatedVisibility;
+    }
+
     public void reset() {
         mCalledOnCreateContextMenu = false;
 
@@ -618,6 +657,7 @@
         mCalledOnSetAlpha = false;
         mCalledOnTouchEvent = false;
         mCalledOnTrackballEvent = false;
+        mCalledOnHoverEvent = false;
         mCalledOnWindowFocusChanged = false;
         mCalledDispatchRestoreInstanceState = false;
         mCalledDispatchSaveInstanceState = false;
@@ -632,8 +672,11 @@
         mCalledComputeScroll = false;
         mCalledDispatchKeyEventPreIme = false;
         mCalledOnKeyPreIme = false;
+        mCalledGetPointerIcon = false;
+        mCalledOnVisibilityAggregated = false;
 
         mOldWidth = -1;
         mOldHeight = -1;
+        mLastAggregatedVisibility = false;
     }
 }
diff --git a/tests/tests/view/src/android/view/cts/ScaleGestureDetectorTest.java b/tests/tests/view/src/android/view/cts/ScaleGestureDetectorTest.java
index b8ba200..b56d67e 100644
--- a/tests/tests/view/src/android/view/cts/ScaleGestureDetectorTest.java
+++ b/tests/tests/view/src/android/view/cts/ScaleGestureDetectorTest.java
@@ -32,7 +32,7 @@
     private Context mContext;
 
     public ScaleGestureDetectorTest() {
-        super("com.android.cts.view", ScaleGestureDetectorCtsActivity.class);
+        super("android.view.cts", ScaleGestureDetectorCtsActivity.class);
     }
 
     @Override
diff --git a/tests/tests/view/src/android/view/cts/SearchEventActivity.java b/tests/tests/view/src/android/view/cts/SearchEventActivity.java
index 6cc8c85..292ecb9 100644
--- a/tests/tests/view/src/android/view/cts/SearchEventActivity.java
+++ b/tests/tests/view/src/android/view/cts/SearchEventActivity.java
@@ -16,7 +16,7 @@
 
 package android.view.cts;
 
-import com.android.cts.view.R;
+import android.view.cts.R;
 
 import android.app.Activity;
 import android.os.Bundle;
diff --git a/tests/tests/view/src/android/view/cts/SearchEventTest.java b/tests/tests/view/src/android/view/cts/SearchEventTest.java
index 4df52a1..629b3ab 100644
--- a/tests/tests/view/src/android/view/cts/SearchEventTest.java
+++ b/tests/tests/view/src/android/view/cts/SearchEventTest.java
@@ -16,7 +16,7 @@
 
 package android.view.cts;
 
-import com.android.cts.view.R;
+import android.view.cts.R;
 
 import android.app.Instrumentation;
 import android.test.ActivityInstrumentationTestCase2;
diff --git a/tests/tests/view/src/android/view/cts/SurfaceViewTest.java b/tests/tests/view/src/android/view/cts/SurfaceViewTest.java
index a84653d..aa97ffd 100644
--- a/tests/tests/view/src/android/view/cts/SurfaceViewTest.java
+++ b/tests/tests/view/src/android/view/cts/SurfaceViewTest.java
@@ -37,7 +37,7 @@
     private MockSurfaceView mMockSurfaceView;
 
     public SurfaceViewTest() {
-        super("com.android.cts.view", SurfaceViewCtsActivity.class);
+        super("android.view.cts", SurfaceViewCtsActivity.class);
     }
 
     @Override
diff --git a/tests/tests/view/src/android/view/cts/TextureViewCtsActivity.java b/tests/tests/view/src/android/view/cts/TextureViewCtsActivity.java
new file mode 100644
index 0000000..029e308
--- /dev/null
+++ b/tests/tests/view/src/android/view/cts/TextureViewCtsActivity.java
@@ -0,0 +1,274 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.view.cts;
+
+import static android.opengl.GLES20.GL_COLOR_BUFFER_BIT;
+import static android.opengl.GLES20.glClear;
+import static android.opengl.GLES20.glClearColor;
+
+import android.app.Activity;
+import android.graphics.Color;
+import android.graphics.SurfaceTexture;
+import android.opengl.GLUtils;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.view.TextureView;
+import android.view.TextureView.SurfaceTextureListener;
+import android.view.View;
+import android.view.ViewGroup.LayoutParams;
+import android.widget.FrameLayout;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import javax.microedition.khronos.egl.EGL10;
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.egl.EGLContext;
+import javax.microedition.khronos.egl.EGLDisplay;
+import javax.microedition.khronos.egl.EGLSurface;
+
+public class TextureViewCtsActivity extends Activity implements SurfaceTextureListener {
+    private final static long TIME_OUT_MS = 10000;
+    private Object mLock = new Object();
+
+    private View mPreview;
+    private TextureView mTextureView;
+    private HandlerThread mGLThreadLooper;
+    private Handler mGLThread;
+
+    private SurfaceTexture mSurface;
+    private int mSurfaceUpdatedCount;
+
+    static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
+    static final int EGL_OPENGL_ES2_BIT = 4;
+
+    private EGL10 mEgl;
+    private EGLDisplay mEglDisplay;
+    private EGLConfig mEglConfig;
+    private EGLContext mEglContext;
+    private EGLSurface mEglSurface;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        if (mGLThreadLooper == null) {
+            mGLThreadLooper = new HandlerThread("GLThread");
+            mGLThreadLooper.start();
+            mGLThread = new Handler(mGLThreadLooper.getLooper());
+        }
+
+        View preview = new View(this);
+        preview.setBackgroundColor(Color.WHITE);
+        mPreview = preview;
+        mTextureView = new TextureView(this);
+        mTextureView.setSurfaceTextureListener(this);
+
+        FrameLayout content = new FrameLayout(this);
+        content.setBackgroundColor(Color.BLACK);
+        content.addView(mTextureView,
+                LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
+        content.addView(mPreview,
+                LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
+
+        setContentView(content);
+    }
+
+    private class RunSignalAndCatch implements Runnable {
+        public Throwable error;
+        private Runnable mRunnable;
+        private CountDownLatch mFence;
+
+        RunSignalAndCatch(Runnable run, CountDownLatch fence) {
+            mRunnable = run;
+            mFence = fence;
+        }
+
+        @Override
+        public void run() {
+            try {
+                mRunnable.run();
+            } catch (Throwable t) {
+                error = t;
+            } finally {
+                mFence.countDown();
+            }
+        }
+    }
+
+    private void runOnGLThread(Runnable r) throws Throwable {
+        CountDownLatch fence = new CountDownLatch(1);
+        RunSignalAndCatch wrapper = new RunSignalAndCatch(r, fence);
+        mGLThread.post(wrapper);
+        fence.await(TIME_OUT_MS, TimeUnit.MILLISECONDS);
+        if (wrapper.error != null) {
+            throw wrapper.error;
+        }
+    }
+
+    public void waitForSurface() throws InterruptedException {
+        synchronized (mLock) {
+            while (mSurface == null) {
+                mLock.wait(TIME_OUT_MS);
+            }
+        }
+    }
+
+    public void initGl() throws Throwable {
+        if (mEglSurface != null) return;
+        runOnGLThread(mDoInitGL);
+    }
+
+    public void drawColor(int color) throws Throwable {
+        runOnGLThread(() -> {
+            glClearColor(Color.red(color) / 255.0f,
+                    Color.green(color) / 255.0f,
+                    Color.blue(color) / 255.0f,
+                    Color.alpha(color) / 255.0f);
+            glClear(GL_COLOR_BUFFER_BIT);
+            if (!mEgl.eglSwapBuffers(mEglDisplay, mEglSurface)) {
+                throw new RuntimeException("Cannot swap buffers");
+            }
+        });
+    }
+
+    public void finishGL() throws Throwable {
+        if (mEglSurface == null) return;
+        runOnGLThread(() -> doFinishGL());
+    }
+
+    public int waitForSurfaceUpdateCount(int updateCount) throws InterruptedException {
+        synchronized (mLock) {
+            while (updateCount > mSurfaceUpdatedCount) {
+                mLock.wait(TIME_OUT_MS);
+            }
+            return mSurfaceUpdatedCount;
+        }
+    }
+
+    public void removeCover() {
+        mPreview.setVisibility(View.GONE);
+    }
+
+    private void doFinishGL() {
+        mEgl.eglDestroyContext(mEglDisplay, mEglContext);
+        mEglContext = null;
+        mEgl.eglDestroySurface(mEglDisplay, mEglSurface);
+        mEglSurface = null;
+        mEgl.eglTerminate(mEglDisplay);
+    }
+
+    @Override
+    public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
+        synchronized (mLock) {
+            mSurface = surface;
+            mLock.notifyAll();
+        }
+    }
+
+    @Override
+    public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
+    }
+
+    @Override
+    public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
+        synchronized (mLock) {
+            mSurface = null;
+            mLock.notifyAll();
+        }
+        return true;
+    }
+
+    @Override
+    public void onSurfaceTextureUpdated(SurfaceTexture surface) {
+        synchronized (mLock) {
+            mSurfaceUpdatedCount++;
+            mLock.notifyAll();
+        }
+    }
+
+    private Runnable mDoInitGL = new Runnable() {
+        @Override
+        public void run() {
+            mEgl = (EGL10) EGLContext.getEGL();
+
+            mEglDisplay = mEgl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
+            if (mEglDisplay == EGL10.EGL_NO_DISPLAY) {
+                throw new RuntimeException("eglGetDisplay failed "
+                        + GLUtils.getEGLErrorString(mEgl.eglGetError()));
+            }
+
+            int[] version = new int[2];
+            if (!mEgl.eglInitialize(mEglDisplay, version)) {
+                throw new RuntimeException("eglInitialize failed " +
+                        GLUtils.getEGLErrorString(mEgl.eglGetError()));
+            }
+
+            mEglConfig = chooseEglConfig();
+            if (mEglConfig == null) {
+                throw new RuntimeException("eglConfig not initialized");
+            }
+
+            mEglContext = createContext(mEgl, mEglDisplay, mEglConfig);
+
+            mEglSurface = mEgl.eglCreateWindowSurface(mEglDisplay, mEglConfig,
+                    mSurface, null);
+
+            if (mEglSurface == null || mEglSurface == EGL10.EGL_NO_SURFACE) {
+                int error = mEgl.eglGetError();
+                throw new RuntimeException("createWindowSurface failed "
+                        + GLUtils.getEGLErrorString(error));
+            }
+
+            if (!mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
+                throw new RuntimeException("eglMakeCurrent failed "
+                        + GLUtils.getEGLErrorString(mEgl.eglGetError()));
+            }
+        }
+    };
+
+    EGLContext createContext(EGL10 egl, EGLDisplay eglDisplay, EGLConfig eglConfig) {
+        int[] attrib_list = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE };
+        return egl.eglCreateContext(eglDisplay, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list);
+    }
+
+    private EGLConfig chooseEglConfig() {
+        int[] configsCount = new int[1];
+        EGLConfig[] configs = new EGLConfig[1];
+        int[] configSpec = getConfig();
+        if (!mEgl.eglChooseConfig(mEglDisplay, configSpec, configs, 1, configsCount)) {
+            throw new IllegalArgumentException("eglChooseConfig failed " +
+                    GLUtils.getEGLErrorString(mEgl.eglGetError()));
+        } else if (configsCount[0] > 0) {
+            return configs[0];
+        }
+        return null;
+    }
+
+    private int[] getConfig() {
+        return new int[] {
+                EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+                EGL10.EGL_RED_SIZE, 8,
+                EGL10.EGL_GREEN_SIZE, 8,
+                EGL10.EGL_BLUE_SIZE, 8,
+                EGL10.EGL_ALPHA_SIZE, 8,
+                EGL10.EGL_DEPTH_SIZE, 0,
+                EGL10.EGL_STENCIL_SIZE, 0,
+                EGL10.EGL_NONE
+        };
+    }
+}
diff --git a/tests/tests/view/src/android/view/cts/TextureViewTest.java b/tests/tests/view/src/android/view/cts/TextureViewTest.java
new file mode 100644
index 0000000..12c689f
--- /dev/null
+++ b/tests/tests/view/src/android/view/cts/TextureViewTest.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.view.cts;
+
+import android.app.Instrumentation;
+import android.graphics.Bitmap;
+import android.graphics.Color;
+import android.graphics.Point;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.MediumTest;
+import android.support.test.rule.ActivityTestRule;
+import android.view.View;
+import android.view.cts.util.ViewTestUtils;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+import java.util.concurrent.TimeoutException;
+
+@MediumTest
+public class TextureViewTest {
+
+    @Rule
+    public ActivityTestRule<TextureViewCtsActivity> mActivityRule = new ActivityTestRule<>(
+            TextureViewCtsActivity.class);
+
+    private TextureViewCtsActivity mActivity;
+    private Instrumentation mInstrumentation;
+
+    @Before
+    public void setUp() throws Exception {
+        mActivity = mActivityRule.getActivity();
+        mInstrumentation = InstrumentationRegistry.getInstrumentation();
+        assertNotNull(mActivity);
+        assertNotNull(mInstrumentation);
+    }
+
+    @Test
+    public void testFirstFrames() throws Throwable {
+        final Point center = new Point();
+        mInstrumentation.waitForIdleSync();
+        mInstrumentation.runOnMainSync(() -> {
+            View content = mActivity.findViewById(android.R.id.content);
+            int[] outLocation = new int[2];
+            content.getLocationOnScreen(outLocation);
+            center.x = outLocation[0] + (content.getWidth() / 2);
+            center.y = outLocation[1] + (content.getHeight() / 2);
+        });
+        assertTrue(center.x > 0);
+        assertTrue(center.y > 0);
+        waitForColor(center, Color.WHITE);
+        mActivity.waitForSurface();
+        mActivity.initGl();
+        int updatedCount;
+        updatedCount = mActivity.waitForSurfaceUpdateCount(0);
+        assertEquals(0, updatedCount);
+        mActivity.drawColor(Color.GREEN);
+        updatedCount = mActivity.waitForSurfaceUpdateCount(1);
+        assertEquals(1, updatedCount);
+        assertEquals(Color.WHITE, getPixel(center));
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mActivity,
+                () -> mActivity.removeCover());
+
+        int color;
+        color = waitForChange(center, Color.WHITE);
+        assertEquals(Color.GREEN, color);
+        mActivity.drawColor(Color.BLUE);
+        updatedCount = mActivity.waitForSurfaceUpdateCount(2);
+        assertEquals(2, updatedCount);
+        color = waitForChange(center, color);
+        assertEquals(Color.BLUE, color);
+    }
+
+    private int getPixel(Point point) {
+        Bitmap screenshot = mInstrumentation.getUiAutomation().takeScreenshot();
+        int pixel = screenshot.getPixel(point.x, point.y);
+        screenshot.recycle();
+        return pixel;
+    }
+
+    private void waitForColor(Point point, int color)
+            throws InterruptedException, TimeoutException {
+        for (int i = 0; i < 20; i++) {
+            int pixel = getPixel(point);
+            if (pixel == color) {
+                return;
+            }
+            Thread.sleep(16);
+        }
+        throw new TimeoutException();
+    }
+
+    private int waitForChange(Point point, int color)
+            throws InterruptedException, TimeoutException {
+        for (int i = 0; i < 20; i++) {
+            int pixel = getPixel(point);
+            if (pixel != color) {
+                return pixel;
+            }
+            Thread.sleep(16);
+        }
+        throw new TimeoutException();
+    }
+}
\ No newline at end of file
diff --git a/tests/tests/view/src/android/view/cts/TouchDelegateTest.java b/tests/tests/view/src/android/view/cts/TouchDelegateTest.java
index 34d96bc..47fe6c6 100644
--- a/tests/tests/view/src/android/view/cts/TouchDelegateTest.java
+++ b/tests/tests/view/src/android/view/cts/TouchDelegateTest.java
@@ -44,7 +44,7 @@
     private Exception mException;
 
     public TouchDelegateTest() {
-        super("com.android.cts.view", MockActivity.class);
+        super("android.view.cts", MockActivity.class);
     }
 
     @Override
diff --git a/tests/tests/view/src/android/view/cts/UsingViewsCtsActivity.java b/tests/tests/view/src/android/view/cts/UsingViewsCtsActivity.java
index a5ccbcd..a9361a3 100644
--- a/tests/tests/view/src/android/view/cts/UsingViewsCtsActivity.java
+++ b/tests/tests/view/src/android/view/cts/UsingViewsCtsActivity.java
@@ -18,7 +18,7 @@
 
 import android.app.Activity;
 import android.os.Bundle;
-import com.android.cts.view.R;
+import android.view.cts.R;
 
 /**
  * A simple activity to test "Using Views"
diff --git a/tests/tests/view/src/android/view/cts/ViewGroupCtsActivity.java b/tests/tests/view/src/android/view/cts/ViewGroupCtsActivity.java
index 880a450..de1db19 100644
--- a/tests/tests/view/src/android/view/cts/ViewGroupCtsActivity.java
+++ b/tests/tests/view/src/android/view/cts/ViewGroupCtsActivity.java
@@ -35,8 +35,8 @@
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-        setContentView(com.android.cts.view.R.layout.viewgrouptest_stub);
-        TextView textView = (TextView)findViewById(com.android.cts.view.R.id.viewgrouptest_stub);
+        setContentView(android.view.cts.R.layout.viewgrouptest_stub);
+        TextView textView = (TextView)findViewById(android.view.cts.R.id.viewgrouptest_stub);
         textView.setText("test");
     }
 
@@ -49,7 +49,7 @@
             mHandler.postDelayed(new Runnable() {
                 public void run() {
                     MockLinearLayout mll =
-                        (MockLinearLayout) findViewById(com.android.cts.view.R.id.
+                        (MockLinearLayout) findViewById(android.view.cts.R.id.
                                                                         mocklinearlayout);
                     if (!mll.mIsInvalidateChildInParentCalled) {
                         fail();
diff --git a/tests/tests/view/src/android/view/cts/ViewGroupOverlayCtsActivity.java b/tests/tests/view/src/android/view/cts/ViewGroupOverlayCtsActivity.java
new file mode 100644
index 0000000..9913692
--- /dev/null
+++ b/tests/tests/view/src/android/view/cts/ViewGroupOverlayCtsActivity.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.view.cts;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class ViewGroupOverlayCtsActivity extends Activity {
+    @Override
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        setContentView(R.layout.viewgroupoverlay_layout);
+    }
+}
diff --git a/tests/tests/view/src/android/view/cts/ViewGroupOverlayTest.java b/tests/tests/view/src/android/view/cts/ViewGroupOverlayTest.java
new file mode 100644
index 0000000..886cc81
--- /dev/null
+++ b/tests/tests/view/src/android/view/cts/ViewGroupOverlayTest.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.view.cts;
+
+import android.app.Instrumentation;
+import android.content.Context;
+import android.graphics.Color;
+import android.graphics.Rect;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
+import android.os.SystemClock;
+import android.platform.test.annotations.Presubmit;
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.util.Pair;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewGroupOverlay;
+import android.view.cts.util.DrawingUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.mockito.Mockito.*;
+
+@SmallTest
+public class ViewGroupOverlayTest extends
+        ActivityInstrumentationTestCase2<ViewGroupOverlayCtsActivity> {
+    private ViewGroup mViewGroupWithOverlay;
+    private ViewGroupOverlay mViewGroupOverlay;
+    private Context mContext;
+
+    public ViewGroupOverlayTest() {
+        super("android.view.cts", ViewGroupOverlayCtsActivity.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        mViewGroupWithOverlay = (ViewGroup) getActivity().findViewById(R.id.viewgroup_with_overlay);
+        mViewGroupOverlay = mViewGroupWithOverlay.getOverlay();
+        mContext = getInstrumentation().getTargetContext();
+    }
+
+    @Presubmit
+    public void testBasics() {
+        DrawingUtils.assertAllPixelsOfColor("Default fill", mViewGroupWithOverlay,
+                Color.WHITE, null);
+        assertNotNull("Overlay is not null", mViewGroupOverlay);
+    }
+
+    public void testAddNullView() throws Throwable {
+        try {
+            runTestOnUiThread(() -> mViewGroupOverlay.add((View) null));
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+        }
+    }
+
+    public void testRemoveNullView() throws Throwable {
+        try {
+            runTestOnUiThread(() -> mViewGroupOverlay.remove((View) null));
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+        }
+    }
+
+    public void testOverlayWithOneView() throws Throwable {
+        // Add one colored view to the overlay
+        final View redView = new View(mContext);
+        redView.setBackgroundColor(Color.RED);
+        redView.layout(10, 20, 30, 40);
+
+        runTestOnUiThread(() -> mViewGroupOverlay.add(redView));
+
+        final List<Pair<Rect, Integer>> colorRectangles = new ArrayList<>();
+        colorRectangles.add(new Pair<>(new Rect(10, 20, 30, 40), Color.RED));
+        DrawingUtils.assertAllPixelsOfColor("Overlay with one red view",
+                mViewGroupWithOverlay, Color.WHITE, colorRectangles);
+
+        // Now remove that view from the overlay and test that we're back to pure white fill
+        runTestOnUiThread(() -> mViewGroupOverlay.remove(redView));
+        DrawingUtils.assertAllPixelsOfColor("Back to default fill", mViewGroupWithOverlay,
+                Color.WHITE, null);
+    }
+
+    public void testOverlayWithNonOverlappingViews() throws Throwable {
+        // Add three views to the overlay
+        final View redView = new View(mContext);
+        redView.setBackgroundColor(Color.RED);
+        redView.layout(10, 20, 30, 40);
+        final View greenView = new View(mContext);
+        greenView.setBackgroundColor(Color.GREEN);
+        greenView.layout(60, 30, 90, 50);
+        final View blueView = new View(mContext);
+        blueView.setBackgroundColor(Color.BLUE);
+        blueView.layout(40, 60, 80, 90);
+
+        runTestOnUiThread(
+                () -> {
+                    mViewGroupOverlay.add(redView);
+                    mViewGroupOverlay.add(greenView);
+                    mViewGroupOverlay.add(blueView);
+                });
+
+        final List<Pair<Rect, Integer>> colorRectangles = new ArrayList<>();
+        colorRectangles.add(new Pair<>(new Rect(10, 20, 30, 40), Color.RED));
+        colorRectangles.add(new Pair<>(new Rect(60, 30, 90, 50), Color.GREEN));
+        colorRectangles.add(new Pair<>(new Rect(40, 60, 80, 90), Color.BLUE));
+        DrawingUtils.assertAllPixelsOfColor("Overlay with three views", mViewGroupWithOverlay,
+                Color.WHITE, colorRectangles);
+
+        // Remove one of the views from the overlay
+        runTestOnUiThread(() -> mViewGroupOverlay.remove(greenView));
+        colorRectangles.clear();
+        colorRectangles.add(new Pair<>(new Rect(10, 20, 30, 40), Color.RED));
+        colorRectangles.add(new Pair<>(new Rect(40, 60, 80, 90), Color.BLUE));
+        DrawingUtils.assertAllPixelsOfColor("Overlay with two views", mViewGroupWithOverlay,
+                Color.WHITE, colorRectangles);
+
+        // Clear all views from the overlay and test that we're back to pure white fill
+        runTestOnUiThread(() -> mViewGroupOverlay.clear());
+        DrawingUtils.assertAllPixelsOfColor("Back to default fill", mViewGroupWithOverlay,
+                Color.WHITE, null);
+    }
+
+
+    public void testOverlayWithNonOverlappingViewAndDrawable() throws Throwable {
+        // Add one view and one drawable to the overlay
+        final View redView = new View(mContext);
+        redView.setBackgroundColor(Color.RED);
+        redView.layout(10, 20, 30, 40);
+        final Drawable greenDrawable = new ColorDrawable(Color.GREEN);
+        greenDrawable.setBounds(60, 30, 90, 50);
+
+        runTestOnUiThread(
+                () -> {
+                    mViewGroupOverlay.add(redView);
+                    mViewGroupOverlay.add(greenDrawable);
+                });
+
+        final List<Pair<Rect, Integer>> colorRectangles = new ArrayList<>();
+        colorRectangles.add(new Pair<>(new Rect(10, 20, 30, 40), Color.RED));
+        colorRectangles.add(new Pair<>(new Rect(60, 30, 90, 50), Color.GREEN));
+        DrawingUtils.assertAllPixelsOfColor("Overlay with one view and one drawable",
+                mViewGroupWithOverlay, Color.WHITE, colorRectangles);
+
+        // Remove the view from the overlay
+        runTestOnUiThread(() -> mViewGroupOverlay.remove(redView));
+        colorRectangles.clear();
+        colorRectangles.add(new Pair<>(new Rect(60, 30, 90, 50), Color.GREEN));
+        DrawingUtils.assertAllPixelsOfColor("Overlay with one drawable", mViewGroupWithOverlay,
+                Color.WHITE, colorRectangles);
+
+        // Clear everything from the overlay and test that we're back to pure white fill
+        runTestOnUiThread(() -> mViewGroupOverlay.clear());
+        DrawingUtils.assertAllPixelsOfColor("Back to default fill", mViewGroupWithOverlay,
+                Color.WHITE, null);
+    }
+
+    public void testOverlayWithOverlappingViews() throws Throwable {
+        // Add two overlapping colored views to the overlay
+        final View redView = new View(mContext);
+        redView.setBackgroundColor(Color.RED);
+        redView.layout(10, 20, 60, 40);
+        final View greenView = new View(mContext);
+        greenView.setBackgroundColor(Color.GREEN);
+        greenView.layout(30, 20, 80, 40);
+
+        runTestOnUiThread(
+                () -> {
+                    mViewGroupOverlay.add(redView);
+                    mViewGroupOverlay.add(greenView);
+                });
+
+        // Our overlay views overlap in horizontal 30-60 range. Here we test that the
+        // second view is the one that is drawn last in that range.
+        final List<Pair<Rect, Integer>> colorRectangles = new ArrayList<>();
+        colorRectangles.add(new Pair<>(new Rect(10, 20, 30, 40), Color.RED));
+        colorRectangles.add(new Pair<>(new Rect(30, 20, 80, 40), Color.GREEN));
+        DrawingUtils.assertAllPixelsOfColor("Overlay with two drawables", mViewGroupWithOverlay,
+                Color.WHITE, colorRectangles);
+
+        // Remove the second view from the overlay
+        runTestOnUiThread(() -> mViewGroupOverlay.remove(greenView));
+        colorRectangles.clear();
+        colorRectangles.add(new Pair<>(new Rect(10, 20, 60, 40), Color.RED));
+        DrawingUtils.assertAllPixelsOfColor("Overlay with one drawable", mViewGroupWithOverlay,
+                Color.WHITE, colorRectangles);
+
+        // Clear all views from the overlay and test that we're back to pure white fill
+        runTestOnUiThread(() -> mViewGroupOverlay.clear());
+        DrawingUtils.assertAllPixelsOfColor("Back to default fill", mViewGroupWithOverlay,
+                Color.WHITE, null);
+    }
+
+    public void testOverlayWithOverlappingViewAndDrawable() throws Throwable {
+        // Add two overlapping colored views to the overlay
+        final Drawable redDrawable = new ColorDrawable(Color.RED);
+        redDrawable.setBounds(10, 20, 60, 40);
+        final View greenView = new View(mContext);
+        greenView.setBackgroundColor(Color.GREEN);
+        greenView.layout(30, 20, 80, 40);
+
+        runTestOnUiThread(
+                () -> {
+                    mViewGroupOverlay.add(redDrawable);
+                    mViewGroupOverlay.add(greenView);
+                });
+
+        // Our overlay views overlap in horizontal 30-60 range. Even though the green view was
+        // added after the red drawable, *all* overlay drawables are drawn after the overlay views.
+        // So in the overlap range we expect color red
+        final List<Pair<Rect, Integer>> colorRectangles = new ArrayList<>();
+        colorRectangles.add(new Pair<>(new Rect(10, 20, 60, 40), Color.RED));
+        colorRectangles.add(new Pair<>(new Rect(60, 20, 80, 40), Color.GREEN));
+        DrawingUtils.assertAllPixelsOfColor("Overlay with one view and one drawable",
+                mViewGroupWithOverlay, Color.WHITE, colorRectangles);
+
+        // Remove the drawable from the overlay
+        runTestOnUiThread(() -> mViewGroupOverlay.remove(redDrawable));
+        colorRectangles.clear();
+        colorRectangles.add(new Pair<>(new Rect(30, 20, 80, 40), Color.GREEN));
+        DrawingUtils.assertAllPixelsOfColor("Overlay with one view", mViewGroupWithOverlay,
+                Color.WHITE, colorRectangles);
+
+        // Clear all views from the overlay and test that we're back to pure white fill
+        runTestOnUiThread(() -> mViewGroupOverlay.clear());
+        DrawingUtils.assertAllPixelsOfColor("Back to default fill", mViewGroupWithOverlay,
+                Color.WHITE, null);
+    }
+
+    public void testOverlayViewNoClicks() throws Throwable {
+        // Add one colored view with mock click listener to the overlay
+        final View redView = new View(mContext);
+        redView.setBackgroundColor(Color.RED);
+        final View.OnClickListener mockClickListener = mock(View.OnClickListener.class);
+        redView.setOnClickListener(mockClickListener);
+        redView.layout(10, 20, 30, 40);
+
+        runTestOnUiThread(() -> mViewGroupOverlay.add(redView));
+
+        // If we call performClick or dispatchTouchEvent on the view that we've added to the
+        // overlay, that will invoke the listener that we've registered. But here we need to
+        // test that such a view doesn't get clicks in the regular event processing pipeline
+        // that handles individual events at the screen level. Use Instrumentation to emulate
+        // the high-level sequence of events instead.
+        final int[] viewGroupOnScreenXY = new int[2];
+        mViewGroupWithOverlay.getLocationOnScreen(viewGroupOnScreenXY);
+
+        // Compute the coordinates for emulating a tap in the center of the view we've added
+        // to the overlay.
+        final int emulatedTapX = viewGroupOnScreenXY[0] + redView.getLeft()
+                + redView.getWidth() / 2;
+        final int emulatedTapY = viewGroupOnScreenXY[1] + redView.getTop()
+                + redView.getHeight() / 2;
+        final Instrumentation instrumentation = getInstrumentation();
+
+        // Inject DOWN event
+        long downTime = SystemClock.uptimeMillis();
+        MotionEvent eventDown = MotionEvent.obtain(
+                downTime, downTime, MotionEvent.ACTION_DOWN, emulatedTapX, emulatedTapY, 1);
+        instrumentation.sendPointerSync(eventDown);
+
+        // Inject MOVE event
+        long moveTime = SystemClock.uptimeMillis();
+        MotionEvent eventMove = MotionEvent.obtain(
+                moveTime, moveTime, MotionEvent.ACTION_MOVE, emulatedTapX, emulatedTapY, 1);
+        instrumentation.sendPointerSync(eventMove);
+
+        // Inject UP event
+        long upTime = SystemClock.uptimeMillis();
+        MotionEvent eventUp = MotionEvent.obtain(
+                upTime, upTime, MotionEvent.ACTION_UP, emulatedTapX, emulatedTapY, 1);
+        instrumentation.sendPointerSync(eventUp);
+
+        // Wait for the system to process all events in the queue
+        instrumentation.waitForIdleSync();
+
+        // Verify that our mock listener hasn't been called
+        verify(mockClickListener, never()).onClick(any(View.class));
+    }
+
+    public void testOverlayReparenting() throws Throwable {
+        // Find the view that we're about to add to our overlay
+        final View level2View = mViewGroupWithOverlay.findViewById(R.id.level2);
+        final View level3View = level2View.findViewById(R.id.level3);
+
+        assertTrue(level2View == level3View.getParent());
+
+        // Set the fill of this view to red
+        runTestOnUiThread(
+                () -> {
+                    level3View.setBackgroundColor(Color.RED);
+                    mViewGroupOverlay.add(level3View);
+                });
+
+        // At this point we expect the view that was added to the overlay to have been removed
+        // from its original parent
+        assertFalse(level2View == level3View.getParent());
+
+        // Check the expected visual appearance of our view group. We expect that the view that
+        // was added to the overlay to maintain its relative location inside the activity.
+        final List<Pair<Rect, Integer>> colorRectangles = new ArrayList<>();
+        colorRectangles.add(new Pair<>(new Rect(65, 60, 85, 90), Color.RED));
+        DrawingUtils.assertAllPixelsOfColor("Empty overlay before adding grandchild",
+                mViewGroupWithOverlay, Color.WHITE, colorRectangles);
+
+    }
+}
diff --git a/tests/tests/view/src/android/view/cts/ViewGroupTest.java b/tests/tests/view/src/android/view/cts/ViewGroupTest.java
index 7fc5579..49979ca 100644
--- a/tests/tests/view/src/android/view/cts/ViewGroupTest.java
+++ b/tests/tests/view/src/android/view/cts/ViewGroupTest.java
@@ -16,19 +16,16 @@
 
 package android.view.cts;
 
-import android.view.cts.util.XmlUtils;
-
-
 import android.content.Context;
 import android.content.Intent;
-import android.cts.util.CTSResult;
 import android.content.res.XmlResourceParser;
+import android.cts.util.CTSResult;
 import android.graphics.Bitmap;
+import android.graphics.Bitmap.Config;
 import android.graphics.Canvas;
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.graphics.Region;
-import android.graphics.Bitmap.Config;
 import android.graphics.drawable.BitmapDrawable;
 import android.os.Parcelable;
 import android.os.SystemClock;
@@ -44,19 +41,20 @@
 import android.view.MenuItem;
 import android.view.MotionEvent;
 import android.view.View;
-import android.view.ViewGroup;
-import android.view.WindowManager;
 import android.view.View.BaseSavedState;
 import android.view.View.MeasureSpec;
 import android.view.View.OnTouchListener;
+import android.view.ViewGroup;
 import android.view.ViewGroup.LayoutParams;
 import android.view.ViewGroup.OnHierarchyChangeListener;
+import android.view.WindowManager;
 import android.view.animation.AlphaAnimation;
 import android.view.animation.Animation;
+import android.view.animation.Animation.AnimationListener;
 import android.view.animation.LayoutAnimationController;
 import android.view.animation.RotateAnimation;
 import android.view.animation.Transformation;
-import android.view.animation.Animation.AnimationListener;
+import android.view.cts.util.XmlUtils;
 import android.widget.TextView;
 
 import java.util.ArrayList;
@@ -338,23 +336,23 @@
 
         Canvas canvas = new Canvas();
         MockViewGroup vg = new MockViewGroup(mContext);
-        MockViewGroup son = new MockViewGroup(mContext);
-        son.setAnimation(new MockAnimation());
-        vg.addView(son);
+        MockViewGroup child = new MockViewGroup(mContext);
+        child.setAnimation(new MockAnimation());
+        vg.addView(child);
         assertEquals(1, vg.getChildCount());
 
-        assertNotNull(son.getAnimation());
+        assertNotNull(child.getAnimation());
         vg.dispatchDraw(canvas);
         assertEquals(1, vg.drawChildCalledTime);
 
-        son.setAnimation(new MockAnimation());
+        child.setAnimation(new MockAnimation());
         vg.removeAllViewsInLayout();
 
         vg.drawChildCalledTime = 0;
         vg.dispatchDraw(canvas);
         assertEquals(1, vg.drawChildCalledTime);
 
-        son.setAnimation(new MockAnimation());
+        child.setAnimation(new MockAnimation());
         vg.clearDisappearingChildren();
 
         vg.drawChildCalledTime = 0;
@@ -535,6 +533,7 @@
         MockTextView textView = new MockTextView(mContext);
         mMotionEvent = null;
         textView.setOnTouchListener(new OnTouchListener() {
+            @Override
             public boolean onTouch(View v, MotionEvent event) {
                 mMotionEvent = event;
                 return true;
@@ -683,11 +682,11 @@
 
     public void testFocusableViewAvailable() {
         MockViewGroup vg = new MockViewGroup(mContext);
-        MockView son = new MockView(mContext);
-        vg.addView(son);
+        MockView child = new MockView(mContext);
+        vg.addView(child);
 
-        son.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS);
-        son.focusableViewAvailable(vg);
+        child.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS);
+        child.focusableViewAvailable(vg);
 
         assertTrue(vg.isFocusableViewAvailable);
     }
@@ -695,11 +694,11 @@
     public void testFocusSearch() {
         MockViewGroup vg = new MockViewGroup(mContext);
         MockTextView textView = new MockTextView(mContext);
-        MockView son = new MockView(mContext);
-        vg.addView(son);
-        son.addView(textView);
-        assertNotNull(son.focusSearch(textView, 1));
-        assertSame(textView, son.focusSearch(textView, 1));
+        MockView child = new MockView(mContext);
+        vg.addView(child);
+        child.addView(textView);
+        assertNotNull(child.focusSearch(textView, 1));
+        assertSame(textView, child.focusSearch(textView, 1));
     }
 
     public void testGatherTransparentRegion() {
@@ -726,7 +725,7 @@
     public void testGenerateLayoutParamsWithParaAttributeSet() throws Exception{
         MockViewGroup vg = new MockViewGroup(mContext);
         XmlResourceParser set = mContext.getResources().getLayout(
-                com.android.cts.view.R.layout.abslistview_layout);
+                android.view.cts.R.layout.abslistview_layout);
         XmlUtils.beginDocument(set, "ViewGroup_Layout");
         LayoutParams lp = vg.generateLayoutParams(set);
         assertNotNull(lp);
@@ -738,7 +737,10 @@
         MockViewGroup vg = new MockViewGroup(mContext);
         LayoutParams p = new LayoutParams(LayoutParams.WRAP_CONTENT,
                 LayoutParams.MATCH_PARENT);
-        assertSame(p, vg.generateLayoutParams(p));
+        LayoutParams generatedParams = vg.generateLayoutParams(p);
+        assertEquals(generatedParams.getClass(), p.getClass());
+        assertEquals(p.width, generatedParams.width);
+        assertEquals(p.height, generatedParams.height);
     }
 
     public void testGetChildDrawingOrder() {
@@ -808,12 +810,15 @@
 
         AnimationListener al = new AnimationListener() {
 
+            @Override
             public void onAnimationEnd(Animation animation) {
             }
 
+            @Override
             public void onAnimationRepeat(Animation animation) {
             }
 
+            @Override
             public void onAnimationStart(Animation animation) {
             }
         };
@@ -924,18 +929,18 @@
         final int width = 100;
         final int height = 200;
         MockViewGroup vg = new MockViewGroup(mContext);
-        MockView son = new MockView(mContext);
-        son.setLayoutParams(new LayoutParams(width, height));
-        son.forceLayout();
-        vg.addView(son);
+        MockView child = new MockView(mContext);
+        child.setLayoutParams(new LayoutParams(width, height));
+        child.forceLayout();
+        vg.addView(child);
 
         final int parentWidthMeasureSpec = 1;
         final int parentHeightMeasureSpec = 2;
-        vg.measureChild(son, parentWidthMeasureSpec, parentHeightMeasureSpec);
+        vg.measureChild(child, parentWidthMeasureSpec, parentHeightMeasureSpec);
         assertEquals(ViewGroup.getChildMeasureSpec(parentWidthMeasureSpec, 0, width),
-                son.mWidthMeasureSpec);
+                child.mWidthMeasureSpec);
         assertEquals(ViewGroup.getChildMeasureSpec(parentHeightMeasureSpec, 0, height),
-                son.mHeightMeasureSpec);
+                child.mHeightMeasureSpec);
     }
 
     public void testMeasureChildren() {
@@ -966,24 +971,24 @@
         final int parentHeightMeasureSpec = 3;
         final int heightUsed = 4;
         MockViewGroup vg = new MockViewGroup(mContext);
-        MockView son = new MockView(mContext);
+        MockView child = new MockView(mContext);
 
-        vg.addView(son);
-        son.setLayoutParams(new ViewGroup.LayoutParams(width, height));
+        vg.addView(child);
+        child.setLayoutParams(new ViewGroup.LayoutParams(width, height));
         try {
-            vg.measureChildWithMargins(son, parentWidthMeasureSpec, widthUsed,
+            vg.measureChildWithMargins(child, parentWidthMeasureSpec, widthUsed,
                     parentHeightMeasureSpec, heightUsed);
             fail("measureChildWithMargins should throw out class cast exception");
         } catch (RuntimeException e) {
         }
-        son.setLayoutParams(new ViewGroup.MarginLayoutParams(width, height));
+        child.setLayoutParams(new ViewGroup.MarginLayoutParams(width, height));
 
-        vg.measureChildWithMargins(son, parentWidthMeasureSpec, widthUsed, parentHeightMeasureSpec,
+        vg.measureChildWithMargins(child, parentWidthMeasureSpec, widthUsed, parentHeightMeasureSpec,
                 heightUsed);
         assertEquals(ViewGroup.getChildMeasureSpec(parentWidthMeasureSpec, parentHeightMeasureSpec,
-                width), son.mWidthMeasureSpec);
+                width), child.mWidthMeasureSpec);
         assertEquals(ViewGroup.getChildMeasureSpec(widthUsed, heightUsed, height),
-                son.mHeightMeasureSpec);
+                child.mHeightMeasureSpec);
     }
 
     public void testOffsetDescendantRectToMyCoords() {
@@ -1032,16 +1037,16 @@
 
     public void testOnAnimationEnd() {
         // this function is a call back function it should be tested in ViewGroup#drawChild.
-        MockViewGroup father = new MockViewGroup(mContext);
-        MockViewGroup son = new MockViewGroup(mContext);
-        son.setAnimation(new MockAnimation());
+        MockViewGroup parent = new MockViewGroup(mContext);
+        MockViewGroup child = new MockViewGroup(mContext);
+        child.setAnimation(new MockAnimation());
         // this call will make mPrivateFlags |= ANIMATION_STARTED;
-        son.onAnimationStart();
-        father.addView(son);
+        child.onAnimationStart();
+        parent.addView(child);
 
         MockCanvas canvas = new MockCanvas();
-        assertFalse(father.drawChild(canvas, son, 100));
-        assertTrue(son.isOnAnimationEndCalled);
+        assertFalse(parent.drawChild(canvas, child, 100));
+        assertTrue(child.isOnAnimationEndCalled);
     }
 
     private class MockAnimation extends Animation {
@@ -1062,22 +1067,22 @@
 
     public void testOnAnimationStart() {
         // This is a call back method. It should be tested in ViewGroup#drawChild.
-        MockViewGroup father = new MockViewGroup(mContext);
-        MockViewGroup son = new MockViewGroup(mContext);
+        MockViewGroup parent = new MockViewGroup(mContext);
+        MockViewGroup child = new MockViewGroup(mContext);
 
-        father.addView(son);
+        parent.addView(child);
 
         MockCanvas canvas = new MockCanvas();
         try {
-            assertFalse(father.drawChild(canvas, son, 100));
-            assertFalse(son.isOnAnimationStartCalled);
+            assertFalse(parent.drawChild(canvas, child, 100));
+            assertFalse(child.isOnAnimationStartCalled);
         } catch (Exception e) {
             // expected
         }
 
-        son.setAnimation(new MockAnimation());
-        assertFalse(father.drawChild(canvas, son, 100));
-        assertTrue(son.isOnAnimationStartCalled);
+        child.setAnimation(new MockAnimation());
+        assertFalse(parent.drawChild(canvas, child, 100));
+        assertTrue(child.isOnAnimationStartCalled);
     }
 
     public void testOnCreateDrawableState() {
@@ -1132,35 +1137,35 @@
     }
 
     public void testRemoveAllViewsInLayout() {
-        MockViewGroup father = new MockViewGroup(mContext);
-        MockViewGroup son = new MockViewGroup(mContext);
+        MockViewGroup parent = new MockViewGroup(mContext);
+        MockViewGroup child = new MockViewGroup(mContext);
         MockTextView textView = new MockTextView(mContext);
 
-        assertEquals(0, father.getChildCount());
+        assertEquals(0, parent.getChildCount());
 
-        son.addView(textView);
-        father.addView(son);
-        assertEquals(1, father.getChildCount());
+        child.addView(textView);
+        parent.addView(child);
+        assertEquals(1, parent.getChildCount());
 
-        father.removeAllViewsInLayout();
-        assertEquals(0, father.getChildCount());
-        assertEquals(1, son.getChildCount());
-        assertNull(son.getParent());
-        assertSame(son, textView.getParent());
+        parent.removeAllViewsInLayout();
+        assertEquals(0, parent.getChildCount());
+        assertEquals(1, child.getChildCount());
+        assertNull(child.getParent());
+        assertSame(child, textView.getParent());
     }
 
     public void testRemoveDetachedView() {
-        MockViewGroup father = new MockViewGroup(mContext);
-        MockViewGroup son1 = new MockViewGroup(mContext);
-        MockViewGroup son2 = new MockViewGroup(mContext);
+        MockViewGroup parent = new MockViewGroup(mContext);
+        MockViewGroup child1 = new MockViewGroup(mContext);
+        MockViewGroup child2 = new MockViewGroup(mContext);
         MockOnHierarchyChangeListener listener = new MockOnHierarchyChangeListener();
-        father.setOnHierarchyChangeListener(listener);
-        father.addView(son1);
-        father.addView(son2);
+        parent.setOnHierarchyChangeListener(listener);
+        parent.addView(child1);
+        parent.addView(child2);
 
-        father.removeDetachedView(son1, false);
-        assertSame(father, listener.sParent);
-        assertSame(son1, listener.sChild);
+        parent.removeDetachedView(child1, false);
+        assertSame(parent, listener.sParent);
+        assertSame(child1, listener.sChild);
     }
 
     static class MockOnHierarchyChangeListener implements OnHierarchyChangeListener {
@@ -1168,9 +1173,11 @@
         public View sParent;
         public View sChild;
 
+        @Override
         public void onChildViewAdded(View parent, View child) {
         }
 
+        @Override
         public void onChildViewRemoved(View parent, View child) {
             sParent = parent;
             sChild = child;
@@ -1178,93 +1185,123 @@
     }
 
     public void testRemoveView() {
-        MockViewGroup father = new MockViewGroup(mContext);
-        MockViewGroup son = new MockViewGroup(mContext);
+        MockViewGroup parent = new MockViewGroup(mContext);
+        MockViewGroup child = new MockViewGroup(mContext);
 
-        assertEquals(0, father.getChildCount());
+        assertEquals(0, parent.getChildCount());
 
-        father.addView(son);
-        assertEquals(1, father.getChildCount());
+        parent.addView(child);
+        assertEquals(1, parent.getChildCount());
 
-        father.removeView(son);
-        assertEquals(0, father.getChildCount());
-        assertNull(son.getParent());
+        parent.removeView(child);
+        assertEquals(0, parent.getChildCount());
+        assertNull(child.getParent());
     }
 
     public void testRemoveViewAt() {
-        MockViewGroup father = new MockViewGroup(mContext);
-        MockViewGroup son = new MockViewGroup(mContext);
+        MockViewGroup parent = new MockViewGroup(mContext);
+        MockViewGroup child = new MockViewGroup(mContext);
 
-        assertEquals(0, father.getChildCount());
+        assertEquals(0, parent.getChildCount());
 
-        father.addView(son);
-        assertEquals(1, father.getChildCount());
+        parent.addView(child);
+        assertEquals(1, parent.getChildCount());
 
         try {
-            father.removeViewAt(2);
+            parent.removeViewAt(2);
             fail("should throw out null pointer exception");
         } catch (RuntimeException e) {
             // expected
         }
-        assertEquals(1, father.getChildCount());
+        assertEquals(1, parent.getChildCount());
 
-        father.removeViewAt(0);
-        assertEquals(0, father.getChildCount());
-        assertNull(son.getParent());
+        parent.removeViewAt(0);
+        assertEquals(0, parent.getChildCount());
+        assertNull(child.getParent());
     }
 
     public void testRemoveViewInLayout() {
-        MockViewGroup father = new MockViewGroup(mContext);
-        MockViewGroup son = new MockViewGroup(mContext);
+        MockViewGroup parent = new MockViewGroup(mContext);
+        MockViewGroup child = new MockViewGroup(mContext);
 
-        assertEquals(0, father.getChildCount());
+        assertEquals(0, parent.getChildCount());
 
-        father.addView(son);
-        assertEquals(1, father.getChildCount());
+        parent.addView(child);
+        assertEquals(1, parent.getChildCount());
 
-        father.removeViewInLayout(son);
-        assertEquals(0, father.getChildCount());
-        assertNull(son.getParent());
+        parent.removeViewInLayout(child);
+        assertEquals(0, parent.getChildCount());
+        assertNull(child.getParent());
     }
 
     public void testRemoveViews() {
-        MockViewGroup father = new MockViewGroup(mContext);
-        MockViewGroup son1 = new MockViewGroup(mContext);
-        MockViewGroup son2 = new MockViewGroup(mContext);
+        MockViewGroup parent = new MockViewGroup(mContext);
+        MockViewGroup child1 = new MockViewGroup(mContext);
+        MockViewGroup child2 = new MockViewGroup(mContext);
 
-        assertEquals(0, father.getChildCount());
+        assertEquals(0, parent.getChildCount());
+        parent.addView(child1);
+        parent.addView(child2);
+        assertEquals(2, parent.getChildCount());
 
-        father.addView(son1);
-        father.addView(son2);
-        assertEquals(2, father.getChildCount());
+        try {
+            parent.removeViews(-1, 1); // negative begin
+            fail("should fail with IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {}
 
-        father.removeViews(0, 1);
-        assertEquals(1, father.getChildCount());
-        assertNull(son1.getParent());
+        try {
+            parent.removeViews(0, -1); // negative count
+            fail("should fail with IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {}
 
-        father.removeViews(0, 1);
-        assertEquals(0, father.getChildCount());
-        assertNull(son2.getParent());
+        try {
+            parent.removeViews(1, 2); // past end
+            fail("should fail with IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {}
+        assertEquals(2, parent.getChildCount()); // child list unmodified
+
+        parent.removeViews(0, 1);
+        assertEquals(1, parent.getChildCount());
+        assertNull(child1.getParent());
+
+        parent.removeViews(0, 1);
+        assertEquals(0, parent.getChildCount());
+        assertNull(child2.getParent());
     }
 
     public void testRemoveViewsInLayout() {
-        MockViewGroup father = new MockViewGroup(mContext);
-        MockViewGroup son1 = new MockViewGroup(mContext);
-        MockViewGroup son2 = new MockViewGroup(mContext);
+        MockViewGroup parent = new MockViewGroup(mContext);
+        MockViewGroup child1 = new MockViewGroup(mContext);
+        MockViewGroup child2 = new MockViewGroup(mContext);
 
-        assertEquals(0, father.getChildCount());
+        assertEquals(0, parent.getChildCount());
+        parent.addView(child1);
+        parent.addView(child2);
+        assertEquals(2, parent.getChildCount());
 
-        father.addView(son1);
-        father.addView(son2);
-        assertEquals(2, father.getChildCount());
+        try {
+            parent.removeViewsInLayout(-1, 1); // negative begin
+            fail("should fail with IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {}
 
-        father.removeViewsInLayout(0, 1);
-        assertEquals(1, father.getChildCount());
-        assertNull(son1.getParent());
+        try {
+            parent.removeViewsInLayout(0, -1); // negative count
+            fail("should fail with IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {}
 
-        father.removeViewsInLayout(0, 1);
-        assertEquals(0, father.getChildCount());
-        assertNull(son2.getParent());
+        try {
+            parent.removeViewsInLayout(1, 2); // past end
+            fail("should fail with IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {}
+        assertEquals(2, parent.getChildCount()); // child list unmodified
+
+        parent.removeViewsInLayout(0, 1);
+        assertEquals(1, parent.getChildCount());
+        assertNull(child1.getParent());
+
+        parent.removeViewsInLayout(0, 1);
+        assertEquals(0, parent.getChildCount());
+        assertNull(child2.getParent());
     }
 
     public void testRequestChildFocus() {
@@ -1286,13 +1323,13 @@
     }
 
     public void testRequestDisallowInterceptTouchEvent() {
-        MockViewGroup father = new MockViewGroup(mContext);
-        MockView son = new MockView(mContext);
+        MockViewGroup parent = new MockViewGroup(mContext);
+        MockView child = new MockView(mContext);
 
-        father.addView(son);
-        son.requestDisallowInterceptTouchEvent(true);
-        son.requestDisallowInterceptTouchEvent(false);
-        assertTrue(father.isRequestDisallowInterceptTouchEventCalled);
+        parent.addView(child);
+        child.requestDisallowInterceptTouchEvent(true);
+        child.requestDisallowInterceptTouchEvent(false);
+        assertTrue(parent.isRequestDisallowInterceptTouchEventCalled);
     }
 
     public void testRequestFocus() {
@@ -1303,13 +1340,13 @@
     }
 
     public void testRequestTransparentRegion() {
-        MockViewGroup father = new MockViewGroup(mContext);
-        MockView son1 = new MockView(mContext);
-        MockView son2 = new MockView(mContext);
-        son1.addView(son2);
-        father.addView(son1);
-        son1.requestTransparentRegion(son2);
-        assertTrue(father.isRequestTransparentRegionCalled);
+        MockViewGroup parent = new MockViewGroup(mContext);
+        MockView child1 = new MockView(mContext);
+        MockView child2 = new MockView(mContext);
+        child1.addView(child2);
+        parent.addView(child1);
+        child1.requestTransparentRegion(child2);
+        assertTrue(parent.isRequestTransparentRegionCalled);
     }
 
     public void testScheduleLayoutAnimation() {
@@ -1476,15 +1513,15 @@
     }
 
     public void testSetOnHierarchyChangeListener() {
-        MockViewGroup father = new MockViewGroup(mContext);
-        MockViewGroup son = new MockViewGroup(mContext);
+        MockViewGroup parent = new MockViewGroup(mContext);
+        MockViewGroup child = new MockViewGroup(mContext);
         MockOnHierarchyChangeListener listener = new MockOnHierarchyChangeListener();
-        father.setOnHierarchyChangeListener(listener);
-        father.addView(son);
+        parent.setOnHierarchyChangeListener(listener);
+        parent.addView(child);
 
-        father.removeDetachedView(son, false);
-        assertSame(father, listener.sParent);
-        assertSame(son, listener.sChild);
+        parent.removeDetachedView(child, false);
+        assertSame(parent, listener.sParent);
+        assertSame(child, listener.sChild);
     }
 
     public void testSetPadding() {
@@ -1595,12 +1632,21 @@
     }
 
     public void testShowContextMenuForChild() {
-        MockViewGroup father = new MockViewGroup(mContext);
-        MockViewGroup son = new MockViewGroup(mContext);
-        father.addView(son);
+        MockViewGroup parent = new MockViewGroup(mContext);
+        MockViewGroup child = new MockViewGroup(mContext);
+        parent.addView(child);
 
-        son.showContextMenuForChild(null);
-        assertTrue(father.isShowContextMenuForChildCalled);
+        child.showContextMenuForChild(null);
+        assertTrue(parent.isShowContextMenuForChildCalled);
+    }
+
+    public void testShowContextMenuForChild_WithXYCoords() {
+        MockViewGroup parent = new MockViewGroup(mContext);
+        MockViewGroup child = new MockViewGroup(mContext);
+        parent.addView(child);
+
+        child.showContextMenuForChild(null, 48, 48);
+        assertTrue(parent.isShowContextMenuForChildCalledWithXYCoords);
     }
 
     public void testStartLayoutAnimation() {
@@ -1616,24 +1662,24 @@
     }
 
     public void testUpdateViewLayout() {
-        MockViewGroup father = new MockViewGroup(mContext);
-        MockViewGroup son = new MockViewGroup(mContext);
+        MockViewGroup parent = new MockViewGroup(mContext);
+        MockViewGroup child = new MockViewGroup(mContext);
 
-        father.addView(son);
+        parent.addView(child);
         LayoutParams param = new LayoutParams(100, 200);
-        father.updateViewLayout(son, param);
-        assertEquals(param.width, son.getLayoutParams().width);
-        assertEquals(param.height, son.getLayoutParams().height);
+        parent.updateViewLayout(child, param);
+        assertEquals(param.width, child.getLayoutParams().width);
+        assertEquals(param.height, child.getLayoutParams().height);
     }
 
     public void testDebug() {
         final int EXPECTED = 100;
-        MockViewGroup father = new MockViewGroup(mContext);
-        MockViewGroup son = new MockViewGroup(mContext);
-        father.addView(son);
+        MockViewGroup parent = new MockViewGroup(mContext);
+        MockViewGroup child = new MockViewGroup(mContext);
+        parent.addView(child);
 
-        father.debug(EXPECTED);
-        assertEquals(EXPECTED + 1, son.debugDepth);
+        parent.debug(EXPECTED);
+        assertEquals(EXPECTED + 1, child.debugDepth);
     }
 
     public void testDispatchKeyEventPreIme() {
@@ -1960,6 +2006,7 @@
 
         public boolean isRecomputeViewAttributesCalled;
         public boolean isShowContextMenuForChildCalled;
+        public boolean isShowContextMenuForChildCalledWithXYCoords;
         public boolean isRefreshDrawableStateCalled;
         public boolean isOnRestoreInstanceStateCalled;
         public boolean isOnCreateDrawableStateCalled;
@@ -1977,7 +2024,6 @@
         public int debugDepth;
         public int drawChildCalledTime;
         public Canvas canvas;
-        public boolean isInvalidateChildInParentCalled;
         public boolean isDrawableStateChangedCalled;
         public boolean isRequestLayoutCalled;
         public boolean isOnLayoutCalled;
@@ -2221,6 +2267,12 @@
         }
 
         @Override
+        public boolean showContextMenuForChild(View originalView, float x, float y) {
+            isShowContextMenuForChildCalledWithXYCoords = true;
+            return super.showContextMenuForChild(originalView, x, y);
+        }
+
+        @Override
         public boolean isInTouchMode() {
             super.isInTouchMode();
             return false;
@@ -2370,6 +2422,7 @@
         }
     }
 
+    @Override
     public void setResult(int resultCode) {
         synchronized (mSync) {
             mSync.mHasNotify = true;
diff --git a/tests/tests/view/src/android/view/cts/ViewGroup_LayoutParamsTest.java b/tests/tests/view/src/android/view/cts/ViewGroup_LayoutParamsTest.java
index 5dadffd..7476ba6 100644
--- a/tests/tests/view/src/android/view/cts/ViewGroup_LayoutParamsTest.java
+++ b/tests/tests/view/src/android/view/cts/ViewGroup_LayoutParamsTest.java
@@ -16,7 +16,7 @@
 
 package android.view.cts;
 
-import com.android.cts.view.R;
+import android.view.cts.R;
 
 import org.xmlpull.v1.XmlPullParserException;
 
diff --git a/tests/tests/view/src/android/view/cts/ViewGroup_MarginLayoutParamsTest.java b/tests/tests/view/src/android/view/cts/ViewGroup_MarginLayoutParamsTest.java
index e53cba2..2bf3f8b 100644
--- a/tests/tests/view/src/android/view/cts/ViewGroup_MarginLayoutParamsTest.java
+++ b/tests/tests/view/src/android/view/cts/ViewGroup_MarginLayoutParamsTest.java
@@ -16,7 +16,7 @@
 
 package android.view.cts;
 
-import com.android.cts.view.R;
+import android.view.cts.R;
 
 import android.content.Context;
 import android.content.res.XmlResourceParser;
@@ -170,4 +170,40 @@
 
         assertEquals(true, mMarginLayoutParams.isMarginRelative());
     }
+
+    public void testResolveMarginsExplicit() {
+        // LTR / relative margin case
+        mMarginLayoutParams = new ViewGroup.MarginLayoutParams(320, 480);
+        mMarginLayoutParams.setMargins(0, 30, 0, 140);
+        mMarginLayoutParams.setMarginStart(20);
+        mMarginLayoutParams.setMarginEnd(120);
+        mMarginLayoutParams.resolveLayoutDirection(View.LAYOUT_DIRECTION_LTR);
+
+        assertEquals(20, mMarginLayoutParams.getMarginStart());
+        assertEquals(30, mMarginLayoutParams.topMargin);
+        assertEquals(120, mMarginLayoutParams.getMarginEnd());
+        assertEquals(140, mMarginLayoutParams.bottomMargin);
+
+        assertEquals(20, mMarginLayoutParams.leftMargin);
+        assertEquals(120, mMarginLayoutParams.rightMargin);
+
+        assertEquals(true, mMarginLayoutParams.isMarginRelative());
+
+        // RTL / relative margin case
+        mMarginLayoutParams = new ViewGroup.MarginLayoutParams(320, 480);
+        mMarginLayoutParams.setMargins(0, 30, 0, 140);
+        mMarginLayoutParams.setMarginStart(20);
+        mMarginLayoutParams.setMarginEnd(120);
+        mMarginLayoutParams.resolveLayoutDirection(View.LAYOUT_DIRECTION_RTL);
+
+        assertEquals(20, mMarginLayoutParams.getMarginStart());
+        assertEquals(30, mMarginLayoutParams.topMargin);
+        assertEquals(120, mMarginLayoutParams.getMarginEnd());
+        assertEquals(140, mMarginLayoutParams.bottomMargin);
+
+        assertEquals(120, mMarginLayoutParams.leftMargin);
+        assertEquals(20, mMarginLayoutParams.rightMargin);
+
+        assertEquals(true, mMarginLayoutParams.isMarginRelative());
+    }
 }
diff --git a/tests/tests/view/src/android/view/cts/ViewLayoutPositionTestCtsActivity.java b/tests/tests/view/src/android/view/cts/ViewLayoutPositionTestCtsActivity.java
index 69dc70f..41f3e33 100644
--- a/tests/tests/view/src/android/view/cts/ViewLayoutPositionTestCtsActivity.java
+++ b/tests/tests/view/src/android/view/cts/ViewLayoutPositionTestCtsActivity.java
@@ -18,7 +18,7 @@
 
 import android.app.Activity;
 import android.os.Bundle;
-import com.android.cts.view.R;
+import android.view.cts.R;
 
 public class ViewLayoutPositionTestCtsActivity extends Activity {
     @Override
diff --git a/tests/tests/view/src/android/view/cts/ViewOverlayCtsActivity.java b/tests/tests/view/src/android/view/cts/ViewOverlayCtsActivity.java
new file mode 100644
index 0000000..8b0a488
--- /dev/null
+++ b/tests/tests/view/src/android/view/cts/ViewOverlayCtsActivity.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.view.cts;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class ViewOverlayCtsActivity extends Activity {
+    @Override
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        setContentView(R.layout.viewoverlay_layout);
+    }
+}
diff --git a/tests/tests/view/src/android/view/cts/ViewOverlayTest.java b/tests/tests/view/src/android/view/cts/ViewOverlayTest.java
new file mode 100644
index 0000000..32477c9
--- /dev/null
+++ b/tests/tests/view/src/android/view/cts/ViewOverlayTest.java
@@ -0,0 +1,262 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.view.cts;
+
+import android.graphics.Color;
+import android.graphics.Rect;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.util.Pair;
+import android.view.View;
+import android.view.ViewOverlay;
+import android.view.cts.util.DrawingUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@SmallTest
+public class ViewOverlayTest extends ActivityInstrumentationTestCase2<ViewOverlayCtsActivity> {
+    private View mViewWithOverlay;
+    private ViewOverlay mViewOverlay;
+
+    public ViewOverlayTest() {
+        super("android.view.cts", ViewOverlayCtsActivity.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        mViewWithOverlay = getActivity().findViewById(R.id.view_with_overlay);
+        mViewOverlay = mViewWithOverlay.getOverlay();
+    }
+
+    public void testBasics() {
+        DrawingUtils.assertAllPixelsOfColor("Default fill", mViewWithOverlay,
+                Color.WHITE, null);
+        assertNotNull("Overlay is not null", mViewOverlay);
+    }
+
+    public void testAddNullDrawable() throws Throwable {
+        try {
+            runTestOnUiThread(() -> mViewOverlay.add(null));
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+        }
+    }
+
+    public void testRemoveNullDrawable() throws Throwable {
+        try {
+            runTestOnUiThread(() -> mViewOverlay.remove(null));
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+        }
+    }
+
+    public void testOverlayWithOneDrawable() throws Throwable {
+        // Add one colored drawable to the overlay
+        final Drawable redDrawable = new ColorDrawable(Color.RED);
+        redDrawable.setBounds(20, 30, 40, 50);
+        runTestOnUiThread(() -> mViewOverlay.add(redDrawable));
+
+        final List<Pair<Rect, Integer>> colorRectangles = new ArrayList<>();
+        colorRectangles.add(new Pair<>(new Rect(20, 30, 40, 50), Color.RED));
+        DrawingUtils.assertAllPixelsOfColor("Overlay with one red drawable", mViewWithOverlay,
+                Color.WHITE, colorRectangles);
+
+        // Now remove that drawable from the overlay and test that we're back to pure white fill
+        runTestOnUiThread(() -> mViewOverlay.remove(redDrawable));
+        DrawingUtils.assertAllPixelsOfColor("Back to default fill", mViewWithOverlay,
+                Color.WHITE, null);
+    }
+
+    public void testAddTheSameDrawableTwice() throws Throwable {
+        final Drawable redDrawable = new ColorDrawable(Color.RED);
+        redDrawable.setBounds(20, 30, 40, 50);
+        runTestOnUiThread(
+                () -> {
+                    // Add the same drawable twice
+                    mViewOverlay.add(redDrawable);
+                    mViewOverlay.add(redDrawable);
+                });
+
+        final List<Pair<Rect, Integer>> colorRectangles = new ArrayList<>();
+        colorRectangles.add(new Pair<>(new Rect(20, 30, 40, 50), Color.RED));
+        DrawingUtils.assertAllPixelsOfColor("Overlay with one red drawable", mViewWithOverlay,
+                Color.WHITE, colorRectangles);
+
+        // Now remove that drawable from the overlay and test that we're back to pure white fill
+        runTestOnUiThread(() -> mViewOverlay.remove(redDrawable));
+        DrawingUtils.assertAllPixelsOfColor("Back to default fill", mViewWithOverlay,
+                Color.WHITE, null);
+    }
+
+    public void testRemoveTheSameDrawableTwice() throws Throwable {
+        // Add one colored drawable to the overlay
+        final Drawable redDrawable = new ColorDrawable(Color.RED);
+        redDrawable.setBounds(20, 30, 40, 50);
+        runTestOnUiThread(() -> mViewOverlay.add(redDrawable));
+
+        final List<Pair<Rect, Integer>> colorRectangles = new ArrayList<>();
+        colorRectangles.add(new Pair<>(new Rect(20, 30, 40, 50), Color.RED));
+        DrawingUtils.assertAllPixelsOfColor("Overlay with one red drawable", mViewWithOverlay,
+                Color.WHITE, colorRectangles);
+
+        // Now remove that drawable from the overlay and test that we're back to pure white fill
+        runTestOnUiThread(
+                () -> {
+                    // Remove the drawable twice. The second should be a no-op
+                    mViewOverlay.remove(redDrawable);
+                    mViewOverlay.remove(redDrawable);
+                });
+        DrawingUtils.assertAllPixelsOfColor("Back to default fill", mViewWithOverlay,
+                Color.WHITE, null);
+    }
+
+    public void testOverlayWithNonOverlappingDrawables() throws Throwable {
+        // Add three color drawables to the overlay
+        final Drawable redDrawable = new ColorDrawable(Color.RED);
+        redDrawable.setBounds(10, 20, 30, 40);
+        final Drawable greenDrawable = new ColorDrawable(Color.GREEN);
+        greenDrawable.setBounds(60, 30, 90, 50);
+        final Drawable blueDrawable = new ColorDrawable(Color.BLUE);
+        blueDrawable.setBounds(40, 60, 80, 90);
+
+        runTestOnUiThread(
+                () -> {
+                    mViewOverlay.add(redDrawable);
+                    mViewOverlay.add(greenDrawable);
+                    mViewOverlay.add(blueDrawable);
+                });
+
+        final List<Pair<Rect, Integer>> colorRectangles = new ArrayList<>();
+        colorRectangles.add(new Pair<>(new Rect(10, 20, 30, 40), Color.RED));
+        colorRectangles.add(new Pair<>(new Rect(60, 30, 90, 50), Color.GREEN));
+        colorRectangles.add(new Pair<>(new Rect(40, 60, 80, 90), Color.BLUE));
+        DrawingUtils.assertAllPixelsOfColor("Overlay with three drawables", mViewWithOverlay,
+                Color.WHITE, colorRectangles);
+
+        // Remove one of the drawables from the overlay
+        runTestOnUiThread(() -> mViewOverlay.remove(greenDrawable));
+        colorRectangles.clear();
+        colorRectangles.add(new Pair<>(new Rect(10, 20, 30, 40), Color.RED));
+        colorRectangles.add(new Pair<>(new Rect(40, 60, 80, 90), Color.BLUE));
+        DrawingUtils.assertAllPixelsOfColor("Overlay with two drawables", mViewWithOverlay,
+                Color.WHITE, colorRectangles);
+
+        // Clear all drawables from the overlay and test that we're back to pure white fill
+        runTestOnUiThread(() -> mViewOverlay.clear());
+        DrawingUtils.assertAllPixelsOfColor("Back to default fill", mViewWithOverlay,
+                Color.WHITE, null);
+    }
+
+    public void testOverlayWithOverlappingDrawables() throws Throwable {
+        // Add two overlapping color drawables to the overlay
+        final Drawable redDrawable = new ColorDrawable(Color.RED);
+        redDrawable.setBounds(10, 20, 60, 40);
+        final Drawable greenDrawable = new ColorDrawable(Color.GREEN);
+        greenDrawable.setBounds(30, 20, 80, 40);
+
+        runTestOnUiThread(
+                () -> {
+                    mViewOverlay.add(redDrawable);
+                    mViewOverlay.add(greenDrawable);
+                });
+
+        // Our overlay drawables overlap in horizontal 30-60 range. Here we test that the
+        // second drawable is the one that is drawn last in that range.
+        final List<Pair<Rect, Integer>> colorRectangles = new ArrayList<>();
+        colorRectangles.add(new Pair<>(new Rect(10, 20, 30, 40), Color.RED));
+        colorRectangles.add(new Pair<>(new Rect(30, 20, 80, 40), Color.GREEN));
+        DrawingUtils.assertAllPixelsOfColor("Overlay with two drawables", mViewWithOverlay,
+                Color.WHITE, colorRectangles);
+
+        // Remove the second from the overlay
+        runTestOnUiThread(() -> mViewOverlay.remove(greenDrawable));
+        colorRectangles.clear();
+        colorRectangles.add(new Pair<>(new Rect(10, 20, 60, 40), Color.RED));
+        DrawingUtils.assertAllPixelsOfColor("Overlay with one drawable", mViewWithOverlay,
+                Color.WHITE, colorRectangles);
+
+        // Clear all drawables from the overlay and test that we're back to pure white fill
+        runTestOnUiThread(() -> mViewOverlay.clear());
+        DrawingUtils.assertAllPixelsOfColor("Back to default fill", mViewWithOverlay,
+                Color.WHITE, null);
+    }
+
+    public void testOverlayDynamicChangesToDrawable() throws Throwable {
+        // Add one colored drawable to the overlay
+        final ColorDrawable drawable = new ColorDrawable(Color.RED);
+        drawable.setBounds(20, 30, 40, 50);
+        runTestOnUiThread(() -> mViewOverlay.add(drawable));
+
+        final List<Pair<Rect, Integer>> colorRectangles = new ArrayList<>();
+        colorRectangles.add(new Pair<>(new Rect(20, 30, 40, 50), Color.RED));
+        DrawingUtils.assertAllPixelsOfColor("Overlay with one red drawable", mViewWithOverlay,
+                Color.WHITE, colorRectangles);
+
+        // Update the bounds of our red drawable. Note that ideally we want to verify that
+        // ViewOverlay's internal implementation tracks the changes to the drawables and kicks
+        // off a redraw pass at some point. Here we are testing a subset of that - that the
+        // next time a redraw of View / ViewOverlay happens, it catches the new state of our
+        // original drawable.
+        runTestOnUiThread(() -> drawable.setBounds(50, 10, 80, 90));
+        colorRectangles.clear();
+        colorRectangles.add(new Pair<>(new Rect(50, 10, 80, 90), Color.RED));
+        DrawingUtils.assertAllPixelsOfColor("Red drawable moved", mViewWithOverlay,
+                Color.WHITE, colorRectangles);
+
+        // Update the color of our drawable. Same (partial) testing as before.
+        runTestOnUiThread(() -> drawable.setColor(Color.GREEN));
+        colorRectangles.clear();
+        colorRectangles.add(new Pair<>(new Rect(50, 10, 80, 90), Color.GREEN));
+        DrawingUtils.assertAllPixelsOfColor("Drawable is green now", mViewWithOverlay,
+                Color.WHITE, colorRectangles);
+    }
+
+    public void testOverlayDynamicChangesToOverlappingDrawables() throws Throwable {
+        // Add two overlapping color drawables to the overlay
+        final ColorDrawable redDrawable = new ColorDrawable(Color.RED);
+        redDrawable.setBounds(10, 20, 60, 40);
+        final ColorDrawable greenDrawable = new ColorDrawable(Color.GREEN);
+        greenDrawable.setBounds(30, 20, 80, 40);
+
+        runTestOnUiThread(
+                () -> {
+                    mViewOverlay.add(redDrawable);
+                    mViewOverlay.add(greenDrawable);
+                });
+
+        // Our overlay drawables overlap in horizontal 30-60 range. This is the same test as
+        // in testOverlayWithOverlappingDrawables
+        final List<Pair<Rect, Integer>> colorRectangles = new ArrayList<>();
+        colorRectangles.add(new Pair<>(new Rect(10, 20, 30, 40), Color.RED));
+        colorRectangles.add(new Pair<>(new Rect(30, 20, 80, 40), Color.GREEN));
+        DrawingUtils.assertAllPixelsOfColor("Overlay with two drawables", mViewWithOverlay,
+                Color.WHITE, colorRectangles);
+
+        // Now change the color of the first drawable and verify that it didn't "bump" it up
+        // in the drawing order.
+        runTestOnUiThread(() -> redDrawable.setColor(Color.BLUE));
+        colorRectangles.add(new Pair<>(new Rect(10, 20, 30, 40), Color.BLUE));
+        colorRectangles.add(new Pair<>(new Rect(30, 20, 80, 40), Color.GREEN));
+        DrawingUtils.assertAllPixelsOfColor("Overlay with two drawables", mViewWithOverlay,
+                Color.WHITE, colorRectangles);
+    }
+}
\ No newline at end of file
diff --git a/tests/tests/view/src/android/view/cts/ViewStubCtsActivity.java b/tests/tests/view/src/android/view/cts/ViewStubCtsActivity.java
index d2f2a4f..4268837 100644
--- a/tests/tests/view/src/android/view/cts/ViewStubCtsActivity.java
+++ b/tests/tests/view/src/android/view/cts/ViewStubCtsActivity.java
@@ -18,7 +18,7 @@
 
 import android.app.Activity;
 import android.os.Bundle;
-import com.android.cts.view.R;
+import android.view.cts.R;
 
 public class ViewStubCtsActivity extends Activity {
     @Override
diff --git a/tests/tests/view/src/android/view/cts/ViewStubTest.java b/tests/tests/view/src/android/view/cts/ViewStubTest.java
index c9cd44b..bdb988d 100644
--- a/tests/tests/view/src/android/view/cts/ViewStubTest.java
+++ b/tests/tests/view/src/android/view/cts/ViewStubTest.java
@@ -16,7 +16,7 @@
 
 package android.view.cts;
 
-import com.android.cts.view.R;
+import android.view.cts.R;
 
 import org.xmlpull.v1.XmlPullParser;
 
@@ -40,7 +40,7 @@
     private Activity mActivity;
 
     public ViewStubTest() {
-        super("com.android.cts.view", ViewStubCtsActivity.class);
+        super("android.view.cts", ViewStubCtsActivity.class);
     }
 
     @Override
diff --git a/tests/tests/view/src/android/view/cts/ViewTest.java b/tests/tests/view/src/android/view/cts/ViewTest.java
index 2c5b30a..426a20f 100644
--- a/tests/tests/view/src/android/view/cts/ViewTest.java
+++ b/tests/tests/view/src/android/view/cts/ViewTest.java
@@ -16,7 +16,9 @@
 
 package android.view.cts;
 
-import com.android.cts.view.R;
+import static org.mockito.Mockito.*;
+
+import android.graphics.BitmapFactory;
 import com.android.internal.view.menu.ContextMenuBuilder;
 
 import android.content.Context;
@@ -45,6 +47,7 @@
 import android.text.format.DateUtils;
 import android.util.AttributeSet;
 import android.util.Log;
+import android.util.Pair;
 import android.util.SparseArray;
 import android.util.Xml;
 import android.view.ActionMode;
@@ -57,6 +60,7 @@
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MotionEvent;
+import android.view.PointerIcon;
 import android.view.SoundEffectConstants;
 import android.view.TouchDelegate;
 import android.view.View;
@@ -71,6 +75,7 @@
 import android.view.ViewConfiguration;
 import android.view.ViewGroup;
 import android.view.ViewParent;
+import android.view.ViewTreeObserver;
 import android.view.WindowManager;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.animation.AlphaAnimation;
@@ -84,9 +89,12 @@
 import android.widget.LinearLayout;
 import android.widget.ListView;
 
+import java.lang.reflect.Constructor;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 
 /**
  * Test {@link View}.
@@ -146,6 +154,38 @@
         }
     }
 
+    // Test that validates that Views can be constructed on a thread that
+    // does not have a Looper. Necessary for async inflation
+    private Pair<Class<?>, Throwable> sCtorException = null;
+    public void testConstructor2() throws Exception {
+        final Object[] args = new Object[] { mActivity, null };
+        final CountDownLatch latch = new CountDownLatch(1);
+        sCtorException = null;
+        new Thread() {
+            @Override
+            public void run() {
+                final Class<?>[] ctorSignature = new Class[] {
+                        Context.class, AttributeSet.class};
+                for (Class<?> clazz : ASYNC_INFLATE_VIEWS) {
+                    try {
+                        Constructor<?> constructor = clazz.getConstructor(ctorSignature);
+                        constructor.setAccessible(true);
+                        constructor.newInstance(args);
+                    } catch (Throwable t) {
+                        sCtorException = new Pair<Class<?>, Throwable>(clazz, t);
+                        break;
+                    }
+                }
+                latch.countDown();
+            }
+        }.start();
+        latch.await();
+        if (sCtorException != null) {
+            throw new AssertionError("Failed to inflate "
+                    + sCtorException.first.getName(), sCtorException.second);
+        }
+    }
+
     public void testGetContext() {
         View view = new View(mActivity);
         assertSame(mActivity, view.getContext());
@@ -221,6 +261,7 @@
 
         // check whether it has started
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.startAnimation(animation);
             }
@@ -289,6 +330,7 @@
         final int WRAP_CONTENT = ViewGroup.LayoutParams.WRAP_CONTENT;
         final int btnHeight = view.getHeight()/3;
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 mActivity.addContentView(button,
                         new LinearLayout.LayoutParams(WRAP_CONTENT, btnHeight));
@@ -311,6 +353,104 @@
         assertNull(view.getTouchDelegate());
     }
 
+    public void testMouseEventCallsGetPointerIcon() {
+        final MockView view = (MockView) mActivity.findViewById(R.id.mock_view);
+
+        final int[] xy = new int[2];
+        view.getLocationOnScreen(xy);
+        final int viewWidth = view.getWidth();
+        final int viewHeight = view.getHeight();
+        float x = xy[0] + viewWidth / 2.0f;
+        float y = xy[1] + viewHeight / 2.0f;
+
+        long eventTime = SystemClock.uptimeMillis();
+
+        MotionEvent.PointerCoords[] pointerCoords = new MotionEvent.PointerCoords[1];
+        pointerCoords[0] = new MotionEvent.PointerCoords();
+        pointerCoords[0].x = x;
+        pointerCoords[0].y = y;
+
+        final int[] pointerIds = new int[1];
+        pointerIds[0] = 0;
+
+        MotionEvent event = MotionEvent.obtain(0, eventTime, MotionEvent.ACTION_HOVER_MOVE,
+                1, pointerIds, pointerCoords, 0, 0, 0, 0, 0, InputDevice.SOURCE_MOUSE, 0);
+        getInstrumentation().sendPointerSync(event);
+        getInstrumentation().waitForIdleSync();
+
+        assertTrue(view.hasCalledGetPointerIcon());
+
+        final MockView view2 = (MockView) mActivity.findViewById(R.id.scroll_view);
+        assertFalse(view2.hasCalledGetPointerIcon());
+    }
+
+    public void testAccessPointerShape() {
+        View view = mActivity.findViewById(R.id.pointer_icon_layout);
+        MotionEvent event = MotionEvent.obtain(0, 0, MotionEvent.ACTION_HOVER_MOVE,
+                                               view.getX(), view.getY(), 0);
+
+        // First view has pointerShape="help"
+        assertEquals(PointerIcon.getSystemIcon(mActivity, PointerIcon.STYLE_HELP),
+                     view.getPointerIcon(event, 0, 0));
+
+        // Second view inherits pointerShape="crosshair" from the parent
+        event.setLocation(0, 21);
+        assertEquals(PointerIcon.getSystemIcon(mActivity, PointerIcon.STYLE_CROSSHAIR),
+                     view.getPointerIcon(event, 0, 21));
+
+        // Third view has custom pointer shape defined in a resource.
+        event.setLocation(0, 41);
+        assertNotNull(view.getPointerIcon(event, 0, 41));
+
+        // Parent view has pointerShape="crosshair"
+        event.setLocation(0, 61);
+        assertEquals(PointerIcon.getSystemIcon(mActivity, PointerIcon.STYLE_CROSSHAIR),
+                     view.getPointerIcon(event, 0, 61));
+
+        // Outside of the parent view, no pointer shape defined.
+        event.setLocation(0, 71);
+        assertNull(view.getPointerIcon(event, 0, 71));
+
+        view.setPointerIcon(PointerIcon.getSystemIcon(mActivity, PointerIcon.STYLE_TEXT));
+        assertEquals(PointerIcon.getSystemIcon(mActivity, PointerIcon.STYLE_TEXT),
+                     view.getPointerIcon(event, 0,71));
+        event.recycle();
+    }
+
+    public void testCreatePointerIcons() {
+        assertSystemPointerIcon(PointerIcon.STYLE_NULL);
+        assertSystemPointerIcon(PointerIcon.STYLE_DEFAULT);
+        assertSystemPointerIcon(PointerIcon.STYLE_ARROW);
+        assertSystemPointerIcon(PointerIcon.STYLE_CONTEXT_MENU);
+        assertSystemPointerIcon(PointerIcon.STYLE_HAND);
+        assertSystemPointerIcon(PointerIcon.STYLE_HELP);
+        assertSystemPointerIcon(PointerIcon.STYLE_WAIT);
+        assertSystemPointerIcon(PointerIcon.STYLE_CELL);
+        assertSystemPointerIcon(PointerIcon.STYLE_CROSSHAIR);
+        assertSystemPointerIcon(PointerIcon.STYLE_TEXT);
+        assertSystemPointerIcon(PointerIcon.STYLE_VERTICAL_TEXT);
+        assertSystemPointerIcon(PointerIcon.STYLE_ALIAS);
+        assertSystemPointerIcon(PointerIcon.STYLE_COPY);
+        assertSystemPointerIcon(PointerIcon.STYLE_NO_DROP);
+        assertSystemPointerIcon(PointerIcon.STYLE_ALL_SCROLL);
+        assertSystemPointerIcon(PointerIcon.STYLE_HORIZONTAL_DOUBLE_ARROW);
+        assertSystemPointerIcon(PointerIcon.STYLE_VERTICAL_DOUBLE_ARROW);
+        assertSystemPointerIcon(PointerIcon.STYLE_TOP_RIGHT_DIAGONAL_DOUBLE_ARROW);
+        assertSystemPointerIcon(PointerIcon.STYLE_TOP_LEFT_DIAGONAL_DOUBLE_ARROW);
+        assertSystemPointerIcon(PointerIcon.STYLE_ZOOM_IN);
+        assertSystemPointerIcon(PointerIcon.STYLE_ZOOM_OUT);
+        assertSystemPointerIcon(PointerIcon.STYLE_GRAB);
+
+        assertNotNull(PointerIcon.loadCustomIcon(mResources, R.drawable.custom_pointer_icon));
+
+        Bitmap bitmap = BitmapFactory.decodeResource(mResources, R.drawable.icon_blue);
+        assertNotNull(PointerIcon.createCustomIcon(bitmap, 0, 0));
+    }
+
+    private void assertSystemPointerIcon(int style) {
+        assertNotNull(PointerIcon.getSystemIcon(mActivity, style));
+    }
+
     @UiThreadTest
     public void testAccessTag() {
         ViewGroup viewGroup = (ViewGroup) mActivity.findViewById(R.id.viewlayout_root);
@@ -347,6 +487,7 @@
         assertEquals(-1, mockView.getOldWOnSizeChanged());
         assertEquals(-1, mockView.getOldHOnSizeChanged());
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 viewGroup.addView(mockView);
             }
@@ -365,6 +506,7 @@
         int oldh = view.getHeight();
         final LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(200, 100);
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.setLayoutParams(layoutParams);
             }
@@ -439,6 +581,7 @@
         view.reset();
         assertFalse(view.hasCalledOnLayout());
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.requestLayout();
             }
@@ -587,6 +730,7 @@
         // width is 0
         final LinearLayout.LayoutParams layoutParams1 = new LinearLayout.LayoutParams(0, 300);
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.setLayoutParams(layoutParams1);
             }
@@ -597,6 +741,7 @@
         // height is -10
         final LinearLayout.LayoutParams layoutParams2 = new LinearLayout.LayoutParams(200, -10);
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.setLayoutParams(layoutParams2);
             }
@@ -611,6 +756,7 @@
         final LinearLayout.LayoutParams layoutParams3 =
                 new LinearLayout.LayoutParams(halfWidth, halfHeight);
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.setLayoutParams(layoutParams3);
             }
@@ -641,6 +787,7 @@
         // width is 0
         final LinearLayout.LayoutParams layoutParams1 = new LinearLayout.LayoutParams(0, 300);
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.setLayoutParams(layoutParams1);
             }
@@ -651,6 +798,7 @@
         // height is -10
         final LinearLayout.LayoutParams layoutParams2 = new LinearLayout.LayoutParams(200, -10);
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.setLayoutParams(layoutParams2);
             }
@@ -665,6 +813,7 @@
         final LinearLayout.LayoutParams layoutParams3 =
                 new LinearLayout.LayoutParams(halfWidth, halfHeight);
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.setLayoutParams(layoutParams3);
             }
@@ -685,6 +834,7 @@
         assertEquals(view.getWidth(), view.computeHorizontalScrollExtent());
 
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.scrollTo(12, 0);
             }
@@ -695,6 +845,7 @@
         assertEquals(view.getWidth(), view.computeHorizontalScrollExtent());
 
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.scrollBy(12, 0);
             }
@@ -707,6 +858,7 @@
         int newWidth = 200;
         final LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(newWidth, 100);
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.setLayoutParams(layoutParams);
             }
@@ -727,6 +879,7 @@
 
         final int scrollToY = 34;
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.scrollTo(0, scrollToY);
             }
@@ -738,6 +891,7 @@
 
         final int scrollByY = 200;
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.scrollBy(0, scrollByY);
             }
@@ -750,6 +904,7 @@
         int newHeight = 333;
         final LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(200, newHeight);
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.setLayoutParams(layoutParams);
             }
@@ -770,6 +925,7 @@
         assertEquals(0f, view.getBottomFadingEdgeStrength());
 
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.scrollTo(10, 10);
             }
@@ -781,6 +937,7 @@
         assertEquals(0f, view.getBottomFadingEdgeStrength());
 
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.scrollTo(-10, -10);
             }
@@ -937,7 +1094,7 @@
 
     public void testAddFocusables() {
         View view = new View(mActivity);
-        ArrayList<View> viewList = new ArrayList<View>();
+        ArrayList<View> viewList = new ArrayList<>();
 
         // view is not focusable
         assertFalse(view.isFocusable());
@@ -1247,6 +1404,24 @@
         assertTrue(mMockParent.hasShowContextMenuForChild());
     }
 
+    public void testShowContextMenuXY() {
+        MockViewParent parent = new MockViewParent(mActivity);
+        MockView view = new MockView(mActivity);
+
+        assertNull(view.getParent());
+        try {
+            view.showContextMenu(0, 0);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+        }
+
+        view.setParent(parent);
+        assertFalse(parent.hasShowContextMenuForChildXY());
+
+        assertFalse(view.showContextMenu(0, 0));
+        assertTrue(parent.hasShowContextMenuForChildXY());
+    }
+
     public void testFitSystemWindows() {
         final XmlResourceParser parser = mResources.getLayout(R.layout.view_layout);
         final AttributeSet attrs = Xml.asAttributeSet(parser);
@@ -1315,6 +1490,43 @@
         assertTrue(listener.hasOnLongClick());
     }
 
+    public void testPerformLongClickXY() {
+        MockViewParent parent = new MockViewParent(mActivity);
+        MockView view = new MockView(mActivity);
+
+        try {
+            view.performLongClick(0, 0);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+        }
+
+        parent.addView(view);
+        assertFalse(parent.hasShowContextMenuForChildXY());
+
+        // Verify default context menu behavior.
+        assertFalse(view.performLongClick(0, 0));
+        assertTrue(parent.hasShowContextMenuForChildXY());
+    }
+
+    public void testPerformLongClickXY_WithListener() {
+        OnLongClickListener listener = mock(OnLongClickListener.class);
+        when(listener.onLongClick(any(View.class))).thenReturn(true);
+
+        MockViewParent parent = new MockViewParent(mActivity);
+        MockView view = new MockView(mActivity);
+
+        view.setOnLongClickListener(listener);
+        verify(listener, never()).onLongClick(any(View.class));
+
+        parent.addView(view);
+        assertFalse(parent.hasShowContextMenuForChildXY());
+
+        // Verify listener is preferred over default context menu.
+        assertTrue(view.performLongClick(0, 0));
+        assertFalse(parent.hasShowContextMenuForChildXY());
+        verify(listener).onLongClick(view);
+    }
+
     public void testSetOnLongClickListener() {
         MockView view = new MockView(mActivity);
         view.setParent(mMockParent);
@@ -1443,6 +1655,7 @@
 
         view.reset();
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.requestLayout();
             }
@@ -1455,6 +1668,7 @@
         view.reset();
         final LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(200, 100);
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.setLayoutParams(layoutParams);
             }
@@ -1512,6 +1726,7 @@
         View view = new View(mActivity);
         Drawable drawable = new StateListDrawable();
         Runnable what = new Runnable() {
+            @Override
             public void run() {
                 // do nothing
             }
@@ -1539,6 +1754,7 @@
         View view = new View(mActivity);
         Drawable drawable = new StateListDrawable();
         Runnable what = new Runnable() {
+            @Override
             public void run() {
                 // do nothing
             }
@@ -1699,7 +1915,6 @@
     }
 
     public void testGetLocationOnScreen() {
-        View view = new View(mActivity);
         int[] location = new int[] { -1, -1 };
 
         // mAttachInfo is not null
@@ -1732,7 +1947,7 @@
 
     public void testAddTouchables() {
         View view = new View(mActivity);
-        ArrayList<View> result = new ArrayList<View>();
+        ArrayList<View> result = new ArrayList<>();
         assertEquals(0, result.size());
 
         view.addTouchables(result);
@@ -1878,6 +2093,7 @@
     public void testOnKeyShortcut() throws Throwable {
         final MockView view = (MockView) mActivity.findViewById(R.id.mock_view);
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.setFocusable(true);
                 view.requestFocus();
@@ -1896,6 +2112,7 @@
     public void testOnKeyMultiple() throws Throwable {
         final MockView view = (MockView) mActivity.findViewById(R.id.mock_view);
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.setFocusable(true);
             }
@@ -1925,6 +2142,7 @@
     public void testOnTrackballEvent() throws Throwable {
         final MockView view = (MockView) mActivity.findViewById(R.id.mock_view);
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.setEnabled(true);
                 view.setFocusable(true);
@@ -1976,6 +2194,7 @@
     public void testDispatchUnhandledMove() throws Throwable {
         final MockView view = (MockView) mActivity.findViewById(R.id.mock_view);
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.setFocusable(true);
                 view.requestFocus();
@@ -1994,6 +2213,7 @@
         final ViewGroup viewGroup = (ViewGroup) mActivity.findViewById(R.id.viewlayout_root);
 
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 viewGroup.addView(mockView);
             }
@@ -2003,6 +2223,7 @@
 
         mockView.reset();
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 getActivity().setVisible(false);
             }
@@ -2013,6 +2234,7 @@
 
         mockView.reset();
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 getActivity().setVisible(true);
             }
@@ -2023,6 +2245,7 @@
 
         mockView.reset();
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 viewGroup.removeView(mockView);
             }
@@ -2043,6 +2266,7 @@
 
         final LinearLayout.LayoutParams layoutParams1 = new LinearLayout.LayoutParams(0, 300);
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.setLayoutParams(layoutParams1);
             }
@@ -2052,6 +2276,7 @@
 
         final LinearLayout.LayoutParams layoutParams2 = new LinearLayout.LayoutParams(200, -10);
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.setLayoutParams(layoutParams2);
             }
@@ -2066,6 +2291,7 @@
         final LinearLayout.LayoutParams layoutParams3 =
                 new LinearLayout.LayoutParams(halfWidth, halfHeight);
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.setLayoutParams(layoutParams3);
                 view.scrollTo(20, -30);
@@ -2124,7 +2350,7 @@
     public void testSaveAndRestoreHierarchyState() {
         int viewId = R.id.mock_view;
         MockView view = (MockView) mActivity.findViewById(viewId);
-        SparseArray<Parcelable> container = new SparseArray<Parcelable>();
+        SparseArray<Parcelable> container = new SparseArray<>();
         view.saveHierarchyState(container);
         assertTrue(view.hasCalledDispatchSaveInstanceState());
         assertTrue(view.hasCalledOnSaveInstanceState());
@@ -2168,6 +2394,7 @@
     public void testOnKeyDownOrUp() throws Throwable {
         final MockView view = (MockView) mActivity.findViewById(R.id.mock_view);
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.setFocusable(true);
                 view.requestFocus();
@@ -2194,6 +2421,7 @@
         assertTrue(view.hasCalledOnKeyDown());
 
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.setEnabled(true);
                 view.setClickable(true);
@@ -2230,6 +2458,74 @@
         assertTrue(listener.hasOnClick());
     }
 
+    private void checkBounds(final ViewGroup viewGroup, final View view,
+            final CountDownLatch countDownLatch, final int left, final int top,
+            final int width, final int height) {
+        viewGroup.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
+            @Override
+            public boolean onPreDraw() {
+                assertEquals(left, view.getLeft());
+                assertEquals(top, view.getTop());
+                assertEquals(width, view.getWidth());
+                assertEquals(height, view.getHeight());
+                countDownLatch.countDown();
+                viewGroup.getViewTreeObserver().removeOnPreDrawListener(this);
+                return true;
+            }
+        });
+    }
+
+    public void testAddRemoveAffectsWrapContentLayout() throws Throwable {
+        final int childWidth = 100;
+        final int childHeight = 200;
+        final int parentHeight = 400;
+        final MockLinearLayout parent = new MockLinearLayout(mActivity);
+        ViewGroup.LayoutParams parentParams = new ViewGroup.LayoutParams(
+                ViewGroup.LayoutParams.WRAP_CONTENT, parentHeight);
+        parent.setLayoutParams(parentParams);
+        final MockView child = new MockView(mActivity);
+        child.setBackgroundColor(Color.GREEN);
+        ViewGroup.LayoutParams childParams = new ViewGroup.LayoutParams(childWidth, childHeight);
+        child.setLayoutParams(childParams);
+        final ViewGroup viewGroup = (ViewGroup) mActivity.findViewById(R.id.viewlayout_root);
+
+        // Idea:
+        // Add the wrap_content parent view to the hierarchy (removing other views as they
+        // are not needed), test that parent is 0xparentHeight
+        // Add the child view to the parent, test that parent has same width as child
+        // Remove the child view from the parent, test that parent is 0xparentHeight
+        final CountDownLatch countDownLatch1 = new CountDownLatch(1);
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                viewGroup.removeAllViews();
+                viewGroup.addView(parent);
+                checkBounds(viewGroup, parent, countDownLatch1, 0, 0, 0, parentHeight);
+            }
+        });
+        countDownLatch1.await(500, TimeUnit.MILLISECONDS);
+
+        final CountDownLatch countDownLatch2 = new CountDownLatch(1);
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                parent.addView(child);
+                checkBounds(viewGroup, parent, countDownLatch2, 0, 0, childWidth, parentHeight);
+            }
+        });
+        countDownLatch2.await(500, TimeUnit.MILLISECONDS);
+
+        final CountDownLatch countDownLatch3 = new CountDownLatch(1);
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                parent.removeView(child);
+                checkBounds(viewGroup, parent, countDownLatch3, 0, 0, 0, parentHeight);
+            }
+        });
+        countDownLatch3.await(500, TimeUnit.MILLISECONDS);
+    }
+
     @UiThreadTest
     public void testDispatchKeyEvent() {
         MockView view = (MockView) mActivity.findViewById(R.id.mock_view);
@@ -2338,6 +2634,7 @@
 
         view.reset();
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.invalidate();
             }
@@ -2352,6 +2649,7 @@
 
         view.reset();
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.setVisibility(View.INVISIBLE);
                 view.invalidate();
@@ -2375,6 +2673,7 @@
         final Rect dirty = new Rect(view.getLeft() + 1, view.getTop() + 1,
                 view.getLeft() + view.getWidth() / 2, view.getTop() + view.getHeight() / 2);
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.invalidate(dirty);
             }
@@ -2389,6 +2688,7 @@
 
         view.reset();
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.setVisibility(View.INVISIBLE);
                 view.invalidate(dirty);
@@ -2406,6 +2706,7 @@
         final Rect dirty = new Rect(view.getLeft() + 1, view.getTop() + 1,
                 view.getLeft() + view.getWidth() / 2, view.getTop() + view.getHeight() / 2);
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.invalidate(dirty.left, dirty.top, dirty.right, dirty.bottom);
             }
@@ -2420,6 +2721,7 @@
 
         view.reset();
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.setVisibility(View.INVISIBLE);
                 view.invalidate(dirty.left, dirty.top, dirty.right, dirty.bottom);
@@ -2436,6 +2738,7 @@
 
         view.reset();
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.setBackgroundDrawable(d1);
                 view.invalidateDrawable(d1);
@@ -2451,6 +2754,7 @@
 
         view.reset();
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.invalidateDrawable(d2);
             }
@@ -2525,6 +2829,7 @@
         }.run();
 
         new PollingCheck() {
+            @Override
             protected boolean check() {
                 return view.hasCalledOnWindowFocusChanged();
             }
@@ -2537,7 +2842,7 @@
         assertFalse(view.hasCalledOnWindowFocusChanged());
         assertFalse(view.hasCalledDispatchWindowFocusChanged());
 
-        CtsActivity activity = launchActivity("com.android.cts.view", CtsActivity.class, null);
+        CtsActivity activity = launchActivity("android.view.cts", CtsActivity.class, null);
 
         // Wait until the window lost focus.
         new PollingCheck(TIMEOUT_DELTA) {
@@ -2556,6 +2861,7 @@
     public void testDraw() throws Throwable {
         final MockView view = (MockView) mActivity.findViewById(R.id.mock_view);
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.requestLayout();
             }
@@ -2614,15 +2920,7 @@
         Rect rectangle = new Rect();
         MockViewGroupParent parent = new MockViewGroupParent(mActivity);
 
-        final Rect requestedRect = new Rect();
-        MockViewGroupParent grandparent = new MockViewGroupParent(mActivity) {
-            @Override
-            public boolean requestChildRectangleOnScreen(View child, Rect rectangle,
-                    boolean immediate) {
-                requestedRect.set(rectangle);
-                return super.requestChildRectangleOnScreen(child, rectangle, immediate);
-            }
-        };
+        MockViewGroupParent grandparent = new MockViewGroupParent(mActivity);
 
         // parent is null
         assertFalse(view.requestRectangleOnScreen(rectangle));
@@ -2644,10 +2942,12 @@
         assertTrue(parent.hasRequestChildRectangleOnScreen());
         assertTrue(grandparent.hasRequestChildRectangleOnScreen());
 
-        assertEquals(-1, requestedRect.left);
-        assertEquals(-2, requestedRect.top);
-        assertEquals(-1, requestedRect.right);
-        assertEquals(-2, requestedRect.bottom);
+        // it is grand parent's responsibility to check parent's scroll offset
+        final Rect requestedRect = grandparent.getLastRequestedChildRectOnScreen();
+        assertEquals(0, requestedRect.left);
+        assertEquals(0, requestedRect.top);
+        assertEquals(0, requestedRect.right);
+        assertEquals(0, requestedRect.bottom);
 
         try {
             view.requestRectangleOnScreen(null);
@@ -2656,6 +2956,70 @@
         }
     }
 
+    public void testRequestRectangleOnScreen3() {
+        requestRectangleOnScreenTest(false);
+    }
+
+    public void testRequestRectangleOnScreen4() {
+        requestRectangleOnScreenTest(true);
+    }
+
+    public void testRequestRectangleOnScreen5() {
+        MockView child = new MockView(mActivity);
+
+        MockViewGroupParent parent = new MockViewGroupParent(mActivity);
+        MockViewGroupParent grandParent = new MockViewGroupParent(mActivity);
+        parent.addView(child);
+        grandParent.addView(parent);
+
+        child.layout(5, 6, 7, 9);
+        child.requestRectangleOnScreen(new Rect(10, 10, 12, 13));
+        assertEquals(new Rect(10, 10, 12, 13), parent.getLastRequestedChildRectOnScreen());
+        assertEquals(new Rect(15, 16, 17, 19), grandParent.getLastRequestedChildRectOnScreen());
+
+        child.scrollBy(1, 2);
+        child.requestRectangleOnScreen(new Rect(10, 10, 12, 13));
+        assertEquals(new Rect(10, 10, 12, 13), parent.getLastRequestedChildRectOnScreen());
+        assertEquals(new Rect(14, 14, 16, 17), grandParent.getLastRequestedChildRectOnScreen());
+    }
+
+    private void requestRectangleOnScreenTest(boolean scrollParent) {
+        MockView child = new MockView(mActivity);
+
+        MockViewGroupParent parent = new MockViewGroupParent(mActivity);
+        MockViewGroupParent grandParent = new MockViewGroupParent(mActivity);
+        parent.addView(child);
+        grandParent.addView(parent);
+
+        child.requestRectangleOnScreen(new Rect(10, 10, 12, 13));
+        assertEquals(new Rect(10, 10, 12, 13), parent.getLastRequestedChildRectOnScreen());
+        assertEquals(new Rect(10, 10, 12, 13), grandParent.getLastRequestedChildRectOnScreen());
+
+        child.scrollBy(1, 2);
+        if (scrollParent) {
+            // should not affect anything
+            parent.scrollBy(25, 30);
+            parent.layout(3, 5, 7, 9);
+        }
+        child.requestRectangleOnScreen(new Rect(10, 10, 12, 13));
+        assertEquals(new Rect(10, 10, 12, 13), parent.getLastRequestedChildRectOnScreen());
+        assertEquals(new Rect(9, 8, 11, 11), grandParent.getLastRequestedChildRectOnScreen());
+    }
+
+    public void testRequestRectangleOnScreenWithScale() {
+        // scale should not affect the rectangle
+        MockView child = new MockView(mActivity);
+        child.setScaleX(2);
+        child.setScaleX(3);
+        MockViewGroupParent parent = new MockViewGroupParent(mActivity);
+        MockViewGroupParent grandParent = new MockViewGroupParent(mActivity);
+        parent.addView(child);
+        grandParent.addView(parent);
+        child.requestRectangleOnScreen(new Rect(10, 10, 12, 13));
+        assertEquals(new Rect(10, 10, 12, 13), parent.getLastRequestedChildRectOnScreen());
+        assertEquals(new Rect(10, 10, 12, 13), grandParent.getLastRequestedChildRectOnScreen());
+    }
+
     /**
      * For the duration of the tap timeout we are in a 'prepressed' state
      * to differentiate between taps and touch scrolls.
@@ -2682,6 +3046,7 @@
         assertTrue(view.hasCalledOnTouchEvent());
 
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.setEnabled(true);
                 view.setClickable(true);
@@ -2971,6 +3336,7 @@
                 Context.INPUT_METHOD_SERVICE);
         final LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(300, 500);
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 mockView.setBackgroundDrawable(d);
                 mockView.setHorizontalFadingEdgeEnabled(true);
@@ -2990,6 +3356,7 @@
         // FIXME: why the size of view doesn't change?
 
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 imm.hideSoftInputFromInputMethod(mockView.getWindowToken(), 0);
             }
@@ -3001,6 +3368,7 @@
         final MockView mockView = (MockView) mActivity.findViewById(R.id.mock_view);
         final View fitWindowsView = mActivity.findViewById(R.id.fit_windows);
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 mockView.setFocusableInTouchMode(true);
                 fitWindowsView.setFocusable(true);
@@ -3021,6 +3389,7 @@
         assertFalse(fitWindowsView.isFocused());
         assertFalse(mockView.isFocused());
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 mockView.requestFocus();
             }
@@ -3028,6 +3397,7 @@
         getInstrumentation().waitForIdleSync();
         assertTrue(mockView.isFocused());
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 fitWindowsView.requestFocus();
             }
@@ -3042,6 +3412,7 @@
         assertTrue(mockView.isFocused());
         assertFalse(fitWindowsView.isFocused());
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 fitWindowsView.requestFocus();
             }
@@ -3195,9 +3566,10 @@
         items.add("1");
         items.add("2");
         items.add("3");
-        final Adapter<String> adapter = new Adapter<String>(mActivity, 0, items);
+        final Adapter<String> adapter = new Adapter<>(mActivity, 0, items);
 
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 mActivity.setContentView(listView);
                 listView.setAdapter(adapter);
@@ -3207,6 +3579,7 @@
         final MockView focusChild = (MockView) listView.getChildAt(0);
 
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 focusChild.requestFocus();
             }
@@ -3215,6 +3588,7 @@
         assertTrue(listView.getChildAt(0).isFocused());
 
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 listView.detachViewFromParent(focusChild);
             }
@@ -3264,7 +3638,7 @@
     }
 
     private static class Adapter<T> extends ArrayAdapter<T> {
-        ArrayList<MockView> views = new ArrayList<MockView>();
+        ArrayList<MockView> views = new ArrayList<>();
 
         public Adapter(Context context, int textViewResourceId, List<T> objects) {
             super(context, textViewResourceId, objects);
@@ -3294,6 +3668,7 @@
         final MockView view = (MockView) mActivity.findViewById(R.id.mock_view);
 
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.setFocusable(true);
                 view.requestFocus();
@@ -3490,6 +3865,210 @@
         assertNull(mode);
     }
 
+    public void testPointerCapture() throws Throwable {
+        final ViewGroup viewGroup = (ViewGroup) mActivity.findViewById(R.id.viewlayout_root);
+
+        long downTime = SystemClock.uptimeMillis();
+        int[] location = new int[2];
+        viewGroup.getLocationOnScreen(location);
+        float x = location[0] + viewGroup.getWidth() / 2;
+        float y = location[1] + viewGroup.getHeight() / 2;
+        final MotionEvent dummyMotion = MotionEvent.obtain(
+            downTime, downTime, MotionEvent.ACTION_HOVER_MOVE, x, y, 0);
+        dummyMotion.setSource(InputDevice.SOURCE_MOUSE);
+        final MockView view = (MockView)mActivity.findViewById(R.id.mock_view);
+
+        assertFalse(view.hasPointerCapture());
+
+        view.setPointerCapture();
+        assertTrue(view.hasPointerCapture());
+        getInstrumentation().sendPointerSync(dummyMotion);
+        getInstrumentation().waitForIdleSync();
+        assertTrue(view.hasCalledOnHoverEvent());
+        view.reset();
+
+        view.releasePointerCapture();
+        assertFalse(view.hasPointerCapture());
+
+        final MockView view2 = new MockView(mActivity);
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                viewGroup.addView(view2);
+            }
+        });
+        getInstrumentation().waitForIdleSync();
+
+        view.setPointerCapture();
+        assertTrue(view.hasPointerCapture());
+        assertFalse(view2.hasPointerCapture());
+
+        getInstrumentation().sendPointerSync(dummyMotion);
+        getInstrumentation().waitForIdleSync();
+        assertTrue(view.hasCalledOnHoverEvent());
+        assertFalse(view2.hasCalledOnHoverEvent());
+        view.reset();
+
+        view2.setPointerCapture();
+        assertFalse(view.hasPointerCapture());
+        assertTrue(view2.hasPointerCapture());
+
+        getInstrumentation().sendPointerSync(dummyMotion);
+        getInstrumentation().waitForIdleSync();
+        assertFalse(view.hasCalledOnHoverEvent());
+        assertTrue(view2.hasCalledOnHoverEvent());
+
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                viewGroup.removeView(view2);
+            }
+        });
+        getInstrumentation().waitForIdleSync();
+        assertFalse(view.hasPointerCapture());
+        assertFalse(view2.hasPointerCapture());
+
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                viewGroup.addView(view2);
+            }
+        });
+        getInstrumentation().waitForIdleSync();
+        assertFalse(view.hasPointerCapture());
+        assertFalse(view2.hasPointerCapture());
+    }
+
+    public void testVisibilityAggregated() throws Throwable {
+        final View grandparent = mActivity.findViewById(R.id.viewlayout_root);
+        final View parent = mActivity.findViewById(R.id.aggregate_visibility_parent);
+        final MockView mv = (MockView) mActivity.findViewById(R.id.mock_view_aggregate_visibility);
+
+        assertEquals(parent, mv.getParent());
+        assertEquals(grandparent, parent.getParent());
+
+        assertTrue(mv.hasCalledOnVisibilityAggregated());
+        assertTrue(mv.getLastAggregatedVisibility());
+
+        final Runnable reset = new Runnable() {
+            @Override
+            public void run() {
+                grandparent.setVisibility(View.VISIBLE);
+                parent.setVisibility(View.VISIBLE);
+                mv.setVisibility(View.VISIBLE);
+                mv.reset();
+            }
+        };
+
+        runTestOnUiThread(reset);
+
+        setVisibilityOnUiThread(parent, View.GONE);
+
+        assertTrue(mv.hasCalledOnVisibilityAggregated());
+        assertFalse(mv.getLastAggregatedVisibility());
+
+        runTestOnUiThread(reset);
+
+        setVisibilityOnUiThread(grandparent, View.GONE);
+
+        assertTrue(mv.hasCalledOnVisibilityAggregated());
+        assertFalse(mv.getLastAggregatedVisibility());
+
+        runTestOnUiThread(reset);
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                grandparent.setVisibility(View.GONE);
+                parent.setVisibility(View.GONE);
+                mv.setVisibility(View.VISIBLE);
+
+                grandparent.setVisibility(View.VISIBLE);
+            }
+        });
+
+        assertTrue(mv.hasCalledOnVisibilityAggregated());
+        assertFalse(mv.getLastAggregatedVisibility());
+
+        runTestOnUiThread(reset);
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                grandparent.setVisibility(View.GONE);
+                parent.setVisibility(View.INVISIBLE);
+
+                grandparent.setVisibility(View.VISIBLE);
+            }
+        });
+
+        assertTrue(mv.hasCalledOnVisibilityAggregated());
+        assertFalse(mv.getLastAggregatedVisibility());
+
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                parent.setVisibility(View.VISIBLE);
+            }
+        });
+
+        assertTrue(mv.getLastAggregatedVisibility());
+    }
+
+    public void testOverlappingRendering() {
+        View overlappingUnsetView = mActivity.findViewById(R.id.overlapping_rendering_unset);
+        View overlappingFalseView = mActivity.findViewById(R.id.overlapping_rendering_false);
+        View overlappingTrueView = mActivity.findViewById(R.id.overlapping_rendering_true);
+
+        assertTrue(overlappingUnsetView.hasOverlappingRendering());
+        assertTrue(overlappingUnsetView.getHasOverlappingRendering());
+        overlappingUnsetView.forceHasOverlappingRendering(false);
+        assertTrue(overlappingUnsetView.hasOverlappingRendering());
+        assertFalse(overlappingUnsetView.getHasOverlappingRendering());
+        overlappingUnsetView.forceHasOverlappingRendering(true);
+        assertTrue(overlappingUnsetView.hasOverlappingRendering());
+        assertTrue(overlappingUnsetView.getHasOverlappingRendering());
+
+        assertTrue(overlappingTrueView.hasOverlappingRendering());
+        assertTrue(overlappingTrueView.getHasOverlappingRendering());
+
+        assertTrue(overlappingFalseView.hasOverlappingRendering());
+        assertFalse(overlappingFalseView.getHasOverlappingRendering());
+
+        View overridingView = new MockOverlappingRenderingSubclass(mActivity, false);
+        assertFalse(overridingView.hasOverlappingRendering());
+
+        overridingView = new MockOverlappingRenderingSubclass(mActivity, true);
+        assertTrue(overridingView.hasOverlappingRendering());
+        overridingView.forceHasOverlappingRendering(false);
+        assertFalse(overridingView.getHasOverlappingRendering());
+        assertTrue(overridingView.hasOverlappingRendering());
+        overridingView.forceHasOverlappingRendering(true);
+        assertTrue(overridingView.getHasOverlappingRendering());
+        assertTrue(overridingView.hasOverlappingRendering());
+    }
+
+    private void setVisibilityOnUiThread(final View view, final int visibility) throws Throwable {
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                view.setVisibility(visibility);
+            }
+        });
+    }
+
+    private static class MockOverlappingRenderingSubclass extends View {
+        boolean mOverlap;
+
+        public MockOverlappingRenderingSubclass(Context context, boolean overlap) {
+            super(context);
+            mOverlap = overlap;
+        }
+
+        @Override
+        public boolean hasOverlappingRendering() {
+            return mOverlap;
+        }
+    }
+
     private static class MockViewGroup extends ViewGroup {
         boolean isStartActionModeForChildCalled = false;
         int startActionModeForChildType = ActionMode.TYPE_PRIMARY;
@@ -3677,19 +4256,16 @@
     }
 
     private final static class MockViewParent extends ViewGroup {
-        private boolean mHasClearChildFocus = false;
         private boolean mHasRequestLayout = false;
         private boolean mHasCreateContextMenu = false;
         private boolean mHasShowContextMenuForChild = false;
-        private boolean mHasGetChildVisibleRect = false;
-        private boolean mHasInvalidateChild = false;
-        private boolean mHasOnCreateDrawableState = false;
+        private boolean mHasShowContextMenuForChildXY = false;
         private boolean mHasChildDrawableStateChanged = false;
         private boolean mHasBroughtChildToFront = false;
-        private Rect mTempRect;
 
         private final static int[] DEFAULT_PARENT_STATE_SET = new int[] { 789 };
 
+        @Override
         public boolean requestChildRectangleOnScreen(View child, Rect rectangle,
                 boolean immediate) {
             return false;
@@ -3699,6 +4275,7 @@
             super(context);
         }
 
+        @Override
         public void bringChildToFront(View child) {
             mHasBroughtChildToFront = true;
         }
@@ -3707,6 +4284,7 @@
             return mHasBroughtChildToFront;
         }
 
+        @Override
         public void childDrawableStateChanged(View child) {
             mHasChildDrawableStateChanged = true;
         }
@@ -3725,14 +4303,12 @@
             super.dispatchSetSelected(selected);
         }
 
+        @Override
         public void clearChildFocus(View child) {
-            mHasClearChildFocus = true;
+
         }
 
-        public boolean hasClearChildFocus() {
-            return mHasClearChildFocus;
-        }
-
+        @Override
         public void createContextMenu(ContextMenu menu) {
             mHasCreateContextMenu = true;
         }
@@ -3741,16 +4317,18 @@
             return mHasCreateContextMenu;
         }
 
+        @Override
         public View focusSearch(View v, int direction) {
             return v;
         }
 
+        @Override
         public void focusableViewAvailable(View v) {
 
         }
 
+        @Override
         public boolean getChildVisibleRect(View child, Rect r, Point offset) {
-            mHasGetChildVisibleRect = true;
             return false;
         }
 
@@ -3759,26 +4337,27 @@
 
         }
 
-        public boolean hasGetChildVisibleRect() {
-            return mHasGetChildVisibleRect;
-        }
-
+        @Override
         public ViewParent invalidateChildInParent(int[] location, Rect r) {
             return null;
         }
 
+        @Override
         public boolean isLayoutRequested() {
             return false;
         }
 
+        @Override
         public void recomputeViewAttributes(View child) {
 
         }
 
+        @Override
         public void requestChildFocus(View child, View focused) {
 
         }
 
+        @Override
         public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
 
         }
@@ -3792,20 +4371,30 @@
             return mHasRequestLayout;
         }
 
+        @Override
         public void requestTransparentRegion(View child) {
 
         }
 
+        @Override
         public boolean showContextMenuForChild(View originalView) {
             mHasShowContextMenuForChild = true;
             return false;
         }
 
+        @Override
+        public boolean showContextMenuForChild(View originalView, float x, float y) {
+            mHasShowContextMenuForChildXY = true;
+            return false;
+        }
+
+        @Override
         public ActionMode startActionModeForChild(View originalView,
                 ActionMode.Callback callback) {
             return null;
         }
 
+        @Override
         public ActionMode startActionModeForChild(View originalView,
                 ActionMode.Callback callback, int type) {
             return null;
@@ -3815,40 +4404,29 @@
             return mHasShowContextMenuForChild;
         }
 
+        public boolean hasShowContextMenuForChildXY() {
+            return mHasShowContextMenuForChildXY;
+        }
+
         @Override
         protected int[] onCreateDrawableState(int extraSpace) {
-            mHasOnCreateDrawableState = true;
             return DEFAULT_PARENT_STATE_SET;
         }
 
+        @Override
         public boolean requestSendAccessibilityEvent(View child, AccessibilityEvent event) {
             return false;
         }
 
-        public static int[] getDefaultParentStateSet() {
-            return DEFAULT_PARENT_STATE_SET;
-        }
-
-        public boolean hasOnCreateDrawableState() {
-            return mHasOnCreateDrawableState;
-        }
-
         public void reset() {
-            mHasClearChildFocus = false;
             mHasRequestLayout = false;
             mHasCreateContextMenu = false;
             mHasShowContextMenuForChild = false;
-            mHasGetChildVisibleRect = false;
-            mHasInvalidateChild = false;
-            mHasOnCreateDrawableState = false;
+            mHasShowContextMenuForChildXY = false;
             mHasChildDrawableStateChanged = false;
             mHasBroughtChildToFront = false;
         }
 
-        public void childOverlayStateChanged(View child) {
-
-        }
-
         @Override
         public void childHasTransientStateChanged(View child, boolean hasTransientState) {
 
@@ -3907,6 +4485,7 @@
     private final class OnCreateContextMenuListenerImpl implements OnCreateContextMenuListener {
         private boolean mHasOnCreateContextMenu = false;
 
+        @Override
         public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
             mHasOnCreateContextMenu = true;
         }
@@ -3922,6 +4501,8 @@
 
     private static class MockViewGroupParent extends ViewGroup implements ViewParent {
         private boolean mHasRequestChildRectangleOnScreen = false;
+        private Rect mLastRequestedChildRectOnScreen = new Rect(
+                Integer.MIN_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE);
 
         public MockViewGroupParent(Context context) {
             super(context);
@@ -3936,9 +4517,14 @@
         public boolean requestChildRectangleOnScreen(View child,
                 Rect rectangle, boolean immediate) {
             mHasRequestChildRectangleOnScreen = true;
+            mLastRequestedChildRectOnScreen.set(rectangle);
             return super.requestChildRectangleOnScreen(child, rectangle, immediate);
         }
 
+        public Rect getLastRequestedChildRectOnScreen() {
+            return mLastRequestedChildRectOnScreen;
+        }
+
         public boolean hasRequestChildRectangleOnScreen() {
             return mHasRequestChildRectangleOnScreen;
         }
@@ -3956,6 +4542,7 @@
     private static final class OnClickListenerImpl implements OnClickListener {
         private boolean mHasOnClick = false;
 
+        @Override
         public void onClick(View v) {
             mHasOnClick = true;
         }
@@ -3980,6 +4567,7 @@
             mHasOnLongClick = false;
         }
 
+        @Override
         public boolean onLongClick(View v) {
             mHasOnLongClick = true;
             return true;
@@ -3999,6 +4587,7 @@
             mLastViewContextClicked = null;
         }
 
+        @Override
         public boolean onContextClick(View v) {
             mHasContextClick = true;
             mLastViewContextClicked = v;
@@ -4013,6 +4602,7 @@
     private static final class OnFocusChangeListenerImpl implements OnFocusChangeListener {
         private boolean mHasOnFocusChange = false;
 
+        @Override
         public void onFocusChange(View v, boolean hasFocus) {
             mHasOnFocusChange = true;
         }
@@ -4029,6 +4619,7 @@
     private static final class OnKeyListenerImpl implements OnKeyListener {
         private boolean mHasOnKey = false;
 
+        @Override
         public boolean onKey(View v, int keyCode, KeyEvent event) {
             mHasOnKey = true;
             return true;
@@ -4046,6 +4637,7 @@
     private static final class OnTouchListenerImpl implements OnTouchListener {
         private boolean mHasOnTouch = false;
 
+        @Override
         public boolean onTouch(View v, MotionEvent event) {
             mHasOnTouch = true;
             return true;
@@ -4080,7 +4672,7 @@
         public void reset() {
             mCalledOnTouchEvent = false;
         }
-    };
+    }
 
     private static final class ViewData {
         public int childCount;
@@ -4091,8 +4683,80 @@
     private static final class MockRunnable implements Runnable {
         public boolean hasRun = false;
 
+        @Override
         public void run() {
             hasRun = true;
         }
     }
+
+    private static final Class<?> ASYNC_INFLATE_VIEWS[] = {
+        android.app.FragmentBreadCrumbs.class,
+// DISABLED because it doesn't have a AppWidgetHostView(Context, AttributeSet)
+// constructor, so it's not inflate-able
+//        android.appwidget.AppWidgetHostView.class,
+        android.gesture.GestureOverlayView.class,
+        android.inputmethodservice.ExtractEditText.class,
+        android.inputmethodservice.KeyboardView.class,
+//        android.media.tv.TvView.class,
+//        android.opengl.GLSurfaceView.class,
+//        android.view.SurfaceView.class,
+        android.view.TextureView.class,
+        android.view.ViewStub.class,
+//        android.webkit.WebView.class,
+        android.widget.AbsoluteLayout.class,
+        android.widget.AdapterViewFlipper.class,
+        android.widget.AnalogClock.class,
+        android.widget.AutoCompleteTextView.class,
+        android.widget.Button.class,
+        android.widget.CalendarView.class,
+        android.widget.CheckBox.class,
+        android.widget.CheckedTextView.class,
+        android.widget.Chronometer.class,
+        android.widget.DatePicker.class,
+        android.widget.DialerFilter.class,
+        android.widget.DigitalClock.class,
+        android.widget.EditText.class,
+        android.widget.ExpandableListView.class,
+        android.widget.FrameLayout.class,
+        android.widget.Gallery.class,
+        android.widget.GridView.class,
+        android.widget.HorizontalScrollView.class,
+        android.widget.ImageButton.class,
+        android.widget.ImageSwitcher.class,
+        android.widget.ImageView.class,
+        android.widget.LinearLayout.class,
+        android.widget.ListView.class,
+        android.widget.MediaController.class,
+        android.widget.MultiAutoCompleteTextView.class,
+        android.widget.NumberPicker.class,
+        android.widget.ProgressBar.class,
+        android.widget.QuickContactBadge.class,
+        android.widget.RadioButton.class,
+        android.widget.RadioGroup.class,
+        android.widget.RatingBar.class,
+        android.widget.RelativeLayout.class,
+        android.widget.ScrollView.class,
+        android.widget.SeekBar.class,
+// DISABLED because it has required attributes
+//        android.widget.SlidingDrawer.class,
+        android.widget.Spinner.class,
+        android.widget.StackView.class,
+        android.widget.Switch.class,
+        android.widget.TabHost.class,
+        android.widget.TabWidget.class,
+        android.widget.TableLayout.class,
+        android.widget.TableRow.class,
+        android.widget.TextClock.class,
+        android.widget.TextSwitcher.class,
+        android.widget.TextView.class,
+        android.widget.TimePicker.class,
+        android.widget.ToggleButton.class,
+        android.widget.TwoLineListItem.class,
+//        android.widget.VideoView.class,
+        android.widget.ViewAnimator.class,
+        android.widget.ViewFlipper.class,
+        android.widget.ViewSwitcher.class,
+        android.widget.ZoomButton.class,
+        android.widget.ZoomControls.class,
+    };
 }
diff --git a/tests/tests/view/src/android/view/cts/ViewTestCtsActivity.java b/tests/tests/view/src/android/view/cts/ViewTestCtsActivity.java
index 01215bc..bbe6ccc 100644
--- a/tests/tests/view/src/android/view/cts/ViewTestCtsActivity.java
+++ b/tests/tests/view/src/android/view/cts/ViewTestCtsActivity.java
@@ -20,7 +20,7 @@
 import android.os.Bundle;
 import android.os.SystemClock;
 import android.util.Log;
-import com.android.cts.view.R;
+import android.view.cts.R;
 
 public class ViewTestCtsActivity extends Activity {
     private boolean mHasWindowFocus = false;
diff --git a/tests/tests/view/src/android/view/cts/ViewTreeObserverTest.java b/tests/tests/view/src/android/view/cts/ViewTreeObserverTest.java
index 7071808..b799e76 100644
--- a/tests/tests/view/src/android/view/cts/ViewTreeObserverTest.java
+++ b/tests/tests/view/src/android/view/cts/ViewTreeObserverTest.java
@@ -16,7 +16,7 @@
 
 package android.view.cts;
 
-import com.android.cts.view.R;
+import android.view.cts.R;
 
 import android.app.Activity;
 import android.app.Instrumentation;
diff --git a/tests/tests/view/src/android/view/cts/View_AnimationTest.java b/tests/tests/view/src/android/view/cts/View_AnimationTest.java
index 64bb2f7..07abb6f 100644
--- a/tests/tests/view/src/android/view/cts/View_AnimationTest.java
+++ b/tests/tests/view/src/android/view/cts/View_AnimationTest.java
@@ -24,7 +24,7 @@
 import android.view.animation.TranslateAnimation;
 import android.view.animation.cts.AnimationTestUtils;
 
-import com.android.cts.view.R;
+import android.view.cts.R;
 
 
 /**
@@ -40,7 +40,7 @@
     private TranslateAnimation mAnimation;
 
     public View_AnimationTest() {
-        super("com.android.cts.view", ViewTestCtsActivity.class);
+        super("android.view.cts", ViewTestCtsActivity.class);
     }
 
     @Override
diff --git a/tests/tests/view/src/android/view/cts/View_FocusHandlingTest.java b/tests/tests/view/src/android/view/cts/View_FocusHandlingTest.java
index 97992ee..564620e 100644
--- a/tests/tests/view/src/android/view/cts/View_FocusHandlingTest.java
+++ b/tests/tests/view/src/android/view/cts/View_FocusHandlingTest.java
@@ -16,7 +16,7 @@
 
 package android.view.cts;
 
-import com.android.cts.view.R;
+import android.view.cts.R;
 
 
 import android.app.Activity;
@@ -28,7 +28,7 @@
 public class View_FocusHandlingTest
         extends ActivityInstrumentationTestCase2<FocusHandlingCtsActivity> {
     public View_FocusHandlingTest() {
-        super("com.android.cts.view", FocusHandlingCtsActivity.class);
+        super("android.view.cts", FocusHandlingCtsActivity.class);
     }
 
     @UiThreadTest
diff --git a/tests/tests/view/src/android/view/cts/View_IdsTest.java b/tests/tests/view/src/android/view/cts/View_IdsTest.java
index e65ccf5..4dd00d6 100644
--- a/tests/tests/view/src/android/view/cts/View_IdsTest.java
+++ b/tests/tests/view/src/android/view/cts/View_IdsTest.java
@@ -16,7 +16,7 @@
 
 package android.view.cts;
 
-import com.android.cts.view.R;
+import android.view.cts.R;
 
 
 import android.app.Activity;
@@ -29,7 +29,7 @@
 
 public class View_IdsTest extends ActivityInstrumentationTestCase2<UsingViewsCtsActivity> {
     public View_IdsTest() {
-        super("com.android.cts.view", UsingViewsCtsActivity.class);
+        super("android.view.cts", UsingViewsCtsActivity.class);
     }
 
     @UiThreadTest
diff --git a/tests/tests/view/src/android/view/cts/View_LayoutPositionTest.java b/tests/tests/view/src/android/view/cts/View_LayoutPositionTest.java
index 3938607..53514dc 100644
--- a/tests/tests/view/src/android/view/cts/View_LayoutPositionTest.java
+++ b/tests/tests/view/src/android/view/cts/View_LayoutPositionTest.java
@@ -16,7 +16,7 @@
 
 package android.view.cts;
 
-import com.android.cts.view.R;
+import android.view.cts.R;
 
 
 import android.app.Activity;
@@ -36,7 +36,7 @@
     private Activity mActivity;
 
     public View_LayoutPositionTest() {
-        super("com.android.cts.view", ViewLayoutPositionTestCtsActivity.class);
+        super("android.view.cts", ViewLayoutPositionTestCtsActivity.class);
     }
 
     @Override
diff --git a/tests/tests/view/src/android/view/cts/View_UsingViewsTest.java b/tests/tests/view/src/android/view/cts/View_UsingViewsTest.java
index f6d067d..413c356 100644
--- a/tests/tests/view/src/android/view/cts/View_UsingViewsTest.java
+++ b/tests/tests/view/src/android/view/cts/View_UsingViewsTest.java
@@ -16,7 +16,7 @@
 
 package android.view.cts;
 
-import com.android.cts.view.R;
+import android.view.cts.R;
 
 
 import android.app.Activity;
@@ -78,7 +78,7 @@
     private TextView mWarningTextView;
 
     public View_UsingViewsTest() {
-        super("com.android.cts.view", UsingViewsCtsActivity.class);
+        super("android.view.cts", UsingViewsCtsActivity.class);
     }
 
     @Override
diff --git a/tests/tests/view/src/android/view/cts/WindowCtsActivity.java b/tests/tests/view/src/android/view/cts/WindowCtsActivity.java
index 8af808c..3cfcc96 100644
--- a/tests/tests/view/src/android/view/cts/WindowCtsActivity.java
+++ b/tests/tests/view/src/android/view/cts/WindowCtsActivity.java
@@ -16,7 +16,7 @@
 
 package android.view.cts;
 
-import com.android.cts.view.R;
+import android.view.cts.R;
 
 import android.app.Activity;
 import android.os.Bundle;
diff --git a/tests/tests/view/src/android/view/cts/WindowManager_LayoutParamsTest.java b/tests/tests/view/src/android/view/cts/WindowManager_LayoutParamsTest.java
index 40b4b28..84350bd 100644
--- a/tests/tests/view/src/android/view/cts/WindowManager_LayoutParamsTest.java
+++ b/tests/tests/view/src/android/view/cts/WindowManager_LayoutParamsTest.java
@@ -120,7 +120,8 @@
         assertEquals(WindowManager.LayoutParams.TITLE_CHANGED
                 | WindowManager.LayoutParams.ALPHA_CHANGED
                 | WindowManager.LayoutParams.ANIMATION_CHANGED
-                | WindowManager.LayoutParams.DIM_AMOUNT_CHANGED,
+                | WindowManager.LayoutParams.DIM_AMOUNT_CHANGED
+                | WindowManager.LayoutParams.ACCESSIBILITY_TITLE_CHANGED,
                 mLayoutParams.copyFrom(params));
         assertEquals(params.getTitle(), mLayoutParams.getTitle());
         assertEquals(params.alpha, mLayoutParams.alpha);
diff --git a/tests/tests/view/src/android/view/cts/WindowTest.java b/tests/tests/view/src/android/view/cts/WindowTest.java
index dcfcfb7..439eda5 100644
--- a/tests/tests/view/src/android/view/cts/WindowTest.java
+++ b/tests/tests/view/src/android/view/cts/WindowTest.java
@@ -16,7 +16,8 @@
 
 package android.view.cts;
 
-import com.android.cts.view.R;
+import android.view.ContextThemeWrapper;
+import android.view.cts.R;
 
 import android.app.Instrumentation;
 import android.app.Presentation;
@@ -45,6 +46,7 @@
 import android.view.InputDevice;
 import android.view.InputQueue;
 import android.view.KeyEvent;
+import android.view.KeyboardShortcutGroup;
 import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.MenuItem;
@@ -61,6 +63,7 @@
 import android.widget.Button;
 import android.widget.TextView;
 
+import java.util.List;
 import java.util.concurrent.Semaphore;
 import java.util.concurrent.TimeUnit;
 
@@ -80,7 +83,7 @@
     private VirtualDisplay mVirtualDisplay;
 
     public WindowTest() {
-        super("com.android.cts.view", WindowCtsActivity.class);
+        super("android.view.cts", WindowCtsActivity.class);
     }
 
     @Override
@@ -292,7 +295,7 @@
         int screenHeight = dm.heightPixels;
         assertTrue(decor.getWidth() >= screenWidth);
         assertTrue(decor.getHeight() >= screenHeight);
-        assertSame(mWindow.getContext(), decor.getContext());
+        assertTrue(decor.getContext() instanceof ContextThemeWrapper);
     }
 
     /**
@@ -868,6 +871,9 @@
         public void addContentView(View view, ViewGroup.LayoutParams params) {
         }
 
+        public void clearContentView() {
+        }
+
         public View getCurrentFocus() {
             return null;
         }
@@ -1025,9 +1031,27 @@
         }
 
         @Override
+        public void setDecorCaptionShade(int decorCaptionShade) {
+
+        }
+
+        @Override
+        public void setResizingCaptionDrawable(Drawable drawable) {
+
+        }
+
+        @Override
         public int getNavigationBarColor() {
             return 0;
         }
+
+        @Override
+        public void onMultiWindowModeChanged() {
+        }
+
+        @Override
+        public void reportActivityRelaunched() {
+        }
     }
 
     private class MockWindowCallback implements Window.Callback {
diff --git a/tests/tests/view/src/android/view/cts/util/DrawingUtils.java b/tests/tests/view/src/android/view/cts/util/DrawingUtils.java
new file mode 100644
index 0000000..3be7447
--- /dev/null
+++ b/tests/tests/view/src/android/view/cts/util/DrawingUtils.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.view.cts.util;
+
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.util.Pair;
+import android.view.View;
+import junit.framework.Assert;
+
+import java.util.List;
+
+public class DrawingUtils {
+    /**
+     * Checks the pixels in the specified {@link View}. This methods draws the view into an
+     * offscreen bitmap and checks each pixel to match the expected color. The expected color
+     * of each pixel is either the color associated with the {@link Rect} that contains it,
+     * or the default color in case none of the rectangles cover that pixel.
+     *
+     * In case of a mismatch this method will call {@link Assert#fail(String)}
+     * with detailed description of the mismatch.
+     */
+    public static void assertAllPixelsOfColor(String failMessagePrefix, View view,
+            int defaultColor, List<Pair<Rect, Integer>> colorRectangles) {
+        final int viewWidth = view.getWidth();
+        final int viewHeight = view.getHeight();
+        // Create a bitmap that matches the size of our view
+        final Bitmap bitmap = Bitmap.createBitmap(viewWidth, viewHeight, Bitmap.Config.ARGB_8888);
+        // Create a canvas that wraps the bitmap
+        final Canvas canvas = new Canvas(bitmap);
+        // And ask the view to draw itself to the canvas / bitmap
+        view.draw(canvas);
+
+        // Now create a golden bitmap based on the colors passed to us
+        final Bitmap goldenBitmap = Bitmap.createBitmap(viewWidth, viewHeight,
+                Bitmap.Config.ARGB_8888);
+        // Create a canvas that wraps the bitmap
+        final Canvas goldenCanvas = new Canvas(goldenBitmap);
+        // Fill it with default color
+        final Paint goldenPaint = new Paint();
+        goldenPaint.setStyle(Paint.Style.FILL_AND_STROKE);
+        goldenPaint.setColor(defaultColor);
+        goldenCanvas.drawRect(0, 0, viewWidth, viewHeight, goldenPaint);
+        if (colorRectangles != null) {
+            for (Pair<Rect, Integer> colorRectangle : colorRectangles) {
+                goldenPaint.setColor(colorRectangle.second);
+                goldenCanvas.drawRect(colorRectangle.first, goldenPaint);
+            }
+        }
+
+        // Compare bitmap pixels (row-wise)
+        try {
+            int[] rowPixels = new int[viewWidth];
+            int[] rowGoldenPixels = new int[viewWidth];
+            for (int row = 0; row < viewHeight; row++) {
+                bitmap.getPixels(rowPixels, 0, viewWidth, 0, row, viewWidth, 1);
+                goldenBitmap.getPixels(rowGoldenPixels, 0, viewWidth, 0, row, viewWidth, 1);
+                for (int column = 0; column < viewWidth; column++) {
+                    int expectedPixelColor = rowGoldenPixels[column];
+                    int actualPixelColor = rowPixels[column];
+                    if (rowPixels[column] != expectedPixelColor) {
+                        String mismatchDescription = failMessagePrefix
+                                + ": expected all drawable colors to be ["
+                                + Color.alpha(expectedPixelColor) + ","
+                                + Color.red(expectedPixelColor) + ","
+                                + Color.green(expectedPixelColor) + ","
+                                + Color.blue(expectedPixelColor)
+                                + "] but at position (" + row + "," + column + ") found ["
+                                + Color.alpha(actualPixelColor) + ","
+                                + Color.red(actualPixelColor) + ","
+                                + Color.green(actualPixelColor) + ","
+                                + Color.blue(actualPixelColor) + "]";
+                        Assert.fail(mismatchDescription);
+                    }
+                }
+            }
+        } finally {
+            bitmap.recycle();
+            goldenBitmap.recycle();
+        }
+    }
+}
diff --git a/tests/tests/view/src/android/view/cts/util/ViewTestUtils.java b/tests/tests/view/src/android/view/cts/util/ViewTestUtils.java
new file mode 100644
index 0000000..b70e882
--- /dev/null
+++ b/tests/tests/view/src/android/view/cts/util/ViewTestUtils.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.view.cts.util;
+
+import junit.framework.Assert;
+
+import android.app.Activity;
+import android.app.Instrumentation;
+import android.view.View;
+import android.view.ViewTreeObserver;
+import android.view.ViewTreeObserver.OnDrawListener;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Utilities for testing View behavior.
+ */
+public class ViewTestUtils {
+
+    /**
+     * Runs the specified Runnable on the main thread and ensures that the
+     * specified View's tree is drawn before returning.
+     *
+     * @param instrumentation the instrumentation used to run the test
+     * @param view the view whose tree should be drawn before returning
+     * @param runner the runnable to run on the main thread
+     */
+    public static void runOnMainAndDrawSync(Instrumentation instrumentation,
+            final Activity activity, final Runnable runner) {
+        final CountDownLatch latch = new CountDownLatch(1);
+
+        instrumentation.runOnMainSync(() -> {
+            final View view = activity.findViewById(android.R.id.content);
+            final ViewTreeObserver observer = view.getViewTreeObserver();
+            final OnDrawListener listener = new OnDrawListener() {
+                @Override
+                public void onDraw() {
+                    observer.removeOnDrawListener(this);
+                    view.post(() -> latch.countDown());
+                }
+            };
+
+            observer.addOnDrawListener(listener);
+            runner.run();
+        });
+
+        try {
+            Assert.assertTrue("Expected draw pass occurred within 5 seconds",
+                    latch.await(5, TimeUnit.SECONDS));
+        } catch (InterruptedException e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/tests/view/src/android/view/inputmethod/cts/BaseInputConnectionTest.java b/tests/tests/view/src/android/view/inputmethod/cts/BaseInputConnectionTest.java
index 30edecb..ee61446 100644
--- a/tests/tests/view/src/android/view/inputmethod/cts/BaseInputConnectionTest.java
+++ b/tests/tests/view/src/android/view/inputmethod/cts/BaseInputConnectionTest.java
@@ -16,15 +16,13 @@
 
 package android.view.inputmethod.cts;
 
-import com.android.cts.view.R;
-
-
 import android.app.Instrumentation;
 import android.content.Context;
 import android.cts.util.PollingCheck;
 import android.os.Bundle;
 import android.test.ActivityInstrumentationTestCase2;
 import android.text.Editable;
+import android.text.Selection;
 import android.text.Spannable;
 import android.text.SpannableString;
 import android.text.TextUtils;
@@ -32,10 +30,12 @@
 import android.view.KeyEvent;
 import android.view.View;
 import android.view.Window;
+import android.view.cts.R;
 import android.view.inputmethod.BaseInputConnection;
 import android.view.inputmethod.CompletionInfo;
 import android.view.inputmethod.ExtractedTextRequest;
 import android.view.inputmethod.InputMethodManager;
+import android.view.inputmethod.cts.util.InputConnectionTestUtils;
 import android.widget.EditText;
 
 public class BaseInputConnectionTest extends
@@ -48,7 +48,7 @@
     private Instrumentation mInstrumentation;
 
     public BaseInputConnectionTest() {
-        super("com.android.cts.view", InputMethodCtsActivity.class);
+        super("android.view.cts", InputMethodCtsActivity.class);
     }
 
     @Override
@@ -163,7 +163,7 @@
         }.run();
         assertEquals(0, dummyConnection.getCursorCapsMode(TextUtils.CAP_MODE_WORDS));
 
-        // Test deleteSurroudingText
+        // Test deleteSurroundingText
         int end = text2.length();
         mConnection.setSelection(end, end);
         // Delete the ending space
@@ -254,6 +254,237 @@
         mConnection.reportFullscreenMode(false);
         assertFalse(imManager.isFullscreenMode());
         mConnection.reportFullscreenMode(true);
-        assertTrue(imManager.isFullscreenMode());
+        // Only IMEs are allowed to report full-screen mode.  Calling this method from the
+        // application should have no effect.
+        assertFalse(imManager.isFullscreenMode());
+    }
+
+    /**
+     * An utility method to create an instance of {@link BaseInputConnection} in dummy mode with
+     * an initial text and selection range.
+     * @param view the {@link View} to be associated with the {@link BaseInputConnection}.
+     * @param source the initial text.
+     * @return {@link BaseInputConnection} instantiated in dummy mode with {@code source} and
+     * selection range from {@code selectionStart} to {@code selectionEnd}
+     */
+    private static BaseInputConnection createDummyConnectionWithSelection(
+            final View view, final CharSequence source) {
+        final int selectionStart = Selection.getSelectionStart(source);
+        final int selectionEnd = Selection.getSelectionEnd(source);
+        final Editable editable = Editable.Factory.getInstance().newEditable(source);
+        Selection.setSelection(editable, selectionStart, selectionEnd);
+        return new BaseInputConnection(view, false) {
+            @Override
+            public Editable getEditable() {
+                return editable;
+            }
+        };
+    }
+
+    private void testDeleteSurroundingTextMain(final String initialState,
+            final int deleteBefore, final int deleteAfter, final String expectedState) {
+        final CharSequence source = InputConnectionTestUtils.formatString(initialState);
+        final BaseInputConnection ic = createDummyConnectionWithSelection(mView, source);
+        ic.deleteSurroundingText(deleteBefore, deleteAfter);
+
+        final CharSequence expectedString = InputConnectionTestUtils.formatString(expectedState);
+        final int expectedSelectionStart = Selection.getSelectionStart(expectedString);
+        final int expectedSelectionEnd = Selection.getSelectionEnd(expectedString);
+
+        // It is sufficient to check the surrounding text up to source.length() characters, because
+        // InputConnection.deleteSurroundingText() is not supposed to increase the text length.
+        final int retrievalLength = source.length();
+        if (expectedSelectionStart == 0) {
+            assertTrue(TextUtils.isEmpty(ic.getTextBeforeCursor(retrievalLength, 0)));
+        } else {
+            assertEquals(expectedString.subSequence(0, expectedSelectionStart).toString(),
+                    ic.getTextBeforeCursor(retrievalLength, 0).toString());
+        }
+        if (expectedSelectionStart == expectedSelectionEnd) {
+            assertTrue(TextUtils.isEmpty(ic.getSelectedText(0)));  // null is allowed.
+        } else {
+            assertEquals(expectedString.subSequence(expectedSelectionStart,
+                    expectedSelectionEnd).toString(), ic.getSelectedText(0).toString());
+        }
+        if (expectedSelectionEnd == expectedString.length()) {
+            assertTrue(TextUtils.isEmpty(ic.getTextAfterCursor(retrievalLength, 0)));
+        } else {
+            assertEquals(expectedString.subSequence(expectedSelectionEnd,
+                    expectedString.length()).toString(),
+                    ic.getTextAfterCursor(retrievalLength, 0).toString());
+        }
+    }
+
+    /**
+     * Tests {@link BaseInputConnection#deleteSurroundingText(int, int)} comprehensively.
+     */
+    public void testDeleteSurroundingText() throws Throwable {
+        testDeleteSurroundingTextMain("012[]3456789", 0, 0, "012[]3456789");
+        testDeleteSurroundingTextMain("012[]3456789", -1, -1, "012[]3456789");
+        testDeleteSurroundingTextMain("012[]3456789", 1, 2, "01[]56789");
+        testDeleteSurroundingTextMain("012[]3456789", 10, 1, "[]456789");
+        testDeleteSurroundingTextMain("012[]3456789", 1, 10, "01[]");
+        testDeleteSurroundingTextMain("[]0123456789", 3, 3, "[]3456789");
+        testDeleteSurroundingTextMain("0123456789[]", 3, 3, "0123456[]");
+        testDeleteSurroundingTextMain("012[345]6789", 0, 0, "012[345]6789");
+        testDeleteSurroundingTextMain("012[345]6789", -1, -1, "012[345]6789");
+        testDeleteSurroundingTextMain("012[345]6789", 1, 2, "01[345]89");
+        testDeleteSurroundingTextMain("012[345]6789", 10, 1, "[345]789");
+        testDeleteSurroundingTextMain("012[345]6789", 1, 10, "01[345]");
+        testDeleteSurroundingTextMain("[012]3456789", 3, 3, "[012]6789");
+        testDeleteSurroundingTextMain("0123456[789]", 3, 3, "0123[789]");
+        testDeleteSurroundingTextMain("[0123456789]", 0, 0, "[0123456789]");
+        testDeleteSurroundingTextMain("[0123456789]", 1, 1, "[0123456789]");
+
+        // Surrogate characters do not have any special meanings.  Validating the character sequence
+        // is beyond the goal of this API.
+        testDeleteSurroundingTextMain("0<>[]3456789", 1, 0, "0<[]3456789");
+        testDeleteSurroundingTextMain("0<>[]3456789", 2, 0, "0[]3456789");
+        testDeleteSurroundingTextMain("0<>[]3456789", 3, 0, "[]3456789");
+        testDeleteSurroundingTextMain("012[]<>56789", 0, 1, "012[]>56789");
+        testDeleteSurroundingTextMain("012[]<>56789", 0, 2, "012[]56789");
+        testDeleteSurroundingTextMain("012[]<>56789", 0, 3, "012[]6789");
+        testDeleteSurroundingTextMain("0<<[]3456789", 1, 0, "0<[]3456789");
+        testDeleteSurroundingTextMain("0<<[]3456789", 2, 0, "0[]3456789");
+        testDeleteSurroundingTextMain("0<<[]3456789", 3, 0, "[]3456789");
+        testDeleteSurroundingTextMain("012[]<<56789", 0, 1, "012[]<56789");
+        testDeleteSurroundingTextMain("012[]<<56789", 0, 2, "012[]56789");
+        testDeleteSurroundingTextMain("012[]<<56789", 0, 3, "012[]6789");
+        testDeleteSurroundingTextMain("0>>[]3456789", 1, 0, "0>[]3456789");
+        testDeleteSurroundingTextMain("0>>[]3456789", 2, 0, "0[]3456789");
+        testDeleteSurroundingTextMain("0>>[]3456789", 3, 0, "[]3456789");
+        testDeleteSurroundingTextMain("012[]>>56789", 0, 1, "012[]>56789");
+        testDeleteSurroundingTextMain("012[]>>56789", 0, 2, "012[]56789");
+        testDeleteSurroundingTextMain("012[]>>56789", 0, 3, "012[]6789");
+    }
+
+    private void testDeleteSurroundingTextInCodePointsMain(final String initialState,
+            final int deleteBeforeInCodePoints, final int deleteAfterInCodePoints,
+            final String expectedState) {
+        final CharSequence source = InputConnectionTestUtils.formatString(initialState);
+        final BaseInputConnection ic = createDummyConnectionWithSelection(mView, source);
+        ic.deleteSurroundingTextInCodePoints(deleteBeforeInCodePoints, deleteAfterInCodePoints);
+
+        final CharSequence expectedString = InputConnectionTestUtils.formatString(expectedState);
+        final int expectedSelectionStart = Selection.getSelectionStart(expectedString);
+        final int expectedSelectionEnd = Selection.getSelectionEnd(expectedString);
+
+        // It is sufficient to check the surrounding text up to source.length() characters, because
+        // InputConnection.deleteSurroundingTextInCodePoints() is not supposed to increase the text
+        // length.
+        final int retrievalLength = source.length();
+        if (expectedSelectionStart == 0) {
+            assertTrue(TextUtils.isEmpty(ic.getTextBeforeCursor(retrievalLength, 0)));
+        } else {
+            assertEquals(expectedString.subSequence(0, expectedSelectionStart).toString(),
+                    ic.getTextBeforeCursor(retrievalLength, 0).toString());
+        }
+        if (expectedSelectionStart == expectedSelectionEnd) {
+            assertTrue(TextUtils.isEmpty(ic.getSelectedText(0)));  // null is allowed.
+        } else {
+            assertEquals(expectedString.subSequence(expectedSelectionStart,
+                    expectedSelectionEnd).toString(), ic.getSelectedText(0).toString());
+        }
+        if (expectedSelectionEnd == expectedString.length()) {
+            assertTrue(TextUtils.isEmpty(ic.getTextAfterCursor(retrievalLength, 0)));
+        } else {
+            assertEquals(expectedString.subSequence(expectedSelectionEnd,
+                    expectedString.length()).toString(),
+                    ic.getTextAfterCursor(retrievalLength, 0).toString());
+        }
+    }
+
+    /**
+     * Tests {@link BaseInputConnection#deleteSurroundingTextInCodePoints(int, int)}
+     * comprehensively.
+     */
+    public void testDeleteSurroundingTextInCodePoints() throws Throwable {
+        testDeleteSurroundingTextInCodePointsMain("012[]3456789", 0, 0, "012[]3456789");
+        testDeleteSurroundingTextInCodePointsMain("012[]3456789", -1, -1, "012[]3456789");
+        testDeleteSurroundingTextInCodePointsMain("012[]3456789", 1, 2, "01[]56789");
+        testDeleteSurroundingTextInCodePointsMain("012[]3456789", 10, 1, "[]456789");
+        testDeleteSurroundingTextInCodePointsMain("012[]3456789", 1, 10, "01[]");
+        testDeleteSurroundingTextInCodePointsMain("[]0123456789", 3, 3, "[]3456789");
+        testDeleteSurroundingTextInCodePointsMain("0123456789[]", 3, 3, "0123456[]");
+        testDeleteSurroundingTextInCodePointsMain("012[345]6789", 0, 0, "012[345]6789");
+        testDeleteSurroundingTextInCodePointsMain("012[345]6789", -1, -1, "012[345]6789");
+        testDeleteSurroundingTextInCodePointsMain("012[345]6789", 1, 2, "01[345]89");
+        testDeleteSurroundingTextInCodePointsMain("012[345]6789", 10, 1, "[345]789");
+        testDeleteSurroundingTextInCodePointsMain("012[345]6789", 1, 10, "01[345]");
+        testDeleteSurroundingTextInCodePointsMain("[012]3456789", 3, 3, "[012]6789");
+        testDeleteSurroundingTextInCodePointsMain("0123456[789]", 3, 3, "0123[789]");
+        testDeleteSurroundingTextInCodePointsMain("[0123456789]", 0, 0, "[0123456789]");
+        testDeleteSurroundingTextInCodePointsMain("[0123456789]", 1, 1, "[0123456789]");
+
+        testDeleteSurroundingTextInCodePointsMain("0<>[]3456789", 1, 0, "0[]3456789");
+        testDeleteSurroundingTextInCodePointsMain("0<>[]3456789", 2, 0, "[]3456789");
+        testDeleteSurroundingTextInCodePointsMain("0<>[]3456789", 3, 0, "[]3456789");
+        testDeleteSurroundingTextInCodePointsMain("012[]<>56789", 0, 1, "012[]56789");
+        testDeleteSurroundingTextInCodePointsMain("012[]<>56789", 0, 2, "012[]6789");
+        testDeleteSurroundingTextInCodePointsMain("012[]<>56789", 0, 3, "012[]789");
+
+        testDeleteSurroundingTextInCodePointsMain("[]<><><><><>", 0, 0, "[]<><><><><>");
+        testDeleteSurroundingTextInCodePointsMain("[]<><><><><>", 0, 1, "[]<><><><>");
+        testDeleteSurroundingTextInCodePointsMain("[]<><><><><>", 0, 2, "[]<><><>");
+        testDeleteSurroundingTextInCodePointsMain("[]<><><><><>", 0, 3, "[]<><>");
+        testDeleteSurroundingTextInCodePointsMain("[]<><><><><>", 0, 4, "[]<>");
+        testDeleteSurroundingTextInCodePointsMain("[]<><><><><>", 0, 5, "[]");
+        testDeleteSurroundingTextInCodePointsMain("[]<><><><><>", 0, 6, "[]");
+        testDeleteSurroundingTextInCodePointsMain("[]<><><><><>", 0, 1000, "[]");
+        testDeleteSurroundingTextInCodePointsMain("<><><><><>[]", 0, 0, "<><><><><>[]");
+        testDeleteSurroundingTextInCodePointsMain("<><><><><>[]", 1, 0, "<><><><>[]");
+        testDeleteSurroundingTextInCodePointsMain("<><><><><>[]", 2, 0, "<><><>[]");
+        testDeleteSurroundingTextInCodePointsMain("<><><><><>[]", 3, 0, "<><>[]");
+        testDeleteSurroundingTextInCodePointsMain("<><><><><>[]", 4, 0, "<>[]");
+        testDeleteSurroundingTextInCodePointsMain("<><><><><>[]", 5, 0, "[]");
+        testDeleteSurroundingTextInCodePointsMain("<><><><><>[]", 6, 0, "[]");
+        testDeleteSurroundingTextInCodePointsMain("<><><><><>[]", 1000, 0, "[]");
+
+        testDeleteSurroundingTextInCodePointsMain("0<<[]3456789", 1, 0, "0<<[]3456789");
+        testDeleteSurroundingTextInCodePointsMain("0<<[]3456789", 2, 0, "0<<[]3456789");
+        testDeleteSurroundingTextInCodePointsMain("0<<[]3456789", 3, 0, "0<<[]3456789");
+        testDeleteSurroundingTextInCodePointsMain("012[]<<56789", 0, 1, "012[]<<56789");
+        testDeleteSurroundingTextInCodePointsMain("012[]<<56789", 0, 2, "012[]<<56789");
+        testDeleteSurroundingTextInCodePointsMain("012[]<<56789", 0, 3, "012[]<<56789");
+        testDeleteSurroundingTextInCodePointsMain("0>>[]3456789", 1, 0, "0>>[]3456789");
+        testDeleteSurroundingTextInCodePointsMain("0>>[]3456789", 2, 0, "0>>[]3456789");
+        testDeleteSurroundingTextInCodePointsMain("0>>[]3456789", 3, 0, "0>>[]3456789");
+        testDeleteSurroundingTextInCodePointsMain("012[]>>56789", 0, 1, "012[]>>56789");
+        testDeleteSurroundingTextInCodePointsMain("012[]>>56789", 0, 2, "012[]>>56789");
+        testDeleteSurroundingTextInCodePointsMain("012[]>>56789", 0, 3, "012[]>>56789");
+        testDeleteSurroundingTextInCodePointsMain("01<[]>456789", 1, 0, "01<[]>456789");
+        testDeleteSurroundingTextInCodePointsMain("01<[]>456789", 0, 1, "01<[]>456789");
+        testDeleteSurroundingTextInCodePointsMain("<12[]3456789", 1, 0, "<1[]3456789");
+        testDeleteSurroundingTextInCodePointsMain("<12[]3456789", 2, 0, "<[]3456789");
+        testDeleteSurroundingTextInCodePointsMain("<12[]3456789", 3, 0, "<12[]3456789");
+        testDeleteSurroundingTextInCodePointsMain("<<>[]3456789", 1, 0, "<[]3456789");
+        testDeleteSurroundingTextInCodePointsMain("<<>[]3456789", 2, 0, "<<>[]3456789");
+        testDeleteSurroundingTextInCodePointsMain("<<>[]3456789", 3, 0, "<<>[]3456789");
+        testDeleteSurroundingTextInCodePointsMain("012[]34>6789", 0, 1, "012[]4>6789");
+        testDeleteSurroundingTextInCodePointsMain("012[]34>6789", 0, 2, "012[]>6789");
+        testDeleteSurroundingTextInCodePointsMain("012[]34>6789", 0, 3, "012[]34>6789");
+        testDeleteSurroundingTextInCodePointsMain("012[]<>>6789", 0, 1, "012[]>6789");
+        testDeleteSurroundingTextInCodePointsMain("012[]<>>6789", 0, 2, "012[]<>>6789");
+        testDeleteSurroundingTextInCodePointsMain("012[]<>>6789", 0, 3, "012[]<>>6789");
+
+        // Atomicity test.
+        testDeleteSurroundingTextInCodePointsMain("0<<[]3456789", 1, 1, "0<<[]3456789");
+        testDeleteSurroundingTextInCodePointsMain("0<<[]3456789", 2, 1, "0<<[]3456789");
+        testDeleteSurroundingTextInCodePointsMain("0<<[]3456789", 3, 1, "0<<[]3456789");
+        testDeleteSurroundingTextInCodePointsMain("012[]<<56789", 1, 1, "012[]<<56789");
+        testDeleteSurroundingTextInCodePointsMain("012[]<<56789", 1, 2, "012[]<<56789");
+        testDeleteSurroundingTextInCodePointsMain("012[]<<56789", 1, 3, "012[]<<56789");
+        testDeleteSurroundingTextInCodePointsMain("0>>[]3456789", 1, 1, "0>>[]3456789");
+        testDeleteSurroundingTextInCodePointsMain("0>>[]3456789", 2, 1, "0>>[]3456789");
+        testDeleteSurroundingTextInCodePointsMain("0>>[]3456789", 3, 1, "0>>[]3456789");
+        testDeleteSurroundingTextInCodePointsMain("012[]>>56789", 1, 1, "012[]>>56789");
+        testDeleteSurroundingTextInCodePointsMain("012[]>>56789", 1, 2, "012[]>>56789");
+        testDeleteSurroundingTextInCodePointsMain("012[]>>56789", 1, 3, "012[]>>56789");
+        testDeleteSurroundingTextInCodePointsMain("01<[]>456789", 1, 1, "01<[]>456789");
+
+        // Do not verify the character sequences in the selected region.
+        testDeleteSurroundingTextInCodePointsMain("01[><]456789", 1, 0, "0[><]456789");
+        testDeleteSurroundingTextInCodePointsMain("01[><]456789", 0, 1, "01[><]56789");
+        testDeleteSurroundingTextInCodePointsMain("01[><]456789", 1, 1, "0[><]56789");
     }
 }
diff --git a/tests/tests/view/src/android/view/inputmethod/cts/EditorInfoTest.java b/tests/tests/view/src/android/view/inputmethod/cts/EditorInfoTest.java
index 1981d6f..22c6be4 100644
--- a/tests/tests/view/src/android/view/inputmethod/cts/EditorInfoTest.java
+++ b/tests/tests/view/src/android/view/inputmethod/cts/EditorInfoTest.java
@@ -21,6 +21,7 @@
 import android.os.Parcel;
 import android.test.AndroidTestCase;
 import android.text.TextUtils;
+import android.util.LocaleList;
 import android.util.Printer;
 import android.view.inputmethod.EditorInfo;
 
@@ -41,13 +42,14 @@
         info.initialSelStart = 0;
         info.inputType = EditorInfo.TYPE_MASK_CLASS;
         info.label = "label";
-        info.packageName = "com.android.cts.view";
+        info.packageName = "android.view.cts";
         info.privateImeOptions = "privateIme";
         Bundle b = new Bundle();
         String key = "bundleKey";
         String value = "bundleValue";
         b.putString(key, value);
         info.extras = b;
+        info.hintLocales = LocaleList.forLanguageTags("en-PH,en-US");
 
         assertEquals(0, info.describeContents());
 
@@ -70,6 +72,7 @@
         assertEquals(info.actionLabel.toString(), targetInfo.actionLabel.toString());
         assertEquals(info.label.toString(), targetInfo.label.toString());
         assertEquals(info.extras.getString(key), targetInfo.extras.getString(key));
+        assertEquals(info.hintLocales, targetInfo.hintLocales);
 
         TestPrinter printer = new TestPrinter();
         String prefix = "TestEditorInfo";
@@ -77,6 +80,17 @@
         assertTrue(printer.isPrintlnCalled);
     }
 
+    public void testNullHintLocals() {
+        EditorInfo info = new EditorInfo();
+        info.hintLocales = null;
+        Parcel p = Parcel.obtain();
+        info.writeToParcel(p, 0);
+        p.setDataPosition(0);
+        EditorInfo targetInfo = EditorInfo.CREATOR.createFromParcel(p);
+        p.recycle();
+        assertNull(targetInfo.hintLocales);
+    }
+
     private class TestPrinter implements Printer {
         public boolean isPrintlnCalled;
         public void println(String x) {
diff --git a/tests/tests/view/src/android/view/inputmethod/cts/InputConnectionWrapperTest.java b/tests/tests/view/src/android/view/inputmethod/cts/InputConnectionWrapperTest.java
index 8913d6e..1ddfd2b 100644
--- a/tests/tests/view/src/android/view/inputmethod/cts/InputConnectionWrapperTest.java
+++ b/tests/tests/view/src/android/view/inputmethod/cts/InputConnectionWrapperTest.java
@@ -18,6 +18,7 @@
 
 
 import android.os.Bundle;
+import android.os.Handler;
 import android.test.AndroidTestCase;
 import android.text.TextUtils;
 import android.view.KeyEvent;
@@ -54,6 +55,8 @@
         assertTrue(inputConnection.isCommitTextCalled);
         wrapper.deleteSurroundingText(10, 100);
         assertTrue(inputConnection.isDeleteSurroundingTextCalled);
+        wrapper.deleteSurroundingTextInCodePoints(10, 100);
+        assertTrue(inputConnection.isDeleteSurroundingTextInCodePointsCalled);
         wrapper.endBatchEdit();
         assertTrue(inputConnection.isEndBatchEditCalled);
         wrapper.finishComposingText();
@@ -86,6 +89,11 @@
         assertTrue(inputConnection.isSetComposingRegionCalled);
         wrapper.requestCursorUpdates(InputConnection.CURSOR_UPDATE_IMMEDIATE);
         assertTrue(inputConnection.isRequestCursorUpdatesCalled);
+        wrapper.closeConnection();
+        assertTrue(inputConnection.isCloseConnectionCalled);
+        assertFalse(inputConnection.isGetHandlerCalled);
+        assertNull(inputConnection.getHandler());
+        assertTrue(inputConnection.isGetHandlerCalled);
     }
 
     private class MockInputConnection implements InputConnection {
@@ -95,6 +103,7 @@
         public boolean isCommitCorrectionCalled;
         public boolean isCommitTextCalled;
         public boolean isDeleteSurroundingTextCalled;
+        public boolean isDeleteSurroundingTextInCodePointsCalled;
         public boolean isEndBatchEditCalled;
         public boolean isFinishComposingTextCalled;
         public boolean isGetCursorCapsModeCalled;
@@ -111,6 +120,8 @@
         public boolean isSetComposingRegionCalled;
         public boolean isSetSelectionCalled;
         public boolean isRequestCursorUpdatesCalled;
+        public boolean isGetHandlerCalled;
+        public boolean isCloseConnectionCalled;
 
         public boolean beginBatchEdit() {
             isBeginBatchEditCalled = true;
@@ -142,6 +153,11 @@
             return false;
         }
 
+        public boolean deleteSurroundingTextInCodePoints(int beforeLength, int afterLength) {
+            isDeleteSurroundingTextInCodePointsCalled = true;
+            return false;
+        }
+
         public boolean endBatchEdit() {
             isEndBatchEditCalled = true;
             return false;
@@ -221,5 +237,14 @@
             isRequestCursorUpdatesCalled = true;
             return false;
         }
+
+        public Handler getHandler() {
+            isGetHandlerCalled = true;
+            return null;
+        }
+
+        public void closeConnection() {
+            isCloseConnectionCalled = true;
+        }
     }
 }
diff --git a/tests/tests/view/src/android/view/inputmethod/cts/InputMethodCtsActivity.java b/tests/tests/view/src/android/view/inputmethod/cts/InputMethodCtsActivity.java
index 45e5ff2..acbe8a1 100644
--- a/tests/tests/view/src/android/view/inputmethod/cts/InputMethodCtsActivity.java
+++ b/tests/tests/view/src/android/view/inputmethod/cts/InputMethodCtsActivity.java
@@ -17,7 +17,7 @@
 
 import android.app.Activity;
 import android.os.Bundle;
-import com.android.cts.view.R;
+import android.view.cts.R;
 
 public class InputMethodCtsActivity extends Activity {
     @Override
diff --git a/tests/tests/view/src/android/view/inputmethod/cts/InputMethodInfoTest.java b/tests/tests/view/src/android/view/inputmethod/cts/InputMethodInfoTest.java
index 1a067b4..3e071b6 100644
--- a/tests/tests/view/src/android/view/inputmethod/cts/InputMethodInfoTest.java
+++ b/tests/tests/view/src/android/view/inputmethod/cts/InputMethodInfoTest.java
@@ -37,7 +37,6 @@
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.HashMap;
 import java.util.List;
 
 public class InputMethodInfoTest extends AndroidTestCase {
@@ -202,10 +201,9 @@
             return;
         }
 
-        final InputMethodManager imm = (InputMethodManager) mContext
-                .getSystemService(Context.INPUT_METHOD_SERVICE);
+        final InputMethodManager imm = mContext.getSystemService(InputMethodManager.class);
         final List<InputMethodInfo> imis = imm.getInputMethodList();
-        final ArrayList<String> localeList = new ArrayList<String>(Arrays.asList(
+        final ArrayList<String> localeList = new ArrayList<>(Arrays.asList(
                 Resources.getSystem().getAssets().getLocales()));
         boolean foundEnabledSystemImeSubtypeWithValidLanguage = false;
         for (InputMethodInfo imi : imis) {
@@ -239,6 +237,32 @@
         assertTrue(foundEnabledSystemImeSubtypeWithValidLanguage);
     }
 
+    public void testAtLeastOneEncryptionAwareInputMethodIsAvailable() {
+        if (!getContext().getPackageManager().hasSystemFeature(
+                PackageManager.FEATURE_INPUT_METHODS)) {
+            return;
+        }
+
+        final InputMethodManager imm = mContext.getSystemService(InputMethodManager.class);
+        final List<InputMethodInfo> imis = imm.getInputMethodList();
+        boolean hasEncryptionAwareInputMethod = false;
+        for (final InputMethodInfo imi : imis) {
+            final ServiceInfo serviceInfo = imi.getServiceInfo();
+            if (serviceInfo == null) {
+                continue;
+            }
+            if ((serviceInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) !=
+                    ApplicationInfo.FLAG_SYSTEM) {
+                continue;
+            }
+            if (serviceInfo.encryptionAware) {
+                hasEncryptionAwareInputMethod = true;
+                break;
+            }
+        }
+        assertTrue(hasEncryptionAwareInputMethod);
+    }
+
     class MockPrinter implements Printer {
         @Override
         public void println(String x) {
diff --git a/tests/tests/view/src/android/view/inputmethod/cts/InputMethodManagerTest.java b/tests/tests/view/src/android/view/inputmethod/cts/InputMethodManagerTest.java
index b84292f..9389e92 100644
--- a/tests/tests/view/src/android/view/inputmethod/cts/InputMethodManagerTest.java
+++ b/tests/tests/view/src/android/view/inputmethod/cts/InputMethodManagerTest.java
@@ -15,7 +15,7 @@
  */
 package android.view.inputmethod.cts;
 
-import com.android.cts.view.R;
+import android.view.cts.R;
 
 import android.app.Instrumentation;
 import android.content.Context;
@@ -38,7 +38,7 @@
                   extends ActivityInstrumentationTestCase2<InputMethodCtsActivity> {
 
     public InputMethodManagerTest() {
-        super("com.android.cts.view", InputMethodCtsActivity.class);
+        super("android.view.cts", InputMethodCtsActivity.class);
     }
 
     private InputMethodCtsActivity mActivity;
@@ -98,10 +98,11 @@
         assertTrue(imManager.isAcceptingText());
         assertTrue(imManager.isActive(view));
 
-        connection.reportFullscreenMode(false);
         assertFalse(imManager.isFullscreenMode());
         connection.reportFullscreenMode(true);
-        assertTrue(imManager.isFullscreenMode());
+        // Only IMEs are allowed to report full-screen mode.  Calling this method from the
+        // application should have no effect.
+        assertFalse(imManager.isFullscreenMode());
 
         runTestOnUiThread(new Runnable() {
             @Override
diff --git a/tests/tests/view/src/android/view/inputmethod/cts/KeyboardTest.java b/tests/tests/view/src/android/view/inputmethod/cts/KeyboardTest.java
index ce7f9d7..f56ad0e 100644
--- a/tests/tests/view/src/android/view/inputmethod/cts/KeyboardTest.java
+++ b/tests/tests/view/src/android/view/inputmethod/cts/KeyboardTest.java
@@ -16,7 +16,7 @@
 
 package android.view.inputmethod.cts;
 
-import com.android.cts.view.R;
+import android.view.cts.R;
 
 import android.os.Build.VERSION;
 import android.os.Build.VERSION_CODES;
diff --git a/tests/tests/view/src/android/view/inputmethod/cts/util/InputConnectionTestUtils.java b/tests/tests/view/src/android/view/inputmethod/cts/util/InputConnectionTestUtils.java
new file mode 100644
index 0000000..3735c33
--- /dev/null
+++ b/tests/tests/view/src/android/view/inputmethod/cts/util/InputConnectionTestUtils.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.view.inputmethod.cts.util;
+
+import android.text.Selection;
+import android.text.SpannableStringBuilder;
+
+public final class InputConnectionTestUtils {
+
+    /**
+     * A utility function to generate test string for input method APIs.  There are several
+     * pre-defined meta characters that are useful for unit tests.
+     *
+     * <p>Pre-defined meta characters:</p>
+     * <dl>
+     *     <dl>{@code [}</dl><dd>The text selection starts from here.</dd>
+     *     <dl>{@code ]}</dl><dd>The text selection ends at here.</dd>
+     *     <dl>{@code <}</dl><dd>Represents a high surrogate character.</dd>
+     *     <dl>{@code >}</dl><dd>Represents a low surrogate character.</dd>
+     * </ul>
+     *
+     * <p>Examples: {@code "012[3<>67]89"} will be converted to {@ode "0123HL6789"}, where
+     * {@code "H"} and {@code "L"} indicate certain high and low surrogate characters, respectively,
+     * with selecting {@code "3HL67"}.</p>
+     *
+     * @param formatString
+     * @return A {@link CharSequence} object with text selection specified by the meta characters.
+     */
+    public static CharSequence formatString(final String formatString) {
+        final String U1F427 = "\uD83D\uDC27";
+        final SpannableStringBuilder builder = new SpannableStringBuilder();
+        int selectionStart = -1;
+        int selectionEnd = -1;
+        for (int i = 0; i < formatString.length(); ++i) {
+            final Character c = formatString.charAt(i);
+            switch (c) {
+                case '[':
+                    selectionStart = builder.length();
+                    break;
+                case ']':
+                    selectionEnd = builder.length();
+                    break;
+                case '<':
+                    builder.append(U1F427.charAt(0));  // High surrogate
+                    break;
+                case '>':
+                    builder.append(U1F427.charAt(1));  // Low surrogate
+                    break;
+                default:
+                    builder.append(c);
+                    break;
+            }
+        }
+        if (selectionStart < 0) {
+            throw new UnsupportedOperationException("Selection marker '[' must be specified.");
+        }
+        if (selectionEnd < 0) {
+            throw new UnsupportedOperationException("Selection marker ']' must be specified.");
+        }
+        Selection.setSelection(builder, selectionStart, selectionEnd);
+        return builder;
+    }
+}
diff --git a/tests/tests/voiceinteraction/Android.mk b/tests/tests/voiceinteraction/Android.mk
index b8f95e3..e470f86 100644
--- a/tests/tests/voiceinteraction/Android.mk
+++ b/tests/tests/voiceinteraction/Android.mk
@@ -27,6 +27,11 @@
 
 LOCAL_PACKAGE_NAME := CtsVoiceInteractionTestCases
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_CTS_MODULE_CONFIG := $(LOCAL_PATH)/Old$(CTS_MODULE_TEST_CONFIG)
+
 LOCAL_SDK_VERSION := current
 
 include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/voiceinteraction/AndroidManifest.xml b/tests/tests/voiceinteraction/AndroidManifest.xml
index 4c6989f..562f030 100644
--- a/tests/tests/voiceinteraction/AndroidManifest.xml
+++ b/tests/tests/voiceinteraction/AndroidManifest.xml
@@ -32,6 +32,13 @@
               <category android:name="android.intent.category.DEFAULT" />
           </intent-filter>
       </activity>
+      <activity android:name="TestLocalInteractionActivity"
+                android:label="Local Interaction Activity">
+          <intent-filter>
+              <action android:name="android.intent.action.TEST_LOCAL_INTERACTION_ACTIVITY" />
+              <category android:name="android.intent.category.DEFAULT" />
+          </intent-filter>
+      </activity>
     </application>
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
diff --git a/tests/tests/voiceinteraction/AndroidTest.xml b/tests/tests/voiceinteraction/AndroidTest.xml
index fa1ab70..c69c247 100644
--- a/tests/tests/voiceinteraction/AndroidTest.xml
+++ b/tests/tests/voiceinteraction/AndroidTest.xml
@@ -13,11 +13,19 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<configuration description="Test module config for VoiceInteraction">
-    <include name="common-config" />
-    <option name="cts-apk-installer:test-file-name" value="CtsVoiceInteractionService.apk" />
-    <option name="cts-apk-installer:test-file-name" value="CtsVoiceInteractionApp.apk" />
-    <option name="run-command:run-command"
-         value="settings put secure voice_interaction_service android.voiceinteraction.service/.MainInteractionService" />
-    <option name="cts-apk-installer:test-file-name" value="CtsVoiceInteractionTestCases.apk" />
+<configuration description="Config for CTS Voice Interaction test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsVoiceInteractionService.apk" />
+        <option name="test-file-name" value="CtsVoiceInteractionApp.apk" />
+        <option name="test-file-name" value="CtsVoiceInteractionTestCases.apk" />
+    </target_preparer>
+
+    <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+        <option name="run-command" value="settings put secure voice_interaction_service android.voiceinteraction.service/.MainInteractionService" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.voiceinteraction.cts" />
+    </test>
 </configuration>
diff --git a/tests/tests/voiceinteraction/OldAndroidTest.xml b/tests/tests/voiceinteraction/OldAndroidTest.xml
new file mode 100644
index 0000000..fa1ab70
--- /dev/null
+++ b/tests/tests/voiceinteraction/OldAndroidTest.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Test module config for VoiceInteraction">
+    <include name="common-config" />
+    <option name="cts-apk-installer:test-file-name" value="CtsVoiceInteractionService.apk" />
+    <option name="cts-apk-installer:test-file-name" value="CtsVoiceInteractionApp.apk" />
+    <option name="run-command:run-command"
+         value="settings put secure voice_interaction_service android.voiceinteraction.service/.MainInteractionService" />
+    <option name="cts-apk-installer:test-file-name" value="CtsVoiceInteractionTestCases.apk" />
+</configuration>
diff --git a/tests/tests/voiceinteraction/common/src/android/voiceinteraction/common/Utils.java b/tests/tests/voiceinteraction/common/src/android/voiceinteraction/common/Utils.java
index ff3bcfd..fc8916e 100644
--- a/tests/tests/voiceinteraction/common/src/android/voiceinteraction/common/Utils.java
+++ b/tests/tests/voiceinteraction/common/src/android/voiceinteraction/common/Utils.java
@@ -61,6 +61,9 @@
     public static final String COMMANDREQUEST_CANCEL_SUCCESS = "commandrequest cancel ok";
     public static final String TEST_ERROR = "Error In Test:";
 
+    public static final String PRIVATE_OPTIONS_KEY = "private_key";
+    public static final String PRIVATE_OPTIONS_VALUE = "private_value";
+
     public static final String toBundleString(Bundle bundle) {
         if (bundle == null) {
             return "*** Bundle is null ****";
diff --git a/tests/tests/voiceinteraction/service/Android.mk b/tests/tests/voiceinteraction/service/Android.mk
index 4338f13..c485f21 100644
--- a/tests/tests/voiceinteraction/service/Android.mk
+++ b/tests/tests/voiceinteraction/service/Android.mk
@@ -27,6 +27,9 @@
 
 LOCAL_PACKAGE_NAME := CtsVoiceInteractionService
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_SDK_VERSION := current
 
 include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/tests/tests/voiceinteraction/service/res/xml/interaction_service.xml b/tests/tests/voiceinteraction/service/res/xml/interaction_service.xml
index dd7e7b8..fa256ef 100644
--- a/tests/tests/voiceinteraction/service/res/xml/interaction_service.xml
+++ b/tests/tests/voiceinteraction/service/res/xml/interaction_service.xml
@@ -18,4 +18,5 @@
     android:sessionService="android.voiceinteraction.service.MainInteractionSessionService"
     android:recognitionService="android.voiceinteraction.service.MainRecognitionService"
     android:settingsActivity="android.voiceinteraction.service.SettingsActivity"
-    android:supportsAssist="false" />
+    android:supportsAssist="false"
+    android:supportsLocalInteraction="true" />
diff --git a/tests/tests/voiceinteraction/service/src/android/voiceinteraction/service/MainInteractionSession.java b/tests/tests/voiceinteraction/service/src/android/voiceinteraction/service/MainInteractionSession.java
index eeb4047..788224e 100644
--- a/tests/tests/voiceinteraction/service/src/android/voiceinteraction/service/MainInteractionSession.java
+++ b/tests/tests/voiceinteraction/service/src/android/voiceinteraction/service/MainInteractionSession.java
@@ -60,7 +60,16 @@
     public void onShow(Bundle args, int showFlags) {
         super.onShow(args, showFlags);
         mStartIntent = args.getParcelable("intent");
-        startVoiceActivity(mStartIntent);
+        if (mStartIntent != null) {
+            startVoiceActivity(mStartIntent);
+        } else if ((showFlags & SHOW_SOURCE_ACTIVITY) == SHOW_SOURCE_ACTIVITY) {
+            // Verify args
+            if (args == null
+                    || !Utils.PRIVATE_OPTIONS_VALUE.equals(
+                            args.getString(Utils.PRIVATE_OPTIONS_KEY))) {
+                throw new IllegalArgumentException("Incorrect arguments for SHOW_SOURCE_ACTIVITY");
+            }
+        }
     }
 
     void assertPromptFromTestApp(CharSequence prompt, Bundle extras) {
diff --git a/tests/tests/voiceinteraction/src/android/voiceinteraction/cts/LocalVoiceInteractionTest.java b/tests/tests/voiceinteraction/src/android/voiceinteraction/cts/LocalVoiceInteractionTest.java
new file mode 100644
index 0000000..55ebebe
--- /dev/null
+++ b/tests/tests/voiceinteraction/src/android/voiceinteraction/cts/LocalVoiceInteractionTest.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.voiceinteraction.cts;
+
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Bundle;
+import android.test.ActivityInstrumentationTestCase2;
+import android.util.Log;
+
+import junit.framework.Assert;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import android.voiceinteraction.common.Utils;
+
+public class LocalVoiceInteractionTest
+        extends ActivityInstrumentationTestCase2<TestLocalInteractionActivity> {
+
+    private static final int TIMEOUT_MS = 20 * 1000;
+
+    private TestLocalInteractionActivity mTestActivity;
+    private Context mContext;
+    private final CountDownLatch mLatchStart = new CountDownLatch(1);
+    private final CountDownLatch mLatchStop = new CountDownLatch(1);
+
+    public LocalVoiceInteractionTest() {
+        super(TestLocalInteractionActivity.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        startTestActivity();
+        mContext = getInstrumentation().getTargetContext();
+    }
+
+    private void startTestActivity() throws Exception {
+        Intent intent = new Intent();
+        intent.setAction("android.intent.action.TEST_LOCAL_INTERACTION_ACTIVITY");
+        intent.setComponent(new ComponentName(getInstrumentation().getContext(),
+                TestLocalInteractionActivity.class));
+        setActivityIntent(intent);
+        mTestActivity = getActivity();
+    }
+
+    public void testLifecycle() throws Exception {
+        assertTrue("Doesn't support LocalVoiceInteraction",
+                mTestActivity.isLocalVoiceInteractionSupported());
+        mTestActivity.startLocalInteraction(mLatchStart);
+        if (!mLatchStart.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
+            fail("Failed to start voice interaction in " + TIMEOUT_MS + "msec");
+            return;
+        }
+        mTestActivity.stopLocalInteraction(mLatchStop);
+        if (!mLatchStop.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
+            fail("Failed to stop voice interaction in " + TIMEOUT_MS + "msec");
+            return;
+        }
+        mTestActivity.finish();
+    }
+}
diff --git a/tests/tests/voiceinteraction/src/android/voiceinteraction/cts/TestLocalInteractionActivity.java b/tests/tests/voiceinteraction/src/android/voiceinteraction/cts/TestLocalInteractionActivity.java
new file mode 100644
index 0000000..4999fbe
--- /dev/null
+++ b/tests/tests/voiceinteraction/src/android/voiceinteraction/cts/TestLocalInteractionActivity.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.voiceinteraction.cts;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.content.ComponentName;
+import android.content.Context;
+import android.os.Bundle;
+import android.util.Log;
+import android.voiceinteraction.common.Utils;
+
+import java.util.concurrent.CountDownLatch;
+
+public class TestLocalInteractionActivity extends Activity {
+    static final String TAG = "TestLocalInteractionActivity";
+
+    private CountDownLatch mStarted;
+    private CountDownLatch mStopped;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        Log.i(TAG, " in onCreate");
+    }
+
+    void startLocalInteraction(CountDownLatch counter) {
+        Bundle privateOptions = new Bundle();
+        privateOptions.putString(Utils.PRIVATE_OPTIONS_KEY, Utils.PRIVATE_OPTIONS_VALUE);
+        mStarted = counter;
+        startLocalVoiceInteraction(privateOptions);
+    }
+
+    @Override
+    public void onLocalVoiceInteractionStarted() {
+        Log.i(TAG, " in onLocalVoiceInteractionStarted");
+        if (mStarted != null) {
+            mStarted.countDown();
+        }
+    }
+
+    void stopLocalInteraction(CountDownLatch counter) {
+        mStopped = counter;
+        stopLocalVoiceInteraction();
+    }
+
+    @Override
+    public void onLocalVoiceInteractionStopped() {
+        Log.i(TAG, " in onLocalVoiceInteractionStarted");
+        if (mStopped != null) {
+            mStopped.countDown();
+        }
+    }
+}
diff --git a/tests/tests/voiceinteraction/testapp/Android.mk b/tests/tests/voiceinteraction/testapp/Android.mk
index 7453880..aa40e53 100644
--- a/tests/tests/voiceinteraction/testapp/Android.mk
+++ b/tests/tests/voiceinteraction/testapp/Android.mk
@@ -29,4 +29,7 @@
 
 LOCAL_SDK_VERSION := current
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/tests/tests/voicesettings/Android.mk b/tests/tests/voicesettings/Android.mk
index e6bb108..4f53362 100644
--- a/tests/tests/voicesettings/Android.mk
+++ b/tests/tests/voicesettings/Android.mk
@@ -27,6 +27,11 @@
 
 LOCAL_PACKAGE_NAME := CtsVoiceSettingsTestCases
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_CTS_MODULE_CONFIG := $(LOCAL_PATH)/Old$(CTS_MODULE_TEST_CONFIG)
+
 LOCAL_SDK_VERSION := current
 
 include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/voicesettings/AndroidTest.xml b/tests/tests/voicesettings/AndroidTest.xml
index e3be691..64f5335 100644
--- a/tests/tests/voicesettings/AndroidTest.xml
+++ b/tests/tests/voicesettings/AndroidTest.xml
@@ -1,3 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
 <!-- Copyright (C) 2015 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
@@ -12,10 +13,16 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<configuration description="Test module config for VoiceInteraction">
-    <include name="common-config" />
-    <option name="cts-apk-installer:test-file-name" value="CtsVoiceSettingsService.apk" />
-    <option name="run-command:run-command"
-         value="settings put secure voice_interaction_service android.voicesettings.service/.MainInteractionService" />
-    <option name="cts-apk-installer:test-file-name" value="CtsVoiceSettingsTestCases.apk" />
+<configuration description="Config for CTS Voice Settings test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsVoiceSettingsService.apk" />
+        <option name="test-file-name" value="CtsVoiceSettingsTestCases.apk" />
+    </target_preparer>
+    <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+        <option name="run-command" value="settings put secure voice_interaction_service android.voicesettings.service/.MainInteractionService" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.voicesettings.cts" />
+    </test>
 </configuration>
diff --git a/tests/tests/voicesettings/OldAndroidTest.xml b/tests/tests/voicesettings/OldAndroidTest.xml
new file mode 100644
index 0000000..246bf06
--- /dev/null
+++ b/tests/tests/voicesettings/OldAndroidTest.xml
@@ -0,0 +1,20 @@
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Test module config for VoiceSettings">
+    <include name="common-config" />
+    <option name="cts-apk-installer:test-file-name" value="CtsVoiceSettingsService.apk" />
+    <option name="run-command:run-command"
+         value="settings put secure voice_interaction_service android.voicesettings.service/.MainInteractionService" />
+</configuration>
diff --git a/tests/tests/voicesettings/service/Android.mk b/tests/tests/voicesettings/service/Android.mk
index d472ade..cc26569 100644
--- a/tests/tests/voicesettings/service/Android.mk
+++ b/tests/tests/voicesettings/service/Android.mk
@@ -27,6 +27,9 @@
 
 LOCAL_PACKAGE_NAME := CtsVoiceSettingsService
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 LOCAL_SDK_VERSION := current
 
 include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/tests/tests/webkit/Android.mk b/tests/tests/webkit/Android.mk
index 17a1f27..3a09f77 100644
--- a/tests/tests/webkit/Android.mk
+++ b/tests/tests/webkit/Android.mk
@@ -23,12 +23,20 @@
 
 LOCAL_JAVA_LIBRARIES := android.test.runner org.apache.http.legacy
 
-LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctsdeviceutillegacy ctstestserver ctstestrunner
+LOCAL_STATIC_JAVA_LIBRARIES := \
+    ctsdeviceutil \
+    ctsdeviceutillegacy \
+    ctstestserver \
+    ctstestrunner \
+    platform-test-annotations
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
 LOCAL_PACKAGE_NAME := CtsWebkitTestCases
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 # uncomment when dalvik.annotation.Test* are removed or part of SDK
 #LOCAL_SDK_VERSION := current
 
diff --git a/tests/tests/webkit/AndroidManifest.xml b/tests/tests/webkit/AndroidManifest.xml
index fa25824..44df7c4 100644
--- a/tests/tests/webkit/AndroidManifest.xml
+++ b/tests/tests/webkit/AndroidManifest.xml
@@ -16,7 +16,7 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.webkit">
+    package="android.webkit.cts">
 
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"/>
@@ -59,7 +59,7 @@
     </application>
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.cts.webkit"
+                     android:targetPackage="android.webkit.cts"
                      android:label="CTS tests of android.webkit">
         <meta-data android:name="listener"
             android:value="com.android.cts.runner.CtsTestRunListener" />
diff --git a/tests/tests/webkit/AndroidTest.xml b/tests/tests/webkit/AndroidTest.xml
new file mode 100644
index 0000000..e6649e1
--- /dev/null
+++ b/tests/tests/webkit/AndroidTest.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS Webkit test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.WifiCheck" />
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.LocationCheck" />
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsWebkitTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.webkit.cts" />
+        <option name="runtime-hint" value="6m39s" />
+    </test>
+
+</configuration>
diff --git a/tests/tests/webkit/assets/webkit/jsunload.html b/tests/tests/webkit/assets/webkit/jsunload.html
index fb0673e..f016eb7 100644
--- a/tests/tests/webkit/assets/webkit/jsunload.html
+++ b/tests/tests/webkit/assets/webkit/jsunload.html
@@ -19,7 +19,7 @@
     </head>
     <script type="text/javascript">
         function fireUnload() {
-            return "testOnJsBeforeUnload";
+            return "this message will be a hardcoded string in chrome.";
         }
         window.onbeforeunload = fireUnload;
     </script>
diff --git a/tests/tests/webkit/assets/webkit/test_loginForm.html b/tests/tests/webkit/assets/webkit/test_loginForm.html
new file mode 100644
index 0000000..0935cf1
--- /dev/null
+++ b/tests/tests/webkit/assets/webkit/test_loginForm.html
@@ -0,0 +1,23 @@
+<!-- Copyright (C) 2009 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<html>
+    <body>
+        <form>
+            <input type='text' name='username' value='Cts Test'/>
+            <input type='submit' name='submit' value='Submit'/>
+        </form>
+    </body>
+</html>
diff --git a/tests/tests/webkit/src/android/webkit/cts/CookieManagerTest.java b/tests/tests/webkit/src/android/webkit/cts/CookieManagerTest.java
index 856b4aa..ffde739 100644
--- a/tests/tests/webkit/src/android/webkit/cts/CookieManagerTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/CookieManagerTest.java
@@ -42,7 +42,7 @@
     private WebViewOnUiThread mOnUiThread;
 
     public CookieManagerTest() {
-        super("com.android.cts.webkit", CookieSyncManagerCtsActivity.class);
+        super("android.webkit.cts", CookieSyncManagerCtsActivity.class);
     }
 
     @Override
diff --git a/tests/tests/webkit/src/android/webkit/cts/CookieTest.java b/tests/tests/webkit/src/android/webkit/cts/CookieTest.java
index 555266b..4f89ec1 100644
--- a/tests/tests/webkit/src/android/webkit/cts/CookieTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/CookieTest.java
@@ -17,6 +17,7 @@
 package android.webkit.cts;
 
 import android.cts.util.NullWebViewUtils;
+import android.platform.test.annotations.Presubmit;
 import android.test.ActivityInstrumentationTestCase2;
 import android.webkit.CookieManager;
 import android.webkit.CookieSyncManager;
@@ -30,7 +31,7 @@
     private static final long WAIT_TIME = 50;
 
     public CookieTest() {
-        super("com.android.cts.webkit", CookieSyncManagerCtsActivity.class);
+        super("android.webkit.cts", CookieSyncManagerCtsActivity.class);
     }
 
     @Override
@@ -56,6 +57,7 @@
         assertFalse(mCookieManager.hasCookies());
     }
 
+    @Presubmit
     public void testDomain() {
         if (!NullWebViewUtils.isWebViewAvailable()) {
             return;
diff --git a/tests/tests/webkit/src/android/webkit/cts/GeolocationTest.java b/tests/tests/webkit/src/android/webkit/cts/GeolocationTest.java
index 7ab4fe2..1394ccd 100644
--- a/tests/tests/webkit/src/android/webkit/cts/GeolocationTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/GeolocationTest.java
@@ -62,8 +62,8 @@
 
     // The URLs does not matter since the tests will intercept the load, but it has to be a real
     // url, and different domains.
-    private static final String URL_1 = "http://www.example.com";
-    private static final String URL_2 = "http://www.example.org";
+    private static final String URL_1 = "https://www.example.com";
+    private static final String URL_2 = "https://www.example.org";
 
     private static final String JS_INTERFACE_NAME = "Android";
     private static final int POLLING_TIMEOUT = 60 * 1000;
@@ -110,7 +110,7 @@
     private List<String> mProviders;
 
     public GeolocationTest() throws Exception {
-        super("com.android.cts.webkit", WebViewCtsActivity.class);
+        super("android.webkit.cts", WebViewCtsActivity.class);
     }
 
     // Both this test and WebViewOnUiThread need to override some of the methods on WebViewClient,
diff --git a/tests/tests/webkit/src/android/webkit/cts/HttpAuthHandlerTest.java b/tests/tests/webkit/src/android/webkit/cts/HttpAuthHandlerTest.java
index 5c86987..10bf6d8 100644
--- a/tests/tests/webkit/src/android/webkit/cts/HttpAuthHandlerTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/HttpAuthHandlerTest.java
@@ -38,7 +38,7 @@
     private WebViewOnUiThread mOnUiThread;
 
     public HttpAuthHandlerTest() {
-        super("com.android.cts.webkit", WebViewCtsActivity.class);
+        super("android.webkit.cts", WebViewCtsActivity.class);
     }
 
     @Override
diff --git a/tests/tests/webkit/src/android/webkit/cts/PostMessageTest.java b/tests/tests/webkit/src/android/webkit/cts/PostMessageTest.java
index 2a6af6e..6ffe69c 100644
--- a/tests/tests/webkit/src/android/webkit/cts/PostMessageTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/PostMessageTest.java
@@ -38,7 +38,7 @@
     private static final String BASE_URI = "http://www.example.com";
 
     public PostMessageTest() {
-        super("com.android.cts.webkit", WebViewCtsActivity.class);
+        super("android.webkit.cts", WebViewCtsActivity.class);
     }
 
     @Override
diff --git a/tests/tests/webkit/src/android/webkit/cts/ServiceWorkerClientTest.java b/tests/tests/webkit/src/android/webkit/cts/ServiceWorkerClientTest.java
new file mode 100644
index 0000000..a77d648
--- /dev/null
+++ b/tests/tests/webkit/src/android/webkit/cts/ServiceWorkerClientTest.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.webkit.cts;
+
+import android.cts.util.PollingCheck;
+import android.test.ActivityInstrumentationTestCase2;
+
+import android.webkit.JavascriptInterface;
+import android.webkit.ServiceWorkerController;
+import android.webkit.ServiceWorkerClient;
+import android.webkit.WebResourceResponse;
+import android.webkit.WebResourceRequest;
+import android.webkit.WebView;
+import android.webkit.WebViewClient;
+import android.webkit.cts.WebViewOnUiThread.WaitForLoadedClient;
+
+import java.io.ByteArrayInputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Callable;
+
+
+public class ServiceWorkerClientTest extends ActivityInstrumentationTestCase2<WebViewCtsActivity> {
+
+    // The BASE_URL does not matter since the tests will intercept the load, but it should be https
+    // for the Service Worker registration to succeed.
+    private static final String BASE_URL = "https://www.example.com/";
+    private static final String INDEX_URL = BASE_URL + "index.html";
+    private static final String SW_URL = BASE_URL + "sw.js";
+    private static final String FETCH_URL = BASE_URL + "fetch.html";
+
+    private static final String JS_INTERFACE_NAME = "Android";
+    private static final int POLLING_TIMEOUT = 60 * 1000;
+
+    // static HTML page always injected instead of the url loaded.
+    private static final String INDEX_RAW_HTML =
+            "<!DOCTYPE html>\n"
+            + "<html>\n"
+            + "  <body>\n"
+            + "    <script>\n"
+            + "      navigator.serviceWorker.register('sw.js').then(function(reg) {\n"
+            + "         " + JS_INTERFACE_NAME + ".registrationSuccess();\n"
+            + "      }).catch(function(err) { \n"
+            + "         console.error(err);\n"
+            + "      });\n"
+            + "    </script>\n"
+            + "  </body>\n"
+            + "</html>\n";
+    private static final String SW_RAW_HTML = "fetch('fetch.html');";
+
+    private JavascriptStatusReceiver mJavascriptStatusReceiver;
+    private WebViewOnUiThread mOnUiThread;
+
+    public ServiceWorkerClientTest() throws Exception {
+        super("android.webkit.cts", WebViewCtsActivity.class);
+    }
+
+    // Both this test and WebViewOnUiThread need to override some of the methods on WebViewClient,
+    // so this test subclasses the WebViewClient from WebViewOnUiThread.
+    private static class InterceptClient extends WaitForLoadedClient {
+
+        public InterceptClient(WebViewOnUiThread webViewOnUiThread) throws Exception {
+            super(webViewOnUiThread);
+        }
+
+        @Override
+        public WebResourceResponse shouldInterceptRequest(WebView view,
+                WebResourceRequest request) {
+            // Only return content for INDEX_URL, deny all other requests.
+            try {
+                if (request.getUrl().toString().equals(INDEX_URL)) {
+                    return new WebResourceResponse("text/html", "utf-8",
+                        new ByteArrayInputStream(INDEX_RAW_HTML.getBytes("UTF-8")));
+                }
+            } catch(java.io.UnsupportedEncodingException e) {}
+            return new WebResourceResponse("text/html", "UTF-8", null);
+        }
+    }
+
+    public static class InterceptServiceWorkerClient extends ServiceWorkerClient {
+        private List<WebResourceRequest> mInterceptedRequests = new ArrayList<WebResourceRequest>();
+
+        @Override
+        public WebResourceResponse shouldInterceptRequest(WebResourceRequest request) {
+            // Records intercepted requests and only return content for SW_URL.
+            mInterceptedRequests.add(request);
+            try {
+                if (request.getUrl().toString().equals(SW_URL)) {
+                    return new WebResourceResponse("application/javascript", "utf-8",
+                        new ByteArrayInputStream(SW_RAW_HTML.getBytes("UTF-8")));
+                }
+            } catch(java.io.UnsupportedEncodingException e) {}
+            return new WebResourceResponse("text/html", "UTF-8", null);
+        }
+
+        List<WebResourceRequest> getInterceptedRequests() {
+            return mInterceptedRequests;
+        }
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        WebView webview = getActivity().getWebView();
+        if (webview == null) return;
+        mOnUiThread = new WebViewOnUiThread(this, webview);
+        mOnUiThread.getSettings().setJavaScriptEnabled(true);
+
+        mJavascriptStatusReceiver = new JavascriptStatusReceiver();
+        mOnUiThread.addJavascriptInterface(mJavascriptStatusReceiver, JS_INTERFACE_NAME);
+        mOnUiThread.setWebViewClient(new InterceptClient(mOnUiThread));
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        if (mOnUiThread != null) {
+            mOnUiThread.cleanUp();
+        }
+        super.tearDown();
+    }
+
+    // Test correct invocation of shouldInterceptRequest for Service Workers.
+    public void testServiceWorkerClientInterceptCallback() throws Exception {
+        final InterceptServiceWorkerClient mInterceptServiceWorkerClient =
+                new InterceptServiceWorkerClient();
+        ServiceWorkerController swController = ServiceWorkerController.getInstance();
+        swController.setServiceWorkerClient(mInterceptServiceWorkerClient);
+
+        mOnUiThread.loadUrlAndWaitForCompletion(INDEX_URL);
+
+        Callable<Boolean> registrationSuccess = new Callable<Boolean>() {
+            @Override
+            public Boolean call() {
+                return mJavascriptStatusReceiver.mRegistrationSuccess;
+            }
+        };
+        PollingCheck.check("JS could not register Service Worker", POLLING_TIMEOUT,
+                registrationSuccess);
+
+        Callable<Boolean> receivedRequest = new Callable<Boolean>() {
+            @Override
+            public Boolean call() {
+                return mInterceptServiceWorkerClient.getInterceptedRequests().size() >= 2;
+            }
+        };
+        PollingCheck.check("Service Worker intercept callbacks not invoked", POLLING_TIMEOUT,
+                receivedRequest);
+
+        List<WebResourceRequest> requests = mInterceptServiceWorkerClient.getInterceptedRequests();
+        assertEquals(2, requests.size());
+        assertEquals(SW_URL, requests.get(0).getUrl().toString());
+        assertEquals(FETCH_URL, requests.get(1).getUrl().toString());
+    }
+
+    // Object added to the page via AddJavascriptInterface() that is used by the test Javascript to
+    // notify back to Java if the Service Worker registration was successful.
+    public final static class JavascriptStatusReceiver {
+        public volatile boolean mRegistrationSuccess = false;
+
+        @JavascriptInterface
+        public void registrationSuccess() {
+            mRegistrationSuccess = true;
+        }
+    }
+}
+
diff --git a/tests/tests/webkit/src/android/webkit/cts/TestHtmlConstants.java b/tests/tests/webkit/src/android/webkit/cts/TestHtmlConstants.java
index 1ab5e5a..68d944b 100644
--- a/tests/tests/webkit/src/android/webkit/cts/TestHtmlConstants.java
+++ b/tests/tests/webkit/src/android/webkit/cts/TestHtmlConstants.java
@@ -55,6 +55,8 @@
     public static final String BLANK_PAGE_URL = "webkit/test_blankPage.html";
     public static final String ADD_JAVA_SCRIPT_INTERFACE_URL = "webkit/test_jsInterface.html";
 
+    public static final String LOGIN_FORM_URL = "webkit/test_loginForm.html";
+
     public static final String EXT_WEB_URL1 = "http://www.example.com/";
 
     public static final String LOCAL_FILESYSTEM_URL = "file:///etc/hosts";
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebBackForwardListTest.java b/tests/tests/webkit/src/android/webkit/cts/WebBackForwardListTest.java
index 7d25b84..e7d6211 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebBackForwardListTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebBackForwardListTest.java
@@ -31,7 +31,7 @@
     private WebViewOnUiThread mOnUiThread;
 
     public WebBackForwardListTest() {
-        super("com.android.cts.webkit", WebViewCtsActivity.class);
+        super("android.webkit.cts", WebViewCtsActivity.class);
     }
 
     @Override
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebChromeClientTest.java b/tests/tests/webkit/src/android/webkit/cts/WebChromeClientTest.java
index 150fd86..424d856 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebChromeClientTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebChromeClientTest.java
@@ -198,7 +198,7 @@
         runWindowTest(false);
     }
 
-    public void testOnJsBeforeUnload() throws Exception {
+    public void testOnJsBeforeUnloadIsCalled() throws Exception {
         if (!NullWebViewUtils.isWebViewAvailable()) {
             return;
         }
@@ -221,7 +221,6 @@
                 return webChromeClient.hadOnJsBeforeUnload();
             }
         }.run();
-        assertEquals(webChromeClient.getMessage(), "testOnJsBeforeUnload");
     }
 
     public void testOnJsAlert() throws Exception {
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebHistoryItemTest.java b/tests/tests/webkit/src/android/webkit/cts/WebHistoryItemTest.java
index a6b647df..dc9e615 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebHistoryItemTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebHistoryItemTest.java
@@ -48,7 +48,7 @@
     };
 
     public WebHistoryItemTest() {
-        super("com.android.cts.webkit", WebViewCtsActivity.class);
+        super("android.webkit.cts", WebViewCtsActivity.class);
     }
 
     @Override
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java b/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
index 592e308..7729baf 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
@@ -64,7 +64,7 @@
     private Context mContext;
 
     public WebSettingsTest() {
-        super("com.android.cts.webkit", WebViewCtsActivity.class);
+        super("android.webkit.cts", WebViewCtsActivity.class);
     }
 
     @Override
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebViewClientTest.java b/tests/tests/webkit/src/android/webkit/cts/WebViewClientTest.java
index 0697429..ff30a2f 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebViewClientTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebViewClientTest.java
@@ -34,11 +34,14 @@
 import android.webkit.WebView;
 import android.webkit.WebViewClient;
 import android.webkit.cts.WebViewOnUiThread.WaitForLoadedClient;
+import android.util.Pair;
 
 import java.io.ByteArrayInputStream;
 import java.nio.charset.StandardCharsets;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.List;
+import java.util.ArrayList;
 
 public class WebViewClientTest extends ActivityInstrumentationTestCase2<WebViewCtsActivity> {
     private static final long TEST_TIMEOUT = 5000;
@@ -48,7 +51,7 @@
     private CtsTestServer mWebServer;
 
     public WebViewClientTest() {
-        super("com.android.cts.webkit", WebViewCtsActivity.class);
+        super("android.webkit.cts", WebViewCtsActivity.class);
     }
 
     @Override
@@ -85,7 +88,7 @@
             return;
         }
         final WebViewClient webViewClient = new WebViewClient();
-        assertFalse(webViewClient.shouldOverrideUrlLoading(mOnUiThread.getWebView(), null));
+        assertFalse(webViewClient.shouldOverrideUrlLoading(mOnUiThread.getWebView(), new String()));
     }
 
     // Verify shouldoverrideurlloading called on top level navigation
@@ -102,6 +105,10 @@
         mOnUiThread.loadDataAndWaitForCompletion(data, "text/html", null);
         clickOnLinkUsingJs("link", mOnUiThread);
         assertEquals(TEST_URL, webViewClient.getLastShouldOverrideUrl());
+        assertNotNull(webViewClient.getLastShouldOverrideResourceRequest());
+        assertTrue(webViewClient.getLastShouldOverrideResourceRequest().isForMainFrame());
+        assertFalse(webViewClient.getLastShouldOverrideResourceRequest().isRedirect());
+        assertFalse(webViewClient.getLastShouldOverrideResourceRequest().hasGesture());
     }
 
     // Verify shouldoverrideurlloading called on webview called via onCreateWindow
@@ -210,6 +217,40 @@
         }.run();
     }
 
+    public void testOnReceivedLoginRequest() throws Exception {
+        if (!NullWebViewUtils.isWebViewAvailable()) {
+            return;
+        }
+        final MockWebViewClient webViewClient = new MockWebViewClient();
+        mOnUiThread.setWebViewClient(webViewClient);
+        TestWebServer testServer = null;
+        //set the url and html
+        final String path = "/main";
+        final String page = "<head></head><body>test onReceivedLoginRequest</body>";
+        final String headerName = "x-auto-login";
+        final String headerValue = "realm=com.google&account=foo%40bar.com&args=random_string";
+        List<Pair<String, String>> headers = new ArrayList<Pair<String, String>>();
+        headers.add(Pair.create(headerName, headerValue));
+
+        try {
+            testServer = new TestWebServer(false);
+            String url = testServer.setResponse(path, page, headers);
+            assertFalse(webViewClient.hasOnReceivedLoginRequest());
+            mOnUiThread.loadUrlAndWaitForCompletion(url);
+            assertTrue(webViewClient.hasOnReceivedLoginRequest());
+            new PollingCheck(TEST_TIMEOUT) {
+                @Override
+                protected boolean check() {
+                    return webViewClient.hasOnReceivedLoginRequest();
+                }
+            }.run();
+           assertEquals("com.google", webViewClient.getLoginRequestRealm());
+           assertEquals("foo@bar.com", webViewClient.getLoginRequestAccount());
+           assertEquals("random_string", webViewClient.getLoginRequestArgs());
+        } finally {
+            testServer.shutdown();
+        }
+    }
     public void testOnReceivedError() throws Exception {
         if (!NullWebViewUtils.isWebViewAvailable()) {
             return;
@@ -541,10 +582,15 @@
         private boolean mOnFormResubmissionCalled;
         private boolean mDoUpdateVisitedHistoryCalled;
         private boolean mOnReceivedHttpAuthRequestCalled;
+        private boolean mOnReceivedLoginRequest;
+        private String mOnReceivedLoginAccount;
+        private String mOnReceivedLoginArgs;
+        private String mOnReceivedLoginRealm;
         private boolean mOnUnhandledKeyEventCalled;
         private boolean mOnScaleChangedCalled;
         private int mShouldOverrideUrlLoadingCallCount;
         private String mLastShouldOverrideUrl;
+        private WebResourceRequest mLastShouldOverrideResourceRequest;
 
         public MockWebViewClient() {
             super(mOnUiThread);
@@ -566,6 +612,10 @@
             return mOnReceivedErrorCode;
         }
 
+        public boolean hasOnReceivedLoginRequest() {
+            return mOnReceivedLoginRequest;
+        }
+
         public WebResourceError hasOnReceivedResourceError() {
             return mOnReceivedResourceError;
         }
@@ -602,6 +652,22 @@
             return mLastShouldOverrideUrl;
         }
 
+        public WebResourceRequest getLastShouldOverrideResourceRequest() {
+            return mLastShouldOverrideResourceRequest;
+        }
+
+        public String getLoginRequestRealm() {
+            return mOnReceivedLoginRealm;
+        }
+
+        public String getLoginRequestAccount() {
+            return mOnReceivedLoginAccount;
+        }
+
+        public String getLoginRequestArgs() {
+            return mOnReceivedLoginArgs;
+        }
+
         @Override
         public void onPageStarted(WebView view, String url, Bitmap favicon) {
             super.onPageStarted(view, url, favicon);
@@ -645,6 +711,16 @@
         }
 
         @Override
+        public void onReceivedLoginRequest(WebView view, String realm, String account,
+                String args) {
+            super.onReceivedLoginRequest(view, realm, account, args);
+            mOnReceivedLoginRequest = true;
+            mOnReceivedLoginRealm = realm;
+            mOnReceivedLoginAccount = account;
+            mOnReceivedLoginArgs = args;
+       }
+
+        @Override
         public void onFormResubmission(WebView view, Message dontResend, Message resend) {
             mOnFormResubmissionCalled = true;
             dontResend.sendToTarget();
@@ -678,6 +754,15 @@
         @Override
         public boolean shouldOverrideUrlLoading(WebView view, String url) {
             mLastShouldOverrideUrl = url;
+            mLastShouldOverrideResourceRequest = null;
+            mShouldOverrideUrlLoadingCallCount++;
+            return false;
+        }
+
+        @Override
+        public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
+            mLastShouldOverrideUrl = request.getUrl().toString();
+            mLastShouldOverrideResourceRequest = request;
             mShouldOverrideUrlLoadingCallCount++;
             return false;
         }
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebViewCtsActivity.java b/tests/tests/webkit/src/android/webkit/cts/WebViewCtsActivity.java
index 9af7266..1b05154 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebViewCtsActivity.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebViewCtsActivity.java
@@ -16,7 +16,7 @@
 
 package android.webkit.cts;
 
-import com.android.cts.webkit.R;
+import android.webkit.cts.R;
 
 import android.app.Activity;
 import android.cts.util.NullWebViewUtils;
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebViewSslTest.java b/tests/tests/webkit/src/android/webkit/cts/WebViewSslTest.java
index 6555731..e07267f 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebViewSslTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebViewSslTest.java
@@ -430,7 +430,7 @@
     private WebViewOnUiThread mOnUiThread;
 
     public WebViewSslTest() {
-        super("com.android.cts.webkit", WebViewCtsActivity.class);
+        super("android.webkit.cts", WebViewCtsActivity.class);
     }
 
     @Override
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebViewStartupTest.java b/tests/tests/webkit/src/android/webkit/cts/WebViewStartupTest.java
index 776cfab..a4ebaca 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebViewStartupTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebViewStartupTest.java
@@ -20,6 +20,7 @@
 import android.content.Context;
 import android.cts.util.NullWebViewUtils;
 import android.cts.util.PollingCheck;
+import android.os.StrictMode;
 import android.test.ActivityInstrumentationTestCase2;
 import android.test.UiThreadTest;
 import android.util.Log;
@@ -39,7 +40,7 @@
     private WebViewStartupCtsActivity mActivity;
 
     public WebViewStartupTest() {
-        super("com.android.cts.webkit", WebViewStartupCtsActivity.class);
+        super("android.webkit.cts", WebViewStartupCtsActivity.class);
     }
 
     @Override
@@ -89,4 +90,20 @@
         assertEquals("42", m.group(1)); // value got incremented
     }
 
+    @UiThreadTest
+    public void testStrictModeNotViolatedOnStartup() throws Throwable {
+        StrictMode.ThreadPolicy oldPolicy = StrictMode.getThreadPolicy();
+        StrictMode.ThreadPolicy testPolicy = new StrictMode.ThreadPolicy.Builder()
+            .detectDiskReads()
+            .penaltyLog()
+            .penaltyDeath()
+            .build();
+        StrictMode.setThreadPolicy(testPolicy);
+        try {
+            mActivity.createAndAttachWebView();
+        } finally {
+            StrictMode.setThreadPolicy(oldPolicy);
+        }
+    }
+
 }
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java b/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
index 23c8dba..3f4fd92 100755
--- a/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
@@ -1126,6 +1126,39 @@
         }.run();
     }
 
+    public void testClearFormData() throws Throwable {
+        if (!NullWebViewUtils.isWebViewAvailable()) {
+            return;
+        }
+        try {
+            startWebServer(false);
+            WebSettings settings = mOnUiThread.getSettings();
+            settings.setDatabaseEnabled(true);
+            WebViewDatabase webViewDatabase = WebViewDatabase.getInstance(getActivity());
+            webViewDatabase.clearFormData();
+            final String url = mWebServer.getAssetUrl(TestHtmlConstants.LOGIN_FORM_URL);
+            mOnUiThread.loadUrlAndWaitForCompletion(url);
+            new PollingCheck(TEST_TIMEOUT) {
+                @Override
+                public boolean check() {
+                    return !WebViewDatabase.getInstance(getActivity()).hasFormData();
+                }
+            }.run();
+
+            // click submit
+            moveFocusDown();
+            getInstrumentation().sendKeyDownUpSync(KeyEvent.KEYCODE_ENTER);
+            new PollingCheck(TEST_TIMEOUT) {
+                @Override
+                public boolean check() {
+                    return WebViewDatabase.getInstance(getActivity()).hasFormData();
+                }
+            }.run();
+        } finally {
+            WebViewDatabase.getInstance(getActivity()).clearFormData();
+        }
+    }
+
     @UiThreadTest
     public void testAccessHttpAuthUsernamePassword() {
         if (!NullWebViewUtils.isWebViewAvailable()) {
@@ -1592,7 +1625,7 @@
         } while (mOnUiThread.pageDown(false));
 
         waitForFlingDone(mOnUiThread);
-        int bottomScrollY = mOnUiThread.getScrollY();
+        final int bottomScrollY = mOnUiThread.getScrollY();
 
         assertTrue(mOnUiThread.pageUp(false));
 
@@ -1601,17 +1634,25 @@
         } while (mOnUiThread.pageUp(false));
 
         waitForFlingDone(mOnUiThread);
-        int topScrollY = mOnUiThread.getScrollY();
+        final int topScrollY = mOnUiThread.getScrollY();
 
         // jump to the bottom
         assertTrue(mOnUiThread.pageDown(true));
-        waitForFlingDone(mOnUiThread);
-        assertEquals(bottomScrollY, mOnUiThread.getScrollY());
+        new PollingCheck() {
+            @Override
+            protected boolean check() {
+                return bottomScrollY == mOnUiThread.getScrollY();
+            }
+        }.run();
 
         // jump to the top
         assertTrue(mOnUiThread.pageUp(true));
-        waitForFlingDone(mOnUiThread);
-        assertEquals(topScrollY, mOnUiThread.getScrollY());
+         new PollingCheck() {
+            @Override
+            protected boolean check() {
+                return topScrollY == mOnUiThread.getScrollY();
+            }
+        }.run();
     }
 
     public void testGetContentHeight() throws Throwable {
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebView_WebViewTransportTest.java b/tests/tests/webkit/src/android/webkit/cts/WebView_WebViewTransportTest.java
index 1db7fca..4fa9b4f 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebView_WebViewTransportTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebView_WebViewTransportTest.java
@@ -27,7 +27,7 @@
         extends ActivityInstrumentationTestCase2<WebViewCtsActivity> {
 
     public WebView_WebViewTransportTest() {
-        super("com.android.cts.webkit", WebViewCtsActivity.class);
+        super("android.webkit.cts", WebViewCtsActivity.class);
     }
 
     @UiThreadTest
diff --git a/tests/tests/widget/Android.mk b/tests/tests/widget/Android.mk
index 505f82c..96f10fc 100644
--- a/tests/tests/widget/Android.mk
+++ b/tests/tests/widget/Android.mk
@@ -21,7 +21,12 @@
 # and when built explicitly put it in the data partition
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
 
-LOCAL_STATIC_JAVA_LIBRARIES += android-common ctsdeviceutil ctstestrunner
+LOCAL_STATIC_JAVA_LIBRARIES += \
+    mockito-target \
+    android-common \
+    ctsdeviceutil \
+    ctstestrunner \
+    platform-test-annotations
 
 LOCAL_JAVA_LIBRARIES := android.test.runner
 
@@ -29,4 +34,7 @@
 
 LOCAL_PACKAGE_NAME := CtsWidgetTestCases
 
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
 include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/widget/AndroidManifest.xml b/tests/tests/widget/AndroidManifest.xml
index bc43106..48f2f06 100644
--- a/tests/tests/widget/AndroidManifest.xml
+++ b/tests/tests/widget/AndroidManifest.xml
@@ -16,7 +16,7 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.widget">
+    package="android.widget.cts">
 
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <application android:label="Android TestCase"
@@ -28,6 +28,14 @@
 
         <uses-library android:name="android.test.runner" />
 
+        <activity android:name="android.widget.cts.EmptyCtsActivity"
+                  android:label="EmptyCtsActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+            </intent-filter>
+        </activity>
+
         <activity android:name="android.widget.cts.TwoLineListItemCtsActivity"
             android:label="TwoLineListItemCtsActivity">
             <intent-filter>
@@ -69,7 +77,24 @@
         </activity>
 
         <activity android:name="android.widget.cts.ImageViewCtsActivity"
-            android:label="ImageViewCtsActivity">
+                  android:label="ImageViewCtsActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name="android.widget.cts.SwitchCtsActivity"
+                  android:label="SwitchCtsActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name="android.widget.cts.ToolbarCtsActivity"
+            android:theme="@android:style/Theme.Material.Light.NoActionBar"
+            android:label="ToolbarCtsActivity">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
@@ -196,8 +221,24 @@
             </intent-filter>
         </activity>
 
-        <activity android:name="android.widget.cts.MockPopupWindowCtsActivity"
-            android:label="MockPopupWindowCtsActivity">
+        <activity android:name="android.widget.cts.PopupWindowCtsActivity"
+            android:label="PopupWindowCtsActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name="android.widget.cts.PopupMenuCtsActivity"
+                  android:label="PopupMenuCtsActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name="android.widget.cts.ListPopupWindowCtsActivity"
+                  android:label="ListPopupWindowCtsActivity">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
@@ -335,6 +376,14 @@
             </intent-filter>
         </activity>
 
+        <activity android:name="android.widget.cts.CalendarViewCtsActivity"
+                  android:label="CalendarViewCtsActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+            </intent-filter>
+        </activity>
+
         <activity android:name="android.app.ActivityGroup"
             android:label="ActivityGroup" />
 
@@ -355,7 +404,7 @@
     </application>
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.cts.widget"
+                     android:targetPackage="android.widget.cts"
                      android:label="CTS tests of android.widget">
         <meta-data android:name="listener"
             android:value="com.android.cts.runner.CtsTestRunListener" />
diff --git a/tests/tests/widget/AndroidTest.xml b/tests/tests/widget/AndroidTest.xml
new file mode 100644
index 0000000..ed7742a
--- /dev/null
+++ b/tests/tests/widget/AndroidTest.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS Widget test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.WifiCheck" />
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsWidgetTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.widget.cts" />
+        <option name="runtime-hint" value="11m55s" />
+    </test>
+</configuration>
diff --git a/tests/tests/widget/res/drawable-xxhdpi/ic_delete.png b/tests/tests/widget/res/drawable-xxhdpi/ic_delete.png
new file mode 100644
index 0000000..6d7cb81
--- /dev/null
+++ b/tests/tests/widget/res/drawable-xxhdpi/ic_delete.png
Binary files differ
diff --git a/tests/tests/widget/res/drawable-xxhdpi/ic_edit.png b/tests/tests/widget/res/drawable-xxhdpi/ic_edit.png
new file mode 100644
index 0000000..4af4ae6
--- /dev/null
+++ b/tests/tests/widget/res/drawable-xxhdpi/ic_edit.png
Binary files differ
diff --git a/tests/tests/widget/res/drawable-xxhdpi/ic_highlight.png b/tests/tests/widget/res/drawable-xxhdpi/ic_highlight.png
new file mode 100644
index 0000000..3a5d6e3
--- /dev/null
+++ b/tests/tests/widget/res/drawable-xxhdpi/ic_highlight.png
Binary files differ
diff --git a/tests/tests/widget/res/drawable-xxhdpi/ic_ignore.png b/tests/tests/widget/res/drawable-xxhdpi/ic_ignore.png
new file mode 100644
index 0000000..ed36f70
--- /dev/null
+++ b/tests/tests/widget/res/drawable-xxhdpi/ic_ignore.png
Binary files differ
diff --git a/tests/tests/widget/res/drawable-xxhdpi/ic_print.png b/tests/tests/widget/res/drawable-xxhdpi/ic_print.png
new file mode 100644
index 0000000..f55abe0
--- /dev/null
+++ b/tests/tests/widget/res/drawable-xxhdpi/ic_print.png
Binary files differ
diff --git a/tests/tests/widget/res/drawable-xxhdpi/ic_search.png b/tests/tests/widget/res/drawable-xxhdpi/ic_search.png
new file mode 100644
index 0000000..3ae490e
--- /dev/null
+++ b/tests/tests/widget/res/drawable-xxhdpi/ic_search.png
Binary files differ
diff --git a/tests/tests/widget/res/drawable-xxhdpi/ic_share.png b/tests/tests/widget/res/drawable-xxhdpi/ic_share.png
new file mode 100644
index 0000000..032c786
--- /dev/null
+++ b/tests/tests/widget/res/drawable-xxhdpi/ic_share.png
Binary files differ
diff --git a/tests/tests/widget/res/drawable/blue_fill.xml b/tests/tests/widget/res/drawable/blue_fill.xml
new file mode 100644
index 0000000..5a24f08
--- /dev/null
+++ b/tests/tests/widget/res/drawable/blue_fill.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<shape
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+    <solid android:color="#0000FF" />
+</shape>
\ No newline at end of file
diff --git a/tests/tests/widget/res/drawable/magenta_fill.xml b/tests/tests/widget/res/drawable/magenta_fill.xml
new file mode 100644
index 0000000..cbb594f
--- /dev/null
+++ b/tests/tests/widget/res/drawable/magenta_fill.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<shape
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+    <solid android:color="#FF00FF" />
+</shape>
\ No newline at end of file
diff --git a/tests/tests/widget/res/drawable/red_fill.xml b/tests/tests/widget/res/drawable/red_fill.xml
new file mode 100644
index 0000000..e443240
--- /dev/null
+++ b/tests/tests/widget/res/drawable/red_fill.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<shape
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+    <solid android:color="#8F00" />
+</shape>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/drawable/inset_mutate_testimage.jpg b/tests/tests/widget/res/drawable/statelist_testimage.jpg
similarity index 100%
copy from tests/tests/graphics/res/drawable/inset_mutate_testimage.jpg
copy to tests/tests/widget/res/drawable/statelist_testimage.jpg
Binary files differ
diff --git a/tests/tests/widget/res/drawable/statelistdrawable.xml b/tests/tests/widget/res/drawable/statelistdrawable.xml
new file mode 100644
index 0000000..e0624ad
--- /dev/null
+++ b/tests/tests/widget/res/drawable/statelistdrawable.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+   <item android:state_selected="true" android:drawable="@drawable/blue_fill"/>
+   <item android:state_focused="true" android:drawable="@drawable/statelist_testimage"/>
+   <item android:state_enabled="false" android:drawable="@drawable/statelist_testimage"/>
+</selector>
+
diff --git a/tests/tests/widget/res/drawable/yellow_fill.xml b/tests/tests/widget/res/drawable/yellow_fill.xml
new file mode 100644
index 0000000..3bd8097
--- /dev/null
+++ b/tests/tests/widget/res/drawable/yellow_fill.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<shape
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+    <solid android:color="#FFFF00" />
+</shape>
\ No newline at end of file
diff --git a/tests/tests/widget/res/layout/calendarview_layout.xml b/tests/tests/widget/res/layout/calendarview_layout.xml
new file mode 100644
index 0000000..3bc5e47
--- /dev/null
+++ b/tests/tests/widget/res/layout/calendarview_layout.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2016 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+
+<ScrollView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:fillViewport="true">
+
+    <LinearLayout
+        android:id="@+id/container"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical">
+
+        <CalendarView
+            android:id="@+id/calendar_view_material"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:firstDayOfWeek="2"
+            android:dateTextAppearance="@style/TextAppearance.WithColor"
+            android:weekDayTextAppearance="@style/TextAppearance.WithColorGreen" />
+
+        <!-- CalendarView in Holo Light style for testing attributes and APIs that control
+             the deprecated visual aspects of this widget. -->
+        <CalendarView
+            style="@android:style/Widget.Holo.Light.CalendarView"
+            android:id="@+id/calendar_view_holoyolo"
+            android:layout_width="match_parent"
+            android:layout_height="320dip"
+            android:firstDayOfWeek="3"
+            android:shownWeekCount="5"
+            android:showWeekNumber="false"
+            android:selectedWeekBackgroundColor="@color/calendarview_week_background"
+            android:focusedMonthDateColor="@color/calendarview_focusedmonthdate"
+            android:unfocusedMonthDateColor="@color/calendarview_unfocusedmonthdate"
+            android:dateTextAppearance="@style/TextAppearance.WithColor"
+            android:weekDayTextAppearance="@style/TextAppearance.WithColorGreen"
+            android:selectedDateVerticalBar="@drawable/blue_fill" />
+
+    </LinearLayout>
+
+</ScrollView>
diff --git a/tests/tests/widget/res/layout/digitalclock_layout.xml b/tests/tests/widget/res/layout/digitalclock_layout.xml
index d405af2..618dbea 100644
--- a/tests/tests/widget/res/layout/digitalclock_layout.xml
+++ b/tests/tests/widget/res/layout/digitalclock_layout.xml
@@ -14,7 +14,7 @@
      limitations under the License.
 -->
 
-<com.android.cts.widget.alarmclock.DigitalClock android:id="@+id/digitalClock"
+<android.widget.cts.alarmclock.DigitalClock android:id="@+id/digitalClock"
      xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_width="wrap_content"
      android:layout_height="208dip"
@@ -45,4 +45,4 @@
              android:text="@string/pm"
              android:textSize="28sp"/>
      </LinearLayout>
-</com.android.cts.widget.alarmclock.DigitalClock>
+</android.widget.cts.alarmclock.DigitalClock>
diff --git a/tests/tests/widget/res/layout/imageview_layout.xml b/tests/tests/widget/res/layout/imageview_layout.xml
index e56a9c9..80512e2 100644
--- a/tests/tests/widget/res/layout/imageview_layout.xml
+++ b/tests/tests/widget/res/layout/imageview_layout.xml
@@ -17,10 +17,11 @@
  */
 -->
 
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:orientation="vertical"
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:layout_height="match_parent">
+    android:layout_height="match_parent"
+    android:orientation="vertical">
 
     <ImageView
         android:id="@+id/imageview"
@@ -34,5 +35,13 @@
         android:tint="@android:color/white"
         android:tintMode="src_over" />
 
+    <ImageView
+        android:id="@+id/image_tint_with_source"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:src="@drawable/icon_red"
+        android:tint="@android:color/white"
+        android:tintMode="src_over" />
+
 </LinearLayout>
 
diff --git a/tests/tests/widget/res/layout/linearlayout_layout.xml b/tests/tests/widget/res/layout/linearlayout_layout.xml
index c70937d..8881552 100644
--- a/tests/tests/widget/res/layout/linearlayout_layout.xml
+++ b/tests/tests/widget/res/layout/linearlayout_layout.xml
@@ -15,6 +15,7 @@
  * limitations under the License.
  -->
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                android:id="@+id/linearlayout_root"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:orientation="vertical">
diff --git a/tests/tests/widget/res/layout/list_popup_window.xml b/tests/tests/widget/res/layout/list_popup_window.xml
new file mode 100644
index 0000000..bcf5893
--- /dev/null
+++ b/tests/tests/widget/res/layout/list_popup_window.xml
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<RelativeLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/main_container"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <android.widget.cts.MockViewForListPopupWindow
+        android:id="@+id/anchor_upper_left"
+        android:layout_width="10dp"
+        android:layout_height="10dp"
+        android:layout_alignParentLeft="true"
+        android:layout_alignParentTop="true"
+        android:background="#f00" />
+
+    <View
+        android:id="@+id/anchor_upper"
+        android:layout_width="10dp"
+        android:layout_height="10dp"
+        android:layout_centerHorizontal="true"
+        android:layout_alignParentTop="true"
+        android:background="#f00" />
+
+    <View
+        android:id="@+id/anchor_upper_right"
+        android:layout_width="10dp"
+        android:layout_height="10dp"
+        android:layout_alignParentRight="true"
+        android:layout_alignParentTop="true"
+        android:background="#f00" />
+
+    <View
+        android:id="@+id/anchor_middle_left"
+        android:layout_width="10dp"
+        android:layout_height="10dp"
+        android:layout_alignParentLeft="true"
+        android:layout_centerVertical="true"
+        android:background="#0f0" />
+
+    <View
+        android:id="@+id/anchor_middle"
+        android:layout_width="10dp"
+        android:layout_height="10dp"
+        android:layout_centerHorizontal="true"
+        android:layout_centerVertical="true"
+        android:background="#0f0" />
+
+    <View
+        android:id="@+id/anchor_middle_right"
+        android:layout_width="10dp"
+        android:layout_height="10dp"
+        android:layout_alignParentRight="true"
+        android:layout_centerVertical="true"
+        android:background="#0f0" />
+
+    <View
+        android:id="@+id/anchor_lower_left"
+        android:layout_width="10dp"
+        android:layout_height="10dp"
+        android:layout_alignParentLeft="true"
+        android:layout_alignParentBottom="true"
+        android:background="#00f" />
+
+    <View
+        android:id="@+id/anchor_lower"
+        android:layout_width="10dp"
+        android:layout_height="10dp"
+        android:layout_centerHorizontal="true"
+        android:layout_alignParentBottom="true"
+        android:background="#00f" />
+
+    <View
+        android:id="@+id/anchor_lower_right"
+        android:layout_width="10dp"
+        android:layout_height="10dp"
+        android:layout_alignParentRight="true"
+        android:layout_alignParentBottom="true"
+        android:background="#00f" />
+
+</RelativeLayout>
diff --git a/tests/tests/widget/res/layout/popup_menu.xml b/tests/tests/widget/res/layout/popup_menu.xml
new file mode 100644
index 0000000..bcf5893
--- /dev/null
+++ b/tests/tests/widget/res/layout/popup_menu.xml
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<RelativeLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/main_container"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <android.widget.cts.MockViewForListPopupWindow
+        android:id="@+id/anchor_upper_left"
+        android:layout_width="10dp"
+        android:layout_height="10dp"
+        android:layout_alignParentLeft="true"
+        android:layout_alignParentTop="true"
+        android:background="#f00" />
+
+    <View
+        android:id="@+id/anchor_upper"
+        android:layout_width="10dp"
+        android:layout_height="10dp"
+        android:layout_centerHorizontal="true"
+        android:layout_alignParentTop="true"
+        android:background="#f00" />
+
+    <View
+        android:id="@+id/anchor_upper_right"
+        android:layout_width="10dp"
+        android:layout_height="10dp"
+        android:layout_alignParentRight="true"
+        android:layout_alignParentTop="true"
+        android:background="#f00" />
+
+    <View
+        android:id="@+id/anchor_middle_left"
+        android:layout_width="10dp"
+        android:layout_height="10dp"
+        android:layout_alignParentLeft="true"
+        android:layout_centerVertical="true"
+        android:background="#0f0" />
+
+    <View
+        android:id="@+id/anchor_middle"
+        android:layout_width="10dp"
+        android:layout_height="10dp"
+        android:layout_centerHorizontal="true"
+        android:layout_centerVertical="true"
+        android:background="#0f0" />
+
+    <View
+        android:id="@+id/anchor_middle_right"
+        android:layout_width="10dp"
+        android:layout_height="10dp"
+        android:layout_alignParentRight="true"
+        android:layout_centerVertical="true"
+        android:background="#0f0" />
+
+    <View
+        android:id="@+id/anchor_lower_left"
+        android:layout_width="10dp"
+        android:layout_height="10dp"
+        android:layout_alignParentLeft="true"
+        android:layout_alignParentBottom="true"
+        android:background="#00f" />
+
+    <View
+        android:id="@+id/anchor_lower"
+        android:layout_width="10dp"
+        android:layout_height="10dp"
+        android:layout_centerHorizontal="true"
+        android:layout_alignParentBottom="true"
+        android:background="#00f" />
+
+    <View
+        android:id="@+id/anchor_lower_right"
+        android:layout_width="10dp"
+        android:layout_height="10dp"
+        android:layout_alignParentRight="true"
+        android:layout_alignParentBottom="true"
+        android:background="#00f" />
+
+</RelativeLayout>
diff --git a/tests/tests/widget/res/layout/popup_window.xml b/tests/tests/widget/res/layout/popup_window.xml
new file mode 100644
index 0000000..9736675
--- /dev/null
+++ b/tests/tests/widget/res/layout/popup_window.xml
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<RelativeLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/main_container"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <View
+        android:id="@+id/anchor_upper_left"
+        android:layout_width="10dp"
+        android:layout_height="10dp"
+        android:layout_alignParentLeft="true"
+        android:layout_alignParentTop="true"
+        android:background="#f00" />
+
+    <View
+        android:id="@+id/anchor_upper"
+        android:layout_width="10dp"
+        android:layout_height="10dp"
+        android:layout_centerHorizontal="true"
+        android:layout_alignParentTop="true"
+        android:background="#f00" />
+
+    <View
+        android:id="@+id/anchor_upper_right"
+        android:layout_width="10dp"
+        android:layout_height="10dp"
+        android:layout_alignParentRight="true"
+        android:layout_alignParentTop="true"
+        android:background="#f00" />
+
+    <View
+        android:id="@+id/anchor_middle_left"
+        android:layout_width="10dp"
+        android:layout_height="10dp"
+        android:layout_alignParentLeft="true"
+        android:layout_centerVertical="true"
+        android:background="#0f0" />
+
+    <View
+        android:id="@+id/anchor_middle"
+        android:layout_width="10dp"
+        android:layout_height="10dp"
+        android:layout_centerHorizontal="true"
+        android:layout_centerVertical="true"
+        android:background="#0f0" />
+
+    <View
+        android:id="@+id/anchor_middle_right"
+        android:layout_width="10dp"
+        android:layout_height="10dp"
+        android:layout_alignParentRight="true"
+        android:layout_centerVertical="true"
+        android:background="#0f0" />
+
+    <View
+        android:id="@+id/anchor_lower_left"
+        android:layout_width="10dp"
+        android:layout_height="10dp"
+        android:layout_alignParentLeft="true"
+        android:layout_alignParentBottom="true"
+        android:background="#00f" />
+
+    <View
+        android:id="@+id/anchor_lower"
+        android:layout_width="10dp"
+        android:layout_height="10dp"
+        android:layout_centerHorizontal="true"
+        android:layout_alignParentBottom="true"
+        android:background="#00f" />
+
+    <View
+        android:id="@+id/anchor_lower_right"
+        android:layout_width="10dp"
+        android:layout_height="10dp"
+        android:layout_alignParentRight="true"
+        android:layout_alignParentBottom="true"
+        android:background="#00f" />
+
+</RelativeLayout>
diff --git a/tests/tests/widget/res/layout/popup_window_item.xml b/tests/tests/widget/res/layout/popup_window_item.xml
new file mode 100644
index 0000000..b53fd22
--- /dev/null
+++ b/tests/tests/widget/res/layout/popup_window_item.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<TextView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@android:id/text1"
+    android:layout_width="match_parent"
+    android:layout_height="@dimen/popup_row_height"
+    android:textAppearance="?android:attr/textAppearanceListItemSmall"
+    android:gravity="center_vertical"
+    android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd" />
diff --git a/tests/tests/widget/res/layout/popupwindow.xml b/tests/tests/widget/res/layout/popupwindow.xml
index f93f965..cf69831 100644
--- a/tests/tests/widget/res/layout/popupwindow.xml
+++ b/tests/tests/widget/res/layout/popupwindow.xml
@@ -14,36 +14,82 @@
      limitations under the License.
 -->
 
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<RelativeLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/main_container"
     android:layout_width="match_parent"
     android:layout_height="match_parent">
 
-    <View android:id="@+id/anchor_upper"
+    <View
+        android:id="@+id/anchor_upper_left"
         android:layout_width="10dp"
         android:layout_height="10dp"
+        android:layout_alignParentLeft="true"
         android:layout_alignParentTop="true"
-        android:layout_centerHorizontal="true"
         android:background="#f00" />
 
-    <View android:id="@+id/anchor_lower"
+    <View
+        android:id="@+id/anchor_upper"
         android:layout_width="10dp"
         android:layout_height="10dp"
-        android:layout_alignParentBottom="true"
         android:layout_centerHorizontal="true"
-        android:background="#0f0" />
+        android:layout_alignParentTop="true"
+        android:background="#f00" />
 
-    <View android:id="@+id/anchor_middle_left"
+    <View
+        android:id="@+id/anchor_upper_right"
+        android:layout_width="10dp"
+        android:layout_height="10dp"
+        android:layout_alignParentRight="true"
+        android:layout_alignParentTop="true"
+        android:background="#f00" />
+
+    <View
+        android:id="@+id/anchor_middle_left"
         android:layout_width="10dp"
         android:layout_height="10dp"
         android:layout_alignParentLeft="true"
         android:layout_centerVertical="true"
-        android:background="#00f" />
+        android:background="#0f0" />
 
-    <View android:id="@+id/anchor_middle_right"
+    <View
+        android:id="@+id/anchor_middle"
+        android:layout_width="10dp"
+        android:layout_height="10dp"
+        android:layout_centerHorizontal="true"
+        android:layout_centerVertical="true"
+        android:background="#0f0" />
+
+    <View
+        android:id="@+id/anchor_middle_right"
         android:layout_width="10dp"
         android:layout_height="10dp"
         android:layout_alignParentRight="true"
         android:layout_centerVertical="true"
-        android:background="#ff0" />
+        android:background="#0f0" />
+
+    <View
+        android:id="@+id/anchor_lower_left"
+        android:layout_width="10dp"
+        android:layout_height="10dp"
+        android:layout_alignParentLeft="true"
+        android:layout_alignParentBottom="true"
+        android:background="#00f" />
+
+    <View
+        android:id="@+id/anchor_lower"
+        android:layout_width="10dp"
+        android:layout_height="10dp"
+        android:layout_centerHorizontal="true"
+        android:layout_alignParentBottom="true"
+        android:background="#00f" />
+
+    <View
+        android:id="@+id/anchor_lower_right"
+        android:layout_width="10dp"
+        android:layout_height="10dp"
+        android:layout_alignParentRight="true"
+        android:layout_alignParentBottom="true"
+        android:background="#00f" />
 
 </RelativeLayout>
diff --git a/tests/tests/widget/res/layout/popupwindow_prompt.xml b/tests/tests/widget/res/layout/popupwindow_prompt.xml
new file mode 100644
index 0000000..c1260b6
--- /dev/null
+++ b/tests/tests/widget/res/layout/popupwindow_prompt.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<TextView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/popupwindow_prompt"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:padding="8dp"
+    android:textAppearance="?android:attr/textAppearanceMedium"
+    android:text="@string/prompt" />
diff --git a/tests/tests/widget/res/layout/seekbar_layout.xml b/tests/tests/widget/res/layout/seekbar_layout.xml
index 5c311fd..4b4a6b7 100644
--- a/tests/tests/widget/res/layout/seekbar_layout.xml
+++ b/tests/tests/widget/res/layout/seekbar_layout.xml
@@ -32,4 +32,11 @@
         android:layout_width="wrap_content"
         android:layout_height="wrap_content" />
 
+    <SeekBar
+        android:id="@+id/tick_mark_tint"
+        android:tickMarkTint="@android:color/white"
+        android:tickMarkTintMode="src_over"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content" />
+
 </LinearLayout>
diff --git a/tests/tests/widget/res/layout/switch_layout.xml b/tests/tests/widget/res/layout/switch_layout.xml
index a34845b..12e10d2 100644
--- a/tests/tests/widget/res/layout/switch_layout.xml
+++ b/tests/tests/widget/res/layout/switch_layout.xml
@@ -16,6 +16,7 @@
   -->
 
 <Switch xmlns:android="http://schemas.android.com/apk/res/android"
+        android:id="@+id/switch_view"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:thumbTint="@android:color/white"
diff --git a/tests/tests/widget/res/layout/tabhost_custom.xml b/tests/tests/widget/res/layout/tabhost_custom.xml
new file mode 100644
index 0000000..5308a18
--- /dev/null
+++ b/tests/tests/widget/res/layout/tabhost_custom.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<TabWidget
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@android:id/tabs"
+    android:layout_width="match_parent"
+    android:layout_height="68dip"
+    android:tabStripEnabled="false"
+    android:tabStripLeft="@drawable/icon_red"
+    android:tabStripRight="@drawable/icon_green" />
diff --git a/tests/tests/widget/res/layout/tabhost_layout.xml b/tests/tests/widget/res/layout/tabhost_layout.xml
index 1bae57a..de766f9 100644
--- a/tests/tests/widget/res/layout/tabhost_layout.xml
+++ b/tests/tests/widget/res/layout/tabhost_layout.xml
@@ -24,8 +24,7 @@
         android:layout_height="68dip"
         android:paddingLeft="1dip"
         android:paddingRight="1dip"
-        android:paddingTop="4dip"
-    />
+        android:paddingTop="4dip" />
 
     <FrameLayout android:id="@android:id/tabcontent"
         android:layout_width="match_parent"
diff --git a/tests/tests/widget/res/layout/toolbar_layout.xml b/tests/tests/widget/res/layout/toolbar_layout.xml
new file mode 100644
index 0000000..3a74188
--- /dev/null
+++ b/tests/tests/widget/res/layout/toolbar_layout.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical">
+
+    <Toolbar
+        android:id="@+id/toolbar_main"
+        android:layout_width="match_parent"
+        android:layout_height="?android:attr/actionBarSize"
+        android:titleMargin="5px"
+        android:titleMarginTop="10px"
+        android:titleMarginEnd="15px"
+        android:titleMarginBottom="20px"
+        android:popupTheme="@style/PopupWindow.NullTransitions" />
+
+    <Toolbar
+        android:id="@+id/toolbar2"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content" />
+
+</LinearLayout>
+
diff --git a/tests/tests/widget/res/menu/popup_menu.xml b/tests/tests/widget/res/menu/popup_menu.xml
new file mode 100644
index 0000000..f50efc5
--- /dev/null
+++ b/tests/tests/widget/res/menu/popup_menu.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 Google Inc.
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:id="@+id/action_highlight"
+          android:title="@string/popup_menu_highlight" />
+    <item android:id="@+id/action_edit"
+          android:title="@string/popup_menu_edit" />
+    <item android:id="@+id/action_delete"
+          android:title="@string/popup_menu_delete" />
+    <item android:id="@+id/action_ignore"
+          android:title="@string/popup_menu_ignore" />
+    <item android:id="@+id/action_share"
+          android:title="@string/popup_menu_share">
+        <menu>
+            <item android:id="@+id/action_share_email"
+                  android:title="@string/popup_menu_share_email" />
+            <item android:id="@+id/action_share_circles"
+                  android:title="@string/popup_menu_share_circles" />
+        </menu>
+    </item>
+    <item android:id="@+id/action_print"
+          android:title="@string/popup_menu_print" />
+</menu>
diff --git a/tests/tests/widget/res/menu/popup_menu_single.xml b/tests/tests/widget/res/menu/popup_menu_single.xml
new file mode 100644
index 0000000..3984b03
--- /dev/null
+++ b/tests/tests/widget/res/menu/popup_menu_single.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 Google Inc.
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:id="@+id/action_highlight"
+          android:title="@string/popup_menu_highlight" />
+</menu>
diff --git a/tests/tests/widget/res/menu/toolbar_menu.xml b/tests/tests/widget/res/menu/toolbar_menu.xml
new file mode 100644
index 0000000..3631ff6
--- /dev/null
+++ b/tests/tests/widget/res/menu/toolbar_menu.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 Google Inc.
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:id="@+id/action_highlight"
+          android:title="@string/popup_menu_highlight"
+          android:icon="@drawable/ic_highlight"
+          android:showAsAction="always" />
+    <item android:id="@+id/action_edit"
+          android:title="@string/popup_menu_edit"
+          android:icon="@drawable/ic_edit"
+          android:showAsAction="always" />
+    <item android:id="@+id/action_delete"
+          android:title="@string/popup_menu_delete"
+          android:icon="@drawable/ic_delete"
+          android:showAsAction="never" />
+    <item android:id="@+id/action_ignore"
+          android:title="@string/popup_menu_ignore"
+          android:icon="@drawable/ic_ignore"
+          android:showAsAction="never" />
+    <item android:id="@+id/action_share"
+          android:title="@string/popup_menu_share"
+          android:icon="@drawable/ic_share"
+          android:showAsAction="never">
+        <menu>
+            <item android:id="@+id/action_share_email"
+                  android:title="@string/popup_menu_share_email" />
+            <item android:id="@+id/action_share_circles"
+                  android:title="@string/popup_menu_share_circles" />
+        </menu>
+    </item>
+    <item android:id="@+id/action_print"
+          android:title="@string/popup_menu_print"
+          android:icon="@drawable/ic_print"
+          android:showAsAction="never" />
+</menu>
diff --git a/tests/tests/widget/res/menu/toolbar_menu_search.xml b/tests/tests/widget/res/menu/toolbar_menu_search.xml
new file mode 100644
index 0000000..2321554
--- /dev/null
+++ b/tests/tests/widget/res/menu/toolbar_menu_search.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 Google Inc.
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:id="@+id/action_search"
+          android:title="@string/popup_menu_search"
+          android:icon="@drawable/ic_search"
+          android:showAsAction="always|collapseActionView"
+          android:actionViewClass="android.widget.SearchView" />
+</menu>
diff --git a/tests/tests/widget/res/transition/custom_transition.xml b/tests/tests/widget/res/transition/custom_transition.xml
new file mode 100644
index 0000000..cb8ea5c
--- /dev/null
+++ b/tests/tests/widget/res/transition/custom_transition.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<transition xmlns:android="http://schemas.android.com/apk/res/android"
+            class="android.widget.cts.PopupWindowTest$CustomTransition"
+            android:duration="250" />
diff --git a/tests/tests/widget/res/values/colors.xml b/tests/tests/widget/res/values/colors.xml
index f3cc325..f104a6d2 100644
--- a/tests/tests/widget/res/values/colors.xml
+++ b/tests/tests/widget/res/values/colors.xml
@@ -23,4 +23,14 @@
     <color name="testcolor1">#ff00ff00</color>
     <color name="testcolor2">#ffff0000</color>
     <color name="failColor">#ff0000ff</color>
+
+    <color name="calendarview_week_background">#40FF0000</color>
+    <color name="calendarview_focusedmonthdate">#9080A0FF</color>
+    <color name="calendarview_unfocusedmonthdate">#9070F080</color>
+
+    <color name="calendarview_week_background_new">#60808000</color>
+    <color name="calendarview_focusedmonthdate_new">#A0B020FF</color>
+    <color name="calendarview_unfocusedmonthdate_new">#4070F0F0</color>
+    <color name="calendarview_week_number_new">#9090FF</color>
+    <color name="calendarview_week_separatorline_new">#AFAF00</color>
 </resources>
diff --git a/tests/tests/widget/res/values/dimens.xml b/tests/tests/widget/res/values/dimens.xml
new file mode 100644
index 0000000..3690039
--- /dev/null
+++ b/tests/tests/widget/res/values/dimens.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<resources>
+    <dimen name="popup_row_height">48dp</dimen>
+</resources>
\ No newline at end of file
diff --git a/tests/tests/widget/res/values/strings.xml b/tests/tests/widget/res/values/strings.xml
index c167278..63ceffa 100644
--- a/tests/tests/widget/res/values/strings.xml
+++ b/tests/tests/widget/res/values/strings.xml
@@ -154,6 +154,7 @@
    <string name="search_label">Android CTS</string>
    <string name="tag1">tag 1</string>
    <string name="tag2">tag 2</string>
+   <string name="prompt">prompt</string>
 
    <string name="button">Button</string>
    <string name="holo_test">Holo Test</string>
@@ -176,4 +177,20 @@
 text, I would love to see the kind of devices you guys now use! Guys, maybe some devices need longer string!
 I think so, so how about double this string, like copy and paste! </string>
     <string name="rectangle200">"M 0,0 l 200,0 l 0, 200 l -200, 0 z"</string>
+
+    <string name="popup_show">Show popup</string>
+    <string name="popup_menu_highlight">Highlight</string>
+    <string name="popup_menu_edit">Edit</string>
+    <string name="popup_menu_delete">Delete</string>
+    <string name="popup_menu_ignore">Ignore</string>
+    <string name="popup_menu_share">Share</string>
+    <string name="popup_menu_share_email">Via email</string>
+    <string name="popup_menu_share_circles">To my circles</string>
+    <string name="popup_menu_print">Print</string>
+    <string name="popup_menu_search">Search</string>
+
+    <string name="toolbar_title">Toolbar title</string>
+    <string name="toolbar_subtitle">Toolbar subtitle</string>
+    <string name="toolbar_navigation">Toolbar navigation</string>
+    <string name="toolbar_logo">Toolbar logo</string>
 </resources>
diff --git a/tests/tests/widget/res/values/styles.xml b/tests/tests/widget/res/values/styles.xml
index 81925cc..345b450 100644
--- a/tests/tests/widget/res/values/styles.xml
+++ b/tests/tests/widget/res/values/styles.xml
@@ -35,6 +35,18 @@
         <item name="type16">Typed Value!</item>
     </style>
 
+    <style name="PopupWindow" parent="@android:style/Widget.Material.ListPopupWindow" />
+
+    <style name="PopupWindow.NullTransitions">
+        <item name="android:popupEnterTransition">@null</item>
+        <item name="android:popupExitTransition">@null</item>
+    </style>
+
+    <style name="PopupWindow.CustomTransitions">
+        <item name="android:popupEnterTransition">@transition/custom_transition</item>
+        <item name="android:popupExitTransition">@transition/custom_transition</item>
+    </style>
+
     <style name="TextViewWithoutColorAndAppearance">
         <item name="android:textSize">18sp</item>
     </style>
@@ -59,6 +71,18 @@
         <item name="android:textColor">#ffff0000</item>
     </style>
 
+    <style name="TextAppearance.WithColorGreen">
+        <item name="android:textColor">#ff00ff00</item>
+    </style>
+
+    <style name="TextAppearance.WithColorBlue">
+        <item name="android:textColor">#ff0000ff</item>
+    </style>
+
+    <style name="TextAppearance.WithColorMagenta">
+        <item name="android:textColor">#ffff00ff</item>
+    </style>
+
     <style name="TextAppearance.All">
         <item name="android:textColor">@drawable/black</item>
         <item name="android:textSize">20px</item>
@@ -169,4 +193,13 @@
         <item name="android:windowSwipeToDismiss">false</item>
     </style>
 
+    <style name="PopupEmptyStyle" />
+
+    <style name="TabWidgetCustomStyle" parent="android:Widget.TabWidget">
+        <item name="android:tabStripEnabled">false</item>
+        <item name="android:tabStripLeft">@drawable/icon_green</item>
+        <item name="android:tabStripRight">@drawable/icon_red</item>
+    </style>
+
+    <style name="ToolbarPopupTheme_Test" parent="@android:style/ThemeOverlay.Material.Light" />
 </resources>
diff --git a/tests/tests/widget/src/android/widget/cts/AbsListViewTest.java b/tests/tests/widget/src/android/widget/cts/AbsListViewTest.java
index 2b38827..cf8012e 100644
--- a/tests/tests/widget/src/android/widget/cts/AbsListViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/AbsListViewTest.java
@@ -16,7 +16,8 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.widget.cts.R;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
@@ -73,7 +74,7 @@
     private static final float DELTA = 0.001f;
 
     public AbsListViewTest() {
-        super("com.android.cts.widget", ListViewCtsActivity.class);
+        super("android.widget.cts", ListViewCtsActivity.class);
     }
 
 
@@ -648,6 +649,98 @@
         assertFalse(listView.isInFilterMode());
     }
 
+    @MediumTest
+    public void testSetItemChecked_multipleModeSameValue()
+            throws Throwable {
+        // Calling setItemChecked with the same value in multiple choice mode should not cause
+        // requestLayout
+        mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mListView.setItemChecked(0, false);
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+        assertFalse(mListView.isLayoutRequested());
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mListView.setItemChecked(0, false);
+            }
+        });
+        assertFalse(mListView.isLayoutRequested());
+    }
+
+    @MediumTest
+    public void testSetItemChecked_singleModeSameValue()
+            throws Throwable {
+        // Calling setItemChecked with the same value in single choice mode should not cause
+        // requestLayout
+        mListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mListView.setItemChecked(0, false);
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+        assertFalse(mListView.isLayoutRequested());
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mListView.setItemChecked(0, false);
+            }
+        });
+        assertFalse(mListView.isLayoutRequested());
+    }
+
+    @MediumTest
+    public void testSetItemChecked_multipleModeDifferentValue()
+            throws Throwable {
+        // Calling setItemChecked with a different value in multiple choice mode should cause
+        // requestLayout
+        mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mListView.setItemChecked(0, false);
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+        assertFalse(mListView.isLayoutRequested());
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mListView.setItemChecked(0, true);
+            }
+        });
+        assertTrue(mListView.isLayoutRequested());
+    }
+
+    @MediumTest
+    public void testSetItemChecked_singleModeDifferentValue()
+            throws Throwable {
+        // Calling setItemChecked with a different value in single choice mode should cause
+        // requestLayout
+        mListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mListView.setItemChecked(0, false);
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+        assertFalse(mListView.isLayoutRequested());
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mListView.setItemChecked(0, true);
+            }
+        });
+        assertTrue(mListView.isLayoutRequested());
+    }
+
     public void testLayoutChildren() {
         /**
          * the subclass ListView and GridView override this method, so we can not test
diff --git a/tests/tests/widget/src/android/widget/cts/AbsListView_LayoutParamsTest.java b/tests/tests/widget/src/android/widget/cts/AbsListView_LayoutParamsTest.java
index 305a9e2..7e88a19 100644
--- a/tests/tests/widget/src/android/widget/cts/AbsListView_LayoutParamsTest.java
+++ b/tests/tests/widget/src/android/widget/cts/AbsListView_LayoutParamsTest.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 
 import org.xmlpull.v1.XmlPullParser;
diff --git a/tests/tests/widget/src/android/widget/cts/AbsSeekBarTest.java b/tests/tests/widget/src/android/widget/cts/AbsSeekBarTest.java
index dfad3bbb..93032f6 100644
--- a/tests/tests/widget/src/android/widget/cts/AbsSeekBarTest.java
+++ b/tests/tests/widget/src/android/widget/cts/AbsSeekBarTest.java
@@ -16,22 +16,19 @@
 
 package android.widget.cts;
 
-import android.content.res.ColorStateList;
-import android.graphics.Color;
-import android.graphics.PorterDuff;
-import android.test.UiThreadTest;
-
-import com.android.cts.widget.R;
-
+import android.widget.cts.R;
 
 import android.app.Activity;
 import android.content.Context;
-import android.content.res.Resources;
+import android.content.res.ColorStateList;
 import android.cts.util.PollingCheck;
 import android.graphics.Canvas;
+import android.graphics.Color;
 import android.graphics.ColorFilter;
+import android.graphics.PorterDuff;
 import android.graphics.drawable.Drawable;
 import android.test.ActivityInstrumentationTestCase2;
+import android.test.UiThreadTest;
 import android.util.AttributeSet;
 import android.view.KeyEvent;
 import android.widget.AbsSeekBar;
@@ -42,17 +39,16 @@
  */
 public class AbsSeekBarTest extends ActivityInstrumentationTestCase2<ProgressBarCtsActivity> {
     public AbsSeekBarTest() {
-        super("com.android.cts.widget", ProgressBarCtsActivity.class);
+        super("android.widget.cts", ProgressBarCtsActivity.class);
     }
 
     private Activity mActivity;
-    private Resources mResources;
 
     @Override
     protected void setUp() throws Exception {
         super.setUp();
+
         mActivity = getActivity();
-        mResources = mActivity.getResources();
     }
 
     public void testConstructor() {
@@ -81,17 +77,38 @@
 
     public void testSetThumb() {
         MyAbsSeekBar myAbsSeekBar = new MyAbsSeekBar(mActivity);
-        Drawable drawable1 = mResources.getDrawable(R.drawable.scenery);
-        Drawable drawable2 = mResources.getDrawable(R.drawable.pass);
+        Drawable drawable1 = mActivity.getDrawable(R.drawable.scenery);
+        Drawable drawable2 = mActivity.getDrawable(R.drawable.pass);
 
         assertFalse(myAbsSeekBar.verifyDrawable(drawable1));
         assertFalse(myAbsSeekBar.verifyDrawable(drawable2));
 
         myAbsSeekBar.setThumb(drawable1);
+        assertSame(drawable1, myAbsSeekBar.getThumb());
         assertTrue(myAbsSeekBar.verifyDrawable(drawable1));
         assertFalse(myAbsSeekBar.verifyDrawable(drawable2));
 
         myAbsSeekBar.setThumb(drawable2);
+        assertSame(drawable2, myAbsSeekBar.getThumb());
+        assertFalse(myAbsSeekBar.verifyDrawable(drawable1));
+        assertTrue(myAbsSeekBar.verifyDrawable(drawable2));
+    }
+
+    public void testSetTickMark() {
+        MyAbsSeekBar myAbsSeekBar = new MyAbsSeekBar(mActivity);
+        Drawable drawable1 = mActivity.getDrawable(R.drawable.black);
+        Drawable drawable2 = mActivity.getDrawable(R.drawable.black);
+
+        assertFalse(myAbsSeekBar.verifyDrawable(drawable1));
+        assertFalse(myAbsSeekBar.verifyDrawable(drawable2));
+
+        myAbsSeekBar.setTickMark(drawable1);
+        assertSame(drawable1, myAbsSeekBar.getTickMark());
+        assertTrue(myAbsSeekBar.verifyDrawable(drawable1));
+        assertFalse(myAbsSeekBar.verifyDrawable(drawable2));
+
+        myAbsSeekBar.setTickMark(drawable2);
+        assertSame(drawable2, myAbsSeekBar.getTickMark());
         assertFalse(myAbsSeekBar.verifyDrawable(drawable1));
         assertTrue(myAbsSeekBar.verifyDrawable(drawable2));
     }
@@ -112,30 +129,27 @@
 
     public void testVerifyDrawable() {
         MyAbsSeekBar myAbsSeekBar = new MyAbsSeekBar(mActivity);
-        Drawable drawable1 = mResources.getDrawable(R.drawable.scenery);
-        Drawable drawable2 = mResources.getDrawable(R.drawable.pass);
-        Drawable drawable3 = mResources.getDrawable(R.drawable.blue);
-        Drawable drawable4 = mResources.getDrawable(R.drawable.black);
+        Drawable drawable1 = mActivity.getDrawable(R.drawable.scenery);
+        Drawable drawable2 = mActivity.getDrawable(R.drawable.pass);
+        Drawable drawable3 = mActivity.getDrawable(R.drawable.blue);
+        Drawable drawable4 = mActivity.getDrawable(R.drawable.black);
 
         assertFalse(myAbsSeekBar.verifyDrawable(drawable1));
         assertFalse(myAbsSeekBar.verifyDrawable(drawable2));
         assertFalse(myAbsSeekBar.verifyDrawable(drawable3));
         assertFalse(myAbsSeekBar.verifyDrawable(drawable4));
-        assertTrue(myAbsSeekBar.verifyDrawable(null));
 
         myAbsSeekBar.setThumb(drawable1);
         assertTrue(myAbsSeekBar.verifyDrawable(drawable1));
         assertFalse(myAbsSeekBar.verifyDrawable(drawable2));
         assertFalse(myAbsSeekBar.verifyDrawable(drawable3));
         assertFalse(myAbsSeekBar.verifyDrawable(drawable4));
-        assertTrue(myAbsSeekBar.verifyDrawable(null));
 
         myAbsSeekBar.setThumb(drawable2);
         assertFalse(myAbsSeekBar.verifyDrawable(drawable1));
         assertTrue(myAbsSeekBar.verifyDrawable(drawable2));
         assertFalse(myAbsSeekBar.verifyDrawable(drawable3));
         assertFalse(myAbsSeekBar.verifyDrawable(drawable4));
-        assertTrue(myAbsSeekBar.verifyDrawable(null));
 
         myAbsSeekBar.setBackgroundDrawable(drawable2);
         myAbsSeekBar.setProgressDrawable(drawable3);
@@ -144,7 +158,6 @@
         assertTrue(myAbsSeekBar.verifyDrawable(drawable2));
         assertTrue(myAbsSeekBar.verifyDrawable(drawable3));
         assertTrue(myAbsSeekBar.verifyDrawable(drawable4));
-        assertFalse(myAbsSeekBar.verifyDrawable(null));
     }
 
     public void testAccessKeyProgressIncrement() throws Throwable {
@@ -239,10 +252,32 @@
                 thumb.hasCalledSetTint());
     }
 
-    public void testFoo() {
-        // Do not test these APIs. They are callbacks which:
-        // 1. The callback machanism has been tested in super class
-        // 2. The functionality is implmentation details, no need to test
+    @UiThreadTest
+    public void testTickMarkTint() {
+        mActivity.setContentView(R.layout.seekbar_layout);
+
+        SeekBar inflatedView = (SeekBar) mActivity.findViewById(R.id.tick_mark_tint);
+
+        assertEquals("TickMark tint inflated correctly",
+                Color.WHITE, inflatedView.getTickMarkTintList().getDefaultColor());
+        assertEquals("TickMark tint mode inflated correctly",
+                PorterDuff.Mode.SRC_OVER, inflatedView.getTickMarkTintMode());
+
+        MockDrawable tickMark = new MockDrawable();
+        SeekBar view = new SeekBar(mActivity);
+
+        view.setTickMark(tickMark);
+        assertFalse("No tickMark tint applied by default", tickMark.hasCalledSetTint());
+
+        view.setTickMarkTintList(ColorStateList.valueOf(Color.WHITE));
+        assertTrue("TickMark tint applied when setTickMarkTintList() called after setTickMark()",
+                tickMark.hasCalledSetTint());
+
+        tickMark.reset();
+        view.setTickMark(null);
+        view.setTickMark(tickMark);
+        assertTrue("TickMark tint applied when setTickMarkTintList() called before setTickMark()",
+                tickMark.hasCalledSetTint());
     }
 
     private static class MyAbsSeekBar extends AbsSeekBar {
@@ -275,13 +310,7 @@
         private boolean mCalledSetTint = false;
 
         @Override
-        public void draw(Canvas canvas) {
-            mCalledDraw = true;
-        }
-
-        public boolean hasCalledDraw() {
-            return mCalledDraw;
-        }
+        public void draw(Canvas canvas) { }
 
         public void reset() {
             mCalledDraw = false;
diff --git a/tests/tests/widget/src/android/widget/cts/AbsSpinnerTest.java b/tests/tests/widget/src/android/widget/cts/AbsSpinnerTest.java
index 9669c7c..e07e8b1 100644
--- a/tests/tests/widget/src/android/widget/cts/AbsSpinnerTest.java
+++ b/tests/tests/widget/src/android/widget/cts/AbsSpinnerTest.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 
 import org.xmlpull.v1.XmlPullParser;
@@ -43,7 +43,7 @@
     private Context mContext;
 
     public AbsSpinnerTest() {
-        super("com.android.cts.widget", RelativeLayoutCtsActivity.class);
+        super("android.widget.cts", RelativeLayoutCtsActivity.class);
     }
 
     @Override
@@ -78,7 +78,7 @@
     public void testSetSelectionIntBoolean() {
         AbsSpinner absSpinner = (AbsSpinner) getActivity().findViewById(R.id.spinner1);
         ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(mContext,
-                com.android.cts.widget.R.array.string, android.R.layout.simple_spinner_item);
+                android.widget.cts.R.array.string, android.R.layout.simple_spinner_item);
         adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
         absSpinner.setAdapter(adapter);
         assertEquals(0, absSpinner.getSelectedItemPosition());
@@ -101,7 +101,7 @@
     public void testSetSelectionInt() {
         AbsSpinner absSpinner = (AbsSpinner) getActivity().findViewById(R.id.spinner1);
         ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(mContext,
-                com.android.cts.widget.R.array.string, android.R.layout.simple_spinner_item);
+                android.widget.cts.R.array.string, android.R.layout.simple_spinner_item);
         adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
         absSpinner.setAdapter(adapter);
         assertEquals(0, absSpinner.getSelectedItemPosition());
@@ -123,7 +123,7 @@
     public void testAccessAdapter() {
         AbsSpinner absSpinner = (AbsSpinner) getActivity().findViewById(R.id.spinner1);
         ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(mContext,
-                com.android.cts.widget.R.array.string, android.R.layout.simple_spinner_item);
+                android.widget.cts.R.array.string, android.R.layout.simple_spinner_item);
         adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
 
         absSpinner.setAdapter(adapter);
@@ -159,7 +159,7 @@
         AbsSpinner absSpinner = (AbsSpinner) getActivity().findViewById(R.id.spinner1);
 
         ArrayAdapter<CharSequence> adapter1 = ArrayAdapter.createFromResource(mContext,
-                com.android.cts.widget.R.array.string, android.R.layout.simple_spinner_item);
+                android.widget.cts.R.array.string, android.R.layout.simple_spinner_item);
 
         absSpinner.setAdapter(adapter1);
         assertEquals(adapter1.getCount(), absSpinner.getCount());
@@ -236,7 +236,7 @@
     public void testOnSaveAndRestoreInstanceState() {
         AbsSpinner absSpinner = (AbsSpinner) getActivity().findViewById(R.id.spinner1);
         ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(mContext,
-                com.android.cts.widget.R.array.string, android.R.layout.simple_spinner_item);
+                android.widget.cts.R.array.string, android.R.layout.simple_spinner_item);
         adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
         absSpinner.setAdapter(adapter);
         assertEquals(0, absSpinner.getSelectedItemPosition());
diff --git a/tests/tests/widget/src/android/widget/cts/AbsoluteLayoutTest.java b/tests/tests/widget/src/android/widget/cts/AbsoluteLayoutTest.java
index bac2479..a838f65 100644
--- a/tests/tests/widget/src/android/widget/cts/AbsoluteLayoutTest.java
+++ b/tests/tests/widget/src/android/widget/cts/AbsoluteLayoutTest.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 
 import org.xmlpull.v1.XmlPullParser;
@@ -46,7 +46,7 @@
     private LayoutParams mAbsoluteLayoutParams;
 
     public AbsoluteLayoutTest() {
-        super("com.android.cts.widget", CtsActivity.class);
+        super("android.widget.cts", CtsActivity.class);
     }
 
     @Override
diff --git a/tests/tests/widget/src/android/widget/cts/AbsoluteLayout_LayoutParamsTest.java b/tests/tests/widget/src/android/widget/cts/AbsoluteLayout_LayoutParamsTest.java
index ebc4e74..2723581 100644
--- a/tests/tests/widget/src/android/widget/cts/AbsoluteLayout_LayoutParamsTest.java
+++ b/tests/tests/widget/src/android/widget/cts/AbsoluteLayout_LayoutParamsTest.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 
 import org.xmlpull.v1.XmlPullParser;
diff --git a/tests/tests/widget/src/android/widget/cts/AdapterViewCtsActivity.java b/tests/tests/widget/src/android/widget/cts/AdapterViewCtsActivity.java
index 956ff9a..a85e365 100644
--- a/tests/tests/widget/src/android/widget/cts/AdapterViewCtsActivity.java
+++ b/tests/tests/widget/src/android/widget/cts/AdapterViewCtsActivity.java
@@ -25,7 +25,7 @@
 import android.widget.ArrayAdapter;
 import android.widget.ListView;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 /**
  * A minimal application for AdapterView test.
diff --git a/tests/tests/widget/src/android/widget/cts/AdapterViewTest.java b/tests/tests/widget/src/android/widget/cts/AdapterViewTest.java
index ccbdd56..1b9137f 100644
--- a/tests/tests/widget/src/android/widget/cts/AdapterViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/AdapterViewTest.java
@@ -39,7 +39,7 @@
 import android.widget.AdapterView.OnItemSelectedListener;
 import android.provider.Settings;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 
 public class AdapterViewTest extends ActivityInstrumentationTestCase2<AdapterViewCtsActivity> {
@@ -55,7 +55,7 @@
     private AdapterView<ListAdapter> mAdapterView;
 
     public AdapterViewTest() {
-        super("com.android.cts.widget", AdapterViewCtsActivity.class);
+        super("android.widget.cts", AdapterViewCtsActivity.class);
     }
 
     @Override
diff --git a/tests/tests/widget/src/android/widget/cts/AdapterView_AdapterContextMenuInfoTest.java b/tests/tests/widget/src/android/widget/cts/AdapterView_AdapterContextMenuInfoTest.java
index fde6095..17c7a1e 100644
--- a/tests/tests/widget/src/android/widget/cts/AdapterView_AdapterContextMenuInfoTest.java
+++ b/tests/tests/widget/src/android/widget/cts/AdapterView_AdapterContextMenuInfoTest.java
@@ -16,7 +16,6 @@
 
 package android.widget.cts;
 
-
 import android.test.AndroidTestCase;
 import android.view.View;
 import android.widget.AdapterView;
diff --git a/tests/tests/widget/src/android/widget/cts/AnalogClockTest.java b/tests/tests/widget/src/android/widget/cts/AnalogClockTest.java
index ef1a45d..fae6516 100644
--- a/tests/tests/widget/src/android/widget/cts/AnalogClockTest.java
+++ b/tests/tests/widget/src/android/widget/cts/AnalogClockTest.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 
 import org.xmlpull.v1.XmlPullParser;
@@ -33,7 +33,7 @@
     private Activity mActivity;
 
     public AnalogClockTest() {
-        super("com.android.cts.widget", FrameLayoutCtsActivity.class);
+        super("android.widget.cts", FrameLayoutCtsActivity.class);
     }
 
     @Override
diff --git a/tests/tests/widget/src/android/widget/cts/ArrayAdapterTest.java b/tests/tests/widget/src/android/widget/cts/ArrayAdapterTest.java
index fdca64c..03677f2 100644
--- a/tests/tests/widget/src/android/widget/cts/ArrayAdapterTest.java
+++ b/tests/tests/widget/src/android/widget/cts/ArrayAdapterTest.java
@@ -29,7 +29,7 @@
 import android.widget.Filter;
 import android.widget.TextView;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 
 public class ArrayAdapterTest extends InstrumentationTestCase {
diff --git a/tests/tests/widget/src/android/widget/cts/AutoCompleteCtsActivity.java b/tests/tests/widget/src/android/widget/cts/AutoCompleteCtsActivity.java
index 3d68f3e..1a12d66 100644
--- a/tests/tests/widget/src/android/widget/cts/AutoCompleteCtsActivity.java
+++ b/tests/tests/widget/src/android/widget/cts/AutoCompleteCtsActivity.java
@@ -19,7 +19,7 @@
 import android.app.Activity;
 import android.os.Bundle;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 /**
  * A minimal application for AutoCompleteTextView test.
diff --git a/tests/tests/widget/src/android/widget/cts/AutoCompleteTextViewTest.java b/tests/tests/widget/src/android/widget/cts/AutoCompleteTextViewTest.java
index c08abbc..eb22d6b 100644
--- a/tests/tests/widget/src/android/widget/cts/AutoCompleteTextViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/AutoCompleteTextViewTest.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 
 import org.xmlpull.v1.XmlPullParser;
@@ -53,7 +53,7 @@
      * Instantiates a new text view test.
      */
     public AutoCompleteTextViewTest() {
-        super("com.android.cts.widget", AutoCompleteCtsActivity.class);
+        super("android.widget.cts", AutoCompleteCtsActivity.class);
     }
 
     /** The m activity. */
diff --git a/tests/tests/widget/src/android/widget/cts/BaseAdapterTest.java b/tests/tests/widget/src/android/widget/cts/BaseAdapterTest.java
index 0369259..7659c1e 100644
--- a/tests/tests/widget/src/android/widget/cts/BaseAdapterTest.java
+++ b/tests/tests/widget/src/android/widget/cts/BaseAdapterTest.java
@@ -16,7 +16,6 @@
 
 package android.widget.cts;
 
-
 import android.database.DataSetObserver;
 import android.test.AndroidTestCase;
 import android.view.View;
diff --git a/tests/tests/widget/src/android/widget/cts/ButtonTest.java b/tests/tests/widget/src/android/widget/cts/ButtonTest.java
index 47d7108..9da2ecf 100644
--- a/tests/tests/widget/src/android/widget/cts/ButtonTest.java
+++ b/tests/tests/widget/src/android/widget/cts/ButtonTest.java
@@ -24,7 +24,7 @@
 import android.util.Xml;
 import android.widget.Button;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 
 public class ButtonTest extends AndroidTestCase {
diff --git a/tests/tests/widget/src/android/widget/cts/CalendarViewCtsActivity.java b/tests/tests/widget/src/android/widget/cts/CalendarViewCtsActivity.java
new file mode 100644
index 0000000..b0a15bf
--- /dev/null
+++ b/tests/tests/widget/src/android/widget/cts/CalendarViewCtsActivity.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.widget.cts;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.CalendarView;
+import android.widget.Toolbar;
+
+/**
+ * A minimal application for {@link CalendarView} test.
+ */
+public class CalendarViewCtsActivity extends Activity {
+    /**
+     * Called with the activity is first created.
+     */
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.calendarview_layout);
+    }
+}
+
diff --git a/tests/tests/widget/src/android/widget/cts/CalendarViewTest.java b/tests/tests/widget/src/android/widget/cts/CalendarViewTest.java
new file mode 100644
index 0000000..31ad341
--- /dev/null
+++ b/tests/tests/widget/src/android/widget/cts/CalendarViewTest.java
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.widget.cts;
+
+import android.annotation.ColorInt;
+import android.app.Instrumentation;
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.widget.CalendarView;
+import android.widget.cts.util.TestUtils;
+
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+
+@MediumTest
+public class CalendarViewTest extends ActivityInstrumentationTestCase2<CalendarViewCtsActivity> {
+    private CalendarViewCtsActivity mActivity;
+    private CalendarView mCalendarViewMaterial;
+    private CalendarView mCalendarViewHolo;
+
+    public CalendarViewTest() {
+        super("android.widget.cts", CalendarViewCtsActivity.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mActivity = getActivity();
+        mCalendarViewMaterial = (CalendarView) mActivity.findViewById(R.id.calendar_view_material);
+        mCalendarViewHolo = (CalendarView) mActivity.findViewById(R.id.calendar_view_holoyolo);
+
+        // Initialize both calendar views to the current date
+        final long currentDate = new GregorianCalendar().getTime().getTime();
+        getInstrumentation().runOnMainSync(() -> {
+            mCalendarViewMaterial.setDate(currentDate);
+            mCalendarViewHolo.setDate(currentDate);
+        });
+    }
+
+    public void testConstructor() {
+        new CalendarView(mActivity);
+
+        new CalendarView(mActivity, null);
+
+        new CalendarView(mActivity, null, android.R.attr.calendarViewStyle);
+
+        new CalendarView(mActivity, null, 0, android.R.style.Widget_Material_Light_CalendarView);
+    }
+
+    public void testAccessDate() {
+        final Instrumentation instrumentation = getInstrumentation();
+
+        // Go back one year
+        final Calendar newCalendar = new GregorianCalendar();
+        newCalendar.set(Calendar.YEAR, newCalendar.get(Calendar.YEAR) - 1);
+        final long yearAgoDate = newCalendar.getTime().getTime();
+
+        instrumentation.runOnMainSync(
+                () -> mCalendarViewMaterial.setDate(yearAgoDate));
+        assertEquals(yearAgoDate, mCalendarViewMaterial.getDate());
+
+        // Go forward two years (one year from current date in aggregate)
+        newCalendar.set(Calendar.YEAR, newCalendar.get(Calendar.YEAR) + 2);
+        final long yearHenceDate = newCalendar.getTime().getTime();
+
+        instrumentation.runOnMainSync(
+                () -> mCalendarViewMaterial.setDate(yearHenceDate, true, false));
+        assertEquals(yearHenceDate, mCalendarViewMaterial.getDate());
+    }
+
+    public void testAccessMinMaxDate() {
+        final Instrumentation instrumentation = getInstrumentation();
+
+        // Use a range of minus/plus one year as min/max dates
+        final Calendar minCalendar = new GregorianCalendar();
+        minCalendar.set(Calendar.YEAR, minCalendar.get(Calendar.YEAR) - 1);
+        final Calendar maxCalendar = new GregorianCalendar();
+        maxCalendar.set(Calendar.YEAR, maxCalendar.get(Calendar.YEAR) + 1);
+
+        final long minDate = minCalendar.getTime().getTime();
+        final long maxDate = maxCalendar.getTime().getTime();
+
+        instrumentation.runOnMainSync(() -> {
+            mCalendarViewMaterial.setMinDate(minDate);
+            mCalendarViewMaterial.setMaxDate(maxDate);
+        });
+
+        assertEquals(mCalendarViewMaterial.getMinDate(), minDate);
+        assertEquals(mCalendarViewMaterial.getMaxDate(), maxDate);
+    }
+
+    public void testAppearanceMaterial() {
+        // The logic in this method is performed on a Material-styled CalendarView and
+        // non-deprecated attributes / visual appearance APIs
+
+        // Test the initial appearance defined in the layout XML
+        assertEquals(2, mCalendarViewMaterial.getFirstDayOfWeek());
+        assertEquals(R.style.TextAppearance_WithColor,
+                mCalendarViewMaterial.getDateTextAppearance());
+        assertEquals(R.style.TextAppearance_WithColorGreen,
+                mCalendarViewMaterial.getWeekDayTextAppearance());
+
+        final Instrumentation instrumentation = getInstrumentation();
+
+        // Change the visual appearance of the widget
+        instrumentation.runOnMainSync(() -> {
+            mCalendarViewMaterial.setFirstDayOfWeek(3);
+            mCalendarViewMaterial.setDateTextAppearance(R.style.TextAppearance_WithColorBlue);
+            mCalendarViewMaterial.setWeekDayTextAppearance(R.style.TextAppearance_WithColorMagenta);
+        });
+
+        assertEquals(3, mCalendarViewMaterial.getFirstDayOfWeek());
+        assertEquals(R.style.TextAppearance_WithColorBlue,
+                mCalendarViewMaterial.getDateTextAppearance());
+        assertEquals(R.style.TextAppearance_WithColorMagenta,
+                mCalendarViewMaterial.getWeekDayTextAppearance());
+    }
+
+    public void testAppearanceHolo() {
+        // All the logic in this method is performed on a Holo-styled CalendarView, as
+        // under Material design we are ignoring most of these decorative attributes
+
+        // Test the initial appearance defined in the layout XML
+        assertEquals(3, mCalendarViewHolo.getFirstDayOfWeek());
+        assertEquals(5, mCalendarViewHolo.getShownWeekCount());
+        assertFalse(mCalendarViewHolo.getShowWeekNumber());
+        assertEquals(R.style.TextAppearance_WithColor,
+                mCalendarViewHolo.getDateTextAppearance());
+        assertEquals(R.style.TextAppearance_WithColorGreen,
+                mCalendarViewHolo.getWeekDayTextAppearance());
+        assertEquals(mActivity.getColor(R.color.calendarview_week_background),
+                mCalendarViewHolo.getSelectedWeekBackgroundColor());
+        assertEquals(mActivity.getColor(R.color.calendarview_focusedmonthdate),
+                mCalendarViewHolo.getFocusedMonthDateColor());
+        assertEquals(mActivity.getColor(R.color.calendarview_unfocusedmonthdate),
+                mCalendarViewHolo.getUnfocusedMonthDateColor());
+        TestUtils.assertAllPixelsOfColor("Selected date vertical bar blue",
+                mCalendarViewHolo.getSelectedDateVerticalBar(), 40, 40, true, 0xFF0000FF, 1, true);
+
+        final Instrumentation instrumentation = getInstrumentation();
+
+        // Change the visual appearance of the widget
+        final @ColorInt int newSelectedWeekBackgroundColor =
+                mActivity.getColor(R.color.calendarview_week_background_new);
+        final @ColorInt int newFocusedMonthDateColor =
+                mActivity.getColor(R.color.calendarview_focusedmonthdate_new);
+        final @ColorInt int newUnfocusedMonthDataColor =
+                mActivity.getColor(R.color.calendarview_unfocusedmonthdate_new);
+        final @ColorInt int newWeekNumberColor =
+                mActivity.getColor(R.color.calendarview_week_number_new);
+        final @ColorInt int newWeekSeparatorLineColor =
+                mActivity.getColor(R.color.calendarview_week_separatorline_new);
+
+        instrumentation.runOnMainSync(() -> {
+            mCalendarViewHolo.setFirstDayOfWeek(1);
+            mCalendarViewHolo.setShownWeekCount(4);
+            mCalendarViewHolo.setShowWeekNumber(true);
+            mCalendarViewHolo.setDateTextAppearance(R.style.TextAppearance_WithColorBlue);
+            mCalendarViewHolo.setWeekDayTextAppearance(R.style.TextAppearance_WithColorMagenta);
+            mCalendarViewHolo.setSelectedWeekBackgroundColor(newSelectedWeekBackgroundColor);
+            mCalendarViewHolo.setFocusedMonthDateColor(newFocusedMonthDateColor);
+            mCalendarViewHolo.setUnfocusedMonthDateColor(newUnfocusedMonthDataColor);
+            mCalendarViewHolo.setWeekNumberColor(newWeekNumberColor);
+            mCalendarViewHolo.setWeekSeparatorLineColor(newWeekSeparatorLineColor);
+        });
+
+        assertEquals(1, mCalendarViewHolo.getFirstDayOfWeek());
+        assertEquals(4, mCalendarViewHolo.getShownWeekCount());
+        assertTrue(mCalendarViewHolo.getShowWeekNumber());
+        assertEquals(R.style.TextAppearance_WithColorBlue,
+                mCalendarViewHolo.getDateTextAppearance());
+        assertEquals(R.style.TextAppearance_WithColorMagenta,
+                mCalendarViewHolo.getWeekDayTextAppearance());
+        assertEquals(newSelectedWeekBackgroundColor,
+                mCalendarViewHolo.getSelectedWeekBackgroundColor());
+        assertEquals(newFocusedMonthDateColor,
+                mCalendarViewHolo.getFocusedMonthDateColor());
+        assertEquals(newUnfocusedMonthDataColor,
+                mCalendarViewHolo.getUnfocusedMonthDateColor());
+        assertEquals(newWeekNumberColor,
+                mCalendarViewHolo.getWeekNumberColor());
+        assertEquals(newWeekSeparatorLineColor,
+                mCalendarViewHolo.getWeekSeparatorLineColor());
+
+        instrumentation.runOnMainSync(
+                () -> mCalendarViewHolo.setSelectedDateVerticalBar(R.drawable.yellow_fill));
+        TestUtils.assertAllPixelsOfColor("Selected date vertical bar yellow",
+                mCalendarViewHolo.getSelectedDateVerticalBar(), 40, 40, true, 0xFFFFFF00, 1, true);
+
+        instrumentation.runOnMainSync(
+                () -> mCalendarViewHolo.setSelectedDateVerticalBar(
+                        mActivity.getDrawable(R.drawable.magenta_fill)));
+        TestUtils.assertAllPixelsOfColor("Selected date vertical bar magenta",
+                mCalendarViewHolo.getSelectedDateVerticalBar(), 40, 40, true, 0xFFFF00FF, 1, true);
+    }
+}
diff --git a/tests/tests/widget/src/android/widget/cts/CheckBoxTest.java b/tests/tests/widget/src/android/widget/cts/CheckBoxTest.java
index 21e463f..b3a6e67 100644
--- a/tests/tests/widget/src/android/widget/cts/CheckBoxTest.java
+++ b/tests/tests/widget/src/android/widget/cts/CheckBoxTest.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 
 import org.xmlpull.v1.XmlPullParser;
diff --git a/tests/tests/widget/src/android/widget/cts/CheckedTextViewCtsActivity.java b/tests/tests/widget/src/android/widget/cts/CheckedTextViewCtsActivity.java
index a0ed498..52bef54 100644
--- a/tests/tests/widget/src/android/widget/cts/CheckedTextViewCtsActivity.java
+++ b/tests/tests/widget/src/android/widget/cts/CheckedTextViewCtsActivity.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 import android.app.Activity;
 import android.os.Bundle;
diff --git a/tests/tests/widget/src/android/widget/cts/CheckedTextViewTest.java b/tests/tests/widget/src/android/widget/cts/CheckedTextViewTest.java
index c5d3bd1..039ca70 100644
--- a/tests/tests/widget/src/android/widget/cts/CheckedTextViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/CheckedTextViewTest.java
@@ -16,7 +16,8 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.os.Parcelable;
+import android.widget.cts.R;
 
 
 import android.app.Activity;
@@ -44,7 +45,7 @@
     private Instrumentation mInstrumentation;
 
     public CheckedTextViewTest() {
-        super("com.android.cts.widget", CheckedTextViewCtsActivity.class);
+        super("android.widget.cts", CheckedTextViewCtsActivity.class);
     }
 
     @Override
@@ -266,6 +267,35 @@
         assertFalse(checkedTextView.isLayoutRequested());
     }
 
+    public void testSetCheckMarkByMixedTypes() {
+        CheckedTextView checkedTextView = new MockCheckedTextView(mActivity);
+        cleanUpForceLayoutFlags(checkedTextView);
+
+        // Specifically test for b/22626247 (AOSP issue 180455).
+        checkedTextView.setCheckMarkDrawable(R.drawable.scenery);
+        checkedTextView.setCheckMarkDrawable(null);
+        checkedTextView.setCheckMarkDrawable(R.drawable.scenery);
+        assertNotNull(checkedTextView.getCheckMarkDrawable());
+    }
+
+    public void testAccessInstanceState() {
+        CheckedTextView checkedTextView = new MockCheckedTextView(mActivity);
+        Parcelable state;
+
+        assertFalse(checkedTextView.isChecked());
+        assertFalse(checkedTextView.getFreezesText());
+
+        state = checkedTextView.onSaveInstanceState();
+        assertNotNull(state);
+        assertFalse(checkedTextView.getFreezesText());
+
+        checkedTextView.setChecked(true);
+
+        checkedTextView.onRestoreInstanceState(state);
+        assertFalse(checkedTextView.isChecked());
+        assertTrue(checkedTextView.isLayoutRequested());
+    }
+
     public void testOnDraw() {
         // Do not test. Implementation details.
     }
diff --git a/tests/tests/widget/src/android/widget/cts/ChronometerCtsActivity.java b/tests/tests/widget/src/android/widget/cts/ChronometerCtsActivity.java
index 3a7833d..7925b49 100644
--- a/tests/tests/widget/src/android/widget/cts/ChronometerCtsActivity.java
+++ b/tests/tests/widget/src/android/widget/cts/ChronometerCtsActivity.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 import android.app.Activity;
 import android.os.Bundle;
 import android.view.ViewGroup;
diff --git a/tests/tests/widget/src/android/widget/cts/ChronometerTest.java b/tests/tests/widget/src/android/widget/cts/ChronometerTest.java
index 7910274..ff1435f 100644
--- a/tests/tests/widget/src/android/widget/cts/ChronometerTest.java
+++ b/tests/tests/widget/src/android/widget/cts/ChronometerTest.java
@@ -28,7 +28,7 @@
 public class ChronometerTest extends ActivityInstrumentationTestCase2<ChronometerCtsActivity> {
     private ChronometerCtsActivity mActivity;
     public ChronometerTest() {
-        super("com.android.cts.widget", ChronometerCtsActivity.class);
+        super("android.widget.cts", ChronometerCtsActivity.class);
     }
 
     @Override
diff --git a/tests/tests/widget/src/android/widget/cts/CompoundButtonTest.java b/tests/tests/widget/src/android/widget/cts/CompoundButtonTest.java
index 98bf047..34d94a5 100644
--- a/tests/tests/widget/src/android/widget/cts/CompoundButtonTest.java
+++ b/tests/tests/widget/src/android/widget/cts/CompoundButtonTest.java
@@ -22,7 +22,7 @@
 import android.graphics.PorterDuff;
 import android.view.LayoutInflater;
 import android.widget.ToggleButton;
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 
 import org.xmlpull.v1.XmlPullParser;
@@ -172,7 +172,7 @@
         compoundButton.drawableStateChanged();
 
         // drawableStateChanged when CheckMarkDrawable is not null.
-        Drawable drawable = mResources.getDrawable(R.drawable.scenery);
+        Drawable drawable = mResources.getDrawable(R.drawable.statelistdrawable);
         compoundButton.setButtonDrawable(drawable);
         drawable.setState(null);
         assertNull(drawable.getState());
diff --git a/tests/tests/widget/src/android/widget/cts/CursorAdapterTest.java b/tests/tests/widget/src/android/widget/cts/CursorAdapterTest.java
index 730083e..0e6fb4d 100644
--- a/tests/tests/widget/src/android/widget/cts/CursorAdapterTest.java
+++ b/tests/tests/widget/src/android/widget/cts/CursorAdapterTest.java
@@ -37,7 +37,7 @@
 import android.widget.FilterQueryProvider;
 import android.widget.TextView;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 /**
  * Test {@link CursorAdapter}.
@@ -64,7 +64,7 @@
     protected void setUp() throws Exception {
         super.setUp();
         mContext = getInstrumentation().getTargetContext();
-        File dbDir = mContext.getDir("tests", Context.MODE_WORLD_WRITEABLE);
+        File dbDir = mContext.getDir("tests", Context.MODE_PRIVATE);
         mDatabaseFile = new File(dbDir, "database_test.db");
         if (mDatabaseFile.exists()) {
             mDatabaseFile.delete();
diff --git a/tests/tests/widget/src/android/widget/cts/CursorTreeAdapterTest.java b/tests/tests/widget/src/android/widget/cts/CursorTreeAdapterTest.java
index f74b9972..8ef414d 100644
--- a/tests/tests/widget/src/android/widget/cts/CursorTreeAdapterTest.java
+++ b/tests/tests/widget/src/android/widget/cts/CursorTreeAdapterTest.java
@@ -32,7 +32,7 @@
 import android.widget.FilterQueryProvider;
 import android.widget.TextView;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 
 /**
@@ -96,7 +96,7 @@
     protected void setUp() throws Exception {
         super.setUp();
         mContext = getInstrumentation().getTargetContext();
-        File dbDir = mContext.getDir("tests", Context.MODE_WORLD_WRITEABLE);
+        File dbDir = mContext.getDir("tests", Context.MODE_PRIVATE);
         mDatabaseFile = new File(dbDir, "database_test.db");
         if (mDatabaseFile.exists()) {
             mDatabaseFile.delete();
diff --git a/tests/tests/widget/src/android/widget/cts/DatePickerTest.java b/tests/tests/widget/src/android/widget/cts/DatePickerTest.java
index 3fa238e..c48f684 100644
--- a/tests/tests/widget/src/android/widget/cts/DatePickerTest.java
+++ b/tests/tests/widget/src/android/widget/cts/DatePickerTest.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 import android.content.Context;
 import android.content.res.XmlResourceParser;
diff --git a/tests/tests/widget/src/android/widget/cts/DialerFilterCtsActivity.java b/tests/tests/widget/src/android/widget/cts/DialerFilterCtsActivity.java
index 572d3fb..406a49a 100644
--- a/tests/tests/widget/src/android/widget/cts/DialerFilterCtsActivity.java
+++ b/tests/tests/widget/src/android/widget/cts/DialerFilterCtsActivity.java
@@ -18,7 +18,7 @@
 
 import android.app.Activity;
 import android.os.Bundle;
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 /**
  * A minimal application for DialerFilter test.
diff --git a/tests/tests/widget/src/android/widget/cts/DialerFilterTest.java b/tests/tests/widget/src/android/widget/cts/DialerFilterTest.java
index 68a17e7..a99f56a 100644
--- a/tests/tests/widget/src/android/widget/cts/DialerFilterTest.java
+++ b/tests/tests/widget/src/android/widget/cts/DialerFilterTest.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 
 import org.xmlpull.v1.XmlPullParser;
@@ -45,7 +45,7 @@
     private DialerFilter mDialerFilter;
 
     public DialerFilterTest() {
-        super("com.android.cts.widget", DialerFilterCtsActivity.class);
+        super("android.widget.cts", DialerFilterCtsActivity.class);
     }
 
     @Override
diff --git a/tests/tests/widget/src/android/widget/cts/DigitalClockCtsActivity.java b/tests/tests/widget/src/android/widget/cts/DigitalClockCtsActivity.java
index 68cb3f0..d92651e 100644
--- a/tests/tests/widget/src/android/widget/cts/DigitalClockCtsActivity.java
+++ b/tests/tests/widget/src/android/widget/cts/DigitalClockCtsActivity.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 import android.app.Activity;
 import android.os.Bundle;
diff --git a/tests/tests/widget/src/android/widget/cts/DigitalClockTest.java b/tests/tests/widget/src/android/widget/cts/DigitalClockTest.java
index 86a9672..2bfcc59 100644
--- a/tests/tests/widget/src/android/widget/cts/DigitalClockTest.java
+++ b/tests/tests/widget/src/android/widget/cts/DigitalClockTest.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 import org.xmlpull.v1.XmlPullParserException;
 
@@ -42,7 +42,7 @@
     private Context mContext;
 
     public DigitalClockTest() {
-        super("com.android.cts.widget", DigitalClockCtsActivity.class);
+        super("android.widget.cts", DigitalClockCtsActivity.class);
     }
 
     @Override
@@ -114,7 +114,7 @@
     private AttributeSet getAttributeSet(int resourceId) {
         XmlResourceParser parser = mActivity.getResources().getXml(resourceId);
         try {
-            XmlUtils.beginDocument(parser, "com.android.cts.widget.alarmclock.DigitalClock");
+            XmlUtils.beginDocument(parser, "android.widget.cts.alarmclock.DigitalClock");
         } catch (XmlPullParserException e) {
             fail("unexpected XmlPullParserException.");
         } catch (IOException e) {
diff --git a/tests/tests/widget/src/android/widget/cts/EditTextTest.java b/tests/tests/widget/src/android/widget/cts/EditTextTest.java
index 7a71a58..acf5f38 100644
--- a/tests/tests/widget/src/android/widget/cts/EditTextTest.java
+++ b/tests/tests/widget/src/android/widget/cts/EditTextTest.java
@@ -20,6 +20,7 @@
 
 import android.content.Context;
 import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
 import android.text.TextUtils;
 import android.text.method.ArrowKeyMovementMethod;
 import android.text.method.MovementMethod;
@@ -28,7 +29,7 @@
 import android.widget.EditText;
 import android.widget.TextView.BufferType;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 
 public class EditTextTest extends AndroidTestCase {
@@ -238,6 +239,78 @@
         }
     }
 
+    @SmallTest
+    public void testOnSaveInstanceState_savesTextStateWhenFreezesTextIsTrue() {
+        // prepare TextView for before saveInstanceState
+        final String testStr = "This is a test str";
+        EditText editText1 = new EditText(mContext);
+        editText1.setFreezesText(true);
+        editText1.setText(testStr);
+
+        // prepare TextView for after saveInstanceState
+        EditText editText2 = new EditText(mContext);
+        editText2.setFreezesText(true);
+
+        editText2.onRestoreInstanceState(editText1.onSaveInstanceState());
+
+        assertEquals(editText1.getText().toString(), editText2.getText().toString());
+    }
+
+    @SmallTest
+    public void testOnSaveInstanceState_savesTextStateWhenFreezesTextIfFalse() {
+        // prepare TextView for before saveInstanceState
+        final String testStr = "This is a test str";
+        EditText editText1 = new EditText(mContext);
+        editText1.setFreezesText(false);
+        editText1.setText(testStr);
+
+        // prepare TextView for after saveInstanceState
+        EditText editText2 = new EditText(mContext);
+        editText2.setFreezesText(false);
+
+        editText2.onRestoreInstanceState(editText1.onSaveInstanceState());
+
+        assertEquals(editText1.getText().toString(), editText2.getText().toString());
+    }
+
+    @SmallTest
+    public void testOnSaveInstanceState_savesSelectionStateWhenFreezesTextIsFalse() {
+        // prepare TextView for before saveInstanceState
+        final String testStr = "This is a test str";
+        EditText editText1 = new EditText(mContext);
+        editText1.setFreezesText(false);
+        editText1.setText(testStr);
+        editText1.setSelection(2, testStr.length() - 2);
+
+        // prepare TextView for after saveInstanceState
+        EditText editText2 = new EditText(mContext);
+        editText2.setFreezesText(false);
+
+        editText2.onRestoreInstanceState(editText1.onSaveInstanceState());
+
+        assertEquals(editText1.getSelectionStart(), editText2.getSelectionStart());
+        assertEquals(editText1.getSelectionEnd(), editText2.getSelectionEnd());
+    }
+
+    @SmallTest
+    public void testOnSaveInstanceState_savesSelectionStateWhenFreezesTextIsTrue() {
+        // prepare TextView for before saveInstanceState
+        final String testStr = "This is a test str";
+        EditText editText1 = new EditText(mContext);
+        editText1.setFreezesText(true);
+        editText1.setText(testStr);
+        editText1.setSelection(2, testStr.length() - 2);
+
+        // prepare TextView for after saveInstanceState
+        EditText editText2 = new EditText(mContext);
+        editText2.setFreezesText(true);
+
+        editText2.onRestoreInstanceState(editText1.onSaveInstanceState());
+
+        assertEquals(editText1.getSelectionStart(), editText2.getSelectionStart());
+        assertEquals(editText1.getSelectionEnd(), editText2.getSelectionEnd());
+    }
+
     private class MockEditText extends EditText {
         public MockEditText(Context context) {
             super(context);
diff --git a/tests/tests/widget/src/android/widget/cts/EmptyCtsActivity.java b/tests/tests/widget/src/android/widget/cts/EmptyCtsActivity.java
new file mode 100644
index 0000000..425de1f
--- /dev/null
+++ b/tests/tests/widget/src/android/widget/cts/EmptyCtsActivity.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.widget.cts;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class EmptyCtsActivity extends Activity {
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+    }
+}
\ No newline at end of file
diff --git a/tests/tests/widget/src/android/widget/cts/ExpandableListViewTest.java b/tests/tests/widget/src/android/widget/cts/ExpandableListViewTest.java
index ac48ed8..e773ebf 100644
--- a/tests/tests/widget/src/android/widget/cts/ExpandableListViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/ExpandableListViewTest.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 
 import org.xmlpull.v1.XmlPullParser;
diff --git a/tests/tests/widget/src/android/widget/cts/FilterTest.java b/tests/tests/widget/src/android/widget/cts/FilterTest.java
index 2c598dd..7a1d111 100644
--- a/tests/tests/widget/src/android/widget/cts/FilterTest.java
+++ b/tests/tests/widget/src/android/widget/cts/FilterTest.java
@@ -32,7 +32,7 @@
     private MockFilter mMockFilter;
 
     public FilterTest() {
-        super("com.android.cts.widget", CtsActivity.class);
+        super("android.widget.cts", CtsActivity.class);
     }
 
     public void testConstructor() throws Throwable {
diff --git a/tests/tests/widget/src/android/widget/cts/FrameLayoutCtsActivity.java b/tests/tests/widget/src/android/widget/cts/FrameLayoutCtsActivity.java
index c638313..1f97af4 100644
--- a/tests/tests/widget/src/android/widget/cts/FrameLayoutCtsActivity.java
+++ b/tests/tests/widget/src/android/widget/cts/FrameLayoutCtsActivity.java
@@ -18,7 +18,7 @@
 
 import android.app.Activity;
 import android.os.Bundle;
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 /**
  * A minimal application for frame layout test.
diff --git a/tests/tests/widget/src/android/widget/cts/FrameLayoutTest.java b/tests/tests/widget/src/android/widget/cts/FrameLayoutTest.java
index 31d9fff..4309dbb 100644
--- a/tests/tests/widget/src/android/widget/cts/FrameLayoutTest.java
+++ b/tests/tests/widget/src/android/widget/cts/FrameLayoutTest.java
@@ -16,22 +16,19 @@
 
 package android.widget.cts;
 
-import android.content.res.ColorStateList;
-import android.cts.util.WidgetTestUtils;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.ColorFilter;
-import android.graphics.PorterDuff;
-
-import com.android.cts.widget.R;
-
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
 import android.app.Activity;
 import android.app.Instrumentation;
 import android.content.Context;
+import android.content.res.ColorStateList;
 import android.cts.util.PollingCheck;
+import android.cts.util.WidgetTestUtils;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.ColorFilter;
+import android.graphics.PorterDuff;
 import android.graphics.Rect;
 import android.graphics.Region;
 import android.graphics.drawable.BitmapDrawable;
@@ -47,6 +44,8 @@
 import android.widget.FrameLayout.LayoutParams;
 import android.widget.LinearLayout;
 import android.widget.TextView;
+import android.widget.cts.R;
+import android.widget.cts.util.ViewTestUtils;
 
 import java.io.IOException;
 
@@ -56,7 +55,7 @@
     private FrameLayout mFrameLayout;
 
     public FrameLayoutTest() {
-        super("com.android.cts.widget", FrameLayoutCtsActivity.class);
+        super("android.widget.cts", FrameLayoutCtsActivity.class);
     }
 
     @Override
@@ -88,12 +87,8 @@
         assertTrue(mFrameLayout.getWidth() > foreground.getIntrinsicWidth());
         assertNull(mFrameLayout.getForeground());
 
-        mActivity.runOnUiThread(new Runnable() {
-            public void run() {
-                mFrameLayout.setForeground(foreground);
-            }
-        });
-        mInstrumentation.waitForIdleSync();
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mFrameLayout,
+                () -> mFrameLayout.setForeground(foreground));
         assertSame(foreground, mFrameLayout.getForeground());
         // check the default gravity FILL, it completely fills its container
         assertTrue(foreground.isVisible());
@@ -108,18 +103,16 @@
         assertEquals(mFrameLayout.getWidth(), rect.right - rect.left);
 
         // should get a new foreground again, because former foreground has been stretched
-        final BitmapDrawable newForeground
-                = (BitmapDrawable) mActivity.getResources().getDrawable(R.drawable.size_48x48);
+        final BitmapDrawable newForeground =
+                (BitmapDrawable) mActivity.getResources().getDrawable(R.drawable.size_48x48);
         compareScaledPixels(48, newForeground.getIntrinsicHeight());
         compareScaledPixels(48, newForeground.getIntrinsicWidth());
         assertTrue(mFrameLayout.getHeight() > newForeground.getIntrinsicHeight());
         assertTrue(mFrameLayout.getWidth() > foreground.getIntrinsicWidth());
 
-        mActivity.runOnUiThread(new Runnable() {
-            public void run() {
-                mFrameLayout.setForeground(newForeground);
-                mFrameLayout.setForegroundGravity(Gravity.CENTER);
-            }
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mFrameLayout, () -> {
+            mFrameLayout.setForeground(newForeground);
+            mFrameLayout.setForegroundGravity(Gravity.CENTER);
         });
         mInstrumentation.waitForIdleSync();
         assertSame(newForeground, mFrameLayout.getForeground());
@@ -132,24 +125,19 @@
     }
 
     public void testGatherTransparentRegion() {
-        final LinearLayout container
-                = (LinearLayout) mActivity.findViewById(R.id.framelayout_container);
+        final LinearLayout container =
+                (LinearLayout) mActivity.findViewById(R.id.framelayout_container);
         final Drawable foreground = mActivity.getResources().getDrawable(R.drawable.size_48x48);
-        mActivity.runOnUiThread(new Runnable() {
-            public void run() {
-                mFrameLayout.setForeground(foreground);
-                mFrameLayout.setForegroundGravity(Gravity.CENTER);
-            }
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mFrameLayout, () -> {
+            mFrameLayout.setForeground(foreground);
+            mFrameLayout.setForegroundGravity(Gravity.CENTER);
         });
         mInstrumentation.waitForIdleSync();
         Region region = new Region(foreground.getBounds());
         assertTrue(mFrameLayout.gatherTransparentRegion(region));
 
-        mActivity.runOnUiThread(new Runnable() {
-            public void run() {
-                container.requestTransparentRegion(mFrameLayout);
-            }
-        });
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mFrameLayout,
+                () -> container.requestTransparentRegion(mFrameLayout));
         mInstrumentation.waitForIdleSync();
         region = new Region(foreground.getBounds());
         assertTrue(mFrameLayout.gatherTransparentRegion(region));
@@ -168,11 +156,9 @@
         assertEquals(textView.getMeasuredWidth(), frameLayout.getMeasuredWidth());
 
         // measureAll is false and text view is GONE, text view will NOT be measured
-        mActivity.runOnUiThread(new Runnable() {
-            public void run() {
-                textView.setVisibility(View.GONE);
-                frameLayout.requestLayout();
-            }
+        mActivity.runOnUiThread(() -> {
+            textView.setVisibility(View.GONE);
+            frameLayout.requestLayout();
         });
         mInstrumentation.waitForIdleSync();
         assertFalse(frameLayout.getConsiderGoneChildrenWhenMeasuring());
@@ -183,11 +169,9 @@
         assertEquals(button.getMeasuredWidth(), frameLayout.getMeasuredWidth());
 
         // measureAll is true and text view is GONE, text view will be measured
-        mActivity.runOnUiThread(new Runnable() {
-            public void run() {
-                frameLayout.setMeasureAllChildren(true);
-                frameLayout.requestLayout();
-            }
+        mActivity.runOnUiThread(() -> {
+            frameLayout.setMeasureAllChildren(true);
+            frameLayout.requestLayout();
         });
         mInstrumentation.waitForIdleSync();
         assertTrue(frameLayout.getConsiderGoneChildrenWhenMeasuring());
@@ -237,6 +221,24 @@
         assertTrue(myFrameLayout.checkLayoutParams(params2));
     }
 
+    public void testGenerateLayoutParamsFromMarginParams() {
+        MyFrameLayout myFrameLayout = new MyFrameLayout(mActivity);
+        ViewGroup.MarginLayoutParams lp = new ViewGroup.MarginLayoutParams(3, 5);
+        lp.leftMargin = 1;
+        lp.topMargin = 2;
+        lp.rightMargin = 3;
+        lp.bottomMargin = 4;
+        LayoutParams generated = (LayoutParams) myFrameLayout.generateLayoutParams(lp);
+        assertNotNull(generated);
+        assertEquals(3, generated.width);
+        assertEquals(5, generated.height);
+
+        assertEquals(1, generated.leftMargin);
+        assertEquals(2, generated.topMargin);
+        assertEquals(3, generated.rightMargin);
+        assertEquals(4, generated.bottomMargin);
+    }
+
     public void testDrawableStateChanged() {
         // drawableStateChanged() is implementation details, do NOT test
     }
diff --git a/tests/tests/widget/src/android/widget/cts/FrameLayout_LayoutParamsTest.java b/tests/tests/widget/src/android/widget/cts/FrameLayout_LayoutParamsTest.java
index 1e7082f..5774b53 100644
--- a/tests/tests/widget/src/android/widget/cts/FrameLayout_LayoutParamsTest.java
+++ b/tests/tests/widget/src/android/widget/cts/FrameLayout_LayoutParamsTest.java
@@ -16,7 +16,8 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.view.Gravity;
+import android.widget.cts.R;
 
 
 import org.xmlpull.v1.XmlPullParser;
@@ -75,4 +76,47 @@
             // expected, test success.
         }
     }
+
+    public void testCopyConstructor() {
+        FrameLayout.LayoutParams copy;
+
+        final FrameLayout.LayoutParams fllp = new FrameLayout.LayoutParams(
+                LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
+        fllp.gravity = Gravity.BOTTOM;
+        fllp.leftMargin = 5;
+        fllp.topMargin = 10;
+        fllp.rightMargin = 15;
+        fllp.bottomMargin = 20;
+
+        copy = new FrameLayout.LayoutParams(fllp);
+        assertEquals("Width", fllp.width, copy.width);
+        assertEquals("Height", fllp.height, copy.height);
+        assertEquals("Gravity", fllp.gravity, copy.gravity);
+        assertEquals("Left margin", fllp.leftMargin, copy.leftMargin);
+        assertEquals("Top margin", fllp.topMargin, copy.topMargin);
+        assertEquals("Right margin", fllp.rightMargin, copy.rightMargin);
+        assertEquals("Bottom margin", fllp.bottomMargin, copy.bottomMargin);
+
+        final MarginLayoutParams mlp = new MarginLayoutParams(
+                LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
+        mlp.leftMargin = 5;
+        mlp.topMargin = 10;
+        mlp.rightMargin = 15;
+        mlp.bottomMargin = 20;
+
+        copy = new FrameLayout.LayoutParams(mlp);
+        assertEquals("Width", mlp.width, copy.width);
+        assertEquals("Height", mlp.height, copy.height);
+        assertEquals("Left margin", fllp.leftMargin, copy.leftMargin);
+        assertEquals("Top margin", fllp.topMargin, copy.topMargin);
+        assertEquals("Right margin", fllp.rightMargin, copy.rightMargin);
+        assertEquals("Bottom margin", fllp.bottomMargin, copy.bottomMargin);
+
+        final ViewGroup.LayoutParams vglp = new ViewGroup.LayoutParams(
+                LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
+
+        copy = new FrameLayout.LayoutParams(vglp);
+        assertEquals("Width", vglp.width, copy.width);
+        assertEquals("Height", vglp.height, copy.height);
+    }
 }
diff --git a/tests/tests/widget/src/android/widget/cts/GalleryCtsActivity.java b/tests/tests/widget/src/android/widget/cts/GalleryCtsActivity.java
index 8d32717..8039f47 100644
--- a/tests/tests/widget/src/android/widget/cts/GalleryCtsActivity.java
+++ b/tests/tests/widget/src/android/widget/cts/GalleryCtsActivity.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 import android.app.Activity;
 import android.content.Context;
diff --git a/tests/tests/widget/src/android/widget/cts/GalleryTest.java b/tests/tests/widget/src/android/widget/cts/GalleryTest.java
index 581107c..dd39461 100644
--- a/tests/tests/widget/src/android/widget/cts/GalleryTest.java
+++ b/tests/tests/widget/src/android/widget/cts/GalleryTest.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
@@ -64,7 +64,7 @@
     private final static float DELTA = 0.01f;
 
     public GalleryTest() {
-        super("com.android.cts.widget", GalleryCtsActivity.class);
+        super("android.widget.cts", GalleryCtsActivity.class);
     }
 
     @Override
diff --git a/tests/tests/widget/src/android/widget/cts/Gallery_LayoutParamsTest.java b/tests/tests/widget/src/android/widget/cts/Gallery_LayoutParamsTest.java
index 0502e38..eacb676 100644
--- a/tests/tests/widget/src/android/widget/cts/Gallery_LayoutParamsTest.java
+++ b/tests/tests/widget/src/android/widget/cts/Gallery_LayoutParamsTest.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 
 import org.xmlpull.v1.XmlPullParserException;
diff --git a/tests/tests/widget/src/android/widget/cts/GridLayoutCtsActivity.java b/tests/tests/widget/src/android/widget/cts/GridLayoutCtsActivity.java
index 3277ee8..bfbde22 100644
--- a/tests/tests/widget/src/android/widget/cts/GridLayoutCtsActivity.java
+++ b/tests/tests/widget/src/android/widget/cts/GridLayoutCtsActivity.java
@@ -18,7 +18,7 @@
 
 import android.app.Activity;
 import android.os.Bundle;
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 /**
  * A minimal application for {@link android.widget.GridLayout} test.
diff --git a/tests/tests/widget/src/android/widget/cts/GridLayoutTest.java b/tests/tests/widget/src/android/widget/cts/GridLayoutTest.java
index d701623..65e86b3 100644
--- a/tests/tests/widget/src/android/widget/cts/GridLayoutTest.java
+++ b/tests/tests/widget/src/android/widget/cts/GridLayoutTest.java
@@ -27,7 +27,7 @@
 import android.widget.Button;
 import android.widget.GridLayout;
 import android.widget.TextView;
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 import org.xmlpull.v1.XmlPullParser;
 
 import static android.view.ViewGroup.LAYOUT_MODE_OPTICAL_BOUNDS;
@@ -117,7 +117,7 @@
     private Context mContext;
 
     public GridLayoutTest() {
-        super("com.android.cts.widget", GridLayoutCtsActivity.class);
+        super("android.widget.cts", GridLayoutCtsActivity.class);
     }
 
     @Override
@@ -162,6 +162,24 @@
         assertEquals(ViewGroup.LayoutParams.WRAP_CONTENT, lp.height);
     }
 
+    public void testGenerateLayoutParamsFromMarginParams() {
+        MyGridLayout gridLayout = new MyGridLayout(mContext);
+        ViewGroup.MarginLayoutParams lp = new ViewGroup.MarginLayoutParams(3, 5);
+        lp.leftMargin = 1;
+        lp.topMargin = 2;
+        lp.rightMargin = 3;
+        lp.bottomMargin = 4;
+        GridLayout.LayoutParams generated = gridLayout.generateLayoutParams(lp);
+        assertNotNull(generated);
+        assertEquals(3, generated.width);
+        assertEquals(5, generated.height);
+
+        assertEquals(1, generated.leftMargin);
+        assertEquals(2, generated.topMargin);
+        assertEquals(3, generated.rightMargin);
+        assertEquals(4, generated.bottomMargin);
+    }
+
     private View[][] populate(GridLayout container) {
         Context context = container.getContext();
         int N = VERTICAL_ALIGNMENTS.length;
@@ -260,4 +278,29 @@
         //p.setLayoutMode(ViewGroup.LAYOUT_MODE_OPTICAL_BOUNDS);
         //test(p, table);
     }
+
+    private static class MyGridLayout extends GridLayout {
+
+        public MyGridLayout(Context context) {
+            super(context);
+        }
+
+        public MyGridLayout(Context context, AttributeSet attrs) {
+            super(context, attrs);
+        }
+
+        public MyGridLayout(Context context, AttributeSet attrs, int defStyleAttr) {
+            super(context, attrs, defStyleAttr);
+        }
+
+        public MyGridLayout(Context context, AttributeSet attrs, int defStyleAttr,
+                int defStyleRes) {
+            super(context, attrs, defStyleAttr, defStyleRes);
+        }
+
+        @Override
+        protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
+            return super.generateLayoutParams(p);
+        }
+    }
 }
diff --git a/tests/tests/widget/src/android/widget/cts/GridViewCtsActivity.java b/tests/tests/widget/src/android/widget/cts/GridViewCtsActivity.java
index 7a1182d..7b2e7a3 100644
--- a/tests/tests/widget/src/android/widget/cts/GridViewCtsActivity.java
+++ b/tests/tests/widget/src/android/widget/cts/GridViewCtsActivity.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 import android.app.Activity;
 import android.os.Bundle;
diff --git a/tests/tests/widget/src/android/widget/cts/GridViewTest.java b/tests/tests/widget/src/android/widget/cts/GridViewTest.java
index 3c615bd..8698280 100644
--- a/tests/tests/widget/src/android/widget/cts/GridViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/GridViewTest.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 
 import org.xmlpull.v1.XmlPullParser;
@@ -57,7 +57,7 @@
     private Instrumentation mInstrumentation;
 
     public GridViewTest() {
-        super("com.android.cts.widget", GridViewCtsActivity.class);
+        super("android.widget.cts", GridViewCtsActivity.class);
     }
 
     private GridView findGridViewById(int id) {
diff --git a/tests/tests/widget/src/android/widget/cts/HorizontalScrollViewCtsActivity.java b/tests/tests/widget/src/android/widget/cts/HorizontalScrollViewCtsActivity.java
index 312111a..a10e63a 100644
--- a/tests/tests/widget/src/android/widget/cts/HorizontalScrollViewCtsActivity.java
+++ b/tests/tests/widget/src/android/widget/cts/HorizontalScrollViewCtsActivity.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 import android.app.Activity;
 import android.os.Bundle;
diff --git a/tests/tests/widget/src/android/widget/cts/HorizontalScrollViewTest.java b/tests/tests/widget/src/android/widget/cts/HorizontalScrollViewTest.java
index 36398c3..afdc869 100644
--- a/tests/tests/widget/src/android/widget/cts/HorizontalScrollViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/HorizontalScrollViewTest.java
@@ -16,7 +16,8 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.FrameLayout;
+import android.widget.cts.R;
 
 
 import org.xmlpull.v1.XmlPullParser;
@@ -30,14 +31,14 @@
 import android.test.UiThreadTest;
 import android.util.AttributeSet;
 import android.util.Xml;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.View.MeasureSpec;
-import android.view.ViewGroup.LayoutParams;
 import android.widget.HorizontalScrollView;
 import android.widget.TextView;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
 
 /**
  * Test {@link HorizontalScrollView}.
@@ -54,7 +55,7 @@
     private Activity mActivity;
 
     public HorizontalScrollViewTest() {
-        super("com.android.cts.widget", HorizontalScrollViewCtsActivity.class);
+        super("android.widget.cts", HorizontalScrollViewCtsActivity.class);
     }
 
     @Override
@@ -332,6 +333,182 @@
         assertEquals(30, child.getMeasuredWidth());
     }
 
+    public void testMeasureSpecs() {
+        MyView child = spy(new MyView(mActivity));
+        MyHorizontalScrollView scrollView = new MyHorizontalScrollView(mActivity);
+        scrollView.addView(child);
+
+        scrollView.measureChild(child, MeasureSpec.makeMeasureSpec(100, MeasureSpec.EXACTLY),
+                MeasureSpec.makeMeasureSpec(150, MeasureSpec.EXACTLY));
+        verify(child).onMeasure(
+                eq(MeasureSpec.makeMeasureSpec(100, MeasureSpec.UNSPECIFIED)),
+                eq(MeasureSpec.makeMeasureSpec(150, MeasureSpec.EXACTLY)));
+    }
+
+    public void testMeasureSpecsWithPadding() {
+        MyView child = spy(new MyView(mActivity));
+        MyHorizontalScrollView scrollView = new MyHorizontalScrollView(mActivity);
+        scrollView.setPadding(3, 5, 7, 11);
+        scrollView.addView(child);
+
+        scrollView.measureChild(child, MeasureSpec.makeMeasureSpec(100, MeasureSpec.EXACTLY),
+                MeasureSpec.makeMeasureSpec(150, MeasureSpec.EXACTLY));
+        verify(child).onMeasure(
+                eq(MeasureSpec.makeMeasureSpec(90, MeasureSpec.UNSPECIFIED)),
+                eq(MeasureSpec.makeMeasureSpec(134, MeasureSpec.EXACTLY)));
+    }
+
+    public void testMeasureSpecsWithMargins() {
+        MyView child = spy(new MyView(mActivity));
+        MyHorizontalScrollView scrollView = new MyHorizontalScrollView(mActivity);
+        scrollView.addView(child);
+
+        scrollView.measureChildWithMargins(child,
+                MeasureSpec.makeMeasureSpec(100, MeasureSpec.EXACTLY), 15,
+                MeasureSpec.makeMeasureSpec(150, MeasureSpec.EXACTLY), 20);
+        verify(child).onMeasure(
+                eq(MeasureSpec.makeMeasureSpec(85, MeasureSpec.UNSPECIFIED)),
+                eq(MeasureSpec.makeMeasureSpec(130, MeasureSpec.EXACTLY)));
+    }
+
+    public void testMeasureSpecsWithMarginsAndPadding() {
+        MyView child = spy(new MyView(mActivity));
+        MyHorizontalScrollView scrollView = new MyHorizontalScrollView(mActivity);
+        scrollView.setPadding(3, 5, 7, 11);
+        scrollView.addView(child);
+
+        scrollView.measureChildWithMargins(child,
+                MeasureSpec.makeMeasureSpec(100, MeasureSpec.EXACTLY), 15,
+                MeasureSpec.makeMeasureSpec(150, MeasureSpec.EXACTLY), 20);
+        verify(child).onMeasure(
+                eq(MeasureSpec.makeMeasureSpec(75, MeasureSpec.UNSPECIFIED)),
+                eq(MeasureSpec.makeMeasureSpec(114, MeasureSpec.EXACTLY)));
+    }
+
+    public void testMeasureSpecsWithMarginsAndNoHintWidth() {
+        MyView child = spy(new MyView(mActivity));
+        MyHorizontalScrollView scrollView = new MyHorizontalScrollView(mActivity);
+        scrollView.addView(child);
+
+        scrollView.measureChildWithMargins(child,
+                MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), 15,
+                MeasureSpec.makeMeasureSpec(150, MeasureSpec.EXACTLY), 20);
+        verify(child).onMeasure(
+                eq(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)),
+                eq(MeasureSpec.makeMeasureSpec(130, MeasureSpec.EXACTLY)));
+    }
+
+    public void testFillViewport() {
+        MyHorizontalScrollView scrollView = new MyHorizontalScrollView(mActivity);
+
+        MyView child = new MyView(mActivity);
+        scrollView.setFillViewport(true);
+        child.setLayoutParams(new ViewGroup.LayoutParams(
+                ViewGroup.LayoutParams.WRAP_CONTENT,
+                ViewGroup.LayoutParams.WRAP_CONTENT
+        ));
+
+        scrollView.addView(child);
+        scrollView.measure(MeasureSpec.makeMeasureSpec(150, MeasureSpec.EXACTLY),
+                MeasureSpec.makeMeasureSpec(100, MeasureSpec.EXACTLY));
+
+        assertEquals(150, child.getMeasuredWidth());
+        assertEquals(100, child.getMeasuredHeight());
+
+        scrollView.layout(0, 0, 150, 100);
+        assertEquals(0, child.getLeft());
+    }
+
+    public void testFillViewportWithScrollViewPadding() {
+        MyHorizontalScrollView scrollView = new MyHorizontalScrollView(mActivity);
+        scrollView.setFillViewport(true);
+        scrollView.setPadding(3, 10, 5, 7);
+
+        MyView child = new MyView(mActivity);
+        child.setLayoutParams(new ViewGroup.LayoutParams(10,10));
+        child.setDesiredWidth(30);
+
+        scrollView.addView(child);
+        scrollView.measure(MeasureSpec.makeMeasureSpec(100, MeasureSpec.EXACTLY),
+                MeasureSpec.makeMeasureSpec(150, MeasureSpec.EXACTLY));
+
+        assertEquals(92, child.getMeasuredWidth());
+        assertEquals(10, child.getMeasuredHeight());
+
+        scrollView.layout(0, 0, 100, 150);
+        assertEquals(3, child.getLeft());
+    }
+
+    public void testFillViewportWithChildMargins() {
+        MyHorizontalScrollView scrollView = new MyHorizontalScrollView(mActivity);
+        scrollView.setFillViewport(true);
+
+        MyView child = new MyView(mActivity);
+        FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(10, 10);
+        lp.leftMargin = 3;
+        lp.topMargin = 10;
+        lp.rightMargin = 5;
+        lp.bottomMargin = 7;
+        child.setDesiredWidth(30);
+        child.setLayoutParams(lp);
+
+        scrollView.addView(child);
+        scrollView.measure(MeasureSpec.makeMeasureSpec(100, MeasureSpec.EXACTLY),
+                MeasureSpec.makeMeasureSpec(150, MeasureSpec.EXACTLY));
+
+        assertEquals(92, child.getMeasuredWidth());
+        assertEquals(10, child.getMeasuredHeight());
+
+        scrollView.layout(0, 0, 100, 150);
+        assertEquals(3, child.getLeft());
+    }
+
+    public void testFillViewportWithScrollViewPaddingAlreadyFills() {
+        MyHorizontalScrollView scrollView = new MyHorizontalScrollView(mActivity);
+        scrollView.setFillViewport(true);
+        scrollView.setPadding(3, 10, 5, 7);
+
+        MyView child = new MyView(mActivity);
+        child.setDesiredWidth(175);
+
+        scrollView.addView(child);
+        scrollView.measure(MeasureSpec.makeMeasureSpec(100, MeasureSpec.EXACTLY),
+                MeasureSpec.makeMeasureSpec(150, MeasureSpec.EXACTLY));
+
+
+        assertEquals(175, child.getMeasuredWidth());
+        assertEquals(133, child.getMeasuredHeight());
+
+        scrollView.layout(0, 0, 100, 150);
+        assertEquals(3, child.getLeft());
+    }
+
+    public void testFillViewportWithChildMarginsAlreadyFills() {
+        MyHorizontalScrollView scrollView = new MyHorizontalScrollView(mActivity);
+        scrollView.setFillViewport(true);
+        MyView child = new MyView(mActivity);
+        FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
+                ViewGroup.LayoutParams.MATCH_PARENT,
+                ViewGroup.LayoutParams.WRAP_CONTENT);
+
+        lp.leftMargin = 3;
+        lp.topMargin = 10;
+        lp.rightMargin = 5;
+        lp.bottomMargin = 7;
+        child.setLayoutParams(lp);
+        child.setDesiredWidth(175);
+
+        scrollView.addView(child);
+        scrollView.measure(MeasureSpec.makeMeasureSpec(100, MeasureSpec.EXACTLY),
+                MeasureSpec.makeMeasureSpec(150, MeasureSpec.EXACTLY));
+
+        assertEquals(175, child.getMeasuredWidth());
+        assertEquals(133, child.getMeasuredHeight());
+
+        scrollView.layout(0, 0, 100, 150);
+        assertEquals(3, child.getLeft());
+    }
+
     @UiThreadTest
     public void testPageScroll() {
         mScrollView.setSmoothScrollingEnabled(false);
@@ -462,9 +639,9 @@
         assertTrue(mScrollView.getChildCount() > 0);
         assertEquals(ITEM_WIDTH * ITEM_COUNT, mScrollView.computeHorizontalScrollRange());
 
-        MyScrollView myScrollView = new MyScrollView(mActivity);
-        assertEquals(0, myScrollView.getChildCount());
-        assertEquals(0, myScrollView.computeVerticalScrollRange());
+        MyHorizontalScrollView scrollView = new MyHorizontalScrollView(mActivity);
+        assertEquals(0, scrollView.getChildCount());
+        assertEquals(0, scrollView.computeHorizontalScrollRange());
     }
 
     @UiThreadTest
@@ -564,7 +741,7 @@
         assertTrue(mScrollView.getRightFadingEdgeStrength() <= 1.0f);
         assertTrue(mScrollView.getRightFadingEdgeStrength() >= 0.0f);
 
-        MyScrollView myScrollView = new MyScrollView(mActivity);
+        MyHorizontalScrollView myScrollView = new MyHorizontalScrollView(mActivity);
         assertEquals(0, myScrollView.getChildCount());
         assertTrue(mScrollView.getLeftFadingEdgeStrength() <= 1.0f);
         assertTrue(mScrollView.getLeftFadingEdgeStrength() >= 0.0f);
@@ -674,9 +851,31 @@
         }.run();
     }
 
-    private static class MyView extends View {
+    public static class MyView extends View {
+        // measure in this height if set
+        private Integer mDesiredWidth;
         public MyView(Context context) {
             super(context);
         }
+
+        public void setDesiredWidth(Integer desiredWidth) {
+            mDesiredWidth = desiredWidth;
+        }
+
+        @Override
+        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+            if (mDesiredWidth != null) {
+                int mode = MeasureSpec.getMode(widthMeasureSpec);
+                int size = MeasureSpec.getSize(widthMeasureSpec);
+                int newWidth = size;
+                if (mode == MeasureSpec.AT_MOST) {
+                    newWidth = Math.max(size, mDesiredWidth);
+                } else if (mode == MeasureSpec.UNSPECIFIED) {
+                    newWidth = mDesiredWidth;
+                }
+                setMeasuredDimension(newWidth, getMeasuredHeight());
+            }
+        }
     }
 }
diff --git a/tests/tests/widget/src/android/widget/cts/ImageButtonTest.java b/tests/tests/widget/src/android/widget/cts/ImageButtonTest.java
index 374c9c2..05c0e3f 100644
--- a/tests/tests/widget/src/android/widget/cts/ImageButtonTest.java
+++ b/tests/tests/widget/src/android/widget/cts/ImageButtonTest.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 
 import org.xmlpull.v1.XmlPullParser;
diff --git a/tests/tests/widget/src/android/widget/cts/ImageSwitcherTest.java b/tests/tests/widget/src/android/widget/cts/ImageSwitcherTest.java
index eb75557..a7bca5c 100644
--- a/tests/tests/widget/src/android/widget/cts/ImageSwitcherTest.java
+++ b/tests/tests/widget/src/android/widget/cts/ImageSwitcherTest.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 
 import org.xmlpull.v1.XmlPullParser;
@@ -170,7 +170,7 @@
                 if (target != null) {
                     target.close();
                 }
-            } catch (IOException _) {
+            } catch (IOException ignored) {
                 // Ignore the IOException.
             }
         }
diff --git a/tests/tests/widget/src/android/widget/cts/ImageViewCtsActivity.java b/tests/tests/widget/src/android/widget/cts/ImageViewCtsActivity.java
index 295f3da..e68c986 100644
--- a/tests/tests/widget/src/android/widget/cts/ImageViewCtsActivity.java
+++ b/tests/tests/widget/src/android/widget/cts/ImageViewCtsActivity.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 import android.app.Activity;
 import android.os.Bundle;
diff --git a/tests/tests/widget/src/android/widget/cts/ImageViewTest.java b/tests/tests/widget/src/android/widget/cts/ImageViewTest.java
index aa1df34..844b922 100644
--- a/tests/tests/widget/src/android/widget/cts/ImageViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/ImageViewTest.java
@@ -25,6 +25,11 @@
 import android.content.res.ColorStateList;
 import android.graphics.Color;
 
+import android.graphics.drawable.ColorDrawable;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.widget.cts.util.TestUtils;
+import android.widget.cts.util.ViewTestUtils;
+import org.junit.Assert;
 import org.xmlpull.v1.XmlPullParser;
 
 import android.app.Activity;
@@ -49,18 +54,22 @@
 import android.widget.ImageView;
 import android.widget.ImageView.ScaleType;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.*;
 
 
 /**
  * Test {@link ImageView}.
  */
+@SmallTest
 public class ImageViewTest extends ActivityInstrumentationTestCase<ImageViewCtsActivity> {
     private ImageView mImageView;
     private Activity mActivity;
 
     public ImageViewTest() {
-        super("com.android.cts.widget", ImageViewCtsActivity.class);
+        super("android.widget.cts", ImageViewCtsActivity.class);
     }
 
     /**
@@ -95,7 +104,7 @@
                 if (target != null) {
                     target.close();
                 }
-            } catch (IOException _) {
+            } catch (IOException ignored) {
                 // Ignore the IOException.
             }
         }
@@ -115,6 +124,8 @@
 
         new ImageView(mActivity, null, 0);
 
+        new ImageView(mActivity, null, 0, 0);
+
         XmlPullParser parser = mActivity.getResources().getXml(R.layout.imageview_layout);
         AttributeSet attrs = Xml.asAttributeSet(parser);
         new ImageView(mActivity, attrs);
@@ -143,9 +154,11 @@
         imageView.setScaleType(ScaleType.FIT_XY);
 
         imageView.setAdjustViewBounds(false);
+        assertFalse(imageView.getAdjustViewBounds());
         assertEquals(ScaleType.FIT_XY, imageView.getScaleType());
 
         imageView.setAdjustViewBounds(true);
+        assertTrue(imageView.getAdjustViewBounds());
         assertEquals(ScaleType.FIT_CENTER, imageView.getScaleType());
     }
 
@@ -240,7 +253,7 @@
         mImageView.setImageDrawable(null);
         assertNull(mImageView.getDrawable());
 
-        final Drawable drawable = mActivity.getResources().getDrawable(R.drawable.testimage);
+        final Drawable drawable = mActivity.getDrawable(R.drawable.testimage);
         mImageView.setImageDrawable(drawable);
         assertTrue(mImageView.isLayoutRequested());
         assertNotNull(mImageView.getDrawable());
@@ -336,68 +349,91 @@
         assertEquals(matrix, imageView.getImageMatrix());
     }
 
-    public void testGetBaseline() {
-        final ImageView imageView = new ImageView(mActivity);
-        assertEquals(-1, imageView.getBaseline());
+    @UiThreadTest
+    public void testAccessBaseline() {
+        mImageView = findImageViewById(R.id.imageview);
+
+        mImageView.setImageDrawable(null);
+        assertNull(mImageView.getDrawable());
+
+        final Drawable drawable = mActivity.getDrawable(R.drawable.testimage);
+        mImageView.setImageDrawable(drawable);
+
+        assertEquals(-1, mImageView.getBaseline());
+
+        mImageView.setBaseline(50);
+        assertEquals(50, mImageView.getBaseline());
+
+        mImageView.setBaselineAlignBottom(true);
+        assertTrue(mImageView.getBaselineAlignBottom());
+        assertEquals(mImageView.getMeasuredHeight(), mImageView.getBaseline());
+
+        mImageView.setBaselineAlignBottom(false);
+        assertFalse(mImageView.getBaselineAlignBottom());
+        assertEquals(50, mImageView.getBaseline());
     }
 
+    @UiThreadTest
     public void testSetColorFilter1() {
-        MockDrawable drawable = new MockDrawable();
+        mImageView = findImageViewById(R.id.imageview);
 
-        ImageView imageView = new ImageView(mActivity);
-        imageView.setImageDrawable(drawable);
-        imageView.setColorFilter(null);
+        final Drawable drawable = mActivity.getDrawable(R.drawable.testimage);
+        mImageView.setImageDrawable(drawable);
+
+        mImageView.setColorFilter(null);
         assertNull(drawable.getColorFilter());
 
-        imageView.setColorFilter(0, PorterDuff.Mode.CLEAR);
+        mImageView.setColorFilter(0, PorterDuff.Mode.CLEAR);
         assertNotNull(drawable.getColorFilter());
+        assertNotNull(mImageView.getColorFilter());
     }
 
+    @UiThreadTest
     public void testClearColorFilter() {
-        MockDrawable drawable = new MockDrawable();
+        mImageView = findImageViewById(R.id.imageview);
+
+        final Drawable drawable = mActivity.getDrawable(R.drawable.testimage);
+        mImageView.setImageDrawable(drawable);
+
         ColorFilter cf = new ColorFilter();
+        mImageView.setColorFilter(cf);
 
-        ImageView imageView = new ImageView(mActivity);
-        imageView.setImageDrawable(drawable);
-        imageView.setColorFilter(cf);
-
-        imageView.clearColorFilter();
+        mImageView.clearColorFilter();
         assertNull(drawable.getColorFilter());
+        assertNull(mImageView.getColorFilter());
     }
 
+    @UiThreadTest
     public void testSetColorFilter2() {
-        MockDrawable drawable = new MockDrawable();
+        mImageView = findImageViewById(R.id.imageview);
 
-        ImageView imageView = new ImageView(mActivity);
-        imageView.setImageDrawable(drawable);
-        imageView.setColorFilter(null);
+        final Drawable drawable = mActivity.getDrawable(R.drawable.testimage);
+        mImageView.setImageDrawable(drawable);
+
+        mImageView.setColorFilter(null);
         assertNull(drawable.getColorFilter());
+        assertNull(mImageView.getColorFilter());
 
         ColorFilter cf = new ColorFilter();
-        imageView.setColorFilter(cf);
+        mImageView.setColorFilter(cf);
         assertSame(cf, drawable.getColorFilter());
-    }
-
-    public void testSetAlpha() {
-        MockDrawable drawable = new MockDrawable();
-
-        ImageView imageView = new ImageView(mActivity);
-        imageView.setImageDrawable(drawable);
-        imageView.setAlpha(0);
-        assertEquals(0, drawable.getAlpha());
-
-        imageView.setAlpha(255);
-        assertEquals(255, drawable.getAlpha());
+        assertSame(cf, mImageView.getColorFilter());
     }
 
     public void testDrawableStateChanged() {
-        MockImageView mockImageView = new MockImageView(mActivity);
-        MockDrawable drawable = new MockDrawable();
+        MockImageView imageView = spy(new MockImageView(mActivity));
+        Drawable selectorDrawable = mActivity.getDrawable(R.drawable.statelistdrawable);
+        imageView.setImageDrawable(selectorDrawable);
 
-        assertSame(StateSet.WILD_CARD, drawable.getState());
-        mockImageView.setImageDrawable(drawable);
-        mockImageView.drawableStateChanged();
-        assertSame(mockImageView.getDrawableState(), drawable.getState());
+        // We shouldn't have been called on state change yet
+        verify(imageView, never()).drawableStateChanged();
+        // Mark image view as selected. Since our selector drawable has an "entry" for selected
+        // state, that should cause a call to drawableStateChanged()
+        imageView.setSelected(true);
+        // Test that our image view has indeed called its own drawableStateChanged()
+        verify(imageView, times(1)).drawableStateChanged();
+        // And verify that image view's state matches that of our drawable
+        Assert.assertArrayEquals(imageView.getDrawableState(), selectorDrawable.getState());
     }
 
     public void testOnCreateDrawableState() {
@@ -419,10 +455,11 @@
 
     public void testOnDraw() {
         MockImageView mockImageView = new MockImageView(mActivity);
-        MockDrawable drawable = new MockDrawable();
+        Drawable drawable = spy(mActivity.getDrawable(R.drawable.icon_red));
         mockImageView.setImageDrawable(drawable);
         mockImageView.onDraw(new Canvas());
-        assertTrue(drawable.hasDrawCalled());
+
+        verify(drawable, atLeastOnce()).draw(any(Canvas.class));
     }
 
     public void testOnMeasure() {
@@ -433,68 +470,139 @@
     }
 
     public void testSetFrame() {
-        MockImageView mockImageView = new MockImageView(mActivity);
-        assertFalse(mockImageView.hasOnSizeChangedCalled());
+        MockImageView mockImageView = spy(new MockImageView(mActivity));
+        verify(mockImageView, never()).onSizeChanged(anyInt(), anyInt(), anyInt(), anyInt());
+
         assertTrue(mockImageView.setFrame(5, 10, 100, 200));
         assertEquals(5, mockImageView.getLeft());
         assertEquals(10, mockImageView.getTop());
         assertEquals(100, mockImageView.getRight());
         assertEquals(200, mockImageView.getBottom());
-        assertTrue(mockImageView.hasOnSizeChangedCalled());
+        verify(mockImageView, times(1)).onSizeChanged(95, 190, 0, 0);
 
-        mockImageView.reset();
         assertFalse(mockImageView.setFrame(5, 10, 100, 200));
-        assertFalse(mockImageView.hasOnSizeChangedCalled());
+        // Verify that there were no more calls to onSizeChanged (since the new frame is the
+        // same frame as we had before).
+        verify(mockImageView, times(1)).onSizeChanged(anyInt(), anyInt(), anyInt(), anyInt());
     }
 
     public void testVerifyDrawable() {
         MockImageView mockImageView = new MockImageView(mActivity);
-        MockDrawable drawable = new MockDrawable();
+        Drawable drawable = new ColorDrawable(0xFFFF0000);
         mockImageView.setImageDrawable(drawable);
-        MockDrawable bgdrawable = new MockDrawable();
-        mockImageView.setBackgroundDrawable(bgdrawable);
+        Drawable backgroundDrawable = new ColorDrawable(0xFF0000FF);
+        mockImageView.setBackgroundDrawable(backgroundDrawable);
+
         assertFalse(mockImageView.verifyDrawable(null));
-        assertFalse(mockImageView.verifyDrawable(new MockDrawable()));
+        assertFalse(mockImageView.verifyDrawable(new ColorDrawable(0xFF00FF00)));
         assertTrue(mockImageView.verifyDrawable(drawable));
-        assertTrue(mockImageView.verifyDrawable(bgdrawable));
+        assertTrue(mockImageView.verifyDrawable(backgroundDrawable));
     }
 
-    public void testImageTint() {
-        ImageView inflatedView = (ImageView) mActivity.findViewById(R.id.image_tint);
+    @UiThreadTest
+    public void testImageTintBasics() {
+        mImageView = findImageViewById(R.id.image_tint);
 
         assertEquals("Image tint inflated correctly",
-                Color.WHITE, inflatedView.getImageTintList().getDefaultColor());
+                Color.WHITE, mImageView.getImageTintList().getDefaultColor());
         assertEquals("Image tint mode inflated correctly",
-                PorterDuff.Mode.SRC_OVER, inflatedView.getImageTintMode());
+                PorterDuff.Mode.SRC_OVER, mImageView.getImageTintMode());
 
-        MockDrawable image = new MockDrawable();
-        ImageView view = new ImageView(mActivity);
-
-        view.setImageDrawable(image);
-        assertFalse("No image tint applied by default", image.hasCalledSetTint());
-
-        view.setImageTintList(ColorStateList.valueOf(Color.WHITE));
-        assertTrue("Image tint applied when setImageTintList() called after set()",
-                image.hasCalledSetTint());
-
-        image.reset();
-        view.setImageDrawable(null);
-        view.setImageDrawable(image);
-        assertTrue("Image tint applied when setImageTintList() called before set()",
-                image.hasCalledSetTint());
+        mImageView.setImageTintMode(PorterDuff.Mode.SRC_IN);
+        assertEquals(PorterDuff.Mode.SRC_IN, mImageView.getImageTintMode());
     }
 
-    private static class MockImageView extends ImageView {
-        private boolean mOnSizeChangedCalled = false;
+    public void testImageTintDrawableUpdates() {
+        Drawable drawable = spy(mActivity.getDrawable(R.drawable.icon_red));
 
-        public boolean hasOnSizeChangedCalled() {
-            return mOnSizeChangedCalled;
-        }
+        ImageView view = new ImageView(mActivity);
+        view.setImageDrawable(drawable);
+        // No image tint applied by default
+        verify(drawable, never()).setTintList(any(ColorStateList.class));
 
-        public void reset() {
-            mOnSizeChangedCalled = false;
-        }
+        view.setImageTintList(ColorStateList.valueOf(Color.WHITE));
+        // Image tint applied when setImageTintList() called after setImageDrawable()
+        verify(drawable, times(1)).setTintList(any(ColorStateList.class));
 
+        view.setImageDrawable(null);
+        view.setImageDrawable(drawable);
+        // Image tint applied when setImageTintList() called before setImageDrawable()
+        verify(drawable, times(2)).setTintList(any(ColorStateList.class));
+    }
+
+    @UiThreadTest
+    public void testImageTintVisuals() {
+        mImageView = findImageViewById(R.id.image_tint_with_source);
+        TestUtils.assertAllPixelsOfColor("All pixels should be white", mImageView,
+                0xFFFFFFFF, 1, false);
+
+        // Use translucent white tint. Together with SRC_OVER mode (defined in XML) the end
+        // result should be a fully opaque image view with solid fill color in between red
+        // and white.
+        mImageView.setImageTintList(ColorStateList.valueOf(0x80FFFFFF));
+        TestUtils.assertAllPixelsOfColor("All pixels should be light red", mImageView,
+                0xFFFF8080, 1, false);
+
+        // Switch to SRC_IN mode. This should completely ignore the original drawable set on
+        // the image view and use the last set tint color (50% alpha white).
+        mImageView.setImageTintMode(PorterDuff.Mode.SRC_IN);
+        TestUtils.assertAllPixelsOfColor("All pixels should be 50% alpha white", mImageView,
+                0x80FFFFFF, 1, false);
+
+        // Switch to DST mode. This should completely ignore the last set tint color and use the
+        // the original drawable set on the image view.
+        mImageView.setImageTintMode(PorterDuff.Mode.DST);
+        TestUtils.assertAllPixelsOfColor("All pixels should be red", mImageView,
+                0xFFFF0000, 1, false);
+    }
+
+    @UiThreadTest
+    public void testAlpha() {
+        mImageView = findImageViewById(R.id.imageview);
+        mImageView.setImageResource(R.drawable.blue_fill);
+
+        TestUtils.assertAllPixelsOfColor("All pixels should be blue", mImageView,
+                0xFF0000FF, 1, false);
+
+        mImageView.setAlpha(128);
+        TestUtils.assertAllPixelsOfColor("All pixels should be 50% alpha blue", mImageView,
+                0x800000FF, 1, false);
+
+        mImageView.setAlpha(0);
+        TestUtils.assertAllPixelsOfColor("All pixels should be transparent", mImageView,
+                0x00000000, 1, false);
+
+        mImageView.setAlpha(255);
+        TestUtils.assertAllPixelsOfColor("All pixels should be blue", mImageView,
+                0xFF0000FF, 1, false);
+    }
+
+    @UiThreadTest
+    public void testImageAlpha() {
+        mImageView = findImageViewById(R.id.imageview);
+        mImageView.setImageResource(R.drawable.blue_fill);
+
+        assertEquals(255, mImageView.getImageAlpha());
+        TestUtils.assertAllPixelsOfColor("All pixels should be blue", mImageView,
+                0xFF0000FF, 1, false);
+
+        mImageView.setImageAlpha(128);
+        assertEquals(128, mImageView.getImageAlpha());
+        TestUtils.assertAllPixelsOfColor("All pixels should be 50% alpha blue", mImageView,
+                0x800000FF, 1, false);
+
+        mImageView.setImageAlpha(0);
+        assertEquals(0, mImageView.getImageAlpha());
+        TestUtils.assertAllPixelsOfColor("All pixels should be transparent", mImageView,
+                0x00000000, 1, false);
+
+        mImageView.setImageAlpha(255);
+        assertEquals(255, mImageView.getImageAlpha());
+        TestUtils.assertAllPixelsOfColor("All pixels should be blue", mImageView,
+                0xFF0000FF, 1, false);
+    }
+
+    protected static class MockImageView extends ImageView {
         public MockImageView(Context context) {
             super(context);
         }
@@ -540,64 +648,7 @@
         }
 
         protected void onSizeChanged(int w, int h, int oldw, int oldh) {
-            mOnSizeChangedCalled = true;
-        }
-    }
-
-    private class MockDrawable extends Drawable {
-        private ColorFilter mColorFilter;
-        private boolean mDrawCalled = false;
-        private boolean mCalledSetTint = false;
-        private int mAlpha;
-
-        public boolean hasDrawCalled() {
-            return mDrawCalled;
-        }
-
-        public ColorFilter getColorFilter() {
-            return mColorFilter;
-        }
-
-        @Override
-        public void draw(Canvas canvas) {
-            mDrawCalled = true;
-        }
-
-        @Override
-        public void setAlpha(int alpha) {
-            mAlpha = alpha;
-        }
-
-        public int getAlpha() {
-            return mAlpha;
-        }
-
-        @Override
-        public void setColorFilter(ColorFilter cf) {
-            mColorFilter = cf;
-        }
-
-        @Override
-        public int getOpacity() {
-            return 0;
-        }
-
-        public boolean isStateful() {
-            return true;
-        }
-
-        @Override
-        public void setTintList(ColorStateList tint) {
-            super.setTintList(tint);
-            mCalledSetTint = true;
-        }
-
-        public boolean hasCalledSetTint() {
-            return mCalledSetTint;
-        }
-
-        public void reset() {
-            mCalledSetTint = false;
+            super.onSizeChanged(w, h, oldw, oldh);
         }
     }
 }
diff --git a/tests/tests/widget/src/android/widget/cts/LayoutDirectionCtsActivity.java b/tests/tests/widget/src/android/widget/cts/LayoutDirectionCtsActivity.java
index 093f554..755091d 100644
--- a/tests/tests/widget/src/android/widget/cts/LayoutDirectionCtsActivity.java
+++ b/tests/tests/widget/src/android/widget/cts/LayoutDirectionCtsActivity.java
@@ -18,7 +18,7 @@
 
 import android.app.Activity;
 import android.os.Bundle;
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 /**
  * A minimal application for layout direction test.
diff --git a/tests/tests/widget/src/android/widget/cts/LayoutDirectionTest.java b/tests/tests/widget/src/android/widget/cts/LayoutDirectionTest.java
index c393e95..2369c5a 100644
--- a/tests/tests/widget/src/android/widget/cts/LayoutDirectionTest.java
+++ b/tests/tests/widget/src/android/widget/cts/LayoutDirectionTest.java
@@ -20,7 +20,7 @@
 import android.test.UiThreadTest;
 import android.view.ViewGroup;
 import android.widget.*;
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 import static android.view.View.LAYOUT_DIRECTION_LTR;
 import static android.view.View.LAYOUT_DIRECTION_RTL;
diff --git a/tests/tests/widget/src/android/widget/cts/LinearLayoutCtsActivity.java b/tests/tests/widget/src/android/widget/cts/LinearLayoutCtsActivity.java
index 0cb5bc0..4a04b52 100644
--- a/tests/tests/widget/src/android/widget/cts/LinearLayoutCtsActivity.java
+++ b/tests/tests/widget/src/android/widget/cts/LinearLayoutCtsActivity.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 import android.app.Activity;
 import android.os.Bundle;
diff --git a/tests/tests/widget/src/android/widget/cts/LinearLayoutTest.java b/tests/tests/widget/src/android/widget/cts/LinearLayoutTest.java
index 5815f9a..4d0903a 100644
--- a/tests/tests/widget/src/android/widget/cts/LinearLayoutTest.java
+++ b/tests/tests/widget/src/android/widget/cts/LinearLayoutTest.java
@@ -20,18 +20,24 @@
 
 import android.app.Activity;
 import android.content.Context;
+import android.graphics.Color;
 import android.test.ActivityInstrumentationTestCase;
 import android.test.ViewAsserts;
 import android.util.AttributeSet;
 import android.util.Xml;
+import android.view.View;
+import android.view.View.MeasureSpec;
 import android.view.ViewGroup;
-import android.widget.LinearLayout.LayoutParams;
+import android.view.ViewTreeObserver;
 import android.widget.AbsoluteLayout;
 import android.widget.LinearLayout;
+import android.widget.LinearLayout.LayoutParams;
 import android.widget.ListView;
 import android.widget.TextView;
+import android.widget.cts.R;
 
-import com.android.cts.widget.R;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 
 /**
  * Test {@link LinearLayout}.
@@ -41,7 +47,7 @@
     private Activity mActivity;
 
     public LinearLayoutTest() {
-        super("com.android.cts.widget", LinearLayoutCtsActivity.class);
+        super("android.widget.cts", LinearLayoutCtsActivity.class);
     }
 
     @Override
@@ -171,6 +177,54 @@
         assertEquals(Math.ceil(parentWidth * 0.3), weight03.getWidth(), 1.0);
     }
 
+    public void testWeightDistribution() {
+        LinearLayout layout = new LinearLayout(mActivity);
+        for (int i = 0; i < 3; i++) {
+            layout.addView(new View(mActivity), new LayoutParams(0, 0, 1));
+        }
+
+        int size = 100;
+        int spec = MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY);
+
+        for (int i = 0; i < 3; i++) {
+            View child = layout.getChildAt(i);
+            LayoutParams lp = (LayoutParams) child.getLayoutParams();
+            lp.height = 0;
+            lp.width = LayoutParams.MATCH_PARENT;
+            child.setLayoutParams(lp);
+        }
+        layout.setOrientation(LinearLayout.VERTICAL);
+        layout.measure(spec, spec);
+        layout.layout(0, 0, size, size);
+        assertEquals(100, layout.getWidth());
+        assertEquals(100, layout.getChildAt(0).getWidth());
+        assertEquals(100, layout.getChildAt(1).getWidth());
+        assertEquals(100, layout.getChildAt(2).getWidth());
+        assertEquals(100, layout.getHeight());
+        assertEquals(33, layout.getChildAt(0).getHeight());
+        assertEquals(33, layout.getChildAt(1).getHeight());
+        assertEquals(34, layout.getChildAt(2).getHeight());
+
+        for (int i = 0; i < 3; i++) {
+            View child = layout.getChildAt(i);
+            LayoutParams lp = (LayoutParams) child.getLayoutParams();
+            lp.height = LayoutParams.MATCH_PARENT;
+            lp.width = 0;
+            child.setLayoutParams(lp);
+        }
+        layout.setOrientation(LinearLayout.HORIZONTAL);
+        layout.measure(spec, spec);
+        layout.layout(0, 0, size, size);
+        assertEquals(100, layout.getWidth());
+        assertEquals(33, layout.getChildAt(0).getWidth());
+        assertEquals(33, layout.getChildAt(1).getWidth());
+        assertEquals(34, layout.getChildAt(2).getWidth());
+        assertEquals(100, layout.getHeight());
+        assertEquals(100, layout.getChildAt(0).getHeight());
+        assertEquals(100, layout.getChildAt(1).getHeight());
+        assertEquals(100, layout.getChildAt(2).getHeight());
+    }
+
     public void testGenerateLayoutParams() {
         ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(320, 240);
         MockLinearLayout mockLinearLayout = new MockLinearLayout(mContext);
@@ -218,6 +272,24 @@
         assertNull(mockLinearLayout.generateDefaultLayoutParams());
     }
 
+    public void testGenerateLayoutParamsFromMarginParams() {
+        MockLinearLayout layout = new MockLinearLayout(mContext);
+        ViewGroup.MarginLayoutParams lp = new ViewGroup.MarginLayoutParams(3, 5);
+        lp.leftMargin = 1;
+        lp.topMargin = 2;
+        lp.rightMargin = 3;
+        lp.bottomMargin = 4;
+        LinearLayout.LayoutParams generated = layout.generateLayoutParams(lp);
+        assertNotNull(generated);
+        assertEquals(3, generated.width);
+        assertEquals(5, generated.height);
+
+        assertEquals(1, generated.leftMargin);
+        assertEquals(2, generated.topMargin);
+        assertEquals(3, generated.rightMargin);
+        assertEquals(4, generated.bottomMargin);
+    }
+
     /**
      * layout of horizontal LinearLayout.
      * ----------------------------------------------------
@@ -327,6 +399,78 @@
         assertEquals(parent.getWidth(), rightView.getRight());
     }
 
+    private void checkBounds(final ViewGroup viewGroup, final View view,
+            final CountDownLatch countDownLatch, final int left, final int top,
+            final int width, final int height) {
+        viewGroup.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
+            @Override
+            public boolean onPreDraw() {
+                assertEquals(left, view.getLeft());
+                assertEquals(top, view.getTop());
+                assertEquals(width, view.getWidth());
+                assertEquals(height, view.getHeight());
+                countDownLatch.countDown();
+                viewGroup.getViewTreeObserver().removeOnPreDrawListener(this);
+                return true;
+            }
+        });
+    }
+
+    public void testVisibilityAffectsLayout() throws Throwable {
+        // Toggling view visibility between GONE/VISIBLE can affect the position of
+        // other children in that container. This test verifies that these changes
+        // on the first child of a LinearLayout affects the position of a second child
+        final int childWidth = 100;
+        final int childHeight = 200;
+        final LinearLayout parent = new LinearLayout(mActivity);
+        ViewGroup.LayoutParams parentParams = new ViewGroup.LayoutParams(
+                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
+        parent.setLayoutParams(parentParams);
+        final View child1 = new View(mActivity);
+        child1.setBackgroundColor(Color.GREEN);
+        ViewGroup.LayoutParams childParams = new ViewGroup.LayoutParams(childWidth, childHeight);
+        child1.setLayoutParams(childParams);
+        final View child2 = new View(mActivity);
+        child2.setBackgroundColor(Color.RED);
+        childParams = new ViewGroup.LayoutParams(childWidth, childHeight);
+        child2.setLayoutParams(childParams);
+        final ViewGroup viewGroup = (ViewGroup) mActivity.findViewById(R.id.linearlayout_root);
+
+        final CountDownLatch countDownLatch1 = new CountDownLatch(1);
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                viewGroup.removeAllViews();
+                viewGroup.addView(parent);
+                parent.addView(child1);
+                parent.addView(child2);
+                checkBounds(viewGroup, child1, countDownLatch1, 0, 0, childWidth, childHeight);
+                checkBounds(viewGroup, child2, countDownLatch1,
+                        childWidth, 0, childWidth, childHeight);
+            }
+        });
+        countDownLatch1.await(500, TimeUnit.MILLISECONDS);
+
+        final CountDownLatch countDownLatch2 = new CountDownLatch(1);
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                child1.setVisibility(View.GONE);
+                checkBounds(viewGroup, child2, countDownLatch2, 0, 0, childWidth, childHeight);
+            }
+        });
+        countDownLatch2.await(500, TimeUnit.MILLISECONDS);
+
+        final CountDownLatch countDownLatch3 = new CountDownLatch(2);
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                child1.setVisibility(View.VISIBLE);
+                checkBounds(viewGroup, child1, countDownLatch3, 0, 0, childWidth, childHeight);
+                checkBounds(viewGroup, child2, countDownLatch3,
+                        childWidth, 0, childWidth, childHeight);
+            }
+        });
+        countDownLatch3.await(500, TimeUnit.MILLISECONDS);
+    }
+
     private class MockListView extends ListView {
         private final static int DEFAULT_CHILD_BASE_LINE = 1;
 
diff --git a/tests/tests/widget/src/android/widget/cts/LinearLayout_LayoutParamsTest.java b/tests/tests/widget/src/android/widget/cts/LinearLayout_LayoutParamsTest.java
index 31be765..4f36e94 100644
--- a/tests/tests/widget/src/android/widget/cts/LinearLayout_LayoutParamsTest.java
+++ b/tests/tests/widget/src/android/widget/cts/LinearLayout_LayoutParamsTest.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 import org.xmlpull.v1.XmlPullParserException;
 
diff --git a/tests/tests/widget/src/android/widget/cts/ListPopupWindowCtsActivity.java b/tests/tests/widget/src/android/widget/cts/ListPopupWindowCtsActivity.java
new file mode 100755
index 0000000..69d7400
--- /dev/null
+++ b/tests/tests/widget/src/android/widget/cts/ListPopupWindowCtsActivity.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.widget.cts;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.PopupWindow;
+import android.widget.cts.R;
+
+/**
+ * Stub activity for testing {@link PopupWindow}
+ */
+public class ListPopupWindowCtsActivity extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.list_popup_window);
+    }
+}
+
diff --git a/tests/tests/widget/src/android/widget/cts/ListPopupWindowTest.java b/tests/tests/widget/src/android/widget/cts/ListPopupWindowTest.java
index c4636fc..ea0861f 100644
--- a/tests/tests/widget/src/android/widget/cts/ListPopupWindowTest.java
+++ b/tests/tests/widget/src/android/widget/cts/ListPopupWindowTest.java
@@ -16,47 +16,84 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
-
 import android.app.Activity;
 import android.app.Instrumentation;
 import android.content.Context;
+import android.graphics.Rect;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
+import android.os.SystemClock;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.InstrumentationRegistry;
 import android.test.ActivityInstrumentationTestCase2;
-import android.test.UiThreadTest;
+import android.test.suitebuilder.annotation.SmallTest;
 import android.view.Display;
+import android.view.Gravity;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
 import android.view.View;
+import android.view.ViewGroup;
 import android.view.WindowManager;
+import android.widget.AdapterView;
+import android.widget.BaseAdapter;
+import android.widget.ListAdapter;
 import android.widget.ListPopupWindow;
+import android.widget.ListView;
 import android.widget.PopupWindow;
-import android.widget.PopupWindow.OnDismissListener;
+import android.widget.TextView;
+import android.widget.cts.util.ViewTestUtils;
 
+import static org.mockito.Mockito.*;
+
+@SmallTest
 public class ListPopupWindowTest extends
-        ActivityInstrumentationTestCase2<MockPopupWindowCtsActivity> {
+        ActivityInstrumentationTestCase2<ListPopupWindowCtsActivity> {
     private Instrumentation mInstrumentation;
     private Activity mActivity;
 
+    private Builder mPopupWindowBuilder;
+
     /** The list popup window. */
     private ListPopupWindow mPopupWindow;
 
+    private AdapterView.OnItemClickListener mItemClickListener;
+
+    /**
+     * Item click listener that dismisses our <code>ListPopupWindow</code> when any item
+     * is clicked. Note that this needs to be a separate class that is also protected (not
+     * private) so that Mockito can "spy" on it.
+     */
+    protected class PopupItemClickListener implements AdapterView.OnItemClickListener {
+        @Override
+        public void onItemClick(AdapterView<?> parent, View view, int position,
+                long id) {
+            mPopupWindow.dismiss();
+        }
+    }
+
     /**
      * Instantiates a new popup window test.
      */
     public ListPopupWindowTest() {
-        super(MockPopupWindowCtsActivity.class);
+        super(ListPopupWindowCtsActivity.class);
     }
 
-    /*
-     * (non-Javadoc)
-     *
-     * @see android.test.ActivityInstrumentationTestCase#setUp()
-     */
     @Override
     protected void setUp() throws Exception {
         super.setUp();
         mInstrumentation = getInstrumentation();
         mActivity = getActivity();
+        mItemClickListener = new PopupItemClickListener();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        if ((mPopupWindowBuilder != null) && (mPopupWindow != null)) {
+            mPopupWindowBuilder.dismiss();
+        }
+
+        super.tearDown();
     }
 
     public void testConstructor() {
@@ -69,8 +106,14 @@
         new ListPopupWindow(mActivity, null, 0, android.R.style.Widget_Material_ListPopupWindow);
     }
 
-    public void testAccessBackground() {
+    public void testNoDefaultVisibility() {
         mPopupWindow = new ListPopupWindow(mActivity);
+        assertFalse(mPopupWindow.isShowing());
+    }
+
+    public void testAccessBackground() {
+        mPopupWindowBuilder = new Builder();
+        mPopupWindowBuilder.show();
 
         Drawable drawable = new ColorDrawable();
         mPopupWindow.setBackgroundDrawable(drawable);
@@ -81,7 +124,8 @@
     }
 
     public void testAccessAnimationStyle() {
-        mPopupWindow = new ListPopupWindow(mActivity);
+        mPopupWindowBuilder = new Builder();
+        mPopupWindowBuilder.show();
         assertEquals(0, mPopupWindow.getAnimationStyle());
 
         mPopupWindow.setAnimationStyle(android.R.style.Animation_Toast);
@@ -93,7 +137,9 @@
     }
 
     public void testAccessHeight() {
-        mPopupWindow = new ListPopupWindow(mActivity);
+        mPopupWindowBuilder = new Builder();
+        mPopupWindowBuilder.show();
+
         assertEquals(WindowManager.LayoutParams.WRAP_CONTENT, mPopupWindow.getHeight());
 
         int height = getDisplay().getHeight() / 2;
@@ -127,7 +173,9 @@
     }
 
     public void testAccessWidth() {
-        mPopupWindow = new ListPopupWindow(mActivity);
+        mPopupWindowBuilder = new Builder().ignoreContentWidth();
+        mPopupWindowBuilder.show();
+
         assertEquals(WindowManager.LayoutParams.WRAP_CONTENT, mPopupWindow.getWidth());
 
         int width = getDisplay().getWidth() / 2;
@@ -150,174 +198,813 @@
         assertEquals(width, mPopupWindow.getWidth());
     }
 
-    public void testShow() {
-        int[] anchorXY = new int[2];
-        int[] viewOnScreenXY = new int[2];
-        int[] viewInWindowXY = new int[2];
-
-        mPopupWindow = new ListPopupWindow(mActivity);
-
+    private void verifyAnchoring(int horizontalOffset, int verticalOffset, int gravity) {
         final View upperAnchor = mActivity.findViewById(R.id.anchor_upper);
-        mPopupWindow.setAnchorView(upperAnchor);
-
-        mInstrumentation.runOnMainSync(new Runnable() {
-            public void run() {
-                mPopupWindow.show();
-            }
-        });
-        mInstrumentation.waitForIdleSync();
+        final ListView listView = mPopupWindow.getListView();
+        int[] anchorXY = new int[2];
+        int[] listViewOnScreenXY = new int[2];
+        int[] listViewInWindowXY = new int[2];
 
         assertTrue(mPopupWindow.isShowing());
+        assertEquals(upperAnchor, mPopupWindow.getAnchorView());
 
-        mPopupWindow.getListView().getLocationOnScreen(viewOnScreenXY);
+        listView.getLocationOnScreen(listViewOnScreenXY);
         upperAnchor.getLocationOnScreen(anchorXY);
-        mPopupWindow.getListView().getLocationInWindow(viewInWindowXY);
-        assertEquals(anchorXY[0] + viewInWindowXY[0], viewOnScreenXY[0]);
-        assertEquals(anchorXY[1] + viewInWindowXY[1] + upperAnchor.getHeight(), viewOnScreenXY[1]);
+        listView.getLocationInWindow(listViewInWindowXY);
 
-        dismissPopup();
+        int expectedListViewOnScreenX = anchorXY[0] + listViewInWindowXY[0] + horizontalOffset;
+        final int absoluteGravity =
+                Gravity.getAbsoluteGravity(gravity, upperAnchor.getLayoutDirection());
+        if (absoluteGravity == Gravity.RIGHT) {
+            expectedListViewOnScreenX -= (listView.getWidth() - upperAnchor.getWidth());
+        }
+        int expectedListViewOnScreenY = anchorXY[1] + listViewInWindowXY[1]
+                + upperAnchor.getHeight() + verticalOffset;
+        assertEquals(expectedListViewOnScreenX, listViewOnScreenXY[0]);
+        assertEquals(expectedListViewOnScreenY, listViewOnScreenXY[1]);
+    }
+
+    public void testAnchoring() {
+        mPopupWindowBuilder = new Builder();
+        mPopupWindowBuilder.show();
+
+        assertEquals(0, mPopupWindow.getHorizontalOffset());
+        assertEquals(0, mPopupWindow.getVerticalOffset());
+
+        verifyAnchoring(0, 0, Gravity.NO_GRAVITY);
+    }
+
+    public void testAnchoringWithHorizontalOffset() {
+        mPopupWindowBuilder = new Builder().withHorizontalOffset(50);
+        mPopupWindowBuilder.show();
+
+        assertEquals(50, mPopupWindow.getHorizontalOffset());
+        assertEquals(0, mPopupWindow.getVerticalOffset());
+
+        verifyAnchoring(50, 0, Gravity.NO_GRAVITY);
+    }
+
+    public void testAnchoringWithVerticalOffset() {
+        mPopupWindowBuilder = new Builder().withVerticalOffset(60);
+        mPopupWindowBuilder.show();
+
+        assertEquals(0, mPopupWindow.getHorizontalOffset());
+        assertEquals(60, mPopupWindow.getVerticalOffset());
+
+        verifyAnchoring(0, 60, Gravity.NO_GRAVITY);
+    }
+
+    public void testAnchoringWithRightGravity() {
+        mPopupWindowBuilder = new Builder().withDropDownGravity(Gravity.RIGHT);
+        mPopupWindowBuilder.show();
+
+        assertEquals(0, mPopupWindow.getHorizontalOffset());
+        assertEquals(0, mPopupWindow.getVerticalOffset());
+
+        verifyAnchoring(0, 0, Gravity.RIGHT);
+    }
+
+    public void testAnchoringWithEndGravity() {
+        mPopupWindowBuilder = new Builder().withDropDownGravity(Gravity.END);
+        mPopupWindowBuilder.show();
+
+        assertEquals(0, mPopupWindow.getHorizontalOffset());
+        assertEquals(0, mPopupWindow.getVerticalOffset());
+
+        verifyAnchoring(0, 0, Gravity.END);
     }
 
     public void testSetWindowLayoutType() {
-        mPopupWindow = new ListPopupWindow(mActivity);
-
-        final View upperAnchor = mActivity.findViewById(R.id.anchor_upper);
-        mPopupWindow.setAnchorView(upperAnchor);
-        mPopupWindow.setWindowLayoutType(
+        mPopupWindowBuilder = new Builder().withWindowLayoutType(
                 WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL);
-
-        mInstrumentation.runOnMainSync(new Runnable() {
-            public void run() {
-                mPopupWindow.show();
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-
+        mPopupWindowBuilder.show();
         assertTrue(mPopupWindow.isShowing());
 
         WindowManager.LayoutParams p = (WindowManager.LayoutParams)
                 mPopupWindow.getListView().getRootView().getLayoutParams();
         assertEquals(WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL, p.type);
-
-        dismissPopup();
     }
 
-    @UiThreadTest
     public void testDismiss() {
-        mPopupWindow = new ListPopupWindow(mActivity);
-        assertFalse(mPopupWindow.isShowing());
-        View anchorView = mActivity.findViewById(R.id.anchor_upper);
-        mPopupWindow.setAnchorView(anchorView);
-        mPopupWindow.show();
+        mPopupWindowBuilder = new Builder();
+        mPopupWindowBuilder.show();
+        assertTrue(mPopupWindow.isShowing());
 
-        mPopupWindow.dismiss();
+        mPopupWindowBuilder.dismiss();
         assertFalse(mPopupWindow.isShowing());
 
-        mPopupWindow.dismiss();
+        mPopupWindowBuilder.dismiss();
         assertFalse(mPopupWindow.isShowing());
     }
 
     public void testSetOnDismissListener() {
-        mPopupWindow = new ListPopupWindow(mActivity);
-        mPopupWindow.setOnDismissListener(null);
+        mPopupWindowBuilder = new Builder().withDismissListener();
+        mPopupWindowBuilder.show();
+        mPopupWindowBuilder.dismiss();
+        verify(mPopupWindowBuilder.mOnDismissListener, times(1)).onDismiss();
 
-        MockOnDismissListener onDismissListener = new MockOnDismissListener();
-        mPopupWindow.setOnDismissListener(onDismissListener);
-        showPopup();
-        dismissPopup();
-        assertEquals(1, onDismissListener.getOnDismissCalledCount());
-
-        showPopup();
-        dismissPopup();
-        assertEquals(2, onDismissListener.getOnDismissCalledCount());
+        mPopupWindowBuilder.showAgain();
+        mPopupWindowBuilder.dismiss();
+        verify(mPopupWindowBuilder.mOnDismissListener, times(2)).onDismiss();
 
         mPopupWindow.setOnDismissListener(null);
-        showPopup();
-        dismissPopup();
-        assertEquals(2, onDismissListener.getOnDismissCalledCount());
+        mPopupWindowBuilder.showAgain();
+        mPopupWindowBuilder.dismiss();
+        // Since we've reset the listener to null, we are not expecting any more interactions
+        // on the previously registered listener.
+        verifyNoMoreInteractions(mPopupWindowBuilder.mOnDismissListener);
     }
 
     public void testAccessInputMethodMode() {
-        mPopupWindow = new ListPopupWindow(mActivity);
+        mPopupWindowBuilder = new Builder().withDismissListener();
+        mPopupWindowBuilder.show();
+
         assertEquals(PopupWindow.INPUT_METHOD_NEEDED, mPopupWindow.getInputMethodMode());
+        assertFalse(mPopupWindow.isInputMethodNotNeeded());
 
         mPopupWindow.setInputMethodMode(PopupWindow.INPUT_METHOD_FROM_FOCUSABLE);
         assertEquals(PopupWindow.INPUT_METHOD_FROM_FOCUSABLE, mPopupWindow.getInputMethodMode());
+        assertFalse(mPopupWindow.isInputMethodNotNeeded());
 
         mPopupWindow.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED);
         assertEquals(PopupWindow.INPUT_METHOD_NEEDED, mPopupWindow.getInputMethodMode());
+        assertFalse(mPopupWindow.isInputMethodNotNeeded());
 
         mPopupWindow.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED);
         assertEquals(PopupWindow.INPUT_METHOD_NOT_NEEDED, mPopupWindow.getInputMethodMode());
+        assertTrue(mPopupWindow.isInputMethodNotNeeded());
 
         mPopupWindow.setInputMethodMode(-1);
         assertEquals(-1, mPopupWindow.getInputMethodMode());
+        assertFalse(mPopupWindow.isInputMethodNotNeeded());
+    }
+
+    public void testAccessSoftInputMethodMode() {
+        mPopupWindowBuilder = new Builder().withDismissListener();
+        mPopupWindowBuilder.show();
+
+        mPopupWindow = new ListPopupWindow(mActivity);
+        assertEquals(WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED,
+                mPopupWindow.getSoftInputMode());
+
+        mPopupWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
+        assertEquals(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE,
+                mPopupWindow.getSoftInputMode());
+
+        mPopupWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
+        assertEquals(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE,
+                mPopupWindow.getSoftInputMode());
+    }
+
+    private void verifyDismissalViaTouch(boolean setupAsModal) throws Throwable {
+        // Register a click listener on the top-level container
+        final View mainContainer = mActivity.findViewById(R.id.main_container);
+        View.OnClickListener mockContainerClickListener = mock(View.OnClickListener.class);
+        mainContainer.setOnClickListener(mockContainerClickListener);
+
+        // Configure a list popup window with requested modality
+        mPopupWindowBuilder = new Builder().setModal(setupAsModal).withDismissListener();
+        mPopupWindowBuilder.show();
+
+        assertTrue("Popup window showing", mPopupWindow.isShowing());
+        // Make sure that the modality of the popup window is set up correctly
+        assertEquals("Popup window modality", setupAsModal, mPopupWindow.isModal());
+
+        // Determine the location of the popup on the screen so that we can emulate
+        // a tap outside of its bounds to dismiss it
+        final int[] popupOnScreenXY = new int[2];
+        final Rect rect = new Rect();
+        mPopupWindow.getListView().getLocationOnScreen(popupOnScreenXY);
+        mPopupWindow.getBackground().getPadding(rect);
+
+        int emulatedTapX = popupOnScreenXY[0] - rect.left - 20;
+        int emulatedTapY = popupOnScreenXY[1] + mPopupWindow.getListView().getHeight() +
+                rect.top + rect.bottom + 20;
+
+        // The logic below uses Instrumentation to emulate a tap outside the bounds of the
+        // displayed list popup window. This tap is then treated by the framework to be "split" as
+        // the ACTION_OUTSIDE for the popup itself, as well as DOWN / MOVE / UP for the underlying
+        // view root if the popup is not modal.
+        // It is not correct to emulate these two sequences separately in the test, as it
+        // wouldn't emulate the user-facing interaction for this test. Note that usage
+        // of Instrumentation is necessary here since Espresso's actions operate at the level
+        // of view or data. Also, we don't want to use View.dispatchTouchEvent directly as
+        // that would require emulation of two separate sequences as well.
+
+        Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
+
+        // Inject DOWN event
+        long downTime = SystemClock.uptimeMillis();
+        MotionEvent eventDown = MotionEvent.obtain(
+                downTime, downTime, MotionEvent.ACTION_DOWN, emulatedTapX, emulatedTapY, 1);
+        instrumentation.sendPointerSync(eventDown);
+
+        // Inject MOVE event
+        long moveTime = SystemClock.uptimeMillis();
+        MotionEvent eventMove = MotionEvent.obtain(
+                moveTime, moveTime, MotionEvent.ACTION_MOVE, emulatedTapX, emulatedTapY, 1);
+        instrumentation.sendPointerSync(eventMove);
+
+        // Inject UP event
+        long upTime = SystemClock.uptimeMillis();
+        MotionEvent eventUp = MotionEvent.obtain(
+                upTime, upTime, MotionEvent.ACTION_UP, emulatedTapX, emulatedTapY, 1);
+        instrumentation.sendPointerSync(eventUp);
+
+        // Wait for the system to process all events in the queue
+        instrumentation.waitForIdleSync();
+
+        // At this point our popup should not be showing and should have notified its
+        // dismiss listener
+        verify(mPopupWindowBuilder.mOnDismissListener, times(1)).onDismiss();
+        assertFalse("Popup window not showing after outside click", mPopupWindow.isShowing());
+
+        // Also test that the click outside the popup bounds has been "delivered" to the main
+        // container only if the popup is not modal
+        verify(mockContainerClickListener, times(setupAsModal ? 0 : 1)).onClick(mainContainer);
+    }
+
+    public void testDismissalOutsideNonModal() throws Throwable {
+        verifyDismissalViaTouch(false);
+    }
+
+    public void testDismissalOutsideModal() throws Throwable {
+        verifyDismissalViaTouch(true);
+    }
+
+    public void testItemClicks() throws Throwable {
+        mPopupWindowBuilder = new Builder().withItemClickListener().withDismissListener();
+        mPopupWindowBuilder.show();
+
+        runTestOnUiThread(() -> mPopupWindow.performItemClick(2));
+        mInstrumentation.waitForIdleSync();
+
+        verify(mPopupWindowBuilder.mOnItemClickListener, times(1)).onItemClick(
+                any(AdapterView.class), any(View.class), eq(2), eq(2L));
+        // Also verify that the popup window has been dismissed
+        assertFalse(mPopupWindow.isShowing());
+        verify(mPopupWindowBuilder.mOnDismissListener, times(1)).onDismiss();
+
+        mPopupWindowBuilder.showAgain();
+        runTestOnUiThread(() -> mPopupWindow.getListView().performItemClick(null, 1, 1));
+        mInstrumentation.waitForIdleSync();
+
+        verify(mPopupWindowBuilder.mOnItemClickListener, times(1)).onItemClick(
+                any(AdapterView.class), any(View.class), eq(1), eq(1L));
+        // Also verify that the popup window has been dismissed
+        assertFalse(mPopupWindow.isShowing());
+        verify(mPopupWindowBuilder.mOnDismissListener, times(2)).onDismiss();
+
+        // Finally verify that our item click listener has only been called twice
+        verifyNoMoreInteractions(mPopupWindowBuilder.mOnItemClickListener);
+    }
+
+    public void testPromptViewAbove() throws Throwable {
+        final View promptView = LayoutInflater.from(mActivity).inflate(
+                R.layout.popupwindow_prompt, null);
+        mPopupWindowBuilder = new Builder().withPrompt(
+                promptView, ListPopupWindow.POSITION_PROMPT_ABOVE);
+        mPopupWindowBuilder.show();
+
+        // Verify that our prompt is displayed on the screen and is above the first list item
+        assertTrue(promptView.isAttachedToWindow());
+        assertTrue(promptView.isShown());
+        assertEquals(ListPopupWindow.POSITION_PROMPT_ABOVE, mPopupWindow.getPromptPosition());
+
+        final int[] promptViewOnScreenXY = new int[2];
+        promptView.getLocationOnScreen(promptViewOnScreenXY);
+
+        final ListView listView = mPopupWindow.getListView();
+        final View firstListChild = listView.getChildAt(0);
+        final int[] firstChildOnScreenXY = new int[2];
+        firstListChild.getLocationOnScreen(firstChildOnScreenXY);
+
+        assertTrue(promptViewOnScreenXY[1] + promptView.getHeight() <= firstChildOnScreenXY[1]);
+    }
+
+    public void testPromptViewBelow() throws Throwable {
+        final View promptView = LayoutInflater.from(mActivity).inflate(
+                R.layout.popupwindow_prompt, null);
+        mPopupWindowBuilder = new Builder().withPrompt(
+                promptView, ListPopupWindow.POSITION_PROMPT_BELOW);
+        mPopupWindowBuilder.show();
+
+        // Verify that our prompt is displayed on the screen and is below the last list item
+        assertTrue(promptView.isAttachedToWindow());
+        assertTrue(promptView.isShown());
+        assertEquals(ListPopupWindow.POSITION_PROMPT_BELOW, mPopupWindow.getPromptPosition());
+
+        final int[] promptViewOnScreenXY = new int[2];
+        promptView.getLocationOnScreen(promptViewOnScreenXY);
+
+        final ListView listView = mPopupWindow.getListView();
+        final View lastListChild = listView.getChildAt(listView.getChildCount() - 1);
+        final int[] lastChildOnScreenXY = new int[2];
+        lastListChild.getLocationOnScreen(lastChildOnScreenXY);
+
+        assertTrue(lastChildOnScreenXY[1] + lastListChild.getHeight() <= promptViewOnScreenXY[1]);
+    }
+
+    @Presubmit
+    public void testAccessSelection() throws Throwable {
+        mPopupWindowBuilder = new Builder().withItemSelectedListener();
+        mPopupWindowBuilder.show();
+
+        final ListView listView = mPopupWindow.getListView();
+
+        // Select an item
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, listView,
+                () -> mPopupWindow.setSelection(1));
+
+        // And verify the current selection state + selection listener invocation
+        verify(mPopupWindowBuilder.mOnItemSelectedListener, times(1)).onItemSelected(
+                any(AdapterView.class), any(View.class), eq(1), eq(1L));
+        assertEquals(1, mPopupWindow.getSelectedItemId());
+        assertEquals(1, mPopupWindow.getSelectedItemPosition());
+        assertEquals("Bob", mPopupWindow.getSelectedItem());
+        View selectedView = mPopupWindow.getSelectedView();
+        assertNotNull(selectedView);
+        assertEquals("Bob",
+                ((TextView) selectedView.findViewById(android.R.id.text1)).getText());
+
+        // Select another item
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, listView,
+                () -> mPopupWindow.setSelection(3));
+
+        // And verify the new selection state + selection listener invocation
+        verify(mPopupWindowBuilder.mOnItemSelectedListener, times(1)).onItemSelected(
+                any(AdapterView.class), any(View.class), eq(3), eq(3L));
+        assertEquals(3, mPopupWindow.getSelectedItemId());
+        assertEquals(3, mPopupWindow.getSelectedItemPosition());
+        assertEquals("Deirdre", mPopupWindow.getSelectedItem());
+        selectedView = mPopupWindow.getSelectedView();
+        assertNotNull(selectedView);
+        assertEquals("Deirdre",
+                ((TextView) selectedView.findViewById(android.R.id.text1)).getText());
+
+        // Clear selection
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, listView,
+                () -> mPopupWindow.clearListSelection());
+
+        // And verify empty selection state + no more selection listener invocation
+        verify(mPopupWindowBuilder.mOnItemSelectedListener, times(1)).onNothingSelected(
+                any(AdapterView.class));
+        assertEquals(AdapterView.INVALID_ROW_ID, mPopupWindow.getSelectedItemId());
+        assertEquals(AdapterView.INVALID_POSITION, mPopupWindow.getSelectedItemPosition());
+        assertEquals(null, mPopupWindow.getSelectedItem());
+        assertEquals(null, mPopupWindow.getSelectedView());
+        verifyNoMoreInteractions(mPopupWindowBuilder.mOnItemSelectedListener);
+    }
+
+    public void testNoDefaultDismissalWithBackButton() throws Throwable {
+        mPopupWindowBuilder = new Builder().withDismissListener();
+        mPopupWindowBuilder.show();
+
+        // Send BACK key event. As we don't have any custom code that dismisses ListPopupWindow,
+        // and ListPopupWindow doesn't track that system-level key event on its own, ListPopupWindow
+        // should stay visible
+        mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_BACK);
+        verify(mPopupWindowBuilder.mOnDismissListener, never()).onDismiss();
+        assertTrue(mPopupWindow.isShowing());
+    }
+
+    public void testCustomDismissalWithBackButton() throws Throwable {
+        mPopupWindowBuilder = new Builder().withAnchor(R.id.anchor_upper_left)
+                .withDismissListener();
+        mPopupWindowBuilder.show();
+
+        // "Point" our custom extension of EditText to our ListPopupWindow
+        final MockViewForListPopupWindow anchor =
+                (MockViewForListPopupWindow) mPopupWindow.getAnchorView();
+        anchor.wireTo(mPopupWindow);
+        // Request focus on our EditText
+        runTestOnUiThread(() -> anchor.requestFocus());
+        mInstrumentation.waitForIdleSync();
+        assertTrue(anchor.isFocused());
+
+        // Send BACK key event. As our custom extension of EditText calls
+        // ListPopupWindow.onKeyPreIme, the end result should be the dismissal of the
+        // ListPopupWindow
+        mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_BACK);
+        verify(mPopupWindowBuilder.mOnDismissListener, times(1)).onDismiss();
+        assertFalse(mPopupWindow.isShowing());
+    }
+
+    public void testListSelectionWithDPad() throws Throwable {
+        mPopupWindowBuilder = new Builder().withAnchor(R.id.anchor_upper_left)
+                .withDismissListener().withItemSelectedListener();
+        mPopupWindowBuilder.show();
+
+        // "Point" our custom extension of EditText to our ListPopupWindow
+        final MockViewForListPopupWindow anchor =
+                (MockViewForListPopupWindow) mPopupWindow.getAnchorView();
+        anchor.wireTo(mPopupWindow);
+        // Request focus on our EditText
+        runTestOnUiThread(() -> anchor.requestFocus());
+        mInstrumentation.waitForIdleSync();
+        assertTrue(anchor.isFocused());
+
+        // Select entry #1 in the popup list
+        final ListView listView = mPopupWindow.getListView();
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, listView,
+                () -> mPopupWindow.setSelection(1));
+        verify(mPopupWindowBuilder.mOnItemSelectedListener, times(1)).onItemSelected(
+                any(AdapterView.class), any(View.class), eq(1), eq(1L));
+
+        // Send DPAD_DOWN key event. As our custom extension of EditText calls
+        // ListPopupWindow.onKeyDown and onKeyUp, the end result should be transfer of selection
+        // down one row
+        mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_DOWN);
+        mInstrumentation.waitForIdleSync();
+
+        // At this point we expect that item #2 was selected
+        verify(mPopupWindowBuilder.mOnItemSelectedListener, times(1)).onItemSelected(
+                any(AdapterView.class), any(View.class), eq(2), eq(2L));
+
+        // Send a DPAD_UP key event. As our custom extension of EditText calls
+        // ListPopupWindow.onKeyDown and onKeyUp, the end result should be transfer of selection
+        // up one row
+        mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_UP);
+        mInstrumentation.waitForIdleSync();
+
+        // At this point we expect that item #1 was selected
+        verify(mPopupWindowBuilder.mOnItemSelectedListener, times(2)).onItemSelected(
+                any(AdapterView.class), any(View.class), eq(1), eq(1L));
+
+        // Send one more DPAD_UP key event. As our custom extension of EditText calls
+        // ListPopupWindow.onKeyDown and onKeyUp, the end result should be transfer of selection
+        // up one more row
+        mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_UP);
+        mInstrumentation.waitForIdleSync();
+
+        // At this point we expect that item #0 was selected
+        verify(mPopupWindowBuilder.mOnItemSelectedListener, times(1)).onItemSelected(
+                any(AdapterView.class), any(View.class), eq(0), eq(0L));
+
+        // Send ENTER key event. As our custom extension of EditText calls
+        // ListPopupWindow.onKeyDown and onKeyUp, the end result should be dismissal of
+        // the popup window
+        mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_ENTER);
+        mInstrumentation.waitForIdleSync();
+
+        verify(mPopupWindowBuilder.mOnDismissListener, times(1)).onDismiss();
+        assertFalse(mPopupWindow.isShowing());
+
+        verifyNoMoreInteractions(mPopupWindowBuilder.mOnItemSelectedListener);
+        verifyNoMoreInteractions(mPopupWindowBuilder.mOnDismissListener);
     }
 
     /**
-     * The listener interface for receiving OnDismiss events. The class that is
-     * interested in processing a OnDismiss event implements this interface, and
-     * the object created with that class is registered with a component using
-     * the component's <code>setOnDismissListener<code> method. When
-     * the OnDismiss event occurs, that object's appropriate
-     * method is invoked.
+     * Emulates a drag-down gestures by injecting ACTION events with {@link Instrumentation}.
      */
-    private static class MockOnDismissListener implements OnDismissListener {
+    private void emulateDragDownGesture(int emulatedX, int emulatedStartY, int swipeAmount) {
+        // The logic below uses Instrumentation to emulate a swipe / drag gesture to bring up
+        // the popup content.
 
-        /** The Ondismiss called count. */
-        private int mOnDismissCalledCount;
+        // Inject DOWN event
+        long downTime = SystemClock.uptimeMillis();
+        MotionEvent eventDown = MotionEvent.obtain(
+                downTime, downTime, MotionEvent.ACTION_DOWN, emulatedX, emulatedStartY, 1);
+        mInstrumentation.sendPointerSync(eventDown);
 
-        /**
-         * Gets the onDismiss() called count.
-         *
-         * @return the on dismiss called count
-         */
-        public int getOnDismissCalledCount() {
-            return mOnDismissCalledCount;
+        // Inject a sequence of MOVE events that emulate a "swipe down" gesture
+        for (int i = 0; i < 10; i++) {
+            long moveTime = SystemClock.uptimeMillis();
+            final int moveY = emulatedStartY + swipeAmount * i / 10;
+            MotionEvent eventMove = MotionEvent.obtain(
+                    moveTime, moveTime, MotionEvent.ACTION_MOVE, emulatedX, moveY, 1);
+            mInstrumentation.sendPointerSync(eventMove);
+            // sleep for a bit to emulate a 200ms swipe
+            SystemClock.sleep(20);
         }
 
-        /*
-         * (non-Javadoc)
-         *
-         * @see android.widget.PopupWindow.OnDismissListener#onDismiss()
-         */
-        public void onDismiss() {
-            mOnDismissCalledCount++;
-        }
+        // Inject UP event
+        long upTime = SystemClock.uptimeMillis();
+        MotionEvent eventUp = MotionEvent.obtain(
+                upTime, upTime, MotionEvent.ACTION_UP, emulatedX, emulatedStartY + swipeAmount, 1);
+        mInstrumentation.sendPointerSync(eventUp);
 
+        // Wait for the system to process all events in the queue
+        mInstrumentation.waitForIdleSync();
+    }
+
+    public void testCreateOnDragListener() throws Throwable {
+        // In this test we want precise control over the height of the popup content since
+        // we need to know by how much to swipe down to end the emulated gesture over the
+        // specific item in the popup. This is why we're using a popup style that removes
+        // all decoration around the popup content, as well as our own row layout with known
+        // height.
+        mPopupWindowBuilder = new Builder()
+                .withPopupStyleAttr(R.style.PopupEmptyStyle)
+                .withContentRowLayoutId(R.layout.popup_window_item)
+                .withItemClickListener().withDismissListener();
+
+        // Configure ListPopupWindow without showing it
+        mPopupWindowBuilder.configure();
+
+        // Get the anchor view and configure it with ListPopupWindow's drag-to-open listener
+        final View anchor = mActivity.findViewById(mPopupWindowBuilder.mAnchorId);
+        View.OnTouchListener dragListener = mPopupWindow.createDragToOpenListener(anchor);
+        anchor.setOnTouchListener(dragListener);
+        // And also configure it to show the popup window on click
+        anchor.setOnClickListener((View view) -> mPopupWindow.show());
+
+        // Get the height of a row item in our popup window
+        final int popupRowHeight = mActivity.getResources().getDimensionPixelSize(
+                R.dimen.popup_row_height);
+
+        final int[] anchorOnScreenXY = new int[2];
+        anchor.getLocationOnScreen(anchorOnScreenXY);
+
+        // Compute the start coordinates of a downward swipe and the amount of swipe. We'll
+        // be swiping by twice the row height. That, combined with the swipe originating in the
+        // center of the anchor should result in clicking the second row in the popup.
+        int emulatedX = anchorOnScreenXY[0] + anchor.getWidth() / 2;
+        int emulatedStartY = anchorOnScreenXY[1] + anchor.getHeight() / 2;
+        int swipeAmount = 2 * popupRowHeight;
+
+        // Emulate drag-down gesture with a sequence of motion events
+        emulateDragDownGesture(emulatedX, emulatedStartY, swipeAmount);
+
+        // We expect the swipe / drag gesture to result in clicking the second item in our list.
+        verify(mPopupWindowBuilder.mOnItemClickListener, times(1)).onItemClick(
+                any(AdapterView.class), any(View.class), eq(1), eq(1L));
+        // Since our item click listener calls dismiss() on the popup, we expect the popup to not
+        // be showing
+        assertFalse(mPopupWindow.isShowing());
+        // At this point our popup should have notified its dismiss listener
+        verify(mPopupWindowBuilder.mOnDismissListener, times(1)).onDismiss();
     }
 
     /**
-     * Show PopupWindow.
+     * Inner helper class to configure an instance of <code>ListPopupWindow</code> for the
+     * specific test. The main reason for its existence is that once a popup window is shown
+     * with the show() method, most of its configuration APIs are no-ops. This means that
+     * we can't add logic that is specific to a certain test (such as dismissing a non-modal
+     * popup window) once it's shown and we have a reference to a displayed ListPopupWindow.
      */
-    // FIXME: logcat info complains that there is window leakage due to that mPopupWindow is not
-    // clean up. Need to fix it.
-    private void showPopup() {
-        mInstrumentation.runOnMainSync(new Runnable() {
-            public void run() {
-                if (mPopupWindow == null || mPopupWindow.isShowing()) {
-                    return;
+    public class Builder {
+        private boolean mIsModal;
+        private boolean mHasDismissListener;
+        private boolean mHasItemClickListener;
+        private boolean mHasItemSelectedListener;
+        private boolean mIgnoreContentWidth;
+        private int mHorizontalOffset;
+        private int mVerticalOffset;
+        private int mDropDownGravity;
+        private int mAnchorId = R.id.anchor_upper;
+        private int mContentRowLayoutId = android.R.layout.simple_list_item_1;
+
+        private boolean mHasWindowLayoutType;
+        private int mWindowLayoutType;
+
+        private boolean mUseCustomPopupStyle;
+        private int mPopupStyleAttr;
+
+        private View mPromptView;
+        private int mPromptPosition;
+
+        private AdapterView.OnItemClickListener mOnItemClickListener;
+        private AdapterView.OnItemSelectedListener mOnItemSelectedListener;
+        private PopupWindow.OnDismissListener mOnDismissListener;
+
+        public Builder() {
+        }
+
+        public Builder withAnchor(int anchorId) {
+            mAnchorId = anchorId;
+            return this;
+        }
+
+        public Builder withContentRowLayoutId(int contentRowLayoutId) {
+            mContentRowLayoutId = contentRowLayoutId;
+            return this;
+        }
+
+        public Builder withPopupStyleAttr(int popupStyleAttr) {
+            mUseCustomPopupStyle = true;
+            mPopupStyleAttr = popupStyleAttr;
+            return this;
+        }
+
+        public Builder ignoreContentWidth() {
+            mIgnoreContentWidth = true;
+            return this;
+        }
+
+        public Builder setModal(boolean isModal) {
+            mIsModal = isModal;
+            return this;
+        }
+
+        public Builder withItemClickListener() {
+            mHasItemClickListener = true;
+            return this;
+        }
+
+        public Builder withItemSelectedListener() {
+            mHasItemSelectedListener = true;
+            return this;
+        }
+
+        public Builder withDismissListener() {
+            mHasDismissListener = true;
+            return this;
+        }
+
+        public Builder withWindowLayoutType(int windowLayoutType) {
+            mHasWindowLayoutType = true;
+            mWindowLayoutType = windowLayoutType;
+            return this;
+        }
+
+        public Builder withHorizontalOffset(int horizontalOffset) {
+            mHorizontalOffset = horizontalOffset;
+            return this;
+        }
+
+        public Builder withVerticalOffset(int verticalOffset) {
+            mVerticalOffset = verticalOffset;
+            return this;
+        }
+
+        public Builder withDropDownGravity(int dropDownGravity) {
+            mDropDownGravity = dropDownGravity;
+            return this;
+        }
+
+        public Builder withPrompt(View promptView, int promptPosition) {
+            mPromptView = promptView;
+            mPromptPosition = promptPosition;
+            return this;
+        }
+
+        private int getContentWidth(ListAdapter listAdapter, Drawable background) {
+            if (listAdapter == null) {
+                return 0;
+            }
+
+            int width = 0;
+            View itemView = null;
+            int itemType = 0;
+
+            for (int i = 0; i < listAdapter.getCount(); i++) {
+                final int positionType = listAdapter.getItemViewType(i);
+                if (positionType != itemType) {
+                    itemType = positionType;
+                    itemView = null;
                 }
-                View anchor = mActivity.findViewById(R.id.anchor_upper);
-                mPopupWindow.setAnchorView(anchor);
-                mPopupWindow.show();
-                assertTrue(mPopupWindow.isShowing());
+                itemView = listAdapter.getView(i, itemView, null);
+                if (itemView.getLayoutParams() == null) {
+                    itemView.setLayoutParams(new ViewGroup.LayoutParams(
+                            ViewGroup.LayoutParams.WRAP_CONTENT,
+                            ViewGroup.LayoutParams.WRAP_CONTENT));
+                }
+                itemView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
+                width = Math.max(width, itemView.getMeasuredWidth());
             }
-        });
-        mInstrumentation.waitForIdleSync();
-    }
 
-    /**
-     * Dismiss PopupWindow.
-     */
-    private void dismissPopup() {
-        mInstrumentation.runOnMainSync(new Runnable() {
-            public void run() {
-                if (mPopupWindow == null || !mPopupWindow.isShowing())
-                    return;
-                mPopupWindow.dismiss();
+            // Add background padding to measured width
+            if (background != null) {
+                final Rect rect = new Rect();
+                background.getPadding(rect);
+                width += rect.left + rect.right;
             }
-        });
-        mInstrumentation.waitForIdleSync();
+
+            return width;
+        }
+
+        private void configure() {
+            if (mUseCustomPopupStyle) {
+                mPopupWindow = new ListPopupWindow(mActivity, null, mPopupStyleAttr, 0);
+            } else {
+                mPopupWindow = new ListPopupWindow(mActivity);
+            }
+            final String[] POPUP_CONTENT =
+                    new String[]{"Alice", "Bob", "Charlie", "Deirdre", "El"};
+            final BaseAdapter listPopupAdapter = new BaseAdapter() {
+                class ViewHolder {
+                    private TextView title;
+                }
+
+                @Override
+                public int getCount() {
+                    return POPUP_CONTENT.length;
+                }
+
+                @Override
+                public Object getItem(int position) {
+                    return POPUP_CONTENT[position];
+                }
+
+                @Override
+                public long getItemId(int position) {
+                    return position;
+                }
+
+                @Override
+                public View getView(int position, View convertView, ViewGroup parent) {
+                    if (convertView == null) {
+                        convertView = LayoutInflater.from(mActivity).inflate(
+                                mContentRowLayoutId, parent, false);
+                        ViewHolder viewHolder = new ViewHolder();
+                        viewHolder.title = (TextView) convertView.findViewById(android.R.id.text1);
+                        convertView.setTag(viewHolder);
+                    }
+
+                    ViewHolder viewHolder = (ViewHolder) convertView.getTag();
+                    viewHolder.title.setText(POPUP_CONTENT[position]);
+                    return convertView;
+                }
+            };
+
+            mPopupWindow.setAdapter(listPopupAdapter);
+            mPopupWindow.setAnchorView(mActivity.findViewById(mAnchorId));
+
+            // The following mock listeners have to be set before the call to show() as
+            // they are set on the internally constructed drop down.
+            if (mHasItemClickListener) {
+                // Wrap our item click listener with a Mockito spy
+                mOnItemClickListener = spy(mItemClickListener);
+                // Register that spy as the item click listener on the ListPopupWindow
+                mPopupWindow.setOnItemClickListener(mOnItemClickListener);
+                // And configure Mockito to call our original listener with onItemClick.
+                // This way we can have both our item click listener running to dismiss the popup
+                // window, and track the invocations of onItemClick with Mockito APIs.
+                doCallRealMethod().when(mOnItemClickListener).onItemClick(
+                        any(AdapterView.class), any(View.class), any(int.class), any(int.class));
+            }
+
+            if (mHasItemSelectedListener) {
+                mOnItemSelectedListener = mock(AdapterView.OnItemSelectedListener.class);
+                mPopupWindow.setOnItemSelectedListener(mOnItemSelectedListener);
+                mPopupWindow.setListSelector(mActivity.getDrawable(R.drawable.red_fill));
+            }
+
+            if (mHasDismissListener) {
+                mOnDismissListener = mock(PopupWindow.OnDismissListener.class);
+                mPopupWindow.setOnDismissListener(mOnDismissListener);
+            }
+
+            mPopupWindow.setModal(mIsModal);
+            if (mHasWindowLayoutType) {
+                mPopupWindow.setWindowLayoutType(mWindowLayoutType);
+            }
+
+            if (!mIgnoreContentWidth) {
+                mPopupWindow.setContentWidth(
+                        getContentWidth(listPopupAdapter, mPopupWindow.getBackground()));
+            }
+
+            if (mHorizontalOffset != 0) {
+                mPopupWindow.setHorizontalOffset(mHorizontalOffset);
+            }
+
+            if (mVerticalOffset != 0) {
+                mPopupWindow.setVerticalOffset(mVerticalOffset);
+            }
+
+            if (mDropDownGravity != Gravity.NO_GRAVITY) {
+                mPopupWindow.setDropDownGravity(mDropDownGravity);
+            }
+
+            if (mPromptView != null) {
+                mPopupWindow.setPromptPosition(mPromptPosition);
+                mPopupWindow.setPromptView(mPromptView);
+            }
+        }
+
+        private void show() {
+            configure();
+
+            mInstrumentation.runOnMainSync(
+                    () -> {
+                        mPopupWindow.show();
+                        assertTrue(mPopupWindow.isShowing());
+                    });
+            mInstrumentation.waitForIdleSync();
+        }
+
+        private void showAgain() {
+            mInstrumentation.runOnMainSync(
+                    () -> {
+                        if (mPopupWindow == null || mPopupWindow.isShowing()) {
+                            return;
+                        }
+                        mPopupWindow.show();
+                        assertTrue(mPopupWindow.isShowing());
+                    });
+            mInstrumentation.waitForIdleSync();
+        }
+
+        private void dismiss() {
+            mInstrumentation.runOnMainSync(
+                    () -> {
+                        if (mPopupWindow == null || !mPopupWindow.isShowing())
+                            return;
+                        mPopupWindow.dismiss();
+                    });
+            mInstrumentation.waitForIdleSync();
+        }
     }
 }
diff --git a/tests/tests/widget/src/android/widget/cts/ListViewCtsActivity.java b/tests/tests/widget/src/android/widget/cts/ListViewCtsActivity.java
index 186e47b..ce198b3 100644
--- a/tests/tests/widget/src/android/widget/cts/ListViewCtsActivity.java
+++ b/tests/tests/widget/src/android/widget/cts/ListViewCtsActivity.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 import android.app.Activity;
 import android.os.Bundle;
diff --git a/tests/tests/widget/src/android/widget/cts/ListViewTest.java b/tests/tests/widget/src/android/widget/cts/ListViewTest.java
index 838f7a8..3ee9ead 100644
--- a/tests/tests/widget/src/android/widget/cts/ListViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/ListViewTest.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 import org.xmlpull.v1.XmlPullParser;
 
@@ -37,13 +37,14 @@
 import android.view.KeyEvent;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.ViewTreeObserver.OnDrawListener;
 import android.view.animation.LayoutAnimationController;
-import android.widget.AbsListView;
 import android.widget.AdapterView;
 import android.widget.AdapterView.OnItemClickListener;
 import android.widget.ArrayAdapter;
 import android.widget.ListView;
 import android.widget.TextView;
+import android.widget.cts.util.ViewTestUtils;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -51,6 +52,8 @@
 
 import junit.framework.Assert;
 
+import static org.mockito.Mockito.*;
+
 public class ListViewTest extends ActivityInstrumentationTestCase2<ListViewCtsActivity> {
     private final String[] mCountryList = new String[] {
         "Argentina", "Australia", "China", "France", "Germany", "Italy", "Japan", "United States"
@@ -69,7 +72,7 @@
     private ArrayAdapter<String> mAdapter_empty;
 
     public ListViewTest() {
-        super("com.android.cts.widget", ListViewCtsActivity.class);
+        super("android.widget.cts", ListViewCtsActivity.class);
     }
 
     protected void setUp() throws Exception {
@@ -128,21 +131,13 @@
     }
 
     private void setAdapter(final ArrayAdapter<String> adapter) {
-        mInstrumentation.runOnMainSync(new Runnable() {
-            public void run() {
-                mListView.setAdapter(adapter);
-            }
-        });
-        mInstrumentation.waitForIdleSync();
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView,
+                () -> mListView.setAdapter(adapter));
     }
 
     public void testAccessDividerHeight() {
-        mInstrumentation.runOnMainSync(new Runnable() {
-            public void run() {
-                mListView.setAdapter(mAdapter_countries);
-            }
-        });
-        mInstrumentation.waitForIdleSync();
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView,
+                () -> mListView.setAdapter(mAdapter_countries));
 
         Drawable d = mListView.getDivider();
         final Rect r = d.getBounds();
@@ -153,21 +148,15 @@
             }
         }.run();
 
-        mInstrumentation.runOnMainSync(new Runnable() {
-            public void run() {
-                mListView.setDividerHeight(20);
-            }
-        });
-        mInstrumentation.waitForIdleSync();
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView,
+                () -> mListView.setDividerHeight(20));
+
         assertEquals(20, mListView.getDividerHeight());
         assertEquals(20, r.bottom - r.top);
 
-        mInstrumentation.runOnMainSync(new Runnable() {
-            public void run() {
-                mListView.setDividerHeight(10);
-            }
-        });
-        mInstrumentation.waitForIdleSync();
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView,
+                () -> mListView.setDividerHeight(10));
+
         assertEquals(10, mListView.getDividerHeight());
         assertEquals(10, r.bottom - r.top);
     }
@@ -183,22 +172,14 @@
     }
 
     public void testAccessAdapter() {
-        mInstrumentation.runOnMainSync(new Runnable() {
-            public void run() {
-                mListView.setAdapter(mAdapter_countries);
-            }
-        });
-        mInstrumentation.waitForIdleSync();
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView,
+                () -> mListView.setAdapter(mAdapter_countries));
 
         assertSame(mAdapter_countries, mListView.getAdapter());
         assertEquals(mCountryList.length, mListView.getCount());
 
-        mInstrumentation.runOnMainSync(new Runnable() {
-            public void run() {
-                mListView.setAdapter(mAdapter_names);
-            }
-        });
-        mInstrumentation.waitForIdleSync();
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView,
+                () -> mListView.setAdapter(mAdapter_names));
 
         assertSame(mAdapter_names, mListView.getAdapter());
         assertEquals(mNameList.length, mListView.getCount());
@@ -283,52 +264,26 @@
         final TextView footerView2 = new TextView(mActivity);
         footerView2.setText("footerview2");
 
-        mInstrumentation.runOnMainSync(new Runnable() {
-            public void run() {
-                mListView.setFooterDividersEnabled(true);
-            }
-        });
-        mInstrumentation.waitForIdleSync();
+        mInstrumentation.runOnMainSync(() -> mListView.setFooterDividersEnabled(true));
         assertEquals(0, mListView.getFooterViewsCount());
 
-        mInstrumentation.runOnMainSync(new Runnable() {
-            public void run() {
-                mListView.addFooterView(footerView1, null, true);
-            }
-        });
-        mInstrumentation.waitForIdleSync();
+        mInstrumentation.runOnMainSync(() -> mListView.addFooterView(footerView1, null, true));
         assertEquals(1, mListView.getFooterViewsCount());
 
-        mInstrumentation.runOnMainSync(new Runnable() {
-            public void run() {
-                mListView.addFooterView(footerView2);
-            }
-        });
+        mInstrumentation.runOnMainSync(() -> mListView.addFooterView(footerView2));
 
         mInstrumentation.waitForIdleSync();
         assertEquals(2, mListView.getFooterViewsCount());
 
-        mInstrumentation.runOnMainSync(new Runnable() {
-            public void run() {
-                mListView.setAdapter(mAdapter_countries);
-            }
-        });
-        mInstrumentation.waitForIdleSync();
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView,
+                () -> mListView.setAdapter(mAdapter_countries));
 
-        mInstrumentation.runOnMainSync(new Runnable() {
-            public void run() {
-                mListView.removeFooterView(footerView1);
-            }
-        });
-        mInstrumentation.waitForIdleSync();
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView,
+                () -> mListView.removeFooterView(footerView1));
         assertEquals(1, mListView.getFooterViewsCount());
 
-        mInstrumentation.runOnMainSync(new Runnable() {
-            public void run() {
-                mListView.removeFooterView(footerView2);
-            }
-        });
-        mInstrumentation.waitForIdleSync();
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView,
+                () -> mListView.removeFooterView(footerView2));
         assertEquals(0, mListView.getFooterViewsCount());
     }
 
@@ -336,28 +291,13 @@
         final TextView headerView1 = (TextView) mActivity.findViewById(R.id.headerview1);
         final TextView headerView2 = (TextView) mActivity.findViewById(R.id.headerview2);
 
-        mInstrumentation.runOnMainSync(new Runnable() {
-            public void run() {
-                mListView.setHeaderDividersEnabled(true);
-            }
-        });
-        mInstrumentation.waitForIdleSync();
+        mInstrumentation.runOnMainSync(() -> mListView.setHeaderDividersEnabled(true));
         assertEquals(0, mListView.getHeaderViewsCount());
 
-        mInstrumentation.runOnMainSync(new Runnable() {
-            public void run() {
-                mListView.addHeaderView(headerView2, null, true);
-            }
-        });
-        mInstrumentation.waitForIdleSync();
+        mInstrumentation.runOnMainSync(() -> mListView.addHeaderView(headerView2, null, true));
         assertEquals(1, mListView.getHeaderViewsCount());
 
-        mInstrumentation.runOnMainSync(new Runnable() {
-            public void run() {
-                mListView.addHeaderView(headerView1);
-            }
-        });
-        mInstrumentation.waitForIdleSync();
+        mInstrumentation.runOnMainSync(() -> mListView.addHeaderView(headerView1));
         assertEquals(2, mListView.getHeaderViewsCount());
     }
 
@@ -389,32 +329,18 @@
                 return super.getCount() + 1;
             }
         };
-        runTestOnUiThread(new Runnable() {
-            @Override
-            public void run() {
-                mListView.setAdapter(adapter);
-            }
-        });
-        getInstrumentation().waitForIdleSync();
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView,
+                () -> mListView.setAdapter(adapter));
 
-        runTestOnUiThread(new Runnable() {
-            @Override
-            public void run() {
-                adapter.notifyDataSetChanged();
-            }
-        });
-        getInstrumentation().waitForIdleSync();
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView,
+                () -> adapter.notifyDataSetChanged());
 
         assertEquals(0, mismatch.size());
     }
 
     public void testAccessDivider() {
-        mInstrumentation.runOnMainSync(new Runnable() {
-            public void run() {
-                mListView.setAdapter(mAdapter_countries);
-            }
-        });
-        mInstrumentation.waitForIdleSync();
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView,
+                () -> mListView.setAdapter(mAdapter_countries));
 
         Drawable defaultDrawable = mListView.getDivider();
         final Rect r = defaultDrawable.getBounds();
@@ -427,57 +353,33 @@
 
         final Drawable d = mActivity.getResources().getDrawable(R.drawable.scenery);
 
-        mInstrumentation.runOnMainSync(new Runnable() {
-            public void run() {
-                mListView.setDivider(d);
-            }
-        });
-        mInstrumentation.waitForIdleSync();
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView,
+                () -> mListView.setDivider(d));
         assertSame(d, mListView.getDivider());
         assertEquals(d.getBounds().height(), mListView.getDividerHeight());
 
-        mInstrumentation.runOnMainSync(new Runnable() {
-            public void run() {
-                mListView.setDividerHeight(10);
-            }
-        });
-        mInstrumentation.waitForIdleSync();
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView,
+                () -> mListView.setDividerHeight(10));
         assertEquals(10, mListView.getDividerHeight());
         assertEquals(10, d.getBounds().height());
     }
 
     public void testSetSelection() {
-        mInstrumentation.runOnMainSync(new Runnable() {
-            public void run() {
-                mListView.setAdapter(mAdapter_countries);
-            }
-        });
-        mInstrumentation.waitForIdleSync();
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView,
+                () -> mListView.setAdapter(mAdapter_countries));
 
-        mInstrumentation.runOnMainSync(new Runnable() {
-            public void run() {
-                mListView.setSelection(1);
-            }
-        });
-        mInstrumentation.waitForIdleSync();
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView,
+                () -> mListView.setSelection(1));
         String item = (String) mListView.getSelectedItem();
         assertEquals(mCountryList[1], item);
 
-        mInstrumentation.runOnMainSync(new Runnable() {
-            public void run() {
-                mListView.setSelectionFromTop(5, 0);
-            }
-        });
-        mInstrumentation.waitForIdleSync();
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView,
+                () -> mListView.setSelectionFromTop(5, 0));
         item = (String) mListView.getSelectedItem();
         assertEquals(mCountryList[5], item);
 
-        mInstrumentation.runOnMainSync(new Runnable() {
-            public void run() {
-                mListView.setSelectionAfterHeaderView();
-            }
-        });
-        mInstrumentation.waitForIdleSync();
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView,
+                () -> mListView.setSelectionAfterHeaderView());
         item = (String) mListView.getSelectedItem();
         assertEquals(mCountryList[0], item);
     }
@@ -487,20 +389,12 @@
     }
 
     public void testPerformItemClick() {
-        mInstrumentation.runOnMainSync(new Runnable() {
-            public void run() {
-                mListView.setAdapter(mAdapter_countries);
-            }
-        });
-        mInstrumentation.waitForIdleSync();
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView,
+                () -> mListView.setAdapter(mAdapter_countries));
 
         mListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
-        mInstrumentation.runOnMainSync(new Runnable() {
-            public void run() {
-                mListView.setSelection(2);
-            }
-        });
-        mInstrumentation.waitForIdleSync();
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView,
+                () -> mListView.setSelection(2));
 
         final TextView child = (TextView) mAdapter_countries.getView(2, null, mListView);
         assertNotNull(child);
@@ -508,30 +402,19 @@
         final long itemID = mAdapter_countries.getItemId(2);
         assertEquals(2, itemID);
 
-        mInstrumentation.runOnMainSync(new Runnable() {
-            public void run() {
-                mListView.performItemClick(child, 2, itemID);
-            }
-        });
+        mInstrumentation.runOnMainSync(() -> mListView.performItemClick(child, 2, itemID));
         mInstrumentation.waitForIdleSync();
 
-        MockOnItemClickListener onClickListener = new MockOnItemClickListener();
+        OnItemClickListener onClickListener = mock(OnItemClickListener.class);
         mListView.setOnItemClickListener(onClickListener);
+        verify(onClickListener, never()).onItemClick(any(AdapterView.class), any(View.class),
+                anyInt(), anyLong());
 
-        assertNull(onClickListener.getView());
-        assertEquals(0, onClickListener.getPosition());
-        assertEquals(0, onClickListener.getID());
-
-        mInstrumentation.runOnMainSync(new Runnable() {
-            public void run() {
-                mListView.performItemClick(child, 2, itemID);
-            }
-        });
+        mInstrumentation.runOnMainSync(() -> mListView.performItemClick(child, 2, itemID));
         mInstrumentation.waitForIdleSync();
 
-        assertSame(child, onClickListener.getView());
-        assertEquals(2, onClickListener.getPosition());
-        assertEquals(2, onClickListener.getID());
+        verify(onClickListener, times(1)).onItemClick(mListView, child, 2, 2L);
+        verifyNoMoreInteractions(onClickListener);
     }
 
     public void testSaveAndRestoreInstanceState() {
@@ -539,52 +422,39 @@
     }
 
     public void testDispatchKeyEvent() {
-        mInstrumentation.runOnMainSync(new Runnable() {
-            public void run() {
-                mListView.setAdapter(mAdapter_countries);
-                mListView.requestFocus();
-            }
-        });
-        mInstrumentation.waitForIdleSync();
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView,
+                () -> {
+                    mListView.setAdapter(mAdapter_countries);
+                    mListView.requestFocus();
+                });
         assertTrue(mListView.hasFocus());
 
-        mInstrumentation.runOnMainSync(new Runnable() {
-            public void run() {
-                mListView.setSelection(1);
-            }
-        });
-        mInstrumentation.waitForIdleSync();
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView,
+                () -> mListView.setSelection(1));
         String item = (String) mListView.getSelectedItem();
         assertEquals(mCountryList[1], item);
 
-        mInstrumentation.runOnMainSync(new Runnable() {
-            public void run() {
-                KeyEvent keyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_A);
-                mListView.dispatchKeyEvent(keyEvent);
-            }
-        });
-        mInstrumentation.waitForIdleSync();
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView,
+                () ->  {
+                    KeyEvent keyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_A);
+                    mListView.dispatchKeyEvent(keyEvent);
+                });
 
-        mInstrumentation.runOnMainSync(new Runnable() {
-            public void run() {
-                KeyEvent keyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_DOWN);
-                mListView.dispatchKeyEvent(keyEvent);
-                mListView.dispatchKeyEvent(keyEvent);
-                mListView.dispatchKeyEvent(keyEvent);
-            }
-        });
-        mInstrumentation.waitForIdleSync();
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView,
+                () -> {
+                    KeyEvent keyEvent = new KeyEvent(KeyEvent.ACTION_DOWN,
+                            KeyEvent.KEYCODE_DPAD_DOWN);
+                    mListView.dispatchKeyEvent(keyEvent);
+                    mListView.dispatchKeyEvent(keyEvent);
+                    mListView.dispatchKeyEvent(keyEvent);
+                });
         item = (String)mListView.getSelectedItem();
         assertEquals(mCountryList[4], item);
     }
 
     public void testRequestChildRectangleOnScreen() {
-        mInstrumentation.runOnMainSync(new Runnable() {
-            public void run() {
-                mListView.setAdapter(mAdapter_countries);
-            }
-        });
-        mInstrumentation.waitForIdleSync();
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView,
+                () -> mListView.setAdapter(mAdapter_countries));
 
         TextView child = (TextView) mAdapter_countries.getView(0, null, mListView);
         assertNotNull(child);
@@ -695,30 +565,6 @@
         }
     }
 
-    private static class MockOnItemClickListener implements OnItemClickListener {
-        private View mView;
-        private int mPosition;
-        private long mID;
-
-        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
-            mView = view;
-            mPosition = position;
-            mID = id;
-        }
-
-        public View getView() {
-            return mView;
-        }
-
-        public int getPosition() {
-            return mPosition;
-        }
-
-        public long getID() {
-            return mID;
-        }
-    }
-
     /**
      * The following functions are merged from frameworktest.
      */
@@ -803,27 +649,19 @@
         final ArrayAdapter<String> adapter = new ArrayAdapter<String>(mActivity,
                 android.R.layout.simple_list_item_1, items);
 
-        mInstrumentation.runOnMainSync(new Runnable() {
-            @Override
-            public void run() {
-                listView.setAdapter(adapter);
-            }
-        });
-        mInstrumentation.waitForIdleSync();
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, listView,
+                () -> listView.setAdapter(adapter));
 
         final View oldItem = listView.getChildAt(2);
         final CharSequence oldText = ((TextView) oldItem.findViewById(android.R.id.text1))
                 .getText();
         oldItem.setHasTransientState(true);
 
-        mInstrumentation.runOnMainSync(new Runnable() {
-            @Override
-            public void run() {
-                adapter.remove(adapter.getItem(0));
-                adapter.notifyDataSetChanged();
-            }
-        });
-        mInstrumentation.waitForIdleSync();
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, listView,
+                () -> {
+                    adapter.remove(adapter.getItem(0));
+                    adapter.notifyDataSetChanged();
+                });
 
         final View newItem = listView.getChildAt(2);
         final CharSequence newText = ((TextView) newItem.findViewById(android.R.id.text1))
@@ -838,13 +676,8 @@
         final StableArrayAdapter<String> adapter = new StableArrayAdapter<String>(mActivity,
                 android.R.layout.simple_list_item_1, items);
 
-        mInstrumentation.runOnMainSync(new Runnable() {
-            @Override
-            public void run() {
-                listView.setAdapter(adapter);
-            }
-        });
-        mInstrumentation.waitForIdleSync();
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView,
+                () -> listView.setAdapter(adapter));
 
         final Object tag = new Object();
         final View oldItem = listView.getChildAt(2);
@@ -853,14 +686,11 @@
         oldItem.setHasTransientState(true);
         oldItem.setTag(tag);
 
-        mInstrumentation.runOnMainSync(new Runnable() {
-            @Override
-            public void run() {
-                adapter.remove(adapter.getItem(0));
-                adapter.notifyDataSetChanged();
-            }
-        });
-        mInstrumentation.waitForIdleSync();
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, listView,
+                () -> {
+                    adapter.remove(adapter.getItem(0));
+                    adapter.notifyDataSetChanged();
+                });
 
         final View newItem = listView.getChildAt(1);
         final CharSequence newText = ((TextView) newItem.findViewById(android.R.id.text1))
diff --git a/tests/tests/widget/src/android/widget/cts/MediaControllerCtsActivity.java b/tests/tests/widget/src/android/widget/cts/MediaControllerCtsActivity.java
index 5dfcc59..ac8f100 100644
--- a/tests/tests/widget/src/android/widget/cts/MediaControllerCtsActivity.java
+++ b/tests/tests/widget/src/android/widget/cts/MediaControllerCtsActivity.java
@@ -20,7 +20,7 @@
 import android.os.Bundle;
 import android.widget.MediaController;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 /**
  * A minimal application for {@link MediaController} test.
diff --git a/tests/tests/widget/src/android/widget/cts/MediaControllerTest.java b/tests/tests/widget/src/android/widget/cts/MediaControllerTest.java
index 49bc767..2c60a91 100644
--- a/tests/tests/widget/src/android/widget/cts/MediaControllerTest.java
+++ b/tests/tests/widget/src/android/widget/cts/MediaControllerTest.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 
 import org.xmlpull.v1.XmlPullParser;
@@ -50,7 +50,7 @@
     private static final long DEFAULT_TIMEOUT = 3000;
 
     public MediaControllerTest() {
-        super("com.android.cts.widget", MediaControllerCtsActivity.class);
+        super("android.widget.cts", MediaControllerCtsActivity.class);
     }
 
     @Override
@@ -166,7 +166,7 @@
 
         try {
             source = mActivity.getResources().openRawResource(R.raw.testvideo);
-            target = mActivity.openFileOutput(VIDEO_NAME, Context.MODE_WORLD_READABLE);
+            target = mActivity.openFileOutput(VIDEO_NAME, Context.MODE_PRIVATE);
 
             final byte[] buffer = new byte[1024];
             for (int len = source.read(buffer); len > 0; len = source.read(buffer)) {
@@ -182,7 +182,7 @@
                 if (target != null) {
                     target.close();
                 }
-            } catch (final IOException _) {
+            } catch (final IOException ignored) {
                 // Ignore the IOException.
             }
         }
diff --git a/tests/tests/widget/src/android/widget/cts/MockPopupWindowCtsActivity.java b/tests/tests/widget/src/android/widget/cts/MockPopupWindowCtsActivity.java
deleted file mode 100755
index 9589fec..0000000
--- a/tests/tests/widget/src/android/widget/cts/MockPopupWindowCtsActivity.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.widget.cts;
-
-import com.android.cts.widget.R;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.widget.PopupWindow;
-import android.view.View;
-import android.view.View.OnApplyWindowInsetsListener;
-import android.view.Window;
-import android.view.WindowInsets;
-
-/**
- * Stub activity for testing {@link PopupWindow}
- */
-public class MockPopupWindowCtsActivity extends Activity {
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.popupwindow);
-    }
-}
-
diff --git a/tests/tests/widget/src/android/widget/cts/MockURLSpanTestActivity.java b/tests/tests/widget/src/android/widget/cts/MockURLSpanTestActivity.java
index ab4940c..3d27f9a 100644
--- a/tests/tests/widget/src/android/widget/cts/MockURLSpanTestActivity.java
+++ b/tests/tests/widget/src/android/widget/cts/MockURLSpanTestActivity.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 import android.app.Activity;
 import android.os.Bundle;
diff --git a/tests/tests/widget/src/android/widget/cts/MockViewForListPopupWindow.java b/tests/tests/widget/src/android/widget/cts/MockViewForListPopupWindow.java
new file mode 100644
index 0000000..dc6cfc6
--- /dev/null
+++ b/tests/tests/widget/src/android/widget/cts/MockViewForListPopupWindow.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.widget.cts;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.KeyEvent;
+import android.widget.EditText;
+import android.widget.ListPopupWindow;
+
+public class MockViewForListPopupWindow extends EditText {
+    private ListPopupWindow mListPopupWindow;
+
+    public MockViewForListPopupWindow(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public MockViewForListPopupWindow(Context context) {
+        super(context);
+    }
+
+    public void wireTo(ListPopupWindow listPopupWindow) {
+        mListPopupWindow = listPopupWindow;
+    }
+
+    @Override
+    public boolean onKeyPreIme(int keyCode, KeyEvent event) {
+        if (mListPopupWindow != null) {
+            return mListPopupWindow.onKeyPreIme(keyCode, event);
+        }
+        return super.onKeyPreIme(keyCode, event);
+    }
+
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        if (mListPopupWindow != null) {
+            return mListPopupWindow.onKeyDown(keyCode, event);
+        }
+        return super.onKeyDown(keyCode, event);
+    }
+
+    @Override
+    public boolean onKeyUp(int keyCode, KeyEvent event) {
+        if (mListPopupWindow != null) {
+            return mListPopupWindow.onKeyUp(keyCode, event);
+        }
+        return super.onKeyUp(keyCode, event);
+    }
+}
+
diff --git a/tests/tests/widget/src/android/widget/cts/MultiAutoCompleteTextViewCtsActivity.java b/tests/tests/widget/src/android/widget/cts/MultiAutoCompleteTextViewCtsActivity.java
index 1379150..b5de67b 100644
--- a/tests/tests/widget/src/android/widget/cts/MultiAutoCompleteTextViewCtsActivity.java
+++ b/tests/tests/widget/src/android/widget/cts/MultiAutoCompleteTextViewCtsActivity.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 import android.app.Activity;
 import android.os.Bundle;
diff --git a/tests/tests/widget/src/android/widget/cts/MultiAutoCompleteTextViewTest.java b/tests/tests/widget/src/android/widget/cts/MultiAutoCompleteTextViewTest.java
index 4afdb80..5c18030 100644
--- a/tests/tests/widget/src/android/widget/cts/MultiAutoCompleteTextViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/MultiAutoCompleteTextViewTest.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 
 import org.xmlpull.v1.XmlPullParser;
@@ -44,7 +44,7 @@
     private Activity mActivity;
 
     public MultiAutoCompleteTextViewTest() {
-        super("com.android.cts.widget", MultiAutoCompleteTextViewCtsActivity.class);
+        super("android.widget.cts", MultiAutoCompleteTextViewCtsActivity.class);
     }
 
     @Override
diff --git a/tests/tests/widget/src/android/widget/cts/MyHorizontalScrollView.java b/tests/tests/widget/src/android/widget/cts/MyHorizontalScrollView.java
index 639193a..a5a0150 100644
--- a/tests/tests/widget/src/android/widget/cts/MyHorizontalScrollView.java
+++ b/tests/tests/widget/src/android/widget/cts/MyHorizontalScrollView.java
@@ -67,4 +67,19 @@
         super.measureChildWithMargins(child, parentWidthMeasureSpec,
                 widthUsed, parentHeightMeasureSpec, heightUsed);
     }
+
+    @Override
+    public int computeVerticalScrollRange() {
+        return super.computeVerticalScrollRange();
+    }
+
+    @Override
+    public int computeVerticalScrollOffset() {
+        return super.computeVerticalScrollOffset();
+    }
+
+    @Override
+    public int computeVerticalScrollExtent() {
+        return super.computeVerticalScrollExtent();
+    }
 }
diff --git a/tests/tests/widget/src/android/widget/cts/PopupMenuCtsActivity.java b/tests/tests/widget/src/android/widget/cts/PopupMenuCtsActivity.java
new file mode 100755
index 0000000..a2c5391
--- /dev/null
+++ b/tests/tests/widget/src/android/widget/cts/PopupMenuCtsActivity.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.widget.cts;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.PopupWindow;
+import android.widget.cts.R;
+
+/**
+ * Stub activity for testing {@link PopupWindow}
+ */
+public class PopupMenuCtsActivity extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.popup_menu);
+    }
+}
+
diff --git a/tests/tests/widget/src/android/widget/cts/PopupMenuTest.java b/tests/tests/widget/src/android/widget/cts/PopupMenuTest.java
index 2dff4cb..ee38448 100644
--- a/tests/tests/widget/src/android/widget/cts/PopupMenuTest.java
+++ b/tests/tests/widget/src/android/widget/cts/PopupMenuTest.java
@@ -16,22 +16,34 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
-
 import android.app.Activity;
 import android.app.Instrumentation;
+import android.os.SystemClock;
 import android.test.ActivityInstrumentationTestCase2;
+import android.test.suitebuilder.annotation.SmallTest;
 import android.view.Gravity;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.MotionEvent;
+import android.view.SubMenu;
+import android.view.View;
+import android.widget.EditText;
 import android.widget.PopupMenu;
 
+import static org.mockito.Mockito.*;
 
+@SmallTest
 public class PopupMenuTest extends
-        ActivityInstrumentationTestCase2<MockPopupWindowCtsActivity> {
+        ActivityInstrumentationTestCase2<PopupMenuCtsActivity> {
     private Instrumentation mInstrumentation;
     private Activity mActivity;
 
+    private Builder mBuilder;
+    private PopupMenu mPopupMenu;
+
     public PopupMenuTest() {
-        super("com.android.cts.widget", MockPopupWindowCtsActivity.class);
+        super("android.widget.cts", PopupMenuCtsActivity.class);
     }
 
     @Override
@@ -39,57 +51,326 @@
         super.setUp();
         mInstrumentation = getInstrumentation();
         mActivity = getActivity();
+
+        try {
+            runTestOnUiThread(() -> {
+                // Disable and remove focusability on the first child of our activity so that
+                // it doesn't bring in the soft keyboard that can mess up with some of the tests
+                // (such as menu dismissal when we emulate a tap outside the menu bounds).
+                final EditText editText = (EditText) mActivity.findViewById(R.id.anchor_upper_left);
+                editText.setEnabled(false);
+                editText.setFocusable(false);
+            });
+        } catch (Throwable t) {
+            throw new RuntimeException(t);
+        }
     }
 
-    public void testAccessGravity() {
-        PopupMenu popupMenu = new PopupMenu(mActivity,
-                mActivity.findViewById(R.id.anchor_middle_left));
-        assertEquals(Gravity.NO_GRAVITY, popupMenu.getGravity());
-        popupMenu.setGravity(Gravity.TOP);
-        assertEquals(Gravity.TOP, popupMenu.getGravity());
+    @Override
+    protected void tearDown() throws Exception {
+        if (mPopupMenu != null) {
+            try {
+                runTestOnUiThread(() -> mPopupMenu.dismiss());
+            } catch (Throwable t) {
+                throw new RuntimeException(t);
+            }
+        }
+        super.tearDown();
     }
 
-    public void testOnDismissListener() {
-        final PopupMenu popupMenu = new PopupMenu(mActivity,
-                mActivity.findViewById(R.id.anchor_middle_left));
-        TestPopupDismissListener listener = new TestPopupDismissListener();
-        popupMenu.setOnDismissListener(listener);
+    private void verifyMenuContent() {
+        final Menu menu = mPopupMenu.getMenu();
+        assertEquals(6, menu.size());
+        assertEquals(R.id.action_highlight, menu.getItem(0).getItemId());
+        assertEquals(R.id.action_edit, menu.getItem(1).getItemId());
+        assertEquals(R.id.action_delete, menu.getItem(2).getItemId());
+        assertEquals(R.id.action_ignore, menu.getItem(3).getItemId());
+        assertEquals(R.id.action_share, menu.getItem(4).getItemId());
+        assertEquals(R.id.action_print, menu.getItem(5).getItemId());
 
-        mInstrumentation.runOnMainSync(new Runnable() {
-            public void run() {
-                popupMenu.show();
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-        assertEquals(0, listener.getDismissCount());
-
-        mInstrumentation.runOnMainSync(new Runnable() {
-            public void run() {
-                popupMenu.dismiss();
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-        assertEquals(1, listener.getDismissCount());
-
-        mInstrumentation.runOnMainSync(new Runnable() {
-            public void run() {
-                popupMenu.dismiss();
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-        assertEquals(1, listener.getDismissCount());
+        final SubMenu shareSubMenu = menu.getItem(4).getSubMenu();
+        assertNotNull(shareSubMenu);
+        assertEquals(2, shareSubMenu.size());
+        assertEquals(R.id.action_share_email, shareSubMenu.getItem(0).getItemId());
+        assertEquals(R.id.action_share_circles, shareSubMenu.getItem(1).getItemId());
     }
 
-    private class TestPopupDismissListener implements PopupMenu.OnDismissListener {
-        int mDismissCount;
+    public void testPopulateViaInflater() throws Throwable {
+        mBuilder = new Builder().inflateWithInflater(true);
+        runTestOnUiThread(() -> mBuilder.show());
+        mInstrumentation.waitForIdleSync();
 
-        @Override
-        public void onDismiss(PopupMenu menu) {
-            mDismissCount++;
+        verifyMenuContent();
+    }
+
+    public void testDirectPopulate() throws Throwable {
+        mBuilder = new Builder().inflateWithInflater(false);
+        runTestOnUiThread(() -> mBuilder.show());
+        mInstrumentation.waitForIdleSync();
+
+        verifyMenuContent();
+    }
+
+    public void testAccessGravity() throws Throwable {
+        mBuilder = new Builder();
+        runTestOnUiThread(() -> mBuilder.show());
+
+        assertEquals(Gravity.NO_GRAVITY, mPopupMenu.getGravity());
+        mPopupMenu.setGravity(Gravity.TOP);
+        assertEquals(Gravity.TOP, mPopupMenu.getGravity());
+    }
+
+    public void testConstructorWithGravity() throws Throwable {
+        mBuilder = new Builder().withGravity(Gravity.TOP);
+        runTestOnUiThread(() -> mBuilder.show());
+
+        assertEquals(Gravity.TOP, mPopupMenu.getGravity());
+    }
+
+    public void testDismissalViaAPI() throws Throwable {
+        mBuilder = new Builder().withDismissListener();
+        runTestOnUiThread(() -> mBuilder.show());
+
+        mInstrumentation.waitForIdleSync();
+        verify(mBuilder.mOnDismissListener, never()).onDismiss(mPopupMenu);
+
+        runTestOnUiThread(() -> mPopupMenu.dismiss());
+        mInstrumentation.waitForIdleSync();
+        verify(mBuilder.mOnDismissListener, times(1)).onDismiss(mPopupMenu);
+
+        runTestOnUiThread(() -> mPopupMenu.dismiss());
+        mInstrumentation.waitForIdleSync();
+        // Shouldn't have any more interactions with our dismiss listener since the menu was
+        // already dismissed when we called dismiss()
+        verifyNoMoreInteractions(mBuilder.mOnDismissListener);
+    }
+
+    public void testNestedDismissalViaAPI() throws Throwable {
+        // Use empty popup style to remove all transitions from the popup. That way we don't
+        // need to synchronize with the popup window enter transition before proceeding to
+        // "click" a submenu item.
+        mBuilder = new Builder().withDismissListener()
+                .withPopupStyleResource(R.style.PopupWindow_NullTransitions);
+        runTestOnUiThread(() -> mBuilder.show());
+        mInstrumentation.waitForIdleSync();
+        verify(mBuilder.mOnDismissListener, never()).onDismiss(mPopupMenu);
+
+        runTestOnUiThread(() -> mPopupMenu.getMenu().performIdentifierAction(R.id.action_share, 0));
+        mInstrumentation.waitForIdleSync();
+
+        runTestOnUiThread(() -> mPopupMenu.getMenu().findItem(R.id.action_share).getSubMenu().
+                        performIdentifierAction(R.id.action_share_email, 0));
+        mInstrumentation.waitForIdleSync();
+
+        runTestOnUiThread(() -> mPopupMenu.dismiss());
+        mInstrumentation.waitForIdleSync();
+        verify(mBuilder.mOnDismissListener, times(1)).onDismiss(mPopupMenu);
+
+        runTestOnUiThread(() -> mPopupMenu.dismiss());
+        mInstrumentation.waitForIdleSync();
+        // Shouldn't have any more interactions with our dismiss listener since the menu was
+        // already dismissed when we called dismiss()
+        verifyNoMoreInteractions(mBuilder.mOnDismissListener);
+    }
+
+    public void testDismissalViaTouch() throws Throwable {
+        // Use empty popup style to remove all transitions from the popup. That way we don't
+        // need to synchronize with the popup window enter transition before proceeding to
+        // emulate a click outside the popup window bounds.
+        mBuilder = new Builder().withDismissListener()
+                .withPopupMenuContent(R.menu.popup_menu_single)
+                .withPopupStyleResource(R.style.PopupWindow_NullTransitions);
+        runTestOnUiThread(() -> mBuilder.show());
+        mInstrumentation.waitForIdleSync();
+
+        // Determine the location of the anchor on the screen so that we can emulate
+        // a tap outside of the popup bounds to dismiss the popup
+        final int[] anchorOnScreenXY = new int[2];
+        mBuilder.mAnchor.getLocationOnScreen(anchorOnScreenXY);
+
+        int emulatedTapX = anchorOnScreenXY[0] + 10;
+        int emulatedTapY = anchorOnScreenXY[1] - 20;
+
+        // The logic below uses Instrumentation to emulate a tap outside the bounds of the
+        // displayed popup menu. This tap is then treated by the framework to be "split" as
+        // the ACTION_OUTSIDE for the popup itself, as well as DOWN / MOVE / UP for the underlying
+        // view root if the popup is not modal.
+        // It is not correct to emulate these two sequences separately in the test, as it
+        // wouldn't emulate the user-facing interaction for this test. Note that usage
+        // of Instrumentation is necessary here since Espresso's actions operate at the level
+        // of view or data. Also, we don't want to use View.dispatchTouchEvent directly as
+        // that would require emulation of two separate sequences as well.
+
+        // Inject DOWN event
+        long downTime = SystemClock.uptimeMillis();
+        MotionEvent eventDown = MotionEvent.obtain(
+                downTime, downTime, MotionEvent.ACTION_DOWN, emulatedTapX, emulatedTapY, 1);
+        mInstrumentation.sendPointerSync(eventDown);
+
+        // Inject MOVE event
+        long moveTime = SystemClock.uptimeMillis();
+        MotionEvent eventMove = MotionEvent.obtain(
+                moveTime, moveTime, MotionEvent.ACTION_MOVE, emulatedTapX, emulatedTapY, 1);
+        mInstrumentation.sendPointerSync(eventMove);
+
+        // Inject UP event
+        long upTime = SystemClock.uptimeMillis();
+        MotionEvent eventUp = MotionEvent.obtain(
+                upTime, upTime, MotionEvent.ACTION_UP, emulatedTapX, emulatedTapY, 1);
+        mInstrumentation.sendPointerSync(eventUp);
+
+        // Wait for the system to process all events in the queue
+        mInstrumentation.waitForIdleSync();
+
+        // At this point our popup should have notified its dismiss listener
+        verify(mBuilder.mOnDismissListener, times(1)).onDismiss(mPopupMenu);
+    }
+
+    public void testSimpleMenuItemClickViaAPI() throws Throwable {
+        mBuilder = new Builder().withMenuItemClickListener().withDismissListener();
+        runTestOnUiThread(() -> mBuilder.show());
+
+        // Verify that our menu item click listener hasn't been called yet
+        verify(mBuilder.mOnMenuItemClickListener, never()).onMenuItemClick(any(MenuItem.class));
+
+        runTestOnUiThread(
+                () -> mPopupMenu.getMenu().performIdentifierAction(R.id.action_highlight, 0));
+
+        // Verify that our menu item click listener has been called with the expected menu item
+        verify(mBuilder.mOnMenuItemClickListener, times(1)).onMenuItemClick(
+                mPopupMenu.getMenu().findItem(R.id.action_highlight));
+
+        // Popup menu should be automatically dismissed on selecting an item
+        verify(mBuilder.mOnDismissListener, times(1)).onDismiss(mPopupMenu);
+        verifyNoMoreInteractions(mBuilder.mOnDismissListener);
+    }
+
+    public void testSubMenuClickViaAPI() throws Throwable {
+        // Use empty popup style to remove all transitions from the popup. That way we don't
+        // need to synchronize with the popup window enter transition before proceeding to
+        // "click" a submenu item.
+        mBuilder = new Builder().withDismissListener().withMenuItemClickListener()
+                .withPopupStyleResource(R.style.PopupWindow_NullTransitions);
+        runTestOnUiThread(() -> mBuilder.show());
+        mInstrumentation.waitForIdleSync();
+
+        // Verify that our menu item click listener hasn't been called yet
+        verify(mBuilder.mOnMenuItemClickListener, never()).onMenuItemClick(any(MenuItem.class));
+
+        runTestOnUiThread(() -> mPopupMenu.getMenu().performIdentifierAction(R.id.action_share, 0));
+        // Verify that our menu item click listener has been called on "share" action
+        // and that the dismiss listener hasn't been called just as a result of opening the submenu.
+        verify(mBuilder.mOnMenuItemClickListener, times(1)).onMenuItemClick(
+                mPopupMenu.getMenu().findItem(R.id.action_share));
+        verify(mBuilder.mOnDismissListener, never()).onDismiss(mPopupMenu);
+
+        runTestOnUiThread(() -> mPopupMenu.getMenu().findItem(R.id.action_share).getSubMenu().
+                        performIdentifierAction(R.id.action_share_email, 0));
+
+        // Verify that out menu item click listener has been called with the expected menu item
+        verify(mBuilder.mOnMenuItemClickListener, times(1)).onMenuItemClick(
+                mPopupMenu.getMenu().findItem(R.id.action_share).getSubMenu()
+                        .findItem(R.id.action_share_email));
+        verifyNoMoreInteractions(mBuilder.mOnMenuItemClickListener);
+
+        // Popup menu should be automatically dismissed on selecting an item
+        verify(mBuilder.mOnDismissListener, times(1)).onDismiss(mPopupMenu);
+        verifyNoMoreInteractions(mBuilder.mOnDismissListener);
+    }
+
+    /**
+     * Inner helper class to configure an instance of {@link PopupMenu} for the specific test.
+     * The main reason for its existence is that once a popup menu is shown with the show() method,
+     * most of its configuration APIs are no-ops. This means that we can't add logic that is
+     * specific to a certain test once it's shown and we have a reference to a displayed
+     * {@link PopupMenu}.
+     */
+    public class Builder {
+        private boolean mHasDismissListener;
+        private boolean mHasMenuItemClickListener;
+        private boolean mInflateWithInflater;
+
+        private int mPopupMenuContent = R.menu.popup_menu;
+
+        private boolean mUseCustomPopupResource;
+        private int mPopupStyleResource = 0;
+
+        private boolean mUseCustomGravity;
+        private int mGravity = Gravity.NO_GRAVITY;
+
+        private PopupMenu.OnMenuItemClickListener mOnMenuItemClickListener;
+        private PopupMenu.OnDismissListener mOnDismissListener;
+
+        private View mAnchor;
+
+        public Builder withMenuItemClickListener() {
+            mHasMenuItemClickListener = true;
+            return this;
         }
 
-        int getDismissCount() {
-            return mDismissCount;
+        public Builder withDismissListener() {
+            mHasDismissListener = true;
+            return this;
+        }
+
+        public Builder inflateWithInflater(boolean inflateWithInflater) {
+            mInflateWithInflater = inflateWithInflater;
+            return this;
+        }
+
+        public Builder withPopupStyleResource(int popupStyleResource) {
+            mUseCustomPopupResource = true;
+            mPopupStyleResource = popupStyleResource;
+            return this;
+        }
+
+        public Builder withPopupMenuContent(int popupMenuContent) {
+            mPopupMenuContent = popupMenuContent;
+            return this;
+        }
+
+        public Builder withGravity(int gravity) {
+            mUseCustomGravity = true;
+            mGravity = gravity;
+            return this;
+        }
+
+        private void configure() {
+            mAnchor = mActivity.findViewById(R.id.anchor_middle_left);
+            if (!mUseCustomGravity && !mUseCustomPopupResource) {
+                mPopupMenu = new PopupMenu(mActivity, mAnchor);
+            } else if (!mUseCustomPopupResource) {
+                mPopupMenu = new PopupMenu(mActivity, mAnchor, mGravity);
+            } else {
+                mPopupMenu = new PopupMenu(mActivity, mAnchor, Gravity.NO_GRAVITY,
+                        0, mPopupStyleResource);
+            }
+
+            if (mInflateWithInflater) {
+                final MenuInflater menuInflater = mPopupMenu.getMenuInflater();
+                menuInflater.inflate(mPopupMenuContent, mPopupMenu.getMenu());
+            } else {
+                mPopupMenu.inflate(mPopupMenuContent);
+            }
+
+            if (mHasMenuItemClickListener) {
+                // Register a mock listener to be notified when a menu item in our popup menu has
+                // been clicked.
+                mOnMenuItemClickListener = mock(PopupMenu.OnMenuItemClickListener.class);
+                mPopupMenu.setOnMenuItemClickListener(mOnMenuItemClickListener);
+            }
+
+            if (mHasDismissListener) {
+                // Register a mock listener to be notified when our popup menu is dismissed.
+                mOnDismissListener = mock(PopupMenu.OnDismissListener.class);
+                mPopupMenu.setOnDismissListener(mOnDismissListener);
+            }
+        }
+
+        public void show() {
+            configure();
+            // Show the popup menu
+            mPopupMenu.show();
         }
     }
 }
diff --git a/tests/tests/widget/src/android/widget/cts/PopupWindowCtsActivity.java b/tests/tests/widget/src/android/widget/cts/PopupWindowCtsActivity.java
new file mode 100755
index 0000000..418f04a4
--- /dev/null
+++ b/tests/tests/widget/src/android/widget/cts/PopupWindowCtsActivity.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.widget.cts;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.PopupWindow;
+import android.widget.cts.R;
+
+/**
+ * Stub activity for testing {@link PopupWindow}
+ */
+public class PopupWindowCtsActivity extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.popup_window);
+    }
+}
+
diff --git a/tests/tests/widget/src/android/widget/cts/PopupWindowTest.java b/tests/tests/widget/src/android/widget/cts/PopupWindowTest.java
index bb638e4..96b37d3 100644
--- a/tests/tests/widget/src/android/widget/cts/PopupWindowTest.java
+++ b/tests/tests/widget/src/android/widget/cts/PopupWindowTest.java
@@ -16,36 +16,43 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
-
-
 import android.app.Activity;
 import android.app.Instrumentation;
 import android.content.Context;
 import android.graphics.Color;
+import android.graphics.Rect;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
-import android.os.Debug;
 import android.os.SystemClock;
 import android.test.ActivityInstrumentationTestCase2;
 import android.test.UiThreadTest;
 import android.transition.Transition;
+import android.transition.Transition.TransitionListener;
 import android.transition.TransitionValues;
+import android.util.AttributeSet;
 import android.view.Display;
 import android.view.Gravity;
 import android.view.MotionEvent;
 import android.view.View;
-import android.view.ViewGroup;
-import android.view.WindowManager;
 import android.view.View.OnTouchListener;
+import android.view.ViewGroup;
 import android.view.ViewGroup.LayoutParams;
+import android.view.WindowManager;
 import android.widget.ImageView;
 import android.widget.PopupWindow;
-import android.widget.TextView;
 import android.widget.PopupWindow.OnDismissListener;
+import android.widget.TextView;
+import android.widget.cts.R;
+
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
 public class PopupWindowTest extends
-        ActivityInstrumentationTestCase2<MockPopupWindowCtsActivity> {
+        ActivityInstrumentationTestCase2<PopupWindowCtsActivity> {
     private Instrumentation mInstrumentation;
     private Activity mActivity;
     /** The popup window. */
@@ -55,7 +62,7 @@
      * Instantiates a new popup window test.
      */
     public PopupWindowTest() {
-        super("com.android.cts.widget", MockPopupWindowCtsActivity.class);
+        super("android.widget.cts", PopupWindowCtsActivity.class);
     }
 
     /*
@@ -127,6 +134,53 @@
         assertTrue(mPopupWindow.isFocusable());
     }
 
+    public void testAccessEnterExitTransitions() {
+        PopupWindow w;
+
+        w = new PopupWindow(mActivity, null, 0, 0);
+        assertNull(w.getEnterTransition());
+        assertNull(w.getExitTransition());
+
+        w = new PopupWindow(mActivity, null, 0, R.style.PopupWindow_NullTransitions);
+        assertNull(w.getEnterTransition());
+        assertNull(w.getExitTransition());
+
+        w = new PopupWindow(mActivity, null, 0, R.style.PopupWindow_CustomTransitions);
+        assertTrue(w.getEnterTransition() instanceof CustomTransition);
+        assertTrue(w.getExitTransition() instanceof CustomTransition);
+
+        Transition enterTransition = new CustomTransition();
+        Transition exitTransition = new CustomTransition();
+        w = new PopupWindow(mActivity, null, 0, 0);
+        w.setEnterTransition(enterTransition);
+        w.setExitTransition(exitTransition);
+        assertEquals(enterTransition, w.getEnterTransition());
+        assertEquals(exitTransition, w.getExitTransition());
+
+        w.setEnterTransition(null);
+        w.setExitTransition(null);
+        assertNull(w.getEnterTransition());
+        assertNull(w.getExitTransition());
+    }
+
+    public static class CustomTransition extends Transition {
+        public CustomTransition() {
+        }
+
+        // This constructor is needed for reflection-based creation of a transition when
+        // the transition is defined in layout XML via attribute.
+        @SuppressWarnings("unused")
+        public CustomTransition(Context context, AttributeSet attrs) {
+            super(context, attrs);
+        }
+
+        @Override
+        public void captureStartValues(TransitionValues transitionValues) {}
+
+        @Override
+        public void captureEndValues(TransitionValues transitionValues) {}
+    }
+
     public void testAccessBackground() {
         mPopupWindow = new PopupWindow(mActivity);
 
@@ -243,37 +297,281 @@
         assertEquals(width, mPopupWindow.getWidth());
     }
 
+    private static final int TOP = 0x00;
+    private static final int BOTTOM = 0x01;
+
+    private static final int LEFT = 0x00;
+    private static final int RIGHT = 0x01;
+
+    private static final int GREATER_THAN = 1;
+    private static final int LESS_THAN = -1;
+    private static final int EQUAL_TO = 0;
+
     public void testShowAsDropDown() {
-        int[] anchorXY = new int[2];
-        int[] viewOnScreenXY = new int[2];
-        int[] viewInWindowXY = new int[2];
+        final PopupWindow popup = createPopupWindow(createPopupContent(50, 50));
+        popup.setClipToScreenEnabled(false);
+        popup.setOverlapAnchor(false);
+        popup.setAnimationStyle(0);
+        popup.setExitTransition(null);
+        popup.setEnterTransition(null);
 
-        mPopupWindow = createPopupWindow(createPopupContent());
-        final View upperAnchor = mActivity.findViewById(R.id.anchor_upper);
+        assertPosition(popup, R.id.anchor_upper_left,
+                LEFT, EQUAL_TO, LEFT, TOP, EQUAL_TO, BOTTOM);
+        assertPosition(popup, R.id.anchor_upper,
+                LEFT, EQUAL_TO, LEFT, TOP, EQUAL_TO, BOTTOM);
+        assertPosition(popup, R.id.anchor_upper_right,
+                RIGHT, EQUAL_TO, RIGHT, TOP, EQUAL_TO, BOTTOM);
 
-        mInstrumentation.runOnMainSync(new Runnable() {
-            public void run() {
-                mPopupWindow.showAsDropDown(upperAnchor);
-            }
-        });
-        mInstrumentation.waitForIdleSync();
+        assertPosition(popup, R.id.anchor_middle_left,
+                LEFT, EQUAL_TO, LEFT, TOP, EQUAL_TO, BOTTOM);
+        assertPosition(popup, R.id.anchor_middle,
+                LEFT, EQUAL_TO, LEFT, TOP, EQUAL_TO, BOTTOM);
+        assertPosition(popup, R.id.anchor_middle_right,
+                RIGHT, EQUAL_TO, RIGHT, TOP, EQUAL_TO, BOTTOM);
 
-        assertTrue(mPopupWindow.isShowing());
+        assertPosition(popup, R.id.anchor_lower_left,
+                LEFT, EQUAL_TO, LEFT, BOTTOM, EQUAL_TO, TOP);
+        assertPosition(popup, R.id.anchor_lower,
+                LEFT, EQUAL_TO, LEFT, BOTTOM, EQUAL_TO, TOP);
+        assertPosition(popup, R.id.anchor_lower_right,
+                RIGHT, EQUAL_TO, RIGHT, BOTTOM, EQUAL_TO, TOP);
+    }
 
-        mPopupWindow.getContentView().getLocationOnScreen(viewOnScreenXY);
-        upperAnchor.getLocationOnScreen(anchorXY);
-        mPopupWindow.getContentView().getLocationInWindow(viewInWindowXY);
-        assertEquals(anchorXY[0] + viewInWindowXY[0], viewOnScreenXY[0]);
-        assertEquals(anchorXY[1] + viewInWindowXY[1] + upperAnchor.getHeight(), viewOnScreenXY[1]);
+    public void testShowAsDropDown_ClipToScreen() {
+        final PopupWindow popup = createPopupWindow(createPopupContent(50, 50));
+        popup.setClipToScreenEnabled(true);
+        popup.setOverlapAnchor(false);
+        popup.setAnimationStyle(0);
+        popup.setExitTransition(null);
+        popup.setEnterTransition(null);
 
-        dismissPopup();
+        assertPosition(popup, R.id.anchor_upper_left,
+                LEFT, EQUAL_TO, LEFT, TOP, EQUAL_TO, BOTTOM);
+        assertPosition(popup, R.id.anchor_upper,
+                LEFT, EQUAL_TO, LEFT, TOP, EQUAL_TO, BOTTOM);
+        assertPosition(popup, R.id.anchor_upper_right,
+                RIGHT, EQUAL_TO, RIGHT, TOP, EQUAL_TO, BOTTOM);
+
+        assertPosition(popup, R.id.anchor_middle_left,
+                LEFT, EQUAL_TO, LEFT, TOP, EQUAL_TO, BOTTOM);
+        assertPosition(popup, R.id.anchor_middle,
+                LEFT, EQUAL_TO, LEFT, TOP, EQUAL_TO, BOTTOM);
+        assertPosition(popup, R.id.anchor_middle_right,
+                RIGHT, EQUAL_TO, RIGHT, TOP, EQUAL_TO, BOTTOM);
+
+        assertPosition(popup, R.id.anchor_lower_left,
+                LEFT, EQUAL_TO, LEFT, BOTTOM, EQUAL_TO, TOP);
+        assertPosition(popup, R.id.anchor_lower,
+                LEFT, EQUAL_TO, LEFT, BOTTOM, EQUAL_TO, TOP);
+        assertPosition(popup, R.id.anchor_lower_right,
+                RIGHT, EQUAL_TO, RIGHT, BOTTOM, EQUAL_TO, TOP);
+    }
+
+    public void testShowAsDropDown_ClipToScreen_Overlap() {
+        final PopupWindow popup = createPopupWindow(createPopupContent(50, 50));
+        popup.setClipToScreenEnabled(true);
+        popup.setOverlapAnchor(true);
+        popup.setAnimationStyle(0);
+        popup.setExitTransition(null);
+        popup.setEnterTransition(null);
+
+        assertPosition(popup, R.id.anchor_upper_left,
+                LEFT, EQUAL_TO, LEFT, TOP, EQUAL_TO, TOP);
+        assertPosition(popup, R.id.anchor_upper,
+                LEFT, EQUAL_TO, LEFT, TOP, EQUAL_TO, TOP);
+        assertPosition(popup, R.id.anchor_upper_right,
+                RIGHT, EQUAL_TO, RIGHT, TOP, EQUAL_TO, TOP);
+
+        assertPosition(popup, R.id.anchor_middle_left,
+                LEFT, EQUAL_TO, LEFT, TOP, EQUAL_TO, TOP);
+        assertPosition(popup, R.id.anchor_middle,
+                LEFT, EQUAL_TO, LEFT, TOP, EQUAL_TO, TOP);
+        assertPosition(popup, R.id.anchor_middle_right,
+                RIGHT, EQUAL_TO, RIGHT, TOP, EQUAL_TO, TOP);
+
+        assertPosition(popup, R.id.anchor_lower_left,
+                LEFT, EQUAL_TO, LEFT, BOTTOM, EQUAL_TO, TOP);
+        assertPosition(popup, R.id.anchor_lower,
+                LEFT, EQUAL_TO, LEFT, BOTTOM, EQUAL_TO, TOP);
+        assertPosition(popup, R.id.anchor_lower_right,
+                RIGHT, EQUAL_TO, RIGHT, BOTTOM, EQUAL_TO, TOP);
+    }
+
+    public void testShowAsDropDown_ClipToScreen_Overlap_Offset() {
+        final PopupWindow popup = createPopupWindow(createPopupContent(50, 50));
+        popup.setClipToScreenEnabled(true);
+        popup.setOverlapAnchor(true);
+        popup.setAnimationStyle(0);
+        popup.setExitTransition(null);
+        popup.setEnterTransition(null);
+
+        final int offsetX = mActivity.findViewById(R.id.anchor_upper).getWidth() / 2;
+        final int offsetY = mActivity.findViewById(R.id.anchor_upper).getHeight() / 2;
+        final int gravity = Gravity.TOP | Gravity.START;
+
+        assertPosition(popup, R.id.anchor_upper_left,
+                LEFT, GREATER_THAN, LEFT, TOP, GREATER_THAN, TOP,
+                offsetX, offsetY, gravity);
+        assertPosition(popup, R.id.anchor_upper,
+                LEFT, GREATER_THAN, LEFT, TOP, GREATER_THAN, TOP,
+                offsetX, offsetY, gravity);
+        assertPosition(popup, R.id.anchor_upper_right,
+                RIGHT, EQUAL_TO, RIGHT, TOP, GREATER_THAN, TOP,
+                offsetX, offsetY, gravity);
+
+        assertPosition(popup, R.id.anchor_middle_left,
+                LEFT, GREATER_THAN, LEFT, TOP, GREATER_THAN, TOP,
+                offsetX, offsetY, gravity);
+        assertPosition(popup, R.id.anchor_middle,
+                LEFT, GREATER_THAN, LEFT, TOP, GREATER_THAN, TOP,
+                offsetX, offsetY, gravity);
+        assertPosition(popup, R.id.anchor_middle_right,
+                RIGHT, EQUAL_TO, RIGHT, TOP, GREATER_THAN, TOP,
+                offsetX, offsetY, gravity);
+
+        assertPosition(popup, R.id.anchor_lower_left,
+                LEFT, GREATER_THAN, LEFT, BOTTOM, LESS_THAN, BOTTOM,
+                offsetX, offsetY, gravity);
+        assertPosition(popup, R.id.anchor_lower,
+                LEFT, GREATER_THAN, LEFT, BOTTOM, LESS_THAN, BOTTOM,
+                offsetX, offsetY, gravity);
+        assertPosition(popup, R.id.anchor_lower_right,
+                RIGHT, EQUAL_TO, RIGHT, BOTTOM, LESS_THAN, BOTTOM,
+                offsetX, offsetY, gravity);
+    }
+
+    public void testShowAsDropDown_ClipToScreen_TooBig() {
+        final View rootView = mActivity.findViewById(R.id.anchor_upper_left).getRootView();
+        final int width = rootView.getWidth() * 2;
+        final int height = rootView.getHeight() * 2;
+
+        final PopupWindow popup = createPopupWindow(createPopupContent(width, height));
+        popup.setWidth(width);
+        popup.setHeight(height);
+
+        popup.setClipToScreenEnabled(true);
+        popup.setOverlapAnchor(false);
+        popup.setAnimationStyle(0);
+        popup.setExitTransition(null);
+        popup.setEnterTransition(null);
+
+        assertPosition(popup, R.id.anchor_upper_left,
+                LEFT, EQUAL_TO, LEFT, TOP, LESS_THAN, TOP);
+        assertPosition(popup, R.id.anchor_upper,
+                LEFT, LESS_THAN, LEFT, TOP, LESS_THAN, TOP);
+        assertPosition(popup, R.id.anchor_upper_right,
+                RIGHT, EQUAL_TO, RIGHT, TOP, LESS_THAN, TOP);
+
+        assertPosition(popup, R.id.anchor_middle_left,
+                LEFT, EQUAL_TO, LEFT, TOP, LESS_THAN, TOP);
+        assertPosition(popup, R.id.anchor_middle,
+                LEFT, LESS_THAN, LEFT, TOP, LESS_THAN, TOP);
+        assertPosition(popup, R.id.anchor_middle_right,
+                RIGHT, EQUAL_TO, RIGHT, TOP, LESS_THAN, TOP);
+
+        assertPosition(popup, R.id.anchor_lower_left,
+                LEFT, EQUAL_TO, LEFT, BOTTOM, EQUAL_TO, BOTTOM);
+        assertPosition(popup, R.id.anchor_lower,
+                LEFT, LESS_THAN, LEFT, BOTTOM, EQUAL_TO, BOTTOM);
+        assertPosition(popup, R.id.anchor_lower_right,
+                RIGHT, EQUAL_TO, RIGHT, BOTTOM, EQUAL_TO, BOTTOM);
+    }
+
+    private void assertPosition(PopupWindow popup, int anchorId,
+            int contentEdgeX, int operatorX, int anchorEdgeX,
+            int contentEdgeY, int operatorY, int anchorEdgeY) {
+        assertPosition(popup, anchorId,
+                contentEdgeX, operatorX, anchorEdgeX,
+                contentEdgeY, operatorY, anchorEdgeY,
+                0, 0, Gravity.TOP | Gravity.START);
+    }
+
+    private void assertPosition(PopupWindow popup, int anchorId,
+            int contentEdgeX, int operatorX, int anchorEdgeX,
+            int contentEdgeY, int operatorY, int anchorEdgeY,
+            int offsetX, int offsetY, int gravity) {
+        final View content = popup.getContentView();
+        final View anchor = mActivity.findViewById(anchorId);
+
+        getInstrumentation().runOnMainSync(() -> popup.showAsDropDown(
+                anchor, offsetX, offsetY, gravity));
+        getInstrumentation().waitForIdleSync();
+
+        assertTrue(popup.isShowing());
+        assertPositionX(content, contentEdgeX, operatorX, anchor, anchorEdgeX);
+        assertPositionY(content, contentEdgeY, operatorY, anchor, anchorEdgeY);
+
+        // Make sure it fits in the display frame.
+        final Rect displayFrame = new Rect();
+        anchor.getWindowVisibleDisplayFrame(displayFrame);
+        final Rect contentFrame = new Rect();
+        content.getBoundsOnScreen(contentFrame);
+        assertTrue("Content (" + contentFrame + ") extends outside display (" + displayFrame + ")",
+                displayFrame.contains(contentFrame));
+
+        getInstrumentation().runOnMainSync(() -> popup.dismiss());
+        getInstrumentation().waitForIdleSync();
+
+        assertFalse(popup.isShowing());
+    }
+
+    public static void assertPositionY(View content, int contentEdge, int flags,
+            View anchor, int anchorEdge) {
+        final int[] anchorOnScreenXY = new int[2];
+        anchor.getLocationOnScreen(anchorOnScreenXY);
+        int anchorY = anchorOnScreenXY[1];
+        if ((anchorEdge & BOTTOM) == BOTTOM) {
+            anchorY += anchor.getHeight();
+        }
+
+        final int[] contentOnScreenXY = new int[2];
+        content.getLocationOnScreen(contentOnScreenXY);
+        int contentY = contentOnScreenXY[1];
+        if ((contentEdge & BOTTOM) == BOTTOM) {
+            contentY += content.getHeight();
+        }
+
+        assertComparison(contentY, flags, anchorY);
+    }
+
+    private static void assertPositionX(View content, int contentEdge, int flags,
+            View anchor, int anchorEdge) {
+        final int[] anchorOnScreenXY = new int[2];
+        anchor.getLocationOnScreen(anchorOnScreenXY);
+        int anchorX = anchorOnScreenXY[0];
+        if ((anchorEdge & RIGHT) == RIGHT) {
+            anchorX += anchor.getWidth();
+        }
+
+        final int[] contentOnScreenXY = new int[2];
+        content.getLocationOnScreen(contentOnScreenXY);
+        int contentX = contentOnScreenXY[0];
+        if ((contentEdge & RIGHT) == RIGHT) {
+            contentX += content.getWidth();
+        }
+
+        assertComparison(contentX, flags, anchorX);
+    }
+
+    private static void assertComparison(int left, int operator, int right) {
+        switch (operator) {
+            case GREATER_THAN:
+                assertTrue(left + " <= " + right, left > right);
+                break;
+            case LESS_THAN:
+                assertTrue(left + " >= " + right, left < right);
+                break;
+            case EQUAL_TO:
+                assertTrue(left + " != " + right, left == right);
+                break;
+        }
     }
 
     public void testShowAtLocation() {
         int[] popupContentViewInWindowXY = new int[2];
         int[] popupContentViewOnScreenXY = new int[2];
 
-        mPopupWindow = createPopupWindow(createPopupContent());
+        mPopupWindow = createPopupWindow(createPopupContent(50, 50));
         // Do not attach within the decor; we will be measuring location
         // with regard to screen coordinates.
         mPopupWindow.setAttachedInDecor(false);
@@ -286,11 +584,8 @@
         assertEquals(0, popupContentViewInWindowXY[0]);
         assertEquals(0, popupContentViewInWindowXY[1]);
 
-        mInstrumentation.runOnMainSync(new Runnable() {
-            public void run() {
-                mPopupWindow.showAtLocation(upperAnchor, Gravity.NO_GRAVITY, xOff, yOff);
-            }
-        });
+        mInstrumentation.runOnMainSync(
+                () -> mPopupWindow.showAtLocation(upperAnchor, Gravity.NO_GRAVITY, xOff, yOff));
         mInstrumentation.waitForIdleSync();
 
         assertTrue(mPopupWindow.isShowing());
@@ -309,7 +604,7 @@
         int[] viewOnScreenXY = new int[2];
         int[] viewInWindowXY = new int[2];
 
-        mPopupWindow = createPopupWindow(createPopupContent());
+        mPopupWindow = createPopupWindow(createPopupContent(50, 50));
         final View upperAnchor = mActivity.findViewById(R.id.anchor_upper);
         upperAnchor.getLocationOnScreen(anchorXY);
         int height = upperAnchor.getHeight();
@@ -317,11 +612,7 @@
         final int xOff = 11;
         final int yOff = 12;
 
-        mInstrumentation.runOnMainSync(new Runnable() {
-            public void run() {
-                mPopupWindow.showAsDropDown(upperAnchor, xOff, yOff);
-            }
-        });
+        mInstrumentation.runOnMainSync(() -> mPopupWindow.showAsDropDown(upperAnchor, xOff, yOff));
         mInstrumentation.waitForIdleSync();
 
         mPopupWindow.getContentView().getLocationOnScreen(viewOnScreenXY);
@@ -337,7 +628,7 @@
         int[] viewOnScreenXY = new int[2];
         int[] viewInWindowXY = new int[2];
 
-        mPopupWindow = createPopupWindow(createPopupContent());
+        mPopupWindow = createPopupWindow(createPopupContent(50, 50));
         final View upperAnchor = mActivity.findViewById(R.id.anchor_upper);
         upperAnchor.getLocationOnScreen(anchorXY);
 
@@ -345,11 +636,7 @@
         mPopupWindow.setOverlapAnchor(true);
         assertTrue(mPopupWindow.getOverlapAnchor());
 
-        mInstrumentation.runOnMainSync(new Runnable() {
-            public void run() {
-                mPopupWindow.showAsDropDown(upperAnchor, 0, 0);
-            }
-        });
+        mInstrumentation.runOnMainSync(() -> mPopupWindow.showAsDropDown(upperAnchor, 0, 0));
         mInstrumentation.waitForIdleSync();
 
         mPopupWindow.getContentView().getLocationOnScreen(viewOnScreenXY);
@@ -359,7 +646,7 @@
     }
 
     public void testAccessWindowLayoutType() {
-        mPopupWindow = createPopupWindow(createPopupContent());
+        mPopupWindow = createPopupWindow(createPopupContent(50, 50));
         assertEquals(WindowManager.LayoutParams.TYPE_APPLICATION_PANEL,
                 mPopupWindow.getWindowLayoutType());
         mPopupWindow.setWindowLayoutType(WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL);
@@ -368,7 +655,7 @@
     }
 
     public void testGetMaxAvailableHeight() {
-        mPopupWindow = createPopupWindow(createPopupContent());
+        mPopupWindow = createPopupWindow(createPopupContent(50, 50));
 
         View anchorView = mActivity.findViewById(R.id.anchor_upper);
         int avaliable = getDisplay().getHeight() - anchorView.getHeight();
@@ -409,7 +696,7 @@
 
     @UiThreadTest
     public void testDismiss() {
-        mPopupWindow = createPopupWindow(createPopupContent());
+        mPopupWindow = createPopupWindow(createPopupContent(50, 50));
         assertFalse(mPopupWindow.isShowing());
         View anchorView = mActivity.findViewById(R.id.anchor_upper);
         mPopupWindow.showAsDropDown(anchorView);
@@ -425,24 +712,24 @@
         mPopupWindow = new PopupWindow(new TextView(mActivity));
         mPopupWindow.setOnDismissListener(null);
 
-        MockOnDismissListener onDismissListener = new MockOnDismissListener();
+        OnDismissListener onDismissListener = mock(OnDismissListener.class);
         mPopupWindow.setOnDismissListener(onDismissListener);
         showPopup();
         dismissPopup();
-        assertEquals(1, onDismissListener.getOnDismissCalledCount());
+        verify(onDismissListener, times(1)).onDismiss();
 
         showPopup();
         dismissPopup();
-        assertEquals(2, onDismissListener.getOnDismissCalledCount());
+        verify(onDismissListener, times(2)).onDismiss();
 
         mPopupWindow.setOnDismissListener(null);
         showPopup();
         dismissPopup();
-        assertEquals(2, onDismissListener.getOnDismissCalledCount());
+        verify(onDismissListener, times(2)).onDismiss();
     }
 
     public void testUpdate() {
-        mPopupWindow = createPopupWindow(createPopupContent());
+        mPopupWindow = createPopupWindow(createPopupContent(50, 50));
         mPopupWindow.setBackgroundDrawable(null);
         showPopup();
 
@@ -464,11 +751,7 @@
         assertEquals(0, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS & p.flags);
         assertEquals(0, WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM & p.flags);
 
-        mInstrumentation.runOnMainSync(new Runnable() {
-            public void run() {
-                mPopupWindow.update();
-            }
-        });
+        mInstrumentation.runOnMainSync(() -> mPopupWindow.update());
         mInstrumentation.waitForIdleSync();
 
         assertEquals(WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES,
@@ -485,33 +768,36 @@
     }
 
     public void testEnterExitTransition() {
-        mPopupWindow = createPopupWindow(createPopupContent());
-        final View anchorView = mActivity.findViewById(R.id.anchor_upper);
+        TransitionListener enterListener = mock(TransitionListener.class);
+        Transition enterTransition = new BaseTransition();
+        enterTransition.addListener(enterListener);
 
-        final MockTransition enterTransition = new MockTransition();
-        final MockTransition exitTransition = new MockTransition();
+        TransitionListener exitListener = mock(TransitionListener.class);
+        Transition exitTransition = new BaseTransition();
+        exitTransition.addListener(exitListener);
+
+        OnDismissListener dismissListener = mock(OnDismissListener.class);
+
+        mPopupWindow = createPopupWindow(createPopupContent(50, 50));
         mPopupWindow.setEnterTransition(enterTransition);
         mPopupWindow.setExitTransition(exitTransition);
+        mPopupWindow.setOnDismissListener(dismissListener);
+        verify(enterListener, never()).onTransitionStart(any(Transition.class));
+        verify(exitListener, never()).onTransitionStart(any(Transition.class));
+        verify(dismissListener, never()).onDismiss();
 
-        mInstrumentation.runOnMainSync(new Runnable() {
-            public void run() {
-                mPopupWindow.showAsDropDown(anchorView, 0, 0);
-            }
-        });
+        final View anchorView = mActivity.findViewById(R.id.anchor_upper);
+        mInstrumentation.runOnMainSync(() -> mPopupWindow.showAsDropDown(anchorView, 0, 0));
         mInstrumentation.waitForIdleSync();
+        verify(enterListener, times(1)).onTransitionStart(any(Transition.class));
+        verify(exitListener, never()).onTransitionStart(any(Transition.class));
+        verify(dismissListener, never()).onDismiss();
 
-        assertEquals(1, enterTransition.getTransitionCount());
-        assertEquals(0, exitTransition.getTransitionCount());
-
-        mInstrumentation.runOnMainSync(new Runnable() {
-            public void run() {
-                mPopupWindow.dismiss();
-            }
-        });
+        mInstrumentation.runOnMainSync(() -> mPopupWindow.dismiss());
         mInstrumentation.waitForIdleSync();
-
-        assertEquals(1, enterTransition.getTransitionCount());
-        assertEquals(1, exitTransition.getTransitionCount());
+        verify(enterListener, times(1)).onTransitionStart(any(Transition.class));
+        verify(exitListener, times(1)).onTransitionStart(any(Transition.class));
+        verify(dismissListener, times(1)).onDismiss();
     }
 
     public void testUpdatePositionAndDimension() {
@@ -519,13 +805,11 @@
         int[] sndXY = new int[2];
         int[] viewInWindowXY = new int[2];
 
-        mInstrumentation.runOnMainSync(new Runnable() {
-            public void run() {
-                mPopupWindow = createPopupWindow(createPopupContent());
-                // Do not attach within the decor; we will be measuring location
-                // with regard to screen coordinates.
-                mPopupWindow.setAttachedInDecor(false);
-            }
+        mInstrumentation.runOnMainSync(() -> {
+            mPopupWindow = createPopupWindow(createPopupContent(50, 50));
+            // Do not attach within the decor; we will be measuring location
+            // with regard to screen coordinates.
+            mPopupWindow.setAttachedInDecor(false);
         });
 
         mInstrumentation.waitForIdleSync();
@@ -538,11 +822,7 @@
         mPopupWindow.getContentView().getLocationInWindow(viewInWindowXY);
 
         // update if it is not shown
-        mInstrumentation.runOnMainSync(new Runnable() {
-            public void run() {
-                mPopupWindow.update(20, 50, 50, 50);
-            }
-        });
+        mInstrumentation.runOnMainSync(() -> mPopupWindow.update(20, 50, 50, 50));
 
         mInstrumentation.waitForIdleSync();
         assertTrue(mPopupWindow.isShowing());
@@ -554,11 +834,7 @@
         assertEquals(viewInWindowXY[1] + 50, fstXY[1]);
 
         // ignore if width or height is -1
-        mInstrumentation.runOnMainSync(new Runnable() {
-            public void run() {
-                mPopupWindow.update(4, 0, -1, -1, true);
-            }
-        });
+        mInstrumentation.runOnMainSync(() -> mPopupWindow.update(4, 0, -1, -1, true));
         mInstrumentation.waitForIdleSync();
 
         assertTrue(mPopupWindow.isShowing());
@@ -573,11 +849,8 @@
     }
 
     public void testUpdateDimensionAndAlignAnchorView() {
-        mInstrumentation.runOnMainSync(new Runnable() {
-            public void run() {
-                mPopupWindow = createPopupWindow(createPopupContent());
-            }
-        });
+        mInstrumentation.runOnMainSync(
+                () -> mPopupWindow = createPopupWindow(createPopupContent(50, 50)));
         mInstrumentation.waitForIdleSync();
 
         final View anchorView = mActivity.findViewById(R.id.anchor_upper);
@@ -587,39 +860,23 @@
         assertEquals(100, mPopupWindow.getWidth());
         assertEquals(100, mPopupWindow.getHeight());
 
-        mInstrumentation.runOnMainSync(new Runnable() {
-            public void run() {
-                mPopupWindow.showAsDropDown(anchorView);
-            }
-        });
+        mInstrumentation.runOnMainSync(() -> mPopupWindow.showAsDropDown(anchorView));
         mInstrumentation.waitForIdleSync();
         // update if it is shown
-        mInstrumentation.runOnMainSync(new Runnable() {
-            public void run() {
-                mPopupWindow.update(anchorView, 50, 50);
-            }
-        });
+        mInstrumentation.runOnMainSync(() -> mPopupWindow.update(anchorView, 50, 50));
         mInstrumentation.waitForIdleSync();
         assertTrue(mPopupWindow.isShowing());
         assertEquals(50, mPopupWindow.getWidth());
         assertEquals(50, mPopupWindow.getHeight());
 
         // ignore if width or height is -1
-        mInstrumentation.runOnMainSync(new Runnable() {
-            public void run() {
-                mPopupWindow.update(anchorView, -1, -1);
-            }
-        });
+        mInstrumentation.runOnMainSync(() -> mPopupWindow.update(anchorView, -1, -1));
         mInstrumentation.waitForIdleSync();
         assertTrue(mPopupWindow.isShowing());
         assertEquals(50, mPopupWindow.getWidth());
         assertEquals(50, mPopupWindow.getHeight());
 
-        mInstrumentation.runOnMainSync(new Runnable() {
-            public void run() {
-                mPopupWindow.dismiss();
-            }
-        });
+        mInstrumentation.runOnMainSync(() -> mPopupWindow.dismiss());
         mInstrumentation.waitForIdleSync();
     }
 
@@ -628,7 +885,7 @@
         int[] viewInWindowOff = new int[2];
         int[] viewXY = new int[2];
 
-        mPopupWindow = createPopupWindow(createPopupContent());
+        mPopupWindow = createPopupWindow(createPopupContent(50, 50));
         final View anchorView = mActivity.findViewById(R.id.anchor_upper);
         // Do not update if it is not shown
         assertFalse(mPopupWindow.isShowing());
@@ -640,11 +897,7 @@
         mPopupWindow.getContentView().getLocationInWindow(viewInWindowOff);
 
         // update if it is not shown
-        mInstrumentation.runOnMainSync(new Runnable() {
-            public void run() {
-                mPopupWindow.update(anchorView, 20, 50, 50, 50);
-            }
-        });
+        mInstrumentation.runOnMainSync(() -> mPopupWindow.update(anchorView, 20, 50, 50, 50));
 
         mInstrumentation.waitForIdleSync();
 
@@ -659,11 +912,7 @@
         assertEquals(anchorXY[1] + anchorView.getHeight() + 50 + viewInWindowOff[1], viewXY[1]);
 
         // ignore width and height but change location
-        mInstrumentation.runOnMainSync(new Runnable() {
-            public void run() {
-                mPopupWindow.update(anchorView, 10, 50, -1, -1);
-            }
-        });
+        mInstrumentation.runOnMainSync(() -> mPopupWindow.update(anchorView, 10, 50, -1, -1));
         mInstrumentation.waitForIdleSync();
 
         assertTrue(mPopupWindow.isShowing());
@@ -677,11 +926,7 @@
         assertEquals(anchorXY[1] + anchorView.getHeight() + 50 + viewInWindowOff[1], viewXY[1]);
 
         final View anotherView = mActivity.findViewById(R.id.anchor_middle_left);
-        mInstrumentation.runOnMainSync(new Runnable() {
-            public void run() {
-                mPopupWindow.update(anotherView, 0, 0, 60, 60);
-            }
-        });
+        mInstrumentation.runOnMainSync(() -> mPopupWindow.update(anotherView, 0, 0, 60, 60));
         mInstrumentation.waitForIdleSync();
 
         assertTrue(mPopupWindow.isShowing());
@@ -741,31 +986,20 @@
     }
 
     public void testIsAboveAnchor() {
-        mInstrumentation.runOnMainSync(new Runnable() {
-            public void run() {
-                mPopupWindow = createPopupWindow(createPopupContent());
-            }
-        });
+        mInstrumentation.runOnMainSync(() -> mPopupWindow = createPopupWindow(createPopupContent(50,
+                50)));
         mInstrumentation.waitForIdleSync();
         final View upperAnchor = mActivity.findViewById(R.id.anchor_upper);
 
-        mInstrumentation.runOnMainSync(new Runnable() {
-            public void run() {
-                mPopupWindow.showAsDropDown(upperAnchor);
-            }
-        });
+        mInstrumentation.runOnMainSync(() -> mPopupWindow.showAsDropDown(upperAnchor));
         mInstrumentation.waitForIdleSync();
         assertFalse(mPopupWindow.isAboveAnchor());
         dismissPopup();
 
-        mPopupWindow = createPopupWindow(createPopupContent());
+        mPopupWindow = createPopupWindow(createPopupContent(50, 50));
         final View lowerAnchor = mActivity.findViewById(R.id.anchor_lower);
 
-        mInstrumentation.runOnMainSync(new Runnable() {
-            public void run() {
-                mPopupWindow.showAsDropDown(lowerAnchor, 0, 0);
-            }
-        });
+        mInstrumentation.runOnMainSync(() -> mPopupWindow.showAsDropDown(lowerAnchor, 0, 0));
         mInstrumentation.waitForIdleSync();
         assertTrue(mPopupWindow.isAboveAnchor());
         dismissPopup();
@@ -774,7 +1008,9 @@
     public void testSetTouchInterceptor() {
         mPopupWindow = new PopupWindow(new TextView(mActivity));
 
-        MockOnTouchListener onTouchListener = new MockOnTouchListener();
+        OnTouchListener onTouchListener = mock(OnTouchListener.class);
+        when(onTouchListener.onTouch(any(View.class), any(MotionEvent.class))).thenReturn(true);
+
         mPopupWindow.setTouchInterceptor(onTouchListener);
         mPopupWindow.setFocusable(true);
         mPopupWindow.setOutsideTouchable(true);
@@ -794,20 +1030,20 @@
         MotionEvent event = MotionEvent.obtain(downTime, eventTime,
                 MotionEvent.ACTION_DOWN, x, y, 0);
         getInstrumentation().sendPointerSync(event);
-        assertEquals(1, onTouchListener.getOnTouchCalledCount());
+        verify(onTouchListener, times(1)).onTouch(any(View.class), any(MotionEvent.class));
 
         downTime = SystemClock.uptimeMillis();
         eventTime = SystemClock.uptimeMillis();
         event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP, x, y, 0);
         getInstrumentation().sendPointerSync(event);
-        assertEquals(2, onTouchListener.getOnTouchCalledCount());
+        verify(onTouchListener, times(2)).onTouch(any(View.class), any(MotionEvent.class));
 
         mPopupWindow.setTouchInterceptor(null);
         downTime = SystemClock.uptimeMillis();
         eventTime = SystemClock.uptimeMillis();
         event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_DOWN, x, y, 0);
         getInstrumentation().sendPointerSync(event);
-        assertEquals(2, onTouchListener.getOnTouchCalledCount());
+        verify(onTouchListener, times(2)).onTouch(any(View.class), any(MotionEvent.class));
     }
 
     public void testSetWindowLayoutMode() {
@@ -819,123 +1055,24 @@
         assertEquals(0, p.height);
 
         mPopupWindow.setWindowLayoutMode(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
-        mInstrumentation.runOnMainSync(new Runnable() {
-            public void run() {
-                mPopupWindow.update(20, 50, 50, 50);
-            }
-        });
+        mInstrumentation.runOnMainSync(() -> mPopupWindow.update(20, 50, 50, 50));
 
         assertEquals(LayoutParams.WRAP_CONTENT, p.width);
         assertEquals(LayoutParams.MATCH_PARENT, p.height);
     }
 
-    /**
-     * The listener interface for receiving OnDismiss events. The class that is
-     * interested in processing a OnDismiss event implements this interface, and
-     * the object created with that class is registered with a component using
-     * the component's <code>setOnDismissListener<code> method. When
-     * the OnDismiss event occurs, that object's appropriate
-     * method is invoked.
-     */
-    private static class MockOnDismissListener implements OnDismissListener {
+    private static class BaseTransition extends Transition {
+        @Override
+        public void captureStartValues(TransitionValues transitionValues) {}
 
-        /** The Ondismiss called count. */
-        private int mOnDismissCalledCount;
-
-        /**
-         * Gets the onDismiss() called count.
-         *
-         * @return the on dismiss called count
-         */
-        public int getOnDismissCalledCount() {
-            return mOnDismissCalledCount;
-        }
-
-        /*
-         * (non-Javadoc)
-         *
-         * @see android.widget.PopupWindow.OnDismissListener#onDismiss()
-         */
-        public void onDismiss() {
-            mOnDismissCalledCount++;
-        }
-
+        @Override
+        public void captureEndValues(TransitionValues transitionValues) {}
     }
 
-    /**
-     * The listener interface for receiving touch events.
-     */
-    private static class MockOnTouchListener implements OnTouchListener {
-
-        /** The onTouch called count. */
-        private int mOnTouchCalledCount;
-
-        /**
-         * Gets the onTouch() called count.
-         *
-         * @return the onTouch() called count
-         */
-        public int getOnTouchCalledCount() {
-            return mOnTouchCalledCount;
-        }
-
-        /*
-         * (non-Javadoc)
-         *
-         * @see android.widget.PopupWindow.OnTouchListener#onDismiss()
-         */
-        public boolean onTouch(View v, MotionEvent event) {
-            mOnTouchCalledCount++;
-            return true;
-        }
-    }
-
-    private static class MockTransition extends Transition {
-        private int mTransitionCount;
-
-        private MockTransition() {
-            addListener(new Transition.TransitionListener() {
-                @Override
-                public void onTransitionStart(Transition transition) {
-
-                }
-
-                public void onTransitionEnd(Transition transition) {
-                    mTransitionCount++;
-                }
-
-                @Override
-                public void onTransitionCancel(Transition transition) {
-
-                }
-
-                @Override
-                public void onTransitionPause(Transition transition) {
-
-                }
-
-                @Override
-                public void onTransitionResume(Transition transition) {
-
-                }
-            });
-        }
-
-        public void captureStartValues(TransitionValues transitionValues) {
-        }
-
-        public void captureEndValues(TransitionValues transitionValues) {
-        }
-
-        int getTransitionCount() {
-            return mTransitionCount;
-        }
-    }
-
-    private View createPopupContent() {
-        View popupView = new View(mActivity);
-        popupView.setLayoutParams(new ViewGroup.LayoutParams(50, 50));
-        popupView.setBackgroundColor(Color.WHITE);
+    private View createPopupContent(int width, int height) {
+        final View popupView = new View(mActivity);
+        popupView.setLayoutParams(new ViewGroup.LayoutParams(width, height));
+        popupView.setBackgroundColor(Color.MAGENTA);
 
         return popupView;
     }
@@ -944,6 +1081,7 @@
         PopupWindow window = new PopupWindow(mActivity);
         window.setWidth(100);
         window.setHeight(100);
+        window.setBackgroundDrawable(new ColorDrawable(Color.YELLOW));
         return window;
     }
 
@@ -953,35 +1091,24 @@
         return window;
     }
 
-    /**
-     * Show PopupWindow.
-     */
-    // FIXME: logcat info complains that there is window leakage due to that mPopupWindow is not
-    // clean up. Need to fix it.
     private void showPopup() {
-        mInstrumentation.runOnMainSync(new Runnable() {
-            public void run() {
-                if (mPopupWindow == null || mPopupWindow.isShowing()) {
-                    return;
-                }
-                View anchor = mActivity.findViewById(R.id.anchor_upper);
-                mPopupWindow.showAsDropDown(anchor);
-                assertTrue(mPopupWindow.isShowing());
+        mInstrumentation.runOnMainSync(() -> {
+            if (mPopupWindow == null || mPopupWindow.isShowing()) {
+                return;
             }
+            View anchor = mActivity.findViewById(R.id.anchor_upper);
+            mPopupWindow.showAsDropDown(anchor);
+            assertTrue(mPopupWindow.isShowing());
         });
         mInstrumentation.waitForIdleSync();
     }
 
-    /**
-     * Dismiss PopupWindow.
-     */
     private void dismissPopup() {
-        mInstrumentation.runOnMainSync(new Runnable() {
-            public void run() {
-                if (mPopupWindow == null || !mPopupWindow.isShowing())
-                    return;
-                mPopupWindow.dismiss();
+        mInstrumentation.runOnMainSync(() -> {
+            if (mPopupWindow == null || !mPopupWindow.isShowing()) {
+                return;
             }
+            mPopupWindow.dismiss();
         });
         mInstrumentation.waitForIdleSync();
     }
diff --git a/tests/tests/widget/src/android/widget/cts/ProgressBarTest.java b/tests/tests/widget/src/android/widget/cts/ProgressBarTest.java
index e57d298..1cf7334 100644
--- a/tests/tests/widget/src/android/widget/cts/ProgressBarTest.java
+++ b/tests/tests/widget/src/android/widget/cts/ProgressBarTest.java
@@ -21,7 +21,7 @@
 import android.graphics.PorterDuff;
 import android.view.LayoutInflater;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 
 import android.content.Context;
@@ -267,18 +267,8 @@
         mockProgressBar.invalidateDrawable(mockDrawable2);
         assertFalse(mockProgressBar.hasCalledInvalidate());
 
-        try {
-            mockProgressBar.invalidateDrawable(null);
-            fail("Should throw NullPointerException");
-        } catch (NullPointerException e) {
-            // issue 1695243, not clear what is supposed to happen if drawable is null.
-        }
-
         mockProgressBar.setIndeterminateDrawable(mockDrawable1);
         mockProgressBar.setProgressDrawable(mockDrawable2);
-
-        mockProgressBar.invalidateDrawable(null);
-        assertFalse(mockProgressBar.hasCalledInvalidate());
     }
 
     public void testPostInvalidate() {
diff --git a/tests/tests/widget/src/android/widget/cts/RadioButtonTest.java b/tests/tests/widget/src/android/widget/cts/RadioButtonTest.java
index 4ec4eb5..eb9387b 100644
--- a/tests/tests/widget/src/android/widget/cts/RadioButtonTest.java
+++ b/tests/tests/widget/src/android/widget/cts/RadioButtonTest.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 
 import android.content.Context;
diff --git a/tests/tests/widget/src/android/widget/cts/RadioGroupTest.java b/tests/tests/widget/src/android/widget/cts/RadioGroupTest.java
index a172ecb..b2154e2 100644
--- a/tests/tests/widget/src/android/widget/cts/RadioGroupTest.java
+++ b/tests/tests/widget/src/android/widget/cts/RadioGroupTest.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 
 import org.xmlpull.v1.XmlPullParser;
diff --git a/tests/tests/widget/src/android/widget/cts/RadioGroup_LayoutParamsTest.java b/tests/tests/widget/src/android/widget/cts/RadioGroup_LayoutParamsTest.java
index b14c0e8..37cd632 100644
--- a/tests/tests/widget/src/android/widget/cts/RadioGroup_LayoutParamsTest.java
+++ b/tests/tests/widget/src/android/widget/cts/RadioGroup_LayoutParamsTest.java
@@ -114,7 +114,7 @@
         }
 
         mLayoutParams = new LayoutParams(getContext(),
-                getAttributeSet(com.android.cts.widget.R.layout.radiogroup_1));
+                getAttributeSet(android.widget.cts.R.layout.radiogroup_1));
         assertNotNull(mLayoutParams);
         assertEquals(0.5, mLayoutParams.weight, 0);
         assertEquals(Gravity.BOTTOM, mLayoutParams.gravity);
@@ -131,7 +131,7 @@
 
         try {
             new RadioGroup.LayoutParams(null,
-                    getAttributeSet(com.android.cts.widget.R.layout.radiogroup_1));
+                    getAttributeSet(android.widget.cts.R.layout.radiogroup_1));
             fail("The constructor should throw NullPointerException when param Context is null.");
         } catch (NullPointerException e) {
         }
@@ -143,7 +143,7 @@
         assertEquals(LayoutParams.WRAP_CONTENT, layoutParams.width);
         assertEquals(LayoutParams.WRAP_CONTENT, layoutParams.height);
 
-        AttributeSet attrs = getAttributeSet(com.android.cts.widget.R.layout.radiogroup_1);
+        AttributeSet attrs = getAttributeSet(android.widget.cts.R.layout.radiogroup_1);
         TypedArray a = mContext.obtainStyledAttributes(attrs, R.styleable.ViewGroup_MarginLayout);
         layoutParams.setBaseAttributes(a,
                 R.styleable.ViewGroup_MarginLayout_layout_width,
diff --git a/tests/tests/widget/src/android/widget/cts/RatingBarCtsActivity.java b/tests/tests/widget/src/android/widget/cts/RatingBarCtsActivity.java
index 7d4e232..1a9cb40 100644
--- a/tests/tests/widget/src/android/widget/cts/RatingBarCtsActivity.java
+++ b/tests/tests/widget/src/android/widget/cts/RatingBarCtsActivity.java
@@ -19,7 +19,7 @@
 import android.app.Activity;
 import android.os.Bundle;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 /**
  * An application for ProgressBar test
diff --git a/tests/tests/widget/src/android/widget/cts/RatingBarTest.java b/tests/tests/widget/src/android/widget/cts/RatingBarTest.java
index 211d7fe..669e7a1 100644
--- a/tests/tests/widget/src/android/widget/cts/RatingBarTest.java
+++ b/tests/tests/widget/src/android/widget/cts/RatingBarTest.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 import android.content.Context;
 import android.test.ActivityInstrumentationTestCase2;
@@ -32,7 +32,7 @@
     private RatingBarCtsActivity mActivity;
 
     public RatingBarTest() {
-        super("com.android.cts.widget", RatingBarCtsActivity.class);
+        super("android.widget.cts", RatingBarCtsActivity.class);
     }
 
     @Override
diff --git a/tests/tests/widget/src/android/widget/cts/RelativeLayoutCtsActivity.java b/tests/tests/widget/src/android/widget/cts/RelativeLayoutCtsActivity.java
index df83f54..c394ca4 100644
--- a/tests/tests/widget/src/android/widget/cts/RelativeLayoutCtsActivity.java
+++ b/tests/tests/widget/src/android/widget/cts/RelativeLayoutCtsActivity.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 import android.app.Activity;
 import android.os.Bundle;
diff --git a/tests/tests/widget/src/android/widget/cts/RelativeLayoutTest.java b/tests/tests/widget/src/android/widget/cts/RelativeLayoutTest.java
index b228ca6..2f3be6f 100644
--- a/tests/tests/widget/src/android/widget/cts/RelativeLayoutTest.java
+++ b/tests/tests/widget/src/android/widget/cts/RelativeLayoutTest.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
@@ -46,7 +46,7 @@
     private Activity mActivity;
 
     public RelativeLayoutTest() {
-        super("com.android.cts.widget", RelativeLayoutCtsActivity.class);
+        super("android.widget.cts", RelativeLayoutCtsActivity.class);
     }
 
     @Override
@@ -296,6 +296,25 @@
         assertEquals(ViewGroup.LayoutParams.WRAP_CONTENT, layoutParams.height);
     }
 
+    public void testGenerateLayoutParamsFromMarginParams() {
+        MyRelativeLayout layout = new MyRelativeLayout(mActivity);
+        ViewGroup.MarginLayoutParams lp = new ViewGroup.MarginLayoutParams(3, 5);
+        lp.leftMargin = 1;
+        lp.topMargin = 2;
+        lp.rightMargin = 3;
+        lp.bottomMargin = 4;
+        RelativeLayout.LayoutParams generated = (RelativeLayout.LayoutParams)
+                layout.generateLayoutParams(lp);
+        assertNotNull(generated);
+        assertEquals(3, generated.width);
+        assertEquals(5, generated.height);
+
+        assertEquals(1, generated.leftMargin);
+        assertEquals(2, generated.topMargin);
+        assertEquals(3, generated.rightMargin);
+        assertEquals(4, generated.bottomMargin);
+    }
+
     public void testOnMeasure() {
         // onMeasure() is implementation details, do NOT test
     }
diff --git a/tests/tests/widget/src/android/widget/cts/RelativeLayout_LayoutParamsTest.java b/tests/tests/widget/src/android/widget/cts/RelativeLayout_LayoutParamsTest.java
index 07c7b77..5706781 100644
--- a/tests/tests/widget/src/android/widget/cts/RelativeLayout_LayoutParamsTest.java
+++ b/tests/tests/widget/src/android/widget/cts/RelativeLayout_LayoutParamsTest.java
@@ -16,10 +16,11 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 import android.test.ActivityInstrumentationTestCase2;
 import android.test.ViewAsserts;
+import android.util.LayoutDirection;
 import android.view.View;
 import android.view.ViewGroup.MarginLayoutParams;
 import android.widget.RelativeLayout;
@@ -31,7 +32,7 @@
         ActivityInstrumentationTestCase2<RelativeLayoutCtsActivity> {
 
     public RelativeLayout_LayoutParamsTest() {
-        super("com.android.cts.widget", RelativeLayoutCtsActivity.class);
+        super("android.widget.cts", RelativeLayoutCtsActivity.class);
     }
 
     public void testConstructor() {
@@ -415,6 +416,29 @@
         assertEquals(Integer.MIN_VALUE, rules[RelativeLayout.ALIGN_LEFT]);
     }
 
+    public void testRemoveRule() {
+        RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(200, 300);
+
+        layoutParams.addRule(RelativeLayout.ALIGN_PARENT_START, RelativeLayout.TRUE);
+        layoutParams.resolveLayoutDirection(LayoutDirection.LTR);
+        assertEquals(0, layoutParams.getRule(RelativeLayout.ALIGN_PARENT_START));
+        assertEquals(RelativeLayout.TRUE, layoutParams.getRule(RelativeLayout.ALIGN_PARENT_LEFT));
+        assertEquals(0, layoutParams.getRule(RelativeLayout.CENTER_HORIZONTAL));
+
+        layoutParams.removeRule(RelativeLayout.ALIGN_PARENT_START);
+        layoutParams.addRule(RelativeLayout.CENTER_HORIZONTAL, RelativeLayout.TRUE);
+        layoutParams.resolveLayoutDirection(LayoutDirection.LTR);
+        assertEquals(0, layoutParams.getRule(RelativeLayout.ALIGN_PARENT_START));
+        assertEquals(0, layoutParams.getRule(RelativeLayout.ALIGN_PARENT_LEFT));
+        assertEquals(RelativeLayout.TRUE, layoutParams.getRule(RelativeLayout.CENTER_HORIZONTAL));
+
+        layoutParams.removeRule(RelativeLayout.CENTER_HORIZONTAL);
+        layoutParams.resolveLayoutDirection(LayoutDirection.LTR);
+        assertEquals(0, layoutParams.getRule(RelativeLayout.ALIGN_PARENT_START));
+        assertEquals(0, layoutParams.getRule(RelativeLayout.ALIGN_PARENT_LEFT));
+        assertEquals(0, layoutParams.getRule(RelativeLayout.CENTER_HORIZONTAL));
+    }
+
     public void testDebug() {
         RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(200, 300);
         assertNotNull(layoutParams.debug("test: "));
diff --git a/tests/tests/widget/src/android/widget/cts/RemoteViewsActivityTest.java b/tests/tests/widget/src/android/widget/cts/RemoteViewsActivityTest.java
index ab109b1..369d7aa 100644
--- a/tests/tests/widget/src/android/widget/cts/RemoteViewsActivityTest.java
+++ b/tests/tests/widget/src/android/widget/cts/RemoteViewsActivityTest.java
@@ -26,11 +26,11 @@
 import android.view.ViewGroup;
 import android.widget.RemoteViews;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 public class RemoteViewsActivityTest
         extends ActivityInstrumentationTestCase2<RemoteViewsCtsActivity> {
-    private static final String PACKAGE_NAME = "com.android.cts.widget";
+    private static final String PACKAGE_NAME = "android.widget.cts";
     private Activity mActivity;
 
     public RemoteViewsActivityTest() {
diff --git a/tests/tests/widget/src/android/widget/cts/RemoteViewsCtsActivity.java b/tests/tests/widget/src/android/widget/cts/RemoteViewsCtsActivity.java
index 4da5aa2..64001dc 100644
--- a/tests/tests/widget/src/android/widget/cts/RemoteViewsCtsActivity.java
+++ b/tests/tests/widget/src/android/widget/cts/RemoteViewsCtsActivity.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 import android.app.Activity;
 import android.cts.util.NullWebViewUtils;
diff --git a/tests/tests/widget/src/android/widget/cts/RemoteViewsTest.java b/tests/tests/widget/src/android/widget/cts/RemoteViewsTest.java
index 58738a1..605dbb6 100644
--- a/tests/tests/widget/src/android/widget/cts/RemoteViewsTest.java
+++ b/tests/tests/widget/src/android/widget/cts/RemoteViewsTest.java
@@ -18,7 +18,7 @@
 
 import android.graphics.drawable.Icon;
 import android.test.UiThreadTest;
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 
 import android.app.Activity;
@@ -59,7 +59,7 @@
  * Test {@link RemoteViews}.
  */
 public class RemoteViewsTest extends ActivityInstrumentationTestCase2<RemoteViewsCtsActivity> {
-    private static final String PACKAGE_NAME = "com.android.cts.widget";
+    private static final String PACKAGE_NAME = "android.widget.cts";
 
     private static final int INVALD_ID = -1;
 
@@ -633,7 +633,7 @@
                 if (target != null) {
                     target.close();
                 }
-            } catch (IOException _) {
+            } catch (IOException ignored) {
                 // Ignore the IOException.
             }
         }
diff --git a/tests/tests/widget/src/android/widget/cts/ResourceCursorAdapterTest.java b/tests/tests/widget/src/android/widget/cts/ResourceCursorAdapterTest.java
index 580be27..aefca0f 100644
--- a/tests/tests/widget/src/android/widget/cts/ResourceCursorAdapterTest.java
+++ b/tests/tests/widget/src/android/widget/cts/ResourceCursorAdapterTest.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 
 import android.content.Context;
diff --git a/tests/tests/widget/src/android/widget/cts/ResourceCursorTreeAdapterTest.java b/tests/tests/widget/src/android/widget/cts/ResourceCursorTreeAdapterTest.java
index 760f7e4..e801e93 100644
--- a/tests/tests/widget/src/android/widget/cts/ResourceCursorTreeAdapterTest.java
+++ b/tests/tests/widget/src/android/widget/cts/ResourceCursorTreeAdapterTest.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 
 import android.content.Context;
diff --git a/tests/tests/widget/src/android/widget/cts/ScrollViewCtsActivity.java b/tests/tests/widget/src/android/widget/cts/ScrollViewCtsActivity.java
index 8965610..b2b51c6 100644
--- a/tests/tests/widget/src/android/widget/cts/ScrollViewCtsActivity.java
+++ b/tests/tests/widget/src/android/widget/cts/ScrollViewCtsActivity.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 import android.app.Activity;
 import android.os.Bundle;
diff --git a/tests/tests/widget/src/android/widget/cts/ScrollViewTest.java b/tests/tests/widget/src/android/widget/cts/ScrollViewTest.java
index a8fb224..26510f27 100644
--- a/tests/tests/widget/src/android/widget/cts/ScrollViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/ScrollViewTest.java
@@ -16,7 +16,12 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+import android.widget.FrameLayout;
+import android.widget.cts.R;
 
 
 import org.xmlpull.v1.XmlPullParser;
@@ -34,7 +39,6 @@
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.View.MeasureSpec;
-import android.view.ViewGroup.LayoutParams;
 import android.widget.ScrollView;
 import android.widget.TextView;
 
@@ -61,7 +65,7 @@
     private Activity mActivity;
 
     public ScrollViewTest() {
-        super("com.android.cts.widget", ScrollViewCtsActivity.class);
+        super("android.widget.cts", ScrollViewCtsActivity.class);
     }
 
     @Override
@@ -351,6 +355,179 @@
         assertEquals(100, child.getMeasuredWidth());
     }
 
+    public void testMeasureSpecs() {
+        MyView child = spy(new MyView(mActivity));
+        MyScrollView scrollView = new MyScrollView(mActivity);
+        scrollView.addView(child);
+
+        scrollView.measureChild(child, MeasureSpec.makeMeasureSpec(150, MeasureSpec.EXACTLY),
+                MeasureSpec.makeMeasureSpec(100, MeasureSpec.EXACTLY));
+        verify(child).onMeasure(
+                eq(MeasureSpec.makeMeasureSpec(150, MeasureSpec.EXACTLY)),
+                eq(MeasureSpec.makeMeasureSpec(100, MeasureSpec.UNSPECIFIED)));
+    }
+
+    public void testMeasureSpecsWithPadding() {
+        MyView child = spy(new MyView(mActivity));
+        MyScrollView scrollView = new MyScrollView(mActivity);
+        scrollView.setPadding(3, 5, 7, 11);
+        scrollView.addView(child);
+
+        scrollView.measureChild(child, MeasureSpec.makeMeasureSpec(150, MeasureSpec.EXACTLY),
+                MeasureSpec.makeMeasureSpec(100, MeasureSpec.EXACTLY));
+        verify(child).onMeasure(
+                eq(MeasureSpec.makeMeasureSpec(140, MeasureSpec.EXACTLY)),
+                eq(MeasureSpec.makeMeasureSpec(84, MeasureSpec.UNSPECIFIED)));
+    }
+
+    public void testMeasureSpecsWithMargins() {
+        MyView child = spy(new MyView(mActivity));
+        MyScrollView scrollView = new MyScrollView(mActivity);
+        scrollView.addView(child);
+
+        scrollView.measureChildWithMargins(child,
+                MeasureSpec.makeMeasureSpec(150, MeasureSpec.EXACTLY), 20,
+                MeasureSpec.makeMeasureSpec(100, MeasureSpec.EXACTLY), 15);
+        verify(child).onMeasure(
+                eq(MeasureSpec.makeMeasureSpec(130, MeasureSpec.EXACTLY)),
+                eq(MeasureSpec.makeMeasureSpec(85, MeasureSpec.UNSPECIFIED)));
+    }
+
+    public void testMeasureSpecsWithMarginsAndPadding() {
+        MyView child = spy(new MyView(mActivity));
+        MyScrollView scrollView = new MyScrollView(mActivity);
+        scrollView.setPadding(3, 5, 7, 11);
+        scrollView.addView(child);
+
+        scrollView.measureChildWithMargins(child,
+                MeasureSpec.makeMeasureSpec(150, MeasureSpec.EXACTLY), 20,
+                MeasureSpec.makeMeasureSpec(100, MeasureSpec.EXACTLY), 15);
+        verify(child).onMeasure(
+                eq(MeasureSpec.makeMeasureSpec(120, MeasureSpec.EXACTLY)),
+                eq(MeasureSpec.makeMeasureSpec(69, MeasureSpec.UNSPECIFIED)));
+    }
+
+    public void testMeasureSpecsWithMarginsAndNoHintWidth() {
+        MyView child = spy(new MyView(mActivity));
+        MyScrollView scrollView = new MyScrollView(mActivity);
+        scrollView.addView(child);
+
+        scrollView.measureChildWithMargins(child,
+                MeasureSpec.makeMeasureSpec(150, MeasureSpec.EXACTLY), 20,
+                MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), 15);
+        verify(child).onMeasure(
+                eq(MeasureSpec.makeMeasureSpec(130, MeasureSpec.EXACTLY)),
+                eq(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)));
+    }
+
+    public void testFillViewport() {
+        MyScrollView scrollView = new MyScrollView(mActivity);
+        scrollView.setFillViewport(true);
+
+        MyView child = new MyView(mActivity);
+        child.setLayoutParams(new ViewGroup.LayoutParams(100, 100));
+
+        scrollView.addView(child);
+        scrollView.measure(MeasureSpec.makeMeasureSpec(100, MeasureSpec.EXACTLY),
+                MeasureSpec.makeMeasureSpec(150, MeasureSpec.EXACTLY));
+
+        assertEquals(150, child.getMeasuredHeight());
+        assertEquals(100, child.getMeasuredWidth());
+
+        scrollView.layout(0, 0, 100, 150);
+        assertEquals(0, child.getTop());
+    }
+
+    public void testFillViewportWithScrollViewPadding() {
+        MyScrollView scrollView = new MyScrollView(mActivity);
+        scrollView.setFillViewport(true);
+        scrollView.setPadding(3, 10, 5, 7);
+
+        MyView child = new MyView(mActivity);
+        child.setLayoutParams(new ViewGroup.LayoutParams(10,10));
+        child.setDesiredHeight(30);
+
+        scrollView.addView(child);
+        scrollView.measure(MeasureSpec.makeMeasureSpec(100, MeasureSpec.EXACTLY),
+                MeasureSpec.makeMeasureSpec(150, MeasureSpec.EXACTLY));
+
+        assertEquals(133, child.getMeasuredHeight());
+        assertEquals(10, child.getMeasuredWidth());
+
+        scrollView.layout(0, 0, 100, 150);
+        assertEquals(10, child.getTop());
+    }
+
+    public void testFillViewportWithChildMargins() {
+        MyScrollView scrollView = new MyScrollView(mActivity);
+        scrollView.setFillViewport(true);
+
+        MyView child = new MyView(mActivity);
+        FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(10, 10);
+        lp.leftMargin = 3;
+        lp.topMargin = 10;
+        lp.rightMargin = 5;
+        lp.bottomMargin = 7;
+        child.setDesiredHeight(30);
+        child.setLayoutParams(lp);
+
+        scrollView.addView(child);
+        scrollView.measure(MeasureSpec.makeMeasureSpec(100, MeasureSpec.EXACTLY),
+                MeasureSpec.makeMeasureSpec(150, MeasureSpec.EXACTLY));
+
+        assertEquals(133, child.getMeasuredHeight());
+        assertEquals(10, child.getMeasuredWidth());
+
+        scrollView.layout(0, 0, 100, 150);
+        assertEquals(10, child.getTop());
+    }
+
+    public void testFillViewportWithScrollViewPaddingAlreadyFills() {
+        MyScrollView scrollView = new MyScrollView(mActivity);
+        scrollView.setFillViewport(true);
+        scrollView.setPadding(3, 10, 5, 7);
+
+        MyView child = new MyView(mActivity);
+        child.setDesiredHeight(175);
+
+        scrollView.addView(child);
+        scrollView.measure(MeasureSpec.makeMeasureSpec(100, MeasureSpec.EXACTLY),
+                MeasureSpec.makeMeasureSpec(150, MeasureSpec.EXACTLY));
+
+
+        assertEquals(92, child.getMeasuredWidth());
+        assertEquals(175, child.getMeasuredHeight());
+
+        scrollView.layout(0, 0, 100, 150);
+        assertEquals(10, child.getTop());
+    }
+
+    public void testFillViewportWithChildMarginsAlreadyFills() {
+        MyScrollView scrollView = new MyScrollView(mActivity);
+        scrollView.setFillViewport(true);
+        MyView child = new MyView(mActivity);
+        FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
+                ViewGroup.LayoutParams.MATCH_PARENT,
+                ViewGroup.LayoutParams.WRAP_CONTENT);
+
+        lp.leftMargin = 3;
+        lp.topMargin = 10;
+        lp.rightMargin = 5;
+        lp.bottomMargin = 7;
+        child.setLayoutParams(lp);
+        child.setDesiredHeight(175);
+
+        scrollView.addView(child);
+        scrollView.measure(MeasureSpec.makeMeasureSpec(100, MeasureSpec.EXACTLY),
+                MeasureSpec.makeMeasureSpec(150, MeasureSpec.EXACTLY));
+
+        assertEquals(92, child.getMeasuredWidth());
+        assertEquals(175, child.getMeasuredHeight());
+
+        scrollView.layout(0, 0, 100, 150);
+        assertEquals(10, child.getTop());
+    }
+
     @UiThreadTest
     public void testPageScroll() {
         mScrollView.setSmoothScrollingEnabled(false);
@@ -703,9 +880,31 @@
         }.run();
     }
 
-    private static class MyView extends View {
+    public static class MyView extends View {
+        // measure in this height if set
+        private Integer mDesiredHeight;
         public MyView(Context context) {
             super(context);
         }
+
+        public void setDesiredHeight(Integer desiredHeight) {
+            mDesiredHeight = desiredHeight;
+        }
+
+        @Override
+        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+            if (mDesiredHeight != null) {
+                int mode = MeasureSpec.getMode(heightMeasureSpec);
+                int size = MeasureSpec.getSize(heightMeasureSpec);
+                int newHeight = size;
+                if (mode == MeasureSpec.AT_MOST) {
+                    newHeight = Math.max(size, mDesiredHeight);
+                } else if (mode == MeasureSpec.UNSPECIFIED) {
+                    newHeight = mDesiredHeight;
+                }
+                setMeasuredDimension(getMeasuredWidth(), newHeight);
+            }
+        }
     }
 }
diff --git a/tests/tests/widget/src/android/widget/cts/SeekBarCtsActivity.java b/tests/tests/widget/src/android/widget/cts/SeekBarCtsActivity.java
index e7842c2..e22b910 100644
--- a/tests/tests/widget/src/android/widget/cts/SeekBarCtsActivity.java
+++ b/tests/tests/widget/src/android/widget/cts/SeekBarCtsActivity.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 import android.app.Activity;
 import android.os.Bundle;
diff --git a/tests/tests/widget/src/android/widget/cts/SeekBarTest.java b/tests/tests/widget/src/android/widget/cts/SeekBarTest.java
index 43aada2..b9ad733 100644
--- a/tests/tests/widget/src/android/widget/cts/SeekBarTest.java
+++ b/tests/tests/widget/src/android/widget/cts/SeekBarTest.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 
 import android.app.Activity;
@@ -38,7 +38,7 @@
     private Instrumentation mInstrumentation;
 
     public SeekBarTest() {
-        super("com.android.cts.widget", SeekBarCtsActivity.class);
+        super("android.widget.cts", SeekBarCtsActivity.class);
     }
 
     @Override
diff --git a/tests/tests/widget/src/android/widget/cts/SimpleAdapterTest.java b/tests/tests/widget/src/android/widget/cts/SimpleAdapterTest.java
index 28ff15e..5a9af25 100644
--- a/tests/tests/widget/src/android/widget/cts/SimpleAdapterTest.java
+++ b/tests/tests/widget/src/android/widget/cts/SimpleAdapterTest.java
@@ -92,7 +92,7 @@
         mContext = getInstrumentation().getTargetContext();
         mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
         mAdapterHost = (LinearLayout) mInflater.inflate(
-                com.android.cts.widget.R.layout.cursoradapter_host, null);
+                android.widget.cts.R.layout.cursoradapter_host, null);
 
         // new the SimpleAdapter instance
         mSimpleAdapter = new SimpleAdapter(mContext,
@@ -289,9 +289,9 @@
         // String represents resId
         ImageView view = new ImageView(mContext);
         assertNull(view.getDrawable());
-        mSimpleAdapter.setViewImage(view, String.valueOf(com.android.cts.widget.R.drawable.scenery));
+        mSimpleAdapter.setViewImage(view, String.valueOf(android.widget.cts.R.drawable.scenery));
         BitmapDrawable d = (BitmapDrawable) mContext.getResources().getDrawable(
-                com.android.cts.widget.R.drawable.scenery);
+                android.widget.cts.R.drawable.scenery);
         WidgetTestUtils.assertEquals(d.getBitmap(),
                 ((BitmapDrawable) view.getDrawable()).getBitmap());
 
@@ -314,9 +314,9 @@
         // resId
         view = new ImageView(mContext);
         assertNull(view.getDrawable());
-        mSimpleAdapter.setViewImage(view, com.android.cts.widget.R.drawable.scenery);
+        mSimpleAdapter.setViewImage(view, android.widget.cts.R.drawable.scenery);
         d = (BitmapDrawable) mContext.getResources()
-                .getDrawable(com.android.cts.widget.R.drawable.scenery);
+                .getDrawable(android.widget.cts.R.drawable.scenery);
         WidgetTestUtils.assertEquals(d.getBitmap(),
                 ((BitmapDrawable) view.getDrawable()).getBitmap());
 
@@ -331,11 +331,11 @@
         assertNull(view.getDrawable());
         try {
             mSimpleAdapter.setViewImage(view, SimpleCursorAdapterTest.createTestImage(mContext,
-                    "testimage", com.android.cts.widget.R.raw.testimage));
+                    "testimage", android.widget.cts.R.raw.testimage));
             assertNotNull(view.getDrawable());
             Bitmap actualBitmap = ((BitmapDrawable) view.getDrawable()).getBitmap();
             Bitmap testBitmap = WidgetTestUtils.getUnscaledAndDitheredBitmap(mContext.getResources(),
-                    com.android.cts.widget.R.raw.testimage, actualBitmap.getConfig());
+                    android.widget.cts.R.raw.testimage, actualBitmap.getConfig());
             WidgetTestUtils.assertEquals(testBitmap, actualBitmap);
         } finally {
             SimpleCursorAdapterTest.destroyTestImage(mContext,"testimage");
diff --git a/tests/tests/widget/src/android/widget/cts/SimpleCursorAdapterTest.java b/tests/tests/widget/src/android/widget/cts/SimpleCursorAdapterTest.java
index 13184de..469e581 100644
--- a/tests/tests/widget/src/android/widget/cts/SimpleCursorAdapterTest.java
+++ b/tests/tests/widget/src/android/widget/cts/SimpleCursorAdapterTest.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 
 import android.content.Context;
@@ -185,7 +185,7 @@
     public void testSetViewImage() {
         SimpleCursorAdapter simpleCursorAdapter = makeSimpleCursorAdapter();
         // resId
-        int sceneryImgResId = com.android.cts.widget.R.drawable.scenery;
+        int sceneryImgResId = android.widget.cts.R.drawable.scenery;
         ImageView view = new ImageView(mContext);
         assertNull(view.getDrawable());
         simpleCursorAdapter.setViewImage(view, String.valueOf(sceneryImgResId));
@@ -216,7 +216,7 @@
         view = new ImageView(mContext);
         assertNull(view.getDrawable());
         try {
-            int testimgRawId = com.android.cts.widget.R.raw.testimage;
+            int testimgRawId = android.widget.cts.R.raw.testimage;
             simpleCursorAdapter.setViewImage(view,
                     createTestImage(mContext, SAMPLE_IMAGE_NAME, testimgRawId));
             assertNotNull(view.getDrawable());
@@ -327,7 +327,7 @@
         LayoutInflater layoutInflater = (LayoutInflater) mContext.getSystemService(
                 Context.LAYOUT_INFLATER_SERVICE);
         ViewGroup viewGroup = (ViewGroup) layoutInflater.inflate(
-                com.android.cts.widget.R.layout.cursoradapter_host, null);
+                android.widget.cts.R.layout.cursoradapter_host, null);
         View result = simpleCursorAdapter.newView(mContext, null, viewGroup);
         assertNotNull(result);
         assertEquals(R.id.cursorAdapter_item0, result.getId());
@@ -343,7 +343,7 @@
         LayoutInflater layoutInflater = (LayoutInflater) mContext.getSystemService(
                 Context.LAYOUT_INFLATER_SERVICE);
         ViewGroup viewGroup = (ViewGroup) layoutInflater.inflate(
-                com.android.cts.widget.R.layout.cursoradapter_host, null);
+                android.widget.cts.R.layout.cursoradapter_host, null);
         View result = simpleCursorAdapter.newDropDownView(null, null, viewGroup);
         assertNotNull(result);
         assertEquals(R.id.cursorAdapter_item0, result.getId());
@@ -436,7 +436,7 @@
 
         try {
             source = context.getResources().openRawResource(resId);
-            target = context.openFileOutput(fileName, Context.MODE_WORLD_WRITEABLE);
+            target = context.openFileOutput(fileName, Context.MODE_PRIVATE);
 
             byte[] buffer = new byte[1024];
             for (int len = source.read(buffer); len > 0; len = source.read(buffer)) {
diff --git a/tests/tests/widget/src/android/widget/cts/SimpleCursorTreeAdapterTest.java b/tests/tests/widget/src/android/widget/cts/SimpleCursorTreeAdapterTest.java
index c9fdbc3..02941fa 100644
--- a/tests/tests/widget/src/android/widget/cts/SimpleCursorTreeAdapterTest.java
+++ b/tests/tests/widget/src/android/widget/cts/SimpleCursorTreeAdapterTest.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 
 import android.content.Context;
@@ -136,9 +136,9 @@
         ImageView view = new ImageView(mContext);
         assertNull(view.getDrawable());
         mSimpleCursorTreeAdapter.setViewImage(view,
-                String.valueOf(com.android.cts.widget.R.drawable.scenery));
+                String.valueOf(android.widget.cts.R.drawable.scenery));
         BitmapDrawable d = (BitmapDrawable) mContext.getResources().getDrawable(
-                com.android.cts.widget.R.drawable.scenery);
+                android.widget.cts.R.drawable.scenery);
         WidgetTestUtils.assertEquals(d.getBitmap(),
                 ((BitmapDrawable) view.getDrawable()).getBitmap());
 
@@ -164,10 +164,10 @@
         try {
             mSimpleCursorTreeAdapter.setViewImage(view,
                     SimpleCursorAdapterTest.createTestImage(mContext, SAMPLE_IMAGE_NAME,
-                            com.android.cts.widget.R.raw.testimage));
+                            android.widget.cts.R.raw.testimage));
             Bitmap actualBitmap = ((BitmapDrawable) view.getDrawable()).getBitmap();
             Bitmap test = WidgetTestUtils.getUnscaledAndDitheredBitmap(mContext.getResources(),
-                    com.android.cts.widget.R.raw.testimage, actualBitmap.getConfig());
+                    android.widget.cts.R.raw.testimage, actualBitmap.getConfig());
             WidgetTestUtils.assertEquals(test, actualBitmap);
         } finally {
             SimpleCursorAdapterTest.destroyTestImage(mContext, SAMPLE_IMAGE_NAME);
diff --git a/tests/tests/widget/src/android/widget/cts/SimpleExpandableListAdapterTest.java b/tests/tests/widget/src/android/widget/cts/SimpleExpandableListAdapterTest.java
index d1c63c0..674f427 100644
--- a/tests/tests/widget/src/android/widget/cts/SimpleExpandableListAdapterTest.java
+++ b/tests/tests/widget/src/android/widget/cts/SimpleExpandableListAdapterTest.java
@@ -98,7 +98,7 @@
 
         mAdapterHost = (LinearLayout) ((LayoutInflater) mContext
                 .getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(
-                com.android.cts.widget.R.layout.cursoradapter_host, null);
+                android.widget.cts.R.layout.cursoradapter_host, null);
     }
 
     public void testConstructor() {
diff --git a/tests/tests/widget/src/android/widget/cts/SlidingDrawerCtsActivity.java b/tests/tests/widget/src/android/widget/cts/SlidingDrawerCtsActivity.java
index 8b55e63..d1362c1 100644
--- a/tests/tests/widget/src/android/widget/cts/SlidingDrawerCtsActivity.java
+++ b/tests/tests/widget/src/android/widget/cts/SlidingDrawerCtsActivity.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 import android.app.Activity;
 import android.os.Bundle;
diff --git a/tests/tests/widget/src/android/widget/cts/SlidingDrawerTest.java b/tests/tests/widget/src/android/widget/cts/SlidingDrawerTest.java
index 862fccf..2af1b06 100644
--- a/tests/tests/widget/src/android/widget/cts/SlidingDrawerTest.java
+++ b/tests/tests/widget/src/android/widget/cts/SlidingDrawerTest.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 
 import org.xmlpull.v1.XmlPullParser;
@@ -51,7 +51,7 @@
     private Object mLock;
 
     public SlidingDrawerTest() {
-        super("com.android.cts.widget", SlidingDrawerCtsActivity.class);
+        super("android.widget.cts", SlidingDrawerCtsActivity.class);
     }
 
     @Override
diff --git a/tests/tests/widget/src/android/widget/cts/SpinnerTest.java b/tests/tests/widget/src/android/widget/cts/SpinnerTest.java
index ea37470..eea1e3e 100644
--- a/tests/tests/widget/src/android/widget/cts/SpinnerTest.java
+++ b/tests/tests/widget/src/android/widget/cts/SpinnerTest.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 
 import android.app.AlertDialog;
@@ -37,7 +37,7 @@
     private Context mTargetContext;
 
     public SpinnerTest() {
-        super("com.android.cts.widget", RelativeLayoutCtsActivity.class);
+        super("android.widget.cts", RelativeLayoutCtsActivity.class);
     }
 
     @Override
@@ -77,7 +77,7 @@
 
         spinner = (Spinner) getActivity().findViewById(R.id.spinner1);
         ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(mTargetContext,
-                com.android.cts.widget.R.array.string, android.R.layout.simple_spinner_item);
+                android.widget.cts.R.array.string, android.R.layout.simple_spinner_item);
         adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
         spinner.setAdapter(adapter);
         assertTrue(spinner.getBaseline() > 0);
diff --git a/tests/tests/widget/src/android/widget/cts/SwitchCtsActivity.java b/tests/tests/widget/src/android/widget/cts/SwitchCtsActivity.java
new file mode 100644
index 0000000..7be5831
--- /dev/null
+++ b/tests/tests/widget/src/android/widget/cts/SwitchCtsActivity.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.widget.cts;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.Switch;
+import android.widget.cts.R;
+
+/**
+ * A minimal application for {@link Switch} test.
+ */
+public class SwitchCtsActivity extends Activity {
+    /**
+     * Called with the activity is first created.
+     */
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.switch_layout);
+    }
+}
diff --git a/tests/tests/widget/src/android/widget/cts/SwitchTest.java b/tests/tests/widget/src/android/widget/cts/SwitchTest.java
index 164e7bf..216b17b 100644
--- a/tests/tests/widget/src/android/widget/cts/SwitchTest.java
+++ b/tests/tests/widget/src/android/widget/cts/SwitchTest.java
@@ -16,65 +16,71 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
-
-import android.content.Context;
+import android.app.Activity;
 import android.content.res.ColorStateList;
-import android.content.res.XmlResourceParser;
-import android.cts.util.WidgetTestUtils;
 import android.graphics.Color;
 import android.graphics.PorterDuff.Mode;
-import android.test.AndroidTestCase;
-import android.util.Xml;
+import android.test.ActivityInstrumentationTestCase;
+import android.test.UiThreadTest;
+import android.test.suitebuilder.annotation.SmallTest;
 import android.widget.Switch;
+import org.xmlpull.v1.XmlPullParserException;
 
 import java.io.IOException;
-import org.xmlpull.v1.XmlPullParserException;
 
 /**
  * Test {@link Switch}.
  */
-public class SwitchTest extends AndroidTestCase {
-    public void testConstructor() throws XmlPullParserException, IOException {
-        new Switch(mContext);
+@SmallTest
+public class SwitchTest extends ActivityInstrumentationTestCase<SwitchCtsActivity> {
+    private Activity mActivity;
+    private Switch mSwitch;
 
-        XmlResourceParser parser = mContext.getResources().getLayout(R.layout.switch_layout);
-        WidgetTestUtils.beginDocument(parser, "Switch");
-
-        new Switch(mContext, parser);
-
-        new Switch(mContext, parser, 0);
-
-        new Switch(mContext, parser, 0, 0);
+    public SwitchTest() {
+        super("android.widget.cts", SwitchCtsActivity.class);
     }
 
-    public void testAccessThumbTint() throws XmlPullParserException, IOException {
-        XmlResourceParser parser = mContext.getResources().getLayout(R.layout.switch_layout);
-        WidgetTestUtils.beginDocument(parser, "Switch");
-        Switch aSwitch = new Switch(mContext, parser);
-        assertEquals(Color.WHITE, aSwitch.getThumbTintList().getDefaultColor());
-        assertEquals(Mode.SRC_OVER, aSwitch.getThumbTintMode());
-
-        ColorStateList colors = ColorStateList.valueOf(Color.RED);
-        aSwitch.setThumbTintList(colors);
-        aSwitch.setThumbTintMode(Mode.XOR);
-
-        assertSame(colors, aSwitch.getThumbTintList());
-        assertEquals(Mode.XOR, aSwitch.getThumbTintMode());
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mActivity = getActivity();
+        mSwitch = (Switch) mActivity.findViewById(R.id.switch_view);
     }
 
-    public void testAccessTrackTint() throws XmlPullParserException, IOException {
-        XmlResourceParser parser = mContext.getResources().getLayout(R.layout.switch_layout);
-        WidgetTestUtils.beginDocument(parser, "Switch");
-        Switch aSwitch = new Switch(mContext, parser);
-        assertEquals(Color.BLACK, aSwitch.getTrackTintList().getDefaultColor());
-        assertEquals(Mode.SRC_ATOP, aSwitch.getTrackTintMode());
+    @UiThreadTest
+    public void testConstructor() {
+        new Switch(mActivity);
+
+        new Switch(mActivity, null);
+
+        new Switch(mActivity, null, android.R.attr.switchStyle);
+
+        new Switch(mActivity, null, 0, android.R.style.Widget_Material_Light_CompoundButton_Switch);
+    }
+
+    @UiThreadTest
+    public void testAccessThumbTint() {
+        assertEquals(Color.WHITE, mSwitch.getThumbTintList().getDefaultColor());
+        assertEquals(Mode.SRC_OVER, mSwitch.getThumbTintMode());
 
         ColorStateList colors = ColorStateList.valueOf(Color.RED);
-        aSwitch.setTrackTintList(colors);
-        aSwitch.setTrackTintMode(Mode.XOR);
+        mSwitch.setThumbTintList(colors);
+        mSwitch.setThumbTintMode(Mode.XOR);
 
-        assertSame(colors, aSwitch.getTrackTintList());
-        assertEquals(Mode.XOR, aSwitch.getTrackTintMode());
+        assertSame(colors, mSwitch.getThumbTintList());
+        assertEquals(Mode.XOR, mSwitch.getThumbTintMode());
+    }
+
+    @UiThreadTest
+    public void testAccessTrackTint() {
+        assertEquals(Color.BLACK, mSwitch.getTrackTintList().getDefaultColor());
+        assertEquals(Mode.SRC_ATOP, mSwitch.getTrackTintMode());
+
+        ColorStateList colors = ColorStateList.valueOf(Color.RED);
+        mSwitch.setTrackTintList(colors);
+        mSwitch.setTrackTintMode(Mode.XOR);
+
+        assertSame(colors, mSwitch.getTrackTintList());
+        assertEquals(Mode.XOR, mSwitch.getTrackTintMode());
     }
 }
diff --git a/tests/tests/widget/src/android/widget/cts/TabHostCtsActivity.java b/tests/tests/widget/src/android/widget/cts/TabHostCtsActivity.java
index 9703dd7..189dbee 100644
--- a/tests/tests/widget/src/android/widget/cts/TabHostCtsActivity.java
+++ b/tests/tests/widget/src/android/widget/cts/TabHostCtsActivity.java
@@ -22,7 +22,7 @@
 import android.widget.TabHost;
 import android.widget.TextView;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 /**
  * A minimal application for TabHost test.
diff --git a/tests/tests/widget/src/android/widget/cts/TabHostTest.java b/tests/tests/widget/src/android/widget/cts/TabHostTest.java
index 00ecd40..8756687 100644
--- a/tests/tests/widget/src/android/widget/cts/TabHostTest.java
+++ b/tests/tests/widget/src/android/widget/cts/TabHostTest.java
@@ -16,25 +16,26 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
-
-
 import android.app.Activity;
 import android.app.ActivityGroup;
 import android.content.Intent;
 import android.cts.util.WidgetTestUtils;
 import android.test.ActivityInstrumentationTestCase2;
 import android.test.UiThreadTest;
+import android.test.suitebuilder.annotation.SmallTest;
 import android.view.View;
 import android.widget.ListView;
 import android.widget.TabHost;
-import android.widget.TextView;
 import android.widget.TabHost.OnTabChangeListener;
 import android.widget.TabHost.TabSpec;
+import android.widget.TextView;
+
+import static org.mockito.Mockito.*;
 
 /**
  * Test {@link TabHost}.
  */
+@SmallTest
 public class TabHostTest extends ActivityInstrumentationTestCase2<TabHostCtsActivity> {
     private static final String TAG_TAB1 = "tab 1";
     private static final String TAG_TAB2 = "tab 2";
@@ -43,7 +44,7 @@
     private TabHostCtsActivity mActivity;
 
     public TabHostTest() {
-        super("com.android.cts.widget", TabHostCtsActivity.class);
+        super("android.widget.cts", TabHostCtsActivity.class);
     }
 
     @Override
@@ -72,7 +73,7 @@
      * 2. no exception occurs when doing normal operation after setup().
      */
     public void testSetup1() throws Throwable {
-        final Activity activity = launchActivity("com.android.cts.widget", CtsActivity.class, null);
+        final Activity activity = launchActivity("android.widget.cts", CtsActivity.class, null);
 
         runTestOnUiThread(new Runnable() {
             public void run() {
@@ -103,7 +104,7 @@
      * 2. no exception occurs when uses TabSpec.setContent(android.content.Intent) after setup().
      */
     public void testSetup2() throws Throwable {
-        final ActivityGroup activity = launchActivity("com.android.cts.widget",
+        final ActivityGroup activity = launchActivity("android.widget.cts",
                 ActivityGroup.class, null);
 
 
@@ -182,18 +183,12 @@
         assertEquals(0, tabHost.getCurrentTab());
         assertNotNull(tabHost.getCurrentView());
 
-        /*
-        TODO: Uncomment after fixing clearAllTabs() issue.
-        The code below throws a NullPointerException in clearAllTabs(). The method throwing the
-        exception is TabWidget.onFocusChange().
-
         tabHost.clearAllTabs();
 
         assertEquals(0, tabHost.getTabWidget().getChildCount());
         assertEquals(0, tabHost.getTabContentView().getChildCount());
         assertEquals(-1, tabHost.getCurrentTab());
         assertNull(tabHost.getCurrentView());
-        */
     }
 
     public void testGetTabWidget() {
@@ -334,25 +329,23 @@
         TabHost tabHost = mActivity.getTabHost();
 
         // add a tab, and change current tab to the new tab
-        MockOnTabChangeListener listener = new MockOnTabChangeListener();
-        tabHost.setOnTabChangedListener(listener);
+        OnTabChangeListener mockTabChangeListener = mock(OnTabChangeListener.class);
+        tabHost.setOnTabChangedListener(mockTabChangeListener);
 
         TabSpec tabSpec = tabHost.newTabSpec(TAG_TAB2);
         tabSpec.setIndicator(TAG_TAB2);
         tabSpec.setContent(new MyTabContentFactoryList());
         tabHost.addTab(tabSpec);
         tabHost.setCurrentTab(1);
-        assertTrue(listener.hasCalledOnTabChanged());
+        verify(mockTabChangeListener, times(1)).onTabChanged(TAG_TAB2);
 
         // change current tab to the first one
-        listener.reset();
         tabHost.setCurrentTab(0);
-        assertTrue(listener.hasCalledOnTabChanged());
+        verify(mockTabChangeListener, times(1)).onTabChanged(TabHostCtsActivity.INITIAL_TAB_TAG);
 
         // set the same tab
-        listener.reset();
         tabHost.setCurrentTab(0);
-        assertFalse(listener.hasCalledOnTabChanged());
+        verifyNoMoreInteractions(mockTabChangeListener);
     }
 
     @UiThreadTest
@@ -387,21 +380,4 @@
             return lv;
         }
     }
-
-    private class MockOnTabChangeListener implements OnTabChangeListener {
-        private boolean mCalledOnTabChanged = false;
-
-        boolean hasCalledOnTabChanged() {
-            return mCalledOnTabChanged;
-        }
-
-        void reset() {
-            mCalledOnTabChanged = false;
-        }
-
-        public void onTabChanged(String tabId) {
-            mCalledOnTabChanged = true;
-        }
-    }
-
 }
diff --git a/tests/tests/widget/src/android/widget/cts/TabHost_TabSpecTest.java b/tests/tests/widget/src/android/widget/cts/TabHost_TabSpecTest.java
index 5745808..e8825c7 100644
--- a/tests/tests/widget/src/android/widget/cts/TabHost_TabSpecTest.java
+++ b/tests/tests/widget/src/android/widget/cts/TabHost_TabSpecTest.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 
 import android.app.Activity;
@@ -46,7 +46,7 @@
     private TabHostCtsActivity mActivity;
 
     public TabHost_TabSpecTest() {
-        super("com.android.cts.widget", TabHostCtsActivity.class);
+        super("android.widget.cts", TabHostCtsActivity.class);
     }
 
     @Override
@@ -137,7 +137,7 @@
         TabSpec tabSpec2 = mTabHost.newTabSpec("tab spec 2");
         tabSpec2.setIndicator("tab 2");
         // TabContentFactory to create a TextView as the content of the tab.
-        tabSpec2.setContent(com.android.cts.widget.R.id.tabhost_textview);
+        tabSpec2.setContent(android.widget.cts.R.id.tabhost_textview);
         mTabHost.addTab(tabSpec2);
         mTabHost.setCurrentTab(1);
         TextView currentView = (TextView) mTabHost.getCurrentView();
@@ -147,7 +147,7 @@
         TabSpec tabSpec3 = mTabHost.newTabSpec("tab spec 3");
         tabSpec3.setIndicator("tab 3");
         // TabContentFactory to create a ListView as the content of the tab.
-        tabSpec3.setContent(com.android.cts.widget.R.id.tabhost_listview);
+        tabSpec3.setContent(android.widget.cts.R.id.tabhost_listview);
         mTabHost.addTab(tabSpec3);
         mTabHost.setCurrentTab(2);
         assertTrue(mTabHost.getCurrentView() instanceof ListView);
diff --git a/tests/tests/widget/src/android/widget/cts/TabWidgetTest.java b/tests/tests/widget/src/android/widget/cts/TabWidgetTest.java
index 1f2e66c..58fbf46 100644
--- a/tests/tests/widget/src/android/widget/cts/TabWidgetTest.java
+++ b/tests/tests/widget/src/android/widget/cts/TabWidgetTest.java
@@ -19,24 +19,29 @@
 
 import android.app.Activity;
 import android.content.Context;
+import android.graphics.drawable.Drawable;
 import android.test.ActivityInstrumentationTestCase2;
 import android.test.UiThreadTest;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.view.LayoutInflater;
 import android.view.View;
 import android.widget.LinearLayout;
+import android.widget.LinearLayout.LayoutParams;
 import android.widget.ListView;
 import android.widget.RelativeLayout;
 import android.widget.TabWidget;
 import android.widget.TextView;
-import android.widget.LinearLayout.LayoutParams;
+import android.widget.cts.util.TestUtils;
 
 /**
  * Test {@link TabWidget}.
  */
+@SmallTest
 public class TabWidgetTest extends ActivityInstrumentationTestCase2<TabHostCtsActivity> {
     private Activity mActivity;
 
     public TabWidgetTest() {
-        super("com.android.cts.widget", TabHostCtsActivity.class);
+        super("android.widget.cts", TabHostCtsActivity.class);
     }
 
     @Override
@@ -53,6 +58,76 @@
         new TabWidget(mActivity, null, 0);
     }
 
+    public void testConstructorWithStyle() {
+        TabWidget tabWidget = new TabWidget(mActivity, null, 0, R.style.TabWidgetCustomStyle);
+
+        assertFalse(tabWidget.isStripEnabled());
+
+        Drawable leftStripDrawable = tabWidget.getLeftStripDrawable();
+        assertNotNull(leftStripDrawable);
+        TestUtils.assertAllPixelsOfColor("Left strip green", leftStripDrawable,
+                leftStripDrawable.getIntrinsicWidth(), leftStripDrawable.getIntrinsicHeight(),
+                true, 0xFF00FF00, 1, false);
+
+        Drawable rightStripDrawable = tabWidget.getRightStripDrawable();
+        assertNotNull(rightStripDrawable);
+        TestUtils.assertAllPixelsOfColor("Right strip red", rightStripDrawable,
+                rightStripDrawable.getIntrinsicWidth(), rightStripDrawable.getIntrinsicHeight(),
+                true, 0xFFFF0000, 1, false);
+    }
+
+    public void testInflateFromXml() {
+        LayoutInflater inflater = LayoutInflater.from(mActivity);
+        TabWidget tabWidget = (TabWidget) inflater.inflate(R.layout.tabhost_custom, null, false);
+
+        assertFalse(tabWidget.isStripEnabled());
+
+        Drawable leftStripDrawable = tabWidget.getLeftStripDrawable();
+        assertNotNull(leftStripDrawable);
+        TestUtils.assertAllPixelsOfColor("Left strip red", leftStripDrawable,
+                leftStripDrawable.getIntrinsicWidth(), leftStripDrawable.getIntrinsicHeight(),
+                true, 0xFFFF0000, 1, false);
+
+        Drawable rightStripDrawable = tabWidget.getRightStripDrawable();
+        assertNotNull(rightStripDrawable);
+        TestUtils.assertAllPixelsOfColor("Right strip green", rightStripDrawable,
+                rightStripDrawable.getIntrinsicWidth(), rightStripDrawable.getIntrinsicHeight(),
+                true, 0xFF00FF00, 1, false);
+    }
+
+    @UiThreadTest
+    public void testTabCount() {
+        TabHostCtsActivity activity = getActivity();
+        TabWidget tabWidget = activity.getTabWidget();
+
+        // We have one tab added in onCreate() of our activity
+        assertEquals(1, tabWidget.getTabCount());
+
+        for (int i = 1; i < 10; i++) {
+            tabWidget.addView(new TextView(mActivity));
+            assertEquals(i + 1, tabWidget.getTabCount());
+        }
+    }
+
+    @UiThreadTest
+    public void testTabViews() {
+        TabHostCtsActivity activity = getActivity();
+        TabWidget tabWidget = activity.getTabWidget();
+
+        // We have one tab added in onCreate() of our activity. We "reach" into the default tab
+        // indicator layout in the same way we do in TabHost_TabSpecTest tests.
+        TextView tab0 = (TextView) tabWidget.getChildTabViewAt(0).findViewById(android.R.id.title);
+        assertNotNull(tab0);
+        assertEquals(TabHostCtsActivity.INITIAL_TAB_LABEL, tab0.getText());
+
+        for (int i = 1; i < 10; i++) {
+            TextView toAdd = new TextView(mActivity);
+            toAdd.setText("Tab #" + i);
+            tabWidget.addView(toAdd);
+            assertEquals(toAdd, tabWidget.getChildTabViewAt(i));
+        }
+    }
+
     public void testChildDrawableStateChanged() {
         MockTabWidget mockTabWidget = new MockTabWidget(mActivity);
         TextView tv0 = new TextView(mActivity);
@@ -138,8 +213,11 @@
         }
     }
 
+    @UiThreadTest
     public void testSetEnabled() {
-        TabWidget tabWidget = new TabWidget(mActivity);
+        TabHostCtsActivity activity = getActivity();
+        TabWidget tabWidget = activity.getTabWidget();
+
         tabWidget.addView(new TextView(mActivity));
         tabWidget.addView(new TextView(mActivity));
         assertTrue(tabWidget.isEnabled());
@@ -194,6 +272,78 @@
         }
     }
 
+    @UiThreadTest
+    public void testStripEnabled() {
+        TabHostCtsActivity activity = getActivity();
+        TabWidget tabWidget = activity.getTabWidget();
+
+        tabWidget.setStripEnabled(true);
+        assertTrue(tabWidget.isStripEnabled());
+
+        tabWidget.setStripEnabled(false);
+        assertFalse(tabWidget.isStripEnabled());
+    }
+
+    @UiThreadTest
+    public void testStripDrawables() {
+        TabHostCtsActivity activity = getActivity();
+        TabWidget tabWidget = activity.getTabWidget();
+
+        // Test setting left strip drawable
+        tabWidget.setLeftStripDrawable(R.drawable.icon_green);
+        Drawable leftStripDrawable = tabWidget.getLeftStripDrawable();
+        assertNotNull(leftStripDrawable);
+        TestUtils.assertAllPixelsOfColor("Left strip green", leftStripDrawable,
+                leftStripDrawable.getIntrinsicWidth(), leftStripDrawable.getIntrinsicHeight(),
+                true, 0xFF00FF00, 1, false);
+
+        tabWidget.setLeftStripDrawable(activity.getResources().getDrawable(
+                R.drawable.icon_red, null));
+        leftStripDrawable = tabWidget.getLeftStripDrawable();
+        assertNotNull(leftStripDrawable);
+        TestUtils.assertAllPixelsOfColor("Left strip red", leftStripDrawable,
+                leftStripDrawable.getIntrinsicWidth(), leftStripDrawable.getIntrinsicHeight(),
+                true, 0xFFFF0000, 1, false);
+
+        // Test setting right strip drawable
+        tabWidget.setRightStripDrawable(R.drawable.icon_red);
+        Drawable rightStripDrawable = tabWidget.getRightStripDrawable();
+        assertNotNull(rightStripDrawable);
+        TestUtils.assertAllPixelsOfColor("Right strip red", rightStripDrawable,
+                rightStripDrawable.getIntrinsicWidth(), rightStripDrawable.getIntrinsicHeight(),
+                true, 0xFFFF0000, 1, false);
+
+        tabWidget.setRightStripDrawable(activity.getResources().getDrawable(
+                R.drawable.icon_green, null));
+        rightStripDrawable = tabWidget.getRightStripDrawable();
+        assertNotNull(rightStripDrawable);
+        TestUtils.assertAllPixelsOfColor("Left strip green", rightStripDrawable,
+                rightStripDrawable.getIntrinsicWidth(), rightStripDrawable.getIntrinsicHeight(),
+                true, 0xFF00FF00, 1, false);
+    }
+
+    @UiThreadTest
+    public void testDividerDrawables() {
+        TabHostCtsActivity activity = getActivity();
+        TabWidget tabWidget = activity.getTabWidget();
+
+        tabWidget.setDividerDrawable(R.drawable.icon_blue);
+        Drawable dividerDrawable = tabWidget.getDividerDrawable();
+        assertNotNull(dividerDrawable);
+        TestUtils.assertAllPixelsOfColor("Divider blue", dividerDrawable,
+                dividerDrawable.getIntrinsicWidth(), dividerDrawable.getIntrinsicHeight(),
+                true, 0xFF0000FF, 1, false);
+
+        tabWidget.setDividerDrawable(activity.getResources().getDrawable(
+                R.drawable.icon_yellow, null));
+        dividerDrawable = tabWidget.getDividerDrawable();
+        assertNotNull(dividerDrawable);
+        TestUtils.assertAllPixelsOfColor("Divider yellow", dividerDrawable,
+                dividerDrawable.getIntrinsicWidth(), dividerDrawable.getIntrinsicHeight(),
+                true, 0xFFFFFF00, 1, false);
+
+    }
+
     public void testOnFocusChange() {
         // onFocusChange() is implementation details, do NOT test
     }
diff --git a/tests/tests/widget/src/android/widget/cts/TableCtsActivity.java b/tests/tests/widget/src/android/widget/cts/TableCtsActivity.java
index f76caed..490d261 100644
--- a/tests/tests/widget/src/android/widget/cts/TableCtsActivity.java
+++ b/tests/tests/widget/src/android/widget/cts/TableCtsActivity.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 import android.app.Activity;
 import android.os.Bundle;
diff --git a/tests/tests/widget/src/android/widget/cts/TableLayoutTest.java b/tests/tests/widget/src/android/widget/cts/TableLayoutTest.java
index b9f0d1f..ccf22d9 100644
--- a/tests/tests/widget/src/android/widget/cts/TableLayoutTest.java
+++ b/tests/tests/widget/src/android/widget/cts/TableLayoutTest.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 import android.content.Context;
 import android.content.res.XmlResourceParser;
@@ -42,7 +42,7 @@
     private Context mContext;
 
     public TableLayoutTest() {
-        super("com.android.cts.widget", TableCtsActivity.class);
+        super("android.widget.cts", TableCtsActivity.class);
     }
 
     @Override
@@ -58,14 +58,14 @@
         new TableLayout(mContext, null);
 
         TableCtsActivity activity = getActivity();
-        activity.setContentView(com.android.cts.widget.R.layout.table_layout_1);
+        activity.setContentView(android.widget.cts.R.layout.table_layout_1);
         TableLayout tableLayout = (TableLayout) activity
-                .findViewById(com.android.cts.widget.R.id.table1);
+                .findViewById(android.widget.cts.R.id.table1);
         assertTrue(tableLayout.isColumnCollapsed(0));
         assertTrue(tableLayout.isColumnStretchable(2));
 
-        activity.setContentView(com.android.cts.widget.R.layout.table_layout_2);
-        tableLayout = (TableLayout) activity.findViewById(com.android.cts.widget.R.id.table2);
+        activity.setContentView(android.widget.cts.R.layout.table_layout_2);
+        tableLayout = (TableLayout) activity.findViewById(android.widget.cts.R.id.table2);
         assertTrue(tableLayout.isColumnShrinkable(1));
     }
 
@@ -205,12 +205,12 @@
         final TableCtsActivity activity = getActivity();
         getInstrumentation().runOnMainSync(new Runnable() {
             public void run() {
-                activity.setContentView(com.android.cts.widget.R.layout.table_layout_1);
+                activity.setContentView(android.widget.cts.R.layout.table_layout_1);
             }
         });
         getInstrumentation().waitForIdleSync();
         final TableLayout tableLayout =
-                (TableLayout) activity.findViewById(com.android.cts.widget.R.id.table1);
+                (TableLayout) activity.findViewById(android.widget.cts.R.id.table1);
 
         // Preparation: remove Collapsed mark for column 0.
         getInstrumentation().runOnMainSync(new Runnable() {
diff --git a/tests/tests/widget/src/android/widget/cts/TableLayout_LayoutParamsTest.java b/tests/tests/widget/src/android/widget/cts/TableLayout_LayoutParamsTest.java
index cbc41ce..fbd9f97 100644
--- a/tests/tests/widget/src/android/widget/cts/TableLayout_LayoutParamsTest.java
+++ b/tests/tests/widget/src/android/widget/cts/TableLayout_LayoutParamsTest.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 import org.xmlpull.v1.XmlPullParser;
 
diff --git a/tests/tests/widget/src/android/widget/cts/TableRowTest.java b/tests/tests/widget/src/android/widget/cts/TableRowTest.java
index 6012f59..2e917f8 100644
--- a/tests/tests/widget/src/android/widget/cts/TableRowTest.java
+++ b/tests/tests/widget/src/android/widget/cts/TableRowTest.java
@@ -33,7 +33,7 @@
 import android.widget.TableRow;
 import android.widget.TextView;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 
 /**
@@ -44,7 +44,7 @@
     Context mTargetContext;
 
     public TableRowTest() {
-        super("com.android.cts.widget", TableCtsActivity.class);
+        super("android.widget.cts", TableCtsActivity.class);
     }
 
     @Override
@@ -83,9 +83,9 @@
     @UiThreadTest
     public void testGetVirtualChildAt() {
         TableCtsActivity activity = getActivity();
-        activity.setContentView(com.android.cts.widget.R.layout.table_layout_1);
+        activity.setContentView(android.widget.cts.R.layout.table_layout_1);
         TableLayout tableLayout = (TableLayout) activity
-                .findViewById(com.android.cts.widget.R.id.table1);
+                .findViewById(android.widget.cts.R.id.table1);
 
         TableRow tableRow = (TableRow) tableLayout.getChildAt(0);
         Resources resources = activity.getResources();
@@ -96,8 +96,8 @@
         assertEquals(resources.getString(R.string.table_layout_third),
                 ((TextView) tableRow.getVirtualChildAt(2)).getText().toString());
 
-        activity.setContentView(com.android.cts.widget.R.layout.table_layout_2);
-        tableLayout = (TableLayout) activity.findViewById(com.android.cts.widget.R.id.table2);
+        activity.setContentView(android.widget.cts.R.layout.table_layout_2);
+        tableLayout = (TableLayout) activity.findViewById(android.widget.cts.R.id.table2);
 
         tableRow = (TableRow) tableLayout.getChildAt(0);
         assertNull(tableRow.getVirtualChildAt(0));
@@ -114,15 +114,15 @@
     @UiThreadTest
     public void testGetVirtualChildCount() {
         TableCtsActivity activity = getActivity();
-        activity.setContentView(com.android.cts.widget.R.layout.table_layout_1);
+        activity.setContentView(android.widget.cts.R.layout.table_layout_1);
         TableLayout tableLayout = (TableLayout) activity
-                .findViewById(com.android.cts.widget.R.id.table1);
+                .findViewById(android.widget.cts.R.id.table1);
 
         TableRow tableRow = (TableRow) tableLayout.getChildAt(0);
         assertEquals(3, tableRow.getVirtualChildCount());
 
-        activity.setContentView(com.android.cts.widget.R.layout.table_layout_2);
-        tableLayout = (TableLayout) activity.findViewById(com.android.cts.widget.R.id.table2);
+        activity.setContentView(android.widget.cts.R.layout.table_layout_2);
+        tableLayout = (TableLayout) activity.findViewById(android.widget.cts.R.id.table2);
 
         tableRow = (TableRow) tableLayout.getChildAt(0);
         assertEquals(5, tableRow.getVirtualChildCount());
diff --git a/tests/tests/widget/src/android/widget/cts/TableRow_LayoutParamsTest.java b/tests/tests/widget/src/android/widget/cts/TableRow_LayoutParamsTest.java
index 8308414..ce3be70 100644
--- a/tests/tests/widget/src/android/widget/cts/TableRow_LayoutParamsTest.java
+++ b/tests/tests/widget/src/android/widget/cts/TableRow_LayoutParamsTest.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 import org.xmlpull.v1.XmlPullParser;
 
@@ -42,7 +42,7 @@
     Context mTargetContext;
 
     public TableRow_LayoutParamsTest() {
-        super("com.android.cts.widget", TableCtsActivity.class);
+        super("android.widget.cts", TableCtsActivity.class);
     }
 
     @Override
diff --git a/tests/tests/widget/src/android/widget/cts/TextViewCtsActivity.java b/tests/tests/widget/src/android/widget/cts/TextViewCtsActivity.java
index 888f215..31fc486 100644
--- a/tests/tests/widget/src/android/widget/cts/TextViewCtsActivity.java
+++ b/tests/tests/widget/src/android/widget/cts/TextViewCtsActivity.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 import android.app.Activity;
 import android.os.Bundle;
diff --git a/tests/tests/widget/src/android/widget/cts/TextViewFadingEdgeTest.java b/tests/tests/widget/src/android/widget/cts/TextViewFadingEdgeTest.java
new file mode 100644
index 0000000..e627c2b
--- /dev/null
+++ b/tests/tests/widget/src/android/widget/cts/TextViewFadingEdgeTest.java
@@ -0,0 +1,215 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.widget.cts;
+
+import android.cts.util.PollingCheck;
+import android.test.ActivityInstrumentationTestCase2;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+
+import static android.view.Gravity.CENTER;
+import static android.view.Gravity.LEFT;
+import static android.view.Gravity.NO_GRAVITY;
+import static android.view.Gravity.RIGHT;
+import static android.view.View.TEXT_ALIGNMENT_INHERIT;
+import static android.widget.TextView.TEXT_ALIGNMENT_TEXT_START;
+import static android.widget.TextView.TEXT_ALIGNMENT_TEXT_END;
+import static android.widget.TextView.TEXT_ALIGNMENT_VIEW_START;
+import static android.widget.TextView.TEXT_ALIGNMENT_VIEW_END;
+
+public class TextViewFadingEdgeTest extends ActivityInstrumentationTestCase2<EmptyCtsActivity> {
+
+    public static final float DELTA = 0.01f;
+    private static final String LONG_RTL_STRING = "مرحبا الروبوت مرحبا الروبوت مرحبا الروبوت";
+    private static final String LONG_LTR_STRING = "start start1 middle middle1 end end1";
+    private static final String SHORT_RTL_STRING = "ت";
+    private static final String SHORT_LTR_STRING = "s";
+    public static final int ANY_PADDING = 15;
+    public static final int ANY_FADE_LENGTH = 60;
+
+    private static final TestCase[] TEST_DATA = {
+            // no fade - fading disabled
+            new TestCase("Should not fade when text:empty, fading:disabled",
+                    null, false, NO_GRAVITY, TEXT_ALIGNMENT_INHERIT, 0f, 0f),
+            new TestCase("Should not fade when text:short, dir:LTR, fading:disabled",
+                    SHORT_LTR_STRING, false, NO_GRAVITY, TEXT_ALIGNMENT_INHERIT, 0f, 0f),
+            new TestCase("Should not fade when text:short, dir:RTL, fading:disabled",
+                    SHORT_RTL_STRING, false, NO_GRAVITY, TEXT_ALIGNMENT_INHERIT, 0f, 0f),
+            new TestCase("Should not fade when text:long , dir:LTR, fading:disabled",
+                    LONG_LTR_STRING, false, NO_GRAVITY, TEXT_ALIGNMENT_INHERIT, 0f, 0f),
+            new TestCase("Should not fade when text:long , dir:RTL, fading:disabled",
+                    LONG_RTL_STRING, false, NO_GRAVITY, TEXT_ALIGNMENT_INHERIT, 0f, 0f),
+            new TestCase("Should not fade when text:long, dir:LTR, scroll:middle",
+                    LONG_LTR_STRING, false, NO_GRAVITY, TEXT_ALIGNMENT_INHERIT, true, 0f, 0f),
+            new TestCase("Should not fade when text:long, dir:RTL, scroll:middle",
+                    LONG_RTL_STRING, false, NO_GRAVITY, TEXT_ALIGNMENT_INHERIT, true, 0f, 0f),
+
+            // no fade - text is shorter than view width
+            new TestCase("Should not fade when text:empty",
+                    null, true, NO_GRAVITY, TEXT_ALIGNMENT_INHERIT, 0f, 0f),
+            new TestCase("Should not fade when text:short, dir:LTR",
+                    SHORT_LTR_STRING, true, NO_GRAVITY, TEXT_ALIGNMENT_INHERIT, 0f, 0f),
+            new TestCase("Should not fade when text:short, dir:LTR, gravity:center",
+                    SHORT_LTR_STRING, true, CENTER, TEXT_ALIGNMENT_INHERIT, 0f, 0f),
+            new TestCase("Should not fade when text:short, dir:RTL",
+                    SHORT_RTL_STRING, true, NO_GRAVITY, TEXT_ALIGNMENT_INHERIT, 0f, 0f),
+            new TestCase("Should not fade when text:short, dir:RTL, gravity:center",
+                    SHORT_RTL_STRING, true, CENTER, TEXT_ALIGNMENT_INHERIT, 0f, 0f),
+
+            // left fade - LTR
+            new TestCase("Should fade left when text:long, dir:LTR, gravity:right",
+                    LONG_LTR_STRING, true, RIGHT, TEXT_ALIGNMENT_INHERIT, 1f, 0f),
+            new TestCase("Should fade left when text:long, dir:LTR, textAlignment:textEnd",
+                    LONG_LTR_STRING, true, NO_GRAVITY, TEXT_ALIGNMENT_TEXT_END, 1f, 0f),
+            new TestCase("Should fade left when text:long, dir:LTR, textAlignment:viewEnd",
+                    LONG_LTR_STRING, true, NO_GRAVITY, TEXT_ALIGNMENT_VIEW_END, 1f, 0f),
+
+            // left fade - RTL
+            new TestCase("Should fade left when text:long, dir:RTL",
+                    LONG_RTL_STRING, true, NO_GRAVITY, TEXT_ALIGNMENT_INHERIT, 1f, 0f),
+            new TestCase("Should fade left when text:long, dir:RTL, gravity:right",
+                    LONG_RTL_STRING, true, RIGHT, TEXT_ALIGNMENT_INHERIT, 1f, 0f),
+            new TestCase("Should fade left when text:long, dir:RTL, textAlignment:textStart",
+                    LONG_RTL_STRING, true, NO_GRAVITY, TEXT_ALIGNMENT_TEXT_START, 1f, 0f),
+            new TestCase("Should fade left when text:long, dir:RTL, textAlignment:viewEnd",
+                    LONG_RTL_STRING, true, NO_GRAVITY, TEXT_ALIGNMENT_VIEW_END, 1f, 0f),
+
+            // right fade - LTR
+            new TestCase("Should fade right when text:long, dir:LTR",
+                    LONG_LTR_STRING, true, NO_GRAVITY, TEXT_ALIGNMENT_INHERIT, 0f, 1f),
+            new TestCase("Should fade right when text:long, dir:LTR, textAlignment:textStart",
+                    LONG_LTR_STRING, true, NO_GRAVITY, TEXT_ALIGNMENT_TEXT_START, 0f, 1f),
+            new TestCase("Should fade right when text:long, dir:LTR, gravity:left",
+                    LONG_LTR_STRING, true, LEFT, TEXT_ALIGNMENT_INHERIT, 0f, 1f),
+            new TestCase("Should fade right when text:long, dir:LTR, textAlignment:viewStart",
+                    LONG_LTR_STRING, true, NO_GRAVITY, TEXT_ALIGNMENT_VIEW_START, 0f, 1f),
+
+            // right fade - RTL
+            new TestCase("Should fade right when text:long, dir:RTL, gravity:left",
+                    LONG_RTL_STRING, true, LEFT, TEXT_ALIGNMENT_INHERIT, 0f, 1f),
+            new TestCase("Should fade right when text:long, dir:RTL, textAlignment:viewStart",
+                    LONG_RTL_STRING, true, NO_GRAVITY, TEXT_ALIGNMENT_VIEW_START, 0f, 1f),
+            new TestCase("Should fade right when text:long, dir:RTL, textAlignment:textEnd",
+                    LONG_RTL_STRING, true, NO_GRAVITY, TEXT_ALIGNMENT_TEXT_END, 0f, 1f),
+
+            // left and right fade
+            new TestCase("Should fade both when text:long, dir:LTR, scroll:middle",
+                    LONG_LTR_STRING, true, NO_GRAVITY, TEXT_ALIGNMENT_INHERIT, true, 1f, 1f),
+            new TestCase("Should fade both when text:long, dir:RTL, scroll:middle",
+                    LONG_RTL_STRING, true, NO_GRAVITY, TEXT_ALIGNMENT_INHERIT, true, 1f, 1f)
+    };
+
+    public TextViewFadingEdgeTest() {
+        super("android.widget.cts", EmptyCtsActivity.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        new PollingCheck() {
+            @Override
+            protected boolean check() {
+                return getActivity().hasWindowFocus();
+            }
+        }.run();
+    }
+
+    public void testFadingEdge() {
+        for (TestCase data : TEST_DATA) {
+            MockTextView textView = createTextView(data.text, data.horizontalFadingEnabled,
+                    data.gravity, data.textAlignment, data.scrollToMiddle);
+
+            assertEquals(data.errorMsg,
+                    data.expectationLeft, textView.getLeftFadingEdgeStrength(), DELTA);
+            assertEquals(data.errorMsg,
+                    data.expectationRight, textView.getRightFadingEdgeStrength(), DELTA);
+        }
+    }
+
+    private final MockTextView createTextView(String text, boolean horizontalFadingEnabled,
+            int gravity, int textAlignment, boolean scrollToMiddle) {
+        final MockTextView textView = new MockTextView(getActivity());
+        textView.setSingleLine(true);
+        textView.setTextSize(30);
+        textView.setPadding(ANY_PADDING, ANY_PADDING, ANY_PADDING, ANY_PADDING);
+        textView.setFadingEdgeLength(ANY_FADE_LENGTH);
+        textView.setLayoutParams(new ViewGroup.LayoutParams(300,
+                ViewGroup.LayoutParams.WRAP_CONTENT));
+        textView.setHorizontalFadingEdgeEnabled(horizontalFadingEnabled);
+        textView.setText(text);
+        textView.setGravity(gravity);
+        textView.setTextAlignment(textAlignment);
+
+        final FrameLayout layout = new FrameLayout(getActivity());
+        ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(
+                ViewGroup.LayoutParams.MATCH_PARENT,
+                ViewGroup.LayoutParams.MATCH_PARENT);
+        layout.setLayoutParams(layoutParams);
+        layout.addView(textView);
+
+        getActivity().runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                getActivity().setContentView(layout);
+            }
+        });
+        getInstrumentation().waitForIdleSync();
+        if(scrollToMiddle) {
+            getActivity().runOnUiThread(new Runnable() {
+                @Override
+                public void run() {
+                    float lineMid = (textView.getLayout().getLineLeft(0) +
+                            textView.getLayout().getLineRight(0)) / 2;
+                    int scrollPosition = (int) lineMid;
+                    textView.setScrollX(scrollPosition);
+                }
+            });
+        }
+        getInstrumentation().waitForIdleSync();
+        return textView;
+    }
+
+    private static class TestCase {
+        final String errorMsg;
+        final String text;
+        final boolean horizontalFadingEnabled;
+        final int gravity;
+        final int textAlignment;
+        final float expectationLeft;
+        final float expectationRight;
+        final boolean scrollToMiddle;
+
+        TestCase(String errorMsg, String text, boolean horizontalFadingEnabled, int gravity,
+                 int textAlignment, boolean scrollToMiddle, float expectationLeft,
+                 float expectationRight) {
+            this.errorMsg = errorMsg;
+            this.text = text;
+            this.horizontalFadingEnabled = horizontalFadingEnabled;
+            this.gravity = gravity;
+            this.textAlignment = textAlignment;
+            this.expectationLeft = expectationLeft;
+            this.expectationRight = expectationRight;
+            this.scrollToMiddle = scrollToMiddle;
+        }
+
+        TestCase(String errorMsg, String text, boolean horizontalFadingEnabled, int gravity,
+                 int textAlignment, float expectationLeft, float expectationRight) {
+            this(errorMsg, text, horizontalFadingEnabled, gravity, textAlignment, false,
+                    expectationLeft, expectationRight);
+        }
+    }
+}
diff --git a/tests/tests/widget/src/android/widget/cts/TextViewTest.java b/tests/tests/widget/src/android/widget/cts/TextViewTest.java
index 829171c..40d42a2 100644
--- a/tests/tests/widget/src/android/widget/cts/TextViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/TextViewTest.java
@@ -16,10 +16,6 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
-
-import org.xmlpull.v1.XmlPullParserException;
-
 import android.app.Activity;
 import android.app.Instrumentation;
 import android.app.Instrumentation.ActivityMonitor;
@@ -38,14 +34,16 @@
 import android.graphics.RectF;
 import android.graphics.Typeface;
 import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.Parcelable;
 import android.test.ActivityInstrumentationTestCase2;
-import android.test.MoreAsserts;
 import android.test.TouchUtils;
 import android.test.UiThreadTest;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.test.suitebuilder.annotation.SmallTest;
 import android.text.Editable;
 import android.text.InputFilter;
 import android.text.InputType;
@@ -53,6 +51,7 @@
 import android.text.Selection;
 import android.text.Spannable;
 import android.text.SpannableString;
+import android.text.Spanned;
 import android.text.TextPaint;
 import android.text.TextUtils;
 import android.text.TextUtils.TruncateAt;
@@ -72,13 +71,16 @@
 import android.text.method.TextKeyListener.Capitalize;
 import android.text.method.TimeKeyListener;
 import android.text.method.TransformationMethod;
+import android.text.style.ImageSpan;
 import android.text.style.URLSpan;
+import android.text.style.UnderlineSpan;
 import android.text.util.Linkify;
 import android.util.DisplayMetrics;
+import android.util.LocaleList;
 import android.util.TypedValue;
+import android.view.ActionMode;
 import android.view.ContextMenu;
 import android.view.ContextMenu.ContextMenuInfo;
-import android.view.ActionMode;
 import android.view.Gravity;
 import android.view.KeyEvent;
 import android.view.Menu;
@@ -101,6 +103,8 @@
 import android.widget.TextView.BufferType;
 import android.widget.TextView.OnEditorActionListener;
 
+import org.xmlpull.v1.XmlPullParserException;
+
 import java.io.IOException;
 import java.util.Locale;
 
@@ -121,7 +125,7 @@
     private CharSequence mTransformedText;
 
     public TextViewTest() {
-        super("com.android.cts.widget", TextViewCtsActivity.class);
+        super("android.widget.cts", TextViewCtsActivity.class);
     }
 
     @Override
@@ -820,6 +824,39 @@
         assertEquals(0, mTextView.getLineHeight());
     }
 
+    public void testSetElegantLineHeight() {
+        mTextView = findTextView(R.id.textview_text);
+        assertFalse(mTextView.getPaint().isElegantTextHeight());
+        mActivity.runOnUiThread(new Runnable() {
+            public void run() {
+                mTextView.setWidth(mTextView.getWidth() / 3);
+                mTextView.setPadding(1, 2, 3, 4);
+                mTextView.setGravity(Gravity.BOTTOM);
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+
+        int oldHeight = mTextView.getHeight();
+        mActivity.runOnUiThread(new Runnable() {
+            public void run() {
+                mTextView.setElegantTextHeight(true);
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+
+        assertTrue(mTextView.getPaint().isElegantTextHeight());
+        assertTrue(mTextView.getHeight() > oldHeight);
+
+        mActivity.runOnUiThread(new Runnable() {
+            public void run() {
+                mTextView.setElegantTextHeight(false);
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+        assertFalse(mTextView.getPaint().isElegantTextHeight());
+        assertTrue(mTextView.getHeight() == oldHeight);
+    }
+
     public void testInstanceState() {
         // Do not test. Implementation details.
     }
@@ -1266,6 +1303,99 @@
         }
     }
 
+    @MediumTest
+    public void testSetText_updatesHeightAfterRemovingImageSpan() {
+        // Height calculation had problems when TextView had width: match_parent
+        final int textViewWidth = ViewGroup.LayoutParams.MATCH_PARENT;
+        final Spannable text = new SpannableString("some text");
+        final int spanHeight = 100;
+
+        // prepare TextView, width: MATCH_PARENT
+        TextView textView = new TextView(getActivity());
+        textView.setSingleLine(true);
+        textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 2);
+        textView.setPadding(0, 0, 0, 0);
+        textView.setIncludeFontPadding(false);
+        textView.setText(text);
+        final FrameLayout layout = new FrameLayout(mActivity);
+        final ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(textViewWidth,
+                ViewGroup.LayoutParams.WRAP_CONTENT);
+        layout.addView(textView, layoutParams);
+        layout.setLayoutParams(layoutParams);
+        mActivity.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                getActivity().setContentView(layout);
+            }
+        });
+        getInstrumentation().waitForIdleSync();
+
+        // measure height of text with no span
+        final int heightWithoutSpan = textView.getHeight();
+        assertTrue("Text height should be smaller than span height",
+                heightWithoutSpan < spanHeight);
+
+        // add ImageSpan to text
+        Drawable drawable = mInstrumentation.getContext().getDrawable(R.drawable.scenery);
+        drawable.setBounds(0, 0, spanHeight, spanHeight);
+        ImageSpan span = new ImageSpan(drawable);
+        text.setSpan(span, 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+        mActivity.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                textView.setText(text);
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+
+        // measure height with span
+        final int heightWithSpan = textView.getHeight();
+        assertTrue("Text height should be greater or equal than span height",
+                heightWithSpan >= spanHeight);
+
+        // remove the span
+        text.removeSpan(span);
+        mActivity.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                textView.setText(text);
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+
+        final int heightAfterRemoveSpan = textView.getHeight();
+        assertEquals("Text height should be same after removing the span",
+                heightWithoutSpan, heightAfterRemoveSpan);
+    }
+
+    public void testRemoveSelectionWithSelectionHandles() {
+        initTextViewForTyping();
+
+        mActivity.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mTextView.setTextIsSelectable(true);
+                mTextView.setText("abcd", BufferType.EDITABLE);
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+
+        // Long click on the text selects all text and shows selection handlers. The view has an
+        // attribute layout_width="wrap_content", so clicked location (the center of the view)
+        // should be on the text.
+        TouchUtils.longClickView(this, mTextView);
+
+        mActivity.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                Selection.removeSelection((Spannable) mTextView.getText());
+            }
+        });
+
+        // Make sure that a crash doesn't happen with {@link Selection#removeSelection}.
+        mInstrumentation.waitForIdleSync();
+    }
+
     public void testUndo_insert() {
         initTextViewForTyping();
 
@@ -1699,6 +1829,65 @@
         mInstrumentation.waitForIdleSync();
     }
 
+    public void testCopyAndPaste_byKey() {
+        initTextViewForTyping();
+
+        // Type "abc".
+        mInstrumentation.sendStringSync("abc");
+        mActivity.runOnUiThread(new Runnable() {
+            public void run() {
+                // Select "bc"
+                Selection.setSelection((Spannable) mTextView.getText(), 1, 3);
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+        // Copy "bc"
+        sendKeys(KeyEvent.KEYCODE_COPY);
+
+        mActivity.runOnUiThread(new Runnable() {
+            public void run() {
+                // Set cursor between 'b' and 'c'.
+                Selection.setSelection((Spannable) mTextView.getText(), 2, 2);
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+        // Paste "bc"
+        sendKeys(KeyEvent.KEYCODE_PASTE);
+        assertEquals("abbcc", mTextView.getText().toString());
+
+        mActivity.runOnUiThread(new Runnable() {
+            public void run() {
+                Selection.selectAll((Spannable) mTextView.getText());
+                KeyEvent copyWithMeta = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN,
+                        KeyEvent.KEYCODE_COPY, 0, KeyEvent.META_SHIFT_LEFT_ON);
+                // Shift + copy doesn't perform copy.
+                mTextView.onKeyDown(KeyEvent.KEYCODE_COPY, copyWithMeta);
+                Selection.setSelection((Spannable) mTextView.getText(), 0, 0);
+                mTextView.onTextContextMenuItem(android.R.id.paste);
+                assertEquals("bcabbcc", mTextView.getText().toString());
+
+                Selection.selectAll((Spannable) mTextView.getText());
+                copyWithMeta = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_COPY, 0,
+                        KeyEvent.META_CTRL_LEFT_ON);
+                // Control + copy doesn't perform copy.
+                mTextView.onKeyDown(KeyEvent.KEYCODE_COPY, copyWithMeta);
+                Selection.setSelection((Spannable) mTextView.getText(), 0, 0);
+                mTextView.onTextContextMenuItem(android.R.id.paste);
+                assertEquals("bcbcabbcc", mTextView.getText().toString());
+
+                Selection.selectAll((Spannable) mTextView.getText());
+                copyWithMeta = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_COPY, 0,
+                        KeyEvent.META_SHIFT_LEFT_ON | KeyEvent.META_CTRL_LEFT_ON);
+                // Control + Shift + copy doesn't perform copy.
+                mTextView.onKeyDown(KeyEvent.KEYCODE_COPY, copyWithMeta);
+                Selection.setSelection((Spannable) mTextView.getText(), 0, 0);
+                mTextView.onTextContextMenuItem(android.R.id.paste);
+                assertEquals("bcbcbcabbcc", mTextView.getText().toString());
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+    }
+
     public void testCutAndPaste() {
         initTextViewForTyping();
         mActivity.runOnUiThread(new Runnable() {
@@ -1724,6 +1913,57 @@
         mInstrumentation.waitForIdleSync();
     }
 
+    public void testCutAndPaste_byKey() {
+        initTextViewForTyping();
+
+        // Type "abc".
+        mInstrumentation.sendStringSync("abc");
+        mActivity.runOnUiThread(new Runnable() {
+            public void run() {
+                // Select "bc"
+                Selection.setSelection((Spannable) mTextView.getText(), 1, 3);
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+        // Cut "bc"
+        sendKeys(KeyEvent.KEYCODE_CUT);
+
+        mActivity.runOnUiThread(new Runnable() {
+            public void run() {
+                assertEquals("a", mTextView.getText().toString());
+                // Move cursor to the head
+                Selection.setSelection((Spannable) mTextView.getText(), 0, 0);
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+        // Paste "bc"
+        sendKeys(KeyEvent.KEYCODE_PASTE);
+        assertEquals("bca", mTextView.getText().toString());
+
+        mActivity.runOnUiThread(new Runnable() {
+            public void run() {
+                Selection.selectAll((Spannable) mTextView.getText());
+                KeyEvent cutWithMeta = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN,
+                        KeyEvent.KEYCODE_CUT, 0, KeyEvent.META_SHIFT_LEFT_ON);
+                // Shift + cut doesn't perform cut.
+                mTextView.onKeyDown(KeyEvent.KEYCODE_CUT, cutWithMeta);
+                assertEquals("bca", mTextView.getText().toString());
+
+                cutWithMeta = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_CUT, 0,
+                        KeyEvent.META_CTRL_LEFT_ON);
+                // Control + cut doesn't perform cut.
+                mTextView.onKeyDown(KeyEvent.KEYCODE_CUT, cutWithMeta);
+                assertEquals("bca", mTextView.getText().toString());
+
+                cutWithMeta = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_CUT, 0,
+                        KeyEvent.META_SHIFT_LEFT_ON | KeyEvent.META_CTRL_LEFT_ON);
+                // Control + Shift + cut doesn't perform cut.
+                mTextView.onKeyDown(KeyEvent.KEYCODE_CUT, cutWithMeta);
+                assertEquals("bca", mTextView.getText().toString());
+            }
+        });
+    }
+
     private static boolean hasSpansAtMiddleOfText(final TextView textView, final Class<?> type) {
         final Spannable spannable = (Spannable)textView.getText();
         final int at = spannable.length() / 2;
@@ -1766,6 +2006,7 @@
 
     @UiThreadTest
     public void testSaveInstanceState() {
+        // should save text when freezesText=true
         TextView originalTextView = new TextView(mActivity);
         final String text = "This is a string";
         originalTextView.setText(text);
@@ -1778,23 +2019,104 @@
     }
 
     @UiThreadTest
-    public void testSaveInstanceStateSelection() {
-        TextView originalTextView = new TextView(mActivity);
+    public void testOnSaveInstanceState_whenFreezesTextIsFalse() {
         final String text = "This is a string";
-        final Spannable spannable = new SpannableString(text);
-        originalTextView.setText(spannable);
-        originalTextView.setTextIsSelectable(true);
-        Selection.setSelection((Spannable) originalTextView.getText(), 5, 7);
-        originalTextView.setFreezesText(true);  // needed to actually save state
-        Parcelable state = originalTextView.onSaveInstanceState();
+        { // should not save text when freezesText=false
+            // prepare TextView for before saveInstanceState
+            TextView textView1 = new TextView(mActivity);
+            textView1.setFreezesText(false);
+            textView1.setText(text);
 
-        TextView restoredTextView = new TextView(mActivity);
-        // Setting a selection only has an effect on a TextView when it is selectable.
-        restoredTextView.setTextIsSelectable(true);
-        restoredTextView.onRestoreInstanceState(state);
-        assertEquals(text, restoredTextView.getText().toString());
-        assertEquals(5, restoredTextView.getSelectionStart());
-        assertEquals(7, restoredTextView.getSelectionEnd());
+            // prepare TextView for after saveInstanceState
+            TextView textView2 = new TextView(mActivity);
+            textView2.setFreezesText(false);
+
+            textView2.onRestoreInstanceState(textView1.onSaveInstanceState());
+
+            assertEquals("", textView2.getText().toString());
+        }
+
+        { // should not save text even when textIsSelectable=true
+            // prepare TextView for before saveInstanceState
+            TextView textView1 = new TextView(mActivity);
+            textView1.setFreezesText(false);
+            textView1.setTextIsSelectable(true);
+            textView1.setText(text);
+
+            // prepare TextView for after saveInstanceState
+            TextView textView2 = new TextView(mActivity);
+            textView2.setFreezesText(false);
+            textView2.setTextIsSelectable(true);
+
+            textView2.onRestoreInstanceState(textView1.onSaveInstanceState());
+
+            assertEquals("", textView2.getText().toString());
+        }
+    }
+
+    @UiThreadTest
+    @SmallTest
+    public void testOnSaveInstanceState_doesNotSaveSelectionWhenDoesNotExist() {
+        // prepare TextView for before saveInstanceState
+        final String text = "This is a string";
+        TextView textView1 = new TextView(mActivity);
+        textView1.setFreezesText(true);
+        textView1.setText(text);
+
+        // prepare TextView for after saveInstanceState
+        TextView textView2 = new TextView(mActivity);
+        textView2.setFreezesText(true);
+
+        textView2.onRestoreInstanceState(textView1.onSaveInstanceState());
+
+        assertEquals(-1, textView2.getSelectionStart());
+        assertEquals(-1, textView2.getSelectionEnd());
+    }
+
+    @UiThreadTest
+    @SmallTest
+    public void testOnSaveInstanceState_doesNotRestoreSelectionWhenTextIsAbsent() {
+        // prepare TextView for before saveInstanceState
+        final String text = "This is a string";
+        TextView textView1 = new TextView(mActivity);
+        textView1.setFreezesText(false);
+        textView1.setTextIsSelectable(true);
+        textView1.setText(text);
+        Selection.setSelection((Spannable) textView1.getText(), 2, text.length() - 2);
+
+        // prepare TextView for after saveInstanceState
+        TextView textView2 = new TextView(mActivity);
+        textView2.setFreezesText(false);
+        textView2.setTextIsSelectable(true);
+
+        textView2.onRestoreInstanceState(textView1.onSaveInstanceState());
+
+        assertEquals("", textView2.getText().toString());
+        //when textIsSelectable, selection start and end are initialized to 0
+        assertEquals(0, textView2.getSelectionStart());
+        assertEquals(0, textView2.getSelectionEnd());
+    }
+
+    @UiThreadTest
+    @SmallTest
+    public void testOnSaveInstanceState_savesSelectionWhenExists() {
+        final String text = "This is a string";
+        // prepare TextView for before saveInstanceState
+        TextView textView1 = new TextView(mActivity);
+        textView1.setFreezesText(true);
+        textView1.setTextIsSelectable(true);
+        textView1.setText(text);
+        Selection.setSelection((Spannable) textView1.getText(), 2, text.length() - 2);
+
+        // prepare TextView for after saveInstanceState
+        TextView textView2 = new TextView(mActivity);
+        textView2.setFreezesText(true);
+        textView2.setTextIsSelectable(true);
+
+        textView2.onRestoreInstanceState(textView1.onSaveInstanceState());
+
+        assertEquals(textView1.getSelectionStart(), textView2.getSelectionStart());
+        assertEquals(textView1.getSelectionEnd(), textView2.getSelectionEnd());
     }
 
     @UiThreadTest
@@ -2151,6 +2473,7 @@
 
     public void testSetIncludeFontPadding() {
         mTextView = findTextView(R.id.textview_text);
+        assertTrue(mTextView.getIncludeFontPadding());
         mActivity.runOnUiThread(new Runnable() {
             public void run() {
                 mTextView.setWidth(mTextView.getWidth() / 3);
@@ -2169,6 +2492,7 @@
         mInstrumentation.waitForIdleSync();
 
         assertTrue(mTextView.getHeight() < oldHeight);
+        assertFalse(mTextView.getIncludeFontPadding());
     }
 
     public void testScroll() {
@@ -2268,6 +2592,81 @@
         // there is no method to check if '...yLongVeryLongWord' is painted in the screen.
     }
 
+    public void testEllipsizeEndAndNoEllipsizeHasSameBaselineForSingleLine() {
+        int textWidth = calculateTextWidth(LONG_TEXT);
+
+        TextView tvEllipsizeEnd = new TextView(getActivity());
+        tvEllipsizeEnd.setEllipsize(TruncateAt.END);
+        tvEllipsizeEnd.setMaxLines(1);
+        tvEllipsizeEnd.setWidth(textWidth >> 2);
+        tvEllipsizeEnd.setText(LONG_TEXT);
+
+        TextView tvEllipsizeNone = new TextView(getActivity());
+        tvEllipsizeNone.setWidth(textWidth >> 2);
+        tvEllipsizeNone.setText("a");
+
+        final FrameLayout layout = new FrameLayout(mActivity);
+        ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(
+                ViewGroup.LayoutParams.MATCH_PARENT,
+                ViewGroup.LayoutParams.MATCH_PARENT);
+        layout.addView(tvEllipsizeEnd, layoutParams);
+        layout.addView(tvEllipsizeNone, layoutParams);
+        layout.setLayoutParams(layoutParams);
+
+        mActivity.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                getActivity().setContentView(layout);
+            }
+        });
+        getInstrumentation().waitForIdleSync();
+
+        assertEquals("Ellipsized and non ellipsized single line texts should have the same " +
+                        "baseline",
+                tvEllipsizeEnd.getLayout().getLineBaseline(0),
+                tvEllipsizeNone.getLayout().getLineBaseline(0));
+    }
+
+    public void testEllipsizeEndAndNoEllipsizeHasSameBaselineForMultiLine() {
+        int textWidth = calculateTextWidth(LONG_TEXT);
+
+        TextView tvEllipsizeEnd = new TextView(getActivity());
+        tvEllipsizeEnd.setEllipsize(TruncateAt.END);
+        tvEllipsizeEnd.setMaxLines(2);
+        tvEllipsizeEnd.setWidth(textWidth >> 2);
+        tvEllipsizeEnd.setText(LONG_TEXT);
+
+        TextView tvEllipsizeNone = new TextView(getActivity());
+        tvEllipsizeNone.setMaxLines(2);
+        tvEllipsizeNone.setWidth(textWidth >> 2);
+        tvEllipsizeNone.setText(LONG_TEXT);
+
+        final FrameLayout layout = new FrameLayout(mActivity);
+        ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(
+                ViewGroup.LayoutParams.MATCH_PARENT,
+                ViewGroup.LayoutParams.MATCH_PARENT);
+
+        layout.addView(tvEllipsizeEnd, layoutParams);
+        layout.addView(tvEllipsizeNone, layoutParams);
+        layout.setLayoutParams(layoutParams);
+
+        mActivity.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                getActivity().setContentView(layout);
+            }
+        });
+        getInstrumentation().waitForIdleSync();
+
+        assertEquals(tvEllipsizeEnd.getLineCount(), tvEllipsizeNone.getLineCount());
+        for (int i = 0; i < tvEllipsizeEnd.getLineCount(); i++) {
+            assertEquals("Ellipsized and non ellipsized multi line texts should have the same " +
+                            "baseline for line " + i,
+                    tvEllipsizeEnd.getLayout().getLineBaseline(i),
+                    tvEllipsizeNone.getLayout().getLineBaseline(i));
+        }
+    }
+
     public void testSetCursorVisible() {
         mTextView = new TextView(mActivity);
 
@@ -2427,6 +2826,129 @@
         }
     }
 
+    @UiThreadTest
+    public void testAppend_doesNotAddLinksWhenAppendedTextDoesNotContainLinks() {
+        mTextView = new TextView(mActivity);
+        mTextView.setAutoLinkMask(Linkify.ALL);
+        mTextView.setText("text without URL");
+
+        mTextView.append(" another text without URL");
+
+        Spannable text = (Spannable) mTextView.getText();
+        URLSpan[] urlSpans = text.getSpans(0, text.length(), URLSpan.class);
+        assertEquals("URLSpan count should be zero", 0, urlSpans.length);
+        assertEquals("text without URL another text without URL", text.toString());
+    }
+
+    @UiThreadTest
+    public void testAppend_doesNotAddLinksWhenAutoLinkIsNotEnabled() {
+        mTextView = new TextView(mActivity);
+        mTextView.setText("text without URL");
+
+        mTextView.append(" text with URL http://android.com");
+
+        Spannable text = (Spannable) mTextView.getText();
+        URLSpan[] urlSpans = text.getSpans(0, text.length(), URLSpan.class);
+        assertEquals("URLSpan count should be zero", 0, urlSpans.length);
+        assertEquals("text without URL text with URL http://android.com", text.toString());
+    }
+
+    @UiThreadTest
+    public void testAppend_addsLinksWhenAutoLinkIsEnabled() {
+        mTextView = new TextView(mActivity);
+        mTextView.setAutoLinkMask(Linkify.ALL);
+        mTextView.setText("text without URL");
+
+        mTextView.append(" text with URL http://android.com");
+
+        Spannable text = (Spannable) mTextView.getText();
+        URLSpan[] urlSpans = text.getSpans(0, text.length(), URLSpan.class);
+        assertEquals("URLSpan count should be one after appending a URL", 1, urlSpans.length);
+        assertEquals("URLSpan URL should be same as the appended URL",
+                urlSpans[0].getURL(), "http://android.com");
+        assertEquals("text without URL text with URL http://android.com", text.toString());
+    }
+
+    @UiThreadTest
+    public void testAppend_addsLinksEvenWhenThereAreUrlsSetBefore() {
+        mTextView = new TextView(mActivity);
+        mTextView.setAutoLinkMask(Linkify.ALL);
+        mTextView.setText("text with URL http://android.com/before");
+
+        mTextView.append(" text with URL http://android.com");
+
+        Spannable text = (Spannable) mTextView.getText();
+        URLSpan[] urlSpans = text.getSpans(0, text.length(), URLSpan.class);
+        assertEquals("URLSpan count should be two after appending another URL", 2, urlSpans.length);
+        assertEquals("First URLSpan URL should be same",
+                urlSpans[0].getURL(), "http://android.com/before");
+        assertEquals("URLSpan URL should be same as the appended URL",
+                urlSpans[1].getURL(), "http://android.com");
+        assertEquals("text with URL http://android.com/before text with URL http://android.com",
+                text.toString());
+    }
+
+    @UiThreadTest
+    public void testAppend_setsMovementMethodWhenTextContainsUrlAndAutoLinkIsEnabled() {
+        mTextView = new TextView(mActivity);
+        mTextView.setAutoLinkMask(Linkify.ALL);
+        mTextView.setText("text without a URL");
+
+        mTextView.append(" text with a url: http://android.com");
+
+        assertNotNull("MovementMethod should not be null when text contains url",
+                mTextView.getMovementMethod());
+        assertTrue("MovementMethod should be instance of LinkMovementMethod when text contains url",
+                mTextView.getMovementMethod() instanceof LinkMovementMethod);
+    }
+
+    @UiThreadTest
+    public void testAppend_addsLinksWhenTextIsSpannableAndContainsUrlAndAutoLinkIsEnabled() {
+        mTextView = new TextView(mActivity);
+        mTextView.setAutoLinkMask(Linkify.ALL);
+        mTextView.setText("text without a URL");
+
+        mTextView.append(new SpannableString(" text with a url: http://android.com"));
+
+        Spannable text = (Spannable) mTextView.getText();
+        URLSpan[] urlSpans = text.getSpans(0, text.length(), URLSpan.class);
+        assertEquals("URLSpan count should be one after appending a URL", 1, urlSpans.length);
+        assertEquals("URLSpan URL should be same as the appended URL",
+                urlSpans[0].getURL(), "http://android.com");
+    }
+
+    @UiThreadTest
+    public void testAppend_addsLinkIfAppendedTextCompletesPartialUrlAtTheEndOfExistingText() {
+        mTextView = new TextView(mActivity);
+        mTextView.setAutoLinkMask(Linkify.ALL);
+        mTextView.setText("text with a partial url android.");
+
+        mTextView.append("com");
+
+        Spannable text = (Spannable) mTextView.getText();
+        URLSpan[] urlSpans = text.getSpans(0, text.length(), URLSpan.class);
+        assertEquals("URLSpan count should be one after appending to partial URL",
+                1, urlSpans.length);
+        assertEquals("URLSpan URL should be same as the appended URL",
+                urlSpans[0].getURL(), "http://android.com");
+    }
+
+    @UiThreadTest
+    public void testAppend_addsLinkIfAppendedTextUpdatesUrlAtTheEndOfExistingText() {
+        mTextView = new TextView(mActivity);
+        mTextView.setAutoLinkMask(Linkify.ALL);
+        mTextView.setText("text with a url http://android.com");
+
+        mTextView.append("/textview");
+
+        Spannable text = (Spannable) mTextView.getText();
+        URLSpan[] urlSpans = text.getSpans(0, text.length(), URLSpan.class);
+        assertEquals("URLSpan count should still be one after extending a URL", 1, urlSpans.length);
+        assertEquals("URLSpan URL should be same as the new URL",
+                urlSpans[0].getURL(), "http://android.com/textview");
+    }
+
+
     public void testAccessTransformationMethod() {
         // check the password attribute in xml
         mTextView = findTextView(R.id.textview_password);
@@ -3022,6 +3544,23 @@
         mTextView.setCompoundDrawableTintMode(PorterDuff.Mode.XOR);
         assertSame(colors, mTextView.getCompoundDrawableTintList());
         assertEquals(PorterDuff.Mode.XOR, mTextView.getCompoundDrawableTintMode());
+
+        // Ensure the tint is preserved across drawable changes.
+        mTextView.setCompoundDrawablesRelative(null, null, null, null);
+        assertSame(colors, mTextView.getCompoundDrawableTintList());
+        assertEquals(PorterDuff.Mode.XOR, mTextView.getCompoundDrawableTintMode());
+
+        mTextView.setCompoundDrawables(null, null, null, null);
+        assertSame(colors, mTextView.getCompoundDrawableTintList());
+        assertEquals(PorterDuff.Mode.XOR, mTextView.getCompoundDrawableTintMode());
+
+        ColorDrawable dr1 = new ColorDrawable(Color.RED);
+        ColorDrawable dr2 = new ColorDrawable(Color.GREEN);
+        ColorDrawable dr3 = new ColorDrawable(Color.BLUE);
+        ColorDrawable dr4 = new ColorDrawable(Color.YELLOW);
+        mTextView.setCompoundDrawables(dr1, dr2, dr3, dr4);
+        assertSame(colors, mTextView.getCompoundDrawableTintList());
+        assertEquals(PorterDuff.Mode.XOR, mTextView.getCompoundDrawableTintMode());
     }
 
     public void testSetHorizontallyScrolling() {
@@ -3132,46 +3671,6 @@
         assertEquals(-1, textView.getFrameBottom());
     }
 
-    public void testGetFadingEdgeStrength() {
-        final MockTextView textViewLeft = (MockTextView) mActivity.findViewById(
-                R.id.mock_textview_left);
-        mActivity.runOnUiThread(new Runnable() {
-            public void run() {
-                textViewLeft.setEllipsize(null);
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-
-        // fading is shown on right side if the text aligns left
-        assertEquals(0.0f, textViewLeft.getLeftFadingEdgeStrength(), 0.01f);
-        assertEquals(1.0f, textViewLeft.getRightFadingEdgeStrength(), 0.01f);
-
-        final MockTextView textViewRight = (MockTextView) mActivity.findViewById(
-                R.id.mock_textview_right);
-        mActivity.runOnUiThread(new Runnable() {
-            public void run() {
-                textViewRight.setEllipsize(null);
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-        // fading is shown on left side if the text aligns right
-        assertEquals(1.0f, textViewRight.getLeftFadingEdgeStrength(), 0.01f);
-        assertEquals(0.0f, textViewRight.getRightFadingEdgeStrength(), 0.01f);
-
-        final MockTextView textViewCenter = (MockTextView) mActivity.findViewById(
-                R.id.mock_textview_center);
-        mActivity.runOnUiThread(new Runnable() {
-            public void run() {
-                textViewCenter.setEllipsize(null);
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-        // fading is shown on both sides if the text aligns center
-        assertEquals(1.0f, textViewCenter.getLeftFadingEdgeStrength(), 0.01f);
-        assertEquals(1.0f, textViewCenter.getRightFadingEdgeStrength(), 0.01f);
-    }
-
-
     public void testMarquee() {
         final MockTextView textView = new MockTextView(mActivity);
         textView.setText(LONG_TEXT);
@@ -3213,17 +3712,11 @@
             }
         }.run();
 
-        final float leftFadingEdgeStrength = textView.getLeftFadingEdgeStrength();
-        final float rightFadingEdgeStrength = textView.getRightFadingEdgeStrength();
-
-        // wait for the marquee to continue
-        // the left fading becomes thicker while the right fading becomes thiner
-        // as the text moves towards left
+        // wait for left marquee to fully apply
         new PollingCheck(TIMEOUT) {
             @Override
             protected boolean check() {
-                return leftFadingEdgeStrength < textView.getLeftFadingEdgeStrength()
-                        && rightFadingEdgeStrength > textView.getRightFadingEdgeStrength();
+                return textView.getLeftFadingEdgeStrength() > 0.99f;
             }
         }.run();
         assertFalse(runnable.getIsSelected1());
@@ -3512,6 +4005,28 @@
         assertEquals(1, mTextView.getImeActionId());
     }
 
+    public void testAccessImeHintLocales() {
+        final TextView textView = new TextView(mActivity);
+        textView.setText("", BufferType.EDITABLE);
+        textView.setKeyListener(null);
+        textView.setRawInputType(InputType.TYPE_CLASS_TEXT);
+        assertNull(textView.getImeHintLocales());
+        {
+            final EditorInfo editorInfo = new EditorInfo();
+            textView.onCreateInputConnection(editorInfo);
+            assertNull(editorInfo.hintLocales);
+        }
+
+        final LocaleList localeList = LocaleList.forLanguageTags("en-PH,en-US");
+        textView.setImeHintLocales(localeList);
+        assertEquals(localeList, textView.getImeHintLocales());
+        {
+            final EditorInfo editorInfo = new EditorInfo();
+            textView.onCreateInputConnection(editorInfo);
+            assertEquals(localeList, editorInfo.hintLocales);
+        }
+    }
+
     @UiThreadTest
     public void testSetExtractedText() {
         mTextView = findTextView(R.id.textview_text);
@@ -3519,10 +4034,53 @@
                 mTextView.getText().toString());
 
         ExtractedText et = new ExtractedText();
+
+        // Update text and selection.
         et.text = "test";
+        et.selectionStart = 0;
+        et.selectionEnd = 2;
 
         mTextView.setExtractedText(et);
         assertEquals("test", mTextView.getText().toString());
+        assertEquals(0, mTextView.getSelectionStart());
+        assertEquals(2, mTextView.getSelectionEnd());
+
+        // Use partialStartOffset and partialEndOffset
+        et.partialStartOffset = 2;
+        et.partialEndOffset = 3;
+        et.text = "x";
+        et.selectionStart = 2;
+        et.selectionEnd = 3;
+
+        mTextView.setExtractedText(et);
+        assertEquals("text", mTextView.getText().toString());
+        assertEquals(2, mTextView.getSelectionStart());
+        assertEquals(3, mTextView.getSelectionEnd());
+
+        // Update text with spans.
+        final SpannableString ss = new SpannableString("ex");
+        ss.setSpan(new UnderlineSpan(), 0, 2, 0);
+        ss.setSpan(new URLSpan("ctstest://TextView/test"), 1, 2, 0);
+
+        et.text = ss;
+        et.partialStartOffset = 1;
+        et.partialEndOffset = 3;
+        mTextView.setExtractedText(et);
+
+        assertEquals("text", mTextView.getText().toString());
+        final Editable editable = mTextView.getEditableText();
+        final UnderlineSpan[] underlineSpans = mTextView.getEditableText().getSpans(
+                0, editable.length(), UnderlineSpan.class);
+        assertEquals(1, underlineSpans.length);
+        assertEquals(1, editable.getSpanStart(underlineSpans[0]));
+        assertEquals(3, editable.getSpanEnd(underlineSpans[0]));
+
+        final URLSpan[] urlSpans = mTextView.getEditableText().getSpans(
+                0, editable.length(), URLSpan.class);
+        assertEquals(1, urlSpans.length);
+        assertEquals(2, editable.getSpanStart(urlSpans[0]));
+        assertEquals(3, editable.getSpanEnd(urlSpans[0]));
+        assertEquals("ctstest://TextView/test", urlSpans[0].getURL());
     }
 
     public void testMoveCursorToVisibleOffset() throws Throwable {
@@ -4026,6 +4584,41 @@
         }
     }
 
+    public void testTextLocales() {
+        TextView tv = new TextView(mActivity);
+        assertEquals(Locale.getDefault(), tv.getTextLocale());
+        assertEquals(LocaleList.getDefault(), tv.getTextLocales());
+
+        tv.setTextLocale(Locale.CHINESE);
+        assertEquals(Locale.CHINESE, tv.getTextLocale());
+        assertEquals(new LocaleList(Locale.CHINESE), tv.getTextLocales());
+
+        tv.setTextLocales(LocaleList.forLanguageTags("en,ja"));
+        assertEquals(Locale.forLanguageTag("en"), tv.getTextLocale());
+        assertEquals(LocaleList.forLanguageTags("en,ja"), tv.getTextLocales());
+
+        try {
+            tv.setTextLocale(null);
+            fail("Setting the text locale to null should throw");
+        } catch (Throwable e) {
+            assertEquals(IllegalArgumentException.class, e.getClass());
+        }
+
+        try {
+            tv.setTextLocales(null);
+            fail("Setting the text locales to null should throw");
+        } catch (Throwable e) {
+            assertEquals(IllegalArgumentException.class, e.getClass());
+        }
+
+        try {
+            tv.setTextLocales(new LocaleList());
+            fail("Setting the text locale to an empty list should throw");
+        } catch (Throwable e) {
+            assertEquals(IllegalArgumentException.class, e.getClass());
+        }
+    }
+
     public void testAllCapsLocalization() {
         String testString = "abcdefghijklmnopqrstuvwxyz";
 
diff --git a/tests/tests/widget/src/android/widget/cts/TimePickerTest.java b/tests/tests/widget/src/android/widget/cts/TimePickerTest.java
index 1ce2844..39554bb 100644
--- a/tests/tests/widget/src/android/widget/cts/TimePickerTest.java
+++ b/tests/tests/widget/src/android/widget/cts/TimePickerTest.java
@@ -39,7 +39,7 @@
     private Instrumentation mInstrumentation;
 
     public TimePickerTest() {
-        super("com.android.cts.widget", CtsActivity.class);
+        super("android.widget.cts", CtsActivity.class);
     }
 
     @Override
@@ -52,7 +52,7 @@
 
     public void testConstructors() {
         AttributeSet attrs =
-            mContext.getResources().getLayout(com.android.cts.widget.R.layout.timepicker);
+            mContext.getResources().getLayout(android.widget.cts.R.layout.timepicker);
         assertNotNull(attrs);
 
         new TimePicker(mContext);
diff --git a/tests/tests/widget/src/android/widget/cts/ToastTest.java b/tests/tests/widget/src/android/widget/cts/ToastTest.java
index 90a161e..854247e 100644
--- a/tests/tests/widget/src/android/widget/cts/ToastTest.java
+++ b/tests/tests/widget/src/android/widget/cts/ToastTest.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 
 import android.app.Activity;
@@ -44,7 +44,7 @@
     private ViewTreeObserver.OnGlobalLayoutListener mLayoutListener;
 
     public ToastTest() {
-        super("com.android.cts.widget", CtsActivity.class);
+        super("android.widget.cts", CtsActivity.class);
     }
 
     @Override
diff --git a/tests/tests/widget/src/android/widget/cts/ToggleButtonTest.java b/tests/tests/widget/src/android/widget/cts/ToggleButtonTest.java
index b3bc31e..d335c13 100644
--- a/tests/tests/widget/src/android/widget/cts/ToggleButtonTest.java
+++ b/tests/tests/widget/src/android/widget/cts/ToggleButtonTest.java
@@ -21,13 +21,14 @@
 import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.drawable.Drawable;
+import android.graphics.drawable.StateListDrawable;
 import android.test.InstrumentationTestCase;
 import android.test.UiThreadTest;
 import android.util.AttributeSet;
 import android.util.Xml;
 import android.widget.ToggleButton;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 
 /**
@@ -96,9 +97,13 @@
         // drawableStateChanged without any drawable.
         toggleButton.drawableStateChanged();
 
+        StateListDrawable drawable = new StateListDrawable();
+        drawable.addState(new int[] { android.R.attr.state_pressed },
+                mContext.getDrawable(R.drawable.scenery));
+        drawable.addState(new int[] {},
+                mContext.getDrawable(R.drawable.scenery));
+
         // drawableStateChanged when CheckMarkDrawable is not null.
-        Resources resources = mContext.getResources();
-        Drawable drawable = resources.getDrawable(R.drawable.scenery);
         toggleButton.setButtonDrawable(drawable);
         drawable.setState(null);
         assertNull(drawable.getState());
diff --git a/tests/tests/widget/src/android/widget/cts/ToolbarCtsActivity.java b/tests/tests/widget/src/android/widget/cts/ToolbarCtsActivity.java
new file mode 100644
index 0000000..413976d
--- /dev/null
+++ b/tests/tests/widget/src/android/widget/cts/ToolbarCtsActivity.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.widget.cts;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.Toolbar;
+
+/**
+ * A minimal application for {@link Toolbar} test.
+ */
+public class ToolbarCtsActivity extends Activity {
+    private Toolbar mMainToolbar;
+
+    /**
+     * Called with the activity is first created.
+     */
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.toolbar_layout);
+
+        mMainToolbar = (Toolbar) findViewById(R.id.toolbar_main);
+        setActionBar(mMainToolbar);
+    }
+
+    public Toolbar getMainToolbar() {
+        return mMainToolbar;
+    }
+}
+
diff --git a/tests/tests/widget/src/android/widget/cts/ToolbarTest.java b/tests/tests/widget/src/android/widget/cts/ToolbarTest.java
new file mode 100644
index 0000000..7f9690c
--- /dev/null
+++ b/tests/tests/widget/src/android/widget/cts/ToolbarTest.java
@@ -0,0 +1,385 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.widget.cts;
+
+import android.app.Instrumentation;
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Color;
+import android.graphics.drawable.Drawable;
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.UiThreadTest;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.ListPopupWindow;
+import android.widget.Toolbar;
+import android.widget.cts.util.TestUtils;
+import android.widget.cts.util.ViewTestUtils;
+
+import static org.mockito.Mockito.*;
+
+@MediumTest
+public class ToolbarTest extends ActivityInstrumentationTestCase2<ToolbarCtsActivity> {
+    private Toolbar mMainToolbar;
+    private ToolbarCtsActivity mActivity;
+
+    public ToolbarTest() {
+        super("android.widget.cts", ToolbarCtsActivity.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mActivity = getActivity();
+        mMainToolbar = mActivity.getMainToolbar();
+    }
+
+    public void testConstructor() {
+        new Toolbar(mActivity);
+
+        new Toolbar(mActivity, null);
+
+        new Toolbar(mActivity, null, android.R.attr.toolbarStyle);
+
+        new Toolbar(mActivity, null, 0, android.R.style.Widget_Material_Toolbar);
+    }
+
+    public void testTitleAndSubtitleContent() {
+        // Note that this method is *not* annotated to run on the UI thread, and every
+        // call to setTitle / setSubtitle is wrapped to wait until the next draw pass
+        // of our main toolbar. While this is not strictly necessary to check the result
+        // of getTitle / getSubtitle, this logic follows the path of deferred layout
+        // and invalidation of the TextViews that show the title / subtitle in the Toolbar.
+
+        final Instrumentation instrumentation = getInstrumentation();
+
+        ViewTestUtils.runOnMainAndDrawSync(instrumentation, mMainToolbar,
+                () -> mMainToolbar.setTitle(R.string.toolbar_title));
+        assertEquals(mActivity.getString(R.string.toolbar_title), mMainToolbar.getTitle());
+
+        ViewTestUtils.runOnMainAndDrawSync(instrumentation, mMainToolbar,
+                () -> mMainToolbar.setTitle("New title"));
+        assertEquals("New title", mMainToolbar.getTitle());
+
+        ViewTestUtils.runOnMainAndDrawSync(instrumentation, mMainToolbar,
+                () -> mMainToolbar.setSubtitle(R.string.toolbar_subtitle));
+        assertEquals(mActivity.getString(R.string.toolbar_subtitle), mMainToolbar.getSubtitle());
+
+        ViewTestUtils.runOnMainAndDrawSync(instrumentation, mMainToolbar,
+                () -> mMainToolbar.setSubtitle("New subtitle"));
+        assertEquals("New subtitle", mMainToolbar.getSubtitle());
+    }
+
+    public void testTitleAndSubtitleAppearance() {
+        final Instrumentation instrumentation = getInstrumentation();
+
+        ViewTestUtils.runOnMainAndDrawSync(instrumentation, mMainToolbar,
+                () -> mMainToolbar.setTitle(R.string.toolbar_title));
+        ViewTestUtils.runOnMainAndDrawSync(instrumentation, mMainToolbar,
+                () -> mMainToolbar.setSubtitle(R.string.toolbar_subtitle));
+
+        // Since there are no APIs to get reference to the underlying implementation of
+        // title and subtitle, here we are testing that calling the relevant APIs doesn't crash
+
+        ViewTestUtils.runOnMainAndDrawSync(instrumentation, mMainToolbar,
+                () -> mMainToolbar.setTitleTextColor(Color.RED));
+        ViewTestUtils.runOnMainAndDrawSync(instrumentation, mMainToolbar,
+                () -> mMainToolbar.setSubtitleTextColor(Color.BLUE));
+
+        ViewTestUtils.runOnMainAndDrawSync(instrumentation, mMainToolbar,
+                () -> mMainToolbar.setTitleTextAppearance(
+                        mActivity, R.style.TextAppearance_NotColors));
+        ViewTestUtils.runOnMainAndDrawSync(instrumentation, mMainToolbar,
+                () -> mMainToolbar.setSubtitleTextAppearance(
+                        mActivity, R.style.TextAppearance_WithColor));
+    }
+
+    @UiThreadTest
+    public void testGetTitleMargins() {
+        assertEquals(5, mMainToolbar.getTitleMarginStart());
+        assertEquals(10, mMainToolbar.getTitleMarginTop());
+        assertEquals(15, mMainToolbar.getTitleMarginEnd());
+        assertEquals(20, mMainToolbar.getTitleMarginBottom());
+    }
+
+    @UiThreadTest
+    public void testSetTitleMargins() {
+        Toolbar toolbar = (Toolbar) mActivity.findViewById(R.id.toolbar2);
+
+        toolbar.setTitleMargin(5, 10, 15, 20);
+        assertEquals(5, toolbar.getTitleMarginStart());
+        assertEquals(10, toolbar.getTitleMarginTop());
+        assertEquals(15, toolbar.getTitleMarginEnd());
+        assertEquals(20, toolbar.getTitleMarginBottom());
+
+        toolbar.setTitleMarginStart(25);
+        toolbar.setTitleMarginTop(30);
+        toolbar.setTitleMarginEnd(35);
+        toolbar.setTitleMarginBottom(40);
+        assertEquals(25, toolbar.getTitleMarginStart());
+        assertEquals(30, toolbar.getTitleMarginTop());
+        assertEquals(35, toolbar.getTitleMarginEnd());
+        assertEquals(40, toolbar.getTitleMarginBottom());
+    }
+
+    public void testMenuContent() {
+        final Instrumentation instrumentation = getInstrumentation();
+
+        ViewTestUtils.runOnMainAndDrawSync(instrumentation, mMainToolbar,
+                () -> mMainToolbar.inflateMenu(R.menu.toolbar_menu));
+
+        final Menu menu = mMainToolbar.getMenu();
+
+        assertEquals(6, menu.size());
+        assertEquals(R.id.action_highlight, menu.getItem(0).getItemId());
+        assertEquals(R.id.action_edit, menu.getItem(1).getItemId());
+        assertEquals(R.id.action_delete, menu.getItem(2).getItemId());
+        assertEquals(R.id.action_ignore, menu.getItem(3).getItemId());
+        assertEquals(R.id.action_share, menu.getItem(4).getItemId());
+        assertEquals(R.id.action_print, menu.getItem(5).getItemId());
+
+        assertFalse(mMainToolbar.hasExpandedActionView());
+
+        Toolbar.OnMenuItemClickListener menuItemClickListener =
+                mock(Toolbar.OnMenuItemClickListener.class);
+        mMainToolbar.setOnMenuItemClickListener(menuItemClickListener);
+
+        menu.performIdentifierAction(R.id.action_highlight, 0);
+        verify(menuItemClickListener, times(1)).onMenuItemClick(
+                menu.findItem(R.id.action_highlight));
+
+        menu.performIdentifierAction(R.id.action_share, 0);
+        verify(menuItemClickListener, times(1)).onMenuItemClick(
+                menu.findItem(R.id.action_share));
+    }
+
+    public void testMenuOverflowShowHide() {
+        final Instrumentation instrumentation = getInstrumentation();
+
+        // Inflate menu and check that we're not showing overflow menu yet
+        instrumentation.runOnMainSync(() -> mMainToolbar.inflateMenu(R.menu.toolbar_menu));
+        assertFalse(mMainToolbar.isOverflowMenuShowing());
+
+        // Ask to show overflow menu and check that it's showing
+        instrumentation.runOnMainSync(() -> mMainToolbar.showOverflowMenu());
+        instrumentation.waitForIdleSync();
+        assertTrue(mMainToolbar.isOverflowMenuShowing());
+
+        // Ask to hide the overflow menu and check that it's not showing
+        instrumentation.runOnMainSync(() -> mMainToolbar.hideOverflowMenu());
+        instrumentation.waitForIdleSync();
+        assertFalse(mMainToolbar.isOverflowMenuShowing());
+    }
+
+    public void testMenuOverflowSubmenu() {
+        final Instrumentation instrumentation = getInstrumentation();
+
+        // Inflate menu and check that we're not showing overflow menu yet
+        ViewTestUtils.runOnMainAndDrawSync(instrumentation, mMainToolbar,
+                () -> mMainToolbar.inflateMenu(R.menu.toolbar_menu));
+        assertFalse(mMainToolbar.isOverflowMenuShowing());
+
+        // Ask to show overflow menu and check that it's showing
+        instrumentation.runOnMainSync(() -> mMainToolbar.showOverflowMenu());
+        instrumentation.waitForIdleSync();
+        assertTrue(mMainToolbar.isOverflowMenuShowing());
+
+        // Register a mock menu item click listener on the toolbar
+        Toolbar.OnMenuItemClickListener menuItemClickListener =
+                mock(Toolbar.OnMenuItemClickListener.class);
+        mMainToolbar.setOnMenuItemClickListener(menuItemClickListener);
+
+        final Menu menu = mMainToolbar.getMenu();
+
+        // Ask to "perform" the share action and check that the menu click listener has
+        // been notified
+        instrumentation.runOnMainSync(() -> menu.performIdentifierAction(R.id.action_share, 0));
+        verify(menuItemClickListener, times(1)).onMenuItemClick(
+                menu.findItem(R.id.action_share));
+
+        // Ask to dismiss all the popups and check that we're not showing the overflow menu
+        instrumentation.runOnMainSync(() -> mMainToolbar.dismissPopupMenus());
+        instrumentation.waitForIdleSync();
+        assertFalse(mMainToolbar.isOverflowMenuShowing());
+    }
+
+    public void testMenuOverflowIcon() {
+        final Instrumentation instrumentation = getInstrumentation();
+
+        // Inflate menu and check that we're not showing overflow menu yet
+        ViewTestUtils.runOnMainAndDrawSync(instrumentation, mMainToolbar,
+                () -> mMainToolbar.inflateMenu(R.menu.toolbar_menu));
+
+        final Drawable overflowIcon = mActivity.getDrawable(R.drawable.icon_red);
+        ViewTestUtils.runOnMainAndDrawSync(instrumentation, mMainToolbar,
+                () -> mMainToolbar.setOverflowIcon(overflowIcon));
+
+        final Drawable toolbarOverflowIcon = mMainToolbar.getOverflowIcon();
+        TestUtils.assertAllPixelsOfColor("Overflow icon is red", toolbarOverflowIcon,
+                toolbarOverflowIcon.getIntrinsicWidth(), toolbarOverflowIcon.getIntrinsicHeight(),
+                true, 0XFFFF0000, 1, false);
+    }
+
+    public void testActionView() {
+        final Instrumentation instrumentation = getInstrumentation();
+
+        // Inflate menu and check that we don't have an expanded action view
+        ViewTestUtils.runOnMainAndDrawSync(instrumentation, mMainToolbar,
+                () -> mMainToolbar.inflateMenu(R.menu.toolbar_menu_search));
+        assertFalse(mMainToolbar.hasExpandedActionView());
+
+        // Expand search menu item's action view and verify that main toolbar has an expanded
+        // action view
+        final MenuItem searchMenuItem = mMainToolbar.getMenu().findItem(R.id.action_search);
+        instrumentation.runOnMainSync(() -> searchMenuItem.expandActionView());
+        instrumentation.waitForIdleSync();
+        assertTrue(searchMenuItem.isActionViewExpanded());
+        assertTrue(mMainToolbar.hasExpandedActionView());
+
+        // Collapse search menu item's action view and verify that main toolbar doesn't have an
+        // expanded action view
+        instrumentation.runOnMainSync(() -> searchMenuItem.collapseActionView());
+        instrumentation.waitForIdleSync();
+        assertFalse(searchMenuItem.isActionViewExpanded());
+        assertFalse(mMainToolbar.hasExpandedActionView());
+
+        // Expand search menu item's action view again
+        instrumentation.runOnMainSync(() -> searchMenuItem.expandActionView());
+        instrumentation.waitForIdleSync();
+        assertTrue(searchMenuItem.isActionViewExpanded());
+        assertTrue(mMainToolbar.hasExpandedActionView());
+
+        // Now collapse search menu item's action view via toolbar's API and verify that main
+        // toolbar doesn't have an expanded action view
+        instrumentation.runOnMainSync(() -> mMainToolbar.collapseActionView());
+        instrumentation.waitForIdleSync();
+        assertFalse(searchMenuItem.isActionViewExpanded());
+        assertFalse(mMainToolbar.hasExpandedActionView());
+    }
+
+    public void testNavigationConfiguration() {
+        final Instrumentation instrumentation = getInstrumentation();
+
+        ViewTestUtils.runOnMainAndDrawSync(instrumentation, mMainToolbar,
+                () -> mMainToolbar.setNavigationIcon(R.drawable.icon_green));
+        Drawable toolbarNavigationIcon = mMainToolbar.getNavigationIcon();
+        TestUtils.assertAllPixelsOfColor("Navigation icon is green", toolbarNavigationIcon,
+                toolbarNavigationIcon.getIntrinsicWidth(),
+                toolbarNavigationIcon.getIntrinsicHeight(),
+                true, 0xFF00FF00, 1, false);
+
+        ViewTestUtils.runOnMainAndDrawSync(instrumentation, mMainToolbar,
+                () -> mMainToolbar.setNavigationIcon(mActivity.getDrawable(R.drawable.icon_blue)));
+        toolbarNavigationIcon = mMainToolbar.getNavigationIcon();
+        TestUtils.assertAllPixelsOfColor("Navigation icon is blue", toolbarNavigationIcon,
+                toolbarNavigationIcon.getIntrinsicWidth(),
+                toolbarNavigationIcon.getIntrinsicHeight(),
+                true, 0xFF0000FF, 1, false);
+
+        instrumentation.runOnMainSync(
+                () -> mMainToolbar.setNavigationContentDescription(R.string.toolbar_navigation));
+        assertEquals(mActivity.getResources().getString(R.string.toolbar_navigation),
+                mMainToolbar.getNavigationContentDescription());
+
+        instrumentation.runOnMainSync(
+                () -> mMainToolbar.setNavigationContentDescription("Navigation legend"));
+        assertEquals("Navigation legend", mMainToolbar.getNavigationContentDescription());
+    }
+
+    public void testLogoConfiguration() {
+        final Instrumentation instrumentation = getInstrumentation();
+
+        ViewTestUtils.runOnMainAndDrawSync(instrumentation, mMainToolbar,
+                () -> mMainToolbar.setLogo(R.drawable.icon_yellow));
+        Drawable toolbarLogo = mMainToolbar.getLogo();
+        TestUtils.assertAllPixelsOfColor("Logo is yellow", toolbarLogo,
+                toolbarLogo.getIntrinsicWidth(),
+                toolbarLogo.getIntrinsicHeight(),
+                true, 0xFFFFFF00, 1, false);
+
+        ViewTestUtils.runOnMainAndDrawSync(instrumentation, mMainToolbar,
+                () -> mMainToolbar.setLogo(mActivity.getDrawable(R.drawable.icon_red)));
+        toolbarLogo = mMainToolbar.getLogo();
+        TestUtils.assertAllPixelsOfColor("Logo is red", toolbarLogo,
+                toolbarLogo.getIntrinsicWidth(),
+                toolbarLogo.getIntrinsicHeight(),
+                true, 0xFFFF0000, 1, false);
+
+        instrumentation.runOnMainSync(
+                () -> mMainToolbar.setLogoDescription(R.string.toolbar_logo));
+        assertEquals(mActivity.getResources().getString(R.string.toolbar_logo),
+                mMainToolbar.getLogoDescription());
+
+        instrumentation.runOnMainSync(
+                () -> mMainToolbar.setLogoDescription("Logo legend"));
+        assertEquals("Logo legend", mMainToolbar.getLogoDescription());
+    }
+
+    @UiThreadTest
+    public void testContentInsetsLtr() {
+        mMainToolbar.setLayoutDirection(View.LAYOUT_DIRECTION_LTR);
+
+        mMainToolbar.setContentInsetsAbsolute(20, 25);
+        assertEquals(20, mMainToolbar.getContentInsetLeft());
+        assertEquals(20, mMainToolbar.getContentInsetStart());
+        assertEquals(25, mMainToolbar.getContentInsetRight());
+        assertEquals(25, mMainToolbar.getContentInsetEnd());
+
+        mMainToolbar.setContentInsetsRelative(40, 20);
+        assertEquals(40, mMainToolbar.getContentInsetLeft());
+        assertEquals(40, mMainToolbar.getContentInsetStart());
+        assertEquals(20, mMainToolbar.getContentInsetRight());
+        assertEquals(20, mMainToolbar.getContentInsetEnd());
+    }
+
+    @UiThreadTest
+    public void testContentInsetsRtl() {
+        mMainToolbar.setLayoutDirection(View.LAYOUT_DIRECTION_RTL);
+
+        mMainToolbar.setContentInsetsAbsolute(20, 25);
+        assertEquals(20, mMainToolbar.getContentInsetLeft());
+        assertEquals(25, mMainToolbar.getContentInsetStart());
+        assertEquals(25, mMainToolbar.getContentInsetRight());
+        assertEquals(20, mMainToolbar.getContentInsetEnd());
+
+        mMainToolbar.setContentInsetsRelative(40, 20);
+        assertEquals(20, mMainToolbar.getContentInsetLeft());
+        assertEquals(40, mMainToolbar.getContentInsetStart());
+        assertEquals(40, mMainToolbar.getContentInsetRight());
+        assertEquals(20, mMainToolbar.getContentInsetEnd());
+    }
+
+    @UiThreadTest
+    public void testPopupTheme() {
+        mMainToolbar.setPopupTheme(R.style.ToolbarPopupTheme_Test);
+        assertEquals(R.style.ToolbarPopupTheme_Test, mMainToolbar.getPopupTheme());
+    }
+
+    public void testNavigationOnClickListener() {
+        View.OnClickListener mockListener = mock(View.OnClickListener.class);
+        mMainToolbar.setNavigationOnClickListener(mockListener);
+
+        verify(mockListener, never()).onClick(any(View.class));
+
+        getInstrumentation().runOnMainSync(() -> mMainToolbar.getNavigationView().performClick());
+        verify(mockListener, times(1)).onClick(any(View.class));
+
+        verifyNoMoreInteractions(mockListener);
+    }
+}
diff --git a/tests/tests/widget/src/android/widget/cts/TwoLineListItemCtsActivity.java b/tests/tests/widget/src/android/widget/cts/TwoLineListItemCtsActivity.java
index bd2c36d..68413ff 100644
--- a/tests/tests/widget/src/android/widget/cts/TwoLineListItemCtsActivity.java
+++ b/tests/tests/widget/src/android/widget/cts/TwoLineListItemCtsActivity.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 import android.app.Activity;
 import android.os.Bundle;
diff --git a/tests/tests/widget/src/android/widget/cts/TwoLineListItemTest.java b/tests/tests/widget/src/android/widget/cts/TwoLineListItemTest.java
index 18dd407..4ee22a1 100644
--- a/tests/tests/widget/src/android/widget/cts/TwoLineListItemTest.java
+++ b/tests/tests/widget/src/android/widget/cts/TwoLineListItemTest.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 
 import android.app.Activity;
@@ -36,7 +36,7 @@
     private Activity mActivity;
 
     public TwoLineListItemTest() {
-        super("com.android.cts.widget", TwoLineListItemCtsActivity.class);
+        super("android.widget.cts", TwoLineListItemCtsActivity.class);
     }
 
     @Override
diff --git a/tests/tests/widget/src/android/widget/cts/VideoViewCtsActivity.java b/tests/tests/widget/src/android/widget/cts/VideoViewCtsActivity.java
index ad0d6eb..e831f04 100644
--- a/tests/tests/widget/src/android/widget/cts/VideoViewCtsActivity.java
+++ b/tests/tests/widget/src/android/widget/cts/VideoViewCtsActivity.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 import android.app.Activity;
 import android.os.Bundle;
diff --git a/tests/tests/widget/src/android/widget/cts/VideoViewTest.java b/tests/tests/widget/src/android/widget/cts/VideoViewTest.java
index d9af514..265b802 100644
--- a/tests/tests/widget/src/android/widget/cts/VideoViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/VideoViewTest.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 import android.app.Activity;
 import android.app.Instrumentation;
@@ -108,7 +108,7 @@
      * Instantiates a new video view test.
      */
     public VideoViewTest() {
-        super("com.android.cts.widget", VideoViewCtsActivity.class);
+        super("android.widget.cts", VideoViewCtsActivity.class);
     }
 
     /**
@@ -127,7 +127,7 @@
 
         try {
             source = mActivity.getResources().openRawResource(R.raw.testvideo);
-            target = mActivity.openFileOutput(VIDEO_NAME, Context.MODE_WORLD_READABLE);
+            target = mActivity.openFileOutput(VIDEO_NAME, Context.MODE_PRIVATE);
 
             final byte[] buffer = new byte[1024];
             for (int len = source.read(buffer); len > 0; len = source.read(buffer)) {
diff --git a/tests/tests/widget/src/android/widget/cts/ViewAnimatorCtsActivity.java b/tests/tests/widget/src/android/widget/cts/ViewAnimatorCtsActivity.java
index 21deef7..ec3e59e 100644
--- a/tests/tests/widget/src/android/widget/cts/ViewAnimatorCtsActivity.java
+++ b/tests/tests/widget/src/android/widget/cts/ViewAnimatorCtsActivity.java
@@ -18,7 +18,7 @@
 
 import android.app.Activity;
 import android.os.Bundle;
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 /**
  * A minimal application for ViewAnimator test.
diff --git a/tests/tests/widget/src/android/widget/cts/ViewAnimatorTest.java b/tests/tests/widget/src/android/widget/cts/ViewAnimatorTest.java
index 024e3ee..696761b 100644
--- a/tests/tests/widget/src/android/widget/cts/ViewAnimatorTest.java
+++ b/tests/tests/widget/src/android/widget/cts/ViewAnimatorTest.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 
 import org.xmlpull.v1.XmlPullParser;
@@ -43,7 +43,7 @@
     private AttributeSet mAttributeSet;
 
     public ViewAnimatorTest() {
-        super("com.android.cts.widget", ViewAnimatorCtsActivity.class);
+        super("android.widget.cts", ViewAnimatorCtsActivity.class);
     }
 
     @Override
diff --git a/tests/tests/widget/src/android/widget/cts/ViewFlipperCtsActivity.java b/tests/tests/widget/src/android/widget/cts/ViewFlipperCtsActivity.java
index 7f13f6c..ba90590 100644
--- a/tests/tests/widget/src/android/widget/cts/ViewFlipperCtsActivity.java
+++ b/tests/tests/widget/src/android/widget/cts/ViewFlipperCtsActivity.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 import android.app.Activity;
 import android.os.Bundle;
diff --git a/tests/tests/widget/src/android/widget/cts/ViewFlipperTest.java b/tests/tests/widget/src/android/widget/cts/ViewFlipperTest.java
index 025fae4..5ec242e 100644
--- a/tests/tests/widget/src/android/widget/cts/ViewFlipperTest.java
+++ b/tests/tests/widget/src/android/widget/cts/ViewFlipperTest.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 
 import org.xmlpull.v1.XmlPullParser;
@@ -37,7 +37,7 @@
     private Activity mActivity;
 
     public ViewFlipperTest() {
-        super("com.android.cts.widget", ViewFlipperCtsActivity.class);
+        super("android.widget.cts", ViewFlipperCtsActivity.class);
     }
 
     protected void setUp() throws Exception {
diff --git a/tests/tests/widget/src/android/widget/cts/ViewGroupCtsActivity.java b/tests/tests/widget/src/android/widget/cts/ViewGroupCtsActivity.java
index 4e14fc2..f3b3a3e 100644
--- a/tests/tests/widget/src/android/widget/cts/ViewGroupCtsActivity.java
+++ b/tests/tests/widget/src/android/widget/cts/ViewGroupCtsActivity.java
@@ -35,8 +35,8 @@
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-        setContentView(com.android.cts.widget.R.layout.viewgrouptest_stub);
-        TextView textView = (TextView)findViewById(com.android.cts.widget.R.id.viewgrouptest_stub);
+        setContentView(android.widget.cts.R.layout.viewgrouptest_stub);
+        TextView textView = (TextView)findViewById(android.widget.cts.R.id.viewgrouptest_stub);
         textView.setText("test");
     }
 
@@ -49,7 +49,7 @@
             mHandler.postDelayed(new Runnable() {
                 public void run() {
                     MockLinearLayout mll =
-                        (MockLinearLayout) findViewById(com.android.cts.widget.R.id.
+                        (MockLinearLayout) findViewById(android.widget.cts.R.id.
                                                                         mocklinearlayout);
                     if (!mll.mIsInvalidateChildInParentCalled) {
                         fail();
diff --git a/tests/tests/widget/src/android/widget/cts/ViewSwitcherTest.java b/tests/tests/widget/src/android/widget/cts/ViewSwitcherTest.java
index ce18267..7828570 100644
--- a/tests/tests/widget/src/android/widget/cts/ViewSwitcherTest.java
+++ b/tests/tests/widget/src/android/widget/cts/ViewSwitcherTest.java
@@ -28,7 +28,7 @@
 import android.widget.ViewSwitcher;
 import android.widget.ViewSwitcher.ViewFactory;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 
 /**
diff --git a/tests/tests/widget/src/android/widget/cts/ZoomButtonCtsActivity.java b/tests/tests/widget/src/android/widget/cts/ZoomButtonCtsActivity.java
index e371b3f..28563f5 100644
--- a/tests/tests/widget/src/android/widget/cts/ZoomButtonCtsActivity.java
+++ b/tests/tests/widget/src/android/widget/cts/ZoomButtonCtsActivity.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 import android.app.Activity;
 import android.os.Bundle;
diff --git a/tests/tests/widget/src/android/widget/cts/ZoomButtonTest.java b/tests/tests/widget/src/android/widget/cts/ZoomButtonTest.java
index 3d906db..493c484 100644
--- a/tests/tests/widget/src/android/widget/cts/ZoomButtonTest.java
+++ b/tests/tests/widget/src/android/widget/cts/ZoomButtonTest.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.cts.widget.R;
+import android.widget.cts.R;
 
 
 import org.xmlpull.v1.XmlPullParser;
@@ -37,7 +37,7 @@
     private Activity mActivity;
 
     public ZoomButtonTest() {
-        super("com.android.cts.widget", ZoomButtonCtsActivity.class);
+        super("android.widget.cts", ZoomButtonCtsActivity.class);
     }
 
     @Override
diff --git a/tests/tests/widget/src/android/widget/cts/util/TestUtils.java b/tests/tests/widget/src/android/widget/cts/util/TestUtils.java
new file mode 100644
index 0000000..8d8f573
--- /dev/null
+++ b/tests/tests/widget/src/android/widget/cts/util/TestUtils.java
@@ -0,0 +1,212 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.widget.cts.util;
+
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.drawable.Drawable;
+import android.support.annotation.ColorInt;
+import android.support.annotation.NonNull;
+import android.util.Pair;
+import android.view.View;
+import android.view.ViewParent;
+import junit.framework.Assert;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class TestUtils {
+    /**
+     * This method takes a view and returns a single bitmap that is the layered combination
+     * of background drawables of this view and all its ancestors. It can be used to abstract
+     * away the specific implementation of a view hierarchy that is not exposed via class APIs
+     * or a view hierarchy that depends on the platform version. Instead of hard-coded lookups
+     * of particular inner implementations of such a view hierarchy that can break during
+     * refactoring or on newer platform versions, calling this API returns a "combined" background
+     * of the view.
+     *
+     * For example, it is useful to get the combined background of a popup / dropdown without
+     * delving into the inner implementation details of how that popup is implemented on a
+     * particular platform version.
+     */
+    public static Bitmap getCombinedBackgroundBitmap(View view) {
+        final int bitmapWidth = view.getWidth();
+        final int bitmapHeight = view.getHeight();
+
+        // Create a bitmap
+        final Bitmap bitmap = Bitmap.createBitmap(bitmapWidth, bitmapHeight,
+                Bitmap.Config.ARGB_8888);
+        // Create a canvas that wraps the bitmap
+        final Canvas canvas = new Canvas(bitmap);
+
+        // As the draw pass starts at the top of view hierarchy, our first step is to traverse
+        // the ancestor hierarchy of our view and collect a list of all ancestors with non-null
+        // and visible backgrounds. At each step we're keeping track of the combined offsets
+        // so that we can properly combine all of the visuals together in the next pass.
+        List<View> ancestorsWithBackgrounds = new ArrayList<>();
+        List<Pair<Integer, Integer>> ancestorOffsets = new ArrayList<>();
+        int offsetX = 0;
+        int offsetY = 0;
+        while (true) {
+            final Drawable backgroundDrawable = view.getBackground();
+            if ((backgroundDrawable != null) && backgroundDrawable.isVisible()) {
+                ancestorsWithBackgrounds.add(view);
+                ancestorOffsets.add(Pair.create(offsetX, offsetY));
+            }
+            // Go to the parent
+            ViewParent parent = view.getParent();
+            if (!(parent instanceof View)) {
+                // We're done traversing the ancestor chain
+                break;
+            }
+
+            // Update the offsets based on the location of current view in its parent's bounds
+            offsetX += view.getLeft();
+            offsetY += view.getTop();
+
+            view = (View) parent;
+        }
+
+        // Now we're going to iterate over the collected ancestors in reverse order (starting from
+        // the topmost ancestor) and draw their backgrounds into our combined bitmap. At each step
+        // we are respecting the offsets of our original view in the coordinate system of the
+        // currently drawn ancestor.
+        final int layerCount = ancestorsWithBackgrounds.size();
+        for (int i = layerCount - 1; i >= 0; i--) {
+            View ancestor = ancestorsWithBackgrounds.get(i);
+            Pair<Integer, Integer> offsets = ancestorOffsets.get(i);
+
+            canvas.translate(offsets.first, offsets.second);
+            ancestor.getBackground().draw(canvas);
+            canvas.translate(-offsets.first, -offsets.second);
+        }
+
+        return bitmap;
+    }
+
+    /**
+     * Checks whether all the pixels in the specified View are of the same specified color.
+     *
+     * In case there is a color mismatch, the behavior of this method depends on the
+     * <code>throwExceptionIfFails</code> parameter. If it is <code>true</code>, this method will
+     * throw an <code>Exception</code> describing the mismatch. Otherwise this method will call
+     * <code>Assert.fail</code> with detailed description of the mismatch.
+     */
+    public static void assertAllPixelsOfColor(String failMessagePrefix, @NonNull View view,
+            @ColorInt int color, int allowedComponentVariance, boolean throwExceptionIfFails) {
+        // Create a bitmap
+        Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(),
+                Bitmap.Config.ARGB_8888);
+        // Create a canvas that wraps the bitmap
+        Canvas canvas = new Canvas(bitmap);
+        // And ask the view to draw itself to the canvas / bitmap
+        view.draw(canvas);
+
+        try {
+            assertAllPixelsOfColor(failMessagePrefix, bitmap, view.getWidth(), view.getHeight(),
+                    color, allowedComponentVariance, throwExceptionIfFails);
+        } finally {
+            bitmap.recycle();
+        }
+    }
+
+    /**
+     * Checks whether all the pixels in the specified drawable are of the same specified color.
+     *
+     * In case there is a color mismatch, the behavior of this method depends on the
+     * <code>throwExceptionIfFails</code> parameter. If it is <code>true</code>, this method will
+     * throw an <code>Exception</code> describing the mismatch. Otherwise this method will call
+     * <code>Assert.fail</code> with detailed description of the mismatch.
+     */
+    public static void assertAllPixelsOfColor(String failMessagePrefix, @NonNull Drawable drawable,
+            int drawableWidth, int drawableHeight, boolean callSetBounds, @ColorInt int color,
+            int allowedComponentVariance, boolean throwExceptionIfFails) {
+            // Create a bitmap
+            Bitmap bitmap = Bitmap.createBitmap(drawableWidth, drawableHeight,
+                    Bitmap.Config.ARGB_8888);
+            // Create a canvas that wraps the bitmap
+            Canvas canvas = new Canvas(bitmap);
+            if (callSetBounds) {
+                // Configure the drawable to have bounds that match the passed size
+                drawable.setBounds(0, 0, drawableWidth, drawableHeight);
+            }
+            // And ask the drawable to draw itself to the canvas / bitmap
+            drawable.draw(canvas);
+
+        try {
+            assertAllPixelsOfColor(failMessagePrefix, bitmap, drawableWidth, drawableHeight, color,
+                    allowedComponentVariance, throwExceptionIfFails);
+        } finally {
+            bitmap.recycle();
+        }
+    }
+
+    /**
+     * Checks whether all the pixels in the specified bitmap are of the same specified color.
+     *
+     * In case there is a color mismatch, the behavior of this method depends on the
+     * <code>throwExceptionIfFails</code> parameter. If it is <code>true</code>, this method will
+     * throw an <code>Exception</code> describing the mismatch. Otherwise this method will call
+     * <code>Assert.fail</code> with detailed description of the mismatch.
+     */
+    public static void assertAllPixelsOfColor(String failMessagePrefix, @NonNull Bitmap bitmap,
+            int bitmapWidth, int bitmapHeight, @ColorInt int color,
+            int allowedComponentVariance, boolean throwExceptionIfFails) {
+            int[] rowPixels = new int[bitmapWidth];
+        for (int row = 0; row < bitmapHeight; row++) {
+            bitmap.getPixels(rowPixels, 0, bitmapWidth, 0, row, bitmapWidth, 1);
+            for (int column = 0; column < bitmapWidth; column++) {
+                int sourceAlpha = Color.alpha(rowPixels[column]);
+                int sourceRed = Color.red(rowPixels[column]);
+                int sourceGreen = Color.green(rowPixels[column]);
+                int sourceBlue = Color.blue(rowPixels[column]);
+
+                int expectedAlpha = Color.alpha(color);
+                int expectedRed = Color.red(color);
+                int expectedGreen = Color.green(color);
+                int expectedBlue = Color.blue(color);
+
+                int varianceAlpha = Math.abs(sourceAlpha - expectedAlpha);
+                int varianceRed = Math.abs(sourceRed - expectedRed);
+                int varianceGreen = Math.abs(sourceGreen - expectedGreen);
+                int varianceBlue = Math.abs(sourceBlue - expectedBlue);
+
+                boolean isColorMatch = (varianceAlpha <= allowedComponentVariance)
+                        && (varianceRed <= allowedComponentVariance)
+                        && (varianceGreen <= allowedComponentVariance)
+                        && (varianceBlue <= allowedComponentVariance);
+
+                if (!isColorMatch) {
+                    String mismatchDescription = failMessagePrefix
+                            + ": expected all drawable colors to be ["
+                            + expectedAlpha + "," + expectedRed + ","
+                            + expectedGreen + "," + expectedBlue
+                            + "] but at position (" + row + "," + column + ") out of ("
+                            + bitmapWidth + "," + bitmapHeight + ") found ["
+                            + sourceAlpha + "," + sourceRed + ","
+                            + sourceGreen + "," + sourceBlue + "]";
+                    if (throwExceptionIfFails) {
+                        throw new RuntimeException(mismatchDescription);
+                    } else {
+                        Assert.fail(mismatchDescription);
+                    }
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/tests/widget/src/android/widget/cts/util/ViewTestUtils.java b/tests/tests/widget/src/android/widget/cts/util/ViewTestUtils.java
new file mode 100644
index 0000000..02ac28c
--- /dev/null
+++ b/tests/tests/widget/src/android/widget/cts/util/ViewTestUtils.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.widget.cts.util;
+
+import junit.framework.Assert;
+
+import android.app.Instrumentation;
+import android.view.View;
+import android.view.ViewTreeObserver;
+import android.view.ViewTreeObserver.OnDrawListener;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Utilities for testing View behavior.
+ */
+public class ViewTestUtils {
+
+    /**
+     * Runs the specified Runnable on the main thread and ensures that the
+     * specified View's tree is drawn before returning.
+     *
+     * @param instrumentation the instrumentation used to run the test
+     * @param view the view whose tree should be drawn before returning
+     * @param runner the runnable to run on the main thread
+     */
+    public static void runOnMainAndDrawSync(Instrumentation instrumentation,
+            final View view, final Runnable runner) {
+        final CountDownLatch latch = new CountDownLatch(1);
+
+        instrumentation.runOnMainSync(() -> {
+            final ViewTreeObserver observer = view.getViewTreeObserver();
+            final OnDrawListener listener = new OnDrawListener() {
+                @Override
+                public void onDraw() {
+                    observer.removeOnDrawListener(this);
+                    view.post(() -> latch.countDown());
+                }
+            };
+
+            observer.addOnDrawListener(listener);
+            runner.run();
+        });
+
+        try {
+            Assert.assertTrue("Expected draw pass occurred within 5 seconds",
+                    latch.await(5, TimeUnit.SECONDS));
+        } catch (InterruptedException e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
diff --git a/tests/tvprovider/Android.mk b/tests/tvprovider/Android.mk
new file mode 100644
index 0000000..1b90a79
--- /dev/null
+++ b/tests/tvprovider/Android.mk
@@ -0,0 +1,34 @@
+# Copyright (C) 2014 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+# don't include this package in any target
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil compatibility-device-util ctstestrunner
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := CtsTvProviderTestCases
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_PACKAGE)
+
diff --git a/tests/tvprovider/AndroidManifest.xml b/tests/tvprovider/AndroidManifest.xml
new file mode 100644
index 0000000..40714a6
--- /dev/null
+++ b/tests/tvprovider/AndroidManifest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="android.tvprovider.cts">
+
+    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+    <uses-permission android:name="com.android.providers.tv.permission.WRITE_EPG_DATA" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+            android:targetPackage="android.tvprovider.cts"
+            android:label="CTS tests for TV Provider" />
+</manifest>
diff --git a/tests/tvprovider/AndroidTest.xml b/tests/tvprovider/AndroidTest.xml
new file mode 100644
index 0000000..f92b37d
--- /dev/null
+++ b/tests/tvprovider/AndroidTest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS TV Provider test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsTvProviderTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.tvprovider.cts" />
+    </test>
+</configuration>
diff --git a/tests/tvprovider/src/android/tvprovider/cts/TvProviderPerfTest.java b/tests/tvprovider/src/android/tvprovider/cts/TvProviderPerfTest.java
new file mode 100644
index 0000000..b5fa019
--- /dev/null
+++ b/tests/tvprovider/src/android/tvprovider/cts/TvProviderPerfTest.java
@@ -0,0 +1,379 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.tvprovider.cts;
+
+import android.content.ComponentName;
+import android.content.ContentProviderOperation;
+import android.content.ContentProviderResult;
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.OperationApplicationException;
+import android.content.pm.PackageManager;
+import android.cts.util.CtsAndroidTestCase;
+import android.database.Cursor;
+import android.media.tv.TvContract;
+import android.media.tv.TvContract.Channels;
+import android.media.tv.TvContract.Programs;
+import android.net.Uri;
+import android.os.RemoteException;
+
+import com.android.compatibility.common.util.DeviceReportLog;
+import com.android.compatibility.common.util.MeasureRun;
+import com.android.compatibility.common.util.MeasureTime;
+import com.android.compatibility.common.util.ResultType;
+import com.android.compatibility.common.util.ResultUnit;
+import com.android.compatibility.common.util.Stat;
+import com.android.cts.util.TimeoutReq;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Test performance of TvProvider on a device. TvProvider typically handles hundreds of
+ * thousands of records periodically, so it is desirable to have performance under a reasonable
+ * bar.
+ */
+public class TvProviderPerfTest extends CtsAndroidTestCase {
+    private static final int TRANSACTION_RUNS = 100;
+    private static final int QUERY_RUNS = 10;
+
+    private ContentResolver mContentResolver;
+    private String mInputId;
+    private boolean mHasTvInputFramework;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mHasTvInputFramework = getContext().getPackageManager().hasSystemFeature(
+                PackageManager.FEATURE_LIVE_TV);
+        if (!mHasTvInputFramework) return;
+        mContentResolver = getContext().getContentResolver();
+        mInputId = TvContract.buildInputId(new ComponentName(getContext(), getClass()));
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        try {
+            if (!mHasTvInputFramework) return;
+            mContentResolver.delete(Programs.CONTENT_URI, null, null);
+            mContentResolver.delete(Channels.CONTENT_URI, null, null);
+        } finally {
+            super.tearDown();
+        }
+    }
+
+    @TimeoutReq(minutes = 8)
+    public void testChannels() throws Exception {
+        if (!mHasTvInputFramework) return;
+        double[] averages = new double[5];
+
+        // Insert
+        final ArrayList<ContentProviderOperation> operations = new ArrayList<>();
+        final int TRANSACTION_SIZE = 1000;
+        double[] applyBatchTimes = MeasureTime.measure(TRANSACTION_RUNS, new MeasureRun() {
+            @Override
+            public void run(int i) {
+                operations.clear();
+                for (int j = 0; j < TRANSACTION_SIZE; ++j) {
+                    ContentValues values = new ContentValues();
+                    values.put(Channels.COLUMN_INPUT_ID, mInputId);
+                    values.put(Channels.COLUMN_SERVICE_TYPE,
+                            Channels.SERVICE_TYPE_AUDIO_VIDEO);
+                    values.put(Channels.COLUMN_TYPE, Channels.TYPE_OTHER);
+                    operations.add(
+                            ContentProviderOperation.newInsert(Channels.CONTENT_URI)
+                            .withValues(values).build());
+                }
+                try {
+                    mContentResolver.applyBatch(TvContract.AUTHORITY, operations);
+                } catch (OperationApplicationException | RemoteException e) {
+                    throw new RuntimeException(e);
+                }
+            }
+        });
+        DeviceReportLog report = new DeviceReportLog();
+        report.addValues("Elapsed time for insert: ",
+                applyBatchTimes, ResultType.LOWER_BETTER, ResultUnit.MS);
+        averages[0] = Stat.getAverage(applyBatchTimes);
+
+        // Update
+        final String[] projection = { Channels._ID };
+        try (final Cursor cursor = mContentResolver.query(Channels.CONTENT_URI,
+                projection, null, null, null)) {
+            applyBatchTimes = MeasureTime.measure(TRANSACTION_RUNS, new MeasureRun() {
+                @Override
+                public void run(int i) {
+                    operations.clear();
+                    for (int j = 0; j < TRANSACTION_SIZE && cursor.moveToNext(); ++j) {
+                        Uri channelUri = TvContract.buildChannelUri(cursor.getLong(0));
+                        String number = Integer.toString(i * TRANSACTION_SIZE + j);
+                        operations.add(
+                                ContentProviderOperation.newUpdate(channelUri)
+                                .withValue(Channels.COLUMN_DISPLAY_NUMBER, number)
+                                .build());
+                    }
+                    try {
+                        mContentResolver.applyBatch(TvContract.AUTHORITY, operations);
+                    } catch (OperationApplicationException | RemoteException e) {
+                        throw new RuntimeException(e);
+                    }
+                }
+            });
+        }
+        report.addValues("Elapsed time for update: ",
+                applyBatchTimes, ResultType.LOWER_BETTER, ResultUnit.MS);
+        averages[1] = Stat.getAverage(applyBatchTimes);
+
+        // Query channels
+        applyBatchTimes = MeasureTime.measure(QUERY_RUNS, new MeasureRun() {
+            @Override
+            public void run(int i) {
+                try (Cursor cursor = mContentResolver.query(Channels.CONTENT_URI, null, null,
+                        null, null)) {
+                    while (cursor.moveToNext()) {
+                        // Do nothing. Just iterate all the items.
+                    }
+                }
+            }
+        });
+        report.addValues("Elapsed time for query (channels): ",
+                applyBatchTimes, ResultType.LOWER_BETTER, ResultUnit.MS);
+        averages[2] = Stat.getAverage(applyBatchTimes);
+
+        // Query a channel
+        try (final Cursor cursor = mContentResolver.query(Channels.CONTENT_URI,
+                projection, null, null, null)) {
+            applyBatchTimes = MeasureTime.measure(QUERY_RUNS, new MeasureRun() {
+                @Override
+                public void run(int i) {
+                    assertTrue(cursor.moveToNext());
+                    try (Cursor c = mContentResolver.query(TvContract.buildChannelUri(
+                            cursor.getLong(0)), null, null, null, null)) {
+                        while (c.moveToNext()) {
+                            // Do nothing. Just iterate all the items.
+                        }
+                    }
+                }
+            });
+        }
+        report.addValues("Elapsed time for query (a channel): ",
+                applyBatchTimes, ResultType.LOWER_BETTER, ResultUnit.MS);
+        averages[3] = Stat.getAverage(applyBatchTimes);
+
+        // Delete
+        applyBatchTimes = MeasureTime.measure(1, new MeasureRun() {
+            @Override
+            public void run(int i) {
+                mContentResolver.delete(TvContract.buildChannelsUriForInput(mInputId), null, null);
+            }
+        });
+        report.addValues("Elapsed time for delete: ",
+                applyBatchTimes, ResultType.LOWER_BETTER, ResultUnit.MS);
+        averages[4] = Stat.getAverage(applyBatchTimes);
+
+        report.addValues("Average elapsed time for insert, update, query (channels), "
+                + "query (a channel), delete: ",
+                averages, ResultType.LOWER_BETTER, ResultUnit.MS);
+        report.submit(getInstrumentation());
+    }
+
+    @TimeoutReq(minutes = 12)
+    public void testPrograms() throws Exception {
+        if (!mHasTvInputFramework) return;
+        double[] averages = new double[7];
+
+        // Prepare (insert channels)
+        final ArrayList<ContentProviderOperation> operations = new ArrayList<>();
+        final int TRANSACTION_SIZE = 1000;
+        final int NUM_CHANNELS = 100;
+        final List<Uri> channelUris = new ArrayList<>();
+
+        operations.clear();
+        for (int i = 0; i < NUM_CHANNELS; ++i) {
+            ContentValues values = new ContentValues();
+            values.put(Channels.COLUMN_INPUT_ID, mInputId);
+            values.put(Channels.COLUMN_SERVICE_TYPE,
+                    Channels.SERVICE_TYPE_AUDIO_VIDEO);
+            values.put(Channels.COLUMN_TYPE, Channels.TYPE_OTHER);
+            operations.add(
+                    ContentProviderOperation.newInsert(Channels.CONTENT_URI)
+                    .withValues(values).build());
+        }
+        try {
+            ContentProviderResult[] results =
+                    mContentResolver.applyBatch(TvContract.AUTHORITY, operations);
+            for (ContentProviderResult result : results) {
+                channelUris.add(result.uri);
+            }
+        } catch (OperationApplicationException | RemoteException e) {
+            throw new RuntimeException(e);
+        }
+
+        // Insert
+        double[] applyBatchTimes = MeasureTime.measure(NUM_CHANNELS, new MeasureRun() {
+            @Override
+            public void run(int i) {
+                operations.clear();
+                Uri channelUri = channelUris.get(i);
+                long channelId = ContentUris.parseId(channelUri);
+                for (int j = 0; j < TRANSACTION_SIZE; ++j) {
+                    ContentValues values = new ContentValues();
+                    values.put(Programs.COLUMN_CHANNEL_ID, channelId);
+                    operations.add(
+                            ContentProviderOperation.newInsert(Programs.CONTENT_URI)
+                            .withValues(values).build());
+                }
+                try {
+                    mContentResolver.applyBatch(TvContract.AUTHORITY, operations);
+                } catch (OperationApplicationException | RemoteException e) {
+                    throw new RuntimeException(e);
+                }
+            }
+        });
+        DeviceReportLog report = new DeviceReportLog();
+        report.addValues("Elapsed time for insert: ",
+                applyBatchTimes, ResultType.LOWER_BETTER, ResultUnit.MS);
+        averages[0] = Stat.getAverage(applyBatchTimes);
+
+        // Update
+        final long PROGRAM_DURATION_MS = 60 * 1000;
+        final String[] projection = { Programs._ID };
+        applyBatchTimes = MeasureTime.measure(NUM_CHANNELS, new MeasureRun() {
+            @Override
+            public void run(int i) {
+                Uri channelUri = channelUris.get(i);
+                operations.clear();
+                try (Cursor cursor = mContentResolver.query(
+                        TvContract.buildProgramsUriForChannel(channelUri),
+                        projection, null, null, null)) {
+                    long startTimeMs = 0;
+                    long endTimeMs = 0;
+                    while (cursor.moveToNext()) {
+                        Uri programUri = TvContract.buildProgramUri(cursor.getLong(0));
+                        endTimeMs += PROGRAM_DURATION_MS;
+                        operations.add(
+                                ContentProviderOperation.newUpdate(programUri)
+                                .withValue(Programs.COLUMN_START_TIME_UTC_MILLIS, startTimeMs)
+                                .withValue(Programs.COLUMN_END_TIME_UTC_MILLIS, endTimeMs)
+                                .build());
+                        startTimeMs = endTimeMs;
+                    }
+                }
+                try {
+                    mContentResolver.applyBatch(TvContract.AUTHORITY, operations);
+                } catch (OperationApplicationException | RemoteException e) {
+                    throw new RuntimeException(e);
+                }
+            }
+        });
+        report.addValues("Elapsed time for update: ",
+                applyBatchTimes, ResultType.LOWER_BETTER, ResultUnit.MS);
+        averages[1] = Stat.getAverage(applyBatchTimes);
+
+        // Query programs
+        applyBatchTimes = MeasureTime.measure(QUERY_RUNS, new MeasureRun() {
+            @Override
+            public void run(int i) {
+                try (Cursor cursor = mContentResolver.query(Programs.CONTENT_URI, null, null,
+                        null, null)) {
+                    while (cursor.moveToNext()) {
+                        // Do nothing. Just iterate all the items.
+                    }
+                }
+            }
+        });
+        report.addValues("Elapsed time for query (programs): ",
+                applyBatchTimes, ResultType.LOWER_BETTER, ResultUnit.MS);
+        averages[2] = Stat.getAverage(applyBatchTimes);
+
+        // Query programs with selection
+        applyBatchTimes = MeasureTime.measure(QUERY_RUNS, new MeasureRun() {
+            @Override
+            public void run(int i) {
+                Uri channelUri = channelUris.get(i);
+                try (Cursor cursor = mContentResolver.query(
+                        TvContract.buildProgramsUriForChannel(
+                                channelUri, 0,
+                                PROGRAM_DURATION_MS * TRANSACTION_SIZE / 2),
+                        null, null, null, null)) {
+                    while (cursor.moveToNext()) {
+                        // Do nothing. Just iterate all the items.
+                    }
+                }
+            }
+        });
+        report.addValues("Elapsed time for query (programs with selection): ",
+                applyBatchTimes, ResultType.LOWER_BETTER, ResultUnit.MS);
+        averages[3] = Stat.getAverage(applyBatchTimes);
+
+        // Query a program
+        try (final Cursor cursor = mContentResolver.query(Programs.CONTENT_URI,
+                projection, null, null, null)) {
+            applyBatchTimes = MeasureTime.measure(QUERY_RUNS, new MeasureRun() {
+                @Override
+                public void run(int i) {
+                    assertTrue(cursor.moveToNext());
+                    try (Cursor c = mContentResolver.query(TvContract.buildProgramUri(
+                            cursor.getLong(0)), null, null, null, null)) {
+                        while (c.moveToNext()) {
+                            // Do nothing. Just iterate all the items.
+                        }
+                    }
+                }
+            });
+        }
+        report.addValues("Elapsed time for query (a program): ",
+                applyBatchTimes, ResultType.LOWER_BETTER, ResultUnit.MS);
+        averages[4] = Stat.getAverage(applyBatchTimes);
+
+        // Delete programs
+        applyBatchTimes = MeasureTime.measure(NUM_CHANNELS, new MeasureRun() {
+            @Override
+            public void run(int i) {
+                Uri channelUri = channelUris.get(i);
+                mContentResolver.delete(
+                        TvContract.buildProgramsUriForChannel(
+                                channelUri,
+                                PROGRAM_DURATION_MS * TRANSACTION_SIZE / 2,
+                                PROGRAM_DURATION_MS * TRANSACTION_SIZE),
+                        null, null);
+            }
+        });
+        report.addValues("Elapsed time for delete programs: ",
+                applyBatchTimes, ResultType.LOWER_BETTER, ResultUnit.MS);
+        averages[5] = Stat.getAverage(applyBatchTimes);
+
+        // Delete channels
+        applyBatchTimes = MeasureTime.measure(NUM_CHANNELS, new MeasureRun() {
+            @Override
+            public void run(int i) {
+                Uri channelUri = channelUris.get(i);
+                mContentResolver.delete(channelUri, null, null);
+            }
+        });
+        report.addValues("Elapsed time for delete channels: ",
+                applyBatchTimes, ResultType.LOWER_BETTER, ResultUnit.MS);
+        averages[6] = Stat.getAverage(applyBatchTimes);
+
+        report.addValues("Average elapsed time for insert, update, query (programs), "
+                + "query (programs with selection), query (a channel), delete (channels), "
+                + "delete (programs): ",
+                averages, ResultType.LOWER_BETTER, ResultUnit.MS);
+        report.submit(getInstrumentation());
+    }
+}
diff --git a/tests/ui/Android.mk b/tests/ui/Android.mk
new file mode 100644
index 0000000..3d13489
--- /dev/null
+++ b/tests/ui/Android.mk
@@ -0,0 +1,36 @@
+# Copyright (C) 2012 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+# don't include this package in any target
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil compatibility-device-util ctstestrunner
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := CtsUiDeviceTestCases
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_SDK_VERSION := 16
+
+include $(BUILD_CTS_PACKAGE)
+
+
diff --git a/tests/ui/AndroidManifest.xml b/tests/ui/AndroidManifest.xml
new file mode 100644
index 0000000..5ed06b4
--- /dev/null
+++ b/tests/ui/AndroidManifest.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2012 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.ui.cts" >
+
+    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+
+        <activity
+            android:name=".ScrollingActivity"
+            android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+
+    <instrumentation
+        android:name="android.support.test.runner.AndroidJUnitRunner"
+        android:label="UI Latency measurement"
+        android:targetPackage="android.ui.cts" >
+        <meta-data
+            android:name="listener"
+            android:value="com.android.cts.runner.CtsTestRunListener" />
+    </instrumentation>
+
+</manifest>
diff --git a/tests/ui/AndroidTest.xml b/tests/ui/AndroidTest.xml
new file mode 100644
index 0000000..de75d28
--- /dev/null
+++ b/tests/ui/AndroidTest.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS UI test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsUiDeviceTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.ui.cts" />
+        <option name="runtime-hint" value="5m" />
+    </test>
+</configuration>
diff --git a/tests/ui/src/android/ui/cts/ScrollingActivity.java b/tests/ui/src/android/ui/cts/ScrollingActivity.java
new file mode 100644
index 0000000..d5fc4b0
--- /dev/null
+++ b/tests/ui/src/android/ui/cts/ScrollingActivity.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.ui.cts;
+
+import android.app.ListActivity;
+import android.os.Bundle;
+import android.widget.AbsListView;
+import android.widget.AbsListView.OnScrollListener;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Activity for measuring scrolling time of long list.
+ */
+public class ScrollingActivity extends ListActivity implements OnScrollListener {
+    static final String TAG = "ScrollingActivity";
+    private static final String NUM_ELEMENTS_EXTRA = "num_elements";
+    private static final int NUM_ELEMENTS_DEFAULT = 10000;
+    private static final int SCROLL_TIME_IN_MS = 1;
+    private static final int WAIT_TIMEOUT_IN_SECS = 5 * 60;
+    private String[] mItems;
+    private CountDownLatch mLatchStop = null;
+    private int mTargetLoc;
+    private int mNumElements;
+
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        mNumElements = getIntent().getIntExtra(NUM_ELEMENTS_EXTRA, NUM_ELEMENTS_DEFAULT);
+        mItems = new String[mNumElements];
+        for (int i = 0; i < mNumElements; i++) {
+            mItems[i] = Integer.toString(i);
+        }
+        setListAdapter(new ArrayAdapter<String>(this,
+                android.R.layout.simple_list_item_1, mItems));
+        ListView view = getListView();
+        view.setOnScrollListener(this);
+    }
+
+    public boolean scrollToTop() {
+        return doScroll(0);
+    }
+    public boolean scrollToBottom() {
+        return doScroll(mNumElements - 1);
+    }
+
+    private boolean doScroll(final int loc) {
+        mLatchStop = new CountDownLatch(1);
+        mTargetLoc = loc;
+        final ListView view = getListView();
+        runOnUiThread( new Runnable() {
+            @Override
+            public void run() {
+                view.smoothScrollToPositionFromTop(loc, 0, SCROLL_TIME_IN_MS);
+            }
+        });
+        boolean result = false;
+        try {
+            result = mLatchStop.await(WAIT_TIMEOUT_IN_SECS, TimeUnit.SECONDS);
+        } catch (InterruptedException e) {
+            // ignore
+        }
+        mLatchStop = null;
+        return result;
+    }
+
+    @Override
+    public void onScrollStateChanged(AbsListView view, int scrollState) {
+
+    }
+
+    @Override
+    public void onScroll(AbsListView view, int firstVisibleItem,
+            int visibleItemCount, int totalItemCount) {
+        //Log.i(TAG, "onScroll " + firstVisibleItem + " " + visibleItemCount);
+        if ((mTargetLoc >= firstVisibleItem) &&
+                (mTargetLoc <= (firstVisibleItem + visibleItemCount))) {
+            if (mLatchStop != null) {
+                mLatchStop.countDown();
+            }
+        }
+    }
+}
diff --git a/tests/ui/src/android/ui/cts/ScrollingTest.java b/tests/ui/src/android/ui/cts/ScrollingTest.java
new file mode 100644
index 0000000..4902807
--- /dev/null
+++ b/tests/ui/src/android/ui/cts/ScrollingTest.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.ui.cts;
+
+import android.test.ActivityInstrumentationTestCase2;
+
+import com.android.compatibility.common.util.DeviceReportLog;
+import com.android.compatibility.common.util.MeasureRun;
+import com.android.compatibility.common.util.MeasureTime;
+import com.android.compatibility.common.util.ResultType;
+import com.android.compatibility.common.util.ResultUnit;
+import com.android.compatibility.common.util.Stat;
+import com.android.cts.util.TimeoutReq;
+
+import java.io.IOException;
+
+public class ScrollingTest extends ActivityInstrumentationTestCase2<ScrollingActivity> {
+    private ScrollingActivity mActivity;
+
+    public ScrollingTest() {
+        super(ScrollingActivity.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mActivity = getActivity();
+        getInstrumentation().waitForIdleSync();
+        try {
+            runTestOnUiThread(new Runnable() {
+                @Override
+                public void run() {
+                }
+            });
+        } catch (Throwable e) {
+            e.printStackTrace();
+            fail();
+        }
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        mActivity = null;
+        super.tearDown();
+    }
+
+    @TimeoutReq(minutes = 30)
+    public void testFullScrolling() throws Exception {
+        final int NUMBER_REPEAT = 10;
+        final ScrollingActivity activity = mActivity;
+        double[] results = MeasureTime.measure(NUMBER_REPEAT, new MeasureRun() {
+
+            @Override
+            public void run(int i) throws IOException {
+                assertTrue(activity.scrollToBottom());
+                assertTrue(activity.scrollToTop());
+            }
+        });
+        DeviceReportLog report = new DeviceReportLog();
+        report.addValues("scrolling time", results, ResultType.LOWER_BETTER,ResultUnit.MS);
+        Stat.StatResult stat = Stat.getStat(results);
+        report.setSummary("scrolling time", stat.mAverage, ResultType.LOWER_BETTER,ResultUnit.MS);
+        report.submit(getInstrumentation());
+    }
+}
diff --git a/tests/uiautomator/Android.mk b/tests/uiautomator/Android.mk
deleted file mode 100644
index d0d4b8e..0000000
--- a/tests/uiautomator/Android.mk
+++ /dev/null
@@ -1,34 +0,0 @@
-# Copyright (C) 2012 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA)/local/tmp
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_MODULE := CtsUiAutomatorTests
-LOCAL_JAVA_LIBRARIES := uiautomator.core
-LOCAL_PROGUARD_ENABLED := disabled
-LOCAL_CTS_TEST_APK := CtsUiAutomatorApp
-LOCAL_CTS_TEST_APP_PACKAGE := com.android.cts.uiautomator
-LOCAL_CTS_TEST_PACKAGE := android.uiautomator
-
-include $(BUILD_CTS_UI_JAVA_LIBRARY)
-
-# Build the test APK using its own makefile, and any other CTS-related packages
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/uiautomator/src/com/android/cts/uiautomatortest/CtsUiAutomatorTest.java b/tests/uiautomator/src/com/android/cts/uiautomatortest/CtsUiAutomatorTest.java
deleted file mode 100644
index 7e4c367..0000000
--- a/tests/uiautomator/src/com/android/cts/uiautomatortest/CtsUiAutomatorTest.java
+++ /dev/null
@@ -1,1072 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.cts.uiautomatortest;
-
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.os.RemoteException;
-import android.os.SystemClock;
-import android.util.Log;
-
-import com.android.uiautomator.core.UiCollection;
-import com.android.uiautomator.core.UiDevice;
-import com.android.uiautomator.core.UiObject;
-import com.android.uiautomator.core.UiObjectNotFoundException;
-import com.android.uiautomator.core.UiScrollable;
-import com.android.uiautomator.core.UiSelector;
-import com.android.uiautomator.core.UiWatcher;
-import com.android.uiautomator.testrunner.UiAutomatorTestCase;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.IOException;
-
-/**
- * Sanity test uiautomator functionality on target device.
- */
-public class CtsUiAutomatorTest extends UiAutomatorTestCase {
-    private static final String LOG_TAG = CtsUiAutomatorTest.class.getSimpleName();
-    private static final String[] LIST_SCROLL_TESTS = new String[] {
-            "Test 17", "Test 11", "Test 20", "Test 35"
-    };
-    private static final String LAUNCH_APP = "am start -a android.intent.action.MAIN"
-            + " -n com.android.cts.uiautomator/.MainActivity -W";
-    private static final String PKG_NAME = "com.android.cts.uiautomator";
-
-    // Maximum wait for key object to become visible
-    private static final int WAIT_EXIST_TIMEOUT = 5 * 1000;
-
-    private static final String SCREEN_SHOT_FILE_PATH_NAME = "/data/local/tmp/ctsScreenShot";
-
-    // Should match the value defined in UiObject
-    private static final int FINGER_TOUCH_HALF_WIDTH = 20;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        // Make sure the test app is always running
-        UiDevice.getInstance().waitForIdle();
-        if (!new UiObject(new UiSelector().packageName(PKG_NAME)).exists())
-            runShellCommand(LAUNCH_APP);
-    }
-
-    /**
-     * Helper to execute a command on the shell
-     *
-     * @throws IOException
-     * @throws InterruptedException
-     */
-    private void runShellCommand(String command) throws IOException, InterruptedException {
-        Process p = null;
-        BufferedReader resultReader = null;
-        try {
-            p = Runtime.getRuntime().exec(command);
-            int status = p.waitFor();
-            if (status != 0) {
-                throw new RuntimeException(String.format("Run shell command: %s, status: %s",
-                        command, status));
-            }
-        } finally {
-            if (resultReader != null) {
-                resultReader.close();
-            }
-            if (p != null) {
-                p.destroy();
-            }
-        }
-    }
-
-    /*
-     * Items in the listScrollTests array should be spread out such that a
-     * scroll is required to reach each item at each of the far ends.
-     */
-    public void testListScrollAndSelect() throws UiObjectNotFoundException {
-        UiScrollable listView = new UiScrollable(
-                new UiSelector().className(android.widget.ListView.class.getName()));
-
-        // on single fragment display
-        if (!listView.exists())
-            UiDevice.getInstance().pressBack();
-
-        for (String test : LIST_SCROLL_TESTS) {
-            openTest(test);
-            verifyTestDetailsExists(test);
-        }
-    }
-
-    /**
-     * Test erasing of multi word text in edit field and input of new text. Test
-     * verifying input text using a complex UiSelector
-     *
-     * @throws UiObjectNotFoundException
-     */
-    public void testTextEraseAndInput() throws UiObjectNotFoundException {
-        String testText = "Android Ui Automator Input Text";
-        openTest("Test 1");
-
-        UiObject editText = new UiObject(new UiSelector().className(android.widget.EditText.class
-                .getName()));
-        editText.setText(testText);
-
-        UiObject submitButton = new UiObject(new UiSelector()
-                .className(android.widget.Button.class.getName()).clickable(true)
-                .textStartsWith("Submit"));
-        submitButton.click();
-
-        UiObject result = new UiObject(new UiSelector().className(
-                android.widget.LinearLayout.class.getName()).childSelector(
-                (new UiSelector().className(android.widget.ScrollView.class.getName())
-                        .childSelector(new UiSelector().className(android.widget.TextView.class
-                                .getName())))));
-
-        if (!testText.equals(result.getText())) {
-            throw new UiObjectNotFoundException("Test text: " + testText);
-        }
-
-        getObjectByText("OK").click();
-    }
-
-    /**
-     * Select each of the buttons by using only the content description property
-     *
-     * @throws UiObjectNotFoundException
-     */
-    public void testSelectByContentDescription() throws UiObjectNotFoundException {
-        openTest("Test 2");
-        getObjectByDescription("Button 1").click();
-        verifyDialogActionResults("Button 1");
-        getObjectByDescription("Button 2").click();
-        verifyDialogActionResults("Button 2");
-        getObjectByDescription("Button 3").click();
-        verifyDialogActionResults("Button 3");
-    }
-
-    /**
-     * Select each of the buttons by using only the text property
-     *
-     * @throws UiObjectNotFoundException
-     */
-    public void testSelectByText() throws UiObjectNotFoundException {
-        openTest("Test 2");
-        getObjectByText("Button 1").click();
-        verifyDialogActionResults("Button 1");
-        getObjectByText("Button 2").click();
-        verifyDialogActionResults("Button 2");
-        getObjectByText("Button 3").click();
-        verifyDialogActionResults("Button 3");
-    }
-
-    /**
-     * Select each of the buttons by using only the index property
-     *
-     * @throws UiObjectNotFoundException
-     */
-    public void testSelectByIndex() throws UiObjectNotFoundException {
-        openTest("Test 2");
-        getObjectByIndex(android.widget.Button.class.getName(), 0).click();
-        verifyDialogActionResults("Button 1");
-        getObjectByIndex(android.widget.Button.class.getName(), 1).click();
-        verifyDialogActionResults("Button 2");
-        getObjectByIndex(android.widget.Button.class.getName(), 2).click();
-        verifyDialogActionResults("Button 3");
-    }
-
-    /**
-     * Select each of the buttons by using only the instance number
-     *
-     * @throws UiObjectNotFoundException
-     */
-    public void testSelectByInstance() throws UiObjectNotFoundException {
-        openTest("Test 2");
-        getObjectByInstance(android.widget.Button.class.getName(), 0).click();
-        verifyDialogActionResults("Button 1");
-        getObjectByInstance(android.widget.Button.class.getName(), 1).click();
-        verifyDialogActionResults("Button 2");
-        getObjectByInstance(android.widget.Button.class.getName(), 2).click();
-        verifyDialogActionResults("Button 3");
-    }
-
-    /**
-     * Test when a node's state is changed due to an action, it is updated in the accessibility
-     * hierarchy.
-     *
-     * @throws UiObjectNotFoundException
-     */
-    public void testSelectAfterContentChanged() throws UiObjectNotFoundException {
-        openTest("Test 2");
-        UiObject dynaButton = getObjectByText("Before");
-        dynaButton.click();
-        assertTrue("Button state change is not refreshed in accessibility hierarchy",
-                getObjectByText("After").exists());
-    }
-
-    /**
-     * Test opening the options menu using the soft buttons
-     *
-     * @throws UiObjectNotFoundException
-     * @throws InterruptedException
-     * @throws IOException
-     */
-    public void testDeviceSoftKeys() throws UiObjectNotFoundException, IOException,
-            InterruptedException {
-        openTest("Test 2");
-        UiDevice device = UiDevice.getInstance();
-        device.pressMenu();
-        getObjectByText("Finish").click();
-        verifyDialogActionResults("Finish");
-
-        // Back button
-        openTest("Test 1");
-        UiObject editText = new UiObject(new UiSelector().className(android.widget.EditText.class
-                .getName()));
-        editText.setText("Android Geppetto Test Application");
-
-        UiObject submitButton = new UiObject(new UiSelector()
-                .className(android.widget.Button.class.getName()).clickable(true)
-                .textStartsWith("Submit"));
-        submitButton.click();
-
-        // Text from the popup dialog
-        UiObject result = new UiObject(new UiSelector().textContains("geppetto"));
-
-        // Back button test to dismiss the dialog
-        assertTrue("Wait for exist must return true", result.waitForExists(2000));
-        device.pressBack();
-        result.waitUntilGone(1000);
-        assertFalse("Wait for exist must return false after press back", result.exists());
-
-        // Home button test
-        openTest("Test 5");
-        String pkgName = device.getCurrentPackageName();
-        assertTrue("CTS test app must be running", pkgName.equals(PKG_NAME));
-        device.pressHome();
-        boolean gone = new UiObject(new UiSelector().packageName(PKG_NAME)).waitUntilGone(5000);
-        assertTrue("CTS test app still visble after pressing home", gone);
-    }
-
-    /**
-     * This view is in constant update generating window content changed events.
-     * The test will read the time displayed and exhaust each wait for idle
-     * timeout until it read and sets the text back into the edit field and
-     * presses submit. A dialog box should pop up with the time it took since
-     * reading the value until pressing submit.
-     *
-     * @throws UiObjectNotFoundException
-     */
-    public void testWaitForIdleTimeout() throws UiObjectNotFoundException {
-        openTest("Test 3");
-        UiObject clk = new UiObject(new UiSelector().descriptionStartsWith("Performance "));
-
-        // First default wait for idle timeout assumed to be 10 seconds
-        String txtTime = clk.getText();
-        UiObject edit = new UiObject(new UiSelector().className(android.widget.EditText.class
-                .getName()));
-
-        // Second default wait for idle timeout assumed to be 10 seconds.
-        // Total ~20.
-        edit.setText(txtTime);
-
-        // Third default wait for idle timeout assumed to be 10 seconds.
-        // Total ~30.
-        getObjectByText("Submit").click();
-
-        // The value read should have value between 30 and 60 seconds indicating
-        // that the internal default timeouts for wait-for-idle is in acceptable
-        // range.
-        UiObject readTime = new UiObject(new UiSelector().className(
-                android.widget.TextView.class.getName()).instance(1));
-        String timeDiff = readTime.getText();
-        Log.i(LOG_TAG, "Sync time: " + timeDiff);
-
-        getObjectByText("OK").click();
-
-        int totalDelay = Integer.parseInt(timeDiff);
-
-        // Cumulative waits in this test should add up to at minimum 30 seconds
-        assertFalse("Timeout for wait-for-idle is too short. Expecting minimum 30 seconds",
-                totalDelay < 30 * 1000);
-
-        // allow for tolerance in time measurements due to differences between
-        // device speeds
-        assertFalse("Timeout for wait-for-idle is too long. Expecting maximum 60 seconds",
-                totalDelay > 60 * 1000);
-    }
-
-    /**
-     * This view is in constant update generating window content changed events.
-     * This test uses the soft key presses and clicks while the background
-     * screen is constantly updating causing a constant busy state.
-     *
-     * @throws UiObjectNotFoundException
-     */
-    public void testVerifyMenuClicks() throws UiObjectNotFoundException {
-        openTest("Test 3");
-        UiDevice.getInstance().pressMenu();
-        new UiObject(new UiSelector().text("Submit")).click();
-        verifyDialogActionResults("Submit");
-        UiDevice.getInstance().pressMenu();
-        new UiObject(new UiSelector().text("Exit")).click();
-        verifyDialogActionResults("Exit");
-    }
-
-    /**
-     * Verifies swipeRight, swipeLeft and raw swipe APIs perform as expected.
-     *
-     * @throws UiObjectNotFoundException
-     */
-    public void testSwipes() throws UiObjectNotFoundException {
-        openTest("Test 4");
-        UiObject textView = new UiObject(new UiSelector().textContains("["));
-
-        textView.swipeLeft(10);
-        assertTrue("UiObject swipe left 1->2", "[ 2 ]".equals(textView.getText()));
-
-        textView.swipeLeft(10);
-        assertTrue("UiObject swipe left 2->3", "[ 3 ]".equals(textView.getText()));
-
-        textView.swipeLeft(10);
-        assertTrue("UiObject swipe left 3->4", "[ 4 ]".equals(textView.getText()));
-
-        textView.swipeRight(10);
-        assertTrue("UiObject swipe right 3<-4", "[ 3 ]".equals(textView.getText()));
-
-        textView.swipeRight(10);
-        assertTrue("UiObject swipe right 2<-3", "[ 2 ]".equals(textView.getText()));
-
-        textView.swipeRight(10);
-        assertTrue("UiObject swipe right 1<-2", "[ 1 ]".equals(textView.getText()));
-
-        Rect tb = textView.getBounds();
-        UiDevice.getInstance().swipe(tb.right - 20, tb.centerY(), tb.left + 20, tb.centerY(), 50);
-
-        SystemClock.sleep(100);
-        assertTrue("UiDevice raw swipe 1->2", "[ 2 ]".equals(textView.getText()));
-    }
-
-    /**
-     * Creates a complex selector
-     *
-     * @throws UiObjectNotFoundException
-     */
-    public void testComplexSelectors() throws UiObjectNotFoundException {
-        openTest("Test 5");
-        UiSelector frameLayout = new UiSelector().className(android.widget.FrameLayout.class
-                .getName());
-        UiSelector gridLayout = new UiSelector().className(android.widget.GridLayout.class
-                .getName());
-        UiSelector toggleButton = new UiSelector().className(android.widget.ToggleButton.class
-                .getName());
-        UiObject button = new UiObject(frameLayout.childSelector(gridLayout).childSelector(
-                toggleButton));
-
-        assertTrue("Toggle button value should be OFF", "OFF".equals(button.getText()));
-        button.click();
-        assertTrue("Toggle button value should be ON", "ON".equals(button.getText()));
-        button.click();
-        assertTrue("Toggle button value should be OFF", "OFF".equals(button.getText()));
-    }
-
-    /**
-     * Test when an object does not exist, an exception is thrown
-     * @throws UiObjectNotFoundException
-     */
-    public void testExceptionObjectNotFound() throws UiObjectNotFoundException {
-        UiSelector selector = new UiSelector().text("Nothing should be found");
-        UiSelector child = new UiSelector().className("Nothing");
-        UiObject obj = new UiObject(selector.childSelector(child));
-
-        assertFalse("Object is reported as existing", obj.exists());
-
-        try {
-            obj.click();
-        } catch (UiObjectNotFoundException e) {
-            return;
-        }
-        assertTrue("Exception not thrown for Object not found", false);
-    }
-
-    /**
-     * Verifies the UiWatcher registration and trigger function
-     *
-     * @throws UiObjectNotFoundException
-     */
-    public void testUiWatcher() throws UiObjectNotFoundException {
-        openTest("Test 5");
-        UiDevice device = UiDevice.getInstance();
-        device.registerWatcher("Artificial crash", new UiWatcher() {
-
-            @Override
-            public boolean checkForCondition() {
-                if (new UiObject(new UiSelector().packageName("android")).exists()) {
-                    try {
-                        // Expecting a localized OK button
-                        new UiObject(new UiSelector().className(
-                                android.widget.Button.class.getName()).enabled(true)).click();
-                    } catch (UiObjectNotFoundException e) {
-                    }
-                    return true;
-                }
-                return false;
-            }
-        });
-
-        // Causes a runtime exception to be thrown
-        getObjectByText("Button").click();
-
-        // Fake doing something while the exception is being displayed
-        SystemClock.sleep(2000);
-        device.runWatchers();
-        assertTrue("UiWatcher not triggered", device.hasAnyWatcherTriggered());
-    }
-
-    /**
-     * Verifies the 'checked' property of both UiSelector and UiObject
-     *
-     * @throws UiObjectNotFoundException
-     */
-    public void testSelectorChecked() throws UiObjectNotFoundException {
-        openTest("Test 5");
-        UiObject checkboxChecked = new UiObject(new UiSelector().className(
-                android.widget.CheckBox.class.getName()).checked(true));
-        UiObject checkboxNotChecked = new UiObject(new UiSelector().className(
-                android.widget.CheckBox.class.getName()).checked(false));
-
-        checkboxNotChecked.click();
-        assertTrue("Checkbox should be checked", checkboxChecked.isChecked());
-        checkboxChecked.click();
-        assertFalse("Checkbox should be unchecked", checkboxNotChecked.isChecked());
-    }
-
-    /**
-     * Verifies the 'Clickable' property of both the UiSelector and UiObject
-     *
-     * @throws UiObjectNotFoundException
-     */
-    public void testSelectorClickable() throws UiObjectNotFoundException {
-        openTest("Test 5");
-        UiSelector clickableCheckbox = new UiSelector().clickable(true).className(
-                android.widget.CheckBox.class.getName());
-        UiSelector notClickableProgress = new UiSelector().clickable(false).className(
-                android.widget.ProgressBar.class.getName());
-
-        assertTrue("Selector clickable", new UiObject(clickableCheckbox).isClickable());
-        assertFalse("Selector not clickable", new UiObject(notClickableProgress).isClickable());
-    }
-
-    /**
-     * Verifies the 'focusable' property of both UiSelector and UiObject
-     *
-     * @throws UiObjectNotFoundException
-     */
-    public void testSelectorFocusable() throws UiObjectNotFoundException {
-        openTest("Test 5");
-        UiSelector mainLayout = new UiSelector().description("Widgets Collection");
-        UiSelector focusableCheckbox = mainLayout.childSelector(new UiSelector().className(
-                android.widget.CheckBox.class.getName()).focusable(true));
-        UiSelector notFocusableSpinner = mainLayout.childSelector(new UiSelector().className(
-                android.widget.Spinner.class.getName()).focusable(false));
-
-        assertTrue("Selector focusable", new UiObject(focusableCheckbox).isFocusable());
-        assertFalse("Selector not focusable", new UiObject(notFocusableSpinner).isFocusable());
-    }
-
-    /**
-     * Verifies the 'DescriptionContains' property of UiSelector
-     *
-     * @throws UiObjectNotFoundException
-     */
-    public void testSelectorDescriptionContains() throws UiObjectNotFoundException {
-        openTest("Test 5");
-        UiSelector progressDescriptionContains = new UiSelector().descriptionContains("%");
-        assertTrue("Selector descriptionContains", "Progress is 50 %".equals(new UiObject(
-                progressDescriptionContains).getContentDescription()));
-    }
-
-    /**
-     * Verifies the 'DescriptionStarts' property of UiSelector
-     *
-     * @throws UiObjectNotFoundException
-     */
-    public void testSelectorDescriptionStarts() throws UiObjectNotFoundException {
-        openTest("Test 5");
-        UiSelector progressDescriptionStart = new UiSelector().descriptionStartsWith("progress");
-        assertTrue("Selector descriptionStart", "Progress is 50 %".equals(new UiObject(
-                progressDescriptionStart).getContentDescription()));
-    }
-
-    /**
-     * Verifies the 'Enabled' property of both UiSelector and UiObject
-     *
-     * @throws UiObjectNotFoundException
-     */
-    public void testSelectorEnabled() throws UiObjectNotFoundException {
-        openTest("Test 5");
-        UiSelector mainLayout = new UiSelector().description("Widgets Collection");
-        UiSelector buttonDisabled = mainLayout.childSelector(new UiSelector().className(
-                android.widget.Button.class.getName()).enabled(false));
-        UiSelector buttonEnabled = mainLayout.childSelector(new UiSelector().className(
-                android.widget.Button.class.getName()).enabled(true));
-
-        assertFalse("Selector enabled false", new UiObject(buttonDisabled).isEnabled());
-        assertTrue("Selector enabled true", new UiObject(buttonEnabled).isEnabled());
-    }
-
-    /**
-     * Verifies the UiCollection object child counting by object pattern
-     *
-     * @throws UiObjectNotFoundException
-     */
-    public void testCollectionCount() throws UiObjectNotFoundException {
-        openTest("Test 5");
-        UiCollection collection = new UiCollection(
-                new UiSelector().description("Widgets Collection"));
-        assertTrue("Collection layout not found", collection.waitForExists(WAIT_EXIST_TIMEOUT));
-
-        assertTrue("Collection count",
-                collection.getChildCount(new UiSelector().clickable(true)) == 6);
-    }
-
-    /**
-     * Verifies the UiCollection can find an object by text and returning by
-     * pattern
-     *
-     * @throws UiObjectNotFoundException
-     */
-    public void testCollectionGetChildByText() throws UiObjectNotFoundException {
-        openTest("Test 5");
-        UiCollection collection = new UiCollection(
-                new UiSelector().description("Widgets Collection"));
-        assertTrue("Collection layout not found", collection.waitForExists(WAIT_EXIST_TIMEOUT));
-
-        UiObject item = collection.getChildByText(
-                new UiSelector().className(android.widget.Button.class.getName()), "Button");
-
-        assertTrue("Collection get child by text", "Button".equals(item.getText()));
-    }
-
-    /**
-     * Verifies the UiCollection can find an object by instance and returning by
-     * pattern
-     *
-     * @throws UiObjectNotFoundException
-     */
-    public void testCollectionGetChildByInstance() throws UiObjectNotFoundException {
-        openTest("Test 5");
-        UiCollection collection = new UiCollection(
-                new UiSelector().description("Widgets Collection"));
-        assertTrue("Collection layout not found", collection.waitForExists(WAIT_EXIST_TIMEOUT));
-
-        // find the second button
-        UiObject item = collection.getChildByInstance(
-                new UiSelector().className(android.widget.Button.class.getName()), 1);
-
-        assertTrue("Collection get child by instance", "Button".equals(item.getText()));
-    }
-
-    /**
-     * Verifies the UiCollection can find an object by description and returning
-     * by pattern
-     *
-     * @throws UiObjectNotFoundException
-     */
-    public void testCollectionGetChildByDescription() throws UiObjectNotFoundException {
-        openTest("Test 5");
-        UiCollection collection = new UiCollection(
-                new UiSelector().description("Widgets Collection"));
-        assertTrue("Collection layout not found", collection.waitForExists(WAIT_EXIST_TIMEOUT));
-
-        UiObject item = collection.getChildByDescription(
-                new UiSelector().className(android.widget.Button.class.getName()),
-                "Description for Button");
-
-        assertTrue("Collection get child by description", "Button".equals(item.getText()));
-    }
-
-    /**
-     * Test Orientation APIs by causing rotations and verifying current state
-     *
-     * @throws RemoteException
-     * @throws UiObjectNotFoundException
-     * @since API Level 17
-     */
-    public void testRotation() throws RemoteException, UiObjectNotFoundException {
-        openTest("Test 5");
-        UiDevice device = UiDevice.getInstance();
-
-        device.setOrientationLeft();
-        device.waitForIdle(); // isNaturalOrientation is not waiting for idle
-        SystemClock.sleep(1000);
-        assertFalse("Device orientation should not be natural", device.isNaturalOrientation());
-
-        device.setOrientationNatural();
-        device.waitForIdle(); // isNaturalOrientation is not waiting for idle
-        SystemClock.sleep(1000);
-        assertTrue("Device orientation should be natural", device.isNaturalOrientation());
-
-        device.setOrientationRight();
-        device.waitForIdle(); // isNaturalOrientation is not waiting for idle
-        SystemClock.sleep(1000);
-        assertFalse("Device orientation should not be natural", device.isNaturalOrientation());
-
-        device.setOrientationNatural();
-    }
-
-    /**
-     * Reads the current device's product name. Since it is not possible to predetermine the
-     * would be value, the check verifies that the value is not null and not empty.
-     *
-     * @since API Level 17
-     */
-    public void testGetProductName() {
-        String name = UiDevice.getInstance().getProductName();
-        assertFalse("Product name check returned empty string", name.isEmpty());
-    }
-
-    /**
-     * Select each of the buttons by using only regex text
-     *
-     * @throws UiObjectNotFoundException
-     * @since API Level 17
-     */
-    public void testSelectByTextMatch() throws UiObjectNotFoundException {
-        openTest("Test 2");
-        getObjectByTextMatch(".*n\\s1$").click();
-        verifyDialogActionResults("Button 1");
-        getObjectByTextMatch(".*n\\s2$").click();
-        verifyDialogActionResults("Button 2");
-        getObjectByTextMatch(".*n\\s3$").click();
-        verifyDialogActionResults("Button 3");
-    }
-
-    /**
-     * Select each of the buttons by using only regex content-description
-     *
-     * @throws UiObjectNotFoundException
-     * @since API Level 17
-     */
-    public void testSelectByDescriptionMatch() throws UiObjectNotFoundException {
-        openTest("Test 2");
-        getObjectByDescriptionMatch(".*n\\s1$").click();
-        verifyDialogActionResults("Button 1");
-        getObjectByDescriptionMatch(".*n\\s2$").click();
-        verifyDialogActionResults("Button 2");
-        getObjectByDescriptionMatch(".*n\\s3$").click();
-        verifyDialogActionResults("Button 3");
-    }
-
-    /**
-     * Select each of the buttons by using only regex class name
-     *
-     * @throws UiObjectNotFoundException
-     * @since API Level 17
-     */
-    public void testSelectByClassMatch() throws UiObjectNotFoundException {
-        openTest("Test 5");
-        UiObject tgl = getObjectByClassMatch(".*ToggleButton$", 0);
-        String tglValue = tgl.getText();
-        tgl.click();
-
-        assertFalse("Matching class by Regex failed", tglValue.equals(tgl.getText()));
-    }
-
-    /**
-     * Select each of the buttons by using only class type
-     *
-     * @throws UiObjectNotFoundException
-     * @since API Level 17
-     */
-    public void testSelectByClassType() throws UiObjectNotFoundException {
-        openTest("Test 5");
-        UiObject tgl = getObjectByClass(android.widget.ToggleButton.class, 0);
-        String tglValue = tgl.getText();
-        tgl.click();
-
-        assertFalse("Matching class by class type failed", tglValue.equals(tgl.getText()));
-    }
-
-    /**
-     * Test the coordinates of 3 buttons side by side verifying vertical and
-     * horizontal coordinates.
-     *
-     * @throws UiObjectNotFoundException
-     * @since API Level 17
-     */
-    public void testGetVisibleBounds() throws UiObjectNotFoundException {
-        openTest("Test 2");
-        Rect rect1 = getObjectByText("Button 1").getVisibleBounds();
-        Rect rect2 = getObjectByText("Button 2").getVisibleBounds();
-        Rect rect3 = getObjectByText("Button 3").getVisibleBounds();
-
-        assertTrue("X coordinate check failed",
-                rect1.left < rect2.left && rect2.right < rect3.right);
-        assertTrue("Y coordinate check failed",
-                rect1.top == rect2.top && rect2.bottom == rect3.bottom);
-    }
-
-   /**
-     * Tests the LongClick functionality in the API
-     *
-     * @throws UiObjectNotFoundException
-     * @since API Level 17
-     */
-    public void testSelectorLongClickable() throws UiObjectNotFoundException {
-        openTest("Test 2");
-        getObjectByText("Button 1").longClick();
-        verifyDialogActionResults("Longclick Button 1");
-    }
-
-    /**
-     * Test the UiSelector's long-clickable property
-     *
-     * @throws UiObjectNotFoundException
-     * @since API Level 17
-     */
-    public void testSelectorLongClickableProperty() throws UiObjectNotFoundException {
-        openTest("Test 2");
-        UiObject button3 = new UiObject(new UiSelector().className(
-                android.widget.Button.class).longClickable(true).instance(2));
-        button3.longClick();
-        verifyDialogActionResults("Longclick Button 3");
-    }
-
-    /**
-     * Takes a screen shot of the current display and checks if the file is
-     * created and is not zero size.
-     *
-     * @since API Level 17
-     */
-    public void testTakeScreenShots() {
-        File storePath = new File(SCREEN_SHOT_FILE_PATH_NAME);
-        getUiDevice().takeScreenshot(storePath);
-
-        assertTrue("Screenshot file not detected in store", storePath.exists());
-        assertTrue("Zero size for screenshot file", storePath.length() > 0);
-    }
-
-    /**
-     * Verifies the 'Resource-Id' property of UiSelector
-     *
-     * @throws UiObjectNotFoundException
-     * @since API Level 18
-     */
-    public void testSelectorResourceId() throws UiObjectNotFoundException {
-        openTest("Test 5");
-        UiSelector toggleSelector =
-                new UiSelector().resourceId("com.android.cts.uiautomator:id/test_5_toggleButton");
-        UiObject toggleButton = new UiObject(toggleSelector);
-        assertTrue("Object with selector resource-id not found", toggleButton.exists());
-        assertTrue("Incorrect object for selector resource-id returned",
-                "OFF".equals(toggleButton.getText()) || "ON".equals(toggleButton.getText()));
-    }
-
-    /**
-     * Verify the UiSelector property resourceIdMatches
-     *
-     * @throws UiObjectNotFoundException
-     * @since API Level 18
-     */
-    public void testSelectorResourceIdMatches() throws UiObjectNotFoundException {
-        openTest("Test 2");
-        new UiObject(new UiSelector().resourceIdMatches("(?i).*button.*").instance(2)).click();
-        verifyDialogActionResults("Button 3");
-        new UiObject(new UiSelector().resourceIdMatches("(?i).*button1.*")).click();
-        verifyDialogActionResults("Button 1");
-    }
-
-    /**
-     * Performs a pinch out from the center of a view to its edges and listens to
-     * the motion events to make sure the starting and ending points of both pointers
-     * are correct.
-     *
-     * @throws UiObjectNotFoundException
-     * @since API Level 18
-     */
-    public void testPinchOut() throws UiObjectNotFoundException {
-        openTest("Test 12");
-
-        UiObject screen = new UiObject(
-                new UiSelector().description("Details View"));
-
-        // get the current view dimensions
-        Rect screenRect = screen.getBounds();
-
-        // perform the pinch for 100% of the view dimensions starting form
-        // the center out to the edges.
-        screen.pinchOut(100, 30);
-
-        // dialog with the detected pointers motion coordinates is displayed.
-        UiObject results = new UiObject(new UiSelector().className(
-                android.widget.ScrollView.class).childSelector(new UiSelector().className(
-                        android.widget.TextView.class)));
-        String allPointers = results.getText();
-        new UiObject(new UiSelector().text("OK")).click(); // dismiss dialog
-
-        // parse pointer 1
-        Point p1s = parsePointerCoordinates(allPointers, 0, 0); // start
-        Point p1e = parsePointerCoordinates(allPointers, 0, 1); // end
-        // parse pointer 2
-        Point p2s = parsePointerCoordinates(allPointers, 1, 0); // start
-        Point p2e = parsePointerCoordinates(allPointers, 1, 1); // end
-
-        assertTrue("All Y axis coordinates for pointer 1 must be the same", p1s.y == p1e.y);
-        assertTrue("All Y axis coordinates for pointer 2 must be the same", p2s.y == p2e.y);
-        assertTrue("All Y axis coordinates for both pointers must be the same", p1s.y == p2s.y);
-        assertTrue("Pinch must be in center of target view", p2s.y == screenRect.centerY());
-
-        assertTrue("Touch-down X coordinate for pointer 1 is invalid",
-                withinMarginOfError(0.125f, screenRect.centerX(), p1s.x));
-
-        assertTrue("Touch-down X coordinate for pointer 2 is invalid",
-                withinMarginOfError(0.125f, screenRect.centerX(), p2s.x));
-
-        assertTrue("Touch-up X coordinate for pointer 1 is invalid",
-                withinMarginOfError(0.125f, screenRect.centerX() - screenRect.left,
-                        screenRect.centerX() - p1e.x));
-
-        assertTrue("Touch-up X coordinate for pointer 2 is invalid",
-                withinMarginOfError(0.125f, screenRect.right, p2e.x));
-    }
-
-    /**
-     * Performs a pinch in from the edges of a view to its center and listens to
-     * the motion events to make sure the starting and ending points of both pointers
-     * are correct.
-     *
-     * @throws UiObjectNotFoundException
-     * @since API Level 18
-     */
-    public void testPinchIn() throws UiObjectNotFoundException {
-        openTest("Test 12");
-
-        UiObject screen = new UiObject(
-                new UiSelector().description("Details View"));
-
-        // get the current view dimensions
-        Rect screenRect = screen.getBounds();
-
-        // perform the pinch for 100% of the view dimensions starting form
-        // the edges in towards the center.
-        screen.pinchIn(100, 30);
-
-        // dialog with the detected pointers motion coordinates is displayed.
-        UiObject results = new UiObject(new UiSelector().className(
-                android.widget.ScrollView.class).childSelector(new UiSelector().className(
-                        android.widget.TextView.class)));
-        String allPointers = results.getText();
-        new UiObject(new UiSelector().text("OK")).click(); // dismiss dialog
-
-        // parse pointer 1
-        Point p1s = parsePointerCoordinates(allPointers, 0, 0); // start
-        Point p1e = parsePointerCoordinates(allPointers, 0, 1); // end
-        // parse pointer 2
-        Point p2s = parsePointerCoordinates(allPointers, 1, 0); // start
-        Point p2e = parsePointerCoordinates(allPointers, 1, 1); // end
-
-        assertTrue("All Y axis coordinates for pointer 1 must be the same", p1s.y == p1e.y);
-        assertTrue("All Y axis coordinates for pointer 2 must be the same", p2s.y == p2e.y);
-        assertTrue("All Y axis coordinates for both pointers must be the same", p1s.y == p2s.y);
-        assertTrue("Pinch must be in center of target view", p2s.y == screenRect.centerY());
-
-        assertTrue("Touch-down X coordinate for pointer 1 is invalid",
-                withinMarginOfError(0.125f, screenRect.centerX() - screenRect.left,
-                        screenRect.centerX() -  p1s.x));
-
-        assertTrue("Touch-down X coordinate for pointer 2 is invalid",
-                withinMarginOfError(0.125f, screenRect.right, p2s.x));
-
-        assertTrue("Touch-up X coordinate for pointer 1 is invalid",
-                withinMarginOfError(0.125f, screenRect.centerX() - FINGER_TOUCH_HALF_WIDTH, p1e.x));
-
-        assertTrue("Touch-up X coordinate for pointer 2 is invalid",
-                withinMarginOfError(0.125f, screenRect.centerX() + FINGER_TOUCH_HALF_WIDTH, p2e.x));
-    }
-
-    /**
-     * Performs a drag and drop operation from one UiObject to another UiObject
-     *
-     * @throws UiObjectNotFoundException
-     * @since API Level 18
-     */
-    public void testDragToObject() throws UiObjectNotFoundException {
-        openTest("Test 5");
-
-        UiObject imageButton = new UiObject(new UiSelector().description("Image button"));
-        UiObject starsBar = new UiObject(new UiSelector().className(android.widget.RatingBar.class));
-
-        Rect starsBarRect = starsBar.getBounds();
-        Rect imageButtonRect = imageButton.getBounds();
-        imageButton.dragTo(starsBar, 30);
-
-        // dialog with the detected pointers motion coordinates is displayed.
-        UiObject results = new UiObject(new UiSelector().className(
-                android.widget.ScrollView.class).childSelector(new UiSelector().className(
-                        android.widget.TextView.class)));
-        String allPointers = results.getText();
-        new UiObject(new UiSelector().text("OK")).click(); // dismiss dialog
-
-        // parse pointer 1
-        Point p1s = parsePointerCoordinates(allPointers, 0, 0); // start
-        Point p1e = parsePointerCoordinates(allPointers, 0, 1); // end
-
-        assertTrue("Invalid touch starting.X reported",
-                withinMarginOfError(0.05f, imageButtonRect.centerX(), p1s.x));
-        assertTrue("Invalid touch starting.Y reported",
-                withinMarginOfError(0.05f, imageButtonRect.centerY(), p1s.y));
-        assertTrue("Invalid touch ending.X reported",
-                withinMarginOfError(0.05f, starsBarRect.centerX(), p1e.x));
-        assertTrue("Invalid touch ending.Y reported",
-                withinMarginOfError(0.05f, starsBarRect.centerY(), p1e.y));
-    }
-
-    /**
-     * Performs a drag and drop operation from one UiObject to a specified coordinates
-     *
-     * @throws UiObjectNotFoundException
-     * @since API Level 18
-     */
-   public void testDragToCoordinates() throws UiObjectNotFoundException {
-       openTest("Test 5");
-
-       UiObject imageButton = new UiObject(new UiSelector().description("Image button"));
-       UiObject starsBar = new UiObject(new UiSelector().className(android.widget.RatingBar.class));
-
-       Rect starsBarRect = starsBar.getBounds();
-       Rect imageButtonRect = imageButton.getBounds();
-       imageButton.dragTo(starsBarRect.centerX(), starsBarRect.centerY(), 30);
-
-       // dialog with the detected pointers motion coordinates is displayed.
-       UiObject results = new UiObject(new UiSelector().className(
-               android.widget.ScrollView.class).childSelector(new UiSelector().className(
-                       android.widget.TextView.class)));
-       String allPointers = results.getText();
-       new UiObject(new UiSelector().text("OK")).click(); // dismiss dialog
-
-       // parse pointer 1
-       Point p1s = parsePointerCoordinates(allPointers, 0, 0); // start
-       Point p1e = parsePointerCoordinates(allPointers, 0, 1); // end
-
-       assertTrue("Invalid touch starting.X reported",
-               withinMarginOfError(0.05f, imageButtonRect.centerX(), p1s.x));
-       assertTrue("Invalid touch starting.Y reported",
-               withinMarginOfError(0.05f, imageButtonRect.centerY(), p1s.y));
-       assertTrue("Invalid touch ending.X reported",
-               withinMarginOfError(0.05f, starsBarRect.centerX(), p1e.x));
-       assertTrue("Invalid touch ending.Y reported",
-               withinMarginOfError(0.05f, starsBarRect.centerY(), p1e.y));
-   }
-
-   /**
-    * Detect if actual value is within the allowable margin of error of the expected value.
-    *
-    * Used essentially with actual values that may vary from the expected values such in the
-    * cases of touch and pinch and touch and swipe where the starting or ending points may
-    * not exactly match the expected value.
-    *
-    * @param marginPrecent is values between 0 and 1
-    * @param expected
-    * @param actual
-    * @return true if actual is within the allowed range from expected
-    */
-   private boolean withinMarginOfError(float marginPrecent, int expected, int actual) {
-       int m = (int) (marginPrecent * expected);
-       return actual >= expected - m && actual <= expected + m;
-   }
-
-   /**
-     * Parses a string containing starting to ending coordinates of one or more pointers.
-     *
-     * @param allPointers is a raw string with coordinates from all detected pointers
-     * @param pointerNumber is the desired pointer to be parsed
-     * @param edge is the 0 for the start or 1 for the end of the swipe
-     * @return Point containing the start or end coordinates of the specified pointer number
-     */
-    private Point parsePointerCoordinates(String allPointers, int pointerNumber, int edge) {
-        String pointers[] = allPointers.split("\n");
-        String coordinates = pointers[pointerNumber].split(":")[edge];
-        String xy[] = coordinates.split(",");
-        return new Point(Integer.parseInt(xy[0]), Integer.parseInt(xy[1]));
-    }
-
-    /**
-     * Private helper to open test views. Also covers UiScrollable tests
-     *
-     * @param name
-     * @throws UiObjectNotFoundException
-     */
-    private void openTest(String name) throws UiObjectNotFoundException {
-        try {
-            UiDevice.getInstance().setOrientationNatural();
-        } catch (RemoteException e) {
-            // will catch it in its own test. For now try to put the device
-            // in its natural orientation prior to each test
-        }
-        UiScrollable listView = new UiScrollable(
-                new UiSelector().className(android.widget.ListView.class.getName()));
-
-        // on single fragment display
-        if (!listView.exists())
-            UiDevice.getInstance().pressBack();
-
-        UiObject testItem = listView.getChildByText(
-                new UiSelector().className(android.widget.TextView.class.getName()), name);
-
-        testItem.click();
-    }
-
-    private void verifyTestDetailsExists(String name) throws UiObjectNotFoundException {
-        // verify that we're at the right test
-        new UiObject(new UiSelector().description("Details").text(name)).getText();
-    }
-
-    private UiObject getObjectByText(String txt) {
-        return new UiObject(new UiSelector().text(txt));
-    }
-
-    private UiObject getObjectByTextMatch(String regex) {
-        return new UiObject(new UiSelector().textMatches(regex));
-    }
-
-    private UiObject getObjectByDescriptionMatch(String regex) {
-        return new UiObject(new UiSelector().descriptionMatches(regex));
-    }
-
-    private UiObject getObjectByDescription(String txt) {
-        return new UiObject(new UiSelector().description(txt));
-    }
-
-    private UiObject getObjectByClassMatch(String regex, int instance) {
-        return new UiObject(new UiSelector().classNameMatches(regex).instance(instance));
-    }
-
-    private <T> UiObject getObjectByClass(Class<T> type, int instance) {
-        return new UiObject(new UiSelector().className(type).instance(instance));
-    }
-
-    private UiObject getObjectByIndex(String className, int index) {
-        return new UiObject(new UiSelector().className(className).index(index));
-    }
-
-    private UiObject getObjectByInstance(String className, int instance) {
-        return new UiObject(new UiSelector().className(className).instance(instance));
-    }
-
-    private void verifyDialogActionResults(String txt) throws UiObjectNotFoundException {
-        if (!getObjectByText("Action results").exists() || !getObjectByText(txt).exists()) {
-            throw new UiObjectNotFoundException(txt);
-        }
-        getObjectByText("OK").click();
-    }
-}
diff --git a/tests/uiautomator/test-apps/Android.mk b/tests/uiautomator/test-apps/Android.mk
deleted file mode 100644
index e790e1e..0000000
--- a/tests/uiautomator/test-apps/Android.mk
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright (C) 2012 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT 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 $(call all-subdir-makefiles)
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/Android.mk b/tests/uiautomator/test-apps/CtsUiAutomatorApp/Android.mk
deleted file mode 100644
index 3827754..0000000
--- a/tests/uiautomator/test-apps/CtsUiAutomatorApp/Android.mk
+++ /dev/null
@@ -1,33 +0,0 @@
-# Copyright (C) 2012 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_SDK_VERSION := current
-
-LOCAL_PACKAGE_NAME := CtsUiAutomatorApp
-LOCAL_STATIC_JAVA_LIBRARIES = android-support-v4
-
-LOCAL_PROGUARD_ENABLED := disabled
-
-LOCAL_DEX_PREOPT := false
-
-include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/AndroidManifest.xml b/tests/uiautomator/test-apps/CtsUiAutomatorApp/AndroidManifest.xml
deleted file mode 100644
index 87c2d82..0000000
--- a/tests/uiautomator/test-apps/CtsUiAutomatorApp/AndroidManifest.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.uiautomator"
-    android:versionCode="1"
-    android:versionName="1.0" >
-    <uses-sdk
-        android:minSdkVersion="14"
-        android:targetSdkVersion="15" />
-
-    <uses-permission android:name="android.permission.INTERNET"/>
-    <application
-        android:icon="@drawable/ic_launcher"
-        android:label="@string/app_name"
-        android:theme="@style/AppTheme" >
-        <activity
-            android:name=".MainActivity"
-            android:label="@string/title_test_list" >
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-        <activity
-            android:name=".SinglePaneDetailActivity"
-            android:label="@string/title_test_detail" >
-            <meta-data
-                android:name="android.support.PARENT_ACTIVITY"
-                android:value="FragmentActivity" />
-        </activity>
-     </application>
-
-</manifest>
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/drawable-hdpi/ic_action_search.png b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/drawable-hdpi/ic_action_search.png
deleted file mode 100644
index 67de12d..0000000
--- a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/drawable-hdpi/ic_action_search.png
+++ /dev/null
Binary files differ
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/drawable-hdpi/ic_launcher.png b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/drawable-hdpi/ic_launcher.png
deleted file mode 100644
index 947dbfc..0000000
--- a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/drawable-hdpi/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/drawable-ldpi/ic_launcher.png b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/drawable-ldpi/ic_launcher.png
deleted file mode 100644
index e075065..0000000
--- a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/drawable-ldpi/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/drawable-mdpi/ic_action_search.png b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/drawable-mdpi/ic_action_search.png
deleted file mode 100644
index 134d549..0000000
--- a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/drawable-mdpi/ic_action_search.png
+++ /dev/null
Binary files differ
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/drawable-mdpi/ic_launcher.png b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/drawable-mdpi/ic_launcher.png
deleted file mode 100644
index f91af33..0000000
--- a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/drawable-mdpi/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/drawable-xhdpi/ic_action_search.png b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/drawable-xhdpi/ic_action_search.png
deleted file mode 100644
index d699c6b..0000000
--- a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/drawable-xhdpi/ic_action_search.png
+++ /dev/null
Binary files differ
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/drawable-xhdpi/ic_launcher.png b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/drawable-xhdpi/ic_launcher.png
deleted file mode 100644
index 542a9cb..0000000
--- a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/drawable-xhdpi/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout-land/test5_detail_fragment.xml b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout-land/test5_detail_fragment.xml
deleted file mode 100644
index 123ebde..0000000
--- a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout-land/test5_detail_fragment.xml
+++ /dev/null
@@ -1,123 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:contentDescription="@string/test_5_Widgets_collection"
-    android:orientation="horizontal" >
-
-    <LinearLayout
-        android:layout_width="wrap_content"
-        android:layout_height="match_parent"
-        android:orientation="vertical" >
-
-        <CheckBox
-            android:id="@+id/test_5_checkBox"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="@string/test5_CheckBox" />
-
-        <Spinner
-            android:id="@+id/test_5_spinner"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content" />
-
-        <ProgressBar
-            android:id="@+id/test_5_progressBar"
-            style="?android:attr/progressBarStyleLarge"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content" />
-
-        <GridLayout
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:columnCount="3" >
-
-            <ImageButton
-                android:id="@+id/test_5_imageButton"
-                android:layout_column="0"
-                android:layout_gravity="left"
-                android:layout_row="0"
-                android:src="@drawable/ic_launcher" />
-
-            <RatingBar
-                android:id="@+id/test_5_ratingBar"
-                android:layout_column="1"
-                android:layout_columnSpan="2"
-                android:layout_gravity="left|bottom"
-                android:layout_row="0" />
-
-            <Button
-                android:id="@+id/test_5_button2"
-                style="?android:attr/buttonStyleSmall"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_gravity="left|bottom"
-                android:enabled="false"
-                android:layout_row="0"
-                android:text="@string/test5_Button_Disabled" />
-
-            <Space
-                android:layout_width="21dp"
-                android:layout_height="1dp"
-                android:layout_column="1"
-                android:layout_row="0" />
-
-            <Space
-                android:layout_width="1dp"
-                android:layout_height="21dp"
-                android:layout_column="0"
-                android:layout_row="0" />
-
-            <Space
-                android:layout_width="221dp"
-                android:layout_height="15dp"
-                android:layout_column="2"
-                android:layout_row="1" />
-
-            <ToggleButton
-                android:id="@+id/test_5_toggleButton"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_column="2"
-                android:text="@string/test5_ToggleButton" />
-        </GridLayout>
-
-    </LinearLayout>
-
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:orientation="vertical" >
-
-        <SeekBar
-            android:id="@+id/test_5_seekBar"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content" />
-
-        <Button
-            android:id="@+id/test_5_button1"
-            style="?android:attr/buttonStyleSmall"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:contentDescription="@string/test5_Button_Description"
-            android:text="@string/test5_Button" />
-
-    </LinearLayout>
-
-</LinearLayout>
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/activity_main.xml b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/activity_main.xml
deleted file mode 100644
index 72b68f3..0000000
--- a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/activity_main.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:tools="http://schemas.android.com/tools"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    tools:context=".MainActivity" >
-
-    <TextView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_centerHorizontal="true"
-        android:layout_centerVertical="true"
-        android:text="@string/hello_world" />
-
-</RelativeLayout>
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/list_activity.xml b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/list_activity.xml
deleted file mode 100644
index 25bca5d..0000000
--- a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/list_activity.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-<fragment xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:tools="http://schemas.android.com/tools"
-    android:name="com.android.cts.uiautomator.TestListFragment"
-    android:id="@+id/item_list"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:layout_marginLeft="16dp"
-    android:layout_marginRight="16dp"
-    tools:context=".MainActivity" />
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/simple_list_item_selected.xml b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/simple_list_item_selected.xml
deleted file mode 100644
index 978ceee..0000000
--- a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/simple_list_item_selected.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-<TextView xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/label"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:textAppearance="?android:attr/textAppearanceListItemSmall"
-    android:gravity="center_vertical"
-    android:paddingLeft="?android:attr/listPreferredItemPaddingLeft"
-    android:paddingRight="?android:attr/listPreferredItemPaddingRight"
-    android:background="?android:attr/activatedBackgroundIndicator"
-    android:minHeight="?android:attr/listPreferredItemHeightSmall"
-/>
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/singlepane_activity.xml b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/singlepane_activity.xml
deleted file mode 100644
index 78b2545..0000000
--- a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/singlepane_activity.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:tools="http://schemas.android.com/tools"
-    android:id="@+id/test_results_detail_container"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    tools:context=".TestResultsDetailActivity" />
\ No newline at end of file
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/test1_detail_fragment.xml b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/test1_detail_fragment.xml
deleted file mode 100644
index c9b2a05..0000000
--- a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/test1_detail_fragment.xml
+++ /dev/null
@@ -1,61 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/test_1_detail_container"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:orientation="vertical" >
-
-    <TextView
-        android:id="@+id/item1_test_description"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:padding="5dp"
-        android:text="@string/test1_description" />
-
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:orientation="horizontal" >
-
-        <EditText
-            android:id="@+id/test1TextField"
-            android:layout_width="0dip"
-            android:layout_height="wrap_content"
-            android:layout_marginLeft="5dp"
-            android:layout_weight="2"
-            android:inputType="textNoSuggestions"
-            android:paddingLeft="5dip"
-            android:paddingRight="5dip"
-            android:width="200dip" >
-
-            <requestFocus />
-        </EditText>
-
-        <Button
-            android:id="@+id/test1SubmitButton"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_marginLeft="5dip"
-            android:layout_marginRight="5dip"
-            android:minWidth="64dip"
-            android:text="@string/buttonSubmit" />
-
-    </LinearLayout>
-
-</LinearLayout>
\ No newline at end of file
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/test2_detail_fragment.xml b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/test2_detail_fragment.xml
deleted file mode 100644
index 1bf60b8..0000000
--- a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/test2_detail_fragment.xml
+++ /dev/null
@@ -1,78 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/test_2_detail_container"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:orientation="vertical" >
-
-    <TextView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:padding="5dp"
-        android:text="@string/test2_description" />
-
-    <LinearLayout
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_gravity="center_horizontal"
-        android:orientation="horizontal" >
-
-        <Button
-            android:id="@+id/test2button1"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:contentDescription="@string/button1"
-            android:text="@string/button1" />
-
-        <Button
-            android:id="@+id/test2button2"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:contentDescription="@string/button2"
-            android:text="@string/button2" />
-
-        <Button
-            android:id="@+id/test2button3"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:contentDescription="@string/button3"
-            android:text="@string/button3" />
-    </LinearLayout>
-
-    <TextView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:padding="5dp"
-        android:text="@string/test2_description_2" />
-
-    <LinearLayout
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_gravity="center_horizontal"
-        android:orientation="horizontal" >
-
-        <Button
-            android:id="@+id/test2dynaButton"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:contentDescription="@string/buttonBefore"
-            android:text="@string/buttonBefore" />
-
-    </LinearLayout>
-</LinearLayout>
\ No newline at end of file
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/test3_detail_fragment.xml b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/test3_detail_fragment.xml
deleted file mode 100644
index de7ecb6..0000000
--- a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/test3_detail_fragment.xml
+++ /dev/null
@@ -1,76 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/test_3_detail_container"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:orientation="vertical" >
-
-    <TextView
-        android:id="@+id/item3_test_description"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:padding="5dp"
-        android:text="@string/test3_description" />
-
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:orientation="vertical" >
-
-        <TextView
-            android:id="@+id/test3ClockTextView"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center_horizontal"
-            android:layout_marginBottom="10dip"
-            android:layout_marginTop="10dip"
-            android:contentDescription="@string/test3ClockDescription"
-            android:padding="10dp"
-            android:text="@string/test3InitialClock" />
-
-    </LinearLayout>
-
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:orientation="horizontal" >
-
-        <EditText
-            android:id="@+id/test3TextField"
-            android:layout_width="0dip"
-            android:layout_height="wrap_content"
-            android:layout_marginLeft="5dp"
-            android:layout_weight="2"
-            android:inputType="numberDecimal"
-            android:paddingLeft="5dip"
-            android:paddingRight="5dip"
-            android:width="200dip" >
-            <requestFocus />
-        </EditText>
-
-        <Button
-            android:id="@+id/test3SubmitButton"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_marginLeft="5dip"
-            android:layout_marginRight="5dip"
-            android:minWidth="64dip"
-            android:text="@string/buttonSubmit" />
-    </LinearLayout>
-</LinearLayout>
\ No newline at end of file
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/test4_detail_fragment.xml b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/test4_detail_fragment.xml
deleted file mode 100644
index dbf88ee..0000000
--- a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/test4_detail_fragment.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
- <android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:tools="http://schemas.android.com/tools"
-    android:id="@+id/test_4_detail_container"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    tools:context=".Test4DetailActivity" />
\ No newline at end of file
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/test5_detail_fragment.xml b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/test5_detail_fragment.xml
deleted file mode 100644
index e34f271..0000000
--- a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/test5_detail_fragment.xml
+++ /dev/null
@@ -1,109 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:contentDescription="@string/test_5_Widgets_collection"
-    android:orientation="vertical" >
-
-    <CheckBox
-        android:id="@+id/test_5_checkBox"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:text="@string/test5_CheckBox" />
-
-    <Spinner
-        android:id="@+id/test_5_spinner"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content" />
-
-    <ProgressBar
-        android:id="@+id/test_5_progressBar"
-        style="?android:attr/progressBarStyleLarge"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content" />
-
-    <GridLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:columnCount="3" >
-
-        <ImageButton
-            android:id="@+id/test_5_imageButton"
-            android:layout_column="0"
-            android:layout_gravity="left"
-            android:layout_row="0"
-            android:src="@drawable/ic_launcher" />
-
-        <RatingBar
-            android:id="@+id/test_5_ratingBar"
-            android:layout_column="1"
-            android:layout_columnSpan="2"
-            android:layout_gravity="left|bottom"
-            android:layout_row="0" />
-
-        <Button
-            android:id="@+id/test_5_button2"
-            style="?android:attr/buttonStyleSmall"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="left|bottom"
-            android:enabled="false"
-            android:layout_row="0"
-            android:text="@string/test5_Button_Disabled" />
-
-        <Space
-            android:layout_width="21dp"
-            android:layout_height="1dp"
-            android:layout_column="1"
-            android:layout_row="0" />
-
-        <Space
-            android:layout_width="1dp"
-            android:layout_height="21dp"
-            android:layout_column="0"
-            android:layout_row="0" />
-
-        <Space
-            android:layout_width="221dp"
-            android:layout_height="15dp"
-            android:layout_column="2"
-            android:layout_row="1" />
-
-        <ToggleButton
-            android:id="@+id/test_5_toggleButton"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_column="2"
-            android:text="@string/test5_ToggleButton" />
-    </GridLayout>
-
-    <SeekBar
-        android:id="@+id/test_5_seekBar"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content" />
-
-    <Button
-        android:id="@+id/test_5_button1"
-        style="?android:attr/buttonStyleSmall"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:contentDescription="@string/test5_Button_Description"
-        android:text="@string/test5_Button" />
-
-</LinearLayout>
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/test6_detail_fragment.xml b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/test6_detail_fragment.xml
deleted file mode 100644
index 01a9fdc..0000000
--- a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/test6_detail_fragment.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:orientation="vertical" >
-
-    <WebView
-        android:id="@+id/test6WebView"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent" />
-
-</LinearLayout>
\ No newline at end of file
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/test_results_detail_fragment.xml b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/test_results_detail_fragment.xml
deleted file mode 100644
index e8b8c05..0000000
--- a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/test_results_detail_fragment.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/test_results_detail_container"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:contentDescription="@string/title_test_view_detail"
-    android:orientation="vertical" >
-
-    <TextView
-        android:id="@+id/textView1"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:padding="5dp"
-        android:text="@string/now_displaying_results_for" />
-
-    <TextView
-        android:id="@+id/testResultsTextView"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_gravity="center_horizontal"
-        android:contentDescription="@string/title_test_detail"
-        android:paddingLeft="2dp"
-        android:paddingTop="5dp"
-        android:textColor="#00aa00"
-        android:textSize="@dimen/padding_large"
-        android:textStyle="bold" />
-
-</LinearLayout>
\ No newline at end of file
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/twopane_activity.xml b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/twopane_activity.xml
deleted file mode 100644
index 3777db6..0000000
--- a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/twopane_activity.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:tools="http://schemas.android.com/tools"
-    android:orientation="horizontal"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:layout_marginLeft="16dp"
-    android:layout_marginRight="16dp"
-    android:divider="?android:attr/dividerHorizontal"
-    android:showDividers="middle"
-    tools:context=".TestListActivity">
-
-    <fragment
-        android:id="@+id/item_list"
-        android:name="com.android.cts.uiautomator.TestListFragment"
-        android:layout_width="0dp"
-        android:layout_height="match_parent"
-        android:layout_weight="1" />
-
-    <FrameLayout android:id="@+id/test_detail_container"
-        android:layout_width="0dp"
-        android:layout_height="match_parent"
-        android:layout_weight="3" />
-
-</LinearLayout>
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/menu/activity_main.xml b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/menu/activity_main.xml
deleted file mode 100644
index c54c287..0000000
--- a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/menu/activity_main.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-<menu xmlns:android="http://schemas.android.com/apk/res/android" >
-
-    <item
-        android:id="@+id/menu_settings"
-        android:orderInCategory="100"
-        android:showAsAction="never"
-        android:title="@string/menu_settings"/>
-
-</menu>
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/menu/test1_detail_activity.xml b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/menu/test1_detail_activity.xml
deleted file mode 100644
index fe1fe20..0000000
--- a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/menu/test1_detail_activity.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:id="@+id/menu_settings"
-        android:title="@string/menu_settings"
-        android:orderInCategory="100"
-        android:showAsAction="never" />
-</menu>
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/menu/test2_detail_activity.xml b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/menu/test2_detail_activity.xml
deleted file mode 100644
index 405d4c8..0000000
--- a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/menu/test2_detail_activity.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:id="@+id/menu_text1"
-        android:title="Submit" />
-    <item android:id="@+id/menu_text2"
-        android:icon="@drawable/ic_launcher"
-        android:title="Done" />
-    <item android:id="@+id/menu_text3"
-        android:title="OK" />
-    <item android:id="@+id/menu_text4"
-        android:title="Finish" />
-    <item android:id="@+id/menu_text5"
-        android:title="Complete" />
-    <item android:id="@+id/menu_text6"
-        android:title="Exit" />
-</menu>
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/menu/test3_detail_activity.xml b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/menu/test3_detail_activity.xml
deleted file mode 100644
index fe1fe20..0000000
--- a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/menu/test3_detail_activity.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:id="@+id/menu_settings"
-        android:title="@string/menu_settings"
-        android:orderInCategory="100"
-        android:showAsAction="never" />
-</menu>
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/menu/test4_detail_activity.xml b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/menu/test4_detail_activity.xml
deleted file mode 100644
index fe1fe20..0000000
--- a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/menu/test4_detail_activity.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:id="@+id/menu_settings"
-        android:title="@string/menu_settings"
-        android:orderInCategory="100"
-        android:showAsAction="never" />
-</menu>
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/menu/test5_detail_activity.xml b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/menu/test5_detail_activity.xml
deleted file mode 100644
index fe1fe20..0000000
--- a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/menu/test5_detail_activity.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:id="@+id/menu_settings"
-        android:title="@string/menu_settings"
-        android:orderInCategory="100"
-        android:showAsAction="never" />
-</menu>
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/menu/test6_detail_activity.xml b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/menu/test6_detail_activity.xml
deleted file mode 100644
index fe1fe20..0000000
--- a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/menu/test6_detail_activity.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:id="@+id/menu_settings"
-        android:title="@string/menu_settings"
-        android:orderInCategory="100"
-        android:showAsAction="never" />
-</menu>
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/menu/test_results_detail_activity.xml b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/menu/test_results_detail_activity.xml
deleted file mode 100644
index febffa2..0000000
--- a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/menu/test_results_detail_activity.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:id="@+id/menu_settings"
-        android:title="@string/menu_settings"
-        android:orderInCategory="100"
-        android:showAsAction="never" />
-</menu>
-
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/values-large/dimens.xml b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/values-large/dimens.xml
deleted file mode 100644
index 788578a..0000000
--- a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/values-large/dimens.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-<resources>
-
-    <dimen name="padding_small">8dp</dimen>
-    <dimen name="padding_medium">16dp</dimen>
-    <dimen name="padding_large">16dp</dimen>
-
-</resources>
\ No newline at end of file
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/values-large/refs.xml b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/values-large/refs.xml
deleted file mode 100644
index ac82847..0000000
--- a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/values-large/refs.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-<resources>
-    <item type="layout" name="list_activity">@layout/twopane_activity</item>
-</resources>
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/values-sw600dp/refs.xml b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/values-sw600dp/refs.xml
deleted file mode 100644
index ac82847..0000000
--- a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/values-sw600dp/refs.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-<resources>
-    <item type="layout" name="list_activity">@layout/twopane_activity</item>
-</resources>
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/values-v11/styles.xml b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/values-v11/styles.xml
deleted file mode 100644
index 504d3e3..0000000
--- a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/values-v11/styles.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-<resources>
-
-    <style name="AppTheme" parent="android:Theme.Holo.Light" />
-
-</resources>
\ No newline at end of file
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/values-v14/styles.xml b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/values-v14/styles.xml
deleted file mode 100644
index 1232912..0000000
--- a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/values-v14/styles.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-<resources>
-
-    <style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar" />
-
-</resources>
\ No newline at end of file
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/values-watch/styles.xml b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/values-watch/styles.xml
deleted file mode 100644
index 1d904c2..0000000
--- a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/values-watch/styles.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-<resources>
-
-    <style name="AppTheme" parent="android:Theme.Holo.Light.NoActionBar" />
-
-</resources>
\ No newline at end of file
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/values/dimens.xml b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/values/dimens.xml
deleted file mode 100644
index d607bb7..0000000
--- a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/values/dimens.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-<resources>
-
-    <dimen name="padding_small">8dp</dimen>
-    <dimen name="padding_medium">8dp</dimen>
-    <dimen name="padding_large">16dp</dimen>
-
-</resources>
\ No newline at end of file
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/values/strings.xml b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/values/strings.xml
deleted file mode 100644
index 04f0df4..0000000
--- a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/values/strings.xml
+++ /dev/null
@@ -1,63 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-<resources>
-
-    <string name="app_name">UiAutomator Test App</string>
-    <string name="test1_description">This helps verify entering text into a pre-populated field. The pop-up dialog will echo the text entered after clicking submit. The initial value in the field must first be deleted.</string>
-    <string name="menu_settings">Settings</string>
-    <string name="title_activity_item1_detail">Item1DetailActivity</string>
-    <string name="buttonSubmit">Submit</string>
-    <string name="item1_dialog_title">Text submitted</string>
-    <string name="OK">OK</string>
-    <string name="title_test_list">UiAutomator Tests</string>
-    <string name="title_test_detail">Details</string>
-    <string name="hello_world">Hello world!</string>
-    <string name="title_activity_test2_detail">Test2DetailActivity</string>
-    <string name="test2_description">This helps test selection of button using Instance, Text and Content Description. Once clicked, a dialog pops up to verify the properties of button clicked.</string>
-    <string name="test2_description_2">This tests a Button text changing dynamically after a click. The test should attempt to find the button after it has changed using its new text.</string>
-    <string name="test3_description">The tests should read the clock, then write the clock back into the EditText then press submit. A dialog will display the time it took from reading the clock until submit is press. This can be used to get an idea of performance differences.</string>
-    <string name="button1">Button 1</string>
-    <string name="button1long">Longclick Button 1</string>
-    <string name="button2">Button 2</string>
-    <string name="button2long">Longclick Button 2</string>
-    <string name="button3">Button 3</string>
-    <string name="button3long">Longclick Button 3</string>
-    <string name="buttonBefore">Before</string>
-    <string name="buttonAfter">After</string>
-    <string name="dialog_title_result">Action results</string>
-    <string name="now_displaying_results_for">Verifying scroll into view and list item selection. Now displaying results for:</string>
-    <string name="title_activity_test3_detail">Performance test</string>
-    <string name="test3ClockDescription">Performance clock</string>
-    <string name="test3InitialClock">0000000000</string>
-    <string name="test3_dialog_title">Time difference in ms</string>
-    <string name="test5_CheckBox">CheckBox</string>
-    <string name="test5_ToggleButton">ToggleButton</string>
-    <string name="test5_Button">Button</string>
-    <string name="test5_Button_Description">Description for Button</string>
-    <string name="test5_Button_Disabled">Button D</string>
-    <string name="title_section4">Section 4</string>
-    <string name="title_section3">Section 3</string>
-    <string name="title_section2">Section 2</string>
-    <string name="title_section1">Section 1</string>
-    <string name="title_activity_test4_detail">Test4DetailActivity</string>
-    <string name="title_activity_test5_detail">Test5DetailActivity</string>
-    <string name="title_activity_test6_detail">Test6DetailActivity</string>
-    <string name="test_5_Widgets_collection">Widgets Collection</string>
-    <string name="generic_item_touch_dialog_title">Multi-touch test dialog</string>
-    <string name="drag_item_touch_dialog_title">Drag and drop test dialog</string>
-    <string name="title_test_view_detail">Details View</string>
-</resources>
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/values/styles.xml b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/values/styles.xml
deleted file mode 100644
index bce88ae..0000000
--- a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/values/styles.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-<resources>
-
-    <style name="AppTheme" parent="android:Theme.Light" />
-
-</resources>
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/MainActivity.java b/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/MainActivity.java
deleted file mode 100644
index 81833b7..0000000
--- a/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/MainActivity.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.cts.uiautomator;
-
-import android.content.Intent;
-import android.os.Bundle;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentActivity;
-import android.view.WindowManager;
-
-public class MainActivity extends FragmentActivity implements TestListFragment.Callbacks {
-
-    private boolean mTwoPane;
-    public static final String LOG_TAG = "UiAutomatorApp";
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        // If the device is locked, this attempts to dismiss the KeyGuard
-        getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD |
-                WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON |
-                      WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
-
-        setContentView(R.layout.list_activity);
-
-        if (findViewById(R.id.test_detail_container) != null) {
-            mTwoPane = true;
-            ((TestListFragment) getSupportFragmentManager().findFragmentById(R.id.item_list))
-                    .setActivateOnItemClick(true);
-        }
-    }
-
-    @Override
-    public void onItemSelected(String id) {
-        if (mTwoPane) {
-            Fragment fragment = TestItems.getFragment(id);
-            getSupportFragmentManager().beginTransaction()
-                    .replace(R.id.test_detail_container, fragment).commit();
-        } else {
-            Intent detailIntent = new Intent(this, SinglePaneDetailActivity.class);
-            detailIntent.putExtra("item_id", id);
-            startActivity(detailIntent);
-        }
-    }
-}
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/SinglePaneDetailActivity.java b/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/SinglePaneDetailActivity.java
deleted file mode 100644
index 1c0ff8c..0000000
--- a/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/SinglePaneDetailActivity.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.uiautomator;
-
-import android.os.Bundle;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentActivity;
-import android.support.v4.app.NavUtils;
-import android.view.Menu;
-import android.view.MenuItem;
-
-public class SinglePaneDetailActivity extends FragmentActivity {
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.singlepane_activity);
-        getActionBar().setDisplayHomeAsUpEnabled(true);
-
-        if (savedInstanceState == null) {
-            Fragment fragment = TestItems.getFragment(getIntent().getStringExtra("item_id"));
-            getSupportFragmentManager().beginTransaction()
-                    .add(R.id.test_results_detail_container, fragment).commit();
-        }
-    }
-
-    @Override
-    public boolean onCreateOptionsMenu(Menu menu) {
-        getMenuInflater().inflate(R.menu.test_results_detail_activity, menu);
-        return true;
-    }
-
-    @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
-        switch (item.getItemId()) {
-            case android.R.id.home:
-                NavUtils.navigateUpFromSameTask(this);
-                return true;
-        }
-        return super.onOptionsItemSelected(item);
-    }
-}
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/Test1DetailFragment.java b/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/Test1DetailFragment.java
deleted file mode 100644
index e8eddba..0000000
--- a/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/Test1DetailFragment.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.uiautomator;
-
-import android.app.AlertDialog;
-import android.content.Context;
-import android.os.Bundle;
-import android.support.v4.app.Fragment;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.inputmethod.InputMethodManager;
-import android.widget.Button;
-import android.widget.EditText;
-
-public class Test1DetailFragment extends Fragment {
-
-    public static final String ARG_ITEM_ID = "item_id";
-    private Button mSubmitButton;
-    private EditText mEditText;
-    TestItems.TestItem mItem;
-
-    public Test1DetailFragment() {
-    }
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        if (getArguments().containsKey(ARG_ITEM_ID)) {
-            mItem = TestItems.getTest(getArguments().getString(ARG_ITEM_ID));
-        }
-    }
-
-    @Override
-    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) {
-        View rootView = inflater.inflate(R.layout.test1_detail_fragment, container, false);
-        if (mItem != null) {
-            ((EditText) rootView.findViewById(R.id.test1TextField)).setText(mItem.mName);
-
-            mSubmitButton = (Button) rootView.findViewById(R.id.test1SubmitButton);
-            mEditText = (EditText) rootView.findViewById(R.id.test1TextField);
-            mEditText.setText("");
-            mSubmitButton.setOnClickListener(new Button.OnClickListener() {
-                @Override
-                public void onClick(View v) {
-                    final String savedInput = mEditText.getText().toString();
-                    // clear so we won't be confused by the input text in
-                    // validation
-                    mEditText.setText("");
-                    // close soft keyboard
-                    InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(
-                            Context.INPUT_METHOD_SERVICE);
-                    imm.hideSoftInputFromWindow(mEditText.getWindowToken(), 0);
-                    // display the submitted text
-                    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
-                    builder.setTitle(R.string.item1_dialog_title);
-                    builder.setPositiveButton(R.string.OK, null);
-                    builder.setMessage(savedInput);
-                    AlertDialog diag = builder.create();
-                    diag.show();
-                }
-            });
-        }
-        return rootView;
-    }
-}
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/Test2DetailFragment.java b/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/Test2DetailFragment.java
deleted file mode 100644
index 4fb322f..0000000
--- a/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/Test2DetailFragment.java
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.uiautomator;
-
-import android.app.AlertDialog;
-import android.os.Bundle;
-import android.support.v4.app.Fragment;
-import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.Button;
-
-public class Test2DetailFragment extends Fragment {
-    public static final String ARG_ITEM_ID = "item_id";
-    private Button mButton1, mButton2, mButton3, mDynaButton;
-
-    public Test2DetailFragment() {
-    }
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setHasOptionsMenu(true);
-    }
-
-    @Override
-    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
-        inflater.inflate(R.menu.test2_detail_activity, menu);
-    }
-
-    @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
-        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
-        builder.setTitle(R.string.dialog_title_result);
-        builder.setMessage(item.getTitle());
-        builder.setPositiveButton(R.string.OK, null);
-        AlertDialog diag = builder.create();
-        diag.show();
-        return super.onOptionsItemSelected(item);
-    }
-
-    @Override
-    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) {
-        View rootView = inflater.inflate(R.layout.test2_detail_fragment, container, false);
-
-        mButton1 = (Button) rootView.findViewById(R.id.test2button1);
-        mButton2 = (Button) rootView.findViewById(R.id.test2button2);
-        mButton3 = (Button) rootView.findViewById(R.id.test2button3);
-        mDynaButton = (Button) rootView.findViewById(R.id.test2dynaButton);
-
-        mButton1.setOnClickListener(new Button.OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
-                builder.setTitle(R.string.dialog_title_result);
-                builder.setPositiveButton(R.string.OK, null);
-                builder.setMessage(R.string.button1);
-                AlertDialog diag = builder.create();
-                diag.show();
-            }
-        });
-
-        mButton1.setOnLongClickListener(new Button.OnLongClickListener() {
-            @Override
-            public boolean onLongClick(View v) {
-                AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
-                builder.setTitle(R.string.dialog_title_result);
-                builder.setPositiveButton(R.string.OK, null);
-                builder.setMessage(R.string.button1long);
-                AlertDialog diag = builder.create();
-                diag.show();
-                return true;
-            }
-        });
-
-        mButton2.setOnClickListener(new Button.OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
-                builder.setTitle(R.string.dialog_title_result);
-                builder.setPositiveButton(R.string.OK, null);
-                builder.setMessage(R.string.button2);
-                AlertDialog diag = builder.create();
-                diag.show();
-            }
-        });
-
-        mButton2.setOnLongClickListener(new Button.OnLongClickListener() {
-            @Override
-            public boolean onLongClick(View v) {
-                AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
-                builder.setTitle(R.string.dialog_title_result);
-                builder.setPositiveButton(R.string.OK, null);
-                builder.setMessage(R.string.button2long);
-                AlertDialog diag = builder.create();
-                diag.show();
-                return true;
-            }
-        });
-
-        mButton3.setOnClickListener(new Button.OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
-                builder.setTitle(R.string.dialog_title_result);
-                builder.setPositiveButton(R.string.OK, null);
-                builder.setMessage(R.string.button3);
-                AlertDialog diag = builder.create();
-                diag.show();
-            }
-        });
-
-        mButton3.setOnLongClickListener(new Button.OnLongClickListener() {
-            @Override
-            public boolean onLongClick(View v) {
-                AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
-                builder.setTitle(R.string.dialog_title_result);
-                builder.setPositiveButton(R.string.OK, null);
-                builder.setMessage(R.string.button3long);
-                AlertDialog diag = builder.create();
-                diag.show();
-                return true;
-            }
-        });
-
-        mDynaButton.setOnClickListener(new Button.OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                mDynaButton.setText(R.string.buttonAfter);
-                mDynaButton.setContentDescription(getString(R.string.buttonAfter));
-            }
-        });
-
-        return rootView;
-    }
-}
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/Test3DetailFragment.java b/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/Test3DetailFragment.java
deleted file mode 100644
index e0be0cf..0000000
--- a/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/Test3DetailFragment.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.uiautomator;
-
-import android.app.AlertDialog;
-import android.content.Context;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.SystemClock;
-import android.support.v4.app.Fragment;
-import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.inputmethod.InputMethodManager;
-import android.widget.Button;
-import android.widget.EditText;
-import android.widget.TextView;
-
-public class Test3DetailFragment extends Fragment {
-
-    public static final String ARG_ITEM_ID = "item_id";
-    private TextView mTextClock;
-    private Button mSubmitButton;
-    private EditText mEditText;
-    private long mCurrentTime;
-    private final Object sync = new Object();
-    private boolean mRunCounter = true;
-
-    public Test3DetailFragment() {
-    }
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setHasOptionsMenu(true);
-    }
-
-    @Override
-    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
-        inflater.inflate(R.menu.test2_detail_activity, menu);
-    }
-
-    @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
-        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
-        builder.setTitle(R.string.dialog_title_result);
-        builder.setMessage(item.getTitle());
-        builder.setPositiveButton(R.string.OK, null);
-        AlertDialog diag = builder.create();
-        diag.show();
-        return super.onOptionsItemSelected(item);
-    }
-
-    private final Handler mHandler = new Handler();
-
-    final Runnable mClockRunnable = new Runnable() {
-        @Override
-        public void run() {
-            // call the activity method that updates the UI
-            updateClockOnUi();
-        }
-    };
-
-    private void updateClockOnUi() {
-        synchronized (sync) {
-            mTextClock.setText("" + mCurrentTime);
-        }
-    }
-
-    @Override
-    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) {
-        View rootView = inflater.inflate(R.layout.test3_detail_fragment, container, false);
-        mTextClock = (TextView) rootView.findViewById(R.id.test3ClockTextView);
-        mSubmitButton = (Button) rootView.findViewById(R.id.test3SubmitButton);
-        mEditText = (EditText) rootView.findViewById(R.id.test3TextField);
-        mSubmitButton.setOnClickListener(new Button.OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                // close soft keyboard
-                InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(
-                        Context.INPUT_METHOD_SERVICE);
-                imm.hideSoftInputFromWindow(mEditText.getWindowToken(), 0);
-
-                // display the submitted text
-                AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
-                builder.setTitle(R.string.test3_dialog_title);
-                builder.setPositiveButton(R.string.OK, null);
-                CharSequence inputText = mEditText.getText();
-                if (inputText != null && !inputText.toString().isEmpty()) {
-                    long inputTime = Long.parseLong(inputText.toString());
-                    builder.setMessage("" + (mCurrentTime - inputTime));
-                } else {
-                    builder.setMessage("<NO DATA>");
-                }
-                AlertDialog diag = builder.create();
-                diag.show();
-                mEditText.setText("");
-                mRunCounter = false;
-            }
-        });
-
-        new Thread(new Runnable() {
-            @Override
-            public void run() {
-                while (mRunCounter) {
-                    synchronized (sync) {
-                        mCurrentTime = SystemClock.elapsedRealtime();
-                    }
-                    mHandler.post(mClockRunnable);
-                    SystemClock.sleep(100);
-                }
-            }
-        }).start();
-
-        return rootView;
-    }
-}
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/Test4DetailFragment.java b/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/Test4DetailFragment.java
deleted file mode 100644
index 0c914dc..0000000
--- a/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/Test4DetailFragment.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.uiautomator;
-
-import android.app.ActionBar;
-import android.app.FragmentTransaction;
-import android.os.Bundle;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentManager;
-import android.support.v4.app.FragmentPagerAdapter;
-import android.support.v4.view.ViewPager;
-import android.view.Gravity;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.TextView;
-
-public class Test4DetailFragment extends Fragment implements ActionBar.TabListener {
-    public static final String ARG_ITEM_ID = "item_id";
-
-    /**
-     * The {@link android.support.v4.view.PagerAdapter} that will provide
-     * fragments for each of the sections. We use a
-     * {@link android.support.v4.app.FragmentPagerAdapter} derivative, which
-     * will keep every loaded fragment in memory. If this becomes too memory
-     * intensive, it may be best to switch to a
-     * {@link android.support.v4.app.FragmentStatePagerAdapter}.
-     */
-    SectionsPagerAdapter mSectionsPagerAdapter;
-
-    /**
-     * The {@link ViewPager} that will host the section contents.
-     */
-    ViewPager mViewPager;
-
-    public Test4DetailFragment() {
-    }
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-    }
-
-    @Override
-    public void onDestroyView() {
-        getActivity().getActionBar().removeAllTabs();
-        super.onDestroyView();
-    }
-
-    @Override
-    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) {
-
-        View rootView = inflater.inflate(R.layout.test4_detail_fragment, container, false);
-
-        // Set up the action bar.
-        final ActionBar actionBar = getActivity().getActionBar();
-        if (actionBar.getTabCount() > 0) {
-            return rootView;
-        }
-        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
-
-        // Create the adapter that will return a fragment for each of the three
-        // primary sections of the app.
-        mSectionsPagerAdapter = new SectionsPagerAdapter(getActivity().getSupportFragmentManager());
-
-        // Set up the ViewPager with the sections adapter.
-        mViewPager = (ViewPager) rootView.findViewById(R.id.test_4_detail_container);
-        mViewPager.setAdapter(mSectionsPagerAdapter);
-
-        // When swiping between different sections, select the corresponding
-        // tab. We can also use ActionBar.Tab#select() to do this if we have a
-        // reference to the Tab.
-        mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
-            @Override
-            public void onPageSelected(int position) {
-                actionBar.setSelectedNavigationItem(position);
-            }
-        });
-
-        // For each of the sections in the app, add a tab to the action bar.
-        for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
-            // Create a tab with text corresponding to the page title defined by
-            // the adapter. Also specify this Activity object, which implements
-            // the TabListener interface, as the listener for when this tab is
-            // selected.
-            actionBar.addTab(actionBar.newTab().setText(mSectionsPagerAdapter.getPageTitle(i))
-                    .setTabListener(this));
-        }
-        return rootView;
-    }
-
-    @Override
-    public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
-    }
-
-    @Override
-    public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
-    }
-
-    @Override
-    public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
-    }
-
-    /**
-     * A {@link FragmentPagerAdapter} that returns a fragment corresponding to
-     * one of the primary sections of the app.
-     */
-    public class SectionsPagerAdapter extends FragmentPagerAdapter {
-
-        public SectionsPagerAdapter(FragmentManager fm) {
-            super(fm);
-        }
-
-        @Override
-        public Fragment getItem(int i) {
-            Fragment fragment = new DummySectionFragment();
-            Bundle args = new Bundle();
-            args.putInt(DummySectionFragment.ARG_SECTION_NUMBER, i + 1);
-            fragment.setArguments(args);
-            return fragment;
-        }
-
-        @Override
-        public int getCount() {
-            return 4;
-        }
-
-        @Override
-        public CharSequence getPageTitle(int position) {
-            switch (position) {
-                case 0:
-                    return getString(R.string.title_section1).toUpperCase();
-                case 1:
-                    return getString(R.string.title_section2).toUpperCase();
-                case 2:
-                    return getString(R.string.title_section3).toUpperCase();
-                case 3:
-                    return getString(R.string.title_section4).toUpperCase();
-            }
-            return null;
-        }
-    }
-
-    /**
-     * A dummy fragment representing a section of the app, but that simply
-     * displays dummy text.
-     */
-    public static class DummySectionFragment extends Fragment {
-        public DummySectionFragment() {
-        }
-
-        public static final String ARG_SECTION_NUMBER = "section_number";
-
-        @Override
-        public View onCreateView(LayoutInflater inflater, ViewGroup container,
-                Bundle savedInstanceState) {
-            TextView textView = new TextView(getActivity());
-            textView.setGravity(Gravity.CENTER);
-            Bundle args = getArguments();
-            textView.setText("[ " + Integer.toString(args.getInt(ARG_SECTION_NUMBER)) + " ]");
-            return textView;
-        }
-    }
-}
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/Test5DetailFragment.java b/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/Test5DetailFragment.java
deleted file mode 100644
index e2dd156..0000000
--- a/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/Test5DetailFragment.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.uiautomator;
-
-import android.app.AlertDialog;
-import android.os.Bundle;
-import android.support.v4.app.Fragment;
-import android.view.LayoutInflater;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.Button;
-import android.widget.CheckBox;
-import android.widget.ImageButton;
-import android.widget.SeekBar;
-import android.widget.Spinner;
-
-public class Test5DetailFragment extends Fragment {
-
-    public static final String ARG_ITEM_ID = "item_id";
-
-    class PointerEvent {
-        int startX;
-        int startY;
-        int endX;
-        int endY;
-    }
-
-    private final PointerEvent mPointerEvent = new PointerEvent();
-
-    public Test5DetailFragment() {
-    }
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-    }
-
-    @Override
-    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) {
-        View rootView = inflater.inflate(R.layout.test5_detail_fragment, container, false);
-
-        // Set the content description for the following
-        Spinner spinner = (Spinner) rootView.findViewById(R.id.test_5_spinner);
-        spinner.setContentDescription("Spinner");
-        ImageButton imageButton = (ImageButton) rootView.findViewById(R.id.test_5_imageButton);
-        imageButton.setContentDescription("Image button");
-
-        // Each time this view is displayed, reset the following states
-        SeekBar seekBar = (SeekBar) rootView.findViewById(R.id.test_5_seekBar);
-        seekBar.setProgress(50);
-        seekBar.setContentDescription("Progress is 50 %");
-        CheckBox checkbox = (CheckBox) rootView.findViewById(R.id.test_5_checkBox);
-        checkbox.setChecked(false);
-
-        // Register click event handlers for the following
-        Button button = (Button) rootView.findViewById(R.id.test_5_button1);
-        button.setOnClickListener(new Button.OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                // we want an artificial crash
-                throw new RuntimeException("Artificial crash to test UiWatcher");
-            }
-        });
-
-        imageButton.setOnTouchListener(new ImageButton.OnTouchListener() {
-
-            @Override
-            public boolean onTouch(View v, MotionEvent event) {
-                if (event.getAction() == MotionEvent.ACTION_DOWN) {
-                    resetTouchResults();
-                    collectStartAction(event, v);
-                } else if (event.getAction() == MotionEvent.ACTION_UP) {
-                    collectEndAction(event, v);
-                    displayTouchResults();
-                }
-                return false;
-            }
-        });
-
-        return rootView;
-    }
-
-    private void displayTouchResults() {
-        StringBuilder output = new StringBuilder();
-
-        output.append(String.format("%d,%d:%d,%d\n",
-                mPointerEvent.startX, mPointerEvent.startY, mPointerEvent.endX,
-                mPointerEvent.endY));
-
-        // display the submitted text
-        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
-        builder.setTitle(R.string.drag_item_touch_dialog_title);
-        builder.setPositiveButton(R.string.OK, null);
-        builder.setMessage(output.toString());
-        AlertDialog diag = builder.create();
-        diag.show();
-    }
-
-    /**
-     * Clears all collected pointer results
-     */
-    private void resetTouchResults() {
-         mPointerEvent.startX = mPointerEvent.startY =
-                    mPointerEvent.endX = mPointerEvent.endY = -1;
-    }
-
-    /**
-     * Collects pointer touch information converting from relative to absolute before
-     * storing it as starting touch coordinates.
-     *
-     * @param event
-     * @param view
-     * @param pointerIndex
-     */
-    private void collectStartAction(MotionEvent event, View view) {
-        int offsetInScreen[] = new int[2];
-        view.getLocationOnScreen(offsetInScreen);
-        mPointerEvent.startX = (int)(event.getX() + offsetInScreen[0]);
-        mPointerEvent.startY = (int)(event.getY() + offsetInScreen[1]);
-    }
-
-    /**
-     * Collects pointer touch information converting from relative to absolute before
-     * storing it as ending touch coordinates.
-     *
-     * @param event
-     * @param view
-     * @param pointerIndex
-     */
-    private void collectEndAction(MotionEvent event, View view) {
-        int offsetInScreen[] = new int[2];
-        view.getLocationOnScreen(offsetInScreen);
-        mPointerEvent.endX = (int)(event.getX() + offsetInScreen[0]);
-        mPointerEvent.endY = (int)(event.getY() + offsetInScreen[1]);
-    }
-}
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/Test6DetailFragment.java b/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/Test6DetailFragment.java
deleted file mode 100644
index 90bcfcf..0000000
--- a/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/Test6DetailFragment.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.uiautomator;
-
-import android.os.Bundle;
-import android.support.v4.app.Fragment;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.webkit.WebView;
-
-public class Test6DetailFragment extends Fragment {
-    public static final String ARG_ITEM_ID = "item_id";
-    private final static String PAGE = "<html><body>"
-            + "This is test <b>6</b> for WebView text traversal test."
-            + "<p/><a href=\"http://google.com\">This is a link to google</a><br/>"
-            + "<h5>This is h5 text</h5>"
-            + "<a href=\"http://yahoo.com\">This is a link to yahoo</a>"
-            + "<p/><h4>This is h4 text</h4>" + "</body></html>";
-
-    public Test6DetailFragment() {
-    }
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-    }
-
-    @Override
-    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) {
-        View rootView = inflater.inflate(R.layout.test6_detail_fragment, container, false);
-        WebView wv = (WebView) rootView.findViewById(R.id.test6WebView);
-        wv.loadData(PAGE, "text/html", null);
-        return rootView;
-    }
-}
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/TestGenericDetailFragment.java b/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/TestGenericDetailFragment.java
deleted file mode 100644
index a7215c3..0000000
--- a/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/TestGenericDetailFragment.java
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.uiautomator;
-
-import android.app.AlertDialog;
-import android.os.Bundle;
-import android.support.v4.app.Fragment;
-import android.view.LayoutInflater;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.TextView;
-
-public class TestGenericDetailFragment extends Fragment {
-    public static final String ARG_ITEM_ID = "item_id";
-    TestItems.TestItem mItem;
-
-    private class PointerEvent {
-        int startX;
-        int startY;
-        int endX;
-        int endY;
-    }
-
-    private final PointerEvent[] mPointerEvents = new PointerEvent[10];
-
-    public TestGenericDetailFragment() {
-    }
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        if (getArguments().containsKey(ARG_ITEM_ID)) {
-            mItem = TestItems.getTest(getArguments().getString(ARG_ITEM_ID));
-        }
-    }
-
-    @Override
-    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) {
-        View rootView = inflater.inflate(R.layout.test_results_detail_fragment, container, false);
-        if (mItem != null) {
-            ((TextView) rootView.findViewById(R.id.testResultsTextView)).setText(mItem.mName);
-        }
-
-        // listen to touch events to verify the multiPointerGesture APIs
-        // Since API Level 18
-        rootView.setOnTouchListener(new View.OnTouchListener() {
-            @Override
-            public boolean onTouch(View v, MotionEvent event) {
-
-                switch(event.getAction() & MotionEvent.ACTION_MASK) {
-                    case MotionEvent.ACTION_DOWN:
-                        // Reset any collected touch coordinate results on the primary touch down
-                        resetTouchResults();
-                        // collect this event
-                        collectStartAction(event, v, 0);
-                        break;
-
-                    case MotionEvent.ACTION_POINTER_DOWN:
-                        // collect this event
-                        collectStartAction(event, v, getPointerIndex(event));
-                        break;
-
-                    case MotionEvent.ACTION_POINTER_UP:
-                        // collect this event
-                        collectEndAction(event, v, getPointerIndex(event));
-                        break;
-
-                    case MotionEvent.ACTION_UP:
-                        // collect this event
-                        collectEndAction(event, v, 0);
-                        // on the primary touch up display results collected for all pointers
-                        displayTouchResults();
-                        break;
-                }
-                return true;
-            }
-        });
-
-        return rootView;
-    }
-
-    /**
-     * Displays collected results from all pointers into a dialog view in the following
-     * format: "startX,startY:endX,endY" where each line represent data for a pointer if
-     * multiple pointers (fingers) were detected.
-     */
-    private void displayTouchResults() {
-        StringBuilder output = new StringBuilder();
-        for (int x = 0; x < mPointerEvents.length; x++) {
-            if (mPointerEvents[x].startX == -1)
-                break;
-
-            output.append(String.format("%d,%d:%d,%d\n",
-                    mPointerEvents[x].startX, mPointerEvents[x].startY, mPointerEvents[x].endX,
-                    mPointerEvents[x].endY));
-        }
-
-        // display the submitted text
-        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
-        builder.setTitle(R.string.generic_item_touch_dialog_title);
-        builder.setPositiveButton(R.string.OK, null);
-        builder.setMessage(output.toString());
-        AlertDialog diag = builder.create();
-        diag.show();
-    }
-
-    /**
-     * Clears all collected pointer results
-     */
-    private void resetTouchResults() {
-        for (int x = 0; x < mPointerEvents.length; x++) {
-            if (mPointerEvents[x] == null)
-                mPointerEvents[x] = new PointerEvent();
-            mPointerEvents[x].startX = mPointerEvents[x].startY =
-                    mPointerEvents[x].endX = mPointerEvents[x].endY = -1;
-        }
-    }
-
-    /**
-     * Collects pointer touch information converting from relative to absolute before
-     * storing it as starting touch coordinates.
-     *
-     * @param event
-     * @param view
-     * @param pointerIndex
-     */
-    private void collectStartAction(MotionEvent event, View view, int pointerIndex) {
-        int offsetInScreen[] = new int[2];
-        view.getLocationOnScreen(offsetInScreen);
-        mPointerEvents[getPointerId(event)].startX =
-                (int)(event.getX(pointerIndex) + offsetInScreen[0]);
-        mPointerEvents[getPointerId(event)].startY =
-                (int)(event.getY(pointerIndex) + offsetInScreen[1]);
-    }
-
-    /**
-     * Collects pointer touch information converting from relative to absolute before
-     * storing it as ending touch coordinates.
-     *
-     * @param event
-     * @param view
-     * @param pointerIndex
-     */
-    private void collectEndAction(MotionEvent event, View view, int pointerIndex) {
-        int offsetInScreen[] = new int[2];
-        view.getLocationOnScreen(offsetInScreen);
-        mPointerEvents[getPointerId(event)].endX =
-                (int)(event.getX(pointerIndex) + offsetInScreen[0]);
-        mPointerEvents[getPointerId(event)].endY =
-                (int)(event.getY(pointerIndex) + offsetInScreen[1]);
-    }
-
-    private int getPointerId(MotionEvent event) {
-        return event.getPointerId(getPointerIndex(event));
-    }
-
-    private int getPointerIndex(MotionEvent event) {
-        return ((event.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK)
-                >> MotionEvent.ACTION_POINTER_INDEX_SHIFT);
-    }
-}
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/TestItems.java b/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/TestItems.java
deleted file mode 100644
index db6e693..0000000
--- a/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/TestItems.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.uiautomator;
-
-import android.os.Bundle;
-import android.support.v4.app.Fragment;
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-public class TestItems {
-    private static String LOG_TAG = TestItems.class.getSimpleName();
-    private static List<TestItem> ITEMS = new ArrayList<TestItem>();
-    private static Map<String, TestItem> ITEM_MAP = new HashMap<String, TestItem>();
-
-    public static class TestItem {
-        public String mId;
-        public String mName;
-        private final Class<Fragment> mClassFragment;
-        public String mTestDescription;
-
-        @SuppressWarnings("unchecked")
-        public TestItem(String id, String name, Class<?> clsf) {
-            mId = id;
-            mName = name;
-            mClassFragment = (Class<Fragment>) clsf;
-        }
-
-        @Override
-        public String toString() {
-            return mName;
-        }
-    }
-
-    static {
-        addTestItem(new TestItem("1", "Test 1", Test1DetailFragment.class));
-        addTestItem(new TestItem("2", "Test 2", Test2DetailFragment.class));
-        addTestItem(new TestItem("3", "Test 3", Test3DetailFragment.class));
-        addTestItem(new TestItem("4", "Test 4", Test4DetailFragment.class));
-        addTestItem(new TestItem("5", "Test 5", Test5DetailFragment.class));
-        addTestItem(new TestItem("6", "Test 6", Test6DetailFragment.class));
-        addTestItem(new TestItem("7", "Test 7", TestGenericDetailFragment.class));
-        addTestItem(new TestItem("8", "Test 8", TestGenericDetailFragment.class));
-        addTestItem(new TestItem("9", "Test 9", TestGenericDetailFragment.class));
-        addTestItem(new TestItem("10", "Test 10", TestGenericDetailFragment.class));
-        addTestItem(new TestItem("11", "Test 11", TestGenericDetailFragment.class));
-        addTestItem(new TestItem("12", "Test 12", TestGenericDetailFragment.class));
-        addTestItem(new TestItem("13", "Test 13", TestGenericDetailFragment.class));
-        addTestItem(new TestItem("14", "Test 14", TestGenericDetailFragment.class));
-        addTestItem(new TestItem("15", "Test 15", TestGenericDetailFragment.class));
-        addTestItem(new TestItem("16", "Test 16", TestGenericDetailFragment.class));
-        addTestItem(new TestItem("17", "Test 17", TestGenericDetailFragment.class));
-        addTestItem(new TestItem("18", "Test 18", TestGenericDetailFragment.class));
-        addTestItem(new TestItem("19", "Test 19", TestGenericDetailFragment.class));
-        addTestItem(new TestItem("20", "Test 20", TestGenericDetailFragment.class));
-        addTestItem(new TestItem("21", "Test 21", TestGenericDetailFragment.class));
-        addTestItem(new TestItem("22", "Test 22", TestGenericDetailFragment.class));
-        addTestItem(new TestItem("23", "Test 23", TestGenericDetailFragment.class));
-        addTestItem(new TestItem("24", "Test 24", TestGenericDetailFragment.class));
-        addTestItem(new TestItem("25", "Test 25", TestGenericDetailFragment.class));
-        addTestItem(new TestItem("26", "Test 26", TestGenericDetailFragment.class));
-        addTestItem(new TestItem("27", "Test 27", TestGenericDetailFragment.class));
-        addTestItem(new TestItem("28", "Test 28", TestGenericDetailFragment.class));
-        addTestItem(new TestItem("29", "Test 29", TestGenericDetailFragment.class));
-        addTestItem(new TestItem("30", "Test 30", TestGenericDetailFragment.class));
-        addTestItem(new TestItem("31", "Test 31", TestGenericDetailFragment.class));
-        addTestItem(new TestItem("32", "Test 32", TestGenericDetailFragment.class));
-        addTestItem(new TestItem("33", "Test 33", TestGenericDetailFragment.class));
-        addTestItem(new TestItem("34", "Test 34", TestGenericDetailFragment.class));
-        addTestItem(new TestItem("35", "Test 35", TestGenericDetailFragment.class));
-        addTestItem(new TestItem("36", "Test 36", TestGenericDetailFragment.class));
-        addTestItem(new TestItem("37", "Test 37", TestGenericDetailFragment.class));
-        addTestItem(new TestItem("38", "Test 38", TestGenericDetailFragment.class));
-        addTestItem(new TestItem("39", "Test 39", TestGenericDetailFragment.class));
-        addTestItem(new TestItem("40", "Test 40", TestGenericDetailFragment.class));
-    }
-
-    private static void addTestItem(TestItem item) {
-        ITEMS.add(item);
-        ITEM_MAP.put(item.mId, item);
-    }
-
-    public static List<TestItem> getTests() {
-        return ITEMS;
-    }
-
-    public static TestItem getTest(String id) {
-        return ITEM_MAP.get(id);
-    }
-
-    public static TestItem getTest(int pos) {
-        return ITEMS.get(pos);
-    }
-
-    public static Fragment getFragment(String id) {
-        try {
-            Fragment fragment = getTest(id).mClassFragment.newInstance();
-            Bundle arguments = new Bundle();
-            arguments.putString("item_id", id);
-            fragment.setArguments(arguments);
-            return fragment;
-        } catch (InstantiationException e) {
-            Log.e(LOG_TAG, "Exception", e);
-            return null;
-        } catch (IllegalAccessException e) {
-            Log.e(LOG_TAG, "Exception", e);
-            return null;
-        }
-    }
-}
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/TestListFragment.java b/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/TestListFragment.java
deleted file mode 100644
index 46f0f73..0000000
--- a/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/TestListFragment.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.cts.uiautomator;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.support.v4.app.ListFragment;
-import android.view.View;
-import android.widget.ArrayAdapter;
-import android.widget.ListView;
-
-public class TestListFragment extends ListFragment {
-
-    private static final String STATE_ACTIVATED_POSITION = "activated_position";
-
-    private Callbacks mCallbacks = sDummyCallbacks;
-    private int mActivatedPosition = ListView.INVALID_POSITION;
-
-    public interface Callbacks {
-
-        public void onItemSelected(String id);
-    }
-
-    private static Callbacks sDummyCallbacks = new Callbacks() {
-        @Override
-        public void onItemSelected(String id) {
-        }
-    };
-
-    public TestListFragment() {
-    }
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setListAdapter(new ArrayAdapter<TestItems.TestItem>(getActivity(),
-                R.layout.simple_list_item_selected, R.id.label, TestItems.getTests()));
-    }
-
-    @Override
-    public void onViewCreated(View view, Bundle savedState) {
-        super.onViewCreated(view, savedState);
-        if (savedState != null && savedState.containsKey(STATE_ACTIVATED_POSITION)) {
-            setActivatedPosition(savedState.getInt(STATE_ACTIVATED_POSITION));
-        }
-    }
-
-    @Override
-    public void onAttach(Activity activity) {
-        super.onAttach(activity);
-        if (!(activity instanceof Callbacks)) {
-            throw new IllegalStateException("Activity must implement fragment's callbacks.");
-        }
-
-        mCallbacks = (Callbacks) activity;
-    }
-
-    @Override
-    public void onDetach() {
-        super.onDetach();
-        mCallbacks = sDummyCallbacks;
-    }
-
-    @Override
-    public void onListItemClick(ListView listView, View view, int position, long id) {
-        super.onListItemClick(listView, view, position, id);
-        mCallbacks.onItemSelected(TestItems.getTest(position).mId);
-    }
-
-    @Override
-    public void onSaveInstanceState(Bundle outState) {
-        super.onSaveInstanceState(outState);
-        if (mActivatedPosition != ListView.INVALID_POSITION) {
-            outState.putInt(STATE_ACTIVATED_POSITION, mActivatedPosition);
-        }
-    }
-
-    public void setActivateOnItemClick(boolean activateOnItemClick) {
-        getListView().setChoiceMode(
-                activateOnItemClick ? ListView.CHOICE_MODE_SINGLE : ListView.CHOICE_MODE_NONE);
-    }
-
-    public void setActivatedPosition(int position) {
-        if (position == ListView.INVALID_POSITION) {
-            getListView().setItemChecked(mActivatedPosition, false);
-        } else {
-            getListView().setItemChecked(position, true);
-        }
-
-        mActivatedPosition = position;
-    }
-}
diff --git a/tests/video/Android.mk b/tests/video/Android.mk
new file mode 100644
index 0000000..5348731
--- /dev/null
+++ b/tests/video/Android.mk
@@ -0,0 +1,40 @@
+# Copyright (C) 2013 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+# don't include this package in any target
+LOCAL_MODULE_TAGS := optional
+# and when built explicitly put it in the data partition
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+# include both the 32 and 64 bit versions
+LOCAL_MULTILIB := both
+
+LOCAL_STATIC_JAVA_LIBRARIES := ctsmediautil ctsdeviceutil compatibility-device-util ctstestrunner
+
+LOCAL_JNI_SHARED_LIBRARIES := libctsmediacodec_jni libnativehelper_compat_libc++
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := CtsVideoTestCases
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_PACKAGE)
+
diff --git a/tests/video/AndroidManifest.xml b/tests/video/AndroidManifest.xml
new file mode 100644
index 0000000..22dad9e
--- /dev/null
+++ b/tests/video/AndroidManifest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="android.video.cts">
+
+    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+            android:targetPackage="android.video.cts"
+            android:label="CTS tests for Video" >
+        <meta-data
+            android:name="listener"
+            android:value="com.android.cts.runner.CtsTestRunListener" />
+    </instrumentation>
+</manifest>
diff --git a/tests/video/AndroidTest.xml b/tests/video/AndroidTest.xml
new file mode 100644
index 0000000..0c98c42
--- /dev/null
+++ b/tests/video/AndroidTest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS Video test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsVideoTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.video.cts" />
+    </test>
+</configuration>
diff --git a/tests/video/src/android/video/cts/CodecInfo.java b/tests/video/src/android/video/cts/CodecInfo.java
new file mode 100644
index 0000000..c1bf0a9
--- /dev/null
+++ b/tests/video/src/android/video/cts/CodecInfo.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.video.cts;
+
+import android.media.MediaCodec;
+import android.media.MediaCodecInfo;
+import android.media.MediaCodecInfo.CodecCapabilities;
+import android.media.MediaCodecInfo.CodecProfileLevel;
+import android.media.MediaCodecInfo.VideoCapabilities;
+import android.media.MediaCodecList;
+import android.media.MediaFormat;
+import android.util.Log;
+import android.util.Range;
+
+import java.io.IOException;
+
+/**
+ * Utility class for getting codec information like bit rate, fps, and etc.
+ * Uses public member variables instead of methods as this code is only for video benchmarking.
+ */
+public class CodecInfo {
+    /** bit rate in bps */
+    public int mBitRate = 0;
+    /** Frame rate */
+    public int mFps = 0;
+    /** if codec is supporting YUV semiplanar format */
+    public boolean mSupportSemiPlanar = false;
+    /** if codec is supporting YUV planar format */
+    public boolean mSupportPlanar = false;
+
+    private static final String TAG = "CodecInfo";
+    private static final String VIDEO_AVC = MediaFormat.MIMETYPE_VIDEO_AVC;
+    /**
+     * Check if given codec with given (w,h) is supported.
+     * @param codecName codec name
+     * @param mimeType codec type in mime format like MediaFormat.MIMETYPE_VIDEO_AVC
+     * @param w video width
+     * @param h video height
+     * @return null if the configuration is not supported.
+     */
+    public static CodecInfo getSupportedFormatInfo(
+            String codecName, String mimeType, int w, int h) {
+        MediaCodec codec;
+        try {
+            codec = MediaCodec.createByCodecName(codecName);
+        } catch (IOException e) {
+            return null;
+        }
+
+        CodecCapabilities cap = codec.getCodecInfo().getCapabilitiesForType(mimeType);
+        if (cap.colorFormats.length == 0) {
+            Log.w(TAG, "no supported color format");
+            codec.release();
+            return null;
+        }
+
+        CodecInfo info = new CodecInfo();
+        for (int color : cap.colorFormats) {
+            if (color == CodecCapabilities.COLOR_FormatYUV420SemiPlanar) {
+                info.mSupportSemiPlanar = true;
+            }
+            if (color == CodecCapabilities.COLOR_FormatYUV420Planar) {
+                info.mSupportPlanar = true;
+            }
+        }
+        printIntArray("supported colors", cap.colorFormats);
+
+        VideoCapabilities vidCap = cap.getVideoCapabilities();
+        try {
+            info.mFps = vidCap.getSupportedFrameRatesFor(w, h).getUpper().intValue();
+        } catch (IllegalArgumentException e) {
+            Log.w(TAG, "unsupported size");
+            codec.release();
+            return null;
+        }
+        info.mBitRate = vidCap.getBitrateRange().getUpper();
+        Log.i(TAG, "test bit rate " + info.mBitRate + " fps " + info.mFps);
+        codec.release();
+        return info;
+    }
+
+    // for debugging
+    private static void printIntArray(String msg, int[] data) {
+        StringBuilder builder = new StringBuilder();
+        builder.append(msg);
+        builder.append(":");
+        for (int e : data) {
+            builder.append(Integer.toHexString(e));
+            builder.append(",");
+        }
+        builder.deleteCharAt(builder.length() - 1);
+        Log.i(TAG, builder.toString());
+    }
+}
diff --git a/tests/video/src/android/video/cts/VideoEncoderDecoderTest.java b/tests/video/src/android/video/cts/VideoEncoderDecoderTest.java
new file mode 100644
index 0000000..2c54d35
--- /dev/null
+++ b/tests/video/src/android/video/cts/VideoEncoderDecoderTest.java
@@ -0,0 +1,1203 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.video.cts;
+
+import android.cts.util.MediaUtils;
+import android.cts.util.DeviceReportLog;
+import android.graphics.ImageFormat;
+import android.graphics.Point;
+import android.media.Image;
+import android.media.Image.Plane;
+import android.media.MediaCodec;
+import android.media.MediaCodec.BufferInfo;
+import android.media.MediaCodecInfo;
+import android.media.MediaCodecInfo.CodecCapabilities;
+import android.media.MediaCodecList;
+import android.media.MediaFormat;
+import android.media.cts.CodecImage;
+import android.media.cts.CodecUtils;
+import android.media.cts.YUVImage;
+import android.util.Log;
+import android.util.Pair;
+import android.util.Range;
+
+import android.cts.util.CtsAndroidTestCase;
+import com.android.cts.util.ResultType;
+import com.android.cts.util.ResultUnit;
+import com.android.compatibility.common.util.Stat;
+import com.android.cts.util.TimeoutReq;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.Random;
+
+/**
+ * This tries to test video encoder / decoder performance by running encoding / decoding
+ * without displaying the raw data. To make things simpler, encoder is used to encode synthetic
+ * data and decoder is used to decode the encoded video. This approach does not work where
+ * there is only decoder. Performance index is total time taken for encoding and decoding
+ * the whole frames.
+ * To prevent sacrificing quality for faster encoding / decoding, randomly selected pixels are
+ * compared with the original image. As the pixel comparison can slow down the decoding process,
+ * only some randomly selected pixels are compared. As there can be only one performance index,
+ * error above certain threshold in pixel value will be treated as an error.
+ */
+public class VideoEncoderDecoderTest extends CtsAndroidTestCase {
+    private static final String TAG = "VideoEncoderDecoderTest";
+    // this wait time affects fps as too big value will work as a blocker if device fps
+    // is not very high.
+    private static final long VIDEO_CODEC_WAIT_TIME_US = 5000;
+    private static final boolean VERBOSE = false;
+    private static final String VIDEO_AVC = MediaFormat.MIMETYPE_VIDEO_AVC;
+    private static final String VIDEO_VP8 = MediaFormat.MIMETYPE_VIDEO_VP8;
+    private static final String VIDEO_H263 = MediaFormat.MIMETYPE_VIDEO_H263;
+    private static final String VIDEO_MPEG4 = MediaFormat.MIMETYPE_VIDEO_MPEG4;
+    private static final String VIDEO_HEVC = MediaFormat.MIMETYPE_VIDEO_HEVC;
+    private int mCurrentTestRound = 0;
+    private double[][] mEncoderFrameTimeDiff = null;
+    private double[][] mDecoderFrameTimeDiff = null;
+    // i frame interval for encoder
+    private static final int KEY_I_FRAME_INTERVAL = 5;
+    private static final int MOVING_AVERAGE_NUM = 10;
+
+    private static final int Y_CLAMP_MIN = 16;
+    private static final int Y_CLAMP_MAX = 235;
+    private static final int YUV_PLANE_ADDITIONAL_LENGTH = 200;
+    private ByteBuffer mYBuffer, mYDirectBuffer;
+    private ByteBuffer mUVBuffer, mUVDirectBuffer;
+    private int mSrcColorFormat;
+    private int mDstColorFormat;
+    private int mBufferWidth;
+    private int mBufferHeight;
+    private int mVideoWidth;
+    private int mVideoHeight;
+    private int mFrameRate;
+
+    private MediaFormat mEncInputFormat;
+    private MediaFormat mEncOutputFormat;
+    private MediaFormat mDecOutputFormat;
+
+    private LinkedList<Pair<ByteBuffer, BufferInfo>> mEncodedOutputBuffer;
+    // check this many pixels per each decoded frame
+    // checking too many points decreases decoder frame rates a lot.
+    private static final int PIXEL_CHECK_PER_FRAME = 1000;
+    // RMS error in pixel values above this will be treated as error.
+    private static final double PIXEL_RMS_ERROR_MARGAIN = 20.0;
+    private double mRmsErrorMargain = PIXEL_RMS_ERROR_MARGAIN;
+    private Random mRandom;
+
+    private class TestConfig {
+        public boolean mTestPixels = true;
+        public boolean mTestResult = false;
+        public boolean mReportFrameTime = false;
+        public int mTotalFrames = 300;
+        public int mMaxTimeMs = 120000;  // 2 minutes
+        public int mNumberOfRepeat = 10;
+    }
+
+    private TestConfig mTestConfig;
+
+    private DeviceReportLog mReportLog;
+
+    @Override
+    protected void setUp() throws Exception {
+        mEncodedOutputBuffer = new LinkedList<Pair<ByteBuffer, BufferInfo>>();
+        // Use time as a seed, hoping to prevent checking pixels in the same pattern
+        long now = System.currentTimeMillis();
+        mRandom = new Random(now);
+        mTestConfig = new TestConfig();
+        mReportLog = new DeviceReportLog();
+        super.setUp();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        mEncodedOutputBuffer.clear();
+        mEncodedOutputBuffer = null;
+        mYBuffer = null;
+        mUVBuffer = null;
+        mYDirectBuffer = null;
+        mUVDirectBuffer = null;
+        mRandom = null;
+        mTestConfig = null;
+        mReportLog.deliverReportToHost(getInstrumentation());
+        super.tearDown();
+    }
+
+    private String getEncoderName(String mime) {
+        return getCodecName(mime, true /* isEncoder */);
+    }
+
+    private String getDecoderName(String mime) {
+        return getCodecName(mime, false /* isEncoder */);
+    }
+
+    private String getCodecName(String mime, boolean isEncoder) {
+        MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
+        for (MediaCodecInfo info : mcl.getCodecInfos()) {
+            if (info.isEncoder() != isEncoder) {
+                continue;
+            }
+            CodecCapabilities caps = null;
+            try {
+                caps = info.getCapabilitiesForType(mime);
+            } catch (IllegalArgumentException e) {  // mime is not supported
+                continue;
+            }
+            return info.getName();
+        }
+        return null;
+    }
+
+    private String[] getEncoderName(String mime, boolean isGoog) {
+        return getCodecName(mime, isGoog, true /* isEncoder */);
+    }
+
+    private String[] getDecoderName(String mime, boolean isGoog) {
+        return getCodecName(mime, isGoog, false /* isEncoder */);
+    }
+
+    private String[] getCodecName(String mime, boolean isGoog, boolean isEncoder) {
+        MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
+        ArrayList<String> result = new ArrayList<String>();
+        for (MediaCodecInfo info : mcl.getCodecInfos()) {
+            if (info.isEncoder() != isEncoder
+                    || info.getName().toLowerCase().startsWith("omx.google.") != isGoog) {
+                continue;
+            }
+            CodecCapabilities caps = null;
+            try {
+                caps = info.getCapabilitiesForType(mime);
+            } catch (IllegalArgumentException e) {  // mime is not supported
+                continue;
+            }
+            result.add(info.getName());
+        }
+        return result.toArray(new String[result.size()]);
+    }
+
+    public void testAvc0176x0144() throws Exception {
+        doTestDefault(VIDEO_AVC, 176, 144);
+    }
+
+    public void testAvc0352x0288() throws Exception {
+        doTestDefault(VIDEO_AVC, 352, 288);
+    }
+
+    public void testAvc0720x0480() throws Exception {
+        doTestDefault(VIDEO_AVC, 720, 480);
+    }
+
+    public void testAvc1280x0720() throws Exception {
+        doTestDefault(VIDEO_AVC, 1280, 720);
+    }
+
+    /**
+     * resolution intentionally set to 1072 not 1080
+     * as 1080 is not multiple of 16, and it requires additional setting like stride
+     * which is not specified in API documentation.
+     */
+    public void testAvc1920x1072() throws Exception {
+        doTestDefault(VIDEO_AVC, 1920, 1072);
+    }
+
+    // Avc tests
+    public void testAvc0320x0240Other() throws Exception {
+        doTestOther(VIDEO_AVC, 320, 240);
+    }
+
+    public void testAvc0320x0240Goog() throws Exception {
+        doTestGoog(VIDEO_AVC, 320, 240);
+    }
+
+    public void testAvc0720x0480Other() throws Exception {
+        doTestOther(VIDEO_AVC, 720, 480);
+    }
+
+    public void testAvc0720x0480Goog() throws Exception {
+        doTestGoog(VIDEO_AVC, 720, 480);
+    }
+
+    @TimeoutReq(minutes = 10)
+    public void testAvc1280x0720Other() throws Exception {
+        doTestOther(VIDEO_AVC, 1280, 720);
+    }
+
+    @TimeoutReq(minutes = 10)
+    public void testAvc1280x0720Goog() throws Exception {
+        doTestGoog(VIDEO_AVC, 1280, 720);
+    }
+
+    @TimeoutReq(minutes = 10)
+    public void testAvc1920x1080Other() throws Exception {
+        doTestOther(VIDEO_AVC, 1920, 1080);
+    }
+
+    @TimeoutReq(minutes = 10)
+    public void testAvc1920x1080Goog() throws Exception {
+        doTestGoog(VIDEO_AVC, 1920, 1080);
+    }
+
+    // Vp8 tests
+    public void testVp80320x0180Other() throws Exception {
+        doTestOther(VIDEO_VP8, 320, 180);
+    }
+
+    public void testVp80320x0180Goog() throws Exception {
+        doTestGoog(VIDEO_VP8, 320, 180);
+    }
+
+    public void testVp80640x0360Other() throws Exception {
+        doTestOther(VIDEO_VP8, 640, 360);
+    }
+
+    public void testVp80640x0360Goog() throws Exception {
+        doTestGoog(VIDEO_VP8, 640, 360);
+    }
+
+    @TimeoutReq(minutes = 10)
+    public void testVp81280x0720Other() throws Exception {
+        doTestOther(VIDEO_VP8, 1280, 720);
+    }
+
+    @TimeoutReq(minutes = 10)
+    public void testVp81280x0720Goog() throws Exception {
+        doTestGoog(VIDEO_VP8, 1280, 720);
+    }
+
+    @TimeoutReq(minutes = 10)
+    public void testVp81920x1080Other() throws Exception {
+        doTestOther(VIDEO_VP8, 1920, 1080);
+    }
+
+    @TimeoutReq(minutes = 10)
+    public void testVp81920x1080Goog() throws Exception {
+        doTestGoog(VIDEO_VP8, 1920, 1080);
+    }
+
+    // H263 tests
+    public void testH2630176x0144Other() throws Exception {
+        doTestOther(VIDEO_H263, 176, 144);
+    }
+
+    public void testH2630176x0144Goog() throws Exception {
+        doTestGoog(VIDEO_H263, 176, 144);
+    }
+
+    public void testH2630352x0288Other() throws Exception {
+        doTestOther(VIDEO_H263, 352, 288);
+    }
+
+    public void testH2630352x0288Goog() throws Exception {
+        doTestGoog(VIDEO_H263, 352, 288);
+    }
+
+    // Mpeg4 tests
+    public void testMpeg40176x0144Other() throws Exception {
+        doTestOther(VIDEO_MPEG4, 176, 144);
+    }
+
+    public void testMpeg40176x0144Goog() throws Exception {
+        doTestGoog(VIDEO_MPEG4, 176, 144);
+    }
+
+    public void testMpeg40352x0288Other() throws Exception {
+        doTestOther(VIDEO_MPEG4, 352, 288);
+    }
+
+    public void testMpeg40352x0288Goog() throws Exception {
+        doTestGoog(VIDEO_MPEG4, 352, 288);
+    }
+
+    public void testMpeg40640x0480Other() throws Exception {
+        doTestOther(VIDEO_MPEG4, 640, 480);
+    }
+
+    public void testMpeg40640x0480Goog() throws Exception {
+        doTestGoog(VIDEO_MPEG4, 640, 480);
+    }
+
+    @TimeoutReq(minutes = 10)
+    public void testMpeg41280x0720Other() throws Exception {
+        doTestOther(VIDEO_MPEG4, 1280, 720);
+    }
+
+    @TimeoutReq(minutes = 10)
+    public void testMpeg41280x0720Goog() throws Exception {
+        doTestGoog(VIDEO_MPEG4, 1280, 720);
+    }
+
+    // Hevc tests
+    public void testHevc0320x0240Other() throws Exception {
+        doTestOther(VIDEO_HEVC, 320, 240);
+    }
+
+    public void testHevc0320x0240Goog() throws Exception {
+        doTestGoog(VIDEO_HEVC, 320, 240);
+    }
+
+    public void testHevc0720x0480Other() throws Exception {
+        doTestOther(VIDEO_HEVC, 720, 480);
+    }
+
+    public void testHevc0720x0480Goog() throws Exception {
+        doTestGoog(VIDEO_HEVC, 720, 480);
+    }
+
+    @TimeoutReq(minutes = 10)
+    public void testHevc1280x0720Other() throws Exception {
+        doTestOther(VIDEO_HEVC, 1280, 720);
+    }
+
+    @TimeoutReq(minutes = 10)
+    public void testHevc1280x0720Goog() throws Exception {
+        doTestGoog(VIDEO_HEVC, 1280, 720);
+    }
+
+    @TimeoutReq(minutes = 10)
+    public void testHevc1920x1080Other() throws Exception {
+        doTestOther(VIDEO_HEVC, 1920, 1080);
+    }
+
+    @TimeoutReq(minutes = 10)
+    public void testHevc1920x1080Goog() throws Exception {
+        doTestGoog(VIDEO_HEVC, 1920, 1080);
+    }
+
+    @TimeoutReq(minutes = 10)
+    public void testHevc3840x2160Other() throws Exception {
+        doTestOther(VIDEO_HEVC, 3840, 2160);
+    }
+
+    @TimeoutReq(minutes = 10)
+    public void testHevc3840x2160Goog() throws Exception {
+        doTestGoog(VIDEO_HEVC, 3840, 2160);
+    }
+
+    private boolean isSrcSemiPlanar() {
+        return mSrcColorFormat == CodecCapabilities.COLOR_FormatYUV420SemiPlanar;
+    }
+
+    private boolean isSrcFlexYUV() {
+        return mSrcColorFormat == CodecCapabilities.COLOR_FormatYUV420Flexible;
+    }
+
+    private boolean isDstSemiPlanar() {
+        return mDstColorFormat == CodecCapabilities.COLOR_FormatYUV420SemiPlanar;
+    }
+
+    private boolean isDstFlexYUV() {
+        return mDstColorFormat == CodecCapabilities.COLOR_FormatYUV420Flexible;
+    }
+
+    private static int getColorFormat(CodecInfo info) {
+        if (info.mSupportSemiPlanar) {
+            return CodecCapabilities.COLOR_FormatYUV420SemiPlanar;
+        } else if (info.mSupportPlanar) {
+            return CodecCapabilities.COLOR_FormatYUV420Planar;
+        } else {
+            // FlexYUV must be supported
+            return CodecCapabilities.COLOR_FormatYUV420Flexible;
+        }
+    }
+
+    private void doTestGoog(String mimeType, int w, int h) throws Exception {
+        mTestConfig.mTestPixels = false;
+        mTestConfig.mTestResult = true;
+        mTestConfig.mTotalFrames = 3000;
+        mTestConfig.mNumberOfRepeat = 2;
+        doTest(true /* isGoog */, mimeType, w, h);
+    }
+
+    private void doTestOther(String mimeType, int w, int h) throws Exception {
+        mTestConfig.mTestPixels = false;
+        mTestConfig.mTestResult = true;
+        mTestConfig.mTotalFrames = 3000;
+        mTestConfig.mNumberOfRepeat = 2;
+        doTest(false /* isGoog */, mimeType, w, h);
+    }
+
+    private void doTestDefault(String mimeType, int w, int h) throws Exception {
+        String encoderName = getEncoderName(mimeType);
+        if (encoderName == null) {
+            Log.i(TAG, "Encoder for " + mimeType + " not found");
+            return;
+        }
+
+        String decoderName = getDecoderName(mimeType);
+        if (decoderName == null) {
+            Log.i(TAG, "Encoder for " + mimeType + " not found");
+            return;
+        }
+
+        doTestByName(encoderName, decoderName, mimeType, w, h);
+    }
+
+    /**
+     * Run encoding / decoding test for given mimeType of codec
+     * @param isGoog test google or non-google codec.
+     * @param mimeType like video/avc
+     * @param w video width
+     * @param h video height
+     */
+    private void doTest(boolean isGoog, String mimeType, int w, int h)
+            throws Exception {
+        String[] encoderNames = getEncoderName(mimeType, isGoog);
+        if (encoderNames.length == 0) {
+            Log.i(TAG, isGoog ? "Google " : "Non-google "
+                    + "encoder for " + mimeType + " not found");
+            return;
+        }
+
+        String[] decoderNames = getDecoderName(mimeType, isGoog);
+        if (decoderNames.length == 0) {
+            Log.i(TAG, isGoog ? "Google " : "Non-google "
+                    + "decoder for " + mimeType + " not found");
+            return;
+        }
+
+        for (String encoderName: encoderNames) {
+            for (String decoderName: decoderNames) {
+                doTestByName(encoderName, decoderName, mimeType, w, h);
+            }
+        }
+    }
+
+    private void doTestByName(
+            String encoderName, String decoderName, String mimeType, int w, int h)
+            throws Exception {
+        CodecInfo infoEnc = CodecInfo.getSupportedFormatInfo(encoderName, mimeType, w, h);
+        if (infoEnc == null) {
+            Log.i(TAG, "Encoder " + mimeType + " with " + w + "," + h + " not supported");
+            return;
+        }
+        CodecInfo infoDec = CodecInfo.getSupportedFormatInfo(decoderName, mimeType, w, h);
+        assertNotNull(infoDec);
+        mVideoWidth = w;
+        mVideoHeight = h;
+
+        mSrcColorFormat = getColorFormat(infoEnc);
+        mDstColorFormat = getColorFormat(infoDec);
+        Log.i(TAG, "Testing video resolution " + w + "x" + h +
+                   ": enc format " + mSrcColorFormat +
+                   ", dec format " + mDstColorFormat);
+
+        initYUVPlane(w + YUV_PLANE_ADDITIONAL_LENGTH, h + YUV_PLANE_ADDITIONAL_LENGTH);
+        // Adjust total number of frames to prevent OOM.
+        Runtime rt = Runtime.getRuntime();
+        long usedMemory = rt.totalMemory() - rt.freeMemory();
+        mTestConfig.mTotalFrames = Math.min(mTestConfig.mTotalFrames,
+                (int) (rt.maxMemory() - usedMemory) /
+                (infoEnc.mBitRate / 8 / infoEnc.mFps + 1));
+        Log.i(TAG, "Total testing frames " + mTestConfig.mTotalFrames);
+
+        mEncoderFrameTimeDiff =
+                new double[mTestConfig.mNumberOfRepeat][mTestConfig.mTotalFrames - 1];
+        mDecoderFrameTimeDiff =
+                new double[mTestConfig.mNumberOfRepeat][mTestConfig.mTotalFrames - 1];
+        double[] encoderFpsResults = new double[mTestConfig.mNumberOfRepeat];
+        double[] decoderFpsResults = new double[mTestConfig.mNumberOfRepeat];
+        double[] totalFpsResults = new double[mTestConfig.mNumberOfRepeat];
+        double[] decoderRmsErrorResults = new double[mTestConfig.mNumberOfRepeat];
+        boolean success = true;
+        for (int i = 0; i < mTestConfig.mNumberOfRepeat && success; i++) {
+            mCurrentTestRound = i;
+            MediaFormat format = new MediaFormat();
+            format.setString(MediaFormat.KEY_MIME, mimeType);
+            format.setInteger(MediaFormat.KEY_BIT_RATE, infoEnc.mBitRate);
+            format.setInteger(MediaFormat.KEY_WIDTH, w);
+            format.setInteger(MediaFormat.KEY_HEIGHT, h);
+            format.setInteger(MediaFormat.KEY_COLOR_FORMAT, mSrcColorFormat);
+            format.setInteger(MediaFormat.KEY_FRAME_RATE, infoEnc.mFps);
+            mFrameRate = infoEnc.mFps;
+            format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, KEY_I_FRAME_INTERVAL);
+
+            double encodingTime = runEncoder(encoderName, format, mTestConfig.mTotalFrames);
+            // re-initialize format for decoder
+            format = new MediaFormat();
+            format.setString(MediaFormat.KEY_MIME, mimeType);
+            format.setInteger(MediaFormat.KEY_WIDTH, w);
+            format.setInteger(MediaFormat.KEY_HEIGHT, h);
+            format.setInteger(MediaFormat.KEY_COLOR_FORMAT, mDstColorFormat);
+            double[] decoderResult = runDecoder(decoderName, format);
+            if (decoderResult == null) {
+                success = false;
+            } else {
+                double decodingTime = decoderResult[0];
+                decoderRmsErrorResults[i] = decoderResult[1];
+                encoderFpsResults[i] = (double)mTestConfig.mTotalFrames / encodingTime * 1000.0;
+                decoderFpsResults[i] = (double)mTestConfig.mTotalFrames / decodingTime * 1000.0;
+                totalFpsResults[i] =
+                        (double)mTestConfig.mTotalFrames / (encodingTime + decodingTime) * 1000.0;
+            }
+
+            // clear things for re-start
+            mEncodedOutputBuffer.clear();
+            // it will be good to clean everything to make every run the same.
+            System.gc();
+        }
+        mReportLog.printArray("encoder", encoderFpsResults, ResultType.HIGHER_BETTER,
+                ResultUnit.FPS);
+        mReportLog.printArray("rms error", decoderRmsErrorResults, ResultType.LOWER_BETTER,
+                ResultUnit.NONE);
+        mReportLog.printArray("decoder", decoderFpsResults, ResultType.HIGHER_BETTER,
+                ResultUnit.FPS);
+        mReportLog.printArray("encoder decoder", totalFpsResults, ResultType.HIGHER_BETTER,
+                ResultUnit.FPS);
+        mReportLog.printValue(mimeType + " encoder average fps for " + w + "x" + h,
+                Stat.getAverage(encoderFpsResults), ResultType.HIGHER_BETTER, ResultUnit.FPS);
+        mReportLog.printValue(mimeType + " decoder average fps for " + w + "x" + h,
+                Stat.getAverage(decoderFpsResults), ResultType.HIGHER_BETTER, ResultUnit.FPS);
+        mReportLog.printSummary("encoder decoder", Stat.getAverage(totalFpsResults),
+                ResultType.HIGHER_BETTER, ResultUnit.FPS);
+
+        boolean encTestPassed = false;
+        boolean decTestPassed = false;
+        double[] measuredFps = new double[mTestConfig.mNumberOfRepeat];
+        String[] resultRawData = new String[mTestConfig.mNumberOfRepeat];
+        for (int i = 0; i < mTestConfig.mNumberOfRepeat; i++) {
+            // make sure that rms error is not too big.
+            if (decoderRmsErrorResults[i] >= mRmsErrorMargain) {
+                fail("rms error is bigger than the limit "
+                        + decoderRmsErrorResults[i] + " vs " + mRmsErrorMargain);
+            }
+
+            if (mTestConfig.mReportFrameTime) {
+                mReportLog.printValue(
+                        "encodertest#" + i + ": " + Arrays.toString(mEncoderFrameTimeDiff[i]),
+                        0, ResultType.NEUTRAL, ResultUnit.NONE);
+                mReportLog.printValue(
+                        "decodertest#" + i + ": " + Arrays.toString(mDecoderFrameTimeDiff[i]),
+                        0, ResultType.NEUTRAL, ResultUnit.NONE);
+            }
+
+            if (mTestConfig.mTestResult) {
+                double[] avgs = MediaUtils.calculateMovingAverage(
+                        mEncoderFrameTimeDiff[i], MOVING_AVERAGE_NUM);
+                double encMin = Stat.getMin(avgs);
+                double encMax = Stat.getMax(avgs);
+                double encAvg = MediaUtils.getAverage(mEncoderFrameTimeDiff[i]);
+                double encStdev = MediaUtils.getStdev(avgs);
+                String prefix = "codec=" + encoderName + " round=" + i +
+                        " EncInputFormat=" + mEncInputFormat +
+                        " EncOutputFormat=" + mEncOutputFormat;
+                String result =
+                        MediaUtils.logResults(mReportLog, prefix, encMin, encMax, encAvg, encStdev);
+                double measuredEncFps = 1000000000 / encMin;
+                resultRawData[i] = result;
+                measuredFps[i] = measuredEncFps;
+                if (!encTestPassed) {
+                    encTestPassed = MediaUtils.verifyResults(
+                            encoderName, mimeType, w, h, measuredEncFps);
+                }
+
+                avgs = MediaUtils.calculateMovingAverage(
+                        mDecoderFrameTimeDiff[i], MOVING_AVERAGE_NUM);
+                double decMin = Stat.getMin(avgs);
+                double decMax = Stat.getMax(avgs);
+                double decAvg = MediaUtils.getAverage(mDecoderFrameTimeDiff[i]);
+                double decStdev = MediaUtils.getStdev(avgs);
+                prefix = "codec=" + decoderName + " size=" + w + "x" + h + " round=" + i +
+                        " DecOutputFormat=" + mDecOutputFormat;
+                MediaUtils.logResults(mReportLog, prefix, decMin, decMax, decAvg, decStdev);
+                double measuredDecFps = 1000000000 / decMin;
+                if (!decTestPassed) {
+                    decTestPassed = MediaUtils.verifyResults(
+                            decoderName, mimeType, w, h, measuredDecFps);
+                }
+            }
+        }
+
+        if (mTestConfig.mTestResult) {
+            if (!encTestPassed) {
+                Range<Double> reportedRange =
+                    MediaUtils.getAchievableFrameRatesFor(encoderName, mimeType, w, h);
+                String failMessage =
+                    MediaUtils.getErrorMessage(reportedRange, measuredFps, resultRawData);
+                fail(failMessage);
+            }
+            // Decoder result will be verified in VideoDecoderPerfTest
+            // if (!decTestPassed) {
+            //     fail("Measured fps for " + decoderName +
+            //             " doesn't match with reported achievable frame rates.");
+            // }
+        }
+        measuredFps = null;
+        resultRawData = null;
+    }
+
+    /**
+     * run encoder benchmarking
+     * @param encoderName encoder name
+     * @param format format of media to encode
+     * @param totalFrames total number of frames to encode
+     * @return time taken in ms to encode the frames. This does not include initialization time.
+     */
+    private double runEncoder(String encoderName, MediaFormat format, int totalFrames) {
+        MediaCodec codec = null;
+        try {
+            codec = MediaCodec.createByCodecName(encoderName);
+            codec.configure(
+                    format,
+                    null /* surface */,
+                    null /* crypto */,
+                    MediaCodec.CONFIGURE_FLAG_ENCODE);
+        } catch (IllegalStateException e) {
+            Log.e(TAG, "codec '" + encoderName + "' failed configuration.");
+            codec.release();
+            assertTrue("codec '" + encoderName + "' failed configuration.", false);
+        } catch (IOException | NullPointerException e) {
+            Log.i(TAG, "could not find codec for " + format);
+            return Double.NaN;
+        }
+        codec.start();
+        mEncInputFormat = codec.getInputFormat();
+        ByteBuffer[] codecOutputBuffers = codec.getOutputBuffers();
+
+        int numBytesSubmitted = 0;
+        int numBytesDequeued = 0;
+        int inFramesCount = 0;
+        long lastOutputTimeNs = 0;
+        long start = System.currentTimeMillis();
+        while (true) {
+            int index;
+
+            if (inFramesCount < totalFrames) {
+                index = codec.dequeueInputBuffer(VIDEO_CODEC_WAIT_TIME_US /* timeoutUs */);
+                if (index != MediaCodec.INFO_TRY_AGAIN_LATER) {
+                    int size;
+                    boolean eos = (inFramesCount == (totalFrames - 1));
+                    if (!eos && ((System.currentTimeMillis() - start) > mTestConfig.mMaxTimeMs)) {
+                        eos = true;
+                    }
+                    // when encoder only supports flexYUV, use Image only; otherwise,
+                    // use ByteBuffer & Image each on half of the frames to test both
+                    if (isSrcFlexYUV() || inFramesCount % 2 == 0) {
+                        Image image = codec.getInputImage(index);
+                        // image should always be available
+                        assertTrue(image != null);
+                        size = queueInputImageEncoder(
+                                codec, image, index, inFramesCount,
+                                eos ? MediaCodec.BUFFER_FLAG_END_OF_STREAM : 0);
+                    } else {
+                        ByteBuffer buffer = codec.getInputBuffer(index);
+                        size = queueInputBufferEncoder(
+                                codec, buffer, index, inFramesCount,
+                                eos ? MediaCodec.BUFFER_FLAG_END_OF_STREAM : 0);
+                    }
+                    inFramesCount++;
+                    numBytesSubmitted += size;
+                    if (VERBOSE) {
+                        Log.d(TAG, "queued " + size + " bytes of input data, frame " +
+                                (inFramesCount - 1));
+                    }
+
+                }
+            }
+            MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
+            index = codec.dequeueOutputBuffer(info, VIDEO_CODEC_WAIT_TIME_US /* timeoutUs */);
+            if (index == MediaCodec.INFO_TRY_AGAIN_LATER) {
+            } else if (index == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
+                mEncOutputFormat = codec.getOutputFormat();
+            } else if (index == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
+                codecOutputBuffers = codec.getOutputBuffers();
+            } else if (index >= 0) {
+                if (lastOutputTimeNs > 0) {
+                    int pos = mEncodedOutputBuffer.size() - 1;
+                    if (pos < mEncoderFrameTimeDiff[mCurrentTestRound].length) {
+                        long diff = System.nanoTime() - lastOutputTimeNs;
+                        mEncoderFrameTimeDiff[mCurrentTestRound][pos] = diff;
+                    }
+                }
+                lastOutputTimeNs = System.nanoTime();
+
+                dequeueOutputBufferEncoder(codec, codecOutputBuffers, index, info);
+                numBytesDequeued += info.size;
+                if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
+                    if (VERBOSE) {
+                        Log.d(TAG, "dequeued output EOS.");
+                    }
+                    break;
+                }
+                if (VERBOSE) {
+                    Log.d(TAG, "dequeued " + info.size + " bytes of output data.");
+                }
+            }
+        }
+        long finish = System.currentTimeMillis();
+        int validDataNum = Math.min(mEncodedOutputBuffer.size() - 1,
+                mEncoderFrameTimeDiff[mCurrentTestRound].length);
+        mEncoderFrameTimeDiff[mCurrentTestRound] =
+                Arrays.copyOf(mEncoderFrameTimeDiff[mCurrentTestRound], validDataNum);
+        if (VERBOSE) {
+            Log.d(TAG, "queued a total of " + numBytesSubmitted + "bytes, "
+                    + "dequeued " + numBytesDequeued + " bytes.");
+        }
+        codec.stop();
+        codec.release();
+        codec = null;
+        return (double)(finish - start);
+    }
+
+    /**
+     * Fills input buffer for encoder from YUV buffers.
+     * @return size of enqueued data.
+     */
+    private int queueInputBufferEncoder(
+            MediaCodec codec, ByteBuffer buffer, int index, int frameCount, int flags) {
+        buffer.clear();
+
+        Point origin = getOrigin(frameCount);
+        // Y color first
+        int srcOffsetY = origin.x + origin.y * mBufferWidth;
+        final byte[] yBuffer = mYBuffer.array();
+        for (int i = 0; i < mVideoHeight; i++) {
+            buffer.put(yBuffer, srcOffsetY, mVideoWidth);
+            srcOffsetY += mBufferWidth;
+        }
+        if (isSrcSemiPlanar()) {
+            int srcOffsetU = origin.y / 2 * mBufferWidth + origin.x / 2 * 2;
+            final byte[] uvBuffer = mUVBuffer.array();
+            for (int i = 0; i < mVideoHeight / 2; i++) {
+                buffer.put(uvBuffer, srcOffsetU, mVideoWidth);
+                srcOffsetU += mBufferWidth;
+            }
+        } else {
+            int srcOffsetU = origin.y / 2 * mBufferWidth / 2 + origin.x / 2;
+            int srcOffsetV = srcOffsetU + mBufferWidth / 2 * mBufferHeight / 2;
+            final byte[] uvBuffer = mUVBuffer.array();
+            for (int i = 0; i < mVideoHeight / 2; i++) { //U only
+                buffer.put(uvBuffer, srcOffsetU, mVideoWidth / 2);
+                srcOffsetU += mBufferWidth / 2;
+            }
+            for (int i = 0; i < mVideoHeight / 2; i++) { //V only
+                buffer.put(uvBuffer, srcOffsetV, mVideoWidth / 2);
+                srcOffsetV += mBufferWidth / 2;
+            }
+        }
+        int size = mVideoHeight * mVideoWidth * 3 / 2;
+        long ptsUsec = computePresentationTime(frameCount);
+
+        codec.queueInputBuffer(index, 0 /* offset */, size, ptsUsec /* timeUs */, flags);
+        if (VERBOSE && (frameCount == 0)) {
+            printByteArray("Y ", mYBuffer.array(), 0, 20);
+            printByteArray("UV ", mUVBuffer.array(), 0, 20);
+            printByteArray("UV ", mUVBuffer.array(), mBufferWidth * 60, 20);
+        }
+        return size;
+    }
+
+    /**
+     * Fills input image for encoder from YUV buffers.
+     * @return size of enqueued data.
+     */
+    private int queueInputImageEncoder(
+            MediaCodec codec, Image image, int index, int frameCount, int flags) {
+        assertTrue(image.getFormat() == ImageFormat.YUV_420_888);
+
+
+        Point origin = getOrigin(frameCount);
+
+        // Y color first
+        CodecImage srcImage = new YUVImage(
+                origin,
+                mVideoWidth, mVideoHeight,
+                mBufferWidth, mBufferHeight,
+                isSrcSemiPlanar(),
+                mYDirectBuffer, mUVDirectBuffer);
+
+        CodecUtils.copyFlexYUVImage(image, srcImage);
+
+        int size = mVideoHeight * mVideoWidth * 3 / 2;
+        long ptsUsec = computePresentationTime(frameCount);
+
+        codec.queueInputBuffer(index, 0 /* offset */, size, ptsUsec /* timeUs */, flags);
+        if (VERBOSE && (frameCount == 0)) {
+            printByteArray("Y ", mYBuffer.array(), 0, 20);
+            printByteArray("UV ", mUVBuffer.array(), 0, 20);
+            printByteArray("UV ", mUVBuffer.array(), mBufferWidth * 60, 20);
+        }
+        return size;
+    }
+
+    /**
+     * Dequeue encoded data from output buffer and store for later usage.
+     */
+    private void dequeueOutputBufferEncoder(
+            MediaCodec codec, ByteBuffer[] outputBuffers,
+            int index, MediaCodec.BufferInfo info) {
+        ByteBuffer output = outputBuffers[index];
+        int l = info.size;
+        ByteBuffer copied = ByteBuffer.allocate(l);
+        output.get(copied.array(), 0, l);
+        BufferInfo savedInfo = new BufferInfo();
+        savedInfo.set(0, l, info.presentationTimeUs, info.flags);
+        mEncodedOutputBuffer.addLast(Pair.create(copied, savedInfo));
+        codec.releaseOutputBuffer(index, false /* render */);
+    }
+
+    /**
+     * run decoder benchmarking with encoded stream stored from encoding phase
+     * @param decoderName decoder name
+     * @param format format of media to decode
+     * @return returns length-2 array with 0: time for decoding, 1 : rms error of pixels
+     */
+    private double[] runDecoder(String decoderName, MediaFormat format) {
+        MediaCodec codec = null;
+        try {
+            codec = MediaCodec.createByCodecName(decoderName);
+        } catch (IOException | NullPointerException e) {
+            Log.i(TAG, "could not find decoder for " + format);
+            return null;
+        }
+        codec.configure(format, null /* surface */, null /* crypto */, 0 /* flags */);
+        codec.start();
+        ByteBuffer[] codecInputBuffers = codec.getInputBuffers();
+
+        double totalErrorSquared = 0;
+
+        MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
+        boolean sawOutputEOS = false;
+        int inputLeft = mEncodedOutputBuffer.size();
+        int inputBufferCount = 0;
+        int outFrameCount = 0;
+        YUVValue expected = new YUVValue();
+        YUVValue decoded = new YUVValue();
+        long lastOutputTimeNs = 0;
+        long start = System.currentTimeMillis();
+        while (!sawOutputEOS) {
+            if (inputLeft > 0) {
+                int inputBufIndex = codec.dequeueInputBuffer(VIDEO_CODEC_WAIT_TIME_US);
+
+                if (inputBufIndex >= 0) {
+                    ByteBuffer dstBuf = codecInputBuffers[inputBufIndex];
+                    dstBuf.clear();
+                    ByteBuffer src = mEncodedOutputBuffer.get(inputBufferCount).first;
+                    BufferInfo srcInfo = mEncodedOutputBuffer.get(inputBufferCount).second;
+                    int writeSize = src.capacity();
+                    dstBuf.put(src.array(), 0, writeSize);
+
+                    int flags = srcInfo.flags;
+                    if ((System.currentTimeMillis() - start) > mTestConfig.mMaxTimeMs) {
+                        flags |= MediaCodec.BUFFER_FLAG_END_OF_STREAM;
+                    }
+
+                    codec.queueInputBuffer(
+                            inputBufIndex,
+                            0 /* offset */,
+                            writeSize,
+                            srcInfo.presentationTimeUs,
+                            flags);
+                    inputLeft --;
+                    inputBufferCount ++;
+                }
+            }
+
+            int res = codec.dequeueOutputBuffer(info, VIDEO_CODEC_WAIT_TIME_US);
+            if (res >= 0) {
+                int outputBufIndex = res;
+
+                // only do YUV compare on EOS frame if the buffer size is none-zero
+                if (info.size > 0) {
+                    if (lastOutputTimeNs > 0) {
+                        int pos = outFrameCount - 1;
+                        if (pos < mDecoderFrameTimeDiff[mCurrentTestRound].length) {
+                            long diff = System.nanoTime() - lastOutputTimeNs;
+                            mDecoderFrameTimeDiff[mCurrentTestRound][pos] = diff;
+                        }
+                    }
+                    lastOutputTimeNs = System.nanoTime();
+
+                    if (mTestConfig.mTestPixels) {
+                        Point origin = getOrigin(outFrameCount);
+                        int i;
+
+                        // if decoder supports planar or semiplanar, check output with
+                        // ByteBuffer & Image each on half of the points
+                        int pixelCheckPerFrame = PIXEL_CHECK_PER_FRAME;
+                        if (!isDstFlexYUV()) {
+                            pixelCheckPerFrame /= 2;
+                            ByteBuffer buf = codec.getOutputBuffer(outputBufIndex);
+                            if (VERBOSE && (outFrameCount == 0)) {
+                                printByteBuffer("Y ", buf, 0, 20);
+                                printByteBuffer("UV ", buf, mVideoWidth * mVideoHeight, 20);
+                                printByteBuffer("UV ", buf,
+                                        mVideoWidth * mVideoHeight + mVideoWidth * 60, 20);
+                            }
+                            for (i = 0; i < pixelCheckPerFrame; i++) {
+                                int w = mRandom.nextInt(mVideoWidth);
+                                int h = mRandom.nextInt(mVideoHeight);
+                                getPixelValuesFromYUVBuffers(origin.x, origin.y, w, h, expected);
+                                getPixelValuesFromOutputBuffer(buf, w, h, decoded);
+                                if (VERBOSE) {
+                                    Log.i(TAG, outFrameCount + "-" + i + "- th round: ByteBuffer:"
+                                            + " expected "
+                                            + expected.mY + "," + expected.mU + "," + expected.mV
+                                            + " decoded "
+                                            + decoded.mY + "," + decoded.mU + "," + decoded.mV);
+                                }
+                                totalErrorSquared += expected.calcErrorSquared(decoded);
+                            }
+                        }
+
+                        Image image = codec.getOutputImage(outputBufIndex);
+                        assertTrue(image != null);
+                        for (i = 0; i < pixelCheckPerFrame; i++) {
+                            int w = mRandom.nextInt(mVideoWidth);
+                            int h = mRandom.nextInt(mVideoHeight);
+                            getPixelValuesFromYUVBuffers(origin.x, origin.y, w, h, expected);
+                            getPixelValuesFromImage(image, w, h, decoded);
+                            if (VERBOSE) {
+                                Log.i(TAG, outFrameCount + "-" + i + "- th round: FlexYUV:"
+                                        + " expcted "
+                                        + expected.mY + "," + expected.mU + "," + expected.mV
+                                        + " decoded "
+                                        + decoded.mY + "," + decoded.mU + "," + decoded.mV);
+                            }
+                            totalErrorSquared += expected.calcErrorSquared(decoded);
+                        }
+                    }
+                    outFrameCount++;
+                }
+                codec.releaseOutputBuffer(outputBufIndex, false /* render */);
+                if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
+                    Log.d(TAG, "saw output EOS.");
+                    sawOutputEOS = true;
+                }
+            } else if (res == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
+                mDecOutputFormat = codec.getOutputFormat();
+                Log.d(TAG, "output format has changed to " + mDecOutputFormat);
+                int colorFormat = mDecOutputFormat.getInteger(MediaFormat.KEY_COLOR_FORMAT);
+                if (colorFormat == CodecCapabilities.COLOR_FormatYUV420SemiPlanar
+                        || colorFormat == CodecCapabilities.COLOR_FormatYUV420Planar) {
+                    mDstColorFormat = colorFormat;
+                } else {
+                    mDstColorFormat = CodecCapabilities.COLOR_FormatYUV420Flexible;
+                    Log.w(TAG, "output format changed to unsupported one " +
+                            Integer.toHexString(colorFormat) + ", using FlexYUV");
+                }
+            }
+        }
+        long finish = System.currentTimeMillis();
+        int validDataNum = Math.min(outFrameCount - 1,
+                mDecoderFrameTimeDiff[mCurrentTestRound].length);
+        mDecoderFrameTimeDiff[mCurrentTestRound] =
+                Arrays.copyOf(mDecoderFrameTimeDiff[mCurrentTestRound], validDataNum);
+        codec.stop();
+        codec.release();
+        codec = null;
+
+        // divide by 3 as sum is done for Y, U, V.
+        double errorRms = Math.sqrt(totalErrorSquared / PIXEL_CHECK_PER_FRAME / outFrameCount / 3);
+        double[] result = { (double) finish - start, errorRms };
+        return result;
+    }
+
+    /**
+     *  returns origin in the absolute frame for given frame count.
+     *  The video scene is moving by moving origin per each frame.
+     */
+    private Point getOrigin(int frameCount) {
+        if (frameCount < 100) {
+            return new Point(2 * frameCount, 0);
+        } else if (frameCount < 200) {
+            return new Point(200, (frameCount - 100) * 2);
+        } else {
+            if (frameCount > 300) { // for safety
+                frameCount = 300;
+            }
+            return new Point(600 - frameCount * 2, 600 - frameCount * 2);
+        }
+    }
+
+    /**
+     * initialize reference YUV plane
+     * @param w This should be YUV_PLANE_ADDITIONAL_LENGTH pixels bigger than video resolution
+     *          to allow movements
+     * @param h This should be YUV_PLANE_ADDITIONAL_LENGTH pixels bigger than video resolution
+     *          to allow movements
+     * @param semiPlanarEnc
+     * @param semiPlanarDec
+     */
+    private void initYUVPlane(int w, int h) {
+        int bufferSizeY = w * h;
+        mYBuffer = ByteBuffer.allocate(bufferSizeY);
+        mUVBuffer = ByteBuffer.allocate(bufferSizeY / 2);
+        mYDirectBuffer = ByteBuffer.allocateDirect(bufferSizeY);
+        mUVDirectBuffer = ByteBuffer.allocateDirect(bufferSizeY / 2);
+        mBufferWidth = w;
+        mBufferHeight = h;
+        final byte[] yArray = mYBuffer.array();
+        final byte[] uvArray = mUVBuffer.array();
+        for (int i = 0; i < h; i++) {
+            for (int j = 0; j < w; j++) {
+                yArray[i * w + j]  = clampY((i + j) & 0xff);
+            }
+        }
+        if (isSrcSemiPlanar()) {
+            for (int i = 0; i < h/2; i++) {
+                for (int j = 0; j < w/2; j++) {
+                    uvArray[i * w + 2 * j]  = (byte) (i & 0xff);
+                    uvArray[i * w + 2 * j + 1]  = (byte) (j & 0xff);
+                }
+            }
+        } else { // planar, U first, then V
+            int vOffset = bufferSizeY / 4;
+            for (int i = 0; i < h/2; i++) {
+                for (int j = 0; j < w/2; j++) {
+                    uvArray[i * w/2 + j]  = (byte) (i & 0xff);
+                    uvArray[i * w/2 + vOffset + j]  = (byte) (j & 0xff);
+                }
+            }
+        }
+        mYDirectBuffer.put(yArray);
+        mUVDirectBuffer.put(uvArray);
+        mYDirectBuffer.rewind();
+        mUVDirectBuffer.rewind();
+    }
+
+    /**
+     * class to store pixel values in YUV
+     *
+     */
+    public class YUVValue {
+        public byte mY;
+        public byte mU;
+        public byte mV;
+        public YUVValue() {
+        }
+
+        public boolean equalTo(YUVValue other) {
+            return (mY == other.mY) && (mU == other.mU) && (mV == other.mV);
+        }
+
+        public double calcErrorSquared(YUVValue other) {
+            // Java's byte is signed but here we want to calculate difference in unsigned bytes.
+            double yDelta = (mY & 0xFF) - (other.mY & 0xFF);
+            double uDelta = (mU & 0xFF) - (other.mU & 0xFF);
+            double vDelta = (mV & 0xFF) - (other.mV & 0xFF);
+            return yDelta * yDelta + uDelta * uDelta + vDelta * vDelta;
+        }
+    }
+
+    /**
+     * Read YUV values from given position (x,y) for given origin (originX, originY)
+     * The whole data is already available from YBuffer and UVBuffer.
+     * @param result pass the result via this. This is for avoiding creating / destroying too many
+     *               instances
+     */
+    private void getPixelValuesFromYUVBuffers(int originX, int originY, int x, int y,
+            YUVValue result) {
+        result.mY = mYBuffer.get((originY + y) * mBufferWidth + (originX + x));
+        if (isSrcSemiPlanar()) {
+            int index = (originY + y) / 2 * mBufferWidth + (originX + x) / 2 * 2;
+            //Log.d(TAG, "YUV " + originX + "," + originY + "," + x + "," + y + "," + index);
+            result.mU = mUVBuffer.get(index);
+            result.mV = mUVBuffer.get(index + 1);
+        } else {
+            int vOffset = mBufferWidth * mBufferHeight / 4;
+            int index = (originY + y) / 2 * mBufferWidth / 2 + (originX + x) / 2;
+            result.mU = mUVBuffer.get(index);
+            result.mV = mUVBuffer.get(vOffset + index);
+        }
+    }
+
+    /**
+     * Read YUV pixels from decoded output buffer for give (x, y) position
+     * Output buffer is composed of Y parts followed by U/V
+     * @param result pass the result via this. This is for avoiding creating / destroying too many
+     *               instances
+     */
+    private void getPixelValuesFromOutputBuffer(ByteBuffer buffer, int x, int y, YUVValue result) {
+        result.mY = buffer.get(y * mVideoWidth + x);
+        if (isDstSemiPlanar()) {
+            int index = mVideoWidth * mVideoHeight + y / 2 * mVideoWidth + x / 2 * 2;
+            //Log.d(TAG, "Decoded " + x + "," + y + "," + index);
+            result.mU = buffer.get(index);
+            result.mV = buffer.get(index + 1);
+        } else {
+            int vOffset = mVideoWidth * mVideoHeight / 4;
+            int index = mVideoWidth * mVideoHeight + y / 2 * mVideoWidth / 2 + x / 2;
+            result.mU = buffer.get(index);
+            result.mV = buffer.get(index + vOffset);
+        }
+    }
+
+    private void getPixelValuesFromImage(Image image, int x, int y, YUVValue result) {
+        assertTrue(image.getFormat() == ImageFormat.YUV_420_888);
+
+        Plane[] planes = image.getPlanes();
+        assertTrue(planes.length == 3);
+
+        result.mY = getPixelFromPlane(planes[0], x, y);
+        result.mU = getPixelFromPlane(planes[1], x / 2, y / 2);
+        result.mV = getPixelFromPlane(planes[2], x / 2, y / 2);
+    }
+
+    private byte getPixelFromPlane(Plane plane, int x, int y) {
+        ByteBuffer buf = plane.getBuffer();
+        return buf.get(y * plane.getRowStride() + x * plane.getPixelStride());
+    }
+
+    /**
+     * Y cannot have full range. clamp it to prevent invalid value.
+     */
+    private byte clampY(int y) {
+        if (y < Y_CLAMP_MIN) {
+            y = Y_CLAMP_MIN;
+        } else if (y > Y_CLAMP_MAX) {
+            y = Y_CLAMP_MAX;
+        }
+        return (byte) (y & 0xff);
+    }
+
+    // for debugging
+    private void printByteArray(String msg, byte[] data, int offset, int len) {
+        StringBuilder builder = new StringBuilder();
+        builder.append(msg);
+        builder.append(":");
+        for (int i = offset; i < offset + len; i++) {
+            builder.append(Integer.toHexString(data[i]));
+            builder.append(",");
+        }
+        builder.deleteCharAt(builder.length() - 1);
+        Log.i(TAG, builder.toString());
+    }
+
+    // for debugging
+    private void printByteBuffer(String msg, ByteBuffer data, int offset, int len) {
+        StringBuilder builder = new StringBuilder();
+        builder.append(msg);
+        builder.append(":");
+        for (int i = offset; i < offset + len; i++) {
+            builder.append(Integer.toHexString(data.get(i)));
+            builder.append(",");
+        }
+        builder.deleteCharAt(builder.length() - 1);
+        Log.i(TAG, builder.toString());
+    }
+
+    /**
+     * Generates the presentation time for frame N, in microseconds.
+     */
+    private long computePresentationTime(int frameIndex) {
+        return 132 + frameIndex * 1000000L / mFrameRate;
+    }
+}
diff --git a/tests/vm/Android.mk b/tests/vm/Android.mk
new file mode 100755
index 0000000..ed28a37
--- /dev/null
+++ b/tests/vm/Android.mk
@@ -0,0 +1,39 @@
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+# Don't include this package in any target
+LOCAL_MODULE_TAGS := tests
+# When built, explicitly put it in the data partition.
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_DEX_PREOPT := false
+
+LOCAL_PROGUARD_ENABLED := disabled
+
+LOCAL_STATIC_JAVA_LIBRARIES := compatibility-device-util android-support-test
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_PACKAGE_NAME := CtsVmTestCases
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_PACKAGE)
diff --git a/tests/vm/AndroidManifest.xml b/tests/vm/AndroidManifest.xml
new file mode 100755
index 0000000..cbd2c90
--- /dev/null
+++ b/tests/vm/AndroidManifest.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.vm.cts">
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <!--  self-instrumenting test package. -->
+    <instrumentation
+        android:name="android.support.test.runner.AndroidJUnitRunner"
+        android:label="CTS VM test cases"
+        android:targetPackage="android.vm.cts" >
+    </instrumentation>
+</manifest>
+
diff --git a/tests/vm/AndroidTest.xml b/tests/vm/AndroidTest.xml
new file mode 100644
index 0000000..fc1098b
--- /dev/null
+++ b/tests/vm/AndroidTest.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS VM test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsVmTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.vm.cts" />
+        <option name="runtime-hint" value="20m14s" />
+    </test>
+</configuration>
diff --git a/tests/vm/src/android/vm/cts/opcodes/add_double/AddDoubleTest.java b/tests/vm/src/android/vm/cts/opcodes/add_double/AddDoubleTest.java
new file mode 100644
index 0000000..ba5a41d
--- /dev/null
+++ b/tests/vm/src/android/vm/cts/opcodes/add_double/AddDoubleTest.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.vm.cts.opcodes.add_double;
+
+import junit.framework.TestCase;
+
+public class AddDoubleTest extends TestCase {
+
+    /**
+     * @title Arguments = 2.7d, 3.14d
+     */
+    public void testN1() {
+        AddDouble_1 t = new AddDouble_1();
+        assertEquals(5.84d, t.run(2.7d, 3.14d));
+    }
+
+    /**
+     * @title Arguments = 0, -3.14d
+     */
+    public void testN2() {
+        AddDouble_1 t = new AddDouble_1();
+        assertEquals(-3.14d, t.run(0, -3.14d));
+    }
+
+    /**
+     * @title Arguments = -3.14d, -2.7d
+     */
+    public void testN3() {
+        AddDouble_1 t = new AddDouble_1();
+        assertEquals(-5.84d, t.run(-3.14d, -2.7d));
+    }
+
+    /**
+     * @title Arguments = Double.MAX_VALUE, Double.NaN
+     */
+    public void testB1() {
+        AddDouble_1 t = new AddDouble_1();
+        assertEquals(Double.NaN, t.run(Double.MAX_VALUE, Double.NaN));
+    }
+
+    /**
+     * @title Arguments = Double.POSITIVE_INFINITY,
+     * Double.NEGATIVE_INFINITY
+     */
+    public void testB2() {
+        AddDouble_1 t = new AddDouble_1();
+        assertEquals(Double.NaN, t.run(Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY));
+    }
+
+    /**
+     * @title Arguments = Double.POSITIVE_INFINITY,
+     * Double.POSITIVE_INFINITY
+     */
+    public void testB3() {
+        AddDouble_1 t = new AddDouble_1();
+        assertEquals(Double.POSITIVE_INFINITY, t.run(Double.POSITIVE_INFINITY,
+                Double.POSITIVE_INFINITY));
+    }
+
+    /**
+     * @title Arguments = Double.POSITIVE_INFINITY, -2.7d
+     */
+    public void testB4() {
+        AddDouble_1 t = new AddDouble_1();
+        assertEquals(Double.POSITIVE_INFINITY, t.run(Double.POSITIVE_INFINITY, -2.7d));
+    }
+
+    /**
+     * @title Arguments = +0, -0
+     */
+    public void testB5() {
+        AddDouble_1 t = new AddDouble_1();
+        assertEquals(+0d, t.run(+0d, -0d));
+    }
+
+    /**
+     * @title Arguments = -0d, -0d
+     */
+    public void testB6() {
+        AddDouble_1 t = new AddDouble_1();
+        assertEquals(-0d, t.run(-0d, -0d));
+    }
+
+    /**
+     * @title Arguments = -2.7d, 2.7d
+     */
+    public void testB7() {
+        AddDouble_1 t = new AddDouble_1();
+        assertEquals(+0d, t.run(-2.7d, 2.7d));
+    }
+
+    /**
+     * @title Arguments = Double.MAX_VALUE, Double.MAX_VALUE
+     */
+    public void testB8() {
+        AddDouble_1 t = new AddDouble_1();
+        assertEquals(Double.POSITIVE_INFINITY, t.run(Double.MAX_VALUE, Double.MAX_VALUE));
+    }
+
+    /**
+     * @title Arguments = Double.MIN_VALUE, -4.9E-324
+     */
+    public void testB9() {
+        AddDouble_1 t = new AddDouble_1();
+        assertEquals(0d, t.run(Double.MIN_VALUE, -4.9E-324));
+    }
+
+}
diff --git a/tests/vm/src/android/vm/cts/opcodes/add_double/AddDouble_1.java b/tests/vm/src/android/vm/cts/opcodes/add_double/AddDouble_1.java
new file mode 100644
index 0000000..d4ebed2
--- /dev/null
+++ b/tests/vm/src/android/vm/cts/opcodes/add_double/AddDouble_1.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.vm.cts.opcodes.add_double;
+
+public class AddDouble_1 {
+
+    public double run(double a, double b) {
+        return a + b;
+    }
+}
diff --git a/tests/vm/src/android/vm/cts/opcodes/add_double/AddDouble_3.java b/tests/vm/src/android/vm/cts/opcodes/add_double/AddDouble_3.java
new file mode 100644
index 0000000..587a68b
--- /dev/null
+++ b/tests/vm/src/android/vm/cts/opcodes/add_double/AddDouble_3.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.vm.cts.opcodes.add_double;
+
+public class AddDouble_3 {
+
+    public double run(long a, double b) {
+        return 1;
+    }
+}
diff --git a/tests/vm/src/android/vm/cts/opcodes/add_double_2addr/AddDouble2AddrTest.java b/tests/vm/src/android/vm/cts/opcodes/add_double_2addr/AddDouble2AddrTest.java
new file mode 100644
index 0000000..27de92c
--- /dev/null
+++ b/tests/vm/src/android/vm/cts/opcodes/add_double_2addr/AddDouble2AddrTest.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.vm.cts.opcodes.add_double_2addr;
+
+import junit.framework.TestCase;
+
+public class AddDouble2AddrTest extends TestCase {
+    /**
+     * @title Arguments = 2.7d, 3.14d
+     */
+    public void testN1() {
+        AddDouble2Addr_1 t = new AddDouble2Addr_1();
+        assertEquals(5.84d, t.run(2.7d, 3.14d));
+    }
+
+    /**
+     * @title Arguments = 0, -3.14d
+     */
+    public void testN2() {
+        AddDouble2Addr_1 t = new AddDouble2Addr_1();
+        assertEquals(-3.14d, t.run(0, -3.14d));
+    }
+
+    /**
+     * @title Arguments = -3.14d, -2.7d
+     */
+    public void testN3() {
+        AddDouble2Addr_1 t = new AddDouble2Addr_1();
+        assertEquals(-5.84d, t.run(-3.14d, -2.7d));
+    }
+
+    /**
+     * @title Arguments = Double.MAX_VALUE, Double.NaN
+     */
+    public void testB1() {
+        AddDouble2Addr_1 t = new AddDouble2Addr_1();
+        assertEquals(Double.NaN, t.run(Double.MAX_VALUE, Double.NaN));
+    }
+
+    /**
+     * @title Arguments = Double.POSITIVE_INFINITY,
+     * Double.NEGATIVE_INFINITY
+     */
+    public void testB2() {
+        AddDouble2Addr_1 t = new AddDouble2Addr_1();
+        assertEquals(Double.NaN, t.run(Double.POSITIVE_INFINITY,
+                Double.NEGATIVE_INFINITY));
+    }
+
+    /**
+     * @title Arguments = Double.POSITIVE_INFINITY,
+     * Double.POSITIVE_INFINITY
+     */
+    public void testB3() {
+        AddDouble2Addr_1 t = new AddDouble2Addr_1();
+        assertEquals(Double.POSITIVE_INFINITY, t.run(Double.POSITIVE_INFINITY,
+                Double.POSITIVE_INFINITY));
+    }
+
+    /**
+     * @title Arguments = Double.POSITIVE_INFINITY, -2.7d
+     */
+    public void testB4() {
+        AddDouble2Addr_1 t = new AddDouble2Addr_1();
+        assertEquals(Double.POSITIVE_INFINITY, t.run(Double.POSITIVE_INFINITY,
+                -2.7d));
+    }
+
+    /**
+     * @title Arguments = +0, -0
+     */
+    public void testB5() {
+        AddDouble2Addr_1 t = new AddDouble2Addr_1();
+        assertEquals(+0d, t.run(+0d, -0d));
+    }
+
+    /**
+     * @title Arguments = -0d, -0d
+     */
+    public void testB6() {
+        AddDouble2Addr_1 t = new AddDouble2Addr_1();
+        assertEquals(-0d, t.run(-0d, -0d));
+    }
+
+    /**
+     * @title Arguments = -2.7d, 2.7d
+     */
+    public void testB7() {
+        AddDouble2Addr_1 t = new AddDouble2Addr_1();
+        assertEquals(+0d, t.run(-2.7d, 2.7d));
+    }
+
+    /**
+     * @title Arguments = Double.MAX_VALUE, Double.MAX_VALUE
+     */
+    public void testB8() {
+        AddDouble2Addr_1 t = new AddDouble2Addr_1();
+        assertEquals(Double.POSITIVE_INFINITY, t.run(Double.MAX_VALUE,
+                Double.MAX_VALUE));
+    }
+
+    /**
+     * @title Arguments = Double.MIN_VALUE, -4.9E-324
+     */
+    public void testB9() {
+        AddDouble2Addr_1 t = new AddDouble2Addr_1();
+        assertEquals(0d, t.run(Double.MIN_VALUE, -4.9E-324));
+    }
+
+}
diff --git a/tests/vm/src/android/vm/cts/opcodes/add_double_2addr/AddDouble2Addr_1.java b/tests/vm/src/android/vm/cts/opcodes/add_double_2addr/AddDouble2Addr_1.java
new file mode 100644
index 0000000..2536113
--- /dev/null
+++ b/tests/vm/src/android/vm/cts/opcodes/add_double_2addr/AddDouble2Addr_1.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.vm.cts.opcodes.add_double_2addr;
+
+public class AddDouble2Addr_1 {
+
+    public double run(double a, double b) {
+        return a + b;
+    }
+}
diff --git a/tests/vm/src/android/vm/cts/opcodes/add_double_2addr/AddDouble2Addr_3.java b/tests/vm/src/android/vm/cts/opcodes/add_double_2addr/AddDouble2Addr_3.java
new file mode 100644
index 0000000..7ed1fe8
--- /dev/null
+++ b/tests/vm/src/android/vm/cts/opcodes/add_double_2addr/AddDouble2Addr_3.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.vm.cts.opcodes.add_double_2addr;
+
+public class AddDouble2Addr_3 {
+
+    public double run(long a) {
+        return 0;
+    }
+}
diff --git a/tests/vm/src/android/vm/cts/opcodes/add_float/AddFloatTest.java b/tests/vm/src/android/vm/cts/opcodes/add_float/AddFloatTest.java
new file mode 100644
index 0000000..76490b0
--- /dev/null
+++ b/tests/vm/src/android/vm/cts/opcodes/add_float/AddFloatTest.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.vm.cts.opcodes.add_float;
+
+import junit.framework.TestCase;
+
+public class AddFloatTest extends TestCase {
+    /**
+     * @title Arguments = 2.7f, 3.14f
+     */
+    public void testN1() {
+        AddFloat_1 t = new AddFloat_1();
+        assertEquals(5.84f, t.run(2.7f, 3.14f));
+    }
+
+    /**
+     * @title Arguments = 0, -3.14f
+     */
+    public void testN2() {
+        AddFloat_1 t = new AddFloat_1();
+        assertEquals(-3.14f, t.run(0, -3.14f));
+    }
+
+    /**
+     * @title Arguments = -3.14f, -2.7f
+     */
+    public void testN3() {
+        AddFloat_1 t = new AddFloat_1();
+        assertEquals(-5.84f, t.run(-3.14f, -2.7f));
+    }
+
+    /**
+     * @title Arguments = Float.MAX_VALUE, Float.NaN
+     */
+    public void testB1() {
+        AddFloat_1 t = new AddFloat_1();
+        assertEquals(Float.POSITIVE_INFINITY, t.run(3.3028235E38f, 0.11E38f));
+    }
+
+    /**
+     * @title Arguments = Float.POSITIVE_INFINITY,
+     * Float.NEGATIVE_INFINITY
+     */
+    public void testB2() {
+        AddFloat_1 t = new AddFloat_1();
+        assertTrue(Float.isNaN(t.run(Float.POSITIVE_INFINITY,
+                Float.NEGATIVE_INFINITY)));
+    }
+
+    /**
+     * @title Arguments = Float.POSITIVE_INFINITY,
+     * Float.POSITIVE_INFINITY
+     */
+    public void testB3() {
+        AddFloat_1 t = new AddFloat_1();
+        assertEquals(Float.POSITIVE_INFINITY, t.run(Float.POSITIVE_INFINITY,
+                Float.POSITIVE_INFINITY));
+    }
+
+    /**
+     * @title Arguments = Float.POSITIVE_INFINITY, -2.7f
+     */
+    public void testB4() {
+        AddFloat_1 t = new AddFloat_1();
+        assertEquals(Float.POSITIVE_INFINITY, t.run(Float.POSITIVE_INFINITY,
+                -2.7f));
+    }
+
+    /**
+     * @title Arguments = +0, -0f
+     */
+    public void testB5() {
+        AddFloat_1 t = new AddFloat_1();
+        assertEquals(+0f, t.run(+0f, -0f));
+    }
+
+    /**
+     * @title Arguments = -0f, -0f
+     */
+    public void testB6() {
+        AddFloat_1 t = new AddFloat_1();
+        assertEquals(-0f, t.run(-0f, -0f));
+    }
+
+    /**
+     * @title Arguments = -2.7f, 2.7f
+     */
+    public void testB7() {
+        AddFloat_1 t = new AddFloat_1();
+        assertEquals(+0f, t.run(-2.7f, 2.7f));
+    }
+
+    /**
+     * @title Arguments = Float.MAX_VALUE, Float.MAX_VALUE
+     */
+    public void testB8() {
+        AddFloat_1 t = new AddFloat_1();
+        assertEquals(Float.POSITIVE_INFINITY, t.run(Float.MAX_VALUE,
+                Float.MAX_VALUE));
+    }
+
+    /**
+     * @title Arguments = Float.MIN_VALUE, -1.4E-45f
+     */
+    public void testB9() {
+        AddFloat_1 t = new AddFloat_1();
+        assertEquals(0f, t.run(Float.MIN_VALUE, -1.4E-45f));
+    }
+}
diff --git a/tests/vm/src/android/vm/cts/opcodes/add_float/AddFloat_1.java b/tests/vm/src/android/vm/cts/opcodes/add_float/AddFloat_1.java
new file mode 100644
index 0000000..aff5beb
--- /dev/null
+++ b/tests/vm/src/android/vm/cts/opcodes/add_float/AddFloat_1.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.vm.cts.opcodes.add_float;
+
+public class AddFloat_1 {
+
+    public float run(float a, float b) {
+        return a + b;
+    }
+}
diff --git a/tests/vm/src/android/vm/cts/opcodes/add_float/AddFloat_5.java b/tests/vm/src/android/vm/cts/opcodes/add_float/AddFloat_5.java
new file mode 100644
index 0000000..2eba052
--- /dev/null
+++ b/tests/vm/src/android/vm/cts/opcodes/add_float/AddFloat_5.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.vm.cts.opcodes.add_float;
+
+public class AddFloat_5 {
+
+    public float run(int a, float b) {
+        return 0;
+    }
+}
diff --git a/tests/vm/src/android/vm/cts/opcodes/add_float_2addr/AddFloat2AddrTest.java b/tests/vm/src/android/vm/cts/opcodes/add_float_2addr/AddFloat2AddrTest.java
new file mode 100644
index 0000000..177e564
--- /dev/null
+++ b/tests/vm/src/android/vm/cts/opcodes/add_float_2addr/AddFloat2AddrTest.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.vm.cts.opcodes.add_float_2addr;
+
+import junit.framework.TestCase;
+
+public class AddFloat2AddrTest extends TestCase {
+    /**
+     * @title Arguments = 2.7f, 3.14f
+     */
+    public void testN1() {
+        AddFloat2Addr_1 t = new AddFloat2Addr_1();
+        assertEquals(5.84f, t.run(2.7f, 3.14f));
+    }
+
+    /**
+     * @title Arguments = 0, -3.14f
+     */
+    public void testN2() {
+        AddFloat2Addr_1 t = new AddFloat2Addr_1();
+        assertEquals(-3.14f, t.run(0, -3.14f));
+    }
+
+    /**
+     * @title Arguments = -3.14f, -2.7f
+     */
+    public void testN3() {
+        AddFloat2Addr_1 t = new AddFloat2Addr_1();
+        assertEquals(-5.84f, t.run(-3.14f, -2.7f));
+    }
+
+    /**
+     * @title Arguments = Float.MAX_VALUE, Float.NaN
+     */
+    public void testB1() {
+        AddFloat2Addr_1 t = new AddFloat2Addr_1();
+        assertEquals(Float.POSITIVE_INFINITY, t.run(3.3028235E38f, 0.11E38f));
+    }
+
+    /**
+     * @title Arguments = Float.POSITIVE_INFINITY,
+     * Float.NEGATIVE_INFINITY
+     */
+    public void testB2() {
+        AddFloat2Addr_1 t = new AddFloat2Addr_1();
+        assertTrue(Float.isNaN(t.run(Float.POSITIVE_INFINITY,
+                Float.NEGATIVE_INFINITY)));
+    }
+
+    /**
+     * @title Arguments = Float.POSITIVE_INFINITY,
+     * Float.POSITIVE_INFINITY
+     */
+    public void testB3() {
+        AddFloat2Addr_1 t = new AddFloat2Addr_1();
+        assertEquals(Float.POSITIVE_INFINITY, t.run(Float.POSITIVE_INFINITY,
+                Float.POSITIVE_INFINITY));
+    }
+
+    /**
+     * @title Arguments = Float.POSITIVE_INFINITY, -2.7f
+     */
+    public void testB4() {
+        AddFloat2Addr_1 t = new AddFloat2Addr_1();
+        assertEquals(Float.POSITIVE_INFINITY, t.run(Float.POSITIVE_INFINITY,
+                -2.7f));
+    }
+
+    /**
+     * @title Arguments = +0, -0f
+     */
+    public void testB5() {
+        AddFloat2Addr_1 t = new AddFloat2Addr_1();
+        assertEquals(+0f, t.run(+0f, -0f));
+    }
+
+    /**
+     * @title Arguments = -0f, -0f
+     */
+    public void testB6() {
+        AddFloat2Addr_1 t = new AddFloat2Addr_1();
+        assertEquals(-0f, t.run(-0f, -0f));
+    }
+
+    /**
+     * @title Arguments = -2.7f, 2.7f
+     */
+    public void testB7() {
+        AddFloat2Addr_1 t = new AddFloat2Addr_1();
+        assertEquals(+0f, t.run(-2.7f, 2.7f));
+    }
+
+    /**
+     * @title Arguments = Float.MAX_VALUE, Float.MAX_VALUE
+     */
+    public void testB8() {
+        AddFloat2Addr_1 t = new AddFloat2Addr_1();
+        assertEquals(Float.POSITIVE_INFINITY, t.run(Float.MAX_VALUE,
+                Float.MAX_VALUE));
+    }
+
+    /**
+     * @title Arguments = Float.MIN_VALUE, -1.4E-45f
+     */
+    public void testB9() {
+        AddFloat2Addr_1 t = new AddFloat2Addr_1();
+        assertEquals(0f, t.run(Float.MIN_VALUE, -1.4E-45f));
+    }
+
+    
+}
diff --git a/tests/vm/src/android/vm/cts/opcodes/add_float_2addr/AddFloat2Addr_1.java b/tests/vm/src/android/vm/cts/opcodes/add_float_2addr/AddFloat2Addr_1.java
new file mode 100644
index 0000000..cabd4f9
--- /dev/null
+++ b/tests/vm/src/android/vm/cts/opcodes/add_float_2addr/AddFloat2Addr_1.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.vm.cts.opcodes.add_float_2addr;
+
+public class AddFloat2Addr_1 {
+
+    public float run(float a, float b) {
+        return a + b;
+    }
+}
diff --git a/tests/vm/src/android/vm/cts/opcodes/add_float_2addr/AddFloat2Addr_5.java b/tests/vm/src/android/vm/cts/opcodes/add_float_2addr/AddFloat2Addr_5.java
new file mode 100644
index 0000000..7fdd723
--- /dev/null
+++ b/tests/vm/src/android/vm/cts/opcodes/add_float_2addr/AddFloat2Addr_5.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.vm.cts.opcodes.add_float_2addr;
+
+public class AddFloat2Addr_5 {
+
+    public float run(int a, float b) {
+        return 0;
+    }
+}
diff --git a/tests/vm/src/android/vm/cts/opcodes/add_int/AddIntTest.java b/tests/vm/src/android/vm/cts/opcodes/add_int/AddIntTest.java
new file mode 100644
index 0000000..7e67da6
--- /dev/null
+++ b/tests/vm/src/android/vm/cts/opcodes/add_int/AddIntTest.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.vm.cts.opcodes.add_int;
+
+import junit.framework.TestCase;
+
+public class AddIntTest extends TestCase {
+    /**
+     * @title Arguments = 8, 4
+     */
+    public void testN1() {
+        AddInt_1 t = new AddInt_1();
+        assertEquals(12, t.run(8, 4));
+    }
+
+    /**
+     * @title Arguments = 0, 255
+     */
+    public void testN2() {
+        AddInt_1 t = new AddInt_1();
+        assertEquals(255, t.run(0, 255));
+    }
+
+    /**
+     * @title Arguments = 0, -65536
+     */
+    public void testN3() {
+        AddInt_1 t = new AddInt_1();
+        assertEquals(-65536, t.run(0, -65536));
+    }
+
+    /**
+     * @title Arguments = 0, -2147483647
+     */
+    public void testN4() {
+        AddInt_1 t = new AddInt_1();
+        assertEquals(-2147483647, t.run(0, -2147483647));
+    }
+
+    /**
+     * @title Arguments = 0x7ffffffe, 2
+     */
+    public void testN5() {
+        AddInt_1 t = new AddInt_1();
+        assertEquals(-2147483648, t.run(0x7ffffffe, 2));
+    }
+
+    /**
+     * @title Arguments = -1, 1
+     */
+    public void testN6() {
+        AddInt_1 t = new AddInt_1();
+        assertEquals(0, t.run(-1, 1));
+    }
+
+
+    /**
+     * @title Arguments = 0, Integer.MAX_VALUE
+     */
+    public void testB1() {
+        AddInt_1 t = new AddInt_1();
+        assertEquals(Integer.MAX_VALUE, t.run(0, Integer.MAX_VALUE));
+    }
+
+    /**
+     * @title Arguments = Integer.MAX_VALUE, Integer.MAX_VALUE
+     */
+    public void testB2() {
+        AddInt_1 t = new AddInt_1();
+        assertEquals(-2, t.run(Integer.MAX_VALUE, Integer.MAX_VALUE));
+    }
+
+    /**
+     * @title Arguments = Integer.MAX_VALUE, 1
+     */
+    public void testB3() {
+        AddInt_1 t = new AddInt_1();
+        assertEquals(Integer.MIN_VALUE, t.run(Integer.MAX_VALUE, 1));
+    }
+
+    /**
+     * @title Arguments = Integer.MIN_VALUE, 1
+     */
+    public void testB4() {
+        AddInt_1 t = new AddInt_1();
+        assertEquals(-2147483647, t.run(Integer.MIN_VALUE, 1));
+    }
+
+    /**
+     * @title Arguments = 0, 0
+     */
+    public void testB5() {
+        AddInt_1 t = new AddInt_1();
+        assertEquals(0, t.run(0, 0));
+    }
+
+    /**
+     * @title Arguments = Integer.MIN_VALUE, Integer.MIN_VALUE
+     */
+    public void testB6() {
+        AddInt_1 t = new AddInt_1();
+        assertEquals(0, t.run(Integer.MIN_VALUE, Integer.MIN_VALUE));
+    }
+
+}
diff --git a/tests/vm/src/android/vm/cts/opcodes/add_int/AddInt_1.java b/tests/vm/src/android/vm/cts/opcodes/add_int/AddInt_1.java
new file mode 100644
index 0000000..825821d
--- /dev/null
+++ b/tests/vm/src/android/vm/cts/opcodes/add_int/AddInt_1.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.vm.cts.opcodes.add_int;
+
+public class AddInt_1 {
+
+    public int run(int a, int b) {
+        return a + b;
+    }
+}
diff --git a/tests/vm/src/android/vm/cts/opcodes/add_int/AddInt_5.java b/tests/vm/src/android/vm/cts/opcodes/add_int/AddInt_5.java
new file mode 100644
index 0000000..c17caaa
--- /dev/null
+++ b/tests/vm/src/android/vm/cts/opcodes/add_int/AddInt_5.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.vm.cts.opcodes.add_int;
+
+public class AddInt_5 {
+
+    public int run(int a, float b) {
+        return 0;
+    }
+}
diff --git a/tests/vm/src/android/vm/cts/opcodes/add_int_2addr/AddInt2AddrTest.java b/tests/vm/src/android/vm/cts/opcodes/add_int_2addr/AddInt2AddrTest.java
new file mode 100644
index 0000000..b2c4eb3
--- /dev/null
+++ b/tests/vm/src/android/vm/cts/opcodes/add_int_2addr/AddInt2AddrTest.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.vm.cts.opcodes.add_int_2addr;
+
+import junit.framework.TestCase;
+
+public class AddInt2AddrTest extends TestCase {
+    /**
+     * @title Arguments = 8, 4
+     */
+    public void testN1() {
+        AddInt2Addr_1 t = new AddInt2Addr_1();
+        assertEquals(12, t.run(8, 4));
+    }
+
+    /**
+     * @title Arguments = 0, 255
+     */
+    public void testN2() {
+        AddInt2Addr_1 t = new AddInt2Addr_1();
+        assertEquals(255, t.run(0, 255));
+    }
+
+    /**
+     * @title Arguments = 0, -65536
+     */
+    public void testN3() {
+        AddInt2Addr_1 t = new AddInt2Addr_1();
+        assertEquals(-65536, t.run(0, -65536));
+    }
+
+    /**
+     * @title Arguments = 0, -2147483647
+     */
+    public void testN4() {
+        AddInt2Addr_1 t = new AddInt2Addr_1();
+        assertEquals(-2147483647, t.run(0, -2147483647));
+    }
+
+    /**
+     * @title Arguments = 0x7ffffffe, 2
+     */
+    public void testN5() {
+        AddInt2Addr_1 t = new AddInt2Addr_1();
+        assertEquals(-2147483648, t.run(0x7ffffffe, 2));
+    }
+
+    /**
+     * @title Arguments = -1, 1
+     */
+    public void testN6() {
+        AddInt2Addr_1 t = new AddInt2Addr_1();
+        assertEquals(0, t.run(-1, 1));
+    }
+
+    /**
+     * @title Arguments = 0, Integer.MAX_VALUE
+     */
+    public void testB1() {
+        AddInt2Addr_1 t = new AddInt2Addr_1();
+        assertEquals(Integer.MAX_VALUE, t.run(0, Integer.MAX_VALUE));
+    }
+
+    /**
+     * @title Arguments = Integer.MAX_VALUE, Integer.MAX_VALUE
+     */
+    public void testB2() {
+        AddInt2Addr_1 t = new AddInt2Addr_1();
+        assertEquals(-2, t.run(Integer.MAX_VALUE, Integer.MAX_VALUE));
+    }
+
+    /**
+     * @title Arguments = Integer.MAX_VALUE, 1
+     */
+    public void testB3() {
+        AddInt2Addr_1 t = new AddInt2Addr_1();
+        assertEquals(Integer.MIN_VALUE, t.run(Integer.MAX_VALUE, 1));
+    }
+
+    /**
+     * @title Arguments = Integer.MIN_VALUE, 1
+     */
+    public void testB4() {
+        AddInt2Addr_1 t = new AddInt2Addr_1();
+        assertEquals(-2147483647, t.run(Integer.MIN_VALUE, 1));
+    }
+
+    /**
+     * @title Arguments = 0, 0
+     */
+    public void testB5() {
+        AddInt2Addr_1 t = new AddInt2Addr_1();
+        assertEquals(0, t.run(0, 0));
+    }
+
+    /**
+     * @title Arguments = Integer.MIN_VALUE, Integer.MIN_VALUE
+     */
+    public void testB6() {
+        AddInt2Addr_1 t = new AddInt2Addr_1();
+        assertEquals(0, t.run(Integer.MIN_VALUE, Integer.MIN_VALUE));
+    }
+
+}
diff --git a/tests/vm/src/android/vm/cts/opcodes/add_int_2addr/AddInt2Addr_1.java b/tests/vm/src/android/vm/cts/opcodes/add_int_2addr/AddInt2Addr_1.java
new file mode 100644
index 0000000..ec0757b
--- /dev/null
+++ b/tests/vm/src/android/vm/cts/opcodes/add_int_2addr/AddInt2Addr_1.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.vm.cts.opcodes.add_int_2addr;
+
+public class AddInt2Addr_1 {
+
+    public int run(int a, int b) {
+        return a+b;
+    }
+}
diff --git a/tests/vm/src/android/vm/cts/opcodes/add_int_2addr/AddInt2Addr_5.java b/tests/vm/src/android/vm/cts/opcodes/add_int_2addr/AddInt2Addr_5.java
new file mode 100644
index 0000000..8b78444
--- /dev/null
+++ b/tests/vm/src/android/vm/cts/opcodes/add_int_2addr/AddInt2Addr_5.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.vm.cts.opcodes.add_int_2addr;
+
+public class AddInt2Addr_5 {
+
+    public int run(int a, float b) {
+        return 0;
+    }
+}
diff --git a/tests/vm/src/android/vm/cts/opcodes/add_int_lit16/AddIntLit16Test.java b/tests/vm/src/android/vm/cts/opcodes/add_int_lit16/AddIntLit16Test.java
new file mode 100644
index 0000000..cc378df
--- /dev/null
+++ b/tests/vm/src/android/vm/cts/opcodes/add_int_lit16/AddIntLit16Test.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.vm.cts.opcodes.add_int_lit16;
+
+import junit.framework.TestCase;
+
+public class AddIntLit16Test extends TestCase {
+    /**
+     * @title Arguments = 8 + 4
+     */
+    public void testN1() {
+        AddIntLit16_1 t = new AddIntLit16_1();
+        assertEquals(12, t.run());
+    }
+
+    /**
+     * @title Arguments = 0 + 255
+     */
+    public void testN2() {
+        AddIntLit16_2 t = new AddIntLit16_2();
+        assertEquals(255, t.run());
+    }
+
+    /**
+     * @title Arguments = 0 + (-32768)
+     */
+    public void testN3() {
+        AddIntLit16_3 t = new AddIntLit16_3();
+        assertEquals(-32768, t.run());
+    }
+
+    /**
+     * @title Arguments = (-2147483647) + 0
+     */
+    public void testN4() {
+        AddIntLit16_4 t = new AddIntLit16_4();
+        assertEquals(-2147483647, t.run());
+    }
+
+    /**
+     * @title Arguments = 0x7ffffffe + 2
+     */
+    public void testN5() {
+        AddIntLit16_5 t = new AddIntLit16_5();
+        assertEquals(-2147483648, t.run());
+    }
+
+    /**
+     * @title Arguments = -1 + 1
+     */
+    public void testN6() {
+        AddIntLit16_6 t = new AddIntLit16_6();
+        assertEquals(0, t.run());
+    }
+
+    /**
+     * @title Arguments = 0 + Short.MAX_VALUE
+     */
+    public void testB1() {
+        AddIntLit16_7 t = new AddIntLit16_7();
+        assertEquals(Short.MAX_VALUE, t.run());
+    }
+
+    /**
+     * @title Arguments = Integer.MAX_VALUE + Short.MAX_VALUE
+     */
+    public void testB2() {
+        AddIntLit16_8 t = new AddIntLit16_8();
+        assertEquals(-2147450882, t.run());
+    }
+
+    /**
+     * @title Arguments = Integer.MAX_VALUE + 1
+     */
+    public void testB3() {
+        AddIntLit16_9 t = new AddIntLit16_9();
+        assertEquals(Integer.MIN_VALUE, t.run());
+    }
+
+    /**
+     * @title Arguments = Integer.MIN_VALUE + 1
+     */
+    public void testB4() {
+        AddIntLit16_10 t = new AddIntLit16_10();
+        assertEquals(-2147483647, t.run());
+    }
+
+    /**
+     * @title Arguments = 0 + 0
+     */
+    public void testB5() {
+        AddIntLit16_11 t = new AddIntLit16_11();
+        assertEquals(0, t.run());
+    }
+
+    /**
+     * @title Arguments = Short.MIN_VALUE + Short.MIN_VALUE
+     */
+    public void testB6() {
+        AddIntLit16_12 t = new AddIntLit16_12();
+        assertEquals(-65536, t.run());
+    }
+    
+}
diff --git a/tests/vm/src/android/vm/cts/opcodes/add_int_lit16/AddIntLit16_1.java b/tests/vm/src/android/vm/cts/opcodes/add_int_lit16/AddIntLit16_1.java
new file mode 100644
index 0000000..95313ee
--- /dev/null
+++ b/tests/vm/src/android/vm/cts/opcodes/add_int_lit16/AddIntLit16_1.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.vm.cts.opcodes.add_int_lit16;
+
+public class AddIntLit16_1 {
+
+    public int run() {
+        return 8 + 4;
+    }
+}
diff --git a/tests/vm/src/android/vm/cts/opcodes/add_int_lit16/AddIntLit16_10.java b/tests/vm/src/android/vm/cts/opcodes/add_int_lit16/AddIntLit16_10.java
new file mode 100644
index 0000000..e5fa9fa
--- /dev/null
+++ b/tests/vm/src/android/vm/cts/opcodes/add_int_lit16/AddIntLit16_10.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.vm.cts.opcodes.add_int_lit16;
+
+public class AddIntLit16_10 {
+
+    public int run() {
+        return Integer.MIN_VALUE + 1;
+    }
+}
diff --git a/tests/vm/src/android/vm/cts/opcodes/add_int_lit16/AddIntLit16_11.java b/tests/vm/src/android/vm/cts/opcodes/add_int_lit16/AddIntLit16_11.java
new file mode 100644
index 0000000..375cfff
--- /dev/null
+++ b/tests/vm/src/android/vm/cts/opcodes/add_int_lit16/AddIntLit16_11.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.vm.cts.opcodes.add_int_lit16;
+
+public class AddIntLit16_11 {
+
+    public int run() {
+        return 0 + 0;
+    }
+}
diff --git a/tests/vm/src/android/vm/cts/opcodes/add_int_lit16/AddIntLit16_12.java b/tests/vm/src/android/vm/cts/opcodes/add_int_lit16/AddIntLit16_12.java
new file mode 100644
index 0000000..3c30be0
--- /dev/null
+++ b/tests/vm/src/android/vm/cts/opcodes/add_int_lit16/AddIntLit16_12.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.vm.cts.opcodes.add_int_lit16;
+
+public class AddIntLit16_12 {
+
+    public int run() {
+        return Short.MIN_VALUE + Short.MIN_VALUE;
+    }
+}
diff --git a/tests/vm/src/android/vm/cts/opcodes/add_int_lit16/AddIntLit16_16.java b/tests/vm/src/android/vm/cts/opcodes/add_int_lit16/AddIntLit16_16.java
new file mode 100644
index 0000000..5f3d6f9
--- /dev/null
+++ b/tests/vm/src/android/vm/cts/opcodes/add_int_lit16/AddIntLit16_16.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.vm.cts.opcodes.add_int_lit16;
+
+public class AddIntLit16_16 {
+
+    public int run(float f) {
+        return 0;
+    }
+}
diff --git a/tests/vm/src/android/vm/cts/opcodes/add_int_lit16/AddIntLit16_2.java b/tests/vm/src/android/vm/cts/opcodes/add_int_lit16/AddIntLit16_2.java
new file mode 100644
index 0000000..69c6c8d
--- /dev/null
+++ b/tests/vm/src/android/vm/cts/opcodes/add_int_lit16/AddIntLit16_2.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.vm.cts.opcodes.add_int_lit16;
+
+public class AddIntLit16_2 {
+
+    public int run() {
+        return 0 + 255;
+    }
+}
diff --git a/tests/vm/src/android/vm/cts/opcodes/add_int_lit16/AddIntLit16_3.java b/tests/vm/src/android/vm/cts/opcodes/add_int_lit16/AddIntLit16_3.java
new file mode 100644
index 0000000..51e84ba
--- /dev/null
+++ b/tests/vm/src/android/vm/cts/opcodes/add_int_lit16/AddIntLit16_3.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.vm.cts.opcodes.add_int_lit16;
+
+public class AddIntLit16_3 {
+
+    public int run() {
+        return 0 + (-32768);
+    }
+}
diff --git a/tests/vm/src/android/vm/cts/opcodes/add_int_lit16/AddIntLit16_4.java b/tests/vm/src/android/vm/cts/opcodes/add_int_lit16/AddIntLit16_4.java
new file mode 100644
index 0000000..0fa1146
--- /dev/null
+++ b/tests/vm/src/android/vm/cts/opcodes/add_int_lit16/AddIntLit16_4.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.vm.cts.opcodes.add_int_lit16;
+
+public class AddIntLit16_4 {
+
+    public int run() {
+        return (-2147483647) + 0;
+    }
+}
diff --git a/tests/vm/src/android/vm/cts/opcodes/add_int_lit16/AddIntLit16_5.java b/tests/vm/src/android/vm/cts/opcodes/add_int_lit16/AddIntLit16_5.java
new file mode 100644
index 0000000..2080b8b
--- /dev/null
+++ b/tests/vm/src/android/vm/cts/opcodes/add_int_lit16/AddIntLit16_5.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.vm.cts.opcodes.add_int_lit16;
+
+public class AddIntLit16_5 {
+
+    public int run() {
+        return 0x7ffffffe + 2;
+    }
+}
diff --git a/tests/vm/src/android/vm/cts/opcodes/add_int_lit16/AddIntLit16_6.java b/tests/vm/src/android/vm/cts/opcodes/add_int_lit16/AddIntLit16_6.java
new file mode 100644
index 0000000..4db27b0
--- /dev/null
+++ b/tests/vm/src/android/vm/cts/opcodes/add_int_lit16/AddIntLit16_6.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.vm.cts.opcodes.add_int_lit16;
+
+public class AddIntLit16_6 {
+
+    public int run() {
+        return -1 + 1;
+    }
+}
diff --git a/tests/vm/src/android/vm/cts/opcodes/add_int_lit16/AddIntLit16_7.java b/tests/vm/src/android/vm/cts/opcodes/add_int_lit16/AddIntLit16_7.java
new file mode 100644
index 0000000..b74ed5d
--- /dev/null
+++ b/tests/vm/src/android/vm/cts/opcodes/add_int_lit16/AddIntLit16_7.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.vm.cts.opcodes.add_int_lit16;
+
+public class AddIntLit16_7 {
+
+    public int run() {
+        return 0 + Short.MAX_VALUE;
+    }
+}
diff --git a/tests/vm/src/android/vm/cts/opcodes/add_int_lit16/AddIntLit16_8.java b/tests/vm/src/android/vm/cts/opcodes/add_int_lit16/AddIntLit16_8.java
new file mode 100644
index 0000000..c4900e0
--- /dev/null
+++ b/tests/vm/src/android/vm/cts/opcodes/add_int_lit16/AddIntLit16_8.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.vm.cts.opcodes.add_int_lit16;
+
+public class AddIntLit16_8 {
+
+    public int run() {
+        return Integer.MAX_VALUE + Short.MAX_VALUE;
+    }
+}
diff --git a/tests/vm/src/android/vm/cts/opcodes/add_int_lit16/AddIntLit16_9.java b/tests/vm/src/android/vm/cts/opcodes/add_int_lit16/AddIntLit16_9.java
new file mode 100644
index 0000000..3368cf9
--- /dev/null
+++ b/tests/vm/src/android/vm/cts/opcodes/add_int_lit16/AddIntLit16_9.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.vm.cts.opcodes.add_int_lit16;
+
+public class AddIntLit16_9 {
+
+    public int run() {
+        return Integer.MAX_VALUE + 1;
+    }
+}
diff --git a/tests/vm/src/android/vm/cts/opcodes/add_int_lit8/AddIntLit8.java b/tests/vm/src/android/vm/cts/opcodes/add_int_lit8/AddIntLit8.java
new file mode 100644
index 0000000..fe3710b
--- /dev/null
+++ b/tests/vm/src/android/vm/cts/opcodes/add_int_lit8/AddIntLit8.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.vm.cts.opcodes.add_int_lit8;
+
+import junit.framework.TestCase;
+
+public class AddIntLit8 extends TestCase {
+    /**
+     * @title Arguments = 8 + 4
+     */
+    public void testN1() {
+        AddIntLit8_1 t = new AddIntLit8_1();
+        assertEquals(12, t.run());
+    }
+
+    /**
+     * @title Arguments = Byte.MIN_VALUE + Byte.MAX_VALUE
+     */
+    public void testN2() {
+        AddIntLit8_2 t = new AddIntLit8_2();
+        assertEquals(-1, t.run());
+    }
+
+    /**
+     * @title Arguments = 0 + (-128)
+     */
+    public void testN3() {
+        AddIntLit8_3 t = new AddIntLit8_3();
+        assertEquals(-128, t.run());
+    }
+
+    /**
+     * @title Arguments = (-2147483647) + 0
+     */
+    public void testN4() {
+        AddIntLit8_4 t = new AddIntLit8_4();
+        assertEquals(-2147483647, t.run());
+    }
+
+    /**
+     * @title Arguments = 0x7ffffffe + 2
+     */
+    public void testN5() {
+        AddIntLit8_5 t = new AddIntLit8_5();
+        assertEquals(-2147483648, t.run());
+    }
+
+    /**
+     * @title Arguments = -1 + 1
+     */
+    public void testN6() {
+        AddIntLit8_6 t = new AddIntLit8_6();
+        assertEquals(0, t.run());
+    }
+
+    /**
+     * @title Arguments = 0 + Byte.MAX_VALUE
+     */
+    public void testB1() {
+        AddIntLit8_7 t = new AddIntLit8_7();
+        assertEquals(Byte.MAX_VALUE, t.run());
+    }
+
+    /**
+     * @title Arguments = Integer.MAX_VALUE + Byte.MAX_VALUE
+     */
+    public void testB2() {
+        AddIntLit8_8 t = new AddIntLit8_8();
+        assertEquals(-2147483522, t.run());
+    }
+
+    /**
+     * @title Arguments = Integer.MAX_VALUE + 1
+     */
+    public void testB3() {
+        AddIntLit8_9 t = new AddIntLit8_9();
+        assertEquals(Integer.MIN_VALUE, t.run());
+    }
+
+    /**
+     * @title Arguments = Integer.MIN_VALUE + 1
+     */
+    public void testB4() {
+        AddIntLit8_10 t = new AddIntLit8_10();
+        assertEquals(-2147483647, t.run());
+    }
+
+    /**
+     * @title Arguments = 0 + 0
+     */
+    public void testB5() {
+        AddIntLit8_11 t = new AddIntLit8_11();
+        assertEquals(0, t.run());
+    }
+
+    /**
+     * @title Arguments = Short.MIN_VALUE + Byte.MIN_VALUE
+     */
+    public void testB6() {
+        AddIntLit8_12 t = new AddIntLit8_12();
+        assertEquals(-32896, t.run());
+    }
+
+}
diff --git a/tests/vm/src/android/vm/cts/opcodes/add_int_lit8/AddIntLit8_1.java b/tests/vm/src/android/vm/cts/opcodes/add_int_lit8/AddIntLit8_1.java
new file mode 100644
index 0000000..2017b31
--- /dev/null
+++ b/tests/vm/src/android/vm/cts/opcodes/add_int_lit8/AddIntLit8_1.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.vm.cts.opcodes.add_int_lit8;
+
+public class AddIntLit8_1 {
+
+    public int run() {
+        return 8 + 4;
+    }
+}
diff --git a/tests/vm/src/android/vm/cts/opcodes/add_int_lit8/AddIntLit8_10.java b/tests/vm/src/android/vm/cts/opcodes/add_int_lit8/AddIntLit8_10.java
new file mode 100644
index 0000000..88fae83
--- /dev/null
+++ b/tests/vm/src/android/vm/cts/opcodes/add_int_lit8/AddIntLit8_10.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.vm.cts.opcodes.add_int_lit8;
+
+public class AddIntLit8_10 {
+
+    public int run() {
+        return Integer.MIN_VALUE + 1;
+    }
+}
diff --git a/tests/vm/src/android/vm/cts/opcodes/add_int_lit8/AddIntLit8_11.java b/tests/vm/src/android/vm/cts/opcodes/add_int_lit8/AddIntLit8_11.java
new file mode 100644
index 0000000..5c29a91
--- /dev/null
+++ b/tests/vm/src/android/vm/cts/opcodes/add_int_lit8/AddIntLit8_11.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.vm.cts.opcodes.add_int_lit8;
+
+public class AddIntLit8_11 {
+
+    public int run() {
+        return 0 + 0;
+    }
+}
diff --git a/tests/vm/src/android/vm/cts/opcodes/add_int_lit8/AddIntLit8_12.java b/tests/vm/src/android/vm/cts/opcodes/add_int_lit8/AddIntLit8_12.java
new file mode 100644
index 0000000..9fa0a8d
--- /dev/null
+++ b/tests/vm/src/android/vm/cts/opcodes/add_int_lit8/AddIntLit8_12.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.vm.cts.opcodes.add_int_lit8;
+
+public class AddIntLit8_12 {
+
+    public int run() {
+        return Short.MIN_VALUE + Byte.MIN_VALUE;
+    }
+}
diff --git a/tests/vm/src/android/vm/cts/opcodes/add_int_lit8/AddIntLit8_16.java b/tests/vm/src/android/vm/cts/opcodes/add_int_lit8/AddIntLit8_16.java
new file mode 100644
index 0000000..f8338e8
--- /dev/null
+++ b/tests/vm/src/android/vm/cts/opcodes/add_int_lit8/AddIntLit8_16.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.vm.cts.opcodes.add_int_lit8;
+
+public class AddIntLit8_16 {
+
+    public int run(float f) {
+        return 0;
+    }
+}
diff --git a/tests/vm/src/android/vm/cts/opcodes/add_int_lit8/AddIntLit8_2.java b/tests/vm/src/android/vm/cts/opcodes/add_int_lit8/AddIntLit8_2.java
new file mode 100644
index 0000000..eaa4f38
--- /dev/null
+++ b/tests/vm/src/android/vm/cts/opcodes/add_int_lit8/AddIntLit8_2.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.vm.cts.opcodes.add_int_lit8;
+
+public class AddIntLit8_2 {
+
+    public int run() {
+        return Byte.MIN_VALUE + Byte.MAX_VALUE;
+    }
+}
diff --git a/tests/vm/src/android/vm/cts/opcodes/add_int_lit8/AddIntLit8_3.java b/tests/vm/src/android/vm/cts/opcodes/add_int_lit8/AddIntLit8_3.java
new file mode 100644
index 0000000..e7b0534
--- /dev/null
+++ b/tests/vm/src/android/vm/cts/opcodes/add_int_lit8/AddIntLit8_3.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.vm.cts.opcodes.add_int_lit8;
+
+public class AddIntLit8_3 {
+
+    public int run() {
+        return 0 + (-128);
+    }
+}
diff --git a/tests/vm/src/android/vm/cts/opcodes/add_int_lit8/AddIntLit8_4.java b/tests/vm/src/android/vm/cts/opcodes/add_int_lit8/AddIntLit8_4.java
new file mode 100644
index 0000000..7a22091
--- /dev/null
+++ b/tests/vm/src/android/vm/cts/opcodes/add_int_lit8/AddIntLit8_4.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.vm.cts.opcodes.add_int_lit8;
+
+public class AddIntLit8_4 {
+
+    public int run() {
+        return (-2147483647) + 0;
+    }
+}
diff --git a/tests/vm/src/android/vm/cts/opcodes/add_int_lit8/AddIntLit8_5.java b/tests/vm/src/android/vm/cts/opcodes/add_int_lit8/AddIntLit8_5.java
new file mode 100644
index 0000000..bfbd8c5
--- /dev/null
+++ b/tests/vm/src/android/vm/cts/opcodes/add_int_lit8/AddIntLit8_5.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.vm.cts.opcodes.add_int_lit8;
+
+public class AddIntLit8_5 {
+
+    public int run() {
+        return 0x7ffffffe + 2;
+    }
+}
diff --git a/tests/vm/src/android/vm/cts/opcodes/add_int_lit8/AddIntLit8_6.java b/tests/vm/src/android/vm/cts/opcodes/add_int_lit8/AddIntLit8_6.java
new file mode 100644
index 0000000..7c14c37
--- /dev/null
+++ b/tests/vm/src/android/vm/cts/opcodes/add_int_lit8/AddIntLit8_6.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.vm.cts.opcodes.add_int_lit8;
+
+public class AddIntLit8_6 {
+
+    public int run() {
+        return -1 + 1;
+    }
+}
diff --git a/tests/vm/src/android/vm/cts/opcodes/add_int_lit8/AddIntLit8_7.java b/tests/vm/src/android/vm/cts/opcodes/add_int_lit8/AddIntLit8_7.java
new file mode 100644
index 0000000..d5347d0
--- /dev/null
+++ b/tests/vm/src/android/vm/cts/opcodes/add_int_lit8/AddIntLit8_7.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.vm.cts.opcodes.add_int_lit8;
+
+public class AddIntLit8_7 {
+
+    public int run() {
+        return 0 + Byte.MAX_VALUE;
+    }
+}
diff --git a/tests/vm/src/android/vm/cts/opcodes/add_int_lit8/AddIntLit8_8.java b/tests/vm/src/android/vm/cts/opcodes/add_int_lit8/AddIntLit8_8.java
new file mode 100644
index 0000000..c7a8a9b
--- /dev/null
+++ b/tests/vm/src/android/vm/cts/opcodes/add_int_lit8/AddIntLit8_8.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.vm.cts.opcodes.add_int_lit8;
+
+public class AddIntLit8_8 {
+
+    public int run() {
+        return Integer.MAX_VALUE + Byte.MAX_VALUE;
+    }
+}
diff --git a/tests/vm/src/android/vm/cts/opcodes/add_int_lit8/AddIntLit8_9.java b/tests/vm/src/android/vm/cts/opcodes/add_int_lit8/AddIntLit8_9.java
new file mode 100644
index 0000000..c246375
--- /dev/null
+++ b/tests/vm/src/android/vm/cts/opcodes/add_int_lit8/AddIntLit8_9.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.vm.cts.opcodes.add_int_lit8;
+
+public class AddIntLit8_9 {
+
+    public int run() {
+        return Integer.MAX_VALUE + 1;
+    }
+}
diff --git a/tests/vm/src/android/vm/cts/opcodes/add_long/AddLongTest.java b/tests/vm/src/android/vm/cts/opcodes/add_long/AddLongTest.java
new file mode 100644
index 0000000..27c4536
--- /dev/null
+++ b/tests/vm/src/android/vm/cts/opcodes/add_long/AddLongTest.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.vm.cts.opcodes.add_long;
+
+import junit.framework.TestCase;
+
+public class AddLongTest extends TestCase {
+    /**
+     * @title Arguments = 12345678l, 87654321l
+     */
+    public void testN1() {
+        AddLong_1 t = new AddLong_1();
+        assertEquals(99999999l, t.run(12345678l, 87654321l));
+    }
+
+    /**
+     * @title Arguments = 0l, 87654321l
+     */
+    public void testN2() {
+        AddLong_1 t = new AddLong_1();
+        assertEquals(87654321l, t.run(0l, 87654321l));
+    }
+
+    /**
+     * @title Arguments = -12345678l, 0l
+     */
+    public void testN3() {
+        AddLong_1 t = new AddLong_1();
+        assertEquals(-12345678l, t.run(-12345678l, 0l));
+    }
+
+    /**
+     * @title Arguments = 0 + Long.MAX_VALUE
+     */
+    public void testB1() {
+        AddLong_1 t = new AddLong_1();
+        assertEquals(9223372036854775807L, t.run(0l, Long.MAX_VALUE));
+    }
+
+    /**
+     * @title Arguments = 0 + Long.MIN_VALUE
+     */
+    public void testB2() {
+        AddLong_1 t = new AddLong_1();
+        assertEquals(-9223372036854775808L, t.run(0l, Long.MIN_VALUE));
+    }
+
+    /**
+     * @title Arguments = 0 + 0
+     */
+    public void testB3() {
+        AddLong_1 t = new AddLong_1();
+        assertEquals(0l, t.run(0l, 0l));
+    }
+
+    /**
+     * @title Arguments = Long.MAX_VALUE + Long.MAX_VALUE
+     */
+    public void testB4() {
+        AddLong_1 t = new AddLong_1();
+        assertEquals(-2, t.run(Long.MAX_VALUE, Long.MAX_VALUE));
+    }
+
+    /**
+     * @title Arguments = Long.MAX_VALUE + Long.MIN_VALUE
+     */
+    public void testB5() {
+        AddLong_1 t = new AddLong_1();
+        assertEquals(-1l, t.run(Long.MAX_VALUE, Long.MIN_VALUE));
+    }
+
+    /**
+     * @title Arguments = Long.MIN_VALUE + Long.MIN_VALUE
+     */
+    public void testB6() {
+        AddLong_1 t = new AddLong_1();
+        assertEquals(0l, t.run(Long.MIN_VALUE, Long.MIN_VALUE));
+    }
+
+    /**
+     * @title Arguments = Long.MIN_VALUE + 1
+     */
+    public void testB7() {
+        AddLong_1 t = new AddLong_1();
+        assertEquals(-9223372036854775807l, t.run(Long.MIN_VALUE, 1l));
+    }
+
+    /**
+     * @title Arguments = Long.MAX_VALUE + 1
+     */
+    public void testB8() {
+        AddLong_1 t = new AddLong_1();
+        assertEquals(-9223372036854775808l, t.run(Long.MAX_VALUE, 1l));
+    }
+
+}
diff --git a/tests/vm/src/android/vm/cts/opcodes/add_long/AddLong_1.java b/tests/vm/src/android/vm/cts/opcodes/add_long/AddLong_1.java
new file mode 100644
index 0000000..285e4df
--- /dev/null
+++ b/tests/vm/src/android/vm/cts/opcodes/add_long/AddLong_1.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.vm.cts.opcodes.add_long;
+
+public class AddLong_1 {
+
+    public long run(long a, long b) {
+        return a+b;
+    }
+}
diff --git a/tests/vm/src/android/vm/cts/opcodes/add_long/AddLong_6.java b/tests/vm/src/android/vm/cts/opcodes/add_long/AddLong_6.java
new file mode 100644
index 0000000..ff7195e
--- /dev/null
+++ b/tests/vm/src/android/vm/cts/opcodes/add_long/AddLong_6.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.vm.cts.opcodes.add_long;
+
+public class AddLong_6 {
+
+    public long run(long a, double b) {
+        return 0;
+    }
+}
diff --git a/tests/vm/src/android/vm/cts/opcodes/add_long_2addr/AddLong2AddrTest.java b/tests/vm/src/android/vm/cts/opcodes/add_long_2addr/AddLong2AddrTest.java
new file mode 100644
index 0000000..5e97757
--- /dev/null
+++ b/tests/vm/src/android/vm/cts/opcodes/add_long_2addr/AddLong2AddrTest.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.vm.cts.opcodes.add_long_2addr;
+
+import junit.framework.TestCase;
+
+public class AddLong2AddrTest extends TestCase {
+    /**
+     * @title Arguments = 12345678l, 87654321l
+     */
+    public void testN1() {
+        AddLong2Addr_1 t = new AddLong2Addr_1();
+        assertEquals(99999999l, t.run(12345678l, 87654321l));
+    }
+
+    /**
+     * @title Arguments = 0l, 87654321l
+     */
+    public void testN2() {
+        AddLong2Addr_1 t = new AddLong2Addr_1();
+        assertEquals(87654321l, t.run(0l, 87654321l));
+    }
+
+    /**
+     * @title Arguments = -12345678l, 0l
+     */
+    public void testN3() {
+        AddLong2Addr_1 t = new AddLong2Addr_1();
+        assertEquals(-12345678l, t.run(-12345678l, 0l));
+    }
+
+    /**
+     * @title Arguments = 0 + Long.MAX_VALUE
+     */
+    public void testB1() {
+        AddLong2Addr_1 t = new AddLong2Addr_1();
+        assertEquals(9223372036854775807L, t.run(0l, Long.MAX_VALUE));
+    }
+
+    /**
+     * @title Arguments = 0 + Long.MIN_VALUE
+     */
+    public void testB2() {
+        AddLong2Addr_1 t = new AddLong2Addr_1();
+        assertEquals(-9223372036854775808L, t.run(0l, Long.MIN_VALUE));
+    }
+
+    /**
+     * @title Arguments = 0 + 0
+     */
+    public void testB3() {
+        AddLong2Addr_1 t = new AddLong2Addr_1();
+        assertEquals(0l, t.run(0l, 0l));
+    }
+
+    /**
+     * @title Arguments = Long.MAX_VALUE + Long.MAX_VALUE
+     */
+    public void testB4() {
+        AddLong2Addr_1 t = new AddLong2Addr_1();
+        assertEquals(-2, t.run(Long.MAX_VALUE, Long.MAX_VALUE));
+    }
+
+    /**
+     * @title Arguments = Long.MAX_VALUE + Long.MIN_VALUE
+     */
+    public void testB5() {
+        AddLong2Addr_1 t = new AddLong2Addr_1();
+        assertEquals(-1l, t.run(Long.MAX_VALUE, Long.MIN_VALUE));
+    }
+
+    /**
+     * @title Arguments = Long.MIN_VALUE + Long.MIN_VALUE
+     */
+    public void testB6() {
+        AddLong2Addr_1 t = new AddLong2Addr_1();
+        assertEquals(0l, t.run(Long.MIN_VALUE, Long.MIN_VALUE));
+    }
+
+    /**
+     * @title Arguments = Long.MIN_VALUE + 1
+     */
+    public void testB7() {
+        AddLong2Addr_1 t = new AddLong2Addr_1();
+        assertEquals(-9223372036854775807l, t.run(Long.MIN_VALUE, 1l));
+    }
+
+    /**
+     * @title Arguments = Long.MAX_VALUE + 1
+     */
+    public void testB8() {
+        AddLong2Addr_1 t = new AddLong2Addr_1();
+        assertEquals(-9223372036854775808l, t.run(Long.MAX_VALUE, 1l));
+    }
+
+}
diff --git a/tests/vm/src/android/vm/cts/opcodes/add_long_2addr/AddLong2Addr_1.java b/tests/vm/src/android/vm/cts/opcodes/add_long_2addr/AddLong2Addr_1.java
new file mode 100644
index 0000000..777a356
--- /dev/null
+++ b/tests/vm/src/android/vm/cts/opcodes/add_long_2addr/AddLong2Addr_1.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.vm.cts.opcodes.add_long_2addr;
+
+public class AddLong2Addr_1 {
+
+    public long run(long a, long b) {
+        return a+b;
+    }
+}
diff --git a/tests/vm/src/android/vm/cts/opcodes/add_long_2addr/AddLong2Addr_6.java b/tests/vm/src/android/vm/cts/opcodes/add_long_2addr/AddLong2Addr_6.java
new file mode 100644
index 0000000..4c7dd18
--- /dev/null
+++ b/tests/vm/src/android/vm/cts/opcodes/add_long_2addr/AddLong2Addr_6.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.vm.cts.opcodes.add_long_2addr;
+
+public class AddLong2Addr_6 {
+
+    public long run(double a) {
+        return 0;
+    }
+}
diff --git a/tests/vr/Android.mk b/tests/vr/Android.mk
new file mode 100644
index 0000000..04644a0
--- /dev/null
+++ b/tests/vr/Android.mk
@@ -0,0 +1,39 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := CtsVrTestCases
+
+# Don't include this package in any target.
+LOCAL_MODULE_TAGS := optional
+
+# Include both the 32 and 64 bit versions
+LOCAL_MULTILIB := both
+
+# When built, explicitly put it in the data partition.
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_SDK_VERSION := current
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/vr/AndroidManifest.xml b/tests/vr/AndroidManifest.xml
new file mode 100644
index 0000000..877d846
--- /dev/null
+++ b/tests/vr/AndroidManifest.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.vr.cts"
+    android:versionCode="1"
+    android:versionName="1.0" >
+
+    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+    <uses-sdk android:minSdkVersion="14" />
+    <uses-feature android:glEsVersion="0x00020000"/>
+    <instrumentation
+        android:name="android.support.test.runner.AndroidJUnitRunner"
+        android:targetPackage="android.vr.cts" >
+        <meta-data android:name="listener"
+            android:value="com.android.cts.runner.CtsTestRunListener" />
+    </instrumentation>
+
+    <application
+        android:icon="@drawable/ic_launcher"
+        android:label="@string/app_name"
+        android:hardwareAccelerated="false" >
+
+         <activity
+            android:label="@string/app_name"
+            android:name="android.vr.cts.OpenGLESActivity">
+         </activity>
+         <activity android:name=".CtsActivity"
+                  android:label="CtsActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+            </intent-filter>
+        </activity>
+         <uses-library  android:name="android.test.runner" />
+    </application>
+
+</manifest>
diff --git a/tests/vr/AndroidTest.xml b/tests/vr/AndroidTest.xml
new file mode 100644
index 0000000..a687370
--- /dev/null
+++ b/tests/vr/AndroidTest.xml
@@ -0,0 +1,23 @@
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS VR test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsVrTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.vr.cts" />
+    </test>
+</configuration>
diff --git a/tests/vr/res/drawable-hdpi/ic_launcher.png b/tests/vr/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..8074c4c
--- /dev/null
+++ b/tests/vr/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/tests/vr/res/drawable-ldpi/ic_launcher.png b/tests/vr/res/drawable-ldpi/ic_launcher.png
new file mode 100644
index 0000000..1095584
--- /dev/null
+++ b/tests/vr/res/drawable-ldpi/ic_launcher.png
Binary files differ
diff --git a/tests/vr/res/drawable-mdpi/ic_launcher.png b/tests/vr/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..a07c69f
--- /dev/null
+++ b/tests/vr/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/tests/vr/res/layout/main.xml b/tests/vr/res/layout/main.xml
new file mode 100644
index 0000000..fc2dfc1
--- /dev/null
+++ b/tests/vr/res/layout/main.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:orientation="vertical" >
+
+</LinearLayout>
\ No newline at end of file
diff --git a/tests/vr/res/values/strings.xml b/tests/vr/res/values/strings.xml
new file mode 100644
index 0000000..e87ad4a
--- /dev/null
+++ b/tests/vr/res/values/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<resources>
+    <string name="app_name">CtsVrTestCases</string>
+
+</resources>
diff --git a/tests/vr/src/android/vr/cts/CtsActivity.java b/tests/vr/src/android/vr/cts/CtsActivity.java
new file mode 100644
index 0000000..33fff08
--- /dev/null
+++ b/tests/vr/src/android/vr/cts/CtsActivity.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.vr.cts;
+
+import android.app.Activity;
+
+public class CtsActivity extends Activity {
+
+}
diff --git a/tests/vr/src/android/vr/cts/OpenGLESActivity.java b/tests/vr/src/android/vr/cts/OpenGLESActivity.java
new file mode 100644
index 0000000..dc219dc
--- /dev/null
+++ b/tests/vr/src/android/vr/cts/OpenGLESActivity.java
@@ -0,0 +1,287 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.vr.cts;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.opengl.EGL14;
+import android.opengl.GLES20;
+import android.opengl.GLSurfaceView;
+import android.opengl.GLSurfaceView.Renderer;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.Window;
+import android.view.WindowManager;
+
+import java.lang.InterruptedException;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import javax.microedition.khronos.egl.EGL10;
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.egl.EGLContext;
+import javax.microedition.khronos.egl.EGLDisplay;
+import javax.microedition.khronos.egl.EGLSurface;
+
+public class OpenGLESActivity extends Activity {
+    private static final String TAG = "OpenGLESActivity";
+
+    public static final String EXTRA_VIEW_INDEX = "viewIndex";
+    public static final String EXTRA_PROTECTED = "protected";
+    public static final String EXTRA_PRIORITY = "priority";
+    public static final String EXTRA_LATCH_COUNT = "latchCount";
+
+
+    public static final int EGL_PROTECTED_CONTENT_EXT = 0x32C0;
+
+    // Context priority enums are not exposed in Java.
+    public static final int EGL_CONTEXT_PRIORITY_LEVEL_IMG = 0x3100;
+
+    OpenGLES20View mView;
+    Renderer mRenderer;
+    int mRendererType;
+    private CountDownLatch mLatch;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        Window window = getWindow();
+        window.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
+
+        int viewIndex = getIntent().getIntExtra(EXTRA_VIEW_INDEX, -1);
+        int protectedAttribute = getIntent().getIntExtra(EXTRA_PROTECTED, -1);
+        int priorityAttribute = getIntent().getIntExtra(EXTRA_PRIORITY, -1);
+        int latchCount = getIntent().getIntExtra(EXTRA_LATCH_COUNT, 1);
+        mLatch = new CountDownLatch(latchCount);
+        mView = new OpenGLES20View(this, viewIndex, protectedAttribute, priorityAttribute,
+            mLatch);
+
+        setContentView(mView);
+    }
+
+    public int glGetError() {
+        return ((RendererBasicTest)mRenderer).mError;
+    }
+
+    public static void checkEglError(String msg) {
+        boolean failed = false;
+        int error;
+        while ((error = EGL14.eglGetError()) != EGL14.EGL_SUCCESS) {
+            Log.e(TAG, msg + ": EGL error: 0x" + Integer.toHexString(error));
+            failed = true;
+        }
+        if (failed) {
+            throw new RuntimeException("EGL error encountered (EGL error: 0x" +
+                Integer.toHexString(error) + ")");
+        }
+    }
+
+    public void runOnGlThread(Runnable r) throws Throwable {
+        CountDownLatch fence = new CountDownLatch(1);
+        RunSignalAndCatch wrapper = new RunSignalAndCatch(r, fence);
+
+        mView.queueEvent(wrapper);
+        fence.await(5000, TimeUnit.MILLISECONDS);
+        if (wrapper.error != null) {
+            throw wrapper.error;
+        }
+    }
+
+    public static boolean contextHasAttributeWithValue(int attribute, int value) {
+        int[] values = new int[1];
+        EGL14.eglQueryContext(EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY),
+            EGL14.eglGetCurrentContext(), attribute, values, 0);
+        checkEglError("eglQueryContext");
+        return values[0] == value;
+    }
+
+    public static boolean surfaceHasAttributeWithValue(int attribute, int value) {
+        int[] values = new int[1];
+        EGL14.eglQuerySurface(EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY),
+            EGL14.eglGetCurrentSurface(EGL14.EGL_DRAW), attribute, values, 0);
+        checkEglError("eglQueryContext");
+        return values[0] == value;
+    }
+
+    public static void setSurfaceAttribute(int attribute, int value) {
+        int[] values = new int[1];
+        EGL14.eglSurfaceAttrib(EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY),
+            EGL14.eglGetCurrentSurface(EGL14.EGL_DRAW), attribute, value);
+        checkEglError("eglSurfaceAttrib");
+    }
+
+    public boolean waitForFrameDrawn() {
+        boolean result = false;
+        try {
+            result = mLatch.await(1L, TimeUnit.SECONDS);
+        } catch (InterruptedException e) {
+            // just return false
+        }
+        return result;
+    }
+
+    public boolean supportsVrHighPerformance() {
+        PackageManager pm = getPackageManager();
+        return pm.hasSystemFeature(PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE);
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+        if (mView != null) {
+            mView.onPause();
+        }
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        if (mView != null) {
+            mView.onResume();
+        }
+    }
+
+    private class RunSignalAndCatch implements Runnable {
+        public Throwable error;
+        private Runnable mRunnable;
+        private CountDownLatch mFence;
+
+        RunSignalAndCatch(Runnable run, CountDownLatch fence) {
+            mRunnable = run;
+            mFence = fence;
+        }
+
+        @Override
+        public void run() {
+            try {
+                mRunnable.run();
+            } catch (Throwable t) {
+                error = t;
+            } finally {
+                mFence.countDown();
+            }
+        }
+    }
+
+    class OpenGLES20View extends GLSurfaceView {
+
+        public OpenGLES20View(Context context, int index, int protectedAttribute,
+            int priorityAttribute, CountDownLatch latch) {
+            super(context);
+            setEGLContextClientVersion(2);
+
+            if (protectedAttribute == 1) {
+                setEGLContextFactory(new ProtectedContextFactory());
+                setEGLWindowSurfaceFactory(new ProtectedWindowSurfaceFactory());
+            } else if (priorityAttribute != 0) {
+                setEGLContextFactory(new PriorityContextFactory(priorityAttribute));
+            }
+
+            if (index == 1) {
+                mRenderer = new RendererBasicTest(latch);
+            } else  if (index == 2) {
+                mRenderer = new RendererProtectedTexturesTest(latch);
+            } else  if (index == 3) {
+                mRenderer = new RendererRefreshRateTest(latch);
+            } else {
+                throw new RuntimeException();
+            }
+            setRenderer(mRenderer);
+        }
+
+        @Override
+        public void setEGLContextClientVersion(int version) {
+            super.setEGLContextClientVersion(version);
+        }
+    }
+
+    private class PriorityContextFactory implements GLSurfaceView.EGLContextFactory {
+        private int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
+        private int mEGLContextClientVersion = 2;
+
+        private int mPriority;
+
+        PriorityContextFactory(int priorityAttribute) {
+            super();
+            mPriority = priorityAttribute;
+        }
+
+        public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig config) {
+            int[] attrib_list = { EGL_CONTEXT_CLIENT_VERSION, mEGLContextClientVersion,
+                EGL_CONTEXT_PRIORITY_LEVEL_IMG,  mPriority, EGL10.EGL_NONE };
+
+            EGLContext context = egl.eglCreateContext(display, config, EGL10.EGL_NO_CONTEXT,
+                attrib_list);
+            if (context == EGL10.EGL_NO_CONTEXT) {
+              Log.e(TAG, "Error creating EGL context.");
+            }
+            checkEglError("eglCreateContext");
+            return context;
+        }
+
+        public void destroyContext(EGL10 egl, EGLDisplay display, EGLContext context) {
+            if (!egl.eglDestroyContext(display, context)) {
+              Log.e("DefaultContextFactory", "display:" + display + " context: " + context);
+            }
+          }
+    }
+
+    private class ProtectedContextFactory implements GLSurfaceView.EGLContextFactory {
+        private int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
+        private int mEGLContextClientVersion = 2;
+
+        public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig config) {
+            int[] attrib_list = { EGL_CONTEXT_CLIENT_VERSION, mEGLContextClientVersion,
+                EGL_PROTECTED_CONTENT_EXT,  EGL14.EGL_TRUE,
+                EGL10.EGL_NONE };
+
+            EGLContext context = egl.eglCreateContext(display, config, EGL10.EGL_NO_CONTEXT,
+                attrib_list);
+            if (context == EGL10.EGL_NO_CONTEXT) {
+              Log.e(TAG, "Error creating EGL context.");
+            }
+            checkEglError("eglCreateContext");
+            return context;
+        }
+
+        public void destroyContext(EGL10 egl, EGLDisplay display, EGLContext context) {
+            if (!egl.eglDestroyContext(display, context)) {
+              Log.e("DefaultContextFactory", "display:" + display + " context: " + context);
+            }
+          }
+    }
+
+    private static class ProtectedWindowSurfaceFactory implements GLSurfaceView.EGLWindowSurfaceFactory {
+
+      public EGLSurface createWindowSurface(EGL10 egl, EGLDisplay display,
+                                            EGLConfig config, Object nativeWindow) {
+        EGLSurface result = null;
+        try {
+          int[] attrib_list = { EGL_PROTECTED_CONTENT_EXT,  EGL14.EGL_TRUE, EGL10.EGL_NONE };
+          result = egl.eglCreateWindowSurface(display, config, nativeWindow, attrib_list);
+          checkEglError("eglCreateWindowSurface");
+        } catch (IllegalArgumentException e) {
+          Log.e(TAG, "eglCreateWindowSurface", e);
+        }
+        return result;
+      }
+
+      public void destroySurface(EGL10 egl, EGLDisplay display, EGLSurface surface) {
+        egl.eglDestroySurface(display, surface);
+      }
+    }
+}
diff --git a/tests/vr/src/android/vr/cts/RendererBasicTest.java b/tests/vr/src/android/vr/cts/RendererBasicTest.java
new file mode 100644
index 0000000..9e1b2a4
--- /dev/null
+++ b/tests/vr/src/android/vr/cts/RendererBasicTest.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.vr.cts;
+
+import android.opengl.GLES20;
+import android.opengl.GLSurfaceView;
+import android.opengl.GLSurfaceView.Renderer;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.FloatBuffer;
+import java.util.concurrent.CountDownLatch;
+
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.opengles.GL10;
+
+public class RendererBasicTest implements GLSurfaceView.Renderer {
+    private String vertexShaderCode =
+              "attribute vec4 vPosition; \n"
+            + "void main(){              \n" +
+                 "gl_Position = vPosition; \n"
+            + "}                         \n";
+
+    private String fragmentShaderCode = "precision mediump float;  \n"
+            + "void main(){              \n"
+            + " gl_FragColor = vec4 (0.63671875, 0.76953125, 0.22265625, 1.0); \n"
+            + "}  \n";
+
+
+    FloatBuffer floatBuffer;
+    int mProgram;
+    int maPositionHandle;
+    float[] mColorOne = new float[4];
+
+    int[] mShaderCount = null;
+    int mError;
+
+    // child may need to manipulate them directly
+    protected CountDownLatch mLatch;
+    protected boolean mDrawn = false;
+
+    public RendererBasicTest(CountDownLatch latch) {
+        mLatch = latch;
+    }
+
+    @Override
+    public void onSurfaceChanged(GL10 gl, int width, int height) {
+    }
+
+    public int loadShader(int type, String shaderCode) {
+        int shader = GLES20.glCreateShader(type);
+        GLES20.glShaderSource(shader, shaderCode);
+        GLES20.glCompileShader(shader);
+        return shader;
+    }
+
+    @Override
+    public void onDrawFrame(GL10 gl) {
+        if (mDrawn) {
+            return;
+        }
+        mDrawn = true;
+        doOnDrawFrame(gl);
+        mLatch.countDown();
+    }
+
+    public void doOnDrawFrame(GL10 gl) {
+        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
+        GLES20.glUseProgram(mProgram);
+
+        GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT,
+                false, 12, floatBuffer);
+        GLES20.glEnableVertexAttribArray(maPositionHandle);
+        GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 3);
+        mShaderCount = new int[1];
+        int[] shaders = new int[10];
+        GLES20.glGetAttachedShaders(mProgram, 10, mShaderCount, 0, shaders, 0);
+    }
+
+    @Override
+    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
+        GLES20.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
+        initShapes();
+        int vertexShaderOne = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
+        int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);
+        mProgram =  GLES20.glCreateProgram();
+        GLES20.glAttachShader(mProgram, vertexShaderOne);
+        GLES20.glAttachShader(mProgram, fragmentShader);
+        GLES20.glLinkProgram(mProgram);
+        int[] linkStatus = new int[1];
+        GLES20.glGetProgramiv(mProgram, GLES20.GL_LINK_STATUS, linkStatus, 0);
+        if (linkStatus[0] != GLES20.GL_TRUE) {
+           //do nothing
+        }
+
+    }
+
+    public void initShapes(){
+        float triangleCoords[] = {   -0.5f, -0.25f, 0,
+                 0.5f, -0.25f, 0,
+                 0.0f,  0.559016994f, 0};
+        ByteBuffer byteBuffer = ByteBuffer.allocateDirect(triangleCoords.length * 4);
+        byteBuffer.order(ByteOrder.nativeOrder());
+        floatBuffer = byteBuffer.asFloatBuffer();
+        floatBuffer.put(triangleCoords);
+        floatBuffer.position(0);
+    }
+}
diff --git a/tests/vr/src/android/vr/cts/RendererProtectedTexturesTest.java b/tests/vr/src/android/vr/cts/RendererProtectedTexturesTest.java
new file mode 100644
index 0000000..e53dfe0
--- /dev/null
+++ b/tests/vr/src/android/vr/cts/RendererProtectedTexturesTest.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.vr.cts;
+
+import java.nio.IntBuffer;
+
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.opengles.GL10;
+
+import android.opengl.GLES20;
+
+import java.util.concurrent.CountDownLatch;
+
+public class RendererProtectedTexturesTest extends RendererBasicTest {
+
+    private String vertexShaderCode = "attribute vec4 vPosition; \n"
+            + "void main(){              \n"
+            +    "gl_Position = vPosition; \n"
+            + "}                         \n";
+
+    private String fragmentShaderCode = "precision mediump float;  \n"
+            + "sampler2D protectedTexture;\n"
+            + "void main(){              \n"
+            + " gl_FragColor = texture2D(protectedTexture, vec2(0.76953125, 0.22265625)); \n"
+            + "}  \n";
+
+    // TODO: Update this value when the extension is ratified.
+    public static int GL_CONTEXT_FLAG_PROTECTED_CONTENT_BIT = 0x00000016;
+    public static int GL_TEXTURE_PROTECTED_EXT = 0x8BFA;
+
+    private IntBuffer mTexture;
+
+    public RendererProtectedTexturesTest(CountDownLatch latch) {
+        super(latch);
+    }
+
+    @Override
+    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
+        GLES20.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
+        initShapes();
+        int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
+        int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);
+        mProgram = GLES20.glCreateProgram();
+        GLES20.glAttachShader(mProgram, vertexShader);
+        GLES20.glAttachShader(mProgram, fragmentShader);
+        GLES20.glLinkProgram(mProgram);
+        int[] linkStatus = new int[1];
+        GLES20.glGetProgramiv(mProgram, GLES20.GL_LINK_STATUS, linkStatus, 0);
+        if (linkStatus[0] != GLES20.GL_TRUE) {
+           //do nothing
+        }
+
+        // Create and bind a protected texture.
+        mTexture = IntBuffer.allocate(1);
+        GLES20.glGenTextures(1, mTexture);
+        GLES20.glActiveTexture(GLES20.GL_TEXTURE2);
+        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTexture.get(0));
+        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GL_TEXTURE_PROTECTED_EXT, GLES20.GL_TRUE);
+        int loc = GLES20.glGetUniformLocation(mProgram, "protectedTexture");
+        GLES20.glUniform1i(loc, 2);
+    }
+}
+
diff --git a/tests/vr/src/android/vr/cts/RendererRefreshRateTest.java b/tests/vr/src/android/vr/cts/RendererRefreshRateTest.java
new file mode 100644
index 0000000..30a0e3a
--- /dev/null
+++ b/tests/vr/src/android/vr/cts/RendererRefreshRateTest.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.vr.cts;
+
+import java.util.concurrent.CountDownLatch;
+import javax.microedition.khronos.opengles.GL10;
+
+public class RendererRefreshRateTest extends RendererBasicTest {
+
+    public RendererRefreshRateTest(CountDownLatch latch) {
+        super(latch);
+    }
+
+    @Override
+    public void onDrawFrame(GL10 gl) {
+        doOnDrawFrame(gl);
+        mLatch.countDown();
+    }
+}
diff --git a/tests/vr/src/android/vr/cts/VrCpuTest.java b/tests/vr/src/android/vr/cts/VrCpuTest.java
new file mode 100644
index 0000000..f015899
--- /dev/null
+++ b/tests/vr/src/android/vr/cts/VrCpuTest.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.vr.cts;
+
+import android.content.pm.PackageManager;
+import android.os.Process;
+import android.test.ActivityInstrumentationTestCase2;
+
+public class VrCpuTest extends ActivityInstrumentationTestCase2<CtsActivity> {
+    private CtsActivity mActivity;
+
+    public VrCpuTest() {
+        super(CtsActivity.class);
+    }
+
+    public void testHasAtLeastTwoCores() {
+        mActivity = getActivity();
+        if (mActivity.getPackageManager().hasSystemFeature(
+                PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE)) {
+            assertTrue(Runtime.getRuntime().availableProcessors() >= 2);
+        }
+    }
+
+    public void testHasExclusiveCores() {
+        mActivity = getActivity();
+        if (mActivity.getPackageManager().hasSystemFeature(
+                PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE)) {
+            int[] excl_cores = Process.getExclusiveCores();
+            assertTrue(excl_cores.length >= 1);
+        }
+    }
+}
diff --git a/tests/vr/src/android/vr/cts/VrDisplayTest.java b/tests/vr/src/android/vr/cts/VrDisplayTest.java
new file mode 100644
index 0000000..6b8b302
--- /dev/null
+++ b/tests/vr/src/android/vr/cts/VrDisplayTest.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.vr.cts;
+
+import android.content.Context;
+import android.content.Intent;
+import android.opengl.EGL14;
+import android.opengl.GLES32;
+import android.test.ActivityInstrumentationTestCase2;
+import android.util.DisplayMetrics;
+import android.view.WindowManager;
+
+import java.nio.IntBuffer;
+
+public class VrDisplayTest extends ActivityInstrumentationTestCase2<OpenGLESActivity> {
+
+    private OpenGLESActivity mActivity;
+
+    public VrDisplayTest() {
+        super(OpenGLESActivity.class);
+    }
+
+    private OpenGLESActivity getGlEsActivity(int latchCount, int viewIndex) {
+        Intent intent = new Intent();
+        intent.putExtra(OpenGLESActivity.EXTRA_LATCH_COUNT, latchCount);
+        intent.putExtra(OpenGLESActivity.EXTRA_VIEW_INDEX, viewIndex);
+        intent.putExtra(OpenGLESActivity.EXTRA_PROTECTED, 0);
+        intent.putExtra(OpenGLESActivity.EXTRA_PRIORITY, 0);
+        setActivityIntent(intent);
+        OpenGLESActivity activity = getActivity();
+        if (latchCount == 1) {
+          assertTrue(activity.waitForFrameDrawn());
+        }
+        return activity;
+    }
+
+    /**
+     * Tests that the refresh rate is at least 60Hz.
+     */
+    public void testRefreshRateIsAtLeast60Hz() throws Throwable {
+        final int NUM_FRAMES = 200;
+        mActivity = getGlEsActivity(NUM_FRAMES, 3);
+        if (!mActivity.supportsVrHighPerformance())
+            return;
+
+        long startNanos = System.nanoTime();
+
+        // Render a few hundred frames.
+        int error;
+        while (!mActivity.waitForFrameDrawn());
+        error = mActivity.glGetError();
+        assertEquals(GLES32.GL_NO_ERROR, error);
+        long endNanos = System.nanoTime();
+
+        double fps = NUM_FRAMES / (double)(endNanos - startNanos) * 1e9;
+        assertTrue(fps >= 59.);
+    }
+
+    /**
+     * Tests that the display resolution is at least 1080p.
+     */
+    public void testDisplayResolution() {
+        mActivity = getGlEsActivity(1, 1);
+        if (!mActivity.supportsVrHighPerformance())
+            return;
+
+        WindowManager windowManager = (WindowManager)mActivity.getSystemService(
+            Context.WINDOW_SERVICE);
+        DisplayMetrics metrics = new DisplayMetrics();
+
+        // Find the real screen size.
+        int displayWidth;
+        int displayHeight;
+        windowManager.getDefaultDisplay().getRealMetrics(metrics);
+        if (metrics.widthPixels > metrics.heightPixels) {
+          displayWidth = metrics.widthPixels;
+          displayHeight = metrics.heightPixels;
+        } else {
+          displayWidth = metrics.heightPixels;
+          displayHeight = metrics.widthPixels;
+        }
+        assertTrue(displayWidth >= 1920);
+        assertTrue(displayHeight >= 1080);
+    }
+}
diff --git a/tests/vr/src/android/vr/cts/VrExtensionBehaviorTest.java b/tests/vr/src/android/vr/cts/VrExtensionBehaviorTest.java
new file mode 100644
index 0000000..0641bfb
--- /dev/null
+++ b/tests/vr/src/android/vr/cts/VrExtensionBehaviorTest.java
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.vr.cts;
+
+import android.content.Intent;
+import android.opengl.EGL14;
+import android.opengl.GLES32;
+import android.test.ActivityInstrumentationTestCase2;
+
+import java.nio.IntBuffer;
+
+public class VrExtensionBehaviorTest extends ActivityInstrumentationTestCase2<OpenGLESActivity> {
+
+    private static final int EGL_CONTEXT_PRIORITY_HIGH_IMG = 0x3101;
+    private static final int EGL_CONTEXT_PRIORITY_MEDIUM_IMG = 0x3102;
+    private static final int EGL_CONTEXT_PRIORITY_LOW_IMG = 0x3103;
+
+    private static final int EGL_FRONT_BUFFER_AUTO_REFRESH_ANDROID = 0x314C;
+
+    private OpenGLESActivity mActivity;
+
+    public VrExtensionBehaviorTest() {
+        super(OpenGLESActivity.class);
+    }
+
+    private OpenGLESActivity getGlEsActivity(int viewIndex, int createProtected,
+        int priorityAttribute) {
+        Intent intent = new Intent();
+        intent.putExtra(OpenGLESActivity.EXTRA_VIEW_INDEX, viewIndex);
+        intent.putExtra(OpenGLESActivity.EXTRA_PROTECTED, createProtected);
+        intent.putExtra(OpenGLESActivity.EXTRA_PRIORITY, priorityAttribute);
+        setActivityIntent(intent);
+        OpenGLESActivity activity = getActivity();
+        assertTrue(activity.waitForFrameDrawn());
+        return activity;
+    }
+
+    /**
+     * Tests that protected content contexts and surfaces can be created.
+     */
+    public void testProtectedContent() throws Throwable {
+        mActivity = getGlEsActivity(1, 1, 0);
+        if (!mActivity.supportsVrHighPerformance())
+            return;
+
+        int error = mActivity.glGetError();
+        assertEquals(GLES32.GL_NO_ERROR, error);
+
+        mActivity.runOnGlThread(new Runnable() {
+            public void run() {
+                // Check that both the context and surface have the right attribute set.
+                assertTrue("Unable to validate protected context",
+                    OpenGLESActivity.contextHasAttributeWithValue(
+                        OpenGLESActivity.EGL_PROTECTED_CONTENT_EXT, EGL14.EGL_TRUE));
+                assertTrue("Unable to validate protected surface",
+                    OpenGLESActivity.surfaceHasAttributeWithValue(
+                        OpenGLESActivity.EGL_PROTECTED_CONTENT_EXT, EGL14.EGL_TRUE));
+            }
+        });
+    }
+
+    /**
+     * Tests that textures can be marked as protected.
+     */
+    public void testProtectedTextures() throws Throwable {
+        mActivity = getGlEsActivity(2, 1, 0);
+        if (!mActivity.supportsVrHighPerformance())
+            return;
+
+        int error = mActivity.glGetError();
+        assertEquals(GLES32.GL_NO_ERROR, error);
+
+        mActivity.runOnGlThread(new Runnable() {
+            public void run() {
+                // Check that both the context and surface have the right attribute set.
+                int[] values = new int[1];
+                GLES32.glGetIntegerv(GLES32.GL_CONTEXT_FLAGS, values, 0);
+                assertTrue("Context is not a protected context",
+                    (values[0] & RendererProtectedTexturesTest.GL_CONTEXT_FLAG_PROTECTED_CONTENT_BIT) != 0);
+
+                values[0] = 0;
+                GLES32.glGetTexParameteriv(GLES32.GL_TEXTURE_2D,
+                    RendererProtectedTexturesTest.GL_TEXTURE_PROTECTED_EXT, values, 0);
+                assertEquals("Texture is not marked as protected", GLES32.GL_TRUE, values[0]);
+            }
+        });
+    }
+
+    /**
+     * Tests that context priority can be set to high.
+     */
+    public void testContextPriorityHigh() throws Throwable {
+        runContextPriorityTest(EGL_CONTEXT_PRIORITY_HIGH_IMG);
+    }
+
+    /**
+     * Tests that context priority can be set to medium.
+     */
+    public void testContextPriorityMedium() throws Throwable {
+        runContextPriorityTest(EGL_CONTEXT_PRIORITY_MEDIUM_IMG);
+    }
+
+    /**
+     * Tests that context priority can be set to low.
+     */
+    public void testContextPriorityLow() throws Throwable {
+        runContextPriorityTest(EGL_CONTEXT_PRIORITY_LOW_IMG);
+    }
+
+    /**
+     * Tests that context priority can be set to low.
+     */
+    public void testMutableRenderBuffer() throws Throwable {
+
+        mActivity = getGlEsActivity(1, 0, 0);
+        if (!mActivity.supportsVrHighPerformance())
+            return;
+
+        int error = mActivity.glGetError();
+        assertEquals(GLES32.GL_NO_ERROR, error);
+
+        mActivity.runOnGlThread(new Runnable() {
+            public void run() {
+                OpenGLESActivity.setSurfaceAttribute(EGL14.EGL_RENDER_BUFFER,
+                    EGL14.EGL_SINGLE_BUFFER);
+                OpenGLESActivity.setSurfaceAttribute(EGL_FRONT_BUFFER_AUTO_REFRESH_ANDROID,
+                    EGL14.EGL_TRUE);
+                swapBuffers();
+                assertTrue("Unable to enable single buffered mode",
+                    OpenGLESActivity.contextHasAttributeWithValue(
+                        EGL14.EGL_RENDER_BUFFER, EGL14.EGL_SINGLE_BUFFER));
+                assertTrue("Unable to enable single buffered mode",
+                    OpenGLESActivity.contextHasAttributeWithValue(
+                        EGL_FRONT_BUFFER_AUTO_REFRESH_ANDROID, EGL14.EGL_TRUE));
+
+                OpenGLESActivity.setSurfaceAttribute(EGL14.EGL_RENDER_BUFFER,
+                    EGL14.EGL_BACK_BUFFER);
+                swapBuffers();
+                assertTrue("Unable to disable single buffered mode",
+                    OpenGLESActivity.contextHasAttributeWithValue(
+                        EGL14.EGL_RENDER_BUFFER, EGL14.EGL_BACK_BUFFER));
+            }
+        });
+    }
+
+    /**
+     * Runs a context priority test.
+     */
+    private void runContextPriorityTest(int priority) throws Throwable {
+        mActivity = getGlEsActivity(1, 0, priority);
+        if (!mActivity.supportsVrHighPerformance())
+            return;
+
+        int error = mActivity.glGetError();
+        assertEquals(GLES32.GL_NO_ERROR, error);
+
+        mActivity.runOnGlThread(new Runnable() {
+            public void run() {
+                assertTrue("Unable to set context priority to " + Integer.toHexString(priority),
+                    OpenGLESActivity.contextHasAttributeWithValue(
+                        OpenGLESActivity.EGL_CONTEXT_PRIORITY_LEVEL_IMG, priority));
+            }
+        });
+    }
+
+    /**
+     * Swaps EGL buffers.
+     */
+    private void swapBuffers() {
+        EGL14.eglSwapBuffers(EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY),
+            EGL14.eglGetCurrentSurface(EGL14.EGL_DRAW));
+    }
+}
diff --git a/tests/vr/src/android/vr/cts/VrSensorsTest.java b/tests/vr/src/android/vr/cts/VrSensorsTest.java
new file mode 100644
index 0000000..1f44def
--- /dev/null
+++ b/tests/vr/src/android/vr/cts/VrSensorsTest.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.vr.cts;
+
+import android.content.pm.PackageManager;
+import android.test.AndroidTestCase;
+
+/**
+ * Tests related to sensors and VR.
+ */
+public class VrSensorsTest extends AndroidTestCase {
+    private static final String TAG = "VrSensorsTest";
+
+    /**
+     * Tests creating a protected context.
+     */
+    public void testHiFiSensorsAreSupported() {
+        PackageManager pm = getContext().getPackageManager();
+        assertTrue(!pm.hasSystemFeature(PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE) ||
+            pm.hasSystemFeature(PackageManager.FEATURE_HIFI_SENSORS));
+    }
+}
diff --git a/tools/Android.mk b/tools/Android.mk
index 8377036..169accf 100644
--- a/tools/Android.mk
+++ b/tools/Android.mk
@@ -17,13 +17,13 @@
 JUNIT_HOST_JAR := $(HOST_OUT_JAVA_LIBRARIES)/junit.jar
 HOSTTESTLIB_JAR := $(HOST_OUT_JAVA_LIBRARIES)/hosttestlib.jar
 TF_JAR := $(HOST_OUT_JAVA_LIBRARIES)/tradefed-prebuilt.jar
-CTS_TF_JAR := $(HOST_OUT_JAVA_LIBRARIES)/cts-tradefed.jar
-CTS_TF_EXEC_PATH ?= $(HOST_OUT_EXECUTABLES)/cts-tradefed
+CTS_TF_JAR := $(HOST_OUT_JAVA_LIBRARIES)/old-cts-tradefed.jar
+CTS_TF_EXEC_PATH ?= $(HOST_OUT_EXECUTABLES)/old-cts-tradefed
 
-cts_prebuilt_jar := $(HOST_OUT)/cts/android-cts/tools/cts-prebuilt.jar
-$(cts_prebuilt_jar): PRIVATE_TESTS_DIR := $(HOST_OUT)/cts/android-cts/repository/testcases
-$(cts_prebuilt_jar): PRIVATE_PLANS_DIR := $(HOST_OUT)/cts/android-cts/repository/plans
-$(cts_prebuilt_jar): PRIVATE_TOOLS_DIR := $(HOST_OUT)/cts/android-cts/tools
+cts_prebuilt_jar := $(HOST_OUT)/old-cts/old-android-cts/tools/cts-prebuilt.jar
+$(cts_prebuilt_jar): PRIVATE_TESTS_DIR := $(HOST_OUT)/old-cts/old-android-cts/repository/testcases
+$(cts_prebuilt_jar): PRIVATE_PLANS_DIR := $(HOST_OUT)/old-cts/old-android-cts/repository/plans
+$(cts_prebuilt_jar): PRIVATE_TOOLS_DIR := $(HOST_OUT)/old-cts/old-android-cts/tools
 $(cts_prebuilt_jar): $(JUNIT_HOST_JAR) $(HOSTTESTLIB_JAR) $(TF_JAR) $(CTS_TF_JAR) $(CTS_TF_EXEC_PATH) $(ADDITIONAL_TF_JARS) | $(ACP) $(HOST_OUT_EXECUTABLES)/adb
 	mkdir -p $(PRIVATE_TESTS_DIR)
 	mkdir -p $(PRIVATE_PLANS_DIR)
@@ -33,10 +33,10 @@
 .PHONY: cts-harness
 cts-harness : $(cts_prebuilt_jar)
 
-# Put the test coverage report in the dist dir if "cts" is among the build goals.
-ifneq ($(filter cts, $(MAKECMDGOALS)),)
-  $(call dist-for-goals,cts,$(CTS_TF_JAR))
-  $(call dist-for-goals,cts,$(HOSTTESTLIB_JAR))
+# Put the test coverage report in the dist dir if "old-cts" is among the build goals.
+ifneq ($(filter old-cts, $(MAKECMDGOALS)),)
+  $(call dist-for-goals,old-cts,$(CTS_TF_JAR))
+  $(call dist-for-goals,old-cts,$(HOSTTESTLIB_JAR))
 endif
 
 include $(call all-subdir-makefiles)
diff --git a/tools/cts-api-coverage/src/com/android/cts/apicoverage/ApiClass.java b/tools/cts-api-coverage/src/com/android/cts/apicoverage/ApiClass.java
index 73cea67..2d24931 100644
--- a/tools/cts-api-coverage/src/com/android/cts/apicoverage/ApiClass.java
+++ b/tools/cts-api-coverage/src/com/android/cts/apicoverage/ApiClass.java
@@ -197,6 +197,13 @@
     }
 
     /**
+     * @return true iff the parameter is a var arg parameter.
+     */
+    private static boolean isVarArg(String parameter) {
+        return parameter.endsWith("...");
+    }
+
+    /**
      * Compare class types.
      * @param apiType The type as reported by the api
      * @param testType The type as found used in a test
@@ -206,7 +213,9 @@
     private static boolean compareType(String apiType, String testType) {
         return apiType.equals(testType) ||
                 isGenericType(apiType) && !testType.equals(VOID) ||
-                isGenericArrayType(apiType) && isArrayType(testType) ;
+                isGenericArrayType(apiType) && isArrayType(testType) ||
+                isVarArg(apiType) && isArrayType(testType) &&
+                        apiType.startsWith(testType.substring(0, testType.indexOf("[")));
     }
 
     /**
diff --git a/tools/cts-device-info/Android.mk b/tools/cts-device-info/Android.mk
index 5f2b223..4b43d39 100644
--- a/tools/cts-device-info/Android.mk
+++ b/tools/cts-device-info/Android.mk
@@ -18,11 +18,18 @@
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
+DEVICE_INFO_MIN_SDK := 23
+DEVICE_INFO_TARGET_SDK := 23
+
 DEVICE_INFO_PERMISSIONS :=
 
-DEVICE_INFO_ACTIVITIES :=
+DEVICE_INFO_ACTIVITIES := \
+    com.android.compatibility.common.deviceinfo.GlesStubActivity \
+    com.android.cts.deviceinfo.CameraDeviceInfo
 
 LOCAL_PACKAGE_NAME := CtsDeviceInfo
 
-include $(BUILD_CTS_DEVICE_INFO_PACKAGE)
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
 
+include $(BUILD_CTS_DEVICE_INFO_PACKAGE)
diff --git a/tools/cts-device-info/src/com/android/cts/deviceinfo/CameraDeviceInfo.java b/tools/cts-device-info/src/com/android/cts/deviceinfo/CameraDeviceInfo.java
new file mode 100644
index 0000000..41afdb9eb
--- /dev/null
+++ b/tools/cts-device-info/src/com/android/cts/deviceinfo/CameraDeviceInfo.java
@@ -0,0 +1,531 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.deviceinfo;
+
+import android.content.Context;
+import android.graphics.Rect;
+import android.hardware.Camera;
+import android.hardware.camera2.CameraAccessException;
+import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CameraManager;
+import android.hardware.camera2.params.BlackLevelPattern;
+import android.hardware.camera2.params.ColorSpaceTransform;
+import android.hardware.camera2.params.StreamConfigurationMap;
+import android.media.CamcorderProfile;
+import android.os.Build;
+import android.util.Log;
+import android.util.Rational;
+import android.util.Size;
+import android.util.SizeF;
+import android.util.Range;
+
+import com.android.compatibility.common.deviceinfo.DeviceInfo;
+import com.android.compatibility.common.util.DeviceInfoStore;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.Field;
+import java.lang.reflect.GenericArrayType;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.HashSet;
+import java.util.List;
+
+/**
+ * Camera information collector.
+ */
+public final class CameraDeviceInfo extends DeviceInfo {
+    private static final String TAG = "CameraDeviceInfo";
+
+    private final static class CameraCharacteristicsStorer {
+        private CameraManager mCameraManager;
+        private DeviceInfoStore mStore;
+
+        public CameraCharacteristicsStorer(CameraManager cameraManager, DeviceInfoStore store) {
+            if (cameraManager == null || store == null) {
+                throw new IllegalArgumentException("can not create an CameraMetadataGetter object"
+                        + " with null CameraManager or null DeviceInfoStore");
+            }
+
+            mCameraManager = cameraManager;
+            mStore = store;
+        }
+
+        public void storeCameraInfo(String cameraId) throws Exception {
+            try {
+                CameraCharacteristics chars = mCameraManager.getCameraCharacteristics(cameraId);
+                mStore.startGroup(); // per camera chars
+                mStore.addResult("cameraId", cameraId);
+                storeCameraChars(chars);
+                mStore.endGroup(); // per camera chars
+            } catch (CameraAccessException e) {
+                Log.e(TAG,
+                        "Unable to get camera camera static info, skip this camera, error: "
+                                + e.getMessage());
+            }
+            return;
+        }
+
+        private void storeRational(
+                Rational rat, String protoName) throws Exception {
+            if (protoName == null) {
+                mStore.startGroup();
+            } else {
+                mStore.startGroup(protoName);
+            }
+            mStore.addResult("numerator", rat.getNumerator());
+            mStore.addResult("denominator", rat.getDenominator());
+            mStore.endGroup();
+        }
+
+        private void storeSize(
+                Size size, String protoName) throws Exception {
+            if (protoName == null) {
+                mStore.startGroup();
+            } else {
+                mStore.startGroup(protoName);
+            }
+            mStore.addResult("width", size.getWidth());
+            mStore.addResult("height", size.getHeight());
+            mStore.endGroup();
+        }
+
+        private void storeSizeF(
+                SizeF size, String protoName) throws Exception {
+            if (protoName == null) {
+                mStore.startGroup();
+            } else {
+                mStore.startGroup(protoName);
+            }
+            mStore.addResult("width", size.getWidth());
+            mStore.addResult("height", size.getHeight());
+            mStore.endGroup();
+        }
+
+        private void storeRect(
+                Rect rect, String protoName) throws Exception {
+            if (protoName == null) {
+                mStore.startGroup();
+            } else {
+                mStore.startGroup(protoName);
+            }
+            mStore.addResult("left", rect.left);
+            mStore.addResult("right", rect.right);
+            mStore.addResult("top", rect.top);
+            mStore.addResult("bottom", rect.bottom);
+            mStore.endGroup();
+        }
+
+        private void storeStreamConfigurationMap(
+                StreamConfigurationMap map, String protoName) throws Exception {
+            if (protoName == null) {
+                mStore.startGroup();
+            } else {
+                mStore.startGroup(protoName);
+            }
+
+            int fmts[] = map.getOutputFormats();
+            if (fmts != null) {
+                mStore.startArray("availableStreamConfigurations");
+                for (int fi = 0; fi < Array.getLength(fmts); fi++) {
+                    Size sizes[] = map.getOutputSizes(fmts[fi]);
+                    if (sizes != null) {
+                        for (int si = 0; si < Array.getLength(sizes); si++) {
+                            mStore.startGroup();
+                            mStore.addResult("format", fmts[fi]);
+                            mStore.addResult("width", sizes[si].getWidth());
+                            mStore.addResult("height", sizes[si].getHeight());
+                            mStore.addResult("input", false);
+                            mStore.addResult("minFrameDuration",
+                                            map.getOutputMinFrameDuration(fmts[fi], sizes[si]));
+                            mStore.endGroup();
+                        }
+                    }
+                }
+                mStore.endArray();
+            }
+            mStore.endGroup();
+        }
+
+        private void storeRangeInt(
+                Range<Integer> range, String protoName) throws Exception {
+            if (protoName == null) {
+                mStore.startGroup();
+            } else {
+                mStore.startGroup(protoName);
+            }
+            mStore.addResult("lower", range.getLower());
+            mStore.addResult("upper", range.getUpper());
+            mStore.endGroup();
+        }
+
+        private void storeRangeLong(
+                Range<Long> range, String protoName) throws Exception {
+            if (protoName == null) {
+                mStore.startGroup();
+            } else {
+                mStore.startGroup(protoName);
+            }
+            mStore.addResult("lower", range.getLower());
+            mStore.addResult("upper", range.getUpper());
+            mStore.endGroup();
+        }
+
+        private void storeColorSpaceTransform(
+                ColorSpaceTransform xform, String protoName) throws Exception {
+            if (protoName == null) {
+                mStore.startGroup();
+            } else {
+                mStore.startGroup(protoName);
+            }
+
+            mStore.startArray("elements");
+            for (int row = 0; row < 3; row++) {
+                for (int col = 0; col < 3; col++) {
+                    storeRational((Rational) xform.getElement(col, row), null);
+                }
+            }
+            mStore.endArray();
+            mStore.endGroup();
+        }
+
+        private void storeBlackLevelPattern(
+                BlackLevelPattern pat, String protoName) throws Exception {
+            if (protoName == null) {
+                mStore.startGroup();
+            } else {
+                mStore.startGroup(protoName);
+            }
+            int patVals[] = new int[4];
+            pat.copyTo(patVals, 0);
+            mStore.addArrayResult("black_level_pattern", patVals);
+            mStore.endGroup();
+        }
+
+        private static String getKeyName(Object keyObj) {
+            return ((CameraCharacteristics.Key) keyObj).getName();
+        }
+
+        private static Object getKeyValue(CameraCharacteristics chars, Object keyObj) {
+            return chars.get((CameraCharacteristics.Key) keyObj);
+        }
+
+        private void storeEntry(Type keyType, Object keyObj,
+                CameraCharacteristics chars) throws Exception {
+            String keyName = getKeyName(keyObj);
+            String protoName = keyName.replace('.', '_');
+            Object keyValue = getKeyValue(chars, keyObj);
+            if (keyValue == null) {
+                return;
+            }
+
+            if (keyType == int.class || keyType == Integer.class) {
+                mStore.addResult(protoName, (int) keyValue);
+                return;
+            } else if (keyType == float.class || keyType == Float.class) {
+                mStore.addResult(protoName, (float) keyValue);
+                return;
+            } else if (keyType == long.class || keyType == Long.class) {
+                mStore.addResult(protoName, (long) keyValue);
+                return;
+            } else if (keyType == double.class || keyType == Double.class) {
+                mStore.addResult(protoName, (double) keyValue);
+                return;
+            } else if (keyType == boolean.class || keyType == Boolean.class) {
+                mStore.addResult(protoName, (boolean) keyValue);
+                return;
+            } else if (keyType == byte.class || keyType == Byte.class) {
+                // Infostore does not support byte, convert to int32 and save
+                int intValue = (int) ((byte) keyValue);
+                mStore.addResult(protoName, intValue);
+                return;
+            } else if (keyType == Rational.class) {
+                storeRational((Rational) keyValue, protoName);
+                return;
+            } else if (keyType == Size.class) {
+                storeSize((Size) keyValue, protoName);
+                return;
+            } else if (keyType == SizeF.class) {
+                storeSizeF((SizeF) keyValue, protoName);
+                return;
+            } else if (keyType == Rect.class) {
+                storeRect((Rect) keyValue, protoName);
+                return;
+            } else if (keyType == StreamConfigurationMap.class) {
+                storeStreamConfigurationMap(
+                        (StreamConfigurationMap) keyValue, protoName);
+                return;
+            } else if (keyType instanceof ParameterizedType &&
+                    ((ParameterizedType) keyType).getRawType() == Range.class &&
+                    ((ParameterizedType) keyType).getActualTypeArguments()[0] == Integer.class) {
+                storeRangeInt((Range<Integer>) keyValue, protoName);
+                return;
+            } else if (keyType instanceof ParameterizedType &&
+                    ((ParameterizedType) keyType).getRawType() == Range.class &&
+                    ((ParameterizedType) keyType).getActualTypeArguments()[0] == Long.class) {
+                storeRangeLong((Range<Long>) keyValue, protoName);
+                return;
+            } else if (keyType == ColorSpaceTransform.class) {
+                storeColorSpaceTransform((ColorSpaceTransform) keyValue, protoName);
+                return;
+            } else if (keyType == BlackLevelPattern.class) {
+                storeBlackLevelPattern((BlackLevelPattern) keyValue, protoName);
+                return;
+            } else {
+                Log.w(TAG, "Storing unsupported key type: " + keyType +
+                        " for keyName: " + keyName);
+                return;
+            }
+        }
+
+        private void storeArrayEntry(Type keyType, Object keyObj,
+                CameraCharacteristics chars) throws Exception {
+            String keyName = getKeyName(keyObj);
+            String protoName = keyName.replace('.', '_');
+            Object keyValue = getKeyValue(chars, keyObj);
+            if (keyValue == null) {
+                return;
+            }
+
+            int arrayLen = Array.getLength(keyValue);
+            if (arrayLen == 0) {
+                return;
+            }
+            Type elmtType = ((GenericArrayType) keyType).getGenericComponentType();
+
+            if (elmtType == int.class) {
+                mStore.addArrayResult(protoName, (int[]) keyValue);
+                return;
+            } else if (elmtType == float.class) {
+                mStore.addArrayResult(protoName, (float[]) keyValue);
+                return;
+            } else if (elmtType == long.class) {
+                mStore.addArrayResult(protoName, (long[]) keyValue);
+                return;
+            } else if (elmtType == double.class) {
+                mStore.addArrayResult(protoName, (double[]) keyValue);
+                return;
+            } else if (elmtType == boolean.class) {
+                mStore.addArrayResult(protoName, (boolean[]) keyValue);
+                return;
+            } else if (elmtType == byte.class) {
+                // Infostore does not support byte, convert to int32 and save
+                int[] intValues = new int[arrayLen];
+                for (int i = 0; i < arrayLen; i++) {
+                    intValues[i] = (int) ((byte) Array.get(keyValue, i));
+                }
+                mStore.addArrayResult(protoName, intValues);
+                return;
+            } else if (elmtType == Rational.class) {
+                mStore.startArray(protoName);
+                for (int i = 0; i < arrayLen; i++) {
+                    storeRational((Rational) Array.get(keyValue, i), null);
+                }
+                mStore.endArray();
+                return;
+            } else if (elmtType == Size.class) {
+                mStore.startArray(protoName);
+                for (int i = 0; i < arrayLen; i++) {
+                    storeSize((Size) Array.get(keyValue, i), null);
+                }
+                mStore.endArray();
+                return;
+            } else if (elmtType == Rect.class) {
+                mStore.startArray(protoName);
+                for (int i = 0; i < arrayLen; i++) {
+                    storeRect((Rect) Array.get(keyValue, i), null);
+                }
+                mStore.endArray();
+                return;
+            } else if (elmtType instanceof ParameterizedType &&
+                    ((ParameterizedType) elmtType).getRawType() == Range.class &&
+                    ((ParameterizedType) elmtType).getActualTypeArguments()[0] == Integer.class) {
+                mStore.startArray(protoName);
+                for (int i = 0; i < arrayLen; i++) {
+                    storeRangeInt((Range<Integer>) Array.get(keyValue, i), null);
+                }
+                mStore.endArray();
+                return;
+            } else if (elmtType == BlackLevelPattern.class) {
+                mStore.startArray(protoName);
+                for (int i = 0; i < arrayLen; i++) {
+                    storeBlackLevelPattern((BlackLevelPattern) Array.get(keyValue, i), null);
+                }
+                mStore.endArray();
+                return;
+            } else {
+                Log.w(TAG, "Storing unsupported array type: " + elmtType +
+                        " for keyName: " + keyName);
+                return;
+            }
+        }
+
+        private void storeCameraChars(
+                CameraCharacteristics chars) throws Exception {
+            HashSet<String> charsKeyNames = getAllCharacteristicsKeyNames();
+            Field[] allFields = chars.getClass().getDeclaredFields();
+            for (Field field : allFields) {
+                if (Modifier.isPublic(field.getModifiers()) &&
+                        Modifier.isStatic(field.getModifiers()) &&
+                        field.getType() == CameraCharacteristics.Key.class &&
+                        field.getGenericType() instanceof ParameterizedType) {
+                    ParameterizedType paramType = (ParameterizedType) field.getGenericType();
+                    Type[] argTypes = paramType.getActualTypeArguments();
+                    if (argTypes.length > 0) {
+                        try {
+                            Type keyType = argTypes[0];
+                            Object keyObj = field.get(chars);
+                            String keyName = getKeyName(keyObj);
+                            if (charsKeyNames.contains(keyName)) {
+                                if (keyType instanceof GenericArrayType) {
+                                    storeArrayEntry(keyType, keyObj, chars);
+                                } else {
+                                    storeEntry(keyType, keyObj, chars);
+                                }
+                            }
+                        } catch (IllegalAccessException e) {
+                            throw new IllegalStateException(
+                                    "Access error for field: " + field + ": ", e);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+
+    @Override
+    protected void collectDeviceInfo(DeviceInfoStore store) throws Exception {
+        store.addResult("profile_480p", CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_480P));
+        store.addResult("profile_720p", CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_720P));
+        store.addResult("profile_1080p", CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_1080P));
+        store.addResult("profile_cif", CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_CIF));
+        store.addResult("profile_qcif", CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_QCIF));
+        store.addResult("profile_qvga", CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_QVGA));
+
+        CameraManager cameraManager = (CameraManager)
+                getContext().getSystemService(Context.CAMERA_SERVICE);
+        try {
+            String[] cameraIdList = cameraManager.getCameraIdList();
+            store.addResult("num_of_camera", cameraIdList.length);
+            if (cameraIdList.length > 0) {
+                CameraCharacteristicsStorer charsStorer =
+                        new CameraCharacteristicsStorer(cameraManager, store);
+                store.startArray("per_camera_info");
+                for (int i = 0; i < cameraIdList.length; i++) {
+                    charsStorer.storeCameraInfo(cameraIdList[i]);
+                }
+                store.endArray(); // per_camera_info
+            }
+        } catch (CameraAccessException e) {
+            Log.e(TAG,
+                    "Unable to get camera camera ID list, error: "
+                            + e.getMessage());
+        }
+    }
+
+    /*@O~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~
+     * The key entries below this point are generated from metadata
+     * definitions in /system/media/camera/docs. Do not modify by hand or
+     * modify the comment blocks at the start or end.
+     *~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~*/
+
+    private static HashSet<String> getAllCharacteristicsKeyNames() {
+        HashSet<String> charsKeyNames = new HashSet<String>();
+        charsKeyNames.add(CameraCharacteristics.COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES.getName());
+        charsKeyNames.add(CameraCharacteristics.CONTROL_AE_AVAILABLE_ANTIBANDING_MODES.getName());
+        charsKeyNames.add(CameraCharacteristics.CONTROL_AE_AVAILABLE_MODES.getName());
+        charsKeyNames.add(CameraCharacteristics.CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES.getName());
+        charsKeyNames.add(CameraCharacteristics.CONTROL_AE_COMPENSATION_RANGE.getName());
+        charsKeyNames.add(CameraCharacteristics.CONTROL_AE_COMPENSATION_STEP.getName());
+        charsKeyNames.add(CameraCharacteristics.CONTROL_AF_AVAILABLE_MODES.getName());
+        charsKeyNames.add(CameraCharacteristics.CONTROL_AVAILABLE_EFFECTS.getName());
+        charsKeyNames.add(CameraCharacteristics.CONTROL_AVAILABLE_SCENE_MODES.getName());
+        charsKeyNames.add(CameraCharacteristics.CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES.getName());
+        charsKeyNames.add(CameraCharacteristics.CONTROL_AWB_AVAILABLE_MODES.getName());
+        charsKeyNames.add(CameraCharacteristics.CONTROL_MAX_REGIONS_AE.getName());
+        charsKeyNames.add(CameraCharacteristics.CONTROL_MAX_REGIONS_AWB.getName());
+        charsKeyNames.add(CameraCharacteristics.CONTROL_MAX_REGIONS_AF.getName());
+        charsKeyNames.add(CameraCharacteristics.CONTROL_AE_LOCK_AVAILABLE.getName());
+        charsKeyNames.add(CameraCharacteristics.CONTROL_AWB_LOCK_AVAILABLE.getName());
+        charsKeyNames.add(CameraCharacteristics.CONTROL_AVAILABLE_MODES.getName());
+        charsKeyNames.add(CameraCharacteristics.CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE.getName());
+        charsKeyNames.add(CameraCharacteristics.EDGE_AVAILABLE_EDGE_MODES.getName());
+        charsKeyNames.add(CameraCharacteristics.FLASH_INFO_AVAILABLE.getName());
+        charsKeyNames.add(CameraCharacteristics.HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES.getName());
+        charsKeyNames.add(CameraCharacteristics.JPEG_AVAILABLE_THUMBNAIL_SIZES.getName());
+        charsKeyNames.add(CameraCharacteristics.LENS_FACING.getName());
+        charsKeyNames.add(CameraCharacteristics.LENS_INFO_AVAILABLE_APERTURES.getName());
+        charsKeyNames.add(CameraCharacteristics.LENS_INFO_AVAILABLE_FILTER_DENSITIES.getName());
+        charsKeyNames.add(CameraCharacteristics.LENS_INFO_AVAILABLE_FOCAL_LENGTHS.getName());
+        charsKeyNames.add(CameraCharacteristics.LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION.getName());
+        charsKeyNames.add(CameraCharacteristics.LENS_INFO_HYPERFOCAL_DISTANCE.getName());
+        charsKeyNames.add(CameraCharacteristics.LENS_INFO_MINIMUM_FOCUS_DISTANCE.getName());
+        charsKeyNames.add(CameraCharacteristics.LENS_INFO_FOCUS_DISTANCE_CALIBRATION.getName());
+        charsKeyNames.add(CameraCharacteristics.NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES.getName());
+        charsKeyNames.add(CameraCharacteristics.REQUEST_MAX_NUM_OUTPUT_RAW.getName());
+        charsKeyNames.add(CameraCharacteristics.REQUEST_MAX_NUM_OUTPUT_PROC.getName());
+        charsKeyNames.add(CameraCharacteristics.REQUEST_MAX_NUM_OUTPUT_PROC_STALLING.getName());
+        charsKeyNames.add(CameraCharacteristics.REQUEST_MAX_NUM_INPUT_STREAMS.getName());
+        charsKeyNames.add(CameraCharacteristics.REQUEST_PIPELINE_MAX_DEPTH.getName());
+        charsKeyNames.add(CameraCharacteristics.REQUEST_PARTIAL_RESULT_COUNT.getName());
+        charsKeyNames.add(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES.getName());
+        charsKeyNames.add(CameraCharacteristics.SCALER_AVAILABLE_MAX_DIGITAL_ZOOM.getName());
+        charsKeyNames.add(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP.getName());
+        charsKeyNames.add(CameraCharacteristics.SCALER_CROPPING_TYPE.getName());
+        charsKeyNames.add(CameraCharacteristics.SENSOR_REFERENCE_ILLUMINANT1.getName());
+        charsKeyNames.add(CameraCharacteristics.SENSOR_REFERENCE_ILLUMINANT2.getName());
+        charsKeyNames.add(CameraCharacteristics.SENSOR_CALIBRATION_TRANSFORM1.getName());
+        charsKeyNames.add(CameraCharacteristics.SENSOR_CALIBRATION_TRANSFORM2.getName());
+        charsKeyNames.add(CameraCharacteristics.SENSOR_COLOR_TRANSFORM1.getName());
+        charsKeyNames.add(CameraCharacteristics.SENSOR_COLOR_TRANSFORM2.getName());
+        charsKeyNames.add(CameraCharacteristics.SENSOR_FORWARD_MATRIX1.getName());
+        charsKeyNames.add(CameraCharacteristics.SENSOR_FORWARD_MATRIX2.getName());
+        charsKeyNames.add(CameraCharacteristics.SENSOR_BLACK_LEVEL_PATTERN.getName());
+        charsKeyNames.add(CameraCharacteristics.SENSOR_MAX_ANALOG_SENSITIVITY.getName());
+        charsKeyNames.add(CameraCharacteristics.SENSOR_ORIENTATION.getName());
+        charsKeyNames.add(CameraCharacteristics.SENSOR_AVAILABLE_TEST_PATTERN_MODES.getName());
+        charsKeyNames.add(CameraCharacteristics.SENSOR_OPTICAL_BLACK_REGIONS.getName());
+        charsKeyNames.add(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE.getName());
+        charsKeyNames.add(CameraCharacteristics.SENSOR_INFO_SENSITIVITY_RANGE.getName());
+        charsKeyNames.add(CameraCharacteristics.SENSOR_INFO_COLOR_FILTER_ARRANGEMENT.getName());
+        charsKeyNames.add(CameraCharacteristics.SENSOR_INFO_EXPOSURE_TIME_RANGE.getName());
+        charsKeyNames.add(CameraCharacteristics.SENSOR_INFO_MAX_FRAME_DURATION.getName());
+        charsKeyNames.add(CameraCharacteristics.SENSOR_INFO_PHYSICAL_SIZE.getName());
+        charsKeyNames.add(CameraCharacteristics.SENSOR_INFO_PIXEL_ARRAY_SIZE.getName());
+        charsKeyNames.add(CameraCharacteristics.SENSOR_INFO_WHITE_LEVEL.getName());
+        charsKeyNames.add(CameraCharacteristics.SENSOR_INFO_TIMESTAMP_SOURCE.getName());
+        charsKeyNames.add(CameraCharacteristics.SENSOR_INFO_LENS_SHADING_APPLIED.getName());
+        charsKeyNames.add(CameraCharacteristics.SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE.getName());
+        charsKeyNames.add(CameraCharacteristics.SHADING_AVAILABLE_MODES.getName());
+        charsKeyNames.add(CameraCharacteristics.STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES.getName());
+        charsKeyNames.add(CameraCharacteristics.STATISTICS_INFO_MAX_FACE_COUNT.getName());
+        charsKeyNames.add(CameraCharacteristics.STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES.getName());
+        charsKeyNames.add(CameraCharacteristics.STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES.getName());
+        charsKeyNames.add(CameraCharacteristics.TONEMAP_MAX_CURVE_POINTS.getName());
+        charsKeyNames.add(CameraCharacteristics.TONEMAP_AVAILABLE_TONE_MAP_MODES.getName());
+        charsKeyNames.add(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL.getName());
+        charsKeyNames.add(CameraCharacteristics.SYNC_MAX_LATENCY.getName());
+        charsKeyNames.add(CameraCharacteristics.REPROCESS_MAX_CAPTURE_STALL.getName());
+        charsKeyNames.add(CameraCharacteristics.DEPTH_DEPTH_IS_EXCLUSIVE.getName());
+
+        return charsKeyNames;
+    }
+
+    /*~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~
+     * End generated code
+     *~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~O@*/
+}
diff --git a/tools/cts-device-info/src/com/android/cts/deviceinfo/SampleDeviceInfo.java b/tools/cts-device-info/src/com/android/cts/deviceinfo/SampleDeviceInfo.java
index b8dbb6e..8d3d7ada 100644
--- a/tools/cts-device-info/src/com/android/cts/deviceinfo/SampleDeviceInfo.java
+++ b/tools/cts-device-info/src/com/android/cts/deviceinfo/SampleDeviceInfo.java
@@ -18,7 +18,7 @@
 import android.os.Bundle;
 
 import com.android.compatibility.common.deviceinfo.DeviceInfo;
-import com.android.compatibility.common.util.InfoStore;
+import com.android.compatibility.common.util.DeviceInfoStore;
 
 import java.util.Arrays;
 
@@ -28,7 +28,7 @@
 public class SampleDeviceInfo extends DeviceInfo {
 
     @Override
-    protected void collectDeviceInfo(InfoStore store) throws Exception {
+    protected void collectDeviceInfo(DeviceInfoStore store) throws Exception {
         boolean[] booleans = {Boolean.TRUE, Boolean.FALSE};
         double[] doubles = {Double.MAX_VALUE, Double.MIN_VALUE};
         int[] ints = {Integer.MAX_VALUE, Integer.MIN_VALUE};
@@ -58,4 +58,3 @@
         store.endGroup(); // foo
     }
 }
-
diff --git a/tools/cts-java-scanner-doclet/src/com/android/cts/javascannerdoclet/CtsJavaScannerDoclet.java b/tools/cts-java-scanner-doclet/src/com/android/cts/javascannerdoclet/CtsJavaScannerDoclet.java
index 78d4249..1b48ddf 100644
--- a/tools/cts-java-scanner-doclet/src/com/android/cts/javascannerdoclet/CtsJavaScannerDoclet.java
+++ b/tools/cts-java-scanner-doclet/src/com/android/cts/javascannerdoclet/CtsJavaScannerDoclet.java
@@ -65,6 +65,10 @@
 
     static final String JUNIT_TEST_CASE_CLASS_NAME = "junit.framework.testcase";
 
+    private static final String TIMEOUT_ANNOTATION = "com.android.cts.util.TimeoutReq";
+    private static final String SUPPRESS_ANNOTATION =
+            "android.test.suitebuilder.annotation.Suppress";
+
     public static boolean start(RootDoc root) {
         ClassDoc[] classes = root.classes();
         if (classes == null) {
@@ -93,10 +97,11 @@
                             continue;
                         }
 
+                        boolean suppressed = false;
                         AnnotationDesc[] annotations = method.annotations();
                         for (AnnotationDesc annot : annotations) {
                             String atype = annot.annotationType().toString();
-                            if (atype.equals("com.android.cts.util.TimeoutReq")) {
+                            if (atype.equals(TIMEOUT_ANNOTATION)) {
                                 ElementValuePair[] cpairs = annot.elementValues();
                                 for (ElementValuePair pair : cpairs) {
                                     AnnotationTypeElementDoc elem = pair.element();
@@ -105,8 +110,13 @@
                                         timeout = ((Integer) value.value());
                                     }
                                 }
+                            } else if (atype.equals(SUPPRESS_ANNOTATION)) {
+                                suppressed = true;
                             }
                         }
+                        if (suppressed) {
+                            continue;
+                        }
                     } else {
                         /* JUnit4 */
                         boolean isTest = false;
diff --git a/tools/cts-preconditions/Android.mk b/tools/cts-preconditions/Android.mk
new file mode 100644
index 0000000..5497dda
--- /dev/null
+++ b/tools/cts-preconditions/Android.mk
@@ -0,0 +1,39 @@
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+# Don't include this package in any target
+LOCAL_MODULE_TAGS := tests
+# When built, explicitly put it in the data partition.
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_DEX_PREOPT := false
+
+LOCAL_PROGUARD_ENABLED := disabled
+
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-test compatibility-device-preconditions
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_PACKAGE_NAME := CtsPreconditions
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_PACKAGE)
diff --git a/tools/cts-preconditions/AndroidManifest.xml b/tools/cts-preconditions/AndroidManifest.xml
new file mode 100644
index 0000000..a8eb827
--- /dev/null
+++ b/tools/cts-preconditions/AndroidManifest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.preconditions.cts">
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <!--  self-instrumenting test package. -->
+    <instrumentation
+        android:name="android.support.test.runner.AndroidJUnitRunner"
+        android:label="CTS preconditions test"
+        android:targetPackage="com.android.preconditions.cts" >
+    </instrumentation>
+</manifest>
diff --git a/tools/cts-preconditions/src/com/android/preconditions/cts/PreconditionsTest.java b/tools/cts-preconditions/src/com/android/preconditions/cts/PreconditionsTest.java
new file mode 100644
index 0000000..34413e9
--- /dev/null
+++ b/tools/cts-preconditions/src/com/android/preconditions/cts/PreconditionsTest.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.preconditions.cts;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.test.AndroidTestCase;
+import android.util.Log;
+
+import com.android.compatibility.common.preconditions.ExternalStorageHelper;
+import com.android.compatibility.common.preconditions.ScreenLockHelper;
+
+/**
+ * A test to verify that device-side preconditions are met for CTS
+ */
+public class PreconditionsTest extends AndroidTestCase {
+
+    private static final String TAG = "PreconditionsTest";
+
+    /**
+     * Test if device has no screen lock
+     * @throws Exception
+     */
+    public void testScreenUnlocked() throws Exception {
+        PackageManager pm = this.getContext().getPackageManager();
+        if (pm.hasSystemFeature(PackageManager.FEATURE_LEANBACK)
+                || pm.hasSystemFeature(PackageManager.FEATURE_WATCH)
+                || pm.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
+            Log.i(TAG, "Skipping screen lock precondition for this device type");
+            return; // do not test for unlocked screen on devices with no screen lock
+        }
+        assertFalse("Device must have screen lock disabled",
+                ScreenLockHelper.isDeviceSecure(this.getContext()));
+    }
+
+    /**
+     * Test if device has accessible external storage
+     * @throws Exception
+     */
+    public void testExternalStoragePresent() throws Exception {
+        assertTrue("Device must have external storage mounted in order to run CTS",
+                ExternalStorageHelper.isExternalStorageReadable());
+        assertTrue("Device external storage must be writable in order to run CTS",
+                ExternalStorageHelper.isExternalStorageWritable());
+    }
+
+}
diff --git a/tools/cts-tradefed/Android.mk b/tools/cts-tradefed/Android.mk
new file mode 100644
index 0000000..6ae6066
--- /dev/null
+++ b/tools/cts-tradefed/Android.mk
@@ -0,0 +1,35 @@
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, ../../common/host-side/tradefed/src)
+
+LOCAL_JAVA_RESOURCE_DIRS := res
+LOCAL_JAVA_RESOURCE_DIRS += ../../common/host-side/tradefed/res
+
+LOCAL_SUITE_BUILD_NUMBER := $(BUILD_NUMBER_FROM_FILE)
+LOCAL_SUITE_TARGET_ARCH := $(TARGET_ARCH)
+LOCAL_SUITE_NAME := CTS
+LOCAL_SUITE_FULLNAME := "Compatibility Test Suite"
+LOCAL_SUITE_VERSION := 5.0
+
+LOCAL_MODULE := cts-tradefed
+
+include $(BUILD_COMPATIBILITY_SUITE)
+
+# Build all sub-directories
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tools/cts-tradefed/DynamicConfig.xml b/tools/cts-tradefed/DynamicConfig.xml
new file mode 100644
index 0000000..e02d61e
--- /dev/null
+++ b/tools/cts-tradefed/DynamicConfig.xml
@@ -0,0 +1,20 @@
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<dynamicConfig>
+    <entry key="MediaFilesUrl">
+         <value>https://dl.google.com/dl/android/cts/android-cts-media-1.1.zip</value>
+    </entry>
+</dynamicConfig>
diff --git a/tools/cts-tradefed/README b/tools/cts-tradefed/README
new file mode 100644
index 0000000..d1357aa
--- /dev/null
+++ b/tools/cts-tradefed/README
@@ -0,0 +1,83 @@
+CTS Trade Federation
+---------------------
+
+CTS Trade Federation, cts-tradefed for short, is the next
+generation test harness for CTS.
+
+cts-tradefed is built on top of the Android Trade Federation test harness.
+
+It works in a similar manner to the prior CTS harness, but supports some
+advanced features such as:
+
+  - modular, flexible extensible design. cts-tradefed can be extended to
+support running CTS in a continuous test environment.
+  - supports sharding a CTS test run across multiple devices in parallel
+  - automatically continue a CTS test run on another device if connection
+is lost
+
+Configuring cts-tradefed
+------------------------
+
+1. Ensure 'adb' is in your current PATH. adb can be found in the
+Android SDK available from http://developer.android.com
+
+Example:
+  PATH=$PATH:/home/myuser/android-sdk-linux_x86/platform-tools
+
+2. Follow the 'Setting up your device' steps documented in the
+CTS User Manual. The CTS User Manual can be downloaded at
+http://source.android.com/compatibility/downloads.html
+
+3. Connect the device to the host machine.
+
+4. Ensure device is visible via 'adb devices'
+
+Using cts-tradefed
+-------------------
+
+To run a test plan on a single device:
+
+1. Make sure you have at least one device connected
+2. Launch the cts-tradefed console by running the 'cts-tradefed'. If you've
+downloaded and extracted the CTS zip, the script can be found at
+  android-cts/tools/cts-tradefed
+Or else if you are working from the Android source tree and have run make cts,
+the script can be found at
+  out/host/linux-x86/cts/android-cts/tools/cts-tradefed
+3. Type:
+'run cts' to run the default CTS plan
+
+Some other useful commands are
+
+To run a test module:
+'run cts --module <module_name>'
+
+To run a specific test:
+'run cts --test <test_name>'
+
+To shard a plan test run on multiple devices
+'run cts --shards <number of shards>
+note: all connected devices must be running the same build
+
+For more options:
+'run cts --help'
+
+CTS Tradefed Development
+------------------------
+See http://source.android.com for instructions on obtaining the Android
+platform source code and setting up a build environment.
+
+The source for the CTS extensions for tradefed can be found at
+<android source root>/cts/tools/tradefed-host
+
+The source for the tradefed framework can be found on the 'tradefed' branch.
+
+Perform these steps to build and run cts-tradefed from the development
+environment:
+cd <path to android source root>
+make cts
+cts-tradefed
+
+More documentation and details on using and extending trade federation will
+be forthcoming in the near future.
+
diff --git a/tools/cts-tradefed/etc/Android.mk b/tools/cts-tradefed/etc/Android.mk
new file mode 100644
index 0000000..1c376db
--- /dev/null
+++ b/tools/cts-tradefed/etc/Android.mk
@@ -0,0 +1,22 @@
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_PREBUILT_EXECUTABLES := cts-tradefed
+include $(BUILD_HOST_PREBUILT)
+
diff --git a/tools/cts-tradefed/etc/cts-tradefed b/tools/cts-tradefed/etc/cts-tradefed
new file mode 100755
index 0000000..b6a036a
--- /dev/null
+++ b/tools/cts-tradefed/etc/cts-tradefed
@@ -0,0 +1,119 @@
+#!/bin/bash
+
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# launcher script for cts-tradefed harness
+# can be used from an Android build environment, or a standalone cts zip
+
+checkFile() {
+    if [ ! -f "$1" ]; then
+        echo "Unable to locate $1"
+        exit
+    fi;
+}
+
+checkPath() {
+    if ! type -P $1 &> /dev/null; then
+        echo "Unable to find $1 in path."
+        exit
+    fi;
+}
+
+checkPath adb
+checkPath java
+
+# check java version
+JAVA_VERSION=$(java -version 2>&1 | head -n 2 | grep '[ "]1\.[678][\. "$$]')
+if [ "${JAVA_VERSION}" == "" ]; then
+    echo "Wrong java version. 1.6, 1.7 or 1.8 is required."
+    exit
+fi
+
+# check debug flag and set up remote debugging
+if [ -n "${TF_DEBUG}" ]; then
+  if [ -z "${TF_DEBUG_PORT}" ]; then
+    TF_DEBUG_PORT=10088
+  fi
+  RDBG_FLAG=-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=${TF_DEBUG_PORT}
+fi
+
+# get OS
+HOST=`uname`
+if [ "$HOST" == "Linux" ]; then
+    OS="linux-x86"
+elif [ "$HOST" == "Darwin" ]; then
+    OS="darwin-x86"
+else
+    echo "Unrecognized OS"
+    exit
+fi
+
+# check if in Android build env
+if [ ! -z "${ANDROID_BUILD_TOP}" ]; then
+    if [ ! -z "${ANDROID_HOST_OUT}" ]; then
+      CTS_ROOT=${ANDROID_HOST_OUT}/cts
+    else
+      CTS_ROOT=${ANDROID_BUILD_TOP}/${OUT_DIR:-out}/host/${OS}/cts
+    fi
+    if [ ! -d ${CTS_ROOT} ]; then
+        echo "Could not find $CTS_ROOT in Android build environment. Try 'make cts'"
+        exit
+    fi;
+fi;
+
+if [ -z ${CTS_ROOT} ]; then
+    # assume we're in an extracted cts install
+    CTS_ROOT="$(dirname $0)/../.."
+fi;
+
+JAR_DIR=${CTS_ROOT}/android-cts/tools
+JARS="tradefed-prebuilt
+  hosttestlib
+  compatibility-host-util
+  cts-tradefed"
+
+for JAR in $JARS; do
+    checkFile ${JAR_DIR}/${JAR}.jar
+    JAR_PATH=${JAR_PATH}:${JAR_DIR}/${JAR}.jar
+done
+
+OPTIONAL_JARS="
+  google-tradefed
+  google-tradefed-tests
+  google-tf-prod-tests"
+
+for JAR in $OPTIONAL_JARS; do
+    if [ -f "$JAR.jar" ]; then
+        JAR_PATH=${JAR_PATH}:${JAR_DIR}/${JAR}.jar
+    fi;
+done
+
+# load any shared libraries for host-side executables
+LIB_DIR=${CTS_ROOT}/android-cts/lib
+if [ "$HOST" == "Linux" ]; then
+    LD_LIBRARY_PATH=${LIB_DIR}:${LIB_DIR}64:${LD_LIBRARY_PATH}
+    export LD_LIBRARY_PATH
+elif [ "$HOST" == "Darwin" ]; then
+    DYLD_LIBRARY_PATH=${LIB_DIR}:${LIB_DIR}64:${DYLD_LIBRARY_PATH}
+    export DYLD_LIBRARY_PATH
+fi
+
+# include any host-side test jars
+for j in ${CTS_ROOT}/android-cts/testcases/*.jar; do
+    JAR_PATH=${JAR_PATH}:$j
+done
+
+java $RDBG_FLAG -cp ${JAR_PATH} -DCTS_ROOT=${CTS_ROOT} com.android.compatibility.common.tradefed.command.CompatibilityConsole "$@"
+
diff --git a/tools/cts-tradefed/res/config/basic-reporters.xml b/tools/cts-tradefed/res/config/basic-reporters.xml
new file mode 100644
index 0000000..6fddf24
--- /dev/null
+++ b/tools/cts-tradefed/res/config/basic-reporters.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Configuration with basic CTS reporters" >
+</configuration>
diff --git a/tools/cts-tradefed/res/config/collect-tests-only.xml b/tools/cts-tradefed/res/config/collect-tests-only.xml
new file mode 100644
index 0000000..25bf4d0
--- /dev/null
+++ b/tools/cts-tradefed/res/config/collect-tests-only.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Runs CTS from a pre-existing CTS installation">
+
+    <include name="cts" />
+
+    <!-- This tells cts-tradefed and the server what the plan name is, reports that have this plan
+         name should not be accepted, as it doesn't actually run the tests it simply marks all of
+         them as passed.
+         Obviously no one would modify the report before uploading to falsify this
+         information, as that would be dishonest, and dishonesty kills kittens :'( -->
+    <option name="compatibility:plan" value="collect-tests-only" />
+
+    <option name="skip-device-info" value="true" />
+    <option name="skip-preconditions" value="true" />
+    <option name="skip-connectivity-check" value="true" />
+    <option name="preparer-whitelist" value="com.android.compatibility.common.tradefed.targetprep.ApkInstaller" />
+    <option name="preparer-whitelist" value="com.android.compatibility.common.tradefed.targetprep.FilePusher" />
+
+    <!-- Tell all AndroidJUnitTests to only list the tests -->
+    <option name="compatibility:test-arg" value="com.android.tradefed.testtype.AndroidJUnitTest:collect-tests-only:true" />
+
+    <!-- Tell all GTests to only list the tests -->
+    <option name="compatibility:test-arg" value="com.android.tradefed.testtype.GTest:collect-tests-only:true" />
+
+    <!-- Tell all HostTests to only list the tests -->
+    <option name="compatibility:test-arg" value="com.android.tradefed.testtype.HostTest:collect-tests-only:true" />
+
+    <!-- Tell all DEQPTests to only list the tests -->
+    <option name="compatibility:test-arg" value="com.drawelements.deqp.runner.DeqpTestRunner:collect-tests-only:true" />
+
+    <!-- Tell all JarHostTests to only list the tests -->
+    <option name="compatibility:test-arg" value="com.android.compatibility.common.tradefed.testtype.JarHostTest:collect-tests-only:true" />
+
+</configuration>
diff --git a/tools/cts-tradefed/res/config/cts-camera.xml b/tools/cts-tradefed/res/config/cts-camera.xml
new file mode 100644
index 0000000..5bc395d
--- /dev/null
+++ b/tools/cts-tradefed/res/config/cts-camera.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Runs CTS-camera from a pre-existing CTS installation">
+
+    <include name="cts" />
+
+    <option name="compatibility:plan" value="cts-camera" />
+
+    <!-- All camera CTS tests -->
+    <option name="compatibility:include-filter" value="CtsCameraTestCases" />
+
+    <!-- Other camera related CTS tests -->
+    <option name="compatibility:include-filter"
+        value="CtsAppTestCases android.app.cts.SystemFeaturesTest#testCameraFeatures"/>
+    <option name="compatibility:include-filter"
+        value="CtsPermissionTestCases android.permission.cts.CameraPermissionTest"/>
+    <option name="compatibility:include-filter"
+        value="CtsPermissionTestCases android.permission.cts.Camera2PermissionTest"/>
+
+</configuration>
diff --git a/tools/cts-tradefed/res/config/cts-filtered-sample.xml b/tools/cts-tradefed/res/config/cts-filtered-sample.xml
new file mode 100644
index 0000000..73b98c5
--- /dev/null
+++ b/tools/cts-tradefed/res/config/cts-filtered-sample.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Runs CTS from a pre-existing CTS installation">
+
+    <include name="common-compatibility-config" />
+
+    <option name="compatibility:plan" value="cts-filtered-sample" />
+
+    <!-- Tell all AndroidJUnitTests to only run the medium sized tests -->
+    <option name="compatibility:test-arg" value="com.android.tradefed.testtype.AndroidJUnitTest:size:medium" />
+
+    <!-- Tell 64bit CtsContentTestCases which timeout to use -->
+    <option name="compatibility:module-arg" value="arm64-v8a CtsContentTestCases:test-timeout:600" />
+
+    <!-- Include CtsGestureTestCases but only run the tests on arm32 -->
+    <option name="compatibility:include-filter" value="armeabi-v7a CtsGestureTestCases" />
+
+    <!-- Exclude CtsMediaStressTestCases -->
+    <option name="compatibility:exclude-filter" value="CtsMediaStressTestCases" />
+
+    <!-- Include CtsUtilTestCases but only run the small tests -->
+    <option name="compatibility:module-arg" value="CtsUtilTestCases:size:small" />
+
+</configuration>
diff --git a/tools/cts-tradefed/res/config/cts-java.xml b/tools/cts-tradefed/res/config/cts-java.xml
new file mode 100644
index 0000000..52c25c9
--- /dev/null
+++ b/tools/cts-tradefed/res/config/cts-java.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Runs Core Java Tests from a pre-existing CTS installation">
+
+    <include name="cts" />
+
+    <option name="compatibility:plan" value="cts-java" />
+
+    <!-- Include CtsLibcoreTestCases -->
+    <option name="compatibility:include-filter" value="CtsLibcoreTestCases" />
+
+    <!-- Exclude CtsLibcoreTestCases harmony -->
+    <option name="compatibility:exclude-filter" value="CtsLibcoreTestCases android.core.tests.libcore.package.harmony" />
+
+</configuration>
diff --git a/tools/cts-tradefed/res/config/cts-known-failures.xml b/tools/cts-tradefed/res/config/cts-known-failures.xml
new file mode 100644
index 0000000..4d656b1
--- /dev/null
+++ b/tools/cts-tradefed/res/config/cts-known-failures.xml
@@ -0,0 +1,218 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Configuration with CTS known failures" >
+    <!-- <option name="compatibility:exclude-filter" value="MODULE_NAME" /> Excludes whole module -->
+    <!-- <option name="compatibility:exclude-filter" value="MODULE_NAME PACKAGE_NAME" /> Excludes whole package -->
+    <!-- <option name="compatibility:exclude-filter" value="MODULE_NAME PACKAGE_NAME.CLASS_NAME" /> Excludes whole class -->
+    <!-- <option name="compatibility:exclude-filter" value="MODULE_NAME PACKAGE_NAME.CLASS_NAME#TEST_NAME" /> Excludes individual test -->
+
+    <!-- b/17595050 -->
+    <option name="compatibility:exclude-filter" value="CtsAccessibilityServiceTestCases android.accessibilityservice.cts.AccessibilityTextTraversalTest#testActionNextAndPreviousAtGranularityPageOverText" />
+    <option name="compatibility:exclude-filter" value="CtsAccessibilityServiceTestCases android.accessibilityservice.cts.AccessibilityTextTraversalTest#testActionNextAndPreviousAtGranularityPageOverTextExtend" />
+
+    <!-- b/17508787 -->
+    <option name="compatibility:exclude-filter" value="CtsAdminTestCases android.admin.cts.DevicePolicyManagerTest#testUninstallAllUserCaCerts_failIfNotProfileOwner" />
+
+    <!-- b/23776083 -->
+    <option name="compatibility:exclude-filter" value="CtsAlarmClockTestCases android.alarmclock.cts.DismissAlarmTest#testAll" />
+    <option name="compatibility:exclude-filter" value="CtsAlarmClockTestCases android.alarmclock.cts.SetAlarmTest#testAll" />
+    <option name="compatibility:exclude-filter" value="CtsAlarmClockTestCases android.alarmclock.cts.SnoozeAlarmTest#testAll" />
+
+    <!-- b/17993121 -->
+    <option name="compatibility:exclude-filter" value="CtsAppWidgetTestCases android.appwidget.cts.AppWidgetTest#testAppWidgetProviderCallbacks" />
+    <option name="compatibility:exclude-filter" value="CtsAppWidgetTestCases android.appwidget.cts.AppWidgetTest#testBindAppWidget" />
+    <option name="compatibility:exclude-filter" value="CtsAppWidgetTestCases android.appwidget.cts.AppWidgetTest#testCollectionWidgets" />
+    <option name="compatibility:exclude-filter" value="CtsAppWidgetTestCases android.appwidget.cts.AppWidgetTest#testDeleteHost" />
+    <option name="compatibility:exclude-filter" value="CtsAppWidgetTestCases android.appwidget.cts.AppWidgetTest#testDeleteHosts" />
+    <option name="compatibility:exclude-filter" value="CtsAppWidgetTestCases android.appwidget.cts.AppWidgetTest#testGetAppWidgetIds" />
+    <option name="compatibility:exclude-filter" value="CtsAppWidgetTestCases android.appwidget.cts.AppWidgetTest#testGetAppWidgetInfo" />
+    <option name="compatibility:exclude-filter" value="CtsAppWidgetTestCases android.appwidget.cts.AppWidgetTest#testGetAppWidgetOptions" />
+    <option name="compatibility:exclude-filter" value="CtsAppWidgetTestCases android.appwidget.cts.AppWidgetTest#testPartiallyUpdateAppWidgetViaWidgetId" />
+    <option name="compatibility:exclude-filter" value="CtsAppWidgetTestCases android.appwidget.cts.AppWidgetTest#testPartiallyUpdateAppWidgetViaWidgetIds" />
+    <option name="compatibility:exclude-filter" value="CtsAppWidgetTestCases android.appwidget.cts.AppWidgetTest#testTwoAppWidgetProviderCallbacks" />
+    <option name="compatibility:exclude-filter" value="CtsAppWidgetTestCases android.appwidget.cts.AppWidgetTest#testUpdateAppWidgetViaComponentName" />
+    <option name="compatibility:exclude-filter" value="CtsAppWidgetTestCases android.appwidget.cts.AppWidgetTest#testUpdateAppWidgetViaWidgetId" />
+    <option name="compatibility:exclude-filter" value="CtsAppWidgetTestCases android.appwidget.cts.AppWidgetTest#testUpdateAppWidgetViaWidgetIds" />
+
+    <!-- b/21668302 -->
+    <option name="compatibility:exclude-filter" value="CtsAssistTestCases android.assist.cts.AssistantContentViewTest#testAssistantContentViewDimens" />
+    <option name="compatibility:exclude-filter" value="CtsAssistTestCases android.assist.cts.ExtraAssistDataTest#testAssistContentAndAssistData" />
+    <option name="compatibility:exclude-filter" value="CtsAssistTestCases android.assist.cts.FocusChangeTest#testLayerCausesUnderlyingActivityToLoseFocus" />
+    <option name="compatibility:exclude-filter" value="CtsAssistTestCases android.assist.cts.LargeViewHierarchyTest#testTextView" />
+    <option name="compatibility:exclude-filter" value="CtsAssistTestCases android.assist.cts.ScreenshotTest#testBlueScreenshot" />
+    <option name="compatibility:exclude-filter" value="CtsAssistTestCases android.assist.cts.ScreenshotTest#testGreenScreenshot" />
+    <option name="compatibility:exclude-filter" value="CtsAssistTestCases android.assist.cts.ScreenshotTest#testRedScreenshot" />
+    <option name="compatibility:exclude-filter" value="CtsAssistTestCases android.assist.cts.TextViewTest#testTextView" />
+    <option name="compatibility:exclude-filter" value="CtsAssistTestCases android.assist.cts.WebViewTest#testWebView" />
+
+    <!-- b/23776099 -->
+    <option name="compatibility:exclude-filter" value="CtsCallLogTestCases android.calllog.cts.CallLogBackupTest#testSingleCallBackup" />
+
+    <!-- b/17530117 -->
+    <option name="compatibility:exclude-filter" value="CtsCameraTestCases android.hardware.camera2.cts.AllocationTest#testBlackWhite" />
+    <option name="compatibility:exclude-filter" value="CtsCameraTestCases android.hardware.camera2.cts.AllocationTest#testParamSensitivity" />
+    <!-- b/17989532 -->
+    <option name="compatibility:exclude-filter" value="CtsCameraTestCases android.hardware.camera2.cts.SurfaceViewPreviewTest#testPreparePerformance" />
+    <!-- b/23008511 -->
+    <option name="compatibility:exclude-filter" value="CtsCameraTestCases android.hardware.cts.CameraTest#testPreviewFpsRange" />
+
+    <option name="compatibility:exclude-filter" value="CtsCarTestCases" />
+
+    <!-- b/27578806 -->
+    <option name="compatibility:exclude-filter" value="CtsCppToolsTestCases com.android.cts.cpptools.RunAsHostTest#testRunAs" />
+
+    <!-- b/23776893 -->
+    <option name="compatibility:exclude-filter" value="CtsDumpsysHostTestCases android.dumpsys.cts.DumpsysHostTest#testBatterystatsOutput" />
+    <option name="compatibility:exclude-filter" value="CtsDumpsysHostTestCases android.dumpsys.cts.DumpsysHostTest#testGfxinfoFramestats" />
+
+    <!-- b/22922206 b/27534791 -->
+    <option name="compatibility:exclude-filter" value="CtsHardwareTestCases android.hardware.cts.SensorBatchingTests#testAccelerometer_50hz_batching" />
+    <option name="compatibility:exclude-filter" value="CtsHardwareTestCases android.hardware.cts.SensorBatchingTests#testAccelerometer_fastest_batching" />
+    <option name="compatibility:exclude-filter" value="CtsHardwareTestCases android.hardware.cts.SensorBatchingTests#testGravity_50hz_batching" />
+    <option name="compatibility:exclude-filter" value="CtsHardwareTestCases android.hardware.cts.SensorBatchingTests#testGravity_fastest_batching" />
+    <option name="compatibility:exclude-filter" value="CtsHardwareTestCases android.hardware.cts.SensorBatchingTests#testGyroscope_50hz_batching" />
+    <option name="compatibility:exclude-filter" value="CtsHardwareTestCases android.hardware.cts.SensorBatchingTests#testGyroscope_50hz_flush" />
+    <option name="compatibility:exclude-filter" value="CtsHardwareTestCases android.hardware.cts.SensorBatchingTests#testGyroscope_fastest_batching" />
+    <option name="compatibility:exclude-filter" value="CtsHardwareTestCases android.hardware.cts.SensorBatchingTests#testLinearAcceleration_50hz_batching" />
+    <option name="compatibility:exclude-filter" value="CtsHardwareTestCases android.hardware.cts.SensorBatchingTests#testLinearAcceleration_fastest_batching" />
+    <option name="compatibility:exclude-filter" value="CtsHardwareTestCases android.hardware.cts.SensorBatchingTests#testMagneticField_50hz_batching" />
+    <option name="compatibility:exclude-filter" value="CtsHardwareTestCases android.hardware.cts.SensorBatchingTests#testMagneticField_fastest_batching" />
+    <option name="compatibility:exclude-filter" value="CtsHardwareTestCases android.hardware.cts.SensorBatchingTests#testMagneticFieldUncalibrated_50hz_batching" />
+    <option name="compatibility:exclude-filter" value="CtsHardwareTestCases android.hardware.cts.SensorBatchingTests#testMagneticFieldUncalibrated_fastest_batching" />
+    <option name="compatibility:exclude-filter" value="CtsHardwareTestCases android.hardware.cts.SensorBatchingTests#testPressure_50hz_batching" />
+    <option name="compatibility:exclude-filter" value="CtsHardwareTestCases android.hardware.cts.SensorBatchingTests#testPressure_fastest_batching" />
+    <option name="compatibility:exclude-filter" value="CtsHardwareTestCases android.hardware.cts.SensorBatchingTests#testRotationVector_50hz_batching" />
+    <option name="compatibility:exclude-filter" value="CtsHardwareTestCases android.hardware.cts.SensorBatchingTests#testRotationVector_50hz_flush" />
+    <option name="compatibility:exclude-filter" value="CtsHardwareTestCases android.hardware.cts.SensorBatchingTests#testRotationVector_fastest_batching" />
+    <option name="compatibility:exclude-filter" value="CtsHardwareTestCases android.hardware.cts.SensorIntegrationTests#testSensorsMovingRates" />
+    <option name="compatibility:exclude-filter" value="CtsHardwareTestCases android.hardware.cts.SensorIntegrationTests#testSensorsWithSeveralClients" />
+    <option name="compatibility:exclude-filter" value="CtsHardwareTestCases android.hardware.cts.SensorTest#testBatchAndFlush" />
+    <option name="compatibility:exclude-filter" value="CtsHardwareTestCases android.hardware.cts.SensorTest#testSensorTimeStamps" />
+    <option name="compatibility:exclude-filter" value="CtsHardwareTestCases android.hardware.cts.SingleSensorTests#testGyroscope_15hz" />
+    <option name="compatibility:exclude-filter" value="CtsHardwareTestCases android.hardware.cts.SingleSensorTests#testGyroscope_1hz" />
+    <option name="compatibility:exclude-filter" value="CtsHardwareTestCases android.hardware.cts.SingleSensorTests#testMagneticField_1hz" />
+    <option name="compatibility:exclude-filter" value="CtsHardwareTestCases android.hardware.cts.SingleSensorTests#testMagneticField_50hz" />
+    <option name="compatibility:exclude-filter" value="CtsHardwareTestCases android.hardware.cts.SingleSensorTests#testMagneticFieldUncalibrated_200hz" />
+    <option name="compatibility:exclude-filter" value="CtsHardwareTestCases android.hardware.cts.SingleSensorTests#testOrientation_5hz" />
+
+    <!-- b/16720689 -->
+    <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.DebuggerOnDemand.OnthrowDebuggerLaunchTest#testDebuggerLaunch001" />
+    <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.DebuggerOnDemand.OnthrowDebuggerLaunchTest#testDebuggerLaunch002" />
+    <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.DebuggerOnDemand.OnthrowDebuggerLaunchTest#testDebuggerLaunch003" />
+    <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.DebuggerOnDemand.OnthrowDebuggerLaunchTest#testDebuggerLaunch004" />
+    <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.DebuggerOnDemand.OnthrowLaunchDebugger001#testDebugger002" />
+    <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.DebuggerOnDemand.OnthrowLaunchDebugger002#testDebugger" />
+    <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.Events.ClassUnloadTest#testClassUnloadEvent" />
+    <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.Events.MonitorContendedEnteredTest#testMonitorContendedEnteredForClassMatch" />
+    <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.Events.MonitorContendedEnterTest#testMonitorContendedEnterForClassMatch" />
+    <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.Events.MonitorWaitedTest#testMonitorWaitedForClassExclude" />
+    <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.Events.MonitorWaitedTest#testMonitorWaitedForClassMatchExact" />
+    <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.Events.MonitorWaitedTest#testMonitorWaitedForClassMatchFirst" />
+    <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.Events.MonitorWaitedTest#testMonitorWaitedForClassMatchSecond" />
+    <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.Events.MonitorWaitedTest#testMonitorWaitedForClassOnly" />
+    <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.Events.MonitorWaitTest#testMonitorWaitForClassExclude" />
+    <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.Events.MonitorWaitTest#testMonitorWaitForClassMatchExact" />
+    <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.Events.MonitorWaitTest#testMonitorWaitForClassMatchFirst" />
+    <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.Events.MonitorWaitTest#testMonitorWaitForClassMatchSecond" />
+    <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.Events.MonitorWaitTest#testMonitorWaitForClassOnly" />
+    <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.ReferenceType.ClassFileVersionTest#testClassFileVersion001" />
+    <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.ReferenceType.NestedTypesTest#testNestedTypes001" />
+    <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.ThreadReference.StopTest#testStop001" />
+    <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.VirtualMachine.HoldEventsTest#testHoldEvents001" />
+    <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.VirtualMachine.ReleaseEventsTest#testReleaseEvents001" />
+
+    <!-- b/18117279 b/21262226 b/23144425 -->
+    <option name="compatibility:exclude-filter" value="CtsJobSchedulerTestCases android.jobscheduler.cts.ConnectivityConstraintTest#testConnectivityConstraintExecutes_withMobile" />
+    <option name="compatibility:exclude-filter" value="CtsJobSchedulerTestCases android.jobscheduler.cts.ConnectivityConstraintTest#testConnectivityConstraintExecutes_withWifi" />
+    <option name="compatibility:exclude-filter" value="CtsJobSchedulerTestCases android.jobscheduler.cts.ConnectivityConstraintTest#testUnmeteredConstraintExecutes_withWifi" />
+    <option name="compatibility:exclude-filter" value="CtsJobSchedulerTestCases android.jobscheduler.cts.ConnectivityConstraintTest#testUnmeteredConstraintFails_withMobile" />
+    <option name="compatibility:exclude-filter" value="CtsJobSchedulerTestCases android.jobscheduler.cts.TimingConstraintsTest#testJobParameters_unexpiredDeadline" />
+
+    <!-- b/25850508 -->
+    <option name="compatibility:exclude-filter" value="CtsMediaStressTestCases android.mediastress.cts.preconditions.MediaPreparerTest#testCopyMediaFiles" />
+    <option name="compatibility:exclude-filter" value="CtsMediaStressTestCases android.mediastress.cts.preconditions.MediaPreparerTest#testGetMaxVideoPlaybackResolutionFound" />
+    <option name="compatibility:exclude-filter" value="CtsMediaStressTestCases android.mediastress.cts.preconditions.MediaPreparerTest#testGetMaxVideoPlaybackResolutionNotFound" />
+    <option name="compatibility:exclude-filter" value="CtsMediaStressTestCases android.mediastress.cts.preconditions.MediaPreparerTest#testMediaFilesExistOnDeviceFalse" />
+    <option name="compatibility:exclude-filter" value="CtsMediaStressTestCases android.mediastress.cts.preconditions.MediaPreparerTest#testMediaFilesExistOnDeviceTrue" />
+    <option name="compatibility:exclude-filter" value="CtsMediaStressTestCases android.mediastress.cts.preconditions.MediaPreparerTest#testSetMountPoint" />
+    <option name="compatibility:exclude-filter" value="CtsMediaStressTestCases android.mediastress.cts.preconditions.MediaPreparerTest#testSkipMediaDownload" />
+
+    <!-- b/17144778 -->
+    <option name="compatibility:exclude-filter" value="CtsMediaTestCases android.media.cts.ImageReaderDecoderTest#testHwAVCDecode360pForFlexibleYuv" />
+    <!-- b/23827982 -->
+    <option name="compatibility:exclude-filter" value="CtsMediaTestCases android.media.cts.VideoEncoderTest#testGoogH264FlexArbitraryW" />
+    <option name="compatibility:exclude-filter" value="CtsMediaTestCases android.media.cts.VideoEncoderTest#testGoogH264SurfArbitraryW" />
+
+    <!-- b/25651805 -->
+    <option name="compatibility:exclude-filter" value="CtsNetTestCases android.net.cts.ConnectivityManagerTest#testRestrictedNetworks" />
+    <!-- b/18682315 -->
+    <option name="compatibility:exclude-filter" value="CtsNetTestCases android.net.cts.SSLCertificateSocketFactoryTest#testCreateSocket" />
+    <option name="compatibility:exclude-filter" value="CtsNetTestCases android.net.cts.SSLCertificateSocketFactoryTest#test_createSocket_bind" />
+    <option name="compatibility:exclude-filter" value="CtsNetTestCases android.net.cts.SSLCertificateSocketFactoryTest#test_createSocket_simple" />
+    <option name="compatibility:exclude-filter" value="CtsNetTestCases android.net.cts.SSLCertificateSocketFactoryTest#test_createSocket_wrapping" />
+
+    <!-- b/17394321 -->
+    <option name="compatibility:exclude-filter" value="CtsOpenGlPerfTestCases android.openglperf.cts.GlAppSwitchTest#testGlActivitySwitchingFast" />
+    <option name="compatibility:exclude-filter" value="CtsOpenGlPerfTestCases android.openglperf.cts.GlAppSwitchTest#testGlActivitySwitchingSlow" />
+
+    <!-- b/18091590 -->
+    <option name="compatibility:exclude-filter" value="CtsOpenGlPerfTestCases android.openglperf.cts.GlVboPerfTest#testVboWithVaryingIndexBufferNumbers" />
+
+    <!-- b/23192492 -->
+    <option name="compatibility:exclude-filter" value="CtsPermission2TestCases android.permission2.cts.ProtectedBroadcastsTest#testSendProtectedBroadcasts" />
+
+    <option name="compatibility:exclude-filter" value="CtsSampleDeviceTestCases" />
+    <option name="compatibility:exclude-filter" value="CtsSampleHostTestCases" />
+
+    <!-- b/18461670 -->
+    <option name="compatibility:exclude-filter" value="CtsSecurityTestCases android.security.cts.AudioPolicyBinderTest#test_getStreamVolumeLeak" />
+    <option name="compatibility:exclude-filter" value="CtsSecurityTestCases android.security.cts.AudioPolicyBinderTest#test_isStreamActive" />
+    <option name="compatibility:exclude-filter" value="CtsSecurityTestCases android.security.cts.AudioPolicyBinderTest#test_isStreamActiveRemotely" />
+    <option name="compatibility:exclude-filter" value="CtsSecurityTestCases android.security.cts.AudioPolicyBinderTest#test_startAudioSource" />
+    <option name="compatibility:exclude-filter" value="CtsSecurityTestCases android.security.cts.AudioPolicyBinderTest#test_startOutput" />
+    <option name="compatibility:exclude-filter" value="CtsSecurityTestCases android.security.cts.AudioPolicyBinderTest#test_stopOutput" />
+    <!-- b/27218502 -->
+    <option name="compatibility:exclude-filter" value="CtsSecurityTestCases android.security.cts.MediaCryptoTest#testMediaCryptoClearKey" />
+    <option name="compatibility:exclude-filter" value="CtsSecurityTestCases android.security.cts.MediaCryptoTest#testMediaCryptoWidevine" />
+
+    <!-- b/26150806 -->
+    <option name="compatibility:exclude-filter" value="CtsSignatureTestCases android.signature.cts.tests" />
+
+    <!-- b/23427621 -->
+    <option name="compatibility:exclude-filter" value="CtsSystemUiTestCases android.systemui.cts.LightStatusBarTests#testLightStatusBarIcons" />
+
+    <!-- b/23604254 -->
+    <option name="compatibility:exclude-filter" value="CtsTelecomTestCases android.telecom.cts.ExtendedInCallServiceTest#testAddNewOutgoingCallAndThenDisconnect" />
+    <option name="compatibility:exclude-filter" value="CtsTelecomTestCases android.telecom.cts.RemoteConferenceTest#testRemoteConferenceCallbacks_ConferenceableConnections" />
+
+    <!-- b/23979591 -->
+    <option name="compatibility:exclude-filter" value="CtsTelephonyTestCases android.telephony.cts.CellInfoTest#testCellInfo" />
+
+    <!-- b/23779020 -->
+    <option name="compatibility:exclude-filter" value="CtsTransitionTestCases android.transition.cts.ChangeScrollTest#testChangeScroll" />
+
+    <!-- b/17536113 -->
+    <option name="compatibility:exclude-filter" value="CtsUsageStatsTestCases android.app.usage.cts.UsageStatsTest#testNoAccessSilentlyFails" />
+    <option name="compatibility:exclude-filter" value="CtsUsageStatsTestCases android.app.usage.cts.UsageStatsTest#testOrderedActivityLaunchSequenceInEventLog" />
+    <option name="compatibility:exclude-filter" value="CtsUsageStatsTestCases android.app.usage.cts.UsageStatsTest#testPackageUsageStatsIntervals" />
+    <option name="compatibility:exclude-filter" value="CtsUsageStatsTestCases android.app.usage.cts.UsageStatsTest#testUsageEventsParceling" />
+
+    <!-- b/23238984 -->
+    <option name="compatibility:exclude-filter" value="CtsVoiceSettingsTestCases android.voicesettings.cts.ZenModeTest#testAll" />
+
+    <!-- b/26235244 -->
+    <option name="compatibility:exclude-filter" value="android.util.cts.EventLogTest#testWriteEventWithOversizeValue" />
+</configuration>
diff --git a/tools/cts-tradefed/res/config/cts-pdk.xml b/tools/cts-tradefed/res/config/cts-pdk.xml
new file mode 100644
index 0000000..32dcecc
--- /dev/null
+++ b/tools/cts-tradefed/res/config/cts-pdk.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Runs Tests useful on validating a PDK fusion build">
+
+    <include name="cts" />
+
+    <option name="compatibility:plan" value="cts-pdk" />
+
+    <!-- Include test modules -->
+    <option name="compatibility:include-filter" value="CtsAadbHostTestCases" />
+    <option name="compatibility:include-filter" value="CtsBluetoothTestCases" />
+    <option name="compatibility:include-filter" value="CtsGraphicsTestCases" />
+    <option name="compatibility:include-filter" value="CtsGraphics2TestCases" />
+    <option name="compatibility:include-filter" value="CtsHardwareTestCases" />
+    <option name="compatibility:include-filter" value="CtsMediaTestCases" />
+    <option name="compatibility:include-filter" value="CtsNetTestCases" />
+    <option name="compatibility:include-filter" value="CtsDeqpTestCases" />
+    <option name="compatibility:include-filter" value="CtsRenderscriptTestCases" />
+    <option name="compatibility:include-filter" value="CtsRenderscriptLegacyTestCases" />
+    <option name="compatibility:include-filter" value="CtsTelephonyTestCases" />
+    <option name="compatibility:include-filter" value="CtsTelephony2TestCases" />
+    <option name="compatibility:include-filter" value="CtsRsBlasTestCases" />
+    <option name="compatibility:include-filter" value="CtsNativeMediaSlTestCases" />
+    <option name="compatibility:include-filter" value="CtsNativeMediaXaTestCases" />
+
+</configuration>
diff --git a/tools/cts-tradefed/res/config/cts-preconditions.xml b/tools/cts-tradefed/res/config/cts-preconditions.xml
new file mode 100644
index 0000000..cc71524
--- /dev/null
+++ b/tools/cts-tradefed/res/config/cts-preconditions.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="CTS precondition configs">
+
+    <option name="compatibility:plan" value="cts-preconditions" />
+
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.DynamicConfigPusher">
+        <option name="target" value="host" />
+        <option name="config-filename" value="cts"/>
+        <option name="version" value="1.0"/>
+    </target_preparer>
+
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.StayAwakePreparer" />
+
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.SettingsPreparer">
+        <option name="device-setting" value="verifier_verify_adb_installs"/>
+        <option name="setting-type" value="global"/>
+        <option name="set-value" value="0"/>
+    </target_preparer>
+
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkPreconditionCheck">
+        <option name="apk" value="CtsPreconditions.apk"/>
+        <option name="package" value="com.android.preconditions.cts"/>
+    </target_preparer>
+
+    <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+        <option name="run-command" value="rm -rf /sdcard/device-info-files" />
+        <option name="run-command" value="rm -rf /sdcard/report-log-files" />
+    </target_preparer>
+
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.DeviceInfoCollector">
+        <option name="apk" value="CtsDeviceInfo.apk"/>
+        <option name="package" value="com.android.compatibility.common.deviceinfo"/>
+        <option name="src-dir" value="/sdcard/device-info-files/"/>
+        <option name="dest-dir" value="device-info-files/"/>
+    </target_preparer>
+
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ReportLogCollector">
+        <option name="src-dir" value="/sdcard/report-log-files/"/>
+        <option name="dest-dir" value="report-log-files/"/>
+        <option name="temp-dir" value="temp-report-logs/"/>
+    </target_preparer>
+
+</configuration>
diff --git a/tools/cts-tradefed/res/config/cts.xml b/tools/cts-tradefed/res/config/cts.xml
new file mode 100644
index 0000000..2eb0c3e
--- /dev/null
+++ b/tools/cts-tradefed/res/config/cts.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Runs CTS from a pre-existing CTS installation">
+
+    <include name="everything" />
+    <include name="cts-preconditions" />
+    <include name="cts-known-failures" />
+
+    <option name="compatibility:plan" value="cts" />
+
+    <option name="enable-root" value="false" />
+
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.PropertyCheck">
+        <option name="property-name" value="ro.build.type" />
+        <option name="expected-value" value="user"/> <!-- Device should have user build -->
+        <option name="throw-error" value="false"/> <!-- Only print warning if not user build -->
+    </target_preparer>
+
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.PropertyCheck">
+        <option name="property-name" value="ro.product.locale" />
+        <option name="expected-value" value="en-US"/> <!-- Device locale should be US English -->
+        <option name="throw-error" value="false"/> <!-- Only print warning if not en-US -->
+    </target_preparer>
+    <template-include name="reporters" default="basic-reporters" />
+
+</configuration>
diff --git a/tools/cts-tradefed/tests/Android.mk b/tools/cts-tradefed/tests/Android.mk
new file mode 100644
index 0000000..280cdfb
--- /dev/null
+++ b/tools/cts-tradefed/tests/Android.mk
@@ -0,0 +1,25 @@
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_MODULE := cts-tradefed-tests
+LOCAL_MODULE_TAGS := optional
+LOCAL_JAVA_LIBRARIES := tradefed-prebuilt cts-tradefed
+
+include $(BUILD_HOST_JAVA_LIBRARY)
\ No newline at end of file
diff --git a/tools/cts-tradefed/tests/run_tests.sh b/tools/cts-tradefed/tests/run_tests.sh
new file mode 100755
index 0000000..64f4bb6
--- /dev/null
+++ b/tools/cts-tradefed/tests/run_tests.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Helper script for running unit tests for compatibility libraries
+
+CTS_DIR=$(dirname ${0})/../../..
+source ${CTS_DIR}/test_defs.sh
+
+JARS="
+    compatibility-common-util-hostsidelib\
+    compatibility-host-util\
+    cts-tradefed-tests\
+    cts-tradefed"
+
+run_tests "com.android.compatibility.tradefed.CtsTradefedTest" "${JARS}" "${@}"
diff --git a/tools/cts-tradefed/tests/src/com/android/compatibility/tradefed/CtsTradefedTest.java b/tools/cts-tradefed/tests/src/com/android/compatibility/tradefed/CtsTradefedTest.java
new file mode 100644
index 0000000..651ee39
--- /dev/null
+++ b/tools/cts-tradefed/tests/src/com/android/compatibility/tradefed/CtsTradefedTest.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.tradefed;
+
+import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
+import com.android.compatibility.common.tradefed.build.CompatibilityBuildProvider;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.util.FileUtil;
+
+import junit.framework.TestCase;
+
+import java.io.File;
+
+/**
+ * Tests for cts-tradefed.
+ */
+public class CtsTradefedTest extends TestCase {
+
+    private static final String PROPERTY_NAME = "CTS_ROOT";
+    private static final String SUITE_FULL_NAME = "Compatibility Test Suite";
+    private static final String SUITE_NAME = "CTS";
+    private static final String SUITE_PLAN = "cts";
+    private static final String DYNAMIC_CONFIG_URL = "";
+
+    public void testSuiteInfoLoad() throws Exception {
+        // Test the values in the manifest can be loaded
+        File root = FileUtil.createTempDir("root");
+        System.setProperty(PROPERTY_NAME, root.getAbsolutePath());
+        File base = new File(root, "android-cts");
+        base.mkdirs();
+        File tests = new File(base, "testcases");
+        tests.mkdirs();
+        CompatibilityBuildProvider provider = new CompatibilityBuildProvider();
+        IBuildInfo info = provider.getBuild();
+        CompatibilityBuildHelper helper = new CompatibilityBuildHelper(info);
+        helper.init(SUITE_PLAN, DYNAMIC_CONFIG_URL);
+        assertEquals("Incorrect suite full name", SUITE_FULL_NAME, helper.getSuiteFullName());
+        assertEquals("Incorrect suite name", SUITE_NAME, helper.getSuiteName());
+        FileUtil.recursiveDelete(root);
+        System.clearProperty(PROPERTY_NAME);
+    }
+}
diff --git a/tools/cts-xml-generator/src/Android.mk b/tools/cts-xml-generator/src/Android.mk
index a6d85b6..94c561b 100644
--- a/tools/cts-xml-generator/src/Android.mk
+++ b/tools/cts-xml-generator/src/Android.mk
@@ -18,15 +18,13 @@
 # ============================================================
 include $(CLEAR_VARS)
 
-LOCAL_SRC_FILES := \
-    $(call all-subdir-java-files) \
-    ../../../libs/commonutil/src/com/android/cts/util/AbiUtils.java
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
 
 LOCAL_JAR_MANIFEST := MANIFEST.mf
 
 LOCAL_MODULE := cts-xml-generator
 LOCAL_MODULE_TAGS := optional
 
-LOCAL_STATIC_JAVA_LIBRARIES := vogarexpectlib
+LOCAL_STATIC_JAVA_LIBRARIES := vogarexpectlib compatibility-host-util
 
 include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/TestCase.java b/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/TestCase.java
index ed09b8e..c680c2a 100644
--- a/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/TestCase.java
+++ b/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/TestCase.java
@@ -46,4 +46,8 @@
     public int compareTo(TestCase another) {
         return getName().compareTo(another.getName());
     }
+
+    public int countTests() {
+        return mTests.size();
+    }
 }
diff --git a/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/TestSuite.java b/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/TestSuite.java
index 466f8d7..1d71e1f 100644
--- a/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/TestSuite.java
+++ b/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/TestSuite.java
@@ -66,4 +66,15 @@
     public int compareTo(TestSuite another) {
         return getName().compareTo(another.getName());
     }
+
+    public int countTests() {
+        int count = 0;
+        for (TestSuite suite : mSuites.values()) {
+            count += suite.countTests();
+        }
+        for (TestCase testCase : mCases) {
+            count += testCase.countTests();
+        }
+        return count;
+    }
 }
diff --git a/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/XmlGenerator.java b/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/XmlGenerator.java
index 328b855..f139053 100644
--- a/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/XmlGenerator.java
+++ b/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/XmlGenerator.java
@@ -16,12 +16,12 @@
 
 package com.android.cts.xmlgenerator;
 
-import com.android.cts.util.AbiUtils;
-
 import vogar.Expectation;
 import vogar.ExpectationStore;
 import vogar.Result;
 
+import com.android.compatibility.common.util.AbiUtils;
+
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
@@ -166,6 +166,9 @@
             StringBuilder nameCollector) {
         Collection<TestSuite> sorted = sortCollection(suites);
         for (TestSuite suite : sorted) {
+            if (suite.countTests() == 0) {
+                continue;
+            }
             writer.append("<TestSuite name=\"").append(suite.getName()).println("\">");
 
             String namePart = suite.getName();
@@ -187,6 +190,9 @@
             StringBuilder nameCollector) {
         Collection<TestCase> sorted = sortCollection(cases);
         for (TestCase testCase : sorted) {
+            if (testCase.countTests() == 0) {
+                continue;
+            }
             String name = testCase.getName();
             writer.append("<TestCase name=\"").append(name).println("\">");
             nameCollector.append('.').append(name);
@@ -259,7 +265,7 @@
         String[] unsupportedAbis = description.split(":")[1].split(",");
         for (String a : unsupportedAbis) {
             String abi = a.trim();
-            if (!AbiUtils.isAbiSupportedByCts(abi)) {
+            if (!AbiUtils.isAbiSupportedByCompatibility(abi)) {
                 throw new RuntimeException(
                         String.format("Unrecognised ABI %s in %s", abi, description));
             }
diff --git a/tools/selinux/SELinuxNeverallowTestFrame.py b/tools/selinux/SELinuxNeverallowTestFrame.py
index 45900de..f1219c1 100644
--- a/tools/selinux/SELinuxNeverallowTestFrame.py
+++ b/tools/selinux/SELinuxNeverallowTestFrame.py
@@ -18,55 +18,52 @@
 
 package android.cts.security;
 
-import com.android.cts.tradefed.build.CtsBuildHelper;
+import com.android.cts.migration.MigrationHelper;
 import com.android.tradefed.build.IBuildInfo;
 import com.android.tradefed.device.ITestDevice;
 import com.android.tradefed.testtype.DeviceTestCase;
 import com.android.tradefed.testtype.IBuildReceiver;
+import com.android.tradefed.testtype.IDeviceTest;
 
 import java.io.BufferedReader;
 import java.io.File;
-import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
-import java.io.FileOutputStream;
-import java.lang.String;
-import java.net.URL;
-import java.util.Scanner;
 
 /**
  * Neverallow Rules SELinux tests.
  */
-public class SELinuxNeverallowRulesTest extends DeviceTestCase {
+public class SELinuxNeverallowRulesTest extends DeviceTestCase implements IBuildReceiver, IDeviceTest {
     private File sepolicyAnalyze;
     private File devicePolicyFile;
 
+    private IBuildInfo mBuild;
+
     /**
      * A reference to the device under test.
      */
     private ITestDevice mDevice;
 
-    private File copyResourceToTempFile(String resName) throws IOException {
-        InputStream is = this.getClass().getResourceAsStream(resName);
-        File tempFile = File.createTempFile("SELinuxHostTest", ".tmp");
-        FileOutputStream os = new FileOutputStream(tempFile);
-        int rByte = 0;
-        while ((rByte = is.read()) != -1) {
-            os.write(rByte);
-        }
-        os.flush();
-        os.close();
-        tempFile.deleteOnExit();
-        return tempFile;
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setBuild(IBuildInfo build) {
+        mBuild = build;
     }
 
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setDevice(ITestDevice device) {
+        super.setDevice(device);
+        mDevice = device;
+    }
     @Override
     protected void setUp() throws Exception {
         super.setUp();
-        mDevice = getDevice();
-
-        /* retrieve the sepolicy-analyze executable from jar */
-        sepolicyAnalyze = copyResourceToTempFile("/sepolicy-analyze");
+        sepolicyAnalyze = MigrationHelper.getTestFile(mBuild, "sepolicy-analyze");
         sepolicyAnalyze.setExecutable(true);
 
         /* obtain sepolicy file from running device */
diff --git a/tools/signature-tools/Android.mk b/tools/signature-tools/Android.mk
deleted file mode 100644
index cf9e053..0000000
--- a/tools/signature-tools/Android.mk
+++ /dev/null
@@ -1,66 +0,0 @@
-# Copyright (C) 2008 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-
-# signature-tools java library
-# ============================================================
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under,src)
-LOCAL_JAVA_RESOURCE_DIRS := templates
-
-LOCAL_MODULE := signature-tools
-LOCAL_JAVA_LIBRARIES := dx dex-tools
-LOCAL_STATIC_JAVA_LIBRARIES := stringtemplate antlr-2.7.7
-LOCAL_CLASSPATH := $(HOST_JDK_TOOLS_JAR)
-
-include $(BUILD_HOST_JAVA_LIBRARY)
-
-# prebuilt stringtemplate.jar
-# ============================================================
-include $(CLEAR_VARS)
-
-LOCAL_PREBUILT_JAVA_LIBRARIES := stringtemplate:lib/stringtemplate.jar
-
-include $(BUILD_HOST_PREBUILT)
-
-# prebuilt antlr-2.7.7.jar
-# ============================================================
-include $(CLEAR_VARS)
-
-LOCAL_PREBUILT_JAVA_LIBRARIES := antlr-2.7.7:lib/antlr-2.7.7.jar
-
-include $(BUILD_HOST_PREBUILT)
-
-# signature-tool script
-# ============================================================
-include $(CLEAR_VARS)
-
-LOCAL_PREBUILT_EXECUTABLES := sig
-include $(BUILD_HOST_PREBUILT)
-
-# signature-create script
-# ============================================================
-include $(CLEAR_VARS)
-
-LOCAL_PREBUILT_EXECUTABLES := sig-create
-include $(BUILD_HOST_PREBUILT)
-
-# signature-check script
-# ============================================================
-include $(CLEAR_VARS)
-
-LOCAL_PREBUILT_EXECUTABLES := sig-check
-include $(BUILD_HOST_PREBUILT)
diff --git a/tools/signature-tools/README.txt b/tools/signature-tools/README.txt
deleted file mode 100644
index b4198b9..0000000
--- a/tools/signature-tools/README.txt
+++ /dev/null
@@ -1,55 +0,0 @@
-__signature-tools__
-
-This project contains the source code and tests for API signature comparison tools.
-It consists roughly of five parts:
-
-#Signature model : A generic model to represent the structure of an API
-
-#Converters      : A dex -> signature model converter (utilizing the dex-tools parser)
-                   A java source -> signature model converter (utilizing the doclet tools)
-
-#Delta model     : A model to represent differences between two signature models
-    
-#Comparator      : Put two signature models into the comparator and you get a delta model
-
-#Report engine   : Translates a delta model to a html output based on templates (utilizing the StringTemplate framework)
-
-
-Since this folder contains a .project file, it can be imported directly into eclipse as a java project.
-
-Feel free to improve!
-
-_Structure_
-
-dex.reader
-  |
-  src : source code
-  |  |
-  |	 signature :  the driver classes
-  |  		|
-  |     compare : the comparator code
-  |     |   |
-  |     |   model : the delta model
-  |     |
-  |     converter : the converters
-  |     |
-  |     io : common io interfaces
-  |     |   |
-  |     |   html : html report generator
-  |     |
-  |     model : signature model
-  |
-  test : source code of the test suite
-  |
-  templates : templates for html output generation
-  |
-  launches : eclipse launches for the tools
-  |
-  lib : required libraries
-  |
-  spec : various input files to try the tool 
-  |
-  README.txt : you are here
-  |
-  TODO.txt   : tasks which are still open
- 
diff --git a/tools/signature-tools/TODO.txt b/tools/signature-tools/TODO.txt
deleted file mode 100644
index fd20800..0000000
--- a/tools/signature-tools/TODO.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-__Todo__
-
-Add more complex tests
-Add more spec
-Add "plugin system" to enable different loader / differ / report engines. This can be simple as register the class name of the available loaders in a property file
diff --git a/tools/signature-tools/lib/antlr-2.7.7.jar b/tools/signature-tools/lib/antlr-2.7.7.jar
deleted file mode 100644
index 5e5f14b..0000000
--- a/tools/signature-tools/lib/antlr-2.7.7.jar
+++ /dev/null
Binary files differ
diff --git a/tools/signature-tools/lib/stringtemplate.jar b/tools/signature-tools/lib/stringtemplate.jar
deleted file mode 100644
index 8e41531..0000000
--- a/tools/signature-tools/lib/stringtemplate.jar
+++ /dev/null
Binary files differ
diff --git a/tools/signature-tools/sig b/tools/signature-tools/sig
deleted file mode 100755
index 19b57fa..0000000
--- a/tools/signature-tools/sig
+++ /dev/null
@@ -1,47 +0,0 @@
-#!/bin/bash
-#
-# Copyright (C) 2008 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Set up prog to be the path of this script, including following symlinks,
-# and set up progdir to be the fully-qualified pathname of its directory.
-
-prog="$0"
-while [ -h "${prog}" ]; do
-    newProg=`/bin/ls -ld "${prog}"`
-    newProg=`expr "${newProg}" : ".* -> \(.*\)$"`
-    if expr "x${newProg}" : 'x/' >/dev/null; then
-        prog="${newProg}"
-    else
-        progdir=`dirname "${prog}"`
-        prog="${progdir}/${newProg}"
-    fi
-done
-oldwd=`pwd`
-progdir=`dirname "${prog}"`
-cd "${progdir}"
-progdir=`pwd`
-prog="${progdir}"/`basename "${prog}"`
-cd "${oldwd}"
-
-libdir=`dirname $progdir`/framework
-
-javaOpts=""
-while expr "x$1" : 'x-J' >/dev/null; do
-    opt=`expr "$1" : '-J\(.*\)'`
-    javaOpts="${javaOpts} -${opt}"
-    shift
-done
-
-exec java $javaOpts -classpath $libdir/signature-tools.jar:$libdir/dex-tools.jar:$libdir/stringtemplate.jar:$libdir/antlr-2.7.7.jar signature.Main "$@"
\ No newline at end of file
diff --git a/tools/signature-tools/sig-check b/tools/signature-tools/sig-check
deleted file mode 100755
index 0c1cbce..0000000
--- a/tools/signature-tools/sig-check
+++ /dev/null
@@ -1,114 +0,0 @@
-#!/bin/bash
-#
-# Copyright (C) 2008 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Set up prog to be the path of this script, including following symlinks,
-# and set up progdir to be the fully-qualified pathname of its directory.
-
-prog="$0"
-while [ -h "${prog}" ]; do
-    newProg=`/bin/ls -ld "${prog}"`
-    newProg=`expr "${newProg}" : ".* -> \(.*\)$"`
-    if expr "x${newProg}" : 'x/' >/dev/null; then
-        prog="${newProg}"
-    else
-        progdir=`dirname "${prog}"`
-        prog="${progdir}/${newProg}"
-    fi
-done
-oldwd=`pwd`
-progdir=`dirname "${prog}"`
-cd "${progdir}"
-progdir=`pwd`
-prog="${progdir}"/`basename "${prog}"`
-cd "${oldwd}"
-
-libdir=`dirname $progdir`/framework
-classpath=$libdir/signature-tools.jar:$libdir/dex-tools.jar:\
-$libdir/stringtemplate.jar:$libdir/antlr-2.7.7.jar
-
-javaOpts=""
-while expr "x$1" : 'x-J' >/dev/null; do
-    opt=`expr "$1" : '-J\(.*\)'`
-    javaOpts="${javaOpts} -${opt}"
-    shift
-done
-
-COREDEX=${ANDROID_PRODUCT_OUT}/../../common/obj/JAVA_LIBRARIES/core_intermediates/classes.dex
-
-if [ ! -f ${COREDEX} ]; then
-    echo ERROR: $COREDEX not found
-    exit -1;
-fi
-
-sig --compare \
---from sig ${ANDROID_BUILD_TOP}/cts/tools/signature-tools/spec/android.spec \
---name android cupcake reference \
---to dex ${COREDEX} \
---name Android 1.0 \(current build\) \
---out ${ANDROID_BUILD_TOP}/out/delta \
---packages \
-java.beans \
-java.io \
-java.lang \
-java.lang.annotation \
-java.lang.ref \
-java.lang.reflect \
-java.math \
-java.net \
-java.nio \
-java.nio.channels \
-java.nio.channels.spi \
-java.nio.charset \
-java.nio.charset.spi \
-java.security \
-java.security.acl \
-java.security.cert \
-java.security.interfaces \
-java.security.spec \
-java.sql \
-java.text \
-java.util \
-java.util.concurrent \
-java.util.concurrent.atomic \
-java.util.concurrent.locks \
-java.util.jar \
-java.util.logging \
-java.util.prefs \
-java.util.regex \
-java.util.zip \
-javax.crypto \
-javax.crypto.interfaces \
-javax.crypto.spec \
-javax.imageio \
-javax.imageio.event \
-javax.imageio.metadata \
-javax.imageio.plugins.bmp \
-javax.imageio.plugins.jpeg \
-javax.imageio.spi \
-javax.imageio.stream \
-javax.net \
-javax.net.ssl \
-javax.security.auth \
-javax.security.auth.callback \
-javax.security.auth.login \
-javax.security.auth.x500 \
-javax.security.cert \
-javax.sql \
-javax.xml.parsers \
-org.w3c.dom \
-org.xml.sax \
-org.xml.sax.ext \
-org.xml.sax.helpers
diff --git a/tools/signature-tools/sig-create b/tools/signature-tools/sig-create
deleted file mode 100755
index 4049e69..0000000
--- a/tools/signature-tools/sig-create
+++ /dev/null
@@ -1,111 +0,0 @@
-#!/bin/bash
-#
-# Copyright (C) 2008 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Set up prog to be the path of this script, including following symlinks,
-# and set up progdir to be the fully-qualified pathname of its directory.
-
-prog="$0"
-while [ -h "${prog}" ]; do
-    newProg=`/bin/ls -ld "${prog}"`
-    newProg=`expr "${newProg}" : ".* -> \(.*\)$"`
-    if expr "x${newProg}" : 'x/' >/dev/null; then
-        prog="${newProg}"
-    else
-        progdir=`dirname "${prog}"`
-        prog="${progdir}/${newProg}"
-    fi
-done
-oldwd=`pwd`
-progdir=`dirname "${prog}"`
-cd "${progdir}"
-progdir=`pwd`
-prog="${progdir}"/`basename "${prog}"`
-cd "${oldwd}"
-
-libdir=`dirname $progdir`/framework
-classpath=$libdir/signature-tools.jar:$libdir/dex-tools.jar:\
-$libdir/stringtemplate.jar:$libdir/antlr-2.7.7.jar
-
-javaOpts=""
-while expr "x$1" : 'x-J' >/dev/null; do
-    opt=`expr "$1" : '-J\(.*\)'`
-    javaOpts="${javaOpts} -${opt}"
-    shift
-done
-
-COREDEX=${ANDROID_PRODUCT_OUT}/../../common/obj/JAVA_LIBRARIES/core_intermediates/classes.dex
-
-if [ ! -f ${COREDEX} ]; then
-    echo ERROR: $COREDEX not found
-    exit -1;
-fi
-
-sig --create dex ${COREDEX} \
---out ${ANDROID_BUILD_TOP}/out/dex \
---name cts_dex_1.0.1 \
---packages           \
-java.beans \
-java.io \
-java.lang \
-java.lang.annotation \
-java.lang.ref \
-java.lang.reflect \
-java.math \
-java.net \
-java.nio \
-java.nio.channels \
-java.nio.channels.spi \
-java.nio.charset \
-java.nio.charset.spi \
-java.security \
-java.security.acl \
-java.security.cert \
-java.security.interfaces \
-java.security.spec \
-java.sql \
-java.text \
-java.util \
-java.util.concurrent \
-java.util.concurrent.atomic \
-java.util.concurrent.locks \
-java.util.jar \
-java.util.logging \
-java.util.prefs \
-java.util.regex \
-java.util.zip \
-javax.crypto \
-javax.crypto.interfaces \
-javax.crypto.spec \
-javax.imageio \
-javax.imageio.event \
-javax.imageio.metadata \
-javax.imageio.plugins.bmp \
-javax.imageio.plugins.jpeg \
-javax.imageio.spi \
-javax.imageio.stream \
-javax.net \
-javax.net.ssl \
-javax.security.auth \
-javax.security.auth.callback \
-javax.security.auth.login \
-javax.security.auth.x500 \
-javax.security.cert \
-javax.sql \
-javax.xml.parsers \
-org.w3c.dom \
-org.xml.sax \
-org.xml.sax.ext \
-org.xml.sax.helpers
\ No newline at end of file
diff --git a/tools/signature-tools/spec/android.spec b/tools/signature-tools/spec/android.spec
deleted file mode 100644
index fbbf53a..0000000
--- a/tools/signature-tools/spec/android.spec
+++ /dev/null
Binary files differ
diff --git a/tools/signature-tools/src/signature/Main.java b/tools/signature-tools/src/signature/Main.java
deleted file mode 100644
index 5b1c9ff..0000000
--- a/tools/signature-tools/src/signature/Main.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature;
-
-/**
- * The main entry point for the signature tool. If invoked with
- * <code>--create</code> the call is delegated to
- * {@link signature.converter.Main}. If invoked with <code>--compare</code> the
- * call is delegated to {@link signature.compare.Main}.
- * 
- * @see signature.converter.Main
- * @see signature.compare.Main
- */
-public class Main {
-
-    private static final String USAGE_MESSAGE = "usage:\n"
-            + "  sig --create (doclet | dex) sourcefiles --out directory"
-            + " --name <name> --packages packageName{ packageName}\n"
-            + "  sig --compare --from=(doclet | dex | sig) <sourcefiles>"
-            + " --name <name> --to=(doclet | dex | sig) <sourcefiles>"
-            + " --name <name> --out directory"
-            + " --packages packageName{ packageName}\n  sig --help";
-
-    /**
-     * This class is uninstantiable.
-     */
-    private Main() {
-        // This space intentionally left blank.
-    }
-
-    /**
-     * Run!
-     */
-    public static void main(String[] args) {
-        boolean gotCmd = false;
-        boolean showUsage = false;
-
-        try {
-            for (int i = 0; i < args.length; i++) {
-                String arg = args[i];
-                if (arg.equals("--") || !arg.startsWith("--")) {
-                    gotCmd = false;
-                    showUsage = true;
-                    break;
-                }
-
-                gotCmd = true;
-                if (arg.equals("--create")) {
-                    signature.converter.Main.main(without(args, i));
-                    break;
-                } else if (arg.equals("--compare")) {
-                    signature.compare.Main.main(without(args, i));
-                    break;
-                } else if (arg.equals("--version")) {
-                    version();
-                    break;
-                } else if (arg.equals("--help")) {
-                    showUsage = true;
-                    break;
-                } else {
-                    gotCmd = false;
-                }
-            }
-        } catch (UsageException ex) {
-            showUsage = true;
-        } catch (RuntimeException ex) {
-            System.err.println("\nUNEXPECTED TOP-LEVEL EXCEPTION:");
-            ex.printStackTrace();
-            System.exit(2);
-        } catch (Throwable ex) {
-            System.err.println("\nUNEXPECTED TOP-LEVEL ERROR:");
-            ex.printStackTrace();
-            System.exit(3);
-        }
-
-        if (!gotCmd) {
-            System.err.println("error: no command specified");
-            showUsage = true;
-        }
-
-        if (showUsage) {
-            usage();
-            System.exit(1);
-        }
-    }
-
-    /**
-     * Prints the version message.
-     */
-    private static void version() {
-        System.err.println("android sigtools version " + Version.VERSION);
-        System.exit(0);
-    }
-
-    /**
-     * Prints the usage message.
-     */
-    private static void usage() {
-        System.err.println(USAGE_MESSAGE);
-    }
-
-    /**
-     * Returns a copy of the given argument array, but without the indicated
-     * element.
-     * 
-     * @param orig
-     *            non-null; original array
-     * @param n
-     *            which element to omit
-     * @return non-null; new array
-     */
-    private static String[] without(String[] orig, int n) {
-        int len = orig.length - 1;
-        String[] newa = new String[len];
-        System.arraycopy(orig, 0, newa, 0, n);
-        System.arraycopy(orig, n + 1, newa, n, len - n);
-        return newa;
-    }
-
-}
diff --git a/tools/signature-tools/src/signature/UsageException.java b/tools/signature-tools/src/signature/UsageException.java
deleted file mode 100644
index 6cdf9cf..0000000
--- a/tools/signature-tools/src/signature/UsageException.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature;
-
-/**
- * Simple exception class used to communicate that the command-line tool should
- * print the usage message.
- */
-@SuppressWarnings("serial")
-public class UsageException extends RuntimeException {
-    // This space intentionally left blank.
-}
diff --git a/tools/signature-tools/src/signature/Version.java b/tools/signature-tools/src/signature/Version.java
deleted file mode 100644
index d20e81f..0000000
--- a/tools/signature-tools/src/signature/Version.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature;
-
-/**
- * {@code Version} defines the VERSION constant of the signature tools.
- */
-public class Version {
-    /**
-     * The program version of the signature tools.
-     */
-    public static final String VERSION = "0.1";
-}
diff --git a/tools/signature-tools/src/signature/compare/ApiComparator.java b/tools/signature-tools/src/signature/compare/ApiComparator.java
deleted file mode 100644
index 9232d2d..0000000
--- a/tools/signature-tools/src/signature/compare/ApiComparator.java
+++ /dev/null
@@ -1,1705 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare;
-
-import signature.compare.model.IAnnotationDelta;
-import signature.compare.model.IAnnotationElementDelta;
-import signature.compare.model.IAnnotationFieldDelta;
-import signature.compare.model.IApiDelta;
-import signature.compare.model.IClassDefinitionDelta;
-import signature.compare.model.IConstructorDelta;
-import signature.compare.model.IDelta;
-import signature.compare.model.IEnumConstantDelta;
-import signature.compare.model.IFieldDelta;
-import signature.compare.model.IGenericDeclarationDelta;
-import signature.compare.model.IMethodDelta;
-import signature.compare.model.IModifierDelta;
-import signature.compare.model.IPackageDelta;
-import signature.compare.model.IParameterDelta;
-import signature.compare.model.IParameterizedTypeDelta;
-import signature.compare.model.IPrimitiveTypeDelta;
-import signature.compare.model.ITypeReferenceDelta;
-import signature.compare.model.ITypeVariableDefinitionDelta;
-import signature.compare.model.IUpperBoundsDelta;
-import signature.compare.model.IValueDelta;
-import signature.compare.model.IWildcardTypeDelta;
-import signature.compare.model.impl.SigAnnotationDelta;
-import signature.compare.model.impl.SigAnnotationElementDelta;
-import signature.compare.model.impl.SigAnnotationFieldDelta;
-import signature.compare.model.impl.SigApiDelta;
-import signature.compare.model.impl.SigArrayTypeDelta;
-import signature.compare.model.impl.SigClassDefinitionDelta;
-import signature.compare.model.impl.SigClassReferenceDelta;
-import signature.compare.model.impl.SigConstructorDelta;
-import signature.compare.model.impl.SigEnumConstantDelta;
-import signature.compare.model.impl.SigFieldDelta;
-import signature.compare.model.impl.SigGenericDeclarationDelta;
-import signature.compare.model.impl.SigMethodDelta;
-import signature.compare.model.impl.SigModifierDelta;
-import signature.compare.model.impl.SigPackageDelta;
-import signature.compare.model.impl.SigParameterDelta;
-import signature.compare.model.impl.SigParameterizedTypeDelta;
-import signature.compare.model.impl.SigPrimitiveTypeDelta;
-import signature.compare.model.impl.SigTypeDelta;
-import signature.compare.model.impl.SigTypeVariableDefinitionDelta;
-import signature.compare.model.impl.SigTypeVariableReferenceDelta;
-import signature.compare.model.impl.SigUpperBoundsDelta;
-import signature.compare.model.impl.SigValueDelta;
-import signature.compare.model.impl.SigWildcardTypeDelta;
-import signature.compare.model.subst.ClassProjection;
-import signature.compare.model.subst.ViewpointAdapter;
-import signature.model.IAnnotation;
-import signature.model.IAnnotationElement;
-import signature.model.IAnnotationField;
-import signature.model.IApi;
-import signature.model.IArrayType;
-import signature.model.IClassDefinition;
-import signature.model.IClassReference;
-import signature.model.IConstructor;
-import signature.model.IEnumConstant;
-import signature.model.IExecutableMember;
-import signature.model.IField;
-import signature.model.IGenericDeclaration;
-import signature.model.IMethod;
-import signature.model.IPackage;
-import signature.model.IParameter;
-import signature.model.IParameterizedType;
-import signature.model.IPrimitiveType;
-import signature.model.ITypeReference;
-import signature.model.ITypeVariableDefinition;
-import signature.model.ITypeVariableReference;
-import signature.model.IWildcardType;
-import signature.model.Kind;
-import signature.model.Modifier;
-import signature.model.impl.SigAnnotationElement;
-import signature.model.impl.SigArrayType;
-
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Set;
-
-/**
- * {@code ApiComparator} takes two signature models as input and creates a delta
- * model describing the differences between those.
- */
-public class ApiComparator implements IApiComparator {
-
-    public IApiDelta compare(IApi from, IApi to) {
-        assert from.getVisibility() == to.getVisibility();
-
-        Set<IPackage> fromPackages = from.getPackages();
-        Set<IPackage> toPackages = to.getPackages();
-
-        Set<IPackageDelta> packageDeltas = compareSets(fromPackages,
-                toPackages, new SigComparator<IPackage, IPackageDelta>() {
-                    public IPackageDelta createChangedDelta(IPackage from,
-                            IPackage to) {
-                        return comparePackage(from, to);
-                    }
-
-                    public IPackageDelta createAddRemoveDelta(IPackage from,
-                            IPackage to) {
-                        return new SigPackageDelta(from, to);
-                    }
-
-                    public boolean considerEqualElement(IPackage from,
-                            IPackage to) {
-                        return from.getName().equals(to.getName());
-                    }
-                });
-
-        SigApiDelta delta = null;
-        if (packageDeltas != null) {
-            delta = new SigApiDelta(from, to);
-            delta.setPackageDeltas(packageDeltas);
-        }
-        return delta;
-    }
-
-    private IPackageDelta comparePackage(IPackage from, IPackage to) {
-        assert from.getName().equals(to.getName());
-
-        Set<IClassDefinition> fromClasses = from.getClasses();
-        Set<IClassDefinition> toClasses = to.getClasses();
-
-        Set<IClassDefinitionDelta> classDeltas = compareSets(fromClasses,
-                toClasses,
-                new SigComparator<IClassDefinition, IClassDefinitionDelta>() {
-                    public boolean considerEqualElement(IClassDefinition from,
-                            IClassDefinition to) {
-                        return sameClassDefinition(from, to);
-                    }
-
-                    public IClassDefinitionDelta createChangedDelta(
-                            IClassDefinition from, IClassDefinition to) {
-                        return compareClass(from, to);
-                    }
-
-                    public IClassDefinitionDelta createAddRemoveDelta(
-                            IClassDefinition from, IClassDefinition to) {
-                        return new SigClassDefinitionDelta(from, to);
-                    }
-                });
-
-        SigPackageDelta delta = null;
-        if (classDeltas != null) {
-            delta = new SigPackageDelta(from, to);
-            delta.setClassDeltas(classDeltas);
-        }
-
-        // Annotations
-        Set<IAnnotationDelta> annotationDeltas = compareAnnotations(from
-                .getAnnotations(), to.getAnnotations());
-        if (annotationDeltas != null) {
-            if (delta != null) {
-                delta = new SigPackageDelta(from, to);
-            }
-            delta.setAnnotationDeltas(annotationDeltas);
-        }
-        return delta;
-    }
-
-    private IClassDefinitionDelta compareClass(IClassDefinition from,
-            IClassDefinition to) {
-        assert from.getKind() == to.getKind();
-        assert from.getName().equals(to.getName());
-        assert from.getPackageName().equals(to.getPackageName());
-
-        SigClassDefinitionDelta classDelta = null;
-
-        // modifiers
-        Set<IModifierDelta> modifierDeltas = compareModifiers(from
-                .getModifiers(), to.getModifiers());
-        if (modifierDeltas != null) {
-            if (classDelta == null) {
-                classDelta = new SigClassDefinitionDelta(from, to);
-            }
-            classDelta.setModifierDeltas(modifierDeltas);
-        }
-
-        // super class
-        ITypeReferenceDelta<?> superTypeDelta = compareType(from
-                .getSuperClass(), to.getSuperClass(), false);
-        if (superTypeDelta != null) {
-            if (classDelta == null) {
-                classDelta = new SigClassDefinitionDelta(from, to);
-            }
-            classDelta.setSuperClassDelta(superTypeDelta);
-        }
-
-        // interfaces
-        Set<ITypeReferenceDelta<?>> interfaceDeltas = compareInterfaces(from,
-                to);
-        if (interfaceDeltas != null) {
-            if (classDelta == null) {
-                classDelta = new SigClassDefinitionDelta(from, to);
-            }
-            classDelta.setInterfaceDeltas(interfaceDeltas);
-        }
-
-        // type variables
-        Set<ITypeVariableDefinitionDelta> typeVariableDeltas =
-                compareTypeVariableSequence(from.getTypeParameters(),
-                        to.getTypeParameters());
-        if (typeVariableDeltas != null) {
-            if (classDelta == null) {
-                classDelta = new SigClassDefinitionDelta(from, to);
-            }
-            classDelta.setTypeVariableDeltas(typeVariableDeltas);
-        }
-
-        // constructors
-        Set<IConstructorDelta> constructorDeltas = compareConstructors(from
-                .getConstructors(), to.getConstructors());
-        if (constructorDeltas != null) {
-            if (classDelta == null) {
-                classDelta = new SigClassDefinitionDelta(from, to);
-            }
-            classDelta.setConstructorDeltas(constructorDeltas);
-        }
-
-        // methods
-        Set<IMethodDelta> methodDeltas = compareMethods(from, to);
-        if (methodDeltas != null) {
-            if (classDelta == null) {
-                classDelta = new SigClassDefinitionDelta(from, to);
-            }
-            classDelta.setMethodDeltas(methodDeltas);
-        }
-
-        // fields
-        Set<IFieldDelta> fieldDeltas = compareFields(from.getFields(), to
-                .getFields());
-        if (fieldDeltas != null) {
-            if (classDelta == null) {
-                classDelta = new SigClassDefinitionDelta(from, to);
-            }
-            classDelta.setFieldDeltas(fieldDeltas);
-        }
-
-        // enum constants
-        if (from.getKind() == Kind.ENUM) {
-            Set<IEnumConstantDelta> enumDeltas = compareEnumConstants(from
-                    .getEnumConstants(), to.getEnumConstants());
-            if (enumDeltas != null) {
-                if (classDelta == null) {
-                    classDelta = new SigClassDefinitionDelta(from, to);
-                }
-                classDelta.setEnumConstantDeltas(enumDeltas);
-            }
-        } else if (from.getKind() == Kind.ANNOTATION) {
-            Set<IAnnotationFieldDelta> annotationFieldDeltas =
-                    compareAnnotationFields(from.getAnnotationFields(),
-                            to.getAnnotationFields());
-            if (annotationFieldDeltas != null) {
-                if (classDelta == null) {
-                    classDelta = new SigClassDefinitionDelta(from, to);
-                }
-                classDelta.setAnnotationFieldDeltas(annotationFieldDeltas);
-            }
-        }
-
-        Set<IAnnotationDelta> annotationDeltas = compareAnnotations(from
-                .getAnnotations(), to.getAnnotations());
-        if (annotationDeltas != null) {
-            if (classDelta == null) {
-                classDelta = new SigClassDefinitionDelta(from, to);
-            }
-            classDelta.setAnnotationDeltas(annotationDeltas);
-        }
-        return classDelta;
-    }
-
-    private Set<ITypeReferenceDelta<?>> compareInterfaces(
-            IClassDefinition from, IClassDefinition to) {
-        Set<ITypeReference> fromClosure = getInterfaceClosure(from);
-        Set<ITypeReference> toClosure = getInterfaceClosure(to);
-
-        Set<ITypeReference> fromInterfaces = from.getInterfaces();
-        Set<ITypeReference> toInterfaces = to.getInterfaces();
-
-        Set<ITypeReferenceDelta<?>> deltas =
-                new HashSet<ITypeReferenceDelta<?>>();
-
-        // check whether all from interfaces are directly or indirectly
-        // implemented by the to method
-        for (ITypeReference type : fromInterfaces) {
-            if (!containsType(type, toInterfaces)) {
-                if (!(containsType(type, toClosure) /*
-                                                     * && !containsType(type,
-                                                     * toInterfaces)
-                                                     */)) {
-                    deltas.add(new SigTypeDelta<ITypeReference>(type, null));
-                }
-            }
-        }
-
-        // check whether all interfaces to are directly or indirectly
-        // implemented by the from method
-        for (ITypeReference type : toInterfaces) {
-            if (!containsType(type, fromInterfaces)) {
-                if (!(containsType(type, fromClosure) /*
-                                                       * && !containsType(type,
-                                                       * fromInterfaces)
-                                                       */)) {
-                    deltas.add(new SigTypeDelta<ITypeReference>(null, type));
-                }
-            }
-        }
-        return deltas.isEmpty() ? null : deltas;
-    }
-
-
-    private boolean containsType(ITypeReference type,
-            Set<ITypeReference> setOfTypes) {
-        for (ITypeReference other : setOfTypes) {
-            if (compareType(type, other, false) == null) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private Set<ITypeReference> getInterfaceClosure(IClassDefinition clazz) {
-        Set<ITypeReference> closure = new HashSet<ITypeReference>();
-        collectInterfaceClosure(ViewpointAdapter.getReferenceTo(clazz),
-                closure);
-        return closure;
-    }
-
-    private void collectInterfaceClosure(ITypeReference clazz,
-            Set<ITypeReference> closure) {
-
-        IClassDefinition classDefinition = getClassDefinition(clazz);
-        Set<ITypeReference> interfaces = classDefinition.getInterfaces();
-        if (interfaces == null) {
-            return;
-        }
-        for (ITypeReference interfaze : interfaces) {
-            closure.add(interfaze);
-        }
-
-        ITypeReference superclass = classDefinition.getSuperClass();
-        if (superclass != null) {
-            if (superclass instanceof IParameterizedType) {
-                collectInterfaceClosure(((IParameterizedType) superclass)
-                        .getRawType(), closure);
-            } else {
-                collectInterfaceClosure(superclass, closure);
-            }
-        }
-        for (ITypeReference interfaze : interfaces) {
-            if (interfaze instanceof IParameterizedType) {
-                collectInterfaceClosure(((IParameterizedType) interfaze)
-                        .getRawType(), closure);
-            } else {
-                collectInterfaceClosure(interfaze, closure);
-            }
-        }
-    }
-
-    private Set<IAnnotationDelta> compareAnnotations(Set<IAnnotation> from,
-            Set<IAnnotation> to) {
-        return compareSets(from, to,
-                new SigComparator<IAnnotation, IAnnotationDelta>() {
-                    public IAnnotationDelta createAddRemoveDelta(
-                            IAnnotation from, IAnnotation to) {
-                        return new SigAnnotationDelta(from, to);
-                    }
-
-                    public boolean considerEqualElement(IAnnotation from,
-                            IAnnotation to) {
-                        return sameClassDefinition(from.getType()
-                                .getClassDefinition(), to.getType()
-                                .getClassDefinition());
-                    }
-
-                    public IAnnotationDelta createChangedDelta(
-                            IAnnotation from, IAnnotation to) {
-                        return compareAnnotation(from, to);
-                    }
-                });
-    }
-
-    private Set<IAnnotationFieldDelta> compareAnnotationFields(
-            Set<IAnnotationField> from, Set<IAnnotationField> to) {
-        return compareSets(from, to,
-                new SigComparator<IAnnotationField, IAnnotationFieldDelta>() {
-                    public boolean considerEqualElement(IAnnotationField from,
-                            IAnnotationField to) {
-                        return from.getName().equals(to.getName());
-                    }
-
-                    public IAnnotationFieldDelta createAddRemoveDelta(
-                            IAnnotationField from, IAnnotationField to) {
-                        return new SigAnnotationFieldDelta(from, to);
-                    }
-
-                    public IAnnotationFieldDelta createChangedDelta(
-                            IAnnotationField from, IAnnotationField to) {
-                        return compareAnnotationField(from, to);
-                    }
-                });
-    }
-
-    private Set<IEnumConstantDelta> compareEnumConstants(
-            Set<IEnumConstant> from, Set<IEnumConstant> to) {
-        return compareSets(from, to,
-                new SigComparator<IEnumConstant, IEnumConstantDelta>() {
-                    public boolean considerEqualElement(IEnumConstant from,
-                            IEnumConstant to) {
-                        return from.getName().equals(to.getName());
-                    }
-
-                    public IEnumConstantDelta createAddRemoveDelta(
-                            IEnumConstant from, IEnumConstant to) {
-                        return new SigEnumConstantDelta(from, to);
-                    }
-
-                    public IEnumConstantDelta createChangedDelta(
-                            IEnumConstant from, IEnumConstant to) {
-                        return compareEnumConstant(from, to);
-                    }
-                });
-    }
-
-    private Set<IFieldDelta> compareFields(Set<IField> from, Set<IField> to) {
-        return compareSets(from, to, new SigComparator<IField, IFieldDelta>() {
-            public boolean considerEqualElement(IField from, IField to) {
-                return from.getName().equals(to.getName());
-            }
-
-            public IFieldDelta createAddRemoveDelta(IField from, IField to) {
-                return new SigFieldDelta(from, to);
-            }
-
-            public IFieldDelta createChangedDelta(IField from, IField to) {
-                return compareField(from, to);
-            }
-        });
-    }
-
-    private Set<IMethodDelta> compareMethods(IClassDefinition from,
-            IClassDefinition to) {
-        assert from != null;
-        assert to != null;
-
-        Set<IMethod> toMethods = new HashSet<IMethod>(to.getMethods());
-        Set<IMethod> toClosure = getMethodClosure(to);
-        Set<IMethod> fromMethods = new HashSet<IMethod>(from.getMethods());
-        Set<IMethod> fromClosure = getMethodClosure(from);
-
-        Set<IMethodDelta> deltas = new HashSet<IMethodDelta>();
-
-        for (IMethod method : fromMethods) {
-            IMethod compatibleMethod = findCompatibleMethod(method, toMethods);
-            if (compatibleMethod == null) {
-                compatibleMethod = findCompatibleMethod(method, toClosure);
-                if (compatibleMethod == null) {
-                    deltas.add(new SigMethodDelta(method, null));
-                }
-            }
-
-            if (compatibleMethod != null) {
-                IMethodDelta delta = compareMethod(method, compatibleMethod);
-                if (delta != null) {
-                    deltas.add(delta);
-                }
-            }
-        }
-
-        for (IMethod method : toMethods) {
-            IMethod compatibleMethod = findCompatibleMethod(method, fromMethods);
-            if (compatibleMethod == null) {
-                compatibleMethod = findCompatibleMethod(method, fromClosure);
-                if (compatibleMethod == null) {
-                    deltas.add(new SigMethodDelta(null, method));
-                }
-            }
-        }
-        return deltas.isEmpty() ? null : deltas;
-    }
-
-    private IMethod findCompatibleMethod(IMethod method, Set<IMethod> set) {
-        for (IMethod methodFromSet : set) {
-            if (equalsSignature(method, methodFromSet)) {
-                return methodFromSet;
-            }
-        }
-        return null;
-    }
-
-
-    private Set<IMethod> getMethodClosure(IClassDefinition clazz) {
-        Set<IMethod> closure = new HashSet<IMethod>();
-        collectMethods(new ClassProjection(clazz,
-                new HashMap<ITypeVariableDefinition, ITypeReference>()),
-                closure);
-        return closure;
-    }
-
-    private void collectMethods(IClassDefinition clazz, Set<IMethod> closure) {
-        if (clazz == null) {
-            return;
-        }
-        if (clazz.getMethods() != null) {
-            closure.addAll(clazz.getMethods());
-        }
-        if (clazz.getSuperClass() != null) {
-            collectMethods(getClassDefinition(clazz.getSuperClass()), closure);
-        }
-        if (clazz.getInterfaces() != null) {
-            for (ITypeReference interfaze : clazz.getInterfaces()) {
-                collectMethods(getClassDefinition(interfaze), closure);
-            }
-        }
-    }
-
-    private Set<IConstructorDelta> compareConstructors(Set<IConstructor> from,
-            Set<IConstructor> to) {
-        return compareSets(from, to,
-                new SigComparator<IConstructor, IConstructorDelta>() {
-                    public boolean considerEqualElement(IConstructor from,
-                            IConstructor to) {
-                        return equalsSignature(from, to);
-                    }
-
-                    public IConstructorDelta createAddRemoveDelta(
-                            IConstructor from, IConstructor to) {
-                        return new SigConstructorDelta(from, to);
-                    }
-
-                    public IConstructorDelta createChangedDelta(
-                            IConstructor from, IConstructor to) {
-                        return compareConstructor(from, to);
-                    }
-                });
-    }
-
-    // compares names and parameter types
-    private boolean equalsSignature(IExecutableMember from,
-            IExecutableMember to) {
-        if (from.getName().equals(to.getName())) {
-            return compareTypeSequence(getParameterList(from.getParameters()),
-                    getParameterList(to.getParameters()), true) == null;
-        }
-        return false;
-    }
-
-    private List<ITypeReference> getParameterList(List<IParameter> parameters) {
-        List<ITypeReference> parameterTypes = new LinkedList<ITypeReference>();
-        for (IParameter parameter : parameters) {
-            parameterTypes.add(parameter.getType());
-        }
-        return parameterTypes;
-    }
-
-    private IAnnotationDelta compareAnnotation(IAnnotation from,
-            IAnnotation to) {
-        assert sameClassDefinition(from.getType().getClassDefinition(), to
-                .getType().getClassDefinition());
-
-        Set<IAnnotationElement> fromAnnotationElement =
-                getNormalizedAnnotationElements(from);
-        Set<IAnnotationElement> toAnnotationElement =
-                getNormalizedAnnotationElements(to);
-
-        Set<IAnnotationElementDelta> annotationElementDeltas =
-                compareAnnotationElements(
-                        fromAnnotationElement, toAnnotationElement);
-        SigAnnotationDelta delta = null;
-
-        if (annotationElementDeltas != null) {
-            delta = new SigAnnotationDelta(from, to);
-            delta.setAnnotationElementDeltas(annotationElementDeltas);
-        }
-        return delta;
-    }
-
-    /**
-     * Returns the annotation elements for the given annotation. The returned
-     * set contains all declared elements plus all elements with default values.
-     * 
-     * @param annotation
-     *            the annotation to return the elements for
-     * @return the default enriched annotation elements
-     */
-    private Set<IAnnotationElement> getNormalizedAnnotationElements(
-            IAnnotation annotation) {
-        Set<IAnnotationElement> elements = new HashSet<IAnnotationElement>(
-                annotation.getElements());
-
-        Set<String> names = new HashSet<String>();
-        for (IAnnotationElement annotationElement : elements) {
-            names.add(annotationElement.getDeclaringField().getName());
-        }
-
-        for (IAnnotationField field : annotation.getType().getClassDefinition()
-                .getAnnotationFields()) {
-            if (!names.contains(field.getName())) {
-                SigAnnotationElement sigAnnotationElement =
-                        new SigAnnotationElement();
-                sigAnnotationElement.setDeclaringField(field);
-                sigAnnotationElement.setValue(field.getDefaultValue());
-                elements.add(sigAnnotationElement);
-            }
-        }
-        return elements;
-    }
-
-    private Set<IAnnotationElementDelta> compareAnnotationElements(
-            Set<IAnnotationElement> from, Set<IAnnotationElement> to) {
-        return compareSets(from, to,
-                new SigComparator<IAnnotationElement, IAnnotationElementDelta>() {
-                    public boolean considerEqualElement(
-                            IAnnotationElement from, IAnnotationElement to) {
-                        return from.getDeclaringField().getName().equals(
-                                to.getDeclaringField().getName());
-                    }
-
-                    public IAnnotationElementDelta createAddRemoveDelta(
-                            IAnnotationElement from, IAnnotationElement to) {
-                        return new SigAnnotationElementDelta(from, to);
-                    }
-
-                    public IAnnotationElementDelta createChangedDelta(
-                            IAnnotationElement from, IAnnotationElement to) {
-                        return compareAnnotationElement(from, to);
-                    }
-                });
-    }
-
-    private IAnnotationElementDelta compareAnnotationElement(
-            IAnnotationElement from, IAnnotationElement to) {
-        SigAnnotationElementDelta delta = null;
-        SigValueDelta valueDelta = compareValue(from.getValue(), to.getValue());
-
-        if (valueDelta != null) {
-            delta = new SigAnnotationElementDelta(from, to);
-            delta.setValueDelta(valueDelta);
-        }
-        return delta;
-    }
-
-    /**
-     * Removes the {@link Modifier#ABSTRACT} modifier.
-     */
-    private Set<Modifier> prepareMethodModifiers(IMethod method) {
-        Set<Modifier> modifierCopy = new HashSet<Modifier>(method
-                .getModifiers());
-        modifierCopy.remove(Modifier.ABSTRACT);
-        return modifierCopy;
-    }
-
-    private IMethodDelta compareMethod(IMethod from, IMethod to) {
-        assert from != null && to != null;
-
-        SigMethodDelta methodDelta = null;
-        Set<IModifierDelta> modiferDeltas = compareModifiers(
-                prepareMethodModifiers(from), prepareMethodModifiers(to));
-        if (modiferDeltas != null) {
-            methodDelta = new SigMethodDelta(from, to);
-            methodDelta.setModifierDeltas(modiferDeltas);
-        }
-
-        Set<IParameterDelta> parameterDeltas = compareParameterSequence(from
-                .getParameters(), to.getParameters());
-        if (parameterDeltas != null) {
-            if (methodDelta == null) {
-                methodDelta = new SigMethodDelta(from, to);
-            }
-            methodDelta.setParameterDeltas(parameterDeltas);
-        }
-
-        Set<IAnnotationDelta> annotationDeltas = compareAnnotations(from
-                .getAnnotations(), to.getAnnotations());
-        if (annotationDeltas != null) {
-            if (methodDelta == null) {
-                methodDelta = new SigMethodDelta(from, to);
-            }
-            methodDelta.setAnnotationDeltas(annotationDeltas);
-        }
-
-        Set<ITypeVariableDefinitionDelta> typeParameterDeltas =
-                compareTypeVariableSequence(from.getTypeParameters(),
-                        to.getTypeParameters());
-        if (typeParameterDeltas != null) {
-            if (methodDelta == null) {
-                methodDelta = new SigMethodDelta(from, to);
-            }
-            methodDelta.setTypeVariableDeltas(typeParameterDeltas);
-        }
-
-        Set<ITypeReferenceDelta<?>> exceptionDeltas = compareTypes(
-                normalizeExceptions(from.getExceptions()),
-                normalizeExceptions(to.getExceptions()));
-        if (exceptionDeltas != null) {
-            if (methodDelta == null) {
-                methodDelta = new SigMethodDelta(from, to);
-            }
-            methodDelta.setExceptionDeltas(exceptionDeltas);
-        }
-
-        ITypeReferenceDelta<?> returnTypeDelta = compareType(from
-                .getReturnType(), to.getReturnType(), false);
-        if (returnTypeDelta != null) {
-            if (methodDelta == null) {
-                methodDelta = new SigMethodDelta(from, to);
-            }
-            methodDelta.setReturnTypeDelta(returnTypeDelta);
-        }
-
-        return methodDelta;
-    }
-
-    // remove runtime exceptions,
-    // remove sub types of containing exception
-    private Set<ITypeReference> normalizeExceptions(
-            Set<ITypeReference> exceptions) {
-        Set<ITypeReference> exceptionCopy = new HashSet<ITypeReference>(
-                exceptions);
-
-        Iterator<ITypeReference> iterator = exceptionCopy.iterator();
-        while (iterator.hasNext()) {
-            ITypeReference exception = iterator.next();
-            if (isRuntimeExceptionOrErrorSubtype(exception)) {
-                iterator.remove();
-            }
-        }
-        exceptionCopy = removeSpecializations(exceptionCopy);
-        return exceptionCopy;
-    }
-
-    private Set<ITypeReference> removeSpecializations(
-            Set<ITypeReference> exceptions) {
-        Set<ITypeReference> exceptionCopy = new HashSet<ITypeReference>(
-                exceptions);
-        for (ITypeReference type : exceptions) {
-            Iterator<ITypeReference> it = exceptionCopy.iterator();
-            while (it.hasNext()) {
-                ITypeReference subType = it.next();
-                if (isSuperClass(getClassDefinition(type),
-                        getClassDefinition(subType))) {
-                    it.remove();
-                }
-            }
-        }
-        return exceptionCopy;
-    }
-
-    /**
-     * Returns true if superC is a super class of subC.
-     */
-    private boolean isSuperClass(IClassDefinition superC,
-            IClassDefinition subC) {
-        if (superC == null || subC == null) {
-            return false;
-        }
-
-        if (subC.getSuperClass() == null) {
-            return false;
-        } else {
-            if (getClassDefinition(subC.getSuperClass()).equals(superC)) {
-                return true;
-            } else {
-                return isSuperClass(superC, getClassDefinition(subC
-                        .getSuperClass()));
-            }
-        }
-    }
-
-    private boolean isSuperInterface(IClassDefinition superClass,
-            IClassDefinition subClass) {
-        if (superClass == null || subClass == null) {
-            return false;
-        }
-
-        if (subClass.getInterfaces() == null) {
-            return false;
-        } else {
-            if (getClassDefinitions(subClass.getInterfaces()).contains(
-                    superClass)) {
-                return true;
-            } else {
-                for (ITypeReference subType : subClass.getInterfaces()) {
-                    if (isSuperInterface(superClass,
-                            getClassDefinition(subType))) {
-                        return true;
-                    }
-                }
-                return false;
-            }
-        }
-    }
-
-    private Set<IClassDefinition> getClassDefinitions(
-            Set<ITypeReference> references) {
-        Set<IClassDefinition> definitions = new HashSet<IClassDefinition>();
-        for (ITypeReference ref : references) {
-            definitions.add(getClassDefinition(ref));
-        }
-        return definitions;
-    }
-
-    /**
-     * Returns null if type is not one of:
-     * <ul>
-     * <li>IClassReference</li>
-     * <li>IParameterizedType</li>
-     * </ul>
-     */
-    private IClassDefinition getClassDefinition(ITypeReference type) {
-        assert type != null;
-
-        IClassDefinition returnValue = null;
-        if (type instanceof IClassReference) {
-            returnValue = ((IClassReference) type).getClassDefinition();
-        } else if (type instanceof IParameterizedType) {
-            returnValue = ((IParameterizedType) type).getRawType()
-                    .getClassDefinition();
-        }
-        return returnValue;
-    }
-
-    private boolean isRuntimeExceptionOrErrorSubtype(ITypeReference exception) {
-
-        IClassDefinition clazz = getClassDefinition(exception);
-        if (clazz != null) {
-            if (isRuntimeExceptionOrError(clazz)) {
-                return true;
-            } else if (clazz.getSuperClass() != null) {
-                return isRuntimeExceptionOrErrorSubtype(clazz.getSuperClass());
-            } else {
-                return false;
-            }
-        }
-        return false;
-    }
-
-    private boolean isRuntimeExceptionOrError(IClassDefinition exception) {
-        if (exception == null) {
-            return false;
-        }
-        String packageName = exception.getPackageName();
-        String className = exception.getName();
-
-        if (packageName != null && className != null
-                && "java.lang".equals(packageName)) {
-            return "RuntimeException".equals(className)
-                    || "Error".equals(className);
-        }
-        return false;
-    }
-
-    private IConstructorDelta compareConstructor(IConstructor from,
-            IConstructor to) {
-        SigConstructorDelta constructorDelta = null;
-        Set<IModifierDelta> modiferDeltas = compareModifiers(from
-                .getModifiers(), to.getModifiers());
-        if (modiferDeltas != null) {
-            constructorDelta = new SigConstructorDelta(from, to);
-            constructorDelta.setModifierDeltas(modiferDeltas);
-        }
-
-        Set<IParameterDelta> parameterDeltas = compareParameterSequence(from
-                .getParameters(), to.getParameters());
-        if (parameterDeltas != null) {
-            if (constructorDelta == null) {
-                constructorDelta = new SigConstructorDelta(from, to);
-            }
-            constructorDelta.setParameterDeltas(parameterDeltas);
-        }
-
-        Set<IAnnotationDelta> annotationDeltas = compareAnnotations(from
-                .getAnnotations(), to.getAnnotations());
-        if (annotationDeltas != null) {
-            if (constructorDelta == null) {
-                constructorDelta = new SigConstructorDelta(from, to);
-            }
-            constructorDelta.setAnnotationDeltas(annotationDeltas);
-        }
-
-        Set<ITypeVariableDefinitionDelta> typeParameterDeltas =
-                compareTypeVariableSequence(from.getTypeParameters(),
-                        to.getTypeParameters());
-        if (typeParameterDeltas != null) {
-            if (constructorDelta == null) {
-                constructorDelta = new SigConstructorDelta(from, to);
-            }
-            constructorDelta.setTypeVariableDeltas(typeParameterDeltas);
-        }
-
-        Set<ITypeReferenceDelta<?>> exceptionDeltas = compareTypes(
-                normalizeExceptions(from.getExceptions()),
-                normalizeExceptions(to.getExceptions()));
-        if (exceptionDeltas != null) {
-            if (constructorDelta == null) {
-                constructorDelta = new SigConstructorDelta(from, to);
-            }
-            constructorDelta.setExceptionDeltas(exceptionDeltas);
-        }
-        return constructorDelta;
-    }
-
-    private Set<IParameterDelta> compareParameterSequence(
-            List<IParameter> from, List<IParameter> to) {
-        assert from.size() == to.size();
-        Set<IParameterDelta> deltas = new HashSet<IParameterDelta>();
-        Iterator<IParameter> fromIterator = from.iterator();
-        Iterator<IParameter> toIterator = to.iterator();
-        while (fromIterator.hasNext() && toIterator.hasNext()) {
-            IParameterDelta delta = compareParameter(fromIterator.next(),
-                    toIterator.next());
-            if (delta != null) {
-                deltas.add(delta);
-            }
-        }
-        return deltas.isEmpty() ? null : deltas;
-    }
-
-    private IParameterDelta compareParameter(IParameter from, IParameter to) {
-        SigParameterDelta delta = null;
-        ITypeReferenceDelta<?> typeDelta = compareType(from.getType(), to
-                .getType(), false);
-        if (typeDelta != null) {
-            if (delta == null) {
-                delta = new SigParameterDelta(from, to);
-            }
-            delta.setTypeDelta(typeDelta);
-        }
-
-        Set<IAnnotationDelta> annotationDeltas = compareAnnotations(from
-                .getAnnotations(), to.getAnnotations());
-        if (annotationDeltas != null) {
-            if (delta == null) {
-                delta = new SigParameterDelta(from, to);
-            }
-            delta.setAnnotationDeltas(annotationDeltas);
-        }
-        return delta;
-    }
-
-    private Set<ITypeVariableDefinitionDelta> compareTypeVariableSequence(
-            List<ITypeVariableDefinition> from,
-            List<ITypeVariableDefinition> to) {
-        Set<ITypeVariableDefinitionDelta> deltas =
-                new HashSet<ITypeVariableDefinitionDelta>();
-        if (from.size() != to.size()) {
-            for (ITypeVariableDefinition fromVariable : from) {
-                deltas.add(new SigTypeVariableDefinitionDelta(fromVariable,
-                        null));
-            }
-            for (ITypeVariableDefinition toVariable : to) {
-                deltas
-                        .add(new SigTypeVariableDefinitionDelta(null,
-                                toVariable));
-            }
-        }
-
-        Iterator<ITypeVariableDefinition> fromIterator = from.iterator();
-        Iterator<ITypeVariableDefinition> toIterator = to.iterator();
-        while (fromIterator.hasNext() && toIterator.hasNext()) {
-            ITypeVariableDefinitionDelta delta = compareTypeVariableDefinition(
-                    fromIterator.next(), toIterator.next());
-            if (delta != null) {
-                deltas.add(delta);
-            }
-        }
-        return deltas.isEmpty() ? null : deltas;
-    }
-
-    private ITypeVariableDefinitionDelta compareTypeVariableDefinition(
-            ITypeVariableDefinition from, ITypeVariableDefinition to) {
-        IGenericDeclarationDelta declarationDelta = compareGenericDeclaration(
-                from, to);
-
-        if (declarationDelta != null) {
-            SigTypeVariableDefinitionDelta delta =
-                    new SigTypeVariableDefinitionDelta(from, to);
-            delta.setGenericDeclarationDelta(declarationDelta);
-            return delta;
-        }
-        IUpperBoundsDelta upperBoundDelta = compareUpperBounds(from
-                .getUpperBounds(), to.getUpperBounds());
-
-        if (upperBoundDelta != null) {
-            SigTypeVariableDefinitionDelta delta =
-                    new SigTypeVariableDefinitionDelta(from, to);
-            delta.setUpperBoundsDelta(upperBoundDelta);
-            return delta;
-        }
-        return null;
-    }
-
-    private ITypeReferenceDelta<ITypeVariableReference> compareTypeVariableReference(
-            ITypeVariableReference from, ITypeVariableReference to) {
-        IGenericDeclarationDelta declarationDelta = compareGenericDeclaration(
-                from.getTypeVariableDefinition(), to
-                        .getTypeVariableDefinition());
-        if (declarationDelta != null) {
-            SigTypeVariableReferenceDelta delta =
-                    new SigTypeVariableReferenceDelta(from, to);
-            delta.setGenericDeclarationDelta(declarationDelta);
-            return delta;
-        }
-        return null;
-    }
-
-    private Set<IModifierDelta> compareModifiers(Set<Modifier> from,
-            Set<Modifier> to) {
-        return compareSets(from, to,
-                new SigComparator<Modifier, IModifierDelta>() {
-                    public boolean considerEqualElement(Modifier from,
-                            Modifier to) {
-                        return from.equals(to);
-                    }
-
-                    public IModifierDelta createAddRemoveDelta(Modifier from,
-                            Modifier to) {
-                        return new SigModifierDelta(from, to);
-                    }
-
-                    public IModifierDelta createChangedDelta(Modifier from,
-                            Modifier to) {
-                        return null;
-                    }
-                });
-    }
-
-
-    private IFieldDelta compareField(IField from, IField to) {
-        SigFieldDelta fieldDelta = null;
-
-        Set<IModifierDelta> modiferDeltas = compareModifiers(from
-                .getModifiers(), to.getModifiers());
-        if (modiferDeltas != null) {
-            fieldDelta = new SigFieldDelta(from, to);
-            fieldDelta.setModifierDeltas(modiferDeltas);
-        }
-
-        Set<IAnnotationDelta> annotationDeltas = compareAnnotations(from
-                .getAnnotations(), to.getAnnotations());
-        if (annotationDeltas != null) {
-            if (fieldDelta == null) {
-                fieldDelta = new SigFieldDelta(from, to);
-            }
-            fieldDelta.setAnnotationDeltas(annotationDeltas);
-        }
-
-        ITypeReferenceDelta<?> typeDelta = compareType(from.getType(), to
-                .getType(), false);
-        if (typeDelta != null) {
-            if (fieldDelta == null) {
-                fieldDelta = new SigFieldDelta(from, to);
-            }
-            fieldDelta.setTypeDelta(typeDelta);
-        }
-        return fieldDelta;
-    }
-
-    private IEnumConstantDelta compareEnumConstant(IEnumConstant from,
-            IEnumConstant to) {
-        SigEnumConstantDelta enumConstantDelta = null;
-
-        Set<IModifierDelta> modiferDeltas = compareModifiers(from
-                .getModifiers(), to.getModifiers());
-        if (modiferDeltas != null) {
-            enumConstantDelta = new SigEnumConstantDelta(from, to);
-            enumConstantDelta.setModifierDeltas(modiferDeltas);
-        }
-
-        Set<IAnnotationDelta> annotationDeltas = compareAnnotations(from
-                .getAnnotations(), to.getAnnotations());
-        if (annotationDeltas != null) {
-            if (enumConstantDelta == null) {
-                enumConstantDelta = new SigEnumConstantDelta(from, to);
-            }
-            enumConstantDelta.setAnnotationDeltas(annotationDeltas);
-        }
-
-        ITypeReferenceDelta<?> typeDelta = compareType(from.getType(), to
-                .getType(), false);
-        if (typeDelta != null) {
-            if (enumConstantDelta == null) {
-                enumConstantDelta = new SigEnumConstantDelta(from, to);
-            }
-            enumConstantDelta.setTypeDelta(typeDelta);
-        }
-
-        // FIXME ordinal not supported in dex
-        // ValueDelta ordinalDelta = compareValue(from.getOrdinal(),
-        // to.getOrdinal());
-        // if (ordinalDelta != null) {
-        // if (enumConstantDelta == null) {
-        // enumConstantDelta = new SigEnumConstantDelta(from, to);
-        // }
-        // enumConstantDelta.setOrdinalDelta(ordinalDelta);
-        // }
-
-        return enumConstantDelta;
-    }
-
-    private IAnnotationFieldDelta compareAnnotationField(IAnnotationField from,
-            IAnnotationField to) {
-        SigAnnotationFieldDelta annotationFieldDelta = null;
-
-        Set<IModifierDelta> modiferDeltas = compareModifiers(from
-                .getModifiers(), to.getModifiers());
-        if (modiferDeltas != null) {
-            annotationFieldDelta = new SigAnnotationFieldDelta(from, to);
-            annotationFieldDelta.setModifierDeltas(modiferDeltas);
-        }
-
-        Set<IAnnotationDelta> annotationDeltas = compareAnnotations(from
-                .getAnnotations(), to.getAnnotations());
-        if (annotationDeltas != null) {
-            if (annotationFieldDelta == null) {
-                annotationFieldDelta = new SigAnnotationFieldDelta(from, to);
-            }
-            annotationFieldDelta.setAnnotationDeltas(annotationDeltas);
-        }
-
-        ITypeReferenceDelta<?> typeDelta = compareType(from.getType(), to
-                .getType(), false);
-        if (typeDelta != null) {
-            if (annotationFieldDelta == null) {
-                annotationFieldDelta = new SigAnnotationFieldDelta(from, to);
-            }
-            annotationFieldDelta.setTypeDelta(typeDelta);
-        }
-
-        IValueDelta defaultValueDelta = compareValue(from.getDefaultValue(), to
-                .getDefaultValue());
-        if (defaultValueDelta != null) {
-            if (annotationFieldDelta == null) {
-                annotationFieldDelta = new SigAnnotationFieldDelta(from, to);
-            }
-            annotationFieldDelta.setDefaultValueDelta(defaultValueDelta);
-        }
-
-        return annotationFieldDelta;
-    }
-
-    private SigValueDelta compareValue(Object from, Object to) {
-        // same value
-        if (from == null && to == null) {
-            return null;
-        }
-
-        // one of both is null and other is not
-        if (from == null || to == null) {
-            return new SigValueDelta(from, to);
-        }
-
-        SigValueDelta delta = null;
-        // different types
-        if (from.getClass() == to.getClass()) {
-            if (from.getClass().isArray()) {
-                Object[] fromArray = (Object[]) from;
-                Object[] toArray = (Object[]) from;
-                if (!Arrays.equals(fromArray, toArray)) {
-                    delta = new SigValueDelta(from, to);
-                }
-            } else if (from instanceof IEnumConstant) {
-                IEnumConstantDelta enumConstantDelta = compareEnumConstant(
-                        (IEnumConstant) from, (IEnumConstant) to);
-                if (enumConstantDelta != null) {
-                    delta = new SigValueDelta(from, to);
-                }
-            } else if (from instanceof IAnnotation) {
-                IAnnotationDelta annotationDelta = compareAnnotation(
-                        (IAnnotation) from, (IAnnotation) to);
-                if (annotationDelta != null) {
-                    delta = new SigValueDelta(from, to);
-                }
-            } else if (from instanceof IField) {
-                IFieldDelta fieldDelta = compareField((IField) from,
-                        (IField) to);
-                if (fieldDelta != null) {
-                    delta = new SigValueDelta(from, to);
-                }
-            } else if (from instanceof ITypeReference) {
-                ITypeReferenceDelta<? extends ITypeReference> typeDelta =
-                        compareType((ITypeReference) from, (ITypeReference) to,
-                                false);
-                if (typeDelta != null) {
-                    delta = new SigValueDelta(from, to);
-                }
-            } else if (!from.equals(to)) {
-                delta = new SigValueDelta(from, to);
-            }
-
-        } else if (!(from == null && to == null)) {
-            delta = new SigValueDelta(from, to);
-        }
-        return delta;
-    }
-
-    private boolean considerEqualTypes(ITypeReference from, ITypeReference to) {
-        assert from != null && to != null;
-
-        if (implementInterface(from, to, IPrimitiveType.class)) {
-            return comparePrimitiveType((IPrimitiveType) from,
-                    (IPrimitiveType) to) == null;
-        }
-        if (implementInterface(from, to, IClassReference.class)) {
-            return sameClassDefinition(((IClassReference) from)
-                    .getClassDefinition(), ((IClassReference) to)
-                    .getClassDefinition());
-        }
-        if (implementInterface(from, to, IArrayType.class)) {
-            return considerEqualTypes(((IArrayType) from).getComponentType(),
-                    ((IArrayType) to).getComponentType());
-        }
-        if (implementInterface(from, to, IParameterizedType.class)) {
-            return compareClassReference(((IParameterizedType) from)
-                    .getRawType(), ((IParameterizedType) to)
-                    .getRawType()) == null;
-        }
-        if (implementInterface(from, to, ITypeVariableReference.class)) {
-            return compareTypeVariableReference((ITypeVariableReference) from,
-                    (ITypeVariableReference) to) == null;
-        }
-
-        return false;
-    }
-
-    private Set<ITypeReference> fromComparison = new HashSet<ITypeReference>();
-    private Set<ITypeReference> toComparison = new HashSet<ITypeReference>();
-
-
-    private boolean areInComparison(ITypeReference from, ITypeReference to) {
-        return fromComparison.contains(from) && toComparison.contains(to);
-    }
-
-    private void markInComparison(ITypeReference from, ITypeReference to) {
-        fromComparison.add(from);
-        toComparison.add(to);
-    }
-
-    private void markFinishedComparison(ITypeReference from,
-            ITypeReference to) {
-        fromComparison.remove(from);
-        toComparison.remove(to);
-    }
-
-    private ITypeReferenceDelta<? extends ITypeReference> compareType(
-            ITypeReference from, ITypeReference to, boolean acceptErasedTypes) {
-
-        if (from == null && to == null) {
-            return null;
-        }
-        if ((from == null && to != null) || (from != null && to == null)) {
-            return new SigTypeDelta<ITypeReference>(from, to);
-        }
-        if (areInComparison(from, to)) {
-            return null;
-        }
-        try {
-            markInComparison(from, to);
-
-            if (implementInterface(from, to, IPrimitiveType.class)) {
-                return comparePrimitiveType((IPrimitiveType) from,
-                        (IPrimitiveType) to);
-            }
-            if (implementInterface(from, to, IClassReference.class)) {
-                return compareClassReference((IClassReference) from,
-                        (IClassReference) to);
-            }
-            if (implementInterface(from, to, IArrayType.class)) {
-                return compareArrayType((IArrayType) from, (IArrayType) to);
-            }
-            if (implementInterface(from, to, IParameterizedType.class)) {
-                return compareParameterizedType((IParameterizedType) from,
-                        (IParameterizedType) to, acceptErasedTypes);
-            }
-            if (implementInterface(from, to, ITypeVariableReference.class)) {
-                return compareTypeVariableReference(
-                        (ITypeVariableReference) from,
-                        (ITypeVariableReference) to);
-            }
-            if (implementInterface(from, to, IWildcardType.class)) {
-                return compareWildcardType((IWildcardType) from,
-                        (IWildcardType) to);
-            }
-
-            if (acceptErasedTypes) {
-                if (isGeneric(from) && !isGeneric(to)) {
-                    return compareType(getErasedType(from), to, false);
-                }
-
-                if (!isGeneric(from) && isGeneric(to)) {
-                    return compareType(from, getErasedType(to), false);
-                }
-            }
-            return new SigTypeDelta<ITypeReference>(from, to);
-        } finally {
-            markFinishedComparison(from, to);
-        }
-    }
-
-    private boolean isGeneric(ITypeReference reference) {
-        if (reference instanceof IParameterizedType
-                || reference instanceof ITypeVariableReference
-                || reference instanceof IWildcardType) {
-            return true;
-        }
-        if (reference instanceof IArrayType) {
-            return isGeneric(((IArrayType) reference).getComponentType());
-        }
-        return false;
-    }
-
-    private ITypeReference getErasedType(ITypeReference reference) {
-
-        if (reference instanceof IParameterizedType) {
-            return ((IParameterizedType) reference).getRawType();
-        }
-        if (reference instanceof ITypeVariableReference) {
-            ITypeVariableDefinition typeVariableDefinition =
-                    ((ITypeVariableReference) reference)
-                            .getTypeVariableDefinition();
-            return getErasedType(
-                    typeVariableDefinition.getUpperBounds().get(0));
-        }
-        if (reference instanceof IWildcardType) {
-            return getErasedType(((IWildcardType) reference).getUpperBounds()
-                    .get(0));
-        }
-        if (reference instanceof IArrayType) {
-            // FIXME implement with erasure projection?
-            return new SigArrayType(getErasedType(((IArrayType) reference)
-                    .getComponentType()));
-        }
-        if (reference instanceof IPrimitiveType) {
-            return reference;
-        }
-        if (reference instanceof IClassReference) {
-            return reference;
-        }
-        throw new IllegalArgumentException("Unexpected type: " + reference);
-    }
-
-    private boolean implementInterface(ITypeReference from, ITypeReference to,
-            Class<?> check) {
-        return check.isAssignableFrom(from.getClass())
-                && check.isAssignableFrom(to.getClass());
-    }
-
-    private IWildcardTypeDelta compareWildcardType(IWildcardType from,
-            IWildcardType to) {
-        SigWildcardTypeDelta delta = null;
-
-        ITypeReference fromLowerBound = from.getLowerBound();
-        ITypeReference toLowerBound = to.getLowerBound();
-
-        ITypeReferenceDelta<?> lowerBoundDelta = compareType(fromLowerBound,
-                toLowerBound, false);
-        if (lowerBoundDelta != null) {
-            delta = new SigWildcardTypeDelta(from, to);
-            delta.setLowerBoundDelta(lowerBoundDelta);
-        }
-
-        IUpperBoundsDelta upperBoundsDelta = compareUpperBounds(from
-                .getUpperBounds(), to.getUpperBounds());
-        if (upperBoundsDelta != null) {
-            if (delta == null) {
-                delta = new SigWildcardTypeDelta(from, to);
-            }
-            delta.setUpperBoundDelta(upperBoundsDelta);
-        }
-        return delta;
-    }
-
-    private IGenericDeclarationDelta compareGenericDeclaration(
-            ITypeVariableDefinition fromVariable,
-            ITypeVariableDefinition toVariable) {
-        IGenericDeclarationDelta delta = null;
-
-        IGenericDeclaration from = fromVariable.getGenericDeclaration();
-        IGenericDeclaration to = toVariable.getGenericDeclaration();
-
-        if (from != null && to != null) {
-
-            if (from.getClass() != to.getClass()) {
-                delta = new SigGenericDeclarationDelta(from, to);
-            } else if (from instanceof IClassDefinition) {
-                IClassDefinition fromDeclaringClass = (IClassDefinition) from;
-                IClassDefinition toDeclaringClass = (IClassDefinition) to;
-
-                if (!sameClassDefinition(fromDeclaringClass,
-                        toDeclaringClass)) {
-                    delta = new SigGenericDeclarationDelta(from, to);
-                }
-
-            } else if (from instanceof IConstructor) {
-                IConstructor fromConstructor = (IConstructor) from;
-                IConstructor toConstructor = (IConstructor) from;
-
-                String fromConstructorName = fromConstructor.getName();
-                String fromClassName = fromConstructor.getDeclaringClass()
-                        .getQualifiedName();
-
-                String toConstructorName = toConstructor.getName();
-                String toClassName = toConstructor.getDeclaringClass()
-                        .getQualifiedName();
-
-                if ((!fromConstructorName.equals(toConstructorName))
-                        || (!fromClassName.equals(toClassName))) {
-                    delta = new SigGenericDeclarationDelta(from, to);
-                }
-
-            } else if (from instanceof IMethod) {
-                IMethod fromMethod = (IMethod) from;
-                IMethod toMethod = (IMethod) from;
-
-                String fromConstructorName = fromMethod.getName();
-                String fromClassName = fromMethod.getDeclaringClass()
-                        .getQualifiedName();
-
-                String toConstructorName = toMethod.getName();
-                String toClassName = toMethod.getDeclaringClass()
-                        .getQualifiedName();
-
-                if ((!fromConstructorName.equals(toConstructorName))
-                        || (!fromClassName.equals(toClassName))) {
-                    delta = new SigGenericDeclarationDelta(from, to);
-                }
-            } else {
-                throw new IllegalStateException("Invlaid eclaration site: "
-                        + from);
-            }
-
-            // check position
-            int fromPosition = getPositionOf(fromVariable, from);
-            int toPosition = getPositionOf(toVariable, to);
-
-            if (fromPosition != toPosition) {
-                delta = new SigGenericDeclarationDelta(from, to);
-            }
-
-
-        } else {
-            // one of both is null
-            delta = new SigGenericDeclarationDelta(from, to);
-        }
-        return delta;
-    }
-
-    private int getPositionOf(ITypeVariableDefinition variable,
-            IGenericDeclaration declaration) {
-        return declaration.getTypeParameters().indexOf(variable);
-    }
-
-    private IUpperBoundsDelta compareUpperBounds(List<ITypeReference> from,
-            List<ITypeReference> to) {
-        if (from.isEmpty() && to.isEmpty()) {
-            return null;
-        }
-        SigUpperBoundsDelta delta = null;
-
-        ITypeReference fromFirstUpperBound = from.get(0);
-        ITypeReference toFirstUpperBound = to.get(0);
-
-        ITypeReferenceDelta<?> firstUpperBoundDelta = compareType(
-                fromFirstUpperBound, toFirstUpperBound, false);
-        if (firstUpperBoundDelta != null) {
-            delta = new SigUpperBoundsDelta(from, to);
-            delta.setFirstUpperBoundDelta(firstUpperBoundDelta);
-        } else {
-            // normalize
-            Set<ITypeReference> normalizedfrom = removeGeneralizations(
-                    new HashSet<ITypeReference>(from));
-            Set<ITypeReference> normalizedto = removeGeneralizations(
-                    new HashSet<ITypeReference>(to));
-
-            Set<ITypeReferenceDelta<?>> remainingUpperBoundsDelta =
-                    compareTypes(normalizedfrom, normalizedto);
-            if (remainingUpperBoundsDelta != null) {
-                delta = new SigUpperBoundsDelta(from, to);
-                delta.setRemainingUpperBoundDeltas(remainingUpperBoundsDelta);
-            }
-        }
-        return delta;
-    }
-
-    private Set<ITypeReference> removeGeneralizations(
-            Set<ITypeReference> bounds) {
-        Set<ITypeReference> boundsCopy = new HashSet<ITypeReference>(bounds);
-        for (ITypeReference type : bounds) {
-            Iterator<ITypeReference> it = boundsCopy.iterator();
-            while (it.hasNext()) {
-                ITypeReference superType = it.next();
-                if (isSuperClass(getClassDefinition(superType),
-                        getClassDefinition(type))
-                        || isSuperInterface(getClassDefinition(superType),
-                                getClassDefinition(type))) {
-                    it.remove();
-                }
-            }
-        }
-        return boundsCopy;
-    }
-
-    private IParameterizedTypeDelta compareParameterizedType(
-            IParameterizedType from, IParameterizedType to,
-            boolean ignoreTypeArguments) {
-
-        SigParameterizedTypeDelta delta = null;
-        // check raw type
-        ITypeReferenceDelta<?> rawTypeDelta = compareType(from.getRawType(), to
-                .getRawType(), false);
-        if (rawTypeDelta != null) {
-            delta = new SigParameterizedTypeDelta(from, to);
-            delta.setRawTypeDelta(rawTypeDelta);
-        } else {
-            // check owner type
-            ITypeReferenceDelta<?> ownerTypeDelta = compareType(from
-                    .getOwnerType(), to.getOwnerType(), false);
-            if (ownerTypeDelta != null) {
-                delta = new SigParameterizedTypeDelta(from, to);
-                delta.setOwnerTypeDelta(ownerTypeDelta);
-            } else {
-                // check argument type
-                if (!ignoreTypeArguments) {
-                    Set<ITypeReferenceDelta<?>> argumentTypeDeltas =
-                            compareTypeSequence(from.getTypeArguments(),
-                                    to.getTypeArguments(), false);
-                    if (argumentTypeDeltas != null) {
-                        delta = new SigParameterizedTypeDelta(from, to);
-                        delta.setArgumentTypeDeltas(argumentTypeDeltas);
-                    }
-                }
-            }
-        }
-        return delta;
-    }
-
-    private Set<ITypeReferenceDelta<? extends ITypeReference>> compareTypeSequence(
-            List<ITypeReference> from, List<ITypeReference> to,
-            boolean ignoreTypeArguments) {
-        Set<ITypeReferenceDelta<?>> deltas =
-                new HashSet<ITypeReferenceDelta<?>>();
-        if (from.size() != to.size()) {
-
-            for (ITypeReference type : from) {
-                deltas.add(new SigTypeDelta<ITypeReference>(type, null));
-            }
-            for (ITypeReference type : to) {
-                deltas.add(new SigTypeDelta<ITypeReference>(null, type));
-            }
-            return deltas;
-        }
-
-        Iterator<? extends ITypeReference> fromIterator = from.iterator();
-        Iterator<? extends ITypeReference> toIterator = to.iterator();
-        while (fromIterator.hasNext() && toIterator.hasNext()) {
-            ITypeReferenceDelta<?> delta = compareType(fromIterator.next(),
-                    toIterator.next(), ignoreTypeArguments);
-            if (delta != null) {
-                deltas.add(delta);
-            }
-        }
-        return deltas.isEmpty() ? null : deltas;
-    }
-
-    private Set<ITypeReferenceDelta<? extends ITypeReference>> compareTypes(
-            Set<ITypeReference> from, Set<ITypeReference> to) {
-        return compareSets(from, to,
-                new SigComparator<ITypeReference, ITypeReferenceDelta<? extends ITypeReference>>() {
-                    public ITypeReferenceDelta<? extends ITypeReference> createAddRemoveDelta(
-                            ITypeReference from, ITypeReference to) {
-                        return new SigTypeDelta<ITypeReference>(from, to);
-                    }
-
-                    public boolean considerEqualElement(ITypeReference from,
-                            ITypeReference to) {
-                        return considerEqualTypes(from, to);
-                    }
-
-                    public ITypeReferenceDelta<? extends ITypeReference> createChangedDelta(
-                            ITypeReference from, ITypeReference to) {
-                        return compareType(from, to, false);
-                    }
-                });
-    }
-
-    private static interface SigComparator<T, S extends IDelta<? extends T>> {
-        boolean considerEqualElement(T from, T to);
-
-        S createChangedDelta(T from, T to);
-
-        /**
-         * If null is returned, it will be ignored.
-         */
-        S createAddRemoveDelta(T from, T to);
-    }
-
-
-    private <T, S extends IDelta<? extends T>> Set<S> compareSets(Set<T> from,
-            Set<T> to, SigComparator<T, S> comparator) {
-
-        Set<T> toCopy = new HashSet<T>(to);
-        Set<S> deltas = new HashSet<S>();
-
-        for (T fromType : from) {
-            Iterator<T> toIterator = toCopy.iterator();
-            boolean equals = false;
-            boolean hasNext = toIterator.hasNext();
-
-            while (hasNext && !equals) {
-                T toElement = toIterator.next();
-                equals = comparator.considerEqualElement(fromType, toElement);
-                if (equals) {
-                    S compare = comparator.createChangedDelta(fromType,
-                            toElement);
-                    if (compare != null) {
-                        deltas.add(compare);
-                    }
-                }
-                hasNext = toIterator.hasNext();
-            }
-
-            if (equals) {
-                toIterator.remove();
-            } else {
-                S delta = comparator.createAddRemoveDelta(fromType, null);
-                if (delta != null) {
-                    deltas.add(delta);
-                }
-            }
-        }
-
-        for (T type : toCopy) {
-            S delta = comparator.createAddRemoveDelta(null, type);
-            if (delta != null) {
-                deltas.add(delta);
-            }
-        }
-        return deltas.isEmpty() ? null : deltas;
-    }
-
-
-    private ITypeReferenceDelta<?> compareArrayType(IArrayType from,
-            IArrayType to) {
-        ITypeReferenceDelta<?> componentTypeDelta = compareType(from
-                .getComponentType(), to.getComponentType(), false);
-        if (componentTypeDelta != null) {
-            SigArrayTypeDelta delta = new SigArrayTypeDelta(from, to);
-            delta.setComponentTypeDelta(componentTypeDelta);
-            return delta;
-        }
-        return null;
-    }
-
-    private ITypeReferenceDelta<IClassReference> compareClassReference(
-            IClassReference fromRef, IClassReference toRef) {
-        IClassDefinition from = fromRef.getClassDefinition();
-        IClassDefinition to = toRef.getClassDefinition();
-
-        if (!sameClassDefinition(from, to)) {
-            return new SigClassReferenceDelta(fromRef, toRef);
-        }
-        return null;
-    }
-
-
-    private boolean sameClassDefinition(IClassDefinition from,
-            IClassDefinition to) {
-        boolean sameName = from.getName().equals(to.getName());
-        boolean samePackage = from.getPackageName().equals(to.getPackageName());
-
-        Kind fromKind = from.getKind();
-        Kind toKind = to.getKind();
-        boolean sameKind = (fromKind == null || toKind == null)
-                || fromKind.equals(toKind);
-
-        return sameName && samePackage && sameKind;
-    }
-
-    private IPrimitiveTypeDelta comparePrimitiveType(IPrimitiveType from,
-            IPrimitiveType to) {
-        if (!from.equals(to)) {
-            return new SigPrimitiveTypeDelta(from, to);
-        }
-        return null;
-    }
-}
diff --git a/tools/signature-tools/src/signature/compare/IApiComparator.java b/tools/signature-tools/src/signature/compare/IApiComparator.java
deleted file mode 100644
index 08ed97f..0000000
--- a/tools/signature-tools/src/signature/compare/IApiComparator.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare;
-
-import signature.compare.model.IApiDelta;
-import signature.model.IApi;
-
-/**
- * {@code IApiComparator} defines the functionality of a signature comparator.
- */
-public interface IApiComparator {
-
-    /**
-     * Returns a difference model which describes the differences from {@code
-     * fromApi} to {@code toApi}.
-     * 
-     * @param fromApi
-     *            differences are computed relative to {@code fromApi}
-     * @param toApi
-     *            the target signature model
-     * @return a difference model which describes the differences from {@code
-     *         fromApi} to {@code toApi}
-     */
-    IApiDelta compare(IApi fromApi, IApi toApi);
-}
diff --git a/tools/signature-tools/src/signature/compare/Main.java b/tools/signature-tools/src/signature/compare/Main.java
deleted file mode 100644
index 80edb45..0000000
--- a/tools/signature-tools/src/signature/compare/Main.java
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare;
-
-import signature.UsageException;
-import signature.compare.model.IApiDelta;
-import signature.compare.model.IPackageDelta;
-import signature.compare.model.impl.SigDelta;
-import signature.converter.Visibility;
-import signature.converter.dex.DexFactory;
-import signature.converter.doclet.DocletFactory;
-import signature.io.IApiDeltaExternalizer;
-import signature.io.IApiLoader;
-import signature.io.html.HtmlDeltaExternalizer;
-import signature.io.impl.BinaryApi;
-import signature.model.IApi;
-
-import java.io.IOException;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * Driver class for the --compare option.
- */
-public class Main {
-
-    /**
-     * <pre>
-     * --from=(doclet | dex | sig) <sourcefiles>
-     * --name <name>
-     * --to=(doclet | dex | sig) <sourcefiles>
-     * --name <name>
-     * --out directory
-     * --packages packageName{ packageName}
-     * </pre>
-     */
-    public static void main(String[] args) throws IOException {
-        int at = 0;
-
-        if (!"--from".equals(args[at])) {
-            throw new UsageException();
-        }
-        String fromType = args[++at];
-
-        boolean hasName = false;
-        Set<String> fromFiles = new HashSet<String>();
-        ++at;
-        for (/* at */; at < args.length; at++) {
-            if ("--name".equals(args[at])) {
-                hasName = true;
-                break;
-            }
-            if ("--to".equals(args[at])) {
-                break;
-            }
-            fromFiles.add(args[at]);
-        }
-
-        String nameFrom = null;
-        if (hasName) {
-            nameFrom = "";
-            if (!"--name".equals(args[at])) {
-                throw new UsageException();
-            }
-            ++at;
-            for (/* at */; at < args.length; at++) {
-                if ("--to".equals(args[at])) {
-                    break;
-                }
-                nameFrom += args[at];
-                nameFrom += " ";
-            }
-            nameFrom = nameFrom.trim();
-        }
-
-        if (!"--to".equals(args[at])) {
-            throw new UsageException();
-        }
-        String toType = args[++at];
-
-        hasName = false;
-        Set<String> toFiles = new HashSet<String>();
-        ++at;
-        for (/* at */; at < args.length; at++) {
-            if ("--name".equals(args[at])) {
-                hasName = true;
-                break;
-            }
-            if ("--out".equals(args[at])) {
-                break;
-            }
-            toFiles.add(args[at]);
-        }
-
-        String nameTo = null;
-        if (hasName) {
-            nameTo = "";
-            if (!"--name".equals(args[at])) {
-                throw new UsageException();
-            }
-            ++at;
-            for (/* at */; at < args.length; at++) {
-                if ("--out".equals(args[at])) {
-                    break;
-                }
-                nameTo += args[at];
-                nameTo += " ";
-            }
-            nameTo = nameTo.trim();
-        }
-
-        if (!"--out".equals(args[at])) {
-            throw new UsageException();
-        }
-        String output = args[++at];
-
-        if (!"--packages".equals(args[++at])) {
-            throw new UsageException();
-        }
-        Set<String> packages = new HashSet<String>();
-        ++at;
-        for (/* at */; at < args.length; at++) {
-            packages.add(args[at]);
-        }
-
-        IApiComparator comparator = new ApiComparator();
-        IApi fromApi = getApi(fromType, nameFrom, fromFiles, packages);
-        IApi toApi = getApi(toType, nameTo, toFiles, packages);
-
-        IApiDeltaExternalizer externalizer = new HtmlDeltaExternalizer();
-        System.out.println("Writing delta report to " + output);
-        IApiDelta delta = comparator.compare(fromApi, toApi);
-        if (delta == null) {
-            delta = new EmptyDelta(fromApi, toApi);
-        }
-
-        externalizer.externalize(output, delta);
-    }
-
-    private static class EmptyDelta extends SigDelta<IApi> implements
-            IApiDelta {
-        public EmptyDelta(IApi from, IApi to) {
-            super(from, to);
-        }
-
-        public Set<IPackageDelta> getPackageDeltas() {
-            return Collections.emptySet();
-        }
-    }
-
-    private static IApi getApi(String specType, String name,
-            Set<String> fileNames, Set<String> packageNames) throws
-            IOException {
-        System.out.println("Loading " + name + " of type " + specType
-                + " from " + fileNames);
-        IApiLoader factory = null;
-        if ("doclet".equals(specType)) {
-            checkName(name);
-            factory = new DocletFactory();
-        } else if ("dex".equals(specType)) {
-            checkName(name);
-            factory = new DexFactory();
-        } else if ("sig".equals(specType)) {
-            factory = new BinaryApi();
-        } else {
-            throw new UsageException();
-        }
-        return factory.loadApi(name, Visibility.PROTECTED, fileNames,
-                packageNames);
-    }
-
-    private static void checkName(String name) {
-        if (name == null) {
-            throw new UsageException();
-        }
-    }
-}
diff --git a/tools/signature-tools/src/signature/compare/model/DeltaType.java b/tools/signature-tools/src/signature/compare/model/DeltaType.java
deleted file mode 100644
index a3aad2c..0000000
--- a/tools/signature-tools/src/signature/compare/model/DeltaType.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model;
-
-/**
- * {@code DeltaType} defines the three possible types of a delta.
- */
-public enum DeltaType {
-    /**
-     * States that an element was added to the toApi.
-     */
-    ADDED,
-    /**
-     * States that an element was removed from the toApi.
-     */
-    REMOVED,
-    /**
-     * States that an element changed.
-     */
-    CHANGED
-}
diff --git a/tools/signature-tools/src/signature/compare/model/IAnnotatableElementDelta.java b/tools/signature-tools/src/signature/compare/model/IAnnotatableElementDelta.java
deleted file mode 100644
index dd41c60..0000000
--- a/tools/signature-tools/src/signature/compare/model/IAnnotatableElementDelta.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model;
-
-import java.util.Set;
-
-/**
- * {@code IAnnotatableElementDelta} is the common base interface for deltas
- * which may have {@link IAnnotationDelta}s.
- */
-public interface IAnnotatableElementDelta {
-
-    /**
-     * Returns a set of annotation deltas or {@code null} if no deltas are
-     * available.
-     * 
-     * @return a set of annotation deltas, maybe {@code null}
-     */
-    Set<IAnnotationDelta> getAnnotationDeltas();
-}
diff --git a/tools/signature-tools/src/signature/compare/model/IAnnotationDelta.java b/tools/signature-tools/src/signature/compare/model/IAnnotationDelta.java
deleted file mode 100644
index 2e29358..0000000
--- a/tools/signature-tools/src/signature/compare/model/IAnnotationDelta.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model;
-
-import java.util.Set;
-
-import signature.model.IAnnotation;
-
-/**
- * {@code IAnnotationDelta} models the delta between two {@link IAnnotation}
- * instances.
- */
-public interface IAnnotationDelta extends IDelta<IAnnotation> {
-
-    /**
-     * Returns a set of annotation element deltas or {@code null} if no deltas
-     * are available.
-     * 
-     * @return a set of annotation element deltas, maybe {@code null}
-     */
-    Set<IAnnotationElementDelta> getAnnotationElementDeltas();
-}
diff --git a/tools/signature-tools/src/signature/compare/model/IAnnotationElementDelta.java b/tools/signature-tools/src/signature/compare/model/IAnnotationElementDelta.java
deleted file mode 100644
index 4355fdb..0000000
--- a/tools/signature-tools/src/signature/compare/model/IAnnotationElementDelta.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model;
-
-import signature.model.IAnnotationElement;
-
-/**
- * {@code IAnnotationElementDelta} models the delta between two
- * {@link IAnnotationElement} instances.
- */
-public interface IAnnotationElementDelta extends IDelta<IAnnotationElement> {
-
-    /**
-     * Returns a value delta or {@code null} if no delta is available.
-     * 
-     * @return a value delta, maybe {@code null}
-     */
-    IValueDelta getValueDelta();
-}
diff --git a/tools/signature-tools/src/signature/compare/model/IAnnotationFieldDelta.java b/tools/signature-tools/src/signature/compare/model/IAnnotationFieldDelta.java
deleted file mode 100644
index 223072a..0000000
--- a/tools/signature-tools/src/signature/compare/model/IAnnotationFieldDelta.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model;
-
-import signature.model.IAnnotationField;
-
-/**
- * {@code IAnnotationFieldDelta} models the delta between two
- * {@link IAnnotationField} instances.
- */
-public interface IAnnotationFieldDelta extends IMemberDelta<IAnnotationField> {
-
-    /**
-     * Returns the default value delta or {@code null} if no delta is available.
-     * 
-     * @return the default value delta, maybe {@code null}
-     */
-    IValueDelta getDefaultValueDelta();
-}
diff --git a/tools/signature-tools/src/signature/compare/model/IApiDelta.java b/tools/signature-tools/src/signature/compare/model/IApiDelta.java
deleted file mode 100644
index 78a8c34..0000000
--- a/tools/signature-tools/src/signature/compare/model/IApiDelta.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model;
-
-import java.util.Set;
-
-import signature.model.IApi;
-
-/**
- * {@code IApiDelta} models the delta between two {@link IApi} instances.
- */
-public interface IApiDelta extends IDelta<IApi> {
-
-    /**
-     * Returns a set of package deltas or {@code null} if no deltas are
-     * available.
-     * 
-     * @return a set of package deltas, maybe {@code null}
-     */
-    Set<IPackageDelta> getPackageDeltas();
-}
diff --git a/tools/signature-tools/src/signature/compare/model/IArrayTypeDelta.java b/tools/signature-tools/src/signature/compare/model/IArrayTypeDelta.java
deleted file mode 100644
index bb29bcd..0000000
--- a/tools/signature-tools/src/signature/compare/model/IArrayTypeDelta.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model;
-
-import signature.model.IArrayType;
-
-/**
- * {@code IArrayTypeDelta} models the delta between two {@link IArrayType}
- * instances.
- */
-public interface IArrayTypeDelta extends ITypeReferenceDelta<IArrayType> {
-
-    /**
-     * Returns a component type delta or {@code null} if no delta is available.
-     * 
-     * @return a component type delta, maybe {@code null}
-     */
-    ITypeReferenceDelta<?> getComponentTypeDelta();
-}
diff --git a/tools/signature-tools/src/signature/compare/model/IClassDefinitionDelta.java b/tools/signature-tools/src/signature/compare/model/IClassDefinitionDelta.java
deleted file mode 100644
index 5cbaf9b..0000000
--- a/tools/signature-tools/src/signature/compare/model/IClassDefinitionDelta.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model;
-
-import java.util.Set;
-
-import signature.model.IClassDefinition;
-
-/**
- * {@code IClassDefinitionDelta} models the delta between two
- * {@link IClassDefinition} instances.
- */
-public interface IClassDefinitionDelta extends
-        ITypeDefinitionDelta<IClassDefinition>, IAnnotatableElementDelta,
-        ITypeVariableDeltas {
-
-    /**
-     * Returns a set of field deltas or {@code null} if no deltas are available.
-     * 
-     * @return a set of field deltas, maybe {@code null}
-     */
-    Set<IFieldDelta> getFieldDeltas();
-
-    /**
-     * Returns a set of enum constant deltas or {@code null} if no deltas are
-     * available.
-     * 
-     * @return a set of enum constant deltas, maybe {@code null}
-     */
-    Set<IEnumConstantDelta> getEnumConstantDeltas();
-
-    /**
-     * Returns a set of annotation field deltas or {@code null} if no deltas are
-     * available.
-     * 
-     * @return a set of annotation field deltas, maybe {@code null}
-     */
-    Set<IAnnotationFieldDelta> getAnnotationFieldDeltas();
-
-    /**
-     * Returns a set of method deltas or {@code null} if no deltas are
-     * available.
-     * 
-     * @return a set of method deltas, maybe {@code null}
-     */
-    Set<IMethodDelta> getMethodDeltas();
-
-    /**
-     * Returns a set of constructor deltas or {@code null} if no deltas are
-     * available.
-     * 
-     * @return a set of constructor deltas, maybe {@code null}
-     */
-    Set<IConstructorDelta> getConstructorDeltas();
-
-    /**
-     * Returns a set of modifier deltas or {@code null} if no deltas are
-     * available.
-     * 
-     * @return a set of modifier deltas, maybe {@code null}
-     */
-    Set<IModifierDelta> getModifierDeltas();
-
-    /**
-     * Returns a super class delta or {@code null} if no delta is available.
-     * 
-     * @return a super class delta, maybe {@code null}
-     */
-    ITypeReferenceDelta<?> getSuperClassDelta();
-
-    /**
-     * Returns a set of interface deltas or {@code null} if no deltas are
-     * available.
-     * 
-     * @return a set of interface deltas, maybe {@code null}
-     */
-    Set<ITypeReferenceDelta<?>> getInterfaceDeltas();
-}
diff --git a/tools/signature-tools/src/signature/compare/model/IConstructorDelta.java b/tools/signature-tools/src/signature/compare/model/IConstructorDelta.java
deleted file mode 100644
index 64ba993..0000000
--- a/tools/signature-tools/src/signature/compare/model/IConstructorDelta.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model;
-
-import signature.model.IConstructor;
-
-/**
- * {@code IConstructorDelta} models the delta between two {@link IConstructor}
- * instances.
- */
-public interface IConstructorDelta extends
-        IExecutableMemberDelta<IConstructor> {
-}
diff --git a/tools/signature-tools/src/signature/compare/model/IDelta.java b/tools/signature-tools/src/signature/compare/model/IDelta.java
deleted file mode 100644
index bd94388..0000000
--- a/tools/signature-tools/src/signature/compare/model/IDelta.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model;
-
-/**
- * {@code IDelta} is the common base interface for all delta model elements. It
- * describes a delta from a "from" element to a "to" element.
- * 
- * @param <T>
- *            the type of the compared elements
- */
-public interface IDelta<T> {
-
-    /**
-     * Returns the type of this delta.
-     * 
-     * @return the type of this delta
-     */
-    DeltaType getType();
-
-    /**
-     * Returns the "from" element. Is null if type is {@link DeltaType#ADDED}
-     * 
-     * @return the "from" element
-     */
-    T getFrom();
-
-    /**
-     * Returns the "to" element. Is null if type is {@link DeltaType#REMOVED}
-     * 
-     * @return the "to" element
-     */
-    T getTo();
-}
diff --git a/tools/signature-tools/src/signature/compare/model/IEnumConstantDelta.java b/tools/signature-tools/src/signature/compare/model/IEnumConstantDelta.java
deleted file mode 100644
index 6590c5a..0000000
--- a/tools/signature-tools/src/signature/compare/model/IEnumConstantDelta.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model;
-
-import signature.model.IEnumConstant;
-
-/**
- * {@code IEnumConstantDelta} models the delta between two {@link IEnumConstant}
- * instances.
- */
-public interface IEnumConstantDelta extends IMemberDelta<IEnumConstant> {
-    IValueDelta getOrdinalDelta();
-}
diff --git a/tools/signature-tools/src/signature/compare/model/IExecutableMemberDelta.java b/tools/signature-tools/src/signature/compare/model/IExecutableMemberDelta.java
deleted file mode 100644
index 30f7038..0000000
--- a/tools/signature-tools/src/signature/compare/model/IExecutableMemberDelta.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model;
-
-import java.util.Set;
-
-import signature.model.IExecutableMember;
-
-/**
- * {@code IExecutableMemberDelta} models the delta between two
- * {@link IExecutableMember} instances.
- */
-public interface IExecutableMemberDelta<T extends IExecutableMember> extends
-        IDelta<T>, ITypeVariableDeltas, IAnnotatableElementDelta {
-
-    /**
-     * Returns a set of modifier deltas or {@code null} if no deltas are
-     * available.
-     * 
-     * @return a set of modifier deltas, maybe {@code null}
-     */
-    Set<IModifierDelta> getModifierDeltas();
-
-    /**
-     * Returns a set of exception deltas or {@code null} if no deltas are
-     * available.
-     * 
-     * @return a set of exception deltas, maybe {@code null}
-     */
-    Set<ITypeReferenceDelta<?>> getExceptionDeltas();
-
-    /**
-     * Returns a set of parameter deltas or {@code null} if no deltas are
-     * available.
-     * 
-     * @return a set of parameter deltas, maybe {@code null}
-     */
-    Set<IParameterDelta> getParameterDeltas();
-}
diff --git a/tools/signature-tools/src/signature/compare/model/IFieldDelta.java b/tools/signature-tools/src/signature/compare/model/IFieldDelta.java
deleted file mode 100644
index ab9bf76..0000000
--- a/tools/signature-tools/src/signature/compare/model/IFieldDelta.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model;
-
-import signature.model.IField;
-
-/**
- * {@code IFieldDelta} models the delta between two {@link IField} instances.
- */
-public interface IFieldDelta extends IMemberDelta<IField> {
-}
diff --git a/tools/signature-tools/src/signature/compare/model/IGenericDeclarationDelta.java b/tools/signature-tools/src/signature/compare/model/IGenericDeclarationDelta.java
deleted file mode 100644
index 5cd518c..0000000
--- a/tools/signature-tools/src/signature/compare/model/IGenericDeclarationDelta.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model;
-
-import signature.model.IGenericDeclaration;
-
-/**
- * {@code IGenericDeclarationDelta} models the delta between two
- * {@link IGenericDeclaration} instances.
- */
-public interface IGenericDeclarationDelta extends IDelta<IGenericDeclaration> {
-}
diff --git a/tools/signature-tools/src/signature/compare/model/IMemberDelta.java b/tools/signature-tools/src/signature/compare/model/IMemberDelta.java
deleted file mode 100644
index df78307..0000000
--- a/tools/signature-tools/src/signature/compare/model/IMemberDelta.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model;
-
-import java.util.Set;
-
-import signature.model.IField;
-
-/**
- * {@code IMemberDelta} models the delta between two {@link IField} subclass
- * instances.
- */
-public interface IMemberDelta<T extends IField> extends IDelta<T>,
-        IAnnotatableElementDelta {
-
-    /**
-     * Returns a type delta or {@code null} if no delta is available.
-     * 
-     * @return a type delta, maybe {@code null}
-     */
-    ITypeReferenceDelta<?> getTypeDelta();
-
-    /**
-     * Returns a set of modifier deltas or {@code null} if no deltas are
-     * available.
-     * 
-     * @return a set of modifier deltas, maybe {@code null}
-     */
-    Set<IModifierDelta> getModifierDeltas();
-}
diff --git a/tools/signature-tools/src/signature/compare/model/IMethodDelta.java b/tools/signature-tools/src/signature/compare/model/IMethodDelta.java
deleted file mode 100644
index 3e94d26..0000000
--- a/tools/signature-tools/src/signature/compare/model/IMethodDelta.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model;
-
-import signature.model.IMethod;
-
-/**
- * {@code IMethodDelta} models the delta between two {@link IMethod} subclass
- * instances.
- */
-public interface IMethodDelta extends IExecutableMemberDelta<IMethod> {
-
-    /**
-     * Returns a return type delta or {@code null} if no delta is available.
-     * 
-     * @return a return type delta, maybe {@code null}
-     */
-    ITypeReferenceDelta<?> getReturnTypeDelta();
-}
diff --git a/tools/signature-tools/src/signature/compare/model/IModifierDelta.java b/tools/signature-tools/src/signature/compare/model/IModifierDelta.java
deleted file mode 100644
index 4553e10..0000000
--- a/tools/signature-tools/src/signature/compare/model/IModifierDelta.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model;
-
-import signature.model.Modifier;
-
-/**
- * {@code IModifierDelta} models the delta between two {@link Modifier}
- * instances.
- */
-public interface IModifierDelta extends IDelta<Modifier> {
-}
diff --git a/tools/signature-tools/src/signature/compare/model/IPackageDelta.java b/tools/signature-tools/src/signature/compare/model/IPackageDelta.java
deleted file mode 100644
index 8c697c3..0000000
--- a/tools/signature-tools/src/signature/compare/model/IPackageDelta.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model;
-
-import java.util.Set;
-
-import signature.model.IPackage;
-
-/**
- * {@code IPackageDelta} models the delta between two {@link IPackage}
- * instances.
- */
-public interface IPackageDelta extends IDelta<IPackage>,
-        IAnnotatableElementDelta {
-
-    /**
-     * Returns a set of class definition deltas or {@code null} if no deltas are
-     * available.
-     * 
-     * @return a set of class definition deltas, maybe {@code null}
-     */
-    Set<IClassDefinitionDelta> getClassDeltas();
-}
diff --git a/tools/signature-tools/src/signature/compare/model/IParameterDelta.java b/tools/signature-tools/src/signature/compare/model/IParameterDelta.java
deleted file mode 100644
index b2a6a80..0000000
--- a/tools/signature-tools/src/signature/compare/model/IParameterDelta.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model;
-
-import signature.model.IParameter;
-
-/**
- * {@code IParameterDelta} models the delta between two {@link IParameter}
- * instances.
- */
-public interface IParameterDelta extends IDelta<IParameter>,
-        IAnnotatableElementDelta {
-
-    /**
-     * Returns a parameter type delta or {@code null} if no delta is available.
-     * 
-     * @return a parameter type delta, maybe {@code null}
-     */
-    public ITypeReferenceDelta<?> getTypeDelta();
-}
diff --git a/tools/signature-tools/src/signature/compare/model/IParameterizedTypeDelta.java b/tools/signature-tools/src/signature/compare/model/IParameterizedTypeDelta.java
deleted file mode 100644
index be54a01..0000000
--- a/tools/signature-tools/src/signature/compare/model/IParameterizedTypeDelta.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model;
-
-import java.util.Set;
-
-import signature.model.IParameterizedType;
-
-/**
- * {@code IParameterizedTypeDelta} models the delta between two
- * {@link IParameterizedType} instances.
- */
-public interface IParameterizedTypeDelta extends
-        ITypeReferenceDelta<IParameterizedType> {
-
-    /**
-     * Returns a raw type delta or {@code null} if no delta is available.
-     * 
-     * @return a raw type delta, maybe {@code null}
-     */
-    ITypeReferenceDelta<?> getRawTypeDelta();
-
-    /**
-     * Returns a owner type delta or {@code null} if no delta is available.
-     * 
-     * @return a owner type delta, maybe {@code null}
-     */
-    ITypeReferenceDelta<?> getOwnerTypeDelta();
-
-    /**
-     * Returns a set of argument type deltas or {@code null} if no deltas are
-     * available.
-     * 
-     * @return a set of argument type deltas, maybe {@code null}
-     */
-    Set<ITypeReferenceDelta<?>> getArgumentTypeDeltas();
-}
diff --git a/tools/signature-tools/src/signature/compare/model/IPrimitiveTypeDelta.java b/tools/signature-tools/src/signature/compare/model/IPrimitiveTypeDelta.java
deleted file mode 100644
index f729435..0000000
--- a/tools/signature-tools/src/signature/compare/model/IPrimitiveTypeDelta.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model;
-
-import signature.model.IPrimitiveType;
-
-/**
- * {@code IPrimitiveTypeDelta} models the delta between two
- * {@link IPrimitiveType} instances.
- */
-public interface IPrimitiveTypeDelta extends
-        ITypeReferenceDelta<IPrimitiveType> {
-}
diff --git a/tools/signature-tools/src/signature/compare/model/ITypeDefinitionDelta.java b/tools/signature-tools/src/signature/compare/model/ITypeDefinitionDelta.java
deleted file mode 100644
index 932cc39..0000000
--- a/tools/signature-tools/src/signature/compare/model/ITypeDefinitionDelta.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model;
-
-import signature.model.ITypeDefinition;
-
-/**
- * {@code ITypeDefinitionDelta} is the common base interface for deltas which
- * model differences between type definitions.
- */
-public interface ITypeDefinitionDelta<T extends ITypeDefinition> extends
-        IDelta<T> {
-}
diff --git a/tools/signature-tools/src/signature/compare/model/ITypeReferenceDelta.java b/tools/signature-tools/src/signature/compare/model/ITypeReferenceDelta.java
deleted file mode 100644
index fba52f0..0000000
--- a/tools/signature-tools/src/signature/compare/model/ITypeReferenceDelta.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model;
-
-import signature.model.ITypeReference;
-
-/**
- * {@code ITypeReferenceDelta} is the common base interface for deltas which
- * model differences between type references.
- */
-public interface ITypeReferenceDelta<T extends ITypeReference> extends
-        IDelta<T> {
-}
diff --git a/tools/signature-tools/src/signature/compare/model/ITypeVariableDefinitionDelta.java b/tools/signature-tools/src/signature/compare/model/ITypeVariableDefinitionDelta.java
deleted file mode 100644
index 1e8f3cd..0000000
--- a/tools/signature-tools/src/signature/compare/model/ITypeVariableDefinitionDelta.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model;
-
-import signature.model.ITypeVariableDefinition;
-
-/**
- * {@code ITypeVariableDefinitionDelta} models the delta between two
- * {@link ITypeVariableDefinition} instances.
- */
-public interface ITypeVariableDefinitionDelta extends
-        ITypeDefinitionDelta<ITypeVariableDefinition> {
-
-    /**
-     * Returns an upper bound delta or {@code null} if no delta is available.
-     * 
-     * @return an upper bound delta, maybe {@code null}
-     */
-    IUpperBoundsDelta getUpperBoundsDelta();
-
-    /**
-     * Returns a generic declaration delta or {@code null} if no delta is
-     * available.
-     * 
-     * @return a generic declaration delta, maybe {@code null}
-     */
-    IGenericDeclarationDelta getGenericDeclarationDelta();
-}
diff --git a/tools/signature-tools/src/signature/compare/model/ITypeVariableDeltas.java b/tools/signature-tools/src/signature/compare/model/ITypeVariableDeltas.java
deleted file mode 100644
index a88ea30..0000000
--- a/tools/signature-tools/src/signature/compare/model/ITypeVariableDeltas.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model;
-
-import java.util.Set;
-
-/**
- * Common interface for all deltas which may have {@code
- * ITypeVariableDefinitionDelta}s. Type variable deltas can occur, where type
- * variables can be defined. On classes, constructors and methods.
- * 
- * @see IClassDefinitionDelta
- * @see IExecutableMemberDelta (common super interface of the following two
- *      interfaces)
- * @see IConstructorDelta
- * @see IMethodDelta
- */
-public interface ITypeVariableDeltas {
-
-    /**
-     * Returns a set of type variable deltas or {@code null} if no deltas are
-     * available.
-     * 
-     * @return a set of type variable deltas, maybe {@code null}
-     */
-    Set<ITypeVariableDefinitionDelta> getTypeVariableDeltas();
-}
diff --git a/tools/signature-tools/src/signature/compare/model/IUpperBoundsDelta.java b/tools/signature-tools/src/signature/compare/model/IUpperBoundsDelta.java
deleted file mode 100644
index 44bd39a..0000000
--- a/tools/signature-tools/src/signature/compare/model/IUpperBoundsDelta.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model;
-
-import java.util.List;
-import java.util.Set;
-
-import signature.model.ITypeReference;
-
-/**
- * {@code IUpperBoundsDelta} models the delta between two {@link List
- * &lt;ITypeReference&gt;} instances.
- * <p>
- * This interface is aware, that for the first argument, the order of the upper
- * bounds is relevant (for erasure).
- */
-public interface IUpperBoundsDelta extends IDelta<List<ITypeReference>> {
-    
-    /**
-     * Returns the upper bound delta of the first upper bound or {@code null} if
-     * no delta is available.
-     *
-     * @return the upper bound delta of the first upper bound, maybe {@code
-     *         null}
-     */
-    ITypeReferenceDelta<?> getFirstUpperBoundDelta();
-
-    /**
-     * Returns a set of remaining upper bound deltas or {@code null} if no
-     * deltas are available.
-     *
-     * @return a set of remaining upper bound deltas, maybe {@code null}
-     */
-    Set<ITypeReferenceDelta<?>> getRemainingUpperBoundDeltas();
-}
diff --git a/tools/signature-tools/src/signature/compare/model/IValueDelta.java b/tools/signature-tools/src/signature/compare/model/IValueDelta.java
deleted file mode 100644
index abd1f59..0000000
--- a/tools/signature-tools/src/signature/compare/model/IValueDelta.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model;
-
-
-/**
- * {@code IValueDelta} models the delta between two
- * {@link Object} instances.
- */
-public interface IValueDelta extends IDelta<Object> {}
diff --git a/tools/signature-tools/src/signature/compare/model/IWildcardTypeDelta.java b/tools/signature-tools/src/signature/compare/model/IWildcardTypeDelta.java
deleted file mode 100644
index 1fda09c..0000000
--- a/tools/signature-tools/src/signature/compare/model/IWildcardTypeDelta.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model;
-
-import signature.model.IWildcardType;
-
-/**
- * {@code IWildcardTypeDelta} models the delta between two
- * {@link IWildcardType} instances.
- */
-public interface IWildcardTypeDelta extends ITypeReferenceDelta<IWildcardType> {
-    
-    /**
-     * Returns the upper bound delta or {@code null} if no delta is available.
-     *
-     * @return the upper bound delta, maybe {@code null}
-     */
-    IUpperBoundsDelta getUpperBoundDelta();
-
-    /**
-     * Returns the lower bound delta or {@code null} if no delta is available.
-     *
-     * @return the lower bound delta, maybe {@code null}
-     */
-    ITypeReferenceDelta<?> getLowerBoundDelta();
-}
diff --git a/tools/signature-tools/src/signature/compare/model/impl/SigAnnotationDelta.java b/tools/signature-tools/src/signature/compare/model/impl/SigAnnotationDelta.java
deleted file mode 100644
index 78e515f..0000000
--- a/tools/signature-tools/src/signature/compare/model/impl/SigAnnotationDelta.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model.impl;
-
-import java.util.Set;
-
-import signature.compare.model.IAnnotationDelta;
-import signature.compare.model.IAnnotationElementDelta;
-import signature.model.IAnnotation;
-
-public class SigAnnotationDelta extends SigDelta<IAnnotation> implements
-        IAnnotationDelta {
-
-    private Set<IAnnotationElementDelta> annotationElementDeltas;
-
-    public SigAnnotationDelta(IAnnotation from, IAnnotation to) {
-        super(from, to);
-    }
-
-    public Set<IAnnotationElementDelta> getAnnotationElementDeltas() {
-        return annotationElementDeltas;
-    }
-
-    public void setAnnotationElementDeltas(
-            Set<IAnnotationElementDelta> annotationElementDeltas) {
-        this.annotationElementDeltas = annotationElementDeltas;
-    }
-}
diff --git a/tools/signature-tools/src/signature/compare/model/impl/SigAnnotationElementDelta.java b/tools/signature-tools/src/signature/compare/model/impl/SigAnnotationElementDelta.java
deleted file mode 100644
index cc7a6fc..0000000
--- a/tools/signature-tools/src/signature/compare/model/impl/SigAnnotationElementDelta.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model.impl;
-
-import signature.compare.model.IAnnotationElementDelta;
-import signature.compare.model.IValueDelta;
-import signature.model.IAnnotationElement;
-
-public class SigAnnotationElementDelta extends SigDelta<IAnnotationElement>
-        implements IAnnotationElementDelta {
-
-    private IValueDelta valueDelta;
-
-    public SigAnnotationElementDelta(IAnnotationElement from,
-            IAnnotationElement to) {
-        super(from, to);
-    }
-
-    public IValueDelta getValueDelta() {
-        return valueDelta;
-    }
-
-    public void setValueDelta(IValueDelta valueDelta) {
-        this.valueDelta = valueDelta;
-    }
-}
diff --git a/tools/signature-tools/src/signature/compare/model/impl/SigAnnotationFieldDelta.java b/tools/signature-tools/src/signature/compare/model/impl/SigAnnotationFieldDelta.java
deleted file mode 100644
index 90fcd7b..0000000
--- a/tools/signature-tools/src/signature/compare/model/impl/SigAnnotationFieldDelta.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model.impl;
-
-import signature.compare.model.IAnnotationFieldDelta;
-import signature.compare.model.IValueDelta;
-import signature.model.IAnnotationField;
-
-public class SigAnnotationFieldDelta extends SigMemberDelta<IAnnotationField>
-        implements IAnnotationFieldDelta {
-
-    private IValueDelta defaultValueDelta;
-
-    public SigAnnotationFieldDelta(IAnnotationField from, IAnnotationField to) {
-        super(from, to);
-    }
-
-    public IValueDelta getDefaultValueDelta() {
-        return defaultValueDelta;
-    }
-
-    public void setDefaultValueDelta(IValueDelta valueDelta) {
-        this.defaultValueDelta = valueDelta;
-    }
-
-}
diff --git a/tools/signature-tools/src/signature/compare/model/impl/SigApiDelta.java b/tools/signature-tools/src/signature/compare/model/impl/SigApiDelta.java
deleted file mode 100644
index bc2bd56..0000000
--- a/tools/signature-tools/src/signature/compare/model/impl/SigApiDelta.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model.impl;
-
-import signature.compare.model.IApiDelta;
-import signature.compare.model.IPackageDelta;
-import signature.model.IApi;
-
-import java.util.Set;
-
-public class SigApiDelta extends SigDelta<IApi> implements IApiDelta {
-
-    private Set<IPackageDelta> packageDeltas;
-
-    public SigApiDelta(IApi from, IApi to) {
-        super(from, to);
-    }
-
-    public Set<IPackageDelta> getPackageDeltas() {
-        return packageDeltas;
-    }
-
-    public void setPackageDeltas(Set<IPackageDelta> packageDeltas) {
-        this.packageDeltas = packageDeltas;
-    }
-}
diff --git a/tools/signature-tools/src/signature/compare/model/impl/SigArrayTypeDelta.java b/tools/signature-tools/src/signature/compare/model/impl/SigArrayTypeDelta.java
deleted file mode 100644
index 5d47293..0000000
--- a/tools/signature-tools/src/signature/compare/model/impl/SigArrayTypeDelta.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model.impl;
-
-import signature.compare.model.IArrayTypeDelta;
-import signature.compare.model.ITypeReferenceDelta;
-import signature.model.IArrayType;
-
-public class SigArrayTypeDelta extends SigTypeDelta<IArrayType> implements
-        IArrayTypeDelta {
-
-    private ITypeReferenceDelta<?> componentTypeDelta;
-
-    public SigArrayTypeDelta(IArrayType from, IArrayType to) {
-        super(from, to);
-    }
-
-    public ITypeReferenceDelta<?> getComponentTypeDelta() {
-        return componentTypeDelta;
-    }
-
-    public void setComponentTypeDelta(
-            ITypeReferenceDelta<?> componentTypeDelta) {
-        this.componentTypeDelta = componentTypeDelta;
-    }
-}
diff --git a/tools/signature-tools/src/signature/compare/model/impl/SigClassDefinitionDelta.java b/tools/signature-tools/src/signature/compare/model/impl/SigClassDefinitionDelta.java
deleted file mode 100644
index 4034351..0000000
--- a/tools/signature-tools/src/signature/compare/model/impl/SigClassDefinitionDelta.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model.impl;
-
-import signature.compare.model.IAnnotationDelta;
-import signature.compare.model.IAnnotationFieldDelta;
-import signature.compare.model.IClassDefinitionDelta;
-import signature.compare.model.IConstructorDelta;
-import signature.compare.model.IEnumConstantDelta;
-import signature.compare.model.IFieldDelta;
-import signature.compare.model.IMethodDelta;
-import signature.compare.model.IModifierDelta;
-import signature.compare.model.ITypeReferenceDelta;
-import signature.compare.model.ITypeVariableDefinitionDelta;
-import signature.model.IClassDefinition;
-
-import java.util.Set;
-
-public class SigClassDefinitionDelta extends
-        SigTypeDefinitionDelta<IClassDefinition> implements
-        IClassDefinitionDelta {
-
-    public SigClassDefinitionDelta(IClassDefinition from, IClassDefinition to) {
-        super(from, to);
-    }
-
-    private Set<IAnnotationFieldDelta> annotationFieldDeltas;
-    private Set<IConstructorDelta> constructorDeltas;
-    private Set<IEnumConstantDelta> enumConstantDeltas;
-    private Set<IFieldDelta> fieldDeltas;
-    private Set<ITypeReferenceDelta<?>> interfaceDeltas;
-    private Set<IMethodDelta> methodDeltas;
-    private Set<IModifierDelta> modifierDeltas;
-    private ITypeReferenceDelta<?> superClassDelta;
-    private Set<IAnnotationDelta> annotationDeltas;
-    private Set<ITypeVariableDefinitionDelta> typeVariableDeltas;
-
-    public Set<IAnnotationFieldDelta> getAnnotationFieldDeltas() {
-        return annotationFieldDeltas;
-    }
-
-    public void setAnnotationFieldDeltas(
-            Set<IAnnotationFieldDelta> annotationFieldDeltas) {
-        this.annotationFieldDeltas = annotationFieldDeltas;
-    }
-
-    public Set<IConstructorDelta> getConstructorDeltas() {
-        return constructorDeltas;
-    }
-
-    public void setConstructorDeltas(
-            Set<IConstructorDelta> constructorDeltas) {
-        this.constructorDeltas = constructorDeltas;
-    }
-
-    public Set<IEnumConstantDelta> getEnumConstantDeltas() {
-        return enumConstantDeltas;
-    }
-
-    public void setEnumConstantDeltas(
-            Set<IEnumConstantDelta> enumConstantDeltas) {
-        this.enumConstantDeltas = enumConstantDeltas;
-    }
-
-    public Set<IFieldDelta> getFieldDeltas() {
-        return fieldDeltas;
-    }
-
-    public void setFieldDeltas(Set<IFieldDelta> fieldDeltas) {
-        this.fieldDeltas = fieldDeltas;
-    }
-
-    public Set<ITypeReferenceDelta<?>> getInterfaceDeltas() {
-        return interfaceDeltas;
-    }
-
-    public void setInterfaceDeltas(
-            Set<ITypeReferenceDelta<?>> interfaceDeltas) {
-        this.interfaceDeltas = interfaceDeltas;
-    }
-
-    public Set<IMethodDelta> getMethodDeltas() {
-        return methodDeltas;
-    }
-
-    public void setMethodDeltas(Set<IMethodDelta> methodDeltas) {
-        this.methodDeltas = methodDeltas;
-    }
-
-    public Set<IModifierDelta> getModifierDeltas() {
-        return modifierDeltas;
-    }
-
-    public void setModifierDeltas(Set<IModifierDelta> modifierDeltas) {
-        this.modifierDeltas = modifierDeltas;
-    }
-
-    public ITypeReferenceDelta<?> getSuperClassDelta() {
-        return superClassDelta;
-    }
-
-    public void setSuperClassDelta(ITypeReferenceDelta<?> superClassDelta) {
-        this.superClassDelta = superClassDelta;
-    }
-
-    public Set<IAnnotationDelta> getAnnotationDeltas() {
-        return annotationDeltas;
-    }
-
-    public void setAnnotationDeltas(Set<IAnnotationDelta> annotationDeltas) {
-        this.annotationDeltas = annotationDeltas;
-    }
-
-    public Set<ITypeVariableDefinitionDelta> getTypeVariableDeltas() {
-        return typeVariableDeltas;
-    }
-
-    public void setTypeVariableDeltas(
-            Set<ITypeVariableDefinitionDelta> typeVariableDeltas) {
-        this.typeVariableDeltas = typeVariableDeltas;
-    }
-}
diff --git a/tools/signature-tools/src/signature/compare/model/impl/SigClassReferenceDelta.java b/tools/signature-tools/src/signature/compare/model/impl/SigClassReferenceDelta.java
deleted file mode 100644
index 18741eb..0000000
--- a/tools/signature-tools/src/signature/compare/model/impl/SigClassReferenceDelta.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model.impl;
-
-import signature.compare.model.ITypeReferenceDelta;
-import signature.model.IClassReference;
-
-public class SigClassReferenceDelta extends SigDelta<IClassReference>
-        implements ITypeReferenceDelta<IClassReference> {
-
-    public SigClassReferenceDelta(IClassReference from, IClassReference to) {
-        super(from, to);
-    }
-}
diff --git a/tools/signature-tools/src/signature/compare/model/impl/SigConstructorDelta.java b/tools/signature-tools/src/signature/compare/model/impl/SigConstructorDelta.java
deleted file mode 100644
index 9a7cf70..0000000
--- a/tools/signature-tools/src/signature/compare/model/impl/SigConstructorDelta.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model.impl;
-
-import signature.compare.model.IConstructorDelta;
-import signature.model.IConstructor;
-
-public class SigConstructorDelta extends SigExecutableMemberDelta<IConstructor>
-        implements IConstructorDelta {
-
-    public SigConstructorDelta(IConstructor from, IConstructor to) {
-        super(from, to);
-    }
-}
diff --git a/tools/signature-tools/src/signature/compare/model/impl/SigDelta.java b/tools/signature-tools/src/signature/compare/model/impl/SigDelta.java
deleted file mode 100644
index 933bf00..0000000
--- a/tools/signature-tools/src/signature/compare/model/impl/SigDelta.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model.impl;
-
-import java.lang.reflect.Field;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Set;
-
-import signature.compare.model.IDelta;
-import signature.compare.model.DeltaType;
-
-public abstract class SigDelta<T> implements IDelta<T> {
-    private T from;
-    private T to;
-
-    public SigDelta(T from, T to) {
-        this.from = from;
-        this.to = to;
-    }
-
-    public final T getFrom() {
-        return from;
-    }
-
-    public final T getTo() {
-        return to;
-    }
-
-    public final DeltaType getType() {
-        if (from == null && to != null) {
-            return DeltaType.ADDED;
-        }
-        if (from != null && to == null) {
-            return DeltaType.REMOVED;
-        }
-        return DeltaType.CHANGED;
-    }
-
-    private static <T extends IDelta<?>> Set<T> getDeltas(Set<T> deltas,
-            DeltaType type) {
-        Set<T> addedElements = new HashSet<T>();
-        for (T delta : deltas) {
-            if (type.equals(delta.getType())) {
-                addedElements.add(delta);
-            }
-        }
-        return addedElements;
-    }
-
-    public static <T extends IDelta<?>> Set<T> getAdded(Set<T> deltas) {
-        return getDeltas(deltas, DeltaType.ADDED);
-    }
-
-    public static <T extends IDelta<?>> Set<T> getRemoved(Set<T> deltas) {
-        return getDeltas(deltas, DeltaType.REMOVED);
-    }
-
-    public static <T extends IDelta<?>> Set<T> getChanged(Set<T> deltas) {
-        return getDeltas(deltas, DeltaType.CHANGED);
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder builder = new StringBuilder();
-        builder.append(getClass().getSimpleName());
-        builder.append(":\n");
-
-        List<Field> allFields = new LinkedList<Field>();
-
-        Class<?> actualClass = getClass();
-
-        // add all fields / super classes also
-        do {
-            allFields.addAll(Arrays.asList(actualClass.getDeclaredFields()));
-            actualClass = actualClass.getSuperclass();
-        } while (actualClass != Object.class);
-
-        builder.append("from: ");
-        builder.append(from);
-        builder.append("\nto:    ");
-        builder.append(to);
-        builder.append("\n");
-        try {
-            for (Field field : allFields) {
-                if (!ignore.contains(field.getName())) {
-                    field.setAccessible(true);
-                    Object delta = field.get(this);
-                    if (delta != null) {
-                        builder.append(field.getName());
-                        builder.append(":\n");
-                        builder.append(delta);
-                    }
-                }
-            }
-        } catch (IllegalArgumentException e) {
-            e.printStackTrace();
-        } catch (IllegalAccessException e) {
-            e.printStackTrace();
-        } catch (SecurityException e) {
-            e.printStackTrace();
-        }
-
-        return builder.toString();
-    }
-
-    private static Set<String> ignore = new HashSet<String>();
-    {
-        ignore.add("from");
-        ignore.add("to");
-        ignore.add("reason");
-        ignore.add("ignore"); // =)
-    }
-}
diff --git a/tools/signature-tools/src/signature/compare/model/impl/SigEnumConstantDelta.java b/tools/signature-tools/src/signature/compare/model/impl/SigEnumConstantDelta.java
deleted file mode 100644
index 3a7f9e7..0000000
--- a/tools/signature-tools/src/signature/compare/model/impl/SigEnumConstantDelta.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model.impl;
-
-import signature.compare.model.IEnumConstantDelta;
-import signature.compare.model.IValueDelta;
-import signature.model.IEnumConstant;
-
-public class SigEnumConstantDelta extends SigMemberDelta<IEnumConstant>
-        implements IEnumConstantDelta {
-
-    private IValueDelta ordinalDelta;
-
-    public SigEnumConstantDelta(IEnumConstant from, IEnumConstant to) {
-        super(from, to);
-    }
-
-    public IValueDelta getOrdinalDelta() {
-        return ordinalDelta;
-    }
-
-    public void setOrdinalDelta(IValueDelta ordinalDelta) {
-        this.ordinalDelta = ordinalDelta;
-    }
-}
diff --git a/tools/signature-tools/src/signature/compare/model/impl/SigExecutableMemberDelta.java b/tools/signature-tools/src/signature/compare/model/impl/SigExecutableMemberDelta.java
deleted file mode 100644
index 1d871e4..0000000
--- a/tools/signature-tools/src/signature/compare/model/impl/SigExecutableMemberDelta.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model.impl;
-
-import signature.compare.model.IAnnotationDelta;
-import signature.compare.model.IExecutableMemberDelta;
-import signature.compare.model.IModifierDelta;
-import signature.compare.model.IParameterDelta;
-import signature.compare.model.ITypeReferenceDelta;
-import signature.compare.model.ITypeVariableDefinitionDelta;
-import signature.model.IExecutableMember;
-
-import java.util.Set;
-
-public abstract class SigExecutableMemberDelta<T extends IExecutableMember>
-        extends SigDelta<T> implements IExecutableMemberDelta<T> {
-
-    private Set<ITypeReferenceDelta<?>> exceptionDeltas;
-    private Set<IModifierDelta> modifierDeltas;
-    private Set<ITypeVariableDefinitionDelta> typeVariableDeltas;
-    private Set<IAnnotationDelta> annotationDeltas;
-    private Set<IParameterDelta> parameterDeltas;
-
-    public SigExecutableMemberDelta(T from, T to) {
-        super(from, to);
-    }
-
-    public Set<ITypeReferenceDelta<?>> getExceptionDeltas() {
-        return exceptionDeltas;
-    }
-
-    public void setExceptionDeltas(
-            Set<ITypeReferenceDelta<?>> exceptionDeltas) {
-        this.exceptionDeltas = exceptionDeltas;
-    }
-
-    public Set<IModifierDelta> getModifierDeltas() {
-        return modifierDeltas;
-    }
-
-    public void setModifierDeltas(Set<IModifierDelta> modifierDeltas) {
-        this.modifierDeltas = modifierDeltas;
-    }
-
-    public Set<ITypeVariableDefinitionDelta> getTypeVariableDeltas() {
-        return typeVariableDeltas;
-    }
-
-    public void setTypeVariableDeltas(
-            Set<ITypeVariableDefinitionDelta> typeVariableDeltas) {
-        this.typeVariableDeltas = typeVariableDeltas;
-    }
-
-    public Set<IAnnotationDelta> getAnnotationDeltas() {
-        return annotationDeltas;
-    }
-
-    public void setAnnotationDeltas(Set<IAnnotationDelta> annotationDeltas) {
-        this.annotationDeltas = annotationDeltas;
-    }
-
-    public Set<IParameterDelta> getParameterDeltas() {
-        return parameterDeltas;
-    }
-
-    public void setParameterDeltas(Set<IParameterDelta> parameterDeltas) {
-        this.parameterDeltas = parameterDeltas;
-    }
-}
diff --git a/tools/signature-tools/src/signature/compare/model/impl/SigFieldDelta.java b/tools/signature-tools/src/signature/compare/model/impl/SigFieldDelta.java
deleted file mode 100644
index 6807eea..0000000
--- a/tools/signature-tools/src/signature/compare/model/impl/SigFieldDelta.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model.impl;
-
-import signature.compare.model.IFieldDelta;
-import signature.model.IField;
-
-public class SigFieldDelta extends SigMemberDelta<IField> implements
-        IFieldDelta {
-
-    public SigFieldDelta(IField from, IField to) {
-        super(from, to);
-    }
-}
diff --git a/tools/signature-tools/src/signature/compare/model/impl/SigGenericDeclarationDelta.java b/tools/signature-tools/src/signature/compare/model/impl/SigGenericDeclarationDelta.java
deleted file mode 100644
index d377b95..0000000
--- a/tools/signature-tools/src/signature/compare/model/impl/SigGenericDeclarationDelta.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model.impl;
-
-import signature.compare.model.IGenericDeclarationDelta;
-import signature.model.IGenericDeclaration;
-
-public class SigGenericDeclarationDelta extends SigDelta<IGenericDeclaration>
-        implements IGenericDeclarationDelta {
-
-    public SigGenericDeclarationDelta(IGenericDeclaration from,
-            IGenericDeclaration to) {
-        super(from, to);
-    }
-}
diff --git a/tools/signature-tools/src/signature/compare/model/impl/SigMemberDelta.java b/tools/signature-tools/src/signature/compare/model/impl/SigMemberDelta.java
deleted file mode 100644
index 2c5e9cb..0000000
--- a/tools/signature-tools/src/signature/compare/model/impl/SigMemberDelta.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model.impl;
-
-import java.util.Set;
-
-import signature.compare.model.IAnnotationDelta;
-import signature.compare.model.IMemberDelta;
-import signature.compare.model.IModifierDelta;
-import signature.compare.model.ITypeReferenceDelta;
-import signature.model.IField;
-
-public abstract class SigMemberDelta<T extends IField> extends SigDelta<T>
-        implements IMemberDelta<T> {
-
-    private Set<IModifierDelta> modifierDeltas;
-    private ITypeReferenceDelta<?> typeDelta;
-    private Set<IAnnotationDelta> annotationDeltas;
-
-
-    public SigMemberDelta(T from, T to) {
-        super(from, to);
-    }
-
-    public Set<IModifierDelta> getModifierDeltas() {
-        return modifierDeltas;
-    }
-
-    public void setModifierDeltas(Set<IModifierDelta> modifierDeltas) {
-        this.modifierDeltas = modifierDeltas;
-    }
-
-    public ITypeReferenceDelta<?> getTypeDelta() {
-        return typeDelta;
-    }
-
-    public void setTypeDelta(ITypeReferenceDelta<?> typeDelta) {
-        this.typeDelta = typeDelta;
-    }
-
-    public Set<IAnnotationDelta> getAnnotationDeltas() {
-        return annotationDeltas;
-    }
-
-    public void setAnnotationDeltas(Set<IAnnotationDelta> annotationDeltas) {
-        this.annotationDeltas = annotationDeltas;
-    }
-}
diff --git a/tools/signature-tools/src/signature/compare/model/impl/SigMethodDelta.java b/tools/signature-tools/src/signature/compare/model/impl/SigMethodDelta.java
deleted file mode 100644
index 0a3fb2f..0000000
--- a/tools/signature-tools/src/signature/compare/model/impl/SigMethodDelta.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model.impl;
-
-import signature.compare.model.IMethodDelta;
-import signature.compare.model.ITypeReferenceDelta;
-import signature.model.IMethod;
-
-public class SigMethodDelta extends SigExecutableMemberDelta<IMethod> implements
-        IMethodDelta {
-
-    private ITypeReferenceDelta<?> returnTypeDelta;
-
-    public SigMethodDelta(IMethod from, IMethod to) {
-        super(from, to);
-    }
-
-    public ITypeReferenceDelta<?> getReturnTypeDelta() {
-        return returnTypeDelta;
-    }
-
-    public void setReturnTypeDelta(ITypeReferenceDelta<?> returnTypeDelta) {
-        this.returnTypeDelta = returnTypeDelta;
-    }
-}
diff --git a/tools/signature-tools/src/signature/compare/model/impl/SigModifierDelta.java b/tools/signature-tools/src/signature/compare/model/impl/SigModifierDelta.java
deleted file mode 100644
index aa5e380..0000000
--- a/tools/signature-tools/src/signature/compare/model/impl/SigModifierDelta.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model.impl;
-
-import signature.compare.model.IModifierDelta;
-import signature.model.Modifier;
-
-public class SigModifierDelta extends SigDelta<Modifier> implements
-        IModifierDelta {
-
-    public SigModifierDelta(Modifier from, Modifier to) {
-        super(from, to);
-    }
-}
diff --git a/tools/signature-tools/src/signature/compare/model/impl/SigPackageDelta.java b/tools/signature-tools/src/signature/compare/model/impl/SigPackageDelta.java
deleted file mode 100644
index 0f368f6..0000000
--- a/tools/signature-tools/src/signature/compare/model/impl/SigPackageDelta.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model.impl;
-
-import java.util.Set;
-
-import signature.compare.model.IAnnotationDelta;
-import signature.compare.model.IClassDefinitionDelta;
-import signature.compare.model.IPackageDelta;
-import signature.model.IPackage;
-
-public class SigPackageDelta extends SigDelta<IPackage> implements
-        IPackageDelta {
-
-    private Set<IClassDefinitionDelta> classDeltas;
-    private Set<IAnnotationDelta> annotationDeltas;
-
-    public SigPackageDelta(IPackage from, IPackage to) {
-        super(from, to);
-    }
-
-    public Set<IClassDefinitionDelta> getClassDeltas() {
-        return classDeltas;
-    }
-
-    public void setClassDeltas(Set<IClassDefinitionDelta> classDeltas) {
-        this.classDeltas = classDeltas;
-    }
-
-    public Set<IAnnotationDelta> getAnnotationDeltas() {
-        return annotationDeltas;
-    }
-
-    public void setAnnotationDeltas(Set<IAnnotationDelta> annotationDeltas) {
-        this.annotationDeltas = annotationDeltas;
-    }
-
-}
diff --git a/tools/signature-tools/src/signature/compare/model/impl/SigParameterDelta.java b/tools/signature-tools/src/signature/compare/model/impl/SigParameterDelta.java
deleted file mode 100644
index aee6466..0000000
--- a/tools/signature-tools/src/signature/compare/model/impl/SigParameterDelta.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model.impl;
-
-import java.util.Set;
-
-import signature.compare.model.IAnnotationDelta;
-import signature.compare.model.IParameterDelta;
-import signature.compare.model.ITypeReferenceDelta;
-import signature.model.IParameter;
-
-public class SigParameterDelta extends SigDelta<IParameter> implements
-        IParameterDelta {
-
-    private ITypeReferenceDelta<?> typeDelta;
-    private Set<IAnnotationDelta> annotationDeltas;
-
-    public SigParameterDelta(IParameter from, IParameter to) {
-        super(from, to);
-    }
-
-    public ITypeReferenceDelta<?> getTypeDelta() {
-        return typeDelta;
-    }
-
-    public void setTypeDelta(ITypeReferenceDelta<?> typeDelta) {
-        this.typeDelta = typeDelta;
-    }
-
-    public Set<IAnnotationDelta> getAnnotationDeltas() {
-        return annotationDeltas;
-    }
-
-    public void setAnnotationDeltas(Set<IAnnotationDelta> annotationDeltas) {
-        this.annotationDeltas = annotationDeltas;
-    }
-}
diff --git a/tools/signature-tools/src/signature/compare/model/impl/SigParameterizedTypeDelta.java b/tools/signature-tools/src/signature/compare/model/impl/SigParameterizedTypeDelta.java
deleted file mode 100644
index 08fbc21..0000000
--- a/tools/signature-tools/src/signature/compare/model/impl/SigParameterizedTypeDelta.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model.impl;
-
-import java.util.Set;
-
-import signature.compare.model.IParameterizedTypeDelta;
-import signature.compare.model.ITypeReferenceDelta;
-import signature.model.IParameterizedType;
-
-public class SigParameterizedTypeDelta extends SigTypeDelta<IParameterizedType>
-        implements IParameterizedTypeDelta {
-
-    private ITypeReferenceDelta<?> ownerTypeDelta;
-    private ITypeReferenceDelta<?> rawTypeDelta;
-    private Set<ITypeReferenceDelta<?>> argumentTypeDeltas;
-
-    public SigParameterizedTypeDelta(IParameterizedType from,
-            IParameterizedType to) {
-        super(from, to);
-    }
-
-    public ITypeReferenceDelta<?> getOwnerTypeDelta() {
-        return ownerTypeDelta;
-    }
-
-    public void setOwnerTypeDelta(ITypeReferenceDelta<?> ownerTypeDelta) {
-        this.ownerTypeDelta = ownerTypeDelta;
-    }
-
-    public ITypeReferenceDelta<?> getRawTypeDelta() {
-        return rawTypeDelta;
-    }
-
-    public void setRawTypeDelta(ITypeReferenceDelta<?> rawTypeDelta) {
-        this.rawTypeDelta = rawTypeDelta;
-    }
-
-    public Set<ITypeReferenceDelta<?>> getArgumentTypeDeltas() {
-        return argumentTypeDeltas;
-    }
-
-    public void setArgumentTypeDeltas(
-            Set<ITypeReferenceDelta<?>> argumentTypeDeltas) {
-        this.argumentTypeDeltas = argumentTypeDeltas;
-    }
-}
diff --git a/tools/signature-tools/src/signature/compare/model/impl/SigPrimitiveTypeDelta.java b/tools/signature-tools/src/signature/compare/model/impl/SigPrimitiveTypeDelta.java
deleted file mode 100644
index 03be8fa..0000000
--- a/tools/signature-tools/src/signature/compare/model/impl/SigPrimitiveTypeDelta.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model.impl;
-
-import signature.compare.model.IPrimitiveTypeDelta;
-import signature.model.IPrimitiveType;
-
-public class SigPrimitiveTypeDelta extends SigTypeDelta<IPrimitiveType>
-        implements IPrimitiveTypeDelta {
-
-    public SigPrimitiveTypeDelta(IPrimitiveType from, IPrimitiveType to) {
-        super(from, to);
-    }
-}
diff --git a/tools/signature-tools/src/signature/compare/model/impl/SigTypeDefinitionDelta.java b/tools/signature-tools/src/signature/compare/model/impl/SigTypeDefinitionDelta.java
deleted file mode 100644
index c0bff8e..0000000
--- a/tools/signature-tools/src/signature/compare/model/impl/SigTypeDefinitionDelta.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model.impl;
-
-import signature.compare.model.ITypeDefinitionDelta;
-import signature.model.ITypeDefinition;
-
-public abstract class SigTypeDefinitionDelta<T extends ITypeDefinition> extends
-        SigDelta<T> implements ITypeDefinitionDelta<T> {
-
-    public SigTypeDefinitionDelta(T from, T to) {
-        super(from, to);
-    }
-}
diff --git a/tools/signature-tools/src/signature/compare/model/impl/SigTypeDelta.java b/tools/signature-tools/src/signature/compare/model/impl/SigTypeDelta.java
deleted file mode 100644
index 718258c..0000000
--- a/tools/signature-tools/src/signature/compare/model/impl/SigTypeDelta.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model.impl;
-
-import signature.compare.model.ITypeReferenceDelta;
-import signature.model.ITypeReference;
-
-public class SigTypeDelta<T extends ITypeReference> extends SigDelta<T>
-        implements ITypeReferenceDelta<T> {
-
-    public SigTypeDelta(T from, T to) {
-        super(from, to);
-    }
-}
diff --git a/tools/signature-tools/src/signature/compare/model/impl/SigTypeVariableDefinitionDelta.java b/tools/signature-tools/src/signature/compare/model/impl/SigTypeVariableDefinitionDelta.java
deleted file mode 100644
index 348c728..0000000
--- a/tools/signature-tools/src/signature/compare/model/impl/SigTypeVariableDefinitionDelta.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model.impl;
-
-import signature.compare.model.IGenericDeclarationDelta;
-import signature.compare.model.ITypeVariableDefinitionDelta;
-import signature.compare.model.IUpperBoundsDelta;
-import signature.model.ITypeVariableDefinition;
-
-public class SigTypeVariableDefinitionDelta extends
-        SigDelta<ITypeVariableDefinition> implements
-        ITypeVariableDefinitionDelta {
-
-    private IUpperBoundsDelta upperBoundsDelta;
-    private IGenericDeclarationDelta genericDeclarationDelta;
-
-    public SigTypeVariableDefinitionDelta(ITypeVariableDefinition from,
-            ITypeVariableDefinition to) {
-        super(from, to);
-    }
-
-    public IUpperBoundsDelta getUpperBoundsDelta() {
-        return upperBoundsDelta;
-    }
-
-    public void setUpperBoundsDelta(IUpperBoundsDelta upperBoundsDelta) {
-        this.upperBoundsDelta = upperBoundsDelta;
-    }
-
-    public IGenericDeclarationDelta getGenericDeclarationDelta() {
-        return genericDeclarationDelta;
-    }
-
-    public void setGenericDeclarationDelta(
-            IGenericDeclarationDelta genericDeclarationDelta) {
-        this.genericDeclarationDelta = genericDeclarationDelta;
-    }
-}
diff --git a/tools/signature-tools/src/signature/compare/model/impl/SigTypeVariableReferenceDelta.java b/tools/signature-tools/src/signature/compare/model/impl/SigTypeVariableReferenceDelta.java
deleted file mode 100644
index 4414a16..0000000
--- a/tools/signature-tools/src/signature/compare/model/impl/SigTypeVariableReferenceDelta.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model.impl;
-
-import signature.compare.model.IGenericDeclarationDelta;
-import signature.compare.model.ITypeReferenceDelta;
-import signature.model.ITypeVariableReference;
-
-public class SigTypeVariableReferenceDelta extends
-        SigDelta<ITypeVariableReference> implements
-        ITypeReferenceDelta<ITypeVariableReference> {
-
-    private IGenericDeclarationDelta genericDeclarationDelta;
-
-    public SigTypeVariableReferenceDelta(ITypeVariableReference from,
-            ITypeVariableReference to) {
-        super(from, to);
-    }
-
-    public IGenericDeclarationDelta getGenericDeclarationDelta() {
-        return genericDeclarationDelta;
-    }
-
-    public void setGenericDeclarationDelta(
-            IGenericDeclarationDelta genericDeclarationDelta) {
-        this.genericDeclarationDelta = genericDeclarationDelta;
-    }
-}
diff --git a/tools/signature-tools/src/signature/compare/model/impl/SigUpperBoundsDelta.java b/tools/signature-tools/src/signature/compare/model/impl/SigUpperBoundsDelta.java
deleted file mode 100644
index 8822b26..0000000
--- a/tools/signature-tools/src/signature/compare/model/impl/SigUpperBoundsDelta.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model.impl;
-
-import java.util.List;
-import java.util.Set;
-
-import signature.compare.model.ITypeReferenceDelta;
-import signature.compare.model.IUpperBoundsDelta;
-import signature.model.ITypeReference;
-
-public class SigUpperBoundsDelta extends SigDelta<List<ITypeReference>>
-        implements IUpperBoundsDelta {
-
-    private ITypeReferenceDelta<?> firstUpperBoundDelta;
-    private Set<ITypeReferenceDelta<?>> remainingUpperBoundDeltas;
-
-    public SigUpperBoundsDelta(List<ITypeReference> from,
-            List<ITypeReference> to) {
-        super(from, to);
-    }
-
-
-    public ITypeReferenceDelta<?> getFirstUpperBoundDelta() {
-        return firstUpperBoundDelta;
-    }
-
-    public void setFirstUpperBoundDelta(
-            ITypeReferenceDelta<?> firstUpperBoundDelta) {
-        this.firstUpperBoundDelta = firstUpperBoundDelta;
-    }
-
-    public Set<ITypeReferenceDelta<?>> getRemainingUpperBoundDeltas() {
-        return remainingUpperBoundDeltas;
-    }
-
-    public void setRemainingUpperBoundDeltas(
-            Set<ITypeReferenceDelta<?>> remainingUpperBoundDeltas) {
-        this.remainingUpperBoundDeltas = remainingUpperBoundDeltas;
-    }
-}
diff --git a/tools/signature-tools/src/signature/compare/model/impl/SigValueDelta.java b/tools/signature-tools/src/signature/compare/model/impl/SigValueDelta.java
deleted file mode 100644
index 9521f0e..0000000
--- a/tools/signature-tools/src/signature/compare/model/impl/SigValueDelta.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model.impl;
-
-import signature.compare.model.IValueDelta;
-
-public class SigValueDelta extends SigDelta<Object> implements IValueDelta {
-
-    public SigValueDelta(Object from, Object to) {
-        super(from, to);
-    }
-}
diff --git a/tools/signature-tools/src/signature/compare/model/impl/SigWildcardTypeDelta.java b/tools/signature-tools/src/signature/compare/model/impl/SigWildcardTypeDelta.java
deleted file mode 100644
index e6cafcb..0000000
--- a/tools/signature-tools/src/signature/compare/model/impl/SigWildcardTypeDelta.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model.impl;
-
-import signature.compare.model.ITypeReferenceDelta;
-import signature.compare.model.IUpperBoundsDelta;
-import signature.compare.model.IWildcardTypeDelta;
-import signature.model.IWildcardType;
-
-public class SigWildcardTypeDelta extends SigTypeDelta<IWildcardType>
-        implements IWildcardTypeDelta {
-
-    private ITypeReferenceDelta<?> lowerBoundDelta;
-    private IUpperBoundsDelta upperBoundDelta;
-
-    public SigWildcardTypeDelta(IWildcardType from, IWildcardType to) {
-        super(from, to);
-    }
-
-    public ITypeReferenceDelta<?> getLowerBoundDelta() {
-        return lowerBoundDelta;
-    }
-
-    public void setLowerBoundDelta(ITypeReferenceDelta<?> lowerBoundDelta) {
-        this.lowerBoundDelta = lowerBoundDelta;
-    }
-
-    public IUpperBoundsDelta getUpperBoundDelta() {
-        return upperBoundDelta;
-    }
-
-    public void setUpperBoundDelta(IUpperBoundsDelta upperBoundDelta) {
-        this.upperBoundDelta = upperBoundDelta;
-    }
-}
diff --git a/tools/signature-tools/src/signature/compare/model/subst/ArrayTypeProjection.java b/tools/signature-tools/src/signature/compare/model/subst/ArrayTypeProjection.java
deleted file mode 100644
index 428146e..0000000
--- a/tools/signature-tools/src/signature/compare/model/subst/ArrayTypeProjection.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model.subst;
-
-import java.util.Map;
-
-import signature.model.IArrayType;
-import signature.model.ITypeReference;
-import signature.model.ITypeVariableDefinition;
-import signature.model.impl.SigArrayType;
-
-public class ArrayTypeProjection implements IArrayType {
-
-    private final IArrayType original;
-    private final Map<ITypeVariableDefinition, ITypeReference> mappings;
-
-    public ArrayTypeProjection(IArrayType original,
-            Map<ITypeVariableDefinition, ITypeReference> mappings) {
-        this.original = original;
-        this.mappings = mappings;
-    }
-
-    public ITypeReference getComponentType() {
-        return ViewpointAdapter.substitutedTypeReference(original
-                .getComponentType(), mappings);
-    }
-
-    @Override
-    public int hashCode() {
-        return SigArrayType.hashCode(this);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        return SigArrayType.equals(this, obj);
-    }
-
-    @Override
-    public String toString() {
-        return "(" + SigArrayType.toString(this) + " : " + mappings + " )";
-    }
-}
diff --git a/tools/signature-tools/src/signature/compare/model/subst/ClassProjection.java b/tools/signature-tools/src/signature/compare/model/subst/ClassProjection.java
deleted file mode 100644
index 630d102..0000000
--- a/tools/signature-tools/src/signature/compare/model/subst/ClassProjection.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model.subst;
-
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import signature.model.IAnnotation;
-import signature.model.IAnnotationField;
-import signature.model.IClassDefinition;
-import signature.model.IConstructor;
-import signature.model.IEnumConstant;
-import signature.model.IField;
-import signature.model.IMethod;
-import signature.model.ITypeReference;
-import signature.model.ITypeVariableDefinition;
-import signature.model.Kind;
-import signature.model.Modifier;
-import signature.model.impl.SigClassDefinition;
-
-public class ClassProjection implements IClassDefinition {
-
-    private final IClassDefinition original;
-    private final Map<ITypeVariableDefinition, ITypeReference> substitutions;
-
-    public ClassProjection(IClassDefinition original,
-            Map<ITypeVariableDefinition, ITypeReference> mapping) {
-        this.original = original;
-        this.substitutions = mapping;
-    }
-
-    public Set<IAnnotationField> getAnnotationFields() {
-        throw new UnsupportedOperationException();
-    }
-
-    public Set<IAnnotation> getAnnotations() {
-        throw new UnsupportedOperationException();
-    }
-
-    public Set<IConstructor> getConstructors() {
-        throw new UnsupportedOperationException();
-    }
-
-    public IClassDefinition getDeclaringClass() {
-        throw new UnsupportedOperationException();
-    }
-
-    public Set<IEnumConstant> getEnumConstants() {
-        throw new UnsupportedOperationException();
-    }
-
-    public Set<IField> getFields() {
-        throw new UnsupportedOperationException();
-    }
-
-    public Set<IClassDefinition> getInnerClasses() {
-        throw new UnsupportedOperationException();
-    }
-
-    Set<ITypeReference> interfaces = null;
-
-    public Set<ITypeReference> getInterfaces() {
-        if (interfaces == null) {
-            Set<ITypeReference> originalInterfaces = original.getInterfaces();
-            if (originalInterfaces == null) {
-                interfaces = Collections.emptySet();
-            } else {
-                interfaces = new HashSet<ITypeReference>();
-                for (ITypeReference interfaze : originalInterfaces) {
-                    interfaces.add(ViewpointAdapter.substitutedTypeReference(
-                            interfaze, substitutions));
-                }
-                interfaces = Collections.unmodifiableSet(interfaces);
-            }
-        }
-        return interfaces;
-    }
-
-    public Kind getKind() {
-        return original.getKind();
-    }
-
-
-    Set<IMethod> methods = null;
-
-    public Set<IMethod> getMethods() {
-        if (methods == null) {
-            Set<IMethod> originalMethods = original.getMethods();
-            if (originalMethods == null) {
-                methods = Collections.emptySet();
-            } else {
-                methods = new HashSet<IMethod>();
-                for (IMethod m : original.getMethods()) {
-                    methods.add(new MethodProjection(m, substitutions));
-                }
-                methods = Collections.unmodifiableSet(methods);
-            }
-        }
-        return methods;
-    }
-
-    public Set<Modifier> getModifiers() {
-        return original.getModifiers();
-    }
-
-    public String getName() {
-        return original.getName();
-    }
-
-    public List<String> getPackageFragments() {
-        return original.getPackageFragments();
-    }
-
-    public String getPackageName() {
-        return original.getPackageName();
-    }
-
-    public String getQualifiedName() {
-        return original.getQualifiedName();
-    }
-
-    private boolean superClassInit = false;
-    private ITypeReference superClass = null;
-
-    public ITypeReference getSuperClass() {
-        if (!superClassInit) {
-            ITypeReference originalSuperClass = original.getSuperClass();
-            if (originalSuperClass != null) {
-                superClass = ViewpointAdapter.substitutedTypeReference(original
-                        .getSuperClass(), substitutions);
-            }
-            superClassInit = true;
-        }
-        return superClass;
-    }
-
-    // Definitions of type variables are not substituted
-    public List<ITypeVariableDefinition> getTypeParameters() {
-        return original.getTypeParameters();
-    }
-
-    @Override
-    public int hashCode() {
-        return SigClassDefinition.hashCode(this);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        return SigClassDefinition.equals(this, obj);
-    }
-
-    @Override
-    public String toString() {
-        return "(" + SigClassDefinition.toString(this) + " : " + substitutions
-                + " )";
-    }
-
-}
diff --git a/tools/signature-tools/src/signature/compare/model/subst/ClassReferenceProjection.java b/tools/signature-tools/src/signature/compare/model/subst/ClassReferenceProjection.java
deleted file mode 100644
index 648ccf8..0000000
--- a/tools/signature-tools/src/signature/compare/model/subst/ClassReferenceProjection.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model.subst;
-
-import signature.model.IClassDefinition;
-import signature.model.IClassReference;
-import signature.model.ITypeReference;
-import signature.model.ITypeVariableDefinition;
-import signature.model.impl.SigClassReference;
-
-import java.util.Map;
-
-public class ClassReferenceProjection implements IClassReference {
-
-    private final IClassReference original;
-    private final Map<ITypeVariableDefinition, ITypeReference> mappings;
-
-    public ClassReferenceProjection(IClassReference original,
-            Map<ITypeVariableDefinition, ITypeReference> mappings) {
-        this.original = original;
-        this.mappings = mappings;
-    }
-
-    public IClassDefinition getClassDefinition() {
-        return new ClassProjection(original.getClassDefinition(), mappings);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        return SigClassReference.equals(this, obj);
-    }
-
-    @Override
-    public int hashCode() {
-        return SigClassReference.hashCode(this);
-    }
-
-    @Override
-    public String toString() {
-        return "(" + SigClassReference.toString(this) + " : " + mappings + " )";
-    }
-}
diff --git a/tools/signature-tools/src/signature/compare/model/subst/ConstructorProjection.java b/tools/signature-tools/src/signature/compare/model/subst/ConstructorProjection.java
deleted file mode 100644
index 1ffd616..0000000
--- a/tools/signature-tools/src/signature/compare/model/subst/ConstructorProjection.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model.subst;
-
-import signature.model.IConstructor;
-import signature.model.ITypeReference;
-import signature.model.ITypeVariableDefinition;
-
-import java.util.Map;
-
-public class ConstructorProjection extends ExecutableMemberProjection implements
-        IConstructor {
-
-    public ConstructorProjection(IConstructor original,
-            Map<ITypeVariableDefinition, ITypeReference> mappings) {
-        super(original, mappings);
-    }
-
-}
diff --git a/tools/signature-tools/src/signature/compare/model/subst/ExecutableMemberProjection.java b/tools/signature-tools/src/signature/compare/model/subst/ExecutableMemberProjection.java
deleted file mode 100644
index f96ac54..0000000
--- a/tools/signature-tools/src/signature/compare/model/subst/ExecutableMemberProjection.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model.subst;
-
-import signature.model.IAnnotation;
-import signature.model.IClassDefinition;
-import signature.model.IExecutableMember;
-import signature.model.IParameter;
-import signature.model.ITypeReference;
-import signature.model.ITypeVariableDefinition;
-import signature.model.Modifier;
-
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-public abstract class ExecutableMemberProjection implements IExecutableMember {
-
-    private final IExecutableMember original;
-    private final Map<ITypeVariableDefinition, ITypeReference> mappings;
-
-    public ExecutableMemberProjection(IExecutableMember original,
-            Map<ITypeVariableDefinition, ITypeReference> mappings) {
-        this.original = original;
-        this.mappings = mappings;
-    }
-
-    public Set<IAnnotation> getAnnotations() {
-        return original.getAnnotations();
-    }
-
-    public IClassDefinition getDeclaringClass() {
-        throw new UnsupportedOperationException();
-    }
-
-    public Set<ITypeReference> getExceptions() {
-        return ViewpointAdapter.substitutedTypeReferences(original
-                .getExceptions(), mappings);
-    }
-
-    public Set<Modifier> getModifiers() {
-        return original.getModifiers();
-    }
-
-    public String getName() {
-        return original.getName();
-    }
-
-    public List<IParameter> getParameters() {
-        List<IParameter> result = new LinkedList<IParameter>();
-        for (IParameter parameter : original.getParameters()) {
-            result.add(new ParameterProjection(parameter, mappings));
-        }
-        return result;
-    }
-
-    public List<ITypeVariableDefinition> getTypeParameters() {
-        // FIXME bounds need to be substituted ?
-        return original.getTypeParameters();
-    }
-}
diff --git a/tools/signature-tools/src/signature/compare/model/subst/MethodProjection.java b/tools/signature-tools/src/signature/compare/model/subst/MethodProjection.java
deleted file mode 100644
index c98fb09..0000000
--- a/tools/signature-tools/src/signature/compare/model/subst/MethodProjection.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model.subst;
-
-import signature.model.IMethod;
-import signature.model.ITypeReference;
-import signature.model.ITypeVariableDefinition;
-import signature.model.impl.SigMethod;
-
-import java.util.Map;
-
-public class MethodProjection extends ExecutableMemberProjection implements
-        IMethod {
-
-    private final IMethod original;
-    private Map<ITypeVariableDefinition, ITypeReference> mappings;
-
-    public MethodProjection(IMethod original,
-            Map<ITypeVariableDefinition, ITypeReference> mappings) {
-        super(original, mappings);
-        this.mappings = mappings;
-        this.original = original;
-    }
-
-    public ITypeReference getReturnType() {
-        return ViewpointAdapter.substitutedTypeReference(original
-                .getReturnType(), mappings);
-    }
-
-    @Override
-    public String toString() {
-        return "(" + SigMethod.toString(this) + " : " + mappings + " )";
-    }
-}
diff --git a/tools/signature-tools/src/signature/compare/model/subst/ParameterProjection.java b/tools/signature-tools/src/signature/compare/model/subst/ParameterProjection.java
deleted file mode 100644
index 9c48ab7..0000000
--- a/tools/signature-tools/src/signature/compare/model/subst/ParameterProjection.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model.subst;
-
-import signature.model.IAnnotation;
-import signature.model.IParameter;
-import signature.model.ITypeReference;
-import signature.model.ITypeVariableDefinition;
-
-import java.util.Map;
-import java.util.Set;
-
-public class ParameterProjection implements IParameter {
-    private IParameter original;
-    private Map<ITypeVariableDefinition, ITypeReference> mappings;
-
-    public ParameterProjection(IParameter original,
-            Map<ITypeVariableDefinition, ITypeReference> mappings) {
-        this.original = original;
-        this.mappings = mappings;
-    }
-
-    public Set<IAnnotation> getAnnotations() {
-        return original.getAnnotations();
-    }
-
-    public ITypeReference getType() {
-        return ViewpointAdapter.substitutedTypeReference(original.getType(),
-                mappings);
-    }
-
-    @Override
-    public String toString() {
-        return getType().toString();
-    }
-}
diff --git a/tools/signature-tools/src/signature/compare/model/subst/ParameterizedTypeProjection.java b/tools/signature-tools/src/signature/compare/model/subst/ParameterizedTypeProjection.java
deleted file mode 100644
index 59836db..0000000
--- a/tools/signature-tools/src/signature/compare/model/subst/ParameterizedTypeProjection.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model.subst;
-
-import signature.model.IClassReference;
-import signature.model.IParameterizedType;
-import signature.model.ITypeReference;
-import signature.model.ITypeVariableDefinition;
-import signature.model.impl.SigParameterizedType;
-
-import java.util.List;
-import java.util.Map;
-
-public class ParameterizedTypeProjection implements IParameterizedType {
-
-    private final IParameterizedType original;
-
-    private final Map<ITypeVariableDefinition, ITypeReference> mappings;
-
-    public ParameterizedTypeProjection(IParameterizedType original,
-            Map<ITypeVariableDefinition, ITypeReference> mappings) {
-        this.original = original;
-        this.mappings = mappings;
-    }
-
-    public ITypeReference getOwnerType() {
-        ITypeReference ownerType = original.getOwnerType();
-        if (ownerType == null) {
-            return null;
-        }
-        return ViewpointAdapter.substitutedTypeReference(ownerType, mappings);
-    }
-
-    private IClassReference rawType = null;
-
-    /**
-     * Returns the raw type with substituted type variables.
-     * 
-     * @return the raw type with substituted type variables
-     */
-    public IClassReference getRawType() {
-        if (rawType == null) {
-            rawType = (IClassReference) ViewpointAdapter
-                    .substitutedTypeReference(original.getRawType(),
-                            ViewpointAdapter.createTypeMapping(this, original
-                                    .getRawType().getClassDefinition()));
-        }
-        return rawType;
-    }
-
-    private List<ITypeReference> arguments = null;
-
-    public List<ITypeReference> getTypeArguments() {
-        if (arguments == null) {
-            arguments = ViewpointAdapter.substitutedTypeReferences(original
-                    .getTypeArguments(), mappings);
-        }
-        return arguments;
-    }
-
-    @Override
-    public int hashCode() {
-        return SigParameterizedType.hashCode(this);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        return SigParameterizedType.equals(this, obj);
-    }
-
-    @Override
-    public String toString() {
-        return SigParameterizedType.toString(this);
-    }
-}
diff --git a/tools/signature-tools/src/signature/compare/model/subst/ViewpointAdapter.java b/tools/signature-tools/src/signature/compare/model/subst/ViewpointAdapter.java
deleted file mode 100644
index 88f457f..0000000
--- a/tools/signature-tools/src/signature/compare/model/subst/ViewpointAdapter.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model.subst;
-
-import signature.model.IArrayType;
-import signature.model.IClassDefinition;
-import signature.model.IClassReference;
-import signature.model.IParameterizedType;
-import signature.model.IPrimitiveType;
-import signature.model.ITypeReference;
-import signature.model.ITypeVariableDefinition;
-import signature.model.ITypeVariableReference;
-import signature.model.IWildcardType;
-import signature.model.impl.SigClassReference;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-public class ViewpointAdapter {
-
-    static Map<ITypeVariableDefinition, ITypeReference> createTypeMapping(
-            IParameterizedType paramameterizedType,
-            IClassDefinition parameterizedTypeDefinition) {
-        List<ITypeVariableDefinition> typeParameters =
-                parameterizedTypeDefinition.getTypeParameters();
-        List<ITypeReference> actualTypeArguments = paramameterizedType
-                .getTypeArguments();
-        if (actualTypeArguments == null || typeParameters == null) {
-            return Collections.emptyMap();
-        }
-        Map<ITypeVariableDefinition, ITypeReference> substitution =
-                new HashMap<ITypeVariableDefinition, ITypeReference>();
-        Iterator<ITypeVariableDefinition> paramsIterator = typeParameters
-                .iterator();
-        Iterator<ITypeReference> argumentsIterator = actualTypeArguments
-                .iterator();
-        while (paramsIterator.hasNext() && argumentsIterator.hasNext()) {
-            substitution.put(paramsIterator.next(), argumentsIterator.next());
-        }
-        return substitution;
-    }
-
-    public static Set<ITypeReference> substitutedTypeReferences(
-            Set<ITypeReference> original,
-            Map<ITypeVariableDefinition, ITypeReference> mappings) {
-        List<ITypeReference> result = new ArrayList<ITypeReference>(original);
-        return new HashSet<ITypeReference>(substitutedTypeReferences(result,
-                mappings));
-    }
-
-    public static List<ITypeReference> substitutedTypeReferences(
-            List<ITypeReference> original,
-            Map<ITypeVariableDefinition, ITypeReference> mappings) {
-        List<ITypeReference> result = new ArrayList<ITypeReference>(original
-                .size());
-        for (ITypeReference typeReference : original) {
-            result.add(substitutedTypeReference(typeReference, mappings));
-        }
-        return result;
-    }
-
-    public static ITypeReference substitutedTypeReference(
-            ITypeReference original,
-            Map<ITypeVariableDefinition, ITypeReference> mappings) {
-        ITypeReference type = original;
-        if (type instanceof IClassReference) {
-            return new ClassReferenceProjection((IClassReference) original,
-                    mappings);
-        } else if (type instanceof IPrimitiveType) {
-            return type;
-        } else if (type instanceof IArrayType) {
-            return new ArrayTypeProjection((IArrayType) type, mappings);
-        } else if (type instanceof IParameterizedType) {
-            return new ParameterizedTypeProjection((IParameterizedType) type,
-                    mappings);
-        } else if (type instanceof IWildcardType) {
-            return new WildcardTypeProjection((IWildcardType) type, mappings);
-        } else if (type instanceof ITypeVariableReference) {
-            // here happens the substitution
-            ITypeReference subst = mappings.get(((ITypeVariableReference) type)
-                    .getTypeVariableDefinition());
-            return subst != null ? subst : type;
-        }
-        throw new IllegalStateException();
-    }
-
-    public static IClassReference getReferenceTo(IClassDefinition definition) {
-        return new SigClassReference(new ClassProjection(definition,
-                new HashMap<ITypeVariableDefinition, ITypeReference>()));
-    }
-}
diff --git a/tools/signature-tools/src/signature/compare/model/subst/WildcardTypeProjection.java b/tools/signature-tools/src/signature/compare/model/subst/WildcardTypeProjection.java
deleted file mode 100644
index a59873c..0000000
--- a/tools/signature-tools/src/signature/compare/model/subst/WildcardTypeProjection.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.compare.model.subst;
-
-import signature.model.ITypeReference;
-import signature.model.ITypeVariableDefinition;
-import signature.model.IWildcardType;
-import signature.model.impl.SigWildcardType;
-
-import java.util.List;
-import java.util.Map;
-
-public class WildcardTypeProjection implements IWildcardType {
-
-    private final IWildcardType original;
-
-    private final Map<ITypeVariableDefinition, ITypeReference> mappings;
-
-    public WildcardTypeProjection(IWildcardType original,
-            Map<ITypeVariableDefinition, ITypeReference> mappings) {
-        this.original = original;
-        this.mappings = mappings;
-    }
-
-    public ITypeReference getLowerBound() {
-        return ViewpointAdapter.substitutedTypeReference(original
-                .getLowerBound(), mappings);
-    }
-
-    public List<ITypeReference> getUpperBounds() {
-        return ViewpointAdapter.substitutedTypeReferences(original
-                .getUpperBounds(), mappings);
-    }
-
-    @Override
-    public int hashCode() {
-        return SigWildcardType.hashCode(this);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        return SigWildcardType.equals(this, obj);
-    }
-
-    @Override
-    public String toString() {
-        return SigWildcardType.toString(this);
-    }
-}
diff --git a/tools/signature-tools/src/signature/converter/Main.java b/tools/signature-tools/src/signature/converter/Main.java
deleted file mode 100644
index f426877..0000000
--- a/tools/signature-tools/src/signature/converter/Main.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.converter;
-
-import signature.UsageException;
-import signature.converter.dex.DexFactory;
-import signature.converter.doclet.DocletFactory;
-import signature.io.IApiLoader;
-import signature.io.IApiExternalizer;
-import signature.io.impl.BinaryApi;
-
-import java.io.IOException;
-import java.util.HashSet;
-import java.util.Set;
-
-public class Main {
-    // (doclet | dex) sourcefiles --out file --name name --packages packageName{
-    // packageName}" +
-    public static void main(String[] args) throws IOException {
-        String type = args[0];
-        Set<String> sources = new HashSet<String>();
-        int at = 1;
-        for (/* at */; at < args.length; at++) {
-            if ("--out".equals(args[at])) {
-                break;
-            }
-            sources.add(args[at]);
-        }
-
-        if (!"--out".equals(args[at])) {
-            throw new UsageException();
-        }
-        String targetFile = args[++at];
-
-        if (!"--name".equals(args[++at])) {
-            throw new UsageException();
-        }
-        String name = args[++at];
-
-        if (!"--packages".equals(args[++at])) {
-            throw new UsageException();
-        }
-        Set<String> packages = new HashSet<String>();
-        ++at;
-        for (/* at */; at < args.length; at++) {
-            packages.add(args[at]);
-        }
-
-        IApiExternalizer externalizer = new BinaryApi();
-        IApiLoader factory = null;
-
-        if ("doclet".equals(type)) {
-            factory = new DocletFactory();
-        } else if ("dex".equals(type)) {
-            factory = new DexFactory();
-        } else {
-            throw new UsageException();
-        }
-
-        externalizer.externalizeApi(targetFile, factory.loadApi(name,
-                Visibility.PROTECTED, sources, packages));
-    }
-}
diff --git a/tools/signature-tools/src/signature/converter/Visibility.java b/tools/signature-tools/src/signature/converter/Visibility.java
deleted file mode 100644
index 653c617..0000000
--- a/tools/signature-tools/src/signature/converter/Visibility.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.converter;
-
-/**
- * This enum defines which members are part of the API.
- * 
- * <ul>
- * <li><code>PUBLIC</code> only the public classes and members are included.
- * <li><code>PROTECTED</code> the public and protected classes members are
- * included.
- * <li><code>PACKAGE</code> the public, protected and package visible classes
- * and members are included.
- * <li><code>PRIVATE</code> all classes and members are included.
- * </ul>
- * <p>
- * The default visibility mode is <code>PROTECTED</code>.
- * 
- */
-public enum Visibility {
-    PUBLIC, PROTECTED, PACKAGE, PRIVATE;
-}
diff --git a/tools/signature-tools/src/signature/converter/dex/DexFactory.java b/tools/signature-tools/src/signature/converter/dex/DexFactory.java
deleted file mode 100644
index b7cc00e..0000000
--- a/tools/signature-tools/src/signature/converter/dex/DexFactory.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.converter.dex;
-
-import dex.structure.DexFile;
-import signature.converter.Visibility;
-import signature.io.IApiLoader;
-import signature.model.IApi;
-import signature.model.IPackage;
-import signature.model.impl.SigApi;
-
-import java.io.IOException;
-import java.util.Iterator;
-import java.util.Set;
-
-public class DexFactory implements IApiLoader {
-
-    public IApi loadApi(String name, Visibility visibility,
-            Set<String> fileNames, Set<String> packageNames) throws
-            IOException {
-        DexToSigConverter converter = new DexToSigConverter();
-        Set<DexFile> files = DexUtil.getDexFiles(fileNames);
-        SigApi api = converter.convertApi(name, files, visibility);
-
-        Iterator<IPackage> it = api.getPackages().iterator();
-        while (it.hasNext()) {
-            IPackage aPackage = it.next();
-            boolean found = false;
-            for (String packageName : packageNames) {
-                if (aPackage.getName().equals(packageName)) {
-                    found = true;
-                }
-            }
-            if (!found) {
-                it.remove();
-            }
-        }
-        return api;
-    }
-}
diff --git a/tools/signature-tools/src/signature/converter/dex/DexToSigConverter.java b/tools/signature-tools/src/signature/converter/dex/DexToSigConverter.java
deleted file mode 100644
index 13312bd..0000000
--- a/tools/signature-tools/src/signature/converter/dex/DexToSigConverter.java
+++ /dev/null
@@ -1,938 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.converter.dex;
-
-import static signature.converter.dex.DexUtil.convertAnyWay;
-import static signature.converter.dex.DexUtil.declaresExceptions;
-import static signature.converter.dex.DexUtil.declaresMemberClasses;
-import static signature.converter.dex.DexUtil.findPackageInfo;
-import static signature.converter.dex.DexUtil.getClassModifiers;
-import static signature.converter.dex.DexUtil.getClassName;
-import static signature.converter.dex.DexUtil.getDefaultMappingsAnnotation;
-import static signature.converter.dex.DexUtil.getDexName;
-import static signature.converter.dex.DexUtil.getEnclosingClassName;
-import static signature.converter.dex.DexUtil.getExceptionSignature;
-import static signature.converter.dex.DexUtil.getGenericSignature;
-import static signature.converter.dex.DexUtil.getKind;
-import static signature.converter.dex.DexUtil.getMemberClassNames;
-import static signature.converter.dex.DexUtil.getModifier;
-import static signature.converter.dex.DexUtil.getPackageName;
-import static signature.converter.dex.DexUtil.getQualifiedName;
-import static signature.converter.dex.DexUtil.hasAnnotationDefaultSignature;
-import static signature.converter.dex.DexUtil.hasGenericSignature;
-import static signature.converter.dex.DexUtil.isAnnotation;
-import static signature.converter.dex.DexUtil.isConstructor;
-import static signature.converter.dex.DexUtil.isEnclosingClass;
-import static signature.converter.dex.DexUtil.isEnum;
-import static signature.converter.dex.DexUtil.isInternalAnnotation;
-import static signature.converter.dex.DexUtil.isJavaLangObject;
-import static signature.converter.dex.DexUtil.isMethod;
-import static signature.converter.dex.DexUtil.isVisible;
-import static signature.converter.dex.DexUtil.splitTypeList;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import signature.converter.Visibility;
-import signature.model.IAnnotation;
-import signature.model.IAnnotationElement;
-import signature.model.IAnnotationField;
-import signature.model.IClassDefinition;
-import signature.model.IClassReference;
-import signature.model.IConstructor;
-import signature.model.IEnumConstant;
-import signature.model.IField;
-import signature.model.IMethod;
-import signature.model.IPackage;
-import signature.model.IParameter;
-import signature.model.ITypeReference;
-import signature.model.ITypeVariableDefinition;
-import signature.model.Kind;
-import signature.model.Modifier;
-import signature.model.impl.SigAnnotation;
-import signature.model.impl.SigAnnotationElement;
-import signature.model.impl.SigAnnotationField;
-import signature.model.impl.SigApi;
-import signature.model.impl.SigClassDefinition;
-import signature.model.impl.SigClassReference;
-import signature.model.impl.SigConstructor;
-import signature.model.impl.SigEnumConstant;
-import signature.model.impl.SigExecutableMember;
-import signature.model.impl.SigField;
-import signature.model.impl.SigMethod;
-import signature.model.impl.SigPackage;
-import signature.model.impl.SigParameter;
-import signature.model.impl.Uninitialized;
-import signature.model.util.TypePool;
-import dex.structure.DexAnnotation;
-import dex.structure.DexAnnotationAttribute;
-import dex.structure.DexClass;
-import dex.structure.DexEncodedAnnotation;
-import dex.structure.DexEncodedValue;
-import dex.structure.DexField;
-import dex.structure.DexFile;
-import dex.structure.DexMethod;
-import dex.structure.DexParameter;
-
-/**
- * Converts a set of dex files to the signature compare api.
- */
-public final class DexToSigConverter implements IClassInitializer {
-
-    private final FieldPool elementPool;
-    private final TypePool factory;
-    private static final Set<IField> EMPTY_FIELDS = Collections.emptySet();
-    private static final Set<IEnumConstant> EMPTY_ENUM_CONSTANTS = Collections
-            .emptySet();
-    private static final Set<IAnnotationField> EMPTY_ANNOTATION_FIELDS =
-            Collections.emptySet();
-    private static final List<ITypeVariableDefinition> EMPTY_TYPE_VARIABLES =
-            Collections.emptyList();
-    private static final Set<IClassDefinition> EMPTY_INNER_CLASSES =
-            Collections.emptySet();
-    private static final Set<ITypeReference> EMPTY_EXCEPTIONS = Collections
-            .emptySet();
-    private Visibility visibility;
-    private Map<String, DexClass> dexNameToDexClass;
-
-
-    /**
-     * Creates a new instance of {@link DexToSigConverter}.
-     */
-    public DexToSigConverter() {
-        factory = new TypePool();
-        elementPool = new FieldPool();
-    }
-
-
-    public SigApi convertApi(String apiName, Set<DexFile> dexFiles,
-            Visibility visibility) {
-        this.visibility = visibility;
-        SigApi api = new SigApi(apiName, visibility);
-        api.setPackages(convertPackages(dexFiles));
-        factory.replaceAllUninitialiezWithNull();
-        return api;
-    }
-
-    /**
-     * Converts the given {@link DexFile}s into the corresponding (packages
-     * including their (classes and their members, etc.))E
-     * 
-     * @param parsedFiles
-     *            the dex files to convert
-     * @return the converted packages
-     */
-    /* package */Set<IPackage> convertPackages(Set<DexFile> parsedFiles) {
-        Map<String, SigPackage> packageNameToPackage =
-                new HashMap<String, SigPackage>();
-        Map<SigPackage, Set<DexClass>> packageToDexClasses =
-                new HashMap<SigPackage, Set<DexClass>>();
-
-        dexNameToDexClass = new HashMap<String, DexClass>();
-
-        for (DexFile dexFile : parsedFiles) {
-            List<DexClass> definedClasses = dexFile.getDefinedClasses();
-            for (DexClass dexClass : definedClasses) {
-
-                dexNameToDexClass.put(dexClass.getName(), dexClass);
-
-                String dexName = dexClass.getName();
-                String packageName = getPackageName(dexName);
-                SigPackage aPackage = packageNameToPackage.get(packageName);
-                if (aPackage == null) {
-                    aPackage = convertPackage(packageName);
-                    packageNameToPackage.put(packageName, aPackage);
-
-                    Set<DexClass> classes = new HashSet<DexClass>();
-                    packageToDexClasses.put(aPackage, classes);
-                }
-                Set<DexClass> classes = packageToDexClasses.get(aPackage);
-                classes.add(dexClass);
-            }
-        }
-
-        Set<SigClassDefinition> allClasses = new HashSet<SigClassDefinition>();
-
-        for (SigPackage aPackage : packageToDexClasses.keySet()) {
-            Set<SigClassDefinition> classes = convertClasses(packageToDexClasses
-                    .get(aPackage));
-            allClasses.addAll(classes);
-            aPackage.setClasses(new HashSet<IClassDefinition>(classes));
-        }
-
-        // remove package info
-        for (SigPackage aPackage : packageToDexClasses.keySet()) {
-            IClassDefinition packageInfo = findPackageInfo(aPackage);
-            if (packageInfo != null) {
-                aPackage.setAnnotations(packageInfo.getAnnotations());
-                aPackage.getClasses().remove(packageInfo);
-            }
-        }
-
-        // link enclosed classes only if they are part of visible api
-        for (SigClassDefinition sigClass : allClasses) {
-            String dexName = getDexName(sigClass);
-            DexClass dexClass = dexNameToDexClass.get(dexName);
-
-            if (declaresMemberClasses(dexClass)) {
-                Set<String> enclosedClassesNames =
-                        getMemberClassNames(dexClass);
-                Set<IClassDefinition> memberClasses =
-                        new HashSet<IClassDefinition>();
-                for (String enclosedClassName : enclosedClassesNames) {
-                    SigClassDefinition memberClass = factory.getClass(
-                            getPackageName(enclosedClassName),
-                            getClassName(enclosedClassName));
-                    // add inner class only if parsed
-                    if (allClasses.contains(memberClass)) {
-                        memberClasses.add(memberClass);
-                    }
-                }
-                sigClass.setInnerClasses(memberClasses);
-            } else {
-                sigClass.setInnerClasses(EMPTY_INNER_CLASSES);
-            }
-        }
-
-        // remove inner classes, is outer class is not visible
-        for (SigClassDefinition sigClass : allClasses) {
-            if (hasInvisibleParent(sigClass, dexNameToDexClass)) {
-                SigPackage sigPackage = packageNameToPackage.get(sigClass
-                        .getPackageName());
-                sigPackage.getClasses().remove(sigClass);
-            }
-        }
-        return new HashSet<IPackage>(packageToDexClasses.keySet());
-    }
-
-    private boolean hasInvisibleParent(IClassDefinition sigClass,
-            Map<String, DexClass> dexNameToDexClass) {
-
-        do {
-            String dexName = getDexName(sigClass);
-            DexClass dexClass = dexNameToDexClass.get(dexName);
-            if (isEnclosingClass(dexClass)) {
-                IClassDefinition declaringClass = sigClass.getDeclaringClass();
-                DexClass declaringDexClass = dexNameToDexClass
-                        .get(getDexName(declaringClass));
-                if (!isVisible(declaringDexClass, visibility)) {
-                    return true;
-                }
-            }
-        } while ((sigClass = sigClass.getDeclaringClass()) != null);
-        return false;
-    }
-
-    /**
-     * Converts a simple string to the corresponding {@link SigPackage}.<br>
-     * Format: "a.b.c"
-     * 
-     * @param packageName
-     *            the name of the package
-     * @return the package
-     */
-    protected SigPackage convertPackage(String packageName) {
-        SigPackage sigPackage = new SigPackage(packageName);
-        return sigPackage;
-    }
-
-    /**
-     * Converts a set of {@link DexClass} objects to a set of the corresponding
-     * {@link SigClassDefinition} objects.
-     * 
-     * @param dexClasses
-     *            the {@link DexClass} objects
-     * @return a set of {@link DexClass} objects
-     */
-    protected Set<SigClassDefinition> convertClasses(Set<DexClass> dexClasses) {
-        Set<SigClassDefinition> classes = new HashSet<SigClassDefinition>();
-        for (DexClass dexClass : dexClasses) {
-            // convert all classes but synthetic, return only initialized
-            if (convertAnyWay(dexClass)) {
-                SigClassDefinition sigCLass = convertClass(dexClass);
-                if (isVisible(dexClass, visibility)) {
-                    classes.add(sigCLass);
-                }
-            }
-        }
-        return classes;
-    }
-
-    /**
-     * Converts a {@link DexClass} to the corresponding
-     * {@link SigClassDefinition}.
-     * 
-     * @param dexClass
-     *            the {@link DexClass} to convert
-     * @return the corresponding {@link SigClassDefinition}
-     */
-    protected SigClassDefinition convertClass(DexClass dexClass) {
-        assert dexClass != null;
-
-        String packageName = getPackageName(dexClass.getName());
-        String className = getClassName(dexClass.getName());
-        SigClassDefinition sigClass = factory.getClass(packageName, className);
-        // Kind
-        sigClass.setKind(getKind(dexClass));
-        // modifiers
-        Set<Modifier> modifiers = getModifier(getClassModifiers(dexClass));
-        sigClass.setModifiers(modifiers);
-
-        if (isEnclosingClass(dexClass)) {
-            String declaringClassDexName = getEnclosingClassName(dexClass);
-            declaringClassDexName = getClassName(declaringClassDexName);
-            // declaring class is in same package
-            sigClass.setDeclaringClass(factory.getClass(sigClass
-                    .getPackageName(), declaringClassDexName));
-        } else {
-            sigClass.setDeclaringClass(null);
-        }
-
-        if (hasGenericSignature(dexClass)) {
-            GenericSignatureParser parser = new GenericSignatureParser(factory,
-                    this);
-            parser.parseForClass(sigClass, getGenericSignature(dexClass));
-            sigClass.setTypeParameters(parser.formalTypeParameters);
-
-            if (Kind.INTERFACE.equals(sigClass.getKind())) {
-                sigClass.setSuperClass(null);
-            } else {
-                sigClass.setSuperClass(parser.superclassType);
-            }
-
-            sigClass.setInterfaces(new HashSet<ITypeReference>(
-                    parser.interfaceTypes));
-        } else {
-
-            // Type parameters
-            sigClass.setTypeParameters(EMPTY_TYPE_VARIABLES);
-
-            // java.lang.Object has no super class
-            if (isJavaLangObject(dexClass)) {
-                sigClass.setSuperClass(null);
-            } else {
-
-                if (Kind.INTERFACE.equals(sigClass.getKind())
-                        || Kind.ANNOTATION.equals(sigClass.getKind())) {
-                    sigClass.setSuperClass(null);
-                } else {
-                    String superClassPackageName = getPackageName(dexClass
-                            .getSuperClass());
-                    String superClassName = getClassName(dexClass
-                            .getSuperClass());
-                    sigClass.setSuperClass(factory.getClassReference(
-                            superClassPackageName, superClassName));
-                }
-            }
-
-            List<String> interfaceDexNames = dexClass.getInterfaces();
-            Set<ITypeReference> interfaces = new HashSet<ITypeReference>();
-            for (String interfaceDexName : interfaceDexNames) {
-                String interfacePackageName = getPackageName(interfaceDexName);
-                String interfaceName = getClassName(interfaceDexName);
-                SigClassDefinition interfaze = factory.getClass(
-                        interfacePackageName, interfaceName);
-                interfaze.setKind(Kind.INTERFACE);
-                interfaces.add(new SigClassReference(interfaze));
-            }
-            sigClass.setInterfaces(interfaces);
-        }
-
-        // constructors
-        Set<SigConstructor> constructors = convertConstructors(dexClass
-                .getMethods());
-        for (SigConstructor constructor : constructors) {
-            constructor.setDeclaringClass(sigClass);
-        }
-        sigClass.setConstructors(new HashSet<IConstructor>(constructors));
-
-        // methods
-        Set<SigMethod> methods = Collections.emptySet();
-
-
-        if (isAnnotation(dexClass)) {
-            Map<String, Object> mappings = getDefaultValueMapping(dexClass);
-            Set<SigAnnotationField> annotationFields = convertAnnotationFields(
-                    dexClass.getMethods(), mappings);
-            sigClass.setAnnotationFields(new HashSet<IAnnotationField>(
-                    annotationFields));
-            addAnnotationsToAnnotationFields(dexClass.getMethods(),
-                    annotationFields);
-
-            sigClass.setEnumConstants(EMPTY_ENUM_CONSTANTS);
-            sigClass.setFields(EMPTY_FIELDS);
-
-            // sigClass.setAnnotationFields(new
-            // HashSet<IAnnotationField>(convertAnnotationFields(dexClass)));
-        } else if (isEnum(dexClass)) {
-            Set<IField> fields = new HashSet<IField>();
-            Set<IEnumConstant> enumConstants = new HashSet<IEnumConstant>();
-
-            for (DexField dexField : dexClass.getFields()) {
-                if (isVisible(dexField, visibility)) {
-                    if (dexField.isEnumConstant()) {
-                        enumConstants.add(convertEnumConstant(dexField));
-                    } else {
-                        fields.add(convertField(dexField));
-                    }
-                }
-            }
-
-            sigClass.setFields(fields);
-            sigClass.setEnumConstants(enumConstants);
-            sigClass.setAnnotationFields(EMPTY_ANNOTATION_FIELDS);
-            methods = convertMethods(dexClass.getMethods());
-        } else {
-            // fields
-            sigClass.setFields(new HashSet<IField>(convertFields(dexClass
-                    .getFields())));
-            sigClass.setEnumConstants(EMPTY_ENUM_CONSTANTS);
-            sigClass.setAnnotationFields(EMPTY_ANNOTATION_FIELDS);
-            methods = convertMethods(dexClass.getMethods());
-        }
-
-        for (SigMethod method : methods) {
-            method.setDeclaringClass(sigClass);
-        }
-        sigClass.setMethods(new HashSet<IMethod>(methods));
-
-        // Annotations
-        sigClass.setAnnotations(convertAnnotations(dexClass.getAnnotations()));
-
-        return sigClass;
-    }
-
-    @SuppressWarnings("unchecked")
-    private Map<String, Object> getDefaultValueMapping(DexClass dexClass) {
-        HashMap<String, Object> mappings = new HashMap<String, Object>();
-        if (hasAnnotationDefaultSignature(dexClass)) {
-            // read mapping to defaults from annotation
-            DexAnnotation annotation = getDefaultMappingsAnnotation(dexClass);
-            DexAnnotationAttribute dexAnnotationAttribute = annotation
-                    .getAttributes().get(0);
-            if ("value".equals(dexAnnotationAttribute.getName())) {
-                DexEncodedValue encodedValue = dexAnnotationAttribute
-                        .getEncodedValue();
-                DexEncodedValue value = (DexEncodedValue) encodedValue
-                        .getValue();
-                List<DexAnnotationAttribute> defaults = 
-                        (List<DexAnnotationAttribute>) value.getValue();
-                for (DexAnnotationAttribute defaultAttribute : defaults) {
-                    mappings.put(defaultAttribute.getName(),
-                            convertEncodedValue(defaultAttribute
-                                    .getEncodedValue()));
-                }
-            }
-        }
-        return mappings;
-    }
-
-
-    private void addAnnotationsToAnnotationFields(List<DexMethod> methods,
-            Set<SigAnnotationField> annotationFields) {
-        Map<String, SigAnnotationField> nameToAnnotationField =
-                new HashMap<String, SigAnnotationField>();
-
-        for (SigAnnotationField annotationField : annotationFields) {
-            nameToAnnotationField.put(annotationField.getName(),
-                    annotationField);
-        }
-
-        for (DexMethod method : methods) {
-            SigAnnotationField annotationField = nameToAnnotationField
-                    .get(method.getName());
-            annotationField.setAnnotations(convertAnnotations(method
-                    .getAnnotations()));
-        }
-    }
-
-
-    private Set<SigAnnotationField> convertAnnotationFields(
-            List<DexMethod> list, Map<String, Object> mappings) {
-        Set<SigAnnotationField> annotationfields =
-                new HashSet<SigAnnotationField>();
-        for (DexMethod dexMethod : list) {
-            if (isVisible(dexMethod, visibility)) {
-                annotationfields.add(convertAnnotationField(dexMethod, mappings
-                        .get(dexMethod.getName())));
-            }
-        }
-        return annotationfields;
-    }
-
-    private SigAnnotationField convertAnnotationField(DexMethod dexMethod,
-            Object defaultValue) {
-        SigAnnotationField annotationField = new SigAnnotationField(dexMethod
-                .getName());
-        annotationField.setDefaultValue(defaultValue);
-        annotationField.setModifiers(getModifier(dexMethod.getModifiers()));
-        GenericSignatureParser parser = new GenericSignatureParser(factory,
-                this);
-        annotationField.setType(parser.parseNonGenericType(dexMethod
-                .getReturnType()));
-        return annotationField;
-    }
-
-    private IEnumConstant convertEnumConstant(DexField dexField) {
-        String qualifiedTypeName = getQualifiedName(dexField
-                .getDeclaringClass().getName());
-        SigEnumConstant enumConstant = elementPool.getEnumConstant(
-                qualifiedTypeName, dexField.getName());
-        Set<Modifier> modifiers = getModifier(dexField.getModifiers());
-        modifiers.add(Modifier.STATIC);
-        enumConstant.setModifiers(modifiers);
-
-        String typePackageName = getPackageName(dexField.getType());
-        String typeName = getClassName(dexField.getType());
-        enumConstant.setType(factory.getClassReference(typePackageName,
-                typeName));
-        enumConstant.setAnnotations(convertAnnotations(dexField
-                .getAnnotations()));
-        return enumConstant;
-    }
-
-    private Set<SigField> convertFields(List<DexField> dexFields) {
-        Set<SigField> fields = new HashSet<SigField>();
-        for (DexField dexField : dexFields) {
-            if (isVisible(dexField, visibility)) {
-                fields.add(convertField(dexField));
-            }
-        }
-        return fields;
-    }
-
-    private SigField convertField(DexField dexField) {
-        String qualTypeName = getQualifiedName(dexField.getDeclaringClass()
-                .getName());
-        SigField field = elementPool.getField(qualTypeName, dexField.getName());
-
-        field.setModifiers(getModifier(dexField.getModifiers()));
-
-        field.setAnnotations(convertAnnotations(dexField.getAnnotations()));
-
-        if (hasGenericSignature(dexField)) {
-            GenericSignatureParser parser = new GenericSignatureParser(factory,
-                    this);
-            String declaringClassPackageName = getPackageName(dexField
-                    .getDeclaringClass().getName());
-            String declaringClassName = getClassName(dexField
-                    .getDeclaringClass().getName());
-
-            parser.parseForField(factory.getClass(declaringClassPackageName,
-                    declaringClassName), getGenericSignature(dexField));
-            field.setType(parser.fieldType);
-        } else {
-            GenericSignatureParser parser = new GenericSignatureParser(factory,
-                    this);
-            field.setType(parser.parseNonGenericType(dexField.getType()));
-        }
-
-        return field;
-    }
-
-    /**
-     * Converts a set of {@link DexMethod} to a set of corresponding
-     * {@link IConstructor}. This method ignores methods which are not
-     * constructors.
-     * 
-     * @param methods
-     *            the {@link DexMethod}s to convert
-     * @return the corresponding {@link IConstructor}s
-     */
-    private Set<SigConstructor> convertConstructors(List<DexMethod> methods) {
-        Set<SigConstructor> constructors = new HashSet<SigConstructor>();
-        for (DexMethod method : methods) {
-            if (isConstructor(method) && isVisible(method, visibility)) {
-                constructors.add(convertConstructor(method));
-            }
-        }
-        return constructors;
-    }
-
-    /**
-     * Converts a set of {@link DexMethod} to a set of corresponding
-     * {@link DexMethod}. This method ignores methods which are constructors.
-     * 
-     * @param methods
-     *            the {@link DexMethod}s to convert
-     * @return the corresponding {@link IConstructor}s
-     */
-    private Set<SigMethod> convertMethods(List<DexMethod> methods) {
-        Set<SigMethod> sigMethods = new HashSet<SigMethod>();
-        for (DexMethod method : methods) {
-            if (isMethod(method) && isVisible(method, visibility)) {
-                sigMethods.add(convertMethod(method));
-            }
-        }
-        return sigMethods;
-    }
-
-    /**
-     * Converts a dexMethod which must be a constructor to the corresponding
-     * {@link SigConstructor} instance.
-     * 
-     * @param dexMethod
-     *            the dex constructor to convert
-     * @return the corresponding {@link SigConstructor}
-     */
-    public SigConstructor convertConstructor(DexMethod dexMethod) {
-        String declaringClassName = getClassName(dexMethod.getDeclaringClass()
-                .getName());
-
-        SigConstructor constructor = new SigConstructor(declaringClassName);
-        constructor.setModifiers(getModifier(dexMethod.getModifiers()));
-        String declaringClassPackageName = getPackageName(dexMethod
-                .getDeclaringClass().getName());
-
-
-        SigClassDefinition declaringClass = factory.getClass(
-                declaringClassPackageName, declaringClassName);
-        constructor.setDeclaringClass(declaringClass);
-
-        // Annotations
-        constructor.setAnnotations(convertAnnotations(dexMethod
-                .getAnnotations()));
-
-        if (hasGenericSignature(dexMethod)) {
-            GenericSignatureParser parser = new GenericSignatureParser(factory,
-                    this);
-            parser.parseForConstructor(constructor,
-                    getGenericSignature(dexMethod));
-
-            // type parameters
-            constructor.setTypeParameters(parser.formalTypeParameters);
-
-            // parameters
-            // generic parameter types parameters
-            List<DexParameter> dexParameters = dexMethod.getParameters();
-            List<IParameter> parameters = new ArrayList<IParameter>(
-                    parser.parameterTypes.size());
-            Iterator<DexParameter> iterator = dexParameters.iterator();
-            for (ITypeReference parameterType : parser.parameterTypes) {
-                SigParameter parameter = new SigParameter(parameterType);
-                iterator.hasNext();
-                DexParameter dexParam = iterator.next();
-                parameter.setAnnotations(convertAnnotations(dexParam
-                        .getAnnotations()));
-                parameters.add(parameter);
-            }
-
-            constructor.setParameters(parameters);
-
-            // exceptions
-            constructor.setExceptions(new HashSet<ITypeReference>(
-                    parser.exceptionTypes));
-
-        } else {
-            convertNonGenericExecutableMember(constructor, dexMethod);
-
-            // remove first parameter of non static inner class constructors
-            // implicit outer.this reference
-            if (declaringClass.getDeclaringClass() != null) {
-                if (!declaringClass.getModifiers().contains(Modifier.STATIC)) {
-                    if (constructor.getParameters().isEmpty()) {
-                        throw new IllegalStateException(
-                                "Expected at least one parameter!");
-                    }
-                    IParameter first = constructor.getParameters().remove(0);
-                    String enclosingName = declaringClass.getDeclaringClass()
-                            .getName();
-                    String firstParameterTypeName = ((IClassReference) first
-                            .getType()).getClassDefinition().getName();
-                    if (!enclosingName.equals(firstParameterTypeName))
-                        throw new IllegalStateException(
-                                "Expected first constructor parameter of type "
-                                        + enclosingName);
-                }
-            }
-        }
-
-        addExceptions(constructor, dexMethod);
-        return constructor;
-    }
-
-    public SigMethod convertMethod(DexMethod dexMethod) {
-        SigMethod method = new SigMethod(dexMethod.getName());
-        method.setModifiers(getModifier(dexMethod.getModifiers()));
-
-        String declaringClassPackageName = getPackageName(dexMethod
-                .getDeclaringClass().getName());
-        String declaringClassName = getClassName(dexMethod.getDeclaringClass()
-                .getName());
-
-        method.setDeclaringClass(factory.getClass(declaringClassPackageName,
-                declaringClassName));
-
-        // Annotations
-        method.setAnnotations(convertAnnotations(dexMethod.getAnnotations()));
-
-        if (hasGenericSignature(dexMethod)) {
-            GenericSignatureParser parser = new GenericSignatureParser(factory,
-                    this);
-            parser.parseForMethod(method, getGenericSignature(dexMethod));
-
-            // type parameters
-            method.setTypeParameters(parser.formalTypeParameters);
-
-            // generic parameter types parameters
-            List<DexParameter> dexParameters = dexMethod.getParameters();
-            List<IParameter> parameters = new ArrayList<IParameter>(
-                    parser.parameterTypes.size());
-            Iterator<DexParameter> iterator = dexParameters.iterator();
-            for (ITypeReference parameterType : parser.parameterTypes) {
-                SigParameter parameter = new SigParameter(parameterType);
-                iterator.hasNext();
-                DexParameter dexParam = iterator.next();
-                parameter.setAnnotations(convertAnnotations(dexParam
-                        .getAnnotations()));
-                parameters.add(parameter);
-            }
-            method.setParameters(parameters);
-
-            // exceptions
-            method.setExceptions(new HashSet<ITypeReference>(
-                    parser.exceptionTypes));
-            method.setReturnType(parser.returnType);
-
-        } else {
-            convertNonGenericExecutableMember(method, dexMethod);
-            GenericSignatureParser parser = new GenericSignatureParser(factory,
-                    this);
-            ITypeReference type = parser.parseNonGenericReturnType(dexMethod
-                    .getReturnType());
-            method.setReturnType(type);
-        }
-        addExceptions(method, dexMethod);
-        return method;
-    }
-
-    private void addExceptions(SigExecutableMember member,
-            DexMethod dexMethod) {
-        if (declaresExceptions(dexMethod)) {
-            String exceptionSignature = getExceptionSignature(dexMethod);
-            Set<String> exceptionTypeNames = splitTypeList(exceptionSignature);
-            Set<ITypeReference> exceptions = new HashSet<ITypeReference>();
-
-            for (String exTypeName : exceptionTypeNames) {
-                String packageName = getPackageName(exTypeName);
-                String className = getClassName(exTypeName);
-                exceptions.add(factory
-                        .getClassReference(packageName, className));
-            }
-            member.setExceptions(exceptions);
-        } else {
-            member.setExceptions(EMPTY_EXCEPTIONS);
-        }
-    }
-
-    private void convertNonGenericExecutableMember(SigExecutableMember member,
-            DexMethod dexMethod) {
-        List<DexParameter> dexParameters = dexMethod.getParameters();
-        List<IParameter> parameters = new ArrayList<IParameter>(dexParameters
-                .size());
-
-        for (DexParameter dexParameter : dexParameters) {
-            GenericSignatureParser parser = new GenericSignatureParser(factory,
-                    this);
-            ITypeReference type = parser.parseNonGenericType(dexParameter
-                    .getTypeName());
-            SigParameter parameter = new SigParameter(type);
-            parameters.add(parameter);
-            // Annotations
-            parameter.setAnnotations(convertAnnotations(dexParameter
-                    .getAnnotations()));
-        }
-        member.setParameters(parameters);
-
-        member.setTypeParameters(EMPTY_TYPE_VARIABLES);
-
-        // if (declaresExceptions(dexMethod)) {
-        // String exceptionSignature = getExceptionSignature(dexMethod);
-        // Set<String> exceptionTypeNames = splitTypeList(exceptionSignature);
-        // Set<IType> exceptions = new HashSet<IType>();
-        //
-        // for (String exTypeName : exceptionTypeNames) {
-        // String packageName = getPackageName(exTypeName);
-        // String className = getClassName(exTypeName);
-        // exceptions.add(factory.getClass(packageName, className));
-        // }
-        // member.setExceptions(exceptions);
-        // } else {
-        // member.setExceptions(EMPTY_EXCEPTIONS);
-        // }
-    }
-
-    /**
-     * Converts a set of {@link DexAnnotation} to a set of corresponding
-     * {@link SigAnnotation}.
-     * 
-     * @param dexAnnotations
-     *            the {@link DexAnnotation}s to convert
-     * @return the corresponding {@link SigAnnotation}s
-     */
-    private Set<IAnnotation> convertAnnotations(
-            Set<DexAnnotation> dexAnnotations) {
-        Set<IAnnotation> annotations = new HashSet<IAnnotation>();
-        for (DexAnnotation dexAnnotation : dexAnnotations) {
-            if (!isInternalAnnotation(dexAnnotation)) {
-                annotations.add(convertAnnotation(dexAnnotation));
-            }
-        }
-        return annotations;
-    }
-
-    /**
-     * Converts a {@link DexAnnotation} to the corresponding
-     * {@link SigAnnotation}.
-     * 
-     * @param dexAnnotation
-     *            the {@link DexAnnotation} to convert
-     * @return the corresponding {@link SigAnnotation}
-     */
-    protected SigAnnotation convertAnnotation(DexAnnotation dexAnnotation) {
-        SigAnnotation sigAnnotation = new SigAnnotation();
-        String packageName = getPackageName(dexAnnotation.getTypeName());
-        String className = getClassName(dexAnnotation.getTypeName());
-        sigAnnotation
-                .setType(factory.getClassReference(packageName, className));
-        sigAnnotation.setElements(convertAnnotationElements(dexAnnotation
-                .getAttributes()));
-        return sigAnnotation;
-    }
-
-    private Set<IAnnotationElement> convertAnnotationElements(
-            List<DexAnnotationAttribute> attributes) {
-        Set<IAnnotationElement> annotationAttributes =
-                new HashSet<IAnnotationElement>();
-        for (DexAnnotationAttribute dexAnnotationAttribute : attributes) {
-            annotationAttributes
-                    .add(convertAnnotationAttribute(dexAnnotationAttribute));
-        }
-        return annotationAttributes;
-    }
-
-    private IAnnotationElement convertAnnotationAttribute(
-            DexAnnotationAttribute dexAnnotationAttribute) {
-
-        SigAnnotationElement sigElement = new SigAnnotationElement();
-        String nameOfField = dexAnnotationAttribute.getName();
-
-
-        String typeName = dexAnnotationAttribute.getAnnotation().getTypeName();
-        SigClassDefinition annotationClass = factory.getClass(
-                getPackageName(typeName), getClassName(typeName));
-        if (!Uninitialized.isInitialized(
-                annotationClass.getAnnotationFields())) {
-            initializeClass(getPackageName(typeName), getClassName(typeName));
-        }
-        for (IAnnotationField field : annotationClass.getAnnotationFields()) {
-            if (nameOfField.equals(field.getName())) {
-                sigElement.setDeclaringField(field);
-            }
-        }
-
-        sigElement.setValue(convertEncodedValue(dexAnnotationAttribute
-                .getEncodedValue()));
-        return sigElement;
-    }
-
-    @SuppressWarnings("unchecked")
-    private Object convertEncodedValue(DexEncodedValue dexEnodedValue) {
-        Object value = null;
-        switch (dexEnodedValue.getType()) {
-        case VALUE_INT:
-        case VALUE_BOOLEAN:
-        case VALUE_BYTE:
-        case VALUE_CHAR:
-        case VALUE_DOUBLE:
-        case VALUE_FLOAT:
-        case VALUE_LONG:
-        case VALUE_NULL:
-        case VALUE_STRING:
-        case VALUE_SHORT:
-            value = dexEnodedValue.getValue();
-            break;
-        case VALUE_ARRAY: {
-            List<DexEncodedValue> dexValues =
-                    (List<DexEncodedValue>) dexEnodedValue.getValue();
-            Object[] arrayValues = new Object[dexValues.size()];
-            int i = 0;
-            for (DexEncodedValue dexValue : dexValues) {
-                arrayValues[i++] = convertEncodedValue(dexValue);
-            }
-            value = arrayValues;
-            break;
-        }
-        case VALUE_ANNOTATION: {
-            DexEncodedAnnotation annotation =
-                    (DexEncodedAnnotation) dexEnodedValue.getValue();
-            SigAnnotation sigAnnotation = new SigAnnotation();
-            String packageName = getPackageName(annotation.getTypeName());
-            String className = getClassName(annotation.getTypeName());
-            sigAnnotation.setType(factory.getClassReference(packageName,
-                    className));
-
-            sigAnnotation.setElements(convertAnnotationElements(annotation
-                    .getValue()));
-            value = sigAnnotation;
-            break;
-        }
-        case VALUE_FIELD: {
-            String fieldDesc = (String) dexEnodedValue.getValue();
-            // FORMAT La/b/E;!CONSTANT
-            String[] typeAndFieldName = fieldDesc.split("!");
-            String typeName = typeAndFieldName[0];
-            String fieldName = typeAndFieldName[1];
-            value = elementPool.getField(getQualifiedName(typeName), fieldName);
-            break;
-        }
-        case VALUE_ENUM: {
-            String fieldDesc = (String) dexEnodedValue.getValue();
-            // FORMAT La/b/E;!CONSTANT
-            String[] typeAndFieldName = fieldDesc.split("!");
-            String typeName = typeAndFieldName[0];
-            String fieldName = typeAndFieldName[1];
-            value = elementPool.getEnumConstant(getQualifiedName(typeName),
-                    fieldName);
-            break;
-        }
-        case VALUE_TYPE: {
-            String typeName = (String) dexEnodedValue.getValue();
-            GenericSignatureParser parser = new GenericSignatureParser(factory,
-                    this);
-            value = parser.parseNonGenericReturnType(typeName);
-            break;
-        }
-        default:
-            throw new IllegalStateException();
-        }
-        return value;
-    }
-
-    public IClassDefinition initializeClass(String packageName,
-            String className) {
-        String dexName = getDexName(packageName, className);
-        DexClass dexClass = dexNameToDexClass.get(dexName);
-        return convertClass(dexClass);
-    }
-}
diff --git a/tools/signature-tools/src/signature/converter/dex/DexUtil.java b/tools/signature-tools/src/signature/converter/dex/DexUtil.java
deleted file mode 100644
index f661af2..0000000
--- a/tools/signature-tools/src/signature/converter/dex/DexUtil.java
+++ /dev/null
@@ -1,600 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.converter.dex;
-
-import java.io.IOException;
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import signature.converter.Visibility;
-import signature.model.IClassDefinition;
-import signature.model.Kind;
-import signature.model.Modifier;
-import signature.model.impl.SigPackage;
-import signature.model.util.ModelUtil;
-import dex.reader.DexBuffer;
-import dex.reader.DexFileReader;
-import dex.structure.DexAnnotatedElement;
-import dex.structure.DexAnnotation;
-import dex.structure.DexAnnotationAttribute;
-import dex.structure.DexClass;
-import dex.structure.DexEncodedValue;
-import dex.structure.DexField;
-import dex.structure.DexFile;
-import dex.structure.DexMethod;
-
-
-public class DexUtil {
-
-    private static final String PACKAGE_INFO = "package-info";
-    private static final String THROWS_ANNOTATION =
-            "Ldalvik/annotation/Throws;";
-    private static final String SIGNATURE_ANNOTATION =
-            "Ldalvik/annotation/Signature;";
-    private static final String ANNOTATION_DEFAULT_ANNOTATION =
-            "Ldalvik/annotation/AnnotationDefault;";
-    private static final String ENCLOSING_CLASS_ANNOTATION =
-            "Ldalvik/annotation/EnclosingClass;";
-    private static final String ENCLOSING_METHOD_ANNOTATION =
-            "Ldalvik/annotation/EnclosingMethod;";
-    private static final String INNER_CLASS_ANNOTATION =
-            "Ldalvik/annotation/InnerClass;";
-    private static final String MEMBER_CLASS_ANNOTATION =
-            "Ldalvik/annotation/MemberClasses;";
-    private static final String JAVA_LANG_OBJECT = "Ljava/lang/Object;";
-
-    private static final Set<String> INTERNAL_ANNOTATION_NAMES;
-
-    static {
-        Set<String> tmp = new HashSet<String>();
-        tmp.add(THROWS_ANNOTATION);
-        tmp.add(SIGNATURE_ANNOTATION);
-        tmp.add(ANNOTATION_DEFAULT_ANNOTATION);
-        tmp.add(ENCLOSING_CLASS_ANNOTATION);
-        tmp.add(ENCLOSING_METHOD_ANNOTATION);
-        tmp.add(INNER_CLASS_ANNOTATION);
-        tmp.add(MEMBER_CLASS_ANNOTATION);
-        INTERNAL_ANNOTATION_NAMES = Collections.unmodifiableSet(tmp);
-    }
-
-    private DexUtil() {
-        // not constructable from outside
-    }
-
-    /**
-     * "La/b/c/A;" -> "a.b.c" "LA;" -> "" empty string
-     * 
-     * @param classIdentifier
-     * @return the package name
-     */
-    public static String getPackageName(String classIdentifier) {
-        String name = removeTrailingSemicolon(removeHeadingL(classIdentifier));
-        return ModelUtil.getPackageName(name.replace("/", "."));
-    }
-
-    /**
-     * "La/b/c/A;" -> "A" "LA;" -> "A"
-     * 
-     * @param classIdentifier
-     *            the dalvik internal identifier
-     * @return the class name
-     */
-    public static String getClassName(String classIdentifier) {
-        String name = removeTrailingSemicolon(removeHeadingL(classIdentifier));
-        return ModelUtil.getClassName(name.replace("/", ".")).replace('$', '.');
-    }
-
-    public static String getQualifiedName(String classIdentifier) {
-        String name = removeTrailingSemicolon(removeHeadingL(classIdentifier));
-        return name.replace('/', '.');
-    }
-
-    private static String removeHeadingL(String className) {
-        assert className.startsWith("L");
-        return className.substring(1);
-    }
-
-    private static String removeTrailingSemicolon(String className) {
-        assert className.endsWith(";");
-        return className.substring(0, className.length() - 1);
-    }
-
-    public static String getDexName(String packageName, String className) {
-        return "L" + packageName.replace('.', '/') + "/"
-                + className.replace('.', '$') + ";";
-    }
-
-    public static String getDexName(IClassDefinition sigClass) {
-        return getDexName(sigClass.getPackageName(), sigClass.getName());
-    }
-
-    /**
-     * Returns correct modifiers for inner classes
-     */
-    public static int getClassModifiers(DexClass clazz) {
-        int modifiers = 0;
-        if (isInnerClass(clazz)) {
-            Integer accessFlags = (Integer) getAnnotationAttributeValue(
-                    getAnnotation(clazz, INNER_CLASS_ANNOTATION),
-                            "accessFlags");
-            modifiers = accessFlags.intValue();
-        } else {
-            modifiers = clazz.getModifiers();
-        }
-        return modifiers;
-    }
-
-    /**
-     * Returns a set containing all modifiers for the given int.
-     * 
-     * @param mod
-     *            the original bit coded modifiers as specified by
-     *            {@link java.lang.reflect.Modifier}
-     * @return a set containing {@link signature.model.Modifier} elements
-     */
-    public static Set<Modifier> getModifier(int mod) {
-        Set<Modifier> modifiers = EnumSet.noneOf(Modifier.class);
-        if (java.lang.reflect.Modifier.isAbstract(mod))
-            modifiers.add(Modifier.ABSTRACT);
-        if (java.lang.reflect.Modifier.isFinal(mod))
-            modifiers.add(Modifier.FINAL);
-        // if (java.lang.reflect.Modifier.isNative(mod))
-        // modifiers.add(Modifier.NATIVE);
-        if (java.lang.reflect.Modifier.isPrivate(mod))
-            modifiers.add(Modifier.PRIVATE);
-        if (java.lang.reflect.Modifier.isProtected(mod))
-            modifiers.add(Modifier.PROTECTED);
-        if (java.lang.reflect.Modifier.isPublic(mod))
-            modifiers.add(Modifier.PUBLIC);
-        if (java.lang.reflect.Modifier.isStatic(mod))
-            modifiers.add(Modifier.STATIC);
-        // if (java.lang.reflect.Modifier.isStrict(mod))
-        // modifiers.add(Modifier.STRICT);
-        // if (java.lang.reflect.Modifier.isSynchronized(mod))
-        // modifiers.add(Modifier.SYNCHRONIZED);
-        // if (java.lang.reflect.Modifier.isTransient(mod))
-        // modifiers.add(Modifier.TRANSIENT);
-        if (java.lang.reflect.Modifier.isVolatile(mod))
-            modifiers.add(Modifier.VOLATILE);
-
-        return modifiers;
-    }
-
-    /**
-     * Returns true if the given class is an enumeration, false otherwise.
-     * 
-     * @param dexClass
-     *            the DexClass under test
-     * @return true if the given class is an enumeration, false otherwise
-     */
-    public static boolean isEnum(DexClass dexClass) {
-        return (getClassModifiers(dexClass) & 0x4000) > 0;
-    }
-
-    /**
-     * Returns true if the given class is an interface, false otherwise.
-     * 
-     * @param dexClass
-     *            the DexClass under test
-     * @return true if the given class is an interface, false otherwise
-     */
-    public static boolean isInterface(DexClass dexClass) {
-        int modifiers = getClassModifiers(dexClass);
-        return java.lang.reflect.Modifier.isInterface(modifiers);
-    }
-
-    /**
-     * Returns true if the given class is an annotation, false otherwise.
-     * 
-     * @param dexClass
-     *            the DexClass under test
-     * @return true if the given class is an annotation, false otherwise
-     */
-    public static boolean isAnnotation(DexClass dexClass) {
-        return (getClassModifiers(dexClass) & 0x2000) > 0;
-    }
-
-    public static boolean isSynthetic(int modifier) {
-        return (modifier & 0x1000) > 0;
-    }
-
-    /**
-     * Returns the Kind of the given DexClass.
-     * 
-     * @param dexClass
-     *            the DexClass under test
-     * @return the Kind of the given class
-     */
-    public static Kind getKind(DexClass dexClass) {
-        // order of branches is crucial since a annotation is also an interface
-        if (isEnum(dexClass)) {
-            return Kind.ENUM;
-        } else if (isAnnotation(dexClass)) {
-            return Kind.ANNOTATION;
-        } else if (isInterface(dexClass)) {
-            return Kind.INTERFACE;
-        } else {
-            return Kind.CLASS;
-        }
-    }
-
-    /**
-     * Returns whether the specified annotated element has an annotation with
-     * type "Ldalvik/annotation/Throws;".
-     * 
-     * @param annotatedElement
-     *            the annotated element to check
-     * @return <code>true</code> if the given annotated element has the
-     *         mentioned annotation, false otherwise
-     */
-    public static boolean declaresExceptions(
-            DexAnnotatedElement annotatedElement) {
-        return getAnnotation(annotatedElement, THROWS_ANNOTATION) != null;
-    }
-
-    /**
-     * Returns the throws signature if the given element has such an annotation,
-     * null otherwise.
-     * 
-     * @param annotatedElement
-     *            the annotated element
-     * @return he generic signature if the given element has such an annotation,
-     *         null otherwise
-     */
-    @SuppressWarnings("unchecked")
-    public static String getExceptionSignature(
-            DexAnnotatedElement annotatedElement) {
-        DexAnnotation annotation = getAnnotation(annotatedElement,
-                THROWS_ANNOTATION);
-        if (annotation != null) {
-            List<DexEncodedValue> value =
-                    (List<DexEncodedValue>) getAnnotationAttributeValue(
-                            annotation, "value");
-            return concatEncodedValues(value);
-        }
-        return null;
-    }
-
-    /**
-     * Splits a list of types:
-     * "Ljava/io/IOException;Ljava/lang/IllegalStateException;" <br>
-     * into separate type designators: <br>
-     * "Ljava/io/IOException;" , "Ljava/lang/IllegalStateException;"
-     * 
-     * @param typeList
-     *            the type list
-     * @return a set of type designators
-     */
-    public static Set<String> splitTypeList(String typeList) {
-        String[] split = typeList.split(";");
-        Set<String> separateTypes = new HashSet<String>();
-        for (String string : split) {
-            separateTypes.add(string + ";");// add semicolon again
-        }
-        return separateTypes;
-    }
-
-    /**
-     * Returns whether the specified annotated element has an annotation with
-     * type "Ldalvik/annotation/Signature;".
-     * 
-     * @param annotatedElement
-     *            the annotated element to check
-     * @return <code>true</code> if the given annotated element has the
-     *         mentioned annotation, false otherwise
-     */
-    public static boolean hasGenericSignature(
-            DexAnnotatedElement annotatedElement) {
-        return getAnnotation(annotatedElement, SIGNATURE_ANNOTATION) != null;
-    }
-
-    /**
-     * Returns the generic signature if the given element has such an
-     * annotation, null otherwise.
-     * 
-     * @param annotatedElement
-     *            the annotated element
-     * @return he generic signature if the given element has such an annotation,
-     *         null otherwise
-     */
-    @SuppressWarnings("unchecked")
-    public static String getGenericSignature(
-            DexAnnotatedElement annotatedElement) {
-        DexAnnotation annotation = getAnnotation(annotatedElement,
-                SIGNATURE_ANNOTATION);
-        if (annotation != null) {
-            List<DexEncodedValue> value =
-                    (List<DexEncodedValue>) getAnnotationAttributeValue(
-                            annotation, "value");
-            return concatEncodedValues(value);
-        }
-        return null;
-    }
-
-    /**
-     * Returns whether the specified annotated element has an annotation with
-     * type "Ldalvik/annotation/AnnotationDefault;".
-     * 
-     * @param annotatedElement
-     *            the annotated element to check
-     * @return <code>true</code> if the given annotated element has the
-     *         mentioned annotation, false otherwise
-     */
-    public static boolean hasAnnotationDefaultSignature(
-            DexAnnotatedElement annotatedElement) {
-        return getAnnotation(
-                annotatedElement, ANNOTATION_DEFAULT_ANNOTATION)!= null;
-    }
-
-    /**
-     * Returns a mapping form annotation attribute name to its default value.
-     * 
-     * @param dexClass
-     *            the class defining a annotation
-     * @return a mapping form annotation attribute name to its default value
-     */
-    public static DexAnnotation getDefaultMappingsAnnotation(
-            DexClass dexClass) {
-        return getAnnotation(dexClass, ANNOTATION_DEFAULT_ANNOTATION);
-    }
-
-    /**
-     * Returns the annotation with the specified type from the given element or
-     * null if no such annotation is available.
-     * 
-     * @param element
-     *            the annotated element
-     * @param annotationType
-     *            the dex internal name of the annotation type
-     * @return the annotation with the specified type or null if not present
-     */
-    public static DexAnnotation getAnnotation(DexAnnotatedElement element,
-            String annotationType) {
-        assert element != null;
-        assert annotationType != null;
-
-        for (DexAnnotation anno : element.getAnnotations()) {
-            if (annotationType.equals(anno.getTypeName())) {
-                return anno;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Returns the value for the specified attribute name of the given
-     * annotation or null if not present.
-     * 
-     * @param annotation
-     *            the annotation
-     * @param attributeName
-     *            the name of the attribute
-     * @return the value for the specified attribute
-     */
-    public static Object getAnnotationAttributeValue(DexAnnotation annotation,
-            String attributeName) {
-        for (DexAnnotationAttribute dexAnnotationAttribute : annotation
-                .getAttributes()) {
-            if (attributeName.equals(dexAnnotationAttribute.getName())) {
-                return dexAnnotationAttribute.getEncodedValue().getValue();
-            }
-        }
-        return null;
-    }
-
-    private static String concatEncodedValues(List<DexEncodedValue> values) {
-        StringBuilder builder = new StringBuilder();
-        for (DexEncodedValue string : values) {
-            builder.append(string.getValue());
-        }
-        return builder.toString();
-    }
-
-    /**
-     * Returns true if the given method is a constructor, false otherwise.
-     * 
-     * @param method
-     *            the method to test
-     * @return true if the given method is a constructor, false otherwise
-     */
-    public static boolean isConstructor(DexMethod method) {
-        return "<init>".equals(method.getName());
-    }
-
-    /**
-     * Returns true if the given method is a static constructor, false
-     * otherwise.
-     * 
-     * @param method
-     *            the method to test
-     * @return true if the given method is a static constructor, false otherwise
-     */
-    public static boolean isStaticConstructor(DexMethod method) {
-        return "<clinit>".equals(method.getName());
-    }
-
-    public static boolean isMethod(DexMethod method) {
-        return !isConstructor(method) && !isStaticConstructor(method);
-    }
-
-    /**
-     * Returns the package-info class for the given package.
-     * 
-     * @param aPackage
-     *            the package
-     * @return the class called "package-info" or null, if not available
-     */
-    public static IClassDefinition findPackageInfo(SigPackage aPackage) {
-        for (IClassDefinition clazz : aPackage.getClasses()) {
-            if (PACKAGE_INFO.equals(clazz.getName())) {
-                return clazz;
-            }
-        }
-        return null;
-    }
-
-    public static boolean isPackageInfo(DexClass clazz) {
-        return PACKAGE_INFO.equals(getClassName(clazz.getName()));
-    }
-
-    public static boolean isInternalAnnotation(DexAnnotation dexAnnotation) {
-        return INTERNAL_ANNOTATION_NAMES.contains(dexAnnotation.getTypeName());
-    }
-
-    /**
-     * An InnerClass annotation is attached to each class which is defined in
-     * the lexical scope of another class's definition. Any class which has this
-     * annotation must also have either an EnclosingClass annotation or an
-     * EnclosingMethod annotation.
-     */
-    public static boolean isInnerClass(DexClass clazz) {
-        return getAnnotation(clazz, INNER_CLASS_ANNOTATION) != null;
-    }
-
-    /**
-     * An EnclosingClass annotation is attached to each class which is either
-     * defined as a member of another class, per se, or is anonymous but not
-     * defined within a method body (e.g., a synthetic inner class). Every class
-     * that has this annotation must also have an InnerClass annotation.
-     * Additionally, a class may not have both an EnclosingClass and an
-     * EnclosingMethod annotation.
-     */
-    public static boolean isEnclosingClass(DexClass clazz) {
-        return getAnnotation(clazz, ENCLOSING_CLASS_ANNOTATION) != null;
-    }
-
-    public static boolean declaresMemberClasses(DexClass dexClass) {
-        return getAnnotation(dexClass, MEMBER_CLASS_ANNOTATION) != null;
-    }
-
-    @SuppressWarnings("unchecked")
-    public static Set<String> getMemberClassNames(DexClass dexClass) {
-        DexAnnotation annotation = getAnnotation(dexClass,
-                MEMBER_CLASS_ANNOTATION);
-        List<DexEncodedValue> enclosedClasses =
-                (List<DexEncodedValue>) getAnnotationAttributeValue(
-                        annotation, "value");
-        Set<String> enclosedClassesNames = new HashSet<String>();
-        for (DexEncodedValue string : enclosedClasses) {
-            enclosedClassesNames.add((String) string.getValue());
-        }
-        return enclosedClassesNames;
-    }
-
-
-    public static String getEnclosingClassName(DexClass dexClass) {
-        DexAnnotation annotation = getAnnotation(dexClass,
-                ENCLOSING_CLASS_ANNOTATION);
-        String value = (String) getAnnotationAttributeValue(annotation,
-                "value");
-        return value;
-    }
-
-    public static boolean convertAnyWay(DexClass dexClass) {
-        return !isSynthetic(getClassModifiers(dexClass))
-                && !isAnonymousClassName(dexClass.getName())
-                || isPackageInfo(dexClass);
-    }
-
-    public static boolean isVisible(DexClass dexClass, Visibility visibility) {
-        // package info is always visible
-        if (isPackageInfo(dexClass)) {
-            return true;
-        }
-
-        if (isDeclaredInMethod(dexClass)) {
-            return false;
-        }
-
-        if (isAnonymousClassName(dexClass.getName())) {
-            return false;
-        }
-
-        int modifiers = getClassModifiers(dexClass);
-
-        return isVisible(modifiers, visibility);
-    }
-
-    private static boolean isDeclaredInMethod(DexClass dexClass) {
-        return getAnnotation(dexClass, ENCLOSING_METHOD_ANNOTATION) != null;
-    }
-
-    /**
-     * Returns whether the given dex identifier is an anonymous class name.
-     * Format: La/b/C$1;
-     * 
-     * @param dexName
-     *            the name to analyze
-     * @return whether the given dex identifier is an anonymous class name
-     */
-    public static boolean isAnonymousClassName(String dexName) {
-        int index = dexName.lastIndexOf('$');
-        return (index != 0) ? Character.isDigit(dexName.charAt(index + 1))
-                : false;
-    }
-
-    public static boolean isVisible(DexField dexField, Visibility visibility) {
-        return isVisible(dexField.getModifiers(), visibility);
-    }
-
-    public static boolean isVisible(DexMethod dexMethod,
-            Visibility visibility) {
-        return isVisible(dexMethod.getModifiers(), visibility);
-    }
-
-    private static boolean isVisible(int modifiers, Visibility visibility) {
-
-        if (isSynthetic(modifiers)) {
-            return false;
-        }
-
-        Set<Modifier> elementModifiers = getModifier(modifiers);
-        if (elementModifiers.contains(Modifier.PUBLIC)) {
-            return true;
-        } else if (elementModifiers.contains(Modifier.PROTECTED)) {
-            return visibility == Visibility.PROTECTED
-                    || visibility == Visibility.PACKAGE
-                    || visibility == Visibility.PRIVATE;
-        } else if (elementModifiers.contains(Modifier.PRIVATE)) {
-            return visibility == Visibility.PRIVATE;
-        } else {
-            return visibility == Visibility.PACKAGE
-                    || visibility == Visibility.PRIVATE;
-        }
-    }
-
-    public static Set<DexFile> getDexFiles(Set<String> fileNames)
-            throws IOException {
-        Set<DexFile> parsedFiles = new HashSet<DexFile>();
-
-        for (String dexFile : fileNames) {
-            DexFileReader reader = new DexFileReader();
-            DexBuffer dexBuffer = new DexBuffer(dexFile);
-            parsedFiles.add(reader.read(dexBuffer));
-        }
-        return parsedFiles;
-    }
-
-
-    public static boolean isJavaLangObject(DexClass dexClass) {
-        assert dexClass != null;
-        return JAVA_LANG_OBJECT.equals(dexClass.getName());
-    }
-}
diff --git a/tools/signature-tools/src/signature/converter/dex/FieldPool.java b/tools/signature-tools/src/signature/converter/dex/FieldPool.java
deleted file mode 100644
index 6587820..0000000
--- a/tools/signature-tools/src/signature/converter/dex/FieldPool.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.converter.dex;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import signature.model.impl.SigEnumConstant;
-import signature.model.impl.SigField;
-
-public class FieldPool {
-
-    private Map<FieldKey, SigField> fieldStore;
-    private Map<FieldKey, SigEnumConstant> constantStore;
-
-    public FieldPool() {
-        fieldStore = new HashMap<FieldKey, SigField>();
-        constantStore = new HashMap<FieldKey, SigEnumConstant>();
-    }
-
-    private static class FieldKey {
-        private final String qualifiedClassName;
-        private final String fieldName;
-
-        public FieldKey(String qualifiedClassName, String fieldName) {
-            this.qualifiedClassName = qualifiedClassName;
-            this.fieldName = fieldName;
-        }
-
-        @Override
-        public int hashCode() {
-            final int prime = 31;
-            int result = prime * fieldName.hashCode();
-            result = prime * result + qualifiedClassName.hashCode();
-            return result;
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            FieldKey other = (FieldKey) obj;
-            if (!fieldName.equals(other.fieldName)) {
-                return false;
-            }
-            if (!qualifiedClassName.equals(other.qualifiedClassName)) {
-                return false;
-            }
-            return true;
-        }
-    }
-
-    public SigField getField(String qualifiedClassName, String fieldName) {
-        FieldKey key = new FieldKey(qualifiedClassName, fieldName);
-        SigField sigField = fieldStore.get(key);
-        if (sigField == null) {
-            sigField = new SigField(fieldName);
-            fieldStore.put(key, sigField);
-        }
-        return sigField;
-    }
-
-    public SigEnumConstant getEnumConstant(String qualifiedName,
-            String fieldName) {
-        FieldKey key = new FieldKey(qualifiedName, fieldName);
-        SigEnumConstant sigField = constantStore.get(key);
-        if (sigField == null) {
-            sigField = new SigEnumConstant(fieldName);
-            constantStore.put(key, sigField);
-        }
-        return sigField;
-    }
-
-}
diff --git a/tools/signature-tools/src/signature/converter/dex/GenericSignatureParser.java b/tools/signature-tools/src/signature/converter/dex/GenericSignatureParser.java
deleted file mode 100644
index 773e2fc..0000000
--- a/tools/signature-tools/src/signature/converter/dex/GenericSignatureParser.java
+++ /dev/null
@@ -1,651 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.converter.dex;
-
-import static signature.converter.dex.DexUtil.getClassName;
-import static signature.converter.dex.DexUtil.getPackageName;
-import signature.model.IClassDefinition;
-import signature.model.IClassReference;
-import signature.model.IConstructor;
-import signature.model.IGenericDeclaration;
-import signature.model.IMethod;
-import signature.model.ITypeReference;
-import signature.model.ITypeVariableDefinition;
-import signature.model.ITypeVariableReference;
-import signature.model.impl.SigArrayType;
-import signature.model.impl.SigParameterizedType;
-import signature.model.impl.SigPrimitiveType;
-import signature.model.impl.SigTypeVariableDefinition;
-import signature.model.impl.SigWildcardType;
-import signature.model.impl.Uninitialized;
-import signature.model.util.ITypeFactory;
-
-import java.lang.reflect.GenericSignatureFormatError;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Implements a parser for the generics signature attribute. Uses a top-down,
- * recursive descent parsing approach for the following grammar:
- * 
- * <pre>
- * ClassSignature ::=
- *     OptFormalTypeParams SuperclassSignature {SuperinterfaceSignature}.
- * SuperclassSignature ::= ClassTypeSignature.
- * SuperinterfaceSignature ::= ClassTypeSignature.
- *
- * OptFormalTypeParams ::=
- *     ["<" FormalTypeParameter {FormalTypeParameter} ">"].
- *
- * FormalTypeParameter ::= Ident ClassBound {InterfaceBound}.
- * ClassBound ::= ":" [FieldTypeSignature].
- * InterfaceBound ::= ":" FieldTypeSignature.
- *
- * FieldTypeSignature ::=
- *     ClassTypeSignature | ArrayTypeSignature | TypeVariableSignature.
- * ArrayTypeSignature ::= "[" TypSignature.
- *
- * ClassTypeSignature ::=
- *     "L" {Ident "/"} Ident OptTypeArguments {"." Ident OptTypeArguments} ";".
- *
- * OptTypeArguments ::= "<" TypeArgument {TypeArgument} ">".
- *
- * TypeArgument ::= ([WildcardIndicator] FieldTypeSignature) | "*".
- * WildcardIndicator ::= "+" | "-".
- *
- * TypeVariableSignature ::= "T" Ident ";".
- *
- * TypSignature ::= FieldTypeSignature | BaseType.
- * BaseType ::= "B" | "C" | "D" | "F" | "I" | "J" | "S" | "Z".
- *
- * MethodTypeSignature ::=
- *     OptFormalTypeParams "(" {TypeSignature} ")" ReturnType {ThrowsSignature}.
- * ThrowsSignature ::= ("^" ClassTypeSignature) | ("^" TypeVariableSignature).
- *
- * ReturnType ::= TypSignature | VoidDescriptor.
- * VoidDescriptor ::= "V".
- * </pre>
- */
-public class GenericSignatureParser {
-
-    public List<ITypeReference> exceptionTypes;
-    public List<ITypeReference> parameterTypes;
-    public List<ITypeVariableDefinition> formalTypeParameters;
-    public ITypeReference returnType;
-    public ITypeReference fieldType;
-    public List<ITypeReference> interfaceTypes;
-    public ITypeReference superclassType;
-
-    private IGenericDeclaration genericDecl;
-
-    /*
-     * Parser:
-     */
-    private char symbol; // 0: eof; else valid term symbol or first char of
-    // identifier.
-    private String identifier;
-
-
-    /*
-     * Scanner: eof is private to the scan methods and it's set only when a scan
-     * is issued at the end of the buffer.
-     */
-    private boolean eof;
-
-    private char[] buffer;
-    private int pos;
-
-    private final ITypeFactory factory;
-    private final IClassInitializer classFinder;
-    private boolean parseForField;
-
-
-    public GenericSignatureParser(ITypeFactory factory,
-            IClassInitializer classFinder) {
-        this.factory = factory;
-        this.classFinder = classFinder;
-    }
-
-    private void setInput(IGenericDeclaration genericDecl, String input) {
-        if (input != null) {
-            this.genericDecl = genericDecl;
-            this.buffer = input.toCharArray();
-            this.eof = false;
-            scanSymbol();
-        } else {
-            this.eof = true;
-        }
-    }
-
-    public ITypeReference parseNonGenericType(String typeSignature) {
-        setInput(null, typeSignature);
-        ITypeReference type = parsePrimitiveType();
-        if (type == null) {
-            type = parseFieldTypeSignature();
-        }
-        return type;
-    }
-
-    public ITypeReference parseNonGenericReturnType(String typeSignature) {
-        setInput(null, typeSignature);
-        ITypeReference returnType = parsePrimitiveType();
-        if (returnType == null) {
-            returnType = parseReturnType();
-        }
-        return returnType;
-    }
-
-    private ITypeReference parsePrimitiveType() {
-        switch (symbol) {
-        case 'B':
-            scanSymbol();
-            return SigPrimitiveType.BYTE_TYPE;
-        case 'C':
-            scanSymbol();
-            return SigPrimitiveType.CHAR_TYPE;
-        case 'D':
-            scanSymbol();
-            return SigPrimitiveType.DOUBLE_TYPE;
-        case 'F':
-            scanSymbol();
-            return SigPrimitiveType.FLOAT_TYPE;
-        case 'I':
-            scanSymbol();
-            return SigPrimitiveType.INT_TYPE;
-        case 'J':
-            scanSymbol();
-            return SigPrimitiveType.LONG_TYPE;
-        case 'S':
-            scanSymbol();
-            return SigPrimitiveType.SHORT_TYPE;
-        case 'Z':
-            scanSymbol();
-            return SigPrimitiveType.BOOLEAN_TYPE;
-        default:
-            return null;
-        }
-    }
-
-    /**
-     * Parses the generic signature of a class and creates the data structure
-     * representing the signature.
-     * 
-     * @param classToProcess
-     *            the GenericDeclaration calling this method
-     * @param signature
-     *            the generic signature of the class
-     */
-    public void parseForClass(IClassDefinition classToProcess,
-            String signature) {
-        setInput(classToProcess, signature);
-        if (!eof) {
-            parseClassSignature();
-        } else {
-            throw new IllegalStateException("Generic signature is invalid!");
-        }
-    }
-
-    /**
-     * Parses the generic signature of a method and creates the data structure
-     * representing the signature.
-     * 
-     * @param genericDecl
-     *            the GenericDeclaration calling this method
-     * @param signature
-     *            the generic signature of the class
-     */
-    public void parseForMethod(IMethod genericDecl, String signature) {
-        setInput(genericDecl, signature);
-        if (!eof) {
-            parseMethodTypeSignature();
-        } else {
-            throw new IllegalStateException("Generic signature is invalid!");
-        }
-    }
-
-    /**
-     * Parses the generic signature of a constructor and creates the data
-     * structure representing the signature.
-     * 
-     * @param genericDecl
-     *            the GenericDeclaration calling this method
-     * @param signature
-     *            the generic signature of the class
-     */
-    public void parseForConstructor(IConstructor genericDecl,
-            String signature) {
-        setInput(genericDecl, signature);
-        if (!eof) {
-            parseMethodTypeSignature();
-        } else {
-            throw new IllegalStateException("Generic signature is invalid!");
-        }
-    }
-
-    /**
-     * Parses the generic signature of a field and creates the data structure
-     * representing the signature.
-     * 
-     * @param genericDecl
-     *            the GenericDeclaration calling this method
-     * @param signature
-     *            the generic signature of the class
-     */
-    public void parseForField(IClassDefinition genericDecl, String signature) {
-        parseForField = true;
-        setInput(genericDecl, signature);
-        try {
-            if (!eof) {
-                this.fieldType = parseFieldTypeSignature();
-            } else {
-                throw new IllegalStateException(
-                        "Generic signature is invalid!");
-            }
-        } finally {
-            parseForField = false;
-        }
-    }
-
-    private void parseClassSignature() {
-        // ClassSignature ::=
-        // OptFormalTypeParameters SuperclassSignature
-        // {SuperinterfaceSignature}.
-
-        parseOptFormalTypeParameters();
-
-        // SuperclassSignature ::= ClassTypeSignature.
-        this.superclassType = parseClassTypeSignature();
-
-        interfaceTypes = new ArrayList<ITypeReference>(16);
-        while (symbol > 0) {
-            // SuperinterfaceSignature ::= ClassTypeSignature.
-            interfaceTypes.add(parseClassTypeSignature());
-        }
-    }
-
-    private void parseOptFormalTypeParameters() {
-        // OptFormalTypeParameters ::=
-        // ["<" FormalTypeParameter {FormalTypeParameter} ">"].
-
-        List<ITypeVariableDefinition> typeParameters =
-                new ArrayList<ITypeVariableDefinition>();
-
-        if (symbol == '<') {
-            scanSymbol();
-            typeParameters.add(parseFormalTypeParameter());
-            while ((symbol != '>') && (symbol > 0)) {
-                typeParameters.add(parseFormalTypeParameter());
-            }
-            expect('>');
-        }
-
-        formalTypeParameters = typeParameters;
-    }
-
-    private SigTypeVariableDefinition parseFormalTypeParameter() {
-        // FormalTypeParameter ::= Ident ClassBound {InterfaceBound}.
-
-        scanIdentifier();
-        String name = identifier.intern();
-        SigTypeVariableDefinition typeVariable = factory.getTypeVariable(name,
-                genericDecl);
-
-        List<ITypeReference> bounds = new ArrayList<ITypeReference>();
-
-        // ClassBound ::= ":" [FieldTypeSignature].
-        expect(':');
-        if (symbol == 'L' || symbol == '[' || symbol == 'T') {
-            bounds.add(parseFieldTypeSignature());
-        }
-
-        while (symbol == ':') {
-            // InterfaceBound ::= ":" FieldTypeSignature.
-            scanSymbol();
-            bounds.add(parseFieldTypeSignature());
-        }
-        typeVariable.setUpperBounds(bounds);
-        return typeVariable;
-    }
-
-    /**
-     * Returns the generic declaration for the type variable with the specified
-     * name.
-     * 
-     * @param variableName
-     *            the name of the type variable
-     * @param declaration
-     *            the declaration to start searching
-     * @return the declaration which defines the specified type variable
-     */
-    private IGenericDeclaration getDeclarationOfTypeVariable(
-            String variableName, IClassDefinition declaration) {
-        assert variableName != null;
-        assert declaration != null;
-
-        if (!Uninitialized.isInitialized(declaration.getTypeParameters())) {
-            declaration = classFinder.initializeClass(declaration
-                    .getPackageName(), declaration.getName());
-        }
-
-        for (ITypeVariableDefinition typeVariable : declaration
-                .getTypeParameters()) {
-            if (variableName.equals(typeVariable.getName())) {
-                return declaration;
-            }
-        }
-        return getDeclarationOfTypeVariable(variableName, declaration
-                .getDeclaringClass());
-    }
-
-    private ITypeReference parseFieldTypeSignature() {
-        // FieldTypeSignature ::= ClassTypeSignature | ArrayTypeSignature
-        // | TypeVariableSignature.
-
-        switch (symbol) {
-        case 'L':
-            return parseClassTypeSignature();
-        case '[':
-            // ArrayTypeSignature ::= "[" TypSignature.
-            scanSymbol();
-            SigArrayType arrayType = factory.getArrayType(parseTypeSignature());
-            return arrayType;
-        case 'T':
-            return parseTypeVariableSignature();
-        default:
-            throw new GenericSignatureFormatError();
-        }
-    }
-
-    private ITypeReference parseClassTypeSignature() {
-        // ClassTypeSignature ::= "L" {Ident "/"} Ident
-        // OptTypeArguments {"." Ident OptTypeArguments} ";".
-
-        expect('L');
-
-        StringBuilder qualIdent = new StringBuilder("L");
-        scanIdentifier();
-        while (symbol == '/') {
-            scanSymbol();
-            qualIdent.append(identifier).append("/");
-            scanIdentifier();
-        }
-
-        qualIdent.append(this.identifier);
-
-
-        List<ITypeReference> typeArgs = parseOptTypeArguments();
-
-        ITypeReference parentType = null;
-
-        String packageName = getPackageName(qualIdent.toString() + ";");
-        String className = getClassName(qualIdent.toString() + ";");
-
-        if (typeArgs.isEmpty()) {
-            parentType = factory.getClassReference(packageName, className);
-        } else {
-            IClassReference rawType = factory.getClassReference(packageName,
-                    className);
-            SigParameterizedType parameterizedType = factory
-                    .getParameterizedType(null, rawType, typeArgs);
-            parentType = parameterizedType;
-        }
-
-        ITypeReference typeToReturn = parentType;
-
-
-        // if owner type is a parameterized type, the types are separated by '.'
-        while (symbol == '.') {
-            // Deal with Member Classes:
-            scanSymbol();
-            scanIdentifier();
-            qualIdent.append("$").append(identifier);
-            typeArgs = parseOptTypeArguments();
-            ITypeReference memberType = null;
-
-            packageName = getPackageName(qualIdent.toString() + ";");
-            className = getClassName(qualIdent.toString() + ";");
-
-            if (typeArgs.isEmpty()) {
-                memberType = factory.getClassReference(packageName, className);
-            } else {
-                IClassReference rawType = factory.getClassReference(
-                        packageName, className);
-                SigParameterizedType parameterizedType = factory
-                        .getParameterizedType(parentType, rawType, typeArgs);
-                memberType = parameterizedType;
-            }
-            typeToReturn = memberType;
-        }
-
-        expect(';');
-
-        return typeToReturn;
-    }
-
-    private List<ITypeReference> parseOptTypeArguments() {
-        // OptTypeArguments ::= "<" TypeArgument {TypeArgument} ">".
-
-        List<ITypeReference> typeArgs = new ArrayList<ITypeReference>(8);
-        if (symbol == '<') {
-            scanSymbol();
-
-            typeArgs.add(parseTypeArgument());
-            while ((symbol != '>') && (symbol > 0)) {
-                typeArgs.add(parseTypeArgument());
-            }
-            expect('>');
-        }
-        return typeArgs;
-    }
-
-    private ITypeReference parseTypeArgument() {
-        // TypeArgument ::= (["+" | "-"] FieldTypeSignature) | "*".
-        List<ITypeReference> extendsBound = new ArrayList<ITypeReference>(1);
-        ITypeReference superBound = null;
-        if (symbol == '*') {
-            scanSymbol();
-            extendsBound.add(factory.getClassReference("java.lang", "Object"));
-            SigWildcardType wildcardType = factory.getWildcardType(superBound,
-                    extendsBound);
-            return wildcardType;
-        } else if (symbol == '+') {
-            scanSymbol();
-            extendsBound.add(parseFieldTypeSignature());
-            SigWildcardType wildcardType = factory.getWildcardType(superBound,
-                    extendsBound);
-            return wildcardType;
-        } else if (symbol == '-') {
-            scanSymbol();
-            superBound = parseFieldTypeSignature();
-            extendsBound.add(factory.getClassReference("java.lang", "Object"));
-            SigWildcardType wildcardType = factory.getWildcardType(superBound,
-                    extendsBound);
-            return wildcardType;
-        } else {
-            return parseFieldTypeSignature();
-        }
-    }
-
-    private ITypeVariableReference parseTypeVariableSignature() {
-        // TypeVariableSignature ::= "T" Ident ";".
-        expect('T');
-        scanIdentifier();
-        expect(';');
-
-        IGenericDeclaration declaration = genericDecl;
-
-        if (!factory.containsTypeVariableDefinition(identifier, declaration)) {
-            // since a field is not a generic declaration, i need to treat it
-            // differently.
-            // the generic declaration
-            if (parseForField) {
-                declaration = getDeclarationOfTypeVariable(identifier,
-                        (IClassDefinition) genericDecl);
-            } else {
-                declaration = getDeclarationOfTypeVariable(identifier,
-                        genericDecl.getDeclaringClass());
-            }
-            // just create type variable
-            factory.getTypeVariable(identifier, declaration);
-        }
-
-        return factory.getTypeVariableReference(identifier, declaration);
-    }
-
-    private ITypeReference parseTypeSignature() {
-        switch (symbol) {
-        case 'B':
-            scanSymbol();
-            return SigPrimitiveType.BYTE_TYPE;
-        case 'C':
-            scanSymbol();
-            return SigPrimitiveType.CHAR_TYPE;
-        case 'D':
-            scanSymbol();
-            return SigPrimitiveType.DOUBLE_TYPE;
-        case 'F':
-            scanSymbol();
-            return SigPrimitiveType.FLOAT_TYPE;
-        case 'I':
-            scanSymbol();
-            return SigPrimitiveType.INT_TYPE;
-        case 'J':
-            scanSymbol();
-            return SigPrimitiveType.LONG_TYPE;
-        case 'S':
-            scanSymbol();
-            return SigPrimitiveType.SHORT_TYPE;
-        case 'Z':
-            scanSymbol();
-            return SigPrimitiveType.BOOLEAN_TYPE;
-        default:
-            // Not an elementary type, but a FieldTypeSignature.
-            return parseFieldTypeSignature();
-        }
-    }
-
-    private void parseMethodTypeSignature() {
-        // MethodTypeSignature ::= [FormalTypeParameters]
-        // "(" {TypeSignature} ")" ReturnType {ThrowsSignature}.
-
-        parseOptFormalTypeParameters();
-
-        parameterTypes = new ArrayList<ITypeReference>(16);
-        expect('(');
-        while (symbol != ')' && (symbol > 0)) {
-            parameterTypes.add(parseTypeSignature());
-        }
-        expect(')');
-
-        returnType = parseReturnType();
-
-        exceptionTypes = new ArrayList<ITypeReference>(8);
-        while (symbol == '^') {
-            scanSymbol();
-
-            // ThrowsSignature ::= ("^" ClassTypeSignature) |
-            // ("^" TypeVariableSignature).
-            if (symbol == 'T') {
-                exceptionTypes.add(parseTypeVariableSignature());
-            } else {
-                exceptionTypes.add(parseClassTypeSignature());
-            }
-        }
-    }
-
-    private ITypeReference parseReturnType() {
-        // ReturnType ::= TypeSignature | "V".
-        if (symbol != 'V') {
-            return parseTypeSignature();
-        } else {
-            scanSymbol();
-            return SigPrimitiveType.VOID_TYPE;
-        }
-    }
-
-
-    //
-    // Scanner:
-    //
-
-    private void scanSymbol() {
-        if (!eof) {
-            if (pos < buffer.length) {
-                symbol = buffer[pos];
-                pos++;
-            } else {
-                symbol = 0;
-                eof = true;
-            }
-        } else {
-            throw new GenericSignatureFormatError();
-        }
-    }
-
-    private void expect(char c) {
-        if (symbol == c) {
-            scanSymbol();
-        } else {
-            throw new GenericSignatureFormatError();
-        }
-    }
-
-    private boolean isStopSymbol(char ch) {
-        switch (ch) {
-        case ':':
-        case '/':
-        case ';':
-        case '<':
-        case '.':
-            return true;
-        }
-        return false;
-    }
-
-    // PRE: symbol is the first char of the identifier.
-    // POST: symbol = the next symbol AFTER the identifier.
-    private void scanIdentifier() {
-        if (!eof) {
-            StringBuilder identBuf = new StringBuilder(32);
-            if (!isStopSymbol(symbol)) {
-                identBuf.append(symbol);
-                do {
-                    char ch = buffer[pos];
-                    if ((ch >= 'a') && (ch <= 'z') || (ch >= 'A')
-                            && (ch <= 'Z') || !isStopSymbol(ch)) {
-                        identBuf.append(buffer[pos]);
-                        pos++;
-                    } else {
-                        identifier = identBuf.toString();
-                        scanSymbol();
-                        return;
-                    }
-                } while (pos != buffer.length);
-                identifier = identBuf.toString();
-                symbol = 0;
-                eof = true;
-            } else {
-                // Ident starts with incorrect char.
-                symbol = 0;
-                eof = true;
-                throw new GenericSignatureFormatError();
-            }
-        } else {
-            throw new GenericSignatureFormatError();
-        }
-    }
-}
diff --git a/tools/signature-tools/src/signature/converter/dex/IClassInitializer.java b/tools/signature-tools/src/signature/converter/dex/IClassInitializer.java
deleted file mode 100644
index 935ca49..0000000
--- a/tools/signature-tools/src/signature/converter/dex/IClassInitializer.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.converter.dex;
-
-import signature.model.IClassDefinition;
-
-public interface IClassInitializer {
-    IClassDefinition initializeClass(String packageName, String className);
-}
diff --git a/tools/signature-tools/src/signature/converter/doclet/DocletToSigConverter.java b/tools/signature-tools/src/signature/converter/doclet/DocletToSigConverter.java
deleted file mode 100644
index f9ebe77..0000000
--- a/tools/signature-tools/src/signature/converter/doclet/DocletToSigConverter.java
+++ /dev/null
@@ -1,636 +0,0 @@
-/*

- * Copyright (C) 2009 The Android Open Source Project

- *

- * Licensed under the Apache License, Version 2.0 (the "License");

- * you may not use this file except in compliance with the License.

- * You may obtain a copy of the License at

- *

- *      http://www.apache.org/licenses/LICENSE-2.0

- *

- * Unless required by applicable law or agreed to in writing, software

- * distributed under the License is distributed on an "AS IS" BASIS,

- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

- * See the License for the specific language governing permissions and

- * limitations under the License.

- */

-

-package signature.converter.doclet;

-

-import java.util.EnumSet;

-import java.util.HashMap;

-import java.util.HashSet;

-import java.util.LinkedList;

-import java.util.List;

-import java.util.Map;

-import java.util.Set;

-import java.util.Stack;

-import java.util.Map.Entry;

-

-import signature.converter.Visibility;

-import signature.model.IAnnotation;

-import signature.model.IAnnotationElement;

-import signature.model.IAnnotationField;

-import signature.model.IApi;

-import signature.model.IClassDefinition;

-import signature.model.IClassReference;

-import signature.model.IConstructor;

-import signature.model.IEnumConstant;

-import signature.model.IField;

-import signature.model.IGenericDeclaration;

-import signature.model.IMethod;

-import signature.model.IPackage;

-import signature.model.IParameter;

-import signature.model.ITypeReference;

-import signature.model.ITypeVariableDefinition;

-import signature.model.ITypeVariableReference;

-import signature.model.Kind;

-import signature.model.Modifier;

-import signature.model.impl.SigAnnotation;

-import signature.model.impl.SigAnnotationElement;

-import signature.model.impl.SigAnnotationField;

-import signature.model.impl.SigApi;

-import signature.model.impl.SigClassDefinition;

-import signature.model.impl.SigClassReference;

-import signature.model.impl.SigConstructor;

-import signature.model.impl.SigEnumConstant;

-import signature.model.impl.SigExecutableMember;

-import signature.model.impl.SigField;

-import signature.model.impl.SigMethod;

-import signature.model.impl.SigPackage;

-import signature.model.impl.SigParameter;

-import signature.model.impl.SigPrimitiveType;

-import signature.model.impl.SigTypeVariableDefinition;

-import signature.model.impl.SigTypeVariableReference;

-import signature.model.util.TypePool;

-

-import com.sun.javadoc.AnnotationDesc;

-import com.sun.javadoc.AnnotationTypeDoc;

-import com.sun.javadoc.AnnotationTypeElementDoc;

-import com.sun.javadoc.AnnotationValue;

-import com.sun.javadoc.ClassDoc;

-import com.sun.javadoc.ConstructorDoc;

-import com.sun.javadoc.ExecutableMemberDoc;

-import com.sun.javadoc.FieldDoc;

-import com.sun.javadoc.MethodDoc;

-import com.sun.javadoc.PackageDoc;

-import com.sun.javadoc.Parameter;

-import com.sun.javadoc.ParameterizedType;

-import com.sun.javadoc.ProgramElementDoc;

-import com.sun.javadoc.RootDoc;

-import com.sun.javadoc.Type;

-import com.sun.javadoc.TypeVariable;

-import com.sun.javadoc.WildcardType;

-import com.sun.javadoc.AnnotationDesc.ElementValuePair;

-

-public class DocletToSigConverter {

-

-    TypePool pool;

-    Set<String> packageNames;

-

-    /**

-     * Converts the signature information javadoc knows about into a

-     * signature.model.ISources structure.

-     */

-    public IApi convertDocletRoot(String name, RootDoc root,

-            Visibility visibility, Set<String> packageNames) {

-        this.pool = new TypePool();

-        this.packageNames = packageNames;

-

-        Set<IPackage> packages = new HashSet<IPackage>();

-

-        for (PackageDoc pack : root.specifiedPackages()) {

-            assert packageNames.contains(pack.name());

-            packages.add(convertPackage(pack));

-        }

-

-        SigApi sources = new SigApi(name, visibility);

-        sources.setPackages(packages);

-        return sources;

-    }

-

-    private IPackage convertPackage(PackageDoc packageDoc) {

-        Set<IClassDefinition> classes = new HashSet<IClassDefinition>();

-        for (ClassDoc clazz : packageDoc.allClasses()) {

-            // classes.add((IClass)convertType(clazz));

-            classes.add(convertClass(clazz));

-        }

-

-        SigPackage p = new SigPackage(packageDoc.name());

-        p.setClasses(classes);

-        p.setAnnotations(convertAnnotations(packageDoc.annotations()));

-        return p;

-    }

-

-    private SigClassDefinition convertClass(ClassDoc classDoc) {

-

-        SigClassDefinition c = pool.getClass(classDoc.containingPackage()

-                .name(), classDoc.name());

-        if (c.getKind() != Kind.UNINITIALIZED) return c;

-

-        if (classDoc.isEnum())

-            c.setKind(Kind.ENUM);

-        else if (classDoc.isInterface())

-            c.setKind(Kind.INTERFACE);

-        else if (classDoc.isClass())

-            c.setKind(Kind.CLASS);

-        else if (classDoc.isAnnotationType()) c.setKind(Kind.ANNOTATION);

-

-        if (!packageNames.contains(c.getPackageName())) {

-            // no additional conversion for this class is necessary

-            initializeClass(c);

-            return c;

-        }

-

-        c.setModifiers(convertModifiers(classDoc.modifierSpecifier()));

-        if (Kind.INTERFACE.equals(c.getKind())

-                || Kind.ANNOTATION.equals(c.getKind())) {

-            c.getModifiers().add(Modifier.ABSTRACT);

-        }

-

-        // superclass may be a class or a parameterized type (e.g. extends

-        // List<String>),

-        // may also be null if classDoc is an interface

-        Type superclassType = classDoc.superclassType();

-        if (superclassType != null) {

-            c.setSuperClass(convertTypeReference(classDoc.superclassType()));

-        } else {

-            c.setSuperClass(null);

-        }

-

-        Set<ITypeReference> interfaces = new HashSet<ITypeReference>();

-        for (Type interfaceType : classDoc.interfaceTypes()) {

-            interfaces.add(convertTypeReference(interfaceType));

-        }

-        c.setInterfaces(interfaces);

-

-        ClassDoc containingClass = classDoc.containingClass();

-        if (containingClass != null)

-            c.setDeclaringClass(convertClass(containingClass));

-        else

-            c.setDeclaringClass(null);

-

-        Set<IClassDefinition> innerClasses = new HashSet<IClassDefinition>();

-        for (ClassDoc innerClass : classDoc.innerClasses()) {

-            innerClasses.add(convertClass(innerClass));

-        }

-        c.setInnerClasses(innerClasses);

-

-        Set<IConstructor> constructors = new HashSet<IConstructor>();

-        for (ConstructorDoc constructor : classDoc.constructors()) {

-            constructors.add(convertConstructor(constructor));

-        }

-        c.setConstructors(constructors);

-

-        Set<IMethod> methods = new HashSet<IMethod>();

-        for (MethodDoc method : classDoc.methods()) {

-            methods.add(convertMethod(method));

-        }

-        c.setMethods(methods);

-

-        Set<IField> fields = new HashSet<IField>();

-        for (FieldDoc field : classDoc.fields()) {

-            fields.add(convertField(field));

-        }

-        c.setFields(fields);

-

-        Set<IEnumConstant> enumConstants = new HashSet<IEnumConstant>();

-        int ordinal = 0;

-        for (FieldDoc enumConstant : classDoc.enumConstants()) {

-            enumConstants.add(convertEnumConstant(enumConstant, ordinal++));

-        }

-        c.setEnumConstants(enumConstants);

-

-        List<ITypeVariableDefinition> typeParameters =

-                new LinkedList<ITypeVariableDefinition>();

-        for (TypeVariable typeVariable : classDoc.typeParameters()) {

-            typeParameters

-                    .add(((ITypeVariableReference) convertTypeReference(

-                            typeVariable)).getTypeVariableDefinition());

-        }

-        c.setTypeParameters(typeParameters);

-

-        if (classDoc.isAnnotationType()) {

-            Map<SigAnnotationField, AnnotationTypeElementDoc> annotationFieldAnnotations =

-                    new HashMap<SigAnnotationField, AnnotationTypeElementDoc>();

-

-            // AnnotationTypeDoc annotationType =

-            // classDoc.asAnnotationTypeDoc(); // bug in Doclet Implementation,

-            // has been reported to sun

-            AnnotationTypeDoc annotationType = (AnnotationTypeDoc) classDoc;

-

-            Set<IAnnotationField> annotationFields =

-                    new HashSet<IAnnotationField>();

-            for (AnnotationTypeElementDoc annotationElement : annotationType

-                    .elements()) {

-                SigAnnotationField annotationField = new SigAnnotationField(

-                        annotationElement.name());

-                annotationField.setModifiers(convertModifiers(annotationElement

-                        .modifierSpecifier()));

-                annotationField.setType(convertTypeReference(annotationElement

-                        .returnType()));

-                annotationField

-                        .setDefaultValue(convertAnnotationValue(

-                                annotationElement.defaultValue()));

-

-                // the annotations on fields are set later because these

-                // annotations may be of

-                // the same type and may use fields which are not yet defined

-                annotationFieldAnnotations.put(annotationField,

-                        annotationElement);

-

-                annotationFields.add(annotationField);

-            }

-            c.setAnnotationFields(annotationFields);

-

-            // set annotation field annotations

-            for (Entry<SigAnnotationField, AnnotationTypeElementDoc> entry :

-                    annotationFieldAnnotations.entrySet()) {

-                entry.getKey().setAnnotations(

-                        convertAnnotations(entry.getValue().annotations()));

-            }

-        } else { // no annotation type

-            c.setAnnotationFields(null);

-        }

-

-        // set class annotations

-        c.setAnnotations(convertAnnotations(classDoc.annotations()));

-

-        return c;

-

-    }

-

-    private Object convertAnnotationValue(AnnotationValue annotationValue) {

-        if (annotationValue == null) {

-            return null;

-        }

-        Object value = annotationValue.value();

-        if (value instanceof Type) {

-            // Type contains primitive types as well, e.g. void.class

-            return convertTypeReference((Type) value);

-        } else if (value instanceof String) {

-            return value;

-        } else if (value instanceof Double || value instanceof Float

-                || value instanceof Long || value instanceof Integer

-                || value instanceof Short || value instanceof Byte

-                || value instanceof Character || value instanceof Boolean) {

-            return value;

-        } else if (value instanceof FieldDoc) {

-            FieldDoc field = (FieldDoc) value;

-            String name = field.name();

-            ITypeReference fieldType = convertTypeReference(field.type());

-            IClassReference fieldClassRef = (IClassReference) fieldType;

-            IClassDefinition fieldClass = fieldClassRef.getClassDefinition();

-

-            assert fieldClass.getKind() == Kind.ENUM;

-            Set<IEnumConstant> constants = fieldClass.getEnumConstants();

-            for (IEnumConstant enumConstant : constants) {

-                if (enumConstant.getName().equals(name)) value = enumConstant;

-            }

-            assert value instanceof IEnumConstant;

-            return value;

-        } else if (value instanceof AnnotationDesc) {

-            return convertAnnotation((AnnotationDesc) value);

-        } else if (value instanceof AnnotationValue) {

-            return convertAnnotationValue((AnnotationValue) value);

-        } else if (value instanceof AnnotationValue[]) {

-            AnnotationValue[] arr = (AnnotationValue[]) value;

-            int length = arr.length;

-            Object[] annotationArray = new Object[length];

-            for (int i = 0; i < length; i++) {

-                annotationArray[i] = convertAnnotationValue(arr[i]);

-            }

-            return annotationArray;

-        } else {

-            throw new RuntimeException("not expected case");

-        }

-    }

-

-    private ITypeReference convertArrayType(Type type) {

-        assert type.asWildcardType() == null;

-        assert type.asAnnotationTypeDoc() == null;

-

-        ITypeReference baseType = null;

-        if (type.asTypeVariable() != null) {

-            baseType = convertTypeReference(type.asTypeVariable());

-        } else if (type.asParameterizedType() != null) {

-            baseType = convertTypeReference(type.asParameterizedType());

-        } else if (type.asClassDoc() != null) {

-            baseType = new SigClassReference(convertClass(type.asClassDoc()));

-        } else if (type.isPrimitive()) {

-            baseType = SigPrimitiveType.valueOfTypeName(type.typeName());

-        } else {

-            throw new RuntimeException(type.toString());

-        }

-

-        ITypeReference arrayType = baseType;

-        int dimension = type.dimension().length() / 2;

-        while (dimension > 0) {

-            arrayType = pool.getArrayType(arrayType);

-            dimension--;

-        }

-

-        return arrayType;

-    }

-

-    private SigTypeVariableDefinition currentTypeVariableDefinition = null;

-

-    private ITypeReference convertTypeReference(Type type) {

-        assert type != null;

-

-        if (!"".equals(type.dimension())) {

-            return convertArrayType(type);

-        }

-

-        ParameterizedType pType = type.asParameterizedType();

-        if (pType != null) {

-            ITypeReference ownerType = null;

-            Type containingType = pType.containingType();

-            if (containingType != null)

-                ownerType = convertTypeReference(containingType);

-            IClassReference rawType = new SigClassReference(convertClass(pType

-                    .asClassDoc()));

-

-            List<ITypeReference> typeArguments =

-                    new LinkedList<ITypeReference>();

-            for (Type typeArgument : pType.typeArguments()) {

-                typeArguments.add(convertTypeReference(typeArgument));

-            }

-

-            if (typeArguments.size() > 0) {

-                return pool.getParameterizedType(ownerType, rawType,

-                        typeArguments);

-            } else {

-                return rawType;

-            }

-        }

-

-        TypeVariable tv = type.asTypeVariable();

-        if (tv != null) {

-            String name = tv.typeName();

-

-            if (currentTypeVariableDefinition != null

-                    && name.equals(currentTypeVariableDefinition.getName()))

-                return new SigTypeVariableReference(

-                        currentTypeVariableDefinition);

-

-            IGenericDeclaration genericDeclaration = null;

-            ProgramElementDoc programElement = tv.owner();

-            if (programElement instanceof ClassDoc) {

-                genericDeclaration = convertClass((ClassDoc) programElement);

-            } else if (programElement instanceof MethodDoc

-                    && currentMethod.size() > 0) {

-                genericDeclaration = currentMethod.peek();

-            } else if (programElement instanceof ConstructorDoc

-                    && currentConstructor.size() > 0) {

-                genericDeclaration = currentConstructor.peek();

-            } else {

-                throw new IllegalStateException("situation not expected");

-            }

-            SigTypeVariableDefinition typeVariable = pool.getTypeVariable(name,

-                    genericDeclaration);

-

-            List<ITypeReference> upperBounds = new LinkedList<ITypeReference>();

-            for (Type upperBound : tv.bounds()) {

-                // we are converting a type variable declaration which is stored

-                // in the

-                // field currentTypeVariableDefinition

-                assert currentTypeVariableDefinition == null;

-                currentTypeVariableDefinition = typeVariable;

-                upperBounds.add(convertTypeReference(upperBound));

-                currentTypeVariableDefinition = null;

-            }

-            if (upperBounds.size() == 0) {

-                // no explicit bounds, use java.lang.Object

-                upperBounds.add(pool.getClassReference("java.lang", "Object"));

-            }

-            typeVariable.setUpperBounds(upperBounds);

-

-            return new SigTypeVariableReference(typeVariable);

-        }

-

-        WildcardType wt = type.asWildcardType();

-        if (wt != null) {

-            ITypeReference lowerBound = null;

-            for (Type superBound : wt.superBounds()) {

-                lowerBound = convertTypeReference(superBound);

-            }

-

-            List<ITypeReference> upperBounds = new LinkedList<ITypeReference>();

-            for (Type upperBound : wt.extendsBounds()) {

-                upperBounds.add(convertTypeReference(upperBound));

-            }

-            if (upperBounds.size() == 0) {

-                // no explicit bounds, use java.lang.Object

-                upperBounds.add(pool.getClassReference("java.lang", "Object"));

-            }

-

-            return pool.getWildcardType(lowerBound, upperBounds);

-        }

-

-        ClassDoc c = type.asClassDoc();

-        if (c != null) {

-            return new SigClassReference(convertClass(c));

-        }

-

-        if (type.isPrimitive()) {

-            return SigPrimitiveType.valueOfTypeName(type.typeName());

-        }

-

-        throw new IllegalStateException(type.toString());

-    }

-

-    private void convertExecutableMember(ExecutableMemberDoc member,

-            SigExecutableMember m) {

-        Set<Modifier> modifiers = convertModifiers(member.modifierSpecifier());

-

-        // Doclet Bug: final values method is not considered as final

-        if (member.containingClass().isEnum() && member.name().equals("values")

-                && member.parameters().length == 0) {

-            modifiers.add(Modifier.FINAL);

-        }

-

-        if (member.containingClass().isInterface()) {

-            modifiers.add(Modifier.ABSTRACT);

-        }

-

-        m.setModifiers(modifiers);

-        m.setAnnotations(convertAnnotations(member.annotations()));

-        m.setDeclaringClass(convertClass(member.containingClass()));

-

-        List<ITypeVariableDefinition> typeParameters =

-                new LinkedList<ITypeVariableDefinition>();

-        for (TypeVariable typeParameter : member.typeParameters()) {

-            String name = typeParameter.typeName();

-            IGenericDeclaration genericDeclaration = null;

-            if (currentMethod.size() > 0)

-                genericDeclaration = currentMethod.peek();

-            else if (currentConstructor.size() > 0)

-                genericDeclaration = currentConstructor.peek();

-            else

-                throw new RuntimeException();

-            SigTypeVariableDefinition p = pool.getTypeVariable(name,

-                    genericDeclaration);

-

-            List<ITypeReference> upperBounds = new LinkedList<ITypeReference>();

-            for (Type u : typeParameter.bounds()) {

-                upperBounds.add(convertTypeReference(u));

-            }

-            p.setUpperBounds(upperBounds);

-            typeParameters.add(p);

-        }

-        m.setTypeParameters(typeParameters);

-

-        List<IParameter> parameters = new LinkedList<IParameter>();

-        for (Parameter parameter : member.parameters()) {

-            SigParameter p = new SigParameter(convertTypeReference(parameter

-                    .type()));

-            p.setAnnotations(convertAnnotations(parameter.annotations()));

-            parameters.add(p);

-        }

-        m.setParameters(parameters);

-

-        Set<ITypeReference> exceptions = new HashSet<ITypeReference>();

-        for (Type exceptionType : member.thrownExceptionTypes()) {

-            exceptions.add(convertTypeReference(exceptionType));

-        }

-        m.setExceptions(exceptions);

-    }

-

-    private Stack<SigMethod> currentMethod = new Stack<SigMethod>();

-

-    private IMethod convertMethod(MethodDoc method) {

-        SigMethod m = new SigMethod(method.name());

-        currentMethod.push(m);

-        convertExecutableMember(method, m);

-        m.setReturnType(convertTypeReference(method.returnType()));

-        currentMethod.pop();

-        return m;

-    }

-

-    private Stack<SigConstructor> currentConstructor =

-            new Stack<SigConstructor>();

-

-    private IConstructor convertConstructor(ConstructorDoc constructor) {

-        SigConstructor c = new SigConstructor(constructor.name());

-        currentConstructor.push(c);

-        convertExecutableMember(constructor, c);

-        currentConstructor.pop();

-        return c;

-    }

-

-    private IField convertField(FieldDoc field) {

-        SigField f = new SigField(field.name());

-        f.setAnnotations(convertAnnotations(field.annotations()));

-        f.setModifiers(convertModifiers(field.modifierSpecifier()));

-        f.setType(convertTypeReference(field.type()));

-        return f;

-    }

-

-    private IEnumConstant convertEnumConstant(FieldDoc enumConstant,

-            int ordinal) {

-        SigEnumConstant ec = new SigEnumConstant(enumConstant.name());

-        ec.setOrdinal(ordinal);

-        ec.setAnnotations(convertAnnotations(enumConstant.annotations()));

-        ec.setModifiers(convertModifiers(enumConstant.modifierSpecifier()));

-        ec.setType(convertTypeReference(enumConstant.type()));

-        return ec;

-    }

-

-    private Set<IAnnotation> convertAnnotations(

-            AnnotationDesc[] annotationDescs) {

-        Set<IAnnotation> annotations = new HashSet<IAnnotation>();

-        for (AnnotationDesc annotationDesc : annotationDescs) {

-            if (!annotationRetentionIsSource(annotationDesc))

-                annotations.add(convertAnnotation(annotationDesc));

-        }

-        return annotations;

-    }

-

-    private boolean annotationRetentionIsSource(AnnotationDesc annotationDesc) {

-        AnnotationTypeDoc type = annotationDesc.annotationType();

-        AnnotationDesc[] annotations = type.annotations();

-        for (AnnotationDesc d : annotations) {

-            if ("java.lang.annotation.Retention".equals(d.annotationType()

-                    .qualifiedName())) {

-                for (ElementValuePair value : d.elementValues()) {

-                    if ("value".equals(value.element().name())) {

-                        return "java.lang.annotation.RetentionPolicy.SOURCE"

-                                .equals(value.value().value().toString());

-                    }

-                }

-            }

-        }

-        // default retention policy is CLASS

-        return false;

-    }

-

-    private IAnnotation convertAnnotation(AnnotationDesc annotationDesc) {

-        SigAnnotation a = new SigAnnotation();

-

-        IClassReference annotationType = (IClassReference) convertTypeReference(

-                annotationDesc.annotationType());

-        a.setType(annotationType);

-

-        Set<IAnnotationElement> elements = new HashSet<IAnnotationElement>();

-        for (AnnotationDesc.ElementValuePair pair : annotationDesc

-                .elementValues()) {

-            SigAnnotationElement element = new SigAnnotationElement();

-            elements.add(element);

-

-            element.setValue(convertAnnotationValue(pair.value()));

-            String name = pair.element().name();

-            for (IAnnotationField field : annotationType.getClassDefinition()

-                    .getAnnotationFields()) {

-                if (field.getName().equals(name)) {

-                    element.setDeclaringField(field);

-                }

-            }

-        }

-        a.setElements(elements);

-        return a;

-    }

-

-    private void initializeClass(SigClassDefinition c) {

-        c.setAnnotationFields(null);

-        c.setAnnotations(null);

-        c.setConstructors(null);

-        c.setDeclaringClass(null);

-        c.setEnumConstants(null);

-        c.setFields(null);

-        c.setInnerClasses(null);

-        c.setInterfaces(null);

-        c.setMethods(null);

-        c.setModifiers(null);

-        c.setSuperClass(null);

-        c.setTypeParameters(null);

-    }

-

-    private Set<Modifier> convertModifiers(int mod) {

-        Set<Modifier> modifiers = EnumSet.noneOf(Modifier.class);

-        if (java.lang.reflect.Modifier.isAbstract(mod))

-            modifiers.add(Modifier.ABSTRACT);

-        if (java.lang.reflect.Modifier.isFinal(mod))

-            modifiers.add(Modifier.FINAL);

-        // if (java.lang.reflect.Modifier.isNative(mod))

-        // modifiers.add(Modifier.NATIVE);

-        if (java.lang.reflect.Modifier.isPrivate(mod))

-            modifiers.add(Modifier.PRIVATE);

-        if (java.lang.reflect.Modifier.isProtected(mod))

-            modifiers.add(Modifier.PROTECTED);

-        if (java.lang.reflect.Modifier.isPublic(mod))

-            modifiers.add(Modifier.PUBLIC);

-        if (java.lang.reflect.Modifier.isStatic(mod))

-            modifiers.add(Modifier.STATIC);

-        // if (java.lang.reflect.Modifier.isStrict(mod))

-        // modifiers.add(Modifier.STRICT);

-        // if (java.lang.reflect.Modifier.isSynchronized(mod))

-        // modifiers.add(Modifier.SYNCHRONIZED);

-        // if (java.lang.reflect.Modifier.isTransient(mod))

-        // modifiers.add(Modifier.TRANSIENT);

-        if (java.lang.reflect.Modifier.isVolatile(mod))

-            modifiers.add(Modifier.VOLATILE);

-

-        return modifiers;

-    }

-

-}

diff --git a/tools/signature-tools/src/signature/io/IApiDeltaExternalizer.java b/tools/signature-tools/src/signature/io/IApiDeltaExternalizer.java
deleted file mode 100644
index bf3cb8b..0000000
--- a/tools/signature-tools/src/signature/io/IApiDeltaExternalizer.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.io;
-
-import java.io.IOException;
-
-import signature.compare.model.IApiDelta;
-
-public interface IApiDeltaExternalizer {
-    void externalize(String location, IApiDelta delta) throws IOException;
-}
diff --git a/tools/signature-tools/src/signature/io/IApiExternalizer.java b/tools/signature-tools/src/signature/io/IApiExternalizer.java
deleted file mode 100644
index 3bbfbe5..0000000
--- a/tools/signature-tools/src/signature/io/IApiExternalizer.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*

- * Copyright (C) 2009 The Android Open Source Project

- *

- * Licensed under the Apache License, Version 2.0 (the "License");

- * you may not use this file except in compliance with the License.

- * You may obtain a copy of the License at

- *

- *      http://www.apache.org/licenses/LICENSE-2.0

- *

- * Unless required by applicable law or agreed to in writing, software

- * distributed under the License is distributed on an "AS IS" BASIS,

- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

- * See the License for the specific language governing permissions and

- * limitations under the License.

- */

-

-package signature.io;

-

-import signature.model.IApi;

-

-import java.io.IOException;

-

-/**

- * This interface is used to write API definitions. Possible implementations of

- * this interface use Java serialization to store the API in binary form on the

- * disk. An alternative implementation can use ASCII files.

- */

-public interface IApiExternalizer {

-    void externalizeApi(String loacation, IApi signature) throws IOException;

-}

diff --git a/tools/signature-tools/src/signature/io/IApiLoader.java b/tools/signature-tools/src/signature/io/IApiLoader.java
deleted file mode 100644
index a38fa1a..0000000
--- a/tools/signature-tools/src/signature/io/IApiLoader.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.io;
-
-import java.io.IOException;
-import java.util.Set;
-
-import signature.converter.Visibility;
-import signature.model.IApi;
-
-public interface IApiLoader {
-    IApi loadApi(String name, Visibility visibility, Set<String> fileNames,
-            Set<String> packageNames) throws IOException;
-}
diff --git a/tools/signature-tools/src/signature/io/html/ApiOverviewPage.java b/tools/signature-tools/src/signature/io/html/ApiOverviewPage.java
deleted file mode 100644
index d97c092..0000000
--- a/tools/signature-tools/src/signature/io/html/ApiOverviewPage.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.io.html;
-
-import org.antlr.stringtemplate.StringTemplate;
-
-import signature.compare.model.IApiDelta;
-import signature.compare.model.IPackageDelta;
-import signature.compare.model.impl.SigDelta;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-public class ApiOverviewPage implements IEmitter {
-
-    private final IApiDelta apiDelta;
-
-    private List<IPackageDelta> removedPackages;
-    private List<IPackageDelta> addedPackages;
-    private List<IPackageDelta> changedPackages;
-    private Map<String, String> commonInfos;
-
-    public ApiOverviewPage(IApiDelta apiDelta,
-            Map<String, String> commonInfos) {
-        this.apiDelta = apiDelta;
-        this.commonInfos = commonInfos;
-        prepareData();
-    }
-
-    private void prepareData() {
-        if (apiDelta.getPackageDeltas().isEmpty()) {
-            commonInfos.put("no_delta", "no_delta");
-        }
-        removedPackages = new ArrayList<IPackageDelta>(SigDelta
-                .getRemoved(apiDelta.getPackageDeltas()));
-        Collections.sort(removedPackages, new PackageByNameComparator());
-
-        addedPackages = new ArrayList<IPackageDelta>(SigDelta.getAdded(apiDelta
-                .getPackageDeltas()));
-        Collections.sort(addedPackages, new PackageByNameComparator());
-
-        changedPackages = new ArrayList<IPackageDelta>(SigDelta
-                .getChanged(apiDelta.getPackageDeltas()));
-        Collections.sort(changedPackages, new PackageByNameComparator());
-    }
-
-    public void writeTo(StringBuilder b) {
-        StringTemplate template = TemplateStore
-                .getStringTemplate("ApiOverviewPage");
-        template.setArgumentContext(commonInfos);
-        template.setAttribute("removed_packages", removedPackages);
-        template.setAttribute("added_packages", addedPackages);
-        template.setAttribute("changed_packages", changedPackages);
-        b.append(template.toString());
-    }
-}
diff --git a/tools/signature-tools/src/signature/io/html/ClassByNameComparator.java b/tools/signature-tools/src/signature/io/html/ClassByNameComparator.java
deleted file mode 100644
index 8e23434..0000000
--- a/tools/signature-tools/src/signature/io/html/ClassByNameComparator.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.io.html;
-
-import signature.compare.model.IClassDefinitionDelta;
-
-import java.util.Comparator;
-
-public class ClassByNameComparator implements
-        Comparator<IClassDefinitionDelta> {
-
-    public int compare(IClassDefinitionDelta a, IClassDefinitionDelta b) {
-        assert a.getType() == b.getType();
-        if (a.getFrom() != null) {
-            return a.getFrom().getName().compareTo(b.getFrom().getName());
-        } else {
-            return a.getTo().getName().compareTo(b.getTo().getName());
-        }
-    }
-}
diff --git a/tools/signature-tools/src/signature/io/html/ClassOverviewPage.java b/tools/signature-tools/src/signature/io/html/ClassOverviewPage.java
deleted file mode 100644
index 6951fb3..0000000
--- a/tools/signature-tools/src/signature/io/html/ClassOverviewPage.java
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.io.html;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Map;
-
-import org.antlr.stringtemplate.StringTemplate;
-
-import signature.compare.model.IAnnotationFieldDelta;
-import signature.compare.model.IClassDefinitionDelta;
-import signature.compare.model.IConstructorDelta;
-import signature.compare.model.IEnumConstantDelta;
-import signature.compare.model.IFieldDelta;
-import signature.compare.model.IMethodDelta;
-import signature.compare.model.impl.SigDelta;
-
-public class ClassOverviewPage implements IEmitter {
-
-    private static final String PAGE = "ClassOverviewPage";
-
-    private final IClassDefinitionDelta classDelta;
-
-    private FieldByNameComparator<IFieldDelta> fieldComparator =
-            new FieldByNameComparator<IFieldDelta>();
-    private ArrayList<IFieldDelta> removedFields;
-    private ArrayList<IFieldDelta> addedFields;
-    private ArrayList<IFieldDelta> changedFields;
-
-    private FieldByNameComparator<IAnnotationFieldDelta> annotationfieldComparator =
-            new FieldByNameComparator<IAnnotationFieldDelta>();
-    private ArrayList<IAnnotationFieldDelta> removedAnnotationFields;
-    private ArrayList<IAnnotationFieldDelta> addedAnnotationFields;
-    private ArrayList<IAnnotationFieldDelta> changedAnnotationFields;
-
-    private FieldByNameComparator<IEnumConstantDelta> enumConstantComparator =
-            new FieldByNameComparator<IEnumConstantDelta>();
-    private ArrayList<IEnumConstantDelta> removedEnumConstants;
-    private ArrayList<IEnumConstantDelta> addedEnumConstants;
-    private ArrayList<IEnumConstantDelta> changedEnumConstants;
-
-    private ExecutableMemberComparator constructorComparator =
-            new ExecutableMemberComparator();
-    private ArrayList<IConstructorDelta> removedConstructors;
-    private ArrayList<IConstructorDelta> addedConstructors;
-    private ArrayList<IConstructorDelta> changedConstructors;
-
-    private ExecutableMemberComparator methodComparator =
-            new ExecutableMemberComparator();
-    private ArrayList<IMethodDelta> removedMethods;
-    private ArrayList<IMethodDelta> addedMethods;
-    private ArrayList<IMethodDelta> changedMethods;
-
-    private final Map<String, String> commonInfos;
-
-    public ClassOverviewPage(IClassDefinitionDelta classDelta,
-            Map<String, String> commonInfos) {
-        this.classDelta = classDelta;
-        this.commonInfos = commonInfos;
-        prepareData();
-    }
-
-    private void prepareData() {
-        if (classDelta.getFieldDeltas() != null) {
-            prepareFieldDeltas();
-        }
-        if (classDelta.getAnnotationFieldDeltas() != null) {
-            prepareAnnotationFieldDeltas();
-        }
-        if (classDelta.getEnumConstantDeltas() != null) {
-            prepareEnumConstantDeltas();
-        }
-        if (classDelta.getConstructorDeltas() != null) {
-            prepareConstructorDeltas();
-        }
-        if (classDelta.getMethodDeltas() != null) {
-            prepareMethodDeltas();
-        }
-    }
-
-    private void prepareFieldDeltas() {
-        removedFields = new ArrayList<IFieldDelta>(SigDelta
-                .getRemoved(classDelta.getFieldDeltas()));
-        Collections.sort(removedFields, fieldComparator);
-
-        addedFields = new ArrayList<IFieldDelta>(SigDelta.getAdded(classDelta
-                .getFieldDeltas()));
-        Collections.sort(addedFields, fieldComparator);
-
-        changedFields = new ArrayList<IFieldDelta>(SigDelta
-                .getChanged(classDelta.getFieldDeltas()));
-        Collections.sort(changedFields, fieldComparator);
-    }
-
-    private void prepareAnnotationFieldDeltas() {
-        removedAnnotationFields = new ArrayList<IAnnotationFieldDelta>(SigDelta
-                .getRemoved(classDelta.getAnnotationFieldDeltas()));
-        Collections.sort(removedAnnotationFields, annotationfieldComparator);
-
-        addedAnnotationFields = new ArrayList<IAnnotationFieldDelta>(SigDelta
-                .getAdded(classDelta.getAnnotationFieldDeltas()));
-        Collections.sort(addedAnnotationFields, annotationfieldComparator);
-
-        changedAnnotationFields = new ArrayList<IAnnotationFieldDelta>(SigDelta
-                .getChanged(classDelta.getAnnotationFieldDeltas()));
-        Collections.sort(changedAnnotationFields, annotationfieldComparator);
-    }
-
-    private void prepareEnumConstantDeltas() {
-        removedEnumConstants = new ArrayList<IEnumConstantDelta>(SigDelta
-                .getRemoved(classDelta.getEnumConstantDeltas()));
-        Collections.sort(removedEnumConstants, enumConstantComparator);
-
-        addedEnumConstants = new ArrayList<IEnumConstantDelta>(SigDelta
-                .getAdded(classDelta.getEnumConstantDeltas()));
-        Collections.sort(addedEnumConstants, enumConstantComparator);
-
-        changedEnumConstants = new ArrayList<IEnumConstantDelta>(SigDelta
-                .getChanged(classDelta.getEnumConstantDeltas()));
-        Collections.sort(changedEnumConstants, enumConstantComparator);
-    }
-
-    private void prepareConstructorDeltas() {
-        removedConstructors = new ArrayList<IConstructorDelta>(SigDelta
-                .getRemoved(classDelta.getConstructorDeltas()));
-        Collections.sort(removedConstructors, constructorComparator);
-
-        addedConstructors = new ArrayList<IConstructorDelta>(SigDelta
-                .getAdded(classDelta.getConstructorDeltas()));
-        Collections.sort(addedConstructors, constructorComparator);
-
-        changedConstructors = new ArrayList<IConstructorDelta>(SigDelta
-                .getChanged(classDelta.getConstructorDeltas()));
-        Collections.sort(changedConstructors, constructorComparator);
-    }
-
-    private void prepareMethodDeltas() {
-        removedMethods = new ArrayList<IMethodDelta>(SigDelta
-                .getRemoved(classDelta.getMethodDeltas()));
-        Collections.sort(removedMethods, methodComparator);
-
-        addedMethods = new ArrayList<IMethodDelta>(SigDelta.getAdded(classDelta
-                .getMethodDeltas()));
-        Collections.sort(addedMethods, methodComparator);
-
-        changedMethods = new ArrayList<IMethodDelta>(SigDelta
-                .getChanged(classDelta.getMethodDeltas()));
-        Collections.sort(changedMethods, methodComparator);
-    }
-
-    public void writeTo(StringBuilder b) {
-        StringTemplate template = TemplateStore.getStringTemplate(PAGE);
-
-        template.setAttribute("class_delta", classDelta);
-        boolean annotationDelta = classDelta.getAnnotationDeltas() != null;
-        boolean modifierDelta = classDelta.getModifierDeltas() != null;
-        boolean typeVariableDelta = classDelta.getTypeVariableDeltas() != null;
-        boolean superClassDelta = classDelta.getSuperClassDelta() != null;
-        boolean interfaceDelta = classDelta.getInterfaceDeltas() != null;
-        boolean hasSignatureDelta = annotationDelta || modifierDelta
-                || typeVariableDelta || superClassDelta || interfaceDelta;
-
-        template.setAttribute("has_class_signature_delta", hasSignatureDelta);
-
-        template.setAttribute("removed_fields", removedFields);
-        template.setAttribute("added_fields", addedFields);
-        template.setAttribute("changed_fields", changedFields);
-
-        template.setAttribute("removed_annotation_fields",
-                removedAnnotationFields);
-        template.setAttribute("added_annotation_fields", addedAnnotationFields);
-        template.setAttribute("changed_annotation_fields",
-                changedAnnotationFields);
-
-        template.setAttribute("removed_enum_constants", removedEnumConstants);
-        template.setAttribute("added_enum_constants", addedEnumConstants);
-        template.setAttribute("changed_enum_constants", changedEnumConstants);
-
-        template.setAttribute("removed_constructors", removedConstructors);
-        template.setAttribute("added_constructors", addedConstructors);
-        template.setAttribute("changed_constructors", changedConstructors);
-
-        template.setAttribute("removed_methods", removedMethods);
-        template.setAttribute("added_methods", addedMethods);
-        template.setAttribute("changed_methods", changedMethods);
-
-        template.setArgumentContext(commonInfos);
-        b.append(template.toString());
-    }
-}
diff --git a/tools/signature-tools/src/signature/io/html/ExecutableMemberComparator.java b/tools/signature-tools/src/signature/io/html/ExecutableMemberComparator.java
deleted file mode 100644
index e342342..0000000
--- a/tools/signature-tools/src/signature/io/html/ExecutableMemberComparator.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.io.html;
-
-import signature.compare.model.IExecutableMemberDelta;
-import signature.model.IArrayType;
-import signature.model.IClassDefinition;
-import signature.model.IClassReference;
-import signature.model.IExecutableMember;
-import signature.model.IParameter;
-import signature.model.IParameterizedType;
-import signature.model.IPrimitiveType;
-import signature.model.ITypeDefinition;
-import signature.model.ITypeReference;
-import signature.model.ITypeVariableDefinition;
-import signature.model.ITypeVariableReference;
-
-import java.util.Comparator;
-import java.util.Iterator;
-import java.util.List;
-
-public class ExecutableMemberComparator implements
-        Comparator<IExecutableMemberDelta<? extends IExecutableMember>> {
-
-    public int compare(IExecutableMemberDelta<? extends IExecutableMember> a,
-            IExecutableMemberDelta<? extends IExecutableMember> b) {
-        assert a.getType() == b.getType();
-        IExecutableMember aMember = null;
-        IExecutableMember bMember = null;
-
-        if (a.getFrom() != null) {
-            aMember = a.getFrom();
-            bMember = b.getFrom();
-        } else {
-            aMember = a.getTo();
-            bMember = b.getTo();
-        }
-
-        int returnValue = aMember.getName().compareTo(bMember.getName());
-        return returnValue != 0 ? returnValue : compareParameterLists(aMember
-                .getParameters(), bMember.getParameters());
-    }
-
-    private int compareParameterLists(List<IParameter> a, List<IParameter> b) {
-        if (a.size() != b.size()) {
-            return a.size() - b.size();
-        }
-        Iterator<IParameter> aIt = a.iterator();
-        Iterator<IParameter> bIt = b.iterator();
-        int returnValue = 0;
-        while (aIt.hasNext() && bIt.hasNext()) {
-            returnValue += getTypeName(aIt.next().getType()).compareTo(
-                    getTypeName(bIt.next().getType()));
-        }
-        return returnValue;
-    }
-
-    private String getTypeName(ITypeReference type) {
-        if (type instanceof IClassReference) {
-            return getTypeName(((IClassReference) type).getClassDefinition());
-        }
-        if (type instanceof ITypeVariableReference) {
-            return getTypeName(((ITypeVariableReference) type)
-                    .getTypeVariableDefinition());
-        }
-        if (type instanceof IParameterizedType) {
-            return getTypeName(((IParameterizedType) type).getRawType());
-        }
-        if (type instanceof IArrayType) {
-            return getTypeName(((IArrayType) type).getComponentType());
-        }
-        if (type instanceof IPrimitiveType) {
-            return ((IPrimitiveType) type).getName();
-        }
-        return type.toString();
-    }
-
-    private String getTypeName(ITypeDefinition type) {
-        if (type instanceof IClassDefinition) {
-            return ((IClassDefinition) type).getName();
-        }
-        if (type instanceof ITypeVariableDefinition) {
-            return ((ITypeVariableDefinition) type).getName();
-        }
-        return type.toString();
-    }
-
-}
diff --git a/tools/signature-tools/src/signature/io/html/FieldByNameComparator.java b/tools/signature-tools/src/signature/io/html/FieldByNameComparator.java
deleted file mode 100644
index 9aaf1f8..0000000
--- a/tools/signature-tools/src/signature/io/html/FieldByNameComparator.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.io.html;
-
-import java.util.Comparator;
-
-import signature.compare.model.IMemberDelta;
-import signature.model.IField;
-
-public class FieldByNameComparator<T extends IMemberDelta<?>> implements
-        Comparator<T> {
-
-    public int compare(T a, T b) {
-        assert a.getType() == b.getType();
-        IField aField = null;
-        IField bField = null;
-
-        // FIXME File javac or jdt bug.
-        // Note: Casts are required by javac 1.5.0_16.
-        if (a.getFrom() != null) {
-            aField = (IField) a.getFrom();
-            bField = (IField) b.getFrom();
-        } else {
-            aField = (IField) a.getTo();
-            bField = (IField) b.getTo();
-        }
-        return aField.getName().compareTo(bField.getName());
-    }
-}
diff --git a/tools/signature-tools/src/signature/io/html/HtmlDeltaExternalizer.java b/tools/signature-tools/src/signature/io/html/HtmlDeltaExternalizer.java
deleted file mode 100644
index 1ba5cba..0000000
--- a/tools/signature-tools/src/signature/io/html/HtmlDeltaExternalizer.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.io.html;
-
-import org.antlr.stringtemplate.StringTemplate;
-
-import signature.Version;
-import signature.compare.model.IApiDelta;
-import signature.compare.model.IClassDefinitionDelta;
-import signature.compare.model.IDelta;
-import signature.compare.model.IPackageDelta;
-import signature.compare.model.impl.SigDelta;
-import signature.io.IApiDeltaExternalizer;
-import signature.model.IClassDefinition;
-import signature.model.IPackage;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.text.DateFormat;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-
-public class HtmlDeltaExternalizer implements IApiDeltaExternalizer {
-
-    private static final String OVERVIEW_PAGE_NAME = "changes.html";
-    private static final String STYLE_SHEET_NAME = "styles.css";
-    private static final String DELTA_FOLDER = "changes" + File.separator;
-
-    public void externalize(String location, IApiDelta apiDelta)
-            throws IOException {
-        if (!location.endsWith(File.separator)) {
-            location += File.separator;
-        }
-
-        File directory = new File(location);
-        if (!directory.exists()) {
-            directory.mkdirs();
-        }
-
-        copyStyleSheet(location);
-
-        Map<String, String> commonInfos = new HashMap<String, String>();
-        commonInfos.put("creation_time", DateFormat.getDateTimeInstance()
-                .format(new Date()));
-        commonInfos.put("from_desc", apiDelta.getFrom().getName());
-        commonInfos.put("to_desc", apiDelta.getTo().getName());
-
-        // write overview page
-        StringBuilder content = new StringBuilder();
-        ApiOverviewPage apiOverviewPage = new ApiOverviewPage(apiDelta,
-                commonInfos);
-        apiOverviewPage.writeTo(content);
-        writeToFile(location + OVERVIEW_PAGE_NAME, content.toString());
-
-        // write package overview
-        Set<IPackageDelta> changedPackages = SigDelta.getChanged(apiDelta
-                .getPackageDeltas());
-        if (!changedPackages.isEmpty()) {
-
-            File file = new File(location + DELTA_FOLDER);
-            if (!file.exists()) {
-                file.mkdir();
-            }
-
-            for (IPackageDelta packageDelta : changedPackages) {
-                content = new StringBuilder();
-                PackageOverviewPage packagePage = new PackageOverviewPage(
-                        packageDelta, commonInfos);
-                packagePage.writeTo(content);
-                IPackage aPackage = getAnElement(packageDelta);
-                String packageOverviewFileName = location + DELTA_FOLDER
-                        + "pkg_" + aPackage.getName() + ".html";
-                writeToFile(packageOverviewFileName, content.toString());
-
-                // write class overviews
-                for (IClassDefinitionDelta classDelta : packageDelta
-                        .getClassDeltas()) {
-                    content = new StringBuilder();
-                    ClassOverviewPage classPage = new ClassOverviewPage(
-                            classDelta, commonInfos);
-                    classPage.writeTo(content);
-                    IClassDefinition aClass = getAnElement(classDelta);
-                    String classOverviewFileName = location + DELTA_FOLDER
-                            + aPackage.getName() + "." + aClass.getName()
-                            + ".html";
-                    writeToFile(classOverviewFileName, content.toString());
-                }
-            }
-        }
-        // write class overview
-    }
-
-    private static <T> T getAnElement(IDelta<T> delta) {
-        if (delta.getFrom() != null) {
-            return delta.getFrom();
-        } else {
-            return delta.getTo();
-        }
-    }
-
-    private void copyStyleSheet(String directory) throws IOException {
-        StringTemplate template = TemplateStore.getStringTemplate("Styles");
-        template.setAttribute("version", Version.VERSION);
-        writeToFile(directory + STYLE_SHEET_NAME, template.toString());
-    }
-
-    private void writeToFile(String fileName, String content)
-            throws IOException {
-        FileOutputStream fileOutputStream = new FileOutputStream(fileName);
-        fileOutputStream.write(content.getBytes());
-        fileOutputStream.flush();
-        fileOutputStream.close();
-    }
-}
diff --git a/tools/signature-tools/src/signature/io/html/IEmitter.java b/tools/signature-tools/src/signature/io/html/IEmitter.java
deleted file mode 100644
index db73e66..0000000
--- a/tools/signature-tools/src/signature/io/html/IEmitter.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.io.html;
-
-public interface IEmitter {
-    void writeTo(StringBuilder b);
-}
diff --git a/tools/signature-tools/src/signature/io/html/PackageByNameComparator.java b/tools/signature-tools/src/signature/io/html/PackageByNameComparator.java
deleted file mode 100644
index 3bbff71..0000000
--- a/tools/signature-tools/src/signature/io/html/PackageByNameComparator.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.io.html;
-
-import signature.compare.model.IPackageDelta;
-import signature.model.IPackage;
-
-import java.util.Comparator;
-
-public class PackageByNameComparator implements Comparator<IPackageDelta> {
-
-    public int compare(IPackageDelta a, IPackageDelta b) {
-        assert a.getType() == b.getType();
-        IPackage aPackage = null;
-        IPackage bPackage = null;
-
-        if (a.getFrom() != null) {
-            aPackage = a.getFrom();
-            bPackage = b.getFrom();
-        } else {
-            aPackage = a.getTo();
-            bPackage = b.getTo();
-        }
-        return aPackage.getName().compareTo(bPackage.getName());
-    }
-}
diff --git a/tools/signature-tools/src/signature/io/html/PackageOverviewPage.java b/tools/signature-tools/src/signature/io/html/PackageOverviewPage.java
deleted file mode 100644
index ccfe3cc..0000000
--- a/tools/signature-tools/src/signature/io/html/PackageOverviewPage.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.io.html;
-
-import org.antlr.stringtemplate.StringTemplate;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-import signature.compare.model.IClassDefinitionDelta;
-import signature.compare.model.IPackageDelta;
-import signature.compare.model.impl.SigDelta;
-
-public class PackageOverviewPage implements IEmitter {
-
-    private static final String PACGE = "PackageOverviewPage";
-
-    private final IPackageDelta delta;
-
-    private List<IClassDefinitionDelta> removedClasses;
-    private List<IClassDefinitionDelta> addedClasses;
-    private List<IClassDefinitionDelta> changedClasses;
-    private final Map<String, String> commonInfos;
-
-
-    public PackageOverviewPage(IPackageDelta delta,
-            Map<String, String> commonInfos) {
-        this.delta = delta;
-        this.commonInfos = commonInfos;
-        prepareData();
-    }
-
-    private void prepareData() {
-        removedClasses = new ArrayList<IClassDefinitionDelta>(SigDelta
-                .getRemoved(delta.getClassDeltas()));
-        Collections.sort(removedClasses, new ClassByNameComparator());
-
-        addedClasses = new ArrayList<IClassDefinitionDelta>(SigDelta
-                .getAdded(delta.getClassDeltas()));
-        Collections.sort(addedClasses, new ClassByNameComparator());
-
-        changedClasses = new ArrayList<IClassDefinitionDelta>(SigDelta
-                .getChanged(delta.getClassDeltas()));
-        Collections.sort(changedClasses, new ClassByNameComparator());
-    }
-
-    public void writeTo(StringBuilder b) {
-        StringTemplate template = TemplateStore.getStringTemplate(PACGE);
-        template.setArgumentContext(commonInfos);
-        template.setAttribute("package_delta", delta);
-        template.setAttribute("removed_classes", removedClasses);
-        template.setAttribute("added_classes", addedClasses);
-        template.setAttribute("changed_classes", changedClasses);
-        b.append(template.toString());
-    }
-
-
-
-}
diff --git a/tools/signature-tools/src/signature/io/html/TemplateStore.java b/tools/signature-tools/src/signature/io/html/TemplateStore.java
deleted file mode 100644
index a161bf7..0000000
--- a/tools/signature-tools/src/signature/io/html/TemplateStore.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.io.html;
-
-import java.io.InputStream;
-import java.io.InputStreamReader;
-
-import org.antlr.stringtemplate.StringTemplate;
-import org.antlr.stringtemplate.StringTemplateGroup;
-import org.antlr.stringtemplate.language.DefaultTemplateLexer;
-
-public class TemplateStore {
-
-    private static StringTemplateGroup group = initialize();
-
-
-    private static StringTemplateGroup initialize() {
-        InputStream modelStream = TemplateStore.class.getClassLoader()
-                .getResourceAsStream("model/model.stg");
-        InputStreamReader modelReader = new InputStreamReader(modelStream);
-        StringTemplateGroup modelGroup = new StringTemplateGroup(modelReader,
-                DefaultTemplateLexer.class);
-
-        InputStream stream = TemplateStore.class.getClassLoader()
-                .getResourceAsStream("delta/deltas.stg");
-        InputStreamReader reader = new InputStreamReader(stream);
-        StringTemplateGroup deltaGroup = new StringTemplateGroup(reader,
-                DefaultTemplateLexer.class);
-
-        StringTemplateGroup group = new StringTemplateGroup("signature", null,
-                DefaultTemplateLexer.class);
-        group.setSuperGroup(deltaGroup);
-
-        deltaGroup.setSuperGroup(modelGroup);
-        return group;
-    }
-
-    private TemplateStore() {/* no instances allowed */
-    }
-
-    public static StringTemplate getStringTemplate(String name) {
-        return group.getInstanceOf(name);
-    }
-}
diff --git a/tools/signature-tools/src/signature/io/impl/BinaryApi.java b/tools/signature-tools/src/signature/io/impl/BinaryApi.java
deleted file mode 100644
index f12cf6a7..0000000
--- a/tools/signature-tools/src/signature/io/impl/BinaryApi.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*

- * Copyright (C) 2009 The Android Open Source Project

- *

- * Licensed under the Apache License, Version 2.0 (the "License");

- * you may not use this file except in compliance with the License.

- * You may obtain a copy of the License at

- *

- *      http://www.apache.org/licenses/LICENSE-2.0

- *

- * Unless required by applicable law or agreed to in writing, software

- * distributed under the License is distributed on an "AS IS" BASIS,

- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

- * See the License for the specific language governing permissions and

- * limitations under the License.

- */

-

-package signature.io.impl;

-

-import signature.converter.Visibility;

-import signature.io.IApiExternalizer;

-import signature.io.IApiLoader;

-import signature.model.IApi;

-import java.io.File;

-import java.io.FileInputStream;

-import java.io.FileOutputStream;

-import java.io.IOException;

-import java.io.ObjectInputStream;

-import java.io.ObjectOutputStream;

-import java.util.Set;

-

-public class BinaryApi implements IApiExternalizer, IApiLoader {

-

-    public void externalizeApi(String fileName, IApi api) throws IOException {

-

-        File directory = new File(fileName);

-        if (!directory.exists()) {

-            directory.mkdirs();

-        }

-

-        File file = new File(directory, getFileName(api));

-        file.createNewFile();

-

-        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(

-                file));

-        oos.writeObject(api);

-

-        oos.flush();

-        oos.close();

-    }

-

-    private String getFileName(IApi api) {

-        return api.getName().replaceAll(" ", "_").concat(".sig");

-    }

-

-    public IApi loadApi(String name, Visibility visibility,

-            Set<String> fileNames, Set<String> packageNames) throws

-            IOException {

-        System.err

-                .println("Binary signature loader ignores visibility and " +

-                        "package names.");

-        if (fileNames.size() != 1) {

-            throw new IllegalArgumentException(

-                    "Only one file can be processed by the binary signature " +

-                    "loader.");

-        }

-        String fileName = fileNames.iterator().next();

-        File file = new File(fileName);

-        ObjectInputStream ois = new ObjectInputStream(

-                new FileInputStream(file));

-        IApi sig = null;

-        try {

-            sig = (IApi) ois.readObject();

-        } catch (ClassNotFoundException e) {

-            throw new IllegalArgumentException(e);

-        }

-        if (name != null) {

-            sig.setName(name);

-        }

-

-        ois.close();

-        return sig;

-    }

-}

diff --git a/tools/signature-tools/src/signature/io/impl/ToStringExternalizer.java b/tools/signature-tools/src/signature/io/impl/ToStringExternalizer.java
deleted file mode 100644
index 62615af..0000000
--- a/tools/signature-tools/src/signature/io/impl/ToStringExternalizer.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.io.impl;
-
-import signature.compare.model.IApiDelta;
-import signature.io.IApiDeltaExternalizer;
-
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStreamWriter;
-
-public class ToStringExternalizer implements IApiDeltaExternalizer {
-
-    public void externalize(String location, IApiDelta delta)
-            throws IOException {
-
-        OutputStreamWriter outputStreamWriter = new OutputStreamWriter(
-                new FileOutputStream(location));
-
-        if (delta == null) {
-            outputStreamWriter.write("No delta found!");
-        } else {
-            outputStreamWriter.write(delta.toString());
-        }
-        outputStreamWriter.close();
-    }
-}
diff --git a/tools/signature-tools/src/signature/model/IAnnotatableElement.java b/tools/signature-tools/src/signature/model/IAnnotatableElement.java
deleted file mode 100644
index 53d6c38..0000000
--- a/tools/signature-tools/src/signature/model/IAnnotatableElement.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.model;
-
-import java.util.Set;
-
-/**
- * Common interface for model elements which may be annotated. Annotations can
- * be attached to:
- * <ul>
- * <li>Classes (IClass), including annotations which are also classes
- * <li>Methods and Constructors (IExecutableMember)
- * <li>Fields (IField), including the annotation fields and enum constants
- * <li>Parameters (IParameter)
- * </ul>
- */
-public interface IAnnotatableElement {
-
-    /**
-     * Returns a set of annotations of a model element.
-     * 
-     * @return a set of annotations of a model element
-     */
-    Set<IAnnotation> getAnnotations();
-}
diff --git a/tools/signature-tools/src/signature/model/IAnnotation.java b/tools/signature-tools/src/signature/model/IAnnotation.java
deleted file mode 100644
index c31689d..0000000
--- a/tools/signature-tools/src/signature/model/IAnnotation.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.model;
-
-import java.util.Set;
-
-/**
- * {@code IAnnotation} models an <em>instance</em> of an annotation which is
- * attached to a program element. The definition of an annotation type is
- * modeled as an {@link IClassDefinition} with the {@link Kind#ANNOTATION}.
- */
-public interface IAnnotation {
-    /**
-     * Returns the annotation type of this annotation.
-     * 
-     * @return the annotation type of this annotation
-     */
-    IClassReference getType();
-
-    /**
-     * Returns the elements declared in this annotation. The values which are
-     * not declared are not contained in this list. Each element consists of its
-     * name and its value.
-     * 
-     * @return elements declared in this annotation
-     */
-    Set<IAnnotationElement> getElements();
-}
diff --git a/tools/signature-tools/src/signature/model/IAnnotationElement.java b/tools/signature-tools/src/signature/model/IAnnotationElement.java
deleted file mode 100644
index 5637fd6..0000000
--- a/tools/signature-tools/src/signature/model/IAnnotationElement.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.model;
-
-/**
- * {@code IAnnotationElement} models an annotation element which consist of a
- * name and a value.
- */
-public interface IAnnotationElement {
-    /**
-     * Returns the value of this annotation element. The type of this value is
-     * restricted to the possible value types for annotation elements.
-     * <p>
-     * The following types are possible:
-     * <ul>
-     * <li>a wrapper class for a primitive type
-     * <li>String (for String values)
-     * <li>IType (representing a class literal) FIXME Reference? Def?
-     * <li>IEnumConstant (representing an enum constant)
-     * <li>IAnnotation
-     * </ul>
-     * and (one-dimensional) arrays of the above types.
-     * 
-     * @return the value of this annotation element
-     */
-    Object getValue();
-
-    /**
-     * Returns the corresponding annotation field declaration. This declaration
-     * contains e.g. the name of this element, its type and its modifiers. The
-     * declaration also contains the default value of this element which is
-     * overwritten by this annotation element.
-     * 
-     * @return the corresponding annotation field declaration
-     */
-    IAnnotationField getDeclaringField();
-
-}
diff --git a/tools/signature-tools/src/signature/model/IAnnotationField.java b/tools/signature-tools/src/signature/model/IAnnotationField.java
deleted file mode 100644
index c40707f..0000000
--- a/tools/signature-tools/src/signature/model/IAnnotationField.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.model;
-
-/**
- * {@code IAnnotationField} models a field in a annotation definition. The
- * following example shows an annotation field <code>androField</code> of type
- * String and the default value "droid".
- * 
- * <pre>
- * 
- * @interface A { String androField() default "droid"; }
- * 
- *            </pre>
- */
-public interface IAnnotationField extends IField {
-
-    /**
-     * Returns the default value. If no default value is set then null is
-     * returned.
-     * 
-     * The type of the returned object is one of the following:
-     * <ul>
-     * <li>a wrapper class for a primitive type
-     * <li>String (for String values)
-     * <li>IType (representing a class literal)
-     * <li>IEnumConstant (representing an enum constant)
-     * <li>IAnnotation
-     * </ul>
-     * and (one-dimensional) arrays of the above types. If an array is returned,
-     * then the type of the result is Object[]. The elements of this array are
-     * of the above listed types.
-     */
-    Object getDefaultValue();
-}
diff --git a/tools/signature-tools/src/signature/model/IApi.java b/tools/signature-tools/src/signature/model/IApi.java
deleted file mode 100644
index de51938..0000000
--- a/tools/signature-tools/src/signature/model/IApi.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.model;
-
-import signature.converter.Visibility;
-
-import java.util.Set;
-
-/**
- * {@code IApi} models the root of an api.
- */
-public interface IApi {
-    /**
-     * Returns the name of this api.
-     * 
-     * @return the name of this api
-     */
-    String getName();
-
-    /**
-     * Sets the name of this api.
-     * 
-     * @param name
-     *            the name of this api
-     */
-    void setName(String name);
-
-    /**
-     * Returns the set of packages which constitute this api.
-     * 
-     * @return the set of packages which constitute this api
-     */
-    Set<IPackage> getPackages();
-
-    /**
-     * Returns the visibility of this api. The visibility describes which
-     * elements are visible. Only elements with a visibility greater or equal
-     * this visibility are contained in this api model.
-     * 
-     * @return the visibility of this api
-     * @see Visibility
-     */
-    Visibility getVisibility();
-}
diff --git a/tools/signature-tools/src/signature/model/IArrayType.java b/tools/signature-tools/src/signature/model/IArrayType.java
deleted file mode 100644
index bb63e67..0000000
--- a/tools/signature-tools/src/signature/model/IArrayType.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*

- * Copyright (C) 2009 The Android Open Source Project

- *

- * Licensed under the Apache License, Version 2.0 (the "License");

- * you may not use this file except in compliance with the License.

- * You may obtain a copy of the License at

- *

- *      http://www.apache.org/licenses/LICENSE-2.0

- *

- * Unless required by applicable law or agreed to in writing, software

- * distributed under the License is distributed on an "AS IS" BASIS,

- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

- * See the License for the specific language governing permissions and

- * limitations under the License.

- */

-

-package signature.model;

-

-/**

- * {@code IArrayType} models an array type.

- */

-public interface IArrayType extends ITypeReference {

-

-    /**

-     * Returns the component type of this array type.

-     * 

-     * @return component type of this array type

-     */

-    ITypeReference getComponentType();

-}

diff --git a/tools/signature-tools/src/signature/model/IClassDefinition.java b/tools/signature-tools/src/signature/model/IClassDefinition.java
deleted file mode 100644
index 1bd5401..0000000
--- a/tools/signature-tools/src/signature/model/IClassDefinition.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.model;
-
-import java.util.List;
-import java.util.Set;
-
-/**
- * {@code IClassDefinition} models a class definition. This is the model
- * equivalent to a class.
- */
-public interface IClassDefinition extends ITypeDefinition, IGenericDeclaration,
-        IAnnotatableElement {
-
-    /**
-     * Returns the kind of this class definition.
-     * 
-     * @return the kind of this class definition
-     */
-    Kind getKind();
-
-    /**
-     * Returns the name of this class definition.
-     * 
-     * @return the name of this class definition
-     */
-    String getName();
-
-    /**
-     * Returns the '.' separated package name of this class.
-     * 
-     * @return the '.' separated package name of this class
-     */
-    String getPackageName();
-
-    /**
-     * Returns a list containing each package fragment.
-     * <p>
-     * If {@link #getPackageName()} returns : "a.b.c" this method returns a list
-     * containing the three elements "a", "b", "c".
-     * <p>
-     * Note: this method exists only for convenience in output templating.
-     * 
-     * @return a list containing each package fragment
-     */
-    List<String> getPackageFragments();
-
-    /**
-     * Returns the qualified name of this class definition. The qualified name
-     * is composed of {@link #getPackageName()} '.' {@link #getName()}
-     * 
-     * @return the qualified name of this class definition
-     */
-    String getQualifiedName();
-
-    /**
-     * Returns the super class for this class definition. May return {@code
-     * null} if this class definition does not have any superclass. This is the
-     * case if the kind of this class definition is {@link Kind#INTERFACE} or
-     * this class definition is {@link Object}.
-     * 
-     * @return the super class for this class definition or {@code null}
-     */
-    ITypeReference getSuperClass();
-
-    /**
-     * Returns the declared interfaces this class definition implements . If no
-     * interfaces are declared, an empty set is returned.
-     * 
-     * @return the declared interfaces for this class definition
-     */
-    Set<ITypeReference> getInterfaces();
-
-    /**
-     * Returns the modifiers for this class definition.
-     * 
-     * @return the modifiers for this class definition
-     */
-    Set<Modifier> getModifiers();
-
-    /**
-     * Returns all declared methods of this class definition.
-     * 
-     * @return all declared methods of this class definition
-     */
-    Set<IMethod> getMethods();
-
-    /**
-     * Returns all declared constructors of this class definition.
-     * 
-     * @return all declared constructors of this class definition
-     */
-    Set<IConstructor> getConstructors();
-
-    /**
-     * Returns all declared fields of this class definition.
-     * 
-     * @return all declared fields of this class definition
-     */
-    Set<IField> getFields();
-
-    /**
-     * Returns all declared enumeration constant definitions of this class
-     * definition. The returned set may only contain elements if the kind of
-     * this class definition is {@link Kind#ENUM}.
-     * 
-     * @return all declared enumeration constants of this class definition
-     */
-    Set<IEnumConstant> getEnumConstants();
-
-    /**
-     * Returns all declared annotation field definitions of this class
-     * definition. The returned set may only contain elements if the kind of
-     * this class definition is {@link Kind#ANNOTATION}.
-     * 
-     * @return all declared annotation fields of this class definition
-     */
-    Set<IAnnotationField> getAnnotationFields();
-
-    /**
-     * Returns all classes which where defined in the lexical scope of this
-     * class definition. Anonymous classes are never returned.
-     * 
-     * @return all classes which where defined in the lexical scope of this
-     *         class definition
-     */
-    Set<IClassDefinition> getInnerClasses();
-}
diff --git a/tools/signature-tools/src/signature/model/IClassReference.java b/tools/signature-tools/src/signature/model/IClassReference.java
deleted file mode 100644
index bcb2c55..0000000
--- a/tools/signature-tools/src/signature/model/IClassReference.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.model;
-
-/**
- * {@code IClassReference} models a reference to an {@link IClassDefinition}. If
- * the referenced {@link IClassDefinition} defines
- * {@link ITypeVariableDefinition}s, this reference can be seen as a raw type.
- */
-public interface IClassReference extends ITypeReference {
-
-    /**
-     * Returns the definition this class reference is referencing.
-     * 
-     * @return the definition this class reference is referencing
-     */
-    IClassDefinition getClassDefinition();
-}
diff --git a/tools/signature-tools/src/signature/model/IConstructor.java b/tools/signature-tools/src/signature/model/IConstructor.java
deleted file mode 100644
index 29f5275..0000000
--- a/tools/signature-tools/src/signature/model/IConstructor.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.model;
-
-/**
- * {@code IConstructor} models a constructor.
- */
-public interface IConstructor extends IExecutableMember {
-}
diff --git a/tools/signature-tools/src/signature/model/IEnumConstant.java b/tools/signature-tools/src/signature/model/IEnumConstant.java
deleted file mode 100644
index 681e62b..0000000
--- a/tools/signature-tools/src/signature/model/IEnumConstant.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.model;
-
-/**
- * {@code IEnumConstant} models an enumeration constant.
- */
-public interface IEnumConstant extends IField {
-
-    /**
-     * Returns the ordinal of this enum constant.
-     * 
-     * @return the ordinal of this enum constant.
-     */
-    int getOrdinal();
-}
diff --git a/tools/signature-tools/src/signature/model/IExecutableMember.java b/tools/signature-tools/src/signature/model/IExecutableMember.java
deleted file mode 100644
index ef7f7ba..0000000
--- a/tools/signature-tools/src/signature/model/IExecutableMember.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.model;
-
-import java.util.List;
-import java.util.Set;
-
-/**
- * {@code IExecutableMember} is the common super interface for methods an
- * constructors.
- */
-public interface IExecutableMember extends IGenericDeclaration,
-        IAnnotatableElement {
-
-    /**
-     * Returns the name of this executable member.
-     * 
-     * @return the name of this executable member
-     */
-    String getName();
-
-    /**
-     * Returns the parameters of this executable member.
-     * 
-     * @return the parameters of this executable member
-     */
-    List<IParameter> getParameters();
-
-    /**
-     * Returns the declared exceptions of this executable member.
-     * 
-     * @return the declared exceptions of this executable member
-     */
-    Set<ITypeReference> getExceptions();
-
-    /**
-     * Returns the modifiers of this executable member.
-     * 
-     * @return the modifiers of this executable member
-     */
-    Set<Modifier> getModifiers();
-}
diff --git a/tools/signature-tools/src/signature/model/IField.java b/tools/signature-tools/src/signature/model/IField.java
deleted file mode 100644
index 3cf7593..0000000
--- a/tools/signature-tools/src/signature/model/IField.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.model;
-
-import java.util.Set;
-
-/**
- * {@code IField} models a field.
- */
-public interface IField extends IAnnotatableElement {
-
-    /**
-     * Returns the name of this field.
-     * 
-     * @return the name of this field
-     */
-    String getName();
-
-    /**
-     * Returns the type of this field.
-     * 
-     * @return the type of this field
-     */
-    ITypeReference getType();
-
-    /**
-     * Returns the modifiers of this field.
-     * 
-     * @return the modifiers of this field
-     */
-    Set<Modifier> getModifiers();
-}
diff --git a/tools/signature-tools/src/signature/model/IGenericDeclaration.java b/tools/signature-tools/src/signature/model/IGenericDeclaration.java
deleted file mode 100644
index d7f4683..0000000
--- a/tools/signature-tools/src/signature/model/IGenericDeclaration.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.model;
-
-import java.util.List;
-
-/**
- * {@code IGenericDeclaration} is the common base interface for elements which
- * can define type variables.
- */
-public interface IGenericDeclaration {
-
-    /**
-     * Returns a list of all defined type variables on this generic declaration.
-     * 
-     * @return a list of all defined type variables
-     */
-    List<ITypeVariableDefinition> getTypeParameters();
-
-    /**
-     * Returns the class definition which declares this element or {@code null}
-     * if this declaration is a top level class definition.
-     * 
-     * @return the class definition which declares this element or {@code null}
-     */
-    IClassDefinition getDeclaringClass();
-}
diff --git a/tools/signature-tools/src/signature/model/IMethod.java b/tools/signature-tools/src/signature/model/IMethod.java
deleted file mode 100644
index e205db1..0000000
--- a/tools/signature-tools/src/signature/model/IMethod.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.model;
-
-import signature.model.impl.SigPrimitiveType;
-
-/**
- * {@code IMethod} models a method.
- */
-public interface IMethod extends IExecutableMember {
-
-    /**
-     * Returns the return type of this method.
-     * <p>
-     * If the declared return type is {@code void}
-     * {@link SigPrimitiveType#VOID_TYPE} is returned.
-     * 
-     * @return the return type of this method
-     */
-    ITypeReference getReturnType();
-}
diff --git a/tools/signature-tools/src/signature/model/IPackage.java b/tools/signature-tools/src/signature/model/IPackage.java
deleted file mode 100644
index 78b14ce..0000000
--- a/tools/signature-tools/src/signature/model/IPackage.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.model;
-
-import java.util.List;
-import java.util.Set;
-
-/**
- * {@code IPackage} models a package.
- */
-public interface IPackage extends IAnnotatableElement {
-
-    /**
-     * Returns the name of this package.
-     * 
-     * @return the name of this package
-     */
-    String getName();
-
-    /**
-     * Returns a list containing each package fragment.
-     * <p>
-     * If {@link #getName()} returns : "a.b.c" this method returns a list
-     * containing the three elements "a", "b", "c".
-     * <p>
-     * Note: this method exists only for convenience in output templating.
-     * 
-     * @return a list containing each package fragment
-     */
-    List<String> getPackageFragments();
-
-    /**
-     * Returns all classes declared in this package, including ordinary classes,
-     * interfaces, enum types and annotation types. Nested classes are returned
-     * as well.
-     * 
-     * @return all classes declared in this package
-     */
-    Set<IClassDefinition> getClasses();
-}
diff --git a/tools/signature-tools/src/signature/model/IParameter.java b/tools/signature-tools/src/signature/model/IParameter.java
deleted file mode 100644
index bd359d5..0000000
--- a/tools/signature-tools/src/signature/model/IParameter.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.model;
-
-/**
- * {@code IParameter} models a parameter of an {@link IExecutableMember}.
- */
-public interface IParameter extends IAnnotatableElement {
-
-    /**
-     * Returns the type of this parameter.
-     * 
-     * @return the type of this parameter
-     */
-    ITypeReference getType();
-}
diff --git a/tools/signature-tools/src/signature/model/IParameterizedType.java b/tools/signature-tools/src/signature/model/IParameterizedType.java
deleted file mode 100644
index 59f5692..0000000
--- a/tools/signature-tools/src/signature/model/IParameterizedType.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.model;
-
-import java.util.List;
-
-/**
- * {@code IParameterizedType} models a parameterized type. A parameterized type
- * instantiates a generic class definition with actual type arguments.
- * 
- * <pre>
- * IClassDefinition:
- * public class A<T> {}
- *
- * public class XXX {
- * IParameterizedType (raw type: A , type arguments: Number)
- *   public A<Number> fields;
- * }
- * </pre>
- */
-public interface IParameterizedType extends ITypeReference {
-
-    /**
-     * Returns the actual type arguments of this parameterized type.
-     * 
-     * @return the actual type arguments of this parameterized type
-     */
-    List<ITypeReference> getTypeArguments();
-
-    /**
-     * Returns the raw type of this parameterized type.
-     * 
-     * @return the raw type of this parameterized type
-     */
-    IClassReference getRawType();
-
-    /**
-     * Returns the owner type of this parameterized type or {@code null}.
-     * 
-     * <pre>
-     * class Y&lt;T&gt; {
-     *     class Z&lt;S&gt; {
-     *     }
-     *
-     *     Y&lt;Integer&gt;.Z&lt;String&gt; a;
-     * }
-     * </pre>
-     */
-    ITypeReference getOwnerType(); // A.B<String> -> A
-}
diff --git a/tools/signature-tools/src/signature/model/IPrimitiveType.java b/tools/signature-tools/src/signature/model/IPrimitiveType.java
deleted file mode 100644
index 917b96b..0000000
--- a/tools/signature-tools/src/signature/model/IPrimitiveType.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.model;
-
-/**
- * {@code IPrimitiveType} models a primitive type.
- */
-public interface IPrimitiveType extends ITypeReference {
-
-    /**
-     * Returns the name of this primitive type, i.e. one of the following
-     * strings:
-     * <ul>
-     * <li><code>boolean</code>
-     * <li><code>byte</code>
-     * <li><code>char</code>
-     * <li><code>short</code>
-     * <li><code>int</code>
-     * <li><code>float</code>
-     * <li><code>double</code>
-     * <li><code>void</code>
-     * </ul>
-     * 
-     * @return the name of this primitive type
-     */
-    public String getName();
-}
diff --git a/tools/signature-tools/src/signature/model/ITypeDefinition.java b/tools/signature-tools/src/signature/model/ITypeDefinition.java
deleted file mode 100644
index b182f21..0000000
--- a/tools/signature-tools/src/signature/model/ITypeDefinition.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.model;
-
-/**
- * {@code ITypeDefinition} is the common interface for type definitions. A type
- * definition is either an {@link ITypeVariableDefinition} or an
- * {@link IClassDefinition}.
- */
-public interface ITypeDefinition {
-}
diff --git a/tools/signature-tools/src/signature/model/ITypeReference.java b/tools/signature-tools/src/signature/model/ITypeReference.java
deleted file mode 100644
index f17f172..0000000
--- a/tools/signature-tools/src/signature/model/ITypeReference.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.model;
-
-/**
- * {@code ITypeReference} is the common interface for type references.
- */
-public interface ITypeReference {
-}
diff --git a/tools/signature-tools/src/signature/model/ITypeVariableDefinition.java b/tools/signature-tools/src/signature/model/ITypeVariableDefinition.java
deleted file mode 100644
index df0ead0..0000000
--- a/tools/signature-tools/src/signature/model/ITypeVariableDefinition.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.model;
-
-import java.util.List;
-
-/**
- * {@code ITypeVariableDefinition} models a type variable definition.
- */
-public interface ITypeVariableDefinition extends ITypeDefinition {
-
-    /**
-     * Returns the upper bounds for this type variable as specified by the
-     * extends clause. If no upper bounds are explicitly specified then
-     * java.lang.Object is returned as upper bound.
-     * 
-     * @return the upper bounds for this type variable
-     */
-    List<ITypeReference> getUpperBounds();
-
-    /**
-     * Returns the name of this type variable.
-     * 
-     * @return the name of this type variable
-     */
-    String getName();
-
-    /**
-     * Returns the element on which this type variable is declared.
-     * 
-     * @return the element on which this type variable is declared
-     */
-    IGenericDeclaration getGenericDeclaration();
-}
diff --git a/tools/signature-tools/src/signature/model/ITypeVariableReference.java b/tools/signature-tools/src/signature/model/ITypeVariableReference.java
deleted file mode 100644
index 64e0657..0000000
--- a/tools/signature-tools/src/signature/model/ITypeVariableReference.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.model;
-
-/**
- * {@code ITypeVariableReference} models a reference to an
- * {@link ITypeVariableDefinition}.
- */
-public interface ITypeVariableReference extends ITypeReference {
-
-    /**
-     * Returns the definition this type variable reference is referencing.
-     * 
-     * @return the definition this type variable reference is referencing
-     */
-    ITypeVariableDefinition getTypeVariableDefinition();
-}
diff --git a/tools/signature-tools/src/signature/model/IWildcardType.java b/tools/signature-tools/src/signature/model/IWildcardType.java
deleted file mode 100644
index 02a0d2d..0000000
--- a/tools/signature-tools/src/signature/model/IWildcardType.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.model;
-
-import java.util.List;
-
-/**
- * {@code IWildcardType} models a wildcard type.
- */
-public interface IWildcardType extends ITypeReference {
-
-    /**
-     * Returns the upper bounds for this type variable as specified by the
-     * extends clause. If no upper bounds are explicitly specified then
-     * java.lang.Object is returned as upper bound.
-     * 
-     * @return the upper bounds for this type variable
-     */
-    List<ITypeReference> getUpperBounds();
-
-    /**
-     * Returns the lower bounds for this type variable as specified by the super
-     * clause. If no lower bounds are explicitly specified then null is returned
-     * as lower bound.
-     * 
-     * @return the lower bounds for this type variable
-     */
-    ITypeReference getLowerBound();
-
-}
diff --git a/tools/signature-tools/src/signature/model/Kind.java b/tools/signature-tools/src/signature/model/Kind.java
deleted file mode 100644
index 219e039..0000000
--- a/tools/signature-tools/src/signature/model/Kind.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.model;
-
-/**
- * Type of the modeled class.
- */
-public enum Kind {
-    CLASS("class"), INTERFACE("interface"), ANNOTATION("@interface"), ENUM(
-            "enum"), UNINITIALIZED("UNINITIALIZED");
-
-    private final String name;
-
-    Kind(String name) {
-        this.name = name;
-    }
-
-    @Override
-    public String toString() {
-        return name;
-    }
-}
diff --git a/tools/signature-tools/src/signature/model/Modifier.java b/tools/signature-tools/src/signature/model/Modifier.java
deleted file mode 100644
index 223e88f..0000000
--- a/tools/signature-tools/src/signature/model/Modifier.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.model;
-
-import java.util.Set;
-
-/**
- * {@class Modifier} models a modifer.
- */
-public enum Modifier {
-    PUBLIC("public"), PRIVATE("private"), PROTECTED("protected"), STATIC(
-            "static"), FINAL("final"), SYNCHRONIZED("synchronized"), VOLATILE(
-            "volatile"), TRANSIENT("transient"), NATIVE("native"), ABSTRACT(
-            "abstract"), STRICT("strict");
-
-    private final String printableName;
-
-    private Modifier(String printableName) {
-        this.printableName = printableName;
-    }
-
-    @Override
-    public String toString() {
-        return printableName;
-    }
-
-    public static String toString(Set<Modifier> modifiers) {
-        StringBuilder s = new StringBuilder();
-
-        for (Modifier modifier : values()) {
-            if (modifiers.contains(modifier)) {
-                s.append(modifier.printableName);
-                s.append(" ");
-            }
-        }
-
-        return s.toString();
-    }
-}
diff --git a/tools/signature-tools/src/signature/model/impl/SigAnnotatableElement.java b/tools/signature-tools/src/signature/model/impl/SigAnnotatableElement.java
deleted file mode 100644
index 53f021e..0000000
--- a/tools/signature-tools/src/signature/model/impl/SigAnnotatableElement.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.model.impl;
-
-import java.io.Serializable;
-import java.util.Collections;
-import java.util.Set;
-
-import signature.model.IAnnotatableElement;
-import signature.model.IAnnotation;
-
-@SuppressWarnings("serial")
-public abstract class SigAnnotatableElement implements IAnnotatableElement,
-        Serializable {
-    private Set<IAnnotation> annotations;
-
-    public SigAnnotatableElement() {
-        annotations = Collections.emptySet();
-    }
-
-    public Set<IAnnotation> getAnnotations() {
-        return annotations;
-    }
-
-    public void setAnnotations(Set<IAnnotation> annotations) {
-        this.annotations = annotations;
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder builder = new StringBuilder();
-        for (IAnnotation annotation : getAnnotations()) {
-            builder.append(annotation);
-        }
-        return builder.toString();
-    }
-}
diff --git a/tools/signature-tools/src/signature/model/impl/SigAnnotation.java b/tools/signature-tools/src/signature/model/impl/SigAnnotation.java
deleted file mode 100644
index b7d0354..0000000
--- a/tools/signature-tools/src/signature/model/impl/SigAnnotation.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.model.impl;
-
-import signature.model.IAnnotation;
-import signature.model.IAnnotationElement;
-import signature.model.IClassReference;
-
-import java.io.Serializable;
-import java.util.Collections;
-import java.util.Set;
-
-@SuppressWarnings("serial")
-public class SigAnnotation implements IAnnotation, Serializable {
-
-    private Set<IAnnotationElement> elements;
-    private IClassReference type;
-
-    public SigAnnotation() {
-        elements = Collections.emptySet();
-    }
-
-    public IClassReference getType() {
-        return type;
-    }
-
-    public void setType(IClassReference type) {
-        this.type = type;
-    }
-
-    public Set<IAnnotationElement> getElements() {
-        return elements;
-    }
-
-    public void setElements(Set<IAnnotationElement> elements) {
-        this.elements = elements;
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder builder = new StringBuilder();
-        builder.append("@");
-        builder.append(getType());
-        if (!getElements().isEmpty()) {
-            builder.append("{");
-            for (IAnnotationElement element : getElements()) {
-                builder.append("\n");
-                builder.append(element.toString());
-            }
-            builder.append("}");
-        }
-        return builder.toString();
-    }
-}
diff --git a/tools/signature-tools/src/signature/model/impl/SigAnnotationElement.java b/tools/signature-tools/src/signature/model/impl/SigAnnotationElement.java
deleted file mode 100644
index 3d676a7..0000000
--- a/tools/signature-tools/src/signature/model/impl/SigAnnotationElement.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.model.impl;
-
-import java.io.Serializable;
-
-import signature.model.IAnnotationElement;
-import signature.model.IAnnotationField;
-
-@SuppressWarnings("serial")
-public class SigAnnotationElement implements IAnnotationElement, Serializable {
-
-    private IAnnotationField declaringField;
-    private Object value;
-
-    public IAnnotationField getDeclaringField() {
-        return declaringField;
-    }
-
-    public void setDeclaringField(IAnnotationField declaringField) {
-        this.declaringField = declaringField;
-    }
-
-    public Object getValue() {
-        return value;
-    }
-
-    public void setValue(Object value) {
-        this.value = value;
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder builder = new StringBuilder();
-        builder.append(getDeclaringField().getName());
-        builder.append(" = ");
-        builder.append(getValue());
-        return builder.toString();
-    }
-}
diff --git a/tools/signature-tools/src/signature/model/impl/SigAnnotationField.java b/tools/signature-tools/src/signature/model/impl/SigAnnotationField.java
deleted file mode 100644
index 5dd6faf..0000000
--- a/tools/signature-tools/src/signature/model/impl/SigAnnotationField.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.model.impl;
-
-import java.io.Serializable;
-
-import signature.model.IAnnotationField;
-
-@SuppressWarnings("serial")
-public class SigAnnotationField extends SigField implements IAnnotationField,
-        Serializable {
-
-    private Object defaultValue = Uninitialized.unset();
-
-    public SigAnnotationField(String name) {
-        super(name);
-    }
-
-    public Object getDefaultValue() {
-        return defaultValue;
-    }
-
-    public void setDefaultValue(Object defaultValue) {
-        this.defaultValue = defaultValue;
-    }
-}
diff --git a/tools/signature-tools/src/signature/model/impl/SigApi.java b/tools/signature-tools/src/signature/model/impl/SigApi.java
deleted file mode 100644
index b573f8f..0000000
--- a/tools/signature-tools/src/signature/model/impl/SigApi.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.model.impl;
-
-import java.io.Serializable;
-import java.util.Set;
-
-import signature.converter.Visibility;
-import signature.model.IApi;
-import signature.model.IPackage;
-
-@SuppressWarnings("serial")
-public class SigApi implements IApi, Serializable {
-
-    private Set<IPackage> packages = Uninitialized.unset();
-    private String description;
-    private Visibility visibility;
-
-    public SigApi(String description, Visibility visibility) {
-        this.description = description;
-        this.visibility = visibility;
-    }
-
-    public String getName() {
-        return description;
-    }
-
-    public void setName(String description) {
-        this.description = description;
-    }
-
-    public Set<IPackage> getPackages() {
-        return packages;
-    }
-
-    public void setPackages(Set<IPackage> packages) {
-        this.packages = packages;
-    }
-
-    public Visibility getVisibility() {
-        return visibility;
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder builder = new StringBuilder();
-        builder.append(getName());
-        return builder.toString();
-    }
-}
diff --git a/tools/signature-tools/src/signature/model/impl/SigArrayType.java b/tools/signature-tools/src/signature/model/impl/SigArrayType.java
deleted file mode 100644
index 3d20824e..0000000
--- a/tools/signature-tools/src/signature/model/impl/SigArrayType.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*

- * Copyright (C) 2009 The Android Open Source Project

- *

- * Licensed under the Apache License, Version 2.0 (the "License");

- * you may not use this file except in compliance with the License.

- * You may obtain a copy of the License at

- *

- *      http://www.apache.org/licenses/LICENSE-2.0

- *

- * Unless required by applicable law or agreed to in writing, software

- * distributed under the License is distributed on an "AS IS" BASIS,

- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

- * See the License for the specific language governing permissions and

- * limitations under the License.

- */

-

-package signature.model.impl;

-

-import java.io.Serializable;

-

-import signature.model.IArrayType;

-import signature.model.ITypeReference;

-

-@SuppressWarnings("serial")

-public class SigArrayType implements IArrayType, Serializable {

-    private ITypeReference componentType;

-

-    public SigArrayType(ITypeReference componentType) {

-        this.componentType = componentType;

-    }

-

-    public ITypeReference getComponentType() {

-        return componentType;

-    }

-

-    @Override

-    public int hashCode() {

-        return SigArrayType.hashCode(this);

-    }

-

-    public static int hashCode(IArrayType type) {

-        return type.getComponentType().hashCode();

-    }

-

-    @Override

-    public boolean equals(Object obj) {

-        return SigArrayType.equals(this, obj);

-    }

-

-    public static boolean equals(IArrayType thiz, Object that) {

-        if (!(that instanceof IArrayType)) {

-            return false;

-        }

-        IArrayType other = (IArrayType) that;

-        return thiz.getComponentType().equals(other.getComponentType());

-    }

-

-    @Override

-    public String toString() {

-        return SigArrayType.toString(this);

-    }

-

-    public static String toString(IArrayType type) {

-        StringBuilder builder = new StringBuilder();

-        builder.append(type.getComponentType().toString());

-        builder.append("[]");

-        return builder.toString();

-    }

-}

diff --git a/tools/signature-tools/src/signature/model/impl/SigClassDefinition.java b/tools/signature-tools/src/signature/model/impl/SigClassDefinition.java
deleted file mode 100644
index fe7c7ab..0000000
--- a/tools/signature-tools/src/signature/model/impl/SigClassDefinition.java
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.model.impl;
-
-import java.io.Serializable;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Set;
-
-import signature.model.IAnnotationField;
-import signature.model.IClassDefinition;
-import signature.model.IConstructor;
-import signature.model.IEnumConstant;
-import signature.model.IField;
-import signature.model.IMethod;
-import signature.model.ITypeReference;
-import signature.model.ITypeVariableDefinition;
-import signature.model.Kind;
-import signature.model.Modifier;
-import signature.model.util.ModelUtil;
-
-@SuppressWarnings("serial")
-public class SigClassDefinition extends SigAnnotatableElement implements
-        IClassDefinition, Serializable {
-
-    private String name;
-    private Kind kind = Kind.UNINITIALIZED;
-    private ITypeReference superClass = Uninitialized.unset();
-    private Set<ITypeReference> interfaces = Uninitialized.unset();
-    private Set<Modifier> modifiers = Uninitialized.unset();
-    private Set<IMethod> methods = Uninitialized.unset();
-    private Set<IConstructor> constructors = Uninitialized.unset();
-    private Set<IClassDefinition> innerClasses = Uninitialized.unset();
-    private Set<IAnnotationField> annotationFields = Uninitialized.unset();
-    private Set<IField> fields = Uninitialized.unset();
-    private Set<IEnumConstant> enumConstants = Uninitialized.unset();
-    private IClassDefinition declaringClass = Uninitialized.unset();
-    private List<ITypeVariableDefinition> typeParameters = Uninitialized
-            .unset();
-    private String packageName;
-
-    public SigClassDefinition(String packageName, String name) {
-        this.packageName = packageName;
-        this.name = name;
-    }
-
-    public Kind getKind() {
-        return kind;
-    }
-
-    public void setKind(Kind kind) {
-        this.kind = kind;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public String getPackageName() {
-        return packageName;
-    }
-
-    public List<String> getPackageFragments() {
-        return Arrays.asList(packageName.split("\\."));
-    }
-
-    public String getQualifiedName() {
-        return packageName + "." + name;
-    }
-
-    public Set<Modifier> getModifiers() {
-        return modifiers;
-    }
-
-    public void setModifiers(Set<Modifier> modifiers) {
-        this.modifiers = modifiers;
-    }
-
-    public Set<IClassDefinition> getInnerClasses() {
-        return innerClasses;
-    }
-
-    public void setInnerClasses(Set<IClassDefinition> innerClasses) {
-        this.innerClasses = innerClasses;
-    }
-
-    public Set<ITypeReference> getInterfaces() {
-        return interfaces;
-    }
-
-    public void setInterfaces(Set<ITypeReference> interfaces) {
-        this.interfaces = interfaces;
-    }
-
-    public Set<IMethod> getMethods() {
-        return methods;
-    }
-
-    public void setMethods(Set<IMethod> methods) {
-        this.methods = methods;
-    }
-
-    public Set<IConstructor> getConstructors() {
-        return constructors;
-    }
-
-    public void setConstructors(Set<IConstructor> constructors) {
-        this.constructors = constructors;
-    }
-
-    public ITypeReference getSuperClass() {
-        return superClass;
-    }
-
-    public void setSuperClass(ITypeReference superClass) {
-        this.superClass = superClass;
-    }
-
-    public IClassDefinition getDeclaringClass() {
-        return declaringClass;
-    }
-
-    public void setDeclaringClass(IClassDefinition declaringClass) {
-        this.declaringClass = declaringClass;
-    }
-
-    public Set<IAnnotationField> getAnnotationFields() {
-        return annotationFields;
-    }
-
-    public void setAnnotationFields(Set<IAnnotationField> annotationFields) {
-        this.annotationFields = annotationFields;
-    }
-
-    public Set<IField> getFields() {
-        return fields;
-    }
-
-    public void setFields(Set<IField> fields) {
-        this.fields = fields;
-    }
-
-    public Set<IEnumConstant> getEnumConstants() {
-        return enumConstants;
-    }
-
-    public void setEnumConstants(Set<IEnumConstant> enumConstants) {
-        this.enumConstants = enumConstants;
-    }
-
-    public List<ITypeVariableDefinition> getTypeParameters() {
-        return typeParameters;
-    }
-
-    public void setTypeParameters(
-            List<ITypeVariableDefinition> typeParameters) {
-        this.typeParameters = typeParameters;
-    }
-
-    @Override
-    public int hashCode() {
-        return SigClassDefinition.hashCode(this);
-    }
-
-    public static int hashCode(IClassDefinition definition) {
-        // FIXME find out why name and packageName are null during
-        // de-serialization some cases
-        // replace the following lines with:
-        // return definition.getQualifiedName().hashCode();
-        final int prime = 31;
-        int result = 1;
-        result = prime
-                + ((definition.getName() == null) ? 0 : definition.getName()
-                        .hashCode());
-        result = prime
-                * result
-                + ((definition.getPackageName() == null) ? 0 : definition
-                        .getPackageName().hashCode());
-        return result;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        return SigClassDefinition.equals(this, obj);
-    }
-
-    public static boolean equals(IClassDefinition thiz, Object obj) {
-        if (thiz == obj) return true;
-        if (obj instanceof IClassDefinition) {
-            IClassDefinition that = (IClassDefinition) obj;
-            return thiz.getName().equals(that.getName())
-                    && thiz.getPackageName().equals(that.getPackageName());
-        }
-        return false;
-    }
-
-    @Override
-    public String toString() {
-        return SigClassDefinition.toString(this);
-    }
-
-    public static String toString(IClassDefinition type) {
-        StringBuilder builder = new StringBuilder();
-        if (type.getAnnotations() != null && !type.getAnnotations().isEmpty()) {
-            // FIXME print annotations builder.append(super.toString());
-            builder.append("\n");
-        }
-        builder.append(type.getQualifiedName());
-        if (type.getTypeParameters() != null
-                && (!type.getTypeParameters().isEmpty())) {
-            builder.append("<");
-            ModelUtil.separate(type.getTypeParameters(), ", ");
-            builder.append(">");
-        }
-        return builder.toString();
-    }
-}
diff --git a/tools/signature-tools/src/signature/model/impl/SigClassReference.java b/tools/signature-tools/src/signature/model/impl/SigClassReference.java
deleted file mode 100644
index d4336de..0000000
--- a/tools/signature-tools/src/signature/model/impl/SigClassReference.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.model.impl;
-
-import signature.model.IClassDefinition;
-import signature.model.IClassReference;
-
-import java.io.Serializable;
-
-@SuppressWarnings("serial")
-public class SigClassReference implements IClassReference, Serializable {
-
-    private final IClassDefinition definition;
-
-    public SigClassReference(IClassDefinition definition) {
-        this.definition = definition;
-    }
-
-    public IClassDefinition getClassDefinition() {
-        return definition;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        return SigClassReference.equals(this, obj);
-    }
-
-    public static boolean equals(IClassReference thiz, Object that) {
-        if (that instanceof IClassReference) {
-            return thiz.getClassDefinition().equals(
-                    ((IClassReference) that).getClassDefinition());
-        }
-        return false;
-    }
-
-    @Override
-    public int hashCode() {
-        return SigClassReference.hashCode(this);
-    }
-
-    public static int hashCode(IClassReference thiz) {
-        return thiz.getClassDefinition().hashCode();
-    }
-
-    @Override
-    public String toString() {
-        return SigClassReference.toString(this);
-    }
-
-    public static String toString(IClassReference thiz) {
-        return "-> " + thiz.getClassDefinition().getQualifiedName();
-    }
-}
diff --git a/tools/signature-tools/src/signature/model/impl/SigConstructor.java b/tools/signature-tools/src/signature/model/impl/SigConstructor.java
deleted file mode 100644
index 1da3026..0000000
--- a/tools/signature-tools/src/signature/model/impl/SigConstructor.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.model.impl;
-
-import java.io.Serializable;
-
-import signature.model.IConstructor;
-import signature.model.Modifier;
-import signature.model.util.ModelUtil;
-
-@SuppressWarnings("serial")
-public class SigConstructor extends SigExecutableMember implements
-        IConstructor, Serializable {
-
-    public SigConstructor(String name) {
-        super(name);
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder builder = new StringBuilder();
-        builder.append(super.toString());
-        builder.append(" ");
-        builder.append(Modifier.toString(getModifiers()));
-        if (getTypeParameters() != null && !getTypeParameters().isEmpty()) {
-            builder.append("<");
-            builder.append(ModelUtil.separate(getTypeParameters(), ", "));
-            builder.append("> ");
-        }
-        builder.append(getName());
-        builder.append("(");
-        builder.append(getParameters().isEmpty() ? "" : ModelUtil.separate(
-                getParameters(), ", "));
-        builder.append(")");
-        if (getExceptions() != null && !getExceptions().isEmpty()) {
-            builder.append(" throws ");
-            builder.append(ModelUtil.separate(getExceptions(), " "));
-        }
-        return builder.toString();
-    }
-}
diff --git a/tools/signature-tools/src/signature/model/impl/SigEnumConstant.java b/tools/signature-tools/src/signature/model/impl/SigEnumConstant.java
deleted file mode 100644
index 2878988..0000000
--- a/tools/signature-tools/src/signature/model/impl/SigEnumConstant.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.model.impl;
-
-import signature.model.IEnumConstant;
-
-@SuppressWarnings("serial")
-public class SigEnumConstant extends SigField implements IEnumConstant {
-
-    private static final int UNKNOWN = -1;
-
-    private int ordinal = UNKNOWN;
-
-    public SigEnumConstant(String name) {
-        super(name);
-    }
-
-    public int getOrdinal() {
-        if (ordinal == UNKNOWN) {
-            throw new UnsupportedOperationException();
-        }
-        return ordinal;
-    }
-
-    public void setOrdinal(int ordinal) {
-        this.ordinal = ordinal;
-    }
-}
diff --git a/tools/signature-tools/src/signature/model/impl/SigExecutableMember.java b/tools/signature-tools/src/signature/model/impl/SigExecutableMember.java
deleted file mode 100644
index 3203d59..0000000
--- a/tools/signature-tools/src/signature/model/impl/SigExecutableMember.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.model.impl;
-
-import signature.model.IClassDefinition;
-import signature.model.IExecutableMember;
-import signature.model.IParameter;
-import signature.model.ITypeReference;
-import signature.model.ITypeVariableDefinition;
-import signature.model.Modifier;
-
-import java.io.Serializable;
-import java.util.List;
-import java.util.Set;
-
-@SuppressWarnings("serial")
-public abstract class SigExecutableMember extends SigAnnotatableElement
-        implements IExecutableMember, Serializable {
-
-    private String name;
-    private List<IParameter> parameters = Uninitialized.unset();
-    private Set<ITypeReference> exceptions = Uninitialized.unset();
-    private Set<Modifier> modifiers = Uninitialized.unset();
-    private List<ITypeVariableDefinition> typeParameters = Uninitialized
-            .unset();
-    private IClassDefinition declaringClass = Uninitialized.unset();
-
-    public SigExecutableMember(String name) {
-        this.name = name;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public List<IParameter> getParameters() {
-        return parameters;
-    }
-
-    public void setParameters(List<IParameter> parameters) {
-        this.parameters = parameters;
-    }
-
-    public Set<ITypeReference> getExceptions() {
-        return exceptions;
-    }
-
-    public void setExceptions(Set<ITypeReference> exceptions) {
-        this.exceptions = exceptions;
-    }
-
-    public Set<Modifier> getModifiers() {
-        return modifiers;
-    }
-
-    public void setModifiers(Set<Modifier> modifiers) {
-        this.modifiers = modifiers;
-    }
-
-    public List<ITypeVariableDefinition> getTypeParameters() {
-        return typeParameters;
-    }
-
-    public void setTypeParameters(
-            List<ITypeVariableDefinition> typeParameters) {
-        this.typeParameters = typeParameters;
-    }
-
-    public IClassDefinition getDeclaringClass() {
-        return declaringClass;
-    }
-
-    public void setDeclaringClass(IClassDefinition declaringClass) {
-        this.declaringClass = declaringClass;
-    }
-}
diff --git a/tools/signature-tools/src/signature/model/impl/SigField.java b/tools/signature-tools/src/signature/model/impl/SigField.java
deleted file mode 100644
index e305566..0000000
--- a/tools/signature-tools/src/signature/model/impl/SigField.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.model.impl;
-
-import signature.model.IField;
-import signature.model.ITypeReference;
-import signature.model.Modifier;
-
-import java.io.Serializable;
-import java.util.Collections;
-import java.util.Set;
-
-@SuppressWarnings("serial")
-public class SigField extends SigAnnotatableElement implements IField,
-        Serializable {
-
-    private String name;
-    private ITypeReference type = Uninitialized.unset();
-    private Set<Modifier> modifiers = Uninitialized.unset();
-
-    public SigField(String name) {
-        this.name = name;
-        modifiers = Collections.emptySet();
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public Set<Modifier> getModifiers() {
-        return modifiers;
-    }
-
-    public void setModifiers(Set<Modifier> modifiers) {
-        this.modifiers = modifiers;
-    }
-
-    public ITypeReference getType() {
-        return type;
-    }
-
-    public void setType(ITypeReference type) {
-        this.type = type;
-    }
-
-
-    @Override
-    public String toString() {
-        StringBuilder builder = new StringBuilder();
-        if (getAnnotations() != null && !getAnnotations().isEmpty()) {
-            builder.append(super.toString());
-            builder.append("\n");
-        }
-        builder.append(Modifier.toString(getModifiers()));
-        builder.append(getType().toString());
-        builder.append(" ");
-        builder.append(getName());
-        return builder.toString();
-    }
-}
diff --git a/tools/signature-tools/src/signature/model/impl/SigMethod.java b/tools/signature-tools/src/signature/model/impl/SigMethod.java
deleted file mode 100644
index 489397f..0000000
--- a/tools/signature-tools/src/signature/model/impl/SigMethod.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.model.impl;
-
-import java.io.Serializable;
-
-import signature.model.IMethod;
-import signature.model.ITypeReference;
-import signature.model.Modifier;
-import signature.model.util.ModelUtil;
-
-@SuppressWarnings("serial")
-public class SigMethod extends SigExecutableMember implements IMethod,
-        Serializable {
-
-    private ITypeReference returnType = Uninitialized.unset();
-
-    public SigMethod(String name) {
-        super(name);
-    }
-
-
-    public ITypeReference getReturnType() {
-        return returnType;
-    }
-
-    public void setReturnType(ITypeReference returnType) {
-        this.returnType = returnType;
-    }
-
-    @Override
-    public String toString() {
-        return SigMethod.toString(this);
-    }
-
-    public static String toString(IMethod method) {
-        StringBuilder builder = new StringBuilder();
-        builder.append(Modifier.toString(method.getModifiers()));
-        builder.append(method.getReturnType());
-        builder.append(" ");
-        if (method.getTypeParameters() != null
-                && !method.getTypeParameters().isEmpty()) {
-            builder.append("<");
-            builder
-                    .append(ModelUtil
-                            .separate(method.getTypeParameters(), ", "));
-            builder.append("> ");
-        }
-        builder.append(method.getName());
-        builder.append("(");
-        builder.append(method.getParameters().isEmpty() ? "" : ModelUtil
-                .separate(method.getParameters(), ", "));
-        builder.append(")");
-        if (method.getExceptions() != null
-                && !method.getExceptions().isEmpty()) {
-            builder.append(" throws ");
-            builder.append(ModelUtil.separate(method.getExceptions(), " "));
-        }
-        return builder.toString();
-    }
-}
diff --git a/tools/signature-tools/src/signature/model/impl/SigPackage.java b/tools/signature-tools/src/signature/model/impl/SigPackage.java
deleted file mode 100644
index 686917c..0000000
--- a/tools/signature-tools/src/signature/model/impl/SigPackage.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.model.impl;
-
-import signature.model.IClassDefinition;
-import signature.model.IPackage;
-
-import java.io.Serializable;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Set;
-
-@SuppressWarnings("serial")
-public class SigPackage extends SigAnnotatableElement implements IPackage,
-        Serializable {
-
-    private String name;
-    private Set<IClassDefinition> classes = Uninitialized.unset();
-
-    public SigPackage(String name) {
-        this.name = name;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public List<String> getPackageFragments() {
-        return Arrays.asList(name.split("\\."));
-    }
-
-    public Set<IClassDefinition> getClasses() {
-        return classes;
-    }
-
-    public void setClasses(Set<IClassDefinition> classes) {
-        this.classes = classes;
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder builder = new StringBuilder();
-        builder.append("package: ");
-        builder.append(getName());
-        return builder.toString();
-    }
-}
diff --git a/tools/signature-tools/src/signature/model/impl/SigParameter.java b/tools/signature-tools/src/signature/model/impl/SigParameter.java
deleted file mode 100644
index d9d3369..0000000
--- a/tools/signature-tools/src/signature/model/impl/SigParameter.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.model.impl;
-
-import signature.model.IParameter;
-import signature.model.ITypeReference;
-
-import java.io.Serializable;
-
-@SuppressWarnings("serial")
-public class SigParameter extends SigAnnotatableElement implements IParameter,
-        Serializable {
-
-    private ITypeReference type;
-
-    public SigParameter(ITypeReference type) {
-        this.type = type;
-    }
-
-    public ITypeReference getType() {
-        return type;
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder builder = new StringBuilder();
-        builder.append(super.toString());
-        builder.append(" ");
-        builder.append(getType().toString());
-        return builder.toString();
-    }
-}
diff --git a/tools/signature-tools/src/signature/model/impl/SigParameterizedType.java b/tools/signature-tools/src/signature/model/impl/SigParameterizedType.java
deleted file mode 100644
index d726135..0000000
--- a/tools/signature-tools/src/signature/model/impl/SigParameterizedType.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.model.impl;
-
-import signature.model.IClassReference;
-import signature.model.IParameterizedType;
-import signature.model.ITypeReference;
-import signature.model.util.ModelUtil;
-
-import java.io.Serializable;
-import java.util.List;
-
-@SuppressWarnings("serial")
-public class SigParameterizedType implements IParameterizedType, Serializable {
-
-    private ITypeReference ownerType;
-    private IClassReference rawType;
-    private List<ITypeReference> typeArguments;
-
-    public SigParameterizedType(ITypeReference ownerType,
-            IClassReference rawType, List<ITypeReference> typeArguments) {
-        this.ownerType = ownerType;
-        this.rawType = rawType;
-        this.typeArguments = typeArguments;
-    }
-
-    public ITypeReference getOwnerType() {
-        ITypeReference returnValue = ownerType;
-        if (returnValue == null) {
-            if (rawType.getClassDefinition().getDeclaringClass() != null) {
-                returnValue = new SigClassReference(rawType
-                        .getClassDefinition().getDeclaringClass());
-            }
-        }
-        return returnValue;
-    }
-
-    public IClassReference getRawType() {
-        return rawType;
-    }
-
-    public List<ITypeReference> getTypeArguments() {
-        return typeArguments;
-    }
-
-    @Override
-    public int hashCode() {
-        return hashCode(this);
-    }
-
-    public static int hashCode(IParameterizedType type) {
-        final int prime = 31;
-        int result = 1;
-        result = prime * type.getRawType().hashCode();
-        result = prime * result + type.getTypeArguments().hashCode();
-        return result;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        return equals(this, obj);
-    }
-
-    public static boolean equals(IParameterizedType thiz, Object that) {
-        if (!(that instanceof IParameterizedType)) {
-            return false;
-        }
-        IParameterizedType other = (IParameterizedType) that;
-        if (thiz.getOwnerType() == null) {
-            if (other.getOwnerType() != null) {
-                return false;
-            }
-        } else if (Uninitialized.isInitialized(thiz.getOwnerType())) {
-            if (!Uninitialized.isInitialized(other.getOwnerType())) {
-                return false;
-            }
-        } else if (!thiz.getOwnerType().equals(other.getOwnerType())) {
-            return false;
-        }
-        if (!thiz.getRawType().equals(other.getRawType())) {
-            return false;
-        }
-        if (!thiz.getTypeArguments().equals(other.getTypeArguments())) {
-            return false;
-        }
-        return true;
-    }
-
-
-    @Override
-    public String toString() {
-        return SigParameterizedType.toString(this);
-    }
-
-    public static String toString(IParameterizedType type) {
-        StringBuilder builder = new StringBuilder();
-        if (type.getOwnerType() != null) {
-            builder.append(type.getOwnerType().toString());
-            builder.append("::");
-        }
-        builder.append(type.getRawType());
-        builder.append("<");
-        builder.append(ModelUtil.separate(type.getTypeArguments(), ", "));
-        builder.append(">");
-        return builder.toString();
-    }
-}
diff --git a/tools/signature-tools/src/signature/model/impl/SigPrimitiveType.java b/tools/signature-tools/src/signature/model/impl/SigPrimitiveType.java
deleted file mode 100644
index 2786169..0000000
--- a/tools/signature-tools/src/signature/model/impl/SigPrimitiveType.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*

- * Copyright (C) 2009 The Android Open Source Project

- *

- * Licensed under the Apache License, Version 2.0 (the "License");

- * you may not use this file except in compliance with the License.

- * You may obtain a copy of the License at

- *

- *      http://www.apache.org/licenses/LICENSE-2.0

- *

- * Unless required by applicable law or agreed to in writing, software

- * distributed under the License is distributed on an "AS IS" BASIS,

- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

- * See the License for the specific language governing permissions and

- * limitations under the License.

- */

-

-package signature.model.impl;

-

-import signature.model.IPrimitiveType;

-

-public enum SigPrimitiveType implements IPrimitiveType {

-    VOID_TYPE("void"), BOOLEAN_TYPE("boolean"), BYTE_TYPE("byte"), CHAR_TYPE(

-            "char"), SHORT_TYPE("short"), INT_TYPE("int"), LONG_TYPE("long"),

-            FLOAT_TYPE("float"), DOUBLE_TYPE("double");

-

-    private String name;

-

-    private SigPrimitiveType(String name) {

-        this.name = name;

-    }

-

-    public static SigPrimitiveType valueOfTypeName(String name) {

-        for (SigPrimitiveType primitive : values()) {

-            if (primitive.name.equals(name)) {

-                return primitive;

-            }

-        }

-        throw new IllegalArgumentException(name + " is not a primitive type");

-    }

-

-    public String getName() {

-        return name;

-    }

-

-    @Override

-    public String toString() {

-        return name;

-    }

-}

diff --git a/tools/signature-tools/src/signature/model/impl/SigTypeVariableDefinition.java b/tools/signature-tools/src/signature/model/impl/SigTypeVariableDefinition.java
deleted file mode 100644
index e0f918e..0000000
--- a/tools/signature-tools/src/signature/model/impl/SigTypeVariableDefinition.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.model.impl;
-
-import signature.model.IGenericDeclaration;
-import signature.model.ITypeReference;
-import signature.model.ITypeVariableDefinition;
-import signature.model.util.ModelUtil;
-
-import java.io.Serializable;
-import java.util.List;
-
-@SuppressWarnings("serial")
-public class SigTypeVariableDefinition implements ITypeVariableDefinition,
-        Serializable {
-
-    private String name;
-    private IGenericDeclaration genericDeclaration;
-    private List<ITypeReference> upperBounds = Uninitialized.unset();
-
-    public SigTypeVariableDefinition(String name,
-            IGenericDeclaration genericDeclaration) {
-        this.name = name;
-        this.genericDeclaration = genericDeclaration;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public IGenericDeclaration getGenericDeclaration() {
-        return genericDeclaration;
-    }
-
-    public List<ITypeReference> getUpperBounds() {
-        return upperBounds;
-    }
-
-    public void setUpperBounds(List<ITypeReference> upperBounds) {
-        this.upperBounds = upperBounds;
-    }
-
-
-    @Override
-    public String toString() {
-        StringBuilder builder = new StringBuilder();
-        builder.append(name);
-        if (getUpperBounds().size() != 1) {
-            builder.append(ModelUtil.separate(getUpperBounds(), ", "));
-        } else {
-            if (!ModelUtil.isJavaLangObject(getUpperBounds().get(0))) {
-                builder.append(getUpperBounds().get(0));
-            }
-        }
-        return builder.toString();
-    }
-
-}
diff --git a/tools/signature-tools/src/signature/model/impl/SigTypeVariableReference.java b/tools/signature-tools/src/signature/model/impl/SigTypeVariableReference.java
deleted file mode 100644
index 6bd2593..0000000
--- a/tools/signature-tools/src/signature/model/impl/SigTypeVariableReference.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.model.impl;
-
-import java.io.Serializable;
-
-import signature.model.ITypeVariableDefinition;
-import signature.model.ITypeVariableReference;
-
-@SuppressWarnings("serial")
-public class SigTypeVariableReference implements ITypeVariableReference,
-        Serializable {
-
-    private ITypeVariableDefinition definition;
-
-    public SigTypeVariableReference(ITypeVariableDefinition definition) {
-        this.definition = definition;
-    }
-
-    public ITypeVariableDefinition getTypeVariableDefinition() {
-        return definition;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (getClass() == obj.getClass()) {
-            return getTypeVariableDefinition().equals(
-                    ((ITypeVariableReference) obj).getTypeVariableDefinition());
-        }
-        return false;
-    }
-
-    @Override
-    public int hashCode() {
-        return getTypeVariableDefinition().hashCode();
-    }
-
-    @Override
-    public String toString() {
-        return getTypeVariableDefinition().getName();
-    }
-}
diff --git a/tools/signature-tools/src/signature/model/impl/SigWildcardType.java b/tools/signature-tools/src/signature/model/impl/SigWildcardType.java
deleted file mode 100644
index c24ac23..0000000
--- a/tools/signature-tools/src/signature/model/impl/SigWildcardType.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.model.impl;
-
-import signature.model.ITypeReference;
-import signature.model.IWildcardType;
-
-import java.io.Serializable;
-import java.util.List;
-
-@SuppressWarnings("serial")
-public class SigWildcardType implements IWildcardType, Serializable {
-
-    private ITypeReference lowerBound;
-    private List<ITypeReference> upperBounds;
-
-    public SigWildcardType(ITypeReference lowerBound,
-            List<ITypeReference> upperBounds) {
-        this.lowerBound = lowerBound;
-        this.upperBounds = upperBounds;
-    }
-
-    public ITypeReference getLowerBound() {
-        return lowerBound;
-    }
-
-    public List<ITypeReference> getUpperBounds() {
-        return upperBounds;
-    }
-
-    @Override
-    public int hashCode() {
-        return SigWildcardType.hashCode(this);
-    }
-
-    public static int hashCode(IWildcardType type) {
-        final int prime = 31;
-        int result = 1;
-        result = prime
-                + ((type.getLowerBound() == null) ? 0 : type.getLowerBound()
-                        .hashCode());
-        result = prime * result + type.getUpperBounds().hashCode();
-        return result;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        return SigWildcardType.equals(this, obj);
-    }
-
-    public static boolean equals(IWildcardType thiz, Object obj) {
-        if (thiz == obj) return true;
-        if (obj == null) return false;
-        if (!(obj instanceof IWildcardType)) return false;
-        IWildcardType that = (IWildcardType) obj;
-        if (thiz.getLowerBound() == null) {
-            if (that.getLowerBound() != null) return false;
-        } else if (!thiz.getLowerBound().equals(that.getLowerBound()))
-            return false;
-        if (!thiz.getUpperBounds().equals(that.getUpperBounds())) return false;
-        return true;
-    }
-
-
-    @Override
-    public String toString() {
-        return SigWildcardType.toString(this);
-    }
-
-    public static String toString(IWildcardType thiz) {
-        StringBuilder builder = new StringBuilder();
-        builder.append("?");
-        if (thiz.getLowerBound() != null) {
-            builder.append(" ");
-            builder.append(" super ");
-            builder.append(thiz.getLowerBound());
-        }
-        if (!thiz.getUpperBounds().isEmpty()) {
-            builder.append(" extends ");
-            builder.append(thiz.getUpperBounds());
-        }
-        return builder.toString();
-    }
-}
diff --git a/tools/signature-tools/src/signature/model/impl/Uninitialized.java b/tools/signature-tools/src/signature/model/impl/Uninitialized.java
deleted file mode 100644
index cc88479..0000000
--- a/tools/signature-tools/src/signature/model/impl/Uninitialized.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.model.impl;
-
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-import java.util.List;
-import java.util.Set;
-
-import signature.model.IAnnotationField;
-import signature.model.IClassDefinition;
-import signature.model.IClassReference;
-import signature.model.IPackage;
-import signature.model.ITypeReference;
-import signature.model.ITypeVariableDefinition;
-import signature.model.ITypeVariableReference;
-import signature.model.Kind;
-
-/**
- *
- */
-public class Uninitialized {
-
-    private static final Object UNINITIALIZED;
-
-    static {
-        UNINITIALIZED = Proxy.newProxyInstance(Uninitialized.class
-                .getClassLoader(), new Class[] {
-                ITypeReference.class, IPackage.class, IClassDefinition.class,
-                IClassReference.class, ITypeVariableReference.class,
-                ITypeVariableDefinition.class, IAnnotationField.class,
-                Set.class, List.class}, new InvocationHandler() {
-            public Object invoke(Object proxy, Method method, Object[] args)
-                    throws Throwable {
-                if (method.getName().equals("toString")) {
-                    return "Uninitialized";
-                }
-
-                throw new UnsupportedOperationException();
-            }
-        });
-    }
-
-    @SuppressWarnings("unchecked")
-    public static <T> T unset() {
-        return (T) UNINITIALIZED;
-    }
-
-    public static boolean isInitialized(Object o) {
-        return o != UNINITIALIZED && o != Kind.UNINITIALIZED;
-    }
-}
diff --git a/tools/signature-tools/src/signature/model/util/ITypeFactory.java b/tools/signature-tools/src/signature/model/util/ITypeFactory.java
deleted file mode 100644
index af3e3a9..0000000
--- a/tools/signature-tools/src/signature/model/util/ITypeFactory.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.model.util;
-
-import signature.model.IClassReference;
-import signature.model.IGenericDeclaration;
-import signature.model.ITypeReference;
-import signature.model.ITypeVariableReference;
-import signature.model.impl.SigArrayType;
-import signature.model.impl.SigClassDefinition;
-import signature.model.impl.SigParameterizedType;
-import signature.model.impl.SigTypeVariableDefinition;
-import signature.model.impl.SigWildcardType;
-
-import java.util.List;
-
-public interface ITypeFactory {
-
-    public static final String JAVA_LANG_OBJECT = "java.lang.Object";
-
-    /**
-     * Returns the existing type or creates a new one.<br>
-     * Format: java.lang.Object
-     */
-    public SigClassDefinition getClass(String packageName, String className);
-
-    public IClassReference getClassReference(String packageName,
-            String className);
-
-    /**
-     * Returns the existing array type or creates a new one.
-     * 
-     * @param componentType
-     *            the component type of the array
-     * @return the array type
-     */
-    public SigArrayType getArrayType(ITypeReference componentType);
-
-    /**
-     * Returns the existing parameterized type or creates a new one.
-     * 
-     * @param ownerType
-     *            the owner of the parameterized type
-     * @param rawType
-     *            the type which is parameterized
-     * @param typeArguments
-     *            the type arguments
-     * @return the parameterized type
-     */
-    public SigParameterizedType getParameterizedType(ITypeReference ownerType,
-            IClassReference rawType, List<ITypeReference> typeArguments);
-
-
-    public boolean containsTypeVariableDefinition(String name,
-            IGenericDeclaration genericDeclaration);
-
-    /**
-     * Returns the existing type variable or creates a new one.
-     * 
-     * @param genericDeclaration
-     *            the declaration site of the variable
-     * @param name
-     *            the name of the type variable
-     * @return the type variable
-     */
-    public SigTypeVariableDefinition getTypeVariable(String name,
-            IGenericDeclaration genericDeclaration);
-
-    public ITypeVariableReference getTypeVariableReference(String name,
-            IGenericDeclaration genericDeclaration);
-
-    /**
-     * Returns the existing wildcard type or creates a new one. Wildcard types
-     * are equal if they have the same lower bound and have the same upper
-     * bounds. The order of the upper bounds is irrelevant except for the first
-     * element. <br>
-     * Note: This does not mean that two values with equal wildcard type can be
-     * assigned to each other!
-     * 
-     * @param lowerBound
-     *            the lower bound
-     * @param upperBounds
-     *            the upper bounds
-     * @return the wildcard type
-     */
-    public SigWildcardType getWildcardType(ITypeReference lowerBound,
-            List<ITypeReference> upperBounds);
-
-}
diff --git a/tools/signature-tools/src/signature/model/util/ModelUtil.java b/tools/signature-tools/src/signature/model/util/ModelUtil.java
deleted file mode 100644
index f66fd2c..0000000
--- a/tools/signature-tools/src/signature/model/util/ModelUtil.java
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.model.util;
-
-import signature.model.IAnnotatableElement;
-import signature.model.IAnnotation;
-import signature.model.IAnnotationElement;
-import signature.model.IAnnotationField;
-import signature.model.IApi;
-import signature.model.IClassDefinition;
-import signature.model.IField;
-import signature.model.IPackage;
-import signature.model.ITypeReference;
-
-import java.util.Collection;
-
-public class ModelUtil {
-    private ModelUtil() {
-    }
-
-    /**
-     * Returns the IClass for the given className.<br>
-     * Format: a.b.C
-     * 
-     * @param qualifiedClassName
-     *            the fully qualified class name
-     * @return the IClass instance or null;
-     */
-    public static IClassDefinition getClass(IPackage aPackage,
-            String qualifiedClassName) {
-        for (IClassDefinition clazz : aPackage.getClasses()) {
-            if (qualifiedClassName.equals(clazz.getName())) {
-                return clazz;
-            }
-        }
-        return null;
-    }
-
-    public static IAnnotation getAnnotation(IAnnotatableElement element,
-            String qualifiedTypeName) {
-        for (IAnnotation annotation : element.getAnnotations()) {
-            if (qualifiedTypeName.equals(annotation.getType()
-                    .getClassDefinition().getQualifiedName())) {
-                return annotation;
-            }
-        }
-        return null;
-    }
-
-    public static IAnnotationElement getAnnotationElement(
-            IAnnotation annotation, String elementName) {
-        for (IAnnotationElement element : annotation.getElements()) {
-            if (elementName.equals(element.getDeclaringField().getName())) {
-                return element;
-            }
-        }
-        return null;
-    }
-
-    public static IField getField(IClassDefinition clazz, String fieldName) {
-        for (IField field : clazz.getFields()) {
-            if (fieldName.equals(field.getName())) {
-                return field;
-            }
-        }
-        return null;
-    }
-
-    public static IAnnotationField getAnnotationField(
-            IClassDefinition annotation, String fieldName) {
-        for (IAnnotationField field : annotation.getAnnotationFields()) {
-            if (fieldName.equals(field.getName())) {
-                return field;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Returns the IPackage for the given className.<br>
-     * Format: a.b
-     * 
-     * @param api
-     *            the api
-     * @param packageName
-     *            the name of the package
-     * @return the IClass instance or null;
-     */
-    public static IPackage getPackage(IApi api, String packageName) {
-        for (IPackage aPackage : api.getPackages()) {
-            if (packageName.equals(aPackage.getName())) {
-                return aPackage;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * "a.b.c.A;" -> "a.b.c" "A" -> "" empty string
-     * 
-     * @param classIdentifier
-     * @return the package name
-     */
-    public static String getPackageName(String classIdentifier) {
-        int lastIndexOfSlash = classIdentifier.lastIndexOf('.');
-        String packageName = null;
-        if (lastIndexOfSlash == -1) {
-            packageName = "";
-        } else {
-            packageName = classIdentifier.substring(0, lastIndexOfSlash);
-        }
-        return packageName;
-    }
-
-    /**
-     * "a.b.c.A;" -> "A" "A" -> "A"
-     * 
-     * @param classIdentifier
-     *            fully qualified class name
-     * @return the class name
-     */
-    public static String getClassName(String classIdentifier) {
-        int lastIndexOfDot = classIdentifier.lastIndexOf('.');
-        String className = null;
-        if (lastIndexOfDot == -1) {
-            className = classIdentifier;
-        } else {
-            className = classIdentifier.substring(lastIndexOfDot + 1);
-        }
-        return className;
-    }
-
-
-    public static String separate(Collection<? extends Object> elements,
-            String separator) {
-        StringBuilder s = new StringBuilder();
-        boolean first = true;
-        for (Object object : elements) {
-            if (!first) {
-                s.append(separator);
-            }
-            s.append(object.toString());
-            first = false;
-        }
-        return s.toString();
-    }
-
-    public static boolean isJavaLangObject(ITypeReference type) {
-        if (type instanceof IClassDefinition) {
-            IClassDefinition clazz = (IClassDefinition) type;
-            if ("java.lang".equals(clazz.getPackageName())) {
-                return "Object".equals(clazz.getName());
-            }
-        }
-        return false;
-    }
-
-}
diff --git a/tools/signature-tools/src/signature/model/util/TypePool.java b/tools/signature-tools/src/signature/model/util/TypePool.java
deleted file mode 100644
index dc48113..0000000
--- a/tools/signature-tools/src/signature/model/util/TypePool.java
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.model.util;
-
-import static signature.model.impl.Uninitialized.isInitialized;
-import signature.model.IClassReference;
-import signature.model.IGenericDeclaration;
-import signature.model.ITypeReference;
-import signature.model.ITypeVariableReference;
-import signature.model.impl.SigArrayType;
-import signature.model.impl.SigClassDefinition;
-import signature.model.impl.SigClassReference;
-import signature.model.impl.SigParameterizedType;
-import signature.model.impl.SigTypeVariableDefinition;
-import signature.model.impl.SigTypeVariableReference;
-import signature.model.impl.SigWildcardType;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Pool and factory for all {@link ITypeReference} instances.<br>
- * Note: This class is not thread save
- */
-public class TypePool implements ITypeFactory {
-
-    /**
-     * Pool for all SigClass objects. Key format: "java.lang.Object", "a.b.C$D
-     */
-    private Map<String, SigClassDefinition> classPool;
-    /** Pool for all SigTypeVariable objects */
-    private Map<TypeVariableKey, SigTypeVariableDefinition> typeVariablePool;
-
-    public TypePool() {
-        classPool = new HashMap<String, SigClassDefinition>();
-        typeVariablePool =
-                new HashMap<TypeVariableKey, SigTypeVariableDefinition>();
-    }
-
-    public SigClassDefinition getClass(String packageName, String className) {
-        String key = packageName + "<>" + className;
-        SigClassDefinition clazz = classPool.get(key);
-        if (clazz == null) {
-            clazz = new SigClassDefinition(packageName, className);
-            classPool.put(key, clazz);
-        }
-        return clazz;
-    }
-
-    public IClassReference getClassReference(String packageName,
-            String className) {
-        return new SigClassReference(getClass(packageName, className));
-    }
-
-    public SigArrayType getArrayType(ITypeReference componentType) {
-        assert componentType != null;
-        return new SigArrayType(componentType);
-    }
-
-    public SigParameterizedType getParameterizedType(ITypeReference ownerType,
-            IClassReference rawType, List<ITypeReference> typeArguments) {
-        assert rawType != null;
-        assert typeArguments != null;
-        return new SigParameterizedType(ownerType, rawType, typeArguments);
-    }
-
-    private static class TypeVariableKey {
-        private String name;
-        private IGenericDeclaration genericDeclaration;
-
-        public TypeVariableKey(String name,
-                IGenericDeclaration genericDeclaration) {
-            this.genericDeclaration = genericDeclaration;
-            this.name = name;
-        }
-
-        @Override
-        public int hashCode() {
-            final int prime = 31;
-            int result = 1;
-            result = prime * result + genericDeclaration.hashCode();
-            result = prime * result + name.hashCode();
-            return result;
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            TypeVariableKey other = (TypeVariableKey) obj;
-            if (genericDeclaration != other.genericDeclaration) {
-                return false;
-            }
-            if (!name.equals(other.name)) {
-                return false;
-            }
-            return true;
-        }
-    }
-
-    public boolean containsTypeVariableDefinition(String name,
-            IGenericDeclaration genericDeclaration) {
-        TypeVariableKey key = new TypeVariableKey(name, genericDeclaration);
-        return typeVariablePool.get(key) != null;
-    }
-
-    public SigTypeVariableDefinition getTypeVariable(String name,
-            IGenericDeclaration genericDeclaration) {
-        assert name != null;
-        assert genericDeclaration != null;
-
-        TypeVariableKey key = new TypeVariableKey(name, genericDeclaration);
-        SigTypeVariableDefinition sigTypeVariable = typeVariablePool.get(key);
-        if (sigTypeVariable == null) {
-            sigTypeVariable = new SigTypeVariableDefinition(name,
-                    genericDeclaration);
-            typeVariablePool.put(key, sigTypeVariable);
-        }
-        return sigTypeVariable;
-    }
-
-    public ITypeVariableReference getTypeVariableReference(String name,
-            IGenericDeclaration genericDeclaration) {
-        return new SigTypeVariableReference(getTypeVariable(name,
-                genericDeclaration));
-    }
-
-    public SigWildcardType getWildcardType(ITypeReference lowerBound,
-            List<ITypeReference> upperBounds) {
-        assert upperBounds != null;
-
-        SigWildcardType sigWildcardType = new SigWildcardType(lowerBound,
-                upperBounds);
-        return sigWildcardType;
-    }
-
-    public void replaceAllUninitialiezWithNull() {
-        for (SigClassDefinition clazz : classPool.values()) {
-            replaceUninitializedWithNull(clazz);
-        }
-    }
-
-    private static void replaceUninitializedWithNull(
-            SigClassDefinition clazz) {
-        if (clazz == null) {
-            return;
-        }
-        if (!isInitialized(clazz.getAnnotationFields())) {
-            clazz.setAnnotationFields(null);
-        }
-        if (!isInitialized(clazz.getAnnotations())) {
-            clazz.setAnnotations(null);
-        }
-        if (!isInitialized(clazz.getAnnotations())) {
-            clazz.setAnnotations(null);
-        }
-        if (!isInitialized(clazz.getConstructors())) {
-            clazz.setConstructors(null);
-        }
-        if (!isInitialized(clazz.getDeclaringClass())) {
-            clazz.setDeclaringClass(null);
-        }
-
-        if (!isInitialized(clazz.getEnumConstants())) {
-            clazz.setEnumConstants(null);
-        }
-        if (!isInitialized(clazz.getFields())) {
-            clazz.setFields(null);
-        }
-        if (!isInitialized(clazz.getInnerClasses())) {
-            clazz.setInnerClasses(null);
-        }
-        if (!isInitialized(clazz.getInterfaces())) {
-            clazz.setInterfaces(null);
-        }
-        if (!isInitialized(clazz.getKind())) {
-            clazz.setKind(null);
-        }
-        if (!isInitialized(clazz.getMethods())) {
-            clazz.setMethods(null);
-        }
-        if (!isInitialized(clazz.getModifiers())) {
-            clazz.setModifiers(null);
-        }
-        if (!isInitialized(clazz.getSuperClass())) {
-            clazz.setSuperClass(null);
-        }
-        if (!isInitialized(clazz.getTypeParameters())) {
-            clazz.setTypeParameters(null);
-        }
-    }
-}
diff --git a/tools/signature-tools/templates/ApiOverviewPage.st b/tools/signature-tools/templates/ApiOverviewPage.st
deleted file mode 100644
index 4faa193..0000000
--- a/tools/signature-tools/templates/ApiOverviewPage.st
+++ /dev/null
@@ -1,60 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
-<html>
-<head>
-$Common_meta()$
-<title>
-Android API Differences Report
-</title>
-<body>
-<div class="body">
-
-$Header()$
-
-
-<div class="content">
-<h2>Android API Differences Report</h2>
-<p>This document details the changes in the Android framework API. It shows 
-additions, modifications, and removals for packages, classes, methods, and 
-fields. Each reference to an API change includes a brief description of the 
-API and an explanation of the change and suggested workaround, where available.</p>
-
-<p>The differences described in this report are based a comparison of the APIs 
-whose versions are specified in the upper-right corner of this page. It compares a 
-newer "to" API to an older "from" version, noting any changes relative to the 
-older API. So, for example, indicated API removals are no longer present in the "to" 
-API.</p>
-<p>For more information about the Android framework API and SDK, 
-see the <a href="http://code.google.com/android/index.html" target="_top">Android product site</a>.</p>
-
-$if(no_delta)$
-<h3>Congratulation!</h3>
-No differences were detected between the two provided APIs.
-$endif$
-
-
-$if(removed_packages)$
-$Table(name="Removed Packages", rows=removed_packages:{$it.from:ModelElementRow()$})$
-<br/>
-$endif$
-
-
-$if(added_packages)$
-$Table(name="Added Packages", rows=added_packages:{$it.to:PackageAddedLink()$}:SimpleTableRow())$
-<br/>
-$endif$
-
-$if(changed_packages)$
-$Table(name="Changed Packages", rows=changed_packages:{$it.to:PackageChangedLink()$}:SimpleTableRow())$
-<br/>
-$endif$
-</div>
-
-
-</div>
-</body>
-</html>
-
-
-
-
-
diff --git a/tools/signature-tools/templates/ClassChangedLink.st b/tools/signature-tools/templates/ClassChangedLink.st
deleted file mode 100644
index 20e0ed9..0000000
--- a/tools/signature-tools/templates/ClassChangedLink.st
+++ /dev/null
@@ -1 +0,0 @@
-$Link(url={$it.packageName$.$it.name$.html}, name={<tt>$it.name$</tt>})$
diff --git a/tools/signature-tools/templates/ClassOverviewPage.st b/tools/signature-tools/templates/ClassOverviewPage.st
deleted file mode 100644
index 45b4c1c..0000000
--- a/tools/signature-tools/templates/ClassOverviewPage.st
+++ /dev/null
@@ -1,131 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
-<html>
-<head>
-$Common_meta()$
-<title>
-$class_delta.to.packageName$.$class_delta.to.name$
-</title>
-</head>
-<body>
-
-<div class="body">
-
-$Header()$
-
-<div class="content">
-<h2>Class $class_delta.to.packageName$.$class_delta.to:ClassReferenceLink()$</h2>
-<br/>
-
-$if(has_class_signature_delta)$
-<table summary="Signature Difference" border="1" width="100%">
-  <tr>
-    <th colspan=3>Signature Difference</th>
-  </tr>
-  <tbody>
-    <tr class="default">
-      <td>$SigClassDefinition(element=class_delta.to)$</td>
-      <td>
-        $if(class_delta.annotationDeltas)$   $MultiSubDelta(desc="Annotations Changed:", deltas=class_delta.annotationDeltas)$      $endif$
-        $if(class_delta.modifierDeltas)$     $MultiSubDelta(desc="Modifiers Changed:", deltas=class_delta.modifierDeltas)$          $endif$
-        $if(class_delta.typeVariableDeltas)$ $MultiSubDelta(desc="Type Variables Changed:", deltas=class_delta.typeVariableDeltas)$ $endif$
-        $if(class_delta.superClassDelta)$    $SingleSubDelta(desc="Superclass Changed", delta=class_delta.superClassDelta)$               $endif$
-        $if(class_delta.interfaceDeltas)$    $MultiSubDelta(desc="Interfaces Changed:", deltas=class_delta.interfaceDeltas)$        $endif$
-      </td>
-    </tr>
-  </tbody>
-</table>
-<br/>
-$endif$
-
-$! Annotation Fields !$
-
-$if(removed_annotation_fields)$
-$Table(name="Removed Annotation Fields", rows=removed_annotation_fields:{$it.from:ModelElementRow()$})$
-<br/>
-$endif$
-
-$if(added_annotation_fields)$
-$Table(name="Added Annotation Fields", rows=added_annotation_fields:{$it.to:ModelElementRow()$})$
-<br/>
-$endif$
-
-$if(changed_annotation_fields)$
-$Table(name="Changed Annotation Fields", rows=changed_annotation_fields:DeltaTableRow())$
-<br/>
-$endif$
-
-
-$! --------Enum Constants-------- !$
-
-$if(removed_enum_constants)$
-$Table(name="Removed Enum Constants", rows=removed_enum_constants:{$it.from:ModelElementRow()$})$
-<br/>
-$endif$
-
-$if(added_enum_constants)$
-$Table(name="Added Enum Constants", rows=added_enum_constants:{$it.to:ModelElementRow()$})$
-<br/>
-$endif$
-
-$if(changed_enum_constants)$
-$Table(name="Changed Enum Constants", rows=changed_enum_constants:DeltaTableRow())$
-<br/>
-$endif$
-
-
-$! Fields !$
-
-$if(removed_fields)$
-$Table(name="Removed Fields", rows=removed_fields:{$it.from:ModelElementRow()$})$
-<br/>
-$endif$
-
-$if(added_fields)$
-$Table(name="Added Fields", rows=added_fields:{$it.to:ModelElementRow()$})$
-<br/>
-$endif$
-
-$if(changed_fields)$
-$Table(name="Changed Fields", rows=changed_fields:DeltaTableRow())$
-<br/>
-$endif$
-
-
-$! Constructors !$
-
-$if(removed_constructors)$
-$Table(name="Removed Constructors", rows=removed_constructors:{$it.from:ModelElementRow()$})$
-<br/>
-$endif$
-
-$if(added_constructors)$
-$Table(name="Added Constructors", rows=added_constructors:{$it.to:ModelElementRow()$})$
-<br/>
-$endif$
-
-$if(changed_constructors)$
-$Table(name="Changed Constructors", rows=changed_constructors:DeltaTableRow())$
-<br/>
-$endif$
-
-
-$! Methods !$
-
-$if(removed_methods)$
-$Table(name="Removed Methods", rows=removed_methods:{$it.from:ModelElementRow()$})$
-<br/>
-$endif$
-
-$if(added_methods)$
-$Table(name="Added Methods", rows=added_methods:{$it.to:ModelElementRow()$})$
-<br/>
-$endif$
-
-$if(changed_methods)$
-$Table(name="Changed Methods", rows=changed_methods:DeltaTableRow())$
-<br/>
-$endif$
-</div>
-</div>
-</body>
-</html>
\ No newline at end of file
diff --git a/tools/signature-tools/templates/ClassReferenceLink.st b/tools/signature-tools/templates/ClassReferenceLink.st
deleted file mode 100644
index c22e9b5..0000000
--- a/tools/signature-tools/templates/ClassReferenceLink.st
+++ /dev/null
@@ -1 +0,0 @@
-$Link(url={http://code.google.com/android/reference/$it.packageFragments; separator="/"$/$it.name$.html}, name={<tt>$it.name$</tt>})$
diff --git a/tools/signature-tools/templates/Common_meta.st b/tools/signature-tools/templates/Common_meta.st
deleted file mode 100644
index 8663781..0000000
--- a/tools/signature-tools/templates/Common_meta.st
+++ /dev/null
@@ -1,12 +0,0 @@
-<meta name="generator" content="Android signature tools v 1.0">
-<meta name="keywords" content="API difference, difference between two APIs, API diff">
-<link type="text/css" rel="stylesheet" href="../styles.css" title="Stylesheet"/>
-<link type="text/css" rel="stylesheet" href="styles.css" title="Stylesheet"/>
-
-<link rel="stylesheet" type="text/css" href="http://code.google.com/android/assets/codesite/codesite.css"/>
-<link rel="stylesheet" type="text/css" href="http://code.google.com/android/assets/codesite/semantic_headers.css"/>
-<link rel="stylesheet" type="text/css" href="http://code.google.com/android/assets/style.css"/> 
-
-
-
-
diff --git a/tools/signature-tools/templates/DeltaTableRow.st b/tools/signature-tools/templates/DeltaTableRow.st
deleted file mode 100644
index 4d0974c..0000000
--- a/tools/signature-tools/templates/DeltaTableRow.st
+++ /dev/null
@@ -1,8 +0,0 @@
-<tr class="deltaTableRow">
-  <td class="element">
-    $ElementType(element=it.to):{<tt>$it$</tt>}$
-  </td>
-  <td class="delta">
-    $DeltaTypeSwitch(delta=it)$
-  </td>
-</tr>
diff --git a/tools/signature-tools/templates/Header.st b/tools/signature-tools/templates/Header.st
deleted file mode 100644
index 9aa8e2f..0000000
--- a/tools/signature-tools/templates/Header.st
+++ /dev/null
@@ -1,21 +0,0 @@
-<div class="header">
-  <div class="logo">
-    <a href="http://code.google.com/android/documentation.html"><img style="border: 0;" src="http://code.google.com/android/images/android_icon_125.png"/></a>
-  </div>
-  <div class="specbox">
-    <table>
-      <tr>
-        <th colspan="2"> API Diff Specification </th>
-      </tr>
-      <tr>
-        <td>To Version:</td> <td>$to_desc$</td>
-      </tr>
-      <tr>
-        <td>From Version:</td> <td>$from_desc$</td>
-      </tr>
-      <tr>
-        <td>Generated</td> <td>$creation_time$</td>
-      </tr>
-    </table>
-  </div>
-</div>
\ No newline at end of file
diff --git a/tools/signature-tools/templates/Link.st b/tools/signature-tools/templates/Link.st
deleted file mode 100644
index 2421094..0000000
--- a/tools/signature-tools/templates/Link.st
+++ /dev/null
@@ -1 +0,0 @@
-<a class="$link_style; null="default"$" href="$url$">$name$</a>
\ No newline at end of file
diff --git a/tools/signature-tools/templates/ModelElementRow.st b/tools/signature-tools/templates/ModelElementRow.st
deleted file mode 100644
index 54b20c6..0000000
--- a/tools/signature-tools/templates/ModelElementRow.st
+++ /dev/null
@@ -1,6 +0,0 @@
-<tr class="deltaTableRow">
-  <td class="element">
-    $ElementType(element=it):{<tt>$it$</tt>}$
-  </td>
-</tr>
-
diff --git a/tools/signature-tools/templates/PackageAddedLink.st b/tools/signature-tools/templates/PackageAddedLink.st
deleted file mode 100644
index eb352da..0000000
--- a/tools/signature-tools/templates/PackageAddedLink.st
+++ /dev/null
@@ -1 +0,0 @@
-$Link(url={http://code.google.com/android/reference/$it.packageFragments; separator="/"$/package-summary.html}, name={<tt>$it.name$</tt>})$
diff --git a/tools/signature-tools/templates/PackageChangedLink.st b/tools/signature-tools/templates/PackageChangedLink.st
deleted file mode 100644
index 5951f2a..0000000
--- a/tools/signature-tools/templates/PackageChangedLink.st
+++ /dev/null
@@ -1 +0,0 @@
-$Link(url={changes/pkg_$it.name$.html}, name={<tt>$it.name$</tt>})$
\ No newline at end of file
diff --git a/tools/signature-tools/templates/PackageOverviewPage.st b/tools/signature-tools/templates/PackageOverviewPage.st
deleted file mode 100644
index ebeded0..0000000
--- a/tools/signature-tools/templates/PackageOverviewPage.st
+++ /dev/null
@@ -1,39 +0,0 @@
-<!doctype html public "-//w3c//dtd html 4.0 frameset//en""http://www.w3.org/tr/rec-html40/frameset.dtd">
-<html>
-<head>
-$Common_meta()$
-<title>
-Android API Differences Report
-</title>
-<body>
-
-<div class="body">
-
-$Header()$
-
-<div class="content">
-
-<h2>
-Package $Link(url={http://code.google.com/android/reference/$package_delta.to.packageFragments; separator="/"$/package-summary.html}, name=package_delta.to.name)$
-</h2>
-
-
-$if(removed_classes)$
-$Table(name="Removed Classes and Interfaces", rows=removed_classes:{$it.from:{<tt>$it.name$</tt>}$}:SimpleTableRow())$
-<br/>
-$endif$
-
-
-$if(added_classes)$
-$Table(name="Added Classes and Interfaces", rows=added_classes:{$it.to:ClassReferenceLink()$}:SimpleTableRow())$
-<br/>
-$endif$
-
-$if(changed_classes)$
-$Table(name="Changed Classes and Interfaces", rows=changed_classes:{$it.to:ClassChangedLink()$}:SimpleTableRow())$
-<br/>
-$endif$
-</div>
-</div>
-</body>
-</html>
\ No newline at end of file
diff --git a/tools/signature-tools/templates/SimpleTableRow.st b/tools/signature-tools/templates/SimpleTableRow.st
deleted file mode 100644
index 3e7e7c2..0000000
--- a/tools/signature-tools/templates/SimpleTableRow.st
+++ /dev/null
@@ -1,5 +0,0 @@
-<tr class="default">
-  <td>
-    $it$
-  </td>
-</tr>
diff --git a/tools/signature-tools/templates/Styles.st b/tools/signature-tools/templates/Styles.st
deleted file mode 100644
index 4294eb3..0000000
--- a/tools/signature-tools/templates/Styles.st
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Noser signature html output v$version$
- */
-
-/* default link style*/
-a.default:link      {color: blue; text-decoration: none}
-a.default:hover     {color: blue; text-decoration: underline;}
-a.default:visited   {color: blue; text-decoration: none}
-
-/* discreet link style */
-a.discreet:link     {color: black; text-decoration: none}
-a.discreet:visited  {color: black; text-decoration: none}
-a.discreet:hover    {color: black; text-decoration: underline;}
-
-ul { 
-	list-style-type: none 
-}
-
-.body {
-	margin: 10px;
-}
-
-.header {
-    position:relative;
-	width: 100%;
-	
-}
-
-.logo {
-	left:0px;
-}
-.specbox {
-    position:absolute;
-	right:0px;
-	top:0px;
-}
-
-.content {
-	width: 100%;
-	position: relative;
-	top:75px;
-}
-
-
diff --git a/tools/signature-tools/templates/Table.st b/tools/signature-tools/templates/Table.st
deleted file mode 100644
index 2eecb8e..0000000
--- a/tools/signature-tools/templates/Table.st
+++ /dev/null
@@ -1,9 +0,0 @@
-<table summary="$name$" border="1" width="100%">
-<tr>
-  <th COLSPAN=2>$name$</th>
-</tr>
-<tbody>
-$rows$
-</tbody>
-</table>
-
diff --git a/tools/signature-tools/templates/delta/deltas.stg b/tools/signature-tools/templates/delta/deltas.stg
deleted file mode 100644
index a27d641..0000000
--- a/tools/signature-tools/templates/delta/deltas.stg
+++ /dev/null
@@ -1,149 +0,0 @@
-group deltas;
-
-
-ADDED(delta)  ::= "Added $ElementType(element=delta.to)$"
-
-
-REMOVED(delta) ::= "Removed $ElementType(element=delta.from)$"
-
-
-CHANGED(delta) ::= "$DeltaType(delta)$"
-
-
-DeltaType(delta) ::= "$({$delta.class.simpleName$})(delta)$"
-
-
-DeltaTypeSwitch(delta) ::= "$delta:({$delta.type$})(delta)$"
-
-
-MultiSubDelta(desc, deltas) ::= <<
-$if(deltas)$
-$if(!deltas.empty)$
-$desc$
-<ul>
-$deltas:{<li>$DeltaTypeSwitch(delta=it)$</li>}$
-</ul>
-$endif$
-$endif$ 
->>
-
-
-SigAnnotationDelta(delta) ::= <<
-$MultiSubDelta(desc="Annotation Elements changed:", deltas=delta.annotationElementDeltas)$
->>
-
-
-
-SigAnnotationElementDelta(delta) ::= <<
-$SingleSubDelta(desc="Value changed:", delta=delta.valueDelta)$
->>
-
-
-SigArrayTypeDelta(delta) ::= <<
-$SingleSubDelta(desc="Component Type of array changed:", delta=delta.componentTypeDelta)$
->>
-
-
-SigClassReferenceDelta(delta) ::= "from $SigClass(element=delta.from)$ to $SigClass(element=delta.to)$"
-
-
-SigConstructorDelta(delta) ::= "$SigExecutableMemberDelta(delta=delta)$"
-
-SigMethodDelta(delta) ::= <<
-$SigExecutableMemberDelta(delta=delta)$
-$if(delta.returnTypeDelta)$
-$SingleSubDelta(desc="Return Type changed:", delta=delta.returnTypeDelta)$
-$endif$
->>
-
-
-SigExecutableMemberDelta(delta) ::= <<
-$if(delta.annotationDeltas)$
-$MultiSubDelta(desc="Annotations changed:", deltas=delta.annotationDeltas)$
-$endif$
-
-$if(delta.modifierDeltas)$
-$MultiSubDelta(desc="Modifiers changed:", deltas=delta.modifierDeltas)$
-$endif$
-
-$if(delta.typeVariableDeltas)$
-$MultiSubDelta(desc="Type Variables changed:", deltas=delta.typeVariableDeltas)$
-$endif$
-
-$if(delta.exceptionDeltas)$
-$MultiSubDelta(desc="Exceptions changed:", deltas=delta.exceptionDeltas)$
-$endif$
-
-$if(delta.parameterDeltas)$
-$MultiSubDelta(desc="Parameters changed:", deltas=delta.parameterDeltas)$
-$endif$
->>
-
-SigFieldDelta(delta) ::= <<
-$SingleSubDelta(desc="Type changed:", delta=delta.typeDelta)$
-$MultiSubDelta(desc="Modifiers changed:", deltas=delta.modifierDeltas)$
-$MultiSubDelta(desc="Annotations changed:", deltas=delta.annotationDeltas)$
->>
-
-SigGenericDelclarationDelta(delta) ::= "GenericDelclarationDelta $delta$"
-
-SigModifierDelta(delta) ::= "SigModifierDelta.st: Please file a bug if you see this message"
-
-
-SigParameterDelta(delta) ::= <<
-$if(delta.annotationDeltas)$
-$MultiSubDelta(desc="Annotations changed:", deltas=delta.annotationDeltas)$
-$endif$
-
-$if(delta.typeDelta)$
-$SingleSubDelta(desc="Type changed:", delta=delta.typeDelta)$
-$endif$
->>
-
-
-SigParameterizedTypeDelta(delta) ::= <<
-$SingleSubDelta(desc="Owner Type changed:", delta=delta.ownerTypeDelta)$
-$SingleSubDelta(desc="Raw Type changed:", delta=delta.rawTypeDelta)$
-$MultiSubDelta(desc="Type Arguments changed:", deltas=delta.argumentTypeDeltas)$
->>
-
-
-SigPrimitiveTypeDelta(delta) ::= "from $delta.from$ to $delta.to$"
-
-SigTypeDelta(delta) ::= "from $ElementType(element=delta.from)$ to $ElementType(element=delta.to)$"
-
-SigTypeVariableReferenceDelta(delta) ::= <<
-SigTypeVariableReferenceDelta:
-$delta$
->>
-
-SigTypeVariableDefinitionDelta(delta) ::= <<
-$SingleSubDelta(desc="Upper Bound changed:", delta=delta.upperBoundsDelta)$
-$SingleSubDelta(desc="Declaration changed:", delta=delta.genericDeclarationDelta)$
->>
-
-SigUpperBoundsDelta(delta) ::= <<
-$SingleSubDelta(desc="First Upper Bound changed:", delta=delta.firstUpperBoundDelta)$
-$MultiSubDelta(desc="Upper Bounds changed:", deltas=delta.remainingUpperBoundDeltas)$
->>
-
-SigWildcardTypeDelta(delta) ::= <<
-$SingleSubDelta(desc="Lower Bound changed:", delta=delta.lowerBoundDelta)$
-$SingleSubDelta(desc="Upper Bounds changed:", delta=delta.upperBoundDelta)$
->>
-
-SigAnnotationFieldDelta(delta) ::= <<
-$SigFieldDelta(delta = delta)$
-$SingleSubDelta(desc="Default value changed:", delta=delta.defaultValueDelta)$
->>
-
-SingleSubDelta(desc, delta) ::= <<
-$if(delta)$
-$desc$
-<ul>
-  <li>$DeltaTypeSwitch(delta=delta)$</li>
-</ul>
-$endif$
->>
-
-
diff --git a/tools/signature-tools/templates/model/model.stg b/tools/signature-tools/templates/model/model.stg
deleted file mode 100644
index 425ad36..0000000
--- a/tools/signature-tools/templates/model/model.stg
+++ /dev/null
@@ -1,135 +0,0 @@
-group model;
-
-ElementType(element) ::= <<
-$({$element.class.simpleName$})(element = element)$
->>
-
-Modifier(element) ::= <<
-$element$
->>
-
-SigAnnotation(element) ::= <<
-@$ElementType(element = element.type)$
-$if(element.elements)$
-{$element.elements:{$SigAnnotationElement(element=it)$}$}
-$endif$
->>
-
-SigAnnotationElement(element) ::= <<
-$element.declaringField.name$=$element.value$
->>
-
-SigAnnotationField(element) ::= <<
-$SigField(element = element)$ $if(element.defaultValue)$ default=$element.defaultValue$$endif$
->>
-
-SigArrayType(element) ::= <<
-$ElementType(element = element.componentType)$[]
->>
-
-
-SigClassDefinition(element) ::= <<
-$Annotations(element = element)$
-$Modifiers(element = element)$$element.kind$ $element:ClassReferenceLink(link_style="discreet")$
-$TypeParameters(element = element)$
-$if(element.superClass)$ extends $ElementType(element=element.superClass)$$endif$
-$if(element.interfaces)$ implements $element.interfaces:{$ElementType(element=it)$}; separator=", "$$endif$
->>
-
-ClassReferenceProjection(element) ::= <<
-$SigClassReference(element= element)$
->>
-
-SigClassReference(element) ::= <<
-$ClassReferenceLink(it = element.classDefinition, link_style="discreet")$
->>
-
-SigConstructor(element) ::= <<
-$Annotations(element= element, separator=" ")$
-$Modifiers(element= element)$
-$TypeParameters(element= element)$
-$SigExecutableMember(element= element)$
->>
-
-//FIXME add SigEnumConstantReference to format correct in either case
-SigEnumConstant(element) ::= <<
-enum constant $ElementType(element=element.type)$.$element.name$
->>
-
-SigExecutableMember(element) ::= <<
-$element.name$($element.parameters:{$SigParameter(element=it)$}; separator=", "$)
-$if(element.exceptions)$ throws $element.exceptions:{$ElementType(element=it)$}; separator=", "$$endif$
->>
-
-SigField(element) ::= <<
-$Annotations(element = element, separator="<br/>")$
-$Modifiers(element = element)$$ElementType(element=element.type)$ $element.name$
->>
-
-MethodProjection(element) ::= <<
-$SigMethod(element=element)$
->>
-
-SigMethod(element) ::= <<
-$Annotations(element=element)$
-$Modifiers(element=element)$
-$TypeParameters(element=element)$
-$ElementType(element=element.returnType)$ $SigExecutableMember(element = element)$
->>
-
-SigPackage(element) ::= <<
-$element.name$
->>
-
-SigParameter(element) ::= <<
-$Annotations(element = element, separator=" ")$
-$ElementType(element=element.type)$
->>
-
-ParameterizedTypeProjection(element) ::= <<
-$SigParameterizedType(element = element)$
->>
-
-SigParameterizedType(element) ::= <<
-$if(element.ownerType)$$ElementType(element=element.ownerType)$$endif$
-$SigClassReference(element=element.rawType)$
-$if(element.typeArguments)$&lt;$element.typeArguments:{$ElementType(element=it)$}$&gt;$endif$
->>
-
-SigPrimitiveType(element) ::= <<
-$element.name$
->>
-
-SigTypeVariableDefinition(element) ::= <<
-$element.name$$if(!element.upperBounds.empty)$ extends $element.upperBounds:{$ElementType(element=it)$}; separator=", "$$endif$
->>
-
-SigTypeVariableReference(element) ::= <<
-$element.typeVariableDefinition.name$
->>
-
-SigWildcardType(element) ::= <<
-?
-$if(element.lowerBound)$ super $ElementType(element=element.lowerBound)$$endif$
-$if(!element.upperBounds.empty)$ extends $element.upperBounds:{$ElementType(element=it)$}; separator=", "$$endif$
->>
-
-
-/* helper templates*/
-
-Modifiers(element) ::= <<
-$if(element.modifiers)$
-$element.modifiers; separator=" "$$\ $
-$endif$
->>
-
-Annotations(element, separator) ::= <<
-$if(element.annotations)$
-$element.annotations:{$SigAnnotation(element=it)$}; separator=separator$
-$separator$
-$endif$
->>
-
-TypeParameters(element) ::= <<
-$if(element.typeParameters)$ &lt;$element.typeParameters:{$SigTypeVariableDefinition(element=it)$}; separator=", "$&gt;$endif$
->>
diff --git a/tools/signature-tools/test/signature/comparator/AllDexTests.java b/tools/signature-tools/test/signature/comparator/AllDexTests.java
deleted file mode 100644
index b44dcb6..0000000
--- a/tools/signature-tools/test/signature/comparator/AllDexTests.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.comparator;
-import org.junit.runner.RunWith;
-import org.junit.runners.Suite;
-
-import signature.converter.dex.DexTestConverter;
-import signature.converter.util.ITestSourceConverter;
-
-@RunWith(Suite.class)
-@Suite.SuiteClasses({
-    AllDexTests.DexPackageCompareTest.class,
-    AllDexTests.DexClassCompareTest.class,
-    AllDexTests.DexMethodCompareTests.class,
-    AllDexTests.DexAnnotationCompareTest.class
-})
-public class AllDexTests {
-    private static ITestSourceConverter newConverter(){
-        return new DexTestConverter();
-    }
-    
-    public static class DexPackageCompareTest extends PackageCompareTest {
-        @Override public ITestSourceConverter createConverter() {
-            return newConverter();
-        }
-    }
-    
-    public static class DexClassCompareTest extends ClassCompareTest {
-        @Override public ITestSourceConverter createConverter() {
-            return newConverter();
-        }
-    }
-    
-    public static class DexMethodCompareTests extends MethodCompareTests {
-        @Override public ITestSourceConverter createConverter() {
-            return newConverter();
-        }
-    }
-    
-    public static class DexAnnotationCompareTest extends AnnotationCompareTest{
-        @Override public ITestSourceConverter createConverter() {
-            return newConverter();
-        }
-    }
-    
-    
-}
\ No newline at end of file
diff --git a/tools/signature-tools/test/signature/comparator/AllDocletTests.java b/tools/signature-tools/test/signature/comparator/AllDocletTests.java
deleted file mode 100644
index 327d931..0000000
--- a/tools/signature-tools/test/signature/comparator/AllDocletTests.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.comparator;
-import org.junit.runner.RunWith;
-import org.junit.runners.Suite;
-
-import signature.converter.doclet.DocletTestConverter;
-import signature.converter.util.ITestSourceConverter;
-
-@RunWith(Suite.class)
-@Suite.SuiteClasses({
-    AllDocletTests.DocletPackageCompareTest.class,
-    AllDocletTests.DocletClassCompareTest.class,
-    AllDocletTests.DocletMethodCompareTests.class
-})
-public class AllDocletTests {
-    private static ITestSourceConverter newConverter(){
-        return new DocletTestConverter();
-    }
-    
-    public static class DocletPackageCompareTest extends PackageCompareTest {
-        @Override public ITestSourceConverter createConverter() {
-            return newConverter();
-        }
-    }
-    
-    public static class DocletClassCompareTest extends ClassCompareTest {
-        @Override public ITestSourceConverter createConverter() {
-            return newConverter();
-        }
-    }
-    
-    public static class DocletMethodCompareTests extends MethodCompareTests {
-        @Override public ITestSourceConverter createConverter() {
-            return newConverter();
-        }
-    }
-}
\ No newline at end of file
diff --git a/tools/signature-tools/test/signature/comparator/AnnotationCompareTest.java b/tools/signature-tools/test/signature/comparator/AnnotationCompareTest.java
deleted file mode 100644
index c72b637..0000000
--- a/tools/signature-tools/test/signature/comparator/AnnotationCompareTest.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.comparator;
-
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-
-import org.junit.Test;
-
-import signature.comparator.util.AbstractComparatorTest;
-import signature.converter.util.CompilationUnit;
-import signature.model.IApi;
-
-import java.io.IOException;
-
-public abstract class AnnotationCompareTest extends AbstractComparatorTest {
-
-    @Test
-    public void testAnnotationValue() throws IOException{
-        CompilationUnit A0 = new CompilationUnit("a.A0", 
-                "package a; " +
-                "public @interface A0 {" +
-                "  A1 value() default @A1;" + 
-                "}");
-        CompilationUnit A1 = new CompilationUnit("a.A1", 
-                "package a; " +
-                "public @interface A1 {" +
-                "}");
-         CompilationUnit AnnotBDefault = new CompilationUnit("a.B", 
-                    "package a; " +
-                    "@A0 " +
-                    "public class B {}");
-         CompilationUnit AnnotB = new CompilationUnit("a.B", 
-                    "package a; " +
-                    "@A0 " +
-                    "public class B {}");
-          IApi fromApi = convert(A0, A1, AnnotBDefault);
-          IApi toApi = convert(A0, A1, AnnotB);
-          assertNull(compare(fromApi, toApi));
-    }
-    
-       @Test
-        public void testDefaultAnnotationValue() throws IOException{
-             CompilationUnit A0 = new CompilationUnit("a.A0", 
-                    "package a; " +
-                    "public @interface A0 {" +
-                    "  String value() default \"bla\";" +
-                    "}");
-             CompilationUnit A1 = new CompilationUnit("a.A0", 
-                    "package a; " +
-                    "public @interface A0 {" +
-                    "  String value();" + 
-                    "}");
-              IApi fromApi = convert(A0);
-              IApi toApi = convert(A1);
-              assertNotNull(compare(fromApi, toApi));
-        }
-}
diff --git a/tools/signature-tools/test/signature/comparator/ClassCompareTest.java b/tools/signature-tools/test/signature/comparator/ClassCompareTest.java
deleted file mode 100644
index 7171978..0000000
--- a/tools/signature-tools/test/signature/comparator/ClassCompareTest.java
+++ /dev/null
@@ -1,388 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.comparator;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertSame;
-
-import org.junit.Test;
-
-import signature.comparator.util.AbstractComparatorTest;
-import signature.compare.model.IAnnotationDelta;
-import signature.compare.model.IApiDelta;
-import signature.compare.model.IClassDefinitionDelta;
-import signature.compare.model.DeltaType;
-import signature.compare.model.ITypeReferenceDelta;
-import signature.converter.util.CompilationUnit;
-import signature.model.IApi;
-
-import java.io.IOException;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.lang.reflect.TypeVariable;
-import java.util.Set;
-
-public abstract class ClassCompareTest extends AbstractComparatorTest {
-
-    @Test
-    public void compareEqualClasses() throws IOException{
-         CompilationUnit A = new CompilationUnit("a.A", 
-                    "package a; " +
-                    "public class A {}");
-         CompilationUnit B = new CompilationUnit("a.B", 
-                    "package a; " +
-                    "public class B {}");
-          IApi fromApi = convert(A, B);
-          IApi toApi = convert(A, B);
-          assertNull(compare(fromApi, toApi));
-    }
-
-    @Test
-    public void compareMissingClass() throws IOException{
-         CompilationUnit A = new CompilationUnit("a.A", 
-                    "package a; " +
-                    "public class A {}");
-         CompilationUnit B = new CompilationUnit("a.B", 
-                    "package a; " +
-                    "public class B {}");
-          IApi fromApi = convert(A, B);
-          IApi toApi = convert(A);
-          
-          IApiDelta delta = compare(fromApi, toApi);
-          IClassDefinitionDelta classDelta = getSingleClassDelta(delta);
-          assertSame(DeltaType.REMOVED, classDelta.getType());
-    }
-    
-    @Test
-    public void compareAddedClass() throws IOException{
-         CompilationUnit A = new CompilationUnit("a.A", 
-                    "package a; " +
-                    "public class A {}");
-         CompilationUnit B = new CompilationUnit("a.B", 
-                    "package a; " +
-                    "public class B {}");
-          IApi fromApi = convert(A);
-          IApi toApi = convert(A, B);
-          
-          IApiDelta delta = compare(fromApi, toApi);
-          IClassDefinitionDelta classDelta = getSingleClassDelta(delta);
-          assertSame(DeltaType.ADDED, classDelta.getType());
-    }
-    
-    @Test
-    public void compareAnnotationsOnClass() throws IOException{
-         CompilationUnit A = new CompilationUnit("a.A", 
-                    "package a; " +
-                    "public class A {}");
-         CompilationUnit AnnotA = new CompilationUnit("a.A", 
-                    "package a; " +
-                    "@Deprecated " +
-                    "public class A {}");
-          IApi fromApi = convert(A);
-          IApi toApi = convert(AnnotA);
-          
-          IApiDelta delta = compare(fromApi, toApi);
-          IClassDefinitionDelta classDelta = getSingleClassDelta(delta);
-          
-          System.out.println(classDelta);
-          
-          Set<IAnnotationDelta> annotationDeltas = classDelta.getAnnotationDeltas();
-          assertEquals(1, annotationDeltas.size());
-          
-          IAnnotationDelta annotationDelta = annotationDeltas.iterator().next();
-          assertSame(DeltaType.ADDED, annotationDelta.getType());
-    }
-    
-    @Test
-    public void compareDefaultedAnnotationElementOnClass() throws IOException{
-        CompilationUnit annot = new CompilationUnit("a.A", 
-                "package a; " +
-                "public @interface A {" +
-                "  String name() default \"NAME\" ;" + 
-                "}");
-         CompilationUnit AnnotBDefault = new CompilationUnit("a.B", 
-                    "package a; " +
-                    "@A " +
-                    "public class B {}");
-         CompilationUnit AnnotB = new CompilationUnit("a.B", 
-                    "package a; " +
-                    "@A(name=\"NAME\") " +
-                    "public class B {}");
-          IApi fromApi = convert(annot, AnnotBDefault);
-          IApi toApi = convert(annot, AnnotB);
-          assertNull(compare(fromApi, toApi));
-    }
-    
-    @Test
-    public void compareSameInterfaces() throws IOException{
-         CompilationUnit A = new CompilationUnit("a.A", 
-                    "package a; " +
-                    "public class A implements Comparable<String>{ " +
-                    "  public int compareTo(String another){return 0;}" +
-                    "}");
-          IApi fromApi = convert(A);
-          IApi toApi = convert(A);
-          assertNull(compare(fromApi, toApi));
-    }
-    
-    @Test
-    public void compareMissingInterface() throws IOException{
-         CompilationUnit A0 = new CompilationUnit("a.A", 
-                 "package a; " +
-                 "public class A implements Cloneable{}");
-         CompilationUnit A1 = new CompilationUnit("a.A", 
-                 "package a; " +
-                 "public class A {}");
-          IApi fromApi = convert(A0);
-          IApi toApi = convert(A1);
-          IApiDelta apiDelta = compare(fromApi, toApi);
-          IClassDefinitionDelta classDelta =  getSingleClassDelta(apiDelta);
-          assertEquals(1, classDelta.getInterfaceDeltas().size());
-          ITypeReferenceDelta<?> interfaceDelta = classDelta.getInterfaceDeltas().iterator().next();
-          assertNotNull(interfaceDelta);
-    }
-    
-    @Test
-    public void compareMissingGenericInterface0() throws IOException{
-        CompilationUnit I = new CompilationUnit("a.I", 
-                "package a; " +
-                "public interface I<T>{}");
-        CompilationUnit B = new CompilationUnit("a.B", 
-                "package a; " +
-                "public class B implements I<String>{}");
-         CompilationUnit A0 = new CompilationUnit("a.A", 
-                "package a; " +
-                "public class A extends B implements I<String>{}");
-         CompilationUnit A1 = new CompilationUnit("a.A", 
-                 "package a; " +
-                 "public class A extends B {}");
-          IApi fromApi = convert(I, B, A0);
-          IApi toApi = convert(I, B, A1);
-          IApiDelta apiDelta = compare(fromApi, toApi);
-          assertNull(apiDelta);
-    }
-    
-    @Test
-    public void compareMissingGenericInterface1() throws IOException{
-        CompilationUnit I = new CompilationUnit("a.I", 
-                "package a; " +
-                "public interface I<T>{}");
-        CompilationUnit B = new CompilationUnit("a.B", 
-                "package a; " +
-                "public class B<T> implements I<T>{}");
-         CompilationUnit A0 = new CompilationUnit("a.A", 
-                "package a; " +
-                "public class A<T> extends B<T> implements I<T>{}");
-                 //generic declaration of 'T' in I<T> is A<T>
-         CompilationUnit A1 = new CompilationUnit("a.A", 
-                 "package a; " +
-                 "public class A<T> extends B<T> {}");
-                 //generic declaration of 'T' in I<T> is B<T>
-          IApi fromApi = convert(I, B, A0);
-          IApi toApi = convert(I, B, A1);
-          IApiDelta apiDelta = compare(fromApi, toApi);
-          assertNull(apiDelta);
-    }
-    
-    static interface I<T>{}
-    static class B<T> implements I<T>{}
-    static class A0<E extends Number> extends B<E> implements I<E>{}
-    static class A1<S extends Number> extends B<S>{}
-    
-    @Test
-    public void compareMissingGenericInterfaceReflection() {
-        ParameterizedType sC = (ParameterizedType)A0.class.getGenericSuperclass();
-        Type[] bounds = ((TypeVariable<?>)sC.getActualTypeArguments()[0]).getBounds();
-        Type[] a1Int = A1.class.getGenericInterfaces();
-        assertEquals(0,a1Int.length);
-    }
-    
-    @Test
-    public void compareInterfaceClosure() throws IOException{
-         CompilationUnit I0 = new CompilationUnit("a.I0", 
-                 "package a; " +
-                 "public interface I0{}");
-         CompilationUnit I1 = new CompilationUnit("a.I1", 
-                 "package a; " +
-                 "public interface I1 extends I0{}");
-         CompilationUnit C0 = new CompilationUnit("a.C0", 
-                 "package a; " +
-                 "public class C0 implements I1{}");
-         CompilationUnit C0_I1 = new CompilationUnit("a.C0", 
-                 "package a; " +
-                 "public class C0 implements I1, I0{}");
-          IApi fromApi = convert(I0, I1, C0);
-          IApi toApi = convert(I0, I1, C0_I1);
-          IApiDelta apiDelta = compare(fromApi, toApi);
-          assertNull(apiDelta);
-    }
-    
-    @Test
-    public void compareUpperBounds0() throws IOException{
-        CompilationUnit Number = new CompilationUnit("a.Number", 
-                    "package a; " +
-                    "public class Number implements java.io.Serializable{}");
-         CompilationUnit I0 = new CompilationUnit("a.I", 
-                    "package a; " +
-                    "public interface I<T extends Number & java.io.Serializable>{}");
-         CompilationUnit I1 = new CompilationUnit("a.I", 
-                     "package a; " +
-                     "public interface I<T extends Number>{}");
-          IApi fromApi = convert(I0,Number);
-          IApi toApi = convert(I1,Number);
-          IApiDelta apiDelta = compare(fromApi, toApi);
-          assertNull(apiDelta);
-    }
-    
-    @Test
-    public void compareUpperBounds1() throws IOException{
-        CompilationUnit Number = new CompilationUnit("a.Number", 
-                    "package a; " +
-                    "public class Number {}");
-         CompilationUnit I0 = new CompilationUnit("a.I", 
-                    "package a; " +
-                    "public interface I<T extends Number & java.io.Serializable>{}");
-         CompilationUnit I1 = new CompilationUnit("a.I", 
-                     "package a; " +
-                     "public interface I<T extends Number>{}");
-          IApi fromApi = convert(I0,Number);
-          IApi toApi = convert(I1,Number);
-          IApiDelta apiDelta = compare(fromApi, toApi);
-          assertNotNull(apiDelta);
-    }
-    
-    @Test
-    public void compareTypeVariables0() throws IOException{
-        CompilationUnit C0 = new CompilationUnit("a.C", 
-                    "package a; " +
-                    "public class C<T,S> {}");
-        CompilationUnit C1 = new CompilationUnit("a.C", 
-                    "package a; " +
-                    "public class C<S,T> {}");
-          IApi fromApi = convert(C0);
-          IApi toApi = convert(C1);
-          IApiDelta apiDelta = compare(fromApi, toApi);
-          assertNull(apiDelta);
-    }
-    
-    @Test
-    public void compareTypeVariables1() throws IOException{
-        CompilationUnit C0 = new CompilationUnit("a.C", 
-                    "package a; " +
-                    "public class C<T,S> {}");
-        CompilationUnit C1 = new CompilationUnit("a.C", 
-                    "package a; " +
-                    "public class C<T,S,R> {}");
-          IApi fromApi = convert(C0);
-          IApi toApi = convert(C1);
-          IApiDelta apiDelta = compare(fromApi, toApi);
-          assertNotNull(apiDelta);
-    }
-    
-    @Test
-    public void compareTypeVariables2() throws IOException{
-        CompilationUnit C0 = new CompilationUnit("a.C", 
-                    "package a; " +
-                    "public class C<T,S> {" +
-                    "  public void m(T t, S s){} " +
-                    "}");
-        CompilationUnit C1 = new CompilationUnit("a.C", 
-                    "package a; " +
-                    "public class C<S,T> {" +
-                    "  public void m(S s, T t){} " +
-                    "}");
-          IApi fromApi = convert(C0);
-          IApi toApi = convert(C1);
-          IApiDelta apiDelta = compare(fromApi, toApi);
-          assertNull(apiDelta);
-    }
-    
-    @Test
-    public void compareTypeVariables3() throws IOException{
-        CompilationUnit C0 = new CompilationUnit("a.C", 
-                    "package a; " +
-                    "public class C<T,S> {" +
-                    "  public void m(T t, S s){} " +
-                    "}");
-        CompilationUnit C1 = new CompilationUnit("a.C", 
-                    "package a; " +
-                    "public class C<S,T> {" +
-                    "  public void m(T t, S s){} " +
-                    "}");
-          IApi fromApi = convert(C0);
-          IApi toApi = convert(C1);
-          IApiDelta apiDelta = compare(fromApi, toApi);
-          assertNotNull(apiDelta);
-    }
-    
-    @Test
-    public void compareTypeVariables4() throws IOException{
-        CompilationUnit C0 = new CompilationUnit("a.C", 
-                    "package a; " +
-                    "public class C<T> {" +
-                    "  public class I{" +
-                    "    public void m(T t){}" +
-                    "  } " +
-                    "}");
-        CompilationUnit C1 = new CompilationUnit("a.C", 
-                    "package a; " +
-                    "public class C {" +
-                    "  public class I<T>{" +
-                    "    public void m(T t){}" +
-                    "  } " +
-                    "}");
-          IApi fromApi = convert(C0);
-          IApi toApi = convert(C1);
-          IApiDelta apiDelta = compare(fromApi, toApi);
-          assertNotNull(apiDelta);
-    }
-    
-    @Test
-    public void interfaceClosureTest() throws IOException{
-        CompilationUnit B = new CompilationUnit("a.B", 
-                    "package a; " +
-                    "public class  B<S> {}");
-        CompilationUnit C = new CompilationUnit("a.C", 
-                "package a; " +
-                "public class C<R> extends B<R>  {}");
-        CompilationUnit E = new CompilationUnit("a.E", 
-                "package a; " +
-                "public class E<Q> extends C<Q> {}");
-        CompilationUnit F = new CompilationUnit("a.F", 
-                "package a; " +
-                "public class F<P> extends E<P> {}");
-        CompilationUnit G = new CompilationUnit("a.G", 
-                "package a; " +
-                "public class G<O> extends F<O> {}");
-        CompilationUnit H = new CompilationUnit("a.H", 
-                "package a; " +
-                "public class H<R> extends G<R> {}");
-//        IApi fromApi = convert(B,C, E, F);
-//        IApi toApi = convert(B,C,E, F);
-          IApi fromApi = convert(B,C, E,F, G, H);
-          IApi toApi = convert(B,C,E,F, G, H);
-          
-          
-          long start = System.currentTimeMillis();
-          IApiDelta apiDelta = compare(fromApi, toApi);
-          System.out.println("compare took :" + (System.currentTimeMillis() -start) + "ms");
-          assertNull(apiDelta);
-    }
-    
-}
\ No newline at end of file
diff --git a/tools/signature-tools/test/signature/comparator/MethodCompareTests.java b/tools/signature-tools/test/signature/comparator/MethodCompareTests.java
deleted file mode 100644
index 3e94506..0000000
--- a/tools/signature-tools/test/signature/comparator/MethodCompareTests.java
+++ /dev/null
@@ -1,495 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.comparator;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-
-import java.io.IOException;
-
-import org.junit.Test;
-
-import signature.comparator.util.AbstractComparatorTest;
-import signature.compare.model.IApiDelta;
-import signature.compare.model.IClassDefinitionDelta;
-import signature.compare.model.DeltaType;
-import signature.converter.util.CompilationUnit;
-import signature.model.IApi;
-
-public abstract class MethodCompareTests extends AbstractComparatorTest {
-
-    
-    @Test
-    public void compareEqualClasses() throws IOException{
-        CompilationUnit A = new CompilationUnit("a.A", 
-                      "package a; " +
-                      "public class A {" +
-                      "  public void m(){}" +
-                      "}");
-        IApi fromApi = convert(A);
-        IApi toApi = convert(A);
-        assertNull(compare(fromApi, toApi));
-    }
-      
-    @Test
-    public void compareMissingMethod() throws IOException{
-        CompilationUnit A = new CompilationUnit("a.A", 
-                      "package a; " +
-                      "public class A {" +
-                      "  public void m(){}" +
-                      "}");
-        CompilationUnit AMissing = new CompilationUnit("a.A", 
-                      "package a; " +
-                      "public class A {" +
-                      "}");
-        IApi fromApi = convert(A);
-        IApi toApi = convert(AMissing);
-        IApiDelta delta = compare(fromApi, toApi);
-        assertNotNull(delta);
-        IClassDefinitionDelta classDelta = delta.getPackageDeltas().iterator().next().getClassDeltas().iterator().next();
-        assertEquals(1, classDelta.getMethodDeltas().size());
-        assertEquals(DeltaType.REMOVED, classDelta.getMethodDeltas().iterator().next().getType());
-    }
-      
-    @Test 
-    public void compareAddedMethod() throws IOException{
-        CompilationUnit A = new CompilationUnit("a.A", 
-                  "package a; " +
-                  "public class A {" +
-                  "  public void m(){}" +
-                  "}");
-        CompilationUnit AMissing = new CompilationUnit("a.A", 
-                  "package a; " +
-                  "public class A {" +
-                  "}");
-        IApi fromApi = convert(AMissing);
-        IApi toApi = convert(A);
-        IApiDelta delta = compare(fromApi, toApi);
-        assertNotNull(delta);
-        IClassDefinitionDelta classDelta = delta.getPackageDeltas().iterator().next().getClassDeltas().iterator().next();
-        assertEquals(1, classDelta.getMethodDeltas().size());
-        assertEquals(DeltaType.ADDED, classDelta.getMethodDeltas().iterator().next().getType());
-    }
-      
-    @Test
-    public void compareChangedMethod() throws IOException{
-        CompilationUnit A = new CompilationUnit("a.A", 
-                  "package a; " +
-                  "public class A {" +
-                  "  public void m(){}" +
-                  "}");
-        CompilationUnit AMissing = new CompilationUnit("a.A", 
-                  "package a; " +
-                  "public class A {" +
-                  "  public void m() throws Exception {}" +
-                  "}");
-        IApi fromApi = convert(AMissing);
-        IApi toApi = convert(A);
-        IApiDelta delta = compare(fromApi, toApi);
-        assertNotNull(delta);
-        IClassDefinitionDelta classDelta = delta.getPackageDeltas().iterator().next().getClassDeltas().iterator().next();
-        assertEquals(1, classDelta.getMethodDeltas().size());
-        assertEquals(DeltaType.CHANGED, classDelta.getMethodDeltas().iterator().next().getType());
-    }
-      
-    @Test
-    public void compareAddedParameterMethod() throws IOException{
-        CompilationUnit A = new CompilationUnit("a.A", 
-                  "package a; " +
-                  "public class A {" +
-                  "  public void m(){}" +
-                  "}");
-        CompilationUnit AMissing = new CompilationUnit("a.A", 
-                  "package a; " +
-                  "public class A {" +
-                  "  public void m(int i) {}" +
-                  "}");
-        IApi fromApi = convert(AMissing);
-        IApi toApi = convert(A);
-        IApiDelta delta = compare(fromApi, toApi);
-        assertNotNull(delta);
-        IClassDefinitionDelta classDelta = delta.getPackageDeltas().iterator().next().getClassDeltas().iterator().next();
-        assertEquals(2, classDelta.getMethodDeltas().size()); //one added , one removed
-    }
-      
-    @Test
-    public void compareExceptions0() throws IOException{
-        CompilationUnit E0 = new CompilationUnit("a.E0", 
-                "package a; " +
-                "public class E0 extends Exception {}");
-        CompilationUnit E1 = new CompilationUnit("a.E1", 
-                "package a; " +
-                "public class E1 extends E0 {}");
-        CompilationUnit C0 = new CompilationUnit("a.C0", 
-                 "package a; " +
-                 "public class C0 {" +
-                 "  public void m() throws E0 {}" +
-                 "}");
-        CompilationUnit C0_E1 = new CompilationUnit("a.C0", 
-                 "package a; " +
-                 "public class C0{" +
-                 "  public void m() throws E0, E1 {}" +
-                 "}");
-        IApi fromApi = convert(E0, E1, C0);
-        IApi toApi = convert(E0, E1, C0_E1);
-        IApiDelta apiDelta = compare(fromApi, toApi);
-        assertNull(apiDelta);
-    }
-    
-    @Test
-    public void compareExceptions1() throws IOException{
-        CompilationUnit E0 = new CompilationUnit("a.E0", 
-                "package a; " +
-                "public class E0 extends Exception {}");
-        CompilationUnit E1 = new CompilationUnit("a.E1", 
-                "package a; " +
-                "public class E1 extends Exception {}");
-        CompilationUnit C0 = new CompilationUnit("a.C0", 
-                 "package a; " +
-                 "public class C0 {" +
-                 "  public void m() throws E0 {}" +
-                 "}");
-        CompilationUnit C0_E1 = new CompilationUnit("a.C0", 
-                 "package a; " +
-                 "public class C0{" +
-                 "  public void m() throws E0, E1 {}" +
-                 "}");
-        IApi fromApi = convert(E0, E1, C0);
-        IApi toApi = convert(E0, E1, C0_E1);
-        IApiDelta apiDelta = compare(fromApi, toApi);
-        assertNotNull(apiDelta);
-    }
-    
-    @Test
-    public void compareRuntimeExceptions() throws IOException{
-        CompilationUnit E0 = new CompilationUnit("a.E0", 
-                 "package a; " +
-                 "public class E0 extends RuntimeException {}");
-        CompilationUnit C0 = new CompilationUnit("a.C0", 
-                 "package a; " +
-                 "public class C0{" +
-                 "  public void m() {}" +
-                 "}");
-        CompilationUnit C0_E0 = new CompilationUnit("a.C0", 
-                 "package a; " +
-                 "public class C0 {" +
-                 "  public void m() throws E0 {}" +
-                 "}");
-        IApi fromApi = convert(E0, C0);
-        IApi toApi = convert(E0, C0_E0);
-        IApiDelta apiDelta = compare(fromApi, toApi);
-        assertNull(apiDelta);
-    }
-    
-    @Test
-    public void compareAnnotations() throws IOException{
-        CompilationUnit C0 = new CompilationUnit("a.C0", 
-                 "package a; " +
-                 "public class C0{" +
-                 "  public void m(int i) {}" +
-                 "}");
-        CompilationUnit C1 = new CompilationUnit("a.C0", 
-                 "package a; " +
-                 "public class C0 {" +
-                 "  public void m(@Deprecated  int i) {}" +
-                 "}");
-        IApi fromApi = convert(C0);
-        IApi toApi = convert(C1);
-        IApiDelta apiDelta = compare(fromApi, toApi);
-        assertNotNull(apiDelta);
-    }
-    
-    @Test
-    public void compareMissingDefaultConstructor() throws IOException{
-        CompilationUnit C0 = new CompilationUnit("a.C0", 
-                 "package a; " +
-                 "public class C0{" +
-                 "  public C0() {}" +
-                 "}");
-        CompilationUnit C1 = new CompilationUnit("a.C0", 
-                 "package a; " +
-                 "public class C0 {}");
-        IApi fromApi = convert(C0);
-        IApi toApi = convert(C1);
-        IApiDelta apiDelta = compare(fromApi, toApi);
-        assertNull(apiDelta);
-    }
-        
-    @Test
-    public void compareMissingAbstractMethod() throws IOException{
-        CompilationUnit I = new CompilationUnit("a.I", 
-                 "package a; " +
-                 "public interface I{" +
-                 "  void m();" + 
-                   "}");
-        CompilationUnit C0 = new CompilationUnit("a.C0", 
-                 "package a; " +
-                 "public abstract class C0 implements I{" +
-                 "  public abstract void m(); " +
-                 "}");
-        CompilationUnit C1 = new CompilationUnit("a.C0", 
-                 "package a; " +
-                 "public abstract class C0 implements I{}");
-        IApi fromApi = convert(C0, I);
-        IApi toApi = convert(C1, I);
-        IApiDelta apiDelta = compare(fromApi, toApi);
-        assertNull(apiDelta);
-    }
-           
-    @Test
-    public void compareMissingInheritedMethod() throws IOException{
-        CompilationUnit I = new CompilationUnit("a.I", 
-                "package a; " +
-                "public class I{" +
-                "  public void m(){};" + 
-                "}");
-        CompilationUnit C0 = new CompilationUnit("a.C0", 
-                "package a; " +
-                "public class C0 extends I{" +
-                "  public void m(){}; " +
-                "}");
-        CompilationUnit C1 = new CompilationUnit("a.C0", 
-                "package a; " +
-                "public class C0 extends I{}");
-        IApi fromApi = convert(C0, I);
-        IApi toApi = convert(C1, I);
-        IApiDelta apiDelta = compare(fromApi, toApi);
-        assertNull(apiDelta);
-     }
-       
-    @Test
-    public void compareMissingInheritedMethodGeneric0() throws IOException{
-        CompilationUnit I = new CompilationUnit("a.I", 
-                "package a; " +
-                "public class I<T>{" +
-                "  public void m(T t){};" + 
-                "}");
-        CompilationUnit C0 = new CompilationUnit("a.C0", 
-                "package a; " +
-                "public class C0<T> extends I<T>{" +
-                "  public void m(T t){}; " +
-                "}");
-        CompilationUnit C1 = new CompilationUnit("a.C0", 
-                "package a; " +
-                "public class C0<T> extends I<T>{}");
-        IApi fromApi = convert(C0, I);
-        IApi toApi = convert(C1, I);
-        IApiDelta apiDelta = compare(fromApi, toApi);
-        assertNull(apiDelta);
-    }
-           
-    @Test
-    public void compareMissingInheritedMethodGeneric1() throws IOException{
-        CompilationUnit I = new CompilationUnit("a.I", 
-                "package a; " +
-                "public class I<T,S>{" +
-                "  public void m(S s){};" + 
-                "}");
-        CompilationUnit C0 = new CompilationUnit("a.C0", 
-                "package a; " +
-                "public class C0<Q, R> extends I<Q,R>{" +
-                "  public void m(R t){}; " +
-                "}");
-        CompilationUnit C1 = new CompilationUnit("a.C0", 
-                "package a; " +
-                "public class C0<Y,Z> extends I<Y,Z>{}");
-         IApi fromApi = convert(C0, I);
-         IApi toApi = convert(C1, I);
-         IApiDelta apiDelta = compare(fromApi, toApi);
-         assertNull(apiDelta);
-    }
-           
-    @Test
-    public void compareMissingInheritedMethodGeneric2() throws IOException{
-        CompilationUnit I = new CompilationUnit("a.I", 
-                "package a; " +
-                "public class I<T,S>{" +
-                "  public void m(S s){};" + 
-                "}");
-        CompilationUnit J = new CompilationUnit("a.J", 
-                "package a; " +
-                "public class J<W> extends I<Number,W>{" +
-                "  public void m(W w){};" + 
-                "}");
-        CompilationUnit C0 = new CompilationUnit("a.C0", 
-                "package a; " +
-                "public class C0<Q> extends J<Q>{" +
-                "  public void m(Q t){}; " +
-                "}");
-        CompilationUnit C1 = new CompilationUnit("a.C0", 
-                "package a; " +
-                "public class C0<Y> extends J<Y>{}");
-        IApi fromApi = convert(C0, I, J);
-        IApi toApi = convert(C1, I, J);
-        IApiDelta apiDelta = compare(fromApi, toApi);
-        assertNull(apiDelta);
-    }
-    
-    
-
-    @Test
-    public void compareMissingInheritedMethodGeneric3() throws IOException{
-        CompilationUnit Q = new CompilationUnit("a.Q", 
-                "package a; " +
-                "public class Q<S,T>{ " +
-                "  public void m(T s){} " +
-                "}");
-        
-        CompilationUnit W = new CompilationUnit("a.W", 
-                "package a; " +
-                "public class W<A,B> extends Q<A,A>{}");
-        CompilationUnit E0 = new CompilationUnit("a.E", 
-                "package a; " +
-                "public class E<C,D> extends W<C,C>{" +
-                "  public void m(C s){}" +
-                "}");
-        CompilationUnit E1 = new CompilationUnit("a.E", 
-                "package a; " +
-                "public class E<C,D> extends W<C,C>{}");
-        IApi fromApi = convert(E0, Q, W);
-        IApi toApi = convert(E1, Q, W);
-        IApiDelta apiDelta = compare(fromApi, toApi);
-        assertNull(apiDelta);
-    }
-    
-    @Test
-    public void compareMissingInheritedMethodGeneric4() throws IOException{
-        CompilationUnit Q = new CompilationUnit("a.Q", 
-                "package a; " +
-                "public class Q<S,T>{ " +
-                "  public void m(T t, S s){} " +
-                "}");
-        
-        CompilationUnit W = new CompilationUnit("a.W", 
-                "package a; " +
-                "public class W<A,B> extends Q<A,A>{}");
-        CompilationUnit E0 = new CompilationUnit("a.E", 
-                "package a; " +
-                "public class E<C,D> extends W<C,C>{" +
-                "  public void m(C s, C c){}" +
-                "}");
-        CompilationUnit E1 = new CompilationUnit("a.E", 
-                "package a; " +
-                "public class E<C,D> extends W<C,C>{}");
-        IApi fromApi = convert(E0, Q, W);
-        IApi toApi = convert(E1, Q, W);
-        IApiDelta apiDelta = compare(fromApi, toApi);
-        assertNull(apiDelta);
-    }
-    
-    @Test
-    public void compareMissingInheritedMethodGeneric5() throws IOException{
-        CompilationUnit Q = new CompilationUnit("a.Q", 
-                "package a; " +
-                "public class Q{}");
-        
-        CompilationUnit I = new CompilationUnit("a.I", 
-                "package a; " +
-                "public class I<S,T>{" +
-                "  public void m(T s){};" + 
-                "}");
-        CompilationUnit C0 = new CompilationUnit("a.C0", 
-                "package a; " +
-                "public class C0<P> extends I<P, Q>{" +
-                "  public void m(Q t){}; " +
-                "}");
-        CompilationUnit C1 = new CompilationUnit("a.C0", 
-                "package a; " +
-                "public class C0<Y> extends I<Y, Q>{}");
-        IApi fromApi = convert(C0, I, Q);
-        IApi toApi = convert(C1, I, Q);
-        IApiDelta apiDelta = compare(fromApi, toApi);
-        assertNull(apiDelta);
-    }
-    
-    
-    @Test
-    public void substitutionTest() throws IOException{
-        CompilationUnit NUMBER = new CompilationUnit("a.Number", 
-                "package a; " +
-                "public class Number{}");
-        CompilationUnit Q = new CompilationUnit("a.A", 
-                "package a; " +
-                "public class A<T>{ " +
-                "  public void m(T t){} " +
-                "}");
-        CompilationUnit E0 = new CompilationUnit("a.E", 
-                "package a; " +
-                "public class E extends A<Number>{" +
-                "  public void m(Number n){}" +
-                "}");
-        CompilationUnit E1 = new CompilationUnit("a.E", 
-                "package a; " +
-                "public class E extends A<Number>{}");
-        IApi fromApi = convert(E0, Q, NUMBER);
-        IApi toApi = convert(E1, Q, NUMBER);
-        
-        IApiDelta apiDelta = compare(fromApi, toApi);
-        assertNull(apiDelta);
-    }
-    
-    @Test
-    public void substitutionArrayTest() throws IOException{
-        CompilationUnit NUMBER = new CompilationUnit("a.Number", 
-                "package a; " +
-                "public class Number{}");
-        CompilationUnit Q = new CompilationUnit("a.A", 
-                "package a; " +
-                "public class A<T>{ " +
-                "  public void m(T[] t){} " +
-                "}");
-        CompilationUnit E0 = new CompilationUnit("a.E", 
-                "package a; " +
-                "public class E extends A<Number>{" +
-                "  public void m(Number[] n){}" +
-                "}");
-        CompilationUnit E1 = new CompilationUnit("a.E", 
-                "package a; " +
-                "public class E extends A<Number>{}");
-        IApi fromApi = convert(E0, Q, NUMBER);
-        IApi toApi = convert(E1, Q, NUMBER);
-        
-        IApiDelta apiDelta = compare(fromApi, toApi);
-        assertNull(apiDelta);
-    }
-    
-    @Test
-    public void substitutionNestedTypes() throws IOException{
-        CompilationUnit NUMBER = new CompilationUnit("a.Number", 
-                "package a; " +
-                "public class Number{}");
-        CompilationUnit Q = new CompilationUnit("a.A", 
-                "package a; " +
-                "public class A<T>{ " +
-                "  public void m(A<A<T[]>> t){} " +
-                "}");
-        CompilationUnit E0 = new CompilationUnit("a.E", 
-                "package a; " +
-                "public class E extends A<Number>{" +
-                "  public void m(A<A<Number[]>> n){}" +
-                "}");
-        CompilationUnit E1 = new CompilationUnit("a.E", 
-                "package a; " +
-                "public class E extends A<Number>{}");
-        IApi fromApi = convert(E0, Q, NUMBER);
-        IApi toApi = convert(E1, Q, NUMBER);
-        
-        IApiDelta apiDelta = compare(fromApi, toApi);
-        assertNull(apiDelta);
-    }
-}
diff --git a/tools/signature-tools/test/signature/comparator/PackageCompareTest.java b/tools/signature-tools/test/signature/comparator/PackageCompareTest.java
deleted file mode 100644
index d522186..0000000
--- a/tools/signature-tools/test/signature/comparator/PackageCompareTest.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.comparator;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-
-import org.junit.Test;
-
-import signature.comparator.util.AbstractComparatorTest;
-import signature.compare.model.IApiDelta;
-import signature.compare.model.DeltaType;
-import signature.compare.model.IPackageDelta;
-import signature.converter.util.CompilationUnit;
-import signature.model.IApi;
-
-import java.io.IOException;
-
-public abstract class PackageCompareTest extends AbstractComparatorTest{
-
-    @Test
-    public void compareEqualPackageTest0() throws IOException{
-         CompilationUnit from = new CompilationUnit("a.A", 
-                    "package a; " +
-                    "public class A {}");
-          IApi fromApi = convert(from);
-          IApi toApi = convert(from);
-          IApiDelta delta = compare(fromApi, toApi);
-          assertNull(delta);
-    }
-
-    @Test
-    public void compareEqualPackageTest1() throws IOException{
-         CompilationUnit from0 = new CompilationUnit("a.A", 
-                    "package a; " +
-                    "public class A {}");
-         CompilationUnit from1 = new CompilationUnit("a.b.A", 
-                    "package a.b; " +
-                    "public class A {}");
-          IApi fromApi = convert(from0, from1);
-          IApi toApi = convert(from0, from1);
-          assertNull(compare(fromApi, toApi));
-    }
-
-    @Test
-    public void compareRemovedPackagePackageTest1() throws IOException{
-         CompilationUnit packageA = new CompilationUnit("a.A", 
-                    "package a; " +
-                    "public class A {}");
-         CompilationUnit packageB = new CompilationUnit("a.b.A", 
-                    "package a.b; " +
-                    "public class A {}");
-          IApi fromApi = convert(packageA, packageB);
-          IApi toApi = convert(packageA);
-          IApiDelta apiDelta = compare(fromApi, toApi);
-          assertNotNull(apiDelta);
-          
-          assertEquals(1, apiDelta.getPackageDeltas().size());
-          IPackageDelta packageDelta = apiDelta.getPackageDeltas().iterator().next();
-          assertEquals(DeltaType.REMOVED, packageDelta.getType());
-    }
-
-    @Test
-    public void compareAddedPackagePackageTest1() throws IOException{
-         CompilationUnit packageA = new CompilationUnit("a.A", 
-                    "package a; " +
-                    "public class A {}");
-         CompilationUnit packageB = new CompilationUnit("a.b.A", 
-                    "package a.b; " +
-                    "public class A {}");
-          IApi fromApi = convert(packageA);
-          IApi toApi = convert(packageA, packageB);
-          IApiDelta apiDelta = compare(fromApi, toApi);
-          assertNotNull(apiDelta);
-          
-          assertEquals(1, apiDelta.getPackageDeltas().size());
-          IPackageDelta packageDelta = apiDelta.getPackageDeltas().iterator().next();
-          assertEquals(DeltaType.ADDED, packageDelta.getType());
-    }
-}
diff --git a/tools/signature-tools/test/signature/comparator/util/AbstractComparatorTest.java b/tools/signature-tools/test/signature/comparator/util/AbstractComparatorTest.java
deleted file mode 100644
index 6392dc9..0000000
--- a/tools/signature-tools/test/signature/comparator/util/AbstractComparatorTest.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.comparator.util;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-
-import org.junit.Before;
-
-import signature.compare.ApiComparator;
-import signature.compare.IApiComparator;
-import signature.compare.model.IApiDelta;
-import signature.compare.model.IClassDefinitionDelta;
-import signature.compare.model.IPackageDelta;
-import signature.converter.util.AbstractConvertTest;
-import signature.model.IApi;
-public abstract class AbstractComparatorTest extends AbstractConvertTest{
-
-    private IApiComparator comparator;
-
-    @Before
-    public void setupComparator() {
-        comparator = new ApiComparator();
-    }
-    
-    public IApiDelta compare(IApi from, IApi to){
-        return comparator.compare(from, to);
-    }
-
-    public IPackageDelta getSinglePackageDelta(IApiDelta apiDelta){
-        assertNotNull(apiDelta);
-        assertEquals(1, apiDelta.getPackageDeltas().size());
-        return apiDelta.getPackageDeltas().iterator().next();
-    }
-    
-    public IClassDefinitionDelta getSingleClassDelta(IApiDelta apiDelta){
-        IPackageDelta packageDelta = getSinglePackageDelta(apiDelta);
-        assertEquals(1, packageDelta.getClassDeltas().size());
-        return packageDelta.getClassDeltas().iterator().next();
-    }
-
-}
diff --git a/tools/signature-tools/test/signature/converter/AllDexTests.java b/tools/signature-tools/test/signature/converter/AllDexTests.java
deleted file mode 100644
index 84d26a8..0000000
--- a/tools/signature-tools/test/signature/converter/AllDexTests.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.converter;
-
-import org.junit.runner.RunWith;
-import org.junit.runners.Suite;
-
-import signature.converter.dex.DexTestConverter;
-import signature.converter.util.ITestSourceConverter;
-
-@RunWith(Suite.class)
-@Suite.SuiteClasses({
-    AllDexTests.ClassTest.class,
-    AllDexTests.PackageTest.class,
-    AllDexTests.AnnotationTest.class,
-    AllDexTests.VisibilityTest.class,
-    AllDexTests.WildcardTest.class,
-    AllDexTests.EnumTest.class
-})
-public class AllDexTests {
-    private static ITestSourceConverter newConverter(){
-        return new DexTestConverter();
-    }
-    
-    public static class ClassTest extends ConvertClassTest {
-        @Override public ITestSourceConverter createConverter() {
-            return newConverter();
-        }
-    }
-    public static class AnnotationTest extends ConvertAnnotationTest {
-        @Override public ITestSourceConverter createConverter() {
-            return newConverter();
-        }
-    }
-    public static class PackageTest extends ConvertPackageTest {
-        @Override public ITestSourceConverter createConverter() {
-            return newConverter();
-        }
-    }
-    public static class VisibilityTest extends ConvertVisibilityTest {
-        @Override public ITestSourceConverter createConverter() {
-            return newConverter();
-        }
-    }
-    
-    public static class WildcardTest extends ConvertWildcardTest {
-        @Override public ITestSourceConverter createConverter() {
-            return newConverter();
-        }
-    }
-    
-    public static class EnumTest extends ConvertEnumTest {
-        @Override public ITestSourceConverter createConverter() {
-            return newConverter();
-        }
-    }
-    
-    public static class ParameterizedTypeTest extends ConvertParameterizedTypeTest {
-        @Override public ITestSourceConverter createConverter() {
-            return newConverter();
-        }
-    }
-}
-
diff --git a/tools/signature-tools/test/signature/converter/AllDocletTests.java b/tools/signature-tools/test/signature/converter/AllDocletTests.java
deleted file mode 100644
index 610917e..0000000
--- a/tools/signature-tools/test/signature/converter/AllDocletTests.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.converter;
-
-import org.junit.runner.RunWith;
-import org.junit.runners.Suite;
-
-import signature.converter.doclet.DocletTestConverter;
-import signature.converter.util.ITestSourceConverter;
-
-@RunWith(Suite.class)
-@Suite.SuiteClasses({
-    AllDocletTests.ClassTest.class,
-    AllDocletTests.PackageTest.class,
-    AllDocletTests.AnnotationTest.class,
-    AllDocletTests.VisibilityTest.class,
-    AllDocletTests.WildcardTest.class,
-    AllDocletTests.EnumTest.class
-})
-public class AllDocletTests {
-    private static ITestSourceConverter newConverter(){
-        return new DocletTestConverter();
-    }
-    
-    public static class ClassTest extends ConvertClassTest {
-        @Override public ITestSourceConverter createConverter() {
-            return newConverter();
-        }
-    }
-    public static class AnnotationTest extends ConvertAnnotationTest {
-        @Override public ITestSourceConverter createConverter() {
-            return newConverter();
-        }
-    }
-    public static class PackageTest extends ConvertPackageTest {
-        @Override public ITestSourceConverter createConverter() {
-            return newConverter();
-        }
-    }
-    public static class VisibilityTest extends ConvertVisibilityTest {
-        @Override public ITestSourceConverter createConverter() {
-            return newConverter();
-        }
-    }
-    public static class WildcardTest extends ConvertWildcardTest {
-        @Override
-        public ITestSourceConverter createConverter() {
-            return newConverter();
-        }
-    }
-    public static class EnumTest extends ConvertEnumTest {
-        @Override public ITestSourceConverter createConverter() {
-            return newConverter();
-        }
-    }
-}
-
diff --git a/tools/signature-tools/test/signature/converter/ConvertAnnotationTest.java b/tools/signature-tools/test/signature/converter/ConvertAnnotationTest.java
deleted file mode 100644
index f53f403..0000000
--- a/tools/signature-tools/test/signature/converter/ConvertAnnotationTest.java
+++ /dev/null
@@ -1,761 +0,0 @@
-/*

- * Copyright (C) 2009 The Android Open Source Project

- *

- * Licensed under the Apache License, Version 2.0 (the "License");

- * you may not use this file except in compliance with the License.

- * You may obtain a copy of the License at

- *

- *      http://www.apache.org/licenses/LICENSE-2.0

- *

- * Unless required by applicable law or agreed to in writing, software

- * distributed under the License is distributed on an "AS IS" BASIS,

- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

- * See the License for the specific language governing permissions and

- * limitations under the License.

- */

-

-package signature.converter;

-

-import static org.junit.Assert.assertEquals;

-import static org.junit.Assert.assertSame;

-import static org.junit.Assert.assertTrue;

-

-import java.io.IOException;

-import java.util.Set;

-

-import org.junit.Test;

-

-import signature.converter.util.AbstractConvertTest;

-import signature.converter.util.CompilationUnit;

-import signature.model.IAnnotation;

-import signature.model.IAnnotationField;

-import signature.model.IApi;

-import signature.model.IArrayType;

-import signature.model.IClassDefinition;

-import signature.model.IClassReference;

-import signature.model.IEnumConstant;

-import signature.model.IPackage;

-import signature.model.IPrimitiveType;

-import signature.model.ITypeReference;

-import signature.model.Kind;

-import signature.model.impl.SigClassReference;

-import signature.model.impl.SigPrimitiveType;

-import signature.model.util.ModelUtil;

-

-public abstract class ConvertAnnotationTest extends AbstractConvertTest {

-

-    // Tests whether an annotation declaration element may be annotated with 

-    // the declared annotation.

-    @Test

-    public void convertAnnotationDefinition1() throws IOException {

-        CompilationUnit classSrc = new CompilationUnit("a.ToDo", 

-                "package a; " +

-                "public @interface ToDo {" +

-                "    @ToDo(name=\"ToDo\")" +

-                "   String name() default \"nobody\";" +

-                "}");

-        IApi api = convert(classSrc);

-        IPackage sigPackage = ModelUtil.getPackage(api, "a");

-        IClassDefinition sigClass = ModelUtil.getClass(sigPackage, "ToDo");

-        assertTrue(sigClass.getKind() == Kind.ANNOTATION);

-        assertEquals(0, sigClass.getConstructors().size());

-        assertEquals(0, sigClass.getMethods().size());

-        assertEquals(0, sigClass.getFields().size());

-        Set<IAnnotationField> annotationFields = sigClass.getAnnotationFields();

-        assertEquals(1, annotationFields.size());

-        IAnnotationField field = annotationFields.iterator().next();

-        assertEquals("name", field.getName());

-        assertEquals("String", ((IClassReference)field.getType()).getClassDefinition().getName());

-        assertEquals("nobody", field.getDefaultValue());

-        Set<IAnnotation> annotations = field.getAnnotations();

-        assertEquals(1, annotations.size());

-        IAnnotation annotation = annotations.iterator().next();

-        assertSame(sigClass, annotation.getType().getClassDefinition());

-        // TODO TEST add additional assert for annotation.getElements()

-    }

-

-    // Tests whether an annotation declaration may be annotated with 

-    // the declared annotation.

-    @Test

-    public void convertAnnotationDefinition2() throws IOException {

-        CompilationUnit classSrc = new CompilationUnit("a.ToDo", 

-                "package a; " +

-                "@ToDo\n" +

-                "public @interface ToDo {" +

-                "   String name() default \"nobody\";" +

-                "}");

-        IApi api = convert(classSrc);

-        IPackage sigPackage = ModelUtil.getPackage(api, "a");

-        IClassDefinition sigClass = ModelUtil.getClass(sigPackage, "ToDo");

-        assertTrue(sigClass.getKind() == Kind.ANNOTATION);

-        assertEquals(0, sigClass.getConstructors().size());

-        assertEquals(0, sigClass.getMethods().size());

-        assertEquals(0, sigClass.getFields().size());

-        Set<IAnnotation> annotations = sigClass.getAnnotations();

-        assertEquals(1, annotations.size());

-        IAnnotation annotation = annotations.iterator().next();

-        assertSame(sigClass, ((SigClassReference)annotation.getType()).getClassDefinition());

-        assertEquals(0, annotation.getElements().size());

-    }

-

-    @Test

-    public void convertAnnotationDefinition3() throws IOException {

-        CompilationUnit classSrc = new CompilationUnit("a.ToDo", 

-                "package a; " +

-                "public @interface ToDo {" +

-                "   String name() default \"nobody\";" +

-                "   int num() default 3;" +

-                "}");

-        IApi api = convert(classSrc);

-        IPackage sigPackage = ModelUtil.getPackage(api, "a");

-        IClassDefinition sigClass = ModelUtil.getClass(sigPackage, "ToDo");

-        assertTrue(sigClass.getKind() == Kind.ANNOTATION);

-        assertEquals(0, sigClass.getConstructors().size());

-        assertEquals(0, sigClass.getMethods().size());

-        assertEquals(0, sigClass.getFields().size());

-        Set<IAnnotationField> annotationFields = sigClass.getAnnotationFields();

-        assertEquals(2, annotationFields.size());

-        IAnnotationField name = ModelUtil.getAnnotationField(sigClass, "name");

-        IAnnotationField num = ModelUtil.getAnnotationField(sigClass, "num");

-        

-        assertEquals("name", name.getName());

-        assertEquals("num", num.getName());

-        

-        assertEquals("nobody", name.getDefaultValue());

-        assertEquals(3, num.getDefaultValue());

-    }

-    

-    

-    // tests whether default int value has the correct type and defaultValue

-    @Test

-    public void testAnnotationDefaultsInt1() throws IOException {

-        CompilationUnit src = new CompilationUnit("a.A", 

-                "package a; " +

-                "public @interface A {" +

-                "    int value() default 1;" +

-                "}");

-        IApi api = convert(src);

-        IPackage sigPackage = ModelUtil.getPackage(api, "a");

-        IClassDefinition sigClass = ModelUtil.getClass(sigPackage, "A");

-        assertTrue(sigClass.getKind() == Kind.ANNOTATION);

-        Set<IAnnotationField> annotationFields = sigClass.getAnnotationFields();

-        assertEquals(1, annotationFields.size());

-        IAnnotationField annotationField = annotationFields.iterator().next();

-        assertEquals("value", annotationField.getName());

-        assertTrue(annotationField.getType() instanceof IPrimitiveType);

-        IPrimitiveType annotationFieldType = (IPrimitiveType)annotationField.getType();

-        assertSame(SigPrimitiveType.INT_TYPE, annotationFieldType);

-        

-        assertTrue(annotationField.getDefaultValue() instanceof Integer);

-        Integer defaultValue = (Integer)annotationField.getDefaultValue();

-        assertEquals(1, defaultValue.intValue());

-    }

-

-    // tests whether default int[] value has the correct type and defaultValue

-    @Test

-    public void testAnnotationDefaultsInt2() throws IOException {

-        CompilationUnit src = new CompilationUnit("a.A", 

-                "package a; " +

-                "public @interface A {" +

-                "    int[] value() default {};" +

-                "}");

-        IApi api = convert(src);

-        IPackage sigPackage = ModelUtil.getPackage(api, "a");

-        IClassDefinition sigClass = ModelUtil.getClass(sigPackage, "A");

-        assertTrue(sigClass.getKind() == Kind.ANNOTATION);

-        Set<IAnnotationField> annotationFields = sigClass.getAnnotationFields();

-        assertEquals(1, annotationFields.size());

-        IAnnotationField field = annotationFields.iterator().next();

-        assertEquals("value", field.getName());

-        

-        assertTrue(field.getType() instanceof IArrayType);

-        assertTrue(field.getDefaultValue() instanceof Object[]);

-        assertSame(field.getDefaultValue().getClass(), Object[].class);

-        Object[] defaultValue = (Object[])field.getDefaultValue();

-        assertEquals(0, defaultValue.length);

-    }

-

-    // tests whether default int[] value has the correct type and defaultValue

-    @Test

-    public void testAnnotationDefaultsInt3() throws IOException {

-        CompilationUnit src = new CompilationUnit("a.A", 

-                "package a; " +

-                "public @interface A {" +

-                "    int[] value() default {1,2};" +

-                "}");

-        IApi api = convert(src);

-        IPackage sigPackage = ModelUtil.getPackage(api, "a");

-        IClassDefinition sigClass = ModelUtil.getClass(sigPackage, "A");

-        assertTrue(sigClass.getKind() == Kind.ANNOTATION);

-        Set<IAnnotationField> annotationFields = sigClass.getAnnotationFields();

-        assertEquals(1, annotationFields.size());

-        IAnnotationField field = annotationFields.iterator().next();

-        assertEquals("value", field.getName());

-        

-        assertTrue(field.getType() instanceof IArrayType);

-        assertTrue(field.getDefaultValue() instanceof Object[]);

-        assertSame(field.getDefaultValue().getClass(), Object[].class);

-        Object[] defaultValue = (Object[])field.getDefaultValue();

-        assertEquals(2, defaultValue.length);

-        

-        Object defaultValue0 = defaultValue[0];

-        assertTrue(defaultValue0 instanceof Integer);

-        Integer defaultValue0int = (Integer)defaultValue0;

-        assertEquals(1, defaultValue0int.intValue());

-

-        Object defaultValue1 = defaultValue[1];

-        assertTrue(defaultValue1 instanceof Integer);

-        Integer defaultValue1int = (Integer)defaultValue1;

-        assertEquals(2, defaultValue1int.intValue());

-    }

-

-

-    // tests whether default double value has the correct type and defaultValue

-    @Test

-    public void testAnnotationDefaultsDouble1() throws IOException {

-        CompilationUnit src = new CompilationUnit("a.A", 

-                "package a; " +

-                "public @interface A {" +

-                "    double value() default 1;" +

-                "}");

-        IApi api = convert(src);

-        IPackage sigPackage = ModelUtil.getPackage(api, "a");

-        IClassDefinition sigClass = ModelUtil.getClass(sigPackage, "A");

-        assertTrue(sigClass.getKind() == Kind.ANNOTATION);

-        Set<IAnnotationField> annotationFields = sigClass.getAnnotationFields();

-        assertEquals(1, annotationFields.size());

-        IAnnotationField annotationField = annotationFields.iterator().next();

-        assertEquals("value", annotationField.getName());

-        assertTrue(annotationField.getType() instanceof IPrimitiveType);

-        IPrimitiveType annotationFieldType = (IPrimitiveType)annotationField.getType();

-        assertSame(SigPrimitiveType.DOUBLE_TYPE, annotationFieldType);

-        

-        

-        assertTrue(annotationField.getDefaultValue() instanceof Double);

-        Double defaultValue = (Double)annotationField.getDefaultValue();

-        assertEquals(1.0, defaultValue.doubleValue());

-    }

-

-    // tests whether default int[] value has the correct type and defaultValue

-    @Test

-    public void testAnnotationDefaultsDouble2() throws IOException {

-        CompilationUnit src = new CompilationUnit("a.A", 

-                "package a; " +

-                "public @interface A {" +

-                "    double[] value() default {};" +

-                "}");

-        IApi api = convert(src);

-        IPackage sigPackage = ModelUtil.getPackage(api, "a");

-        IClassDefinition sigClass = ModelUtil.getClass(sigPackage, "A");

-        assertTrue(sigClass.getKind() == Kind.ANNOTATION);

-        Set<IAnnotationField> annotationFields = sigClass.getAnnotationFields();

-        assertEquals(1, annotationFields.size());

-        IAnnotationField field = annotationFields.iterator().next();

-        assertEquals("value", field.getName());

-        

-        assertTrue(field.getType() instanceof IArrayType);

-        assertTrue(field.getDefaultValue() instanceof Object[]);

-        assertSame(field.getDefaultValue().getClass(), Object[].class);

-        Object[] defaultValue = (Object[])field.getDefaultValue();

-        assertEquals(0, defaultValue.length);

-    }

-

-    // tests whether default int[] value has the correct type and defaultValue

-    @Test

-    public void testAnnotationDefaultsDouble3() throws IOException {

-        CompilationUnit src = new CompilationUnit("a.A", 

-                "package a; " +

-                "public @interface A {" +

-                "    double[] value() default {1,2.5};" +

-                "}");

-        IApi api = convert(src);

-        IPackage sigPackage = ModelUtil.getPackage(api, "a");

-        IClassDefinition sigClass = ModelUtil.getClass(sigPackage, "A");

-        assertTrue(sigClass.getKind() == Kind.ANNOTATION);

-        Set<IAnnotationField> annotationFields = sigClass.getAnnotationFields();

-        assertEquals(1, annotationFields.size());

-        IAnnotationField field = annotationFields.iterator().next();

-        assertEquals("value", field.getName());

-        

-        assertTrue(field.getType() instanceof IArrayType);

-        assertTrue(field.getDefaultValue() instanceof Object[]);

-        assertSame(field.getDefaultValue().getClass(), Object[].class);

-        Object[] defaultValue = (Object[])field.getDefaultValue();

-        assertEquals(2, defaultValue.length);

-        

-        Object defaultValue0 = defaultValue[0];

-        assertTrue(defaultValue0 instanceof Double);

-        Double defaultValue0int = (Double)defaultValue0;

-        assertEquals(1, defaultValue0int.doubleValue());

-

-        Object defaultValue1 = defaultValue[1];

-        assertTrue(defaultValue1 instanceof Double);

-        Double defaultValue1int = (Double)defaultValue1;

-        assertEquals(2.5, defaultValue1int.doubleValue());

-    }

-

-

-    // tests whether default enum value has the correct type

-    @Test

-    public void testAnnotationDefaultsEnum1() throws IOException {

-        CompilationUnit src1 = new CompilationUnit("a.A", 

-                "package a; " +

-                "public @interface A {" +

-                "    Kind value() default Kind.TWO;" +

-                "}");

-        CompilationUnit src2 = new CompilationUnit("a.Kind", 

-                "package a; " +

-                "public enum Kind {" +

-                "    ONE, TWO, THREE" +

-                "}");

-        IApi api = convert(src1, src2);

-        IPackage sigPackage = ModelUtil.getPackage(api, "a");

-        IClassDefinition sigClass = ModelUtil.getClass(sigPackage, "A");

-        assertTrue(sigClass.getKind() == Kind.ANNOTATION);

-        Set<IAnnotationField> annotationFields = sigClass.getAnnotationFields();

-        assertEquals(1, annotationFields.size());

-        IAnnotationField field = annotationFields.iterator().next();

-        assertEquals("value", field.getName());

-        assertEquals("Kind", ((IClassReference)field.getType()).getClassDefinition().getName());

-        assertTrue(field.getDefaultValue() instanceof IEnumConstant);

-        IEnumConstant defaultValue = (IEnumConstant)field.getDefaultValue();

-//        assertEquals(1, defaultValue.getOrdinal());

-        assertEquals("TWO", defaultValue.getName());

-        

-        IClassDefinition enumClass = ModelUtil.getClass(sigPackage, "Kind");

-        assertTrue(enumClass.getKind() == Kind.ENUM);

-        IEnumConstant enumTWO = null;

-        Set<IEnumConstant> enumConstants = enumClass.getEnumConstants();

-        for(IEnumConstant c : enumConstants){

-            if("TWO".equals(c.getName())) enumTWO = c;

-        }

-        assertSame(enumTWO, defaultValue);

-    }

-

-    // tests whether default enum value has the correct type

-    @Test

-    public void testAnnotationDefaultsEnum2() throws IOException {

-        CompilationUnit src1 = new CompilationUnit("a.A", 

-                "package a; " +

-                "public @interface A {" +

-                "    Kind[] value() default {};" +

-                "}");

-        CompilationUnit src2 = new CompilationUnit("a.Kind", 

-                "package a; " +

-                "public enum Kind {" +

-                "    ONE, TWO, THREE" +

-                "}");

-        IApi api = convert(src1, src2);

-        IPackage sigPackage = ModelUtil.getPackage(api, "a");

-        IClassDefinition sigClass = ModelUtil.getClass(sigPackage, "A");

-        assertTrue(sigClass.getKind() == Kind.ANNOTATION);

-        Set<IAnnotationField> annotationFields = sigClass.getAnnotationFields();

-        assertEquals(1, annotationFields.size());

-        IAnnotationField field = annotationFields.iterator().next();

-        assertEquals("value", field.getName());

-        assertTrue(field.getType() instanceof IArrayType);

-        assertTrue(field.getDefaultValue() instanceof Object[]);

-        assertSame(field.getDefaultValue().getClass(), Object[].class);

-        Object[] defaultValue = (Object[])field.getDefaultValue();

-        assertEquals(0, defaultValue.length);

-    }

-

-    // tests whether default enum value has the correct type

-    @Test

-    public void testAnnotationDefaultsEnum3() throws IOException {

-        CompilationUnit src1 = new CompilationUnit("a.A", 

-                "package a; " +

-                "public @interface A {" +

-                "    Kind[] value() default {Kind.ONE,Kind.TWO};" +

-                "}");

-        CompilationUnit src2 = new CompilationUnit("a.Kind", 

-                "package a; " +

-                "public enum Kind {" +

-                "    ONE, TWO, THREE" +

-                "}");

-        IApi api = convert(src1, src2);

-        IPackage sigPackage = ModelUtil.getPackage(api, "a");

-        IClassDefinition sigClass = ModelUtil.getClass(sigPackage, "A");

-        assertTrue(sigClass.getKind() == Kind.ANNOTATION);

-        

-        Set<IAnnotationField> annotationFields = sigClass.getAnnotationFields();

-        assertEquals(1, annotationFields.size());

-        IAnnotationField field = annotationFields.iterator().next();

-        assertEquals("value", field.getName());

-        

-        assertTrue(field.getType() instanceof IArrayType);

-        assertTrue(field.getDefaultValue() instanceof Object[]);

-        assertSame(field.getDefaultValue().getClass(), Object[].class);

-        Object[] defaultValue = (Object[])field.getDefaultValue();

-        assertEquals(2, defaultValue.length);

-        

-        IClassDefinition enumClass = ModelUtil.getClass(sigPackage, "Kind");

-        assertTrue(enumClass.getKind() == Kind.ENUM);

-        IEnumConstant enumONE = null;

-        IEnumConstant enumTWO = null;

-        Set<IEnumConstant> enumConstants = enumClass.getEnumConstants();

-        for(IEnumConstant c : enumConstants){

-            if("ONE".equals(c.getName())) enumONE = c;

-            if("TWO".equals(c.getName())) enumTWO = c;

-        }

-

-        Object defaultValue0 = defaultValue[0];

-        assertTrue(defaultValue0 instanceof IEnumConstant);

-        IEnumConstant defaultValue0enum = (IEnumConstant)defaultValue0;

-//        assertEquals(0, defaultValue0enum.getOrdinal());

-        assertEquals("ONE", defaultValue0enum.getName());

-        assertSame(enumONE, defaultValue0enum);

-

-        Object defaultValue1 = defaultValue[1];

-        assertTrue(defaultValue1 instanceof IEnumConstant);

-        IEnumConstant defaultValue1enum = (IEnumConstant)defaultValue1;

-//        assertEquals(1, defaultValue1enum.getOrdinal());

-        assertEquals("TWO", defaultValue1enum.getName());

-        assertSame(enumTWO, defaultValue1enum);

-    }

-

-    

-    @Test

-    public void testAnnotationDefaultsAnnotation1() throws IOException {

-        CompilationUnit src1 = new CompilationUnit("a.A", 

-                "package a; " +

-                "public @interface A {" +

-                "    AA aa() default @AA;" +

-                "}");

-        CompilationUnit src2 = new CompilationUnit("a.AA", 

-                "package a; " +

-                "public @interface AA {}");

-        IApi api = convert(src1, src2);

-        IPackage sigPackage = ModelUtil.getPackage(api, "a");

-        IClassDefinition sigClass = ModelUtil.getClass(sigPackage, "A");

-        assertTrue(sigClass.getKind() == Kind.ANNOTATION);

-        Set<IAnnotationField> annotationFields = sigClass.getAnnotationFields();

-        assertEquals(1, annotationFields.size());

-        IAnnotationField field = annotationFields.iterator().next();

-        assertEquals("aa", field.getName());

-        IClassReference fieldType = (IClassReference)field.getType();

-        assertEquals("AA", fieldType.getClassDefinition().getName());

-        

-        IClassDefinition aaType = ModelUtil.getClass(sigPackage, "AA");

-        assertTrue(aaType.getKind() == Kind.ANNOTATION);

-        assertSame(aaType, fieldType.getClassDefinition());

-        

-        assertTrue(field.getDefaultValue() instanceof IAnnotation);

-        IAnnotation defaultValue = (IAnnotation)field.getDefaultValue();

-        assertEquals(0, defaultValue.getElements().size());

-        assertSame(aaType, defaultValue.getType().getClassDefinition());

-    }

-

-    @Test

-    public void testAnnotationDefaultsAnnotation2() throws IOException {

-        CompilationUnit src1 = new CompilationUnit("a.A", 

-                "package a; " +

-                "public @interface A {" +

-                "    AA[] aa() default {};" +

-                "}");

-        CompilationUnit src2 = new CompilationUnit("a.AA", 

-                "package a; " +

-                "public @interface AA {}");

-        

-        IApi api = convert(src1, src2);

-        IPackage sigPackage = ModelUtil.getPackage(api, "a");

-        IClassDefinition sigClass = ModelUtil.getClass(sigPackage, "A");

-        assertTrue(sigClass.getKind() == Kind.ANNOTATION);

-        Set<IAnnotationField> annotationFields = sigClass.getAnnotationFields();

-        assertEquals(1, annotationFields.size());

-        IAnnotationField field = annotationFields.iterator().next();

-        assertEquals("aa", field.getName());

-        

-        assertTrue(field.getType() instanceof IArrayType);

-        assertTrue(field.getDefaultValue() instanceof Object[]);

-        assertSame(field.getDefaultValue().getClass(), Object[].class);

-        Object[] defaultValue = (Object[])field.getDefaultValue();

-        assertEquals(0, defaultValue.length);

-    }

-

-    @Test

-    public void testAnnotationDefaultsAnnotation3() throws IOException {

-        CompilationUnit src1 = new CompilationUnit("a.A", 

-                "package a; " +

-                "public @interface A {" +

-                "    AA[] aa() default {@AA,@AA};" +

-                "}");

-        CompilationUnit src2 = new CompilationUnit("a.AA", 

-                "package a; " +

-                "public @interface AA {}");

-        

-        IApi api = convert(src1, src2);

-        IPackage sigPackage = ModelUtil.getPackage(api, "a");

-        IClassDefinition sigClass = ModelUtil.getClass(sigPackage, "A");

-        assertTrue(sigClass.getKind() == Kind.ANNOTATION);

-        Set<IAnnotationField> annotationFields = sigClass.getAnnotationFields();

-        assertEquals(1, annotationFields.size());

-        IAnnotationField field = annotationFields.iterator().next();

-        assertEquals("aa", field.getName());

-        

-        assertTrue(field.getType() instanceof IArrayType);

-        assertTrue(field.getDefaultValue() instanceof Object[]);

-        assertSame(field.getDefaultValue().getClass(), Object[].class);

-        Object[] defaultValue = (Object[])field.getDefaultValue();

-        assertEquals(2, defaultValue.length);

-        

-        IClassDefinition aaType = ModelUtil.getClass(sigPackage, "AA");

-        assertTrue(aaType.getKind() == Kind.ANNOTATION);

-        

-        Object defaultValue0 = defaultValue[0];

-        assertTrue(defaultValue0 instanceof IAnnotation);

-        IAnnotation defaultValue0ann = (IAnnotation)defaultValue0;

-        assertSame(aaType, defaultValue0ann.getType().getClassDefinition());

-        assertEquals(0, defaultValue0ann.getElements().size());

-        

-        Object defaultValue1 = defaultValue[1];

-        assertTrue(defaultValue1 instanceof IAnnotation);

-        IAnnotation defaultValue1ann = (IAnnotation)defaultValue1;

-        assertSame(aaType, defaultValue1ann.getType().getClassDefinition());

-        assertEquals(0, defaultValue1ann.getElements().size());  

-    }

-

-

-

-    @Test

-    public void testAnnotationDefaultsString1() throws IOException {

-        CompilationUnit src = new CompilationUnit("a.A", 

-                "package a;" +

-                "public @interface A {" +

-                "    String str() default \"xxx\";" +

-                "}");

-        IApi api = convert(src);

-        IPackage sigPackage = ModelUtil.getPackage(api, "a");

-        IClassDefinition sigClass = ModelUtil.getClass(sigPackage, "A");

-        assertTrue(sigClass.getKind() == Kind.ANNOTATION);

-        Set<IAnnotationField> annotationFields = sigClass.getAnnotationFields();

-        assertEquals(1, annotationFields.size());

-        IAnnotationField field = annotationFields.iterator().next();

-        assertEquals("str", field.getName());

-        

-        assertTrue(field.getType() instanceof IClassReference);

-        assertEquals("String", ((IClassReference)field.getType()).getClassDefinition().getName());

-        

-        assertTrue(field.getDefaultValue() instanceof String);

-        String defaultValue = (String)field.getDefaultValue();

-        assertEquals("xxx", defaultValue);

-    }

-

-    @Test    

-    public void testAnnotationDefaultsString2() throws IOException {

-        CompilationUnit src = new CompilationUnit("a.A", 

-                "package a;" +

-                "public @interface A {" +

-                "    String[] str() default {};" +

-                "}");

-        IApi api = convert(src);

-        IPackage sigPackage = ModelUtil.getPackage(api, "a");

-        IClassDefinition sigClass = ModelUtil.getClass(sigPackage, "A");

-        assertTrue(sigClass.getKind() == Kind.ANNOTATION);

-        Set<IAnnotationField> annotationFields = sigClass.getAnnotationFields();

-        assertEquals(1, annotationFields.size());

-        IAnnotationField field = annotationFields.iterator().next();

-        assertEquals("str", field.getName());

-        

-        assertTrue(field.getType() instanceof IArrayType);

-        Object defaultValue = field.getDefaultValue();

-        assertTrue(defaultValue instanceof Object[]);

-        assertSame(defaultValue.getClass(), Object[].class);

-        assertEquals(0, ((Object[])defaultValue).length);

-    }

-

-    @Test    

-    public void testAnnotationDefaultsString3() throws IOException {

-        CompilationUnit src = new CompilationUnit("a.A", 

-                "package a;" +

-                "public @interface A {" +

-                "    String[] str() default {\"ONE\", \"TWO\"};" +

-                "}");

-        IApi api = convert(src);

-        IPackage sigPackage = ModelUtil.getPackage(api, "a");

-        IClassDefinition sigClass = ModelUtil.getClass(sigPackage, "A");

-        assertTrue(sigClass.getKind() == Kind.ANNOTATION);

-        Set<IAnnotationField> annotationFields = sigClass.getAnnotationFields();

-        assertEquals(1, annotationFields.size());

-        IAnnotationField field = annotationFields.iterator().next();

-        assertEquals("str", field.getName());

-        

-        assertTrue(field.getType() instanceof IArrayType);

-        assertTrue(field.getDefaultValue() instanceof Object[]);

-        assertSame(field.getDefaultValue().getClass(), Object[].class);

-        Object[] defaultValue = (Object[])field.getDefaultValue();

-        assertEquals(2, defaultValue.length);

-        

-        Object defaultValue0 = defaultValue[0];

-        assertTrue(defaultValue0 instanceof String);

-        String defaultValue0str = (String)defaultValue0;

-        assertEquals("ONE", defaultValue0str);

-

-        Object defaultValue1 = defaultValue[1];

-        assertTrue(defaultValue1 instanceof String);

-        String defaultValue1str = (String)defaultValue1;

-        assertEquals("TWO", defaultValue1str);

-    }

-

-    @Test

-    public void testAnnotationDefaultsClass1() throws IOException {

-        CompilationUnit src = new CompilationUnit("a.A", 

-                "package a;" +

-                "public @interface A {" +

-                "    Class cc() default A.class;" +

-                "}");

-        IApi api = convert(src);

-        IPackage sigPackage = ModelUtil.getPackage(api, "a");

-        IClassDefinition aType = ModelUtil.getClass(sigPackage, "A");

-        assertTrue(aType.getKind() == Kind.ANNOTATION);

-        Set<IAnnotationField> annotationFields = aType.getAnnotationFields();

-        assertEquals(1, annotationFields.size());

-        IAnnotationField field = annotationFields.iterator().next();

-        assertEquals("cc", field.getName());

-        

-        assertTrue(field.getType() instanceof IClassReference);

-        assertEquals("Class", ((IClassReference)field.getType()).getClassDefinition().getName());

-        Object defaultValue = field.getDefaultValue();

-        assertSame(aType, ((IClassReference)defaultValue).getClassDefinition());

-    }

-

-    @Test

-    public void testAnnotationDefaultsClass2() throws IOException {

-        CompilationUnit src = new CompilationUnit("a.A", 

-                "package a;" +

-                "public @interface A {" +

-                "    Class cc() default void.class;" +

-                "}");

-        IApi api = convert(src);

-        IPackage sigPackage = ModelUtil.getPackage(api, "a");

-        IClassDefinition aType = ModelUtil.getClass(sigPackage, "A");

-        assertTrue(aType.getKind() == Kind.ANNOTATION);

-        Set<IAnnotationField> annotationFields = aType.getAnnotationFields();

-        assertEquals(1, annotationFields.size());

-        IAnnotationField field = annotationFields.iterator().next();

-        assertEquals("cc", field.getName());

-        

-        assertTrue(field.getType() instanceof IClassReference);

-        assertEquals("Class", ((IClassReference)field.getType()).getClassDefinition().getName());

-        

-        Object defaultValue = field.getDefaultValue();

-        assertTrue(defaultValue instanceof IPrimitiveType);

-        assertEquals("void", ((IPrimitiveType)defaultValue).getName());

-        assertSame(SigPrimitiveType.VOID_TYPE, defaultValue);

-    }

-

-    @Test

-    public void testAnnotationDefaultsClass3() throws IOException {

-        CompilationUnit src = new CompilationUnit("a.A", 

-                "package a;" +

-                "public @interface A {" +

-                "    Class[] cc() default {};" +

-                "}");

-        IApi api = convert(src);

-        IPackage sigPackage = ModelUtil.getPackage(api, "a");

-        IClassDefinition aType = ModelUtil.getClass(sigPackage, "A");

-        assertTrue(aType.getKind() == Kind.ANNOTATION);

-        Set<IAnnotationField> annotationFields = aType.getAnnotationFields();

-        assertEquals(1, annotationFields.size());

-        IAnnotationField field = annotationFields.iterator().next();

-        assertEquals("cc", field.getName());

-        

-        assertTrue(field.getDefaultValue() instanceof Object[]);

-        assertSame(field.getDefaultValue().getClass(), Object[].class);

-        Object[] defaultValue = (Object[])field.getDefaultValue();

-        assertEquals(0, defaultValue.length);

-    }

-

-    @Test

-    public void testAnnotationDefaultsClass4() throws IOException {

-        CompilationUnit src = new CompilationUnit("a.A", 

-                "package a;" +

-                "public @interface A {" +

-                "    Class[] cc() default {A.class, void.class};" +

-                "}");

-        IApi api = convert(src);

-        IPackage sigPackage = ModelUtil.getPackage(api, "a");

-        IClassDefinition aType = ModelUtil.getClass(sigPackage, "A");

-        assertTrue(aType.getKind() == Kind.ANNOTATION);

-        Set<IAnnotationField> annotationFields = aType.getAnnotationFields();

-        assertEquals(1, annotationFields.size());

-        IAnnotationField field = annotationFields.iterator().next();

-        assertEquals("cc", field.getName());

-        

-        assertTrue(field.getDefaultValue() instanceof Object[]);

-        assertSame(field.getDefaultValue().getClass(), Object[].class);

-        Object[] defaultValue = (Object[])field.getDefaultValue();

-        assertEquals(2, defaultValue.length);

-        

-        Object defaultValue0 = defaultValue[0];

-        assertTrue(defaultValue0 instanceof ITypeReference);

-        ITypeReference defaultValue0type = (ITypeReference)defaultValue0;

-        assertSame(aType, ((IClassReference)defaultValue0type).getClassDefinition());

-

-        Object defaultValue1 = defaultValue[1];

-        assertTrue(defaultValue1 instanceof ITypeReference);

-        assertTrue(defaultValue1 instanceof IPrimitiveType);

-        IPrimitiveType defaultValue1type = (IPrimitiveType)defaultValue1;

-        assertEquals("void", defaultValue1type.getName());

-        assertSame(SigPrimitiveType.VOID_TYPE, defaultValue1type);

-    }

-    

-    @Test

-    public void testAnnotationRetentionRuntime() throws IOException {

-        CompilationUnit retention = new CompilationUnit("java.lang.annotation.Retention", 

-                "package java.lang.annotation; " +

-                "@Retention(RetentionPolicy.RUNTIME) " + 

-                //"@Target(ElementType.ANNOTATION_TYPE) " + 

-                "public @interface Retention { " +

-                "   RetentionPolicy value() default RetentionPolicy.CLASS; " +

-                "}");

-        CompilationUnit retentionPolicy = new CompilationUnit("java.lang.annotation.RetentionPolicy", 

-                "package java.lang.annotation; " +

-                "public enum RetentionPolicy { " + 

-                "    SOURCE," + 

-                "    CLASS," + 

-                "    RUNTIME" + 

-                "}");

-        CompilationUnit anno = new CompilationUnit("a.A", 

-                "package a;" +

-                "@java.lang.annotation.Retention(value=java.lang.annotation.RetentionPolicy.SOURCE)" +

-                "public @interface A{}");

-        CompilationUnit cla = new CompilationUnit("a.B",  

-                "package a;" +

-                "@A public class B{}");

-        IApi api = convert(anno, cla, retention, retentionPolicy);

-        IPackage sigPackage = ModelUtil.getPackage(api, "a");

-        IClassDefinition aType = ModelUtil.getClass(sigPackage, "B");

-        assertTrue(aType.getAnnotations().isEmpty());

-    }

-    

-    @Test

-    public void testAnnotationRetentionClass() throws IOException {

-        CompilationUnit retention = new CompilationUnit("java.lang.annotation.Retention", 

-                "package java.lang.annotation; " +

-                "@Retention(RetentionPolicy.RUNTIME) " + 

-                //"@Target(ElementType.ANNOTATION_TYPE) " + 

-                "public @interface Retention { " +

-                "   RetentionPolicy value() default RetentionPolicy.CLASS; " +

-                "}");

-        CompilationUnit retentionPolicy = new CompilationUnit("java.lang.annotation.RetentionPolicy", 

-                "package java.lang.annotation; " +

-                "public enum RetentionPolicy { " + 

-                "    SOURCE," + 

-                "    CLASS," + 

-                "    RUNTIME" + 

-                "}");

-        CompilationUnit anno = new CompilationUnit("a.A", 

-                "package a;" +

-                "@java.lang.annotation.Retention(value=java.lang.annotation.RetentionPolicy.CLASS)" +

-                "public @interface A{}");

-        CompilationUnit cla = new CompilationUnit("a.B",  

-                "package a;" +

-                "@A public class B{}");

-        IApi api = convert(anno, cla, retention, retentionPolicy);

-        IPackage sigPackage = ModelUtil.getPackage(api, "a");

-        IClassDefinition aType = ModelUtil.getClass(sigPackage, "B");

-        assertEquals(1, aType.getAnnotations().size());

-    }

-

-}

diff --git a/tools/signature-tools/test/signature/converter/ConvertClassTest.java b/tools/signature-tools/test/signature/converter/ConvertClassTest.java
deleted file mode 100644
index 5bcdcb4..0000000
--- a/tools/signature-tools/test/signature/converter/ConvertClassTest.java
+++ /dev/null
@@ -1,668 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.converter;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotSame;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertTrue;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.junit.Test;
-
-import signature.converter.util.AbstractConvertTest;
-import signature.converter.util.CompilationUnit;
-import signature.model.IAnnotation;
-import signature.model.IApi;
-import signature.model.IArrayType;
-import signature.model.IClassDefinition;
-import signature.model.IClassReference;
-import signature.model.IConstructor;
-import signature.model.IField;
-import signature.model.IMethod;
-import signature.model.IPackage;
-import signature.model.IParameter;
-import signature.model.IParameterizedType;
-import signature.model.ITypeReference;
-import signature.model.ITypeVariableDefinition;
-import signature.model.ITypeVariableReference;
-import signature.model.Kind;
-import signature.model.Modifier;
-import signature.model.impl.SigPrimitiveType;
-import signature.model.util.ModelUtil;
-
-public abstract class ConvertClassTest extends AbstractConvertTest {
-    
-    @Test
-    public void convertPackageClassTest() throws IOException {
-        IApi api = convert(new CompilationUnit("a.b.A", "package a.b; public class A{}"));
-        IPackage sigPackage = ModelUtil.getPackage(api, "a.b");
-        IClassDefinition sigClass = ModelUtil.getClass(sigPackage, "A");
-        assertEquals("a.b.A", sigClass.getQualifiedName());
-        assertEquals("A", sigClass.getName());
-        assertEquals("a.b", sigPackage.getName());
-        assertEquals(1, sigPackage.getClasses().size());
-    }
-    
-    @Test
-    public void convertClassClassTest() throws IOException {
-        IApi api = convert(new CompilationUnit("a.A", "package a; public class A{}"));
-        IPackage sigPackage = ModelUtil.getPackage(api, "a");
-        IClassDefinition sigClass = ModelUtil.getClass(sigPackage, "A");
-        assertEquals("a.A", sigClass.getQualifiedName());
-        assertEquals("A", sigClass.getName());
-        assertEquals(Kind.CLASS, sigClass.getKind());
-        assertTrue(sigClass.getModifiers().contains(Modifier.PUBLIC));
-    }
-    
-    @Test
-    public void convertClassInterfaceTest() throws IOException {
-        IApi api = convert(new CompilationUnit("a.A", "package a; public interface A{}"));
-        IPackage sigPackage = ModelUtil.getPackage(api, "a");
-        IClassDefinition sigClass = ModelUtil.getClass(sigPackage, "A");
-        assertEquals("a.A", sigClass.getQualifiedName());
-        assertEquals("A", sigClass.getName());
-        assertEquals(Kind.INTERFACE, sigClass.getKind());
-        assertTrue(sigClass.getModifiers().contains(Modifier.PUBLIC));
-    }
-    
-    @Test
-    public void convertClassEnumTest() throws IOException {
-        IApi api = convert(new CompilationUnit("a.A", "package a; public enum A{}"));
-        IPackage sigPackage = ModelUtil.getPackage(api, "a");
-        IClassDefinition sigClass = ModelUtil.getClass(sigPackage, "A");
-        assertEquals("a.A", sigClass.getQualifiedName());
-        assertEquals("A", sigClass.getName());
-        assertEquals(Kind.ENUM, sigClass.getKind());
-        assertTrue(sigClass.getModifiers().contains(Modifier.PUBLIC));
-    }
-    
-    @Test
-    public void convertClassAnnotationTest() throws IOException {
-        IApi api = convert(new CompilationUnit("a.A", "package a; public @interface A{}"));
-        IPackage sigPackage = ModelUtil.getPackage(api, "a");
-        IClassDefinition sigClass = ModelUtil.getClass(sigPackage, "A");
-        assertEquals("a.A", sigClass.getQualifiedName());
-        assertEquals("A", sigClass.getName());
-        assertEquals(Kind.ANNOTATION, sigClass.getKind());
-        assertTrue(sigClass.getModifiers().contains(Modifier.PUBLIC));
-    }
-    
-    @Test
-    public void convertAnnotationTest() throws IOException {
-        IApi api = convert(new CompilationUnit("a.A", "package a; @Deprecated public class A{}"));
-        IPackage sigPackage = ModelUtil.getPackage(api, "a");
-        IClassDefinition sigClass = ModelUtil.getClass(sigPackage, "A");
-        assertEquals("a.A", sigClass.getQualifiedName());
-        assertEquals("A", sigClass.getName());
-        assertEquals(Kind.CLASS, sigClass.getKind());
-        assertTrue(sigClass.getModifiers().contains(Modifier.PUBLIC));
-        assertEquals(1, sigClass.getAnnotations().size());
-        IAnnotation annotation = sigClass.getAnnotations().iterator().next();        
-        assertEquals("java.lang.Deprecated", annotation.getType().getClassDefinition().getQualifiedName());
-    }
-    
-    @Test
-    public void convertAnnotationOnFieldTest() throws IOException {
-        IApi api = convert(new CompilationUnit("a.A", 
-                "package a; " +
-                "public class A{" +
-                "  @Deprecated" +
-                "  public int f;" +
-                "}"));
-        IPackage sigPackage = ModelUtil.getPackage(api, "a");
-        IClassDefinition sigClass = ModelUtil.getClass(sigPackage, "A");
-        assertEquals("a.A", sigClass.getQualifiedName());
-        assertEquals("A", sigClass.getName());
-        assertEquals(Kind.CLASS, sigClass.getKind());
-        assertTrue(sigClass.getModifiers().contains(Modifier.PUBLIC));
-        assertEquals(1, sigClass.getFields().size());
-        IField field = sigClass.getFields().iterator().next(); 
-        assertEquals("f", field.getName());
-        assertEquals(1, field.getAnnotations().size());
-        IAnnotation annotation = field.getAnnotations().iterator().next();        
-        assertEquals("java.lang.Deprecated", annotation.getType().getClassDefinition().getQualifiedName());
-    }
-    
-    @Test
-    public void convertGenericClass0() throws IOException {
-        IApi api = convert(new CompilationUnit("a.A", "package a; public class A<T> {}"));
-        IPackage sigPackage = ModelUtil.getPackage(api, "a");
-        IClassDefinition sigClass = ModelUtil.getClass(sigPackage, "A");
-       assertEquals("a.A", sigClass.getQualifiedName());
-        assertEquals("A", sigClass.getName());
-        assertEquals(Kind.CLASS, sigClass.getKind());
-        assertTrue(sigClass.getModifiers().contains(Modifier.PUBLIC));
-        //test type variable
-        assertEquals(1, sigClass.getTypeParameters().size());
-        ITypeVariableDefinition variable = sigClass.getTypeParameters().get(0);
-        assertEquals("T", variable.getName());
-        //test type variable bound 
-        assertEquals(1, variable.getUpperBounds().size());
-        IClassReference bound = (IClassReference) variable.getUpperBounds().get(0);
-        assertEquals("java.lang.Object", bound.getClassDefinition().getQualifiedName());
-    }
-    
-    @Test
-    public void convertGenericClass00() throws IOException {
-        IApi api = convert(new CompilationUnit("a.A", "package a; public class A<T extends Integer> {}"));
-        IPackage sigPackage = ModelUtil.getPackage(api, "a");
-        IClassDefinition sigClass = ModelUtil.getClass(sigPackage, "A");
-        assertEquals("a.A", sigClass.getQualifiedName());
-        assertEquals("A", sigClass.getName());
-        assertEquals(Kind.CLASS, sigClass.getKind());
-        assertTrue(sigClass.getModifiers().contains(Modifier.PUBLIC));
-        //test type variable
-        assertEquals(1, sigClass.getTypeParameters().size());
-        ITypeVariableDefinition variable = sigClass.getTypeParameters().get(0);
-        assertEquals("T", variable.getName());
-        //test type variable bound 
-        assertEquals(1, variable.getUpperBounds().size());
-        IClassReference bound = (IClassReference) variable.getUpperBounds().get(0);
-        assertEquals("java.lang.Integer", bound.getClassDefinition().getQualifiedName());
-    }
-    
-    @Test
-    public void convertGenericClass1() throws IOException {
-        IApi api = convert(new CompilationUnit("a.A", "package a; public class A<S,T> {}"));
-        IPackage sigPackage = ModelUtil.getPackage(api, "a");
-        IClassDefinition sigClass = ModelUtil.getClass(sigPackage, "A");
-        assertEquals("a.A", sigClass.getQualifiedName());
-        assertEquals("A", sigClass.getName());
-        assertEquals(Kind.CLASS, sigClass.getKind());
-        assertTrue(sigClass.getModifiers().contains(Modifier.PUBLIC));
-        //test type variable
-        assertEquals(2, sigClass.getTypeParameters().size());
-        ITypeVariableDefinition variableS = sigClass.getTypeParameters().get(0);
-        assertEquals("S", variableS.getName());
-        //test type variable bound 
-        assertEquals(1, variableS.getUpperBounds().size());
-        IClassReference boundS = (IClassReference) variableS.getUpperBounds().get(0);
-        assertEquals("java.lang.Object", boundS.getClassDefinition().getQualifiedName());
-        
-        ITypeVariableDefinition variableT = sigClass.getTypeParameters().get(1);
-        assertEquals("T", variableT.getName());
-        //test type variable bound 
-        assertEquals(1, variableT.getUpperBounds().size());
-        IClassReference boundT = (IClassReference) variableT.getUpperBounds().get(0);
-        assertEquals("java.lang.Object", boundT.getClassDefinition().getQualifiedName());
-    }
-    
-    @Test
-    public void convertGenericClass2() throws IOException {
-        IApi api = convert(new CompilationUnit("a.A", "package a; public class A<S,T extends S> {}"));
-        IPackage sigPackage = ModelUtil.getPackage(api, "a");
-        IClassDefinition sigClass = ModelUtil.getClass(sigPackage, "A");
-        assertEquals("a.A", sigClass.getQualifiedName());
-        assertEquals("A", sigClass.getName());
-        assertEquals(Kind.CLASS, sigClass.getKind());
-        assertTrue(sigClass.getModifiers().contains(Modifier.PUBLIC));
-        //test type variable
-        assertEquals(2, sigClass.getTypeParameters().size());
-        ITypeVariableDefinition variableS = sigClass.getTypeParameters().get(0);
-        assertEquals("S", variableS.getName());
-        //test type variable bound 
-        assertEquals(1, variableS.getUpperBounds().size());
-        IClassReference boundS = (IClassReference) variableS.getUpperBounds().get(0);
-        assertEquals("java.lang.Object", boundS.getClassDefinition().getQualifiedName());
-        
-        ITypeVariableDefinition variableT = sigClass.getTypeParameters().get(1);
-        assertEquals("T", variableT.getName());
-        //test type variable bound 
-        assertEquals(1, variableT.getUpperBounds().size());
-        ITypeVariableReference boundT = (ITypeVariableReference) variableT.getUpperBounds().get(0);
-        assertSame(variableS, boundT.getTypeVariableDefinition());
-    }
-    
-    @Test
-    public void convertClassImplementsInterface0() throws IOException {
-        IApi api = convert(new CompilationUnit("a.A", "package a; public class A implements Cloneable {}"));
-        IPackage sigPackage = ModelUtil.getPackage(api, "a");
-        IClassDefinition sigClass = ModelUtil.getClass(sigPackage, "A");
-        assertEquals("a.A", sigClass.getQualifiedName());
-        assertEquals("A", sigClass.getName());
-        assertEquals(Kind.CLASS, sigClass.getKind());
-        assertTrue(sigClass.getModifiers().contains(Modifier.PUBLIC));
-        
-        assertEquals(1, sigClass.getInterfaces().size());
-        IClassDefinition clonable = ((IClassReference) sigClass.getInterfaces().iterator().next()).getClassDefinition();
-        assertEquals("java.lang.Cloneable", clonable.getQualifiedName());
-        assertEquals(Kind.INTERFACE, clonable.getKind());
-    }
-    
-    @Test
-    public void convertClassImplementsInterface1() throws IOException {
-        CompilationUnit classSrc = new CompilationUnit("a.A", "package a; public class A implements I {}");
-        CompilationUnit interfaceSrc = new CompilationUnit("a.I", "package a; public interface I {}");
-        IApi api = convert(classSrc, interfaceSrc);
-        IPackage sigPackage = ModelUtil.getPackage(api, "a");
-        IClassDefinition sigClass = ModelUtil.getClass(sigPackage, "A");
-        assertEquals("a.A", sigClass.getQualifiedName());
-        assertEquals("A", sigClass.getName());
-        assertEquals(Kind.CLASS, sigClass.getKind());
-        assertTrue(sigClass.getModifiers().contains(Modifier.PUBLIC));
-        
-        IClassDefinition sigInterface = ModelUtil.getClass(sigPackage, "I");
-        assertEquals("a.I", sigInterface.getQualifiedName());
-        assertEquals("I", sigInterface.getName());
-        assertEquals(Kind.INTERFACE, sigInterface.getKind());
-        assertTrue(sigInterface.getModifiers().contains(Modifier.PUBLIC));
-        
-        assertEquals(1, sigClass.getInterfaces().size());
-        IClassReference interfaze = (IClassReference) sigClass.getInterfaces().iterator().next();
-        assertEquals(Kind.INTERFACE, interfaze.getClassDefinition().getKind());
-        assertSame(sigInterface, interfaze.getClassDefinition());
-    }
-    
-    @Test
-    public void convertClassImplementsGenericInterface0() throws IOException {
-        CompilationUnit classSrc = new CompilationUnit("a.A", "package a; public class A implements I<String> {}");
-        CompilationUnit interfaceSrc = new CompilationUnit("a.I", "package a; public interface I<T> {}");
-        IApi api = convert(classSrc, interfaceSrc);
-        IPackage sigPackage = ModelUtil.getPackage(api, "a");
-        IClassDefinition sigClass = ModelUtil.getClass(sigPackage, "A");
-        assertEquals("a.A", sigClass.getQualifiedName());
-        assertEquals("A", sigClass.getName());
-        assertEquals(Kind.CLASS, sigClass.getKind());
-        assertTrue(sigClass.getModifiers().contains(Modifier.PUBLIC));
-        
-        IClassDefinition sigInterface = ModelUtil.getClass(sigPackage, "I");
-        assertEquals("a.I", sigInterface.getQualifiedName());
-        assertEquals("I", sigInterface.getName());
-        assertEquals(Kind.INTERFACE, sigInterface.getKind());
-        assertTrue(sigInterface.getModifiers().contains(Modifier.PUBLIC));
-        
-        assertEquals(1, sigClass.getInterfaces().size());
-        IParameterizedType interfaze = (IParameterizedType) sigClass.getInterfaces().iterator().next();
-        //compare raw type "I"
-        assertSame(sigInterface, interfaze.getRawType().getClassDefinition());
-        //test type argument string
-        assertEquals(1,  interfaze.getTypeArguments().size());
-        IClassReference string = (IClassReference) interfaze.getTypeArguments().get(0);
-        assertEquals("java.lang.String", string.getClassDefinition().getQualifiedName());
-    }
-    
-    @Test
-    public void convertGenericClassImplementsGenericInterface() throws IOException {
-        CompilationUnit classSrc = new CompilationUnit("a.A", "package a; public class A<T> implements I<T> {}");
-        CompilationUnit interfaceSrc = new CompilationUnit("a.I", "package a; public interface I<T> {}");
-        IApi api = convert(classSrc, interfaceSrc);
-        IPackage sigPackage = ModelUtil.getPackage(api, "a");
-        IClassDefinition sigClass = ModelUtil.getClass(sigPackage, "A");
-        assertEquals("a.A", sigClass.getQualifiedName());
-        assertEquals("A", sigClass.getName());
-        assertEquals(Kind.CLASS, sigClass.getKind());
-        assertTrue(sigClass.getModifiers().contains(Modifier.PUBLIC));
-        
-        //get type variable from class
-        assertEquals(1, sigClass.getTypeParameters().size());
-        ITypeVariableDefinition classTypeVar = sigClass.getTypeParameters().get(0);
-        assertEquals("T", classTypeVar.getName());
-        assertSame(sigClass, classTypeVar.getGenericDeclaration());
-        
-        //inspect interface
-        IClassDefinition sigInterface = ModelUtil.getClass(sigPackage, "I");
-        assertEquals("a.I", sigInterface.getQualifiedName());
-        assertEquals("I", sigInterface.getName());
-        assertEquals(Kind.INTERFACE, sigInterface.getKind());
-        assertTrue(sigInterface.getModifiers().contains(Modifier.PUBLIC));
-        
-        //get type variable from interface
-        assertEquals(1, sigInterface.getTypeParameters().size());
-        ITypeVariableDefinition interfaceTypeVar = sigInterface.getTypeParameters().get(0);
-        
-        //get implemented interface from A
-        assertEquals(1, sigClass.getInterfaces().size());
-        IParameterizedType interfaze = (IParameterizedType) sigClass.getInterfaces().iterator().next();
-        
-        //compare raw type "I"
-        assertSame(sigInterface, interfaze.getRawType().getClassDefinition());
-        
-        //test if type variable of A is type argument of I
-        assertEquals(1,  interfaze.getTypeArguments().size());
-        ITypeVariableReference argument = (ITypeVariableReference) interfaze.getTypeArguments().get(0);
-        assertSame(sigClass, argument.getTypeVariableDefinition().getGenericDeclaration());
-        assertEquals(classTypeVar, argument.getTypeVariableDefinition());
-        
-        //test that the two type parameters are not equal
-        assertNotSame(classTypeVar, interfaceTypeVar);
-        assertEquals(classTypeVar.getName(), interfaceTypeVar.getName());
-        assertNotSame(classTypeVar.getGenericDeclaration(), interfaceTypeVar.getGenericDeclaration());
-    }
-    
-    @Test
-    public void convertConstructor0() throws IOException {
-        CompilationUnit classSrc = new CompilationUnit("a.A", "package a; public class A { public A(){} }");
-        IApi api = convert(classSrc);
-        IPackage sigPackage = ModelUtil.getPackage(api, "a");
-        IClassDefinition sigClass = ModelUtil.getClass(sigPackage, "A");
-        assertEquals(1, sigClass.getConstructors().size());
-        IConstructor constructor = sigClass.getConstructors().iterator().next();
-        assertTrue(constructor.getModifiers().contains(Modifier.PUBLIC));
-    }
-    
-    @Test
-    public void convertConstructor1a() throws IOException {
-        CompilationUnit classSrc = new CompilationUnit("a.A", "package a; public class A { public class B{ } }");
-        IApi api = convert(classSrc);
-        IPackage sigPackage = ModelUtil.getPackage(api, "a");
-        IClassDefinition sigClass = ModelUtil.getClass(sigPackage, "A.B");
-        assertEquals(1, sigClass.getConstructors().size());
-        IConstructor constructor = sigClass.getConstructors().iterator().next();
-        assertTrue(constructor.getModifiers().contains(Modifier.PUBLIC));
-    }
-    
-    @Test
-    public void convertConstructor1b() throws IOException {
-        CompilationUnit classSrc = new CompilationUnit("a.A", "package a; public class A { protected class B{ } }");
-        IApi api = convert(classSrc);
-        IPackage sigPackage = ModelUtil.getPackage(api, "a");
-        IClassDefinition sigClass = ModelUtil.getClass(sigPackage, "A.B");
-        assertEquals(1, sigClass.getConstructors().size());
-        IConstructor constructor = sigClass.getConstructors().iterator().next();
-        assertTrue(constructor.getModifiers().contains(Modifier.PROTECTED));
-    }
-    
-    @Test
-    public void convertConstructor2() throws IOException {
-        CompilationUnit classSrc = new CompilationUnit("a.A", "package a; public class A {}");
-        IApi api = convert(classSrc);
-        IPackage sigPackage = ModelUtil.getPackage(api, "a");
-        IClassDefinition sigClass = ModelUtil.getClass(sigPackage, "A");
-        assertEquals(1, sigClass.getConstructors().size());
-    }
-    
-    @Test
-    public void convertConstructor3() throws IOException {
-        CompilationUnit classSrc = new CompilationUnit("a.A", "package a; public class A { public class B { public B(){}} }");
-        IApi api = convert(classSrc);
-        IPackage sigPackage = ModelUtil.getPackage(api, "a");
-        IClassDefinition sigClass = ModelUtil.getClass(sigPackage, "A.B");
-        assertEquals(1, sigClass.getConstructors().size());
-    }
-    
-    @Test
-    public void convertConstructorWithException() throws IOException {
-        CompilationUnit classSrc = new CompilationUnit("a.A", "package a; public class A { public A() throws NullPointerException{} }");
-        IApi api = convert(classSrc);
-        IPackage sigPackage = ModelUtil.getPackage(api, "a");
-        IClassDefinition sigClass = ModelUtil.getClass(sigPackage, "A");
-        assertEquals(1, sigClass.getConstructors().size());
-        IConstructor constructor = sigClass.getConstructors().iterator().next();
-        assertTrue(constructor.getModifiers().contains(Modifier.PUBLIC));
-        assertEquals(1, constructor.getExceptions().size());
-        IClassReference exception = (IClassReference) constructor.getExceptions().iterator().next();
-        assertEquals("java.lang.NullPointerException", exception.getClassDefinition().getQualifiedName());
-    }
-    
-    @Test
-    public void convertConstructorWithParameter() throws IOException {
-        CompilationUnit classSrc = new CompilationUnit("a.A", "package a; public class A { public A(String param){} }");
-        IApi api = convert(classSrc);
-        IPackage sigPackage = ModelUtil.getPackage(api, "a");
-        IClassDefinition sigClass = ModelUtil.getClass(sigPackage, "A");
-        assertEquals(1, sigClass.getConstructors().size());
-        IConstructor constructor = sigClass.getConstructors().iterator().next();
-        assertTrue(constructor.getModifiers().contains(Modifier.PUBLIC));
-        assertEquals(1, constructor.getParameters().size());
-        IParameter param = constructor.getParameters().get(0);
-        assertEquals("java.lang.String", ((IClassReference)param.getType()).getClassDefinition().getQualifiedName());
-    }
-    
-    @Test
-    public void convertConstructorWithGenericParameter() throws IOException {
-        CompilationUnit classSrc = new CompilationUnit("a.A", "package a; public class A<T> { public A(T param){} }");
-        IApi api = convert(classSrc);
-        IPackage sigPackage = ModelUtil.getPackage(api, "a");
-        IClassDefinition sigClass = ModelUtil.getClass(sigPackage, "A");
-        assertEquals(1, sigClass.getConstructors().size());
-        IConstructor constructor = sigClass.getConstructors().iterator().next();
-        assertTrue(constructor.getModifiers().contains(Modifier.PUBLIC));
-        assertEquals(1, constructor.getParameters().size());
-        IParameter param = constructor.getParameters().get(0);
-        ITypeVariableDefinition paramType = ((ITypeVariableReference)param.getType()).getTypeVariableDefinition();
-        assertEquals("T", paramType.getName());
-        assertSame(sigClass, paramType.getGenericDeclaration());
-    }
-    
-    @Test
-    public void convertVoidMethod() throws IOException {
-        CompilationUnit classSrc = new CompilationUnit("a.A", "package a; public class A { public void m(){} }");
-        IApi api = convert(classSrc);
-        IPackage sigPackage = ModelUtil.getPackage(api, "a");
-        IClassDefinition sigClass = ModelUtil.getClass(sigPackage, "A");
-        assertEquals(1, sigClass.getMethods().size());
-        IMethod method = sigClass.getMethods().iterator().next();
-        assertTrue(method.getModifiers().contains(Modifier.PUBLIC));
-        assertEquals("m", method.getName());
-        assertSame(SigPrimitiveType.VOID_TYPE, method.getReturnType());
-    }
-    
-    @Test
-    public void convertArrayMethod() throws IOException {
-        CompilationUnit classSrc = new CompilationUnit("a.A", "package a; public class A { public String[] m(){ return null; } }");
-        IApi api = convert(classSrc);
-        IPackage sigPackage = ModelUtil.getPackage(api, "a");
-        IClassDefinition sigClass = ModelUtil.getClass(sigPackage, "A");
-        assertEquals(1, sigClass.getMethods().size());
-        IMethod method = sigClass.getMethods().iterator().next();
-        assertTrue(method.getModifiers().contains(Modifier.PUBLIC));
-        assertEquals("m", method.getName());
-        IArrayType arrayType = (IArrayType) method.getReturnType();
-        IClassDefinition clazz = ((IClassReference) arrayType.getComponentType()).getClassDefinition();
-        assertEquals("java.lang.String", clazz.getQualifiedName());
-    }
-    
-     @Test
-    public void testParameterConformance1() throws IOException {
-           IApi api = convert(new CompilationUnit("test.A", 
-                "package test; " +
-                   "import java.util.List;" +
-                   "public class A<T> {" +
-                   "  public String[] a;" +
-                   "  public String[] b;" +
-                   "  public List<String> c;" +
-                   "  public List<String> d;" +
-                   "  public List<T> e;" +
-                   "  public List<T> f;" +
-                   "}"
-           ));
-        IPackage p = ModelUtil.getPackage(api, "test");
-        assertEquals("test", p.getName());
-        IClassDefinition c = ModelUtil.getClass(p, "A");
-        assertEquals("A", c.getName());
-        assertEquals("test.A", c.getQualifiedName());
-        
-        Map<String, IField> fields = new HashMap<String, IField>();
-        for(IField f : c.getFields()){
-            fields.put(f.getName(), f);
-        }
-        assertSame(((IClassReference)((IArrayType)fields.get("a").getType()).getComponentType()).getClassDefinition(), ((IClassReference)((IArrayType)fields.get("b").getType()).getComponentType()).getClassDefinition());
-        assertSame(((IParameterizedType)fields.get("c").getType()).getRawType().getClassDefinition(), ((IParameterizedType)fields.get("d").getType()).getRawType().getClassDefinition());
-        assertSame(((IParameterizedType)fields.get("e").getType()).getRawType().getClassDefinition(), ((IParameterizedType)fields.get("f").getType()).getRawType().getClassDefinition());
-        
-        ITypeReference type = fields.get("f").getType();
-        assertTrue(type instanceof IParameterizedType);
-        ITypeReference typeArgument = ((IParameterizedType)type).getTypeArguments().get(0);
-        ITypeVariableDefinition typeParameter = c.getTypeParameters().get(0);
-        assertSame(((ITypeVariableReference)typeArgument).getTypeVariableDefinition(), typeParameter);
-    }
-
-    @Test
-    public void testParameterConformance2() throws IOException {
-           IApi api = convert(new CompilationUnit("test.A", 
-                "package test; " +
-                   "public class A<T> {" +
-                   "  public <T> T foo(T t){return null;}" +
-                   "}"
-           ));
-        IPackage p = ModelUtil.getPackage(api, "test");
-        assertEquals("test", p.getName());
-
-        IPackage sigPackage = ModelUtil.getPackage(api, "test");
-        IClassDefinition sigClass = ModelUtil.getClass(sigPackage, "A");
-        ITypeVariableDefinition t = sigClass.getTypeParameters().get(0);
-        
-        IMethod sigMethod = sigClass.getMethods().iterator().next();
-        ITypeVariableDefinition t1 = sigMethod.getTypeParameters().get(0);
-        IParameter param = sigMethod.getParameters().get(0);
-        ITypeReference t2 = param.getType();
-        ITypeReference t3 = sigMethod.getReturnType();
-
-        assertSame(t1, ((ITypeVariableReference)t2).getTypeVariableDefinition());
-        assertSame(((ITypeVariableReference)t2).getTypeVariableDefinition(), ((ITypeVariableReference)t3).getTypeVariableDefinition());
-        
-        assertNotSame(t, t1);
-    }
-    
-    @Test
-    public void testInnerReferenceToOuterTypeVariable() throws IOException {
-           IApi api = convert(new CompilationUnit("test.A", 
-                "package test; " +
-                "public class A<T> {" +
-                "  public class B {" +
-                "    public T f;" +
-                "  }  " +
-                "}"
-        ));
-        IPackage p = ModelUtil.getPackage(api, "test");
-        assertEquals("test", p.getName());
-
-        IPackage sigPackage = ModelUtil.getPackage(api, "test");
-        IClassDefinition sigClass = ModelUtil.getClass(sigPackage, "A");
-        ITypeVariableDefinition t = sigClass.getTypeParameters().get(0);
-        
-        IClassDefinition innerClass = ModelUtil.getClass(sigPackage, "A.B");
-        IField field = ModelUtil.getField(innerClass, "f");
-        
-        assertSame(t, ((ITypeVariableReference)field.getType()).getTypeVariableDefinition());
-    }
-    
-    
-    @Test
-    public void convertTypeVariableMultipleUpperBound() throws IOException {
-        String source = 
-            "package a; " +
-            "public class A<T extends Comparable<T> & java.io.Serializable> {}";
-            IApi api = convert(new CompilationUnit("a.A", source));
-            IPackage sigPackage = ModelUtil.getPackage(api, "a");
-            IClassDefinition sigClass = ModelUtil.getClass(sigPackage, "A");
-            
-            List<ITypeVariableDefinition> typeParameters = sigClass.getTypeParameters();
-            assertEquals(1, typeParameters.size());
-            
-            ITypeVariableDefinition typeVariable = typeParameters.get(0);
-            List<ITypeReference> upperBounds = typeVariable.getUpperBounds();
-            assertEquals(2, upperBounds.size());
-            ITypeReference firstBound = upperBounds.get(0);
-            ITypeReference secondBound = upperBounds.get(1);
-            
-            assertTrue(firstBound instanceof IParameterizedType);
-            
-            IParameterizedType parametrizedType = (IParameterizedType)firstBound;
-            
-            IClassReference rawType = parametrizedType.getRawType();
-            assertEquals("Comparable", rawType.getClassDefinition().getName());
-            assertEquals(1, parametrizedType.getTypeArguments().size());
-            ITypeVariableReference variable = (ITypeVariableReference) parametrizedType.getTypeArguments().get(0);
-            assertSame(typeVariable, variable.getTypeVariableDefinition());
-            
-            assertTrue(secondBound instanceof IClassReference);
-            IClassReference secondBoundClass = (IClassReference) secondBound;
-            assertEquals("Serializable", secondBoundClass.getClassDefinition().getName());
-    }
-    
-    @Test
-    public void convertPrivateStaticInnerClass0() throws IOException {
-        String source = 
-            "package a; " +
-            "public class A { " +
-            "  private static class I{}" +
-            "  private transient Object i = new I(); " +
-            "}";
-            IApi api = convert(Visibility.PRIVATE, new CompilationUnit("a.A", source));
-            IPackage sigPackage = ModelUtil.getPackage(api, "a");
-            IClassDefinition innerClass = ModelUtil.getClass(sigPackage, "A.I");
-            assertEquals("A.I", innerClass.getName());
-            Set<IConstructor> constructors = innerClass.getConstructors();
-            assertEquals(1, constructors.size());
-    }
-    
-    @Test
-    public void convertPrivateStaticInnerClass1() throws IOException {
-        String source = 
-            "package a; " +
-            "public class A {" + 
-            "  private static class B {" + 
-            "    public static class C {}" + 
-            "  }" + 
-            "}";
-            IApi api = convert(new CompilationUnit("a.A", source));
-            IPackage sigPackage = ModelUtil.getPackage(api, "a");
-            assertEquals(1, sigPackage.getClasses().size());
-    }
-    
-    /**
-     * Tests whether the first constructor argument is removed.
-     */
-    @Test
-    public void convertNonStaticInnerClassConstructor0() throws IOException {
-        String source = 
-            "package a; " +
-            "public class A {" + 
-            "  public class B {" + 
-            "      public B(){}" +
-            "  }" + 
-            "}";
-            IApi api = convert(new CompilationUnit("a.A", source));
-            IPackage sigPackage = ModelUtil.getPackage(api, "a");
-            IClassDefinition innerClass = ModelUtil.getClass(sigPackage, "A.B");
-            assertEquals(1, innerClass.getConstructors().size());
-            Set<IConstructor> constructors = innerClass.getConstructors();
-            IConstructor first = constructors.iterator().next();
-            //implicit A.this reference must be removed
-            assertEquals(0, first.getParameters().size());
-    }
-    
-    /**
-     * Tests whether the first constructor argument is removed.
-     */
-    @Test
-    public void convertNonStaticInnerClassConstructor1() throws IOException {
-        String source = 
-            "package a; " +
-            "public class A {" + 
-            "  public class B {}" + 
-            "}";
-            IApi api = convert(new CompilationUnit("a.A", source));
-            IPackage sigPackage = ModelUtil.getPackage(api, "a");
-            IClassDefinition innerClass = ModelUtil.getClass(sigPackage, "A.B");
-            assertEquals(1, innerClass.getConstructors().size());
-            Set<IConstructor> constructors = innerClass.getConstructors();
-            IConstructor first = constructors.iterator().next();
-            //implicit A.this reference must be removed
-            assertEquals(0, first.getParameters().size());
-    }
-    
-    
-   
-}
diff --git a/tools/signature-tools/test/signature/converter/ConvertEnumTest.java b/tools/signature-tools/test/signature/converter/ConvertEnumTest.java
deleted file mode 100644
index 98ebd61..0000000
--- a/tools/signature-tools/test/signature/converter/ConvertEnumTest.java
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.converter;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.assertFalse;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-import org.junit.Test;
-
-import signature.converter.util.AbstractConvertTest;
-import signature.converter.util.CompilationUnit;
-import signature.model.IApi;
-import signature.model.IArrayType;
-import signature.model.IClassDefinition;
-import signature.model.IClassReference;
-import signature.model.IConstructor;
-import signature.model.IEnumConstant;
-import signature.model.IField;
-import signature.model.IMethod;
-import signature.model.IPackage;
-import signature.model.IParameter;
-import signature.model.Kind;
-import signature.model.Modifier;
-import signature.model.util.ModelUtil;
-
-public abstract class ConvertEnumTest extends AbstractConvertTest {
-    
-    @Test
-    public void testEnum1() throws IOException {
-        IApi api = convert(new CompilationUnit("test.A", 
-                "package test; " +
-                "public enum A {" +
-                "  ONE, TWO, THREE" +
-                "}"));
-        IPackage sigPackage = ModelUtil.getPackage(api, "test");
-        IClassDefinition c = ModelUtil.getClass(sigPackage, "A");
-        assertNotNull(c);
-        assertTrue(c.getKind() == Kind.ENUM);
-
-        Set<IEnumConstant> constants = c.getEnumConstants();
-        assertEquals(3, constants.size());
-        
-        Set<String> constantNames = new HashSet<String>();
-        for (IEnumConstant constant : constants) {
-            constantNames.add(constant.getName());
-        }
-        
-        assertTrue(constantNames.contains("ONE"));
-        assertTrue(constantNames.contains("TWO"));
-        assertTrue(constantNames.contains("THREE"));
-        
-//        IEnumConstant[] enumConstants = new IEnumConstant[3];
-//        for (IEnumConstant enumConstant : constants) {
-//            enumConstants[enumConstant.getOrdinal()] = enumConstant;
-//            assertEquals(0, enumConstant.getAnnotations().size());
-//            assertSame(c, enumConstant.getType());
-//        }
-//        
-//        assertEquals("ONE", enumConstants[0].getName());
-//        assertEquals("TWO", enumConstants[1].getName());
-//        assertEquals("THREE", enumConstants[2].getName());
-    }
-
-    @Test
-    public void testEnum2() throws IOException {
-        IApi api = convert(new CompilationUnit("test.A", 
-                "package test; " +
-                "public enum A {" +
-                "  ONE, TWO, THREE;" +
-                "  public static A FOUR = ONE;" +
-                "}"));
-        IPackage sigPackage = ModelUtil.getPackage(api, "test");
-        IClassDefinition c = ModelUtil.getClass(sigPackage, "A");
-        assertNotNull(c);
-        assertTrue(c.getKind() == Kind.ENUM);
-
-        Set<IEnumConstant> constants = c.getEnumConstants();
-        assertEquals(3, constants.size());
-        
-        Set<IField> fields = c.getFields();
-        assertEquals(1, fields.size());
-        IField field = c.getFields().iterator().next();
-        
-        assertEquals("FOUR", field.getName());
-        assertSame(c, ((IClassReference)field.getType()).getClassDefinition());
-    }
-
-
-   @Test
-    public void testEnum3() throws IOException {
-        IApi api = convert(new CompilationUnit("test.A", 
-                "package test; " +
-                "public enum A {" +
-                "  ONE(1), TWO(2), THREE(3);" +
-                "  A(int value){}" +
-                "}"));
-        IPackage sigPackage = ModelUtil.getPackage(api, "test");
-        IClassDefinition c = ModelUtil.getClass(sigPackage, "A");
-        assertNotNull(c);
-        assertTrue(c.getKind() == Kind.ENUM);
-
-        Set<IEnumConstant> constants = c.getEnumConstants();
-        assertEquals(3, constants.size());
-        
-        Set<IConstructor> ctors = c.getConstructors();
-        assertEquals(0, ctors.size());
-
-        Set<IMethod> methods = c.getMethods();
-        assertEquals(2, methods.size());
-        Map<String, IMethod> map = new HashMap<String, IMethod>();
-        for(IMethod m : methods){
-            map.put(m.getName(), m);
-        }
-        
-        IMethod values = map.get("values");
-        assertNotNull(values);
-        assertEquals(0, values.getParameters().size());
-        assertTrue(values.getReturnType() instanceof IArrayType);
-        assertSame(c, ((IClassReference)((IArrayType)values.getReturnType()).getComponentType()).getClassDefinition());
-        assertTrue(c.getModifiers().contains(Modifier.PUBLIC));
-        assertFalse(c.getModifiers().contains(Modifier.STATIC));
-        assertTrue(c.getModifiers().contains(Modifier.FINAL));
-        
-        IMethod valueOf = map.get("valueOf");
-        assertNotNull(valueOf);
-        assertEquals(1, valueOf.getParameters().size());
-        IParameter param = valueOf.getParameters().iterator().next();
-        assertEquals("java.lang.String", ((IClassReference)param.getType()).getClassDefinition().getQualifiedName());
-        assertSame(c, ((IClassReference)valueOf.getReturnType()).getClassDefinition());
-    }
-   
-   @Test
-   public void testEnum4() throws IOException {
-       IApi api = convert(new CompilationUnit("test.A", 
-               "package test; " +
-               "public enum A {" +
-               "  ONE { void m(){} }, TWO{ void m(){} };" +
-               "  abstract void m();" +
-               "}"));
-       IPackage sigPackage = ModelUtil.getPackage(api, "test");
-       IClassDefinition c = ModelUtil.getClass(sigPackage, "A");
-       assertNotNull(c);
-       assertTrue(c.getKind() == Kind.ENUM);
-
-       Set<IEnumConstant> constants = c.getEnumConstants();
-       assertEquals(2, constants.size());
-       
-       Set<IConstructor> ctors = c.getConstructors();
-       assertEquals(0, ctors.size());
-
-       Set<IMethod> methods = c.getMethods();
-       assertEquals(2, methods.size());
-       Map<String, IMethod> map = new HashMap<String, IMethod>();
-       for(IMethod m : methods){
-           map.put(m.getName(), m);
-       }
-       
-       IMethod values = map.get("values");
-       assertNotNull(values);
-       assertEquals(0, values.getParameters().size());
-       assertTrue(values.getReturnType() instanceof IArrayType);
-       assertSame(c, ((IClassReference)((IArrayType)values.getReturnType()).getComponentType()).getClassDefinition());
-       assertTrue(c.getModifiers().contains(Modifier.PUBLIC));
-       assertFalse(c.getModifiers().contains(Modifier.STATIC));
-       assertFalse(c.getModifiers().contains(Modifier.FINAL));
-   }
-
-}
diff --git a/tools/signature-tools/test/signature/converter/ConvertPackageTest.java b/tools/signature-tools/test/signature/converter/ConvertPackageTest.java
deleted file mode 100644
index edd2a41..0000000
--- a/tools/signature-tools/test/signature/converter/ConvertPackageTest.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*

- * Copyright (C) 2009 The Android Open Source Project

- *

- * Licensed under the Apache License, Version 2.0 (the "License");

- * you may not use this file except in compliance with the License.

- * You may obtain a copy of the License at

- *

- *      http://www.apache.org/licenses/LICENSE-2.0

- *

- * Unless required by applicable law or agreed to in writing, software

- * distributed under the License is distributed on an "AS IS" BASIS,

- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

- * See the License for the specific language governing permissions and

- * limitations under the License.

- */

-

-package signature.converter;

-

-import static org.junit.Assert.assertEquals;

-

-import java.io.IOException;

-

-import org.junit.Test;

-

-import signature.converter.util.AbstractConvertTest;

-import signature.converter.util.CompilationUnit;

-import signature.model.IAnnotation;

-import signature.model.IApi;

-import signature.model.IPackage;

-import signature.model.util.ModelUtil;

-

-public abstract class ConvertPackageTest extends AbstractConvertTest {

-

-    // tests whether package annotations are returned

-    @Test

-    public void testPackageAnnotation() throws IOException {

-        CompilationUnit packageSrc = new CompilationUnit("a.package-info", "@Deprecated package a;");

-        CompilationUnit classSrc = new CompilationUnit("a.X", "package a; public class X{}");

-        IApi api = convert(classSrc, packageSrc);

-        IPackage sigPackage = ModelUtil.getPackage(api, "a");

-        assertEquals(1, sigPackage.getAnnotations().size());

-        IAnnotation annotation = sigPackage.getAnnotations().iterator().next();        

-        assertEquals("java.lang.Deprecated", annotation.getType().getClassDefinition().getQualifiedName());

-    }

-        

-    // tests that package-info is not returned as class 

-    @Test

-    public void testNumberOfClasses1() throws IOException {

-        CompilationUnit packageSrc = new CompilationUnit("a.package-info", "@Deprecated package a;");

-        CompilationUnit classSrc = new CompilationUnit("a.X", "package a; public class X{}");

-        IApi api = convert(classSrc, packageSrc);

-        IPackage sigPackage = ModelUtil.getPackage(api, "a");

-        assertEquals(1, sigPackage.getClasses().size());

-    }

-        

-    // tests that nested classes are returned as package classes 

-    @Test

-    public void testNumberOfClasses2() throws IOException {

-        CompilationUnit src = new CompilationUnit("a.X",

-                "package a;" +

-                "public class X{" +

-                "   public static class Y{}" +

-                "}");

-        IApi api = convert(src);

-        IPackage sigPackage = ModelUtil.getPackage(api, "a");

-        assertEquals(2, sigPackage.getClasses().size());

-    }

-        

-}
\ No newline at end of file
diff --git a/tools/signature-tools/test/signature/converter/ConvertParameterizedTypeTest.java b/tools/signature-tools/test/signature/converter/ConvertParameterizedTypeTest.java
deleted file mode 100644
index 653d42f..0000000
--- a/tools/signature-tools/test/signature/converter/ConvertParameterizedTypeTest.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.converter;
-
-import static org.junit.Assert.*;
-
-import java.io.IOException;
-import java.lang.reflect.Field;
-import java.lang.reflect.ParameterizedType;
-import org.junit.Test;
-
-import signature.converter.util.AbstractConvertTest;
-import signature.converter.util.CompilationUnit;
-import signature.model.IApi;
-import signature.model.IClassDefinition;
-import signature.model.IField;
-import signature.model.IPackage;
-import signature.model.IParameterizedType;
-import signature.model.ITypeReference;
-import signature.model.util.ModelUtil;
-
-public abstract class ConvertParameterizedTypeTest extends AbstractConvertTest {
-    /**
-     * [L, a, /, A, $, B, <, L, j, a, v, a, /, l, a, n, g, /, I, n, t, e, g, e, r, ;, >, ;]
-     * '$' - separated
-     * @throws IOException
-     */
-    @Test
-    public void convertParameterizedType() throws IOException {
-        String source = 
-        "package a; " +
-        "public class A{" +
-        "  public class B<T> {} " +
-        "  public A.B<Integer> f; "+
-        "}";
-        IApi api = convert(new CompilationUnit("a.A", source));
-        IPackage sigPackage = ModelUtil.getPackage(api, "a");
-        IClassDefinition sigClass = ModelUtil.getClass(sigPackage, "A");
-        IField field = ModelUtil.getField(sigClass, "f");
-        
-        ITypeReference type = field.getType();
-        assertTrue(type instanceof IParameterizedType);
-        
-        IParameterizedType parametrizedType = (IParameterizedType)type;
-        ITypeReference ownerType = parametrizedType.getOwnerType();
-        assertNotNull(ownerType);
-    }
-    
-    @Test
-    public void convertWildcardLowerBound() throws IOException {
-        String clazz = 
-        "package a; " +
-        "public final class A<T> implements I<T>{ " +
-        " abstract class Super{} " +
-        " final class Sub extends Super implements I<T>{} " +
-        "}";
-        String interfaze = 
-            "package a; " +
-            "public interface I <T>{}";
-        IApi api = convert(Visibility.PRIVATE, new CompilationUnit("a.A", clazz),new CompilationUnit("a.I", interfaze));
-        IPackage sigPackage = ModelUtil.getPackage(api, "a");
-        IClassDefinition sigClass = ModelUtil.getClass(sigPackage, "A.Sub");
-        System.out.println(sigClass);
-    }
-    
-    public class A{
-      public class B<T> {}
-      public A.B<Integer> f;
-    }
-   
-    @Test
-    public void reflectionTest0() throws SecurityException, NoSuchFieldException{
-        Field field = A.class.getDeclaredField("f");
-        ParameterizedType paramType = (ParameterizedType)field.getGenericType();
-        assertNotNull(paramType.getOwnerType());
-    }
-    
-    public static class C<T>{}
-    
-    ConvertParameterizedTypeTest.C<String> f;
-     
-      @Test
-      public void reflectionTest1() throws SecurityException, NoSuchFieldException{
-          Field field = ConvertParameterizedTypeTest.class.getDeclaredField("f");
-          ParameterizedType paramType = (ParameterizedType)field.getGenericType();
-          assertNotNull(paramType.getOwnerType());
-      }
-      
-      public static class E<T>{
-          static class F<Q>{}
-          E.F<String> f;
-      }
-      
-       
-     @Test
-    public void reflectionTest2() throws SecurityException, NoSuchFieldException {
-        Field field = E.class.getDeclaredField("f");
-        ParameterizedType paramType = (ParameterizedType) field.getGenericType();
-        assertNotNull(paramType.getOwnerType());
-    }
-}
diff --git a/tools/signature-tools/test/signature/converter/ConvertVisibilityTest.java b/tools/signature-tools/test/signature/converter/ConvertVisibilityTest.java
deleted file mode 100644
index 09fc32f..0000000
--- a/tools/signature-tools/test/signature/converter/ConvertVisibilityTest.java
+++ /dev/null
@@ -1,173 +0,0 @@
-/*

- * Copyright (C) 2009 The Android Open Source Project

- *

- * Licensed under the Apache License, Version 2.0 (the "License");

- * you may not use this file except in compliance with the License.

- * You may obtain a copy of the License at

- *

- *      http://www.apache.org/licenses/LICENSE-2.0

- *

- * Unless required by applicable law or agreed to in writing, software

- * distributed under the License is distributed on an "AS IS" BASIS,

- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

- * See the License for the specific language governing permissions and

- * limitations under the License.

- */

-

-package signature.converter;

-

-import static org.junit.Assert.assertEquals;

-import static org.junit.Assert.assertNotNull;

-

-import java.io.IOException;

-import java.util.Set;

-

-import org.junit.Test;

-

-import signature.converter.Visibility;

-import signature.converter.util.AbstractConvertTest;

-import signature.converter.util.CompilationUnit;

-import signature.model.IApi;

-import signature.model.IClassDefinition;

-import signature.model.IMethod;

-import signature.model.IPackage;

-import signature.model.util.ModelUtil;

-

-public abstract class ConvertVisibilityTest extends AbstractConvertTest {

-

-    @Test

-    public void testVisibilityMethods1() throws IOException {

-        CompilationUnit src = new CompilationUnit("a.A", 

-                "package a;" +

-                "public class A{" +

-                "   public void foo1(){}" +

-                "   protected void foo2(){}" +

-                "   void foo3(){}" +

-                "   private void foo4(){}" +

-                "}");

-

-        IApi api = convert(Visibility.PUBLIC, src);

-        IPackage p = ModelUtil.getPackage(api, "a");

-        IClassDefinition c = ModelUtil.getClass(p, "A");

-        Set<IMethod> methods = c.getMethods();

-        assertEquals(1, methods.size());

-    }

-    

-    @Test

-    public void testVisibilityMethods2() throws IOException {

-        CompilationUnit src = new CompilationUnit("a.A", 

-                "package a;" +

-                "public class A{" +

-                "   public void foo1(){}" +

-                "   protected void foo2(){}" +

-                "   void foo3(){}" +

-                "   private void foo4(){}" +

-                "}");

-

-        IApi api = convert(Visibility.PROTECTED, src);

-        IPackage p = ModelUtil.getPackage(api, "a");

-        IClassDefinition c = ModelUtil.getClass(p, "A");

-        Set<IMethod> methods = c.getMethods();

-        assertEquals(2, methods.size());

-    }

-    

-    @Test

-    public void testVisibilityMethods3() throws IOException {

-        CompilationUnit src = new CompilationUnit("a.A", 

-                "package a;" +

-                "public class A{" +

-                "   public void foo1(){}" +

-                "   protected void foo2(){}" +

-                "   void foo3(){}" +

-                "   private void foo4(){}" +

-                "}");

-

-        IApi api = convert(Visibility.PACKAGE, src);

-        IPackage p = ModelUtil.getPackage(api, "a");

-        IClassDefinition c = ModelUtil.getClass(p, "A");

-        Set<IMethod> methods = c.getMethods();

-        assertEquals(3, methods.size());

-    }

-    

-    @Test

-    public void testVisibilityMethods4() throws IOException {

-        CompilationUnit src = new CompilationUnit("a.A", 

-                "package a;" +

-                "public class A{" +

-                "   public void foo1(){}" +

-                "   protected void foo2(){}" +

-                "   void foo3(){}" +

-                "   private void foo4(){}" +

-                "}");

-

-        IApi api = convert(Visibility.PRIVATE, src);

-        IPackage p = ModelUtil.getPackage(api, "a");

-        IClassDefinition c = ModelUtil.getClass(p, "A");

-        Set<IMethod> methods = c.getMethods();

-        assertEquals(4, methods.size());

-    }

-    

-    @Test

-    public void testVisibility1() throws IOException {

-        CompilationUnit src = new CompilationUnit("a.X1", 

-                "package a;" +

-                "public class X1{" +

-                "   static class X2{}" +

-                "   protected static class X3{}" +

-                "   private static class X4{}" +

-                "}");

-

-        IApi api = convert(Visibility.PUBLIC, src);

-        IPackage sigPackage = ModelUtil.getPackage(api, "a");

-        assertEquals(1, sigPackage.getClasses().size());

-    }

-

-    @Test

-    public void testVisibility2() throws IOException {

-        CompilationUnit src = new CompilationUnit("a.X1", 

-                "package a;" +

-                "public class X1{" +

-                "   static class X2{}" +

-                "   protected static class X3{}" +

-                "   private static class X4{}" +

-                "}");

-

-        IApi api = convert(Visibility.PROTECTED, src);

-        IPackage sigPackage = ModelUtil.getPackage(api, "a");

-        assertEquals(2, sigPackage.getClasses().size());

-        assertNotNull(ModelUtil.getClass(sigPackage, "X1.X3"));

-    }

-

-    @Test

-    public void testVisibility3() throws IOException {

-        CompilationUnit src = new CompilationUnit("a.X1", 

-                "package a;" +

-                "public class X1{" +

-                "   static class X2{}" +

-                "   protected static class X3{}" +

-                "   private static class X4{}" +

-                "}");

-

-        IApi api = convert(Visibility.PACKAGE, src);

-        IPackage sigPackage = ModelUtil.getPackage(api, "a");

-        assertEquals(3, sigPackage.getClasses().size());

-        assertNotNull(ModelUtil.getClass(sigPackage, "X1.X2"));

-    }

-    

-    @Test

-    public void testVisibility4() throws IOException {

-        CompilationUnit src = new CompilationUnit("a.X1", 

-                "package a;" +

-                "public class X1{" +

-                "   static class X2{}" +

-                "   protected static class X3{}" +

-                "   private static class X4{}" +

-                "}");

-

-        IApi api = convert(Visibility.PRIVATE, src);

-        IPackage sigPackage = ModelUtil.getPackage(api, "a");

-        assertEquals(4, sigPackage.getClasses().size());

-        assertNotNull(ModelUtil.getClass(sigPackage, "X1.X4"));

-    }

-

-}
\ No newline at end of file
diff --git a/tools/signature-tools/test/signature/converter/ConvertWildcardTest.java b/tools/signature-tools/test/signature/converter/ConvertWildcardTest.java
deleted file mode 100644
index d18c568..0000000
--- a/tools/signature-tools/test/signature/converter/ConvertWildcardTest.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.converter;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import org.junit.Test;
-
-import signature.converter.util.AbstractConvertTest;
-import signature.converter.util.CompilationUnit;
-import signature.model.IApi;
-import signature.model.IClassDefinition;
-import signature.model.IClassReference;
-import signature.model.IField;
-import signature.model.IPackage;
-import signature.model.IParameterizedType;
-import signature.model.ITypeReference;
-import signature.model.IWildcardType;
-import signature.model.util.ModelUtil;
-
-import java.io.IOException;
-
-public abstract class ConvertWildcardTest extends AbstractConvertTest {
-    
-    @Test
-    public void convertWildcardUpperBound() throws IOException {
-        String source = 
-            "package a; " +
-            "public class A{" +
-            "  public java.util.Set<? extends Number> f; "+
-            "}";
-            IApi api = convert(new CompilationUnit("a.A", source));
-            IPackage sigPackage = ModelUtil.getPackage(api, "a");
-            IClassDefinition sigClass = ModelUtil.getClass(sigPackage, "A");
-            IField field = ModelUtil.getField(sigClass, "f");
-            
-            ITypeReference type = field.getType();
-            assertTrue(type instanceof IParameterizedType);
-            
-            IParameterizedType parametrizedType = (IParameterizedType)type;
-            
-            IClassDefinition rawType = parametrizedType.getRawType().getClassDefinition();
-            assertEquals("Set", rawType.getName());
-            
-            assertEquals(1, parametrizedType.getTypeArguments().size());
-            IWildcardType wildcardType = (IWildcardType) parametrizedType.getTypeArguments().get(0);
-            assertEquals(1, wildcardType.getUpperBounds().size());
-            ITypeReference upperBound = wildcardType.getUpperBounds().get(0);
-            assertTrue(upperBound instanceof IClassReference);
-            
-            assertEquals("Number", ((IClassReference)upperBound).getClassDefinition().getName());
-    }    
-    
-    @Test
-    public void convertWildcardLowerBound() throws IOException {
-        String source = 
-        "package a; " +
-        "public class A{" +
-        "  public java.util.Set<? super Number> f; "+
-        "}";
-        IApi api = convert(new CompilationUnit("a.A", source));
-        IPackage sigPackage = ModelUtil.getPackage(api, "a");
-        IClassDefinition sigClass = ModelUtil.getClass(sigPackage, "A");
-        IField field = ModelUtil.getField(sigClass, "f");
-        
-        ITypeReference type = field.getType();
-        assertTrue(type instanceof IParameterizedType);
-        
-        IParameterizedType parametrizedType = (IParameterizedType)type;
-        
-        IClassDefinition rawType = parametrizedType.getRawType().getClassDefinition();
-        assertEquals("Set", rawType.getName());
-        
-        assertEquals(1, parametrizedType.getTypeArguments().size());
-        IWildcardType wildcardType = (IWildcardType) parametrizedType.getTypeArguments().get(0);
-        assertEquals(1, wildcardType.getUpperBounds().size());
-        ITypeReference upperBound = wildcardType.getUpperBounds().get(0);
-        assertTrue(upperBound instanceof IClassReference);
-        assertEquals("Object", ((IClassReference)upperBound).getClassDefinition().getName());
-        
-        ITypeReference lowerBound = wildcardType.getLowerBound();
-        assertTrue(lowerBound instanceof IClassReference);
-        assertEquals("Number", ((IClassReference)lowerBound).getClassDefinition().getName());
-    }
-}
diff --git a/tools/signature-tools/test/signature/converter/dex/DexExternalizerTest.java b/tools/signature-tools/test/signature/converter/dex/DexExternalizerTest.java
deleted file mode 100644
index 8e27da5..0000000
--- a/tools/signature-tools/test/signature/converter/dex/DexExternalizerTest.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.converter.dex;
-
-import org.junit.Test;
-
-import signature.converter.Visibility;
-import signature.io.IApiExternalizer;
-import signature.io.impl.BinaryApi;
-import signature.model.IApi;
-
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.HashSet;
-
-public class DexExternalizerTest {
-    
-    @Test
-    public void testExternalizer() throws IOException{
-        DexToSigConverter converter = new DexToSigConverter();
-        IApi api = converter.convertApi("Dex Tests", DexUtil.getDexFiles(new HashSet<String>(Arrays.asList(new String[]{"resources/javaCore.dex"}))), Visibility.PRIVATE);
-        System.setProperty("sun.io.serialization.extendedDebugInfo", "true");
-        IApiExternalizer externalizer = new BinaryApi();
-        externalizer.externalizeApi("dex-spec", api);
-    }
-}
diff --git a/tools/signature-tools/test/signature/converter/dex/DexTestConverter.java b/tools/signature-tools/test/signature/converter/dex/DexTestConverter.java
deleted file mode 100644
index b6b90fa..0000000
--- a/tools/signature-tools/test/signature/converter/dex/DexTestConverter.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.converter.dex;
-
-import dex.reader.util.JavaSource;
-import dex.reader.util.JavaSourceToDexUtil;
-import dex.structure.DexFile;
-import signature.converter.Visibility;
-import signature.converter.dex.DexToSigConverter;
-import signature.converter.util.AbstractTestSourceConverter;
-import signature.converter.util.CompilationUnit;
-import signature.model.IApi;
-
-import java.io.IOException;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-
-public class DexTestConverter extends AbstractTestSourceConverter {
-
-    public IApi convert(Visibility visibility, Set<CompilationUnit> units) throws IOException {
-        JavaSourceToDexUtil toDexUtil = new JavaSourceToDexUtil();
-        DexToSigConverter converter = new DexToSigConverter();
-        Set<JavaSource> sources = new HashSet<JavaSource>();
-        for (CompilationUnit unit : units) {
-            sources.add(new JavaSource(unit.getName(), unit.getSource()));
-        }
-        DexFile dexFile = toDexUtil.getAllFrom(sources);
-        return converter.convertApi("Dex Tests", Collections.singleton(dexFile), visibility);
-    }
-
-}
diff --git a/tools/signature-tools/test/signature/converter/dex/DexUtilTest.java b/tools/signature-tools/test/signature/converter/dex/DexUtilTest.java
deleted file mode 100644
index ff005fb..0000000
--- a/tools/signature-tools/test/signature/converter/dex/DexUtilTest.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.converter.dex;
-
-
-import dex.reader.DexTestsCommon;
-import dex.reader.util.JavaSource;
-import dex.reader.util.JavaSourceToDexUtil;
-import dex.structure.DexClass;
-import dex.structure.DexFile;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import signature.converter.dex.DexToSigConverter;
-import signature.model.impl.SigPackage;
-import static signature.converter.dex.DexUtil.*;
-
-import java.io.IOException;
-
-import static org.junit.Assert.*;
-
-public class DexUtilTest extends DexTestsCommon {
-
-    private JavaSourceToDexUtil dexUtil;
-    private DexToSigConverter converter;
-    
-    @Before
-    public void setupDexUtil(){
-        dexUtil = new JavaSourceToDexUtil();
-        converter = new DexToSigConverter();
-    }
-    
-    @Test
-    public void convertPackageTest(){
-        SigPackage aPackage = converter.convertPackage("a");
-        assertEquals("a", aPackage.getName());
-        
-        aPackage = converter.convertPackage("a.b.c");
-        assertEquals("a.b.c", aPackage.getName());
-    }
-    
-    @Test
-    public void getPackageNameTest(){
-        assertEquals("",getPackageName("LA;"));
-        assertEquals("a",getPackageName("La/A;"));
-        assertEquals("a.b.c",getPackageName("La/b/c/A;"));
-    }
-    
-    @Test
-    public void getClassNameTest(){
-        assertEquals("A",getClassName("LA;"));
-        assertEquals("A",getClassName("La/A;"));
-        assertEquals("A",getClassName("La/b/c/A;"));
-    }
-    
-    @Test
-    public void hasGenericSignatureTest() throws IOException {
-        DexFile dexFile = dexUtil.getFrom(new JavaSource("A", "public class A{}"));
-        DexClass dexClass = getClass(dexFile, "LA;");
-        assertFalse(hasGenericSignature(dexClass));
-
-        dexFile = dexUtil.getFrom(new JavaSource("B", "public class B<T>{}"));
-        dexClass = getClass(dexFile, "LB;");
-        assertTrue(hasGenericSignature(dexClass));
-    }
-    
-    @Test
-    public void getGenericSignatureTest() throws IOException {
-        DexFile dexFile =  dexUtil.getFrom(new JavaSource("A", "public class A{}"));
-        DexClass dexClass = getClass(dexFile, "LA;");
-        assertNull(getGenericSignature(dexClass));
-        
-        dexFile =  dexUtil.getFrom(new JavaSource("B", "public class B<T>{}"));
-        dexClass = getClass(dexFile, "LB;");
-        assertEquals("<T:Ljava/lang/Object;>Ljava/lang/Object;", getGenericSignature(dexClass));
-    }
-    
-    
-    
-}
diff --git a/tools/signature-tools/test/signature/converter/dex/GenericSignatureParserTest.java b/tools/signature-tools/test/signature/converter/dex/GenericSignatureParserTest.java
deleted file mode 100644
index 52d73f8..0000000
--- a/tools/signature-tools/test/signature/converter/dex/GenericSignatureParserTest.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.converter.dex;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertSame;
-import dex.reader.DexTestsCommon;
-import dex.reader.util.JavaSource;
-import dex.reader.util.JavaSourceToDexUtil;
-import dex.structure.DexClass;
-import dex.structure.DexFile;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import signature.converter.dex.DexToSigConverter;
-import signature.converter.dex.DexUtil;
-import signature.converter.dex.GenericSignatureParser;
-import signature.model.impl.SigClassDefinition;
-import signature.model.util.TypePool;
-
-import java.io.IOException;
-
-public class GenericSignatureParserTest extends DexTestsCommon{
-    
-    private DexToSigConverter converter;
-    private JavaSourceToDexUtil dexUtil;
-    private GenericSignatureParser parser;
-
-    @Before
-    public void setupConverter(){
-        converter = new DexToSigConverter();
-        dexUtil = new JavaSourceToDexUtil();
-        parser = new GenericSignatureParser(new TypePool(), converter);
-    }
-    
-    @Test
-    public void getGenericSignatureTest() throws IOException {
-        DexFile  dexFile =  dexUtil.getFrom(new JavaSource("B", "public class B<T>{}"));
-        DexClass dexClass = getClass(dexFile, "LB;");
-        assertEquals("<T:Ljava/lang/Object;>Ljava/lang/Object;", DexUtil.getGenericSignature(dexClass));
-        SigClassDefinition sigClass = converter.convertClass(dexClass);
-        
-        parser.parseForClass(sigClass, DexUtil.getGenericSignature(dexClass));
-        //type parameter name
-        assertEquals(1, parser.formalTypeParameters.size());
-        assertEquals("T", parser.formalTypeParameters.get(0).getName());
-        //type parameter declaration
-        assertSame(sigClass, parser.formalTypeParameters.get(0).getGenericDeclaration());
-        //type parameter upper bounds
-        assertEquals(1, parser.formalTypeParameters.get(0).getUpperBounds().size());
-//        IType type = parser.formalTypeParameters.get(0).getUpperBounds().get(0);
-        
-    }
-}
diff --git a/tools/signature-tools/test/signature/converter/doclet/DocletTestConverter.java b/tools/signature-tools/test/signature/converter/doclet/DocletTestConverter.java
deleted file mode 100644
index 8e867ddb..0000000
--- a/tools/signature-tools/test/signature/converter/doclet/DocletTestConverter.java
+++ /dev/null
@@ -1,182 +0,0 @@
-/*

- * Copyright (C) 2009 The Android Open Source Project

- *

- * Licensed under the Apache License, Version 2.0 (the "License");

- * you may not use this file except in compliance with the License.

- * You may obtain a copy of the License at

- *

- *      http://www.apache.org/licenses/LICENSE-2.0

- *

- * Unless required by applicable law or agreed to in writing, software

- * distributed under the License is distributed on an "AS IS" BASIS,

- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

- * See the License for the specific language governing permissions and

- * limitations under the License.

- */

-

-package signature.converter.doclet;

-

-import java.io.File;

-import java.io.FileWriter;

-import java.io.IOException;

-import java.io.PrintWriter;

-import java.io.StringWriter;

-import java.lang.reflect.Constructor;

-import java.util.HashSet;

-import java.util.Set;

-

-import signature.converter.Visibility;

-import signature.converter.doclet.DocletToSigConverter;

-import signature.converter.util.CompilationUnit;

-import signature.model.IApi;

-import signature.model.util.ModelUtil;

-

-import com.sun.javadoc.RootDoc;

-import com.sun.tools.javac.util.Context;

-import com.sun.tools.javac.util.ListBuffer;

-import com.sun.tools.javac.util.Options;

-import com.sun.tools.javadoc.JavadocTool;

-import com.sun.tools.javadoc.Messager;

-import com.sun.tools.javadoc.ModifierFilter;

-import com.sun.tools.javadoc.RootDocImpl;

-

-public class DocletTestConverter extends signature.converter.util.AbstractTestSourceConverter {

-

-    static String sourcepath;

-    static String separator;

-    

-    static {

-        separator = System.getProperty("file.separator");

-

-        sourcepath = System.getProperty("java.io.tmpdir");

-        sourcepath = sourcepath + separator + "cts" + separator;

-        System.out.println(">> "+sourcepath);

-    }

-

-    public IApi convert(Visibility visibility, Set<CompilationUnit> units) throws IOException {

-        try {

-            Set<String> packages = new HashSet<String>();

-            for(CompilationUnit u : units){

-                putSource(u);

-                String p = ModelUtil.getPackageName(u.getName());

-                assert p.length() > 0 : "default package not supported by doclets";

-                packages.add(p);

-            }

-            

-            RootDoc root = getRootDoc(visibility, packages);

-

-            DocletToSigConverter converter = new DocletToSigConverter();

-            

-            IApi api = converter.convertDocletRoot("Doclet Test", root, visibility, packages);

-            return api;

-        }

-        finally {

-            removeSources();

-        }

-    }

-    

-    public static void putSource(CompilationUnit source) throws IOException {

-        String directory = sourcepath;

-        String filename = source.getName();    // a.b.C

-        int pos = filename.indexOf(".");

-        while(pos > 0) {

-            directory = directory + filename.substring(0, pos) + separator;

-            filename = filename.substring(pos+1);

-            pos = filename.indexOf(".");

-        }

-        

-        File file = new File(directory, filename + ".java");

-        File parent = file.getParentFile();

-        parent.mkdirs();

-        

-        FileWriter wr = new FileWriter(file);

-        wr.write(source.getSource());

-        wr.close();

-    }

-

-    private static void removeSources() {

-        File file = new File(sourcepath);

-        removeFile(file);

-    }

-    

-    private static void removeFile(File file){

-        if(file.isDirectory()){

-            for(File f : file.listFiles()) removeFile(f);

-        }

-        file.delete();

-    }

-

-    private static RootDoc getRootDoc(Visibility visibility, java.util.Set<String> packages) throws IOException  {

-        long accessModifier = 0;

-        if(visibility == Visibility.PUBLIC){

-            accessModifier = 

-                com.sun.tools.javac.code.Flags.PUBLIC;    // 0x1

-        }

-        if(visibility == Visibility.PROTECTED){

-            accessModifier = 

-                com.sun.tools.javac.code.Flags.PUBLIC    // 0x1

-                | com.sun.tools.javac.code.Flags.PROTECTED;    // 0x4

-        }

-        if(visibility == Visibility.PACKAGE){

-            accessModifier = 

-                com.sun.tools.javac.code.Flags.PUBLIC    // 0x1

-                | com.sun.tools.javac.code.Flags.PROTECTED    // 0x4

-                | com.sun.tools.javadoc.ModifierFilter.PACKAGE; // 0x80000000

-        }

-        if(visibility == Visibility.PRIVATE){

-            accessModifier = 

-                com.sun.tools.javac.code.Flags.PUBLIC    // 0x1

-                | com.sun.tools.javac.code.Flags.PROTECTED    // 0x4

-                | com.sun.tools.javadoc.ModifierFilter.PACKAGE // 0x80000000

-                | com.sun.tools.javac.code.Flags.PRIVATE;    // 0x2

-        }

-

-        ModifierFilter showAccess = new ModifierFilter(accessModifier);

-        boolean breakiterator = false;

-        boolean quiet = false;

-        boolean legacy = false;

-        boolean docClasses = false;

-        

-        String docLocale = "";

-        String encoding = null;

-        ListBuffer<String> javaNames = new ListBuffer<String>();

-        for(String p : packages)

-            javaNames.append(p);

-        

-        ListBuffer<String[]> options = new ListBuffer<String[]>();

-    

-        

-//        String sourcepath = "//D:/Documents/Projects/08_CTS/signature-tools/signature-tools/test/";

-        options.append(new String[]{"-sourcepath", sourcepath});

-        

-        ListBuffer<String> subPackages = new ListBuffer<String>();

-        ListBuffer<String> excludedPackages = new ListBuffer<String>();

-

-        Context context = new Context();

-        Options compOpts = Options.instance(context);

-        compOpts.put("-sourcepath", sourcepath);

-        

-        Constructor<Messager> c;

-        try {

-//            c = Messager.class.getDeclaredConstructor(Context.class, String.class);

-//            c.setAccessible(true);

-//            c.newInstance(context, "SigTest");

-            c = Messager.class.getDeclaredConstructor(Context.class, String.class, PrintWriter.class, PrintWriter.class, PrintWriter.class);

-            c.setAccessible(true);

-            PrintWriter err = new PrintWriter(new StringWriter());

-            PrintWriter warn = new PrintWriter(new StringWriter());

-            PrintWriter notice = new PrintWriter(new StringWriter());

-            c.newInstance(context, "SigTest", err, warn, notice);

-        } catch (Exception e) {

-            throw new RuntimeException(e);

-        }

-

-        JavadocTool comp = JavadocTool.make0(context);

-        RootDocImpl root = comp.getRootDocImpl(docLocale, encoding, showAccess,

-                javaNames.toList(), options.toList(), breakiterator,

-                subPackages.toList(), excludedPackages.toList(), docClasses,

-                legacy, quiet);

-        return root;

-    }

-    

-}

diff --git a/tools/signature-tools/test/signature/converter/util/AbstractConvertTest.java b/tools/signature-tools/test/signature/converter/util/AbstractConvertTest.java
deleted file mode 100644
index 04935d8..0000000
--- a/tools/signature-tools/test/signature/converter/util/AbstractConvertTest.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.converter.util;
-
-import java.io.IOException;
-import java.util.Set;
-
-import org.junit.Before;
-
-import signature.converter.Visibility;
-import signature.model.IApi;
-
-public abstract class AbstractConvertTest extends AbstractTestSourceConverter {
-    
-    private ITestSourceConverter converter;
-    
-    /**
-     * Creates and returns a converter instance.
-     * @return a converter instance
-     */
-    public abstract ITestSourceConverter createConverter();
-    
-    
-    @Before
-    public void setupConverter(){
-        converter = createConverter();
-    }
-
-    public IApi convert(Visibility visibility, Set<CompilationUnit> units) throws IOException {
-        return converter.convert(visibility, units);
-    }
-
-}
diff --git a/tools/signature-tools/test/signature/converter/util/AbstractTestSourceConverter.java b/tools/signature-tools/test/signature/converter/util/AbstractTestSourceConverter.java
deleted file mode 100644
index 5ca7422..0000000
--- a/tools/signature-tools/test/signature/converter/util/AbstractTestSourceConverter.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.converter.util;
-
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Set;
-
-import signature.converter.Visibility;
-import signature.model.IApi;
-
-public abstract class AbstractTestSourceConverter implements ITestSourceConverter {
-
-    public IApi convert(Set<CompilationUnit> units) throws IOException {
-        return convert(Visibility.PROTECTED, units);
-    }
-    public IApi convert(CompilationUnit... units) throws IOException {
-        return convert(Visibility.PROTECTED, new HashSet<CompilationUnit>(Arrays.asList(units)));
-    }
-    public IApi convert(Visibility visibility, CompilationUnit... units) throws IOException {
-        return convert(visibility, new HashSet<CompilationUnit>(Arrays.asList(units)));
-    }
-}
-
diff --git a/tools/signature-tools/test/signature/converter/util/CompilationUnit.java b/tools/signature-tools/test/signature/converter/util/CompilationUnit.java
deleted file mode 100644
index 95960ae..0000000
--- a/tools/signature-tools/test/signature/converter/util/CompilationUnit.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.converter.util;
-
-public class CompilationUnit {
-    
-    /** a.b.C */
-    private String name;
-    private String source;
-    
-    public CompilationUnit(String name, String source) {
-        this.name = name;
-        this.source = source;
-    }
-    
-    public String getName() {
-        return name;
-    }
-    
-    public String getSource() {
-        return source;
-    }
-}
diff --git a/tools/signature-tools/test/signature/converter/util/ITestSourceConverter.java b/tools/signature-tools/test/signature/converter/util/ITestSourceConverter.java
deleted file mode 100644
index 568a3e9..0000000
--- a/tools/signature-tools/test/signature/converter/util/ITestSourceConverter.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package signature.converter.util;
-
-import java.io.IOException;
-import java.util.Set;
-
-import signature.converter.Visibility;
-import signature.model.IApi;
-
-public interface ITestSourceConverter {
-    IApi convert(Set<CompilationUnit> units) throws IOException;
-    IApi convert(CompilationUnit... units) throws IOException;
-    IApi convert(Visibility visibility, Set<CompilationUnit> units) throws IOException;
-    IApi convert(Visibility visibility, CompilationUnit... units) throws IOException;
-}
diff --git a/tools/tradefed-host/.classpath b/tools/tradefed-host/.classpath
index dbeeb01..e716219 100644
--- a/tools/tradefed-host/.classpath
+++ b/tools/tradefed-host/.classpath
@@ -7,6 +7,5 @@
 	<classpathentry exported="true" kind="var" path="CTS_SRC_ROOT/out/host/common/obj/JAVA_LIBRARIES/ctsdeviceinfolib_intermediates/javalib.jar"/>
 	<classpathentry kind="var" path="CTS_SRC_ROOT/out/host/common/obj/JAVA_LIBRARIES/hosttestlib_intermediates/javalib.jar"/>
 	<classpathentry kind="var" path="CTS_SRC_ROOT/prebuilts/misc/common/tradefed/tradefed-prebuilt.jar"/>
-	<classpathentry combineaccessrules="false" kind="src" path="/cts-commonutil"/>
 	<classpathentry kind="output" path="bin"/>
 </classpath>
diff --git a/tools/tradefed-host/Android.mk b/tools/tradefed-host/Android.mk
index 1f73e95..e7954a6 100644
--- a/tools/tradefed-host/Android.mk
+++ b/tools/tradefed-host/Android.mk
@@ -22,10 +22,10 @@
 
 LOCAL_JAVA_RESOURCE_DIRS := res
 
-LOCAL_MODULE := cts-tradefed
+LOCAL_MODULE := old-cts-tradefed
 LOCAL_MODULE_TAGS := optional
 LOCAL_JAVA_LIBRARIES := tradefed-prebuilt hosttestlib
-LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceinfolib
+LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceinfolib compatibility-host-util
 
 LOCAL_JAR_MANIFEST := MANIFEST.mf
 
diff --git a/tools/tradefed-host/etc/Android.mk b/tools/tradefed-host/etc/Android.mk
index f3bee3f..3c2a3cf 100644
--- a/tools/tradefed-host/etc/Android.mk
+++ b/tools/tradefed-host/etc/Android.mk
@@ -17,6 +17,6 @@
 
 LOCAL_MODULE_TAGS := optional
 
-LOCAL_PREBUILT_EXECUTABLES := cts-tradefed
+LOCAL_PREBUILT_EXECUTABLES := old-cts-tradefed
 include $(BUILD_HOST_PREBUILT)
 
diff --git a/tools/tradefed-host/etc/cts-tradefed b/tools/tradefed-host/etc/cts-tradefed
deleted file mode 100755
index 3df2720..0000000
--- a/tools/tradefed-host/etc/cts-tradefed
+++ /dev/null
@@ -1,101 +0,0 @@
-#!/bin/bash
-
-# Copyright (C) 2011 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#       http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# launcher script for cts-tradefed harness
-# can be used from an Android build environment, or a standalone cts zip
-
-checkFile() {
-    if [ ! -f "$1" ]; then
-        echo "Unable to locate $1"
-        exit
-    fi;
-}
-
-checkPath() {
-    if ! type -P $1 &> /dev/null; then
-        echo "Unable to find $1 in path."
-        exit
-    fi;
-}
-
-checkPath adb
-checkPath java
-
-# check java version
-JAVA_VERSION=$(java -version 2>&1 | head -n 2 | grep '[ "]1\.[678][\. "$$]')
-if [ "${JAVA_VERSION}" == "" ]; then
-    echo "Wrong java version. 1.6, 1.7 or 1.8 is required."
-    exit
-fi
-
-# check debug flag and set up remote debugging
-if [ -n "${TF_DEBUG}" ]; then
-  if [ -z "${TF_DEBUG_PORT}" ]; then
-    TF_DEBUG_PORT=10088
-  fi
-  RDBG_FLAG=-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=${TF_DEBUG_PORT}
-fi
-
-# get OS
-HOST=`uname`
-if [ "$HOST" == "Linux" ]; then
-    OS="linux-x86"
-elif [ "$HOST" == "Darwin" ]; then
-    OS="darwin-x86"
-else
-    echo "Unrecognized OS"
-    exit
-fi
-
-# check if in Android build env
-if [ ! -z "${ANDROID_BUILD_TOP}" ]; then
-    if [ ! -z "${ANDROID_HOST_OUT}" ]; then
-      CTS_ROOT=${ANDROID_HOST_OUT}/cts
-    else
-      CTS_ROOT=${ANDROID_BUILD_TOP}/${OUT_DIR:-out}/host/${OS}/cts
-    fi
-    if [ ! -d ${CTS_ROOT} ]; then
-        echo "Could not find $CTS_ROOT in Android build environment. Try 'make cts'"
-        exit
-    fi;
-fi;
-
-if [ -z ${CTS_ROOT} ]; then
-    # assume we're in an extracted cts install
-    CTS_ROOT="$(dirname $0)/../.."
-fi;
-
-JAR_DIR=${CTS_ROOT}/android-cts/tools
-JARS="tradefed-prebuilt.jar hosttestlib.jar cts-tradefed.jar"
-
-for JAR in $JARS; do
-    checkFile ${JAR_DIR}/${JAR}
-    JAR_PATH=${JAR_PATH}:${JAR_DIR}/${JAR}
-done
-
-# load any shared libraries for host-side executables
-LIB_DIR=${CTS_ROOT}/android-cts/lib
-if [ "$HOST" == "Linux" ]; then
-    LD_LIBRARY_PATH=${LIB_DIR}:${LIB_DIR}64:${LD_LIBRARY_PATH}
-    export LD_LIBRARY_PATH
-elif [ "$HOST" == "Darwin" ]; then
-    DYLD_LIBRARY_PATH=${LIB_DIR}:${LIB_DIR}64:${DYLD_LIBRARY_PATH}
-    export DYLD_LIBRARY_PATH
-fi
-
-java $RDBG_FLAG \
-  -cp ${JAR_PATH} -DCTS_ROOT=${CTS_ROOT} com.android.cts.tradefed.command.CtsConsole "$@"
-
diff --git a/tools/tradefed-host/etc/old-cts-tradefed b/tools/tradefed-host/etc/old-cts-tradefed
new file mode 100755
index 0000000..1dc7638
--- /dev/null
+++ b/tools/tradefed-host/etc/old-cts-tradefed
@@ -0,0 +1,101 @@
+#!/bin/bash
+
+# Copyright (C) 2011 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# launcher script for old-cts-tradefed harness
+# can be used from an Android build environment, or a standalone cts zip
+
+checkFile() {
+    if [ ! -f "$1" ]; then
+        echo "Unable to locate $1"
+        exit
+    fi;
+}
+
+checkPath() {
+    if ! type -P $1 &> /dev/null; then
+        echo "Unable to find $1 in path."
+        exit
+    fi;
+}
+
+checkPath adb
+checkPath java
+
+# check java version
+JAVA_VERSION=$(java -version 2>&1 | head -n 2 | grep '[ "]1\.[678][\. "$$]')
+if [ "${JAVA_VERSION}" == "" ]; then
+    echo "Wrong java version. 1.6, 1.7 or 1.8 is required."
+    exit
+fi
+
+# check debug flag and set up remote debugging
+if [ -n "${TF_DEBUG}" ]; then
+  if [ -z "${TF_DEBUG_PORT}" ]; then
+    TF_DEBUG_PORT=10088
+  fi
+  RDBG_FLAG=-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=${TF_DEBUG_PORT}
+fi
+
+# get OS
+HOST=`uname`
+if [ "$HOST" == "Linux" ]; then
+    OS="linux-x86"
+elif [ "$HOST" == "Darwin" ]; then
+    OS="darwin-x86"
+else
+    echo "Unrecognized OS"
+    exit
+fi
+
+# check if in Android build env
+if [ ! -z "${ANDROID_BUILD_TOP}" ]; then
+    if [ ! -z "${ANDROID_HOST_OUT}" ]; then
+      OLD_CTS_ROOT=${ANDROID_HOST_OUT}/old-cts
+    else
+      OLD_CTS_ROOT=${ANDROID_BUILD_TOP}/${OUT_DIR:-out}/host/${OS}/old-cts
+    fi
+    if [ ! -d ${OLD_CTS_ROOT} ]; then
+        echo "Could not find $OLD_CTS_ROOT in Android build environment. Try 'make old-cts'"
+        exit
+    fi;
+fi;
+
+if [ -z ${OLD_CTS_ROOT} ]; then
+    # assume we're in an extracted cts install
+    OLD_CTS_ROOT="$(dirname $0)/../.."
+fi;
+
+JAR_DIR=${OLD_CTS_ROOT}/old-android-cts/tools
+JARS="tradefed-prebuilt.jar hosttestlib.jar old-cts-tradefed.jar"
+
+for JAR in $JARS; do
+    checkFile ${JAR_DIR}/${JAR}
+    JAR_PATH=${JAR_PATH}:${JAR_DIR}/${JAR}
+done
+
+# load any shared libraries for host-side executables
+LIB_DIR=${OLD_CTS_ROOT}/old-android-cts/lib
+if [ "$HOST" == "Linux" ]; then
+    LD_LIBRARY_PATH=${LIB_DIR}:${LIB_DIR}64:${LD_LIBRARY_PATH}
+    export LD_LIBRARY_PATH
+elif [ "$HOST" == "Darwin" ]; then
+    DYLD_LIBRARY_PATH=${LIB_DIR}:${LIB_DIR}64:${DYLD_LIBRARY_PATH}
+    export DYLD_LIBRARY_PATH
+fi
+
+java $RDBG_FLAG \
+  -cp ${JAR_PATH} -DCTS_ROOT=${OLD_CTS_ROOT} com.android.cts.tradefed.command.CtsConsole "$@"
+
diff --git a/tools/tradefed-host/res/config/basic-reporters.xml b/tools/tradefed-host/res/config/basic-reporters.xml
new file mode 100644
index 0000000..d52a85b
--- /dev/null
+++ b/tools/tradefed-host/res/config/basic-reporters.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Configuration with basic cts reporters" >
+    <result_reporter class="com.android.cts.tradefed.result.CtsTestLogReporter" />
+    <result_reporter class="com.android.cts.tradefed.result.IssueReporter" />
+</configuration>
diff --git a/tools/tradefed-host/res/config/cts.xml b/tools/tradefed-host/res/config/cts.xml
index 416b400..e08ad81 100644
--- a/tools/tradefed-host/res/config/cts.xml
+++ b/tools/tradefed-host/res/config/cts.xml
@@ -20,9 +20,9 @@
     <build_provider class="com.android.cts.tradefed.build.CtsBuildProvider" />
     <device_recovery class="com.android.tradefed.device.WaitDeviceRecovery" />
     <test class="com.android.cts.tradefed.testtype.CtsTest" />
-    <logger class="com.android.tradefed.log.FileLogger" />
+    <logger class="com.android.tradefed.log.FileLogger">
+        <option name="log-level-display" value="WARN" />
+    </logger>
     <result_reporter class="com.android.cts.tradefed.result.CtsXmlResultReporter" />
-    <result_reporter class="com.android.cts.tradefed.result.CtsTestLogReporter" />
-    <result_reporter class="com.android.cts.tradefed.result.IssueReporter" />
-
+    <template-include name="reporters" default="basic-reporters" />
 </configuration>
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/build/CtsBuildHelper.java b/tools/tradefed-host/src/com/android/cts/tradefed/build/CtsBuildHelper.java
index 0940355..1a9f04b 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/build/CtsBuildHelper.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/build/CtsBuildHelper.java
@@ -29,8 +29,8 @@
  */
 public class CtsBuildHelper {
 
-    static final String CTS_DIR_NAME = "android-cts";
-    private final String mSuiteName = "CTS";
+    static final String CTS_DIR_NAME = "old-android-cts";
+    private final String mSuiteName = "OLD-CTS";
     /** The root location of the extracted CTS package */
     private final File mRootDir;
     /** the {@link #CTS_DIR_NAME} directory */
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/build/CtsBuildProvider.java b/tools/tradefed-host/src/com/android/cts/tradefed/build/CtsBuildProvider.java
index 66a4562..c1ab1f1 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/build/CtsBuildProvider.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/build/CtsBuildProvider.java
@@ -31,7 +31,10 @@
     @Option(name="cts-install-path", description="the path to the cts installation to use")
     private String mCtsRootDirPath = System.getProperty("CTS_ROOT");
 
-    public static final String CTS_BUILD_VERSION = "6.0_r3";
+    @Option(name="branch", description="build branch name to supply.")
+    private String mBranch = null;
+
+    public static final String CTS_BUILD_VERSION = "5.0_r1.91";
     public static final String CTS_PACKAGE = "com.android.cts.tradefed.testtype";
 
     /**
@@ -46,6 +49,9 @@
             Package.getPackage(CTS_PACKAGE).getImplementationVersion(),
             "cts", "cts");
         ctsBuild.setRootDir(new File(mCtsRootDirPath));
+        if (mBranch  != null) {
+            ctsBuild.setBuildBranch(mBranch);
+        }
         return ctsBuild;
     }
 
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/command/CtsConsole.java b/tools/tradefed-host/src/com/android/cts/tradefed/command/CtsConsole.java
index 24239e6..4cb9e16 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/command/CtsConsole.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/command/CtsConsole.java
@@ -15,6 +15,7 @@
  */
 package com.android.cts.tradefed.command;
 
+import com.android.compatibility.common.util.AbiUtils;
 import com.android.cts.tradefed.build.CtsBuildHelper;
 import com.android.cts.tradefed.build.CtsBuildProvider;
 import com.android.cts.tradefed.result.ITestResultRepo;
@@ -23,7 +24,6 @@
 import com.android.cts.tradefed.result.TestResultRepo;
 import com.android.cts.tradefed.testtype.ITestPackageRepo;
 import com.android.cts.tradefed.testtype.TestPackageRepo;
-import com.android.cts.util.AbiUtils;
 import com.android.tradefed.build.IFolderBuildInfo;
 import com.android.tradefed.command.Console;
 import com.android.tradefed.config.ArgsOptionParser;
@@ -120,7 +120,7 @@
                 CtsBuildHelper ctsBuild = getCtsBuildHelper();
                 if (ctsBuild != null) {
                     // FIXME may want to only add certain ABIs
-                    addDerivedPlan(ctsBuild, AbiUtils.getAbisSupportedByCts(), flatArgs);
+                    addDerivedPlan(ctsBuild, AbiUtils.getAbisSupportedByCompatibility(), flatArgs);
                 }
             }
         };
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/device/DeviceInfoCollector.java b/tools/tradefed-host/src/com/android/cts/tradefed/device/DeviceInfoCollector.java
index 61561a5..0ab70a7 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/device/DeviceInfoCollector.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/device/DeviceInfoCollector.java
@@ -15,7 +15,7 @@
  */
 package com.android.cts.tradefed.device;
 
-import com.android.cts.util.AbiUtils;
+import com.android.compatibility.common.util.AbiUtils;
 import com.android.cts.tradefed.result.CtsXmlResultReporter;
 import com.android.ddmlib.IDevice;
 import com.android.ddmlib.Log;
@@ -48,14 +48,14 @@
     public static final String EXTENDED_APP_PACKAGE_NAME =
             "com.android.compatibility.common.deviceinfo";
     private static final String EXTENDED_INSTRUMENTATION_NAME =
-            "com.android.compatibility.common.deviceinfo.DeviceInfoInstrument";
+            "android.support.test.runner.AndroidJUnitRunner";
     private static final String DEVICE_INFO_FILES = "device-info-files";
 
     public static final Set<String> IDS = new HashSet<String>();
     public static final Set<String> EXTENDED_IDS = new HashSet<String>();
 
     static {
-        for (String abi : AbiUtils.getAbisSupportedByCts()) {
+        for (String abi : AbiUtils.getAbisSupportedByCompatibility()) {
             IDS.add(AbiUtils.createId(abi, APP_PACKAGE_NAME));
             EXTENDED_IDS.add(AbiUtils.createId(abi, EXTENDED_APP_PACKAGE_NAME));
         }
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/result/CtsTestLogReporter.java b/tools/tradefed-host/src/com/android/cts/tradefed/result/CtsTestLogReporter.java
index b7f064f..8500d01 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/result/CtsTestLogReporter.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/result/CtsTestLogReporter.java
@@ -16,8 +16,8 @@
 
 package com.android.cts.tradefed.result;
 
+import com.android.compatibility.common.util.AbiUtils;
 import com.android.cts.tradefed.device.DeviceInfoCollector;
-import com.android.cts.util.AbiUtils;
 import com.android.ddmlib.Log;
 import com.android.ddmlib.Log.LogLevel;
 import com.android.ddmlib.testrunner.TestIdentifier;
@@ -35,6 +35,8 @@
  */
 public class CtsTestLogReporter extends StubTestInvocationListener implements IShardableListener {
 
+    private static final String DEVICE_INFO_ERROR = "DEVICE_INFO_ERROR_";
+
     @Option(name = "quiet-output", description = "Mute display of test results.")
     private boolean mQuietOutput = false;
 
@@ -84,6 +86,9 @@
      */
     @Override
     public void testStarted(TestIdentifier test) {
+        if (mIsExtendedDeviceInfoRun) {
+            return;
+        }
         mCurrentPkgResult.insertTest(test);
     }
 
@@ -92,6 +97,9 @@
      */
     @Override
     public void testFailed(TestIdentifier test, String trace) {
+        if (mIsExtendedDeviceInfoRun) {
+            return;
+        }
         mCurrentPkgResult.reportTestFailure(test, CtsTestStatus.FAIL, trace);
     }
 
@@ -100,6 +108,9 @@
      */
     @Override
     public void testAssumptionFailure(TestIdentifier test, String trace) {
+        if (mIsExtendedDeviceInfoRun) {
+            return;
+        }
         // TODO: do something different here?
         mCurrentPkgResult.reportTestFailure(test, CtsTestStatus.FAIL, trace);
     }
@@ -109,6 +120,17 @@
      */
     @Override
     public void testEnded(TestIdentifier test, Map<String, String> testMetrics) {
+        if (mIsExtendedDeviceInfoRun) {
+            for (Map.Entry<String, String> metricsEntry : testMetrics.entrySet()) {
+                String key = metricsEntry.getKey();
+                String value = metricsEntry.getValue();
+                if (key.startsWith(DEVICE_INFO_ERROR)) {
+                    throw new RuntimeException(String.format(
+                        "Error collecting extended device info: %s=%s", key, value));
+                }
+            }
+            return;
+        }
         mCurrentPkgResult.reportTestEnded(test, testMetrics);
         Test result = mCurrentPkgResult.findTest(test);
         String stack = result.getStackTrace() == null ? "" : "\n" + result.getStackTrace();
@@ -121,6 +143,9 @@
      */
     @Override
     public void invocationEnded(long elapsedTime) {
+        if (mIsExtendedDeviceInfoRun) {
+            return;
+        }
         // display the results of the last completed run
         if (mCurrentPkgResult != null) {
             logCompleteRun(mCurrentPkgResult);
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/result/CtsXmlResultReporter.java b/tools/tradefed-host/src/com/android/cts/tradefed/result/CtsXmlResultReporter.java
index 3efc7fc..07caaef 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/result/CtsXmlResultReporter.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/result/CtsXmlResultReporter.java
@@ -61,6 +61,8 @@
         implements ITestInvocationListener, ITestSummaryListener, ILogSaverListener {
 
     private static final String LOG_TAG = "CtsXmlResultReporter";
+    private static final String DEVICE_INFO = "DEVICE_INFO_";
+    private static final String DEVICE_INFO_EXT = ".deviceinfo.json";
 
     public static final String CTS_RESULT_DIR = "cts-result-dir";
     static final String TEST_RESULT_FILE_NAME = "testResult.xml";
@@ -238,6 +240,7 @@
     @Override
     public void testLogSaved(String dataName, LogDataType dataType, InputStreamSource dataStream,
             LogFile logFile) {
+        CLog.i("Got log for %s %s %s", dataName, dataType, logFile.getUrl());
         if (mIncludeTestLogTags && mCurrentTest != null) {
             TestLog log = TestLog.fromDataName(dataName, logFile.getUrl());
             if (log != null) {
@@ -335,9 +338,10 @@
 
     private void checkExtendedDeviceInfoMetrics(Map<String, String> runMetrics) {
         for (Map.Entry<String, String> metricEntry : runMetrics.entrySet()) {
+            String key = metricEntry.getKey();
             String value = metricEntry.getValue();
-            if (!value.endsWith(".deviceinfo.json")) {
-                CLog.e(String.format("%s failed: %s", metricEntry.getKey(), value));
+            if (!key.startsWith(DEVICE_INFO) && !value.endsWith(DEVICE_INFO_EXT)) {
+                CLog.e(String.format("%s failed: %s", key, value));
             }
         }
     }
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/result/PlanCreator.java b/tools/tradefed-host/src/com/android/cts/tradefed/result/PlanCreator.java
index 3881c0e..0926635 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/result/PlanCreator.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/result/PlanCreator.java
@@ -22,7 +22,6 @@
 import com.android.cts.tradefed.testtype.ITestPlan;
 import com.android.cts.tradefed.testtype.TestPackageRepo;
 import com.android.cts.tradefed.testtype.TestPlan;
-import com.android.cts.util.AbiUtils;
 import com.android.ddmlib.Log;
 import com.android.ddmlib.Log.LogLevel;
 import com.android.ddmlib.testrunner.TestIdentifier;
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/result/Test.java b/tools/tradefed-host/src/com/android/cts/tradefed/result/Test.java
index 12a2b29..e25ea5a 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/result/Test.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/result/Test.java
@@ -15,7 +15,8 @@
  */
 package com.android.cts.tradefed.result;
 
-import com.android.ddmlib.Log;
+import com.android.compatibility.common.util.MetricsXmlSerializer;
+import com.android.compatibility.common.util.ReportLog;
 import com.android.cts.tradefed.result.TestLog.TestLogType;
 
 import org.kxml2.io.KXmlSerializer;
@@ -38,27 +39,13 @@
     private static final String RESULT_ATTR = "result";
     private static final String SCENE_TAG = "FailedScene";
     private static final String STACK_TAG = "StackTrace";
-    private static final String SUMMARY_TAG = "Summary";
-    private static final String DETAILS_TAG = "Details";
-    private static final String VALUEARRAY_TAG = "ValueArray";
-    private static final String VALUE_TAG = "Value";
-    private static final String TARGET_ATTR = "target";
-    private static final String SCORETYPE_ATTR = "scoreType";
-    private static final String UNIT_ATTR = "unit";
-    private static final String SOURCE_ATTR = "source";
-    // separators for the message
-    private static final String LOG_SEPARATOR = "\\+\\+\\+";
-    private static final String LOG_ELEM_SEPARATOR = "\\|";
-
     private String mName;
     private CtsTestStatus mResult;
     private String mStartTime;
     private String mEndTime;
     private String mMessage;
     private String mStackTrace;
-    // summary and details passed from cts
-    private String mSummary;
-    private String mDetails;
+    private ReportLog mReport;
 
     /**
      * Log info for this test like a logcat dump or bugreport.
@@ -73,7 +60,7 @@
     }
 
     /**
-     * Create a {@link Test} from a {@link TestResult}.
+     * Create a {@link Test}.
      *
      * @param name
      */
@@ -135,20 +122,12 @@
         mMessage = getFailureMessageFromStackTrace(mStackTrace);
     }
 
-    public String getSummary() {
-        return mSummary;
+    public ReportLog getReportLog() {
+        return mReport;
     }
 
-    public void setSummary(String summary) {
-        mSummary = summary;
-    }
-
-    public String getDetails() {
-        return mDetails;
-    }
-
-    public void setDetails(String details) {
-        mDetails = details;
+    public void setReportLog(ReportLog report) {
+        mReport = report;
     }
 
     public void updateEndTime() {
@@ -185,113 +164,12 @@
             }
             serializer.endTag(CtsXmlResultReporter.ns, SCENE_TAG);
         }
-        if (mSummary != null) {
-            // <Summary message = "screen copies per sec" scoretype="higherBetter" unit="fps">
-            // 23938.82978723404</Summary>
-            PerfResultSummary summary = parseSummary(mSummary);
-            if (summary != null) {
-                serializer.startTag(CtsXmlResultReporter.ns, SUMMARY_TAG);
-                serializer.attribute(CtsXmlResultReporter.ns, MESSAGE_ATTR, summary.mMessage);
-                if (summary.mTarget.length() != 0 && !summary.mTarget.equals(" ")) {
-                    serializer.attribute(CtsXmlResultReporter.ns, TARGET_ATTR, summary.mTarget);
-                }
-                serializer.attribute(CtsXmlResultReporter.ns, SCORETYPE_ATTR, summary.mType);
-                serializer.attribute(CtsXmlResultReporter.ns, UNIT_ATTR, summary.mUnit);
-                serializer.text(summary.mValue);
-                serializer.endTag(CtsXmlResultReporter.ns, SUMMARY_TAG);
-                // add details only if summary is present
-                // <Details>
-                //   <ValueArray source=”com.android.cts.dram.BandwidthTest#doRunMemcpy:98”
-                //                    message=”measure1” unit="ms" scoretype="higherBetter">
-                //     <Value>0.0</Value>
-                //     <Value>0.1</Value>
-                //   </ValueArray>
-                // </Details>
-                if (mDetails != null) {
-                    PerfResultDetail[] ds = parseDetails(mDetails);
-                    serializer.startTag(CtsXmlResultReporter.ns, DETAILS_TAG);
-                        for (PerfResultDetail d : ds) {
-                            if (d == null) {
-                                continue;
-                            }
-                            serializer.startTag(CtsXmlResultReporter.ns, VALUEARRAY_TAG);
-                            serializer.attribute(CtsXmlResultReporter.ns, SOURCE_ATTR, d.mSource);
-                            serializer.attribute(CtsXmlResultReporter.ns, MESSAGE_ATTR,
-                                    d.mMessage);
-                            serializer.attribute(CtsXmlResultReporter.ns, SCORETYPE_ATTR, d.mType);
-                            serializer.attribute(CtsXmlResultReporter.ns, UNIT_ATTR, d.mUnit);
-                            for (String v : d.mValues) {
-                                if (v == null) {
-                                    continue;
-                                }
-                                serializer.startTag(CtsXmlResultReporter.ns, VALUE_TAG);
-                                serializer.text(v);
-                                serializer.endTag(CtsXmlResultReporter.ns, VALUE_TAG);
-                            }
-                            serializer.endTag(CtsXmlResultReporter.ns, VALUEARRAY_TAG);
-                        }
-                    serializer.endTag(CtsXmlResultReporter.ns, DETAILS_TAG);
-                }
-            }
-        }
+        MetricsXmlSerializer metricsXmlSerializer = new MetricsXmlSerializer(serializer);
+        metricsXmlSerializer.serialize(mReport);
         serializer.endTag(CtsXmlResultReporter.ns, TAG);
     }
 
     /**
-     *  class containing performance result.
-     */
-    public static class PerfResultCommon {
-        public String mMessage;
-        public String mType;
-        public String mUnit;
-    }
-
-    private class PerfResultSummary extends PerfResultCommon {
-        public String mTarget;
-        public String mValue;
-    }
-
-    private class PerfResultDetail extends PerfResultCommon {
-        public String mSource;
-        public String[] mValues;
-    }
-
-    private PerfResultSummary parseSummary(String summary) {
-        String[] elems = summary.split(LOG_ELEM_SEPARATOR);
-        PerfResultSummary r = new PerfResultSummary();
-        if (elems.length < 5) {
-            Log.w(TAG, "wrong message " + summary);
-            return null;
-        }
-        r.mMessage = elems[0];
-        r.mTarget = elems[1];
-        r.mType = elems[2];
-        r.mUnit = elems[3];
-        r.mValue = elems[4];
-        return r;
-    }
-
-    private PerfResultDetail[] parseDetails(String details) {
-        String[] arrays = details.split(LOG_SEPARATOR);
-        PerfResultDetail[] rs = new PerfResultDetail[arrays.length];
-        for (int i = 0; i < arrays.length; i++) {
-            String[] elems = arrays[i].split(LOG_ELEM_SEPARATOR);
-            if (elems.length < 5) {
-                Log.w(TAG, "wrong message " + arrays[i]);
-                continue;
-            }
-            PerfResultDetail r = new PerfResultDetail();
-            r.mSource = elems[0];
-            r.mMessage = elems[1];
-            r.mType = elems[2];
-            r.mUnit = elems[3];
-            r.mValues = elems[4].split(" ");
-            rs[i] = r;
-        }
-        return rs;
-    }
-
-    /**
      * Strip out any invalid XML characters that might cause the report to be unviewable.
      * http://www.w3.org/TR/REC-xml/#dt-character
      */
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/result/TestPackageResult.java b/tools/tradefed-host/src/com/android/cts/tradefed/result/TestPackageResult.java
index 45224f6..2229671 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/result/TestPackageResult.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/result/TestPackageResult.java
@@ -15,9 +15,10 @@
  */
 package com.android.cts.tradefed.result;
 
+import com.android.compatibility.common.util.AbiUtils;
+import com.android.compatibility.common.util.MetricsStore;
+import com.android.compatibility.common.util.ReportLog;
 import com.android.cts.tradefed.testtype.CtsTest;
-import com.android.cts.tradefed.util.CtsHostStore;
-import com.android.cts.util.AbiUtils;
 import com.android.ddmlib.testrunner.TestIdentifier;
 import com.android.tradefed.log.LogUtil.CLog;
 
@@ -33,8 +34,6 @@
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 
 /**
  * Data structure for a CTS test package result.
@@ -45,7 +44,7 @@
 
     static final String TAG = "TestPackage";
 
-    public static final String CTS_RESULT_KEY = "CTS_TEST_RESULT";
+    public static final String RESULT_KEY = "COMPATIBILITY_TEST_RESULT";
 
     private static final String DIGEST_ATTR = "digest";
     private static final String APP_PACKAGE_NAME_ATTR = "appPackageName";
@@ -54,8 +53,6 @@
     private static final String ns = CtsXmlResultReporter.ns;
     private static final String SIGNATURE_TEST_PKG = "android.tests.sigtest";
 
-    private static final Pattern mCtsLogPattern = Pattern.compile("(.*)\\+\\+\\+\\+(.*)");
-
     private String mDeviceSerial;
     private String mAppPackageName;
     private String mName;
@@ -249,23 +246,22 @@
         // Collect performance results
         for (TestIdentifier test : mTestMetrics.keySet()) {
             // device test can have performance results in test metrics
-            String perfResult = mTestMetrics.get(test).get(CTS_RESULT_KEY);
-            // host test should be checked in CtsHostStore.
-            if (perfResult == null) {
-                perfResult = CtsHostStore.removeCtsResult(mDeviceSerial, mAbi, test.toString());
+            String perfResult = mTestMetrics.get(test).get(RESULT_KEY);
+            ReportLog report = null;
+            if (perfResult != null) {
+                try {
+                    report = ReportLog.parse(perfResult);
+                } catch (XmlPullParserException | IOException e) {
+                    e.printStackTrace();
+                }
+            } else {
+                // host test should be checked into MetricsStore.
+                report = MetricsStore.removeResult(mDeviceSerial, getAbi(), test.toString());
             }
             Test result = findTest(test);
-            if (perfResult != null && !result.getResult().equals(CtsTestStatus.FAIL)) {
-                // CTS result is passed in Summary++++Details format.
-                // Extract Summary and Details, and pass them.
-                Matcher m = mCtsLogPattern.matcher(perfResult);
-                if (m.find()) {
-                    result.setResultStatus(CtsTestStatus.PASS);
-                    result.setSummary(m.group(1));
-                    result.setDetails(m.group(2));
-                } else {
-                    CLog.e("CTS Result unrecognizable:" + perfResult);
-                }
+            if (report != null && !result.getResult().equals(CtsTestStatus.FAIL)) {
+                result.setResultStatus(CtsTestStatus.PASS);
+                result.setReportLog(report);
             }
         }
     }
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/result/TestResults.java b/tools/tradefed-host/src/com/android/cts/tradefed/result/TestResults.java
index 9f67f2d..a3f1591 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/result/TestResults.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/result/TestResults.java
@@ -15,8 +15,8 @@
  */
 package com.android.cts.tradefed.result;
 
+import com.android.compatibility.common.util.AbiUtils;
 import com.android.cts.tradefed.build.CtsBuildProvider;
-import com.android.cts.util.AbiUtils;
 import com.android.tradefed.log.LogUtil.CLog;
 
 import org.kxml2.io.KXmlSerializer;
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/targetprep/CtsRootDeviceSetup.java b/tools/tradefed-host/src/com/android/cts/tradefed/targetprep/CtsRootDeviceSetup.java
index 0e768e2..f75a99e 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/targetprep/CtsRootDeviceSetup.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/targetprep/CtsRootDeviceSetup.java
@@ -41,7 +41,7 @@
  */
 public class CtsRootDeviceSetup implements ITargetPreparer {
 
-    private static final String DEVICE_ADMIN_APK_FILE_NAME = "CtsDeviceAdmin.apk";
+    private static final String DEVICE_ADMIN_APK_FILE_NAME = "CtsAdminApp.apk";
 
     /**
      * {@inheritDoc}
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/CtsInstrumentationApkTest.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/CtsInstrumentationApkTest.java
index 66d1135f..1fa4e7b 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/CtsInstrumentationApkTest.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/CtsInstrumentationApkTest.java
@@ -15,8 +15,8 @@
  */
 package com.android.cts.tradefed.testtype;
 
+import com.android.compatibility.common.util.AbiUtils;
 import com.android.cts.tradefed.build.CtsBuildHelper;
-import com.android.cts.util.AbiUtils;
 import com.android.ddmlib.Log;
 import com.android.tradefed.build.IBuildInfo;
 import com.android.tradefed.device.DeviceNotAvailableException;
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/CtsTest.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/CtsTest.java
index 244f348..1e82294 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/CtsTest.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/CtsTest.java
@@ -16,11 +16,12 @@
 
 package com.android.cts.tradefed.testtype;
 
+import com.android.compatibility.common.util.AbiUtils;
+import com.android.compatibility.common.util.MonitoringUtils;
 import com.android.cts.tradefed.build.CtsBuildHelper;
 import com.android.cts.tradefed.device.DeviceInfoCollector;
 import com.android.cts.tradefed.result.CtsTestStatus;
 import com.android.cts.tradefed.result.PlanCreator;
-import com.android.cts.util.AbiUtils;
 import com.android.ddmlib.Log;
 import com.android.ddmlib.Log.LogLevel;
 import com.android.ddmlib.testrunner.TestIdentifier;
@@ -64,7 +65,6 @@
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.Comparator;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.LinkedHashSet;
@@ -199,6 +199,11 @@
     @Option(name = "min-pre-reboot-package-count", description =
             "The minimum number of packages to require a pre test reboot")
     private int mMinPreRebootPackageCount = 2;
+
+    @Option(name = "skip-connectivity-check",
+            description = "Don't verify device connectivity between module execution.")
+    private boolean mSkipConnectivityCheck = false;
+
     private final int mShardAssignment;
     private final int mTotalShards;
     private ITestDevice mDevice = null;
@@ -252,20 +257,6 @@
         }
     }
 
-
-    /**
-     * A {@link Comparator} for sorting {@link TestPackage}s by running time hint.
-     */
-    static class RuntimeHintComparator implements Comparator<TestPackage> {
-
-        @Override
-        public int compare(TestPackage left, TestPackage right) {
-            return Long.compare(left.getPackageDef().getRuntimeHint(),
-                    right.getPackageDef().getRuntimeHint());
-        }
-
-    }
-
     /**
      * A {@link ResultForwarder} that will forward a bugreport on each failed test.
      */
@@ -533,6 +524,10 @@
                     remainingPackageCount, totalTestCount));
             IAbi currentAbi = null;
 
+            // check connectivity upfront
+            if (!mSkipConnectivityCheck) {
+                MonitoringUtils.checkDeviceConnectivity(getDevice(), listener, "start");
+            }
             for (int i = mLastTestPackageIndex; i < mTestPackageList.size(); i++) {
                 TestPackage testPackage = mTestPackageList.get(i);
 
@@ -580,6 +575,11 @@
                 performPackagePrepareSetup(testPackage.getPackageDef());
                 test.run(filterMap.get(testPackage.getPackageDef().getId()));
                 performPackagePreparerTearDown(testPackage.getPackageDef());
+                if (!mSkipConnectivityCheck) {
+                    MonitoringUtils.checkDeviceConnectivity(getDevice(), listener,
+                            String.format("%s-%s", testPackage.getPackageDef().getName(),
+                                    testPackage.getPackageDef().getAbi().getName()));
+                }
                 if (i < mTestPackageList.size() - 1) {
                     TestPackage nextPackage = mTestPackageList.get(i + 1);
                     rebootIfNecessary(testPackage, nextPackage);
@@ -826,10 +826,6 @@
             int numTestPackages = testPackageList.size();
             int totalShards = Math.min(mTotalShards, numTestPackages);
 
-            // Sort test packages by running time hint, to force packages with large expected
-            // running times to different shards if possible.
-            Collections.sort(testPackageList, new RuntimeHintComparator());
-
             List<TestPackage> shardTestPackageList = new ArrayList<>();
             for (int i = mShardAssignment; i < numTestPackages; i += totalShards) {
                 shardTestPackageList.add(testPackageList.get(i));
@@ -1096,7 +1092,7 @@
      * Exposed for unit testing
      */
     ITestPlan createPlan(String planName) {
-        return new TestPlan(planName, AbiUtils.getAbisSupportedByCts());
+        return new TestPlan(planName, AbiUtils.getAbisSupportedByCompatibility());
     }
 
     /**
@@ -1110,7 +1106,7 @@
         String bitness = (mForceAbi == null) ? "" : mForceAbi;
         Set<String> abis = new HashSet<>();
         for (String abi : AbiFormatter.getSupportedAbis(mDevice, bitness)) {
-            if (AbiUtils.isAbiSupportedByCts(abi)) {
+            if (AbiUtils.isAbiSupportedByCompatibility(abi)) {
                 abis.add(abi);
             }
         }
@@ -1125,7 +1121,7 @@
      */
     ITestPlan createPlan(PlanCreator planCreator)
             throws ConfigurationException {
-        return planCreator.createDerivedPlan(mCtsBuild, AbiUtils.getAbisSupportedByCts());
+        return planCreator.createDerivedPlan(mCtsBuild, AbiUtils.getAbisSupportedByCompatibility());
     }
 
     /**
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/DeqpTestRunner.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/DeqpTestRunner.java
index 885f267..7bde54e 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/DeqpTestRunner.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/DeqpTestRunner.java
@@ -1,7 +1,7 @@
 package com.android.cts.tradefed.testtype;
 
+import com.android.compatibility.common.util.AbiUtils;
 import com.android.cts.tradefed.build.CtsBuildHelper;
-import com.android.cts.util.AbiUtils;
 import com.android.ddmlib.AdbCommandRejectedException;
 import com.android.ddmlib.IShellOutputReceiver;
 import com.android.ddmlib.MultiLineReceiver;
@@ -161,7 +161,7 @@
     }
 
     private static final class CapabilityQueryFailureException extends Exception {
-    };
+    }
 
     /**
      * Test configuration of dEPQ test instance execution.
@@ -241,13 +241,13 @@
         private boolean mGotTestResult;
         private String mCurrentTestLog;
 
-        private class PendingResult
-        {
+        private class PendingResult {
             boolean allInstancesPassed;
             Map<BatchRunConfiguration, String> testLogs;
             Map<BatchRunConfiguration, String> errorMessages;
             Set<BatchRunConfiguration> remainingConfigs;
-        };
+        }
+
         private final Map<TestIdentifier, PendingResult> mPendingResults = new HashMap<>();
 
         public void setSink(ITestInvocationListener sink) {
@@ -781,7 +781,7 @@
      */
     public static interface ISleepProvider {
         public void sleep(int milliseconds);
-    };
+    }
 
     private static class SleepProvider implements ISleepProvider {
         public void sleep(int milliseconds) {
@@ -790,7 +790,7 @@
             } catch (InterruptedException ex) {
             }
         }
-    };
+    }
 
     /**
      * Interface for failure recovery.
@@ -1050,7 +1050,7 @@
         private void rebootDevice() throws DeviceNotAvailableException {
             mDevice.reboot();
         }
-    };
+    }
 
     /**
      * Parse map of instance arguments to map of BatchRunConfigurations
@@ -1372,12 +1372,13 @@
         public AdbComLinkOpenError(String description, Throwable inner) {
             super(description, inner);
         }
-    };
+    }
+
     private static final class AdbComLinkKilledError extends Exception {
         public AdbComLinkKilledError(String description, Throwable inner) {
             super(description, inner);
         }
-    };
+    }
 
     /**
      * Executes a given command in adb shell
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/GeeTest.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/GeeTest.java
index 9cbcd20..f11c76d 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/GeeTest.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/GeeTest.java
@@ -16,6 +16,7 @@
 
 package com.android.cts.tradefed.testtype;
 
+import com.android.compatibility.common.util.AbiUtils;
 import com.android.cts.tradefed.build.CtsBuildHelper;
 import com.android.ddmlib.testrunner.ITestRunListener;
 import com.android.tradefed.build.IBuildInfo;
@@ -149,7 +150,8 @@
     }
 
     void runTest(ITestRunListener listener) throws DeviceNotAvailableException {
-        GeeTestResultParser resultParser = new GeeTestResultParser(mPackageName, listener);
+        String id = AbiUtils.createId(mAbi.getName(), mPackageName);
+        GeeTestResultParser resultParser = new GeeTestResultParser(id, listener);
         resultParser.setFakePackagePrefix(mPackageName + ".");
 
         String fullPath = NATIVE_TESTS_DIRECTORY + ANDROID_PATH_SEPARATOR + mExeName;
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/ITestPackageDef.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/ITestPackageDef.java
index 630dee3..13f3572 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/ITestPackageDef.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/ITestPackageDef.java
@@ -72,11 +72,6 @@
     public IAbi getAbi();
 
     /**
-     * @return the estimated running time of this test package.
-     */
-    public long getRuntimeHint();
-
-    /**
      * Set the filter to use for tests
      *
      * @param testFilter
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/ITestPackageRepo.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/ITestPackageRepo.java
index 234f437..893758f 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/ITestPackageRepo.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/ITestPackageRepo.java
@@ -16,7 +16,7 @@
 
 package com.android.cts.tradefed.testtype;
 
-import com.android.cts.util.AbiUtils;
+import com.android.compatibility.common.util.AbiUtils;
 
 import java.util.List;
 import java.util.Map;
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageDef.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageDef.java
index d08c0bc..1234893 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageDef.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageDef.java
@@ -16,8 +16,7 @@
 
 package com.android.cts.tradefed.testtype;
 
-import com.android.cts.util.AbiUtils;
-import com.android.ddmlib.Log.LogLevel;
+import com.android.compatibility.common.util.AbiUtils;
 import com.android.ddmlib.testrunner.TestIdentifier;
 import com.android.tradefed.log.LogUtil.CLog;
 import com.android.tradefed.targetprep.ITargetPreparer;
@@ -54,7 +53,6 @@
     public static final String WRAPPED_NATIVE_TEST = "wrappednative";
     public static final String VM_HOST_TEST = "vmHostTest";
     public static final String DEQP_TEST = "deqpTest";
-    public static final String UIAUTOMATOR_TEST = "uiAutomator";
     public static final String JUNIT_DEVICE_TEST = "jUnitDeviceTest";
 
     private String mAppPackageName = null;
@@ -66,7 +64,6 @@
     private String mRunTimeArgs = null;
     private String mTestPackageName = null;
     private String mDigest = null;
-    private long mRuntimeHint = 0;
     private IAbi mAbi = null;
     private List<ITargetPreparer> mPreparers = null;
 
@@ -138,18 +135,6 @@
      * {@inheritDoc}
      */
     @Override
-    public long getRuntimeHint() {
-        return mRuntimeHint;
-    }
-
-    void setRuntimeHint(long runtimeHint) {
-        mRuntimeHint = runtimeHint;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
     public String getName() {
         return mName;
     }
@@ -254,7 +239,7 @@
                 CLog.d("Setting new timeout to " + mTimeoutInMins + " mins");
                 hostTest.setTimeout(mTimeoutInMins * 60 * 1000);
             }
-            hostTest.setRunName(mAppPackageName);
+            hostTest.setRunName(getId());
             hostTest.setJarFileName(mJarPath);
             hostTest.setTests(mTests);
             hostTest.setAbi(mAbi);
@@ -263,7 +248,7 @@
         } else if (VM_HOST_TEST.equals(mTestType)) {
             CLog.d("Creating vm host test for %s", mName);
             VMHostTest vmHostTest = new VMHostTest();
-            vmHostTest.setRunName(mAppPackageName);
+            vmHostTest.setRunName(getId());
             vmHostTest.setJarFileName(mJarPath);
             vmHostTest.setTests(mTests);
             vmHostTest.setAbi(mAbi);
@@ -283,13 +268,10 @@
             WrappedGTest wrappedGeeTest = new WrappedGTest(mAppNameSpace, mAppPackageName, mName, mRunner);
             wrappedGeeTest.setAbi(mAbi);
             return wrappedGeeTest;
-        } else if (UIAUTOMATOR_TEST.equals(mTestType)) {
-            UiAutomatorJarTest uiautomatorTest = new UiAutomatorJarTest();
-            return setUiAutomatorTest(uiautomatorTest);
         } else if (JUNIT_DEVICE_TEST.equals(mTestType)){
             CLog.d("Creating JUnit device test %s", mName);
             JUnitDeviceTest jUnitDeviceTest = new JUnitDeviceTest();
-            jUnitDeviceTest.setRunName(mAppPackageName);
+            jUnitDeviceTest.setRunName(getId());
             jUnitDeviceTest.addTestJarFileName(mJarPath);
             jUnitDeviceTest.addRunTimeArgs(mRunTimeArgs);
             jUnitDeviceTest.setTests(mTests);
@@ -318,7 +300,7 @@
      */
     private InstrumentationTest setInstrumentationTest(CtsInstrumentationApkTest instrTest,
             File testCaseDir) {
-        instrTest.setRunName(mAppPackageName);
+        instrTest.setRunName(getId());
         instrTest.setPackageName(mAppNameSpace);
         instrTest.setRunnerName(mRunner);
         instrTest.setAbi(mAbi);
@@ -328,37 +310,10 @@
         // mName means 'apk file name' for instrumentation tests
         instrTest.addInstallApk(String.format("%s.apk", mName), mAppNameSpace);
         mDigest = generateDigest(testCaseDir, String.format("%s.apk", mName));
-        if (mTests.size() > 1000) {
-            // TODO: hack, large test suites can take longer to collect tests, increase timeout
-            instrTest.setCollectsTestsShellTimeout(10 * 60 * 1000);
-        }
         return instrTest;
     }
 
     /**
-     * Populates given {@link UiAutomatorJarTest} with data from the package xml.
-     *
-     * @param uiautomatorTest
-     * @return the populated {@link UiAutomatorJarTest} or <code>null</code>
-     */
-    @SuppressWarnings("deprecation")
-    private IRemoteTest setUiAutomatorTest(UiAutomatorJarTest uiautomatorTest) {
-        uiautomatorTest.setInstallArtifacts(getJarPath());
-        if (mClassName != null) {
-            if (mMethodName != null) {
-                CLog.logAndDisplay(LogLevel.WARN, "ui automator tests don't currently support" +
-                        "running  individual methods");
-            }
-            uiautomatorTest.addClassName(mClassName);
-        } else {
-            uiautomatorTest.addClassNames(mTestClasses);
-        }
-        uiautomatorTest.setRunName(mAppPackageName);
-        uiautomatorTest.setCaptureLogs(false);
-        return uiautomatorTest;
-    }
-
-    /**
      * Filter the tests to run based on list of included/excluded tests, class and method name.
      *
      * @return the filtered collection of tests
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageRepo.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageRepo.java
index 7e16170..9857105b 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageRepo.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageRepo.java
@@ -15,7 +15,7 @@
  */
 package com.android.cts.tradefed.testtype;
 
-import com.android.cts.util.AbiUtils;
+import com.android.compatibility.common.util.AbiUtils;
 import com.android.ddmlib.Log;
 import com.android.tradefed.config.ConfigurationException;
 import com.android.tradefed.config.ConfigurationFactory;
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageXmlParser.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageXmlParser.java
index 951c461..acd977e 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageXmlParser.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageXmlParser.java
@@ -15,7 +15,7 @@
  */
 package com.android.cts.tradefed.testtype;
 
-import com.android.cts.util.AbiUtils;
+import com.android.compatibility.common.util.AbiUtils;
 import com.android.ddmlib.Log;
 import com.android.ddmlib.testrunner.TestIdentifier;
 import com.android.tradefed.util.xml.AbstractXmlParser;
@@ -86,12 +86,8 @@
                 final String targetNameSpace = attributes.getValue("targetNameSpace");
                 final String runTimeArgs = attributes.getValue("runtimeArgs");
                 final String testType = getTestType(attributes);
-                long runTimeHint = 0;
-                if (attributes.getValue("runtimeHint") != null) {
-                    runTimeHint = Long.parseLong(attributes.getValue("runtimeHint"));
-                }
 
-                for (String abiName : AbiUtils.getAbisSupportedByCts()) {
+                for (String abiName : AbiUtils.getAbisSupportedByCompatibility()) {
                     Abi abi = new Abi(abiName, AbiUtils.getBitness(abiName));
                     TestPackageDef packageDef = new TestPackageDef();
                     packageDef.setAppPackageName(appPackageName);
@@ -106,7 +102,6 @@
                     }
                     packageDef.setTargetBinaryName(targetBinaryName);
                     packageDef.setTargetNameSpace(targetNameSpace);
-                    packageDef.setRuntimeHint(runTimeHint);
                     packageDef.setAbi(abi);
                     mPackageDefs.put(abiName, packageDef);
                 }
@@ -159,7 +154,7 @@
                         Set<String> abis = new HashSet<String>();
                         if (abiList == null) {
                             // If no specification, add all supported abis
-                            abis.addAll(AbiUtils.getAbisSupportedByCts());
+                            abis.addAll(AbiUtils.getAbisSupportedByCompatibility());
                         } else {
                             for (String abi : abiList.split(",")) {
                                 // Else only add the abi which are supported
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPlan.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPlan.java
index 2419784..6b02db9 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPlan.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPlan.java
@@ -16,7 +16,7 @@
 
 package com.android.cts.tradefed.testtype;
 
-import com.android.cts.util.AbiUtils;
+import com.android.compatibility.common.util.AbiUtils;
 import com.android.ddmlib.testrunner.TestIdentifier;
 import com.android.tradefed.util.ArrayUtil;
 import com.android.tradefed.util.xml.AbstractXmlParser;
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/UiAutomatorJarTest.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/UiAutomatorJarTest.java
deleted file mode 100644
index 83cc6d6..0000000
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/UiAutomatorJarTest.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.cts.tradefed.testtype;
-
-import com.android.cts.tradefed.build.CtsBuildHelper;
-import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.testtype.IBuildReceiver;
-import com.android.tradefed.testtype.UiAutomatorTest;
-
-import java.io.FileNotFoundException;
-import java.util.Arrays;
-
-import junit.framework.Assert;
-
-/**
- * A {@link UiAutomatorTest} that will install a uiautomator jar before test
- * execution, and uninstall on execution completion.
- */
-public class UiAutomatorJarTest extends UiAutomatorTest implements IBuildReceiver {
-
-    // TODO: expose this in parent
-    private static final String SHELL_EXE_BASE = "/data/local/tmp/";
-
-    /** the file names of the CTS jar to install */
-    private String mTestJarFileName;
-
-    private CtsBuildHelper mCtsBuild = null;
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void setBuild(IBuildInfo build) {
-        mCtsBuild  = CtsBuildHelper.createBuildHelper(build);
-    }
-
-    /**
-     * Setter for CTS build files needed to perform the test. 
-     *
-     * @param testJarName the file name of the jar containing the uiautomator tests
-     */
-    public void setInstallArtifacts(String testJarName) {
-        mTestJarFileName = testJarName;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void run(final ITestInvocationListener listener)
-            throws DeviceNotAvailableException {
-        Assert.assertNotNull("missing device", getDevice());
-        Assert.assertNotNull("missing build", mCtsBuild);
-        Assert.assertNotNull("missing jar to install", mTestJarFileName);
-
-        installJar();
-
-        super.run(listener);
-
-        uninstallJar();
-    }
-
-    private void installJar() throws DeviceNotAvailableException {
-        CLog.d("Installing %s on %s", mTestJarFileName, getDevice().getSerialNumber());
-        String fullJarPath = String.format("%s%s", SHELL_EXE_BASE, mTestJarFileName);
-        try {
-            boolean result = getDevice().pushFile(mCtsBuild.getTestApp(mTestJarFileName),
-                    fullJarPath);
-            Assert.assertTrue(String.format("Failed to push file to %s", fullJarPath), result);
-            setTestJarPaths(Arrays.asList(fullJarPath));
-        }  catch (FileNotFoundException e) {
-            Assert.fail(String.format("Could not find file %s", mTestJarFileName));
-        }
-    }
-
-    private void uninstallJar() throws DeviceNotAvailableException {
-        CLog.d("Uninstalling %s on %s", mTestJarFileName, getDevice().getSerialNumber());
-        String fullJarPath = String.format("%s%s", SHELL_EXE_BASE, mTestJarFileName);
-        getDevice().executeShellCommand(String.format("rm %s", fullJarPath));
-    }
-}
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/WrappedGTest.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/WrappedGTest.java
index e3ff8257..4f40c89 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/WrappedGTest.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/WrappedGTest.java
@@ -16,8 +16,8 @@
 
 package com.android.cts.tradefed.testtype;
 
+import com.android.compatibility.common.util.AbiUtils;
 import com.android.cts.tradefed.build.CtsBuildHelper;
-import com.android.cts.util.AbiUtils;
 import com.android.ddmlib.testrunner.ITestRunListener;
 import com.android.tradefed.build.IBuildInfo;
 import com.android.tradefed.device.DeviceNotAvailableException;
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/util/CtsHostStore.java b/tools/tradefed-host/src/com/android/cts/tradefed/util/CtsHostStore.java
deleted file mode 100644
index 288b48c..0000000
--- a/tools/tradefed-host/src/com/android/cts/tradefed/util/CtsHostStore.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.cts.tradefed.util;
-
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * Utility class for storing Cts Results.
- * This is necessary for host tests where test metrics cannot be passed.
- */
-public class CtsHostStore {
-
-    // needs concurrent version as there can be multiple client accessing this.
-    // But there is no additional protection for the same key as that should not happen.
-    private static final ConcurrentHashMap<String, String> mMap =
-            new ConcurrentHashMap<String, String>();
-
-    /**
-     * Stores CTS result. Existing result with the same key will be replaced.
-     * Note that key is generated in the form of device_serial#class#method name.
-     * So there should be no concurrent test for the same (serial, class, method).
-     * @param deviceSerial
-     * @param abi
-     * @param classMethodName
-     * @param result CTS result string
-     */
-    public static void storeCtsResult(String deviceSerial, String abi, String classMethodName, String result) {
-        mMap.put(generateTestKey(deviceSerial, abi, classMethodName), result);
-    }
-
-    /**
-     * retrieves a CTS result for the given condition and remove it from the internal
-     * storage. If there is no result for the given condition, it will return null.
-     */
-    public static String removeCtsResult(String deviceSerial, String abi, String classMethodName) {
-        return mMap.remove(generateTestKey(deviceSerial, abi, classMethodName));
-    }
-
-    /**
-     * @return test key in the form of device_serial#abi#class_name#method_name
-     */
-    private static String generateTestKey(String deviceSerial, String abi, String classMethodName) {
-        return String.format("%s#%s#%s", deviceSerial, abi, classMethodName);
-
-    }
-}
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/util/HostReportLog.java b/tools/tradefed-host/src/com/android/cts/tradefed/util/HostReportLog.java
index 645dbb9..f72b097 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/util/HostReportLog.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/util/HostReportLog.java
@@ -16,17 +16,17 @@
 
 package com.android.cts.tradefed.util;
 
+import com.android.compatibility.common.util.MetricsReportLog;
 import com.android.cts.util.ReportLog;
 
 /**
  * ReportLog for host tests
  * Note that setTestInfo should be set before throwing report
+ *
+ * This class is deprecated, use {@link MetricsReportLog} instead.
  */
+@Deprecated
 public class HostReportLog extends ReportLog {
-    private final String mDeviceSerial;
-    private final String mAbiName;
-    private final String mClassMethodName;
-
     /**
      * @param deviceSerial serial number of the device
      * @param abiName the name of the ABI on which the test was run
@@ -34,12 +34,10 @@
      *        Note that ReportLog.getClassMethodNames() provide this.
      */
     public HostReportLog(String deviceSerial, String abiName, String classMethodName) {
-        mDeviceSerial = deviceSerial;
-        mAbiName = abiName;
-        mClassMethodName = classMethodName;
+        super(new MetricsReportLog(deviceSerial, abiName, classMethodName));
     }
 
     public void deliverReportToHost() {
-        CtsHostStore.storeCtsResult(mDeviceSerial, mAbiName, mClassMethodName, generateReport());
+        ((MetricsReportLog) mReportLog).submit();
     }
-}
+}
\ No newline at end of file
diff --git a/tools/tradefed-host/tests/Android.mk b/tools/tradefed-host/tests/Android.mk
index 2734a5b..365deb8 100644
--- a/tools/tradefed-host/tests/Android.mk
+++ b/tools/tradefed-host/tests/Android.mk
@@ -19,9 +19,9 @@
 # Only compile source java files in this lib.
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
-LOCAL_MODULE := cts-tradefed-tests
+LOCAL_MODULE := old-cts-tradefed-tests
 LOCAL_MODULE_TAGS := optional
-LOCAL_JAVA_LIBRARIES := tradefed-prebuilt cts-tradefed
+LOCAL_JAVA_LIBRARIES := tradefed-prebuilt old-cts-tradefed
 LOCAL_STATIC_JAVA_LIBRARIES := easymock
 
 include $(BUILD_HOST_JAVA_LIBRARY)
\ No newline at end of file
diff --git a/tools/tradefed-host/tests/run_unit_func_tests.sh b/tools/tradefed-host/tests/run_unit_func_tests.sh
index 461a80d..8c08c4e 100755
--- a/tools/tradefed-host/tests/run_unit_func_tests.sh
+++ b/tools/tradefed-host/tests/run_unit_func_tests.sh
@@ -37,7 +37,7 @@
 fi;
 
 JAR_DIR=${ANDROID_BUILD_TOP}/out/host/$OS/framework
-JARS="tradefed-prebuilt.jar hosttestlib.jar cts-tradefed.jar cts-tradefed-tests.jar"
+JARS="tradefed-prebuilt.jar hosttestlib.jar old-cts-tradefed.jar old-cts-tradefed-tests.jar"
 
 for JAR in $JARS; do
     checkFile ${JAR_DIR}/${JAR}
diff --git a/tools/tradefed-host/tests/run_unit_tests.sh b/tools/tradefed-host/tests/run_unit_tests.sh
index d089c05..a1bb12c 100755
--- a/tools/tradefed-host/tests/run_unit_tests.sh
+++ b/tools/tradefed-host/tests/run_unit_tests.sh
@@ -37,7 +37,7 @@
 fi;
 
 JAR_DIR=${ANDROID_BUILD_TOP}/out/host/$OS/framework
-JARS="tradefed-prebuilt.jar hosttestlib.jar cts-tradefed.jar cts-tradefed-tests.jar"
+JARS="tradefed-prebuilt.jar hosttestlib.jar old-cts-tradefed.jar old-cts-tradefed-tests.jar"
 
 for JAR in $JARS; do
     checkFile ${JAR_DIR}/${JAR}
diff --git a/tools/tradefed-host/tests/src/com/android/cts/tradefed/result/CtsXmlResultReporterTest.java b/tools/tradefed-host/tests/src/com/android/cts/tradefed/result/CtsXmlResultReporterTest.java
index 958dbe4..361b91c 100644
--- a/tools/tradefed-host/tests/src/com/android/cts/tradefed/result/CtsXmlResultReporterTest.java
+++ b/tools/tradefed-host/tests/src/com/android/cts/tradefed/result/CtsXmlResultReporterTest.java
@@ -17,11 +17,10 @@
 
 import static com.android.cts.tradefed.result.CtsXmlResultReporter.CTS_RESULT_FILE_VERSION;
 
+import com.android.compatibility.common.util.AbiUtils;
 import com.android.cts.tradefed.UnitTests;
-import com.android.cts.util.AbiUtils;
 import com.android.ddmlib.testrunner.TestIdentifier;
 import com.android.tradefed.build.IFolderBuildInfo;
-import com.android.tradefed.log.LogUtil.CLog;
 import com.android.tradefed.result.LogDataType;
 import com.android.tradefed.result.LogFile;
 import com.android.tradefed.result.TestSummary;
@@ -36,8 +35,8 @@
 import java.io.File;
 import java.io.IOException;
 import java.io.OutputStream;
-import java.util.Arrays;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
diff --git a/tools/tradefed-host/tests/src/com/android/cts/tradefed/testtype/CtsTestTest.java b/tools/tradefed-host/tests/src/com/android/cts/tradefed/testtype/CtsTestTest.java
index 98caad1..19204b7 100644
--- a/tools/tradefed-host/tests/src/com/android/cts/tradefed/testtype/CtsTestTest.java
+++ b/tools/tradefed-host/tests/src/com/android/cts/tradefed/testtype/CtsTestTest.java
@@ -15,10 +15,10 @@
  */
 package com.android.cts.tradefed.testtype;
 
+import com.android.compatibility.common.util.AbiUtils;
 import com.android.cts.tradefed.UnitTests;
 import com.android.cts.tradefed.build.StubCtsBuildHelper;
 import com.android.cts.tradefed.result.PlanCreator;
-import com.android.cts.util.AbiUtils;
 import com.android.ddmlib.testrunner.TestIdentifier;
 import com.android.tradefed.device.DeviceNotAvailableException;
 import com.android.tradefed.device.ITestDevice;
diff --git a/tools/tradefed-host/tests/src/com/android/cts/tradefed/testtype/DeqpTestRunnerTest.java b/tools/tradefed-host/tests/src/com/android/cts/tradefed/testtype/DeqpTestRunnerTest.java
index a22634f..2ba6b42 100644
--- a/tools/tradefed-host/tests/src/com/android/cts/tradefed/testtype/DeqpTestRunnerTest.java
+++ b/tools/tradefed-host/tests/src/com/android/cts/tradefed/testtype/DeqpTestRunnerTest.java
@@ -15,18 +15,16 @@
  */
 package com.android.cts.tradefed.testtype;
 
-import com.android.cts.tradefed.build.StubCtsBuildHelper;
+import com.android.compatibility.common.util.AbiUtils;
 import com.android.cts.tradefed.UnitTests;
-import com.android.cts.util.AbiUtils;
+import com.android.cts.tradefed.build.StubCtsBuildHelper;
 import com.android.ddmlib.IDevice;
 import com.android.ddmlib.IShellOutputReceiver;
 import com.android.ddmlib.ShellCommandUnresponsiveException;
-import com.android.ddmlib.testrunner.ITestRunListener;
 import com.android.ddmlib.testrunner.TestIdentifier;
 import com.android.tradefed.device.DeviceNotAvailableException;
 import com.android.tradefed.device.ITestDevice;
 import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.testtype.IAbi;
 import com.android.tradefed.util.IRunUtil;
 import com.android.tradefed.util.RunInterruptedException;
 
@@ -38,7 +36,6 @@
 
 import java.io.File;
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.List;
diff --git a/tools/tradefed-host/tests/src/com/android/cts/tradefed/testtype/TestPackageXmlParserTest.java b/tools/tradefed-host/tests/src/com/android/cts/tradefed/testtype/TestPackageXmlParserTest.java
index bd48c51..8655885 100644
--- a/tools/tradefed-host/tests/src/com/android/cts/tradefed/testtype/TestPackageXmlParserTest.java
+++ b/tools/tradefed-host/tests/src/com/android/cts/tradefed/testtype/TestPackageXmlParserTest.java
@@ -16,7 +16,7 @@
 
 package com.android.cts.tradefed.testtype;
 
-import com.android.cts.util.AbiUtils;
+import com.android.compatibility.common.util.AbiUtils;
 import com.android.ddmlib.testrunner.TestIdentifier;
 import com.android.tradefed.util.xml.AbstractXmlParser.ParseException;
 
@@ -100,7 +100,7 @@
             assertEquals("com.example", def.getAppNameSpace());
             assertEquals("android.example", def.getAppPackageName());
             assertEquals("android.test.InstrumentationTestRunner", def.getRunner());
-            assertTrue(AbiUtils.isAbiSupportedByCts(def.getAbi().getName()));
+            assertTrue(AbiUtils.isAbiSupportedByCompatibility(def.getAbi().getName()));
         }
     }
 
diff --git a/tools/tradefed-host/tests/src/com/android/cts/tradefed/testtype/TestPlanTest.java b/tools/tradefed-host/tests/src/com/android/cts/tradefed/testtype/TestPlanTest.java
index 5b28539..be260ea 100644
--- a/tools/tradefed-host/tests/src/com/android/cts/tradefed/testtype/TestPlanTest.java
+++ b/tools/tradefed-host/tests/src/com/android/cts/tradefed/testtype/TestPlanTest.java
@@ -16,7 +16,7 @@
 
 package com.android.cts.tradefed.testtype;
 
-import com.android.cts.util.AbiUtils;
+import com.android.compatibility.common.util.AbiUtils;
 import com.android.ddmlib.testrunner.TestIdentifier;
 import com.android.tradefed.util.xml.AbstractXmlParser.ParseException;
 
@@ -75,7 +75,7 @@
     @Override
     protected void setUp() throws Exception {
         super.setUp();
-        mPlan = new TestPlan("plan", AbiUtils.getAbisSupportedByCts());
+        mPlan = new TestPlan("plan", AbiUtils.getAbisSupportedByCompatibility());
     }
 
     /**
@@ -91,7 +91,7 @@
      * @param plan
      */
     private void assertTestData(TestPlan plan) {
-        Set<String> abis = AbiUtils.getAbisSupportedByCts();
+        Set<String> abis = AbiUtils.getAbisSupportedByCompatibility();
         assertEquals(2 * abis.size(), plan.getTestIds().size());
         List<String> sortedAbis = new ArrayList<String>(abis);
         Collections.sort(sortedAbis);
@@ -112,7 +112,7 @@
      */
     public void testParse_exclude() throws ParseException  {
         mPlan.parse(getStringAsStream(TEST_EXCLUDED_DATA));
-        Set<String> abis = AbiUtils.getAbisSupportedByCts();
+        Set<String> abis = AbiUtils.getAbisSupportedByCompatibility();
         assertEquals(abis.size(), mPlan.getTestIds().size());
 
         for (String abi : abis) {
@@ -136,7 +136,7 @@
      * @param plan
      */
     private void assertMultiExcluded(TestPlan plan) {
-        Set<String> abis = AbiUtils.getAbisSupportedByCts();
+        Set<String> abis = AbiUtils.getAbisSupportedByCompatibility();
         assertEquals(abis.size(), plan.getTestIds().size());
 
         for (String abi : abis) {
@@ -154,7 +154,7 @@
      */
     public void testParse_classExclude() throws ParseException  {
         mPlan.parse(getStringAsStream(TEST_CLASS_EXCLUDED_DATA));
-        Set<String> abis = AbiUtils.getAbisSupportedByCts();
+        Set<String> abis = AbiUtils.getAbisSupportedByCompatibility();
         assertEquals(abis.size(), mPlan.getTestIds().size());
 
         for (String abi : abis) {
@@ -179,14 +179,14 @@
      * @throws IOException
      */
     public void testSerialize_packages() throws ParseException, IOException  {
-        Set<String> abis = AbiUtils.getAbisSupportedByCts();
+        Set<String> abis = AbiUtils.getAbisSupportedByCompatibility();
         for (String abi : abis) {
             mPlan.addPackage(AbiUtils.createId(abi, TEST_NAME1));
             mPlan.addPackage(AbiUtils.createId(abi, TEST_NAME2));
         }
         ByteArrayOutputStream outStream = new ByteArrayOutputStream();
         mPlan.serialize(outStream);
-        TestPlan parsedPlan = new TestPlan("parsed", AbiUtils.getAbisSupportedByCts());
+        TestPlan parsedPlan = new TestPlan("parsed", AbiUtils.getAbisSupportedByCompatibility());
         parsedPlan.parse(getStringAsStream(outStream.toString()));
         // parsedPlan should contain same contents as TEST_DATA
         assertTestData(parsedPlan);
@@ -196,7 +196,7 @@
      * Test serializing and deserializing plan with multiple excluded tests
      */
     public void testSerialize_multiExclude() throws ParseException, IOException  {
-        Set<String> abis = AbiUtils.getAbisSupportedByCts();
+        Set<String> abis = AbiUtils.getAbisSupportedByCompatibility();
 
         for (String abi : abis) {
             String test1Id = AbiUtils.createId(abi, TEST_NAME1);
@@ -208,7 +208,7 @@
         }
         ByteArrayOutputStream outStream = new ByteArrayOutputStream();
         mPlan.serialize(outStream);
-        TestPlan parsedPlan = new TestPlan("parsed", AbiUtils.getAbisSupportedByCts());
+        TestPlan parsedPlan = new TestPlan("parsed", AbiUtils.getAbisSupportedByCompatibility());
         parsedPlan.parse(getStringAsStream(outStream.toString()));
         // parsedPlan should contain same contents as TEST_DATA
         assertMultiExcluded(parsedPlan);
diff --git a/tools/utils/Android.mk b/tools/utils/Android.mk
index 0ba5cf4..d26abb1 100644
--- a/tools/utils/Android.mk
+++ b/tools/utils/Android.mk
@@ -25,6 +25,6 @@
 LOCAL_CLASSPATH := $(HOST_JDK_TOOLS_JAR)
 
 LOCAL_JAVA_LIBRARIES := junit
-LOCAL_STATIC_JAVA_LIBRARIES := ctsabiutilslib vogarexpectlib
+LOCAL_STATIC_JAVA_LIBRARIES := compatibility-host-util vogarexpectlib
 
 include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/tools/utils/CollectAllTests.java b/tools/utils/CollectAllTests.java
index 83c451e..8003f4d 100644
--- a/tools/utils/CollectAllTests.java
+++ b/tools/utils/CollectAllTests.java
@@ -13,7 +13,8 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-import com.android.cts.util.AbiUtils;
+
+import com.android.compatibility.common.util.AbiUtils;
 
 import org.junit.runner.RunWith;
 import org.w3c.dom.Document;
@@ -220,6 +221,13 @@
                 continue;
             }
 
+            // Avoid inner classes: they should not have tests and often they can have dependencies
+            // on test frameworks that need to be resolved and would need to be on the classpath.
+            // e.g. Mockito.
+            if (className.contains("$")) {
+                continue;
+            }
+
             try {
                 Class<?> klass = Class.forName(className,
                                                false,
diff --git a/tools/utils/VogarUtils.java b/tools/utils/VogarUtils.java
index 8e77e7c..77c62da 100644
--- a/tools/utils/VogarUtils.java
+++ b/tools/utils/VogarUtils.java
@@ -14,13 +14,13 @@
  * limitations under the License.
  */
 
-import com.android.cts.util.AbiUtils;
-
 import vogar.Expectation;
 import vogar.ExpectationStore;
 import vogar.ModeId;
 import vogar.Result;
 
+import com.android.compatibility.common.util.AbiUtils;
+
 import java.io.File;
 import java.io.FilenameFilter;
 import java.io.IOException;
diff --git a/tools/utils/buildCts.py b/tools/utils/buildCts.py
index 9f462ca..f983b15 100755
--- a/tools/utils/buildCts.py
+++ b/tools/utils/buildCts.py
@@ -20,6 +20,7 @@
 import os
 import re
 import shutil
+import string
 import subprocess
 import sys
 import xml.dom.minidom as dom
@@ -37,6 +38,16 @@
   f.close()
   return lines
 
+def ReadDeqpTestList(testRoot, file):
+  """Reads a file, converts test names from deqp to CTS format, and returns
+  its contents as a line list.
+  """
+  REPO_ROOT = os.path.join(testRoot, "../../..")
+  f = open(os.path.join(REPO_ROOT, "external/deqp/android/cts", file), 'r');
+  lines = [string.join(line.strip().rsplit('.',1),'#') for line in f.readlines()]
+  f.close()
+  return lines
+
 def GetMakeFileVars(makefile_path):
   """Extracts variable definitions from the given make file.
 
@@ -107,17 +118,20 @@
     packages.sort()
 
     plan = tools.TestPlan(packages)
+    plan.Exclude('android\.car')
     plan.Exclude('android\.performance.*')
     self.__WritePlan(plan, 'CTS')
     self.__WritePlan(plan, 'CTS-TF')
 
     plan = tools.TestPlan(packages)
+    plan.Exclude('android\.car')
     plan.Exclude('android\.performance.*')
     plan.Exclude('android\.media\.cts\.StreamingMediaPlayerTest.*')
     # Test plan to not include media streaming tests
     self.__WritePlan(plan, 'CTS-No-Media-Stream')
 
     plan = tools.TestPlan(packages)
+    plan.Exclude('android\.car')
     plan.Exclude('android\.performance.*')
     self.__WritePlan(plan, 'SDK')
 
@@ -127,12 +141,12 @@
 
     plan = tools.TestPlan(packages)
     plan.Include(r'android\.core\.tests.*')
-    plan.Exclude(r'android\.core\.tests\.libcore.\package.\harmony*')
+    plan.Exclude(r'android\.core\.tests\.libcore\.package\.harmony*')
     self.__WritePlan(plan, 'Java')
 
     # TODO: remove this once the tests are fixed and merged into Java plan above.
     plan = tools.TestPlan(packages)
-    plan.Include(r'android\.core\.tests\.libcore.\package.\harmony*')
+    plan.Include(r'android\.core\.tests\.libcore\.package\.harmony*')
     self.__WritePlan(plan, 'Harmony')
 
     plan = tools.TestPlan(packages)
@@ -157,6 +171,7 @@
     plan.Include('android\.telephony')
     plan.Include('android\.nativemedia.*')
     plan.Include('com\.android\.cts\..*')#TODO(stuartscott): Should PDK have all these?
+    plan.Exclude('android\.car')
     self.__WritePlan(plan, 'PDK')
 
     temporarily_known_failure_tests = BuildCtsTemporarilyKnownFailureList();
@@ -165,7 +180,8 @@
 
     # CTS Stable plan
     plan = tools.TestPlan(packages)
-    plan.Exclude(r'com\.android\.cts\.browserbench')
+    plan.Exclude('android\.car')
+    plan.Exclude(r'android\.browser')
     for package, test_list in flaky_tests.iteritems():
       plan.ExcludeTests(package, test_list)
     for package, test_list in releasekey_tests.iteritems():
@@ -175,7 +191,7 @@
     # CTS Flaky plan - list of tests known to be flaky in lab environment
     plan = tools.TestPlan(packages)
     plan.Exclude('.*')
-    plan.Include(r'com\.android\.cts\.browserbench')
+    plan.Include(r'android\.browser')
     for package, test_list in flaky_tests.iteritems():
       plan.Include(package+'$')
       plan.IncludeTests(package, test_list)
@@ -190,7 +206,7 @@
     plan.Exclude('.*')
     for package, test_list in small_tests.iteritems():
       plan.Include(package+'$')
-    plan.Exclude(r'com\.android\.cts\.browserbench')
+    plan.Exclude(r'android\.browser')
     for package, test_list in flaky_tests.iteritems():
       plan.ExcludeTests(package, test_list)
     for package, test_list in releasekey_tests.iteritems():
@@ -203,7 +219,7 @@
     plan.Exclude('.*')
     for package, test_list in medium_tests.iteritems():
       plan.Include(package+'$')
-    plan.Exclude(r'com\.android\.cts\.browserbench')
+    plan.Exclude(r'android\.browser')
     for package, test_list in flaky_tests.iteritems():
       plan.ExcludeTests(package, test_list)
     for package, test_list in releasekey_tests.iteritems():
@@ -215,7 +231,7 @@
     plan = tools.TestPlan(packages)
     plan.Exclude('.*')
     plan.Include(r'android\.hardware$')
-    plan.Exclude(r'com\.android\.cts\.browserbench')
+    plan.Exclude(r'android\.browser')
     for package, test_list in flaky_tests.iteritems():
       plan.ExcludeTests(package, test_list)
     for package, test_list in releasekey_tests.iteritems():
@@ -241,7 +257,7 @@
     plan.Exclude('.*')
     plan.Include(r'android\.media$')
     plan.Include(r'android\.view$')
-    plan.Exclude(r'com\.android\.cts\.browserbench')
+    plan.Exclude(r'android\.browser')
     for package, test_list in flaky_tests.iteritems():
       plan.ExcludeTests(package, test_list)
     for package, test_list in releasekey_tests.iteritems():
@@ -252,7 +268,7 @@
     plan = tools.TestPlan(packages)
     plan.Exclude('.*')
     plan.Include(r'android\.mediastress$')
-    plan.Exclude(r'com\.android\.cts\.browserbench')
+    plan.Exclude(r'android\.browser')
     for package, test_list in flaky_tests.iteritems():
       plan.ExcludeTests(package, test_list)
     for package, test_list in releasekey_tests.iteritems():
@@ -264,7 +280,7 @@
     plan.Exclude('.*')
     for package, test_list in new_test_packages.iteritems():
       plan.Include(package+'$')
-    plan.Exclude(r'com\.android\.cts\.browserbench')
+    plan.Exclude(r'android\.browser')
     for package, test_list in flaky_tests.iteritems():
       plan.ExcludeTests(package, test_list)
     for package, test_list in releasekey_tests.iteritems():
@@ -275,8 +291,21 @@
     plan = tools.TestPlan(packages)
     plan.Exclude('.*')
     plan.Include(r'com\.drawelements\.')
+    plan.IncludeTests('com.drawelements.deqp.egl', ReadDeqpTestList(self.test_root, 'mnc/egl-master.txt'))
+    plan.IncludeTests('com.drawelements.deqp.gles2', ReadDeqpTestList(self.test_root, 'mnc/gles2-master.txt'))
+    plan.IncludeTests('com.drawelements.deqp.gles3', ReadDeqpTestList(self.test_root, 'mnc/gles3-master.txt'))
+    plan.IncludeTests('com.drawelements.deqp.gles31', ReadDeqpTestList(self.test_root, 'mnc/gles31-master.txt'))
     self.__WritePlan(plan, 'CTS-DEQP')
 
+    plan = tools.TestPlan(packages)
+    plan.Exclude('.*')
+    plan.Include(r'com\.drawelements\.')
+    plan.ExcludeTests('com.drawelements.deqp.egl', ReadDeqpTestList(self.test_root, 'mnc/egl-master.txt'))
+    plan.ExcludeTests('com.drawelements.deqp.gles2', ReadDeqpTestList(self.test_root, 'mnc/gles2-master.txt'))
+    plan.ExcludeTests('com.drawelements.deqp.gles3', ReadDeqpTestList(self.test_root, 'mnc/gles3-master.txt'))
+    plan.ExcludeTests('com.drawelements.deqp.gles31', ReadDeqpTestList(self.test_root, 'mnc/gles31-master.txt'))
+    self.__WritePlan(plan, 'CTS-DEQP-for-next-rel')
+
     # CTS - sub plan for new test packages added for staging
     plan = tools.TestPlan(packages)
     for package, test_list in small_tests.iteritems():
@@ -290,7 +319,8 @@
     plan.Exclude(r'android\.media$')
     plan.Exclude(r'android\.view$')
     plan.Exclude(r'android\.mediastress$')
-    plan.Exclude(r'com\.android\.cts\.browserbench')
+    plan.Exclude(r'android\.browser')
+    plan.Exclude('android\.car')
     for package, test_list in flaky_tests.iteritems():
       plan.ExcludeTests(package, test_list)
     for package, test_list in releasekey_tests.iteritems():
@@ -315,6 +345,7 @@
     plan.Exclude('.*')
     plan.Include(r'android\.security$')
     plan.Include('android\.host\.jdwpsecurity$')
+    plan.Include('android\.host\.abioverride$')
     self.__WritePlan(plan, 'Security')
 
 def BuildAospMediumSizeTestList():
@@ -334,7 +365,7 @@
       'android.telephony' : [],
       'android.webkit' : [],
       'android.widget' : [],
-      'com.android.cts.browserbench' : []}
+      'android.browser' : []}
 
 def BuildAospSmallSizeTestList():
   """ Construct a default dict that lists packages names of small tests
@@ -347,6 +378,7 @@
       'android.accounts' : [],
       'android.admin' : [],
       'android.animation' : [],
+      'android.appsecurity' : [],
       'android.bionic' : [],
       'android.bluetooth' : [],
       'android.calendarcommon' : [],
@@ -357,9 +389,11 @@
       'android.core.tests.libcore.package.sun' : [],
       'android.core.tests.libcore.package.tests' : [],
       'android.database' : [],
+      'android.dram' : [],
       'android.dreams' : [],
       'android.drm' : [],
       'android.effect' : [],
+      'android.filesystem' : [],
       'android.gesture' : [],
       'android.graphics' : [],
       'android.graphics2' : [],
@@ -368,7 +402,6 @@
       'android.location' : [],
       'android.nativemedia.sl' : [],
       'android.nativemedia.xa' : [],
-      'android.nativeopengl' : [],
       'android.ndef' : [],
       'android.opengl' : [],
       'android.openglperf' : [],
@@ -380,23 +413,22 @@
       'android.rscpp' : [],
       'android.rsg' : [],
       'android.sax' : [],
+      'android.server' : [],
       'android.signature' : [],
+      'android.simplecpu' : [],
+      'android.simpleperf' : [],
       'android.speech' : [],
-      'android.tests.appsecurity' : [],
       'android.text' : [],
       'android.textureview' : [],
       'android.theme' : [],
       'android.usb' : [],
       'android.util' : [],
-      'com.android.cts.dram' : [],
-      'com.android.cts.filesystemperf' : [],
+      'android.video' : [],
       'com.android.cts.jank' : [],
       'com.android.cts.jank2' : [],
       'com.android.cts.opengl' : [],
-      'com.android.cts.simplecpu' : [],
       'com.android.cts.ui' : [],
       'com.android.cts.uihost' : [],
-      'com.android.cts.videoperf' : [],
       'zzz.android.monkey' : []}
 
 def BuildCtsVettedNewPackagesList():
@@ -516,8 +548,8 @@
       'android.voicesettings' : [
           'android.voicesettings.cts.ZenModeTest#testAll',
       ],
-      'com.android.cts.systemui' : [
-          'com.android.cts.systemui.LightStatusBarTests#testLightStatusBarIcons',
+      'android.systemui.cts' : [
+          'android.systemui.cts.LightStatusBarTests#testLightStatusBarIcons',
       ],
       'com.android.cts.app.os' : [
           'com.android.cts.app.os.OsHostTests#testNonExportedActivities',
@@ -550,4 +582,3 @@
   if result != 0:
     sys.exit(result)
   builder.GenerateTestPlans()
-
diff --git a/tools/utils/certificates.py b/tools/utils/certificates.py
new file mode 100644
index 0000000..dc92767
--- /dev/null
+++ b/tools/utils/certificates.py
@@ -0,0 +1,100 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the 'License');
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an 'AS IS' BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+import random
+
+from OpenSSL import crypto
+from Crypto.PublicKey import RSA
+
+class Certificate(object):
+    cert = None
+    key = None
+    def __init__(self, cert, key):
+        self.cert = cert
+        self.key = key
+
+    def cert_pem(self):
+        return crypto.dump_certificate(crypto.FILETYPE_PEM, self.cert)
+
+    def key_pem(self):
+        return crypto.dump_privatekey(crypto.FILETYPE_PEM, self.key)
+
+    def save_to_file(self, path):
+        with open(path, "w") as f:
+            f.write(self.cert_pem())
+            f.write(self.key_pem())
+
+    def save_cert_to_file(self, path):
+        with open(path, "w") as f:
+            f.write(self.cert_pem())
+
+    @staticmethod
+    def from_file(path):
+        with open(path) as f:
+            data = f.read()
+            cert = crypto.load_certificate(crypto.FILETYPE_PEM, data)
+            key = crypto.load_privatekey(crypto.FILETYPE_PEM, data)
+            return Certificate(cert, key)
+
+    @staticmethod
+    def create(cn, issuer=None, key=None, keysize=2048, digest="sha256",
+            notBefore="20150101000000+0000", notAfter="20300101000000+0000",
+            additional_extensions=None):
+        if key is None:
+            key = crypto.PKey()
+            key.generate_key(crypto.TYPE_RSA, keysize)
+
+        cert = crypto.X509()
+        cert.set_pubkey(key)
+        cert.set_version(2)
+        cert.set_serial_number(random.randint(0, 2**20))
+
+        cert.set_notBefore(notBefore)
+        cert.set_notAfter(notAfter)
+        cert.get_subject().CN = cn
+        cert.set_issuer(cert.get_subject() if issuer is None else issuer.cert.get_subject())
+        # Add the CA=True basic constraint
+        basicContraints = crypto.X509Extension("basicConstraints", True, "CA:TRUE")
+        cert.add_extensions([basicContraints])
+        if additional_extensions is not None:
+            cert.add_extensions(additional_extensions)
+
+        signing_key = key if issuer is None else issuer.key
+        cert.sign(signing_key, digest)
+
+        return Certificate(cert, key)
+
+if __name__ == "__main__":
+    # Generate test certificates.
+    a = Certificate.create("Root A")
+    a_sha1 = Certificate.create("Root A", key=a.key, digest="sha1")
+    b = Certificate.create("Root B")
+    a_to_b = Certificate.create("Root A", b, a.key)
+    b_to_a = Certificate.create("Root B", a, b.key)
+    leaf1 = Certificate.create("Leaf", a)
+    intermediate_a = Certificate.create("intermediate", a)
+    intermediate_b = Certificate.create("intermediate", b, intermediate_a.key)
+    leaf2 = Certificate.create("Leaf 2", intermediate_a)
+
+    # Save test certificates.
+    a.save_cert_to_file("a.pem")
+    a_sha1.save_cert_to_file("a_sha1.pem")
+    b.save_cert_to_file("b.pem")
+    a_to_b.save_cert_to_file("a_to_b.pem")
+    b_to_a.save_cert_to_file("b_to_a.pem")
+    leaf1.save_cert_to_file("leaf1.pem")
+    leaf2.save_cert_to_file("leaf2.pem")
+    intermediate_a.save_cert_to_file("intermediate_a.pem")
+    intermediate_b.save_cert_to_file("intermediate_b.pem")
diff --git a/tools/utils/java-cert-list-generator.sh b/tools/utils/java-cert-list-generator.sh
index b8cee18..33e9aaa 100755
--- a/tools/utils/java-cert-list-generator.sh
+++ b/tools/utils/java-cert-list-generator.sh
@@ -50,7 +50,7 @@
   static final String[] CERTIFICATE_DATA = {
 STARTCLASS
 
-CERT_DIRECTORY=$ANDROID_BUILD_TOP/libcore/luni/src/main/files/cacerts
+CERT_DIRECTORY=$ANDROID_BUILD_TOP/system/ca-certificates/files/
 for FILE in `ls $CERT_DIRECTORY`; do
   FINGERPRINT=`cat $CERT_DIRECTORY/$FILE | grep "SHA1 Fingerprint=" | cut -d '=' -f 2`
   echo "      \"${FINGERPRINT}\","
diff --git a/tools/vm-tests-tf/Android.mk b/tools/vm-tests-tf/Android.mk
index b1cbe37..ef6aa84 100644
--- a/tools/vm-tests-tf/Android.mk
+++ b/tools/vm-tests-tf/Android.mk
@@ -30,17 +30,11 @@
 
 cts-tf-dalvik-lib.jack := $(full_classes_jack)
 
-private_jill_jarjar_asm := $(addprefix $(HOST_OUT_JAVA_LIBRARIES)/,jill-jarjar-asm.jar)
-$(private_jill_jarjar_asm) : PRIVATE_JARJAR_RULES := $(LOCAL_PATH)/jill-jarjar-rules.txt
-$(private_jill_jarjar_asm) : $(addprefix $(HOST_OUT_JAVA_LIBRARIES)/,jill.jar) | $(JARJAR)
-	@echo JarJar: $@
-	$(hide) java -jar $(JARJAR) process $(PRIVATE_JARJAR_RULES) $< $@
-
 # buildutil java library
 # ============================================================
 include $(CLEAR_VARS)
 
-# custom variables used to generate test description. do not touch!
+# custom variables used by cts/tools/utils/CollectAllTests.java to generate test description. do not touch!
 LOCAL_TEST_TYPE := vmHostTest
 LOCAL_JAR_PATH := android.core.vm-tests-tf.jar
 
@@ -50,10 +44,9 @@
 LOCAL_MODULE_CLASS := JAVA_LIBRARIES
 LOCAL_MODULE_TAGS := optional
 
-LOCAL_JAVA_LIBRARIES := dx dasm cfassembler junit
-LOCAL_JAVA_LIBRARIES += jack
+LOCAL_JAVA_LIBRARIES := dx dasm cfassembler junit jsr305lib
 
-LOCAL_CLASSPATH := $(HOST_JDK_TOOLS_JAR) $(private_jill_jarjar_asm)
+LOCAL_CLASSPATH := $(HOST_JDK_TOOLS_JAR)
 
 include $(BUILD_HOST_JAVA_LIBRARY)
 
@@ -63,28 +56,39 @@
 include $(CLEAR_VARS)
 
 LOCAL_JACK_ENABLED := $(strip $(LOCAL_JACK_ENABLED))
-intermediates := $(call intermediates-dir-for,JAVA_LIBRARIES,vm-tests-tf,HOST)
-vmteststf_jar := $(intermediates)/android.core.vm-tests-tf.jar
-vmteststf_dep_jars := $(addprefix $(HOST_OUT_JAVA_LIBRARIES)/, cts-tf-dalvik-buildutil.jar dasm.jar dx.jar cfassembler.jar junit.jar)
-vmteststf_dep_jars += $(addprefix $(HOST_OUT_JAVA_LIBRARIES)/, jack.jar)
-vmteststf_dep_jars += $(private_jill_jarjar_asm)
+LOCAL_MODULE := vm-tests-tf
+LOCAL_MODULE_CLASS := JAVA_LIBRARIES
+LOCAL_MODULE_SUFFIX := $(COMMON_JAVA_PACKAGE_SUFFIX)
+LOCAL_IS_HOST_MODULE := true
+LOCAL_BUILT_MODULE_STEM := javalib.jar
+intermediates := $(call local-intermediates-dir)
+# Install the module as $(intermediates)/android.core.vm-tests-tf.jar.
+LOCAL_INSTALLED_MODULE_STEM := android.core.vm-tests-tf.jar
+LOCAL_MODULE_PATH := $(intermediates)
 
-$(vmteststf_jar): PRIVATE_JACK_VM_ARGS := $(LOCAL_JACK_VM_ARGS)
-$(vmteststf_jar): PRIVATE_JACK_EXTRA_ARGS := $(LOCAL_JACK_EXTRA_ARGS)
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+vmteststf_dep_jars := $(addprefix $(HOST_OUT_JAVA_LIBRARIES)/, cts-tf-dalvik-buildutil.jar dasm.jar dx.jar cfassembler.jar junit.jar)
+
+$(LOCAL_BUILT_MODULE): PRIVATE_JACK_EXTRA_ARGS := $(LOCAL_JACK_EXTRA_ARGS)
 
 ifdef LOCAL_JACK_ENABLED
     vmteststf_dep_jars += $(cts-tf-dalvik-lib.jack)
 endif
 
-$(vmteststf_jar): PRIVATE_SRC_FOLDER := $(LOCAL_PATH)/src
-$(vmteststf_jar): PRIVATE_INTERMEDIATES_CLASSES := $(call intermediates-dir-for,JAVA_LIBRARIES,cts-tf-dalvik-buildutil,HOST)/classes
-$(vmteststf_jar): PRIVATE_INTERMEDIATES := $(intermediates)/tests
-$(vmteststf_jar): PRIVATE_INTERMEDIATES_DEXCORE_JAR := $(intermediates)/tests/dot/junit/dexcore.jar
-$(vmteststf_jar): PRIVATE_INTERMEDIATES_MAIN_FILES := $(intermediates)/main_files
-$(vmteststf_jar): PRIVATE_INTERMEDIATES_HOSTJUNIT_FILES := $(intermediates)/hostjunit_files
-$(vmteststf_jar): PRIVATE_CLASS_PATH := $(subst $(space),:,$(vmteststf_dep_jars)):$(HOST_JDK_TOOLS_JAR)
+$(LOCAL_BUILT_MODULE): PRIVATE_SRC_FOLDER := $(LOCAL_PATH)/src
+$(LOCAL_BUILT_MODULE): PRIVATE_INTERMEDIATES_CLASSES := $(call intermediates-dir-for,JAVA_LIBRARIES,cts-tf-dalvik-buildutil,HOST)/classes
+$(LOCAL_BUILT_MODULE): PRIVATE_INTERMEDIATES := $(intermediates)/tests
+$(LOCAL_BUILT_MODULE): PRIVATE_INTERMEDIATES_DEXCORE_JAR := $(intermediates)/tests/dot/junit/dexcore.jar
+$(LOCAL_BUILT_MODULE): PRIVATE_INTERMEDIATES_MAIN_FILES := $(intermediates)/main_files
+$(LOCAL_BUILT_MODULE): PRIVATE_INTERMEDIATES_HOSTJUNIT_FILES := $(intermediates)/hostjunit_files
+$(LOCAL_BUILT_MODULE): PRIVATE_CLASS_PATH := $(subst $(space),:,$(vmteststf_dep_jars)):$(HOST_JDK_TOOLS_JAR)
+$(LOCAL_BUILT_MODULE): PRIVATE_JACK_VERSION := $(LOCAL_JACK_VERSION)
 ifndef LOCAL_JACK_ENABLED
-$(vmteststf_jar) : $(vmteststf_dep_jars) $(JACK_JAR) $(JILL_JAR) $(HOST_OUT_JAVA_LIBRARIES)/tradefed-prebuilt.jar
+$(LOCAL_BUILT_MODULE) : $(vmteststf_dep_jars) $(HOST_OUT_JAVA_LIBRARIES)/tradefed-prebuilt.jar
 	$(hide) rm -rf $(dir $@) && mkdir -p $(dir $@)
 	$(hide) mkdir -p $(PRIVATE_INTERMEDIATES_HOSTJUNIT_FILES)/dot/junit $(dir $(PRIVATE_INTERMEDIATES_DEXCORE_JAR))
 	# generated and compile the host side junit tests
@@ -97,30 +101,36 @@
 		$(addprefix -C $(PRIVATE_INTERMEDIATES_CLASSES) , dot/junit/DxUtil.class dot/junit/DxAbstractMain.class)
 	$(hide) $(DX) -JXms16M -JXmx768M --dex --output=$(PRIVATE_INTERMEDIATES_DEXCORE_JAR) \
 		$(if $(NO_OPTIMIZE_DX), --no-optimize) $(PRIVATE_INTERMEDIATES_DEXCORE_JAR).jar && rm -f $(PRIVATE_INTERMEDIATES_DEXCORE_JAR).jar
-	$(hide) cd $(PRIVATE_INTERMEDIATES_HOSTJUNIT_FILES)/classes && zip -q -r ../../android.core.vm-tests-tf.jar .
-	$(hide) cd $(dir $@) && zip -q -r android.core.vm-tests-tf.jar tests
+	$(hide) cd $(PRIVATE_INTERMEDIATES_HOSTJUNIT_FILES)/classes && zip -q -r ../../$(notdir $@) .
+	$(hide) cd $(dir $@) && zip -q -r $(notdir $@) tests
 else # LOCAL_JACK_ENABLED
-$(vmteststf_jar) : $(vmteststf_dep_jars) $(JACK_JAR) $(JILL_JAR) $(call intermediates-dir-for,JAVA_LIBRARIES,core-libart,,COMMON)/classes.jack $(HOST_OUT_JAVA_LIBRARIES)/tradefed-prebuilt.jar
+oj_jack := $(call intermediates-dir-for,JAVA_LIBRARIES,core-oj,,COMMON)/classes.jack
+libart_jack := $(call intermediates-dir-for,JAVA_LIBRARIES,core-libart,,COMMON)/classes.jack
+$(LOCAL_BUILT_MODULE): PRIVATE_DALVIK_SUITE_CLASSPATH := $(oj_jack):$(libart_jack):$(cts-tf-dalvik-lib.jack):$(HOST_OUT_JAVA_LIBRARIES)/tradefed-prebuilt.jar
+$(LOCAL_BUILT_MODULE) : $(vmteststf_dep_jars) $(JACK) $(oj_jack) $(libart_jack) $(HOST_OUT_JAVA_LIBRARIES)/tradefed-prebuilt.jar | setup-jack-server
 	$(hide) rm -rf $(dir $@) && mkdir -p $(dir $@)
 	$(hide) mkdir -p $(PRIVATE_INTERMEDIATES_HOSTJUNIT_FILES)/dot/junit $(dir $(PRIVATE_INTERMEDIATES_DEXCORE_JAR))
 	# generated and compile the host side junit tests
 	@echo "Write generated Main_*.java files to $(PRIVATE_INTERMEDIATES_MAIN_FILES)"
-	$(hide) java -cp $(PRIVATE_CLASS_PATH) util.build.JackBuildDalvikSuite $(PRIVATE_SRC_FOLDER) $(PRIVATE_INTERMEDIATES) \
-		$(call intermediates-dir-for,JAVA_LIBRARIES,core-libart,,COMMON)/classes.jack:$(cts-tf-dalvik-lib.jack):$(HOST_OUT_JAVA_LIBRARIES)/tradefed-prebuilt.jar \
+	$(hide) JACK_VERSION=$(PRIVATE_JACK_VERSION) java -cp $(PRIVATE_CLASS_PATH) util.build.JackBuildDalvikSuite $(JACK) $(PRIVATE_SRC_FOLDER) $(PRIVATE_INTERMEDIATES) \
+		$(PRIVATE_DALVIK_SUITE_CLASSPATH) \
 		$(PRIVATE_INTERMEDIATES_MAIN_FILES) $(PRIVATE_INTERMEDIATES_CLASSES) $(PRIVATE_INTERMEDIATES_HOSTJUNIT_FILES) $$RUN_VM_TESTS_RTO
 	@echo "Generate $(PRIVATE_INTERMEDIATES_DEXCORE_JAR)"
 	$(hide) jar -cf $(PRIVATE_INTERMEDIATES_DEXCORE_JAR)-class.jar \
 		$(addprefix -C $(PRIVATE_INTERMEDIATES_CLASSES) , dot/junit/DxUtil.class dot/junit/DxAbstractMain.class)
-	$(hide) $(JILL) --output $(PRIVATE_INTERMEDIATES_DEXCORE_JAR).jack $(PRIVATE_INTERMEDIATES_DEXCORE_JAR)-class.jar
+	$(hide) $(call call-jack) --import $(PRIVATE_INTERMEDIATES_DEXCORE_JAR)-class.jar --output-jack $(PRIVATE_INTERMEDIATES_DEXCORE_JAR).jack
 	$(hide) mkdir -p $(PRIVATE_INTERMEDIATES_DEXCORE_JAR).tmp
-	$(hide) $(call call-jack,$(PRIVATE_JACK_VM_ARGS),$(PRIVATE_JACK_EXTRA_ARGS)) --output-dex $(PRIVATE_INTERMEDIATES_DEXCORE_JAR).tmp \
+	$(hide) $(call call-jack,$(PRIVATE_JACK_EXTRA_ARGS)) --output-dex $(PRIVATE_INTERMEDIATES_DEXCORE_JAR).tmp \
 		$(if $(NO_OPTIMIZE_DX), -D jack.dex.optimize "false") --import $(PRIVATE_INTERMEDIATES_DEXCORE_JAR).jack && rm -f $(PRIVATE_INTERMEDIATES_DEXCORE_JAR).jack
 	$(hide) cd $(PRIVATE_INTERMEDIATES_DEXCORE_JAR).tmp && zip -q -r $(abspath $(PRIVATE_INTERMEDIATES_DEXCORE_JAR)) .
-	$(hide) cd $(PRIVATE_INTERMEDIATES_HOSTJUNIT_FILES)/classes && zip -q -r ../../android.core.vm-tests-tf.jar .
-	$(hide) cd $(dir $@) && zip -q -r android.core.vm-tests-tf.jar tests
+	$(hide) cd $(PRIVATE_INTERMEDIATES_HOSTJUNIT_FILES)/classes && zip -q -r ../../$(notdir $@) .
+	$(hide) cd $(dir $@) && zip -q -r $(notdir $@) tests
+oj_jack :=
+libart_jack :=
 endif # LOCAL_JACK_ENABLED
 
 # Clean up temp vars
 intermediates :=
-vmteststf_jar :=
 vmteststf_dep_jars :=
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tools/vm-tests-tf/AndroidTest.xml b/tools/vm-tests-tf/AndroidTest.xml
new file mode 100644
index 0000000..35db3ad
--- /dev/null
+++ b/tools/vm-tests-tf/AndroidTest.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS VM test cases">
+    <target_preparer class="android.core.vm.targetprep.VmTestPreparer" />
+    <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
+        <option name="jar" value="android.core.vm-tests-tf.jar" />
+    </test>
+</configuration>
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface/Test_invoke_interface.java b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface/Test_invoke_interface.java
index 6972253..82e05d3 100644
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface/Test_invoke_interface.java
+++ b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface/Test_invoke_interface.java
@@ -27,6 +27,9 @@
 import dot.junit.opcodes.invoke_interface.d.T_invoke_interface_18;
 import dot.junit.opcodes.invoke_interface.d.T_invoke_interface_20;
 import dot.junit.opcodes.invoke_interface.d.T_invoke_interface_21;
+import dot.junit.opcodes.invoke_interface.d.T_invoke_interface_23;
+import dot.junit.opcodes.invoke_interface.d.T_invoke_interface_24;
+import dot.junit.opcodes.invoke_interface.d.T_invoke_interface_25;
 import dot.junit.opcodes.invoke_interface.d.T_invoke_interface_3;
 import dot.junit.opcodes.invoke_interface.d.T_invoke_interface_4;
 import dot.junit.opcodes.invoke_interface.d.T_invoke_interface_5;
@@ -57,7 +60,12 @@
         assertEquals(1, t.run(impl));
     }
 
-
+    /**
+     * @title invoke default interface method
+     */
+    public void testN3() {
+        loadAndRun("dot.junit.opcodes.invoke_interface.d.T_invoke_interface_25", null);
+    }
 
     /**
      * @title objref is null
@@ -116,6 +124,22 @@
     }
 
     /**
+     * @title Attempt to invoke conflict method
+     */
+    public void testE7() {
+        loadAndRun("dot.junit.opcodes.invoke_interface.d.T_invoke_interface_23",
+                   IncompatibleClassChangeError.class);
+    }
+
+    /**
+     * @title Attempt to invoke abstract method
+     */
+    public void testE8() {
+        loadAndRun("dot.junit.opcodes.invoke_interface.d.T_invoke_interface_24",
+                   AbstractMethodError.class);
+    }
+
+    /**
      * @constraint A16
      * @title invalid constant pool index
      */
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface/d/ITestDefault.java b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface/d/ITestDefault.java
new file mode 100644
index 0000000..9db9b03
--- /dev/null
+++ b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface/d/ITestDefault.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dot.junit.opcodes.invoke_interface;
+
+public interface ITestDefault {
+  public void testDefault();
+  // CTS doesn't like default methods. The real implementation is below.
+  // public default int testDefault() {
+  //   return 1;
+  // }
+}
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface/d/ITestDefault2.java b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface/d/ITestDefault2.java
new file mode 100644
index 0000000..b765b6b
--- /dev/null
+++ b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface/d/ITestDefault2.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dot.junit.opcodes.invoke_interface;
+
+public interface ITestDefault2 {
+  public void testDefault();
+  // CTS doesn't like default methods. The real implementation is below.
+  // public default int testDefault() {
+  //   return 2;
+  // }
+}
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface/d/ITestNonDefault.java b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface/d/ITestNonDefault.java
new file mode 100644
index 0000000..c9c648e
--- /dev/null
+++ b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface/d/ITestNonDefault.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dot.junit.opcodes.invoke_interface;
+
+public interface ITestNonDefault extends ITestDefault, ITestDefault2 {
+  // Shadow the default implementation with a non-default one.
+  public void testDefault();
+}
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface/d/T_invoke_interface_23.d b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface/d/T_invoke_interface_23.d
new file mode 100644
index 0000000..6709286
--- /dev/null
+++ b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface/d/T_invoke_interface_23.d
@@ -0,0 +1,49 @@
+; Copyright (C) 2016 The Android Open Source Project
+;
+; Licensed under the Apache License, Version 2.0 (the "License");
+; you may not use this file except in compliance with the License.
+; You may obtain a copy of the License at
+;
+;      http://www.apache.org/licenses/LICENSE-2.0
+;
+; Unless required by applicable law or agreed to in writing, software
+; distributed under the License is distributed on an "AS IS" BASIS,
+; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+; See the License for the specific language governing permissions and
+; limitations under the License.
+
+.source ITestDefault2.java
+.interface public dot.junit.opcodes.invoke_interface.d.ITestDefault2
+
+.method public testDefault()V
+.limit regs 2
+    return-void
+.end method
+
+.source ITestDefault.java
+.interface public dot.junit.opcodes.invoke_interface.d.ITestDefault
+
+.method public testDefault()V
+.limit regs 2
+    return-void
+.end method
+
+.source T_invoke_interface_23.java
+.class public dot.junit.opcodes.invoke_interface.d.T_invoke_interface_23
+.super java/lang/Object
+.implements dot.junit.opcodes.invoke_interface.d.ITestDefault
+.implements dot.junit.opcodes.invoke_interface.d.ITestDefault2
+
+.method public <init>()V
+.limit regs 2
+
+       invoke-direct {v1}, java/lang/Object/<init>()V
+       return-void
+.end method
+
+.method public run()V
+.limit regs 1
+       invoke-interface {v0}, dot/junit/opcodes/invoke_interface/d/ITestDefault/testDefault()V
+       return-void
+.end method
+
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface/d/T_invoke_interface_23.java b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface/d/T_invoke_interface_23.java
new file mode 100644
index 0000000..30a772f
--- /dev/null
+++ b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface/d/T_invoke_interface_23.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dot.junit.opcodes.invoke_interface.d;
+
+
+public class T_invoke_interface_23 {
+    public void run() {
+
+    }
+}
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface/d/T_invoke_interface_24.d b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface/d/T_invoke_interface_24.d
new file mode 100644
index 0000000..577510a
--- /dev/null
+++ b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface/d/T_invoke_interface_24.d
@@ -0,0 +1,58 @@
+; Copyright (C) 2016 The Android Open Source Project
+;
+; Licensed under the Apache License, Version 2.0 (the "License");
+; you may not use this file except in compliance with the License.
+; You may obtain a copy of the License at
+;
+;      http://www.apache.org/licenses/LICENSE-2.0
+;
+; Unless required by applicable law or agreed to in writing, software
+; distributed under the License is distributed on an "AS IS" BASIS,
+; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+; See the License for the specific language governing permissions and
+; limitations under the License.
+
+.source ITestDefault2.java
+.interface public dot.junit.opcodes.invoke_interface.d.ITestDefault2
+
+.method public testDefault()V
+.limit regs 2
+    return-void
+.end method
+
+.source ITestDefault.java
+.interface public dot.junit.opcodes.invoke_interface.d.ITestDefault
+
+.method public testDefault()V
+.limit regs 2
+    return-void
+.end method
+
+.source ITestNonDefault.java
+.interface public dot.junit.opcodes.invoke_interface.d.ITestNonDefault
+.implements dot.junit.opcodes.invoke_interface.d.ITestDefault
+.implements dot.junit.opcodes.invoke_interface.d.ITestDefault2
+
+.method public abstract testDefault()V
+.end method
+
+
+.source T_invoke_interface_24.java
+.class public dot.junit.opcodes.invoke_interface.d.T_invoke_interface_24
+.super java/lang/Object
+.implements dot.junit.opcodes.invoke_interface.d.ITestNonDefault
+.implements dot.junit.opcodes.invoke_interface.d.ITestDefault2
+
+.method public <init>()V
+.limit regs 2
+
+       invoke-direct {v1}, java/lang/Object/<init>()V
+       return-void
+.end method
+
+.method public run()V
+.limit regs 1
+       invoke-interface {v0}, dot/junit/opcodes/invoke_interface/d/ITestDefault2/testDefault()V
+       return-void
+.end method
+
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface/d/T_invoke_interface_24.java b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface/d/T_invoke_interface_24.java
new file mode 100644
index 0000000..23758bb
--- /dev/null
+++ b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface/d/T_invoke_interface_24.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dot.junit.opcodes.invoke_interface.d;
+
+
+public class T_invoke_interface_24 {
+    public void run() {
+
+    }
+}
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface/d/T_invoke_interface_25.d b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface/d/T_invoke_interface_25.d
new file mode 100644
index 0000000..19b57b4
--- /dev/null
+++ b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface/d/T_invoke_interface_25.d
@@ -0,0 +1,40 @@
+; Copyright (C) 2016 The Android Open Source Project
+;
+; Licensed under the Apache License, Version 2.0 (the "License");
+; you may not use this file except in compliance with the License.
+; You may obtain a copy of the License at
+;
+;      http://www.apache.org/licenses/LICENSE-2.0
+;
+; Unless required by applicable law or agreed to in writing, software
+; distributed under the License is distributed on an "AS IS" BASIS,
+; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+; See the License for the specific language governing permissions and
+; limitations under the License.
+
+.source ITestDefault.java
+.interface public dot.junit.opcodes.invoke_interface.d.ITestDefault
+
+.method public testDefault()V
+.limit regs 2
+    return-void
+.end method
+
+.source T_invoke_interface_25.java
+.class public dot.junit.opcodes.invoke_interface.d.T_invoke_interface_25
+.super java/lang/Object
+.implements dot.junit.opcodes.invoke_interface.d.ITestDefault
+
+.method public <init>()V
+.limit regs 2
+
+       invoke-direct {v1}, java/lang/Object/<init>()V
+       return-void
+.end method
+
+.method public run()V
+.limit regs 1
+       invoke-interface {v0}, dot/junit/opcodes/invoke_interface/d/ITestDefault/testDefault()V
+       return-void
+.end method
+
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface/d/T_invoke_interface_25.java b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface/d/T_invoke_interface_25.java
new file mode 100644
index 0000000..7eab58e
--- /dev/null
+++ b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface/d/T_invoke_interface_25.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dot.junit.opcodes.invoke_interface.d;
+
+public class T_invoke_interface_25 {
+    public void run() {
+
+    }
+}
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface_range/Test_invoke_interface_range.java b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface_range/Test_invoke_interface_range.java
index 8faa506..887eb24 100644
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface_range/Test_invoke_interface_range.java
+++ b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface_range/Test_invoke_interface_range.java
@@ -27,6 +27,9 @@
 import dot.junit.opcodes.invoke_interface_range.d.T_invoke_interface_range_18;
 import dot.junit.opcodes.invoke_interface_range.d.T_invoke_interface_range_20;
 import dot.junit.opcodes.invoke_interface_range.d.T_invoke_interface_range_21;
+import dot.junit.opcodes.invoke_interface_range.d.T_invoke_interface_range_23;
+import dot.junit.opcodes.invoke_interface_range.d.T_invoke_interface_range_24;
+import dot.junit.opcodes.invoke_interface_range.d.T_invoke_interface_range_25;
 import dot.junit.opcodes.invoke_interface_range.d.T_invoke_interface_range_3;
 import dot.junit.opcodes.invoke_interface_range.d.T_invoke_interface_range_4;
 import dot.junit.opcodes.invoke_interface_range.d.T_invoke_interface_range_5;
@@ -57,7 +60,12 @@
         assertEquals(1, t.run(impl));
     }
 
-
+    /**
+     * @title invoke default interface method
+     */
+    public void testN3() {
+        loadAndRun("dot.junit.opcodes.invoke_interface_range.d.T_invoke_interface_range_25", null);
+    }
 
     /**
      * @title objref is null
@@ -100,6 +108,23 @@
     }
 
     /**
+     * @title Attempt to invoke conflict method
+     */
+    public void testE7() {
+        loadAndRun("dot.junit.opcodes.invoke_interface_range.d.T_invoke_interface_range_23",
+                   IncompatibleClassChangeError.class);
+    }
+
+    /**
+     * @title Attempt to invoke abstract method
+     */
+    public void testE8() {
+        loadAndRun("dot.junit.opcodes.invoke_interface_range.d.T_invoke_interface_range_24",
+                   AbstractMethodError.class);
+    }
+
+
+    /**
      * @constraint A17
      * @title invalid constant pool index
      */
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface_range/d/ITestDefault.java b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface_range/d/ITestDefault.java
new file mode 100644
index 0000000..9998454
--- /dev/null
+++ b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface_range/d/ITestDefault.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dot.junit.opcodes.invoke_interface_range;
+
+public interface ITestDefault {
+  public void testDefault();
+  // public default int testDefault() {
+  //   return 1;
+  // }
+}
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface_range/d/ITestDefault2.java b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface_range/d/ITestDefault2.java
new file mode 100644
index 0000000..fcfc3a5
--- /dev/null
+++ b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface_range/d/ITestDefault2.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dot.junit.opcodes.invoke_interface_range;
+
+public interface ITestDefault2 {
+  public void testDefault();
+  // public default int testDefault() {
+  //   return 2;
+  // }
+}
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface_range/d/ITestNonDefault.java b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface_range/d/ITestNonDefault.java
new file mode 100644
index 0000000..0f1ccdc
--- /dev/null
+++ b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface_range/d/ITestNonDefault.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dot.junit.opcodes.invoke_interface_range;
+
+public interface ITestNonDefault extends ITestDefault, ITestDefault2 {
+  // Shadow the default implementation with a non-default one.
+  public void testDefault();
+}
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface_range/d/T_invoke_interface_range_23.d b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface_range/d/T_invoke_interface_range_23.d
new file mode 100644
index 0000000..9314daa
--- /dev/null
+++ b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface_range/d/T_invoke_interface_range_23.d
@@ -0,0 +1,49 @@
+; Copyright (C) 2016 The Android Open Source Project
+;
+; Licensed under the Apache License, Version 2.0 (the "License");
+; you may not use this file except in compliance with the License.
+; You may obtain a copy of the License at
+;
+;      http://www.apache.org/licenses/LICENSE-2.0
+;
+; Unless required by applicable law or agreed to in writing, software
+; distributed under the License is distributed on an "AS IS" BASIS,
+; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+; See the License for the specific language governing permissions and
+; limitations under the License.
+
+.source ITestDefault2.java
+.interface public dot.junit.opcodes.invoke_interface_range.d.ITestDefault2
+
+.method public testDefault()V
+.limit regs 2
+    return-void
+.end method
+
+.source ITestDefault.java
+.interface public dot.junit.opcodes.invoke_interface_range.d.ITestDefault
+
+.method public testDefault()V
+.limit regs 2
+    return-void
+.end method
+
+.source T_invoke_interface_range_23.java
+.class public dot.junit.opcodes.invoke_interface_range.d.T_invoke_interface_range_23
+.super java/lang/Object
+.implements dot.junit.opcodes.invoke_interface_range.d.ITestDefault
+.implements dot.junit.opcodes.invoke_interface_range.d.ITestDefault2
+
+.method public <init>()V
+.limit regs 2
+
+       invoke-direct {v1}, java/lang/Object/<init>()V
+       return-void
+.end method
+
+.method public run()V
+.limit regs 1
+       invoke-interface/range {v0}, dot/junit/opcodes/invoke_interface_range/d/ITestDefault/testDefault()V
+       return-void
+.end method
+
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface_range/d/T_invoke_interface_range_23.java b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface_range/d/T_invoke_interface_range_23.java
new file mode 100644
index 0000000..4014a2b
--- /dev/null
+++ b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface_range/d/T_invoke_interface_range_23.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dot.junit.opcodes.invoke_interface_range.d;
+
+
+public class T_invoke_interface_range_23 {
+    public void run() {
+
+    }
+}
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface_range/d/T_invoke_interface_range_24.d b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface_range/d/T_invoke_interface_range_24.d
new file mode 100644
index 0000000..c70dfb6
--- /dev/null
+++ b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface_range/d/T_invoke_interface_range_24.d
@@ -0,0 +1,58 @@
+; Copyright (C) 2016 The Android Open Source Project
+;
+; Licensed under the Apache License, Version 2.0 (the "License");
+; you may not use this file except in compliance with the License.
+; You may obtain a copy of the License at
+;
+;      http://www.apache.org/licenses/LICENSE-2.0
+;
+; Unless required by applicable law or agreed to in writing, software
+; distributed under the License is distributed on an "AS IS" BASIS,
+; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+; See the License for the specific language governing permissions and
+; limitations under the License.
+
+.source ITestDefault2.java
+.interface public dot.junit.opcodes.invoke_interface_range.d.ITestDefault2
+
+.method public testDefault()V
+.limit regs 2
+    return-void
+.end method
+
+.source ITestDefault.java
+.interface public dot.junit.opcodes.invoke_interface_range.d.ITestDefault
+
+.method public testDefault()V
+.limit regs 2
+    return-void
+.end method
+
+.source ITestNonDefault.java
+.interface public dot.junit.opcodes.invoke_interface_range.d.ITestNonDefault
+.implements dot.junit.opcodes.invoke_interface_range.d.ITestDefault
+.implements dot.junit.opcodes.invoke_interface_range.d.ITestDefault2
+
+.method public abstract testDefault()V
+.end method
+
+
+.source T_invoke_interface_range_24.java
+.class public dot.junit.opcodes.invoke_interface_range.d.T_invoke_interface_range_24
+.super java/lang/Object
+.implements dot.junit.opcodes.invoke_interface_range.d.ITestNonDefault
+.implements dot.junit.opcodes.invoke_interface_range.d.ITestDefault2
+
+.method public <init>()V
+.limit regs 2
+
+       invoke-direct {v1}, java/lang/Object/<init>()V
+       return-void
+.end method
+
+.method public run()V
+.limit regs 1
+       invoke-interface/range {v0}, dot/junit/opcodes/invoke_interface_range/d/ITestDefault2/testDefault()V
+       return-void
+.end method
+
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface_range/d/T_invoke_interface_range_24.java b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface_range/d/T_invoke_interface_range_24.java
new file mode 100644
index 0000000..098d38e
--- /dev/null
+++ b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface_range/d/T_invoke_interface_range_24.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dot.junit.opcodes.invoke_interface_range.d;
+
+
+public class T_invoke_interface_range_24 {
+    public void run() {
+
+    }
+}
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface_range/d/T_invoke_interface_range_25.d b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface_range/d/T_invoke_interface_range_25.d
new file mode 100644
index 0000000..fd10395
--- /dev/null
+++ b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface_range/d/T_invoke_interface_range_25.d
@@ -0,0 +1,40 @@
+; Copyright (C) 2016 The Android Open Source Project
+;
+; Licensed under the Apache License, Version 2.0 (the "License");
+; you may not use this file except in compliance with the License.
+; You may obtain a copy of the License at
+;
+;      http://www.apache.org/licenses/LICENSE-2.0
+;
+; Unless required by applicable law or agreed to in writing, software
+; distributed under the License is distributed on an "AS IS" BASIS,
+; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+; See the License for the specific language governing permissions and
+; limitations under the License.
+
+.source ITestDefault.java
+.interface public dot.junit.opcodes.invoke_interface_range.d.ITestDefault
+
+.method public testDefault()V
+.limit regs 2
+    return-void
+.end method
+
+.source T_invoke_interface_range_25.java
+.class public dot.junit.opcodes.invoke_interface_range.d.T_invoke_interface_range_25
+.super java/lang/Object
+.implements dot.junit.opcodes.invoke_interface_range.d.ITestDefault
+
+.method public <init>()V
+.limit regs 2
+
+       invoke-direct {v1}, java/lang/Object/<init>()V
+       return-void
+.end method
+
+.method public run()V
+.limit regs 1
+       invoke-interface/range {v0}, dot/junit/opcodes/invoke_interface_range/d/ITestDefault/testDefault()V
+       return-void
+.end method
+
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface_range/d/T_invoke_interface_range_25.java b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface_range/d/T_invoke_interface_range_25.java
new file mode 100644
index 0000000..7e6c136
--- /dev/null
+++ b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface_range/d/T_invoke_interface_range_25.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dot.junit.opcodes.invoke_interface_range.d;
+
+public class T_invoke_interface_range_25 {
+    public void run() {
+
+    }
+}
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super/Test_invoke_super.java b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super/Test_invoke_super.java
index 0995fb0..75eaaae 100644
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super/Test_invoke_super.java
+++ b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super/Test_invoke_super.java
@@ -28,6 +28,9 @@
 import dot.junit.opcodes.invoke_super.d.T_invoke_super_2;
 import dot.junit.opcodes.invoke_super.d.T_invoke_super_20;
 import dot.junit.opcodes.invoke_super.d.T_invoke_super_24;
+import dot.junit.opcodes.invoke_super.d.T_invoke_super_26;
+import dot.junit.opcodes.invoke_super.d.T_invoke_super_27;
+import dot.junit.opcodes.invoke_super.d.T_invoke_super_28;
 import dot.junit.opcodes.invoke_super.d.T_invoke_super_4;
 import dot.junit.opcodes.invoke_super.d.T_invoke_super_5;
 import dot.junit.opcodes.invoke_super.d.T_invoke_super_6;
@@ -79,6 +82,13 @@
     }
 
     /**
+     * @title invoke-super in conflict class
+     */
+    public void testN7() {
+        loadAndRun("dot.junit.opcodes.invoke_super.d.T_invoke_super_26", null);
+    }
+
+    /**
      * @title obj ref is null
      */
     public void testE1() {
@@ -104,6 +114,21 @@
     }
 
     /**
+     * @title Attempt to invoke abstract interface method
+     */
+    public void testE5() {
+        loadAndRun("dot.junit.opcodes.invoke_super.d.T_invoke_super_27", AbstractMethodError.class);
+    }
+
+    /**
+     * @title Attempt to invoke abstract interface method
+     */
+    public void testE6() {
+        loadAndRun("dot.junit.opcodes.invoke_super.d.T_invoke_super_28",
+                   IncompatibleClassChangeError.class);
+    }
+
+    /**
      * @constraint A13
      * @title invalid constant pool index
      */
@@ -236,8 +261,8 @@
      * @title attempt to invoke interface method
      */
     public void testVFE18() {
-        loadAndRun("dot.junit.opcodes.invoke_super.d.T_invoke_super_24", 
-                   IncompatibleClassChangeError.class);
+        loadAndRun("dot.junit.opcodes.invoke_super.d.T_invoke_super_24",
+                   AbstractMethodError.class);
     }
 
     /**
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super/d/ITestConflict.java b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super/d/ITestConflict.java
new file mode 100644
index 0000000..78bf082
--- /dev/null
+++ b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super/d/ITestConflict.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dot.junit.opcodes.invoke_super;
+
+public interface ITestConflict extends ITestDefault, ITestDefault2 { }
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super/d/ITestDefault.java b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super/d/ITestDefault.java
new file mode 100644
index 0000000..27954b1
--- /dev/null
+++ b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super/d/ITestDefault.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dot.junit.opcodes.invoke_super;
+
+public interface ITestDefault {
+  public void testDefault();
+  // public default int testDefault() {
+  //   return 1;
+  // }
+}
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super/d/ITestDefault2.java b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super/d/ITestDefault2.java
new file mode 100644
index 0000000..95acc72
--- /dev/null
+++ b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super/d/ITestDefault2.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dot.junit.opcodes.invoke_super;
+
+public interface ITestDefault2 {
+  public void testDefault();
+  // public default int testDefault() {
+  //   return 2;
+  // }
+}
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super/d/ITestNonDefault.java b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super/d/ITestNonDefault.java
new file mode 100644
index 0000000..eaf3a50
--- /dev/null
+++ b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super/d/ITestNonDefault.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dot.junit.opcodes.invoke_super;
+
+public interface ITestNonDefault extends ITestDefault, ITestDefault2 {
+  // Shadow the default implementation with a non-default one.
+  public void testDefault();
+}
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super/d/T_invoke_super_26.d b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super/d/T_invoke_super_26.d
new file mode 100644
index 0000000..1e68d5f
--- /dev/null
+++ b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super/d/T_invoke_super_26.d
@@ -0,0 +1,50 @@
+; Copyright (C) 2016 The Android Open Source Project
+;
+; Licensed under the Apache License, Version 2.0 (the "License");
+; you may not use this file except in compliance with the License.
+; You may obtain a copy of the License at
+;
+;      http://www.apache.org/licenses/LICENSE-2.0
+;
+; Unless required by applicable law or agreed to in writing, software
+; distributed under the License is distributed on an "AS IS" BASIS,
+; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+; See the License for the specific language governing permissions and
+; limitations under the License.
+
+.source ITestDefault2.java
+.interface public dot.junit.opcodes.invoke_super.d.ITestDefault2
+
+.method public testDefault()V
+.limit regs 2
+    return-void
+.end method
+
+.source ITestDefault.java
+.interface public dot.junit.opcodes.invoke_super.d.ITestDefault
+
+.method public testDefault()V
+.limit regs 2
+    return-void
+.end method
+
+.source T_invoke_super_26.java
+.class public dot.junit.opcodes.invoke_super.d.T_invoke_super_26
+.super java/lang/Object
+.implements dot.junit.opcodes.invoke_super.d.ITestDefault
+.implements dot.junit.opcodes.invoke_super.d.ITestDefault2
+
+.method public <init>()V
+.limit regs 2
+
+       invoke-direct {v1}, java/lang/Object/<init>()V
+       return-void
+.end method
+
+.method public run()V
+.limit regs 1
+       invoke-super {v0}, dot/junit/opcodes/invoke_super/d/ITestDefault/testDefault()V
+       invoke-super {v0}, dot/junit/opcodes/invoke_super/d/ITestDefault2/testDefault()V
+       return-void
+.end method
+
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super/d/T_invoke_super_26.java b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super/d/T_invoke_super_26.java
new file mode 100644
index 0000000..b6fbfbd
--- /dev/null
+++ b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super/d/T_invoke_super_26.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dot.junit.opcodes.invoke_super.d;
+
+
+public class T_invoke_super_26 {
+    public void run() {
+
+    }
+}
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super/d/T_invoke_super_27.d b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super/d/T_invoke_super_27.d
new file mode 100644
index 0000000..8bda6a5
--- /dev/null
+++ b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super/d/T_invoke_super_27.d
@@ -0,0 +1,58 @@
+; Copyright (C) 2016 The Android Open Source Project
+;
+; Licensed under the Apache License, Version 2.0 (the "License");
+; you may not use this file except in compliance with the License.
+; You may obtain a copy of the License at
+;
+;      http://www.apache.org/licenses/LICENSE-2.0
+;
+; Unless required by applicable law or agreed to in writing, software
+; distributed under the License is distributed on an "AS IS" BASIS,
+; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+; See the License for the specific language governing permissions and
+; limitations under the License.
+
+.source ITestDefault2.java
+.interface public dot.junit.opcodes.invoke_super.d.ITestDefault2
+
+.method public testDefault()V
+.limit regs 2
+    return-void
+.end method
+
+.source ITestDefault.java
+.interface public dot.junit.opcodes.invoke_super.d.ITestDefault
+
+.method public testDefault()V
+.limit regs 2
+    return-void
+.end method
+
+.source ITestNonDefault.java
+.interface public dot.junit.opcodes.invoke_super.d.ITestNonDefault
+.implements dot.junit.opcodes.invoke_super.d.ITestDefault
+.implements dot.junit.opcodes.invoke_super.d.ITestDefault2
+
+.method public abstract testDefault()V
+.end method
+
+
+.source T_invoke_super_27.java
+.class public dot.junit.opcodes.invoke_super.d.T_invoke_super_27
+.super java/lang/Object
+.implements dot.junit.opcodes.invoke_super.d.ITestNonDefault
+.implements dot.junit.opcodes.invoke_super.d.ITestDefault2
+
+.method public <init>()V
+.limit regs 2
+
+       invoke-direct {v1}, java/lang/Object/<init>()V
+       return-void
+.end method
+
+.method public run()V
+.limit regs 1
+       invoke-super {v0}, dot/junit/opcodes/invoke_super/d/ITestNonDefault/testDefault()V
+       return-void
+.end method
+
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super/d/T_invoke_super_27.java b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super/d/T_invoke_super_27.java
new file mode 100644
index 0000000..822b5f0
--- /dev/null
+++ b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super/d/T_invoke_super_27.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dot.junit.opcodes.invoke_super.d;
+
+
+public class T_invoke_super_27 {
+    public void run() {
+
+    }
+}
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super/d/T_invoke_super_28.d b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super/d/T_invoke_super_28.d
new file mode 100644
index 0000000..350fdb8
--- /dev/null
+++ b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super/d/T_invoke_super_28.d
@@ -0,0 +1,53 @@
+; Copyright (C) 2016 The Android Open Source Project
+;
+; Licensed under the Apache License, Version 2.0 (the "License");
+; you may not use this file except in compliance with the License.
+; You may obtain a copy of the License at
+;
+;      http://www.apache.org/licenses/LICENSE-2.0
+;
+; Unless required by applicable law or agreed to in writing, software
+; distributed under the License is distributed on an "AS IS" BASIS,
+; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+; See the License for the specific language governing permissions and
+; limitations under the License.
+
+.source ITestDefault2.java
+.interface public dot.junit.opcodes.invoke_super.d.ITestDefault2
+
+.method public testDefault()V
+.limit regs 2
+    return-void
+.end method
+
+.source ITestDefault.java
+.interface public dot.junit.opcodes.invoke_super.d.ITestDefault
+
+.method public testDefault()V
+.limit regs 2
+    return-void
+.end method
+
+.source ITestConflict.java
+.interface public dot.junit.opcodes.invoke_super.d.ITestConflict
+.implements dot.junit.opcodes.invoke_super.d.ITestDefault
+.implements dot.junit.opcodes.invoke_super.d.ITestDefault2
+
+.source T_invoke_super_28.java
+.class public dot.junit.opcodes.invoke_super.d.T_invoke_super_28
+.super java/lang/Object
+.implements dot.junit.opcodes.invoke_super.d.ITestConflict
+
+.method public <init>()V
+.limit regs 2
+
+       invoke-direct {v1}, java/lang/Object/<init>()V
+       return-void
+.end method
+
+.method public run()V
+.limit regs 1
+       invoke-super {v0}, dot/junit/opcodes/invoke_super/d/ITestConflict/testDefault()V
+       return-void
+.end method
+
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super/d/T_invoke_super_28.java b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super/d/T_invoke_super_28.java
new file mode 100644
index 0000000..69cd80c
--- /dev/null
+++ b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super/d/T_invoke_super_28.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dot.junit.opcodes.invoke_super.d;
+
+
+public class T_invoke_super_28 {
+    public void run() {
+
+    }
+}
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/Test_invoke_super_range.java b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/Test_invoke_super_range.java
index 9007ef4..5d78ecb 100644
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/Test_invoke_super_range.java
+++ b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/Test_invoke_super_range.java
@@ -79,6 +79,13 @@
     }
 
     /**
+     * @title invoke-super in conflict class
+     */
+    public void testN7() {
+        loadAndRun("dot.junit.opcodes.invoke_super_range.d.T_invoke_super_range_26", null);
+    }
+
+    /**
      * @title obj ref is null
      */
     public void testE1() {
@@ -106,6 +113,22 @@
     }
 
     /**
+     * @title Attempt to invoke abstract interface method
+     */
+    public void testE5() {
+        loadAndRun("dot.junit.opcodes.invoke_super_range.d.T_invoke_super_range_27", AbstractMethodError.class);
+    }
+
+    /**
+     * @title Attempt to invoke abstract interface method
+     */
+    public void testE6() {
+        loadAndRun("dot.junit.opcodes.invoke_super_range.d.T_invoke_super_range_28",
+                   IncompatibleClassChangeError.class);
+    }
+
+
+    /**
      * @constraint A14
      * @title invalid constant pool index
      */
@@ -243,7 +266,7 @@
     public void testVFE18() {
         //@uses dot.junit.opcodes.invoke_super_range.d.T_invoke_super_range_24
         loadAndRun("dot.junit.opcodes.invoke_super_range.d.T_invoke_super_range_24",
-                   IncompatibleClassChangeError.class);
+                   AbstractMethodError.class);
     }
 
     /**
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/ITestConflict.java b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/ITestConflict.java
new file mode 100644
index 0000000..03c8c00
--- /dev/null
+++ b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/ITestConflict.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dot.junit.opcodes.invoke_super_range;
+
+public interface ITestConflict extends ITestDefault, ITestDefault2 { }
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/ITestDefault.java b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/ITestDefault.java
new file mode 100644
index 0000000..f8bbf86a0
--- /dev/null
+++ b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/ITestDefault.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dot.junit.opcodes.invoke_super_range;
+
+public interface ITestDefault {
+  public void testDefault();
+  // public default int testDefault() {
+  //   return 1;
+  // }
+}
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/ITestDefault2.java b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/ITestDefault2.java
new file mode 100644
index 0000000..0faeba3
--- /dev/null
+++ b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/ITestDefault2.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dot.junit.opcodes.invoke_super_range;
+
+public interface ITestDefault2 {
+  public void testDefault();
+  // public default int testDefault() {
+  //   return 2;
+  // }
+}
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/ITestNonDefault.java b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/ITestNonDefault.java
new file mode 100644
index 0000000..26c2b60
--- /dev/null
+++ b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/ITestNonDefault.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dot.junit.opcodes.invoke_super_range;
+
+public interface ITestNonDefault extends ITestDefault, ITestDefault2 {
+  // Shadow the default implementation with a non-default one.
+  public void testDefault();
+}
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/T_invoke_super_range_26.d b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/T_invoke_super_range_26.d
new file mode 100644
index 0000000..8e53186
--- /dev/null
+++ b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/T_invoke_super_range_26.d
@@ -0,0 +1,50 @@
+; Copyright (C) 2016 The Android Open Source Project
+;
+; Licensed under the Apache License, Version 2.0 (the "License");
+; you may not use this file except in compliance with the License.
+; You may obtain a copy of the License at
+;
+;      http://www.apache.org/licenses/LICENSE-2.0
+;
+; Unless required by applicable law or agreed to in writing, software
+; distributed under the License is distributed on an "AS IS" BASIS,
+; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+; See the License for the specific language governing permissions and
+; limitations under the License.
+
+.source ITestDefault2.java
+.interface public dot.junit.opcodes.invoke_super_range.d.ITestDefault2
+
+.method public testDefault()V
+.limit regs 2
+    return-void
+.end method
+
+.source ITestDefault.java
+.interface public dot.junit.opcodes.invoke_super_range.d.ITestDefault
+
+.method public testDefault()V
+.limit regs 2
+    return-void
+.end method
+
+.source T_invoke_super_range_26.java
+.class public dot.junit.opcodes.invoke_super_range.d.T_invoke_super_range_26
+.super java/lang/Object
+.implements dot.junit.opcodes.invoke_super_range.d.ITestDefault
+.implements dot.junit.opcodes.invoke_super_range.d.ITestDefault2
+
+.method public <init>()V
+.limit regs 2
+
+       invoke-direct {v1}, java/lang/Object/<init>()V
+       return-void
+.end method
+
+.method public run()V
+.limit regs 1
+       invoke-super/range {v0}, dot/junit/opcodes/invoke_super_range/d/ITestDefault/testDefault()V
+       invoke-super/range {v0}, dot/junit/opcodes/invoke_super_range/d/ITestDefault2/testDefault()V
+       return-void
+.end method
+
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/T_invoke_super_range_26.java b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/T_invoke_super_range_26.java
new file mode 100644
index 0000000..4f1f54b
--- /dev/null
+++ b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/T_invoke_super_range_26.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dot.junit.opcodes.invoke_super_range.d;
+
+
+public class T_invoke_super_range_26 {
+    public void run() {
+
+    }
+}
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/T_invoke_super_range_27.d b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/T_invoke_super_range_27.d
new file mode 100644
index 0000000..752182c
--- /dev/null
+++ b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/T_invoke_super_range_27.d
@@ -0,0 +1,58 @@
+; Copyright (C) 2016 The Android Open Source Project
+;
+; Licensed under the Apache License, Version 2.0 (the "License");
+; you may not use this file except in compliance with the License.
+; You may obtain a copy of the License at
+;
+;      http://www.apache.org/licenses/LICENSE-2.0
+;
+; Unless required by applicable law or agreed to in writing, software
+; distributed under the License is distributed on an "AS IS" BASIS,
+; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+; See the License for the specific language governing permissions and
+; limitations under the License.
+
+.source ITestDefault2.java
+.interface public dot.junit.opcodes.invoke_super_range.d.ITestDefault2
+
+.method public testDefault()V
+.limit regs 2
+    return-void
+.end method
+
+.source ITestDefault.java
+.interface public dot.junit.opcodes.invoke_super_range.d.ITestDefault
+
+.method public testDefault()V
+.limit regs 2
+    return-void
+.end method
+
+.source ITestNonDefault.java
+.interface public dot.junit.opcodes.invoke_super_range.d.ITestNonDefault
+.implements dot.junit.opcodes.invoke_super_range.d.ITestDefault
+.implements dot.junit.opcodes.invoke_super_range.d.ITestDefault2
+
+.method public abstract testDefault()V
+.end method
+
+
+.source T_invoke_super_range_27.java
+.class public dot.junit.opcodes.invoke_super_range.d.T_invoke_super_range_27
+.super java/lang/Object
+.implements dot.junit.opcodes.invoke_super_range.d.ITestNonDefault
+.implements dot.junit.opcodes.invoke_super_range.d.ITestDefault2
+
+.method public <init>()V
+.limit regs 2
+
+       invoke-direct {v1}, java/lang/Object/<init>()V
+       return-void
+.end method
+
+.method public run()V
+.limit regs 1
+       invoke-super/range {v0}, dot/junit/opcodes/invoke_super_range/d/ITestNonDefault/testDefault()V
+       return-void
+.end method
+
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/T_invoke_super_range_27.java b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/T_invoke_super_range_27.java
new file mode 100644
index 0000000..655bb44b
--- /dev/null
+++ b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/T_invoke_super_range_27.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dot.junit.opcodes.invoke_super_range.d;
+
+
+public class T_invoke_super_range_27 {
+    public void run() {
+
+    }
+}
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/T_invoke_super_range_28.d b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/T_invoke_super_range_28.d
new file mode 100644
index 0000000..df29d4d
--- /dev/null
+++ b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/T_invoke_super_range_28.d
@@ -0,0 +1,53 @@
+; Copyright (C) 2016 The Android Open Source Project
+;
+; Licensed under the Apache License, Version 2.0 (the "License");
+; you may not use this file except in compliance with the License.
+; You may obtain a copy of the License at
+;
+;      http://www.apache.org/licenses/LICENSE-2.0
+;
+; Unless required by applicable law or agreed to in writing, software
+; distributed under the License is distributed on an "AS IS" BASIS,
+; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+; See the License for the specific language governing permissions and
+; limitations under the License.
+
+.source ITestDefault2.java
+.interface public dot.junit.opcodes.invoke_super_range.d.ITestDefault2
+
+.method public testDefault()V
+.limit regs 2
+    return-void
+.end method
+
+.source ITestDefault.java
+.interface public dot.junit.opcodes.invoke_super_range.d.ITestDefault
+
+.method public testDefault()V
+.limit regs 2
+    return-void
+.end method
+
+.source ITestConflict.java
+.interface public dot.junit.opcodes.invoke_super_range.d.ITestConflict
+.implements dot.junit.opcodes.invoke_super_range.d.ITestDefault
+.implements dot.junit.opcodes.invoke_super_range.d.ITestDefault2
+
+.source T_invoke_super_range_28.java
+.class public dot.junit.opcodes.invoke_super_range.d.T_invoke_super_range_28
+.super java/lang/Object
+.implements dot.junit.opcodes.invoke_super_range.d.ITestConflict
+
+.method public <init>()V
+.limit regs 2
+
+       invoke-direct {v1}, java/lang/Object/<init>()V
+       return-void
+.end method
+
+.method public run()V
+.limit regs 1
+       invoke-super/range {v0}, dot/junit/opcodes/invoke_super_range/d/ITestConflict/testDefault()V
+       return-void
+.end method
+
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/T_invoke_super_range_28.java b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/T_invoke_super_range_28.java
new file mode 100644
index 0000000..160033c
--- /dev/null
+++ b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/T_invoke_super_range_28.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dot.junit.opcodes.invoke_super_range.d;
+
+
+public class T_invoke_super_range_28 {
+    public void run() {
+
+    }
+}
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/Test_invoke_virtual.java b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/Test_invoke_virtual.java
index 55423f4..4bdbb99 100644
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/Test_invoke_virtual.java
+++ b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/Test_invoke_virtual.java
@@ -79,6 +79,13 @@
     }
 
     /**
+     * @title invoke default interface method
+     */
+    public void testN7() {
+        loadAndRun("dot.junit.opcodes.invoke_virtual.d.T_invoke_virtual_28", null);
+    }
+
+    /**
      * @title expected NullPointerException
      */
     public void testE1() {
@@ -104,6 +111,23 @@
     }
 
     /**
+     * @title Attempt to invoke conflict method
+     */
+    public void testE5() {
+        loadAndRun("dot.junit.opcodes.invoke_virtual.d.T_invoke_virtual_26",
+                   IncompatibleClassChangeError.class);
+    }
+
+    /**
+     * @title Attempt to invoke abstract method
+     */
+    public void testE6() {
+        loadAndRun("dot.junit.opcodes.invoke_virtual.d.T_invoke_virtual_27",
+                   AbstractMethodError.class);
+    }
+
+
+    /**
      * @constraint A13
      * @title invalid constant pool index
      */
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/d/ITestDefault.java b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/d/ITestDefault.java
new file mode 100644
index 0000000..70f5ec4
--- /dev/null
+++ b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/d/ITestDefault.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dot.junit.opcodes.invoke_virtual;
+
+public interface ITestDefault {
+  public void testDefault();
+  // public default int testDefault() {
+  //   return 1;
+  // }
+}
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/d/ITestDefault2.java b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/d/ITestDefault2.java
new file mode 100644
index 0000000..58204c7
--- /dev/null
+++ b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/d/ITestDefault2.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dot.junit.opcodes.invoke_virtual;
+
+public interface ITestDefault2 {
+  public void testDefault();
+  // public default int testDefault() {
+  //   return 2;
+  // }
+}
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/d/ITestNonDefault.java b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/d/ITestNonDefault.java
new file mode 100644
index 0000000..11f7b17
--- /dev/null
+++ b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/d/ITestNonDefault.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dot.junit.opcodes.invoke_virtual;
+
+public interface ITestNonDefault extends ITestDefault, ITestDefault2 {
+  // Shadow the default implementation with a non-default one.
+  public void testDefault();
+}
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/d/T_invoke_virtual_26.d b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/d/T_invoke_virtual_26.d
new file mode 100644
index 0000000..0e87969
--- /dev/null
+++ b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/d/T_invoke_virtual_26.d
@@ -0,0 +1,49 @@
+; Copyright (C) 2016 The Android Open Source Project
+;
+; Licensed under the Apache License, Version 2.0 (the "License");
+; you may not use this file except in compliance with the License.
+; You may obtain a copy of the License at
+;
+;      http://www.apache.org/licenses/LICENSE-2.0
+;
+; Unless required by applicable law or agreed to in writing, software
+; distributed under the License is distributed on an "AS IS" BASIS,
+; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+; See the License for the specific language governing permissions and
+; limitations under the License.
+
+.source ITestDefault2.java
+.interface public dot.junit.opcodes.invoke_virtual.d.ITestDefault2
+
+.method public testDefault()V
+.limit regs 2
+    return-void
+.end method
+
+.source ITestDefault.java
+.interface public dot.junit.opcodes.invoke_virtual.d.ITestDefault
+
+.method public testDefault()V
+.limit regs 2
+    return-void
+.end method
+
+.source T_invoke_virtual_26.java
+.class public dot.junit.opcodes.invoke_virtual.d.T_invoke_virtual_26
+.super java/lang/Object
+.implements dot.junit.opcodes.invoke_virtual.d.ITestDefault
+.implements dot.junit.opcodes.invoke_virtual.d.ITestDefault2
+
+.method public <init>()V
+.limit regs 2
+
+       invoke-direct {v1}, java/lang/Object/<init>()V
+       return-void
+.end method
+
+.method public run()V
+.limit regs 1
+       invoke-virtual {v0}, dot/junit/opcodes/invoke_virtual/d/T_invoke_virtual_26/testDefault()V
+       return-void
+.end method
+
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/d/T_invoke_virtual_26.java b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/d/T_invoke_virtual_26.java
new file mode 100644
index 0000000..54b5f19
--- /dev/null
+++ b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/d/T_invoke_virtual_26.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dot.junit.opcodes.invoke_virtual.d;
+
+
+public class T_invoke_virtual_26 {
+    public void run() {
+
+    }
+}
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/d/T_invoke_virtual_27.d b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/d/T_invoke_virtual_27.d
new file mode 100644
index 0000000..d34045b
--- /dev/null
+++ b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/d/T_invoke_virtual_27.d
@@ -0,0 +1,58 @@
+; Copyright (C) 2016 The Android Open Source Project
+;
+; Licensed under the Apache License, Version 2.0 (the "License");
+; you may not use this file except in compliance with the License.
+; You may obtain a copy of the License at
+;
+;      http://www.apache.org/licenses/LICENSE-2.0
+;
+; Unless required by applicable law or agreed to in writing, software
+; distributed under the License is distributed on an "AS IS" BASIS,
+; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+; See the License for the specific language governing permissions and
+; limitations under the License.
+
+.source ITestDefault2.java
+.interface public dot.junit.opcodes.invoke_virtual.d.ITestDefault2
+
+.method public testDefault()V
+.limit regs 2
+    return-void
+.end method
+
+.source ITestDefault.java
+.interface public dot.junit.opcodes.invoke_virtual.d.ITestDefault
+
+.method public testDefault()V
+.limit regs 2
+    return-void
+.end method
+
+.source ITestNonDefault.java
+.interface public dot.junit.opcodes.invoke_virtual.d.ITestNonDefault
+.implements dot.junit.opcodes.invoke_virtual.d.ITestDefault
+.implements dot.junit.opcodes.invoke_virtual.d.ITestDefault2
+
+.method public abstract testDefault()V
+.end method
+
+
+.source T_invoke_virtual_27.java
+.class public dot.junit.opcodes.invoke_virtual.d.T_invoke_virtual_27
+.super java/lang/Object
+.implements dot.junit.opcodes.invoke_virtual.d.ITestNonDefault
+.implements dot.junit.opcodes.invoke_virtual.d.ITestDefault2
+
+.method public <init>()V
+.limit regs 2
+
+       invoke-direct {v1}, java/lang/Object/<init>()V
+       return-void
+.end method
+
+.method public run()V
+.limit regs 1
+       invoke-virtual {v0}, dot/junit/opcodes/invoke_virtual/d/T_invoke_virtual_27/testDefault()V
+       return-void
+.end method
+
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/d/T_invoke_virtual_27.java b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/d/T_invoke_virtual_27.java
new file mode 100644
index 0000000..28461b5
--- /dev/null
+++ b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/d/T_invoke_virtual_27.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dot.junit.opcodes.invoke_virtual.d;
+
+
+public class T_invoke_virtual_27 {
+    public void run() {
+
+    }
+}
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/d/T_invoke_virtual_28.d b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/d/T_invoke_virtual_28.d
new file mode 100644
index 0000000..8d3cf9e
--- /dev/null
+++ b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/d/T_invoke_virtual_28.d
@@ -0,0 +1,40 @@
+; Copyright (C) 2016 The Android Open Source Project
+;
+; Licensed under the Apache License, Version 2.0 (the "License");
+; you may not use this file except in compliance with the License.
+; You may obtain a copy of the License at
+;
+;      http://www.apache.org/licenses/LICENSE-2.0
+;
+; Unless required by applicable law or agreed to in writing, software
+; distributed under the License is distributed on an "AS IS" BASIS,
+; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+; See the License for the specific language governing permissions and
+; limitations under the License.
+
+.source ITestDefault.java
+.interface public dot.junit.opcodes.invoke_virtual.d.ITestDefault
+
+.method public testDefault()V
+.limit regs 2
+    return-void
+.end method
+
+.source T_invoke_virtual_28.java
+.class public dot.junit.opcodes.invoke_virtual.d.T_invoke_virtual_28
+.super java/lang/Object
+.implements dot.junit.opcodes.invoke_virtual.d.ITestDefault
+
+.method public <init>()V
+.limit regs 2
+
+       invoke-direct {v1}, java/lang/Object/<init>()V
+       return-void
+.end method
+
+.method public run()V
+.limit regs 1
+       invoke-virtual {v0}, dot/junit/opcodes/invoke_virtual/d/T_invoke_virtual_28/testDefault()V
+       return-void
+.end method
+
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/d/T_invoke_virtual_28.java b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/d/T_invoke_virtual_28.java
new file mode 100644
index 0000000..6d599e3
--- /dev/null
+++ b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/d/T_invoke_virtual_28.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dot.junit.opcodes.invoke_virtual.d;
+
+
+public class T_invoke_virtual_28 {
+    public void run() {
+
+    }
+}
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/Test_invoke_virtual_range.java b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/Test_invoke_virtual_range.java
index 5aa7d33..a454f58 100644
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/Test_invoke_virtual_range.java
+++ b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/Test_invoke_virtual_range.java
@@ -88,6 +88,13 @@
     }
 
     /**
+     * @title invoke default interface method
+     */
+    public void testN8() {
+        loadAndRun("dot.junit.opcodes.invoke_virtual_range.d.T_invoke_virtual_range_28", null);
+    }
+
+    /**
      * @title expected NullPointerException
      */
     public void testE1() {
@@ -113,6 +120,22 @@
     }
 
     /**
+     * @title Attempt to invoke conflict method
+     */
+    public void testE5() {
+        loadAndRun("dot.junit.opcodes.invoke_virtual_range.d.T_invoke_virtual_range_26",
+                   IncompatibleClassChangeError.class);
+    }
+
+    /**
+     * @title Attempt to invoke abstract method
+     */
+    public void testE6() {
+        loadAndRun("dot.junit.opcodes.invoke_virtual_range.d.T_invoke_virtual_range_27",
+                   AbstractMethodError.class);
+    }
+
+    /**
      * @constraint A14
      * @title invalid constant pool index
      */
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/ITestDefault.java b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/ITestDefault.java
new file mode 100644
index 0000000..73c2051
--- /dev/null
+++ b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/ITestDefault.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dot.junit.opcodes.invoke_virtual_range;
+
+public interface ITestDefault {
+  public void testDefault();
+  // public default int testDefault() {
+  //   return 1;
+  // }
+}
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/ITestDefault2.java b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/ITestDefault2.java
new file mode 100644
index 0000000..9f4e014
--- /dev/null
+++ b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/ITestDefault2.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dot.junit.opcodes.invoke_virtual_range;
+
+public interface ITestDefault2 {
+  public void testDefault();
+  // public default int testDefault() {
+  //   return 2;
+  // }
+}
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/ITestNonDefault.java b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/ITestNonDefault.java
new file mode 100644
index 0000000..7e62b53
--- /dev/null
+++ b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/ITestNonDefault.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dot.junit.opcodes.invoke_virtual_range;
+
+public interface ITestNonDefault extends ITestDefault, ITestDefault2 {
+  // Shadow the default implementation with a non-default one.
+  public void testDefault();
+}
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_26.d b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_26.d
new file mode 100644
index 0000000..31ea1ee
--- /dev/null
+++ b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_26.d
@@ -0,0 +1,49 @@
+; Copyright (C) 2016 The Android Open Source Project
+;
+; Licensed under the Apache License, Version 2.0 (the "License");
+; you may not use this file except in compliance with the License.
+; You may obtain a copy of the License at
+;
+;      http://www.apache.org/licenses/LICENSE-2.0
+;
+; Unless required by applicable law or agreed to in writing, software
+; distributed under the License is distributed on an "AS IS" BASIS,
+; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+; See the License for the specific language governing permissions and
+; limitations under the License.
+
+.source ITestDefault2.java
+.interface public dot.junit.opcodes.invoke_virtual_range.d.ITestDefault2
+
+.method public testDefault()V
+.limit regs 2
+    return-void
+.end method
+
+.source ITestDefault.java
+.interface public dot.junit.opcodes.invoke_virtual_range.d.ITestDefault
+
+.method public testDefault()V
+.limit regs 2
+    return-void
+.end method
+
+.source T_invoke_virtual_range_26.java
+.class public dot.junit.opcodes.invoke_virtual_range.d.T_invoke_virtual_range_26
+.super java/lang/Object
+.implements dot.junit.opcodes.invoke_virtual_range.d.ITestDefault
+.implements dot.junit.opcodes.invoke_virtual_range.d.ITestDefault2
+
+.method public <init>()V
+.limit regs 2
+
+       invoke-direct {v1}, java/lang/Object/<init>()V
+       return-void
+.end method
+
+.method public run()V
+.limit regs 1
+       invoke-virtual/range {v0}, dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_26/testDefault()V
+       return-void
+.end method
+
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_26.java b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_26.java
new file mode 100644
index 0000000..23a749a
--- /dev/null
+++ b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_26.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dot.junit.opcodes.invoke_virtual_range.d;
+
+
+public class T_invoke_virtual_range_26 {
+    public void run() {
+
+    }
+}
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_27.d b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_27.d
new file mode 100644
index 0000000..ce470e3
--- /dev/null
+++ b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_27.d
@@ -0,0 +1,58 @@
+; Copyright (C) 2016 The Android Open Source Project
+;
+; Licensed under the Apache License, Version 2.0 (the "License");
+; you may not use this file except in compliance with the License.
+; You may obtain a copy of the License at
+;
+;      http://www.apache.org/licenses/LICENSE-2.0
+;
+; Unless required by applicable law or agreed to in writing, software
+; distributed under the License is distributed on an "AS IS" BASIS,
+; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+; See the License for the specific language governing permissions and
+; limitations under the License.
+
+.source ITestDefault2.java
+.interface public dot.junit.opcodes.invoke_virtual_range.d.ITestDefault2
+
+.method public testDefault()V
+.limit regs 2
+    return-void
+.end method
+
+.source ITestDefault.java
+.interface public dot.junit.opcodes.invoke_virtual_range.d.ITestDefault
+
+.method public testDefault()V
+.limit regs 2
+    return-void
+.end method
+
+.source ITestNonDefault.java
+.interface public dot.junit.opcodes.invoke_virtual_range.d.ITestNonDefault
+.implements dot.junit.opcodes.invoke_virtual_range.d.ITestDefault
+.implements dot.junit.opcodes.invoke_virtual_range.d.ITestDefault2
+
+.method public abstract testDefault()V
+.end method
+
+
+.source T_invoke_virtual_range_27.java
+.class public dot.junit.opcodes.invoke_virtual_range.d.T_invoke_virtual_range_27
+.super java/lang/Object
+.implements dot.junit.opcodes.invoke_virtual_range.d.ITestNonDefault
+.implements dot.junit.opcodes.invoke_virtual_range.d.ITestDefault2
+
+.method public <init>()V
+.limit regs 2
+
+       invoke-direct {v1}, java/lang/Object/<init>()V
+       return-void
+.end method
+
+.method public run()V
+.limit regs 1
+       invoke-virtual/range {v0}, dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_27/testDefault()V
+       return-void
+.end method
+
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_27.java b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_27.java
new file mode 100644
index 0000000..099389d
--- /dev/null
+++ b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_27.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dot.junit.opcodes.invoke_virtual_range.d;
+
+
+public class T_invoke_virtual_range_27 {
+    public void run() {
+
+    }
+}
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_28.d b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_28.d
new file mode 100644
index 0000000..5617cbd
--- /dev/null
+++ b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_28.d
@@ -0,0 +1,40 @@
+; Copyright (C) 2016 The Android Open Source Project
+;
+; Licensed under the Apache License, Version 2.0 (the "License");
+; you may not use this file except in compliance with the License.
+; You may obtain a copy of the License at
+;
+;      http://www.apache.org/licenses/LICENSE-2.0
+;
+; Unless required by applicable law or agreed to in writing, software
+; distributed under the License is distributed on an "AS IS" BASIS,
+; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+; See the License for the specific language governing permissions and
+; limitations under the License.
+
+.source ITestDefault.java
+.interface public dot.junit.opcodes.invoke_virtual_range.d.ITestDefault
+
+.method public testDefault()V
+.limit regs 2
+    return-void
+.end method
+
+.source T_invoke_virtual_range_28.java
+.class public dot.junit.opcodes.invoke_virtual_range.d.T_invoke_virtual_range_28
+.super java/lang/Object
+.implements dot.junit.opcodes.invoke_virtual_range.d.ITestDefault
+
+.method public <init>()V
+.limit regs 2
+
+       invoke-direct {v1}, java/lang/Object/<init>()V
+       return-void
+.end method
+
+.method public run()V
+.limit regs 1
+       invoke-virtual/range {v0}, dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_28/testDefault()V
+       return-void
+.end method
+
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_28.java b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_28.java
new file mode 100644
index 0000000..b0081de
--- /dev/null
+++ b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_28.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dot.junit.opcodes.invoke_virtual_range.d;
+
+
+public class T_invoke_virtual_range_28 {
+    public void run() {
+
+    }
+}
diff --git a/tools/vm-tests-tf/src/util/build/BuildDalvikSuite.java b/tools/vm-tests-tf/src/util/build/BuildDalvikSuite.java
index 0e31884..08b1e5f 100644
--- a/tools/vm-tests-tf/src/util/build/BuildDalvikSuite.java
+++ b/tools/vm-tests-tf/src/util/build/BuildDalvikSuite.java
@@ -19,6 +19,7 @@
 import com.android.dex.util.FileUtils;
 
 import dot.junit.AllTests;
+import util.build.BuildStep.BuildFile;
 
 import junit.framework.TestCase;
 import junit.framework.TestResult;
@@ -56,6 +57,8 @@
  */
 public class BuildDalvikSuite {
 
+    public static final String TARGET_MAIN_FILE = "mains.jar";
+
     public static boolean DEBUG = true;
 
     private static String JAVASRC_FOLDER = "";
@@ -102,7 +105,10 @@
      */
     public static void main(String[] args) throws IOException {
 
-        parseArgs(args);
+        if (!parseArgs(args)) {
+          printUsage();
+          System.exit(-1);
+        }
 
         long start = System.currentTimeMillis();
         BuildDalvikSuite cat = new BuildDalvikSuite(false);
@@ -112,7 +118,7 @@
         System.out.println("elapsed seconds: " + (end - start) / 1000);
     }
 
-    public static void parseArgs(String[] args) {
+    public static boolean parseArgs(String[] args) {
       if (args.length > 5) {
           JAVASRC_FOLDER = args[0];
           OUTPUT_FOLDER = args[1];
@@ -130,15 +136,18 @@
               restrictTo = args[6];
               System.out.println("restricting build to: " + restrictTo);
           }
-
+          return true;
       } else {
-          System.out.println("usage: java-src-folder output-folder classpath " +
-                  "generated-main-files compiled_output generated-main-files " +
-          "[restrict-to-opcode]");
-          System.exit(-1);
+          return false;
       }
     }
 
+    private static void printUsage() {
+        System.out.println("usage: java-src-folder output-folder classpath " +
+                           "generated-main-files compiled_output generated-main-files " +
+                           "[restrict-to-opcode]");
+    }
+
     public BuildDalvikSuite(boolean useJack) {
       this.useJack = useJack;
     }
@@ -257,14 +266,10 @@
         final String targetCoreJarPath = String.format("%s/dot/junit/dexcore.jar",
                 TARGET_JAR_ROOT_PATH);
 
-        // push class with Main jar.
-        String mjar = "Main_" + method + ".jar";
-        String pPath = pName.replaceAll("\\.","/");
-        String mainJar = String.format("%s/%s/%s", TARGET_JAR_ROOT_PATH, pPath, mjar);
+        String mainsJar = String.format("%s/%s", TARGET_JAR_ROOT_PATH, TARGET_MAIN_FILE);
 
-        String cp = String.format("%s:%s", targetCoreJarPath, mainJar);
+        String cp = String.format("%s:%s", targetCoreJarPath, mainsJar);
         for (String depFqcn : dependentTestClassNames) {
-            int lastDotPos = depFqcn.lastIndexOf('.');
             String sourceName = depFqcn.replaceAll("\\.", "/") + ".jar";
             String targetName= String.format("%s/%s", TARGET_JAR_ROOT_PATH,
                     sourceName);
@@ -289,7 +294,13 @@
         hostJunitBuildStep = new JavacBuildStep(
             HOSTJUNIT_CLASSES_OUTPUT_FOLDER, CLASS_PATH);
 
-        srcBuildStep = new JavacBuildStep(CLASSES_OUTPUT_FOLDER, CLASS_PATH);
+        String mainsJar = OUTPUT_FOLDER + File.separator + TARGET_MAIN_FILE;
+        if (useJack) {
+            srcBuildStep = new JackBuildStep(mainsJar,
+            CLASS_PATH);
+        } else {
+            srcBuildStep = new JavacBuildStep(CLASSES_OUTPUT_FOLDER, CLASS_PATH);
+        }
 
         for (Entry<String, List<String>> entry : map.entrySet()) {
 
@@ -355,23 +366,7 @@
                 File sourceFile = getFileFromPackage(pName, method);
 
                 writeToFile(sourceFile, content);
-                if (useJack) {
-                    File jackFile = new File(CLASSES_OUTPUT_FOLDER + "/" +
-                            getFileName(pName, method, ".jack"));
-                    JackBuildStep step = new JackBuildStep(jackFile.getAbsolutePath(), CLASS_PATH);
-                    step.addSourceFile(sourceFile.getAbsolutePath());
-                    if (!step.build()) {
-                        System.out.println("main src dalvik-cts-buildutil build step failed");
-                        System.exit(1);
-                    }
-                } else {
-                    srcBuildStep.addSourceFile(sourceFile.getAbsolutePath());
-                }
-
-                BuildStep dexBuildStep = generateDexBuildStep(
-                        CLASSES_OUTPUT_FOLDER, getFileName(pName, method, ""), null);
-                targets.add(dexBuildStep);
-
+                srcBuildStep.addSourceFile(sourceFile.getAbsolutePath());
 
                 // prepare the entry in the data file for the bash script.
                 // e.g.
@@ -459,6 +454,15 @@
 
         }
 
+        if (!useJack) {
+          DxBuildStep dexBuildStep = new DxBuildStep(
+              new BuildStep.BuildFile(new File(CLASSES_OUTPUT_FOLDER)),
+              new BuildStep.BuildFile(new File(mainsJar)),
+              false);
+
+          targets.add(dexBuildStep);
+        }
+
         // write latest HOSTJUNIT generated file.
         flushHostJunitFile();
 
@@ -471,12 +475,11 @@
             System.exit(1);
         }
 
-        if (!useJack) {
-            if (!srcBuildStep.build()) {
-                System.out.println("main src dalvik-cts-buildutil build step failed");
-                System.exit(1);
-            }
+        if (!srcBuildStep.build()) {
+            System.out.println("main src dalvik-cts-buildutil build step failed");
+            System.exit(1);
         }
+
         for (BuildStep buildStep : targets) {
             if (!buildStep.build()) {
                 System.out.println("building failed. buildStep: " +
@@ -541,15 +544,17 @@
 
         File srcFile = new File(sourceFolder, fileName + ".java");
         if (srcFile.exists()) {
-            JackBuildStep jackBuildStep = null;
+            BuildStep dexBuildStep;
             if (useJack) {
-                jackBuildStep = new JackBuildStep(
-                        COMPILED_CLASSES_FOLDER + File.separator + fileName + ".jack",
+                JackBuildStep jackBuildStep = new JackBuildStep(
+                    OUTPUT_FOLDER + File.separator + fileName + ".jar",
                         CLASS_PATH);
                 jackBuildStep.addSourceFile(srcFile.getAbsolutePath());
+                dexBuildStep = jackBuildStep;
+            } else {
+              dexBuildStep = generateDexBuildStep(
+                COMPILED_CLASSES_FOLDER, fileName, null);
             }
-            BuildStep dexBuildStep = generateDexBuildStep(
-                COMPILED_CLASSES_FOLDER, fileName, jackBuildStep);
             targets.add(dexBuildStep);
             return;
         }
diff --git a/tools/vm-tests-tf/src/util/build/BuildStep.java b/tools/vm-tests-tf/src/util/build/BuildStep.java
index dbc6bca..e3349bd 100644
--- a/tools/vm-tests-tf/src/util/build/BuildStep.java
+++ b/tools/vm-tests-tf/src/util/build/BuildStep.java
@@ -37,6 +37,10 @@
             this.folder = new File(folder);
             this.fileName = new File(this.folder, fileName);
         }
+        BuildFile(File file) {
+          this.folder = file.getParentFile();
+          this.fileName = file;
+      }
 
         String getPath() {
             return fileName.getAbsolutePath();
@@ -70,7 +74,8 @@
         this.outputFile = outputFile;
     }
 
-    BuildStep() {
+    BuildStep(File output) {
+        this.outputFile = new BuildFile(output);
     }
 
     private Set<BuildStep> children;
@@ -117,8 +122,7 @@
     }
 
     public int compareTo(BuildStep o) {
-        return (inputFile == o.inputFile ? 0 : (inputFile != null
-                ? (o.inputFile != null ? inputFile.getPath().compareTo(
-                        o.inputFile.getPath()) : 1) : -1));
+        return (outputFile == o.outputFile ? 0 : outputFile.getPath().compareTo(
+                        o.outputFile.getPath()));
     }
 }
diff --git a/tools/vm-tests-tf/src/util/build/BytesStreamSucker.java b/tools/vm-tests-tf/src/util/build/BytesStreamSucker.java
new file mode 100644
index 0000000..f243c17
--- /dev/null
+++ b/tools/vm-tests-tf/src/util/build/BytesStreamSucker.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package util.build;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import javax.annotation.Nonnull;
+
+/**
+ * Class that continuously read an {@link InputStream} and optionally could write the input in a
+ * {@link OutputStream}.
+ */
+public class BytesStreamSucker {
+
+  private static final int BUFFER_SIZE = 4096;
+
+  @Nonnull
+  private final byte[] buffer = new byte[BUFFER_SIZE];
+
+  @Nonnull
+  private final InputStream is;
+
+  @Nonnull
+  private final OutputStream os;
+
+  private final boolean toBeClose;
+
+  public BytesStreamSucker(
+      @Nonnull InputStream is, @Nonnull OutputStream os, boolean toBeClose) {
+    this.is = is;
+    this.os = os;
+    this.toBeClose = toBeClose;
+  }
+
+  public BytesStreamSucker(@Nonnull InputStream is, @Nonnull OutputStream os) {
+    this(is, os, false);
+  }
+
+  public void suck() throws IOException {
+    try {
+      int bytesRead;
+      while ((bytesRead = is.read(buffer)) >= 0) {
+        os.write(buffer, 0, bytesRead);
+        os.flush();
+      }
+    } finally {
+      if (toBeClose) {
+        os.close();
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/tools/vm-tests-tf/src/util/build/CharactersStreamSucker.java b/tools/vm-tests-tf/src/util/build/CharactersStreamSucker.java
new file mode 100644
index 0000000..ce4dfb1
--- /dev/null
+++ b/tools/vm-tests-tf/src/util/build/CharactersStreamSucker.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package util.build;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.PrintStream;
+
+import javax.annotation.Nonnull;
+
+/**
+ * Class that continuously read an {@link InputStream} and optionally could print the input in a
+ * {@link PrintStream}.
+ */
+public class CharactersStreamSucker {
+
+  @Nonnull
+  private final BufferedReader ir;
+
+  @Nonnull
+  private final PrintStream os;
+
+  private final boolean toBeClose;
+
+  public CharactersStreamSucker(
+      @Nonnull InputStream is, @Nonnull PrintStream os, boolean toBeClose) {
+    this.ir = new BufferedReader(new InputStreamReader(is));
+    this.os = os;
+    this.toBeClose = toBeClose;
+  }
+
+  public CharactersStreamSucker(@Nonnull InputStream is, @Nonnull PrintStream os) {
+    this(is, os, false);
+  }
+
+  public void suck() throws IOException {
+    String line;
+
+    try {
+      while ((line = ir.readLine()) != null) {
+        os.println(line);
+      }
+    } finally {
+      if (toBeClose) {
+        os.close();
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/tools/vm-tests-tf/src/util/build/ExecuteFile.java b/tools/vm-tests-tf/src/util/build/ExecuteFile.java
new file mode 100644
index 0000000..128e477
--- /dev/null
+++ b/tools/vm-tests-tf/src/util/build/ExecuteFile.java
@@ -0,0 +1,275 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package util.build;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.io.StreamTokenizer;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
+
+/**
+ * Class to handle the execution of an external process
+ */
+public class ExecuteFile {
+  @Nonnull
+  private final String[] cmdLine;
+
+  @CheckForNull
+  private File workDir;
+
+  @CheckForNull
+  private InputStream inStream;
+  private boolean inToBeClose;
+
+  @CheckForNull
+  private OutputStream outStream;
+  private boolean outToBeClose;
+
+  @CheckForNull
+  private OutputStream errStream;
+  private boolean errToBeClose;
+  private boolean verbose;
+
+  @Nonnull
+  private final Logger logger = Logger.getLogger(this.getClass().getName());
+
+  public void setErr(@Nonnull File file) throws FileNotFoundException {
+    errStream = new FileOutputStream(file);
+    errToBeClose = true;
+  }
+
+  public void setOut(@Nonnull File file) throws FileNotFoundException {
+    outStream = new FileOutputStream(file);
+    outToBeClose = true;
+  }
+
+  public void setIn(@Nonnull File file) throws FileNotFoundException {
+    inStream = new FileInputStream(file);
+    inToBeClose = true;
+  }
+
+  public void setErr(@Nonnull OutputStream stream) {
+    errStream = stream;
+  }
+
+  public void setOut(@Nonnull OutputStream stream) {
+    outStream = stream;
+  }
+
+  public void setIn(@Nonnull InputStream stream) {
+    inStream = stream;
+  }
+
+  public void setWorkingDir(@Nonnull File dir, boolean create) throws IOException {
+    if (!dir.isDirectory()) {
+      if (create && !dir.exists()) {
+        if (!dir.mkdirs()) {
+          throw new IOException("Directory creation failed");
+        }
+      } else {
+        throw new FileNotFoundException(dir.getPath() + " is not a directory");
+      }
+    }
+
+    workDir = dir;
+  }
+
+  public void setVerbose(boolean verbose) {
+    this.verbose = verbose;
+  }
+
+  public ExecuteFile(@Nonnull File exec, @Nonnull String[] args) {
+    cmdLine = new String[args.length + 1];
+    System.arraycopy(args, 0, cmdLine, 1, args.length);
+
+    cmdLine[0] = exec.getAbsolutePath();
+  }
+
+  public ExecuteFile(@Nonnull String exec, @Nonnull String[] args) {
+    cmdLine = new String[args.length + 1];
+    System.arraycopy(args, 0, cmdLine, 1, args.length);
+
+    cmdLine[0] = exec;
+  }
+
+  public ExecuteFile(@Nonnull File exec) {
+    cmdLine = new String[1];
+    cmdLine[0] = exec.getAbsolutePath();
+  }
+
+  public ExecuteFile(@Nonnull String[] cmdLine) {
+    this.cmdLine = cmdLine.clone();
+  }
+
+  public ExecuteFile(@Nonnull String cmdLine) throws IOException {
+    StringReader reader = new StringReader(cmdLine);
+    StreamTokenizer tokenizer = new StreamTokenizer(reader);
+    tokenizer.resetSyntax();
+    // Only standard spaces are recognized as whitespace chars
+    tokenizer.whitespaceChars(' ', ' ');
+    // Matches alphanumerical and common special symbols like '(' and ')'
+    tokenizer.wordChars('!', 'z');
+    // Quote chars will be ignored when parsing strings
+    tokenizer.quoteChar('\'');
+    tokenizer.quoteChar('\"');
+    ArrayList<String> tokens = new ArrayList<String>();
+    while (tokenizer.nextToken() != StreamTokenizer.TT_EOF) {
+      String token = tokenizer.sval;
+      if (token != null) {
+        tokens.add(token);
+      }
+    }
+    this.cmdLine = tokens.toArray(new String[0]);
+  }
+
+  public boolean run() {
+    int ret;
+    Process proc = null;
+    Thread suckOut = null;
+    Thread suckErr = null;
+    Thread suckIn = null;
+
+    try {
+      StringBuilder cmdLineBuilder = new StringBuilder();
+      for (String arg : cmdLine) {
+        cmdLineBuilder.append(arg).append(' ');
+      }
+      if (verbose) {
+        PrintStream printStream;
+        if (outStream instanceof PrintStream) {
+          printStream = (PrintStream) outStream;
+        } else {
+          printStream = System.out;
+        }
+
+        if (printStream != null) {
+          printStream.println(cmdLineBuilder);
+        }
+      } else {
+        logger.log(Level.FINE, "Execute: {0}", cmdLineBuilder);
+      }
+
+      proc = Runtime.getRuntime().exec(cmdLine, null, workDir);
+
+      InputStream localInStream = inStream;
+      if (localInStream != null) {
+        suckIn = new Thread(
+            new ThreadBytesStreamSucker(localInStream, proc.getOutputStream(), inToBeClose));
+      } else {
+        proc.getOutputStream().close();
+      }
+
+      OutputStream localOutStream = outStream;
+      if (localOutStream != null) {
+        if (localOutStream instanceof PrintStream) {
+          suckOut = new Thread(new ThreadCharactersStreamSucker(proc.getInputStream(),
+              (PrintStream) localOutStream, outToBeClose));
+        } else {
+          suckOut = new Thread(
+              new ThreadBytesStreamSucker(proc.getInputStream(), localOutStream, outToBeClose));
+        }
+      }
+
+      OutputStream localErrStream = errStream;
+      if (localErrStream != null) {
+        if (localErrStream instanceof PrintStream) {
+          suckErr = new Thread(new ThreadCharactersStreamSucker(proc.getErrorStream(),
+              (PrintStream) localErrStream, errToBeClose));
+        } else {
+          suckErr = new Thread(
+              new ThreadBytesStreamSucker(proc.getErrorStream(), localErrStream, errToBeClose));
+        }
+      }
+
+      if (suckIn != null) {
+        suckIn.start();
+      }
+      if (suckOut != null) {
+        suckOut.start();
+      }
+      if (suckErr != null) {
+        suckErr.start();
+      }
+
+      proc.waitFor();
+      if (suckIn != null) {
+        suckIn.join();
+      }
+      if (suckOut != null) {
+        suckOut.join();
+      }
+      if (suckErr != null) {
+        suckErr.join();
+      }
+
+      ret = proc.exitValue();
+      proc.destroy();
+
+      return ret == 0;
+    } catch (Throwable e) {
+      e.printStackTrace();
+      return false;
+    }
+  }
+
+  private static class ThreadBytesStreamSucker extends BytesStreamSucker implements Runnable {
+
+    public ThreadBytesStreamSucker(@Nonnull InputStream is, @Nonnull OutputStream os,
+        boolean toBeClose) {
+      super(is, os, toBeClose);
+    }
+
+    @Override
+    public void run() {
+      try {
+        suck();
+      } catch (IOException e) {
+        // Best effort
+      }
+    }
+  }
+
+  private static class ThreadCharactersStreamSucker extends CharactersStreamSucker implements
+      Runnable {
+
+    public ThreadCharactersStreamSucker(@Nonnull InputStream is, @Nonnull PrintStream ps,
+        boolean toBeClose) {
+      super(is, ps, toBeClose);
+    }
+
+    @Override
+    public void run() {
+      try {
+        suck();
+      } catch (IOException e) {
+        // Best effort
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/tools/vm-tests-tf/src/util/build/JackBuildDalvikSuite.java b/tools/vm-tests-tf/src/util/build/JackBuildDalvikSuite.java
index a508e5b..2b45f9c 100644
--- a/tools/vm-tests-tf/src/util/build/JackBuildDalvikSuite.java
+++ b/tools/vm-tests-tf/src/util/build/JackBuildDalvikSuite.java
@@ -20,9 +20,23 @@
 
 public class JackBuildDalvikSuite {
 
+    public static String JACK;
+
     public static void main(String[] args) throws IOException {
 
-        BuildDalvikSuite.parseArgs(args);
+        String[] remainingArgs;
+        if (args.length > 0) {
+            JACK = args[0];
+            remainingArgs = new String[args.length - 1];
+            System.arraycopy(args, 1, remainingArgs, 0, remainingArgs.length);
+        } else {
+            remainingArgs = args;
+        }
+
+        if (!BuildDalvikSuite.parseArgs(remainingArgs)) {
+            printUsage();
+            System.exit(-1);
+        }
 
         long start = System.currentTimeMillis();
         BuildDalvikSuite cat = new BuildDalvikSuite(true);
@@ -31,4 +45,11 @@
 
         System.out.println("elapsed seconds: " + (end - start) / 1000);
     }
+
+
+    private static void printUsage() {
+        System.out.println("usage: java-src-folder output-folder classpath " +
+                           "generated-main-files compiled_output generated-main-files " +
+                           "[restrict-to-opcode]");
+    }
 }
diff --git a/tools/vm-tests-tf/src/util/build/JackBuildStep.java b/tools/vm-tests-tf/src/util/build/JackBuildStep.java
index 1e1ede6..ed46582 100644
--- a/tools/vm-tests-tf/src/util/build/JackBuildStep.java
+++ b/tools/vm-tests-tf/src/util/build/JackBuildStep.java
@@ -16,11 +16,10 @@
 
 package util.build;
 
-import com.android.jack.Jack;
-import com.android.jack.Main;
-import com.android.jack.Options;
-
 import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.Writer;
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
@@ -33,6 +32,7 @@
     private final Set<String> sourceFiles = new HashSet<String>();
 
     public JackBuildStep(String destPath, String classPath) {
+        super(new File(destPath));
         this.destPath = destPath;
         this.classPath = classPath;
     }
@@ -55,23 +55,68 @@
                         + outDir.getAbsolutePath());
                 return false;
             }
-            List<String> commandLine = new ArrayList(4 + sourceFiles.size());
-            commandLine.add("--verbose");
-            commandLine.add("error");
-            commandLine.add("--classpath");
-            commandLine.add(classPath);
-            commandLine.add("--output-jack");
-            commandLine.add(destPath);
-            commandLine.addAll(sourceFiles);
 
+            File tmpOutDir = new File(outDir, outputFile.fileName.getName() + ".dexTmp");
+            if (!tmpOutDir.exists() && !tmpOutDir.mkdirs()) {
+                System.err.println("failed to create temp dir: "
+                        + tmpOutDir.getAbsolutePath());
+                return false;
+            }
+            File tmpDex = new File(tmpOutDir, "classes.dex");
+
+            File tmpArgs = new File(outDir, outputFile.fileName.getName() + ".args");
+
+            Writer argsOut = null;
             try {
-                Options options = Main.parseCommandLine(commandLine);
-                Jack.checkAndRun(options);
+                argsOut = new FileWriter(tmpArgs);
+                for (String source : sourceFiles) {
+                    argsOut.append(source);
+                    argsOut.append('\n');
+                }
+                argsOut.close();
+                argsOut = null;
+
+                List<String> commandLine = new ArrayList<String>(6 + sourceFiles.size());
+                commandLine.add("--verbose");
+                commandLine.add("error");
+                commandLine.add("--classpath");
+                commandLine.add(classPath);
+                commandLine.add("--output-dex");
+                commandLine.add(tmpOutDir.getAbsolutePath());
+                commandLine.add("@" + tmpArgs.getPath());
+
+                ExecuteFile exec = new ExecuteFile(JackBuildDalvikSuite.JACK,
+                    commandLine.toArray(new String[commandLine.size()]));
+                exec.setErr(System.err);
+                exec.setOut(System.out);
+                if (!exec.run()) {
+                    return false;
+                }
+
+                JarBuildStep jarStep = new JarBuildStep(
+                    new BuildFile(tmpDex),
+                    "classes.dex",
+                    outputFile,
+                    /* deleteInputFileAfterBuild = */ true);
+                if (!jarStep.build()) {
+                  throw new IOException("Failed to make jar: " + outputFile.getPath());
+                }
+                return true;
             } catch (Throwable ex) {
                 ex.printStackTrace();
                 return false;
+            } finally {
+                tmpDex.delete();
+                tmpArgs.delete();
+                tmpOutDir.delete();
+                if (argsOut != null) {
+                    try {
+                        argsOut.close();
+                    } catch (IOException io) {
+                        // Ignore, don't override already thrown exception
+                    }
+                }
             }
-            return true;
         }
         return false;
     }
diff --git a/tools/vm-tests-tf/src/util/build/JackDexBuildStep.java b/tools/vm-tests-tf/src/util/build/JackDexBuildStep.java
index 304eaa0..cbd5a3b 100644
--- a/tools/vm-tests-tf/src/util/build/JackDexBuildStep.java
+++ b/tools/vm-tests-tf/src/util/build/JackDexBuildStep.java
@@ -16,11 +16,8 @@
 
 package util.build;
 
-import com.android.jack.Jack;
-import com.android.jack.Main;
-import com.android.jack.Options;
-
 import java.io.File;
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -41,7 +38,7 @@
             String outputFilePath = outputFile.fileName.getAbsolutePath();
             if (outputFilePath.endsWith(".dex")) {
               throw new AssertionError(
-                  "DexBuildStep does not support dex output outside of an archive");
+                  "JackDexBuildStep does not support dex output outside of an archive");
             }
 
             File outDir = outputFile.fileName.getParentFile();
@@ -51,17 +48,39 @@
                 return false;
             }
 
-            List<String> commandLine = new ArrayList<String>(4);
-            commandLine.add("--verbose");
-            commandLine.add("error");
-            commandLine.add("--output-dex-zip");
-            commandLine.add(outputFilePath);
-            commandLine.add("--import");
-            commandLine.add(inputFile.fileName.getAbsolutePath());
+            File tmpOutDir = new File(outDir, outputFile.fileName.getName() + ".dexTmp");
+            if (!tmpOutDir.exists() && !tmpOutDir.mkdirs()) {
+                System.err.println("failed to create temp dir: "
+                        + tmpOutDir.getAbsolutePath());
+                return false;
+            }
+            File tmpDex = new File(tmpOutDir, "classes.dex");
 
             try {
-               Options options = Main.parseCommandLine(commandLine);
-               Jack.checkAndRun(options);
+                List<String> commandLine = new ArrayList<String>(4);
+                commandLine.add("--verbose");
+                commandLine.add("error");
+                commandLine.add("--output-dex");
+                commandLine.add(tmpOutDir.getAbsolutePath());
+                commandLine.add("--import");
+                commandLine.add(inputFile.fileName.getAbsolutePath());
+
+                ExecuteFile exec = new ExecuteFile(JackBuildDalvikSuite.JACK,
+                    commandLine.toArray(new String[commandLine.size()]));
+                exec.setErr(System.err);
+                exec.setOut(System.out);
+                if (!exec.run()) {
+                  return false;
+                }
+
+                JarBuildStep jarStep = new JarBuildStep(
+                    new BuildFile(tmpDex),
+                    "classes.dex",
+                    outputFile,
+                    /* deleteInputFileAfterBuild = */ true);
+                if (!jarStep.build()) {
+                  throw new IOException("Failed to make jar: " + outputFile.getPath());
+                }
                 if (deleteInputFileAfterBuild) {
                     inputFile.fileName.delete();
                 }
@@ -71,6 +90,9 @@
                         + inputFile.fileName.getAbsolutePath() + " to "
                         + outputFile.fileName.getAbsolutePath());
                 ex.printStackTrace();
+            } finally {
+              tmpDex.delete();
+              tmpOutDir.delete();
             }
         }
         return false;
diff --git a/tools/vm-tests-tf/src/util/build/JavacBuildStep.java b/tools/vm-tests-tf/src/util/build/JavacBuildStep.java
index a07bb69..a1cde1f 100644
--- a/tools/vm-tests-tf/src/util/build/JavacBuildStep.java
+++ b/tools/vm-tests-tf/src/util/build/JavacBuildStep.java
@@ -29,6 +29,7 @@
     private final String classPath;
     private final Set<String> sourceFiles = new HashSet<String>();
     public JavacBuildStep(String destPath, String classPath) {
+        super(new File(destPath));
         this.destPath = destPath;
         this.classPath = classPath;
     }
diff --git a/tools/vm-tests-tf/src/util/build/JillBuildStep.java b/tools/vm-tests-tf/src/util/build/JillBuildStep.java
index d2e435e..80cd49c 100644
--- a/tools/vm-tests-tf/src/util/build/JillBuildStep.java
+++ b/tools/vm-tests-tf/src/util/build/JillBuildStep.java
@@ -16,11 +16,8 @@
 
 package util.build;
 
-import com.android.jill.Jill;
-import com.android.jill.Main;
-import com.android.jill.Options;
-
 import java.io.File;
+import java.io.IOException;
 
 public class JillBuildStep extends BuildStep {
 
@@ -31,29 +28,52 @@
     @Override
     boolean build() {
         if (super.build()) {
-
-            File outDir = outputFile.fileName.getParentFile();
-            if (!outDir.exists() && !outDir.mkdirs()) {
-                System.err.println("failed to create output dir: "
-                        + outDir.getAbsolutePath());
-                return false;
-            }
-
-            int args = 3;
-            String[] commandLine = new String[args];
-            commandLine[0] = "--output";
-            commandLine[1] = outputFile.fileName.getAbsolutePath();
-            commandLine[2] = inputFile.fileName.getAbsolutePath();
-
+            File tmpInputJar = new File(inputFile.fileName.getPath() + ".jar");
             try {
-                Options options = Main.getOptions(commandLine);
-                Jill.process(options);
-            } catch (Throwable ex) {
-                ex.printStackTrace();
-                return false;
-            }
 
-            return true;
+                File outDir = outputFile.fileName.getParentFile();
+                if (!outDir.exists() && !outDir.mkdirs()) {
+                    System.err.println("failed to create output dir: "
+                            + outDir.getAbsolutePath());
+                    return false;
+                }
+
+                // input file is a class file but jack supports only jar
+                JarBuildStep jarStep = new JarBuildStep(
+                    inputFile,
+                    inputFile.fileName.getName(),
+                    new BuildFile(tmpInputJar),
+                    /* deleteInputFileAfterBuild = */ false);
+                if (!jarStep.build()) {
+                  throw new IOException("Failed to make jar: " + outputFile.getPath());
+                }
+
+
+                String[] commandLine = new String[] {
+                    "--verbose",
+                    "error",
+                    "--import",
+                    tmpInputJar.getAbsolutePath(),
+                    "--output-jack",
+                    outputFile.fileName.getAbsolutePath(),
+                  };
+
+                ExecuteFile exec = new ExecuteFile(JackBuildDalvikSuite.JACK, commandLine);
+                exec.setErr(System.err);
+                exec.setOut(System.out);
+                if (!exec.run()) {
+                    return false;
+                }
+
+                return true;
+            } catch (Throwable ex) {
+                System.err.println("exception while transforming jack file from jar "
+                        + inputFile.fileName.getAbsolutePath() + " to "
+                        + outputFile.fileName.getAbsolutePath());
+                ex.printStackTrace();
+            } finally {
+                tmpInputJar.delete();
+            }
         }
         return false;
     }
diff --git a/tools/vm-tests-tf/src/util/build/SourceBuildStep.java b/tools/vm-tests-tf/src/util/build/SourceBuildStep.java
index 4a68a05..9f9142d 100644
--- a/tools/vm-tests-tf/src/util/build/SourceBuildStep.java
+++ b/tools/vm-tests-tf/src/util/build/SourceBuildStep.java
@@ -16,8 +16,14 @@
 
 package util.build;
 
+import java.io.File;
+
 public abstract class SourceBuildStep extends BuildStep {
 
+  SourceBuildStep(File destFile) {
+    super(destFile);
+  }
+
   public abstract void addSourceFile(String sourceFile);
 
 }
diff --git a/tools/vm-tests-tf/targetprep/Android.mk b/tools/vm-tests-tf/targetprep/Android.mk
new file mode 100644
index 0000000..8abde93
--- /dev/null
+++ b/tools/vm-tests-tf/targetprep/Android.mk
@@ -0,0 +1,32 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_JAVA_LIBRARIES := compatibility-host-util cts-tradefed tradefed-prebuilt
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE := compatibility-host-vm-targetprep
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+include $(BUILD_HOST_JAVA_LIBRARY)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tools/vm-tests-tf/targetprep/src/android/core/vm/targetprep/VmTestPreparer.java b/tools/vm-tests-tf/targetprep/src/android/core/vm/targetprep/VmTestPreparer.java
new file mode 100644
index 0000000..d46e330
--- /dev/null
+++ b/tools/vm-tests-tf/targetprep/src/android/core/vm/targetprep/VmTestPreparer.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.core.vm.targetprep;
+
+import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.config.Option;
+import com.android.tradefed.config.OptionClass;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.log.LogUtil.CLog;
+import com.android.tradefed.targetprep.BuildError;
+import com.android.tradefed.targetprep.ITargetCleaner;
+import com.android.tradefed.targetprep.TargetSetupError;
+import com.android.tradefed.util.FileUtil;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.zip.ZipFile;
+
+/**
+ * Configures the device to run VM tests.
+ */
+@OptionClass(alias="vm-test-preparer")
+public class VmTestPreparer implements ITargetCleaner {
+
+    private static final String JAR_FILE = "android.core.vm-tests-tf.jar";
+    private static final String TEMP_DIR = "/data/local/tmp";
+    private static final String VM_TEMP_DIR = TEMP_DIR +"/vm-tests";
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setUp(ITestDevice device, IBuildInfo buildInfo)
+            throws TargetSetupError, BuildError, DeviceNotAvailableException {
+        CompatibilityBuildHelper helper = new CompatibilityBuildHelper(buildInfo);
+        if (!installVmPrereqs(device, helper)) {
+            throw new RuntimeException(String.format(
+                    "Failed to install vm-tests prereqs on device %s",
+                    device.getSerialNumber()));
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void tearDown(ITestDevice device, IBuildInfo buildInfo, Throwable e)
+            throws DeviceNotAvailableException {
+        cleanupDeviceFiles(device);
+    }
+
+    /**
+     * Install pre-requisite jars for running vm-tests, creates temp directories for test.
+     *
+     * @param device the {@link ITestDevice}
+     * @param ctsBuild the {@link CompatibilityBuildHelper}
+     * @throws DeviceNotAvailableException
+     * @return true if test jar files are extracted and pushed to device successfully
+     */
+    private boolean installVmPrereqs(ITestDevice device, CompatibilityBuildHelper ctsBuild)
+            throws DeviceNotAvailableException {
+        cleanupDeviceFiles(device);
+        // Creates temp directory recursively. We also need to create the dalvik-cache directory
+        // which is used by the dalvikvm to optimize things. Without the dalvik-cache, there will be
+        // a sigsev thrown by the vm.
+        createRemoteDir(device, VM_TEMP_DIR + "/dalvik-cache" );
+        try {
+            File tmpDir = new File(System.getProperty("java.io.tmpdir"));
+            File localTmpDir = FileUtil.createTempDir("cts-vm", tmpDir);
+            File jarFile = new File(ctsBuild.getTestsDir(), JAR_FILE);
+            if (!jarFile.exists()) {
+                CLog.e("Missing jar file %s", jarFile.getPath());
+                return false;
+            }
+            ZipFile zipFile = new ZipFile(jarFile);
+            FileUtil.extractZip(zipFile, localTmpDir);
+            File localTestTmpDir = new File(localTmpDir, "tests");
+            if (!device.pushDir(localTestTmpDir, VM_TEMP_DIR)) {
+                CLog.e("Failed to push vm test files");
+                return false;
+            }
+            FileUtil.recursiveDelete(localTmpDir);
+        } catch (IOException e) {
+            CLog.e("Failed to extract jar file %s and sync it to device %s.",
+                    JAR_FILE, device.getSerialNumber());
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Removes temporary file directory from device
+     *
+     * @param device
+     * @throws DeviceNotAvailableException
+     */
+    private void cleanupDeviceFiles(ITestDevice device) throws DeviceNotAvailableException {
+        if (device.doesFileExist(VM_TEMP_DIR)) {
+            device.executeShellCommand(String.format("rm -r %s", VM_TEMP_DIR));
+        }
+    }
+
+    /**
+     * Creates the file directory recursively in the device.
+     *
+     * @param device the {@link ITestDevice}
+     * @param remoteFilePath the absolute path.
+     * @throws DeviceNotAvailableException
+     */
+    private void createRemoteDir(ITestDevice device, String remoteFilePath)
+            throws DeviceNotAvailableException {
+        if (device.doesFileExist(remoteFilePath)) {
+            return;
+        }
+        if (!(device.doesFileExist(TEMP_DIR))) {
+            CLog.e("Error: %s does not exist", TEMP_DIR);
+        }
+        device.executeShellCommand(String.format("mkdir %s", VM_TEMP_DIR));
+        device.executeShellCommand(String.format("mkdir %s", remoteFilePath));
+    }
+}
\ No newline at end of file